From 92efc9c3451446311461aa133533620f83ed40dc Mon Sep 17 00:00:00 2001 From: dehnert Date: Thu, 3 Jan 2013 15:48:09 +0100 Subject: [PATCH 001/152] Taming Boost::Spirit... --- src/parser/PrismParser.h | 96 ++++++++++++++++++++++++++++++++++++++++ src/storm.cpp | 17 ++++--- 2 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 src/parser/PrismParser.h diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h new file mode 100644 index 000000000..5b74df99a --- /dev/null +++ b/src/parser/PrismParser.h @@ -0,0 +1,96 @@ +/* + * PrismParser.h + * + * Created on: Jan 3, 2013 + * Author: Christian Dehnert + */ + +#ifndef PRISMPARSER_H_ +#define PRISMPARSER_H_ + +#include +#include +#include +#include +#include +#include + +namespace storm { +namespace parser { +class intConstDef { +public: + std::string name; + int value; + + void print() { + std::cout << "(" << name << ", " << value << ")" << std::endl; + } +}; +} +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::parser::intConstDef, + (std::string, name) + (int, value) +) + +namespace storm { + +namespace parser { + +namespace qi = boost::spirit::qi; +namespace ascii = boost::spirit::ascii; + +class PrismParser { + +public: + void test() { + std::string str = "const int ab = 10;"; + std::string::const_iterator iter = str.begin(); + std::string::const_iterator end = str.end(); + prismGrammar grammar; + + intConstDef result; + bool r = phrase_parse(iter, end, grammar, ascii::space, result); + + std::cout << r << std::endl; + + if (r && iter == end) { + std::cout << "-------------------------\n"; + std::cout << "Parsing succeeded\n"; + result.print(); + // std::cout << "result = " << result << std::endl; + std::cout << "-------------------------\n"; + } else { + std::string rest(iter, end); + std::cout << "-------------------------\n"; + std::cout << "Parsing failed\n"; + std::cout << "stopped at: " << rest << "\"\n"; + std::cout << "-------------------------\n"; + } + } + +private: + template + struct prismGrammar : qi::grammar { + + prismGrammar() : prismGrammar::base_type(start) { + identifierName %= +(qi::char_); + integerConstantDefinition %= qi::lit("const") >> qi::lit("int") >> identifierName >> "=" >> qi::int_ >> ";"; + + start %= integerConstantDefinition; + } + + qi::rule start; + qi::rule integerConstantDefinition; + qi::rule identifierName; + + }; +}; + +} // namespace parser + +} // namespace storm + +#endif /* PRISMPARSER_H_ */ diff --git a/src/storm.cpp b/src/storm.cpp index 0c5951961..eed86455e 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -35,6 +35,8 @@ #include "log4cplus/consoleappender.h" #include "log4cplus/fileappender.h" +#include "src/parser/PrismParser.h" + #include "src/exceptions/InvalidSettingsException.h" log4cplus::Logger logger; @@ -230,13 +232,16 @@ void testChecking() { * Main entry point. */ int main(const int argc, const char* argv[]) { - initializeLogger(); - if (!parseOptions(argc, argv)) { - return 0; - } - printHeader(argc, argv); + // initializeLogger(); + // if (!parseOptions(argc, argv)) { + // return 0; + //} + // printHeader(argc, argv); + + // testChecking(); - testChecking(); + storm::parser::PrismParser parser; + parser.test(); cleanUp(); return 0; From a7ab5bb309e2cf96ca843c4c70a3d3259da94d0e Mon Sep 17 00:00:00 2001 From: dehnert Date: Thu, 3 Jan 2013 23:46:45 +0100 Subject: [PATCH 002/152] More fun with Spirit. --- src/ir/expressions/BaseExpression.h | 33 ++++++++ .../BinaryBooleanFunctionExpression.h | 63 +++++++++++++++ .../BinaryNumericalFunctionExpression.h | 63 +++++++++++++++ src/ir/expressions/BinaryRelationExpression.h | 64 +++++++++++++++ src/ir/expressions/BooleanLiteral.h | 51 ++++++++++++ src/ir/expressions/ConstantExpression.h | 47 +++++++++++ src/ir/expressions/DoubleLiteral.h | 47 +++++++++++ src/ir/expressions/Expressions.h | 21 +++++ src/ir/expressions/IntegerLiteral.h | 47 +++++++++++ .../UnaryBooleanFunctionExpression.h | 56 +++++++++++++ .../UnaryNumericalFunctionExpression.h | 56 +++++++++++++ src/ir/expressions/VariableExpression.h | 47 +++++++++++ src/parser/PrismParser.h | 80 ++++++++++++------- 13 files changed, 646 insertions(+), 29 deletions(-) create mode 100644 src/ir/expressions/BaseExpression.h create mode 100644 src/ir/expressions/BinaryBooleanFunctionExpression.h create mode 100644 src/ir/expressions/BinaryNumericalFunctionExpression.h create mode 100644 src/ir/expressions/BinaryRelationExpression.h create mode 100644 src/ir/expressions/BooleanLiteral.h create mode 100644 src/ir/expressions/ConstantExpression.h create mode 100644 src/ir/expressions/DoubleLiteral.h create mode 100644 src/ir/expressions/Expressions.h create mode 100644 src/ir/expressions/IntegerLiteral.h create mode 100644 src/ir/expressions/UnaryBooleanFunctionExpression.h create mode 100644 src/ir/expressions/UnaryNumericalFunctionExpression.h create mode 100644 src/ir/expressions/VariableExpression.h diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h new file mode 100644 index 000000000..aea967901 --- /dev/null +++ b/src/ir/expressions/BaseExpression.h @@ -0,0 +1,33 @@ +/* + * Expression.h + * + * Created on: 03.01.2013 + * Author: chris + */ + +#ifndef EXPRESSION_H_ +#define EXPRESSION_H_ + +namespace storm { + +namespace ir { + +namespace expressions { + +class BaseExpression { + +public: + virtual ~BaseExpression() { + + } + + virtual std::string toString() const = 0; +}; + +} + +} + +} + +#endif /* EXPRESSION_H_ */ diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.h b/src/ir/expressions/BinaryBooleanFunctionExpression.h new file mode 100644 index 000000000..a5688f188 --- /dev/null +++ b/src/ir/expressions/BinaryBooleanFunctionExpression.h @@ -0,0 +1,63 @@ +/* + * BinaryBooleanFunctionExpression.h + * + * Created on: 03.01.2013 + * Author: chris + */ + +#ifndef BINARYBOOLEANFUNCTIONEXPRESSION_H_ +#define BINARYBOOLEANFUNCTIONEXPRESSION_H_ + +#include "src/ir/expressions/BaseExpression.h" +#include + +namespace storm { + +namespace ir { + +namespace expressions { + +class BinaryBooleanFunctionExpression : public BaseExpression { +public: + enum FunctorType {AND, OR, XOR, IMPLIES} functor; + BaseExpression* left; + BaseExpression* right; + + BinaryBooleanFunctionExpression(BaseExpression* left, BaseExpression* right, FunctorType functor) { + this->left = left; + this->right = right; + this->functor = functor; + } + + virtual ~BinaryBooleanFunctionExpression() { + + } + + virtual std::string toString() const { + std::string result = left->toString(); + switch (functor) { + case AND: result += " & "; break; + case OR: result += " | "; break; + case XOR: result += " ^ "; break; + case IMPLIES: result += " => "; break; + } + result += right->toString(); + + return result; + } +}; + +} + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::expressions::BinaryBooleanFunctionExpression, + (storm::ir::expressions::BaseExpression*, left) + (storm::ir::expressions::BaseExpression*, right) + (storm::ir::expressions::BinaryBooleanFunctionExpression::FunctorType, functor) +) + +#endif /* BINARYBOOLEANFUNCTIONEXPRESSION_H_ */ diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h new file mode 100644 index 000000000..9df88dc91 --- /dev/null +++ b/src/ir/expressions/BinaryNumericalFunctionExpression.h @@ -0,0 +1,63 @@ +/* + * BinaryFunctionExpression.h + * + * Created on: 03.01.2013 + * Author: chris + */ + +#ifndef BINARYFUNCTIONEXPRESSION_H_ +#define BINARYFUNCTIONEXPRESSION_H_ + +#include "src/ir/expressions/BaseExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class BinaryNumericalFunctionExpression : public BaseExpression { +public: + BaseExpression* left; + BaseExpression* right; + enum FunctorType {PLUS, MINUS, TIMES, DIVIDE} functor; + + BinaryNumericalFunctionExpression(BaseExpression* left, BaseExpression* right, FunctorType functor) { + this->left = left; + this->right = right; + this->functor = functor; + } + + virtual ~BinaryNumericalFunctionExpression() { + + } + + virtual std::string toString() const { + std::string result = left->toString(); + switch (functor) { + case PLUS: result += " + "; break; + case MINUS: result += " - "; break; + case TIMES: result += " * "; break; + case DIVIDE: result += " / "; break; + } + result += right->toString(); + + return result; + } + +}; + +} + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::expressions::BinaryNumericalFunctionExpression, + (storm::ir::expressions::BaseExpression*, left) + (storm::ir::expressions::BaseExpression*, right) + (storm::ir::expressions::BinaryNumericalFunctionExpression::FunctorType, functor) +) + +#endif /* BINARYFUNCTIONEXPRESSION_H_ */ diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h new file mode 100644 index 000000000..f765d0d85 --- /dev/null +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -0,0 +1,64 @@ +/* + * BinaryRelationExpression.h + * + * Created on: 03.01.2013 + * Author: chris + */ + +#ifndef BINARYRELATIONEXPRESSION_H_ +#define BINARYRELATIONEXPRESSION_H_ + +#include "src/ir/expressions/BaseExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class BinaryRelationExpression : public BaseExpression { +public: + BaseExpression* left; + BaseExpression* right; + enum RelationType {EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL} relation; + + BinaryRelationExpression(BaseExpression* left, BaseExpression* right, RelationType relation) { + this->left = left; + this->right = right; + this->relation = relation; + } + + virtual ~BinaryRelationExpression() { + + } + + virtual std::string toString() const { + std::string result = left->toString(); + switch (relation) { + case EQUAL: result += " == "; break; + case LESS: result += " < "; break; + case LESS_OR_EQUAL: result += " <= "; break; + case GREATER: result += " > "; break; + case GREATER_OR_EQUAL: result += " >= "; break; + } + result += right->toString(); + + return result; + } + +}; + +} + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::expressions::BinaryRelationExpression, + (storm::ir::expressions::BaseExpression*, left) + (storm::ir::expressions::BaseExpression*, right) + (storm::ir::expressions::BinaryRelationExpression::RelationType, relation) +) + +#endif /* BINARYRELATIONEXPRESSION_H_ */ diff --git a/src/ir/expressions/BooleanLiteral.h b/src/ir/expressions/BooleanLiteral.h new file mode 100644 index 000000000..c2300cded --- /dev/null +++ b/src/ir/expressions/BooleanLiteral.h @@ -0,0 +1,51 @@ +/* + * BooleanLiteral.h + * + * Created on: 03.01.2013 + * Author: chris + */ + +#ifndef BOOLEANLITERAL_H_ +#define BOOLEANLITERAL_H_ + +#include "src/ir/expressions/BaseExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class BooleanLiteral : public BaseExpression { +public: + bool value; + + BooleanLiteral(bool value) { + this->value = value; + } + + virtual ~BooleanLiteral() { + + } + + virtual std::string toString() const { + if (value) { + return std::string("true"); + } else { + return std::string("false"); + } + } +}; + +} + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::expressions::BooleanLiteral, + (bool, value) +) + +#endif /* BOOLEANLITERAL_H_ */ diff --git a/src/ir/expressions/ConstantExpression.h b/src/ir/expressions/ConstantExpression.h new file mode 100644 index 000000000..38581d1e4 --- /dev/null +++ b/src/ir/expressions/ConstantExpression.h @@ -0,0 +1,47 @@ +/* + * ConstantExpression.h + * + * Created on: 03.01.2013 + * Author: chris + */ + +#ifndef CONSTANTEXPRESSION_H_ +#define CONSTANTEXPRESSION_H_ + +#include "src/ir/expressions/BaseExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class ConstantExpression : public BaseExpression { +public: + std::string constantName; + + ConstantExpression(std::string constantName) { + this->constantName = constantName; + } + + virtual ~ConstantExpression() { + + } + + virtual std::string toString() const { + return constantName; + } +}; + +} + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::expressions::ConstantExpression, + (std::string, constantName) +) + +#endif /* CONSTANTEXPRESSION_H_ */ diff --git a/src/ir/expressions/DoubleLiteral.h b/src/ir/expressions/DoubleLiteral.h new file mode 100644 index 000000000..8aca54125 --- /dev/null +++ b/src/ir/expressions/DoubleLiteral.h @@ -0,0 +1,47 @@ +/* + * DoubleLiteral.h + * + * Created on: 03.01.2013 + * Author: chris + */ + +#ifndef DOUBLELITERAL_H_ +#define DOUBLELITERAL_H_ + +#include "src/ir/expressions/BaseExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class DoubleLiteral : public BaseExpression { +public: + double value; + + DoubleLiteral(double value) { + this->value = value; + } + + virtual ~DoubleLiteral() { + + } + + virtual std::string toString() const { + return boost::lexical_cast(value); + } +}; + +} + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::expressions::DoubleLiteral, + (double, value) +) + +#endif /* DOUBLELITERAL_H_ */ diff --git a/src/ir/expressions/Expressions.h b/src/ir/expressions/Expressions.h new file mode 100644 index 000000000..868fff365 --- /dev/null +++ b/src/ir/expressions/Expressions.h @@ -0,0 +1,21 @@ +/* + * Expressions.h + * + * Created on: 03.01.2013 + * Author: chris + */ + +#ifndef EXPRESSIONS_H_ +#define EXPRESSIONS_H_ + +#include "BinaryBooleanFunctionExpression.h" +#include "BinaryNumericalFunctionExpression.h" +#include "BinaryRelationExpression.h" +#include "BooleanLiteral.h" +#include "DoubleLiteral.h" +#include "IntegerLiteral.h" +#include "UnaryBooleanFunctionExpression.h" +#include "UnaryNumericalFunctionExpression.h" +#include "VariableExpression.h" + +#endif /* EXPRESSIONS_H_ */ diff --git a/src/ir/expressions/IntegerLiteral.h b/src/ir/expressions/IntegerLiteral.h new file mode 100644 index 000000000..bea4c1743 --- /dev/null +++ b/src/ir/expressions/IntegerLiteral.h @@ -0,0 +1,47 @@ +/* + * IntegerLiteral.h + * + * Created on: 03.01.2013 + * Author: chris + */ + +#ifndef INTEGERLITERAL_H_ +#define INTEGERLITERAL_H_ + +#include "src/ir/expressions/BaseExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class IntegerLiteral : public BaseExpression { +public: + int value; + + IntegerLiteral(int value) { + this->value = value; + } + + virtual ~IntegerLiteral() { + + } + + virtual std::string toString() const { + return boost::lexical_cast(value); + } +}; + +} + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::expressions::IntegerLiteral, + (int, value) +) + +#endif /* INTEGERLITERAL_H_ */ diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.h b/src/ir/expressions/UnaryBooleanFunctionExpression.h new file mode 100644 index 000000000..14c75a87f --- /dev/null +++ b/src/ir/expressions/UnaryBooleanFunctionExpression.h @@ -0,0 +1,56 @@ +/* + * UnaryBooleanFunctionExpression.h + * + * Created on: 03.01.2013 + * Author: chris + */ + +#ifndef UNARYBOOLEANFUNCTIONEXPRESSION_H_ +#define UNARYBOOLEANFUNCTIONEXPRESSION_H_ + +#include "src/ir/expressions/BaseExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class UnaryBooleanFunctionExpression : public BaseExpression { +public: + BaseExpression* child; + enum FunctorType {NOT} functor; + + UnaryBooleanFunctionExpression(BaseExpression* child, FunctorType functor) { + this->child = child; + this->functor = functor; + } + + virtual ~UnaryBooleanFunctionExpression() { + + } + + virtual std::string toString() const { + std::string result = ""; + switch (functor) { + case NOT: result += "!"; break; + } + result += child->toString(); + + return result; + } +}; + +} + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::expressions::UnaryBooleanFunctionExpression, + (storm::ir::expressions::BaseExpression*, child) + (storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType, functor) +) + +#endif /* UNARYBOOLEANFUNCTIONEXPRESSION_H_ */ diff --git a/src/ir/expressions/UnaryNumericalFunctionExpression.h b/src/ir/expressions/UnaryNumericalFunctionExpression.h new file mode 100644 index 000000000..c367cffd2 --- /dev/null +++ b/src/ir/expressions/UnaryNumericalFunctionExpression.h @@ -0,0 +1,56 @@ +/* + * UnaryFunctionExpression.h + * + * Created on: 03.01.2013 + * Author: chris + */ + +#ifndef UNARYFUNCTIONEXPRESSION_H_ +#define UNARYFUNCTIONEXPRESSION_H_ + +#include "src/ir/expressions/BaseExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class UnaryNumericalFunctionExpression : public BaseExpression { +public: + BaseExpression* child; + enum FunctorType {MINUS} functor; + + UnaryNumericalFunctionExpression(BaseExpression* child, FunctorType functor) { + this->child = child; + this->functor = functor; + } + + virtual ~UnaryNumericalFunctionExpression() { + + } + + virtual std::string toString() const { + std::string result = ""; + switch (functor) { + case MINUS: result += "-"; break; + } + result += child->toString(); + + return result; + } +}; + +} + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::expressions::UnaryNumericalFunctionExpression, + (storm::ir::expressions::BaseExpression*, child) + (storm::ir::expressions::UnaryNumericalFunctionExpression::FunctorType, functor) +) + +#endif /* UNARYFUNCTIONEXPRESSION_H_ */ diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h new file mode 100644 index 000000000..9a1121503 --- /dev/null +++ b/src/ir/expressions/VariableExpression.h @@ -0,0 +1,47 @@ +/* + * VariableExpression.h + * + * Created on: 03.01.2013 + * Author: chris + */ + +#ifndef VARIABLEEXPRESSION_H_ +#define VARIABLEEXPRESSION_H_ + +#include "src/ir/expressions/BaseExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class VariableExpression : public BaseExpression { +public: + std::string variableName; + + VariableExpression(std::string variableName) { + this->variableName = variableName; + } + + virtual ~VariableExpression() { + + } + + virtual std::string toString() const { + return variableName; + } +}; + +} + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::expressions::VariableExpression, + (std::string, variableName) +) + +#endif /* VARIABLEEXPRESSION_H_ */ diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 5b74df99a..a8073bb95 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -15,25 +15,7 @@ #include #include -namespace storm { -namespace parser { -class intConstDef { -public: - std::string name; - int value; - - void print() { - std::cout << "(" << name << ", " << value << ")" << std::endl; - } -}; -} -} - -BOOST_FUSION_ADAPT_STRUCT( - storm::parser::intConstDef, - (std::string, name) - (int, value) -) +#include "src/ir/expressions/Expressions.h" namespace storm { @@ -41,6 +23,7 @@ namespace parser { namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; +namespace phoenix = boost::phoenix; class PrismParser { @@ -51,7 +34,7 @@ public: std::string::const_iterator end = str.end(); prismGrammar grammar; - intConstDef result; + storm::ir::expressions::BaseExpression* result; bool r = phrase_parse(iter, end, grammar, ascii::space, result); std::cout << r << std::endl; @@ -59,8 +42,7 @@ public: if (r && iter == end) { std::cout << "-------------------------\n"; std::cout << "Parsing succeeded\n"; - result.print(); - // std::cout << "result = " << result << std::endl; + std::cout << "result = " << result << std::endl; std::cout << "-------------------------\n"; } else { std::string rest(iter, end); @@ -72,19 +54,59 @@ public: } private: + struct keywords_ : qi::symbols { + keywords_() { + add + ("dtmc", 1) + ("ctmc", 2) + ("mdp", 3) + ("ctmdp", 4) + ("const", 5) + ("int", 6) + ("bool", 7) + ("module", 8) + ("endmodule", 9) + ("rewards", 10) + ("endrewards", 11) + ("true", 12) + ("false", 13) + ; + } + }; + + struct variables_ : qi::symbols { + // Intentionally left empty. This map is filled during parsing. + }; + + struct modules_ : qi::symbols { + // Intentionally left empty. This map is filled during parsing. + }; + template - struct prismGrammar : qi::grammar { + struct prismGrammar : qi::grammar { prismGrammar() : prismGrammar::base_type(start) { - identifierName %= +(qi::char_); - integerConstantDefinition %= qi::lit("const") >> qi::lit("int") >> identifierName >> "=" >> qi::int_ >> ";"; + // identifierName %= qi::lexeme[qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9")]; + // integerConstantDefinition %= qi::lit("const") >> qi::lit("int") >> identifierName >> "=" >> qi::int_ >> ";"; + + start %= literalExpression; - start %= integerConstantDefinition; + literalExpression %= (booleanLiteralExpression | integerLiteralExpression | doubleLiteralExpression); + booleanLiteralExpression = qi::bool_[qi::_val = phoenix::new_(qi::_1)]; + integerLiteralExpression = qi::int_[qi::_val = phoenix::new_(qi::_1)]; + doubleLiteralExpression = qi::double_[qi::_val = phoenix::new_(qi::_1)]; } - qi::rule start; - qi::rule integerConstantDefinition; - qi::rule identifierName; + qi::rule start; + + // The expression rules. + qi::rule literalExpression; + qi::rule booleanLiteralExpression; + qi::rule integerLiteralExpression; + qi::rule doubleLiteralExpression; + + // qi::rule integerConstantDefinition; + // qi::rule identifierName; }; }; From a4b7b2782907349d78e5f78613194daef3cb0e84 Mon Sep 17 00:00:00 2001 From: dehnert Date: Fri, 4 Jan 2013 23:38:45 +0100 Subject: [PATCH 003/152] Added parsing support for expressions. Now working on parsing probabilistic programs. --- src/ir/Module.h | 24 ++ src/ir/Program.h | 35 +++ src/ir/RewardModel.h | 24 ++ .../expressions/BooleanConstantExpression.h | 66 +++++ src/ir/expressions/DoubleConstantExpression.h | 66 +++++ src/ir/expressions/Expressions.h | 3 + .../expressions/IntegerConstantExpression.h | 66 +++++ src/parser/PrismParser.h | 237 +++++++++++++----- 8 files changed, 465 insertions(+), 56 deletions(-) create mode 100644 src/ir/Module.h create mode 100644 src/ir/Program.h create mode 100644 src/ir/RewardModel.h create mode 100644 src/ir/expressions/BooleanConstantExpression.h create mode 100644 src/ir/expressions/DoubleConstantExpression.h create mode 100644 src/ir/expressions/IntegerConstantExpression.h diff --git a/src/ir/Module.h b/src/ir/Module.h new file mode 100644 index 000000000..d61a42add --- /dev/null +++ b/src/ir/Module.h @@ -0,0 +1,24 @@ +/* + * Module.h + * + * Created on: 04.01.2013 + * Author: chris + */ + +#ifndef MODULE_H_ +#define MODULE_H_ + +namespace storm { + +namespace ir { + +class Module { + +}; + +} + +} + + +#endif /* MODULE_H_ */ diff --git a/src/ir/Program.h b/src/ir/Program.h new file mode 100644 index 000000000..70797f40f --- /dev/null +++ b/src/ir/Program.h @@ -0,0 +1,35 @@ +/* + * Program.h + * + * Created on: 04.01.2013 + * Author: chris + */ + +#ifndef PROGRAM_H_ +#define PROGRAM_H_ + +#include "src/ir/expressions/ConstantExpression.h" +#include "Module.h" +#include "RewardModel.h" + +namespace storm { + +namespace ir { + +class Program { +public: + enum ModelType {DTMC, CTMC, MDP, CTMDP} modelType; + std::map undefinedConstantExpressions; + std::vector modules; + std::map rewards; + + std::string toString() { + return std::string("prog!"); + } +}; + +} + +} + +#endif /* PROGRAM_H_ */ diff --git a/src/ir/RewardModel.h b/src/ir/RewardModel.h new file mode 100644 index 000000000..b53194668 --- /dev/null +++ b/src/ir/RewardModel.h @@ -0,0 +1,24 @@ +/* + * RewardModel.h + * + * Created on: 04.01.2013 + * Author: chris + */ + +#ifndef REWARDMODEL_H_ +#define REWARDMODEL_H_ + +namespace storm { + +namespace ir { + +class RewardModel { + +}; + +} + +} + + +#endif /* REWARDMODEL_H_ */ diff --git a/src/ir/expressions/BooleanConstantExpression.h b/src/ir/expressions/BooleanConstantExpression.h new file mode 100644 index 000000000..5d36598b2 --- /dev/null +++ b/src/ir/expressions/BooleanConstantExpression.h @@ -0,0 +1,66 @@ +/* + * BooleanConstantExpression.h + * + * Created on: 04.01.2013 + * Author: chris + */ + +#ifndef BOOLEANCONSTANTEXPRESSION_H_ +#define BOOLEANCONSTANTEXPRESSION_H_ + +#include "ConstantExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class BooleanConstantExpression : public ConstantExpression { +public: + BooleanConstantExpression(std::string constantName) : ConstantExpression(constantName) { + defined = false; + value = false; + } + + virtual ~BooleanConstantExpression() { + + } + + virtual std::string toString() const { + std::string result = this->constantName; + if (defined) { + result += "[" + boost::lexical_cast(value) + "]"; + } + return result; + } + + bool isDefined() { + return defined; + } + + bool getValue() { + return value; + } + + void define(bool value) { + defined = true; + this->value = value; + } + + bool value; + bool defined; +}; + +} + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::expressions::BooleanConstantExpression, + (std::string, constantName) +) + +#endif /* BOOLEANCONSTANTEXPRESSION_H_ */ diff --git a/src/ir/expressions/DoubleConstantExpression.h b/src/ir/expressions/DoubleConstantExpression.h new file mode 100644 index 000000000..6969965ae --- /dev/null +++ b/src/ir/expressions/DoubleConstantExpression.h @@ -0,0 +1,66 @@ +/* + * DoubleConstantExpression.h + * + * Created on: 04.01.2013 + * Author: chris + */ + +#ifndef DOUBLECONSTANTEXPRESSION_H_ +#define DOUBLECONSTANTEXPRESSION_H_ + +#include "ConstantExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class DoubleConstantExpression : public ConstantExpression { +public: + DoubleConstantExpression(std::string constantName) : ConstantExpression(constantName) { + defined = false; + value = 0.0; + } + + virtual ~DoubleConstantExpression() { + + } + + virtual std::string toString() const { + std::string result = this->constantName; + if (defined) { + result += "[" + boost::lexical_cast(value) + "]"; + } + return result; + } + + bool isDefined() { + return defined; + } + + double getValue() { + return value; + } + + void define(double value) { + defined = true; + this->value = value; + } + + double value; + bool defined; +}; + +} + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::expressions::DoubleConstantExpression, + (std::string, constantName) +) + +#endif /* DOUBLECONSTANTEXPRESSION_H_ */ diff --git a/src/ir/expressions/Expressions.h b/src/ir/expressions/Expressions.h index 868fff365..5a69dc34c 100644 --- a/src/ir/expressions/Expressions.h +++ b/src/ir/expressions/Expressions.h @@ -17,5 +17,8 @@ #include "UnaryBooleanFunctionExpression.h" #include "UnaryNumericalFunctionExpression.h" #include "VariableExpression.h" +#include "BooleanConstantExpression.h" +#include "IntegerConstantExpression.h" +#include "DoubleConstantExpression.h" #endif /* EXPRESSIONS_H_ */ diff --git a/src/ir/expressions/IntegerConstantExpression.h b/src/ir/expressions/IntegerConstantExpression.h new file mode 100644 index 000000000..d0df521af --- /dev/null +++ b/src/ir/expressions/IntegerConstantExpression.h @@ -0,0 +1,66 @@ +/* + * IntegerConstantExpression.h + * + * Created on: 04.01.2013 + * Author: chris + */ + +#ifndef INTEGERCONSTANTEXPRESSION_H_ +#define INTEGERCONSTANTEXPRESSION_H_ + +#include "ConstantExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class IntegerConstantExpression : public ConstantExpression { +public: + IntegerConstantExpression(std::string constantName) : ConstantExpression(constantName) { + defined = false; + value = 0; + } + + virtual ~IntegerConstantExpression() { + + } + + virtual std::string toString() const { + std::string result = this->constantName; + if (defined) { + result += "[" + boost::lexical_cast(value) + "]"; + } + return result; + } + + bool isDefined() { + return defined; + } + + int getValue() { + return value; + } + + void define(int value) { + defined = true; + this->value = value; + } + + int value; + bool defined; +}; + +} + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::expressions::IntegerConstantExpression, + (std::string, constantName) +) + +#endif /* INTEGERCONSTANTEXPRESSION_H_ */ diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index a8073bb95..61bf5b63f 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -9,13 +9,12 @@ #define PRISMPARSER_H_ #include -#include -#include -#include +#include #include #include #include "src/ir/expressions/Expressions.h" +#include "src/ir/Program.h" namespace storm { @@ -29,85 +28,211 @@ class PrismParser { public: void test() { - std::string str = "const int ab = 10;"; - std::string::const_iterator iter = str.begin(); - std::string::const_iterator end = str.end(); - prismGrammar grammar; + std::string testInput = ""; + // storm::ir::Program* result = getProgram(testInput); + getProgram(testInput); + +/* std::cout << "Resulting program:" << std::endl; + std::cout << "-------------------------\n"; + std::cout << result->toString() << std::endl; + std::cout << "-------------------------\n"; */ + } - storm::ir::expressions::BaseExpression* result; - bool r = phrase_parse(iter, end, grammar, ascii::space, result); + void getProgram(std::string inputString) { + using qi::_val; + using qi::int_; + using qi::_r1; + using qi::_1; + using phoenix::ref; + using phoenix::val; - std::cout << r << std::endl; + prismGrammar grammar; + std::string::const_iterator it = inputString.begin(); + std::string::const_iterator end = inputString.end(); + storm::ir::Program result; - if (r && iter == end) { - std::cout << "-------------------------\n"; - std::cout << "Parsing succeeded\n"; - std::cout << "result = " << result << std::endl; - std::cout << "-------------------------\n"; + int resultInt = 0; + std::string input = "asdf"; + bool r = phrase_parse(it, end, grammar(phoenix::val(input)), ascii::space, resultInt); + + if (r && it == end) { + std::cout << "Parsing successful!" << std::endl; } else { - std::string rest(iter, end); + std::string rest(it, end); std::cout << "-------------------------\n"; std::cout << "Parsing failed\n"; - std::cout << "stopped at: " << rest << "\"\n"; + std::cout << "stopped at: \"" << rest << "\"\n"; std::cout << "-------------------------\n"; } } private: - struct keywords_ : qi::symbols { - keywords_() { - add - ("dtmc", 1) - ("ctmc", 2) - ("mdp", 3) - ("ctmdp", 4) - ("const", 5) - ("int", 6) - ("bool", 7) - ("module", 8) - ("endmodule", 9) - ("rewards", 10) - ("endrewards", 11) - ("true", 12) - ("false", 13) - ; - } - }; - - struct variables_ : qi::symbols { - // Intentionally left empty. This map is filled during parsing. - }; - - struct modules_ : qi::symbols { - // Intentionally left empty. This map is filled during parsing. - }; - template - struct prismGrammar : qi::grammar { + struct prismGrammar : qi::grammar { prismGrammar() : prismGrammar::base_type(start) { - // identifierName %= qi::lexeme[qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9")]; - // integerConstantDefinition %= qi::lit("const") >> qi::lit("int") >> identifierName >> "=" >> qi::int_ >> ";"; - - start %= literalExpression; + using qi::_val; + using qi::int_; + using qi::_r1; + using qi::_1; + using phoenix::ref; + + // start = constantDefinitionList(phoenix::ref(qi::_r1), phoenix::ref(qi::_r1)); + start = qi::lit(qi::_r1) >> int_; + constantDefinitionList = qi::int_; + + variableDefinition %= (booleanVariableDefinition | integerVariableDefinition); + booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") >> qi::lit(";"))[phoenix::bind(booleanVariables_.add, qi::_1, phoenix::new_(qi::_1)), phoenix::bind(allVariables_.add, qi::_1, phoenix::new_(qi::_1)), qi::_val = phoenix::new_(qi::_1)]; + integerVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("[") >> integerConstantExpression >> qi::lit("..") >> integerConstantExpression >> qi::lit("]") >> qi::lit(";"))[phoenix::bind(integerVariables_.add, qi::_1, phoenix::new_(qi::_1)), phoenix::bind(allVariables_.add, qi::_1, phoenix::new_(qi::_1)), qi::_val = phoenix::new_(qi::_1)]; + + constantDefinition %= (definedConstantDefinition | undefinedConstantDefinition); + definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); + undefinedConstantDefinition %= (undefinedBooleanConstantDefinition | undefinedIntegerConstantDefinition | undefinedDoubleConstantDefinition); + definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") >> booleanLiteralExpression >> qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") >> integerLiteralExpression >> qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") >> doubleLiteralExpression >> qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, phoenix::new_(qi::_1)), phoenix::bind(allConstants_.add, qi::_1, phoenix::new_(qi::_1)), qi::_val = phoenix::new_(qi::_1)]; + undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, phoenix::new_(qi::_1)), phoenix::bind(allConstants_.add, qi::_1, phoenix::new_(qi::_1)), qi::_val = phoenix::new_(qi::_1)]; + undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, phoenix::new_(qi::_1)), phoenix::bind(allConstants_.add, qi::_1, phoenix::new_(qi::_1)), qi::_val = phoenix::new_(qi::_1)]; + + expression %= (booleanExpression | integerExpression | doubleExpression); + + booleanExpression %= orExpression; + orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::OR)]; + andExpression = atomicBooleanExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> atomicBooleanExpression)[qi::_val = phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND)]; + atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression); + relativeExpression = (integerExpression >> relations_ >> integerExpression)[qi::_val = phoenix::new_(qi::_1, qi::_3, qi::_2)]; + + integerExpression %= integerPlusExpression; + integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> integerMultExpression)[qi::_val = phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS)]; + integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES)]; + atomicIntegerExpression %= (integerVariableExpression | qi::lit("(") >> integerExpression >> qi::lit(")") | integerConstantExpression); + + doubleExpression %= doublePlusExpression; + doublePlusExpression = doubleMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> doubleMultExpression)[qi::_val = phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS)]; + doubleMultExpression %= atomicDoubleExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicDoubleExpression)[qi::_val = phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES)]; + atomicDoubleExpression %= (qi::lit("(") >> doubleExpression >> qi::lit(")") | doubleConstantExpression); literalExpression %= (booleanLiteralExpression | integerLiteralExpression | doubleLiteralExpression); booleanLiteralExpression = qi::bool_[qi::_val = phoenix::new_(qi::_1)]; integerLiteralExpression = qi::int_[qi::_val = phoenix::new_(qi::_1)]; doubleLiteralExpression = qi::double_[qi::_val = phoenix::new_(qi::_1)]; - } - qi::rule start; + constantExpression %= (booleanConstantExpression | integerConstantExpression | doubleConstantExpression); + booleanConstantExpression %= (booleanConstants_ | booleanLiteralExpression); + integerConstantExpression %= (integerConstants_ | integerLiteralExpression); + doubleConstantExpression %= (doubleConstants_ | doubleLiteralExpression); - // The expression rules. + variableExpression = (integerVariableExpression | booleanVariableExpression); + integerVariableExpression = integerVariables_; + booleanVariableExpression = booleanVariables_; + + freeIdentifierName %= qi::lexeme[(qi::alpha >> *(qi::alnum)) - allVariables_ - allConstants_]; + } + + // The starting point of the grammar. + qi::rule start; + + qi::rule constantDefinitionList; + + qi::rule variableDefinition; + qi::rule booleanVariableDefinition; + qi::rule integerVariableDefinition; + + qi::rule constantDefinition; + qi::rule undefinedConstantDefinition; + qi::rule definedConstantDefinition; + qi::rule undefinedBooleanConstantDefinition; + qi::rule undefinedIntegerConstantDefinition; + qi::rule undefinedDoubleConstantDefinition; + qi::rule definedBooleanConstantDefinition; + qi::rule definedIntegerConstantDefinition; + qi::rule definedDoubleConstantDefinition; + + qi::rule freeIdentifierName; + + // The starting point for arbitrary expressions. + qi::rule expression; + + // Rules with boolean result type. + qi::rule booleanExpression; + qi::rule orExpression; + qi::rule andExpression; + qi::rule atomicBooleanExpression; + qi::rule relativeExpression; + + // Rules with integer result type. + qi::rule integerExpression; + qi::rule integerPlusExpression; + qi::rule integerMultExpression; + qi::rule atomicIntegerExpression; + + // Rules with double result type. + qi::rule doubleExpression; + qi::rule doublePlusExpression; + qi::rule doubleMultExpression; + qi::rule atomicDoubleExpression; + + // Rules for variable recognition. + qi::rule variableExpression; + qi::rule booleanVariableExpression; + qi::rule integerVariableExpression; + + // Rules for constant recognition. + qi::rule constantExpression; + qi::rule booleanConstantExpression; + qi::rule integerConstantExpression; + qi::rule doubleConstantExpression; + + // Rules for literal recognition. qi::rule literalExpression; qi::rule booleanLiteralExpression; qi::rule integerLiteralExpression; qi::rule doubleLiteralExpression; - // qi::rule integerConstantDefinition; - // qi::rule identifierName; - + struct keywordsStruct : qi::symbols { + keywordsStruct() { + add + ("dtmc", 1) + ("ctmc", 2) + ("mdp", 3) + ("ctmdp", 4) + ("const", 5) + ("int", 6) + ("bool", 7) + ("module", 8) + ("endmodule", 9) + ("rewards", 10) + ("endrewards", 11) + ("true", 12) + ("false", 13) + ; + } + } keywords_; + + struct relationalOperatorStruct : qi::symbols { + relationalOperatorStruct() { + add + ("==", storm::ir::expressions::BinaryRelationExpression::EQUAL) + ("<", storm::ir::expressions::BinaryRelationExpression::LESS) + ("<=", storm::ir::expressions::BinaryRelationExpression::LESS_OR_EQUAL) + (">", storm::ir::expressions::BinaryRelationExpression::GREATER) + (">=", storm::ir::expressions::BinaryRelationExpression::GREATER_OR_EQUAL) + ; + } + } relations_; + + struct variablesStruct : qi::symbols { + // Intentionally left empty. This map is filled during parsing. + } integerVariables_, booleanVariables_, allVariables_ ; + + struct constantsStruct : qi::symbols { + // Intentionally left empty. This map is filled during parsing. + } integerConstants_, booleanConstants_, doubleConstants_, allConstants_; + + struct modulesStruct : qi::symbols { + // Intentionally left empty. This map is filled during parsing. + } modules_; }; }; From b381321653701a99551f86c496911495af213499 Mon Sep 17 00:00:00 2001 From: dehnert Date: Tue, 8 Jan 2013 22:34:51 +0100 Subject: [PATCH 004/152] Added more classes to IR. Extended PRISM-format parser. --- CMakeLists.txt | 2 +- FindPantheios.cmake | 466 ------------------ FindSTLSoft.cmake | 56 --- src/ir/Assignment.h | 35 ++ src/ir/BooleanVariable.h | 43 ++ src/ir/Command.h | 40 ++ src/ir/IR.h | 22 + src/ir/IntegerVariable.h | 51 ++ src/ir/Module.h | 41 ++ src/ir/Program.h | 41 +- src/ir/Update.h | 33 ++ src/ir/Variable.h | 45 ++ .../BinaryBooleanFunctionExpression.h | 10 +- .../BinaryNumericalFunctionExpression.h | 10 +- src/ir/expressions/BinaryRelationExpression.h | 10 +- src/ir/expressions/Expressions.h | 1 + .../UnaryBooleanFunctionExpression.h | 6 +- .../UnaryNumericalFunctionExpression.h | 6 +- src/parser/PrctlParser.cpp | 147 ------ src/parser/PrctlParser.h | 33 -- src/parser/PrismParser.h | 237 ++++----- src/storm.cpp | 4 +- 22 files changed, 501 insertions(+), 838 deletions(-) delete mode 100644 FindPantheios.cmake delete mode 100644 FindSTLSoft.cmake create mode 100644 src/ir/Assignment.h create mode 100644 src/ir/BooleanVariable.h create mode 100644 src/ir/Command.h create mode 100644 src/ir/IR.h create mode 100644 src/ir/IntegerVariable.h create mode 100644 src/ir/Update.h create mode 100644 src/ir/Variable.h delete mode 100644 src/parser/PrctlParser.cpp delete mode 100644 src/parser/PrctlParser.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c4f2aec85..df1e897f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,7 @@ elseif(MSVC) else(CLANG) # Set standard flags for clang set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -funroll-loops") - set (CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Wall -Werror -pedantic -Wno-unused-variable") + set (CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Wall -Werror -pedantic -Wno-unused-variable -DBOOST_RESULT_OF_USE_TR1 -DBOOST_NO_DECLTYPE") # Turn on popcnt instruction if desired (yes by default) if (USE_POPCNT) diff --git a/FindPantheios.cmake b/FindPantheios.cmake deleted file mode 100644 index bfc5f39ad..000000000 --- a/FindPantheios.cmake +++ /dev/null @@ -1,466 +0,0 @@ -# Locate the Pantheois Logging Framework. -# -# Defines the following variables: -# -# PANTHEIOS_FOUND - Found the Pantheios Logging Framework -# PANTHEIOS_INCLUDE_DIRS - Include directories -# -# Accepts the following variables as input: -# -# PANTHEIOS_ROOT - (as a CMake or environment variable) -# The root directory of the pantheios install prefix -# -# PANTHEIOS_USE_DYNAMIC_RUNTIME -# -# If you want to use splitting, specify LRSplit and than preface the components with L and R, so e.g. LRSplit LFile RSyslog -# To use more than one BackEnd, specify NBackEnd followed by a list of components. NBackEnd requires the NFrontEnd. -# -# Possible Components for BackEnd: -# ACELogger -# COMErrorObject -# File -# FileCallback -# FPrintf -# FPrintfCallback -# Null -# Speech -# Syslog -# WindowsConsole -# WindowsConsoleCallback -# WindowsDebugger -# WindowsDebuggerCallback -# WindowsEventLog -# WindowsMessageBox -# WindowsSyslog -# WindowsSyslogCallback -# -# Possible components for FrontEnd: -# NoFrontEnd -# SimpleFrontEnd -# NFrontEnd -# -# - -#============================================================================= -# Copyright 2012 Philipp Berger -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) -# -# Credits: -# -# HUGE thanks to Michael Wild -# Additional thanks to: -# Mateusz Loskot -# Rolf Eike Beer - - - -# default for WideString option -set(PANTHEIOS_WIDESTRING 0) -# default for Front- and BackEnd -set(PANTHEIOS_FRONTEND "simple") -set(PANTHEIOS_BACKEND "file") -set(PANTHEIOS_BACKEND_L OFF) -set(PANTHEIOS_BACKEND_R OFF) -set(PANTHEIOS_BACKEND_LIST) - -# Use FIND_PACKAGE( Pantheios COMPONENTS ... ) to enable modules -if( Pantheios_FIND_COMPONENTS ) - list(FIND Pantheios_FIND_COMPONENTS "LRSplit" PANTHEIOS_use_lrsplit) - list(FIND Pantheios_FIND_COMPONENTS "NFrontEnd" PANTHEIOS_use_nfe) - list(FIND Pantheios_FIND_COMPONENTS "NBackEnd" PANTHEIOS_use_nbe) - list(FIND Pantheios_FIND_COMPONENTS "WideString" PANTHEIOS_use_ws) - - list(REMOVE_ITEM Pantheios_FIND_COMPONENTS "LRSplit" "NFrontEnd" "NBackEnd" "WideString") - - if (NOT PANTHEIOS_use_ws EQUAL -1) - # Use WideString - set(PANTHEIOS_WIDESTRING 1) - endif() - - if (NOT PANTHEIOS_use_lrsplit EQUAL -1) - # Found LRSplit - set(PANTHEIOS_BACKEND "lrsplit") - if (NOT PANTHEIOS_use_nbe EQUAL -1) - # Also found NBe - message(FATAL_ERROR "Pantheios: Use either LRSplit or NBackEnd, not both.") - endif() - if (NOT PANTHEIOS_use_nfe EQUAL -1) - # Also found NFe - message(FATAL_ERROR "Pantheios: Use either LRSplit or NFrontEnd, not both.") - endif() - - foreach( component ${Pantheios_FIND_COMPONENTS} ) - # LRSplit L BackEnds - string(SUBSTRING ${component} 0 1 _sub_comp_head) - string(LENGTH ${component} _length_comp) - math(EXPR _length_comp_tail "${_length_comp} - 1") - string(SUBSTRING ${component} 1 ${_length_comp_tail} _sub_comp_tail) - - if ((_sub_comp_tail STREQUAL "ACELogger") OR (_sub_comp_tail STREQUAL "COMErrorObject") OR (_sub_comp_tail STREQUAL "File") OR (_sub_comp_tail STREQUAL "FileCallback") OR (_sub_comp_tail STREQUAL "FPrintf") OR (_sub_comp_tail STREQUAL "FPrintfCallback") OR (_sub_comp_tail STREQUAL "Null") OR (_sub_comp_tail STREQUAL "Speech") OR (_sub_comp_tail STREQUAL "Syslog") OR (_sub_comp_tail STREQUAL "WindowsConsole") OR (_sub_comp_tail STREQUAL "WindowsConsoleCallback") OR (_sub_comp_tail STREQUAL "WindowsDebugger") OR (_sub_comp_tail STREQUAL "WindowsDebuggerCallback") OR (_sub_comp_tail STREQUAL "WindowsEventLog") OR (_sub_comp_tail STREQUAL "WindowsMessageBox") OR (_sub_comp_tail STREQUAL "WindowsSyslog") OR (_sub_comp_tail STREQUAL "WindowsSyslogCallback")) - if ((_sub_comp_head STREQUAL L) OR (_sub_comp_head STREQUAL R)) - message(STATUS "Pantheios: Setting LRSplit BackEnd ${_sub_comp_head} to ${_sub_comp_tail}") - string(TOLOWER ${_sub_comp_tail} _sub_comp_tail_low) - set(PANTHEIOS_BACKEND_${_sub_comp_head} "${_sub_comp_tail_low}") - else () - message(FATAL_ERROR "Pantheios: Internal Parsing Error") - endif() - - # FrontEnds - elseif (component STREQUAL "NoFrontEnd") - message(STATUS "Pantheios: Setting FrontEnd to NoFrontEnd") - set(PANTHEIOS_FRONTEND "null") - elseif (component STREQUAL "SimpleFrontEnd") - message(STATUS "Pantheios: Setting FrontEnd to SimpleFrontEnd") - set(PANTHEIOS_FRONTEND "simple") - - else () - message(FATAL_ERROR "Unknown Component: ${component}") - endif () - endforeach(component) - elseif (NOT PANTHEIOS_use_nbe EQUAL -1) - # Found NBackEnd - if (PANTHEIOS_use_nfe EQUAL -1) - message(FATAL_ERROR "Pantheios: Usage of NBackEnd requires the NFrontEnd.") - endif() - set(PANTHEIOS_BACKEND "N") - set(PANTHEIOS_FRONTEND "N") - - foreach( component ${Pantheios_FIND_COMPONENTS} ) - # Std BackEnds - if ((component STREQUAL "ACELogger") OR (component STREQUAL "COMErrorObject") OR (component STREQUAL "File") OR (component STREQUAL "FileCallback") OR (component STREQUAL "FPrintf") OR (component STREQUAL "FPrintfCallback") OR (component STREQUAL "Null") OR (component STREQUAL "Speech") OR (component STREQUAL "Syslog") OR (component STREQUAL "WindowsConsole") OR (component STREQUAL "WindowsConsoleCallback") OR (component STREQUAL "WindowsDebugger") OR (component STREQUAL "WindowsDebuggerCallback") OR (component STREQUAL "WindowsEventLog") OR (component STREQUAL "WindowsMessageBox") OR (component STREQUAL "WindowsSyslog") OR (component STREQUAL "WindowsSyslogCallback")) - message(STATUS "Pantheios: Adding BackEnd ${component}") - string(TOLOWER ${component} _low_comp) - list(APPEND PANTHEIOS_BACKEND_LIST ${_low_comp}) - else () - message(FATAL_ERROR "Unknown Component: ${component}") - endif () - endforeach(component) - else () - # Simple, one FE, one BE - foreach( component ${Pantheios_FIND_COMPONENTS} ) - if ((component STREQUAL "ACELogger") OR (component STREQUAL "COMErrorObject") OR (component STREQUAL "File") OR (component STREQUAL "FileCallback") OR (component STREQUAL "FPrintf") OR (component STREQUAL "FPrintfCallback") OR (component STREQUAL "Null") OR (component STREQUAL "Speech") OR (component STREQUAL "Syslog") OR (component STREQUAL "WindowsConsole") OR (component STREQUAL "WindowsConsoleCallback") OR (component STREQUAL "WindowsDebugger") OR (component STREQUAL "WindowsDebuggerCallback") OR (component STREQUAL "WindowsEventLog") OR (component STREQUAL "WindowsMessageBox") OR (component STREQUAL "WindowsSyslog") OR (component STREQUAL "WindowsSyslogCallback")) - message(STATUS "Pantheios: Setting BackEnd to ${component}") - string(TOLOWER ${component} _low_comp) - set(PANTHEIOS_BACKEND ${_low_comp}) - - # FrontEnds - elseif (component STREQUAL "NoFrontEnd") - message(STATUS "Pantheios: Setting FrontEnd to NoFrontEnd") - set(PANTHEIOS_FRONTEND "null") - elseif (component STREQUAL "SimpleFrontEnd") - message(STATUS "Pantheios: Setting FrontEnd to SimpleFrontEnd") - set(PANTHEIOS_FRONTEND "simple") - else () - message(FATAL_ERROR "Unknown Component: ${component}") - endif () - endforeach(component) - endif () -endif(Pantheios_FIND_COMPONENTS) - -if (PANTHEIOS_USE_DYNAMIC_RUNTIME) - set(PANTHEIOS_LIB_LINKTYPE "dll") -else () - set(PANTHEIOS_LIB_LINKTYPE "mt") -endif () - -if(PANTHEIOS_INCLUDE_DIR) - if (NOT PANTHEIOS_ROOT) - get_filename_component(PANTHEIOS_ROOT "${PANTHEIOS_INCLUDE_DIR}" PATH) - endif() - - get_filename_component(PANTHEIOS_ROOT_HINT "${PANTHEIOS_INCLUDE_DIR}" PATH) -endif() - -find_path(PANTHEIOS_INCLUDE_DIR pantheios/pantheios.h - PATH_SUFFIXES include - HINTS ${PANTHEIOS_ROOT} ${PANTHEIOS_ROOT_HINT} - ENV PANTHEIOS_ROOT -) - -# No idea what the stuff for ICC et. al. is, so I don't handle it here... -set(_P_COMP_TAG) -set(_P_OS_TAG) -set(_P_ARCH_TAG) -if(MSVC) - if(MSVC60) - set(_P_COMP_TAG vc6) - elseif(MSVC70) - set(_P_COMP_TAG vc7) - elseif(MSVC71) - set(_P_COMP_TAG vc71) - elseif(MSVC80) - set(_P_COMP_TAG vc8) - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_P_ARCH_TAG .x64) - endif() - elseif(MSVC90) - set(_P_COMP_TAG vc9) - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_P_ARCH_TAG .x64) - endif() - elseif(MSVC10) - set(_P_COMP_TAG vc10) - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_P_ARCH_TAG .x64) - endif() - elseif(MSVC11) - set(_P_COMP_TAG vc11) - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_P_ARCH_TAG .x64) - endif() - endif() -elseif(CMAKE_COMPILER_IS_GNUCC) - execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) - string(REGEX MATCHALL "[0-9]+" GCC_VERSION_COMPONENTS ${GCC_VERSION}) - list(GET GCC_VERSION_COMPONENTS 0 GCC_MAJOR) - list(GET GCC_VERSION_COMPONENTS 1 GCC_MINOR) - set(_P_COMP_TAG gcc${GCC_MAJOR}${GCC_MINOR}) - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_P_ARCH_TAG .file64bit) - endif() -else() - message(FATAL_ERROR "Pantheios: Your compiler/environment is currently unsupported.") -endif() - -set(_P_LIB_TAG ${_P_COMP_TAG}${_P_OS_TAG}${_P_ARCH_TAG}) - -# Is this the right way? -set(PANTHEIOS_INCLUDE_DIRS ${PANTHEIOS_INCLUDE_DIR}) - -set(_P_REQUIRED_LIBVARS) -set(PANTHEIOS_LIBRARIES) -set(PANTHEIOS_LIBRARIES_DEBUG) -set(PANTHEIOS_LIBRARIES_RELEASE) - - -#core and util libraries -foreach(l core util) - find_library(PANTHEIOS_${l}_${PANTHEIOS_LIB_LINKTYPE}_DEBUG_LIBRARY - pantheios.1.${l}.${_P_LIB_TAG}.${PANTHEIOS_LIB_LINKTYPE}.debug - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT - ) - - find_library(PANTHEIOS_${l}_${PANTHEIOS_LIB_LINKTYPE}_LIBRARY - pantheios.1.${l}.${_P_LIB_TAG}.${PANTHEIOS_LIB_LINKTYPE} - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT - ) - - list(APPEND _P_REQUIRED_LIBVARS - PANTHEIOS_${l}_${PANTHEIOS_LIB_LINKTYPE}_DEBUG_LIBRARY - PANTHEIOS_${l}_${PANTHEIOS_LIB_LINKTYPE}_LIBRARY - ) - list(APPEND PANTHEIOS_LIBRARIES - debug ${PANTHEIOS_${l}_${PANTHEIOS_LIB_LINKTYPE}_DEBUG_LIBRARY} - optimized ${PANTHEIOS_${l}_${PANTHEIOS_LIB_LINKTYPE}_LIBRARY} - ) -endforeach() - -# set PANTHEIOS_LIBRARY_DIRS -get_filename_component(PANTHEIOS_LIBRARY_DIRS ${PANTHEIOS_core_${PANTHEIOS_LIB_LINKTYPE}_LIBRARY} PATH) - - - -# backend libraries (split, sole, local, remote and common) -set(_P_LT ${PANTHEIOS_LIB_LINKTYPE}) -set(_P_BE ${PANTHEIOS_BACKEND}) - -find_library(PANTHEIOS_be_${_P_BE}_${_P_LT}_DEBUG_LIBRARY - pantheios.1.be.${_P_BE}.${_P_LIB_TAG}.${_P_LT}.debug - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT -) - -find_library(PANTHEIOS_be_${_P_BE}_${_P_LT}_LIBRARY - pantheios.1.be.${_P_BE}.${_P_LIB_TAG}.${_P_LT} - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT -) - -list(APPEND _P_REQUIRED_LIBVARS - PANTHEIOS_be_${_P_BE}_${_P_LT}_DEBUG_LIBRARY - PANTHEIOS_be_${_P_BE}_${_P_LT}_LIBRARY -) -list(APPEND PANTHEIOS_LIBRARIES - debug ${PANTHEIOS_be_${_P_BE}_${_P_LT}_DEBUG_LIBRARY} - optimized ${PANTHEIOS_be_${_P_BE}_${_P_LT}_LIBRARY} -) - -if (_P_BE STREQUAL N) - # N Backend, go through list - message(STATUS "Pantheios: Dbg: Lib-n") - - foreach (blib PANTHEIOS_BACKEND_LIST) - find_library(PANTHEIOS_bec_${blib}_${_P_LT}_DEBUG_LIBRARY - pantheios.1.bec.${blib}.${_P_LIB_TAG}.${_P_LT}.debug - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT - ) - - find_library(PANTHEIOS_bec_${blib}_${_P_LT}_LIBRARY - pantheios.1.bec.${blib}.${_P_LIB_TAG}.${_P_LT} - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT - ) - - list(APPEND _P_REQUIRED_LIBVARS - PANTHEIOS_bec_${blib}_${_P_LT}_DEBUG_LIBRARY - PANTHEIOS_bec_${blib}_${_P_LT}_LIBRARY - ) - list(APPEND PANTHEIOS_LIBRARIES - debug ${PANTHEIOS_bec_${blib}_${_P_LT}_DEBUG_LIBRARY} - optimized ${PANTHEIOS_bec_${blib}_${_P_LT}_LIBRARY} - ) - endforeach() -elseif (_P_BE STREQUAL lrsplit) - # LRSplit - message(STATUS "Pantheios: Dbg: Lib-lrsplit") - - # Left side - foreach (t bec bel) - find_library(PANTHEIOS_${t}_${PANTHEIOS_BACKEND_L}_${_P_LT}_DEBUG_LIBRARY - pantheios.1.${t}.${PANTHEIOS_BACKEND_L}.${_P_LIB_TAG}.${_P_LT}.debug - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT - ) - - find_library(PANTHEIOS_${t}_${PANTHEIOS_BACKEND_L}_${_P_LT}_LIBRARY - pantheios.1.${t}.${PANTHEIOS_BACKEND_L}.${_P_LIB_TAG}.${_P_LT} - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT - ) - list(APPEND _P_REQUIRED_LIBVARS - PANTHEIOS_${t}_${PANTHEIOS_BACKEND_L}_${_P_LT}_DEBUG_LIBRARY - PANTHEIOS_${t}_${PANTHEIOS_BACKEND_L}_${_P_LT}_LIBRARY - ) - list(APPEND PANTHEIOS_LIBRARIES - debug ${PANTHEIOS_${t}_${PANTHEIOS_BACKEND_L}_${_P_LT}_DEBUG_LIBRARY} - optimized ${PANTHEIOS_${t}_${PANTHEIOS_BACKEND_L}_${_P_LT}_LIBRARY} - ) - endforeach() - # Right side - foreach (t bec ber) - find_library(PANTHEIOS_${t}_${PANTHEIOS_BACKEND_R}_${_P_LT}_DEBUG_LIBRARY - pantheios.1.${t}.${PANTHEIOS_BACKEND_R}.${_P_LIB_TAG}.${_P_LT}.debug - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT - ) - - find_library(PANTHEIOS_${t}_${PANTHEIOS_BACKEND_R}_${_P_LT}_LIBRARY - pantheios.1.${t}.${PANTHEIOS_BACKEND_R}.${_P_LIB_TAG}.${_P_LT} - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT - ) - list(APPEND _P_REQUIRED_LIBVARS - PANTHEIOS_${t}_${PANTHEIOS_BACKEND_R}_${_P_LT}_DEBUG_LIBRARY - PANTHEIOS_${t}_${PANTHEIOS_BACKEND_R}_${_P_LT}_LIBRARY - ) - list(APPEND PANTHEIOS_LIBRARIES - debug ${PANTHEIOS_${t}_${PANTHEIOS_BACKEND_R}_${_P_LT}_DEBUG_LIBRARY} - optimized ${PANTHEIOS_${t}_${PANTHEIOS_BACKEND_R}_${_P_LT}_LIBRARY} - ) - endforeach() -else () - # normal - message(STATUS "Pantheios: Dbg: Lib-normal") - foreach (t bec) - find_library(PANTHEIOS_${t}_${PANTHEIOS_BACKEND}_${_P_LT}_DEBUG_LIBRARY - pantheios.1.${t}.${PANTHEIOS_BACKEND}.${_P_LIB_TAG}.${_P_LT}.debug - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT - ) - - find_library(PANTHEIOS_${t}_${PANTHEIOS_BACKEND}_${_P_LT}_LIBRARY - pantheios.1.${t}.${PANTHEIOS_BACKEND}.${_P_LIB_TAG}.${_P_LT} - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT - ) - list(APPEND _P_REQUIRED_LIBVARS - PANTHEIOS_${t}_${PANTHEIOS_BACKEND}_${_P_LT}_DEBUG_LIBRARY - PANTHEIOS_${t}_${PANTHEIOS_BACKEND}_${_P_LT}_LIBRARY - ) - list(APPEND PANTHEIOS_LIBRARIES - debug ${PANTHEIOS_${t}_${PANTHEIOS_BACKEND}_${_P_LT}_DEBUG_LIBRARY} - optimized ${PANTHEIOS_${t}_${PANTHEIOS_BACKEND}_${_P_LT}_LIBRARY} - ) - endforeach() -endif() - -# frontent libraries -set(PANTHEIOS_fe_DEBUG_LIBRARY) -set(PANTHEIOS_fe_LIBRARY) -if(NOT PANTHEIOS_FRONTENT STREQUAL null) - set(_P_FE ${PANTHEIOS_FRONTEND}) - find_library(PANTHEIOS_${_P_FE}_${_P_LT}_DEBUG_LIBRARY - pantheios.1.fe.${_P_FE}.${_P_LIB_TAG}.${_P_LT}.debug - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT - ) - find_library(PANTHEIOS_${_P_FE}_${_P_LT}_LIBRARY - pantheios.1.fe.${_P_FE}.${_P_LIB_TAG}.${_P_LT} - PATH_SUFFIXES lib - HINTS ${PANTHEIOS_ROOT_HINT} ${PANTHEIOS_ROOT} - ENV PANTHEIOS_ROOT - ) - - list(APPEND _P_REQUIRED_LIBVARS - PANTHEIOS_${_P_FE}_${_P_LT}_DEBUG_LIBRARY - PANTHEIOS_${_P_FE}_${_P_LT}_LIBRARY - ) - list(APPEND PANTHEIOS_LIBRARIES - debug ${PANTHEIOS_${_P_FE}_${_P_LT}_DEBUG_LIBRARY} - optimized ${PANTHEIOS_${_P_FE}_${_P_LT}_LIBRARY} - ) -endif() - -# gcc needs the core library mentioned a second time at the end -# (see Pantheios FAQ Q/A8) -# At this point, the core has to be found already, -# so only the additions to the lists are repeated here... -if(CMAKE_COMPILER_IS_GNUCC) - list(APPEND _P_REQUIRED_LIBVARS - PANTHEIOS_core_${PANTHEIOS_LIB_LINKTYPE}_DEBUG_LIBRARY - PANTHEIOS_core_${PANTHEIOS_LIB_LINKTYPE}_LIBRARY - ) - list(APPEND PANTHEIOS_LIBRARIES - debug ${PANTHEIOS_core_${PANTHEIOS_LIB_LINKTYPE}_DEBUG_LIBRARY} - optimized ${PANTHEIOS_core_${PANTHEIOS_LIB_LINKTYPE}_LIBRARY} - ) -endif() - -# copy to NAME_LIBS -set(PANTHEIOS_LIBS ${PANTHEIOS_LIBRARIES}) - -# handle the QUIETLY and REQUIRED arguments and set Pantheios_FOUND to TRUE if -# all listed variables are TRUE -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Pantheios - REQUIRED_VARS PANTHEIOS_INCLUDE_DIR ${_P_REQUIRED_LIBVARS} -) - -message(STATUS ${PANTHEIOS_INCLUDE_DIR} ${PANTHEIOS_LIBRARIES}) -mark_as_advanced(PANTHEIOS_INCLUDE_DIR PANTHEIOS_LIBRARIES) - diff --git a/FindSTLSoft.cmake b/FindSTLSoft.cmake deleted file mode 100644 index 5499ff851..000000000 --- a/FindSTLSoft.cmake +++ /dev/null @@ -1,56 +0,0 @@ -# Locate the STLSoft Headers. -# -# Defines the following variables: -# -# STLSOFT_FOUND - Found the Pantheios Logging Framework -# STLSOFT_INCLUDE_DIRS - Include directories -# -# Accepts the following variables as input: -# -# STLSOFT_ROOT - (as a CMake or environment variable) -# The root directory of the STLSoft install prefix -# -# - -#============================================================================= -# Copyright 2012 Philipp Berger -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) -# - - - - -if(STLSOFT_INCLUDE_DIR) - if (NOT STLSOFT_ROOT) - get_filename_component(STLSOFT_ROOT "${STLSOFT_INCLUDE_DIR}" PATH) - endif() - - get_filename_component(STLSOFT_ROOT_HINT "${STLSOFT_INCLUDE_DIR}" PATH) -endif() - -find_path(STLSOFT_INCLUDE_DIR stlsoft/stlsoft.h - PATH_SUFFIXES include - HINTS ${STLSOFT_ROOT} ${STLSOFT_ROOT_HINT} - ENV STLSOFT_ROOT -) -set(STLSOFT_INCLUDE_DIRS ${STLSOFT_INCLUDE_DIR}) - -# handle the QUIETLY and REQUIRED arguments and set STLSOFT_FOUND to TRUE if -# all listed variables are TRUE -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(STLSoft - REQUIRED_VARS STLSOFT_INCLUDE_DIR -) - - -mark_as_advanced(STLSOFT_INCLUDE_DIR) - diff --git a/src/ir/Assignment.h b/src/ir/Assignment.h new file mode 100644 index 000000000..a552bb750 --- /dev/null +++ b/src/ir/Assignment.h @@ -0,0 +1,35 @@ +/* + * Assignment.h + * + * Created on: 06.01.2013 + * Author: chris + */ + +#ifndef ASSIGNMENT_H_ +#define ASSIGNMENT_H_ + +#include "expressions/Expressions.h" +#include + +namespace storm { + +namespace ir { + +class Assignment { +public: + + std::string variableName; + std::shared_ptr expression; +}; + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::Assignment, + (std::string, variableName) + (std::shared_ptr, expression) +) + +#endif /* ASSIGNMENT_H_ */ diff --git a/src/ir/BooleanVariable.h b/src/ir/BooleanVariable.h new file mode 100644 index 000000000..71e09e4ea --- /dev/null +++ b/src/ir/BooleanVariable.h @@ -0,0 +1,43 @@ +/* + * BooleanVariable.h + * + * Created on: 08.01.2013 + * Author: chris + */ + +#ifndef BOOLEANVARIABLE_H_ +#define BOOLEANVARIABLE_H_ + +namespace storm { + +namespace ir { + +class BooleanVariable : public Variable { +public: + BooleanVariable() { + + } + + BooleanVariable(std::string variableName) : Variable(variableName) { + + } + + virtual ~BooleanVariable() { + + } + + virtual std::string toString() { + return variableName + ": bool;"; + } +}; + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::BooleanVariable, + (std::string, variableName) +) + +#endif /* BOOLEANVARIABLE_H_ */ diff --git a/src/ir/Command.h b/src/ir/Command.h new file mode 100644 index 000000000..92fd673f1 --- /dev/null +++ b/src/ir/Command.h @@ -0,0 +1,40 @@ +/* + * Command.h + * + * Created on: 06.01.2013 + * Author: chris + */ + +#ifndef COMMAND_H_ +#define COMMAND_H_ + +#include "IR.h" + +namespace storm { + +namespace ir { + +class Command { +public: + std::string commandName; + std::shared_ptr guardExpression; + std::vector updates; + + std::string toString() { + return "command!"; + } + +}; + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::Command, + (std::string, commandName) + (std::shared_ptr, guardExpression) + (std::vector, updates) +) + +#endif /* COMMAND_H_ */ diff --git a/src/ir/IR.h b/src/ir/IR.h new file mode 100644 index 000000000..c919ca128 --- /dev/null +++ b/src/ir/IR.h @@ -0,0 +1,22 @@ +/* + * IR.h + * + * Created on: 06.01.2013 + * Author: chris + */ + +#ifndef IR_H_ +#define IR_H_ + +#include "expressions/Expressions.h" +#include "Assignment.h" +#include "Update.h" +#include "Command.h" +#include "Variable.h" +#include "BooleanVariable.h" +#include "IntegerVariable.h" +#include "Module.h" +#include "RewardModel.h" +#include "Program.h" + +#endif /* IR_H_ */ diff --git a/src/ir/IntegerVariable.h b/src/ir/IntegerVariable.h new file mode 100644 index 000000000..58a6e8f52 --- /dev/null +++ b/src/ir/IntegerVariable.h @@ -0,0 +1,51 @@ +/* + * IntegerVariable.h + * + * Created on: 08.01.2013 + * Author: chris + */ + +#ifndef INTEGERVARIABLE_H_ +#define INTEGERVARIABLE_H_ + +#include "Variable.h" + +namespace storm { + +namespace ir { + +class IntegerVariable : public Variable { +public: + IntegerVariable() { + + } + + IntegerVariable(std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound) : Variable(variableName), lowerBound(lowerBound), upperBound(upperBound) { + + } + + virtual ~IntegerVariable() { + + } + + virtual std::string toString() { + return variableName + ": int[];"; + } + + void setLowerBound(std::shared_ptr& lowerBound) { + this->lowerBound = lowerBound; + } + + void setUpperBound(std::shared_ptr& upperBound) { + this->upperBound = upperBound; + } + + std::shared_ptr lowerBound; + std::shared_ptr upperBound; +}; + +} + +} + +#endif /* INTEGERVARIABLE_H_ */ diff --git a/src/ir/Module.h b/src/ir/Module.h index d61a42add..d68503f78 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -8,11 +8,47 @@ #ifndef MODULE_H_ #define MODULE_H_ +#include "IR.h" + namespace storm { namespace ir { class Module { +public: + Module() { + + } + + std::string toString() { + std::string result = "module " + moduleName + "\n"; + for (auto variable : booleanVariables) { + result += "\t" + variable.toString() + "\n"; + } + result += "\n"; + for (auto variable : integerVariables) { + result += "\t" + variable.toString() + "\n"; + } + for (auto command : commands) { + result += "\t" + command.toString() + "\n"; + } + result += "endmodule\n"; + return result; + } + + void addBooleanVariable(storm::ir::BooleanVariable variable) { + booleanVariables.push_back(variable); + } + + void addIntegerVariable(storm::ir::IntegerVariable variable) { + integerVariables.push_back(variable); + } + + std::string moduleName; + + std::vector booleanVariables; + std::vector integerVariables; + std::vector commands; }; @@ -20,5 +56,10 @@ class Module { } +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::Module, + (std::string, moduleName) + (std::vector, commands) +) #endif /* MODULE_H_ */ diff --git a/src/ir/Program.h b/src/ir/Program.h index 70797f40f..98b13e9de 100644 --- a/src/ir/Program.h +++ b/src/ir/Program.h @@ -19,12 +19,44 @@ namespace ir { class Program { public: enum ModelType {DTMC, CTMC, MDP, CTMDP} modelType; - std::map undefinedConstantExpressions; + std::map> booleanUndefinedConstantExpressions; + std::map> integerUndefinedConstantExpressions; + std::map> doubleUndefinedConstantExpressions; std::vector modules; std::map rewards; std::string toString() { - return std::string("prog!"); + std::string result = ""; + for (auto element : booleanUndefinedConstantExpressions) { + result += "const bool " + element.first + ";\n"; + } + for (auto element : integerUndefinedConstantExpressions) { + result += "const int " + element.first + ";\n"; + } + for (auto element : doubleUndefinedConstantExpressions) { + result += "const double " + element.first + ";\n"; + } + for (auto mod : modules) { + result += mod.toString(); + } + + return result; + } + + void addBooleanUndefinedConstantExpression(std::string constantName, std::shared_ptr constantExpression) { + booleanUndefinedConstantExpressions[constantName] = constantExpression; + } + + void addIntegerUndefinedConstantExpression(std::string constantName, std::shared_ptr constantExpression) { + integerUndefinedConstantExpressions[constantName] = constantExpression; + } + + void addDoubleUndefinedConstantExpression(std::string constantName, std::shared_ptr constantExpression) { + doubleUndefinedConstantExpressions[constantName] = constantExpression; + } + + void setModules(std::vector modules) { + this->modules = modules; } }; @@ -32,4 +64,9 @@ public: } +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::Program, + (std::vector, modules) +) + #endif /* PROGRAM_H_ */ diff --git a/src/ir/Update.h b/src/ir/Update.h new file mode 100644 index 000000000..9cc1648a7 --- /dev/null +++ b/src/ir/Update.h @@ -0,0 +1,33 @@ +/* + * Update.h + * + * Created on: 06.01.2013 + * Author: chris + */ + +#ifndef UPDATE_H_ +#define UPDATE_H_ + +#include "IR.h" + +namespace storm { + +namespace ir { + +class Update { +public: + std::shared_ptr likelihoodExpression; + std::vector assignments; +}; + +} + +} + +BOOST_FUSION_ADAPT_STRUCT( + storm::ir::Update, + (std::shared_ptr, likelihoodExpression) + (std::vector, assignments) +) + +#endif /* UPDATE_H_ */ diff --git a/src/ir/Variable.h b/src/ir/Variable.h new file mode 100644 index 000000000..4456ae8f1 --- /dev/null +++ b/src/ir/Variable.h @@ -0,0 +1,45 @@ +/* + * Variable.h + * + * Created on: 06.01.2013 + * Author: chris + */ + +#ifndef VARIABLE_H_ +#define VARIABLE_H_ + +namespace storm { + +namespace ir { + +class Variable { +public: + std::string variableName; + + Variable() { + + } + + Variable(std::string variableName) : variableName(variableName) { + + } + + virtual ~Variable() { + + } + + virtual std::string toString() { + return variableName; + } + + void setVariableName(std::string variableName) { + this->variableName = variableName; + } +}; + +} + +} + + +#endif /* VARIABLE_H_ */ diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.h b/src/ir/expressions/BinaryBooleanFunctionExpression.h index a5688f188..5a745ba36 100644 --- a/src/ir/expressions/BinaryBooleanFunctionExpression.h +++ b/src/ir/expressions/BinaryBooleanFunctionExpression.h @@ -20,10 +20,10 @@ namespace expressions { class BinaryBooleanFunctionExpression : public BaseExpression { public: enum FunctorType {AND, OR, XOR, IMPLIES} functor; - BaseExpression* left; - BaseExpression* right; + std::shared_ptr left; + std::shared_ptr right; - BinaryBooleanFunctionExpression(BaseExpression* left, BaseExpression* right, FunctorType functor) { + BinaryBooleanFunctionExpression(std::shared_ptr left, std::shared_ptr right, FunctorType functor) { this->left = left; this->right = right; this->functor = functor; @@ -55,8 +55,8 @@ public: BOOST_FUSION_ADAPT_STRUCT( storm::ir::expressions::BinaryBooleanFunctionExpression, - (storm::ir::expressions::BaseExpression*, left) - (storm::ir::expressions::BaseExpression*, right) + (std::shared_ptr, left) + (std::shared_ptr, right) (storm::ir::expressions::BinaryBooleanFunctionExpression::FunctorType, functor) ) diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h index 9df88dc91..0a8b7cffe 100644 --- a/src/ir/expressions/BinaryNumericalFunctionExpression.h +++ b/src/ir/expressions/BinaryNumericalFunctionExpression.h @@ -18,11 +18,11 @@ namespace expressions { class BinaryNumericalFunctionExpression : public BaseExpression { public: - BaseExpression* left; - BaseExpression* right; + std::shared_ptr left; + std::shared_ptr right; enum FunctorType {PLUS, MINUS, TIMES, DIVIDE} functor; - BinaryNumericalFunctionExpression(BaseExpression* left, BaseExpression* right, FunctorType functor) { + BinaryNumericalFunctionExpression(std::shared_ptr left, std::shared_ptr right, FunctorType functor) { this->left = left; this->right = right; this->functor = functor; @@ -55,8 +55,8 @@ public: BOOST_FUSION_ADAPT_STRUCT( storm::ir::expressions::BinaryNumericalFunctionExpression, - (storm::ir::expressions::BaseExpression*, left) - (storm::ir::expressions::BaseExpression*, right) + (std::shared_ptr, left) + (std::shared_ptr, right) (storm::ir::expressions::BinaryNumericalFunctionExpression::FunctorType, functor) ) diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h index f765d0d85..47bd531bd 100644 --- a/src/ir/expressions/BinaryRelationExpression.h +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -18,11 +18,11 @@ namespace expressions { class BinaryRelationExpression : public BaseExpression { public: - BaseExpression* left; - BaseExpression* right; + std::shared_ptr left; + std::shared_ptr right; enum RelationType {EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL} relation; - BinaryRelationExpression(BaseExpression* left, BaseExpression* right, RelationType relation) { + BinaryRelationExpression(std::shared_ptr left, std::shared_ptr right, RelationType relation) { this->left = left; this->right = right; this->relation = relation; @@ -56,8 +56,8 @@ public: BOOST_FUSION_ADAPT_STRUCT( storm::ir::expressions::BinaryRelationExpression, - (storm::ir::expressions::BaseExpression*, left) - (storm::ir::expressions::BaseExpression*, right) + (std::shared_ptr, left) + (std::shared_ptr, right) (storm::ir::expressions::BinaryRelationExpression::RelationType, relation) ) diff --git a/src/ir/expressions/Expressions.h b/src/ir/expressions/Expressions.h index 5a69dc34c..b52474459 100644 --- a/src/ir/expressions/Expressions.h +++ b/src/ir/expressions/Expressions.h @@ -8,6 +8,7 @@ #ifndef EXPRESSIONS_H_ #define EXPRESSIONS_H_ +#include "BaseExpression.h" #include "BinaryBooleanFunctionExpression.h" #include "BinaryNumericalFunctionExpression.h" #include "BinaryRelationExpression.h" diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.h b/src/ir/expressions/UnaryBooleanFunctionExpression.h index 14c75a87f..f1e71e296 100644 --- a/src/ir/expressions/UnaryBooleanFunctionExpression.h +++ b/src/ir/expressions/UnaryBooleanFunctionExpression.h @@ -18,10 +18,10 @@ namespace expressions { class UnaryBooleanFunctionExpression : public BaseExpression { public: - BaseExpression* child; + std::shared_ptr child; enum FunctorType {NOT} functor; - UnaryBooleanFunctionExpression(BaseExpression* child, FunctorType functor) { + UnaryBooleanFunctionExpression(std::shared_ptr child, FunctorType functor) { this->child = child; this->functor = functor; } @@ -49,7 +49,7 @@ public: BOOST_FUSION_ADAPT_STRUCT( storm::ir::expressions::UnaryBooleanFunctionExpression, - (storm::ir::expressions::BaseExpression*, child) + (std::shared_ptr, child) (storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType, functor) ) diff --git a/src/ir/expressions/UnaryNumericalFunctionExpression.h b/src/ir/expressions/UnaryNumericalFunctionExpression.h index c367cffd2..084fc74d8 100644 --- a/src/ir/expressions/UnaryNumericalFunctionExpression.h +++ b/src/ir/expressions/UnaryNumericalFunctionExpression.h @@ -18,10 +18,10 @@ namespace expressions { class UnaryNumericalFunctionExpression : public BaseExpression { public: - BaseExpression* child; + std::shared_ptr child; enum FunctorType {MINUS} functor; - UnaryNumericalFunctionExpression(BaseExpression* child, FunctorType functor) { + UnaryNumericalFunctionExpression(std::shared_ptr child, FunctorType functor) { this->child = child; this->functor = functor; } @@ -49,7 +49,7 @@ public: BOOST_FUSION_ADAPT_STRUCT( storm::ir::expressions::UnaryNumericalFunctionExpression, - (storm::ir::expressions::BaseExpression*, child) + (std::shared_ptr, child) (storm::ir::expressions::UnaryNumericalFunctionExpression::FunctorType, functor) ) diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp deleted file mode 100644 index 9c0850ca5..000000000 --- a/src/parser/PrctlParser.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include "src/parser/PrctlParser.h" - -#include -#include -//#include - -#include -#include -#include -#include -#include -#include - -#include - -namespace bs = boost::spirit; - -namespace -{ - using namespace bs; - using namespace bs::qi; - using namespace bs::standard; - - struct SpiritParser : public grammar< char const* > - { - typedef rule< char const* > rule_none; - typedef rule< char const*, double() > rule_double; - typedef rule< char const*, std::string() > rule_string; - - /*! - * @brief Generic Nonterminals. - */ - rule_none ws; - rule_string variable; - rule_double value; - - /*! - * @brief Nonterminals for file header. - */ - rule< char const* > varDef; - rule_none type; - - /*! - * @brief Nonterminals for formula. - */ - rule_none formula, opP; - - /*! - * @brief Nonterminals for high-level file structure. - */ - rule_none file, header; - - /*! - * @brief Variable assignments. - */ - std::map variables; - - /*! - * @brief Resulting formula. - */ - storm::formula::PctlFormula* result; - - struct dump - { - void print(double const& i, std::string& s) - { - std::cout << s << " = " << i << std::endl; - } - void operator()(double const& a, unused_type, unused_type) const - { - std::cout << a << std::endl; - } - void operator()(std::string const& a, unused_type, unused_type) const - { - std::cout << a << std::endl; - } - void operator()(utree const& a, unused_type, unused_type) const - { - std::cout << &a << std::endl; - } - }; - - SpiritParser() : SpiritParser::base_type(file, "PRCTL parser") - { - variable %= alnum; - ws = *( space ); - value %= ( double_ | int_ ); // double_ must be *before* int_ - type = string("int") | string("double"); - - /* - * Todo: - * Use two arguments at one point in the code, e.g. do something like - * this->variables[ variable ] = value - * - * You can have local variables in rules, but somehow does not work. - * You can also (somehow) let a rule return some arbitrary class and let boost magically collect the arguments for the constructor. - * No idea how this can possibly work, did not get this to work. - * You can also generate a syntax tree and do this manually (-> utree)... somehow. - * - * Attention: spirit had some major upgrades in the last few releases. 1.48 already lacks some features that might be useful. - * - * The rules parse the const definitions of - * http://www.prismmodelchecker.org/manual/PropertySpecification/PropertiesFiles - * We actually do not need them, but the problems I described above are fairly generic. - * We will not be able to parse the formulas if we don't solve them... - * - * Example input: - * const int k = 7; - * const double T = 9; - * const double p = 0.01; - * - * Parser can be run via ./storm --test-prctl foo bar - * foo and bar are necessary, otherwise the option parser fails... - */ - - varDef = - string("const") >> ws >> - type >> ws >> - variable >> ws >> - string("=") >> ws >> - value >> ws >> - string(";"); - - header = +( varDef >> ws ); - - file = header; - } - - - }; -} - -storm::parser::PrctlParser::PrctlParser(const char* filename) -{ - SpiritParser p; - storm::parser::MappedFile file(filename); - - char* data = file.data; - if (bs::qi::parse< char const* >(data, file.dataend, p)) - { - std::cout << "File was parsed" << std::endl; - std::string rest(data, file.dataend); - std::cout << "Rest: " << rest << std::endl; - this->formula = p.result; - } - else this->formula = NULL; -} diff --git a/src/parser/PrctlParser.h b/src/parser/PrctlParser.h deleted file mode 100644 index 79c2e81c7..000000000 --- a/src/parser/PrctlParser.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef STORM_PARSER_PRCTLPARSER_H_ -#define STORM_PARSER_PRCTLPARSER_H_ - -#include "src/formula/PctlFormula.h" -#include "src/parser/Parser.h" - -namespace storm { -namespace parser { - -/*! - * @brief Load PRCTL file - */ -class PrctlParser : Parser -{ - public: - PrctlParser(const char * filename); - - /*! - * @brief return formula object parsed from file. - */ - storm::formula::PctlFormula* getFormula() - { - return this->formula; - } - - private: - storm::formula::PctlFormula* formula; -}; - -} // namespace parser -} // namespace storm - -#endif /* STORM_PARSER_PRCTLPARSER_H_ */ diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 61bf5b63f..6a6a39476 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -13,8 +13,7 @@ #include #include -#include "src/ir/expressions/Expressions.h" -#include "src/ir/Program.h" +#include "src/ir/IR.h" namespace storm { @@ -28,35 +27,28 @@ class PrismParser { public: void test() { - std::string testInput = ""; - // storm::ir::Program* result = getProgram(testInput); + std::string testInput = "" \ + "" \ + "const bool d; const int c; const double x;" \ + "module test " \ + " a : bool;" \ + "endmodule" \ + "module test2 endmodule"; getProgram(testInput); - -/* std::cout << "Resulting program:" << std::endl; - std::cout << "-------------------------\n"; - std::cout << result->toString() << std::endl; - std::cout << "-------------------------\n"; */ } void getProgram(std::string inputString) { - using qi::_val; - using qi::int_; - using qi::_r1; - using qi::_1; - using phoenix::ref; - using phoenix::val; - - prismGrammar grammar; + storm::ir::Program result; + prismGrammar grammar(result); std::string::const_iterator it = inputString.begin(); std::string::const_iterator end = inputString.end(); - storm::ir::Program result; - int resultInt = 0; - std::string input = "asdf"; - bool r = phrase_parse(it, end, grammar(phoenix::val(input)), ascii::space, resultInt); + storm::ir::Program realResult; + bool r = phrase_parse(it, end, grammar, ascii::space, realResult); if (r && it == end) { std::cout << "Parsing successful!" << std::endl; + std::cout << realResult.toString() << std::endl; } else { std::string rest(it, end); std::cout << "-------------------------\n"; @@ -68,127 +60,146 @@ public: private: template - struct prismGrammar : qi::grammar { + struct prismGrammar : qi::grammar { - prismGrammar() : prismGrammar::base_type(start) { - using qi::_val; - using qi::int_; - using qi::_r1; - using qi::_1; - using phoenix::ref; + prismGrammar(storm::ir::Program& program) : prismGrammar::base_type(start), program(program) { + freeIdentifierName %= qi::lexeme[(qi::alpha >> *(qi::alnum)) - allVariables_ - allConstants_]; - // start = constantDefinitionList(phoenix::ref(qi::_r1), phoenix::ref(qi::_r1)); - start = qi::lit(qi::_r1) >> int_; - constantDefinitionList = qi::int_; + booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + doubleLiteralExpression = qi::double_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + literalExpression %= (booleanLiteralExpression | integerLiteralExpression | doubleLiteralExpression); - variableDefinition %= (booleanVariableDefinition | integerVariableDefinition); - booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") >> qi::lit(";"))[phoenix::bind(booleanVariables_.add, qi::_1, phoenix::new_(qi::_1)), phoenix::bind(allVariables_.add, qi::_1, phoenix::new_(qi::_1)), qi::_val = phoenix::new_(qi::_1)]; - integerVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("[") >> integerConstantExpression >> qi::lit("..") >> integerConstantExpression >> qi::lit("]") >> qi::lit(";"))[phoenix::bind(integerVariables_.add, qi::_1, phoenix::new_(qi::_1)), phoenix::bind(allVariables_.add, qi::_1, phoenix::new_(qi::_1)), qi::_val = phoenix::new_(qi::_1)]; + integerVariableExpression = integerVariables_; + booleanVariableExpression = booleanVariables_; + variableExpression = (integerVariableExpression | booleanVariableExpression); - constantDefinition %= (definedConstantDefinition | undefinedConstantDefinition); - definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); - undefinedConstantDefinition %= (undefinedBooleanConstantDefinition | undefinedIntegerConstantDefinition | undefinedDoubleConstantDefinition); - definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") >> booleanLiteralExpression >> qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; - definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") >> integerLiteralExpression >> qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; - definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") >> doubleLiteralExpression >> qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; - undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, phoenix::new_(qi::_1)), phoenix::bind(allConstants_.add, qi::_1, phoenix::new_(qi::_1)), qi::_val = phoenix::new_(qi::_1)]; - undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, phoenix::new_(qi::_1)), phoenix::bind(allConstants_.add, qi::_1, phoenix::new_(qi::_1)), qi::_val = phoenix::new_(qi::_1)]; - undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, phoenix::new_(qi::_1)), phoenix::bind(allConstants_.add, qi::_1, phoenix::new_(qi::_1)), qi::_val = phoenix::new_(qi::_1)]; + booleanConstantExpression %= (booleanConstants_ | booleanLiteralExpression); + integerConstantExpression %= (integerConstants_ | integerLiteralExpression); + doubleConstantExpression %= (doubleConstants_ | doubleLiteralExpression); + constantExpression %= (booleanConstantExpression | integerConstantExpression | doubleConstantExpression); - expression %= (booleanExpression | integerExpression | doubleExpression); + atomicIntegerExpression %= (integerVariableExpression | qi::lit("(") >> integerExpression >> qi::lit(")") | integerConstantExpression); + integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> integerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + integerExpression %= integerPlusExpression; - booleanExpression %= orExpression; - orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::OR)]; - andExpression = atomicBooleanExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> atomicBooleanExpression)[qi::_val = phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND)]; + atomicDoubleExpression %= (qi::lit("(") >> doubleExpression >> qi::lit(")") | doubleConstantExpression); + doubleMultExpression %= atomicDoubleExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicDoubleExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + doublePlusExpression %= doubleMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> doubleMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + doubleExpression %= doublePlusExpression; + + relativeExpression = (integerExpression >> relations_ >> integerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression); - relativeExpression = (integerExpression >> relations_ >> integerExpression)[qi::_val = phoenix::new_(qi::_1, qi::_3, qi::_2)]; + andExpression = atomicBooleanExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; + orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::OR))]; + booleanExpression %= orExpression; - integerExpression %= integerPlusExpression; - integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> integerMultExpression)[qi::_val = phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS)]; - integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES)]; - atomicIntegerExpression %= (integerVariableExpression | qi::lit("(") >> integerExpression >> qi::lit(")") | integerConstantExpression); + expression %= (booleanExpression | integerExpression | doubleExpression); - doubleExpression %= doublePlusExpression; - doublePlusExpression = doubleMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> doubleMultExpression)[qi::_val = phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS)]; - doubleMultExpression %= atomicDoubleExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicDoubleExpression)[qi::_val = phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES)]; - atomicDoubleExpression %= (qi::lit("(") >> doubleExpression >> qi::lit(")") | doubleConstantExpression); + booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a)]; + integerVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("[") >> integerConstantExpression >> qi::lit("..") >> integerConstantExpression >> qi::lit("]") >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a), phoenix::bind(&storm::ir::IntegerVariable::setVariableName, qi::_val, qi::_1), phoenix::bind(&storm::ir::IntegerVariable::setLowerBound, qi::_val, qi::_2), phoenix::bind(&storm::ir::IntegerVariable::setUpperBound, qi::_val, qi::_3)]; + variableDefinition = (booleanVariableDefinition[phoenix::bind(&storm::ir::Module::addBooleanVariable, qi::_r1, qi::_1)] | integerVariableDefinition[phoenix::bind(&storm::ir::Module::addIntegerVariable, qi::_r1, qi::_1)]); - literalExpression %= (booleanLiteralExpression | integerLiteralExpression | doubleLiteralExpression); - booleanLiteralExpression = qi::bool_[qi::_val = phoenix::new_(qi::_1)]; - integerLiteralExpression = qi::int_[qi::_val = phoenix::new_(qi::_1)]; - doubleLiteralExpression = qi::double_[qi::_val = phoenix::new_(qi::_1)]; + definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") >> booleanLiteralExpression >> qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") >> integerLiteralExpression >> qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") >> doubleLiteralExpression >> qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit(";"))[qi::_val = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanConstants_.add, qi::_1, qi::_val), phoenix::bind(allConstants_.add, qi::_1, qi::_val), phoenix::bind(&storm::ir::Program::addBooleanUndefinedConstantExpression, program, qi::_1, qi::_val)]; + undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit(";"))[qi::_val = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerConstants_.add, qi::_1, qi::_val), phoenix::bind(allConstants_.add, qi::_1, qi::_val), phoenix::bind(&storm::ir::Program::addIntegerUndefinedConstantExpression, program, qi::_1, qi::_val)]; + undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit(";"))[qi::_val = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(doubleConstants_.add, qi::_1, qi::_val), phoenix::bind(allConstants_.add, qi::_1, qi::_val), phoenix::bind(&storm::ir::Program::addDoubleUndefinedConstantExpression, program, qi::_1, qi::_val)]; + definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); + undefinedConstantDefinition %= (undefinedBooleanConstantDefinition | undefinedIntegerConstantDefinition | undefinedDoubleConstantDefinition); + constantDefinition %= (definedConstantDefinition | undefinedConstantDefinition); - constantExpression %= (booleanConstantExpression | integerConstantExpression | doubleConstantExpression); - booleanConstantExpression %= (booleanConstants_ | booleanLiteralExpression); - integerConstantExpression %= (integerConstants_ | integerLiteralExpression); - doubleConstantExpression %= (doubleConstants_ | doubleLiteralExpression); + constantDefinitionList = +constantDefinition; - variableExpression = (integerVariableExpression | booleanVariableExpression); - integerVariableExpression = integerVariables_; - booleanVariableExpression = booleanVariables_; + integerVariableName %= integerVariableNames_; + booleanVariableName %= booleanVariableNames_; - freeIdentifierName %= qi::lexeme[(qi::alpha >> *(qi::alnum)) - allVariables_ - allConstants_]; + assignmentDefinition = qi::lit("(") >> integerVariableName >> qi::lit("'") >> integerExpression >> qi::lit(")") | qi::lit("(") >> booleanVariableName >> qi::lit("'") >> booleanExpression >> qi::lit(")"); + assignmentDefinitionList %= assignmentDefinition % "&"; + updateDefinition %= doubleConstantExpression >> qi::lit(":") >> assignmentDefinitionList; + updateListDefinition = +updateDefinition; + commandDefinition %= qi::lit("[") >> freeIdentifierName >> qi::lit("]") >> booleanExpression >> qi::lit("->") >> updateListDefinition >> qi::lit(";"); + + moduleDefinition %= qi::lit("module") >> freeIdentifierName >> *variableDefinition(qi::_val) >> *commandDefinition >> qi::lit("endmodule"); + + moduleDefinitionList = +moduleDefinition; + + start = constantDefinitionList >> moduleDefinitionList; } // The starting point of the grammar. - qi::rule start; + qi::rule start; + qi::rule constantDefinitionList; + qi::rule(), ascii::space_type> moduleDefinitionList; - qi::rule constantDefinitionList; + qi::rule moduleDefinition; - qi::rule variableDefinition; - qi::rule booleanVariableDefinition; - qi::rule integerVariableDefinition; + qi::rule variableDefinition; + qi::rule>, ascii::space_type> booleanVariableDefinition; + qi::rule>, ascii::space_type> integerVariableDefinition; - qi::rule constantDefinition; - qi::rule undefinedConstantDefinition; - qi::rule definedConstantDefinition; - qi::rule undefinedBooleanConstantDefinition; - qi::rule undefinedIntegerConstantDefinition; - qi::rule undefinedDoubleConstantDefinition; - qi::rule definedBooleanConstantDefinition; - qi::rule definedIntegerConstantDefinition; - qi::rule definedDoubleConstantDefinition; + qi::rule commandDefinition; + + qi::rule(), ascii::space_type> updateListDefinition; + qi::rule updateDefinition; + qi::rule(), ascii::space_type> assignmentDefinitionList; + qi::rule assignmentDefinition; + + qi::rule integerVariableName; + qi::rule booleanVariableName; + + qi::rule(), ascii::space_type> constantDefinition; + qi::rule(), ascii::space_type> undefinedConstantDefinition; + qi::rule(), ascii::space_type> definedConstantDefinition; + qi::rule(), ascii::space_type> undefinedBooleanConstantDefinition; + qi::rule(), ascii::space_type> undefinedIntegerConstantDefinition; + qi::rule(), ascii::space_type> undefinedDoubleConstantDefinition; + qi::rule(), ascii::space_type> definedBooleanConstantDefinition; + qi::rule(), ascii::space_type> definedIntegerConstantDefinition; + qi::rule(), ascii::space_type> definedDoubleConstantDefinition; qi::rule freeIdentifierName; // The starting point for arbitrary expressions. - qi::rule expression; + qi::rule(), ascii::space_type> expression; // Rules with boolean result type. - qi::rule booleanExpression; - qi::rule orExpression; - qi::rule andExpression; - qi::rule atomicBooleanExpression; - qi::rule relativeExpression; + qi::rule(), ascii::space_type> booleanExpression; + qi::rule(), ascii::space_type> orExpression; + qi::rule(), ascii::space_type> andExpression; + qi::rule(), ascii::space_type> atomicBooleanExpression; + qi::rule(), ascii::space_type> relativeExpression; // Rules with integer result type. - qi::rule integerExpression; - qi::rule integerPlusExpression; - qi::rule integerMultExpression; - qi::rule atomicIntegerExpression; + qi::rule(), ascii::space_type> integerExpression; + qi::rule(), ascii::space_type> integerPlusExpression; + qi::rule(), ascii::space_type> integerMultExpression; + qi::rule(), ascii::space_type> atomicIntegerExpression; // Rules with double result type. - qi::rule doubleExpression; - qi::rule doublePlusExpression; - qi::rule doubleMultExpression; - qi::rule atomicDoubleExpression; + qi::rule(), ascii::space_type> doubleExpression; + qi::rule(), ascii::space_type> doublePlusExpression; + qi::rule(), ascii::space_type> doubleMultExpression; + qi::rule(), ascii::space_type> atomicDoubleExpression; // Rules for variable recognition. - qi::rule variableExpression; - qi::rule booleanVariableExpression; - qi::rule integerVariableExpression; + qi::rule(), ascii::space_type> variableExpression; + qi::rule(), ascii::space_type> booleanVariableExpression; + qi::rule(), ascii::space_type> integerVariableExpression; // Rules for constant recognition. - qi::rule constantExpression; - qi::rule booleanConstantExpression; - qi::rule integerConstantExpression; - qi::rule doubleConstantExpression; + qi::rule(), ascii::space_type> constantExpression; + qi::rule(), ascii::space_type> booleanConstantExpression; + qi::rule(), ascii::space_type> integerConstantExpression; + qi::rule(), ascii::space_type> doubleConstantExpression; // Rules for literal recognition. - qi::rule literalExpression; - qi::rule booleanLiteralExpression; - qi::rule integerLiteralExpression; - qi::rule doubleLiteralExpression; + qi::rule(), ascii::space_type> literalExpression; + qi::rule(), ascii::space_type> booleanLiteralExpression; + qi::rule(), ascii::space_type> integerLiteralExpression; + qi::rule(), ascii::space_type> doubleLiteralExpression; struct keywordsStruct : qi::symbols { keywordsStruct() { @@ -222,17 +233,23 @@ private: } } relations_; - struct variablesStruct : qi::symbols { + struct variablesStruct : qi::symbols> { // Intentionally left empty. This map is filled during parsing. - } integerVariables_, booleanVariables_, allVariables_ ; + } integerVariables_, booleanVariables_, allVariables_; - struct constantsStruct : qi::symbols { + struct variableNamesStruct : qi::symbols { + // Intentionally left empty. This map is filled during parsing. + } integerVariableNames_, booleanVariableNames_; + + struct constantsStruct : qi::symbols> { // Intentionally left empty. This map is filled during parsing. } integerConstants_, booleanConstants_, doubleConstants_, allConstants_; struct modulesStruct : qi::symbols { // Intentionally left empty. This map is filled during parsing. } modules_; + + storm::ir::Program& program; }; }; diff --git a/src/storm.cpp b/src/storm.cpp index eed86455e..0a08d6064 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -25,7 +25,7 @@ #include "src/modelChecker/EigenDtmcPrctlModelChecker.h" #include "src/modelChecker/GmmxxDtmcPrctlModelChecker.h" #include "src/parser/DtmcParser.h" -#include "src/parser/PrctlParser.h" +// #include "src/parser/PrctlParser.h" #include "src/solver/GraphAnalyzer.h" #include "src/utility/Settings.h" #include "src/formula/Formulas.h" @@ -111,7 +111,7 @@ bool parseOptions(const int argc, const char* argv[]) { return false; } if (s->isSet("test-prctl")) { - storm::parser::PrctlParser parser(s->getString("test-prctl").c_str()); + // storm::parser::PrctlParser parser(s->getString("test-prctl").c_str()); delete s; return false; } From f7194a416d7b013fb857080d2c26c8fc0867497c Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 9 Jan 2013 17:19:48 +0100 Subject: [PATCH 005/152] Cleaned IR classes a bit and made attributes private. Changed grammar rules accordingly. --- src/ir/Assignment.h | 31 +++++++++++++++------ src/ir/BooleanVariable.h | 7 +---- src/ir/Command.h | 34 +++++++++++++++-------- src/ir/IntegerVariable.h | 11 ++------ src/ir/Module.h | 18 ++++++++----- src/ir/Program.h | 42 +++++++++++++++++++---------- src/ir/RewardModel.h | 1 - src/ir/Update.h | 27 ++++++++++++++----- src/ir/Variable.h | 9 ++++--- src/ir/expressions/BaseExpression.h | 4 ++- src/parser/PrismParser.h | 12 ++++----- 11 files changed, 123 insertions(+), 73 deletions(-) diff --git a/src/ir/Assignment.h b/src/ir/Assignment.h index a552bb750..308d1f27f 100644 --- a/src/ir/Assignment.h +++ b/src/ir/Assignment.h @@ -8,8 +8,7 @@ #ifndef ASSIGNMENT_H_ #define ASSIGNMENT_H_ -#include "expressions/Expressions.h" -#include +#include "expressions/BaseExpression.h" namespace storm { @@ -18,6 +17,28 @@ namespace ir { class Assignment { public: + Assignment() : variableName(""), expression(nullptr) { + + } + + Assignment(std::string variableName, std::shared_ptr expression) + : variableName(variableName), expression(expression) { + + } + + std::string getVariableName() { + return variableName; + } + + std::shared_ptr getExpression() { + return expression; + } + + std::string toString() { + return variableName + "' = " + expression->toString(); + } + +private: std::string variableName; std::shared_ptr expression; }; @@ -26,10 +47,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::Assignment, - (std::string, variableName) - (std::shared_ptr, expression) -) - #endif /* ASSIGNMENT_H_ */ diff --git a/src/ir/BooleanVariable.h b/src/ir/BooleanVariable.h index 71e09e4ea..051982316 100644 --- a/src/ir/BooleanVariable.h +++ b/src/ir/BooleanVariable.h @@ -27,7 +27,7 @@ public: } virtual std::string toString() { - return variableName + ": bool;"; + return getVariableName() + ": bool;"; } }; @@ -35,9 +35,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::BooleanVariable, - (std::string, variableName) -) - #endif /* BOOLEANVARIABLE_H_ */ diff --git a/src/ir/Command.h b/src/ir/Command.h index 92fd673f1..9a687eab6 100644 --- a/src/ir/Command.h +++ b/src/ir/Command.h @@ -16,25 +16,37 @@ namespace ir { class Command { public: - std::string commandName; - std::shared_ptr guardExpression; - std::vector updates; + + Command() : commandName(""), guardExpression(nullptr), updates() { + + } + + Command(std::string commandName, std::shared_ptr guardExpression, std::vector updates) + : commandName(commandName), guardExpression(guardExpression), updates(updates) { + + } std::string toString() { - return "command!"; + std::string result = "[" + commandName + "] " + guardExpression->toString() + " -> "; + for (uint_fast64_t i = 0; i < updates.size(); ++i) { + result += updates[i].toString(); + if (i < updates.size() - 1) { + result += " + "; + } + } + result += ";"; + return result; } +private: + std::string commandName; + std::shared_ptr guardExpression; + std::vector updates; + }; } } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::Command, - (std::string, commandName) - (std::shared_ptr, guardExpression) - (std::vector, updates) -) - #endif /* COMMAND_H_ */ diff --git a/src/ir/IntegerVariable.h b/src/ir/IntegerVariable.h index 58a6e8f52..0e8ab9521 100644 --- a/src/ir/IntegerVariable.h +++ b/src/ir/IntegerVariable.h @@ -29,17 +29,10 @@ public: } virtual std::string toString() { - return variableName + ": int[];"; - } - - void setLowerBound(std::shared_ptr& lowerBound) { - this->lowerBound = lowerBound; - } - - void setUpperBound(std::shared_ptr& upperBound) { - this->upperBound = upperBound; + return getVariableName() + ": int[" + lowerBound->toString() + ".." + upperBound->toString() + "];"; } +private: std::shared_ptr lowerBound; std::shared_ptr upperBound; }; diff --git a/src/ir/Module.h b/src/ir/Module.h index d68503f78..02966a5a1 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -16,7 +16,16 @@ namespace ir { class Module { public: - Module() { + Module() : moduleName(""), booleanVariables(), integerVariables(), commands() { + + } + + Module(std::string moduleName, std::vector booleanVariables, std::vector integerVariables, std::vector commands) + : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), commands(commands) { + + } + + Module(std::string moduleName, std::vector commands) : moduleName(moduleName), booleanVariables(), integerVariables(), commands(commands) { } @@ -44,6 +53,7 @@ public: integerVariables.push_back(variable); } +private: std::string moduleName; std::vector booleanVariables; @@ -56,10 +66,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::Module, - (std::string, moduleName) - (std::vector, commands) -) - #endif /* MODULE_H_ */ diff --git a/src/ir/Program.h b/src/ir/Program.h index 98b13e9de..16e213cab 100644 --- a/src/ir/Program.h +++ b/src/ir/Program.h @@ -18,15 +18,30 @@ namespace ir { class Program { public: - enum ModelType {DTMC, CTMC, MDP, CTMDP} modelType; - std::map> booleanUndefinedConstantExpressions; - std::map> integerUndefinedConstantExpressions; - std::map> doubleUndefinedConstantExpressions; - std::vector modules; - std::map rewards; + + enum ModelType {DTMC, CTMC, MDP, CTMDP}; + + Program() : modelType(DTMC), booleanUndefinedConstantExpressions(), integerUndefinedConstantExpressions(), doubleUndefinedConstantExpressions(), modules(), rewards() { + + } + + Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector modules, std::map rewards) + : modelType(modelType), booleanUndefinedConstantExpressions(booleanUndefinedConstantExpressions), integerUndefinedConstantExpressions(integerUndefinedConstantExpressions), doubleUndefinedConstantExpressions(doubleUndefinedConstantExpressions), modules(modules), rewards(rewards) { + + } + + Program(ModelType modelType, std::vector modules) : modelType(modelType), booleanUndefinedConstantExpressions(), integerUndefinedConstantExpressions(), doubleUndefinedConstantExpressions(), modules(modules), rewards() { + + } std::string toString() { std::string result = ""; + switch (modelType) { + case DTMC: result += "dtmc\n"; break; + case CTMC: result += "ctmc\n"; break; + case MDP: result += "mdp\n"; break; + case CTMDP: result += "ctmdp\n"; break; + } for (auto element : booleanUndefinedConstantExpressions) { result += "const bool " + element.first + ";\n"; } @@ -55,18 +70,17 @@ public: doubleUndefinedConstantExpressions[constantName] = constantExpression; } - void setModules(std::vector modules) { - this->modules = modules; - } +private: + ModelType modelType; + std::map> booleanUndefinedConstantExpressions; + std::map> integerUndefinedConstantExpressions; + std::map> doubleUndefinedConstantExpressions; + std::vector modules; + std::map rewards; }; } } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::Program, - (std::vector, modules) -) - #endif /* PROGRAM_H_ */ diff --git a/src/ir/RewardModel.h b/src/ir/RewardModel.h index b53194668..16cb70f62 100644 --- a/src/ir/RewardModel.h +++ b/src/ir/RewardModel.h @@ -20,5 +20,4 @@ class RewardModel { } - #endif /* REWARDMODEL_H_ */ diff --git a/src/ir/Update.h b/src/ir/Update.h index 9cc1648a7..e2751703a 100644 --- a/src/ir/Update.h +++ b/src/ir/Update.h @@ -16,6 +16,27 @@ namespace ir { class Update { public: + Update() : likelihoodExpression(nullptr), assignments() { + + } + + Update(std::shared_ptr likelihoodExpression, std::vector assignments) + : likelihoodExpression(likelihoodExpression), assignments(assignments) { + + } + + std::string toString() { + std::string result = likelihoodExpression->toString() + " : "; + for (uint_fast64_t i = 0; i < assignments.size(); ++i) { + result += assignments[i].toString(); + if (i < assignments.size() - 1) { + result += " & "; + } + } + return result; + } + +private: std::shared_ptr likelihoodExpression; std::vector assignments; }; @@ -24,10 +45,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::Update, - (std::shared_ptr, likelihoodExpression) - (std::vector, assignments) -) - #endif /* UPDATE_H_ */ diff --git a/src/ir/Variable.h b/src/ir/Variable.h index 4456ae8f1..abb62df35 100644 --- a/src/ir/Variable.h +++ b/src/ir/Variable.h @@ -14,8 +14,6 @@ namespace ir { class Variable { public: - std::string variableName; - Variable() { } @@ -32,9 +30,12 @@ public: return variableName; } - void setVariableName(std::string variableName) { - this->variableName = variableName; + std::string getVariableName() { + return variableName; } + +private: + std::string variableName; }; } diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h index aea967901..9d6c93db2 100644 --- a/src/ir/expressions/BaseExpression.h +++ b/src/ir/expressions/BaseExpression.h @@ -21,7 +21,9 @@ public: } - virtual std::string toString() const = 0; + virtual std::string toString() const { + return "expr here!"; + } }; } diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 6a6a39476..14ca7fba3 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -98,7 +98,7 @@ private: expression %= (booleanExpression | integerExpression | doubleExpression); booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a)]; - integerVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("[") >> integerConstantExpression >> qi::lit("..") >> integerConstantExpression >> qi::lit("]") >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a), phoenix::bind(&storm::ir::IntegerVariable::setVariableName, qi::_val, qi::_1), phoenix::bind(&storm::ir::IntegerVariable::setLowerBound, qi::_val, qi::_2), phoenix::bind(&storm::ir::IntegerVariable::setUpperBound, qi::_val, qi::_3)]; + integerVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("[") >> integerConstantExpression >> qi::lit("..") >> integerConstantExpression >> qi::lit("]") >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a)]; variableDefinition = (booleanVariableDefinition[phoenix::bind(&storm::ir::Module::addBooleanVariable, qi::_r1, qi::_1)] | integerVariableDefinition[phoenix::bind(&storm::ir::Module::addIntegerVariable, qi::_r1, qi::_1)]); definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") >> booleanLiteralExpression >> qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; @@ -116,17 +116,17 @@ private: integerVariableName %= integerVariableNames_; booleanVariableName %= booleanVariableNames_; - assignmentDefinition = qi::lit("(") >> integerVariableName >> qi::lit("'") >> integerExpression >> qi::lit(")") | qi::lit("(") >> booleanVariableName >> qi::lit("'") >> booleanExpression >> qi::lit(")"); + assignmentDefinition = (qi::lit("(") >> integerVariableName >> qi::lit("'") >> integerExpression >> qi::lit(")"))[qi::_val = phoenix::construct(qi::_1, qi::_2)] | (qi::lit("(") >> booleanVariableName >> qi::lit("'") >> booleanExpression >> qi::lit(")"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; assignmentDefinitionList %= assignmentDefinition % "&"; - updateDefinition %= doubleConstantExpression >> qi::lit(":") >> assignmentDefinitionList; + updateDefinition = (doubleConstantExpression >> qi::lit(":") >> assignmentDefinitionList)[qi::_val = phoenix::construct(qi::_1, qi::_2)]; updateListDefinition = +updateDefinition; - commandDefinition %= qi::lit("[") >> freeIdentifierName >> qi::lit("]") >> booleanExpression >> qi::lit("->") >> updateListDefinition >> qi::lit(";"); + commandDefinition = (qi::lit("[") >> freeIdentifierName >> qi::lit("]") >> booleanExpression >> qi::lit("->") >> updateListDefinition >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3)]; - moduleDefinition %= qi::lit("module") >> freeIdentifierName >> *variableDefinition(qi::_val) >> *commandDefinition >> qi::lit("endmodule"); + moduleDefinition = (qi::lit("module") >> freeIdentifierName >> *variableDefinition(qi::_val) >> *commandDefinition >> qi::lit("endmodule"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; moduleDefinitionList = +moduleDefinition; - start = constantDefinitionList >> moduleDefinitionList; + start = (constantDefinitionList >> moduleDefinitionList)[qi::_val = phoenix::construct(storm::ir::Program::ModelType::DTMC, qi::_1)]; } // The starting point of the grammar. From 3deca3f2d3d63d7a4e7919be0c0d1921c613249c Mon Sep 17 00:00:00 2001 From: dehnert Date: Thu, 10 Jan 2013 09:59:42 +0100 Subject: [PATCH 006/152] Intermediate Commit to switch workplace. --- src/parser/PrismParser.h | 56 ++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 14ca7fba3..5706a2273 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -97,21 +97,19 @@ private: expression %= (booleanExpression | integerExpression | doubleExpression); - booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a)]; - integerVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("[") >> integerConstantExpression >> qi::lit("..") >> integerConstantExpression >> qi::lit("]") >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a)]; - variableDefinition = (booleanVariableDefinition[phoenix::bind(&storm::ir::Module::addBooleanVariable, qi::_r1, qi::_1)] | integerVariableDefinition[phoenix::bind(&storm::ir::Module::addIntegerVariable, qi::_r1, qi::_1)]); + booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableInfo_.add, qi::_1, qi::_val)]; + integerVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("[") >> integerConstantExpression >> qi::lit("..") >> integerConstantExpression >> qi::lit("]") >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableInfo_.add, qi::_1, qi::_val)]; + variableDefinition = (booleanVariableDefinition | integerVariableDefinition); definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") >> booleanLiteralExpression >> qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") >> integerLiteralExpression >> qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") >> doubleLiteralExpression >> qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; - undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit(";"))[qi::_val = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanConstants_.add, qi::_1, qi::_val), phoenix::bind(allConstants_.add, qi::_1, qi::_val), phoenix::bind(&storm::ir::Program::addBooleanUndefinedConstantExpression, program, qi::_1, qi::_val)]; - undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit(";"))[qi::_val = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerConstants_.add, qi::_1, qi::_val), phoenix::bind(allConstants_.add, qi::_1, qi::_val), phoenix::bind(&storm::ir::Program::addIntegerUndefinedConstantExpression, program, qi::_1, qi::_val)]; - undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit(";"))[qi::_val = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(doubleConstants_.add, qi::_1, qi::_val), phoenix::bind(allConstants_.add, qi::_1, qi::_val), phoenix::bind(&storm::ir::Program::addDoubleUndefinedConstantExpression, program, qi::_1, qi::_val)]; + undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(integerConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(doubleConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); - undefinedConstantDefinition %= (undefinedBooleanConstantDefinition | undefinedIntegerConstantDefinition | undefinedDoubleConstantDefinition); - constantDefinition %= (definedConstantDefinition | undefinedConstantDefinition); - - constantDefinitionList = +constantDefinition; + // undefinedConstantDefinition = (undefinedBooleanConstantDefinition | undefinedIntegerConstantDefinition | undefinedDoubleConstantDefinition); + // constantDefinitionList = *(definedConstantDefinition | undefinedConstantDefinition); integerVariableName %= integerVariableNames_; booleanVariableName %= booleanVariableNames_; @@ -122,21 +120,21 @@ private: updateListDefinition = +updateDefinition; commandDefinition = (qi::lit("[") >> freeIdentifierName >> qi::lit("]") >> booleanExpression >> qi::lit("->") >> updateListDefinition >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3)]; - moduleDefinition = (qi::lit("module") >> freeIdentifierName >> *variableDefinition(qi::_val) >> *commandDefinition >> qi::lit("endmodule"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; + moduleDefinition = (qi::lit("module") >> freeIdentifierName >> *(booleanVariableDefinition[phoenix::push_back(qi::_a, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> *commandDefinition >> qi::lit("endmodule"))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_3)]; moduleDefinitionList = +moduleDefinition; - start = (constantDefinitionList >> moduleDefinitionList)[qi::_val = phoenix::construct(storm::ir::Program::ModelType::DTMC, qi::_1)]; + start = (*(definedConstantDefinition | (undefinedBooleanConstantDefinition[phoenix::push_back(qi::_a, qi::_1)] | undefinedIntegerConstantDefinition[phoenix::push_back(qi::_b, qi::_1)] | undefinedDoubleConstantDefinition[phoenix::push_back(qi::_c, qi::_1)])) >> moduleDefinitionList)[qi::_val = phoenix::construct(storm::ir::Program::ModelType::DTMC, qi::_a, qi::_b, qi::_c, qi::_1)]; } // The starting point of the grammar. - qi::rule start; + qi::rule>,std::vector>,std::vector>>, ascii::space_type> start; qi::rule constantDefinitionList; qi::rule(), ascii::space_type> moduleDefinitionList; - qi::rule moduleDefinition; + qi::rule, std::vector>, ascii::space_type> moduleDefinition; - qi::rule variableDefinition; + qi::rule variableDefinition; qi::rule>, ascii::space_type> booleanVariableDefinition; qi::rule>, ascii::space_type> integerVariableDefinition; @@ -151,11 +149,11 @@ private: qi::rule booleanVariableName; qi::rule(), ascii::space_type> constantDefinition; - qi::rule(), ascii::space_type> undefinedConstantDefinition; + qi::rule undefinedConstantDefinition; qi::rule(), ascii::space_type> definedConstantDefinition; - qi::rule(), ascii::space_type> undefinedBooleanConstantDefinition; - qi::rule(), ascii::space_type> undefinedIntegerConstantDefinition; - qi::rule(), ascii::space_type> undefinedDoubleConstantDefinition; + qi::rule>, ascii::space_type> undefinedBooleanConstantDefinition; + qi::rule>, ascii::space_type> undefinedIntegerConstantDefinition; + qi::rule>, ascii::space_type> undefinedDoubleConstantDefinition; qi::rule(), ascii::space_type> definedBooleanConstantDefinition; qi::rule(), ascii::space_type> definedIntegerConstantDefinition; qi::rule(), ascii::space_type> definedDoubleConstantDefinition; @@ -241,10 +239,30 @@ private: // Intentionally left empty. This map is filled during parsing. } integerVariableNames_, booleanVariableNames_; + struct booleanVariableTypesStruct : qi::symbols { + // Intentionally left empty. This map is filled during parsing. + } booleanVariableInfo_; + + struct integerVariableTypesStruct : qi::symbols { + // Intentionally left empty. This map is filled during parsing. + } integerVariableInfo_; + struct constantsStruct : qi::symbols> { // Intentionally left empty. This map is filled during parsing. } integerConstants_, booleanConstants_, doubleConstants_, allConstants_; + struct undefinedBooleanConstantsTypesStruct : qi::symbols> { + // Intentionally left empty. This map is filled during parsing. + } booleanConstantInfo_; + + struct undefinedIntegerConstantsTypesStruct : qi::symbols> { + // Intentionally left empty. This map is filled during parsing. + } integerConstantInfo_; + + struct undefinedDoubleConstantsTypesStruct : qi::symbols> { + // Intentionally left empty. This map is filled during parsing. + } doubleConstantInfo_; + struct modulesStruct : qi::symbols { // Intentionally left empty. This map is filled during parsing. } modules_; From a44da7d50a6b8907e7bb137457ba79a806014747 Mon Sep 17 00:00:00 2001 From: dehnert Date: Thu, 10 Jan 2013 18:24:52 +0100 Subject: [PATCH 007/152] Commit to switch workplace. --- src/ir/Assignment.h | 2 +- src/ir/BooleanVariable.h | 9 +- src/ir/IR.h | 2 + src/ir/IntegerVariable.h | 11 +- src/ir/Module.h | 1 - src/ir/Program.h | 26 +- src/ir/RewardModel.h | 26 +- src/ir/StateReward.h | 40 +++ src/ir/TransitionReward.h | 41 +++ src/ir/Variable.h | 9 +- src/ir/expressions/BinaryRelationExpression.h | 2 +- src/parser/PrismParser.h | 281 +++++++++++------- src/storm.cpp | 2 +- test.input | 19 ++ 14 files changed, 344 insertions(+), 127 deletions(-) create mode 100644 src/ir/StateReward.h create mode 100644 src/ir/TransitionReward.h create mode 100644 test.input diff --git a/src/ir/Assignment.h b/src/ir/Assignment.h index 308d1f27f..e6069d48f 100644 --- a/src/ir/Assignment.h +++ b/src/ir/Assignment.h @@ -35,7 +35,7 @@ public: } std::string toString() { - return variableName + "' = " + expression->toString(); + return "(" + variableName + "' = " + expression->toString() + ")"; } private: diff --git a/src/ir/BooleanVariable.h b/src/ir/BooleanVariable.h index 051982316..eccf92078 100644 --- a/src/ir/BooleanVariable.h +++ b/src/ir/BooleanVariable.h @@ -18,7 +18,7 @@ public: } - BooleanVariable(std::string variableName) : Variable(variableName) { + BooleanVariable(std::string variableName, std::shared_ptr initialValue = nullptr) : Variable(variableName, initialValue) { } @@ -27,7 +27,12 @@ public: } virtual std::string toString() { - return getVariableName() + ": bool;"; + std::string result = getVariableName() + ": bool"; + if (this->getInitialValue() != nullptr) { + result += " init " + this->getInitialValue()->toString(); + } + result += ";"; + return result; } }; diff --git a/src/ir/IR.h b/src/ir/IR.h index c919ca128..029e88fed 100644 --- a/src/ir/IR.h +++ b/src/ir/IR.h @@ -16,6 +16,8 @@ #include "BooleanVariable.h" #include "IntegerVariable.h" #include "Module.h" +#include "StateReward.h" +#include "TransitionReward.h" #include "RewardModel.h" #include "Program.h" diff --git a/src/ir/IntegerVariable.h b/src/ir/IntegerVariable.h index 0e8ab9521..abde92cb3 100644 --- a/src/ir/IntegerVariable.h +++ b/src/ir/IntegerVariable.h @@ -16,11 +16,11 @@ namespace ir { class IntegerVariable : public Variable { public: - IntegerVariable() { + IntegerVariable() : lowerBound(nullptr), upperBound(nullptr) { } - IntegerVariable(std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound) : Variable(variableName), lowerBound(lowerBound), upperBound(upperBound) { + IntegerVariable(std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue = nullptr) : Variable(variableName, initialValue), lowerBound(lowerBound), upperBound(upperBound) { } @@ -29,7 +29,12 @@ public: } virtual std::string toString() { - return getVariableName() + ": int[" + lowerBound->toString() + ".." + upperBound->toString() + "];"; + std::string result = getVariableName() + ": [" + lowerBound->toString() + ".." + upperBound->toString() + "]"; + if (this->getInitialValue() != nullptr) { + result += " init " + this->getInitialValue()->toString(); + } + result += ";"; + return result; } private: diff --git a/src/ir/Module.h b/src/ir/Module.h index 02966a5a1..a1046db76 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -34,7 +34,6 @@ public: for (auto variable : booleanVariables) { result += "\t" + variable.toString() + "\n"; } - result += "\n"; for (auto variable : integerVariables) { result += "\t" + variable.toString() + "\n"; } diff --git a/src/ir/Program.h b/src/ir/Program.h index 16e213cab..2ee72c08d 100644 --- a/src/ir/Program.h +++ b/src/ir/Program.h @@ -19,9 +19,9 @@ namespace ir { class Program { public: - enum ModelType {DTMC, CTMC, MDP, CTMDP}; + enum ModelType {UNDEFINED, DTMC, CTMC, MDP, CTMDP}; - Program() : modelType(DTMC), booleanUndefinedConstantExpressions(), integerUndefinedConstantExpressions(), doubleUndefinedConstantExpressions(), modules(), rewards() { + Program() : modelType(UNDEFINED), booleanUndefinedConstantExpressions(), integerUndefinedConstantExpressions(), doubleUndefinedConstantExpressions(), modules(), rewards() { } @@ -30,6 +30,12 @@ public: } + Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector modules) + : modelType(modelType), booleanUndefinedConstantExpressions(booleanUndefinedConstantExpressions), integerUndefinedConstantExpressions(integerUndefinedConstantExpressions), doubleUndefinedConstantExpressions(doubleUndefinedConstantExpressions), modules(modules), rewards() { + + } + + Program(ModelType modelType, std::vector modules) : modelType(modelType), booleanUndefinedConstantExpressions(), integerUndefinedConstantExpressions(), doubleUndefinedConstantExpressions(), modules(modules), rewards() { } @@ -37,10 +43,11 @@ public: std::string toString() { std::string result = ""; switch (modelType) { - case DTMC: result += "dtmc\n"; break; - case CTMC: result += "ctmc\n"; break; - case MDP: result += "mdp\n"; break; - case CTMDP: result += "ctmdp\n"; break; + case UNDEFINED: result += "undefined\n\n"; break; + case DTMC: result += "dtmc\n\n"; break; + case CTMC: result += "ctmc\n\n"; break; + case MDP: result += "mdp\n\n"; break; + case CTMDP: result += "ctmdp\n\n"; break; } for (auto element : booleanUndefinedConstantExpressions) { result += "const bool " + element.first + ";\n"; @@ -51,8 +58,15 @@ public: for (auto element : doubleUndefinedConstantExpressions) { result += "const double " + element.first + ";\n"; } + result += "\n"; for (auto mod : modules) { result += mod.toString(); + result += "\n"; + } + + for (auto rewardModel : rewards) { + result += rewardModel.second.toString(); + result +="\n"; } return result; diff --git a/src/ir/RewardModel.h b/src/ir/RewardModel.h index 16cb70f62..746eea70e 100644 --- a/src/ir/RewardModel.h +++ b/src/ir/RewardModel.h @@ -13,7 +13,31 @@ namespace storm { namespace ir { class RewardModel { - +public: + RewardModel() : rewardModelName(""), stateRewards(), transitionRewards() { + + } + + RewardModel(std::string rewardModelName, std::vector stateRewards, std::vector transitionRewards) : rewardModelName(rewardModelName), stateRewards(stateRewards), transitionRewards(transitionRewards) { + + } + + std::string toString() { + std::string result = "rewards \"" + rewardModelName + "\n"; + for (auto reward : stateRewards) { + result += reward.toString() + "\n"; + } + for (auto reward : transitionRewards) { + result += reward.toString() + "\n"; + } + result += "endrewards\n"; + return result; + } + +private: + std::string rewardModelName; + std::vector stateRewards; + std::vector transitionRewards; }; } diff --git a/src/ir/StateReward.h b/src/ir/StateReward.h new file mode 100644 index 000000000..2a0d23b69 --- /dev/null +++ b/src/ir/StateReward.h @@ -0,0 +1,40 @@ +/* + * StateReward.h + * + * Created on: Jan 10, 2013 + * Author: chris + */ + +#ifndef STATEREWARD_H_ +#define STATEREWARD_H_ + +#include "expressions/BaseExpression.h" + +namespace storm { + +namespace ir { + +class StateReward { +public: + StateReward() : statePredicate(nullptr), rewardValue(nullptr) { + + } + + StateReward(std::shared_ptr statePredicate, std::shared_ptr rewardValue) : statePredicate(statePredicate), rewardValue(rewardValue) { + + } + + std::string toString() { + return statePredicate->toString() + ": " + rewardValue->toString() + ";"; + } + +private: + std::shared_ptr statePredicate; + std::shared_ptr rewardValue; +}; + +} + +} + +#endif /* STATEREWARD_H_ */ diff --git a/src/ir/TransitionReward.h b/src/ir/TransitionReward.h new file mode 100644 index 000000000..2181d5b05 --- /dev/null +++ b/src/ir/TransitionReward.h @@ -0,0 +1,41 @@ +/* + * TransitionReward.h + * + * Created on: Jan 10, 2013 + * Author: chris + */ + +#ifndef TRANSITIONREWARD_H_ +#define TRANSITIONREWARD_H_ + +#include "expressions/BaseExpression.h" + +namespace storm { + +namespace ir { + +class TransitionReward { +public: + TransitionReward() : commandName(""), statePredicate(nullptr), rewardValue(nullptr) { + + } + + TransitionReward(std::string commandName, std::shared_ptr statePredicate, std::shared_ptr rewardValue) : commandName(commandName), statePredicate(statePredicate), rewardValue(rewardValue) { + + } + + std::string toString() { + return "[" + commandName + "] " + statePredicate->toString() + ": " + rewardValue->toString() + ";"; + } + +private: + std::string commandName; + std::shared_ptr statePredicate; + std::shared_ptr rewardValue; +}; + +} + +} + +#endif /* TRANSITIONREWARD_H_ */ diff --git a/src/ir/Variable.h b/src/ir/Variable.h index abb62df35..c015bb98b 100644 --- a/src/ir/Variable.h +++ b/src/ir/Variable.h @@ -14,11 +14,11 @@ namespace ir { class Variable { public: - Variable() { + Variable() : variableName(""), initialValue(nullptr) { } - Variable(std::string variableName) : variableName(variableName) { + Variable(std::string variableName, std::shared_ptr initialValue = nullptr) : variableName(variableName), initialValue(initialValue) { } @@ -34,8 +34,13 @@ public: return variableName; } + std::shared_ptr getInitialValue() { + return initialValue; + } + private: std::string variableName; + std::shared_ptr initialValue; }; } diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h index 47bd531bd..8ab6aba44 100644 --- a/src/ir/expressions/BinaryRelationExpression.h +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -35,7 +35,7 @@ public: virtual std::string toString() const { std::string result = left->toString(); switch (relation) { - case EQUAL: result += " == "; break; + case EQUAL: result += " = "; break; case LESS: result += " < "; break; case LESS_OR_EQUAL: result += " <= "; break; case GREATER: result += " > "; break; diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 5706a2273..67046b0ec 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -8,13 +8,20 @@ #ifndef PRISMPARSER_H_ #define PRISMPARSER_H_ +#include #include #include +#include +#include #include #include #include "src/ir/IR.h" +#include +#include +#include + namespace storm { namespace parser { @@ -26,43 +33,43 @@ namespace phoenix = boost::phoenix; class PrismParser { public: - void test() { - std::string testInput = "" \ - "" \ - "const bool d; const int c; const double x;" \ - "module test " \ - " a : bool;" \ - "endmodule" \ - "module test2 endmodule"; - getProgram(testInput); + void test(std::string const& fileName) { + std::ifstream inputFileStream(fileName, std::ios::in); + getProgram(inputFileStream, fileName); + inputFileStream.close(); } - void getProgram(std::string inputString) { + void getProgram(std::istream& inputStream, std::string const& fileName) { + typedef std::istreambuf_iterator base_iterator_type; + base_iterator_type in_begin(inputStream); + + typedef boost::spirit::multi_pass forward_iterator_type; + forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin); + forward_iterator_type fwd_end; + + typedef boost::spirit::classic::position_iterator2 pos_iterator_type; + pos_iterator_type position_begin(fwd_begin, fwd_end, fileName); + pos_iterator_type position_end; + storm::ir::Program result; - prismGrammar grammar(result); - std::string::const_iterator it = inputString.begin(); - std::string::const_iterator end = inputString.end(); - - storm::ir::Program realResult; - bool r = phrase_parse(it, end, grammar, ascii::space, realResult); - - if (r && it == end) { - std::cout << "Parsing successful!" << std::endl; - std::cout << realResult.toString() << std::endl; - } else { - std::string rest(it, end); - std::cout << "-------------------------\n"; - std::cout << "Parsing failed\n"; - std::cout << "stopped at: \"" << rest << "\"\n"; - std::cout << "-------------------------\n"; + prismGrammar> *(qi::char_ - qi::eol) >> qi::eol)> grammar; + try { + phrase_parse(position_begin, position_end, grammar, ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result); + } catch(const qi::expectation_failure& e) { + const boost::spirit::classic::file_position_base& pos = e.first.get_position(); + std::stringstream msg; + msg << "parse error at file '" << pos.file << "' line " << pos.line << " column " << pos.column << std::endl << "'" << e.first.get_currentline() << "'" << std::endl << std::setw(pos.column) << " " << "^- here"; + throw storm::exceptions::WrongFileFormatException() << msg.str(); } + + std::cout << result.toString(); } private: - template - struct prismGrammar : qi::grammar { + template + struct prismGrammar : qi::grammar>, std::map>, std::map>, std::map>, Skipper> { - prismGrammar(storm::ir::Program& program) : prismGrammar::base_type(start), program(program) { + prismGrammar() : prismGrammar::base_type(start) { freeIdentifierName %= qi::lexeme[(qi::alpha >> *(qi::alnum)) - allVariables_ - allConstants_]; booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; @@ -84,120 +91,167 @@ private: integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> integerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; integerExpression %= integerPlusExpression; - atomicDoubleExpression %= (qi::lit("(") >> doubleExpression >> qi::lit(")") | doubleConstantExpression); - doubleMultExpression %= atomicDoubleExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicDoubleExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; - doublePlusExpression %= doubleMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> doubleMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; - doubleExpression %= doublePlusExpression; + constantAtomicIntegerExpression %= (qi::lit("(") >> constantIntegerExpression >> qi::lit(")") | integerConstantExpression); + constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantIntegerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + constantIntegerExpression %= constantIntegerPlusExpression; + + // This block defines all expressions of type double that are by syntax constant. That is, they are evaluable given the values for all constants. + constantAtomicDoubleExpression %= (qi::lit("(") >> constantDoubleExpression >> qi::lit(")") | doubleConstantExpression); + constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicDoubleExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantDoubleMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + constantDoubleExpression %= constantDoublePlusExpression; + // This block defines all expressions of type boolean. relativeExpression = (integerExpression >> relations_ >> integerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; - atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression); - andExpression = atomicBooleanExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; + atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")") | booleanConstantExpression); + notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType::NOT))]; + andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::OR))]; booleanExpression %= orExpression; - expression %= (booleanExpression | integerExpression | doubleExpression); + // This block defines all expressions of type boolean that are by syntax constant. That is, they are evaluable given the values for all constants. + constantRelativeExpression = (constantIntegerExpression >> relations_ >> constantIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; + constantAtomicBooleanExpression %= (constantRelativeExpression | qi::lit("(") >> constantBooleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression); + constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType::NOT))]; + constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; + constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::OR))]; + constantBooleanExpression %= constantOrExpression; - booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableInfo_.add, qi::_1, qi::_val)]; - integerVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("[") >> integerConstantExpression >> qi::lit("..") >> integerConstantExpression >> qi::lit("]") >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableInfo_.add, qi::_1, qi::_val)]; - variableDefinition = (booleanVariableDefinition | integerVariableDefinition); + // This block defines the general root of all expressions. Most of the time, however, you may want to start with a more specialized rule. + expression %= (booleanExpression | integerExpression | constantDoubleExpression); - definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") >> booleanLiteralExpression >> qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; - definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") >> integerLiteralExpression >> qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; - definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") >> doubleLiteralExpression >> qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; - undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; - undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(integerConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; - undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(doubleConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; - definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); - // undefinedConstantDefinition = (undefinedBooleanConstantDefinition | undefinedIntegerConstantDefinition | undefinedDoubleConstantDefinition); - // constantDefinitionList = *(definedConstantDefinition | undefinedConstantDefinition); + stateRewardDefinition = (booleanExpression > qi::lit(":") > constantDoubleExpression >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; + transitionRewardDefinition = (qi::lit("[") > commandName > qi::lit("]") > booleanExpression > qi::lit(":") > constantDoubleExpression > qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3)]; + rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > freeIdentifierName > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) > qi::lit("endrewards"))[qi::_r1[qi::_1] = phoenix::construct(qi::_1, qi::_a, qi::_b)]; + rewardDefinitionList = *rewardDefinition(qi::_r1); + // This block defines auxiliary entities that are used to check whether a certain variable exist. integerVariableName %= integerVariableNames_; booleanVariableName %= booleanVariableNames_; + commandName %= commandNames_; - assignmentDefinition = (qi::lit("(") >> integerVariableName >> qi::lit("'") >> integerExpression >> qi::lit(")"))[qi::_val = phoenix::construct(qi::_1, qi::_2)] | (qi::lit("(") >> booleanVariableName >> qi::lit("'") >> booleanExpression >> qi::lit(")"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; + // This block defines all entities that are needed for parsing a single command. + assignmentDefinition = (qi::lit("(") >> integerVariableName > qi::lit("'") > qi::lit("=") > integerExpression > qi::lit(")"))[qi::_val = phoenix::construct(qi::_1, qi::_2)] | (qi::lit("(") > booleanVariableName > qi::lit("'") > qi::lit("=") > booleanExpression > qi::lit(")"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; assignmentDefinitionList %= assignmentDefinition % "&"; - updateDefinition = (doubleConstantExpression >> qi::lit(":") >> assignmentDefinitionList)[qi::_val = phoenix::construct(qi::_1, qi::_2)]; - updateListDefinition = +updateDefinition; - commandDefinition = (qi::lit("[") >> freeIdentifierName >> qi::lit("]") >> booleanExpression >> qi::lit("->") >> updateListDefinition >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3)]; + updateDefinition = (constantDoubleExpression > qi::lit(":") > assignmentDefinitionList)[qi::_val = phoenix::construct(qi::_1, qi::_2)]; + updateListDefinition = +updateDefinition % "+"; + commandDefinition = (qi::lit("[") > -((freeIdentifierName[phoenix::bind(commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit("->") > updateListDefinition > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; - moduleDefinition = (qi::lit("module") >> freeIdentifierName >> *(booleanVariableDefinition[phoenix::push_back(qi::_a, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> *commandDefinition >> qi::lit("endmodule"))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_3)]; + // This block defines all entities that are neede for parsing variable definitions. + booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_b), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableInfo_.add, qi::_1, qi::_val)]; + integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3, qi::_b), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableInfo_.add, qi::_1, qi::_val)]; + variableDefinition = (booleanVariableDefinition | integerVariableDefinition); - moduleDefinitionList = +moduleDefinition; + // This block defines all entities that are needed for parsing a module. + moduleDefinition = (qi::lit("module") > freeIdentifierName > *(booleanVariableDefinition[phoenix::push_back(qi::_a, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_b, qi::_1)]) > +commandDefinition > qi::lit("endmodule"))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_3)]; + moduleDefinitionList %= +moduleDefinition; + + // This block defines all entities that are needed for parsing constant definitions. + definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") > booleanLiteralExpression > qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") > integerLiteralExpression > qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") > doubleLiteralExpression > qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + undefinedBooleanConstantDefinition = (qi::lit("const") > qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), qi::_r1[qi::_1] = qi::_a, phoenix::bind(booleanConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + undefinedIntegerConstantDefinition = (qi::lit("const") > qi::lit("int") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), qi::_r1[qi::_1] = qi::_a, phoenix::bind(integerConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(integerConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + undefinedDoubleConstantDefinition = (qi::lit("const") > qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), qi::_r1[qi::_1] = qi::_a, phoenix::bind(doubleConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); + undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3)); + constantDefinitionList = *(definedConstantDefinition | undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3)); - start = (*(definedConstantDefinition | (undefinedBooleanConstantDefinition[phoenix::push_back(qi::_a, qi::_1)] | undefinedIntegerConstantDefinition[phoenix::push_back(qi::_b, qi::_1)] | undefinedDoubleConstantDefinition[phoenix::push_back(qi::_c, qi::_1)])) >> moduleDefinitionList)[qi::_val = phoenix::construct(storm::ir::Program::ModelType::DTMC, qi::_a, qi::_b, qi::_c, qi::_1)]; + // This block defines all entities that are needed for parsing a program. + modelTypeDefinition = modelType_; + start = (modelTypeDefinition > constantDefinitionList(qi::_a, qi::_b, qi::_c) > moduleDefinitionList > rewardDefinitionList(qi::_d))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_d)]; } // The starting point of the grammar. - qi::rule>,std::vector>,std::vector>>, ascii::space_type> start; - qi::rule constantDefinitionList; - qi::rule(), ascii::space_type> moduleDefinitionList; + qi::rule>, std::map>, std::map>, std::map>, Skipper> start; + qi::rule modelTypeDefinition; + qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; + qi::rule(), Skipper> moduleDefinitionList; - qi::rule, std::vector>, ascii::space_type> moduleDefinition; + qi::rule, std::vector>, Skipper> moduleDefinition; - qi::rule variableDefinition; - qi::rule>, ascii::space_type> booleanVariableDefinition; - qi::rule>, ascii::space_type> integerVariableDefinition; + qi::rule variableDefinition; + qi::rule, std::shared_ptr>, Skipper> booleanVariableDefinition; + qi::rule, std::shared_ptr>, Skipper> integerVariableDefinition; - qi::rule commandDefinition; + qi::rule, Skipper> commandDefinition; - qi::rule(), ascii::space_type> updateListDefinition; - qi::rule updateDefinition; - qi::rule(), ascii::space_type> assignmentDefinitionList; - qi::rule assignmentDefinition; + qi::rule(), Skipper> updateListDefinition; + qi::rule updateDefinition; + qi::rule(), Skipper> assignmentDefinitionList; + qi::rule assignmentDefinition; - qi::rule integerVariableName; - qi::rule booleanVariableName; + qi::rule integerVariableName; + qi::rule booleanVariableName; + qi::rule commandName; - qi::rule(), ascii::space_type> constantDefinition; - qi::rule undefinedConstantDefinition; - qi::rule(), ascii::space_type> definedConstantDefinition; - qi::rule>, ascii::space_type> undefinedBooleanConstantDefinition; - qi::rule>, ascii::space_type> undefinedIntegerConstantDefinition; - qi::rule>, ascii::space_type> undefinedDoubleConstantDefinition; - qi::rule(), ascii::space_type> definedBooleanConstantDefinition; - qi::rule(), ascii::space_type> definedIntegerConstantDefinition; - qi::rule(), ascii::space_type> definedDoubleConstantDefinition; + qi::rule&), Skipper> rewardDefinitionList; + qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; + qi::rule stateRewardDefinition; + qi::rule transitionRewardDefinition; - qi::rule freeIdentifierName; + qi::rule(), Skipper> constantDefinition; + qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; + qi::rule(), Skipper> definedConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedBooleanConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedIntegerConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedDoubleConstantDefinition; + qi::rule(), Skipper> definedBooleanConstantDefinition; + qi::rule(), Skipper> definedIntegerConstantDefinition; + qi::rule(), Skipper> definedDoubleConstantDefinition; + + qi::rule freeIdentifierName; // The starting point for arbitrary expressions. - qi::rule(), ascii::space_type> expression; + qi::rule(), Skipper> expression; // Rules with boolean result type. - qi::rule(), ascii::space_type> booleanExpression; - qi::rule(), ascii::space_type> orExpression; - qi::rule(), ascii::space_type> andExpression; - qi::rule(), ascii::space_type> atomicBooleanExpression; - qi::rule(), ascii::space_type> relativeExpression; + qi::rule(), Skipper> booleanExpression; + qi::rule(), Skipper> orExpression; + qi::rule(), Skipper> andExpression; + qi::rule(), Skipper> notExpression; + qi::rule(), Skipper> atomicBooleanExpression; + qi::rule(), Skipper> relativeExpression; + qi::rule(), Skipper> constantBooleanExpression; + qi::rule(), Skipper> constantOrExpression; + qi::rule(), Skipper> constantAndExpression; + qi::rule(), Skipper> constantNotExpression; + qi::rule(), Skipper> constantAtomicBooleanExpression; + qi::rule(), Skipper> constantRelativeExpression; // Rules with integer result type. - qi::rule(), ascii::space_type> integerExpression; - qi::rule(), ascii::space_type> integerPlusExpression; - qi::rule(), ascii::space_type> integerMultExpression; - qi::rule(), ascii::space_type> atomicIntegerExpression; + qi::rule(), Skipper> integerExpression; + qi::rule(), Skipper> integerPlusExpression; + qi::rule(), Skipper> integerMultExpression; + qi::rule(), Skipper> atomicIntegerExpression; + qi::rule(), Skipper> constantIntegerExpression; + qi::rule(), Skipper> constantIntegerPlusExpression; + qi::rule(), Skipper> constantIntegerMultExpression; + qi::rule(), Skipper> constantAtomicIntegerExpression; // Rules with double result type. - qi::rule(), ascii::space_type> doubleExpression; - qi::rule(), ascii::space_type> doublePlusExpression; - qi::rule(), ascii::space_type> doubleMultExpression; - qi::rule(), ascii::space_type> atomicDoubleExpression; + qi::rule(), Skipper> constantDoubleExpression; + qi::rule(), Skipper> constantDoublePlusExpression; + qi::rule(), Skipper> constantDoubleMultExpression; + qi::rule(), Skipper> constantAtomicDoubleExpression; // Rules for variable recognition. - qi::rule(), ascii::space_type> variableExpression; - qi::rule(), ascii::space_type> booleanVariableExpression; - qi::rule(), ascii::space_type> integerVariableExpression; + qi::rule(), Skipper> variableExpression; + qi::rule(), Skipper> booleanVariableExpression; + qi::rule(), Skipper> integerVariableExpression; // Rules for constant recognition. - qi::rule(), ascii::space_type> constantExpression; - qi::rule(), ascii::space_type> booleanConstantExpression; - qi::rule(), ascii::space_type> integerConstantExpression; - qi::rule(), ascii::space_type> doubleConstantExpression; + qi::rule(), Skipper> constantExpression; + qi::rule(), Skipper> booleanConstantExpression; + qi::rule(), Skipper> integerConstantExpression; + qi::rule(), Skipper> doubleConstantExpression; // Rules for literal recognition. - qi::rule(), ascii::space_type> literalExpression; - qi::rule(), ascii::space_type> booleanLiteralExpression; - qi::rule(), ascii::space_type> integerLiteralExpression; - qi::rule(), ascii::space_type> doubleLiteralExpression; + qi::rule(), Skipper> literalExpression; + qi::rule(), Skipper> booleanLiteralExpression; + qi::rule(), Skipper> integerLiteralExpression; + qi::rule(), Skipper> doubleLiteralExpression; struct keywordsStruct : qi::symbols { keywordsStruct() { @@ -219,10 +273,21 @@ private: } } keywords_; + struct modelTypeStruct : qi::symbols { + modelTypeStruct() { + add + ("dtmc", storm::ir::Program::ModelType::DTMC) + ("ctmc", storm::ir::Program::ModelType::CTMC) + ("mdp", storm::ir::Program::ModelType::MDP) + ("ctmdp", storm::ir::Program::ModelType::CTMDP) + ; + } + } modelType_; + struct relationalOperatorStruct : qi::symbols { relationalOperatorStruct() { add - ("==", storm::ir::expressions::BinaryRelationExpression::EQUAL) + ("=", storm::ir::expressions::BinaryRelationExpression::EQUAL) ("<", storm::ir::expressions::BinaryRelationExpression::LESS) ("<=", storm::ir::expressions::BinaryRelationExpression::LESS_OR_EQUAL) (">", storm::ir::expressions::BinaryRelationExpression::GREATER) @@ -235,9 +300,9 @@ private: // Intentionally left empty. This map is filled during parsing. } integerVariables_, booleanVariables_, allVariables_; - struct variableNamesStruct : qi::symbols { + struct entityNamesStruct : qi::symbols { // Intentionally left empty. This map is filled during parsing. - } integerVariableNames_, booleanVariableNames_; + } integerVariableNames_, booleanVariableNames_, commandNames_; struct booleanVariableTypesStruct : qi::symbols { // Intentionally left empty. This map is filled during parsing. @@ -266,8 +331,6 @@ private: struct modulesStruct : qi::symbols { // Intentionally left empty. This map is filled during parsing. } modules_; - - storm::ir::Program& program; }; }; diff --git a/src/storm.cpp b/src/storm.cpp index 0a08d6064..faba3559b 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -241,7 +241,7 @@ int main(const int argc, const char* argv[]) { // testChecking(); storm::parser::PrismParser parser; - parser.test(); + parser.test("test.input"); cleanUp(); return 0; diff --git a/test.input b/test.input new file mode 100644 index 000000000..e2e86d63a --- /dev/null +++ b/test.input @@ -0,0 +1,19 @@ +dtmc + +module die + +// local state +s : [0..7] init 0; +// value of the dice +d : [0..6] init 0; + +[] s=0 -> 0.5 : (s'=1) + 0.5 : (s'=2); +[] s=1 -> 0.5 : (s'=3) + 0.5 : (s'=4); +[] s=2 -> 0.5 : (s'=5) + 0.5 : (s'=6); +[] s=3 -> 0.5 : (s'=1) + 0.5 : (s'=7) & (d'=1); +[] s=4 -> 0.5 : (s'=7) & (d'=2) + 0.5 : (s'=7) & (d'=3); +[] s=5 -> 0.5 : (s'=7) & (d'=4) + 0.5 : (s'=7) & (d'=5); +[] s=6 -> 0.5 : (s'=2) + 0.5 : (s'=7) & (d'=6); +[] s==7 -> 1 : (s'=7); + +endmodule From 6a33f845122b14213b6d61f00ee84c8e08e440a4 Mon Sep 17 00:00:00 2001 From: dehnert Date: Fri, 11 Jan 2013 00:12:28 +0100 Subject: [PATCH 008/152] Another step towards PRISM model parsing: small models get recognized correctly. --- src/ir/Program.h | 2 ++ src/ir/RewardModel.h | 8 +++++++- src/ir/StateReward.h | 2 +- src/ir/TransitionReward.h | 2 +- src/parser/PrismParser.h | 17 +++++++++-------- test.input | 11 ++++++++++- 6 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/ir/Program.h b/src/ir/Program.h index 2ee72c08d..e2b94af57 100644 --- a/src/ir/Program.h +++ b/src/ir/Program.h @@ -12,6 +12,8 @@ #include "Module.h" #include "RewardModel.h" +#include + namespace storm { namespace ir { diff --git a/src/ir/RewardModel.h b/src/ir/RewardModel.h index 746eea70e..21c08fa75 100644 --- a/src/ir/RewardModel.h +++ b/src/ir/RewardModel.h @@ -8,6 +8,8 @@ #ifndef REWARDMODEL_H_ #define REWARDMODEL_H_ +#include + namespace storm { namespace ir { @@ -22,8 +24,12 @@ public: } + RewardModel(RewardModel const& other) : rewardModelName(other.rewardModelName), stateRewards(other.stateRewards), transitionRewards(other.transitionRewards) { + + } + std::string toString() { - std::string result = "rewards \"" + rewardModelName + "\n"; + std::string result = "rewards \"" + rewardModelName + "\"\n"; for (auto reward : stateRewards) { result += reward.toString() + "\n"; } diff --git a/src/ir/StateReward.h b/src/ir/StateReward.h index 2a0d23b69..9128c74ff 100644 --- a/src/ir/StateReward.h +++ b/src/ir/StateReward.h @@ -25,7 +25,7 @@ public: } std::string toString() { - return statePredicate->toString() + ": " + rewardValue->toString() + ";"; + return "\t" + statePredicate->toString() + ": " + rewardValue->toString() + ";"; } private: diff --git a/src/ir/TransitionReward.h b/src/ir/TransitionReward.h index 2181d5b05..d444560ec 100644 --- a/src/ir/TransitionReward.h +++ b/src/ir/TransitionReward.h @@ -25,7 +25,7 @@ public: } std::string toString() { - return "[" + commandName + "] " + statePredicate->toString() + ": " + rewardValue->toString() + ";"; + return "\t[" + commandName + "] " + statePredicate->toString() + ": " + rewardValue->toString() + ";"; } private: diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 67046b0ec..74735e5c9 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -58,7 +58,8 @@ public: } catch(const qi::expectation_failure& e) { const boost::spirit::classic::file_position_base& pos = e.first.get_position(); std::stringstream msg; - msg << "parse error at file '" << pos.file << "' line " << pos.line << " column " << pos.column << std::endl << "'" << e.first.get_currentline() << "'" << std::endl << std::setw(pos.column) << " " << "^- here"; + msg << "parse error at file '" << pos.file << "' line " << pos.line << " column " << pos.column << std::endl << "'" << e.first.get_currentline() << "'" << std::endl << std::setw(pos.column + 1) << " " << "^------- here"; + std::cout << msg.str() << std::endl; throw storm::exceptions::WrongFileFormatException() << msg.str(); } @@ -70,7 +71,7 @@ private: struct prismGrammar : qi::grammar>, std::map>, std::map>, std::map>, Skipper> { prismGrammar() : prismGrammar::base_type(start) { - freeIdentifierName %= qi::lexeme[(qi::alpha >> *(qi::alnum)) - allVariables_ - allConstants_]; + freeIdentifierName %= qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))] - allVariables_ - allConstants_; booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; @@ -122,8 +123,8 @@ private: expression %= (booleanExpression | integerExpression | constantDoubleExpression); stateRewardDefinition = (booleanExpression > qi::lit(":") > constantDoubleExpression >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; - transitionRewardDefinition = (qi::lit("[") > commandName > qi::lit("]") > booleanExpression > qi::lit(":") > constantDoubleExpression > qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3)]; - rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > freeIdentifierName > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) > qi::lit("endrewards"))[qi::_r1[qi::_1] = phoenix::construct(qi::_1, qi::_a, qi::_b)]; + transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit(":") > constantDoubleExpression > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; + rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > freeIdentifierName > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) > qi::lit("endrewards"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_a, qi::_b)))]; rewardDefinitionList = *rewardDefinition(qi::_r1); // This block defines auxiliary entities that are used to check whether a certain variable exist. @@ -151,9 +152,9 @@ private: definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") > booleanLiteralExpression > qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") > integerLiteralExpression > qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") > doubleLiteralExpression > qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; - undefinedBooleanConstantDefinition = (qi::lit("const") > qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), qi::_r1[qi::_1] = qi::_a, phoenix::bind(booleanConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; - undefinedIntegerConstantDefinition = (qi::lit("const") > qi::lit("int") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), qi::_r1[qi::_1] = qi::_a, phoenix::bind(integerConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(integerConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; - undefinedDoubleConstantDefinition = (qi::lit("const") > qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), qi::_r1[qi::_1] = qi::_a, phoenix::bind(doubleConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(booleanConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(integerConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(integerConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(doubleConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3)); constantDefinitionList = *(definedConstantDefinition | undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3)); @@ -189,7 +190,7 @@ private: qi::rule&), Skipper> rewardDefinitionList; qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; qi::rule stateRewardDefinition; - qi::rule transitionRewardDefinition; + qi::rule, Skipper> transitionRewardDefinition; qi::rule(), Skipper> constantDefinition; qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; diff --git a/test.input b/test.input index e2e86d63a..1b6636c6b 100644 --- a/test.input +++ b/test.input @@ -1,5 +1,9 @@ dtmc +const bool sic; +const int i; +const double e; + module die // local state @@ -14,6 +18,11 @@ d : [0..6] init 0; [] s=4 -> 0.5 : (s'=7) & (d'=2) + 0.5 : (s'=7) & (d'=3); [] s=5 -> 0.5 : (s'=7) & (d'=4) + 0.5 : (s'=7) & (d'=5); [] s=6 -> 0.5 : (s'=2) + 0.5 : (s'=7) & (d'=6); -[] s==7 -> 1 : (s'=7); +[] s=7 -> 1 : (s'=7); endmodule + +rewards "coin_flips" + [] s<7 : 1; + s>3 : 1; +endrewards From f52201466c5d7315fc2fc6930863aa461da4569a Mon Sep 17 00:00:00 2001 From: dehnert Date: Fri, 11 Jan 2013 16:56:00 +0100 Subject: [PATCH 009/152] Parsing labels works now. --- CMakeLists.txt | 31 +++++- src/ir/Command.h | 3 +- src/ir/IntegerVariable.h | 1 + src/ir/Module.h | 12 +-- src/ir/Program.h | 28 +++--- src/ir/Update.h | 2 +- src/ir/expressions/VariableExpression.h | 6 +- src/parser/PrismParser.h | 126 +++++++++++++++++++----- test.input | 8 +- 9 files changed, 155 insertions(+), 62 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index df1e897f5..a52cf47ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,10 @@ message(STATUS "GMMXX_INCLUDE_DIR is ${GMMXX_INCLUDE_DIR}") option(DEBUG "Sets whether the DEBUG mode is used" ON) option(USE_POPCNT "Sets whether the popcnt instruction is going to be used." ON) option(USE_BOOST_STATIC_LIBRARIES "Sets whether the Boost libraries should be linked statically." ON) +option(LINK_LIBCXXABI "Sets whether libc++abi should be linked" OFF) +set(ADDITIONAL_INCLUDE_DIRS "" CACHE STRING "Additional directories added to the include directories.") +set(ADDITIONAL_LINK_DIRS "" CACHE STRING "Additional directories added to the link directories.") +set(CUSTOM_BOOST_ROOT "" CACHE STRING "A custom path to the Boost root directory.") # If the DEBUG option was turned on, we will target a debug version and a release version otherwise if (DEBUG) @@ -74,9 +78,12 @@ elseif(MSVC) # required for GMM to compile, ugly error directive in their code add_definitions(/D_SCL_SECURE_NO_DEPRECATE) else(CLANG) + # As CLANG is not set as a variable, we need to set it in case we have not matched another compiler. + set (CLANG ON) # Set standard flags for clang set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -funroll-loops") - set (CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Wall -Werror -pedantic -Wno-unused-variable -DBOOST_RESULT_OF_USE_TR1 -DBOOST_NO_DECLTYPE") + # TODO: activate -Werror asap + set (CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Wall -pedantic -Wno-unused-variable -DBOOST_RESULT_OF_USE_TR1 -DBOOST_NO_DECLTYPE") # Turn on popcnt instruction if desired (yes by default) if (USE_POPCNT) @@ -118,6 +125,11 @@ find_package(Doxygen REQUIRED) set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) set(Boost_USE_STATIC_RUNTIME OFF) + +# If a custom boost root directory was specified, we set the corresponding hint for the script to find it. +if(CUSTOM_BOOST_ROOT) + set(BOOST_ROOT "${CUSTOM_BOOST_ROOT}") +endif(CUSTOM_BOOST_ROOT) find_package(Boost REQUIRED COMPONENTS program_options) if(Boost_FOUND) @@ -138,6 +150,16 @@ include_directories(${EIGEN3_INCLUDE_DIR}) # Add GMMXX to the included directories include_directories(${GMMXX_INCLUDE_DIR}) +# Add custom additional include or link directories +if (ADDITIONAL_INCLUDE_DIRS) + message(STATUS "Using additional include directories ${ADDITIONAL_INCLUDE_DIRS}") + include_directories(${ADDITIONAL_INCLUDE_DIRS}) +endif(ADDITIONAL_INCLUDE_DIRS) +if (ADDITIONAL_LINK_DIRS) + message(STATUS "Using additional link directories ${ADDITIONAL_LINK_DIRS}") + link_directories(${ADDITIONAL_LINK_DIRS}) +endif(ADDITIONAL_LINK_DIRS) + # Add the executables # Must be created *after* Boost was added because of LINK_DIRECTORIES add_executable(storm ${STORM_SOURCES} ${STORM_HEADERS}) @@ -147,6 +169,13 @@ add_executable(storm-tests ${STORM_TEST_SOURCES} ${STORM_TEST_HEADERS}) target_link_libraries(storm ${Boost_LIBRARIES}) target_link_libraries(storm-tests ${Boost_LIBRARIES}) +# Link against libc++abi if requested. May be needed to build on Linux systems using clang. +if (LINK_LIBCXXABI) + message (STATUS "Linking against libc++abi.") + target_link_libraries(storm "c++abi") + target_link_libraries(storm-tests "c++abi") +endif(LINK_LIBCXXABI) + # Add a target to generate API documentation with Doxygen if(DOXYGEN_FOUND) set(CMAKE_DOXYGEN_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc") diff --git a/src/ir/Command.h b/src/ir/Command.h index 9a687eab6..c5bfee6d5 100644 --- a/src/ir/Command.h +++ b/src/ir/Command.h @@ -8,7 +8,8 @@ #ifndef COMMAND_H_ #define COMMAND_H_ -#include "IR.h" +#include "expressions/BaseExpression.h" +#include "Update.h" namespace storm { diff --git a/src/ir/IntegerVariable.h b/src/ir/IntegerVariable.h index abde92cb3..78c638954 100644 --- a/src/ir/IntegerVariable.h +++ b/src/ir/IntegerVariable.h @@ -9,6 +9,7 @@ #define INTEGERVARIABLE_H_ #include "Variable.h" +#include "expressions/BaseExpression.h" namespace storm { diff --git a/src/ir/Module.h b/src/ir/Module.h index a1046db76..bb3142328 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -8,7 +8,9 @@ #ifndef MODULE_H_ #define MODULE_H_ -#include "IR.h" +#include "BooleanVariable.h" +#include "IntegerVariable.h" +#include "Command.h" namespace storm { @@ -44,14 +46,6 @@ public: return result; } - void addBooleanVariable(storm::ir::BooleanVariable variable) { - booleanVariables.push_back(variable); - } - - void addIntegerVariable(storm::ir::IntegerVariable variable) { - integerVariables.push_back(variable); - } - private: std::string moduleName; diff --git a/src/ir/Program.h b/src/ir/Program.h index e2b94af57..57a6ac11a 100644 --- a/src/ir/Program.h +++ b/src/ir/Program.h @@ -8,12 +8,13 @@ #ifndef PROGRAM_H_ #define PROGRAM_H_ -#include "src/ir/expressions/ConstantExpression.h" +#include "expressions/BaseExpression.h" +#include "expressions/BooleanConstantExpression.h" +#include "expressions/IntegerConstantExpression.h" +#include "expressions/DoubleConstantExpression.h" #include "Module.h" #include "RewardModel.h" -#include - namespace storm { namespace ir { @@ -27,8 +28,8 @@ public: } - Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector modules, std::map rewards) - : modelType(modelType), booleanUndefinedConstantExpressions(booleanUndefinedConstantExpressions), integerUndefinedConstantExpressions(integerUndefinedConstantExpressions), doubleUndefinedConstantExpressions(doubleUndefinedConstantExpressions), modules(modules), rewards(rewards) { + Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector modules, std::map rewards, std::map> labels) + : modelType(modelType), booleanUndefinedConstantExpressions(booleanUndefinedConstantExpressions), integerUndefinedConstantExpressions(integerUndefinedConstantExpressions), doubleUndefinedConstantExpressions(doubleUndefinedConstantExpressions), modules(modules), rewards(rewards), labels(labels) { } @@ -71,19 +72,11 @@ public: result +="\n"; } - return result; - } - - void addBooleanUndefinedConstantExpression(std::string constantName, std::shared_ptr constantExpression) { - booleanUndefinedConstantExpressions[constantName] = constantExpression; - } - - void addIntegerUndefinedConstantExpression(std::string constantName, std::shared_ptr constantExpression) { - integerUndefinedConstantExpressions[constantName] = constantExpression; - } + for (auto label : labels) { + result += "label " + label.first + " = " + label.second->toString() + ";\n"; + } - void addDoubleUndefinedConstantExpression(std::string constantName, std::shared_ptr constantExpression) { - doubleUndefinedConstantExpressions[constantName] = constantExpression; + return result; } private: @@ -93,6 +86,7 @@ private: std::map> doubleUndefinedConstantExpressions; std::vector modules; std::map rewards; + std::map> labels; }; } diff --git a/src/ir/Update.h b/src/ir/Update.h index e2751703a..1ea4b0dc1 100644 --- a/src/ir/Update.h +++ b/src/ir/Update.h @@ -8,7 +8,7 @@ #ifndef UPDATE_H_ #define UPDATE_H_ -#include "IR.h" +#include "expressions/BaseExpression.h" namespace storm { diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index 9a1121503..5eceb7c6b 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -10,6 +10,8 @@ #include "src/ir/expressions/BaseExpression.h" +#include + namespace storm { namespace ir { @@ -20,8 +22,8 @@ class VariableExpression : public BaseExpression { public: std::string variableName; - VariableExpression(std::string variableName) { - this->variableName = variableName; + VariableExpression(std::string variableName) : variableName(variableName) { + } virtual ~VariableExpression() { diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 74735e5c9..582f2dafb 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -30,6 +30,10 @@ namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; namespace phoenix = boost::phoenix; +typedef std::istreambuf_iterator base_iterator_type; +typedef boost::spirit::multi_pass forward_iterator_type; +typedef boost::spirit::classic::position_iterator2 pos_iterator_type; + class PrismParser { public: @@ -40,14 +44,11 @@ public: } void getProgram(std::istream& inputStream, std::string const& fileName) { - typedef std::istreambuf_iterator base_iterator_type; base_iterator_type in_begin(inputStream); - typedef boost::spirit::multi_pass forward_iterator_type; forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin); forward_iterator_type fwd_end; - typedef boost::spirit::classic::position_iterator2 pos_iterator_type; pos_iterator_type position_begin(fwd_begin, fwd_end, fileName); pos_iterator_type position_end; @@ -58,8 +59,17 @@ public: } catch(const qi::expectation_failure& e) { const boost::spirit::classic::file_position_base& pos = e.first.get_position(); std::stringstream msg; - msg << "parse error at file '" << pos.file << "' line " << pos.line << " column " << pos.column << std::endl << "'" << e.first.get_currentline() << "'" << std::endl << std::setw(pos.column + 1) << " " << "^------- here"; - std::cout << msg.str() << std::endl; + msg << pos.file << ", line " << pos.line << ", column " << pos.column << ": parse error: expected " << e.what_ << std::endl << "\t" << e.first.get_currentline() << std::endl << "\t"; + int i = 0; + for (i = 0; i < pos.column; ++i) { + msg << "-"; + } + msg << "^"; + for (; i < 80; ++i) { + msg << "-"; + } + msg << std::endl; + std::cout << msg.str(); throw storm::exceptions::WrongFileFormatException() << msg.str(); } @@ -68,104 +78,174 @@ public: private: template - struct prismGrammar : qi::grammar>, std::map>, std::map>, std::map>, Skipper> { + struct prismGrammar : qi::grammar>, std::map>, std::map>, std::map, std::map>>, Skipper> { prismGrammar() : prismGrammar::base_type(start) { - freeIdentifierName %= qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))] - allVariables_ - allConstants_; + freeIdentifierName %= qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_'))) - booleanVariables_ - integerVariables_ - allConstants_]]; + freeIdentifierName.name("unused identifier"); booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + booleanLiteralExpression.name("boolean literal"); integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + integerLiteralExpression.name("integer literal"); doubleLiteralExpression = qi::double_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + doubleLiteralExpression.name("double literal"); literalExpression %= (booleanLiteralExpression | integerLiteralExpression | doubleLiteralExpression); + literalExpression.name("literal"); - integerVariableExpression = integerVariables_; - booleanVariableExpression = booleanVariables_; - variableExpression = (integerVariableExpression | booleanVariableExpression); + integerVariableExpression %= integerVariables_; + integerVariableExpression.name("integer variable"); + booleanVariableExpression %= booleanVariables_; + booleanVariableExpression.name("boolean variable"); + variableExpression %= (integerVariableExpression | booleanVariableExpression); + variableExpression.name("variable"); booleanConstantExpression %= (booleanConstants_ | booleanLiteralExpression); + booleanConstantExpression.name("boolean constant or literal"); integerConstantExpression %= (integerConstants_ | integerLiteralExpression); + integerConstantExpression.name("integer constant or literal"); doubleConstantExpression %= (doubleConstants_ | doubleLiteralExpression); + doubleConstantExpression.name("double constant or literal"); constantExpression %= (booleanConstantExpression | integerConstantExpression | doubleConstantExpression); + constantExpression.name("constant or literal"); atomicIntegerExpression %= (integerVariableExpression | qi::lit("(") >> integerExpression >> qi::lit(")") | integerConstantExpression); + atomicIntegerExpression.name("integer expression"); integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + integerMultExpression.name("integer expression"); integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> integerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + integerPlusExpression.name("integer expression"); integerExpression %= integerPlusExpression; + integerExpression.name("integer expression"); constantAtomicIntegerExpression %= (qi::lit("(") >> constantIntegerExpression >> qi::lit(")") | integerConstantExpression); + constantAtomicIntegerExpression.name("constant integer expression"); constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + constantIntegerMultExpression.name("constant integer expression"); constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantIntegerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + constantIntegerPlusExpression.name("constant integer expression"); constantIntegerExpression %= constantIntegerPlusExpression; + constantIntegerExpression.name("constant integer expression"); // This block defines all expressions of type double that are by syntax constant. That is, they are evaluable given the values for all constants. constantAtomicDoubleExpression %= (qi::lit("(") >> constantDoubleExpression >> qi::lit(")") | doubleConstantExpression); + constantAtomicDoubleExpression.name("constant double expression"); constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicDoubleExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + constantDoubleMultExpression.name("constant double expression"); constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantDoubleMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + constantDoublePlusExpression.name("constant double expression"); constantDoubleExpression %= constantDoublePlusExpression; + constantDoubleExpression.name("constant double expression"); // This block defines all expressions of type boolean. relativeExpression = (integerExpression >> relations_ >> integerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; + relativeExpression.name("boolean expression"); atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")") | booleanConstantExpression); + atomicBooleanExpression.name("boolean expression"); notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType::NOT))]; + notExpression.name("boolean expression"); andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; + andExpression.name("boolean expression"); orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::OR))]; + orExpression.name("boolean expression"); booleanExpression %= orExpression; + booleanExpression.name("boolean expression"); // This block defines all expressions of type boolean that are by syntax constant. That is, they are evaluable given the values for all constants. constantRelativeExpression = (constantIntegerExpression >> relations_ >> constantIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; + constantRelativeExpression.name("constant boolean expression"); constantAtomicBooleanExpression %= (constantRelativeExpression | qi::lit("(") >> constantBooleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression); + constantAtomicBooleanExpression.name("constant boolean expression"); constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType::NOT))]; + constantNotExpression.name("constant boolean expression"); constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; + constantAndExpression.name("constant boolean expression"); constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::OR))]; + constantOrExpression.name("constant boolean expression"); constantBooleanExpression %= constantOrExpression; + constantBooleanExpression.name("constant boolean expression"); // This block defines the general root of all expressions. Most of the time, however, you may want to start with a more specialized rule. expression %= (booleanExpression | integerExpression | constantDoubleExpression); + expression.name("expression"); + // This block defines all entities that are needed for parsing labels. + labelDefinition = (qi::lit("label") >> freeIdentifierName >> qi::lit("=") >> booleanExpression >> qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_2))]; + labelDefinitionList %= *labelDefinition(qi::_r1); + + // This block defines all entities that are needed for parsing a reward model. stateRewardDefinition = (booleanExpression > qi::lit(":") > constantDoubleExpression >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; + stateRewardDefinition.name("state reward definition"); transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit(":") > constantDoubleExpression > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; - rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > freeIdentifierName > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) > qi::lit("endrewards"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_a, qi::_b)))]; + transitionRewardDefinition.name("transition reward definition"); + rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > freeIdentifierName > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> qi::lit("endrewards"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_a, qi::_b)))]; + rewardDefinition.name("reward definition"); rewardDefinitionList = *rewardDefinition(qi::_r1); + rewardDefinitionList.name("reward definition list"); // This block defines auxiliary entities that are used to check whether a certain variable exist. - integerVariableName %= integerVariableNames_; booleanVariableName %= booleanVariableNames_; + booleanVariableName.name("boolean variable"); + integerVariableName %= integerVariableNames_; + integerVariableName.name("integer variable"); commandName %= commandNames_; + commandName.name("command name"); // This block defines all entities that are needed for parsing a single command. assignmentDefinition = (qi::lit("(") >> integerVariableName > qi::lit("'") > qi::lit("=") > integerExpression > qi::lit(")"))[qi::_val = phoenix::construct(qi::_1, qi::_2)] | (qi::lit("(") > booleanVariableName > qi::lit("'") > qi::lit("=") > booleanExpression > qi::lit(")"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; + assignmentDefinition.name("assignment"); assignmentDefinitionList %= assignmentDefinition % "&"; + assignmentDefinitionList.name("assignment list"); updateDefinition = (constantDoubleExpression > qi::lit(":") > assignmentDefinitionList)[qi::_val = phoenix::construct(qi::_1, qi::_2)]; + updateDefinition.name("update"); updateListDefinition = +updateDefinition % "+"; + updateListDefinition.name("update list"); commandDefinition = (qi::lit("[") > -((freeIdentifierName[phoenix::bind(commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit("->") > updateListDefinition > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; + commandDefinition.name("command"); // This block defines all entities that are neede for parsing variable definitions. - booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_b), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableInfo_.add, qi::_1, qi::_val)]; - integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3, qi::_b), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(allVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableInfo_.add, qi::_1, qi::_val)]; + booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[qi::_val = phoenix::construct(phoenix::val("hallo"), qi::_b), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), std::cout << phoenix::val("here!"), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1)]; + booleanVariableDefinition.name("boolean variable declaration"); + integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3, qi::_b), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1)]; + integerVariableDefinition.name("integer variable declaration"); variableDefinition = (booleanVariableDefinition | integerVariableDefinition); + variableDefinition.name("variable declaration"); // This block defines all entities that are needed for parsing a module. moduleDefinition = (qi::lit("module") > freeIdentifierName > *(booleanVariableDefinition[phoenix::push_back(qi::_a, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_b, qi::_1)]) > +commandDefinition > qi::lit("endmodule"))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_3)]; + moduleDefinition.name("module"); moduleDefinitionList %= +moduleDefinition; + moduleDefinitionList.name("module list"); // This block defines all entities that are needed for parsing constant definitions. definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") > booleanLiteralExpression > qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + definedBooleanConstantDefinition.name("defined boolean constant declaration"); definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") > integerLiteralExpression > qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + definedIntegerConstantDefinition.name("defined integer constant declaration"); definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") > doubleLiteralExpression > qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + definedDoubleConstantDefinition.name("defined double constant declaration"); undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(booleanConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + undefinedBooleanConstantDefinition.name("undefined boolean constant declaration"); undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(integerConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(integerConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + undefinedIntegerConstantDefinition.name("undefined integer constant declaration"); undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(doubleConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + undefinedDoubleConstantDefinition.name("undefined double constant declaration"); definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); + definedConstantDefinition.name("defined constant declaration"); undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3)); + undefinedConstantDefinition.name("undefined constant declaration"); constantDefinitionList = *(definedConstantDefinition | undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3)); + constantDefinitionList.name("constant declaration list"); // This block defines all entities that are needed for parsing a program. modelTypeDefinition = modelType_; - start = (modelTypeDefinition > constantDefinitionList(qi::_a, qi::_b, qi::_c) > moduleDefinitionList > rewardDefinitionList(qi::_d))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_d)]; + modelTypeDefinition.name("model type"); + start = (modelTypeDefinition > constantDefinitionList(qi::_a, qi::_b, qi::_c) > moduleDefinitionList > rewardDefinitionList(qi::_d) > labelDefinitionList(qi::_e))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_d, qi::_e)]; + start.name("probabilistic program declaration"); } // The starting point of the grammar. - qi::rule>, std::map>, std::map>, std::map>, Skipper> start; + qi::rule>, std::map>, std::map>, std::map, std::map>>, Skipper> start; qi::rule modelTypeDefinition; qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; qi::rule(), Skipper> moduleDefinitionList; @@ -192,6 +272,9 @@ private: qi::rule stateRewardDefinition; qi::rule, Skipper> transitionRewardDefinition; + qi::rule>&), Skipper> labelDefinitionList; + qi::rule>&), Skipper> labelDefinition; + qi::rule(), Skipper> constantDefinition; qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; qi::rule(), Skipper> definedConstantDefinition; @@ -203,6 +286,7 @@ private: qi::rule(), Skipper> definedDoubleConstantDefinition; qi::rule freeIdentifierName; + qi::rule identifierName; // The starting point for arbitrary expressions. qi::rule(), Skipper> expression; @@ -299,20 +383,12 @@ private: struct variablesStruct : qi::symbols> { // Intentionally left empty. This map is filled during parsing. - } integerVariables_, booleanVariables_, allVariables_; + } integerVariables_, booleanVariables_; struct entityNamesStruct : qi::symbols { // Intentionally left empty. This map is filled during parsing. } integerVariableNames_, booleanVariableNames_, commandNames_; - struct booleanVariableTypesStruct : qi::symbols { - // Intentionally left empty. This map is filled during parsing. - } booleanVariableInfo_; - - struct integerVariableTypesStruct : qi::symbols { - // Intentionally left empty. This map is filled during parsing. - } integerVariableInfo_; - struct constantsStruct : qi::symbols> { // Intentionally left empty. This map is filled during parsing. } integerConstants_, booleanConstants_, doubleConstants_, allConstants_; diff --git a/test.input b/test.input index 1b6636c6b..5339a8416 100644 --- a/test.input +++ b/test.input @@ -1,11 +1,6 @@ dtmc -const bool sic; -const int i; -const double e; - module die - // local state s : [0..7] init 0; // value of the dice @@ -19,10 +14,11 @@ d : [0..6] init 0; [] s=5 -> 0.5 : (s'=7) & (d'=4) + 0.5 : (s'=7) & (d'=5); [] s=6 -> 0.5 : (s'=2) + 0.5 : (s'=7) & (d'=6); [] s=7 -> 1 : (s'=7); - endmodule rewards "coin_flips" [] s<7 : 1; s>3 : 1; endrewards + +label test = s>2; From 4b7c6a894198efc9a241e13416607841874971a7 Mon Sep 17 00:00:00 2001 From: dehnert Date: Fri, 11 Jan 2013 19:53:35 +0100 Subject: [PATCH 010/152] Splitted PrismParser class into header and implementation file. Commented both files properly. Cleaned interface of PrismParser. --- src/ir/expressions/DoubleLiteral.h | 2 + src/parser/PrismParser.cpp | 115 ++++++++++++++++++++ src/parser/PrismParser.h | 166 +++++++++++++---------------- src/storm.cpp | 2 +- 4 files changed, 195 insertions(+), 90 deletions(-) create mode 100644 src/parser/PrismParser.cpp diff --git a/src/ir/expressions/DoubleLiteral.h b/src/ir/expressions/DoubleLiteral.h index 8aca54125..d88dbf33b 100644 --- a/src/ir/expressions/DoubleLiteral.h +++ b/src/ir/expressions/DoubleLiteral.h @@ -10,6 +10,8 @@ #include "src/ir/expressions/BaseExpression.h" +#include "boost/lexical_cast.hpp" + namespace storm { namespace ir { diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp new file mode 100644 index 000000000..f3348cb19 --- /dev/null +++ b/src/parser/PrismParser.cpp @@ -0,0 +1,115 @@ +/* + * PrismParser.cpp + * + * Created on: 11.01.2013 + * Author: chris + */ + +#include "PrismParser.h" +#include "src/utility/OsDetection.h" + +// If the parser fails due to ill-formed data, this exception is thrown. +#include "src/exceptions/WrongFileFormatException.h" + +// Include headers for spirit iterators. Needed for diagnostics and input stream iteration. +#include +#include + +// Needed for file IO. +#include +#include + +// Some typedefs and namespace definitions to reduce code size. +typedef std::istreambuf_iterator base_iterator_type; +typedef boost::spirit::multi_pass forward_iterator_type; +typedef boost::spirit::classic::position_iterator2 pos_iterator_type; +namespace qi = boost::spirit::qi; +namespace phoenix = boost::phoenix; + +namespace storm { + +namespace parser { + +/*! + * Opens the given file for parsing, invokes the helper function to parse the actual content and + * closes the file properly, even if an exception is thrown in the parser. In this case, the + * exception is passed on to the caller. + */ +std::shared_ptr PrismParser::parseFile(std::string const& filename) const { + // Open file and initialize result. + std::ifstream inputFileStream(filename, std::ios::in); + std::shared_ptr result(nullptr); + + // Now try to parse the contents of the file. + try { + result = std::shared_ptr(parse(inputFileStream, filename)); + } catch(std::exception& e) { + // In case of an exception properly close the file before passing exception. + inputFileStream.close(); + throw e; + } + + // Close the stream in case everything went smoothly and return result. + inputFileStream.close(); + return result; +} + +/*! + * Passes iterators to the input stream to the Boost spirit parser and thereby parses the input. + * If the parser throws an expectation failure exception, i.e. expected input different than the one + * provided, this is caught and displayed properly before the exception is passed on. + */ +std::shared_ptr PrismParser::parse(std::istream& inputStream, std::string const& filename) const { + // Prepare iterators to input. + base_iterator_type in_begin(inputStream); + forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin); + forward_iterator_type fwd_end; + pos_iterator_type position_begin(fwd_begin, fwd_end, filename); + pos_iterator_type position_end; + + // Prepare resulting intermediate representation of input. + std::shared_ptr result(new storm::ir::Program()); + + // In order to instantiate the grammar, we have to pass the type of the skipping parser. + // As this is more complex, we let Boost figure out the actual type for us. + prismGrammar> *(qi::char_ - qi::eol) >> qi::eol)> grammar; + try { + // Now parse the content using phrase_parse in order to be able to supply a skipping + // parser. + phrase_parse(position_begin, position_end, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, *result); + } catch(const qi::expectation_failure& e) { + // If the parser expected content different than the one provided, display information + // about the location of the error. + const boost::spirit::classic::file_position_base& pos = e.first.get_position(); + + // Construct the error message including a caret display of the position in the + // erroneous line. + std::stringstream msg; + msg << pos.file << ", line " << pos.line << ", column " << pos.column + << ": parse error: expected " << e.what_ << std::endl << "\t" + << e.first.get_currentline() << std::endl << "\t"; + int i = 0; + for (i = 0; i < pos.column; ++i) { + msg << "-"; + } + msg << "^"; + for (; i < 80; ++i) { + msg << "-"; + } + msg << std::endl; + +// On Mac OS, exception messages are not displayed in case an exception is propagated to the +// operating system, so we need to display the message ourselves. +#if defined(MACOSX) + std::cout << msg.str(); +#endif + // Now propagate exception. + throw storm::exceptions::WrongFileFormatException() << msg.str(); + } + + return result; + } + +} // namespace parser + +} // namespace storm diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 582f2dafb..a06c26dea 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -5,85 +5,76 @@ * Author: Christian Dehnert */ -#ifndef PRISMPARSER_H_ -#define PRISMPARSER_H_ +#ifndef STORM_PARSER_PRISMPARSER_H_ +#define STORM_PARSER_PRISMPARSER_H_ +// Used for Boost spirit. #include #include #include -#include -#include -#include -#include +// All classes of the intermediate representation are used. #include "src/ir/IR.h" +// Used for file input. #include -#include -#include namespace storm { namespace parser { +// Use some namespace shortcuts, to reduce code size. namespace qi = boost::spirit::qi; -namespace ascii = boost::spirit::ascii; namespace phoenix = boost::phoenix; -typedef std::istreambuf_iterator base_iterator_type; -typedef boost::spirit::multi_pass forward_iterator_type; -typedef boost::spirit::classic::position_iterator2 pos_iterator_type; - +/*! + * This class parses the format of the PRISM model checker into an intermediate representation. + */ class PrismParser { - public: - void test(std::string const& fileName) { - std::ifstream inputFileStream(fileName, std::ios::in); - getProgram(inputFileStream, fileName); - inputFileStream.close(); - } - - void getProgram(std::istream& inputStream, std::string const& fileName) { - base_iterator_type in_begin(inputStream); - - forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin); - forward_iterator_type fwd_end; - - pos_iterator_type position_begin(fwd_begin, fwd_end, fileName); - pos_iterator_type position_end; - - storm::ir::Program result; - prismGrammar> *(qi::char_ - qi::eol) >> qi::eol)> grammar; - try { - phrase_parse(position_begin, position_end, grammar, ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result); - } catch(const qi::expectation_failure& e) { - const boost::spirit::classic::file_position_base& pos = e.first.get_position(); - std::stringstream msg; - msg << pos.file << ", line " << pos.line << ", column " << pos.column << ": parse error: expected " << e.what_ << std::endl << "\t" << e.first.get_currentline() << std::endl << "\t"; - int i = 0; - for (i = 0; i < pos.column; ++i) { - msg << "-"; - } - msg << "^"; - for (; i < 80; ++i) { - msg << "-"; - } - msg << std::endl; - std::cout << msg.str(); - throw storm::exceptions::WrongFileFormatException() << msg.str(); - } - - std::cout << result.toString(); - } + /*! + * Parses the given file into the intermediate representation assuming it complies with the + * PRISM syntax. + * @param filename the name of the file to parse. + * @return a shared pointer to the intermediate representation of the PRISM file. + */ + std::shared_ptr parseFile(std::string const& filename) const; private: + /*! + * Parses the given input stream into the intermediate representation assuming it complies with + * the PRISM syntax. + * @param inputStream the input stream to parse. + * @param filename the name of the file the input stream belongs to. Used for diagnostics. + * @return a shared pointer to the intermediate representation of the PRISM file. + */ + std::shared_ptr parse(std::istream& inputStream, std::string const& filename) const; + + /*! + * The Boost spirit grammar for the PRISM language. Returns the intermediate representation of + * the input that complies with the PRISM syntax. + */ template struct prismGrammar : qi::grammar>, std::map>, std::map>, std::map, std::map>>, Skipper> { + /* + * The constructor of the grammar. It defines all rules of the grammar and the corresponding + * semantic actions that take care of constructing the intermediate representation during + * parsing. + * + * Note: The grammar takes care of some semantic checks already. For example, in places + * where we necessarily require a constant expression, this is enforced by not allowing + * variables as subexpressions. Also, variable names are by definition unique and it is + * ensured that variables and constants are properly declared. + * TODO: It should be ensured that updates of a command only refer to variables of the + * current module. + */ prismGrammar() : prismGrammar::base_type(start) { - freeIdentifierName %= qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_'))) - booleanVariables_ - integerVariables_ - allConstants_]]; + // This rule defines all identifiers that have not been previously used. + freeIdentifierName %= qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_'))) - booleanVariableNames_ - integerVariableNames_ - allConstantNames_ - labelNames_ - moduleNames_ - keywords_]]; freeIdentifierName.name("unused identifier"); + // This block defines all literal expressions. booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; booleanLiteralExpression.name("boolean literal"); integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; @@ -93,6 +84,7 @@ private: literalExpression %= (booleanLiteralExpression | integerLiteralExpression | doubleLiteralExpression); literalExpression.name("literal"); + // This block defines all expressions that are variables. integerVariableExpression %= integerVariables_; integerVariableExpression.name("integer variable"); booleanVariableExpression %= booleanVariables_; @@ -100,6 +92,7 @@ private: variableExpression %= (integerVariableExpression | booleanVariableExpression); variableExpression.name("variable"); + // This block defines all atomic expressions that are constant, i.e. literals and constants. booleanConstantExpression %= (booleanConstants_ | booleanLiteralExpression); booleanConstantExpression.name("boolean constant or literal"); integerConstantExpression %= (integerConstants_ | integerLiteralExpression); @@ -109,6 +102,7 @@ private: constantExpression %= (booleanConstantExpression | integerConstantExpression | doubleConstantExpression); constantExpression.name("constant or literal"); + // This block defines all expressions of integral type. atomicIntegerExpression %= (integerVariableExpression | qi::lit("(") >> integerExpression >> qi::lit(")") | integerConstantExpression); atomicIntegerExpression.name("integer expression"); integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; @@ -118,6 +112,7 @@ private: integerExpression %= integerPlusExpression; integerExpression.name("integer expression"); + // This block defines all expressions of integral type that are by syntax constant. That is, they are evaluable given the values for all constants. constantAtomicIntegerExpression %= (qi::lit("(") >> constantIntegerExpression >> qi::lit(")") | integerConstantExpression); constantAtomicIntegerExpression.name("constant integer expression"); constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; @@ -170,8 +165,10 @@ private: expression.name("expression"); // This block defines all entities that are needed for parsing labels. - labelDefinition = (qi::lit("label") >> freeIdentifierName >> qi::lit("=") >> booleanExpression >> qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_2))]; + labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> freeIdentifierName >> -qi::lit("\"") >> qi::lit("=") >> booleanExpression >> qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_2)), phoenix::bind(labelNames_.add, qi::_1, qi::_1)]; + labelDefinition.name("label declaration"); labelDefinitionList %= *labelDefinition(qi::_r1); + labelDefinitionList.name("label declaration list"); // This block defines all entities that are needed for parsing a reward model. stateRewardDefinition = (booleanExpression > qi::lit(":") > constantDoubleExpression >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; @@ -212,23 +209,23 @@ private: variableDefinition.name("variable declaration"); // This block defines all entities that are needed for parsing a module. - moduleDefinition = (qi::lit("module") > freeIdentifierName > *(booleanVariableDefinition[phoenix::push_back(qi::_a, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_b, qi::_1)]) > +commandDefinition > qi::lit("endmodule"))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_3)]; + moduleDefinition = (qi::lit("module") > freeIdentifierName > *(booleanVariableDefinition[phoenix::push_back(qi::_a, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_b, qi::_1)]) > +commandDefinition > qi::lit("endmodule"))[phoenix::bind(moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_3)]; moduleDefinition.name("module"); moduleDefinitionList %= +moduleDefinition; moduleDefinitionList.name("module list"); // This block defines all entities that are needed for parsing constant definitions. - definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") > booleanLiteralExpression > qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") > booleanLiteralExpression > qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; definedBooleanConstantDefinition.name("defined boolean constant declaration"); - definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") > integerLiteralExpression > qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") > integerLiteralExpression > qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; definedIntegerConstantDefinition.name("defined integer constant declaration"); - definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") > doubleLiteralExpression > qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstants_.add, qi::_1, qi::_2), qi::_val = qi::_2]; + definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") > doubleLiteralExpression > qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; definedDoubleConstantDefinition.name("defined double constant declaration"); - undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(booleanConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; undefinedBooleanConstantDefinition.name("undefined boolean constant declaration"); - undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(integerConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(integerConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(integerConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; undefinedIntegerConstantDefinition.name("undefined integer constant declaration"); - undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(doubleConstantInfo_.add, qi::_1, qi::_a), phoenix::bind(doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstants_.add, qi::_1, qi::_a)]; + undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; undefinedDoubleConstantDefinition.name("undefined double constant declaration"); definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); definedConstantDefinition.name("defined constant declaration"); @@ -250,31 +247,37 @@ private: qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; qi::rule(), Skipper> moduleDefinitionList; + // Rules for module definition. qi::rule, std::vector>, Skipper> moduleDefinition; + // Rules for variable definitions. qi::rule variableDefinition; qi::rule, std::shared_ptr>, Skipper> booleanVariableDefinition; qi::rule, std::shared_ptr>, Skipper> integerVariableDefinition; + // Rules for command definitions. qi::rule, Skipper> commandDefinition; - qi::rule(), Skipper> updateListDefinition; qi::rule updateDefinition; qi::rule(), Skipper> assignmentDefinitionList; qi::rule assignmentDefinition; + // Rules for variable/command names. qi::rule integerVariableName; qi::rule booleanVariableName; qi::rule commandName; + // Rules for reward definitions. qi::rule&), Skipper> rewardDefinitionList; qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; qi::rule stateRewardDefinition; qi::rule, Skipper> transitionRewardDefinition; + // Rules for label definitions. qi::rule>&), Skipper> labelDefinitionList; qi::rule>&), Skipper> labelDefinition; + // Rules for constant definitions. qi::rule(), Skipper> constantDefinition; qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; qi::rule(), Skipper> definedConstantDefinition; @@ -338,6 +341,7 @@ private: qi::rule(), Skipper> integerLiteralExpression; qi::rule(), Skipper> doubleLiteralExpression; + // A structure defining the keywords that are not allowed to be chosen as identifiers. struct keywordsStruct : qi::symbols { keywordsStruct() { add @@ -358,6 +362,8 @@ private: } } keywords_; + // A structure mapping the textual representation of a model type to the model type + // representation of the intermediate representation. struct modelTypeStruct : qi::symbols { modelTypeStruct() { add @@ -369,6 +375,8 @@ private: } } modelType_; + // A structure mapping the textual representation of a binary relation to the representation + // of the intermediate representation. struct relationalOperatorStruct : qi::symbols { relationalOperatorStruct() { add @@ -381,33 +389,13 @@ private: } } relations_; - struct variablesStruct : qi::symbols> { - // Intentionally left empty. This map is filled during parsing. - } integerVariables_, booleanVariables_; - - struct entityNamesStruct : qi::symbols { - // Intentionally left empty. This map is filled during parsing. - } integerVariableNames_, booleanVariableNames_, commandNames_; - - struct constantsStruct : qi::symbols> { - // Intentionally left empty. This map is filled during parsing. - } integerConstants_, booleanConstants_, doubleConstants_, allConstants_; - - struct undefinedBooleanConstantsTypesStruct : qi::symbols> { - // Intentionally left empty. This map is filled during parsing. - } booleanConstantInfo_; - - struct undefinedIntegerConstantsTypesStruct : qi::symbols> { - // Intentionally left empty. This map is filled during parsing. - } integerConstantInfo_; - - struct undefinedDoubleConstantsTypesStruct : qi::symbols> { - // Intentionally left empty. This map is filled during parsing. - } doubleConstantInfo_; + // Structures mapping variable and constant names to the corresponding expression nodes of + // the intermediate representation. + struct qi::symbols> integerVariables_, booleanVariables_; + struct qi::symbols> integerConstants_, booleanConstants_, doubleConstants_; - struct modulesStruct : qi::symbols { - // Intentionally left empty. This map is filled during parsing. - } modules_; + // A structure representing the identity function over identifier names. + struct qi::symbols integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_; }; }; @@ -415,4 +403,4 @@ private: } // namespace storm -#endif /* PRISMPARSER_H_ */ +#endif /* STORM_PARSER_PRISMPARSER_H_ */ diff --git a/src/storm.cpp b/src/storm.cpp index faba3559b..c4c75d09a 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -241,7 +241,7 @@ int main(const int argc, const char* argv[]) { // testChecking(); storm::parser::PrismParser parser; - parser.test("test.input"); + parser.parseFile("test.input"); cleanUp(); return 0; From a82c8b31532889ab368920f8dd6d547ec1c996ef Mon Sep 17 00:00:00 2001 From: dehnert Date: Sat, 12 Jan 2013 13:54:27 +0100 Subject: [PATCH 011/152] Moved implementation of PrismParser completely to source file. Fixed some minor things in IR classes. --- src/ir/Command.h | 2 + src/ir/Module.h | 14 +- src/ir/Update.h | 12 +- src/ir/expressions/BaseExpression.h | 2 + src/parser/PrismParser.cpp | 436 +++++++++++++++++++++++++--- src/parser/PrismParser.h | 352 +--------------------- 6 files changed, 413 insertions(+), 405 deletions(-) diff --git a/src/ir/Command.h b/src/ir/Command.h index c5bfee6d5..fa881cb52 100644 --- a/src/ir/Command.h +++ b/src/ir/Command.h @@ -11,6 +11,8 @@ #include "expressions/BaseExpression.h" #include "Update.h" +#include + namespace storm { namespace ir { diff --git a/src/ir/Module.h b/src/ir/Module.h index bb3142328..4b673a757 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -12,6 +12,8 @@ #include "IntegerVariable.h" #include "Command.h" +#include + namespace storm { namespace ir { @@ -22,7 +24,7 @@ public: } - Module(std::string moduleName, std::vector booleanVariables, std::vector integerVariables, std::vector commands) + Module(std::string moduleName, std::map booleanVariables, std::map integerVariables, std::vector commands) : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), commands(commands) { } @@ -34,10 +36,10 @@ public: std::string toString() { std::string result = "module " + moduleName + "\n"; for (auto variable : booleanVariables) { - result += "\t" + variable.toString() + "\n"; + result += "\t" + variable.second.toString() + "\n"; } for (auto variable : integerVariables) { - result += "\t" + variable.toString() + "\n"; + result += "\t" + variable.second.toString() + "\n"; } for (auto command : commands) { result += "\t" + command.toString() + "\n"; @@ -48,11 +50,9 @@ public: private: std::string moduleName; - - std::vector booleanVariables; - std::vector integerVariables; + std::map booleanVariables; + std::map integerVariables; std::vector commands; - }; } diff --git a/src/ir/Update.h b/src/ir/Update.h index 1ea4b0dc1..6f2d3535f 100644 --- a/src/ir/Update.h +++ b/src/ir/Update.h @@ -9,6 +9,7 @@ #define UPDATE_H_ #include "expressions/BaseExpression.h" +#include namespace storm { @@ -20,25 +21,28 @@ public: } - Update(std::shared_ptr likelihoodExpression, std::vector assignments) + Update(std::shared_ptr likelihoodExpression, std::map assignments) : likelihoodExpression(likelihoodExpression), assignments(assignments) { } std::string toString() { std::string result = likelihoodExpression->toString() + " : "; - for (uint_fast64_t i = 0; i < assignments.size(); ++i) { - result += assignments[i].toString(); + uint_fast64_t i = 0; + for (auto assignment : assignments) { + result += assignment.second.toString(); + ++i; if (i < assignments.size() - 1) { result += " & "; } + } return result; } private: std::shared_ptr likelihoodExpression; - std::vector assignments; + std::map assignments; }; } diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h index 9d6c93db2..f2d848fb7 100644 --- a/src/ir/expressions/BaseExpression.h +++ b/src/ir/expressions/BaseExpression.h @@ -8,6 +8,8 @@ #ifndef EXPRESSION_H_ #define EXPRESSION_H_ +#include + namespace storm { namespace ir { diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index f3348cb19..83380003e 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -11,6 +11,11 @@ // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFileFormatException.h" +// Used for Boost spirit. +#include +#include +#include + // Include headers for spirit iterators. Needed for diagnostics and input stream iteration. #include #include @@ -30,6 +35,351 @@ namespace storm { namespace parser { +// The Boost spirit grammar used for parsing the input. +template +struct PrismParser::PrismGrammar : qi::grammar>, std::map>, std::map>, std::map, std::map>>, Skipper> { + + /* + * The constructor of the grammar. It defines all rules of the grammar and the corresponding + * semantic actions that take care of constructing the intermediate representation during + * parsing. + * + * Note: The grammar takes care of some semantic checks already. For example, in places + * where we necessarily require a constant expression, this is enforced by not allowing + * variables as subexpressions. Also, variable names are by definition unique and it is + * ensured that variables and constants are properly declared. + * TODO: It should be ensured that updates of a command only refer to variables of the + * current module. + */ + PrismGrammar() : PrismGrammar::base_type(start) { + // This rule defines all identifiers that have not been previously used. + freeIdentifierName %= qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_'))) - booleanVariableNames_ - integerVariableNames_ - allConstantNames_ - labelNames_ - moduleNames_ - keywords_]]; + freeIdentifierName.name("unused identifier"); + + // This block defines all literal expressions. + booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + booleanLiteralExpression.name("boolean literal"); + integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + integerLiteralExpression.name("integer literal"); + doubleLiteralExpression = qi::double_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + doubleLiteralExpression.name("double literal"); + literalExpression %= (booleanLiteralExpression | integerLiteralExpression | doubleLiteralExpression); + literalExpression.name("literal"); + + // This block defines all expressions that are variables. + integerVariableExpression %= integerVariables_; + integerVariableExpression.name("integer variable"); + booleanVariableExpression %= booleanVariables_; + booleanVariableExpression.name("boolean variable"); + variableExpression %= (integerVariableExpression | booleanVariableExpression); + variableExpression.name("variable"); + + // This block defines all atomic expressions that are constant, i.e. literals and constants. + booleanConstantExpression %= (booleanConstants_ | booleanLiteralExpression); + booleanConstantExpression.name("boolean constant or literal"); + integerConstantExpression %= (integerConstants_ | integerLiteralExpression); + integerConstantExpression.name("integer constant or literal"); + doubleConstantExpression %= (doubleConstants_ | doubleLiteralExpression); + doubleConstantExpression.name("double constant or literal"); + constantExpression %= (booleanConstantExpression | integerConstantExpression | doubleConstantExpression); + constantExpression.name("constant or literal"); + + // This block defines all expressions of integral type. + atomicIntegerExpression %= (integerVariableExpression | qi::lit("(") >> integerExpression >> qi::lit(")") | integerConstantExpression); + atomicIntegerExpression.name("integer expression"); + integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + integerMultExpression.name("integer expression"); + integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> integerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + integerPlusExpression.name("integer expression"); + integerExpression %= integerPlusExpression; + integerExpression.name("integer expression"); + + // This block defines all expressions of integral type that are by syntax constant. That is, they are evaluable given the values for all constants. + constantAtomicIntegerExpression %= (qi::lit("(") >> constantIntegerExpression >> qi::lit(")") | integerConstantExpression); + constantAtomicIntegerExpression.name("constant integer expression"); + constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + constantIntegerMultExpression.name("constant integer expression"); + constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantIntegerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + constantIntegerPlusExpression.name("constant integer expression"); + constantIntegerExpression %= constantIntegerPlusExpression; + constantIntegerExpression.name("constant integer expression"); + + // This block defines all expressions of type double that are by syntax constant. That is, they are evaluable given the values for all constants. + constantAtomicDoubleExpression %= (qi::lit("(") >> constantDoubleExpression >> qi::lit(")") | doubleConstantExpression); + constantAtomicDoubleExpression.name("constant double expression"); + constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicDoubleExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + constantDoubleMultExpression.name("constant double expression"); + constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantDoubleMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + constantDoublePlusExpression.name("constant double expression"); + constantDoubleExpression %= constantDoublePlusExpression; + constantDoubleExpression.name("constant double expression"); + + // This block defines all expressions of type boolean. + relativeExpression = (integerExpression >> relations_ >> integerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; + relativeExpression.name("boolean expression"); + atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")") | booleanConstantExpression); + atomicBooleanExpression.name("boolean expression"); + notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType::NOT))]; + notExpression.name("boolean expression"); + andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; + andExpression.name("boolean expression"); + orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::OR))]; + orExpression.name("boolean expression"); + booleanExpression %= orExpression; + booleanExpression.name("boolean expression"); + + // This block defines all expressions of type boolean that are by syntax constant. That is, they are evaluable given the values for all constants. + constantRelativeExpression = (constantIntegerExpression >> relations_ >> constantIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; + constantRelativeExpression.name("constant boolean expression"); + constantAtomicBooleanExpression %= (constantRelativeExpression | qi::lit("(") >> constantBooleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression); + constantAtomicBooleanExpression.name("constant boolean expression"); + constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType::NOT))]; + constantNotExpression.name("constant boolean expression"); + constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; + constantAndExpression.name("constant boolean expression"); + constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::OR))]; + constantOrExpression.name("constant boolean expression"); + constantBooleanExpression %= constantOrExpression; + constantBooleanExpression.name("constant boolean expression"); + + // This block defines the general root of all expressions. Most of the time, however, you may want to start with a more specialized rule. + expression %= (booleanExpression | integerExpression | constantDoubleExpression); + expression.name("expression"); + + // This block defines all entities that are needed for parsing labels. + labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> freeIdentifierName >> -qi::lit("\"") >> qi::lit("=") >> booleanExpression >> qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_2)), phoenix::bind(labelNames_.add, qi::_1, qi::_1)]; + labelDefinition.name("label declaration"); + labelDefinitionList %= *labelDefinition(qi::_r1); + labelDefinitionList.name("label declaration list"); + + // This block defines all entities that are needed for parsing a reward model. + stateRewardDefinition = (booleanExpression > qi::lit(":") > constantDoubleExpression >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; + stateRewardDefinition.name("state reward definition"); + transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit(":") > constantDoubleExpression > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; + transitionRewardDefinition.name("transition reward definition"); + rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > freeIdentifierName > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> qi::lit("endrewards"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_a, qi::_b)))]; + rewardDefinition.name("reward definition"); + rewardDefinitionList = *rewardDefinition(qi::_r1); + rewardDefinitionList.name("reward definition list"); + + // This block defines auxiliary entities that are used to check whether a certain variable exist. + booleanVariableName %= booleanVariableNames_; + booleanVariableName.name("boolean variable"); + integerVariableName %= integerVariableNames_; + integerVariableName.name("integer variable"); + commandName %= commandNames_; + commandName.name("command name"); + + // This block defines all entities that are needed for parsing a single command. + assignmentDefinition = (qi::lit("(") >> integerVariableName > qi::lit("'") > qi::lit("=") > integerExpression > qi::lit(")"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))] | (qi::lit("(") > booleanVariableName > qi::lit("'") > qi::lit("=") > booleanExpression > qi::lit(")"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))]; + assignmentDefinition.name("assignment"); + assignmentDefinitionList = assignmentDefinition(qi::_r1) % "&"; + assignmentDefinitionList.name("assignment list"); + updateDefinition = (constantDoubleExpression > qi::lit(":") > assignmentDefinitionList(qi::_a))[qi::_val = phoenix::construct(qi::_1, qi::_a)]; + updateDefinition.name("update"); + updateListDefinition = +updateDefinition % "+"; + updateListDefinition.name("update list"); + commandDefinition = (qi::lit("[") > -((freeIdentifierName[phoenix::bind(commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit("->") > updateListDefinition > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; + commandDefinition.name("command"); + + // This block defines all entities that are neede for parsing variable definitions. + booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(phoenix::val(qi::_1), qi::_b))), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1)]; + booleanVariableDefinition.name("boolean variable declaration"); + integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2, qi::_3, qi::_b))), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1)]; + integerVariableDefinition.name("integer variable declaration"); + variableDefinition = (booleanVariableDefinition(qi::_r1) | integerVariableDefinition(qi::_r2)); + variableDefinition.name("variable declaration"); + + // This block defines all entities that are needed for parsing a module. + moduleDefinition = (qi::lit("module") > freeIdentifierName > *(variableDefinition(qi::_a, qi::_b)) > +commandDefinition > qi::lit("endmodule"))[phoenix::bind(moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_2)]; + moduleDefinition.name("module"); + moduleDefinitionList %= +moduleDefinition; + moduleDefinitionList.name("module list"); + + // This block defines all entities that are needed for parsing constant definitions. + definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") > booleanLiteralExpression > qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; + definedBooleanConstantDefinition.name("defined boolean constant declaration"); + definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") > integerLiteralExpression > qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; + definedIntegerConstantDefinition.name("defined integer constant declaration"); + definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") > doubleLiteralExpression > qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; + definedDoubleConstantDefinition.name("defined double constant declaration"); + undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; + undefinedBooleanConstantDefinition.name("undefined boolean constant declaration"); + undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(integerConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; + undefinedIntegerConstantDefinition.name("undefined integer constant declaration"); + undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; + undefinedDoubleConstantDefinition.name("undefined double constant declaration"); + definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); + definedConstantDefinition.name("defined constant declaration"); + undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3)); + undefinedConstantDefinition.name("undefined constant declaration"); + constantDefinitionList = *(definedConstantDefinition | undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3)); + constantDefinitionList.name("constant declaration list"); + + // This block defines all entities that are needed for parsing a program. + modelTypeDefinition = modelType_; + modelTypeDefinition.name("model type"); + start = (modelTypeDefinition > constantDefinitionList(qi::_a, qi::_b, qi::_c) > moduleDefinitionList > rewardDefinitionList(qi::_d) > labelDefinitionList(qi::_e))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_d, qi::_e)]; + start.name("probabilistic program declaration"); + } + + // The starting point of the grammar. + qi::rule>, std::map>, std::map>, std::map, std::map>>, Skipper> start; + qi::rule modelTypeDefinition; + qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; + qi::rule(), Skipper> moduleDefinitionList; + + // Rules for module definition. + qi::rule, std::map>, Skipper> moduleDefinition; + + // Rules for variable definitions. + qi::rule&, std::map&), Skipper> variableDefinition; + qi::rule&), qi::locals, std::shared_ptr>, Skipper> booleanVariableDefinition; + qi::rule&), qi::locals, std::shared_ptr>, Skipper> integerVariableDefinition; + + // Rules for command definitions. + qi::rule, Skipper> commandDefinition; + qi::rule(), Skipper> updateListDefinition; + qi::rule>, Skipper> updateDefinition; + qi::rule&), Skipper> assignmentDefinitionList; + qi::rule&), Skipper> assignmentDefinition; + + // Rules for variable/command names. + qi::rule integerVariableName; + qi::rule booleanVariableName; + qi::rule commandName; + + // Rules for reward definitions. + qi::rule&), Skipper> rewardDefinitionList; + qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; + qi::rule stateRewardDefinition; + qi::rule, Skipper> transitionRewardDefinition; + + // Rules for label definitions. + qi::rule>&), Skipper> labelDefinitionList; + qi::rule>&), Skipper> labelDefinition; + + // Rules for constant definitions. + qi::rule(), Skipper> constantDefinition; + qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; + qi::rule(), Skipper> definedConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedBooleanConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedIntegerConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedDoubleConstantDefinition; + qi::rule(), Skipper> definedBooleanConstantDefinition; + qi::rule(), Skipper> definedIntegerConstantDefinition; + qi::rule(), Skipper> definedDoubleConstantDefinition; + + qi::rule freeIdentifierName; + qi::rule identifierName; + + // The starting point for arbitrary expressions. + qi::rule(), Skipper> expression; + + // Rules with boolean result type. + qi::rule(), Skipper> booleanExpression; + qi::rule(), Skipper> orExpression; + qi::rule(), Skipper> andExpression; + qi::rule(), Skipper> notExpression; + qi::rule(), Skipper> atomicBooleanExpression; + qi::rule(), Skipper> relativeExpression; + qi::rule(), Skipper> constantBooleanExpression; + qi::rule(), Skipper> constantOrExpression; + qi::rule(), Skipper> constantAndExpression; + qi::rule(), Skipper> constantNotExpression; + qi::rule(), Skipper> constantAtomicBooleanExpression; + qi::rule(), Skipper> constantRelativeExpression; + + // Rules with integer result type. + qi::rule(), Skipper> integerExpression; + qi::rule(), Skipper> integerPlusExpression; + qi::rule(), Skipper> integerMultExpression; + qi::rule(), Skipper> atomicIntegerExpression; + qi::rule(), Skipper> constantIntegerExpression; + qi::rule(), Skipper> constantIntegerPlusExpression; + qi::rule(), Skipper> constantIntegerMultExpression; + qi::rule(), Skipper> constantAtomicIntegerExpression; + + // Rules with double result type. + qi::rule(), Skipper> constantDoubleExpression; + qi::rule(), Skipper> constantDoublePlusExpression; + qi::rule(), Skipper> constantDoubleMultExpression; + qi::rule(), Skipper> constantAtomicDoubleExpression; + + // Rules for variable recognition. + qi::rule(), Skipper> variableExpression; + qi::rule(), Skipper> booleanVariableExpression; + qi::rule(), Skipper> integerVariableExpression; + + // Rules for constant recognition. + qi::rule(), Skipper> constantExpression; + qi::rule(), Skipper> booleanConstantExpression; + qi::rule(), Skipper> integerConstantExpression; + qi::rule(), Skipper> doubleConstantExpression; + + // Rules for literal recognition. + qi::rule(), Skipper> literalExpression; + qi::rule(), Skipper> booleanLiteralExpression; + qi::rule(), Skipper> integerLiteralExpression; + qi::rule(), Skipper> doubleLiteralExpression; + + // A structure defining the keywords that are not allowed to be chosen as identifiers. + struct keywordsStruct : qi::symbols { + keywordsStruct() { + add + ("dtmc", 1) + ("ctmc", 2) + ("mdp", 3) + ("ctmdp", 4) + ("const", 5) + ("int", 6) + ("bool", 7) + ("module", 8) + ("endmodule", 9) + ("rewards", 10) + ("endrewards", 11) + ("true", 12) + ("false", 13) + ; + } + } keywords_; + + // A structure mapping the textual representation of a model type to the model type + // representation of the intermediate representation. + struct modelTypeStruct : qi::symbols { + modelTypeStruct() { + add + ("dtmc", storm::ir::Program::ModelType::DTMC) + ("ctmc", storm::ir::Program::ModelType::CTMC) + ("mdp", storm::ir::Program::ModelType::MDP) + ("ctmdp", storm::ir::Program::ModelType::CTMDP) + ; + } + } modelType_; + + // A structure mapping the textual representation of a binary relation to the representation + // of the intermediate representation. + struct relationalOperatorStruct : qi::symbols { + relationalOperatorStruct() { + add + ("=", storm::ir::expressions::BinaryRelationExpression::EQUAL) + ("<", storm::ir::expressions::BinaryRelationExpression::LESS) + ("<=", storm::ir::expressions::BinaryRelationExpression::LESS_OR_EQUAL) + (">", storm::ir::expressions::BinaryRelationExpression::GREATER) + (">=", storm::ir::expressions::BinaryRelationExpression::GREATER_OR_EQUAL) + ; + } + } relations_; + + // Structures mapping variable and constant names to the corresponding expression nodes of + // the intermediate representation. + struct qi::symbols> integerVariables_, booleanVariables_; + struct qi::symbols> integerConstants_, booleanConstants_, doubleConstants_; + + // A structure representing the identity function over identifier names. + struct qi::symbols integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_; +}; + /*! * Opens the given file for parsing, invokes the helper function to parse the actual content and * closes the file properly, even if an exception is thrown in the parser. In this case, the @@ -60,56 +410,56 @@ std::shared_ptr PrismParser::parseFile(std::string const& fi * provided, this is caught and displayed properly before the exception is passed on. */ std::shared_ptr PrismParser::parse(std::istream& inputStream, std::string const& filename) const { - // Prepare iterators to input. - base_iterator_type in_begin(inputStream); - forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin); - forward_iterator_type fwd_end; - pos_iterator_type position_begin(fwd_begin, fwd_end, filename); - pos_iterator_type position_end; - - // Prepare resulting intermediate representation of input. - std::shared_ptr result(new storm::ir::Program()); - - // In order to instantiate the grammar, we have to pass the type of the skipping parser. - // As this is more complex, we let Boost figure out the actual type for us. - prismGrammar> *(qi::char_ - qi::eol) >> qi::eol)> grammar; - try { - // Now parse the content using phrase_parse in order to be able to supply a skipping - // parser. - phrase_parse(position_begin, position_end, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, *result); - } catch(const qi::expectation_failure& e) { - // If the parser expected content different than the one provided, display information - // about the location of the error. - const boost::spirit::classic::file_position_base& pos = e.first.get_position(); - - // Construct the error message including a caret display of the position in the - // erroneous line. - std::stringstream msg; - msg << pos.file << ", line " << pos.line << ", column " << pos.column - << ": parse error: expected " << e.what_ << std::endl << "\t" - << e.first.get_currentline() << std::endl << "\t"; - int i = 0; - for (i = 0; i < pos.column; ++i) { - msg << "-"; - } - msg << "^"; - for (; i < 80; ++i) { - msg << "-"; - } - msg << std::endl; + // Prepare iterators to input. + base_iterator_type in_begin(inputStream); + forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin); + forward_iterator_type fwd_end; + pos_iterator_type position_begin(fwd_begin, fwd_end, filename); + pos_iterator_type position_end; + + // Prepare resulting intermediate representation of input. + std::shared_ptr result(new storm::ir::Program()); + + // In order to instantiate the grammar, we have to pass the type of the skipping parser. + // As this is more complex, we let Boost figure out the actual type for us. + PrismGrammar> *(qi::char_ - qi::eol) >> qi::eol)> grammar; + try { + // Now parse the content using phrase_parse in order to be able to supply a skipping + // parser. + qi::phrase_parse(position_begin, position_end, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, *result); + } catch(const qi::expectation_failure& e) { + // If the parser expected content different than the one provided, display information + // about the location of the error. + const boost::spirit::classic::file_position_base& pos = e.first.get_position(); + + // Construct the error message including a caret display of the position in the + // erroneous line. + std::stringstream msg; + msg << pos.file << ", line " << pos.line << ", column " << pos.column + << ": parse error: expected " << e.what_ << std::endl << "\t" + << e.first.get_currentline() << std::endl << "\t"; + int i = 0; + for (i = 0; i < pos.column; ++i) { + msg << "-"; + } + msg << "^"; + for (; i < 80; ++i) { + msg << "-"; + } + msg << std::endl; // On Mac OS, exception messages are not displayed in case an exception is propagated to the // operating system, so we need to display the message ourselves. #if defined(MACOSX) - std::cout << msg.str(); + std::cout << msg.str(); #endif - // Now propagate exception. - throw storm::exceptions::WrongFileFormatException() << msg.str(); - } - - return result; + // Now propagate exception. + throw storm::exceptions::WrongFileFormatException() << msg.str(); } + return result; +} + } // namespace parser } // namespace storm diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index a06c26dea..f4a563e37 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -8,11 +8,6 @@ #ifndef STORM_PARSER_PRISMPARSER_H_ #define STORM_PARSER_PRISMPARSER_H_ -// Used for Boost spirit. -#include -#include -#include - // All classes of the intermediate representation are used. #include "src/ir/IR.h" @@ -23,10 +18,6 @@ namespace storm { namespace parser { -// Use some namespace shortcuts, to reduce code size. -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; - /*! * This class parses the format of the PRISM model checker into an intermediate representation. */ @@ -55,348 +46,7 @@ private: * the input that complies with the PRISM syntax. */ template - struct prismGrammar : qi::grammar>, std::map>, std::map>, std::map, std::map>>, Skipper> { - - /* - * The constructor of the grammar. It defines all rules of the grammar and the corresponding - * semantic actions that take care of constructing the intermediate representation during - * parsing. - * - * Note: The grammar takes care of some semantic checks already. For example, in places - * where we necessarily require a constant expression, this is enforced by not allowing - * variables as subexpressions. Also, variable names are by definition unique and it is - * ensured that variables and constants are properly declared. - * TODO: It should be ensured that updates of a command only refer to variables of the - * current module. - */ - prismGrammar() : prismGrammar::base_type(start) { - // This rule defines all identifiers that have not been previously used. - freeIdentifierName %= qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_'))) - booleanVariableNames_ - integerVariableNames_ - allConstantNames_ - labelNames_ - moduleNames_ - keywords_]]; - freeIdentifierName.name("unused identifier"); - - // This block defines all literal expressions. - booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; - booleanLiteralExpression.name("boolean literal"); - integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; - integerLiteralExpression.name("integer literal"); - doubleLiteralExpression = qi::double_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; - doubleLiteralExpression.name("double literal"); - literalExpression %= (booleanLiteralExpression | integerLiteralExpression | doubleLiteralExpression); - literalExpression.name("literal"); - - // This block defines all expressions that are variables. - integerVariableExpression %= integerVariables_; - integerVariableExpression.name("integer variable"); - booleanVariableExpression %= booleanVariables_; - booleanVariableExpression.name("boolean variable"); - variableExpression %= (integerVariableExpression | booleanVariableExpression); - variableExpression.name("variable"); - - // This block defines all atomic expressions that are constant, i.e. literals and constants. - booleanConstantExpression %= (booleanConstants_ | booleanLiteralExpression); - booleanConstantExpression.name("boolean constant or literal"); - integerConstantExpression %= (integerConstants_ | integerLiteralExpression); - integerConstantExpression.name("integer constant or literal"); - doubleConstantExpression %= (doubleConstants_ | doubleLiteralExpression); - doubleConstantExpression.name("double constant or literal"); - constantExpression %= (booleanConstantExpression | integerConstantExpression | doubleConstantExpression); - constantExpression.name("constant or literal"); - - // This block defines all expressions of integral type. - atomicIntegerExpression %= (integerVariableExpression | qi::lit("(") >> integerExpression >> qi::lit(")") | integerConstantExpression); - atomicIntegerExpression.name("integer expression"); - integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; - integerMultExpression.name("integer expression"); - integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> integerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; - integerPlusExpression.name("integer expression"); - integerExpression %= integerPlusExpression; - integerExpression.name("integer expression"); - - // This block defines all expressions of integral type that are by syntax constant. That is, they are evaluable given the values for all constants. - constantAtomicIntegerExpression %= (qi::lit("(") >> constantIntegerExpression >> qi::lit(")") | integerConstantExpression); - constantAtomicIntegerExpression.name("constant integer expression"); - constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; - constantIntegerMultExpression.name("constant integer expression"); - constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantIntegerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; - constantIntegerPlusExpression.name("constant integer expression"); - constantIntegerExpression %= constantIntegerPlusExpression; - constantIntegerExpression.name("constant integer expression"); - - // This block defines all expressions of type double that are by syntax constant. That is, they are evaluable given the values for all constants. - constantAtomicDoubleExpression %= (qi::lit("(") >> constantDoubleExpression >> qi::lit(")") | doubleConstantExpression); - constantAtomicDoubleExpression.name("constant double expression"); - constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicDoubleExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; - constantDoubleMultExpression.name("constant double expression"); - constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantDoubleMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; - constantDoublePlusExpression.name("constant double expression"); - constantDoubleExpression %= constantDoublePlusExpression; - constantDoubleExpression.name("constant double expression"); - - // This block defines all expressions of type boolean. - relativeExpression = (integerExpression >> relations_ >> integerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; - relativeExpression.name("boolean expression"); - atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")") | booleanConstantExpression); - atomicBooleanExpression.name("boolean expression"); - notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType::NOT))]; - notExpression.name("boolean expression"); - andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; - andExpression.name("boolean expression"); - orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::OR))]; - orExpression.name("boolean expression"); - booleanExpression %= orExpression; - booleanExpression.name("boolean expression"); - - // This block defines all expressions of type boolean that are by syntax constant. That is, they are evaluable given the values for all constants. - constantRelativeExpression = (constantIntegerExpression >> relations_ >> constantIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; - constantRelativeExpression.name("constant boolean expression"); - constantAtomicBooleanExpression %= (constantRelativeExpression | qi::lit("(") >> constantBooleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression); - constantAtomicBooleanExpression.name("constant boolean expression"); - constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType::NOT))]; - constantNotExpression.name("constant boolean expression"); - constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; - constantAndExpression.name("constant boolean expression"); - constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::OR))]; - constantOrExpression.name("constant boolean expression"); - constantBooleanExpression %= constantOrExpression; - constantBooleanExpression.name("constant boolean expression"); - - // This block defines the general root of all expressions. Most of the time, however, you may want to start with a more specialized rule. - expression %= (booleanExpression | integerExpression | constantDoubleExpression); - expression.name("expression"); - - // This block defines all entities that are needed for parsing labels. - labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> freeIdentifierName >> -qi::lit("\"") >> qi::lit("=") >> booleanExpression >> qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_2)), phoenix::bind(labelNames_.add, qi::_1, qi::_1)]; - labelDefinition.name("label declaration"); - labelDefinitionList %= *labelDefinition(qi::_r1); - labelDefinitionList.name("label declaration list"); - - // This block defines all entities that are needed for parsing a reward model. - stateRewardDefinition = (booleanExpression > qi::lit(":") > constantDoubleExpression >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; - stateRewardDefinition.name("state reward definition"); - transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit(":") > constantDoubleExpression > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; - transitionRewardDefinition.name("transition reward definition"); - rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > freeIdentifierName > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> qi::lit("endrewards"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_a, qi::_b)))]; - rewardDefinition.name("reward definition"); - rewardDefinitionList = *rewardDefinition(qi::_r1); - rewardDefinitionList.name("reward definition list"); - - // This block defines auxiliary entities that are used to check whether a certain variable exist. - booleanVariableName %= booleanVariableNames_; - booleanVariableName.name("boolean variable"); - integerVariableName %= integerVariableNames_; - integerVariableName.name("integer variable"); - commandName %= commandNames_; - commandName.name("command name"); - - // This block defines all entities that are needed for parsing a single command. - assignmentDefinition = (qi::lit("(") >> integerVariableName > qi::lit("'") > qi::lit("=") > integerExpression > qi::lit(")"))[qi::_val = phoenix::construct(qi::_1, qi::_2)] | (qi::lit("(") > booleanVariableName > qi::lit("'") > qi::lit("=") > booleanExpression > qi::lit(")"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; - assignmentDefinition.name("assignment"); - assignmentDefinitionList %= assignmentDefinition % "&"; - assignmentDefinitionList.name("assignment list"); - updateDefinition = (constantDoubleExpression > qi::lit(":") > assignmentDefinitionList)[qi::_val = phoenix::construct(qi::_1, qi::_2)]; - updateDefinition.name("update"); - updateListDefinition = +updateDefinition % "+"; - updateListDefinition.name("update list"); - commandDefinition = (qi::lit("[") > -((freeIdentifierName[phoenix::bind(commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit("->") > updateListDefinition > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; - commandDefinition.name("command"); - - // This block defines all entities that are neede for parsing variable definitions. - booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[qi::_val = phoenix::construct(phoenix::val("hallo"), qi::_b), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), std::cout << phoenix::val("here!"), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1)]; - booleanVariableDefinition.name("boolean variable declaration"); - integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2, qi::_3, qi::_b), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1)]; - integerVariableDefinition.name("integer variable declaration"); - variableDefinition = (booleanVariableDefinition | integerVariableDefinition); - variableDefinition.name("variable declaration"); - - // This block defines all entities that are needed for parsing a module. - moduleDefinition = (qi::lit("module") > freeIdentifierName > *(booleanVariableDefinition[phoenix::push_back(qi::_a, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_b, qi::_1)]) > +commandDefinition > qi::lit("endmodule"))[phoenix::bind(moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_3)]; - moduleDefinition.name("module"); - moduleDefinitionList %= +moduleDefinition; - moduleDefinitionList.name("module list"); - - // This block defines all entities that are needed for parsing constant definitions. - definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") > booleanLiteralExpression > qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; - definedBooleanConstantDefinition.name("defined boolean constant declaration"); - definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") > integerLiteralExpression > qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; - definedIntegerConstantDefinition.name("defined integer constant declaration"); - definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") > doubleLiteralExpression > qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; - definedDoubleConstantDefinition.name("defined double constant declaration"); - undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; - undefinedBooleanConstantDefinition.name("undefined boolean constant declaration"); - undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(integerConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; - undefinedIntegerConstantDefinition.name("undefined integer constant declaration"); - undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; - undefinedDoubleConstantDefinition.name("undefined double constant declaration"); - definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); - definedConstantDefinition.name("defined constant declaration"); - undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3)); - undefinedConstantDefinition.name("undefined constant declaration"); - constantDefinitionList = *(definedConstantDefinition | undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3)); - constantDefinitionList.name("constant declaration list"); - - // This block defines all entities that are needed for parsing a program. - modelTypeDefinition = modelType_; - modelTypeDefinition.name("model type"); - start = (modelTypeDefinition > constantDefinitionList(qi::_a, qi::_b, qi::_c) > moduleDefinitionList > rewardDefinitionList(qi::_d) > labelDefinitionList(qi::_e))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_d, qi::_e)]; - start.name("probabilistic program declaration"); - } - - // The starting point of the grammar. - qi::rule>, std::map>, std::map>, std::map, std::map>>, Skipper> start; - qi::rule modelTypeDefinition; - qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; - qi::rule(), Skipper> moduleDefinitionList; - - // Rules for module definition. - qi::rule, std::vector>, Skipper> moduleDefinition; - - // Rules for variable definitions. - qi::rule variableDefinition; - qi::rule, std::shared_ptr>, Skipper> booleanVariableDefinition; - qi::rule, std::shared_ptr>, Skipper> integerVariableDefinition; - - // Rules for command definitions. - qi::rule, Skipper> commandDefinition; - qi::rule(), Skipper> updateListDefinition; - qi::rule updateDefinition; - qi::rule(), Skipper> assignmentDefinitionList; - qi::rule assignmentDefinition; - - // Rules for variable/command names. - qi::rule integerVariableName; - qi::rule booleanVariableName; - qi::rule commandName; - - // Rules for reward definitions. - qi::rule&), Skipper> rewardDefinitionList; - qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; - qi::rule stateRewardDefinition; - qi::rule, Skipper> transitionRewardDefinition; - - // Rules for label definitions. - qi::rule>&), Skipper> labelDefinitionList; - qi::rule>&), Skipper> labelDefinition; - - // Rules for constant definitions. - qi::rule(), Skipper> constantDefinition; - qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; - qi::rule(), Skipper> definedConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedBooleanConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedIntegerConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedDoubleConstantDefinition; - qi::rule(), Skipper> definedBooleanConstantDefinition; - qi::rule(), Skipper> definedIntegerConstantDefinition; - qi::rule(), Skipper> definedDoubleConstantDefinition; - - qi::rule freeIdentifierName; - qi::rule identifierName; - - // The starting point for arbitrary expressions. - qi::rule(), Skipper> expression; - - // Rules with boolean result type. - qi::rule(), Skipper> booleanExpression; - qi::rule(), Skipper> orExpression; - qi::rule(), Skipper> andExpression; - qi::rule(), Skipper> notExpression; - qi::rule(), Skipper> atomicBooleanExpression; - qi::rule(), Skipper> relativeExpression; - qi::rule(), Skipper> constantBooleanExpression; - qi::rule(), Skipper> constantOrExpression; - qi::rule(), Skipper> constantAndExpression; - qi::rule(), Skipper> constantNotExpression; - qi::rule(), Skipper> constantAtomicBooleanExpression; - qi::rule(), Skipper> constantRelativeExpression; - - // Rules with integer result type. - qi::rule(), Skipper> integerExpression; - qi::rule(), Skipper> integerPlusExpression; - qi::rule(), Skipper> integerMultExpression; - qi::rule(), Skipper> atomicIntegerExpression; - qi::rule(), Skipper> constantIntegerExpression; - qi::rule(), Skipper> constantIntegerPlusExpression; - qi::rule(), Skipper> constantIntegerMultExpression; - qi::rule(), Skipper> constantAtomicIntegerExpression; - - // Rules with double result type. - qi::rule(), Skipper> constantDoubleExpression; - qi::rule(), Skipper> constantDoublePlusExpression; - qi::rule(), Skipper> constantDoubleMultExpression; - qi::rule(), Skipper> constantAtomicDoubleExpression; - - // Rules for variable recognition. - qi::rule(), Skipper> variableExpression; - qi::rule(), Skipper> booleanVariableExpression; - qi::rule(), Skipper> integerVariableExpression; - - // Rules for constant recognition. - qi::rule(), Skipper> constantExpression; - qi::rule(), Skipper> booleanConstantExpression; - qi::rule(), Skipper> integerConstantExpression; - qi::rule(), Skipper> doubleConstantExpression; - - // Rules for literal recognition. - qi::rule(), Skipper> literalExpression; - qi::rule(), Skipper> booleanLiteralExpression; - qi::rule(), Skipper> integerLiteralExpression; - qi::rule(), Skipper> doubleLiteralExpression; - - // A structure defining the keywords that are not allowed to be chosen as identifiers. - struct keywordsStruct : qi::symbols { - keywordsStruct() { - add - ("dtmc", 1) - ("ctmc", 2) - ("mdp", 3) - ("ctmdp", 4) - ("const", 5) - ("int", 6) - ("bool", 7) - ("module", 8) - ("endmodule", 9) - ("rewards", 10) - ("endrewards", 11) - ("true", 12) - ("false", 13) - ; - } - } keywords_; - - // A structure mapping the textual representation of a model type to the model type - // representation of the intermediate representation. - struct modelTypeStruct : qi::symbols { - modelTypeStruct() { - add - ("dtmc", storm::ir::Program::ModelType::DTMC) - ("ctmc", storm::ir::Program::ModelType::CTMC) - ("mdp", storm::ir::Program::ModelType::MDP) - ("ctmdp", storm::ir::Program::ModelType::CTMDP) - ; - } - } modelType_; - - // A structure mapping the textual representation of a binary relation to the representation - // of the intermediate representation. - struct relationalOperatorStruct : qi::symbols { - relationalOperatorStruct() { - add - ("=", storm::ir::expressions::BinaryRelationExpression::EQUAL) - ("<", storm::ir::expressions::BinaryRelationExpression::LESS) - ("<=", storm::ir::expressions::BinaryRelationExpression::LESS_OR_EQUAL) - (">", storm::ir::expressions::BinaryRelationExpression::GREATER) - (">=", storm::ir::expressions::BinaryRelationExpression::GREATER_OR_EQUAL) - ; - } - } relations_; - - // Structures mapping variable and constant names to the corresponding expression nodes of - // the intermediate representation. - struct qi::symbols> integerVariables_, booleanVariables_; - struct qi::symbols> integerConstants_, booleanConstants_, doubleConstants_; - - // A structure representing the identity function over identifier names. - struct qi::symbols integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_; - }; + struct PrismGrammar; }; } // namespace parser From b4ea27d7c414229f9a2235bed876932539c2b45a Mon Sep 17 00:00:00 2001 From: dehnert Date: Sat, 12 Jan 2013 15:37:19 +0100 Subject: [PATCH 012/152] Added checks to parser: Now only local variables may be written in updates and each variable at most once. --- src/parser/PrismParser.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 83380003e..96ae88ca7 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -169,13 +169,17 @@ struct PrismParser::PrismGrammar : qi::grammar> integerVariableName > qi::lit("'") > qi::lit("=") > integerExpression > qi::lit(")"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))] | (qi::lit("(") > booleanVariableName > qi::lit("'") > qi::lit("=") > booleanExpression > qi::lit(")"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))]; + assignmentDefinition = (qi::lit("(") >> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > integerExpression > qi::lit(")"))[phoenix::bind(assignedLocalIntegerVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))] | (qi::lit("(") > unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > booleanExpression > qi::lit(")"))[phoenix::bind(assignedLocalBooleanVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))]; assignmentDefinition.name("assignment"); assignmentDefinitionList = assignmentDefinition(qi::_r1) % "&"; assignmentDefinitionList.name("assignment list"); - updateDefinition = (constantDoubleExpression > qi::lit(":") > assignmentDefinitionList(qi::_a))[qi::_val = phoenix::construct(qi::_1, qi::_a)]; + updateDefinition = (constantDoubleExpression > qi::lit(":")[phoenix::clear(phoenix::ref(assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a))[qi::_val = phoenix::construct(qi::_1, qi::_a)]; updateDefinition.name("update"); updateListDefinition = +updateDefinition % "+"; updateListDefinition.name("update list"); @@ -183,15 +187,15 @@ struct PrismParser::PrismGrammar : qi::grammar> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(phoenix::val(qi::_1), qi::_b))), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1)]; + booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(phoenix::val(qi::_1), qi::_b))), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localBooleanVariables_.add, qi::_1, qi::_1)]; booleanVariableDefinition.name("boolean variable declaration"); - integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2, qi::_3, qi::_b))), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1)]; + integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2, qi::_3, qi::_b))), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localIntegerVariables_.add, qi::_1, qi::_1)]; integerVariableDefinition.name("integer variable declaration"); variableDefinition = (booleanVariableDefinition(qi::_r1) | integerVariableDefinition(qi::_r2)); variableDefinition.name("variable declaration"); // This block defines all entities that are needed for parsing a module. - moduleDefinition = (qi::lit("module") > freeIdentifierName > *(variableDefinition(qi::_a, qi::_b)) > +commandDefinition > qi::lit("endmodule"))[phoenix::bind(moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_2)]; + moduleDefinition = (qi::lit("module")[phoenix::clear(phoenix::ref(localBooleanVariables_)), phoenix::clear(phoenix::ref(localIntegerVariables_))] > freeIdentifierName > *(variableDefinition(qi::_a, qi::_b)) > +commandDefinition > qi::lit("endmodule"))[phoenix::bind(moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_2)]; moduleDefinition.name("module"); moduleDefinitionList %= +moduleDefinition; moduleDefinitionList.name("module list"); @@ -248,6 +252,8 @@ struct PrismParser::PrismGrammar : qi::grammar integerVariableName; qi::rule booleanVariableName; qi::rule commandName; + qi::rule unassignedLocalBooleanVariableName; + qi::rule unassignedLocalIntegerVariableName; // Rules for reward definitions. qi::rule&), Skipper> rewardDefinitionList; @@ -377,7 +383,8 @@ struct PrismParser::PrismGrammar : qi::grammar> integerConstants_, booleanConstants_, doubleConstants_; // A structure representing the identity function over identifier names. - struct qi::symbols integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_; + struct variableNamesStruct : qi::symbols { } integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_, + localBooleanVariables_, localIntegerVariables_, assignedLocalBooleanVariables_, assignedLocalIntegerVariables_; }; /*! From 50f891b9f239c7107fc243d476bed4e6b757508b Mon Sep 17 00:00:00 2001 From: dehnert Date: Sat, 12 Jan 2013 19:35:00 +0100 Subject: [PATCH 013/152] Removed some unnecessary boost stuff from IR expressions. Separated header and source file for all non-expression IR entities (expressions are still to come). Added comments for these classes. --- src/ir/Assignment.cpp | 46 +++++++ src/ir/Assignment.h | 70 ++++++----- src/ir/BooleanVariable.cpp | 41 +++++++ src/ir/BooleanVariable.h | 55 +++++---- src/ir/Command.cpp | 43 +++++++ src/ir/Command.h | 60 ++++----- src/ir/IR.h | 9 +- src/ir/IntegerVariable.cpp | 39 ++++++ src/ir/IntegerVariable.h | 61 +++++----- src/ir/Module.cpp | 46 +++++++ src/ir/Module.h | 70 ++++++----- src/ir/Program.cpp | 67 ++++++++++ src/ir/Program.h | 114 +++++++++--------- src/ir/RewardModel.cpp | 42 +++++++ src/ir/RewardModel.h | 67 +++++----- src/ir/StateReward.cpp | 35 ++++++ src/ir/StateReward.h | 51 +++++--- src/ir/TransitionReward.cpp | 35 ++++++ src/ir/TransitionReward.h | 53 +++++--- src/ir/Update.cpp | 45 +++++++ src/ir/Update.h | 61 +++++----- src/ir/Variable.cpp | 38 ++++++ src/ir/Variable.h | 68 ++++++----- .../BinaryBooleanFunctionExpression.h | 7 -- .../BinaryNumericalFunctionExpression.h | 7 -- src/ir/expressions/BinaryRelationExpression.h | 7 -- .../expressions/BooleanConstantExpression.h | 7 +- src/ir/expressions/BooleanLiteral.h | 5 - src/ir/expressions/ConstantExpression.h | 5 - src/ir/expressions/DoubleConstantExpression.h | 5 - src/ir/expressions/DoubleLiteral.h | 5 - .../expressions/IntegerConstantExpression.h | 5 - src/ir/expressions/IntegerLiteral.h | 5 - .../UnaryBooleanFunctionExpression.h | 6 - .../UnaryNumericalFunctionExpression.h | 6 - src/ir/expressions/VariableExpression.h | 5 - 36 files changed, 892 insertions(+), 399 deletions(-) create mode 100644 src/ir/Assignment.cpp create mode 100644 src/ir/BooleanVariable.cpp create mode 100644 src/ir/Command.cpp create mode 100644 src/ir/IntegerVariable.cpp create mode 100644 src/ir/Module.cpp create mode 100644 src/ir/Program.cpp create mode 100644 src/ir/RewardModel.cpp create mode 100644 src/ir/StateReward.cpp create mode 100644 src/ir/TransitionReward.cpp create mode 100644 src/ir/Update.cpp create mode 100644 src/ir/Variable.cpp diff --git a/src/ir/Assignment.cpp b/src/ir/Assignment.cpp new file mode 100644 index 000000000..095a922f3 --- /dev/null +++ b/src/ir/Assignment.cpp @@ -0,0 +1,46 @@ +/* + * Assignment.cpp + * + * Created on: 12.01.2013 + * Author: Christian Dehnert + */ + +#include "Assignment.h" + +#include + +namespace storm { + +namespace ir { + +// Initializes all members with their default constructors. +Assignment::Assignment() : variableName(), expression() { + // Nothing to do here. +} + +// Initializes all members according to the given values. +Assignment::Assignment(std::string variableName, std::shared_ptr expression) + : variableName(variableName), expression(expression) { + // Nothing to do here. +} + +// Returns the name of the variable associated with this assignment. +std::string const& Assignment::getVariableName() const { + return variableName; +} + +// Returns the expression associated with this assignment. +std::shared_ptr const& Assignment::getExpression() const { + return expression; +} + +// Build a string representation of the assignment. +std::string Assignment::toString() const { + std::stringstream result; + result << "(" << variableName << "' = " << expression->toString() << ")"; + return result.str(); +} + +} // namespace ir + +} // namespace storm diff --git a/src/ir/Assignment.h b/src/ir/Assignment.h index e6069d48f..019cc55eb 100644 --- a/src/ir/Assignment.h +++ b/src/ir/Assignment.h @@ -2,49 +2,65 @@ * Assignment.h * * Created on: 06.01.2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef ASSIGNMENT_H_ -#define ASSIGNMENT_H_ +#ifndef STORM_IR_ASSIGNMENT_H_ +#define STORM_IR_ASSIGNMENT_H_ #include "expressions/BaseExpression.h" +#include + namespace storm { namespace ir { +/*! + * A class representing the assignment of an expression to a variable. + */ class Assignment { public: - - Assignment() : variableName(""), expression(nullptr) { - - } - - Assignment(std::string variableName, std::shared_ptr expression) - : variableName(variableName), expression(expression) { - - } - - std::string getVariableName() { - return variableName; - } - - std::shared_ptr getExpression() { - return expression; - } - - std::string toString() { - return "(" + variableName + "' = " + expression->toString() + ")"; - } + /*! + * Default constructor. Creates an empty assignment. + */ + Assignment(); + + /*! + * Constructs an assignment using the given variable name and expression. + * @param variableName the variable that this assignment targets. + * @param expression the expression to assign to the variable. + */ + Assignment(std::string variableName, std::shared_ptr expression); + + /*! + * Retrieves the name of the variable that this assignment targets. + * @returns the name of the variable that this assignment targets. + */ + std::string const& getVariableName() const; + + /*! + * Retrieves the expression that is assigned to the variable. + * @returns the expression that is assigned to the variable. + */ + std::shared_ptr const& getExpression() const; + + /*! + * Retrieves a string representation of this assignment. + * @returns a string representation of this assignment. + */ + std::string toString() const; private: + // The name of the variable that this assignment targets. std::string variableName; + + // The expression that is assigned to the variable. std::shared_ptr expression; }; -} +} // namespace ir -} +} // namespace storm -#endif /* ASSIGNMENT_H_ */ +#endif /* STORM_IR_ASSIGNMENT_H_ */ diff --git a/src/ir/BooleanVariable.cpp b/src/ir/BooleanVariable.cpp new file mode 100644 index 000000000..e524d6753 --- /dev/null +++ b/src/ir/BooleanVariable.cpp @@ -0,0 +1,41 @@ +/* + * BooleanVariable.cpp + * + * Created on: 12.01.2013 + * Author: Christian Dehnert + */ + +#include "BooleanVariable.h" + +#include + +namespace storm { + +namespace ir { + +// Initializes all members with their default constructors. +BooleanVariable::BooleanVariable() : Variable() { + // Nothing to do here. +} + +// Initializes all members according to the given values. +BooleanVariable::BooleanVariable(std::string variableName, + std::shared_ptr initialValue) + : Variable(variableName, initialValue) { + // Nothing to do here. +} + +// Build a string representation of the variable. +std::string BooleanVariable::toString() const { + std::stringstream result; + result << getVariableName() << ": bool"; + if (this->getInitialValue() != nullptr) { + result << " init " << this->getInitialValue()->toString(); + } + result << ";"; + return result.str(); +} + +} // namespace ir + +} // namespace storm diff --git a/src/ir/BooleanVariable.h b/src/ir/BooleanVariable.h index eccf92078..dc832399e 100644 --- a/src/ir/BooleanVariable.h +++ b/src/ir/BooleanVariable.h @@ -2,42 +2,45 @@ * BooleanVariable.h * * Created on: 08.01.2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef BOOLEANVARIABLE_H_ -#define BOOLEANVARIABLE_H_ +#ifndef STORM_IR_BOOLEANVARIABLE_H_ +#define STORM_IR_BOOLEANVARIABLE_H_ + +#include "Variable.h" +#include namespace storm { namespace ir { +/*! + * A class representing a boolean variable. + */ class BooleanVariable : public Variable { public: - BooleanVariable() { - - } - - BooleanVariable(std::string variableName, std::shared_ptr initialValue = nullptr) : Variable(variableName, initialValue) { - - } - - virtual ~BooleanVariable() { - - } - - virtual std::string toString() { - std::string result = getVariableName() + ": bool"; - if (this->getInitialValue() != nullptr) { - result += " init " + this->getInitialValue()->toString(); - } - result += ";"; - return result; - } + /*! + * Default constructor. Creates a boolean variable without a name. + */ + BooleanVariable(); + + /*! + * Creates a boolean variable with the given name and the given initial value. + * @param variableName the name of the variable. + * @param initialValue the expression that defines the initial value of the variable. + */ + BooleanVariable(std::string variableName, std::shared_ptr initialValue = std::shared_ptr()); + + /*! + * Retrieves a string representation of this variable. + * @returns a string representation of this variable. + */ + std::string toString() const; }; -} +} // namespace ir -} +} // namespace storm -#endif /* BOOLEANVARIABLE_H_ */ +#endif /* STORM_IR_BOOLEANVARIABLE_H_ */ diff --git a/src/ir/Command.cpp b/src/ir/Command.cpp new file mode 100644 index 000000000..832fbb302 --- /dev/null +++ b/src/ir/Command.cpp @@ -0,0 +1,43 @@ +/* + * Command.cpp + * + * Created on: 12.01.2013 + * Author: Christian Dehnert + */ + +#include "Command.h" + +#include + +namespace storm { + +namespace ir { + +// Initializes all members with their default constructors. +Command::Command() : commandName(), guardExpression(), updates() { + // Nothing to do here. +} + +// Initializes all members according to the given values. +Command::Command(std::string commandName, std::shared_ptr guardExpression, std::vector updates) + : commandName(commandName), guardExpression(guardExpression), updates(updates) { + // Nothing to do here. +} + +// Build a string representation of the command. +std::string Command::toString() const { + std::stringstream result; + result << "[" << commandName << "] " << guardExpression->toString() << " -> "; + for (uint_fast64_t i = 0; i < updates.size(); ++i) { + result << updates[i].toString(); + if (i < updates.size() - 1) { + result << " + "; + } + } + result << ";"; + return result.str(); +} + +} // namespace ir + +} // namespace storm diff --git a/src/ir/Command.h b/src/ir/Command.h index fa881cb52..186d81058 100644 --- a/src/ir/Command.h +++ b/src/ir/Command.h @@ -2,54 +2,58 @@ * Command.h * * Created on: 06.01.2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef COMMAND_H_ -#define COMMAND_H_ +#ifndef STORM_IR_COMMAND_H_ +#define STORM_IR_COMMAND_H_ #include "expressions/BaseExpression.h" #include "Update.h" #include +#include namespace storm { namespace ir { +/*! + * A class representing a command. + */ class Command { public: - - Command() : commandName(""), guardExpression(nullptr), updates() { - - } - - Command(std::string commandName, std::shared_ptr guardExpression, std::vector updates) - : commandName(commandName), guardExpression(guardExpression), updates(updates) { - - } - - std::string toString() { - std::string result = "[" + commandName + "] " + guardExpression->toString() + " -> "; - for (uint_fast64_t i = 0; i < updates.size(); ++i) { - result += updates[i].toString(); - if (i < updates.size() - 1) { - result += " + "; - } - } - result += ";"; - return result; - } + /*! + * Default constructor. Creates a a command without name, guard and updates. + */ + Command(); + + /*! + * Creates a command with the given name, guard and updates. + * @param commandName the name of the command. + * @param guardExpression the expression that defines the guard of the command. + */ + Command(std::string commandName, std::shared_ptr guardExpression, std::vector updates); + + /*! + * Retrieves a string representation of this command. + * @returns a string representation of this command. + */ + std::string toString() const; private: + // The name of the command. std::string commandName; + + // The expression that defines the guard of the command. std::shared_ptr guardExpression; - std::vector updates; + // The list of updates of the command. + std::vector updates; }; -} +} // namespace ir -} +} // namespace storm -#endif /* COMMAND_H_ */ +#endif /* STORM_IR_COMMAND_H_ */ diff --git a/src/ir/IR.h b/src/ir/IR.h index 029e88fed..80a794002 100644 --- a/src/ir/IR.h +++ b/src/ir/IR.h @@ -2,12 +2,13 @@ * IR.h * * Created on: 06.01.2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef IR_H_ -#define IR_H_ +#ifndef STORM_IR_IR_H_ +#define STORM_IR_IR_H_ +// Bundle all headers to make it easy to include them. #include "expressions/Expressions.h" #include "Assignment.h" #include "Update.h" @@ -21,4 +22,4 @@ #include "RewardModel.h" #include "Program.h" -#endif /* IR_H_ */ +#endif /* STORM_IR_IR_H_ */ diff --git a/src/ir/IntegerVariable.cpp b/src/ir/IntegerVariable.cpp new file mode 100644 index 000000000..6b6724b1a --- /dev/null +++ b/src/ir/IntegerVariable.cpp @@ -0,0 +1,39 @@ +/* + * IntegerVariable.cpp + * + * Created on: 12.01.2013 + * Author: Christian Dehnert + */ + +#include "IntegerVariable.h" + +#include + +namespace storm { + +namespace ir { + +// Initializes all members with their default constructors. +IntegerVariable::IntegerVariable() : lowerBound(), upperBound() { + // Nothing to do here. +} + +// Initializes all members according to the given values. +IntegerVariable::IntegerVariable(std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue) : Variable(variableName, initialValue), lowerBound(lowerBound), upperBound(upperBound) { + // Nothing to do here. +} + +// Build a string representation of the variable. +std::string IntegerVariable::toString() const { + std::stringstream result; + result << this->getVariableName() << ": [" << lowerBound->toString() << ".." << upperBound->toString() << "]"; + if (this->getInitialValue() != nullptr) { + result << " init " + this->getInitialValue()->toString(); + } + result << ";"; + return result.str(); +} + +} // namespace ir + +} // namespace storm diff --git a/src/ir/IntegerVariable.h b/src/ir/IntegerVariable.h index 78c638954..d687e2a04 100644 --- a/src/ir/IntegerVariable.h +++ b/src/ir/IntegerVariable.h @@ -2,49 +2,56 @@ * IntegerVariable.h * * Created on: 08.01.2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef INTEGERVARIABLE_H_ -#define INTEGERVARIABLE_H_ +#ifndef STORM_IR_INTEGERVARIABLE_H_ +#define STORM_IR_INTEGERVARIABLE_H_ -#include "Variable.h" #include "expressions/BaseExpression.h" +#include "Variable.h" +#include namespace storm { namespace ir { +/*! + * A class representing an integer variable. + */ class IntegerVariable : public Variable { public: - IntegerVariable() : lowerBound(nullptr), upperBound(nullptr) { - - } - - IntegerVariable(std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue = nullptr) : Variable(variableName, initialValue), lowerBound(lowerBound), upperBound(upperBound) { - - } - - virtual ~IntegerVariable() { - - } - - virtual std::string toString() { - std::string result = getVariableName() + ": [" + lowerBound->toString() + ".." + upperBound->toString() + "]"; - if (this->getInitialValue() != nullptr) { - result += " init " + this->getInitialValue()->toString(); - } - result += ";"; - return result; - } + /*! + * Default constructor. Creates an integer variable without a name and lower and upper bounds. + */ + IntegerVariable(); + + /*! + * Creates an integer variable with the given name, lower and upper bounds and the given initial + * value. + * @param variableName the name of the variable. + * @param lowerBound the lower bound of the domain of the variable. + * @param upperBound the upper bound of the domain of the variable. + * @param initialValue the expression that defines the initial value of the variable. + */ + IntegerVariable(std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue = std::shared_ptr()); + + /*! + * Retrieves a string representation of this variable. + * @returns a string representation of this variable. + */ + std::string toString() const; private: + // The lower bound of the domain of the variable. std::shared_ptr lowerBound; + + // The upper bound of the domain of the variable. std::shared_ptr upperBound; }; -} +} // namespace ir -} +} // namespace storm -#endif /* INTEGERVARIABLE_H_ */ +#endif /* STORM_IR_INTEGERVARIABLE_H_ */ diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp new file mode 100644 index 000000000..5f28a8d13 --- /dev/null +++ b/src/ir/Module.cpp @@ -0,0 +1,46 @@ +/* + * Module.cpp + * + * Created on: 12.01.2013 + * Author: Christian Dehnert + */ + +#include "Module.h" + +#include + +namespace storm { + +namespace ir { + +// Initializes all members with their default constructors. +Module::Module() : moduleName(), booleanVariables(), integerVariables(), commands() { + // Nothing to do here. +} + +// Initializes all members according to the given values. +Module::Module(std::string moduleName, std::map booleanVariables, std::map integerVariables, std::vector commands) + : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), commands(commands) { + // Nothing to do here. +} + +// Build a string representation of the variable. +std::string Module::toString() const { + std::stringstream result; + result << "module " << moduleName << std::endl; + for (auto variable : booleanVariables) { + result << "\t" << variable.second.toString() << std::endl; + } + for (auto variable : integerVariables) { + result << "\t" << variable.second.toString() << std::endl; + } + for (auto command : commands) { + result << "\t" << command.toString() << std::endl; + } + result << "endmodule" << std::endl; + return result.str(); +} + +} // namespace ir + +} // namespace storm diff --git a/src/ir/Module.h b/src/ir/Module.h index 4b673a757..ad0218730 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -2,61 +2,65 @@ * Module.h * * Created on: 04.01.2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef MODULE_H_ -#define MODULE_H_ +#ifndef STORM_IR_MODULE_H_ +#define STORM_IR_MODULE_H_ #include "BooleanVariable.h" #include "IntegerVariable.h" #include "Command.h" #include +#include +#include namespace storm { namespace ir { +/*! + * A class representing a module. + */ class Module { public: - Module() : moduleName(""), booleanVariables(), integerVariables(), commands() { - - } - - Module(std::string moduleName, std::map booleanVariables, std::map integerVariables, std::vector commands) - : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), commands(commands) { - - } - - Module(std::string moduleName, std::vector commands) : moduleName(moduleName), booleanVariables(), integerVariables(), commands(commands) { - - } - - std::string toString() { - std::string result = "module " + moduleName + "\n"; - for (auto variable : booleanVariables) { - result += "\t" + variable.second.toString() + "\n"; - } - for (auto variable : integerVariables) { - result += "\t" + variable.second.toString() + "\n"; - } - for (auto command : commands) { - result += "\t" + command.toString() + "\n"; - } - result += "endmodule\n"; - return result; - } + /*! + * Default constructor. Creates an empty module. + */ + Module(); + + /*! + * Creates a module with the given name, variables and commands. + * @param moduleName the name of the module. + * @param booleanVariables a map of boolean variables. + * @param integerVariables a map of integer variables. + * @param commands the vector of commands. + */ + Module(std::string moduleName, std::map booleanVariables, std::map integerVariables, std::vector commands); + + /*! + * Retrieves a string representation of this variable. + * @returns a string representation of this variable. + */ + std::string toString() const; private: + // The name of the module. std::string moduleName; + + // A map of boolean variable names to their details. std::map booleanVariables; + + // A map of integer variable names to their details. std::map integerVariables; + + // The commands associated with the module. std::vector commands; }; -} +} // namespace ir -} +} // namespace storm -#endif /* MODULE_H_ */ +#endif /* STORM_IR_MODULE_H_ */ diff --git a/src/ir/Program.cpp b/src/ir/Program.cpp new file mode 100644 index 000000000..5a250405e --- /dev/null +++ b/src/ir/Program.cpp @@ -0,0 +1,67 @@ +/* + * Program.cpp + * + * Created on: 12.01.2013 + * Author: Christian Dehnert + */ + +#include "Program.h" + +#include + +namespace storm { + +namespace ir { + +// Initializes all members with their default constructors. +Program::Program() : modelType(UNDEFINED), booleanUndefinedConstantExpressions(), integerUndefinedConstantExpressions(), doubleUndefinedConstantExpressions(), modules(), rewards() { + // Nothing to do here. +} + +// Initializes all members according to the given values. +Program::Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector modules, std::map rewards, std::map> labels) + : modelType(modelType), booleanUndefinedConstantExpressions(booleanUndefinedConstantExpressions), integerUndefinedConstantExpressions(integerUndefinedConstantExpressions), doubleUndefinedConstantExpressions(doubleUndefinedConstantExpressions), modules(modules), rewards(rewards), labels(labels) { + // Nothing to do here. +} + +// Build a string representation of the program. +std::string Program::toString() const { + std::stringstream result; + switch (modelType) { + case UNDEFINED: result << "undefined"; break; + case DTMC: result << "dtmc"; break; + case CTMC: result << "ctmc"; break; + case MDP: result << "mdp"; break; + case CTMDP: result << "ctmdp"; break; + } + result << std::endl; + + for (auto element : booleanUndefinedConstantExpressions) { + result << "const bool " << element.first << ";" << std::endl; + } + for (auto element : integerUndefinedConstantExpressions) { + result << "const int " << element.first << ";" << std::endl; + } + for (auto element : doubleUndefinedConstantExpressions) { + result << "const double " << element.first << ";" << std::endl; + } + result << std::endl; + + for (auto mod : modules) { + result << mod.toString() << std::endl; + } + + for (auto rewardModel : rewards) { + result << rewardModel.second.toString() << std::endl; + } + + for (auto label : labels) { + result << "label " << label.first << " = " << label.second->toString() <<";" << std::endl; + } + + return result.str(); +} + +} // namespace ir + +} // namepsace storm diff --git a/src/ir/Program.h b/src/ir/Program.h index 57a6ac11a..8fcd7c10f 100644 --- a/src/ir/Program.h +++ b/src/ir/Program.h @@ -2,11 +2,11 @@ * Program.h * * Created on: 04.01.2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef PROGRAM_H_ -#define PROGRAM_H_ +#ifndef STORM_IR_PROGRAM_H_ +#define STORM_IR_PROGRAM_H_ #include "expressions/BaseExpression.h" #include "expressions/BooleanConstantExpression.h" @@ -15,82 +15,76 @@ #include "Module.h" #include "RewardModel.h" +#include +#include +#include + namespace storm { namespace ir { +/*! + * A class representing a program. + */ class Program { public: + /*! + * An enum for the different model types. + */ enum ModelType {UNDEFINED, DTMC, CTMC, MDP, CTMDP}; - Program() : modelType(UNDEFINED), booleanUndefinedConstantExpressions(), integerUndefinedConstantExpressions(), doubleUndefinedConstantExpressions(), modules(), rewards() { - - } - - Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector modules, std::map rewards, std::map> labels) - : modelType(modelType), booleanUndefinedConstantExpressions(booleanUndefinedConstantExpressions), integerUndefinedConstantExpressions(integerUndefinedConstantExpressions), doubleUndefinedConstantExpressions(doubleUndefinedConstantExpressions), modules(modules), rewards(rewards), labels(labels) { - - } - - Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector modules) - : modelType(modelType), booleanUndefinedConstantExpressions(booleanUndefinedConstantExpressions), integerUndefinedConstantExpressions(integerUndefinedConstantExpressions), doubleUndefinedConstantExpressions(doubleUndefinedConstantExpressions), modules(modules), rewards() { - - } - - - Program(ModelType modelType, std::vector modules) : modelType(modelType), booleanUndefinedConstantExpressions(), integerUndefinedConstantExpressions(), doubleUndefinedConstantExpressions(), modules(modules), rewards() { - - } - - std::string toString() { - std::string result = ""; - switch (modelType) { - case UNDEFINED: result += "undefined\n\n"; break; - case DTMC: result += "dtmc\n\n"; break; - case CTMC: result += "ctmc\n\n"; break; - case MDP: result += "mdp\n\n"; break; - case CTMDP: result += "ctmdp\n\n"; break; - } - for (auto element : booleanUndefinedConstantExpressions) { - result += "const bool " + element.first + ";\n"; - } - for (auto element : integerUndefinedConstantExpressions) { - result += "const int " + element.first + ";\n"; - } - for (auto element : doubleUndefinedConstantExpressions) { - result += "const double " + element.first + ";\n"; - } - result += "\n"; - for (auto mod : modules) { - result += mod.toString(); - result += "\n"; - } - - for (auto rewardModel : rewards) { - result += rewardModel.second.toString(); - result +="\n"; - } - - for (auto label : labels) { - result += "label " + label.first + " = " + label.second->toString() + ";\n"; - } - - return result; - } + /*! + * Default constructor. Creates an empty program. + */ + Program(); + + /*! + * Creates a program with the given model type, undefined constants, modules, rewards and labels. + * @param modelType the type of the model that this program gives rise to. + * @param booleanUndefinedConstantExpressions a map of undefined boolean constants to their + * expression nodes. + * @param integerUndefinedConstantExpressions a map of undefined integer constants to their + * expression nodes. + * @param doubleUndefinedConstantExpressions a map of undefined double constants to their + * expression nodes. + * @param modules The modules of the program. + * @param rewards The reward models of the program. + * @param labels The labels defined for this model. + */ + Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector modules, std::map rewards, std::map> labels); + + /*! + * Retrieves a string representation of this program. + * @returns a string representation of this program. + */ + std::string toString() const; private: + // The type of the model. ModelType modelType; + + // A map of undefined boolean constants to their expression nodes. std::map> booleanUndefinedConstantExpressions; + + // A map of undefined integer constants to their expressions nodes. std::map> integerUndefinedConstantExpressions; + + // A mpa of undefined double constants to their expressions nodes. std::map> doubleUndefinedConstantExpressions; + + // The modules associated with the program. std::vector modules; + + // The reward models associated with the program. std::map rewards; + + // The labels that are defined for this model. std::map> labels; }; -} +} // namespace ir -} +} // namespace storm -#endif /* PROGRAM_H_ */ +#endif /* STORM_IR_PROGRAM_H_ */ diff --git a/src/ir/RewardModel.cpp b/src/ir/RewardModel.cpp new file mode 100644 index 000000000..d8549db6e --- /dev/null +++ b/src/ir/RewardModel.cpp @@ -0,0 +1,42 @@ +/* + * RewardModel.cpp + * + * Created on: 12.01.2013 + * Author: Christian Dehnert + */ + +#include "RewardModel.h" + +#include + +namespace storm { + +namespace ir { + +// Initializes all members with their default constructors. +RewardModel::RewardModel() : rewardModelName(), stateRewards(), transitionRewards() { + // Nothing to do here. +} + +// Initializes all members according to the given values. +RewardModel::RewardModel(std::string rewardModelName, std::vector stateRewards, std::vector transitionRewards) : rewardModelName(rewardModelName), stateRewards(stateRewards), transitionRewards(transitionRewards) { + // Nothing to do here. +} + +// Build a string representation of the reward model. +std::string RewardModel::toString() const { + std::stringstream result; + result << "rewards \"" << rewardModelName << "\"" << std::endl; + for (auto reward : stateRewards) { + result << reward.toString() << std::endl; + } + for (auto reward : transitionRewards) { + result << reward.toString() << std::endl; + } + result << "endrewards" << std::endl; + return result.str(); +} + +} // namespace ir + +} // namespace storm diff --git a/src/ir/RewardModel.h b/src/ir/RewardModel.h index 21c08fa75..fcf8dcf01 100644 --- a/src/ir/RewardModel.h +++ b/src/ir/RewardModel.h @@ -2,52 +2,59 @@ * RewardModel.h * * Created on: 04.01.2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef REWARDMODEL_H_ -#define REWARDMODEL_H_ +#ifndef STORM_IR_REWARDMODEL_H_ +#define STORM_IR_REWARDMODEL_H_ -#include +#include "StateReward.h" +#include "TransitionReward.h" + +#include +#include namespace storm { namespace ir { +/*! + * A class representing a reward model. + */ class RewardModel { public: - RewardModel() : rewardModelName(""), stateRewards(), transitionRewards() { - - } - - RewardModel(std::string rewardModelName, std::vector stateRewards, std::vector transitionRewards) : rewardModelName(rewardModelName), stateRewards(stateRewards), transitionRewards(transitionRewards) { - - } - - RewardModel(RewardModel const& other) : rewardModelName(other.rewardModelName), stateRewards(other.stateRewards), transitionRewards(other.transitionRewards) { - - } - - std::string toString() { - std::string result = "rewards \"" + rewardModelName + "\"\n"; - for (auto reward : stateRewards) { - result += reward.toString() + "\n"; - } - for (auto reward : transitionRewards) { - result += reward.toString() + "\n"; - } - result += "endrewards\n"; - return result; - } + /*! + * Default constructor. Creates an empty reward model. + */ + RewardModel(); + + /*! + * Creates a reward module with the given name, state and transition rewards. + * @param rewardModelName the name of the reward model. + * @param stateRewards A vector of state-based reward. + * @param transitionRewards A vector of transition-based reward. + */ + RewardModel(std::string rewardModelName, std::vector stateRewards, std::vector transitionRewards); + + /*! + * Retrieves a string representation of this variable. + * @returns a string representation of this variable. + */ + std::string toString() const; private: + // The name of the reward model. std::string rewardModelName; + + // The state-based rewards associated with this reward model. std::vector stateRewards; + + // The transition-based rewards associated with this reward model. std::vector transitionRewards; }; -} +} // namespace ir -} +} // namespace storm -#endif /* REWARDMODEL_H_ */ +#endif /* STORM_IR_REWARDMODEL_H_ */ diff --git a/src/ir/StateReward.cpp b/src/ir/StateReward.cpp new file mode 100644 index 000000000..28ed4b72f --- /dev/null +++ b/src/ir/StateReward.cpp @@ -0,0 +1,35 @@ +/* + * StateReward.cpp + * + * Created on: 12.01.2013 + * Author: Christian Dehnert + */ + +#include "StateReward.h" + +#include + +namespace storm { + +namespace ir { + +// Initializes all members with their default constructors. +StateReward::StateReward() : statePredicate(), rewardValue() { + // Nothing to do here. +} + +// Initializes all members according to the given values. +StateReward::StateReward(std::shared_ptr statePredicate, std::shared_ptr rewardValue) : statePredicate(statePredicate), rewardValue(rewardValue) { + // Nothing to do here. +} + +// Build a string representation of the state reward. +std::string StateReward::toString() const { + std::stringstream result; + result << "\t" << statePredicate->toString() << ": " << rewardValue->toString() << ";"; + return result.str(); +} + +} // namespace ir + +} // namespace storm diff --git a/src/ir/StateReward.h b/src/ir/StateReward.h index 9128c74ff..0a127fd0c 100644 --- a/src/ir/StateReward.h +++ b/src/ir/StateReward.h @@ -2,39 +2,56 @@ * StateReward.h * * Created on: Jan 10, 2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef STATEREWARD_H_ -#define STATEREWARD_H_ +#ifndef STORM_IR_STATEREWARD_H_ +#define STORM_IR_STATEREWARD_H_ #include "expressions/BaseExpression.h" +#include + namespace storm { namespace ir { +/*! + * A class representing a state reward. + */ class StateReward { public: - StateReward() : statePredicate(nullptr), rewardValue(nullptr) { - - } - - StateReward(std::shared_ptr statePredicate, std::shared_ptr rewardValue) : statePredicate(statePredicate), rewardValue(rewardValue) { - - } - - std::string toString() { - return "\t" + statePredicate->toString() + ": " + rewardValue->toString() + ";"; - } + /*! + * Default constructor. Creates an empty state reward. + */ + StateReward(); + + /*! + * Creates a state reward for the states satisfying the given expression with the value given + * by a second expression. + * @param statePredicate the predicate that states earning this state-based reward need to + * satisfy. + * @param rewardValue an expression specifying the values of the rewards to attach to the + * states. + */ + StateReward(std::shared_ptr statePredicate, std::shared_ptr rewardValue); + + /*! + * Retrieves a string representation of this state reward. + * @returns a string representation of this state reward. + */ + std::string toString() const; private: + // The predicate that characterizes the states that obtain this reward. std::shared_ptr statePredicate; + + // The expression that specifies the value of the reward obtained. std::shared_ptr rewardValue; }; -} +} // namespace ir -} +} // namespace storm -#endif /* STATEREWARD_H_ */ +#endif /* STORM_IR_STATEREWARD_H_ */ diff --git a/src/ir/TransitionReward.cpp b/src/ir/TransitionReward.cpp new file mode 100644 index 000000000..6052f8b37 --- /dev/null +++ b/src/ir/TransitionReward.cpp @@ -0,0 +1,35 @@ +/* + * TransitionReward.cpp + * + * Created on: 12.01.2013 + * Author: Christian Dehnert + */ + +#include "TransitionReward.h" + +#include + +namespace storm { + +namespace ir { + +// Initializes all members with their default constructors. +TransitionReward::TransitionReward() : commandName(), statePredicate(), rewardValue() { + // Nothing to do here. +} + +// Initializes all members according to the given values. +TransitionReward::TransitionReward(std::string commandName, std::shared_ptr statePredicate, std::shared_ptr rewardValue) : commandName(commandName), statePredicate(statePredicate), rewardValue(rewardValue) { + // Nothing to do here. +} + +// Build a string representation of the transition reward. +std::string TransitionReward::toString() const { + std::stringstream result; + result << "\t[" << commandName << "] " << statePredicate->toString() << ": " << rewardValue->toString() << ";"; + return result.str(); +} + +} // namespace ir + +} // namespace storm diff --git a/src/ir/TransitionReward.h b/src/ir/TransitionReward.h index d444560ec..eaffe10ae 100644 --- a/src/ir/TransitionReward.h +++ b/src/ir/TransitionReward.h @@ -2,11 +2,11 @@ * TransitionReward.h * * Created on: Jan 10, 2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef TRANSITIONREWARD_H_ -#define TRANSITIONREWARD_H_ +#ifndef STORM_IR_TRANSITIONREWARD_H_ +#define STORM_IR_TRANSITIONREWARD_H_ #include "expressions/BaseExpression.h" @@ -14,28 +14,47 @@ namespace storm { namespace ir { +/*! + * A class representing a transition reward. + */ class TransitionReward { public: - TransitionReward() : commandName(""), statePredicate(nullptr), rewardValue(nullptr) { - - } - - TransitionReward(std::string commandName, std::shared_ptr statePredicate, std::shared_ptr rewardValue) : commandName(commandName), statePredicate(statePredicate), rewardValue(rewardValue) { - - } - - std::string toString() { - return "\t[" + commandName + "] " + statePredicate->toString() + ": " + rewardValue->toString() + ";"; - } + /*! + * Default constructor. Creates an empty transition reward. + */ + TransitionReward(); + + /*! + * Creates a transition reward for the transitions with the given name emanating from states + * satisfying the given expression with the value given by another expression. + * @param commandName the name of the command that obtains this reward. + * @param statePredicate the predicate that needs to hold before taking a transition with the + * previously specified name in order to obtain the reward. + * @param rewardValue an expression specifying the values of the rewards to attach to the + * transitions. + */ + TransitionReward(std::string commandName, std::shared_ptr statePredicate, std::shared_ptr rewardValue); + + /*! + * Retrieves a string representation of this transition reward. + * @returns a string representation of this transition reward. + */ + std::string toString() const; private: + // The name of the command this transition-based reward is attached to. std::string commandName; + + // A predicate that needs to be satisfied by states for the reward to be obtained (by taking + // a corresponding command transition). std::shared_ptr statePredicate; + + // The expression specifying the value of the reward obtained along the transitions. std::shared_ptr rewardValue; }; -} +} // namespace ir -} +} // namespace storm -#endif /* TRANSITIONREWARD_H_ */ +#endif /* STORM_IR_TRANSITIONREWARD_H_ */ diff --git a/src/ir/Update.cpp b/src/ir/Update.cpp new file mode 100644 index 000000000..4e59d46be --- /dev/null +++ b/src/ir/Update.cpp @@ -0,0 +1,45 @@ +/* + * Update.cpp + * + * Created on: 12.01.2013 + * Author: Christian Dehnert + */ + +#include "Update.h" + +#include + +namespace storm { + +namespace ir { + +// Initializes all members with their default constructors. +Update::Update() : likelihoodExpression(), assignments() { + // Nothing to do here. +} + +// Initializes all members according to the given values. +Update::Update(std::shared_ptr likelihoodExpression, std::map assignments) + : likelihoodExpression(likelihoodExpression), assignments(assignments) { + // Nothing to do here. +} + +// Build a string representation of the update. +std::string Update::toString() const { + std::stringstream result; + result << likelihoodExpression->toString() << " : "; + uint_fast64_t i = 0; + for (auto assignment : assignments) { + result << assignment.second.toString(); + ++i; + if (i < assignments.size() - 1) { + result << " & "; + } + + } + return result.str(); +} + +} // namespace ir + +} // namespace storm diff --git a/src/ir/Update.h b/src/ir/Update.h index 6f2d3535f..1aeb1d125 100644 --- a/src/ir/Update.h +++ b/src/ir/Update.h @@ -2,51 +2,56 @@ * Update.h * * Created on: 06.01.2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef UPDATE_H_ -#define UPDATE_H_ +#ifndef STORM_IR_UPDATE_H_ +#define STORM_IR_UPDATE_H_ #include "expressions/BaseExpression.h" +#include "Assignment.h" + #include +#include namespace storm { namespace ir { +/*! + * A class representing an update of a command. + */ class Update { public: - Update() : likelihoodExpression(nullptr), assignments() { - - } - - Update(std::shared_ptr likelihoodExpression, std::map assignments) - : likelihoodExpression(likelihoodExpression), assignments(assignments) { - - } - - std::string toString() { - std::string result = likelihoodExpression->toString() + " : "; - uint_fast64_t i = 0; - for (auto assignment : assignments) { - result += assignment.second.toString(); - ++i; - if (i < assignments.size() - 1) { - result += " & "; - } - - } - return result; - } + /*! + * Default constructor. Creates an empty update. + */ + Update(); + + /*! + * Creates an update with the given expression specifying the likelihood and the mapping of + * variable to their assignments. + * @param likelihoodExpression an expression specifying the likelihood of this update. + * @param assignments a map of variable names to their assignments. + */ + Update(std::shared_ptr likelihoodExpression, std::map assignments); + + /*! + * Retrieves a string representation of this update. + * @returns a string representation of this update. + */ + std::string toString() const; private: + // An expression specifying the likelihood of taking this update. std::shared_ptr likelihoodExpression; + + // A mapping of variable names to their assignments in this update. std::map assignments; }; -} +} // namespace ir -} +} // namespace storm -#endif /* UPDATE_H_ */ +#endif /*STORM_IR_UPDATE_H_ */ diff --git a/src/ir/Variable.cpp b/src/ir/Variable.cpp new file mode 100644 index 000000000..a735fa94d --- /dev/null +++ b/src/ir/Variable.cpp @@ -0,0 +1,38 @@ +/* + * Variable.cpp + * + * Created on: 12.01.2013 + * Author: Christian Dehnert + */ + +#include "Variable.h" + +#include + +namespace storm { + +namespace ir { + +// Initializes all members with their default constructors. +Variable::Variable() : variableName(), initialValue() { + // Nothing to do here. +} + +// Initializes all members according to the given values. +Variable::Variable(std::string variableName, std::shared_ptr initialValue) : variableName(variableName), initialValue(initialValue) { + // Nothing to do here. +} + +// Return the name of the variable. +std::string const& Variable::getVariableName() const { + return variableName; +} + +// Return the expression for the initial value of the variable. +std::shared_ptr const& Variable::getInitialValue() const { + return initialValue; +} + +} // namespace ir + +} // namespace storm diff --git a/src/ir/Variable.h b/src/ir/Variable.h index c015bb98b..bbd567073 100644 --- a/src/ir/Variable.h +++ b/src/ir/Variable.h @@ -2,50 +2,60 @@ * Variable.h * * Created on: 06.01.2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef VARIABLE_H_ -#define VARIABLE_H_ +#ifndef STORM_IR_VARIABLE_H_ +#define STORM_IR_VARIABLE_H_ + +#include "expressions/BaseExpression.h" + +#include namespace storm { namespace ir { +/*! + * A class representing a untyped variable. + */ class Variable { public: - Variable() : variableName(""), initialValue(nullptr) { - - } - - Variable(std::string variableName, std::shared_ptr initialValue = nullptr) : variableName(variableName), initialValue(initialValue) { - - } - - virtual ~Variable() { - - } - - virtual std::string toString() { - return variableName; - } - - std::string getVariableName() { - return variableName; - } - - std::shared_ptr getInitialValue() { - return initialValue; - } + /*! + * Default constructor. Creates an unnamed, untyped variable without initial value. + */ + Variable(); + + /*! + * Creates an untyped variable with the given name and initial value. + * @param variableName the name of the variable. + * @param initialValue the expression that defines the initial value of the variable. + */ + Variable(std::string variableName, std::shared_ptr initialValue = std::shared_ptr()); + + /*! + * Retrieves the name of the variable. + * @returns the name of the variable. + */ + std::string const& getVariableName() const; + + /*! + * Retrieves the expression defining the initial value of the variable. + * @returns the expression defining the initial value of the variable. + */ + std::shared_ptr const& getInitialValue() const; private: + // The name of the variable. std::string variableName; + + // The expression defining the initial value of the variable. std::shared_ptr initialValue; }; -} +} // namespace ir -} +} // namespace storm -#endif /* VARIABLE_H_ */ +#endif /* STORM_IR_VARIABLE_H_ */ diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.h b/src/ir/expressions/BinaryBooleanFunctionExpression.h index 5a745ba36..bd388dc04 100644 --- a/src/ir/expressions/BinaryBooleanFunctionExpression.h +++ b/src/ir/expressions/BinaryBooleanFunctionExpression.h @@ -53,11 +53,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::expressions::BinaryBooleanFunctionExpression, - (std::shared_ptr, left) - (std::shared_ptr, right) - (storm::ir::expressions::BinaryBooleanFunctionExpression::FunctorType, functor) -) - #endif /* BINARYBOOLEANFUNCTIONEXPRESSION_H_ */ diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h index 0a8b7cffe..5b928768e 100644 --- a/src/ir/expressions/BinaryNumericalFunctionExpression.h +++ b/src/ir/expressions/BinaryNumericalFunctionExpression.h @@ -53,11 +53,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::expressions::BinaryNumericalFunctionExpression, - (std::shared_ptr, left) - (std::shared_ptr, right) - (storm::ir::expressions::BinaryNumericalFunctionExpression::FunctorType, functor) -) - #endif /* BINARYFUNCTIONEXPRESSION_H_ */ diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h index 8ab6aba44..625b801f5 100644 --- a/src/ir/expressions/BinaryRelationExpression.h +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -54,11 +54,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::expressions::BinaryRelationExpression, - (std::shared_ptr, left) - (std::shared_ptr, right) - (storm::ir::expressions::BinaryRelationExpression::RelationType, relation) -) - #endif /* BINARYRELATIONEXPRESSION_H_ */ diff --git a/src/ir/expressions/BooleanConstantExpression.h b/src/ir/expressions/BooleanConstantExpression.h index 5d36598b2..a10c2363e 100644 --- a/src/ir/expressions/BooleanConstantExpression.h +++ b/src/ir/expressions/BooleanConstantExpression.h @@ -10,6 +10,8 @@ #include "ConstantExpression.h" +#include + namespace storm { namespace ir { @@ -58,9 +60,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::expressions::BooleanConstantExpression, - (std::string, constantName) -) - #endif /* BOOLEANCONSTANTEXPRESSION_H_ */ diff --git a/src/ir/expressions/BooleanLiteral.h b/src/ir/expressions/BooleanLiteral.h index c2300cded..81950e52a 100644 --- a/src/ir/expressions/BooleanLiteral.h +++ b/src/ir/expressions/BooleanLiteral.h @@ -43,9 +43,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::expressions::BooleanLiteral, - (bool, value) -) - #endif /* BOOLEANLITERAL_H_ */ diff --git a/src/ir/expressions/ConstantExpression.h b/src/ir/expressions/ConstantExpression.h index 38581d1e4..239b3dc68 100644 --- a/src/ir/expressions/ConstantExpression.h +++ b/src/ir/expressions/ConstantExpression.h @@ -39,9 +39,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::expressions::ConstantExpression, - (std::string, constantName) -) - #endif /* CONSTANTEXPRESSION_H_ */ diff --git a/src/ir/expressions/DoubleConstantExpression.h b/src/ir/expressions/DoubleConstantExpression.h index 6969965ae..3a7363a65 100644 --- a/src/ir/expressions/DoubleConstantExpression.h +++ b/src/ir/expressions/DoubleConstantExpression.h @@ -58,9 +58,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::expressions::DoubleConstantExpression, - (std::string, constantName) -) - #endif /* DOUBLECONSTANTEXPRESSION_H_ */ diff --git a/src/ir/expressions/DoubleLiteral.h b/src/ir/expressions/DoubleLiteral.h index d88dbf33b..dbdcf55ca 100644 --- a/src/ir/expressions/DoubleLiteral.h +++ b/src/ir/expressions/DoubleLiteral.h @@ -41,9 +41,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::expressions::DoubleLiteral, - (double, value) -) - #endif /* DOUBLELITERAL_H_ */ diff --git a/src/ir/expressions/IntegerConstantExpression.h b/src/ir/expressions/IntegerConstantExpression.h index d0df521af..5ff4d7f87 100644 --- a/src/ir/expressions/IntegerConstantExpression.h +++ b/src/ir/expressions/IntegerConstantExpression.h @@ -58,9 +58,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::expressions::IntegerConstantExpression, - (std::string, constantName) -) - #endif /* INTEGERCONSTANTEXPRESSION_H_ */ diff --git a/src/ir/expressions/IntegerLiteral.h b/src/ir/expressions/IntegerLiteral.h index bea4c1743..aef509321 100644 --- a/src/ir/expressions/IntegerLiteral.h +++ b/src/ir/expressions/IntegerLiteral.h @@ -39,9 +39,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::expressions::IntegerLiteral, - (int, value) -) - #endif /* INTEGERLITERAL_H_ */ diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.h b/src/ir/expressions/UnaryBooleanFunctionExpression.h index f1e71e296..893169b51 100644 --- a/src/ir/expressions/UnaryBooleanFunctionExpression.h +++ b/src/ir/expressions/UnaryBooleanFunctionExpression.h @@ -47,10 +47,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::expressions::UnaryBooleanFunctionExpression, - (std::shared_ptr, child) - (storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType, functor) -) - #endif /* UNARYBOOLEANFUNCTIONEXPRESSION_H_ */ diff --git a/src/ir/expressions/UnaryNumericalFunctionExpression.h b/src/ir/expressions/UnaryNumericalFunctionExpression.h index 084fc74d8..f697f35eb 100644 --- a/src/ir/expressions/UnaryNumericalFunctionExpression.h +++ b/src/ir/expressions/UnaryNumericalFunctionExpression.h @@ -47,10 +47,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::expressions::UnaryNumericalFunctionExpression, - (std::shared_ptr, child) - (storm::ir::expressions::UnaryNumericalFunctionExpression::FunctorType, functor) -) - #endif /* UNARYFUNCTIONEXPRESSION_H_ */ diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index 5eceb7c6b..a6a27fa43 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -41,9 +41,4 @@ public: } -BOOST_FUSION_ADAPT_STRUCT( - storm::ir::expressions::VariableExpression, - (std::string, variableName) -) - #endif /* VARIABLEEXPRESSION_H_ */ From d414b93bad7d68ab0b5b02eade551d4696cfc37f Mon Sep 17 00:00:00 2001 From: dehnert Date: Sun, 13 Jan 2013 22:47:29 +0100 Subject: [PATCH 014/152] Added some functionality to IR. Introduced case distinction for boolean/integer assignments in updates. Started writing an IR adapter. --- .../IntermediateRepresentationAdapter.h | 144 ++++++++++++++++++ .../ExpressionEvaluationException.h | 23 +++ src/exceptions/NotImplementedException.h | 23 +++ src/ir/BooleanVariable.cpp | 6 +- src/ir/BooleanVariable.h | 5 +- src/ir/Command.cpp | 15 ++ src/ir/Command.h | 18 +++ src/ir/IntegerVariable.cpp | 10 +- src/ir/IntegerVariable.h | 3 +- src/ir/Module.cpp | 47 +++++- src/ir/Module.h | 54 ++++++- src/ir/Program.cpp | 9 ++ src/ir/Program.h | 12 ++ src/ir/Update.cpp | 67 +++++++- src/ir/Update.h | 51 ++++++- src/ir/Variable.cpp | 12 +- src/ir/Variable.h | 14 +- src/ir/expressions/BaseExpression.h | 73 +++++++-- .../BinaryBooleanFunctionExpression.h | 57 ++++--- .../BinaryNumericalFunctionExpression.h | 51 +++++-- src/ir/expressions/BinaryRelationExpression.h | 30 +++- .../expressions/BooleanConstantExpression.h | 11 +- src/ir/expressions/BooleanLiteral.h | 8 +- src/ir/expressions/ConstantExpression.h | 8 +- src/ir/expressions/DoubleConstantExpression.h | 17 ++- src/ir/expressions/DoubleLiteral.h | 8 +- .../expressions/IntegerConstantExpression.h | 19 ++- src/ir/expressions/IntegerLiteral.h | 10 +- .../UnaryBooleanFunctionExpression.h | 23 ++- .../UnaryNumericalFunctionExpression.h | 40 ++++- src/ir/expressions/VariableExpression.h | 33 +++- src/parser/PrismParser.cpp | 50 +++--- src/storm.cpp | 4 +- test.input | 30 ++-- 34 files changed, 833 insertions(+), 152 deletions(-) create mode 100644 src/adapters/IntermediateRepresentationAdapter.h create mode 100644 src/exceptions/ExpressionEvaluationException.h create mode 100644 src/exceptions/NotImplementedException.h diff --git a/src/adapters/IntermediateRepresentationAdapter.h b/src/adapters/IntermediateRepresentationAdapter.h new file mode 100644 index 000000000..d60325b11 --- /dev/null +++ b/src/adapters/IntermediateRepresentationAdapter.h @@ -0,0 +1,144 @@ +/* + * IntermediateRepresentationAdapter.h + * + * Created on: 13.01.2013 + * Author: Christian Dehnert + */ + +#ifndef STORM_IR_INTERMEDIATEREPRESENTATIONADAPTER_H_ +#define STORM_IR_INTERMEDIATEREPRESENTATIONADAPTER_H_ + +#include +#include +#include +#include +#include +#include + +typedef std::pair, std::vector> StateType; + +namespace storm { + +namespace adapters { + +class StateHash { +public: + std::size_t operator()(StateType* state) const { + size_t seed = 0; + for (auto it = state->first.begin(); it != state->first.end(); ++it) { + boost::hash_combine(seed, *it); + } + for (auto it = state->second.begin(); it != state->second.end(); ++it) { + boost::hash_combine(seed, *it); + } + return seed; + } +}; + +class IntermediateRepresentationAdapter { +public: + template + static storm::storage::SquareSparseMatrix* toSparseMatrix(storm::ir::Program const& program) { + + uint_fast64_t numberOfIntegerVariables = 0; + uint_fast64_t numberOfBooleanVariables = 0; + for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { + numberOfIntegerVariables += program.getModule(i).getNumberOfIntegerVariables(); + numberOfBooleanVariables += program.getModule(i).getNumberOfBooleanVariables(); + } + + std::vector booleanVariables; + std::vector integerVariables; + booleanVariables.resize(numberOfBooleanVariables); + integerVariables.resize(numberOfIntegerVariables); + + std::unordered_map booleanVariableToIndexMap; + std::unordered_map integerVariableToIndexMap; + + uint_fast64_t nextBooleanVariableIndex = 0; + uint_fast64_t nextIntegerVariableIndex = 0; + for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { + storm::ir::Module const& module = program.getModule(i); + + for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { + booleanVariables[nextBooleanVariableIndex] = module.getBooleanVariable(j); + booleanVariableToIndexMap[module.getBooleanVariable(j).getName()] = nextBooleanVariableIndex; + ++nextBooleanVariableIndex; + } + for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) { + integerVariables[nextIntegerVariableIndex] = module.getIntegerVariable(j); + integerVariableToIndexMap[module.getIntegerVariable(j).getName()] = nextIntegerVariableIndex; + ++nextIntegerVariableIndex; + } + } + + StateType* initialState = new StateType(std::vector(), std::vector()); + std::get<0>(*initialState).resize(numberOfBooleanVariables); + std::get<1>(*initialState).resize(numberOfIntegerVariables); + + for (uint_fast64_t i = 0; i < numberOfBooleanVariables; ++i) { + bool initialValue = booleanVariables[i].getInitialValue()->getValueAsBool(std::get<0>(*initialState), std::get<1>(*initialState)); + std::get<0>(*initialState)[i] = initialValue; + } + + for (uint_fast64_t i = 0; i < numberOfIntegerVariables; ++i) { + int_fast64_t initialValue = integerVariables[i].getInitialValue()->getValueAsInt(std::get<0>(*initialState), std::get<1>(*initialState)); + std::get<1>(*initialState)[i] = initialValue; + } + + std::cout << "Initial State:" << std::get<0>(*initialState) << " / " << std::get<1>(*initialState) << std::endl; + + uint_fast64_t nextIndex = 1; + std::unordered_map stateToIndexMap; + std::vector allStates; + std::queue stateQueue; + + allStates.push_back(initialState); + stateQueue.push(initialState); + stateToIndexMap[initialState] = 0; + + while (!stateQueue.empty()) { + // Get first state in queue. + StateType* currentState = stateQueue.front(); + stateQueue.pop(); + + // Iterate over all modules. + for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { + storm::ir::Module const& module = program.getModule(i); + + // Iterate over all commands. + for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { + storm::ir::Command const& command = module.getCommand(j); + + // Check if this command is enabled in the current state. + if (command.getGuard()->getValueAsBool(std::get<0>(*currentState), std::get<1>(*currentState))) { + for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { + storm::ir::Update const& update = command.getUpdate(k); + + std::map const& booleanAssignmentMap = update.getBooleanAssignments(); + for (auto assignedVariable : booleanAssignmentMap) { + // Check if the variable that is being assigned is a boolean or an integer. + // auto boolIt = + + } + } + } + } + } + } + + // Now free all the elements we allocated. + for (auto element : allStates) { + delete element; + } + return nullptr; + } + +}; + +} + +} + + +#endif /* STORM_IR_INTERMEDIATEREPRESENTATIONADAPTER_H_ */ diff --git a/src/exceptions/ExpressionEvaluationException.h b/src/exceptions/ExpressionEvaluationException.h new file mode 100644 index 000000000..390991c1d --- /dev/null +++ b/src/exceptions/ExpressionEvaluationException.h @@ -0,0 +1,23 @@ +/* + * ExpressionEvaluationException.h + * + * Created on: 12.01.2013 + * Author: Christian Dehnert + */ + +#ifndef STORM_EXCEPTIONS_EXPRESSIONEVALUATIONEXCEPTION_H_ +#define STORM_EXCEPTIONS_EXPRESSIONEVALUATIONEXCEPTION_H_ + +#include "src/exceptions/BaseException.h" + +namespace storm { + +namespace exceptions { + +STORM_EXCEPTION_DEFINE_NEW(ExpressionEvaluationException) + +} + +} + +#endif /* STORM_EXCEPTIONS_EXPRESSIONEVALUATIONEXCEPTION_H_ */ diff --git a/src/exceptions/NotImplementedException.h b/src/exceptions/NotImplementedException.h new file mode 100644 index 000000000..cf98d4d99 --- /dev/null +++ b/src/exceptions/NotImplementedException.h @@ -0,0 +1,23 @@ +/* + * NotImplementedException.h + * + * Created on: 12.01.2013 + * Author: Christian Dehnert + */ + +#ifndef STORM_EXCEPTIONS_NOTIMPLEMENTEDEXCEPTION_H_ +#define STORM_EXCEPTIONS_NOTIMPLEMENTEDEXCEPTION_H_ + +#include "src/exceptions/BaseException.h" + +namespace storm { + +namespace exceptions { + +STORM_EXCEPTION_DEFINE_NEW(NotImplementedException) + +} + +} + +#endif /* STORM_EXCEPTIONS_NOTIMPLEMENTEDEXCEPTION_H_ */ diff --git a/src/ir/BooleanVariable.cpp b/src/ir/BooleanVariable.cpp index e524d6753..b867a1aa1 100644 --- a/src/ir/BooleanVariable.cpp +++ b/src/ir/BooleanVariable.cpp @@ -19,16 +19,16 @@ BooleanVariable::BooleanVariable() : Variable() { } // Initializes all members according to the given values. -BooleanVariable::BooleanVariable(std::string variableName, +BooleanVariable::BooleanVariable(uint_fast64_t index, std::string variableName, std::shared_ptr initialValue) - : Variable(variableName, initialValue) { + : Variable(index, variableName, initialValue) { // Nothing to do here. } // Build a string representation of the variable. std::string BooleanVariable::toString() const { std::stringstream result; - result << getVariableName() << ": bool"; + result << this->getName() << ": bool"; if (this->getInitialValue() != nullptr) { result << " init " << this->getInitialValue()->toString(); } diff --git a/src/ir/BooleanVariable.h b/src/ir/BooleanVariable.h index dc832399e..e12506b67 100644 --- a/src/ir/BooleanVariable.h +++ b/src/ir/BooleanVariable.h @@ -8,6 +8,8 @@ #ifndef STORM_IR_BOOLEANVARIABLE_H_ #define STORM_IR_BOOLEANVARIABLE_H_ +#include "expressions/BooleanLiteral.h" + #include "Variable.h" #include @@ -27,10 +29,11 @@ public: /*! * Creates a boolean variable with the given name and the given initial value. + * @param index a unique (among the variables of equal type) index for the variable. * @param variableName the name of the variable. * @param initialValue the expression that defines the initial value of the variable. */ - BooleanVariable(std::string variableName, std::shared_ptr initialValue = std::shared_ptr()); + BooleanVariable(uint_fast64_t index, std::string variableName, std::shared_ptr initialValue = std::shared_ptr(new storm::ir::expressions::BooleanLiteral(false))); /*! * Retrieves a string representation of this variable. diff --git a/src/ir/Command.cpp b/src/ir/Command.cpp index 832fbb302..5cb4c6354 100644 --- a/src/ir/Command.cpp +++ b/src/ir/Command.cpp @@ -24,6 +24,21 @@ Command::Command(std::string commandName, std::shared_ptr const& Command::getGuard() const { + return guardExpression; +} + +// Return the number of updates. +uint_fast64_t Command::getNumberOfUpdates() const { + return this->updates.size(); +} + +// Return the requested update. +storm::ir::Update const& Command::getUpdate(uint_fast64_t index) const { + return this->updates[index]; +} + // Build a string representation of the command. std::string Command::toString() const { std::stringstream result; diff --git a/src/ir/Command.h b/src/ir/Command.h index 186d81058..2ac54b525 100644 --- a/src/ir/Command.h +++ b/src/ir/Command.h @@ -35,6 +35,24 @@ public: */ Command(std::string commandName, std::shared_ptr guardExpression, std::vector updates); + /*! + * Retrieves a reference to the guard of the command. + * @returns a reference to the guard of the command. + */ + std::shared_ptr const& getGuard() const; + + /*! + * Retrieves the number of updates associated with this command. + * @returns the number of updates associated with this command. + */ + uint_fast64_t getNumberOfUpdates() const; + + /*! + * Retrieves a reference to the update with the given index. + * @returns a reference to the update with the given index. + */ + storm::ir::Update const& getUpdate(uint_fast64_t index) const; + /*! * Retrieves a string representation of this command. * @returns a string representation of this command. diff --git a/src/ir/IntegerVariable.cpp b/src/ir/IntegerVariable.cpp index 6b6724b1a..8374551a9 100644 --- a/src/ir/IntegerVariable.cpp +++ b/src/ir/IntegerVariable.cpp @@ -9,6 +9,8 @@ #include +#include + namespace storm { namespace ir { @@ -19,14 +21,16 @@ IntegerVariable::IntegerVariable() : lowerBound(), upperBound() { } // Initializes all members according to the given values. -IntegerVariable::IntegerVariable(std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue) : Variable(variableName, initialValue), lowerBound(lowerBound), upperBound(upperBound) { - // Nothing to do here. +IntegerVariable::IntegerVariable(uint_fast64_t index, std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue) : Variable(index, variableName, initialValue), lowerBound(lowerBound), upperBound(upperBound) { + if (this->getInitialValue() == nullptr) { + this->setInitialValue(lowerBound); + } } // Build a string representation of the variable. std::string IntegerVariable::toString() const { std::stringstream result; - result << this->getVariableName() << ": [" << lowerBound->toString() << ".." << upperBound->toString() << "]"; + result << this->getName() << ": [" << lowerBound->toString() << ".." << upperBound->toString() << "]"; if (this->getInitialValue() != nullptr) { result << " init " + this->getInitialValue()->toString(); } diff --git a/src/ir/IntegerVariable.h b/src/ir/IntegerVariable.h index d687e2a04..86e2dfc1b 100644 --- a/src/ir/IntegerVariable.h +++ b/src/ir/IntegerVariable.h @@ -29,12 +29,13 @@ public: /*! * Creates an integer variable with the given name, lower and upper bounds and the given initial * value. + * @param index A unique (among the variables of equal type) index for the variable. * @param variableName the name of the variable. * @param lowerBound the lower bound of the domain of the variable. * @param upperBound the upper bound of the domain of the variable. * @param initialValue the expression that defines the initial value of the variable. */ - IntegerVariable(std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue = std::shared_ptr()); + IntegerVariable(uint_fast64_t index, std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue = std::shared_ptr(nullptr)); /*! * Retrieves a string representation of this variable. diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index 5f28a8d13..f76a53b88 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -14,25 +14,62 @@ namespace storm { namespace ir { // Initializes all members with their default constructors. -Module::Module() : moduleName(), booleanVariables(), integerVariables(), commands() { +Module::Module() : moduleName(), booleanVariables(), integerVariables(), booleanVariablesToIndexMap(), + integerVariablesToIndexMap(), commands() { // Nothing to do here. } // Initializes all members according to the given values. -Module::Module(std::string moduleName, std::map booleanVariables, std::map integerVariables, std::vector commands) - : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), commands(commands) { +Module::Module(std::string moduleName, std::vector booleanVariables, + std::vector integerVariables, + std::map booleanVariableToIndexMap, + std::map integerVariableToIndexMap, + std::vector commands) + : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), + booleanVariablesToIndexMap(booleanVariableToIndexMap), + integerVariablesToIndexMap(integerVariableToIndexMap), commands(commands) { // Nothing to do here. } +// Return the number of boolean variables. +uint_fast64_t Module::getNumberOfBooleanVariables() const { + return this->booleanVariables.size(); +} + +// Return the requested boolean variable. +storm::ir::BooleanVariable const& Module::getBooleanVariable(uint_fast64_t index) const { + return this->booleanVariables[index]; +} + +// Return the number of integer variables. +uint_fast64_t Module::getNumberOfIntegerVariables() const { + return this->integerVariables.size(); +} + +// Return the requested integer variable. +storm::ir::IntegerVariable const& Module::getIntegerVariable(uint_fast64_t index) const { + return this->integerVariables[index]; +} + +// Return the number of commands. +uint_fast64_t Module::getNumberOfCommands() const { + return this->commands.size(); +} + +// Return the requested command. +storm::ir::Command const& Module::getCommand(uint_fast64_t index) const { + return this->commands[index]; +} + // Build a string representation of the variable. std::string Module::toString() const { std::stringstream result; result << "module " << moduleName << std::endl; for (auto variable : booleanVariables) { - result << "\t" << variable.second.toString() << std::endl; + result << "\t" << variable.toString() << std::endl; } for (auto variable : integerVariables) { - result << "\t" << variable.second.toString() << std::endl; + result << "\t" << variable.toString() << std::endl; } for (auto command : commands) { result << "\t" << command.toString() << std::endl; diff --git a/src/ir/Module.h b/src/ir/Module.h index ad0218730..0ed2ed010 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -37,7 +37,47 @@ public: * @param integerVariables a map of integer variables. * @param commands the vector of commands. */ - Module(std::string moduleName, std::map booleanVariables, std::map integerVariables, std::vector commands); + Module(std::string moduleName, std::vector booleanVariables, + std::vector integerVariables, + std::map booleanVariableToIndexMap, + std::map integerVariableToIndexMap, + std::vector commands); + + /*! + * Retrieves the number of boolean variables in the module. + * @returns the number of boolean variables in the module. + */ + uint_fast64_t getNumberOfBooleanVariables() const; + + /*! + * Retrieves a reference to the boolean variable with the given index. + * @returns a reference to the boolean variable with the given index. + */ + storm::ir::BooleanVariable const& getBooleanVariable(uint_fast64_t index) const; + + /*! + * Retrieves the number of integer variables in the module. + * @returns the number of integer variables in the module. + */ + uint_fast64_t getNumberOfIntegerVariables() const; + + /*! + * Retrieves a reference to the integer variable with the given index. + * @returns a reference to the integer variable with the given index. + */ + storm::ir::IntegerVariable const& getIntegerVariable(uint_fast64_t index) const; + + /*! + * Retrieves the number of commands of this module. + * @returns the number of commands of this module. + */ + uint_fast64_t getNumberOfCommands() const; + + /*! + * Retrieves a reference to the command with the given index. + * @returns a reference to the command with the given index. + */ + storm::ir::Command const& getCommand(uint_fast64_t index) const; /*! * Retrieves a string representation of this variable. @@ -49,11 +89,17 @@ private: // The name of the module. std::string moduleName; - // A map of boolean variable names to their details. - std::map booleanVariables; + // A list of boolean variables. + std::vector booleanVariables; + + // A list of integer variables. + std::vector integerVariables; + + // A map of boolean variable names to their index. + std::map booleanVariablesToIndexMap; // A map of integer variable names to their details. - std::map integerVariables; + std::map integerVariablesToIndexMap; // The commands associated with the module. std::vector commands; diff --git a/src/ir/Program.cpp b/src/ir/Program.cpp index 5a250405e..e5dfa9ce3 100644 --- a/src/ir/Program.cpp +++ b/src/ir/Program.cpp @@ -62,6 +62,15 @@ std::string Program::toString() const { return result.str(); } +uint_fast64_t Program::getNumberOfModules() const { + return this->modules.size(); +} + +storm::ir::Module const& Program::getModule(uint_fast64_t index) const { + return this->modules[index]; +} + + } // namespace ir } // namepsace storm diff --git a/src/ir/Program.h b/src/ir/Program.h index 8fcd7c10f..8ea9b5b11 100644 --- a/src/ir/Program.h +++ b/src/ir/Program.h @@ -54,6 +54,18 @@ public: */ Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector modules, std::map rewards, std::map> labels); + /*! + * Retrieves the number of modules in the program. + * @returns the number of modules in the program. + */ + uint_fast64_t getNumberOfModules() const; + + /*! + * Retrieves a reference to the module with the given index. + * @param index the index of the module to retrieve. + */ + storm::ir::Module const& getModule(uint_fast64_t index) const; + /*! * Retrieves a string representation of this program. * @returns a string representation of this program. diff --git a/src/ir/Update.cpp b/src/ir/Update.cpp index 4e59d46be..668b543da 100644 --- a/src/ir/Update.cpp +++ b/src/ir/Update.cpp @@ -7,6 +7,8 @@ #include "Update.h" +#include "src/exceptions/OutOfRangeException.h" + #include namespace storm { @@ -14,28 +16,81 @@ namespace storm { namespace ir { // Initializes all members with their default constructors. -Update::Update() : likelihoodExpression(), assignments() { +Update::Update() : likelihoodExpression(), booleanAssignments(), integerAssignments() { // Nothing to do here. } // Initializes all members according to the given values. -Update::Update(std::shared_ptr likelihoodExpression, std::map assignments) - : likelihoodExpression(likelihoodExpression), assignments(assignments) { +Update::Update(std::shared_ptr likelihoodExpression, std::map booleanAssignments, std::map integerAssignments) + : likelihoodExpression(likelihoodExpression), booleanAssignments(booleanAssignments), integerAssignments(integerAssignments) { // Nothing to do here. } +// Return the expression for the likelihood of the update. +std::shared_ptr const& Update::getLikelihoodExpression() const { + return likelihoodExpression; +} + +// Return the number of assignments. +uint_fast64_t Update::getNumberOfBooleanAssignments() const { + return booleanAssignments.size(); +} + +uint_fast64_t Update::getNumberOfIntegerAssignments() const { + return integerAssignments.size(); +} + +// Return the boolean variable name to assignment map. +std::map const& Update::getBooleanAssignments() const { + return booleanAssignments; +} + +// Return the integer variable name to assignment map. +std::map const& Update::getIntegerAssignments() const { + return integerAssignments; +} + +// Return the assignment for the boolean variable if it exists and throw an exception otherwise. +storm::ir::Assignment const& Update::getBooleanAssignment(std::string variableName) const { + auto it = booleanAssignments.find(variableName); + if (it == booleanAssignments.end()) { + throw storm::exceptions::OutOfRangeException() << "Cannot find boolean assignment for variable '" + << variableName << "' in update " << this->toString() << "."; + } + + return (*it).second; +} + +// Return the assignment for the boolean variable if it exists and throw an exception otherwise. +storm::ir::Assignment const& Update::getIntegerAssignment(std::string variableName) const { + auto it = integerAssignments.find(variableName); + if (it == integerAssignments.end()) { + throw storm::exceptions::OutOfRangeException() << "Cannot find integer assignment for variable '" + << variableName << "' in update " << this->toString() << "."; + } + + return (*it).second; +} + // Build a string representation of the update. std::string Update::toString() const { std::stringstream result; result << likelihoodExpression->toString() << " : "; uint_fast64_t i = 0; - for (auto assignment : assignments) { + for (auto assignment : booleanAssignments) { result << assignment.second.toString(); ++i; - if (i < assignments.size() - 1) { + if (i < booleanAssignments.size() - 1 || integerAssignments.size() > 0) { + result << " & "; + } + } + i = 0; + for (auto assignment : integerAssignments) { + result << assignment.second.toString(); + ++i; + if (i < integerAssignments.size() - 1) { result << " & "; } - } return result.str(); } diff --git a/src/ir/Update.h b/src/ir/Update.h index 1aeb1d125..54ddc5cd8 100644 --- a/src/ir/Update.h +++ b/src/ir/Update.h @@ -34,7 +34,49 @@ public: * @param likelihoodExpression an expression specifying the likelihood of this update. * @param assignments a map of variable names to their assignments. */ - Update(std::shared_ptr likelihoodExpression, std::map assignments); + Update(std::shared_ptr likelihoodExpression, std::map booleanAssignments, std::map integerAssignments); + + /*! + * Retrieves the expression for the likelihood of this update. + * @returns the expression for the likelihood of this update. + */ + std::shared_ptr const& getLikelihoodExpression() const; + + /*! + * Retrieves the number of boolean assignments associated with this update. + * @returns the number of boolean assignments associated with this update. + */ + uint_fast64_t getNumberOfBooleanAssignments() const; + + /*! + * Retrieves the number of integer assignments associated with this update. + * @returns the number of integer assignments associated with this update. + */ + uint_fast64_t getNumberOfIntegerAssignments() const; + + /*! + * Retrieves a reference to the map of boolean variable names to their respective assignments. + * @returns a reference to the map of boolean variable names to their respective assignments. + */ + std::map const& getBooleanAssignments() const; + + /*! + * Retrieves a reference to the map of integer variable names to their respective assignments. + * @returns a reference to the map of integer variable names to their respective assignments. + */ + std::map const& getIntegerAssignments() const; + + /*! + * Retrieves a reference to the assignment for the boolean variable with the given name. + * @returns a reference to the assignment for the boolean variable with the given name. + */ + storm::ir::Assignment const& getBooleanAssignment(std::string variableName) const; + + /*! + * Retrieves a reference to the assignment for the integer variable with the given name. + * @returns a reference to the assignment for the integer variable with the given name. + */ + storm::ir::Assignment const& getIntegerAssignment(std::string variableName) const; /*! * Retrieves a string representation of this update. @@ -46,8 +88,11 @@ private: // An expression specifying the likelihood of taking this update. std::shared_ptr likelihoodExpression; - // A mapping of variable names to their assignments in this update. - std::map assignments; + // A mapping of boolean variable names to their assignments in this update. + std::map booleanAssignments; + + // A mapping of integer variable names to their assignments in this update. + std::map integerAssignments; }; } // namespace ir diff --git a/src/ir/Variable.cpp b/src/ir/Variable.cpp index a735fa94d..d051b9ca1 100644 --- a/src/ir/Variable.cpp +++ b/src/ir/Variable.cpp @@ -14,17 +14,17 @@ namespace storm { namespace ir { // Initializes all members with their default constructors. -Variable::Variable() : variableName(), initialValue() { +Variable::Variable() : index(0), variableName(), initialValue() { // Nothing to do here. } // Initializes all members according to the given values. -Variable::Variable(std::string variableName, std::shared_ptr initialValue) : variableName(variableName), initialValue(initialValue) { +Variable::Variable(uint_fast64_t index, std::string variableName, std::shared_ptr initialValue) : index(index), variableName(variableName), initialValue(initialValue) { // Nothing to do here. } // Return the name of the variable. -std::string const& Variable::getVariableName() const { +std::string const& Variable::getName() const { return variableName; } @@ -33,6 +33,12 @@ std::shared_ptr const& Variable::getInit return initialValue; } +// Set the initial value expression to the one provided. +void Variable::setInitialValue(std::shared_ptr const& initialValue) { + this->initialValue = initialValue; +} + + } // namespace ir } // namespace storm diff --git a/src/ir/Variable.h b/src/ir/Variable.h index bbd567073..eed1e538c 100644 --- a/src/ir/Variable.h +++ b/src/ir/Variable.h @@ -28,16 +28,17 @@ public: /*! * Creates an untyped variable with the given name and initial value. + * @param index A unique (among the variables of equal type) index for the variable. * @param variableName the name of the variable. * @param initialValue the expression that defines the initial value of the variable. */ - Variable(std::string variableName, std::shared_ptr initialValue = std::shared_ptr()); + Variable(uint_fast64_t index, std::string variableName, std::shared_ptr initialValue = std::shared_ptr()); /*! * Retrieves the name of the variable. * @returns the name of the variable. */ - std::string const& getVariableName() const; + std::string const& getName() const; /*! * Retrieves the expression defining the initial value of the variable. @@ -45,7 +46,16 @@ public: */ std::shared_ptr const& getInitialValue() const; + /*! + * Sets the initial value to the given expression. + * @param initialValue the new initial value. + */ + void setInitialValue(std::shared_ptr const& initialValue); + private: + // A unique (among the variables of equal type) index for the variable + uint_fast64_t index; + // The name of the variable. std::string variableName; diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h index f2d848fb7..b88953dce 100644 --- a/src/ir/expressions/BaseExpression.h +++ b/src/ir/expressions/BaseExpression.h @@ -2,13 +2,17 @@ * Expression.h * * Created on: 03.01.2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef EXPRESSION_H_ -#define EXPRESSION_H_ +#ifndef STORM_IR_EXPRESSIONS_BASEEXPRESSION_H_ +#define STORM_IR_EXPRESSIONS_BASEEXPRESSION_H_ + +#include "src/exceptions/ExpressionEvaluationException.h" +#include "src/exceptions/NotImplementedException.h" #include +#include namespace storm { @@ -19,19 +23,70 @@ namespace expressions { class BaseExpression { public: + enum ReturnType {undefined, bool_, int_, double_}; + + BaseExpression() : type(undefined) { + + } + + BaseExpression(ReturnType type) : type(type) { + + } + virtual ~BaseExpression() { } - virtual std::string toString() const { - return "expr here!"; + virtual int_fast64_t getValueAsInt(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + if (type != int_) { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '" + << this->getTypeName() << "' as 'int'."; + } + throw storm::exceptions::NotImplementedException() << "Cannot evaluate expression of type '" + << this->getTypeName() << " because evaluation implementation is missing."; + } + + virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + if (type != bool_) { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '" + << this->getTypeName() << "' as 'bool'."; + } + throw storm::exceptions::NotImplementedException() << "Cannot evaluate expression of type '" + << this->getTypeName() << " because evaluation implementation is missing."; + } + + virtual double getValueAsDouble(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + if (type != bool_) { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '" + << this->getTypeName() << "' as 'double'."; + } + throw storm::exceptions::NotImplementedException() << "Cannot evaluate expression of type '" + << this->getTypeName() << " because evaluation implementation is missing."; } + + virtual std::string toString() const = 0; + + std::string getTypeName() const { + switch(type) { + case bool_: return std::string("bool"); + case int_: return std::string("int"); + case double_: return std::string("double"); + default: return std::string("undefined"); + } + } + + ReturnType getType() const { + return type; + } + +private: + ReturnType type; }; -} +} // namespace expressions -} +} // namespace ir -} +} // namespace storm -#endif /* EXPRESSION_H_ */ +#endif /* STORM_IR_EXPRESSIONS_BASEEXPRESSION_H_ */ diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.h b/src/ir/expressions/BinaryBooleanFunctionExpression.h index bd388dc04..e26bd22f3 100644 --- a/src/ir/expressions/BinaryBooleanFunctionExpression.h +++ b/src/ir/expressions/BinaryBooleanFunctionExpression.h @@ -5,11 +5,13 @@ * Author: chris */ -#ifndef BINARYBOOLEANFUNCTIONEXPRESSION_H_ -#define BINARYBOOLEANFUNCTIONEXPRESSION_H_ +#ifndef STORM_IR_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_ +#define STORM_IR_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_ #include "src/ir/expressions/BaseExpression.h" -#include + +#include +#include namespace storm { @@ -19,38 +21,49 @@ namespace expressions { class BinaryBooleanFunctionExpression : public BaseExpression { public: - enum FunctorType {AND, OR, XOR, IMPLIES} functor; - std::shared_ptr left; - std::shared_ptr right; + enum FunctionType {AND, OR}; + + BinaryBooleanFunctionExpression(std::shared_ptr left, std::shared_ptr right, FunctionType functionType) : BaseExpression(bool_), left(left), right(right), functionType(functionType) { - BinaryBooleanFunctionExpression(std::shared_ptr left, std::shared_ptr right, FunctorType functor) { - this->left = left; - this->right = right; - this->functor = functor; } virtual ~BinaryBooleanFunctionExpression() { } + virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + bool resultLeft = left->getValueAsBool(booleanVariableValues, integerVariableValues); + bool resultRight = right->getValueAsBool(booleanVariableValues, integerVariableValues); + switch(functionType) { + case AND: return resultLeft & resultRight; break; + case OR: return resultLeft | resultRight; break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown boolean binary operator: '" << functionType << "'."; + } + } + virtual std::string toString() const { - std::string result = left->toString(); - switch (functor) { - case AND: result += " & "; break; - case OR: result += " | "; break; - case XOR: result += " ^ "; break; - case IMPLIES: result += " => "; break; + std::stringstream result; + result << left->toString(); + switch (functionType) { + case AND: result << " & "; break; + case OR: result << " | "; break; } - result += right->toString(); + result << right->toString(); - return result; + return result.str(); } + +private: + std::shared_ptr left; + std::shared_ptr right; + FunctionType functionType; }; -} +} // namespace expressions -} +} // namespace ir -} +} // namespace storm -#endif /* BINARYBOOLEANFUNCTIONEXPRESSION_H_ */ +#endif /* STORM_IR_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_ */ diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h index 5b928768e..28ba2b3f2 100644 --- a/src/ir/expressions/BinaryNumericalFunctionExpression.h +++ b/src/ir/expressions/BinaryNumericalFunctionExpression.h @@ -18,23 +18,53 @@ namespace expressions { class BinaryNumericalFunctionExpression : public BaseExpression { public: - std::shared_ptr left; - std::shared_ptr right; - enum FunctorType {PLUS, MINUS, TIMES, DIVIDE} functor; + enum FunctionType {PLUS, MINUS, TIMES, DIVIDE}; + + BinaryNumericalFunctionExpression(ReturnType type, std::shared_ptr left, std::shared_ptr right, FunctionType functionType) : BaseExpression(type), left(left), right(right), functionType(functionType) { - BinaryNumericalFunctionExpression(std::shared_ptr left, std::shared_ptr right, FunctorType functor) { - this->left = left; - this->right = right; - this->functor = functor; } virtual ~BinaryNumericalFunctionExpression() { } + virtual int_fast64_t getValueAsInt(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + if (this->getType() != int_) { + BaseExpression::getValueAsInt(booleanVariableValues, integerVariableValues); + } + + int_fast64_t resultLeft = left->getValueAsInt(booleanVariableValues, integerVariableValues); + int_fast64_t resultRight = right->getValueAsInt(booleanVariableValues, integerVariableValues); + switch(functionType) { + case PLUS: return resultLeft + resultRight; break; + case MINUS: return resultLeft - resultRight; break; + case TIMES: return resultLeft * resultRight; break; + case DIVIDE: return resultLeft / resultRight; break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown numeric binary operator: '" << functionType << "'."; + } + } + + virtual double getValueAsDouble(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + if (this->getType() != double_) { + BaseExpression::getValueAsDouble(booleanVariableValues, integerVariableValues); + } + + double resultLeft = left->getValueAsDouble(booleanVariableValues, integerVariableValues); + double resultRight = right->getValueAsDouble(booleanVariableValues, integerVariableValues); + switch(functionType) { + case PLUS: return resultLeft + resultRight; break; + case MINUS: return resultLeft - resultRight; break; + case TIMES: return resultLeft * resultRight; break; + case DIVIDE: return resultLeft / resultRight; break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown numeric binary operator: '" << functionType << "'."; + } + } + virtual std::string toString() const { std::string result = left->toString(); - switch (functor) { + switch (functionType) { case PLUS: result += " + "; break; case MINUS: result += " - "; break; case TIMES: result += " * "; break; @@ -44,7 +74,10 @@ public: return result; } - +private: + std::shared_ptr left; + std::shared_ptr right; + FunctionType functionType; }; } diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h index 625b801f5..db834ea93 100644 --- a/src/ir/expressions/BinaryRelationExpression.h +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -18,23 +18,33 @@ namespace expressions { class BinaryRelationExpression : public BaseExpression { public: - std::shared_ptr left; - std::shared_ptr right; - enum RelationType {EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL} relation; + enum RelationType {EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL}; + + BinaryRelationExpression(std::shared_ptr left, std::shared_ptr right, RelationType relationType) : BaseExpression(bool_), left(left), right(right), relationType(relationType) { - BinaryRelationExpression(std::shared_ptr left, std::shared_ptr right, RelationType relation) { - this->left = left; - this->right = right; - this->relation = relation; } virtual ~BinaryRelationExpression() { } + virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + int_fast64_t resultLeft = left->getValueAsInt(booleanVariableValues, integerVariableValues); + int_fast64_t resultRight = right->getValueAsInt(booleanVariableValues, integerVariableValues); + switch(relationType) { + case EQUAL: return resultLeft == resultRight; break; + case LESS: return resultLeft < resultRight; break; + case LESS_OR_EQUAL: return resultLeft <= resultRight; break; + case GREATER: return resultLeft > resultRight; break; + case GREATER_OR_EQUAL: return resultLeft >= resultRight; break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown boolean binary relation: '" << relationType << "'."; + } + } + virtual std::string toString() const { std::string result = left->toString(); - switch (relation) { + switch (relationType) { case EQUAL: result += " = "; break; case LESS: result += " < "; break; case LESS_OR_EQUAL: result += " <= "; break; @@ -46,6 +56,10 @@ public: return result; } +private: + std::shared_ptr left; + std::shared_ptr right; + RelationType relationType; }; } diff --git a/src/ir/expressions/BooleanConstantExpression.h b/src/ir/expressions/BooleanConstantExpression.h index a10c2363e..cfd6ae418 100644 --- a/src/ir/expressions/BooleanConstantExpression.h +++ b/src/ir/expressions/BooleanConstantExpression.h @@ -20,7 +20,7 @@ namespace expressions { class BooleanConstantExpression : public ConstantExpression { public: - BooleanConstantExpression(std::string constantName) : ConstantExpression(constantName) { + BooleanConstantExpression(std::string constantName) : ConstantExpression(bool_, constantName) { defined = false; value = false; } @@ -29,6 +29,15 @@ public: } + virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + if (!defined) { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Boolean constant '" << this->getConstantName() << "' is undefined."; + } else { + return value; + } + } + virtual std::string toString() const { std::string result = this->constantName; if (defined) { diff --git a/src/ir/expressions/BooleanLiteral.h b/src/ir/expressions/BooleanLiteral.h index 81950e52a..f7d4e9957 100644 --- a/src/ir/expressions/BooleanLiteral.h +++ b/src/ir/expressions/BooleanLiteral.h @@ -20,14 +20,18 @@ class BooleanLiteral : public BaseExpression { public: bool value; - BooleanLiteral(bool value) { - this->value = value; + BooleanLiteral(bool value) : BaseExpression(bool_), value(value) { + } virtual ~BooleanLiteral() { } + virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + return value; + } + virtual std::string toString() const { if (value) { return std::string("true"); diff --git a/src/ir/expressions/ConstantExpression.h b/src/ir/expressions/ConstantExpression.h index 239b3dc68..79c356dba 100644 --- a/src/ir/expressions/ConstantExpression.h +++ b/src/ir/expressions/ConstantExpression.h @@ -20,14 +20,18 @@ class ConstantExpression : public BaseExpression { public: std::string constantName; - ConstantExpression(std::string constantName) { - this->constantName = constantName; + ConstantExpression(ReturnType type, std::string constantName) : BaseExpression(type), constantName(constantName) { + } virtual ~ConstantExpression() { } + std::string const& getConstantName() const { + return constantName; + } + virtual std::string toString() const { return constantName; } diff --git a/src/ir/expressions/DoubleConstantExpression.h b/src/ir/expressions/DoubleConstantExpression.h index 3a7363a65..9ad1e61d6 100644 --- a/src/ir/expressions/DoubleConstantExpression.h +++ b/src/ir/expressions/DoubleConstantExpression.h @@ -18,15 +18,23 @@ namespace expressions { class DoubleConstantExpression : public ConstantExpression { public: - DoubleConstantExpression(std::string constantName) : ConstantExpression(constantName) { - defined = false; - value = 0.0; + DoubleConstantExpression(std::string constantName) : ConstantExpression(double_, constantName), defined(false), value(0) { + } virtual ~DoubleConstantExpression() { } + virtual double getValueAsDouble(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + if (!defined) { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Double constant '" << this->getConstantName() << "' is undefined."; + } else { + return value; + } + } + virtual std::string toString() const { std::string result = this->constantName; if (defined) { @@ -48,8 +56,9 @@ public: this->value = value; } - double value; +private: bool defined; + double value; }; } diff --git a/src/ir/expressions/DoubleLiteral.h b/src/ir/expressions/DoubleLiteral.h index dbdcf55ca..e7854cfa5 100644 --- a/src/ir/expressions/DoubleLiteral.h +++ b/src/ir/expressions/DoubleLiteral.h @@ -22,14 +22,18 @@ class DoubleLiteral : public BaseExpression { public: double value; - DoubleLiteral(double value) { - this->value = value; + DoubleLiteral(double value) : BaseExpression(double_), value(value) { + } virtual ~DoubleLiteral() { } + virtual double getValueAsDouble(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + return value; + } + virtual std::string toString() const { return boost::lexical_cast(value); } diff --git a/src/ir/expressions/IntegerConstantExpression.h b/src/ir/expressions/IntegerConstantExpression.h index 5ff4d7f87..5e7c46ee7 100644 --- a/src/ir/expressions/IntegerConstantExpression.h +++ b/src/ir/expressions/IntegerConstantExpression.h @@ -18,15 +18,23 @@ namespace expressions { class IntegerConstantExpression : public ConstantExpression { public: - IntegerConstantExpression(std::string constantName) : ConstantExpression(constantName) { - defined = false; - value = 0; + IntegerConstantExpression(std::string constantName) : ConstantExpression(int_, constantName), defined(false), value(0) { + } virtual ~IntegerConstantExpression() { } + virtual int_fast64_t getValueAsInt(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + if (!defined) { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Integer constant '" << this->getConstantName() << "' is undefined."; + } else { + return value; + } + } + virtual std::string toString() const { std::string result = this->constantName; if (defined) { @@ -43,13 +51,14 @@ public: return value; } - void define(int value) { + void define(int_fast64_t value) { defined = true; this->value = value; } - int value; +private: bool defined; + int_fast64_t value; }; } diff --git a/src/ir/expressions/IntegerLiteral.h b/src/ir/expressions/IntegerLiteral.h index aef509321..36c78a948 100644 --- a/src/ir/expressions/IntegerLiteral.h +++ b/src/ir/expressions/IntegerLiteral.h @@ -18,16 +18,20 @@ namespace expressions { class IntegerLiteral : public BaseExpression { public: - int value; + int_fast64_t value; + + IntegerLiteral(int_fast64_t value) : BaseExpression(int_), value(value) { - IntegerLiteral(int value) { - this->value = value; } virtual ~IntegerLiteral() { } + virtual int_fast64_t getValueAsInt(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + return value; + } + virtual std::string toString() const { return boost::lexical_cast(value); } diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.h b/src/ir/expressions/UnaryBooleanFunctionExpression.h index 893169b51..b21a70f87 100644 --- a/src/ir/expressions/UnaryBooleanFunctionExpression.h +++ b/src/ir/expressions/UnaryBooleanFunctionExpression.h @@ -18,27 +18,38 @@ namespace expressions { class UnaryBooleanFunctionExpression : public BaseExpression { public: - std::shared_ptr child; - enum FunctorType {NOT} functor; + enum FunctionType {NOT}; + + UnaryBooleanFunctionExpression(std::shared_ptr child, FunctionType functionType) : BaseExpression(bool_), child(child), functionType(functionType) { - UnaryBooleanFunctionExpression(std::shared_ptr child, FunctorType functor) { - this->child = child; - this->functor = functor; } virtual ~UnaryBooleanFunctionExpression() { } + virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + bool resultChild = child->getValueAsBool(booleanVariableValues, integerVariableValues); + switch(functionType) { + case NOT: return !resultChild; break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown boolean unary operator: '" << functionType << "'."; + } + } + virtual std::string toString() const { std::string result = ""; - switch (functor) { + switch (functionType) { case NOT: result += "!"; break; } result += child->toString(); return result; } + +private: + std::shared_ptr child; + FunctionType functionType; }; } diff --git a/src/ir/expressions/UnaryNumericalFunctionExpression.h b/src/ir/expressions/UnaryNumericalFunctionExpression.h index f697f35eb..db5cb2945 100644 --- a/src/ir/expressions/UnaryNumericalFunctionExpression.h +++ b/src/ir/expressions/UnaryNumericalFunctionExpression.h @@ -18,27 +18,55 @@ namespace expressions { class UnaryNumericalFunctionExpression : public BaseExpression { public: - std::shared_ptr child; - enum FunctorType {MINUS} functor; + enum FunctionType {MINUS}; + + UnaryNumericalFunctionExpression(ReturnType type, std::shared_ptr child, FunctionType functionType) : BaseExpression(type), child(child), functionType(functionType) { - UnaryNumericalFunctionExpression(std::shared_ptr child, FunctorType functor) { - this->child = child; - this->functor = functor; } virtual ~UnaryNumericalFunctionExpression() { } + virtual int_fast64_t getValueAsInt(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + if (this->getType() != int_) { + BaseExpression::getValueAsInt(booleanVariableValues, integerVariableValues); + } + + int_fast64_t resultChild = child->getValueAsInt(booleanVariableValues, integerVariableValues); + switch(functionType) { + case MINUS: return -resultChild; break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown numerical unary operator: '" << functionType << "'."; + } + } + + virtual double getValueAsDouble(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + if (this->getType() != double_) { + BaseExpression::getValueAsDouble(booleanVariableValues, integerVariableValues); + } + + double resultChild = child->getValueAsDouble(booleanVariableValues, integerVariableValues); + switch(functionType) { + case MINUS: return -resultChild; break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown numerical unary operator: '" << functionType << "'."; + } + } + virtual std::string toString() const { std::string result = ""; - switch (functor) { + switch (functionType) { case MINUS: result += "-"; break; } result += child->toString(); return result; } + +private: + std::shared_ptr child; + FunctionType functionType; }; } diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index a6a27fa43..02ca79a36 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -20,9 +20,7 @@ namespace expressions { class VariableExpression : public BaseExpression { public: - std::string variableName; - - VariableExpression(std::string variableName) : variableName(variableName) { + VariableExpression(ReturnType type, uint_fast64_t index, std::string variableName) : BaseExpression(type), index(index), variableName(variableName) { } @@ -33,6 +31,35 @@ public: virtual std::string toString() const { return variableName; } + + virtual int_fast64_t getValueAsInt(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + if (this->getType() != int_) { + BaseExpression::getValueAsInt(booleanVariableValues, integerVariableValues); + } + + return integerVariableValues[index]; + } + + virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + if (this->getType() != bool_) { + BaseExpression::getValueAsBool(booleanVariableValues, integerVariableValues); + } + + return booleanVariableValues[index]; + } + + virtual double getValueAsDouble(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + if (this->getType() != double_) { + BaseExpression::getValueAsDouble(booleanVariableValues, integerVariableValues); + } + + throw storm::exceptions::NotImplementedException() << "Cannot evaluate expression with " + << " variable '" << variableName << "' of type double."; + } + +private: + uint_fast64_t index; + std::string variableName; }; } diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 96ae88ca7..fe6c4fd8e 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -51,7 +51,7 @@ struct PrismParser::PrismGrammar : qi::grammar> *(qi::alnum | qi::char_('_'))) - booleanVariableNames_ - integerVariableNames_ - allConstantNames_ - labelNames_ - moduleNames_ - keywords_]]; freeIdentifierName.name("unused identifier"); @@ -87,9 +87,9 @@ struct PrismParser::PrismGrammar : qi::grammar> integerExpression >> qi::lit(")") | integerConstantExpression); atomicIntegerExpression.name("integer expression"); - integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; integerMultExpression.name("integer expression"); - integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> integerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> integerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; integerPlusExpression.name("integer expression"); integerExpression %= integerPlusExpression; integerExpression.name("integer expression"); @@ -97,9 +97,9 @@ struct PrismParser::PrismGrammar : qi::grammar> constantIntegerExpression >> qi::lit(")") | integerConstantExpression); constantAtomicIntegerExpression.name("constant integer expression"); - constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; constantIntegerMultExpression.name("constant integer expression"); - constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantIntegerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantIntegerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; constantIntegerPlusExpression.name("constant integer expression"); constantIntegerExpression %= constantIntegerPlusExpression; constantIntegerExpression.name("constant integer expression"); @@ -107,9 +107,9 @@ struct PrismParser::PrismGrammar : qi::grammar> constantDoubleExpression >> qi::lit(")") | doubleConstantExpression); constantAtomicDoubleExpression.name("constant double expression"); - constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicDoubleExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicDoubleExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::double_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; constantDoubleMultExpression.name("constant double expression"); - constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantDoubleMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantDoubleMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::double_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; constantDoublePlusExpression.name("constant double expression"); constantDoubleExpression %= constantDoublePlusExpression; constantDoubleExpression.name("constant double expression"); @@ -119,7 +119,7 @@ struct PrismParser::PrismGrammar : qi::grammar> booleanExpression >> qi::lit(")") | booleanConstantExpression); atomicBooleanExpression.name("boolean expression"); - notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType::NOT))]; + notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::NOT))]; notExpression.name("boolean expression"); andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; andExpression.name("boolean expression"); @@ -133,7 +133,7 @@ struct PrismParser::PrismGrammar : qi::grammar> constantBooleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression); constantAtomicBooleanExpression.name("constant boolean expression"); - constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType::NOT))]; + constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::NOT))]; constantNotExpression.name("constant boolean expression"); constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; constantAndExpression.name("constant boolean expression"); @@ -175,11 +175,11 @@ struct PrismParser::PrismGrammar : qi::grammar> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > integerExpression > qi::lit(")"))[phoenix::bind(assignedLocalIntegerVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))] | (qi::lit("(") > unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > booleanExpression > qi::lit(")"))[phoenix::bind(assignedLocalBooleanVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))]; + assignmentDefinition = (qi::lit("(") >> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > integerExpression > qi::lit(")"))[phoenix::bind(assignedLocalIntegerVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))] | (qi::lit("(") > unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > booleanExpression > qi::lit(")"))[phoenix::bind(assignedLocalBooleanVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))]; assignmentDefinition.name("assignment"); - assignmentDefinitionList = assignmentDefinition(qi::_r1) % "&"; + assignmentDefinitionList = assignmentDefinition(qi::_r1, qi::_r2) % "&"; assignmentDefinitionList.name("assignment list"); - updateDefinition = (constantDoubleExpression > qi::lit(":")[phoenix::clear(phoenix::ref(assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a))[qi::_val = phoenix::construct(qi::_1, qi::_a)]; + updateDefinition = (constantDoubleExpression > qi::lit(":")[phoenix::clear(phoenix::ref(assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b)]; updateDefinition.name("update"); updateListDefinition = +updateDefinition % "+"; updateListDefinition.name("update list"); @@ -187,15 +187,15 @@ struct PrismParser::PrismGrammar : qi::grammar> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(phoenix::val(qi::_1), qi::_b))), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localBooleanVariables_.add, qi::_1, qi::_1)]; + booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::push_back(qi::_r1, phoenix::construct(phoenix::val(nextBooleanVariableIndex), phoenix::val(qi::_1), qi::_b)), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::val(nextBooleanVariableIndex))), qi::_a = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::bool_, phoenix::val(nextBooleanVariableIndex), qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localBooleanVariables_.add, qi::_1, qi::_1), phoenix::ref(nextBooleanVariableIndex)++]; booleanVariableDefinition.name("boolean variable declaration"); - integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2, qi::_3, qi::_b))), qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localIntegerVariables_.add, qi::_1, qi::_1)]; + integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::push_back(qi::_r1, phoenix::construct(phoenix::val(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3, qi::_b)), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::val(nextIntegerVariableIndex))), qi::_a = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, phoenix::val(nextIntegerVariableIndex), qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localIntegerVariables_.add, qi::_1, qi::_1), phoenix::ref(nextIntegerVariableIndex)++]; integerVariableDefinition.name("integer variable declaration"); - variableDefinition = (booleanVariableDefinition(qi::_r1) | integerVariableDefinition(qi::_r2)); + variableDefinition = (booleanVariableDefinition(qi::_r1, qi::_r3) | integerVariableDefinition(qi::_r2, qi::_r4)); variableDefinition.name("variable declaration"); // This block defines all entities that are needed for parsing a module. - moduleDefinition = (qi::lit("module")[phoenix::clear(phoenix::ref(localBooleanVariables_)), phoenix::clear(phoenix::ref(localIntegerVariables_))] > freeIdentifierName > *(variableDefinition(qi::_a, qi::_b)) > +commandDefinition > qi::lit("endmodule"))[phoenix::bind(moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_2)]; + moduleDefinition = (qi::lit("module")[phoenix::clear(phoenix::ref(localBooleanVariables_)), phoenix::clear(phoenix::ref(localIntegerVariables_))] > freeIdentifierName > *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) > +commandDefinition > qi::lit("endmodule"))[phoenix::bind(moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2)]; moduleDefinition.name("module"); moduleDefinitionList %= +moduleDefinition; moduleDefinitionList.name("module list"); @@ -234,19 +234,19 @@ struct PrismParser::PrismGrammar : qi::grammar(), Skipper> moduleDefinitionList; // Rules for module definition. - qi::rule, std::map>, Skipper> moduleDefinition; + qi::rule, std::vector, std::map, std::map>, Skipper> moduleDefinition; // Rules for variable definitions. - qi::rule&, std::map&), Skipper> variableDefinition; - qi::rule&), qi::locals, std::shared_ptr>, Skipper> booleanVariableDefinition; - qi::rule&), qi::locals, std::shared_ptr>, Skipper> integerVariableDefinition; + qi::rule&, std::vector&, std::map&, std::map&), Skipper> variableDefinition; + qi::rule&, std::map&), qi::locals, std::shared_ptr>, Skipper> booleanVariableDefinition; + qi::rule&, std::map&), qi::locals, std::shared_ptr>, Skipper> integerVariableDefinition; // Rules for command definitions. qi::rule, Skipper> commandDefinition; qi::rule(), Skipper> updateListDefinition; - qi::rule>, Skipper> updateDefinition; - qi::rule&), Skipper> assignmentDefinitionList; - qi::rule&), Skipper> assignmentDefinition; + qi::rule, std::map>, Skipper> updateDefinition; + qi::rule&, std::map&), Skipper> assignmentDefinitionList; + qi::rule&, std::map&), Skipper> assignmentDefinition; // Rules for variable/command names. qi::rule integerVariableName; @@ -377,6 +377,10 @@ struct PrismParser::PrismGrammar : qi::grammar> integerVariables_, booleanVariables_; diff --git a/src/storm.cpp b/src/storm.cpp index c4c75d09a..678189be5 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -36,6 +36,7 @@ #include "log4cplus/fileappender.h" #include "src/parser/PrismParser.h" +#include "src/adapters/IntermediateRepresentationAdapter.h" #include "src/exceptions/InvalidSettingsException.h" @@ -241,7 +242,8 @@ int main(const int argc, const char* argv[]) { // testChecking(); storm::parser::PrismParser parser; - parser.parseFile("test.input"); + std::shared_ptr program = parser.parseFile("test.input"); + storm::storage::SquareSparseMatrix* result = storm::adapters::IntermediateRepresentationAdapter::toSparseMatrix(*program); cleanUp(); return 0; diff --git a/test.input b/test.input index 5339a8416..700951a05 100644 --- a/test.input +++ b/test.input @@ -1,24 +1,24 @@ +// Knuth's model of a fair die using only fair coins dtmc module die -// local state -s : [0..7] init 0; -// value of the dice -d : [0..6] init 0; + + // local state + s : [0..7] init 0; + // value of the dice + d : [0..6] init 0; + + [] s=0 -> 0.5 : (s'=1) + 0.5 : (s'=2); + [] s=1 -> 0.5 : (s'=3) + 0.5 : (s'=4); + [] s=2 -> 0.5 : (s'=5) + 0.5 : (s'=6); + [] s=3 -> 0.5 : (s'=1) + 0.5 : (s'=7) & (d'=1); + [] s=4 -> 0.5 : (s'=7) & (d'=2) + 0.5 : (s'=7) & (d'=3); + [] s=5 -> 0.5 : (s'=7) & (d'=4) + 0.5 : (s'=7) & (d'=5); + [] s=6 -> 0.5 : (s'=2) + 0.5 : (s'=7) & (d'=6); + [] s=7 -> 1: (s'=7); -[] s=0 -> 0.5 : (s'=1) + 0.5 : (s'=2); -[] s=1 -> 0.5 : (s'=3) + 0.5 : (s'=4); -[] s=2 -> 0.5 : (s'=5) + 0.5 : (s'=6); -[] s=3 -> 0.5 : (s'=1) + 0.5 : (s'=7) & (d'=1); -[] s=4 -> 0.5 : (s'=7) & (d'=2) + 0.5 : (s'=7) & (d'=3); -[] s=5 -> 0.5 : (s'=7) & (d'=4) + 0.5 : (s'=7) & (d'=5); -[] s=6 -> 0.5 : (s'=2) + 0.5 : (s'=7) & (d'=6); -[] s=7 -> 1 : (s'=7); endmodule rewards "coin_flips" [] s<7 : 1; - s>3 : 1; endrewards - -label test = s>2; From c19418b8711893cbb3047111fa4c22f65632fe75 Mon Sep 17 00:00:00 2001 From: dehnert Date: Mon, 14 Jan 2013 16:59:15 +0100 Subject: [PATCH 015/152] Intermediate commit to switch workplace. --- .../IntermediateRepresentationAdapter.h | 112 ++++++++++++++++-- src/ir/TransitionReward.h | 2 + src/ir/Update.cpp | 4 +- src/ir/Variable.h | 1 + src/ir/expressions/BaseExpression.h | 6 +- .../BinaryBooleanFunctionExpression.h | 6 +- .../BinaryNumericalFunctionExpression.h | 16 +-- src/ir/expressions/BinaryRelationExpression.h | 6 +- .../expressions/BooleanConstantExpression.h | 2 +- src/ir/expressions/BooleanLiteral.h | 2 +- src/ir/expressions/DoubleConstantExpression.h | 2 +- src/ir/expressions/DoubleLiteral.h | 2 +- .../expressions/IntegerConstantExpression.h | 2 +- src/ir/expressions/IntegerLiteral.h | 2 +- .../UnaryBooleanFunctionExpression.h | 4 +- .../UnaryNumericalFunctionExpression.h | 12 +- src/ir/expressions/VariableExpression.h | 16 +-- src/parser/PrismParser.cpp | 7 +- src/storm.cpp | 2 + 19 files changed, 148 insertions(+), 58 deletions(-) diff --git a/src/adapters/IntermediateRepresentationAdapter.h b/src/adapters/IntermediateRepresentationAdapter.h index d60325b11..01e5a9a17 100644 --- a/src/adapters/IntermediateRepresentationAdapter.h +++ b/src/adapters/IntermediateRepresentationAdapter.h @@ -35,6 +35,13 @@ public: } }; +class StateCompare { +public: + bool operator()(StateType* state1, StateType* state2) const { + return *state1 == *state2; + } +}; + class IntermediateRepresentationAdapter { public: template @@ -72,24 +79,20 @@ public: } } - StateType* initialState = new StateType(std::vector(), std::vector()); - std::get<0>(*initialState).resize(numberOfBooleanVariables); - std::get<1>(*initialState).resize(numberOfIntegerVariables); + StateType* initialState = getNewState(numberOfBooleanVariables, numberOfIntegerVariables); for (uint_fast64_t i = 0; i < numberOfBooleanVariables; ++i) { - bool initialValue = booleanVariables[i].getInitialValue()->getValueAsBool(std::get<0>(*initialState), std::get<1>(*initialState)); + bool initialValue = booleanVariables[i].getInitialValue()->getValueAsBool(*initialState); std::get<0>(*initialState)[i] = initialValue; } for (uint_fast64_t i = 0; i < numberOfIntegerVariables; ++i) { - int_fast64_t initialValue = integerVariables[i].getInitialValue()->getValueAsInt(std::get<0>(*initialState), std::get<1>(*initialState)); + int_fast64_t initialValue = integerVariables[i].getInitialValue()->getValueAsInt(*initialState); std::get<1>(*initialState)[i] = initialValue; } - std::cout << "Initial State:" << std::get<0>(*initialState) << " / " << std::get<1>(*initialState) << std::endl; - uint_fast64_t nextIndex = 1; - std::unordered_map stateToIndexMap; + std::unordered_map stateToIndexMap; std::vector allStates; std::queue stateQueue; @@ -97,6 +100,7 @@ public: stateQueue.push(initialState); stateToIndexMap[initialState] = 0; + uint_fast64_t totalNumberOfTransitions = 0; while (!stateQueue.empty()) { // Get first state in queue. StateType* currentState = stateQueue.front(); @@ -111,15 +115,44 @@ public: storm::ir::Command const& command = module.getCommand(j); // Check if this command is enabled in the current state. - if (command.getGuard()->getValueAsBool(std::get<0>(*currentState), std::get<1>(*currentState))) { + if (command.getGuard()->getValueAsBool(*currentState)) { + std::unordered_map stateToProbabilityMap; for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { storm::ir::Update const& update = command.getUpdate(k); + StateType* newState = new StateType(*currentState); + std::map const& booleanAssignmentMap = update.getBooleanAssignments(); for (auto assignedVariable : booleanAssignmentMap) { - // Check if the variable that is being assigned is a boolean or an integer. - // auto boolIt = + setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(*currentState)); + } + std::map const& integerAssignmentMap = update.getIntegerAssignments(); + for (auto assignedVariable : integerAssignmentMap) { + setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(*currentState)); + } + + auto probIt = stateToProbabilityMap.find(newState); + if (probIt != stateToProbabilityMap.end()) { + stateToProbabilityMap[newState] += update.getLikelihoodExpression()->getValueAsDouble(*currentState); + } else { + ++totalNumberOfTransitions; + stateToProbabilityMap[newState] = update.getLikelihoodExpression()->getValueAsDouble(*currentState); + } + auto it = stateToIndexMap.find(newState); + if (it != stateToIndexMap.end()) { + // Delete the state object directly as we have already seen that state. + delete newState; + } else { + // Add state to the queue of states that are still to be explored. + stateQueue.push(newState); + + // Add state to list of all states so that we can delete it at the end. + allStates.push_back(newState); + + // Give a unique index to the newly found state. + stateToIndexMap[newState] = nextIndex; + ++nextIndex; } } } @@ -127,13 +160,68 @@ public: } } + std::cout << "Found " << allStates.size() << " reachable states and " << totalNumberOfTransitions << " transitions."; + + storm::storage::SquareSparseMatrix* resultMatrix = new storm::storage::SquareSparseMatrix(allStates.size()); + resultMatrix->initialize(totalNumberOfTransitions); + + for (StateType* state : allStates) { + // Iterate over all modules. + for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { + storm::ir::Module const& module = program.getModule(i); + + // Iterate over all commands. + for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { + storm::ir::Command const& command = module.getCommand(j); + + // Check if this command is enabled in the current state. + if (command.getGuard()->getValueAsBool(*currentState)) { + std::unordered_map stateToProbabilityMap; + for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { + storm::ir::Update const& update = command.getUpdate(k); + + StateType* newState = new StateType(*currentState); + + std::map const& booleanAssignmentMap = update.getBooleanAssignments(); + for (auto assignedVariable : booleanAssignmentMap) { + setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(*currentState)); + } + std::map const& integerAssignmentMap = update.getIntegerAssignments(); + for (auto assignedVariable : integerAssignmentMap) { + setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(*currentState)); + } + + auto probIt = stateToProbabilityMap.find(newState); + if (probIt != stateToProbabilityMap.end()) { + stateToProbabilityMap[newState] += update.getLikelihoodExpression()->getValueAsDouble(*currentState); + } else { + ++totalNumberOfTransitions; + stateToProbabilityMap[newState] = update.getLikelihoodExpression()->getValueAsDouble(*currentState); + } + } + // Now free all the elements we allocated. for (auto element : allStates) { delete element; } - return nullptr; + return resultMatrix; } +private: + static StateType* getNewState(uint_fast64_t numberOfBooleanVariables, uint_fast64_t numberOfIntegerVariables) { + StateType* result = new StateType(); + result->first.resize(numberOfBooleanVariables); + result->second.resize(numberOfIntegerVariables); + return result; + } + + static void setValue(StateType* state, uint_fast64_t index, bool value) { + std::get<0>(*state)[index] = value; + } + + static void setValue(StateType* state, uint_fast64_t index, int_fast64_t value) { + std::get<1>(*state)[index] = value; + } }; } diff --git a/src/ir/TransitionReward.h b/src/ir/TransitionReward.h index eaffe10ae..07e0084e0 100644 --- a/src/ir/TransitionReward.h +++ b/src/ir/TransitionReward.h @@ -10,6 +10,8 @@ #include "expressions/BaseExpression.h" +#include + namespace storm { namespace ir { diff --git a/src/ir/Update.cpp b/src/ir/Update.cpp index 668b543da..edacb6fe9 100644 --- a/src/ir/Update.cpp +++ b/src/ir/Update.cpp @@ -79,18 +79,18 @@ std::string Update::toString() const { uint_fast64_t i = 0; for (auto assignment : booleanAssignments) { result << assignment.second.toString(); - ++i; if (i < booleanAssignments.size() - 1 || integerAssignments.size() > 0) { result << " & "; } + ++i; } i = 0; for (auto assignment : integerAssignments) { result << assignment.second.toString(); - ++i; if (i < integerAssignments.size() - 1) { result << " & "; } + ++i; } return result.str(); } diff --git a/src/ir/Variable.h b/src/ir/Variable.h index eed1e538c..2c065a004 100644 --- a/src/ir/Variable.h +++ b/src/ir/Variable.h @@ -11,6 +11,7 @@ #include "expressions/BaseExpression.h" #include +#include namespace storm { diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h index b88953dce..3e228d5cf 100644 --- a/src/ir/expressions/BaseExpression.h +++ b/src/ir/expressions/BaseExpression.h @@ -37,7 +37,7 @@ public: } - virtual int_fast64_t getValueAsInt(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const& variableValues) const { if (type != int_) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '" << this->getTypeName() << "' as 'int'."; @@ -46,7 +46,7 @@ public: << this->getTypeName() << " because evaluation implementation is missing."; } - virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { if (type != bool_) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '" << this->getTypeName() << "' as 'bool'."; @@ -55,7 +55,7 @@ public: << this->getTypeName() << " because evaluation implementation is missing."; } - virtual double getValueAsDouble(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual double getValueAsDouble(std::pair, std::vector> const& variableValues) const { if (type != bool_) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '" << this->getTypeName() << "' as 'double'."; diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.h b/src/ir/expressions/BinaryBooleanFunctionExpression.h index e26bd22f3..957c08658 100644 --- a/src/ir/expressions/BinaryBooleanFunctionExpression.h +++ b/src/ir/expressions/BinaryBooleanFunctionExpression.h @@ -31,9 +31,9 @@ public: } - virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { - bool resultLeft = left->getValueAsBool(booleanVariableValues, integerVariableValues); - bool resultRight = right->getValueAsBool(booleanVariableValues, integerVariableValues); + virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { + bool resultLeft = left->getValueAsBool(variableValues); + bool resultRight = right->getValueAsBool(variableValues); switch(functionType) { case AND: return resultLeft & resultRight; break; case OR: return resultLeft | resultRight; break; diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h index 28ba2b3f2..7a76320a9 100644 --- a/src/ir/expressions/BinaryNumericalFunctionExpression.h +++ b/src/ir/expressions/BinaryNumericalFunctionExpression.h @@ -28,13 +28,13 @@ public: } - virtual int_fast64_t getValueAsInt(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const& variableValues) const { if (this->getType() != int_) { - BaseExpression::getValueAsInt(booleanVariableValues, integerVariableValues); + BaseExpression::getValueAsInt(variableValues); } - int_fast64_t resultLeft = left->getValueAsInt(booleanVariableValues, integerVariableValues); - int_fast64_t resultRight = right->getValueAsInt(booleanVariableValues, integerVariableValues); + int_fast64_t resultLeft = left->getValueAsInt(variableValues); + int_fast64_t resultRight = right->getValueAsInt(variableValues); switch(functionType) { case PLUS: return resultLeft + resultRight; break; case MINUS: return resultLeft - resultRight; break; @@ -45,13 +45,13 @@ public: } } - virtual double getValueAsDouble(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual double getValueAsDouble(std::pair, std::vector> const& variableValues) const { if (this->getType() != double_) { - BaseExpression::getValueAsDouble(booleanVariableValues, integerVariableValues); + BaseExpression::getValueAsDouble(variableValues); } - double resultLeft = left->getValueAsDouble(booleanVariableValues, integerVariableValues); - double resultRight = right->getValueAsDouble(booleanVariableValues, integerVariableValues); + double resultLeft = left->getValueAsDouble(variableValues); + double resultRight = right->getValueAsDouble(variableValues); switch(functionType) { case PLUS: return resultLeft + resultRight; break; case MINUS: return resultLeft - resultRight; break; diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h index db834ea93..fe07f0749 100644 --- a/src/ir/expressions/BinaryRelationExpression.h +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -28,9 +28,9 @@ public: } - virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { - int_fast64_t resultLeft = left->getValueAsInt(booleanVariableValues, integerVariableValues); - int_fast64_t resultRight = right->getValueAsInt(booleanVariableValues, integerVariableValues); + virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { + int_fast64_t resultLeft = left->getValueAsInt(variableValues); + int_fast64_t resultRight = right->getValueAsInt(variableValues); switch(relationType) { case EQUAL: return resultLeft == resultRight; break; case LESS: return resultLeft < resultRight; break; diff --git a/src/ir/expressions/BooleanConstantExpression.h b/src/ir/expressions/BooleanConstantExpression.h index cfd6ae418..58204fee4 100644 --- a/src/ir/expressions/BooleanConstantExpression.h +++ b/src/ir/expressions/BooleanConstantExpression.h @@ -29,7 +29,7 @@ public: } - virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { if (!defined) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " << "Boolean constant '" << this->getConstantName() << "' is undefined."; diff --git a/src/ir/expressions/BooleanLiteral.h b/src/ir/expressions/BooleanLiteral.h index f7d4e9957..b7ee88997 100644 --- a/src/ir/expressions/BooleanLiteral.h +++ b/src/ir/expressions/BooleanLiteral.h @@ -28,7 +28,7 @@ public: } - virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { return value; } diff --git a/src/ir/expressions/DoubleConstantExpression.h b/src/ir/expressions/DoubleConstantExpression.h index 9ad1e61d6..c852329c1 100644 --- a/src/ir/expressions/DoubleConstantExpression.h +++ b/src/ir/expressions/DoubleConstantExpression.h @@ -26,7 +26,7 @@ public: } - virtual double getValueAsDouble(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual double getValueAsDouble(std::pair, std::vector> const& variableValues) const { if (!defined) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " << "Double constant '" << this->getConstantName() << "' is undefined."; diff --git a/src/ir/expressions/DoubleLiteral.h b/src/ir/expressions/DoubleLiteral.h index e7854cfa5..2679a7a5d 100644 --- a/src/ir/expressions/DoubleLiteral.h +++ b/src/ir/expressions/DoubleLiteral.h @@ -30,7 +30,7 @@ public: } - virtual double getValueAsDouble(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual double getValueAsDouble(std::pair, std::vector> const& variableValues) const { return value; } diff --git a/src/ir/expressions/IntegerConstantExpression.h b/src/ir/expressions/IntegerConstantExpression.h index 5e7c46ee7..250b085a3 100644 --- a/src/ir/expressions/IntegerConstantExpression.h +++ b/src/ir/expressions/IntegerConstantExpression.h @@ -26,7 +26,7 @@ public: } - virtual int_fast64_t getValueAsInt(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const& variableValues) const { if (!defined) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " << "Integer constant '" << this->getConstantName() << "' is undefined."; diff --git a/src/ir/expressions/IntegerLiteral.h b/src/ir/expressions/IntegerLiteral.h index 36c78a948..c5cd06119 100644 --- a/src/ir/expressions/IntegerLiteral.h +++ b/src/ir/expressions/IntegerLiteral.h @@ -28,7 +28,7 @@ public: } - virtual int_fast64_t getValueAsInt(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const& variableValues) const { return value; } diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.h b/src/ir/expressions/UnaryBooleanFunctionExpression.h index b21a70f87..e0fae6c5b 100644 --- a/src/ir/expressions/UnaryBooleanFunctionExpression.h +++ b/src/ir/expressions/UnaryBooleanFunctionExpression.h @@ -28,8 +28,8 @@ public: } - virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { - bool resultChild = child->getValueAsBool(booleanVariableValues, integerVariableValues); + virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { + bool resultChild = child->getValueAsBool(variableValues); switch(functionType) { case NOT: return !resultChild; break; default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " diff --git a/src/ir/expressions/UnaryNumericalFunctionExpression.h b/src/ir/expressions/UnaryNumericalFunctionExpression.h index db5cb2945..8b746c1c7 100644 --- a/src/ir/expressions/UnaryNumericalFunctionExpression.h +++ b/src/ir/expressions/UnaryNumericalFunctionExpression.h @@ -28,12 +28,12 @@ public: } - virtual int_fast64_t getValueAsInt(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const& variableValues) const { if (this->getType() != int_) { - BaseExpression::getValueAsInt(booleanVariableValues, integerVariableValues); + BaseExpression::getValueAsInt(variableValues); } - int_fast64_t resultChild = child->getValueAsInt(booleanVariableValues, integerVariableValues); + int_fast64_t resultChild = child->getValueAsInt(variableValues); switch(functionType) { case MINUS: return -resultChild; break; default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " @@ -41,12 +41,12 @@ public: } } - virtual double getValueAsDouble(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual double getValueAsDouble(std::pair, std::vector> const& variableValues) const { if (this->getType() != double_) { - BaseExpression::getValueAsDouble(booleanVariableValues, integerVariableValues); + BaseExpression::getValueAsDouble(variableValues); } - double resultChild = child->getValueAsDouble(booleanVariableValues, integerVariableValues); + double resultChild = child->getValueAsDouble(variableValues); switch(functionType) { case MINUS: return -resultChild; break; default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index 02ca79a36..47b2087cd 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -32,25 +32,25 @@ public: return variableName; } - virtual int_fast64_t getValueAsInt(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const& variableValues) const { if (this->getType() != int_) { - BaseExpression::getValueAsInt(booleanVariableValues, integerVariableValues); + BaseExpression::getValueAsInt(variableValues); } - return integerVariableValues[index]; + return variableValues.second[index]; } - virtual bool getValueAsBool(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { if (this->getType() != bool_) { - BaseExpression::getValueAsBool(booleanVariableValues, integerVariableValues); + BaseExpression::getValueAsBool(variableValues); } - return booleanVariableValues[index]; + return variableValues.first[index]; } - virtual double getValueAsDouble(std::vector const& booleanVariableValues, std::vector const& integerVariableValues) const { + virtual double getValueAsDouble(std::pair, std::vector> const& variableValues) const { if (this->getType() != double_) { - BaseExpression::getValueAsDouble(booleanVariableValues, integerVariableValues); + BaseExpression::getValueAsDouble(variableValues); } throw storm::exceptions::NotImplementedException() << "Cannot evaluate expression with " diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index fe6c4fd8e..92b89fd17 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -459,11 +459,8 @@ std::shared_ptr PrismParser::parse(std::istream& inputStream } msg << std::endl; -// On Mac OS, exception messages are not displayed in case an exception is propagated to the -// operating system, so we need to display the message ourselves. -#if defined(MACOSX) - std::cout << msg.str(); -#endif + std::cerr << msg.str(); + // Now propagate exception. throw storm::exceptions::WrongFileFormatException() << msg.str(); } diff --git a/src/storm.cpp b/src/storm.cpp index 678189be5..cbf16faa8 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -244,6 +244,8 @@ int main(const int argc, const char* argv[]) { storm::parser::PrismParser parser; std::shared_ptr program = parser.parseFile("test.input"); storm::storage::SquareSparseMatrix* result = storm::adapters::IntermediateRepresentationAdapter::toSparseMatrix(*program); + result->print(); + delete result; cleanUp(); return 0; From ed43401c3720a7f090bd610e816f68e4a93551a5 Mon Sep 17 00:00:00 2001 From: dehnert Date: Mon, 14 Jan 2013 20:26:09 +0100 Subject: [PATCH 016/152] Reenable logging to prevent exception. --- src/storm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm.cpp b/src/storm.cpp index cbf16faa8..220ae5a02 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -233,7 +233,7 @@ void testChecking() { * Main entry point. */ int main(const int argc, const char* argv[]) { - // initializeLogger(); + initializeLogger(); // if (!parseOptions(argc, argv)) { // return 0; //} From aba470960fd76e0595d6d62bff7d2930be73fd82 Mon Sep 17 00:00:00 2001 From: dehnert Date: Mon, 14 Jan 2013 20:55:01 +0100 Subject: [PATCH 017/152] Intermediate commit to test code under linux. --- src/adapters/IntermediateRepresentationAdapter.h | 12 +++++++----- src/storm.cpp | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/adapters/IntermediateRepresentationAdapter.h b/src/adapters/IntermediateRepresentationAdapter.h index de35d81a5..fad0217ad 100644 --- a/src/adapters/IntermediateRepresentationAdapter.h +++ b/src/adapters/IntermediateRepresentationAdapter.h @@ -8,6 +8,8 @@ #ifndef STORM_IR_INTERMEDIATEREPRESENTATIONADAPTER_H_ #define STORM_IR_INTERMEDIATEREPRESENTATIONADAPTER_H_ +#include "src/storage/SparseMatrix.h" + #include #include #include @@ -45,7 +47,7 @@ public: class IntermediateRepresentationAdapter { public: template - static storm::storage::SquareSparseMatrix* toSparseMatrix(storm::ir::Program const& program) { + static storm::storage::SparseMatrix* toSparseMatrix(storm::ir::Program const& program) { uint_fast64_t numberOfIntegerVariables = 0; uint_fast64_t numberOfBooleanVariables = 0; @@ -162,7 +164,7 @@ public: std::cout << "Found " << allStates.size() << " reachable states and " << totalNumberOfTransitions << " transitions."; - storm::storage::SquareSparseMatrix* resultMatrix = new storm::storage::SquareSparseMatrix(allStates.size()); + storm::storage::SparseMatrix* resultMatrix = new storm::storage::SparseMatrix(allStates.size()); resultMatrix->initialize(totalNumberOfTransitions); uint_fast64_t currentIndex = 0; @@ -204,9 +206,9 @@ public: } // Now insert the actual values into the matrix. - //for (auto targetIndex : stateIndexToProbabilityMap) { - // resultMatrix->addNextValue(currentIndex, targetIndex.first, targetIndex.second); - //} + for (auto targetIndex : stateIndexToProbabilityMap) { + resultMatrix->addNextValue(currentIndex, targetIndex.first, targetIndex.second); + } } } } diff --git a/src/storm.cpp b/src/storm.cpp index a8390a7e4..dfb2109e5 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -25,7 +25,7 @@ #include "src/modelChecker/EigenDtmcPrctlModelChecker.h" #include "src/modelChecker/GmmxxDtmcPrctlModelChecker.h" #include "src/parser/AutoParser.h" -#include "src/parser/PrctlParser.h" +//#include "src/parser/PrctlParser.h" #include "src/solver/GraphAnalyzer.h" #include "src/utility/Settings.h" #include "src/formula/Formulas.h" @@ -246,7 +246,7 @@ int main(const int argc, const char* argv[]) { storm::parser::PrismParser parser; std::shared_ptr program = parser.parseFile("test.input"); - storm::storage::SquareSparseMatrix* result = storm::adapters::IntermediateRepresentationAdapter::toSparseMatrix(*program); + storm::storage::SparseMatrix* result = storm::adapters::IntermediateRepresentationAdapter::toSparseMatrix(*program); result->print(); delete result; From 152923e14b4c74573743c7b3fd9ed343dfd1561c Mon Sep 17 00:00:00 2001 From: dehnert Date: Tue, 15 Jan 2013 11:18:56 +0100 Subject: [PATCH 018/152] Reverted the PrismParser in the sense that it now again builds a full string of the input first and then parses it, because apparently the adapter iterators of Boost give an awful output under valgrind. --- src/parser/PrismParser.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 92b89fd17..19027a3f8 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -25,9 +25,8 @@ #include // Some typedefs and namespace definitions to reduce code size. -typedef std::istreambuf_iterator base_iterator_type; -typedef boost::spirit::multi_pass forward_iterator_type; -typedef boost::spirit::classic::position_iterator2 pos_iterator_type; +typedef std::string::const_iterator BaseIteratorType; +typedef boost::spirit::classic::position_iterator2 PositionIteratorType; namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; @@ -422,23 +421,27 @@ std::shared_ptr PrismParser::parseFile(std::string const& fi */ std::shared_ptr PrismParser::parse(std::istream& inputStream, std::string const& filename) const { // Prepare iterators to input. - base_iterator_type in_begin(inputStream); - forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin); - forward_iterator_type fwd_end; - pos_iterator_type position_begin(fwd_begin, fwd_end, filename); - pos_iterator_type position_end; + // TODO: Right now, this parses the whole contents of the file into a string first. + // While this is usually not necessary, because there exist adapters that make an input stream + // iterable in both directions without storing it into a string, using the corresponding + // Boost classes gives an awful output under valgrind and is thus disabled for the time being. + std::string fileContent((std::istreambuf_iterator(inputStream)), (std::istreambuf_iterator())); + BaseIteratorType stringIteratorBegin = fileContent.begin(); + BaseIteratorType stringIteratorEnd = fileContent.end(); + PositionIteratorType positionIteratorBegin(stringIteratorBegin, stringIteratorEnd, filename); + PositionIteratorType positionIteratorEnd; // Prepare resulting intermediate representation of input. std::shared_ptr result(new storm::ir::Program()); // In order to instantiate the grammar, we have to pass the type of the skipping parser. // As this is more complex, we let Boost figure out the actual type for us. - PrismGrammar> *(qi::char_ - qi::eol) >> qi::eol)> grammar; + PrismGrammar> *(qi::char_ - qi::eol) >> qi::eol)> grammar; try { // Now parse the content using phrase_parse in order to be able to supply a skipping // parser. - qi::phrase_parse(position_begin, position_end, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, *result); - } catch(const qi::expectation_failure& e) { + qi::phrase_parse(positionIteratorBegin, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, *result); + } catch(const qi::expectation_failure& e) { // If the parser expected content different than the one provided, display information // about the location of the error. const boost::spirit::classic::file_position_base& pos = e.first.get_position(); From f5f04a1c055a64dbf9a28008095d78ad05874e7f Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 16 Jan 2013 22:28:14 +0100 Subject: [PATCH 019/152] Added dummy test to check for valid push to new repo. --- anothertest.input | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 anothertest.input diff --git a/anothertest.input b/anothertest.input new file mode 100644 index 000000000..700951a05 --- /dev/null +++ b/anothertest.input @@ -0,0 +1,24 @@ +// Knuth's model of a fair die using only fair coins +dtmc + +module die + + // local state + s : [0..7] init 0; + // value of the dice + d : [0..6] init 0; + + [] s=0 -> 0.5 : (s'=1) + 0.5 : (s'=2); + [] s=1 -> 0.5 : (s'=3) + 0.5 : (s'=4); + [] s=2 -> 0.5 : (s'=5) + 0.5 : (s'=6); + [] s=3 -> 0.5 : (s'=1) + 0.5 : (s'=7) & (d'=1); + [] s=4 -> 0.5 : (s'=7) & (d'=2) + 0.5 : (s'=7) & (d'=3); + [] s=5 -> 0.5 : (s'=7) & (d'=4) + 0.5 : (s'=7) & (d'=5); + [] s=6 -> 0.5 : (s'=2) + 0.5 : (s'=7) & (d'=6); + [] s=7 -> 1: (s'=7); + +endmodule + +rewards "coin_flips" + [] s<7 : 1; +endrewards From a17c99902b3cbc03ad792235b9c40371a502957b Mon Sep 17 00:00:00 2001 From: dehnert Date: Thu, 24 Jan 2013 20:11:41 +0100 Subject: [PATCH 020/152] The PRISM parser can now parse DTMC models that do not use synchronization. --- .../IntermediateRepresentationAdapter.h | 44 +++++++- src/parser/PrismParser.cpp | 20 ++-- src/storm.cpp | 17 ++- test.input | 105 ++++++++++++++---- 4 files changed, 142 insertions(+), 44 deletions(-) diff --git a/src/adapters/IntermediateRepresentationAdapter.h b/src/adapters/IntermediateRepresentationAdapter.h index fad0217ad..6c5774bfc 100644 --- a/src/adapters/IntermediateRepresentationAdapter.h +++ b/src/adapters/IntermediateRepresentationAdapter.h @@ -9,6 +9,7 @@ #define STORM_IR_INTERMEDIATEREPRESENTATIONADAPTER_H_ #include "src/storage/SparseMatrix.h" +#include "src/utility/Settings.h" #include #include @@ -19,6 +20,10 @@ typedef std::pair, std::vector> StateType; +#include "log4cplus/logger.h" +#include "log4cplus/loggingmacros.h" +extern log4cplus::Logger logger; + namespace storm { namespace adapters { @@ -48,7 +53,7 @@ class IntermediateRepresentationAdapter { public: template static storm::storage::SparseMatrix* toSparseMatrix(storm::ir::Program const& program) { - + LOG4CPLUS_INFO(logger, "Creating sparse matrix for probabilistic program."); uint_fast64_t numberOfIntegerVariables = 0; uint_fast64_t numberOfBooleanVariables = 0; for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { @@ -108,6 +113,8 @@ public: StateType* currentState = stateQueue.front(); stateQueue.pop(); + bool hasTransition = false; + // Iterate over all modules. for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { storm::ir::Module const& module = program.getModule(i); @@ -118,21 +125,27 @@ public: // Check if this command is enabled in the current state. if (command.getGuard()->getValueAsBool(*currentState)) { + hasTransition = true; std::unordered_map stateToProbabilityMap; + std::queue statesToDelete; for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { storm::ir::Update const& update = command.getUpdate(k); StateType* newState = new StateType(*currentState); - + // std::cout << "took state: " << newState->first << "/" << newState->second << std::endl; std::map const& booleanAssignmentMap = update.getBooleanAssignments(); for (auto assignedVariable : booleanAssignmentMap) { setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(*currentState)); } std::map const& integerAssignmentMap = update.getIntegerAssignments(); for (auto assignedVariable : integerAssignmentMap) { + // std::cout << "evaluting " << assignedVariable.second.getExpression()->toString() << " as " << assignedVariable.second.getExpression()->getValueAsInt(*currentState) << std::endl; setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(*currentState)); } + // std::cout << "applied: " << update.toString() << std::endl; + // std::cout << "got: " << newState->first << "/" << newState->second << std::endl; + auto probIt = stateToProbabilityMap.find(newState); if (probIt != stateToProbabilityMap.end()) { stateToProbabilityMap[newState] += update.getLikelihoodExpression()->getValueAsDouble(*currentState); @@ -144,7 +157,7 @@ public: auto it = stateToIndexMap.find(newState); if (it != stateToIndexMap.end()) { // Delete the state object directly as we have already seen that state. - delete newState; + statesToDelete.push(newState); } else { // Add state to the queue of states that are still to be explored. stateQueue.push(newState); @@ -157,18 +170,31 @@ public: ++nextIndex; } } + while (!statesToDelete.empty()) { + delete statesToDelete.front(); + statesToDelete.pop(); + } } } } - } - std::cout << "Found " << allStates.size() << " reachable states and " << totalNumberOfTransitions << " transitions."; + if (!hasTransition) { + if (storm::settings::instance()->isSet("fix-deadlocks")) { + ++totalNumberOfTransitions; + } else { + LOG4CPLUS_ERROR(logger, "Error while creating sparse matrix from probabilistic program: found deadlock state."); + throw storm::exceptions::WrongFileFormatException() << "Error while creating sparse matrix from probabilistic program: found deadlock state."; + } + } + } storm::storage::SparseMatrix* resultMatrix = new storm::storage::SparseMatrix(allStates.size()); resultMatrix->initialize(totalNumberOfTransitions); uint_fast64_t currentIndex = 0; for (StateType* currentState : allStates) { + bool hasTransition = false; + // Iterate over all modules. for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { storm::ir::Module const& module = program.getModule(i); @@ -179,6 +205,7 @@ public: // Check if this command is enabled in the current state. if (command.getGuard()->getValueAsBool(*currentState)) { + hasTransition = true; std::map stateIndexToProbabilityMap; for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { storm::ir::Update const& update = command.getUpdate(k); @@ -212,15 +239,22 @@ public: } } } + if (!hasTransition) { + resultMatrix->addNextValue(currentIndex, currentIndex, 1); + } + ++currentIndex; } resultMatrix->finalize(); + LOG4CPLUS_INFO(logger, "Created sparse matrix with " << allStates.size() << " reachable states and " << totalNumberOfTransitions << " transitions."); + // Now free all the elements we allocated. for (auto element : allStates) { delete element; } + return resultMatrix; } diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 19027a3f8..78795388e 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -88,7 +88,7 @@ struct PrismParser::PrismGrammar : qi::grammar> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; integerMultExpression.name("integer expression"); - integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> integerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> integerMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::MINUS))]]; integerPlusExpression.name("integer expression"); integerExpression %= integerPlusExpression; integerExpression.name("integer expression"); @@ -98,7 +98,7 @@ struct PrismParser::PrismGrammar : qi::grammar> *(qi::lit("*") >> constantAtomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; constantIntegerMultExpression.name("constant integer expression"); - constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantIntegerMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantIntegerMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::MINUS))]]; constantIntegerPlusExpression.name("constant integer expression"); constantIntegerExpression %= constantIntegerPlusExpression; constantIntegerExpression.name("constant integer expression"); @@ -106,9 +106,9 @@ struct PrismParser::PrismGrammar : qi::grammar> constantDoubleExpression >> qi::lit(")") | doubleConstantExpression); constantAtomicDoubleExpression.name("constant double expression"); - constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicDoubleExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::double_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> constantAtomicDoubleExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::double_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::double_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::DIVIDE))]]; constantDoubleMultExpression.name("constant double expression"); - constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *(qi::lit("+") >> constantDoubleMultExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::double_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS))]; + constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantDoubleMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::double_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::double_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::MINUS))]]; constantDoublePlusExpression.name("constant double expression"); constantDoubleExpression %= constantDoublePlusExpression; constantDoubleExpression.name("constant double expression"); @@ -186,9 +186,9 @@ struct PrismParser::PrismGrammar : qi::grammar> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::push_back(qi::_r1, phoenix::construct(phoenix::val(nextBooleanVariableIndex), phoenix::val(qi::_1), qi::_b)), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::val(nextBooleanVariableIndex))), qi::_a = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::bool_, phoenix::val(nextBooleanVariableIndex), qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localBooleanVariables_.add, qi::_1, qi::_1), phoenix::ref(nextBooleanVariableIndex)++]; + booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextBooleanVariableIndex), phoenix::val(qi::_1), qi::_b)), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextBooleanVariableIndex))), qi::_a = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::bool_, phoenix::ref(nextBooleanVariableIndex), qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localBooleanVariables_.add, qi::_1, qi::_1), phoenix::ref(nextBooleanVariableIndex) = phoenix::ref(nextBooleanVariableIndex) + 1]; booleanVariableDefinition.name("boolean variable declaration"); - integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::push_back(qi::_r1, phoenix::construct(phoenix::val(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3, qi::_b)), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::val(nextIntegerVariableIndex))), qi::_a = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, phoenix::val(nextIntegerVariableIndex), qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localIntegerVariables_.add, qi::_1, qi::_1), phoenix::ref(nextIntegerVariableIndex)++]; + integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3, qi::_b)), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextIntegerVariableIndex))), qi::_a = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, phoenix::ref(nextIntegerVariableIndex), qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localIntegerVariables_.add, qi::_1, qi::_1), phoenix::ref(nextIntegerVariableIndex) = phoenix::ref(nextIntegerVariableIndex) + 1]; integerVariableDefinition.name("integer variable declaration"); variableDefinition = (booleanVariableDefinition(qi::_r1, qi::_r3) | integerVariableDefinition(qi::_r2, qi::_r4)); variableDefinition.name("variable declaration"); @@ -297,18 +297,18 @@ struct PrismParser::PrismGrammar : qi::grammar(), Skipper> integerExpression; - qi::rule(), Skipper> integerPlusExpression; + qi::rule(), qi::locals, Skipper> integerPlusExpression; qi::rule(), Skipper> integerMultExpression; qi::rule(), Skipper> atomicIntegerExpression; qi::rule(), Skipper> constantIntegerExpression; - qi::rule(), Skipper> constantIntegerPlusExpression; + qi::rule(), qi::locals, Skipper> constantIntegerPlusExpression; qi::rule(), Skipper> constantIntegerMultExpression; qi::rule(), Skipper> constantAtomicIntegerExpression; // Rules with double result type. qi::rule(), Skipper> constantDoubleExpression; - qi::rule(), Skipper> constantDoublePlusExpression; - qi::rule(), Skipper> constantDoubleMultExpression; + qi::rule(), qi::locals, Skipper> constantDoublePlusExpression; + qi::rule(), qi::locals, Skipper> constantDoubleMultExpression; qi::rule(), Skipper> constantAtomicDoubleExpression; // Rules for variable recognition. diff --git a/src/storm.cpp b/src/storm.cpp index dfb2109e5..b34529d94 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -198,7 +198,7 @@ void testCheckingSynchronousLeader(storm::models::Dtmc& dtmc, uint_fast6 storm::formula::BoundedUntil* boundedUntilFormula = new storm::formula::BoundedUntil(new storm::formula::Ap("true"), electedFormula, 1); probFormula = new storm::formula::ProbabilisticNoBoundOperator(boundedUntilFormula); - for (uint_fast64_t L = 1; L < 5; ++L) { + for (uint_fast64_t L = 9; L < 10; ++L) { boundedUntilFormula->setBound(L*(n + 1)); mc->check(*probFormula); } @@ -224,12 +224,11 @@ void testChecking() { if (parser.getType() == storm::models::DTMC) { std::shared_ptr> dtmc = parser.getModel>(); dtmc->printModelInformationToStream(std::cout); + // testCheckingDie(*dtmc); + // testCheckingCrowds(*dtmc); + testCheckingSynchronousLeader(*dtmc, 5); } else std::cout << "Input is not DTMC" << std::endl; - - // testCheckingDie(*dtmc); - // testCheckingCrowds(*dtmc); - // testCheckingSynchronousLeader(*dtmc, 4); } /*! @@ -237,9 +236,9 @@ void testChecking() { */ int main(const int argc, const char* argv[]) { initializeLogger(); - // if (!parseOptions(argc, argv)) { - // return 0; - //} + if (!parseOptions(argc, argv)) { + return 0; + } // printHeader(argc, argv); // testChecking(); @@ -247,7 +246,7 @@ int main(const int argc, const char* argv[]) { storm::parser::PrismParser parser; std::shared_ptr program = parser.parseFile("test.input"); storm::storage::SparseMatrix* result = storm::adapters::IntermediateRepresentationAdapter::toSparseMatrix(*program); - result->print(); + // result->print(); delete result; cleanUp(); diff --git a/test.input b/test.input index 700951a05..522d107da 100644 --- a/test.input +++ b/test.input @@ -1,24 +1,89 @@ -// Knuth's model of a fair die using only fair coins dtmc -module die - - // local state - s : [0..7] init 0; - // value of the dice - d : [0..6] init 0; - - [] s=0 -> 0.5 : (s'=1) + 0.5 : (s'=2); - [] s=1 -> 0.5 : (s'=3) + 0.5 : (s'=4); - [] s=2 -> 0.5 : (s'=5) + 0.5 : (s'=6); - [] s=3 -> 0.5 : (s'=1) + 0.5 : (s'=7) & (d'=1); - [] s=4 -> 0.5 : (s'=7) & (d'=2) + 0.5 : (s'=7) & (d'=3); - [] s=5 -> 0.5 : (s'=7) & (d'=4) + 0.5 : (s'=7) & (d'=5); - [] s=6 -> 0.5 : (s'=2) + 0.5 : (s'=7) & (d'=6); - [] s=7 -> 1: (s'=7); - +// probability of forwarding +const double PF = 0.8; +const double notPF = .2; // must be 1-PF +// probability that a crowd member is bad +const double badC = .167; + // probability that a crowd member is good +const double goodC = 0.833; +// Total number of protocol runs to analyze +const int TotalRuns = 5; +// size of the crowd +const int CrowdSize = 10; + +module crowds + // protocol phase + phase: [0..4] init 0; + + // crowd member good (or bad) + good: bool init false; + + // number of protocol runs + runCount: [0..TotalRuns] init 0; + + // observe_i is the number of times the attacker observed crowd member i + observe0: [0..TotalRuns] init 0; + + observe1: [0..TotalRuns] init 0; + + observe2: [0..TotalRuns] init 0; + + observe3: [0..TotalRuns] init 0; + + observe4: [0..TotalRuns] init 0; + + observe5: [0..TotalRuns] init 0; + + observe6: [0..TotalRuns] init 0; + + observe7: [0..TotalRuns] init 0; + + observe8: [0..TotalRuns] init 0; + + observe9: [0..TotalRuns] init 0; + + // the last seen crowd member + lastSeen: [0..CrowdSize - 1] init 0; + + // get the protocol started + [] phase=0 & runCount 1: (phase'=1) & (runCount'=runCount+1) & (lastSeen'=0); + + // decide whether crowd member is good or bad according to given probabilities + [] phase=1 -> goodC : (phase'=2) & (good'=true) + badC : (phase'=2) & (good'=false); + + // if the current member is a good member, update the last seen index (chosen uniformly) + [] phase=2 & good -> 1/10 : (lastSeen'=0) & (phase'=3) + 1/10 : (lastSeen'=1) & (phase'=3) + 1/10 : (lastSeen'=2) & (phase'=3) + 1/10 : (lastSeen'=3) & (phase'=3) + 1/10 : (lastSeen'=4) & (phase'=3) + 1/10 : (lastSeen'=5) & (phase'=3) + 1/10 : (lastSeen'=6) & (phase'=3) + 1/10 : (lastSeen'=7) & (phase'=3) + 1/10 : (lastSeen'=8) & (phase'=3) + 1/10 : (lastSeen'=9) & (phase'=3); + + // if the current member is a bad member, record the most recently seen index + [] phase=2 & !good & lastSeen=0 & observe0 < TotalRuns -> 1: (observe0'=observe0+1) & (phase'=4); + [] phase=2 & !good & lastSeen=1 & observe1 < TotalRuns -> 1: (observe1'=observe1+1) & (phase'=4); + [] phase=2 & !good & lastSeen=2 & observe2 < TotalRuns -> 1: (observe2'=observe2+1) & (phase'=4); + [] phase=2 & !good & lastSeen=3 & observe3 < TotalRuns -> 1: (observe3'=observe3+1) & (phase'=4); + [] phase=2 & !good & lastSeen=4 & observe4 < TotalRuns -> 1: (observe4'=observe4+1) & (phase'=4); + [] phase=2 & !good & lastSeen=5 & observe5 < TotalRuns -> 1: (observe5'=observe5+1) & (phase'=4); + [] phase=2 & !good & lastSeen=6 & observe6 < TotalRuns -> 1: (observe6'=observe6+1) & (phase'=4); + [] phase=2 & !good & lastSeen=7 & observe7 < TotalRuns -> 1: (observe7'=observe7+1) & (phase'=4); + [] phase=2 & !good & lastSeen=8 & observe8 < TotalRuns -> 1: (observe8'=observe8+1) & (phase'=4); + [] phase=2 & !good & lastSeen=9 & observe9 < TotalRuns -> 1: (observe9'=observe9+1) & (phase'=4); + + // good crowd members forward with probability PF and deliver otherwise + [] phase=3 -> PF : (phase'=1) + notPF : (phase'=4); + + // deliver the message and start over + [] phase=4 -> 1: (phase'=0); + endmodule -rewards "coin_flips" - [] s<7 : 1; -endrewards +label "observe0Greater1" = observe0>1; +label "observe1Greater1" = observe1>1; +label "observe2Greater1" = observe2>1; +label "observe3Greater1" = observe3>1; +label "observe4Greater1" = observe4>1; +label "observe5Greater1" = observe5>1; +label "observe6Greater1" = observe6>1; +label "observe7Greater1" = observe7>1; +label "observe8Greater1" = observe8>1; +label "observe9Greater1" = observe9>1; +label "observeIGreater1" = observe1>1|observe2>1|observe3>1|observe4>1|observe5>1|observe6>1|observe7>1|observe8>1|observe9>1; +label "observeOnlyTrueSender" = observe0>1&observe1<=1&observe2<=1&observe3<=1&observe4<=1&observe5<=1&observe6<=1&observe7<=1&observe8<=1&observe9<=1; \ No newline at end of file From 9fbebb93490c657a5879395ca14506d3400b32c5 Mon Sep 17 00:00:00 2001 From: dehnert Date: Fri, 25 Jan 2013 16:47:03 +0100 Subject: [PATCH 021/152] Added CUDD to the repository. --- resources/3rdparty/cudd-2.5.0/LICENSE | 31 + resources/3rdparty/cudd-2.5.0/Makefile | 321 + resources/3rdparty/cudd-2.5.0/README | 177 + resources/3rdparty/cudd-2.5.0/RELEASE.NOTES | 131 + resources/3rdparty/cudd-2.5.0/cudd/Makefile | 124 + resources/3rdparty/cudd-2.5.0/cudd/cudd.h | 1070 ++ resources/3rdparty/cudd-2.5.0/cudd/cuddAPI.c | 4893 +++++ .../3rdparty/cudd-2.5.0/cudd/cuddAddAbs.c | 579 + .../3rdparty/cudd-2.5.0/cudd/cuddAddApply.c | 941 + .../3rdparty/cudd-2.5.0/cudd/cuddAddFind.c | 316 + .../3rdparty/cudd-2.5.0/cudd/cuddAddInv.c | 201 + .../3rdparty/cudd-2.5.0/cudd/cuddAddIte.c | 639 + .../3rdparty/cudd-2.5.0/cudd/cuddAddNeg.c | 290 + .../3rdparty/cudd-2.5.0/cudd/cuddAddWalsh.c | 391 + .../3rdparty/cudd-2.5.0/cudd/cuddAndAbs.c | 373 + .../3rdparty/cudd-2.5.0/cudd/cuddAnneal.c | 814 + resources/3rdparty/cudd-2.5.0/cudd/cuddApa.c | 979 + .../3rdparty/cudd-2.5.0/cudd/cuddApprox.c | 2204 +++ .../3rdparty/cudd-2.5.0/cudd/cuddBddAbs.c | 760 + .../3rdparty/cudd-2.5.0/cudd/cuddBddCorr.c | 515 + .../3rdparty/cudd-2.5.0/cudd/cuddBddIte.c | 1430 ++ .../3rdparty/cudd-2.5.0/cudd/cuddBridge.c | 1016 + .../3rdparty/cudd-2.5.0/cudd/cuddCache.c | 1053 ++ .../3rdparty/cudd-2.5.0/cudd/cuddCheck.c | 885 + resources/3rdparty/cudd-2.5.0/cudd/cuddClip.c | 558 + resources/3rdparty/cudd-2.5.0/cudd/cuddCof.c | 327 + .../3rdparty/cudd-2.5.0/cudd/cuddCompose.c | 1749 ++ .../3rdparty/cudd-2.5.0/cudd/cuddDecomp.c | 2177 +++ .../3rdparty/cudd-2.5.0/cudd/cuddEssent.c | 1467 ++ .../3rdparty/cudd-2.5.0/cudd/cuddExact.c | 1020 + .../3rdparty/cudd-2.5.0/cudd/cuddExport.c | 1389 ++ .../3rdparty/cudd-2.5.0/cudd/cuddGenCof.c | 2178 +++ .../3rdparty/cudd-2.5.0/cudd/cuddGenetic.c | 960 + .../3rdparty/cudd-2.5.0/cudd/cuddGroup.c | 2188 +++ .../3rdparty/cudd-2.5.0/cudd/cuddHarwell.c | 568 + resources/3rdparty/cudd-2.5.0/cudd/cuddInit.c | 308 + resources/3rdparty/cudd-2.5.0/cudd/cuddInt.h | 1188 ++ .../3rdparty/cudd-2.5.0/cudd/cuddInteract.c | 432 + .../3rdparty/cudd-2.5.0/cudd/cuddLCache.c | 1557 ++ .../3rdparty/cudd-2.5.0/cudd/cuddLevelQ.c | 583 + .../3rdparty/cudd-2.5.0/cudd/cuddLinear.c | 1365 ++ .../3rdparty/cudd-2.5.0/cudd/cuddLiteral.c | 264 + .../3rdparty/cudd-2.5.0/cudd/cuddMatMult.c | 707 + .../3rdparty/cudd-2.5.0/cudd/cuddPriority.c | 2027 ++ resources/3rdparty/cudd-2.5.0/cudd/cuddRead.c | 517 + resources/3rdparty/cudd-2.5.0/cudd/cuddRef.c | 808 + .../3rdparty/cudd-2.5.0/cudd/cuddReorder.c | 2137 +++ resources/3rdparty/cudd-2.5.0/cudd/cuddSat.c | 1774 ++ resources/3rdparty/cudd-2.5.0/cudd/cuddSign.c | 318 + .../3rdparty/cudd-2.5.0/cudd/cuddSolve.c | 366 + .../3rdparty/cudd-2.5.0/cudd/cuddSplit.c | 686 + .../3rdparty/cudd-2.5.0/cudd/cuddSubsetHB.c | 1331 ++ .../3rdparty/cudd-2.5.0/cudd/cuddSubsetSP.c | 1660 ++ .../3rdparty/cudd-2.5.0/cudd/cuddSymmetry.c | 1707 ++ .../3rdparty/cudd-2.5.0/cudd/cuddTable.c | 3213 ++++ resources/3rdparty/cudd-2.5.0/cudd/cuddUtil.c | 4032 ++++ .../3rdparty/cudd-2.5.0/cudd/cuddWindow.c | 1023 + .../3rdparty/cudd-2.5.0/cudd/cuddZddCount.c | 357 + .../3rdparty/cudd-2.5.0/cudd/cuddZddFuncs.c | 1630 ++ .../3rdparty/cudd-2.5.0/cudd/cuddZddGroup.c | 1340 ++ .../3rdparty/cudd-2.5.0/cudd/cuddZddIsop.c | 912 + .../3rdparty/cudd-2.5.0/cudd/cuddZddLin.c | 971 + .../3rdparty/cudd-2.5.0/cudd/cuddZddMisc.c | 278 + .../3rdparty/cudd-2.5.0/cudd/cuddZddPort.c | 381 + .../3rdparty/cudd-2.5.0/cudd/cuddZddReord.c | 1664 ++ .../3rdparty/cudd-2.5.0/cudd/cuddZddSetop.c | 1166 ++ .../3rdparty/cudd-2.5.0/cudd/cuddZddSymm.c | 1711 ++ .../3rdparty/cudd-2.5.0/cudd/cuddZddUtil.c | 1205 ++ .../3rdparty/cudd-2.5.0/cudd/doc/cudd.doc | 6776 +++++++ .../3rdparty/cudd-2.5.0/cudd/doc/cudd.ps | 5036 +++++ .../cudd-2.5.0/cudd/doc/cuddAllAbs.html | 3114 +++ .../cudd-2.5.0/cudd/doc/cuddAllByFile.html | 13 + .../cudd-2.5.0/cudd/doc/cuddAllByFunc.html | 13 + .../cudd-2.5.0/cudd/doc/cuddAllDet.html | 15754 ++++++++++++++++ .../cudd-2.5.0/cudd/doc/cuddAllFile.html | 4876 +++++ .../cudd-2.5.0/cudd/doc/cuddDesc.html | 33 + .../3rdparty/cudd-2.5.0/cudd/doc/cuddExt.html | 14 + .../cudd-2.5.0/cudd/doc/cuddExtAbs.html | 1415 ++ .../cudd-2.5.0/cudd/doc/cuddExtDet.html | 4450 +++++ .../cudd-2.5.0/cudd/doc/cuddIntro.css | 30 + .../cudd-2.5.0/cudd/doc/cuddIntro.html | 219 + .../cudd-2.5.0/cudd/doc/cuddTitle.html | 18 + .../cudd-2.5.0/cudd/doc/footnode.html | 109 + .../cudd-2.5.0/cudd/doc/icons/blueball.png | Bin 0 -> 333 bytes .../cudd-2.5.0/cudd/doc/icons/ch_beg_r.png | Bin 0 -> 165 bytes .../cudd-2.5.0/cudd/doc/icons/ch_begin.png | Bin 0 -> 174 bytes .../cudd-2.5.0/cudd/doc/icons/ch_del_r.png | Bin 0 -> 288 bytes .../cudd-2.5.0/cudd/doc/icons/ch_delet.png | Bin 0 -> 288 bytes .../cudd-2.5.0/cudd/doc/icons/ch_end.png | Bin 0 -> 171 bytes .../cudd-2.5.0/cudd/doc/icons/ch_end_r.png | Bin 0 -> 155 bytes .../cudd-2.5.0/cudd/doc/icons/contents.png | Bin 0 -> 278 bytes .../cudd-2.5.0/cudd/doc/icons/crossref.png | Bin 0 -> 147 bytes .../cudd-2.5.0/cudd/doc/icons/footnote.png | Bin 0 -> 190 bytes .../cudd-2.5.0/cudd/doc/icons/greenball.png | Bin 0 -> 333 bytes .../cudd-2.5.0/cudd/doc/icons/image.png | Bin 0 -> 244 bytes .../cudd-2.5.0/cudd/doc/icons/index.png | Bin 0 -> 246 bytes .../cudd-2.5.0/cudd/doc/icons/next.png | Bin 0 -> 245 bytes .../cudd-2.5.0/cudd/doc/icons/next_g.png | Bin 0 -> 272 bytes .../cudd-2.5.0/cudd/doc/icons/nx_grp.png | Bin 0 -> 314 bytes .../cudd-2.5.0/cudd/doc/icons/nx_grp_g.png | Bin 0 -> 386 bytes .../cudd-2.5.0/cudd/doc/icons/orangeball.png | Bin 0 -> 333 bytes .../cudd-2.5.0/cudd/doc/icons/pinkball.png | Bin 0 -> 332 bytes .../cudd-2.5.0/cudd/doc/icons/prev.png | Bin 0 -> 279 bytes .../cudd-2.5.0/cudd/doc/icons/prev_g.png | Bin 0 -> 327 bytes .../cudd-2.5.0/cudd/doc/icons/purpleball.png | Bin 0 -> 332 bytes .../cudd-2.5.0/cudd/doc/icons/pv_grp.png | Bin 0 -> 352 bytes .../cudd-2.5.0/cudd/doc/icons/pv_grp_g.png | Bin 0 -> 430 bytes .../cudd-2.5.0/cudd/doc/icons/redball.png | Bin 0 -> 332 bytes .../3rdparty/cudd-2.5.0/cudd/doc/icons/up.png | Bin 0 -> 211 bytes .../cudd-2.5.0/cudd/doc/icons/up_g.png | Bin 0 -> 231 bytes .../cudd-2.5.0/cudd/doc/icons/whiteball.png | Bin 0 -> 229 bytes .../cudd-2.5.0/cudd/doc/icons/yellowball.png | Bin 0 -> 333 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img1.png | Bin 0 -> 201 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img10.png | Bin 0 -> 211 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img11.png | Bin 0 -> 476 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img12.png | Bin 0 -> 555 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img13.png | Bin 0 -> 560 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img14.png | Bin 0 -> 675 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img15.png | Bin 0 -> 200 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img16.png | Bin 0 -> 223 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img17.png | Bin 0 -> 246 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img18.png | Bin 0 -> 298 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img19.png | Bin 0 -> 409 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img2.png | Bin 0 -> 197 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img20.png | Bin 0 -> 238 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img21.png | Bin 0 -> 614 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img22.png | Bin 0 -> 12605 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img3.png | Bin 0 -> 401 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img4.png | Bin 0 -> 204 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img5.png | Bin 0 -> 315 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img6.png | Bin 0 -> 185 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img7.png | Bin 0 -> 262 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img8.png | Bin 0 -> 220 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img9.png | Bin 0 -> 215 bytes .../3rdparty/cudd-2.5.0/cudd/doc/index.html | 219 + .../3rdparty/cudd-2.5.0/cudd/doc/node1.html | 174 + .../3rdparty/cudd-2.5.0/cudd/doc/node2.html | 175 + .../3rdparty/cudd-2.5.0/cudd/doc/node3.html | 1637 ++ .../3rdparty/cudd-2.5.0/cudd/doc/node4.html | 1165 ++ .../3rdparty/cudd-2.5.0/cudd/doc/node5.html | 130 + .../3rdparty/cudd-2.5.0/cudd/doc/node6.html | 132 + .../3rdparty/cudd-2.5.0/cudd/doc/node7.html | 195 + .../3rdparty/cudd-2.5.0/cudd/doc/node8.html | 848 + resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.mat | 53 + resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.out | 396 + resources/3rdparty/cudd-2.5.0/cudd/testcudd.c | 1178 ++ resources/3rdparty/cudd-2.5.0/dddmp/Makefile | 243 + .../3rdparty/cudd-2.5.0/dddmp/README.dddmp | 64 + .../cudd-2.5.0/dddmp/README.testdddmp | 79 + .../3rdparty/cudd-2.5.0/dddmp/RELEASE_NOTES | 60 + resources/3rdparty/cudd-2.5.0/dddmp/dddmp.h | 330 + .../3rdparty/cudd-2.5.0/dddmp/dddmpBinary.c | 343 + .../3rdparty/cudd-2.5.0/dddmp/dddmpConvert.c | 180 + .../3rdparty/cudd-2.5.0/dddmp/dddmpDbg.c | 166 + .../cudd-2.5.0/dddmp/dddmpDdNodeBdd.c | 455 + .../cudd-2.5.0/dddmp/dddmpDdNodeCnf.c | 944 + .../3rdparty/cudd-2.5.0/dddmp/dddmpInt.h | 216 + .../3rdparty/cudd-2.5.0/dddmp/dddmpLoad.c | 1486 ++ .../3rdparty/cudd-2.5.0/dddmp/dddmpLoadCnf.c | 1072 ++ .../3rdparty/cudd-2.5.0/dddmp/dddmpNodeAdd.c | 451 + .../3rdparty/cudd-2.5.0/dddmp/dddmpNodeBdd.c | 452 + .../3rdparty/cudd-2.5.0/dddmp/dddmpNodeCnf.c | 932 + .../3rdparty/cudd-2.5.0/dddmp/dddmpStoreAdd.c | 957 + .../3rdparty/cudd-2.5.0/dddmp/dddmpStoreBdd.c | 1114 ++ .../3rdparty/cudd-2.5.0/dddmp/dddmpStoreCnf.c | 1583 ++ .../cudd-2.5.0/dddmp/dddmpStoreMisc.c | 1641 ++ .../3rdparty/cudd-2.5.0/dddmp/dddmpUtil.c | 436 + .../cudd-2.5.0/dddmp/doc/cmdIndex.html | 9 + .../cudd-2.5.0/dddmp/doc/commands.html | 12 + .../3rdparty/cudd-2.5.0/dddmp/doc/credit.html | 15 + .../cudd-2.5.0/dddmp/doc/dddmp-2.0-A4.ps | 1261 ++ .../cudd-2.5.0/dddmp/doc/dddmp-2.0-Letter.ps | 1260 ++ .../cudd-2.5.0/dddmp/doc/dddmpAllAbs.html | 483 + .../cudd-2.5.0/dddmp/doc/dddmpAllByFile.html | 13 + .../cudd-2.5.0/dddmp/doc/dddmpAllByFunc.html | 13 + .../cudd-2.5.0/dddmp/doc/dddmpAllDet.html | 3704 ++++ .../cudd-2.5.0/dddmp/doc/dddmpAllFile.html | 679 + .../cudd-2.5.0/dddmp/doc/dddmpDesc.html | 28 + .../cudd-2.5.0/dddmp/doc/dddmpDoc.txt | Bin 0 -> 32768 bytes .../cudd-2.5.0/dddmp/doc/dddmpExt.html | 13 + .../cudd-2.5.0/dddmp/doc/dddmpExtAbs.html | 91 + .../cudd-2.5.0/dddmp/doc/dddmpExtDet.html | 693 + .../cudd-2.5.0/dddmp/doc/dddmpTitle.html | 17 + .../cudd-2.5.0/dddmp/doc/packages.html | 12 + .../cudd-2.5.0/dddmp/doc/pkgIndex.html | 13 + resources/3rdparty/cudd-2.5.0/dddmp/exp/0.add | 21 + resources/3rdparty/cudd-2.5.0/dddmp/exp/0.bdd | 19 + .../3rdparty/cudd-2.5.0/dddmp/exp/0or1.bdd | 119 + resources/3rdparty/cudd-2.5.0/dddmp/exp/1.add | 28 + resources/3rdparty/cudd-2.5.0/dddmp/exp/1.bdd | 110 + resources/3rdparty/cudd-2.5.0/dddmp/exp/2.bdd | 118 + .../3rdparty/cudd-2.5.0/dddmp/exp/2and3.bdd | 76 + resources/3rdparty/cudd-2.5.0/dddmp/exp/3.bdd | 304 + resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd | 50 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis1 | 50 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis2 | 50 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis3 | 50 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis4 | 50 + resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf | 130 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.cnf.bis | 130 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.max1 | 125 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.max2 | 125 + .../3rdparty/cudd-2.5.0/dddmp/exp/4bis.bdd | 47 + .../3rdparty/cudd-2.5.0/dddmp/exp/4xor5.bdd | 120 + resources/3rdparty/cudd-2.5.0/dddmp/exp/5.bdd | 31 + .../cudd-2.5.0/dddmp/exp/composeids.txt | 20 + .../3rdparty/cudd-2.5.0/dddmp/exp/one.bdd | 13 + .../cudd-2.5.0/dddmp/exp/runAllTest.out | 269 + .../cudd-2.5.0/dddmp/exp/runAllTest.script | 11 + .../3rdparty/cudd-2.5.0/dddmp/exp/s27RP1.bdd | 18 + .../cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd | 31 + .../dddmp/exp/s27deltaDddmp1.bdd.bis | 31 + .../cudd-2.5.0/dddmp/exp/s27deltaDddmp2.bdd | 32 + .../3rdparty/cudd-2.5.0/dddmp/exp/test1.out | 44 + .../cudd-2.5.0/dddmp/exp/test1.script | 26 + .../3rdparty/cudd-2.5.0/dddmp/exp/test2.out | 23 + .../cudd-2.5.0/dddmp/exp/test2.script | 30 + .../3rdparty/cudd-2.5.0/dddmp/exp/test3.out | 18 + .../cudd-2.5.0/dddmp/exp/test3.script | 69 + .../3rdparty/cudd-2.5.0/dddmp/exp/test4.out | 24 + .../cudd-2.5.0/dddmp/exp/test4.script | 56 + .../3rdparty/cudd-2.5.0/dddmp/exp/test5.out | 28 + .../cudd-2.5.0/dddmp/exp/test5.script | 42 + .../3rdparty/cudd-2.5.0/dddmp/exp/test6.out | 31 + .../cudd-2.5.0/dddmp/exp/test6.script | 50 + .../3rdparty/cudd-2.5.0/dddmp/exp/test7.out | 102 + .../cudd-2.5.0/dddmp/exp/test7.script | 150 + .../cudd-2.5.0/dddmp/exp/varauxids.ord | 50 + .../cudd-2.5.0/dddmp/exp/varnames.ord | 50 + .../3rdparty/cudd-2.5.0/dddmp/exp/zero.bdd | 13 + .../3rdparty/cudd-2.5.0/dddmp/testdddmp.c | 2279 +++ resources/3rdparty/cudd-2.5.0/epd/Makefile | 64 + resources/3rdparty/cudd-2.5.0/epd/epd.c | 1344 ++ resources/3rdparty/cudd-2.5.0/epd/epd.h | 200 + .../3rdparty/cudd-2.5.0/mnemosyne/Makefile | 53 + .../3rdparty/cudd-2.5.0/mnemosyne/README | 39 + .../3rdparty/cudd-2.5.0/mnemosyne/mnemalyse.c | 197 + .../3rdparty/cudd-2.5.0/mnemosyne/mnemconf.h | 89 + .../3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.c | 670 + .../3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.h | 73 + .../3rdparty/cudd-2.5.0/mnemosyne/mtest.c | 38 + resources/3rdparty/cudd-2.5.0/mtr/Makefile | 96 + .../3rdparty/cudd-2.5.0/mtr/Makefile.sis | 83 + resources/3rdparty/cudd-2.5.0/mtr/doc/mtr.doc | 252 + .../cudd-2.5.0/mtr/doc/mtrAllAbs.html | 72 + .../cudd-2.5.0/mtr/doc/mtrAllDet.html | 317 + .../cudd-2.5.0/mtr/doc/mtrExtAbs.html | 72 + .../cudd-2.5.0/mtr/doc/mtrExtDet.html | 324 + resources/3rdparty/cudd-2.5.0/mtr/mtr.h | 187 + resources/3rdparty/cudd-2.5.0/mtr/mtrBasic.c | 450 + resources/3rdparty/cudd-2.5.0/mtr/mtrGroup.c | 877 + resources/3rdparty/cudd-2.5.0/mtr/mtrInt.h | 92 + resources/3rdparty/cudd-2.5.0/mtr/test.groups | 5 + resources/3rdparty/cudd-2.5.0/mtr/testmtr.c | 270 + .../3rdparty/cudd-2.5.0/nanotrav/C17.blif | 16 + .../3rdparty/cudd-2.5.0/nanotrav/C17.out | 101 + .../3rdparty/cudd-2.5.0/nanotrav/C880.blif | 770 + .../3rdparty/cudd-2.5.0/nanotrav/C880.out | 101 + .../3rdparty/cudd-2.5.0/nanotrav/Makefile | 98 + resources/3rdparty/cudd-2.5.0/nanotrav/README | 47 + resources/3rdparty/cudd-2.5.0/nanotrav/bnet.c | 2252 +++ resources/3rdparty/cudd-2.5.0/nanotrav/bnet.h | 187 + .../3rdparty/cudd-2.5.0/nanotrav/chkMterm.c | 235 + .../cudd-2.5.0/nanotrav/doc/bnetAllAbs.html | 45 + .../cudd-2.5.0/nanotrav/doc/bnetAllDet.html | 173 + .../cudd-2.5.0/nanotrav/doc/bnetExtAbs.html | 45 + .../cudd-2.5.0/nanotrav/doc/bnetExtDet.html | 173 + .../cudd-2.5.0/nanotrav/doc/ntrAllAbs.html | 114 + .../cudd-2.5.0/nanotrav/doc/ntrAllDet.html | 513 + .../cudd-2.5.0/nanotrav/doc/ntrExtAbs.html | 111 + .../cudd-2.5.0/nanotrav/doc/ntrExtDet.html | 500 + resources/3rdparty/cudd-2.5.0/nanotrav/main.c | 1394 ++ .../3rdparty/cudd-2.5.0/nanotrav/mult32a.blif | 745 + .../3rdparty/cudd-2.5.0/nanotrav/mult32a.out | 258 + .../3rdparty/cudd-2.5.0/nanotrav/nanotrav.1 | 379 + resources/3rdparty/cudd-2.5.0/nanotrav/ntr.c | 2988 +++ resources/3rdparty/cudd-2.5.0/nanotrav/ntr.h | 283 + .../3rdparty/cudd-2.5.0/nanotrav/ntrBddTest.c | 2315 +++ .../3rdparty/cudd-2.5.0/nanotrav/ntrHeap.c | 390 + .../3rdparty/cudd-2.5.0/nanotrav/ntrMflow.c | 1581 ++ .../3rdparty/cudd-2.5.0/nanotrav/ntrShort.c | 578 + .../3rdparty/cudd-2.5.0/nanotrav/ntrZddTest.c | 468 + .../3rdparty/cudd-2.5.0/nanotrav/rcn25.blif | 335 + .../3rdparty/cudd-2.5.0/nanotrav/rcn25.out | 521 + .../3rdparty/cudd-2.5.0/nanotrav/s27.blif | 30 + .../3rdparty/cudd-2.5.0/nanotrav/s27.out | 95 + resources/3rdparty/cudd-2.5.0/nanotrav/tst.sh | 9 + .../3rdparty/cudd-2.5.0/nanotrav/ucbqsort.c | 228 + resources/3rdparty/cudd-2.5.0/setup.sh | 18 + resources/3rdparty/cudd-2.5.0/shutdown.sh | 2 + .../3rdparty/cudd-2.5.0/sis/Makefile.sis | 97 + resources/3rdparty/cudd-2.5.0/sis/cuddBdd.h | 382 + .../3rdparty/cudd-2.5.0/sis/cuddBddPort.c | 1954 ++ resources/3rdparty/cudd-2.5.0/sis/cuddPwPt.c | 147 + resources/3rdparty/cudd-2.5.0/sis/st.c | 554 + resources/3rdparty/cudd-2.5.0/sis/st.h | 97 + resources/3rdparty/cudd-2.5.0/st/Makefile | 64 + .../3rdparty/cudd-2.5.0/st/doc/stAllAbs.html | 96 + .../3rdparty/cudd-2.5.0/st/doc/stAllDet.html | 462 + .../3rdparty/cudd-2.5.0/st/doc/stExtAbs.html | 96 + .../3rdparty/cudd-2.5.0/st/doc/stExtDet.html | 463 + resources/3rdparty/cudd-2.5.0/st/st.c | 1065 ++ resources/3rdparty/cudd-2.5.0/st/st.h | 232 + resources/3rdparty/cudd-2.5.0/util/Makefile | 64 + .../3rdparty/cudd-2.5.0/util/cpu_stats.c | 89 + resources/3rdparty/cudd-2.5.0/util/cpu_time.c | 76 + .../3rdparty/cudd-2.5.0/util/datalimit.c | 50 + .../3rdparty/cudd-2.5.0/util/pathsearch.c | 94 + resources/3rdparty/cudd-2.5.0/util/pipefork.c | 93 + resources/3rdparty/cudd-2.5.0/util/prtime.c | 21 + resources/3rdparty/cudd-2.5.0/util/ptime.c | 9 + resources/3rdparty/cudd-2.5.0/util/restart.c | 137 + resources/3rdparty/cudd-2.5.0/util/safe_mem.c | 97 + .../3rdparty/cudd-2.5.0/util/saveimage.c | 229 + resources/3rdparty/cudd-2.5.0/util/state.c | 82 + resources/3rdparty/cudd-2.5.0/util/strsav.c | 14 + resources/3rdparty/cudd-2.5.0/util/stub.c | 82 + resources/3rdparty/cudd-2.5.0/util/test-res.c | 57 + resources/3rdparty/cudd-2.5.0/util/test-sav.c | 39 + resources/3rdparty/cudd-2.5.0/util/texpand.c | 57 + resources/3rdparty/cudd-2.5.0/util/util.h | 204 + 321 files changed, 180452 insertions(+) create mode 100644 resources/3rdparty/cudd-2.5.0/LICENSE create mode 100644 resources/3rdparty/cudd-2.5.0/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/README create mode 100644 resources/3rdparty/cudd-2.5.0/RELEASE.NOTES create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cudd.h create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAPI.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddAbs.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddApply.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddFind.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddInv.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddIte.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddNeg.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddWalsh.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAndAbs.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAnneal.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddApa.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddApprox.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddBddAbs.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddBddCorr.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddBddIte.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddBridge.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddCache.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddCheck.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddClip.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddCof.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddCompose.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddDecomp.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddEssent.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddExact.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddExport.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddGenCof.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddGenetic.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddGroup.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddHarwell.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddInit.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddInt.h create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddInteract.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddLCache.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddLevelQ.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddLinear.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddLiteral.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddMatMult.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddPriority.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddRead.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddRef.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddReorder.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSat.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSign.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSolve.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSplit.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetHB.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetSP.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSymmetry.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddTable.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddUtil.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddWindow.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddCount.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddFuncs.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddGroup.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddIsop.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddLin.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddMisc.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddPort.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddReord.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddSetop.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddSymm.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddUtil.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.doc create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.ps create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFile.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFunc.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllFile.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddDesc.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExt.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.css create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddTitle.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/footnode.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/blueball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_beg_r.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_begin.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_del_r.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_delet.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_end.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_end_r.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/contents.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/crossref.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/footnote.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/greenball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/image.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/index.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/next.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/next_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/nx_grp.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/nx_grp_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/orangeball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/pinkball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/prev.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/prev_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/purpleball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/pv_grp.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/pv_grp_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/redball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/up.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/up_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/whiteball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/yellowball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img1.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img10.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img11.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img12.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img13.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img14.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img15.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img16.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img17.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img18.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img19.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img2.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img20.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img21.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img22.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img3.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img4.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img5.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img6.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img7.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img8.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img9.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/index.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node1.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node2.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node3.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node4.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node5.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node6.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node7.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node8.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.mat create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.out create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/testcudd.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/README.dddmp create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/README.testdddmp create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/RELEASE_NOTES create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmp.h create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpBinary.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpConvert.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpDbg.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeBdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeCnf.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpInt.h create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoad.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoadCnf.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeAdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeBdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeCnf.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreAdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreBdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreCnf.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreMisc.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpUtil.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/cmdIndex.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/commands.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/credit.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-A4.ps create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-Letter.ps create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFile.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFunc.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllFile.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDesc.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDoc.txt create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExt.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpTitle.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/packages.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/pkgIndex.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/0.add create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/0.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/0or1.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/1.add create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/1.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/2.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/2and3.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/3.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis1 create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis2 create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis3 create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis4 create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf.bis create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max1 create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max2 create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4bis.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4xor5.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/5.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/composeids.txt create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/one.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/s27RP1.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd.bis create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp2.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/varauxids.ord create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/varnames.ord create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/zero.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/testdddmp.c create mode 100644 resources/3rdparty/cudd-2.5.0/epd/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/epd/epd.c create mode 100644 resources/3rdparty/cudd-2.5.0/epd/epd.h create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/README create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/mnemalyse.c create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/mnemconf.h create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.c create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.h create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/mtest.c create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/Makefile.sis create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/doc/mtr.doc create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/mtr.h create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/mtrBasic.c create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/mtrGroup.c create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/mtrInt.h create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/test.groups create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/testmtr.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/C17.blif create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/C17.out create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/C880.blif create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/C880.out create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/README create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/bnet.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/bnet.h create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/chkMterm.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/main.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.blif create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.out create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/nanotrav.1 create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntr.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntr.h create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntrBddTest.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntrHeap.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntrMflow.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntrShort.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntrZddTest.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.blif create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.out create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/s27.blif create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/s27.out create mode 100755 resources/3rdparty/cudd-2.5.0/nanotrav/tst.sh create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ucbqsort.c create mode 100755 resources/3rdparty/cudd-2.5.0/setup.sh create mode 100755 resources/3rdparty/cudd-2.5.0/shutdown.sh create mode 100644 resources/3rdparty/cudd-2.5.0/sis/Makefile.sis create mode 100644 resources/3rdparty/cudd-2.5.0/sis/cuddBdd.h create mode 100644 resources/3rdparty/cudd-2.5.0/sis/cuddBddPort.c create mode 100644 resources/3rdparty/cudd-2.5.0/sis/cuddPwPt.c create mode 100644 resources/3rdparty/cudd-2.5.0/sis/st.c create mode 100644 resources/3rdparty/cudd-2.5.0/sis/st.h create mode 100644 resources/3rdparty/cudd-2.5.0/st/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/st/doc/stAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/st/doc/stAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/st/doc/stExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/st/doc/stExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/st/st.c create mode 100644 resources/3rdparty/cudd-2.5.0/st/st.h create mode 100644 resources/3rdparty/cudd-2.5.0/util/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/util/cpu_stats.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/cpu_time.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/datalimit.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/pathsearch.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/pipefork.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/prtime.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/ptime.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/restart.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/safe_mem.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/saveimage.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/state.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/strsav.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/stub.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/test-res.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/test-sav.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/texpand.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/util.h diff --git a/resources/3rdparty/cudd-2.5.0/LICENSE b/resources/3rdparty/cudd-2.5.0/LICENSE new file mode 100644 index 000000000..99c7fbae5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 1995-2004, Regents of the University of Colorado + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +Neither the name of the University of Colorado nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/resources/3rdparty/cudd-2.5.0/Makefile b/resources/3rdparty/cudd-2.5.0/Makefile new file mode 100644 index 000000000..e38ffa6ec --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/Makefile @@ -0,0 +1,321 @@ +# $Id$ +# +# Makefile for the CUDD distribution kit +#--------------------------------------------------------------------------- + +# Beginning of the configuration section. These symbol definitions can +# be overridden from the command line. + +# C++ compiler +CXX = g++ +#CXX = icpc +#CXX = ecpc +#CXX = CC +#CXX = /usr/local/opt/SUNWspro/bin/CC +#CXX = cxx + +# Specific options for compilation of C++ files. +CXXFLAGS = +# Stricter standard conformance for g++. +#CXXFLAGS = -std=c++98 +# For Sun CC version 5, this invokes compatibility mode. +#CXXFLAGS = -compat +# On some versions of UP-UX, it is necessary to pass the option +a1 +# to CC for the C++ test program to compile successfully. +#CXXFLAGS = +a1 + +# C compiler used for all targets except optimize_dec, which always uses cc. +#CC = cc +#CC = /usr/local/opt/SUNWspro/bin/cc +CC = gcc +#CC = icc +#CC = ecc +#CC = /usr/ucb/cc +#CC = c89 +#CC = $(CXX) + +# On some machines ranlib is either non-existent or redundant. +# Use the following definition if your machine has ranlib and you think +# it is needed. +RANLIB = ranlib +# Use the following definition if your machine either does not have +# ranlib (e.g., SUN running solaris) or can do without it (e.g., DEC Alpha). +#RANLIB = : + +# Use ICFLAGS to specify machine-independent compilation flags. +# These three are typical settings for cc. +#ICFLAGS = -g +#ICFLAGS = -O +#ICFLAGS = +# These two are typical settings for optimized code with gcc. +#ICFLAGS = -g -O3 -Wall +ICFLAGS = -g -O3 + +# Use XCFLAGS to specify machine-dependent compilation flags. +# For some platforms no special flags are needed. +#XCFLAGS = -DHAVE_IEEE_754 -DBSD +# +#========================== +# Linux +# +# Gcc 4.2.4 or higher on i686. +XCFLAGS = -mtune=native -malign-double -DHAVE_IEEE_754 -DBSD +# Gcc 3.2.2 or higher on i686. +#XCFLAGS = -mtune=pentium4 -malign-double -DHAVE_IEEE_754 -DBSD +# Gcc 2.8.1 on i686. +#XCFLAGS = -mcpu=pentiumpro -malign-double -DHAVE_IEEE_754 -DBSD +# Gcc 4.2.4 or higher on x86_64 (64-bit compilation) +#XCFLAGS = -mtune=native -DHAVE_IEEE_754 -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# Gcc 4.2.4 or higher on x86_64 (32-bit compilation) +#XCFLAGS = -m32 -mtune=native -malign-double -DHAVE_IEEE_754 -DBSD +# Icc on i686 (older versions may not support -xHost). +#XCFLAGS = -ansi -xHost -align -ip -DHAVE_IEEE_754 -DBSD +# Icc on x86_64 (64-bit compilation). +#XCFLAGS = -ansi -xHost -align -ip -DHAVE_IEEE_754 -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# Gcc on ia64. +#XCFLAGS = -DHAVE_IEEE_754 -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# Icc/ecc on ia64. +#XCFLAGS = -ansi -DBSD -DHAVE_IEEE_754 -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# +#========================== +# Solaris +# +# For Solaris, BSD should not be replaced by UNIX100. +#XCFLAGS = -DHAVE_IEEE_754 -DUNIX100 -DEPD_BIG_ENDIAN +# Gcc 2.8.1 or higher on Ultrasparc. +#XCFLAGS = -mcpu=ultrasparc -DHAVE_IEEE_754 -DUNIX100 -DEPD_BIG_ENDIAN +# For Solaris 2.5 and higher, optimized code with /usr/bin/cc or CC. +#XCFLAGS = -DHAVE_IEEE_754 -DUNIX100 -xO5 -native -dalign -DEPD_BIG_ENDIAN +# On IA platforms, -dalign is not supported and causes warnings. +#XCFLAGS = -DHAVE_IEEE_754 -DUNIX100 -xO5 -native +# Recent Sun compilers won't let you use -native on old Ultras. +#XCFLAGS = -DHAVE_IEEE_754 -DUNIX100 -xO5 -dalign -xlibmil -DEPD_BIG_ENDIAN +# For Solaris 2.4, optimized code with /usr/bin/cc. +#XCFLAGS = -DHAVE_IEEE_754 -DUNIX100 -xO4 -dalign -DEPD_BIG_ENDIAN +# For Solaris 2.5 and higher, optimized code with /usr/ucb/cc. +#XCFLAGS = -DHAVE_IEEE_754 -DBSD -xO5 -native -dalign -DEPD_BIG_ENDIAN +#XCFLAGS = -DHAVE_IEEE_754 -DBSD -xO5 -dalign -xlibmil -DEPD_BIG_ENDIAN +# For Solaris 2.4, optimized code with /usr/ucb/cc. +#XCFLAGS = -DHAVE_IEEE_754 -DBSD -xO4 -dalign -DEPD_BIG_ENDIAN +# +#========================== +# DEC Alphas running Digital Unix +# +# For DEC Alphas either -ieee_with_inexact or -ieee_with_no_inexact is +# needed. If you use only BDDs, -ieee_with_no_inexact is enough. +# In the following, we consider three different compilers: +# - the old native compiler (the one of MIPS ancestry that produces u-code); +# - the new native compiler; +# - gcc +# On the Alphas, gcc (as of release 2.7.2) does not support 32-bit pointers +# and IEEE 754 floating point arithmetic. Therefore, for this architecture +# only, the native compilers provide a substatial advantage. +# With the native compilers, specify -xtaso for 32-bit pointers. +# Do not use -xtaso_short because explicit reference to stdout and stderr +# does not work with this option. (Among other things.) +# Notice that -taso must be included in LDFLAGS for -xtaso to work. +# Given the number of possible choices, only some typical configurations +# are proposed here. +# +# Old native compiler for the Alphas; 64-bit pointers. +#XCFLAGS = -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# Old native compiler for the Alphas; 32-bit pointers. +#XCFLAGS = -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -xtaso -DSIZEOF_LONG=8 +# New native compiler for the Alphas; 64-bit pointers. +#XCFLAGS = -g3 -O4 -std -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# New native compiler for the Alphas; 32-bit pointers. +#XCFLAGS = -g3 -O4 -std -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -xtaso -DSIZEOF_LONG=8 +# gcc for the Alphas: compile without HAVE_IEEE_754. +#XCFLAGS = -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# +#========================== +# +# IBM RS6000 +# +# For the IBM RS6000 -qstrict is necessary when specifying -O3 with cc. +#XCFLAGS = -DBSD -DHAVE_IEEE_754 -DEPD_BIG_ENDIAN -O3 -qstrict +# +#========================== +# +# HP-UX +# +# I haven't figured out how to enable IEEE 754 on the HPs I've tried... +# For HP-UX using gcc. +#XCFLAGS = -DUNIX100 -DEPD_BIG_ENDIAN +# For HP-UX using c89. +#XCFLAGS = +O3 -DUNIX100 -DEPD_BIG_ENDIAN +# +#========================== +# +# Windows 95/98/NT/XP/Vista/7 with Cygwin tools +# +# The value of RLIMIT_DATA_DEFAULT should reflect the amount of +# available memory (expressed in bytes). +# Recent versions of cygwin have getrlimit, but the datasize limit +# cannot be set. +#XCFLAGS = -mtune=native -malign-double -DHAVE_IEEE_754 -DHAVE_GETRLIMIT=0 -DRLIMIT_DATA_DEFAULT=268435456 + + +# Define the level of self-checking and verbosity of the CUDD package. +#DDDEBUG = -DDD_DEBUG -DDD_VERBOSE -DDD_STATS -DDD_CACHE_PROFILE -DDD_UNIQUE_PROFILE -DDD_COUNT +DDDEBUG = + +# Define the level of self-checking and verbosity of the MTR package. +#MTRDEBUG = -DMTR_DEBUG +MTRDEBUG = + +# Loader options. +LDFLAGS = +# This may produce faster code on the DECstations. +#LDFLAGS = -jmpopt -Olimit 1000 +# This may be necessary under some old versions of Linux. +#LDFLAGS = -static +# This normally makes the program faster on the DEC Alphas. +#LDFLAGS = -non_shared -om +# This is for 32-bit pointers on the DEC Alphas. +#LDFLAGS = -non_shared -om -taso +#LDFLAGS = -non_shared -taso + +# Define PURE as purify to link with purify. +# Define PURE as quantify to link with quantify. +# Remember to compile with -g if you want line-by-line info with quantify. +PURE = +#PURE = purify +#PURE = quantify + +# Define EXE as .exe for MS-DOS and derivatives. Not required by recent +# versions of cygwin. +EXE = +#EXE = .exe + +# End of the configuration section. +#--------------------------------------------------------------------------- + +MFLAG = -DMNEMOSYNE +MNEMLIB = ../mnemosyne/libmnem.a + +DDWDIR = . +IDIR = $(DDWDIR)/include +INCLUDE = -I$(IDIR) + +BDIRS = cudd dddmp mtr st util epd +DIRS = $(BDIRS) nanotrav + +#------------------------------------------------------------------------ + +.PHONY : build +.PHONY : nanotrav +.PHONY : check_leaks +.PHONY : optimize_dec +.PHONY : testcudd +.PHONY : libobj +.PHONY : testobj +.PHONY : testdddmp +.PHONY : testmtr +.PHONY : lint +.PHONY : all +.PHONY : clean +.PHONY : distclean + + +build: + sh ./setup.sh + @for dir in $(DIRS); do \ + (cd $$dir; \ + echo Making $$dir ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" )\ + done + +nanotrav: build + +check_leaks: + sh ./setup.sh + @for dir in mnemosyne $(DIRS); do \ + (cd $$dir; \ + echo Making $$dir ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG=$(MFLAG) MNEMLIB=$(MNEMLIB) ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" EXE="$(EXE)" )\ + done + +optimize_dec: + sh ./setup.sh + @for dir in $(DIRS); do \ + (cd $$dir; \ + echo Making $$dir ...; \ + make CC=$(CC) RANLIB=$(RANLIB) XCFLAGS="$(XCFLAGS)" LDFLAGS="$(LDFLAGS)" optimize_dec )\ + done + +lint: + sh ./setup.sh + @for dir in $(DIRS) obj; do \ + (cd $$dir; \ + echo Making lint in $$dir ...; \ + make CC=$(CC) lint )\ + done + +tags: + sh ./setup.sh + @for dir in $(DIRS) obj; do \ + (cd $$dir; \ + echo Making tags in $$dir ...; \ + make CC=$(CC) tags )\ + done + +all: + sh ./setup.sh + @for dir in $(DIRS); do \ + (cd $$dir; \ + echo Making all in $$dir ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" all )\ + done + +testcudd: + sh ./setup.sh + @for dir in util st mtr epd; do \ + (cd $$dir; \ + echo Making $$dir ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" )\ + done + @(cd cudd; \ + echo Making testcudd ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" testcudd$(EXE) ) + +objlib: + sh ./setup.sh + @for dir in $(BDIRS); do \ + (cd $$dir; \ + echo Making $$dir ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" )\ + done + @(cd obj; \ + echo Making obj ...; \ + make CXX=$(CXX) CXXFLAGS=$(CXXFLAGS) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" ) + +testobj: objlib + @(cd obj; \ + echo Making testobj ...; \ + make CXX=$(CXX) CXXFLAGS=$(CXXFLAGS) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" testobj$(EXE) ) + +testdddmp: build + @(cd dddmp; \ + echo Making testdddmp ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" testdddmp$(EXE) ) + +testmtr: build + @(cd mtr; \ + echo Making testmtr ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" testmtr$(EXE) ) + +clean: + @for dir in mnemosyne $(DIRS) obj; do \ + (cd $$dir; \ + echo Cleaning $$dir ...; \ + make -s clean ) \ + done + +distclean: + @for dir in mnemosyne $(DIRS) obj; do \ + (cd $$dir; \ + echo Cleaning $$dir ...; \ + make -s EXE="$(EXE)" distclean ) \ + done + sh ./shutdown.sh diff --git a/resources/3rdparty/cudd-2.5.0/README b/resources/3rdparty/cudd-2.5.0/README new file mode 100644 index 000000000..864a416f9 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/README @@ -0,0 +1,177 @@ +$Id$ + +This directory contains a set of packages that allow you to build a toy +application based on the CUDD package. + +The CUDD package is a package written in C for the manipulation of +decision diagrams. It supports binary decision diagrams (BDDs), +algebraic decision diagrams (ADDs), and Zero-Suppressed BDDs (ZDDs). + +The toy application provided in this kit is called nanotrav and is a +simple-minded FSM traversal program. (See the README file and the man +page nanotrav.1 in the nanotrav directory for the details.) It is +included so that you can run a sanity check on your installation. + +INSTALLATION + +Before you build the libraries and programs, you need to check the +Makefile in the top directory. Go through the definitions contained in the +configuration section, and select the desired compiler and compilation +flags. Instructions are provided in the comments of the Makefile. + +You can always specify the options on the command line. For instance, +on some machines you can build a "fast" version of the program by typing: + + make DDDEBUG= MTRDEBUG= ICFLAGS=-O2 + +The Makefile supports several targets: + + make: + Creates a "plain" version of the program. + + make testdddmp: + Builds a test program (testdddmp) for BDD loading from and + storing to disk. See file README.test in the dddmp directory for + how to run the program. + + make testobj: + Builds a test program for the C++ interface. Requires a C++ + compiler. To run the program, run obj/testobj. + + make testcudd: + Builds a test program for CUDD. To run the program, go to the + cudd directory and type "./testcudd -p 2 r7x8.1.mat". The result + can be compared to r7x7.1.out. + + make testmtr: + Builds a test program for the mtr package. To run the program, + go to the mtr directory and type "./testmtr -p 1 test.groups". + + make clean: + Cleans directories, but leaves libraries and programs. + + make distclean: + Cleans thoroughly, returning the directories to their pristine + state. + +The following targets are more or less obsolete and may disappear or +change in the future. + + make check_leaks: + Creates a version of the program with the mnemosyne library + linked to it. It also builds the mnemalyse program, which + helps in finding memory leaks. This target does not work on the + IBM RS6000. The makefile also supports purify. To use purify, + set the PURE variable in the Makefile, and use the standard + target. + + make optimize_dec: + Builds a version of the program using the u-code compiler + available on DEC machines (DECstations and Alphas). The newer + native compiler on the Alphas does not use u-code, though. + Therefore the standard target should be used with it. + + make lint: + Runs lint on all subdirectories except mnemosyne. Creates lint + libraries for all object libraries. + + make tags: + Builds ctags-style tag files for all subdirectories except + mnemosyne. + + make all: + Makes all of the above, except check_leaks, which is + incompatible with a plain "make." + +All targets, except clean and distclean, will create the include +directory if it does not already exist. + +The Makefile does not compile the SIS interface (cuddBddPort.c and +cuddPwPt.c found in subdirectory sis). To compile the interface, you +also need array.h and var_set.h, which are not part of this +distribution, but come with SIS. Detailed instructions on how to +integrate the CUDD package in SIS can be found in the documentation +(cudd/doc). + +PLATFORMS + +This kit has been successfully built on the following configurations: + + PC (ia32 and ia64) running Ubuntu with gcc + PC (ia32 and ia64) running Ubuntu with g++ + PC (ia32 and ia64) running Linux RedHat with gcc + PC (ia32 and ia64) running Linux RedHat with g++ + PC (ia64) running Cygwin on Windows 7 and Vista with gcc + PC (ia64) running Cygwin on Windows 7 and Vista with g++ + +Platforms to which I have no longer access and therefore are no longer +supported. + + PC (ia32) running Linux RedHat with icc + PC (ia32) running Linux RedHat with icpc + PC (ia64) running Linux RedHat with ecc + PC (ia64) running Linux RedHat with ecpc + SUN running Solaris 2.8 with cc + SUN running Solaris 2.8 with CC + SUN running Solaris 2.8 with gcc + SUN running Solaris 2.8 with g++ + DECstation running Ultrix with cc + DECstation running Ultrix with gcc + IBM RS6000 running AIX 3.2.4 with cc (**) + IBM RS6000 running AIX 3.2.4 with gcc + IBM RS6000 running AIX 3.2.4 with g++ + SUN running SunOS with gcc + DEC Alpha running Digital Unix with cc + DEC Alpha running Digital Unix with cxx + DEC Alpha running Digital Unix with gcc + HP 9000/770 running HP-UX with c89 + HP 9000/770 running HP-UX with CC + HP 9000/770 running HP-UX with gcc + HP 9000/770 running HP-UX with g++ (*) + SUN running Solaris 2.8 with /usr/ucb/cc + PC running Solaris 2.8 with /usr/bin/cc + PC running Solaris 2.8 with /usr/ucb/cc + PC running Solaris 2.8 with CC + PC running Solaris 2.8 with gcc + PC running Solaris 2.8 with g++ + +NOTES + (*) C programs were compiled with g++, but linked with gcc. + + (**) Some old versions of the AIX cc compiler have buggy optimizers: + Try compiling with -O2 instead of -O3 if the program crashes. + +Running lint and compiling with gcc -Wall still produces warnings. +Running `purify' under Solaris 2.8 generates no messages. + +SANITY CHECK + +The directory `nanotrav' contains a very simple application based on the +CUDD package. The `nanotrav' directory contains a man page that +describes the options nanotrav supports. The files *.blif are sample +input files for nanotrav. + +If you have built the mnemosyne library (make check_leaks), you can do + cd mnemosyne + make runmtest +This does not work on machines running SunOS, but the version of +nanotrav that uses mnemosyne may work. + +DOCUMENTATION + +Directory cudd-2.5.0/cudd/doc contains HTML documentation for the CUDD +package. The recommended starting point is cuddIntro.html. Documentation +in both postscript(tm) format and plain text format is also provided. +Documentation for the auxiliary libraries (except for the util library) +is in the doc subdirectories. + +FEEDBACK: + +Send feedback to: + +Fabio Somenzi +University of Colorado at Boulder +ECE Dept. +Boulder, CO 80309-0425 +Fabio@Colorado.EDU +http://vlsi.colorado.edu/~fabio diff --git a/resources/3rdparty/cudd-2.5.0/RELEASE.NOTES b/resources/3rdparty/cudd-2.5.0/RELEASE.NOTES new file mode 100644 index 000000000..22867e568 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/RELEASE.NOTES @@ -0,0 +1,131 @@ +Release 2.5.0 of Cudd introduces the ability to set timeouts. The +function that is interrupted returns NULL (which the application must +be prepared to handle,) but the BDDs are uncorrupted and the invoking +program can continue to use the manager. + +In addition, reordering is now aware of timeouts, so that it gives up +when a timeout is approaching to give the invoking program a chance to +obtain some results. + +The response time to the timeout is not immediate, though most of the time +it is well below one second. Checking for timeouts has a small overhead. +In experiments, less than 1% has been observed on average. + +Creation of BDD managers with many variables (e.g., tens or hundreds +of thousands) is now much more efficient. Computing small supports of +BDDs when there are many variables is also much more efficient, but +this has been at the cost of separating the function for BDDs and ADDs +(Cudd_Support) from that for ZDDs (Cudd_zddSupport). + +The C++ interface has undergone a major upgrade. + +The handling of variable gruops in reordering has been much improved. +(Thanks to Arie Gurfinkel for a very detailed bug report!) A handful +of other bugs have been fixed as well. + + +New Functions: + +unsigned long Cudd_ReadStartTime(DdManager *unique); + +unsigned long Cudd_ReadElapsedTime(DdManager *unique); + +void Cudd_SetStartTime(DdManager *unique, unsigned long st); + +void Cudd_ResetStartTime(DdManager *unique); + +unsigned long Cudd_ReadTimeLimit(DdManager *unique); + +void Cudd_SetTimeLimit(DdManager *unique, unsigned long tl); + +void Cudd_UpdateTimeLimit(DdManager * unique); + +void Cudd_IncreaseTimeLimit(DdManager * unique, unsigned long increase); + +void Cudd_UnsetTimeLimit(DdManager *unique); + +int Cudd_TimeLimited(DdManager *unique); + +unsigned int Cudd_ReadMaxReorderings (DdManager *dd); + +void Cudd_SetMaxReorderings (DdManager *dd, unsigned int mr); + +unsigned int Cudd_ReadOrderRandomization(DdManager * dd); + +void Cudd_SetOrderRandomization(DdManager * dd, unsigned int factor); + +int Cudd_PrintGroupedOrder(DdManager * dd, const char *str, void *data); + +int Cudd_EnableOrderingMonitoring(DdManager *dd); + +int Cudd_DisableOrderingMonitoring(DdManager *dd); + +int Cudd_OrderingMonitoring(DdManager *dd); + +DdNode * Cudd_bddExistAbstractLimit(DdManager * manager, DdNode * f, DdNode * cube, unsigned int limit); + +DdNode * Cudd_bddIteLimit (DdManager *dd, DdNode *f, DdNode *g, DdNode *h, unsigned int limit); + +DdNode * Cudd_bddOrLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); + +DdNode * Cudd_bddXnorLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); + +int Cudd_CheckCube (DdManager *dd, DdNode *g); + +DdNode * Cudd_bddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f); + +DdNode * Cudd_bddLargestPrimeUnate(DdManager *dd , DdNode *f, DdNode *phaseBdd); + +int Cudd_Reserve(DdManager *manager, int amount); + +int Cudd_SupportIndices(DdManager * dd, DdNode * f, int **indices); + +int Cudd_VectorSupportIndices(DdManager * dd, DdNode ** F, int n, int **indices); + +DdNode * Cudd_zddSupport(DdManager * dd, DdNode * f); + + +Changed prototypes: + +unsigned int Cudd_ReadReorderings (DdManager *dd); + +---------------------------------------------------------------------- + +Release 2.4.2 of Cudd features several bug fixes. The most important +are those that prevented Cudd from making full use of up to 4 GB of +memory when using 32-bit pointers. A handful of bugs were discovered by +Coverity. (Thanks to Christian Stangier!) + +This release can be compiled with either 64-bit pointers or 32-bit +pointers on x86_64 platforms if sizeof(long) = sizeof(void *) = 8 and +sizeof(int) = 4. This is known as the LP64 model. For 32-bit pointers, +one usually needs supplementary libraries. On Ubuntu and Debian Linux, +one needs g++-multilib, which can be installed with +"apt-get install g++-multilib." + +Added functions + +DdNode *Cudd_Inequality (DdManager * dd, int N, int c, DdNode ** x, +DdNode ** y); + +DdNode * Cudd_Disequality (DdManager * dd, int N, int c, DdNode ** x, +DdNode ** y); + +DdNode * Cudd_bddInterval (DdManager * dd, int N, DdNode ** x, +unsigned int lowerB, unsigned int upperB); + +Changed prototypes: + +int Cudd_DumpBlif (DdManager *dd, int n, DdNode **f, char +**inames, char **onames, char *mname, FILE *fp, int mv); + +int Cudd_DumpBlifBody (DdManager *dd, int n, DdNode **f, char +**inames, char **onames, FILE *fp, int mv); + +The additional parameter allows the caller to choose between plain blif +and blif-MV. + +---------------------------------------------------------------------- + +Release 2.4.1 of Cudd features one major change with respect to previous +releases. The licensing terms are now explicitly stated. diff --git a/resources/3rdparty/cudd-2.5.0/cudd/Makefile b/resources/3rdparty/cudd-2.5.0/cudd/Makefile new file mode 100644 index 000000000..d76954746 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/Makefile @@ -0,0 +1,124 @@ +# $Id$ +# +# Cudd - DD package +#--------------------------- +.SUFFIXES: .o .c .u + +CC = gcc +RANLIB = ranlib +PURE = +# Define EXE as .exe for MS-DOS and derivatives. +EXE = +#EXE = .exe + +MFLAG = +ICFLAGS = -g +XCFLAGS = -DDD_STATS +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) +#DDDEBUG = -DDD_DEBUG -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_UNIQUE_PROFILE +DDDEBUG = + +LINTFLAGS = -u -n -DDD_STATS -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_DEBUG -DDD_UNIQUE_PROFILE + +# this is to create the lint library +LINTSWITCH = -o + +WHERE = .. + +INCLUDE = $(WHERE)/include + +LIBS = ./libcudd.a $(WHERE)/mtr/libmtr.a \ + $(WHERE)/st/libst.a $(WHERE)/util/libutil.a $(WHERE)/epd/libepd.a + +MNEMLIB = + +BLIBS = -kL. -klcudd -kL$(WHERE)/mtr -klmtr \ + -kL$(WHERE)/st -klst -kL$(WHERE)/util -klutil -kL$(WHERE)/epd -klepd + +LINTLIBS = ./llib-lcudd.ln $(WHERE)/mtr/llib-lmtr.ln \ + $(WHERE)/st/llib-lst.ln $(WHERE)/util/llib-lutil.ln \ + $(WHERE)/epd/llib-lepd.ln + +LDFLAGS = + +# files for the package +P = cudd +PSRC = cuddAPI.c cuddAddAbs.c cuddAddApply.c cuddAddFind.c cuddAddIte.c \ + cuddAddInv.c cuddAddNeg.c cuddAddWalsh.c cuddAndAbs.c \ + cuddAnneal.c cuddApa.c cuddApprox.c cuddBddAbs.c cuddBddCorr.c \ + cuddBddIte.c cuddBridge.c cuddCache.c cuddCheck.c cuddClip.c \ + cuddCof.c cuddCompose.c cuddDecomp.c cuddEssent.c \ + cuddExact.c cuddExport.c cuddGenCof.c cuddGenetic.c \ + cuddGroup.c cuddHarwell.c cuddInit.c cuddInteract.c \ + cuddLCache.c cuddLevelQ.c \ + cuddLinear.c cuddLiteral.c cuddMatMult.c cuddPriority.c \ + cuddRead.c cuddRef.c cuddReorder.c cuddSat.c cuddSign.c \ + cuddSolve.c cuddSplit.c cuddSubsetHB.c cuddSubsetSP.c cuddSymmetry.c \ + cuddTable.c cuddUtil.c cuddWindow.c cuddZddCount.c cuddZddFuncs.c \ + cuddZddGroup.c cuddZddIsop.c cuddZddLin.c cuddZddMisc.c \ + cuddZddPort.c cuddZddReord.c cuddZddSetop.c cuddZddSymm.c \ + cuddZddUtil.c +PHDR = cudd.h cuddInt.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +TARGET = test$(P)$(EXE) +TARGETu = test$(P)-u + +# files for the test program +SRC = test$(P).c +OBJ = $(SRC:.c=.o) +UBJ = $(SRC:.c=.u) + +#------------------------------------------------------ + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PSRC) $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) $(DDDEBUG) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) +$(OBJ): $(PHDR) +$(UBJ): $(PHDR) + +$(TARGET): $(SRC) $(OBJ) $(HDR) $(LIBS) $(MNEMLIB) + $(PURE) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +# optimize (DECstations and Alphas only: uses u-code) +$(TARGETu): $(SRC) $(UBJ) $(HDR) $(LIBS:.a=.b) + $(CC) -O3 -Olimit 1000 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +lintpgm: lint + lint $(LINTFLAGS) -I$(INCLUDE) $(SRC) $(LINTLIBS) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +programs: $(TARGET) $(TARGETu) lintpgm + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \ + *.bak *~ tags .gdb_history *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cudd.h b/resources/3rdparty/cudd-2.5.0/cudd/cudd.h new file mode 100644 index 000000000..4a54f8e05 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cudd.h @@ -0,0 +1,1070 @@ +/**CHeaderFile***************************************************************** + + FileName [cudd.h] + + PackageName [cudd] + + Synopsis [The University of Colorado decision diagram package.] + + Description [External functions and data strucures of the CUDD package. +
    +
  • To turn on the gathering of statistics, define DD_STATS. +
  • To link with mis, define DD_MIS. +
+ Modified by Abelardo Pardo to interface it to VIS. + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: cudd.h,v 1.180 2012/02/05 01:07:18 fabio Exp $] + +******************************************************************************/ + +#ifndef _CUDD +#define _CUDD + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include "mtr.h" +#include "epd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define CUDD_VERSION "2.5.0" + +#ifndef SIZEOF_VOID_P +#define SIZEOF_VOID_P 4 +#endif +#ifndef SIZEOF_INT +#define SIZEOF_INT 4 +#endif +#ifndef SIZEOF_LONG +#define SIZEOF_LONG 4 +#endif + +#define CUDD_TRUE 1 +#define CUDD_FALSE 0 + +#define CUDD_VALUE_TYPE double +#define CUDD_OUT_OF_MEM -1 +/* The sizes of the subtables and the cache must be powers of two. */ +#define CUDD_UNIQUE_SLOTS 256 /* initial size of subtables */ +#define CUDD_CACHE_SLOTS 262144 /* default size of the cache */ + +/* Constants for residue functions. */ +#define CUDD_RESIDUE_DEFAULT 0 +#define CUDD_RESIDUE_MSB 1 +#define CUDD_RESIDUE_TC 2 + +/* CUDD_MAXINDEX is defined in such a way that on 32-bit and 64-bit +** machines one can cast an index to (int) without generating a negative +** number. +*/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define CUDD_MAXINDEX (((DdHalfWord) ~0) >> 1) +#else +#define CUDD_MAXINDEX ((DdHalfWord) ~0) +#endif + +/* CUDD_CONST_INDEX is the index of constant nodes. Currently this +** is a synonim for CUDD_MAXINDEX. */ +#define CUDD_CONST_INDEX CUDD_MAXINDEX + +/* These constants define the digits used in the representation of +** arbitrary precision integers. The configurations tested use 8, 16, +** and 32 bits for each digit. The typedefs should be in agreement +** with these definitions. +*/ +#if SIZEOF_LONG == 8 +#define DD_APA_BITS 32 +#define DD_APA_BASE (1L << DD_APA_BITS) +#define DD_APA_HEXPRINT "%08x" +#else +#define DD_APA_BITS 16 +#define DD_APA_BASE (1 << DD_APA_BITS) +#define DD_APA_HEXPRINT "%04x" +#endif +#define DD_APA_MASK (DD_APA_BASE - 1) + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/**Enum************************************************************************ + + Synopsis [Type of reordering algorithm.] + + Description [Type of reordering algorithm.] + +******************************************************************************/ +typedef enum { + CUDD_REORDER_SAME, + CUDD_REORDER_NONE, + CUDD_REORDER_RANDOM, + CUDD_REORDER_RANDOM_PIVOT, + CUDD_REORDER_SIFT, + CUDD_REORDER_SIFT_CONVERGE, + CUDD_REORDER_SYMM_SIFT, + CUDD_REORDER_SYMM_SIFT_CONV, + CUDD_REORDER_WINDOW2, + CUDD_REORDER_WINDOW3, + CUDD_REORDER_WINDOW4, + CUDD_REORDER_WINDOW2_CONV, + CUDD_REORDER_WINDOW3_CONV, + CUDD_REORDER_WINDOW4_CONV, + CUDD_REORDER_GROUP_SIFT, + CUDD_REORDER_GROUP_SIFT_CONV, + CUDD_REORDER_ANNEALING, + CUDD_REORDER_GENETIC, + CUDD_REORDER_LINEAR, + CUDD_REORDER_LINEAR_CONVERGE, + CUDD_REORDER_LAZY_SIFT, + CUDD_REORDER_EXACT +} Cudd_ReorderingType; + + +/**Enum************************************************************************ + + Synopsis [Type of aggregation methods.] + + Description [Type of aggregation methods.] + +******************************************************************************/ +typedef enum { + CUDD_NO_CHECK, + CUDD_GROUP_CHECK, + CUDD_GROUP_CHECK2, + CUDD_GROUP_CHECK3, + CUDD_GROUP_CHECK4, + CUDD_GROUP_CHECK5, + CUDD_GROUP_CHECK6, + CUDD_GROUP_CHECK7, + CUDD_GROUP_CHECK8, + CUDD_GROUP_CHECK9 +} Cudd_AggregationType; + + +/**Enum************************************************************************ + + Synopsis [Type of hooks.] + + Description [Type of hooks.] + +******************************************************************************/ +typedef enum { + CUDD_PRE_GC_HOOK, + CUDD_POST_GC_HOOK, + CUDD_PRE_REORDERING_HOOK, + CUDD_POST_REORDERING_HOOK +} Cudd_HookType; + + +/**Enum************************************************************************ + + Synopsis [Type of error codes.] + + Description [Type of error codes.] + +******************************************************************************/ +typedef enum { + CUDD_NO_ERROR, + CUDD_MEMORY_OUT, + CUDD_TOO_MANY_NODES, + CUDD_MAX_MEM_EXCEEDED, + CUDD_TIMEOUT_EXPIRED, + CUDD_INVALID_ARG, + CUDD_INTERNAL_ERROR +} Cudd_ErrorType; + + +/**Enum************************************************************************ + + Synopsis [Group type for lazy sifting.] + + Description [Group type for lazy sifting.] + +******************************************************************************/ +typedef enum { + CUDD_LAZY_NONE, + CUDD_LAZY_SOFT_GROUP, + CUDD_LAZY_HARD_GROUP, + CUDD_LAZY_UNGROUP +} Cudd_LazyGroupType; + + +/**Enum************************************************************************ + + Synopsis [Variable type.] + + Description [Variable type. Currently used only in lazy sifting.] + +******************************************************************************/ +typedef enum { + CUDD_VAR_PRIMARY_INPUT, + CUDD_VAR_PRESENT_STATE, + CUDD_VAR_NEXT_STATE +} Cudd_VariableType; + + +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +typedef unsigned int DdHalfWord; +#else +typedef unsigned short DdHalfWord; +#endif + +typedef struct DdNode DdNode; + +typedef struct DdChildren { + struct DdNode *T; + struct DdNode *E; +} DdChildren; + +/* The DdNode structure is the only one exported out of the package */ +struct DdNode { + DdHalfWord index; + DdHalfWord ref; /* reference count */ + DdNode *next; /* next pointer for unique table */ + union { + CUDD_VALUE_TYPE value; /* for constant nodes */ + DdChildren kids; /* for internal nodes */ + } type; +}; + +typedef struct DdManager DdManager; + +typedef struct DdGen DdGen; + +/* These typedefs for arbitrary precision arithmetic should agree with +** the corresponding constant definitions above. */ +#if SIZEOF_LONG == 8 +typedef unsigned int DdApaDigit; +typedef unsigned long int DdApaDoubleDigit; +#else +typedef unsigned short int DdApaDigit; +typedef unsigned int DdApaDoubleDigit; +#endif +typedef DdApaDigit * DdApaNumber; + +/* Return type for function computing two-literal clauses. */ +typedef struct DdTlcInfo DdTlcInfo; + +/* Type of hook function. */ +typedef int (*DD_HFP)(DdManager *, const char *, void *); +/* Type of priority function */ +typedef DdNode * (*DD_PRFP)(DdManager * , int, DdNode **, DdNode **, + DdNode **); +/* Type of apply operator. */ +typedef DdNode * (*DD_AOP)(DdManager *, DdNode **, DdNode **); +/* Type of monadic apply operator. */ +typedef DdNode * (*DD_MAOP)(DdManager *, DdNode *); +/* Types of cache tag functions. */ +typedef DdNode * (*DD_CTFP)(DdManager *, DdNode *, DdNode *); +typedef DdNode * (*DD_CTFP1)(DdManager *, DdNode *); +/* Type of memory-out function. */ +typedef void (*DD_OOMFP)(long); +/* Type of comparison function for qsort. */ +typedef int (*DD_QSFP)(const void *, const void *); + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if the node is a constant node.] + + Description [Returns 1 if the node is a constant node (rather than an + internal node). All constant nodes have the same index + (CUDD_CONST_INDEX). The pointer passed to Cudd_IsConstant may be either + regular or complemented.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define Cudd_IsConstant(node) ((Cudd_Regular(node))->index == CUDD_CONST_INDEX) + + +/**Macro*********************************************************************** + + Synopsis [Complements a DD.] + + Description [Complements a DD by flipping the complement attribute of + the pointer (the least significant bit).] + + SideEffects [none] + + SeeAlso [Cudd_NotCond] + +******************************************************************************/ +#define Cudd_Not(node) ((DdNode *)((long)(node) ^ 01)) + + +/**Macro*********************************************************************** + + Synopsis [Complements a DD if a condition is true.] + + Description [Complements a DD if condition c is true; c should be + either 0 or 1, because it is used directly (for efficiency). If in + doubt on the values c may take, use "(c) ? Cudd_Not(node) : node".] + + SideEffects [none] + + SeeAlso [Cudd_Not] + +******************************************************************************/ +#define Cudd_NotCond(node,c) ((DdNode *)((long)(node) ^ (c))) + + +/**Macro*********************************************************************** + + Synopsis [Returns the regular version of a pointer.] + + Description [] + + SideEffects [none] + + SeeAlso [Cudd_Complement Cudd_IsComplement] + +******************************************************************************/ +#define Cudd_Regular(node) ((DdNode *)((unsigned long)(node) & ~01)) + + +/**Macro*********************************************************************** + + Synopsis [Returns the complemented version of a pointer.] + + Description [] + + SideEffects [none] + + SeeAlso [Cudd_Regular Cudd_IsComplement] + +******************************************************************************/ +#define Cudd_Complement(node) ((DdNode *)((unsigned long)(node) | 01)) + + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if a pointer is complemented.] + + Description [] + + SideEffects [none] + + SeeAlso [Cudd_Regular Cudd_Complement] + +******************************************************************************/ +#define Cudd_IsComplement(node) ((int) ((long) (node) & 01)) + + +/**Macro*********************************************************************** + + Synopsis [Returns the then child of an internal node.] + + Description [Returns the then child of an internal node. If + node is a constant node, the result is unpredictable.] + + SideEffects [none] + + SeeAlso [Cudd_E Cudd_V] + +******************************************************************************/ +#define Cudd_T(node) ((Cudd_Regular(node))->type.kids.T) + + +/**Macro*********************************************************************** + + Synopsis [Returns the else child of an internal node.] + + Description [Returns the else child of an internal node. If + node is a constant node, the result is unpredictable.] + + SideEffects [none] + + SeeAlso [Cudd_T Cudd_V] + +******************************************************************************/ +#define Cudd_E(node) ((Cudd_Regular(node))->type.kids.E) + + +/**Macro*********************************************************************** + + Synopsis [Returns the value of a constant node.] + + Description [Returns the value of a constant node. If + node is an internal node, the result is unpredictable.] + + SideEffects [none] + + SeeAlso [Cudd_T Cudd_E] + +******************************************************************************/ +#define Cudd_V(node) ((Cudd_Regular(node))->type.value) + + +/**Macro*********************************************************************** + + Synopsis [Returns the current position in the order of variable + index.] + + Description [Returns the current position in the order of variable + index. This macro is obsolete and is kept for compatibility. New + applications should use Cudd_ReadPerm instead.] + + SideEffects [none] + + SeeAlso [Cudd_ReadPerm] + +******************************************************************************/ +#define Cudd_ReadIndex(dd,index) (Cudd_ReadPerm(dd,index)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the cubes of a decision diagram.] + + Description [Iterates over the cubes of a decision diagram f. +
    +
  • DdManager *manager; +
  • DdNode *f; +
  • DdGen *gen; +
  • int *cube; +
  • CUDD_VALUE_TYPE value; +
+ Cudd_ForeachCube allocates and frees the generator. Therefore the + application should not try to do that. Also, the cube is freed at the + end of Cudd_ForeachCube and hence is not available outside of the loop.

+ CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_GenFree + Cudd_IsGenEmpty Cudd_AutodynDisable] + +******************************************************************************/ +#define Cudd_ForeachCube(manager, f, gen, cube, value)\ + for((gen) = Cudd_FirstCube(manager, f, &cube, &value);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : CUDD_TRUE;\ + (void) Cudd_NextCube(gen, &cube, &value)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the primes of a Boolean function.] + + Description [Iterates over the primes of a Boolean function producing + a prime and irredundant cover. +

    +
  • DdManager *manager; +
  • DdNode *l; +
  • DdNode *u; +
  • DdGen *gen; +
  • int *cube; +
+ The Boolean function is described by an upper bound and a lower bound. If + the function is completely specified, the two bounds coincide. + Cudd_ForeachPrime allocates and frees the generator. Therefore the + application should not try to do that. Also, the cube is freed at the + end of Cudd_ForeachPrime and hence is not available outside of the loop.

+ CAUTION: It is a mistake to change a diagram on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_ForeachCube Cudd_FirstPrime Cudd_NextPrime Cudd_GenFree + Cudd_IsGenEmpty] + +******************************************************************************/ +#define Cudd_ForeachPrime(manager, l, u, gen, cube)\ + for((gen) = Cudd_FirstPrime(manager, l, u, &cube);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : CUDD_TRUE;\ + (void) Cudd_NextPrime(gen, &cube)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the nodes of a decision diagram.] + + Description [Iterates over the nodes of a decision diagram f. +

    +
  • DdManager *manager; +
  • DdNode *f; +
  • DdGen *gen; +
  • DdNode *node; +
+ The nodes are returned in a seemingly random order. + Cudd_ForeachNode allocates and frees the generator. Therefore the + application should not try to do that.

+ CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_ForeachCube Cudd_FirstNode Cudd_NextNode Cudd_GenFree + Cudd_IsGenEmpty Cudd_AutodynDisable] + +******************************************************************************/ +#define Cudd_ForeachNode(manager, f, gen, node)\ + for((gen) = Cudd_FirstNode(manager, f, &node);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : CUDD_TRUE;\ + (void) Cudd_NextNode(gen, &node)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the paths of a ZDD.] + + Description [Iterates over the paths of a ZDD f. +

    +
  • DdManager *manager; +
  • DdNode *f; +
  • DdGen *gen; +
  • int *path; +
+ Cudd_zddForeachPath allocates and frees the generator. Therefore the + application should not try to do that. Also, the path is freed at the + end of Cudd_zddForeachPath and hence is not available outside of the loop.

+ CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_zddFirstPath Cudd_zddNextPath Cudd_GenFree + Cudd_IsGenEmpty Cudd_AutodynDisable] + +******************************************************************************/ +#define Cudd_zddForeachPath(manager, f, gen, path)\ + for((gen) = Cudd_zddFirstPath(manager, f, &path);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : CUDD_TRUE;\ + (void) Cudd_zddNextPath(gen, &path)) + + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern DdNode * Cudd_addNewVar (DdManager *dd); +extern DdNode * Cudd_addNewVarAtLevel (DdManager *dd, int level); +extern DdNode * Cudd_bddNewVar (DdManager *dd); +extern DdNode * Cudd_bddNewVarAtLevel (DdManager *dd, int level); +extern DdNode * Cudd_addIthVar (DdManager *dd, int i); +extern DdNode * Cudd_bddIthVar (DdManager *dd, int i); +extern DdNode * Cudd_zddIthVar (DdManager *dd, int i); +extern int Cudd_zddVarsFromBddVars (DdManager *dd, int multiplicity); +extern DdNode * Cudd_addConst (DdManager *dd, CUDD_VALUE_TYPE c); +extern int Cudd_IsNonConstant (DdNode *f); +extern unsigned long Cudd_ReadStartTime(DdManager *unique); +extern unsigned long Cudd_ReadElapsedTime(DdManager *unique); +extern void Cudd_SetStartTime(DdManager *unique, unsigned long st); +extern void Cudd_ResetStartTime(DdManager *unique); +extern unsigned long Cudd_ReadTimeLimit(DdManager *unique); +extern void Cudd_SetTimeLimit(DdManager *unique, unsigned long tl); +extern void Cudd_UpdateTimeLimit(DdManager * unique); +extern void Cudd_IncreaseTimeLimit(DdManager * unique, unsigned long increase); +extern void Cudd_UnsetTimeLimit(DdManager *unique); +extern int Cudd_TimeLimited(DdManager *unique); +extern void Cudd_AutodynEnable (DdManager *unique, Cudd_ReorderingType method); +extern void Cudd_AutodynDisable (DdManager *unique); +extern int Cudd_ReorderingStatus (DdManager *unique, Cudd_ReorderingType *method); +extern void Cudd_AutodynEnableZdd (DdManager *unique, Cudd_ReorderingType method); +extern void Cudd_AutodynDisableZdd (DdManager *unique); +extern int Cudd_ReorderingStatusZdd (DdManager *unique, Cudd_ReorderingType *method); +extern int Cudd_zddRealignmentEnabled (DdManager *unique); +extern void Cudd_zddRealignEnable (DdManager *unique); +extern void Cudd_zddRealignDisable (DdManager *unique); +extern int Cudd_bddRealignmentEnabled (DdManager *unique); +extern void Cudd_bddRealignEnable (DdManager *unique); +extern void Cudd_bddRealignDisable (DdManager *unique); +extern DdNode * Cudd_ReadOne (DdManager *dd); +extern DdNode * Cudd_ReadZddOne (DdManager *dd, int i); +extern DdNode * Cudd_ReadZero (DdManager *dd); +extern DdNode * Cudd_ReadLogicZero (DdManager *dd); +extern DdNode * Cudd_ReadPlusInfinity (DdManager *dd); +extern DdNode * Cudd_ReadMinusInfinity (DdManager *dd); +extern DdNode * Cudd_ReadBackground (DdManager *dd); +extern void Cudd_SetBackground (DdManager *dd, DdNode *bck); +extern unsigned int Cudd_ReadCacheSlots (DdManager *dd); +extern double Cudd_ReadCacheUsedSlots (DdManager * dd); +extern double Cudd_ReadCacheLookUps (DdManager *dd); +extern double Cudd_ReadCacheHits (DdManager *dd); +extern double Cudd_ReadRecursiveCalls (DdManager * dd); +extern unsigned int Cudd_ReadMinHit (DdManager *dd); +extern void Cudd_SetMinHit (DdManager *dd, unsigned int hr); +extern unsigned int Cudd_ReadLooseUpTo (DdManager *dd); +extern void Cudd_SetLooseUpTo (DdManager *dd, unsigned int lut); +extern unsigned int Cudd_ReadMaxCache (DdManager *dd); +extern unsigned int Cudd_ReadMaxCacheHard (DdManager *dd); +extern void Cudd_SetMaxCacheHard (DdManager *dd, unsigned int mc); +extern int Cudd_ReadSize (DdManager *dd); +extern int Cudd_ReadZddSize (DdManager *dd); +extern unsigned int Cudd_ReadSlots (DdManager *dd); +extern double Cudd_ReadUsedSlots (DdManager * dd); +extern double Cudd_ExpectedUsedSlots (DdManager * dd); +extern unsigned int Cudd_ReadKeys (DdManager *dd); +extern unsigned int Cudd_ReadDead (DdManager *dd); +extern unsigned int Cudd_ReadMinDead (DdManager *dd); +extern unsigned int Cudd_ReadReorderings (DdManager *dd); +extern unsigned int Cudd_ReadMaxReorderings (DdManager *dd); +extern void Cudd_SetMaxReorderings (DdManager *dd, unsigned int mr); +extern long Cudd_ReadReorderingTime (DdManager * dd); +extern int Cudd_ReadGarbageCollections (DdManager * dd); +extern long Cudd_ReadGarbageCollectionTime (DdManager * dd); +extern double Cudd_ReadNodesFreed (DdManager * dd); +extern double Cudd_ReadNodesDropped (DdManager * dd); +extern double Cudd_ReadUniqueLookUps (DdManager * dd); +extern double Cudd_ReadUniqueLinks (DdManager * dd); +extern int Cudd_ReadSiftMaxVar (DdManager *dd); +extern void Cudd_SetSiftMaxVar (DdManager *dd, int smv); +extern int Cudd_ReadSiftMaxSwap (DdManager *dd); +extern void Cudd_SetSiftMaxSwap (DdManager *dd, int sms); +extern double Cudd_ReadMaxGrowth (DdManager *dd); +extern void Cudd_SetMaxGrowth (DdManager *dd, double mg); +extern double Cudd_ReadMaxGrowthAlternate (DdManager * dd); +extern void Cudd_SetMaxGrowthAlternate (DdManager * dd, double mg); +extern int Cudd_ReadReorderingCycle (DdManager * dd); +extern void Cudd_SetReorderingCycle (DdManager * dd, int cycle); +extern MtrNode * Cudd_ReadTree (DdManager *dd); +extern void Cudd_SetTree (DdManager *dd, MtrNode *tree); +extern void Cudd_FreeTree (DdManager *dd); +extern MtrNode * Cudd_ReadZddTree (DdManager *dd); +extern void Cudd_SetZddTree (DdManager *dd, MtrNode *tree); +extern void Cudd_FreeZddTree (DdManager *dd); +extern unsigned int Cudd_NodeReadIndex (DdNode *node); +extern int Cudd_ReadPerm (DdManager *dd, int i); +extern int Cudd_ReadPermZdd (DdManager *dd, int i); +extern int Cudd_ReadInvPerm (DdManager *dd, int i); +extern int Cudd_ReadInvPermZdd (DdManager *dd, int i); +extern DdNode * Cudd_ReadVars (DdManager *dd, int i); +extern CUDD_VALUE_TYPE Cudd_ReadEpsilon (DdManager *dd); +extern void Cudd_SetEpsilon (DdManager *dd, CUDD_VALUE_TYPE ep); +extern Cudd_AggregationType Cudd_ReadGroupcheck (DdManager *dd); +extern void Cudd_SetGroupcheck (DdManager *dd, Cudd_AggregationType gc); +extern int Cudd_GarbageCollectionEnabled (DdManager *dd); +extern void Cudd_EnableGarbageCollection (DdManager *dd); +extern void Cudd_DisableGarbageCollection (DdManager *dd); +extern int Cudd_DeadAreCounted (DdManager *dd); +extern void Cudd_TurnOnCountDead (DdManager *dd); +extern void Cudd_TurnOffCountDead (DdManager *dd); +extern int Cudd_ReadRecomb (DdManager *dd); +extern void Cudd_SetRecomb (DdManager *dd, int recomb); +extern int Cudd_ReadSymmviolation (DdManager *dd); +extern void Cudd_SetSymmviolation (DdManager *dd, int symmviolation); +extern int Cudd_ReadArcviolation (DdManager *dd); +extern void Cudd_SetArcviolation (DdManager *dd, int arcviolation); +extern int Cudd_ReadPopulationSize (DdManager *dd); +extern void Cudd_SetPopulationSize (DdManager *dd, int populationSize); +extern int Cudd_ReadNumberXovers (DdManager *dd); +extern void Cudd_SetNumberXovers (DdManager *dd, int numberXovers); +extern unsigned int Cudd_ReadOrderRandomization(DdManager * dd); +extern void Cudd_SetOrderRandomization(DdManager * dd, unsigned int factor); +extern unsigned long Cudd_ReadMemoryInUse (DdManager *dd); +extern int Cudd_PrintInfo (DdManager *dd, FILE *fp); +extern long Cudd_ReadPeakNodeCount (DdManager *dd); +extern int Cudd_ReadPeakLiveNodeCount (DdManager * dd); +extern long Cudd_ReadNodeCount (DdManager *dd); +extern long Cudd_zddReadNodeCount (DdManager *dd); +extern int Cudd_AddHook (DdManager *dd, DD_HFP f, Cudd_HookType where); +extern int Cudd_RemoveHook (DdManager *dd, DD_HFP f, Cudd_HookType where); +extern int Cudd_IsInHook (DdManager * dd, DD_HFP f, Cudd_HookType where); +extern int Cudd_StdPreReordHook (DdManager *dd, const char *str, void *data); +extern int Cudd_StdPostReordHook (DdManager *dd, const char *str, void *data); +extern int Cudd_EnableReorderingReporting (DdManager *dd); +extern int Cudd_DisableReorderingReporting (DdManager *dd); +extern int Cudd_ReorderingReporting (DdManager *dd); +extern int Cudd_PrintGroupedOrder(DdManager * dd, const char *str, void *data); +extern int Cudd_EnableOrderingMonitoring(DdManager *dd); +extern int Cudd_DisableOrderingMonitoring(DdManager *dd); +extern int Cudd_OrderingMonitoring(DdManager *dd); +extern Cudd_ErrorType Cudd_ReadErrorCode (DdManager *dd); +extern void Cudd_ClearErrorCode (DdManager *dd); +extern FILE * Cudd_ReadStdout (DdManager *dd); +extern void Cudd_SetStdout (DdManager *dd, FILE *fp); +extern FILE * Cudd_ReadStderr (DdManager *dd); +extern void Cudd_SetStderr (DdManager *dd, FILE *fp); +extern unsigned int Cudd_ReadNextReordering (DdManager *dd); +extern void Cudd_SetNextReordering (DdManager *dd, unsigned int next); +extern double Cudd_ReadSwapSteps (DdManager *dd); +extern unsigned int Cudd_ReadMaxLive (DdManager *dd); +extern void Cudd_SetMaxLive (DdManager *dd, unsigned int maxLive); +extern unsigned long Cudd_ReadMaxMemory (DdManager *dd); +extern void Cudd_SetMaxMemory (DdManager *dd, unsigned long maxMemory); +extern int Cudd_bddBindVar (DdManager *dd, int index); +extern int Cudd_bddUnbindVar (DdManager *dd, int index); +extern int Cudd_bddVarIsBound (DdManager *dd, int index); +extern DdNode * Cudd_addExistAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_addUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_addOrAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_addApply (DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g); +extern DdNode * Cudd_addPlus (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addTimes (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addThreshold (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addSetNZ (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addDivide (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addMinus (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addMinimum (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addMaximum (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addOneZeroMaximum (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addDiff (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addAgreement (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addOr (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addNand (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addNor (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addXor (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addXnor (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addMonadicApply (DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f); +extern DdNode * Cudd_addLog (DdManager * dd, DdNode * f); +extern DdNode * Cudd_addFindMax (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addFindMin (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addIthBit (DdManager *dd, DdNode *f, int bit); +extern DdNode * Cudd_addScalarInverse (DdManager *dd, DdNode *f, DdNode *epsilon); +extern DdNode * Cudd_addIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * Cudd_addIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * Cudd_addEvalConst (DdManager *dd, DdNode *f, DdNode *g); +extern int Cudd_addLeq (DdManager * dd, DdNode * f, DdNode * g); +extern DdNode * Cudd_addCmpl (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addNegate (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addRoundOff (DdManager *dd, DdNode *f, int N); +extern DdNode * Cudd_addWalsh (DdManager *dd, DdNode **x, DdNode **y, int n); +extern DdNode * Cudd_addResidue (DdManager *dd, int n, int m, int options, int top); +extern DdNode * Cudd_bddAndAbstract (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube); +extern DdNode * Cudd_bddAndAbstractLimit (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, unsigned int limit); +extern int Cudd_ApaNumberOfDigits (int binaryDigits); +extern DdApaNumber Cudd_NewApaNumber (int digits); +extern void Cudd_ApaCopy (int digits, DdApaNumber source, DdApaNumber dest); +extern DdApaDigit Cudd_ApaAdd (int digits, DdApaNumber a, DdApaNumber b, DdApaNumber sum); +extern DdApaDigit Cudd_ApaSubtract (int digits, DdApaNumber a, DdApaNumber b, DdApaNumber diff); +extern DdApaDigit Cudd_ApaShortDivision (int digits, DdApaNumber dividend, DdApaDigit divisor, DdApaNumber quotient); +extern unsigned int Cudd_ApaIntDivision (int digits, DdApaNumber dividend, unsigned int divisor, DdApaNumber quotient); +extern void Cudd_ApaShiftRight (int digits, DdApaDigit in, DdApaNumber a, DdApaNumber b); +extern void Cudd_ApaSetToLiteral (int digits, DdApaNumber number, DdApaDigit literal); +extern void Cudd_ApaPowerOfTwo (int digits, DdApaNumber number, int power); +extern int Cudd_ApaCompare (int digitsFirst, DdApaNumber first, int digitsSecond, DdApaNumber second); +extern int Cudd_ApaCompareRatios (int digitsFirst, DdApaNumber firstNum, unsigned int firstDen, int digitsSecond, DdApaNumber secondNum, unsigned int secondDen); +extern int Cudd_ApaPrintHex (FILE *fp, int digits, DdApaNumber number); +extern int Cudd_ApaPrintDecimal (FILE *fp, int digits, DdApaNumber number); +extern int Cudd_ApaPrintExponential (FILE * fp, int digits, DdApaNumber number, int precision); +extern DdApaNumber Cudd_ApaCountMinterm (DdManager *manager, DdNode *node, int nvars, int *digits); +extern int Cudd_ApaPrintMinterm (FILE *fp, DdManager *dd, DdNode *node, int nvars); +extern int Cudd_ApaPrintMintermExp (FILE * fp, DdManager * dd, DdNode * node, int nvars, int precision); +extern int Cudd_ApaPrintDensity (FILE * fp, DdManager * dd, DdNode * node, int nvars); +extern DdNode * Cudd_UnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality); +extern DdNode * Cudd_OverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality); +extern DdNode * Cudd_RemapUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality); +extern DdNode * Cudd_RemapOverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality); +extern DdNode * Cudd_BiasedUnderApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0); +extern DdNode * Cudd_BiasedOverApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0); +extern DdNode * Cudd_bddExistAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_bddExistAbstractLimit(DdManager * manager, DdNode * f, DdNode * cube, unsigned int limit); +extern DdNode * Cudd_bddXorExistAbstract (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube); +extern DdNode * Cudd_bddUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_bddBooleanDiff (DdManager *manager, DdNode *f, int x); +extern int Cudd_bddVarIsDependent (DdManager *dd, DdNode *f, DdNode *var); +extern double Cudd_bddCorrelation (DdManager *manager, DdNode *f, DdNode *g); +extern double Cudd_bddCorrelationWeights (DdManager *manager, DdNode *f, DdNode *g, double *prob); +extern DdNode * Cudd_bddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); + extern DdNode * Cudd_bddIteLimit (DdManager *dd, DdNode *f, DdNode *g, DdNode *h, unsigned int limit); +extern DdNode * Cudd_bddIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * Cudd_bddIntersect (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddAnd (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddAndLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); +extern DdNode * Cudd_bddOr (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddOrLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); +extern DdNode * Cudd_bddNand (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddNor (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddXor (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddXnor (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddXnorLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); +extern int Cudd_bddLeq (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_addBddThreshold (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value); +extern DdNode * Cudd_addBddStrictThreshold (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value); +extern DdNode * Cudd_addBddInterval (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper); +extern DdNode * Cudd_addBddIthBit (DdManager *dd, DdNode *f, int bit); +extern DdNode * Cudd_BddToAdd (DdManager *dd, DdNode *B); +extern DdNode * Cudd_addBddPattern (DdManager *dd, DdNode *f); +extern DdNode * Cudd_bddTransfer (DdManager *ddSource, DdManager *ddDestination, DdNode *f); +extern int Cudd_DebugCheck (DdManager *table); +extern int Cudd_CheckKeys (DdManager *table); +extern DdNode * Cudd_bddClippingAnd (DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction); +extern DdNode * Cudd_bddClippingAndAbstract (DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction); +extern DdNode * Cudd_Cofactor (DdManager *dd, DdNode *f, DdNode *g); +extern int Cudd_CheckCube (DdManager *dd, DdNode *g); +extern DdNode * Cudd_bddCompose (DdManager *dd, DdNode *f, DdNode *g, int v); +extern DdNode * Cudd_addCompose (DdManager *dd, DdNode *f, DdNode *g, int v); +extern DdNode * Cudd_addPermute (DdManager *manager, DdNode *node, int *permut); +extern DdNode * Cudd_addSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n); +extern DdNode * Cudd_bddPermute (DdManager *manager, DdNode *node, int *permut); +extern DdNode * Cudd_bddVarMap (DdManager *manager, DdNode *f); +extern int Cudd_SetVarMap (DdManager *manager, DdNode **x, DdNode **y, int n); +extern DdNode * Cudd_bddSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n); +extern DdNode * Cudd_bddAdjPermuteX (DdManager *dd, DdNode *B, DdNode **x, int n); +extern DdNode * Cudd_addVectorCompose (DdManager *dd, DdNode *f, DdNode **vector); +extern DdNode * Cudd_addGeneralVectorCompose (DdManager *dd, DdNode *f, DdNode **vectorOn, DdNode **vectorOff); +extern DdNode * Cudd_addNonSimCompose (DdManager *dd, DdNode *f, DdNode **vector); +extern DdNode * Cudd_bddVectorCompose (DdManager *dd, DdNode *f, DdNode **vector); +extern int Cudd_bddApproxConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts); +extern int Cudd_bddApproxDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts); +extern int Cudd_bddIterConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts); +extern int Cudd_bddIterDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts); +extern int Cudd_bddGenConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts); +extern int Cudd_bddGenDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts); +extern int Cudd_bddVarConjDecomp (DdManager *dd, DdNode * f, DdNode ***conjuncts); +extern int Cudd_bddVarDisjDecomp (DdManager *dd, DdNode * f, DdNode ***disjuncts); +extern DdNode * Cudd_FindEssential (DdManager *dd, DdNode *f); +extern int Cudd_bddIsVarEssential (DdManager *manager, DdNode *f, int id, int phase); +extern DdTlcInfo * Cudd_FindTwoLiteralClauses (DdManager * dd, DdNode * f); +extern int Cudd_PrintTwoLiteralClauses (DdManager * dd, DdNode * f, char **names, FILE *fp); +extern int Cudd_ReadIthClause (DdTlcInfo * tlc, int i, DdHalfWord *var1, DdHalfWord *var2, int *phase1, int *phase2); +extern void Cudd_tlcInfoFree (DdTlcInfo * t); +extern int Cudd_DumpBlif (DdManager *dd, int n, DdNode **f, char **inames, char **onames, char *mname, FILE *fp, int mv); +extern int Cudd_DumpBlifBody (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp, int mv); +extern int Cudd_DumpDot (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern int Cudd_DumpDaVinci (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern int Cudd_DumpDDcal (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern int Cudd_DumpFactoredForm (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern DdNode * Cudd_bddConstrain (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_bddRestrict (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_bddNPAnd (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_addConstrain (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode ** Cudd_bddConstrainDecomp (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addRestrict (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode ** Cudd_bddCharToVect (DdManager *dd, DdNode *f); +extern DdNode * Cudd_bddLICompaction (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_bddSqueeze (DdManager *dd, DdNode *l, DdNode *u); +extern DdNode * Cudd_bddMinimize (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_SubsetCompress (DdManager *dd, DdNode *f, int nvars, int threshold); +extern DdNode * Cudd_SupersetCompress (DdManager *dd, DdNode *f, int nvars, int threshold); +extern MtrNode * Cudd_MakeTreeNode (DdManager *dd, unsigned int low, unsigned int size, unsigned int type); +extern int Cudd_addHarwell (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, DdNode ***xn, DdNode ***yn_, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy, int pr); +extern DdManager * Cudd_Init (unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory); +extern void Cudd_Quit (DdManager *unique); +extern int Cudd_PrintLinear (DdManager *table); +extern int Cudd_ReadLinear (DdManager *table, int x, int y); +extern DdNode * Cudd_bddLiteralSetIntersection (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_addMatrixMultiply (DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz); +extern DdNode * Cudd_addTimesPlus (DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz); +extern DdNode * Cudd_addTriangle (DdManager *dd, DdNode *f, DdNode *g, DdNode **z, int nz); +extern DdNode * Cudd_addOuterSum (DdManager *dd, DdNode *M, DdNode *r, DdNode *c); +extern DdNode * Cudd_PrioritySelect (DdManager *dd, DdNode *R, DdNode **x, DdNode **y, DdNode **z, DdNode *Pi, int n, DdNode * (*)(DdManager *, int, DdNode **, DdNode **, DdNode **)); +extern DdNode * Cudd_Xgty (DdManager *dd, int N, DdNode **z, DdNode **x, DdNode **y); +extern DdNode * Cudd_Xeqy (DdManager *dd, int N, DdNode **x, DdNode **y); +extern DdNode * Cudd_addXeqy (DdManager *dd, int N, DdNode **x, DdNode **y); +extern DdNode * Cudd_Dxygtdxz (DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z); +extern DdNode * Cudd_Dxygtdyz (DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z); +extern DdNode * Cudd_Inequality (DdManager * dd, int N, int c, DdNode ** x, DdNode ** y); +extern DdNode * Cudd_Disequality (DdManager * dd, int N, int c, DdNode ** x, DdNode ** y); +extern DdNode * Cudd_bddInterval (DdManager * dd, int N, DdNode ** x, unsigned int lowerB, unsigned int upperB); +extern DdNode * Cudd_CProjection (DdManager *dd, DdNode *R, DdNode *Y); +extern DdNode * Cudd_addHamming (DdManager *dd, DdNode **xVars, DdNode **yVars, int nVars); +extern int Cudd_MinHammingDist (DdManager *dd, DdNode *f, int *minterm, int upperBound); +extern DdNode * Cudd_bddClosestCube (DdManager *dd, DdNode * f, DdNode *g, int *distance); +extern int Cudd_addRead (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, DdNode ***xn, DdNode ***yn_, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy); +extern int Cudd_bddRead (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy); +extern void Cudd_Ref (DdNode *n); +extern void Cudd_RecursiveDeref (DdManager *table, DdNode *n); +extern void Cudd_IterDerefBdd (DdManager *table, DdNode *n); +extern void Cudd_DelayedDerefBdd (DdManager * table, DdNode * n); +extern void Cudd_RecursiveDerefZdd (DdManager *table, DdNode *n); +extern void Cudd_Deref (DdNode *node); +extern int Cudd_CheckZeroRef (DdManager *manager); +extern int Cudd_ReduceHeap (DdManager *table, Cudd_ReorderingType heuristic, int minsize); +extern int Cudd_ShuffleHeap (DdManager *table, int *permutation); +extern DdNode * Cudd_Eval (DdManager *dd, DdNode *f, int *inputs); +extern DdNode * Cudd_ShortestPath (DdManager *manager, DdNode *f, int *weight, int *support, int *length); +extern DdNode * Cudd_LargestCube (DdManager *manager, DdNode *f, int *length); +extern int Cudd_ShortestLength (DdManager *manager, DdNode *f, int *weight); +extern DdNode * Cudd_Decreasing (DdManager *dd, DdNode *f, int i); +extern DdNode * Cudd_Increasing (DdManager *dd, DdNode *f, int i); +extern int Cudd_EquivDC (DdManager *dd, DdNode *F, DdNode *G, DdNode *D); +extern int Cudd_bddLeqUnless (DdManager *dd, DdNode *f, DdNode *g, DdNode *D); +extern int Cudd_EqualSupNorm (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr); +extern DdNode * Cudd_bddMakePrime (DdManager *dd, DdNode *cube, DdNode *f); +extern DdNode * Cudd_bddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f); +extern DdNode * Cudd_bddLargestPrimeUnate(DdManager *dd , DdNode *f, DdNode *phaseBdd); +extern double * Cudd_CofMinterm (DdManager *dd, DdNode *node); +extern DdNode * Cudd_SolveEqn (DdManager * bdd, DdNode *F, DdNode *Y, DdNode **G, int **yIndex, int n); +extern DdNode * Cudd_VerifySol (DdManager * bdd, DdNode *F, DdNode **G, int *yIndex, int n); +extern DdNode * Cudd_SplitSet (DdManager *manager, DdNode *S, DdNode **xVars, int n, double m); +extern DdNode * Cudd_SubsetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold); +extern DdNode * Cudd_SupersetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold); +extern DdNode * Cudd_SubsetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit); +extern DdNode * Cudd_SupersetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit); +extern void Cudd_SymmProfile (DdManager *table, int lower, int upper); +extern unsigned int Cudd_Prime (unsigned int p); +extern int Cudd_Reserve(DdManager *manager, int amount); +extern int Cudd_PrintMinterm (DdManager *manager, DdNode *node); +extern int Cudd_bddPrintCover (DdManager *dd, DdNode *l, DdNode *u); +extern int Cudd_PrintDebug (DdManager *dd, DdNode *f, int n, int pr); +extern int Cudd_DagSize (DdNode *node); +extern int Cudd_EstimateCofactor (DdManager *dd, DdNode * node, int i, int phase); +extern int Cudd_EstimateCofactorSimple (DdNode * node, int i); +extern int Cudd_SharingSize (DdNode **nodeArray, int n); +extern double Cudd_CountMinterm (DdManager *manager, DdNode *node, int nvars); +extern int Cudd_EpdCountMinterm (DdManager *manager, DdNode *node, int nvars, EpDouble *epd); +extern double Cudd_CountPath (DdNode *node); +extern double Cudd_CountPathsToNonZero (DdNode *node); +extern int Cudd_SupportIndices(DdManager * dd, DdNode * f, int **indices); +extern DdNode * Cudd_Support (DdManager *dd, DdNode *f); +extern int * Cudd_SupportIndex (DdManager *dd, DdNode *f); +extern int Cudd_SupportSize (DdManager *dd, DdNode *f); +extern int Cudd_VectorSupportIndices(DdManager * dd, DdNode ** F, int n, int **indices); +extern DdNode * Cudd_VectorSupport (DdManager *dd, DdNode **F, int n); +extern int * Cudd_VectorSupportIndex (DdManager *dd, DdNode **F, int n); +extern int Cudd_VectorSupportSize (DdManager *dd, DdNode **F, int n); +extern int Cudd_ClassifySupport (DdManager *dd, DdNode *f, DdNode *g, DdNode **common, DdNode **onlyF, DdNode **onlyG); +extern int Cudd_CountLeaves (DdNode *node); +extern int Cudd_bddPickOneCube (DdManager *ddm, DdNode *node, char *string); +extern DdNode * Cudd_bddPickOneMinterm (DdManager *dd, DdNode *f, DdNode **vars, int n); +extern DdNode ** Cudd_bddPickArbitraryMinterms (DdManager *dd, DdNode *f, DdNode **vars, int n, int k); +extern DdNode * Cudd_SubsetWithMaskVars (DdManager *dd, DdNode *f, DdNode **vars, int nvars, DdNode **maskVars, int mvars); +extern DdGen * Cudd_FirstCube (DdManager *dd, DdNode *f, int **cube, CUDD_VALUE_TYPE *value); +extern int Cudd_NextCube (DdGen *gen, int **cube, CUDD_VALUE_TYPE *value); +extern DdGen * Cudd_FirstPrime(DdManager *dd, DdNode *l, DdNode *u, int **cube); +extern int Cudd_NextPrime(DdGen *gen, int **cube); +extern DdNode * Cudd_bddComputeCube (DdManager *dd, DdNode **vars, int *phase, int n); +extern DdNode * Cudd_addComputeCube (DdManager *dd, DdNode **vars, int *phase, int n); +extern DdNode * Cudd_CubeArrayToBdd (DdManager *dd, int *array); +extern int Cudd_BddToCubeArray (DdManager *dd, DdNode *cube, int *array); +extern DdGen * Cudd_FirstNode (DdManager *dd, DdNode *f, DdNode **node); +extern int Cudd_NextNode (DdGen *gen, DdNode **node); +extern int Cudd_GenFree (DdGen *gen); +extern int Cudd_IsGenEmpty (DdGen *gen); +extern DdNode * Cudd_IndicesToCube (DdManager *dd, int *array, int n); +extern void Cudd_PrintVersion (FILE *fp); +extern double Cudd_AverageDistance (DdManager *dd); +extern long Cudd_Random (void); +extern void Cudd_Srandom (long seed); +extern double Cudd_Density (DdManager *dd, DdNode *f, int nvars); +extern void Cudd_OutOfMem (long size); +extern int Cudd_zddCount (DdManager *zdd, DdNode *P); +extern double Cudd_zddCountDouble (DdManager *zdd, DdNode *P); +extern DdNode * Cudd_zddProduct (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddUnateProduct (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddWeakDiv (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddDivide (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddWeakDivF (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddDivideF (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddComplement (DdManager *dd, DdNode *node); +extern MtrNode * Cudd_MakeZddTreeNode (DdManager *dd, unsigned int low, unsigned int size, unsigned int type); +extern DdNode * Cudd_zddIsop (DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I); +extern DdNode * Cudd_bddIsop (DdManager *dd, DdNode *L, DdNode *U); +extern DdNode * Cudd_MakeBddFromZddCover (DdManager *dd, DdNode *node); +extern int Cudd_zddDagSize (DdNode *p_node); +extern double Cudd_zddCountMinterm (DdManager *zdd, DdNode *node, int path); +extern void Cudd_zddPrintSubtable (DdManager *table); +extern DdNode * Cudd_zddPortFromBdd (DdManager *dd, DdNode *B); +extern DdNode * Cudd_zddPortToBdd (DdManager *dd, DdNode *f); +extern int Cudd_zddReduceHeap (DdManager *table, Cudd_ReorderingType heuristic, int minsize); +extern int Cudd_zddShuffleHeap (DdManager *table, int *permutation); +extern DdNode * Cudd_zddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * Cudd_zddUnion (DdManager *dd, DdNode *P, DdNode *Q); +extern DdNode * Cudd_zddIntersect (DdManager *dd, DdNode *P, DdNode *Q); +extern DdNode * Cudd_zddDiff (DdManager *dd, DdNode *P, DdNode *Q); +extern DdNode * Cudd_zddDiffConst (DdManager *zdd, DdNode *P, DdNode *Q); +extern DdNode * Cudd_zddSubset1 (DdManager *dd, DdNode *P, int var); +extern DdNode * Cudd_zddSubset0 (DdManager *dd, DdNode *P, int var); +extern DdNode * Cudd_zddChange (DdManager *dd, DdNode *P, int var); +extern void Cudd_zddSymmProfile (DdManager *table, int lower, int upper); +extern int Cudd_zddPrintMinterm (DdManager *zdd, DdNode *node); +extern int Cudd_zddPrintCover (DdManager *zdd, DdNode *node); +extern int Cudd_zddPrintDebug (DdManager *zdd, DdNode *f, int n, int pr); +extern DdGen * Cudd_zddFirstPath (DdManager *zdd, DdNode *f, int **path); +extern int Cudd_zddNextPath (DdGen *gen, int **path); +extern char * Cudd_zddCoverPathToString (DdManager *zdd, int *path, char *str); +extern DdNode * Cudd_zddSupport(DdManager * dd, DdNode * f); +extern int Cudd_zddDumpDot (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern int Cudd_bddSetPiVar (DdManager *dd, int index); +extern int Cudd_bddSetPsVar (DdManager *dd, int index); +extern int Cudd_bddSetNsVar (DdManager *dd, int index); +extern int Cudd_bddIsPiVar (DdManager *dd, int index); +extern int Cudd_bddIsPsVar (DdManager *dd, int index); +extern int Cudd_bddIsNsVar (DdManager *dd, int index); +extern int Cudd_bddSetPairIndex (DdManager *dd, int index, int pairIndex); +extern int Cudd_bddReadPairIndex (DdManager *dd, int index); +extern int Cudd_bddSetVarToBeGrouped (DdManager *dd, int index); +extern int Cudd_bddSetVarHardGroup (DdManager *dd, int index); +extern int Cudd_bddResetVarToBeGrouped (DdManager *dd, int index); +extern int Cudd_bddIsVarToBeGrouped (DdManager *dd, int index); +extern int Cudd_bddSetVarToBeUngrouped (DdManager *dd, int index); +extern int Cudd_bddIsVarToBeUngrouped (DdManager *dd, int index); +extern int Cudd_bddIsVarHardGroup (DdManager *dd, int index); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _CUDD */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAPI.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAPI.c new file mode 100644 index 000000000..0985cf13d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAPI.c @@ -0,0 +1,4893 @@ +/**CFile*********************************************************************** + + FileName [cuddAPI.c] + + PackageName [cudd] + + Synopsis [Application interface functions.] + + Description [External procedures included in this module: +

    +
  • Cudd_addNewVar() +
  • Cudd_addNewVarAtLevel() +
  • Cudd_bddNewVar() +
  • Cudd_bddNewVarAtLevel() +
  • Cudd_addIthVar() +
  • Cudd_bddIthVar() +
  • Cudd_zddIthVar() +
  • Cudd_zddVarsFromBddVars() +
  • Cudd_addConst() +
  • Cudd_IsNonConstant() +
  • Cudd_ReadStartTime() +
  • Cudd_ReadElapsedTime() +
  • Cudd_SetStartTime() +
  • Cudd_ResetStartTime() +
  • Cudd_ReadTimeLimit() +
  • Cudd_SetTimeLimit() +
  • Cudd_UpdateTimeLimit() +
  • Cudd_IncreaseTimeLimit() +
  • Cudd_UnsetTimeLimit() +
  • Cudd_TimeLimited() +
  • Cudd_AutodynEnable() +
  • Cudd_AutodynDisable() +
  • Cudd_ReorderingStatus() +
  • Cudd_AutodynEnableZdd() +
  • Cudd_AutodynDisableZdd() +
  • Cudd_ReorderingStatusZdd() +
  • Cudd_zddRealignmentEnabled() +
  • Cudd_zddRealignEnable() +
  • Cudd_zddRealignDisable() +
  • Cudd_bddRealignmentEnabled() +
  • Cudd_bddRealignEnable() +
  • Cudd_bddRealignDisable() +
  • Cudd_ReadOne() +
  • Cudd_ReadZddOne() +
  • Cudd_ReadZero() +
  • Cudd_ReadLogicZero() +
  • Cudd_ReadPlusInfinity() +
  • Cudd_ReadMinusInfinity() +
  • Cudd_ReadBackground() +
  • Cudd_SetBackground() +
  • Cudd_ReadCacheSlots() +
  • Cudd_ReadCacheUsedSlots() +
  • Cudd_ReadCacheLookUps() +
  • Cudd_ReadCacheHits() +
  • Cudd_ReadMinHit() +
  • Cudd_SetMinHit() +
  • Cudd_ReadLooseUpTo() +
  • Cudd_SetLooseUpTo() +
  • Cudd_ReadMaxCache() +
  • Cudd_ReadMaxCacheHard() +
  • Cudd_SetMaxCacheHard() +
  • Cudd_ReadSize() +
  • Cudd_ReadSlots() +
  • Cudd_ReadUsedSlots() +
  • Cudd_ExpectedUsedSlots() +
  • Cudd_ReadKeys() +
  • Cudd_ReadDead() +
  • Cudd_ReadMinDead() +
  • Cudd_ReadReorderings() +
  • Cudd_ReadMaxReorderings() +
  • Cudd_SetMaxReorderings() +
  • Cudd_ReadReorderingTime() +
  • Cudd_ReadGarbageCollections() +
  • Cudd_ReadGarbageCollectionTime() +
  • Cudd_ReadNodesFreed() +
  • Cudd_ReadNodesDropped() +
  • Cudd_ReadUniqueLookUps() +
  • Cudd_ReadUniqueLinks() +
  • Cudd_ReadSiftMaxVar() +
  • Cudd_SetSiftMaxVar() +
  • Cudd_ReadMaxGrowth() +
  • Cudd_SetMaxGrowth() +
  • Cudd_ReadMaxGrowthAlternate() +
  • Cudd_SetMaxGrowthAlternate() +
  • Cudd_ReadReorderingCycle() +
  • Cudd_SetReorderingCycle() +
  • Cudd_ReadTree() +
  • Cudd_SetTree() +
  • Cudd_FreeTree() +
  • Cudd_ReadZddTree() +
  • Cudd_SetZddTree() +
  • Cudd_FreeZddTree() +
  • Cudd_NodeReadIndex() +
  • Cudd_ReadPerm() +
  • Cudd_ReadInvPerm() +
  • Cudd_ReadVars() +
  • Cudd_ReadEpsilon() +
  • Cudd_SetEpsilon() +
  • Cudd_ReadGroupCheck() +
  • Cudd_SetGroupcheck() +
  • Cudd_GarbageCollectionEnabled() +
  • Cudd_EnableGarbageCollection() +
  • Cudd_DisableGarbageCollection() +
  • Cudd_DeadAreCounted() +
  • Cudd_TurnOnCountDead() +
  • Cudd_TurnOffCountDead() +
  • Cudd_ReadRecomb() +
  • Cudd_SetRecomb() +
  • Cudd_ReadSymmviolation() +
  • Cudd_SetSymmviolation() +
  • Cudd_ReadArcviolation() +
  • Cudd_SetArcviolation() +
  • Cudd_ReadPopulationSize() +
  • Cudd_SetPopulationSize() +
  • Cudd_ReadNumberXovers() +
  • Cudd_SetNumberXovers() +
  • Cudd_ReadOrderRandomization() +
  • Cudd_SetOrderRandomization() +
  • Cudd_ReadMemoryInUse() +
  • Cudd_PrintInfo() +
  • Cudd_ReadPeakNodeCount() +
  • Cudd_ReadPeakLiveNodeCount() +
  • Cudd_ReadNodeCount() +
  • Cudd_zddReadNodeCount() +
  • Cudd_AddHook() +
  • Cudd_RemoveHook() +
  • Cudd_IsInHook() +
  • Cudd_StdPreReordHook() +
  • Cudd_StdPostReordHook() +
  • Cudd_EnableReorderingReporting() +
  • Cudd_DisableReorderingReporting() +
  • Cudd_ReorderingReporting() +
  • Cudd_PrintGroupedOrder() +
  • Cudd_EnableOrderingMonitoring() +
  • Cudd_DisableOrderingMonitoring() +
  • Cudd_OrderingMonitoring() +
  • Cudd_ReadErrorCode() +
  • Cudd_ClearErrorCode() +
  • Cudd_ReadStdout() +
  • Cudd_SetStdout() +
  • Cudd_ReadStderr() +
  • Cudd_SetStderr() +
  • Cudd_ReadNextReordering() +
  • Cudd_SetNextReordering() +
  • Cudd_ReadSwapSteps() +
  • Cudd_ReadMaxLive() +
  • Cudd_SetMaxLive() +
  • Cudd_ReadMaxMemory() +
  • Cudd_SetMaxMemory() +
  • Cudd_bddBindVar() +
  • Cudd_bddUnbindVar() +
  • Cudd_bddVarIsBound() +
  • Cudd_bddSetPiVar() +
  • Cudd_bddSetPsVar() +
  • Cudd_bddSetNsVar() +
  • Cudd_bddIsPiVar() +
  • Cudd_bddIsPsVar() +
  • Cudd_bddIsNsVar() +
  • Cudd_bddSetPairIndex() +
  • Cudd_bddReadPairIndex() +
  • Cudd_bddSetVarToBeGrouped() +
  • Cudd_bddSetVarHardGroup() +
  • Cudd_bddResetVarToBeGrouped() +
  • Cudd_bddIsVarToBeGrouped() +
  • Cudd_bddSetVarToBeUngrouped() +
  • Cudd_bddIsVarToBeUngrouped() +
  • Cudd_bddIsVarHardGroup() +
+ Static procedures included in this module: +
    +
  • fixVarTree() +
] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAPI.c,v 1.64 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void fixVarTree (MtrNode *treenode, int *perm, int size); +static int addMultiplicityGroups (DdManager *dd, MtrNode *treenode, int multiplicity, char *vmask, char *lmask); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns a new ADD variable.] + + Description [Creates a new ADD variable. The new variable has an + index equal to the largest previous index plus 1. Returns a + pointer to the new variable if successful; NULL otherwise. + An ADD variable differs from a BDD variable because it points to the + arithmetic zero, instead of having a complement pointer to 1. ] + + SideEffects [None] + + SeeAlso [Cudd_bddNewVar Cudd_addIthVar Cudd_addConst + Cudd_addNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_addNewVar( + DdManager * dd) +{ + DdNode *res; + + if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); + do { + dd->reordered = 0; + res = cuddUniqueInter(dd,dd->size,DD_ONE(dd),DD_ZERO(dd)); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_addNewVar */ + + +/**Function******************************************************************** + + Synopsis [Returns a new ADD variable at a specified level.] + + Description [Creates a new ADD variable. The new variable has an + index equal to the largest previous index plus 1 and is positioned at + the specified level in the order. Returns a pointer to the new + variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_addNewVarAtLevel( + DdManager * dd, + int level) +{ + DdNode *res; + + if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); + if (level >= dd->size) return(Cudd_addIthVar(dd,level)); + if (!cuddInsertSubtables(dd,1,level)) return(NULL); + do { + dd->reordered = 0; + res = cuddUniqueInter(dd,dd->size - 1,DD_ONE(dd),DD_ZERO(dd)); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_addNewVarAtLevel */ + + +/**Function******************************************************************** + + Synopsis [Returns a new BDD variable.] + + Description [Creates a new BDD variable. The new variable has an + index equal to the largest previous index plus 1. Returns a + pointer to the new variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_bddNewVar( + DdManager * dd) +{ + DdNode *res; + + if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); + res = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); + + return(res); + +} /* end of Cudd_bddNewVar */ + + +/**Function******************************************************************** + + Synopsis [Returns a new BDD variable at a specified level.] + + Description [Creates a new BDD variable. The new variable has an + index equal to the largest previous index plus 1 and is positioned at + the specified level in the order. Returns a pointer to the new + variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNewVar Cudd_bddIthVar Cudd_addNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_bddNewVarAtLevel( + DdManager * dd, + int level) +{ + DdNode *res; + + if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); + if (level >= dd->size) return(Cudd_bddIthVar(dd,level)); + if (!cuddInsertSubtables(dd,1,level)) return(NULL); + res = dd->vars[dd->size - 1]; + + return(res); + +} /* end of Cudd_bddNewVarAtLevel */ + + +/**Function******************************************************************** + + Synopsis [Returns the ADD variable with index i.] + + Description [Retrieves the ADD variable with index i if it already + exists, or creates a new ADD variable. Returns a pointer to the + variable if successful; NULL otherwise. An ADD variable differs from + a BDD variable because it points to the arithmetic zero, instead of + having a complement pointer to 1. ] + + SideEffects [None] + + SeeAlso [Cudd_addNewVar Cudd_bddIthVar Cudd_addConst + Cudd_addNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_addIthVar( + DdManager * dd, + int i) +{ + DdNode *res; + + if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); + do { + dd->reordered = 0; + res = cuddUniqueInter(dd,i,DD_ONE(dd),DD_ZERO(dd)); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_addIthVar */ + + +/**Function******************************************************************** + + Synopsis [Returns the BDD variable with index i.] + + Description [Retrieves the BDD variable with index i if it already + exists, or creates a new BDD variable. Returns a pointer to the + variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel + Cudd_ReadVars] + +******************************************************************************/ +DdNode * +Cudd_bddIthVar( + DdManager * dd, + int i) +{ + DdNode *res; + + if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); + if (i < dd->size) { + res = dd->vars[i]; + } else { + res = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + } + + return(res); + +} /* end of Cudd_bddIthVar */ + + +/**Function******************************************************************** + + Synopsis [Returns the ZDD variable with index i.] + + Description [Retrieves the ZDD variable with index i if it already + exists, or creates a new ZDD variable. Returns a pointer to the + variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddIthVar Cudd_addIthVar] + +******************************************************************************/ +DdNode * +Cudd_zddIthVar( + DdManager * dd, + int i) +{ + DdNode *res; + DdNode *zvar; + DdNode *lower; + int j; + + if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); + + /* The i-th variable function has the following structure: + ** at the level corresponding to index i there is a node whose "then" + ** child points to the universe, and whose "else" child points to zero. + ** Above that level there are nodes with identical children. + */ + + /* First we build the node at the level of index i. */ + lower = (i < dd->sizeZ - 1) ? dd->univ[dd->permZ[i]+1] : DD_ONE(dd); + do { + dd->reordered = 0; + zvar = cuddUniqueInterZdd(dd, i, lower, DD_ZERO(dd)); + } while (dd->reordered == 1); + + if (zvar == NULL) + return(NULL); + cuddRef(zvar); + + /* Now we add the "filler" nodes above the level of index i. */ + for (j = dd->permZ[i] - 1; j >= 0; j--) { + do { + dd->reordered = 0; + res = cuddUniqueInterZdd(dd, dd->invpermZ[j], zvar, zvar); + } while (dd->reordered == 1); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd,zvar); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd,zvar); + zvar = res; + } + cuddDeref(zvar); + return(zvar); + +} /* end of Cudd_zddIthVar */ + + +/**Function******************************************************************** + + Synopsis [Creates one or more ZDD variables for each BDD variable.] + + Description [Creates one or more ZDD variables for each BDD + variable. If some ZDD variables already exist, only the missing + variables are created. Parameter multiplicity allows the caller to + control how many variables are created for each BDD variable in + existence. For instance, if ZDDs are used to represent covers, two + ZDD variables are required for each BDD variable. The order of the + BDD variables is transferred to the ZDD variables. If a variable + group tree exists for the BDD variables, a corresponding ZDD + variable group tree is created by expanding the BDD variable + tree. In any case, the ZDD variables derived from the same BDD + variable are merged in a ZDD variable group. If a ZDD variable group + tree exists, it is freed. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel] + +******************************************************************************/ +int +Cudd_zddVarsFromBddVars( + DdManager * dd /* DD manager */, + int multiplicity /* how many ZDD variables are created for each BDD variable */) +{ + int res; + int i, j; + int allnew; + int *permutation; + + if (multiplicity < 1) return(0); + allnew = dd->sizeZ == 0; + if (dd->size * multiplicity > dd->sizeZ) { + res = cuddResizeTableZdd(dd,dd->size * multiplicity - 1); + if (res == 0) return(0); + } + /* Impose the order of the BDD variables to the ZDD variables. */ + if (allnew) { + for (i = 0; i < dd->size; i++) { + for (j = 0; j < multiplicity; j++) { + dd->permZ[i * multiplicity + j] = + dd->perm[i] * multiplicity + j; + dd->invpermZ[dd->permZ[i * multiplicity + j]] = + i * multiplicity + j; + } + } + for (i = 0; i < dd->sizeZ; i++) { + dd->univ[i]->index = dd->invpermZ[i]; + } + } else { + permutation = ALLOC(int,dd->sizeZ); + if (permutation == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < dd->size; i++) { + for (j = 0; j < multiplicity; j++) { + permutation[i * multiplicity + j] = + dd->invperm[i] * multiplicity + j; + } + } + for (i = dd->size * multiplicity; i < dd->sizeZ; i++) { + permutation[i] = i; + } + res = Cudd_zddShuffleHeap(dd, permutation); + FREE(permutation); + if (res == 0) return(0); + } + /* Copy and expand the variable group tree if it exists. */ + if (dd->treeZ != NULL) { + Cudd_FreeZddTree(dd); + } + if (dd->tree != NULL) { + dd->treeZ = Mtr_CopyTree(dd->tree, multiplicity); + if (dd->treeZ == NULL) return(0); + } else if (multiplicity > 1) { + dd->treeZ = Mtr_InitGroupTree(0, dd->sizeZ); + if (dd->treeZ == NULL) return(0); + dd->treeZ->index = dd->invpermZ[0]; + } + /* Create groups for the ZDD variables derived from the same BDD variable. + */ + if (multiplicity > 1) { + char *vmask, *lmask; + + vmask = ALLOC(char, dd->size); + if (vmask == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + lmask = ALLOC(char, dd->size); + if (lmask == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < dd->size; i++) { + vmask[i] = lmask[i] = 0; + } + res = addMultiplicityGroups(dd,dd->treeZ,multiplicity,vmask,lmask); + FREE(vmask); + FREE(lmask); + if (res == 0) return(0); + } + return(1); + +} /* end of Cudd_zddVarsFromBddVars */ + + +/**Function******************************************************************** + + Synopsis [Returns the ADD for constant c.] + + Description [Retrieves the ADD for constant c if it already + exists, or creates a new ADD. Returns a pointer to the + ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNewVar Cudd_addIthVar] + +******************************************************************************/ +DdNode * +Cudd_addConst( + DdManager * dd, + CUDD_VALUE_TYPE c) +{ + return(cuddUniqueConst(dd,c)); + +} /* end of Cudd_addConst */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if a DD node is not constant.] + + Description [Returns 1 if a DD node is not constant. This function is + useful to test the results of Cudd_bddIteConstant, Cudd_addIteConstant, + Cudd_addEvalConst. These results may be a special value signifying + non-constant. In the other cases the macro Cudd_IsConstant can be used.] + + SideEffects [None] + + SeeAlso [Cudd_IsConstant Cudd_bddIteConstant Cudd_addIteConstant + Cudd_addEvalConst] + +******************************************************************************/ +int +Cudd_IsNonConstant( + DdNode *f) +{ + return(f == DD_NON_CONSTANT || !Cudd_IsConstant(f)); + +} /* end of Cudd_IsNonConstant */ + + +/**Function******************************************************************** + + Synopsis [Returns the start time of the manager.] + + Description [Returns the start time of the manager. This is initially set + to the number of milliseconds since the program started, but may be reset by + the application.] + + SideEffects [None] + + SeeAlso [Cudd_SetStartTime Cudd_ResetStartTime Cudd_ReadTimeLimit] + +******************************************************************************/ +unsigned long +Cudd_ReadStartTime( + DdManager * unique) +{ + return unique->startTime; + +} /* end of Cudd_ReadStartTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the time elapsed since the start time of the manager.] + + Description [Returns the time elapsed since the start time of the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadStartTime Cudd_SetStartTime] + +******************************************************************************/ +unsigned long +Cudd_ReadElapsedTime( + DdManager * unique) +{ + return util_cpu_time() - unique->startTime; + +} /* end of Cudd_ReadElapsedTime */ + + +/**Function******************************************************************** + + Synopsis [Sets the start time of the manager.] + + Description [Sets the start time of the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadStartTime Cudd_ResetStartTime Cudd_ReadElapsedTime + Cudd_SetTimeLimit] + +******************************************************************************/ +void +Cudd_SetStartTime( + DdManager * unique, + unsigned long st) +{ + unique->startTime = st; + +} /* end of Cudd_SetStartTime */ + + +/**Function******************************************************************** + + Synopsis [Resets the start time of the manager.] + + Description [Resets the start time of the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadStartTime Cudd_SetStartTime Cudd_SetTimeLimit] + +******************************************************************************/ +void +Cudd_ResetStartTime( + DdManager * unique) +{ + unique->startTime = util_cpu_time(); + +} /* end of Cudd_ResetStartTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the time limit for the manager.] + + Description [Returns the time limit for the manager. This is initially set + to a very large number, but may be reset by the application.] + + SideEffects [None] + + SeeAlso [Cudd_SetTimeLimit Cudd_UpdateTimeLimit Cudd_UnsetTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_ReadStartTime] + +******************************************************************************/ +unsigned long +Cudd_ReadTimeLimit( + DdManager * unique) +{ + return unique->timeLimit; + +} /* end of Cudd_ReadTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Sets the time limit for the manager.] + + Description [Sets the time limit for the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_UnsetTimeLimit Cudd_UpdateTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_SetTimeLimit( + DdManager * unique, + unsigned long tl) +{ + unique->timeLimit = tl; + +} /* end of Cudd_SetTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Updates the time limit for the manager.] + + Description [Updates the time limit for the manager by subtracting the + elapsed time from it.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UnsetTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_UpdateTimeLimit( + DdManager * unique) +{ + unsigned long elapsed; + if (unique->timeLimit == ~0UL) + return; + elapsed = util_cpu_time() - unique->startTime; + if (unique->timeLimit >= elapsed) { + unique->timeLimit -= elapsed; + } else { + unique->timeLimit = 0; + } + +} /* end of Cudd_UpdateTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Increases the time limit for the manager.] + + Description [Increases the time limit for the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UnsetTimeLimit + Cudd_UpdateTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_IncreaseTimeLimit( + DdManager * unique, + unsigned long increase) +{ + if (unique->timeLimit == ~0UL) + unique->timeLimit = increase; + else + unique->timeLimit += increase; + +} /* end of Cudd_IncreaseTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Unsets the time limit for the manager.] + + Description [Unsets the time limit for the manager. Actually, sets it to + a very large value.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UpdateTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_UnsetTimeLimit( + DdManager * unique) +{ + unique->timeLimit = ~0UL; + +} /* end of Cudd_UnsetTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Returns true if the time limit for the manager is set.] + + Description [Returns true if the time limit for the manager is set.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UpdateTimeLimit + Cudd_UnsetTimeLimit Cudd_IncreaseTimeLimit] + +******************************************************************************/ +int +Cudd_TimeLimited( + DdManager * unique) +{ + return unique->timeLimit != ~0UL; + +} /* end of Cudd_TimeLimited */ + + +/**Function******************************************************************** + + Synopsis [Enables automatic dynamic reordering of BDDs and ADDs.] + + Description [Enables automatic dynamic reordering of BDDs and + ADDs. Parameter method is used to determine the method used for + reordering. If CUDD_REORDER_SAME is passed, the method is + unchanged.] + + SideEffects [None] + + SeeAlso [Cudd_AutodynDisable Cudd_ReorderingStatus + Cudd_AutodynEnableZdd] + +******************************************************************************/ +void +Cudd_AutodynEnable( + DdManager * unique, + Cudd_ReorderingType method) +{ + unique->autoDyn = 1; + if (method != CUDD_REORDER_SAME) { + unique->autoMethod = method; + } +#ifndef DD_NO_DEATH_ROW + /* If reordering is enabled, using the death row causes too many + ** invocations. Hence, we shrink the death row to just one entry. + */ + cuddClearDeathRow(unique); + unique->deathRowDepth = 1; + unique->deadMask = unique->deathRowDepth - 1; + if ((unsigned) unique->nextDead > unique->deadMask) { + unique->nextDead = 0; + } + unique->deathRow = REALLOC(DdNodePtr, unique->deathRow, + unique->deathRowDepth); +#endif + return; + +} /* end of Cudd_AutodynEnable */ + + +/**Function******************************************************************** + + Synopsis [Disables automatic dynamic reordering.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_AutodynEnable Cudd_ReorderingStatus + Cudd_AutodynDisableZdd] + +******************************************************************************/ +void +Cudd_AutodynDisable( + DdManager * unique) +{ + unique->autoDyn = 0; + return; + +} /* end of Cudd_AutodynDisable */ + + +/**Function******************************************************************** + + Synopsis [Reports the status of automatic dynamic reordering of BDDs + and ADDs.] + + Description [Reports the status of automatic dynamic reordering of + BDDs and ADDs. Parameter method is set to the reordering method + currently selected. Returns 1 if automatic reordering is enabled; 0 + otherwise.] + + SideEffects [Parameter method is set to the reordering method currently + selected.] + + SeeAlso [Cudd_AutodynEnable Cudd_AutodynDisable + Cudd_ReorderingStatusZdd] + +******************************************************************************/ +int +Cudd_ReorderingStatus( + DdManager * unique, + Cudd_ReorderingType * method) +{ + *method = unique->autoMethod; + return(unique->autoDyn); + +} /* end of Cudd_ReorderingStatus */ + + +/**Function******************************************************************** + + Synopsis [Enables automatic dynamic reordering of ZDDs.] + + Description [Enables automatic dynamic reordering of ZDDs. Parameter + method is used to determine the method used for reordering ZDDs. If + CUDD_REORDER_SAME is passed, the method is unchanged.] + + SideEffects [None] + + SeeAlso [Cudd_AutodynDisableZdd Cudd_ReorderingStatusZdd + Cudd_AutodynEnable] + +******************************************************************************/ +void +Cudd_AutodynEnableZdd( + DdManager * unique, + Cudd_ReorderingType method) +{ + unique->autoDynZ = 1; + if (method != CUDD_REORDER_SAME) { + unique->autoMethodZ = method; + } + return; + +} /* end of Cudd_AutodynEnableZdd */ + + +/**Function******************************************************************** + + Synopsis [Disables automatic dynamic reordering of ZDDs.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_AutodynEnableZdd Cudd_ReorderingStatusZdd + Cudd_AutodynDisable] + +******************************************************************************/ +void +Cudd_AutodynDisableZdd( + DdManager * unique) +{ + unique->autoDynZ = 0; + return; + +} /* end of Cudd_AutodynDisableZdd */ + + +/**Function******************************************************************** + + Synopsis [Reports the status of automatic dynamic reordering of ZDDs.] + + Description [Reports the status of automatic dynamic reordering of + ZDDs. Parameter method is set to the ZDD reordering method currently + selected. Returns 1 if automatic reordering is enabled; 0 + otherwise.] + + SideEffects [Parameter method is set to the ZDD reordering method currently + selected.] + + SeeAlso [Cudd_AutodynEnableZdd Cudd_AutodynDisableZdd + Cudd_ReorderingStatus] + +******************************************************************************/ +int +Cudd_ReorderingStatusZdd( + DdManager * unique, + Cudd_ReorderingType * method) +{ + *method = unique->autoMethodZ; + return(unique->autoDynZ); + +} /* end of Cudd_ReorderingStatusZdd */ + + +/**Function******************************************************************** + + Synopsis [Tells whether the realignment of ZDD order to BDD order is + enabled.] + + Description [Returns 1 if the realignment of ZDD order to BDD order is + enabled; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddRealignEnable Cudd_zddRealignDisable + Cudd_bddRealignEnable Cudd_bddRealignDisable] + +******************************************************************************/ +int +Cudd_zddRealignmentEnabled( + DdManager * unique) +{ + return(unique->realign); + +} /* end of Cudd_zddRealignmentEnabled */ + + +/**Function******************************************************************** + + Synopsis [Enables realignment of ZDD order to BDD order.] + + Description [Enables realignment of the ZDD variable order to the + BDD variable order after the BDDs and ADDs have been reordered. The + number of ZDD variables must be a multiple of the number of BDD + variables for realignment to make sense. If this condition is not met, + Cudd_ReduceHeap will return 0. Let M be the + ratio of the two numbers. For the purpose of realignment, the ZDD + variables from M*i to (M+1)*i-1 are + reagarded as corresponding to BDD variable i. Realignment + is initially disabled.] + + SideEffects [None] + + SeeAlso [Cudd_ReduceHeap Cudd_zddRealignDisable + Cudd_zddRealignmentEnabled Cudd_bddRealignDisable + Cudd_bddRealignmentEnabled] + +******************************************************************************/ +void +Cudd_zddRealignEnable( + DdManager * unique) +{ + unique->realign = 1; + return; + +} /* end of Cudd_zddRealignEnable */ + + +/**Function******************************************************************** + + Synopsis [Disables realignment of ZDD order to BDD order.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddRealignEnable Cudd_zddRealignmentEnabled + Cudd_bddRealignEnable Cudd_bddRealignmentEnabled] + +******************************************************************************/ +void +Cudd_zddRealignDisable( + DdManager * unique) +{ + unique->realign = 0; + return; + +} /* end of Cudd_zddRealignDisable */ + + +/**Function******************************************************************** + + Synopsis [Tells whether the realignment of BDD order to ZDD order is + enabled.] + + Description [Returns 1 if the realignment of BDD order to ZDD order is + enabled; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddRealignEnable Cudd_bddRealignDisable + Cudd_zddRealignEnable Cudd_zddRealignDisable] + +******************************************************************************/ +int +Cudd_bddRealignmentEnabled( + DdManager * unique) +{ + return(unique->realignZ); + +} /* end of Cudd_bddRealignmentEnabled */ + + +/**Function******************************************************************** + + Synopsis [Enables realignment of BDD order to ZDD order.] + + Description [Enables realignment of the BDD variable order to the + ZDD variable order after the ZDDs have been reordered. The + number of ZDD variables must be a multiple of the number of BDD + variables for realignment to make sense. If this condition is not met, + Cudd_zddReduceHeap will return 0. Let M be the + ratio of the two numbers. For the purpose of realignment, the ZDD + variables from M*i to (M+1)*i-1 are + reagarded as corresponding to BDD variable i. Realignment + is initially disabled.] + + SideEffects [None] + + SeeAlso [Cudd_zddReduceHeap Cudd_bddRealignDisable + Cudd_bddRealignmentEnabled Cudd_zddRealignDisable + Cudd_zddRealignmentEnabled] + +******************************************************************************/ +void +Cudd_bddRealignEnable( + DdManager * unique) +{ + unique->realignZ = 1; + return; + +} /* end of Cudd_bddRealignEnable */ + + +/**Function******************************************************************** + + Synopsis [Disables realignment of ZDD order to BDD order.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_bddRealignEnable Cudd_bddRealignmentEnabled + Cudd_zddRealignEnable Cudd_zddRealignmentEnabled] + +******************************************************************************/ +void +Cudd_bddRealignDisable( + DdManager * unique) +{ + unique->realignZ = 0; + return; + +} /* end of Cudd_bddRealignDisable */ + + +/**Function******************************************************************** + + Synopsis [Returns the one constant of the manager.] + + Description [Returns the one constant of the manager. The one + constant is common to ADDs and BDDs.] + + SideEffects [None] + + SeeAlso [Cudd_ReadZero Cudd_ReadLogicZero Cudd_ReadZddOne] + +******************************************************************************/ +DdNode * +Cudd_ReadOne( + DdManager * dd) +{ + return(dd->one); + +} /* end of Cudd_ReadOne */ + + +/**Function******************************************************************** + + Synopsis [Returns the ZDD for the constant 1 function.] + + Description [Returns the ZDD for the constant 1 function. + The representation of the constant 1 function as a ZDD depends on + how many variables it (nominally) depends on. The index of the + topmost variable in the support is given as argument i.] + + SideEffects [None] + + SeeAlso [Cudd_ReadOne] + +******************************************************************************/ +DdNode * +Cudd_ReadZddOne( + DdManager * dd, + int i) +{ + if (i < 0) + return(NULL); + return(i < dd->sizeZ ? dd->univ[i] : DD_ONE(dd)); + +} /* end of Cudd_ReadZddOne */ + + + +/**Function******************************************************************** + + Synopsis [Returns the zero constant of the manager.] + + Description [Returns the zero constant of the manager. The zero + constant is the arithmetic zero, rather than the logic zero. The + latter is the complement of the one constant.] + + SideEffects [None] + + SeeAlso [Cudd_ReadOne Cudd_ReadLogicZero] + +******************************************************************************/ +DdNode * +Cudd_ReadZero( + DdManager * dd) +{ + return(DD_ZERO(dd)); + +} /* end of Cudd_ReadZero */ + + +/**Function******************************************************************** + + Synopsis [Returns the logic zero constant of the manager.] + + Description [Returns the zero constant of the manager. The logic zero + constant is the complement of the one constant, and is distinct from + the arithmetic zero.] + + SideEffects [None] + + SeeAlso [Cudd_ReadOne Cudd_ReadZero] + +******************************************************************************/ +DdNode * +Cudd_ReadLogicZero( + DdManager * dd) +{ + return(Cudd_Not(DD_ONE(dd))); + +} /* end of Cudd_ReadLogicZero */ + + +/**Function******************************************************************** + + Synopsis [Reads the plus-infinity constant from the manager.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_ReadPlusInfinity( + DdManager * dd) +{ + return(dd->plusinfinity); + +} /* end of Cudd_ReadPlusInfinity */ + + +/**Function******************************************************************** + + Synopsis [Reads the minus-infinity constant from the manager.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_ReadMinusInfinity( + DdManager * dd) +{ + return(dd->minusinfinity); + +} /* end of Cudd_ReadMinusInfinity */ + + +/**Function******************************************************************** + + Synopsis [Reads the background constant of the manager.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_ReadBackground( + DdManager * dd) +{ + return(dd->background); + +} /* end of Cudd_ReadBackground */ + + +/**Function******************************************************************** + + Synopsis [Sets the background constant of the manager.] + + Description [Sets the background constant of the manager. It assumes + that the DdNode pointer bck is already referenced.] + + SideEffects [None] + +******************************************************************************/ +void +Cudd_SetBackground( + DdManager * dd, + DdNode * bck) +{ + dd->background = bck; + +} /* end of Cudd_SetBackground */ + + +/**Function******************************************************************** + + Synopsis [Reads the number of slots in the cache.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadCacheUsedSlots] + +******************************************************************************/ +unsigned int +Cudd_ReadCacheSlots( + DdManager * dd) +{ + return(dd->cacheSlots); + +} /* end of Cudd_ReadCacheSlots */ + + +/**Function******************************************************************** + + Synopsis [Reads the fraction of used slots in the cache.] + + Description [Reads the fraction of used slots in the cache. The unused + slots are those in which no valid data is stored. Garbage collection, + variable reordering, and cache resizing may cause used slots to become + unused.] + + SideEffects [None] + + SeeAlso [Cudd_ReadCacheSlots] + +******************************************************************************/ +double +Cudd_ReadCacheUsedSlots( + DdManager * dd) +{ + unsigned long used = 0; + int slots = dd->cacheSlots; + DdCache *cache = dd->cache; + int i; + + for (i = 0; i < slots; i++) { + used += cache[i].h != 0; + } + + return((double)used / (double) dd->cacheSlots); + +} /* end of Cudd_ReadCacheUsedSlots */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of cache look-ups.] + + Description [Returns the number of cache look-ups.] + + SideEffects [None] + + SeeAlso [Cudd_ReadCacheHits] + +******************************************************************************/ +double +Cudd_ReadCacheLookUps( + DdManager * dd) +{ + return(dd->cacheHits + dd->cacheMisses + + dd->totCachehits + dd->totCacheMisses); + +} /* end of Cudd_ReadCacheLookUps */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of cache hits.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadCacheLookUps] + +******************************************************************************/ +double +Cudd_ReadCacheHits( + DdManager * dd) +{ + return(dd->cacheHits + dd->totCachehits); + +} /* end of Cudd_ReadCacheHits */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of recursive calls.] + + Description [Returns the number of recursive calls if the package is + compiled with DD_COUNT defined.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +double +Cudd_ReadRecursiveCalls( + DdManager * dd) +{ +#ifdef DD_COUNT + return(dd->recursiveCalls); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadRecursiveCalls */ + + + +/**Function******************************************************************** + + Synopsis [Reads the hit rate that causes resizinig of the computed + table.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetMinHit] + +******************************************************************************/ +unsigned int +Cudd_ReadMinHit( + DdManager * dd) +{ + /* Internally, the package manipulates the ratio of hits to + ** misses instead of the ratio of hits to accesses. */ + return((unsigned int) (0.5 + 100 * dd->minHit / (1 + dd->minHit))); + +} /* end of Cudd_ReadMinHit */ + + +/**Function******************************************************************** + + Synopsis [Sets the hit rate that causes resizinig of the computed + table.] + + Description [Sets the minHit parameter of the manager. This + parameter controls the resizing of the computed table. If the hit + rate is larger than the specified value, and the cache is not + already too large, then its size is doubled.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMinHit] + +******************************************************************************/ +void +Cudd_SetMinHit( + DdManager * dd, + unsigned int hr) +{ + /* Internally, the package manipulates the ratio of hits to + ** misses instead of the ratio of hits to accesses. */ + dd->minHit = (double) hr / (100.0 - (double) hr); + +} /* end of Cudd_SetMinHit */ + + +/**Function******************************************************************** + + Synopsis [Reads the looseUpTo parameter of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetLooseUpTo Cudd_ReadMinHit Cudd_ReadMinDead] + +******************************************************************************/ +unsigned int +Cudd_ReadLooseUpTo( + DdManager * dd) +{ + return(dd->looseUpTo); + +} /* end of Cudd_ReadLooseUpTo */ + + +/**Function******************************************************************** + + Synopsis [Sets the looseUpTo parameter of the manager.] + + Description [Sets the looseUpTo parameter of the manager. This + parameter of the manager controls the threshold beyond which no fast + growth of the unique table is allowed. The threshold is given as a + number of slots. If the value passed to this function is 0, the + function determines a suitable value based on the available memory.] + + SideEffects [None] + + SeeAlso [Cudd_ReadLooseUpTo Cudd_SetMinHit] + +******************************************************************************/ +void +Cudd_SetLooseUpTo( + DdManager * dd, + unsigned int lut) +{ + if (lut == 0) { + unsigned long datalimit = getSoftDataLimit(); + lut = (unsigned int) (datalimit / (sizeof(DdNode) * + DD_MAX_LOOSE_FRACTION)); + } + dd->looseUpTo = lut; + +} /* end of Cudd_SetLooseUpTo */ + + +/**Function******************************************************************** + + Synopsis [Returns the soft limit for the cache size.] + + Description [Returns the soft limit for the cache size.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxCacheHard] + +******************************************************************************/ +unsigned int +Cudd_ReadMaxCache( + DdManager * dd) +{ + return(2 * dd->cacheSlots + dd->cacheSlack); + +} /* end of Cudd_ReadMaxCache */ + + +/**Function******************************************************************** + + Synopsis [Reads the maxCacheHard parameter of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetMaxCacheHard Cudd_ReadMaxCache] + +******************************************************************************/ +unsigned int +Cudd_ReadMaxCacheHard( + DdManager * dd) +{ + return(dd->maxCacheHard); + +} /* end of Cudd_ReadMaxCache */ + + +/**Function******************************************************************** + + Synopsis [Sets the maxCacheHard parameter of the manager.] + + Description [Sets the maxCacheHard parameter of the manager. The + cache cannot grow larger than maxCacheHard entries. This parameter + allows an application to control the trade-off of memory versus + speed. If the value passed to this function is 0, the function + determines a suitable maximum cache size based on the available memory.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxCacheHard Cudd_SetMaxCache] + +******************************************************************************/ +void +Cudd_SetMaxCacheHard( + DdManager * dd, + unsigned int mc) +{ + if (mc == 0) { + unsigned long datalimit = getSoftDataLimit(); + mc = (unsigned int) (datalimit / (sizeof(DdCache) * + DD_MAX_CACHE_FRACTION)); + } + dd->maxCacheHard = mc; + +} /* end of Cudd_SetMaxCacheHard */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of BDD variables in existance.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadZddSize] + +******************************************************************************/ +int +Cudd_ReadSize( + DdManager * dd) +{ + return(dd->size); + +} /* end of Cudd_ReadSize */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of ZDD variables in existance.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadSize] + +******************************************************************************/ +int +Cudd_ReadZddSize( + DdManager * dd) +{ + return(dd->sizeZ); + +} /* end of Cudd_ReadZddSize */ + + +/**Function******************************************************************** + + Synopsis [Returns the total number of slots of the unique table.] + + Description [Returns the total number of slots of the unique table. + This number ismainly for diagnostic purposes.] + + SideEffects [None] + +******************************************************************************/ +unsigned int +Cudd_ReadSlots( + DdManager * dd) +{ + return(dd->slots); + +} /* end of Cudd_ReadSlots */ + + +/**Function******************************************************************** + + Synopsis [Reads the fraction of used slots in the unique table.] + + Description [Reads the fraction of used slots in the unique + table. The unused slots are those in which no valid data is + stored. Garbage collection, variable reordering, and subtable + resizing may cause used slots to become unused.] + + SideEffects [None] + + SeeAlso [Cudd_ReadSlots] + +******************************************************************************/ +double +Cudd_ReadUsedSlots( + DdManager * dd) +{ + unsigned long used = 0; + int i, j; + int size = dd->size; + DdNodePtr *nodelist; + DdSubtable *subtable; + DdNode *node; + DdNode *sentinel = &(dd->sentinel); + + /* Scan each BDD/ADD subtable. */ + for (i = 0; i < size; i++) { + subtable = &(dd->subtables[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != sentinel) { + used++; + } + } + } + + /* Scan the ZDD subtables. */ + size = dd->sizeZ; + + for (i = 0; i < size; i++) { + subtable = &(dd->subtableZ[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + used++; + } + } + } + + /* Constant table. */ + subtable = &(dd->constants); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + used++; + } + } + + return((double)used / (double) dd->slots); + +} /* end of Cudd_ReadUsedSlots */ + + +/**Function******************************************************************** + + Synopsis [Computes the expected fraction of used slots in the unique + table.] + + Description [Computes the fraction of slots in the unique table that + should be in use. This expected value is based on the assumption + that the hash function distributes the keys randomly; it can be + compared with the result of Cudd_ReadUsedSlots to monitor the + performance of the unique table hash function.] + + SideEffects [None] + + SeeAlso [Cudd_ReadSlots Cudd_ReadUsedSlots] + +******************************************************************************/ +double +Cudd_ExpectedUsedSlots( + DdManager * dd) +{ + int i; + int size = dd->size; + DdSubtable *subtable; + double empty = 0.0; + + /* To each subtable we apply the corollary to Theorem 8.5 (occupancy + ** distribution) from Sedgewick and Flajolet's Analysis of Algorithms. + ** The corollary says that for a table with M buckets and a load ratio + ** of r, the expected number of empty buckets is asymptotically given + ** by M * exp(-r). + */ + + /* Scan each BDD/ADD subtable. */ + for (i = 0; i < size; i++) { + subtable = &(dd->subtables[i]); + empty += (double) subtable->slots * + exp(-(double) subtable->keys / (double) subtable->slots); + } + + /* Scan the ZDD subtables. */ + size = dd->sizeZ; + + for (i = 0; i < size; i++) { + subtable = &(dd->subtableZ[i]); + empty += (double) subtable->slots * + exp(-(double) subtable->keys / (double) subtable->slots); + } + + /* Constant table. */ + subtable = &(dd->constants); + empty += (double) subtable->slots * + exp(-(double) subtable->keys / (double) subtable->slots); + + return(1.0 - empty / (double) dd->slots); + +} /* end of Cudd_ExpectedUsedSlots */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of nodes in the unique table.] + + Description [Returns the total number of nodes currently in the unique + table, including the dead nodes.] + + SideEffects [None] + + SeeAlso [Cudd_ReadDead] + +******************************************************************************/ +unsigned int +Cudd_ReadKeys( + DdManager * dd) +{ + return(dd->keys); + +} /* end of Cudd_ReadKeys */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of dead nodes in the unique table.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadKeys] + +******************************************************************************/ +unsigned int +Cudd_ReadDead( + DdManager * dd) +{ + return(dd->dead); + +} /* end of Cudd_ReadDead */ + + +/**Function******************************************************************** + + Synopsis [Reads the minDead parameter of the manager.] + + Description [Reads the minDead parameter of the manager. The minDead + parameter is used by the package to decide whether to collect garbage + or resize a subtable of the unique table when the subtable becomes + too full. The application can indirectly control the value of minDead + by setting the looseUpTo parameter.] + + SideEffects [None] + + SeeAlso [Cudd_ReadDead Cudd_ReadLooseUpTo Cudd_SetLooseUpTo] + +******************************************************************************/ +unsigned int +Cudd_ReadMinDead( + DdManager * dd) +{ + return(dd->minDead); + +} /* end of Cudd_ReadMinDead */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of times reordering has occurred.] + + Description [Returns the number of times reordering has occurred in the + manager. The number includes both the calls to Cudd_ReduceHeap from + the application program and those automatically performed by the + package. However, calls that do not even initiate reordering are not + counted. A call may not initiate reordering if there are fewer than + minsize live nodes in the manager, or if CUDD_REORDER_NONE is specified + as reordering method. The calls to Cudd_ShuffleHeap are not counted.] + + SideEffects [None] + + SeeAlso [Cudd_ReduceHeap Cudd_ReadReorderingTime] + +******************************************************************************/ +unsigned int +Cudd_ReadReorderings( + DdManager * dd) +{ + return(dd->reorderings); + +} /* end of Cudd_ReadReorderings */ + + +/**Function******************************************************************** + + Synopsis [Returns the maximum number of times reordering may be invoked.] + + Description [Returns the maximum number of times reordering may be invoked in + this manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadReorderings Cudd_SetMaxReorderings Cudd_ReduceHeap] + +******************************************************************************/ +unsigned int +Cudd_ReadMaxReorderings( + DdManager * dd) +{ + return(dd->maxReorderings); + +} /* end of Cudd_ReadMaxReorderings */ + + +/**Function******************************************************************** + + Synopsis [Sets the maximum number of times reordering may be invoked.] + + Description [Sets the maximum number of times reordering may be invoked in + this manager. The default value is (practically) infinite.] + + SideEffects [None] + + SeeAlso [Cudd_ReadReorderings Cudd_ReadMaxReorderings Cudd_ReduceHeap] + +******************************************************************************/ +void +Cudd_SetMaxReorderings( + DdManager * dd, unsigned int mr) +{ + dd->maxReorderings = mr; + +} /* end of Cudd_SetMaxReorderings */ + + +/**Function******************************************************************** + + Synopsis [Returns the time spent in reordering.] + + Description [Returns the number of milliseconds spent reordering + variables since the manager was initialized. The time spent in collecting + garbage before reordering is included.] + + SideEffects [None] + + SeeAlso [Cudd_ReadReorderings] + +******************************************************************************/ +long +Cudd_ReadReorderingTime( + DdManager * dd) +{ + return(dd->reordTime); + +} /* end of Cudd_ReadReorderingTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of times garbage collection has occurred.] + + Description [Returns the number of times garbage collection has + occurred in the manager. The number includes both the calls from + reordering procedures and those caused by requests to create new + nodes.] + + SideEffects [None] + + SeeAlso [Cudd_ReadGarbageCollectionTime] + +******************************************************************************/ +int +Cudd_ReadGarbageCollections( + DdManager * dd) +{ + return(dd->garbageCollections); + +} /* end of Cudd_ReadGarbageCollections */ + + +/**Function******************************************************************** + + Synopsis [Returns the time spent in garbage collection.] + + Description [Returns the number of milliseconds spent doing garbage + collection since the manager was initialized.] + + SideEffects [None] + + SeeAlso [Cudd_ReadGarbageCollections] + +******************************************************************************/ +long +Cudd_ReadGarbageCollectionTime( + DdManager * dd) +{ + return(dd->GCTime); + +} /* end of Cudd_ReadGarbageCollectionTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of nodes freed.] + + Description [Returns the number of nodes returned to the free list if the + keeping of this statistic is enabled; -1 otherwise. This statistic is + enabled only if the package is compiled with DD_STATS defined.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNodesDropped] + +******************************************************************************/ +double +Cudd_ReadNodesFreed( + DdManager * dd) +{ +#ifdef DD_STATS + return(dd->nodesFreed); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadNodesFreed */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of nodes dropped.] + + Description [Returns the number of nodes killed by dereferencing if the + keeping of this statistic is enabled; -1 otherwise. This statistic is + enabled only if the package is compiled with DD_STATS defined.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNodesFreed] + +******************************************************************************/ +double +Cudd_ReadNodesDropped( + DdManager * dd) +{ +#ifdef DD_STATS + return(dd->nodesDropped); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadNodesDropped */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of look-ups in the unique table.] + + Description [Returns the number of look-ups in the unique table if the + keeping of this statistic is enabled; -1 otherwise. This statistic is + enabled only if the package is compiled with DD_UNIQUE_PROFILE defined.] + + SideEffects [None] + + SeeAlso [Cudd_ReadUniqueLinks] + +******************************************************************************/ +double +Cudd_ReadUniqueLookUps( + DdManager * dd) +{ +#ifdef DD_UNIQUE_PROFILE + return(dd->uniqueLookUps); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadUniqueLookUps */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of links followed in the unique table.] + + Description [Returns the number of links followed during look-ups in the + unique table if the keeping of this statistic is enabled; -1 otherwise. + If an item is found in the first position of its collision list, the + number of links followed is taken to be 0. If it is in second position, + the number of links is 1, and so on. This statistic is enabled only if + the package is compiled with DD_UNIQUE_PROFILE defined.] + + SideEffects [None] + + SeeAlso [Cudd_ReadUniqueLookUps] + +******************************************************************************/ +double +Cudd_ReadUniqueLinks( + DdManager * dd) +{ +#ifdef DD_UNIQUE_PROFILE + return(dd->uniqueLinks); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadUniqueLinks */ + + +/**Function******************************************************************** + + Synopsis [Reads the siftMaxVar parameter of the manager.] + + Description [Reads the siftMaxVar parameter of the manager. This + parameter gives the maximum number of variables that will be sifted + for each invocation of sifting.] + + SideEffects [None] + + SeeAlso [Cudd_ReadSiftMaxSwap Cudd_SetSiftMaxVar] + +******************************************************************************/ +int +Cudd_ReadSiftMaxVar( + DdManager * dd) +{ + return(dd->siftMaxVar); + +} /* end of Cudd_ReadSiftMaxVar */ + + +/**Function******************************************************************** + + Synopsis [Sets the siftMaxVar parameter of the manager.] + + Description [Sets the siftMaxVar parameter of the manager. This + parameter gives the maximum number of variables that will be sifted + for each invocation of sifting.] + + SideEffects [None] + + SeeAlso [Cudd_SetSiftMaxSwap Cudd_ReadSiftMaxVar] + +******************************************************************************/ +void +Cudd_SetSiftMaxVar( + DdManager * dd, + int smv) +{ + dd->siftMaxVar = smv; + +} /* end of Cudd_SetSiftMaxVar */ + + +/**Function******************************************************************** + + Synopsis [Reads the siftMaxSwap parameter of the manager.] + + Description [Reads the siftMaxSwap parameter of the manager. This + parameter gives the maximum number of swaps that will be attempted + for each invocation of sifting. The real number of swaps may exceed + the set limit because the package will always complete the sifting + of the variable that causes the limit to be reached.] + + SideEffects [None] + + SeeAlso [Cudd_ReadSiftMaxVar Cudd_SetSiftMaxSwap] + +******************************************************************************/ +int +Cudd_ReadSiftMaxSwap( + DdManager * dd) +{ + return(dd->siftMaxSwap); + +} /* end of Cudd_ReadSiftMaxSwap */ + + +/**Function******************************************************************** + + Synopsis [Sets the siftMaxSwap parameter of the manager.] + + Description [Sets the siftMaxSwap parameter of the manager. This + parameter gives the maximum number of swaps that will be attempted + for each invocation of sifting. The real number of swaps may exceed + the set limit because the package will always complete the sifting + of the variable that causes the limit to be reached.] + + SideEffects [None] + + SeeAlso [Cudd_SetSiftMaxVar Cudd_ReadSiftMaxSwap] + +******************************************************************************/ +void +Cudd_SetSiftMaxSwap( + DdManager * dd, + int sms) +{ + dd->siftMaxSwap = sms; + +} /* end of Cudd_SetSiftMaxSwap */ + + +/**Function******************************************************************** + + Synopsis [Reads the maxGrowth parameter of the manager.] + + Description [Reads the maxGrowth parameter of the manager. This + parameter determines how much the number of nodes can grow during + sifting of a variable. Overall, sifting never increases the size of + the decision diagrams. This parameter only refers to intermediate + results. A lower value will speed up sifting, possibly at the + expense of quality.] + + SideEffects [None] + + SeeAlso [Cudd_SetMaxGrowth Cudd_ReadMaxGrowthAlternate] + +******************************************************************************/ +double +Cudd_ReadMaxGrowth( + DdManager * dd) +{ + return(dd->maxGrowth); + +} /* end of Cudd_ReadMaxGrowth */ + + +/**Function******************************************************************** + + Synopsis [Sets the maxGrowth parameter of the manager.] + + Description [Sets the maxGrowth parameter of the manager. This + parameter determines how much the number of nodes can grow during + sifting of a variable. Overall, sifting never increases the size of + the decision diagrams. This parameter only refers to intermediate + results. A lower value will speed up sifting, possibly at the + expense of quality.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate] + +******************************************************************************/ +void +Cudd_SetMaxGrowth( + DdManager * dd, + double mg) +{ + dd->maxGrowth = mg; + +} /* end of Cudd_SetMaxGrowth */ + + +/**Function******************************************************************** + + Synopsis [Reads the maxGrowthAlt parameter of the manager.] + + Description [Reads the maxGrowthAlt parameter of the manager. This + parameter is analogous to the maxGrowth paramter, and is used every + given number of reorderings instead of maxGrowth. The number of + reorderings is set with Cudd_SetReorderingCycle. If the number of + reorderings is 0 (default) maxGrowthAlt is never used.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate + Cudd_SetReorderingCycle Cudd_ReadReorderingCycle] + +******************************************************************************/ +double +Cudd_ReadMaxGrowthAlternate( + DdManager * dd) +{ + return(dd->maxGrowthAlt); + +} /* end of Cudd_ReadMaxGrowthAlternate */ + + +/**Function******************************************************************** + + Synopsis [Sets the maxGrowthAlt parameter of the manager.] + + Description [Sets the maxGrowthAlt parameter of the manager. This + parameter is analogous to the maxGrowth paramter, and is used every + given number of reorderings instead of maxGrowth. The number of + reorderings is set with Cudd_SetReorderingCycle. If the number of + reorderings is 0 (default) maxGrowthAlt is never used.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowth + Cudd_SetReorderingCycle Cudd_ReadReorderingCycle] + +******************************************************************************/ +void +Cudd_SetMaxGrowthAlternate( + DdManager * dd, + double mg) +{ + dd->maxGrowthAlt = mg; + +} /* end of Cudd_SetMaxGrowthAlternate */ + + +/**Function******************************************************************** + + Synopsis [Reads the reordCycle parameter of the manager.] + + Description [Reads the reordCycle parameter of the manager. This + parameter determines how often the alternate threshold on maximum + growth is used in reordering.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate + Cudd_SetReorderingCycle] + +******************************************************************************/ +int +Cudd_ReadReorderingCycle( + DdManager * dd) +{ + return(dd->reordCycle); + +} /* end of Cudd_ReadReorderingCycle */ + + +/**Function******************************************************************** + + Synopsis [Sets the reordCycle parameter of the manager.] + + Description [Sets the reordCycle parameter of the manager. This + parameter determines how often the alternate threshold on maximum + growth is used in reordering.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate + Cudd_ReadReorderingCycle] + +******************************************************************************/ +void +Cudd_SetReorderingCycle( + DdManager * dd, + int cycle) +{ + dd->reordCycle = cycle; + +} /* end of Cudd_SetReorderingCycle */ + + +/**Function******************************************************************** + + Synopsis [Returns the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetTree Cudd_FreeTree Cudd_ReadZddTree] + +******************************************************************************/ +MtrNode * +Cudd_ReadTree( + DdManager * dd) +{ + return(dd->tree); + +} /* end of Cudd_ReadTree */ + + +/**Function******************************************************************** + + Synopsis [Sets the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_FreeTree Cudd_ReadTree Cudd_SetZddTree] + +******************************************************************************/ +void +Cudd_SetTree( + DdManager * dd, + MtrNode * tree) +{ + if (dd->tree != NULL) { + Mtr_FreeTree(dd->tree); + } + dd->tree = tree; + if (tree == NULL) return; + + fixVarTree(tree, dd->perm, dd->size); + return; + +} /* end of Cudd_SetTree */ + + +/**Function******************************************************************** + + Synopsis [Frees the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetTree Cudd_ReadTree Cudd_FreeZddTree] + +******************************************************************************/ +void +Cudd_FreeTree( + DdManager * dd) +{ + if (dd->tree != NULL) { + Mtr_FreeTree(dd->tree); + dd->tree = NULL; + } + return; + +} /* end of Cudd_FreeTree */ + + +/**Function******************************************************************** + + Synopsis [Returns the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetZddTree Cudd_FreeZddTree Cudd_ReadTree] + +******************************************************************************/ +MtrNode * +Cudd_ReadZddTree( + DdManager * dd) +{ + return(dd->treeZ); + +} /* end of Cudd_ReadZddTree */ + + +/**Function******************************************************************** + + Synopsis [Sets the ZDD variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_FreeZddTree Cudd_ReadZddTree Cudd_SetTree] + +******************************************************************************/ +void +Cudd_SetZddTree( + DdManager * dd, + MtrNode * tree) +{ + if (dd->treeZ != NULL) { + Mtr_FreeTree(dd->treeZ); + } + dd->treeZ = tree; + if (tree == NULL) return; + + fixVarTree(tree, dd->permZ, dd->sizeZ); + return; + +} /* end of Cudd_SetZddTree */ + + +/**Function******************************************************************** + + Synopsis [Frees the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetZddTree Cudd_ReadZddTree Cudd_FreeTree] + +******************************************************************************/ +void +Cudd_FreeZddTree( + DdManager * dd) +{ + if (dd->treeZ != NULL) { + Mtr_FreeTree(dd->treeZ); + dd->treeZ = NULL; + } + return; + +} /* end of Cudd_FreeZddTree */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the node.] + + Description [Returns the index of the node. The node pointer can be + either regular or complemented.] + + SideEffects [None] + + SeeAlso [Cudd_ReadIndex] + +******************************************************************************/ +unsigned int +Cudd_NodeReadIndex( + DdNode * node) +{ + return((unsigned int) Cudd_Regular(node)->index); + +} /* end of Cudd_NodeReadIndex */ + + +/**Function******************************************************************** + + Synopsis [Returns the current position of the i-th variable in the + order.] + + Description [Returns the current position of the i-th variable in + the order. If the index is CUDD_CONST_INDEX, returns + CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns + -1.] + + SideEffects [None] + + SeeAlso [Cudd_ReadInvPerm Cudd_ReadPermZdd] + +******************************************************************************/ +int +Cudd_ReadPerm( + DdManager * dd, + int i) +{ + if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); + if (i < 0 || i >= dd->size) return(-1); + return(dd->perm[i]); + +} /* end of Cudd_ReadPerm */ + + +/**Function******************************************************************** + + Synopsis [Returns the current position of the i-th ZDD variable in the + order.] + + Description [Returns the current position of the i-th ZDD variable + in the order. If the index is CUDD_CONST_INDEX, returns + CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns + -1.] + + SideEffects [None] + + SeeAlso [Cudd_ReadInvPermZdd Cudd_ReadPerm] + +******************************************************************************/ +int +Cudd_ReadPermZdd( + DdManager * dd, + int i) +{ + if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); + if (i < 0 || i >= dd->sizeZ) return(-1); + return(dd->permZ[i]); + +} /* end of Cudd_ReadPermZdd */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the variable currently in the i-th + position of the order.] + + Description [Returns the index of the variable currently in the i-th + position of the order. If the index is CUDD_CONST_INDEX, returns + CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.] + + SideEffects [None] + + SeeAlso [Cudd_ReadPerm Cudd_ReadInvPermZdd] + +******************************************************************************/ +int +Cudd_ReadInvPerm( + DdManager * dd, + int i) +{ + if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); + if (i < 0 || i >= dd->size) return(-1); + return(dd->invperm[i]); + +} /* end of Cudd_ReadInvPerm */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the ZDD variable currently in the i-th + position of the order.] + + Description [Returns the index of the ZDD variable currently in the + i-th position of the order. If the index is CUDD_CONST_INDEX, returns + CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.] + + SideEffects [None] + + SeeAlso [Cudd_ReadPerm Cudd_ReadInvPermZdd] + +******************************************************************************/ +int +Cudd_ReadInvPermZdd( + DdManager * dd, + int i) +{ + if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); + if (i < 0 || i >= dd->sizeZ) return(-1); + return(dd->invpermZ[i]); + +} /* end of Cudd_ReadInvPermZdd */ + + +/**Function******************************************************************** + + Synopsis [Returns the i-th element of the vars array.] + + Description [Returns the i-th element of the vars array if it falls + within the array bounds; NULL otherwise. If i is the index of an + existing variable, this function produces the same result as + Cudd_bddIthVar. However, if the i-th var does not exist yet, + Cudd_bddIthVar will create it, whereas Cudd_ReadVars will not.] + + SideEffects [None] + + SeeAlso [Cudd_bddIthVar] + +******************************************************************************/ +DdNode * +Cudd_ReadVars( + DdManager * dd, + int i) +{ + if (i < 0 || i > dd->size) return(NULL); + return(dd->vars[i]); + +} /* end of Cudd_ReadVars */ + + +/**Function******************************************************************** + + Synopsis [Reads the epsilon parameter of the manager.] + + Description [Reads the epsilon parameter of the manager. The epsilon + parameter control the comparison between floating point numbers.] + + SideEffects [None] + + SeeAlso [Cudd_SetEpsilon] + +******************************************************************************/ +CUDD_VALUE_TYPE +Cudd_ReadEpsilon( + DdManager * dd) +{ + return(dd->epsilon); + +} /* end of Cudd_ReadEpsilon */ + + +/**Function******************************************************************** + + Synopsis [Sets the epsilon parameter of the manager to ep.] + + Description [Sets the epsilon parameter of the manager to ep. The epsilon + parameter control the comparison between floating point numbers.] + + SideEffects [None] + + SeeAlso [Cudd_ReadEpsilon] + +******************************************************************************/ +void +Cudd_SetEpsilon( + DdManager * dd, + CUDD_VALUE_TYPE ep) +{ + dd->epsilon = ep; + +} /* end of Cudd_SetEpsilon */ + + +/**Function******************************************************************** + + Synopsis [Reads the groupcheck parameter of the manager.] + + Description [Reads the groupcheck parameter of the manager. The + groupcheck parameter determines the aggregation criterion in group + sifting.] + + SideEffects [None] + + SeeAlso [Cudd_SetGroupcheck] + +******************************************************************************/ +Cudd_AggregationType +Cudd_ReadGroupcheck( + DdManager * dd) +{ + return(dd->groupcheck); + +} /* end of Cudd_ReadGroupCheck */ + + +/**Function******************************************************************** + + Synopsis [Sets the parameter groupcheck of the manager to gc.] + + Description [Sets the parameter groupcheck of the manager to gc. The + groupcheck parameter determines the aggregation criterion in group + sifting.] + + SideEffects [None] + + SeeAlso [Cudd_ReadGroupCheck] + +******************************************************************************/ +void +Cudd_SetGroupcheck( + DdManager * dd, + Cudd_AggregationType gc) +{ + dd->groupcheck = gc; + +} /* end of Cudd_SetGroupcheck */ + + +/**Function******************************************************************** + + Synopsis [Tells whether garbage collection is enabled.] + + Description [Returns 1 if garbage collection is enabled; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_EnableGarbageCollection Cudd_DisableGarbageCollection] + +******************************************************************************/ +int +Cudd_GarbageCollectionEnabled( + DdManager * dd) +{ + return(dd->gcEnabled); + +} /* end of Cudd_GarbageCollectionEnabled */ + + +/**Function******************************************************************** + + Synopsis [Enables garbage collection.] + + Description [Enables garbage collection. Garbage collection is + initially enabled. Therefore it is necessary to call this function + only if garbage collection has been explicitly disabled.] + + SideEffects [None] + + SeeAlso [Cudd_DisableGarbageCollection Cudd_GarbageCollectionEnabled] + +******************************************************************************/ +void +Cudd_EnableGarbageCollection( + DdManager * dd) +{ + dd->gcEnabled = 1; + +} /* end of Cudd_EnableGarbageCollection */ + + +/**Function******************************************************************** + + Synopsis [Disables garbage collection.] + + Description [Disables garbage collection. Garbage collection is + initially enabled. This function may be called to disable it. + However, garbage collection will still occur when a new node must be + created and no memory is left, or when garbage collection is required + for correctness. (E.g., before reordering.)] + + SideEffects [None] + + SeeAlso [Cudd_EnableGarbageCollection Cudd_GarbageCollectionEnabled] + +******************************************************************************/ +void +Cudd_DisableGarbageCollection( + DdManager * dd) +{ + dd->gcEnabled = 0; + +} /* end of Cudd_DisableGarbageCollection */ + + +/**Function******************************************************************** + + Synopsis [Tells whether dead nodes are counted towards triggering + reordering.] + + Description [Tells whether dead nodes are counted towards triggering + reordering. Returns 1 if dead nodes are counted; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_TurnOnCountDead Cudd_TurnOffCountDead] + +******************************************************************************/ +int +Cudd_DeadAreCounted( + DdManager * dd) +{ + return(dd->countDead == 0 ? 1 : 0); + +} /* end of Cudd_DeadAreCounted */ + + +/**Function******************************************************************** + + Synopsis [Causes the dead nodes to be counted towards triggering + reordering.] + + Description [Causes the dead nodes to be counted towards triggering + reordering. This causes more frequent reorderings. By default dead + nodes are not counted.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_TurnOffCountDead Cudd_DeadAreCounted] + +******************************************************************************/ +void +Cudd_TurnOnCountDead( + DdManager * dd) +{ + dd->countDead = 0; + +} /* end of Cudd_TurnOnCountDead */ + + +/**Function******************************************************************** + + Synopsis [Causes the dead nodes not to be counted towards triggering + reordering.] + + Description [Causes the dead nodes not to be counted towards + triggering reordering. This causes less frequent reorderings. By + default dead nodes are not counted. Therefore there is no need to + call this function unless Cudd_TurnOnCountDead has been previously + called.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_TurnOnCountDead Cudd_DeadAreCounted] + +******************************************************************************/ +void +Cudd_TurnOffCountDead( + DdManager * dd) +{ + dd->countDead = ~0; + +} /* end of Cudd_TurnOffCountDead */ + + +/**Function******************************************************************** + + Synopsis [Returns the current value of the recombination parameter used + in group sifting.] + + Description [Returns the current value of the recombination + parameter used in group sifting. A larger (positive) value makes the + aggregation of variables due to the second difference criterion more + likely. A smaller (negative) value makes aggregation less likely.] + + SideEffects [None] + + SeeAlso [Cudd_SetRecomb] + +******************************************************************************/ +int +Cudd_ReadRecomb( + DdManager * dd) +{ + return(dd->recomb); + +} /* end of Cudd_ReadRecomb */ + + +/**Function******************************************************************** + + Synopsis [Sets the value of the recombination parameter used in group + sifting.] + + Description [Sets the value of the recombination parameter used in + group sifting. A larger (positive) value makes the aggregation of + variables due to the second difference criterion more likely. A + smaller (negative) value makes aggregation less likely. The default + value is 0.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_ReadRecomb] + +******************************************************************************/ +void +Cudd_SetRecomb( + DdManager * dd, + int recomb) +{ + dd->recomb = recomb; + +} /* end of Cudd_SetRecomb */ + + +/**Function******************************************************************** + + Synopsis [Returns the current value of the symmviolation parameter used + in group sifting.] + + Description [Returns the current value of the symmviolation + parameter. This parameter is used in group sifting to decide how + many violations to the symmetry conditions f10 = f01 or + f11 = f00 are tolerable when checking for aggregation + due to extended symmetry. The value should be between 0 and 100. A + small value causes fewer variables to be aggregated. The default + value is 0.] + + SideEffects [None] + + SeeAlso [Cudd_SetSymmviolation] + +******************************************************************************/ +int +Cudd_ReadSymmviolation( + DdManager * dd) +{ + return(dd->symmviolation); + +} /* end of Cudd_ReadSymmviolation */ + + +/**Function******************************************************************** + + Synopsis [Sets the value of the symmviolation parameter used + in group sifting.] + + Description [Sets the value of the symmviolation + parameter. This parameter is used in group sifting to decide how + many violations to the symmetry conditions f10 = f01 or + f11 = f00 are tolerable when checking for aggregation + due to extended symmetry. The value should be between 0 and 100. A + small value causes fewer variables to be aggregated. The default + value is 0.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_ReadSymmviolation] + +******************************************************************************/ +void +Cudd_SetSymmviolation( + DdManager * dd, + int symmviolation) +{ + dd->symmviolation = symmviolation; + +} /* end of Cudd_SetSymmviolation */ + + +/**Function******************************************************************** + + Synopsis [Returns the current value of the arcviolation parameter used + in group sifting.] + + Description [Returns the current value of the arcviolation + parameter. This parameter is used in group sifting to decide how + many arcs into y not coming from x are + tolerable when checking for aggregation due to extended + symmetry. The value should be between 0 and 100. A small value + causes fewer variables to be aggregated. The default value is 0.] + + SideEffects [None] + + SeeAlso [Cudd_SetArcviolation] + +******************************************************************************/ +int +Cudd_ReadArcviolation( + DdManager * dd) +{ + return(dd->arcviolation); + +} /* end of Cudd_ReadArcviolation */ + + +/**Function******************************************************************** + + Synopsis [Sets the value of the arcviolation parameter used + in group sifting.] + + Description [Sets the value of the arcviolation + parameter. This parameter is used in group sifting to decide how + many arcs into y not coming from x are + tolerable when checking for aggregation due to extended + symmetry. The value should be between 0 and 100. A small value + causes fewer variables to be aggregated. The default value is 0.] + + SideEffects [None] + + SeeAlso [Cudd_ReadArcviolation] + +******************************************************************************/ +void +Cudd_SetArcviolation( + DdManager * dd, + int arcviolation) +{ + dd->arcviolation = arcviolation; + +} /* end of Cudd_SetArcviolation */ + + +/**Function******************************************************************** + + Synopsis [Reads the current size of the population used by the + genetic algorithm for reordering.] + + Description [Reads the current size of the population used by the + genetic algorithm for variable reordering. A larger population size will + cause the genetic algorithm to take more time, but will generally + produce better results. The default value is 0, in which case the + package uses three times the number of variables as population size, + with a maximum of 120.] + + SideEffects [None] + + SeeAlso [Cudd_SetPopulationSize] + +******************************************************************************/ +int +Cudd_ReadPopulationSize( + DdManager * dd) +{ + return(dd->populationSize); + +} /* end of Cudd_ReadPopulationSize */ + + +/**Function******************************************************************** + + Synopsis [Sets the size of the population used by the + genetic algorithm for reordering.] + + Description [Sets the size of the population used by the + genetic algorithm for variable reordering. A larger population size will + cause the genetic algorithm to take more time, but will generally + produce better results. The default value is 0, in which case the + package uses three times the number of variables as population size, + with a maximum of 120.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_ReadPopulationSize] + +******************************************************************************/ +void +Cudd_SetPopulationSize( + DdManager * dd, + int populationSize) +{ + dd->populationSize = populationSize; + +} /* end of Cudd_SetPopulationSize */ + + +/**Function******************************************************************** + + Synopsis [Reads the current number of crossovers used by the + genetic algorithm for reordering.] + + Description [Reads the current number of crossovers used by the + genetic algorithm for variable reordering. A larger number of crossovers will + cause the genetic algorithm to take more time, but will generally + produce better results. The default value is 0, in which case the + package uses three times the number of variables as number of crossovers, + with a maximum of 60.] + + SideEffects [None] + + SeeAlso [Cudd_SetNumberXovers] + +******************************************************************************/ +int +Cudd_ReadNumberXovers( + DdManager * dd) +{ + return(dd->numberXovers); + +} /* end of Cudd_ReadNumberXovers */ + + +/**Function******************************************************************** + + Synopsis [Sets the number of crossovers used by the + genetic algorithm for reordering.] + + Description [Sets the number of crossovers used by the genetic + algorithm for variable reordering. A larger number of crossovers + will cause the genetic algorithm to take more time, but will + generally produce better results. The default value is 0, in which + case the package uses three times the number of variables as number + of crossovers, with a maximum of 60.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNumberXovers] + +******************************************************************************/ +void +Cudd_SetNumberXovers( + DdManager * dd, + int numberXovers) +{ + dd->numberXovers = numberXovers; + +} /* end of Cudd_SetNumberXovers */ + + +/**Function******************************************************************** + + Synopsis [Returns the order randomization factor.] + + Description [Returns the order randomization factor. If non-zero this + factor is used to determine a perturbation of the next reordering threshold. + Larger factors cause larger perturbations.] + + SideEffects [None] + + SeeAlso [Cudd_SetOrderRandomization] + +******************************************************************************/ +unsigned int +Cudd_ReadOrderRandomization( + DdManager * dd) +{ + return(dd->randomizeOrder); + +} /* end of Cudd_ReadOrderRandomization */ + + +/**Function******************************************************************** + + Synopsis [Sets the order randomization factor.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadOrderRandomization] + +******************************************************************************/ +void +Cudd_SetOrderRandomization( + DdManager * dd, + unsigned int factor) +{ + dd->randomizeOrder = factor; + +} /* end of Cudd_SetOrderRandomization */ + + +/**Function******************************************************************** + + Synopsis [Returns the memory in use by the manager measured in bytes.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +unsigned long +Cudd_ReadMemoryInUse( + DdManager * dd) +{ + return(dd->memused); + +} /* end of Cudd_ReadMemoryInUse */ + + +/**Function******************************************************************** + + Synopsis [Prints out statistics and settings for a CUDD manager.] + + Description [Prints out statistics and settings for a CUDD manager. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_PrintInfo( + DdManager * dd, + FILE * fp) +{ + int retval; + Cudd_ReorderingType autoMethod, autoMethodZ; + + /* Modifiable parameters. */ + retval = fprintf(fp,"**** CUDD modifiable parameters ****\n"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Hard limit for cache size: %u\n", + Cudd_ReadMaxCacheHard(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache hit threshold for resizing: %u%%\n", + Cudd_ReadMinHit(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Garbage collection enabled: %s\n", + Cudd_GarbageCollectionEnabled(dd) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Limit for fast unique table growth: %u\n", + Cudd_ReadLooseUpTo(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp, + "Maximum number of variables sifted per reordering: %d\n", + Cudd_ReadSiftMaxVar(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp, + "Maximum number of variable swaps per reordering: %d\n", + Cudd_ReadSiftMaxSwap(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Maximum growth while sifting a variable: %g\n", + Cudd_ReadMaxGrowth(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Dynamic reordering of BDDs enabled: %s\n", + Cudd_ReorderingStatus(dd,&autoMethod) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Default BDD reordering method: %d\n", + (int) autoMethod); + if (retval == EOF) return(0); + retval = fprintf(fp,"Dynamic reordering of ZDDs enabled: %s\n", + Cudd_ReorderingStatusZdd(dd,&autoMethodZ) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Default ZDD reordering method: %d\n", + (int) autoMethodZ); + if (retval == EOF) return(0); + retval = fprintf(fp,"Realignment of ZDDs to BDDs enabled: %s\n", + Cudd_zddRealignmentEnabled(dd) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Realignment of BDDs to ZDDs enabled: %s\n", + Cudd_bddRealignmentEnabled(dd) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Dead nodes counted in triggering reordering: %s\n", + Cudd_DeadAreCounted(dd) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Group checking criterion: %d\n", + (int) Cudd_ReadGroupcheck(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Recombination threshold: %d\n", Cudd_ReadRecomb(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Symmetry violation threshold: %d\n", + Cudd_ReadSymmviolation(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Arc violation threshold: %d\n", + Cudd_ReadArcviolation(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"GA population size: %d\n", + Cudd_ReadPopulationSize(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of crossovers for GA: %d\n", + Cudd_ReadNumberXovers(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Next reordering threshold: %u\n", + Cudd_ReadNextReordering(dd)); + if (retval == EOF) return(0); + + /* Non-modifiable parameters. */ + retval = fprintf(fp,"**** CUDD non-modifiable parameters ****\n"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Memory in use: %lu\n", Cudd_ReadMemoryInUse(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Peak number of nodes: %ld\n", + Cudd_ReadPeakNodeCount(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Peak number of live nodes: %d\n", + Cudd_ReadPeakLiveNodeCount(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of BDD variables: %d\n", dd->size); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of ZDD variables: %d\n", dd->sizeZ); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache entries: %u\n", dd->cacheSlots); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache look-ups: %.0f\n", + Cudd_ReadCacheLookUps(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache hits: %.0f\n", + Cudd_ReadCacheHits(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache insertions: %.0f\n", + dd->cacheinserts); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache collisions: %.0f\n", + dd->cachecollisions); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache deletions: %.0f\n", + dd->cachedeletions); + if (retval == EOF) return(0); + retval = cuddCacheProfile(dd,fp); + if (retval == 0) return(0); + retval = fprintf(fp,"Soft limit for cache size: %u\n", + Cudd_ReadMaxCache(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of buckets in unique table: %u\n", dd->slots); + if (retval == EOF) return(0); + retval = fprintf(fp,"Used buckets in unique table: %.2f%% (expected %.2f%%)\n", + 100.0 * Cudd_ReadUsedSlots(dd), + 100.0 * Cudd_ExpectedUsedSlots(dd)); + if (retval == EOF) return(0); +#ifdef DD_UNIQUE_PROFILE + retval = fprintf(fp,"Unique lookups: %.0f\n", dd->uniqueLookUps); + if (retval == EOF) return(0); + retval = fprintf(fp,"Unique links: %.0f (%g per lookup)\n", + dd->uniqueLinks, dd->uniqueLinks / dd->uniqueLookUps); + if (retval == EOF) return(0); +#endif + retval = fprintf(fp,"Number of BDD and ADD nodes: %u\n", dd->keys); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of ZDD nodes: %u\n", dd->keysZ); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of dead BDD and ADD nodes: %u\n", dd->dead); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of dead ZDD nodes: %u\n", dd->deadZ); + if (retval == EOF) return(0); + retval = fprintf(fp,"Total number of nodes allocated: %.0f\n", + dd->allocated); + if (retval == EOF) return(0); + retval = fprintf(fp,"Total number of nodes reclaimed: %.0f\n", + dd->reclaimed); + if (retval == EOF) return(0); +#ifdef DD_STATS + retval = fprintf(fp,"Nodes freed: %.0f\n", dd->nodesFreed); + if (retval == EOF) return(0); + retval = fprintf(fp,"Nodes dropped: %.0f\n", dd->nodesDropped); + if (retval == EOF) return(0); +#endif +#ifdef DD_COUNT + retval = fprintf(fp,"Number of recursive calls: %.0f\n", + Cudd_ReadRecursiveCalls(dd)); + if (retval == EOF) return(0); +#endif + retval = fprintf(fp,"Garbage collections so far: %d\n", + Cudd_ReadGarbageCollections(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Time for garbage collection: %.2f sec\n", + ((double)Cudd_ReadGarbageCollectionTime(dd)/1000.0)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Reorderings so far: %d\n", dd->reorderings); + if (retval == EOF) return(0); + retval = fprintf(fp,"Time for reordering: %.2f sec\n", + ((double)Cudd_ReadReorderingTime(dd)/1000.0)); + if (retval == EOF) return(0); +#ifdef DD_COUNT + retval = fprintf(fp,"Node swaps in reordering: %.0f\n", + Cudd_ReadSwapSteps(dd)); + if (retval == EOF) return(0); +#endif + + return(1); + +} /* end of Cudd_PrintInfo */ + + +/**Function******************************************************************** + + Synopsis [Reports the peak number of nodes.] + + Description [Reports the peak number of nodes. This number includes + node on the free list. At the peak, the number of nodes on the free + list is guaranteed to be less than DD_MEM_CHUNK.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNodeCount Cudd_PrintInfo] + +******************************************************************************/ +long +Cudd_ReadPeakNodeCount( + DdManager * dd) +{ + long count = 0; + DdNodePtr *scan = dd->memoryList; + + while (scan != NULL) { + count += DD_MEM_CHUNK; + scan = (DdNodePtr *) *scan; + } + return(count); + +} /* end of Cudd_ReadPeakNodeCount */ + + +/**Function******************************************************************** + + Synopsis [Reports the peak number of live nodes.] + + Description [Reports the peak number of live nodes.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNodeCount Cudd_PrintInfo Cudd_ReadPeakNodeCount] + +******************************************************************************/ +int +Cudd_ReadPeakLiveNodeCount( + DdManager * dd) +{ + unsigned int live = dd->keys - dd->dead; + + if (live > dd->peakLiveNodes) { + dd->peakLiveNodes = live; + } + return((int)dd->peakLiveNodes); + +} /* end of Cudd_ReadPeakLiveNodeCount */ + + +/**Function******************************************************************** + + Synopsis [Reports the number of nodes in BDDs and ADDs.] + + Description [Reports the number of live nodes in BDDs and ADDs. This + number does not include the isolated projection functions and the + unused constants. These nodes that are not counted are not part of + the DDs manipulated by the application.] + + SideEffects [None] + + SeeAlso [Cudd_ReadPeakNodeCount Cudd_zddReadNodeCount] + +******************************************************************************/ +long +Cudd_ReadNodeCount( + DdManager * dd) +{ + long count; + int i; + +#ifndef DD_NO_DEATH_ROW + cuddClearDeathRow(dd); +#endif + + count = (long) (dd->keys - dd->dead); + + /* Count isolated projection functions. Their number is subtracted + ** from the node count because they are not part of the BDDs. + */ + for (i=0; i < dd->size; i++) { + if (dd->vars[i]->ref == 1) count--; + } + /* Subtract from the count the unused constants. */ + if (DD_ZERO(dd)->ref == 1) count--; + if (DD_PLUS_INFINITY(dd)->ref == 1) count--; + if (DD_MINUS_INFINITY(dd)->ref == 1) count--; + + return(count); + +} /* end of Cudd_ReadNodeCount */ + + + +/**Function******************************************************************** + + Synopsis [Reports the number of nodes in ZDDs.] + + Description [Reports the number of nodes in ZDDs. This + number always includes the two constants 1 and 0.] + + SideEffects [None] + + SeeAlso [Cudd_ReadPeakNodeCount Cudd_ReadNodeCount] + +******************************************************************************/ +long +Cudd_zddReadNodeCount( + DdManager * dd) +{ + return((long)(dd->keysZ - dd->deadZ + 2)); + +} /* end of Cudd_zddReadNodeCount */ + + +/**Function******************************************************************** + + Synopsis [Adds a function to a hook.] + + Description [Adds a function to a hook. A hook is a list of + application-provided functions called on certain occasions by the + package. Returns 1 if the function is successfully added; 2 if the + function was already in the list; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_RemoveHook] + +******************************************************************************/ +int +Cudd_AddHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where) +{ + DdHook **hook, *nextHook, *newHook; + + switch (where) { + case CUDD_PRE_GC_HOOK: + hook = &(dd->preGCHook); + break; + case CUDD_POST_GC_HOOK: + hook = &(dd->postGCHook); + break; + case CUDD_PRE_REORDERING_HOOK: + hook = &(dd->preReorderingHook); + break; + case CUDD_POST_REORDERING_HOOK: + hook = &(dd->postReorderingHook); + break; + default: + return(0); + } + /* Scan the list and find whether the function is already there. + ** If so, just return. */ + nextHook = *hook; + while (nextHook != NULL) { + if (nextHook->f == f) { + return(2); + } + hook = &(nextHook->next); + nextHook = nextHook->next; + } + /* The function was not in the list. Create a new item and append it + ** to the end of the list. */ + newHook = ALLOC(DdHook,1); + if (newHook == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newHook->next = NULL; + newHook->f = f; + *hook = newHook; + return(1); + +} /* end of Cudd_AddHook */ + + +/**Function******************************************************************** + + Synopsis [Removes a function from a hook.] + + Description [Removes a function from a hook. A hook is a list of + application-provided functions called on certain occasions by the + package. Returns 1 if successful; 0 the function was not in the list.] + + SideEffects [None] + + SeeAlso [Cudd_AddHook] + +******************************************************************************/ +int +Cudd_RemoveHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where) +{ + DdHook **hook, *nextHook; + + switch (where) { + case CUDD_PRE_GC_HOOK: + hook = &(dd->preGCHook); + break; + case CUDD_POST_GC_HOOK: + hook = &(dd->postGCHook); + break; + case CUDD_PRE_REORDERING_HOOK: + hook = &(dd->preReorderingHook); + break; + case CUDD_POST_REORDERING_HOOK: + hook = &(dd->postReorderingHook); + break; + default: + return(0); + } + nextHook = *hook; + while (nextHook != NULL) { + if (nextHook->f == f) { + *hook = nextHook->next; + FREE(nextHook); + return(1); + } + hook = &(nextHook->next); + nextHook = nextHook->next; + } + + return(0); + +} /* end of Cudd_RemoveHook */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a function is in a hook.] + + Description [Checks whether a function is in a hook. A hook is a list of + application-provided functions called on certain occasions by the + package. Returns 1 if the function is found; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_AddHook Cudd_RemoveHook] + +******************************************************************************/ +int +Cudd_IsInHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where) +{ + DdHook *hook; + + switch (where) { + case CUDD_PRE_GC_HOOK: + hook = dd->preGCHook; + break; + case CUDD_POST_GC_HOOK: + hook = dd->postGCHook; + break; + case CUDD_PRE_REORDERING_HOOK: + hook = dd->preReorderingHook; + break; + case CUDD_POST_REORDERING_HOOK: + hook = dd->postReorderingHook; + break; + default: + return(0); + } + /* Scan the list and find whether the function is already there. */ + while (hook != NULL) { + if (hook->f == f) { + return(1); + } + hook = hook->next; + } + return(0); + +} /* end of Cudd_IsInHook */ + + +/**Function******************************************************************** + + Synopsis [Sample hook function to call before reordering.] + + Description [Sample hook function to call before reordering. + Prints on the manager's stdout reordering method and initial size. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_StdPostReordHook] + +******************************************************************************/ +int +Cudd_StdPreReordHook( + DdManager *dd, + const char *str, + void *data) +{ + Cudd_ReorderingType method = (Cudd_ReorderingType) (ptruint) data; + int retval; + + retval = fprintf(dd->out,"%s reordering with ", str); + if (retval == EOF) return(0); + switch (method) { + case CUDD_REORDER_SIFT_CONVERGE: + case CUDD_REORDER_SYMM_SIFT_CONV: + case CUDD_REORDER_GROUP_SIFT_CONV: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + case CUDD_REORDER_LINEAR_CONVERGE: + retval = fprintf(dd->out,"converging "); + if (retval == EOF) return(0); + break; + default: + break; + } + switch (method) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + retval = fprintf(dd->out,"random"); + break; + case CUDD_REORDER_SIFT: + case CUDD_REORDER_SIFT_CONVERGE: + retval = fprintf(dd->out,"sifting"); + break; + case CUDD_REORDER_SYMM_SIFT: + case CUDD_REORDER_SYMM_SIFT_CONV: + retval = fprintf(dd->out,"symmetric sifting"); + break; + case CUDD_REORDER_LAZY_SIFT: + retval = fprintf(dd->out,"lazy sifting"); + break; + case CUDD_REORDER_GROUP_SIFT: + case CUDD_REORDER_GROUP_SIFT_CONV: + retval = fprintf(dd->out,"group sifting"); + break; + case CUDD_REORDER_WINDOW2: + case CUDD_REORDER_WINDOW3: + case CUDD_REORDER_WINDOW4: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + retval = fprintf(dd->out,"window"); + break; + case CUDD_REORDER_ANNEALING: + retval = fprintf(dd->out,"annealing"); + break; + case CUDD_REORDER_GENETIC: + retval = fprintf(dd->out,"genetic"); + break; + case CUDD_REORDER_LINEAR: + case CUDD_REORDER_LINEAR_CONVERGE: + retval = fprintf(dd->out,"linear sifting"); + break; + case CUDD_REORDER_EXACT: + retval = fprintf(dd->out,"exact"); + break; + default: + return(0); + } + if (retval == EOF) return(0); + + retval = fprintf(dd->out,": from %ld to ... ", strcmp(str, "BDD") == 0 ? + Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd)); + if (retval == EOF) return(0); + fflush(dd->out); + return(1); + +} /* end of Cudd_StdPreReordHook */ + + +/**Function******************************************************************** + + Synopsis [Sample hook function to call after reordering.] + + Description [Sample hook function to call after reordering. + Prints on the manager's stdout final size and reordering time. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_StdPreReordHook] + +******************************************************************************/ +int +Cudd_StdPostReordHook( + DdManager *dd, + const char *str, + void *data) +{ + unsigned long initialTime = (long) data; + int retval; + unsigned long finalTime = util_cpu_time(); + double totalTimeSec = (double)(finalTime - initialTime) / 1000.0; + + retval = fprintf(dd->out,"%ld nodes in %g sec\n", strcmp(str, "BDD") == 0 ? + Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd), + totalTimeSec); + if (retval == EOF) return(0); + retval = fflush(dd->out); + if (retval == EOF) return(0); + return(1); + +} /* end of Cudd_StdPostReordHook */ + + +/**Function******************************************************************** + + Synopsis [Enables reporting of reordering stats.] + + Description [Enables reporting of reordering stats. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Installs functions in the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_DisableReorderingReporting Cudd_ReorderingReporting] + +******************************************************************************/ +int +Cudd_EnableReorderingReporting( + DdManager *dd) +{ + if (!Cudd_AddHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_EnableReorderingReporting */ + + +/**Function******************************************************************** + + Synopsis [Disables reporting of reordering stats.] + + Description [Disables reporting of reordering stats. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Removes functions from the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_EnableReorderingReporting Cudd_ReorderingReporting] + +******************************************************************************/ +int +Cudd_DisableReorderingReporting( + DdManager *dd) +{ + if (!Cudd_RemoveHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_DisableReorderingReporting */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if reporting of reordering stats is enabled.] + + Description [Returns 1 if reporting of reordering stats is enabled; + 0 otherwise.] + + SideEffects [none] + + SeeAlso [Cudd_EnableReorderingReporting Cudd_DisableReorderingReporting] + +******************************************************************************/ +int +Cudd_ReorderingReporting( + DdManager *dd) +{ + return(Cudd_IsInHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)); + +} /* end of Cudd_ReorderingReporting */ + + +/**Function******************************************************************** + + Synopsis [Hook function to print the current variable order.] + + Description [Hook function to print the current variable order. It may be + called before or after reordering. Prints on the manager's stdout a + parenthesized list that describes the variable groups. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_StdPreReordHook] + +******************************************************************************/ +int +Cudd_PrintGroupedOrder( + DdManager * dd, + const char *str, + void *data) +{ + int isBdd = strcmp(str, "ZDD"); + MtrNode *tree = isBdd ? dd->tree : dd->treeZ; + int *invperm = isBdd ? dd->invperm : dd->invpermZ; + int size = isBdd ? dd->size : dd->sizeZ; + if (tree == NULL) { + int i, retval; + for (i=0; i < size; i++) { + retval = fprintf(dd->out, "%c%d", i==0 ? '(' : ',', invperm[i]); + if (retval == EOF) return(0); + } + retval = fprintf(dd->out,")\n"); + return (retval != EOF); + } else { + return Mtr_PrintGroupedOrder(tree,invperm,dd->out); + } + +} /* end of Cudd_PrintGroupedOrder */ + + +/**Function******************************************************************** + + Synopsis [Enables monitoring of ordering.] + + Description [Enables monitoring of ordering. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Installs functions in the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_EnableReorderingReporting] + +******************************************************************************/ +int +Cudd_EnableOrderingMonitoring( + DdManager *dd) +{ + if (!Cudd_AddHook(dd, Cudd_PrintGroupedOrder, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_PrintGroupedOrder, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_EnableOrderingMonitoring */ + + +/**Function******************************************************************** + + Synopsis [Disables monitoring of ordering.] + + Description [Disables monitoring of ordering. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Removes functions from the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_EnableOrderingMonitoring] + +******************************************************************************/ +int +Cudd_DisableOrderingMonitoring( + DdManager *dd) +{ + if (!Cudd_RemoveHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_PrintGroupedOrder, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_PrintGroupedOrder, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_DisableOrderingMonitoring */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if monitoring of ordering is enabled.] + + Description [Returns 1 if monitoring of ordering is enabled; + 0 otherwise.] + + SideEffects [none] + + SeeAlso [Cudd_EnableOrderingMonitoring Cudd_DisableOrderingMonitoring] + +******************************************************************************/ +int +Cudd_OrderingMonitoring( + DdManager *dd) +{ + return(Cudd_IsInHook(dd, Cudd_PrintGroupedOrder, CUDD_PRE_REORDERING_HOOK)); + +} /* end of Cudd_OrderingMonitoring */ + + +/**Function******************************************************************** + + Synopsis [Returns the code of the last error.] + + Description [Returns the code of the last error. The error codes are + defined in cudd.h.] + + SideEffects [None] + + SeeAlso [Cudd_ClearErrorCode] + +******************************************************************************/ +Cudd_ErrorType +Cudd_ReadErrorCode( + DdManager *dd) +{ + return(dd->errorCode); + +} /* end of Cudd_ReadErrorCode */ + + +/**Function******************************************************************** + + Synopsis [Clear the error code of a manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadErrorCode] + +******************************************************************************/ +void +Cudd_ClearErrorCode( + DdManager *dd) +{ + dd->errorCode = CUDD_NO_ERROR; + +} /* end of Cudd_ClearErrorCode */ + + +/**Function******************************************************************** + + Synopsis [Reads the stdout of a manager.] + + Description [Reads the stdout of a manager. This is the file pointer to + which messages normally going to stdout are written. It is initialized + to stdout. Cudd_SetStdout allows the application to redirect it.] + + SideEffects [None] + + SeeAlso [Cudd_SetStdout Cudd_ReadStderr] + +******************************************************************************/ +FILE * +Cudd_ReadStdout( + DdManager *dd) +{ + return(dd->out); + +} /* end of Cudd_ReadStdout */ + + +/**Function******************************************************************** + + Synopsis [Sets the stdout of a manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadStdout Cudd_SetStderr] + +******************************************************************************/ +void +Cudd_SetStdout( + DdManager *dd, + FILE *fp) +{ + dd->out = fp; + +} /* end of Cudd_SetStdout */ + + +/**Function******************************************************************** + + Synopsis [Reads the stderr of a manager.] + + Description [Reads the stderr of a manager. This is the file pointer to + which messages normally going to stderr are written. It is initialized + to stderr. Cudd_SetStderr allows the application to redirect it.] + + SideEffects [None] + + SeeAlso [Cudd_SetStderr Cudd_ReadStdout] + +******************************************************************************/ +FILE * +Cudd_ReadStderr( + DdManager *dd) +{ + return(dd->err); + +} /* end of Cudd_ReadStderr */ + + +/**Function******************************************************************** + + Synopsis [Sets the stderr of a manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadStderr Cudd_SetStdout] + +******************************************************************************/ +void +Cudd_SetStderr( + DdManager *dd, + FILE *fp) +{ + dd->err = fp; + +} /* end of Cudd_SetStderr */ + + +/**Function******************************************************************** + + Synopsis [Returns the threshold for the next dynamic reordering.] + + Description [Returns the threshold for the next dynamic reordering. + The threshold is in terms of number of nodes and is in effect only + if reordering is enabled. The count does not include the dead nodes, + unless the countDead parameter of the manager has been changed from + its default setting.] + + SideEffects [None] + + SeeAlso [Cudd_SetNextReordering] + +******************************************************************************/ +unsigned int +Cudd_ReadNextReordering( + DdManager *dd) +{ + return(dd->nextDyn); + +} /* end of Cudd_ReadNextReordering */ + + +/**Function******************************************************************** + + Synopsis [Sets the threshold for the next dynamic reordering.] + + Description [Sets the threshold for the next dynamic reordering. + The threshold is in terms of number of nodes and is in effect only + if reordering is enabled. The count does not include the dead nodes, + unless the countDead parameter of the manager has been changed from + its default setting.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNextReordering] + +******************************************************************************/ +void +Cudd_SetNextReordering( + DdManager *dd, + unsigned int next) +{ + dd->nextDyn = next; + +} /* end of Cudd_SetNextReordering */ + + +/**Function******************************************************************** + + Synopsis [Reads the number of elementary reordering steps.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +double +Cudd_ReadSwapSteps( + DdManager *dd) +{ +#ifdef DD_COUNT + return(dd->swapSteps); +#else + return(-1); +#endif + +} /* end of Cudd_ReadSwapSteps */ + + +/**Function******************************************************************** + + Synopsis [Reads the maximum allowed number of live nodes.] + + Description [Reads the maximum allowed number of live nodes. When this + number is exceeded, the package returns NULL.] + + SideEffects [none] + + SeeAlso [Cudd_SetMaxLive] + +******************************************************************************/ +unsigned int +Cudd_ReadMaxLive( + DdManager *dd) +{ + return(dd->maxLive); + +} /* end of Cudd_ReadMaxLive */ + + +/**Function******************************************************************** + + Synopsis [Sets the maximum allowed number of live nodes.] + + Description [Sets the maximum allowed number of live nodes. When this + number is exceeded, the package returns NULL.] + + SideEffects [none] + + SeeAlso [Cudd_ReadMaxLive] + +******************************************************************************/ +void +Cudd_SetMaxLive( + DdManager *dd, + unsigned int maxLive) +{ + dd->maxLive = maxLive; + +} /* end of Cudd_SetMaxLive */ + + +/**Function******************************************************************** + + Synopsis [Reads the maximum allowed memory.] + + Description [Reads the maximum allowed memory. When this + number is exceeded, the package returns NULL.] + + SideEffects [none] + + SeeAlso [Cudd_SetMaxMemory] + +******************************************************************************/ +unsigned long +Cudd_ReadMaxMemory( + DdManager *dd) +{ + return(dd->maxmemhard); + +} /* end of Cudd_ReadMaxMemory */ + + +/**Function******************************************************************** + + Synopsis [Sets the maximum allowed memory.] + + Description [Sets the maximum allowed memory. When this + number is exceeded, the package returns NULL.] + + SideEffects [none] + + SeeAlso [Cudd_ReadMaxMemory] + +******************************************************************************/ +void +Cudd_SetMaxMemory( + DdManager *dd, + unsigned long maxMemory) +{ + dd->maxmemhard = maxMemory; + +} /* end of Cudd_SetMaxMemory */ + + +/**Function******************************************************************** + + Synopsis [Prevents sifting of a variable.] + + Description [This function sets a flag to prevent sifting of a + variable. Returns 1 if successful; 0 otherwise (i.e., invalid + variable index).] + + SideEffects [Changes the "bindVar" flag in DdSubtable.] + + SeeAlso [Cudd_bddUnbindVar] + +******************************************************************************/ +int +Cudd_bddBindVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].bindVar = 1; + return(1); + +} /* end of Cudd_bddBindVar */ + + +/**Function******************************************************************** + + Synopsis [Allows the sifting of a variable.] + + Description [This function resets the flag that prevents the sifting + of a variable. In successive variable reorderings, the variable will + NOT be skipped, that is, sifted. Initially all variables can be + sifted. It is necessary to call this function only to re-enable + sifting after a call to Cudd_bddBindVar. Returns 1 if successful; 0 + otherwise (i.e., invalid variable index).] + + SideEffects [Changes the "bindVar" flag in DdSubtable.] + + SeeAlso [Cudd_bddBindVar] + +******************************************************************************/ +int +Cudd_bddUnbindVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].bindVar = 0; + return(1); + +} /* end of Cudd_bddUnbindVar */ + + +/**Function******************************************************************** + + Synopsis [Tells whether a variable can be sifted.] + + Description [This function returns 1 if a variable is enabled for + sifting. Initially all variables can be sifted. This function returns + 0 only if there has been a previous call to Cudd_bddBindVar for that + variable not followed by a call to Cudd_bddUnbindVar. The function returns + 0 also in the case in which the index of the variable is out of bounds.] + + SideEffects [none] + + SeeAlso [Cudd_bddBindVar Cudd_bddUnbindVar] + +******************************************************************************/ +int +Cudd_bddVarIsBound( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return(0); + return(dd->subtables[dd->perm[index]].bindVar); + +} /* end of Cudd_bddVarIsBound */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable type to primary input.] + + Description [Sets a variable type to primary input. The variable type is + used by lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetPsVar Cudd_bddSetNsVar Cudd_bddIsPiVar] + +******************************************************************************/ +int +Cudd_bddSetPiVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return (0); + dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRIMARY_INPUT; + return(1); + +} /* end of Cudd_bddSetPiVar */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable type to present state.] + + Description [Sets a variable type to present state. The variable type is + used by lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetPiVar Cudd_bddSetNsVar Cudd_bddIsPsVar] + +******************************************************************************/ +int +Cudd_bddSetPsVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return (0); + dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRESENT_STATE; + return(1); + +} /* end of Cudd_bddSetPsVar */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable type to next state.] + + Description [Sets a variable type to next state. The variable type is + used by lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetPiVar Cudd_bddSetPsVar Cudd_bddIsNsVar] + +******************************************************************************/ +int +Cudd_bddSetNsVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return (0); + dd->subtables[dd->perm[index]].varType = CUDD_VAR_NEXT_STATE; + return(1); + +} /* end of Cudd_bddSetNsVar */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is primary input.] + + Description [Checks whether a variable is primary input. Returns 1 if + the variable's type is primary input; 0 if the variable exists but is + not a primary input; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetPiVar Cudd_bddIsPsVar Cudd_bddIsNsVar] + +******************************************************************************/ +int +Cudd_bddIsPiVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return -1; + return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRIMARY_INPUT); + +} /* end of Cudd_bddIsPiVar */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is present state.] + + Description [Checks whether a variable is present state. Returns 1 if + the variable's type is present state; 0 if the variable exists but is + not a present state; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetPsVar Cudd_bddIsPiVar Cudd_bddIsNsVar] + +******************************************************************************/ +int +Cudd_bddIsPsVar( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return -1; + return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRESENT_STATE); + +} /* end of Cudd_bddIsPsVar */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is next state.] + + Description [Checks whether a variable is next state. Returns 1 if + the variable's type is present state; 0 if the variable exists but is + not a present state; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetNsVar Cudd_bddIsPiVar Cudd_bddIsPsVar] + +******************************************************************************/ +int +Cudd_bddIsNsVar( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return -1; + return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_NEXT_STATE); + +} /* end of Cudd_bddIsNsVar */ + + +/**Function******************************************************************** + + Synopsis [Sets a corresponding pair index for a given index.] + + Description [Sets a corresponding pair index for a given index. + These pair indices are present and next state variable. Returns 1 if + successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddReadPairIndex] + +******************************************************************************/ +int +Cudd_bddSetPairIndex( + DdManager *dd /* manager */, + int index /* variable index */, + int pairIndex /* corresponding variable index */) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].pairIndex = pairIndex; + return(1); + +} /* end of Cudd_bddSetPairIndex */ + + +/**Function******************************************************************** + + Synopsis [Reads a corresponding pair index for a given index.] + + Description [Reads a corresponding pair index for a given index. + These pair indices are present and next state variable. Returns the + corresponding variable index if the variable exists; -1 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetPairIndex] + +******************************************************************************/ +int +Cudd_bddReadPairIndex( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return -1; + return dd->subtables[dd->perm[index]].pairIndex; + +} /* end of Cudd_bddReadPairIndex */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable to be grouped.] + + Description [Sets a variable to be grouped. This function is used for + lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetVarHardGroup Cudd_bddResetVarToBeGrouped] + +******************************************************************************/ +int +Cudd_bddSetVarToBeGrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + if (dd->subtables[dd->perm[index]].varToBeGrouped <= CUDD_LAZY_SOFT_GROUP) { + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_SOFT_GROUP; + } + return(1); + +} /* end of Cudd_bddSetVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable to be a hard group.] + + Description [Sets a variable to be a hard group. This function is used + for lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetVarToBeGrouped Cudd_bddResetVarToBeGrouped + Cudd_bddIsVarHardGroup] + +******************************************************************************/ +int +Cudd_bddSetVarHardGroup( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_HARD_GROUP; + return(1); + +} /* end of Cudd_bddSetVarHardGrouped */ + + +/**Function******************************************************************** + + Synopsis [Resets a variable not to be grouped.] + + Description [Resets a variable not to be grouped. This function is + used for lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetVarToBeGrouped Cudd_bddSetVarHardGroup] + +******************************************************************************/ +int +Cudd_bddResetVarToBeGrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + if (dd->subtables[dd->perm[index]].varToBeGrouped <= + CUDD_LAZY_SOFT_GROUP) { + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_NONE; + } + return(1); + +} /* end of Cudd_bddResetVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is set to be grouped.] + + Description [Checks whether a variable is set to be grouped. This + function is used for lazy sifting.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_bddIsVarToBeGrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(-1); + if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP) + return(0); + else + return(dd->subtables[dd->perm[index]].varToBeGrouped); + +} /* end of Cudd_bddIsVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable to be ungrouped.] + + Description [Sets a variable to be ungrouped. This function is used + for lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddIsVarToBeUngrouped] + +******************************************************************************/ +int +Cudd_bddSetVarToBeUngrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_UNGROUP; + return(1); + +} /* end of Cudd_bddSetVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is set to be ungrouped.] + + Description [Checks whether a variable is set to be ungrouped. This + function is used for lazy sifting. Returns 1 if the variable is marked + to be ungrouped; 0 if the variable exists, but it is not marked to be + ungrouped; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetVarToBeUngrouped] + +******************************************************************************/ +int +Cudd_bddIsVarToBeUngrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(-1); + return dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP; + +} /* end of Cudd_bddIsVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is set to be in a hard group.] + + Description [Checks whether a variable is set to be in a hard group. This + function is used for lazy sifting. Returns 1 if the variable is marked + to be in a hard group; 0 if the variable exists, but it is not marked to be + in a hard group; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetVarHardGroup] + +******************************************************************************/ +int +Cudd_bddIsVarHardGroup( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(-1); + if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_HARD_GROUP) + return(1); + return(0); + +} /* end of Cudd_bddIsVarToBeGrouped */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Fixes a variable group tree.] + + Description [] + + SideEffects [Changes the variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static void +fixVarTree( + MtrNode * treenode, + int * perm, + int size) +{ + treenode->index = treenode->low; + treenode->low = ((int) treenode->index < size) ? + perm[treenode->index] : treenode->index; + if (treenode->child != NULL) + fixVarTree(treenode->child, perm, size); + if (treenode->younger != NULL) + fixVarTree(treenode->younger, perm, size); + return; + +} /* end of fixVarTree */ + + +/**Function******************************************************************** + + Synopsis [Adds multiplicity groups to a ZDD variable group tree.] + + Description [Adds multiplicity groups to a ZDD variable group tree. + Returns 1 if successful; 0 otherwise. This function creates the groups + for set of ZDD variables (whose cardinality is given by parameter + multiplicity) that are created for each BDD variable in + Cudd_zddVarsFromBddVars. The crux of the matter is to determine the index + each new group. (The index of the first variable in the group.) + We first build all the groups for the children of a node, and then deal + with the ZDD variables that are directly attached to the node. The problem + for these is that the tree itself does not provide information on their + position inside the group. While we deal with the children of the node, + therefore, we keep track of all the positions they occupy. The remaining + positions in the tree can be freely used. Also, we keep track of all the + variables placed in the children. All the remaining variables are directly + attached to the group. We can then place any pair of variables not yet + grouped in any pair of available positions in the node.] + + SideEffects [Changes the variable group tree.] + + SeeAlso [Cudd_zddVarsFromBddVars] + +******************************************************************************/ +static int +addMultiplicityGroups( + DdManager *dd /* manager */, + MtrNode *treenode /* current tree node */, + int multiplicity /* how many ZDD vars per BDD var */, + char *vmask /* variable pairs for which a group has been already built */, + char *lmask /* levels for which a group has already been built*/) +{ + int startV, stopV, startL; + int i, j; + MtrNode *auxnode = treenode; + + while (auxnode != NULL) { + if (auxnode->child != NULL) { + addMultiplicityGroups(dd,auxnode->child,multiplicity,vmask,lmask); + } + /* Build remaining groups. */ + startV = dd->permZ[auxnode->index] / multiplicity; + startL = auxnode->low / multiplicity; + stopV = startV + auxnode->size / multiplicity; + /* Walk down vmask starting at startV and build missing groups. */ + for (i = startV, j = startL; i < stopV; i++) { + if (vmask[i] == 0) { + MtrNode *node; + while (lmask[j] == 1) j++; + node = Mtr_MakeGroup(auxnode, j * multiplicity, multiplicity, + MTR_FIXED); + if (node == NULL) { + return(0); + } + node->index = dd->invpermZ[i * multiplicity]; + vmask[i] = 1; + lmask[j] = 1; + } + } + auxnode = auxnode->younger; + } + return(1); + +} /* end of addMultiplicityGroups */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddAbs.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddAbs.c new file mode 100644 index 000000000..5e809c134 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddAbs.c @@ -0,0 +1,579 @@ +/**CFile*********************************************************************** + + FileName [cuddAddAbs.c] + + PackageName [cudd] + + Synopsis [Quantification functions for ADDs.] + + Description [External procedures included in this module: +
    +
  • Cudd_addExistAbstract() +
  • Cudd_addUnivAbstract() +
  • Cudd_addOrAbstract() +
+ Internal procedures included in this module: +
    +
  • cuddAddExistAbstractRecur() +
  • cuddAddUnivAbstractRecur() +
  • cuddAddOrAbstractRecur() +
+ Static procedures included in this module: +
    +
  • addCheckPositiveCube() +
] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddAbs.c,v 1.16 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static DdNode *two; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int addCheckPositiveCube (DdManager *manager, DdNode *cube); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Existentially Abstracts all the variables in cube from f.] + + Description [Abstracts all the variables in cube from f by summing + over all possible values taken by the variables. Returns the + abstracted ADD.] + + SideEffects [None] + + SeeAlso [Cudd_addUnivAbstract Cudd_bddExistAbstract + Cudd_addOrAbstract] + +******************************************************************************/ +DdNode * +Cudd_addExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + two = cuddUniqueConst(manager,(CUDD_VALUE_TYPE) 2); + if (two == NULL) return(NULL); + cuddRef(two); + + if (addCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err,"Error: Can only abstract cubes"); + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddAddExistAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(manager,two); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,two); + cuddDeref(res); + + return(res); + +} /* end of Cudd_addExistAbstract */ + + +/**Function******************************************************************** + + Synopsis [Universally Abstracts all the variables in cube from f.] + + Description [Abstracts all the variables in cube from f by taking + the product over all possible values taken by the variable. Returns + the abstracted ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addExistAbstract Cudd_bddUnivAbstract + Cudd_addOrAbstract] + +******************************************************************************/ +DdNode * +Cudd_addUnivAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (addCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err,"Error: Can only abstract cubes"); + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddAddUnivAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_addUnivAbstract */ + + +/**Function******************************************************************** + + Synopsis [Disjunctively abstracts all the variables in cube from the + 0-1 ADD f.] + + Description [Abstracts all the variables in cube from the 0-1 ADD f + by taking the disjunction over all possible values taken by the + variables. Returns the abstracted ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addUnivAbstract Cudd_addExistAbstract] + +******************************************************************************/ +DdNode * +Cudd_addOrAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (addCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err,"Error: Can only abstract cubes"); + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddAddOrAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + return(res); + +} /* end of Cudd_addOrAbstract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addExistAbstract.] + + Description [Performs the recursive step of Cudd_addExistAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddAddExistAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *T, *E, *res, *res1, *res2, *zero; + + statLine(manager); + zero = DD_ZERO(manager); + + /* Cube is guaranteed to be a cube at this point. */ + if (f == zero || cuddIsConstant(cube)) { + return(f); + } + + /* Abstract a variable that does not appear in f => multiply by 2. */ + if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { + res1 = cuddAddExistAbstractRecur(manager, f, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + /* Use the "internal" procedure to be alerted in case of + ** dynamic reordering. If dynamic reordering occurs, we + ** have to abort the entire abstraction. + */ + res = cuddAddApplyRecur(manager,Cudd_addTimes,res1,two); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + cuddDeref(res); + return(res); + } + + if ((res = cuddCacheLookup2(manager, Cudd_addExistAbstract, f, cube)) != NULL) { + return(res); + } + + T = cuddT(f); + E = cuddE(f); + + /* If the two indices are the same, so are their levels. */ + if (f->index == cube->index) { + res1 = cuddAddExistAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddExistAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddAddApplyRecur(manager, Cudd_addPlus, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); + cuddDeref(res); + return(res); + } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ + res1 = cuddAddExistAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddExistAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); + return(res); + } + +} /* end of cuddAddExistAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addUnivAbstract.] + + Description [Performs the recursive step of Cudd_addUnivAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddAddUnivAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *T, *E, *res, *res1, *res2, *one, *zero; + + statLine(manager); + one = DD_ONE(manager); + zero = DD_ZERO(manager); + + /* Cube is guaranteed to be a cube at this point. + ** zero and one are the only constatnts c such that c*c=c. + */ + if (f == zero || f == one || cube == one) { + return(f); + } + + /* Abstract a variable that does not appear in f. */ + if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { + res1 = cuddAddUnivAbstractRecur(manager, f, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + /* Use the "internal" procedure to be alerted in case of + ** dynamic reordering. If dynamic reordering occurs, we + ** have to abort the entire abstraction. + */ + res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res1); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + cuddDeref(res); + return(res); + } + + if ((res = cuddCacheLookup2(manager, Cudd_addUnivAbstract, f, cube)) != NULL) { + return(res); + } + + T = cuddT(f); + E = cuddE(f); + + /* If the two indices are the same, so are their levels. */ + if (f->index == cube->index) { + res1 = cuddAddUnivAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddUnivAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); + cuddDeref(res); + return(res); + } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ + res1 = cuddAddUnivAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddUnivAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); + return(res); + } + +} /* end of cuddAddUnivAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addOrAbstract.] + + Description [Performs the recursive step of Cudd_addOrAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddAddOrAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *T, *E, *res, *res1, *res2, *one; + + statLine(manager); + one = DD_ONE(manager); + + /* Cube is guaranteed to be a cube at this point. */ + if (cuddIsConstant(f) || cube == one) { + return(f); + } + + /* Abstract a variable that does not appear in f. */ + if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { + res = cuddAddOrAbstractRecur(manager, f, cuddT(cube)); + return(res); + } + + if ((res = cuddCacheLookup2(manager, Cudd_addOrAbstract, f, cube)) != NULL) { + return(res); + } + + T = cuddT(f); + E = cuddE(f); + + /* If the two indices are the same, so are their levels. */ + if (f->index == cube->index) { + res1 = cuddAddOrAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + if (res1 != one) { + res2 = cuddAddOrAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddAddApplyRecur(manager, Cudd_addOr, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + } else { + res = res1; + } + cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); + cuddDeref(res); + return(res); + } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ + res1 = cuddAddOrAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddOrAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); + return(res); + } + +} /* end of cuddAddOrAbstractRecur */ + + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Checks whether cube is an ADD representing the product + of positive literals.] + + Description [Checks whether cube is an ADD representing the product of + positive literals. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +addCheckPositiveCube( + DdManager * manager, + DdNode * cube) +{ + if (Cudd_IsComplement(cube)) return(0); + if (cube == DD_ONE(manager)) return(1); + if (cuddIsConstant(cube)) return(0); + if (cuddE(cube) == DD_ZERO(manager)) { + return(addCheckPositiveCube(manager, cuddT(cube))); + } + return(0); + +} /* end of addCheckPositiveCube */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddApply.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddApply.c new file mode 100644 index 000000000..4ef228a99 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddApply.c @@ -0,0 +1,941 @@ +/**CFile*********************************************************************** + + FileName [cuddAddApply.c] + + PackageName [cudd] + + Synopsis [Apply functions for ADDs and their operators.] + + Description [External procedures included in this module: +
    +
  • Cudd_addApply() +
  • Cudd_addMonadicApply() +
  • Cudd_addPlus() +
  • Cudd_addTimes() +
  • Cudd_addThreshold() +
  • Cudd_addSetNZ() +
  • Cudd_addDivide() +
  • Cudd_addMinus() +
  • Cudd_addMinimum() +
  • Cudd_addMaximum() +
  • Cudd_addOneZeroMaximum() +
  • Cudd_addDiff() +
  • Cudd_addAgreement() +
  • Cudd_addOr() +
  • Cudd_addNand() +
  • Cudd_addNor() +
  • Cudd_addXor() +
  • Cudd_addXnor() +
+ Internal procedures included in this module: +
    +
  • cuddAddApplyRecur() +
  • cuddAddMonadicApplyRecur() +
] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.19 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Applies op to the corresponding discriminants of f and g.] + + Description [Applies op to the corresponding discriminants of f and g. + Returns a pointer to the result if succssful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addMonadicApply Cudd_addPlus Cudd_addTimes + Cudd_addThreshold Cudd_addSetNZ Cudd_addDivide Cudd_addMinus Cudd_addMinimum + Cudd_addMaximum Cudd_addOneZeroMaximum Cudd_addDiff Cudd_addAgreement + Cudd_addOr Cudd_addNand Cudd_addNor Cudd_addXor Cudd_addXnor] + +******************************************************************************/ +DdNode * +Cudd_addApply( + DdManager * dd, + DD_AOP op, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddApplyRecur(dd,op,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addApply */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point addition.] + + Description [Integer and floating point addition. Returns NULL if not + a terminal case; f+g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addPlus( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *res; + DdNode *F, *G; + CUDD_VALUE_TYPE value; + + F = *f; G = *g; + if (F == DD_ZERO(dd)) return(G); + if (G == DD_ZERO(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + value = cuddV(F)+cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); + } + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addPlus */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point multiplication.] + + Description [Integer and floating point multiplication. Returns NULL + if not a terminal case; f * g otherwise. This function can be used also + to take the AND of two 0-1 ADDs.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addTimes( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *res; + DdNode *F, *G; + CUDD_VALUE_TYPE value; + + F = *f; G = *g; + if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ZERO(dd)); + if (F == DD_ONE(dd)) return(G); + if (G == DD_ONE(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + value = cuddV(F)*cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); + } + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addTimes */ + + +/**Function******************************************************************** + + Synopsis [f if f>=g; 0 if f<g.] + + Description [Threshold operator for Apply (f if f >=g; 0 if f<g). + Returns NULL if not a terminal case; f op g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addThreshold( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G || F == DD_PLUS_INFINITY(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F) >= cuddV(G)) { + return(F); + } else { + return(DD_ZERO(dd)); + } + } + return(NULL); + +} /* end of Cudd_addThreshold */ + + +/**Function******************************************************************** + + Synopsis [This operator sets f to the value of g wherever g != 0.] + + Description [This operator sets f to the value of g wherever g != 0. + Returns NULL if not a terminal case; f op g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addSetNZ( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(F); + if (F == DD_ZERO(dd)) return(G); + if (G == DD_ZERO(dd)) return(F); + if (cuddIsConstant(G)) return(G); + return(NULL); + +} /* end of Cudd_addSetNZ */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point division.] + + Description [Integer and floating point division. Returns NULL if not + a terminal case; f / g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addDivide( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *res; + DdNode *F, *G; + CUDD_VALUE_TYPE value; + + F = *f; G = *g; + /* We would like to use F == G -> F/G == 1, but F and G may + ** contain zeroes. */ + if (F == DD_ZERO(dd)) return(DD_ZERO(dd)); + if (G == DD_ONE(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + value = cuddV(F)/cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); + } + return(NULL); + +} /* end of Cudd_addDivide */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point subtraction.] + + Description [Integer and floating point subtraction. Returns NULL if + not a terminal case; f - g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addMinus( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *res; + DdNode *F, *G; + CUDD_VALUE_TYPE value; + + F = *f; G = *g; + if (F == G) return(DD_ZERO(dd)); + if (F == DD_ZERO(dd)) return(cuddAddNegateRecur(dd,G)); + if (G == DD_ZERO(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + value = cuddV(F)-cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); + } + return(NULL); + +} /* end of Cudd_addMinus */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point min.] + + Description [Integer and floating point min for Cudd_addApply. + Returns NULL if not a terminal case; min(f,g) otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addMinimum( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == DD_PLUS_INFINITY(dd)) return(G); + if (G == DD_PLUS_INFINITY(dd)) return(F); + if (F == G) return(F); +#if 0 + /* These special cases probably do not pay off. */ + if (F == DD_MINUS_INFINITY(dd)) return(F); + if (G == DD_MINUS_INFINITY(dd)) return(G); +#endif + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F) <= cuddV(G)) { + return(F); + } else { + return(G); + } + } + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addMinimum */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point max.] + + Description [Integer and floating point max for Cudd_addApply. + Returns NULL if not a terminal case; max(f,g) otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addMaximum( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(F); + if (F == DD_MINUS_INFINITY(dd)) return(G); + if (G == DD_MINUS_INFINITY(dd)) return(F); +#if 0 + /* These special cases probably do not pay off. */ + if (F == DD_PLUS_INFINITY(dd)) return(F); + if (G == DD_PLUS_INFINITY(dd)) return(G); +#endif + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F) >= cuddV(G)) { + return(F); + } else { + return(G); + } + } + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addMaximum */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if f > g and 0 otherwise.] + + Description [Returns 1 if f > g and 0 otherwise. Used in + conjunction with Cudd_addApply. Returns NULL if not a terminal + case.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addOneZeroMaximum( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + + if (*f == *g) return(DD_ZERO(dd)); + if (*g == DD_PLUS_INFINITY(dd)) + return DD_ZERO(dd); + if (cuddIsConstant(*f) && cuddIsConstant(*g)) { + if (cuddV(*f) > cuddV(*g)) { + return(DD_ONE(dd)); + } else { + return(DD_ZERO(dd)); + } + } + + return(NULL); + +} /* end of Cudd_addOneZeroMaximum */ + + +/**Function******************************************************************** + + Synopsis [Returns plusinfinity if f=g; returns min(f,g) if f!=g.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is plusinfinity if f=g; min(f,g) if f!=g.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addDiff( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_PLUS_INFINITY(dd)); + if (F == DD_PLUS_INFINITY(dd)) return(G); + if (G == DD_PLUS_INFINITY(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F) != cuddV(G)) { + if (cuddV(F) < cuddV(G)) { + return(F); + } else { + return(G); + } + } else { + return(DD_PLUS_INFINITY(dd)); + } + } + return(NULL); + +} /* end of Cudd_addDiff */ + + +/**Function******************************************************************** + + Synopsis [f if f==g; background if f!=g.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is f if f==g; background if f!=g.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addAgreement( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(F); + if (F == dd->background) return(F); + if (G == dd->background) return(G); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(dd->background); + return(NULL); + +} /* end of Cudd_addAgreement */ + + +/**Function******************************************************************** + + Synopsis [Disjunction of two 0-1 ADDs.] + + Description [Disjunction of two 0-1 ADDs. Returns NULL + if not a terminal case; f OR g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addOr( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ONE(dd)); + if (cuddIsConstant(F)) return(G); + if (cuddIsConstant(G)) return(F); + if (F == G) return(F); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addOr */ + + +/**Function******************************************************************** + + Synopsis [NAND of two 0-1 ADDs.] + + Description [NAND of two 0-1 ADDs. Returns NULL + if not a terminal case; f NAND g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addNand( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addNand */ + + +/**Function******************************************************************** + + Synopsis [NOR of two 0-1 ADDs.] + + Description [NOR of two 0-1 ADDs. Returns NULL + if not a terminal case; f NOR g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addNor( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ZERO(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ONE(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addNor */ + + +/**Function******************************************************************** + + Synopsis [XOR of two 0-1 ADDs.] + + Description [XOR of two 0-1 ADDs. Returns NULL + if not a terminal case; f XOR g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addXor( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ZERO(dd)); + if (F == DD_ONE(dd) && G == DD_ZERO(dd)) return(DD_ONE(dd)); + if (G == DD_ONE(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addXor */ + + +/**Function******************************************************************** + + Synopsis [XNOR of two 0-1 ADDs.] + + Description [XNOR of two 0-1 ADDs. Returns NULL + if not a terminal case; f XNOR g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addXnor( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ONE(dd)); + if (F == DD_ONE(dd) && G == DD_ONE(dd)) return(DD_ONE(dd)); + if (G == DD_ZERO(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addXnor */ + + +/**Function******************************************************************** + + Synopsis [Applies op to the discriminants of f.] + + Description [Applies op to the discriminants of f. + Returns a pointer to the result if succssful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply Cudd_addLog] + +******************************************************************************/ +DdNode * +Cudd_addMonadicApply( + DdManager * dd, + DD_MAOP op, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddMonadicApplyRecur(dd,op,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addMonadicApply */ + + +/**Function******************************************************************** + + Synopsis [Natural logarithm of an ADD.] + + Description [Natural logarithm of an ADDs. Returns NULL + if not a terminal case; log(f) otherwise. The discriminants of f must + be positive double's.] + + SideEffects [None] + + SeeAlso [Cudd_addMonadicApply] + +******************************************************************************/ +DdNode * +Cudd_addLog( + DdManager * dd, + DdNode * f) +{ + if (cuddIsConstant(f)) { + CUDD_VALUE_TYPE value = log(cuddV(f)); + DdNode *res = cuddUniqueConst(dd,value); + return(res); + } + return(NULL); + +} /* end of Cudd_addLog */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addApply.] + + Description [Performs the recursive step of Cudd_addApply. Returns a + pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddAddMonadicApplyRecur] + +******************************************************************************/ +DdNode * +cuddAddApplyRecur( + DdManager * dd, + DD_AOP op, + DdNode * f, + DdNode * g) +{ + DdNode *res, + *fv, *fvn, *gv, *gvn, + *T, *E; + unsigned int ford, gord; + unsigned int index; + DD_CTFP cacheOp; + + /* Check terminal cases. Op may swap f and g to increase the + * cache hit rate. + */ + statLine(dd); + res = (*op)(dd,&f,&g); + if (res != NULL) return(res); + + /* Check cache. */ + cacheOp = (DD_CTFP) op; + res = cuddCacheLookup2(dd,cacheOp,f,g); + if (res != NULL) return(res); + + /* Recursive step. */ + ford = cuddI(dd,f->index); + gord = cuddI(dd,g->index); + if (ford <= gord) { + index = f->index; + fv = cuddT(f); + fvn = cuddE(f); + } else { + index = g->index; + fv = fvn = f; + } + if (gord <= ford) { + gv = cuddT(g); + gvn = cuddE(g); + } else { + gv = gvn = g; + } + + T = cuddAddApplyRecur(dd,op,fv,gv); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddApplyRecur(dd,op,fvn,gvn); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + + res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,cacheOp,f,g,res); + + return(res); + +} /* end of cuddAddApplyRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addMonadicApply.] + + Description [Performs the recursive step of Cudd_addMonadicApply. Returns a + pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddAddApplyRecur] + +******************************************************************************/ +DdNode * +cuddAddMonadicApplyRecur( + DdManager * dd, + DD_MAOP op, + DdNode * f) +{ + DdNode *res, *ft, *fe, *T, *E; + unsigned int index; + + /* Check terminal cases. */ + statLine(dd); + res = (*op)(dd,f); + if (res != NULL) return(res); + + /* Check cache. */ + res = cuddCacheLookup1(dd,op,f); + if (res != NULL) return(res); + + /* Recursive step. */ + index = f->index; + ft = cuddT(f); + fe = cuddE(f); + + T = cuddAddMonadicApplyRecur(dd,op,ft); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddMonadicApplyRecur(dd,op,fe); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + + res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,op,f,res); + + return(res); + +} /* end of cuddAddMonadicApplyRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddFind.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddFind.c new file mode 100644 index 000000000..1352a87ff --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddFind.c @@ -0,0 +1,316 @@ +/**CFile*********************************************************************** + + FileName [cuddAddFind.c] + + PackageName [cudd] + + Synopsis [Functions to find maximum and minimum in an ADD and to + extract the i-th bit.] + + Description [External procedures included in this module: +
    +
  • Cudd_addFindMax() +
  • Cudd_addFindMin() +
  • Cudd_addIthBit() +
+ Static functions included in this module: +
    +
  • addDoIthBit() +
] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.9 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addDoIthBit (DdManager *dd, DdNode *f, DdNode *index); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Finds the maximum discriminant of f.] + + Description [Returns a pointer to a constant ADD.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addFindMax( + DdManager * dd, + DdNode * f) +{ + DdNode *t, *e, *res; + + statLine(dd); + if (cuddIsConstant(f)) { + return(f); + } + + res = cuddCacheLookup1(dd,Cudd_addFindMax,f); + if (res != NULL) { + return(res); + } + + t = Cudd_addFindMax(dd,cuddT(f)); + if (t == DD_PLUS_INFINITY(dd)) return(t); + + e = Cudd_addFindMax(dd,cuddE(f)); + + res = (cuddV(t) >= cuddV(e)) ? t : e; + + cuddCacheInsert1(dd,Cudd_addFindMax,f,res); + + return(res); + +} /* end of Cudd_addFindMax */ + + +/**Function******************************************************************** + + Synopsis [Finds the minimum discriminant of f.] + + Description [Returns a pointer to a constant ADD.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addFindMin( + DdManager * dd, + DdNode * f) +{ + DdNode *t, *e, *res; + + statLine(dd); + if (cuddIsConstant(f)) { + return(f); + } + + res = cuddCacheLookup1(dd,Cudd_addFindMin,f); + if (res != NULL) { + return(res); + } + + t = Cudd_addFindMin(dd,cuddT(f)); + if (t == DD_MINUS_INFINITY(dd)) return(t); + + e = Cudd_addFindMin(dd,cuddE(f)); + + res = (cuddV(t) <= cuddV(e)) ? t : e; + + cuddCacheInsert1(dd,Cudd_addFindMin,f,res); + + return(res); + +} /* end of Cudd_addFindMin */ + + +/**Function******************************************************************** + + Synopsis [Extracts the i-th bit from an ADD.] + + Description [Produces an ADD from another ADD by replacing all + discriminants whose i-th bit is equal to 1 with 1, and all other + discriminants with 0. The i-th bit refers to the integer + representation of the leaf value. If the value is has a fractional + part, it is ignored. Repeated calls to this procedure allow one to + transform an integer-valued ADD into an array of ADDs, one for each + bit of the leaf values. Returns a pointer to the resulting ADD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddIthBit] + +******************************************************************************/ +DdNode * +Cudd_addIthBit( + DdManager * dd, + DdNode * f, + int bit) +{ + DdNode *res; + DdNode *index; + + /* Use a constant node to remember the bit, so that we can use the + ** global cache. + */ + index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit); + if (index == NULL) return(NULL); + cuddRef(index); + + do { + dd->reordered = 0; + res = addDoIthBit(dd, f, index); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, index); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, index); + cuddDeref(res); + return(res); + +} /* end of Cudd_addIthBit */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addIthBit.] + + Description [Performs the recursive step for Cudd_addIthBit. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +addDoIthBit( + DdManager * dd, + DdNode * f, + DdNode * index) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int mask, value; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + mask = 1 << ((int) cuddV(index)); + value = (int) cuddV(f); + return((value & mask) == 0 ? DD_ZERO(dd) : DD_ONE(dd)); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addDoIthBit,f,index); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addDoIthBit(dd,fv,index); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addDoIthBit(dd,fvn,index); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addDoIthBit,f,index,res); + + return(res); + +} /* end of addDoIthBit */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddInv.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddInv.c new file mode 100644 index 000000000..454aa811d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddInv.c @@ -0,0 +1,201 @@ +/**CFile*********************************************************************** + + FileName [cuddAddInv.c] + + PackageName [cudd] + + Synopsis [Function to compute the scalar inverse of an ADD.] + + Description [External procedures included in this module: +
    +
  • Cudd_addScalarInverse() +
+ Internal procedures included in this module: +
    +
  • cuddAddScalarInverseRecur() +
] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddInv.c,v 1.10 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the scalar inverse of an ADD.] + + Description [Computes an n ADD where the discriminants are the + multiplicative inverses of the corresponding discriminants of the + argument ADD. Returns a pointer to the resulting ADD in case of + success. Returns NULL if any discriminants smaller than epsilon is + encountered.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addScalarInverse( + DdManager * dd, + DdNode * f, + DdNode * epsilon) +{ + DdNode *res; + + if (!cuddIsConstant(epsilon)) { + (void) fprintf(dd->err,"Invalid epsilon\n"); + return(NULL); + } + do { + dd->reordered = 0; + res = cuddAddScalarInverseRecur(dd,f,epsilon); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addScalarInverse */ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of addScalarInverse.] + + Description [Returns a pointer to the resulting ADD in case of + success. Returns NULL if any discriminants smaller than epsilon is + encountered.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddAddScalarInverseRecur( + DdManager * dd, + DdNode * f, + DdNode * epsilon) +{ + DdNode *t, *e, *res; + CUDD_VALUE_TYPE value; + + statLine(dd); + if (cuddIsConstant(f)) { + if (ddAbs(cuddV(f)) < cuddV(epsilon)) return(NULL); + value = 1.0 / cuddV(f); + res = cuddUniqueConst(dd,value); + return(res); + } + + res = cuddCacheLookup2(dd,Cudd_addScalarInverse,f,epsilon); + if (res != NULL) return(res); + + t = cuddAddScalarInverseRecur(dd,cuddT(f),epsilon); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddAddScalarInverseRecur(dd,cuddE(f),epsilon); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + res = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd,Cudd_addScalarInverse,f,epsilon,res); + + return(res); + +} /* end of cuddAddScalarInverseRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddIte.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddIte.c new file mode 100644 index 000000000..a6e84c54c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddIte.c @@ -0,0 +1,639 @@ +/**CFile*********************************************************************** + + FileName [cuddAddIte.c] + + PackageName [cudd] + + Synopsis [ADD ITE function and satellites.] + + Description [External procedures included in this module: +
    +
  • Cudd_addIte() +
  • Cudd_addIteConstant() +
  • Cudd_addEvalConst() +
  • Cudd_addCmpl() +
  • Cudd_addLeq() +
+ Internal procedures included in this module: +
    +
  • cuddAddIteRecur() +
  • cuddAddCmplRecur() +
+ Static procedures included in this module: +
    +
  • addVarToConst() +
] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.16 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void addVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements ITE(f,g,h).] + + Description [Implements ITE(f,g,h). This procedure assumes that f is + a 0-1 ADD. Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addIteConstant Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddIteRecur(dd,f,g,h); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addIte */ + + +/**Function******************************************************************** + + Synopsis [Implements ITEconstant for ADDs.] + + Description [Implements ITEconstant for ADDs. f must be a 0-1 ADD. + Returns a pointer to the resulting ADD (which may or may not be + constant) or DD_NON_CONSTANT. No new nodes are created. This function + can be used, for instance, to check that g has a constant value + (specified by h) whenever f is 1. If the constant value is unknown, + then one should use Cudd_addEvalConst.] + + SideEffects [None] + + SeeAlso [Cudd_addIte Cudd_addEvalConst Cudd_bddIteConstant] + +******************************************************************************/ +DdNode * +Cudd_addIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *one,*zero; + DdNode *Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*r,*t,*e; + unsigned int topf,topg,toph,v; + + statLine(dd); + /* Trivial cases. */ + if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ + return(g); + } + if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ + return(h); + } + + /* From now on, f is known not to be a constant. */ + addVarToConst(f,&g,&h,one,zero); + + /* Check remaining one variable cases. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } + if (cuddIsConstant(g) && cuddIsConstant(h)) { + return(DD_NON_CONSTANT); + } + + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + toph = cuddI(dd,h->index); + v = ddMin(topg,toph); + + /* ITE(F,G,H) = (x,G,H) (non constant) if F = (x,1,0), x < top(G,H). */ + if (topf < v && cuddIsConstant(cuddT(f)) && cuddIsConstant(cuddE(f))) { + return(DD_NON_CONSTANT); + } + + /* Check cache. */ + r = cuddConstantLookup(dd,DD_ADD_ITE_CONSTANT_TAG,f,g,h); + if (r != NULL) { + return(r); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf,v); /* v = top_var(F,G,H) */ + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg == v) { + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + if (toph == v) { + Hv = cuddT(h); Hnv = cuddE(h); + } else { + Hv = Hnv = h; + } + + /* Recursive step. */ + t = Cudd_addIteConstant(dd,Fv,Gv,Hv); + if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + e = Cudd_addIteConstant(dd,Fnv,Gnv,Hnv); + if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, t); + return(t); + +} /* end of Cudd_addIteConstant */ + + +/**Function******************************************************************** + + Synopsis [Checks whether ADD g is constant whenever ADD f is 1.] + + Description [Checks whether ADD g is constant whenever ADD f is 1. f + must be a 0-1 ADD. Returns a pointer to the resulting ADD (which may + or may not be constant) or DD_NON_CONSTANT. If f is identically 0, + the check is assumed to be successful, and the background value is + returned. No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_addIteConstant Cudd_addLeq] + +******************************************************************************/ +DdNode * +Cudd_addEvalConst( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *zero; + DdNode *Fv,*Fnv,*Gv,*Gnv,*r,*t,*e; + unsigned int topf,topg; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + statLine(dd); + /* Terminal cases. */ + if (f == DD_ONE(dd) || cuddIsConstant(g)) { + return(g); + } + if (f == (zero = DD_ZERO(dd))) { + return(dd->background); + } + +#ifdef DD_DEBUG + assert(!cuddIsConstant(f)); +#endif + /* From now on, f and g are known not to be constants. */ + + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + + /* Check cache. */ + r = cuddConstantLookup(dd,DD_ADD_EVAL_CONST_TAG,f,g,g); + if (r != NULL) { + return(r); + } + + /* Compute cofactors. */ + if (topf <= topg) { + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg <= topf) { + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + + /* Recursive step. */ + if (Fv != zero) { + t = Cudd_addEvalConst(dd,Fv,Gv); + if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + if (Fnv != zero) { + e = Cudd_addEvalConst(dd,Fnv,Gnv); + if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + } + cuddCacheInsert2(dd,Cudd_addEvalConst,f,g,t); + return(t); + } else { /* Fnv must be != zero */ + e = Cudd_addEvalConst(dd,Fnv,Gnv); + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e); + return(e); + } + +} /* end of Cudd_addEvalConst */ + + +/**Function******************************************************************** + + Synopsis [Computes the complement of an ADD a la C language.] + + Description [Computes the complement of an ADD a la C language: The + complement of 0 is 1 and the complement of everything else is 0. + Returns a pointer to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNegate] + +******************************************************************************/ +DdNode * +Cudd_addCmpl( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddCmplRecur(dd,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addCmpl */ + + +/**Function******************************************************************** + + Synopsis [Determines whether f is less than or equal to g.] + + Description [Returns 1 if f is less than or equal to g; 0 otherwise. + No new nodes are created. This procedure works for arbitrary ADDs. + For 0-1 ADDs Cudd_addEvalConst is more efficient.] + + SideEffects [None] + + SeeAlso [Cudd_addIteConstant Cudd_addEvalConst Cudd_bddLeq] + +******************************************************************************/ +int +Cudd_addLeq( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *tmp, *fv, *fvn, *gv, *gvn; + unsigned int topf, topg, res; + + /* Terminal cases. */ + if (f == g) return(1); + + statLine(dd); + if (cuddIsConstant(f)) { + if (cuddIsConstant(g)) return(cuddV(f) <= cuddV(g)); + if (f == DD_MINUS_INFINITY(dd)) return(1); + if (f == DD_PLUS_INFINITY(dd)) return(0); /* since f != g */ + } + if (g == DD_PLUS_INFINITY(dd)) return(1); + if (g == DD_MINUS_INFINITY(dd)) return(0); /* since f != g */ + + /* Check cache. */ + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq,f,g); + if (tmp != NULL) { + return(tmp == DD_ONE(dd)); + } + + /* Compute cofactors. One of f and g is not constant. */ + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + if (topf <= topg) { + fv = cuddT(f); fvn = cuddE(f); + } else { + fv = fvn = f; + } + if (topg <= topf) { + gv = cuddT(g); gvn = cuddE(g); + } else { + gv = gvn = g; + } + + res = Cudd_addLeq(dd,fvn,gvn) && Cudd_addLeq(dd,fv,gv); + + /* Store result in cache and return. */ + cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq,f,g, + Cudd_NotCond(DD_ONE(dd),res==0)); + return(res); + +} /* end of Cudd_addLeq */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addIte(f,g,h).] + + Description [Implements the recursive step of Cudd_addIte(f,g,h). + Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addIte] + +******************************************************************************/ +DdNode * +cuddAddIteRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *one,*zero; + DdNode *r,*Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*t,*e; + unsigned int topf,topg,toph,v; + int index; + + statLine(dd); + /* Trivial cases. */ + + /* One variable cases. */ + if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ + return(g); + } + if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ + return(h); + } + + /* From now on, f is known to not be a constant. */ + addVarToConst(f,&g,&h,one,zero); + + /* Check remaining one variable cases. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } + + if (g == one) { /* ITE(F,1,0) = F */ + if (h == zero) return(f); + } + + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + toph = cuddI(dd,h->index); + v = ddMin(topg,toph); + + /* A shortcut: ITE(F,G,H) = (x,G,H) if F=(x,1,0), x < top(G,H). */ + if (topf < v && cuddT(f) == one && cuddE(f) == zero) { + r = cuddUniqueInter(dd,(int)f->index,g,h); + return(r); + } + if (topf < v && cuddT(f) == zero && cuddE(f) == one) { + r = cuddUniqueInter(dd,(int)f->index,h,g); + return(r); + } + + /* Check cache. */ + r = cuddCacheLookup(dd,DD_ADD_ITE_TAG,f,g,h); + if (r != NULL) { + return(r); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf,v); /* v = top_var(F,G,H) */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg == v) { + index = g->index; + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + if (toph == v) { + index = h->index; + Hv = cuddT(h); Hnv = cuddE(h); + } else { + Hv = Hnv = h; + } + + /* Recursive step. */ + t = cuddAddIteRecur(dd,Fv,Gv,Hv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddAddIteRecur(dd,Fnv,Gnv,Hnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert(dd,DD_ADD_ITE_TAG,f,g,h,r); + + return(r); + +} /* end of cuddAddIteRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addCmpl.] + + Description [Performs the recursive step of Cudd_addCmpl. Returns a + pointer to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCmpl] + +******************************************************************************/ +DdNode * +cuddAddCmplRecur( + DdManager * dd, + DdNode * f) +{ + DdNode *one,*zero; + DdNode *r,*Fv,*Fnv,*t,*e; + + statLine(dd); + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + if (cuddIsConstant(f)) { + if (f == zero) { + return(one); + } else { + return(zero); + } + } + r = cuddCacheLookup1(dd,Cudd_addCmpl,f); + if (r != NULL) { + return(r); + } + Fv = cuddT(f); + Fnv = cuddE(f); + t = cuddAddCmplRecur(dd,Fv); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddAddCmplRecur(dd,Fnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + r = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + cuddCacheInsert1(dd,Cudd_addCmpl,f,r); + return(r); + +} /* end of cuddAddCmplRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Replaces variables with constants if possible (part of + canonical form).] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static void +addVarToConst( + DdNode * f, + DdNode ** gp, + DdNode ** hp, + DdNode * one, + DdNode * zero) +{ + DdNode *g = *gp; + DdNode *h = *hp; + + if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + *gp = one; + } + + if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + *hp = zero; + } + +} /* end of addVarToConst */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddNeg.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddNeg.c new file mode 100644 index 000000000..92c1cd71f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddNeg.c @@ -0,0 +1,290 @@ +/**CFile*********************************************************************** + + FileName [cuddAddNeg.c] + + PackageName [cudd] + + Synopsis [Function to compute the negation of an ADD.] + + Description [External procedures included in this module: +
    +
  • Cudd_addNegate() +
  • Cudd_addRoundOff() +
+ Internal procedures included in this module: +
    +
  • cuddAddNegateRecur() +
  • cuddAddRoundOffRecur() +
] + + Author [Fabio Somenzi, Balakrishna Kumthekar] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddNeg.c,v 1.14 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Computes the additive inverse of an ADD.] + + Description [Computes the additive inverse of an ADD. Returns a pointer + to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCmpl] + +******************************************************************************/ +DdNode * +Cudd_addNegate( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddNegateRecur(dd,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addNegate */ + + +/**Function******************************************************************** + + Synopsis [Rounds off the discriminants of an ADD.] + + Description [Rounds off the discriminants of an ADD. The discriminants are + rounded off to N digits after the decimal. Returns a pointer to the result + ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addRoundOff( + DdManager * dd, + DdNode * f, + int N) +{ + DdNode *res; + double trunc = pow(10.0,(double)N); + + do { + dd->reordered = 0; + res = cuddAddRoundOffRecur(dd,f,trunc); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addRoundOff */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addNegate.] + + Description [Implements the recursive step of Cudd_addNegate. + Returns a pointer to the result.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddAddNegateRecur( + DdManager * dd, + DdNode * f) +{ + DdNode *res, + *fv, *fvn, + *T, *E; + + statLine(dd); + /* Check terminal cases. */ + if (cuddIsConstant(f)) { + res = cuddUniqueConst(dd,-cuddV(f)); + return(res); + } + + /* Check cache */ + res = cuddCacheLookup1(dd,Cudd_addNegate,f); + if (res != NULL) return(res); + + /* Recursive Step */ + fv = cuddT(f); + fvn = cuddE(f); + T = cuddAddNegateRecur(dd,fv); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddNegateRecur(dd,fvn); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,Cudd_addNegate,f,res); + + return(res); + +} /* end of cuddAddNegateRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addRoundOff.] + + Description [Implements the recursive step of Cudd_addRoundOff. + Returns a pointer to the result.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddAddRoundOffRecur( + DdManager * dd, + DdNode * f, + double trunc) +{ + + DdNode *res, *fv, *fvn, *T, *E; + double n; + DD_CTFP1 cacheOp; + + statLine(dd); + if (cuddIsConstant(f)) { + n = ceil(cuddV(f)*trunc)/trunc; + res = cuddUniqueConst(dd,n); + return(res); + } + cacheOp = (DD_CTFP1) Cudd_addRoundOff; + res = cuddCacheLookup1(dd,cacheOp,f); + if (res != NULL) { + return(res); + } + /* Recursive Step */ + fv = cuddT(f); + fvn = cuddE(f); + T = cuddAddRoundOffRecur(dd,fv,trunc); + if (T == NULL) { + return(NULL); + } + cuddRef(T); + E = cuddAddRoundOffRecur(dd,fvn,trunc); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,cacheOp,f,res); + return(res); + +} /* end of cuddAddRoundOffRecur */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddWalsh.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddWalsh.c new file mode 100644 index 000000000..146b1d313 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddWalsh.c @@ -0,0 +1,391 @@ +/**CFile*********************************************************************** + + FileName [cuddAddWalsh.c] + + PackageName [cudd] + + Synopsis [Functions that generate Walsh matrices and residue + functions in ADD form.] + + Description [External procedures included in this module: +
    +
  • Cudd_addWalsh() +
  • Cudd_addResidue() +
+ Static procedures included in this module: +
    +
  • addWalshInt() +
] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddWalsh.c,v 1.11 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addWalshInt (DdManager *dd, DdNode **x, DdNode **y, int n); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Generates a Walsh matrix in ADD form.] + + Description [Generates a Walsh matrix in ADD form. Returns a pointer + to the matrixi if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addWalsh( + DdManager * dd, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = addWalshInt(dd, x, y, n); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addWalsh */ + + +/**Function******************************************************************** + + Synopsis [Builds an ADD for the residue modulo m of an n-bit + number.] + + Description [Builds an ADD for the residue modulo m of an n-bit + number. The modulus must be at least 2, and the number of bits at + least 1. Parameter options specifies whether the MSB should be on top + or the LSB; and whther the number whose residue is computed is in + two's complement notation or not. The macro CUDD_RESIDUE_DEFAULT + specifies LSB on top and unsigned number. The macro CUDD_RESIDUE_MSB + specifies MSB on top, and the macro CUDD_RESIDUE_TC specifies two's + complement residue. To request MSB on top and two's complement residue + simultaneously, one can OR the two macros: + CUDD_RESIDUE_MSB | CUDD_RESIDUE_TC. + Cudd_addResidue returns a pointer to the resulting ADD if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addResidue( + DdManager * dd /* manager */, + int n /* number of bits */, + int m /* modulus */, + int options /* options */, + int top /* index of top variable */) +{ + int msbLsb; /* MSB on top (1) or LSB on top (0) */ + int tc; /* two's complement (1) or unsigned (0) */ + int i, j, k, t, residue, thisOne, previous, index; + DdNode **array[2], *var, *tmp, *res; + + /* Sanity check. */ + if (n < 1 && m < 2) return(NULL); + + msbLsb = options & CUDD_RESIDUE_MSB; + tc = options & CUDD_RESIDUE_TC; + + /* Allocate and initialize working arrays. */ + array[0] = ALLOC(DdNode *,m); + if (array[0] == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + array[1] = ALLOC(DdNode *,m); + if (array[1] == NULL) { + FREE(array[0]); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < m; i++) { + array[0][i] = array[1][i] = NULL; + } + + /* Initialize residues. */ + for (i = 0; i < m; i++) { + tmp = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) i); + if (tmp == NULL) { + for (j = 0; j < i; j++) { + Cudd_RecursiveDeref(dd,array[1][j]); + } + FREE(array[0]); + FREE(array[1]); + return(NULL); + } + cuddRef(tmp); + array[1][i] = tmp; + } + + /* Main iteration. */ + residue = 1; /* residue of 2**0 */ + for (k = 0; k < n; k++) { + /* Choose current and previous arrays. */ + thisOne = k & 1; + previous = thisOne ^ 1; + /* Build an ADD projection function. */ + if (msbLsb) { + index = top+n-k-1; + } else { + index = top+k; + } + var = cuddUniqueInter(dd,index,DD_ONE(dd),DD_ZERO(dd)); + if (var == NULL) { + for (j = 0; j < m; j++) { + Cudd_RecursiveDeref(dd,array[previous][j]); + } + FREE(array[0]); + FREE(array[1]); + return(NULL); + } + cuddRef(var); + for (i = 0; i < m; i ++) { + t = (i + residue) % m; + tmp = Cudd_addIte(dd,var,array[previous][t],array[previous][i]); + if (tmp == NULL) { + for (j = 0; j < i; j++) { + Cudd_RecursiveDeref(dd,array[thisOne][j]); + } + for (j = 0; j < m; j++) { + Cudd_RecursiveDeref(dd,array[previous][j]); + } + FREE(array[0]); + FREE(array[1]); + return(NULL); + } + cuddRef(tmp); + array[thisOne][i] = tmp; + } + /* One layer completed. Free the other array for the next iteration. */ + for (i = 0; i < m; i++) { + Cudd_RecursiveDeref(dd,array[previous][i]); + } + Cudd_RecursiveDeref(dd,var); + /* Update residue of 2**k. */ + residue = (2 * residue) % m; + /* Adjust residue for MSB, if this is a two's complement number. */ + if (tc && (k == n - 1)) { + residue = (m - residue) % m; + } + } + + /* We are only interested in the 0-residue node of the top layer. */ + for (i = 1; i < m; i++) { + Cudd_RecursiveDeref(dd,array[(n - 1) & 1][i]); + } + res = array[(n - 1) & 1][0]; + + FREE(array[0]); + FREE(array[1]); + + cuddDeref(res); + return(res); + +} /* end of Cudd_addResidue */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addWalsh.] + + Description [Generates a Walsh matrix in ADD form. Returns a pointer + to the matrixi if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +addWalshInt( + DdManager * dd, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *one, *minusone; + DdNode *t, *u, *t1, *u1, *v, *w; + int i; + + one = DD_ONE(dd); + if (n == 0) return(one); + + /* Build bottom part of ADD outside loop */ + minusone = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) -1); + if (minusone == NULL) return(NULL); + cuddRef(minusone); + v = Cudd_addIte(dd, y[n-1], minusone, one); + if (v == NULL) { + Cudd_RecursiveDeref(dd, minusone); + return(NULL); + } + cuddRef(v); + u = Cudd_addIte(dd, x[n-1], v, one); + if (u == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + if (n>1) { + w = Cudd_addIte(dd, y[n-1], one, minusone); + if (w == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(w); + t = Cudd_addIte(dd, x[n-1], w, minusone); + if (t == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(t); + Cudd_RecursiveDeref(dd, w); + } + cuddDeref(minusone); /* minusone is in the result; it won't die */ + + /* Loop to build the rest of the ADD */ + for (i=n-2; i>=0; i--) { + t1 = t; u1 = u; + v = Cudd_addIte(dd, y[i], t1, u1); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + return(NULL); + } + cuddRef(v); + u = Cudd_addIte(dd, x[i], v, u1); + if (u == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + if (i>0) { + w = Cudd_addIte(dd, y[i], u1, t1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(w); + t = Cudd_addIte(dd, x[i], w, t1); + if (u == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(t); + Cudd_RecursiveDeref(dd, w); + } + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + } + + cuddDeref(u); + return(u); + +} /* end of addWalshInt */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAndAbs.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAndAbs.c new file mode 100644 index 000000000..a800830bf --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAndAbs.c @@ -0,0 +1,373 @@ +/**CFile*********************************************************************** + + FileName [cuddAndAbs.c] + + PackageName [cudd] + + Synopsis [Combined AND and existential abstraction for BDDs] + + Description [External procedures included in this module: +
    +
  • Cudd_bddAndAbstract() +
  • Cudd_bddAndAbstractLimit() +
+ Internal procedures included in this module: +
    +
  • cuddBddAndAbstractRecur() +
] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.20 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Takes the AND of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise. + Cudd_bddAndAbstract implements the semiring matrix multiplication + algorithm for the boolean semiring.] + + SideEffects [None] + + SeeAlso [Cudd_addMatrixMultiply Cudd_addTriangle Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddAndAbstract( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *res; + + do { + manager->reordered = 0; + res = cuddBddAndAbstractRecur(manager, f, g, cube); + } while (manager->reordered == 1); + return(res); + +} /* end of Cudd_bddAndAbstract */ + + +/**Function******************************************************************** + + Synopsis [Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. Returns NULL if too many nodes are required.] + + Description [Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise. + In particular, if the number of new nodes created exceeds + limit, this function returns NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddAndAbstractLimit( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = manager->maxLive; + + manager->maxLive = (manager->keys - manager->dead) + + (manager->keysZ - manager->deadZ) + limit; + do { + manager->reordered = 0; + res = cuddBddAndAbstractRecur(manager, f, g, cube); + } while (manager->reordered == 1); + manager->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddAndAbstractLimit */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Takes the AND of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +cuddBddAndAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *zero, *r, *t, *e; + unsigned int topf, topg, topcube, top, index; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == one && g == one) return(one); + + if (cube == one) { + return(cuddBddAndRecur(manager, f, g)); + } + if (f == one || f == g) { + return(cuddBddExistAbstractRecur(manager, g, cube)); + } + if (g == one) { + return(cuddBddExistAbstractRecur(manager, f, cube)); + } + /* At this point f, g, and cube are not constant. */ + + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; + g = tmp; + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + top = ddMin(topf, topg); + topcube = manager->perm[cube->index]; + + while (topcube < top) { + cube = cuddT(cube); + if (cube == one) { + return(cuddBddAndRecur(manager, f, g)); + } + topcube = manager->perm[cube->index]; + } + /* Now, topcube >= top. */ + + /* Check cache. */ + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube); + if (r != NULL) { + return(r); + } + } + + if (topf == top) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg == top) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + if (topcube == top) { /* quantify */ + DdNode *Cube = cuddT(cube); + t = cuddBddAndAbstractRecur(manager, ft, gt, Cube); + if (t == NULL) return(NULL); + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. Likewise t + t * anything == t. + ** Notice that t == fe implies that fe does not depend on the + ** variables in Cube. Likewise for t == ge. + */ + if (t == one || t == fe || t == ge) { + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, + f, g, cube, t); + return(t); + } + cuddRef(t); + /* Special case: t + !t * anything == t + anything. */ + if (t == Cudd_Not(fe)) { + e = cuddBddExistAbstractRecur(manager, ge, Cube); + } else if (t == Cudd_Not(ge)) { + e = cuddBddExistAbstractRecur(manager, fe, Cube); + } else { + e = cuddBddAndAbstractRecur(manager, fe, ge, Cube); + } + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + if (t == e) { + r = t; + cuddDeref(t); + } else { + cuddRef(e); + r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_DelayedDerefBdd(manager, t); + Cudd_DelayedDerefBdd(manager, e); + cuddDeref(r); + } + } else { + t = cuddBddAndAbstractRecur(manager, ft, gt, cube); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddAndAbstractRecur(manager, fe, ge, cube); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + if (t == e) { + r = t; + cuddDeref(t); + } else { + cuddRef(e); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager, (int) index, + Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + } + } + + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r); + return (r); + +} /* end of cuddBddAndAbstractRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAnneal.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAnneal.c new file mode 100644 index 000000000..622c3d14a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAnneal.c @@ -0,0 +1,814 @@ +/**CFile*********************************************************************** + + FileName [cuddAnneal.c] + + PackageName [cudd] + + Synopsis [Reordering of DDs based on simulated annealing] + + Description [Internal procedures included in this file: +
    +
  • cuddAnnealing() +
+ Static procedures included in this file: +
    +
  • stopping_criterion() +
  • random_generator() +
  • ddExchange() +
  • ddJumpingAux() +
  • ddJumpingUp() +
  • ddJumpingDown() +
  • siftBackwardProb() +
  • copyOrder() +
  • restoreOrder() +
+ ] + + SeeAlso [] + + Author [Jae-Young Jang, Jorgen Sivesind] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Annealing parameters */ +#define BETA 0.6 +#define ALPHA 0.90 +#define EXC_PROB 0.4 +#define JUMP_UP_PROB 0.36 +#define MAXGEN_RATIO 15.0 +#define STOP_TEMP 1.0 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAnneal.c,v 1.15 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef DD_STATS +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +static int tosses; +static int acceptances; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int stopping_criterion (int c1, int c2, int c3, int c4, double temp); +static double random_generator (void); +static int ddExchange (DdManager *table, int x, int y, double temp); +static int ddJumpingAux (DdManager *table, int x, int x_low, int x_high, double temp); +static Move * ddJumpingUp (DdManager *table, int x, int x_low, int initial_size); +static Move * ddJumpingDown (DdManager *table, int x, int x_high, int initial_size); +static int siftBackwardProb (DdManager *table, Move *moves, int size, double temp); +static void copyOrder (DdManager *table, int *array, int lower, int upper); +static int restoreOrder (DdManager *table, int *array, int lower, int upper); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Get new variable-order by simulated annealing algorithm.] + + Description [Get x, y by random selection. Choose either + exchange or jump randomly. In case of jump, choose between jump_up + and jump_down randomly. Do exchange or jump and get optimal case. + Loop until there is no improvement or temperature reaches + minimum. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddAnnealing( + DdManager * table, + int lower, + int upper) +{ + int nvars; + int size; + int x,y; + int result; + int c1, c2, c3, c4; + int BestCost; + int *BestOrder; + double NewTemp, temp; + double rand1; + int innerloop, maxGen; + int ecount, ucount, dcount; + + nvars = upper - lower + 1; + + result = cuddSifting(table,lower,upper); +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + if (result == 0) return(0); + + size = table->keys - table->isolated; + + /* Keep track of the best order. */ + BestCost = size; + BestOrder = ALLOC(int,nvars); + if (BestOrder == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + copyOrder(table,BestOrder,lower,upper); + + temp = BETA * size; + maxGen = (int) (MAXGEN_RATIO * nvars); + + c1 = size + 10; + c2 = c1 + 10; + c3 = size; + c4 = c2 + 10; + ecount = ucount = dcount = 0; + + while (!stopping_criterion(c1, c2, c3, c4, temp)) { +#ifdef DD_STATS + (void) fprintf(table->out,"temp=%f\tsize=%d\tgen=%d\t", + temp,size,maxGen); + tosses = acceptances = 0; +#endif + for (innerloop = 0; innerloop < maxGen; innerloop++) { + /* Choose x, y randomly. */ + x = (int) Cudd_Random() % nvars; + do { + y = (int) Cudd_Random() % nvars; + } while (x == y); + x += lower; + y += lower; + if (x > y) { + int tmp = x; + x = y; + y = tmp; + } + + /* Choose move with roulette wheel. */ + rand1 = random_generator(); + if (rand1 < EXC_PROB) { + result = ddExchange(table,x,y,temp); /* exchange */ + ecount++; +#if 0 + (void) fprintf(table->out, + "Exchange of %d and %d: size = %d\n", + x,y,table->keys - table->isolated); +#endif + } else if (rand1 < EXC_PROB + JUMP_UP_PROB) { + result = ddJumpingAux(table,y,x,y,temp); /* jumping_up */ + ucount++; +#if 0 + (void) fprintf(table->out, + "Jump up of %d to %d: size = %d\n", + y,x,table->keys - table->isolated); +#endif + } else { + result = ddJumpingAux(table,x,x,y,temp); /* jumping_down */ + dcount++; +#if 0 + (void) fprintf(table->out, + "Jump down of %d to %d: size = %d\n", + x,y,table->keys - table->isolated); +#endif + } + + if (!result) { + FREE(BestOrder); + return(0); + } + + size = table->keys - table->isolated; /* keep current size */ + if (size < BestCost) { /* update best order */ + BestCost = size; + copyOrder(table,BestOrder,lower,upper); + } + } + c1 = c2; + c2 = c3; + c3 = c4; + c4 = size; + NewTemp = ALPHA * temp; + if (NewTemp >= 1.0) { + maxGen = (int)(log(NewTemp) / log(temp) * maxGen); + } + temp = NewTemp; /* control variable */ +#ifdef DD_STATS + (void) fprintf(table->out,"uphill = %d\taccepted = %d\n", + tosses,acceptances); + fflush(table->out); +#endif + } + + result = restoreOrder(table,BestOrder,lower,upper); + FREE(BestOrder); + if (!result) return(0); +#ifdef DD_STATS + fprintf(table->out,"#:N_EXCHANGE %8d : total exchanges\n",ecount); + fprintf(table->out,"#:N_JUMPUP %8d : total jumps up\n",ucount); + fprintf(table->out,"#:N_JUMPDOWN %8d : total jumps down",dcount); +#endif + return(1); + +} /* end of cuddAnnealing */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Checks termination condition.] + + Description [If temperature is STOP_TEMP or there is no improvement + then terminates. Returns 1 if the termination criterion is met; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +stopping_criterion( + int c1, + int c2, + int c3, + int c4, + double temp) +{ + if (STOP_TEMP < temp) { + return(0); + } else if ((c1 == c2) && (c1 == c3) && (c1 == c4)) { + return(1); + } else { + return(0); + } + +} /* end of stopping_criterion */ + + +/**Function******************************************************************** + + Synopsis [Random number generator.] + + Description [Returns a double precision value between 0.0 and 1.0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double +random_generator(void) +{ + return((double)(Cudd_Random() / 2147483561.0)); + +} /* end of random_generator */ + + +/**Function******************************************************************** + + Synopsis [This function is for exchanging two variables, x and y.] + + Description [This is the same funcion as ddSwapping except for + comparison expression. Use probability function, exp(-size_change/temp).] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddExchange( + DdManager * table, + int x, + int y, + double temp) +{ + Move *move,*moves; + int tmp; + int x_ref,y_ref; + int x_next,y_next; + int size, result; + int initial_size, limit_size; + + x_ref = x; + y_ref = y; + + x_next = cuddNextHigh(table,x); + y_next = cuddNextLow(table,y); + moves = NULL; + initial_size = limit_size = table->keys - table->isolated; + + for (;;) { + if (x_next == y_next) { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; + x = y; + y = tmp; + } else if (x == y_next) { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + tmp = x; + x = y; + y = tmp; + } else { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + x = x_next; + y = y_next; + } + + x_next = cuddNextHigh(table,x); + y_next = cuddNextLow(table,y); + if (x_next > y_ref) break; + + if ((double) size > DD_MAX_REORDER_GROWTH * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + } + + if (y_next>=x_ref) { + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + } + + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddExchangeOutOfMem; + + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(1); + +ddExchangeOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(0); + +} /* end of ddExchange */ + + +/**Function******************************************************************** + + Synopsis [Moves a variable to a specified position.] + + Description [If x==x_low, it executes jumping_down. If x==x_high, it + executes jumping_up. This funcion is similar to ddSiftingAux. Returns + 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddJumpingAux( + DdManager * table, + int x, + int x_low, + int x_high, + double temp) +{ + Move *move; + Move *moves; /* list of moves */ + int initial_size; + int result; + + initial_size = table->keys - table->isolated; + +#ifdef DD_DEBUG + assert(table->subtables[x].keys > 0); +#endif + + moves = NULL; + + if (cuddNextLow(table,x) < x_low) { + if (cuddNextHigh(table,x) > x_high) return(1); + moves = ddJumpingDown(table,x,x_high,initial_size); + /* after that point x --> x_high unless early termination */ + if (moves == NULL) goto ddJumpingAuxOutOfMem; + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddJumpingAuxOutOfMem; + } else if (cuddNextHigh(table,x) > x_high) { + moves = ddJumpingUp(table,x,x_low,initial_size); + /* after that point x --> x_low unless early termination */ + if (moves == NULL) goto ddJumpingAuxOutOfMem; + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddJumpingAuxOutOfMem; + } else { + (void) fprintf(table->err,"Unexpected condition in ddJumping\n"); + goto ddJumpingAuxOutOfMem; + } + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(1); + +ddJumpingAuxOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(0); + +} /* end of ddJumpingAux */ + + +/**Function******************************************************************** + + Synopsis [This function is for jumping up.] + + Description [This is a simplified version of ddSiftingUp. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +ddJumpingUp( + DdManager * table, + int x, + int x_low, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddNextLow(table,x); + while (y >= x_low) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) goto ddJumpingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddJumpingUpOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > table->maxGrowth * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + x = y; + y = cuddNextLow(table,x); + } + return(moves); + +ddJumpingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of ddJumpingUp */ + + +/**Function******************************************************************** + + Synopsis [This function is for jumping down.] + + Description [This is a simplified version of ddSiftingDown. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +ddJumpingDown( + DdManager * table, + int x, + int x_high, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddNextHigh(table,x); + while (y <= x_high) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddJumpingDownOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddJumpingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > table->maxGrowth * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + x = y; + y = cuddNextHigh(table,x); + } + return(moves); + +ddJumpingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of ddJumpingDown */ + + +/**Function******************************************************************** + + Synopsis [Returns the DD to the best position encountered during + sifting if there was improvement.] + + Description [Otherwise, "tosses a coin" to decide whether to keep + the current configuration or return the DD to the original + one. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +siftBackwardProb( + DdManager * table, + Move * moves, + int size, + double temp) +{ + Move *move; + int res; + int best_size = size; + double coin, threshold; + + /* Look for best size during the last sifting */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < best_size) { + best_size = move->size; + } + } + + /* If best_size equals size, the last sifting did not produce any + ** improvement. We now toss a coin to decide whether to retain + ** this change or not. + */ + if (best_size == size) { + coin = random_generator(); +#ifdef DD_STATS + tosses++; +#endif + threshold = exp(-((double)(table->keys - table->isolated - size))/temp); + if (coin < threshold) { +#ifdef DD_STATS + acceptances++; +#endif + return(1); + } + } + + /* Either there was improvement, or we have decided not to + ** accept the uphill move. Go to best position. + */ + res = table->keys - table->isolated; + for (move = moves; move != NULL; move = move->next) { + if (res == best_size) return(1); + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + + return(1); + +} /* end of sift_backward_prob */ + + +/**Function******************************************************************** + + Synopsis [Copies the current variable order to array.] + + Description [Copies the current variable order to array. + At the same time inverts the permutation.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +copyOrder( + DdManager * table, + int * array, + int lower, + int upper) +{ + int i; + int nvars; + + nvars = upper - lower + 1; + for (i = 0; i < nvars; i++) { + array[i] = table->invperm[i+lower]; + } + +} /* end of copyOrder */ + + +/**Function******************************************************************** + + Synopsis [Restores the variable order in array by a series of sifts up.] + + Description [Restores the variable order in array by a series of sifts up. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +restoreOrder( + DdManager * table, + int * array, + int lower, + int upper) +{ + int i, x, y, size; + int nvars = upper - lower + 1; + + for (i = 0; i < nvars; i++) { + x = table->perm[array[i]]; +#ifdef DD_DEBUG + assert(x >= lower && x <= upper); +#endif + y = cuddNextLow(table,x); + while (y >= i + lower) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) return(0); + x = y; + y = cuddNextLow(table,x); + } + } + + return(1); + +} /* end of restoreOrder */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddApa.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddApa.c new file mode 100644 index 000000000..7c4ff8ce6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddApa.c @@ -0,0 +1,979 @@ +/**CFile*********************************************************************** + + FileName [cuddApa.c] + + PackageName [cudd] + + Synopsis [Arbitrary precision arithmetic functions.] + + Description [External procedures included in this module: +
    +
  • Cudd_ApaNumberOfDigits() +
  • Cudd_NewApaNumber() +
  • Cudd_ApaCopy() +
  • Cudd_ApaAdd() +
  • Cudd_ApaSubtract() +
  • Cudd_ApaShortDivision() +
  • Cudd_ApaIntDivision() +
  • Cudd_ApaShiftRight() +
  • Cudd_ApaSetToLiteral() +
  • Cudd_ApaPowerOfTwo() +
  • Cudd_ApaCompare() +
  • Cudd_ApaCompareRatios() +
  • Cudd_ApaPrintHex() +
  • Cudd_ApaPrintDecimal() +
  • Cudd_ApaPrintExponential() +
  • Cudd_ApaCountMinterm() +
  • Cudd_ApaPrintMinterm() +
  • Cudd_ApaPrintMintermExp() +
  • Cudd_ApaPrintDensity() +
+ Static procedures included in this module: +
    +
  • cuddApaCountMintermAux() +
  • cuddApaStCountfree() +
] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.20 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static DdNode *background, *zero; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdApaNumber cuddApaCountMintermAux (DdNode * node, int digits, DdApaNumber max, DdApaNumber min, st_table * table); +static enum st_retval cuddApaStCountfree (char * key, char * value, char * arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Finds the number of digits for an arbitrary precision + integer.] + + Description [Finds the number of digits for an arbitrary precision + integer given the maximum number of binary digits. The number of + binary digits should be positive. Returns the number of digits if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaNumberOfDigits( + int binaryDigits) +{ + int digits; + + digits = binaryDigits / DD_APA_BITS; + if ((digits * DD_APA_BITS) != binaryDigits) + digits++; + return(digits); + +} /* end of Cudd_ApaNumberOfDigits */ + + +/**Function******************************************************************** + + Synopsis [Allocates memory for an arbitrary precision integer.] + + Description [Allocates memory for an arbitrary precision + integer. Returns a pointer to the allocated memory if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdApaNumber +Cudd_NewApaNumber( + int digits) +{ + return(ALLOC(DdApaDigit, digits)); + +} /* end of Cudd_NewApaNumber */ + + +/**Function******************************************************************** + + Synopsis [Makes a copy of an arbitrary precision integer.] + + Description [Makes a copy of an arbitrary precision integer.] + + SideEffects [Changes parameter dest.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaCopy( + int digits, + DdApaNumber source, + DdApaNumber dest) +{ + int i; + + for (i = 0; i < digits; i++) { + dest[i] = source[i]; + } + +} /* end of Cudd_ApaCopy */ + + +/**Function******************************************************************** + + Synopsis [Adds two arbitrary precision integers.] + + Description [Adds two arbitrary precision integers. Returns the + carry out of the most significant digit.] + + SideEffects [The result of the sum is stored in parameter sum.] + + SeeAlso [] + +******************************************************************************/ +DdApaDigit +Cudd_ApaAdd( + int digits, + DdApaNumber a, + DdApaNumber b, + DdApaNumber sum) +{ + int i; + DdApaDoubleDigit partial = 0; + + for (i = digits - 1; i >= 0; i--) { + partial = a[i] + b[i] + DD_MSDIGIT(partial); + sum[i] = (DdApaDigit) DD_LSDIGIT(partial); + } + return((DdApaDigit) DD_MSDIGIT(partial)); + +} /* end of Cudd_ApaAdd */ + + +/**Function******************************************************************** + + Synopsis [Subtracts two arbitrary precision integers.] + + Description [Subtracts two arbitrary precision integers. Returns the + borrow out of the most significant digit.] + + SideEffects [The result of the subtraction is stored in parameter + diff.] + + SeeAlso [] + +******************************************************************************/ +DdApaDigit +Cudd_ApaSubtract( + int digits, + DdApaNumber a, + DdApaNumber b, + DdApaNumber diff) +{ + int i; + DdApaDoubleDigit partial = DD_APA_BASE; + + for (i = digits - 1; i >= 0; i--) { + partial = DD_MSDIGIT(partial) + DD_APA_MASK + a[i] - b[i]; + diff[i] = (DdApaDigit) DD_LSDIGIT(partial); + } + return((DdApaDigit) DD_MSDIGIT(partial) - 1); + +} /* end of Cudd_ApaSubtract */ + + +/**Function******************************************************************** + + Synopsis [Divides an arbitrary precision integer by a digit.] + + Description [Divides an arbitrary precision integer by a digit.] + + SideEffects [The quotient is returned in parameter quotient.] + + SeeAlso [] + +******************************************************************************/ +DdApaDigit +Cudd_ApaShortDivision( + int digits, + DdApaNumber dividend, + DdApaDigit divisor, + DdApaNumber quotient) +{ + int i; + DdApaDigit remainder; + DdApaDoubleDigit partial; + + remainder = 0; + for (i = 0; i < digits; i++) { + partial = remainder * DD_APA_BASE + dividend[i]; + quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor); + remainder = (DdApaDigit) (partial % divisor); + } + + return(remainder); + +} /* end of Cudd_ApaShortDivision */ + + +/**Function******************************************************************** + + Synopsis [Divides an arbitrary precision integer by an integer.] + + Description [Divides an arbitrary precision integer by a 32-bit + unsigned integer. Returns the remainder of the division. This + procedure relies on the assumption that the number of bits of a + DdApaDigit plus the number of bits of an unsigned int is less the + number of bits of the mantissa of a double. This guarantees that the + product of a DdApaDigit and an unsigned int can be represented + without loss of precision by a double. On machines where this + assumption is not satisfied, this procedure will malfunction.] + + SideEffects [The quotient is returned in parameter quotient.] + + SeeAlso [Cudd_ApaShortDivision] + +******************************************************************************/ +unsigned int +Cudd_ApaIntDivision( + int digits, + DdApaNumber dividend, + unsigned int divisor, + DdApaNumber quotient) +{ + int i; + double partial; + unsigned int remainder = 0; + double ddiv = (double) divisor; + + for (i = 0; i < digits; i++) { + partial = (double) remainder * DD_APA_BASE + dividend[i]; + quotient[i] = (DdApaDigit) (partial / ddiv); + remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv)); + } + + return(remainder); + +} /* end of Cudd_ApaIntDivision */ + + +/**Function******************************************************************** + + Synopsis [Shifts right an arbitrary precision integer by one binary + place.] + + Description [Shifts right an arbitrary precision integer by one + binary place. The most significant binary digit of the result is + taken from parameter in.] + + SideEffects [The result is returned in parameter b.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaShiftRight( + int digits, + DdApaDigit in, + DdApaNumber a, + DdApaNumber b) +{ + int i; + + for (i = digits - 1; i > 0; i--) { + b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1)); + } + b[0] = (a[0] >> 1) | (in << (DD_APA_BITS - 1)); + +} /* end of Cudd_ApaShiftRight */ + + +/**Function******************************************************************** + + Synopsis [Sets an arbitrary precision integer to a one-digit literal.] + + Description [Sets an arbitrary precision integer to a one-digit literal.] + + SideEffects [The result is returned in parameter number.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaSetToLiteral( + int digits, + DdApaNumber number, + DdApaDigit literal) +{ + int i; + + for (i = 0; i < digits - 1; i++) + number[i] = 0; + number[digits - 1] = literal; + +} /* end of Cudd_ApaSetToLiteral */ + + +/**Function******************************************************************** + + Synopsis [Sets an arbitrary precision integer to a power of two.] + + Description [Sets an arbitrary precision integer to a power of + two. If the power of two is too large to be represented, the number + is set to 0.] + + SideEffects [The result is returned in parameter number.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaPowerOfTwo( + int digits, + DdApaNumber number, + int power) +{ + int i; + int index; + + for (i = 0; i < digits; i++) + number[i] = 0; + i = digits - 1 - power / DD_APA_BITS; + if (i < 0) return; + index = power & (DD_APA_BITS - 1); + number[i] = 1 << index; + +} /* end of Cudd_ApaPowerOfTwo */ + + +/**Function******************************************************************** + + Synopsis [Compares two arbitrary precision integers.] + + Description [Compares two arbitrary precision integers. Returns 1 if + the first number is larger; 0 if they are equal; -1 if the second + number is larger.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaCompare( + int digitsFirst, + DdApaNumber first, + int digitsSecond, + DdApaNumber second) +{ + int i; + int firstNZ, secondNZ; + + /* Find first non-zero in both numbers. */ + for (firstNZ = 0; firstNZ < digitsFirst; firstNZ++) + if (first[firstNZ] != 0) break; + for (secondNZ = 0; secondNZ < digitsSecond; secondNZ++) + if (second[secondNZ] != 0) break; + if (digitsFirst - firstNZ > digitsSecond - secondNZ) return(1); + else if (digitsFirst - firstNZ < digitsSecond - secondNZ) return(-1); + for (i = 0; i < digitsFirst - firstNZ; i++) { + if (first[firstNZ + i] > second[secondNZ + i]) return(1); + else if (first[firstNZ + i] < second[secondNZ + i]) return(-1); + } + return(0); + +} /* end of Cudd_ApaCompare */ + + +/**Function******************************************************************** + + Synopsis [Compares the ratios of two arbitrary precision integers to two + unsigned ints.] + + Description [Compares the ratios of two arbitrary precision integers + to two unsigned ints. Returns 1 if the first number is larger; 0 if + they are equal; -1 if the second number is larger.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaCompareRatios( + int digitsFirst, + DdApaNumber firstNum, + unsigned int firstDen, + int digitsSecond, + DdApaNumber secondNum, + unsigned int secondDen) +{ + int result; + DdApaNumber first, second; + unsigned int firstRem, secondRem; + + first = Cudd_NewApaNumber(digitsFirst); + firstRem = Cudd_ApaIntDivision(digitsFirst,firstNum,firstDen,first); + second = Cudd_NewApaNumber(digitsSecond); + secondRem = Cudd_ApaIntDivision(digitsSecond,secondNum,secondDen,second); + result = Cudd_ApaCompare(digitsFirst,first,digitsSecond,second); + FREE(first); + FREE(second); + if (result == 0) { + if ((double)firstRem/firstDen > (double)secondRem/secondDen) + return(1); + else if ((double)firstRem/firstDen < (double)secondRem/secondDen) + return(-1); + } + return(result); + +} /* end of Cudd_ApaCompareRatios */ + + +/**Function******************************************************************** + + Synopsis [Prints an arbitrary precision integer in hexadecimal format.] + + Description [Prints an arbitrary precision integer in hexadecimal format. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintDecimal Cudd_ApaPrintExponential] + +******************************************************************************/ +int +Cudd_ApaPrintHex( + FILE * fp, + int digits, + DdApaNumber number) +{ + int i, result; + + for (i = 0; i < digits; i++) { + result = fprintf(fp,DD_APA_HEXPRINT,number[i]); + if (result == EOF) + return(0); + } + return(1); + +} /* end of Cudd_ApaPrintHex */ + + +/**Function******************************************************************** + + Synopsis [Prints an arbitrary precision integer in decimal format.] + + Description [Prints an arbitrary precision integer in decimal format. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintExponential] + +******************************************************************************/ +int +Cudd_ApaPrintDecimal( + FILE * fp, + int digits, + DdApaNumber number) +{ + int i, result; + DdApaDigit remainder; + DdApaNumber work; + unsigned char *decimal; + int leadingzero; + int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; + + work = Cudd_NewApaNumber(digits); + if (work == NULL) + return(0); + decimal = ALLOC(unsigned char, decimalDigits); + if (decimal == NULL) { + FREE(work); + return(0); + } + Cudd_ApaCopy(digits,number,work); + for (i = decimalDigits - 1; i >= 0; i--) { + remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); + decimal[i] = (unsigned char) remainder; + } + FREE(work); + + leadingzero = 1; + for (i = 0; i < decimalDigits; i++) { + leadingzero = leadingzero && (decimal[i] == 0); + if ((!leadingzero) || (i == (decimalDigits - 1))) { + result = fprintf(fp,"%1d",decimal[i]); + if (result == EOF) { + FREE(decimal); + return(0); + } + } + } + FREE(decimal); + return(1); + +} /* end of Cudd_ApaPrintDecimal */ + + +/**Function******************************************************************** + + Synopsis [Prints an arbitrary precision integer in exponential format.] + + Description [Prints an arbitrary precision integer in exponential format. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintDecimal] + +******************************************************************************/ +int +Cudd_ApaPrintExponential( + FILE * fp, + int digits, + DdApaNumber number, + int precision) +{ + int i, first, last, result; + DdApaDigit remainder; + DdApaNumber work; + unsigned char *decimal; + int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; + + work = Cudd_NewApaNumber(digits); + if (work == NULL) + return(0); + decimal = ALLOC(unsigned char, decimalDigits); + if (decimal == NULL) { + FREE(work); + return(0); + } + Cudd_ApaCopy(digits,number,work); + first = decimalDigits - 1; + for (i = decimalDigits - 1; i >= 0; i--) { + remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); + decimal[i] = (unsigned char) remainder; + if (remainder != 0) first = i; /* keep track of MS non-zero */ + } + FREE(work); + last = ddMin(first + precision, decimalDigits); + + for (i = first; i < last; i++) { + result = fprintf(fp,"%s%1d",i == first+1 ? "." : "", decimal[i]); + if (result == EOF) { + FREE(decimal); + return(0); + } + } + FREE(decimal); + result = fprintf(fp,"e+%d",decimalDigits - first - 1); + if (result == EOF) { + return(0); + } + return(1); + +} /* end of Cudd_ApaPrintExponential */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a DD.] + + Description [Counts the number of minterms of a DD. The function is + assumed to depend on nvars variables. The minterm count is + represented as an arbitrary precision unsigned integer, to allow for + any number of variables CUDD supports. Returns a pointer to the + array representing the number of minterms of the function rooted at + node if successful; NULL otherwise.] + + SideEffects [The number of digits of the result is returned in + parameter digits.] + + SeeAlso [Cudd_CountMinterm] + +******************************************************************************/ +DdApaNumber +Cudd_ApaCountMinterm( + DdManager * manager, + DdNode * node, + int nvars, + int * digits) +{ + DdApaNumber max, min; + st_table *table; + DdApaNumber i,count; + + background = manager->background; + zero = Cudd_Not(manager->one); + + *digits = Cudd_ApaNumberOfDigits(nvars+1); + max = Cudd_NewApaNumber(*digits); + if (max == NULL) { + return(NULL); + } + Cudd_ApaPowerOfTwo(*digits,max,nvars); + min = Cudd_NewApaNumber(*digits); + if (min == NULL) { + FREE(max); + return(NULL); + } + Cudd_ApaSetToLiteral(*digits,min,0); + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) { + FREE(max); + FREE(min); + return(NULL); + } + i = cuddApaCountMintermAux(Cudd_Regular(node),*digits,max,min,table); + if (i == NULL) { + FREE(max); + FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + return(NULL); + } + count = Cudd_NewApaNumber(*digits); + if (count == NULL) { + FREE(max); + FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + if (Cudd_Regular(node)->ref == 1) FREE(i); + return(NULL); + } + if (Cudd_IsComplement(node)) { + (void) Cudd_ApaSubtract(*digits,max,i,count); + } else { + Cudd_ApaCopy(*digits,i,count); + } + FREE(max); + FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + if (Cudd_Regular(node)->ref == 1) FREE(i); + return(count); + +} /* end of Cudd_ApaCountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic.] + + Description [Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintMintermExp] + +******************************************************************************/ +int +Cudd_ApaPrintMinterm( + FILE * fp, + DdManager * dd, + DdNode * node, + int nvars) +{ + int digits; + int result; + DdApaNumber count; + + count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); + if (count == NULL) + return(0); + result = Cudd_ApaPrintDecimal(fp,digits,count); + FREE(count); + if (fprintf(fp,"\n") == EOF) { + return(0); + } + return(result); + +} /* end of Cudd_ApaPrintMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints the number of minterms of a BDD or ADD in exponential + format using arbitrary precision arithmetic.] + + Description [Prints the number of minterms of a BDD or ADD in + exponential format using arbitrary precision arithmetic. Parameter + precision controls the number of signficant digits printed. Returns + 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintMinterm] + +******************************************************************************/ +int +Cudd_ApaPrintMintermExp( + FILE * fp, + DdManager * dd, + DdNode * node, + int nvars, + int precision) +{ + int digits; + int result; + DdApaNumber count; + + count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); + if (count == NULL) + return(0); + result = Cudd_ApaPrintExponential(fp,digits,count,precision); + FREE(count); + if (fprintf(fp,"\n") == EOF) { + return(0); + } + return(result); + +} /* end of Cudd_ApaPrintMintermExp */ + + +/**Function******************************************************************** + + Synopsis [Prints the density of a BDD or ADD using + arbitrary precision arithmetic.] + + Description [Prints the density of a BDD or ADD using + arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaPrintDensity( + FILE * fp, + DdManager * dd, + DdNode * node, + int nvars) +{ + int digits; + int result; + DdApaNumber count,density; + unsigned int size, remainder, fractional; + + count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); + if (count == NULL) + return(0); + size = Cudd_DagSize(node); + density = Cudd_NewApaNumber(digits); + remainder = Cudd_ApaIntDivision(digits,count,size,density); + result = Cudd_ApaPrintDecimal(fp,digits,density); + FREE(count); + FREE(density); + fractional = (unsigned int)((double)remainder / size * 1000000); + if (fprintf(fp,".%u\n", fractional) == EOF) { + return(0); + } + return(result); + +} /* end of Cudd_ApaPrintDensity */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_ApaCountMinterm.] + + Description [Performs the recursive step of Cudd_ApaCountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. + Uses the identity |f'| = max - |f|. + The procedure expects the argument "node" to be a regular pointer, and + guarantees this condition is met in the recursive calls. + For efficiency, the result of a call is cached only if the node has + a reference count greater than 1. + Returns the number of minterms of the function rooted at node.] + + SideEffects [None] + +******************************************************************************/ +static DdApaNumber +cuddApaCountMintermAux( + DdNode * node, + int digits, + DdApaNumber max, + DdApaNumber min, + st_table * table) +{ + DdNode *Nt, *Ne; + DdApaNumber mint, mint1, mint2; + DdApaDigit carryout; + + if (cuddIsConstant(node)) { + if (node == background || node == zero) { + return(min); + } else { + return(max); + } + } + if (node->ref > 1 && st_lookup(table, node, &mint)) { + return(mint); + } + + Nt = cuddT(node); Ne = cuddE(node); + + mint1 = cuddApaCountMintermAux(Nt, digits, max, min, table); + if (mint1 == NULL) return(NULL); + mint2 = cuddApaCountMintermAux(Cudd_Regular(Ne), digits, max, min, table); + if (mint2 == NULL) { + if (Nt->ref == 1) FREE(mint1); + return(NULL); + } + mint = Cudd_NewApaNumber(digits); + if (mint == NULL) { + if (Nt->ref == 1) FREE(mint1); + if (Cudd_Regular(Ne)->ref == 1) FREE(mint2); + return(NULL); + } + if (Cudd_IsComplement(Ne)) { + (void) Cudd_ApaSubtract(digits,max,mint2,mint); + carryout = Cudd_ApaAdd(digits,mint1,mint,mint); + } else { + carryout = Cudd_ApaAdd(digits,mint1,mint2,mint); + } + Cudd_ApaShiftRight(digits,carryout,mint,mint); + /* If the refernce count of a child is 1, its minterm count + ** hasn't been stored in table. Therefore, it must be explicitly + ** freed here. */ + if (Nt->ref == 1) FREE(mint1); + if (Cudd_Regular(Ne)->ref == 1) FREE(mint2); + + if (node->ref > 1) { + if (st_insert(table, (char *)node, (char *)mint) == ST_OUT_OF_MEM) { + FREE(mint); + return(NULL); + } + } + return(mint); + +} /* end of cuddApaCountMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory used to store the minterm counts recorded + in the visited table.] + + Description [Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +cuddApaStCountfree( + char * key, + char * value, + char * arg) +{ + DdApaNumber d; + + d = (DdApaNumber) value; + FREE(d); + return(ST_CONTINUE); + +} /* end of cuddApaStCountfree */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddApprox.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddApprox.c new file mode 100644 index 000000000..23f97415f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddApprox.c @@ -0,0 +1,2204 @@ +/**CFile*********************************************************************** + + FileName [cuddApprox.c] + + PackageName [cudd] + + Synopsis [Procedures to approximate a given BDD.] + + Description [External procedures provided by this module: +
    +
  • Cudd_UnderApprox() +
  • Cudd_OverApprox() +
  • Cudd_RemapUnderApprox() +
  • Cudd_RemapOverApprox() +
  • Cudd_BiasedUnderApprox() +
  • Cudd_BiasedOverApprox() +
+ Internal procedures included in this module: +
    +
  • cuddUnderApprox() +
  • cuddRemapUnderApprox() +
  • cuddBiasedUnderApprox() +
+ Static procedures included in this module: +
    +
  • updateParity() +
  • gatherInfoAux() +
  • gatherInfo() +
  • computeSavings() +
  • updateRefs() +
  • UAmarkNodes() +
  • UAbuildSubset() +
  • RAmarkNodes() +
  • BAmarkNodes() +
  • RAbuildSubset() +
  • BAapplyBias() +
+ ] + + SeeAlso [cuddSubsetHB.c cuddSubsetSP.c cuddGenCof.c] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#ifdef __STDC__ +#include +#else +#define DBL_MAX_EXP 1024 +#endif +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define NOTHING 0 +#define REPLACE_T 1 +#define REPLACE_E 2 +#define REPLACE_N 3 +#define REPLACE_TT 4 +#define REPLACE_TE 5 + +#define DONT_CARE 0 +#define CARE 1 +#define TOTAL_CARE 2 +#define CARE_ERROR 3 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/* Data structure to store the information on each node. It keeps the +** number of minterms of the function rooted at this node in terms of +** the number of variables specified by the user; the number of +** minterms of the complement; the impact of the number of minterms of +** this function on the number of minterms of the root function; the +** reference count of the node from within the root function; the +** flag that says whether the node intersects the care set; the flag +** that says whether the node should be replaced and how; the results +** of subsetting in both phases. */ +typedef struct NodeData { + double mintermsP; /* minterms for the regular node */ + double mintermsN; /* minterms for the complemented node */ + int functionRef; /* references from within this function */ + char care; /* node intersects care set */ + char replace; /* replacement decision */ + short int parity; /* 1: even; 2: odd; 3: both */ + DdNode *resultP; /* result for even parity */ + DdNode *resultN; /* result for odd parity */ +} NodeData; + +typedef struct ApproxInfo { + DdNode *one; /* one constant */ + DdNode *zero; /* BDD zero constant */ + NodeData *page; /* per-node information */ + DdHashTable *table; /* hash table to access the per-node info */ + int index; /* index of the current node */ + double max; /* max number of minterms */ + int size; /* how many nodes are left */ + double minterms; /* how many minterms are left */ +} ApproxInfo; + +/* Item of the queue used in the levelized traversal of the BDD. */ +typedef struct GlobalQueueItem { + struct GlobalQueueItem *next; + struct GlobalQueueItem *cnext; + DdNode *node; + double impactP; + double impactN; +} GlobalQueueItem; + +typedef struct LocalQueueItem { + struct LocalQueueItem *next; + struct LocalQueueItem *cnext; + DdNode *node; + int localRef; +} LocalQueueItem; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddApprox.c,v 1.31 2012/02/05 04:38:07 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void updateParity (DdNode *node, ApproxInfo *info, int newparity); +static NodeData * gatherInfoAux (DdNode *node, ApproxInfo *info, int parity); +static ApproxInfo * gatherInfo (DdManager *dd, DdNode *node, int numVars, int parity); +static int computeSavings (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue); +static int updateRefs (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue); +static int UAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, int safe, double quality); +static DdNode * UAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info); +static int RAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality); +static int BAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality1, double quality0); +static DdNode * RAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info); +static int BAapplyBias (DdManager *dd, DdNode *f, DdNode *b, ApproxInfo *info, DdHashTable *cache); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with Shiple's + underapproximation method.] + + Description [Extracts a dense subset from a BDD. This procedure uses + a variant of Tom Shiple's underapproximation method. The main + difference from the original method is that density is used as cost + function. Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value + returned by Cudd_ReadSize for numVars when the number of variables + is under 1023. If numVars is larger than 1023, it will cause + overflow. If a 0 parameter is passed then the procedure will compute + a value which will avoid overflow but will cause underflow with 2046 + variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_UnderApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddUnderApprox(dd, f, numVars, threshold, safe, quality); + } while (dd->reordered == 1); + + return(subset); + +} /* end of Cudd_UnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with Shiple's + underapproximation method.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the underapproximation procedure except for the fact that it + works on the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_OverApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddUnderApprox(dd, g, numVars, threshold, safe, quality); + } while (dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_OverApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the remapping + underapproximation method.] + + Description [Extracts a dense subset from a BDD. This procedure uses + a remapping technique and density as the cost function. + Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value + returned by Cudd_ReadSize for numVars when the number of variables + is under 1023. If numVars is larger than 1023, it will cause + overflow. If a 0 parameter is passed then the procedure will compute + a value which will avoid overflow but will cause underflow with 2046 + variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_RemapUnderApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddRemapUnderApprox(dd, f, numVars, threshold, quality); + } while (dd->reordered == 1); + + return(subset); + +} /* end of Cudd_RemapUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the remapping + underapproximation method.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the underapproximation procedure except for the fact that it + works on the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_RemapOverApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddRemapUnderApprox(dd, g, numVars, threshold, quality); + } while (dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_RemapOverApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the biased + underapproximation method.] + + Description [Extracts a dense subset from a BDD. This procedure uses + a biased remapping technique and density as the cost function. The bias + is a function. This procedure tries to approximate where the bias is 0 + and preserve the given function where the bias is 1. + Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value + returned by Cudd_ReadSize for numVars when the number of variables + is under 1023. If numVars is larger than 1023, it will cause + overflow. If a 0 parameter is passed then the procedure will compute + a value which will avoid overflow but will cause underflow with 2046 + variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox + Cudd_RemapUnderApprox Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_BiasedUnderApprox( + DdManager *dd /* manager */, + DdNode *f /* function to be subset */, + DdNode *b /* bias function */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality1 /* minimum improvement for accepted changes when b=1 */, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddBiasedUnderApprox(dd, f, b, numVars, threshold, quality1, + quality0); + } while (dd->reordered == 1); + + return(subset); + +} /* end of Cudd_BiasedUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the biased + underapproximation method.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the underapproximation procedure except for the fact that it + works on the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths + Cudd_RemapOverApprox Cudd_BiasedUnderApprox Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_BiasedOverApprox( + DdManager *dd /* manager */, + DdNode *f /* function to be superset */, + DdNode *b /* bias function */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality1 /* minimum improvement for accepted changes when b=1*/, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddBiasedUnderApprox(dd, g, b, numVars, threshold, quality1, + quality0); + } while (dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_BiasedOverApprox */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Applies Tom Shiple's underappoximation algorithm.] + + Description [Applies Tom Shiple's underappoximation algorithm. Proceeds + in three phases: +
    +
  • collect information on each node in the BDD; this is done via DFS. +
  • traverse the BDD in top-down fashion and compute for each node + whether its elimination increases density. +
  • traverse the BDD via DFS and actually perform the elimination. +
+ Returns the approximated BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_UnderApprox] + +******************************************************************************/ +DdNode * +cuddUnderApprox( + DdManager * dd /* DD manager */, + DdNode * f /* current DD */, + int numVars /* maximum number of variables */, + int threshold /* threshold under which approximation stops */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + ApproxInfo *info; + DdNode *subset; + int result; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + return(NULL); + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + /* Create table where node data are accessible via a hash table. */ + info = gatherInfo(dd, f, numVars, safe); + if (info == NULL) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Mark nodes that should be replaced by zero. */ + result = UAmarkNodes(dd, f, info, threshold, safe, quality); + if (result == 0) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Build the result. */ + subset = UAbuildSubset(dd, f, info); +#if 1 + if (subset && info->size < Cudd_DagSize(subset)) + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); +#endif + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + +#ifdef DD_DEBUG + if (subset != NULL) { + cuddRef(subset); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + } + cuddDeref(subset); + } +#endif + return(subset); + +} /* end of cuddUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Applies the remapping underappoximation algorithm.] + + Description [Applies the remapping underappoximation algorithm. + Proceeds in three phases: +
    +
  • collect information on each node in the BDD; this is done via DFS. +
  • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
  • traverse the BDD via DFS and actually perform the elimination. +
+ Returns the approximated BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_RemapUnderApprox] + +******************************************************************************/ +DdNode * +cuddRemapUnderApprox( + DdManager * dd /* DD manager */, + DdNode * f /* current DD */, + int numVars /* maximum number of variables */, + int threshold /* threshold under which approximation stops */, + double quality /* minimum improvement for accepted changes */) +{ + ApproxInfo *info; + DdNode *subset; + int result; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + /* Create table where node data are accessible via a hash table. */ + info = gatherInfo(dd, f, numVars, CUDD_TRUE); + if (info == NULL) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Mark nodes that should be replaced by zero. */ + result = RAmarkNodes(dd, f, info, threshold, quality); + if (result == 0) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Build the result. */ + subset = RAbuildSubset(dd, f, info); +#if 1 + if (subset && info->size < Cudd_DagSize(subset)) + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); +#endif + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + +#ifdef DD_DEBUG + if (subset != NULL) { + cuddRef(subset); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + } + cuddDeref(subset); + dd->errorCode = CUDD_INTERNAL_ERROR; + } +#endif + return(subset); + +} /* end of cuddRemapUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Applies the biased remapping underappoximation algorithm.] + + Description [Applies the biased remapping underappoximation algorithm. + Proceeds in three phases: +
    +
  • collect information on each node in the BDD; this is done via DFS. +
  • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
  • traverse the BDD via DFS and actually perform the elimination. +
+ Returns the approximated BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_BiasedUnderApprox] + +******************************************************************************/ +DdNode * +cuddBiasedUnderApprox( + DdManager *dd /* DD manager */, + DdNode *f /* current DD */, + DdNode *b /* bias function */, + int numVars /* maximum number of variables */, + int threshold /* threshold under which approximation stops */, + double quality1 /* minimum improvement for accepted changes when b=1 */, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + ApproxInfo *info; + DdNode *subset; + int result; + DdHashTable *cache; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + /* Create table where node data are accessible via a hash table. */ + info = gatherInfo(dd, f, numVars, CUDD_TRUE); + if (info == NULL) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + cache = cuddHashTableInit(dd,2,2); + result = BAapplyBias(dd, Cudd_Regular(f), b, info, cache); + if (result == CARE_ERROR) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + cuddHashTableQuit(cache); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + cuddHashTableQuit(cache); + + /* Mark nodes that should be replaced by zero. */ + result = BAmarkNodes(dd, f, info, threshold, quality1, quality0); + if (result == 0) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Build the result. */ + subset = RAbuildSubset(dd, f, info); +#if 1 + if (subset && info->size < Cudd_DagSize(subset)) + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); +#endif + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + +#ifdef DD_DEBUG + if (subset != NULL) { + cuddRef(subset); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + } + cuddDeref(subset); + dd->errorCode = CUDD_INTERNAL_ERROR; + } +#endif + return(subset); + +} /* end of cuddBiasedUnderApprox */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Recursively update the parity of the paths reaching a node.] + + Description [Recursively update the parity of the paths reaching a node. + Assumes that node is regular and propagates the invariant.] + + SideEffects [None] + + SeeAlso [gatherInfoAux] + +******************************************************************************/ +static void +updateParity( + DdNode * node /* function to analyze */, + ApproxInfo * info /* info on BDD */, + int newparity /* new parity for node */) +{ + NodeData *infoN; + DdNode *E; + + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node)) == NULL) + return; + if ((infoN->parity & newparity) != 0) return; + infoN->parity |= (short) newparity; + if (Cudd_IsConstant(node)) return; + updateParity(cuddT(node),info,newparity); + E = cuddE(node); + if (Cudd_IsComplement(E)) { + updateParity(Cudd_Not(E),info,3-newparity); + } else { + updateParity(E,info,newparity); + } + return; + +} /* end of updateParity */ + + +/**Function******************************************************************** + + Synopsis [Recursively counts minterms and computes reference counts + of each node in the BDD.] + + Description [Recursively counts minterms and computes reference + counts of each node in the BDD. Similar to the cuddCountMintermAux + which recursively counts the number of minterms for the dag rooted + at each node in terms of the total number of variables (max). It assumes + that the node pointer passed to it is regular and it maintains the + invariant.] + + SideEffects [None] + + SeeAlso [gatherInfo] + +******************************************************************************/ +static NodeData * +gatherInfoAux( + DdNode * node /* function to analyze */, + ApproxInfo * info /* info on BDD */, + int parity /* gather parity information */) +{ + DdNode *N, *Nt, *Ne; + NodeData *infoN, *infoT, *infoE; + + N = Cudd_Regular(node); + + /* Check whether entry for this node exists. */ + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, N)) != NULL) { + if (parity) { + /* Update parity and propagate. */ + updateParity(N, info, 1 + (int) Cudd_IsComplement(node)); + } + return(infoN); + } + + /* Compute the cofactors. */ + Nt = Cudd_NotCond(cuddT(N), N != node); + Ne = Cudd_NotCond(cuddE(N), N != node); + + infoT = gatherInfoAux(Nt, info, parity); + if (infoT == NULL) return(NULL); + infoE = gatherInfoAux(Ne, info, parity); + if (infoE == NULL) return(NULL); + + infoT->functionRef++; + infoE->functionRef++; + + /* Point to the correct location in the page. */ + infoN = &(info->page[info->index++]); + infoN->parity |= (short) (1 + Cudd_IsComplement(node)); + + infoN->mintermsP = infoT->mintermsP/2; + infoN->mintermsN = infoT->mintermsN/2; + if (Cudd_IsComplement(Ne) ^ Cudd_IsComplement(node)) { + infoN->mintermsP += infoE->mintermsN/2; + infoN->mintermsN += infoE->mintermsP/2; + } else { + infoN->mintermsP += infoE->mintermsP/2; + infoN->mintermsN += infoE->mintermsN/2; + } + + /* Insert entry for the node in the table. */ + if (cuddHashTableGenericInsert(info->table, N, infoN) == 0) { + return(NULL); + } + return(infoN); + +} /* end of gatherInfoAux */ + + +/**Function******************************************************************** + + Synopsis [Gathers information about each node.] + + Description [Counts minterms and computes reference counts of each + node in the BDD. The minterm count is separately computed for the + node and its complement. This is to avoid cancellation + errors. Returns a pointer to the data structure holding the + information gathered if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddUnderApprox gatherInfoAux] + +******************************************************************************/ +static ApproxInfo * +gatherInfo( + DdManager * dd /* manager */, + DdNode * node /* function to be analyzed */, + int numVars /* number of variables node depends on */, + int parity /* gather parity information */) +{ + ApproxInfo * info; + NodeData * infoTop; + + /* If user did not give numVars value, set it to the maximum + ** exponent that the pow function can take. The -1 is due to the + ** discrepancy in the value that pow takes and the value that + ** log gives. + */ + if (numVars == 0) { + numVars = DBL_MAX_EXP - 1; + } + + info = ALLOC(ApproxInfo,1); + if (info == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + info->max = pow(2.0,(double) numVars); + info->one = DD_ONE(dd); + info->zero = Cudd_Not(info->one); + info->size = Cudd_DagSize(node); + /* All the information gathered will be stored in a contiguous + ** piece of memory, which is allocated here. This can be done + ** efficiently because we have counted the number of nodes of the + ** BDD. info->index points to the next available entry in the array + ** that stores the per-node information. */ + info->page = ALLOC(NodeData,info->size); + if (info->page == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(info); + return(NULL); + } + memset(info->page, 0, info->size * sizeof(NodeData)); /* clear all page */ + info->table = cuddHashTableInit(dd,1,info->size); + if (info->table == NULL) { + FREE(info->page); + FREE(info); + return(NULL); + } + /* We visit the DAG in post-order DFS. Hence, the constant node is + ** in first position, and the root of the DAG is in last position. */ + + /* Info for the constant node: Initialize only fields different from 0. */ + if (cuddHashTableGenericInsert(info->table, info->one, info->page) == 0) { + FREE(info->page); + FREE(info); + cuddHashTableGenericQuit(info->table); + return(NULL); + } + info->page[0].mintermsP = info->max; + info->index = 1; + + infoTop = gatherInfoAux(node,info,parity); + if (infoTop == NULL) { + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + return(NULL); + } + if (Cudd_IsComplement(node)) { + info->minterms = infoTop->mintermsN; + } else { + info->minterms = infoTop->mintermsP; + } + + infoTop->functionRef = 1; + return(info); + +} /* end of gatherInfo */ + + +/**Function******************************************************************** + + Synopsis [Counts the nodes that would be eliminated if a given node + were replaced by zero.] + + Description [Counts the nodes that would be eliminated if a given + node were replaced by zero. This procedure uses a queue passed by + the caller for efficiency: since the queue is left empty at the + endof the search, it can be reused as is by the next search. Returns + the count (always striclty positive) if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [UAmarkNodes RAmarkNodes BAmarkNodes] + +******************************************************************************/ +static int +computeSavings( + DdManager * dd, + DdNode * f, + DdNode * skip, + ApproxInfo * info, + DdLevelQueue * queue) +{ + NodeData *infoN; + LocalQueueItem *item; + DdNode *node; + int savings = 0; + + node = Cudd_Regular(f); + skip = Cudd_Regular(skip); + /* Insert the given node in the level queue. Its local reference + ** count is set equal to the function reference count so that the + ** search will continue from it when it is retrieved. */ + item = (LocalQueueItem *) + cuddLevelQueueFirst(queue,node,cuddI(dd,node->index)); + if (item == NULL) + return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node); + item->localRef = infoN->functionRef; + + /* Process the queue. */ + while ((item = (LocalQueueItem *) queue->first) != NULL) { + node = item->node; + if (node != skip) { + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,node); + if (item->localRef == infoN->functionRef) { + /* This node is not shared. */ + DdNode *nodeT, *nodeE; + savings++; + nodeT = cuddT(node); + if (!cuddIsConstant(nodeT)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeT,cuddI(dd,nodeT->index)); + if (item == NULL) return(0); + item->localRef++; + } + nodeE = Cudd_Regular(cuddE(node)); + if (!cuddIsConstant(nodeE)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeE,cuddI(dd,nodeE->index)); + if (item == NULL) return(0); + item->localRef++; + } + } + } + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + } + +#ifdef DD_DEBUG + /* At the end of a local search the queue should be empty. */ + assert(queue->size == 0); +#endif + return(savings); + +} /* end of computeSavings */ + + +/**Function******************************************************************** + + Synopsis [Update function reference counts.] + + Description [Update function reference counts to account for replacement. + Returns the number of nodes saved if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [UAmarkNodes RAmarkNodes BAmarkNodes] + +******************************************************************************/ +static int +updateRefs( + DdManager * dd, + DdNode * f, + DdNode * skip, + ApproxInfo * info, + DdLevelQueue * queue) +{ + NodeData *infoN; + LocalQueueItem *item; + DdNode *node; + int savings = 0; + + node = Cudd_Regular(f); + /* Insert the given node in the level queue. Its function reference + ** count is set equal to 0 so that the search will continue from it + ** when it is retrieved. */ + item = (LocalQueueItem *) cuddLevelQueueFirst(queue,node,cuddI(dd,node->index)); + if (item == NULL) + return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node); + infoN->functionRef = 0; + + if (skip != NULL) { + /* Increase the function reference count of the node to be skipped + ** by 1 to account for the node pointing to it that will be created. */ + skip = Cudd_Regular(skip); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, skip); + infoN->functionRef++; + } + + /* Process the queue. */ + while ((item = (LocalQueueItem *) queue->first) != NULL) { + node = item->node; + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,node); + if (infoN->functionRef == 0) { + /* This node is not shared or to be be skipped. */ + DdNode *nodeT, *nodeE; + savings++; + nodeT = cuddT(node); + if (!cuddIsConstant(nodeT)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeT,cuddI(dd,nodeT->index)); + if (item == NULL) return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,nodeT); + infoN->functionRef--; + } + nodeE = Cudd_Regular(cuddE(node)); + if (!cuddIsConstant(nodeE)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeE,cuddI(dd,nodeE->index)); + if (item == NULL) return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,nodeE); + infoN->functionRef--; + } + } + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + } + +#ifdef DD_DEBUG + /* At the end of a local search the queue should be empty. */ + assert(queue->size == 0); +#endif + return(savings); + +} /* end of updateRefs */ + + +/**Function******************************************************************** + + Synopsis [Marks nodes for replacement by zero.] + + Description [Marks nodes for replacement by zero. Returns 1 if successful; + 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddUnderApprox] + +******************************************************************************/ +static int +UAmarkNodes( + DdManager * dd /* manager */, + DdNode * f /* function to be analyzed */, + ApproxInfo * info /* info on BDD */, + int threshold /* when to stop approximating */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdLevelQueue *queue; + DdLevelQueue *localQueue; + NodeData *infoN; + GlobalQueueItem *item; + DdNode *node; + double numOnset; + double impactP, impactN; + int savings; + +#if 0 + (void) printf("initial size = %d initial minterms = %g\n", + info->size, info->minterms); +#endif + queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); + if (queue == NULL) { + return(0); + } + localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), + dd->initSlots); + if (localQueue == NULL) { + cuddLevelQueueQuit(queue); + return(0); + } + node = Cudd_Regular(f); + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + if (item == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + if (Cudd_IsComplement(f)) { + item->impactP = 0.0; + item->impactN = 1.0; + } else { + item->impactP = 1.0; + item->impactN = 0.0; + } + while (queue->first != NULL) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; + node = Cudd_Regular(node); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node); + if (safe && infoN->parity == 3) { + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + impactP = item->impactP; + impactN = item->impactN; + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,NULL,info,localQueue); + if (savings == 0) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); +#if 0 + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); +#endif + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = CUDD_TRUE; + info->size -= savings; + info->minterms -=numOnset; +#if 0 + (void) printf("replace: new size = %d new minterms = %g\n", + info->size, info->minterms); +#endif + savings -= updateRefs(dd,node,NULL,info,localQueue); + assert(savings == 0); + continue; + } + if (!cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + if (!Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(1); + +} /* end of UAmarkNodes */ + + +/**Function******************************************************************** + + Synopsis [Builds the subset BDD.] + + Description [Builds the subset BDD. Based on the info table, + replaces selected nodes by zero. Returns a pointer to the result if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddUnderApprox] + +******************************************************************************/ +static DdNode * +UAbuildSubset( + DdManager * dd /* DD manager */, + DdNode * node /* current node */, + ApproxInfo * info /* node info */) +{ + + DdNode *Nt, *Ne, *N, *t, *e, *r; + NodeData *infoN; + + if (Cudd_IsConstant(node)) + return(node); + + N = Cudd_Regular(node); + + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, N)) != NULL) { + if (infoN->replace == CUDD_TRUE) { + return(info->zero); + } + if (N == node ) { + if (infoN->resultP != NULL) { + return(infoN->resultP); + } + } else { + if (infoN->resultN != NULL) { + return(infoN->resultN); + } + } + } else { + (void) fprintf(dd->err, + "Something is wrong, ought to be in info table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node)); + Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node)); + + t = UAbuildSubset(dd, Nt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + + e = UAbuildSubset(dd, Ne, info); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + if (N == node) { + infoN->resultP = r; + } else { + infoN->resultN = r; + } + + return(r); + +} /* end of UAbuildSubset */ + + +/**Function******************************************************************** + + Synopsis [Marks nodes for remapping.] + + Description [Marks nodes for remapping. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddRemapUnderApprox] + +******************************************************************************/ +static int +RAmarkNodes( + DdManager * dd /* manager */, + DdNode * f /* function to be analyzed */, + ApproxInfo * info /* info on BDD */, + int threshold /* when to stop approximating */, + double quality /* minimum improvement for accepted changes */) +{ + DdLevelQueue *queue; + DdLevelQueue *localQueue; + NodeData *infoN, *infoT, *infoE; + GlobalQueueItem *item; + DdNode *node, *T, *E; + DdNode *shared; /* grandchild shared by the two children of node */ + double numOnset; + double impact, impactP, impactN; + double minterms; + int savings; + int replace; + +#if 0 + (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n", + info->size, info->minterms); +#endif + queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); + if (queue == NULL) { + return(0); + } + localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), + dd->initSlots); + if (localQueue == NULL) { + cuddLevelQueueQuit(queue); + return(0); + } + /* Enqueue regular pointer to root and initialize impact. */ + node = Cudd_Regular(f); + item = (GlobalQueueItem *) + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + if (item == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + if (Cudd_IsComplement(f)) { + item->impactP = 0.0; + item->impactN = 1.0; + } else { + item->impactP = 1.0; + item->impactN = 0.0; + } + /* The nodes retrieved here are guaranteed to be non-terminal. + ** The initial node is not terminal because constant nodes are + ** dealt with in the calling procedure. Subsequent nodes are inserted + ** only if they are not terminal. */ + while ((item = (GlobalQueueItem *) queue->first) != NULL) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + node = item->node; +#ifdef DD_DEBUG + assert(item->impactP >= 0 && item->impactP <= 1.0); + assert(item->impactN >= 0 && item->impactN <= 1.0); + assert(!Cudd_IsComplement(node)); + assert(!Cudd_IsConstant(node)); +#endif + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node)) == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } +#ifdef DD_DEBUG + assert(infoN->parity >= 1 && infoN->parity <= 3); +#endif + if (infoN->parity == 3) { + /* This node can be reached through paths of different parity. + ** It is not safe to replace it, because remapping will give + ** an incorrect result, while replacement by 0 may cause node + ** splitting. */ + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + T = cuddT(node); + E = cuddE(node); + shared = NULL; + impactP = item->impactP; + impactN = item->impactN; + if (Cudd_bddLeq(dd,T,E)) { + /* Here we know that E is regular. */ +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(E)); +#endif + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, E); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; + if (infoE->functionRef == 1 && !cuddIsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; + if (infoT->functionRef == 1 && !cuddIsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } + numOnset = impact * minterms; + } else if (Cudd_bddLeq(dd,E,T)) { + /* Here E may be complemented. */ + DdNode *Ereg = Cudd_Regular(E); + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, Ereg); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoT->mintermsP/2.0 - + ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; + if (infoT->functionRef == 1 && !cuddIsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = ((E == Ereg) ? infoE->mintermsN : + infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; + if (infoE->functionRef == 1 && !cuddIsConstant(Ereg)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } + numOnset = impact * minterms; + } else { + DdNode *Ereg = Cudd_Regular(E); + DdNode *TT = cuddT(T); + DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TT == ET) { + shared = TT; + replace = REPLACE_TT; + } else { + DdNode *TE = cuddE(T); + DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TE == EE) { + shared = TE; + replace = REPLACE_TE; + } else { + replace = REPLACE_N; + } + } + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,shared,info,localQueue); + if (shared != NULL) { + NodeData *infoS; + infoS = (NodeData *) cuddHashTableGenericLookup(info->table, Cudd_Regular(shared)); + if (Cudd_IsComplement(shared)) { + numOnset -= (infoS->mintermsN * impactP + + infoS->mintermsP * impactN)/2.0; + } else { + numOnset -= (infoS->mintermsP * impactP + + infoS->mintermsN * impactN)/2.0; + } + savings--; + } + } + + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); +#if 0 + if (replace == REPLACE_T || replace == REPLACE_E) + (void) printf("node %p: impact = %g numOnset = %g savings %d\n", + node, impact, numOnset, savings); + else + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); +#endif + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = (char) replace; + info->size -= savings; + info->minterms -=numOnset; +#if 0 + (void) printf("remap(%d): new size = %d new minterms = %g\n", + replace, info->size, info->minterms); +#endif + if (replace == REPLACE_N) { + savings -= updateRefs(dd,node,NULL,info,localQueue); + } else if (replace == REPLACE_T) { + savings -= updateRefs(dd,node,E,info,localQueue); + } else if (replace == REPLACE_E) { + savings -= updateRefs(dd,node,T,info,localQueue); + } else { +#ifdef DD_DEBUG + assert(replace == REPLACE_TT || replace == REPLACE_TE); +#endif + savings -= updateRefs(dd,node,shared,info,localQueue) - 1; + } + assert(savings == 0); + } else { + replace = NOTHING; + } + if (replace == REPLACE_N) continue; + if ((replace == REPLACE_E || replace == NOTHING) && + !cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (replace == REPLACE_E) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + if ((replace == REPLACE_T || replace == NOTHING) && + !Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + if ((replace == REPLACE_TT || replace == REPLACE_TE) && + !Cudd_IsConstant(shared)) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), + cuddI(dd,Cudd_Regular(shared)->index)); + if (Cudd_IsComplement(shared)) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactP; + item->impactN += impactN; + } + } + } + + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(1); + +} /* end of RAmarkNodes */ + + +/**Function******************************************************************** + + Synopsis [Marks nodes for remapping.] + + Description [Marks nodes for remapping. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddBiasedUnderApprox] + +******************************************************************************/ +static int +BAmarkNodes( + DdManager *dd /* manager */, + DdNode *f /* function to be analyzed */, + ApproxInfo *info /* info on BDD */, + int threshold /* when to stop approximating */, + double quality1 /* minimum improvement for accepted changes when b=1 */, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + DdLevelQueue *queue; + DdLevelQueue *localQueue; + NodeData *infoN, *infoT, *infoE; + GlobalQueueItem *item; + DdNode *node, *T, *E; + DdNode *shared; /* grandchild shared by the two children of node */ + double numOnset; + double impact, impactP, impactN; + double minterms; + double quality; + int savings; + int replace; + +#if 0 + (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n", + info->size, info->minterms); +#endif + queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); + if (queue == NULL) { + return(0); + } + localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), + dd->initSlots); + if (localQueue == NULL) { + cuddLevelQueueQuit(queue); + return(0); + } + /* Enqueue regular pointer to root and initialize impact. */ + node = Cudd_Regular(f); + item = (GlobalQueueItem *) + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + if (item == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + if (Cudd_IsComplement(f)) { + item->impactP = 0.0; + item->impactN = 1.0; + } else { + item->impactP = 1.0; + item->impactN = 0.0; + } + /* The nodes retrieved here are guaranteed to be non-terminal. + ** The initial node is not terminal because constant nodes are + ** dealt with in the calling procedure. Subsequent nodes are inserted + ** only if they are not terminal. */ + while (queue->first != NULL) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; +#ifdef DD_DEBUG + assert(item->impactP >= 0 && item->impactP <= 1.0); + assert(item->impactN >= 0 && item->impactN <= 1.0); + assert(!Cudd_IsComplement(node)); + assert(!Cudd_IsConstant(node)); +#endif + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node)) == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + quality = infoN->care ? quality1 : quality0; +#ifdef DD_DEBUG + assert(infoN->parity >= 1 && infoN->parity <= 3); +#endif + if (infoN->parity == 3) { + /* This node can be reached through paths of different parity. + ** It is not safe to replace it, because remapping will give + ** an incorrect result, while replacement by 0 may cause node + ** splitting. */ + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + T = cuddT(node); + E = cuddE(node); + shared = NULL; + impactP = item->impactP; + impactN = item->impactN; + if (Cudd_bddLeq(dd,T,E)) { + /* Here we know that E is regular. */ +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(E)); +#endif + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, E); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } + numOnset = impact * minterms; + } else if (Cudd_bddLeq(dd,E,T)) { + /* Here E may be complemented. */ + DdNode *Ereg = Cudd_Regular(E); + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, Ereg); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoT->mintermsP/2.0 - + ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = ((E == Ereg) ? infoE->mintermsN : + infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } + numOnset = impact * minterms; + } else { + DdNode *Ereg = Cudd_Regular(E); + DdNode *TT = cuddT(T); + DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TT == ET) { + shared = TT; + replace = REPLACE_TT; + } else { + DdNode *TE = cuddE(T); + DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TE == EE) { + shared = TE; + replace = REPLACE_TE; + } else { + replace = REPLACE_N; + } + } + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,shared,info,localQueue); + if (shared != NULL) { + NodeData *infoS; + infoS = (NodeData *) cuddHashTableGenericLookup(info->table, Cudd_Regular(shared)); + if (Cudd_IsComplement(shared)) { + numOnset -= (infoS->mintermsN * impactP + + infoS->mintermsP * impactN)/2.0; + } else { + numOnset -= (infoS->mintermsP * impactP + + infoS->mintermsN * impactN)/2.0; + } + savings--; + } + } + + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); +#if 0 + if (replace == REPLACE_T || replace == REPLACE_E) + (void) printf("node %p: impact = %g numOnset = %g savings %d\n", + node, impact, numOnset, savings); + else + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); +#endif + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = (char) replace; + info->size -= savings; + info->minterms -=numOnset; +#if 0 + (void) printf("remap(%d): new size = %d new minterms = %g\n", + replace, info->size, info->minterms); +#endif + if (replace == REPLACE_N) { + savings -= updateRefs(dd,node,NULL,info,localQueue); + } else if (replace == REPLACE_T) { + savings -= updateRefs(dd,node,E,info,localQueue); + } else if (replace == REPLACE_E) { + savings -= updateRefs(dd,node,T,info,localQueue); + } else { +#ifdef DD_DEBUG + assert(replace == REPLACE_TT || replace == REPLACE_TE); +#endif + savings -= updateRefs(dd,node,shared,info,localQueue) - 1; + } + assert(savings == 0); + } else { + replace = NOTHING; + } + if (replace == REPLACE_N) continue; + if ((replace == REPLACE_E || replace == NOTHING) && + !cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (replace == REPLACE_E) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + if ((replace == REPLACE_T || replace == NOTHING) && + !Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + if ((replace == REPLACE_TT || replace == REPLACE_TE) && + !Cudd_IsConstant(shared)) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), + cuddI(dd,Cudd_Regular(shared)->index)); + if (Cudd_IsComplement(shared)) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + } + + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(1); + +} /* end of BAmarkNodes */ + + +/**Function******************************************************************** + + Synopsis [Builds the subset BDD for cuddRemapUnderApprox.] + + Description [Builds the subset BDDfor cuddRemapUnderApprox. Based + on the info table, performs remapping or replacement at selected + nodes. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [cuddRemapUnderApprox] + +******************************************************************************/ +static DdNode * +RAbuildSubset( + DdManager * dd /* DD manager */, + DdNode * node /* current node */, + ApproxInfo * info /* node info */) +{ + DdNode *Nt, *Ne, *N, *t, *e, *r; + NodeData *infoN; + + if (Cudd_IsConstant(node)) + return(node); + + N = Cudd_Regular(node); + + Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node)); + Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node)); + + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, N)) != NULL) { + if (N == node ) { + if (infoN->resultP != NULL) { + return(infoN->resultP); + } + } else { + if (infoN->resultN != NULL) { + return(infoN->resultN); + } + } + if (infoN->replace == REPLACE_T) { + r = RAbuildSubset(dd, Ne, info); + return(r); + } else if (infoN->replace == REPLACE_E) { + r = RAbuildSubset(dd, Nt, info); + return(r); + } else if (infoN->replace == REPLACE_N) { + return(info->zero); + } else if (infoN->replace == REPLACE_TT) { + DdNode *Ntt = Cudd_NotCond(cuddT(cuddT(N)), + Cudd_IsComplement(node)); + int index = cuddT(N)->index; + e = info->zero; + t = RAbuildSubset(dd, Ntt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + return(r); + } else if (infoN->replace == REPLACE_TE) { + DdNode *Nte = Cudd_NotCond(cuddE(cuddT(N)), + Cudd_IsComplement(node)); + int index = cuddT(N)->index; + t = info->one; + e = RAbuildSubset(dd, Nte, info); + if (e == NULL) { + return(NULL); + } + cuddRef(e); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + r =Cudd_Not(r); + cuddDeref(e); + return(r); + } + } else { + (void) fprintf(dd->err, + "Something is wrong, ought to be in info table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + t = RAbuildSubset(dd, Nt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + + e = RAbuildSubset(dd, Ne, info); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + if (N == node) { + infoN->resultP = r; + } else { + infoN->resultN = r; + } + + return(r); + +} /* end of RAbuildSubset */ + + +/**Function******************************************************************** + + Synopsis [Finds don't care nodes.] + + Description [Finds don't care nodes by traversing f and b in parallel. + Returns the care status of the visited f node if successful; CARE_ERROR + otherwise.] + + SideEffects [None] + + SeeAlso [cuddBiasedUnderApprox] + +******************************************************************************/ +static int +BAapplyBias( + DdManager *dd, + DdNode *f, + DdNode *b, + ApproxInfo *info, + DdHashTable *cache) +{ + DdNode *one, *zero, *res; + DdNode *Ft, *Fe, *B, *Bt, *Be; + unsigned int topf, topb; + NodeData *infoF; + int careT, careE; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + if ((infoF = (NodeData *) cuddHashTableGenericLookup(info->table, f)) == NULL) + return(CARE_ERROR); + if (f == one) return(TOTAL_CARE); + if (b == zero) return(infoF->care); + if (infoF->care == TOTAL_CARE) return(TOTAL_CARE); + + if ((f->ref != 1 || Cudd_Regular(b)->ref != 1) && + (res = cuddHashTableLookup2(cache,f,b)) != NULL) { + if (res->ref == 0) { + cache->manager->dead++; + cache->manager->constants.dead++; + } + return(infoF->care); + } + + topf = dd->perm[f->index]; + B = Cudd_Regular(b); + topb = cuddI(dd,B->index); + if (topf <= topb) { + Ft = cuddT(f); Fe = cuddE(f); + } else { + Ft = Fe = f; + } + if (topb <= topf) { + /* We know that b is not constant because f is not. */ + Bt = cuddT(B); Be = cuddE(B); + if (Cudd_IsComplement(b)) { + Bt = Cudd_Not(Bt); + Be = Cudd_Not(Be); + } + } else { + Bt = Be = b; + } + + careT = BAapplyBias(dd, Ft, Bt, info, cache); + if (careT == CARE_ERROR) + return(CARE_ERROR); + careE = BAapplyBias(dd, Cudd_Regular(Fe), Be, info, cache); + if (careE == CARE_ERROR) + return(CARE_ERROR); + if (careT == TOTAL_CARE && careE == TOTAL_CARE) { + infoF->care = TOTAL_CARE; + } else { + infoF->care = CARE; + } + + if (f->ref != 1 || Cudd_Regular(b)->ref != 1) { + ptrint fanout = (ptrint) f->ref * Cudd_Regular(b)->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert2(cache,f,b,one,fanout)) { + return(CARE_ERROR); + } + } + return(infoF->care); + +} /* end of BAapplyBias */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddBddAbs.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddBddAbs.c new file mode 100644 index 000000000..a806078c5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddBddAbs.c @@ -0,0 +1,760 @@ +/**CFile*********************************************************************** + + FileName [cuddBddAbs.c] + + PackageName [cudd] + + Synopsis [Quantification functions for BDDs.] + + Description [External procedures included in this module: +
    +
  • Cudd_bddExistAbstract() +
  • Cudd_bddExistAbstractLimit() +
  • Cudd_bddXorExistAbstract() +
  • Cudd_bddUnivAbstract() +
  • Cudd_bddBooleanDiff() +
  • Cudd_bddVarIsDependent() +
+ Internal procedures included in this module: +
    +
  • cuddBddExistAbstractRecur() +
  • cuddBddXorExistAbstractRecur() +
  • cuddBddBooleanDiffRecur() +
+ Static procedures included in this module: +
    +
  • bddCheckPositiveCube() +
+ ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.28 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int bddCheckPositiveCube (DdManager *manager, DdNode *cube); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Existentially abstracts all the variables in cube from f.] + + Description [Existentially abstracts all the variables in cube from f. + Returns the abstracted BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddUnivAbstract Cudd_addExistAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddExistAbstract */ + + +/**Function******************************************************************** + + Synopsis [Existentially abstracts all the variables in cube from f.] + + Description [Existentially abstracts all the variables in cube from f. + Returns the abstracted BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddExistAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddExistAbstractLimit( + DdManager * manager, + DdNode * f, + DdNode * cube, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = manager->maxLive; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + manager->maxLive = (manager->keys - manager->dead) + + (manager->keysZ - manager->deadZ) + limit; + do { + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + manager->maxLive = saveLimit; + + return(res); + +} /* end of Cudd_bddExistAbstractLimit */ + + +/**Function******************************************************************** + + Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the exclusive OR of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddUnivAbstract Cudd_bddExistAbstract Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddXorExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *res; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddBddXorExistAbstractRecur(manager, f, g, cube); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddXorExistAbstract */ + + +/**Function******************************************************************** + + Synopsis [Universally abstracts all the variables in cube from f.] + + Description [Universally abstracts all the variables in cube from f. + Returns the abstracted BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddExistAbstract Cudd_addUnivAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddUnivAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube); + } while (manager->reordered == 1); + if (res != NULL) res = Cudd_Not(res); + + return(res); + +} /* end of Cudd_bddUnivAbstract */ + + +/**Function******************************************************************** + + Synopsis [Computes the boolean difference of f with respect to x.] + + Description [Computes the boolean difference of f with respect to the + variable with index x. Returns the BDD of the boolean difference if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_bddBooleanDiff( + DdManager * manager, + DdNode * f, + int x) +{ + DdNode *res, *var; + + /* If the variable is not currently in the manager, f cannot + ** depend on it. + */ + if (x >= manager->size) return(Cudd_Not(DD_ONE(manager))); + var = manager->vars[x]; + + do { + manager->reordered = 0; + res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddBooleanDiff */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is dependent on others in a + function.] + + Description [Checks whether a variable is dependent on others in a + function. Returns 1 if the variable is dependent; 0 otherwise. No + new nodes are created.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_bddVarIsDependent( + DdManager *dd, /* manager */ + DdNode *f, /* function */ + DdNode *var /* variable */) +{ + DdNode *F, *res, *zero, *ft, *fe; + unsigned topf, level; + DD_CTFP cacheOp; + int retval; + + zero = Cudd_Not(DD_ONE(dd)); + if (Cudd_IsConstant(f)) return(f == zero); + + /* From now on f is not constant. */ + F = Cudd_Regular(f); + topf = (unsigned) dd->perm[F->index]; + level = (unsigned) dd->perm[var->index]; + + /* Check terminal case. If topf > index of var, f does not depend on var. + ** Therefore, var is not dependent in f. */ + if (topf > level) { + return(0); + } + + cacheOp = (DD_CTFP) Cudd_bddVarIsDependent; + res = cuddCacheLookup2(dd,cacheOp,f,var); + if (res != NULL) { + return(res != zero); + } + + /* Compute cofactors. */ + ft = Cudd_NotCond(cuddT(F), f != F); + fe = Cudd_NotCond(cuddE(F), f != F); + + if (topf == level) { + retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe)); + } else { + retval = Cudd_bddVarIsDependent(dd,ft,var) && + Cudd_bddVarIsDependent(dd,fe,var); + } + + cuddCacheInsert2(dd,cacheOp,f,var,Cudd_NotCond(zero,retval)); + + return(retval); + +} /* Cudd_bddVarIsDependent */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive steps of Cudd_bddExistAbstract.] + + Description [Performs the recursive steps of Cudd_bddExistAbstract. + Returns the BDD obtained by abstracting the variables + of cube from f if successful; NULL otherwise. It is also used by + Cudd_bddUnivAbstract.] + + SideEffects [None] + + SeeAlso [Cudd_bddExistAbstract Cudd_bddUnivAbstract] + +******************************************************************************/ +DdNode * +cuddBddExistAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *F, *T, *E, *res, *res1, *res2, *one; + + statLine(manager); + one = DD_ONE(manager); + F = Cudd_Regular(f); + + /* Cube is guaranteed to be a cube at this point. */ + if (cube == one || F == one) { + return(f); + } + /* From now on, f and cube are non-constant. */ + + /* Abstract a variable that does not appear in f. */ + while (manager->perm[F->index] > manager->perm[cube->index]) { + cube = cuddT(cube); + if (cube == one) return(f); + } + + /* Check the cache. */ + if (F->ref != 1 && (res = cuddCacheLookup2(manager, Cudd_bddExistAbstract, f, cube)) != NULL) { + return(res); + } + + /* Compute the cofactors of f. */ + T = cuddT(F); E = cuddE(F); + if (f != F) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + + /* If the two indices are the same, so are their levels. */ + if (F->index == cube->index) { + if (T == one || E == one || T == Cudd_Not(E)) { + return(one); + } + res1 = cuddBddExistAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + if (res1 == one) { + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, one); + return(one); + } + cuddRef(res1); + res2 = cuddBddExistAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddBddAndRecur(manager, Cudd_Not(res1), Cudd_Not(res2)); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + res = Cudd_Not(res); + cuddRef(res); + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); + cuddDeref(res); + return(res); + } else { /* if (cuddI(manager,F->index) < cuddI(manager,cube->index)) */ + res1 = cuddBddExistAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddBddExistAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager, res1); + return(NULL); + } + cuddRef(res2); + /* ITE takes care of possible complementation of res1 and of the + ** case in which res1 == res2. */ + res = cuddBddIteRecur(manager, manager->vars[F->index], res1, res2); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); + return(res); + } + +} /* end of cuddBddExistAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the exclusive OR of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +cuddBddXorExistAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *F, *fv, *fnv, *G, *gv, *gnv; + DdNode *one, *zero, *r, *t, *e, *Cube; + unsigned int topf, topg, topcube, top, index; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == g) { + return(zero); + } + if (f == Cudd_Not(g)) { + return(one); + } + if (cube == one) { + return(cuddBddXorRecur(manager, f, g)); + } + if (f == one) { + return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube)); + } + if (g == one) { + return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube)); + } + if (f == zero) { + return(cuddBddExistAbstractRecur(manager, g, cube)); + } + if (g == zero) { + return(cuddBddExistAbstractRecur(manager, f, cube)); + } + + /* At this point f, g, and cube are not constant. */ + + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; + g = tmp; + } + + /* Check cache. */ + r = cuddCacheLookup(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube); + if (r != NULL) { + return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + F = Cudd_Regular(f); + topf = manager->perm[F->index]; + G = Cudd_Regular(g); + topg = manager->perm[G->index]; + top = ddMin(topf, topg); + topcube = manager->perm[cube->index]; + + if (topcube < top) { + return(cuddBddXorExistAbstractRecur(manager, f, g, cuddT(cube))); + } + /* Now, topcube >= top. */ + + if (topf == top) { + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } + } else { + index = G->index; + fv = fnv = f; + } + + if (topg == top) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + if (topcube == top) { + Cube = cuddT(cube); + } else { + Cube = cube; + } + + t = cuddBddXorExistAbstractRecur(manager, fv, gv, Cube); + if (t == NULL) return(NULL); + + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. + */ + if (t == one && topcube == top) { + cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, one); + return(one); + } + cuddRef(t); + + e = cuddBddXorExistAbstractRecur(manager, fnv, gnv, Cube); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (topcube == top) { /* abstract */ + r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + cuddDeref(r); + } else if (t == e) { + r = t; + cuddDeref(t); + cuddDeref(e); + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + } + cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, r); + return (r); + +} /* end of cuddBddXorExistAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive steps of Cudd_bddBoleanDiff.] + + Description [Performs the recursive steps of Cudd_bddBoleanDiff. + Returns the BDD obtained by XORing the cofactors of f with respect to + var if successful; NULL otherwise. Exploits the fact that dF/dx = + dF'/dx.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddBddBooleanDiffRecur( + DdManager * manager, + DdNode * f, + DdNode * var) +{ + DdNode *T, *E, *res, *res1, *res2; + + statLine(manager); + if (cuddI(manager,f->index) > manager->perm[var->index]) { + /* f does not depend on var. */ + return(Cudd_Not(DD_ONE(manager))); + } + + /* From now on, f is non-constant. */ + + /* If the two indices are the same, so are their levels. */ + if (f->index == var->index) { + res = cuddBddXorRecur(manager, cuddT(f), cuddE(f)); + return(res); + } + + /* From now on, cuddI(manager,f->index) < cuddI(manager,cube->index). */ + + /* Check the cache. */ + res = cuddCacheLookup2(manager, cuddBddBooleanDiffRecur, f, var); + if (res != NULL) { + return(res); + } + + /* Compute the cofactors of f. */ + T = cuddT(f); E = cuddE(f); + + res1 = cuddBddBooleanDiffRecur(manager, T, var); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddBddBooleanDiffRecur(manager, Cudd_Regular(E), var); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager, res1); + return(NULL); + } + cuddRef(res2); + /* ITE takes care of possible complementation of res1 and of the + ** case in which res1 == res2. */ + res = cuddBddIteRecur(manager, manager->vars[f->index], res1, res2); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, cuddBddBooleanDiffRecur, f, var, res); + return(res); + +} /* end of cuddBddBooleanDiffRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Checks whether cube is an BDD representing the product of + positive literals.] + + Description [Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +bddCheckPositiveCube( + DdManager * manager, + DdNode * cube) +{ + if (Cudd_IsComplement(cube)) return(0); + if (cube == DD_ONE(manager)) return(1); + if (cuddIsConstant(cube)) return(0); + if (cuddE(cube) == Cudd_Not(DD_ONE(manager))) { + return(bddCheckPositiveCube(manager, cuddT(cube))); + } + return(0); + +} /* end of bddCheckPositiveCube */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddBddCorr.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddBddCorr.c new file mode 100644 index 000000000..e92d24ad6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddBddCorr.c @@ -0,0 +1,515 @@ +/**CFile*********************************************************************** + + FileName [cuddBddCorr.c] + + PackageName [cudd] + + Synopsis [Correlation between BDDs.] + + Description [External procedures included in this module: +
    +
  • Cudd_bddCorrelation() +
  • Cudd_bddCorrelationWeights() +
+ Static procedures included in this module: +
    +
  • bddCorrelationAux() +
  • bddCorrelationWeightsAux() +
  • CorrelCompare() +
  • CorrelHash() +
  • CorrelCleanUp() +
+ ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct hashEntry { + DdNode *f; + DdNode *g; +} HashEntry; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBddCorr.c,v 1.15 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef CORREL_STATS +static int num_calls; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static double bddCorrelationAux (DdManager *dd, DdNode *f, DdNode *g, st_table *table); +static double bddCorrelationWeightsAux (DdManager *dd, DdNode *f, DdNode *g, double *prob, st_table *table); +static int CorrelCompare (const char *key1, const char *key2); +static int CorrelHash (char *key, int modulus); +static enum st_retval CorrelCleanUp (char *key, char *value, char *arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the correlation of f and g.] + + Description [Computes the correlation of f and g. If f == g, their + correlation is 1. If f == g', their correlation is 0. Returns the + fraction of minterms in the ON-set of the EXNOR of f and g. If it + runs out of memory, returns (double)CUDD_OUT_OF_MEM.] + + SideEffects [None] + + SeeAlso [Cudd_bddCorrelationWeights] + +******************************************************************************/ +double +Cudd_bddCorrelation( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + + st_table *table; + double correlation; + +#ifdef CORREL_STATS + num_calls = 0; +#endif + + table = st_init_table(CorrelCompare,CorrelHash); + if (table == NULL) return((double)CUDD_OUT_OF_MEM); + correlation = bddCorrelationAux(manager,f,g,table); + st_foreach(table, CorrelCleanUp, NIL(char)); + st_free_table(table); + return(correlation); + +} /* end of Cudd_bddCorrelation */ + + +/**Function******************************************************************** + + Synopsis [Computes the correlation of f and g for given input + probabilities.] + + Description [Computes the correlation of f and g for given input + probabilities. On input, prob\[i\] is supposed to contain the + probability of the i-th input variable to be 1. + If f == g, their correlation is 1. If f == g', their + correlation is 0. Returns the probability that f and g have the same + value. If it runs out of memory, returns (double)CUDD_OUT_OF_MEM. The + correlation of f and the constant one gives the probability of f.] + + SideEffects [None] + + SeeAlso [Cudd_bddCorrelation] + +******************************************************************************/ +double +Cudd_bddCorrelationWeights( + DdManager * manager, + DdNode * f, + DdNode * g, + double * prob) +{ + + st_table *table; + double correlation; + +#ifdef CORREL_STATS + num_calls = 0; +#endif + + table = st_init_table(CorrelCompare,CorrelHash); + if (table == NULL) return((double)CUDD_OUT_OF_MEM); + correlation = bddCorrelationWeightsAux(manager,f,g,prob,table); + st_foreach(table, CorrelCleanUp, NIL(char)); + st_free_table(table); + return(correlation); + +} /* end of Cudd_bddCorrelationWeights */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCorrelation.] + + Description [Performs the recursive step of Cudd_bddCorrelation. + Returns the fraction of minterms in the ON-set of the EXNOR of f and + g.] + + SideEffects [None] + + SeeAlso [bddCorrelationWeightsAux] + +******************************************************************************/ +static double +bddCorrelationAux( + DdManager * dd, + DdNode * f, + DdNode * g, + st_table * table) +{ + DdNode *Fv, *Fnv, *G, *Gv, *Gnv; + double min, *pmin, min1, min2, *dummy; + HashEntry *entry; + unsigned int topF, topG; + + statLine(dd); +#ifdef CORREL_STATS + num_calls++; +#endif + + /* Terminal cases: only work for BDDs. */ + if (f == g) return(1.0); + if (f == Cudd_Not(g)) return(0.0); + + /* Standardize call using the following properties: + ** (f EXNOR g) = (g EXNOR f) + ** (f' EXNOR g') = (f EXNOR g). + */ + if (f > g) { + DdNode *tmp = f; + f = g; g = tmp; + } + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + g = Cudd_Not(g); + } + /* From now on, f is regular. */ + + entry = ALLOC(HashEntry,1); + if (entry == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + entry->f = f; entry->g = g; + + /* We do not use the fact that + ** correlation(f,g') = 1 - correlation(f,g) + ** to minimize the risk of cancellation. + */ + if (st_lookup(table, entry, &dummy)) { + min = *dummy; + FREE(entry); + return(min); + } + + G = Cudd_Regular(g); + topF = cuddI(dd,f->index); topG = cuddI(dd,G->index); + if (topF <= topG) { Fv = cuddT(f); Fnv = cuddE(f); } else { Fv = Fnv = f; } + if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; } + + if (g != G) { + Gv = Cudd_Not(Gv); + Gnv = Cudd_Not(Gnv); + } + + min1 = bddCorrelationAux(dd, Fv, Gv, table) / 2.0; + if (min1 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return(CUDD_OUT_OF_MEM); + } + min2 = bddCorrelationAux(dd, Fnv, Gnv, table) / 2.0; + if (min2 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return(CUDD_OUT_OF_MEM); + } + min = (min1+min2); + + pmin = ALLOC(double,1); + if (pmin == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + *pmin = min; + + if (st_insert(table,(char *)entry, (char *)pmin) == ST_OUT_OF_MEM) { + FREE(entry); + FREE(pmin); + return((double)CUDD_OUT_OF_MEM); + } + return(min); + +} /* end of bddCorrelationAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCorrelationWeigths.] + + Description [] + + SideEffects [None] + + SeeAlso [bddCorrelationAux] + +******************************************************************************/ +static double +bddCorrelationWeightsAux( + DdManager * dd, + DdNode * f, + DdNode * g, + double * prob, + st_table * table) +{ + DdNode *Fv, *Fnv, *G, *Gv, *Gnv; + double min, *pmin, min1, min2, *dummy; + HashEntry *entry; + int topF, topG, index; + + statLine(dd); +#ifdef CORREL_STATS + num_calls++; +#endif + + /* Terminal cases: only work for BDDs. */ + if (f == g) return(1.0); + if (f == Cudd_Not(g)) return(0.0); + + /* Standardize call using the following properties: + ** (f EXNOR g) = (g EXNOR f) + ** (f' EXNOR g') = (f EXNOR g). + */ + if (f > g) { + DdNode *tmp = f; + f = g; g = tmp; + } + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + g = Cudd_Not(g); + } + /* From now on, f is regular. */ + + entry = ALLOC(HashEntry,1); + if (entry == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + entry->f = f; entry->g = g; + + /* We do not use the fact that + ** correlation(f,g') = 1 - correlation(f,g) + ** to minimize the risk of cancellation. + */ + if (st_lookup(table, entry, &dummy)) { + min = *dummy; + FREE(entry); + return(min); + } + + G = Cudd_Regular(g); + topF = cuddI(dd,f->index); topG = cuddI(dd,G->index); + if (topF <= topG) { + Fv = cuddT(f); Fnv = cuddE(f); + index = f->index; + } else { + Fv = Fnv = f; + index = G->index; + } + if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; } + + if (g != G) { + Gv = Cudd_Not(Gv); + Gnv = Cudd_Not(Gnv); + } + + min1 = bddCorrelationWeightsAux(dd, Fv, Gv, prob, table) * prob[index]; + if (min1 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return((double)CUDD_OUT_OF_MEM); + } + min2 = bddCorrelationWeightsAux(dd, Fnv, Gnv, prob, table) * (1.0 - prob[index]); + if (min2 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return((double)CUDD_OUT_OF_MEM); + } + min = (min1+min2); + + pmin = ALLOC(double,1); + if (pmin == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + *pmin = min; + + if (st_insert(table,(char *)entry, (char *)pmin) == ST_OUT_OF_MEM) { + FREE(entry); + FREE(pmin); + return((double)CUDD_OUT_OF_MEM); + } + return(min); + +} /* end of bddCorrelationWeightsAux */ + + +/**Function******************************************************************** + + Synopsis [Compares two hash table entries.] + + Description [Compares two hash table entries. Returns 0 if they are + identical; 1 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +CorrelCompare( + const char * key1, + const char * key2) +{ + HashEntry *entry1; + HashEntry *entry2; + + entry1 = (HashEntry *) key1; + entry2 = (HashEntry *) key2; + if (entry1->f != entry2->f || entry1->g != entry2->g) return(1); + + return(0); + +} /* end of CorrelCompare */ + + +/**Function******************************************************************** + + Synopsis [Hashes a hash table entry.] + + Description [Hashes a hash table entry. It is patterned after + st_strhash. Returns a value between 0 and modulus.] + + SideEffects [None] + +******************************************************************************/ +static int +CorrelHash( + char * key, + int modulus) +{ + HashEntry *entry; + int val = 0; + + entry = (HashEntry *) key; +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + val = ((int) ((long)entry->f))*997 + ((int) ((long)entry->g)); +#else + val = ((int) entry->f)*997 + ((int) entry->g); +#endif + + return ((val < 0) ? -val : val) % modulus; + +} /* end of CorrelHash */ + + +/**Function******************************************************************** + + Synopsis [Frees memory associated with hash table.] + + Description [Frees memory associated with hash table. Returns + ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +CorrelCleanUp( + char * key, + char * value, + char * arg) +{ + double *d; + HashEntry *entry; + + entry = (HashEntry *) key; + FREE(entry); + d = (double *)value; + FREE(d); + return ST_CONTINUE; + +} /* end of CorrelCleanUp */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddBddIte.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddBddIte.c new file mode 100644 index 000000000..750a51c74 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddBddIte.c @@ -0,0 +1,1430 @@ +/**CFile*********************************************************************** + + FileName [cuddBddIte.c] + + PackageName [cudd] + + Synopsis [BDD ITE function and satellites.] + + Description [External procedures included in this module: +
    +
  • Cudd_bddIte() +
  • Cudd_bddIteLimit() +
  • Cudd_bddIteConstant() +
  • Cudd_bddIntersect() +
  • Cudd_bddAnd() +
  • Cudd_bddAndLimit() +
  • Cudd_bddOr() +
  • Cudd_bddOrLimit() +
  • Cudd_bddNand() +
  • Cudd_bddNor() +
  • Cudd_bddXor() +
  • Cudd_bddXnor() +
  • Cudd_bddXnorLimit() +
  • Cudd_bddLeq() +
+ Internal procedures included in this module: +
    +
  • cuddBddIteRecur() +
  • cuddBddIntersectRecur() +
  • cuddBddAndRecur() +
  • cuddBddXorRecur() +
+ Static procedures included in this module: +
    +
  • bddVarToConst() +
  • bddVarToCanonical() +
  • bddVarToCanonicalSimple() +
] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBddIte.c,v 1.26 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void bddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one); +static int bddVarToCanonical (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp); +static int bddVarToCanonicalSimple (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements ITE(f,g,h).] + + Description [Implements ITE(f,g,h). Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows + up.] + + SideEffects [None] + + SeeAlso [Cudd_addIte Cudd_bddIteConstant Cudd_bddIntersect] + +******************************************************************************/ +DdNode * +Cudd_bddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddIteRecur(dd,f,g,h); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddIte */ + + +/**Function******************************************************************** + + Synopsis [Implements ITE(f,g,h). Returns + NULL if too many nodes are required.] + + Description [Implements ITE(f,g,h). Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte] + +******************************************************************************/ +DdNode * +Cudd_bddIteLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddIteRecur(dd,f,g,h); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddIteLimit */ + + +/**Function******************************************************************** + + Synopsis [Implements ITEconstant(f,g,h).] + + Description [Implements ITEconstant(f,g,h). Returns a pointer to the + resulting BDD (which may or may not be constant) or DD_NON_CONSTANT. + No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_bddIntersect Cudd_bddLeq Cudd_addIteConstant] + +******************************************************************************/ +DdNode * +Cudd_bddIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + int comple; + unsigned int topf, topg, toph, v; + + statLine(dd); + /* Trivial cases. */ + if (f == one) /* ITE(1,G,H) => G */ + return(g); + + if (f == zero) /* ITE(0,G,H) => H */ + return(h); + + /* f now not a constant. */ + bddVarToConst(f, &g, &h, one); /* possibly convert g or h */ + /* to constants */ + + if (g == h) /* ITE(F,G,G) => G */ + return(g); + + if (Cudd_IsConstant(g) && Cudd_IsConstant(h)) + return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */ + /* => DD_NON_CONSTANT */ + + if (g == Cudd_Not(h)) + return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */ + /* if F != G and F != G' */ + + comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph); + + /* Cache lookup. */ + r = cuddConstantLookup(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h); + if (r != NULL) { + return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT)); + } + + v = ddMin(topg, toph); + + /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */ + if (topf < v && cuddT(f) == one && cuddE(f) == zero) { + return(DD_NON_CONSTANT); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf, v); /* v = top_var(F,G,H) */ + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + + if (topg == v) { + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + + if (toph == v) { + H = Cudd_Regular(h); + Hv = cuddT(H); Hnv = cuddE(H); + if (Cudd_IsComplement(h)) { + Hv = Cudd_Not(Hv); + Hnv = Cudd_Not(Hnv); + } + } else { + Hv = Hnv = h; + } + + /* Recursion. */ + t = Cudd_bddIteConstant(dd, Fv, Gv, Hv); + if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) { + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv); + if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) { + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t); + return(Cudd_NotCond(t,comple)); + +} /* end of Cudd_bddIteConstant */ + + +/**Function******************************************************************** + + Synopsis [Returns a function included in the intersection of f and g.] + + Description [Computes a function included in the intersection of f and + g. (That is, a witness that the intersection is not empty.) + Cudd_bddIntersect tries to build as few new nodes as possible. If the + only result of interest is whether f and g intersect, + Cudd_bddLeq should be used instead.] + + SideEffects [None] + + SeeAlso [Cudd_bddLeq Cudd_bddIteConstant] + +******************************************************************************/ +DdNode * +Cudd_bddIntersect( + DdManager * dd /* manager */, + DdNode * f /* first operand */, + DdNode * g /* second operand */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddIntersectRecur(dd,f,g); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_bddIntersect */ + + +/**Function******************************************************************** + + Synopsis [Computes the conjunction of two BDDs f and g.] + + Description [Computes the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAndAbstract Cudd_bddIntersect + Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddAnd( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddAnd */ + + +/**Function******************************************************************** + + Synopsis [Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required.] + + Description [Computes the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddAndLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddAndLimit */ + + +/**Function******************************************************************** + + Synopsis [Computes the disjunction of two BDDs f and g.] + + Description [Computes the disjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddNand Cudd_bddNor + Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddOr( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + } while (dd->reordered == 1); + res = Cudd_NotCond(res,res != NULL); + return(res); + +} /* end of Cudd_bddOr */ + + +/**Function******************************************************************** + + Synopsis [Computes the disjunction of two BDDs f and g. Returns + NULL if too many nodes are required.] + + Description [Computes the disjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddOr] + +******************************************************************************/ +DdNode * +Cudd_bddOrLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + res = Cudd_NotCond(res,res != NULL); + return(res); + +} /* end of Cudd_bddOrLimit */ + + +/**Function******************************************************************** + + Synopsis [Computes the NAND of two BDDs f and g.] + + Description [Computes the NAND of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNor + Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddNand( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + res = Cudd_NotCond(res,res != NULL); + return(res); + +} /* end of Cudd_bddNand */ + + +/**Function******************************************************************** + + Synopsis [Computes the NOR of two BDDs f and g.] + + Description [Computes the NOR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand + Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddNor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddNor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive OR of two BDDs f and g.] + + Description [Computes the exclusive OR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr + Cudd_bddNand Cudd_bddNor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddXor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddXor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive NOR of two BDDs f and g.] + + Description [Computes the exclusive NOR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr + Cudd_bddNand Cudd_bddNor Cudd_bddXor] + +******************************************************************************/ +DdNode * +Cudd_bddXnor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,Cudd_Not(g)); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddXnor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive NOR of two BDDs f and g. Returns + NULL if too many nodes are required.] + + Description [Computes the exclusive NOR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddXnorLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,Cudd_Not(g)); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddXnorLimit */ + + +/**Function******************************************************************** + + Synopsis [Determines whether f is less than or equal to g.] + + Description [Returns 1 if f is less than or equal to g; 0 otherwise. + No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_bddIteConstant Cudd_addEvalConst] + +******************************************************************************/ +int +Cudd_bddLeq( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *one, *zero, *tmp, *F, *fv, *fvn, *gv, *gvn; + unsigned int topf, topg, res; + + statLine(dd); + /* Terminal cases and normalization. */ + if (f == g) return(1); + + if (Cudd_IsComplement(g)) { + /* Special case: if f is regular and g is complemented, + ** f(1,...,1) = 1 > 0 = g(1,...,1). + */ + if (!Cudd_IsComplement(f)) return(0); + /* Both are complemented: Swap and complement because + ** f <= g <=> g' <= f' and we want the second argument to be regular. + */ + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } else if (Cudd_IsComplement(f) && g < f) { + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } + + /* Now g is regular and, if f is not regular, f < g. */ + one = DD_ONE(dd); + if (g == one) return(1); /* no need to test against zero */ + if (f == one) return(0); /* since at this point g != one */ + if (Cudd_Not(f) == g) return(0); /* because neither is constant */ + zero = Cudd_Not(one); + if (f == zero) return(1); + + /* Here neither f nor g is constant. */ + + /* Check cache. */ + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g); + if (tmp != NULL) { + return(tmp == one); + } + + /* Compute cofactors. */ + F = Cudd_Regular(f); + topf = dd->perm[F->index]; + topg = dd->perm[g->index]; + if (topf <= topg) { + fv = cuddT(F); fvn = cuddE(F); + if (f != F) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + } else { + fv = fvn = f; + } + if (topg <= topf) { + gv = cuddT(g); gvn = cuddE(g); + } else { + gv = gvn = g; + } + + /* Recursive calls. Since we want to maximize the probability of + ** the special case f(1,...,1) > g(1,...,1), we consider the negative + ** cofactors first. Indeed, the complementation parity of the positive + ** cofactors is the same as the one of the parent functions. + */ + res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv); + + /* Store result in cache and return. */ + cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero)); + return(res); + +} /* end of Cudd_bddLeq */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddIte.] + + Description [Implements the recursive step of Cudd_bddIte. Returns a + pointer to the resulting BDD. NULL if the intermediate result blows + up or if reordering occurs.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddBddIteRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *one, *zero, *res; + DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; + unsigned int topf, topg, toph, v; + int index; + int comple; + + statLine(dd); + /* Terminal cases. */ + + /* One variable cases. */ + if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */ + return(g); + + if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */ + return(h); + + /* From now on, f is known not to be a constant. */ + if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + if (h == zero) { /* ITE(F,1,0) = F */ + return(f); + } else { + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h)); + return(Cudd_NotCond(res,res != NULL)); + } + } else if (g == zero || f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ + if (h == one) { /* ITE(F,0,1) = !F */ + return(Cudd_Not(f)); + } else { + res = cuddBddAndRecur(dd,Cudd_Not(f),h); + return(res); + } + } + if (h == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + res = cuddBddAndRecur(dd,f,g); + return(res); + } else if (h == one || f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ + res = cuddBddAndRecur(dd,f,Cudd_Not(g)); + return(Cudd_NotCond(res,res != NULL)); + } + + /* Check remaining one variable case. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = F <-> G */ + res = cuddBddXorRecur(dd,f,h); + return(res); + } + + /* From here, there are no constants. */ + comple = bddVarToCanonicalSimple(dd, &f, &g, &h, &topf, &topg, &toph); + + /* f & g are now regular pointers */ + + v = ddMin(topg, toph); + + /* A shortcut: ITE(F,G,H) = (v,G,H) if F = (v,1,0), v < top(G,H). */ + if (topf < v && cuddT(f) == one && cuddE(f) == zero) { + r = cuddUniqueInter(dd, (int) f->index, g, h); + return(Cudd_NotCond(r,comple && r != NULL)); + } + + /* Check cache. */ + r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf, v); /* v = top_var(F,G,H) */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg == v) { + index = g->index; + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + if (toph == v) { + H = Cudd_Regular(h); + index = H->index; + Hv = cuddT(H); Hnv = cuddE(H); + if (Cudd_IsComplement(h)) { + Hv = Cudd_Not(Hv); + Hnv = Cudd_Not(Hnv); + } + } else { + Hv = Hnv = h; + } + + /* Recursive step. */ + t = cuddBddIteRecur(dd,Fv,Gv,Hv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert(dd, DD_BDD_ITE_TAG, f, g, h, r); + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddIteRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddIntersect.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_bddIntersect] + +******************************************************************************/ +DdNode * +cuddBddIntersectRecur( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + DdNode *F, *G, *t, *e; + DdNode *fv, *fnv, *gv, *gnv; + DdNode *one, *zero; + unsigned int index, topf, topg; + + statLine(dd); + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == g || g == one) return(f); + if (f == one) return(g); + + /* At this point f and g are not constant. */ + if (f > g) { DdNode *tmp = f; f = g; g = tmp; } + res = cuddCacheLookup2(dd,Cudd_bddIntersect,f,g); + if (res != NULL) return(res); + + /* Find splitting variable. Here we can skip the use of cuddI, + ** because the operands are known to be non-constant. + */ + F = Cudd_Regular(f); + topf = dd->perm[F->index]; + G = Cudd_Regular(g); + topg = dd->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } + } else { + index = G->index; + fv = fnv = f; + } + + if (topg <= topf) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + /* Compute partial results. */ + t = cuddBddIntersectRecur(dd,fv,gv); + if (t == NULL) return(NULL); + cuddRef(t); + if (t != zero) { + e = zero; + } else { + e = cuddBddIntersectRecur(dd,fnv,gnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddRef(e); + + if (t == e) { /* both equal zero */ + res = t; + } else if (Cudd_IsComplement(t)) { + res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (res == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = cuddUniqueInter(dd,(int)index,t,e); + if (res == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + + cuddCacheInsert2(dd,Cudd_bddIntersect,f,g,res); + + return(res); + +} /* end of cuddBddIntersectRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddAnd.] + + Description [Implements the recursive step of Cudd_bddAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +cuddBddAndRecur( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + DdNode *F, *fv, *fnv, *G, *gv, *gnv; + DdNode *one, *r, *t, *e; + unsigned int topf, topg, index; + + statLine(manager); + one = DD_ONE(manager); + + /* Terminal cases. */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + if (F == G) { + if (f == g) return(f); + else return(Cudd_Not(one)); + } + if (F == one) { + if (f == one) return(g); + else return(f); + } + if (G == one) { + if (g == one) return(f); + else return(g); + } + + /* At this point f and g are not constant. */ + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; + g = tmp; + F = Cudd_Regular(f); + G = Cudd_Regular(g); + } + + /* Check cache. */ + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g); + if (r != NULL) return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } + } else { + index = G->index; + fv = fnv = f; + } + + if (topg <= topf) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + t = cuddBddAndRecur(manager, fv, gv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddAndRecur(manager, fnv, gnv); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r); + return(r); + +} /* end of cuddBddAndRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddXor.] + + Description [Implements the recursive step of Cudd_bddXor by taking + the exclusive OR of two BDDs. Returns a pointer to the result is + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddXor] + +******************************************************************************/ +DdNode * +cuddBddXorRecur( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + DdNode *fv, *fnv, *G, *gv, *gnv; + DdNode *one, *zero, *r, *t, *e; + unsigned int topf, topg, index; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == g) return(zero); + if (f == Cudd_Not(g)) return(one); + if (f > g) { /* Try to increase cache efficiency and simplify tests. */ + DdNode *tmp = f; + f = g; + g = tmp; + } + if (g == zero) return(f); + if (g == one) return(Cudd_Not(f)); + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + g = Cudd_Not(g); + } + /* Now the first argument is regular. */ + if (f == one) return(Cudd_Not(g)); + + /* At this point f and g are not constant. */ + + /* Check cache. */ + r = cuddCacheLookup2(manager, Cudd_bddXor, f, g); + if (r != NULL) return(r); + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[f->index]; + G = Cudd_Regular(g); + topg = manager->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = f->index; + fv = cuddT(f); + fnv = cuddE(f); + } else { + index = G->index; + fv = fnv = f; + } + + if (topg <= topf) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + t = cuddBddXorRecur(manager, fv, gv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddXorRecur(manager, fnv, gnv); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + cuddCacheInsert2(manager, Cudd_bddXor, f, g, r); + return(r); + +} /* end of cuddBddXorRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Replaces variables with constants if possible.] + + Description [This function performs part of the transformation to + standard form by replacing variables with constants if possible.] + + SideEffects [None] + + SeeAlso [bddVarToCanonical bddVarToCanonicalSimple] + +******************************************************************************/ +static void +bddVarToConst( + DdNode * f, + DdNode ** gp, + DdNode ** hp, + DdNode * one) +{ + DdNode *g = *gp; + DdNode *h = *hp; + + if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + *gp = one; + } else if (f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ + *gp = Cudd_Not(one); + } + if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + *hp = Cudd_Not(one); + } else if (f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ + *hp = one; + } + +} /* end of bddVarToConst */ + + +/**Function******************************************************************** + + Synopsis [Picks unique member from equiv expressions.] + + Description [Reduces 2 variable expressions to canonical form.] + + SideEffects [None] + + SeeAlso [bddVarToConst bddVarToCanonicalSimple] + +******************************************************************************/ +static int +bddVarToCanonical( + DdManager * dd, + DdNode ** fp, + DdNode ** gp, + DdNode ** hp, + unsigned int * topfp, + unsigned int * topgp, + unsigned int * tophp) +{ + register DdNode *F, *G, *H, *r, *f, *g, *h; + register unsigned int topf, topg, toph; + DdNode *one = dd->one; + int comple, change; + + f = *fp; + g = *gp; + h = *hp; + F = Cudd_Regular(f); + G = Cudd_Regular(g); + H = Cudd_Regular(h); + topf = cuddI(dd,F->index); + topg = cuddI(dd,G->index); + toph = cuddI(dd,H->index); + + change = 0; + + if (G == one) { /* ITE(F,c,H) */ + if ((topf > toph) || (topf == toph && f > h)) { + r = h; + h = f; + f = r; /* ITE(F,1,H) = ITE(H,1,F) */ + if (g != one) { /* g == zero */ + f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */ + h = Cudd_Not(h); + } + change = 1; + } + } else if (H == one) { /* ITE(F,G,c) */ + if ((topf > topg) || (topf == topg && f > g)) { + r = g; + g = f; + f = r; /* ITE(F,G,0) = ITE(G,F,0) */ + if (h == one) { + f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */ + g = Cudd_Not(g); + } + change = 1; + } + } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */ + if ((topf > topg) || (topf == topg && f > g)) { + r = f; + f = g; + g = r; + h = Cudd_Not(r); + change = 1; + } + } + /* adjust pointers so that the first 2 arguments to ITE are regular */ + if (Cudd_IsComplement(f) != 0) { /* ITE(!F,G,H) = ITE(F,H,G) */ + f = Cudd_Not(f); + r = g; + g = h; + h = r; + change = 1; + } + comple = 0; + if (Cudd_IsComplement(g) != 0) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ + g = Cudd_Not(g); + h = Cudd_Not(h); + change = 1; + comple = 1; + } + if (change != 0) { + *fp = f; + *gp = g; + *hp = h; + } + *topfp = cuddI(dd,f->index); + *topgp = cuddI(dd,g->index); + *tophp = cuddI(dd,Cudd_Regular(h)->index); + + return(comple); + +} /* end of bddVarToCanonical */ + + +/**Function******************************************************************** + + Synopsis [Picks unique member from equiv expressions.] + + Description [Makes sure the first two pointers are regular. This + mat require the complementation of the result, which is signaled by + returning 1 instead of 0. This function is simpler than the general + case because it assumes that no two arguments are the same or + complementary, and no argument is constant.] + + SideEffects [None] + + SeeAlso [bddVarToConst bddVarToCanonical] + +******************************************************************************/ +static int +bddVarToCanonicalSimple( + DdManager * dd, + DdNode ** fp, + DdNode ** gp, + DdNode ** hp, + unsigned int * topfp, + unsigned int * topgp, + unsigned int * tophp) +{ + register DdNode *r, *f, *g, *h; + int comple, change; + + f = *fp; + g = *gp; + h = *hp; + + change = 0; + + /* adjust pointers so that the first 2 arguments to ITE are regular */ + if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */ + f = Cudd_Not(f); + r = g; + g = h; + h = r; + change = 1; + } + comple = 0; + if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ + g = Cudd_Not(g); + h = Cudd_Not(h); + change = 1; + comple = 1; + } + if (change) { + *fp = f; + *gp = g; + *hp = h; + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + *topfp = dd->perm[f->index]; + *topgp = dd->perm[g->index]; + *tophp = dd->perm[Cudd_Regular(h)->index]; + + return(comple); + +} /* end of bddVarToCanonicalSimple */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddBridge.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddBridge.c new file mode 100644 index 000000000..a6207b7f6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddBridge.c @@ -0,0 +1,1016 @@ +/**CFile*********************************************************************** + + FileName [cuddBridge.c] + + PackageName [cudd] + + Synopsis [Translation from BDD to ADD and vice versa and transfer between + different managers.] + + Description [External procedures included in this file: +
    +
  • Cudd_addBddThreshold() +
  • Cudd_addBddStrictThreshold() +
  • Cudd_addBddInterval() +
  • Cudd_addBddIthBit() +
  • Cudd_BddToAdd() +
  • Cudd_addBddPattern() +
  • Cudd_bddTransfer() +
+ Internal procedures included in this file: +
    +
  • cuddBddTransfer() +
  • cuddAddBddDoPattern() +
+ Static procedures included in this file: +
    +
  • addBddDoThreshold() +
  • addBddDoStrictThreshold() +
  • addBddDoInterval() +
  • addBddDoIthBit() +
  • ddBddToAddRecur() +
  • cuddBddTransferRecur() +
+ ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.20 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addBddDoThreshold (DdManager *dd, DdNode *f, DdNode *val); +static DdNode * addBddDoStrictThreshold (DdManager *dd, DdNode *f, DdNode *val); +static DdNode * addBddDoInterval (DdManager *dd, DdNode *f, DdNode *l, DdNode *u); +static DdNode * addBddDoIthBit (DdManager *dd, DdNode *f, DdNode *index); +static DdNode * ddBddToAddRecur (DdManager *dd, DdNode *B); +static DdNode * cuddBddTransferRecur (DdManager *ddS, DdManager *ddD, DdNode *f, st_table *table); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants greater than or equal to value with 1, and all other + discriminants with 0. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd + Cudd_addBddStrictThreshold] + +******************************************************************************/ +DdNode * +Cudd_addBddThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value) +{ + DdNode *res; + DdNode *val; + + val = cuddUniqueConst(dd,value); + if (val == NULL) return(NULL); + cuddRef(val); + + do { + dd->reordered = 0; + res = addBddDoThreshold(dd, f, val); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, val); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, val); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddThreshold */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants STRICTLY greater than value with 1, and all other + discriminants with 0. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd + Cudd_addBddThreshold] + +******************************************************************************/ +DdNode * +Cudd_addBddStrictThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value) +{ + DdNode *res; + DdNode *val; + + val = cuddUniqueConst(dd,value); + if (val == NULL) return(NULL); + cuddRef(val); + + do { + dd->reordered = 0; + res = addBddDoStrictThreshold(dd, f, val); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, val); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, val); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddStrictThreshold */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants greater than or equal to lower and less than or equal to + upper with 1, and all other discriminants with 0. Returns a pointer to + the resulting BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddThreshold Cudd_addBddStrictThreshold + Cudd_addBddPattern Cudd_BddToAdd] + +******************************************************************************/ +DdNode * +Cudd_addBddInterval( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE lower, + CUDD_VALUE_TYPE upper) +{ + DdNode *res; + DdNode *l; + DdNode *u; + + /* Create constant nodes for the interval bounds, so that we can use + ** the global cache. + */ + l = cuddUniqueConst(dd,lower); + if (l == NULL) return(NULL); + cuddRef(l); + u = cuddUniqueConst(dd,upper); + if (u == NULL) { + Cudd_RecursiveDeref(dd,l); + return(NULL); + } + cuddRef(u); + + do { + dd->reordered = 0; + res = addBddDoInterval(dd, f, l, u); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, l); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, l); + Cudd_RecursiveDeref(dd, u); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddInterval */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD by extracting the i-th bit from + the leaves.] + + Description [Converts an ADD to a BDD by replacing all + discriminants whose i-th bit is equal to 1 with 1, and all other + discriminants with 0. The i-th bit refers to the integer + representation of the leaf value. If the value is has a fractional + part, it is ignored. Repeated calls to this procedure allow one to + transform an integer-valued ADD into an array of BDDs, one for each + bit of the leaf values. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd] + +******************************************************************************/ +DdNode * +Cudd_addBddIthBit( + DdManager * dd, + DdNode * f, + int bit) +{ + DdNode *res; + DdNode *index; + + index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit); + if (index == NULL) return(NULL); + cuddRef(index); + + do { + dd->reordered = 0; + res = addBddDoIthBit(dd, f, index); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, index); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, index); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddIthBit */ + + +/**Function******************************************************************** + + Synopsis [Converts a BDD to a 0-1 ADD.] + + Description [Converts a BDD to a 0-1 ADD. Returns a pointer to the + resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddPattern Cudd_addBddThreshold Cudd_addBddInterval + Cudd_addBddStrictThreshold] + +******************************************************************************/ +DdNode * +Cudd_BddToAdd( + DdManager * dd, + DdNode * B) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = ddBddToAddRecur(dd, B); + } while (dd->reordered ==1); + return(res); + +} /* end of Cudd_BddToAdd */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants different from 0 with 1. Returns a pointer to the + resulting BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_BddToAdd Cudd_addBddThreshold Cudd_addBddInterval + Cudd_addBddStrictThreshold] + +******************************************************************************/ +DdNode * +Cudd_addBddPattern( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddBddDoPattern(dd, f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addBddPattern */ + + +/**Function******************************************************************** + + Synopsis [Convert a BDD from a manager to another one.] + + Description [Convert a BDD from a manager to another one. The orders of the + variables in the two managers may be different. Returns a + pointer to the BDD in the destination manager if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_bddTransfer( + DdManager * ddSource, + DdManager * ddDestination, + DdNode * f) +{ + DdNode *res; + do { + ddDestination->reordered = 0; + res = cuddBddTransfer(ddSource, ddDestination, f); + } while (ddDestination->reordered == 1); + return(res); + +} /* end of Cudd_bddTransfer */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Convert a BDD from a manager to another one.] + + Description [Convert a BDD from a manager to another one. Returns a + pointer to the BDD in the destination manager if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddTransfer] + +******************************************************************************/ +DdNode * +cuddBddTransfer( + DdManager * ddS, + DdManager * ddD, + DdNode * f) +{ + DdNode *res; + st_table *table = NULL; + st_generator *gen = NULL; + DdNode *key, *value; + + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) goto failure; + res = cuddBddTransferRecur(ddS, ddD, f, table); + if (res != NULL) cuddRef(res); + + /* Dereference all elements in the table and dispose of the table. + ** This must be done also if res is NULL to avoid leaks in case of + ** reordering. */ + gen = st_init_gen(table); + if (gen == NULL) goto failure; + while (st_gen(gen, &key, &value)) { + Cudd_RecursiveDeref(ddD, value); + } + st_free_gen(gen); gen = NULL; + st_free_table(table); table = NULL; + + if (res != NULL) cuddDeref(res); + return(res); + +failure: + /* No need to free gen because it is always NULL here. */ + if (table != NULL) st_free_table(table); + return(NULL); + +} /* end of cuddBddTransfer */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddPattern.] + + Description [Performs the recursive step for Cudd_addBddPattern. Returns a + pointer to the resulting BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddAddBddDoPattern( + DdManager * dd, + DdNode * f) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),f == DD_ZERO(dd))); + } + + /* Check cache. */ + res = cuddCacheLookup1(dd,Cudd_addBddPattern,f); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = cuddAddBddDoPattern(dd,fv); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddBddDoPattern(dd,fvn); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,Cudd_addBddPattern,f,res); + + return(res); + +} /* end of cuddAddBddDoPattern */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddThreshold.] + + Description [Performs the recursive step for Cudd_addBddThreshold. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [addBddDoStrictThreshold] + +******************************************************************************/ +static DdNode * +addBddDoThreshold( + DdManager * dd, + DdNode * f, + DdNode * val) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(val))); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addBddDoThreshold,f,val); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoThreshold(dd,fv,val); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoThreshold(dd,fvn,val); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addBddDoThreshold,f,val,res); + + return(res); + +} /* end of addBddDoThreshold */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddStrictThreshold.] + + Description [Performs the recursive step for Cudd_addBddStrictThreshold. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [addBddDoThreshold] + +******************************************************************************/ +static DdNode * +addBddDoStrictThreshold( + DdManager * dd, + DdNode * f, + DdNode * val) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) <= cuddV(val))); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addBddDoStrictThreshold,f,val); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoStrictThreshold(dd,fv,val); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoStrictThreshold(dd,fvn,val); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addBddDoStrictThreshold,f,val,res); + + return(res); + +} /* end of addBddDoStrictThreshold */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddInterval.] + + Description [Performs the recursive step for Cudd_addBddInterval. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [addBddDoThreshold addBddDoStrictThreshold] + +******************************************************************************/ +static DdNode * +addBddDoInterval( + DdManager * dd, + DdNode * f, + DdNode * l, + DdNode * u) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(l) || cuddV(f) > cuddV(u))); + } + + /* Check cache. */ + res = cuddCacheLookup(dd,DD_ADD_BDD_DO_INTERVAL_TAG,f,l,u); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoInterval(dd,fv,l,u); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoInterval(dd,fvn,l,u); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert(dd,DD_ADD_BDD_DO_INTERVAL_TAG,f,l,u,res); + + return(res); + +} /* end of addBddDoInterval */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddIthBit.] + + Description [Performs the recursive step for Cudd_addBddIthBit. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +addBddDoIthBit( + DdManager * dd, + DdNode * f, + DdNode * index) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int mask, value; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + mask = 1 << ((int) cuddV(index)); + value = (int) cuddV(f); + return(Cudd_NotCond(DD_ONE(dd),(value & mask) == 0)); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addBddDoIthBit,f,index); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoIthBit(dd,fv,index); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoIthBit(dd,fvn,index); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addBddDoIthBit,f,index,res); + + return(res); + +} /* end of addBddDoIthBit */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_BddToAdd.] + + Description [Performs the recursive step for Cudd_BddToAdd. Returns a + pointer to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +ddBddToAddRecur( + DdManager * dd, + DdNode * B) +{ + DdNode *one; + DdNode *res, *res1, *T, *E, *Bt, *Be; + int complement = 0; + + statLine(dd); + one = DD_ONE(dd); + + if (Cudd_IsConstant(B)) { + if (B == one) { + res = one; + } else { + res = DD_ZERO(dd); + } + return(res); + } + /* Check visited table */ + res = cuddCacheLookup1(dd,ddBddToAddRecur,B); + if (res != NULL) return(res); + + if (Cudd_IsComplement(B)) { + complement = 1; + Bt = cuddT(Cudd_Regular(B)); + Be = cuddE(Cudd_Regular(B)); + } else { + Bt = cuddT(B); + Be = cuddE(B); + } + + T = ddBddToAddRecur(dd, Bt); + if (T == NULL) return(NULL); + cuddRef(T); + + E = ddBddToAddRecur(dd, Be); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + /* No need to check for T == E, because it is guaranteed not to happen. */ + res = cuddUniqueInter(dd, (int) Cudd_Regular(B)->index, T, E); + if (res == NULL) { + Cudd_RecursiveDeref(dd ,T); + Cudd_RecursiveDeref(dd ,E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + if (complement) { + cuddRef(res); + res1 = cuddAddCmplRecur(dd, res); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(res1); + Cudd_RecursiveDeref(dd, res); + res = res1; + cuddDeref(res); + } + + /* Store result. */ + cuddCacheInsert1(dd,ddBddToAddRecur,B,res); + + return(res); + +} /* end of ddBddToAddRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddTransfer.] + + Description [Performs the recursive step of Cudd_bddTransfer. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddBddTransfer] + +******************************************************************************/ +static DdNode * +cuddBddTransferRecur( + DdManager * ddS, + DdManager * ddD, + DdNode * f, + st_table * table) +{ + DdNode *ft, *fe, *t, *e, *var, *res; + DdNode *one, *zero; + int index; + int comple = 0; + + statLine(ddD); + one = DD_ONE(ddD); + comple = Cudd_IsComplement(f); + + /* Trivial cases. */ + if (Cudd_IsConstant(f)) return(Cudd_NotCond(one, comple)); + + /* Make canonical to increase the utilization of the cache. */ + f = Cudd_NotCond(f,comple); + /* Now f is a regular pointer to a non-constant node. */ + + /* Check the cache. */ + if (st_lookup(table, f, &res)) + return(Cudd_NotCond(res,comple)); + + /* Recursive step. */ + index = f->index; + ft = cuddT(f); fe = cuddE(f); + + t = cuddBddTransferRecur(ddS, ddD, ft, table); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + + e = cuddBddTransferRecur(ddS, ddD, fe, table); + if (e == NULL) { + Cudd_RecursiveDeref(ddD, t); + return(NULL); + } + cuddRef(e); + + zero = Cudd_Not(one); + var = cuddUniqueInter(ddD,index,one,zero); + if (var == NULL) { + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + return(NULL); + } + res = cuddBddIteRecur(ddD,var,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + + if (st_add_direct(table, (char *) f, (char *) res) == ST_OUT_OF_MEM) { + Cudd_RecursiveDeref(ddD, res); + return(NULL); + } + return(Cudd_NotCond(res,comple)); + +} /* end of cuddBddTransferRecur */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddCache.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddCache.c new file mode 100644 index 000000000..bf98c69e4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddCache.c @@ -0,0 +1,1053 @@ +/**CFile*********************************************************************** + + FileName [cuddCache.c] + + PackageName [cudd] + + Synopsis [Functions for cache insertion and lookup.] + + Description [Internal procedures included in this module: +
    +
  • cuddInitCache() +
  • cuddCacheInsert() +
  • cuddCacheInsert2() +
  • cuddCacheLookup() +
  • cuddCacheLookupZdd() +
  • cuddCacheLookup2() +
  • cuddCacheLookup2Zdd() +
  • cuddConstantLookup() +
  • cuddCacheProfile() +
  • cuddCacheResize() +
  • cuddCacheFlush() +
  • cuddComputeFloorLog2() +
+ Static procedures included in this module: +
    +
] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef DD_CACHE_PROFILE +#define DD_HYSTO_BINS 8 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddCache.c,v 1.36 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes the computed table.] + + Description [Initializes the computed table. It is called by + Cudd_Init. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Init] + +******************************************************************************/ +int +cuddInitCache( + DdManager * unique /* unique table */, + unsigned int cacheSize /* initial size of the cache */, + unsigned int maxCacheSize /* cache size beyond which no resizing occurs */) +{ + int i; + unsigned int logSize; +#ifndef DD_CACHE_PROFILE + DdNodePtr *mem; + ptruint offset; +#endif + + /* Round cacheSize to largest power of 2 not greater than the requested + ** initial cache size. */ + logSize = cuddComputeFloorLog2(ddMax(cacheSize,unique->slots/2)); + cacheSize = 1 << logSize; + unique->acache = ALLOC(DdCache,cacheSize+1); + if (unique->acache == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + /* If the size of the cache entry is a power of 2, we want to + ** enforce alignment to that power of two. This happens when + ** DD_CACHE_PROFILE is not defined. */ +#ifdef DD_CACHE_PROFILE + unique->cache = unique->acache; + unique->memused += (cacheSize) * sizeof(DdCache); +#else + mem = (DdNodePtr *) unique->acache; + offset = (ptruint) mem & (sizeof(DdCache) - 1); + mem += (sizeof(DdCache) - offset) / sizeof(DdNodePtr); + unique->cache = (DdCache *) mem; + assert(((ptruint) unique->cache & (sizeof(DdCache) - 1)) == 0); + unique->memused += (cacheSize+1) * sizeof(DdCache); +#endif + unique->cacheSlots = cacheSize; + unique->cacheShift = sizeof(int) * 8 - logSize; + unique->maxCacheHard = maxCacheSize; + /* If cacheSlack is non-negative, we can resize. */ + unique->cacheSlack = (int) ddMin(maxCacheSize, + DD_MAX_CACHE_TO_SLOTS_RATIO*unique->slots) - + 2 * (int) cacheSize; + Cudd_SetMinHit(unique,DD_MIN_HIT); + /* Initialize to avoid division by 0 and immediate resizing. */ + unique->cacheMisses = (double) (int) (cacheSize * unique->minHit + 1); + unique->cacheHits = 0; + unique->totCachehits = 0; + /* The sum of cacheMisses and totCacheMisses is always correct, + ** even though cacheMisses is larger than it should for the reasons + ** explained above. */ + unique->totCacheMisses = -unique->cacheMisses; + unique->cachecollisions = 0; + unique->cacheinserts = 0; + unique->cacheLastInserts = 0; + unique->cachedeletions = 0; + + /* Initialize the cache */ + for (i = 0; (unsigned) i < cacheSize; i++) { + unique->cache[i].h = 0; /* unused slots */ + unique->cache[i].data = NULL; /* invalid entry */ +#ifdef DD_CACHE_PROFILE + unique->cache[i].count = 0; +#endif + } + + return(1); + +} /* end of cuddInitCache */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in the cache for a function with three + operands.] + + Description [Inserts a result in the cache for a function with three + operands. The operator tag (see cuddInt.h for details) is split and stored + into unused bits of the first two pointers.] + + SideEffects [None] + + SeeAlso [cuddCacheInsert2 cuddCacheInsert1] + +******************************************************************************/ +void +cuddCacheInsert( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h, + DdNode * data) +{ + int posn; + register DdCache *entry; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + posn = ddCHash2(uh,uf,ug,table->cacheShift); + entry = &table->cache[posn]; + + table->cachecollisions += entry->data != NULL; + table->cacheinserts++; + + entry->f = (DdNode *) uf; + entry->g = (DdNode *) ug; + entry->h = uh; + entry->data = data; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddCacheInsert */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in the cache for a function with two + operands.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddCacheInsert cuddCacheInsert1] + +******************************************************************************/ +void +cuddCacheInsert2( + DdManager * table, + DD_CTFP op, + DdNode * f, + DdNode * g, + DdNode * data) +{ + int posn; + register DdCache *entry; + + posn = ddCHash2(op,f,g,table->cacheShift); + entry = &table->cache[posn]; + + if (entry->data != NULL) { + table->cachecollisions++; + } + table->cacheinserts++; + + entry->f = f; + entry->g = g; + entry->h = (ptruint) op; + entry->data = data; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddCacheInsert2 */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in the cache for a function with two + operands.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddCacheInsert cuddCacheInsert2] + +******************************************************************************/ +void +cuddCacheInsert1( + DdManager * table, + DD_CTFP1 op, + DdNode * f, + DdNode * data) +{ + int posn; + register DdCache *entry; + + posn = ddCHash2(op,f,f,table->cacheShift); + entry = &table->cache[posn]; + + if (entry->data != NULL) { + table->cachecollisions++; + } + table->cacheinserts++; + + entry->f = f; + entry->g = f; + entry->h = (ptruint) op; + entry->data = data; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddCacheInsert1 */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f, + g, and h.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup2 cuddCacheLookup1] + +******************************************************************************/ +DdNode * +cuddCacheLookup( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(uh,uf,ug,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug && + en->h==uh) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f, + g, and h.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup2Zdd cuddCacheLookup1Zdd] + +******************************************************************************/ +DdNode * +cuddCacheLookupZdd( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(uh,uf,ug,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug && + en->h==uh) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookupZdd */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f + and g.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup cuddCacheLookup1] + +******************************************************************************/ +DdNode * +cuddCacheLookup2( + DdManager * table, + DD_CTFP op, + DdNode * f, + DdNode * g) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,g,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup2 */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup cuddCacheLookup2] + +******************************************************************************/ +DdNode * +cuddCacheLookup1( + DdManager * table, + DD_CTFP1 op, + DdNode * f) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,f,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup1 */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f + and g.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookupZdd cuddCacheLookup1Zdd] + +******************************************************************************/ +DdNode * +cuddCacheLookup2Zdd( + DdManager * table, + DD_CTFP op, + DdNode * f, + DdNode * g) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,g,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup2Zdd */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookupZdd cuddCacheLookup2Zdd] + +******************************************************************************/ +DdNode * +cuddCacheLookup1Zdd( + DdManager * table, + DD_CTFP1 op, + DdNode * f) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,f,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup1Zdd */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f, + g, and h.] + + Description [Looks up in the cache for the result of op applied to f, + g, and h. Assumes that the calling procedure (e.g., + Cudd_bddIteConstant) is only interested in whether the result is + constant or not. Returns the result if found (possibly + DD_NON_CONSTANT); otherwise it returns NULL.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup] + +******************************************************************************/ +DdNode * +cuddConstantLookup( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h) +{ + int posn; + DdCache *en,*cache; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + posn = ddCHash2(uh,uf,ug,table->cacheShift); + en = &cache[posn]; + + /* We do not reclaim here because the result should not be + * referenced, but only tested for being a constant. + */ + if (en->data != NULL && + en->f == (DdNodePtr)uf && en->g == (DdNodePtr)ug && en->h == uh) { + table->cacheHits++; + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddConstantLookup */ + + +/**Function******************************************************************** + + Synopsis [Computes and prints a profile of the cache usage.] + + Description [Computes and prints a profile of the cache usage. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddCacheProfile( + DdManager * table, + FILE * fp) +{ + DdCache *cache = table->cache; + int slots = table->cacheSlots; + int nzeroes = 0; + int i, retval; + double exUsed; + +#ifdef DD_CACHE_PROFILE + double count, mean, meansq, stddev, expected; + long max, min; + int imax, imin; + double *hystogramQ, *hystogramR; /* histograms by quotient and remainder */ + int nbins = DD_HYSTO_BINS; + int bin; + long thiscount; + double totalcount, exStddev; + + meansq = mean = expected = 0.0; + max = min = (long) cache[0].count; + imax = imin = 0; + totalcount = 0.0; + + hystogramQ = ALLOC(double, nbins); + if (hystogramQ == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + hystogramR = ALLOC(double, nbins); + if (hystogramR == NULL) { + FREE(hystogramQ); + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < nbins; i++) { + hystogramQ[i] = 0; + hystogramR[i] = 0; + } + + for (i = 0; i < slots; i++) { + thiscount = (long) cache[i].count; + if (thiscount > max) { + max = thiscount; + imax = i; + } + if (thiscount < min) { + min = thiscount; + imin = i; + } + if (thiscount == 0) { + nzeroes++; + } + count = (double) thiscount; + mean += count; + meansq += count * count; + totalcount += count; + expected += count * (double) i; + bin = (i * nbins) / slots; + hystogramQ[bin] += (double) thiscount; + bin = i % nbins; + hystogramR[bin] += (double) thiscount; + } + mean /= (double) slots; + meansq /= (double) slots; + + /* Compute the standard deviation from both the data and the + ** theoretical model for a random distribution. */ + stddev = sqrt(meansq - mean*mean); + exStddev = sqrt((1 - 1/(double) slots) * totalcount / (double) slots); + + retval = fprintf(fp,"Cache average accesses = %g\n", mean); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache access standard deviation = %g ", stddev); + if (retval == EOF) return(0); + retval = fprintf(fp,"(expected = %g)\n", exStddev); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache max accesses = %ld for slot %d\n", max, imax); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache min accesses = %ld for slot %d\n", min, imin); + if (retval == EOF) return(0); + exUsed = 100.0 * (1.0 - exp(-totalcount / (double) slots)); + retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n", + 100.0 - (double) nzeroes * 100.0 / (double) slots, + exUsed); + if (retval == EOF) return(0); + + if (totalcount > 0) { + expected /= totalcount; + retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); + if (retval == EOF) return(0); + retval = fprintf(fp," (expected bin value = %g)\nBy quotient:", + expected); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp," %.0f", hystogramQ[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\nBy residue: "); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp," %.0f", hystogramR[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\n"); + if (retval == EOF) return(0); + } + + FREE(hystogramQ); + FREE(hystogramR); +#else + for (i = 0; i < slots; i++) { + nzeroes += cache[i].h == 0; + } + exUsed = 100.0 * + (1.0 - exp(-(table->cacheinserts - table->cacheLastInserts) / + (double) slots)); + retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n", + 100.0 - (double) nzeroes * 100.0 / (double) slots, + exUsed); + if (retval == EOF) return(0); +#endif + return(1); + +} /* end of cuddCacheProfile */ + + +/**Function******************************************************************** + + Synopsis [Resizes the cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddCacheResize( + DdManager * table) +{ + DdCache *cache, *oldcache, *oldacache, *entry, *old; + int i; + int posn, shift; + unsigned int slots, oldslots; + double offset; + int moved = 0; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; +#ifndef DD_CACHE_PROFILE + ptruint misalignment; + DdNodePtr *mem; +#endif + + oldcache = table->cache; + oldacache = table->acache; + oldslots = table->cacheSlots; + slots = table->cacheSlots = oldslots << 1; + +#ifdef DD_VERBOSE + (void) fprintf(table->err,"Resizing the cache from %d to %d entries\n", + oldslots, slots); + (void) fprintf(table->err, + "\thits = %g\tmisses = %g\thit ratio = %5.3f\n", + table->cacheHits, table->cacheMisses, + table->cacheHits / (table->cacheHits + table->cacheMisses)); +#endif + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + table->acache = cache = ALLOC(DdCache,slots+1); + MMoutOfMemory = saveHandler; + /* If we fail to allocate the new table we just give up. */ + if (cache == NULL) { +#ifdef DD_VERBOSE + (void) fprintf(table->err,"Resizing failed. Giving up.\n"); +#endif + table->cacheSlots = oldslots; + table->acache = oldacache; + /* Do not try to resize again. */ + table->maxCacheHard = oldslots - 1; + table->cacheSlack = - (int) (oldslots + 1); + return; + } + /* If the size of the cache entry is a power of 2, we want to + ** enforce alignment to that power of two. This happens when + ** DD_CACHE_PROFILE is not defined. */ +#ifdef DD_CACHE_PROFILE + table->cache = cache; +#else + mem = (DdNodePtr *) cache; + misalignment = (ptruint) mem & (sizeof(DdCache) - 1); + mem += (sizeof(DdCache) - misalignment) / sizeof(DdNodePtr); + table->cache = cache = (DdCache *) mem; + assert(((ptruint) table->cache & (sizeof(DdCache) - 1)) == 0); +#endif + shift = --(table->cacheShift); + table->memused += (slots - oldslots) * sizeof(DdCache); + table->cacheSlack -= slots; /* need these many slots to double again */ + + /* Clear new cache. */ + for (i = 0; (unsigned) i < slots; i++) { + cache[i].data = NULL; + cache[i].h = 0; +#ifdef DD_CACHE_PROFILE + cache[i].count = 0; +#endif + } + + /* Copy from old cache to new one. */ + for (i = 0; (unsigned) i < oldslots; i++) { + old = &oldcache[i]; + if (old->data != NULL) { + posn = ddCHash2(old->h,old->f,old->g,shift); + entry = &cache[posn]; + entry->f = old->f; + entry->g = old->g; + entry->h = old->h; + entry->data = old->data; +#ifdef DD_CACHE_PROFILE + entry->count = 1; +#endif + moved++; + } + } + + FREE(oldacache); + + /* Reinitialize measurements so as to avoid division by 0 and + ** immediate resizing. + */ + offset = (double) (int) (slots * table->minHit + 1); + table->totCacheMisses += table->cacheMisses - offset; + table->cacheMisses = offset; + table->totCachehits += table->cacheHits; + table->cacheHits = 0; + table->cacheLastInserts = table->cacheinserts - (double) moved; + +} /* end of cuddCacheResize */ + + +/**Function******************************************************************** + + Synopsis [Flushes the cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddCacheFlush( + DdManager * table) +{ + int i, slots; + DdCache *cache; + + slots = table->cacheSlots; + cache = table->cache; + for (i = 0; i < slots; i++) { + table->cachedeletions += cache[i].data != NULL; + cache[i].data = NULL; + } + table->cacheLastInserts = table->cacheinserts; + + return; + +} /* end of cuddCacheFlush */ + + +/**Function******************************************************************** + + Synopsis [Returns the floor of the logarithm to the base 2.] + + Description [Returns the floor of the logarithm to the base 2. + The input value is assumed to be greater than 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddComputeFloorLog2( + unsigned int value) +{ + int floorLog = 0; +#ifdef DD_DEBUG + assert(value > 0); +#endif + while (value > 1) { + floorLog++; + value >>= 1; + } + return(floorLog); + +} /* end of cuddComputeFloorLog2 */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddCheck.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddCheck.c new file mode 100644 index 000000000..424aaba39 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddCheck.c @@ -0,0 +1,885 @@ +/**CFile*********************************************************************** + + FileName [cuddCheck.c] + + PackageName [cudd] + + Synopsis [Functions to check consistency of data structures.] + + Description [External procedures included in this module: +
    +
  • Cudd_DebugCheck() +
  • Cudd_CheckKeys() +
+ Internal procedures included in this module: +
    +
  • cuddHeapProfile() +
  • cuddPrintNode() +
  • cuddPrintVarGroups() +
+ Static procedures included in this module: +
    +
  • debugFindParent() +
+ ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddCheck.c,v 1.37 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void debugFindParent (DdManager *table, DdNode *node); +#if 0 +static void debugCheckParent (DdManager *table, DdNode *node); +#endif + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Checks for inconsistencies in the DD heap.] + + Description [Checks for inconsistencies in the DD heap: +
    +
  • node has illegal index +
  • live node has dead children +
  • node has illegal Then or Else pointers +
  • BDD/ADD node has identical children +
  • ZDD node has zero then child +
  • wrong number of total nodes +
  • wrong number of dead nodes +
  • ref count error at node +
+ Returns 0 if no inconsistencies are found; DD_OUT_OF_MEM if there is + not enough memory; 1 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_CheckKeys] + +******************************************************************************/ +int +Cudd_DebugCheck( + DdManager * table) +{ + unsigned int i; + int j,count; + int slots; + DdNodePtr *nodelist; + DdNode *f; + DdNode *sentinel = &(table->sentinel); + st_table *edgeTable; /* stores internal ref count for each node */ + st_generator *gen; + int flag = 0; + int totalNode; + int deadNode; + int index; + int shift; + + edgeTable = st_init_table(st_ptrcmp,st_ptrhash); + if (edgeTable == NULL) return(CUDD_OUT_OF_MEM); + + /* Check the BDD/ADD subtables. */ + for (i = 0; i < (unsigned) table->size; i++) { + index = table->invperm[i]; + if (i != (unsigned) table->perm[index]) { + (void) fprintf(table->err, + "Permutation corrupted: invperm[%u] = %d\t perm[%d] = %d\n", + i, index, index, table->perm[index]); + } + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + shift = table->subtables[i].shift; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { /* for each subtable slot */ + f = nodelist[j]; + while (f != sentinel) { + totalNode++; + if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { + if ((int) f->index != index) { + (void) fprintf(table->err, + "Error: node has illegal index\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if ((unsigned) cuddI(table,cuddT(f)->index) <= i || + (unsigned) cuddI(table,Cudd_Regular(cuddE(f))->index) + <= i) { + (void) fprintf(table->err, + "Error: node has illegal children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (Cudd_Regular(cuddT(f)) != cuddT(f)) { + (void) fprintf(table->err, + "Error: node has illegal form\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f) == cuddE(f)) { + (void) fprintf(table->err, + "Error: node has identical children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f)->ref == 0 || Cudd_Regular(cuddE(f))->ref == 0) { + (void) fprintf(table->err, + "Error: live node has dead children\n"); + cuddPrintNode(f,table->err); + flag =1; + } + if (ddHash(cuddT(f),cuddE(f),shift) != j) { + (void) fprintf(table->err, "Error: misplaced node\n"); + cuddPrintNode(f,table->err); + flag =1; + } + /* Increment the internal reference count for the + ** then child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddT(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + + /* Increment the internal reference count for the + ** else child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)Cudd_Regular(cuddE(f)), + &count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)Cudd_Regular(cuddE(f)), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { + deadNode++; +#if 0 + debugCheckParent(table,f); +#endif + } else { + fprintf(table->err, + "Error: node has illegal Then or Else pointers\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + + f = f->next; + } /* for each element of the collision list */ + } /* for each subtable slot */ + + if ((unsigned) totalNode != table->subtables[i].keys) { + fprintf(table->err,"Error: wrong number of total nodes\n"); + flag = 1; + } + if ((unsigned) deadNode != table->subtables[i].dead) { + fprintf(table->err,"Error: wrong number of dead nodes\n"); + flag = 1; + } + } /* for each BDD/ADD subtable */ + + /* Check the ZDD subtables. */ + for (i = 0; i < (unsigned) table->sizeZ; i++) { + index = table->invpermZ[i]; + if (i != (unsigned) table->permZ[index]) { + (void) fprintf(table->err, + "Permutation corrupted: invpermZ[%u] = %d\t permZ[%d] = %d in ZDD\n", + i, index, index, table->permZ[index]); + } + nodelist = table->subtableZ[i].nodelist; + slots = table->subtableZ[i].slots; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { /* for each subtable slot */ + f = nodelist[j]; + while (f != NULL) { + totalNode++; + if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { + if ((int) f->index != index) { + (void) fprintf(table->err, + "Error: ZDD node has illegal index\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (Cudd_IsComplement(cuddT(f)) || + Cudd_IsComplement(cuddE(f))) { + (void) fprintf(table->err, + "Error: ZDD node has complemented children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if ((unsigned) cuddIZ(table,cuddT(f)->index) <= i || + (unsigned) cuddIZ(table,cuddE(f)->index) <= i) { + (void) fprintf(table->err, + "Error: ZDD node has illegal children\n"); + cuddPrintNode(f,table->err); + cuddPrintNode(cuddT(f),table->err); + cuddPrintNode(cuddE(f),table->err); + flag = 1; + } + if (cuddT(f) == DD_ZERO(table)) { + (void) fprintf(table->err, + "Error: ZDD node has zero then child\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f)->ref == 0 || cuddE(f)->ref == 0) { + (void) fprintf(table->err, + "Error: ZDD live node has dead children\n"); + cuddPrintNode(f,table->err); + flag =1; + } + /* Increment the internal reference count for the + ** then child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddT(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + + /* Increment the internal reference count for the + ** else child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddE(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddE(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + table->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { + deadNode++; +#if 0 + debugCheckParent(table,f); +#endif + } else { + fprintf(table->err, + "Error: ZDD node has illegal Then or Else pointers\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + + f = f->next; + } /* for each element of the collision list */ + } /* for each subtable slot */ + + if ((unsigned) totalNode != table->subtableZ[i].keys) { + fprintf(table->err, + "Error: wrong number of total nodes in ZDD\n"); + flag = 1; + } + if ((unsigned) deadNode != table->subtableZ[i].dead) { + fprintf(table->err, + "Error: wrong number of dead nodes in ZDD\n"); + flag = 1; + } + } /* for each ZDD subtable */ + + /* Check the constant table. */ + nodelist = table->constants.nodelist; + slots = table->constants.slots; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != NULL) { + totalNode++; + if (f->ref != 0) { + if (f->index != CUDD_CONST_INDEX) { + fprintf(table->err,"Error: node has illegal index\n"); +#if SIZEOF_VOID_P == 8 + fprintf(table->err, + " node 0x%lx, id = %u, ref = %u, value = %g\n", + (ptruint)f,f->index,f->ref,cuddV(f)); +#else + fprintf(table->err, + " node 0x%x, id = %hu, ref = %hu, value = %g\n", + (ptruint)f,f->index,f->ref,cuddV(f)); +#endif + flag = 1; + } + } else { + deadNode++; + } + f = f->next; + } + } + if ((unsigned) totalNode != table->constants.keys) { + (void) fprintf(table->err, + "Error: wrong number of total nodes in constants\n"); + flag = 1; + } + if ((unsigned) deadNode != table->constants.dead) { + (void) fprintf(table->err, + "Error: wrong number of dead nodes in constants\n"); + flag = 1; + } + gen = st_init_gen(edgeTable); + while (st_gen(gen, &f, &count)) { + if (count > (int)(f->ref) && f->ref != DD_MAXREF) { +#if SIZEOF_VOID_P == 8 + fprintf(table->err,"ref count error at node 0x%lx, count = %d, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#else + fprintf(table->err,"ref count error at node 0x%x, count = %d, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#endif + debugFindParent(table,f); + flag = 1; + } + } + st_free_gen(gen); + st_free_table(edgeTable); + + return (flag); + +} /* end of Cudd_DebugCheck */ + + +/**Function******************************************************************** + + Synopsis [Checks for several conditions that should not occur.] + + Description [Checks for the following conditions: +
    +
  • Wrong sizes of subtables. +
  • Wrong number of keys found in unique subtable. +
  • Wrong number of dead found in unique subtable. +
  • Wrong number of keys found in the constant table +
  • Wrong number of dead found in the constant table +
  • Wrong number of total slots found +
  • Wrong number of maximum keys found +
  • Wrong number of total dead found +
+ Reports the average length of non-empty lists. Returns the number of + subtables for which the number of keys is wrong.] + + SideEffects [None] + + SeeAlso [Cudd_DebugCheck] + +******************************************************************************/ +int +Cudd_CheckKeys( + DdManager * table) +{ + int size; + int i,j; + DdNodePtr *nodelist; + DdNode *node; + DdNode *sentinel = &(table->sentinel); + DdSubtable *subtable; + int keys; + int dead; + int count = 0; + int totalKeys = 0; + int totalSlots = 0; + int totalDead = 0; + int nonEmpty = 0; + unsigned int slots; + int logSlots; + int shift; + + size = table->size; + + for (i = 0; i < size; i++) { + subtable = &(table->subtables[i]); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + slots = subtable->slots; + shift = subtable->shift; + logSlots = sizeof(int) * 8 - shift; + if (((slots >> logSlots) << logSlots) != slots) { + (void) fprintf(table->err, + "Unique table %d is not the right power of 2\n", i); + (void) fprintf(table->err, + " slots = %u shift = %d\n", slots, shift); + } + totalSlots += slots; + totalDead += dead; + for (j = 0; (unsigned) j < slots; j++) { + node = nodelist[j]; + if (node != sentinel) { + nonEmpty++; + } + while (node != sentinel) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } + } + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ +in unique table %d (difference=%d)\n", i, keys); + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ +in unique table no. %d (difference=%d)\n", i, dead); + } + } /* for each BDD/ADD subtable */ + + /* Check the ZDD subtables. */ + size = table->sizeZ; + + for (i = 0; i < size; i++) { + subtable = &(table->subtableZ[i]); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + totalSlots += subtable->slots; + totalDead += dead; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + nonEmpty++; + } + while (node != NULL) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } + } + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ +in ZDD unique table no. %d (difference=%d)\n", i, keys); + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ +in ZDD unique table no. %d (difference=%d)\n", i, dead); + } + } /* for each ZDD subtable */ + + /* Check the constant table. */ + subtable = &(table->constants); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + totalSlots += subtable->slots; + totalDead += dead; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + nonEmpty++; + } + while (node != NULL) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } + } + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ +in the constant table (difference=%d)\n", keys); + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ +in the constant table (difference=%d)\n", dead); + } + if ((unsigned) totalKeys != table->keys + table->keysZ) { + (void) fprintf(table->err, "Wrong number of total keys found \ +(difference=%d)\n", (int) (totalKeys-table->keys)); + } + if ((unsigned) totalSlots != table->slots) { + (void) fprintf(table->err, "Wrong number of total slots found \ +(difference=%d)\n", (int) (totalSlots-table->slots)); + } + if (table->minDead != (unsigned) (table->gcFrac * table->slots)) { + (void) fprintf(table->err, "Wrong number of minimum dead found \ +(%u vs. %u)\n", table->minDead, + (unsigned) (table->gcFrac * (double) table->slots)); + } + if ((unsigned) totalDead != table->dead + table->deadZ) { + (void) fprintf(table->err, "Wrong number of total dead found \ +(difference=%d)\n", (int) (totalDead-table->dead)); + } + (void) fprintf(table->out,"Average length of non-empty lists = %g\n", + (double) table->keys / (double) nonEmpty); + + return(count); + +} /* end of Cudd_CheckKeys */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints information about the heap.] + + Description [Prints to the manager's stdout the number of live nodes for each + level of the DD heap that contains at least one live node. It also + prints a summary containing: +
    +
  • total number of tables; +
  • number of tables with live nodes; +
  • table with the largest number of live nodes; +
  • number of nodes in that table. +
+ If more than one table contains the maximum number of live nodes, + only the one of lowest index is reported. Returns 1 in case of success + and 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddHeapProfile( + DdManager * dd) +{ + int ntables = dd->size; + DdSubtable *subtables = dd->subtables; + int i, /* loop index */ + nodes, /* live nodes in i-th layer */ + retval, /* return value of fprintf */ + largest = -1, /* index of the table with most live nodes */ + maxnodes = -1, /* maximum number of live nodes in a table */ + nonempty = 0; /* number of tables with live nodes */ + + /* Print header. */ +#if SIZEOF_VOID_P == 8 + retval = fprintf(dd->out,"*** DD heap profile for 0x%lx ***\n", + (ptruint) dd); +#else + retval = fprintf(dd->out,"*** DD heap profile for 0x%x ***\n", + (ptruint) dd); +#endif + if (retval == EOF) return 0; + + /* Print number of live nodes for each nonempty table. */ + for (i=0; iout,"%5d: %5d nodes\n", i, nodes); + if (retval == EOF) return 0; + if (nodes > maxnodes) { + maxnodes = nodes; + largest = i; + } + } + } + + nodes = dd->constants.keys - dd->constants.dead; + if (nodes) { + nonempty++; + retval = fprintf(dd->out,"const: %5d nodes\n", nodes); + if (retval == EOF) return 0; + if (nodes > maxnodes) { + maxnodes = nodes; + largest = CUDD_CONST_INDEX; + } + } + + /* Print summary. */ + retval = fprintf(dd->out,"Summary: %d tables, %d non-empty, largest: %d ", + ntables+1, nonempty, largest); + if (retval == EOF) return 0; + retval = fprintf(dd->out,"(with %d nodes)\n", maxnodes); + if (retval == EOF) return 0; + + return(1); + +} /* end of cuddHeapProfile */ + + +/**Function******************************************************************** + + Synopsis [Prints out information on a node.] + + Description [Prints out information on a node.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddPrintNode( + DdNode * f, + FILE *fp) +{ + f = Cudd_Regular(f); +#if SIZEOF_VOID_P == 8 + (void) fprintf(fp," node 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#else + (void) fprintf(fp," node 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#endif + +} /* end of cuddPrintNode */ + + + +/**Function******************************************************************** + + Synopsis [Prints the variable groups as a parenthesized list.] + + Description [Prints the variable groups as a parenthesized list. + For each group the level range that it represents is printed. After + each group, the group's flags are printed, preceded by a `|'. For + each flag (except MTR_TERMINAL) a character is printed. +
    +
  • F: MTR_FIXED +
  • N: MTR_NEWNODE +
  • S: MTR_SOFT +
+ The second argument, silent, if different from 0, causes + Cudd_PrintVarGroups to only check the syntax of the group tree.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddPrintVarGroups( + DdManager * dd /* manager */, + MtrNode * root /* root of the group tree */, + int zdd /* 0: BDD; 1: ZDD */, + int silent /* flag to check tree syntax only */) +{ + MtrNode *node; + int level; + + assert(root != NULL); + assert(root->younger == NULL || root->younger->elder == root); + assert(root->elder == NULL || root->elder->younger == root); + if (zdd) { + level = dd->permZ[root->index]; + } else { + level = dd->perm[root->index]; + } + if (!silent) (void) printf("(%d",level); + if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) { + if (!silent) (void) printf(","); + } else { + node = root->child; + while (node != NULL) { + assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size)); + assert(node->parent == root); + cuddPrintVarGroups(dd,node,zdd,silent); + node = node->younger; + } + } + if (!silent) { + (void) printf("%d", (int) (level + root->size - 1)); + if (root->flags != MTR_DEFAULT) { + (void) printf("|"); + if (MTR_TEST(root,MTR_FIXED)) (void) printf("F"); + if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N"); + if (MTR_TEST(root,MTR_SOFT)) (void) printf("S"); + } + (void) printf(")"); + if (root->parent == NULL) (void) printf("\n"); + } + assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0); + return; + +} /* end of cuddPrintVarGroups */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Searches the subtables above node for its parents.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +debugFindParent( + DdManager * table, + DdNode * node) +{ + int i,j; + int slots; + DdNodePtr *nodelist; + DdNode *f; + + for (i = 0; i < cuddI(table,node->index); i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + for (j=0;jout,"parent is at 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n", + (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#else + (void) fprintf(table->out,"parent is at 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n", + (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#endif + } + f = f->next; + } + } + } + +} /* end of debugFindParent */ + + +#if 0 +/**Function******************************************************************** + + Synopsis [Reports an error if a (dead) node has a non-dead parent.] + + Description [Searches all the subtables above node. Very expensive. + The same check is now implemented more efficiently in ddDebugCheck.] + + SideEffects [None] + + SeeAlso [debugFindParent] + +******************************************************************************/ +static void +debugCheckParent( + DdManager * table, + DdNode * node) +{ + int i,j; + int slots; + DdNode **nodelist,*f; + + for (i = 0; i < cuddI(table,node->index); i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + for (j=0;jref != 0) { + (void) fprintf(table->err, + "error with zero ref count\n"); + (void) fprintf(table->err,"parent is 0x%x, id = %u, ref = %u, then = 0x%x, else = 0x%x\n",f,f->index,f->ref,cuddT(f),cuddE(f)); + (void) fprintf(table->err,"child is 0x%x, id = %u, ref = %u, then = 0x%x, else = 0x%x\n",node,node->index,node->ref,cuddT(node),cuddE(node)); + } + f = f->next; + } + } + } +} +#endif diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddClip.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddClip.c new file mode 100644 index 000000000..2993254ff --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddClip.c @@ -0,0 +1,558 @@ +/**CFile*********************************************************************** + + FileName [cuddClip.c] + + PackageName [cudd] + + Synopsis [Clipping functions.] + + Description [External procedures included in this module: +
    +
  • Cudd_bddClippingAnd() +
  • Cudd_bddClippingAndAbstract() +
+ Internal procedures included in this module: +
    +
  • cuddBddClippingAnd() +
  • cuddBddClippingAndAbstract() +
+ Static procedures included in this module: +
    +
  • cuddBddClippingAndRecur() +
  • cuddBddClipAndAbsRecur() +
+ + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.9 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * cuddBddClippingAndRecur (DdManager *manager, DdNode *f, DdNode *g, int distance, int direction); +static DdNode * cuddBddClipAndAbsRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, int distance, int direction); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g.] + + Description [Approximates the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddClippingAnd( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddClippingAnd(dd,f,g,maxDepth,direction); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddClippingAnd */ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube.] + + Description [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. The variables are + existentially abstracted. Returns a pointer to the resulting BDD if + successful; NULL if the intermediate result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract Cudd_bddClippingAnd] + +******************************************************************************/ +DdNode * +Cudd_bddClippingAndAbstract( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + DdNode * cube /* cube of variables to be abstracted */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddClippingAndAbstract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g.] + + Description [Approximates the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddClippingAnd] + +******************************************************************************/ +DdNode * +cuddBddClippingAnd( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + res = cuddBddClippingAndRecur(dd,f,g,maxDepth,direction); + + return(res); + +} /* end of cuddBddClippingAnd */ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube.] + + Description [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddClippingAndAbstract] + +******************************************************************************/ +DdNode * +cuddBddClippingAndAbstract( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + DdNode * cube /* cube of variables to be abstracted */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + res = cuddBddClipAndAbsRecur(dd,f,g,cube,maxDepth,direction); + + return(res); + +} /* end of cuddBddClippingAndAbstract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddClippingAnd.] + + Description [Implements the recursive step of Cudd_bddClippingAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddBddClippingAnd] + +******************************************************************************/ +static DdNode * +cuddBddClippingAndRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + int distance, + int direction) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *zero, *r, *t, *e; + unsigned int topf, topg, index; + DD_CTFP cacheOp; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == g || g == one) return(f); + if (f == one) return(g); + if (distance == 0) { + /* One last attempt at returning the right result. We sort of + ** cheat by calling Cudd_bddLeq. */ + if (Cudd_bddLeq(manager,f,g)) return(f); + if (Cudd_bddLeq(manager,g,f)) return(g); + if (direction == 1) { + if (Cudd_bddLeq(manager,f,Cudd_Not(g)) || + Cudd_bddLeq(manager,g,Cudd_Not(f))) return(zero); + } + return(Cudd_NotCond(one,(direction == 0))); + } + + /* At this point f and g are not constant. */ + distance--; + + /* Check cache. Try to increase cache efficiency by sorting the + ** pointers. */ + if (f > g) { + DdNode *tmp = f; + f = g; g = tmp; + } + F = Cudd_Regular(f); + G = Cudd_Regular(g); + cacheOp = (DD_CTFP) + (direction ? Cudd_bddClippingAnd : cuddBddClippingAnd); + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup2(manager, cacheOp, f, g); + if (r != NULL) return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg <= topf) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + t = cuddBddClippingAndRecur(manager, ft, gt, distance, direction); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddClippingAndRecur(manager, fe, ge, distance, direction); + if (e == NULL) { + Cudd_RecursiveDeref(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert2(manager, cacheOp, f, g, r); + return(r); + +} /* end of cuddBddClippingAndRecur */ + + +/**Function******************************************************************** + + Synopsis [Approximates the AND of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Approximates the AND of two BDDs and simultaneously + abstracts the variables in cube. The variables are existentially + abstracted. Returns a pointer to the result is successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddClippingAndAbstract] + +******************************************************************************/ +static DdNode * +cuddBddClipAndAbsRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube, + int distance, + int direction) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *zero, *r, *t, *e, *Cube; + unsigned int topf, topg, topcube, top, index; + ptruint cacheTag; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == one && g == one) return(one); + if (cube == one) { + return(cuddBddClippingAndRecur(manager, f, g, distance, direction)); + } + if (f == one || f == g) { + return (cuddBddExistAbstractRecur(manager, g, cube)); + } + if (g == one) { + return (cuddBddExistAbstractRecur(manager, f, cube)); + } + if (distance == 0) return(Cudd_NotCond(one,(direction == 0))); + + /* At this point f, g, and cube are not constant. */ + distance--; + + /* Check cache. */ + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; g = tmp; + } + F = Cudd_Regular(f); + G = Cudd_Regular(g); + cacheTag = direction ? DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG : + DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG; + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup(manager, cacheTag, + f, g, cube); + if (r != NULL) { + return(r); + } + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + top = ddMin(topf, topg); + topcube = manager->perm[cube->index]; + + if (topcube < top) { + return(cuddBddClipAndAbsRecur(manager, f, g, cuddT(cube), + distance, direction)); + } + /* Now, topcube >= top. */ + + if (topf == top) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg == top) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + if (topcube == top) { + Cube = cuddT(cube); + } else { + Cube = cube; + } + + t = cuddBddClipAndAbsRecur(manager, ft, gt, Cube, distance, direction); + if (t == NULL) return(NULL); + + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. + */ + if (t == one && topcube == top) { + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, cacheTag, f, g, cube, one); + return(one); + } + cuddRef(t); + + e = cuddBddClipAndAbsRecur(manager, fe, ge, Cube, distance, direction); + if (e == NULL) { + Cudd_RecursiveDeref(manager, t); + return(NULL); + } + cuddRef(e); + + if (topcube == top) { /* abstract */ + r = cuddBddClippingAndRecur(manager, Cudd_Not(t), Cudd_Not(e), + distance, (direction == 0)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + cuddDeref(r); + } else if (t == e) { + r = t; + cuddDeref(t); + cuddDeref(e); + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + } + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, cacheTag, f, g, cube, r); + return (r); + +} /* end of cuddBddClipAndAbsRecur */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddCof.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddCof.c new file mode 100644 index 000000000..cff47b20a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddCof.c @@ -0,0 +1,327 @@ +/**CFile*********************************************************************** + + FileName [cuddCof.c] + + PackageName [cudd] + + Synopsis [Cofactoring functions.] + + Description [External procedures included in this module: +
    +
  • Cudd_Cofactor() +
  • Cudd_CheckCube() +
+ Internal procedures included in this module: +
    +
  • cuddGetBranches() +
  • cuddCofactorRecur() +
+ ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddCof.c,v 1.11 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the cofactor of f with respect to g.] + + Description [Computes the cofactor of f with respect to g; g must be + the BDD or the ADD of a cube. Returns a pointer to the cofactor if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_Cofactor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res,*zero; + + zero = Cudd_Not(DD_ONE(dd)); + if (g == zero || g == DD_ZERO(dd)) { + (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + do { + dd->reordered = 0; + res = cuddCofactorRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_Cofactor */ + + +/**Function******************************************************************** + + Synopsis [Checks whether g is the BDD of a cube.] + + Description [Checks whether g is the BDD of a cube. Returns 1 in case + of success; 0 otherwise. The constant 1 is a valid cube, but all other + constant functions cause cuddCheckCube to return 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_CheckCube( + DdManager * dd, + DdNode * g) +{ + DdNode *g1,*g0,*one,*zero; + + one = DD_ONE(dd); + if (g == one) return(1); + if (Cudd_IsConstant(g)) return(0); + + zero = Cudd_Not(one); + cuddGetBranches(g,&g1,&g0); + + if (g0 == zero) { + return(Cudd_CheckCube(dd, g1)); + } + if (g1 == zero) { + return(Cudd_CheckCube(dd, g0)); + } + return(0); + +} /* end of Cudd_CheckCube */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the children of g.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddGetBranches( + DdNode * g, + DdNode ** g1, + DdNode ** g0) +{ + DdNode *G = Cudd_Regular(g); + + *g1 = cuddT(G); + *g0 = cuddE(G); + if (Cudd_IsComplement(g)) { + *g1 = Cudd_Not(*g1); + *g0 = Cudd_Not(*g0); + } + +} /* end of cuddGetBranches */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_Cofactor.] + + Description [Performs the recursive step of Cudd_Cofactor. Returns a + pointer to the cofactor if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Cofactor] + +******************************************************************************/ +DdNode * +cuddCofactorRecur( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *one,*zero,*F,*G,*g1,*g0,*f1,*f0,*t,*e,*r; + unsigned int topf,topg; + int comple; + + statLine(dd); + F = Cudd_Regular(f); + if (cuddIsConstant(F)) return(f); + + one = DD_ONE(dd); + + /* The invariant g != 0 is true on entry to this procedure and is + ** recursively maintained by it. Therefore it suffices to test g + ** against one to make sure it is not constant. + */ + if (g == one) return(f); + /* From now on, f and g are known not to be constants. */ + + comple = f != F; + r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + topf = dd->perm[F->index]; + G = Cudd_Regular(g); + topg = dd->perm[G->index]; + + /* We take the cofactors of F because we are going to rely on + ** the fact that the cofactors of the complement are the complements + ** of the cofactors to better utilize the cache. Variable comple + ** remembers whether we have to complement the result or not. + */ + if (topf <= topg) { + f1 = cuddT(F); f0 = cuddE(F); + } else { + f1 = f0 = F; + } + if (topg <= topf) { + g1 = cuddT(G); g0 = cuddE(G); + if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); } + } else { + g1 = g0 = g; + } + + zero = Cudd_Not(one); + if (topf >= topg) { + if (g0 == zero || g0 == DD_ZERO(dd)) { + r = cuddCofactorRecur(dd, f1, g1); + } else if (g1 == zero || g1 == DD_ZERO(dd)) { + r = cuddCofactorRecur(dd, f0, g0); + } else { + (void) fprintf(dd->out, + "Cudd_Cofactor: Invalid restriction 2\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + if (r == NULL) return(NULL); + } else /* if (topf < topg) */ { + t = cuddCofactorRecur(dd, f1, g); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddCofactorRecur(dd, f0, g); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e)); + if (r != NULL) + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(dd,(int)F->index,t,e); + } + if (r == NULL) { + Cudd_RecursiveDeref(dd ,e); + Cudd_RecursiveDeref(dd ,t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(dd,Cudd_Cofactor,F,g,r); + + return(Cudd_NotCond(r,comple)); + +} /* end of cuddCofactorRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddCompose.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddCompose.c new file mode 100644 index 000000000..eea044f59 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddCompose.c @@ -0,0 +1,1749 @@ +/**CFile*********************************************************************** + + FileName [cuddCompose.c] + + PackageName [cudd] + + Synopsis [Functional composition and variable permutation of DDs.] + + Description [External procedures included in this module: +
    +
  • Cudd_bddCompose() +
  • Cudd_addCompose() +
  • Cudd_addPermute() +
  • Cudd_addSwapVariables() +
  • Cudd_bddPermute() +
  • Cudd_bddVarMap() +
  • Cudd_SetVarMap() +
  • Cudd_bddSwapVariables() +
  • Cudd_bddAdjPermuteX() +
  • Cudd_addVectorCompose() +
  • Cudd_addGeneralVectorCompose() +
  • Cudd_addNonSimCompose() +
  • Cudd_bddVectorCompose() +
+ Internal procedures included in this module: +
    +
  • cuddBddComposeRecur() +
  • cuddAddComposeRecur() +
+ Static procedures included in this module: +
    +
  • cuddAddPermuteRecur() +
  • cuddBddPermuteRecur() +
  • cuddBddVarMapRecur() +
  • cuddAddVectorComposeRecur() +
  • cuddAddGeneralVectorComposeRecur() +
  • cuddAddNonSimComposeRecur() +
  • cuddBddVectorComposeRecur() +
  • ddIsIthAddVar() +
  • ddIsIthAddVarPair() +
+ The permutation functions use a local cache because the results to + be remembered depend on the permutation being applied. Since the + permutation is just an array, it cannot be stored in the global + cache. There are different procedured for BDDs and ADDs. This is + because bddPermuteRecur uses cuddBddIteRecur. If this were changed, + the procedures could be merged.] + + Author [Fabio Somenzi and Kavita Ravi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddCompose.c,v 1.46 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef DD_DEBUG +static int addPermuteRecurHits; +static int bddPermuteRecurHits; +static int bddVectorComposeHits; +static int addVectorComposeHits; + +static int addGeneralVectorComposeHits; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * cuddAddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut); +static DdNode * cuddBddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut); +static DdNode * cuddBddVarMapRecur (DdManager *manager, DdNode *f); +static DdNode * cuddAddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest); +static DdNode * cuddAddNonSimComposeRecur (DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub); +static DdNode * cuddBddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest); +DD_INLINE static int ddIsIthAddVar (DdManager *dd, DdNode *f, unsigned int i); + +static DdNode * cuddAddGeneralVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest); +DD_INLINE static int ddIsIthAddVarPair (DdManager *dd, DdNode *f, DdNode *g, unsigned int i); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Substitutes g for x_v in the BDD for f.] + + Description [Substitutes g for x_v in the BDD for f. v is the index of the + variable to be substituted. Cudd_bddCompose passes the corresponding + projection function to the recursive procedure, so that the cache may + be used. Returns the composed BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCompose] + +******************************************************************************/ +DdNode * +Cudd_bddCompose( + DdManager * dd, + DdNode * f, + DdNode * g, + int v) +{ + DdNode *proj, *res; + + /* Sanity check. */ + if (v < 0 || v >= dd->size) return(NULL); + + proj = dd->vars[v]; + do { + dd->reordered = 0; + res = cuddBddComposeRecur(dd,f,g,proj); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddCompose */ + + +/**Function******************************************************************** + + Synopsis [Substitutes g for x_v in the ADD for f.] + + Description [Substitutes g for x_v in the ADD for f. v is the index of the + variable to be substituted. g must be a 0-1 ADD. Cudd_bddCompose passes + the corresponding projection function to the recursive procedure, so + that the cache may be used. Returns the composed ADD if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddCompose] + +******************************************************************************/ +DdNode * +Cudd_addCompose( + DdManager * dd, + DdNode * f, + DdNode * g, + int v) +{ + DdNode *proj, *res; + + /* Sanity check. */ + if (v < 0 || v >= dd->size) return(NULL); + + proj = dd->vars[v]; + do { + dd->reordered = 0; + res = cuddAddComposeRecur(dd,f,g,proj); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addCompose */ + + +/**Function******************************************************************** + + Synopsis [Permutes the variables of an ADD.] + + Description [Given a permutation in array permut, creates a new ADD + with permuted variables. There should be an entry in array permut + for each variable in the manager. The i-th entry of permut holds the + index of the variable that is to substitute the i-th + variable. Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_addSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_addPermute( + DdManager * manager, + DdNode * node, + int * permut) +{ + DdHashTable *table; + DdNode *res; + + do { + manager->reordered = 0; + table = cuddHashTableInit(manager,1,2); + if (table == NULL) return(NULL); + /* Recursively solve the problem. */ + res = cuddAddPermuteRecur(manager,table,node,permut); + if (res != NULL) cuddRef(res); + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (manager->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addPermute */ + + +/**Function******************************************************************** + + Synopsis [Swaps two sets of variables of the same size (x and y) in + the ADD f.] + + Description [Swaps two sets of variables of the same size (x and y) in + the ADD f. The size is given by n. The two sets of variables are + assumed to be disjoint. Returns a pointer to the resulting ADD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addPermute Cudd_bddSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_addSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *swapped; + int i, j, k; + int *permut; + + permut = ALLOC(int,dd->size); + if (permut == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) permut[i] = i; + for (i = 0; i < n; i++) { + j = x[i]->index; + k = y[i]->index; + permut[j] = k; + permut[k] = j; + } + + swapped = Cudd_addPermute(dd,f,permut); + FREE(permut); + + return(swapped); + +} /* end of Cudd_addSwapVariables */ + + +/**Function******************************************************************** + + Synopsis [Permutes the variables of a BDD.] + + Description [Given a permutation in array permut, creates a new BDD + with permuted variables. There should be an entry in array permut + for each variable in the manager. The i-th entry of permut holds the + index of the variable that is to substitute the i-th variable. + Returns a pointer to the resulting BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addPermute Cudd_bddSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_bddPermute( + DdManager * manager, + DdNode * node, + int * permut) +{ + DdHashTable *table; + DdNode *res; + + do { + manager->reordered = 0; + table = cuddHashTableInit(manager,1,2); + if (table == NULL) return(NULL); + res = cuddBddPermuteRecur(manager,table,node,permut); + if (res != NULL) cuddRef(res); + /* Dispose of local cache. */ + cuddHashTableQuit(table); + + } while (manager->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_bddPermute */ + + +/**Function******************************************************************** + + Synopsis [Remaps the variables of a BDD using the default variable map.] + + Description [Remaps the variables of a BDD using the default + variable map. A typical use of this function is to swap two sets of + variables. The variable map must be registered with Cudd_SetVarMap. + Returns a pointer to the resulting BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables Cudd_SetVarMap] + +******************************************************************************/ +DdNode * +Cudd_bddVarMap( + DdManager * manager /* DD manager */, + DdNode * f /* function in which to remap variables */) +{ + DdNode *res; + + if (manager->map == NULL) return(NULL); + do { + manager->reordered = 0; + res = cuddBddVarMapRecur(manager, f); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddVarMap */ + + +/**Function******************************************************************** + + Synopsis [Registers a variable mapping with the manager.] + + Description [Registers with the manager a variable mapping described + by two sets of variables. This variable mapping is then used by + functions like Cudd_bddVarMap. This function is convenient for + those applications that perform the same mapping several times. + However, if several different permutations are used, it may be more + efficient not to rely on the registered mapping, because changing + mapping causes the cache to be cleared. (The initial setting, + however, does not clear the cache.) The two sets of variables (x and + y) must have the same size (x and y). The size is given by n. The + two sets of variables are normally disjoint, but this restriction is + not imposeded by the function. When new variables are created, the + map is automatically extended (each new variable maps to + itself). The typical use, however, is to wait until all variables + are created, and then create the map. Returns 1 if the mapping is + successfully registered with the manager; 0 otherwise.] + + SideEffects [Modifies the manager. May clear the cache.] + + SeeAlso [Cudd_bddVarMap Cudd_bddPermute Cudd_bddSwapVariables] + +******************************************************************************/ +int +Cudd_SetVarMap ( + DdManager *manager /* DD manager */, + DdNode **x /* first array of variables */, + DdNode **y /* second array of variables */, + int n /* length of both arrays */) +{ + int i; + + if (manager->map != NULL) { + cuddCacheFlush(manager); + } else { + manager->map = ALLOC(int,manager->maxSize); + if (manager->map == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(0); + } + manager->memused += sizeof(int) * manager->maxSize; + } + /* Initialize the map to the identity. */ + for (i = 0; i < manager->size; i++) { + manager->map[i] = i; + } + /* Create the map. */ + for (i = 0; i < n; i++) { + manager->map[x[i]->index] = y[i]->index; + manager->map[y[i]->index] = x[i]->index; + } + return(1); + +} /* end of Cudd_SetVarMap */ + + +/**Function******************************************************************** + + Synopsis [Swaps two sets of variables of the same size (x and y) in + the BDD f.] + + Description [Swaps two sets of variables of the same size (x and y) + in the BDD f. The size is given by n. The two sets of variables are + assumed to be disjoint. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_addSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_bddSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *swapped; + int i, j, k; + int *permut; + + permut = ALLOC(int,dd->size); + if (permut == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) permut[i] = i; + for (i = 0; i < n; i++) { + j = x[i]->index; + k = y[i]->index; + permut[j] = k; + permut[k] = j; + } + + swapped = Cudd_bddPermute(dd,f,permut); + FREE(permut); + + return(swapped); + +} /* end of Cudd_bddSwapVariables */ + + +/**Function******************************************************************** + + Synopsis [Rearranges a set of variables in the BDD B.] + + Description [Rearranges a set of variables in the BDD B. The size of + the set is given by n. This procedure is intended for the + `randomization' of the priority functions. Returns a pointer to the + BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables + Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_PrioritySelect] + +******************************************************************************/ +DdNode * +Cudd_bddAdjPermuteX( + DdManager * dd, + DdNode * B, + DdNode ** x, + int n) +{ + DdNode *swapped; + int i, j, k; + int *permut; + + permut = ALLOC(int,dd->size); + if (permut == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) permut[i] = i; + for (i = 0; i < n-2; i += 3) { + j = x[i]->index; + k = x[i+1]->index; + permut[j] = k; + permut[k] = j; + } + + swapped = Cudd_bddPermute(dd,B,permut); + FREE(permut); + + return(swapped); + +} /* end of Cudd_bddAdjPermuteX */ + + +/**Function******************************************************************** + + Synopsis [Composes an ADD with a vector of 0-1 ADDs.] + + Description [Given a vector of 0-1 ADDs, creates a new ADD by + substituting the 0-1 ADDs for the variables of the ADD f. There + should be an entry in vector for each variable in the manager. + If no substitution is sought for a given variable, the corresponding + projection function should be specified in the vector. + This function implements simultaneous composition. + Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNonSimCompose Cudd_addPermute Cudd_addCompose + Cudd_bddVectorCompose] + +******************************************************************************/ +DdNode * +Cudd_addVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector) +{ + DdHashTable *table; + DdNode *res; + int deepest; + int i; + + do { + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (!ddIsIthAddVar(dd,vector[i],i)) { + break; + } + } + + /* Recursively solve the problem. */ + res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest); + if (res != NULL) cuddRef(res); + + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (dd->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addVectorCompose */ + + +/**Function******************************************************************** + + Synopsis [Composes an ADD with a vector of ADDs.] + + Description [Given a vector of ADDs, creates a new ADD by substituting the + ADDs for the variables of the ADD f. vectorOn contains ADDs to be substituted + for the x_v and vectorOff the ADDs to be substituted for x_v'. There should + be an entry in vector for each variable in the manager. If no substitution + is sought for a given variable, the corresponding projection function should + be specified in the vector. This function implements simultaneous + composition. Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addVectorCompose Cudd_addNonSimCompose Cudd_addPermute + Cudd_addCompose Cudd_bddVectorCompose] + +******************************************************************************/ +DdNode * +Cudd_addGeneralVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vectorOn, + DdNode ** vectorOff) +{ + DdHashTable *table; + DdNode *res; + int deepest; + int i; + + do { + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) { + break; + } + } + + /* Recursively solve the problem. */ + res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn, + vectorOff,deepest); + if (res != NULL) cuddRef(res); + + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (dd->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addGeneralVectorCompose */ + + +/**Function******************************************************************** + + Synopsis [Composes an ADD with a vector of 0-1 ADDs.] + + Description [Given a vector of 0-1 ADDs, creates a new ADD by + substituting the 0-1 ADDs for the variables of the ADD f. There + should be an entry in vector for each variable in the manager. + This function implements non-simultaneous composition. If any of the + functions being composed depends on any of the variables being + substituted, then the result depends on the order of composition, + which in turn depends on the variable order: The variables farther from + the roots in the order are substituted first. + Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addVectorCompose Cudd_addPermute Cudd_addCompose] + +******************************************************************************/ +DdNode * +Cudd_addNonSimCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector) +{ + DdNode *cube, *key, *var, *tmp, *piece; + DdNode *res; + int i, lastsub; + + /* The cache entry for this function is composed of three parts: + ** f itself, the replacement relation, and the cube of the + ** variables being substituted. + ** The replacement relation is the product of the terms (yi EXNOR gi). + ** This apporach allows us to use the global cache for this function, + ** with great savings in memory with respect to using arrays for the + ** cache entries. + ** First we build replacement relation and cube of substituted + ** variables from the vector specifying the desired composition. + */ + key = DD_ONE(dd); + cuddRef(key); + cube = DD_ONE(dd); + cuddRef(cube); + for (i = (int) dd->size - 1; i >= 0; i--) { + if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) { + continue; + } + var = Cudd_addIthVar(dd,i); + if (var == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(var); + /* Update cube. */ + tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cube); + cube = tmp; + /* Update replacement relation. */ + piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]); + if (piece == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(piece); + Cudd_RecursiveDeref(dd,var); + tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,piece); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,piece); + key = tmp; + } + + /* Now try composition, until no reordering occurs. */ + do { + /* Find real substitution with largest index. */ + for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) { + if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) { + break; + } + } + + /* Recursively solve the problem. */ + dd->reordered = 0; + res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1); + if (res != NULL) cuddRef(res); + + } while (dd->reordered == 1); + + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addNonSimCompose */ + + +/**Function******************************************************************** + + Synopsis [Composes a BDD with a vector of BDDs.] + + Description [Given a vector of BDDs, creates a new BDD by + substituting the BDDs for the variables of the BDD f. There + should be an entry in vector for each variable in the manager. + If no substitution is sought for a given variable, the corresponding + projection function should be specified in the vector. + This function implements simultaneous composition. + Returns a pointer to the resulting BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_bddCompose Cudd_addVectorCompose] + +******************************************************************************/ +DdNode * +Cudd_bddVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector) +{ + DdHashTable *table; + DdNode *res; + int deepest; + int i; + + do { + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (vector[i] != dd->vars[i]) { + break; + } + } + + /* Recursively solve the problem. */ + res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest); + if (res != NULL) cuddRef(res); + + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (dd->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_bddVectorCompose */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCompose.] + + Description [Performs the recursive step of Cudd_bddCompose. + Exploits the fact that the composition of f' with g + produces the complement of the composition of f with g to better + utilize the cache. Returns the composed BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddCompose] + +******************************************************************************/ +DdNode * +cuddBddComposeRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * proj) +{ + DdNode *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e; + unsigned int v, topf, topg, topindex; + int comple; + + statLine(dd); + v = dd->perm[proj->index]; + F = Cudd_Regular(f); + topf = cuddI(dd,F->index); + + /* Terminal case. Subsumes the test for constant f. */ + if (topf > v) return(f); + + /* We solve the problem for a regular pointer, and then complement + ** the result if the pointer was originally complemented. + */ + comple = Cudd_IsComplement(f); + + /* Check cache. */ + r = cuddCacheLookup(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + if (topf == v) { + /* Compose. */ + f1 = cuddT(F); + f0 = cuddE(F); + r = cuddBddIteRecur(dd, g, f1, f0); + if (r == NULL) return(NULL); + } else { + /* Compute cofactors of f and g. Remember the index of the top + ** variable. + */ + G = Cudd_Regular(g); + topg = cuddI(dd,G->index); + if (topf > topg) { + topindex = G->index; + f1 = f0 = F; + } else { + topindex = F->index; + f1 = cuddT(F); + f0 = cuddE(F); + } + if (topg > topf) { + g1 = g0 = g; + } else { + g1 = cuddT(G); + g0 = cuddE(G); + if (g != G) { + g1 = Cudd_Not(g1); + g0 = Cudd_Not(g0); + } + } + /* Recursive step. */ + t = cuddBddComposeRecur(dd, f1, g1, proj); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddComposeRecur(dd, f0, g0, proj); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + cuddRef(e); + + r = cuddBddIteRecur(dd, dd->vars[topindex], t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, t); /* t & e not necessarily part of r */ + Cudd_IterDerefBdd(dd, e); + cuddDeref(r); + } + + cuddCacheInsert(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj,r); + + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addCompose.] + + Description [Performs the recursive step of Cudd_addCompose. + Returns the composed BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCompose] + +******************************************************************************/ +DdNode * +cuddAddComposeRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * proj) +{ + DdNode *f1, *f0, *g1, *g0, *r, *t, *e; + unsigned int v, topf, topg, topindex; + + statLine(dd); + v = dd->perm[proj->index]; + topf = cuddI(dd,f->index); + + /* Terminal case. Subsumes the test for constant f. */ + if (topf > v) return(f); + + /* Check cache. */ + r = cuddCacheLookup(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj); + if (r != NULL) { + return(r); + } + + if (topf == v) { + /* Compose. */ + f1 = cuddT(f); + f0 = cuddE(f); + r = cuddAddIteRecur(dd, g, f1, f0); + if (r == NULL) return(NULL); + } else { + /* Compute cofactors of f and g. Remember the index of the top + ** variable. + */ + topg = cuddI(dd,g->index); + if (topf > topg) { + topindex = g->index; + f1 = f0 = f; + } else { + topindex = f->index; + f1 = cuddT(f); + f0 = cuddE(f); + } + if (topg > topf) { + g1 = g0 = g; + } else { + g1 = cuddT(g); + g0 = cuddE(g); + } + /* Recursive step. */ + t = cuddAddComposeRecur(dd, f1, g1, proj); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddAddComposeRecur(dd, f0, g0, proj); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + r = cuddUniqueInter(dd, (int) topindex, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj,r); + + return(r); + +} /* end of cuddAddComposeRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addPermute.] + + Description [ Recursively puts the ADD in the order given in the + array permut. Checks for trivial cases to terminate recursion, then + splits on the children of this node. Once the solutions for the + children are obtained, it puts into the current position the node + from the rest of the ADD that should be here. Then returns this ADD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper + position is reached in the recursion tree.

+ The DdNode * that is returned is the same ADD as passed in as node, + but in the new order.] + + SideEffects [None] + + SeeAlso [Cudd_addPermute cuddBddPermuteRecur] + +******************************************************************************/ +static DdNode * +cuddAddPermuteRecur( + DdManager * manager /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * node /* ADD to be reordered */, + int * permut /* permutation array */) +{ + DdNode *T,*E; + DdNode *res,*var; + int index; + + statLine(manager); + /* Check for terminal case of constant node. */ + if (cuddIsConstant(node)) { + return(node); + } + + /* If problem already solved, look up answer and return. */ + if (node->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) { +#ifdef DD_DEBUG + addPermuteRecurHits++; +#endif + return(res); + } + + /* Split and recur on children of this node. */ + T = cuddAddPermuteRecur(manager,table,cuddT(node),permut); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddAddPermuteRecur(manager,table,cuddE(node),permut); + if (E == NULL) { + Cudd_RecursiveDeref(manager, T); + return(NULL); + } + cuddRef(E); + + /* Move variable that should be in this position to this position + ** by creating a single var ADD for that variable, and calling + ** cuddAddIteRecur with the T and E we just created. + */ + index = permut[node->index]; + var = cuddUniqueInter(manager,index,DD_ONE(manager),DD_ZERO(manager)); + if (var == NULL) return(NULL); + cuddRef(var); + res = cuddAddIteRecur(manager,var,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(manager,var); + Cudd_RecursiveDeref(manager, T); + Cudd_RecursiveDeref(manager, E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,var); + Cudd_RecursiveDeref(manager, T); + Cudd_RecursiveDeref(manager, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (node->ref != 1) { + ptrint fanout = (ptrint) node->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,node,res,fanout)) { + Cudd_RecursiveDeref(manager, res); + return(NULL); + } + } + cuddDeref(res); + return(res); + +} /* end of cuddAddPermuteRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddPermute.] + + Description [ Recursively puts the BDD in the order given in the array permut. + Checks for trivial cases to terminate recursion, then splits on the + children of this node. Once the solutions for the children are + obtained, it puts into the current position the node from the rest of + the BDD that should be here. Then returns this BDD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper position + is reached in the recursion tree.

+ The DdNode * that is returned is the same BDD as passed in as node, + but in the new order.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute cuddAddPermuteRecur] + +******************************************************************************/ +static DdNode * +cuddBddPermuteRecur( + DdManager * manager /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * node /* BDD to be reordered */, + int * permut /* permutation array */) +{ + DdNode *N,*T,*E; + DdNode *res; + int index; + + statLine(manager); + N = Cudd_Regular(node); + + /* Check for terminal case of constant node. */ + if (cuddIsConstant(N)) { + return(node); + } + + /* If problem already solved, look up answer and return. */ + if (N->ref != 1 && (res = cuddHashTableLookup1(table,N)) != NULL) { +#ifdef DD_DEBUG + bddPermuteRecurHits++; +#endif + return(Cudd_NotCond(res,N != node)); + } + + /* Split and recur on children of this node. */ + T = cuddBddPermuteRecur(manager,table,cuddT(N),permut); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddBddPermuteRecur(manager,table,cuddE(N),permut); + if (E == NULL) { + Cudd_IterDerefBdd(manager, T); + return(NULL); + } + cuddRef(E); + + /* Move variable that should be in this position to this position + ** by retrieving the single var BDD for that variable, and calling + ** cuddBddIteRecur with the T and E we just created. + */ + index = permut[N->index]; + res = cuddBddIteRecur(manager,manager->vars[index],T,E); + if (res == NULL) { + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (N->ref != 1) { + ptrint fanout = (ptrint) N->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,N,res,fanout)) { + Cudd_IterDerefBdd(manager, res); + return(NULL); + } + } + cuddDeref(res); + return(Cudd_NotCond(res,N != node)); + +} /* end of cuddBddPermuteRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddVarMap.] + + Description [Implements the recursive step of Cudd_bddVarMap. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddVarMap] + +******************************************************************************/ +static DdNode * +cuddBddVarMapRecur( + DdManager *manager /* DD manager */, + DdNode *f /* BDD to be remapped */) +{ + DdNode *F, *T, *E; + DdNode *res; + int index; + + statLine(manager); + F = Cudd_Regular(f); + + /* Check for terminal case of constant node. */ + if (cuddIsConstant(F)) { + return(f); + } + + /* If problem already solved, look up answer and return. */ + if (F->ref != 1 && + (res = cuddCacheLookup1(manager,Cudd_bddVarMap,F)) != NULL) { + return(Cudd_NotCond(res,F != f)); + } + + /* Split and recur on children of this node. */ + T = cuddBddVarMapRecur(manager,cuddT(F)); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddBddVarMapRecur(manager,cuddE(F)); + if (E == NULL) { + Cudd_IterDerefBdd(manager, T); + return(NULL); + } + cuddRef(E); + + /* Move variable that should be in this position to this position + ** by retrieving the single var BDD for that variable, and calling + ** cuddBddIteRecur with the T and E we just created. + */ + index = manager->map[F->index]; + res = cuddBddIteRecur(manager,manager->vars[index],T,E); + if (res == NULL) { + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (F->ref != 1) { + cuddCacheInsert1(manager,Cudd_bddVarMap,F,res); + } + cuddDeref(res); + return(Cudd_NotCond(res,F != f)); + +} /* end of cuddBddVarMapRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addVectorCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddVectorComposeRecur( + DdManager * dd /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * f /* ADD in which to compose */, + DdNode ** vector /* functions to substitute */, + int deepest /* depth of deepest substitution */) +{ + DdNode *T,*E; + DdNode *res; + + statLine(dd); + /* If we are past the deepest substitution, return f. */ + if (cuddI(dd,f->index) > deepest) { + return(f); + } + + if ((res = cuddHashTableLookup1(table,f)) != NULL) { +#ifdef DD_DEBUG + addVectorComposeHits++; +#endif + return(res); + } + + /* Split and recur on children of this node. */ + T = cuddAddVectorComposeRecur(dd,table,cuddT(f),vector,deepest); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddAddVectorComposeRecur(dd,table,cuddE(f),vector,deepest); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + /* Retrieve the 0-1 ADD for the current top variable and call + ** cuddAddIteRecur with the T and E we just created. + */ + res = cuddAddIteRecur(dd,vector[f->index],T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again + */ + if (f->ref != 1) { + ptrint fanout = (ptrint) f->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + } + cuddDeref(res); + return(res); + +} /* end of cuddAddVectorComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addGeneralVectorCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddGeneralVectorComposeRecur( + DdManager * dd /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * f /* ADD in which to compose */, + DdNode ** vectorOn /* functions to substitute for x_i */, + DdNode ** vectorOff /* functions to substitute for x_i' */, + int deepest /* depth of deepest substitution */) +{ + DdNode *T,*E,*t,*e; + DdNode *res; + + /* If we are past the deepest substitution, return f. */ + if (cuddI(dd,f->index) > deepest) { + return(f); + } + + if ((res = cuddHashTableLookup1(table,f)) != NULL) { +#ifdef DD_DEBUG + addGeneralVectorComposeHits++; +#endif + return(res); + } + + /* Split and recur on children of this node. */ + T = cuddAddGeneralVectorComposeRecur(dd,table,cuddT(f), + vectorOn,vectorOff,deepest); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddAddGeneralVectorComposeRecur(dd,table,cuddE(f), + vectorOn,vectorOff,deepest); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + /* Retrieve the compose ADDs for the current top variable and call + ** cuddAddApplyRecur with the T and E we just created. + */ + t = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOn[f->index],T); + if (t == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(t); + e = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOff[f->index],E); + if (e == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again + */ + if (f->ref != 1) { + ptrint fanout = (ptrint) f->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + } + cuddDeref(res); + return(res); + +} /* end of cuddAddGeneralVectorComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addNonSimCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddNonSimComposeRecur( + DdManager * dd, + DdNode * f, + DdNode ** vector, + DdNode * key, + DdNode * cube, + int lastsub) +{ + DdNode *f1, *f0, *key1, *key0, *cube1, *var; + DdNode *T,*E; + DdNode *r; + unsigned int top, topf, topk, topc; + unsigned int index; + int i; + DdNode **vect1; + DdNode **vect0; + + statLine(dd); + /* If we are past the deepest substitution, return f. */ + if (cube == DD_ONE(dd) || cuddIsConstant(f)) { + return(f); + } + + /* If problem already solved, look up answer and return. */ + r = cuddCacheLookup(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube); + if (r != NULL) { + return(r); + } + + /* Find top variable. we just need to look at f, key, and cube, + ** because all the varibles in the gi are in key. + */ + topf = cuddI(dd,f->index); + topk = cuddI(dd,key->index); + top = ddMin(topf,topk); + topc = cuddI(dd,cube->index); + top = ddMin(top,topc); + index = dd->invperm[top]; + + /* Compute the cofactors. */ + if (topf == top) { + f1 = cuddT(f); + f0 = cuddE(f); + } else { + f1 = f0 = f; + } + if (topc == top) { + cube1 = cuddT(cube); + /* We want to eliminate vector[index] from key. Otherwise + ** cache performance is severely affected. Hence we + ** existentially quantify the variable with index "index" from key. + */ + var = Cudd_addIthVar(dd, (int) index); + if (var == NULL) { + return(NULL); + } + cuddRef(var); + key1 = cuddAddExistAbstractRecur(dd, key, var); + if (key1 == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(key1); + Cudd_RecursiveDeref(dd,var); + key0 = key1; + } else { + cube1 = cube; + if (topk == top) { + key1 = cuddT(key); + key0 = cuddE(key); + } else { + key1 = key0 = key; + } + cuddRef(key1); + } + + /* Allocate two new vectors for the cofactors of vector. */ + vect1 = ALLOC(DdNode *,lastsub); + if (vect1 == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd,key1); + return(NULL); + } + vect0 = ALLOC(DdNode *,lastsub); + if (vect0 == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd,key1); + FREE(vect1); + return(NULL); + } + + /* Cofactor the gi. Eliminate vect1[index] and vect0[index], because + ** we do not need them. + */ + for (i = 0; i < lastsub; i++) { + DdNode *gi = vector[i]; + if (gi == NULL) { + vect1[i] = vect0[i] = NULL; + } else if (gi->index == index) { + vect1[i] = cuddT(gi); + vect0[i] = cuddE(gi); + } else { + vect1[i] = vect0[i] = gi; + } + } + vect1[index] = vect0[index] = NULL; + + /* Recur on children. */ + T = cuddAddNonSimComposeRecur(dd,f1,vect1,key1,cube1,lastsub); + FREE(vect1); + if (T == NULL) { + Cudd_RecursiveDeref(dd,key1); + FREE(vect0); + return(NULL); + } + cuddRef(T); + E = cuddAddNonSimComposeRecur(dd,f0,vect0,key0,cube1,lastsub); + FREE(vect0); + if (E == NULL) { + Cudd_RecursiveDeref(dd,key1); + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + Cudd_RecursiveDeref(dd,key1); + + /* Retrieve the 0-1 ADD for the current top variable from vector, + ** and call cuddAddIteRecur with the T and E we just created. + */ + r = cuddAddIteRecur(dd,vector[index],T,E); + if (r == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + cuddDeref(r); + + /* Store answer to trim recursion. */ + cuddCacheInsert(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube,r); + + return(r); + +} /* end of cuddAddNonSimComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddVectorCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddBddVectorComposeRecur( + DdManager * dd /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * f /* BDD in which to compose */, + DdNode ** vector /* functions to be composed */, + int deepest /* depth of the deepest substitution */) +{ + DdNode *F,*T,*E; + DdNode *res; + + statLine(dd); + F = Cudd_Regular(f); + + /* If we are past the deepest substitution, return f. */ + if (cuddI(dd,F->index) > deepest) { + return(f); + } + + /* If problem already solved, look up answer and return. */ + if ((res = cuddHashTableLookup1(table,F)) != NULL) { +#ifdef DD_DEBUG + bddVectorComposeHits++; +#endif + return(Cudd_NotCond(res,F != f)); + } + + /* Split and recur on children of this node. */ + T = cuddBddVectorComposeRecur(dd,table,cuddT(F),vector, deepest); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddBddVectorComposeRecur(dd,table,cuddE(F),vector, deepest); + if (E == NULL) { + Cudd_IterDerefBdd(dd, T); + return(NULL); + } + cuddRef(E); + + /* Call cuddBddIteRecur with the BDD that replaces the current top + ** variable and the T and E we just created. + */ + res = cuddBddIteRecur(dd,vector[F->index],T,E); + if (res == NULL) { + Cudd_IterDerefBdd(dd, T); + Cudd_IterDerefBdd(dd, E); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd, T); + Cudd_IterDerefBdd(dd, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (F->ref != 1) { + ptrint fanout = (ptrint) F->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,F,res,fanout)) { + Cudd_IterDerefBdd(dd, res); + return(NULL); + } + } + cuddDeref(res); + return(Cudd_NotCond(res,F != f)); + +} /* end of cuddBddVectorComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Comparison of a function to the i-th ADD variable.] + + Description [Comparison of a function to the i-th ADD variable. Returns 1 if + the function is the i-th ADD variable; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static int +ddIsIthAddVar( + DdManager * dd, + DdNode * f, + unsigned int i) +{ + return(f->index == i && cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd)); + +} /* end of ddIsIthAddVar */ + + +/**Function******************************************************************** + + Synopsis [Comparison of a pair of functions to the i-th ADD variable.] + + Description [Comparison of a pair of functions to the i-th ADD + variable. Returns 1 if the functions are the i-th ADD variable and its + complement; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static int +ddIsIthAddVarPair( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int i) +{ + return(f->index == i && g->index == i && + cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd) && + cuddT(g) == DD_ZERO(dd) && cuddE(g) == DD_ONE(dd)); + +} /* end of ddIsIthAddVarPair */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddDecomp.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddDecomp.c new file mode 100644 index 000000000..066027d95 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddDecomp.c @@ -0,0 +1,2177 @@ +/**CFile*********************************************************************** + + FileName [cuddDecomp.c] + + PackageName [cudd] + + Synopsis [Functions for BDD decomposition.] + + Description [External procedures included in this file: +

    +
  • Cudd_bddApproxConjDecomp() +
  • Cudd_bddApproxDisjDecomp() +
  • Cudd_bddIterConjDecomp() +
  • Cudd_bddIterDisjDecomp() +
  • Cudd_bddGenConjDecomp() +
  • Cudd_bddGenDisjDecomp() +
  • Cudd_bddVarConjDecomp() +
  • Cudd_bddVarDisjDecomp() +
+ Static procedures included in this module: +
    +
  • cuddConjunctsAux() +
  • CreateBotDist() +
  • BuildConjuncts() +
  • ConjunctsFree() +
] + + Author [Kavita Ravi, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ +#define DEPTH 5 +#define THRESHOLD 10 +#define NONE 0 +#define PAIR_ST 1 +#define PAIR_CR 2 +#define G_ST 3 +#define G_CR 4 +#define H_ST 5 +#define H_CR 6 +#define BOTH_G 7 +#define BOTH_H 8 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ +typedef struct Conjuncts { + DdNode *g; + DdNode *h; +} Conjuncts; + +typedef struct NodeStat { + int distance; + int localRef; +} NodeStat; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddDecomp.c,v 1.45 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static DdNode *one, *zero; +long lastTimeG; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +#define FactorsNotStored(factors) ((int)((long)(factors) & 01)) + +#define FactorsComplement(factors) ((Conjuncts *)((long)(factors) | 01)) + +#define FactorsUncomplement(factors) ((Conjuncts *)((long)(factors) ^ 01)) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static NodeStat * CreateBotDist (DdNode * node, st_table * distanceTable); +static double CountMinterms (DdNode * node, double max, st_table * mintermTable, FILE *fp); +static void ConjunctsFree (DdManager * dd, Conjuncts * factors); +static int PairInTables (DdNode * g, DdNode * h, st_table * ghTable); +static Conjuncts * CheckTablesCacheAndReturn (DdNode * node, DdNode * g, DdNode * h, st_table * ghTable, st_table * cacheTable); +static Conjuncts * PickOnePair (DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable); +static Conjuncts * CheckInTables (DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable, int * outOfMem); +static Conjuncts * ZeroCase (DdManager * dd, DdNode * node, Conjuncts * factorsNv, st_table * ghTable, st_table * cacheTable, int switched); +static Conjuncts * BuildConjuncts (DdManager * dd, DdNode * node, st_table * distanceTable, st_table * cacheTable, int approxDistance, int maxLocalRef, st_table * ghTable, st_table * mintermTable); +static int cuddConjunctsAux (DdManager * dd, DdNode * f, DdNode ** c1, DdNode ** c2); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Performs two-way conjunctive decomposition of a + BDD. This procedure owes its name to the use of supersetting to + obtain an initial factor of the given function. Returns the number + of conjuncts produced, that is, 2 if successful; 1 if no meaningful + decomposition was found; 0 otherwise. The conjuncts produced by this + procedure tend to be imbalanced.] + + SideEffects [The factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddApproxDisjDecomp Cudd_bddIterConjDecomp + Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox + Cudd_bddSqueeze Cudd_bddLICompaction] + +******************************************************************************/ +int +Cudd_bddApproxConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the first factor */) +{ + DdNode *superset1, *superset2, *glocal, *hlocal; + int nvars = Cudd_SupportSize(dd,f); + + /* Find a tentative first factor by overapproximation and minimization. */ + superset1 = Cudd_RemapOverApprox(dd,f,nvars,0,1.0); + if (superset1 == NULL) return(0); + cuddRef(superset1); + superset2 = Cudd_bddSqueeze(dd,f,superset1); + if (superset2 == NULL) { + Cudd_RecursiveDeref(dd,superset1); + return(0); + } + cuddRef(superset2); + Cudd_RecursiveDeref(dd,superset1); + + /* Compute the second factor by minimization. */ + hlocal = Cudd_bddLICompaction(dd,f,superset2); + if (hlocal == NULL) { + Cudd_RecursiveDeref(dd,superset2); + return(0); + } + cuddRef(hlocal); + + /* Refine the first factor by minimization. If h turns out to be f, this + ** step guarantees that g will be 1. */ + glocal = Cudd_bddLICompaction(dd,superset2,hlocal); + if (glocal == NULL) { + Cudd_RecursiveDeref(dd,superset2); + Cudd_RecursiveDeref(dd,hlocal); + return(0); + } + cuddRef(glocal); + Cudd_RecursiveDeref(dd,superset2); + + if (glocal != DD_ONE(dd)) { + if (hlocal != DD_ONE(dd)) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,glocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = hlocal; + return(1); + } + +} /* end of Cudd_bddApproxConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD. + Returns the number of disjuncts produced, that is, 2 if successful; + 1 if no meaningful decomposition was found; 0 otherwise. The + disjuncts produced by this procedure tend to be imbalanced.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddApproxConjDecomp Cudd_bddIterDisjDecomp + Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp] + +******************************************************************************/ +int +Cudd_bddApproxDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddApproxConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddApproxDisjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Performs two-way conjunctive decomposition of a + BDD. This procedure owes its name to the iterated use of + supersetting to obtain a factor of the given function. Returns the + number of conjuncts produced, that is, 2 if successful; 1 if no + meaningful decomposition was found; 0 otherwise. The conjuncts + produced by this procedure tend to be imbalanced.] + + SideEffects [The factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddIterDisjDecomp Cudd_bddApproxConjDecomp + Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox + Cudd_bddSqueeze Cudd_bddLICompaction] + +******************************************************************************/ +int +Cudd_bddIterConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the array of conjuncts */) +{ + DdNode *superset1, *superset2, *old[2], *res[2]; + int sizeOld, sizeNew; + int nvars = Cudd_SupportSize(dd,f); + + old[0] = DD_ONE(dd); + cuddRef(old[0]); + old[1] = f; + cuddRef(old[1]); + sizeOld = Cudd_SharingSize(old,2); + + do { + /* Find a tentative first factor by overapproximation and + ** minimization. */ + superset1 = Cudd_RemapOverApprox(dd,old[1],nvars,0,1.0); + if (superset1 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(superset1); + superset2 = Cudd_bddSqueeze(dd,old[1],superset1); + if (superset2 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + Cudd_RecursiveDeref(dd,superset1); + return(0); + } + cuddRef(superset2); + Cudd_RecursiveDeref(dd,superset1); + res[0] = Cudd_bddAnd(dd,old[0],superset2); + if (res[0] == NULL) { + Cudd_RecursiveDeref(dd,superset2); + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(res[0]); + Cudd_RecursiveDeref(dd,superset2); + if (res[0] == old[0]) { + Cudd_RecursiveDeref(dd,res[0]); + break; /* avoid infinite loop */ + } + + /* Compute the second factor by minimization. */ + res[1] = Cudd_bddLICompaction(dd,old[1],res[0]); + if (res[1] == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(res[1]); + + sizeNew = Cudd_SharingSize(res,2); + if (sizeNew <= sizeOld) { + Cudd_RecursiveDeref(dd,old[0]); + old[0] = res[0]; + Cudd_RecursiveDeref(dd,old[1]); + old[1] = res[1]; + sizeOld = sizeNew; + } else { + Cudd_RecursiveDeref(dd,res[0]); + Cudd_RecursiveDeref(dd,res[1]); + break; + } + + } while (1); + + /* Refine the first factor by minimization. If h turns out to + ** be f, this step guarantees that g will be 1. */ + superset1 = Cudd_bddLICompaction(dd,old[0],old[1]); + if (superset1 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(superset1); + Cudd_RecursiveDeref(dd,old[0]); + old[0] = superset1; + + if (old[0] != DD_ONE(dd)) { + if (old[1] != DD_ONE(dd)) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[0]; + (*conjuncts)[1] = old[1]; + return(2); + } else { + Cudd_RecursiveDeref(dd,old[1]); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[0]; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,old[0]); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[1]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[1]; + return(1); + } + +} /* end of Cudd_bddIterConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD. + Returns the number of disjuncts produced, that is, 2 if successful; + 1 if no meaningful decomposition was found; 0 otherwise. The + disjuncts produced by this procedure tend to be imbalanced.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddIterConjDecomp Cudd_bddApproxDisjDecomp + Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp] + +******************************************************************************/ +int +Cudd_bddIterDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddIterConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddIterDisjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Performs two-way conjunctive decomposition of a + BDD. This procedure owes its name to the fact tht it generalizes the + decomposition based on the cofactors with respect to one + variable. Returns the number of conjuncts produced, that is, 2 if + successful; 1 if no meaningful decomposition was found; 0 + otherwise. The conjuncts produced by this procedure tend to be + balanced.] + + SideEffects [The two factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddGenDisjDecomp Cudd_bddApproxConjDecomp + Cudd_bddIterConjDecomp Cudd_bddVarConjDecomp] + +******************************************************************************/ +int +Cudd_bddGenConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the array of conjuncts */) +{ + int result; + DdNode *glocal, *hlocal; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + do { + dd->reordered = 0; + result = cuddConjunctsAux(dd, f, &glocal, &hlocal); + } while (dd->reordered == 1); + + if (result == 0) { + return(0); + } + + if (glocal != one) { + if (hlocal != one) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,glocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = hlocal; + return(1); + } + +} /* end of Cudd_bddGenConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD. + Returns the number of disjuncts produced, that is, 2 if successful; + 1 if no meaningful decomposition was found; 0 otherwise. The + disjuncts produced by this procedure tend to be balanced.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddGenConjDecomp Cudd_bddApproxDisjDecomp + Cudd_bddIterDisjDecomp Cudd_bddVarDisjDecomp] + +******************************************************************************/ +int +Cudd_bddGenDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddGenConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddGenDisjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Conjunctively decomposes one BDD according to a + variable. If f is the function of the BDD and + x is the variable, the decomposition is + (f+x)(f+x'). The variable is chosen so as to balance + the sizes of the two conjuncts and to keep them small. Returns the + number of conjuncts produced, that is, 2 if successful; 1 if no + meaningful decomposition was found; 0 otherwise.] + + SideEffects [The two factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddVarDisjDecomp Cudd_bddGenConjDecomp + Cudd_bddApproxConjDecomp Cudd_bddIterConjDecomp] + +*****************************************************************************/ +int +Cudd_bddVarConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the array of conjuncts */) +{ + int best; + int min; + DdNode *support, *scan, *var, *glocal, *hlocal; + + /* Find best cofactoring variable. */ + support = Cudd_Support(dd,f); + if (support == NULL) return(0); + if (Cudd_IsConstant(support)) { + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = f; + cuddRef((*conjuncts)[0]); + return(1); + } + cuddRef(support); + min = 1000000000; + best = -1; + scan = support; + while (!Cudd_IsConstant(scan)) { + int i = scan->index; + int est1 = Cudd_EstimateCofactor(dd,f,i,1); + int est0 = Cudd_EstimateCofactor(dd,f,i,0); + /* Minimize the size of the larger of the two cofactors. */ + int est = (est1 > est0) ? est1 : est0; + if (est < min) { + min = est; + best = i; + } + scan = cuddT(scan); + } +#ifdef DD_DEBUG + assert(best >= 0 && best < dd->size); +#endif + Cudd_RecursiveDeref(dd,support); + + var = Cudd_bddIthVar(dd,best); + glocal = Cudd_bddOr(dd,f,var); + if (glocal == NULL) { + return(0); + } + cuddRef(glocal); + hlocal = Cudd_bddOr(dd,f,Cudd_Not(var)); + if (hlocal == NULL) { + Cudd_RecursiveDeref(dd,glocal); + return(0); + } + cuddRef(hlocal); + + if (glocal != DD_ONE(dd)) { + if (hlocal != DD_ONE(dd)) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,glocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = hlocal; + return(1); + } + +} /* end of Cudd_bddVarConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD + according to a variable. If f is the function of the + BDD and x is the variable, the decomposition is + f*x + f*x'. The variable is chosen so as to balance + the sizes of the two disjuncts and to keep them small. Returns the + number of disjuncts produced, that is, 2 if successful; 1 if no + meaningful decomposition was found; 0 otherwise.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddVarConjDecomp Cudd_bddApproxDisjDecomp + Cudd_bddIterDisjDecomp Cudd_bddGenDisjDecomp] + +******************************************************************************/ +int +Cudd_bddVarDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddVarConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddVarDisjDecomp */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Get longest distance of node from constant.] + + Description [Get longest distance of node from constant. Returns the + distance of the root from the constant if successful; CUDD_OUT_OF_MEM + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static NodeStat * +CreateBotDist( + DdNode * node, + st_table * distanceTable) +{ + DdNode *N, *Nv, *Nnv; + int distance, distanceNv, distanceNnv; + NodeStat *nodeStat, *nodeStatNv, *nodeStatNnv; + +#if 0 + if (Cudd_IsConstant(node)) { + return(0); + } +#endif + + /* Return the entry in the table if found. */ + N = Cudd_Regular(node); + if (st_lookup(distanceTable, N, &nodeStat)) { + nodeStat->localRef++; + return(nodeStat); + } + + Nv = cuddT(N); + Nnv = cuddE(N); + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* Recur on the children. */ + nodeStatNv = CreateBotDist(Nv, distanceTable); + if (nodeStatNv == NULL) return(NULL); + distanceNv = nodeStatNv->distance; + + nodeStatNnv = CreateBotDist(Nnv, distanceTable); + if (nodeStatNnv == NULL) return(NULL); + distanceNnv = nodeStatNnv->distance; + /* Store max distance from constant; note sometimes this distance + ** may be to 0. + */ + distance = (distanceNv > distanceNnv) ? (distanceNv+1) : (distanceNnv + 1); + + nodeStat = ALLOC(NodeStat, 1); + if (nodeStat == NULL) { + return(0); + } + nodeStat->distance = distance; + nodeStat->localRef = 1; + + if (st_insert(distanceTable, (char *)N, (char *)nodeStat) == + ST_OUT_OF_MEM) { + return(0); + + } + return(nodeStat); + +} /* end of CreateBotDist */ + + +/**Function******************************************************************** + + Synopsis [Count the number of minterms of each node ina a BDD and + store it in a hash table.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double +CountMinterms( + DdNode * node, + double max, + st_table * mintermTable, + FILE *fp) +{ + DdNode *N, *Nv, *Nnv; + double min, minNv, minNnv; + double *dummy; + + N = Cudd_Regular(node); + + if (cuddIsConstant(N)) { + if (node == zero) { + return(0); + } else { + return(max); + } + } + + /* Return the entry in the table if found. */ + if (st_lookup(mintermTable, node, &dummy)) { + min = *dummy; + return(min); + } + + Nv = cuddT(N); + Nnv = cuddE(N); + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* Recur on the children. */ + minNv = CountMinterms(Nv, max, mintermTable, fp); + if (minNv == -1.0) return(-1.0); + minNnv = CountMinterms(Nnv, max, mintermTable, fp); + if (minNnv == -1.0) return(-1.0); + min = minNv / 2.0 + minNnv / 2.0; + /* store + */ + + dummy = ALLOC(double, 1); + if (dummy == NULL) return(-1.0); + *dummy = min; + if (st_insert(mintermTable, (char *)node, (char *)dummy) == ST_OUT_OF_MEM) { + (void) fprintf(fp, "st table insert failed\n"); + } + return(min); + +} /* end of CountMinterms */ + + +/**Function******************************************************************** + + Synopsis [Free factors structure] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ConjunctsFree( + DdManager * dd, + Conjuncts * factors) +{ + Cudd_RecursiveDeref(dd, factors->g); + Cudd_RecursiveDeref(dd, factors->h); + FREE(factors); + return; + +} /* end of ConjunctsFree */ + + +/**Function******************************************************************** + + Synopsis [Check whether the given pair is in the tables.] + + Description [.Check whether the given pair is in the tables. gTable + and hTable are combined. + absence in both is indicated by 0, + presence in gTable is indicated by 1, + presence in hTable by 2 and + presence in both by 3. + The values returned by this function are PAIR_ST, + PAIR_CR, G_ST, G_CR, H_ST, H_CR, BOTH_G, BOTH_H, NONE. + PAIR_ST implies g in gTable and h in hTable + PAIR_CR implies g in hTable and h in gTable + G_ST implies g in gTable and h not in any table + G_CR implies g in hTable and h not in any table + H_ST implies h in hTable and g not in any table + H_CR implies h in gTable and g not in any table + BOTH_G implies both in gTable + BOTH_H implies both in hTable + NONE implies none in table; ] + + SideEffects [] + + SeeAlso [CheckTablesCacheAndReturn CheckInTables] + +******************************************************************************/ +static int +PairInTables( + DdNode * g, + DdNode * h, + st_table * ghTable) +{ + int valueG, valueH, gPresent, hPresent; + + valueG = valueH = gPresent = hPresent = 0; + + gPresent = st_lookup_int(ghTable, (char *)Cudd_Regular(g), &valueG); + hPresent = st_lookup_int(ghTable, (char *)Cudd_Regular(h), &valueH); + + if (!gPresent && !hPresent) return(NONE); + + if (!hPresent) { + if (valueG & 1) return(G_ST); + if (valueG & 2) return(G_CR); + } + if (!gPresent) { + if (valueH & 1) return(H_CR); + if (valueH & 2) return(H_ST); + } + /* both in tables */ + if ((valueG & 1) && (valueH & 2)) return(PAIR_ST); + if ((valueG & 2) && (valueH & 1)) return(PAIR_CR); + + if (valueG & 1) { + return(BOTH_G); + } else { + return(BOTH_H); + } + +} /* end of PairInTables */ + + +/**Function******************************************************************** + + Synopsis [Check the tables for the existence of pair and return one + combination, cache the result.] + + Description [Check the tables for the existence of pair and return + one combination, cache the result. The assumption is that one of the + conjuncts is already in the tables.] + + SideEffects [g and h referenced for the cache] + + SeeAlso [ZeroCase] + +******************************************************************************/ +static Conjuncts * +CheckTablesCacheAndReturn( + DdNode * node, + DdNode * g, + DdNode * h, + st_table * ghTable, + st_table * cacheTable) +{ + int pairValue; + int value; + Conjuncts *factors; + + value = 0; + /* check tables */ + pairValue = PairInTables(g, h, ghTable); + assert(pairValue != NONE); + /* if both dont exist in table, we know one exists(either g or h). + * Therefore store the other and proceed + */ + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) return(NULL); + if ((pairValue == BOTH_H) || (pairValue == H_ST)) { + if (g != one) { + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(g), &value)) { + value |= 1; + } else { + value = 1; + } + if (st_insert(ghTable, (char *)Cudd_Regular(g), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = g; + factors->h = h; + } else if ((pairValue == BOTH_G) || (pairValue == G_ST)) { + if (h != one) { + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(h), &value)) { + value |= 2; + } else { + value = 2; + } + if (st_insert(ghTable, (char *)Cudd_Regular(h), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = g; + factors->h = h; + } else if (pairValue == H_CR) { + if (g != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = h; + factors->h = g; + } else if (pairValue == G_CR) { + if (h != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = h; + factors->h = g; + } else if (pairValue == PAIR_CR) { + /* pair exists in table */ + factors->g = h; + factors->h = g; + } else if (pairValue == PAIR_ST) { + factors->g = g; + factors->h = h; + } + + /* cache the result for this node */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + + return(factors); + +} /* end of CheckTablesCacheAndReturn */ + +/**Function******************************************************************** + + Synopsis [Check the tables for the existence of pair and return one + combination, store in cache.] + + Description [Check the tables for the existence of pair and return + one combination, store in cache. The pair that has more pointers to + it is picked. An approximation of the number of local pointers is + made by taking the reference count of the pairs sent. ] + + SideEffects [] + + SeeAlso [ZeroCase BuildConjuncts] + +******************************************************************************/ +static Conjuncts * +PickOnePair( + DdNode * node, + DdNode * g1, + DdNode * h1, + DdNode * g2, + DdNode * h2, + st_table * ghTable, + st_table * cacheTable) +{ + int value; + Conjuncts *factors; + int oneRef, twoRef; + + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) return(NULL); + + /* count the number of pointers to pair 2 */ + if (h2 == one) { + twoRef = (Cudd_Regular(g2))->ref; + } else if (g2 == one) { + twoRef = (Cudd_Regular(h2))->ref; + } else { + twoRef = ((Cudd_Regular(g2))->ref + (Cudd_Regular(h2))->ref)/2; + } + + /* count the number of pointers to pair 1 */ + if (h1 == one) { + oneRef = (Cudd_Regular(g1))->ref; + } else if (g1 == one) { + oneRef = (Cudd_Regular(h1))->ref; + } else { + oneRef = ((Cudd_Regular(g1))->ref + (Cudd_Regular(h1))->ref)/2; + } + + /* pick the pair with higher reference count */ + if (oneRef >= twoRef) { + factors->g = g1; + factors->h = h1; + } else { + factors->g = g2; + factors->h = h2; + } + + /* + * Store computed factors in respective tables to encourage + * recombination. + */ + if (factors->g != one) { + /* insert g in htable */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->g), &value)) { + if (value == 2) { + value |= 1; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } else { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } + + if (factors->h != one) { + /* insert h in htable */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->h), &value)) { + if (value == 1) { + value |= 2; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } else { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } + + /* Store factors in cache table for later use. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == + ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + + return(factors); + +} /* end of PickOnePair */ + + +/**Function******************************************************************** + + Synopsis [Check if the two pairs exist in the table, If any of the + conjuncts do exist, store in the cache and return the corresponding pair.] + + Description [Check if the two pairs exist in the table. If any of + the conjuncts do exist, store in the cache and return the + corresponding pair.] + + SideEffects [] + + SeeAlso [ZeroCase BuildConjuncts] + +******************************************************************************/ +static Conjuncts * +CheckInTables( + DdNode * node, + DdNode * g1, + DdNode * h1, + DdNode * g2, + DdNode * h2, + st_table * ghTable, + st_table * cacheTable, + int * outOfMem) +{ + int pairValue1, pairValue2; + Conjuncts *factors; + int value; + + *outOfMem = 0; + + /* check existence of pair in table */ + pairValue1 = PairInTables(g1, h1, ghTable); + pairValue2 = PairInTables(g2, h2, ghTable); + + /* if none of the 4 exist in the gh tables, return NULL */ + if ((pairValue1 == NONE) && (pairValue2 == NONE)) { + return NULL; + } + + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + *outOfMem = 1; + return NULL; + } + + /* pairs that already exist in the table get preference. */ + if (pairValue1 == PAIR_ST) { + factors->g = g1; + factors->h = h1; + } else if (pairValue2 == PAIR_ST) { + factors->g = g2; + factors->h = h2; + } else if (pairValue1 == PAIR_CR) { + factors->g = h1; + factors->h = g1; + } else if (pairValue2 == PAIR_CR) { + factors->g = h2; + factors->h = g2; + } else if (pairValue1 == G_ST) { + /* g exists in the table, h is not found in either table */ + factors->g = g1; + factors->h = h1; + if (h1 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == BOTH_G) { + /* g and h are found in the g table */ + factors->g = g1; + factors->h = h1; + if (h1 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == H_ST) { + /* h exists in the table, g is not found in either table */ + factors->g = g1; + factors->h = h1; + if (g1 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == BOTH_H) { + /* g and h are found in the h table */ + factors->g = g1; + factors->h = h1; + if (g1 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == G_ST) { + /* g exists in the table, h is not found in either table */ + factors->g = g2; + factors->h = h2; + if (h2 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == BOTH_G) { + /* g and h are found in the g table */ + factors->g = g2; + factors->h = h2; + if (h2 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == H_ST) { + /* h exists in the table, g is not found in either table */ + factors->g = g2; + factors->h = h2; + if (g2 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == BOTH_H) { + /* g and h are found in the h table */ + factors->g = g2; + factors->h = h2; + if (g2 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == G_CR) { + /* g found in h table and h in none */ + factors->g = h1; + factors->h = g1; + if (h1 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == H_CR) { + /* h found in g table and g in none */ + factors->g = h1; + factors->h = g1; + if (g1 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == G_CR) { + /* g found in h table and h in none */ + factors->g = h2; + factors->h = g2; + if (h2 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == H_CR) { + /* h found in g table and g in none */ + factors->g = h2; + factors->h = g2; + if (g2 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } + + /* Store factors in cache table for later use. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == + ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + return factors; +} /* end of CheckInTables */ + + + +/**Function******************************************************************** + + Synopsis [If one child is zero, do explicitly what Restrict does or better] + + Description [If one child is zero, do explicitly what Restrict does or better. + First separate a variable and its child in the base case. In case of a cube + times a function, separate the cube and function. As a last resort, look in + tables.] + + SideEffects [Frees the BDDs in factorsNv. factorsNv itself is not freed + because it is freed above.] + + SeeAlso [BuildConjuncts] + +******************************************************************************/ +static Conjuncts * +ZeroCase( + DdManager * dd, + DdNode * node, + Conjuncts * factorsNv, + st_table * ghTable, + st_table * cacheTable, + int switched) +{ + int topid; + DdNode *g, *h, *g1, *g2, *h1, *h2, *x, *N, *G, *H, *Gv, *Gnv; + DdNode *Hv, *Hnv; + int value; + int outOfMem; + Conjuncts *factors; + + /* get var at this node */ + N = Cudd_Regular(node); + topid = N->index; + x = dd->vars[topid]; + x = (switched) ? Cudd_Not(x): x; + cuddRef(x); + + /* Seprate variable and child */ + if (factorsNv->g == one) { + Cudd_RecursiveDeref(dd, factorsNv->g); + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + factors->g = x; + factors->h = factorsNv->h; + /* cache the result*/ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + FREE(factors); + return NULL; + } + + /* store x in g table, the other node is already in the table */ + if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { + value |= 1; + } else { + value = 1; + } + if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + return(factors); + } + + /* Seprate variable and child */ + if (factorsNv->h == one) { + Cudd_RecursiveDeref(dd, factorsNv->h); + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + factors->g = factorsNv->g; + factors->h = x; + /* cache the result. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + FREE(factors); + return(NULL); + } + /* store x in h table, the other node is already in the table */ + if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { + value |= 2; + } else { + value = 2; + } + if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + return(factors); + } + + G = Cudd_Regular(factorsNv->g); + Gv = cuddT(G); + Gnv = cuddE(G); + Gv = Cudd_NotCond(Gv, Cudd_IsComplement(node)); + Gnv = Cudd_NotCond(Gnv, Cudd_IsComplement(node)); + /* if the child below is a variable */ + if ((Gv == zero) || (Gnv == zero)) { + h = factorsNv->h; + g = cuddBddAndRecur(dd, x, factorsNv->g); + if (g != NULL) cuddRef(g); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + if (g == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + return NULL; + } + /* CheckTablesCacheAndReturn responsible for allocating + * factors structure., g,h referenced for cache store the + */ + factors = CheckTablesCacheAndReturn(node, + g, + h, + ghTable, + cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g); + Cudd_RecursiveDeref(dd, h); + } + return(factors); + } + + H = Cudd_Regular(factorsNv->h); + Hv = cuddT(H); + Hnv = cuddE(H); + Hv = Cudd_NotCond(Hv, Cudd_IsComplement(node)); + Hnv = Cudd_NotCond(Hnv, Cudd_IsComplement(node)); + /* if the child below is a variable */ + if ((Hv == zero) || (Hnv == zero)) { + g = factorsNv->g; + h = cuddBddAndRecur(dd, x, factorsNv->h); + if (h!= NULL) cuddRef(h); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + if (h == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + return NULL; + } + /* CheckTablesCacheAndReturn responsible for allocating + * factors structure.g,h referenced for table store + */ + factors = CheckTablesCacheAndReturn(node, + g, + h, + ghTable, + cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g); + Cudd_RecursiveDeref(dd, h); + } + return(factors); + } + + /* build g1 = x*g; h1 = h */ + /* build g2 = g; h2 = x*h */ + Cudd_RecursiveDeref(dd, x); + h1 = factorsNv->h; + g1 = cuddBddAndRecur(dd, x, factorsNv->g); + if (g1 != NULL) cuddRef(g1); + if (g1 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + return NULL; + } + + g2 = factorsNv->g; + h2 = cuddBddAndRecur(dd, x, factorsNv->h); + if (h2 != NULL) cuddRef(h2); + if (h2 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNv->g); + return NULL; + } + + /* check whether any pair is in tables */ + factors = CheckInTables(node, g1, h1, g2, h2, ghTable, cacheTable, &outOfMem); + if (outOfMem) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + return NULL; + } + if (factors != NULL) { + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + return factors; + } + + /* check for each pair in tables and choose one */ + factors = PickOnePair(node,g1, h1, g2, h2, ghTable, cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + /* now free what was created and not used */ + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + } + + return(factors); +} /* end of ZeroCase */ + + +/**Function******************************************************************** + + Synopsis [Builds the conjuncts recursively, bottom up.] + + Description [Builds the conjuncts recursively, bottom up. Constants + are returned as (f, f). The cache is checked for previously computed + result. The decomposition points are determined by the local + reference count of this node and the longest distance from the + constant. At the decomposition point, the factors returned are (f, + 1). Recur on the two children. The order is determined by the + heavier branch. Combine the factors of the two children and pick the + one that already occurs in the gh table. Occurence in g is indicated + by value 1, occurence in h by 2, occurence in both 3.] + + SideEffects [] + + SeeAlso [cuddConjunctsAux] + +******************************************************************************/ +static Conjuncts * +BuildConjuncts( + DdManager * dd, + DdNode * node, + st_table * distanceTable, + st_table * cacheTable, + int approxDistance, + int maxLocalRef, + st_table * ghTable, + st_table * mintermTable) +{ + int topid, distance; + Conjuncts *factorsNv, *factorsNnv, *factors; + Conjuncts *dummy; + DdNode *N, *Nv, *Nnv, *temp, *g1, *g2, *h1, *h2, *topv; + double minNv = 0.0, minNnv = 0.0; + double *doubleDummy; + int switched =0; + int outOfMem; + int freeNv = 0, freeNnv = 0, freeTemp; + NodeStat *nodeStat; + int value; + + /* if f is constant, return (f,f) */ + if (Cudd_IsConstant(node)) { + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + factors->g = node; + factors->h = node; + return(FactorsComplement(factors)); + } + + /* If result (a pair of conjuncts) in cache, return the factors. */ + if (st_lookup(cacheTable, node, &dummy)) { + factors = dummy; + return(factors); + } + + /* check distance and local reference count of this node */ + N = Cudd_Regular(node); + if (!st_lookup(distanceTable, N, &nodeStat)) { + (void) fprintf(dd->err, "Not in table, Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + distance = nodeStat->distance; + + /* at or below decomposition point, return (f, 1) */ + if (((nodeStat->localRef > maxLocalRef*2/3) && + (distance < approxDistance*2/3)) || + (distance <= approxDistance/4)) { + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + /* alternate assigning (f,1) */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(node), &value)) { + if (value == 3) { + if (!lastTimeG) { + factors->g = node; + factors->h = one; + lastTimeG = 1; + } else { + factors->g = one; + factors->h = node; + lastTimeG = 0; + } + } else if (value == 1) { + factors->g = node; + factors->h = one; + } else { + factors->g = one; + factors->h = node; + } + } else if (!lastTimeG) { + factors->g = node; + factors->h = one; + lastTimeG = 1; + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(factors); + return NULL; + } + } else { + factors->g = one; + factors->h = node; + lastTimeG = 0; + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(factors); + return NULL; + } + } + return(FactorsComplement(factors)); + } + + /* get the children and recur */ + Nv = cuddT(N); + Nnv = cuddE(N); + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* Choose which subproblem to solve first based on the number of + * minterms. We go first where there are more minterms. + */ + if (!Cudd_IsConstant(Nv)) { + if (!st_lookup(mintermTable, Nv, &doubleDummy)) { + (void) fprintf(dd->err, "Not in table: Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + minNv = *doubleDummy; + } + + if (!Cudd_IsConstant(Nnv)) { + if (!st_lookup(mintermTable, Nnv, &doubleDummy)) { + (void) fprintf(dd->err, "Not in table: Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + minNnv = *doubleDummy; + } + + if (minNv < minNnv) { + temp = Nv; + Nv = Nnv; + Nnv = temp; + switched = 1; + } + + /* build gt, ht recursively */ + if (Nv != zero) { + factorsNv = BuildConjuncts(dd, Nv, distanceTable, + cacheTable, approxDistance, maxLocalRef, + ghTable, mintermTable); + if (factorsNv == NULL) return(NULL); + freeNv = FactorsNotStored(factorsNv); + factorsNv = (freeNv) ? FactorsUncomplement(factorsNv) : factorsNv; + cuddRef(factorsNv->g); + cuddRef(factorsNv->h); + + /* Deal with the zero case */ + if (Nnv == zero) { + /* is responsible for freeing factorsNv */ + factors = ZeroCase(dd, node, factorsNv, ghTable, + cacheTable, switched); + if (freeNv) FREE(factorsNv); + return(factors); + } + } + + /* build ge, he recursively */ + if (Nnv != zero) { + factorsNnv = BuildConjuncts(dd, Nnv, distanceTable, + cacheTable, approxDistance, maxLocalRef, + ghTable, mintermTable); + if (factorsNnv == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + if (freeNv) FREE(factorsNv); + return(NULL); + } + freeNnv = FactorsNotStored(factorsNnv); + factorsNnv = (freeNnv) ? FactorsUncomplement(factorsNnv) : factorsNnv; + cuddRef(factorsNnv->g); + cuddRef(factorsNnv->h); + + /* Deal with the zero case */ + if (Nv == zero) { + /* is responsible for freeing factorsNv */ + factors = ZeroCase(dd, node, factorsNnv, ghTable, + cacheTable, switched); + if (freeNnv) FREE(factorsNnv); + return(factors); + } + } + + /* construct the 2 pairs */ + /* g1 = x*gt + x'*ge; h1 = x*ht + x'*he; */ + /* g2 = x*gt + x'*he; h2 = x*ht + x'*ge */ + if (switched) { + factors = factorsNnv; + factorsNnv = factorsNv; + factorsNv = factors; + freeTemp = freeNv; + freeNv = freeNnv; + freeNnv = freeTemp; + } + + /* Build the factors for this node. */ + topid = N->index; + topv = dd->vars[topid]; + + g1 = cuddBddIteRecur(dd, topv, factorsNv->g, factorsNnv->g); + if (g1 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + + cuddRef(g1); + + h1 = cuddBddIteRecur(dd, topv, factorsNv->h, factorsNnv->h); + if (h1 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + + cuddRef(h1); + + g2 = cuddBddIteRecur(dd, topv, factorsNv->g, factorsNnv->h); + if (g2 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + cuddRef(g2); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + + h2 = cuddBddIteRecur(dd, topv, factorsNv->h, factorsNnv->g); + if (h2 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + cuddRef(h2); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + + /* check for each pair in tables and choose one */ + factors = CheckInTables(node, g1, h1, g2, h2, ghTable, cacheTable, &outOfMem); + if (outOfMem) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + return(NULL); + } + if (factors != NULL) { + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + return(factors); + } + + /* if not in tables, pick one pair */ + factors = PickOnePair(node,g1, h1, g2, h2, ghTable, cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + /* now free what was created and not used */ + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + } + + return(factors); + +} /* end of BuildConjuncts */ + + +/**Function******************************************************************** + + Synopsis [Procedure to compute two conjunctive factors of f and place in *c1 and *c2.] + + Description [Procedure to compute two conjunctive factors of f and + place in *c1 and *c2. Sets up the required data - table of distances + from the constant and local reference count. Also minterm table. ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +static int +cuddConjunctsAux( + DdManager * dd, + DdNode * f, + DdNode ** c1, + DdNode ** c2) +{ + st_table *distanceTable = NULL; + st_table *cacheTable = NULL; + st_table *mintermTable = NULL; + st_table *ghTable = NULL; + st_generator *stGen; + char *key, *value; + Conjuncts *factors; + int distance, approxDistance; + double max, minterms; + int freeFactors; + NodeStat *nodeStat; + int maxLocalRef; + + /* initialize */ + *c1 = NULL; + *c2 = NULL; + + /* initialize distances table */ + distanceTable = st_init_table(st_ptrcmp,st_ptrhash); + if (distanceTable == NULL) goto outOfMem; + + /* make the entry for the constant */ + nodeStat = ALLOC(NodeStat, 1); + if (nodeStat == NULL) goto outOfMem; + nodeStat->distance = 0; + nodeStat->localRef = 1; + if (st_insert(distanceTable, (char *)one, (char *)nodeStat) == ST_OUT_OF_MEM) { + goto outOfMem; + } + + /* Count node distances from constant. */ + nodeStat = CreateBotDist(f, distanceTable); + if (nodeStat == NULL) goto outOfMem; + + /* set the distance for the decomposition points */ + approxDistance = (DEPTH < nodeStat->distance) ? nodeStat->distance : DEPTH; + distance = nodeStat->distance; + + if (distance < approxDistance) { + /* Too small to bother. */ + *c1 = f; + *c2 = DD_ONE(dd); + cuddRef(*c1); cuddRef(*c2); + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); + return(1); + } + + /* record the maximum local reference count */ + maxLocalRef = 0; + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + nodeStat = (NodeStat *)value; + maxLocalRef = (nodeStat->localRef > maxLocalRef) ? + nodeStat->localRef : maxLocalRef; + } + st_free_gen(stGen); stGen = NULL; + + + /* Count minterms for each node. */ + max = pow(2.0, (double)Cudd_SupportSize(dd,f)); /* potential overflow */ + mintermTable = st_init_table(st_ptrcmp,st_ptrhash); + if (mintermTable == NULL) goto outOfMem; + minterms = CountMinterms(f, max, mintermTable, dd->err); + if (minterms == -1.0) goto outOfMem; + + lastTimeG = Cudd_Random() & 1; + cacheTable = st_init_table(st_ptrcmp, st_ptrhash); + if (cacheTable == NULL) goto outOfMem; + ghTable = st_init_table(st_ptrcmp, st_ptrhash); + if (ghTable == NULL) goto outOfMem; + + /* Build conjuncts. */ + factors = BuildConjuncts(dd, f, distanceTable, cacheTable, + approxDistance, maxLocalRef, ghTable, mintermTable); + if (factors == NULL) goto outOfMem; + + /* free up tables */ + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); distanceTable = NULL; + st_free_table(ghTable); ghTable = NULL; + + stGen = st_init_gen(mintermTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(mintermTable); mintermTable = NULL; + + freeFactors = FactorsNotStored(factors); + factors = (freeFactors) ? FactorsUncomplement(factors) : factors; + if (factors != NULL) { + *c1 = factors->g; + *c2 = factors->h; + cuddRef(*c1); + cuddRef(*c2); + if (freeFactors) FREE(factors); + +#if 0 + if ((*c1 == f) && (!Cudd_IsConstant(f))) { + assert(*c2 == one); + } + if ((*c2 == f) && (!Cudd_IsConstant(f))) { + assert(*c1 == one); + } + + if ((*c1 != one) && (!Cudd_IsConstant(f))) { + assert(!Cudd_bddLeq(dd, *c2, *c1)); + } + if ((*c2 != one) && (!Cudd_IsConstant(f))) { + assert(!Cudd_bddLeq(dd, *c1, *c2)); + } +#endif + } + + stGen = st_init_gen(cacheTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + ConjunctsFree(dd, (Conjuncts *)value); + } + st_free_gen(stGen); stGen = NULL; + + st_free_table(cacheTable); cacheTable = NULL; + + return(1); + +outOfMem: + if (distanceTable != NULL) { + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); distanceTable = NULL; + } + if (mintermTable != NULL) { + stGen = st_init_gen(mintermTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(mintermTable); mintermTable = NULL; + } + if (ghTable != NULL) st_free_table(ghTable); + if (cacheTable != NULL) { + stGen = st_init_gen(cacheTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + ConjunctsFree(dd, (Conjuncts *)value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(cacheTable); cacheTable = NULL; + } + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + +} /* end of cuddConjunctsAux */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddEssent.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddEssent.c new file mode 100644 index 000000000..7af6df651 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddEssent.c @@ -0,0 +1,1467 @@ +/**CFile*********************************************************************** + + FileName [cuddEssent.c] + + PackageName [cudd] + + Synopsis [Functions for the detection of essential variables.] + + Description [External procedures included in this file: +
    +
  • Cudd_FindEssential() +
  • Cudd_bddIsVarEssential() +
  • Cudd_FindTwoLiteralClauses() +
  • Cudd_ReadIthClause() +
  • Cudd_PrintTwoLiteralClauses() +
  • Cudd_tlcInfoFree() +
+ Static procedures included in this module: +
    +
  • ddFindEssentialRecur() +
  • ddFindTwoLiteralClausesRecur() +
  • computeClauses() +
  • computeClausesWithUniverse() +
  • emptyClauseSet() +
  • sentinelp() +
  • equalp() +
  • beforep() +
  • oneliteralp() +
  • impliedp() +
  • bitVectorAlloc() +
  • bitVectorClear() +
  • bitVectorFree() +
  • bitVectorRead() +
  • bitVectorSet() +
  • tlcInfoAlloc() +
] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* These definitions are for the bit vectors. */ +#if SIZEOF_LONG == 8 +#define BPL 64 +#define LOGBPL 6 +#else +#define BPL 32 +#define LOGBPL 5 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/* This structure holds the set of clauses for a node. Each clause consists +** of two literals. For one-literal clauses, the second lietral is FALSE. +** Each literal is composed of a variable and a phase. A variable is a node +** index, and requires sizeof(DdHalfWord) bytes. The constant literals use +** CUDD_MAXINDEX as variable indicator. Each phase is a bit: 0 for positive +** phase, and 1 for negative phase. +** Variables and phases are stored separately for the sake of compactness. +** The variables are stored in an array of DdHalfWord's terminated by a +** sentinel (a pair of zeroes). The phases are stored in a bit vector. +** The cnt field holds, at the end, the number of clauses. +** The clauses of the set are kept sorted. For each clause, the first literal +** is the one of least index. So, the clause with literals +2 and -4 is stored +** as (+2,-4). A one-literal clause with literal +3 is stored as +** (+3,-CUDD_MAXINDEX). Clauses are sorted in decreasing order as follows: +** (+5,-7) +** (+5,+6) +** (-5,+7) +** (-4,FALSE) +** (-4,+8) +** ... +** That is, one first looks at the variable of the first literal, then at the +** phase of the first litral, then at the variable of the second literal, +** and finally at the phase of the second literal. +*/ +struct DdTlcInfo { + DdHalfWord *vars; + long *phases; + DdHalfWord cnt; +}; + +/* This structure is for temporary representation of sets of clauses. It is +** meant to be used in link lists, when the number of clauses is not yet +** known. The encoding of a clause is the same as in DdTlcInfo, though +** the phase information is not stored in a bit array. */ +struct TlClause { + DdHalfWord v1, v2; + short p1, p2; + struct TlClause *next; +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef long BitVector; +typedef struct TlClause TlClause; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddEssent.c,v 1.25 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static BitVector *Tolv; +static BitVector *Tolp; +static BitVector *Eolv; +static BitVector *Eolp; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * ddFindEssentialRecur (DdManager *dd, DdNode *f); +static DdTlcInfo * ddFindTwoLiteralClausesRecur (DdManager * dd, DdNode * f, st_table *table); +static DdTlcInfo * computeClauses (DdTlcInfo *Tres, DdTlcInfo *Eres, DdHalfWord label, int size); +static DdTlcInfo * computeClausesWithUniverse (DdTlcInfo *Cres, DdHalfWord label, short phase); +static DdTlcInfo * emptyClauseSet (void); +static int sentinelp (DdHalfWord var1, DdHalfWord var2); +static int equalp (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b); +static int beforep (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b); +static int oneliteralp (DdHalfWord var); +static int impliedp (DdHalfWord var1, short phase1, DdHalfWord var2, short phase2, BitVector *olv, BitVector *olp); +static BitVector * bitVectorAlloc (int size); +DD_INLINE static void bitVectorClear (BitVector *vector, int size); +static void bitVectorFree (BitVector *vector); +DD_INLINE static short bitVectorRead (BitVector *vector, int i); +DD_INLINE static void bitVectorSet (BitVector * vector, int i, short val); +static DdTlcInfo * tlcInfoAlloc (void); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Finds the essential variables of a DD.] + + Description [Returns the cube of the essential variables. A positive + literal means that the variable must be set to 1 for the function to be + 1. A negative literal means that the variable must be set to 0 for the + function to be 1. Returns a pointer to the cube BDD if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddIsVarEssential] + +******************************************************************************/ +DdNode * +Cudd_FindEssential( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = ddFindEssentialRecur(dd,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_FindEssential */ + + +/**Function******************************************************************** + + Synopsis [Determines whether a given variable is essential with a + given phase in a BDD.] + + Description [Determines whether a given variable is essential with a + given phase in a BDD. Uses Cudd_bddIteConstant. Returns 1 if phase == 1 + and f-->x_id, or if phase == 0 and f-->x_id'.] + + SideEffects [None] + + SeeAlso [Cudd_FindEssential] + +******************************************************************************/ +int +Cudd_bddIsVarEssential( + DdManager * manager, + DdNode * f, + int id, + int phase) +{ + DdNode *var; + int res; + + var = Cudd_bddIthVar(manager, id); + + var = Cudd_NotCond(var,phase == 0); + + res = Cudd_bddLeq(manager, f, var); + + return(res); + +} /* end of Cudd_bddIsVarEssential */ + + +/**Function******************************************************************** + + Synopsis [Finds the two literal clauses of a DD.] + + Description [Returns the one- and two-literal clauses of a DD. + Returns a pointer to the structure holding the clauses if + successful; NULL otherwise. For a constant DD, the empty set of clauses + is returned. This is obviously correct for a non-zero constant. For the + constant zero, it is based on the assumption that only those clauses + containing variables in the support of the function are considered. Since + the support of a constant function is empty, no clauses are returned.] + + SideEffects [None] + + SeeAlso [Cudd_FindEssential] + +******************************************************************************/ +DdTlcInfo * +Cudd_FindTwoLiteralClauses( + DdManager * dd, + DdNode * f) +{ + DdTlcInfo *res; + st_table *table; + st_generator *gen; + DdTlcInfo *tlc; + DdNode *node; + int size = dd->size; + + if (Cudd_IsConstant(f)) { + res = emptyClauseSet(); + return(res); + } + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) return(NULL); + Tolv = bitVectorAlloc(size); + if (Tolv == NULL) { + st_free_table(table); + return(NULL); + } + Tolp = bitVectorAlloc(size); + if (Tolp == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + return(NULL); + } + Eolv = bitVectorAlloc(size); + if (Eolv == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + return(NULL); + } + Eolp = bitVectorAlloc(size); + if (Eolp == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + bitVectorFree(Eolv); + return(NULL); + } + + res = ddFindTwoLiteralClausesRecur(dd,f,table); + /* Dispose of table contents and free table. */ + st_foreach_item(table, gen, &node, &tlc) { + if (node != f) { + Cudd_tlcInfoFree(tlc); + } + } + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + bitVectorFree(Eolv); + bitVectorFree(Eolp); + + if (res != NULL) { + int i; + for (i = 0; !sentinelp(res->vars[i], res->vars[i+1]); i += 2); + res->cnt = i >> 1; + } + + return(res); + +} /* end of Cudd_FindTwoLiteralClauses */ + + +/**Function******************************************************************** + + Synopsis [Accesses the i-th clause of a DD.] + + Description [Accesses the i-th clause of a DD given the clause set which + must be already computed. Returns 1 if successful; 0 if i is out of range, + or in case of error.] + + SideEffects [the four components of a clause are returned as side effects.] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +int +Cudd_ReadIthClause( + DdTlcInfo * tlc, + int i, + DdHalfWord *var1, + DdHalfWord *var2, + int *phase1, + int *phase2) +{ + if (tlc == NULL) return(0); + if (tlc->vars == NULL || tlc->phases == NULL) return(0); + if (i < 0 || (unsigned) i >= tlc->cnt) return(0); + *var1 = tlc->vars[2*i]; + *var2 = tlc->vars[2*i+1]; + *phase1 = (int) bitVectorRead(tlc->phases, 2*i); + *phase2 = (int) bitVectorRead(tlc->phases, 2*i+1); + return(1); + +} /* end of Cudd_ReadIthClause */ + + +/**Function******************************************************************** + + Synopsis [Prints the two literal clauses of a DD.] + + Description [Prints the one- and two-literal clauses. Returns 1 if + successful; 0 otherwise. The argument "names" can be NULL, in which case + the variable indices are printed.] + + SideEffects [None] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +int +Cudd_PrintTwoLiteralClauses( + DdManager * dd, + DdNode * f, + char **names, + FILE *fp) +{ + DdHalfWord *vars; + BitVector *phases; + int i; + DdTlcInfo *res = Cudd_FindTwoLiteralClauses(dd, f); + FILE *ifp = fp == NULL ? dd->out : fp; + + if (res == NULL) return(0); + vars = res->vars; + phases = res->phases; + for (i = 0; !sentinelp(vars[i], vars[i+1]); i += 2) { + if (names != NULL) { + if (vars[i+1] == CUDD_MAXINDEX) { + (void) fprintf(ifp, "%s%s\n", + bitVectorRead(phases, i) ? "~" : " ", + names[vars[i]]); + } else { + (void) fprintf(ifp, "%s%s | %s%s\n", + bitVectorRead(phases, i) ? "~" : " ", + names[vars[i]], + bitVectorRead(phases, i+1) ? "~" : " ", + names[vars[i+1]]); + } + } else { + if (vars[i+1] == CUDD_MAXINDEX) { + (void) fprintf(ifp, "%s%d\n", + bitVectorRead(phases, i) ? "~" : " ", + (int) vars[i]); + } else { + (void) fprintf(ifp, "%s%d | %s%d\n", + bitVectorRead(phases, i) ? "~" : " ", + (int) vars[i], + bitVectorRead(phases, i+1) ? "~" : " ", + (int) vars[i+1]); + } + } + } + Cudd_tlcInfoFree(res); + + return(1); + +} /* end of Cudd_PrintTwoLiteralClauses */ + + +/**Function******************************************************************** + + Synopsis [Frees a DdTlcInfo Structure.] + + Description [Frees a DdTlcInfo Structure as well as the memory pointed + by it.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_tlcInfoFree( + DdTlcInfo * t) +{ + if (t->vars != NULL) FREE(t->vars); + if (t->phases != NULL) FREE(t->phases); + FREE(t); + +} /* end of Cudd_tlcInfoFree */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_FindEssential.] + + Description [Implements the recursive step of Cudd_FindEssential. + Returns a pointer to the cube BDD if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +ddFindEssentialRecur( + DdManager * dd, + DdNode * f) +{ + DdNode *T, *E, *F; + DdNode *essT, *essE, *res; + int index; + DdNode *one, *lzero, *azero; + + one = DD_ONE(dd); + F = Cudd_Regular(f); + /* If f is constant the set of essential variables is empty. */ + if (cuddIsConstant(F)) return(one); + + res = cuddCacheLookup1(dd,Cudd_FindEssential,f); + if (res != NULL) { + return(res); + } + + lzero = Cudd_Not(one); + azero = DD_ZERO(dd); + /* Find cofactors: here f is non-constant. */ + T = cuddT(F); + E = cuddE(F); + if (Cudd_IsComplement(f)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + + index = F->index; + if (Cudd_IsConstant(T) && T != lzero && T != azero) { + /* if E is zero, index is essential, otherwise there are no + ** essentials, because index is not essential and no other variable + ** can be, since setting index = 1 makes the function constant and + ** different from 0. + */ + if (E == lzero || E == azero) { + res = dd->vars[index]; + } else { + res = one; + } + } else if (T == lzero || T == azero) { + if (Cudd_IsConstant(E)) { /* E cannot be zero here */ + res = Cudd_Not(dd->vars[index]); + } else { /* E == non-constant */ + /* find essentials in the else branch */ + essE = ddFindEssentialRecur(dd,E); + if (essE == NULL) { + return(NULL); + } + cuddRef(essE); + + /* add index to the set with negative phase */ + res = cuddUniqueInter(dd,index,one,Cudd_Not(essE)); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essE); + return(NULL); + } + res = Cudd_Not(res); + cuddDeref(essE); + } + } else { /* T == non-const */ + if (E == lzero || E == azero) { + /* find essentials in the then branch */ + essT = ddFindEssentialRecur(dd,T); + if (essT == NULL) { + return(NULL); + } + cuddRef(essT); + + /* add index to the set with positive phase */ + /* use And because essT may be complemented */ + res = cuddBddAndRecur(dd,dd->vars[index],essT); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essT); + return(NULL); + } + cuddDeref(essT); + } else if (!Cudd_IsConstant(E)) { + /* if E is a non-zero constant there are no essentials + ** because T is non-constant. + */ + essT = ddFindEssentialRecur(dd,T); + if (essT == NULL) { + return(NULL); + } + if (essT == one) { + res = one; + } else { + cuddRef(essT); + essE = ddFindEssentialRecur(dd,E); + if (essE == NULL) { + Cudd_RecursiveDeref(dd,essT); + return(NULL); + } + cuddRef(essE); + + /* res = intersection(essT, essE) */ + res = cuddBddLiteralSetIntersectionRecur(dd,essT,essE); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essT); + Cudd_RecursiveDeref(dd,essE); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,essT); + Cudd_RecursiveDeref(dd,essE); + cuddDeref(res); + } + } else { /* E is a non-zero constant */ + res = one; + } + } + + cuddCacheInsert1(dd,Cudd_FindEssential, f, res); + return(res); + +} /* end of ddFindEssentialRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_FindTwoLiteralClauses.] + + Description [Implements the recursive step of + Cudd_FindTwoLiteralClauses. The DD node is assumed to be not + constant. Returns a pointer to a set of clauses if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +static DdTlcInfo * +ddFindTwoLiteralClausesRecur( + DdManager * dd, + DdNode * f, + st_table *table) +{ + DdNode *T, *E, *F; + DdNode *one, *lzero, *azero; + DdTlcInfo *res, *Tres, *Eres; + DdHalfWord index; + + F = Cudd_Regular(f); + + assert(!cuddIsConstant(F)); + + /* Check computed table. Separate entries are necessary for + ** a node and its complement. We should update the counter here. */ + if (st_lookup(table, f, &res)) { + return(res); + } + + /* Easy access to the constants for BDDs and ADDs. */ + one = DD_ONE(dd); + lzero = Cudd_Not(one); + azero = DD_ZERO(dd); + + /* Find cofactors and variable labeling the top node. */ + T = cuddT(F); E = cuddE(F); + if (Cudd_IsComplement(f)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + index = F->index; + + if (Cudd_IsConstant(T) && T != lzero && T != azero) { + /* T is a non-zero constant. If E is zero, then this node's index + ** is a one-literal clause. Otherwise, if E is a non-zero + ** constant, there are no clauses for this node. Finally, + ** if E is not constant, we recursively compute its clauses, and then + ** merge using the empty set for T. */ + if (E == lzero || E == azero) { + /* Create the clause (index + 0). */ + res = tlcInfoAlloc(); + if (res == NULL) return(NULL); + res->vars = ALLOC(DdHalfWord,4); + if (res->vars == NULL) { + FREE(res); + return(NULL); + } + res->phases = bitVectorAlloc(2); + if (res->phases == NULL) { + FREE(res->vars); + FREE(res); + return(NULL); + } + res->vars[0] = index; + res->vars[1] = CUDD_MAXINDEX; + res->vars[2] = 0; + res->vars[3] = 0; + bitVectorSet(res->phases, 0, 0); /* positive phase */ + bitVectorSet(res->phases, 1, 1); /* negative phase */ + } else if (Cudd_IsConstant(E)) { + /* If E is a non-zero constant, no clauses. */ + res = emptyClauseSet(); + } else { + /* E is non-constant */ + Tres = emptyClauseSet(); + if (Tres == NULL) return(NULL); + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) { + Cudd_tlcInfoFree(Tres); + return(NULL); + } + res = computeClauses(Tres, Eres, index, dd->size); + Cudd_tlcInfoFree(Tres); + } + } else if (T == lzero || T == azero) { + /* T is zero. If E is a non-zero constant, then the + ** complement of this node's index is a one-literal clause. + ** Otherwise, if E is not constant, we recursively compute its + ** clauses, and then merge using the universal set for T. */ + if (Cudd_IsConstant(E)) { /* E cannot be zero here */ + /* Create the clause (!index + 0). */ + res = tlcInfoAlloc(); + if (res == NULL) return(NULL); + res->vars = ALLOC(DdHalfWord,4); + if (res->vars == NULL) { + FREE(res); + return(NULL); + } + res->phases = bitVectorAlloc(2); + if (res->phases == NULL) { + FREE(res->vars); + FREE(res); + return(NULL); + } + res->vars[0] = index; + res->vars[1] = CUDD_MAXINDEX; + res->vars[2] = 0; + res->vars[3] = 0; + bitVectorSet(res->phases, 0, 1); /* negative phase */ + bitVectorSet(res->phases, 1, 1); /* negative phase */ + } else { /* E == non-constant */ + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) return(NULL); + res = computeClausesWithUniverse(Eres, index, 1); + } + } else { /* T == non-const */ + Tres = ddFindTwoLiteralClausesRecur(dd, T, table); + if (Tres == NULL) return(NULL); + if (Cudd_IsConstant(E)) { + if (E == lzero || E == azero) { + res = computeClausesWithUniverse(Tres, index, 0); + } else { + Eres = emptyClauseSet(); + if (Eres == NULL) return(NULL); + res = computeClauses(Tres, Eres, index, dd->size); + Cudd_tlcInfoFree(Eres); + } + } else { + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) return(NULL); + res = computeClauses(Tres, Eres, index, dd->size); + } + } + + /* Cache results. */ + if (st_add_direct(table, (char *)f, (char *)res) == ST_OUT_OF_MEM) { + FREE(res); + return(NULL); + } + return(res); + +} /* end of ddFindTwoLiteralClausesRecur */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-literal clauses for a node.] + + Description [Computes the two-literal clauses for a node given the + clauses for its children and the label of the node. Returns a + pointer to a TclInfo structure if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [computeClausesWithUniverse] + +******************************************************************************/ +static DdTlcInfo * +computeClauses( + DdTlcInfo *Tres /* list of clauses for T child */, + DdTlcInfo *Eres /* list of clauses for E child */, + DdHalfWord label /* variable labeling the current node */, + int size /* number of variables in the manager */) +{ + DdHalfWord *Tcv = Tres->vars; /* variables of clauses for the T child */ + BitVector *Tcp = Tres->phases; /* phases of clauses for the T child */ + DdHalfWord *Ecv = Eres->vars; /* variables of clauses for the E child */ + BitVector *Ecp = Eres->phases; /* phases of clauses for the E child */ + DdHalfWord *Vcv = NULL; /* pointer to variables of the clauses for v */ + BitVector *Vcp = NULL; /* pointer to phases of the clauses for v */ + DdTlcInfo *res = NULL; /* the set of clauses to be returned */ + int pt = 0; /* index in the list of clauses of T */ + int pe = 0; /* index in the list of clauses of E */ + int cv = 0; /* counter of the clauses for this node */ + TlClause *iclauses = NULL; /* list of inherited clauses */ + TlClause *tclauses = NULL; /* list of 1-literal clauses of T */ + TlClause *eclauses = NULL; /* list of 1-literal clauses of E */ + TlClause *nclauses = NULL; /* list of new (non-inherited) clauses */ + TlClause *lnclause = NULL; /* pointer to last new clause */ + TlClause *newclause; /* temporary pointer to new clauses */ + + /* Initialize sets of one-literal clauses. The one-literal clauses + ** are stored redundantly. These sets allow constant-time lookup, which + ** we need when we check for implication of a two-literal clause by a + ** one-literal clause. The linked lists allow fast sequential + ** processing. */ + bitVectorClear(Tolv, size); + bitVectorClear(Tolp, size); + bitVectorClear(Eolv, size); + bitVectorClear(Eolp, size); + + /* Initialize result structure. */ + res = tlcInfoAlloc(); + if (res == NULL) goto cleanup; + + /* Scan the two input list. Extract inherited two-literal clauses + ** and set aside one-literal clauses from each list. The incoming lists + ** are sorted in the order defined by beforep. The three linked list + ** produced by this loop are sorted in the reverse order because we + ** always append to the front of the lists. + ** The inherited clauses are those clauses (both one- and two-literal) + ** that are common to both children; and the two-literal clauses of + ** one child that are implied by a one-literal clause of the other + ** child. */ + while (!sentinelp(Tcv[pt], Tcv[pt+1]) || !sentinelp(Ecv[pe], Ecv[pe+1])) { + if (equalp(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1))) { + /* Add clause to inherited list. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = Tcv[pt+1]; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = bitVectorRead(Tcp, pt+1); + newclause->next = iclauses; + iclauses = newclause; + pt += 2; pe += 2; cv++; + } else if (beforep(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1))) { + if (oneliteralp(Tcv[pt+1])) { + /* Add this one-literal clause to the T set. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = 1; + newclause->next = tclauses; + tclauses = newclause; + bitVectorSet(Tolv, Tcv[pt], 1); + bitVectorSet(Tolp, Tcv[pt], bitVectorRead(Tcp, pt)); + } else { + if (impliedp(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Eolv, Eolp)) { + /* Add clause to inherited list. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = Tcv[pt+1]; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = bitVectorRead(Tcp, pt+1); + newclause->next = iclauses; + iclauses = newclause; + cv++; + } + } + pt += 2; + } else { /* !beforep() */ + if (oneliteralp(Ecv[pe+1])) { + /* Add this one-literal clause to the E set. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Ecv[pe]; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = bitVectorRead(Ecp, pe); + newclause->p2 = 1; + newclause->next = eclauses; + eclauses = newclause; + bitVectorSet(Eolv, Ecv[pe], 1); + bitVectorSet(Eolp, Ecv[pe], bitVectorRead(Ecp, pe)); + } else { + if (impliedp(Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1), + Tolv, Tolp)) { + /* Add clause to inherited list. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Ecv[pe]; + newclause->v2 = Ecv[pe+1]; + newclause->p1 = bitVectorRead(Ecp, pe); + newclause->p2 = bitVectorRead(Ecp, pe+1); + newclause->next = iclauses; + iclauses = newclause; + cv++; + } + } + pe += 2; + } + } + + /* Add one-literal clauses for the label variable to the front of + ** the two lists. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = label; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = 0; + newclause->p2 = 1; + newclause->next = tclauses; + tclauses = newclause; + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = label; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = 1; + newclause->p2 = 1; + newclause->next = eclauses; + eclauses = newclause; + + /* Produce the non-inherited clauses. We preserve the "reverse" + ** order of the two input lists by appending to the end of the + ** list. In this way, iclauses and nclauses are consistent. */ + while (tclauses != NULL && eclauses != NULL) { + if (beforep(eclauses->v1, eclauses->p1, eclauses->v2, eclauses->p2, + tclauses->v1, tclauses->p1, tclauses->v2, tclauses->p2)) { + TlClause *nextclause = tclauses->next; + TlClause *otherclauses = eclauses; + while (otherclauses != NULL) { + if (tclauses->v1 != otherclauses->v1) { + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = tclauses->v1; + newclause->v2 = otherclauses->v1; + newclause->p1 = tclauses->p1; + newclause->p2 = otherclauses->p1; + newclause->next = NULL; + if (nclauses == NULL) { + nclauses = newclause; + lnclause = newclause; + } else { + lnclause->next = newclause; + lnclause = newclause; + } + cv++; + } + otherclauses = otherclauses->next; + } + FREE(tclauses); + tclauses = nextclause; + } else { + TlClause *nextclause = eclauses->next; + TlClause *otherclauses = tclauses; + while (otherclauses != NULL) { + if (eclauses->v1 != otherclauses->v1) { + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = eclauses->v1; + newclause->v2 = otherclauses->v1; + newclause->p1 = eclauses->p1; + newclause->p2 = otherclauses->p1; + newclause->next = NULL; + if (nclauses == NULL) { + nclauses = newclause; + lnclause = newclause; + } else { + lnclause->next = newclause; + lnclause = newclause; + } + cv++; + } + otherclauses = otherclauses->next; + } + FREE(eclauses); + eclauses = nextclause; + } + } + while (tclauses != NULL) { + TlClause *nextclause = tclauses->next; + FREE(tclauses); + tclauses = nextclause; + } + while (eclauses != NULL) { + TlClause *nextclause = eclauses->next; + FREE(eclauses); + eclauses = nextclause; + } + + /* Merge inherited and non-inherited clauses. Now that we know the + ** total number, we allocate the arrays, and we fill them bottom-up + ** to restore the proper ordering. */ + Vcv = ALLOC(DdHalfWord, 2*(cv+1)); + if (Vcv == NULL) goto cleanup; + if (cv > 0) { + Vcp = bitVectorAlloc(2*cv); + if (Vcp == NULL) goto cleanup; + } else { + Vcp = NULL; + } + res->vars = Vcv; + res->phases = Vcp; + /* Add sentinel. */ + Vcv[2*cv] = 0; + Vcv[2*cv+1] = 0; + while (iclauses != NULL || nclauses != NULL) { + TlClause *nextclause; + cv--; + if (nclauses == NULL || (iclauses != NULL && + beforep(nclauses->v1, nclauses->p1, nclauses->v2, nclauses->p2, + iclauses->v1, iclauses->p1, iclauses->v2, iclauses->p2))) { + Vcv[2*cv] = iclauses->v1; + Vcv[2*cv+1] = iclauses->v2; + bitVectorSet(Vcp, 2*cv, iclauses->p1); + bitVectorSet(Vcp, 2*cv+1, iclauses->p2); + nextclause = iclauses->next; + FREE(iclauses); + iclauses = nextclause; + } else { + Vcv[2*cv] = nclauses->v1; + Vcv[2*cv+1] = nclauses->v2; + bitVectorSet(Vcp, 2*cv, nclauses->p1); + bitVectorSet(Vcp, 2*cv+1, nclauses->p2); + nextclause = nclauses->next; + FREE(nclauses); + nclauses = nextclause; + } + } + assert(cv == 0); + + return(res); + + cleanup: + if (res != NULL) Cudd_tlcInfoFree(res); + while (iclauses != NULL) { + TlClause *nextclause = iclauses->next; + FREE(iclauses); + iclauses = nextclause; + } + while (nclauses != NULL) { + TlClause *nextclause = nclauses->next; + FREE(nclauses); + nclauses = nextclause; + } + while (tclauses != NULL) { + TlClause *nextclause = tclauses->next; + FREE(tclauses); + tclauses = nextclause; + } + while (eclauses != NULL) { + TlClause *nextclause = eclauses->next; + FREE(eclauses); + eclauses = nextclause; + } + + return(NULL); + +} /* end of computeClauses */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-literal clauses for a node.] + + Description [Computes the two-literal clauses for a node with a zero + child, given the clauses for its other child and the label of the + node. Returns a pointer to a TclInfo structure if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [computeClauses] + +******************************************************************************/ +static DdTlcInfo * +computeClausesWithUniverse( + DdTlcInfo *Cres /* list of clauses for child */, + DdHalfWord label /* variable labeling the current node */, + short phase /* 0 if E child is zero; 1 if T child is zero */) +{ + DdHalfWord *Ccv = Cres->vars; /* variables of clauses for child */ + BitVector *Ccp = Cres->phases; /* phases of clauses for child */ + DdHalfWord *Vcv = NULL; /* pointer to the variables of the clauses for v */ + BitVector *Vcp = NULL; /* pointer to the phases of the clauses for v */ + DdTlcInfo *res = NULL; /* the set of clauses to be returned */ + int i; + + /* Initialize result. */ + res = tlcInfoAlloc(); + if (res == NULL) goto cleanup; + /* Count entries for new list and allocate accordingly. */ + for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2); + /* At this point, i is twice the number of clauses in the child's + ** list. We need four more entries for this node: 2 for the one-literal + ** clause for the label, and 2 for the sentinel. */ + Vcv = ALLOC(DdHalfWord,i+4); + if (Vcv == NULL) goto cleanup; + Vcp = bitVectorAlloc(i+4); + if (Vcp == NULL) goto cleanup; + res->vars = Vcv; + res->phases = Vcp; + /* Copy old list into new. */ + for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2) { + Vcv[i] = Ccv[i]; + Vcv[i+1] = Ccv[i+1]; + bitVectorSet(Vcp, i, bitVectorRead(Ccp, i)); + bitVectorSet(Vcp, i+1, bitVectorRead(Ccp, i+1)); + } + /* Add clause corresponding to label. */ + Vcv[i] = label; + bitVectorSet(Vcp, i, phase); + i++; + Vcv[i] = CUDD_MAXINDEX; + bitVectorSet(Vcp, i, 1); + i++; + /* Add sentinel. */ + Vcv[i] = 0; + Vcv[i+1] = 0; + bitVectorSet(Vcp, i, 0); + bitVectorSet(Vcp, i+1, 0); + + return(res); + + cleanup: + /* Vcp is guaranteed to be NULL here. Hence, we do not try to free it. */ + if (Vcv != NULL) FREE(Vcv); + if (res != NULL) Cudd_tlcInfoFree(res); + + return(NULL); + +} /* end of computeClausesWithUniverse */ + + +/**Function******************************************************************** + + Synopsis [Returns an enpty set of clauses.] + + Description [Returns a pointer to an empty set of clauses if + successful; NULL otherwise. No bit vector for the phases is + allocated.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdTlcInfo * +emptyClauseSet(void) +{ + DdTlcInfo *eset; + + eset = ALLOC(DdTlcInfo,1); + if (eset == NULL) return(NULL); + eset->vars = ALLOC(DdHalfWord,2); + if (eset->vars == NULL) { + FREE(eset); + return(NULL); + } + /* Sentinel */ + eset->vars[0] = 0; + eset->vars[1] = 0; + eset->phases = NULL; /* does not matter */ + eset->cnt = 0; + return(eset); + +} /* end of emptyClauseSet */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the argument is the sentinel clause.] + + Description [Returns true iff the argument is the sentinel clause. + A sentinel clause has both variables equal to 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +sentinelp( + DdHalfWord var1, + DdHalfWord var2) +{ + return(var1 == 0 && var2 == 0); + +} /* end of sentinelp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the two arguments are identical clauses.] + + Description [Returns true iff the two arguments are identical + clauses. Since literals are sorted, we only need to compare + literals in the same position.] + + SideEffects [None] + + SeeAlso [beforep] + +******************************************************************************/ +static int +equalp( + DdHalfWord var1a, + short phase1a, + DdHalfWord var1b, + short phase1b, + DdHalfWord var2a, + short phase2a, + DdHalfWord var2b, + short phase2b) +{ + return(var1a == var2a && phase1a == phase2a && + var1b == var2b && phase1b == phase2b); + +} /* end of equalp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the first argument precedes the second in + the clause order.] + + Description [Returns true iff the first argument precedes the second + in the clause order. A clause precedes another if its first lieral + precedes the first literal of the other, or if the first literals + are the same, and its second literal precedes the second literal of + the other clause. A literal precedes another if it has a higher + index, of if it has the same index, but it has lower phase. Phase 0 + is the positive phase, and it is lower than Phase 1 (negative + phase).] + + SideEffects [None] + + SeeAlso [equalp] + +******************************************************************************/ +static int +beforep( + DdHalfWord var1a, + short phase1a, + DdHalfWord var1b, + short phase1b, + DdHalfWord var2a, + short phase2a, + DdHalfWord var2b, + short phase2b) +{ + return(var1a > var2a || (var1a == var2a && + (phase1a < phase2a || (phase1a == phase2a && + (var1b > var2b || (var1b == var2b && phase1b < phase2b)))))); + +} /* end of beforep */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the argument is a one-literal clause.] + + Description [Returns true iff the argument is a one-literal clause. + A one-litaral clause has the constant FALSE as second literal. + Since the constant TRUE is never used, it is sufficient to test for + a constant.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +oneliteralp( + DdHalfWord var) +{ + return(var == CUDD_MAXINDEX); + +} /* end of oneliteralp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff either literal of a clause is in a set of + literals.] + + Description [Returns true iff either literal of a clause is in a set + of literals. The first four arguments specify the clause. The + remaining two arguments specify the literal set.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +impliedp( + DdHalfWord var1, + short phase1, + DdHalfWord var2, + short phase2, + BitVector *olv, + BitVector *olp) +{ + return((bitVectorRead(olv, var1) && + bitVectorRead(olp, var1) == phase1) || + (bitVectorRead(olv, var2) && + bitVectorRead(olp, var2) == phase2)); + +} /* end of impliedp */ + + +/**Function******************************************************************** + + Synopsis [Allocates a bit vector.] + + Description [Allocates a bit vector. The parameter size gives the + number of bits. This procedure allocates enough long's to hold the + specified number of bits. Returns a pointer to the allocated vector + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [bitVectorClear bitVectorFree] + +******************************************************************************/ +static BitVector * +bitVectorAlloc( + int size) +{ + int allocSize; + BitVector *vector; + + /* Find out how many long's we need. + ** There are sizeof(long) * 8 bits in a long. + ** The ceiling of the ratio of two integers m and n is given + ** by ((n-1)/m)+1. Putting all this together, we get... */ + allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1; + vector = ALLOC(BitVector, allocSize); + if (vector == NULL) return(NULL); + /* Clear the whole array. */ + (void) memset(vector, 0, allocSize * sizeof(BitVector)); + return(vector); + +} /* end of bitVectorAlloc */ + + +/**Function******************************************************************** + + Synopsis [Clears a bit vector.] + + Description [Clears a bit vector. The parameter size gives the + number of bits.] + + SideEffects [None] + + SeeAlso [bitVectorAlloc] + +******************************************************************************/ +DD_INLINE +static void +bitVectorClear( + BitVector *vector, + int size) +{ + int allocSize; + + /* Find out how many long's we need. + ** There are sizeof(long) * 8 bits in a long. + ** The ceiling of the ratio of two integers m and n is given + ** by ((n-1)/m)+1. Putting all this together, we get... */ + allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1; + /* Clear the whole array. */ + (void) memset(vector, 0, allocSize * sizeof(BitVector)); + return; + +} /* end of bitVectorClear */ + + +/**Function******************************************************************** + + Synopsis [Frees a bit vector.] + + Description [Frees a bit vector.] + + SideEffects [None] + + SeeAlso [bitVectorAlloc] + +******************************************************************************/ +static void +bitVectorFree( + BitVector *vector) +{ + FREE(vector); + +} /* end of bitVectorFree */ + + +/**Function******************************************************************** + + Synopsis [Returns the i-th entry of a bit vector.] + + Description [Returns the i-th entry of a bit vector.] + + SideEffects [None] + + SeeAlso [bitVectorSet] + +******************************************************************************/ +DD_INLINE +static short +bitVectorRead( + BitVector *vector, + int i) +{ + int word, bit; + short result; + + if (vector == NULL) return((short) 0); + + word = i >> LOGBPL; + bit = i & (BPL - 1); + result = (short) ((vector[word] >> bit) & 1L); + return(result); + +} /* end of bitVectorRead */ + + +/**Function******************************************************************** + + Synopsis [Sets the i-th entry of a bit vector to a value.] + + Description [Sets the i-th entry of a bit vector to a value.] + + SideEffects [None] + + SeeAlso [bitVectorRead] + +******************************************************************************/ +DD_INLINE +static void +bitVectorSet( + BitVector * vector, + int i, + short val) +{ + int word, bit; + + word = i >> LOGBPL; + bit = i & (BPL - 1); + vector[word] &= ~(1L << bit); + vector[word] |= (((long) val) << bit); + +} /* end of bitVectorSet */ + + +/**Function******************************************************************** + + Synopsis [Allocates a DdTlcInfo Structure.] + + Description [Returns a pointer to a DdTlcInfo Structure if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_tlcInfoFree] + +******************************************************************************/ +static DdTlcInfo * +tlcInfoAlloc(void) +{ + DdTlcInfo *res = ALLOC(DdTlcInfo,1); + if (res == NULL) return(NULL); + res->vars = NULL; + res->phases = NULL; + res->cnt = 0; + return(res); + +} /* end of tlcInfoAlloc */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddExact.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddExact.c new file mode 100644 index 000000000..caffbba88 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddExact.c @@ -0,0 +1,1020 @@ +/**CFile*********************************************************************** + + FileName [cuddExact.c] + + PackageName [cudd] + + Synopsis [Functions for exact variable reordering.] + + Description [External procedures included in this file: +
    +
+ Internal procedures included in this module: +
    +
  • cuddExact() +
+ Static procedures included in this module: +
    +
  • getMaxBinomial() +
  • gcd() +
  • getMatrix() +
  • freeMatrix() +
  • getLevelKeys() +
  • ddShuffle() +
  • ddSiftUp() +
  • updateUB() +
  • ddCountRoots() +
  • ddClearGlobal() +
  • computeLB() +
  • updateEntry() +
  • pushDown() +
  • initSymmInfo() +
] + + Author [Cheng Hua, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddExact.c,v 1.30 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef DD_STATS +static int ddTotalShuffles; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int getMaxBinomial (int n); +static DdHalfWord ** getMatrix (int rows, int cols); +static void freeMatrix (DdHalfWord **matrix); +static int getLevelKeys (DdManager *table, int l); +static int ddShuffle (DdManager *table, DdHalfWord *permutation, int lower, int upper); +static int ddSiftUp (DdManager *table, int x, int xLow); +static int updateUB (DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper); +static int ddCountRoots (DdManager *table, int lower, int upper); +static void ddClearGlobal (DdManager *table, int lower, int maxlevel); +static int computeLB (DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level); +static int updateEntry (DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper); +static void pushDown (DdHalfWord *order, int j, int level); +static DdHalfWord * initSymmInfo (DdManager *table, int lower, int upper); +static int checkSymmInfo (DdManager *table, DdHalfWord *symmInfo, int index, int level); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Exact variable ordering algorithm.] + + Description [Exact variable ordering algorithm. Finds an optimum + order for the variables between lower and upper. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddExact( + DdManager * table, + int lower, + int upper) +{ + int k, i, j; + int maxBinomial, oldSubsets, newSubsets; + int subsetCost; + int size; /* number of variables to be reordered */ + int unused, nvars, level, result; + int upperBound, lowerBound, cost; + int roots; + char *mask = NULL; + DdHalfWord *symmInfo = NULL; + DdHalfWord **newOrder = NULL; + DdHalfWord **oldOrder = NULL; + int *newCost = NULL; + int *oldCost = NULL; + DdHalfWord **tmpOrder; + int *tmpCost; + DdHalfWord *bestOrder = NULL; + DdHalfWord *order; +#ifdef DD_STATS + int ddTotalSubsets; +#endif + + /* Restrict the range to be reordered by excluding unused variables + ** at the two ends. */ + while (table->subtables[lower].keys == 1 && + table->vars[table->invperm[lower]]->ref == 1 && + lower < upper) + lower++; + while (table->subtables[upper].keys == 1 && + table->vars[table->invperm[upper]]->ref == 1 && + lower < upper) + upper--; + if (lower == upper) return(1); /* trivial problem */ + + /* Apply symmetric sifting to get a good upper bound and to extract + ** symmetry information. */ + result = cuddSymmSiftingConv(table,lower,upper); + if (result == 0) goto cuddExactOutOfMem; + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + ddTotalShuffles = 0; + ddTotalSubsets = 0; +#endif + + /* Initialization. */ + nvars = table->size; + size = upper - lower + 1; + /* Count unused variable among those to be reordered. This is only + ** used to compute maxBinomial. */ + unused = 0; + for (i = lower + 1; i < upper; i++) { + if (table->subtables[i].keys == 1 && + table->vars[table->invperm[i]]->ref == 1) + unused++; + } + + /* Find the maximum number of subsets we may have to store. */ + maxBinomial = getMaxBinomial(size - unused); + if (maxBinomial == -1) goto cuddExactOutOfMem; + + newOrder = getMatrix(maxBinomial, size); + if (newOrder == NULL) goto cuddExactOutOfMem; + + newCost = ALLOC(int, maxBinomial); + if (newCost == NULL) goto cuddExactOutOfMem; + + oldOrder = getMatrix(maxBinomial, size); + if (oldOrder == NULL) goto cuddExactOutOfMem; + + oldCost = ALLOC(int, maxBinomial); + if (oldCost == NULL) goto cuddExactOutOfMem; + + bestOrder = ALLOC(DdHalfWord, size); + if (bestOrder == NULL) goto cuddExactOutOfMem; + + mask = ALLOC(char, nvars); + if (mask == NULL) goto cuddExactOutOfMem; + + symmInfo = initSymmInfo(table, lower, upper); + if (symmInfo == NULL) goto cuddExactOutOfMem; + + roots = ddCountRoots(table, lower, upper); + + /* Initialize the old order matrix for the empty subset and the best + ** order to the current order. The cost for the empty subset includes + ** the cost of the levels between upper and the constants. These levels + ** are not going to change. Hence, we count them only once. + */ + oldSubsets = 1; + for (i = 0; i < size; i++) { + oldOrder[0][i] = bestOrder[i] = (DdHalfWord) table->invperm[i+lower]; + } + subsetCost = table->constants.keys; + for (i = upper + 1; i < nvars; i++) + subsetCost += getLevelKeys(table,i); + oldCost[0] = subsetCost; + /* The upper bound is initialized to the current size of the BDDs. */ + upperBound = table->keys - table->isolated; + + /* Now consider subsets of increasing size. */ + for (k = 1; k <= size; k++) { +#ifdef DD_STATS + (void) fprintf(table->out,"Processing subsets of size %d\n", k); + fflush(table->out); +#endif + newSubsets = 0; + level = size - k; /* offset of first bottom variable */ + + for (i = 0; i < oldSubsets; i++) { /* for each subset of size k-1 */ + order = oldOrder[i]; + cost = oldCost[i]; + lowerBound = computeLB(table, order, roots, cost, lower, upper, + level); + if (lowerBound >= upperBound) + continue; + /* Impose new order. */ + result = ddShuffle(table, order, lower, upper); + if (result == 0) goto cuddExactOutOfMem; + upperBound = updateUB(table,upperBound,bestOrder,lower,upper); + /* For each top bottom variable. */ + for (j = level; j >= 0; j--) { + /* Skip unused variables. */ + if (table->subtables[j+lower-1].keys == 1 && + table->vars[table->invperm[j+lower-1]]->ref == 1) continue; + /* Find cost under this order. */ + subsetCost = cost + getLevelKeys(table, lower + level); + newSubsets = updateEntry(table, order, level, subsetCost, + newOrder, newCost, newSubsets, mask, + lower, upper); + if (j == 0) + break; + if (checkSymmInfo(table, symmInfo, order[j-1], level) == 0) + continue; + pushDown(order,j-1,level); + /* Impose new order. */ + result = ddShuffle(table, order, lower, upper); + if (result == 0) goto cuddExactOutOfMem; + upperBound = updateUB(table,upperBound,bestOrder,lower,upper); + } /* for each bottom variable */ + } /* for each subset of size k */ + + /* New orders become old orders in preparation for next iteration. */ + tmpOrder = oldOrder; tmpCost = oldCost; + oldOrder = newOrder; oldCost = newCost; + newOrder = tmpOrder; newCost = tmpCost; +#ifdef DD_STATS + ddTotalSubsets += newSubsets; +#endif + oldSubsets = newSubsets; + } + result = ddShuffle(table, bestOrder, lower, upper); + if (result == 0) goto cuddExactOutOfMem; +#ifdef DD_STATS +#ifdef DD_VERBOSE + (void) fprintf(table->out,"\n"); +#endif + (void) fprintf(table->out,"#:S_EXACT %8d: total subsets\n", + ddTotalSubsets); + (void) fprintf(table->out,"#:H_EXACT %8d: total shuffles", + ddTotalShuffles); +#endif + + freeMatrix(newOrder); + freeMatrix(oldOrder); + FREE(bestOrder); + FREE(oldCost); + FREE(newCost); + FREE(symmInfo); + FREE(mask); + return(1); + +cuddExactOutOfMem: + + if (newOrder != NULL) freeMatrix(newOrder); + if (oldOrder != NULL) freeMatrix(oldOrder); + if (bestOrder != NULL) FREE(bestOrder); + if (oldCost != NULL) FREE(oldCost); + if (newCost != NULL) FREE(newCost); + if (symmInfo != NULL) FREE(symmInfo); + if (mask != NULL) FREE(mask); + table->errorCode = CUDD_MEMORY_OUT; + return(0); + +} /* end of cuddExact */ + + +/**Function******************************************************************** + + Synopsis [Returns the maximum value of (n choose k) for a given n.] + + Description [Computes the maximum value of (n choose k) for a given + n. The maximum value occurs for k = n/2 when n is even, or k = + (n-1)/2 when n is odd. The algorithm used in this procedure avoids + intermediate overflow problems. It is based on the identity +
+    binomial(n,k) = n/k * binomial(n-1,k-1).
+  
+ Returns the computed value if successful; -1 if out of range.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +getMaxBinomial( + int n) +{ + double i, j, result; + + if (n < 0 || n > 33) return(-1); /* error */ + if (n < 2) return(1); + + for (result = (double)((n+3)/2), i = result+1, j=2; i <= n; i++, j++) { + result *= i; + result /= j; + } + + return((int)result); + +} /* end of getMaxBinomial */ + + +#if 0 +/**Function******************************************************************** + + Synopsis [Returns the gcd of two integers.] + + Description [Returns the gcd of two integers. Uses the binary GCD + algorithm described in Cormen, Leiserson, and Rivest.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +gcd( + int x, + int y) +{ + int a; + int b; + int lsbMask; + + /* GCD(n,0) = n. */ + if (x == 0) return(y); + if (y == 0) return(x); + + a = x; b = y; lsbMask = 1; + + /* Here both a and b are != 0. The iteration maintains this invariant. + ** Hence, we only need to check for when they become equal. + */ + while (a != b) { + if (a & lsbMask) { + if (b & lsbMask) { /* both odd */ + if (a < b) { + b = (b - a) >> 1; + } else { + a = (a - b) >> 1; + } + } else { /* a odd, b even */ + b >>= 1; + } + } else { + if (b & lsbMask) { /* a even, b odd */ + a >>= 1; + } else { /* both even */ + lsbMask <<= 1; + } + } + } + + return(a); + +} /* end of gcd */ +#endif + + +/**Function******************************************************************** + + Synopsis [Allocates a two-dimensional matrix of ints.] + + Description [Allocates a two-dimensional matrix of ints. + Returns the pointer to the matrix if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [freeMatrix] + +******************************************************************************/ +static DdHalfWord ** +getMatrix( + int rows /* number of rows */, + int cols /* number of columns */) +{ + DdHalfWord **matrix; + int i; + + if (cols*rows == 0) return(NULL); + matrix = ALLOC(DdHalfWord *, rows); + if (matrix == NULL) return(NULL); + matrix[0] = ALLOC(DdHalfWord, cols*rows); + if (matrix[0] == NULL) { + FREE(matrix); + return(NULL); + } + for (i = 1; i < rows; i++) { + matrix[i] = matrix[i-1] + cols; + } + return(matrix); + +} /* end of getMatrix */ + + +/**Function******************************************************************** + + Synopsis [Frees a two-dimensional matrix allocated by getMatrix.] + + Description [] + + SideEffects [None] + + SeeAlso [getMatrix] + +******************************************************************************/ +static void +freeMatrix( + DdHalfWord ** matrix) +{ + FREE(matrix[0]); + FREE(matrix); + return; + +} /* end of freeMatrix */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of nodes at one level of a unique table.] + + Description [Returns the number of nodes at one level of a unique table. + The projection function, if isolated, is not counted.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +getLevelKeys( + DdManager * table, + int l) +{ + int isolated; + int x; /* x is an index */ + + x = table->invperm[l]; + isolated = table->vars[x]->ref == 1; + + return(table->subtables[l].keys - isolated); + +} /* end of getLevelKeys */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables according to a given permutation.] + + Description [Reorders variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. ddShuffle assumes that no + dead nodes are present and that the interaction matrix is properly + initialized. The reordering is achieved by a series of upward sifts. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddShuffle( + DdManager * table, + DdHalfWord * permutation, + int lower, + int upper) +{ + DdHalfWord index; + int level; + int position; +#if 0 + int numvars; +#endif + int result; +#ifdef DD_STATS + unsigned long localTime; + int initialSize; +#ifdef DD_VERBOSE + int finalSize; +#endif + int previousSize; +#endif + +#ifdef DD_STATS + localTime = util_cpu_time(); + initialSize = table->keys - table->isolated; +#endif + +#if 0 + numvars = table->size; + + (void) fprintf(table->out,"%d:", ddTotalShuffles); + for (level = 0; level < numvars; level++) { + (void) fprintf(table->out," %d", table->invperm[level]); + } + (void) fprintf(table->out,"\n"); +#endif + + for (level = 0; level <= upper - lower; level++) { + index = permutation[level]; + position = table->perm[index]; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSiftUp(table,position,level+lower); + if (!result) return(0); + } + +#ifdef DD_STATS + ddTotalShuffles++; +#ifdef DD_VERBOSE + finalSize = table->keys - table->isolated; + if (finalSize < initialSize) { + (void) fprintf(table->out,"-"); + } else if (finalSize > initialSize) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + if ((ddTotalShuffles & 63) == 0) (void) fprintf(table->out,"\n"); + fflush(table->out); +#endif +#endif + + return(1); + +} /* end of ddShuffle */ + + +/**Function******************************************************************** + + Synopsis [Moves one variable up.] + + Description [Takes a variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddSiftUp( + DdManager * table, + int x, + int xLow) +{ + int y; + int size; + + y = cuddNextLow(table,x); + while (y >= xLow) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); + } + return(1); + +} /* end of ddSiftUp */ + + +/**Function******************************************************************** + + Synopsis [Updates the upper bound and saves the best order seen so far.] + + Description [Updates the upper bound and saves the best order seen so far. + Returns the current value of the upper bound.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +updateUB( + DdManager * table, + int oldBound, + DdHalfWord * bestOrder, + int lower, + int upper) +{ + int i; + int newBound = table->keys - table->isolated; + + if (newBound < oldBound) { +#ifdef DD_STATS + (void) fprintf(table->out,"New upper bound = %d\n", newBound); + fflush(table->out); +#endif + for (i = lower; i <= upper; i++) + bestOrder[i-lower] = (DdHalfWord) table->invperm[i]; + return(newBound); + } else { + return(oldBound); + } + +} /* end of updateUB */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of roots.] + + Description [Counts the number of roots at the levels between lower and + upper. The computation is based on breadth-first search. + A node is a root if it is not reachable from any previously visited node. + (All the nodes at level lower are therefore considered roots.) + The visited flag uses the LSB of the next pointer. Returns the root + count. The roots that are constant nodes are always ignored.] + + SideEffects [None] + + SeeAlso [ddClearGlobal] + +******************************************************************************/ +static int +ddCountRoots( + DdManager * table, + int lower, + int upper) +{ + int i,j; + DdNode *f; + DdNodePtr *nodelist; + DdNode *sentinel = &(table->sentinel); + int slots; + int roots = 0; + int maxlevel = lower; + + for (i = lower; i <= upper; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + /* A node is a root of the DAG if it cannot be + ** reached by nodes above it. If a node was never + ** reached during the previous depth-first searches, + ** then it is a root, and we start a new depth-first + ** search from it. + */ + if (!Cudd_IsComplement(f->next)) { + if (f != table->vars[f->index]) { + roots++; + } + } + if (!Cudd_IsConstant(cuddT(f))) { + cuddT(f)->next = Cudd_Complement(cuddT(f)->next); + if (table->perm[cuddT(f)->index] > maxlevel) + maxlevel = table->perm[cuddT(f)->index]; + } + if (!Cudd_IsConstant(cuddE(f))) { + Cudd_Regular(cuddE(f))->next = + Cudd_Complement(Cudd_Regular(cuddE(f))->next); + if (table->perm[Cudd_Regular(cuddE(f))->index] > maxlevel) + maxlevel = table->perm[Cudd_Regular(cuddE(f))->index]; + } + f = Cudd_Regular(f->next); + } + } + } + ddClearGlobal(table, lower, maxlevel); + + return(roots); + +} /* end of ddCountRoots */ + + +/**Function******************************************************************** + + Synopsis [Scans the DD and clears the LSB of the next pointers.] + + Description [Scans the DD and clears the LSB of the next pointers. + The LSB of the next pointers are used as markers to tell whether a + node was reached. Once the roots are counted, these flags are + reset.] + + SideEffects [None] + + SeeAlso [ddCountRoots] + +******************************************************************************/ +static void +ddClearGlobal( + DdManager * table, + int lower, + int maxlevel) +{ + int i,j; + DdNode *f; + DdNodePtr *nodelist; + DdNode *sentinel = &(table->sentinel); + int slots; + + for (i = lower; i <= maxlevel; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + f->next = Cudd_Regular(f->next); + f = f->next; + } + } + } + +} /* end of ddClearGlobal */ + + +/**Function******************************************************************** + + Synopsis [Computes a lower bound on the size of a BDD.] + + Description [Computes a lower bound on the size of a BDD from the + following factors: +
    +
  • size of the lower part of it; +
  • size of the part of the upper part not subjected to reordering; +
  • number of roots in the part of the BDD subjected to reordering; +
  • variable in the support of the roots in the upper part of the + BDD subjected to reordering. +
      ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +computeLB( + DdManager * table /* manager */, + DdHalfWord * order /* optimal order for the subset */, + int roots /* roots between lower and upper */, + int cost /* minimum cost for the subset */, + int lower /* lower level to be reordered */, + int upper /* upper level to be reordered */, + int level /* offset for the current top bottom var */ + ) +{ + int i; + int lb = cost; + int lb1 = 0; + int lb2; + int support; + DdHalfWord ref; + + /* The levels not involved in reordering are not going to change. + ** Add their sizes to the lower bound. + */ + for (i = 0; i < lower; i++) { + lb += getLevelKeys(table,i); + } + /* If a variable is in the support, then there is going + ** to be at least one node labeled by that variable. + */ + for (i = lower; i <= lower+level; i++) { + support = table->subtables[i].keys > 1 || + table->vars[order[i-lower]]->ref > 1; + lb1 += support; + } + + /* Estimate the number of nodes required to connect the roots to + ** the nodes in the bottom part. */ + if (lower+level+1 < table->size) { + if (lower+level < upper) + ref = table->vars[order[level+1]]->ref; + else + ref = table->vars[table->invperm[upper+1]]->ref; + lb2 = table->subtables[lower+level+1].keys - + (ref > (DdHalfWord) 1) - roots; + } else { + lb2 = 0; + } + + lb += lb1 > lb2 ? lb1 : lb2; + + return(lb); + +} /* end of computeLB */ + + +/**Function******************************************************************** + + Synopsis [Updates entry for a subset.] + + Description [Updates entry for a subset. Finds the subset, if it exists. + If the new order for the subset has lower cost, or if the subset did not + exist, it stores the new order and cost. Returns the number of subsets + currently in the table.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +updateEntry( + DdManager * table, + DdHalfWord * order, + int level, + int cost, + DdHalfWord ** orders, + int * costs, + int subsets, + char * mask, + int lower, + int upper) +{ + int i, j; + int size = upper - lower + 1; + + /* Build a mask that says what variables are in this subset. */ + for (i = lower; i <= upper; i++) + mask[table->invperm[i]] = 0; + for (i = level; i < size; i++) + mask[order[i]] = 1; + + /* Check each subset until a match is found or all subsets are examined. */ + for (i = 0; i < subsets; i++) { + DdHalfWord *subset = orders[i]; + for (j = level; j < size; j++) { + if (mask[subset[j]] == 0) + break; + } + if (j == size) /* no mismatches: success */ + break; + } + if (i == subsets || cost < costs[i]) { /* add or replace */ + for (j = 0; j < size; j++) + orders[i][j] = order[j]; + costs[i] = cost; + subsets += (i == subsets); + } + return(subsets); + +} /* end of updateEntry */ + + +/**Function******************************************************************** + + Synopsis [Pushes a variable in the order down to position "level."] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +pushDown( + DdHalfWord * order, + int j, + int level) +{ + int i; + DdHalfWord tmp; + + tmp = order[j]; + for (i = j; i < level; i++) { + order[i] = order[i+1]; + } + order[level] = tmp; + return; + +} /* end of pushDown */ + + +/**Function******************************************************************** + + Synopsis [Gathers symmetry information.] + + Description [Translates the symmetry information stored in the next + field of each subtable from level to indices. This procedure is called + immediately after symmetric sifting, so that the next fields are correct. + By translating this informaton in terms of indices, we make it independent + of subsequent reorderings. The format used is that of the next fields: + a circular list where each variable points to the next variable in the + same symmetry group. Only the entries between lower and upper are + considered. The procedure returns a pointer to an array + holding the symmetry information if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [checkSymmInfo] + +******************************************************************************/ +static DdHalfWord * +initSymmInfo( + DdManager * table, + int lower, + int upper) +{ + int level, index, next, nextindex; + DdHalfWord *symmInfo; + + symmInfo = ALLOC(DdHalfWord, table->size); + if (symmInfo == NULL) return(NULL); + + for (level = lower; level <= upper; level++) { + index = table->invperm[level]; + next = table->subtables[level].next; + nextindex = table->invperm[next]; + symmInfo[index] = nextindex; + } + return(symmInfo); + +} /* end of initSymmInfo */ + + +/**Function******************************************************************** + + Synopsis [Check symmetry condition.] + + Description [Returns 1 if a variable is the one with the highest index + among those belonging to a symmetry group that are in the top part of + the BDD. The top part is given by level.] + + SideEffects [None] + + SeeAlso [initSymmInfo] + +******************************************************************************/ +static int +checkSymmInfo( + DdManager * table, + DdHalfWord * symmInfo, + int index, + int level) +{ + int i; + + i = symmInfo[index]; + while (i != index) { + if (index < i && table->perm[i] <= level) + return(0); + i = symmInfo[i]; + } + return(1); + +} /* end of checkSymmInfo */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddExport.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddExport.c new file mode 100644 index 000000000..3d8da77ac --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddExport.c @@ -0,0 +1,1389 @@ +/**CFile*********************************************************************** + + FileName [cuddExport.c] + + PackageName [cudd] + + Synopsis [Export functions.] + + Description [External procedures included in this module: +
        +
      • Cudd_DumpBlif() +
      • Cudd_DumpBlifBody() +
      • Cudd_DumpDot() +
      • Cudd_DumpDaVinci() +
      • Cudd_DumpDDcal() +
      • Cudd_DumpFactoredForm() +
      + Internal procedures included in this module: +
        +
      + Static procedures included in this module: +
        +
      • ddDoDumpBlif() +
      • ddDoDumpDaVinci() +
      • ddDoDumpDDcal() +
      • ddDoDumpFactoredForm() +
      ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddExport.c,v 1.23 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddDoDumpBlif (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, int mv); +static int ddDoDumpDaVinci (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, ptruint mask); +static int ddDoDumpDDcal (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, ptruint mask); +static int ddDoDumpFactoredForm (DdManager *dd, DdNode *f, FILE *fp, char **names); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Writes a blif file representing the argument BDDs.] + + Description [Writes a blif file representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). Cudd_DumpBlif does not close the file: This is the + caller responsibility. Cudd_DumpBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for onames.] + + SideEffects [None] + + SeeAlso [Cudd_DumpBlifBody Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal + Cudd_DumpDaVinci Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpBlif( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + char * mname /* model name (or NULL) */, + FILE * fp /* pointer to the dump file */, + int mv /* 0: blif, 1: blif-MV */) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; + int retval; + int i; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int,nvars); + if (sorted == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; + } + for (i = 0; i < nvars; i++) sorted[i] = 0; + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(dd,f,n); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + support = NULL; /* so that we do not try to free it in case of failure */ + + /* Write the header (.model .inputs .outputs). */ + if (mname == NULL) { + retval = fprintf(fp,".model DD\n.inputs"); + } else { + retval = fprintf(fp,".model %s\n.inputs",mname); + } + if (retval == EOF) { + FREE(sorted); + return(0); + } + + /* Write the input list by scanning the support array. */ + for (i = 0; i < nvars; i++) { + if (sorted[i]) { + if (inames == NULL) { + retval = fprintf(fp," %d", i); + } else { + retval = fprintf(fp," %s", inames[i]); + } + if (retval == EOF) goto failure; + } + } + FREE(sorted); + sorted = NULL; + + /* Write the .output line. */ + retval = fprintf(fp,"\n.outputs"); + if (retval == EOF) goto failure; + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp," f%d", i); + } else { + retval = fprintf(fp," %s", onames[i]); + } + if (retval == EOF) goto failure; + } + retval = fprintf(fp,"\n"); + if (retval == EOF) goto failure; + + retval = Cudd_DumpBlifBody(dd, n, f, inames, onames, fp, mv); + if (retval == 0) goto failure; + + /* Write trailer and return. */ + retval = fprintf(fp,".end\n"); + if (retval == EOF) goto failure; + + return(1); + +failure: + if (sorted != NULL) FREE(sorted); + if (support != NULL) Cudd_RecursiveDeref(dd,support); + return(0); + +} /* end of Cudd_DumpBlif */ + + +/**Function******************************************************************** + + Synopsis [Writes a blif body representing the argument BDDs.] + + Description [Writes a blif body representing the argument BDDs as a + network of multiplexers. No header (.model, .inputs, and .outputs) and + footer (.end) are produced by this function. One multiplexer is written + for each BDD node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). Cudd_DumpBlifBody does not close the file: This is the + caller responsibility. Cudd_DumpBlifBody uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for onames. This function prints out only + .names part.] + + SideEffects [None] + + SeeAlso [Cudd_DumpBlif Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal + Cudd_DumpDaVinci Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpBlifBody( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */, + int mv /* 0: blif, 1: blif-MV */) +{ + st_table *visited = NULL; + int retval; + int i; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + retval = ddDoDumpBlif(dd,Cudd_Regular(f[i]),fp,visited,inames,mv); + if (retval == 0) goto failure; + } + + /* To account for the possible complement on the root, + ** we put either a buffer or an inverter at the output of + ** the multiplexer representing the top node. + */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp, +#if SIZEOF_VOID_P == 8 + ".names %lx f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); +#else + ".names %x f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); +#endif + } else { + retval = fprintf(fp, +#if SIZEOF_VOID_P == 8 + ".names %lx %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]); +#else + ".names %x %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]); +#endif + } + if (retval == EOF) goto failure; + if (Cudd_IsComplement(f[i])) { + retval = fprintf(fp,"%s0 1\n", mv ? ".def 0\n" : ""); + } else { + retval = fprintf(fp,"%s1 1\n", mv ? ".def 0\n" : ""); + } + if (retval == EOF) goto failure; + } + + st_free_table(visited); + return(1); + +failure: + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_DumpBlifBody */ + + +/**Function******************************************************************** + + Synopsis [Writes a dot file representing the argument DDs.] + + Description [Writes a file representing the argument DDs in a format + suitable for the graph drawing program dot. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, + file system full). + Cudd_DumpDot does not close the file: This is the caller + responsibility. Cudd_DumpDot uses a minimal unique subset of the + hexadecimal address of a node as name for it. + If the argument inames is non-null, it is assumed to hold the pointers + to the names of the inputs. Similarly for onames. + Cudd_DumpDot uses the following convention to draw arcs: +
        +
      • solid line: THEN arcs; +
      • dotted line: complement arcs; +
      • dashed line: regular ELSE arcs. +
      + The dot options are chosen so that the drawing fits on a letter-size + sheet. + ] + + SideEffects [None] + + SeeAlso [Cudd_DumpBlif Cudd_PrintDebug Cudd_DumpDDcal + Cudd_DumpDaVinci Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpDot( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; + st_table *visited = NULL; + st_generator *gen = NULL; + int retval; + int i, j; + int slots; + DdNodePtr *nodelist; + long refAddr, diff, mask; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int,nvars); + if (sorted == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; + } + for (i = 0; i < nvars; i++) sorted[i] = 0; + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(dd,f,n); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + support = NULL; /* so that we do not try to free it in case of failure */ + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Collect all the nodes of this DD in the symbol table. */ + for (i = 0; i < n; i++) { + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; + } + + /* Find how many most significant hex digits are identical + ** in the addresses of all the nodes. Build a mask based + ** on this knowledge, so that digits that carry no information + ** will not be printed. This is done in two steps. + ** 1. We scan the symbol table to find the bits that differ + ** in at least 2 addresses. + ** 2. We choose one of the possible masks. There are 8 possible + ** masks for 32-bit integer, and 16 possible masks for 64-bit + ** integers. + */ + + /* Find the bits that are different. */ + refAddr = (long) Cudd_Regular(f[0]); + diff = 0; + gen = st_init_gen(visited); + if (gen == NULL) goto failure; + while (st_gen(gen, &scan, NULL)) { + diff |= refAddr ^ (long) scan; + } + st_free_gen(gen); gen = NULL; + + /* Choose the mask. */ + for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; + } + + /* Write the header and the global attributes. */ + retval = fprintf(fp,"digraph \"DD\" {\n"); + if (retval == EOF) return(0); + retval = fprintf(fp, + "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); + if (retval == EOF) return(0); + + /* Write the input name subgraph by scanning the support array. */ + retval = fprintf(fp,"{ node [shape = plaintext];\n"); + if (retval == EOF) goto failure; + retval = fprintf(fp," edge [style = invis];\n"); + if (retval == EOF) goto failure; + /* We use a name ("CONST NODES") with an embedded blank, because + ** it is unlikely to appear as an input name. + */ + retval = fprintf(fp," \"CONST NODES\" [style = invis];\n"); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if (sorted[dd->invperm[i]]) { + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"\" %d \" -> ", dd->invperm[i]); + } else { + retval = fprintf(fp,"\" %s \" -> ", inames[dd->invperm[i]]); + } + if (retval == EOF) goto failure; + } + } + retval = fprintf(fp,"\"CONST NODES\"; \n}\n"); + if (retval == EOF) goto failure; + + /* Write the output node subgraph. */ + retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); + if (retval == EOF) goto failure; + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + if (i == n - 1) { + retval = fprintf(fp,"; }\n"); + } else { + retval = fprintf(fp," -> "); + } + if (retval == EOF) goto failure; + } + + /* Write rank info: All nodes with the same index have the same rank. */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invperm[i]]) { + retval = fprintf(fp,"{ rank = same; "); + if (retval == EOF) goto failure; + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"\" %d \";\n", dd->invperm[i]); + } else { + retval = fprintf(fp,"\" %s \";\n", inames[dd->invperm[i]]); + } + if (retval == EOF) goto failure; + nodelist = dd->subtables[i].nodelist; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; + } + } + + /* All constants have the same rank. */ + retval = fprintf(fp, + "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); + if (retval == EOF) goto failure; + nodelist = dd->constants.nodelist; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", + (void *) ((mask & (ptrint) scan) / sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + retval = fprintf(fp,"}\n}\n"); + if (retval == EOF) goto failure; + + /* Write edge info. */ + /* Edges from the output nodes. */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + /* Account for the possible complement on the root. */ + if (Cudd_IsComplement(f[i])) { + retval = fprintf(fp," -> \"%p\" [style = dotted];\n", + (void *) ((mask & (ptrint) f[i]) / sizeof(DdNode))); + } else { + retval = fprintf(fp," -> \"%p\" [style = solid];\n", + (void *) ((mask & (ptrint) f[i]) / sizeof(DdNode))); + } + if (retval == EOF) goto failure; + } + + /* Edges from internal nodes. */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invperm[i]]) { + nodelist = dd->subtables[i].nodelist; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp, + "\"%p\" -> \"%p\";\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddT(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + if (Cudd_IsComplement(cuddE(scan))) { + retval = fprintf(fp, + "\"%p\" -> \"%p\" [style = dotted];\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddE(scan)) / + sizeof(DdNode))); + } else { + retval = fprintf(fp, + "\"%p\" -> \"%p\" [style = dashed];\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddE(scan)) / + sizeof(DdNode))); + } + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + } + } + + /* Write constant labels. */ + nodelist = dd->constants.nodelist; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n", + (void *) ((mask & (ptrint) scan) / sizeof(DdNode)), + cuddV(scan)); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + + /* Write trailer and return. */ + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; + + st_free_table(visited); + FREE(sorted); + return(1); + +failure: + if (sorted != NULL) FREE(sorted); + if (support != NULL) Cudd_RecursiveDeref(dd,support); + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_DumpDot */ + + +/**Function******************************************************************** + + Synopsis [Writes a daVinci file representing the argument BDDs.] + + Description [Writes a daVinci file representing the argument BDDs. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or + file system full). Cudd_DumpDaVinci does not close the file: This + is the caller responsibility. Cudd_DumpDaVinci uses a minimal unique + subset of the hexadecimal address of a node as name for it. If the + argument inames is non-null, it is assumed to hold the pointers to + the names of the inputs. Similarly for onames.] + + SideEffects [None] + + SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDDcal + Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpDaVinci( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + DdNode *support = NULL; + DdNode *scan; + st_table *visited = NULL; + int retval; + int i; + st_generator *gen; + ptruint refAddr, diff, mask; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Collect all the nodes of this DD in the symbol table. */ + for (i = 0; i < n; i++) { + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; + } + + /* Find how many most significant hex digits are identical + ** in the addresses of all the nodes. Build a mask based + ** on this knowledge, so that digits that carry no information + ** will not be printed. This is done in two steps. + ** 1. We scan the symbol table to find the bits that differ + ** in at least 2 addresses. + ** 2. We choose one of the possible masks. There are 8 possible + ** masks for 32-bit integer, and 16 possible masks for 64-bit + ** integers. + */ + + /* Find the bits that are different. */ + refAddr = (ptruint) Cudd_Regular(f[0]); + diff = 0; + gen = st_init_gen(visited); + while (st_gen(gen, &scan, NULL)) { + diff |= refAddr ^ (ptruint) scan; + } + st_free_gen(gen); + + /* Choose the mask. */ + for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; + } + st_free_table(visited); + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + retval = fprintf(fp, "["); + if (retval == EOF) goto failure; + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp, + "l(\"f%d\",n(\"root\",[a(\"OBJECT\",\"f%d\")],", + i,i); + } else { + retval = fprintf(fp, + "l(\"%s\",n(\"root\",[a(\"OBJECT\",\"%s\")],", + onames[i], onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp, "[e(\"edge\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],", + Cudd_IsComplement(f[i]) ? "red" : "blue"); + if (retval == EOF) goto failure; + retval = ddDoDumpDaVinci(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); + if (retval == 0) goto failure; + retval = fprintf(fp, ")]))%s", i == n-1 ? "" : ","); + if (retval == EOF) goto failure; + } + + /* Write trailer and return. */ + retval = fprintf(fp, "]\n"); + if (retval == EOF) goto failure; + + st_free_table(visited); + return(1); + +failure: + if (support != NULL) Cudd_RecursiveDeref(dd,support); + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_DumpDaVinci */ + + +/**Function******************************************************************** + + Synopsis [Writes a DDcal file representing the argument BDDs.] + + Description [Writes a DDcal file representing the argument BDDs. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or + file system full). Cudd_DumpDDcal does not close the file: This + is the caller responsibility. Cudd_DumpDDcal uses a minimal unique + subset of the hexadecimal address of a node as name for it. If the + argument inames is non-null, it is assumed to hold the pointers to + the names of the inputs. Similarly for onames.] + + SideEffects [None] + + SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci + Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpDDcal( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; + st_table *visited = NULL; + int retval; + int i; + st_generator *gen; + ptruint refAddr, diff, mask; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Collect all the nodes of this DD in the symbol table. */ + for (i = 0; i < n; i++) { + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; + } + + /* Find how many most significant hex digits are identical + ** in the addresses of all the nodes. Build a mask based + ** on this knowledge, so that digits that carry no information + ** will not be printed. This is done in two steps. + ** 1. We scan the symbol table to find the bits that differ + ** in at least 2 addresses. + ** 2. We choose one of the possible masks. There are 8 possible + ** masks for 32-bit integer, and 16 possible masks for 64-bit + ** integers. + */ + + /* Find the bits that are different. */ + refAddr = (ptruint) Cudd_Regular(f[0]); + diff = 0; + gen = st_init_gen(visited); + while (st_gen(gen, &scan, NULL)) { + diff |= refAddr ^ (ptruint) scan; + } + st_free_gen(gen); + + /* Choose the mask. */ + for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; + } + st_free_table(visited); + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int,nvars); + if (sorted == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; + } + for (i = 0; i < nvars; i++) sorted[i] = 0; + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(dd,f,n); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + support = NULL; /* so that we do not try to free it in case of failure */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invperm[i]]) { + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"v%d", dd->invperm[i]); + } else { + retval = fprintf(fp,"%s", inames[dd->invperm[i]]); + } + if (retval == EOF) goto failure; + } + retval = fprintf(fp,"%s", i == nvars - 1 ? "\n" : " * "); + if (retval == EOF) goto failure; + } + FREE(sorted); + sorted = NULL; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + retval = ddDoDumpDDcal(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); + if (retval == 0) goto failure; + if (onames == NULL) { + retval = fprintf(fp, "f%d = ", i); + } else { + retval = fprintf(fp, "%s = ", onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp, "n%p%s\n", + (void *) (((ptruint) f[i] & mask) / + (ptruint) sizeof(DdNode)), + Cudd_IsComplement(f[i]) ? "'" : ""); + if (retval == EOF) goto failure; + } + + /* Write trailer and return. */ + retval = fprintf(fp, "["); + if (retval == EOF) goto failure; + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp, "f%d", i); + } else { + retval = fprintf(fp, "%s", onames[i]); + } + retval = fprintf(fp, "%s", i == n-1 ? "" : " "); + if (retval == EOF) goto failure; + } + retval = fprintf(fp, "]\n"); + if (retval == EOF) goto failure; + + st_free_table(visited); + return(1); + +failure: + if (sorted != NULL) FREE(sorted); + if (support != NULL) Cudd_RecursiveDeref(dd,support); + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_DumpDDcal */ + + +/**Function******************************************************************** + + Synopsis [Writes factored forms representing the argument BDDs.] + + Description [Writes factored forms representing the argument BDDs. + The format of the factored form is the one used in the genlib files + for technology mapping in sis. It returns 1 in case of success; 0 + otherwise (e.g., file system full). Cudd_DumpFactoredForm does not + close the file: This is the caller responsibility. Caution must be + exercised because a factored form may be exponentially larger than + the argument BDD. If the argument inames is non-null, it is assumed + to hold the pointers to the names of the inputs. Similarly for + onames.] + + SideEffects [None] + + SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci + Cudd_DumpDDcal] + +******************************************************************************/ +int +Cudd_DumpFactoredForm( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + int retval; + int i; + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp, "f%d = ", i); + } else { + retval = fprintf(fp, "%s = ", onames[i]); + } + if (retval == EOF) return(0); + if (f[i] == DD_ONE(dd)) { + retval = fprintf(fp, "CONST1"); + if (retval == EOF) return(0); + } else if (f[i] == Cudd_Not(DD_ONE(dd)) || f[i] == DD_ZERO(dd)) { + retval = fprintf(fp, "CONST0"); + if (retval == EOF) return(0); + } else { + retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? "!(" : ""); + if (retval == EOF) return(0); + retval = ddDoDumpFactoredForm(dd,Cudd_Regular(f[i]),fp,inames); + if (retval == 0) return(0); + retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? ")" : ""); + if (retval == EOF) return(0); + } + retval = fprintf(fp, "%s", i == n-1 ? "" : "\n"); + if (retval == EOF) return(0); + } + + return(1); + +} /* end of Cudd_DumpFactoredForm */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DumpBlif.] + + Description [Performs the recursive step of Cudd_DumpBlif. Traverses + the BDD f and writes a multiplexer-network description to the file + pointed by fp in blif format. f is assumed to be a regular pointer + and ddDoDumpBlif guarantees this assumption in the recursive calls.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddDoDumpBlif( + DdManager * dd, + DdNode * f, + FILE * fp, + st_table * visited, + char ** names, + int mv) +{ + DdNode *T, *E; + int retval; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + /* If already visited, nothing to do. */ + if (st_is_member(visited, (char *) f) == 1) + return(1); + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Mark node as visited. */ + if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + + /* Check for special case: If constant node, generate constant 1. */ + if (f == DD_ONE(dd)) { +#if SIZEOF_VOID_P == 8 + retval = fprintf(fp, ".names %lx\n1\n",(ptruint) f / (ptruint) sizeof(DdNode)); +#else + retval = fprintf(fp, ".names %x\n1\n",(ptruint) f / (ptruint) sizeof(DdNode)); +#endif + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + + /* Check whether this is an ADD. We deal with 0-1 ADDs, but not + ** with the general case. + */ + if (f == DD_ZERO(dd)) { +#if SIZEOF_VOID_P == 8 + retval = fprintf(fp, ".names %lx\n%s", + (ptruint) f / (ptruint) sizeof(DdNode), + mv ? "0\n" : ""); +#else + retval = fprintf(fp, ".names %x\n%s", + (ptruint) f / (ptruint) sizeof(DdNode), + mv ? "0\n" : ""); +#endif + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + if (cuddIsConstant(f)) + return(0); + + /* Recursive calls. */ + T = cuddT(f); + retval = ddDoDumpBlif(dd,T,fp,visited,names,mv); + if (retval != 1) return(retval); + E = Cudd_Regular(cuddE(f)); + retval = ddDoDumpBlif(dd,E,fp,visited,names,mv); + if (retval != 1) return(retval); + + /* Write multiplexer taking complement arc into account. */ + if (names != NULL) { + retval = fprintf(fp,".names %s", names[f->index]); + } else { +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp,".names %u", f->index); +#else + retval = fprintf(fp,".names %hu", f->index); +#endif + } + if (retval == EOF) + return(0); + +#if SIZEOF_VOID_P == 8 + if (mv) { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %lx %lx %lx\n.def 0\n1 1 - 1\n0 - 0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %lx %lx %lx\n.def 0\n1 1 - 1\n0 - 1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } + } else { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } + } +#else + if (mv) { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %x %x %x\n.def 0\n1 1 - 1\n0 - 0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %x %x %x\n.def 0\n1 1 - 1\n0 - 1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } + } else { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %x %x %x\n11- 1\n0-0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %x %x %x\n11- 1\n0-1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } + } +#endif + if (retval == EOF) { + return(0); + } else { + return(1); + } + +} /* end of ddDoDumpBlif */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DumpDaVinci.] + + Description [Performs the recursive step of Cudd_DumpDaVinci. Traverses + the BDD f and writes a term expression to the file + pointed by fp in daVinci format. f is assumed to be a regular pointer + and ddDoDumpDaVinci guarantees this assumption in the recursive calls.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddDoDumpDaVinci( + DdManager * dd, + DdNode * f, + FILE * fp, + st_table * visited, + char ** names, + ptruint mask) +{ + DdNode *T, *E; + int retval; + ptruint id; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + id = ((ptruint) f & mask) / sizeof(DdNode); + + /* If already visited, insert a reference. */ + if (st_is_member(visited, (char *) f) == 1) { + retval = fprintf(fp,"r(\"%p\")", (void *) id); + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Mark node as visited. */ + if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + + /* Check for special case: If constant node, generate constant 1. */ + if (Cudd_IsConstant(f)) { + retval = fprintf(fp, + "l(\"%p\",n(\"constant\",[a(\"OBJECT\",\"%g\")],[]))", + (void *) id, cuddV(f)); + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + + /* Recursive calls. */ + if (names != NULL) { + retval = fprintf(fp, + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%s\"),", + (void *) id, names[f->index]); + } else { + retval = fprintf(fp, +#if SIZEOF_VOID_P == 8 + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%u\"),", +#else + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%hu\"),", +#endif + (void *) id, f->index); + } + retval = fprintf(fp, "a(\"_GO\",\"ellipse\")],[e(\"then\",[a(\"EDGECOLOR\",\"blue\"),a(\"_DIR\",\"none\")],"); + if (retval == EOF) return(0); + T = cuddT(f); + retval = ddDoDumpDaVinci(dd,T,fp,visited,names,mask); + if (retval != 1) return(retval); + retval = fprintf(fp, "),e(\"else\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],", + Cudd_IsComplement(cuddE(f)) ? "red" : "green"); + if (retval == EOF) return(0); + E = Cudd_Regular(cuddE(f)); + retval = ddDoDumpDaVinci(dd,E,fp,visited,names,mask); + if (retval != 1) return(retval); + + retval = fprintf(fp,")]))"); + if (retval == EOF) { + return(0); + } else { + return(1); + } + +} /* end of ddDoDumpDaVinci */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DumpDDcal.] + + Description [Performs the recursive step of Cudd_DumpDDcal. Traverses + the BDD f and writes a line for each node to the file + pointed by fp in DDcal format. f is assumed to be a regular pointer + and ddDoDumpDDcal guarantees this assumption in the recursive calls.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddDoDumpDDcal( + DdManager * dd, + DdNode * f, + FILE * fp, + st_table * visited, + char ** names, + ptruint mask) +{ + DdNode *T, *E; + int retval; + ptruint id, idT, idE; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + id = ((ptruint) f & mask) / sizeof(DdNode); + + /* If already visited, do nothing. */ + if (st_is_member(visited, (char *) f) == 1) { + return(1); + } + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Mark node as visited. */ + if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + + /* Check for special case: If constant node, assign constant. */ + if (Cudd_IsConstant(f)) { + if (f != DD_ONE(dd) && f != DD_ZERO(dd)) + return(0); + retval = fprintf(fp, "n%p = %g\n", (void *) id, cuddV(f)); + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + + /* Recursive calls. */ + T = cuddT(f); + retval = ddDoDumpDDcal(dd,T,fp,visited,names,mask); + if (retval != 1) return(retval); + E = Cudd_Regular(cuddE(f)); + retval = ddDoDumpDDcal(dd,E,fp,visited,names,mask); + if (retval != 1) return(retval); + idT = ((ptruint) T & mask) / sizeof(DdNode); + idE = ((ptruint) E & mask) / sizeof(DdNode); + if (names != NULL) { + retval = fprintf(fp, "n%p = %s * n%p + %s' * n%p%s\n", + (void *) id, names[f->index], + (void *) idT, names[f->index], + (void *) idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); + } else { +#if SIZEOF_VOID_P == 8 + retval = fprintf(fp, "n%p = v%u * n%p + v%u' * n%p%s\n", +#else + retval = fprintf(fp, "n%p = v%hu * n%p + v%hu' * n%p%s\n", +#endif + (void *) id, f->index, + (void *) idT, f->index, + (void *) idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); + } + if (retval == EOF) { + return(0); + } else { + return(1); + } + +} /* end of ddDoDumpDDcal */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DumpFactoredForm.] + + Description [Performs the recursive step of + Cudd_DumpFactoredForm. Traverses the BDD f and writes a factored + form for each node to the file pointed by fp in terms of the + factored forms of the children. Constants are propagated, and + absorption is applied. f is assumed to be a regular pointer and + ddDoDumpFActoredForm guarantees this assumption in the recursive + calls.] + + SideEffects [None] + + SeeAlso [Cudd_DumpFactoredForm] + +******************************************************************************/ +static int +ddDoDumpFactoredForm( + DdManager * dd, + DdNode * f, + FILE * fp, + char ** names) +{ + DdNode *T, *E; + int retval; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); + assert(!Cudd_IsConstant(f)); +#endif + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Recursive calls. */ + T = cuddT(f); + E = cuddE(f); + if (T != DD_ZERO(dd)) { + if (E != DD_ONE(dd)) { + if (names != NULL) { + retval = fprintf(fp, "%s", names[f->index]); + } else { +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp, "x%u", f->index); +#else + retval = fprintf(fp, "x%hu", f->index); +#endif + } + if (retval == EOF) return(0); + } + if (T != DD_ONE(dd)) { + retval = fprintf(fp, "%s(", E != DD_ONE(dd) ? " * " : ""); + if (retval == EOF) return(0); + retval = ddDoDumpFactoredForm(dd,T,fp,names); + if (retval != 1) return(retval); + retval = fprintf(fp, ")"); + if (retval == EOF) return(0); + } + if (E == Cudd_Not(DD_ONE(dd)) || E == DD_ZERO(dd)) return(1); + retval = fprintf(fp, " + "); + if (retval == EOF) return(0); + } + E = Cudd_Regular(E); + if (T != DD_ONE(dd)) { + if (names != NULL) { + retval = fprintf(fp, "!%s", names[f->index]); + } else { +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp, "!x%u", f->index); +#else + retval = fprintf(fp, "!x%hu", f->index); +#endif + } + if (retval == EOF) return(0); + } + if (E != DD_ONE(dd)) { + retval = fprintf(fp, "%s%s(", T != DD_ONE(dd) ? " * " : "", + E != cuddE(f) ? "!" : ""); + if (retval == EOF) return(0); + retval = ddDoDumpFactoredForm(dd,E,fp,names); + if (retval != 1) return(retval); + retval = fprintf(fp, ")"); + if (retval == EOF) return(0); + } + return(1); + +} /* end of ddDoDumpFactoredForm */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddGenCof.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddGenCof.c new file mode 100644 index 000000000..e129aca44 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddGenCof.c @@ -0,0 +1,2178 @@ +/**CFile*********************************************************************** + + FileName [cuddGenCof.c] + + PackageName [cudd] + + Synopsis [Generalized cofactors for BDDs and ADDs.] + + Description [External procedures included in this module: +
        +
      • Cudd_bddConstrain() +
      • Cudd_bddRestrict() +
      • Cudd_bddNPAnd() +
      • Cudd_addConstrain() +
      • Cudd_bddConstrainDecomp() +
      • Cudd_addRestrict() +
      • Cudd_bddCharToVect() +
      • Cudd_bddLICompaction() +
      • Cudd_bddSqueeze() +
      • Cudd_bddMinimize() +
      • Cudd_SubsetCompress() +
      • Cudd_SupersetCompress() +
      + Internal procedures included in this module: +
        +
      • cuddBddConstrainRecur() +
      • cuddBddRestrictRecur() +
      • cuddBddNPAndRecur() +
      • cuddAddConstrainRecur() +
      • cuddAddRestrictRecur() +
      • cuddBddLICompaction() +
      + Static procedures included in this module: +
        +
      • cuddBddConstrainDecomp() +
      • cuddBddCharToVect() +
      • cuddBddLICMarkEdges() +
      • cuddBddLICBuildResult() +
      • MarkCacheHash() +
      • MarkCacheCompare() +
      • MarkCacheCleanUp() +
      • cuddBddSqueeze() +
      + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Codes for edge markings in Cudd_bddLICompaction. The codes are defined +** so that they can be bitwise ORed to implement the code priority scheme. +*/ +#define DD_LIC_DC 0 +#define DD_LIC_1 1 +#define DD_LIC_0 2 +#define DD_LIC_NL 3 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/* Key for the cache used in the edge marking phase. */ +typedef struct MarkCacheKey { + DdNode *f; + DdNode *c; +} MarkCacheKey; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddGenCof.c,v 1.40 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddBddConstrainDecomp (DdManager *dd, DdNode *f, DdNode **decomp); +static DdNode * cuddBddCharToVect (DdManager *dd, DdNode *f, DdNode *x); +static int cuddBddLICMarkEdges (DdManager *dd, DdNode *f, DdNode *c, st_table *table, st_table *cache); +static DdNode * cuddBddLICBuildResult (DdManager *dd, DdNode *f, st_table *cache, st_table *table); +static int MarkCacheHash (char *ptr, int modulus); +static int MarkCacheCompare (const char *ptr1, const char *ptr2); +static enum st_retval MarkCacheCleanUp (char *key, char *value, char *arg); +static DdNode * cuddBddSqueeze (DdManager *dd, DdNode *l, DdNode *u); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes f constrain c.] + + Description [Computes f constrain c (f @ c). + Uses a canonical form: (f' @ c) = (f @ c)'. (Note: this is not true + for c.) List of special cases: +
        +
      • f @ 0 = 0 +
      • f @ 1 = f +
      • 0 @ c = 0 +
      • 1 @ c = 1 +
      • f @ f = 1 +
      • f @ f'= 0 +
      + Returns a pointer to the result if successful; NULL otherwise. Note that if + F=(f1,...,fn) and reordering takes place while computing F @ c, then the + image restriction property (Img(F,c) = Img(F @ c)) is lost.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict Cudd_addConstrain] + +******************************************************************************/ +DdNode * +Cudd_bddConstrain( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddConstrainRecur(dd,f,c); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddConstrain */ + + +/**Function******************************************************************** + + Synopsis [BDD restrict according to Coudert and Madre's algorithm + (ICCAD90).] + + Description [BDD restrict according to Coudert and Madre's algorithm + (ICCAD90). Returns the restricted BDD if successful; otherwise NULL. + If application of restrict results in a BDD larger than the input + BDD, the input BDD is returned.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_addRestrict] + +******************************************************************************/ +DdNode * +Cudd_bddRestrict( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *suppF, *suppC, *commonSupport; + DdNode *cplus, *res; + int retval; + int sizeF, sizeRes; + + /* Check terminal cases here to avoid computing supports in trivial cases. + ** This also allows us notto check later for the case c == 0, in which + ** there is no common support. */ + if (c == Cudd_Not(DD_ONE(dd))) return(Cudd_Not(DD_ONE(dd))); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(DD_ONE(dd)); + if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd))); + + /* Check if supports intersect. */ + retval = Cudd_ClassifySupport(dd,f,c,&commonSupport,&suppF,&suppC); + if (retval == 0) { + return(NULL); + } + cuddRef(commonSupport); cuddRef(suppF); cuddRef(suppC); + Cudd_IterDerefBdd(dd,suppF); + + if (commonSupport == DD_ONE(dd)) { + Cudd_IterDerefBdd(dd,commonSupport); + Cudd_IterDerefBdd(dd,suppC); + return(f); + } + Cudd_IterDerefBdd(dd,commonSupport); + + /* Abstract from c the variables that do not appear in f. */ + cplus = Cudd_bddExistAbstract(dd, c, suppC); + if (cplus == NULL) { + Cudd_IterDerefBdd(dd,suppC); + return(NULL); + } + cuddRef(cplus); + Cudd_IterDerefBdd(dd,suppC); + + do { + dd->reordered = 0; + res = cuddBddRestrictRecur(dd, f, cplus); + } while (dd->reordered == 1); + if (res == NULL) { + Cudd_IterDerefBdd(dd,cplus); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd,cplus); + /* Make restric safe by returning the smaller of the input and the + ** result. */ + sizeF = Cudd_DagSize(f); + sizeRes = Cudd_DagSize(res); + if (sizeF <= sizeRes) { + Cudd_IterDerefBdd(dd, res); + return(f); + } else { + cuddDeref(res); + return(res); + } + +} /* end of Cudd_bddRestrict */ + + +/**Function******************************************************************** + + Synopsis [Computes f non-polluting-and g.] + + Description [Computes f non-polluting-and g. The non-polluting AND + of f and g is a hybrid of AND and Restrict. From Restrict, this + operation takes the idea of existentially quantifying the top + variable of the second operand if it does not appear in the first. + Therefore, the variables that appear in the result also appear in f. + For the rest, the function behaves like AND. Since the two operands + play different roles, non-polluting AND is not commutative. + + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_bddNPAnd( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddNPAndRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddNPAnd */ + + +/**Function******************************************************************** + + Synopsis [Computes f constrain c for ADDs.] + + Description [Computes f constrain c (f @ c), for f an ADD and c a 0-1 + ADD. List of special cases: +
        +
      • F @ 0 = 0 +
      • F @ 1 = F +
      • 0 @ c = 0 +
      • 1 @ c = 1 +
      • F @ F = 1 +
      + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain] + +******************************************************************************/ +DdNode * +Cudd_addConstrain( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddConstrainRecur(dd,f,c); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addConstrain */ + + +/**Function******************************************************************** + + Synopsis [BDD conjunctive decomposition as in McMillan's CAV96 paper.] + + Description [BDD conjunctive decomposition as in McMillan's CAV96 + paper. The decomposition is canonical only for a given variable + order. If canonicity is required, variable ordering must be disabled + after the decomposition has been computed. Returns an array with one + entry for each BDD variable in the manager if successful; otherwise + NULL. The components of the solution have their reference counts + already incremented (unlike the results of most other functions in + the package).] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_bddExistAbstract] + +******************************************************************************/ +DdNode ** +Cudd_bddConstrainDecomp( + DdManager * dd, + DdNode * f) +{ + DdNode **decomp; + int res; + int i; + + /* Create an initialize decomposition array. */ + decomp = ALLOC(DdNode *,dd->size); + if (decomp == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) { + decomp[i] = NULL; + } + do { + dd->reordered = 0; + /* Clean up the decomposition array in case reordering took place. */ + for (i = 0; i < dd->size; i++) { + if (decomp[i] != NULL) { + Cudd_IterDerefBdd(dd, decomp[i]); + decomp[i] = NULL; + } + } + res = cuddBddConstrainDecomp(dd,f,decomp); + } while (dd->reordered == 1); + if (res == 0) { + FREE(decomp); + return(NULL); + } + /* Missing components are constant ones. */ + for (i = 0; i < dd->size; i++) { + if (decomp[i] == NULL) { + decomp[i] = DD_ONE(dd); + cuddRef(decomp[i]); + } + } + return(decomp); + +} /* end of Cudd_bddConstrainDecomp */ + + +/**Function******************************************************************** + + Synopsis [ADD restrict according to Coudert and Madre's algorithm + (ICCAD90).] + + Description [ADD restrict according to Coudert and Madre's algorithm + (ICCAD90). Returns the restricted ADD if successful; otherwise NULL. + If application of restrict results in an ADD larger than the input + ADD, the input ADD is returned.] + + SideEffects [None] + + SeeAlso [Cudd_addConstrain Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_addRestrict( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *supp_f, *supp_c; + DdNode *res, *commonSupport; + int intersection; + int sizeF, sizeRes; + + /* Check if supports intersect. */ + supp_f = Cudd_Support(dd, f); + if (supp_f == NULL) { + return(NULL); + } + cuddRef(supp_f); + supp_c = Cudd_Support(dd, c); + if (supp_c == NULL) { + Cudd_RecursiveDeref(dd,supp_f); + return(NULL); + } + cuddRef(supp_c); + commonSupport = Cudd_bddLiteralSetIntersection(dd, supp_f, supp_c); + if (commonSupport == NULL) { + Cudd_RecursiveDeref(dd,supp_f); + Cudd_RecursiveDeref(dd,supp_c); + return(NULL); + } + cuddRef(commonSupport); + Cudd_RecursiveDeref(dd,supp_f); + Cudd_RecursiveDeref(dd,supp_c); + intersection = commonSupport != DD_ONE(dd); + Cudd_RecursiveDeref(dd,commonSupport); + + if (intersection) { + do { + dd->reordered = 0; + res = cuddAddRestrictRecur(dd, f, c); + } while (dd->reordered == 1); + sizeF = Cudd_DagSize(f); + sizeRes = Cudd_DagSize(res); + if (sizeF <= sizeRes) { + cuddRef(res); + Cudd_RecursiveDeref(dd, res); + return(f); + } else { + return(res); + } + } else { + return(f); + } + +} /* end of Cudd_addRestrict */ + + +/**Function******************************************************************** + + Synopsis [Computes a vector whose image equals a non-zero function.] + + Description [Computes a vector of BDDs whose image equals a non-zero + function. + The result depends on the variable order. The i-th component of the vector + depends only on the first i variables in the order. Each BDD in the vector + is not larger than the BDD of the given characteristic function. This + function is based on the description of char-to-vect in "Verification of + Sequential Machines Using Boolean Functional Vectors" by O. Coudert, C. + Berthet and J. C. Madre. + Returns a pointer to an array containing the result if successful; NULL + otherwise. The size of the array equals the number of variables in the + manager. The components of the solution have their reference counts + already incremented (unlike the results of most other functions in + the package).] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain] + +******************************************************************************/ +DdNode ** +Cudd_bddCharToVect( + DdManager * dd, + DdNode * f) +{ + int i, j; + DdNode **vect; + DdNode *res = NULL; + + if (f == Cudd_Not(DD_ONE(dd))) return(NULL); + + vect = ALLOC(DdNode *, dd->size); + if (vect == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + do { + dd->reordered = 0; + for (i = 0; i < dd->size; i++) { + res = cuddBddCharToVect(dd,f,dd->vars[dd->invperm[i]]); + if (res == NULL) { + /* Clean up the vector array in case reordering took place. */ + for (j = 0; j < i; j++) { + Cudd_IterDerefBdd(dd, vect[dd->invperm[j]]); + } + break; + } + cuddRef(res); + vect[dd->invperm[i]] = res; + } + } while (dd->reordered == 1); + if (res == NULL) { + FREE(vect); + return(NULL); + } + return(vect); + +} /* end of Cudd_bddCharToVect */ + + +/**Function******************************************************************** + + Synopsis [Performs safe minimization of a BDD.] + + Description [Performs safe minimization of a BDD. Given the BDD + f of a function to be minimized and a BDD + c representing the care set, Cudd_bddLICompaction + produces the BDD of a function that agrees with f + wherever c is 1. Safe minimization means that the size + of the result is guaranteed not to exceed the size of + f. This function is based on the DAC97 paper by Hong et + al.. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_bddLICompaction( + DdManager * dd /* manager */, + DdNode * f /* function to be minimized */, + DdNode * c /* constraint (care set) */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddLICompaction(dd,f,c); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddLICompaction */ + + +/**Function******************************************************************** + + Synopsis [Finds a small BDD in a function interval.] + + Description [Finds a small BDD in a function interval. Given BDDs + l and u, representing the lower bound and + upper bound of a function interval, Cudd_bddSqueeze produces the BDD + of a function within the interval with a small BDD. Returns a + pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction] + +******************************************************************************/ +DdNode * +Cudd_bddSqueeze( + DdManager * dd /* manager */, + DdNode * l /* lower bound */, + DdNode * u /* upper bound */) +{ + DdNode *res; + int sizeRes, sizeL, sizeU; + + do { + dd->reordered = 0; + res = cuddBddSqueeze(dd,l,u); + } while (dd->reordered == 1); + if (res == NULL) return(NULL); + /* We now compare the result with the bounds and return the smallest. + ** We first compare to u, so that in case l == 0 and u == 1, we return + ** 0 as in other minimization algorithms. */ + sizeRes = Cudd_DagSize(res); + sizeU = Cudd_DagSize(u); + if (sizeU <= sizeRes) { + cuddRef(res); + Cudd_IterDerefBdd(dd,res); + res = u; + sizeRes = sizeU; + } + sizeL = Cudd_DagSize(l); + if (sizeL <= sizeRes) { + cuddRef(res); + Cudd_IterDerefBdd(dd,res); + res = l; + sizeRes = sizeL; + } + return(res); + +} /* end of Cudd_bddSqueeze */ + + +/**Function******************************************************************** + + Synopsis [Finds a small BDD that agrees with f over + c.] + + Description [Finds a small BDD that agrees with f over + c. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction Cudd_bddSqueeze] + +******************************************************************************/ +DdNode * +Cudd_bddMinimize( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *cplus, *res; + + if (c == Cudd_Not(DD_ONE(dd))) return(c); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(DD_ONE(dd)); + if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd))); + + cplus = Cudd_RemapOverApprox(dd,c,0,0,1.0); + if (cplus == NULL) return(NULL); + cuddRef(cplus); + res = Cudd_bddLICompaction(dd,f,cplus); + if (res == NULL) { + Cudd_IterDerefBdd(dd,cplus); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd,cplus); + cuddDeref(res); + return(res); + +} /* end of Cudd_bddMinimize */ + + +/**Function******************************************************************** + + Synopsis [Find a dense subset of BDD f.] + + Description [Finds a dense subset of BDD f. Density is + the ratio of number of minterms to number of nodes. Uses several + techniques in series. It is more expensive than other subsetting + procedures, but often produces better results. See + Cudd_SubsetShortPaths for a description of the threshold and nvars + parameters. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_RemapUnderApprox Cudd_SubsetShortPaths + Cudd_SubsetHeavyBranch Cudd_bddSqueeze] + +******************************************************************************/ +DdNode * +Cudd_SubsetCompress( + DdManager * dd /* manager */, + DdNode * f /* BDD whose subset is sought */, + int nvars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the subset */) +{ + DdNode *res, *tmp1, *tmp2; + + tmp1 = Cudd_SubsetShortPaths(dd, f, nvars, threshold, 0); + if (tmp1 == NULL) return(NULL); + cuddRef(tmp1); + tmp2 = Cudd_RemapUnderApprox(dd,tmp1,nvars,0,0.95); + if (tmp2 == NULL) { + Cudd_IterDerefBdd(dd,tmp1); + return(NULL); + } + cuddRef(tmp2); + Cudd_IterDerefBdd(dd,tmp1); + res = Cudd_bddSqueeze(dd,tmp2,f); + if (res == NULL) { + Cudd_IterDerefBdd(dd,tmp2); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd,tmp2); + cuddDeref(res); + return(res); + +} /* end of Cudd_SubsetCompress */ + + +/**Function******************************************************************** + + Synopsis [Find a dense superset of BDD f.] + + Description [Finds a dense superset of BDD f. Density is + the ratio of number of minterms to number of nodes. Uses several + techniques in series. It is more expensive than other supersetting + procedures, but often produces better results. See + Cudd_SupersetShortPaths for a description of the threshold and nvars + parameters. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetCompress Cudd_SupersetRemap Cudd_SupersetShortPaths + Cudd_SupersetHeavyBranch Cudd_bddSqueeze] + +******************************************************************************/ +DdNode * +Cudd_SupersetCompress( + DdManager * dd /* manager */, + DdNode * f /* BDD whose superset is sought */, + int nvars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the superset */) +{ + DdNode *subset; + + subset = Cudd_SubsetCompress(dd, Cudd_Not(f),nvars,threshold); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_SupersetCompress */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddConstrain.] + + Description [Performs the recursive step of Cudd_bddConstrain. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain] + +******************************************************************************/ +DdNode * +cuddBddConstrainRecur( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r; + DdNode *one, *zero; + unsigned int topf, topc; + int index; + int comple = 0; + + statLine(dd); + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Trivial cases. */ + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + if (f == Cudd_Not(c)) return(zero); + + /* Make canonical to increase the utilization of the cache. */ + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + comple = 1; + } + /* Now f is a regular pointer to a non-constant node; c is also + ** non-constant, but may be complemented. + */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_bddConstrain, f, c); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + /* Recursive step. */ + topf = dd->perm[f->index]; + topc = dd->perm[Cudd_Regular(c)->index]; + if (topf <= topc) { + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + index = Cudd_Regular(c)->index; + Fv = Fnv = f; + } + if (topc <= topf) { + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } + } else { + Cv = Cnv = c; + } + + if (!Cudd_IsConstant(Cv)) { + t = cuddBddConstrainRecur(dd, Fv, Cv); + if (t == NULL) + return(NULL); + } else if (Cv == one) { + t = Fv; + } else { /* Cv == zero: return Fnv @ Cnv */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddBddConstrainRecur(dd, Fnv, Cnv); + if (r == NULL) + return(NULL); + } + return(Cudd_NotCond(r,comple)); + } + cuddRef(t); + + if (!Cudd_IsConstant(Cnv)) { + e = cuddBddConstrainRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } else if (Cnv == one) { + e = Fnv; + } else { /* Cnv == zero: return Fv @ Cv previously computed */ + cuddDeref(t); + return(Cudd_NotCond(t,comple)); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd, Cudd_bddConstrain, f, c, r); + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddConstrainRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddRestrict.] + + Description [Performs the recursive step of Cudd_bddRestrict. + Returns the restricted BDD if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +cuddBddRestrictRecur( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; + unsigned int topf, topc; + int index; + int comple = 0; + + statLine(dd); + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Trivial cases */ + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + if (f == Cudd_Not(c)) return(zero); + + /* Make canonical to increase the utilization of the cache. */ + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + comple = 1; + } + /* Now f is a regular pointer to a non-constant node; c is also + ** non-constant, but may be complemented. + */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_bddRestrict, f, c); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + topf = dd->perm[f->index]; + topc = dd->perm[Cudd_Regular(c)->index]; + + if (topc < topf) { /* abstract top variable from c */ + DdNode *d, *s1, *s2; + + /* Find complements of cofactors of c. */ + if (Cudd_IsComplement(c)) { + s1 = cuddT(Cudd_Regular(c)); + s2 = cuddE(Cudd_Regular(c)); + } else { + s1 = Cudd_Not(cuddT(c)); + s2 = Cudd_Not(cuddE(c)); + } + /* Take the OR by applying DeMorgan. */ + d = cuddBddAndRecur(dd, s1, s2); + if (d == NULL) return(NULL); + d = Cudd_Not(d); + cuddRef(d); + r = cuddBddRestrictRecur(dd, f, d); + if (r == NULL) { + Cudd_IterDerefBdd(dd, d); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, d); + cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r); + cuddDeref(r); + return(Cudd_NotCond(r,comple)); + } + + /* Recursive step. Here topf <= topc. */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + if (topc == topf) { + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } + } else { + Cv = Cnv = c; + } + + if (!Cudd_IsConstant(Cv)) { + t = cuddBddRestrictRecur(dd, Fv, Cv); + if (t == NULL) return(NULL); + } else if (Cv == one) { + t = Fv; + } else { /* Cv == zero: return(Fnv @ Cnv) */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddBddRestrictRecur(dd, Fnv, Cnv); + if (r == NULL) return(NULL); + } + return(Cudd_NotCond(r,comple)); + } + cuddRef(t); + + if (!Cudd_IsConstant(Cnv)) { + e = cuddBddRestrictRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } else if (Cnv == one) { + e = Fnv; + } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ + cuddDeref(t); + return(Cudd_NotCond(t,comple)); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r); + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddRestrictRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddAnd.] + + Description [Implements the recursive step of Cudd_bddNPAnd. + Returns a pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNPAnd] + +******************************************************************************/ +DdNode * +cuddBddNPAndRecur( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *r, *t, *e; + unsigned int topf, topg, index; + + statLine(manager); + one = DD_ONE(manager); + + /* Terminal cases. */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + if (F == G) { + if (f == g) return(one); + else return(Cudd_Not(one)); + } + if (G == one) { + if (g == one) return(f); + else return(g); + } + if (F == one) { + return(f); + } + + /* At this point f and g are not constant. */ + /* Check cache. */ + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup2(manager, Cudd_bddNPAnd, f, g); + if (r != NULL) return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + + if (topg < topf) { /* abstract top variable from g */ + DdNode *d; + + /* Find complements of cofactors of g. */ + if (Cudd_IsComplement(g)) { + gt = cuddT(G); + ge = cuddE(G); + } else { + gt = Cudd_Not(cuddT(g)); + ge = Cudd_Not(cuddE(g)); + } + /* Take the OR by applying DeMorgan. */ + d = cuddBddAndRecur(manager, gt, ge); + if (d == NULL) return(NULL); + d = Cudd_Not(d); + cuddRef(d); + r = cuddBddNPAndRecur(manager, f, d); + if (r == NULL) { + Cudd_IterDerefBdd(manager, d); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(manager, d); + cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r); + cuddDeref(r); + return(r); + } + + /* Compute cofactors. */ + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + + if (topg == topf) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + t = cuddBddAndRecur(manager, ft, gt); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddAndRecur(manager, fe, ge); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r); + return(r); + +} /* end of cuddBddNPAndRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addConstrain.] + + Description [Performs the recursive step of Cudd_addConstrain. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addConstrain] + +******************************************************************************/ +DdNode * +cuddAddConstrainRecur( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r; + DdNode *one, *zero; + unsigned int topf, topc; + int index; + + statLine(dd); + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + /* Trivial cases. */ + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + + /* Now f and c are non-constant. */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_addConstrain, f, c); + if (r != NULL) { + return(r); + } + + /* Recursive step. */ + topf = dd->perm[f->index]; + topc = dd->perm[c->index]; + if (topf <= topc) { + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + index = c->index; + Fv = Fnv = f; + } + if (topc <= topf) { + Cv = cuddT(c); Cnv = cuddE(c); + } else { + Cv = Cnv = c; + } + + if (!Cudd_IsConstant(Cv)) { + t = cuddAddConstrainRecur(dd, Fv, Cv); + if (t == NULL) + return(NULL); + } else if (Cv == one) { + t = Fv; + } else { /* Cv == zero: return Fnv @ Cnv */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddAddConstrainRecur(dd, Fnv, Cnv); + if (r == NULL) + return(NULL); + } + return(r); + } + cuddRef(t); + + if (!Cudd_IsConstant(Cnv)) { + e = cuddAddConstrainRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } else if (Cnv == one) { + e = Fnv; + } else { /* Cnv == zero: return Fv @ Cv previously computed */ + cuddDeref(t); + return(t); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd, Cudd_addConstrain, f, c, r); + return(r); + +} /* end of cuddAddConstrainRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addRestrict.] + + Description [Performs the recursive step of Cudd_addRestrict. + Returns the restricted ADD if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_addRestrict] + +******************************************************************************/ +DdNode * +cuddAddRestrictRecur( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; + unsigned int topf, topc; + int index; + + statLine(dd); + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + /* Trivial cases */ + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + + /* Now f and c are non-constant. */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_addRestrict, f, c); + if (r != NULL) { + return(r); + } + + topf = dd->perm[f->index]; + topc = dd->perm[c->index]; + + if (topc < topf) { /* abstract top variable from c */ + DdNode *d, *s1, *s2; + + /* Find cofactors of c. */ + s1 = cuddT(c); + s2 = cuddE(c); + /* Take the OR by applying DeMorgan. */ + d = cuddAddApplyRecur(dd, Cudd_addOr, s1, s2); + if (d == NULL) return(NULL); + cuddRef(d); + r = cuddAddRestrictRecur(dd, f, d); + if (r == NULL) { + Cudd_RecursiveDeref(dd, d); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDeref(dd, d); + cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r); + cuddDeref(r); + return(r); + } + + /* Recursive step. Here topf <= topc. */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + if (topc == topf) { + Cv = cuddT(c); Cnv = cuddE(c); + } else { + Cv = Cnv = c; + } + + if (!Cudd_IsConstant(Cv)) { + t = cuddAddRestrictRecur(dd, Fv, Cv); + if (t == NULL) return(NULL); + } else if (Cv == one) { + t = Fv; + } else { /* Cv == zero: return(Fnv @ Cnv) */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddAddRestrictRecur(dd, Fnv, Cnv); + if (r == NULL) return(NULL); + } + return(r); + } + cuddRef(t); + + if (!Cudd_IsConstant(Cnv)) { + e = cuddAddRestrictRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } else if (Cnv == one) { + e = Fnv; + } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ + cuddDeref(t); + return(t); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r); + return(r); + +} /* end of cuddAddRestrictRecur */ + + + +/**Function******************************************************************** + + Synopsis [Performs safe minimization of a BDD.] + + Description [Performs safe minimization of a BDD. Given the BDD + f of a function to be minimized and a BDD + c representing the care set, Cudd_bddLICompaction + produces the BDD of a function that agrees with f + wherever c is 1. Safe minimization means that the size + of the result is guaranteed not to exceed the size of + f. This function is based on the DAC97 paper by Hong et + al.. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction] + +******************************************************************************/ +DdNode * +cuddBddLICompaction( + DdManager * dd /* manager */, + DdNode * f /* function to be minimized */, + DdNode * c /* constraint (care set) */) +{ + st_table *marktable, *markcache, *buildcache; + DdNode *res, *zero; + + zero = Cudd_Not(DD_ONE(dd)); + if (c == zero) return(zero); + + /* We need to use local caches for both steps of this operation. + ** The results of the edge marking step are only valid as long as the + ** edge markings themselves are available. However, the edge markings + ** are lost at the end of one invocation of Cudd_bddLICompaction. + ** Hence, the cache entries for the edge marking step must be + ** invalidated at the end of this function. + ** For the result of the building step we argue as follows. The result + ** for a node and a given constrain depends on the BDD in which the node + ** appears. Hence, the same node and constrain may give different results + ** in successive invocations. + */ + marktable = st_init_table(st_ptrcmp,st_ptrhash); + if (marktable == NULL) { + return(NULL); + } + markcache = st_init_table(MarkCacheCompare,MarkCacheHash); + if (markcache == NULL) { + st_free_table(marktable); + return(NULL); + } + if (cuddBddLICMarkEdges(dd,f,c,marktable,markcache) == CUDD_OUT_OF_MEM) { + st_foreach(markcache, MarkCacheCleanUp, NULL); + st_free_table(marktable); + st_free_table(markcache); + return(NULL); + } + st_foreach(markcache, MarkCacheCleanUp, NULL); + st_free_table(markcache); + buildcache = st_init_table(st_ptrcmp,st_ptrhash); + if (buildcache == NULL) { + st_free_table(marktable); + return(NULL); + } + res = cuddBddLICBuildResult(dd,f,buildcache,marktable); + st_free_table(buildcache); + st_free_table(marktable); + return(res); + +} /* end of cuddBddLICompaction */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddConstrainDecomp.] + + Description [Performs the recursive step of Cudd_bddConstrainDecomp. + Returns f super (i) if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrainDecomp] + +******************************************************************************/ +static int +cuddBddConstrainDecomp( + DdManager * dd, + DdNode * f, + DdNode ** decomp) +{ + DdNode *F, *fv, *fvn; + DdNode *fAbs; + DdNode *result; + int ok; + + if (Cudd_IsConstant(f)) return(1); + /* Compute complements of cofactors. */ + F = Cudd_Regular(f); + fv = cuddT(F); + fvn = cuddE(F); + if (F == f) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + /* Compute abstraction of top variable. */ + fAbs = cuddBddAndRecur(dd, fv, fvn); + if (fAbs == NULL) { + return(0); + } + cuddRef(fAbs); + fAbs = Cudd_Not(fAbs); + /* Recursively find the next abstraction and the components of the + ** decomposition. */ + ok = cuddBddConstrainDecomp(dd, fAbs, decomp); + if (ok == 0) { + Cudd_IterDerefBdd(dd,fAbs); + return(0); + } + /* Compute the component of the decomposition corresponding to the + ** top variable and store it in the decomposition array. */ + result = cuddBddConstrainRecur(dd, f, fAbs); + if (result == NULL) { + Cudd_IterDerefBdd(dd,fAbs); + return(0); + } + cuddRef(result); + decomp[F->index] = result; + Cudd_IterDerefBdd(dd, fAbs); + return(1); + +} /* end of cuddBddConstrainDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCharToVect.] + + Description [Performs the recursive step of Cudd_bddCharToVect. + This function maintains the invariant that f is non-zero. + Returns the i-th component of the vector if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddCharToVect] + +******************************************************************************/ +static DdNode * +cuddBddCharToVect( + DdManager * dd, + DdNode * f, + DdNode * x) +{ + unsigned int topf; + unsigned int level; + int comple; + + DdNode *one, *zero, *res, *F, *fT, *fE, *T, *E; + + statLine(dd); + /* Check the cache. */ + res = cuddCacheLookup2(dd, cuddBddCharToVect, f, x); + if (res != NULL) { + return(res); + } + + F = Cudd_Regular(f); + + topf = cuddI(dd,F->index); + level = dd->perm[x->index]; + + if (topf > level) return(x); + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + comple = F != f; + fT = Cudd_NotCond(cuddT(F),comple); + fE = Cudd_NotCond(cuddE(F),comple); + + if (topf == level) { + if (fT == zero) return(zero); + if (fE == zero) return(one); + return(x); + } + + /* Here topf < level. */ + if (fT == zero) return(cuddBddCharToVect(dd, fE, x)); + if (fE == zero) return(cuddBddCharToVect(dd, fT, x)); + + T = cuddBddCharToVect(dd, fT, x); + if (T == NULL) { + return(NULL); + } + cuddRef(T); + E = cuddBddCharToVect(dd, fE, x); + if (E == NULL) { + Cudd_IterDerefBdd(dd,T); + return(NULL); + } + cuddRef(E); + res = cuddBddIteRecur(dd, dd->vars[F->index], T, E); + if (res == NULL) { + Cudd_IterDerefBdd(dd,T); + Cudd_IterDerefBdd(dd,E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + cuddCacheInsert2(dd, cuddBddCharToVect, f, x, res); + return(res); + +} /* end of cuddBddCharToVect */ + + +/**Function******************************************************************** + + Synopsis [Performs the edge marking step of Cudd_bddLICompaction.] + + Description [Performs the edge marking step of Cudd_bddLICompaction. + Returns the LUB of the markings of the two outgoing edges of f + if successful; otherwise CUDD_OUT_OF_MEM.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction cuddBddLICBuildResult] + +******************************************************************************/ +static int +cuddBddLICMarkEdges( + DdManager * dd, + DdNode * f, + DdNode * c, + st_table * table, + st_table * cache) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv; + DdNode *one, *zero; + unsigned int topf, topc; + int comple; + int resT, resE, res, retval; + char **slot; + MarkCacheKey *key; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (c == zero) return(DD_LIC_DC); + if (f == one) return(DD_LIC_1); + if (f == zero) return(DD_LIC_0); + + /* Make canonical to increase the utilization of the cache. */ + comple = Cudd_IsComplement(f); + f = Cudd_Regular(f); + /* Now f is a regular pointer to a non-constant node; c may be + ** constant, or it may be complemented. + */ + + /* Check the cache. */ + key = ALLOC(MarkCacheKey, 1); + if (key == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + key->f = f; key->c = c; + if (st_lookup_int(cache, (char *)key, &res)) { + FREE(key); + if (comple) { + if (res == DD_LIC_0) res = DD_LIC_1; + else if (res == DD_LIC_1) res = DD_LIC_0; + } + return(res); + } + + /* Recursive step. */ + topf = dd->perm[f->index]; + topc = cuddI(dd,Cudd_Regular(c)->index); + if (topf <= topc) { + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topc <= topf) { + /* We know that c is not constant because f is not. */ + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } + } else { + Cv = Cnv = c; + } + + resT = cuddBddLICMarkEdges(dd, Fv, Cv, table, cache); + if (resT == CUDD_OUT_OF_MEM) { + FREE(key); + return(CUDD_OUT_OF_MEM); + } + resE = cuddBddLICMarkEdges(dd, Fnv, Cnv, table, cache); + if (resE == CUDD_OUT_OF_MEM) { + FREE(key); + return(CUDD_OUT_OF_MEM); + } + + /* Update edge markings. */ + if (topf <= topc) { + retval = st_find_or_add(table, (char *)f, (char ***)&slot); + if (retval == 0) { + *slot = (char *) (ptrint)((resT << 2) | resE); + } else if (retval == 1) { + *slot = (char *) (ptrint)((int)((ptrint) *slot) | (resT << 2) | resE); + } else { + FREE(key); + return(CUDD_OUT_OF_MEM); + } + } + + /* Cache result. */ + res = resT | resE; + if (st_insert(cache, (char *)key, (char *)(ptrint)res) == ST_OUT_OF_MEM) { + FREE(key); + return(CUDD_OUT_OF_MEM); + } + + /* Take into account possible complementation. */ + if (comple) { + if (res == DD_LIC_0) res = DD_LIC_1; + else if (res == DD_LIC_1) res = DD_LIC_0; + } + return(res); + +} /* end of cuddBddLICMarkEdges */ + + +/**Function******************************************************************** + + Synopsis [Builds the result of Cudd_bddLICompaction.] + + Description [Builds the results of Cudd_bddLICompaction. + Returns a pointer to the minimized BDD if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction cuddBddLICMarkEdges] + +******************************************************************************/ +static DdNode * +cuddBddLICBuildResult( + DdManager * dd, + DdNode * f, + st_table * cache, + st_table * table) +{ + DdNode *Fv, *Fnv, *r, *t, *e; + DdNode *one, *zero; + int index; + int comple; + int markT, markE, markings; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + if (Cudd_IsConstant(f)) return(f); + /* Make canonical to increase the utilization of the cache. */ + comple = Cudd_IsComplement(f); + f = Cudd_Regular(f); + + /* Check the cache. */ + if (st_lookup(cache, f, &r)) { + return(Cudd_NotCond(r,comple)); + } + + /* Retrieve the edge markings. */ + if (st_lookup_int(table, (char *)f, &markings) == 0) + return(NULL); + markT = markings >> 2; + markE = markings & 3; + + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + + if (markT == DD_LIC_NL) { + t = cuddBddLICBuildResult(dd,Fv,cache,table); + if (t == NULL) { + return(NULL); + } + } else if (markT == DD_LIC_1) { + t = one; + } else { + t = zero; + } + cuddRef(t); + if (markE == DD_LIC_NL) { + e = cuddBddLICBuildResult(dd,Fnv,cache,table); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } + } else if (markE == DD_LIC_1) { + e = one; + } else { + e = zero; + } + cuddRef(e); + + if (markT == DD_LIC_DC && markE != DD_LIC_DC) { + r = e; + } else if (markT != DD_LIC_DC && markE == DD_LIC_DC) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + } + cuddDeref(t); + cuddDeref(e); + + if (st_insert(cache, (char *)f, (char *)r) == ST_OUT_OF_MEM) { + cuddRef(r); + Cudd_IterDerefBdd(dd,r); + return(NULL); + } + + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddLICBuildResult */ + + +/**Function******************************************************************** + + Synopsis [Hash function for the computed table of cuddBddLICMarkEdges.] + + Description [Hash function for the computed table of + cuddBddLICMarkEdges. Returns the bucket number.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction] + +******************************************************************************/ +static int +MarkCacheHash( + char * ptr, + int modulus) +{ + int val = 0; + MarkCacheKey *entry; + + entry = (MarkCacheKey *) ptr; + + val = (int) (ptrint) entry->f; + val = val * 997 + (int) (ptrint) entry->c; + + return ((val < 0) ? -val : val) % modulus; + +} /* end of MarkCacheHash */ + + +/**Function******************************************************************** + + Synopsis [Comparison function for the computed table of + cuddBddLICMarkEdges.] + + Description [Comparison function for the computed table of + cuddBddLICMarkEdges. Returns 0 if the two nodes of the key are equal; 1 + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction] + +******************************************************************************/ +static int +MarkCacheCompare( + const char * ptr1, + const char * ptr2) +{ + MarkCacheKey *entry1, *entry2; + + entry1 = (MarkCacheKey *) ptr1; + entry2 = (MarkCacheKey *) ptr2; + + return((entry1->f != entry2->f) || (entry1->c != entry2->c)); + +} /* end of MarkCacheCompare */ + + +/**Function******************************************************************** + + Synopsis [Frees memory associated with computed table of + cuddBddLICMarkEdges.] + + Description [Frees memory associated with computed table of + cuddBddLICMarkEdges. Returns ST_CONTINUE.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction] + +******************************************************************************/ +static enum st_retval +MarkCacheCleanUp( + char * key, + char * value, + char * arg) +{ + MarkCacheKey *entry; + + entry = (MarkCacheKey *) key; + FREE(entry); + return ST_CONTINUE; + +} /* end of MarkCacheCleanUp */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddSqueeze.] + + Description [Performs the recursive step of Cudd_bddSqueeze. This + procedure exploits the fact that if we complement and swap the + bounds of the interval we obtain a valid solution by taking the + complement of the solution to the original problem. Therefore, we + can enforce the condition that the upper bound is always regular. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddSqueeze] + +******************************************************************************/ +static DdNode * +cuddBddSqueeze( + DdManager * dd, + DdNode * l, + DdNode * u) +{ + DdNode *one, *zero, *r, *lt, *le, *ut, *ue, *t, *e; +#if 0 + DdNode *ar; +#endif + int comple = 0; + unsigned int topu, topl; + int index; + + statLine(dd); + if (l == u) { + return(l); + } + one = DD_ONE(dd); + zero = Cudd_Not(one); + /* The only case when l == zero && u == one is at the top level, + ** where returning either one or zero is OK. In all other cases + ** the procedure will detect such a case and will perform + ** remapping. Therefore the order in which we test l and u at this + ** point is immaterial. */ + if (l == zero) return(l); + if (u == one) return(u); + + /* Make canonical to increase the utilization of the cache. */ + if (Cudd_IsComplement(u)) { + DdNode *temp; + temp = Cudd_Not(l); + l = Cudd_Not(u); + u = temp; + comple = 1; + } + /* At this point u is regular and non-constant; l is non-constant, but + ** may be complemented. */ + + /* Here we could check the relative sizes. */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_bddSqueeze, l, u); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + /* Recursive step. */ + topu = dd->perm[u->index]; + topl = dd->perm[Cudd_Regular(l)->index]; + if (topu <= topl) { + index = u->index; + ut = cuddT(u); ue = cuddE(u); + } else { + index = Cudd_Regular(l)->index; + ut = ue = u; + } + if (topl <= topu) { + lt = cuddT(Cudd_Regular(l)); le = cuddE(Cudd_Regular(l)); + if (Cudd_IsComplement(l)) { + lt = Cudd_Not(lt); + le = Cudd_Not(le); + } + } else { + lt = le = l; + } + + /* If one interval is contained in the other, use the smaller + ** interval. This corresponds to one-sided matching. */ + if ((lt == zero || Cudd_bddLeq(dd,lt,le)) && + (ut == one || Cudd_bddLeq(dd,ue,ut))) { /* remap */ + r = cuddBddSqueeze(dd, le, ue); + if (r == NULL) + return(NULL); + return(Cudd_NotCond(r,comple)); + } else if ((le == zero || Cudd_bddLeq(dd,le,lt)) && + (ue == one || Cudd_bddLeq(dd,ut,ue))) { /* remap */ + r = cuddBddSqueeze(dd, lt, ut); + if (r == NULL) + return(NULL); + return(Cudd_NotCond(r,comple)); + } else if ((le == zero || Cudd_bddLeq(dd,le,Cudd_Not(ut))) && + (ue == one || Cudd_bddLeq(dd,Cudd_Not(lt),ue))) { /* c-remap */ + t = cuddBddSqueeze(dd, lt, ut); + cuddRef(t); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(dd, index, Cudd_Not(t), t); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(dd, index, t, Cudd_Not(t)); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddDeref(t); + if (r == NULL) + return(NULL); + cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); + return(Cudd_NotCond(r,comple)); + } else if ((lt == zero || Cudd_bddLeq(dd,lt,Cudd_Not(ue))) && + (ut == one || Cudd_bddLeq(dd,Cudd_Not(le),ut))) { /* c-remap */ + e = cuddBddSqueeze(dd, le, ue); + cuddRef(e); + if (Cudd_IsComplement(e)) { + r = cuddUniqueInter(dd, index, Cudd_Not(e), e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + } else { + r = cuddUniqueInter(dd, index, e, Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + r = Cudd_Not(r); + } + cuddDeref(e); + if (r == NULL) + return(NULL); + cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); + return(Cudd_NotCond(r,comple)); + } + +#if 0 + /* If the two intervals intersect, take a solution from + ** the intersection of the intervals. This guarantees that the + ** splitting variable will not appear in the result. + ** This approach corresponds to two-sided matching, and is very + ** expensive. */ + if (Cudd_bddLeq(dd,lt,ue) && Cudd_bddLeq(dd,le,ut)) { + DdNode *au, *al; + au = cuddBddAndRecur(dd,ut,ue); + if (au == NULL) + return(NULL); + cuddRef(au); + al = cuddBddAndRecur(dd,Cudd_Not(lt),Cudd_Not(le)); + if (al == NULL) { + Cudd_IterDerefBdd(dd,au); + return(NULL); + } + cuddRef(al); + al = Cudd_Not(al); + ar = cuddBddSqueeze(dd, al, au); + if (ar == NULL) { + Cudd_IterDerefBdd(dd,au); + Cudd_IterDerefBdd(dd,al); + return(NULL); + } + cuddRef(ar); + Cudd_IterDerefBdd(dd,au); + Cudd_IterDerefBdd(dd,al); + } else { + ar = NULL; + } +#endif + + t = cuddBddSqueeze(dd, lt, ut); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + e = cuddBddSqueeze(dd, le, ue); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + +#if 0 + /* Check whether there is a result obtained by abstraction and whether + ** it is better than the one obtained by recursion. */ + cuddRef(r); + if (ar != NULL) { + if (Cudd_DagSize(ar) <= Cudd_DagSize(r)) { + Cudd_IterDerefBdd(dd, r); + r = ar; + } else { + Cudd_IterDerefBdd(dd, ar); + } + } + cuddDeref(r); +#endif + + cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddSqueeze */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddGenetic.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddGenetic.c new file mode 100644 index 000000000..8b259fe70 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddGenetic.c @@ -0,0 +1,960 @@ +/**CFile*********************************************************************** + + FileName [cuddGenetic.c] + + PackageName [cudd] + + Synopsis [Genetic algorithm for variable reordering.] + + Description [Internal procedures included in this file: +
        +
      • cuddGa() +
      + Static procedures included in this module: +
        +
      • make_random() +
      • sift_up() +
      • build_dd() +
      • largest() +
      • rand_int() +
      • array_hash() +
      • array_compare() +
      • find_best() +
      • find_average_fitness() +
      • PMX() +
      • roulette() +
      + + The genetic algorithm implemented here is as follows. We start with + the current DD order. We sift this order and use this as the + reference DD. We only keep 1 DD around for the entire process and + simply rearrange the order of this DD, storing the various orders + and their corresponding DD sizes. We generate more random orders to + build an initial population. This initial population is 3 times the + number of variables, with a maximum of 120. Each random order is + built (from the reference DD) and its size stored. Each random + order is also sifted to keep the DD sizes fairly small. Then a + crossover is performed between two orders (picked randomly) and the + two resulting DDs are built and sifted. For each new order, if its + size is smaller than any DD in the population, it is inserted into + the population and the DD with the largest number of nodes is thrown + out. The crossover process happens up to 50 times, and at this point + the DD in the population with the smallest size is chosen as the + result. This DD must then be built from the reference DD.] + + SeeAlso [] + + Author [Curt Musfeldt, Alan Shuler, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddGenetic.c,v 1.30 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static int popsize; /* the size of the population */ +static int numvars; /* the number of input variables in the ckt. */ +/* storedd stores the population orders and sizes. This table has two +** extra rows and one extras column. The two extra rows are used for the +** offspring produced by a crossover. Each row stores one order and its +** size. The order is stored by storing the indices of variables in the +** order in which they appear in the order. The table is in reality a +** one-dimensional array which is accessed via a macro to give the illusion +** it is a two-dimensional structure. +*/ +static int *storedd; +static st_table *computed; /* hash table to identify existing orders */ +static int *repeat; /* how many times an order is present */ +static int large; /* stores the index of the population with + ** the largest number of nodes in the DD */ +static int result; +static int cross; /* the number of crossovers to perform */ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/* macro used to access the population table as if it were a +** two-dimensional structure. +*/ +#define STOREDD(i,j) storedd[(i)*(numvars+1)+(j)] + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int make_random (DdManager *table, int lower); +static int sift_up (DdManager *table, int x, int x_low); +static int build_dd (DdManager *table, int num, int lower, int upper); +static int largest (void); +static int rand_int (int a); +static int array_hash (char *array, int modulus); +static int array_compare (const char *array1, const char *array2); +static int find_best (void); +#ifdef DD_STATS +static double find_average_fitness (void); +#endif +static int PMX (int maxvar); +static int roulette (int *p1, int *p2); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Genetic algorithm for DD reordering.] + + Description [Genetic algorithm for DD reordering. + The two children of a crossover will be stored in + storedd[popsize] and storedd[popsize+1] --- the last two slots in the + storedd array. (This will make comparisons and replacement easy.) + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddGa( + DdManager * table /* manager */, + int lower /* lowest level to be reordered */, + int upper /* highest level to be reorderded */) +{ + int i,n,m; /* dummy/loop vars */ + int index; +#ifdef DD_STATS + double average_fitness; +#endif + int small; /* index of smallest DD in population */ + + /* Do an initial sifting to produce at least one reasonable individual. */ + if (!cuddSifting(table,lower,upper)) return(0); + + /* Get the initial values. */ + numvars = upper - lower + 1; /* number of variables to be reordered */ + if (table->populationSize == 0) { + popsize = 3 * numvars; /* population size is 3 times # of vars */ + if (popsize > 120) { + popsize = 120; /* Maximum population size is 120 */ + } + } else { + popsize = table->populationSize; /* user specified value */ + } + if (popsize < 4) popsize = 4; /* enforce minimum population size */ + + /* Allocate population table. */ + storedd = ALLOC(int,(popsize+2)*(numvars+1)); + if (storedd == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + + /* Initialize the computed table. This table is made up of two data + ** structures: A hash table with the key given by the order, which says + ** if a given order is present in the population; and the repeat + ** vector, which says how many copies of a given order are stored in + ** the population table. If there are multiple copies of an order, only + ** one has a repeat count greater than 1. This copy is the one pointed + ** by the computed table. + */ + repeat = ALLOC(int,popsize); + if (repeat == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + FREE(storedd); + return(0); + } + for (i = 0; i < popsize; i++) { + repeat[i] = 0; + } + computed = st_init_table(array_compare,array_hash); + if (computed == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + FREE(storedd); + FREE(repeat); + return(0); + } + + /* Copy the current DD and its size to the population table. */ + for (i = 0; i < numvars; i++) { + STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */ + } + STOREDD(0,numvars) = table->keys - table->isolated; /* size of initial DD */ + + /* Store the initial order in the computed table. */ + if (st_insert(computed,(char *)storedd,(char *) 0) == ST_OUT_OF_MEM) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[0]++; + + /* Insert the reverse order as second element of the population. */ + for (i = 0; i < numvars; i++) { + STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */ + } + + /* Now create the random orders. make_random fills the population + ** table with random permutations. The successive loop builds and sifts + ** the DDs for the reverse order and each random permutation, and stores + ** the results in the computed table. + */ + if (!make_random(table,lower)) { + table->errorCode = CUDD_MEMORY_OUT; + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + for (i = 1; i < popsize; i++) { + result = build_dd(table,i,lower,upper); /* build and sift order */ + if (!result) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + if (st_lookup_int(computed,(char *)&STOREDD(i,0),&index)) { + repeat[index]++; + } else { + if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) == + ST_OUT_OF_MEM) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[i]++; + } + } + +#if 0 +#ifdef DD_STATS + /* Print the initial population. */ + (void) fprintf(table->out,"Initial population after sifting\n"); + for (m = 0; m < popsize; m++) { + for (i = 0; i < numvars; i++) { + (void) fprintf(table->out," %2d",STOREDD(m,i)); + } + (void) fprintf(table->out," : %3d (%d)\n", + STOREDD(m,numvars),repeat[m]); + } +#endif +#endif + + small = find_best(); +#ifdef DD_STATS + average_fitness = find_average_fitness(); + (void) fprintf(table->out,"\nInitial population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness); +#endif + + /* Decide how many crossovers should be tried. */ + if (table->numberXovers == 0) { + cross = 3*numvars; + if (cross > 60) { /* do a maximum of 50 crossovers */ + cross = 60; + } + } else { + cross = table->numberXovers; /* use user specified value */ + } + if (cross >= popsize) { + cross = popsize; + } + + /* Perform the crossovers to get the best order. */ + for (m = 0; m < cross; m++) { + if (!PMX(table->size)) { /* perform one crossover */ + table->errorCode = CUDD_MEMORY_OUT; + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + /* The offsprings are left in the last two entries of the + ** population table. These are now considered in turn. + */ + for (i = popsize; i <= popsize+1; i++) { + result = build_dd(table,i,lower,upper); /* build and sift child */ + if (!result) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + large = largest(); /* find the largest DD in population */ + + /* If the new child is smaller than the largest DD in the current + ** population, enter it into the population in place of the + ** largest DD. + */ + if (STOREDD(i,numvars) < STOREDD(large,numvars)) { + /* Look up the largest DD in the computed table. + ** Decrease its repetition count. If the repetition count + ** goes to 0, remove the largest DD from the computed table. + */ + result = st_lookup_int(computed,(char *)&STOREDD(large,0), + &index); + if (!result) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[index]--; + if (repeat[index] == 0) { + int *pointer = &STOREDD(index,0); + result = st_delete(computed, &pointer, NULL); + if (!result) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + } + /* Copy the new individual to the entry of the + ** population table just made available and update the + ** computed table. + */ + for (n = 0; n <= numvars; n++) { + STOREDD(large,n) = STOREDD(i,n); + } + if (st_lookup_int(computed,(char *)&STOREDD(large,0), + &index)) { + repeat[index]++; + } else { + if (st_insert(computed,(char *)&STOREDD(large,0), + (char *)(long)large) == ST_OUT_OF_MEM) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[large]++; + } + } + } + } + + /* Find the smallest DD in the population and build it; + ** that will be the result. + */ + small = find_best(); + + /* Print stats on the final population. */ +#ifdef DD_STATS + average_fitness = find_average_fitness(); + (void) fprintf(table->out,"\nFinal population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness); +#endif + + /* Clean up, build the result DD, and return. */ + st_free_table(computed); + computed = NULL; + result = build_dd(table,small,lower,upper); + FREE(storedd); + FREE(repeat); + return(result); + +} /* end of cuddGa */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Generates the random sequences for the initial population.] + + Description [Generates the random sequences for the initial population. + The sequences are permutations of the indices between lower and + upper in the current order.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +make_random( + DdManager * table, + int lower) +{ + int i,j; /* loop variables */ + int *used; /* is a number already in a permutation */ + int next; /* next random number without repetitions */ + + used = ALLOC(int,numvars); + if (used == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } +#if 0 +#ifdef DD_STATS + (void) fprintf(table->out,"Initial population before sifting\n"); + for (i = 0; i < 2; i++) { + for (j = 0; j < numvars; j++) { + (void) fprintf(table->out," %2d",STOREDD(i,j)); + } + (void) fprintf(table->out,"\n"); + } +#endif +#endif + for (i = 2; i < popsize; i++) { + for (j = 0; j < numvars; j++) { + used[j] = 0; + } + /* Generate a permutation of {0...numvars-1} and use it to + ** permute the variables in the layesr from lower to upper. + */ + for (j = 0; j < numvars; j++) { + do { + next = rand_int(numvars-1); + } while (used[next] != 0); + used[next] = 1; + STOREDD(i,j) = table->invperm[next+lower]; + } +#if 0 +#ifdef DD_STATS + /* Print the order just generated. */ + for (j = 0; j < numvars; j++) { + (void) fprintf(table->out," %2d",STOREDD(i,j)); + } + (void) fprintf(table->out,"\n"); +#endif +#endif + } + FREE(used); + return(1); + +} /* end of make_random */ + + +/**Function******************************************************************** + + Synopsis [Moves one variable up.] + + Description [Takes a variable from position x and sifts it up to + position x_low; x_low should be less than x. Returns 1 if successful; + 0 otherwise] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +sift_up( + DdManager * table, + int x, + int x_low) +{ + int y; + int size; + + y = cuddNextLow(table,x); + while (y >= x_low) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); + } + return(1); + +} /* end of sift_up */ + + +/**Function******************************************************************** + + Synopsis [Builds a DD from a given order.] + + Description [Builds a DD from a given order. This procedure also + sifts the final order and inserts into the array the size in nodes + of the result. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +build_dd( + DdManager * table, + int num /* the index of the individual to be built */, + int lower, + int upper) +{ + int i,j; /* loop vars */ + int position; + int index; + int limit; /* how large the DD for this order can grow */ + int size; + + /* Check the computed table. If the order already exists, it + ** suffices to copy the size from the existing entry. + */ + if (computed && st_lookup_int(computed,(char *)&STOREDD(num,0),&index)) { + STOREDD(num,numvars) = STOREDD(index,numvars); +#ifdef DD_STATS + (void) fprintf(table->out,"\nCache hit for index %d", index); +#endif + return(1); + } + + /* Stop if the DD grows 20 times larges than the reference size. */ + limit = 20 * STOREDD(0,numvars); + + /* Sift up the variables so as to build the desired permutation. + ** First the variable that has to be on top is sifted to the top. + ** Then the variable that has to occupy the secon position is sifted + ** up to the second position, and so on. + */ + for (j = 0; j < numvars; j++) { + i = STOREDD(num,j); + position = table->perm[i]; + result = sift_up(table,position,j+lower); + if (!result) return(0); + size = table->keys - table->isolated; + if (size > limit) break; + } + + /* Sift the DD just built. */ +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + result = cuddSifting(table,lower,upper); + if (!result) return(0); + + /* Copy order and size to table. */ + for (j = 0; j < numvars; j++) { + STOREDD(num,j) = table->invperm[lower+j]; + } + STOREDD(num,numvars) = table->keys - table->isolated; /* size of new DD */ + return(1); + +} /* end of build_dd */ + + +/**Function******************************************************************** + + Synopsis [Finds the largest DD in the population.] + + Description [Finds the largest DD in the population. If an order is + repeated, it avoids choosing the copy that is in the computed table + (it has repeat[i] > 1).] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +largest(void) +{ + int i; /* loop var */ + int big; /* temporary holder to return result */ + + big = 0; + while (repeat[big] > 1) big++; + for (i = big + 1; i < popsize; i++) { + if (STOREDD(i,numvars) >= STOREDD(big,numvars) && repeat[i] <= 1) { + big = i; + } + } + return(big); + +} /* end of largest */ + + +/**Function******************************************************************** + + Synopsis [Generates a random number between 0 and the integer a.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +rand_int( + int a) +{ + return(Cudd_Random() % (a+1)); + +} /* end of rand_int */ + + +/**Function******************************************************************** + + Synopsis [Hash function for the computed table.] + + Description [Hash function for the computed table. Returns the bucket + number.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +array_hash( + char * array, + int modulus) +{ + int val = 0; + int i; + int *intarray; + + intarray = (int *) array; + + for (i = 0; i < numvars; i++) { + val = val * 997 + intarray[i]; + } + + return ((val < 0) ? -val : val) % modulus; + +} /* end of array_hash */ + + +/**Function******************************************************************** + + Synopsis [Comparison function for the computed table.] + + Description [Comparison function for the computed table. Returns 0 if + the two arrays are equal; 1 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +array_compare( + const char * array1, + const char * array2) +{ + int i; + int *intarray1, *intarray2; + + intarray1 = (int *) array1; + intarray2 = (int *) array2; + + for (i = 0; i < numvars; i++) { + if (intarray1[i] != intarray2[i]) return(1); + } + return(0); + +} /* end of array_compare */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the fittest individual.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +find_best(void) +{ + int i,small; + + small = 0; + for (i = 1; i < popsize; i++) { + if (STOREDD(i,numvars) < STOREDD(small,numvars)) { + small = i; + } + } + return(small); + +} /* end of find_best */ + + +/**Function******************************************************************** + + Synopsis [Returns the average fitness of the population.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +#ifdef DD_STATS +static double +find_average_fitness(void) +{ + int i; + int total_fitness = 0; + double average_fitness; + + for (i = 0; i < popsize; i++) { + total_fitness += STOREDD(i,numvars); + } + average_fitness = (double) total_fitness / (double) popsize; + return(average_fitness); + +} /* end of find_average_fitness */ +#endif + + +/**Function******************************************************************** + + Synopsis [Performs the crossover between two parents.] + + Description [Performs the crossover between two randomly chosen + parents, and creates two children, x1 and x2. Uses the Partially + Matched Crossover operator.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +PMX( + int maxvar) +{ + int cut1,cut2; /* the two cut positions (random) */ + int mom,dad; /* the two randomly chosen parents */ + int *inv1; /* inverse permutations for repair algo */ + int *inv2; + int i; /* loop vars */ + int u,v; /* aux vars */ + + inv1 = ALLOC(int,maxvar); + if (inv1 == NULL) { + return(0); + } + inv2 = ALLOC(int,maxvar); + if (inv2 == NULL) { + FREE(inv1); + return(0); + } + + /* Choose two orders from the population using roulette wheel. */ + if (!roulette(&mom,&dad)) { + FREE(inv1); + FREE(inv2); + return(0); + } + + /* Choose two random cut positions. A cut in position i means that + ** the cut immediately precedes position i. If cut1 < cut2, we + ** exchange the middle of the two orderings; otherwise, we + ** exchange the beginnings and the ends. + */ + cut1 = rand_int(numvars-1); + do { + cut2 = rand_int(numvars-1); + } while (cut1 == cut2); + +#if 0 + /* Print out the parents. */ + (void) fprintf(table->out, + "Crossover of %d (mom) and %d (dad) between %d and %d\n", + mom,dad,cut1,cut2); + for (i = 0; i < numvars; i++) { + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(mom,i)); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < numvars; i++) { + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(dad,i)); + } + (void) fprintf(table->out,"\n"); +#endif + + /* Initialize the inverse permutations: -1 means yet undetermined. */ + for (i = 0; i < maxvar; i++) { + inv1[i] = -1; + inv2[i] = -1; + } + + /* Copy the portions whithin the cuts. */ + for (i = cut1; i != cut2; i = (i == numvars-1) ? 0 : i+1) { + STOREDD(popsize,i) = STOREDD(dad,i); + inv1[STOREDD(popsize,i)] = i; + STOREDD(popsize+1,i) = STOREDD(mom,i); + inv2[STOREDD(popsize+1,i)] = i; + } + + /* Now apply the repair algorithm outside the cuts. */ + for (i = cut2; i != cut1; i = (i == numvars-1 ) ? 0 : i+1) { + v = i; + do { + u = STOREDD(mom,v); + v = inv1[u]; + } while (v != -1); + STOREDD(popsize,i) = u; + inv1[u] = i; + v = i; + do { + u = STOREDD(dad,v); + v = inv2[u]; + } while (v != -1); + STOREDD(popsize+1,i) = u; + inv2[u] = i; + } + +#if 0 + /* Print the results of crossover. */ + for (i = 0; i < numvars; i++) { + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(popsize,i)); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < numvars; i++) { + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(popsize+1,i)); + } + (void) fprintf(table->out,"\n"); +#endif + + FREE(inv1); + FREE(inv2); + return(1); + +} /* end of PMX */ + + +/**Function******************************************************************** + + Synopsis [Selects two parents with the roulette wheel method.] + + Description [Selects two distinct parents with the roulette wheel method.] + + SideEffects [The indices of the selected parents are returned as side + effects.] + + SeeAlso [] + +******************************************************************************/ +static int +roulette( + int * p1, + int * p2) +{ + double *wheel; + double spin; + int i; + + wheel = ALLOC(double,popsize); + if (wheel == NULL) { + return(0); + } + + /* The fitness of an individual is the reciprocal of its size. */ + wheel[0] = 1.0 / (double) STOREDD(0,numvars); + + for (i = 1; i < popsize; i++) { + wheel[i] = wheel[i-1] + 1.0 / (double) STOREDD(i,numvars); + } + + /* Get a random number between 0 and wheel[popsize-1] (that is, + ** the sum of all fitness values. 2147483561 is the largest number + ** returned by Cudd_Random. + */ + spin = wheel[numvars-1] * (double) Cudd_Random() / 2147483561.0; + + /* Find the lucky element by scanning the wheel. */ + for (i = 0; i < popsize; i++) { + if (spin <= wheel[i]) break; + } + *p1 = i; + + /* Repeat the process for the second parent, making sure it is + ** distinct from the first. + */ + do { + spin = wheel[popsize-1] * (double) Cudd_Random() / 2147483561.0; + for (i = 0; i < popsize; i++) { + if (spin <= wheel[i]) break; + } + } while (i == *p1); + *p2 = i; + + FREE(wheel); + return(1); + +} /* end of roulette */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddGroup.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddGroup.c new file mode 100644 index 000000000..03a1bb7aa --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddGroup.c @@ -0,0 +1,2188 @@ +/**CFile*********************************************************************** + + FileName [cuddGroup.c] + + PackageName [cudd] + + Synopsis [Functions for group sifting.] + + Description [External procedures included in this file: +
        +
      • Cudd_MakeTreeNode() +
      + Internal procedures included in this file: +
        +
      • cuddTreeSifting() +
      + Static procedures included in this module: +
        +
      • ddTreeSiftingAux() +
      • ddCountInternalMtrNodes() +
      • ddReorderChildren() +
      • ddFindNodeHiLo() +
      • ddUniqueCompareGroup() +
      • ddGroupSifting() +
      • ddCreateGroup() +
      • ddGroupSiftingAux() +
      • ddGroupSiftingUp() +
      • ddGroupSiftingDown() +
      • ddGroupMove() +
      • ddGroupMoveBackward() +
      • ddGroupSiftingBackward() +
      • ddMergeGroups() +
      • ddDissolveGroup() +
      • ddNoCheck() +
      • ddSecDiffCheck() +
      • ddExtSymmCheck() +
      • ddVarGroupCheck() +
      • ddSetVarHandled() +
      • ddResetVarHandled() +
      • ddIsVarHandled() +
      • ddFixTree() +
      ] + + Author [Shipra Panda, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Constants for lazy sifting */ +#define DD_NORMAL_SIFT 0 +#define DD_LAZY_SIFT 1 + +/* Constants for sifting up and down */ +#define DD_SIFT_DOWN 0 +#define DD_SIFT_UP 1 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + typedef int (*DD_CHKFP)(DdManager *, int, int); +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddGroup.c,v 1.49 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static int *entry; +extern int ddTotalNumberSwapping; +#ifdef DD_STATS +extern int ddTotalNISwaps; +static int extsymmcalls; +static int extsymm; +static int secdiffcalls; +static int secdiff; +static int secdiffmisfire; +#endif +#ifdef DD_DEBUG +static int pr = 0; /* flag to enable printing while debugging */ + /* by depositing a 1 into it */ +#endif +static unsigned int originalSize; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +#ifdef DD_STATS +static int ddCountInternalMtrNodes (DdManager *table, MtrNode *treenode); +#endif +static int ddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +static void ddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper); +static int ddUniqueCompareGroup (int *ptrX, int *ptrY); +static int ddGroupSifting (DdManager *table, int lower, int upper, DD_CHKFP checkFunction, int lazyFlag); +static void ddCreateGroup (DdManager *table, int x, int y); +static int ddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh, DD_CHKFP checkFunction, int lazyFlag); +static int ddGroupSiftingUp (DdManager *table, int y, int xLow, DD_CHKFP checkFunction, Move **moves); +static int ddGroupSiftingDown (DdManager *table, int x, int xHigh, DD_CHKFP checkFunction, Move **moves); +static int ddGroupMove (DdManager *table, int x, int y, Move **moves); +static int ddGroupMoveBackward (DdManager *table, int x, int y); +static int ddGroupSiftingBackward (DdManager *table, Move *moves, int size, int upFlag, int lazyFlag); +static void ddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high); +static void ddDissolveGroup (DdManager *table, int x, int y); +static int ddNoCheck (DdManager *table, int x, int y); +static int ddSecDiffCheck (DdManager *table, int x, int y); +static int ddExtSymmCheck (DdManager *table, int x, int y); +static int ddVarGroupCheck (DdManager * table, int x, int y); +static int ddSetVarHandled (DdManager *dd, int index); +static int ddResetVarHandled (DdManager *dd, int index); +static int ddIsVarHandled (DdManager *dd, int index); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Creates a new variable group.] + + Description [Creates a new variable group. The group starts at + variable low and contains size variables. The parameter low is the index + of the first variable. If the variable already exists, its current + position in the order is known to the manager. If the variable does + not exist yet, the position is assumed to be the same as the index. + The group tree is created if it does not exist yet. + Returns a pointer to the group if successful; NULL otherwise.] + + SideEffects [The variable tree is changed.] + + SeeAlso [Cudd_MakeZddTreeNode] + +******************************************************************************/ +MtrNode * +Cudd_MakeTreeNode( + DdManager * dd /* manager */, + unsigned int low /* index of the first group variable */, + unsigned int size /* number of variables in the group */, + unsigned int type /* MTR_DEFAULT or MTR_FIXED */) +{ + MtrNode *group; + MtrNode *tree; + unsigned int level; + + /* If the variable does not exist yet, the position is assumed to be + ** the same as the index. Therefore, applications that rely on + ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new + ** variables have to create the variables before they group them. + */ + level = (low < (unsigned int) dd->size) ? dd->perm[low] : low; + + if (level + size - 1> (int) MTR_MAXHIGH) + return(NULL); + + /* If the tree does not exist yet, create it. */ + tree = dd->tree; + if (tree == NULL) { + dd->tree = tree = Mtr_InitGroupTree(0, dd->size); + if (tree == NULL) + return(NULL); + tree->index = dd->size == 0 ? 0 : dd->invperm[0]; + } + + /* Extend the upper bound of the tree if necessary. This allows the + ** application to create groups even before the variables are created. + */ + tree->size = ddMax(tree->size, ddMax(level + size, (unsigned) dd->size)); + + /* Create the group. */ + group = Mtr_MakeGroup(tree, level, size, type); + if (group == NULL) + return(NULL); + + /* Initialize the index field to the index of the variable currently + ** in position low. This field will be updated by the reordering + ** procedure to provide a handle to the group once it has been moved. + */ + group->index = (MtrHalfWord) low; + + return(group); + +} /* end of Cudd_MakeTreeNode */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Tree sifting algorithm.] + + Description [Tree sifting algorithm. Assumes that a tree representing + a group hierarchy is passed as a parameter. It then reorders each + group in postorder fashion by calling ddTreeSiftingAux. Assumes that + no dead nodes are present. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddTreeSifting( + DdManager * table /* DD table */, + Cudd_ReorderingType method /* reordering method for the groups of leaves */) +{ + int i; + int nvars; + int result; + int tempTree; + + /* If no tree is provided we create a temporary one in which all + ** variables are in a single group. After reordering this tree is + ** destroyed. + */ + tempTree = table->tree == NULL; + if (tempTree) { + table->tree = Mtr_InitGroupTree(0,table->size); + table->tree->index = table->invperm[0]; + } + nvars = table->size; + +#ifdef DD_DEBUG + if (pr > 0 && !tempTree) (void) fprintf(table->out,"cuddTreeSifting:"); + Mtr_PrintGroups(table->tree,pr <= 0); +#endif + +#ifdef DD_STATS + extsymmcalls = 0; + extsymm = 0; + secdiffcalls = 0; + secdiff = 0; + secdiffmisfire = 0; + + (void) fprintf(table->out,"\n"); + if (!tempTree) + (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", + ddCountInternalMtrNodes(table,table->tree)); +#endif + + /* Initialize the group of each subtable to itself. Initially + ** there are no groups. Groups are created according to the tree + ** structure in postorder fashion. + */ + for (i = 0; i < nvars; i++) + table->subtables[i].next = i; + + + /* Reorder. */ + result = ddTreeSiftingAux(table, table->tree, method); + +#ifdef DD_STATS /* print stats */ + if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && + (table->groupcheck == CUDD_GROUP_CHECK7 || + table->groupcheck == CUDD_GROUP_CHECK5)) { + (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); + (void) fprintf(table->out,"extsymm = %d",extsymm); + } + if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && + table->groupcheck == CUDD_GROUP_CHECK7) { + (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); + (void) fprintf(table->out,"secdiff = %d\n",secdiff); + (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); + } +#endif + + if (tempTree) + Cudd_FreeTree(table); + else + Mtr_ReorderGroups(table->tree, table->perm); + + return(result); + +} /* end of cuddTreeSifting */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Visits the group tree and reorders each group.] + + Description [Recursively visits the group tree and reorders each + group in postorder fashion. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddTreeSiftingAux( + DdManager * table, + MtrNode * treenode, + Cudd_ReorderingType method) +{ + MtrNode *auxnode; + int res; + Cudd_AggregationType saveCheck; + +#ifdef DD_DEBUG + Mtr_PrintGroups(treenode,1); +#endif + + auxnode = treenode; + while (auxnode != NULL) { + if (auxnode->child != NULL) { + if (!ddTreeSiftingAux(table, auxnode->child, method)) + return(0); + saveCheck = table->groupcheck; + table->groupcheck = CUDD_NO_CHECK; + if (method != CUDD_REORDER_LAZY_SIFT) + res = ddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT); + else + res = ddReorderChildren(table, auxnode, CUDD_REORDER_LAZY_SIFT); + table->groupcheck = saveCheck; + + if (res == 0) + return(0); + } else if (auxnode->size > 1) { + if (!ddReorderChildren(table, auxnode, method)) + return(0); + } + auxnode = auxnode->younger; + } + + return(1); + +} /* end of ddTreeSiftingAux */ + + +#ifdef DD_STATS +/**Function******************************************************************** + + Synopsis [Counts the number of internal nodes of the group tree.] + + Description [Counts the number of internal nodes of the group tree. + Returns the count.] + + SideEffects [None] + +******************************************************************************/ +static int +ddCountInternalMtrNodes( + DdManager * table, + MtrNode * treenode) +{ + MtrNode *auxnode; + int count,nodeCount; + + + nodeCount = 0; + auxnode = treenode; + while (auxnode != NULL) { + if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { + nodeCount++; + count = ddCountInternalMtrNodes(table,auxnode->child); + nodeCount += count; + } + auxnode = auxnode->younger; + } + + return(nodeCount); + +} /* end of ddCountInternalMtrNodes */ +#endif + + +/**Function******************************************************************** + + Synopsis [Reorders the children of a group tree node according to + the options.] + + Description [Reorders the children of a group tree node according to + the options. After reordering puts all the variables in the group + and/or its descendents in a single group. This allows hierarchical + reordering. If the variables in the group do not exist yet, simply + does nothing. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddReorderChildren( + DdManager * table, + MtrNode * treenode, + Cudd_ReorderingType method) +{ + int lower; + int upper; + int result; + unsigned int initialSize; + + ddFindNodeHiLo(table,treenode,&lower,&upper); + /* If upper == -1 these variables do not exist yet. */ + if (upper == -1) + return(1); + + if (treenode->flags == MTR_FIXED) { + result = 1; + } else { +#ifdef DD_STATS + (void) fprintf(table->out," "); +#endif + switch (method) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + result = cuddSwapping(table,lower,upper,method); + break; + case CUDD_REORDER_SIFT: + result = cuddSifting(table,lower,upper); + break; + case CUDD_REORDER_SIFT_CONVERGE: + do { + initialSize = table->keys - table->isolated; + result = cuddSifting(table,lower,upper); + if (initialSize <= table->keys - table->isolated) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + case CUDD_REORDER_SYMM_SIFT: + result = cuddSymmSifting(table,lower,upper); + break; + case CUDD_REORDER_SYMM_SIFT_CONV: + result = cuddSymmSiftingConv(table,lower,upper); + break; + case CUDD_REORDER_GROUP_SIFT: + if (table->groupcheck == CUDD_NO_CHECK) { + result = ddGroupSifting(table,lower,upper,ddNoCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK5) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK7) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else { + (void) fprintf(table->err, + "Unknown group ckecking method\n"); + result = 0; + } + break; + case CUDD_REORDER_GROUP_SIFT_CONV: + do { + initialSize = table->keys - table->isolated; + if (table->groupcheck == CUDD_NO_CHECK) { + result = ddGroupSifting(table,lower,upper,ddNoCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK5) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK7) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else { + (void) fprintf(table->err, + "Unknown group ckecking method\n"); + result = 0; + } +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + result = cuddWindowReorder(table,lower,upper, + CUDD_REORDER_WINDOW4); + if (initialSize <= table->keys - table->isolated) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + case CUDD_REORDER_WINDOW2: + case CUDD_REORDER_WINDOW3: + case CUDD_REORDER_WINDOW4: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + result = cuddWindowReorder(table,lower,upper,method); + break; + case CUDD_REORDER_ANNEALING: + result = cuddAnnealing(table,lower,upper); + break; + case CUDD_REORDER_GENETIC: + result = cuddGa(table,lower,upper); + break; + case CUDD_REORDER_LINEAR: + result = cuddLinearAndSifting(table,lower,upper); + break; + case CUDD_REORDER_LINEAR_CONVERGE: + do { + initialSize = table->keys - table->isolated; + result = cuddLinearAndSifting(table,lower,upper); + if (initialSize <= table->keys - table->isolated) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + case CUDD_REORDER_EXACT: + result = cuddExact(table,lower,upper); + break; + case CUDD_REORDER_LAZY_SIFT: + result = ddGroupSifting(table,lower,upper,ddVarGroupCheck, + DD_LAZY_SIFT); + break; + default: + return(0); + } + } + + /* Create a single group for all the variables that were sifted, + ** so that they will be treated as a single block by successive + ** invocations of ddGroupSifting. + */ + ddMergeGroups(table,treenode,lower,upper); + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddReorderChildren:"); +#endif + + return(result); + +} /* end of ddReorderChildren */ + + +/**Function******************************************************************** + + Synopsis [Finds the lower and upper bounds of the group represented + by treenode.] + + Description [Finds the lower and upper bounds of the group + represented by treenode. From the index and size fields we need to + derive the current positions, and find maximum and minimum.] + + SideEffects [The bounds are returned as side effects.] + + SeeAlso [] + +******************************************************************************/ +static void +ddFindNodeHiLo( + DdManager * table, + MtrNode * treenode, + int * lower, + int * upper) +{ + int low; + int high; + + /* Check whether no variables in this group already exist. + ** If so, return immediately. The calling procedure will know from + ** the values of upper that no reordering is needed. + */ + if ((int) treenode->low >= table->size) { + *lower = table->size; + *upper = -1; + return; + } + + *lower = low = (unsigned int) table->perm[treenode->index]; + high = (int) (low + treenode->size - 1); + + if (high >= table->size) { + /* This is the case of a partially existing group. The aim is to + ** reorder as many variables as safely possible. If the tree + ** node is terminal, we just reorder the subset of the group + ** that is currently in existence. If the group has + ** subgroups, then we only reorder those subgroups that are + ** fully instantiated. This way we avoid breaking up a group. + */ + MtrNode *auxnode = treenode->child; + if (auxnode == NULL) { + *upper = (unsigned int) table->size - 1; + } else { + /* Search the subgroup that strands the table->size line. + ** If the first group starts at 0 and goes past table->size + ** upper will get -1, thus correctly signaling that no reordering + ** should take place. + */ + while (auxnode != NULL) { + int thisLower = table->perm[auxnode->low]; + int thisUpper = thisLower + auxnode->size - 1; + if (thisUpper >= table->size && thisLower < table->size) + *upper = (unsigned int) thisLower - 1; + auxnode = auxnode->younger; + } + } + } else { + /* Normal case: All the variables of the group exist. */ + *upper = (unsigned int) high; + } + +#ifdef DD_DEBUG + /* Make sure that all variables in group are contiguous. */ + assert(treenode->size >= *upper - *lower + 1); +#endif + + return; + +} /* end of ddFindNodeHiLo */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the variables + according to the number of keys in the subtables. Returns the + difference in number of keys between the two variables being + compared.] + + SideEffects [None] + +******************************************************************************/ +static int +ddUniqueCompareGroup( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of ddUniqueCompareGroup */ + + +/**Function******************************************************************** + + Synopsis [Sifts from treenode->low to treenode->high.] + + Description [Sifts from treenode->low to treenode->high. If + croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the + end of the initial sifting. If a group is created, it is then sifted + again. After sifting one variable, the group that contains it is + dissolved. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSifting( + DdManager * table, + int lower, + int upper, + DD_CHKFP checkFunction, + int lazyFlag) +{ + int *var; + int i,j,x,xInit; + int nvars; + int classes; + int result; + int *sifted; + int merged; + int dissolve; +#ifdef DD_STATS + unsigned previousSize; +#endif + int xindex; + + nvars = table->size; + + /* Order variables to sift. */ + entry = NULL; + sifted = NULL; + var = ALLOC(int,nvars); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; + } + entry = ALLOC(int,nvars); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; + } + sifted = ALLOC(int,nvars); + if (sifted == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; + } + + /* Here we consider only one representative for each group. */ + for (i = 0, classes = 0; i < nvars; i++) { + sifted[i] = 0; + x = table->perm[i]; + if ((unsigned) x >= table->subtables[x].next) { + entry[i] = table->subtables[x].keys; + var[classes] = i; + classes++; + } + } + + qsort((void *)var,classes,sizeof(int), + (DD_QSFP) ddUniqueCompareGroup); + + if (lazyFlag) { + for (i = 0; i < nvars; i ++) { + ddResetVarHandled(table, i); + } + } + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime + table->reordTime + > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + xindex = var[i]; + if (sifted[xindex] == 1) /* variable already sifted as part of group */ + continue; + x = table->perm[xindex]; /* find current level of this variable */ + + if (x < lower || x > upper || table->subtables[x].bindVar == 1) + continue; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif +#ifdef DD_DEBUG + /* x is bottom of group */ + assert((unsigned) x >= table->subtables[x].next); +#endif + if ((unsigned) x == table->subtables[x].next) { + dissolve = 1; + result = ddGroupSiftingAux(table,x,lower,upper,checkFunction, + lazyFlag); + } else { + dissolve = 0; + result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); + } + if (!result) goto ddGroupSiftingOutOfMem; + + /* check for aggregation */ + merged = 0; + if (lazyFlag == 0 && table->groupcheck == CUDD_GROUP_CHECK7) { + x = table->perm[xindex]; /* find current level */ + if ((unsigned) x == table->subtables[x].next) { /* not part of a group */ + if (x != upper && sifted[table->invperm[x+1]] == 0 && + (unsigned) x+1 == table->subtables[x+1].next) { + if (ddSecDiffCheck(table,x,x+1)) { + merged =1; + ddCreateGroup(table,x,x+1); + } + } + if (x != lower && sifted[table->invperm[x-1]] == 0 && + (unsigned) x-1 == table->subtables[x-1].next) { + if (ddSecDiffCheck(table,x-1,x)) { + merged =1; + ddCreateGroup(table,x-1,x); + } + } + } + } + + if (merged) { /* a group was created */ + /* move x to bottom of group */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + /* sift */ + result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); + if (!result) goto ddGroupSiftingOutOfMem; +#ifdef DD_STATS + if (table->keys < previousSize + table->isolated) { + (void) fprintf(table->out,"_"); + } else if (table->keys > previousSize + table->isolated) { + (void) fprintf(table->out,"^"); + } else { + (void) fprintf(table->out,"*"); + } + fflush(table->out); + } else { + if (table->keys < previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > previousSize + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + /* Mark variables in the group just sifted. */ + x = table->perm[xindex]; + if ((unsigned) x != table->subtables[x].next) { + xInit = x; + do { + j = table->invperm[x]; + sifted[j] = 1; + x = table->subtables[x].next; + } while (x != xInit); + + /* Dissolve the group if it was created. */ + if (lazyFlag == 0 && dissolve) { + do { + j = table->subtables[x].next; + table->subtables[x].next = x; + x = j; + } while (x != xInit); + } + } + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddGroupSifting:"); +#endif + + if (lazyFlag) ddSetVarHandled(table, xindex); + } /* for */ + + FREE(sifted); + FREE(var); + FREE(entry); + + return(1); + +ddGroupSiftingOutOfMem: + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + if (sifted != NULL) FREE(sifted); + + return(0); + +} /* end of ddGroupSifting */ + + +/**Function******************************************************************** + + Synopsis [Creates a group encompassing variables from x to y in the + DD table.] + + Description [Creates a group encompassing variables from x to y in the + DD table. In the current implementation it must be y == x+1. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static void +ddCreateGroup( + DdManager * table, + int x, + int y) +{ + int gybot; + +#ifdef DD_DEBUG + assert(y == x+1); +#endif + + /* Find bottom of second group. */ + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + + /* Link groups. */ + table->subtables[x].next = y; + table->subtables[gybot].next = x; + + return; + +} /* ddCreateGroup */ + + +/**Function******************************************************************** + + Synopsis [Sifts one variable up and down until it has taken all + positions. Checks for aggregation.] + + Description [Sifts one variable up and down until it has taken all + positions. Checks for aggregation. There may be at most two sweeps, + even if the group grows. Assumes that x is either an isolated + variable, or it is the bottom of a group. All groups may not have + been found. The variable being moved is returned to the best position + seen during sifting. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh, + DD_CHKFP checkFunction, + int lazyFlag) +{ + Move *move; + Move *moves; /* list of moves */ + int initialSize; + int result; + int y; + int topbot; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out, + "ddGroupSiftingAux from %d to %d\n",xLow,xHigh); + assert((unsigned) x >= table->subtables[x].next); /* x is bottom of group */ +#endif + + initialSize = table->keys - table->isolated; + moves = NULL; + + originalSize = initialSize; /* for lazy sifting */ + + /* If we have a singleton, we check for aggregation in both + ** directions before we sift. + */ + if ((unsigned) x == table->subtables[x].next) { + /* Will go down first, unless x == xHigh: + ** Look for aggregation above x. + */ + for (y = x; y > xLow; y--) { + if (!checkFunction(table,y-1,y)) + break; + topbot = table->subtables[y-1].next; /* find top of y-1's group */ + table->subtables[y-1].next = y; + table->subtables[x].next = topbot; /* x is bottom of group so its */ + /* next is top of y-1's group */ + y = topbot + 1; /* add 1 for y--; new y is top of group */ + } + /* Will go up first unless x == xlow: + ** Look for aggregation below x. + */ + for (y = x; y < xHigh; y++) { + if (!checkFunction(table,y,y+1)) + break; + /* find bottom of y+1's group */ + topbot = y + 1; + while ((unsigned) topbot < table->subtables[topbot].next) { + topbot = table->subtables[topbot].next; + } + table->subtables[topbot].next = table->subtables[y].next; + table->subtables[y].next = y + 1; + y = topbot - 1; /* subtract 1 for y++; new y is bottom of group */ + } + } + + /* Now x may be in the middle of a group. + ** Find bottom of x's group. + */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + + if (x == xLow) { /* Sift down */ +#ifdef DD_DEBUG + /* x must be a singleton */ + assert((unsigned) x == table->subtables[x].next); +#endif + if (x == xHigh) return(1); /* just one variable */ + + if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_DOWN,lazyFlag); +#ifdef DD_DEBUG + assert(table->keys - table->isolated <= (unsigned) initialSize); +#endif + if (!result) goto ddGroupSiftingAuxOutOfMem; + + } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ +#ifdef DD_DEBUG + /* x is bottom of group */ + assert((unsigned) x >= table->subtables[x].next); +#endif + /* Find top of x's group */ + x = table->subtables[x].next; + + if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + /* at this point x == xLow, unless early term */ + + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_UP,lazyFlag); +#ifdef DD_DEBUG + assert(table->keys - table->isolated <= (unsigned) initialSize); +#endif + if (!result) goto ddGroupSiftingAuxOutOfMem; + + } else if (x - xLow > xHigh - x) { /* must go down first: shorter */ + if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + /* Find top of group */ + if (moves) { + x = moves->y; + } + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + x = table->subtables[x].next; +#ifdef DD_DEBUG + /* x should be the top of a group */ + assert((unsigned) x <= table->subtables[x].next); +#endif + + if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_UP,lazyFlag); +#ifdef DD_DEBUG + assert(table->keys - table->isolated <= (unsigned) initialSize); +#endif + if (!result) goto ddGroupSiftingAuxOutOfMem; + + } else { /* moving up first: shorter */ + /* Find top of x's group */ + x = table->subtables[x].next; + + if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + if (moves) { + x = moves->x; + } + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; +#ifdef DD_DEBUG + /* x is bottom of a group */ + assert((unsigned) x >= table->subtables[x].next); +#endif + + if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_DOWN,lazyFlag); +#ifdef DD_DEBUG + assert(table->keys - table->isolated <= (unsigned) initialSize); +#endif + if (!result) goto ddGroupSiftingAuxOutOfMem; + } + + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(1); + +ddGroupSiftingAuxOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(0); + +} /* end of ddGroupSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much.] + + Description [Sifts up a variable until either it reaches position + xLow or the size of the DD heap increases too much. Assumes that y is + the top of a group (or a singleton). Checks y for aggregation to the + adjacent variables. Records all the moves that are appended to the + list of moves received as input and returned as a side effect. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSiftingUp( + DdManager * table, + int y, + int xLow, + DD_CHKFP checkFunction, + Move ** moves) +{ + Move *move; + int x; + int size; + int i; + int gxtop,gybot; + int limitSize; + int xindex, yindex; + int zindex; + int z; + int isolated; + int L; /* lower bound on DD size */ +#ifdef DD_DEBUG + int checkL; +#endif + + yindex = table->invperm[y]; + + /* Initialize the lower bound. + ** The part of the DD below the bottom of y's group will not change. + ** The part of the DD above y that does not interact with any + ** variable of y's group will not change. + ** The rest may vanish in the best case, except for + ** the nodes at level xLow, which will not vanish, regardless. + ** What we use here is not really a lower bound, because we ignore + ** the interactions with all variables except y. + */ + limitSize = L = table->keys - table->isolated; + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L -= table->subtables[z].keys - isolated; + } + } + + x = cuddNextLow(table,y); + while (x >= xLow && L <= limitSize) { +#ifdef DD_DEBUG + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + if (pr > 0 && L != checkL) { + (void) fprintf(table->out, + "Inaccurate lower bound: L = %d checkL = %d\n", + L, checkL); + } +#endif + gxtop = table->subtables[x].next; + if (checkFunction(table,x,y)) { + /* Group found, attach groups */ + table->subtables[x].next = y; + i = table->subtables[y].next; + while (table->subtables[i].next != (unsigned) y) + i = table->subtables[i].next; + table->subtables[i].next = gxtop; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_NEWNODE; + move->size = table->keys - table->isolated; + move->next = *moves; + *moves = move; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y are self groups */ + xindex = table->invperm[x]; + size = cuddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); +#endif + if (size == 0) goto ddGroupSiftingUpOutOfMem; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_DEFAULT; + move->size = size; + move->next = *moves; + *moves = move; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out, + "ddGroupSiftingUp (2 single groups):\n"); +#endif + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } else { /* Group move */ + size = ddGroupMove(table,x,y,moves); + if (size == 0) goto ddGroupSiftingUpOutOfMem; + /* Update the lower bound. */ + z = (*moves)->y; + do { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L += table->subtables[z].keys - isolated; + } + z = table->subtables[z].next; + } while (z != (int) (*moves)->y); + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } + y = gxtop; + x = cuddNextLow(table,y); + } + + return(1); + +ddGroupSiftingUpOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of ddGroupSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts down a variable until it reaches position xHigh.] + + Description [Sifts down a variable until it reaches position xHigh. + Assumes that x is the bottom of a group (or a singleton). Records + all the moves. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSiftingDown( + DdManager * table, + int x, + int xHigh, + DD_CHKFP checkFunction, + Move ** moves) +{ + Move *move; + int y; + int size; + int limitSize; + int gxtop,gybot; + int R; /* upper bound on node decrease */ + int xindex, yindex; + int isolated, allVars; + int z; + int zindex; +#ifdef DD_DEBUG + int checkR; +#endif + + /* If the group consists of simple variables, there is no point in + ** sifting it down. This check is redundant if the projection functions + ** do not have external references, because the computation of the + ** lower bound takes care of the problem. It is necessary otherwise to + ** prevent the sifting down of simple variables. */ + y = x; + allVars = 1; + do { + if (table->subtables[y].keys != 1) { + allVars = 0; + break; + } + y = table->subtables[y].next; + } while (table->subtables[y].next != (unsigned) x); + if (allVars) + return(1); + + /* Initialize R. */ + xindex = table->invperm[x]; + gxtop = table->subtables[x].next; + limitSize = size = table->keys - table->isolated; + R = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } + + y = cuddNextHigh(table,x); + while (y <= xHigh && size - R < limitSize) { +#ifdef DD_DEBUG + gxtop = table->subtables[x].next; + checkR = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + assert(R >= checkR); +#endif + /* Find bottom of y group. */ + gybot = table->subtables[y].next; + while (table->subtables[gybot].next != (unsigned) y) + gybot = table->subtables[gybot].next; + + if (checkFunction(table,x,y)) { + /* Group found: attach groups and record move. */ + gxtop = table->subtables[x].next; + table->subtables[x].next = y; + table->subtables[gybot].next = gxtop; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_NEWNODE; + move->size = table->keys - table->isolated; + move->next = *moves; + *moves = move; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y are self groups */ + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); +#endif + if (size == 0) goto ddGroupSiftingDownOutOfMem; + + /* Record move. */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_DEFAULT; + move->size = size; + move->next = *moves; + *moves = move; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out, + "ddGroupSiftingDown (2 single groups):\n"); +#endif + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + + x = y; + y = cuddNextHigh(table,x); + } else { /* Group move */ + /* Update upper bound on node decrease: first phase. */ + gxtop = table->subtables[x].next; + z = gxtop + 1; + do { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R -= table->subtables[z].keys - isolated; + } + z++; + } while (z <= gybot); + size = ddGroupMove(table,x,y,moves); + if (size == 0) goto ddGroupSiftingDownOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + + /* Update upper bound on node decrease: second phase. */ + gxtop = table->subtables[gybot].next; + for (z = gxtop + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } + } + x = gybot; + y = cuddNextHigh(table,x); + } + + return(1); + +ddGroupSiftingDownOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + + return(0); + +} /* end of ddGroupSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Swaps two groups and records the move.] + + Description [Swaps two groups and records the move. Returns the + number of keys in the DD table in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupMove( + DdManager * table, + int x, + int y, + Move ** moves) +{ + Move *move; + int size; + int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + int swapx,swapy; +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + int initialSize,bestSize; +#endif + +#ifdef DD_DEBUG + /* We assume that x < y */ + assert(x < y); +#endif + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtables[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtables[ybot].next) + ybot = table->subtables[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + initialSize = bestSize = table->keys - table->isolated; +#endif + /* Sift the variables of the second group up through the first group */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddGroupMoveOutOfMem; +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (size < bestSize) + bestSize = size; +#endif + swapx = x; swapy = y; + y = x; + x = cuddNextLow(table,y); + } + y = ytop + i; + x = cuddNextLow(table,y); + } +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if ((bestSize < initialSize) && (bestSize < size)) + (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); +#endif + + /* fix groups */ + y = xtop; /* ytop is now where xtop used to be */ + for (i = 0; i < ysize - 1; i++) { + table->subtables[y].next = cuddNextHigh(table,y); + y = cuddNextHigh(table,y); + } + table->subtables[y].next = xtop; /* y is bottom of its group, join */ + /* it to top of its group */ + x = cuddNextHigh(table,y); + newxtop = x; + for (i = 0; i < xsize - 1; i++) { + table->subtables[x].next = cuddNextHigh(table,x); + x = cuddNextHigh(table,x); + } + table->subtables[x].next = newxtop; /* x is bottom of its group, join */ + /* it to top of its group */ +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddGroupMove:\n"); +#endif + + /* Store group move */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupMoveOutOfMem; + move->x = swapx; + move->y = swapy; + move->flags = MTR_DEFAULT; + move->size = table->keys - table->isolated; + move->next = *moves; + *moves = move; + + return(table->keys - table->isolated); + +ddGroupMoveOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of ddGroupMove */ + + +/**Function******************************************************************** + + Synopsis [Undoes the swap two groups.] + + Description [Undoes the swap two groups. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupMoveBackward( + DdManager * table, + int x, + int y) +{ + int size; + int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + + +#ifdef DD_DEBUG + /* We assume that x < y */ + assert(x < y); +#endif + + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtables[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtables[ybot].next) + ybot = table->subtables[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + + /* Sift the variables of the second group up through the first group */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) + return(0); + y = x; + x = cuddNextLow(table,y); + } + y = ytop + i; + x = cuddNextLow(table,y); + } + + /* fix groups */ + y = xtop; + for (i = 0; i < ysize - 1; i++) { + table->subtables[y].next = cuddNextHigh(table,y); + y = cuddNextHigh(table,y); + } + table->subtables[y].next = xtop; /* y is bottom of its group, join */ + /* to its top */ + x = cuddNextHigh(table,y); + newxtop = x; + for (i = 0; i < xsize - 1; i++) { + table->subtables[x].next = cuddNextHigh(table,x); + x = cuddNextHigh(table,x); + } + table->subtables[x].next = newxtop; /* x is bottom of its group, join */ + /* to its top */ +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddGroupMoveBackward:\n"); +#endif + + return(1); + +} /* end of ddGroupMoveBackward */ + + +/**Function******************************************************************** + + Synopsis [Determines the best position for a variables and returns + it there.] + + Description [Determines the best position for a variables and returns + it there. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSiftingBackward( + DdManager * table, + Move * moves, + int size, + int upFlag, + int lazyFlag) +{ + Move *move; + int res; + Move *end_move; + int diff, tmp_diff; + int index; + unsigned int pairlev; + + if (lazyFlag) { + end_move = NULL; + + /* Find the minimum size, and the earliest position at which it + ** was achieved. */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + end_move = move; + } else if (move->size == size) { + if (end_move == NULL) end_move = move; + } + } + + /* Find among the moves that give minimum size the one that + ** minimizes the distance from the corresponding variable. */ + if (moves != NULL) { + diff = Cudd_ReadSize(table) + 1; + index = (upFlag == 1) ? + table->invperm[moves->x] : table->invperm[moves->y]; + pairlev = + (unsigned) table->perm[Cudd_bddReadPairIndex(table, index)]; + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) { + if (upFlag == 1) { + tmp_diff = (move->x > pairlev) ? + move->x - pairlev : pairlev - move->x; + } else { + tmp_diff = (move->y > pairlev) ? + move->y - pairlev : pairlev - move->y; + } + if (tmp_diff < diff) { + diff = tmp_diff; + end_move = move; + } + } + } + } + } else { + /* Find the minimum size. */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + } + + /* In case of lazy sifting, end_move identifies the position at + ** which we want to stop. Otherwise, we stop as soon as we meet + ** the minimum size. */ + for (move = moves; move != NULL; move = move->next) { + if (lazyFlag) { + if (move == end_move) return(1); + } else { + if (move->size == size) return(1); + } + if ((table->subtables[move->x].next == move->x) && + (table->subtables[move->y].next == move->y)) { + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddGroupSiftingBackward:\n"); + assert(table->subtables[move->x].next == move->x); + assert(table->subtables[move->y].next == move->y); +#endif + } else { /* Group move necessary */ + if (move->flags == MTR_NEWNODE) { + ddDissolveGroup(table,(int)move->x,(int)move->y); + } else { + res = ddGroupMoveBackward(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + } + + } + + return(1); + +} /* end of ddGroupSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Merges groups in the DD table.] + + Description [Creates a single group from low to high and adjusts the + index field of the tree node.] + + SideEffects [None] + +******************************************************************************/ +static void +ddMergeGroups( + DdManager * table, + MtrNode * treenode, + int low, + int high) +{ + int i; + MtrNode *auxnode; + int saveindex; + int newindex; + + /* Merge all variables from low to high in one group, unless + ** this is the topmost group. In such a case we do not merge lest + ** we lose the symmetry information. */ + if (treenode != table->tree) { + for (i = low; i < high; i++) + table->subtables[i].next = i+1; + table->subtables[high].next = low; + } + + /* Adjust the index fields of the tree nodes. If a node is the + ** first child of its parent, then the parent may also need adjustment. */ + saveindex = treenode->index; + newindex = table->invperm[low]; + auxnode = treenode; + do { + auxnode->index = newindex; + if (auxnode->parent == NULL || + (int) auxnode->parent->index != saveindex) + break; + auxnode = auxnode->parent; + } while (1); + return; + +} /* end of ddMergeGroups */ + + +/**Function******************************************************************** + + Synopsis [Dissolves a group in the DD table.] + + Description [x and y are variables in a group to be cut in two. The cut + is to pass between x and y.] + + SideEffects [None] + +******************************************************************************/ +static void +ddDissolveGroup( + DdManager * table, + int x, + int y) +{ + int topx; + int boty; + + /* find top and bottom of the two groups */ + boty = y; + while ((unsigned) boty < table->subtables[boty].next) + boty = table->subtables[boty].next; + + topx = table->subtables[boty].next; + + table->subtables[boty].next = y; + table->subtables[x].next = topx; + + return; + +} /* end of ddDissolveGroup */ + + +/**Function******************************************************************** + + Synopsis [Pretends to check two variables for aggregation.] + + Description [Pretends to check two variables for aggregation. Always + returns 0.] + + SideEffects [None] + +******************************************************************************/ +static int +ddNoCheck( + DdManager * table, + int x, + int y) +{ + return(0); + +} /* end of ddNoCheck */ + + +/**Function******************************************************************** + + Synopsis [Checks two variables for aggregation.] + + Description [Checks two variables for aggregation. The check is based + on the second difference of the number of nodes as a function of the + layer. If the second difference is lower than a given threshold + (typically negative) then the two variables should be aggregated. + Returns 1 if the two variables pass the test; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSecDiffCheck( + DdManager * table, + int x, + int y) +{ + double Nx,Nx_1; + double Sx; + double threshold; + int xindex,yindex; + + if (x==0) return(0); + +#ifdef DD_STATS + secdiffcalls++; +#endif + Nx = (double) table->subtables[x].keys; + Nx_1 = (double) table->subtables[x-1].keys; + Sx = (table->subtables[y].keys/Nx) - (Nx/Nx_1); + + threshold = table->recomb / 100.0; + if (Sx < threshold) { + xindex = table->invperm[x]; + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + (void) fprintf(table->out, + "Second difference for %d = %g Pos(%d)\n", + table->invperm[x],Sx,x); +#endif +#ifdef DD_STATS + secdiff++; +#endif + return(1); + } else { +#ifdef DD_STATS + secdiffmisfire++; +#endif + return(0); + } + + } + return(0); + +} /* end of ddSecDiffCheck */ + + +/**Function******************************************************************** + + Synopsis [Checks for extended symmetry of x and y.] + + Description [Checks for extended symmetry of x and y. Returns 1 in + case of extended symmetry; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddExtSymmCheck( + DdManager * table, + int x, + int y) +{ + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10; + DdNode *one; + unsigned comple; /* f0 is complemented */ + int notproj; /* f is not a projection function */ + int arccount; /* number of arcs from layer x to layer y */ + int TotalRefCount; /* total reference count of layer y minus 1 */ + int counter; /* number of nodes of layer x that are allowed */ + /* to violate extended symmetry conditions */ + int arccounter; /* number of arcs into layer y that are allowed */ + /* to come from layers other than x */ + int i; + int xindex; + int yindex; + int res; + int slots; + DdNodePtr *list; + DdNode *sentinel = &(table->sentinel); + + xindex = table->invperm[x]; + yindex = table->invperm[y]; + + /* If the two variables do not interact, we do not want to merge them. */ + if (!cuddTestInteract(table,xindex,yindex)) + return(0); + +#ifdef DD_DEBUG + /* Checks that x and y do not contain just the projection functions. + ** With the test on interaction, these test become redundant, + ** because an isolated projection function does not interact with + ** any other variable. + */ + if (table->subtables[x].keys == 1) { + assert(table->vars[xindex]->ref != 1); + } + if (table->subtables[y].keys == 1) { + assert(table->vars[yindex]->ref != 1); + } +#endif + +#ifdef DD_STATS + extsymmcalls++; +#endif + + arccount = 0; + counter = (int) (table->subtables[x].keys * + (table->symmviolation/100.0) + 0.5); + one = DD_ONE(table); + + slots = table->subtables[x].slots; + list = table->subtables[x].nodelist; + for (i = 0; i < slots; i++) { + f = list[i]; + while (f != sentinel) { + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + f0 = Cudd_Regular(cuddE(f)); + comple = Cudd_IsComplement(cuddE(f)); + notproj = f1 != one || f0 != one || f->ref != (DdHalfWord) 1; + if (f1->index == (unsigned) yindex) { + arccount++; + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + if ((int) f0->index != yindex) { + /* If f is an isolated projection function it is + ** allowed to bypass layer y. + */ + if (notproj) { + if (counter == 0) + return(0); + counter--; /* f bypasses layer y */ + } + } + f11 = f10 = f1; + } + if ((int) f0->index == yindex) { + arccount++; + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + + /* Unless we are looking at a projection function + ** without external references except the one from the + ** table, we insist that f01 == f10 or f11 == f00 + */ + if (notproj) { + if (f01 != f10 && f11 != f00) { + if (counter == 0) + return(0); + counter--; + } + } + + f = f->next; + } /* while */ + } /* for */ + + /* Calculate the total reference counts of y */ + TotalRefCount = -1; /* -1 for projection function */ + slots = table->subtables[y].slots; + list = table->subtables[y].nodelist; + for (i = 0; i < slots; i++) { + f = list[i]; + while (f != sentinel) { + TotalRefCount += f->ref; + f = f->next; + } + } + + arccounter = (int) (table->subtables[y].keys * + (table->arcviolation/100.0) + 0.5); + res = arccount >= TotalRefCount - arccounter; + +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (res) { + (void) fprintf(table->out, + "Found extended symmetry! x = %d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); + } +#endif + +#ifdef DD_STATS + if (res) + extsymm++; +#endif + return(res); + +} /* end ddExtSymmCheck */ + + +/**Function******************************************************************** + + Synopsis [Checks for grouping of x and y.] + + Description [Checks for grouping of x and y. Returns 1 in + case of grouping; 0 otherwise. This function is used for lazy sifting.] + + SideEffects [None] + +******************************************************************************/ +static int +ddVarGroupCheck( + DdManager * table, + int x, + int y) +{ + int xindex = table->invperm[x]; + int yindex = table->invperm[y]; + + if (Cudd_bddIsVarToBeUngrouped(table, xindex)) return(0); + + if (Cudd_bddReadPairIndex(table, xindex) == yindex) { + if (ddIsVarHandled(table, xindex) || + ddIsVarHandled(table, yindex)) { + if (Cudd_bddIsVarToBeGrouped(table, xindex) || + Cudd_bddIsVarToBeGrouped(table, yindex) ) { + if (table->keys - table->isolated <= originalSize) { + return(1); + } + } + } + } + + return(0); + +} /* end of ddVarGroupCheck */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable to already handled.] + + Description [Sets a variable to already handled. This function is used + for lazy sifting.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static int +ddSetVarHandled( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].varHandled = 1; + return(1); + +} /* end of ddSetVarHandled */ + + +/**Function******************************************************************** + + Synopsis [Resets a variable to be processed.] + + Description [Resets a variable to be processed. This function is used + for lazy sifting.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static int +ddResetVarHandled( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].varHandled = 0; + return(1); + +} /* end of ddResetVarHandled */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variables is already handled.] + + Description [Checks whether a variables is already handled. This + function is used for lazy sifting.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static int +ddIsVarHandled( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(-1); + return dd->subtables[dd->perm[index]].varHandled; + +} /* end of ddIsVarHandled */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddHarwell.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddHarwell.c new file mode 100644 index 000000000..323db91d3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddHarwell.c @@ -0,0 +1,568 @@ +/**CFile*********************************************************************** + + FileName [cuddHarwell.c] + + PackageName [cudd] + + Synopsis [Function to read a matrix in Harwell format.] + + Description [External procedures included in this module: +
        +
      • Cudd_addHarwell() +
      + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddHarwell.c,v 1.10 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads in a matrix in the format of the Harwell-Boeing + benchmark suite.] + + Description [Reads in a matrix in the format of the Harwell-Boeing + benchmark suite. The variables are ordered as follows: +
      + x\[0\] y\[0\] x\[1\] y\[1\] ... +
      + 0 is the most significant bit. On input, nx and ny hold the numbers + of row and column variables already in existence. On output, they + hold the numbers of row and column variables actually used by the + matrix. m and n are set to the numbers of rows and columns of the + matrix. Their values on input are immaterial. Returns 1 on + success; 0 otherwise. The ADD for the sparse matrix is returned in + E, and its reference count is > 0.] + + SideEffects [None] + + SeeAlso [Cudd_addRead Cudd_bddRead] + +******************************************************************************/ +int +Cudd_addHarwell( + FILE * fp /* pointer to the input file */, + DdManager * dd /* DD manager */, + DdNode ** E /* characteristic function of the graph */, + DdNode *** x /* array of row variables */, + DdNode *** y /* array of column variables */, + DdNode *** xn /* array of complemented row variables */, + DdNode *** yn_ /* array of complemented column variables */, + int * nx /* number or row variables */, + int * ny /* number or column variables */, + int * m /* number of rows */, + int * n /* number of columns */, + int bx /* first index of row variables */, + int sx /* step of row variables */, + int by /* first index of column variables */, + int sy /* step of column variables */, + int pr /* verbosity level */) +{ + DdNode *one, *zero; + DdNode *w; + DdNode *cubex, *cubey, *minterm1; + int u, v, err, i, j, nv; + double val; + DdNode **lx, **ly, **lxn, **lyn; /* local copies of x, y, xn, yn_ */ + int lnx, lny; /* local copies of nx and ny */ + char title[73], key[9], mxtype[4], rhstyp[4]; + int totcrd, ptrcrd, indcrd, valcrd, rhscrd, + nrow, ncol, nnzero, neltvl, + nrhs, nrhsix; + int *colptr, *rowind; +#if 0 + int nguess, nexact; + int *rhsptr, *rhsind; +#endif + + if (*nx < 0 || *ny < 0) return(0); + + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + /* Read the header */ + err = fscanf(fp, "%72c %8c", title, key); + if (err == EOF) { + return(0); + } else if (err != 2) { + return(0); + } + title[72] = (char) 0; + key[8] = (char) 0; + + err = fscanf(fp, "%d %d %d %d %d", &totcrd, &ptrcrd, &indcrd, + &valcrd, &rhscrd); + if (err == EOF) { + return(0); + } else if (err != 5) { + return(0); + } + + err = fscanf(fp, "%3s %d %d %d %d", mxtype, &nrow, &ncol, + &nnzero, &neltvl); + if (err == EOF) { + return(0); + } else if (err != 5) { + return(0); + } + + /* Skip FORTRAN formats */ + if (rhscrd == 0) { + err = fscanf(fp, "%*s %*s %*s \n"); + } else { + err = fscanf(fp, "%*s %*s %*s %*s \n"); + } + if (err == EOF) { + return(0); + } else if (err != 0) { + return(0); + } + + /* Print out some stuff if requested to be verbose */ + if (pr>0) { + (void) fprintf(dd->out,"%s: type %s, %d rows, %d columns, %d entries\n", key, + mxtype, nrow, ncol, nnzero); + if (pr>1) (void) fprintf(dd->out,"%s\n", title); + } + + /* Check matrix type */ + if (mxtype[0] != 'R' || mxtype[1] != 'U' || mxtype[2] != 'A') { + (void) fprintf(dd->err,"%s: Illegal matrix type: %s\n", + key, mxtype); + return(0); + } + if (neltvl != 0) return(0); + + /* Read optional 5-th line */ + if (rhscrd != 0) { + err = fscanf(fp, "%3c %d %d", rhstyp, &nrhs, &nrhsix); + if (err == EOF) { + return(0); + } else if (err != 3) { + return(0); + } + rhstyp[3] = (char) 0; + if (rhstyp[0] != 'F') { + (void) fprintf(dd->err, + "%s: Sparse right-hand side not yet supported\n", key); + return(0); + } + if (pr>0) (void) fprintf(dd->out,"%d right-hand side(s)\n", nrhs); + } else { + nrhs = 0; + } + + /* Compute the number of variables */ + + /* row and column numbers start from 0 */ + u = nrow - 1; + for (i=0; u > 0; i++) { + u >>= 1; + } + lnx = i; + if (nrhs == 0) { + v = ncol - 1; + } else { + v = 2* (ddMax(ncol, nrhs) - 1); + } + for (i=0; v > 0; i++) { + v >>= 1; + } + lny = i; + + /* Allocate or reallocate arrays for variables as needed */ + if (*nx == 0) { + if (lnx > 0) { + *x = lx = ALLOC(DdNode *,lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *xn = lxn = ALLOC(DdNode *,lnx); + if (lxn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + *x = *xn = NULL; + } + } else if (lnx > *nx) { + *x = lx = REALLOC(DdNode *, *x, lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *xn = lxn = REALLOC(DdNode *, *xn, lnx); + if (lxn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + lx = *x; + lxn = *xn; + } + if (*ny == 0) { + if (lny >0) { + *y = ly = ALLOC(DdNode *,lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *yn_ = lyn = ALLOC(DdNode *,lny); + if (lyn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + *y = *yn_ = NULL; + } + } else if (lny > *ny) { + *y = ly = REALLOC(DdNode *, *y, lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *yn_ = lyn = REALLOC(DdNode *, *yn_, lny); + if (lyn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + ly = *y; + lyn = *yn_; + } + + /* Create new variables as needed */ + for (i= *nx,nv=bx+(*nx)*sx; i < lnx; i++,nv+=sx) { + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); + cuddRef(lx[i]); + do { + dd->reordered = 0; + lxn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lxn[i] == NULL) return(0); + cuddRef(lxn[i]); + } + for (i= *ny,nv=by+(*ny)*sy; i < lny; i++,nv+=sy) { + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); + do { + dd->reordered = 0; + lyn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lyn[i] == NULL) return(0); + cuddRef(lyn[i]); + } + + /* Update matrix parameters */ + *nx = lnx; + *ny = lny; + *m = nrow; + if (nrhs == 0) { + *n = ncol; + } else { + *n = (1 << (lny - 1)) + nrhs; + } + + /* Read structure data */ + colptr = ALLOC(int, ncol+1); + if (colptr == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + rowind = ALLOC(int, nnzero); + if (rowind == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + + for (i=0; ierr,"%s: Unexpected colptr[0] (%d)\n", + key,colptr[0]); + FREE(colptr); + FREE(rowind); + return(0); + } + for (i=0; i=0; nv--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + FREE(colptr); + FREE(rowind); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubey); + cubey = w; + v >>= 1; + } + for (i=colptr[j]; i=0; nv--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + FREE(colptr); + FREE(rowind); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubex); + cubex = w; + u >>= 1; + } + minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); + if (minterm1 == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + FREE(colptr); + FREE(rowind); + return(0); + } + cuddRef(minterm1); + Cudd_RecursiveDeref(dd, cubex); + w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + FREE(colptr); + FREE(rowind); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, *E); + *E = w; + } + Cudd_RecursiveDeref(dd, cubey); + } + FREE(colptr); + FREE(rowind); + + /* Read right-hand sides */ + for (j=0; j=0; nv--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubey); + cubey = w; + v >>= 1; + } + for (i=0; i=0; nv--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubex); + cubex = w; + u >>= 1; + } + minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); + if (minterm1 == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + return(0); + } + cuddRef(minterm1); + Cudd_RecursiveDeref(dd, cubex); + w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, *E); + *E = w; + } + Cudd_RecursiveDeref(dd, cubey); + } + + return(1); + +} /* end of Cudd_addHarwell */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddInit.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddInit.c new file mode 100644 index 000000000..12830bdeb --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddInit.c @@ -0,0 +1,308 @@ +/**CFile*********************************************************************** + + FileName [cuddInit.c] + + PackageName [cudd] + + Synopsis [Functions to initialize and shut down the DD manager.] + + Description [External procedures included in this module: +
        +
      • Cudd_Init() +
      • Cudd_Quit() +
      + Internal procedures included in this module: +
        +
      • cuddZddInitUniv() +
      • cuddZddFreeUniv() +
      + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddInit.c,v 1.34 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Creates a new DD manager.] + + Description [Creates a new DD manager, initializes the table, the + basic constants and the projection functions. If maxMemory is 0, + Cudd_Init decides suitable values for the maximum size of the cache + and for the limit for fast unique table growth based on the available + memory. Returns a pointer to the manager if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Quit] + +******************************************************************************/ +DdManager * +Cudd_Init( + unsigned int numVars /* initial number of BDD variables (i.e., subtables) */, + unsigned int numVarsZ /* initial number of ZDD variables (i.e., subtables) */, + unsigned int numSlots /* initial size of the unique tables */, + unsigned int cacheSize /* initial size of the cache */, + unsigned long maxMemory /* target maximum memory occupation */) +{ + DdManager *unique; + int i,result; + DdNode *one, *zero; + unsigned int maxCacheSize; + unsigned int looseUpTo; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (maxMemory == 0) { + maxMemory = getSoftDataLimit(); + } + looseUpTo = (unsigned int) ((maxMemory / sizeof(DdNode)) / + DD_MAX_LOOSE_FRACTION); + unique = cuddInitTable(numVars,numVarsZ,numSlots,looseUpTo); + if (unique == NULL) return(NULL); + unique->maxmem = (unsigned long) maxMemory / 10 * 9; + maxCacheSize = (unsigned int) ((maxMemory / sizeof(DdCache)) / + DD_MAX_CACHE_FRACTION); + result = cuddInitCache(unique,cacheSize,maxCacheSize); + if (result == 0) return(NULL); + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + unique->stash = ALLOC(char,(maxMemory / DD_STASH_FRACTION) + 4); + MMoutOfMemory = saveHandler; + if (unique->stash == NULL) { + (void) fprintf(unique->err,"Unable to set aside memory\n"); + } + + /* Initialize constants. */ + unique->one = cuddUniqueConst(unique,1.0); + if (unique->one == NULL) return(0); + cuddRef(unique->one); + unique->zero = cuddUniqueConst(unique,0.0); + if (unique->zero == NULL) return(0); + cuddRef(unique->zero); +#ifdef HAVE_IEEE_754 + if (DD_PLUS_INF_VAL != DD_PLUS_INF_VAL * 3 || + DD_PLUS_INF_VAL != DD_PLUS_INF_VAL / 3) { + (void) fprintf(unique->err,"Warning: Crippled infinite values\n"); + (void) fprintf(unique->err,"Recompile without -DHAVE_IEEE_754\n"); + } +#endif + unique->plusinfinity = cuddUniqueConst(unique,DD_PLUS_INF_VAL); + if (unique->plusinfinity == NULL) return(0); + cuddRef(unique->plusinfinity); + unique->minusinfinity = cuddUniqueConst(unique,DD_MINUS_INF_VAL); + if (unique->minusinfinity == NULL) return(0); + cuddRef(unique->minusinfinity); + unique->background = unique->zero; + + /* The logical zero is different from the CUDD_VALUE_TYPE zero! */ + one = unique->one; + zero = Cudd_Not(one); + /* Create the projection functions. */ + unique->vars = ALLOC(DdNodePtr,unique->maxSize); + if (unique->vars == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < unique->size; i++) { + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) return(0); + cuddRef(unique->vars[i]); + } + + if (unique->sizeZ) + cuddZddInitUniv(unique); + + unique->memused += sizeof(DdNode *) * unique->maxSize; + + return(unique); + +} /* end of Cudd_Init */ + + +/**Function******************************************************************** + + Synopsis [Deletes resources associated with a DD manager.] + + Description [Deletes resources associated with a DD manager and + resets the global statistical counters. (Otherwise, another manaqger + subsequently created would inherit the stats of this one.)] + + SideEffects [None] + + SeeAlso [Cudd_Init] + +******************************************************************************/ +void +Cudd_Quit( + DdManager * unique) +{ + if (unique->stash != NULL) FREE(unique->stash); + cuddFreeTable(unique); + +} /* end of Cudd_Quit */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes the ZDD universe.] + + Description [Initializes the ZDD universe. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddZddFreeUniv] + +******************************************************************************/ +int +cuddZddInitUniv( + DdManager * zdd) +{ + DdNode *p, *res; + int i; + + zdd->univ = ALLOC(DdNodePtr, zdd->sizeZ); + if (zdd->univ == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + + res = DD_ONE(zdd); + cuddRef(res); + for (i = zdd->sizeZ - 1; i >= 0; i--) { + unsigned int index = zdd->invpermZ[i]; + p = res; + res = cuddUniqueInterZdd(zdd, index, p, p); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd,p); + FREE(zdd->univ); + return(0); + } + cuddRef(res); + cuddDeref(p); + zdd->univ[i] = res; + } + +#ifdef DD_VERBOSE + cuddZddP(zdd, zdd->univ[0]); +#endif + + return(1); + +} /* end of cuddZddInitUniv */ + + +/**Function******************************************************************** + + Synopsis [Frees the ZDD universe.] + + Description [Frees the ZDD universe.] + + SideEffects [None] + + SeeAlso [cuddZddInitUniv] + +******************************************************************************/ +void +cuddZddFreeUniv( + DdManager * zdd) +{ + if (zdd->univ) { + Cudd_RecursiveDerefZdd(zdd, zdd->univ[0]); + FREE(zdd->univ); + } + +} /* end of cuddZddFreeUniv */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddInt.h b/resources/3rdparty/cudd-2.5.0/cudd/cuddInt.h new file mode 100644 index 000000000..398b057f7 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddInt.h @@ -0,0 +1,1188 @@ +/**CHeaderFile***************************************************************** + + FileName [cuddInt.h] + + PackageName [cudd] + + Synopsis [Internal data structures of the CUDD package.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: cuddInt.h,v 1.142 2012/02/05 01:07:19 fabio Exp $] + +******************************************************************************/ + +#ifndef _CUDDINT +#define _CUDDINT + + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#ifdef DD_MIS +#include "array.h" +#include "list.h" +#include "st.h" +#include "espresso.h" +#include "node.h" +#ifdef SIS +#include "graph.h" +#include "astg.h" +#endif +#include "network.h" +#endif + +#include +#include "cudd.h" +#include "st.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) +# define DD_INLINE __inline__ +# if (__GNUC__ >2 || __GNUC_MINOR__ >=7) +# define DD_UNUSED __attribute__ ((__unused__)) +# else +# define DD_UNUSED +# endif +#else +# if defined(__cplusplus) +# define DD_INLINE inline +# else +# define DD_INLINE +# endif +# define DD_UNUSED +#endif + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_MAXREF ((DdHalfWord) ~0) + +#define DD_DEFAULT_RESIZE 10 /* how many extra variables */ + /* should be added when resizing */ +#define DD_MEM_CHUNK 1022 + +/* These definitions work for CUDD_VALUE_TYPE == double */ +#define DD_ONE_VAL (1.0) +#define DD_ZERO_VAL (0.0) +#define DD_EPSILON (1.0e-12) + +/* The definitions of +/- infinity in terms of HUGE_VAL work on +** the DECstations and on many other combinations of OS/compiler. +*/ +#ifdef HAVE_IEEE_754 +# define DD_PLUS_INF_VAL (HUGE_VAL) +#else +# define DD_PLUS_INF_VAL (10e301) +# define DD_CRI_HI_MARK (10e150) +# define DD_CRI_LO_MARK (-(DD_CRI_HI_MARK)) +#endif +#define DD_MINUS_INF_VAL (-(DD_PLUS_INF_VAL)) + +#define DD_NON_CONSTANT ((DdNode *) 1) /* for Cudd_bddIteConstant */ + +/* Unique table and cache management constants. */ +#define DD_MAX_SUBTABLE_DENSITY 4 /* tells when to resize a subtable */ +/* gc when this percent are dead (measured w.r.t. slots, not keys) +** The first limit (LO) applies normally. The second limit applies when +** the package believes more space for the unique table (i.e., more dead +** nodes) would improve performance, and the unique table is not already +** too large. The third limit applies when memory is low. +*/ +#define DD_GC_FRAC_LO DD_MAX_SUBTABLE_DENSITY * 0.25 +#define DD_GC_FRAC_HI DD_MAX_SUBTABLE_DENSITY * 1.0 +#define DD_GC_FRAC_MIN 0.2 +#define DD_MIN_HIT 30 /* resize cache when hit ratio + above this percentage (default) */ +#define DD_MAX_LOOSE_FRACTION 5 /* 1 / (max fraction of memory used for + unique table in fast growth mode) */ +#define DD_MAX_CACHE_FRACTION 3 /* 1 / (max fraction of memory used for + computed table if resizing enabled) */ +#define DD_STASH_FRACTION 64 /* 1 / (fraction of memory set + aside for emergencies) */ +#define DD_MAX_CACHE_TO_SLOTS_RATIO 4 /* used to limit the cache size */ + +/* Variable ordering default parameter values. */ +#define DD_SIFT_MAX_VAR 1000 +#define DD_SIFT_MAX_SWAPS 2000000 +#define DD_DEFAULT_RECOMB 0 +#define DD_MAX_REORDER_GROWTH 1.2 +#define DD_FIRST_REORDER 4004 /* 4 for the constants */ +#define DD_DYN_RATIO 2 /* when to dynamically reorder */ + +/* Primes for cache hash functions. */ +#define DD_P1 12582917 +#define DD_P2 4256249 +#define DD_P3 741457 +#define DD_P4 1618033999 + +/* Cache tags for 3-operand operators. These tags are stored in the +** least significant bits of the cache operand pointers according to +** the following scheme. The tag consists of two hex digits. Both digits +** must be even, so that they do not interfere with complementation bits. +** The least significant one is stored in Bits 3:1 of the f operand in the +** cache entry. Bit 1 is always 1, so that we can differentiate +** three-operand operations from one- and two-operand operations. +** Therefore, the least significant digit is one of {2,6,a,e}. The most +** significant digit occupies Bits 3:1 of the g operand in the cache +** entry. It can by any even digit between 0 and e. This gives a total +** of 5 bits for the tag proper, which means a maximum of 32 three-operand +** operations. */ +#define DD_ADD_ITE_TAG 0x02 +#define DD_BDD_AND_ABSTRACT_TAG 0x06 +#define DD_BDD_XOR_EXIST_ABSTRACT_TAG 0x0a +#define DD_BDD_ITE_TAG 0x0e +#define DD_ADD_BDD_DO_INTERVAL_TAG 0x22 +#define DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG 0x26 +#define DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG 0x2a +#define DD_BDD_COMPOSE_RECUR_TAG 0x2e +#define DD_ADD_COMPOSE_RECUR_TAG 0x42 +#define DD_ADD_NON_SIM_COMPOSE_TAG 0x46 +#define DD_EQUIV_DC_TAG 0x4a +#define DD_ZDD_ITE_TAG 0x4e +#define DD_ADD_ITE_CONSTANT_TAG 0x62 +#define DD_ADD_EVAL_CONST_TAG 0x66 +#define DD_BDD_ITE_CONSTANT_TAG 0x6a +#define DD_ADD_OUT_SUM_TAG 0x6e +#define DD_BDD_LEQ_UNLESS_TAG 0x82 +#define DD_ADD_TRIANGLE_TAG 0x86 +#define DD_BDD_MAX_EXP_TAG 0x8a + +/* Generator constants. */ +#define CUDD_GEN_CUBES 0 +#define CUDD_GEN_PRIMES 1 +#define CUDD_GEN_NODES 2 +#define CUDD_GEN_ZDD_PATHS 3 +#define CUDD_GEN_EMPTY 0 +#define CUDD_GEN_NONEMPTY 1 + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +struct DdGen { + DdManager *manager; + int type; + int status; + union { + struct { + int *cube; + CUDD_VALUE_TYPE value; + } cubes; + struct { + int *cube; + DdNode *ub; + } primes; + struct { + int size; + } nodes; + } gen; + struct { + int sp; + DdNode **stack; + } stack; + DdNode *node; +}; + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/* Hooks in CUDD are functions that the application registers with the +** manager so that they are called at appropriate times. The functions +** are passed the manager as argument; they should return 1 if +** successful and 0 otherwise. +*/ +typedef struct DdHook { /* hook list element */ + DD_HFP f; /* function to be called */ + struct DdHook *next; /* next element in the list */ +} DdHook; + +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +typedef long ptrint; +typedef unsigned long ptruint; +#else +typedef int ptrint; +typedef unsigned int ptruint; +#endif + +typedef DdNode *DdNodePtr; + +/* Generic local cache item. */ +typedef struct DdLocalCacheItem { + DdNode *value; +#ifdef DD_CACHE_PROFILE + ptrint count; +#endif + DdNode *key[1]; +} DdLocalCacheItem; + +/* Local cache. */ +typedef struct DdLocalCache { + DdLocalCacheItem *item; + unsigned int itemsize; + unsigned int keysize; + unsigned int slots; + int shift; + double lookUps; + double minHit; + double hits; + unsigned int maxslots; + DdManager *manager; + struct DdLocalCache *next; +} DdLocalCache; + +/* Generic hash item. */ +typedef struct DdHashItem { + struct DdHashItem *next; + ptrint count; + DdNode *value; + DdNode *key[1]; +} DdHashItem; + +/* Local hash table */ +typedef struct DdHashTable { + unsigned int keysize; + unsigned int itemsize; + DdHashItem **bucket; + DdHashItem *nextFree; + DdHashItem **memoryList; + unsigned int numBuckets; + int shift; + unsigned int size; + unsigned int maxsize; + DdManager *manager; +} DdHashTable; + +typedef struct DdCache { + DdNode *f,*g; /* DDs */ + ptruint h; /* either operator or DD */ + DdNode *data; /* already constructed DD */ +#ifdef DD_CACHE_PROFILE + ptrint count; +#endif +} DdCache; + +typedef struct DdSubtable { /* subtable for one index */ + DdNode **nodelist; /* hash table */ + int shift; /* shift for hash function */ + unsigned int slots; /* size of the hash table */ + unsigned int keys; /* number of nodes stored in this table */ + unsigned int maxKeys; /* slots * DD_MAX_SUBTABLE_DENSITY */ + unsigned int dead; /* number of dead nodes in this table */ + unsigned int next; /* index of next variable in group */ + int bindVar; /* flag to bind this variable to its level */ + /* Fields for lazy sifting. */ + Cudd_VariableType varType; /* variable type (ps, ns, pi) */ + int pairIndex; /* corresponding variable index (ps <-> ns) */ + int varHandled; /* flag: 1 means variable is already handled */ + Cudd_LazyGroupType varToBeGrouped; /* tells what grouping to apply */ +} DdSubtable; + +struct DdManager { /* specialized DD symbol table */ + /* Constants */ + DdNode sentinel; /* for collision lists */ + DdNode *one; /* constant 1 */ + DdNode *zero; /* constant 0 */ + DdNode *plusinfinity; /* plus infinity */ + DdNode *minusinfinity; /* minus infinity */ + DdNode *background; /* background value */ + /* Computed Table */ + DdCache *acache; /* address of allocated memory for cache */ + DdCache *cache; /* the cache-based computed table */ + unsigned int cacheSlots; /* total number of cache entries */ + int cacheShift; /* shift value for cache hash function */ + double cacheMisses; /* number of cache misses (since resizing) */ + double cacheHits; /* number of cache hits (since resizing) */ + double minHit; /* hit percentage above which to resize */ + int cacheSlack; /* slots still available for resizing */ + unsigned int maxCacheHard; /* hard limit for cache size */ + /* Unique Table */ + int size; /* number of unique subtables */ + int sizeZ; /* for ZDD */ + int maxSize; /* max number of subtables before resizing */ + int maxSizeZ; /* for ZDD */ + DdSubtable *subtables; /* array of unique subtables */ + DdSubtable *subtableZ; /* for ZDD */ + DdSubtable constants; /* unique subtable for the constants */ + unsigned int slots; /* total number of hash buckets */ + unsigned int keys; /* total number of BDD and ADD nodes */ + unsigned int keysZ; /* total number of ZDD nodes */ + unsigned int dead; /* total number of dead BDD and ADD nodes */ + unsigned int deadZ; /* total number of dead ZDD nodes */ + unsigned int maxLive; /* maximum number of live nodes */ + unsigned int minDead; /* do not GC if fewer than these dead */ + double gcFrac; /* gc when this fraction is dead */ + int gcEnabled; /* gc is enabled */ + unsigned int looseUpTo; /* slow growth beyond this limit */ + /* (measured w.r.t. slots, not keys) */ + unsigned int initSlots; /* initial size of a subtable */ + DdNode **stack; /* stack for iterative procedures */ + double allocated; /* number of nodes allocated */ + /* (not during reordering) */ + double reclaimed; /* number of nodes brought back from the dead */ + int isolated; /* isolated projection functions */ + int *perm; /* current variable perm. (index to level) */ + int *permZ; /* for ZDD */ + int *invperm; /* current inv. var. perm. (level to index) */ + int *invpermZ; /* for ZDD */ + DdNode **vars; /* projection functions */ + int *map; /* variable map for fast swap */ + DdNode **univ; /* ZDD 1 for each variable */ + int linearSize; /* number of rows and columns of linear */ + long *interact; /* interacting variable matrix */ + long *linear; /* linear transform matrix */ + /* Memory Management */ + DdNode **memoryList; /* memory manager for symbol table */ + DdNode *nextFree; /* list of free nodes */ + char *stash; /* memory reserve */ +#ifndef DD_NO_DEATH_ROW + DdNode **deathRow; /* queue for dereferencing */ + int deathRowDepth; /* number of slots in the queue */ + int nextDead; /* index in the queue */ + unsigned deadMask; /* mask for circular index update */ +#endif + /* General Parameters */ + CUDD_VALUE_TYPE epsilon; /* tolerance on comparisons */ + /* Dynamic Reordering Parameters */ + int reordered; /* flag set at the end of reordering */ + unsigned int reorderings; /* number of calls to Cudd_ReduceHeap */ + unsigned int maxReorderings;/* maximum number of calls to Cudd_ReduceHeap */ + int siftMaxVar; /* maximum number of vars sifted */ + int siftMaxSwap; /* maximum number of swaps per sifting */ + double maxGrowth; /* maximum growth during reordering */ + double maxGrowthAlt; /* alternate maximum growth for reordering */ + int reordCycle; /* how often to apply alternate threshold */ + int autoDyn; /* automatic dynamic reordering flag (BDD) */ + int autoDynZ; /* automatic dynamic reordering flag (ZDD) */ + Cudd_ReorderingType autoMethod; /* default reordering method */ + Cudd_ReorderingType autoMethodZ; /* default reordering method (ZDD) */ + int realign; /* realign ZDD order after BDD reordering */ + int realignZ; /* realign BDD order after ZDD reordering */ + unsigned int nextDyn; /* reorder if this size is reached */ + unsigned int countDead; /* if 0, count deads to trigger reordering */ + MtrNode *tree; /* variable group tree (BDD) */ + MtrNode *treeZ; /* variable group tree (ZDD) */ + Cudd_AggregationType groupcheck; /* used during group sifting */ + int recomb; /* used during group sifting */ + int symmviolation; /* used during group sifting */ + int arcviolation; /* used during group sifting */ + int populationSize; /* population size for GA */ + int numberXovers; /* number of crossovers for GA */ + unsigned int randomizeOrder; /* perturb the next reordering threshold */ + DdLocalCache *localCaches; /* local caches currently in existence */ + char *hooks; /* application-specific field (used by vis) */ + DdHook *preGCHook; /* hooks to be called before GC */ + DdHook *postGCHook; /* hooks to be called after GC */ + DdHook *preReorderingHook; /* hooks to be called before reordering */ + DdHook *postReorderingHook; /* hooks to be called after reordering */ + FILE *out; /* stdout for this manager */ + FILE *err; /* stderr for this manager */ + Cudd_ErrorType errorCode; /* info on last error */ + unsigned long startTime; /* start time in milliseconds */ + unsigned long timeLimit; /* CPU time limit */ + /* Statistical counters. */ + unsigned long memused; /* total memory allocated for the manager */ + unsigned long maxmem; /* target maximum memory */ + unsigned long maxmemhard; /* hard limit for maximum memory */ + int garbageCollections; /* number of garbage collections */ + unsigned long GCTime; /* total time spent in garbage collection */ + unsigned long reordTime; /* total time spent in reordering */ + double totCachehits; /* total number of cache hits */ + double totCacheMisses; /* total number of cache misses */ + double cachecollisions; /* number of cache collisions */ + double cacheinserts; /* number of cache insertions */ + double cacheLastInserts; /* insertions at the last cache resizing */ + double cachedeletions; /* number of deletions during garbage coll. */ +#ifdef DD_STATS + double nodesFreed; /* number of nodes returned to the free list */ + double nodesDropped; /* number of nodes killed by dereferencing */ +#endif + unsigned int peakLiveNodes; /* maximum number of live nodes */ +#ifdef DD_UNIQUE_PROFILE + double uniqueLookUps; /* number of unique table lookups */ + double uniqueLinks; /* total distance traveled in coll. chains */ +#endif +#ifdef DD_COUNT + double recursiveCalls; /* number of recursive calls */ +#ifdef DD_STATS + double nextSample; /* when to write next line of stats */ +#endif + double swapSteps; /* number of elementary reordering steps */ +#endif +#ifdef DD_MIS + /* mis/verif compatibility fields */ + array_t *iton; /* maps ids in ddNode to node_t */ + array_t *order; /* copy of order_list */ + lsHandle handle; /* where it is in network BDD list */ + network_t *network; + st_table *local_order; /* for local BDDs */ + int nvars; /* variables used so far */ + int threshold; /* for pseudo var threshold value*/ +#endif +}; + +typedef struct Move { + DdHalfWord x; + DdHalfWord y; + unsigned int flags; + int size; + struct Move *next; +} Move; + +/* Generic level queue item. */ +typedef struct DdQueueItem { + struct DdQueueItem *next; + struct DdQueueItem *cnext; + void *key; +} DdQueueItem; + +/* Level queue. */ +typedef struct DdLevelQueue { + void *first; + DdQueueItem **last; + DdQueueItem *freelist; + DdQueueItem **buckets; + int levels; + int itemsize; + int size; + int maxsize; + int numBuckets; + int shift; +} DdLevelQueue; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Adds node to the head of the free list.] + + Description [Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions.] + + SideEffects [None] + + SeeAlso [cuddAllocNode cuddDynamicAllocNode cuddDeallocMove] + +******************************************************************************/ +#define cuddDeallocNode(unique,node) \ + (node)->next = (unique)->nextFree; \ + (unique)->nextFree = node; + +/**Macro*********************************************************************** + + Synopsis [Adds node to the head of the free list.] + + Description [Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions.] + + SideEffects [None] + + SeeAlso [cuddDeallocNode cuddDynamicAllocNode] + +******************************************************************************/ +#define cuddDeallocMove(unique,node) \ + ((DdNode *)(node))->ref = 0; \ + ((DdNode *)(node))->next = (unique)->nextFree; \ + (unique)->nextFree = (DdNode *)(node); + + +/**Macro*********************************************************************** + + Synopsis [Increases the reference count of a node, if it is not + saturated.] + + Description [Increases the reference count of a node, if it is not + saturated. This being a macro, it is faster than Cudd_Ref, but it + cannot be used in constructs like cuddRef(a = b()).] + + SideEffects [none] + + SeeAlso [Cudd_Ref] + +******************************************************************************/ +#define cuddRef(n) cuddSatInc(Cudd_Regular(n)->ref) + + +/**Macro*********************************************************************** + + Synopsis [Decreases the reference count of a node, if it is not + saturated.] + + Description [Decreases the reference count of node. It is primarily + used in recursive procedures to decrease the ref count of a result + node before returning it. This accomplishes the goal of removing the + protection applied by a previous cuddRef. This being a macro, it is + faster than Cudd_Deref, but it cannot be used in constructs like + cuddDeref(a = b()).] + + SideEffects [none] + + SeeAlso [Cudd_Deref] + +******************************************************************************/ +#define cuddDeref(n) cuddSatDec(Cudd_Regular(n)->ref) + + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if the node is a constant node.] + + Description [Returns 1 if the node is a constant node (rather than an + internal node). All constant nodes have the same index + (CUDD_CONST_INDEX). The pointer passed to cuddIsConstant must be regular.] + + SideEffects [none] + + SeeAlso [Cudd_IsConstant] + +******************************************************************************/ +#define cuddIsConstant(node) ((node)->index == CUDD_CONST_INDEX) + + +/**Macro*********************************************************************** + + Synopsis [Returns the then child of an internal node.] + + Description [Returns the then child of an internal node. If + node is a constant node, the result is unpredictable. + The pointer passed to cuddT must be regular.] + + SideEffects [none] + + SeeAlso [Cudd_T] + +******************************************************************************/ +#define cuddT(node) ((node)->type.kids.T) + + +/**Macro*********************************************************************** + + Synopsis [Returns the else child of an internal node.] + + Description [Returns the else child of an internal node. If + node is a constant node, the result is unpredictable. + The pointer passed to cuddE must be regular.] + + SideEffects [none] + + SeeAlso [Cudd_E] + +******************************************************************************/ +#define cuddE(node) ((node)->type.kids.E) + + +/**Macro*********************************************************************** + + Synopsis [Returns the value of a constant node.] + + Description [Returns the value of a constant node. If + node is an internal node, the result is unpredictable. + The pointer passed to cuddV must be regular.] + + SideEffects [none] + + SeeAlso [Cudd_V] + +******************************************************************************/ +#define cuddV(node) ((node)->type.value) + + +/**Macro*********************************************************************** + + Synopsis [Finds the current position of variable index in the + order.] + + Description [Finds the current position of variable index in the + order. This macro duplicates the functionality of Cudd_ReadPerm, + but it does not check for out-of-bounds indices and it is more + efficient.] + + SideEffects [none] + + SeeAlso [Cudd_ReadPerm] + +******************************************************************************/ +#define cuddI(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->perm[(index)]) + + +/**Macro*********************************************************************** + + Synopsis [Finds the current position of ZDD variable index in the + order.] + + Description [Finds the current position of ZDD variable index in the + order. This macro duplicates the functionality of Cudd_ReadPermZdd, + but it does not check for out-of-bounds indices and it is more + efficient.] + + SideEffects [none] + + SeeAlso [Cudd_ReadPermZdd] + +******************************************************************************/ +#define cuddIZ(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->permZ[(index)]) + + +/**Macro*********************************************************************** + + Synopsis [Hash function for the unique table.] + + Description [] + + SideEffects [none] + + SeeAlso [ddCHash ddCHash2] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddHash(f,g,s) \ +((((unsigned)(ptruint)(f) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (s)) +#else +#define ddHash(f,g,s) \ +((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Hash function for the cache.] + + Description [] + + SideEffects [none] + + SeeAlso [ddHash ddCHash2] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddCHash(o,f,g,h,s) \ +((((((unsigned)(ptruint)(f) + (unsigned)(ptruint)(o)) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2 + \ + (unsigned)(ptruint)(h)) * DD_P3) >> (s)) +#else +#define ddCHash(o,f,g,h,s) \ +((((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2 + \ + (unsigned)(h)) * DD_P3) >> (s)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Hash function for the cache for functions with two + operands.] + + Description [] + + SideEffects [none] + + SeeAlso [ddHash ddCHash] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddCHash2(o,f,g,s) \ +(((((unsigned)(ptruint)(f) + (unsigned)(ptruint)(o)) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (s)) +#else +#define ddCHash2(o,f,g,s) \ +(((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Clears the 4 least significant bits of a pointer.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define cuddClean(p) ((DdNode *)((ptruint)(p) & ~0xf)) + + +/**Macro*********************************************************************** + + Synopsis [Computes the minimum of two numbers.] + + Description [] + + SideEffects [none] + + SeeAlso [ddMax] + +******************************************************************************/ +#define ddMin(x,y) (((y) < (x)) ? (y) : (x)) + + +/**Macro*********************************************************************** + + Synopsis [Computes the maximum of two numbers.] + + Description [] + + SideEffects [none] + + SeeAlso [ddMin] + +******************************************************************************/ +#define ddMax(x,y) (((y) > (x)) ? (y) : (x)) + + +/**Macro*********************************************************************** + + Synopsis [Computes the absolute value of a number.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define ddAbs(x) (((x)<0) ? -(x) : (x)) + + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if the absolute value of the difference of the two + arguments x and y is less than e.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define ddEqualVal(x,y,e) (ddAbs((x)-(y))<(e)) + + +/**Macro*********************************************************************** + + Synopsis [Saturating increment operator.] + + Description [] + + SideEffects [none] + + SeeAlso [cuddSatDec] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define cuddSatInc(x) ((x)++) +#else +#define cuddSatInc(x) ((x) += (x) != (DdHalfWord)DD_MAXREF) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Saturating decrement operator.] + + Description [] + + SideEffects [none] + + SeeAlso [cuddSatInc] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define cuddSatDec(x) ((x)--) +#else +#define cuddSatDec(x) ((x) -= (x) != (DdHalfWord)DD_MAXREF) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Returns the constant 1 node.] + + Description [] + + SideEffects [none] + + SeeAlso [DD_ZERO DD_PLUS_INFINITY DD_MINUS_INFINITY] + +******************************************************************************/ +#define DD_ONE(dd) ((dd)->one) + + +/**Macro*********************************************************************** + + Synopsis [Returns the arithmetic 0 constant node.] + + Description [Returns the arithmetic 0 constant node. This is different + from the logical zero. The latter is obtained by + Cudd_Not(DD_ONE(dd)).] + + SideEffects [none] + + SeeAlso [DD_ONE Cudd_Not DD_PLUS_INFINITY DD_MINUS_INFINITY] + +******************************************************************************/ +#define DD_ZERO(dd) ((dd)->zero) + + +/**Macro*********************************************************************** + + Synopsis [Returns the plus infinity constant node.] + + Description [] + + SideEffects [none] + + SeeAlso [DD_ONE DD_ZERO DD_MINUS_INFINITY] + +******************************************************************************/ +#define DD_PLUS_INFINITY(dd) ((dd)->plusinfinity) + + +/**Macro*********************************************************************** + + Synopsis [Returns the minus infinity constant node.] + + Description [] + + SideEffects [none] + + SeeAlso [DD_ONE DD_ZERO DD_PLUS_INFINITY] + +******************************************************************************/ +#define DD_MINUS_INFINITY(dd) ((dd)->minusinfinity) + + +/**Macro*********************************************************************** + + Synopsis [Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL.] + + Description [Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL. + Furthermore, if x <= DD_MINUS_INF_VAL/2, x is set to + DD_MINUS_INF_VAL. Similarly, if DD_PLUS_INF_VAL/2 <= x, x is set to + DD_PLUS_INF_VAL. Normally this macro is a NOOP. However, if + HAVE_IEEE_754 is not defined, it makes sure that a value does not + get larger than infinity in absolute value, and once it gets to + infinity, stays there. If the value overflows before this macro is + applied, no recovery is possible.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#ifdef HAVE_IEEE_754 +#define cuddAdjust(x) +#else +#define cuddAdjust(x) ((x) = ((x) >= DD_CRI_HI_MARK) ? DD_PLUS_INF_VAL : (((x) <= DD_CRI_LO_MARK) ? DD_MINUS_INF_VAL : (x))) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Extract the least significant digit of a double digit.] + + Description [Extract the least significant digit of a double digit. Used + in the manipulation of arbitrary precision integers.] + + SideEffects [None] + + SeeAlso [DD_MSDIGIT] + +******************************************************************************/ +#define DD_LSDIGIT(x) ((x) & DD_APA_MASK) + + +/**Macro*********************************************************************** + + Synopsis [Extract the most significant digit of a double digit.] + + Description [Extract the most significant digit of a double digit. Used + in the manipulation of arbitrary precision integers.] + + SideEffects [None] + + SeeAlso [DD_LSDIGIT] + +******************************************************************************/ +#define DD_MSDIGIT(x) ((x) >> DD_APA_BITS) + + +/**Macro*********************************************************************** + + Synopsis [Outputs a line of stats.] + + Description [Outputs a line of stats if DD_COUNT and DD_STATS are + defined. Increments the number of recursive calls if DD_COUNT is + defined.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +#ifdef DD_COUNT +#ifdef DD_STATS +#define statLine(dd) dd->recursiveCalls++; \ +if (dd->recursiveCalls == dd->nextSample) {(void) fprintf(dd->err, \ +"@%.0f: %u nodes %u live %.0f dropped %.0f reclaimed\n", dd->recursiveCalls, \ +dd->keys, dd->keys - dd->dead, dd->nodesDropped, dd->reclaimed); \ +dd->nextSample += 250000;} +#else +#define statLine(dd) dd->recursiveCalls++; +#endif +#else +#define statLine(dd) +#endif + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern DdNode * cuddAddExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * cuddAddUnivAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * cuddAddOrAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * cuddAddApplyRecur (DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g); +extern DdNode * cuddAddMonadicApplyRecur (DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f); +extern DdNode * cuddAddScalarInverseRecur (DdManager *dd, DdNode *f, DdNode *epsilon); +extern DdNode * cuddAddIteRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddAddCmplRecur (DdManager *dd, DdNode *f); +extern DdNode * cuddAddNegateRecur (DdManager *dd, DdNode *f); +extern DdNode * cuddAddRoundOffRecur (DdManager *dd, DdNode *f, double trunc); +extern DdNode * cuddUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality); +extern DdNode * cuddRemapUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality); +extern DdNode * cuddBiasedUnderApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0); +extern DdNode * cuddBddAndAbstractRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube); +extern int cuddAnnealing (DdManager *table, int lower, int upper); +extern DdNode * cuddBddExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * cuddBddXorExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube); +extern DdNode * cuddBddBooleanDiffRecur (DdManager *manager, DdNode *f, DdNode *var); +extern DdNode * cuddBddIteRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddBddIntersectRecur (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddBddAndRecur (DdManager *manager, DdNode *f, DdNode *g); +extern DdNode * cuddBddXorRecur (DdManager *manager, DdNode *f, DdNode *g); +extern DdNode * cuddBddTransfer (DdManager *ddS, DdManager *ddD, DdNode *f); +extern DdNode * cuddAddBddDoPattern (DdManager *dd, DdNode *f); +extern int cuddInitCache (DdManager *unique, unsigned int cacheSize, unsigned int maxCacheSize); +extern void cuddCacheInsert (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data); +extern void cuddCacheInsert2 (DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data); +extern void cuddCacheInsert1 (DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f, DdNode *data); +extern DdNode * cuddCacheLookup (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddCacheLookupZdd (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddCacheLookup2 (DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g); +extern DdNode * cuddCacheLookup1 (DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f); +extern DdNode * cuddCacheLookup2Zdd (DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g); +extern DdNode * cuddCacheLookup1Zdd (DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f); +extern DdNode * cuddConstantLookup (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h); +extern int cuddCacheProfile (DdManager *table, FILE *fp); +extern void cuddCacheResize (DdManager *table); +extern void cuddCacheFlush (DdManager *table); +extern int cuddComputeFloorLog2 (unsigned int value); +extern int cuddHeapProfile (DdManager *dd); +extern void cuddPrintNode (DdNode *f, FILE *fp); +extern void cuddPrintVarGroups (DdManager * dd, MtrNode * root, int zdd, int silent); +extern DdNode * cuddBddClippingAnd (DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction); +extern DdNode * cuddBddClippingAndAbstract (DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction); +extern void cuddGetBranches (DdNode *g, DdNode **g1, DdNode **g0); +extern DdNode * cuddCofactorRecur (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddBddComposeRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *proj); +extern DdNode * cuddAddComposeRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *proj); +extern int cuddExact (DdManager *table, int lower, int upper); +extern DdNode * cuddBddConstrainRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddBddRestrictRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddBddNPAndRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddAddConstrainRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddAddRestrictRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddBddLICompaction (DdManager *dd, DdNode *f, DdNode *c); +extern int cuddGa (DdManager *table, int lower, int upper); +extern int cuddTreeSifting (DdManager *table, Cudd_ReorderingType method); +extern int cuddZddInitUniv (DdManager *zdd); +extern void cuddZddFreeUniv (DdManager *zdd); +extern void cuddSetInteract (DdManager *table, int x, int y); +extern int cuddTestInteract (DdManager *table, int x, int y); +extern int cuddInitInteract (DdManager *table); +extern DdLocalCache * cuddLocalCacheInit (DdManager *manager, unsigned int keySize, unsigned int cacheSize, unsigned int maxCacheSize); +extern void cuddLocalCacheQuit (DdLocalCache *cache); +extern void cuddLocalCacheInsert (DdLocalCache *cache, DdNodePtr *key, DdNode *value); +extern DdNode * cuddLocalCacheLookup (DdLocalCache *cache, DdNodePtr *key); +extern void cuddLocalCacheClearDead (DdManager *manager); +extern int cuddIsInDeathRow (DdManager *dd, DdNode *f); +extern int cuddTimesInDeathRow (DdManager *dd, DdNode *f); +extern void cuddLocalCacheClearAll (DdManager *manager); +#ifdef DD_CACHE_PROFILE +extern int cuddLocalCacheProfile (DdLocalCache *cache); +#endif +extern DdHashTable * cuddHashTableInit (DdManager *manager, unsigned int keySize, unsigned int initSize); +extern void cuddHashTableQuit (DdHashTable *hash); +extern void cuddHashTableGenericQuit (DdHashTable *hash); +extern int cuddHashTableInsert (DdHashTable *hash, DdNodePtr *key, DdNode *value, ptrint count); +extern DdNode * cuddHashTableLookup (DdHashTable *hash, DdNodePtr *key); +extern int cuddHashTableInsert1 (DdHashTable *hash, DdNode *f, DdNode *value, ptrint count); +extern DdNode * cuddHashTableLookup1 (DdHashTable *hash, DdNode *f); +extern int cuddHashTableInsert2 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *value, ptrint count); +extern DdNode * cuddHashTableLookup2 (DdHashTable *hash, DdNode *f, DdNode *g); +extern int cuddHashTableInsert3 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h, DdNode *value, ptrint count); +extern DdNode * cuddHashTableLookup3 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h); +extern int cuddHashTableGenericInsert(DdHashTable * hash, DdNode * f, void * value); +extern void * cuddHashTableGenericLookup(DdHashTable * hash, DdNode * f); +extern DdLevelQueue * cuddLevelQueueInit (int levels, int itemSize, int numBuckets); +extern void cuddLevelQueueQuit (DdLevelQueue *queue); +extern void * cuddLevelQueueFirst(DdLevelQueue * queue, void * key, int level); +extern void * cuddLevelQueueEnqueue (DdLevelQueue *queue, void *key, int level); +extern void cuddLevelQueueDequeue (DdLevelQueue *queue, int level); +extern int cuddLinearAndSifting (DdManager *table, int lower, int upper); +extern int cuddLinearInPlace (DdManager * table, int x, int y); +extern void cuddUpdateInteractionMatrix (DdManager * table, int xindex, int yindex); +extern int cuddInitLinear (DdManager *table); +extern int cuddResizeLinear (DdManager *table); +extern DdNode * cuddBddLiteralSetIntersectionRecur (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddCProjectionRecur (DdManager *dd, DdNode *R, DdNode *Y, DdNode *Ysupp); +extern DdNode * cuddBddClosestCube (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE bound); +extern void cuddReclaim (DdManager *table, DdNode *n); +extern void cuddReclaimZdd (DdManager *table, DdNode *n); +extern void cuddClearDeathRow (DdManager *table); +extern void cuddShrinkDeathRow (DdManager *table); +extern DdNode * cuddDynamicAllocNode (DdManager *table); +extern int cuddSifting (DdManager *table, int lower, int upper); +extern int cuddSwapping (DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic); +extern int cuddNextHigh (DdManager *table, int x); +extern int cuddNextLow (DdManager *table, int x); +extern int cuddSwapInPlace (DdManager *table, int x, int y); +extern int cuddBddAlignToZdd (DdManager *table); +extern DdNode * cuddBddMakePrime (DdManager *dd, DdNode *cube, DdNode *f); +extern DdNode * cuddSolveEqnRecur (DdManager *bdd, DdNode *F, DdNode *Y, DdNode **G, int n, int *yIndex, int i); +extern DdNode * cuddVerifySol (DdManager *bdd, DdNode *F, DdNode **G, int *yIndex, int n); +#ifdef ST_INCLUDED +extern DdNode* cuddSplitSetRecur (DdManager *manager, st_table *mtable, int *varSeen, DdNode *p, double n, double max, int index); +#endif +extern DdNode * cuddSubsetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold); +extern DdNode * cuddSubsetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit); +extern int cuddSymmCheck (DdManager *table, int x, int y); +extern int cuddSymmSifting (DdManager *table, int lower, int upper); +extern int cuddSymmSiftingConv (DdManager *table, int lower, int upper); +extern DdNode * cuddAllocNode (DdManager *unique); +extern DdManager * cuddInitTable (unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int looseUpTo); +extern void cuddFreeTable (DdManager *unique); +extern int cuddGarbageCollect (DdManager *unique, int clearCache); +extern DdNode * cuddZddGetNode (DdManager *zdd, int id, DdNode *T, DdNode *E); +extern DdNode * cuddZddGetNodeIVO (DdManager *dd, int index, DdNode *g, DdNode *h); +extern DdNode * cuddUniqueInter (DdManager *unique, int index, DdNode *T, DdNode *E); +extern DdNode * cuddUniqueInterIVO (DdManager *unique, int index, DdNode *T, DdNode *E); +extern DdNode * cuddUniqueInterZdd (DdManager *unique, int index, DdNode *T, DdNode *E); +extern DdNode * cuddUniqueConst (DdManager *unique, CUDD_VALUE_TYPE value); +extern void cuddRehash (DdManager *unique, int i); +extern void cuddShrinkSubtable (DdManager *unique, int i); +extern int cuddInsertSubtables (DdManager *unique, int n, int level); +extern int cuddDestroySubtables (DdManager *unique, int n); +extern int cuddResizeTableZdd (DdManager *unique, int index); +extern void cuddSlowTableGrowth (DdManager *unique); +extern int cuddP (DdManager *dd, DdNode *f); +#ifdef ST_INCLUDED +extern enum st_retval cuddStCountfree (char *key, char *value, char *arg); +extern int cuddCollectNodes (DdNode *f, st_table *visited); +#endif +extern DdNodePtr * cuddNodeArray (DdNode *f, int *n); +extern int cuddWindowReorder (DdManager *table, int low, int high, Cudd_ReorderingType submethod); +extern DdNode * cuddZddProduct (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddUnateProduct (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddWeakDiv (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddWeakDivF (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddDivide (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddDivideF (DdManager *dd, DdNode *f, DdNode *g); +extern int cuddZddGetCofactors3 (DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd); +extern int cuddZddGetCofactors2 (DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0); +extern DdNode * cuddZddComplement (DdManager *dd, DdNode *node); +extern int cuddZddGetPosVarIndex(DdManager * dd, int index); +extern int cuddZddGetNegVarIndex(DdManager * dd, int index); +extern int cuddZddGetPosVarLevel(DdManager * dd, int index); +extern int cuddZddGetNegVarLevel(DdManager * dd, int index); +extern int cuddZddTreeSifting (DdManager *table, Cudd_ReorderingType method); +extern DdNode * cuddZddIsop (DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I); +extern DdNode * cuddBddIsop (DdManager *dd, DdNode *L, DdNode *U); +extern DdNode * cuddMakeBddFromZddCover (DdManager *dd, DdNode *node); +extern int cuddZddLinearSifting (DdManager *table, int lower, int upper); +extern int cuddZddAlignToBdd (DdManager *table); +extern int cuddZddNextHigh (DdManager *table, int x); +extern int cuddZddNextLow (DdManager *table, int x); +extern int cuddZddUniqueCompare (int *ptr_x, int *ptr_y); +extern int cuddZddSwapInPlace (DdManager *table, int x, int y); +extern int cuddZddSwapping (DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic); +extern int cuddZddSifting (DdManager *table, int lower, int upper); +extern DdNode * cuddZddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddZddUnion (DdManager *zdd, DdNode *P, DdNode *Q); +extern DdNode * cuddZddIntersect (DdManager *zdd, DdNode *P, DdNode *Q); +extern DdNode * cuddZddDiff (DdManager *zdd, DdNode *P, DdNode *Q); +extern DdNode * cuddZddChangeAux (DdManager *zdd, DdNode *P, DdNode *zvar); +extern DdNode * cuddZddSubset1 (DdManager *dd, DdNode *P, int var); +extern DdNode * cuddZddSubset0 (DdManager *dd, DdNode *P, int var); +extern DdNode * cuddZddChange (DdManager *dd, DdNode *P, int var); +extern int cuddZddSymmCheck (DdManager *table, int x, int y); +extern int cuddZddSymmSifting (DdManager *table, int lower, int upper); +extern int cuddZddSymmSiftingConv (DdManager *table, int lower, int upper); +extern int cuddZddP (DdManager *zdd, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _CUDDINT */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddInteract.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddInteract.c new file mode 100644 index 000000000..42fc68046 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddInteract.c @@ -0,0 +1,432 @@ +/**CFile*********************************************************************** + + FileName [cuddInteract.c] + + PackageName [cudd] + + Synopsis [Functions to manipulate the variable interaction matrix.] + + Description [Internal procedures included in this file: +
        +
      • cuddSetInteract() +
      • cuddTestInteract() +
      • cuddInitInteract() +
      + Static procedures included in this file: +
        +
      • ddSuppInteract() +
      • ddClearLocal() +
      • ddUpdateInteract() +
      • ddClearGlobal() +
      + The interaction matrix tells whether two variables are + both in the support of some function of the DD. The main use of the + interaction matrix is in the in-place swapping. Indeed, if two + variables do not interact, there is no arc connecting the two layers; + therefore, the swap can be performed in constant time, without + scanning the subtables. Another use of the interaction matrix is in + the computation of the lower bounds for sifting. Finally, the + interaction matrix can be used to speed up aggregation checks in + symmetric and group sifting.

      + The computation of the interaction matrix is done with a series of + depth-first searches. The searches start from those nodes that have + only external references. The matrix is stored as a packed array of bits; + since it is symmetric, only the upper triangle is kept in memory. + As a final remark, we note that there may be variables that do + interact, but that for a given variable order have no arc connecting + their layers when they are adjacent. For instance, in ite(a,b,c) with + the order asize, + sets the corresponding bit of the interaction matrix to 1.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddSetInteract( + DdManager * table, + int x, + int y) +{ + int posn, word, bit; + +#ifdef DD_DEBUG + assert(x < y); + assert(y < table->size); + assert(x >= 0); +#endif + + posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1; + word = posn >> LOGBPL; + bit = posn & (BPL-1); + table->interact[word] |= 1L << bit; + +} /* end of cuddSetInteract */ + + +/**Function******************************************************************** + + Synopsis [Test interaction matrix entries.] + + Description [Given a pair of variables 0 <= x < y < table->size, + tests whether the corresponding bit of the interaction matrix is 1. + Returns the value of the bit.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddTestInteract( + DdManager * table, + int x, + int y) +{ + int posn, word, bit, result; + + if (x > y) { + int tmp = x; + x = y; + y = tmp; + } +#ifdef DD_DEBUG + assert(x < y); + assert(y < table->size); + assert(x >= 0); +#endif + + posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1; + word = posn >> LOGBPL; + bit = posn & (BPL-1); + result = (table->interact[word] >> bit) & 1L; + return(result); + +} /* end of cuddTestInteract */ + + +/**Function******************************************************************** + + Synopsis [Initializes the interaction matrix.] + + Description [Initializes the interaction matrix. The interaction + matrix is implemented as a bit vector storing the upper triangle of + the symmetric interaction matrix. The bit vector is kept in an array + of long integers. The computation is based on a series of depth-first + searches, one for each root of the DAG. Two flags are needed: The + local visited flag uses the LSB of the then pointer. The global + visited flag uses the LSB of the next pointer. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddInitInteract( + DdManager * table) +{ + int i,j; + unsigned long words; + long *interact; + char *support; + DdNode *f; + DdNode *sentinel = &(table->sentinel); + DdNodePtr *nodelist; + int slots; + unsigned long n = (unsigned long) table->size; + + words = ((n * (n-1)) >> (1 + LOGBPL)) + 1; + table->interact = interact = ALLOC(long,words); + if (interact == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < words; i++) { + interact[i] = 0; + } + + support = ALLOC(char,n); + if (support == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + FREE(interact); + return(0); + } + for (i = 0; i < n; i++) { + support[i] = 0; + } + + for (i = 0; i < n; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + /* A node is a root of the DAG if it cannot be + ** reached by nodes above it. If a node was never + ** reached during the previous depth-first searches, + ** then it is a root, and we start a new depth-first + ** search from it. + */ + if (!Cudd_IsComplement(f->next)) { + ddSuppInteract(f,support); + ddClearLocal(f); + ddUpdateInteract(table,support); + } + f = Cudd_Regular(f->next); + } + } + } + ddClearGlobal(table); + + FREE(support); + return(1); + +} /* end of cuddInitInteract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Find the support of f.] + + Description [Performs a DFS from f. Uses the LSB of the then pointer + as visited flag.] + + SideEffects [Accumulates in support the variables on which f depends.] + + SeeAlso [] + +******************************************************************************/ +static void +ddSuppInteract( + DdNode * f, + char * support) +{ + if (cuddIsConstant(f) || Cudd_IsComplement(cuddT(f))) { + return; + } + + support[f->index] = 1; + ddSuppInteract(cuddT(f),support); + ddSuppInteract(Cudd_Regular(cuddE(f)),support); + /* mark as visited */ + cuddT(f) = Cudd_Complement(cuddT(f)); + f->next = Cudd_Complement(f->next); + return; + +} /* end of ddSuppInteract */ + + +/**Function******************************************************************** + + Synopsis [Performs a DFS from f, clearing the LSB of the then pointers.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ddClearLocal( + DdNode * f) +{ + if (cuddIsConstant(f) || !Cudd_IsComplement(cuddT(f))) { + return; + } + /* clear visited flag */ + cuddT(f) = Cudd_Regular(cuddT(f)); + ddClearLocal(cuddT(f)); + ddClearLocal(Cudd_Regular(cuddE(f))); + return; + +} /* end of ddClearLocal */ + + +/**Function******************************************************************** + + Synopsis [Marks as interacting all pairs of variables that appear in + support.] + + Description [If support[i] == support[j] == 1, sets the (i,j) entry + of the interaction matrix to 1.] + + SideEffects [Clears support.] + + SeeAlso [] + +******************************************************************************/ +static void +ddUpdateInteract( + DdManager * table, + char * support) +{ + int i,j; + int n = table->size; + + for (i = 0; i < n-1; i++) { + if (support[i] == 1) { + support[i] = 0; + for (j = i+1; j < n; j++) { + if (support[j] == 1) { + cuddSetInteract(table,i,j); + } + } + } + } + support[n-1] = 0; + +} /* end of ddUpdateInteract */ + + +/**Function******************************************************************** + + Synopsis [Scans the DD and clears the LSB of the next pointers.] + + Description [The LSB of the next pointers are used as markers to tell + whether a node was reached by at least one DFS. Once the interaction + matrix is built, these flags are reset.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ddClearGlobal( + DdManager * table) +{ + int i,j; + DdNode *f; + DdNode *sentinel = &(table->sentinel); + DdNodePtr *nodelist; + int slots; + + for (i = 0; i < table->size; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + f->next = Cudd_Regular(f->next); + f = f->next; + } + } + } + +} /* end of ddClearGlobal */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddLCache.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddLCache.c new file mode 100644 index 000000000..63186e105 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddLCache.c @@ -0,0 +1,1557 @@ +/**CFile*********************************************************************** + + FileName [cuddLCache.c] + + PackageName [cudd] + + Synopsis [Functions for local caches.] + + Description [Internal procedures included in this module: +

        +
      • cuddLocalCacheInit() +
      • cuddLocalCacheQuit() +
      • cuddLocalCacheInsert() +
      • cuddLocalCacheLookup() +
      • cuddLocalCacheClearDead() +
      • cuddLocalCacheClearAll() +
      • cuddLocalCacheProfile() +
      • cuddHashTableInit() +
      • cuddHashTableQuit() +
      • cuddHashTableGenericQuit() +
      • cuddHashTableInsert() +
      • cuddHashTableLookup() +
      • cuddHashTableGenericInsert() +
      • cuddHashTableGenericLookup() +
      • cuddHashTableInsert2() +
      • cuddHashTableLookup2() +
      • cuddHashTableInsert3() +
      • cuddHashTableLookup3() +
      + Static procedures included in this module: +
        +
      • cuddLocalCacheResize() +
      • ddLCHash() +
      • cuddLocalCacheAddToList() +
      • cuddLocalCacheRemoveFromList() +
      • cuddHashTableResize() +
      • cuddHashTableAlloc() +
      ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_MAX_HASHTABLE_DENSITY 2 /* tells when to resize a table */ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.27 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Computes hash function for keys of one operand.] + + Description [] + + SideEffects [None] + + SeeAlso [ddLCHash3 ddLCHash] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddLCHash1(f,shift) \ +(((unsigned)(ptruint)(f) * DD_P1) >> (shift)) +#else +#define ddLCHash1(f,shift) \ +(((unsigned)(f) * DD_P1) >> (shift)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Computes hash function for keys of two operands.] + + Description [] + + SideEffects [None] + + SeeAlso [ddLCHash3 ddLCHash] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddLCHash2(f,g,shift) \ +((((unsigned)(ptruint)(f) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (shift)) +#else +#define ddLCHash2(f,g,shift) \ +((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Computes hash function for keys of three operands.] + + Description [] + + SideEffects [None] + + SeeAlso [ddLCHash2 ddLCHash] + +******************************************************************************/ +#define ddLCHash3(f,g,h,shift) ddCHash2(f,g,h,shift) + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void cuddLocalCacheResize (DdLocalCache *cache); +DD_INLINE static unsigned int ddLCHash (DdNodePtr *key, unsigned int keysize, int shift); +static void cuddLocalCacheAddToList (DdLocalCache *cache); +static void cuddLocalCacheRemoveFromList (DdLocalCache *cache); +static int cuddHashTableResize (DdHashTable *hash); +DD_INLINE static DdHashItem * cuddHashTableAlloc (DdHashTable *hash); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes a local computed table.] + + Description [Initializes a computed table. Returns a pointer the + the new local cache in case of success; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddInitCache] + +******************************************************************************/ +DdLocalCache * +cuddLocalCacheInit( + DdManager * manager /* manager */, + unsigned int keySize /* size of the key (number of operands) */, + unsigned int cacheSize /* Initial size of the cache */, + unsigned int maxCacheSize /* Size of the cache beyond which no resizing occurs */) +{ + DdLocalCache *cache; + int logSize; + + cache = ALLOC(DdLocalCache,1); + if (cache == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + cache->manager = manager; + cache->keysize = keySize; + cache->itemsize = (keySize + 1) * sizeof(DdNode *); +#ifdef DD_CACHE_PROFILE + cache->itemsize += sizeof(ptrint); +#endif + logSize = cuddComputeFloorLog2(ddMax(cacheSize,manager->slots/2)); + cacheSize = 1 << logSize; + cache->item = (DdLocalCacheItem *) + ALLOC(char, cacheSize * cache->itemsize); + if (cache->item == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + FREE(cache); + return(NULL); + } + cache->slots = cacheSize; + cache->shift = sizeof(int) * 8 - logSize; + cache->maxslots = ddMin(maxCacheSize,manager->slots); + cache->minHit = manager->minHit; + /* Initialize to avoid division by 0 and immediate resizing. */ + cache->lookUps = (double) (int) (cacheSize * cache->minHit + 1); + cache->hits = 0; + manager->memused += cacheSize * cache->itemsize + sizeof(DdLocalCache); + + /* Initialize the cache. */ + memset(cache->item, 0, cacheSize * cache->itemsize); + + /* Add to manager's list of local caches for GC. */ + cuddLocalCacheAddToList(cache); + + return(cache); + +} /* end of cuddLocalCacheInit */ + + +/**Function******************************************************************** + + Synopsis [Shuts down a local computed table.] + + Description [Initializes the computed table. It is called by + Cudd_Init. Returns a pointer the the new local cache in case of + success; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddLocalCacheInit] + +******************************************************************************/ +void +cuddLocalCacheQuit( + DdLocalCache * cache /* cache to be shut down */) +{ + cache->manager->memused -= + cache->slots * cache->itemsize + sizeof(DdLocalCache); + cuddLocalCacheRemoveFromList(cache); + FREE(cache->item); + FREE(cache); + + return; + +} /* end of cuddLocalCacheQuit */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in a local cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddLocalCacheInsert( + DdLocalCache * cache, + DdNodePtr * key, + DdNode * value) +{ + unsigned int posn; + DdLocalCacheItem *entry; + + posn = ddLCHash(key,cache->keysize,cache->shift); + entry = (DdLocalCacheItem *) ((char *) cache->item + + posn * cache->itemsize); + memcpy(entry->key,key,cache->keysize * sizeof(DdNode *)); + entry->value = value; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddLocalCacheInsert */ + + +/**Function******************************************************************** + + Synopsis [Looks up in a local cache.] + + Description [Looks up in a local cache. Returns the result if found; + it returns NULL if no result is found.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddLocalCacheLookup( + DdLocalCache * cache, + DdNodePtr * key) +{ + unsigned int posn; + DdLocalCacheItem *entry; + DdNode *value; + + cache->lookUps++; + posn = ddLCHash(key,cache->keysize,cache->shift); + entry = (DdLocalCacheItem *) ((char *) cache->item + + posn * cache->itemsize); + if (entry->value != NULL && + memcmp(key,entry->key,cache->keysize*sizeof(DdNode *)) == 0) { + cache->hits++; + value = Cudd_Regular(entry->value); + if (value->ref == 0) { + cuddReclaim(cache->manager,value); + } + return(entry->value); + } + + /* Cache miss: decide whether to resize */ + + if (cache->slots < cache->maxslots && + cache->hits > cache->lookUps * cache->minHit) { + cuddLocalCacheResize(cache); + } + + return(NULL); + +} /* end of cuddLocalCacheLookup */ + + +/**Function******************************************************************** + + Synopsis [Clears the dead entries of the local caches of a manager.] + + Description [Clears the dead entries of the local caches of a manager. + Used during garbage collection.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddLocalCacheClearDead( + DdManager * manager) +{ + DdLocalCache *cache = manager->localCaches; + unsigned int keysize; + unsigned int itemsize; + unsigned int slots; + DdLocalCacheItem *item; + DdNodePtr *key; + unsigned int i, j; + + while (cache != NULL) { + keysize = cache->keysize; + itemsize = cache->itemsize; + slots = cache->slots; + item = cache->item; + for (i = 0; i < slots; i++) { + if (item->value != NULL) { + if (Cudd_Regular(item->value)->ref == 0) { + item->value = NULL; + } else { + key = item->key; + for (j = 0; j < keysize; j++) { + if (Cudd_Regular(key[j])->ref == 0) { + item->value = NULL; + break; + } + } + } + } + item = (DdLocalCacheItem *) ((char *) item + itemsize); + } + cache = cache->next; + } + return; + +} /* end of cuddLocalCacheClearDead */ + + +/**Function******************************************************************** + + Synopsis [Clears the local caches of a manager.] + + Description [Clears the local caches of a manager. + Used before reordering.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddLocalCacheClearAll( + DdManager * manager) +{ + DdLocalCache *cache = manager->localCaches; + + while (cache != NULL) { + memset(cache->item, 0, cache->slots * cache->itemsize); + cache = cache->next; + } + return; + +} /* end of cuddLocalCacheClearAll */ + + +#ifdef DD_CACHE_PROFILE + +#define DD_HYSTO_BINS 8 + +/**Function******************************************************************** + + Synopsis [Computes and prints a profile of a local cache usage.] + + Description [Computes and prints a profile of a local cache usage. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddLocalCacheProfile( + DdLocalCache * cache) +{ + double count, mean, meansq, stddev, expected; + long max, min; + int imax, imin; + int i, retval, slots; + long *hystogram; + int nbins = DD_HYSTO_BINS; + int bin; + long thiscount; + double totalcount; + int nzeroes; + DdLocalCacheItem *entry; + FILE *fp = cache->manager->out; + + slots = cache->slots; + + meansq = mean = expected = 0.0; + max = min = (long) cache->item[0].count; + imax = imin = nzeroes = 0; + totalcount = 0.0; + + hystogram = ALLOC(long, nbins); + if (hystogram == NULL) { + return(0); + } + for (i = 0; i < nbins; i++) { + hystogram[i] = 0; + } + + for (i = 0; i < slots; i++) { + entry = (DdLocalCacheItem *) ((char *) cache->item + + i * cache->itemsize); + thiscount = (long) entry->count; + if (thiscount > max) { + max = thiscount; + imax = i; + } + if (thiscount < min) { + min = thiscount; + imin = i; + } + if (thiscount == 0) { + nzeroes++; + } + count = (double) thiscount; + mean += count; + meansq += count * count; + totalcount += count; + expected += count * (double) i; + bin = (i * nbins) / slots; + hystogram[bin] += thiscount; + } + mean /= (double) slots; + meansq /= (double) slots; + stddev = sqrt(meansq - mean*mean); + + retval = fprintf(fp,"Cache stats: slots = %d average = %g ", slots, mean); + if (retval == EOF) return(0); + retval = fprintf(fp,"standard deviation = %g\n", stddev); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache max accesses = %ld for slot %d\n", max, imax); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache min accesses = %ld for slot %d\n", min, imin); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache unused slots = %d\n", nzeroes); + if (retval == EOF) return(0); + + if (totalcount) { + expected /= totalcount; + retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); + if (retval == EOF) return(0); + retval = fprintf(fp," (expected bin value = %g)\n# ", expected); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp,"%ld ", hystogram[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\n"); + if (retval == EOF) return(0); + } + + FREE(hystogram); + return(1); + +} /* end of cuddLocalCacheProfile */ +#endif + + +/**Function******************************************************************** + + Synopsis [Initializes a hash table.] + + Description [Initializes a hash table. Returns a pointer to the new + table if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableQuit] + +******************************************************************************/ +DdHashTable * +cuddHashTableInit( + DdManager * manager, + unsigned int keySize, + unsigned int initSize) +{ + DdHashTable *hash; + int logSize; + + hash = ALLOC(DdHashTable, 1); + if (hash == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + hash->keysize = keySize; + hash->manager = manager; + hash->memoryList = NULL; + hash->nextFree = NULL; + hash->itemsize = (keySize + 1) * sizeof(DdNode *) + + sizeof(ptrint) + sizeof(DdHashItem *); + /* We have to guarantee that the shift be < 32. */ + if (initSize < 2) initSize = 2; + logSize = cuddComputeFloorLog2(initSize); + hash->numBuckets = 1 << logSize; + hash->shift = sizeof(int) * 8 - logSize; + hash->bucket = ALLOC(DdHashItem *, hash->numBuckets); + if (hash->bucket == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + FREE(hash); + return(NULL); + } + memset(hash->bucket, 0, hash->numBuckets * sizeof(DdHashItem *)); + hash->size = 0; + hash->maxsize = hash->numBuckets * DD_MAX_HASHTABLE_DENSITY; + return(hash); + +} /* end of cuddHashTableInit */ + + +/**Function******************************************************************** + + Synopsis [Shuts down a hash table.] + + Description [Shuts down a hash table, dereferencing all the values.] + + SideEffects [None] + + SeeAlso [cuddHashTableInit] + +******************************************************************************/ +void +cuddHashTableQuit( + DdHashTable * hash) +{ + unsigned int i; + DdManager *dd = hash->manager; + DdHashItem *bucket; + DdHashItem **memlist, **nextmem; + unsigned int numBuckets = hash->numBuckets; + + for (i = 0; i < numBuckets; i++) { + bucket = hash->bucket[i]; + while (bucket != NULL) { + Cudd_RecursiveDeref(dd, bucket->value); + bucket = bucket->next; + } + } + + memlist = hash->memoryList; + while (memlist != NULL) { + nextmem = (DdHashItem **) memlist[0]; + FREE(memlist); + memlist = nextmem; + } + + FREE(hash->bucket); + FREE(hash); + + return; + +} /* end of cuddHashTableQuit */ + + +/**Function******************************************************************** + + Synopsis [Shuts down a hash table.] + + Description [Shuts down a hash table, when the values are not DdNode + pointers.] + + SideEffects [None] + + SeeAlso [cuddHashTableInit] + +******************************************************************************/ +void +cuddHashTableGenericQuit( + DdHashTable * hash) +{ +#ifdef __osf__ +#pragma pointer_size save +#pragma pointer_size short +#endif + DdHashItem **memlist, **nextmem; + + memlist = hash->memoryList; + while (memlist != NULL) { + nextmem = (DdHashItem **) memlist[0]; + FREE(memlist); + memlist = nextmem; + } + + FREE(hash->bucket); + FREE(hash); +#ifdef __osf__ +#pragma pointer_size restore +#endif + + return; + +} /* end of cuddHashTableGenericQuit */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key has more than + three pointers. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [[cuddHashTableInsert1 cuddHashTableInsert2 cuddHashTableInsert3 + cuddHashTableLookup] + +******************************************************************************/ +int +cuddHashTableInsert( + DdHashTable * hash, + DdNodePtr * key, + DdNode * value, + ptrint count) +{ + int result; + unsigned int posn; + DdHashItem *item; + unsigned int i; + +#ifdef DD_DEBUG + assert(hash->keysize > 3); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = value; + cuddRef(value); + item->count = count; + for (i = 0; i < hash->keysize; i++) { + item->key[i] = key[i]; + } + posn = ddLCHash(key,hash->keysize,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableInsert */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key in a hash table.] + + Description [Looks up a key consisting of more than three pointers + in a hash table. Returns the value associated to the key if there + is an entry for the given key in the table; NULL otherwise. If the + entry is present, its reference counter is decremented if not + saturated. If the counter reaches 0, the value of the entry is + dereferenced, and the entry is returned to the free list.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup1 cuddHashTableLookup2 cuddHashTableLookup3 + cuddHashTableInsert] + +******************************************************************************/ +DdNode * +cuddHashTableLookup( + DdHashTable * hash, + DdNodePtr * key) +{ + unsigned int posn; + DdHashItem *item, *prev; + unsigned int i, keysize; + +#ifdef DD_DEBUG + assert(hash->keysize > 3); +#endif + + posn = ddLCHash(key,hash->keysize,hash->shift); + item = hash->bucket[posn]; + prev = NULL; + + keysize = hash->keysize; + while (item != NULL) { + DdNodePtr *key2 = item->key; + int equal = 1; + for (i = 0; i < keysize; i++) { + if (key[i] != key2[i]) { + equal = 0; + break; + } + } + if (equal) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); + } + prev = item; + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableLookup */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key is one pointer. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert cuddHashTableInsert2 cuddHashTableInsert3 + cuddHashTableLookup1] + +******************************************************************************/ +int +cuddHashTableInsert1( + DdHashTable * hash, + DdNode * f, + DdNode * value, + ptrint count) +{ + int result; + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 1); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = value; + cuddRef(value); + item->count = count; + item->key[0] = f; + posn = ddLCHash1(f,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableInsert1 */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key consisting of one pointer in a hash table.] + + Description [Looks up a key consisting of one pointer in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup cuddHashTableLookup2 cuddHashTableLookup3 + cuddHashTableInsert1] + +******************************************************************************/ +DdNode * +cuddHashTableLookup1( + DdHashTable * hash, + DdNode * f) +{ + unsigned int posn; + DdHashItem *item, *prev; + +#ifdef DD_DEBUG + assert(hash->keysize == 1); +#endif + + posn = ddLCHash1(f,hash->shift); + item = hash->bucket[posn]; + prev = NULL; + + while (item != NULL) { + DdNodePtr *key = item->key; + if (f == key[0]) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); + } + prev = item; + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableLookup1 */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key is one + pointer and the value is not a DdNode pointer. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert1 cuddHashTableGenericLookup] + +******************************************************************************/ +int +cuddHashTableGenericInsert( + DdHashTable * hash, + DdNode * f, + void * value) +{ + int result; + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 1); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = (DdNode *) value; + item->count = 0; + item->key[0] = f; + posn = ddLCHash1(f,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableGenericInsert */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key consisting of one pointer in a hash table.] + + Description [Looks up a key consisting of one pointer in a hash + table when the value is not a DdNode pointer. Returns the value + associated to the key if there is an entry for the given key in the + table; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup1 cuddHashTableGenericInsert] + +******************************************************************************/ +void * +cuddHashTableGenericLookup( + DdHashTable * hash, + DdNode * f) +{ + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 1); +#endif + + posn = ddLCHash1(f,hash->shift); + item = hash->bucket[posn]; + + while (item != NULL) { + if (f == item->key[0]) { + return ((void *) item->value); + } + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableGenericLookup */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key is + composed of two pointers. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert3 + cuddHashTableLookup2] + +******************************************************************************/ +int +cuddHashTableInsert2( + DdHashTable * hash, + DdNode * f, + DdNode * g, + DdNode * value, + ptrint count) +{ + int result; + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 2); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = value; + cuddRef(value); + item->count = count; + item->key[0] = f; + item->key[1] = g; + posn = ddLCHash2(f,g,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableInsert2 */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key consisting of two pointers in a hash table.] + + Description [Looks up a key consisting of two pointer in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup3 + cuddHashTableInsert2] + +******************************************************************************/ +DdNode * +cuddHashTableLookup2( + DdHashTable * hash, + DdNode * f, + DdNode * g) +{ + unsigned int posn; + DdHashItem *item, *prev; + +#ifdef DD_DEBUG + assert(hash->keysize == 2); +#endif + + posn = ddLCHash2(f,g,hash->shift); + item = hash->bucket[posn]; + prev = NULL; + + while (item != NULL) { + DdNodePtr *key = item->key; + if ((f == key[0]) && (g == key[1])) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); + } + prev = item; + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableLookup2 */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key is + composed of three pointers. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert2 + cuddHashTableLookup3] + +******************************************************************************/ +int +cuddHashTableInsert3( + DdHashTable * hash, + DdNode * f, + DdNode * g, + DdNode * h, + DdNode * value, + ptrint count) +{ + int result; + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 3); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = value; + cuddRef(value); + item->count = count; + item->key[0] = f; + item->key[1] = g; + item->key[2] = h; + posn = ddLCHash3(f,g,h,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableInsert3 */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key consisting of three pointers in a hash table.] + + Description [Looks up a key consisting of three pointers in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup2 + cuddHashTableInsert3] + +******************************************************************************/ +DdNode * +cuddHashTableLookup3( + DdHashTable * hash, + DdNode * f, + DdNode * g, + DdNode * h) +{ + unsigned int posn; + DdHashItem *item, *prev; + +#ifdef DD_DEBUG + assert(hash->keysize == 3); +#endif + + posn = ddLCHash3(f,g,h,hash->shift); + item = hash->bucket[posn]; + prev = NULL; + + while (item != NULL) { + DdNodePtr *key = item->key; + if ((f == key[0]) && (g == key[1]) && (h == key[2])) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); + } + prev = item; + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableLookup3 */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Resizes a local cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +cuddLocalCacheResize( + DdLocalCache * cache) +{ + DdLocalCacheItem *item, *olditem, *entry, *old; + int i, shift; + unsigned int posn; + unsigned int slots, oldslots; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + olditem = cache->item; + oldslots = cache->slots; + slots = cache->slots = oldslots << 1; + +#ifdef DD_VERBOSE + (void) fprintf(cache->manager->err, + "Resizing local cache from %d to %d entries\n", + oldslots, slots); + (void) fprintf(cache->manager->err, + "\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n", + cache->hits, cache->lookUps, cache->hits / cache->lookUps); +#endif + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + cache->item = item = + (DdLocalCacheItem *) ALLOC(char, slots * cache->itemsize); + MMoutOfMemory = saveHandler; + /* If we fail to allocate the new table we just give up. */ + if (item == NULL) { +#ifdef DD_VERBOSE + (void) fprintf(cache->manager->err,"Resizing failed. Giving up.\n"); +#endif + cache->slots = oldslots; + cache->item = olditem; + /* Do not try to resize again. */ + cache->maxslots = oldslots - 1; + return; + } + shift = --(cache->shift); + cache->manager->memused += (slots - oldslots) * cache->itemsize; + + /* Clear new cache. */ + memset(item, 0, slots * cache->itemsize); + + /* Copy from old cache to new one. */ + for (i = 0; (unsigned) i < oldslots; i++) { + old = (DdLocalCacheItem *) ((char *) olditem + i * cache->itemsize); + if (old->value != NULL) { + posn = ddLCHash(old->key,cache->keysize,shift); + entry = (DdLocalCacheItem *) ((char *) item + + posn * cache->itemsize); + memcpy(entry->key,old->key,cache->keysize*sizeof(DdNode *)); + entry->value = old->value; + } + } + + FREE(olditem); + + /* Reinitialize measurements so as to avoid division by 0 and + ** immediate resizing. + */ + cache->lookUps = (double) (int) (slots * cache->minHit + 1); + cache->hits = 0; + +} /* end of cuddLocalCacheResize */ + + +/**Function******************************************************************** + + Synopsis [Computes the hash value for a local cache.] + + Description [Computes the hash value for a local cache. Returns the + bucket index.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static unsigned int +ddLCHash( + DdNodePtr * key, + unsigned int keysize, + int shift) +{ + unsigned int val = (unsigned int) (ptrint) key[0] * DD_P2; + unsigned int i; + + for (i = 1; i < keysize; i++) { + val = val * DD_P1 + (int) (ptrint) key[i]; + } + + return(val >> shift); + +} /* end of ddLCHash */ + + +/**Function******************************************************************** + + Synopsis [Inserts a local cache in the manager list.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +cuddLocalCacheAddToList( + DdLocalCache * cache) +{ + DdManager *manager = cache->manager; + + cache->next = manager->localCaches; + manager->localCaches = cache; + return; + +} /* end of cuddLocalCacheAddToList */ + + +/**Function******************************************************************** + + Synopsis [Removes a local cache from the manager list.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +cuddLocalCacheRemoveFromList( + DdLocalCache * cache) +{ + DdManager *manager = cache->manager; + DdLocalCache **prevCache, *nextCache; + + prevCache = &(manager->localCaches); + nextCache = manager->localCaches; + + while (nextCache != NULL) { + if (nextCache == cache) { + *prevCache = nextCache->next; + return; + } + prevCache = &(nextCache->next); + nextCache = nextCache->next; + } + return; /* should never get here */ + +} /* end of cuddLocalCacheRemoveFromList */ + + +/**Function******************************************************************** + + Synopsis [Resizes a hash table.] + + Description [Resizes a hash table. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert] + +******************************************************************************/ +static int +cuddHashTableResize( + DdHashTable * hash) +{ + int j; + unsigned int posn; + DdHashItem *item; + DdHashItem *next; + DdNode **key; + int numBuckets; + DdHashItem **buckets; + DdHashItem **oldBuckets = hash->bucket; + int shift; + int oldNumBuckets = hash->numBuckets; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + /* Compute the new size of the table. */ + numBuckets = oldNumBuckets << 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + buckets = ALLOC(DdHashItem *, numBuckets); + MMoutOfMemory = saveHandler; + if (buckets == NULL) { + hash->maxsize <<= 1; + return(1); + } + + hash->bucket = buckets; + hash->numBuckets = numBuckets; + shift = --(hash->shift); + hash->maxsize <<= 1; + memset(buckets, 0, numBuckets * sizeof(DdHashItem *)); + if (hash->keysize == 1) { + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash2(key[0], key[0], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + } else if (hash->keysize == 2) { + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash2(key[0], key[1], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + } else if (hash->keysize == 3) { + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash3(key[0], key[1], key[2], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + } else { + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + posn = ddLCHash(item->key, hash->keysize, shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + } + FREE(oldBuckets); + return(1); + +} /* end of cuddHashTableResize */ + + +/**Function******************************************************************** + + Synopsis [Fast storage allocation for items in a hash table.] + + Description [Fast storage allocation for items in a hash table. The + first 4 bytes of a chunk contain a pointer to the next block; the + rest contains DD_MEM_CHUNK spaces for hash items. Returns a pointer to + a new item if successful; NULL is memory is full.] + + SideEffects [None] + + SeeAlso [cuddAllocNode cuddDynamicAllocNode] + +******************************************************************************/ +DD_INLINE +static DdHashItem * +cuddHashTableAlloc( + DdHashTable * hash) +{ + int i; + unsigned int itemsize = hash->itemsize; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + DdHashItem **mem, *thisOne, *next, *item; + + if (hash->nextFree == NULL) { + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdHashItem **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); + MMoutOfMemory = saveHandler; + if (mem == NULL) { + if (hash->manager->stash != NULL) { + FREE(hash->manager->stash); + hash->manager->stash = NULL; + /* Inhibit resizing of tables. */ + hash->manager->maxCacheHard = hash->manager->cacheSlots - 1; + hash->manager->cacheSlack = - (int) (hash->manager->cacheSlots + 1); + for (i = 0; i < hash->manager->size; i++) { + hash->manager->subtables[i].maxKeys <<= 2; + } + hash->manager->gcFrac = 0.2; + hash->manager->minDead = + (unsigned) (0.2 * (double) hash->manager->slots); + mem = (DdHashItem **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); + } + if (mem == NULL) { + (*MMoutOfMemory)((long)((DD_MEM_CHUNK + 1) * itemsize)); + hash->manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + } + + mem[0] = (DdHashItem *) hash->memoryList; + hash->memoryList = mem; + + thisOne = (DdHashItem *) ((char *) mem + itemsize); + hash->nextFree = thisOne; + for (i = 1; i < DD_MEM_CHUNK; i++) { + next = (DdHashItem *) ((char *) thisOne + itemsize); + thisOne->next = next; + thisOne = next; + } + + thisOne->next = NULL; + + } + item = hash->nextFree; + hash->nextFree = item->next; + return(item); + +} /* end of cuddHashTableAlloc */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddLevelQ.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddLevelQ.c new file mode 100644 index 000000000..34f32c5b8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddLevelQ.c @@ -0,0 +1,583 @@ +/**CFile*********************************************************************** + + FileName [cuddLevelQ.c] + + PackageName [cudd] + + Synopsis [Procedure to manage level queues.] + + Description [The functions in this file allow an application to + easily manipulate a queue where nodes are prioritized by level. The + emphasis is on efficiency. Therefore, the queue items can have + variable size. If the application does not need to attach + information to the nodes, it can declare the queue items to be of + type DdQueueItem. Otherwise, it can declare them to be of a + structure type such that the first three fields are data + pointers. The third pointer points to the node. The first two + pointers are used by the level queue functions. The remaining fields + are initialized to 0 when a new item is created, and are then left + to the exclusive use of the application. On the DEC Alphas the three + pointers must be 32-bit pointers when CUDD is compiled with 32-bit + pointers. The level queue functions make sure that each node + appears at most once in the queue. They do so by keeping a hash + table where the node is used as key. Queue items are recycled via a + free list for efficiency. + + Internal procedures provided by this module: +
        +
      • cuddLevelQueueInit() +
      • cuddLevelQueueQuit() +
      • cuddLevelQueueEnqueue() +
      • cuddLevelQueueDequeue() +
      + Static procedures included in this module: +
        +
      • hashLookup() +
      • hashInsert() +
      • hashDelete() +
      • hashResize() +
      + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.16 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**Macro*********************************************************************** + + Synopsis [Hash function for the table of a level queue.] + + Description [Hash function for the table of a level queue.] + + SideEffects [None] + + SeeAlso [hashInsert hashLookup hashDelete] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define lqHash(key,shift) \ +(((unsigned)(ptruint)(key) * DD_P1) >> (shift)) +#else +#define lqHash(key,shift) \ +(((unsigned)(key) * DD_P1) >> (shift)) +#endif + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdQueueItem * hashLookup(DdLevelQueue *queue, void *key); +static int hashInsert(DdLevelQueue *queue, DdQueueItem *item); +static void hashDelete(DdLevelQueue *queue, DdQueueItem *item); +static int hashResize(DdLevelQueue *queue); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes a level queue.] + + Description [Initializes a level queue. A level queue is a queue + where inserts are based on the levels of the nodes. Within each + level the policy is FIFO. Level queues are useful in traversing a + BDD top-down. Queue items are kept in a free list when dequeued for + efficiency. Returns a pointer to the new queue if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueQuit cuddLevelQueueEnqueue cuddLevelQueueDequeue] + +******************************************************************************/ +DdLevelQueue * +cuddLevelQueueInit( + int levels /* number of levels */, + int itemSize /* size of the item */, + int numBuckets /* initial number of hash buckets */) +{ + DdLevelQueue *queue; + int logSize; + + queue = ALLOC(DdLevelQueue,1); + if (queue == NULL) + return(NULL); + /* Keep pointers to the insertion points for all levels. */ + queue->last = ALLOC(DdQueueItem *, levels); + if (queue->last == NULL) { + FREE(queue); + return(NULL); + } + /* Use a hash table to test for uniqueness. */ + if (numBuckets < 2) numBuckets = 2; + logSize = cuddComputeFloorLog2(numBuckets); + queue->numBuckets = 1 << logSize; + queue->shift = sizeof(int) * 8 - logSize; + queue->buckets = ALLOC(DdQueueItem *, queue->numBuckets); + if (queue->buckets == NULL) { + FREE(queue->last); + FREE(queue); + return(NULL); + } + memset(queue->last, 0, levels * sizeof(DdQueueItem *)); + memset(queue->buckets, 0, queue->numBuckets * sizeof(DdQueueItem *)); + queue->first = NULL; + queue->freelist = NULL; + queue->levels = levels; + queue->itemsize = itemSize; + queue->size = 0; + queue->maxsize = queue->numBuckets * DD_MAX_SUBTABLE_DENSITY; + return(queue); + +} /* end of cuddLevelQueueInit */ + + +/**Function******************************************************************** + + Synopsis [Shuts down a level queue.] + + Description [Shuts down a level queue and releases all the + associated memory.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueInit] + +******************************************************************************/ +void +cuddLevelQueueQuit( + DdLevelQueue * queue) +{ + DdQueueItem *item; + + while (queue->freelist != NULL) { + item = queue->freelist; + queue->freelist = item->next; + FREE(item); + } + while (queue->first != NULL) { + item = (DdQueueItem *) queue->first; + queue->first = item->next; + FREE(item); + } + FREE(queue->buckets); + FREE(queue->last); + FREE(queue); + return; + +} /* end of cuddLevelQueueQuit */ + + +/**Function******************************************************************** + + Synopsis [Inserts a new key in a level queue.] + + Description [Inserts a new key in a level queue. A new entry is + created in the queue only if the node is not already + enqueued. Returns a pointer to the queue item if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueInit cuddLevelQueueDequeue] + +******************************************************************************/ +void * +cuddLevelQueueEnqueue( + DdLevelQueue * queue /* level queue */, + void * key /* key to be enqueued */, + int level /* level at which to insert */) +{ + DdQueueItem *item; + +#ifdef DD_DEBUG + assert(level < queue->levels); +#endif + /* Check whether entry for this node exists. */ + item = hashLookup(queue,key); + if (item != NULL) return(item); + + /* Get a free item from either the free list or the memory manager. */ + if (queue->freelist == NULL) { + item = (DdQueueItem *) ALLOC(char, queue->itemsize); + if (item == NULL) + return(NULL); + } else { + item = queue->freelist; + queue->freelist = item->next; + } + /* Initialize. */ + memset(item, 0, queue->itemsize); + item->key = key; + /* Update stats. */ + queue->size++; + + if (queue->last[level]) { + /* There are already items for this level in the queue. */ + item->next = queue->last[level]->next; + queue->last[level]->next = item; + } else { + /* There are no items at the current level. Look for the first + ** non-empty level preceeding this one. */ + int plevel = level; + while (plevel != 0 && queue->last[plevel] == NULL) + plevel--; + if (queue->last[plevel] == NULL) { + /* No element precedes this one in the queue. */ + item->next = (DdQueueItem *) queue->first; + queue->first = item; + } else { + item->next = queue->last[plevel]->next; + queue->last[plevel]->next = item; + } + } + queue->last[level] = item; + + /* Insert entry for the key in the hash table. */ + if (hashInsert(queue,item) == 0) { + return(NULL); + } + return(item); + +} /* end of cuddLevelQueueEnqueue */ + + +/**Function******************************************************************** + + Synopsis [Inserts the first key in a level queue.] + + Description [Inserts the first key in a level queue. Returns a + pointer to the queue item if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueEnqueue] + +******************************************************************************/ +void * +cuddLevelQueueFirst( + DdLevelQueue * queue /* level queue */, + void * key /* key to be enqueued */, + int level /* level at which to insert */) +{ + DdQueueItem *item; + +#ifdef DD_DEBUG + assert(level < queue->levels); + /* Check whether entry for this node exists. */ + item = hashLookup(queue,key); + assert(item == NULL); +#endif + + /* Get a free item from either the free list or the memory manager. */ + if (queue->freelist == NULL) { + item = (DdQueueItem *) ALLOC(char, queue->itemsize); + if (item == NULL) + return(NULL); + } else { + item = queue->freelist; + queue->freelist = item->next; + } + /* Initialize. */ + memset(item, 0, queue->itemsize); + item->key = key; + /* Update stats. */ + queue->size = 1; + + /* No element precedes this one in the queue. */ + queue->first = item; + queue->last[level] = item; + + /* Insert entry for the key in the hash table. */ + if (hashInsert(queue,item) == 0) { + return(NULL); + } + return(item); + +} /* end of cuddLevelQueueFirst */ + + +/**Function******************************************************************** + + Synopsis [Remove an item from the front of a level queue.] + + Description [Remove an item from the front of a level queue.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueEnqueue] + +******************************************************************************/ +void +cuddLevelQueueDequeue( + DdLevelQueue * queue, + int level) +{ + DdQueueItem *item = (DdQueueItem *) queue->first; + + /* Delete from the hash table. */ + hashDelete(queue,item); + + /* Since we delete from the front, if this is the last item for + ** its level, there are no other items for the same level. */ + if (queue->last[level] == item) { + queue->last[level] = NULL; + } + + queue->first = item->next; + /* Put item on the free list. */ + item->next = queue->freelist; + queue->freelist = item; + /* Update stats. */ + queue->size--; + return; + +} /* end of cuddLevelQueueDequeue */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Looks up a key in the hash table of a level queue.] + + Description [Looks up a key in the hash table of a level queue. Returns + a pointer to the item with the given key if the key is found; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueEnqueue hashInsert] + +******************************************************************************/ +static DdQueueItem * +hashLookup( + DdLevelQueue * queue, + void * key) +{ + int posn; + DdQueueItem *item; + + posn = lqHash(key,queue->shift); + item = queue->buckets[posn]; + + while (item != NULL) { + if (item->key == key) { + return(item); + } + item = item->cnext; + } + return(NULL); + +} /* end of hashLookup */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in the hash table of a level queue.] + + Description [Inserts an item in the hash table of a level queue. Returns + 1 if successful; 0 otherwise. No check is performed to see if an item with + the same key is already in the hash table.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueEnqueue] + +******************************************************************************/ +static int +hashInsert( + DdLevelQueue * queue, + DdQueueItem * item) +{ + int result; + int posn; + + if (queue->size > queue->maxsize) { + result = hashResize(queue); + if (result == 0) return(0); + } + + posn = lqHash(item->key,queue->shift); + item->cnext = queue->buckets[posn]; + queue->buckets[posn] = item; + + return(1); + +} /* end of hashInsert */ + + +/**Function******************************************************************** + + Synopsis [Removes an item from the hash table of a level queue.] + + Description [Removes an item from the hash table of a level queue. + Nothing is done if the item is not in the table.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueDequeue hashInsert] + +******************************************************************************/ +static void +hashDelete( + DdLevelQueue * queue, + DdQueueItem * item) +{ + int posn; + DdQueueItem *prevItem; + + posn = lqHash(item->key,queue->shift); + prevItem = queue->buckets[posn]; + + if (prevItem == NULL) return; + if (prevItem == item) { + queue->buckets[posn] = prevItem->cnext; + return; + } + + while (prevItem->cnext != NULL) { + if (prevItem->cnext == item) { + prevItem->cnext = item->cnext; + return; + } + prevItem = prevItem->cnext; + } + return; + +} /* end of hashDelete */ + + +/**Function******************************************************************** + + Synopsis [Resizes the hash table of a level queue.] + + Description [Resizes the hash table of a level queue. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [hashInsert] + +******************************************************************************/ +static int +hashResize( + DdLevelQueue * queue) +{ + int j; + int posn; + DdQueueItem *item; + DdQueueItem *next; + int numBuckets; + DdQueueItem **buckets; + DdQueueItem **oldBuckets = queue->buckets; + int shift; + int oldNumBuckets = queue->numBuckets; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + /* Compute the new size of the subtable. */ + numBuckets = oldNumBuckets << 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + buckets = queue->buckets = ALLOC(DdQueueItem *, numBuckets); + MMoutOfMemory = saveHandler; + if (buckets == NULL) { + queue->maxsize <<= 1; + return(1); + } + + queue->numBuckets = numBuckets; + shift = --(queue->shift); + queue->maxsize <<= 1; + memset(buckets, 0, numBuckets * sizeof(DdQueueItem *)); + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->cnext; + posn = lqHash(item->key, shift); + item->cnext = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + FREE(oldBuckets); + return(1); + +} /* end of hashResize */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddLinear.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddLinear.c new file mode 100644 index 000000000..387989004 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddLinear.c @@ -0,0 +1,1365 @@ +/**CFile*********************************************************************** + + FileName [cuddLinear.c] + + PackageName [cudd] + + Synopsis [Functions for DD reduction by linear transformations.] + + Description [ Internal procedures included in this module: +
        +
      • cuddLinearAndSifting() +
      • cuddLinearInPlace() +
      • cuddUpdateInteractionMatrix() +
      • cuddInitLinear() +
      • cuddResizeLinear() +
      + Static procedures included in this module: +
        +
      • ddLinearUniqueCompare() +
      • ddLinearAndSiftingAux() +
      • ddLinearAndSiftingUp() +
      • ddLinearAndSiftingDown() +
      • ddLinearAndSiftingBackward() +
      • ddUndoMoves() +
      • cuddXorLinear() +
      ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define CUDD_SWAP_MOVE 0 +#define CUDD_LINEAR_TRANSFORM_MOVE 1 +#define CUDD_INVERSE_TRANSFORM_MOVE 2 +#if SIZEOF_LONG == 8 +#define BPL 64 +#define LOGBPL 6 +#else +#define BPL 32 +#define LOGBPL 5 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddLinear.c,v 1.29 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int *entry; + +#ifdef DD_STATS +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +static int ddTotalNumberLinearTr; +#endif + +#ifdef DD_DEBUG +static int zero = 0; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddLinearUniqueCompare (int *ptrX, int *ptrY); +static int ddLinearAndSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddLinearAndSiftingUp (DdManager *table, int y, int xLow, Move *prevMoves); +static Move * ddLinearAndSiftingDown (DdManager *table, int x, int xHigh, Move *prevMoves); +static int ddLinearAndSiftingBackward (DdManager *table, int size, Move *moves); +static Move* ddUndoMoves (DdManager *table, Move *moves); +static void cuddXorLinear (DdManager *table, int x, int y); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints the linear transform matrix.] + + Description [Prints the linear transform matrix. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_PrintLinear( + DdManager * table) +{ + int i,j,k; + int retval; + int nvars = table->linearSize; + int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + long word; + + for (i = 0; i < nvars; i++) { + for (j = 0; j < wordsPerRow; j++) { + word = table->linear[i*wordsPerRow + j]; + for (k = 0; k < BPL; k++) { + retval = fprintf(table->out,"%ld",word & 1); + if (retval == 0) return(0); + word >>= 1; + } + } + retval = fprintf(table->out,"\n"); + if (retval == 0) return(0); + } + return(1); + +} /* end of Cudd_PrintLinear */ + + +/**Function******************************************************************** + + Synopsis [Reads an entry of the linear transform matrix.] + + Description [Reads an entry of the linear transform matrix.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ReadLinear( + DdManager * table /* CUDD manager */, + int x /* row index */, + int y /* column index */) +{ + int nvars = table->size; + int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + long word; + int bit; + int result; + + assert(table->size == table->linearSize); + + word = wordsPerRow * x + (y >> LOGBPL); + bit = y & (BPL-1); + result = (int) ((table->linear[word] >> bit) & 1); + return(result); + +} /* end of Cudd_ReadLinear */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [BDD reduction based on combination of sifting and linear + transformations.] + + Description [BDD reduction based on combination of sifting and linear + transformations. Assumes that no dead nodes are present. +
        +
      1. Order all the variables according to the number of entries + in each unique table. +
      2. Sift the variable up and down, remembering each time the + total size of the DD heap. At each position, linear transformation + of the two adjacent variables is tried and is accepted if it reduces + the size of the DD. +
      3. Select the best permutation. +
      4. Repeat 3 and 4 for all variables. +
      + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddLinearAndSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; +#ifdef DD_STATS + int previousSize; +#endif + +#ifdef DD_STATS + ddTotalNumberLinearTr = 0; +#endif + + size = table->size; + + var = NULL; + entry = NULL; + if (table->linear == NULL) { + result = cuddInitLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; +#if 0 + (void) fprintf(table->out,"\n"); + result = Cudd_PrintLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; +#endif + } else if (table->size != table->linearSize) { + result = cuddResizeLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; +#if 0 + (void) fprintf(table->out,"\n"); + result = Cudd_PrintLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; +#endif + } + + /* Find order in which to sift variables. */ + entry = ALLOC(int,size); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddLinearAndSiftingOutOfMem; + } + var = ALLOC(int,size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddLinearAndSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; + } + + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddLinearUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { + x = table->perm[var[i]]; + if (x < lower || x > upper) continue; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddLinearAndSiftingAux(table,x,lower,upper); + if (!result) goto cuddLinearAndSiftingOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif +#ifdef DD_DEBUG + (void) Cudd_DebugCheck(table); +#endif + } + + FREE(var); + FREE(entry); + +#ifdef DD_STATS + (void) fprintf(table->out,"\n#:L_LINSIFT %8d: linear trans.", + ddTotalNumberLinearTr); +#endif + + return(1); + +cuddLinearAndSiftingOutOfMem: + + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddLinearAndSifting */ + + +/**Function******************************************************************** + + Synopsis [Linearly combines two adjacent variables.] + + Description [Linearly combines two adjacent variables. Specifically, + replaces the top variable with the exclusive nor of the two variables. + It assumes that no dead nodes are present on entry to this + procedure. The procedure then guarantees that no dead nodes will be + present when it terminates. cuddLinearInPlace assumes that x < + y. Returns the number of keys in the table if successful; 0 + otherwise.] + + SideEffects [The two subtables corrresponding to variables x and y are + modified. The global counters of the unique table are also affected.] + + SeeAlso [cuddSwapInPlace] + +******************************************************************************/ +int +cuddLinearInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int comple, newcomplement; + int i; + int posn; + int isolated; + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0; + DdNode *g,*next,*last; + DdNodePtr *previousP; + DdNode *tmp; + DdNode *sentinel = &(table->sentinel); +#ifdef DD_DEBUG + int count, idcheck; +#endif + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddNextHigh(table,x) == y); + assert(table->subtables[x].keys != 0); + assert(table->subtables[y].keys != 0); + assert(table->subtables[x].dead == 0); + assert(table->subtables[y].dead == 0); +#endif + + xindex = table->invperm[x]; + yindex = table->invperm[y]; + + if (cuddTestInteract(table,xindex,yindex)) { +#ifdef DD_STATS + ddTotalNumberLinearTr++; +#endif + /* Get parameters of x subtable. */ + xlist = table->subtables[x].nodelist; + oldxkeys = table->subtables[x].keys; + xslots = table->subtables[x].slots; + xshift = table->subtables[x].shift; + + /* Get parameters of y subtable. */ + ylist = table->subtables[y].nodelist; + oldykeys = table->subtables[y].keys; + yslots = table->subtables[y].slots; + yshift = table->subtables[y].shift; + + newxkeys = 0; + newykeys = oldykeys; + + /* Check whether the two projection functions involved in this + ** swap are isolated. At the end, we'll be able to tell how many + ** isolated projection functions are there by checking only these + ** two functions again. This is done to eliminate the isolated + ** projection functions from the node count. + */ + isolated = - ((table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1)); + + /* The nodes in the x layer are put in a chain. + ** The chain is handled as a FIFO; g points to the beginning and + ** last points to the end. + */ + g = NULL; +#ifdef DD_DEBUG + last = NULL; +#endif + for (i = 0; i < xslots; i++) { + f = xlist[i]; + if (f == sentinel) continue; + xlist[i] = sentinel; + if (g == NULL) { + g = f; + } else { + last->next = f; + } + while ((next = f->next) != sentinel) { + f = next; + } /* while there are elements in the collision chain */ + last = f; + } /* for each slot of the x subtable */ +#ifdef DD_DEBUG + /* last is always assigned in the for loop because there is at + ** least one key */ + assert(last != NULL); +#endif + last->next = NULL; + +#ifdef DD_COUNT + table->swapSteps += oldxkeys; +#endif + /* Take care of the x nodes that must be re-expressed. + ** They form a linked list pointed by g. + */ + f = g; + while (f != NULL) { + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f1))); +#endif + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = f10 = f1; + } +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f11))); +#endif + f0 = cuddE(f); + comple = Cudd_IsComplement(f0); + f0 = Cudd_Regular(f0); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == f00) { + newf1 = f11; + cuddSatInc(newf1->ref); + } else { + /* Check ylist for triple (yindex,f11,f00). */ + posn = ddHash(f11, f00, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + previousP = &(ylist[posn]); + newf1 = *previousP; + while (f11 < cuddT(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + while (f11 == cuddT(newf1) && f00 < cuddE(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + if (cuddT(newf1) == f11 && cuddE(newf1) == f00) { + cuddSatInc(newf1->ref); + } else { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto cuddLinearOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f00; + /* Insert newf1 in the collision list ylist[posn]; + ** increase the ref counts of f11 and f00. + */ + newykeys++; + newf1->next = *previousP; + *previousP = newf1; + cuddSatInc(f11->ref); + tmp = Cudd_Regular(f00); + cuddSatInc(tmp->ref); + } + } + cuddT(f) = newf1; +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(newf1))); +#endif + + /* Do the same for f0, keeping complement dots into account. */ + /* decrease ref count of f0 */ + tmp = Cudd_Regular(f0); + cuddSatDec(tmp->ref); + /* create the new E child */ + if (f01 == f10) { + newf0 = f01; + tmp = Cudd_Regular(newf0); + cuddSatInc(tmp->ref); + } else { + /* make sure f01 is regular */ + newcomplement = Cudd_IsComplement(f01); + if (newcomplement) { + f01 = Cudd_Not(f01); + f10 = Cudd_Not(f10); + } + /* Check ylist for triple (yindex,f01,f10). */ + posn = ddHash(f01, f10, yshift); + /* For each element newf0 in collision list ylist[posn]. */ + previousP = &(ylist[posn]); + newf0 = *previousP; + while (f01 < cuddT(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + while (f01 == cuddT(newf0) && f10 < cuddE(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + if (cuddT(newf0) == f01 && cuddE(newf0) == f10) { + cuddSatInc(newf0->ref); + } else { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto cuddLinearOutOfMem; + newf0->index = yindex; newf0->ref = 1; + cuddT(newf0) = f01; + cuddE(newf0) = f10; + /* Insert newf0 in the collision list ylist[posn]; + ** increase the ref counts of f01 and f10. + */ + newykeys++; + newf0->next = *previousP; + *previousP = newf0; + cuddSatInc(f01->ref); + tmp = Cudd_Regular(f10); + cuddSatInc(tmp->ref); + } + if (newcomplement) { + newf0 = Cudd_Not(newf0); + } + } + cuddE(f) = newf0; + + /* Re-insert the modified f in xlist. + ** The modified f does not already exists in xlist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, xshift); + newxkeys++; + previousP = &(xlist[posn]); + tmp = *previousP; + while (newf1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; + *previousP = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previousP = &(ylist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + if (f->ref == 0) { + tmp = cuddT(f); + cuddSatDec(tmp->ref); + tmp = Cudd_Regular(cuddE(f)); + cuddSatDec(tmp->ref); + cuddDeallocNode(table,f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = sentinel; + } /* for every collision list */ + +#ifdef DD_DEBUG +#if 0 + (void) fprintf(table->out,"Linearly combining %d and %d\n",x,y); +#endif + count = 0; + idcheck = 0; + for (i = 0; i < yslots; i++) { + f = ylist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) yindex) + idcheck++; + f = f->next; + } + } + if (count != newykeys) { + fprintf(table->err,"Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",oldykeys,newykeys,count); + } + if (idcheck != 0) + fprintf(table->err,"Error in id's of ylist\twrong id's = %d\n",idcheck); + count = 0; + idcheck = 0; + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) xindex) + idcheck++; + f = f->next; + } + } + if (count != newxkeys || newxkeys != oldxkeys) { + fprintf(table->err,"Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",oldxkeys,newxkeys,count); + } + if (idcheck != 0) + fprintf(table->err,"Error in id's of xlist\twrong id's = %d\n",idcheck); +#endif + + isolated += (table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1); + table->isolated += isolated; + + /* Set the appropriate fields in table. */ + table->subtables[y].keys = newykeys; + + /* Here we should update the linear combination table + ** to record that x <- x EXNOR y. This is done by complementing + ** the (x,y) entry of the table. + */ + + table->keys += newykeys - oldykeys; + + cuddXorLinear(table,xindex,yindex); + } + +#ifdef DD_DEBUG + if (zero) { + (void) Cudd_DebugCheck(table); + } +#endif + + return(table->keys - table->isolated); + +cuddLinearOutOfMem: + (void) fprintf(table->err,"Error: cuddLinearInPlace out of memory\n"); + + return (0); + +} /* end of cuddLinearInPlace */ + + +/**Function******************************************************************** + + Synopsis [Updates the interaction matrix.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +void +cuddUpdateInteractionMatrix( + DdManager * table, + int xindex, + int yindex) +{ + int i; + for (i = 0; i < yindex; i++) { + if (i != xindex && cuddTestInteract(table,i,yindex)) { + if (i < xindex) { + cuddSetInteract(table,i,xindex); + } else { + cuddSetInteract(table,xindex,i); + } + } + } + for (i = yindex+1; i < table->size; i++) { + if (i != xindex && cuddTestInteract(table,yindex,i)) { + if (i < xindex) { + cuddSetInteract(table,i,xindex); + } else { + cuddSetInteract(table,xindex,i); + } + } + } + +} /* end of cuddUpdateInteractionMatrix */ + + +/**Function******************************************************************** + + Synopsis [Initializes the linear transform matrix.] + + Description [Initializes the linear transform matrix. Returns 1 if + successful; 0 otherwise.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +cuddInitLinear( + DdManager * table) +{ + int words; + int wordsPerRow; + int nvars; + int word; + int bit; + int i; + long *linear; + + nvars = table->size; + wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + words = wordsPerRow * nvars; + table->linear = linear = ALLOC(long,words); + if (linear == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + table->memused += words * sizeof(long); + table->linearSize = nvars; + for (i = 0; i < words; i++) linear[i] = 0; + for (i = 0; i < nvars; i++) { + word = wordsPerRow * i + (i >> LOGBPL); + bit = i & (BPL-1); + linear[word] = 1 << bit; + } + return(1); + +} /* end of cuddInitLinear */ + + +/**Function******************************************************************** + + Synopsis [Resizes the linear transform matrix.] + + Description [Resizes the linear transform matrix. Returns 1 if + successful; 0 otherwise.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +cuddResizeLinear( + DdManager * table) +{ + int words,oldWords; + int wordsPerRow,oldWordsPerRow; + int nvars,oldNvars; + int word,oldWord; + int bit; + int i,j; + long *linear,*oldLinear; + + oldNvars = table->linearSize; + oldWordsPerRow = ((oldNvars - 1) >> LOGBPL) + 1; + oldWords = oldWordsPerRow * oldNvars; + oldLinear = table->linear; + + nvars = table->size; + wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + words = wordsPerRow * nvars; + table->linear = linear = ALLOC(long,words); + if (linear == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + table->memused += (words - oldWords) * sizeof(long); + for (i = 0; i < words; i++) linear[i] = 0; + + /* Copy old matrix. */ + for (i = 0; i < oldNvars; i++) { + for (j = 0; j < oldWordsPerRow; j++) { + oldWord = oldWordsPerRow * i + j; + word = wordsPerRow * i + j; + linear[word] = oldLinear[oldWord]; + } + } + FREE(oldLinear); + + /* Add elements to the diagonal. */ + for (i = oldNvars; i < nvars; i++) { + word = wordsPerRow * i + (i >> LOGBPL); + bit = i & (BPL-1); + linear[word] = 1 << bit; + } + table->linearSize = nvars; + + return(1); + +} /* end of cuddResizeLinear */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + +******************************************************************************/ +static int +ddLinearUniqueCompare( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of ddLinearUniqueCompare */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. At each step a linear transformation is tried, and, if it + decreases the size of the DD, it is accepted. Finds the best position + and does the required changes. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddLinearAndSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; + + initialSize = table->keys - table->isolated; + + moveDown = NULL; + moveUp = NULL; + + if (x == xLow) { + moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; + + } else if (x == xHigh) { + moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + moveUp = ddUndoMoves(table,moveDown); +#ifdef DD_DEBUG + assert(moveUp == NULL || moveUp->x == x); +#endif + moveUp = ddLinearAndSiftingUp(table,x,xLow,moveUp); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; + + } else { /* must go up first: shorter */ + moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + moveDown = ddUndoMoves(table,moveUp); +#ifdef DD_DEBUG + assert(moveDown == NULL || moveDown->y == x); +#endif + moveDown = ddLinearAndSiftingDown(table,x,xHigh,moveDown); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +ddLinearAndSiftingAuxOutOfMem: + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(0); + +} /* end of ddLinearAndSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable up and applies linear transformations.] + + Description [Sifts a variable up and applies linear transformations. + Moves y up until either it reaches the bound (xLow) or the size of + the DD heap increases too much. Returns the set of moves in case of + success; NULL if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddLinearAndSiftingUp( + DdManager * table, + int y, + int xLow, + Move * prevMoves) +{ + Move *moves; + Move *move; + int x; + int size, newsize; + int limitSize; + int xindex, yindex; + int isolated; + int L; /* lower bound on DD size */ +#ifdef DD_DEBUG + int checkL; + int z; + int zindex; +#endif + + moves = prevMoves; + yindex = table->invperm[y]; + + /* Initialize the lower bound. + ** The part of the DD below y will not change. + ** The part of the DD above y that does not interact with y will not + ** change. The rest may vanish in the best case, except for + ** the nodes at level xLow, which will not vanish, regardless. + */ + limitSize = L = table->keys - table->isolated; + for (x = xLow + 1; x < y; x++) { + xindex = table->invperm[x]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L -= table->subtables[x].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + L -= table->subtables[y].keys - isolated; + + x = cuddNextLow(table,y); + while (x >= xLow && L <= limitSize) { + xindex = table->invperm[x]; +#ifdef DD_DEBUG + checkL = table->keys - table->isolated; + for (z = xLow + 1; z < y; z++) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + checkL -= table->subtables[y].keys - isolated; + if (L != checkL) { + (void) fprintf(table->out, "checkL(%d) != L(%d)\n",checkL,L); + } +#endif + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddLinearAndSiftingUpOutOfMem; + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddLinearAndSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize >= size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem; +#ifdef DD_DEBUG + if (newsize != size) { + (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } +#endif + } else if (cuddTestInteract(table,xindex,yindex)) { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + cuddUpdateInteractionMatrix(table,xindex,yindex); + } + move->size = size; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + y = x; + x = cuddNextLow(table,y); + } + return(moves); + +ddLinearAndSiftingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddLinearAndSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable down and applies linear transformations.] + + Description [Sifts a variable down and applies linear + transformations. Moves x down until either it reaches the bound + (xHigh) or the size of the DD heap increases too much. Returns the + set of moves in case of success; NULL if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddLinearAndSiftingDown( + DdManager * table, + int x, + int xHigh, + Move * prevMoves) +{ + Move *moves; + Move *move; + int y; + int size, newsize; + int R; /* upper bound on node decrease */ + int limitSize; + int xindex, yindex; + int isolated; +#ifdef DD_DEBUG + int checkR; + int z; + int zindex; +#endif + + moves = prevMoves; + /* Initialize R */ + xindex = table->invperm[x]; + limitSize = size = table->keys - table->isolated; + R = 0; + for (y = xHigh; y > x; y--) { + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R += table->subtables[y].keys - isolated; + } + } + + y = cuddNextHigh(table,x); + while (y <= xHigh && size - R < limitSize) { +#ifdef DD_DEBUG + checkR = 0; + for (z = xHigh; z > x; z--) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + if (R != checkR) { + (void) fprintf(table->out, "checkR(%d) != R(%d)\n",checkR,R); + } +#endif + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddLinearAndSiftingDownOutOfMem; + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddLinearAndSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize >= size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem; + if (newsize != size) { + (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } + } else if (cuddTestInteract(table,xindex,yindex)) { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + cuddUpdateInteractionMatrix(table,xindex,yindex); + } + move->size = size; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + x = y; + y = cuddNextHigh(table,x); + } + return(moves); + +ddLinearAndSiftingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddLinearAndSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the DD heap to the order + giving the minimum size.] + + Description [Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddLinearAndSiftingBackward( + DdManager * table, + int size, + Move * moves) +{ + Move *move; + int res; + + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + res = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { + res = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + } + + return(1); + +} /* end of ddLinearAndSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the DD heap to the order + in effect before the moves.] + + Description [Given a set of moves, returns the DD heap to the + order in effect before the moves. Returns 1 in case of success; + 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static Move* +ddUndoMoves( + DdManager * table, + Move * moves) +{ + Move *invmoves = NULL; + Move *move; + Move *invmove; + int size; + + for (move = moves; move != NULL; move = move->next) { + invmove = (Move *) cuddDynamicAllocNode(table); + if (invmove == NULL) goto ddUndoMovesOutOfMem; + invmove->x = move->x; + invmove->y = move->y; + invmove->next = invmoves; + invmoves = invmove; + if (move->flags == CUDD_SWAP_MOVE) { + invmove->flags = CUDD_SWAP_MOVE; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; + size = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ +#ifdef DD_DEBUG + (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); +#endif + invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + size = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } + invmove->size = size; + } + + return(invmoves); + +ddUndoMovesOutOfMem: + while (invmoves != NULL) { + move = invmoves->next; + cuddDeallocMove(table, invmoves); + invmoves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddUndoMoves */ + + +/**Function******************************************************************** + + Synopsis [XORs two rows of the linear transform matrix.] + + Description [XORs two rows of the linear transform matrix and replaces + the first row with the result.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static void +cuddXorLinear( + DdManager * table, + int x, + int y) +{ + int i; + int nvars = table->size; + int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + int xstart = wordsPerRow * x; + int ystart = wordsPerRow * y; + long *linear = table->linear; + + for (i = 0; i < wordsPerRow; i++) { + linear[xstart+i] ^= linear[ystart+i]; + } + +} /* end of cuddXorLinear */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddLiteral.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddLiteral.c new file mode 100644 index 000000000..b81697028 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddLiteral.c @@ -0,0 +1,264 @@ +/**CFile*********************************************************************** + + FileName [cuddLiteral.c] + + PackageName [cudd] + + Synopsis [Functions for manipulation of literal sets represented by + BDDs.] + + Description [External procedures included in this file: +
        +
      • Cudd_bddLiteralSetIntersection() +
      + Internal procedures included in this file: +
        +
      • cuddBddLiteralSetIntersectionRecur() +
      ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddLiteral.c,v 1.9 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the intesection of two sets of literals + represented as BDDs.] + + Description [Computes the intesection of two sets of literals + represented as BDDs. Each set is represented as a cube of the + literals in the set. The empty set is represented by the constant 1. + No variable can be simultaneously present in both phases in a set. + Returns a pointer to the BDD representing the intersected sets, if + successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_bddLiteralSetIntersection( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddLiteralSetIntersectionRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddLiteralSetIntersection */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of + Cudd_bddLiteralSetIntersection.] + + Description [Performs the recursive step of + Cudd_bddLiteralSetIntersection. Scans the cubes for common variables, + and checks whether they agree in phase. Returns a pointer to the + resulting cube if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddBddLiteralSetIntersectionRecur( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res, *tmp; + DdNode *F, *G; + DdNode *fc, *gc; + DdNode *one; + DdNode *zero; + unsigned int topf, topg, comple; + int phasef, phaseg; + + statLine(dd); + if (f == g) return(f); + + F = Cudd_Regular(f); + G = Cudd_Regular(g); + one = DD_ONE(dd); + + /* Here f != g. If F == G, then f and g are complementary. + ** Since they are two cubes, this case only occurs when f == v, + ** g == v', and v is a variable or its complement. + */ + if (F == G) return(one); + + zero = Cudd_Not(one); + topf = cuddI(dd,F->index); + topg = cuddI(dd,G->index); + /* Look for a variable common to both cubes. If there are none, this + ** loop will stop when the constant node is reached in both cubes. + */ + while (topf != topg) { + if (topf < topg) { /* move down on f */ + comple = f != F; + f = cuddT(F); + if (comple) f = Cudd_Not(f); + if (f == zero) { + f = cuddE(F); + if (comple) f = Cudd_Not(f); + } + F = Cudd_Regular(f); + topf = cuddI(dd,F->index); + } else if (topg < topf) { + comple = g != G; + g = cuddT(G); + if (comple) g = Cudd_Not(g); + if (g == zero) { + g = cuddE(G); + if (comple) g = Cudd_Not(g); + } + G = Cudd_Regular(g); + topg = cuddI(dd,G->index); + } + } + + /* At this point, f == one <=> g == 1. It suffices to test one of them. */ + if (f == one) return(one); + + res = cuddCacheLookup2(dd,Cudd_bddLiteralSetIntersection,f,g); + if (res != NULL) { + return(res); + } + + /* Here f and g are both non constant and have the same top variable. */ + comple = f != F; + fc = cuddT(F); + phasef = 1; + if (comple) fc = Cudd_Not(fc); + if (fc == zero) { + fc = cuddE(F); + phasef = 0; + if (comple) fc = Cudd_Not(fc); + } + comple = g != G; + gc = cuddT(G); + phaseg = 1; + if (comple) gc = Cudd_Not(gc); + if (gc == zero) { + gc = cuddE(G); + phaseg = 0; + if (comple) gc = Cudd_Not(gc); + } + + tmp = cuddBddLiteralSetIntersectionRecur(dd,fc,gc); + if (tmp == NULL) { + return(NULL); + } + + if (phasef != phaseg) { + res = tmp; + } else { + cuddRef(tmp); + if (phasef == 0) { + res = cuddBddAndRecur(dd,Cudd_Not(dd->vars[F->index]),tmp); + } else { + res = cuddBddAndRecur(dd,dd->vars[F->index],tmp); + } + if (res == NULL) { + Cudd_RecursiveDeref(dd,tmp); + return(NULL); + } + cuddDeref(tmp); /* Just cuddDeref, because it is included in result */ + } + + cuddCacheInsert2(dd,Cudd_bddLiteralSetIntersection,f,g,res); + + return(res); + +} /* end of cuddBddLiteralSetIntersectionRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddMatMult.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddMatMult.c new file mode 100644 index 000000000..adcbdc79f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddMatMult.c @@ -0,0 +1,707 @@ +/**CFile*********************************************************************** + + FileName [cuddMatMult.c] + + PackageName [cudd] + + Synopsis [Matrix multiplication functions.] + + Description [External procedures included in this module: +
        +
      • Cudd_addMatrixMultiply() +
      • Cudd_addTimesPlus() +
      • Cudd_addTriangle() +
      • Cudd_addOuterSum() +
      + Static procedures included in this module: +
        +
      • addMMRecur() +
      • addTriangleRecur() +
      • cuddAddOuterSumRecur() +
      ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.18 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addMMRecur (DdManager *dd, DdNode *A, DdNode *B, int topP, int *vars); +static DdNode * addTriangleRecur (DdManager *dd, DdNode *f, DdNode *g, int *vars, DdNode *cube); +static DdNode * cuddAddOuterSumRecur (DdManager *dd, DdNode *M, DdNode *r, DdNode *c); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Calculates the product of two matrices represented as + ADDs.] + + Description [Calculates the product of two matrices, A and B, + represented as ADDs. This procedure implements the quasiring multiplication + algorithm. A is assumed to depend on variables x (rows) and z + (columns). B is assumed to depend on variables z (rows) and y + (columns). The product of A and B then depends on x (rows) and y + (columns). Only the z variables have to be explicitly identified; + they are the "summation" variables. Returns a pointer to the + result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addTimesPlus Cudd_addTriangle Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_addMatrixMultiply( + DdManager * dd, + DdNode * A, + DdNode * B, + DdNode ** z, + int nz) +{ + int i, nvars, *vars; + DdNode *res; + + /* Array vars says what variables are "summation" variables. */ + nvars = dd->size; + vars = ALLOC(int,nvars); + if (vars == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < nvars; i++) { + vars[i] = 0; + } + for (i = 0; i < nz; i++) { + vars[z[i]->index] = 1; + } + + do { + dd->reordered = 0; + res = addMMRecur(dd,A,B,-1,vars); + } while (dd->reordered == 1); + FREE(vars); + return(res); + +} /* end of Cudd_addMatrixMultiply */ + + +/**Function******************************************************************** + + Synopsis [Calculates the product of two matrices represented as + ADDs.] + + Description [Calculates the product of two matrices, A and B, + represented as ADDs, using the CMU matrix by matrix multiplication + procedure by Clarke et al.. Matrix A has x's as row variables and z's + as column variables, while matrix B has z's as row variables and y's + as column variables. Returns the pointer to the result if successful; + NULL otherwise. The resulting matrix has x's as row variables and y's + as column variables.] + + SideEffects [None] + + SeeAlso [Cudd_addMatrixMultiply] + +******************************************************************************/ +DdNode * +Cudd_addTimesPlus( + DdManager * dd, + DdNode * A, + DdNode * B, + DdNode ** z, + int nz) +{ + DdNode *w, *cube, *tmp, *res; + int i; + tmp = Cudd_addApply(dd,Cudd_addTimes,A,B); + if (tmp == NULL) return(NULL); + Cudd_Ref(tmp); + Cudd_Ref(cube = DD_ONE(dd)); + for (i = nz-1; i >= 0; i--) { + w = Cudd_addIte(dd,z[i],cube,DD_ZERO(dd)); + if (w == NULL) { + Cudd_RecursiveDeref(dd,tmp); + return(NULL); + } + Cudd_Ref(w); + Cudd_RecursiveDeref(dd,cube); + cube = w; + } + res = Cudd_addExistAbstract(dd,tmp,cube); + if (res == NULL) { + Cudd_RecursiveDeref(dd,tmp); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + Cudd_Ref(res); + Cudd_RecursiveDeref(dd,cube); + Cudd_RecursiveDeref(dd,tmp); + Cudd_Deref(res); + return(res); + +} /* end of Cudd_addTimesPlus */ + + +/**Function******************************************************************** + + Synopsis [Performs the triangulation step for the shortest path + computation.] + + Description [Implements the semiring multiplication algorithm used in + the triangulation step for the shortest path computation. f + is assumed to depend on variables x (rows) and z (columns). g is + assumed to depend on variables z (rows) and y (columns). The product + of f and g then depends on x (rows) and y (columns). Only the z + variables have to be explicitly identified; they are the + "abstraction" variables. Returns a pointer to the result if + successful; NULL otherwise. ] + + SideEffects [None] + + SeeAlso [Cudd_addMatrixMultiply Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_addTriangle( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode ** z, + int nz) +{ + int i, nvars, *vars; + DdNode *res, *cube; + + nvars = dd->size; + vars = ALLOC(int, nvars); + if (vars == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < nvars; i++) vars[i] = -1; + for (i = 0; i < nz; i++) vars[z[i]->index] = i; + cube = Cudd_addComputeCube(dd, z, NULL, nz); + if (cube == NULL) { + FREE(vars); + return(NULL); + } + cuddRef(cube); + + do { + dd->reordered = 0; + res = addTriangleRecur(dd, f, g, vars, cube); + } while (dd->reordered == 1); + if (res != NULL) cuddRef(res); + Cudd_RecursiveDeref(dd,cube); + if (res != NULL) cuddDeref(res); + FREE(vars); + return(res); + +} /* end of Cudd_addTriangle */ + + +/**Function******************************************************************** + + Synopsis [Takes the minimum of a matrix and the outer sum of two vectors.] + + Description [Takes the pointwise minimum of a matrix and the outer + sum of two vectors. This procedure is used in the Floyd-Warshall + all-pair shortest path algorithm. Returns a pointer to the result if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addOuterSum( + DdManager *dd, + DdNode *M, + DdNode *r, + DdNode *c) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddOuterSumRecur(dd, M, r, c); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addOuterSum */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addMatrixMultiply.] + + Description [Performs the recursive step of Cudd_addMatrixMultiply. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +addMMRecur( + DdManager * dd, + DdNode * A, + DdNode * B, + int topP, + int * vars) +{ + DdNode *zero, + *At, /* positive cofactor of first operand */ + *Ae, /* negative cofactor of first operand */ + *Bt, /* positive cofactor of second operand */ + *Be, /* negative cofactor of second operand */ + *t, /* positive cofactor of result */ + *e, /* negative cofactor of result */ + *scaled, /* scaled result */ + *add_scale, /* ADD representing the scaling factor */ + *res; + int i; /* loop index */ + double scale; /* scaling factor */ + int index; /* index of the top variable */ + CUDD_VALUE_TYPE value; + unsigned int topA, topB, topV; + DD_CTFP cacheOp; + + statLine(dd); + zero = DD_ZERO(dd); + + if (A == zero || B == zero) { + return(zero); + } + + if (cuddIsConstant(A) && cuddIsConstant(B)) { + /* Compute the scaling factor. It is 2^k, where k is the + ** number of summation variables below the current variable. + ** Indeed, these constants represent blocks of 2^k identical + ** constant values in both A and B. + */ + value = cuddV(A) * cuddV(B); + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP) { + value *= (CUDD_VALUE_TYPE) 2; + } + } + } + res = cuddUniqueConst(dd, value); + return(res); + } + + /* Standardize to increase cache efficiency. Clearly, A*B != B*A + ** in matrix multiplication. However, which matrix is which is + ** determined by the variables appearing in the ADDs and not by + ** which one is passed as first argument. + */ + if (A > B) { + DdNode *tmp = A; + A = B; + B = tmp; + } + + topA = cuddI(dd,A->index); topB = cuddI(dd,B->index); + topV = ddMin(topA,topB); + + cacheOp = (DD_CTFP) addMMRecur; + res = cuddCacheLookup2(dd,cacheOp,A,B); + if (res != NULL) { + /* If the result is 0, there is no need to normalize. + ** Otherwise we count the number of z variables between + ** the current depth and the top of the ADDs. These are + ** the missing variables that determine the size of the + ** constant blocks. + */ + if (res == zero) return(res); + scale = 1.0; + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { + scale *= 2; + } + } + } + if (scale > 1.0) { + cuddRef(res); + add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); + if (add_scale == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(add_scale); + scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); + if (scaled == NULL) { + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(scaled); + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + res = scaled; + cuddDeref(res); + } + return(res); + } + + /* compute the cofactors */ + if (topV == topA) { + At = cuddT(A); + Ae = cuddE(A); + } else { + At = Ae = A; + } + if (topV == topB) { + Bt = cuddT(B); + Be = cuddE(B); + } else { + Bt = Be = B; + } + + t = addMMRecur(dd, At, Bt, (int)topV, vars); + if (t == NULL) return(NULL); + cuddRef(t); + e = addMMRecur(dd, Ae, Be, (int)topV, vars); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + index = dd->invperm[topV]; + if (vars[index] == 0) { + /* We have split on either the rows of A or the columns + ** of B. We just need to connect the two subresults, + ** which correspond to two submatrices of the result. + */ + res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); + cuddDeref(t); + cuddDeref(e); + } else { + /* we have simultaneously split on the columns of A and + ** the rows of B. The two subresults must be added. + */ + res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + } + + cuddCacheInsert2(dd,cacheOp,A,B,res); + + /* We have computed (and stored in the computed table) a minimal + ** result; that is, a result that assumes no summation variables + ** between the current depth of the recursion and its top + ** variable. We now take into account the z variables by properly + ** scaling the result. + */ + if (res != zero) { + scale = 1.0; + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { + scale *= 2; + } + } + } + if (scale > 1.0) { + add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); + if (add_scale == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(add_scale); + scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); + if (scaled == NULL) { + Cudd_RecursiveDeref(dd, res); + Cudd_RecursiveDeref(dd, add_scale); + return(NULL); + } + cuddRef(scaled); + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + res = scaled; + } + } + cuddDeref(res); + return(res); + +} /* end of addMMRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addTriangle.] + + Description [Performs the recursive step of Cudd_addTriangle. Returns + a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +addTriangleRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + int * vars, + DdNode *cube) +{ + DdNode *fv, *fvn, *gv, *gvn, *t, *e, *res; + CUDD_VALUE_TYPE value; + int top, topf, topg, index; + + statLine(dd); + if (f == DD_PLUS_INFINITY(dd) || g == DD_PLUS_INFINITY(dd)) { + return(DD_PLUS_INFINITY(dd)); + } + + if (cuddIsConstant(f) && cuddIsConstant(g)) { + value = cuddV(f) + cuddV(g); + res = cuddUniqueConst(dd, value); + return(res); + } + if (f < g) { + DdNode *tmp = f; + f = g; + g = tmp; + } + + if (f->ref != 1 || g->ref != 1) { + res = cuddCacheLookup(dd, DD_ADD_TRIANGLE_TAG, f, g, cube); + if (res != NULL) { + return(res); + } + } + + topf = cuddI(dd,f->index); topg = cuddI(dd,g->index); + top = ddMin(topf,topg); + + if (top == topf) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;} + if (top == topg) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;} + + t = addTriangleRecur(dd, fv, gv, vars, cube); + if (t == NULL) return(NULL); + cuddRef(t); + e = addTriangleRecur(dd, fvn, gvn, vars, cube); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + index = dd->invperm[top]; + if (vars[index] < 0) { + res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } else { + res = cuddAddApplyRecur(dd,Cudd_addMinimum,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + cuddDeref(res); + } + + if (f->ref != 1 || g->ref != 1) { + cuddCacheInsert(dd, DD_ADD_TRIANGLE_TAG, f, g, cube, res); + } + + return(res); + +} /* end of addTriangleRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addOuterSum.] + + Description [Performs the recursive step of Cudd_addOuterSum. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddOuterSumRecur( + DdManager *dd, + DdNode *M, + DdNode *r, + DdNode *c) +{ + DdNode *P, *R, *Mt, *Me, *rt, *re, *ct, *ce, *Rt, *Re; + int topM, topc, topr; + int v, index; + + statLine(dd); + /* Check special cases. */ + if (r == DD_PLUS_INFINITY(dd) || c == DD_PLUS_INFINITY(dd)) return(M); + + if (cuddIsConstant(c) && cuddIsConstant(r)) { + R = cuddUniqueConst(dd,Cudd_V(c)+Cudd_V(r)); + cuddRef(R); + if (cuddIsConstant(M)) { + if (cuddV(R) <= cuddV(M)) { + cuddDeref(R); + return(R); + } else { + Cudd_RecursiveDeref(dd,R); + return(M); + } + } else { + P = Cudd_addApply(dd,Cudd_addMinimum,R,M); + cuddRef(P); + Cudd_RecursiveDeref(dd,R); + cuddDeref(P); + return(P); + } + } + + /* Check the cache. */ + R = cuddCacheLookup(dd,DD_ADD_OUT_SUM_TAG,M,r,c); + if (R != NULL) return(R); + + topM = cuddI(dd,M->index); topr = cuddI(dd,r->index); + topc = cuddI(dd,c->index); + v = ddMin(topM,ddMin(topr,topc)); + + /* Compute cofactors. */ + if (topM == v) { Mt = cuddT(M); Me = cuddE(M); } else { Mt = Me = M; } + if (topr == v) { rt = cuddT(r); re = cuddE(r); } else { rt = re = r; } + if (topc == v) { ct = cuddT(c); ce = cuddE(c); } else { ct = ce = c; } + + /* Recursively solve. */ + Rt = cuddAddOuterSumRecur(dd,Mt,rt,ct); + if (Rt == NULL) return(NULL); + cuddRef(Rt); + Re = cuddAddOuterSumRecur(dd,Me,re,ce); + if (Re == NULL) { + Cudd_RecursiveDeref(dd, Rt); + return(NULL); + } + cuddRef(Re); + index = dd->invperm[v]; + R = (Rt == Re) ? Rt : cuddUniqueInter(dd,index,Rt,Re); + if (R == NULL) { + Cudd_RecursiveDeref(dd, Rt); + Cudd_RecursiveDeref(dd, Re); + return(NULL); + } + cuddDeref(Rt); + cuddDeref(Re); + + /* Store the result in the cache. */ + cuddCacheInsert(dd,DD_ADD_OUT_SUM_TAG,M,r,c,R); + + return(R); + +} /* end of cuddAddOuterSumRecur */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddPriority.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddPriority.c new file mode 100644 index 000000000..2b59adca2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddPriority.c @@ -0,0 +1,2027 @@ +/**CFile*********************************************************************** + + FileName [cuddPriority.c] + + PackageName [cudd] + + Synopsis [Priority functions.] + + Description [External procedures included in this file: +
        +
      • Cudd_PrioritySelect() +
      • Cudd_Xgty() +
      • Cudd_Xeqy() +
      • Cudd_addXeqy() +
      • Cudd_Dxygtdxz() +
      • Cudd_Dxygtdyz() +
      • Cudd_Inequality() +
      • Cudd_Disequality() +
      • Cudd_bddInterval() +
      • Cudd_CProjection() +
      • Cudd_addHamming() +
      • Cudd_MinHammingDist() +
      • Cudd_bddClosestCube() +
      + Internal procedures included in this module: +
        +
      • cuddCProjectionRecur() +
      • cuddBddClosestCube() +
      + Static procedures included in this module: +
        +
      • cuddMinHammingDistRecur() +
      • separateCube() +
      • createResult() +
      + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_DEBUG 1 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddPriority.c,v 1.36 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ +static int cuddMinHammingDistRecur (DdNode * f, int *minterm, DdHashTable * table, int upperBound); +static DdNode * separateCube (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE *distance); +static DdNode * createResult (DdManager *dd, unsigned int index, unsigned int phase, DdNode *cube, CUDD_VALUE_TYPE distance); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Selects pairs from R using a priority function.] + + Description [Selects pairs from a relation R(x,y) (given as a BDD) + in such a way that a given x appears in one pair only. Uses a + priority function to determine which y should be paired to a given x. + Cudd_PrioritySelect returns a pointer to + the selected function if successful; NULL otherwise. + Three of the arguments--x, y, and z--are vectors of BDD variables. + The first two are the variables on which R depends. The third vector + is a vector of auxiliary variables, used during the computation. This + vector is optional. If a NULL value is passed instead, + Cudd_PrioritySelect will create the working variables on the fly. + The sizes of x and y (and z if it is not NULL) should equal n. + The priority function Pi can be passed as a BDD, or can be built by + Cudd_PrioritySelect. If NULL is passed instead of a DdNode *, + parameter Pifunc is used by Cudd_PrioritySelect to build a BDD for the + priority function. (Pifunc is a pointer to a C function.) If Pi is not + NULL, then Pifunc is ignored. Pifunc should have the same interface as + the standard priority functions (e.g., Cudd_Dxygtdxz). + Cudd_PrioritySelect and Cudd_CProjection can sometimes be used + interchangeably. Specifically, calling Cudd_PrioritySelect with + Cudd_Xgty as Pifunc produces the same result as calling + Cudd_CProjection with the all-zero minterm as reference minterm. + However, depending on the application, one or the other may be + preferable: +
        +
      • When extracting representatives from an equivalence relation, + Cudd_CProjection has the advantage of nor requiring the auxiliary + variables. +
      • When computing matchings in general bipartite graphs, + Cudd_PrioritySelect normally obtains better results because it can use + more powerful matching schemes (e.g., Cudd_Dxygtdxz). +
      + ] + + SideEffects [If called with z == NULL, will create new variables in + the manager.] + + SeeAlso [Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_Xgty + Cudd_bddAdjPermuteX Cudd_CProjection] + +******************************************************************************/ +DdNode * +Cudd_PrioritySelect( + DdManager * dd /* manager */, + DdNode * R /* BDD of the relation */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */, + DdNode ** z /* array of z variables (optional: may be NULL) */, + DdNode * Pi /* BDD of the priority function (optional: may be NULL) */, + int n /* size of x, y, and z */, + DD_PRFP Pifunc /* function used to build Pi if it is NULL */) +{ + DdNode *res = NULL; + DdNode *zcube = NULL; + DdNode *Rxz, *Q; + int createdZ = 0; + int createdPi = 0; + int i; + + /* Create z variables if needed. */ + if (z == NULL) { + if (Pi != NULL) return(NULL); + z = ALLOC(DdNode *,n); + if (z == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + createdZ = 1; + for (i = 0; i < n; i++) { + if (dd->size >= (int) CUDD_MAXINDEX - 1) goto endgame; + z[i] = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); + if (z[i] == NULL) goto endgame; + } + } + + /* Create priority function BDD if needed. */ + if (Pi == NULL) { + Pi = Pifunc(dd,n,x,y,z); + if (Pi == NULL) goto endgame; + createdPi = 1; + cuddRef(Pi); + } + + /* Initialize abstraction cube. */ + zcube = DD_ONE(dd); + cuddRef(zcube); + for (i = n - 1; i >= 0; i--) { + DdNode *tmpp; + tmpp = Cudd_bddAnd(dd,z[i],zcube); + if (tmpp == NULL) goto endgame; + cuddRef(tmpp); + Cudd_RecursiveDeref(dd,zcube); + zcube = tmpp; + } + + /* Compute subset of (x,y) pairs. */ + Rxz = Cudd_bddSwapVariables(dd,R,y,z,n); + if (Rxz == NULL) goto endgame; + cuddRef(Rxz); + Q = Cudd_bddAndAbstract(dd,Rxz,Pi,zcube); + if (Q == NULL) { + Cudd_RecursiveDeref(dd,Rxz); + goto endgame; + } + cuddRef(Q); + Cudd_RecursiveDeref(dd,Rxz); + res = Cudd_bddAnd(dd,R,Cudd_Not(Q)); + if (res == NULL) { + Cudd_RecursiveDeref(dd,Q); + goto endgame; + } + cuddRef(res); + Cudd_RecursiveDeref(dd,Q); + +endgame: + if (zcube != NULL) Cudd_RecursiveDeref(dd,zcube); + if (createdZ) { + FREE(z); + } + if (createdPi) { + Cudd_RecursiveDeref(dd,Pi); + } + if (res != NULL) cuddDeref(res); + return(res); + +} /* Cudd_PrioritySelect */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function x > y.] + + Description [This function generates a BDD for the function x > y. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has 3*N-1 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. + Argument z is not used by Cudd_Xgty: it is included to make it + call-compatible to Cudd_Dxygtdxz and Cudd_Dxygtdyz.] + + SideEffects [None] + + SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Dxygtdyz] + +******************************************************************************/ +DdNode * +Cudd_Xgty( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + DdNode ** z /* array of z variables: unused */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + DdNode *u, *v, *w; + int i; + + /* Build bottom part of BDD outside loop. */ + u = Cudd_bddAnd(dd, x[N-1], Cudd_Not(y[N-1])); + if (u == NULL) return(NULL); + cuddRef(u); + + /* Loop to build the rest of the BDD. */ + for (i = N-2; i >= 0; i--) { + v = Cudd_bddAnd(dd, y[i], Cudd_Not(u)); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, u); + u = Cudd_bddIte(dd, x[i], Cudd_Not(v), w); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + + } + cuddDeref(u); + return(u); + +} /* end of Cudd_Xgty */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function x==y.] + + Description [This function generates a BDD for the function x==y. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has 3*N-1 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ] + + SideEffects [None] + + SeeAlso [Cudd_addXeqy] + +******************************************************************************/ +DdNode * +Cudd_Xeqy( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + DdNode *u, *v, *w; + int i; + + /* Build bottom part of BDD outside loop. */ + u = Cudd_bddIte(dd, x[N-1], y[N-1], Cudd_Not(y[N-1])); + if (u == NULL) return(NULL); + cuddRef(u); + + /* Loop to build the rest of the BDD. */ + for (i = N-2; i >= 0; i--) { + v = Cudd_bddAnd(dd, y[i], u); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, u); + u = Cudd_bddIte(dd, x[i], v, w); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + } + cuddDeref(u); + return(u); + +} /* end of Cudd_Xeqy */ + + +/**Function******************************************************************** + + Synopsis [Generates an ADD for the function x==y.] + + Description [This function generates an ADD for the function x==y. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The ADD is built bottom-up. + It has 3*N-1 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ] + + SideEffects [None] + + SeeAlso [Cudd_Xeqy] + +******************************************************************************/ +DdNode * +Cudd_addXeqy( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + DdNode *one, *zero; + DdNode *u, *v, *w; + int i; + + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + /* Build bottom part of ADD outside loop. */ + v = Cudd_addIte(dd, y[N-1], one, zero); + if (v == NULL) return(NULL); + cuddRef(v); + w = Cudd_addIte(dd, y[N-1], zero, one); + if (w == NULL) { + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); + u = Cudd_addIte(dd, x[N-1], v, w); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + + /* Loop to build the rest of the ADD. */ + for (i = N-2; i >= 0; i--) { + v = Cudd_addIte(dd, y[i], u, zero); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_addIte(dd, y[i], zero, u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, u); + u = Cudd_addIte(dd, x[i], v, w); + if (w == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + } + cuddDeref(u); + return(u); + +} /* end of Cudd_addXeqy */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function d(x,y) > d(x,z).] + + Description [This function generates a BDD for the function d(x,y) + > d(x,z); + x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\], + y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\], + with 0 the most significant bit. + The distance d(x,y) is defined as: + \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). + The BDD is built bottom-up. + It has 7*N-3 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ] + + SideEffects [None] + + SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdyz Cudd_Xgty Cudd_bddAdjPermuteX] + +******************************************************************************/ +DdNode * +Cudd_Dxygtdxz( + DdManager * dd /* DD manager */, + int N /* number of x, y, and z variables */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */, + DdNode ** z /* array of z variables */) +{ + DdNode *one, *zero; + DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1; + int i; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Build bottom part of BDD outside loop. */ + y1_ = Cudd_bddIte(dd, y[N-1], one, Cudd_Not(z[N-1])); + if (y1_ == NULL) return(NULL); + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[N-1], z[N-1], one); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); + x1 = Cudd_bddIte(dd, x[N-1], y1_, y2); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + + /* Loop to build the rest of the BDD. */ + for (i = N-2; i >= 0; i--) { + z1 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); + if (z1 == NULL) { + Cudd_RecursiveDeref(dd, x1); + return(NULL); + } + cuddRef(z1); + z2 = Cudd_bddIte(dd, z[i], x1, one); + if (z2 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + return(NULL); + } + cuddRef(z2); + z3 = Cudd_bddIte(dd, z[i], one, x1); + if (z3 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + return(NULL); + } + cuddRef(z3); + z4 = Cudd_bddIte(dd, z[i], x1, zero); + if (z4 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + return(NULL); + } + cuddRef(z4); + Cudd_RecursiveDeref(dd, x1); + y1_ = Cudd_bddIte(dd, y[i], z2, Cudd_Not(z1)); + if (y1_ == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + return(NULL); + } + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[i], z4, z3); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + x1 = Cudd_bddIte(dd, x[i], y1_, y2); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + } + cuddDeref(x1); + return(Cudd_Not(x1)); + +} /* end of Cudd_Dxygtdxz */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function d(x,y) > d(y,z).] + + Description [This function generates a BDD for the function d(x,y) + > d(y,z); + x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\], + y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\], + with 0 the most significant bit. + The distance d(x,y) is defined as: + \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). + The BDD is built bottom-up. + It has 7*N-3 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ] + + SideEffects [None] + + SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Xgty Cudd_bddAdjPermuteX] + +******************************************************************************/ +DdNode * +Cudd_Dxygtdyz( + DdManager * dd /* DD manager */, + int N /* number of x, y, and z variables */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */, + DdNode ** z /* array of z variables */) +{ + DdNode *one, *zero; + DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1; + int i; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Build bottom part of BDD outside loop. */ + y1_ = Cudd_bddIte(dd, y[N-1], one, z[N-1]); + if (y1_ == NULL) return(NULL); + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[N-1], z[N-1], zero); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); + x1 = Cudd_bddIte(dd, x[N-1], y1_, Cudd_Not(y2)); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + + /* Loop to build the rest of the BDD. */ + for (i = N-2; i >= 0; i--) { + z1 = Cudd_bddIte(dd, z[i], x1, zero); + if (z1 == NULL) { + Cudd_RecursiveDeref(dd, x1); + return(NULL); + } + cuddRef(z1); + z2 = Cudd_bddIte(dd, z[i], x1, one); + if (z2 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + return(NULL); + } + cuddRef(z2); + z3 = Cudd_bddIte(dd, z[i], one, x1); + if (z3 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + return(NULL); + } + cuddRef(z3); + z4 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); + if (z4 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + return(NULL); + } + cuddRef(z4); + Cudd_RecursiveDeref(dd, x1); + y1_ = Cudd_bddIte(dd, y[i], z2, z1); + if (y1_ == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + return(NULL); + } + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[i], z4, Cudd_Not(z3)); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + x1 = Cudd_bddIte(dd, x[i], y1_, Cudd_Not(y2)); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + } + cuddDeref(x1); + return(Cudd_Not(x1)); + +} /* end of Cudd_Dxygtdyz */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function x - y ≥ c.] + + Description [This function generates a BDD for the function x -y ≥ c. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has a linear number of nodes if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].] + + SideEffects [None] + + SeeAlso [Cudd_Xgty] + +******************************************************************************/ +DdNode * +Cudd_Inequality( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + int c /* right-hand side constant */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + /* The nodes at level i represent values of the difference that are + ** multiples of 2^i. We use variables with names starting with k + ** to denote the multipliers of 2^i in such multiples. */ + int kTrue = c; + int kFalse = c - 1; + /* Mask used to compute the ceiling function. Since we divide by 2^i, + ** we want to know whether the dividend is a multiple of 2^i. If it is, + ** then ceiling and floor coincide; otherwise, they differ by one. */ + int mask = 1; + int i; + + DdNode *f = NULL; /* the eventual result */ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + + /* Two x-labeled nodes are created at most at each iteration. They are + ** stored, along with their k values, in these variables. At each level, + ** the old nodes are freed and the new nodes are copied into the old map. + */ + DdNode *map[2]; + int invalidIndex = 1 << (N-1); + int index[2] = {invalidIndex, invalidIndex}; + + /* This should never happen. */ + if (N < 0) return(NULL); + + /* If there are no bits, both operands are 0. The result depends on c. */ + if (N == 0) { + if (c >= 0) return(one); + else return(zero); + } + + /* The maximum or the minimum difference comparing to c can generate the terminal case */ + if ((1 << N) - 1 < c) return(zero); + else if ((-(1 << N) + 1) >= c) return(one); + + /* Build the result bottom up. */ + for (i = 1; i <= N; i++) { + int kTrueLower, kFalseLower; + int leftChild, middleChild, rightChild; + DdNode *g0, *g1, *fplus, *fequal, *fminus; + int j; + DdNode *newMap[2]; + int newIndex[2]; + + kTrueLower = kTrue; + kFalseLower = kFalse; + /* kTrue = ceiling((c-1)/2^i) + 1 */ + kTrue = ((c-1) >> i) + ((c & mask) != 1) + 1; + mask = (mask << 1) | 1; + /* kFalse = floor(c/2^i) - 1 */ + kFalse = (c >> i) - 1; + newIndex[0] = invalidIndex; + newIndex[1] = invalidIndex; + + for (j = kFalse + 1; j < kTrue; j++) { + /* Skip if node is not reachable from top of BDD. */ + if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue; + + /* Find f- */ + leftChild = (j << 1) - 1; + if (leftChild >= kTrueLower) { + fminus = one; + } else if (leftChild <= kFalseLower) { + fminus = zero; + } else { + assert(leftChild == index[0] || leftChild == index[1]); + if (leftChild == index[0]) { + fminus = map[0]; + } else { + fminus = map[1]; + } + } + + /* Find f= */ + middleChild = j << 1; + if (middleChild >= kTrueLower) { + fequal = one; + } else if (middleChild <= kFalseLower) { + fequal = zero; + } else { + assert(middleChild == index[0] || middleChild == index[1]); + if (middleChild == index[0]) { + fequal = map[0]; + } else { + fequal = map[1]; + } + } + + /* Find f+ */ + rightChild = (j << 1) + 1; + if (rightChild >= kTrueLower) { + fplus = one; + } else if (rightChild <= kFalseLower) { + fplus = zero; + } else { + assert(rightChild == index[0] || rightChild == index[1]); + if (rightChild == index[0]) { + fplus = map[0]; + } else { + fplus = map[1]; + } + } + + /* Build new nodes. */ + g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus); + if (g1 == NULL) { + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g1); + g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal); + if (g0 == NULL) { + Cudd_IterDerefBdd(dd, g1); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g0); + f = Cudd_bddIte(dd, x[N - i], g1, g0); + if (f == NULL) { + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(f); + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + + /* Save newly computed node in map. */ + assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex); + if (newIndex[0] == invalidIndex) { + newIndex[0] = j; + newMap[0] = f; + } else { + newIndex[1] = j; + newMap[1] = f; + } + } + + /* Copy new map to map. */ + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + map[0] = newMap[0]; + map[1] = newMap[1]; + index[0] = newIndex[0]; + index[1] = newIndex[1]; + } + + cuddDeref(f); + return(f); + +} /* end of Cudd_Inequality */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function x - y != c.] + + Description [This function generates a BDD for the function x -y != c. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has a linear number of nodes if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].] + + SideEffects [None] + + SeeAlso [Cudd_Xgty] + +******************************************************************************/ +DdNode * +Cudd_Disequality( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + int c /* right-hand side constant */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + /* The nodes at level i represent values of the difference that are + ** multiples of 2^i. We use variables with names starting with k + ** to denote the multipliers of 2^i in such multiples. */ + int kTrueLb = c + 1; + int kTrueUb = c - 1; + int kFalse = c; + /* Mask used to compute the ceiling function. Since we divide by 2^i, + ** we want to know whether the dividend is a multiple of 2^i. If it is, + ** then ceiling and floor coincide; otherwise, they differ by one. */ + int mask = 1; + int i; + + DdNode *f = NULL; /* the eventual result */ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + + /* Two x-labeled nodes are created at most at each iteration. They are + ** stored, along with their k values, in these variables. At each level, + ** the old nodes are freed and the new nodes are copied into the old map. + */ + DdNode *map[2]; + int invalidIndex = 1 << (N-1); + int index[2] = {invalidIndex, invalidIndex}; + + /* This should never happen. */ + if (N < 0) return(NULL); + + /* If there are no bits, both operands are 0. The result depends on c. */ + if (N == 0) { + if (c != 0) return(one); + else return(zero); + } + + /* The maximum or the minimum difference comparing to c can generate the terminal case */ + if ((1 << N) - 1 < c || (-(1 << N) + 1) > c) return(one); + + /* Build the result bottom up. */ + for (i = 1; i <= N; i++) { + int kTrueLbLower, kTrueUbLower; + int leftChild, middleChild, rightChild; + DdNode *g0, *g1, *fplus, *fequal, *fminus; + int j; + DdNode *newMap[2]; + int newIndex[2]; + + kTrueLbLower = kTrueLb; + kTrueUbLower = kTrueUb; + /* kTrueLb = floor((c-1)/2^i) + 2 */ + kTrueLb = ((c-1) >> i) + 2; + /* kTrueUb = ceiling((c+1)/2^i) - 2 */ + kTrueUb = ((c+1) >> i) + (((c+2) & mask) != 1) - 2; + mask = (mask << 1) | 1; + newIndex[0] = invalidIndex; + newIndex[1] = invalidIndex; + + for (j = kTrueUb + 1; j < kTrueLb; j++) { + /* Skip if node is not reachable from top of BDD. */ + if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue; + + /* Find f- */ + leftChild = (j << 1) - 1; + if (leftChild >= kTrueLbLower || leftChild <= kTrueUbLower) { + fminus = one; + } else if (i == 1 && leftChild == kFalse) { + fminus = zero; + } else { + assert(leftChild == index[0] || leftChild == index[1]); + if (leftChild == index[0]) { + fminus = map[0]; + } else { + fminus = map[1]; + } + } + + /* Find f= */ + middleChild = j << 1; + if (middleChild >= kTrueLbLower || middleChild <= kTrueUbLower) { + fequal = one; + } else if (i == 1 && middleChild == kFalse) { + fequal = zero; + } else { + assert(middleChild == index[0] || middleChild == index[1]); + if (middleChild == index[0]) { + fequal = map[0]; + } else { + fequal = map[1]; + } + } + + /* Find f+ */ + rightChild = (j << 1) + 1; + if (rightChild >= kTrueLbLower || rightChild <= kTrueUbLower) { + fplus = one; + } else if (i == 1 && rightChild == kFalse) { + fplus = zero; + } else { + assert(rightChild == index[0] || rightChild == index[1]); + if (rightChild == index[0]) { + fplus = map[0]; + } else { + fplus = map[1]; + } + } + + /* Build new nodes. */ + g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus); + if (g1 == NULL) { + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g1); + g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal); + if (g0 == NULL) { + Cudd_IterDerefBdd(dd, g1); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g0); + f = Cudd_bddIte(dd, x[N - i], g1, g0); + if (f == NULL) { + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(f); + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + + /* Save newly computed node in map. */ + assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex); + if (newIndex[0] == invalidIndex) { + newIndex[0] = j; + newMap[0] = f; + } else { + newIndex[1] = j; + newMap[1] = f; + } + } + + /* Copy new map to map. */ + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + map[0] = newMap[0]; + map[1] = newMap[1]; + index[0] = newIndex[0]; + index[1] = newIndex[1]; + } + + cuddDeref(f); + return(f); + +} /* end of Cudd_Disequality */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function lowerB ≤ x ≤ upperB.] + + Description [This function generates a BDD for the function + lowerB ≤ x ≤ upperB, where x is an N-bit number, + x\[0\] x\[1\] ... x\[N-1\], with 0 the most significant bit (important!). + The number of variables N should be sufficient to represent the bounds; + otherwise, the bounds are truncated to their N least significant bits. + Two BDDs are built bottom-up for lowerB ≤ x and x ≤ upperB, and they + are finally conjoined.] + + SideEffects [None] + + SeeAlso [Cudd_Xgty] + +******************************************************************************/ +DdNode * +Cudd_bddInterval( + DdManager * dd /* DD manager */, + int N /* number of x variables */, + DdNode ** x /* array of x variables */, + unsigned int lowerB /* lower bound */, + unsigned int upperB /* upper bound */) +{ + DdNode *one, *zero; + DdNode *r, *rl, *ru; + int i; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + rl = one; + cuddRef(rl); + ru = one; + cuddRef(ru); + + /* Loop to build the rest of the BDDs. */ + for (i = N-1; i >= 0; i--) { + DdNode *vl, *vu; + vl = Cudd_bddIte(dd, x[i], + lowerB&1 ? rl : one, + lowerB&1 ? zero : rl); + if (vl == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(vl); + Cudd_IterDerefBdd(dd, rl); + rl = vl; + lowerB >>= 1; + vu = Cudd_bddIte(dd, x[i], + upperB&1 ? ru : zero, + upperB&1 ? one : ru); + if (vu == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(vu); + Cudd_IterDerefBdd(dd, ru); + ru = vu; + upperB >>= 1; + } + + /* Conjoin the two bounds. */ + r = Cudd_bddAnd(dd, rl, ru); + if (r == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + cuddDeref(r); + return(r); + +} /* end of Cudd_bddInterval */ + + +/**Function******************************************************************** + + Synopsis [Computes the compatible projection of R w.r.t. cube Y.] + + Description [Computes the compatible projection of relation R with + respect to cube Y. Returns a pointer to the c-projection if + successful; NULL otherwise. For a comparison between Cudd_CProjection + and Cudd_PrioritySelect, see the documentation of the latter.] + + SideEffects [None] + + SeeAlso [Cudd_PrioritySelect] + +******************************************************************************/ +DdNode * +Cudd_CProjection( + DdManager * dd, + DdNode * R, + DdNode * Y) +{ + DdNode *res; + DdNode *support; + + if (Cudd_CheckCube(dd,Y) == 0) { + (void) fprintf(dd->err, + "Error: The third argument of Cudd_CProjection should be a cube\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + /* Compute the support of Y, which is used by the abstraction step + ** in cuddCProjectionRecur. + */ + support = Cudd_Support(dd,Y); + if (support == NULL) return(NULL); + cuddRef(support); + + do { + dd->reordered = 0; + res = cuddCProjectionRecur(dd,R,Y,support); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd,support); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,support); + cuddDeref(res); + + return(res); + +} /* end of Cudd_CProjection */ + + +/**Function******************************************************************** + + Synopsis [Computes the Hamming distance ADD.] + + Description [Computes the Hamming distance ADD. Returns an ADD that + gives the Hamming distance between its two arguments if successful; + NULL otherwise. The two vectors xVars and yVars identify the variables + that form the two arguments.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addHamming( + DdManager * dd, + DdNode ** xVars, + DdNode ** yVars, + int nVars) +{ + DdNode *result,*tempBdd; + DdNode *tempAdd,*temp; + int i; + + result = DD_ZERO(dd); + cuddRef(result); + + for (i = 0; i < nVars; i++) { + tempBdd = Cudd_bddIte(dd,xVars[i],Cudd_Not(yVars[i]),yVars[i]); + if (tempBdd == NULL) { + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(tempBdd); + tempAdd = Cudd_BddToAdd(dd,tempBdd); + if (tempAdd == NULL) { + Cudd_RecursiveDeref(dd,tempBdd); + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(tempAdd); + Cudd_RecursiveDeref(dd,tempBdd); + temp = Cudd_addApply(dd,Cudd_addPlus,tempAdd,result); + if (temp == NULL) { + Cudd_RecursiveDeref(dd,tempAdd); + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(temp); + Cudd_RecursiveDeref(dd,tempAdd); + Cudd_RecursiveDeref(dd,result); + result = temp; + } + + cuddDeref(result); + return(result); + +} /* end of Cudd_addHamming */ + + +/**Function******************************************************************** + + Synopsis [Returns the minimum Hamming distance between f and minterm.] + + Description [Returns the minimum Hamming distance between the + minterms of a function f and a reference minterm. The function is + given as a BDD; the minterm is given as an array of integers, one + for each variable in the manager. Returns the minimum distance if + it is less than the upper bound; the upper bound if the minimum + distance is at least as large; CUDD_OUT_OF_MEM in case of failure.] + + SideEffects [None] + + SeeAlso [Cudd_addHamming Cudd_bddClosestCube] + +******************************************************************************/ +int +Cudd_MinHammingDist( + DdManager *dd /* DD manager */, + DdNode *f /* function to examine */, + int *minterm /* reference minterm */, + int upperBound /* distance above which an approximate answer is OK */) +{ + DdHashTable *table; + CUDD_VALUE_TYPE epsilon; + int res; + + table = cuddHashTableInit(dd,1,2); + if (table == NULL) { + return(CUDD_OUT_OF_MEM); + } + epsilon = Cudd_ReadEpsilon(dd); + Cudd_SetEpsilon(dd,(CUDD_VALUE_TYPE)0.0); + res = cuddMinHammingDistRecur(f,minterm,table,upperBound); + cuddHashTableQuit(table); + Cudd_SetEpsilon(dd,epsilon); + + return(res); + +} /* end of Cudd_MinHammingDist */ + + +/**Function******************************************************************** + + Synopsis [Finds a cube of f at minimum Hamming distance from g.] + + Description [Finds a cube of f at minimum Hamming distance from the + minterms of g. All the minterms of the cube are at the minimum + distance. If the distance is 0, the cube belongs to the + intersection of f and g. Returns the cube if successful; NULL + otherwise.] + + SideEffects [The distance is returned as a side effect.] + + SeeAlso [Cudd_MinHammingDist] + +******************************************************************************/ +DdNode * +Cudd_bddClosestCube( + DdManager *dd, + DdNode * f, + DdNode *g, + int *distance) +{ + DdNode *res, *acube; + CUDD_VALUE_TYPE rdist; + + /* Compute the cube and distance as a single ADD. */ + do { + dd->reordered = 0; + res = cuddBddClosestCube(dd,f,g,CUDD_CONST_INDEX + 1.0); + } while (dd->reordered == 1); + if (res == NULL) return(NULL); + cuddRef(res); + + /* Unpack distance and cube. */ + do { + dd->reordered = 0; + acube = separateCube(dd, res, &rdist); + } while (dd->reordered == 1); + if (acube == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(acube); + Cudd_RecursiveDeref(dd, res); + + /* Convert cube from ADD to BDD. */ + do { + dd->reordered = 0; + res = cuddAddBddDoPattern(dd, acube); + } while (dd->reordered == 1); + if (res == NULL) { + Cudd_RecursiveDeref(dd, acube); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, acube); + + *distance = (int) rdist; + cuddDeref(res); + return(res); + +} /* end of Cudd_bddClosestCube */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CProjection.] + + Description [Performs the recursive step of Cudd_CProjection. Returns + the projection if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_CProjection] + +******************************************************************************/ +DdNode * +cuddCProjectionRecur( + DdManager * dd, + DdNode * R, + DdNode * Y, + DdNode * Ysupp) +{ + DdNode *res, *res1, *res2, *resA; + DdNode *r, *y, *RT, *RE, *YT, *YE, *Yrest, *Ra, *Ran, *Gamma, *Alpha; + unsigned int topR, topY, top, index; + DdNode *one = DD_ONE(dd); + + statLine(dd); + if (Y == one) return(R); + +#ifdef DD_DEBUG + assert(!Cudd_IsConstant(Y)); +#endif + + if (R == Cudd_Not(one)) return(R); + + res = cuddCacheLookup2(dd, Cudd_CProjection, R, Y); + if (res != NULL) return(res); + + r = Cudd_Regular(R); + topR = cuddI(dd,r->index); + y = Cudd_Regular(Y); + topY = cuddI(dd,y->index); + + top = ddMin(topR, topY); + + /* Compute the cofactors of R */ + if (topR == top) { + index = r->index; + RT = cuddT(r); + RE = cuddE(r); + if (r != R) { + RT = Cudd_Not(RT); RE = Cudd_Not(RE); + } + } else { + RT = RE = R; + } + + if (topY > top) { + /* Y does not depend on the current top variable. + ** We just need to compute the results on the two cofactors of R + ** and make them the children of a node labeled r->index. + */ + res1 = cuddCProjectionRecur(dd,RT,Y,Ysupp); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddCProjectionRecur(dd,RE,Y,Ysupp); + if (res2 == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); + } + cuddRef(res2); + res = cuddBddIteRecur(dd, dd->vars[index], res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(NULL); + } + /* If we have reached this point, res1 and res2 are now + ** incorporated in res. cuddDeref is therefore sufficient. + */ + cuddDeref(res1); + cuddDeref(res2); + } else { + /* Compute the cofactors of Y */ + index = y->index; + YT = cuddT(y); + YE = cuddE(y); + if (y != Y) { + YT = Cudd_Not(YT); YE = Cudd_Not(YE); + } + if (YT == Cudd_Not(one)) { + Alpha = Cudd_Not(dd->vars[index]); + Yrest = YE; + Ra = RE; + Ran = RT; + } else { + Alpha = dd->vars[index]; + Yrest = YT; + Ra = RT; + Ran = RE; + } + Gamma = cuddBddExistAbstractRecur(dd,Ra,cuddT(Ysupp)); + if (Gamma == NULL) return(NULL); + if (Gamma == one) { + res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res = cuddBddAndRecur(dd, Alpha, res1); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); + } + cuddDeref(res1); + } else if (Gamma == Cudd_Not(one)) { + res1 = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res = cuddBddAndRecur(dd, Cudd_Not(Alpha), res1); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); + } + cuddDeref(res1); + } else { + cuddRef(Gamma); + resA = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); + if (resA == NULL) { + Cudd_RecursiveDeref(dd,Gamma); + return(NULL); + } + cuddRef(resA); + res2 = cuddBddAndRecur(dd, Cudd_Not(Gamma), resA); + if (res2 == NULL) { + Cudd_RecursiveDeref(dd,Gamma); + Cudd_RecursiveDeref(dd,resA); + return(NULL); + } + cuddRef(res2); + Cudd_RecursiveDeref(dd,Gamma); + Cudd_RecursiveDeref(dd,resA); + res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd,res2); + return(NULL); + } + cuddRef(res1); + res = cuddBddIteRecur(dd, Alpha, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + } + } + + cuddCacheInsert2(dd,Cudd_CProjection,R,Y,res); + + return(res); + +} /* end of cuddCProjectionRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddClosestCube.] + + Description [Performs the recursive step of Cudd_bddClosestCube. + Returns the cube if succesful; NULL otherwise. The procedure uses a + four-way recursion to examine all four combinations of cofactors of + f and g according to the following formula. +
      +    H(f,g) = min(H(ft,gt), H(fe,ge), H(ft,ge)+1, H(fe,gt)+1)
      +  
      + Bounding is based on the following observations. +
        +
      • If we already found two points at distance 0, there is no point in + continuing. Furthermore, +
      • If F == not(G) then the best we can hope for is a minimum distance + of 1. If we have already found two points at distance 1, there is + no point in continuing. (Indeed, H(F,G) == 1 in this case. We + have to continue, though, to find the cube.) +
      + The variable bound is set at the largest value of the distance + that we are still interested in. Therefore, we desist when +
      +    (bound == -1) and (F != not(G)) or (bound == 0) and (F == not(G)).
      +  
      + If we were maximally aggressive in using the bound, we would always + set the bound to the minimum distance seen thus far minus one. That + is, we would maintain the invariant +
      +    bound < minD,
      +  
      + except at the very beginning, when we have no value for + minD.

      + + However, we do not use bound < minD when examining the + two negative cofactors, because we try to find a large cube at + minimum distance. To do so, we try to find a cube in the negative + cofactors at the same or smaller distance from the cube found in the + positive cofactors.

      + + When we compute H(ft,ge) and H(fe,gt) we + know that we are going to add 1 to the result of the recursive call + to account for the difference in the splitting variable. Therefore, + we decrease the bound correspondingly.

      + + Another important observation concerns the need of examining all + four pairs of cofators only when both f and + g depend on the top variable.

      + + Suppose gt == ge == g. (That is, g does + not depend on the top variable.) Then +

      +    H(f,g) = min(H(ft,g), H(fe,g), H(ft,g)+1, H(fe,g)+1)
      +	   = min(H(ft,g), H(fe,g)) .
      +  
      + Therefore, under these circumstances, we skip the two "cross" cases.

      + + An interesting feature of this function is the scheme used for + caching the results in the global computed table. Since we have a + cube and a distance, we combine them to form an ADD. The + combination replaces the zero child of the top node of the cube with + the negative of the distance. (The use of the negative is to avoid + ambiguity with 1.) The degenerate cases (zero and one) are treated + specially because the distance is known (0 for one, and infinity for + zero).] + + SideEffects [None] + + SeeAlso [Cudd_bddClosestCube] + +******************************************************************************/ +DdNode * +cuddBddClosestCube( + DdManager *dd, + DdNode *f, + DdNode *g, + CUDD_VALUE_TYPE bound) +{ + DdNode *res, *F, *G, *ft, *fe, *gt, *ge, *tt, *ee; + DdNode *ctt, *cee, *cte, *cet; + CUDD_VALUE_TYPE minD, dtt, dee, dte, det; + DdNode *one = DD_ONE(dd); + DdNode *lzero = Cudd_Not(one); + DdNode *azero = DD_ZERO(dd); + unsigned int topf, topg, index; + + statLine(dd); + if (bound < (f == Cudd_Not(g))) return(azero); + /* Terminal cases. */ + if (g == lzero || f == lzero) return(azero); + if (f == one && g == one) return(one); + + /* Check cache. */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + if (F->ref != 1 || G->ref != 1) { + res = cuddCacheLookup2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g); + if (res != NULL) return(res); + } + + topf = cuddI(dd,F->index); + topg = cuddI(dd,G->index); + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg <= topf) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + tt = cuddBddClosestCube(dd,ft,gt,bound); + if (tt == NULL) return(NULL); + cuddRef(tt); + ctt = separateCube(dd,tt,&dtt); + if (ctt == NULL) { + Cudd_RecursiveDeref(dd, tt); + return(NULL); + } + cuddRef(ctt); + Cudd_RecursiveDeref(dd, tt); + minD = dtt; + bound = ddMin(bound,minD); + + ee = cuddBddClosestCube(dd,fe,ge,bound); + if (ee == NULL) { + Cudd_RecursiveDeref(dd, ctt); + return(NULL); + } + cuddRef(ee); + cee = separateCube(dd,ee,&dee); + if (cee == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, ee); + return(NULL); + } + cuddRef(cee); + Cudd_RecursiveDeref(dd, ee); + minD = ddMin(dtt, dee); + if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1); + + if (minD > 0 && topf == topg) { + DdNode *te = cuddBddClosestCube(dd,ft,ge,bound-1); + if (te == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + return(NULL); + } + cuddRef(te); + cte = separateCube(dd,te,&dte); + if (cte == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, te); + return(NULL); + } + cuddRef(cte); + Cudd_RecursiveDeref(dd, te); + dte += 1.0; + minD = ddMin(minD, dte); + } else { + cte = azero; + cuddRef(cte); + dte = CUDD_CONST_INDEX + 1.0; + } + if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1); + + if (minD > 0 && topf == topg) { + DdNode *et = cuddBddClosestCube(dd,fe,gt,bound-1); + if (et == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + return(NULL); + } + cuddRef(et); + cet = separateCube(dd,et,&det); + if (cet == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + Cudd_RecursiveDeref(dd, et); + return(NULL); + } + cuddRef(cet); + Cudd_RecursiveDeref(dd, et); + det += 1.0; + minD = ddMin(minD, det); + } else { + cet = azero; + cuddRef(cet); + det = CUDD_CONST_INDEX + 1.0; + } + + if (minD == dtt) { + if (dtt == dee && ctt == cee) { + res = createResult(dd,CUDD_CONST_INDEX,1,ctt,dtt); + } else { + res = createResult(dd,index,1,ctt,dtt); + } + } else if (minD == dee) { + res = createResult(dd,index,0,cee,dee); + } else if (minD == dte) { +#ifdef DD_DEBUG + assert(topf == topg); +#endif + res = createResult(dd,index,1,cte,dte); + } else { +#ifdef DD_DEBUG + assert(topf == topg); +#endif + res = createResult(dd,index,0,cet,det); + } + if (res == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + Cudd_RecursiveDeref(dd, cet); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + Cudd_RecursiveDeref(dd, cet); + + /* Only cache results that are different from azero to avoid + ** storing results that depend on the value of the bound. */ + if ((F->ref != 1 || G->ref != 1) && res != azero) + cuddCacheInsert2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g, res); + + cuddDeref(res); + return(res); + +} /* end of cuddBddClosestCube */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_MinHammingDist.] + + Description [Performs the recursive step of Cudd_MinHammingDist. + It is based on the following identity. Let H(f) be the + minimum Hamming distance of the minterms of f from the reference + minterm. Then: +

      + H(f) = min(H(f0)+h0,H(f1)+h1) + + where f0 and f1 are the two cofactors of f with respect to its top + variable; h0 is 1 if the minterm assigns 1 to the top variable of f; + h1 is 1 if the minterm assigns 0 to the top variable of f. + The upper bound on the distance is used to bound the depth of the + recursion. + Returns the minimum distance unless it exceeds the upper bound or + computation fails.] + + SideEffects [None] + + SeeAlso [Cudd_MinHammingDist] + +******************************************************************************/ +static int +cuddMinHammingDistRecur( + DdNode * f, + int *minterm, + DdHashTable * table, + int upperBound) +{ + DdNode *F, *Ft, *Fe; + double h, hT, hE; + DdNode *zero, *res; + DdManager *dd = table->manager; + + statLine(dd); + if (upperBound == 0) return(0); + + F = Cudd_Regular(f); + + if (cuddIsConstant(F)) { + zero = Cudd_Not(DD_ONE(dd)); + if (f == dd->background || f == zero) { + return(upperBound); + } else { + return(0); + } + } + if ((res = cuddHashTableLookup1(table,f)) != NULL) { + h = cuddV(res); + if (res->ref == 0) { + dd->dead++; + dd->constants.dead++; + } + return((int) h); + } + + Ft = cuddT(F); Fe = cuddE(F); + if (Cudd_IsComplement(f)) { + Ft = Cudd_Not(Ft); Fe = Cudd_Not(Fe); + } + if (minterm[F->index] == 0) { + DdNode *temp = Ft; + Ft = Fe; Fe = temp; + } + + hT = cuddMinHammingDistRecur(Ft,minterm,table,upperBound); + if (hT == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + if (hT == 0) { + hE = upperBound; + } else { + hE = cuddMinHammingDistRecur(Fe,minterm,table,upperBound - 1); + if (hE == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + } + h = ddMin(hT, hE + 1); + + if (F->ref != 1) { + ptrint fanout = (ptrint) F->ref; + cuddSatDec(fanout); + res = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) h); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + cuddRef(res); Cudd_RecursiveDeref(dd, res); + return(CUDD_OUT_OF_MEM); + } + } + + return((int) h); + +} /* end of cuddMinHammingDistRecur */ + + +/**Function******************************************************************** + + Synopsis [Separates cube from distance.] + + Description [Separates cube from distance. Returns the cube if + successful; NULL otherwise.] + + SideEffects [The distance is returned as a side effect.] + + SeeAlso [cuddBddClosestCube createResult] + +******************************************************************************/ +static DdNode * +separateCube( + DdManager *dd, + DdNode *f, + CUDD_VALUE_TYPE *distance) +{ + DdNode *cube, *t; + + /* One and zero are special cases because the distance is implied. */ + if (Cudd_IsConstant(f)) { + *distance = (f == DD_ONE(dd)) ? 0.0 : + (1.0 + (CUDD_VALUE_TYPE) CUDD_CONST_INDEX); + return(f); + } + + /* Find out which branch points to the distance and replace the top + ** node with one pointing to zero instead. */ + t = cuddT(f); + if (Cudd_IsConstant(t) && cuddV(t) <= 0) { +#ifdef DD_DEBUG + assert(!Cudd_IsConstant(cuddE(f)) || cuddE(f) == DD_ONE(dd)); +#endif + *distance = -cuddV(t); + cube = cuddUniqueInter(dd, f->index, DD_ZERO(dd), cuddE(f)); + } else { +#ifdef DD_DEBUG + assert(!Cudd_IsConstant(t) || t == DD_ONE(dd)); +#endif + *distance = -cuddV(cuddE(f)); + cube = cuddUniqueInter(dd, f->index, t, DD_ZERO(dd)); + } + + return(cube); + +} /* end of separateCube */ + + +/**Function******************************************************************** + + Synopsis [Builds a result for cache storage.] + + Description [Builds a result for cache storage. Returns a pointer + to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddBddClosestCube separateCube] + +******************************************************************************/ +static DdNode * +createResult( + DdManager *dd, + unsigned int index, + unsigned int phase, + DdNode *cube, + CUDD_VALUE_TYPE distance) +{ + DdNode *res, *constant; + + /* Special case. The cube is either one or zero, and we do not + ** add any variables. Hence, the result is also one or zero, + ** and the distance remains implied by the value of the constant. */ + if (index == CUDD_CONST_INDEX && Cudd_IsConstant(cube)) return(cube); + + constant = cuddUniqueConst(dd,-distance); + if (constant == NULL) return(NULL); + cuddRef(constant); + + if (index == CUDD_CONST_INDEX) { + /* Replace the top node. */ + if (cuddT(cube) == DD_ZERO(dd)) { + res = cuddUniqueInter(dd,cube->index,constant,cuddE(cube)); + } else { + res = cuddUniqueInter(dd,cube->index,cuddT(cube),constant); + } + } else { + /* Add a new top node. */ +#ifdef DD_DEBUG + assert(cuddI(dd,index) < cuddI(dd,cube->index)); +#endif + if (phase) { + res = cuddUniqueInter(dd,index,cube,constant); + } else { + res = cuddUniqueInter(dd,index,constant,cube); + } + } + if (res == NULL) { + Cudd_RecursiveDeref(dd, constant); + return(NULL); + } + cuddDeref(constant); /* safe because constant is part of res */ + + return(res); + +} /* end of createResult */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddRead.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddRead.c new file mode 100644 index 000000000..713668fe2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddRead.c @@ -0,0 +1,517 @@ +/**CFile*********************************************************************** + + FileName [cuddRead.c] + + PackageName [cudd] + + Synopsis [Functions to read in a matrix] + + Description [External procedures included in this module: +
        +
      • Cudd_addRead() +
      • Cudd_bddRead() +
      ] + + SeeAlso [cudd_addHarwell.c] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddRead.c,v 1.7 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Reads in a sparse matrix.] + + Description [Reads in a sparse matrix specified in a simple format. + The first line of the input contains the numbers of rows and columns. + The remaining lines contain the elements of the matrix, one per line. + Given a background value + (specified by the background field of the manager), only the values + different from it are explicitly listed. Each foreground element is + described by two integers, i.e., the row and column number, and a + real number, i.e., the value.

      + Cudd_addRead produces an ADD that depends on two sets of variables: x + and y. The x variables (x\[0\] ... x\[nx-1\]) encode the row index and + the y variables (y\[0\] ... y\[ny-1\]) encode the column index. + x\[0\] and y\[0\] are the most significant bits in the indices. + The variables may already exist or may be created by the function. + The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.

      + On input, nx and ny hold the numbers + of row and column variables already in existence. On output, they + hold the numbers of row and column variables actually used by the + matrix. When Cudd_addRead creates the variable arrays, + the index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy. + When some variables already exist Cudd_addRead expects the indices + of the existing x variables to be bx+i*sx, and the indices of the + existing y variables to be by+i*sy.

      + m and n are set to the numbers of rows and columns of the + matrix. Their values on input are immaterial. + The ADD for the + sparse matrix is returned in E, and its reference count is > 0. + Cudd_addRead returns 1 in case of success; 0 otherwise.] + + SideEffects [nx and ny are set to the numbers of row and column + variables. m and n are set to the numbers of rows and columns. x and y + are possibly extended to represent the array of row and column + variables. Similarly for xn and yn_, which hold on return from + Cudd_addRead the complements of the row and column variables.] + + SeeAlso [Cudd_addHarwell Cudd_bddRead] + +******************************************************************************/ +int +Cudd_addRead( + FILE * fp /* input file pointer */, + DdManager * dd /* DD manager */, + DdNode ** E /* characteristic function of the graph */, + DdNode *** x /* array of row variables */, + DdNode *** y /* array of column variables */, + DdNode *** xn /* array of complemented row variables */, + DdNode *** yn_ /* array of complemented column variables */, + int * nx /* number or row variables */, + int * ny /* number or column variables */, + int * m /* number of rows */, + int * n /* number of columns */, + int bx /* first index of row variables */, + int sx /* step of row variables */, + int by /* first index of column variables */, + int sy /* step of column variables */) +{ + DdNode *one, *zero; + DdNode *w, *neW; + DdNode *minterm1; + int u, v, err, i, nv; + int lnx, lny; + CUDD_VALUE_TYPE val; + DdNode **lx, **ly, **lxn, **lyn; + + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + err = fscanf(fp, "%d %d", &u, &v); + if (err == EOF) { + return(0); + } else if (err != 2) { + return(0); + } + + *m = u; + /* Compute the number of x variables. */ + lx = *x; lxn = *xn; + u--; /* row and column numbers start from 0 */ + for (lnx=0; u > 0; lnx++) { + u >>= 1; + } + /* Here we rely on the fact that REALLOC of a null pointer is + ** translates to an ALLOC. + */ + if (lnx > *nx) { + *x = lx = REALLOC(DdNode *, *x, lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *xn = lxn = REALLOC(DdNode *, *xn, lnx); + if (lxn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } + + *n = v; + /* Compute the number of y variables. */ + ly = *y; lyn = *yn_; + v--; /* row and column numbers start from 0 */ + for (lny=0; v > 0; lny++) { + v >>= 1; + } + /* Here we rely on the fact that REALLOC of a null pointer is + ** translates to an ALLOC. + */ + if (lny > *ny) { + *y = ly = REALLOC(DdNode *, *y, lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *yn_ = lyn = REALLOC(DdNode *, *yn_, lny); + if (lyn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } + + /* Create all new variables. */ + for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) { + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); + cuddRef(lx[i]); + do { + dd->reordered = 0; + lxn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lxn[i] == NULL) return(0); + cuddRef(lxn[i]); + } + for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) { + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); + do { + dd->reordered = 0; + lyn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lyn[i] == NULL) return(0); + cuddRef(lyn[i]); + } + *nx = lnx; + *ny = lny; + + *E = dd->background; /* this call will never cause reordering */ + cuddRef(*E); + + while (! feof(fp)) { + err = fscanf(fp, "%d %d %lf", &u, &v, &val); + if (err == EOF) { + break; + } else if (err != 3) { + return(0); + } else if (u >= *m || v >= *n || u < 0 || v < 0) { + return(0); + } + + minterm1 = one; cuddRef(minterm1); + + /* Build minterm1 corresponding to this arc */ + for (i = lnx - 1; i>=0; i--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lx[i]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lxn[i]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + u >>= 1; + } + for (i = lny - 1; i>=0; i--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, ly[i]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lyn[i]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + v >>= 1; + } + /* Create new constant node if necessary. + ** This call will never cause reordering. + */ + neW = cuddUniqueConst(dd, val); + if (neW == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(neW); + + w = Cudd_addIte(dd, minterm1, neW, *E); + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, neW); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, neW); + Cudd_RecursiveDeref(dd, *E); + *E = w; + } + return(1); + +} /* end of Cudd_addRead */ + + +/**Function******************************************************************** + + Synopsis [Reads in a graph (without labels) given as a list of arcs.] + + Description [Reads in a graph (without labels) given as an adjacency + matrix. The first line of the input contains the numbers of rows and + columns of the adjacency matrix. The remaining lines contain the arcs + of the graph, one per line. Each arc is described by two integers, + i.e., the row and column number, or the indices of the two endpoints. + Cudd_bddRead produces a BDD that depends on two sets of variables: x + and y. The x variables (x\[0\] ... x\[nx-1\]) encode + the row index and the y variables (y\[0\] ... y\[ny-1\]) encode the + column index. x\[0\] and y\[0\] are the most significant bits in the + indices. + The variables may already exist or may be created by the function. + The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.

      + On input, nx and ny hold the numbers of row and column variables already + in existence. On output, they hold the numbers of row and column + variables actually used by the matrix. When Cudd_bddRead creates the + variable arrays, the index of x\[i\] is bx+i*sx, and the index of + y\[i\] is by+i*sy. When some variables already exist, Cudd_bddRead + expects the indices of the existing x variables to be bx+i*sx, and the + indices of the existing y variables to be by+i*sy.

      + m and n are set to the numbers of rows and columns of the + matrix. Their values on input are immaterial. The BDD for the graph + is returned in E, and its reference count is > 0. Cudd_bddRead returns + 1 in case of success; 0 otherwise.] + + SideEffects [nx and ny are set to the numbers of row and column + variables. m and n are set to the numbers of rows and columns. x and y + are possibly extended to represent the array of row and column + variables.] + + SeeAlso [Cudd_addHarwell Cudd_addRead] + +******************************************************************************/ +int +Cudd_bddRead( + FILE * fp /* input file pointer */, + DdManager * dd /* DD manager */, + DdNode ** E /* characteristic function of the graph */, + DdNode *** x /* array of row variables */, + DdNode *** y /* array of column variables */, + int * nx /* number or row variables */, + int * ny /* number or column variables */, + int * m /* number of rows */, + int * n /* number of columns */, + int bx /* first index of row variables */, + int sx /* step of row variables */, + int by /* first index of column variables */, + int sy /* step of column variables */) +{ + DdNode *one, *zero; + DdNode *w; + DdNode *minterm1; + int u, v, err, i, nv; + int lnx, lny; + DdNode **lx, **ly; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + err = fscanf(fp, "%d %d", &u, &v); + if (err == EOF) { + return(0); + } else if (err != 2) { + return(0); + } + + *m = u; + /* Compute the number of x variables. */ + lx = *x; + u--; /* row and column numbers start from 0 */ + for (lnx=0; u > 0; lnx++) { + u >>= 1; + } + if (lnx > *nx) { + *x = lx = REALLOC(DdNode *, *x, lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } + + *n = v; + /* Compute the number of y variables. */ + ly = *y; + v--; /* row and column numbers start from 0 */ + for (lny=0; v > 0; lny++) { + v >>= 1; + } + if (lny > *ny) { + *y = ly = REALLOC(DdNode *, *y, lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } + + /* Create all new variables. */ + for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) { + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); + cuddRef(lx[i]); + } + for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) { + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); + } + *nx = lnx; + *ny = lny; + + *E = zero; /* this call will never cause reordering */ + cuddRef(*E); + + while (! feof(fp)) { + err = fscanf(fp, "%d %d", &u, &v); + if (err == EOF) { + break; + } else if (err != 2) { + return(0); + } else if (u >= *m || v >= *n || u < 0 || v < 0) { + return(0); + } + + minterm1 = one; cuddRef(minterm1); + + /* Build minterm1 corresponding to this arc. */ + for (i = lnx - 1; i>=0; i--) { + if (u & 1) { + w = Cudd_bddAnd(dd, minterm1, lx[i]); + } else { + w = Cudd_bddAnd(dd, minterm1, Cudd_Not(lx[i])); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd,minterm1); + minterm1 = w; + u >>= 1; + } + for (i = lny - 1; i>=0; i--) { + if (v & 1) { + w = Cudd_bddAnd(dd, minterm1, ly[i]); + } else { + w = Cudd_bddAnd(dd, minterm1, Cudd_Not(ly[i])); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + v >>= 1; + } + + w = Cudd_bddAnd(dd, Cudd_Not(minterm1), Cudd_Not(*E)); + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + w = Cudd_Not(w); + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, *E); + *E = w; + } + return(1); + +} /* end of Cudd_bddRead */ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddRef.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddRef.c new file mode 100644 index 000000000..457d71442 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddRef.c @@ -0,0 +1,808 @@ +/**CFile*********************************************************************** + + FileName [cuddRef.c] + + PackageName [cudd] + + Synopsis [Functions that manipulate the reference counts.] + + Description [External procedures included in this module: +

        +
      • Cudd_Ref() +
      • Cudd_RecursiveDeref() +
      • Cudd_IterDerefBdd() +
      • Cudd_DelayedDerefBdd() +
      • Cudd_RecursiveDerefZdd() +
      • Cudd_Deref() +
      • Cudd_CheckZeroRef() +
      + Internal procedures included in this module: +
        +
      • cuddReclaim() +
      • cuddReclaimZdd() +
      • cuddClearDeathRow() +
      • cuddShrinkDeathRow() +
      • cuddIsInDeathRow() +
      • cuddTimesInDeathRow() +
      + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddRef.c,v 1.29 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Increases the reference count of a node, if it is not + saturated.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_RecursiveDeref Cudd_Deref] + +******************************************************************************/ +void +Cudd_Ref( + DdNode * n) +{ + + n = Cudd_Regular(n); + + cuddSatInc(n->ref); + +} /* end of Cudd_Ref */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of node n.] + + Description [Decreases the reference count of node n. If n dies, + recursively decreases the reference counts of its children. It is + used to dispose of a DD that is no longer needed.] + + SideEffects [None] + + SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDerefZdd] + +******************************************************************************/ +void +Cudd_RecursiveDeref( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + + unsigned int live = table->keys - table->dead; + if (live > table->peakLiveNodes) { + table->peakLiveNodes = live; + } + + N = Cudd_Regular(n); + + do { +#ifdef DD_DEBUG + assert(N->ref != 0); +#endif + + if (N->ref == 1) { + N->ref = 0; + table->dead++; +#ifdef DD_STATS + table->nodesDropped++; +#endif + if (cuddIsConstant(N)) { + table->constants.dead++; + N = stack[--SP]; + } else { + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } + } else { + cuddSatDec(N->ref); + N = stack[--SP]; + } + } while (SP != 0); + +} /* end of Cudd_RecursiveDeref */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of BDD node n.] + + Description [Decreases the reference count of node n. If n dies, + recursively decreases the reference counts of its children. It is + used to dispose of a BDD that is no longer needed. It is more + efficient than Cudd_RecursiveDeref, but it cannot be used on + ADDs. The greater efficiency comes from being able to assume that no + constant node will ever die as a result of a call to this + procedure.] + + SideEffects [None] + + SeeAlso [Cudd_RecursiveDeref Cudd_DelayedDerefBdd] + +******************************************************************************/ +void +Cudd_IterDerefBdd( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + + unsigned int live = table->keys - table->dead; + if (live > table->peakLiveNodes) { + table->peakLiveNodes = live; + } + + N = Cudd_Regular(n); + + do { +#ifdef DD_DEBUG + assert(N->ref != 0); +#endif + + if (N->ref == 1) { + N->ref = 0; + table->dead++; +#ifdef DD_STATS + table->nodesDropped++; +#endif + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } else { + cuddSatDec(N->ref); + N = stack[--SP]; + } + } while (SP != 0); + +} /* end of Cudd_IterDerefBdd */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of BDD node n.] + + Description [Enqueues node n for later dereferencing. If the queue + is full decreases the reference count of the oldest node N to make + room for n. If N dies, recursively decreases the reference counts of + its children. It is used to dispose of a BDD that is currently not + needed, but may be useful again in the near future. The dereferencing + proper is done as in Cudd_IterDerefBdd.] + + SideEffects [None] + + SeeAlso [Cudd_RecursiveDeref Cudd_IterDerefBdd] + +******************************************************************************/ +void +Cudd_DelayedDerefBdd( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack; + int SP; + + unsigned int live = table->keys - table->dead; + if (live > table->peakLiveNodes) { + table->peakLiveNodes = live; + } + + n = Cudd_Regular(n); +#ifdef DD_DEBUG + assert(n->ref != 0); +#endif + +#ifdef DD_NO_DEATH_ROW + N = n; +#else + if (cuddIsConstant(n) || n->ref > 1) { +#ifdef DD_DEBUG + assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table))); +#endif + cuddSatDec(n->ref); + return; + } + + N = table->deathRow[table->nextDead]; + + if (N != NULL) { +#endif +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(N)); +#endif + stack = table->stack; + SP = 1; + do { +#ifdef DD_DEBUG + assert(N->ref != 0); +#endif + if (N->ref == 1) { + N->ref = 0; + table->dead++; +#ifdef DD_STATS + table->nodesDropped++; +#endif + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } else { + cuddSatDec(N->ref); + N = stack[--SP]; + } + } while (SP != 0); +#ifndef DD_NO_DEATH_ROW + } + table->deathRow[table->nextDead] = n; + + /* Udate insertion point. */ + table->nextDead++; + table->nextDead &= table->deadMask; +#if 0 + if (table->nextDead == table->deathRowDepth) { + if (table->deathRowDepth < table->looseUpTo / 2) { + extern void (*MMoutOfMemory)(long); + void (*saveHandler)(long) = MMoutOfMemory; + DdNodePtr *newRow; + MMoutOfMemory = Cudd_OutOfMem; + newRow = REALLOC(DdNodePtr,table->deathRow,2*table->deathRowDepth); + MMoutOfMemory = saveHandler; + if (newRow == NULL) { + table->nextDead = 0; + } else { + int i; + table->memused += table->deathRowDepth; + i = table->deathRowDepth; + table->deathRowDepth <<= 1; + for (; i < table->deathRowDepth; i++) { + newRow[i] = NULL; + } + table->deadMask = table->deathRowDepth - 1; + table->deathRow = newRow; + } + } else { + table->nextDead = 0; + } + } +#endif +#endif + +} /* end of Cudd_DelayedDerefBdd */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of ZDD node n.] + + Description [Decreases the reference count of ZDD node n. If n dies, + recursively decreases the reference counts of its children. It is + used to dispose of a ZDD that is no longer needed.] + + SideEffects [None] + + SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDeref] + +******************************************************************************/ +void +Cudd_RecursiveDerefZdd( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + + N = n; + + do { +#ifdef DD_DEBUG + assert(N->ref != 0); +#endif + + cuddSatDec(N->ref); + + if (N->ref == 0) { + table->deadZ++; +#ifdef DD_STATS + table->nodesDropped++; +#endif +#ifdef DD_DEBUG + assert(!cuddIsConstant(N)); +#endif + ord = table->permZ[N->index]; + stack[SP++] = cuddE(N); + table->subtableZ[ord].dead++; + N = cuddT(N); + } else { + N = stack[--SP]; + } + } while (SP != 0); + +} /* end of Cudd_RecursiveDerefZdd */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of node.] + + Description [Decreases the reference count of node. It is primarily + used in recursive procedures to decrease the ref count of a result + node before returning it. This accomplishes the goal of removing the + protection applied by a previous Cudd_Ref.] + + SideEffects [None] + + SeeAlso [Cudd_RecursiveDeref Cudd_RecursiveDerefZdd Cudd_Ref] + +******************************************************************************/ +void +Cudd_Deref( + DdNode * node) +{ + node = Cudd_Regular(node); + cuddSatDec(node->ref); + +} /* end of Cudd_Deref */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for nodes with non-zero reference + counts.] + + Description [Checks the unique table for nodes with non-zero + reference counts. It is normally called before Cudd_Quit to make sure + that there are no memory leaks due to missing Cudd_RecursiveDeref's. + Takes into account that reference counts may saturate and that the + basic constants and the projection functions are referenced by the + manager. Returns the number of nodes with non-zero reference count. + (Except for the cases mentioned above.)] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_CheckZeroRef( + DdManager * manager) +{ + int size; + int i, j; + int remain; /* the expected number of remaining references to one */ + DdNodePtr *nodelist; + DdNode *node; + DdNode *sentinel = &(manager->sentinel); + DdSubtable *subtable; + int count = 0; + int index; + +#ifndef DD_NO_DEATH_ROW + cuddClearDeathRow(manager); +#endif + + /* First look at the BDD/ADD subtables. */ + remain = 1; /* reference from the manager */ + size = manager->size; + remain += 2 * size; /* reference from the BDD projection functions */ + + for (i = 0; i < size; i++) { + subtable = &(manager->subtables[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + while (node != sentinel) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + index = (int) node->index; + if (node != manager->vars[index]) { + count++; + } else { + if (node->ref != 1) { + count++; + } + } + } + node = node->next; + } + } + } + + /* Then look at the ZDD subtables. */ + size = manager->sizeZ; + if (size) /* references from ZDD universe */ + remain += 2; + + for (i = 0; i < size; i++) { + subtable = &(manager->subtableZ[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + while (node != NULL) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + index = (int) node->index; + if (node == manager->univ[manager->permZ[index]]) { + if (node->ref > 2) { + count++; + } + } else { + count++; + } + } + node = node->next; + } + } + } + + /* Now examine the constant table. Plusinfinity, minusinfinity, and + ** zero are referenced by the manager. One is referenced by the + ** manager, by the ZDD universe, and by all projection functions. + ** All other nodes should have no references. + */ + nodelist = manager->constants.nodelist; + for (j = 0; (unsigned) j < manager->constants.slots; j++) { + node = nodelist[j]; + while (node != NULL) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + if (node == manager->one) { + if ((int) node->ref != remain) { + count++; + } + } else if (node == manager->zero || + node == manager->plusinfinity || + node == manager->minusinfinity) { + if (node->ref != 1) { + count++; + } + } else { + count++; + } + } + node = node->next; + } + } + return(count); + +} /* end of Cudd_CheckZeroRef */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Brings children of a dead node back.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddReclaimZdd] + +******************************************************************************/ +void +cuddReclaim( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + double initialDead = table->dead; + + N = Cudd_Regular(n); + +#ifdef DD_DEBUG + assert(N->ref == 0); +#endif + + do { + if (N->ref == 0) { + N->ref = 1; + table->dead--; + if (cuddIsConstant(N)) { + table->constants.dead--; + N = stack[--SP]; + } else { + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead--; + N = cuddT(N); + } + } else { + cuddSatInc(N->ref); + N = stack[--SP]; + } + } while (SP != 0); + + N = Cudd_Regular(n); + cuddSatDec(N->ref); + table->reclaimed += initialDead - table->dead; + +} /* end of cuddReclaim */ + + +/**Function******************************************************************** + + Synopsis [Brings children of a dead ZDD node back.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddReclaim] + +******************************************************************************/ +void +cuddReclaimZdd( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + + N = n; + +#ifdef DD_DEBUG + assert(N->ref == 0); +#endif + + do { + cuddSatInc(N->ref); + + if (N->ref == 1) { + table->deadZ--; + table->reclaimed++; +#ifdef DD_DEBUG + assert(!cuddIsConstant(N)); +#endif + ord = table->permZ[N->index]; + stack[SP++] = cuddE(N); + table->subtableZ[ord].dead--; + N = cuddT(N); + } else { + N = stack[--SP]; + } + } while (SP != 0); + + cuddSatDec(n->ref); + +} /* end of cuddReclaimZdd */ + + +/**Function******************************************************************** + + Synopsis [Shrinks the death row.] + + Description [Shrinks the death row by a factor of four.] + + SideEffects [None] + + SeeAlso [cuddClearDeathRow] + +******************************************************************************/ +void +cuddShrinkDeathRow( + DdManager *table) +{ +#ifndef DD_NO_DEATH_ROW + int i; + + if (table->deathRowDepth > 3) { + for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) { + if (table->deathRow[i] == NULL) break; + Cudd_IterDerefBdd(table,table->deathRow[i]); + table->deathRow[i] = NULL; + } + table->deathRowDepth /= 4; + table->deadMask = table->deathRowDepth - 1; + if ((unsigned) table->nextDead > table->deadMask) { + table->nextDead = 0; + } + table->deathRow = REALLOC(DdNodePtr, table->deathRow, + table->deathRowDepth); + } +#endif + +} /* end of cuddShrinkDeathRow */ + + +/**Function******************************************************************** + + Synopsis [Clears the death row.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_DelayedDerefBdd Cudd_IterDerefBdd Cudd_CheckZeroRef + cuddGarbageCollect] + +******************************************************************************/ +void +cuddClearDeathRow( + DdManager *table) +{ +#ifndef DD_NO_DEATH_ROW + int i; + + for (i = 0; i < table->deathRowDepth; i++) { + if (table->deathRow[i] == NULL) break; + Cudd_IterDerefBdd(table,table->deathRow[i]); + table->deathRow[i] = NULL; + } +#ifdef DD_DEBUG + for (; i < table->deathRowDepth; i++) { + assert(table->deathRow[i] == NULL); + } +#endif + table->nextDead = 0; +#endif + +} /* end of cuddClearDeathRow */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a node is in the death row.] + + Description [Checks whether a node is in the death row. Returns the + position of the first occurrence if the node is present; -1 + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_DelayedDerefBdd cuddClearDeathRow] + +******************************************************************************/ +int +cuddIsInDeathRow( + DdManager *dd, + DdNode *f) +{ +#ifndef DD_NO_DEATH_ROW + int i; + + for (i = 0; i < dd->deathRowDepth; i++) { + if (f == dd->deathRow[i]) { + return(i); + } + } +#endif + + return(-1); + +} /* end of cuddIsInDeathRow */ + + +/**Function******************************************************************** + + Synopsis [Counts how many times a node is in the death row.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_DelayedDerefBdd cuddClearDeathRow cuddIsInDeathRow] + +******************************************************************************/ +int +cuddTimesInDeathRow( + DdManager *dd, + DdNode *f) +{ + int count = 0; +#ifndef DD_NO_DEATH_ROW + int i; + + for (i = 0; i < dd->deathRowDepth; i++) { + count += f == dd->deathRow[i]; + } +#endif + + return(count); + +} /* end of cuddTimesInDeathRow */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddReorder.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddReorder.c new file mode 100644 index 000000000..11ce2f528 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddReorder.c @@ -0,0 +1,2137 @@ +/**CFile*********************************************************************** + + FileName [cuddReorder.c] + + PackageName [cudd] + + Synopsis [Functions for dynamic variable reordering.] + + Description [External procedures included in this file: +
        +
      • Cudd_ReduceHeap() +
      • Cudd_ShuffleHeap() +
      + Internal procedures included in this module: +
        +
      • cuddDynamicAllocNode() +
      • cuddSifting() +
      • cuddSwapping() +
      • cuddNextHigh() +
      • cuddNextLow() +
      • cuddSwapInPlace() +
      • cuddBddAlignToZdd() +
      + Static procedures included in this module: +
        +
      • ddUniqueCompare() +
      • ddSwapAny() +
      • ddSiftingAux() +
      • ddSiftingUp() +
      • ddSiftingDown() +
      • ddSiftingBackward() +
      • ddReorderPreprocess() +
      • ddReorderPostprocess() +
      • ddShuffle() +
      • ddSiftUp() +
      • bddFixTree() +
      ] + + Author [Shipra Panda, Bernard Plessier, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_MAX_SUBTABLE_SPARSITY 8 +#define DD_SHRINK_FACTOR 2 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddReorder.c,v 1.71 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int *entry; + +int ddTotalNumberSwapping; +#ifdef DD_STATS +int ddTotalNISwaps; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddUniqueCompare (int *ptrX, int *ptrY); +static Move * ddSwapAny (DdManager *table, int x, int y); +static int ddSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddSiftingUp (DdManager *table, int y, int xLow); +static Move * ddSiftingDown (DdManager *table, int x, int xHigh); +static int ddSiftingBackward (DdManager *table, int size, Move *moves); +static int ddReorderPreprocess (DdManager *table); +static int ddReorderPostprocess (DdManager *table); +static int ddShuffle (DdManager *table, int *permutation); +static int ddSiftUp (DdManager *table, int x, int xLow); +static void bddFixTree (DdManager *table, MtrNode *treenode); +static int ddUpdateMtrTree (DdManager *table, MtrNode *treenode, int *perm, int *invperm); +static int ddCheckPermuation (DdManager *table, MtrNode *treenode, int *perm, int *invperm); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Main dynamic reordering routine.] + + Description [Main dynamic reordering routine. + Calls one of the possible reordering procedures: +
        +
      • Swapping +
      • Sifting +
      • Symmetric Sifting +
      • Group Sifting +
      • Window Permutation +
      • Simulated Annealing +
      • Genetic Algorithm +
      • Dynamic Programming (exact) +
      + + For sifting, symmetric sifting, group sifting, and window + permutation it is possible to request reordering to convergence.

      + + The core of all methods is the reordering procedure + cuddSwapInPlace() which swaps two adjacent variables and is based + on Rudell's paper. + Returns 1 in case of success; 0 otherwise. In the case of symmetric + sifting (with and without convergence) returns 1 plus the number of + symmetric variables, in case of success.] + + SideEffects [Changes the variable order for all diagrams and clears + the cache.] + +******************************************************************************/ +int +Cudd_ReduceHeap( + DdManager * table /* DD manager */, + Cudd_ReorderingType heuristic /* method used for reordering */, + int minsize /* bound below which no reordering occurs */) +{ + DdHook *hook; + int result; + unsigned int nextDyn; +#ifdef DD_STATS + unsigned int initialSize; + unsigned int finalSize; +#endif + unsigned long localTime; + + /* Don't reorder if there are too many dead nodes. */ + if (table->keys - table->dead < (unsigned) minsize) + return(1); + + if (heuristic == CUDD_REORDER_SAME) { + heuristic = table->autoMethod; + } + if (heuristic == CUDD_REORDER_NONE) { + return(1); + } + + /* This call to Cudd_ReduceHeap does initiate reordering. Therefore + ** we count it. + */ + table->reorderings++; + + localTime = util_cpu_time(); + + /* Run the hook functions. */ + hook = table->preReorderingHook; + while (hook != NULL) { + int res = (hook->f)(table, "BDD", (void *)heuristic); + if (res == 0) return(0); + hook = hook->next; + } + + if (!ddReorderPreprocess(table)) return(0); + ddTotalNumberSwapping = 0; + + if (table->keys > table->peakLiveNodes) { + table->peakLiveNodes = table->keys; + } +#ifdef DD_STATS + initialSize = table->keys - table->isolated; + ddTotalNISwaps = 0; + + switch(heuristic) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + (void) fprintf(table->out,"#:I_RANDOM "); + break; + case CUDD_REORDER_SIFT: + case CUDD_REORDER_SIFT_CONVERGE: + case CUDD_REORDER_SYMM_SIFT: + case CUDD_REORDER_SYMM_SIFT_CONV: + case CUDD_REORDER_GROUP_SIFT: + case CUDD_REORDER_GROUP_SIFT_CONV: + (void) fprintf(table->out,"#:I_SIFTING "); + break; + case CUDD_REORDER_WINDOW2: + case CUDD_REORDER_WINDOW3: + case CUDD_REORDER_WINDOW4: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + (void) fprintf(table->out,"#:I_WINDOW "); + break; + case CUDD_REORDER_ANNEALING: + (void) fprintf(table->out,"#:I_ANNEAL "); + break; + case CUDD_REORDER_GENETIC: + (void) fprintf(table->out,"#:I_GENETIC "); + break; + case CUDD_REORDER_LINEAR: + case CUDD_REORDER_LINEAR_CONVERGE: + (void) fprintf(table->out,"#:I_LINSIFT "); + break; + case CUDD_REORDER_EXACT: + (void) fprintf(table->out,"#:I_EXACT "); + break; + default: + return(0); + } + (void) fprintf(table->out,"%8d: initial size",initialSize); +#endif + + /* See if we should use alternate threshold for maximum growth. */ + if (table->reordCycle && table->reorderings % table->reordCycle == 0) { + double saveGrowth = table->maxGrowth; + table->maxGrowth = table->maxGrowthAlt; + result = cuddTreeSifting(table,heuristic); + table->maxGrowth = saveGrowth; + } else { + result = cuddTreeSifting(table,heuristic); + } + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + finalSize = table->keys - table->isolated; + (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n", + ((double)(util_cpu_time() - localTime)/1000.0)); + (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n", + ddTotalNumberSwapping); + (void) fprintf(table->out,"#:M_REORDER %8d: NI swaps\n",ddTotalNISwaps); +#endif + + if (result == 0) + return(0); + + if (!ddReorderPostprocess(table)) + return(0); + + if (table->realign) { + if (!cuddZddAlignToBdd(table)) + return(0); + } + + nextDyn = (table->keys - table->constants.keys + 1) * + DD_DYN_RATIO + table->constants.keys; + if (table->reorderings < 20 || nextDyn > table->nextDyn) + table->nextDyn = nextDyn; + else + table->nextDyn += 20; + if (table->randomizeOrder != 0) { + table->nextDyn += Cudd_Random() & table->randomizeOrder; + } + table->reordered = 1; + + /* Run hook functions. */ + hook = table->postReorderingHook; + while (hook != NULL) { + int res = (hook->f)(table, "BDD", (void *)localTime); + if (res == 0) return(0); + hook = hook->next; + } + /* Update cumulative reordering time. */ + table->reordTime += util_cpu_time() - localTime; + + return(result); + +} /* end of Cudd_ReduceHeap */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables according to given permutation.] + + Description [Reorders variables according to given permutation. + The i-th entry of the permutation array contains the index of the variable + that should be brought to the i-th level. The size of the array should be + equal or greater to the number of variables currently in use. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [Changes the variable order for all diagrams and clears + the cache.] + + SeeAlso [Cudd_ReduceHeap] + +******************************************************************************/ +int +Cudd_ShuffleHeap( + DdManager * table /* DD manager */, + int * permutation /* required variable permutation */) +{ + + int result; + int i; + int identity = 1; + int *perm; + + /* Don't waste time in case of identity permutation. */ + for (i = 0; i < table->size; i++) { + if (permutation[i] != table->invperm[i]) { + identity = 0; + break; + } + } + if (identity == 1) { + return(1); + } + if (!ddReorderPreprocess(table)) return(0); + if (table->keys > table->peakLiveNodes) { + table->peakLiveNodes = table->keys; + } + + perm = ALLOC(int, table->size); + for (i = 0; i < table->size; i++) + perm[permutation[i]] = i; + if (!ddCheckPermuation(table,table->tree,perm,permutation)) { + FREE(perm); + return(0); + } + if (!ddUpdateMtrTree(table,table->tree,perm,permutation)) { + FREE(perm); + return(0); + } + FREE(perm); + + result = ddShuffle(table,permutation); + + if (!ddReorderPostprocess(table)) return(0); + + return(result); + +} /* end of Cudd_ShuffleHeap */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Dynamically allocates a Node.] + + Description [Dynamically allocates a Node. This procedure is similar + to cuddAllocNode in Cudd_Table.c, but it does not attempt garbage + collection, because during reordering there are no dead nodes. + Returns a pointer to a new node if successful; NULL is memory is + full.] + + SideEffects [None] + + SeeAlso [cuddAllocNode] + +******************************************************************************/ +DdNode * +cuddDynamicAllocNode( + DdManager * table) +{ + int i; + DdNodePtr *mem; + DdNode *list, *node; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (table->nextFree == NULL) { /* free list is empty */ + /* Try to allocate a new block. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdNodePtr *) ALLOC(DdNode, DD_MEM_CHUNK + 1); + MMoutOfMemory = saveHandler; + if (mem == NULL && table->stash != NULL) { + FREE(table->stash); + table->stash = NULL; + /* Inhibit resizing of tables. */ + table->maxCacheHard = table->cacheSlots - 1; + table->cacheSlack = - (int) (table->cacheSlots + 1); + for (i = 0; i < table->size; i++) { + table->subtables[i].maxKeys <<= 2; + } + mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1); + } + if (mem == NULL) { + /* Out of luck. Call the default handler to do + ** whatever it specifies for a failed malloc. If this + ** handler returns, then set error code, print + ** warning, and return. */ + (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); + table->errorCode = CUDD_MEMORY_OUT; +#ifdef DD_VERBOSE + (void) fprintf(table->err, + "cuddDynamicAllocNode: out of memory"); + (void) fprintf(table->err,"Memory in use = %lu\n", + table->memused); +#endif + return(NULL); + } else { /* successful allocation; slice memory */ + unsigned long offset; + table->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); + mem[0] = (DdNode *) table->memoryList; + table->memoryList = mem; + + /* Here we rely on the fact that the size of a DdNode is a + ** power of 2 and a multiple of the size of a pointer. + ** If we align one node, all the others will be aligned + ** as well. */ + offset = (unsigned long) mem & (sizeof(DdNode) - 1); + mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); +#ifdef DD_DEBUG + assert(((unsigned long) mem & (sizeof(DdNode) - 1)) == 0); +#endif + list = (DdNode *) mem; + + i = 1; + do { + list[i - 1].ref = 0; + list[i - 1].next = &list[i]; + } while (++i < DD_MEM_CHUNK); + + list[DD_MEM_CHUNK-1].ref = 0; + list[DD_MEM_CHUNK - 1].next = NULL; + + table->nextFree = &list[0]; + } + } /* if free list empty */ + + node = table->nextFree; + table->nextFree = node->next; + return (node); + +} /* end of cuddDynamicAllocNode */ + + +/**Function******************************************************************** + + Synopsis [Implementation of Rudell's sifting algorithm.] + + Description [Implementation of Rudell's sifting algorithm. + Assumes that no dead nodes are present. +

        +
      1. Order all the variables according to the number of entries + in each unique table. +
      2. Sift the variable up and down, remembering each time the + total size of the DD heap. +
      3. Select the best permutation. +
      4. Repeat 3 and 4 for all variables. +
      + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; +#ifdef DD_STATS + int previousSize; +#endif + + size = table->size; + + /* Find order in which to sift variables. */ + var = NULL; + entry = ALLOC(int,size); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddSiftingOutOfMem; + } + var = ALLOC(int,size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; + } + + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime + table->reordTime + > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + x = table->perm[var[i]]; + + if (x < lower || x > upper || table->subtables[x].bindVar == 1) + continue; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSiftingAux(table, x, lower, upper); + if (!result) goto cuddSiftingOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->err,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + FREE(var); + FREE(entry); + + return(1); + +cuddSiftingOutOfMem: + + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddSifting */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables by a sequence of (non-adjacent) swaps.] + + Description [Implementation of Plessier's algorithm that reorders + variables by a sequence of (non-adjacent) swaps. +
        +
      1. Select two variables (RANDOM or HEURISTIC). +
      2. Permute these variables. +
      3. If the nodes have decreased accept the permutation. +
      4. Otherwise reconstruct the original heap. +
      5. Loop. +
      + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddSwapping( + DdManager * table, + int lower, + int upper, + Cudd_ReorderingType heuristic) +{ + int i, j; + int max, keys; + int nvars; + int x, y; + int iterate; + int previousSize; + Move *moves, *move; + int pivot; + int modulo; + int result; + +#ifdef DD_DEBUG + /* Sanity check */ + assert(lower >= 0 && upper < table->size && lower <= upper); +#endif + + nvars = upper - lower + 1; + iterate = nvars; + + for (i = 0; i < iterate; i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { + max = -1; + for (j = lower; j <= upper; j++) { + if ((keys = table->subtables[j].keys) > max) { + max = keys; + pivot = j; + } + } + + modulo = upper - pivot; + if (modulo == 0) { + y = pivot; + } else{ + y = pivot + 1 + ((int) Cudd_Random() % modulo); + } + + modulo = pivot - lower - 1; + if (modulo < 1) { + x = lower; + } else{ + do { + x = (int) Cudd_Random() % modulo; + } while (x == y); + } + } else { + x = ((int) Cudd_Random() % nvars) + lower; + do { + y = ((int) Cudd_Random() % nvars) + lower; + } while (x == y); + } + previousSize = table->keys - table->isolated; + moves = ddSwapAny(table,x,y); + if (moves == NULL) goto cuddSwappingOutOfMem; + result = ddSiftingBackward(table,previousSize,moves); + if (!result) goto cuddSwappingOutOfMem; + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif +#if 0 + (void) fprintf(table->out,"#:t_SWAPPING %8d: tmp size\n", + table->keys - table->isolated); +#endif + } + + return(1); + +cuddSwappingOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(0); + +} /* end of cuddSwapping */ + + +/**Function******************************************************************** + + Synopsis [Finds the next subtable with a larger index.] + + Description [Finds the next subtable with a larger index. Returns the + index.] + + SideEffects [None] + + SeeAlso [cuddNextLow] + +******************************************************************************/ +int +cuddNextHigh( + DdManager * table, + int x) +{ + return(x+1); + +} /* end of cuddNextHigh */ + + +/**Function******************************************************************** + + Synopsis [Finds the next subtable with a smaller index.] + + Description [Finds the next subtable with a smaller index. Returns the + index.] + + SideEffects [None] + + SeeAlso [cuddNextHigh] + +******************************************************************************/ +int +cuddNextLow( + DdManager * table, + int x) +{ + return(x-1); + +} /* end of cuddNextLow */ + + +/**Function******************************************************************** + + Synopsis [Swaps two adjacent variables.] + + Description [Swaps two adjacent variables. It assumes that no dead + nodes are present on entry to this procedure. The procedure then + guarantees that no dead nodes will be present when it terminates. + cuddSwapInPlace assumes that x < y. Returns the number of keys in + the table if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddSwapInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int comple, newcomplement; + int i; + Cudd_VariableType varType; + Cudd_LazyGroupType groupType; + int posn; + int isolated; + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0; + DdNode *g,*next; + DdNodePtr *previousP; + DdNode *tmp; + DdNode *sentinel = &(table->sentinel); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + +#ifdef DD_DEBUG + int count,idcheck; +#endif + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddNextHigh(table,x) == y); + assert(table->subtables[x].keys != 0); + assert(table->subtables[y].keys != 0); + assert(table->subtables[x].dead == 0); + assert(table->subtables[y].dead == 0); +#endif + + ddTotalNumberSwapping++; + + /* Get parameters of x subtable. */ + xindex = table->invperm[x]; + xlist = table->subtables[x].nodelist; + oldxkeys = table->subtables[x].keys; + xslots = table->subtables[x].slots; + xshift = table->subtables[x].shift; + + /* Get parameters of y subtable. */ + yindex = table->invperm[y]; + ylist = table->subtables[y].nodelist; + oldykeys = table->subtables[y].keys; + yslots = table->subtables[y].slots; + yshift = table->subtables[y].shift; + + if (!cuddTestInteract(table,xindex,yindex)) { +#ifdef DD_STATS + ddTotalNISwaps++; +#endif + newxkeys = oldxkeys; + newykeys = oldykeys; + } else { + newxkeys = 0; + newykeys = oldykeys; + + /* Check whether the two projection functions involved in this + ** swap are isolated. At the end, we'll be able to tell how many + ** isolated projection functions are there by checking only these + ** two functions again. This is done to eliminate the isolated + ** projection functions from the node count. + */ + isolated = - ((table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1)); + + /* The nodes in the x layer that do not depend on + ** y will stay there; the others are put in a chain. + ** The chain is handled as a LIFO; g points to the beginning. + */ + g = NULL; + if ((oldxkeys >= xslots || (unsigned) xslots == table->initSlots) && + oldxkeys <= DD_MAX_SUBTABLE_DENSITY * xslots) { + for (i = 0; i < xslots; i++) { + previousP = &(xlist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if (f1->index != (DdHalfWord) yindex && + Cudd_Regular(f0)->index != (DdHalfWord) yindex) { + /* stays */ + newxkeys++; + *previousP = f; + previousP = &(f->next); + } else { + f->index = yindex; + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ + *previousP = sentinel; + } /* for each slot of the x subtable */ + } else { /* resize xlist */ + DdNode *h = NULL; + DdNodePtr *newxlist; + unsigned int newxslots; + int newxshift; + /* Empty current xlist. Nodes that stay go to list h; + ** nodes that move go to list g. */ + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if (f1->index != (DdHalfWord) yindex && + Cudd_Regular(f0)->index != (DdHalfWord) yindex) { + /* stays */ + f->next = h; + h = f; + newxkeys++; + } else { + f->index = yindex; + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ + } /* for each slot of the x subtable */ + /* Decide size of new subtable. */ + newxshift = xshift; + newxslots = xslots; + while ((unsigned) oldxkeys > DD_MAX_SUBTABLE_DENSITY * newxslots) { + newxshift--; + newxslots <<= 1; + } + while ((unsigned) oldxkeys < newxslots && + newxslots > table->initSlots) { + newxshift++; + newxslots >>= 1; + } + /* Try to allocate new table. Be ready to back off. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + newxlist = ALLOC(DdNodePtr, newxslots); + MMoutOfMemory = saveHandler; + if (newxlist == NULL) { + (void) fprintf(table->err, "Unable to resize subtable %d for lack of memory\n", i); + newxlist = xlist; + newxslots = xslots; + newxshift = xshift; + } else { + table->slots += ((int) newxslots - xslots); + table->minDead = (unsigned) + (table->gcFrac * (double) table->slots); + table->cacheSlack = (int) + ddMin(table->maxCacheHard, DD_MAX_CACHE_TO_SLOTS_RATIO + * table->slots) - 2 * (int) table->cacheSlots; + table->memused += + ((int) newxslots - xslots) * sizeof(DdNodePtr); + FREE(xlist); + xslots = newxslots; + xshift = newxshift; + xlist = newxlist; + } + /* Initialize new subtable. */ + for (i = 0; i < xslots; i++) { + xlist[i] = sentinel; + } + /* Move nodes that were parked in list h to their new home. */ + f = h; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); + f0 = cuddE(f); + /* Check xlist for pair (f11,f01). */ + posn = ddHash(f1, f0, xshift); + /* For each element tmp in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + tmp = *previousP; + while (f1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (f1 == cuddT(tmp) && f0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; + *previousP = f; + f = next; + } + } + +#ifdef DD_COUNT + table->swapSteps += oldxkeys - newxkeys; +#endif + /* Take care of the x nodes that must be re-expressed. + ** They form a linked list pointed by g. Their index has been + ** already changed to yindex. + */ + f = g; + while (f != NULL) { + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f1))); +#endif + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = f10 = f1; + } +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f11))); +#endif + f0 = cuddE(f); + comple = Cudd_IsComplement(f0); + f0 = Cudd_Regular(f0); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == f01) { + newf1 = f11; + cuddSatInc(newf1->ref); + } else { + /* Check xlist for triple (xindex,f11,f01). */ + posn = ddHash(f11, f01, xshift); + /* For each element newf1 in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + newf1 = *previousP; + while (f11 < cuddT(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + while (f11 == cuddT(newf1) && f01 < cuddE(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { + cuddSatInc(newf1->ref); + } else { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto cuddSwapOutOfMem; + newf1->index = xindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f01; + /* Insert newf1 in the collision list xlist[posn]; + ** increase the ref counts of f11 and f01. + */ + newxkeys++; + newf1->next = *previousP; + *previousP = newf1; + cuddSatInc(f11->ref); + tmp = Cudd_Regular(f01); + cuddSatInc(tmp->ref); + } + } + cuddT(f) = newf1; +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(newf1))); +#endif + + /* Do the same for f0, keeping complement dots into account. */ + /* Decrease ref count of f0. */ + tmp = Cudd_Regular(f0); + cuddSatDec(tmp->ref); + /* Create the new E child. */ + if (f10 == f00) { + newf0 = f00; + tmp = Cudd_Regular(newf0); + cuddSatInc(tmp->ref); + } else { + /* make sure f10 is regular */ + newcomplement = Cudd_IsComplement(f10); + if (newcomplement) { + f10 = Cudd_Not(f10); + f00 = Cudd_Not(f00); + } + /* Check xlist for triple (xindex,f10,f00). */ + posn = ddHash(f10, f00, xshift); + /* For each element newf0 in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + newf0 = *previousP; + while (f10 < cuddT(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + while (f10 == cuddT(newf0) && f00 < cuddE(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { + cuddSatInc(newf0->ref); + } else { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto cuddSwapOutOfMem; + newf0->index = xindex; newf0->ref = 1; + cuddT(newf0) = f10; + cuddE(newf0) = f00; + /* Insert newf0 in the collision list xlist[posn]; + ** increase the ref counts of f10 and f00. + */ + newxkeys++; + newf0->next = *previousP; + *previousP = newf0; + cuddSatInc(f10->ref); + tmp = Cudd_Regular(f00); + cuddSatInc(tmp->ref); + } + if (newcomplement) { + newf0 = Cudd_Not(newf0); + } + } + cuddE(f) = newf0; + + /* Insert the modified f in ylist. + ** The modified f does not already exists in ylist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, yshift); + newykeys++; + previousP = &(ylist[posn]); + tmp = *previousP; + while (newf1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; + *previousP = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previousP = &(ylist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + if (f->ref == 0) { + tmp = cuddT(f); + cuddSatDec(tmp->ref); + tmp = Cudd_Regular(cuddE(f)); + cuddSatDec(tmp->ref); + cuddDeallocNode(table,f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = sentinel; + } /* for i */ + +#ifdef DD_DEBUG +#if 0 + (void) fprintf(table->out,"Swapping %d and %d\n",x,y); +#endif + count = 0; + idcheck = 0; + for (i = 0; i < yslots; i++) { + f = ylist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) yindex) + idcheck++; + f = f->next; + } + } + if (count != newykeys) { + (void) fprintf(table->out, + "Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n", + oldykeys,newykeys,count); + } + if (idcheck != 0) + (void) fprintf(table->out, + "Error in id's of ylist\twrong id's = %d\n", + idcheck); + count = 0; + idcheck = 0; + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) xindex) + idcheck++; + f = f->next; + } + } + if (count != newxkeys) { + (void) fprintf(table->out, + "Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n", + oldxkeys,newxkeys,count); + } + if (idcheck != 0) + (void) fprintf(table->out, + "Error in id's of xlist\twrong id's = %d\n", + idcheck); +#endif + + isolated += (table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1); + table->isolated += isolated; + } + + /* Set the appropriate fields in table. */ + table->subtables[x].nodelist = ylist; + table->subtables[x].slots = yslots; + table->subtables[x].shift = yshift; + table->subtables[x].keys = newykeys; + table->subtables[x].maxKeys = yslots * DD_MAX_SUBTABLE_DENSITY; + i = table->subtables[x].bindVar; + table->subtables[x].bindVar = table->subtables[y].bindVar; + table->subtables[y].bindVar = i; + /* Adjust filds for lazy sifting. */ + varType = table->subtables[x].varType; + table->subtables[x].varType = table->subtables[y].varType; + table->subtables[y].varType = varType; + i = table->subtables[x].pairIndex; + table->subtables[x].pairIndex = table->subtables[y].pairIndex; + table->subtables[y].pairIndex = i; + i = table->subtables[x].varHandled; + table->subtables[x].varHandled = table->subtables[y].varHandled; + table->subtables[y].varHandled = i; + groupType = table->subtables[x].varToBeGrouped; + table->subtables[x].varToBeGrouped = table->subtables[y].varToBeGrouped; + table->subtables[y].varToBeGrouped = groupType; + + table->subtables[y].nodelist = xlist; + table->subtables[y].slots = xslots; + table->subtables[y].shift = xshift; + table->subtables[y].keys = newxkeys; + table->subtables[y].maxKeys = xslots * DD_MAX_SUBTABLE_DENSITY; + + table->perm[xindex] = y; table->perm[yindex] = x; + table->invperm[x] = yindex; table->invperm[y] = xindex; + + table->keys += newxkeys + newykeys - oldxkeys - oldykeys; + + return(table->keys - table->isolated); + +cuddSwapOutOfMem: + (void) fprintf(table->err,"Error: cuddSwapInPlace out of memory\n"); + + return (0); + +} /* end of cuddSwapInPlace */ + + +/**Function******************************************************************** + + Synopsis [Reorders BDD variables according to the order of the ZDD + variables.] + + Description [Reorders BDD variables according to the order of the + ZDD variables. This function can be called at the end of ZDD + reordering to insure that the order of the BDD variables is + consistent with the order of the ZDD variables. The number of ZDD + variables must be a multiple of the number of BDD variables. Let + M be the ratio of the two numbers. cuddBddAlignToZdd + then considers the ZDD variables from M*i to + (M+1)*i-1 as corresponding to BDD variable + i. This function should be normally called from + Cudd_zddReduceHeap, which clears the cache. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [Changes the BDD variable order for all diagrams and performs + garbage collection of the BDD unique table.] + + SeeAlso [Cudd_ShuffleHeap Cudd_zddReduceHeap] + +******************************************************************************/ +int +cuddBddAlignToZdd( + DdManager * table /* DD manager */) +{ + int *invperm; /* permutation array */ + int M; /* ratio of ZDD variables to BDD variables */ + int i; /* loop index */ + int result; /* return value */ + + /* We assume that a ratio of 0 is OK. */ + if (table->size == 0) + return(1); + + M = table->sizeZ / table->size; + /* Check whether the number of ZDD variables is a multiple of the + ** number of BDD variables. + */ + if (M * table->size != table->sizeZ) + return(0); + /* Create and initialize the inverse permutation array. */ + invperm = ALLOC(int,table->size); + if (invperm == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < table->sizeZ; i += M) { + int indexZ = table->invpermZ[i]; + int index = indexZ / M; + invperm[i / M] = index; + } + /* Eliminate dead nodes. Do not scan the cache again, because we + ** assume that Cudd_zddReduceHeap has already cleared it. + */ + cuddGarbageCollect(table,0); + + /* Initialize number of isolated projection functions. */ + table->isolated = 0; + for (i = 0; i < table->size; i++) { + if (table->vars[i]->ref == 1) table->isolated++; + } + + /* Initialize the interaction matrix. */ + result = cuddInitInteract(table); + if (result == 0) return(0); + + result = ddShuffle(table, invperm); + FREE(invperm); + /* Free interaction matrix. */ + FREE(table->interact); + /* Fix the BDD variable group tree. */ + bddFixTree(table,table->tree); + return(result); + +} /* end of cuddBddAlignToZdd */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + +******************************************************************************/ +static int +ddUniqueCompare( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of ddUniqueCompare */ + + +/**Function******************************************************************** + + Synopsis [Swaps any two variables.] + + Description [Swaps any two variables. Returns the set of moves.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSwapAny( + DdManager * table, + int x, + int y) +{ + Move *move, *moves; + int xRef,yRef; + int xNext,yNext; + int size; + int limitSize; + int tmp; + + if (x >y) { + tmp = x; x = y; y = tmp; + } + + xRef = x; yRef = y; + + xNext = cuddNextHigh(table,x); + yNext = cuddNextLow(table,y); + moves = NULL; + limitSize = table->keys - table->isolated; + + for (;;) { + if ( xNext == yNext) { + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,yNext,y); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = yNext; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + + } else if (x == yNext) { + + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + + } else { + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,yNext,y); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = yNext; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + x = xNext; + y = yNext; + } + + xNext = cuddNextHigh(table,x); + yNext = cuddNextLow(table,y); + if (xNext > yRef) break; + + if ((double) size > table->maxGrowth * (double) limitSize) break; + if (size < limitSize) limitSize = size; + } + if (yNext>=xRef) { + size = cuddSwapInPlace(table,yNext,y); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = yNext; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + } + + return(moves); + +ddSwapAnyOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of ddSwapAny */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; + + initialSize = table->keys - table->isolated; + + moveDown = NULL; + moveUp = NULL; + + if (x == xLow) { + moveDown = ddSiftingDown(table,x,xHigh); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddSiftingAuxOutOfMem; + + } else if (x == xHigh) { + moveUp = ddSiftingUp(table,x,xLow); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddSiftingAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + moveDown = ddSiftingDown(table,x,xHigh); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + if (moveDown != NULL) { + x = moveDown->y; + } + moveUp = ddSiftingUp(table,x,xLow); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position */ + result = ddSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddSiftingAuxOutOfMem; + + } else { /* must go up first: shorter */ + moveUp = ddSiftingUp(table,x,xLow); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + if (moveUp != NULL) { + x = moveUp->x; + } + moveDown = ddSiftingDown(table,x,xHigh); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddSiftingAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +ddSiftingAuxOutOfMem: + if (moveDown != (Move *) CUDD_OUT_OF_MEM) { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + } + if (moveUp != (Move *) CUDD_OUT_OF_MEM) { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + } + + return(0); + +} /* end of ddSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable up.] + + Description [Sifts a variable up. Moves y up until either it reaches + the bound (xLow) or the size of the DD heap increases too much. + Returns the set of moves in case of success; NULL if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSiftingUp( + DdManager * table, + int y, + int xLow) +{ + Move *moves; + Move *move; + int x; + int size; + int limitSize; + int xindex, yindex; + int isolated; + int L; /* lower bound on DD size */ +#ifdef DD_DEBUG + int checkL; + int z; + int zindex; +#endif + + moves = NULL; + yindex = table->invperm[y]; + + /* Initialize the lower bound. + ** The part of the DD below y will not change. + ** The part of the DD above y that does not interact with y will not + ** change. The rest may vanish in the best case, except for + ** the nodes at level xLow, which will not vanish, regardless. + */ + limitSize = L = table->keys - table->isolated; + for (x = xLow + 1; x < y; x++) { + xindex = table->invperm[x]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L -= table->subtables[x].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + L -= table->subtables[y].keys - isolated; + + x = cuddNextLow(table,y); + while (x >= xLow && L <= limitSize) { + xindex = table->invperm[x]; +#ifdef DD_DEBUG + checkL = table->keys - table->isolated; + for (z = xLow + 1; z < y; z++) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + checkL -= table->subtables[y].keys - isolated; + assert(L == checkL); +#endif + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddSiftingUpOutOfMem; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + y = x; + x = cuddNextLow(table,y); + } + return(moves); + +ddSiftingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable down.] + + Description [Sifts a variable down. Moves x down until either it + reaches the bound (xHigh) or the size of the DD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSiftingDown( + DdManager * table, + int x, + int xHigh) +{ + Move *moves; + Move *move; + int y; + int size; + int R; /* upper bound on node decrease */ + int limitSize; + int xindex, yindex; + int isolated; +#ifdef DD_DEBUG + int checkR; + int z; + int zindex; +#endif + + moves = NULL; + /* Initialize R */ + xindex = table->invperm[x]; + limitSize = size = table->keys - table->isolated; + R = 0; + for (y = xHigh; y > x; y--) { + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R += table->subtables[y].keys - isolated; + } + } + + y = cuddNextHigh(table,x); + while (y <= xHigh && size - R < limitSize) { +#ifdef DD_DEBUG + checkR = 0; + for (z = xHigh; z > x; z--) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + assert(R == checkR); +#endif + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddSiftingDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + x = y; + y = cuddNextHigh(table,x); + } + return(moves); + +ddSiftingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the DD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSiftingBackward( + DdManager * table, + int size, + Move * moves) +{ + Move *move; + int res; + + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + + return(1); + +} /* end of ddSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Prepares the DD heap for dynamic reordering.] + + Description [Prepares the DD heap for dynamic reordering. Does + garbage collection, to guarantee that there are no dead nodes; + clears the cache, which is invalidated by dynamic reordering; initializes + the number of isolated projection functions; and initializes the + interaction matrix. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddReorderPreprocess( + DdManager * table) +{ + int i; + int res; + + /* Clear the cache. */ + cuddCacheFlush(table); + cuddLocalCacheClearAll(table); + + /* Eliminate dead nodes. Do not scan the cache again. */ + cuddGarbageCollect(table,0); + + /* Initialize number of isolated projection functions. */ + table->isolated = 0; + for (i = 0; i < table->size; i++) { + if (table->vars[i]->ref == 1) table->isolated++; + } + + /* Initialize the interaction matrix. */ + res = cuddInitInteract(table); + if (res == 0) return(0); + + return(1); + +} /* end of ddReorderPreprocess */ + + +/**Function******************************************************************** + + Synopsis [Cleans up at the end of reordering.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static int +ddReorderPostprocess( + DdManager * table) +{ + +#ifdef DD_VERBOSE + (void) fflush(table->out); +#endif + + /* Free interaction matrix. */ + FREE(table->interact); + + return(1); + +} /* end of ddReorderPostprocess */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables according to a given permutation.] + + Description [Reorders variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. ddShuffle assumes that no + dead nodes are present and that the interaction matrix is properly + initialized. The reordering is achieved by a series of upward sifts. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddShuffle( + DdManager * table, + int * permutation) +{ + int index; + int level; + int position; + int numvars; + int result; +#ifdef DD_STATS + unsigned long localTime; + int initialSize; + int finalSize; + int previousSize; +#endif + + ddTotalNumberSwapping = 0; +#ifdef DD_STATS + localTime = util_cpu_time(); + initialSize = table->keys - table->isolated; + (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n", + initialSize); + ddTotalNISwaps = 0; +#endif + + numvars = table->size; + + for (level = 0; level < numvars; level++) { + index = permutation[level]; + position = table->perm[index]; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSiftUp(table,position,level); + if (!result) return(0); +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + finalSize = table->keys - table->isolated; + (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:T_SHUFFLE %8g: total time (sec)\n", + ((double)(util_cpu_time() - localTime)/1000.0)); + (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n", + ddTotalNumberSwapping); + (void) fprintf(table->out,"#:M_SHUFFLE %8d: NI swaps\n",ddTotalNISwaps); +#endif + + return(1); + +} /* end of ddShuffle */ + + +/**Function******************************************************************** + + Synopsis [Moves one variable up.] + + Description [Takes a variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddSiftUp( + DdManager * table, + int x, + int xLow) +{ + int y; + int size; + + y = cuddNextLow(table,x); + while (y >= xLow) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); + } + return(1); + +} /* end of ddSiftUp */ + + +/**Function******************************************************************** + + Synopsis [Fixes the BDD variable group tree after a shuffle.] + + Description [Fixes the BDD variable group tree after a + shuffle. Assumes that the order of the variables in a terminal node + has not been changed.] + + SideEffects [Changes the BDD variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static void +bddFixTree( + DdManager * table, + MtrNode * treenode) +{ + if (treenode == NULL) return; + treenode->low = ((int) treenode->index < table->size) ? + table->perm[treenode->index] : treenode->index; + if (treenode->child != NULL) { + bddFixTree(table, treenode->child); + } + if (treenode->younger != NULL) + bddFixTree(table, treenode->younger); + if (treenode->parent != NULL && treenode->low < treenode->parent->low) { + treenode->parent->low = treenode->low; + treenode->parent->index = treenode->index; + } + return; + +} /* end of bddFixTree */ + + +/**Function******************************************************************** + + Synopsis [Updates the BDD variable group tree before a shuffle.] + + Description [Updates the BDD variable group tree before a shuffle. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Changes the BDD variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static int +ddUpdateMtrTree( + DdManager * table, + MtrNode * treenode, + int * perm, + int * invperm) +{ + unsigned int i, size; + int index, level, minLevel, maxLevel, minIndex; + + if (treenode == NULL) return(1); + + minLevel = CUDD_MAXINDEX; + maxLevel = 0; + minIndex = -1; + /* i : level */ + for (i = treenode->low; i < treenode->low + treenode->size; i++) { + index = table->invperm[i]; + level = perm[index]; + if (level < minLevel) { + minLevel = level; + minIndex = index; + } + if (level > maxLevel) + maxLevel = level; + } + size = maxLevel - minLevel + 1; + if (minIndex == -1) return(0); + if (size == treenode->size) { + treenode->low = minLevel; + treenode->index = minIndex; + } else { + return(0); + } + + if (treenode->child != NULL) { + if (!ddUpdateMtrTree(table, treenode->child, perm, invperm)) + return(0); + } + if (treenode->younger != NULL) { + if (!ddUpdateMtrTree(table, treenode->younger, perm, invperm)) + return(0); + } + return(1); +} + + +/**Function******************************************************************** + + Synopsis [Checks the BDD variable group tree before a shuffle.] + + Description [Checks the BDD variable group tree before a shuffle. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Changes the BDD variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static int +ddCheckPermuation( + DdManager * table, + MtrNode * treenode, + int * perm, + int * invperm) +{ + unsigned int i, size; + int index, level, minLevel, maxLevel; + + if (treenode == NULL) return(1); + + minLevel = table->size; + maxLevel = 0; + /* i : level */ + for (i = treenode->low; i < treenode->low + treenode->size; i++) { + index = table->invperm[i]; + level = perm[index]; + if (level < minLevel) + minLevel = level; + if (level > maxLevel) + maxLevel = level; + } + size = maxLevel - minLevel + 1; + if (size != treenode->size) + return(0); + + if (treenode->child != NULL) { + if (!ddCheckPermuation(table, treenode->child, perm, invperm)) + return(0); + } + if (treenode->younger != NULL) { + if (!ddCheckPermuation(table, treenode->younger, perm, invperm)) + return(0); + } + return(1); +} diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSat.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSat.c new file mode 100644 index 000000000..a3ef50fc1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSat.c @@ -0,0 +1,1774 @@ +/**CFile*********************************************************************** + + FileName [cuddSat.c] + + PackageName [cudd] + + Synopsis [Functions for the solution of satisfiability related problems.] + + Description [External procedures included in this file: +
        +
      • Cudd_Eval() +
      • Cudd_ShortestPath() +
      • Cudd_LargestCube() +
      • Cudd_ShortestLength() +
      • Cudd_Decreasing() +
      • Cudd_Increasing() +
      • Cudd_EquivDC() +
      • Cudd_bddLeqUnless() +
      • Cudd_EqualSupNorm() +
      • Cudd_bddMakePrime() +
      • Cudd_bddMaximallyExpand() +
      • Cudd_bddLargestPrimeUnate() +
      + Internal procedures included in this module: +
        +
      • cuddBddMakePrime() +
      + Static procedures included in this module: +
        +
      • freePathPair() +
      • getShortest() +
      • getPath() +
      • getLargest() +
      • getCube() +
      • ddBddMaximallyExpand() +
      • ddShortestPathUnate() +
      ] + + Author [Seh-Woong Jeong, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_BIGGY 100000000 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct cuddPathPair { + int pos; + int neg; +} cuddPathPair; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSat.c,v 1.39 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static DdNode *one, *zero; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define WEIGHT(weight, col) ((weight) == NULL ? 1 : weight[col]) + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static enum st_retval freePathPair (char *key, char *value, char *arg); +static cuddPathPair getShortest (DdNode *root, int *cost, int *support, st_table *visited); +static DdNode * getPath (DdManager *manager, st_table *visited, DdNode *f, int *weight, int cost); +static cuddPathPair getLargest (DdNode *root, st_table *visited); +static DdNode * getCube (DdManager *manager, st_table *visited, DdNode *f, int cost); +static DdNode * ddBddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f); +static int ddBddShortestPathUnate(DdManager *dd, DdNode *f, int *phases, st_table *table); +static DdNode * ddGetLargestCubeUnate(DdManager *dd, DdNode *f, int *phases, st_table *table); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns the value of a DD for a given variable assignment.] + + Description [Finds the value of a DD for a given variable + assignment. The variable assignment is passed in an array of int's, + that should specify a zero or a one for each variable in the support + of the function. Returns a pointer to a constant node. No new nodes + are produced.] + + SideEffects [None] + + SeeAlso [Cudd_bddLeq Cudd_addEvalConst] + +******************************************************************************/ +DdNode * +Cudd_Eval( + DdManager * dd, + DdNode * f, + int * inputs) +{ + int comple; + DdNode *ptr; + + comple = Cudd_IsComplement(f); + ptr = Cudd_Regular(f); + + while (!cuddIsConstant(ptr)) { + if (inputs[ptr->index] == 1) { + ptr = cuddT(ptr); + } else { + comple ^= Cudd_IsComplement(cuddE(ptr)); + ptr = Cudd_Regular(cuddE(ptr)); + } + } + return(Cudd_NotCond(ptr,comple)); + +} /* end of Cudd_Eval */ + + +/**Function******************************************************************** + + Synopsis [Finds a shortest path in a DD.] + + Description [Finds a shortest path in a DD. f is the DD we want to + get the shortest path for; weight\[i\] is the weight of the THEN arc + coming from the node whose index is i. If weight is NULL, then unit + weights are assumed for all THEN arcs. All ELSE arcs have 0 weight. + If non-NULL, both weight and support should point to arrays with at + least as many entries as there are variables in the manager. + Returns the shortest path as the BDD of a cube.] + + SideEffects [support contains on return the true support of f. + If support is NULL on entry, then Cudd_ShortestPath does not compute + the true support info. length contains the length of the path.] + + SeeAlso [Cudd_ShortestLength Cudd_LargestCube] + +******************************************************************************/ +DdNode * +Cudd_ShortestPath( + DdManager * manager, + DdNode * f, + int * weight, + int * support, + int * length) +{ + DdNode *F; + st_table *visited; + DdNode *sol; + cuddPathPair *rootPair; + int complement, cost; + int i; + + one = DD_ONE(manager); + zero = DD_ZERO(manager); + + /* Initialize support. Support does not depend on variable order. + ** Hence, it does not need to be reinitialized if reordering occurs. + */ + if (support) { + for (i = 0; i < manager->size; i++) { + support[i] = 0; + } + } + + if (f == Cudd_Not(one) || f == zero) { + *length = DD_BIGGY; + return(Cudd_Not(one)); + } + /* From this point on, a path exists. */ + + do { + manager->reordered = 0; + + /* Initialize visited table. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + + /* Now get the length of the shortest path(s) from f to 1. */ + (void) getShortest(f, weight, support, visited); + + complement = Cudd_IsComplement(f); + + F = Cudd_Regular(f); + + if (!st_lookup(visited, F, &rootPair)) return(NULL); + + if (complement) { + cost = rootPair->neg; + } else { + cost = rootPair->pos; + } + + /* Recover an actual shortest path. */ + sol = getPath(manager,visited,f,weight,cost); + + st_foreach(visited, freePathPair, NULL); + st_free_table(visited); + + } while (manager->reordered == 1); + + *length = cost; + return(sol); + +} /* end of Cudd_ShortestPath */ + + +/**Function******************************************************************** + + Synopsis [Finds a largest cube in a DD.] + + Description [Finds a largest cube in a DD. f is the DD we want to + get the largest cube for. The problem is translated into the one of + finding a shortest path in f, when both THEN and ELSE arcs are assumed to + have unit length. This yields a largest cube in the disjoint cover + corresponding to the DD. Therefore, it is not necessarily the largest + implicant of f. Returns the largest cube as a BDD.] + + SideEffects [The number of literals of the cube is returned in the location + pointed by length if it is non-null.] + + SeeAlso [Cudd_ShortestPath] + +******************************************************************************/ +DdNode * +Cudd_LargestCube( + DdManager * manager, + DdNode * f, + int * length) +{ + register DdNode *F; + st_table *visited; + DdNode *sol; + cuddPathPair *rootPair; + int complement, cost; + + one = DD_ONE(manager); + zero = DD_ZERO(manager); + + if (f == Cudd_Not(one) || f == zero) { + if (length != NULL) { + *length = DD_BIGGY; + } + return(Cudd_Not(one)); + } + /* From this point on, a path exists. */ + + do { + manager->reordered = 0; + + /* Initialize visited table. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + + /* Now get the length of the shortest path(s) from f to 1. */ + (void) getLargest(f, visited); + + complement = Cudd_IsComplement(f); + + F = Cudd_Regular(f); + + if (!st_lookup(visited, F, &rootPair)) return(NULL); + + if (complement) { + cost = rootPair->neg; + } else { + cost = rootPair->pos; + } + + /* Recover an actual shortest path. */ + sol = getCube(manager,visited,f,cost); + + st_foreach(visited, freePathPair, NULL); + st_free_table(visited); + + } while (manager->reordered == 1); + + if (length != NULL) { + *length = cost; + } + return(sol); + +} /* end of Cudd_LargestCube */ + + +/**Function******************************************************************** + + Synopsis [Find the length of the shortest path(s) in a DD.] + + Description [Find the length of the shortest path(s) in a DD. f is + the DD we want to get the shortest path for; weight\[i\] is the + weight of the THEN edge coming from the node whose index is i. All + ELSE edges have 0 weight. Returns the length of the shortest + path(s) if such a path is found; a large number if the function is + identically 0, and CUDD_OUT_OF_MEM in case of failure.] + + SideEffects [None] + + SeeAlso [Cudd_ShortestPath] + +******************************************************************************/ +int +Cudd_ShortestLength( + DdManager * manager, + DdNode * f, + int * weight) +{ + register DdNode *F; + st_table *visited; + cuddPathPair *my_pair; + int complement, cost; + + one = DD_ONE(manager); + zero = DD_ZERO(manager); + + if (f == Cudd_Not(one) || f == zero) { + return(DD_BIGGY); + } + + /* From this point on, a path exists. */ + /* Initialize visited table and support. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + + /* Now get the length of the shortest path(s) from f to 1. */ + (void) getShortest(f, weight, NULL, visited); + + complement = Cudd_IsComplement(f); + + F = Cudd_Regular(f); + + if (!st_lookup(visited, F, &my_pair)) return(CUDD_OUT_OF_MEM); + + if (complement) { + cost = my_pair->neg; + } else { + cost = my_pair->pos; + } + + st_foreach(visited, freePathPair, NULL); + st_free_table(visited); + + return(cost); + +} /* end of Cudd_ShortestLength */ + + +/**Function******************************************************************** + + Synopsis [Determines whether a BDD is negative unate in a + variable.] + + Description [Determines whether the function represented by BDD f is + negative unate (monotonic decreasing) in variable i. Returns the + constant one is f is unate and the (logical) constant zero if it is not. + This function does not generate any new nodes.] + + SideEffects [None] + + SeeAlso [Cudd_Increasing] + +******************************************************************************/ +DdNode * +Cudd_Decreasing( + DdManager * dd, + DdNode * f, + int i) +{ + unsigned int topf, level; + DdNode *F, *fv, *fvn, *res; + DD_CTFP cacheOp; + + statLine(dd); +#ifdef DD_DEBUG + assert(0 <= i && i < dd->size); +#endif + + F = Cudd_Regular(f); + topf = cuddI(dd,F->index); + + /* Check terminal case. If topf > i, f does not depend on var. + ** Therefore, f is unate in i. + */ + level = (unsigned) dd->perm[i]; + if (topf > level) { + return(DD_ONE(dd)); + } + + /* From now on, f is not constant. */ + + /* Check cache. */ + cacheOp = (DD_CTFP) Cudd_Decreasing; + res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]); + if (res != NULL) { + return(res); + } + + /* Compute cofactors. */ + fv = cuddT(F); fvn = cuddE(F); + if (F != f) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + + if (topf == (unsigned) level) { + /* Special case: if fv is regular, fv(1,...,1) = 1; + ** If in addition fvn is complemented, fvn(1,...,1) = 0. + ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not + ** monotonic decreasing in i. + */ + if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) { + return(Cudd_Not(DD_ONE(dd))); + } + res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd)); + } else { + res = Cudd_Decreasing(dd,fv,i); + if (res == DD_ONE(dd)) { + res = Cudd_Decreasing(dd,fvn,i); + } + } + + cuddCacheInsert2(dd,cacheOp,f,dd->vars[i],res); + return(res); + +} /* end of Cudd_Decreasing */ + + +/**Function******************************************************************** + + Synopsis [Determines whether a BDD is positive unate in a + variable.] + + Description [Determines whether the function represented by BDD f is + positive unate (monotonic increasing) in variable i. It is based on + Cudd_Decreasing and the fact that f is monotonic increasing in i if + and only if its complement is monotonic decreasing in i.] + + SideEffects [None] + + SeeAlso [Cudd_Decreasing] + +******************************************************************************/ +DdNode * +Cudd_Increasing( + DdManager * dd, + DdNode * f, + int i) +{ + return(Cudd_Decreasing(dd,Cudd_Not(f),i)); + +} /* end of Cudd_Increasing */ + + +/**Function******************************************************************** + + Synopsis [Tells whether F and G are identical wherever D is 0.] + + Description [Tells whether F and G are identical wherever D is 0. F + and G are either two ADDs or two BDDs. D is either a 0-1 ADD or a + BDD. The function returns 1 if F and G are equivalent, and 0 + otherwise. No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_bddLeqUnless] + +******************************************************************************/ +int +Cudd_EquivDC( + DdManager * dd, + DdNode * F, + DdNode * G, + DdNode * D) +{ + DdNode *tmp, *One, *Gr, *Dr; + DdNode *Fv, *Fvn, *Gv, *Gvn, *Dv, *Dvn; + int res; + unsigned int flevel, glevel, dlevel, top; + + One = DD_ONE(dd); + + statLine(dd); + /* Check terminal cases. */ + if (D == One || F == G) return(1); + if (D == Cudd_Not(One) || D == DD_ZERO(dd) || F == Cudd_Not(G)) return(0); + + /* From now on, D is non-constant. */ + + /* Normalize call to increase cache efficiency. */ + if (F > G) { + tmp = F; + F = G; + G = tmp; + } + if (Cudd_IsComplement(F)) { + F = Cudd_Not(F); + G = Cudd_Not(G); + } + + /* From now on, F is regular. */ + + /* Check cache. */ + tmp = cuddCacheLookup(dd,DD_EQUIV_DC_TAG,F,G,D); + if (tmp != NULL) return(tmp == One); + + /* Find splitting variable. */ + flevel = cuddI(dd,F->index); + Gr = Cudd_Regular(G); + glevel = cuddI(dd,Gr->index); + top = ddMin(flevel,glevel); + Dr = Cudd_Regular(D); + dlevel = dd->perm[Dr->index]; + top = ddMin(top,dlevel); + + /* Compute cofactors. */ + if (top == flevel) { + Fv = cuddT(F); + Fvn = cuddE(F); + } else { + Fv = Fvn = F; + } + if (top == glevel) { + Gv = cuddT(Gr); + Gvn = cuddE(Gr); + if (G != Gr) { + Gv = Cudd_Not(Gv); + Gvn = Cudd_Not(Gvn); + } + } else { + Gv = Gvn = G; + } + if (top == dlevel) { + Dv = cuddT(Dr); + Dvn = cuddE(Dr); + if (D != Dr) { + Dv = Cudd_Not(Dv); + Dvn = Cudd_Not(Dvn); + } + } else { + Dv = Dvn = D; + } + + /* Solve recursively. */ + res = Cudd_EquivDC(dd,Fv,Gv,Dv); + if (res != 0) { + res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn); + } + cuddCacheInsert(dd,DD_EQUIV_DC_TAG,F,G,D,(res) ? One : Cudd_Not(One)); + + return(res); + +} /* end of Cudd_EquivDC */ + + +/**Function******************************************************************** + + Synopsis [Tells whether f is less than of equal to G unless D is 1.] + + Description [Tells whether f is less than of equal to G unless D is + 1. f, g, and D are BDDs. The function returns 1 if f is less than + of equal to G, and 0 otherwise. No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_EquivDC Cudd_bddLeq Cudd_bddIteConstant] + +******************************************************************************/ +int +Cudd_bddLeqUnless( + DdManager *dd, + DdNode *f, + DdNode *g, + DdNode *D) +{ + DdNode *tmp, *One, *F, *G; + DdNode *Ft, *Fe, *Gt, *Ge, *Dt, *De; + int res; + unsigned int flevel, glevel, dlevel, top; + + statLine(dd); + + One = DD_ONE(dd); + + /* Check terminal cases. */ + if (f == g || g == One || f == Cudd_Not(One) || D == One || + D == f || D == Cudd_Not(g)) return(1); + /* Check for two-operand cases. */ + if (D == Cudd_Not(One) || D == g || D == Cudd_Not(f)) + return(Cudd_bddLeq(dd,f,g)); + if (g == Cudd_Not(One) || g == Cudd_Not(f)) return(Cudd_bddLeq(dd,f,D)); + if (f == One) return(Cudd_bddLeq(dd,Cudd_Not(g),D)); + + /* From now on, f, g, and D are non-constant, distinct, and + ** non-complementary. */ + + /* Normalize call to increase cache efficiency. We rely on the + ** fact that f <= g unless D is equivalent to not(g) <= not(f) + ** unless D and to f <= D unless g. We make sure that D is + ** regular, and that at most one of f and g is complemented. We also + ** ensure that when two operands can be swapped, the one with the + ** lowest address comes first. */ + + if (Cudd_IsComplement(D)) { + if (Cudd_IsComplement(g)) { + /* Special case: if f is regular and g is complemented, + ** f(1,...,1) = 1 > 0 = g(1,...,1). If D(1,...,1) = 0, return 0. + */ + if (!Cudd_IsComplement(f)) return(0); + /* !g <= D unless !f or !D <= g unless !f */ + tmp = D; + D = Cudd_Not(f); + if (g < tmp) { + f = Cudd_Not(g); + g = tmp; + } else { + f = Cudd_Not(tmp); + } + } else { + if (Cudd_IsComplement(f)) { + /* !D <= !f unless g or !D <= g unless !f */ + tmp = f; + f = Cudd_Not(D); + if (tmp < g) { + D = g; + g = Cudd_Not(tmp); + } else { + D = Cudd_Not(tmp); + } + } else { + /* f <= D unless g or !D <= !f unless g */ + tmp = D; + D = g; + if (tmp < f) { + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } else { + g = tmp; + } + } + } + } else { + if (Cudd_IsComplement(g)) { + if (Cudd_IsComplement(f)) { + /* !g <= !f unless D or !g <= D unless !f */ + tmp = f; + f = Cudd_Not(g); + if (D < tmp) { + g = D; + D = Cudd_Not(tmp); + } else { + g = Cudd_Not(tmp); + } + } else { + /* f <= g unless D or !g <= !f unless D */ + if (g < f) { + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } + } + } else { + /* f <= g unless D or f <= D unless g */ + if (D < g) { + tmp = D; + D = g; + g = tmp; + } + } + } + + /* From now on, D is regular. */ + + /* Check cache. */ + tmp = cuddCacheLookup(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D); + if (tmp != NULL) return(tmp == One); + + /* Find splitting variable. */ + F = Cudd_Regular(f); + flevel = dd->perm[F->index]; + G = Cudd_Regular(g); + glevel = dd->perm[G->index]; + top = ddMin(flevel,glevel); + dlevel = dd->perm[D->index]; + top = ddMin(top,dlevel); + + /* Compute cofactors. */ + if (top == flevel) { + Ft = cuddT(F); + Fe = cuddE(F); + if (F != f) { + Ft = Cudd_Not(Ft); + Fe = Cudd_Not(Fe); + } + } else { + Ft = Fe = f; + } + if (top == glevel) { + Gt = cuddT(G); + Ge = cuddE(G); + if (G != g) { + Gt = Cudd_Not(Gt); + Ge = Cudd_Not(Ge); + } + } else { + Gt = Ge = g; + } + if (top == dlevel) { + Dt = cuddT(D); + De = cuddE(D); + } else { + Dt = De = D; + } + + /* Solve recursively. */ + res = Cudd_bddLeqUnless(dd,Ft,Gt,Dt); + if (res != 0) { + res = Cudd_bddLeqUnless(dd,Fe,Ge,De); + } + cuddCacheInsert(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D,Cudd_NotCond(One,!res)); + + return(res); + +} /* end of Cudd_bddLeqUnless */ + + +/**Function******************************************************************** + + Synopsis [Compares two ADDs for equality within tolerance.] + + Description [Compares two ADDs for equality within tolerance. Two + ADDs are reported to be equal if the maximum difference between them + (the sup norm of their difference) is less than or equal to the + tolerance parameter. Returns 1 if the two ADDs are equal (within + tolerance); 0 otherwise. If parameter pr is positive + the first failure is reported to the standard output.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_EqualSupNorm( + DdManager * dd /* manager */, + DdNode * f /* first ADD */, + DdNode * g /* second ADD */, + CUDD_VALUE_TYPE tolerance /* maximum allowed difference */, + int pr /* verbosity level */) +{ + DdNode *fv, *fvn, *gv, *gvn, *r; + unsigned int topf, topg; + + statLine(dd); + /* Check terminal cases. */ + if (f == g) return(1); + if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) { + if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) { + return(1); + } else { + if (pr>0) { + (void) fprintf(dd->out,"Offending nodes:\n"); + (void) fprintf(dd->out, + "f: address = %p\t value = %40.30f\n", + (void *) f, cuddV(f)); + (void) fprintf(dd->out, + "g: address = %p\t value = %40.30f\n", + (void *) g, cuddV(g)); + } + return(0); + } + } + + /* We only insert the result in the cache if the comparison is + ** successful. Therefore, if we hit we return 1. */ + r = cuddCacheLookup2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g); + if (r != NULL) { + return(1); + } + + /* Compute the cofactors and solve the recursive subproblems. */ + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + + if (topf <= topg) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;} + if (topg <= topf) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;} + + if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0); + if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0); + + cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g,DD_ONE(dd)); + + return(1); + +} /* end of Cudd_EqualSupNorm */ + + +/**Function******************************************************************** + + Synopsis [Expands cube to a prime implicant of f.] + + Description [Expands cube to a prime implicant of f. Returns the prime + if successful; NULL otherwise. In particular, NULL is returned if cube + is not a real cube or is not an implicant of f.] + + SideEffects [None] + + SeeAlso [Cudd_bddMaximallyExpand] + +******************************************************************************/ +DdNode * +Cudd_bddMakePrime( + DdManager *dd /* manager */, + DdNode *cube /* cube to be expanded */, + DdNode *f /* function of which the cube is to be made a prime */) +{ + DdNode *res; + + if (!Cudd_bddLeq(dd,cube,f)) return(NULL); + + do { + dd->reordered = 0; + res = cuddBddMakePrime(dd,cube,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddMakePrime */ + + +/**Function******************************************************************** + + Synopsis [Expands lb to prime implicants of (f and ub).] + + Description [Expands lb to all prime implicants of (f and ub) that contain lb. + Assumes that lb is contained in ub. Returns the disjunction of the primes if + lb is contained in f; returns the zero BDD if lb is not contained in f; + returns NULL in case of failure. In particular, NULL is returned if cube is + not a real cube or is not an implicant of f. Returning the disjunction of + all prime implicants works because the resulting function is unate.] + + SideEffects [None] + + SeeAlso [Cudd_bddMakePrime] + +******************************************************************************/ +DdNode * +Cudd_bddMaximallyExpand( + DdManager *dd /* manager */, + DdNode *lb /* cube to be expanded */, + DdNode *ub /* upper bound cube */, + DdNode *f /* function against which to expand */) +{ + DdNode *res; + + if (!Cudd_bddLeq(dd,lb,ub)) return(NULL); + + do { + dd->reordered = 0; + res = ddBddMaximallyExpand(dd,lb,ub,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddMaximallyExpand */ + + +/**Function******************************************************************** + + Synopsis [Find a largest prime of a unate function.] + + Description [Find a largest prime implicant of a unate function. + Returns the BDD for the prime if succesful; NULL otherwise. The behavior + is undefined if f is not unate. The third argument is used to determine + whether f is unate positive (increasing) or negative (decreasing) + in each of the variables in its support.] + + SideEffects [None] + + SeeAlso [Cudd_bddMaximallyExpand] + +******************************************************************************/ +DdNode * +Cudd_bddLargestPrimeUnate( + DdManager *dd /* manager */, + DdNode *f /* unate function */, + DdNode *phaseBdd /* cube of the phases */) +{ + DdNode *res; + int *phases; + int retval; + st_table *table; + + /* Extract phase vector for quick access. */ + phases = ALLOC(int, dd->size); + if (phases == NULL) return(NULL); + retval = Cudd_BddToCubeArray(dd, phaseBdd, phases); + if (retval == 0) { + FREE(phases); + return(NULL); + } + do { + dd->reordered = 0; + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) { + FREE(phases); + return(NULL); + } + (void) ddBddShortestPathUnate(dd, f, phases, table); + res = ddGetLargestCubeUnate(dd, f, phases, table); + st_free_table(table); + } while (dd->reordered == 1); + + FREE(phases); + return(res); + +} /* end of Cudd_bddLargestPrimeUnate */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddMakePrime.] + + Description [Performs the recursive step of Cudd_bddMakePrime. + Returns the prime if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddBddMakePrime( + DdManager *dd /* manager */, + DdNode *cube /* cube to be expanded */, + DdNode *f /* function of which the cube is to be made a prime */) +{ + DdNode *scan; + DdNode *t, *e; + DdNode *res = cube; + DdNode *zero = Cudd_Not(DD_ONE(dd)); + + Cudd_Ref(res); + scan = cube; + while (!Cudd_IsConstant(scan)) { + DdNode *reg = Cudd_Regular(scan); + DdNode *var = dd->vars[reg->index]; + DdNode *expanded = Cudd_bddExistAbstract(dd,res,var); + if (expanded == NULL) { + Cudd_RecursiveDeref(dd,res); + return(NULL); + } + Cudd_Ref(expanded); + if (Cudd_bddLeq(dd,expanded,f)) { + Cudd_RecursiveDeref(dd,res); + res = expanded; + } else { + Cudd_RecursiveDeref(dd,expanded); + } + cuddGetBranches(scan,&t,&e); + if (t == zero) { + scan = e; + } else if (e == zero) { + scan = t; + } else { + Cudd_RecursiveDeref(dd,res); + return(NULL); /* cube is not a cube */ + } + } + + if (scan == DD_ONE(dd)) { + Cudd_Deref(res); + return(res); + } else { + Cudd_RecursiveDeref(dd,res); + return(NULL); + } + +} /* end of cuddBddMakePrime */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Frees the entries of the visited symbol table.] + + Description [Frees the entries of the visited symbol table. Returns + ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +freePathPair( + char * key, + char * value, + char * arg) +{ + cuddPathPair *pair; + + pair = (cuddPathPair *) value; + FREE(pair); + return(ST_CONTINUE); + +} /* end of freePathPair */ + + +/**Function******************************************************************** + + Synopsis [Finds the length of the shortest path(s) in a DD.] + + Description [Finds the length of the shortest path(s) in a DD. + Uses a local symbol table to store the lengths for each + node. Only the lengths for the regular nodes are entered in the table, + because those for the complement nodes are simply obtained by swapping + the two lenghts. + Returns a pair of lengths: the length of the shortest path to 1; + and the length of the shortest path to 0. This is done so as to take + complement arcs into account.] + + SideEffects [Accumulates the support of the DD in support.] + + SeeAlso [] + +******************************************************************************/ +static cuddPathPair +getShortest( + DdNode * root, + int * cost, + int * support, + st_table * visited) +{ + cuddPathPair *my_pair, res_pair, pair_T, pair_E; + DdNode *my_root, *T, *E; + int weight; + + my_root = Cudd_Regular(root); + + if (st_lookup(visited, my_root, &my_pair)) { + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); + } + + /* In the case of a BDD the following test is equivalent to + ** testing whether the BDD is the constant 1. This formulation, + ** however, works for ADDs as well, by assuming the usual + ** dichotomy of 0 and != 0. + */ + if (cuddIsConstant(my_root)) { + if (my_root != zero) { + res_pair.pos = 0; + res_pair.neg = DD_BIGGY; + } else { + res_pair.pos = DD_BIGGY; + res_pair.neg = 0; + } + } else { + T = cuddT(my_root); + E = cuddE(my_root); + + pair_T = getShortest(T, cost, support, visited); + pair_E = getShortest(E, cost, support, visited); + weight = WEIGHT(cost, my_root->index); + res_pair.pos = ddMin(pair_T.pos+weight, pair_E.pos); + res_pair.neg = ddMin(pair_T.neg+weight, pair_E.neg); + + /* Update support. */ + if (support != NULL) { + support[my_root->index] = 1; + } + } + + my_pair = ALLOC(cuddPathPair, 1); + if (my_pair == NULL) { + if (Cudd_IsComplement(root)) { + int tmp = res_pair.pos; + res_pair.pos = res_pair.neg; + res_pair.neg = tmp; + } + return(res_pair); + } + my_pair->pos = res_pair.pos; + my_pair->neg = res_pair.neg; + + st_insert(visited, (char *)my_root, (char *)my_pair); + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); + +} /* end of getShortest */ + + +/**Function******************************************************************** + + Synopsis [Build a BDD for a shortest path of f.] + + Description [Build a BDD for a shortest path of f. + Given the minimum length from the root, and the minimum + lengths for each node (in visited), apply triangulation at each node. + Of the two children of each node on a shortest path, at least one is + on a shortest path. In case of ties the procedure chooses the THEN + children. + Returns a pointer to the cube BDD representing the path if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +getPath( + DdManager * manager, + st_table * visited, + DdNode * f, + int * weight, + int cost) +{ + DdNode *sol, *tmp; + DdNode *my_dd, *T, *E; + cuddPathPair *T_pair, *E_pair; + int Tcost, Ecost; + int complement; + + my_dd = Cudd_Regular(f); + complement = Cudd_IsComplement(f); + + sol = one; + cuddRef(sol); + + while (!cuddIsConstant(my_dd)) { + Tcost = cost - WEIGHT(weight, my_dd->index); + Ecost = cost; + + T = cuddT(my_dd); + E = cuddE(my_dd); + + if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} + + st_lookup(visited, Cudd_Regular(T), &T_pair); + if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || + (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { + tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + + complement = Cudd_IsComplement(T); + my_dd = Cudd_Regular(T); + cost = Tcost; + continue; + } + st_lookup(visited, Cudd_Regular(E), &E_pair); + if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || + (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { + tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + complement = Cudd_IsComplement(E); + my_dd = Cudd_Regular(E); + cost = Ecost; + continue; + } + (void) fprintf(manager->err,"We shouldn't be here!!\n"); + manager->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + cuddDeref(sol); + return(sol); + +} /* end of getPath */ + + +/**Function******************************************************************** + + Synopsis [Finds the size of the largest cube(s) in a DD.] + + Description [Finds the size of the largest cube(s) in a DD. + This problem is translated into finding the shortest paths from a node + when both THEN and ELSE arcs have unit lengths. + Uses a local symbol table to store the lengths for each + node. Only the lengths for the regular nodes are entered in the table, + because those for the complement nodes are simply obtained by swapping + the two lenghts. + Returns a pair of lengths: the length of the shortest path to 1; + and the length of the shortest path to 0. This is done so as to take + complement arcs into account.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static cuddPathPair +getLargest( + DdNode * root, + st_table * visited) +{ + cuddPathPair *my_pair, res_pair, pair_T, pair_E; + DdNode *my_root, *T, *E; + + my_root = Cudd_Regular(root); + + if (st_lookup(visited, my_root, &my_pair)) { + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); + } + + /* In the case of a BDD the following test is equivalent to + ** testing whether the BDD is the constant 1. This formulation, + ** however, works for ADDs as well, by assuming the usual + ** dichotomy of 0 and != 0. + */ + if (cuddIsConstant(my_root)) { + if (my_root != zero) { + res_pair.pos = 0; + res_pair.neg = DD_BIGGY; + } else { + res_pair.pos = DD_BIGGY; + res_pair.neg = 0; + } + } else { + T = cuddT(my_root); + E = cuddE(my_root); + + pair_T = getLargest(T, visited); + pair_E = getLargest(E, visited); + res_pair.pos = ddMin(pair_T.pos, pair_E.pos) + 1; + res_pair.neg = ddMin(pair_T.neg, pair_E.neg) + 1; + } + + my_pair = ALLOC(cuddPathPair, 1); + if (my_pair == NULL) { /* simply do not cache this result */ + if (Cudd_IsComplement(root)) { + int tmp = res_pair.pos; + res_pair.pos = res_pair.neg; + res_pair.neg = tmp; + } + return(res_pair); + } + my_pair->pos = res_pair.pos; + my_pair->neg = res_pair.neg; + + /* Caching may fail without affecting correctness. */ + st_insert(visited, (char *)my_root, (char *)my_pair); + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); + +} /* end of getLargest */ + + +/**Function******************************************************************** + + Synopsis [Build a BDD for a largest cube of f.] + + Description [Build a BDD for a largest cube of f. + Given the minimum length from the root, and the minimum + lengths for each node (in visited), apply triangulation at each node. + Of the two children of each node on a shortest path, at least one is + on a shortest path. In case of ties the procedure chooses the THEN + children. + Returns a pointer to the cube BDD representing the path if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +getCube( + DdManager * manager, + st_table * visited, + DdNode * f, + int cost) +{ + DdNode *sol, *tmp; + DdNode *my_dd, *T, *E; + cuddPathPair *T_pair, *E_pair; + int Tcost, Ecost; + int complement; + + my_dd = Cudd_Regular(f); + complement = Cudd_IsComplement(f); + + sol = one; + cuddRef(sol); + + while (!cuddIsConstant(my_dd)) { + Tcost = cost - 1; + Ecost = cost - 1; + + T = cuddT(my_dd); + E = cuddE(my_dd); + + if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} + + if (!st_lookup(visited, Cudd_Regular(T), &T_pair)) return(NULL); + if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || + (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { + tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + + complement = Cudd_IsComplement(T); + my_dd = Cudd_Regular(T); + cost = Tcost; + continue; + } + if (!st_lookup(visited, Cudd_Regular(E), &E_pair)) return(NULL); + if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || + (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { + tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + complement = Cudd_IsComplement(E); + my_dd = Cudd_Regular(E); + cost = Ecost; + continue; + } + (void) fprintf(manager->err,"We shouldn't be here!\n"); + manager->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + cuddDeref(sol); + return(sol); + +} /* end of getCube */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddMaximallyExpand.] + + Description [Performs the recursive step of Cudd_bddMaximallyExpand. + Returns set of primes or zero BDD if successful; NULL otherwise. On entry + to this function, ub and lb should be different from the zero BDD. The + function then maintains this invariant.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +ddBddMaximallyExpand( + DdManager *dd /* manager */, + DdNode *lb /* cube to be expanded */, + DdNode *ub /* upper bound cube */, + DdNode *f /* function against which to expand */) +{ + DdNode *one, *zero, *lbv, *lbvn, *lbnx, *ubv, *ubvn, *fv, *fvn, *res; + DdNode *F, *UB, *LB, *t, *e; + unsigned int top, toplb, topub, topf, index; + + statLine(dd); + /* Terminal cases. */ + one = DD_ONE(dd); + zero = Cudd_Not(one); + assert(ub != zero && lb != zero); + /** There are three major terminal cases in theory: + ** ub -> f : return ub + ** lb == f : return lb + ** not(lb -> f): return zero + ** Only the second case can be checked exactly in constant time. + ** For the others, we check for sufficient conditions. + */ + if (ub == f || f == one) return(ub); + if (lb == f) return(lb); + if (f == zero || ub == Cudd_Not(f) || lb == one || lb == Cudd_Not(f)) + return(zero); + if (!Cudd_IsComplement(lb) && Cudd_IsComplement(f)) return(zero); + + /* Here lb and f are not constant. */ + + /* Check cache. Since lb and ub are cubes, their local reference counts + ** are always 1. Hence, we only check the reference count of f. + */ + F = Cudd_Regular(f); + if (F->ref != 1) { + DdNode *tmp = cuddCacheLookup(dd, DD_BDD_MAX_EXP_TAG, lb, ub, f); + if (tmp != NULL) { + return(tmp); + } + } + + /* Compute cofactors. For lb we use the non-zero one in + ** both branches of the recursion. + */ + LB = Cudd_Regular(lb); + UB = Cudd_Regular(ub); + topf = dd->perm[F->index]; + toplb = dd->perm[LB->index]; + topub = (ub == one) ? CUDD_CONST_INDEX : dd->perm[UB->index]; + assert(toplb <= topub); + top = ddMin(topf,toplb); + if (toplb == top) { + index = LB->index; + lbv = cuddT(LB); + lbvn = cuddE(LB); + if (lb != LB) { + lbv = Cudd_Not(lbv); + lbvn = Cudd_Not(lbvn); + } + if (lbv == zero) { + lbnx = lbvn; + } else { + lbnx = lbv; + } + } else { + index = F->index; + lbnx = lbv = lbvn = lb; + } + if (topub == top) { + ubv = cuddT(UB); + ubvn = cuddE(UB); + if (ub != UB) { + ubv = Cudd_Not(ubv); + ubvn = Cudd_Not(ubvn); + } + } else { + ubv = ubvn = ub; + } + if (topf == top) { + fv = cuddT(F); + fvn = cuddE(F); + if (f != F) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + } else { + fv = fvn = f; + } + + /* Recursive calls. */ + if (ubv != zero) { + t = ddBddMaximallyExpand(dd, lbnx, ubv, fv); + if (t == NULL) return(NULL); + } else { + assert(topub == toplb && topub == top && lbv == zero); + t = zero; + } + cuddRef(t); + + /* If the top variable appears only in lb, the positive and negative + ** cofactors of each operand are the same. We want to avoid a + ** needless recursive call, which would force us to give up the + ** cache optimization trick based on reference counts. + */ + if (ubv == ubvn && fv == fvn) { + res = t; + } else { + if (ubvn != zero) { + e = ddBddMaximallyExpand(dd, lbnx, ubvn, fvn); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } + } else { + assert(topub == toplb && topub == top && lbvn == zero); + e = zero; + } + + if (t == e) { + res = t; + } else { + cuddRef(e); + + if (toplb == top) { + if (lbv == zero) { + /* Top variable appears in negative phase. */ + if (t != one) { + DdNode *newT; + if (Cudd_IsComplement(t)) { + newT = cuddUniqueInter(dd, index, Cudd_Not(t), zero); + if (newT == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + newT = Cudd_Not(newT); + } else { + newT = cuddUniqueInter(dd, index, t, one); + if (newT == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + } + cuddRef(newT); + cuddDeref(t); + t = newT; + } + } else if (lbvn == zero) { + /* Top variable appears in positive phase. */ + if (e != one) { + DdNode *newE; + newE = cuddUniqueInter(dd, index, one, e); + if (newE == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + cuddRef(newE); + cuddDeref(e); + e = newE; + } + } else { + /* Not a cube. */ + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + } + + /* Combine results. */ + res = cuddBddAndRecur(dd, t, e); + if (res == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + } + } + + /* Cache result and return. */ + if (F->ref != 1) { + cuddCacheInsert(dd, DD_BDD_MAX_EXP_TAG, lb, ub, f, res); + } + cuddDeref(res); + return(res); + +} /* end of ddBddMaximallyExpand */ + + +/**Function******************************************************************** + + Synopsis [Performs shortest path computation on a unate function.] + + Description [Performs shortest path computation on a unate function. + Returns the length of the shortest path to one if successful; + CUDD_OUT_OF_MEM otherwise. This function is based on the observation + that in the BDD of a unate function no node except the constant is + reachable from the root via paths of different parity.] + + SideEffects [None] + + SeeAlso [getShortest] + +******************************************************************************/ +static int +ddBddShortestPathUnate( + DdManager *dd, + DdNode *f, + int *phases, + st_table *table) +{ + int positive, l, lT, lE; + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + DdNode *F, *fv, *fvn; + + if (st_lookup_int(table, f, &l)) { + return(l); + } + if (f == one) { + l = 0; + } else if (f == zero) { + l = DD_BIGGY; + } else { + F = Cudd_Regular(f); + fv = cuddT(F); + fvn = cuddE(F); + if (f != F) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + lT = ddBddShortestPathUnate(dd, fv, phases, table); + lE = ddBddShortestPathUnate(dd, fvn, phases, table); + positive = phases[F->index]; + l = positive ? ddMin(lT+1, lE) : ddMin(lT, lE+1); + } + if (st_insert(table, f, (void *)(ptrint) l) == ST_OUT_OF_MEM) { + return(CUDD_OUT_OF_MEM); + } + return(l); + +} /* end of ddShortestPathUnate */ + + +/**Function******************************************************************** + + Synopsis [Extracts largest prime of a unate function.] + + Description [Extracts largest prime of a unate function. Returns the BDD of + the prime if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [getPath] + +******************************************************************************/ +static DdNode * +ddGetLargestCubeUnate( + DdManager *dd, + DdNode *f, + int *phases, + st_table *table) +{ + DdNode *res, *scan; + DdNode *one = DD_ONE(dd); + int cost; + + res = one; + cuddRef(res); + scan = f; + st_lookup_int(table, scan, &cost); + + while (!Cudd_IsConstant(scan)) { + int Pcost, Ncost, Tcost; + DdNode *tmp, *T, *E; + DdNode *rscan = Cudd_Regular(scan); + int index = rscan->index; + assert(phases[index] == 0 || phases[index] == 1); + int positive = phases[index] == 1; + Pcost = positive ? cost - 1 : cost; + Ncost = positive ? cost : cost - 1; + T = cuddT(rscan); + E = cuddE(rscan); + if (rscan != scan) { + T = Cudd_Not(T); + E = Cudd_Not(E); + } + tmp = res; + st_lookup_int(table, T, &Tcost); + if (Tcost == Pcost) { + cost = Pcost; + scan = T; + if (positive) { + tmp = cuddBddAndRecur(dd, dd->vars[index], res); + } + } else { + cost = Ncost; + scan = E; + if (!positive) { + tmp = cuddBddAndRecur(dd, Cudd_Not(dd->vars[index]), res); + } + } + if (tmp == NULL) { + Cudd_IterDerefBdd(dd, res); + return(NULL); + } + cuddRef(tmp); + Cudd_IterDerefBdd(dd, res); + res = tmp; + } + + cuddDeref(res); + return(res); + +} /* end of ddGetLargestCubeUnate */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSign.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSign.c new file mode 100644 index 000000000..60520697a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSign.c @@ -0,0 +1,318 @@ +/**CFile*********************************************************************** + + FileName [cuddSign.c] + + PackageName [cudd] + + Synopsis [Computation of signatures.] + + Description [External procedures included in this module: +
        +
      • Cudd_CofMinterm(); +
      + Static procedures included in this module: +
        +
      • ddCofMintermAux() +
      + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSign.c,v 1.24 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int size; + +#ifdef DD_STATS +static int num_calls; /* should equal 2n-1 (n is the # of nodes) */ +static int table_mem; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static double * ddCofMintermAux (DdManager *dd, DdNode *node, st_table *table); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Computes the fraction of minterms in the on-set of all the + positive cofactors of a BDD or ADD.] + + Description [Computes the fraction of minterms in the on-set of all + the positive cofactors of DD. Returns the pointer to an array of + doubles if successful; NULL otherwise. The array has as many + positions as there are BDD variables in the manager plus one. The + last position of the array contains the fraction of the minterms in + the ON-set of the function represented by the BDD or ADD. The other + positions of the array hold the variable signatures.] + + SideEffects [None] + +******************************************************************************/ +double * +Cudd_CofMinterm( + DdManager * dd, + DdNode * node) +{ + st_table *table; + double *values; + double *result = NULL; + int i, firstLevel; + +#ifdef DD_STATS + unsigned long startTime; + startTime = util_cpu_time(); + num_calls = 0; + table_mem = sizeof(st_table); +#endif + + table = st_init_table(st_ptrcmp, st_ptrhash); + if (table == NULL) { + (void) fprintf(dd->err, + "out-of-memory, couldn't measure DD cofactors.\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + size = dd->size; + values = ddCofMintermAux(dd, node, table); + if (values != NULL) { + result = ALLOC(double,size + 1); + if (result != NULL) { +#ifdef DD_STATS + table_mem += (size + 1) * sizeof(double); +#endif + if (Cudd_IsConstant(node)) + firstLevel = 1; + else + firstLevel = cuddI(dd,Cudd_Regular(node)->index); + for (i = 0; i < size; i++) { + if (i >= cuddI(dd,Cudd_Regular(node)->index)) { + result[dd->invperm[i]] = values[i - firstLevel]; + } else { + result[dd->invperm[i]] = values[size - firstLevel]; + } + } + result[size] = values[size - firstLevel]; + } else { + dd->errorCode = CUDD_MEMORY_OUT; + } + } + +#ifdef DD_STATS + table_mem += table->num_bins * sizeof(st_table_entry *); +#endif + if (Cudd_Regular(node)->ref == 1) FREE(values); + st_foreach(table, cuddStCountfree, NULL); + st_free_table(table); +#ifdef DD_STATS + (void) fprintf(dd->out,"Number of calls: %d\tTable memory: %d bytes\n", + num_calls, table_mem); + (void) fprintf(dd->out,"Time to compute measures: %s\n", + util_print_time(util_cpu_time() - startTime)); +#endif + if (result == NULL) { + (void) fprintf(dd->out, + "out-of-memory, couldn't measure DD cofactors.\n"); + dd->errorCode = CUDD_MEMORY_OUT; + } + return(result); + +} /* end of Cudd_CofMinterm */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Recursive Step for Cudd_CofMinterm function.] + + Description [Traverses the DD node and computes the fraction of + minterms in the on-set of all positive cofactors simultaneously. + It allocates an array with two more entries than there are + variables below the one labeling the node. One extra entry (the + first in the array) is for the variable labeling the node. The other + entry (the last one in the array) holds the fraction of minterms of + the function rooted at node. Each other entry holds the value for + one cofactor. The array is put in a symbol table, to avoid repeated + computation, and its address is returned by the procedure, for use + by the caller. Returns a pointer to the array of cofactor measures.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double * +ddCofMintermAux( + DdManager * dd, + DdNode * node, + st_table * table) +{ + DdNode *N; /* regular version of node */ + DdNode *Nv, *Nnv; + double *values; + double *valuesT, *valuesE; + int i; + int localSize, localSizeT, localSizeE; + double vT, vE; + + statLine(dd); +#ifdef DD_STATS + num_calls++; +#endif + + if (st_lookup(table, node, &values)) { + return(values); + } + + N = Cudd_Regular(node); + if (cuddIsConstant(N)) { + localSize = 1; + } else { + localSize = size - cuddI(dd,N->index) + 1; + } + values = ALLOC(double, localSize); + if (values == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + if (cuddIsConstant(N)) { + if (node == DD_ZERO(dd) || node == Cudd_Not(DD_ONE(dd))) { + values[0] = 0.0; + } else { + values[0] = 1.0; + } + } else { + Nv = Cudd_NotCond(cuddT(N),N!=node); + Nnv = Cudd_NotCond(cuddE(N),N!=node); + + valuesT = ddCofMintermAux(dd, Nv, table); + if (valuesT == NULL) return(NULL); + valuesE = ddCofMintermAux(dd, Nnv, table); + if (valuesE == NULL) return(NULL); + + if (Cudd_IsConstant(Nv)) { + localSizeT = 1; + } else { + localSizeT = size - cuddI(dd,Cudd_Regular(Nv)->index) + 1; + } + if (Cudd_IsConstant(Nnv)) { + localSizeE = 1; + } else { + localSizeE = size - cuddI(dd,Cudd_Regular(Nnv)->index) + 1; + } + values[0] = valuesT[localSizeT - 1]; + for (i = 1; i < localSize; i++) { + if (i >= cuddI(dd,Cudd_Regular(Nv)->index) - cuddI(dd,N->index)) { + vT = valuesT[i - cuddI(dd,Cudd_Regular(Nv)->index) + + cuddI(dd,N->index)]; + } else { + vT = valuesT[localSizeT - 1]; + } + if (i >= cuddI(dd,Cudd_Regular(Nnv)->index) - cuddI(dd,N->index)) { + vE = valuesE[i - cuddI(dd,Cudd_Regular(Nnv)->index) + + cuddI(dd,N->index)]; + } else { + vE = valuesE[localSizeE - 1]; + } + values[i] = (vT + vE) / 2.0; + } + if (Cudd_Regular(Nv)->ref == 1) FREE(valuesT); + if (Cudd_Regular(Nnv)->ref == 1) FREE(valuesE); + } + + if (N->ref > 1) { + if (st_add_direct(table, (char *) node, (char *) values) == ST_OUT_OF_MEM) { + FREE(values); + return(NULL); + } +#ifdef DD_STATS + table_mem += localSize * sizeof(double) + sizeof(st_table_entry); +#endif + } + return(values); + +} /* end of ddCofMintermAux */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSolve.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSolve.c new file mode 100644 index 000000000..e97779d8e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSolve.c @@ -0,0 +1,366 @@ +/**CFile*********************************************************************** + + FileName [cuddSolve.c] + + PackageName [cudd] + + Synopsis [Boolean equation solver and related functions.] + + Description [External functions included in this modoule: +
        +
      • Cudd_SolveEqn() +
      • Cudd_VerifySol() +
      + Internal functions included in this module: +
        +
      • cuddSolveEqnRecur() +
      • cuddVerifySol() +
      ] + + SeeAlso [] + + Author [Balakrishna Kumthekar] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSolve.c,v 1.13 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the solution of F(x,y) = 0.] + + Description [Implements the solution for F(x,y) = 0. The return + value is the consistency condition. The y variables are the unknowns + and the remaining variables are the parameters. Returns the + consistency condition if successful; NULL otherwise. Cudd_SolveEqn + allocates an array and fills it with the indices of the + unknowns. This array is used by Cudd_VerifySol.] + + SideEffects [The solution is returned in G; the indices of the y + variables are returned in yIndex.] + + SeeAlso [Cudd_VerifySol] + +******************************************************************************/ +DdNode * +Cudd_SolveEqn( + DdManager * bdd, + DdNode * F /* the left-hand side of the equation */, + DdNode * Y /* the cube of the y variables */, + DdNode ** G /* the array of solutions (return parameter) */, + int ** yIndex /* index of y variables */, + int n /* numbers of unknowns */) +{ + DdNode *res; + int *temp; + + *yIndex = temp = ALLOC(int, n); + if (temp == NULL) { + bdd->errorCode = CUDD_MEMORY_OUT; + (void) fprintf(bdd->out, + "Cudd_SolveEqn: Out of memory for yIndex\n"); + return(NULL); + } + + do { + bdd->reordered = 0; + res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0); + } while (bdd->reordered == 1); + + return(res); + +} /* end of Cudd_SolveEqn */ + + +/**Function******************************************************************** + + Synopsis [Checks the solution of F(x,y) = 0.] + + Description [Checks the solution of F(x,y) = 0. This procedure + substitutes the solution components for the unknowns of F and returns + the resulting BDD for F.] + + SideEffects [Frees the memory pointed by yIndex.] + + SeeAlso [Cudd_SolveEqn] + +******************************************************************************/ +DdNode * +Cudd_VerifySol( + DdManager * bdd, + DdNode * F /* the left-hand side of the equation */, + DdNode ** G /* the array of solutions */, + int * yIndex /* index of y variables */, + int n /* numbers of unknowns */) +{ + DdNode *res; + + do { + bdd->reordered = 0; + res = cuddVerifySol(bdd, F, G, yIndex, n); + } while (bdd->reordered == 1); + + FREE(yIndex); + + return(res); + +} /* end of Cudd_VerifySol */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_SolveEqn.] + + Description [Implements the recursive step of Cudd_SolveEqn. + Returns NULL if the intermediate solution blows up + or reordering occurs. The parametric solutions are + stored in the array G.] + + SideEffects [none] + + SeeAlso [Cudd_SolveEqn, Cudd_VerifySol] + +******************************************************************************/ +DdNode * +cuddSolveEqnRecur( + DdManager * bdd, + DdNode * F /* the left-hand side of the equation */, + DdNode * Y /* the cube of remaining y variables */, + DdNode ** G /* the array of solutions */, + int n /* number of unknowns */, + int * yIndex /* array holding the y variable indices */, + int i /* level of recursion */) +{ + DdNode *Fn, *Fm1, *Fv, *Fvbar, *T, *w, *nextY, *one; + DdNodePtr *variables; + + int j; + + statLine(bdd); + variables = bdd->vars; + one = DD_ONE(bdd); + + /* Base condition. */ + if (Y == one) { + return F; + } + + /* Cofactor of Y. */ + yIndex[i] = Y->index; + nextY = Cudd_T(Y); + + /* Universal abstraction of F with respect to the top variable index. */ + Fm1 = cuddBddExistAbstractRecur(bdd, Cudd_Not(F), variables[yIndex[i]]); + if (Fm1) { + Fm1 = Cudd_Not(Fm1); + cuddRef(Fm1); + } else { + return(NULL); + } + + Fn = cuddSolveEqnRecur(bdd, Fm1, nextY, G, n, yIndex, i+1); + if (Fn) { + cuddRef(Fn); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + return(NULL); + } + + Fv = cuddCofactorRecur(bdd, F, variables[yIndex[i]]); + if (Fv) { + cuddRef(Fv); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + return(NULL); + } + + Fvbar = cuddCofactorRecur(bdd, F, Cudd_Not(variables[yIndex[i]])); + if (Fvbar) { + cuddRef(Fvbar); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + return(NULL); + } + + /* Build i-th component of the solution. */ + w = cuddBddIteRecur(bdd, variables[yIndex[i]], Cudd_Not(Fv), Fvbar); + if (w) { + cuddRef(w); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + Cudd_RecursiveDeref(bdd, Fvbar); + return(NULL); + } + + T = cuddBddRestrictRecur(bdd, w, Cudd_Not(Fm1)); + if(T) { + cuddRef(T); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + Cudd_RecursiveDeref(bdd, Fvbar); + Cudd_RecursiveDeref(bdd, w); + return(NULL); + } + + Cudd_RecursiveDeref(bdd,Fm1); + Cudd_RecursiveDeref(bdd,w); + Cudd_RecursiveDeref(bdd,Fv); + Cudd_RecursiveDeref(bdd,Fvbar); + + /* Substitute components of solution already found into solution. */ + for (j = n-1; j > i; j--) { + w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]); + if(w) { + cuddRef(w); + } else { + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, T); + return(NULL); + } + Cudd_RecursiveDeref(bdd,T); + T = w; + } + G[i] = T; + + Cudd_Deref(Fn); + + return(Fn); + +} /* end of cuddSolveEqnRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_VerifySol. ] + + Description [] + + SideEffects [none] + + SeeAlso [Cudd_VerifySol] + +******************************************************************************/ +DdNode * +cuddVerifySol( + DdManager * bdd, + DdNode * F /* the left-hand side of the equation */, + DdNode ** G /* the array of solutions */, + int * yIndex /* array holding the y variable indices */, + int n /* number of unknowns */) +{ + DdNode *w, *R; + + int j; + + R = F; + cuddRef(R); + for(j = n - 1; j >= 0; j--) { + w = Cudd_bddCompose(bdd, R, G[j], yIndex[j]); + if (w) { + cuddRef(w); + } else { + return(NULL); + } + Cudd_RecursiveDeref(bdd,R); + R = w; + } + + cuddDeref(R); + + return(R); + +} /* end of cuddVerifySol */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSplit.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSplit.c new file mode 100644 index 000000000..11fe86267 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSplit.c @@ -0,0 +1,686 @@ +/**CFile*********************************************************************** + + FileName [cuddSplit.c] + + PackageName [cudd] + + Synopsis [Returns a subset of minterms from a boolean function.] + + Description [External functions included in this modoule: +
        +
      • Cudd_SplitSet() +
      + Internal functions included in this module: +
        +
      • cuddSplitSetRecur() + + Static functions included in this module: +
          +
        • selectMintermsFromUniverse() +
        • mintermsFromUniverse() +
        • bddAnnotateMintermCount() +
        ] + + SeeAlso [] + + Author [Balakrishna Kumthekar] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * selectMintermsFromUniverse (DdManager *manager, int *varSeen, double n); +static DdNode * mintermsFromUniverse (DdManager *manager, DdNode **vars, int numVars, double n, int index); +static double bddAnnotateMintermCount (DdManager *manager, DdNode *node, double max, st_table *table); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns m minterms from a BDD.] + + Description [Returns m minterms from a BDD whose + support has n variables at most. The procedure tries + to create as few extra nodes as possible. The function represented + by S depends on at most n of the variables + in xVars. Returns a BDD with m minterms + of the on-set of S if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_SplitSet( + DdManager * manager, + DdNode * S, + DdNode ** xVars, + int n, + double m) +{ + DdNode *result; + DdNode *zero, *one; + double max, num; + st_table *mtable; + int *varSeen; + int i,index, size; + + size = manager->size; + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Trivial cases. */ + if (m == 0.0) { + return(zero); + } + if (S == zero) { + return(NULL); + } + + max = pow(2.0,(double)n); + if (m > max) + return(NULL); + + do { + manager->reordered = 0; + /* varSeen is used to mark the variables that are encountered + ** while traversing the BDD S. + */ + varSeen = ALLOC(int, size); + if (varSeen == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + varSeen[i] = -1; + } + for (i = 0; i < n; i++) { + index = (xVars[i])->index; + varSeen[manager->invperm[index]] = 0; + } + + if (S == one) { + if (m == max) { + FREE(varSeen); + return(S); + } + result = selectMintermsFromUniverse(manager,varSeen,m); + if (result) + cuddRef(result); + FREE(varSeen); + } else { + mtable = st_init_table(st_ptrcmp,st_ptrhash); + if (mtable == NULL) { + (void) fprintf(manager->out, + "Cudd_SplitSet: out-of-memory.\n"); + FREE(varSeen); + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + /* The nodes of BDD S are annotated by the number of minterms + ** in their onset. The node and the number of minterms in its + ** onset are stored in mtable. + */ + num = bddAnnotateMintermCount(manager,S,max,mtable); + if (m == num) { + st_foreach(mtable,cuddStCountfree,NIL(char)); + st_free_table(mtable); + FREE(varSeen); + return(S); + } + + result = cuddSplitSetRecur(manager,mtable,varSeen,S,m,max,0); + if (result) + cuddRef(result); + st_foreach(mtable,cuddStCountfree,NULL); + st_free_table(mtable); + FREE(varSeen); + } + } while (manager->reordered == 1); + + cuddDeref(result); + return(result); + +} /* end of Cudd_SplitSet */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_SplitSet.] + + Description [Implements the recursive step of Cudd_SplitSet. The + procedure recursively traverses the BDD and checks to see if any + node satisfies the minterm requirements as specified by 'n'. At any + node X, n is compared to the number of minterms in the onset of X's + children. If either of the child nodes have exactly n minterms, then + that node is returned; else, if n is greater than the onset of one + of the child nodes, that node is retained and the difference in the + number of minterms is extracted from the other child. In case n + minterms can be extracted from constant 1, the algorithm returns the + result with at most log(n) nodes.] + + SideEffects [The array 'varSeen' is updated at every recursive call + to set the variables traversed by the procedure.] + + SeeAlso [] + +******************************************************************************/ +DdNode* +cuddSplitSetRecur( + DdManager * manager, + st_table * mtable, + int * varSeen, + DdNode * p, + double n, + double max, + int index) +{ + DdNode *one, *zero, *N, *Nv; + DdNode *Nnv, *q, *r, *v; + DdNode *result; + double *dummy, numT, numE; + int variable, positive; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* If p is constant, extract n minterms from constant 1. The procedure by + ** construction guarantees that minterms will not be extracted from + ** constant 0. + */ + if (Cudd_IsConstant(p)) { + q = selectMintermsFromUniverse(manager,varSeen,n); + return(q); + } + + N = Cudd_Regular(p); + + /* Set variable as seen. */ + variable = N->index; + varSeen[manager->invperm[variable]] = -1; + + Nv = cuddT(N); + Nnv = cuddE(N); + if (Cudd_IsComplement(p)) { + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); + } + + /* If both the children of 'p' are constants, extract n minterms from a + ** constant node. + */ + if (Cudd_IsConstant(Nv) && Cudd_IsConstant(Nnv)) { + q = selectMintermsFromUniverse(manager,varSeen,n); + if (q == NULL) { + return(NULL); + } + cuddRef(q); + r = cuddBddAndRecur(manager,p,q); + if (r == NULL) { + Cudd_RecursiveDeref(manager,q); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDeref(manager,q); + cuddDeref(r); + return(r); + } + + /* Lookup the # of minterms in the onset of the node from the table. */ + if (!Cudd_IsConstant(Nv)) { + if (!st_lookup(mtable, Nv, &dummy)) return(NULL); + numT = *dummy/(2*(1<size; + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Count the number of variables not encountered so far in procedure + ** cuddSplitSetRecur. + */ + for (i = size-1; i >= 0; i--) { + if(varSeen[i] == 0) + numVars++; + } + vars = ALLOC(DdNode *, numVars); + if (!vars) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + j = 0; + for (i = size-1; i >= 0; i--) { + if(varSeen[i] == 0) { + vars[j] = cuddUniqueInter(manager,manager->perm[i],one,zero); + cuddRef(vars[j]); + j++; + } + } + + /* Compute a function which has n minterms and depends on at most + ** numVars variables. + */ + result = mintermsFromUniverse(manager,vars,numVars,n, 0); + if (result) + cuddRef(result); + + for (i = 0; i < numVars; i++) + Cudd_RecursiveDeref(manager,vars[i]); + FREE(vars); + + return(result); + +} /* end of selectMintermsFromUniverse */ + + +/**Function******************************************************************** + + Synopsis [Recursive procedure to extract n mintems from constant 1.] + + Description [Recursive procedure to extract n mintems from constant 1.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +mintermsFromUniverse( + DdManager * manager, + DdNode ** vars, + int numVars, + double n, + int index) +{ + DdNode *one, *zero; + DdNode *q, *result; + double max, max2; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + max = pow(2.0, (double)numVars); + max2 = max / 2.0; + + if (n == max) + return(one); + if (n == 0.0) + return(zero); + /* if n == 2^(numVars-1), return a single variable */ + if (n == max2) + return vars[index]; + else if (n > max2) { + /* When n > 2^(numVars-1), a single variable vars[index] + ** contains 2^(numVars-1) minterms. The rest are extracted + ** from a constant with 1 less variable. + */ + q = mintermsFromUniverse(manager,vars,numVars-1,(n-max2),index+1); + if (q == NULL) + return(NULL); + cuddRef(q); + result = cuddBddIteRecur(manager,vars[index],one,q); + } else { + /* When n < 2^(numVars-1), a literal of variable vars[index] + ** is selected. The required n minterms are extracted from a + ** constant with 1 less variable. + */ + q = mintermsFromUniverse(manager,vars,numVars-1,n,index+1); + if (q == NULL) + return(NULL); + cuddRef(q); + result = cuddBddAndRecur(manager,vars[index],q); + } + + if (result == NULL) { + Cudd_RecursiveDeref(manager,q); + return(NULL); + } + cuddRef(result); + Cudd_RecursiveDeref(manager,q); + cuddDeref(result); + return(result); + +} /* end of mintermsFromUniverse */ + + +/**Function******************************************************************** + + Synopsis [Annotates every node in the BDD node with its minterm count.] + + Description [Annotates every node in the BDD node with its minterm count. + In this function, every node and the minterm count represented by it are + stored in a hash table.] + + SideEffects [Fills up 'table' with the pair .] + +******************************************************************************/ +static double +bddAnnotateMintermCount( + DdManager * manager, + DdNode * node, + double max, + st_table * table) +{ + + DdNode *N,*Nv,*Nnv; + register double min_v,min_nv; + register double min_N; + double *pmin; + double *dummy; + + statLine(manager); + N = Cudd_Regular(node); + if (cuddIsConstant(N)) { + if (node == DD_ONE(manager)) { + return(max); + } else { + return(0.0); + } + } + + if (st_lookup(table, node, &dummy)) { + return(*dummy); + } + + Nv = cuddT(N); + Nnv = cuddE(N); + if (N != node) { + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); + } + + /* Recur on the two branches. */ + min_v = bddAnnotateMintermCount(manager,Nv,max,table) / 2.0; + if (min_v == (double)CUDD_OUT_OF_MEM) + return ((double)CUDD_OUT_OF_MEM); + min_nv = bddAnnotateMintermCount(manager,Nnv,max,table) / 2.0; + if (min_nv == (double)CUDD_OUT_OF_MEM) + return ((double)CUDD_OUT_OF_MEM); + min_N = min_v + min_nv; + + pmin = ALLOC(double,1); + if (pmin == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + *pmin = min_N; + + if (st_insert(table,(char *)node, (char *)pmin) == ST_OUT_OF_MEM) { + FREE(pmin); + return((double)CUDD_OUT_OF_MEM); + } + + return(min_N); + +} /* end of bddAnnotateMintermCount */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetHB.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetHB.c new file mode 100644 index 000000000..bb0f847b2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetHB.c @@ -0,0 +1,1331 @@ +/**CFile*********************************************************************** + + FileName [cuddSubsetHB.c] + + PackageName [cudd] + + Synopsis [Procedure to subset the given BDD by choosing the heavier + branches.] + + + Description [External procedures provided by this module: +
          +
        • Cudd_SubsetHeavyBranch() +
        • Cudd_SupersetHeavyBranch() +
        + Internal procedures included in this module: +
          +
        • cuddSubsetHeavyBranch() +
        + Static procedures included in this module: +
          +
        • ResizeCountMintermPages(); +
        • ResizeNodeDataPages() +
        • ResizeCountNodePages() +
        • SubsetCountMintermAux() +
        • SubsetCountMinterm() +
        • SubsetCountNodesAux() +
        • SubsetCountNodes() +
        • BuildSubsetBdd() +
        + ] + + SeeAlso [cuddSubsetSP.c] + + Author [Kavita Ravi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#ifdef __STDC__ +#include +#else +#define DBL_MAX_EXP 1024 +#endif +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DEFAULT_PAGE_SIZE 2048 +#define DEFAULT_NODE_DATA_PAGE_SIZE 1024 +#define INITIAL_PAGES 128 + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/* data structure to store the information on each node. It keeps + * the number of minterms represented by the DAG rooted at this node + * in terms of the number of variables specified by the user, number + * of nodes in this DAG and the number of nodes of its child with + * lesser number of minterms that are not shared by the child with + * more minterms + */ +struct NodeData { + double *mintermPointer; + int *nodesPointer; + int *lightChildNodesPointer; +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct NodeData NodeData_t; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSubsetHB.c,v 1.39 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int memOut; +#ifdef DEBUG +static int num_calls; +#endif + +static DdNode *zero, *one; /* constant functions */ +static double **mintermPages; /* pointers to the pages */ +static int **nodePages; /* pointers to the pages */ +static int **lightNodePages; /* pointers to the pages */ +static double *currentMintermPage; /* pointer to the current + page */ +static double max; /* to store the 2^n value of the number + * of variables */ + +static int *currentNodePage; /* pointer to the current + page */ +static int *currentLightNodePage; /* pointer to the + * current page */ +static int pageIndex; /* index to next element */ +static int page; /* index to current page */ +static int pageSize = DEFAULT_PAGE_SIZE; /* page size */ +static int maxPages; /* number of page pointers */ + +static NodeData_t *currentNodeDataPage; /* pointer to the current + page */ +static int nodeDataPage; /* index to next element */ +static int nodeDataPageIndex; /* index to next element */ +static NodeData_t **nodeDataPages; /* index to current page */ +static int nodeDataPageSize = DEFAULT_NODE_DATA_PAGE_SIZE; + /* page size */ +static int maxNodeDataPages; /* number of page pointers */ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void ResizeNodeDataPages (void); +static void ResizeCountMintermPages (void); +static void ResizeCountNodePages (void); +static double SubsetCountMintermAux (DdNode *node, double max, st_table *table); +static st_table * SubsetCountMinterm (DdNode *node, int nvars); +static int SubsetCountNodesAux (DdNode *node, st_table *table, double max); +static int SubsetCountNodes (DdNode *node, st_table *table, int nvars); +static void StoreNodes (st_table *storeTable, DdManager *dd, DdNode *node); +static DdNode * BuildSubsetBdd (DdManager *dd, DdNode *node, int *size, st_table *visitedTable, int threshold, st_table *storeTable, st_table *approxTable); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the heavy branch + heuristic.] + + Description [Extracts a dense subset from a BDD. This procedure + builds a subset by throwing away one of the children of each node, + starting from the root, until the result is small enough. The child + that is eliminated from the result is the one that contributes the + fewer minterms. Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation and node count calculation. The optimal number should + be as close as possible to the size of the support of f. However, + it is safe to pass the value returned by Cudd_ReadSize for numVars + when the number of variables is under 1023. If numVars is larger + than 1023, it will overflow. If a 0 parameter is passed then the + procedure will compute a value which will avoid overflow but will + cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SupersetHeavyBranch Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_SubsetHeavyBranch( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the subset */) +{ + DdNode *subset; + + memOut = 0; + do { + dd->reordered = 0; + subset = cuddSubsetHeavyBranch(dd, f, numVars, threshold); + } while ((dd->reordered == 1) && (!memOut)); + + return(subset); + +} /* end of Cudd_SubsetHeavyBranch */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the heavy branch + heuristic.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the subset procedure except for the fact that it + receives the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. This procedure builds a superset by throwing away + one of the children of each node starting from the root of the + complement function, until the result is small enough. The child + that is eliminated from the result is the one that contributes the + fewer minterms. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation and node count calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_SupersetHeavyBranch( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the superset */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + memOut = 0; + do { + dd->reordered = 0; + subset = cuddSubsetHeavyBranch(dd, g, numVars, threshold); + } while ((dd->reordered == 1) && (!memOut)); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_SupersetHeavyBranch */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [The main procedure that returns a subset by choosing the heavier + branch in the BDD.] + + Description [Here a subset BDD is built by throwing away one of the + children. Starting at root, annotate each node with the number of + minterms (in terms of the total number of variables specified - + numVars), number of nodes taken by the DAG rooted at this node and + number of additional nodes taken by the child that has the lesser + minterms. The child with the lower number of minterms is thrown away + and a dyanmic count of the nodes of the subset is kept. Once the + threshold is reached the subset is returned to the calling + procedure.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetHeavyBranch] + +******************************************************************************/ +DdNode * +cuddSubsetHeavyBranch( + DdManager * dd /* DD manager */, + DdNode * f /* current DD */, + int numVars /* maximum number of variables */, + int threshold /* threshold size for the subset */) +{ + + int i, *size; + st_table *visitedTable; + int numNodes; + NodeData_t *currNodeQual; + DdNode *subset; + st_table *storeTable, *approxTable; + DdNode *key, *value; + st_generator *stGen; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + one = Cudd_ReadOne(dd); + zero = Cudd_Not(one); + + /* If user does not know numVars value, set it to the maximum + * exponent that the pow function can take. The -1 is due to the + * discrepancy in the value that pow takes and the value that + * log gives. + */ + if (numVars == 0) { + /* set default value */ + numVars = DBL_MAX_EXP - 1; + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + max = pow(2.0, (double)numVars); + + /* Create visited table where structures for node data are allocated and + stored in a st_table */ + visitedTable = SubsetCountMinterm(f, numVars); + if ((visitedTable == NULL) || memOut) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + numNodes = SubsetCountNodes(f, visitedTable, numVars); + if (memOut) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + + if (st_lookup(visitedTable, f, &currNodeQual) == 0) { + fprintf(dd->err, + "Something is wrong, ought to be node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + } + + size = ALLOC(int, 1); + if (size == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + *size = numNodes; + +#ifdef DEBUG + num_calls = 0; +#endif + /* table to store nodes being created. */ + storeTable = st_init_table(st_ptrcmp, st_ptrhash); + /* insert the constant */ + cuddRef(one); + if (st_insert(storeTable, Cudd_ReadOne(dd), NULL) == + ST_OUT_OF_MEM) { + fprintf(dd->out, "Something wrong, st_table insert failed\n"); + } + /* table to store approximations of nodes */ + approxTable = st_init_table(st_ptrcmp, st_ptrhash); + subset = (DdNode *)BuildSubsetBdd(dd, f, size, visitedTable, threshold, + storeTable, approxTable); + if (subset != NULL) { + cuddRef(subset); + } + + stGen = st_init_gen(approxTable); + if (stGen == NULL) { + st_free_table(approxTable); + return(NULL); + } + while(st_gen(stGen, &key, &value)) { + Cudd_RecursiveDeref(dd, value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(approxTable); + + stGen = st_init_gen(storeTable); + if (stGen == NULL) { + st_free_table(storeTable); + return(NULL); + } + while(st_gen(stGen, &key, &value)) { + Cudd_RecursiveDeref(dd, key); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(storeTable); + + for (i = 0; i <= page; i++) { + FREE(mintermPages[i]); + } + FREE(mintermPages); + for (i = 0; i <= page; i++) { + FREE(nodePages[i]); + } + FREE(nodePages); + for (i = 0; i <= page; i++) { + FREE(lightNodePages[i]); + } + FREE(lightNodePages); + for (i = 0; i <= nodeDataPage; i++) { + FREE(nodeDataPages[i]); + } + FREE(nodeDataPages); + st_free_table(visitedTable); + FREE(size); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + + if (subset != NULL) { +#ifdef DD_DEBUG + if (!Cudd_bddLeq(dd, subset, f)) { + fprintf(dd->err, "Wrong subset\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } +#endif + cuddDeref(subset); + return(subset); + } else { + return(NULL); + } +} /* end of cuddSubsetHeavyBranch */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store the node data.] + + Description [Resize the number of pages allocated to store the node data + The procedure moves the counter to the next page when the end of + the page is reached and allocates new pages when necessary.] + + SideEffects [Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. ] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeNodeDataPages(void) +{ + int i; + NodeData_t **newNodeDataPages; + + nodeDataPage++; + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. Page numbers are incremented by + * INITIAL_PAGES + */ + if (nodeDataPage == maxNodeDataPages) { + newNodeDataPages = ALLOC(NodeData_t *,maxNodeDataPages + INITIAL_PAGES); + if (newNodeDataPages == NULL) { + for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + memOut = 1; + return; + } else { + for (i = 0; i < maxNodeDataPages; i++) { + newNodeDataPages[i] = nodeDataPages[i]; + } + /* Increase total page count */ + maxNodeDataPages += INITIAL_PAGES; + FREE(nodeDataPages); + nodeDataPages = newNodeDataPages; + } + } + /* Allocate a new page */ + currentNodeDataPage = nodeDataPages[nodeDataPage] = + ALLOC(NodeData_t ,nodeDataPageSize); + if (currentNodeDataPage == NULL) { + for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + memOut = 1; + return; + } + /* reset page index */ + nodeDataPageIndex = 0; + return; + +} /* end of ResizeNodeDataPages */ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store the minterm + counts. ] + + Description [Resize the number of pages allocated to store the minterm + counts. The procedure moves the counter to the next page when the + end of the page is reached and allocates new pages when necessary.] + + SideEffects [Changes the size of minterm pages, page, page index, maximum + number of pages freeing stuff in case of memory out. ] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeCountMintermPages(void) +{ + int i; + double **newMintermPages; + + page++; + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. Page numbers are incremented by + * INITIAL_PAGES + */ + if (page == maxPages) { + newMintermPages = ALLOC(double *,maxPages + INITIAL_PAGES); + if (newMintermPages == NULL) { + for (i = 0; i < page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newMintermPages[i] = mintermPages[i]; + } + /* Increase total page count */ + maxPages += INITIAL_PAGES; + FREE(mintermPages); + mintermPages = newMintermPages; + } + } + /* Allocate a new page */ + currentMintermPage = mintermPages[page] = ALLOC(double,pageSize); + if (currentMintermPage == NULL) { + for (i = 0; i < page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + memOut = 1; + return; + } + /* reset page index */ + pageIndex = 0; + return; + +} /* end of ResizeCountMintermPages */ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store the node counts.] + + Description [Resize the number of pages allocated to store the node counts. + The procedure moves the counter to the next page when the end of + the page is reached and allocates new pages when necessary.] + + SideEffects [Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out.] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeCountNodePages(void) +{ + int i; + int **newNodePages; + + page++; + + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. The number of pages is incremented + * by INITIAL_PAGES. + */ + if (page == maxPages) { + newNodePages = ALLOC(int *,maxPages + INITIAL_PAGES); + if (newNodePages == NULL) { + for (i = 0; i < page; i++) FREE(nodePages[i]); + FREE(nodePages); + for (i = 0; i < page; i++) FREE(lightNodePages[i]); + FREE(lightNodePages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newNodePages[i] = nodePages[i]; + } + FREE(nodePages); + nodePages = newNodePages; + } + + newNodePages = ALLOC(int *,maxPages + INITIAL_PAGES); + if (newNodePages == NULL) { + for (i = 0; i < page; i++) FREE(nodePages[i]); + FREE(nodePages); + for (i = 0; i < page; i++) FREE(lightNodePages[i]); + FREE(lightNodePages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newNodePages[i] = lightNodePages[i]; + } + FREE(lightNodePages); + lightNodePages = newNodePages; + } + /* Increase total page count */ + maxPages += INITIAL_PAGES; + } + /* Allocate a new page */ + currentNodePage = nodePages[page] = ALLOC(int,pageSize); + if (currentNodePage == NULL) { + for (i = 0; i < page; i++) FREE(nodePages[i]); + FREE(nodePages); + for (i = 0; i < page; i++) FREE(lightNodePages[i]); + FREE(lightNodePages); + memOut = 1; + return; + } + /* Allocate a new page */ + currentLightNodePage = lightNodePages[page] = ALLOC(int,pageSize); + if (currentLightNodePage == NULL) { + for (i = 0; i <= page; i++) FREE(nodePages[i]); + FREE(nodePages); + for (i = 0; i < page; i++) FREE(lightNodePages[i]); + FREE(lightNodePages); + memOut = 1; + return; + } + /* reset page index */ + pageIndex = 0; + return; + +} /* end of ResizeCountNodePages */ + + +/**Function******************************************************************** + + Synopsis [Recursively counts minterms of each node in the DAG.] + + Description [Recursively counts minterms of each node in the DAG. + Similar to the cuddCountMintermAux which recursively counts the + number of minterms for the dag rooted at each node in terms of the + total number of variables (max). This procedure creates the node + data structure and stores the minterm count as part of the node + data structure. ] + + SideEffects [Creates structures of type node quality and fills the st_table] + + SeeAlso [SubsetCountMinterm] + +******************************************************************************/ +static double +SubsetCountMintermAux( + DdNode * node /* function to analyze */, + double max /* number of minterms of constant 1 */, + st_table * table /* visitedTable table */) +{ + + DdNode *N,*Nv,*Nnv; /* nodes to store cofactors */ + double min,*pmin; /* minterm count */ + double min1, min2; /* minterm count */ + NodeData_t *dummy; + NodeData_t *newEntry; + int i; + +#ifdef DEBUG + num_calls++; +#endif + + /* Constant case */ + if (Cudd_IsConstant(node)) { + if (node == zero) { + return(0.0); + } else { + return(max); + } + } else { + + /* check if entry for this node exists */ + if (st_lookup(table, node, &dummy)) { + min = *(dummy->mintermPointer); + return(min); + } + + /* Make the node regular to extract cofactors */ + N = Cudd_Regular(node); + + /* store the cofactors */ + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + min1 = SubsetCountMintermAux(Nv, max,table)/2.0; + if (memOut) return(0.0); + min2 = SubsetCountMintermAux(Nnv,max,table)/2.0; + if (memOut) return(0.0); + min = (min1+min2); + + /* if page index is at the bottom, then create a new page */ + if (pageIndex == pageSize) ResizeCountMintermPages(); + if (memOut) { + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0.0); + } + + /* point to the correct location in the page */ + pmin = currentMintermPage+pageIndex; + pageIndex++; + + /* store the minterm count of this node in the page */ + *pmin = min; + + /* Note I allocate the struct here. Freeing taken care of later */ + if (nodeDataPageIndex == nodeDataPageSize) ResizeNodeDataPages(); + if (memOut) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + st_free_table(table); + return(0.0); + } + + newEntry = currentNodeDataPage + nodeDataPageIndex; + nodeDataPageIndex++; + + /* points to the correct location in the page */ + newEntry->mintermPointer = pmin; + /* initialize this field of the Node Quality structure */ + newEntry->nodesPointer = NULL; + + /* insert entry for the node in the table */ + if (st_insert(table,node, newEntry) == ST_OUT_OF_MEM) { + memOut = 1; + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0.0); + } + return(min); + } + +} /* end of SubsetCountMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Counts minterms of each node in the DAG] + + Description [Counts minterms of each node in the DAG. Similar to the + Cudd_CountMinterm procedure except this returns the minterm count for + all the nodes in the bdd in an st_table.] + + SideEffects [none] + + SeeAlso [SubsetCountMintermAux] + +******************************************************************************/ +static st_table * +SubsetCountMinterm( + DdNode * node /* function to be analyzed */, + int nvars /* number of variables node depends on */) +{ + st_table *table; + int i; + + +#ifdef DEBUG + num_calls = 0; +#endif + + max = pow(2.0,(double) nvars); + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) goto OUT_OF_MEM; + maxPages = INITIAL_PAGES; + mintermPages = ALLOC(double *,maxPages); + if (mintermPages == NULL) { + st_free_table(table); + goto OUT_OF_MEM; + } + page = 0; + currentMintermPage = ALLOC(double,pageSize); + mintermPages[page] = currentMintermPage; + if (currentMintermPage == NULL) { + FREE(mintermPages); + st_free_table(table); + goto OUT_OF_MEM; + } + pageIndex = 0; + maxNodeDataPages = INITIAL_PAGES; + nodeDataPages = ALLOC(NodeData_t *, maxNodeDataPages); + if (nodeDataPages == NULL) { + for (i = 0; i <= page ; i++) FREE(mintermPages[i]); + FREE(mintermPages); + st_free_table(table); + goto OUT_OF_MEM; + } + nodeDataPage = 0; + currentNodeDataPage = ALLOC(NodeData_t ,nodeDataPageSize); + nodeDataPages[nodeDataPage] = currentNodeDataPage; + if (currentNodeDataPage == NULL) { + for (i = 0; i <= page ; i++) FREE(mintermPages[i]); + FREE(mintermPages); + FREE(nodeDataPages); + st_free_table(table); + goto OUT_OF_MEM; + } + nodeDataPageIndex = 0; + + (void) SubsetCountMintermAux(node,max,table); + if (memOut) goto OUT_OF_MEM; + return(table); + +OUT_OF_MEM: + memOut = 1; + return(NULL); + +} /* end of SubsetCountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node.] + + Description [Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node. . Note that the same dag may be the lighter child of two + different nodes and have different counts. As with the minterm counts, + the node counts are stored in pages to be space efficient and the + address for these node counts are stored in an st_table associated + to each node. ] + + SideEffects [Updates the node data table with node counts] + + SeeAlso [SubsetCountNodes] + +******************************************************************************/ +static int +SubsetCountNodesAux( + DdNode * node /* current node */, + st_table * table /* table to update node count, also serves as visited table. */, + double max /* maximum number of variables */) +{ + int tval, eval, i; + DdNode *N, *Nv, *Nnv; + double minNv, minNnv; + NodeData_t *dummyN, *dummyNv, *dummyNnv, *dummyNBar; + int *pmin, *pminBar, *val; + + if ((node == NULL) || Cudd_IsConstant(node)) + return(0); + + /* if this node has been processed do nothing */ + if (st_lookup(table, node, &dummyN) == 1) { + val = dummyN->nodesPointer; + if (val != NULL) + return(0); + } else { + return(0); + } + + N = Cudd_Regular(node); + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* find the minterm counts for the THEN and ELSE branches */ + if (Cudd_IsConstant(Nv)) { + if (Nv == zero) { + minNv = 0.0; + } else { + minNv = max; + } + } else { + if (st_lookup(table, Nv, &dummyNv) == 1) + minNv = *(dummyNv->mintermPointer); + else { + return(0); + } + } + if (Cudd_IsConstant(Nnv)) { + if (Nnv == zero) { + minNnv = 0.0; + } else { + minNnv = max; + } + } else { + if (st_lookup(table, Nnv, &dummyNnv) == 1) { + minNnv = *(dummyNnv->mintermPointer); + } + else { + return(0); + } + } + + + /* recur based on which has larger minterm, */ + if (minNv >= minNnv) { + tval = SubsetCountNodesAux(Nv, table, max); + if (memOut) return(0); + eval = SubsetCountNodesAux(Nnv, table, max); + if (memOut) return(0); + + /* store the node count of the lighter child. */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pmin = currentLightNodePage + pageIndex; + *pmin = eval; /* Here the ELSE child is lighter */ + dummyN->lightChildNodesPointer = pmin; + + } else { + eval = SubsetCountNodesAux(Nnv, table, max); + if (memOut) return(0); + tval = SubsetCountNodesAux(Nv, table, max); + if (memOut) return(0); + + /* store the node count of the lighter child. */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pmin = currentLightNodePage + pageIndex; + *pmin = tval; /* Here the THEN child is lighter */ + dummyN->lightChildNodesPointer = pmin; + + } + /* updating the page index for node count storage. */ + pmin = currentNodePage + pageIndex; + *pmin = tval + eval + 1; + dummyN->nodesPointer = pmin; + + /* pageIndex is parallel page index for count_nodes and count_lightNodes */ + pageIndex++; + + /* if this node has been reached first, it belongs to a heavier + branch. Its complement will be reached later on a lighter branch. + Hence the complement has zero node count. */ + + if (st_lookup(table, Cudd_Not(node), &dummyNBar) == 1) { + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i < page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pminBar = currentLightNodePage + pageIndex; + *pminBar = 0; + dummyNBar->lightChildNodesPointer = pminBar; + /* The lighter child has less nodes than the parent. + * So if parent 0 then lighter child zero + */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i < page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pminBar = currentNodePage + pageIndex; + *pminBar = 0; + dummyNBar->nodesPointer = pminBar ; /* maybe should point to zero */ + + pageIndex++; + } + return(*pmin); +} /*end of SubsetCountNodesAux */ + + +/**Function******************************************************************** + + Synopsis [Counts the nodes under the current node and its lighter child] + + Description [Counts the nodes under the current node and its lighter + child. Calls a recursive procedure to count the number of nodes of + a DAG rooted at a particular node and the number of nodes taken by its + lighter child.] + + SideEffects [None] + + SeeAlso [SubsetCountNodesAux] + +******************************************************************************/ +static int +SubsetCountNodes( + DdNode * node /* function to be analyzed */, + st_table * table /* node quality table */, + int nvars /* number of variables node depends on */) +{ + int num; + int i; + +#ifdef DEBUG + num_calls = 0; +#endif + + max = pow(2.0,(double) nvars); + maxPages = INITIAL_PAGES; + nodePages = ALLOC(int *,maxPages); + if (nodePages == NULL) { + goto OUT_OF_MEM; + } + + lightNodePages = ALLOC(int *,maxPages); + if (lightNodePages == NULL) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + FREE(nodePages); + goto OUT_OF_MEM; + } + + page = 0; + currentNodePage = nodePages[page] = ALLOC(int,pageSize); + if (currentNodePage == NULL) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + FREE(lightNodePages); + FREE(nodePages); + goto OUT_OF_MEM; + } + + currentLightNodePage = lightNodePages[page] = ALLOC(int,pageSize); + if (currentLightNodePage == NULL) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + FREE(currentNodePage); + FREE(lightNodePages); + FREE(nodePages); + goto OUT_OF_MEM; + } + + pageIndex = 0; + num = SubsetCountNodesAux(node,table,max); + if (memOut) goto OUT_OF_MEM; + return(num); + +OUT_OF_MEM: + memOut = 1; + return(0); + +} /* end of SubsetCountNodes */ + + +/**Function******************************************************************** + + Synopsis [Procedure to recursively store nodes that are retained in the subset.] + + Description [rocedure to recursively store nodes that are retained in the subset.] + + SideEffects [None] + + SeeAlso [StoreNodes] + +******************************************************************************/ +static void +StoreNodes( + st_table * storeTable, + DdManager * dd, + DdNode * node) +{ + DdNode *N, *Nt, *Ne; + if (Cudd_IsConstant(dd)) { + return; + } + N = Cudd_Regular(node); + if (st_lookup(storeTable, N, NULL)) { + return; + } + cuddRef(N); + if (st_insert(storeTable, N, NULL) == ST_OUT_OF_MEM) { + fprintf(dd->err,"Something wrong, st_table insert failed\n"); + } + + Nt = Cudd_T(N); + Ne = Cudd_E(N); + + StoreNodes(storeTable, dd, Nt); + StoreNodes(storeTable, dd, Ne); + return; + +} + + +/**Function******************************************************************** + + Synopsis [Builds the subset BDD using the heavy branch method.] + + Description [The procedure carries out the building of the subset BDD + starting at the root. Using the three different counts labelling each node, + the procedure chooses the heavier branch starting from the root and keeps + track of the number of nodes it discards at each step, thus keeping count + of the size of the subset BDD dynamically. Once the threshold is satisfied, + the procedure then calls ITE to build the BDD.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +BuildSubsetBdd( + DdManager * dd /* DD manager */, + DdNode * node /* current node */, + int * size /* current size of the subset */, + st_table * visitedTable /* visited table storing all node data */, + int threshold, + st_table * storeTable, + st_table * approxTable) +{ + + DdNode *Nv, *Nnv, *N, *topv, *neW; + double minNv, minNnv; + NodeData_t *currNodeQual; + NodeData_t *currNodeQualT; + NodeData_t *currNodeQualE; + DdNode *ThenBranch, *ElseBranch; + unsigned int topid; + char *dummy; + +#ifdef DEBUG + num_calls++; +#endif + /*If the size of the subset is below the threshold, dont do + anything. */ + if ((*size) <= threshold) { + /* store nodes below this, so we can recombine if possible */ + StoreNodes(storeTable, dd, node); + return(node); + } + + if (Cudd_IsConstant(node)) + return(node); + + /* Look up minterm count for this node. */ + if (!st_lookup(visitedTable, node, &currNodeQual)) { + fprintf(dd->err, + "Something is wrong, ought to be in node quality table\n"); + } + + /* Get children. */ + N = Cudd_Regular(node); + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + /* complement if necessary */ + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + if (!Cudd_IsConstant(Nv)) { + /* find out minterms and nodes contributed by then child */ + if (!st_lookup(visitedTable, Nv, &currNodeQualT)) { + fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + else { + minNv = *(((NodeData_t *)currNodeQualT)->mintermPointer); + } + } else { + if (Nv == zero) { + minNv = 0; + } else { + minNv = max; + } + } + if (!Cudd_IsConstant(Nnv)) { + /* find out minterms and nodes contributed by else child */ + if (!st_lookup(visitedTable, Nnv, &currNodeQualE)) { + fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } else { + minNnv = *(((NodeData_t *)currNodeQualE)->mintermPointer); + } + } else { + if (Nnv == zero) { + minNnv = 0; + } else { + minNnv = max; + } + } + + /* keep track of size of subset by subtracting the number of + * differential nodes contributed by lighter child + */ + *size = (*(size)) - (int)*(currNodeQual->lightChildNodesPointer); + if (minNv >= minNnv) { /*SubsetCountNodesAux procedure takes + the Then branch in case of a tie */ + + /* recur with the Then branch */ + ThenBranch = (DdNode *)BuildSubsetBdd(dd, Nv, size, + visitedTable, threshold, storeTable, approxTable); + if (ThenBranch == NULL) { + return(NULL); + } + cuddRef(ThenBranch); + /* The Else branch is either a node that already exists in the + * subset, or one whose approximation has been computed, or + * Zero. + */ + if (st_lookup(storeTable, Cudd_Regular(Nnv), &dummy)) { + ElseBranch = Nnv; + cuddRef(ElseBranch); + } else { + if (st_lookup(approxTable, Nnv, &dummy)) { + ElseBranch = (DdNode *)dummy; + cuddRef(ElseBranch); + } else { + ElseBranch = zero; + cuddRef(ElseBranch); + } + } + + } + else { + /* recur with the Else branch */ + ElseBranch = (DdNode *)BuildSubsetBdd(dd, Nnv, size, + visitedTable, threshold, storeTable, approxTable); + if (ElseBranch == NULL) { + return(NULL); + } + cuddRef(ElseBranch); + /* The Then branch is either a node that already exists in the + * subset, or one whose approximation has been computed, or + * Zero. + */ + if (st_lookup(storeTable, Cudd_Regular(Nv), &dummy)) { + ThenBranch = Nv; + cuddRef(ThenBranch); + } else { + if (st_lookup(approxTable, Nv, &dummy)) { + ThenBranch = (DdNode *)dummy; + cuddRef(ThenBranch); + } else { + ThenBranch = zero; + cuddRef(ThenBranch); + } + } + } + + /* construct the Bdd with the top variable and the two children */ + topid = Cudd_NodeReadIndex(N); + topv = Cudd_ReadVars(dd, topid); + cuddRef(topv); + neW = cuddBddIteRecur(dd, topv, ThenBranch, ElseBranch); + if (neW != NULL) { + cuddRef(neW); + } + Cudd_RecursiveDeref(dd, topv); + Cudd_RecursiveDeref(dd, ThenBranch); + Cudd_RecursiveDeref(dd, ElseBranch); + + + if (neW == NULL) + return(NULL); + else { + /* store this node in the store table */ + if (!st_lookup(storeTable, Cudd_Regular(neW), &dummy)) { + cuddRef(neW); + if (st_insert(storeTable, Cudd_Regular(neW), NULL) == + ST_OUT_OF_MEM) + return (NULL); + } + /* store the approximation for this node */ + if (N != Cudd_Regular(neW)) { + if (st_lookup(approxTable, node, &dummy)) { + fprintf(dd->err, "This node should not be in the approximated table\n"); + } else { + cuddRef(neW); + if (st_insert(approxTable, node, neW) == + ST_OUT_OF_MEM) + return(NULL); + } + } + cuddDeref(neW); + return(neW); + } +} /* end of BuildSubsetBdd */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetSP.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetSP.c new file mode 100644 index 000000000..fa89f167f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetSP.c @@ -0,0 +1,1660 @@ +/**CFile*********************************************************************** + + FileName [cuddSubsetSP.c] + + PackageName [cudd] + + Synopsis [Procedure to subset the given BDD choosing the shortest paths + (largest cubes) in the BDD.] + + + Description [External procedures included in this module: +
          +
        • Cudd_SubsetShortPaths() +
        • Cudd_SupersetShortPaths() +
        + Internal procedures included in this module: +
          +
        • cuddSubsetShortPaths() +
        + Static procedures included in this module: +
          +
        • BuildSubsetBdd() +
        • CreatePathTable() +
        • AssessPathLength() +
        • CreateTopDist() +
        • CreateBotDist() +
        • ResizeNodeDistPages() +
        • ResizeQueuePages() +
        • stPathTableDdFree() +
        + ] + + SeeAlso [cuddSubsetHB.c] + + Author [Kavita Ravi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DEFAULT_PAGE_SIZE 2048 /* page size to store the BFS queue element type */ +#define DEFAULT_NODE_DIST_PAGE_SIZE 2048 /* page size to store NodeDist_t type */ +#define MAXSHORTINT ((DdHalfWord) ~0) /* constant defined to store + * maximum distance of a node + * from the root or the constant + */ +#define INITIAL_PAGES 128 /* number of initial pages for the + * queue/NodeDist_t type */ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/* structure created to store subset results for each node and distances with + * odd and even parity of the node from the root and sink. Main data structure + * in this procedure. + */ +struct NodeDist { + DdHalfWord oddTopDist; + DdHalfWord evenTopDist; + DdHalfWord oddBotDist; + DdHalfWord evenBotDist; + DdNode *regResult; + DdNode *compResult; +}; + +/* assorted information needed by the BuildSubsetBdd procedure. */ +struct AssortedInfo { + unsigned int maxpath; + int findShortestPath; + int thresholdReached; + st_table *maxpathTable; + int threshold; +}; + +struct GlobalInfo { + struct NodeDist **nodeDistPages; /* pointers to the pages */ + int nodeDistPageIndex; /* index to next element */ + int nodeDistPage; /* index to current page */ + int nodeDistPageSize; /* page size */ + int maxNodeDistPages; /* number of page pointers */ + struct NodeDist *currentNodeDistPage; /* current page */ + DdNode ***queuePages; /* pointers to the pages */ + int queuePageIndex; /* index to next element */ + int queuePage; /* index to current page */ + int queuePageSize; /* page size */ + int maxQueuePages; /* number of page pointers */ + DdNode **currentQueuePage; /* current page */ +#ifdef DD_DEBUG + int numCalls; + int hits; + int thishit; +#endif +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct NodeDist NodeDist_t; +typedef struct GlobalInfo GlobalInfo_t; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSubsetSP.c,v 1.36 2012/02/05 01:07:19 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void ResizeNodeDistPages (DdManager *dd, GlobalInfo_t *gInfo); +static void ResizeQueuePages (DdManager *dd, GlobalInfo_t *gInfo); +static void CreateTopDist (DdManager *dd, GlobalInfo_t *gInfo, st_table *pathTable, int parentPage, int parentQueueIndex, int topLen, DdNode **childPage, int childQueueIndex, int numParents, FILE *fp); +static int CreateBotDist (DdNode *node, st_table *pathTable, unsigned int *pathLengthArray, FILE *fp); +static st_table * CreatePathTable (DdManager *dd, GlobalInfo_t *gInfo, DdNode *node, unsigned int *pathLengthArray, FILE *fp); +static unsigned int AssessPathLength (unsigned int *pathLengthArray, int threshold, int numVars, unsigned int *excess, FILE *fp); +static DdNode * BuildSubsetBdd (DdManager *dd, GlobalInfo_t *gInfo, st_table *pathTable, DdNode *node, struct AssortedInfo *info, st_table *subsetNodeTable); +static enum st_retval stPathTableDdFree (char *key, char *value, char *arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of Exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the shortest paths + heuristic.] + + Description [Extracts a dense subset from a BDD. This procedure + tries to preserve the shortest paths of the input BDD, because they + give many minterms and contribute few nodes. This procedure may + increase the number of nodes in trying to create the subset or + reduce the number of nodes due to recombination as compared to the + original BDD. Hence the threshold may not be strictly adhered to. In + practice, recombination overshadows the increase in the number of + nodes and results in small BDDs as compared to the threshold. The + hardlimit specifies whether threshold needs to be strictly adhered + to. If it is set to 1, the procedure ensures that result is never + larger than the specified limit but may be considerably less than + the threshold. Returns a pointer to the BDD for the subset if + successful; NULL otherwise. The value for numVars should be as + close as possible to the size of the support of f for better + efficiency. However, it is safe to pass the value returned by + Cudd_ReadSize for numVars. If 0 is passed, then the value returned + by Cudd_ReadSize is used.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_SubsetShortPaths( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the subset */, + int hardlimit /* flag: 1 if threshold is a hard limit */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddSubsetShortPaths(dd, f, numVars, threshold, hardlimit); + } while(dd->reordered == 1); + + return(subset); + +} /* end of Cudd_SubsetShortPaths */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the shortest paths + heuristic.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the subset procedure except for the fact that it + receives the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. This procedure tries to preserve the shortest + paths of the complement BDD, because they give many minterms and + contribute few nodes. This procedure may increase the number of + nodes in trying to create the superset or reduce the number of nodes + due to recombination as compared to the original BDD. Hence the + threshold may not be strictly adhered to. In practice, recombination + overshadows the increase in the number of nodes and results in small + BDDs as compared to the threshold. The hardlimit specifies whether + threshold needs to be strictly adhered to. If it is set to 1, the + procedure ensures that result is never larger than the specified + limit but may be considerably less than the threshold. Returns a + pointer to the BDD for the superset if successful; NULL + otherwise. The value for numVars should be as close as possible to + the size of the support of f for better efficiency. However, it is + safe to pass the value returned by Cudd_ReadSize for numVar. If 0 + is passed, then the value returned by Cudd_ReadSize is used.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SupersetHeavyBranch Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_SupersetShortPaths( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the subset */, + int hardlimit /* flag: 1 if threshold is a hard limit */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddSubsetShortPaths(dd, g, numVars, threshold, hardlimit); + } while(dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_SupersetShortPaths */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [The outermost procedure to return a subset of the given BDD + with the shortest path lengths.] + + Description [The outermost procedure to return a subset of the given + BDD with the largest cubes. The path lengths are calculated, the maximum + allowable path length is determined and the number of nodes of this + path length that can be used to build a subset. If the threshold is + larger than the size of the original BDD, the original BDD is + returned. ] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths] + +******************************************************************************/ +DdNode * +cuddSubsetShortPaths( + DdManager * dd /* DD manager */, + DdNode * f /* function to be subset */, + int numVars /* total number of variables in consideration */, + int threshold /* maximum number of nodes allowed in the subset */, + int hardlimit /* flag determining whether threshold should be respected strictly */) +{ + GlobalInfo_t gInfo; + st_table *pathTable; + DdNode *N, *subset; + + unsigned int *pathLengthArray; + unsigned int maxpath, oddLen, evenLen, pathLength, *excess; + int i; + NodeDist_t *nodeStat; + struct AssortedInfo *info; + st_table *subsetNodeTable; + + gInfo.nodeDistPageSize = DEFAULT_NODE_DIST_PAGE_SIZE; + gInfo.queuePageSize = DEFAULT_PAGE_SIZE; + + if (numVars == 0) { + /* set default value */ + numVars = Cudd_ReadSize(dd); + } + + if (threshold > numVars) { + threshold = threshold - numVars; + } + if (f == NULL) { + fprintf(dd->err, "Cannot partition, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + if (Cudd_IsConstant(f)) + return (f); + + pathLengthArray = ALLOC(unsigned int, numVars+1); + for (i = 0; i < numVars+1; i++) pathLengthArray[i] = 0; + + +#ifdef DD_DEBUG + gInfo.numCalls = 0; +#endif + + pathTable = CreatePathTable(dd, &gInfo, f, pathLengthArray, dd->err); + + if ((pathTable == NULL) || (dd->errorCode == CUDD_MEMORY_OUT)) { + if (pathTable != NULL) + st_free_table(pathTable); + FREE(pathLengthArray); + return (NIL(DdNode)); + } + + excess = ALLOC(unsigned int, 1); + *excess = 0; + maxpath = AssessPathLength(pathLengthArray, threshold, numVars, excess, + dd->err); + + if (maxpath != (unsigned) (numVars + 1)) { + + info = ALLOC(struct AssortedInfo, 1); + info->maxpath = maxpath; + info->findShortestPath = 0; + info->thresholdReached = *excess; + info->maxpathTable = st_init_table(st_ptrcmp, st_ptrhash); + info->threshold = threshold; + +#ifdef DD_DEBUG + (void) fprintf(dd->out, "Path length array\n"); + for (i = 0; i < (numVars+1); i++) { + if (pathLengthArray[i]) + (void) fprintf(dd->out, "%d ",i); + } + (void) fprintf(dd->out, "\n"); + for (i = 0; i < (numVars+1); i++) { + if (pathLengthArray[i]) + (void) fprintf(dd->out, "%d ",pathLengthArray[i]); + } + (void) fprintf(dd->out, "\n"); + (void) fprintf(dd->out, "Maxpath = %d, Thresholdreached = %d\n", + maxpath, info->thresholdReached); +#endif + + N = Cudd_Regular(f); + if (!st_lookup(pathTable, N, &nodeStat)) { + fprintf(dd->err, "Something wrong, root node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + FREE(excess); + FREE(info); + return(NULL); + } else { + if ((nodeStat->oddTopDist != MAXSHORTINT) && + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + else + oddLen = MAXSHORTINT; + + if ((nodeStat->evenTopDist != MAXSHORTINT) && + (nodeStat->evenBotDist != MAXSHORTINT)) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + else + evenLen = MAXSHORTINT; + + pathLength = (oddLen <= evenLen) ? oddLen : evenLen; + if (pathLength > maxpath) { + (void) fprintf(dd->err, "All computations are bogus, since root has path length greater than max path length within threshold %u, %u\n", maxpath, pathLength); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + } + +#ifdef DD_DEBUG + gInfo.numCalls = 0; + gInfo.hits = 0; + gInfo.thishit = 0; +#endif + /* initialize a table to store computed nodes */ + if (hardlimit) { + subsetNodeTable = st_init_table(st_ptrcmp, st_ptrhash); + } else { + subsetNodeTable = NIL(st_table); + } + subset = BuildSubsetBdd(dd, &gInfo, pathTable, f, info, subsetNodeTable); + if (subset != NULL) { + cuddRef(subset); + } + /* record the number of times a computed result for a node is hit */ + +#ifdef DD_DEBUG + (void) fprintf(dd->out, "Hits = %d, New==Node = %d, NumCalls = %d\n", + gInfo.hits, gInfo.thishit, gInfo.numCalls); +#endif + + if (subsetNodeTable != NIL(st_table)) { + st_free_table(subsetNodeTable); + } + st_free_table(info->maxpathTable); + st_foreach(pathTable, stPathTableDdFree, (char *)dd); + + FREE(info); + + } else {/* if threshold larger than size of dd */ + subset = f; + cuddRef(subset); + } + FREE(excess); + st_free_table(pathTable); + FREE(pathLengthArray); + for (i = 0; i <= gInfo.nodeDistPage; i++) FREE(gInfo.nodeDistPages[i]); + FREE(gInfo.nodeDistPages); + +#ifdef DD_DEBUG + /* check containment of subset in f */ + if (subset != NULL) { + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong partition\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + } +#endif + + if (subset != NULL) { + cuddDeref(subset); + return(subset); + } else { + return(NULL); + } + +} /* end of cuddSubsetShortPaths */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store the distances + related to each node.] + + Description [Resize the number of pages allocated to store the distances + related to each node. The procedure moves the counter to the + next page when the end of the page is reached and allocates new + pages when necessary. ] + + SideEffects [Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. ] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeNodeDistPages( + DdManager *dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */) +{ + int i; + NodeDist_t **newNodeDistPages; + + /* move to next page */ + gInfo->nodeDistPage++; + + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. Page numbers are incremented by + * INITIAL_PAGES + */ + if (gInfo->nodeDistPage == gInfo->maxNodeDistPages) { + newNodeDistPages = ALLOC(NodeDist_t *,gInfo->maxNodeDistPages + INITIAL_PAGES); + if (newNodeDistPages == NULL) { + for (i = 0; i < gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + dd->errorCode = CUDD_MEMORY_OUT; + return; + } else { + for (i = 0; i < gInfo->maxNodeDistPages; i++) { + newNodeDistPages[i] = gInfo->nodeDistPages[i]; + } + /* Increase total page count */ + gInfo->maxNodeDistPages += INITIAL_PAGES; + FREE(gInfo->nodeDistPages); + gInfo->nodeDistPages = newNodeDistPages; + } + } + /* Allocate a new page */ + gInfo->currentNodeDistPage = gInfo->nodeDistPages[gInfo->nodeDistPage] = + ALLOC(NodeDist_t, gInfo->nodeDistPageSize); + if (gInfo->currentNodeDistPage == NULL) { + for (i = 0; i < gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + dd->errorCode = CUDD_MEMORY_OUT; + return; + } + /* reset page index */ + gInfo->nodeDistPageIndex = 0; + return; + +} /* end of ResizeNodeDistPages */ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd .] + + Description [Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd. The procedure moves the counter to the + next page when the end of the page is reached and allocates new + pages when necessary.] + + SideEffects [Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. ] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeQueuePages( + DdManager *dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */) +{ + int i; + DdNode ***newQueuePages; + + gInfo->queuePage++; + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. Page numbers are incremented by + * INITIAL_PAGES + */ + if (gInfo->queuePage == gInfo->maxQueuePages) { + newQueuePages = ALLOC(DdNode **,gInfo->maxQueuePages + INITIAL_PAGES); + if (newQueuePages == NULL) { + for (i = 0; i < gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + dd->errorCode = CUDD_MEMORY_OUT; + return; + } else { + for (i = 0; i < gInfo->maxQueuePages; i++) { + newQueuePages[i] = gInfo->queuePages[i]; + } + /* Increase total page count */ + gInfo->maxQueuePages += INITIAL_PAGES; + FREE(gInfo->queuePages); + gInfo->queuePages = newQueuePages; + } + } + /* Allocate a new page */ + gInfo->currentQueuePage = gInfo->queuePages[gInfo->queuePage] = + ALLOC(DdNode *,gInfo->queuePageSize); + if (gInfo->currentQueuePage == NULL) { + for (i = 0; i < gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + dd->errorCode = CUDD_MEMORY_OUT; + return; + } + /* reset page index */ + gInfo->queuePageIndex = 0; + return; + +} /* end of ResizeQueuePages */ + + +/**Function******************************************************************** + + Synopsis [ Labels each node with its shortest distance from the root] + + Description [ Labels each node with its shortest distance from the root. + This is done in a BFS search of the BDD. The nodes are processed + in a queue implemented as pages(array) to reduce memory fragmentation. + An entry is created for each node visited. The distance from the root + to the node with the corresponding parity is updated. The procedure + is called recursively each recusion level handling nodes at a given + level from the root.] + + + SideEffects [Creates entries in the pathTable] + + SeeAlso [CreatePathTable CreateBotDist] + +******************************************************************************/ +static void +CreateTopDist( + DdManager *dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */, + st_table * pathTable /* hast table to store path lengths */, + int parentPage /* the pointer to the page on which the first parent in the queue is to be found. */, + int parentQueueIndex /* pointer to the first parent on the page */, + int topLen /* current distance from the root */, + DdNode ** childPage /* pointer to the page on which the first child is to be added. */, + int childQueueIndex /* pointer to the first child */, + int numParents /* number of parents to process in this recursive call */, + FILE *fp /* where to write messages */) +{ + NodeDist_t *nodeStat; + DdNode *N, *Nv, *Nnv, *node, *child, *regChild; + int i; + int processingDone, childrenCount; + +#ifdef DD_DEBUG + gInfo->numCalls++; + + /* assume this procedure comes in with only the root node*/ + /* set queue index to the next available entry for addition */ + /* set queue page to page of addition */ + if ((gInfo->queuePages[parentPage] == childPage) && (parentQueueIndex == + childQueueIndex)) { + fprintf(fp, "Should not happen that they are equal\n"); + } + assert(gInfo->queuePageIndex == childQueueIndex); + assert(gInfo->currentQueuePage == childPage); +#endif + /* number children added to queue is initialized , needed for + * numParents in the next call + */ + childrenCount = 0; + /* process all the nodes in this level */ + while (numParents) { + numParents--; + if (parentQueueIndex == gInfo->queuePageSize) { + parentPage++; + parentQueueIndex = 0; + } + /* a parent to process */ + node = *(gInfo->queuePages[parentPage] + parentQueueIndex); + parentQueueIndex++; + /* get its children */ + N = Cudd_Regular(node); + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + processingDone = 2; + while (processingDone) { + /* processing the THEN and the ELSE children, the THEN + * child first + */ + if (processingDone == 2) { + child = Nv; + } else { + child = Nnv; + } + + regChild = Cudd_Regular(child); + /* dont process if the child is a constant */ + if (!Cudd_IsConstant(child)) { + /* check is already visited, if not add a new entry in + * the path Table + */ + if (!st_lookup(pathTable, regChild, &nodeStat)) { + /* if not in table, has never been visited */ + /* create entry for table */ + if (gInfo->nodeDistPageIndex == gInfo->nodeDistPageSize) + ResizeNodeDistPages(dd, gInfo); + if (dd->errorCode == CUDD_MEMORY_OUT) { + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + st_free_table(pathTable); + return; + } + /* New entry for child in path Table is created here */ + nodeStat = gInfo->currentNodeDistPage + gInfo->nodeDistPageIndex; + gInfo->nodeDistPageIndex++; + + /* Initialize fields of the node data */ + nodeStat->oddTopDist = MAXSHORTINT; + nodeStat->evenTopDist = MAXSHORTINT; + nodeStat->evenBotDist = MAXSHORTINT; + nodeStat->oddBotDist = MAXSHORTINT; + nodeStat->regResult = NULL; + nodeStat->compResult = NULL; + /* update the table entry element, the distance keeps + * track of the parity of the path from the root + */ + if (Cudd_IsComplement(child)) { + nodeStat->oddTopDist = (DdHalfWord) topLen + 1; + } else { + nodeStat->evenTopDist = (DdHalfWord) topLen + 1; + } + + /* insert entry element for child in the table */ + if (st_insert(pathTable, regChild, + nodeStat) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i <= gInfo->nodeDistPage; i++) + FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + st_free_table(pathTable); + return; + } + + /* Create list element for this child to process its children. + * If this node has been processed already, then it appears + * in the path table and hence is never added to the list + * again. + */ + + if (gInfo->queuePageIndex == gInfo->queuePageSize) ResizeQueuePages(dd, gInfo); + if (dd->errorCode == CUDD_MEMORY_OUT) { + for (i = 0; i <= gInfo->nodeDistPage; i++) + FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + st_free_table(pathTable); + return; + } + *(gInfo->currentQueuePage + gInfo->queuePageIndex) = child; + gInfo->queuePageIndex++; + + childrenCount++; + } else { + /* if not been met in a path with this parity before */ + /* put in list */ + if (((Cudd_IsComplement(child)) && (nodeStat->oddTopDist == + MAXSHORTINT)) || ((!Cudd_IsComplement(child)) && + (nodeStat->evenTopDist == MAXSHORTINT))) { + + if (gInfo->queuePageIndex == gInfo->queuePageSize) ResizeQueuePages(dd, gInfo); + if (dd->errorCode == CUDD_MEMORY_OUT) { + for (i = 0; i <= gInfo->nodeDistPage; i++) + FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + st_free_table(pathTable); + return; + + } + *(gInfo->currentQueuePage + gInfo->queuePageIndex) = child; + gInfo->queuePageIndex++; + + /* update the distance with the appropriate parity */ + if (Cudd_IsComplement(child)) { + nodeStat->oddTopDist = (DdHalfWord) topLen + 1; + } else { + nodeStat->evenTopDist = (DdHalfWord) topLen + 1; + } + childrenCount++; + } + + } /* end of else (not found in st_table) */ + } /*end of if Not constant child */ + processingDone--; + } /*end of while processing Nv, Nnv */ + } /*end of while numParents */ + +#ifdef DD_DEBUG + assert(gInfo->queuePages[parentPage] == childPage); + assert(parentQueueIndex == childQueueIndex); +#endif + + if (childrenCount != 0) { + topLen++; + childPage = gInfo->currentQueuePage; + childQueueIndex = gInfo->queuePageIndex; + CreateTopDist(dd, gInfo, pathTable, parentPage, parentQueueIndex, topLen, + childPage, childQueueIndex, childrenCount, fp); + } + + return; + +} /* end of CreateTopDist */ + + +/**Function******************************************************************** + + Synopsis [ Labels each node with the shortest distance from the constant.] + + Description [Labels each node with the shortest distance from the constant. + This is done in a DFS search of the BDD. Each node has an odd + and even parity distance from the sink (since there exists paths to both + zero and one) which is less than MAXSHORTINT. At each node these distances + are updated using the minimum distance of its children from the constant. + SInce now both the length from the root and child is known, the minimum path + length(length of the shortest path between the root and the constant that + this node lies on) of this node can be calculated and used to update the + pathLengthArray] + + SideEffects [Updates Path Table and path length array] + + SeeAlso [CreatePathTable CreateTopDist AssessPathLength] + +******************************************************************************/ +static int +CreateBotDist( + DdNode * node /* current node */, + st_table * pathTable /* path table with path lengths */, + unsigned int * pathLengthArray /* array that stores number of nodes belonging to a particular path length. */, + FILE *fp /* where to write messages */) +{ + DdNode *N, *Nv, *Nnv; + DdNode *realChild; + DdNode *child, *regChild; + NodeDist_t *nodeStat, *nodeStatChild; + unsigned int oddLen, evenLen, pathLength; + DdHalfWord botDist; + int processingDone; + + if (Cudd_IsConstant(node)) + return(1); + N = Cudd_Regular(node); + /* each node has one table entry */ + /* update as you go down the min dist of each node from + the root in each (odd and even) parity */ + if (!st_lookup(pathTable, N, &nodeStat)) { + fprintf(fp, "Something wrong, the entry doesn't exist\n"); + return(0); + } + + /* compute length of odd parity distances */ + if ((nodeStat->oddTopDist != MAXSHORTINT) && + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + else + oddLen = MAXSHORTINT; + + /* compute length of even parity distances */ + if (!((nodeStat->evenTopDist == MAXSHORTINT) || + (nodeStat->evenBotDist == MAXSHORTINT))) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + else + evenLen = MAXSHORTINT; + + /* assign pathlength to minimum of the two */ + pathLength = (oddLen <= evenLen) ? oddLen : evenLen; + + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + /* process each child */ + processingDone = 0; + while (processingDone != 2) { + if (!processingDone) { + child = Nv; + } else { + child = Nnv; + } + + realChild = Cudd_NotCond(child, Cudd_IsComplement(node)); + regChild = Cudd_Regular(child); + if (Cudd_IsConstant(realChild)) { + /* Found a minterm; count parity and shortest distance + ** from the constant. + */ + if (Cudd_IsComplement(child)) + nodeStat->oddBotDist = 1; + else + nodeStat->evenBotDist = 1; + } else { + /* If node not in table, recur. */ + if (!st_lookup(pathTable, regChild, &nodeStatChild)) { + fprintf(fp, "Something wrong, node in table should have been created in top dist proc.\n"); + return(0); + } + + if (nodeStatChild->oddBotDist == MAXSHORTINT) { + if (nodeStatChild->evenBotDist == MAXSHORTINT) { + if (!CreateBotDist(realChild, pathTable, pathLengthArray, fp)) + return(0); + } else { + fprintf(fp, "Something wrong, both bot nodeStats should be there\n"); + return(0); + } + } + + /* Update shortest distance from the constant depending on + ** parity. */ + + if (Cudd_IsComplement(child)) { + /* If parity on the edge then add 1 to even distance + ** of child to get odd parity distance and add 1 to + ** odd distance of child to get even parity + ** distance. Change distance of current node only if + ** the calculated distance is less than existing + ** distance. */ + if (nodeStatChild->oddBotDist != MAXSHORTINT) + botDist = nodeStatChild->oddBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->evenBotDist > botDist ) + nodeStat->evenBotDist = botDist; + + if (nodeStatChild->evenBotDist != MAXSHORTINT) + botDist = nodeStatChild->evenBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->oddBotDist > botDist) + nodeStat->oddBotDist = botDist; + + } else { + /* If parity on the edge then add 1 to even distance + ** of child to get even parity distance and add 1 to + ** odd distance of child to get odd parity distance. + ** Change distance of current node only if the + ** calculated distance is lesser than existing + ** distance. */ + if (nodeStatChild->evenBotDist != MAXSHORTINT) + botDist = nodeStatChild->evenBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->evenBotDist > botDist) + nodeStat->evenBotDist = botDist; + + if (nodeStatChild->oddBotDist != MAXSHORTINT) + botDist = nodeStatChild->oddBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->oddBotDist > botDist) + nodeStat->oddBotDist = botDist; + } + } /* end of else (if not constant child ) */ + processingDone++; + } /* end of while processing Nv, Nnv */ + + /* Compute shortest path length on the fly. */ + if ((nodeStat->oddTopDist != MAXSHORTINT) && + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + else + oddLen = MAXSHORTINT; + + if ((nodeStat->evenTopDist != MAXSHORTINT) && + (nodeStat->evenBotDist != MAXSHORTINT)) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + else + evenLen = MAXSHORTINT; + + /* Update path length array that has number of nodes of a particular + ** path length. */ + if (oddLen < pathLength ) { + if (pathLength != MAXSHORTINT) + pathLengthArray[pathLength]--; + if (oddLen != MAXSHORTINT) + pathLengthArray[oddLen]++; + pathLength = oddLen; + } + if (evenLen < pathLength ) { + if (pathLength != MAXSHORTINT) + pathLengthArray[pathLength]--; + if (evenLen != MAXSHORTINT) + pathLengthArray[evenLen]++; + } + + return(1); + +} /*end of CreateBotDist */ + + +/**Function******************************************************************** + + Synopsis [ The outer procedure to label each node with its shortest + distance from the root and constant] + + Description [ The outer procedure to label each node with its shortest + distance from the root and constant. Calls CreateTopDist and CreateBotDist. + The basis for computing the distance between root and constant is that + the distance may be the sum of even distances from the node to the root + and constant or the sum of odd distances from the node to the root and + constant. Both CreateTopDist and CreateBotDist create the odd and + even parity distances from the root and constant respectively.] + + SideEffects [None] + + SeeAlso [CreateTopDist CreateBotDist] + +******************************************************************************/ +static st_table * +CreatePathTable( + DdManager *dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */, + DdNode * node /* root of function */, + unsigned int * pathLengthArray /* array of path lengths to store nodes labeled with the various path lengths */, + FILE *fp /* where to write messages */) +{ + + st_table *pathTable; + NodeDist_t *nodeStat; + DdHalfWord topLen; + DdNode *N; + int i, numParents; + int insertValue; + DdNode **childPage; + int parentPage; + int childQueueIndex, parentQueueIndex; + + /* Creating path Table for storing data about nodes */ + pathTable = st_init_table(st_ptrcmp,st_ptrhash); + + /* initializing pages for info about each node */ + gInfo->maxNodeDistPages = INITIAL_PAGES; + gInfo->nodeDistPages = ALLOC(NodeDist_t *, gInfo->maxNodeDistPages); + if (gInfo->nodeDistPages == NULL) { + goto OUT_OF_MEM; + } + gInfo->nodeDistPage = 0; + gInfo->currentNodeDistPage = gInfo->nodeDistPages[gInfo->nodeDistPage] = + ALLOC(NodeDist_t, gInfo->nodeDistPageSize); + if (gInfo->currentNodeDistPage == NULL) { + for (i = 0; i <= gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + goto OUT_OF_MEM; + } + gInfo->nodeDistPageIndex = 0; + + /* Initializing pages for the BFS search queue, implemented as an array. */ + gInfo->maxQueuePages = INITIAL_PAGES; + gInfo->queuePages = ALLOC(DdNode **, gInfo->maxQueuePages); + if (gInfo->queuePages == NULL) { + goto OUT_OF_MEM; + } + gInfo->queuePage = 0; + gInfo->currentQueuePage = gInfo->queuePages[gInfo->queuePage] = + ALLOC(DdNode *, gInfo->queuePageSize); + if (gInfo->currentQueuePage == NULL) { + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + goto OUT_OF_MEM; + } + gInfo->queuePageIndex = 0; + + /* Enter the root node into the queue to start with. */ + parentPage = gInfo->queuePage; + parentQueueIndex = gInfo->queuePageIndex; + topLen = 0; + *(gInfo->currentQueuePage + gInfo->queuePageIndex) = node; + gInfo->queuePageIndex++; + childPage = gInfo->currentQueuePage; + childQueueIndex = gInfo->queuePageIndex; + + N = Cudd_Regular(node); + + if (gInfo->nodeDistPageIndex == gInfo->nodeDistPageSize) ResizeNodeDistPages(dd, gInfo); + if (dd->errorCode == CUDD_MEMORY_OUT) { + for (i = 0; i <= gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + st_free_table(pathTable); + goto OUT_OF_MEM; + } + + nodeStat = gInfo->currentNodeDistPage + gInfo->nodeDistPageIndex; + gInfo->nodeDistPageIndex++; + + nodeStat->oddTopDist = MAXSHORTINT; + nodeStat->evenTopDist = MAXSHORTINT; + nodeStat->evenBotDist = MAXSHORTINT; + nodeStat->oddBotDist = MAXSHORTINT; + nodeStat->regResult = NULL; + nodeStat->compResult = NULL; + + insertValue = st_insert(pathTable, N, nodeStat); + if (insertValue == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i <= gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + st_free_table(pathTable); + goto OUT_OF_MEM; + } else if (insertValue == 1) { + fprintf(fp, "Something wrong, the entry exists but didnt show up in st_lookup\n"); + return(NULL); + } + + if (Cudd_IsComplement(node)) { + nodeStat->oddTopDist = 0; + } else { + nodeStat->evenTopDist = 0; + } + numParents = 1; + /* call the function that counts the distance of each node from the + * root + */ +#ifdef DD_DEBUG + gInfo->numCalls = 0; +#endif + CreateTopDist(dd, gInfo, pathTable, parentPage, parentQueueIndex, (int) topLen, + childPage, childQueueIndex, numParents, fp); + if (dd->errorCode == CUDD_MEMORY_OUT) { + fprintf(fp, "Out of Memory and cant count path lengths\n"); + goto OUT_OF_MEM; + } + +#ifdef DD_DEBUG + gInfo->numCalls = 0; +#endif + /* call the function that counts the distance of each node from the + * constant + */ + if (!CreateBotDist(node, pathTable, pathLengthArray, fp)) return(NULL); + + /* free BFS queue pages as no longer required */ + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + return(pathTable); + +OUT_OF_MEM: + (void) fprintf(fp, "Out of Memory, cannot allocate pages\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + +} /*end of CreatePathTable */ + + +/**Function******************************************************************** + + Synopsis [Chooses the maximum allowable path length of nodes under the + threshold.] + + Description [Chooses the maximum allowable path length under each node. + The corner cases are when the threshold is larger than the number + of nodes in the BDD iself, in which case 'numVars + 1' is returned. + If all nodes of a particular path length are needed, then the + maxpath returned is the next one with excess nodes = 0;] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static unsigned int +AssessPathLength( + unsigned int * pathLengthArray /* array determining number of nodes belonging to the different path lengths */, + int threshold /* threshold to determine maximum allowable nodes in the subset */, + int numVars /* maximum number of variables */, + unsigned int * excess /* number of nodes labeled maxpath required in the subset */, + FILE *fp /* where to write messages */) +{ + unsigned int i, maxpath; + int temp; + + temp = threshold; + i = 0; + maxpath = 0; + /* quit loop if i reaches max number of variables or if temp reaches + * below zero + */ + while ((i < (unsigned) numVars+1) && (temp > 0)) { + if (pathLengthArray[i] > 0) { + maxpath = i; + temp = temp - pathLengthArray[i]; + } + i++; + } + /* if all nodes of max path are needed */ + if (temp >= 0) { + maxpath++; /* now maxpath becomes the next maxppath or max number + of variables */ + *excess = 0; + } else { /* normal case when subset required is less than size of + original BDD */ + *excess = temp + pathLengthArray[maxpath]; + } + + if (maxpath == 0) { + fprintf(fp, "Path Length array seems to be all zeroes, check\n"); + } + return(maxpath); + +} /* end of AssessPathLength */ + + +/**Function******************************************************************** + + Synopsis [Builds the BDD with nodes labeled with path length less than or equal to maxpath] + + Description [Builds the BDD with nodes labeled with path length + under maxpath and as many nodes labeled maxpath as determined by the + threshold. The procedure uses the path table to determine which nodes + in the original bdd need to be retained. This procedure picks a + shortest path (tie break decided by taking the child with the shortest + distance to the constant) and recurs down the path till it reaches the + constant. the procedure then starts building the subset upward from + the constant. All nodes labeled by path lengths less than the given + maxpath are used to build the subset. However, in the case of nodes + that have label equal to maxpath, as many are chosen as required by + the threshold. This number is stored in the info structure in the + field thresholdReached. This field is decremented whenever a node + labeled maxpath is encountered and the nodes labeled maxpath are + aggregated in a maxpath table. As soon as the thresholdReached count + goes to 0, the shortest path from this node to the constant is found. + The extraction of nodes with the above labeling is based on the fact + that each node, labeled with a path length, P, has at least one child + labeled P or less. So extracting all nodes labeled a given path length + P ensures complete paths between the root and the constant. Extraction + of a partial number of nodes with a given path length may result in + incomplete paths and hence the additional number of nodes are grabbed + to complete the path. Since the Bdd is built bottom-up, other nodes + labeled maxpath do lie on complete paths. The procedure may cause the + subset to have a larger or smaller number of nodes than the specified + threshold. The increase in the number of nodes is caused by the + building of a subset and the reduction by recombination. However in + most cases, the recombination overshadows the increase and the + procedure returns a result with lower number of nodes than specified. + The subsetNodeTable is NIL when there is no hard limit on the number + of nodes. Further efforts towards keeping the subset closer to the + threshold number were abandoned in favour of keeping the procedure + simple and fast.] + + SideEffects [SubsetNodeTable is changed if it is not NIL.] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +BuildSubsetBdd( + DdManager * dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */, + st_table * pathTable /* path table with path lengths and computed results */, + DdNode * node /* current node */, + struct AssortedInfo * info /* assorted information structure */, + st_table * subsetNodeTable /* table storing computed results */) +{ + DdNode *N, *Nv, *Nnv; + DdNode *ThenBranch, *ElseBranch, *childBranch; + DdNode *child, *regChild, *regNnv, *regNv; + NodeDist_t *nodeStatNv, *nodeStat, *nodeStatNnv; + DdNode *neW, *topv, *regNew; + char *entry; + unsigned int topid; + unsigned int childPathLength, oddLen, evenLen, NnvPathLength, NvPathLength; + unsigned int NvBotDist, NnvBotDist; + int tiebreakChild; + int processingDone, thenDone, elseDone; + + DdNode *zero = Cudd_Not(DD_ONE(dd)); +#ifdef DD_DEBUG + gInfo->numCalls++; +#endif + if (Cudd_IsConstant(node)) + return(node); + + N = Cudd_Regular(node); + /* Find node in table. */ + if (!st_lookup(pathTable, N, &nodeStat)) { + (void) fprintf(dd->err, "Something wrong, node must be in table \n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + /* If the node in the table has been visited, then return the corresponding + ** Dd. Since a node can become a subset of itself, its + ** complement (that is te same node reached by a different parity) will + ** become a superset of the original node and result in some minterms + ** that were not in the original set. Hence two different results are + ** maintained, corresponding to the odd and even parities. + */ + + /* If this node is reached with an odd parity, get odd parity results. */ + if (Cudd_IsComplement(node)) { + if (nodeStat->compResult != NULL) { +#ifdef DD_DEBUG + gInfo->hits++; +#endif + return(nodeStat->compResult); + } + } else { + /* if this node is reached with an even parity, get even parity + * results + */ + if (nodeStat->regResult != NULL) { +#ifdef DD_DEBUG + gInfo->hits++; +#endif + return(nodeStat->regResult); + } + } + + + /* get children */ + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* no child processed */ + processingDone = 0; + /* then child not processed */ + thenDone = 0; + ThenBranch = NULL; + /* else child not processed */ + elseDone = 0; + ElseBranch = NULL; + /* if then child constant, branch is the child */ + if (Cudd_IsConstant(Nv)) { + /*shortest path found */ + if ((Nv == DD_ONE(dd)) && (info->findShortestPath)) { + info->findShortestPath = 0; + } + + ThenBranch = Nv; + cuddRef(ThenBranch); + if (ThenBranch == NULL) { + return(NULL); + } + + thenDone++; + processingDone++; + NvBotDist = MAXSHORTINT; + } else { + /* Derive regular child for table lookup. */ + regNv = Cudd_Regular(Nv); + /* Get node data for shortest path length. */ + if (!st_lookup(pathTable, regNv, &nodeStatNv) ) { + (void) fprintf(dd->err, "Something wrong, node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + /* Derive shortest path length for child. */ + if ((nodeStatNv->oddTopDist != MAXSHORTINT) && + (nodeStatNv->oddBotDist != MAXSHORTINT)) { + oddLen = (nodeStatNv->oddTopDist + nodeStatNv->oddBotDist); + } else { + oddLen = MAXSHORTINT; + } + + if ((nodeStatNv->evenTopDist != MAXSHORTINT) && + (nodeStatNv->evenBotDist != MAXSHORTINT)) { + evenLen = (nodeStatNv->evenTopDist +nodeStatNv->evenBotDist); + } else { + evenLen = MAXSHORTINT; + } + + NvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; + NvBotDist = (oddLen <= evenLen) ? nodeStatNv->oddBotDist: + nodeStatNv->evenBotDist; + } + /* if else child constant, branch is the child */ + if (Cudd_IsConstant(Nnv)) { + /*shortest path found */ + if ((Nnv == DD_ONE(dd)) && (info->findShortestPath)) { + info->findShortestPath = 0; + } + + ElseBranch = Nnv; + cuddRef(ElseBranch); + if (ElseBranch == NULL) { + return(NULL); + } + + elseDone++; + processingDone++; + NnvBotDist = MAXSHORTINT; + } else { + /* Derive regular child for table lookup. */ + regNnv = Cudd_Regular(Nnv); + /* Get node data for shortest path length. */ + if (!st_lookup(pathTable, regNnv, &nodeStatNnv) ) { + (void) fprintf(dd->err, "Something wrong, node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + /* Derive shortest path length for child. */ + if ((nodeStatNnv->oddTopDist != MAXSHORTINT) && + (nodeStatNnv->oddBotDist != MAXSHORTINT)) { + oddLen = (nodeStatNnv->oddTopDist + nodeStatNnv->oddBotDist); + } else { + oddLen = MAXSHORTINT; + } + + if ((nodeStatNnv->evenTopDist != MAXSHORTINT) && + (nodeStatNnv->evenBotDist != MAXSHORTINT)) { + evenLen = (nodeStatNnv->evenTopDist +nodeStatNnv->evenBotDist); + } else { + evenLen = MAXSHORTINT; + } + + NnvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; + NnvBotDist = (oddLen <= evenLen) ? nodeStatNnv->oddBotDist : + nodeStatNnv->evenBotDist; + } + + tiebreakChild = (NvBotDist <= NnvBotDist) ? 1 : 0; + /* while both children not processed */ + while (processingDone != 2) { + if (!processingDone) { + /* if no child processed */ + /* pick the child with shortest path length and record which one + * picked + */ + if ((NvPathLength < NnvPathLength) || + ((NvPathLength == NnvPathLength) && (tiebreakChild == 1))) { + child = Nv; + regChild = regNv; + thenDone = 1; + childPathLength = NvPathLength; + } else { + child = Nnv; + regChild = regNnv; + elseDone = 1; + childPathLength = NnvPathLength; + } /* then path length less than else path length */ + } else { + /* if one child processed, process the other */ + if (thenDone) { + child = Nnv; + regChild = regNnv; + elseDone = 1; + childPathLength = NnvPathLength; + } else { + child = Nv; + regChild = regNv; + thenDone = 1; + childPathLength = NvPathLength; + } /* end of else pick the Then child if ELSE child processed */ + } /* end of else one child has been processed */ + + /* ignore (replace with constant 0) all nodes which lie on paths larger + * than the maximum length of the path required + */ + if (childPathLength > info->maxpath) { + /* record nodes visited */ + childBranch = zero; + } else { + if (childPathLength < info->maxpath) { + if (info->findShortestPath) { + info->findShortestPath = 0; + } + childBranch = BuildSubsetBdd(dd, gInfo, pathTable, child, info, + subsetNodeTable); + + } else { /* Case: path length of node = maxpath */ + /* If the node labeled with maxpath is found in the + ** maxpathTable, use it to build the subset BDD. */ + if (st_lookup(info->maxpathTable, regChild, &entry)) { + /* When a node that is already been chosen is hit, + ** the quest for a complete path is over. */ + if (info->findShortestPath) { + info->findShortestPath = 0; + } + childBranch = BuildSubsetBdd(dd, gInfo, pathTable, child, info, + subsetNodeTable); + } else { + /* If node is not found in the maxpathTable and + ** the threshold has been reached, then if the + ** path needs to be completed, continue. Else + ** replace the node with a zero. */ + if (info->thresholdReached <= 0) { + if (info->findShortestPath) { + if (st_insert(info->maxpathTable, regChild, + NULL) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + (void) fprintf(dd->err, "OUT of memory\n"); + info->thresholdReached = 0; + childBranch = zero; + } else { + info->thresholdReached--; + childBranch = BuildSubsetBdd(dd, gInfo, pathTable, + child, info,subsetNodeTable); + } + } else { /* not find shortest path, we dont need this + node */ + childBranch = zero; + } + } else { /* Threshold hasn't been reached, + ** need the node. */ + if (st_insert(info->maxpathTable, regChild, + NULL) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + (void) fprintf(dd->err, "OUT of memory\n"); + info->thresholdReached = 0; + childBranch = zero; + } else { + info->thresholdReached--; + if (info->thresholdReached <= 0) { + info->findShortestPath = 1; + } + childBranch = BuildSubsetBdd(dd, gInfo, pathTable, + child, info, subsetNodeTable); + + } /* end of st_insert successful */ + } /* end of threshold hasnt been reached yet */ + } /* end of else node not found in maxpath table */ + } /* end of if (path length of node = maxpath) */ + } /* end if !(childPathLength > maxpath) */ + if (childBranch == NULL) { + /* deref other stuff incase reordering has taken place */ + if (ThenBranch != NULL) { + Cudd_RecursiveDeref(dd, ThenBranch); + ThenBranch = NULL; + } + if (ElseBranch != NULL) { + Cudd_RecursiveDeref(dd, ElseBranch); + ElseBranch = NULL; + } + return(NULL); + } + + cuddRef(childBranch); + + if (child == Nv) { + ThenBranch = childBranch; + } else { + ElseBranch = childBranch; + } + processingDone++; + + } /*end of while processing Nv, Nnv */ + + info->findShortestPath = 0; + topid = Cudd_NodeReadIndex(N); + topv = Cudd_ReadVars(dd, topid); + cuddRef(topv); + neW = cuddBddIteRecur(dd, topv, ThenBranch, ElseBranch); + if (neW != NULL) { + cuddRef(neW); + } + Cudd_RecursiveDeref(dd, topv); + Cudd_RecursiveDeref(dd, ThenBranch); + Cudd_RecursiveDeref(dd, ElseBranch); + + + /* Hard Limit of threshold has been imposed */ + if (subsetNodeTable != NIL(st_table)) { + /* check if a new node is created */ + regNew = Cudd_Regular(neW); + /* subset node table keeps all new nodes that have been created to keep + * a running count of how many nodes have been built in the subset. + */ + if (!st_lookup(subsetNodeTable, regNew, &entry)) { + if (!Cudd_IsConstant(regNew)) { + if (st_insert(subsetNodeTable, regNew, + NULL) == ST_OUT_OF_MEM) { + (void) fprintf(dd->err, "Out of memory\n"); + return (NULL); + } + if (st_count(subsetNodeTable) > info->threshold) { + info->thresholdReached = 0; + } + } + } + } + + + if (neW == NULL) { + return(NULL); + } else { + /*store computed result in regular form*/ + if (Cudd_IsComplement(node)) { + nodeStat->compResult = neW; + cuddRef(nodeStat->compResult); + /* if the new node is the same as the corresponding node in the + * original bdd then its complement need not be computed as it + * cannot be larger than the node itself + */ + if (neW == node) { +#ifdef DD_DEBUG + gInfo->thishit++; +#endif + /* if a result for the node has already been computed, then + * it can only be smaller than teh node itself. hence store + * the node result in order not to break recombination + */ + if (nodeStat->regResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->regResult); + } + nodeStat->regResult = Cudd_Not(neW); + cuddRef(nodeStat->regResult); + } + + } else { + nodeStat->regResult = neW; + cuddRef(nodeStat->regResult); + if (neW == node) { +#ifdef DD_DEBUG + gInfo->thishit++; +#endif + if (nodeStat->compResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->compResult); + } + nodeStat->compResult = Cudd_Not(neW); + cuddRef(nodeStat->compResult); + } + } + + cuddDeref(neW); + return(neW); + } /* end of else i.e. Subset != NULL */ +} /* end of BuildSubsetBdd */ + + +/**Function******************************************************************** + + Synopsis [Procedure to free te result dds stored in the NodeDist pages.] + + Description [None] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static enum st_retval +stPathTableDdFree( + char * key, + char * value, + char * arg) +{ + NodeDist_t *nodeStat; + DdManager *dd; + + nodeStat = (NodeDist_t *)value; + dd = (DdManager *)arg; + if (nodeStat->regResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->regResult); + } + if (nodeStat->compResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->compResult); + } + return(ST_CONTINUE); + +} /* end of stPathTableFree */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSymmetry.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSymmetry.c new file mode 100644 index 000000000..7761949ee --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSymmetry.c @@ -0,0 +1,1707 @@ +/**CFile*********************************************************************** + + FileName [cuddSymmetry.c] + + PackageName [cudd] + + Synopsis [Functions for symmetry-based variable reordering.] + + Description [External procedures included in this file: +
          +
        • Cudd_SymmProfile() +
        + Internal procedures included in this module: +
          +
        • cuddSymmCheck() +
        • cuddSymmSifting() +
        • cuddSymmSiftingConv() +
        + Static procedures included in this module: +
          +
        • ddSymmUniqueCompare() +
        • ddSymmSiftingAux() +
        • ddSymmSiftingConvAux() +
        • ddSymmSiftingUp() +
        • ddSymmSiftingDown() +
        • ddSymmGroupMove() +
        • ddSymmGroupMoveBackward() +
        • ddSymmSiftingBackward() +
        • ddSymmSummary() +
        ] + + Author [Shipra Panda, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define MV_OOM (Move *)1 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSymmetry.c,v 1.28 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int *entry; + +extern int ddTotalNumberSwapping; +#ifdef DD_STATS +extern int ddTotalNISwaps; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddSymmUniqueCompare (int *ptrX, int *ptrY); +static int ddSymmSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static int ddSymmSiftingConvAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddSymmSiftingUp (DdManager *table, int y, int xLow); +static Move * ddSymmSiftingDown (DdManager *table, int x, int xHigh); +static int ddSymmGroupMove (DdManager *table, int x, int y, Move **moves); +static int ddSymmGroupMoveBackward (DdManager *table, int x, int y); +static int ddSymmSiftingBackward (DdManager *table, Move *moves, int size); +static void ddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints statistics on symmetric variables.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +void +Cudd_SymmProfile( + DdManager * table, + int lower, + int upper) +{ + int i,x,gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; + + for (i = lower; i <= upper; i++) { + if (table->subtables[i].next != (unsigned) i) { + x = i; + (void) fprintf(table->out,"Group:"); + do { + (void) fprintf(table->out," %d",table->invperm[x]); + TotalSymm++; + gbot = x; + x = table->subtables[x].next; + } while (x != i); + TotalSymmGroups++; +#ifdef DD_DEBUG + assert(table->subtables[gbot].next == (unsigned) i); +#endif + i = gbot; + (void) fprintf(table->out,"\n"); + } + } + (void) fprintf(table->out,"Total Symmetric = %d\n",TotalSymm); + (void) fprintf(table->out,"Total Groups = %d\n",TotalSymmGroups); + +} /* end of Cudd_SymmProfile */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Checks for symmetry of x and y.] + + Description [Checks for symmetry of x and y. Ignores projection + functions, unless they are isolated. Returns 1 in case of symmetry; 0 + otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddSymmCheck( + DdManager * table, + int x, + int y) +{ + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10; + int comple; /* f0 is complemented */ + int xsymmy; /* x and y may be positively symmetric */ + int xsymmyp; /* x and y may be negatively symmetric */ + int arccount; /* number of arcs from layer x to layer y */ + int TotalRefCount; /* total reference count of layer y minus 1 */ + int yindex; + int i; + DdNodePtr *list; + int slots; + DdNode *sentinel = &(table->sentinel); +#ifdef DD_DEBUG + int xindex; +#endif + + /* Checks that x and y are not the projection functions. + ** For x it is sufficient to check whether there is only one + ** node; indeed, if there is one node, it is the projection function + ** and it cannot point to y. Hence, if y isn't just the projection + ** function, it has one arc coming from a layer different from x. + */ + if (table->subtables[x].keys == 1) { + return(0); + } + yindex = table->invperm[y]; + if (table->subtables[y].keys == 1) { + if (table->vars[yindex]->ref == 1) + return(0); + } + + xsymmy = xsymmyp = 1; + arccount = 0; + slots = table->subtables[x].slots; + list = table->subtables[x].nodelist; + for (i = 0; i < slots; i++) { + f = list[i]; + while (f != sentinel) { + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + f0 = Cudd_Regular(cuddE(f)); + comple = Cudd_IsComplement(cuddE(f)); + if ((int) f1->index == yindex) { + arccount++; + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + if ((int) f0->index != yindex) { + /* If f is an isolated projection function it is + ** allowed to bypass layer y. + */ + if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) + return(0); /* f bypasses layer y */ + } + f11 = f10 = f1; + } + if ((int) f0->index == yindex) { + arccount++; + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + + if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) { + xsymmy &= f01 == f10; + xsymmyp &= f11 == f00; + if ((xsymmy == 0) && (xsymmyp == 0)) + return(0); + } + + f = f->next; + } /* while */ + } /* for */ + + /* Calculate the total reference counts of y */ + TotalRefCount = -1; /* -1 for projection function */ + slots = table->subtables[y].slots; + list = table->subtables[y].nodelist; + for (i = 0; i < slots; i++) { + f = list[i]; + while (f != sentinel) { + TotalRefCount += f->ref; + f = f->next; + } + } + +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (arccount == TotalRefCount) { + xindex = table->invperm[x]; + (void) fprintf(table->out, + "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); + } +#endif + + return(arccount == TotalRefCount); + +} /* end of cuddSymmCheck */ + + +/**Function******************************************************************** + + Synopsis [Symmetric sifting algorithm.] + + Description [Symmetric sifting algorithm. + Assumes that no dead nodes are present. +
          +
        1. Order all the variables according to the number of entries in + each unique subtable. +
        2. Sift the variable up and down, remembering each time the total + size of the DD heap and grouping variables that are symmetric. +
        3. Select the best permutation. +
        4. Repeat 3 and 4 for all variables. +
        + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddSymmSiftingConv] + +******************************************************************************/ +int +cuddSymmSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; + int symvars; + int symgroups; +#ifdef DD_STATS + int previousSize; +#endif + + size = table->size; + + /* Find order in which to sift variables. */ + var = NULL; + entry = ALLOC(int,size); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingOutOfMem; + } + var = ALLOC(int,size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; + } + + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); + + /* Initialize the symmetry of each subtable to itself. */ + for (i = lower; i <= upper; i++) { + table->subtables[i].next = i; + } + + for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + x = table->perm[var[i]]; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + if (x < lower || x > upper) continue; + if (table->subtables[x].next == (unsigned) x) { + result = ddSymmSiftingAux(table,x,lower,upper); + if (!result) goto ddSymmSiftingOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } + + FREE(var); + FREE(entry); + + ddSymmSummary(table, lower, upper, &symvars, &symgroups); + +#ifdef DD_STATS + (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n", + symvars); + (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups", + symgroups); +#endif + + return(1+symvars); + +ddSymmSiftingOutOfMem: + + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddSymmSifting */ + + +/**Function******************************************************************** + + Synopsis [Symmetric sifting to convergence algorithm.] + + Description [Symmetric sifting to convergence algorithm. + Assumes that no dead nodes are present. +
          +
        1. Order all the variables according to the number of entries in + each unique subtable. +
        2. Sift the variable up and down, remembering each time the total + size of the DD heap and grouping variables that are symmetric. +
        3. Select the best permutation. +
        4. Repeat 3 and 4 for all variables. +
        5. Repeat 1-4 until no further improvement. +
        + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddSymmSifting] + +******************************************************************************/ +int +cuddSymmSiftingConv( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; + int symvars; + int symgroups; + int classes; + int initialSize; +#ifdef DD_STATS + int previousSize; +#endif + + initialSize = table->keys - table->isolated; + + size = table->size; + + /* Find order in which to sift variables. */ + var = NULL; + entry = ALLOC(int,size); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingConvOutOfMem; + } + var = ALLOC(int,size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingConvOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; + } + + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); + + /* Initialize the symmetry of each subtable to itself + ** for first pass of converging symmetric sifting. + */ + for (i = lower; i <= upper; i++) { + table->subtables[i].next = i; + } + + for (i = 0; i < ddMin(table->siftMaxVar, table->size); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + x = table->perm[var[i]]; + if (x < lower || x > upper) continue; + /* Only sift if not in symmetry group already. */ + if (table->subtables[x].next == (unsigned) x) { +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSymmSiftingAux(table,x,lower,upper); + if (!result) goto ddSymmSiftingConvOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } + + /* Sifting now until convergence. */ + while ((unsigned) initialSize > table->keys - table->isolated) { + initialSize = table->keys - table->isolated; +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + /* Here we consider only one representative for each symmetry class. */ + for (x = lower, classes = 0; x <= upper; x++, classes++) { + while ((unsigned) x < table->subtables[x].next) { + x = table->subtables[x].next; + } + /* Here x is the largest index in a group. + ** Groups consist of adjacent variables. + ** Hence, the next increment of x will move it to a new group. + */ + i = table->invperm[x]; + entry[i] = table->subtables[x].keys; + var[classes] = i; + } + + qsort((void *)var,classes,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + x = table->perm[var[i]]; + if ((unsigned) x >= table->subtables[x].next) { +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSymmSiftingConvAux(table,x,lower,upper); + if (!result ) goto ddSymmSiftingConvOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } /* for */ + } + + ddSymmSummary(table, lower, upper, &symvars, &symgroups); + +#ifdef DD_STATS + (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n", + symvars); + (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups", + symgroups); +#endif + + FREE(var); + FREE(entry); + + return(1+symvars); + +ddSymmSiftingConvOutOfMem: + + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddSymmSiftingConv */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the variables + according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmUniqueCompare( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of ddSymmUniqueCompare */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is not part of a symmetry group. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; + int i; + int topbot; /* index to either top or bottom of symmetry group */ + int initGroupSize, finalGroupSize; + + +#ifdef DD_DEBUG + /* check for previously detected symmetry */ + assert(table->subtables[x].next == (unsigned) x); +#endif + + initialSize = table->keys - table->isolated; + + moveDown = NULL; + moveUp = NULL; + + if ((x - xLow) > (xHigh - x)) { + /* Will go down first, unless x == xHigh: + ** Look for consecutive symmetries above x. + */ + for (i = x; i > xLow; i--) { + if (!cuddSymmCheck(table,i-1,i)) + break; + topbot = table->subtables[i-1].next; /* find top of i-1's group */ + table->subtables[i-1].next = i; + table->subtables[x].next = topbot; /* x is bottom of group so its */ + /* next is top of i-1's group */ + i = topbot + 1; /* add 1 for i--; new i is top of symm group */ + } + } else { + /* Will go up first unless x == xlow: + ** Look for consecutive symmetries below x. + */ + for (i = x; i < xHigh; i++) { + if (!cuddSymmCheck(table,i,i+1)) + break; + /* find bottom of i+1's symm group */ + topbot = i + 1; + while ((unsigned) topbot < table->subtables[topbot].next) { + topbot = table->subtables[topbot].next; + } + table->subtables[topbot].next = table->subtables[i].next; + table->subtables[i].next = i + 1; + i = topbot - 1; /* subtract 1 for i++; new i is bottom of group */ + } + } + + /* Now x may be in the middle of a symmetry group. + ** Find bottom of x's symm group. + */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + + if (x == xLow) { /* Sift down */ + +#ifdef DD_DEBUG + /* x must be a singleton */ + assert((unsigned) x == table->subtables[x].next); +#endif + if (x == xHigh) return(1); /* just one variable */ + + initGroupSize = 1; + + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* after this point x --> xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + if (moveDown == NULL) return(1); + + x = moveDown->y; + /* Find bottom of x's group */ + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + finalGroupSize = i - x + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; + + } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ + /* Find top of x's symm group */ + i = x; /* bottom */ + x = table->subtables[x].next; /* top */ + + if (x == xLow) return(1); /* just one big group */ + + initGroupSize = i - x + 1; + + moveUp = ddSymmSiftingUp(table,x,xLow); + /* after this point x --> xLow, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + if (moveUp == NULL) return(1); + + x = moveUp->x; + /* Find top of x's group */ + i = table->subtables[x].next; +#ifdef DD_DEBUG + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + finalGroupSize = x - i + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; /* x is top here */ + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + x = table->subtables[i].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + initGroupSize = i - x + 1; + + moveUp = ddSymmSiftingUp(table,x,xLow); + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + finalGroupSize = x - i + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; + + } else { /* moving up first: shorter */ + /* Find top of x's symmetry group */ + x = table->subtables[x].next; + + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xHigh, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x is bottom of the symmetry group and i is top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + initGroupSize = x - i + 1; + + moveDown = ddSymmSiftingDown(table,x,xHigh); + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + finalGroupSize = i - x + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +ddSymmSiftingAuxOutOfMem: + if (moveDown != MV_OOM) { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + } + if (moveUp != MV_OOM) { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + } + + return(0); + +} /* end of ddSymmSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is either an isolated variable, or it is the bottom of + a symmetry group. All symmetries may not have been found, because of + exceeded growth limit. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmSiftingConvAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; + int i; + int initGroupSize, finalGroupSize; + + + initialSize = table->keys - table->isolated; + + moveDown = NULL; + moveUp = NULL; + + if (x == xLow) { /* Sift down */ +#ifdef DD_DEBUG + /* x is bottom of symmetry group */ + assert((unsigned) x >= table->subtables[x].next); +#endif + i = table->subtables[x].next; + initGroupSize = x - i + 1; + + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + if (moveDown == NULL) return(1); + + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetric group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + finalGroupSize = i - x + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingConvAuxOutOfMem; + + } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ + /* Find top of x's symm group */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = x; /* bottom */ + x = table->subtables[x].next; /* top */ + + if (x == xLow) return(1); + + initGroupSize = i - x + 1; + + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xLow, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + if (moveUp == NULL) return(1); + + x = moveUp->x; + i = table->subtables[x].next; +#ifdef DD_DEBUG + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + finalGroupSize = x - i + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) + goto ddSymmSiftingConvAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = x; + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + initGroupSize = i - x + 1; + + moveUp = ddSymmSiftingUp(table,x,xLow); + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + finalGroupSize = x - i + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) goto ddSymmSiftingConvAuxOutOfMem; + + } else { /* moving up first: shorter */ + /* Find top of x's symmetry group */ + x = table->subtables[x].next; + + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xHigh, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x is bottom of the symmetry group and i is top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + initGroupSize = x - i + 1; + + moveDown = ddSymmSiftingDown(table,x,xHigh); + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + finalGroupSize = i - x + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingConvAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +ddSymmSiftingConvAuxOutOfMem: + if (moveDown != MV_OOM) { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + } + if (moveUp != MV_OOM) { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + } + + return(0); + +} /* end of ddSymmSiftingConvAux */ + + +/**Function******************************************************************** + + Synopsis [Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much.] + + Description [Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much. Assumes that x is the top + of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; MV_OOM if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSymmSiftingUp( + DdManager * table, + int y, + int xLow) +{ + Move *moves; + Move *move; + int x; + int size; + int i; + int gxtop,gybot; + int limitSize; + int xindex, yindex; + int zindex; + int z; + int isolated; + int L; /* lower bound on DD size */ +#ifdef DD_DEBUG + int checkL; +#endif + + + moves = NULL; + yindex = table->invperm[y]; + + /* Initialize the lower bound. + ** The part of the DD below the bottom of y' group will not change. + ** The part of the DD above y that does not interact with y will not + ** change. The rest may vanish in the best case, except for + ** the nodes at level xLow, which will not vanish, regardless. + */ + limitSize = L = table->keys - table->isolated; + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L -= table->subtables[z].keys - isolated; + } + } + + x = cuddNextLow(table,y); + while (x >= xLow && L <= limitSize) { +#ifdef DD_DEBUG + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + assert(L == checkL); +#endif + gxtop = table->subtables[x].next; + if (cuddSymmCheck(table,x,y)) { + /* Symmetry found, attach symm groups */ + table->subtables[x].next = y; + i = table->subtables[y].next; + while (table->subtables[i].next != (unsigned) y) + i = table->subtables[i].next; + table->subtables[i].next = gxtop; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y have self symmetry */ + xindex = table->invperm[x]; + size = cuddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); +#endif + if (size == 0) goto ddSymmSiftingUpOutOfMem; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSymmSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + } else { /* Group move */ + size = ddSymmGroupMove(table,x,y,&moves); + if (size == 0) goto ddSymmSiftingUpOutOfMem; + /* Update the lower bound. */ + z = moves->y; + do { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L += table->subtables[z].keys - isolated; + } + z = table->subtables[z].next; + } while (z != (int) moves->y); + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + } + y = gxtop; + x = cuddNextLow(table,y); + } + + return(moves); + +ddSymmSiftingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(MV_OOM); + +} /* end of ddSymmSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Moves x down until either it reaches the bound (xHigh) or + the size of the DD heap increases too much.] + + Description [Moves x down until either it reaches the bound (xHigh) + or the size of the DD heap increases too much. Assumes that x is the + bottom of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; MV_OOM if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSymmSiftingDown( + DdManager * table, + int x, + int xHigh) +{ + Move *moves; + Move *move; + int y; + int size; + int limitSize; + int gxtop,gybot; + int R; /* upper bound on node decrease */ + int xindex, yindex; + int isolated; + int z; + int zindex; +#ifdef DD_DEBUG + int checkR; +#endif + + moves = NULL; + /* Initialize R */ + xindex = table->invperm[x]; + gxtop = table->subtables[x].next; + limitSize = size = table->keys - table->isolated; + R = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } + + y = cuddNextHigh(table,x); + while (y <= xHigh && size - R < limitSize) { +#ifdef DD_DEBUG + gxtop = table->subtables[x].next; + checkR = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + assert(R == checkR); +#endif + gybot = table->subtables[y].next; + while (table->subtables[gybot].next != (unsigned) y) + gybot = table->subtables[gybot].next; + if (cuddSymmCheck(table,x,y)) { + /* Symmetry found, attach symm groups */ + gxtop = table->subtables[x].next; + table->subtables[x].next = y; + table->subtables[gybot].next = gxtop; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y have self symmetry */ + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); +#endif + if (size == 0) goto ddSymmSiftingDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSymmSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + } else { /* Group move */ + /* Update upper bound on node decrease: first phase. */ + gxtop = table->subtables[x].next; + z = gxtop + 1; + do { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R -= table->subtables[z].keys - isolated; + } + z++; + } while (z <= gybot); + size = ddSymmGroupMove(table,x,y,&moves); + if (size == 0) goto ddSymmSiftingDownOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + /* Update upper bound on node decrease: second phase. */ + gxtop = table->subtables[gybot].next; + for (z = gxtop + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } + } + x = gybot; + y = cuddNextHigh(table,x); + } + + return(moves); + +ddSymmSiftingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(MV_OOM); + +} /* end of ddSymmSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Swaps two groups.] + + Description [Swaps two groups. x is assumed to be the bottom variable + of the first group. y is assumed to be the top variable of the second + group. Updates the list of moves. Returns the number of keys in the + table if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmGroupMove( + DdManager * table, + int x, + int y, + Move ** moves) +{ + Move *move; + int size; + int i,j; + int xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + int swapx,swapy; + +#ifdef DD_DEBUG + assert(x < y); /* we assume that x < y */ +#endif + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtables[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtables[ybot].next) + ybot = table->subtables[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + + /* Sift the variables of the second group up through the first group. */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) return(0); + swapx = x; swapy = y; + y = x; + x = y - 1; + } + y = ytop + i; + x = y - 1; + } + + /* fix symmetries */ + y = xtop; /* ytop is now where xtop used to be */ + for (i = 0; i < ysize-1 ; i++) { + table->subtables[y].next = y + 1; + y = y + 1; + } + table->subtables[y].next = xtop; /* y is bottom of its group, join */ + /* its symmetry to top of its group */ + x = y + 1; + newxtop = x; + for (i = 0; i < xsize - 1 ; i++) { + table->subtables[x].next = x + 1; + x = x + 1; + } + table->subtables[x].next = newxtop; /* x is bottom of its group, join */ + /* its symmetry to top of its group */ + /* Store group move */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) return(0); + move->x = swapx; + move->y = swapy; + move->size = size; + move->next = *moves; + *moves = move; + + return(size); + +} /* end of ddSymmGroupMove */ + + +/**Function******************************************************************** + + Synopsis [Undoes the swap of two groups.] + + Description [Undoes the swap of two groups. x is assumed to be the + bottom variable of the first group. y is assumed to be the top + variable of the second group. Returns the number of keys in the table + if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmGroupMoveBackward( + DdManager * table, + int x, + int y) +{ + int size; + int i,j; + int xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + +#ifdef DD_DEBUG + assert(x < y); /* We assume that x < y */ +#endif + + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtables[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtables[ybot].next) + ybot = table->subtables[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + + /* Sift the variables of the second group up through the first group. */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) return(0); + y = x; + x = cuddNextLow(table,y); + } + y = ytop + i; + x = y - 1; + } + + /* Fix symmetries. */ + y = xtop; + for (i = 0; i < ysize-1 ; i++) { + table->subtables[y].next = y + 1; + y = y + 1; + } + table->subtables[y].next = xtop; /* y is bottom of its group, join */ + /* its symmetry to top of its group */ + x = y + 1; + newxtop = x; + for (i = 0; i < xsize-1 ; i++) { + table->subtables[x].next = x + 1; + x = x + 1; + } + table->subtables[x].next = newxtop; /* x is bottom of its group, join */ + /* its symmetry to top of its group */ + + return(size); + +} /* end of ddSymmGroupMoveBackward */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the DD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmSiftingBackward( + DdManager * table, + Move * moves, + int size) +{ + Move *move; + int res; + + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + if (table->subtables[move->x].next == move->x && table->subtables[move->y].next == move->y) { + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); +#ifdef DD_DEBUG + assert(table->subtables[move->x].next == move->x); + assert(table->subtables[move->y].next == move->y); +#endif + } else { /* Group move necessary */ + res = ddSymmGroupMoveBackward(table,(int)move->x,(int)move->y); + } + if (!res) return(0); + } + + return(1); + +} /* end of ddSymmSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Counts numbers of symmetric variables and symmetry + groups.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static void +ddSymmSummary( + DdManager * table, + int lower, + int upper, + int * symvars, + int * symgroups) +{ + int i,x,gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; + + for (i = lower; i <= upper; i++) { + if (table->subtables[i].next != (unsigned) i) { + TotalSymmGroups++; + x = i; + do { + TotalSymm++; + gbot = x; + x = table->subtables[x].next; + } while (x != i); +#ifdef DD_DEBUG + assert(table->subtables[gbot].next == (unsigned) i); +#endif + i = gbot; + } + } + *symvars = TotalSymm; + *symgroups = TotalSymmGroups; + + return; + +} /* end of ddSymmSummary */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddTable.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddTable.c new file mode 100644 index 000000000..b8e989375 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddTable.c @@ -0,0 +1,3213 @@ +/**CFile*********************************************************************** + + FileName [cuddTable.c] + + PackageName [cudd] + + Synopsis [Unique table management functions.] + + Description [External procedures included in this module: +
          +
        • Cudd_Prime() +
        • Cudd_Reserve() +
        + Internal procedures included in this module: +
          +
        • cuddAllocNode() +
        • cuddInitTable() +
        • cuddFreeTable() +
        • cuddGarbageCollect() +
        • cuddZddGetNode() +
        • cuddZddGetNodeIVO() +
        • cuddUniqueInter() +
        • cuddUniqueInterIVO() +
        • cuddUniqueInterZdd() +
        • cuddUniqueConst() +
        • cuddRehash() +
        • cuddShrinkSubtable() +
        • cuddInsertSubtables() +
        • cuddDestroySubtables() +
        • cuddResizeTableZdd() +
        • cuddSlowTableGrowth() +
        + Static procedures included in this module: +
          +
        • ddRehashZdd() +
        • ddResizeTable() +
        • cuddFindParent() +
        • cuddOrderedInsert() +
        • cuddOrderedThread() +
        • cuddRotateLeft() +
        • cuddRotateRight() +
        • cuddDoRebalance() +
        • cuddCheckCollisionOrdering() +
        ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST +/* Constants for red/black trees. */ +#define DD_STACK_SIZE 128 +#define DD_RED 0 +#define DD_BLACK 1 +#define DD_PAGE_SIZE 8192 +#define DD_PAGE_MASK ~(DD_PAGE_SIZE - 1) +#endif +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/* This is a hack for when CUDD_VALUE_TYPE is double */ +typedef union hack { + CUDD_VALUE_TYPE value; + unsigned int bits[2]; +} hack; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.126 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST +/* Macros for red/black trees. */ +#define DD_INSERT_COMPARE(x,y) \ + (((ptruint) (x) & DD_PAGE_MASK) - ((ptruint) (y) & DD_PAGE_MASK)) +#define DD_COLOR(p) ((p)->index) +#define DD_IS_BLACK(p) ((p)->index == DD_BLACK) +#define DD_IS_RED(p) ((p)->index == DD_RED) +#define DD_LEFT(p) cuddT(p) +#define DD_RIGHT(p) cuddE(p) +#define DD_NEXT(p) ((p)->next) +#endif +#endif + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void ddRehashZdd (DdManager *unique, int i); +static int ddResizeTable (DdManager *unique, int index, int amount); +static int cuddFindParent (DdManager *table, DdNode *node); +DD_INLINE static void ddFixLimits (DdManager *unique); +#ifdef DD_RED_BLACK_FREE_LIST +static void cuddOrderedInsert (DdNodePtr *root, DdNodePtr node); +static DdNode * cuddOrderedThread (DdNode *root, DdNode *list); +static void cuddRotateLeft (DdNodePtr *nodeP); +static void cuddRotateRight (DdNodePtr *nodeP); +static void cuddDoRebalance (DdNodePtr **stack, int stackN); +#endif +static void ddPatchTree (DdManager *dd, MtrNode *treenode); +#ifdef DD_DEBUG +static int cuddCheckCollisionOrdering (DdManager *unique, int i, int j); +#endif +static void ddReportRefMess (DdManager *unique, int i, const char *caller); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns the next prime >= p.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +unsigned int +Cudd_Prime( + unsigned int p) +{ + int i,pn; + + p--; + do { + p++; + if (p&1) { + pn = 1; + i = 3; + while ((unsigned) (i * i) <= p) { + if (p % i == 0) { + pn = 0; + break; + } + i += 2; + } + } else { + pn = 0; + } + } while (!pn); + return(p); + +} /* end of Cudd_Prime */ + + +/**Function******************************************************************** + + Synopsis [Expand manager without creating variables.] + + Description [Expand a manager by a specified number of subtables without + actually creating new variables. This function can be used to reduce the + frequency of resizing when an estimate of the number of variables is + available. One would call this function instead of passing the number + of variables to Cudd_Init if variables should not be created right away + of if the estimate on their number became available only after the manager + has been created. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Init] + +******************************************************************************/ +int +Cudd_Reserve( + DdManager *manager, + int amount) +{ + int currentSize = manager->size; + if (amount < 0) + return(0); + if (currentSize + amount < currentSize) /* overflow */ + return(0); + if (amount <= manager->maxSize - manager->size) + return(1); + return ddResizeTable(manager, -1, amount); + +} /* end of Cudd_Reserve */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Fast storage allocation for DdNodes in the table.] + + Description [Fast storage allocation for DdNodes in the table. The + first 4 bytes of a chunk contain a pointer to the next block; the + rest contains DD_MEM_CHUNK spaces for DdNodes. Returns a pointer to + a new node if successful; NULL is memory is full.] + + SideEffects [None] + + SeeAlso [cuddDynamicAllocNode] + +******************************************************************************/ +DdNode * +cuddAllocNode( + DdManager * unique) +{ + int i; + DdNodePtr *mem; + DdNode *list, *node; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (unique->nextFree == NULL) { /* free list is empty */ + /* Check for exceeded limits. */ + if ((unique->keys - unique->dead) + (unique->keysZ - unique->deadZ) > + unique->maxLive) { + unique->errorCode = CUDD_TOO_MANY_NODES; + return(NULL); + } + if (util_cpu_time() - unique->startTime > unique->timeLimit) { + unique->errorCode = CUDD_TIMEOUT_EXPIRED; + return(NULL); + } + if (unique->stash == NULL || unique->memused > unique->maxmemhard) { + (void) cuddGarbageCollect(unique,1); + mem = NULL; + } + if (unique->nextFree == NULL) { + if (unique->memused > unique->maxmemhard) { + unique->errorCode = CUDD_MAX_MEM_EXCEEDED; + return(NULL); + } + /* Try to allocate a new block. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1); + MMoutOfMemory = saveHandler; + if (mem == NULL) { + /* No more memory: Try collecting garbage. If this succeeds, + ** we end up with mem still NULL, but unique->nextFree != + ** NULL. */ + if (cuddGarbageCollect(unique,1) == 0) { + /* Last resort: Free the memory stashed away, if there + ** any. If this succeeeds, mem != NULL and + ** unique->nextFree still NULL. */ + if (unique->stash != NULL) { + FREE(unique->stash); + unique->stash = NULL; + /* Inhibit resizing of tables. */ + cuddSlowTableGrowth(unique); + /* Now try again. */ + mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1); + } + if (mem == NULL) { + /* Out of luck. Call the default handler to do + ** whatever it specifies for a failed malloc. + ** If this handler returns, then set error code, + ** print warning, and return. */ + (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); + unique->errorCode = CUDD_MEMORY_OUT; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "cuddAllocNode: out of memory"); + (void) fprintf(unique->err, "Memory in use = %lu\n", + unique->memused); +#endif + return(NULL); + } + } + } + if (mem != NULL) { /* successful allocation; slice memory */ + ptruint offset; + unique->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); + mem[0] = (DdNodePtr) unique->memoryList; + unique->memoryList = mem; + + /* Here we rely on the fact that a DdNode is as large + ** as 4 pointers. */ + offset = (ptruint) mem & (sizeof(DdNode) - 1); + mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); + assert(((ptruint) mem & (sizeof(DdNode) - 1)) == 0); + list = (DdNode *) mem; + + i = 1; + do { + list[i - 1].ref = 0; + list[i - 1].next = &list[i]; + } while (++i < DD_MEM_CHUNK); + + list[DD_MEM_CHUNK-1].ref = 0; + list[DD_MEM_CHUNK-1].next = NULL; + + unique->nextFree = &list[0]; + } + } + } + unique->allocated++; + node = unique->nextFree; + unique->nextFree = node->next; + return(node); + +} /* end of cuddAllocNode */ + + +/**Function******************************************************************** + + Synopsis [Creates and initializes the unique table.] + + Description [Creates and initializes the unique table. Returns a pointer + to the table if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Init cuddFreeTable] + +******************************************************************************/ +DdManager * +cuddInitTable( + unsigned int numVars /* Initial number of BDD variables (and subtables) */, + unsigned int numVarsZ /* Initial number of ZDD variables (and subtables) */, + unsigned int numSlots /* Initial size of the BDD subtables */, + unsigned int looseUpTo /* Limit for fast table growth */) +{ + DdManager *unique = ALLOC(DdManager,1); + int i, j; + DdNodePtr *nodelist; + DdNode *sentinel; + unsigned int slots; + int shift; + + if (unique == NULL) { + return(NULL); + } + sentinel = &(unique->sentinel); + sentinel->ref = 0; + sentinel->index = 0; + cuddT(sentinel) = NULL; + cuddE(sentinel) = NULL; + sentinel->next = NULL; + unique->epsilon = DD_EPSILON; + unique->size = numVars; + unique->sizeZ = numVarsZ; + unique->maxSize = ddMax(DD_DEFAULT_RESIZE, numVars); + unique->maxSizeZ = ddMax(DD_DEFAULT_RESIZE, numVarsZ); + + /* Adjust the requested number of slots to a power of 2. */ + slots = 8; + while (slots < numSlots) { + slots <<= 1; + } + unique->initSlots = slots; + shift = sizeof(int) * 8 - cuddComputeFloorLog2(slots); + + unique->slots = (numVars + numVarsZ + 1) * slots; + unique->keys = 0; + unique->maxLive = ~0; /* very large number */ + unique->keysZ = 0; + unique->dead = 0; + unique->deadZ = 0; + unique->gcFrac = DD_GC_FRAC_HI; + unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots); + unique->looseUpTo = looseUpTo; + unique->gcEnabled = 1; + unique->allocated = 0; + unique->reclaimed = 0; + unique->subtables = ALLOC(DdSubtable,unique->maxSize); + if (unique->subtables == NULL) { + FREE(unique); + return(NULL); + } + unique->subtableZ = ALLOC(DdSubtable,unique->maxSizeZ); + if (unique->subtableZ == NULL) { + FREE(unique->subtables); + FREE(unique); + return(NULL); + } + unique->perm = ALLOC(int,unique->maxSize); + if (unique->perm == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique); + return(NULL); + } + unique->invperm = ALLOC(int,unique->maxSize); + if (unique->invperm == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique); + return(NULL); + } + unique->permZ = ALLOC(int,unique->maxSizeZ); + if (unique->permZ == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique); + return(NULL); + } + unique->invpermZ = ALLOC(int,unique->maxSizeZ); + if (unique->invpermZ == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique); + return(NULL); + } + unique->map = NULL; + unique->stack = ALLOC(DdNodePtr,ddMax(unique->maxSize,unique->maxSizeZ)+1); + if (unique->stack == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique); + return(NULL); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + +#ifndef DD_NO_DEATH_ROW + unique->deathRowDepth = 1 << cuddComputeFloorLog2(unique->looseUpTo >> 2); + unique->deathRow = ALLOC(DdNodePtr,unique->deathRowDepth); + if (unique->deathRow == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique->stack); + FREE(unique); + return(NULL); + } + for (i = 0; i < unique->deathRowDepth; i++) { + unique->deathRow[i] = NULL; + } + unique->nextDead = 0; + unique->deadMask = unique->deathRowDepth - 1; +#endif + + for (i = 0; (unsigned) i < numVars; i++) { + unique->subtables[i].slots = slots; + unique->subtables[i].shift = shift; + unique->subtables[i].keys = 0; + unique->subtables[i].dead = 0; + unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[i].bindVar = 0; + unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[i].pairIndex = 0; + unique->subtables[i].varHandled = 0; + unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + nodelist = unique->subtables[i].nodelist = ALLOC(DdNodePtr,slots); + if (nodelist == NULL) { + for (j = 0; j < i; j++) { + FREE(unique->subtables[j].nodelist); + } + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique->stack); + FREE(unique); + return(NULL); + } + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = sentinel; + } + unique->perm[i] = i; + unique->invperm[i] = i; + } + for (i = 0; (unsigned) i < numVarsZ; i++) { + unique->subtableZ[i].slots = slots; + unique->subtableZ[i].shift = shift; + unique->subtableZ[i].keys = 0; + unique->subtableZ[i].dead = 0; + unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + nodelist = unique->subtableZ[i].nodelist = ALLOC(DdNodePtr,slots); + if (nodelist == NULL) { + for (j = 0; (unsigned) j < numVars; j++) { + FREE(unique->subtables[j].nodelist); + } + FREE(unique->subtables); + for (j = 0; j < i; j++) { + FREE(unique->subtableZ[j].nodelist); + } + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique->stack); + FREE(unique); + return(NULL); + } + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + unique->permZ[i] = i; + unique->invpermZ[i] = i; + } + unique->constants.slots = slots; + unique->constants.shift = shift; + unique->constants.keys = 0; + unique->constants.dead = 0; + unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + nodelist = unique->constants.nodelist = ALLOC(DdNodePtr,slots); + if (nodelist == NULL) { + for (j = 0; (unsigned) j < numVars; j++) { + FREE(unique->subtables[j].nodelist); + } + FREE(unique->subtables); + for (j = 0; (unsigned) j < numVarsZ; j++) { + FREE(unique->subtableZ[j].nodelist); + } + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique->stack); + FREE(unique); + return(NULL); + } + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + + unique->memoryList = NULL; + unique->nextFree = NULL; + + unique->memused = sizeof(DdManager) + (unique->maxSize + unique->maxSizeZ) + * (sizeof(DdSubtable) + 2 * sizeof(int)) + (numVars + 1) * + slots * sizeof(DdNodePtr) + + (ddMax(unique->maxSize,unique->maxSizeZ) + 1) * sizeof(DdNodePtr); +#ifndef DD_NO_DEATH_ROW + unique->memused += unique->deathRowDepth * sizeof(DdNodePtr); +#endif + + /* Initialize fields concerned with automatic dynamic reordering. */ + unique->reordered = 0; + unique->reorderings = 0; + unique->maxReorderings = ~0; + unique->siftMaxVar = DD_SIFT_MAX_VAR; + unique->siftMaxSwap = DD_SIFT_MAX_SWAPS; + unique->maxGrowth = DD_MAX_REORDER_GROWTH; + unique->maxGrowthAlt = 2.0 * DD_MAX_REORDER_GROWTH; + unique->reordCycle = 0; /* do not use alternate threshold */ + unique->autoDyn = 0; /* initially disabled */ + unique->autoDynZ = 0; /* initially disabled */ + unique->autoMethod = CUDD_REORDER_SIFT; + unique->autoMethodZ = CUDD_REORDER_SIFT; + unique->realign = 0; /* initially disabled */ + unique->realignZ = 0; /* initially disabled */ + unique->nextDyn = DD_FIRST_REORDER; + unique->countDead = ~0; + unique->tree = NULL; + unique->treeZ = NULL; + unique->groupcheck = CUDD_GROUP_CHECK7; + unique->recomb = DD_DEFAULT_RECOMB; + unique->symmviolation = 0; + unique->arcviolation = 0; + unique->populationSize = 0; + unique->numberXovers = 0; + unique->randomizeOrder = 0; + unique->linear = NULL; + unique->linearSize = 0; + + /* Initialize ZDD universe. */ + unique->univ = (DdNodePtr *)NULL; + + /* Initialize auxiliary fields. */ + unique->localCaches = NULL; + unique->preGCHook = NULL; + unique->postGCHook = NULL; + unique->preReorderingHook = NULL; + unique->postReorderingHook = NULL; + unique->out = stdout; + unique->err = stderr; + unique->errorCode = CUDD_NO_ERROR; + unique->startTime = util_cpu_time(); + unique->timeLimit = ~0UL; + + /* Initialize statistical counters. */ + unique->maxmemhard = ~ 0UL; + unique->garbageCollections = 0; + unique->GCTime = 0; + unique->reordTime = 0; +#ifdef DD_STATS + unique->nodesDropped = 0; + unique->nodesFreed = 0; +#endif + unique->peakLiveNodes = 0; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLookUps = 0; + unique->uniqueLinks = 0; +#endif +#ifdef DD_COUNT + unique->recursiveCalls = 0; + unique->swapSteps = 0; +#ifdef DD_STATS + unique->nextSample = 250000; +#endif +#endif + + return(unique); + +} /* end of cuddInitTable */ + + +/**Function******************************************************************** + + Synopsis [Frees the resources associated to a unique table.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddInitTable] + +******************************************************************************/ +void +cuddFreeTable( + DdManager * unique) +{ + DdNodePtr *next; + DdNodePtr *memlist = unique->memoryList; + int i; + + if (unique->univ != NULL) cuddZddFreeUniv(unique); + while (memlist != NULL) { + next = (DdNodePtr *) memlist[0]; /* link to next block */ + FREE(memlist); + memlist = next; + } + unique->nextFree = NULL; + unique->memoryList = NULL; + + for (i = 0; i < unique->size; i++) { + FREE(unique->subtables[i].nodelist); + } + for (i = 0; i < unique->sizeZ; i++) { + FREE(unique->subtableZ[i].nodelist); + } + FREE(unique->constants.nodelist); + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->acache); + FREE(unique->perm); + FREE(unique->permZ); + FREE(unique->invperm); + FREE(unique->invpermZ); + FREE(unique->vars); + if (unique->map != NULL) FREE(unique->map); + FREE(unique->stack); +#ifndef DD_NO_DEATH_ROW + FREE(unique->deathRow); +#endif + if (unique->tree != NULL) Mtr_FreeTree(unique->tree); + if (unique->treeZ != NULL) Mtr_FreeTree(unique->treeZ); + if (unique->linear != NULL) FREE(unique->linear); + while (unique->preGCHook != NULL) + Cudd_RemoveHook(unique,unique->preGCHook->f,CUDD_PRE_GC_HOOK); + while (unique->postGCHook != NULL) + Cudd_RemoveHook(unique,unique->postGCHook->f,CUDD_POST_GC_HOOK); + while (unique->preReorderingHook != NULL) + Cudd_RemoveHook(unique,unique->preReorderingHook->f, + CUDD_PRE_REORDERING_HOOK); + while (unique->postReorderingHook != NULL) + Cudd_RemoveHook(unique,unique->postReorderingHook->f, + CUDD_POST_REORDERING_HOOK); + FREE(unique); + +} /* end of cuddFreeTable */ + + +/**Function******************************************************************** + + Synopsis [Performs garbage collection on the unique tables.] + + Description [Performs garbage collection on the BDD and ZDD unique tables. + If clearCache is 0, the cache is not cleared. This should only be + specified if the cache has been cleared right before calling + cuddGarbageCollect. (As in the case of dynamic reordering.) + Returns the total number of deleted nodes.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddGarbageCollect( + DdManager * unique, + int clearCache) +{ + DdHook *hook; + DdCache *cache = unique->cache; + DdNode *sentinel = &(unique->sentinel); + DdNodePtr *nodelist; + int i, j, deleted, totalDeleted, totalDeletedZ; + DdCache *c; + DdNode *node,*next; + DdNodePtr *lastP; + int slots; + unsigned long localTime; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + DdNodePtr tree; +#else + DdNodePtr *memListTrav, *nxtNode; + DdNode *downTrav, *sentry; + int k; +#endif +#endif + +#ifndef DD_NO_DEATH_ROW + cuddClearDeathRow(unique); +#endif + + hook = unique->preGCHook; + while (hook != NULL) { + int res = (hook->f)(unique,"DD",NULL); + if (res == 0) return(0); + hook = hook->next; + } + + if (unique->dead + unique->deadZ == 0) { + hook = unique->postGCHook; + while (hook != NULL) { + int res = (hook->f)(unique,"DD",NULL); + if (res == 0) return(0); + hook = hook->next; + } + return(0); + } + + /* If many nodes are being reclaimed, we want to resize the tables + ** more aggressively, to reduce the frequency of garbage collection. + */ + if (clearCache && unique->gcFrac == DD_GC_FRAC_LO && + unique->slots <= unique->looseUpTo && unique->stash != NULL) { + unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots); +#ifdef DD_VERBOSE + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_HI); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); +#endif + unique->gcFrac = DD_GC_FRAC_HI; + return(0); + } + + localTime = util_cpu_time(); + + unique->garbageCollections++; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "garbage collecting (%d dead BDD nodes out of %d, min %d)...", + unique->dead, unique->keys, unique->minDead); + (void) fprintf(unique->err, + " (%d dead ZDD nodes out of %d)...", + unique->deadZ, unique->keysZ); +#endif + + /* Remove references to garbage collected nodes from the cache. */ + if (clearCache) { + slots = unique->cacheSlots; + for (i = 0; i < slots; i++) { + c = &cache[i]; + if (c->data != NULL) { + if (cuddClean(c->f)->ref == 0 || + cuddClean(c->g)->ref == 0 || + (((ptruint)c->f & 0x2) && Cudd_Regular(c->h)->ref == 0) || + (c->data != DD_NON_CONSTANT && + Cudd_Regular(c->data)->ref == 0)) { + c->data = NULL; + unique->cachedeletions++; + } + } + } + cuddLocalCacheClearDead(unique); + } + + /* Now return dead nodes to free list. Count them for sanity check. */ + totalDeleted = 0; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + tree = NULL; +#endif +#endif + + for (i = 0; i < unique->size; i++) { + if (unique->subtables[i].dead == 0) continue; + nodelist = unique->subtables[i].nodelist; + + deleted = 0; + slots = unique->subtables[i].slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != sentinel) { + next = node->next; + if (node->ref == 0) { + deleted++; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + cuddOrderedInsert(&tree,node); +#endif +#else + cuddDeallocNode(unique,node); +#endif + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = sentinel; + } + if ((unsigned) deleted != unique->subtables[i].dead) { + ddReportRefMess(unique, i, "cuddGarbageCollect"); + } + totalDeleted += deleted; + unique->subtables[i].keys -= deleted; + unique->subtables[i].dead = 0; + } + if (unique->constants.dead != 0) { + nodelist = unique->constants.nodelist; + deleted = 0; + slots = unique->constants.slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != NULL) { + next = node->next; + if (node->ref == 0) { + deleted++; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + cuddOrderedInsert(&tree,node); +#endif +#else + cuddDeallocNode(unique,node); +#endif + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = NULL; + } + if ((unsigned) deleted != unique->constants.dead) { + ddReportRefMess(unique, CUDD_CONST_INDEX, "cuddGarbageCollect"); + } + totalDeleted += deleted; + unique->constants.keys -= deleted; + unique->constants.dead = 0; + } + if ((unsigned) totalDeleted != unique->dead) { + ddReportRefMess(unique, -1, "cuddGarbageCollect"); + } + unique->keys -= totalDeleted; + unique->dead = 0; +#ifdef DD_STATS + unique->nodesFreed += (double) totalDeleted; +#endif + + totalDeletedZ = 0; + + for (i = 0; i < unique->sizeZ; i++) { + if (unique->subtableZ[i].dead == 0) continue; + nodelist = unique->subtableZ[i].nodelist; + + deleted = 0; + slots = unique->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != NULL) { + next = node->next; + if (node->ref == 0) { + deleted++; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + cuddOrderedInsert(&tree,node); +#endif +#else + cuddDeallocNode(unique,node); +#endif + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = NULL; + } + if ((unsigned) deleted != unique->subtableZ[i].dead) { + ddReportRefMess(unique, i, "cuddGarbageCollect"); + } + totalDeletedZ += deleted; + unique->subtableZ[i].keys -= deleted; + unique->subtableZ[i].dead = 0; + } + + /* No need to examine the constant table for ZDDs. + ** If we did we should be careful not to count whatever dead + ** nodes we found there among the dead ZDD nodes. */ + if ((unsigned) totalDeletedZ != unique->deadZ) { + ddReportRefMess(unique, -1, "cuddGarbageCollect"); + } + unique->keysZ -= totalDeletedZ; + unique->deadZ = 0; +#ifdef DD_STATS + unique->nodesFreed += (double) totalDeletedZ; +#endif + + +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + unique->nextFree = cuddOrderedThread(tree,unique->nextFree); +#else + memListTrav = unique->memoryList; + sentry = NULL; + while (memListTrav != NULL) { + ptruint offset; + nxtNode = (DdNodePtr *)memListTrav[0]; + offset = (ptruint) memListTrav & (sizeof(DdNode) - 1); + memListTrav += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); + downTrav = (DdNode *)memListTrav; + k = 0; + do { + if (downTrav[k].ref == 0) { + if (sentry == NULL) { + unique->nextFree = sentry = &downTrav[k]; + } else { + /* First hook sentry->next to the dead node and then + ** reassign sentry to the dead node. */ + sentry = (sentry->next = &downTrav[k]); + } + } + } while (++k < DD_MEM_CHUNK); + memListTrav = nxtNode; + } + sentry->next = NULL; +#endif +#endif + + unique->GCTime += util_cpu_time() - localTime; + + hook = unique->postGCHook; + while (hook != NULL) { + int res = (hook->f)(unique,"DD",NULL); + if (res == 0) return(0); + hook = hook->next; + } + +#ifdef DD_VERBOSE + (void) fprintf(unique->err," done\n"); +#endif + + return(totalDeleted+totalDeletedZ); + +} /* end of cuddGarbageCollect */ + + +/**Function******************************************************************** + + Synopsis [Wrapper for cuddUniqueInterZdd.] + + Description [Wrapper for cuddUniqueInterZdd, which applies the ZDD + reduction rule. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted.] + + SideEffects [None] + + SeeAlso [cuddUniqueInterZdd] + +******************************************************************************/ +DdNode * +cuddZddGetNode( + DdManager * zdd, + int id, + DdNode * T, + DdNode * E) +{ + DdNode *node; + + if (T == DD_ZERO(zdd)) + return(E); + node = cuddUniqueInterZdd(zdd, id, T, E); + return(node); + +} /* end of cuddZddGetNode */ + + +/**Function******************************************************************** + + Synopsis [Wrapper for cuddUniqueInterZdd that is independent of variable + ordering.] + + Description [Wrapper for cuddUniqueInterZdd that is independent of + variable ordering (IVO). This function does not require parameter + index to precede the indices of the top nodes of g and h in the + variable order. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted.] + + SideEffects [None] + + SeeAlso [cuddZddGetNode cuddZddIsop] + +******************************************************************************/ +DdNode * +cuddZddGetNodeIVO( + DdManager * dd, + int index, + DdNode * g, + DdNode * h) +{ + DdNode *f, *r, *t; + DdNode *zdd_one = DD_ONE(dd); + DdNode *zdd_zero = DD_ZERO(dd); + + f = cuddUniqueInterZdd(dd, index, zdd_one, zdd_zero); + if (f == NULL) { + return(NULL); + } + cuddRef(f); + t = cuddZddProduct(dd, f, g); + if (t == NULL) { + Cudd_RecursiveDerefZdd(dd, f); + return(NULL); + } + cuddRef(t); + Cudd_RecursiveDerefZdd(dd, f); + r = cuddZddUnion(dd, t, h); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, t); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDerefZdd(dd, t); + + cuddDeref(r); + return(r); + +} /* end of cuddZddGetNodeIVO */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for the existence of an internal node.] + + Description [Checks the unique table for the existence of an internal + node. If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. For a newly + created node, increments the reference counts of what T and E point + to. Returns a pointer to the new node if successful; NULL if memory + is exhausted or if reordering took place.] + + SideEffects [None] + + SeeAlso [cuddUniqueInterZdd] + +******************************************************************************/ +DdNode * +cuddUniqueInter( + DdManager * unique, + int index, + DdNode * T, + DdNode * E) +{ + int pos; + unsigned int level; + int retval; + DdNodePtr *nodelist; + DdNode *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int gcNumber; + +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLookUps++; +#endif + + if ((0x1ffffUL & (unsigned long) unique->cacheMisses) == 0) { + if (util_cpu_time() - unique->startTime > unique->timeLimit) { + unique->errorCode = CUDD_TIMEOUT_EXPIRED; + return(NULL); + } + } + if (index >= unique->size) { + int amount = ddMax(DD_DEFAULT_RESIZE,unique->size/20); + if (!ddResizeTable(unique,index,amount)) return(NULL); + } + + level = unique->perm[index]; + subtable = &(unique->subtables[level]); + +#ifdef DD_DEBUG + assert(level < (unsigned) cuddI(unique,T->index)); + assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index)); +#endif + + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + while (T == cuddT(looking) && E < cuddE(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + if (T == cuddT(looking) && E == cuddE(looking)) { + if (looking->ref == 0) { + cuddReclaim(unique,looking); + } + return(looking); + } + + /* countDead is 0 if deads should be counted and ~0 if they should not. */ + if (unique->autoDyn && + unique->keys - (unique->dead & unique->countDead) >= unique->nextDyn && + unique->maxReorderings > 0) { + unsigned long cpuTime; +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(unique); + if (retval != 0) return(NULL); + retval = Cudd_CheckKeys(unique); + if (retval != 0) return(NULL); +#endif + retval = Cudd_ReduceHeap(unique,unique->autoMethod,10); /* 10 = whatever */ + unique->maxReorderings--; + if (retval == 0) { + unique->reordered = 2; + } else if ((cpuTime = util_cpu_time()) - unique->startTime > unique->timeLimit) { + unique->errorCode = CUDD_TIMEOUT_EXPIRED; + unique->reordered = 0; + } else if (unique->timeLimit - (cpuTime - unique->startTime) + < unique->reordTime) { + unique->autoDyn = 0; + } +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(unique); + if (retval != 0) unique->reordered = 2; + retval = Cudd_CheckKeys(unique); + if (retval != 0) unique->reordered = 2; +#endif + return(NULL); + } + + if (subtable->keys > subtable->maxKeys) { + if (unique->gcEnabled && + ((unique->dead > unique->minDead) || + ((unique->dead > unique->minDead / 2) && + (subtable->dead > subtable->keys * 0.95)))) { /* too many dead */ + if (util_cpu_time() - unique->startTime > unique->timeLimit) { + unique->errorCode = CUDD_TIMEOUT_EXPIRED; + return(NULL); + } + (void) cuddGarbageCollect(unique,1); + } else { + cuddRehash(unique,(int)level); + } + /* Update pointer to insertion point. In the case of rehashing, + ** the slot may have changed. In the case of garbage collection, + ** the predecessor may have been dead. */ + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + while (T == cuddT(looking) && E < cuddE(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + } + + gcNumber = unique->garbageCollections; + looking = cuddAllocNode(unique); + if (looking == NULL) { + return(NULL); + } + unique->keys++; + subtable->keys++; + + if (gcNumber != unique->garbageCollections) { + DdNode *looking2; + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + previousP = &(nodelist[pos]); + looking2 = *previousP; + + while (T < cuddT(looking2)) { + previousP = &(looking2->next); + looking2 = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + while (T == cuddT(looking2) && E < cuddE(looking2)) { + previousP = &(looking2->next); + looking2 = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + } + looking->index = index; + cuddT(looking) = T; + cuddE(looking) = E; + looking->next = *previousP; + *previousP = looking; + cuddSatInc(T->ref); /* we know T is a regular pointer */ + cuddRef(E); + +#ifdef DD_DEBUG + cuddCheckCollisionOrdering(unique,level,pos); +#endif + + return(looking); + +} /* end of cuddUniqueInter */ + + +/**Function******************************************************************** + + Synopsis [Wrapper for cuddUniqueInter that is independent of variable + ordering.] + + Description [Wrapper for cuddUniqueInter that is independent of + variable ordering (IVO). This function does not require parameter + index to precede the indices of the top nodes of T and E in the + variable order. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted.] + + SideEffects [None] + + SeeAlso [cuddUniqueInter Cudd_MakeBddFromZddCover] + +******************************************************************************/ +DdNode * +cuddUniqueInterIVO( + DdManager * unique, + int index, + DdNode * T, + DdNode * E) +{ + DdNode *result; + DdNode *v; + + v = cuddUniqueInter(unique, index, DD_ONE(unique), + Cudd_Not(DD_ONE(unique))); + if (v == NULL) + return(NULL); + /* Since v is a projection function, we can skip the call to cuddRef. */ + result = cuddBddIteRecur(unique, v, T, E); + return(result); + +} /* end of cuddUniqueInterIVO */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for the existence of an internal + ZDD node.] + + Description [Checks the unique table for the existence of an internal + ZDD node. If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. For a newly + created node, increments the reference counts of what T and E point + to. Returns a pointer to the new node if successful; NULL if memory + is exhausted or if reordering took place.] + + SideEffects [None] + + SeeAlso [cuddUniqueInter] + +******************************************************************************/ +DdNode * +cuddUniqueInterZdd( + DdManager * unique, + int index, + DdNode * T, + DdNode * E) +{ + int pos; + unsigned int level; + int retval; + DdNodePtr *nodelist; + DdNode *looking; + DdSubtable *subtable; + +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLookUps++; +#endif + + if (index >= unique->sizeZ) { + if (!cuddResizeTableZdd(unique,index)) return(NULL); + } + + level = unique->permZ[index]; + subtable = &(unique->subtableZ[level]); + +#ifdef DD_DEBUG + assert(level < (unsigned) cuddIZ(unique,T->index)); + assert(level < (unsigned) cuddIZ(unique,Cudd_Regular(E)->index)); +#endif + + if (subtable->keys > subtable->maxKeys) { + if (unique->gcEnabled && ((unique->deadZ > unique->minDead) || + (10 * subtable->dead > 9 * subtable->keys))) { /* too many dead */ + (void) cuddGarbageCollect(unique,1); + } else { + ddRehashZdd(unique,(int)level); + } + } + + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + looking = nodelist[pos]; + + while (looking != NULL) { + if (cuddT(looking) == T && cuddE(looking) == E) { + if (looking->ref == 0) { + cuddReclaimZdd(unique,looking); + } + return(looking); + } + looking = looking->next; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + + /* countDead is 0 if deads should be counted and ~0 if they should not. */ + if (unique->autoDynZ && + unique->keysZ - (unique->deadZ & unique->countDead) >= unique->nextDyn) { +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(unique); + if (retval != 0) return(NULL); + retval = Cudd_CheckKeys(unique); + if (retval != 0) return(NULL); +#endif + retval = Cudd_zddReduceHeap(unique,unique->autoMethodZ,10); /* 10 = whatever */ + if (retval == 0) unique->reordered = 2; +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(unique); + if (retval != 0) unique->reordered = 2; + retval = Cudd_CheckKeys(unique); + if (retval != 0) unique->reordered = 2; +#endif + return(NULL); + } + + unique->keysZ++; + subtable->keys++; + + looking = cuddAllocNode(unique); + if (looking == NULL) return(NULL); + looking->index = index; + cuddT(looking) = T; + cuddE(looking) = E; + looking->next = nodelist[pos]; + nodelist[pos] = looking; + cuddRef(T); + cuddRef(E); + + return(looking); + +} /* end of cuddUniqueInterZdd */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for the existence of a constant node.] + + Description [Checks the unique table for the existence of a constant node. + If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. Returns a + pointer to the new node.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddUniqueConst( + DdManager * unique, + CUDD_VALUE_TYPE value) +{ + int pos; + DdNodePtr *nodelist; + DdNode *looking; + hack split; + +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLookUps++; +#endif + + if (unique->constants.keys > unique->constants.maxKeys) { + if (unique->gcEnabled && ((unique->dead > unique->minDead) || + (10 * unique->constants.dead > 9 * unique->constants.keys))) { /* too many dead */ + (void) cuddGarbageCollect(unique,1); + } else { + cuddRehash(unique,CUDD_CONST_INDEX); + } + } + + cuddAdjust(value); /* for the case of crippled infinities */ + + if (ddAbs(value) < unique->epsilon) { + value = 0.0; + } + split.value = value; + + pos = ddHash(split.bits[0], split.bits[1], unique->constants.shift); + nodelist = unique->constants.nodelist; + looking = nodelist[pos]; + + /* Here we compare values both for equality and for difference less + * than epsilon. The first comparison is required when values are + * infinite, since Infinity - Infinity is NaN and NaN < X is 0 for + * every X. + */ + while (looking != NULL) { + if (looking->type.value == value || + ddEqualVal(looking->type.value,value,unique->epsilon)) { + if (looking->ref == 0) { + cuddReclaim(unique,looking); + } + return(looking); + } + looking = looking->next; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + + unique->keys++; + unique->constants.keys++; + + looking = cuddAllocNode(unique); + if (looking == NULL) return(NULL); + looking->index = CUDD_CONST_INDEX; + looking->type.value = value; + looking->next = nodelist[pos]; + nodelist[pos] = looking; + + return(looking); + +} /* end of cuddUniqueConst */ + + +/**Function******************************************************************** + + Synopsis [Rehashes a unique subtable.] + + Description [Doubles the size of a unique subtable and rehashes its + contents.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddRehash( + DdManager * unique, + int i) +{ + unsigned int slots, oldslots; + int shift, oldshift; + int j, pos; + DdNodePtr *nodelist, *oldnodelist; + DdNode *node, *next; + DdNode *sentinel = &(unique->sentinel); + hack split; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (unique->gcFrac == DD_GC_FRAC_HI && unique->slots > unique->looseUpTo) { + unique->gcFrac = DD_GC_FRAC_LO; + unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); +#ifdef DD_VERBOSE + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_LO); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); +#endif + } + + if (unique->gcFrac != DD_GC_FRAC_MIN && unique->memused > unique->maxmem) { + unique->gcFrac = DD_GC_FRAC_MIN; + unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots); +#ifdef DD_VERBOSE + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_MIN); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); +#endif + cuddShrinkDeathRow(unique); + if (cuddGarbageCollect(unique,1) > 0) return; + } + + if (i != CUDD_CONST_INDEX) { + oldslots = unique->subtables[i].slots; + oldshift = unique->subtables[i].shift; + oldnodelist = unique->subtables[i].nodelist; + + /* Compute the new size of the subtable. */ + slots = oldslots << 1; + shift = oldshift - 1; + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + (void) fprintf(unique->err, + "Unable to resize subtable %d for lack of memory\n", + i); + /* Prevent frequent resizing attempts. */ + (void) cuddGarbageCollect(unique,1); + if (unique->stash != NULL) { + FREE(unique->stash); + unique->stash = NULL; + /* Inhibit resizing of tables. */ + cuddSlowTableGrowth(unique); + } + return; + } + unique->subtables[i].nodelist = nodelist; + unique->subtables[i].slots = slots; + unique->subtables[i].shift = shift; + unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + + /* Move the nodes from the old table to the new table. + ** This code depends on the type of hash function. + ** It assumes that the effect of doubling the size of the table + ** is to retain one more bit of the 32-bit hash value. + ** The additional bit is the LSB. */ + for (j = 0; (unsigned) j < oldslots; j++) { + DdNodePtr *evenP, *oddP; + node = oldnodelist[j]; + evenP = &(nodelist[j<<1]); + oddP = &(nodelist[(j<<1)+1]); + while (node != sentinel) { + next = node->next; + pos = ddHash(cuddT(node), cuddE(node), shift); + if (pos & 1) { + *oddP = node; + oddP = &(node->next); + } else { + *evenP = node; + evenP = &(node->next); + } + node = next; + } + *evenP = *oddP = sentinel; + } + FREE(oldnodelist); + +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "rehashing layer %d: keys %d dead %d new size %d\n", + i, unique->subtables[i].keys, + unique->subtables[i].dead, slots); +#endif + } else { + oldslots = unique->constants.slots; + oldshift = unique->constants.shift; + oldnodelist = unique->constants.nodelist; + + /* The constant subtable is never subjected to reordering. + ** Therefore, when it is resized, it is because it has just + ** reached the maximum load. We can safely just double the size, + ** with no need for the loop we use for the other tables. + */ + slots = oldslots << 1; + shift = oldshift - 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + (void) fprintf(unique->err, + "Unable to resize constant subtable for lack of memory\n"); + (void) cuddGarbageCollect(unique,1); + for (j = 0; j < unique->size; j++) { + unique->subtables[j].maxKeys <<= 1; + } + unique->constants.maxKeys <<= 1; + return; + } + unique->constants.slots = slots; + unique->constants.shift = shift; + unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + unique->constants.nodelist = nodelist; + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + split.value = cuddV(node); + pos = ddHash(split.bits[0], split.bits[1], shift); + node->next = nodelist[pos]; + nodelist[pos] = node; + node = next; + } + } + FREE(oldnodelist); + +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "rehashing constants: keys %d dead %d new size %d\n", + unique->constants.keys,unique->constants.dead,slots); +#endif + } + + /* Update global data */ + + unique->memused += (slots - oldslots) * sizeof(DdNodePtr); + unique->slots += (slots - oldslots); + ddFixLimits(unique); + +} /* end of cuddRehash */ + + +/**Function******************************************************************** + + Synopsis [Shrinks a subtable.] + + Description [Shrinks a subtable.] + + SideEffects [None] + + SeeAlso [cuddRehash] + +******************************************************************************/ +void +cuddShrinkSubtable( + DdManager *unique, + int i) +{ + int j; + int shift, posn; + DdNodePtr *nodelist, *oldnodelist; + DdNode *node, *next; + DdNode *sentinel = &(unique->sentinel); + unsigned int slots, oldslots; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + oldnodelist = unique->subtables[i].nodelist; + oldslots = unique->subtables[i].slots; + slots = oldslots >> 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + return; + } + unique->subtables[i].nodelist = nodelist; + unique->subtables[i].slots = slots; + unique->subtables[i].shift++; + unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "shrunk layer %d (%d keys) from %d to %d slots\n", + i, unique->subtables[i].keys, oldslots, slots); +#endif + + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = sentinel; + } + shift = unique->subtables[i].shift; + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != sentinel) { + DdNode *looking, *T, *E; + DdNodePtr *previousP; + next = node->next; + posn = ddHash(cuddT(node), cuddE(node), shift); + previousP = &(nodelist[posn]); + looking = *previousP; + T = cuddT(node); + E = cuddE(node); + while (T < cuddT(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + while (T == cuddT(looking) && E < cuddE(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + node->next = *previousP; + *previousP = node; + node = next; + } + } + FREE(oldnodelist); + + unique->memused += ((long) slots - (long) oldslots) * sizeof(DdNode *); + unique->slots += slots - oldslots; + unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); + unique->cacheSlack = (int) + ddMin(unique->maxCacheHard,DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) + - 2 * (int) unique->cacheSlots; + +} /* end of cuddShrinkSubtable */ + + +/**Function******************************************************************** + + Synopsis [Inserts n new subtables in a unique table at level.] + + Description [Inserts n new subtables in a unique table at level. + The number n should be positive, and level should be an existing level. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddDestroySubtables] + +******************************************************************************/ +int +cuddInsertSubtables( + DdManager * unique, + int n, + int level) +{ + DdSubtable *newsubtables; + DdNodePtr *newnodelist; + DdNodePtr *newvars; + DdNode *sentinel = &(unique->sentinel); + int oldsize,newsize; + int i,j,index,reorderSave; + unsigned int numSlots = unique->initSlots; + int *newperm, *newinvperm, *newmap; + DdNode *one, *zero; + +#ifdef DD_DEBUG + assert(n > 0 && level < unique->size); +#endif + + oldsize = unique->size; + /* Easy case: there is still room in the current table. */ + if (oldsize + n <= unique->maxSize) { + /* Shift the tables at and below level. */ + for (i = oldsize - 1; i >= level; i--) { + unique->subtables[i+n].slots = unique->subtables[i].slots; + unique->subtables[i+n].shift = unique->subtables[i].shift; + unique->subtables[i+n].keys = unique->subtables[i].keys; + unique->subtables[i+n].maxKeys = unique->subtables[i].maxKeys; + unique->subtables[i+n].dead = unique->subtables[i].dead; + unique->subtables[i+n].nodelist = unique->subtables[i].nodelist; + unique->subtables[i+n].bindVar = unique->subtables[i].bindVar; + unique->subtables[i+n].varType = unique->subtables[i].varType; + unique->subtables[i+n].pairIndex = unique->subtables[i].pairIndex; + unique->subtables[i+n].varHandled = unique->subtables[i].varHandled; + unique->subtables[i+n].varToBeGrouped = + unique->subtables[i].varToBeGrouped; + + index = unique->invperm[i]; + unique->invperm[i+n] = index; + unique->perm[index] += n; + } + /* Create new subtables. */ + for (i = 0; i < n; i++) { + unique->subtables[level+i].slots = numSlots; + unique->subtables[level+i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtables[level+i].keys = 0; + unique->subtables[level+i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[level+i].dead = 0; + unique->subtables[level+i].bindVar = 0; + unique->subtables[level+i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[level+i].pairIndex = 0; + unique->subtables[level+i].varHandled = 0; + unique->subtables[level+i].varToBeGrouped = CUDD_LAZY_NONE; + + unique->perm[oldsize+i] = level + i; + unique->invperm[level+i] = oldsize + i; + newnodelist = unique->subtables[level+i].nodelist = + ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + if (unique->map != NULL) { + for (i = 0; i < n; i++) { + unique->map[oldsize+i] = oldsize + i; + } + } + } else { + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables. + */ + newsize = oldsize + n + DD_DEFAULT_RESIZE; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "Increasing the table size from %d to %d\n", + unique->maxSize, newsize); +#endif + /* Allocate memory for new arrays (except nodelists). */ + newsubtables = ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newvars = ALLOC(DdNodePtr,newsize); + if (newvars == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + FREE(newsubtables); + return(0); + } + newperm = ALLOC(int,newsize); + if (newperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + FREE(newsubtables); + FREE(newvars); + return(0); + } + newinvperm = ALLOC(int,newsize); + if (newinvperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + return(0); + } + if (unique->map != NULL) { + newmap = ALLOC(int,newsize); + if (newmap == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + FREE(newinvperm); + return(0); + } + unique->memused += (newsize - unique->maxSize) * sizeof(int); + } + unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + /* Copy levels before insertion points from old tables. */ + for (i = 0; i < level; i++) { + newsubtables[i].slots = unique->subtables[i].slots; + newsubtables[i].shift = unique->subtables[i].shift; + newsubtables[i].keys = unique->subtables[i].keys; + newsubtables[i].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i].dead = unique->subtables[i].dead; + newsubtables[i].nodelist = unique->subtables[i].nodelist; + newsubtables[i].bindVar = unique->subtables[i].bindVar; + newsubtables[i].varType = unique->subtables[i].varType; + newsubtables[i].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i].varHandled = unique->subtables[i].varHandled; + newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + newperm[i] = unique->perm[i]; + newinvperm[i] = unique->invperm[i]; + } + /* Finish initializing permutation for new table to old one. */ + for (i = level; i < oldsize; i++) { + newperm[i] = unique->perm[i]; + } + /* Initialize new levels. */ + for (i = level; i < level + n; i++) { + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newsubtables[i].bindVar = 0; + newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + newsubtables[i].pairIndex = 0; + newsubtables[i].varHandled = 0; + newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + newperm[oldsize + i - level] = i; + newinvperm[i] = oldsize + i - level; + newnodelist = newsubtables[i].nodelist = ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + /* We are going to leak some memory. We should clean up. */ + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + /* Copy the old tables for levels past the insertion point. */ + for (i = level; i < oldsize; i++) { + newsubtables[i+n].slots = unique->subtables[i].slots; + newsubtables[i+n].shift = unique->subtables[i].shift; + newsubtables[i+n].keys = unique->subtables[i].keys; + newsubtables[i+n].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i+n].dead = unique->subtables[i].dead; + newsubtables[i+n].nodelist = unique->subtables[i].nodelist; + newsubtables[i+n].bindVar = unique->subtables[i].bindVar; + newsubtables[i+n].varType = unique->subtables[i].varType; + newsubtables[i+n].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i+n].varHandled = unique->subtables[i].varHandled; + newsubtables[i+n].varToBeGrouped = + unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + index = unique->invperm[i]; + newinvperm[i+n] = index; + newperm[index] += n; + } + /* Update the map. */ + if (unique->map != NULL) { + for (i = 0; i < oldsize; i++) { + newmap[i] = unique->map[i]; + } + for (i = oldsize; i < oldsize + n; i++) { + newmap[i] = i; + } + FREE(unique->map); + unique->map = newmap; + } + /* Install the new tables and free the old ones. */ + FREE(unique->subtables); + unique->subtables = newsubtables; + unique->maxSize = newsize; + FREE(unique->vars); + unique->vars = newvars; + FREE(unique->perm); + unique->perm = newperm; + FREE(unique->invperm); + unique->invperm = newinvperm; + /* Update the stack for iterative procedures. */ + if (newsize > unique->maxSizeZ) { + FREE(unique->stack); + unique->stack = ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); + } + } + /* Update manager parameters to account for the new subtables. */ + unique->slots += n * numSlots; + ddFixLimits(unique); + unique->size += n; + + /* Now that the table is in a coherent state, create the new + ** projection functions. We need to temporarily disable reordering, + ** because we cannot reorder without projection functions in place. + **/ + one = unique->one; + zero = Cudd_Not(one); + + reorderSave = unique->autoDyn; + unique->autoDyn = 0; + for (i = oldsize; i < oldsize + n; i++) { + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) { + unique->autoDyn = reorderSave; + /* Shift everything back so table remains coherent. */ + for (j = oldsize; j < i; j++) { + Cudd_IterDerefBdd(unique,unique->vars[j]); + cuddDeallocNode(unique,unique->vars[j]); + unique->vars[j] = NULL; + } + for (j = level; j < oldsize; j++) { + unique->subtables[j].slots = unique->subtables[j+n].slots; + unique->subtables[j].slots = unique->subtables[j+n].slots; + unique->subtables[j].shift = unique->subtables[j+n].shift; + unique->subtables[j].keys = unique->subtables[j+n].keys; + unique->subtables[j].maxKeys = + unique->subtables[j+n].maxKeys; + unique->subtables[j].dead = unique->subtables[j+n].dead; + FREE(unique->subtables[j].nodelist); + unique->subtables[j].nodelist = + unique->subtables[j+n].nodelist; + unique->subtables[j+n].nodelist = NULL; + unique->subtables[j].bindVar = + unique->subtables[j+n].bindVar; + unique->subtables[j].varType = + unique->subtables[j+n].varType; + unique->subtables[j].pairIndex = + unique->subtables[j+n].pairIndex; + unique->subtables[j].varHandled = + unique->subtables[j+n].varHandled; + unique->subtables[j].varToBeGrouped = + unique->subtables[j+n].varToBeGrouped; + index = unique->invperm[j+n]; + unique->invperm[j] = index; + unique->perm[index] -= n; + } + unique->size = oldsize; + unique->slots -= n * numSlots; + ddFixLimits(unique); + (void) Cudd_DebugCheck(unique); + return(0); + } + cuddRef(unique->vars[i]); + } + if (unique->tree != NULL) { + unique->tree->size += n; + unique->tree->index = unique->invperm[0]; + ddPatchTree(unique,unique->tree); + } + unique->autoDyn = reorderSave; + + return(1); + +} /* end of cuddInsertSubtables */ + + +/**Function******************************************************************** + + Synopsis [Destroys the n most recently created subtables in a unique table.] + + Description [Destroys the n most recently created subtables in a unique + table. n should be positive. The subtables should not contain any live + nodes, except the (isolated) projection function. The projection + functions are freed. Returns 1 if successful; 0 otherwise.] + + SideEffects [The variable map used for fast variable substitution is + destroyed if it exists. In this case the cache is also cleared.] + + SeeAlso [cuddInsertSubtables Cudd_SetVarMap] + +******************************************************************************/ +int +cuddDestroySubtables( + DdManager * unique, + int n) +{ + DdSubtable *subtables; + DdNodePtr *nodelist; + DdNodePtr *vars; + int firstIndex, lastIndex; + int index, level, newlevel; + int lowestLevel; + int shift; + int found; + + /* Sanity check and set up. */ + if (n <= 0) return(0); + if (n > unique->size) n = unique->size; + + subtables = unique->subtables; + vars = unique->vars; + firstIndex = unique->size - n; + lastIndex = unique->size; + + /* Check for nodes labeled by the variables being destroyed + ** that may still be in use. It is allowed to destroy a variable + ** only if there are no such nodes. Also, find the lowest level + ** among the variables being destroyed. This will make further + ** processing more efficient. + */ + lowestLevel = unique->size; + for (index = firstIndex; index < lastIndex; index++) { + level = unique->perm[index]; + if (level < lowestLevel) lowestLevel = level; + nodelist = subtables[level].nodelist; + if (subtables[level].keys - subtables[level].dead != 1) return(0); + /* The projection function should be isolated. If the ref count + ** is 1, everything is OK. If the ref count is saturated, then + ** we need to make sure that there are no nodes pointing to it. + ** As for the external references, we assume the application is + ** responsible for them. + */ + if (vars[index]->ref != 1) { + if (vars[index]->ref != DD_MAXREF) return(0); + found = cuddFindParent(unique,vars[index]); + if (found) { + return(0); + } else { + vars[index]->ref = 1; + } + } + Cudd_RecursiveDeref(unique,vars[index]); + } + + /* Collect garbage, because we cannot afford having dead nodes pointing + ** to the dead nodes in the subtables being destroyed. + */ + (void) cuddGarbageCollect(unique,1); + + /* Here we know we can destroy our subtables. */ + for (index = firstIndex; index < lastIndex; index++) { + level = unique->perm[index]; + nodelist = subtables[level].nodelist; +#ifdef DD_DEBUG + assert(subtables[level].keys == 0); +#endif + FREE(nodelist); + unique->memused -= sizeof(DdNodePtr) * subtables[level].slots; + unique->slots -= subtables[level].slots; + unique->dead -= subtables[level].dead; + } + + /* Here all subtables to be destroyed have their keys field == 0 and + ** their hash tables have been freed. + ** We now scan the subtables from level lowestLevel + 1 to level size - 1, + ** shifting the subtables as required. We keep a running count of + ** how many subtables have been moved, so that we know by how many + ** positions each subtable should be shifted. + */ + shift = 1; + for (level = lowestLevel + 1; level < unique->size; level++) { + if (subtables[level].keys == 0) { + shift++; + continue; + } + newlevel = level - shift; + subtables[newlevel].slots = subtables[level].slots; + subtables[newlevel].shift = subtables[level].shift; + subtables[newlevel].keys = subtables[level].keys; + subtables[newlevel].maxKeys = subtables[level].maxKeys; + subtables[newlevel].dead = subtables[level].dead; + subtables[newlevel].nodelist = subtables[level].nodelist; + index = unique->invperm[level]; + unique->perm[index] = newlevel; + unique->invperm[newlevel] = index; + subtables[newlevel].bindVar = subtables[level].bindVar; + subtables[newlevel].varType = subtables[level].varType; + subtables[newlevel].pairIndex = subtables[level].pairIndex; + subtables[newlevel].varHandled = subtables[level].varHandled; + subtables[newlevel].varToBeGrouped = subtables[level].varToBeGrouped; + } + /* Destroy the map. If a surviving variable is + ** mapped to a dying variable, and the map were used again, + ** an out-of-bounds access to unique->vars would result. */ + if (unique->map != NULL) { + cuddCacheFlush(unique); + FREE(unique->map); + unique->map = NULL; + } + + unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); + unique->size -= n; + + return(1); + +} /* end of cuddDestroySubtables */ + + +/**Function******************************************************************** + + Synopsis [Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index.] + + Description [Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index. When new ZDD variables are created, it + is possible to preserve the functions unchanged, or it is possible to + preserve the covers unchanged, but not both. cuddResizeTableZdd preserves + the covers. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [ddResizeTable] + +******************************************************************************/ +int +cuddResizeTableZdd( + DdManager * unique, + int index) +{ + DdSubtable *newsubtables; + DdNodePtr *newnodelist; + int oldsize,newsize; + int i,j,reorderSave; + unsigned int numSlots = unique->initSlots; + int *newperm, *newinvperm; + + oldsize = unique->sizeZ; + /* Easy case: there is still room in the current table. */ + if (index < unique->maxSizeZ) { + for (i = oldsize; i <= index; i++) { + unique->subtableZ[i].slots = numSlots; + unique->subtableZ[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtableZ[i].keys = 0; + unique->subtableZ[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtableZ[i].dead = 0; + unique->permZ[i] = i; + unique->invpermZ[i] = i; + newnodelist = unique->subtableZ[i].nodelist = + ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = NULL; + } + } + } else { + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables up to index included. + */ + newsize = index + DD_DEFAULT_RESIZE; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "Increasing the ZDD table size from %d to %d\n", + unique->maxSizeZ, newsize); +#endif + newsubtables = ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newperm = ALLOC(int,newsize); + if (newperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newinvperm = ALLOC(int,newsize); + if (newinvperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->memused += (newsize - unique->maxSizeZ) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + if (newsize > unique->maxSize) { + FREE(unique->stack); + unique->stack = ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); + } + for (i = 0; i < oldsize; i++) { + newsubtables[i].slots = unique->subtableZ[i].slots; + newsubtables[i].shift = unique->subtableZ[i].shift; + newsubtables[i].keys = unique->subtableZ[i].keys; + newsubtables[i].maxKeys = unique->subtableZ[i].maxKeys; + newsubtables[i].dead = unique->subtableZ[i].dead; + newsubtables[i].nodelist = unique->subtableZ[i].nodelist; + newperm[i] = unique->permZ[i]; + newinvperm[i] = unique->invpermZ[i]; + } + for (i = oldsize; i <= index; i++) { + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newperm[i] = i; + newinvperm[i] = i; + newnodelist = newsubtables[i].nodelist = ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = NULL; + } + } + FREE(unique->subtableZ); + unique->subtableZ = newsubtables; + unique->maxSizeZ = newsize; + FREE(unique->permZ); + unique->permZ = newperm; + FREE(unique->invpermZ); + unique->invpermZ = newinvperm; + } + unique->slots += (index + 1 - unique->sizeZ) * numSlots; + ddFixLimits(unique); + unique->sizeZ = index + 1; + + /* Now that the table is in a coherent state, update the ZDD + ** universe. We need to temporarily disable reordering, + ** because we cannot reorder without universe in place. + */ + + reorderSave = unique->autoDynZ; + unique->autoDynZ = 0; + cuddZddFreeUniv(unique); + if (!cuddZddInitUniv(unique)) { + unique->autoDynZ = reorderSave; + return(0); + } + unique->autoDynZ = reorderSave; + + return(1); + +} /* end of cuddResizeTableZdd */ + + +/**Function******************************************************************** + + Synopsis [Adjusts parameters of a table to slow down its growth.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddSlowTableGrowth( + DdManager *unique) +{ + int i; + + unique->maxCacheHard = unique->cacheSlots - 1; + unique->cacheSlack = - (int) (unique->cacheSlots + 1); + for (i = 0; i < unique->size; i++) { + unique->subtables[i].maxKeys <<= 2; + } + unique->gcFrac = DD_GC_FRAC_MIN; + unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots); + cuddShrinkDeathRow(unique); + (void) fprintf(unique->err,"Slowing down table growth: "); + (void) fprintf(unique->err,"GC fraction = %.2f\t", unique->gcFrac); + (void) fprintf(unique->err,"minDead = %u\n", unique->minDead); + +} /* end of cuddSlowTableGrowth */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Rehashes a ZDD unique subtable.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddRehash] + +******************************************************************************/ +static void +ddRehashZdd( + DdManager * unique, + int i) +{ + unsigned int slots, oldslots; + int shift, oldshift; + int j, pos; + DdNodePtr *nodelist, *oldnodelist; + DdNode *node, *next; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (unique->slots > unique->looseUpTo) { + unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); +#ifdef DD_VERBOSE + if (unique->gcFrac == DD_GC_FRAC_HI) { + (void) fprintf(unique->err,"GC fraction = %.2f\t", + DD_GC_FRAC_LO); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); + } +#endif + unique->gcFrac = DD_GC_FRAC_LO; + } + + assert(i != CUDD_MAXINDEX); + oldslots = unique->subtableZ[i].slots; + oldshift = unique->subtableZ[i].shift; + oldnodelist = unique->subtableZ[i].nodelist; + + /* Compute the new size of the subtable. Normally, we just + ** double. However, after reordering, a table may be severely + ** overloaded. Therefore, we iterate. */ + slots = oldslots; + shift = oldshift; + do { + slots <<= 1; + shift--; + } while (slots * DD_MAX_SUBTABLE_DENSITY < unique->subtableZ[i].keys); + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + (void) fprintf(unique->err, + "Unable to resize ZDD subtable %d for lack of memory.\n", + i); + (void) cuddGarbageCollect(unique,1); + for (j = 0; j < unique->sizeZ; j++) { + unique->subtableZ[j].maxKeys <<= 1; + } + return; + } + unique->subtableZ[i].nodelist = nodelist; + unique->subtableZ[i].slots = slots; + unique->subtableZ[i].shift = shift; + unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + pos = ddHash(cuddT(node), cuddE(node), shift); + node->next = nodelist[pos]; + nodelist[pos] = node; + node = next; + } + } + FREE(oldnodelist); + +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "rehashing layer %d: keys %d dead %d new size %d\n", + i, unique->subtableZ[i].keys, + unique->subtableZ[i].dead, slots); +#endif + + /* Update global data. */ + unique->memused += (slots - oldslots) * sizeof(DdNode *); + unique->slots += (slots - oldslots); + ddFixLimits(unique); + +} /* end of ddRehashZdd */ + + +/**Function******************************************************************** + + Synopsis [Increases the number of subtables in a unique table so + that it meets or exceeds index.] + + Description [Increases the number of subtables in a unique table so + that it meets or exceeds index. The parameter amount determines how + much spare space is allocated to prevent too frequent resizing. If + index is negative, the table is resized, but no new variables are + created. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Reserve cuddResizeTableZdd] + +******************************************************************************/ +static int +ddResizeTable( + DdManager * unique, + int index, + int amount) +{ + DdSubtable *newsubtables; + DdNodePtr *newnodelist; + DdNodePtr *newvars; + DdNode *sentinel = &(unique->sentinel); + int oldsize,newsize; + int i,j,reorderSave; + int numSlots = unique->initSlots; + int *newperm, *newinvperm, *newmap; + DdNode *one, *zero; + + oldsize = unique->size; + /* Easy case: there is still room in the current table. */ + if (index >= 0 && index < unique->maxSize) { + for (i = oldsize; i <= index; i++) { + unique->subtables[i].slots = numSlots; + unique->subtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtables[i].keys = 0; + unique->subtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[i].dead = 0; + unique->subtables[i].bindVar = 0; + unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[i].pairIndex = 0; + unique->subtables[i].varHandled = 0; + unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + unique->perm[i] = i; + unique->invperm[i] = i; + newnodelist = unique->subtables[i].nodelist = + ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + for (j = oldsize; j < i; j++) { + FREE(unique->subtables[j].nodelist); + } + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + if (unique->map != NULL) { + for (i = oldsize; i <= index; i++) { + unique->map[i] = i; + } + } + } else { + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables up to index included. + */ + newsize = (index < 0) ? amount : index + amount; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "Increasing the table size from %d to %d\n", + unique->maxSize, newsize); +#endif + newsubtables = ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newvars = ALLOC(DdNodePtr,newsize); + if (newvars == NULL) { + FREE(newsubtables); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newperm = ALLOC(int,newsize); + if (newperm == NULL) { + FREE(newsubtables); + FREE(newvars); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newinvperm = ALLOC(int,newsize); + if (newinvperm == NULL) { + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + if (unique->map != NULL) { + newmap = ALLOC(int,newsize); + if (newmap == NULL) { + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + FREE(newinvperm); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->memused += (newsize - unique->maxSize) * sizeof(int); + } + unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + if (newsize > unique->maxSizeZ) { + FREE(unique->stack); + unique->stack = ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + FREE(newinvperm); + if (unique->map != NULL) { + FREE(newmap); + } + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); + } + for (i = 0; i < oldsize; i++) { + newsubtables[i].slots = unique->subtables[i].slots; + newsubtables[i].shift = unique->subtables[i].shift; + newsubtables[i].keys = unique->subtables[i].keys; + newsubtables[i].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i].dead = unique->subtables[i].dead; + newsubtables[i].nodelist = unique->subtables[i].nodelist; + newsubtables[i].bindVar = unique->subtables[i].bindVar; + newsubtables[i].varType = unique->subtables[i].varType; + newsubtables[i].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i].varHandled = unique->subtables[i].varHandled; + newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + newperm[i] = unique->perm[i]; + newinvperm[i] = unique->invperm[i]; + } + for (i = oldsize; i <= index; i++) { + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newsubtables[i].bindVar = 0; + newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + newsubtables[i].pairIndex = 0; + newsubtables[i].varHandled = 0; + newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + newperm[i] = i; + newinvperm[i] = i; + newnodelist = newsubtables[i].nodelist = ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + if (unique->map != NULL) { + for (i = 0; i < oldsize; i++) { + newmap[i] = unique->map[i]; + } + for (i = oldsize; i <= index; i++) { + newmap[i] = i; + } + FREE(unique->map); + unique->map = newmap; + } + FREE(unique->subtables); + unique->subtables = newsubtables; + unique->maxSize = newsize; + FREE(unique->vars); + unique->vars = newvars; + FREE(unique->perm); + unique->perm = newperm; + FREE(unique->invperm); + unique->invperm = newinvperm; + } + + /* Now that the table is in a coherent state, create the new + ** projection functions. We need to temporarily disable reordering, + ** because we cannot reorder without projection functions in place. + **/ + if (index >= 0) { + one = unique->one; + zero = Cudd_Not(one); + + unique->size = index + 1; + if (unique->tree != NULL) { + unique->tree->size = ddMax(unique->tree->size, unique->size); + } + unique->slots += (index + 1 - oldsize) * numSlots; + ddFixLimits(unique); + + reorderSave = unique->autoDyn; + unique->autoDyn = 0; + for (i = oldsize; i <= index; i++) { + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) { + unique->autoDyn = reorderSave; + for (j = oldsize; j < i; j++) { + Cudd_IterDerefBdd(unique,unique->vars[j]); + cuddDeallocNode(unique,unique->vars[j]); + unique->vars[j] = NULL; + } + for (j = oldsize; j <= index; j++) { + FREE(unique->subtables[j].nodelist); + unique->subtables[j].nodelist = NULL; + } + unique->size = oldsize; + unique->slots -= (index + 1 - oldsize) * numSlots; + ddFixLimits(unique); + return(0); + } + cuddRef(unique->vars[i]); + } + unique->autoDyn = reorderSave; + } + + return(1); + +} /* end of ddResizeTable */ + + +/**Function******************************************************************** + + Synopsis [Searches the subtables above node for a parent.] + + Description [Searches the subtables above node for a parent. Returns 1 + as soon as one parent is found. Returns 0 is the search is fruitless.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddFindParent( + DdManager * table, + DdNode * node) +{ + int i,j; + int slots; + DdNodePtr *nodelist; + DdNode *f; + + for (i = cuddI(table,node->index) - 1; i >= 0; i--) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (cuddT(f) > node) { + f = f->next; + } + while (cuddT(f) == node && Cudd_Regular(cuddE(f)) > node) { + f = f->next; + } + if (cuddT(f) == node && Cudd_Regular(cuddE(f)) == node) { + return(1); + } + } + } + + return(0); + +} /* end of cuddFindParent */ + + +/**Function******************************************************************** + + Synopsis [Adjusts the values of table limits.] + + Description [Adjusts the values of table fields controlling the. + sizes of subtables and computed table. If the computed table is too small + according to the new values, it is resized.] + + SideEffects [Modifies manager fields. May resize computed table.] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static void +ddFixLimits( + DdManager *unique) +{ + unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); + unique->cacheSlack = (int) ddMin(unique->maxCacheHard, + DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) - + 2 * (int) unique->cacheSlots; + if (unique->cacheSlots < unique->slots/2 && unique->cacheSlack >= 0) + cuddCacheResize(unique); + return; + +} /* end of ddFixLimits */ + + +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST +/**Function******************************************************************** + + Synopsis [Inserts a DdNode in a red/black search tree.] + + Description [Inserts a DdNode in a red/black search tree. Nodes from + the same "page" (defined by DD_PAGE_MASK) are linked in a LIFO list.] + + SideEffects [None] + + SeeAlso [cuddOrderedThread] + +******************************************************************************/ +static void +cuddOrderedInsert( + DdNodePtr * root, + DdNodePtr node) +{ + DdNode *scan; + DdNodePtr *scanP; + DdNodePtr *stack[DD_STACK_SIZE]; + int stackN = 0; + + scanP = root; + while ((scan = *scanP) != NULL) { + stack[stackN++] = scanP; + if (DD_INSERT_COMPARE(node, scan) == 0) { /* add to page list */ + DD_NEXT(node) = DD_NEXT(scan); + DD_NEXT(scan) = node; + return; + } + scanP = (node < scan) ? &DD_LEFT(scan) : &DD_RIGHT(scan); + } + DD_RIGHT(node) = DD_LEFT(node) = DD_NEXT(node) = NULL; + DD_COLOR(node) = DD_RED; + *scanP = node; + stack[stackN] = &node; + cuddDoRebalance(stack,stackN); + +} /* end of cuddOrderedInsert */ + + +/**Function******************************************************************** + + Synopsis [Threads all the nodes of a search tree into a linear list.] + + Description [Threads all the nodes of a search tree into a linear + list. For each node of the search tree, the "left" child, if non-null, has + a lower address than its parent, and the "right" child, if non-null, has a + higher address than its parent. + The list is sorted in order of increasing addresses. The search + tree is destroyed as a result of this operation. The last element of + the linear list is made to point to the address passed in list. Each + node if the search tree is a linearly-linked list of nodes from the + same memory page (as defined in DD_PAGE_MASK). When a node is added to + the linear list, all the elements of the linked list are added.] + + SideEffects [The search tree is destroyed as a result of this operation.] + + SeeAlso [cuddOrderedInsert] + +******************************************************************************/ +static DdNode * +cuddOrderedThread( + DdNode * root, + DdNode * list) +{ + DdNode *current, *next, *prev, *end; + + current = root; + /* The first word in the node is used to implement a stack that holds + ** the nodes from the root of the tree to the current node. Here we + ** put the root of the tree at the bottom of the stack. + */ + *((DdNodePtr *) current) = NULL; + + while (current != NULL) { + if (DD_RIGHT(current) != NULL) { + /* If possible, we follow the "right" link. Eventually we'll + ** find the node with the largest address in the current tree. + ** In this phase we use the first word of a node to implemen + ** a stack of the nodes on the path from the root to "current". + ** Also, we disconnect the "right" pointers to indicate that + ** we have already followed them. + */ + next = DD_RIGHT(current); + DD_RIGHT(current) = NULL; + *((DdNodePtr *)next) = current; + current = next; + } else { + /* We can't proceed along the "right" links any further. + ** Hence "current" is the largest element in the current tree. + ** We make this node the new head of "list". (Repeating this + ** operation until the tree is empty yields the desired linear + ** threading of all nodes.) + */ + prev = *((DdNodePtr *) current); /* save prev node on stack in prev */ + /* Traverse the linked list of current until the end. */ + for (end = current; DD_NEXT(end) != NULL; end = DD_NEXT(end)); + DD_NEXT(end) = list; /* attach "list" at end and make */ + list = current; /* "current" the new head of "list" */ + /* Now, if current has a "left" child, we push it on the stack. + ** Otherwise, we just continue with the parent of "current". + */ + if (DD_LEFT(current) != NULL) { + next = DD_LEFT(current); + *((DdNodePtr *) next) = prev; + current = next; + } else { + current = prev; + } + } + } + + return(list); + +} /* end of cuddOrderedThread */ + + +/**Function******************************************************************** + + Synopsis [Performs the left rotation for red/black trees.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddRotateRight] + +******************************************************************************/ +DD_INLINE +static void +cuddRotateLeft( + DdNodePtr * nodeP) +{ + DdNode *newRoot; + DdNode *oldRoot = *nodeP; + + *nodeP = newRoot = DD_RIGHT(oldRoot); + DD_RIGHT(oldRoot) = DD_LEFT(newRoot); + DD_LEFT(newRoot) = oldRoot; + +} /* end of cuddRotateLeft */ + + +/**Function******************************************************************** + + Synopsis [Performs the right rotation for red/black trees.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddRotateLeft] + +******************************************************************************/ +DD_INLINE +static void +cuddRotateRight( + DdNodePtr * nodeP) +{ + DdNode *newRoot; + DdNode *oldRoot = *nodeP; + + *nodeP = newRoot = DD_LEFT(oldRoot); + DD_LEFT(oldRoot) = DD_RIGHT(newRoot); + DD_RIGHT(newRoot) = oldRoot; + +} /* end of cuddRotateRight */ + + +/**Function******************************************************************** + + Synopsis [Rebalances a red/black tree.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +cuddDoRebalance( + DdNodePtr ** stack, + int stackN) +{ + DdNodePtr *xP, *parentP, *grandpaP; + DdNode *x, *y, *parent, *grandpa; + + xP = stack[stackN]; + x = *xP; + /* Work our way back up, re-balancing the tree. */ + while (--stackN >= 0) { + parentP = stack[stackN]; + parent = *parentP; + if (DD_IS_BLACK(parent)) break; + /* Since the root is black, here a non-null grandparent exists. */ + grandpaP = stack[stackN-1]; + grandpa = *grandpaP; + if (parent == DD_LEFT(grandpa)) { + y = DD_RIGHT(grandpa); + if (y != NULL && DD_IS_RED(y)) { + DD_COLOR(parent) = DD_BLACK; + DD_COLOR(y) = DD_BLACK; + DD_COLOR(grandpa) = DD_RED; + x = grandpa; + stackN--; + } else { + if (x == DD_RIGHT(parent)) { + cuddRotateLeft(parentP); + DD_COLOR(x) = DD_BLACK; + } else { + DD_COLOR(parent) = DD_BLACK; + } + DD_COLOR(grandpa) = DD_RED; + cuddRotateRight(grandpaP); + break; + } + } else { + y = DD_LEFT(grandpa); + if (y != NULL && DD_IS_RED(y)) { + DD_COLOR(parent) = DD_BLACK; + DD_COLOR(y) = DD_BLACK; + DD_COLOR(grandpa) = DD_RED; + x = grandpa; + stackN--; + } else { + if (x == DD_LEFT(parent)) { + cuddRotateRight(parentP); + DD_COLOR(x) = DD_BLACK; + } else { + DD_COLOR(parent) = DD_BLACK; + } + DD_COLOR(grandpa) = DD_RED; + cuddRotateLeft(grandpaP); + } + } + } + DD_COLOR(*(stack[0])) = DD_BLACK; + +} /* end of cuddDoRebalance */ +#endif +#endif + + +/**Function******************************************************************** + + Synopsis [Fixes a variable tree after the insertion of new subtables.] + + Description [Fixes a variable tree after the insertion of new subtables. + After such an insertion, the low fields of the tree below the insertion + point are inconsistent.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ddPatchTree( + DdManager *dd, + MtrNode *treenode) +{ + MtrNode *auxnode = treenode; + + while (auxnode != NULL) { + auxnode->low = dd->perm[auxnode->index]; + if (auxnode->child != NULL) { + ddPatchTree(dd, auxnode->child); + } + auxnode = auxnode->younger; + } + + return; + +} /* end of ddPatchTree */ + + +#ifdef DD_DEBUG +/**Function******************************************************************** + + Synopsis [Checks whether a collision list is ordered.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddCheckCollisionOrdering( + DdManager *unique, + int i, + int j) +{ + int slots; + DdNode *node, *next; + DdNodePtr *nodelist; + DdNode *sentinel = &(unique->sentinel); + + nodelist = unique->subtables[i].nodelist; + slots = unique->subtables[i].slots; + node = nodelist[j]; + if (node == sentinel) return(1); + next = node->next; + while (next != sentinel) { + if (cuddT(node) < cuddT(next) || + (cuddT(node) == cuddT(next) && cuddE(node) < cuddE(next))) { + (void) fprintf(unique->err, + "Unordered list: index %u, position %d\n", i, j); + return(0); + } + node = next; + next = node->next; + } + return(1); + +} /* end of cuddCheckCollisionOrdering */ +#endif + + + + +/**Function******************************************************************** + + Synopsis [Reports problem in garbage collection.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddGarbageCollect cuddGarbageCollectZdd] + +******************************************************************************/ +static void +ddReportRefMess( + DdManager *unique /* manager */, + int i /* table in which the problem occurred */, + const char *caller /* procedure that detected the problem */) +{ + if (i == CUDD_CONST_INDEX) { + (void) fprintf(unique->err, + "%s: problem in constants\n", caller); + } else if (i != -1) { + (void) fprintf(unique->err, + "%s: problem in table %d\n", caller, i); + } + (void) fprintf(unique->err, " dead count != deleted\n"); + (void) fprintf(unique->err, " This problem is often due to a missing \ +call to Cudd_Ref\n or to an extra call to Cudd_RecursiveDeref.\n \ +See the CUDD Programmer's Guide for additional details."); + abort(); + +} /* end of ddReportRefMess */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddUtil.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddUtil.c new file mode 100644 index 000000000..1a1a47a03 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddUtil.c @@ -0,0 +1,4032 @@ +/**CFile*********************************************************************** + + FileName [cuddUtil.c] + + PackageName [cudd] + + Synopsis [Utility functions.] + + Description [External procedures included in this module: +
          +
        • Cudd_PrintMinterm() +
        • Cudd_bddPrintCover() +
        • Cudd_PrintDebug() +
        • Cudd_DagSize() +
        • Cudd_EstimateCofactor() +
        • Cudd_EstimateCofactorSimple() +
        • Cudd_SharingSize() +
        • Cudd_CountMinterm() +
        • Cudd_EpdCountMinterm() +
        • Cudd_CountPath() +
        • Cudd_CountPathsToNonZero() +
        • Cudd_SupportIndices() +
        • Cudd_Support() +
        • Cudd_SupportIndex() +
        • Cudd_SupportSize() +
        • Cudd_VectorSupportIndices() +
        • Cudd_VectorSupport() +
        • Cudd_VectorSupportIndex() +
        • Cudd_VectorSupportSize() +
        • Cudd_ClassifySupport() +
        • Cudd_CountLeaves() +
        • Cudd_bddPickOneCube() +
        • Cudd_bddPickOneMinterm() +
        • Cudd_bddPickArbitraryMinterms() +
        • Cudd_SubsetWithMaskVars() +
        • Cudd_FirstCube() +
        • Cudd_NextCube() +
        • Cudd_bddComputeCube() +
        • Cudd_addComputeCube() +
        • Cudd_FirstNode() +
        • Cudd_NextNode() +
        • Cudd_GenFree() +
        • Cudd_IsGenEmpty() +
        • Cudd_IndicesToCube() +
        • Cudd_PrintVersion() +
        • Cudd_AverageDistance() +
        • Cudd_Random() +
        • Cudd_Srandom() +
        • Cudd_Density() +
        + Internal procedures included in this module: +
          +
        • cuddP() +
        • cuddStCountfree() +
        • cuddCollectNodes() +
        • cuddNodeArray() +
        + Static procedures included in this module: +
          +
        • dp2() +
        • ddPrintMintermAux() +
        • ddDagInt() +
        • ddCountMintermAux() +
        • ddEpdCountMintermAux() +
        • ddCountPathAux() +
        • ddSupportStep() +
        • ddClearFlag() +
        • ddLeavesInt() +
        • ddPickArbitraryMinterms() +
        • ddPickRepresentativeCube() +
        • ddEpdFree() +
        • ddFindSupport() +
        • ddClearVars() +
        • indexCompare() +
        ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Random generator constants. */ +#define MODULUS1 2147483563 +#define LEQA1 40014 +#define LEQQ1 53668 +#define LEQR1 12211 +#define MODULUS2 2147483399 +#define LEQA2 40692 +#define LEQQ2 52774 +#define LEQR2 3791 +#define STAB_SIZE 64 +#define STAB_DIV (1 + (MODULUS1 - 1) / STAB_SIZE) + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddUtil.c,v 1.83 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static DdNode *background, *zero; + +static long cuddRand = 0; +static long cuddRand2; +static long shuffleSelect; +static long shuffleTable[STAB_SIZE]; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define bang(f) ((Cudd_IsComplement(f)) ? '!' : ' ') + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int dp2 (DdManager *dd, DdNode *f, st_table *t); +static void ddPrintMintermAux (DdManager *dd, DdNode *node, int *list); +static int ddDagInt (DdNode *n); +static int cuddNodeArrayRecur (DdNode *f, DdNodePtr *table, int index); +static int cuddEstimateCofactor (DdManager *dd, st_table *table, DdNode * node, int i, int phase, DdNode ** ptr); +static DdNode * cuddUniqueLookup (DdManager * unique, int index, DdNode * T, DdNode * E); +static int cuddEstimateCofactorSimple (DdNode * node, int i); +static double ddCountMintermAux (DdNode *node, double max, DdHashTable *table); +static int ddEpdCountMintermAux (DdNode *node, EpDouble *max, EpDouble *epd, st_table *table); +static double ddCountPathAux (DdNode *node, st_table *table); +static double ddCountPathsToNonZero (DdNode * N, st_table * table); +static void ddSupportStep (DdNode *f, int *support); +static void ddClearFlag (DdNode *f); +static int ddLeavesInt (DdNode *n); +static int ddPickArbitraryMinterms (DdManager *dd, DdNode *node, int nvars, int nminterms, char **string); +static int ddPickRepresentativeCube (DdManager *dd, DdNode *node, double *weight, char *string); +static enum st_retval ddEpdFree (char * key, char * value, char * arg); +static void ddFindSupport(DdManager *dd, DdNode *f, int *SP); +static void ddClearVars(DdManager *dd, int SP); +static int indexCompare(const void *a, const void *b); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints a disjoint sum of products.] + + Description [Prints a disjoint sum of product cover for the function + rooted at node. Each product corresponds to a path from node to a + leaf node different from the logical zero, and different from the + background value. Uses the package default output file. Returns 1 + if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug Cudd_bddPrintCover] + +******************************************************************************/ +int +Cudd_PrintMinterm( + DdManager * manager, + DdNode * node) +{ + int i, *list; + + background = manager->background; + zero = Cudd_Not(manager->one); + list = ALLOC(int,manager->size); + if (list == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < manager->size; i++) list[i] = 2; + ddPrintMintermAux(manager,node,list); + FREE(list); + return(1); + +} /* end of Cudd_PrintMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints a sum of prime implicants of a BDD.] + + Description [Prints a sum of product cover for an incompletely + specified function given by a lower bound and an upper bound. Each + product is a prime implicant obtained by expanding the product + corresponding to a path from node to the constant one. Uses the + package default output file. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintMinterm] + +******************************************************************************/ +int +Cudd_bddPrintCover( + DdManager *dd, + DdNode *l, + DdNode *u) +{ + int *array; + int q, result; + DdNode *lb; +#ifdef DD_DEBUG + DdNode *cover; +#endif + + array = ALLOC(int, Cudd_ReadSize(dd)); + if (array == NULL) return(0); + lb = l; + cuddRef(lb); +#ifdef DD_DEBUG + cover = Cudd_ReadLogicZero(dd); + cuddRef(cover); +#endif + while (lb != Cudd_ReadLogicZero(dd)) { + DdNode *implicant, *prime, *tmp; + int length; + implicant = Cudd_LargestCube(dd,lb,&length); + if (implicant == NULL) { + Cudd_RecursiveDeref(dd,lb); + FREE(array); + return(0); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,u); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,implicant); + FREE(array); + return(0); + } + cuddRef(prime); + Cudd_RecursiveDeref(dd,implicant); + tmp = Cudd_bddAnd(dd,lb,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + FREE(array); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,lb); + lb = tmp; + result = Cudd_BddToCubeArray(dd,prime,array); + if (result == 0) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + FREE(array); + return(0); + } + for (q = 0; q < dd->size; q++) { + switch (array[q]) { + case 0: + (void) fprintf(dd->out, "0"); + break; + case 1: + (void) fprintf(dd->out, "1"); + break; + case 2: + (void) fprintf(dd->out, "-"); + break; + default: + (void) fprintf(dd->out, "?"); + } + } + (void) fprintf(dd->out, " 1\n"); +#ifdef DD_DEBUG + tmp = Cudd_bddOr(dd,prime,cover); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cover); + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + FREE(array); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cover); + cover = tmp; +#endif + Cudd_RecursiveDeref(dd,prime); + } + (void) fprintf(dd->out, "\n"); + Cudd_RecursiveDeref(dd,lb); + FREE(array); +#ifdef DD_DEBUG + if (!Cudd_bddLeq(dd,cover,u) || !Cudd_bddLeq(dd,l,cover)) { + Cudd_RecursiveDeref(dd,cover); + return(0); + } + Cudd_RecursiveDeref(dd,cover); +#endif + return(1); + +} /* end of Cudd_bddPrintCover */ + + +/**Function******************************************************************** + + Synopsis [Prints to the standard output a DD and its statistics.] + + Description [Prints to the standard output a DD and its statistics. + The statistics include the number of nodes, the number of leaves, and + the number of minterms. (The number of minterms is the number of + assignments to the variables that cause the function to be different + from the logical zero (for BDDs) and from the background value (for + ADDs.) The statistics are printed if pr > 0. Specifically: +
          +
        • pr = 0 : prints nothing +
        • pr = 1 : prints counts of nodes and minterms +
        • pr = 2 : prints counts + disjoint sum of product +
        • pr = 3 : prints counts + list of nodes +
        • pr > 3 : prints counts + disjoint sum of product + list of nodes +
        + For the purpose of counting the number of minterms, the function is + supposed to depend on n variables. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize Cudd_CountLeaves Cudd_CountMinterm + Cudd_PrintMinterm] + +******************************************************************************/ +int +Cudd_PrintDebug( + DdManager * dd, + DdNode * f, + int n, + int pr) +{ + DdNode *azero, *bzero; + int nodes; + int leaves; + double minterms; + int retval = 1; + + if (f == NULL) { + (void) fprintf(dd->out,": is the NULL DD\n"); + (void) fflush(dd->out); + return(0); + } + azero = DD_ZERO(dd); + bzero = Cudd_Not(DD_ONE(dd)); + if ((f == azero || f == bzero) && pr > 0){ + (void) fprintf(dd->out,": is the zero DD\n"); + (void) fflush(dd->out); + return(1); + } + if (pr > 0) { + nodes = Cudd_DagSize(f); + if (nodes == CUDD_OUT_OF_MEM) retval = 0; + leaves = Cudd_CountLeaves(f); + if (leaves == CUDD_OUT_OF_MEM) retval = 0; + minterms = Cudd_CountMinterm(dd, f, n); + if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; + (void) fprintf(dd->out,": %d nodes %d leaves %g minterms\n", + nodes, leaves, minterms); + if (pr > 2) { + if (!cuddP(dd, f)) retval = 0; + } + if (pr == 2 || pr > 3) { + if (!Cudd_PrintMinterm(dd,f)) retval = 0; + (void) fprintf(dd->out,"\n"); + } + (void) fflush(dd->out); + } + return(retval); + +} /* end of Cudd_PrintDebug */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of nodes in a DD.] + + Description [Counts the number of nodes in a DD. Returns the number + of nodes in the graph rooted at node.] + + SideEffects [None] + + SeeAlso [Cudd_SharingSize Cudd_PrintDebug] + +******************************************************************************/ +int +Cudd_DagSize( + DdNode * node) +{ + int i; + + i = ddDagInt(Cudd_Regular(node)); + ddClearFlag(Cudd_Regular(node)); + + return(i); + +} /* end of Cudd_DagSize */ + + +/**Function******************************************************************** + + Synopsis [Estimates the number of nodes in a cofactor of a DD.] + + Description [Estimates the number of nodes in a cofactor of a DD. + Returns an estimate of the number of nodes in a cofactor of + the graph rooted at node with respect to the variable whose index is i. + In case of failure, returns CUDD_OUT_OF_MEM. + This function uses a refinement of the algorithm of Cabodi et al. + (ICCAD96). The refinement allows the procedure to account for part + of the recombination that may occur in the part of the cofactor above + the cofactoring variable. This procedure does not create any new node. + It does keep a small table of results; therefore it may run out of memory. + If this is a concern, one should use Cudd_EstimateCofactorSimple, which + is faster, does not allocate any memory, but is less accurate.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize Cudd_EstimateCofactorSimple] + +******************************************************************************/ +int +Cudd_EstimateCofactor( + DdManager *dd /* manager */, + DdNode * f /* function */, + int i /* index of variable */, + int phase /* 1: positive; 0: negative */ + ) +{ + int val; + DdNode *ptr; + st_table *table; + + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) return(CUDD_OUT_OF_MEM); + val = cuddEstimateCofactor(dd,table,Cudd_Regular(f),i,phase,&ptr); + ddClearFlag(Cudd_Regular(f)); + st_free_table(table); + + return(val); + +} /* end of Cudd_EstimateCofactor */ + + +/**Function******************************************************************** + + Synopsis [Estimates the number of nodes in a cofactor of a DD.] + + Description [Estimates the number of nodes in a cofactor of a DD. + Returns an estimate of the number of nodes in the positive cofactor of + the graph rooted at node with respect to the variable whose index is i. + This procedure implements with minor changes the algorithm of Cabodi et al. + (ICCAD96). It does not allocate any memory, it does not change the + state of the manager, and it is fast. However, it has been observed to + overestimate the size of the cofactor by as much as a factor of 2.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize] + +******************************************************************************/ +int +Cudd_EstimateCofactorSimple( + DdNode * node, + int i) +{ + int val; + + val = cuddEstimateCofactorSimple(Cudd_Regular(node),i); + ddClearFlag(Cudd_Regular(node)); + + return(val); + +} /* end of Cudd_EstimateCofactorSimple */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of nodes in an array of DDs.] + + Description [Counts the number of nodes in an array of DDs. Shared + nodes are counted only once. Returns the total number of nodes.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize] + +******************************************************************************/ +int +Cudd_SharingSize( + DdNode ** nodeArray, + int n) +{ + int i,j; + + i = 0; + for (j = 0; j < n; j++) { + i += ddDagInt(Cudd_Regular(nodeArray[j])); + } + for (j = 0; j < n; j++) { + ddClearFlag(Cudd_Regular(nodeArray[j])); + } + return(i); + +} /* end of Cudd_SharingSize */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a DD.] + + Description [Counts the number of minterms of a DD. The function is + assumed to depend on nvars variables. The minterm count is + represented as a double, to allow for a larger number of variables. + Returns the number of minterms of the function rooted at node if + successful; (double) CUDD_OUT_OF_MEM otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug Cudd_CountPath] + +******************************************************************************/ +double +Cudd_CountMinterm( + DdManager * manager, + DdNode * node, + int nvars) +{ + double max; + DdHashTable *table; + double res; + CUDD_VALUE_TYPE epsilon; + + background = manager->background; + zero = Cudd_Not(manager->one); + + max = pow(2.0,(double)nvars); + table = cuddHashTableInit(manager,1,2); + if (table == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + epsilon = Cudd_ReadEpsilon(manager); + Cudd_SetEpsilon(manager,(CUDD_VALUE_TYPE)0.0); + res = ddCountMintermAux(node,max,table); + cuddHashTableQuit(table); + Cudd_SetEpsilon(manager,epsilon); + + return(res); + +} /* end of Cudd_CountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of paths of a DD.] + + Description [Counts the number of paths of a DD. Paths to all + terminal nodes are counted. The path count is represented as a + double, to allow for a larger number of variables. Returns the + number of paths of the function rooted at node if successful; + (double) CUDD_OUT_OF_MEM otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_CountMinterm] + +******************************************************************************/ +double +Cudd_CountPath( + DdNode * node) +{ + + st_table *table; + double i; + + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + i = ddCountPathAux(Cudd_Regular(node),table); + st_foreach(table, cuddStCountfree, NULL); + st_free_table(table); + return(i); + +} /* end of Cudd_CountPath */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a DD with extended precision.] + + Description [Counts the number of minterms of a DD with extended precision. + The function is assumed to depend on nvars variables. The minterm count is + represented as an EpDouble, to allow any number of variables. + Returns 0 if successful; CUDD_OUT_OF_MEM otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug Cudd_CountPath] + +******************************************************************************/ +int +Cudd_EpdCountMinterm( + DdManager * manager, + DdNode * node, + int nvars, + EpDouble * epd) +{ + EpDouble max, tmp; + st_table *table; + int status; + + background = manager->background; + zero = Cudd_Not(manager->one); + + EpdPow2(nvars, &max); + table = st_init_table(EpdCmp, st_ptrhash); + if (table == NULL) { + EpdMakeZero(epd, 0); + return(CUDD_OUT_OF_MEM); + } + status = ddEpdCountMintermAux(Cudd_Regular(node),&max,epd,table); + st_foreach(table, ddEpdFree, NULL); + st_free_table(table); + if (status == CUDD_OUT_OF_MEM) { + EpdMakeZero(epd, 0); + return(CUDD_OUT_OF_MEM); + } + if (Cudd_IsComplement(node)) { + EpdSubtract3(&max, epd, &tmp); + EpdCopy(&tmp, epd); + } + return(0); + +} /* end of Cudd_EpdCountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of paths to a non-zero terminal of a DD.] + + Description [Counts the number of paths to a non-zero terminal of a + DD. The path count is + represented as a double, to allow for a larger number of variables. + Returns the number of paths of the function rooted at node.] + + SideEffects [None] + + SeeAlso [Cudd_CountMinterm Cudd_CountPath] + +******************************************************************************/ +double +Cudd_CountPathsToNonZero( + DdNode * node) +{ + + st_table *table; + double i; + + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + i = ddCountPathsToNonZero(node,table); + st_foreach(table, cuddStCountfree, NULL); + st_free_table(table); + return(i); + +} /* end of Cudd_CountPathsToNonZero */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a DD depends.] + + Description [Finds the variables on which a DD depends. Returns the + number of variables if successful; CUDD_OUT_OF_MEM otherwise.] + + SideEffects [The indices of the support variables are returned as + side effects. If the function is constant, no array is allocated.] + + SeeAlso [Cudd_Support Cudd_SupportIndex Cudd_VectorSupportIndices] + +******************************************************************************/ +int +Cudd_SupportIndices( + DdManager * dd /* manager */, + DdNode * f /* DD whose support is sought */, + int **indices /* array containing (on return) the indices */) +{ + int SP = 0; + + ddFindSupport(dd, Cudd_Regular(f), &SP); + ddClearFlag(Cudd_Regular(f)); + ddClearVars(dd, SP); + if (SP > 0) { + int i; + *indices = ALLOC(int, SP); + if (*indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + + for (i = 0; i < SP; i++) + (*indices)[i] = (int) (ptrint) dd->stack[i]; + + qsort(*indices, SP, sizeof(int), indexCompare); + } else { + *indices = NULL; + } + + return(SP); + +} /* end of Cudd_SupportIndices */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a DD depends.] + + Description [Finds the variables on which a DD depends. + Returns a BDD consisting of the product of the variables if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_VectorSupport Cudd_ClassifySupport] + +******************************************************************************/ +DdNode * +Cudd_Support( + DdManager * dd /* manager */, + DdNode * f /* DD whose support is sought */) +{ + int *support; + DdNode *res; + int j; + + int size = Cudd_SupportIndices(dd, f, &support); + if (size == CUDD_OUT_OF_MEM) + return(NULL); + + /* Transform support from array of indices to cube. */ + res = DD_ONE(dd); + cuddRef(res); + + for (j = size - 1; j >= 0; j--) { /* for each index bottom-up (almost) */ + int index = support[j]; + DdNode *var = dd->vars[index]; + DdNode *tmp = Cudd_bddAnd(dd,res,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,res); + FREE(support); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,res); + res = tmp; + } + + FREE(support); + cuddDeref(res); + return(res); + +} /* end of Cudd_Support */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a DD depends.] + + Description [Finds the variables on which a DD depends. Returns an + index array of the variables if successful; NULL otherwise. The + size of the array equals the number of variables in the manager. + Each entry of the array is 1 if the corresponding variable is in the + support of the DD and 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Support Cudd_SupportIndices Cudd_ClassifySupport] + +******************************************************************************/ +int * +Cudd_SupportIndex( + DdManager * dd /* manager */, + DdNode * f /* DD whose support is sought */) +{ + int *support; + int i; + int size; + + /* Allocate and initialize support array for ddSupportStep. */ + size = ddMax(dd->size, dd->sizeZ); + support = ALLOC(int,size); + if (support == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + support[i] = 0; + } + + /* Compute support and clean up markers. */ + ddSupportStep(Cudd_Regular(f),support); + ddClearFlag(Cudd_Regular(f)); + + return(support); + +} /* end of Cudd_SupportIndex */ + + +/**Function******************************************************************** + + Synopsis [Counts the variables on which a DD depends.] + + Description [Returns the variables on which a DD depends.] + + SideEffects [None] + + SeeAlso [Cudd_Support Cudd_SupportIndices] + +******************************************************************************/ +int +Cudd_SupportSize( + DdManager * dd /* manager */, + DdNode * f /* DD whose support size is sought */) +{ + int SP = 0; + + ddFindSupport(dd, Cudd_Regular(f), &SP); + ddClearFlag(Cudd_Regular(f)); + ddClearVars(dd, SP); + + return(SP); + +} /* end of Cudd_SupportSize */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a set of DDs depends.] + + Description [Finds the variables on which a set of DDs depends. The + set must contain either BDDs and ADDs, or ZDDs. Returns the number + of variables if successful; CUDD_OUT_OF_MEM otherwise.] + + SideEffects [The indices of the support variables are returned as + side effects. If the function is constant, no array is allocated.] + + SeeAlso [Cudd_Support Cudd_SupportIndex Cudd_VectorSupportIndices] + +******************************************************************************/ +int +Cudd_VectorSupportIndices( + DdManager * dd /* manager */, + DdNode ** F /* DD whose support is sought */, + int n /* size of the array */, + int **indices /* array containing (on return) the indices */) +{ + int i; + int SP = 0; + + /* Compute support and clean up markers. */ + for (i = 0; i < n; i++) { + ddFindSupport(dd, Cudd_Regular(F[i]), &SP); + } + for (i = 0; i < n; i++) { + ddClearFlag(Cudd_Regular(F[i])); + } + ddClearVars(dd, SP); + + if (SP > 0) { + int i; + *indices = ALLOC(int, SP); + if (*indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + + for (i = 0; i < SP; i++) + (*indices)[i] = (int) (ptrint) dd->stack[i]; + + qsort(*indices, SP, sizeof(int), indexCompare); + } else { + *indices = NULL; + } + + return(SP); + +} /* end of Cudd_VectorSupportIndices */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a set of DDs depends.] + + Description [Finds the variables on which a set of DDs depends. + The set must contain either BDDs and ADDs, or ZDDs. + Returns a BDD consisting of the product of the variables if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Support Cudd_ClassifySupport] + +******************************************************************************/ +DdNode * +Cudd_VectorSupport( + DdManager * dd /* manager */, + DdNode ** F /* array of DDs whose support is sought */, + int n /* size of the array */) +{ + int *support; + DdNode *res; + int j; + int size = Cudd_VectorSupportIndices(dd, F, n, &support); + if (size == CUDD_OUT_OF_MEM) + return(NULL); + + /* Transform support from array of indices to cube. */ + res = DD_ONE(dd); + cuddRef(res); + + for (j = size - 1; j >= 0; j--) { /* for each index bottom-up (almost) */ + int index = support[j]; + DdNode *var = dd->vars[index]; + DdNode *tmp = Cudd_bddAnd(dd,res,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,res); + FREE(support); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,res); + res = tmp; + } + + FREE(support); + cuddDeref(res); + return(res); + +} /* end of Cudd_VectorSupport */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a set of DDs depends.] + + Description [Finds the variables on which a set of DDs depends. + The set must contain either BDDs and ADDs, or ZDDs. + Returns an index array of the variables if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_SupportIndex Cudd_VectorSupport Cudd_VectorSupportIndices] + +******************************************************************************/ +int * +Cudd_VectorSupportIndex( + DdManager * dd /* manager */, + DdNode ** F /* array of DDs whose support is sought */, + int n /* size of the array */) +{ + int *support; + int i; + int size; + + /* Allocate and initialize support array for ddSupportStep. */ + size = ddMax(dd->size, dd->sizeZ); + support = ALLOC(int,size); + if (support == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + support[i] = 0; + } + + /* Compute support and clean up markers. */ + for (i = 0; i < n; i++) { + ddSupportStep(Cudd_Regular(F[i]),support); + } + for (i = 0; i < n; i++) { + ddClearFlag(Cudd_Regular(F[i])); + } + + return(support); + +} /* end of Cudd_VectorSupportIndex */ + + +/**Function******************************************************************** + + Synopsis [Counts the variables on which a set of DDs depends.] + + Description [Returns the variables on which a set of DDs depends. + The set must contain either BDDs and ADDs, or ZDDs.] + + SideEffects [None] + + SeeAlso [Cudd_VectorSupport Cudd_SupportSize] + +******************************************************************************/ +int +Cudd_VectorSupportSize( + DdManager * dd /* manager */, + DdNode ** F /* array of DDs whose support is sought */, + int n /* size of the array */) +{ + int i; + int SP = 0; + + /* Compute support and clean up markers. */ + for (i = 0; i < n; i++) { + ddFindSupport(dd, Cudd_Regular(F[i]), &SP); + } + for (i = 0; i < n; i++) { + ddClearFlag(Cudd_Regular(F[i])); + } + ddClearVars(dd, SP); + + return(SP); + +} /* end of Cudd_VectorSupportSize */ + + +/**Function******************************************************************** + + Synopsis [Classifies the variables in the support of two DDs.] + + Description [Classifies the variables in the support of two DDs + f and g, depending on whther they appear + in both DDs, only in f, or only in g. + Returns 1 if successful; 0 otherwise.] + + SideEffects [The cubes of the three classes of variables are + returned as side effects.] + + SeeAlso [Cudd_Support Cudd_VectorSupport] + +******************************************************************************/ +int +Cudd_ClassifySupport( + DdManager * dd /* manager */, + DdNode * f /* first DD */, + DdNode * g /* second DD */, + DdNode ** common /* cube of shared variables */, + DdNode ** onlyF /* cube of variables only in f */, + DdNode ** onlyG /* cube of variables only in g */) +{ + int *supportF, *supportG; + int fi, gi; + int sizeF, sizeG; + + sizeF = Cudd_SupportIndices(dd, f, &supportF); + if (sizeF == CUDD_OUT_OF_MEM) + return(0); + + sizeG = Cudd_SupportIndices(dd, g, &supportG); + if (sizeG == CUDD_OUT_OF_MEM) { + FREE(supportF); + return(0); + } + + /* Classify variables and create cubes. This part of the procedure + ** relies on the sorting of the indices in the two support arrays. + */ + *common = *onlyF = *onlyG = DD_ONE(dd); + cuddRef(*common); cuddRef(*onlyF); cuddRef(*onlyG); + fi = sizeF - 1; + gi = sizeG - 1; + while (fi >= 0 || gi >= 0) { + int indexF = fi >= 0 ? supportF[fi] : -1; + int indexG = gi >= 0 ? supportG[gi] : -1; + int index = ddMax(indexF, indexG); + DdNode *var = dd->vars[index]; +#ifdef DD_DEBUG + assert(index >= 0); +#endif + if (indexF == indexG) { + DdNode *tmp = Cudd_bddAnd(dd,*common,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + FREE(supportF); FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*common); + *common = tmp; + fi--; + gi--; + } else if (index == indexF) { + DdNode *tmp = Cudd_bddAnd(dd,*onlyF,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + FREE(supportF); FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*onlyF); + *onlyF = tmp; + fi--; + } else { /* index == indexG */ + DdNode *tmp = Cudd_bddAnd(dd,*onlyG,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + FREE(supportF); FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*onlyG); + *onlyG = tmp; + gi--; + } + } + + FREE(supportF); FREE(supportG); + cuddDeref(*common); cuddDeref(*onlyF); cuddDeref(*onlyG); + return(1); + +} /* end of Cudd_ClassifySupport */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of leaves in a DD.] + + Description [Counts the number of leaves in a DD. Returns the number + of leaves in the DD rooted at node if successful; CUDD_OUT_OF_MEM + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug] + +******************************************************************************/ +int +Cudd_CountLeaves( + DdNode * node) +{ + int i; + + i = ddLeavesInt(Cudd_Regular(node)); + ddClearFlag(Cudd_Regular(node)); + return(i); + +} /* end of Cudd_CountLeaves */ + + +/**Function******************************************************************** + + Synopsis [Picks one on-set cube randomly from the given DD.] + + Description [Picks one on-set cube randomly from the given DD. The + cube is written into an array of characters. The array must have at + least as many entries as there are variables. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPickOneMinterm] + +******************************************************************************/ +int +Cudd_bddPickOneCube( + DdManager * ddm, + DdNode * node, + char * string) +{ + DdNode *N, *T, *E; + DdNode *one, *bzero; + char dir; + int i; + + if (string == NULL || node == NULL) return(0); + + /* The constant 0 function has no on-set cubes. */ + one = DD_ONE(ddm); + bzero = Cudd_Not(one); + if (node == bzero) return(0); + + for (i = 0; i < ddm->size; i++) string[i] = 2; + + for (;;) { + + if (node == one) break; + + N = Cudd_Regular(node); + + T = cuddT(N); E = cuddE(N); + if (Cudd_IsComplement(node)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + if (T == bzero) { + string[N->index] = 0; + node = E; + } else if (E == bzero) { + string[N->index] = 1; + node = T; + } else { + dir = (char) ((Cudd_Random() & 0x2000) >> 13); + string[N->index] = dir; + node = dir ? T : E; + } + } + return(1); + +} /* end of Cudd_bddPickOneCube */ + + +/**Function******************************************************************** + + Synopsis [Picks one on-set minterm randomly from the given DD.] + + Description [Picks one on-set minterm randomly from the given + DD. The minterm is in terms of vars. The array + vars should contain at least all variables in the + support of f; if this condition is not met the minterm + built by this procedure may not be contained in + f. Builds a BDD for the minterm and returns a pointer + to it if successful; NULL otherwise. There are three reasons why the + procedure may fail: +
          +
        • It may run out of memory; +
        • the function f may be the constant 0; +
        • the minterm may not be contained in f. +
        ] + + SideEffects [None] + + SeeAlso [Cudd_bddPickOneCube] + +******************************************************************************/ +DdNode * +Cudd_bddPickOneMinterm( + DdManager * dd /* manager */, + DdNode * f /* function from which to pick one minterm */, + DdNode ** vars /* array of variables */, + int n /* size of vars */) +{ + char *string; + int i, size; + int *indices; + int result; + DdNode *old, *neW; + + size = dd->size; + string = ALLOC(char, size); + if (string == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + indices = ALLOC(int,n); + if (indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(string); + return(NULL); + } + + for (i = 0; i < n; i++) { + indices[i] = vars[i]->index; + } + + result = Cudd_bddPickOneCube(dd,f,string); + if (result == 0) { + FREE(string); + FREE(indices); + return(NULL); + } + + /* Randomize choice for don't cares. */ + for (i = 0; i < n; i++) { + if (string[indices[i]] == 2) + string[indices[i]] = (char) ((Cudd_Random() & 0x20) >> 5); + } + + /* Build result BDD. */ + old = Cudd_ReadOne(dd); + cuddRef(old); + + for (i = n-1; i >= 0; i--) { + neW = Cudd_bddAnd(dd,old,Cudd_NotCond(vars[i],string[indices[i]]==0)); + if (neW == NULL) { + FREE(string); + FREE(indices); + Cudd_RecursiveDeref(dd,old); + return(NULL); + } + cuddRef(neW); + Cudd_RecursiveDeref(dd,old); + old = neW; + } + +#ifdef DD_DEBUG + /* Test. */ + if (Cudd_bddLeq(dd,old,f)) { + cuddDeref(old); + } else { + Cudd_RecursiveDeref(dd,old); + old = NULL; + } +#else + cuddDeref(old); +#endif + + FREE(string); + FREE(indices); + return(old); + +} /* end of Cudd_bddPickOneMinterm */ + + +/**Function******************************************************************** + + Synopsis [Picks k on-set minterms evenly distributed from given DD.] + + Description [Picks k on-set minterms evenly distributed from given DD. + The minterms are in terms of vars. The array + vars should contain at least all variables in the + support of f; if this condition is not met the minterms + built by this procedure may not be contained in + f. Builds an array of BDDs for the minterms and returns a + pointer to it if successful; NULL otherwise. There are three reasons + why the procedure may fail: +
          +
        • It may run out of memory; +
        • the function f may be the constant 0; +
        • the minterms may not be contained in f. +
        ] + + SideEffects [None] + + SeeAlso [Cudd_bddPickOneMinterm Cudd_bddPickOneCube] + +******************************************************************************/ +DdNode ** +Cudd_bddPickArbitraryMinterms( + DdManager * dd /* manager */, + DdNode * f /* function from which to pick k minterms */, + DdNode ** vars /* array of variables */, + int n /* size of vars */, + int k /* number of minterms to find */) +{ + char **string; + int i, j, l, size; + int *indices; + int result; + DdNode **old, *neW; + double minterms; + char *saveString; + int saveFlag, savePoint, isSame; + + minterms = Cudd_CountMinterm(dd,f,n); + if ((double)k > minterms) { + return(NULL); + } + + size = dd->size; + string = ALLOC(char *, k); + if (string == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < k; i++) { + string[i] = ALLOC(char, size + 1); + if (string[i] == NULL) { + for (j = 0; j < i; j++) + FREE(string[i]); + FREE(string); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (j = 0; j < size; j++) string[i][j] = '2'; + string[i][size] = '\0'; + } + indices = ALLOC(int,n); + if (indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + FREE(string[i]); + FREE(string); + return(NULL); + } + + for (i = 0; i < n; i++) { + indices[i] = vars[i]->index; + } + + result = ddPickArbitraryMinterms(dd,f,n,k,string); + if (result == 0) { + for (i = 0; i < k; i++) + FREE(string[i]); + FREE(string); + FREE(indices); + return(NULL); + } + + old = ALLOC(DdNode *, k); + if (old == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + FREE(string[i]); + FREE(string); + FREE(indices); + return(NULL); + } + saveString = ALLOC(char, size + 1); + if (saveString == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + FREE(string[i]); + FREE(string); + FREE(indices); + FREE(old); + return(NULL); + } + saveFlag = 0; + + /* Build result BDD array. */ + for (i = 0; i < k; i++) { + isSame = 0; + if (!saveFlag) { + for (j = i + 1; j < k; j++) { + if (strcmp(string[i], string[j]) == 0) { + savePoint = i; + strcpy(saveString, string[i]); + saveFlag = 1; + break; + } + } + } else { + if (strcmp(string[i], saveString) == 0) { + isSame = 1; + } else { + saveFlag = 0; + for (j = i + 1; j < k; j++) { + if (strcmp(string[i], string[j]) == 0) { + savePoint = i; + strcpy(saveString, string[i]); + saveFlag = 1; + break; + } + } + } + } + /* Randomize choice for don't cares. */ + for (j = 0; j < n; j++) { + if (string[i][indices[j]] == '2') + string[i][indices[j]] = + (char) ((Cudd_Random() & 0x20) ? '1' : '0'); + } + + while (isSame) { + isSame = 0; + for (j = savePoint; j < i; j++) { + if (strcmp(string[i], string[j]) == 0) { + isSame = 1; + break; + } + } + if (isSame) { + strcpy(string[i], saveString); + /* Randomize choice for don't cares. */ + for (j = 0; j < n; j++) { + if (string[i][indices[j]] == '2') + string[i][indices[j]] = + (char) ((Cudd_Random() & 0x20) ? '1' : '0'); + } + } + } + + old[i] = Cudd_ReadOne(dd); + cuddRef(old[i]); + + for (j = 0; j < n; j++) { + if (string[i][indices[j]] == '0') { + neW = Cudd_bddAnd(dd,old[i],Cudd_Not(vars[j])); + } else { + neW = Cudd_bddAnd(dd,old[i],vars[j]); + } + if (neW == NULL) { + FREE(saveString); + for (l = 0; l < k; l++) + FREE(string[l]); + FREE(string); + FREE(indices); + for (l = 0; l <= i; l++) + Cudd_RecursiveDeref(dd,old[l]); + FREE(old); + return(NULL); + } + cuddRef(neW); + Cudd_RecursiveDeref(dd,old[i]); + old[i] = neW; + } + + /* Test. */ + if (!Cudd_bddLeq(dd,old[i],f)) { + FREE(saveString); + for (l = 0; l < k; l++) + FREE(string[l]); + FREE(string); + FREE(indices); + for (l = 0; l <= i; l++) + Cudd_RecursiveDeref(dd,old[l]); + FREE(old); + return(NULL); + } + } + + FREE(saveString); + for (i = 0; i < k; i++) { + cuddDeref(old[i]); + FREE(string[i]); + } + FREE(string); + FREE(indices); + return(old); + +} /* end of Cudd_bddPickArbitraryMinterms */ + + +/**Function******************************************************************** + + Synopsis [Extracts a subset from a BDD.] + + Description [Extracts a subset from a BDD in the following procedure. + 1. Compute the weight for each mask variable by counting the number of + minterms for both positive and negative cofactors of the BDD with + respect to each mask variable. (weight = #positive - #negative) + 2. Find a representative cube of the BDD by using the weight. From the + top variable of the BDD, for each variable, if the weight is greater + than 0.0, choose THEN branch, othereise ELSE branch, until meeting + the constant 1. + 3. Quantify out the variables not in maskVars from the representative + cube and if a variable in maskVars is don't care, replace the + variable with a constant(1 or 0) depending on the weight. + 4. Make a subset of the BDD by multiplying with the modified cube.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_SubsetWithMaskVars( + DdManager * dd /* manager */, + DdNode * f /* function from which to pick a cube */, + DdNode ** vars /* array of variables */, + int nvars /* size of vars */, + DdNode ** maskVars /* array of variables */, + int mvars /* size of maskVars */) +{ + double *weight; + char *string; + int i, size; + int *indices, *mask; + int result; + DdNode *zero, *cube, *newCube, *subset; + DdNode *cof; + + DdNode *support; + support = Cudd_Support(dd,f); + cuddRef(support); + Cudd_RecursiveDeref(dd,support); + + zero = Cudd_Not(dd->one); + size = dd->size; + + weight = ALLOC(double,size); + if (weight == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + weight[i] = 0.0; + } + for (i = 0; i < mvars; i++) { + cof = Cudd_Cofactor(dd, f, maskVars[i]); + cuddRef(cof); + weight[i] = Cudd_CountMinterm(dd, cof, nvars); + Cudd_RecursiveDeref(dd,cof); + + cof = Cudd_Cofactor(dd, f, Cudd_Not(maskVars[i])); + cuddRef(cof); + weight[i] -= Cudd_CountMinterm(dd, cof, nvars); + Cudd_RecursiveDeref(dd,cof); + } + + string = ALLOC(char, size + 1); + if (string == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(weight); + return(NULL); + } + mask = ALLOC(int, size); + if (mask == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(weight); + FREE(string); + return(NULL); + } + for (i = 0; i < size; i++) { + string[i] = '2'; + mask[i] = 0; + } + string[size] = '\0'; + indices = ALLOC(int,nvars); + if (indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(weight); + FREE(string); + FREE(mask); + return(NULL); + } + for (i = 0; i < nvars; i++) { + indices[i] = vars[i]->index; + } + + result = ddPickRepresentativeCube(dd,f,weight,string); + if (result == 0) { + FREE(weight); + FREE(string); + FREE(mask); + FREE(indices); + return(NULL); + } + + cube = Cudd_ReadOne(dd); + cuddRef(cube); + zero = Cudd_Not(Cudd_ReadOne(dd)); + for (i = 0; i < nvars; i++) { + if (string[indices[i]] == '0') { + newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); + } else if (string[indices[i]] == '1') { + newCube = Cudd_bddIte(dd,cube,vars[i],zero); + } else + continue; + if (newCube == NULL) { + FREE(weight); + FREE(string); + FREE(mask); + FREE(indices); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(newCube); + Cudd_RecursiveDeref(dd,cube); + cube = newCube; + } + Cudd_RecursiveDeref(dd,cube); + + for (i = 0; i < mvars; i++) { + mask[maskVars[i]->index] = 1; + } + for (i = 0; i < nvars; i++) { + if (mask[indices[i]]) { + if (string[indices[i]] == '2') { + if (weight[indices[i]] >= 0.0) + string[indices[i]] = '1'; + else + string[indices[i]] = '0'; + } + } else { + string[indices[i]] = '2'; + } + } + + cube = Cudd_ReadOne(dd); + cuddRef(cube); + zero = Cudd_Not(Cudd_ReadOne(dd)); + + /* Build result BDD. */ + for (i = 0; i < nvars; i++) { + if (string[indices[i]] == '0') { + newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); + } else if (string[indices[i]] == '1') { + newCube = Cudd_bddIte(dd,cube,vars[i],zero); + } else + continue; + if (newCube == NULL) { + FREE(weight); + FREE(string); + FREE(mask); + FREE(indices); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(newCube); + Cudd_RecursiveDeref(dd,cube); + cube = newCube; + } + + subset = Cudd_bddAnd(dd,f,cube); + cuddRef(subset); + Cudd_RecursiveDeref(dd,cube); + + /* Test. */ + if (Cudd_bddLeq(dd,subset,f)) { + cuddDeref(subset); + } else { + Cudd_RecursiveDeref(dd,subset); + subset = NULL; + } + + FREE(weight); + FREE(string); + FREE(mask); + FREE(indices); + return(subset); + +} /* end of Cudd_SubsetWithMaskVars */ + + +/**Function******************************************************************** + + Synopsis [Finds the first cube of a decision diagram.] + + Description [Defines an iterator on the onset of a decision diagram + and finds its first cube. Returns a generator that contains the + information necessary to continue the enumeration if successful; NULL + otherwise.

        + A cube is represented as an array of literals, which are integers in + {0, 1, 2}; 0 represents a complemented literal, 1 represents an + uncomplemented literal, and 2 stands for don't care. The enumeration + produces a disjoint cover of the function associated with the diagram. + The size of the array equals the number of variables in the manager at + the time Cudd_FirstCube is called.

        + For each cube, a value is also returned. This value is always 1 for a + BDD, while it may be different from 1 for an ADD. + For BDDs, the offset is the set of cubes whose value is the logical zero. + For ADDs, the offset is the set of cubes whose value is the + background value. The cubes of the offset are not enumerated.] + + SideEffects [The first cube and its value are returned as side effects.] + + SeeAlso [Cudd_ForeachCube Cudd_NextCube Cudd_GenFree Cudd_IsGenEmpty + Cudd_FirstNode] + +******************************************************************************/ +DdGen * +Cudd_FirstCube( + DdManager * dd, + DdNode * f, + int ** cube, + CUDD_VALUE_TYPE * value) +{ + DdGen *gen; + DdNode *top, *treg, *next, *nreg, *prev, *preg; + int i; + int nvars; + + /* Sanity Check. */ + if (dd == NULL || f == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ALLOC(DdGen,1); + if (gen == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = dd; + gen->type = CUDD_GEN_CUBES; + gen->status = CUDD_GEN_EMPTY; + gen->gen.cubes.cube = NULL; + gen->gen.cubes.value = DD_ZERO_VAL; + gen->stack.sp = 0; + gen->stack.stack = NULL; + gen->node = NULL; + + nvars = dd->size; + gen->gen.cubes.cube = ALLOC(int,nvars); + if (gen->gen.cubes.cube == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(gen); + return(NULL); + } + for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; + + /* The maximum stack depth is one plus the number of variables. + ** because a path may have nodes at all levels, including the + ** constant level. + */ + gen->stack.stack = ALLOC(DdNodePtr, nvars+1); + if (gen->stack.stack == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(gen->gen.cubes.cube); + FREE(gen); + return(NULL); + } + for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; + + /* Find the first cube of the onset. */ + gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; + + while (1) { + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + if (!cuddIsConstant(treg)) { + /* Take the else branch first. */ + gen->gen.cubes.cube[treg->index] = 0; + next = cuddE(treg); + if (top != treg) next = Cudd_Not(next); + gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; + } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { + /* Backtrack */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = gen->stack.stack[gen->stack.sp-2]; + preg = Cudd_Regular(prev); + nreg = cuddT(preg); + if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[preg->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[preg->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(top); + goto done; + } + } + +done: + *cube = gen->gen.cubes.cube; + *value = gen->gen.cubes.value; + return(gen); + +} /* end of Cudd_FirstCube */ + + +/**Function******************************************************************** + + Synopsis [Generates the next cube of a decision diagram onset.] + + Description [Generates the next cube of a decision diagram onset, + using generator gen. Returns 0 if the enumeration is completed; 1 + otherwise.] + + SideEffects [The cube and its value are returned as side effects. The + generator is modified.] + + SeeAlso [Cudd_ForeachCube Cudd_FirstCube Cudd_GenFree Cudd_IsGenEmpty + Cudd_NextNode] + +******************************************************************************/ +int +Cudd_NextCube( + DdGen * gen, + int ** cube, + CUDD_VALUE_TYPE * value) +{ + DdNode *top, *treg, *next, *nreg, *prev, *preg; + DdManager *dd = gen->manager; + + /* Backtrack from previously reached terminal node. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + prev = gen->stack.stack[gen->stack.sp-2]; + preg = Cudd_Regular(prev); + nreg = cuddT(preg); + if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[preg->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[preg->index] = 2; + gen->stack.sp--; + } + + while (1) { + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + if (!cuddIsConstant(treg)) { + /* Take the else branch first. */ + gen->gen.cubes.cube[treg->index] = 0; + next = cuddE(treg); + if (top != treg) next = Cudd_Not(next); + gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; + } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { + /* Backtrack */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = gen->stack.stack[gen->stack.sp-2]; + preg = Cudd_Regular(prev); + nreg = cuddT(preg); + if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[preg->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[preg->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(top); + goto done; + } + } + +done: + if (gen->status == CUDD_GEN_EMPTY) return(0); + *cube = gen->gen.cubes.cube; + *value = gen->gen.cubes.value; + return(1); + +} /* end of Cudd_NextCube */ + + +/**Function******************************************************************** + + Synopsis [Finds the first prime of a Boolean function.] + + Description [Defines an iterator on a pair of BDDs describing a + (possibly incompletely specified) Boolean functions and finds the + first cube of a cover of the function. Returns a generator + that contains the information necessary to continue the enumeration + if successful; NULL otherwise.

        + + The two argument BDDs are the lower and upper bounds of an interval. + It is a mistake to call this function with a lower bound that is not + less than or equal to the upper bound.

        + + A cube is represented as an array of literals, which are integers in + {0, 1, 2}; 0 represents a complemented literal, 1 represents an + uncomplemented literal, and 2 stands for don't care. The enumeration + produces a prime and irredundant cover of the function associated + with the two BDDs. The size of the array equals the number of + variables in the manager at the time Cudd_FirstCube is called.

        + + This iterator can only be used on BDDs.] + + SideEffects [The first cube is returned as side effect.] + + SeeAlso [Cudd_ForeachPrime Cudd_NextPrime Cudd_GenFree Cudd_IsGenEmpty + Cudd_FirstCube Cudd_FirstNode] + +******************************************************************************/ +DdGen * +Cudd_FirstPrime( + DdManager *dd, + DdNode *l, + DdNode *u, + int **cube) +{ + DdGen *gen; + DdNode *implicant, *prime, *tmp; + int length, result; + + /* Sanity Check. */ + if (dd == NULL || l == NULL || u == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ALLOC(DdGen,1); + if (gen == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = dd; + gen->type = CUDD_GEN_PRIMES; + gen->status = CUDD_GEN_EMPTY; + gen->gen.primes.cube = NULL; + gen->gen.primes.ub = u; + gen->stack.sp = 0; + gen->stack.stack = NULL; + gen->node = l; + cuddRef(l); + + gen->gen.primes.cube = ALLOC(int,dd->size); + if (gen->gen.primes.cube == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(gen); + return(NULL); + } + + if (gen->node == Cudd_ReadLogicZero(dd)) { + gen->status = CUDD_GEN_EMPTY; + } else { + implicant = Cudd_LargestCube(dd,gen->node,&length); + if (implicant == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + FREE(gen->gen.primes.cube); + FREE(gen); + return(NULL); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,implicant); + FREE(gen->gen.primes.cube); + FREE(gen); + return(NULL); + } + cuddRef(prime); + Cudd_RecursiveDeref(dd,implicant); + tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,prime); + FREE(gen->gen.primes.cube); + FREE(gen); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,gen->node); + gen->node = tmp; + result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); + if (result == 0) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,prime); + FREE(gen->gen.primes.cube); + FREE(gen); + return(NULL); + } + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_NONEMPTY; + } + *cube = gen->gen.primes.cube; + return(gen); + +} /* end of Cudd_FirstPrime */ + + +/**Function******************************************************************** + + Synopsis [Generates the next prime of a Boolean function.] + + Description [Generates the next cube of a Boolean function, + using generator gen. Returns 0 if the enumeration is completed; 1 + otherwise.] + + SideEffects [The cube and is returned as side effects. The + generator is modified.] + + SeeAlso [Cudd_ForeachPrime Cudd_FirstPrime Cudd_GenFree Cudd_IsGenEmpty + Cudd_NextCube Cudd_NextNode] + +******************************************************************************/ +int +Cudd_NextPrime( + DdGen *gen, + int **cube) +{ + DdNode *implicant, *prime, *tmp; + DdManager *dd = gen->manager; + int length, result; + + if (gen->node == Cudd_ReadLogicZero(dd)) { + gen->status = CUDD_GEN_EMPTY; + } else { + implicant = Cudd_LargestCube(dd,gen->node,&length); + if (implicant == NULL) { + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,implicant); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(prime); + Cudd_RecursiveDeref(dd,implicant); + tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,gen->node); + gen->node = tmp; + result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); + if (result == 0) { + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_NONEMPTY; + } + if (gen->status == CUDD_GEN_EMPTY) return(0); + *cube = gen->gen.primes.cube; + return(1); + +} /* end of Cudd_NextPrime */ + + +/**Function******************************************************************** + + Synopsis [Computes the cube of an array of BDD variables.] + + Description [Computes the cube of an array of BDD variables. If + non-null, the phase argument indicates which literal of each + variable should appear in the cube. If phase\[i\] is nonzero, then the + positive literal is used. If phase is NULL, the cube is positive unate. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addComputeCube Cudd_IndicesToCube Cudd_CubeArrayToBdd] + +******************************************************************************/ +DdNode * +Cudd_bddComputeCube( + DdManager * dd, + DdNode ** vars, + int * phase, + int n) +{ + DdNode *cube; + DdNode *fn; + int i; + + cube = DD_ONE(dd); + cuddRef(cube); + + for (i = n - 1; i >= 0; i--) { + if (phase == NULL || phase[i] != 0) { + fn = Cudd_bddAnd(dd,vars[i],cube); + } else { + fn = Cudd_bddAnd(dd,Cudd_Not(vars[i]),cube); + } + if (fn == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(fn); + Cudd_RecursiveDeref(dd,cube); + cube = fn; + } + cuddDeref(cube); + + return(cube); + +} /* end of Cudd_bddComputeCube */ + + +/**Function******************************************************************** + + Synopsis [Computes the cube of an array of ADD variables.] + + Description [Computes the cube of an array of ADD variables. If + non-null, the phase argument indicates which literal of each + variable should appear in the cube. If phase\[i\] is nonzero, then the + positive literal is used. If phase is NULL, the cube is positive unate. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [none] + + SeeAlso [Cudd_bddComputeCube] + +******************************************************************************/ +DdNode * +Cudd_addComputeCube( + DdManager * dd, + DdNode ** vars, + int * phase, + int n) +{ + DdNode *cube, *zero; + DdNode *fn; + int i; + + cube = DD_ONE(dd); + cuddRef(cube); + zero = DD_ZERO(dd); + + for (i = n - 1; i >= 0; i--) { + if (phase == NULL || phase[i] != 0) { + fn = Cudd_addIte(dd,vars[i],cube,zero); + } else { + fn = Cudd_addIte(dd,vars[i],zero,cube); + } + if (fn == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(fn); + Cudd_RecursiveDeref(dd,cube); + cube = fn; + } + cuddDeref(cube); + + return(cube); + +} /* end of Cudd_addComputeCube */ + + +/**Function******************************************************************** + + Synopsis [Builds the BDD of a cube from a positional array.] + + Description [Builds a cube from a positional array. The array must + have one integer entry for each BDD variable. If the i-th entry is + 1, the variable of index i appears in true form in the cube; If the + i-th entry is 0, the variable of index i appears complemented in the + cube; otherwise the variable does not appear in the cube. Returns a + pointer to the BDD for the cube if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddComputeCube Cudd_IndicesToCube Cudd_BddToCubeArray] + +******************************************************************************/ +DdNode * +Cudd_CubeArrayToBdd( + DdManager *dd, + int *array) +{ + DdNode *cube, *var, *tmp; + int i; + int size = Cudd_ReadSize(dd); + + cube = DD_ONE(dd); + cuddRef(cube); + for (i = size - 1; i >= 0; i--) { + if ((array[i] & ~1) == 0) { + var = Cudd_bddIthVar(dd,i); + tmp = Cudd_bddAnd(dd,cube,Cudd_NotCond(var,array[i]==0)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cube); + cube = tmp; + } + } + cuddDeref(cube); + return(cube); + +} /* end of Cudd_CubeArrayToBdd */ + + +/**Function******************************************************************** + + Synopsis [Builds a positional array from the BDD of a cube.] + + Description [Builds a positional array from the BDD of a cube. + Array must have one entry for each BDD variable. The positional + array has 1 in i-th position if the variable of index i appears in + true form in the cube; it has 0 in i-th position if the variable of + index i appears in complemented form in the cube; finally, it has 2 + in i-th position if the variable of index i does not appear in the + cube. Returns 1 if successful (the BDD is indeed a cube); 0 + otherwise.] + + SideEffects [The result is in the array passed by reference.] + + SeeAlso [Cudd_CubeArrayToBdd] + +******************************************************************************/ +int +Cudd_BddToCubeArray( + DdManager *dd, + DdNode *cube, + int *array) +{ + DdNode *scan, *t, *e; + int i; + int size = Cudd_ReadSize(dd); + DdNode *zero = Cudd_Not(DD_ONE(dd)); + + for (i = size-1; i >= 0; i--) { + array[i] = 2; + } + scan = cube; + while (!Cudd_IsConstant(scan)) { + int index = Cudd_Regular(scan)->index; + cuddGetBranches(scan,&t,&e); + if (t == zero) { + array[index] = 0; + scan = e; + } else if (e == zero) { + array[index] = 1; + scan = t; + } else { + return(0); /* cube is not a cube */ + } + } + if (scan == zero) { + return(0); + } else { + return(1); + } + +} /* end of Cudd_BddToCubeArray */ + + +/**Function******************************************************************** + + Synopsis [Finds the first node of a decision diagram.] + + Description [Defines an iterator on the nodes of a decision diagram + and finds its first node. Returns a generator that contains the + information necessary to continue the enumeration if successful; + NULL otherwise. The nodes are enumerated in a reverse topological + order, so that a node is always preceded in the enumeration by its + descendants.] + + SideEffects [The first node is returned as a side effect.] + + SeeAlso [Cudd_ForeachNode Cudd_NextNode Cudd_GenFree Cudd_IsGenEmpty + Cudd_FirstCube] + +******************************************************************************/ +DdGen * +Cudd_FirstNode( + DdManager * dd, + DdNode * f, + DdNode ** node) +{ + DdGen *gen; + int size; + + /* Sanity Check. */ + if (dd == NULL || f == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ALLOC(DdGen,1); + if (gen == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = dd; + gen->type = CUDD_GEN_NODES; + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp = 0; + gen->node = NULL; + + /* Collect all the nodes on the generator stack for later perusal. */ + gen->stack.stack = cuddNodeArray(Cudd_Regular(f), &size); + if (gen->stack.stack == NULL) { + FREE(gen); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + gen->gen.nodes.size = size; + + /* Find the first node. */ + if (gen->stack.sp < gen->gen.nodes.size) { + gen->status = CUDD_GEN_NONEMPTY; + gen->node = gen->stack.stack[gen->stack.sp]; + *node = gen->node; + } + + return(gen); + +} /* end of Cudd_FirstNode */ + + +/**Function******************************************************************** + + Synopsis [Finds the next node of a decision diagram.] + + Description [Finds the node of a decision diagram, using generator + gen. Returns 0 if the enumeration is completed; 1 otherwise.] + + SideEffects [The next node is returned as a side effect.] + + SeeAlso [Cudd_ForeachNode Cudd_FirstNode Cudd_GenFree Cudd_IsGenEmpty + Cudd_NextCube] + +******************************************************************************/ +int +Cudd_NextNode( + DdGen * gen, + DdNode ** node) +{ + /* Find the next node. */ + gen->stack.sp++; + if (gen->stack.sp < gen->gen.nodes.size) { + gen->node = gen->stack.stack[gen->stack.sp]; + *node = gen->node; + return(1); + } else { + gen->status = CUDD_GEN_EMPTY; + return(0); + } + +} /* end of Cudd_NextNode */ + + +/**Function******************************************************************** + + Synopsis [Frees a CUDD generator.] + + Description [Frees a CUDD generator. Always returns 0, so that it can + be used in mis-like foreach constructs.] + + SideEffects [None] + + SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube + Cudd_FirstNode Cudd_NextNode Cudd_IsGenEmpty] + +******************************************************************************/ +int +Cudd_GenFree( + DdGen * gen) +{ + if (gen == NULL) return(0); + switch (gen->type) { + case CUDD_GEN_CUBES: + case CUDD_GEN_ZDD_PATHS: + FREE(gen->gen.cubes.cube); + FREE(gen->stack.stack); + break; + case CUDD_GEN_PRIMES: + FREE(gen->gen.primes.cube); + Cudd_RecursiveDeref(gen->manager,gen->node); + break; + case CUDD_GEN_NODES: + FREE(gen->stack.stack); + break; + default: + return(0); + } + FREE(gen); + return(0); + +} /* end of Cudd_GenFree */ + + +/**Function******************************************************************** + + Synopsis [Queries the status of a generator.] + + Description [Queries the status of a generator. Returns 1 if the + generator is empty or NULL; 0 otherswise.] + + SideEffects [None] + + SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube + Cudd_FirstNode Cudd_NextNode Cudd_GenFree] + +******************************************************************************/ +int +Cudd_IsGenEmpty( + DdGen * gen) +{ + if (gen == NULL) return(1); + return(gen->status == CUDD_GEN_EMPTY); + +} /* end of Cudd_IsGenEmpty */ + + +/**Function******************************************************************** + + Synopsis [Builds a cube of BDD variables from an array of indices.] + + Description [Builds a cube of BDD variables from an array of indices. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddComputeCube Cudd_CubeArrayToBdd] + +******************************************************************************/ +DdNode * +Cudd_IndicesToCube( + DdManager * dd, + int * array, + int n) +{ + DdNode *cube, *tmp; + int i; + + cube = DD_ONE(dd); + cuddRef(cube); + for (i = n - 1; i >= 0; i--) { + tmp = Cudd_bddAnd(dd,Cudd_bddIthVar(dd,array[i]),cube); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cube); + cube = tmp; + } + + cuddDeref(cube); + return(cube); + +} /* end of Cudd_IndicesToCube */ + + +/**Function******************************************************************** + + Synopsis [Prints the package version number.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_PrintVersion( + FILE * fp) +{ + (void) fprintf(fp, "%s\n", CUDD_VERSION); + +} /* end of Cudd_PrintVersion */ + + +/**Function******************************************************************** + + Synopsis [Computes the average distance between adjacent nodes.] + + Description [Computes the average distance between adjacent nodes in + the manager. Adjacent nodes are node pairs such that the second node + is the then child, else child, or next node in the collision list.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +double +Cudd_AverageDistance( + DdManager * dd) +{ + double tetotal, nexttotal; + double tesubtotal, nextsubtotal; + double temeasured, nextmeasured; + int i, j; + int slots, nvars; + long diff; + DdNode *scan; + DdNodePtr *nodelist; + DdNode *sentinel = &(dd->sentinel); + + nvars = dd->size; + if (nvars == 0) return(0.0); + + /* Initialize totals. */ + tetotal = 0.0; + nexttotal = 0.0; + temeasured = 0.0; + nextmeasured = 0.0; + + /* Scan the variable subtables. */ + for (i = 0; i < nvars; i++) { + nodelist = dd->subtables[i].nodelist; + tesubtotal = 0.0; + nextsubtotal = 0.0; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != sentinel) { + diff = (long) scan - (long) cuddT(scan); + tesubtotal += (double) ddAbs(diff); + diff = (long) scan - (long) Cudd_Regular(cuddE(scan)); + tesubtotal += (double) ddAbs(diff); + temeasured += 2.0; + if (scan->next != sentinel) { + diff = (long) scan - (long) scan->next; + nextsubtotal += (double) ddAbs(diff); + nextmeasured += 1.0; + } + scan = scan->next; + } + } + tetotal += tesubtotal; + nexttotal += nextsubtotal; + } + + /* Scan the constant table. */ + nodelist = dd->constants.nodelist; + nextsubtotal = 0.0; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (scan->next != NULL) { + diff = (long) scan - (long) scan->next; + nextsubtotal += (double) ddAbs(diff); + nextmeasured += 1.0; + } + scan = scan->next; + } + } + nexttotal += nextsubtotal; + + return((tetotal + nexttotal) / (temeasured + nextmeasured)); + +} /* end of Cudd_AverageDistance */ + + +/**Function******************************************************************** + + Synopsis [Portable random number generator.] + + Description [Portable number generator based on ran2 from "Numerical + Recipes in C." It is a long period (> 2 * 10^18) random number generator + of L'Ecuyer with Bays-Durham shuffle. Returns a long integer uniformly + distributed between 0 and 2147483561 (inclusive of the endpoint values). + The random generator can be explicitly initialized by calling + Cudd_Srandom. If no explicit initialization is performed, then the + seed 1 is assumed.] + + SideEffects [None] + + SeeAlso [Cudd_Srandom] + +******************************************************************************/ +long +Cudd_Random(void) +{ + int i; /* index in the shuffle table */ + long int w; /* work variable */ + + /* cuddRand == 0 if the geneartor has not been initialized yet. */ + if (cuddRand == 0) Cudd_Srandom(1); + + /* Compute cuddRand = (cuddRand * LEQA1) % MODULUS1 avoiding + ** overflows by Schrage's method. + */ + w = cuddRand / LEQQ1; + cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; + cuddRand += (cuddRand < 0) * MODULUS1; + + /* Compute cuddRand2 = (cuddRand2 * LEQA2) % MODULUS2 avoiding + ** overflows by Schrage's method. + */ + w = cuddRand2 / LEQQ2; + cuddRand2 = LEQA2 * (cuddRand2 - w * LEQQ2) - w * LEQR2; + cuddRand2 += (cuddRand2 < 0) * MODULUS2; + + /* cuddRand is shuffled with the Bays-Durham algorithm. + ** shuffleSelect and cuddRand2 are combined to generate the output. + */ + + /* Pick one element from the shuffle table; "i" will be in the range + ** from 0 to STAB_SIZE-1. + */ + i = (int) (shuffleSelect / STAB_DIV); + /* Mix the element of the shuffle table with the current iterate of + ** the second sub-generator, and replace the chosen element of the + ** shuffle table with the current iterate of the first sub-generator. + */ + shuffleSelect = shuffleTable[i] - cuddRand2; + shuffleTable[i] = cuddRand; + shuffleSelect += (shuffleSelect < 1) * (MODULUS1 - 1); + /* Since shuffleSelect != 0, and we want to be able to return 0, + ** here we subtract 1 before returning. + */ + return(shuffleSelect - 1); + +} /* end of Cudd_Random */ + + +/**Function******************************************************************** + + Synopsis [Initializer for the portable random number generator.] + + Description [Initializer for the portable number generator based on + ran2 in "Numerical Recipes in C." The input is the seed for the + generator. If it is negative, its absolute value is taken as seed. + If it is 0, then 1 is taken as seed. The initialized sets up the two + recurrences used to generate a long-period stream, and sets up the + shuffle table.] + + SideEffects [None] + + SeeAlso [Cudd_Random] + +******************************************************************************/ +void +Cudd_Srandom( + long seed) +{ + int i; + + if (seed < 0) cuddRand = -seed; + else if (seed == 0) cuddRand = 1; + else cuddRand = seed; + cuddRand2 = cuddRand; + /* Load the shuffle table (after 11 warm-ups). */ + for (i = 0; i < STAB_SIZE + 11; i++) { + long int w; + w = cuddRand / LEQQ1; + cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; + cuddRand += (cuddRand < 0) * MODULUS1; + shuffleTable[i % STAB_SIZE] = cuddRand; + } + shuffleSelect = shuffleTable[1 % STAB_SIZE]; + +} /* end of Cudd_Srandom */ + + +/**Function******************************************************************** + + Synopsis [Computes the density of a BDD or ADD.] + + Description [Computes the density of a BDD or ADD. The density is + the ratio of the number of minterms to the number of nodes. If 0 is + passed as number of variables, the number of variables existing in + the manager is used. Returns the density if successful; (double) + CUDD_OUT_OF_MEM otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_CountMinterm Cudd_DagSize] + +******************************************************************************/ +double +Cudd_Density( + DdManager * dd /* manager */, + DdNode * f /* function whose density is sought */, + int nvars /* size of the support of f */) +{ + double minterms; + int nodes; + double density; + + if (nvars == 0) nvars = dd->size; + minterms = Cudd_CountMinterm(dd,f,nvars); + if (minterms == (double) CUDD_OUT_OF_MEM) return(minterms); + nodes = Cudd_DagSize(f); + density = minterms / (double) nodes; + return(density); + +} /* end of Cudd_Density */ + + +/**Function******************************************************************** + + Synopsis [Warns that a memory allocation failed.] + + Description [Warns that a memory allocation failed. + This function can be used as replacement of MMout_of_memory to prevent + the safe_mem functions of the util package from exiting when malloc + returns NULL. One possible use is in case of discretionary allocations; + for instance, the allocation of memory to enlarge the computed table.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_OutOfMem( + long size /* size of the allocation that failed */) +{ + (void) fflush(stdout); + (void) fprintf(stderr, "\nunable to allocate %ld bytes\n", size); + return; + +} /* end of Cudd_OutOfMem */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints a DD to the standard output. One line per node is + printed.] + + Description [Prints a DD to the standard output. One line per node is + printed. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug] + +******************************************************************************/ +int +cuddP( + DdManager * dd, + DdNode * f) +{ + int retval; + st_table *table = st_init_table(st_ptrcmp,st_ptrhash); + + if (table == NULL) return(0); + + retval = dp2(dd,f,table); + st_free_table(table); + (void) fputc('\n',dd->out); + return(retval); + +} /* end of cuddP */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory used to store the minterm counts recorded + in the visited table.] + + Description [Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +enum st_retval +cuddStCountfree( + char * key, + char * value, + char * arg) +{ + double *d; + + d = (double *)value; + FREE(d); + return(ST_CONTINUE); + +} /* end of cuddStCountfree */ + + +/**Function******************************************************************** + + Synopsis [Recursively collects all the nodes of a DD in a symbol + table.] + + Description [Traverses the DD f and collects all its nodes in a + symbol table. f is assumed to be a regular pointer and + cuddCollectNodes guarantees this assumption in the recursive calls. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddCollectNodes( + DdNode * f, + st_table * visited) +{ + DdNode *T, *E; + int retval; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + /* If already visited, nothing to do. */ + if (st_is_member(visited, (char *) f) == 1) + return(1); + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Mark node as visited. */ + if (st_add_direct(visited, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + + /* Check terminal case. */ + if (cuddIsConstant(f)) + return(1); + + /* Recursive calls. */ + T = cuddT(f); + retval = cuddCollectNodes(T,visited); + if (retval != 1) return(retval); + E = Cudd_Regular(cuddE(f)); + retval = cuddCollectNodes(E,visited); + return(retval); + +} /* end of cuddCollectNodes */ + + +/**Function******************************************************************** + + Synopsis [Recursively collects all the nodes of a DD in an array.] + + Description [Traverses the DD f and collects all its nodes in an array. + The caller should free the array returned by cuddNodeArray. + Returns a pointer to the array of nodes in case of success; NULL + otherwise. The nodes are collected in reverse topological order, so + that a node is always preceded in the array by all its descendants.] + + SideEffects [The number of nodes is returned as a side effect.] + + SeeAlso [Cudd_FirstNode] + +******************************************************************************/ +DdNodePtr * +cuddNodeArray( + DdNode *f, + int *n) +{ + DdNodePtr *table; + int size, retval; + + size = ddDagInt(Cudd_Regular(f)); + table = ALLOC(DdNodePtr, size); + if (table == NULL) { + ddClearFlag(Cudd_Regular(f)); + return(NULL); + } + + retval = cuddNodeArrayRecur(f, table, 0); + assert(retval == size); + + *n = size; + return(table); + +} /* cuddNodeArray */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of cuddP.] + + Description [Performs the recursive step of cuddP. Returns 1 in case + of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +dp2( + DdManager *dd, + DdNode * f, + st_table * t) +{ + DdNode *g, *n, *N; + int T,E; + + if (f == NULL) { + return(0); + } + g = Cudd_Regular(f); + if (cuddIsConstant(g)) { +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"ID = %c0x%lx\tvalue = %-9g\n", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g)); +#else + (void) fprintf(dd->out,"ID = %c0x%x\tvalue = %-9g\n", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g)); +#endif + return(1); + } + if (st_is_member(t,(char *) g) == 1) { + return(1); + } + if (st_add_direct(t,(char *) g,NULL) == ST_OUT_OF_MEM) + return(0); +#ifdef DD_STATS +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %d\tr = %d\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode), g->index, g->ref); +#else + (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\tr = %d\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),g->index,g->ref); +#endif +#else +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %u\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),g->index); +#else + (void) fprintf(dd->out,"ID = %c0x%x\tindex = %hu\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),g->index); +#endif +#endif + n = cuddT(g); + if (cuddIsConstant(n)) { + (void) fprintf(dd->out,"T = %-9g\t",cuddV(n)); + T = 1; + } else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"T = 0x%lx\t",(ptruint) n / (ptruint) sizeof(DdNode)); +#else + (void) fprintf(dd->out,"T = 0x%x\t",(ptruint) n / (ptruint) sizeof(DdNode)); +#endif + T = 0; + } + + n = cuddE(g); + N = Cudd_Regular(n); + if (cuddIsConstant(N)) { + (void) fprintf(dd->out,"E = %c%-9g\n",bang(n),cuddV(N)); + E = 1; + } else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"E = %c0x%lx\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode)); +#else + (void) fprintf(dd->out,"E = %c0x%x\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode)); +#endif + E = 0; + } + if (E == 0) { + if (dp2(dd,N,t) == 0) + return(0); + } + if (T == 0) { + if (dp2(dd,cuddT(g),t) == 0) + return(0); + } + return(1); + +} /* end of dp2 */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_PrintMinterm.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static void +ddPrintMintermAux( + DdManager * dd /* manager */, + DdNode * node /* current node */, + int * list /* current recursion path */) +{ + DdNode *N,*Nv,*Nnv; + int i,v,index; + + N = Cudd_Regular(node); + + if (cuddIsConstant(N)) { + /* Terminal case: Print one cube based on the current recursion + ** path, unless we have reached the background value (ADDs) or + ** the logical zero (BDDs). + */ + if (node != background && node != zero) { + for (i = 0; i < dd->size; i++) { + v = list[i]; + if (v == 0) (void) fprintf(dd->out,"0"); + else if (v == 1) (void) fprintf(dd->out,"1"); + else (void) fprintf(dd->out,"-"); + } + (void) fprintf(dd->out," % g\n", cuddV(node)); + } + } else { + Nv = cuddT(N); + Nnv = cuddE(N); + if (Cudd_IsComplement(node)) { + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); + } + index = N->index; + list[index] = 0; + ddPrintMintermAux(dd,Nnv,list); + list[index] = 1; + ddPrintMintermAux(dd,Nv,list); + list[index] = 2; + } + return; + +} /* end of ddPrintMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DagSize.] + + Description [Performs the recursive step of Cudd_DagSize. Returns the + number of nodes in the graph rooted at n.] + + SideEffects [None] + +******************************************************************************/ +static int +ddDagInt( + DdNode * n) +{ + int tval, eval; + + if (Cudd_IsComplement(n->next)) { + return(0); + } + n->next = Cudd_Not(n->next); + if (cuddIsConstant(n)) { + return(1); + } + tval = ddDagInt(cuddT(n)); + eval = ddDagInt(Cudd_Regular(cuddE(n))); + return(1 + tval + eval); + +} /* end of ddDagInt */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of cuddNodeArray.] + + Description [Performs the recursive step of cuddNodeArray. Returns + an the number of nodes in the DD. Clear the least significant bit + of the next field that was used as visited flag by + cuddNodeArrayRecur when counting the nodes. node is supposed to be + regular; the invariant is maintained by this procedure.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddNodeArrayRecur( + DdNode *f, + DdNodePtr *table, + int index) +{ + int tindex, eindex; + + if (!Cudd_IsComplement(f->next)) { + return(index); + } + /* Clear visited flag. */ + f->next = Cudd_Regular(f->next); + if (cuddIsConstant(f)) { + table[index] = f; + return(index + 1); + } + tindex = cuddNodeArrayRecur(cuddT(f), table, index); + eindex = cuddNodeArrayRecur(Cudd_Regular(cuddE(f)), table, tindex); + table[eindex] = f; + return(eindex + 1); + +} /* end of cuddNodeArrayRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CofactorEstimate.] + + Description [Performs the recursive step of Cudd_CofactorEstimate. + Returns an estimate of the number of nodes in the DD of a + cofactor of node. Uses the least significant bit of the next field as + visited flag. node is supposed to be regular; the invariant is maintained + by this procedure.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddEstimateCofactor( + DdManager *dd, + st_table *table, + DdNode * node, + int i, + int phase, + DdNode ** ptr) +{ + int tval, eval, val; + DdNode *ptrT, *ptrE; + + if (Cudd_IsComplement(node->next)) { + if (!st_lookup(table,(char *)node,(char **)ptr)) { + if (st_add_direct(table,(char *)node,(char *)node) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + *ptr = node; + } + return(0); + } + node->next = Cudd_Not(node->next); + if (cuddIsConstant(node)) { + *ptr = node; + if (st_add_direct(table,(char *)node,(char *)node) == ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + return(1); + } + if ((int) node->index == i) { + if (phase == 1) { + *ptr = cuddT(node); + val = ddDagInt(cuddT(node)); + } else { + *ptr = cuddE(node); + val = ddDagInt(Cudd_Regular(cuddE(node))); + } + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + return(val); + } + if (dd->perm[node->index] > dd->perm[i]) { + *ptr = node; + tval = ddDagInt(cuddT(node)); + eval = ddDagInt(Cudd_Regular(cuddE(node))); + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)node) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + val = 1 + tval + eval; + return(val); + } + tval = cuddEstimateCofactor(dd,table,cuddT(node),i,phase,&ptrT); + eval = cuddEstimateCofactor(dd,table,Cudd_Regular(cuddE(node)),i, + phase,&ptrE); + ptrE = Cudd_NotCond(ptrE,Cudd_IsComplement(cuddE(node))); + if (ptrT == ptrE) { /* recombination */ + *ptr = ptrT; + val = tval; + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + } else if ((ptrT != cuddT(node) || ptrE != cuddE(node)) && + (*ptr = cuddUniqueLookup(dd,node->index,ptrT,ptrE)) != NULL) { + if (Cudd_IsComplement((*ptr)->next)) { + val = 0; + } else { + val = 1 + tval + eval; + } + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + } else { + *ptr = node; + val = 1 + tval + eval; + } + return(val); + +} /* end of cuddEstimateCofactor */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for the existence of an internal node.] + + Description [Checks the unique table for the existence of an internal + node. Returns a pointer to the node if it is in the table; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddUniqueInter] + +******************************************************************************/ +static DdNode * +cuddUniqueLookup( + DdManager * unique, + int index, + DdNode * T, + DdNode * E) +{ + int posn; + unsigned int level; + DdNodePtr *nodelist; + DdNode *looking; + DdSubtable *subtable; + + if (index >= unique->size) { + return(NULL); + } + + level = unique->perm[index]; + subtable = &(unique->subtables[level]); + +#ifdef DD_DEBUG + assert(level < (unsigned) cuddI(unique,T->index)); + assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index)); +#endif + + posn = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + looking = nodelist[posn]; + + while (T < cuddT(looking)) { + looking = Cudd_Regular(looking->next); + } + while (T == cuddT(looking) && E < cuddE(looking)) { + looking = Cudd_Regular(looking->next); + } + if (cuddT(looking) == T && cuddE(looking) == E) { + return(looking); + } + + return(NULL); + +} /* end of cuddUniqueLookup */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CofactorEstimateSimple.] + + Description [Performs the recursive step of Cudd_CofactorEstimateSimple. + Returns an estimate of the number of nodes in the DD of the positive + cofactor of node. Uses the least significant bit of the next field as + visited flag. node is supposed to be regular; the invariant is maintained + by this procedure.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddEstimateCofactorSimple( + DdNode * node, + int i) +{ + int tval, eval; + + if (Cudd_IsComplement(node->next)) { + return(0); + } + node->next = Cudd_Not(node->next); + if (cuddIsConstant(node)) { + return(1); + } + tval = cuddEstimateCofactorSimple(cuddT(node),i); + if ((int) node->index == i) return(tval); + eval = cuddEstimateCofactorSimple(Cudd_Regular(cuddE(node)),i); + return(1 + tval + eval); + +} /* end of cuddEstimateCofactorSimple */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CountMinterm.] + + Description [Performs the recursive step of Cudd_CountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: +

        + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. Does not use the + identity |f'| = max - |f|, to minimize loss of accuracy due to + roundoff. Returns the number of minterms of the function rooted at + node.] + + SideEffects [None] + +******************************************************************************/ +static double +ddCountMintermAux( + DdNode * node, + double max, + DdHashTable * table) +{ + DdNode *N, *Nt, *Ne; + double min, minT, minE; + DdNode *res; + + N = Cudd_Regular(node); + + if (cuddIsConstant(N)) { + if (node == background || node == zero) { + return(0.0); + } else { + return(max); + } + } + if (N->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) { + min = cuddV(res); + if (res->ref == 0) { + table->manager->dead++; + table->manager->constants.dead++; + } + return(min); + } + + Nt = cuddT(N); Ne = cuddE(N); + if (Cudd_IsComplement(node)) { + Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); + } + + minT = ddCountMintermAux(Nt,max,table); + if (minT == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + minT *= 0.5; + minE = ddCountMintermAux(Ne,max,table); + if (minE == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + minE *= 0.5; + min = minT + minE; + + if (N->ref != 1) { + ptrint fanout = (ptrint) N->ref; + cuddSatDec(fanout); + res = cuddUniqueConst(table->manager,min); + if (!cuddHashTableInsert1(table,node,res,fanout)) { + cuddRef(res); Cudd_RecursiveDeref(table->manager, res); + return((double)CUDD_OUT_OF_MEM); + } + } + + return(min); + +} /* end of ddCountMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CountPath.] + + Description [Performs the recursive step of Cudd_CountPath. + It is based on the following identity. Let |f| be the + number of paths of f. Then: + + |f| = |f0|+|f1| + + where f0 and f1 are the two cofactors of f. Uses the + identity |f'| = |f|, to improve the utilization of the (local) cache. + Returns the number of paths of the function rooted at node.] + + SideEffects [None] + +******************************************************************************/ +static double +ddCountPathAux( + DdNode * node, + st_table * table) +{ + + DdNode *Nv, *Nnv; + double paths, *ppaths, paths1, paths2; + double *dummy; + + + if (cuddIsConstant(node)) { + return(1.0); + } + if (st_lookup(table, node, &dummy)) { + paths = *dummy; + return(paths); + } + + Nv = cuddT(node); Nnv = cuddE(node); + + paths1 = ddCountPathAux(Nv,table); + if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + paths2 = ddCountPathAux(Cudd_Regular(Nnv),table); + if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + paths = paths1 + paths2; + + ppaths = ALLOC(double,1); + if (ppaths == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + + *ppaths = paths; + + if (st_add_direct(table,(char *)node, (char *)ppaths) == ST_OUT_OF_MEM) { + FREE(ppaths); + return((double)CUDD_OUT_OF_MEM); + } + return(paths); + +} /* end of ddCountPathAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_EpdCountMinterm.] + + Description [Performs the recursive step of Cudd_EpdCountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. Does not use the + identity |f'| = max - |f|, to minimize loss of accuracy due to + roundoff. Returns the number of minterms of the function rooted at + node.] + + SideEffects [None] + +******************************************************************************/ +static int +ddEpdCountMintermAux( + DdNode * node, + EpDouble * max, + EpDouble * epd, + st_table * table) +{ + DdNode *Nt, *Ne; + EpDouble *min, minT, minE; + EpDouble *res; + int status; + + /* node is assumed to be regular */ + if (cuddIsConstant(node)) { + if (node == background || node == zero) { + EpdMakeZero(epd, 0); + } else { + EpdCopy(max, epd); + } + return(0); + } + if (node->ref != 1 && st_lookup(table, node, &res)) { + EpdCopy(res, epd); + return(0); + } + + Nt = cuddT(node); Ne = cuddE(node); + + status = ddEpdCountMintermAux(Nt,max,&minT,table); + if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + EpdMultiply(&minT, (double)0.5); + status = ddEpdCountMintermAux(Cudd_Regular(Ne),max,&minE,table); + if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + if (Cudd_IsComplement(Ne)) { + EpdSubtract3(max, &minE, epd); + EpdCopy(epd, &minE); + } + EpdMultiply(&minE, (double)0.5); + EpdAdd3(&minT, &minE, epd); + + if (node->ref > 1) { + min = EpdAlloc(); + if (!min) + return(CUDD_OUT_OF_MEM); + EpdCopy(epd, min); + if (st_insert(table, (char *)node, (char *)min) == ST_OUT_OF_MEM) { + EpdFree(min); + return(CUDD_OUT_OF_MEM); + } + } + + return(0); + +} /* end of ddEpdCountMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CountPathsToNonZero.] + + Description [Performs the recursive step of Cudd_CountPathsToNonZero. + It is based on the following identity. Let |f| be the + number of paths of f. Then: + + |f| = |f0|+|f1| + + where f0 and f1 are the two cofactors of f. Returns the number of + paths of the function rooted at node.] + + SideEffects [None] + +******************************************************************************/ +static double +ddCountPathsToNonZero( + DdNode * N, + st_table * table) +{ + + DdNode *node, *Nt, *Ne; + double paths, *ppaths, paths1, paths2; + double *dummy; + + node = Cudd_Regular(N); + if (cuddIsConstant(node)) { + return((double) !(Cudd_IsComplement(N) || cuddV(node)==DD_ZERO_VAL)); + } + if (st_lookup(table, N, &dummy)) { + paths = *dummy; + return(paths); + } + + Nt = cuddT(node); Ne = cuddE(node); + if (node != N) { + Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); + } + + paths1 = ddCountPathsToNonZero(Nt,table); + if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + paths2 = ddCountPathsToNonZero(Ne,table); + if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + paths = paths1 + paths2; + + ppaths = ALLOC(double,1); + if (ppaths == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + + *ppaths = paths; + + if (st_add_direct(table,(char *)N, (char *)ppaths) == ST_OUT_OF_MEM) { + FREE(ppaths); + return((double)CUDD_OUT_OF_MEM); + } + return(paths); + +} /* end of ddCountPathsToNonZero */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_Support.] + + Description [Performs the recursive step of Cudd_Support. Performs a + DFS from f. The support is accumulated in supp as a side effect. Uses + the LSB of the then pointer as visited flag.] + + SideEffects [None] + + SeeAlso [ddClearFlag] + +******************************************************************************/ +static void +ddSupportStep( + DdNode * f, + int * support) +{ + if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) + return; + + support[f->index] = 1; + ddSupportStep(cuddT(f),support); + ddSupportStep(Cudd_Regular(cuddE(f)),support); + /* Mark as visited. */ + f->next = Cudd_Complement(f->next); + +} /* end of ddSupportStep */ + + +/**Function******************************************************************** + + Synopsis [Performs a DFS from f, clearing the LSB of the next + pointers.] + + Description [] + + SideEffects [None] + + SeeAlso [ddSupportStep ddFindSupport ddLeavesInt ddDagInt] + +******************************************************************************/ +static void +ddClearFlag( + DdNode * f) +{ + if (!Cudd_IsComplement(f->next)) { + return; + } + /* Clear visited flag. */ + f->next = Cudd_Regular(f->next); + if (cuddIsConstant(f)) { + return; + } + ddClearFlag(cuddT(f)); + ddClearFlag(Cudd_Regular(cuddE(f))); + return; + +} /* end of ddClearFlag */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CountLeaves.] + + Description [Performs the recursive step of Cudd_CountLeaves. Returns + the number of leaves in the DD rooted at n.] + + SideEffects [None] + + SeeAlso [Cudd_CountLeaves] + +******************************************************************************/ +static int +ddLeavesInt( + DdNode * n) +{ + int tval, eval; + + if (Cudd_IsComplement(n->next)) { + return(0); + } + n->next = Cudd_Not(n->next); + if (cuddIsConstant(n)) { + return(1); + } + tval = ddLeavesInt(cuddT(n)); + eval = ddLeavesInt(Cudd_Regular(cuddE(n))); + return(tval + eval); + +} /* end of ddLeavesInt */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddPickArbitraryMinterms.] + + Description [Performs the recursive step of Cudd_bddPickArbitraryMinterms. + Returns 1 if successful; 0 otherwise.] + + SideEffects [none] + + SeeAlso [Cudd_bddPickArbitraryMinterms] + +******************************************************************************/ +static int +ddPickArbitraryMinterms( + DdManager *dd, + DdNode *node, + int nvars, + int nminterms, + char **string) +{ + DdNode *N, *T, *E; + DdNode *one, *bzero; + int i, t, result; + double min1, min2; + + if (string == NULL || node == NULL) return(0); + + /* The constant 0 function has no on-set cubes. */ + one = DD_ONE(dd); + bzero = Cudd_Not(one); + if (nminterms == 0 || node == bzero) return(1); + if (node == one) { + return(1); + } + + N = Cudd_Regular(node); + T = cuddT(N); E = cuddE(N); + if (Cudd_IsComplement(node)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + + min1 = Cudd_CountMinterm(dd, T, nvars) / 2.0; + if (min1 == (double)CUDD_OUT_OF_MEM) return(0); + min2 = Cudd_CountMinterm(dd, E, nvars) / 2.0; + if (min2 == (double)CUDD_OUT_OF_MEM) return(0); + + t = (int)((double)nminterms * min1 / (min1 + min2) + 0.5); + for (i = 0; i < t; i++) + string[i][N->index] = '1'; + for (i = t; i < nminterms; i++) + string[i][N->index] = '0'; + + result = ddPickArbitraryMinterms(dd,T,nvars,t,&string[0]); + if (result == 0) + return(0); + result = ddPickArbitraryMinterms(dd,E,nvars,nminterms-t,&string[t]); + return(result); + +} /* end of ddPickArbitraryMinterms */ + + +/**Function******************************************************************** + + Synopsis [Finds a representative cube of a BDD.] + + Description [Finds a representative cube of a BDD with the weight of + each variable. From the top variable, if the weight is greater than or + equal to 0.0, choose THEN branch unless the child is the constant 0. + Otherwise, choose ELSE branch unless the child is the constant 0.] + + SideEffects [Cudd_SubsetWithMaskVars Cudd_bddPickOneCube] + +******************************************************************************/ +static int +ddPickRepresentativeCube( + DdManager *dd, + DdNode *node, + double *weight, + char *string) +{ + DdNode *N, *T, *E; + DdNode *one, *bzero; + + if (string == NULL || node == NULL) return(0); + + /* The constant 0 function has no on-set cubes. */ + one = DD_ONE(dd); + bzero = Cudd_Not(one); + if (node == bzero) return(0); + + if (node == DD_ONE(dd)) return(1); + + for (;;) { + N = Cudd_Regular(node); + if (N == one) + break; + T = cuddT(N); + E = cuddE(N); + if (Cudd_IsComplement(node)) { + T = Cudd_Not(T); + E = Cudd_Not(E); + } + if (weight[N->index] >= 0.0) { + if (T == bzero) { + node = E; + string[N->index] = '0'; + } else { + node = T; + string[N->index] = '1'; + } + } else { + if (E == bzero) { + node = T; + string[N->index] = '1'; + } else { + node = E; + string[N->index] = '0'; + } + } + } + return(1); + +} /* end of ddPickRepresentativeCube */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory used to store the minterm counts recorded + in the visited table.] + + Description [Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +ddEpdFree( + char * key, + char * value, + char * arg) +{ + EpDouble *epd; + + epd = (EpDouble *) value; + EpdFree(epd); + return(ST_CONTINUE); + +} /* end of ddEpdFree */ + + +/**Function******************************************************************** + + Synopsis [Recursively find the support of f.] + + Description [Recursively find the support of f. This function uses the + LSB of the next field of the nodes of f as visited flag. It also uses the + LSB of the next field of the variables as flag to remember whether a + certain index has already been seen. Finally, it uses the manager stack + to record all seen indices.] + + SideEffects [The stack pointer SP is modified by side-effect. The next + fields are changed and need to be reset.] + +******************************************************************************/ +static void +ddFindSupport( + DdManager *dd, + DdNode *f, + int *SP) +{ + int index; + DdNode *var; + + if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) { + return; + } + + index = f->index; + var = dd->vars[index]; + /* It is possible that var is embedded in f. That causes no problem, + ** though, because if we see it after encountering another node with + ** the same index, nothing is supposed to happen. + */ + if (!Cudd_IsComplement(var->next)) { + var->next = Cudd_Complement(var->next); + dd->stack[*SP] = (DdNode *)(ptrint) index; + (*SP)++; + } + ddFindSupport(dd, cuddT(f), SP); + ddFindSupport(dd, Cudd_Regular(cuddE(f)), SP); + /* Mark as visited. */ + f->next = Cudd_Complement(f->next); + +} /* end of ddFindSupport */ + + +/**Function******************************************************************** + + Synopsis [Clears visited flags for variables.] + + Description [Clears visited flags for variables.] + + SideEffects [None] + +******************************************************************************/ +static void +ddClearVars( + DdManager *dd, + int SP) +{ + int i; + + for (i = 0; i < SP; i++) { + int index = (int) (ptrint) dd->stack[i]; + DdNode *var = dd->vars[index]; + var->next = Cudd_Regular(var->next); + } + +} /* end of ddClearVars */ + + +/**Function******************************************************************** + + Synopsis [Compares indices for qsort.] + + Description [Compares indices for qsort. Subtracting these integers + cannot produce overflow, because they are non-negative.] + + SideEffects [None] + +******************************************************************************/ +static int +indexCompare( + const void *a, + const void *b) +{ + int ia = *((int *) a); + int ib = *((int *) b); + return(ia - ib); + +} /* end of indexCompare */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddWindow.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddWindow.c new file mode 100644 index 000000000..2f80beb16 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddWindow.c @@ -0,0 +1,1023 @@ +/**CFile*********************************************************************** + + FileName [cuddWindow.c] + + PackageName [cudd] + + Synopsis [Functions for variable reordering by window permutation.] + + Description [Internal procedures included in this module: +
          +
        • cuddWindowReorder() +
        + Static procedures included in this module: +
          +
        • ddWindow2() +
        • ddWindowConv2() +
        • ddPermuteWindow3() +
        • ddWindow3() +
        • ddWindowConv3() +
        • ddPermuteWindow4() +
        • ddWindow4() +
        • ddWindowConv4() +
        ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddWindow.c,v 1.15 2012/02/05 01:07:19 fabio Exp $"; +#endif + +#ifdef DD_STATS +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddWindow2 (DdManager *table, int low, int high); +static int ddWindowConv2 (DdManager *table, int low, int high); +static int ddPermuteWindow3 (DdManager *table, int x); +static int ddWindow3 (DdManager *table, int low, int high); +static int ddWindowConv3 (DdManager *table, int low, int high); +static int ddPermuteWindow4 (DdManager *table, int w); +static int ddWindow4 (DdManager *table, int low, int high); +static int ddWindowConv4 (DdManager *table, int low, int high); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Reorders by applying the method of the sliding window.] + + Description [Reorders by applying the method of the sliding window. + Tries all possible permutations to the variables in a window that + slides from low to high. The size of the window is determined by + submethod. Assumes that no dead nodes are present. Returns 1 in + case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddWindowReorder( + DdManager * table /* DD table */, + int low /* lowest index to reorder */, + int high /* highest index to reorder */, + Cudd_ReorderingType submethod /* window reordering option */) +{ + + int res; +#ifdef DD_DEBUG + int supposedOpt; +#endif + + switch (submethod) { + case CUDD_REORDER_WINDOW2: + res = ddWindow2(table,low,high); + break; + case CUDD_REORDER_WINDOW3: + res = ddWindow3(table,low,high); + break; + case CUDD_REORDER_WINDOW4: + res = ddWindow4(table,low,high); + break; + case CUDD_REORDER_WINDOW2_CONV: + res = ddWindowConv2(table,low,high); + break; + case CUDD_REORDER_WINDOW3_CONV: + res = ddWindowConv3(table,low,high); +#ifdef DD_DEBUG + supposedOpt = table->keys - table->isolated; + res = ddWindow3(table,low,high); + if (table->keys - table->isolated != (unsigned) supposedOpt) { + (void) fprintf(table->err, "Convergence failed! (%d != %d)\n", + table->keys - table->isolated, supposedOpt); + } +#endif + break; + case CUDD_REORDER_WINDOW4_CONV: + res = ddWindowConv4(table,low,high); +#ifdef DD_DEBUG + supposedOpt = table->keys - table->isolated; + res = ddWindow4(table,low,high); + if (table->keys - table->isolated != (unsigned) supposedOpt) { + (void) fprintf(table->err,"Convergence failed! (%d != %d)\n", + table->keys - table->isolated, supposedOpt); + } +#endif + break; + default: return(0); + } + + return(res); + +} /* end of cuddWindowReorder */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reorders by applying a sliding window of width 2.] + + Description [Reorders by applying a sliding window of width 2. + Tries both permutations of the variables in a window + that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindow2( + DdManager * table, + int low, + int high) +{ + + int x; + int res; + int size; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 1) return(0); + + res = table->keys - table->isolated; + for (x = low; x < high; x++) { + size = res; + res = cuddSwapInPlace(table,x,x+1); + if (res == 0) return(0); + if (res >= size) { /* no improvement: undo permutation */ + res = cuddSwapInPlace(table,x,x+1); + if (res == 0) return(0); + } +#ifdef DD_STATS + if (res < size) { + (void) fprintf(table->out,"-"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + return(1); + +} /* end of ddWindow2 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by repeatedly applying a sliding window of width 2.] + + Description [Reorders by repeatedly applying a sliding window of width + 2. Tries both permutations of the variables in a window + that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindowConv2( + DdManager * table, + int low, + int high) +{ + int x; + int res; + int nwin; + int newevent; + int *events; + int size; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 1) return(ddWindowConv2(table,low,high)); + + nwin = high-low; + events = ALLOC(int,nwin); + if (events == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (x=0; xkeys - table->isolated; + do { + newevent = 0; + for (x=0; x= size) { /* no improvement: undo permutation */ + res = cuddSwapInPlace(table,x+low,x+low+1); + if (res == 0) { + FREE(events); + return(0); + } + } + if (res < size) { + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + } + events[x] = 0; +#ifdef DD_STATS + if (res < size) { + (void) fprintf(table->out,"-"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } +#ifdef DD_STATS + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } +#endif + } while (newevent); + + FREE(events); + + return(1); + +} /* end of ddWindowConv3 */ + + +/**Function******************************************************************** + + Synopsis [Tries all the permutations of the three variables between + x and x+2 and retains the best.] + + Description [Tries all the permutations of the three variables between + x and x+2 and retains the best. Assumes that no dead nodes are + present. Returns the index of the best permutation (1-6) in case of + success; 0 otherwise.Assumes that no dead nodes are present. Returns + the index of the best permutation (1-6) in case of success; 0 + otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddPermuteWindow3( + DdManager * table, + int x) +{ + int y,z; + int size,sizeNew; + int best; + +#ifdef DD_DEBUG + assert(table->dead == 0); + assert(x+2 < table->size); +#endif + + size = table->keys - table->isolated; + y = x+1; z = y+1; + + /* The permutation pattern is: + ** (x,y)(y,z) + ** repeated three times to get all 3! = 6 permutations. + */ +#define ABC 1 + best = ABC; + +#define BAC 2 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = BAC; + size = sizeNew; + } +#define BCA 3 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = BCA; + size = sizeNew; + } +#define CBA 4 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = CBA; + size = sizeNew; + } +#define CAB 5 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = CAB; + size = sizeNew; + } +#define ACB 6 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = ACB; + size = sizeNew; + } + + /* Now take the shortest route to the best permuytation. + ** The initial permutation is ACB. + */ + switch(best) { + case BCA: if (!cuddSwapInPlace(table,y,z)) return(0); + case CBA: if (!cuddSwapInPlace(table,x,y)) return(0); + case ABC: if (!cuddSwapInPlace(table,y,z)) return(0); + case ACB: break; + case BAC: if (!cuddSwapInPlace(table,y,z)) return(0); + case CAB: if (!cuddSwapInPlace(table,x,y)) return(0); + break; + default: return(0); + } + +#ifdef DD_DEBUG + assert(table->keys - table->isolated == (unsigned) size); +#endif + + return(best); + +} /* end of ddPermuteWindow3 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by applying a sliding window of width 3.] + + Description [Reorders by applying a sliding window of width 3. + Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindow3( + DdManager * table, + int low, + int high) +{ + + int x; + int res; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 2) return(ddWindow2(table,low,high)); + + for (x = low; x+1 < high; x++) { + res = ddPermuteWindow3(table,x); + if (res == 0) return(0); +#ifdef DD_STATS + if (res == ABC) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); +#endif + } + + return(1); + +} /* end of ddWindow3 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by repeatedly applying a sliding window of width 3.] + + Description [Reorders by repeatedly applying a sliding window of width + 3. Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindowConv3( + DdManager * table, + int low, + int high) +{ + int x; + int res; + int nwin; + int newevent; + int *events; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 2) return(ddWindowConv2(table,low,high)); + + nwin = high-low-1; + events = ALLOC(int,nwin); + if (events == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (x=0; x 1) events[x-2] = 1; + newevent = 1; + break; + case BCA: + case CBA: + case CAB: + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + case ACB: + if (x < nwin-2) events[x+2] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + break; + default: + FREE(events); + return(0); + } + events[x] = 0; +#ifdef DD_STATS + if (res == ABC) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); +#endif + } + } +#ifdef DD_STATS + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } +#endif + } while (newevent); + + FREE(events); + + return(1); + +} /* end of ddWindowConv3 */ + + +/**Function******************************************************************** + + Synopsis [Tries all the permutations of the four variables between w + and w+3 and retains the best.] + + Description [Tries all the permutations of the four variables between + w and w+3 and retains the best. Assumes that no dead nodes are + present. Returns the index of the best permutation (1-24) in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddPermuteWindow4( + DdManager * table, + int w) +{ + int x,y,z; + int size,sizeNew; + int best; + +#ifdef DD_DEBUG + assert(table->dead == 0); + assert(w+3 < table->size); +#endif + + size = table->keys - table->isolated; + x = w+1; y = x+1; z = y+1; + + /* The permutation pattern is: + * (w,x)(y,z)(w,x)(x,y) + * (y,z)(w,x)(y,z)(x,y) + * repeated three times to get all 4! = 24 permutations. + * This gives a hamiltonian circuit of Cayley's graph. + * The codes to the permutation are assigned in topological order. + * The permutations at lower distance from the final permutation are + * assigned lower codes. This way we can choose, between + * permutations that give the same size, one that requires the minimum + * number of swaps from the final permutation of the hamiltonian circuit. + * There is an exception to this rule: ABCD is given Code 1, to + * avoid oscillation when convergence is sought. + */ +#define ABCD 1 + best = ABCD; + +#define BACD 7 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = BACD; + size = sizeNew; + } +#define BADC 13 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = BADC; + size = sizeNew; + } +#define ABDC 8 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && ABDC < best)) { + if (sizeNew == 0) return(0); + best = ABDC; + size = sizeNew; + } +#define ADBC 14 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = ADBC; + size = sizeNew; + } +#define ADCB 9 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && ADCB < best)) { + if (sizeNew == 0) return(0); + best = ADCB; + size = sizeNew; + } +#define DACB 15 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = DACB; + size = sizeNew; + } +#define DABC 20 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = DABC; + size = sizeNew; + } +#define DBAC 23 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = DBAC; + size = sizeNew; + } +#define BDAC 19 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && BDAC < best)) { + if (sizeNew == 0) return(0); + best = BDAC; + size = sizeNew; + } +#define BDCA 21 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && BDCA < best)) { + if (sizeNew == 0) return(0); + best = BDCA; + size = sizeNew; + } +#define DBCA 24 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = DBCA; + size = sizeNew; + } +#define DCBA 22 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size || (sizeNew == size && DCBA < best)) { + if (sizeNew == 0) return(0); + best = DCBA; + size = sizeNew; + } +#define DCAB 18 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && DCAB < best)) { + if (sizeNew == 0) return(0); + best = DCAB; + size = sizeNew; + } +#define CDAB 12 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && CDAB < best)) { + if (sizeNew == 0) return(0); + best = CDAB; + size = sizeNew; + } +#define CDBA 17 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && CDBA < best)) { + if (sizeNew == 0) return(0); + best = CDBA; + size = sizeNew; + } +#define CBDA 11 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size || (sizeNew == size && CBDA < best)) { + if (sizeNew == 0) return(0); + best = CBDA; + size = sizeNew; + } +#define BCDA 16 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && BCDA < best)) { + if (sizeNew == 0) return(0); + best = BCDA; + size = sizeNew; + } +#define BCAD 10 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && BCAD < best)) { + if (sizeNew == 0) return(0); + best = BCAD; + size = sizeNew; + } +#define CBAD 5 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && CBAD < best)) { + if (sizeNew == 0) return(0); + best = CBAD; + size = sizeNew; + } +#define CABD 3 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size || (sizeNew == size && CABD < best)) { + if (sizeNew == 0) return(0); + best = CABD; + size = sizeNew; + } +#define CADB 6 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && CADB < best)) { + if (sizeNew == 0) return(0); + best = CADB; + size = sizeNew; + } +#define ACDB 4 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && ACDB < best)) { + if (sizeNew == 0) return(0); + best = ACDB; + size = sizeNew; + } +#define ACBD 2 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && ACBD < best)) { + if (sizeNew == 0) return(0); + best = ACBD; + size = sizeNew; + } + + /* Now take the shortest route to the best permutation. + ** The initial permutation is ACBD. + */ + switch(best) { + case DBCA: if (!cuddSwapInPlace(table,y,z)) return(0); + case BDCA: if (!cuddSwapInPlace(table,x,y)) return(0); + case CDBA: if (!cuddSwapInPlace(table,w,x)) return(0); + case ADBC: if (!cuddSwapInPlace(table,y,z)) return(0); + case ABDC: if (!cuddSwapInPlace(table,x,y)) return(0); + case ACDB: if (!cuddSwapInPlace(table,y,z)) return(0); + case ACBD: break; + case DCBA: if (!cuddSwapInPlace(table,y,z)) return(0); + case BCDA: if (!cuddSwapInPlace(table,x,y)) return(0); + case CBDA: if (!cuddSwapInPlace(table,w,x)) return(0); + if (!cuddSwapInPlace(table,x,y)) return(0); + if (!cuddSwapInPlace(table,y,z)) return(0); + break; + case DBAC: if (!cuddSwapInPlace(table,x,y)) return(0); + case DCAB: if (!cuddSwapInPlace(table,w,x)) return(0); + case DACB: if (!cuddSwapInPlace(table,y,z)) return(0); + case BACD: if (!cuddSwapInPlace(table,x,y)) return(0); + case CABD: if (!cuddSwapInPlace(table,w,x)) return(0); + break; + case DABC: if (!cuddSwapInPlace(table,y,z)) return(0); + case BADC: if (!cuddSwapInPlace(table,x,y)) return(0); + case CADB: if (!cuddSwapInPlace(table,w,x)) return(0); + if (!cuddSwapInPlace(table,y,z)) return(0); + break; + case BDAC: if (!cuddSwapInPlace(table,x,y)) return(0); + case CDAB: if (!cuddSwapInPlace(table,w,x)) return(0); + case ADCB: if (!cuddSwapInPlace(table,y,z)) return(0); + case ABCD: if (!cuddSwapInPlace(table,x,y)) return(0); + break; + case BCAD: if (!cuddSwapInPlace(table,x,y)) return(0); + case CBAD: if (!cuddSwapInPlace(table,w,x)) return(0); + if (!cuddSwapInPlace(table,x,y)) return(0); + break; + default: return(0); + } + +#ifdef DD_DEBUG + assert(table->keys - table->isolated == (unsigned) size); +#endif + + return(best); + +} /* end of ddPermuteWindow4 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by applying a sliding window of width 4.] + + Description [Reorders by applying a sliding window of width 4. + Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindow4( + DdManager * table, + int low, + int high) +{ + + int w; + int res; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 3) return(ddWindow3(table,low,high)); + + for (w = low; w+2 < high; w++) { + res = ddPermuteWindow4(table,w); + if (res == 0) return(0); +#ifdef DD_STATS + if (res == ABCD) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); +#endif + } + + return(1); + +} /* end of ddWindow4 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by repeatedly applying a sliding window of width 4.] + + Description [Reorders by repeatedly applying a sliding window of width + 4. Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindowConv4( + DdManager * table, + int low, + int high) +{ + int x; + int res; + int nwin; + int newevent; + int *events; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 3) return(ddWindowConv3(table,low,high)); + + nwin = high-low-2; + events = ALLOC(int,nwin); + if (events == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (x=0; x 2) events[x-3] = 1; + newevent = 1; + break; + case BADC: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case ABDC: + if (x < nwin-3) events[x+3] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + break; + case ADBC: + case ADCB: + case ACDB: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-2) events[x+2] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + case DACB: + case DABC: + case DBAC: + case BDAC: + case BDCA: + case DBCA: + case DCBA: + case DCAB: + case CDAB: + case CDBA: + case CBDA: + case BCDA: + case CADB: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case BCAD: + case CBAD: + case CABD: + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 1) events[x-2] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case ACBD: + if (x < nwin-2) events[x+2] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + default: + FREE(events); + return(0); + } + events[x] = 0; +#ifdef DD_STATS + if (res == ABCD) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); +#endif + } + } +#ifdef DD_STATS + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } +#endif + } while (newevent); + + FREE(events); + + return(1); + +} /* end of ddWindowConv4 */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddCount.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddCount.c new file mode 100644 index 000000000..b65d1022f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddCount.c @@ -0,0 +1,357 @@ +/**CFile*********************************************************************** + + FileName [cuddZddCount.c] + + PackageName [cudd] + + Synopsis [Procedures to count the number of minterms of a ZDD.] + + Description [External procedures included in this module: +
          +
        • Cudd_zddCount(); +
        • Cudd_zddCountDouble(); +
        + Internal procedures included in this module: +
          +
        + Static procedures included in this module: +
          +
        • cuddZddCountStep(); +
        • cuddZddCountDoubleStep(); +
        • st_zdd_count_dbl_free() +
        • st_zdd_countfree() +
        + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.15 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddZddCountStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty); +static double cuddZddCountDoubleStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty); +static enum st_retval st_zdd_countfree (char *key, char *value, char *arg); +static enum st_retval st_zdd_count_dbl_free (char *key, char *value, char *arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms in a ZDD.] + + Description [Returns an integer representing the number of minterms + in a ZDD.] + + SideEffects [None] + + SeeAlso [Cudd_zddCountDouble] + +******************************************************************************/ +int +Cudd_zddCount( + DdManager * zdd, + DdNode * P) +{ + st_table *table; + int res; + DdNode *base, *empty; + + base = DD_ONE(zdd); + empty = DD_ZERO(zdd); + table = st_init_table(st_ptrcmp, st_ptrhash); + if (table == NULL) return(CUDD_OUT_OF_MEM); + res = cuddZddCountStep(P, table, base, empty); + if (res == CUDD_OUT_OF_MEM) { + zdd->errorCode = CUDD_MEMORY_OUT; + } + st_foreach(table, st_zdd_countfree, NIL(char)); + st_free_table(table); + + return(res); + +} /* end of Cudd_zddCount */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a ZDD.] + + Description [Counts the number of minterms of a ZDD. The result is + returned as a double. If the procedure runs out of memory, it + returns (double) CUDD_OUT_OF_MEM. This procedure is used in + Cudd_zddCountMinterm.] + + SideEffects [None] + + SeeAlso [Cudd_zddCountMinterm Cudd_zddCount] + +******************************************************************************/ +double +Cudd_zddCountDouble( + DdManager * zdd, + DdNode * P) +{ + st_table *table; + double res; + DdNode *base, *empty; + + base = DD_ONE(zdd); + empty = DD_ZERO(zdd); + table = st_init_table(st_ptrcmp, st_ptrhash); + if (table == NULL) return((double)CUDD_OUT_OF_MEM); + res = cuddZddCountDoubleStep(P, table, base, empty); + if (res == (double)CUDD_OUT_OF_MEM) { + zdd->errorCode = CUDD_MEMORY_OUT; + } + st_foreach(table, st_zdd_count_dbl_free, NIL(char)); + st_free_table(table); + + return(res); + +} /* end of Cudd_zddCountDouble */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddCount.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddCountStep( + DdNode * P, + st_table * table, + DdNode * base, + DdNode * empty) +{ + int res; + int *dummy; + + if (P == empty) + return(0); + if (P == base) + return(1); + + /* Check cache. */ + if (st_lookup(table, P, &dummy)) { + res = *dummy; + return(res); + } + + res = cuddZddCountStep(cuddE(P), table, base, empty) + + cuddZddCountStep(cuddT(P), table, base, empty); + + dummy = ALLOC(int, 1); + if (dummy == NULL) { + return(CUDD_OUT_OF_MEM); + } + *dummy = res; + if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) { + FREE(dummy); + return(CUDD_OUT_OF_MEM); + } + + return(res); + +} /* end of cuddZddCountStep */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddCountDouble.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double +cuddZddCountDoubleStep( + DdNode * P, + st_table * table, + DdNode * base, + DdNode * empty) +{ + double res; + double *dummy; + + if (P == empty) + return((double)0.0); + if (P == base) + return((double)1.0); + + /* Check cache */ + if (st_lookup(table, P, &dummy)) { + res = *dummy; + return(res); + } + + res = cuddZddCountDoubleStep(cuddE(P), table, base, empty) + + cuddZddCountDoubleStep(cuddT(P), table, base, empty); + + dummy = ALLOC(double, 1); + if (dummy == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + *dummy = res; + if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) { + FREE(dummy); + return((double)CUDD_OUT_OF_MEM); + } + + return(res); + +} /* end of cuddZddCountDoubleStep */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory associated with the computed table of + Cudd_zddCount.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static enum st_retval +st_zdd_countfree( + char * key, + char * value, + char * arg) +{ + int *d; + + d = (int *)value; + FREE(d); + return(ST_CONTINUE); + +} /* end of st_zdd_countfree */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory associated with the computed table of + Cudd_zddCountDouble.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static enum st_retval +st_zdd_count_dbl_free( + char * key, + char * value, + char * arg) +{ + double *d; + + d = (double *)value; + FREE(d); + return(ST_CONTINUE); + +} /* end of st_zdd_count_dbl_free */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddFuncs.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddFuncs.c new file mode 100644 index 000000000..9d818212b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddFuncs.c @@ -0,0 +1,1630 @@ +/**CFile*********************************************************************** + + FileName [cuddZddFuncs.c] + + PackageName [cudd] + + Synopsis [Functions to manipulate covers represented as ZDDs.] + + Description [External procedures included in this module: +
          +
        • Cudd_zddProduct(); +
        • Cudd_zddUnateProduct(); +
        • Cudd_zddWeakDiv(); +
        • Cudd_zddWeakDivF(); +
        • Cudd_zddDivide(); +
        • Cudd_zddDivideF(); +
        • Cudd_zddComplement(); +
        + Internal procedures included in this module: +
          +
        • cuddZddProduct(); +
        • cuddZddUnateProduct(); +
        • cuddZddWeakDiv(); +
        • cuddZddWeakDivF(); +
        • cuddZddDivide(); +
        • cuddZddDivideF(); +
        • cuddZddGetCofactors3() +
        • cuddZddGetCofactors2() +
        • cuddZddComplement(); +
        • cuddZddGetPosVarIndex(); +
        • cuddZddGetNegVarIndex(); +
        • cuddZddGetPosVarLevel(); +
        • cuddZddGetNegVarLevel(); +
        + Static procedures included in this module: +
          +
        + ] + + SeeAlso [] + + Author [In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddFuncs.c,v 1.17 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the product of two covers represented by ZDDs.] + + Description [Computes the product of two covers represented by + ZDDs. The result is also a ZDD. Returns a pointer to the result if + successful; NULL otherwise. The covers on which Cudd_zddProduct + operates use two ZDD variables for each function variable (one ZDD + variable for each literal of the variable). Those two ZDD variables + should be adjacent in the order.] + + SideEffects [None] + + SeeAlso [Cudd_zddUnateProduct] + +******************************************************************************/ +DdNode * +Cudd_zddProduct( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddProduct(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddProduct */ + + +/**Function******************************************************************** + + Synopsis [Computes the product of two unate covers.] + + Description [Computes the product of two unate covers represented as + ZDDs. Unate covers use one ZDD variable for each BDD + variable. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddProduct] + +******************************************************************************/ +DdNode * +Cudd_zddUnateProduct( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddUnateProduct(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddUnateProduct */ + + +/**Function******************************************************************** + + Synopsis [Applies weak division to two covers.] + + Description [Applies weak division to two ZDDs representing two + covers. Returns a pointer to the ZDD representing the result if + successful; NULL otherwise. The result of weak division depends on + the variable order. The covers on which Cudd_zddWeakDiv operates use + two ZDD variables for each function variable (one ZDD variable for + each literal of the variable). Those two ZDD variables should be + adjacent in the order.] + + SideEffects [None] + + SeeAlso [Cudd_zddDivide] + +******************************************************************************/ +DdNode * +Cudd_zddWeakDiv( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddWeakDiv(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddWeakDiv */ + + +/**Function******************************************************************** + + Synopsis [Computes the quotient of two unate covers.] + + Description [Computes the quotient of two unate covers represented + by ZDDs. Unate covers use one ZDD variable for each BDD + variable. Returns a pointer to the resulting ZDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddWeakDiv] + +******************************************************************************/ +DdNode * +Cudd_zddDivide( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddDivide(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddDivide */ + + +/**Function******************************************************************** + + Synopsis [Modified version of Cudd_zddWeakDiv.] + + Description [Modified version of Cudd_zddWeakDiv. This function may + disappear in future releases.] + + SideEffects [None] + + SeeAlso [Cudd_zddWeakDiv] + +******************************************************************************/ +DdNode * +Cudd_zddWeakDivF( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddWeakDivF(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddWeakDivF */ + + +/**Function******************************************************************** + + Synopsis [Modified version of Cudd_zddDivide.] + + Description [Modified version of Cudd_zddDivide. This function may + disappear in future releases.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddDivideF( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddDivideF(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddDivideF */ + + +/**Function******************************************************************** + + Synopsis [Computes a complement cover for a ZDD node.] + + Description [Computes a complement cover for a ZDD node. For lack of a + better method, we first extract the function BDD from the ZDD cover, + then make the complement of the ZDD cover from the complement of the + BDD node by using ISOP. Returns a pointer to the resulting cover if + successful; NULL otherwise. The result depends on current variable + order.] + + SideEffects [The result depends on current variable order.] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddComplement( + DdManager *dd, + DdNode *node) +{ + DdNode *b, *isop, *zdd_I; + + /* Check cache */ + zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node); + if (zdd_I) + return(zdd_I); + + b = Cudd_MakeBddFromZddCover(dd, node); + if (!b) + return(NULL); + Cudd_Ref(b); + isop = Cudd_zddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I); + if (!isop) { + Cudd_RecursiveDeref(dd, b); + return(NULL); + } + Cudd_Ref(isop); + Cudd_Ref(zdd_I); + Cudd_RecursiveDeref(dd, b); + Cudd_RecursiveDeref(dd, isop); + + cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I); + Cudd_Deref(zdd_I); + return(zdd_I); +} /* end of Cudd_zddComplement */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddProduct.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddProduct] + +******************************************************************************/ +DdNode * +cuddZddProduct( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v, top_f, top_g; + DdNode *tmp, *term1, *term2, *term3; + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *R0, *R1, *Rd, *N0, *N1; + DdNode *r; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + int flag; + int pv, nv; + + statLine(dd); + if (f == zero || g == zero) + return(zero); + if (f == one) + return(g); + if (g == one) + return(f); + + top_f = dd->permZ[f->index]; + top_g = dd->permZ[g->index]; + + if (top_f > top_g) + return(cuddZddProduct(dd, g, f)); + + /* Check cache */ + r = cuddCacheLookup2Zdd(dd, cuddZddProduct, f, g); + if (r) + return(r); + + v = f->index; /* either yi or zi */ + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + Cudd_Ref(gd); + pv = cuddZddGetPosVarIndex(dd, v); + nv = cuddZddGetNegVarIndex(dd, v); + + Rd = cuddZddProduct(dd, fd, gd); + if (Rd == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(Rd); + + term1 = cuddZddProduct(dd, f0, g0); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + return(NULL); + } + Cudd_Ref(term1); + term2 = cuddZddProduct(dd, f0, gd); + if (term2 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term2); + term3 = cuddZddProduct(dd, fd, g0); + if (term3 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); + } + Cudd_Ref(term3); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g0); + tmp = cuddZddUnion(dd, term1, term2); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + R0 = cuddZddUnion(dd, tmp, term3); + if (R0 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(R0); + Cudd_RecursiveDerefZdd(dd, tmp); + Cudd_RecursiveDerefZdd(dd, term3); + N0 = cuddZddGetNode(dd, nv, R0, Rd); /* nv = zi */ + if (N0 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, R0); + return(NULL); + } + Cudd_Ref(N0); + Cudd_RecursiveDerefZdd(dd, R0); + Cudd_RecursiveDerefZdd(dd, Rd); + + term1 = cuddZddProduct(dd, f1, g1); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + return(NULL); + } + Cudd_Ref(term1); + term2 = cuddZddProduct(dd, f1, gd); + if (term2 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term2); + term3 = cuddZddProduct(dd, fd, g1); + if (term3 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); + } + Cudd_Ref(term3); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + tmp = cuddZddUnion(dd, term1, term2); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + R1 = cuddZddUnion(dd, tmp, term3); + if (R1 == NULL) { + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(R1); + Cudd_RecursiveDerefZdd(dd, tmp); + Cudd_RecursiveDerefZdd(dd, term3); + N1 = cuddZddGetNode(dd, pv, R1, N0); /* pv = yi */ + if (N1 == NULL) { + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, R1); + return(NULL); + } + Cudd_Ref(N1); + Cudd_RecursiveDerefZdd(dd, R1); + Cudd_RecursiveDerefZdd(dd, N0); + + cuddCacheInsert2(dd, cuddZddProduct, f, g, N1); + Cudd_Deref(N1); + return(N1); + +} /* end of cuddZddProduct */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddUnateProduct.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddUnateProduct] + +******************************************************************************/ +DdNode * +cuddZddUnateProduct( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v, top_f, top_g; + DdNode *term1, *term2, *term3, *term4; + DdNode *sum1, *sum2; + DdNode *f0, *f1, *g0, *g1; + DdNode *r; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + int flag; + + statLine(dd); + if (f == zero || g == zero) + return(zero); + if (f == one) + return(g); + if (g == one) + return(f); + + top_f = dd->permZ[f->index]; + top_g = dd->permZ[g->index]; + + if (top_f > top_g) + return(cuddZddUnateProduct(dd, g, f)); + + /* Check cache */ + r = cuddCacheLookup2Zdd(dd, cuddZddUnateProduct, f, g); + if (r) + return(r); + + v = f->index; /* either yi or zi */ + flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + + term1 = cuddZddUnateProduct(dd, f1, g1); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(term1); + term2 = cuddZddUnateProduct(dd, f1, g0); + if (term2 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term2); + term3 = cuddZddUnateProduct(dd, f0, g1); + if (term3 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); + } + Cudd_Ref(term3); + term4 = cuddZddUnateProduct(dd, f0, g0); + if (term4 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); + } + Cudd_Ref(term4); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + sum1 = cuddZddUnion(dd, term1, term2); + if (sum1 == NULL) { + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, term4); + return(NULL); + } + Cudd_Ref(sum1); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + sum2 = cuddZddUnion(dd, sum1, term3); + if (sum2 == NULL) { + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, term4); + Cudd_RecursiveDerefZdd(dd, sum1); + return(NULL); + } + Cudd_Ref(sum2); + Cudd_RecursiveDerefZdd(dd, sum1); + Cudd_RecursiveDerefZdd(dd, term3); + r = cuddZddGetNode(dd, v, sum2, term4); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, term4); + Cudd_RecursiveDerefZdd(dd, sum2); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDerefZdd(dd, sum2); + Cudd_RecursiveDerefZdd(dd, term4); + + cuddCacheInsert2(dd, cuddZddUnateProduct, f, g, r); + Cudd_Deref(r); + return(r); + +} /* end of cuddZddUnateProduct */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddWeakDiv.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddWeakDiv] + +******************************************************************************/ +DdNode * +cuddZddWeakDiv( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *q, *tmp; + DdNode *r; + int flag; + + statLine(dd); + if (g == one) + return(f); + if (f == zero || f == one) + return(zero); + if (f == g) + return(one); + + /* Check cache. */ + r = cuddCacheLookup2Zdd(dd, cuddZddWeakDiv, f, g); + if (r) + return(r); + + v = g->index; + + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + Cudd_Ref(gd); + + q = g; + + if (g0 != zero) { + q = cuddZddWeakDiv(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + } + else + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g0); + + if (q == zero) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); + Cudd_Deref(q); + return(zero); + } + + if (g1 != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDiv(dd, f1, g1); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + } + else { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + } + + if (q == zero) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); + Cudd_Deref(q); + return(zero); + } + + if (gd != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDiv(dd, fd, gd); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + } + else { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + } + + cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, q); + Cudd_Deref(q); + return(q); + +} /* end of cuddZddWeakDiv */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddWeakDivF.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddWeakDivF] + +******************************************************************************/ +DdNode * +cuddZddWeakDivF( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v, top_f, top_g, vf, vg; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *q, *tmp; + DdNode *r; + DdNode *term1, *term0, *termd; + int flag; + int pv, nv; + + statLine(dd); + if (g == one) + return(f); + if (f == zero || f == one) + return(zero); + if (f == g) + return(one); + + /* Check cache. */ + r = cuddCacheLookup2Zdd(dd, cuddZddWeakDivF, f, g); + if (r) + return(r); + + top_f = dd->permZ[f->index]; + top_g = dd->permZ[g->index]; + vf = top_f >> 1; + vg = top_g >> 1; + v = ddMin(top_f, top_g); + + if (v == top_f && vf < vg) { + v = f->index; + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + + pv = cuddZddGetPosVarIndex(dd, v); + nv = cuddZddGetNegVarIndex(dd, v); + + term1 = cuddZddWeakDivF(dd, f1, g); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(term1); + Cudd_RecursiveDerefZdd(dd, f1); + term0 = cuddZddWeakDivF(dd, f0, g); + if (term0 == NULL) { + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term0); + Cudd_RecursiveDerefZdd(dd, f0); + termd = cuddZddWeakDivF(dd, fd, g); + if (termd == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term0); + return(NULL); + } + Cudd_Ref(termd); + Cudd_RecursiveDerefZdd(dd, fd); + + tmp = cuddZddGetNode(dd, nv, term0, termd); /* nv = zi */ + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term0); + Cudd_RecursiveDerefZdd(dd, termd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, term0); + Cudd_RecursiveDerefZdd(dd, termd); + q = cuddZddGetNode(dd, pv, term1, tmp); /* pv = yi */ + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, tmp); + + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q); + Cudd_Deref(q); + return(q); + } + + if (v == top_f) + v = f->index; + else + v = g->index; + + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + Cudd_Ref(gd); + + q = g; + + if (g0 != zero) { + q = cuddZddWeakDivF(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + } + else + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g0); + + if (q == zero) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); + Cudd_Deref(q); + return(zero); + } + + if (g1 != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDivF(dd, f1, g1); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + } + else { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + } + + if (q == zero) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); + Cudd_Deref(q); + return(zero); + } + + if (gd != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDivF(dd, fd, gd); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + } + else { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + } + + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q); + Cudd_Deref(q); + return(q); + +} /* end of cuddZddWeakDivF */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddDivide.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddDivide] + +******************************************************************************/ +DdNode * +cuddZddDivide( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *g0, *g1; + DdNode *q, *r, *tmp; + int flag; + + statLine(dd); + if (g == one) + return(f); + if (f == zero || f == one) + return(zero); + if (f == g) + return(one); + + /* Check cache. */ + r = cuddCacheLookup2Zdd(dd, cuddZddDivide, f, g); + if (r) + return(r); + + v = g->index; + + flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */ + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + + r = cuddZddDivide(dd, f1, g1); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(r); + + if (r != zero && g0 != zero) { + tmp = r; + q = cuddZddDivide(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(q); + r = cuddZddIntersect(dd, r, q); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, q); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDerefZdd(dd, q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + + cuddCacheInsert2(dd, cuddZddDivide, f, g, r); + Cudd_Deref(r); + return(r); + +} /* end of cuddZddDivide */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddDivideF.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddDivideF] + +******************************************************************************/ +DdNode * +cuddZddDivideF( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *g0, *g1; + DdNode *q, *r, *tmp; + int flag; + + statLine(dd); + if (g == one) + return(f); + if (f == zero || f == one) + return(zero); + if (f == g) + return(one); + + /* Check cache. */ + r = cuddCacheLookup2Zdd(dd, cuddZddDivideF, f, g); + if (r) + return(r); + + v = g->index; + + flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */ + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + + r = cuddZddDivideF(dd, f1, g1); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(r); + + if (r != zero && g0 != zero) { + tmp = r; + q = cuddZddDivideF(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(q); + r = cuddZddIntersect(dd, r, q); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, q); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDerefZdd(dd, q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + + cuddCacheInsert2(dd, cuddZddDivideF, f, g, r); + Cudd_Deref(r); + return(r); + +} /* end of cuddZddDivideF */ + + +/**Function******************************************************************** + + Synopsis [Computes the three-way decomposition of f w.r.t. v.] + + Description [Computes the three-way decomposition of function f (represented + by a ZDD) wit respect to variable v. Returns 0 if successful; 1 otherwise.] + + SideEffects [The results are returned in f1, f0, and fd.] + + SeeAlso [cuddZddGetCofactors2] + +******************************************************************************/ +int +cuddZddGetCofactors3( + DdManager * dd, + DdNode * f, + int v, + DdNode ** f1, + DdNode ** f0, + DdNode ** fd) +{ + DdNode *pc, *nc; + DdNode *zero = DD_ZERO(dd); + int top, hv, ht, pv, nv; + int level; + + top = dd->permZ[f->index]; + level = dd->permZ[v]; + hv = level >> 1; + ht = top >> 1; + + if (hv < ht) { + *f1 = zero; + *f0 = zero; + *fd = f; + } + else { + pv = cuddZddGetPosVarIndex(dd, v); + nv = cuddZddGetNegVarIndex(dd, v); + + /* not to create intermediate ZDD node */ + if (cuddZddGetPosVarLevel(dd, v) < cuddZddGetNegVarLevel(dd, v)) { + pc = cuddZddSubset1(dd, f, pv); + if (pc == NULL) + return(1); + Cudd_Ref(pc); + nc = cuddZddSubset0(dd, f, pv); + if (nc == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + return(1); + } + Cudd_Ref(nc); + + *f1 = cuddZddSubset0(dd, pc, nv); + if (*f1 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + return(1); + } + Cudd_Ref(*f1); + *f0 = cuddZddSubset1(dd, nc, nv); + if (*f0 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + return(1); + } + Cudd_Ref(*f0); + + *fd = cuddZddSubset0(dd, nc, nv); + if (*fd == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*fd); + } else { + pc = cuddZddSubset1(dd, f, nv); + if (pc == NULL) + return(1); + Cudd_Ref(pc); + nc = cuddZddSubset0(dd, f, nv); + if (nc == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + return(1); + } + Cudd_Ref(nc); + + *f0 = cuddZddSubset0(dd, pc, pv); + if (*f0 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + return(1); + } + Cudd_Ref(*f0); + *f1 = cuddZddSubset1(dd, nc, pv); + if (*f1 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*f1); + + *fd = cuddZddSubset0(dd, nc, pv); + if (*fd == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*fd); + } + + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_Deref(*f1); + Cudd_Deref(*f0); + Cudd_Deref(*fd); + } + return(0); + +} /* end of cuddZddGetCofactors3 */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-way decomposition of f w.r.t. v.] + + Description [] + + SideEffects [The results are returned in f1 and f0.] + + SeeAlso [cuddZddGetCofactors3] + +******************************************************************************/ +int +cuddZddGetCofactors2( + DdManager * dd, + DdNode * f, + int v, + DdNode ** f1, + DdNode ** f0) +{ + *f1 = cuddZddSubset1(dd, f, v); + if (*f1 == NULL) + return(1); + *f0 = cuddZddSubset0(dd, f, v); + if (*f0 == NULL) { + Cudd_RecursiveDerefZdd(dd, *f1); + return(1); + } + return(0); + +} /* end of cuddZddGetCofactors2 */ + + +/**Function******************************************************************** + + Synopsis [Computes a complement of a ZDD node.] + + Description [Computes the complement of a ZDD node. So far, since we + couldn't find a direct way to get the complement of a ZDD cover, we first + convert a ZDD cover to a BDD, then make the complement of the ZDD cover + from the complement of the BDD node by using ISOP.] + + SideEffects [The result depends on current variable order.] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddComplement( + DdManager * dd, + DdNode *node) +{ + DdNode *b, *isop, *zdd_I; + + /* Check cache */ + zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node); + if (zdd_I) + return(zdd_I); + + b = cuddMakeBddFromZddCover(dd, node); + if (!b) + return(NULL); + cuddRef(b); + isop = cuddZddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I); + if (!isop) { + Cudd_RecursiveDeref(dd, b); + return(NULL); + } + cuddRef(isop); + cuddRef(zdd_I); + Cudd_RecursiveDeref(dd, b); + Cudd_RecursiveDeref(dd, isop); + + cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I); + cuddDeref(zdd_I); + return(zdd_I); +} /* end of cuddZddComplement */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of positive ZDD variable.] + + Description [Returns the index of positive ZDD variable.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddGetPosVarIndex( + DdManager * dd, + int index) +{ + int pv = (index >> 1) << 1; + return(pv); +} /* end of cuddZddGetPosVarIndex */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of negative ZDD variable.] + + Description [Returns the index of negative ZDD variable.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddGetNegVarIndex( + DdManager * dd, + int index) +{ + int nv = index | 0x1; + return(nv); +} /* end of cuddZddGetPosVarIndex */ + + +/**Function******************************************************************** + + Synopsis [Returns the level of positive ZDD variable.] + + Description [Returns the level of positive ZDD variable.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddGetPosVarLevel( + DdManager * dd, + int index) +{ + int pv = cuddZddGetPosVarIndex(dd, index); + return(dd->permZ[pv]); +} /* end of cuddZddGetPosVarLevel */ + + +/**Function******************************************************************** + + Synopsis [Returns the level of negative ZDD variable.] + + Description [Returns the level of negative ZDD variable.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddGetNegVarLevel( + DdManager * dd, + int index) +{ + int nv = cuddZddGetNegVarIndex(dd, index); + return(dd->permZ[nv]); +} /* end of cuddZddGetNegVarLevel */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddGroup.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddGroup.c new file mode 100644 index 000000000..11b31734d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddGroup.c @@ -0,0 +1,1340 @@ +/**CFile*********************************************************************** + + FileName [cuddZddGroup.c] + + PackageName [cudd] + + Synopsis [Functions for ZDD group sifting.] + + Description [External procedures included in this file: +
          +
        • Cudd_MakeZddTreeNode() +
        + Internal procedures included in this file: +
          +
        • cuddZddTreeSifting() +
        + Static procedures included in this module: +
          +
        • zddTreeSiftingAux() +
        • zddCountInternalMtrNodes() +
        • zddReorderChildren() +
        • zddFindNodeHiLo() +
        • zddUniqueCompareGroup() +
        • zddGroupSifting() +
        • zddGroupSiftingAux() +
        • zddGroupSiftingUp() +
        • zddGroupSiftingDown() +
        • zddGroupMove() +
        • zddGroupMoveBackward() +
        • zddGroupSiftingBackward() +
        • zddMergeGroups() +
        ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddGroup.c,v 1.22 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int *entry; +extern int zddTotalNumberSwapping; +#ifdef DD_STATS +static int extsymmcalls; +static int extsymm; +static int secdiffcalls; +static int secdiff; +static int secdiffmisfire; +#endif +#ifdef DD_DEBUG +static int pr = 0; /* flag to enable printing while debugging */ + /* by depositing a 1 into it */ +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int zddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +#ifdef DD_STATS +static int zddCountInternalMtrNodes (DdManager *table, MtrNode *treenode); +#endif +static int zddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +static void zddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper); +static int zddUniqueCompareGroup (int *ptrX, int *ptrY); +static int zddGroupSifting (DdManager *table, int lower, int upper); +static int zddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static int zddGroupSiftingUp (DdManager *table, int y, int xLow, Move **moves); +static int zddGroupSiftingDown (DdManager *table, int x, int xHigh, Move **moves); +static int zddGroupMove (DdManager *table, int x, int y, Move **moves); +static int zddGroupMoveBackward (DdManager *table, int x, int y); +static int zddGroupSiftingBackward (DdManager *table, Move *moves, int size); +static void zddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Creates a new ZDD variable group.] + + Description [Creates a new ZDD variable group. The group starts at + variable and contains size variables. The parameter low is the index + of the first variable. If the variable already exists, its current + position in the order is known to the manager. If the variable does + not exist yet, the position is assumed to be the same as the index. + The group tree is created if it does not exist yet. + Returns a pointer to the group if successful; NULL otherwise.] + + SideEffects [The ZDD variable tree is changed.] + + SeeAlso [Cudd_MakeTreeNode] + +******************************************************************************/ +MtrNode * +Cudd_MakeZddTreeNode( + DdManager * dd /* manager */, + unsigned int low /* index of the first group variable */, + unsigned int size /* number of variables in the group */, + unsigned int type /* MTR_DEFAULT or MTR_FIXED */) +{ + MtrNode *group; + MtrNode *tree; + unsigned int level; + + /* If the variable does not exist yet, the position is assumed to be + ** the same as the index. Therefore, applications that rely on + ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new + ** variables have to create the variables before they group them. + */ + level = (low < (unsigned int) dd->sizeZ) ? dd->permZ[low] : low; + + if (level + size - 1> (int) MTR_MAXHIGH) + return(NULL); + + /* If the tree does not exist yet, create it. */ + tree = dd->treeZ; + if (tree == NULL) { + dd->treeZ = tree = Mtr_InitGroupTree(0, dd->sizeZ); + if (tree == NULL) + return(NULL); + tree->index = dd->invpermZ[0]; + } + + /* Extend the upper bound of the tree if necessary. This allows the + ** application to create groups even before the variables are created. + */ + tree->size = ddMax(tree->size, level + size); + + /* Create the group. */ + group = Mtr_MakeGroup(tree, level, size, type); + if (group == NULL) + return(NULL); + + /* Initialize the index field to the index of the variable currently + ** in position low. This field will be updated by the reordering + ** procedure to provide a handle to the group once it has been moved. + */ + group->index = (MtrHalfWord) low; + + return(group); + +} /* end of Cudd_MakeZddTreeNode */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Tree sifting algorithm for ZDDs.] + + Description [Tree sifting algorithm for ZDDs. Assumes that a tree + representing a group hierarchy is passed as a parameter. It then + reorders each group in postorder fashion by calling + zddTreeSiftingAux. Assumes that no dead nodes are present. Returns + 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddZddTreeSifting( + DdManager * table /* DD table */, + Cudd_ReorderingType method /* reordering method for the groups of leaves */) +{ + int i; + int nvars; + int result; + int tempTree; + + /* If no tree is provided we create a temporary one in which all + ** variables are in a single group. After reordering this tree is + ** destroyed. + */ + tempTree = table->treeZ == NULL; + if (tempTree) { + table->treeZ = Mtr_InitGroupTree(0,table->sizeZ); + table->treeZ->index = table->invpermZ[0]; + } + nvars = table->sizeZ; + +#ifdef DD_DEBUG + if (pr > 0 && !tempTree) + (void) fprintf(table->out,"cuddZddTreeSifting:"); + Mtr_PrintGroups(table->treeZ,pr <= 0); +#endif +#if 0 + /* Debugging code. */ + if (table->tree && table->treeZ) { + (void) fprintf(table->out,"\n"); + Mtr_PrintGroups(table->tree, 0); + cuddPrintVarGroups(table,table->tree,0,0); + for (i = 0; i < table->size; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->invperm[i]); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < table->size; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->perm[i]); + } + (void) fprintf(table->out,"\n\n"); + Mtr_PrintGroups(table->treeZ,0); + cuddPrintVarGroups(table,table->treeZ,1,0); + for (i = 0; i < table->sizeZ; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->invpermZ[i]); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < table->sizeZ; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->permZ[i]); + } + (void) fprintf(table->out,"\n"); + } + /* End of debugging code. */ +#endif +#ifdef DD_STATS + extsymmcalls = 0; + extsymm = 0; + secdiffcalls = 0; + secdiff = 0; + secdiffmisfire = 0; + + (void) fprintf(table->out,"\n"); + if (!tempTree) + (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", + zddCountInternalMtrNodes(table,table->treeZ)); +#endif + + /* Initialize the group of each subtable to itself. Initially + ** there are no groups. Groups are created according to the tree + ** structure in postorder fashion. + */ + for (i = 0; i < nvars; i++) + table->subtableZ[i].next = i; + + /* Reorder. */ + result = zddTreeSiftingAux(table, table->treeZ, method); + +#ifdef DD_STATS /* print stats */ + if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && + (table->groupcheck == CUDD_GROUP_CHECK7 || + table->groupcheck == CUDD_GROUP_CHECK5)) { + (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); + (void) fprintf(table->out,"extsymm = %d",extsymm); + } + if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && + table->groupcheck == CUDD_GROUP_CHECK7) { + (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); + (void) fprintf(table->out,"secdiff = %d\n",secdiff); + (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); + } +#endif + + if (tempTree) + Cudd_FreeZddTree(table); + return(result); + +} /* end of cuddZddTreeSifting */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Visits the group tree and reorders each group.] + + Description [Recursively visits the group tree and reorders each + group in postorder fashion. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddTreeSiftingAux( + DdManager * table, + MtrNode * treenode, + Cudd_ReorderingType method) +{ + MtrNode *auxnode; + int res; + +#ifdef DD_DEBUG + Mtr_PrintGroups(treenode,1); +#endif + + auxnode = treenode; + while (auxnode != NULL) { + if (auxnode->child != NULL) { + if (!zddTreeSiftingAux(table, auxnode->child, method)) + return(0); + res = zddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT); + if (res == 0) + return(0); + } else if (auxnode->size > 1) { + if (!zddReorderChildren(table, auxnode, method)) + return(0); + } + auxnode = auxnode->younger; + } + + return(1); + +} /* end of zddTreeSiftingAux */ + + +#ifdef DD_STATS +/**Function******************************************************************** + + Synopsis [Counts the number of internal nodes of the group tree.] + + Description [Counts the number of internal nodes of the group tree. + Returns the count.] + + SideEffects [None] + +******************************************************************************/ +static int +zddCountInternalMtrNodes( + DdManager * table, + MtrNode * treenode) +{ + MtrNode *auxnode; + int count,nodeCount; + + + nodeCount = 0; + auxnode = treenode; + while (auxnode != NULL) { + if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { + nodeCount++; + count = zddCountInternalMtrNodes(table,auxnode->child); + nodeCount += count; + } + auxnode = auxnode->younger; + } + + return(nodeCount); + +} /* end of zddCountInternalMtrNodes */ +#endif + + +/**Function******************************************************************** + + Synopsis [Reorders the children of a group tree node according to + the options.] + + Description [Reorders the children of a group tree node according to + the options. After reordering puts all the variables in the group + and/or its descendents in a single group. This allows hierarchical + reordering. If the variables in the group do not exist yet, simply + does nothing. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddReorderChildren( + DdManager * table, + MtrNode * treenode, + Cudd_ReorderingType method) +{ + int lower; + int upper; + int result; + unsigned int initialSize; + + zddFindNodeHiLo(table,treenode,&lower,&upper); + /* If upper == -1 these variables do not exist yet. */ + if (upper == -1) + return(1); + + if (treenode->flags == MTR_FIXED) { + result = 1; + } else { +#ifdef DD_STATS + (void) fprintf(table->out," "); +#endif + switch (method) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + result = cuddZddSwapping(table,lower,upper,method); + break; + case CUDD_REORDER_SIFT: + result = cuddZddSifting(table,lower,upper); + break; + case CUDD_REORDER_SIFT_CONVERGE: + do { + initialSize = table->keysZ; + result = cuddZddSifting(table,lower,upper); + if (initialSize <= table->keysZ) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + case CUDD_REORDER_SYMM_SIFT: + result = cuddZddSymmSifting(table,lower,upper); + break; + case CUDD_REORDER_SYMM_SIFT_CONV: + result = cuddZddSymmSiftingConv(table,lower,upper); + break; + case CUDD_REORDER_GROUP_SIFT: + result = zddGroupSifting(table,lower,upper); + break; + case CUDD_REORDER_LINEAR: + result = cuddZddLinearSifting(table,lower,upper); + break; + case CUDD_REORDER_LINEAR_CONVERGE: + do { + initialSize = table->keysZ; + result = cuddZddLinearSifting(table,lower,upper); + if (initialSize <= table->keysZ) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + default: + return(0); + } + } + + /* Create a single group for all the variables that were sifted, + ** so that they will be treated as a single block by successive + ** invocations of zddGroupSifting. + */ + zddMergeGroups(table,treenode,lower,upper); + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddReorderChildren:"); +#endif + + return(result); + +} /* end of zddReorderChildren */ + + +/**Function******************************************************************** + + Synopsis [Finds the lower and upper bounds of the group represented + by treenode.] + + Description [Finds the lower and upper bounds of the group represented + by treenode. The high and low fields of treenode are indices. From + those we need to derive the current positions, and find maximum and + minimum.] + + SideEffects [The bounds are returned as side effects.] + + SeeAlso [] + +******************************************************************************/ +static void +zddFindNodeHiLo( + DdManager * table, + MtrNode * treenode, + int * lower, + int * upper) +{ + int low; + int high; + + /* Check whether no variables in this group already exist. + ** If so, return immediately. The calling procedure will know from + ** the values of upper that no reordering is needed. + */ + if ((int) treenode->low >= table->sizeZ) { + *lower = table->sizeZ; + *upper = -1; + return; + } + + *lower = low = (unsigned int) table->permZ[treenode->index]; + high = (int) (low + treenode->size - 1); + + if (high >= table->sizeZ) { + /* This is the case of a partially existing group. The aim is to + ** reorder as many variables as safely possible. If the tree + ** node is terminal, we just reorder the subset of the group + ** that is currently in existence. If the group has + ** subgroups, then we only reorder those subgroups that are + ** fully instantiated. This way we avoid breaking up a group. + */ + MtrNode *auxnode = treenode->child; + if (auxnode == NULL) { + *upper = (unsigned int) table->sizeZ - 1; + } else { + /* Search the subgroup that strands the table->sizeZ line. + ** If the first group starts at 0 and goes past table->sizeZ + ** upper will get -1, thus correctly signaling that no reordering + ** should take place. + */ + while (auxnode != NULL) { + int thisLower = table->permZ[auxnode->low]; + int thisUpper = thisLower + auxnode->size - 1; + if (thisUpper >= table->sizeZ && thisLower < table->sizeZ) + *upper = (unsigned int) thisLower - 1; + auxnode = auxnode->younger; + } + } + } else { + /* Normal case: All the variables of the group exist. */ + *upper = (unsigned int) high; + } + +#ifdef DD_DEBUG + /* Make sure that all variables in group are contiguous. */ + assert(treenode->size >= *upper - *lower + 1); +#endif + + return; + +} /* end of zddFindNodeHiLo */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the variables + according to the number of keys in the subtables. Returns the + difference in number of keys between the two variables being + compared.] + + SideEffects [None] + +******************************************************************************/ +static int +zddUniqueCompareGroup( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of zddUniqueCompareGroup */ + + +/**Function******************************************************************** + + Synopsis [Sifts from treenode->low to treenode->high.] + + Description [Sifts from treenode->low to treenode->high. If + croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the + end of the initial sifting. If a group is created, it is then sifted + again. After sifting one variable, the group that contains it is + dissolved. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSifting( + DdManager * table, + int lower, + int upper) +{ + int *var; + int i,j,x,xInit; + int nvars; + int classes; + int result; + int *sifted; +#ifdef DD_STATS + unsigned previousSize; +#endif + int xindex; + + nvars = table->sizeZ; + + /* Order variables to sift. */ + entry = NULL; + sifted = NULL; + var = ALLOC(int,nvars); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; + } + entry = ALLOC(int,nvars); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; + } + sifted = ALLOC(int,nvars); + if (sifted == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; + } + + /* Here we consider only one representative for each group. */ + for (i = 0, classes = 0; i < nvars; i++) { + sifted[i] = 0; + x = table->permZ[i]; + if ((unsigned) x >= table->subtableZ[x].next) { + entry[i] = table->subtableZ[x].keys; + var[classes] = i; + classes++; + } + } + + qsort((void *)var,classes,sizeof(int),(DD_QSFP)zddUniqueCompareGroup); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + xindex = var[i]; + if (sifted[xindex] == 1) /* variable already sifted as part of group */ + continue; + x = table->permZ[xindex]; /* find current level of this variable */ + if (x < lower || x > upper) + continue; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif +#ifdef DD_DEBUG + /* x is bottom of group */ + assert((unsigned) x >= table->subtableZ[x].next); +#endif + result = zddGroupSiftingAux(table,x,lower,upper); + if (!result) goto zddGroupSiftingOutOfMem; + +#ifdef DD_STATS + if (table->keysZ < previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > previousSize) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + + /* Mark variables in the group just sifted. */ + x = table->permZ[xindex]; + if ((unsigned) x != table->subtableZ[x].next) { + xInit = x; + do { + j = table->invpermZ[x]; + sifted[j] = 1; + x = table->subtableZ[x].next; + } while (x != xInit); + } + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSifting:"); +#endif + } /* for */ + + FREE(sifted); + FREE(var); + FREE(entry); + + return(1); + +zddGroupSiftingOutOfMem: + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + if (sifted != NULL) FREE(sifted); + + return(0); + +} /* end of zddGroupSifting */ + + +/**Function******************************************************************** + + Synopsis [Sifts one variable up and down until it has taken all + positions. Checks for aggregation.] + + Description [Sifts one variable up and down until it has taken all + positions. Checks for aggregation. There may be at most two sweeps, + even if the group grows. Assumes that x is either an isolated + variable, or it is the bottom of a group. All groups may not have + been found. The variable being moved is returned to the best position + seen during sifting. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + Move *move; + Move *moves; /* list of moves */ + int initialSize; + int result; + + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingAux from %d to %d\n",xLow,xHigh); + assert((unsigned) x >= table->subtableZ[x].next); /* x is bottom of group */ +#endif + + initialSize = table->keysZ; + moves = NULL; + + if (x == xLow) { /* Sift down */ +#ifdef DD_DEBUG + /* x must be a singleton */ + assert((unsigned) x == table->subtableZ[x].next); +#endif + if (x == xHigh) return(1); /* just one variable */ + + if (!zddGroupSiftingDown(table,x,xHigh,&moves)) + goto zddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); +#ifdef DD_DEBUG + assert(table->keysZ <= (unsigned) initialSize); +#endif + if (!result) goto zddGroupSiftingAuxOutOfMem; + + } else if (cuddZddNextHigh(table,x) > xHigh) { /* Sift up */ +#ifdef DD_DEBUG + /* x is bottom of group */ + assert((unsigned) x >= table->subtableZ[x].next); +#endif + /* Find top of x's group */ + x = table->subtableZ[x].next; + + if (!zddGroupSiftingUp(table,x,xLow,&moves)) + goto zddGroupSiftingAuxOutOfMem; + /* at this point x == xLow, unless early term */ + + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); +#ifdef DD_DEBUG + assert(table->keysZ <= (unsigned) initialSize); +#endif + if (!result) goto zddGroupSiftingAuxOutOfMem; + + } else if (x - xLow > xHigh - x) { /* must go down first: shorter */ + if (!zddGroupSiftingDown(table,x,xHigh,&moves)) + goto zddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + /* Find top of group */ + if (moves) { + x = moves->y; + } + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; +#ifdef DD_DEBUG + /* x should be the top of a group */ + assert((unsigned) x <= table->subtableZ[x].next); +#endif + + if (!zddGroupSiftingUp(table,x,xLow,&moves)) + goto zddGroupSiftingAuxOutOfMem; + + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); +#ifdef DD_DEBUG + assert(table->keysZ <= (unsigned) initialSize); +#endif + if (!result) goto zddGroupSiftingAuxOutOfMem; + + } else { /* moving up first: shorter */ + /* Find top of x's group */ + x = table->subtableZ[x].next; + + if (!zddGroupSiftingUp(table,x,xLow,&moves)) + goto zddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + if (moves) { + x = moves->x; + } + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; +#ifdef DD_DEBUG + /* x is bottom of a group */ + assert((unsigned) x >= table->subtableZ[x].next); +#endif + + if (!zddGroupSiftingDown(table,x,xHigh,&moves)) + goto zddGroupSiftingAuxOutOfMem; + + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); +#ifdef DD_DEBUG + assert(table->keysZ <= (unsigned) initialSize); +#endif + if (!result) goto zddGroupSiftingAuxOutOfMem; + } + + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(1); + +zddGroupSiftingAuxOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(0); + +} /* end of zddGroupSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much.] + + Description [Sifts up a variable until either it reaches position + xLow or the size of the DD heap increases too much. Assumes that y is + the top of a group (or a singleton). Checks y for aggregation to the + adjacent variables. Records all the moves that are appended to the + list of moves received as input and returned as a side effect. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSiftingUp( + DdManager * table, + int y, + int xLow, + Move ** moves) +{ + Move *move; + int x; + int size; + int gxtop; + int limitSize; + + limitSize = table->keysZ; + + x = cuddZddNextLow(table,y); + while (x >= xLow) { + gxtop = table->subtableZ[x].next; + if (table->subtableZ[x].next == (unsigned) x && + table->subtableZ[y].next == (unsigned) y) { + /* x and y are self groups */ + size = cuddZddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtableZ[x].next == (unsigned) x); + assert(table->subtableZ[y].next == (unsigned) y); +#endif + if (size == 0) goto zddGroupSiftingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto zddGroupSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_DEFAULT; + move->size = size; + move->next = *moves; + *moves = move; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingUp (2 single groups):\n"); +#endif + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } else { /* group move */ + size = zddGroupMove(table,x,y,moves); + if (size == 0) goto zddGroupSiftingUpOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } + y = gxtop; + x = cuddZddNextLow(table,y); + } + + return(1); + +zddGroupSiftingUpOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of zddGroupSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts down a variable until it reaches position xHigh.] + + Description [Sifts down a variable until it reaches position xHigh. + Assumes that x is the bottom of a group (or a singleton). Records + all the moves. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSiftingDown( + DdManager * table, + int x, + int xHigh, + Move ** moves) +{ + Move *move; + int y; + int size; + int limitSize; + int gybot; + + + /* Initialize R */ + limitSize = size = table->keysZ; + y = cuddZddNextHigh(table,x); + while (y <= xHigh) { + /* Find bottom of y group. */ + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + + if (table->subtableZ[x].next == (unsigned) x && + table->subtableZ[y].next == (unsigned) y) { + /* x and y are self groups */ + size = cuddZddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtableZ[x].next == (unsigned) x); + assert(table->subtableZ[y].next == (unsigned) y); +#endif + if (size == 0) goto zddGroupSiftingDownOutOfMem; + + /* Record move. */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto zddGroupSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_DEFAULT; + move->size = size; + move->next = *moves; + *moves = move; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingDown (2 single groups):\n"); +#endif + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + x = y; + y = cuddZddNextHigh(table,x); + } else { /* Group move */ + size = zddGroupMove(table,x,y,moves); + if (size == 0) goto zddGroupSiftingDownOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } + x = gybot; + y = cuddZddNextHigh(table,x); + } + + return(1); + +zddGroupSiftingDownOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + + return(0); + +} /* end of zddGroupSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Swaps two groups and records the move.] + + Description [Swaps two groups and records the move. Returns the + number of keys in the DD table in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupMove( + DdManager * table, + int x, + int y, + Move ** moves) +{ + Move *move; + int size; + int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + int swapx,swapy; +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + int initialSize,bestSize; +#endif + +#ifdef DD_DEBUG + /* We assume that x < y */ + assert(x < y); +#endif + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtableZ[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtableZ[ybot].next) + ybot = table->subtableZ[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + initialSize = bestSize = table->keysZ; +#endif + /* Sift the variables of the second group up through the first group */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddZddSwapInPlace(table,x,y); + if (size == 0) goto zddGroupMoveOutOfMem; +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (size < bestSize) + bestSize = size; +#endif + swapx = x; swapy = y; + y = x; + x = cuddZddNextLow(table,y); + } + y = ytop + i; + x = cuddZddNextLow(table,y); + } +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if ((bestSize < initialSize) && (bestSize < size)) + (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); +#endif + + /* fix groups */ + y = xtop; /* ytop is now where xtop used to be */ + for (i = 0; i < ysize - 1; i++) { + table->subtableZ[y].next = cuddZddNextHigh(table,y); + y = cuddZddNextHigh(table,y); + } + table->subtableZ[y].next = xtop; /* y is bottom of its group, join */ + /* it to top of its group */ + x = cuddZddNextHigh(table,y); + newxtop = x; + for (i = 0; i < xsize - 1; i++) { + table->subtableZ[x].next = cuddZddNextHigh(table,x); + x = cuddZddNextHigh(table,x); + } + table->subtableZ[x].next = newxtop; /* x is bottom of its group, join */ + /* it to top of its group */ +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupMove:\n"); +#endif + + /* Store group move */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto zddGroupMoveOutOfMem; + move->x = swapx; + move->y = swapy; + move->flags = MTR_DEFAULT; + move->size = table->keysZ; + move->next = *moves; + *moves = move; + + return(table->keysZ); + +zddGroupMoveOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of zddGroupMove */ + + +/**Function******************************************************************** + + Synopsis [Undoes the swap two groups.] + + Description [Undoes the swap two groups. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupMoveBackward( + DdManager * table, + int x, + int y) +{ + int size; + int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + + +#ifdef DD_DEBUG + /* We assume that x < y */ + assert(x < y); +#endif + + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtableZ[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtableZ[ybot].next) + ybot = table->subtableZ[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + + /* Sift the variables of the second group up through the first group */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddZddSwapInPlace(table,x,y); + if (size == 0) + return(0); + y = x; + x = cuddZddNextLow(table,y); + } + y = ytop + i; + x = cuddZddNextLow(table,y); + } + + /* fix groups */ + y = xtop; + for (i = 0; i < ysize - 1; i++) { + table->subtableZ[y].next = cuddZddNextHigh(table,y); + y = cuddZddNextHigh(table,y); + } + table->subtableZ[y].next = xtop; /* y is bottom of its group, join */ + /* to its top */ + x = cuddZddNextHigh(table,y); + newxtop = x; + for (i = 0; i < xsize - 1; i++) { + table->subtableZ[x].next = cuddZddNextHigh(table,x); + x = cuddZddNextHigh(table,x); + } + table->subtableZ[x].next = newxtop; /* x is bottom of its group, join */ + /* to its top */ +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupMoveBackward:\n"); +#endif + + return(1); + +} /* end of zddGroupMoveBackward */ + + +/**Function******************************************************************** + + Synopsis [Determines the best position for a variables and returns + it there.] + + Description [Determines the best position for a variables and returns + it there. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSiftingBackward( + DdManager * table, + Move * moves, + int size) +{ + Move *move; + int res; + + + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + if ((table->subtableZ[move->x].next == move->x) && + (table->subtableZ[move->y].next == move->y)) { + res = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingBackward:\n"); + assert(table->subtableZ[move->x].next == move->x); + assert(table->subtableZ[move->y].next == move->y); +#endif + } else { /* Group move necessary */ + res = zddGroupMoveBackward(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + } + + return(1); + +} /* end of zddGroupSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Merges groups in the DD table.] + + Description [Creates a single group from low to high and adjusts the + idex field of the tree node.] + + SideEffects [None] + +******************************************************************************/ +static void +zddMergeGroups( + DdManager * table, + MtrNode * treenode, + int low, + int high) +{ + int i; + MtrNode *auxnode; + int saveindex; + int newindex; + + /* Merge all variables from low to high in one group, unless + ** this is the topmost group. In such a case we do not merge lest + ** we lose the symmetry information. */ + if (treenode != table->treeZ) { + for (i = low; i < high; i++) + table->subtableZ[i].next = i+1; + table->subtableZ[high].next = low; + } + + /* Adjust the index fields of the tree nodes. If a node is the + ** first child of its parent, then the parent may also need adjustment. */ + saveindex = treenode->index; + newindex = table->invpermZ[low]; + auxnode = treenode; + do { + auxnode->index = newindex; + if (auxnode->parent == NULL || + (int) auxnode->parent->index != saveindex) + break; + auxnode = auxnode->parent; + } while (1); + return; + +} /* end of zddMergeGroups */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddIsop.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddIsop.c new file mode 100644 index 000000000..c1eaea3d6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddIsop.c @@ -0,0 +1,912 @@ +/**CFile*********************************************************************** + + FileName [cuddZddIsop.c] + + PackageName [cudd] + + Synopsis [Functions to find irredundant SOP covers as ZDDs from BDDs.] + + Description [External procedures included in this module: +
          +
        • Cudd_bddIsop() +
        • Cudd_zddIsop() +
        • Cudd_MakeBddFromZddCover() +
        + Internal procedures included in this module: +
          +
        • cuddBddIsop() +
        • cuddZddIsop() +
        • cuddMakeBddFromZddCover() +
        + Static procedures included in this module: +
          +
        + ] + + SeeAlso [] + + Author [In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddIsop.c,v 1.22 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Computes an ISOP in ZDD form from BDDs.] + + Description [Computes an irredundant sum of products (ISOP) in ZDD + form from BDDs. The two BDDs L and U represent the lower bound and + the upper bound, respectively, of the function. The ISOP uses two + ZDD variables for each BDD variable: One for the positive literal, + and one for the negative literal. These two variables should be + adjacent in the ZDD order. The two ZDD variables corresponding to + BDD variable i should have indices 2i and + 2i+1. The result of this procedure depends on the + variable order. If successful, Cudd_zddIsop returns the BDD for + the function chosen from the interval. The ZDD representing the + irredundant cover is returned as a side effect in zdd_I. In case of + failure, NULL is returned.] + + SideEffects [zdd_I holds the pointer to the ZDD for the ISOP on + successful return.] + + SeeAlso [Cudd_bddIsop Cudd_zddVarsFromBddVars] + +******************************************************************************/ +DdNode * +Cudd_zddIsop( + DdManager * dd, + DdNode * L, + DdNode * U, + DdNode ** zdd_I) +{ + DdNode *res; + int autoDynZ; + + autoDynZ = dd->autoDynZ; + dd->autoDynZ = 0; + + do { + dd->reordered = 0; + res = cuddZddIsop(dd, L, U, zdd_I); + } while (dd->reordered == 1); + dd->autoDynZ = autoDynZ; + return(res); + +} /* end of Cudd_zddIsop */ + + +/**Function******************************************************************** + + Synopsis [Computes a BDD in the interval between L and U with a + simple sum-of-product cover.] + + Description [Computes a BDD in the interval between L and U with a + simple sum-of-product cover. This procedure is similar to + Cudd_zddIsop, but it does not return the ZDD for the cover. Returns + a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddIsop] + +******************************************************************************/ +DdNode * +Cudd_bddIsop( + DdManager * dd, + DdNode * L, + DdNode * U) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddIsop(dd, L, U); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddIsop */ + + +/**Function******************************************************************** + + Synopsis [Converts a ZDD cover to a BDD.] + + Description [Converts a ZDD cover to a BDD for the function represented + by the cover. If successful, it returns a BDD node, otherwise it returns + NULL.] + + SideEffects [] + + SeeAlso [Cudd_zddIsop] + +******************************************************************************/ +DdNode * +Cudd_MakeBddFromZddCover( + DdManager * dd, + DdNode * node) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddMakeBddFromZddCover(dd, node); + } while (dd->reordered == 1); + return(res); +} /* end of Cudd_MakeBddFromZddCover */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddIsop.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddIsop] + +******************************************************************************/ +DdNode * +cuddZddIsop( + DdManager * dd, + DdNode * L, + DdNode * U, + DdNode ** zdd_I) +{ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + DdNode *zdd_one = DD_ONE(dd); + DdNode *zdd_zero = DD_ZERO(dd); + int v, top_l, top_u; + DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; + DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; + DdNode *Isub0, *Isub1, *Id; + DdNode *zdd_Isub0, *zdd_Isub1, *zdd_Id; + DdNode *x; + DdNode *term0, *term1, *sum; + DdNode *Lv, *Uv, *Lnv, *Unv; + DdNode *r, *y, *z; + int index; + DD_CTFP cacheOp; + + statLine(dd); + if (L == zero) { + *zdd_I = zdd_zero; + return(zero); + } + if (U == one) { + *zdd_I = zdd_one; + return(one); + } + + if (U == zero || L == one) { + printf("*** ERROR : illegal condition for ISOP (U < L).\n"); + exit(1); + } + + /* Check the cache. We store two results for each recursive call. + ** One is the BDD, and the other is the ZDD. Both are needed. + ** Hence we need a double hit in the cache to terminate the + ** recursion. Clearly, collisions may evict only one of the two + ** results. */ + cacheOp = (DD_CTFP) cuddZddIsop; + r = cuddCacheLookup2(dd, cuddBddIsop, L, U); + if (r) { + *zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U); + if (*zdd_I) + return(r); + else { + /* The BDD result may have been dead. In that case + ** cuddCacheLookup2 would have called cuddReclaim, + ** whose effects we now have to undo. */ + cuddRef(r); + Cudd_RecursiveDeref(dd, r); + } + } + + top_l = dd->perm[Cudd_Regular(L)->index]; + top_u = dd->perm[Cudd_Regular(U)->index]; + v = ddMin(top_l, top_u); + + /* Compute cofactors. */ + if (top_l == v) { + index = Cudd_Regular(L)->index; + Lv = Cudd_T(L); + Lnv = Cudd_E(L); + if (Cudd_IsComplement(L)) { + Lv = Cudd_Not(Lv); + Lnv = Cudd_Not(Lnv); + } + } + else { + index = Cudd_Regular(U)->index; + Lv = Lnv = L; + } + + if (top_u == v) { + Uv = Cudd_T(U); + Unv = Cudd_E(U); + if (Cudd_IsComplement(U)) { + Uv = Cudd_Not(Uv); + Unv = Cudd_Not(Unv); + } + } + else { + Uv = Unv = U; + } + + Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv)); + if (Lsub0 == NULL) + return(NULL); + Cudd_Ref(Lsub0); + Usub0 = Unv; + Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv)); + if (Lsub1 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + return(NULL); + } + Cudd_Ref(Lsub1); + Usub1 = Uv; + + Isub0 = cuddZddIsop(dd, Lsub0, Usub0, &zdd_Isub0); + if (Isub0 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + return(NULL); + } + /* + if ((!cuddIsConstant(Cudd_Regular(Isub0))) && + (Cudd_Regular(Isub0)->index != zdd_Isub0->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Isub0->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); + } + */ + Cudd_Ref(Isub0); + Cudd_Ref(zdd_Isub0); + Isub1 = cuddZddIsop(dd, Lsub1, Usub1, &zdd_Isub1); + if (Isub1 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + return(NULL); + } + /* + if ((!cuddIsConstant(Cudd_Regular(Isub1))) && + (Cudd_Regular(Isub1)->index != zdd_Isub1->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Isub1->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); + } + */ + Cudd_Ref(Isub1); + Cudd_Ref(zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + + Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0)); + if (Lsuper0 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + return(NULL); + } + Cudd_Ref(Lsuper0); + Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1)); + if (Lsuper1 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + return(NULL); + } + Cudd_Ref(Lsuper1); + Usuper0 = Unv; + Usuper1 = Uv; + + /* Ld = Lsuper0 + Lsuper1 */ + Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1)); + if (Ld == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + return(NULL); + } + Ld = Cudd_Not(Ld); + Cudd_Ref(Ld); + /* Ud = Usuper0 * Usuper1 */ + Ud = cuddBddAndRecur(dd, Usuper0, Usuper1); + if (Ud == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + Cudd_RecursiveDeref(dd, Ld); + return(NULL); + } + Cudd_Ref(Ud); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + + Id = cuddZddIsop(dd, Ld, Ud, &zdd_Id); + if (Id == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + return(NULL); + } + /* + if ((!cuddIsConstant(Cudd_Regular(Id))) && + (Cudd_Regular(Id)->index != zdd_Id->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Id->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); + } + */ + Cudd_Ref(Id); + Cudd_Ref(zdd_Id); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + + x = cuddUniqueInter(dd, index, one, zero); + if (x == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + return(NULL); + } + Cudd_Ref(x); + /* term0 = x * Isub0 */ + term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0); + if (term0 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + Cudd_Ref(term0); + Cudd_RecursiveDeref(dd, Isub0); + /* term1 = x * Isub1 */ + term1 = cuddBddAndRecur(dd, x, Isub1); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, term0); + return(NULL); + } + Cudd_Ref(term1); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, Isub1); + /* sum = term0 + term1 */ + sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1)); + if (sum == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + return(NULL); + } + sum = Cudd_Not(sum); + Cudd_Ref(sum); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + /* r = sum + Id */ + r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id)); + r = Cudd_NotCond(r, r != NULL); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, sum); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDeref(dd, sum); + Cudd_RecursiveDeref(dd, Id); + + if (zdd_Isub0 != zdd_zero) { + z = cuddZddGetNodeIVO(dd, index * 2 + 1, zdd_Isub0, zdd_Id); + if (z == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, r); + return(NULL); + } + } + else { + z = zdd_Id; + } + Cudd_Ref(z); + if (zdd_Isub1 != zdd_zero) { + y = cuddZddGetNodeIVO(dd, index * 2, zdd_Isub1, z); + if (y == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, r); + Cudd_RecursiveDerefZdd(dd, z); + return(NULL); + } + } + else + y = z; + Cudd_Ref(y); + + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDerefZdd(dd, z); + + cuddCacheInsert2(dd, cuddBddIsop, L, U, r); + cuddCacheInsert2(dd, cacheOp, L, U, y); + + Cudd_Deref(r); + Cudd_Deref(y); + *zdd_I = y; + /* + if (Cudd_Regular(r)->index != y->index / 2) { + printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n"); + } + */ + return(r); + +} /* end of cuddZddIsop */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddIsop.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_bddIsop] + +******************************************************************************/ +DdNode * +cuddBddIsop( + DdManager * dd, + DdNode * L, + DdNode * U) +{ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + int v, top_l, top_u; + DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; + DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; + DdNode *Isub0, *Isub1, *Id; + DdNode *x; + DdNode *term0, *term1, *sum; + DdNode *Lv, *Uv, *Lnv, *Unv; + DdNode *r; + int index; + + statLine(dd); + if (L == zero) + return(zero); + if (U == one) + return(one); + + /* Check cache */ + r = cuddCacheLookup2(dd, cuddBddIsop, L, U); + if (r) + return(r); + + top_l = dd->perm[Cudd_Regular(L)->index]; + top_u = dd->perm[Cudd_Regular(U)->index]; + v = ddMin(top_l, top_u); + + /* Compute cofactors */ + if (top_l == v) { + index = Cudd_Regular(L)->index; + Lv = Cudd_T(L); + Lnv = Cudd_E(L); + if (Cudd_IsComplement(L)) { + Lv = Cudd_Not(Lv); + Lnv = Cudd_Not(Lnv); + } + } + else { + index = Cudd_Regular(U)->index; + Lv = Lnv = L; + } + + if (top_u == v) { + Uv = Cudd_T(U); + Unv = Cudd_E(U); + if (Cudd_IsComplement(U)) { + Uv = Cudd_Not(Uv); + Unv = Cudd_Not(Unv); + } + } + else { + Uv = Unv = U; + } + + Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv)); + if (Lsub0 == NULL) + return(NULL); + Cudd_Ref(Lsub0); + Usub0 = Unv; + Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv)); + if (Lsub1 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + return(NULL); + } + Cudd_Ref(Lsub1); + Usub1 = Uv; + + Isub0 = cuddBddIsop(dd, Lsub0, Usub0); + if (Isub0 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + return(NULL); + } + Cudd_Ref(Isub0); + Isub1 = cuddBddIsop(dd, Lsub1, Usub1); + if (Isub1 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + Cudd_RecursiveDeref(dd, Isub0); + return(NULL); + } + Cudd_Ref(Isub1); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + + Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0)); + if (Lsuper0 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + return(NULL); + } + Cudd_Ref(Lsuper0); + Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1)); + if (Lsuper1 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + return(NULL); + } + Cudd_Ref(Lsuper1); + Usuper0 = Unv; + Usuper1 = Uv; + + /* Ld = Lsuper0 + Lsuper1 */ + Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1)); + Ld = Cudd_NotCond(Ld, Ld != NULL); + if (Ld == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + return(NULL); + } + Cudd_Ref(Ld); + Ud = cuddBddAndRecur(dd, Usuper0, Usuper1); + if (Ud == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + Cudd_RecursiveDeref(dd, Ld); + return(NULL); + } + Cudd_Ref(Ud); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + + Id = cuddBddIsop(dd, Ld, Ud); + if (Id == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + return(NULL); + } + Cudd_Ref(Id); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + + x = cuddUniqueInter(dd, index, one, zero); + if (x == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + return(NULL); + } + Cudd_Ref(x); + term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0); + if (term0 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + Cudd_Ref(term0); + Cudd_RecursiveDeref(dd, Isub0); + term1 = cuddBddAndRecur(dd, x, Isub1); + if (term1 == NULL) { + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, term0); + return(NULL); + } + Cudd_Ref(term1); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, Isub1); + /* sum = term0 + term1 */ + sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1)); + sum = Cudd_NotCond(sum, sum != NULL); + if (sum == NULL) { + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + return(NULL); + } + Cudd_Ref(sum); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + /* r = sum + Id */ + r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id)); + r = Cudd_NotCond(r, r != NULL); + if (r == NULL) { + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, sum); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDeref(dd, sum); + Cudd_RecursiveDeref(dd, Id); + + cuddCacheInsert2(dd, cuddBddIsop, L, U, r); + + Cudd_Deref(r); + return(r); + +} /* end of cuddBddIsop */ + + +/**Function******************************************************************** + + Synopsis [Converts a ZDD cover to a BDD.] + + Description [Converts a ZDD cover to a BDD. If successful, it returns + a BDD node, otherwise it returns NULL. It is a recursive algorithm + that works as follows. First it computes 3 cofactors of a ZDD cover: + f1, f0 and fd. Second, it compute BDDs (b1, b0 and bd) of f1, f0 and fd. + Third, it computes T=b1+bd and E=b0+bd. Fourth, it computes ITE(v,T,E) where + v is the variable which has the index of the top node of the ZDD cover. + In this case, since the index of v can be larger than either the one of T + or the one of E, cuddUniqueInterIVO is called, where IVO stands for + independent from variable ordering.] + + SideEffects [] + + SeeAlso [Cudd_MakeBddFromZddCover] + +******************************************************************************/ +DdNode * +cuddMakeBddFromZddCover( + DdManager * dd, + DdNode * node) +{ + DdNode *neW; + int v; + DdNode *f1, *f0, *fd; + DdNode *b1, *b0, *bd; + DdNode *T, *E; + + statLine(dd); + if (node == dd->one) + return(dd->one); + if (node == dd->zero) + return(Cudd_Not(dd->one)); + + /* Check cache */ + neW = cuddCacheLookup1(dd, cuddMakeBddFromZddCover, node); + if (neW) + return(neW); + + v = Cudd_Regular(node)->index; /* either yi or zi */ + if (cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd)) return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + + b1 = cuddMakeBddFromZddCover(dd, f1); + if (!b1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(b1); + b0 = cuddMakeBddFromZddCover(dd, f0); + if (!b0) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDeref(dd, b1); + return(NULL); + } + Cudd_Ref(b0); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + if (fd != dd->zero) { + bd = cuddMakeBddFromZddCover(dd, fd); + if (!bd) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDeref(dd, b1); + Cudd_RecursiveDeref(dd, b0); + return(NULL); + } + Cudd_Ref(bd); + Cudd_RecursiveDerefZdd(dd, fd); + + T = cuddBddAndRecur(dd, Cudd_Not(b1), Cudd_Not(bd)); + if (!T) { + Cudd_RecursiveDeref(dd, b1); + Cudd_RecursiveDeref(dd, b0); + Cudd_RecursiveDeref(dd, bd); + return(NULL); + } + T = Cudd_NotCond(T, T != NULL); + Cudd_Ref(T); + Cudd_RecursiveDeref(dd, b1); + E = cuddBddAndRecur(dd, Cudd_Not(b0), Cudd_Not(bd)); + if (!E) { + Cudd_RecursiveDeref(dd, b0); + Cudd_RecursiveDeref(dd, bd); + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + E = Cudd_NotCond(E, E != NULL); + Cudd_Ref(E); + Cudd_RecursiveDeref(dd, b0); + Cudd_RecursiveDeref(dd, bd); + } + else { + Cudd_RecursiveDerefZdd(dd, fd); + T = b1; + E = b0; + } + + if (Cudd_IsComplement(T)) { + neW = cuddUniqueInterIVO(dd, v / 2, Cudd_Not(T), Cudd_Not(E)); + if (!neW) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + neW = Cudd_Not(neW); + } + else { + neW = cuddUniqueInterIVO(dd, v / 2, T, E); + if (!neW) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + Cudd_Ref(neW); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + + cuddCacheInsert1(dd, cuddMakeBddFromZddCover, node, neW); + Cudd_Deref(neW); + return(neW); + +} /* end of cuddMakeBddFromZddCover */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddLin.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddLin.c new file mode 100644 index 000000000..3fc989d5b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddLin.c @@ -0,0 +1,971 @@ +/**CFile*********************************************************************** + + FileName [cuddZddLin.c] + + PackageName [cudd] + + Synopsis [Procedures for dynamic variable ordering of ZDDs.] + + Description [Internal procedures included in this module: +
          +
        • cuddZddLinearSifting() +
        + Static procedures included in this module: +
          +
        • cuddZddLinearInPlace() +
        • cuddZddLinerAux() +
        • cuddZddLinearUp() +
        • cuddZddLinearDown() +
        • cuddZddLinearBackward() +
        • cuddZddUndoMoves() +
        + ] + + SeeAlso [cuddLinear.c cuddZddReord.c] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define CUDD_SWAP_MOVE 0 +#define CUDD_LINEAR_TRANSFORM_MOVE 1 +#define CUDD_INVERSE_TRANSFORM_MOVE 2 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddLin.c,v 1.16 2012/02/05 01:07:19 fabio Exp $"; +#endif + +extern int *zdd_entry; +extern int zddTotalNumberSwapping; +static int zddTotalNumberLinearTr; +static DdNode *empty; + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddZddLinearInPlace (DdManager * table, int x, int y); +static int cuddZddLinearAux (DdManager *table, int x, int xLow, int xHigh); +static Move * cuddZddLinearUp (DdManager *table, int y, int xLow, Move *prevMoves); +static Move * cuddZddLinearDown (DdManager *table, int x, int xHigh, Move *prevMoves); +static int cuddZddLinearBackward (DdManager *table, int size, Move *moves); +static Move* cuddZddUndoMoves (DdManager *table, Move *moves); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + + + +/**Function******************************************************************** + + Synopsis [Implementation of the linear sifting algorithm for ZDDs.] + + Description [Implementation of the linear sifting algorithm for ZDDs. + Assumes that no dead nodes are present. +
          +
        1. Order all the variables according to the number of entries + in each unique table. +
        2. Sift the variable up and down and applies the XOR transformation, + remembering each time the total size of the DD heap. +
        3. Select the best permutation. +
        4. Repeat 3 and 4 for all variables. +
        + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddLinearSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; +#ifdef DD_STATS + int previousSize; +#endif + + size = table->sizeZ; + empty = table->zero; + + /* Find order in which to sift variables. */ + var = NULL; + zdd_entry = ALLOC(int, size); + if (zdd_entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; + } + var = ALLOC(int, size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; + } + + qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar, size); i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = cuddZddLinearAux(table, x, lower, upper); + if (!result) + goto cuddZddSiftingOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + FREE(var); + FREE(zdd_entry); + + return(1); + +cuddZddSiftingOutOfMem: + + if (zdd_entry != NULL) FREE(zdd_entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddZddLinearSifting */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Linearly combines two adjacent variables.] + + Description [Linearly combines two adjacent variables. It assumes + that no dead nodes are present on entry to this procedure. The + procedure then guarantees that no dead nodes will be present when it + terminates. cuddZddLinearInPlace assumes that x < y. Returns the + number of keys in the table if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddZddSwapInPlace cuddLinearInPlace] + +******************************************************************************/ +static int +cuddZddLinearInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int i; + int posn; + DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; + DdNode *newf1, *newf0, *g, *next, *previous; + DdNode *special; + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddZddNextHigh(table,x) == y); + assert(table->subtableZ[x].keys != 0); + assert(table->subtableZ[y].keys != 0); + assert(table->subtableZ[x].dead == 0); + assert(table->subtableZ[y].dead == 0); +#endif + + zddTotalNumberLinearTr++; + + /* Get parameters of x subtable. */ + xindex = table->invpermZ[x]; + xlist = table->subtableZ[x].nodelist; + oldxkeys = table->subtableZ[x].keys; + xslots = table->subtableZ[x].slots; + xshift = table->subtableZ[x].shift; + newxkeys = 0; + + /* Get parameters of y subtable. */ + yindex = table->invpermZ[y]; + ylist = table->subtableZ[y].nodelist; + oldykeys = table->subtableZ[y].keys; + yslots = table->subtableZ[y].slots; + yshift = table->subtableZ[y].shift; + newykeys = oldykeys; + + /* The nodes in the x layer are put in two chains. The chain + ** pointed by g holds the normal nodes. When re-expressed they stay + ** in the x list. The chain pointed by special holds the elements + ** that will move to the y list. + */ + g = special = NULL; + for (i = 0; i < xslots; i++) { + f = xlist[i]; + if (f == NULL) continue; + xlist[i] = NULL; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); + /* if (f1->index == yindex) */ cuddSatDec(f1->ref); + f0 = cuddE(f); + /* if (f0->index == yindex) */ cuddSatDec(f0->ref); + if ((int) f1->index == yindex && cuddE(f1) == empty && + (int) f0->index != yindex) { + f->next = special; + special = f; + } else { + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ + } /* for each slot of the x subtable */ + + /* Mark y nodes with pointers from above x. We mark them by + ** changing their index to x. + */ + for (i = 0; i < yslots; i++) { + f = ylist[i]; + while (f != NULL) { + if (f->ref != 0) { + f->index = xindex; + } + f = f->next; + } /* while there are elements in the collision chain */ + } /* for each slot of the y subtable */ + + /* Move special nodes to the y list. */ + f = special; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); + f11 = cuddT(f1); + cuddT(f) = f11; + cuddSatInc(f11->ref); + f0 = cuddE(f); + cuddSatInc(f0->ref); + f->index = yindex; + /* Insert at the beginning of the list so that it will be + ** found first if there is a duplicate. The duplicate will + ** eventually be moved or garbage collected. No node + ** re-expression will add a pointer to it. + */ + posn = ddHash(f11, f0, yshift); + f->next = ylist[posn]; + ylist[posn] = f; + newykeys++; + f = next; + } + + /* Take care of the remaining x nodes that must be re-expressed. + ** They form a linked list pointed by g. + */ + f = g; + while (f != NULL) { +#ifdef DD_COUNT + table->swapSteps++; +#endif + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + if ((int) f1->index == yindex || (int) f1->index == xindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = empty; f10 = f1; + } + f0 = cuddE(f); + if ((int) f0->index == yindex || (int) f0->index == xindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = empty; f00 = f0; + } + /* Create the new T child. */ + if (f01 == empty) { + newf1 = f10; + cuddSatInc(newf1->ref); + } else { + /* Check ylist for triple (yindex, f01, f10). */ + posn = ddHash(f01, f10, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + newf1 = ylist[posn]; + /* Search the collision chain skipping the marked nodes. */ + while (newf1 != NULL) { + if (cuddT(newf1) == f01 && cuddE(newf1) == f10 && + (int) newf1->index == yindex) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f01; + cuddE(newf1) = f10; + /* Insert newf1 in the collision list ylist[pos]; + ** increase the ref counts of f01 and f10 + */ + newykeys++; + newf1->next = ylist[posn]; + ylist[posn] = newf1; + cuddSatInc(f01->ref); + cuddSatInc(f10->ref); + } + } + cuddT(f) = newf1; + + /* Do the same for f0. */ + /* Create the new E child. */ + if (f11 == empty) { + newf0 = f00; + cuddSatInc(newf0->ref); + } else { + /* Check ylist for triple (yindex, f11, f00). */ + posn = ddHash(f11, f00, yshift); + /* For each element newf0 in collision list ylist[posn]. */ + newf0 = ylist[posn]; + while (newf0 != NULL) { + if (cuddT(newf0) == f11 && cuddE(newf0) == f00 && + (int) newf0->index == yindex) { + cuddSatInc(newf0->ref); + break; /* match */ + } + newf0 = newf0->next; + } /* while newf0 */ + if (newf0 == NULL) { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto zddSwapOutOfMem; + newf0->index = yindex; newf0->ref = 1; + cuddT(newf0) = f11; cuddE(newf0) = f00; + /* Insert newf0 in the collision list ylist[posn]; + ** increase the ref counts of f11 and f00. + */ + newykeys++; + newf0->next = ylist[posn]; + ylist[posn] = newf0; + cuddSatInc(f11->ref); + cuddSatInc(f00->ref); + } + } + cuddE(f) = newf0; + + /* Re-insert the modified f in xlist. + ** The modified f does not already exists in xlist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, xshift); + newxkeys++; + f->next = xlist[posn]; + xlist[posn] = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer and move the marked nodes to the x list. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previous = NULL; + f = ylist[i]; + while (f != NULL) { + next = f->next; + if (f->ref == 0) { + cuddSatDec(cuddT(f)->ref); + cuddSatDec(cuddE(f)->ref); + cuddDeallocNode(table, f); + newykeys--; + if (previous == NULL) + ylist[i] = next; + else + previous->next = next; + } else if ((int) f->index == xindex) { /* move marked node */ + if (previous == NULL) + ylist[i] = next; + else + previous->next = next; + f1 = cuddT(f); + cuddSatDec(f1->ref); + /* Check ylist for triple (yindex, f1, empty). */ + posn = ddHash(f1, empty, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + newf1 = ylist[posn]; + while (newf1 != NULL) { + if (cuddT(newf1) == f1 && cuddE(newf1) == empty && + (int) newf1->index == yindex) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f1; cuddE(newf1) = empty; + /* Insert newf1 in the collision list ylist[posn]; + ** increase the ref counts of f1 and empty. + */ + newykeys++; + newf1->next = ylist[posn]; + ylist[posn] = newf1; + if (posn == i && previous == NULL) + previous = newf1; + cuddSatInc(f1->ref); + cuddSatInc(empty->ref); + } + cuddT(f) = newf1; + f0 = cuddE(f); + /* Insert f in x list. */ + posn = ddHash(newf1, f0, xshift); + newxkeys++; + newykeys--; + f->next = xlist[posn]; + xlist[posn] = f; + } else { + previous = f; + } + f = next; + } /* while f */ + } /* for i */ + + /* Set the appropriate fields in table. */ + table->subtableZ[x].keys = newxkeys; + table->subtableZ[y].keys = newykeys; + + table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys; + + /* Update univ section; univ[x] remains the same. */ + table->univ[y] = cuddT(table->univ[x]); + +#if 0 + (void) fprintf(table->out,"x = %d y = %d\n", x, y); + (void) Cudd_DebugCheck(table); + (void) Cudd_CheckKeys(table); +#endif + + return (table->keysZ); + +zddSwapOutOfMem: + (void) fprintf(table->err, "Error: cuddZddSwapInPlace out of memory\n"); + + return (0); + +} /* end of cuddZddLinearInPlace */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddLinearAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + Move *move; + Move *moveUp; /* list of up move */ + Move *moveDown; /* list of down move */ + + int initial_size; + int result; + + initial_size = table->keysZ; + +#ifdef DD_DEBUG + assert(table->subtableZ[x].keys > 0); +#endif + + moveDown = NULL; + moveUp = NULL; + + if (x == xLow) { + moveDown = cuddZddLinearDown(table, x, xHigh, NULL); + /* At this point x --> xHigh. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveDown); + if (!result) + goto cuddZddLinearAuxOutOfMem; + + } else if (x == xHigh) { + moveUp = cuddZddLinearUp(table, x, xLow, NULL); + /* At this point x --> xLow. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveUp); + if (!result) + goto cuddZddLinearAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + moveDown = cuddZddLinearDown(table, x, xHigh, NULL); + /* At this point x --> xHigh. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + moveUp = cuddZddUndoMoves(table,moveDown); +#ifdef DD_DEBUG + assert(moveUp == NULL || moveUp->x == x); +#endif + moveUp = cuddZddLinearUp(table, x, xLow, moveUp); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveUp); + if (!result) + goto cuddZddLinearAuxOutOfMem; + + } else { + moveUp = cuddZddLinearUp(table, x, xLow, NULL); + /* At this point x --> xHigh. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Then move up. */ + moveDown = cuddZddUndoMoves(table,moveUp); +#ifdef DD_DEBUG + assert(moveDown == NULL || moveDown->y == x); +#endif + moveDown = cuddZddLinearDown(table, x, xHigh, moveDown); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveDown); + if (!result) + goto cuddZddLinearAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +cuddZddLinearAuxOutOfMem: + if (moveDown != (Move *) CUDD_OUT_OF_MEM) { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + } + if (moveUp != (Move *) CUDD_OUT_OF_MEM) { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + } + + return(0); + +} /* end of cuddZddLinearAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable up applying the XOR transformation.] + + Description [Sifts a variable up applying the XOR + transformation. Moves y up until either it reaches the bound (xLow) + or the size of the ZDD heap increases too much. Returns the set of + moves in case of success; NULL if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddLinearUp( + DdManager * table, + int y, + int xLow, + Move * prevMoves) +{ + Move *moves; + Move *move; + int x; + int size, newsize; + int limitSize; + + moves = prevMoves; + limitSize = table->keysZ; + + x = cuddZddNextLow(table, y); + while (x >= xLow) { + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddLinearUpOutOfMem; + newsize = cuddZddLinearInPlace(table, x, y); + if (newsize == 0) + goto cuddZddLinearUpOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddLinearUpOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize > size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddZddLinearInPlace(table,x,y); + if (newsize == 0) goto cuddZddLinearUpOutOfMem; +#ifdef DD_DEBUG + if (newsize != size) { + (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } +#endif + } else { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + } + move->size = size; + + if ((double)size > (double)limitSize * table->maxGrowth) + break; + if (size < limitSize) + limitSize = size; + + y = x; + x = cuddZddNextLow(table, y); + } + return(moves); + +cuddZddLinearUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of cuddZddLinearUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable down and applies the XOR transformation.] + + Description [Sifts a variable down. Moves x down until either it + reaches the bound (xHigh) or the size of the ZDD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddLinearDown( + DdManager * table, + int x, + int xHigh, + Move * prevMoves) +{ + Move *moves; + Move *move; + int y; + int size, newsize; + int limitSize; + + moves = prevMoves; + limitSize = table->keysZ; + + y = cuddZddNextHigh(table, x); + while (y <= xHigh) { + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddLinearDownOutOfMem; + newsize = cuddZddLinearInPlace(table, x, y); + if (newsize == 0) + goto cuddZddLinearDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddLinearDownOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize > size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddZddLinearInPlace(table,x,y); + if (newsize == 0) goto cuddZddLinearDownOutOfMem; + if (newsize != size) { + (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } + } else { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + } + move->size = size; + + if ((double)size > (double)limitSize * table->maxGrowth) + break; + if (size < limitSize) + limitSize = size; + + x = y; + y = cuddZddNextHigh(table, x); + } + return(moves); + +cuddZddLinearDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of cuddZddLinearDown */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the ZDD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddLinearBackward( + DdManager * table, + int size, + Move * moves) +{ + Move *move; + int res; + + /* Find the minimum size among moves. */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) + return(0); + if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { + res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + } + + return(1); + +} /* end of cuddZddLinearBackward */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the ZDD heap to the order + in effect before the moves.] + + Description [Given a set of moves, returns the ZDD heap to the + order in effect before the moves. Returns 1 in case of success; + 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static Move* +cuddZddUndoMoves( + DdManager * table, + Move * moves) +{ + Move *invmoves = NULL; + Move *move; + Move *invmove; + int size; + + for (move = moves; move != NULL; move = move->next) { + invmove = (Move *) cuddDynamicAllocNode(table); + if (invmove == NULL) goto cuddZddUndoMovesOutOfMem; + invmove->x = move->x; + invmove->y = move->y; + invmove->next = invmoves; + invmoves = invmove; + if (move->flags == CUDD_SWAP_MOVE) { + invmove->flags = CUDD_SWAP_MOVE; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; + size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ +#ifdef DD_DEBUG + (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); +#endif + invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } + invmove->size = size; + } + + return(invmoves); + +cuddZddUndoMovesOutOfMem: + while (invmoves != NULL) { + move = invmoves->next; + cuddDeallocMove(table, invmoves); + invmoves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of cuddZddUndoMoves */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddMisc.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddMisc.c new file mode 100644 index 000000000..ec7686276 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddMisc.c @@ -0,0 +1,278 @@ +/**CFile*********************************************************************** + + FileName [cuddZddMisc.c] + + PackageName [cudd] + + Synopsis [Miscellaneous utility functions for ZDDs.] + + Description [External procedures included in this module: +
          +
        • Cudd_zddDagSize() +
        • Cudd_zddCountMinterm() +
        • Cudd_zddPrintSubtable() +
        + Internal procedures included in this module: +
          +
        + Static procedures included in this module: +
          +
        • cuddZddDagInt() +
        + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddMisc.c,v 1.18 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddZddDagInt (DdNode *n, st_table *tab); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Counts the number of nodes in a ZDD.] + + Description [Counts the number of nodes in a ZDD. This function + duplicates Cudd_DagSize and is only retained for compatibility.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize] + +******************************************************************************/ +int +Cudd_zddDagSize( + DdNode * p_node) +{ + + int i; + st_table *table; + + table = st_init_table(st_ptrcmp, st_ptrhash); + i = cuddZddDagInt(p_node, table); + st_free_table(table); + return(i); + +} /* end of Cudd_zddDagSize */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a ZDD.] + + Description [Counts the number of minterms of the ZDD rooted at + node. This procedure takes a parameter + path that specifies how many variables are in the + support of the function. If the procedure runs out of memory, it + returns (double) CUDD_OUT_OF_MEM.] + + SideEffects [None] + + SeeAlso [Cudd_zddCountDouble] + +******************************************************************************/ +double +Cudd_zddCountMinterm( + DdManager * zdd, + DdNode * node, + int path) +{ + double dc_var, minterms; + + dc_var = (double)((double)(zdd->sizeZ) - (double)path); + minterms = Cudd_zddCountDouble(zdd, node) / pow(2.0, dc_var); + return(minterms); + +} /* end of Cudd_zddCountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints the ZDD table.] + + Description [Prints the ZDD table for debugging purposes.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_zddPrintSubtable( + DdManager * table) +{ + int i, j; + DdNode *z1, *z1_next, *base; + DdSubtable *ZSubTable; + + base = table->one; + for (i = table->sizeZ - 1; i >= 0; i--) { + ZSubTable = &(table->subtableZ[i]); + printf("subtable[%d]:\n", i); + for (j = ZSubTable->slots - 1; j >= 0; j--) { + z1 = ZSubTable->nodelist[j]; + while (z1 != NIL(DdNode)) { + (void) fprintf(table->out, +#if SIZEOF_VOID_P == 8 + "ID = 0x%lx\tindex = %u\tr = %u\t", + (ptruint) z1 / (ptruint) sizeof(DdNode), + z1->index, z1->ref); +#else + "ID = 0x%x\tindex = %hu\tr = %hu\t", + (ptruint) z1 / (ptruint) sizeof(DdNode), + z1->index, z1->ref); +#endif + z1_next = cuddT(z1); + if (Cudd_IsConstant(z1_next)) { + (void) fprintf(table->out, "T = %d\t\t", + (z1_next == base)); + } + else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(table->out, "T = 0x%lx\t", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); +#else + (void) fprintf(table->out, "T = 0x%x\t", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); +#endif + } + z1_next = cuddE(z1); + if (Cudd_IsConstant(z1_next)) { + (void) fprintf(table->out, "E = %d\n", + (z1_next == base)); + } + else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(table->out, "E = 0x%lx\n", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); +#else + (void) fprintf(table->out, "E = 0x%x\n", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); +#endif + } + + z1_next = z1->next; + z1 = z1_next; + } + } + } + putchar('\n'); + +} /* Cudd_zddPrintSubtable */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddDagSize.] + + Description [Performs the recursive step of Cudd_zddDagSize. Does + not check for out-of-memory conditions.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddDagInt( + DdNode * n, + st_table * tab) +{ + if (n == NIL(DdNode)) + return(0); + + if (st_is_member(tab, (char *)n) == 1) + return(0); + + if (Cudd_IsConstant(n)) + return(0); + + (void)st_insert(tab, (char *)n, NIL(char)); + return(1 + cuddZddDagInt(cuddT(n), tab) + + cuddZddDagInt(cuddE(n), tab)); + +} /* cuddZddDagInt */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddPort.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddPort.c new file mode 100644 index 000000000..c661c6a88 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddPort.c @@ -0,0 +1,381 @@ +/**CFile*********************************************************************** + + FileName [cuddZddPort.c] + + PackageName [cudd] + + Synopsis [Functions that translate BDDs to ZDDs.] + + Description [External procedures included in this module: +
          +
        • Cudd_zddPortFromBdd() +
        • Cudd_zddPortToBdd() +
        + Internal procedures included in this module: +
          +
        + Static procedures included in this module: +
          +
        • zddPortFromBddStep() +
        • zddPortToBddStep() +
        + ] + + SeeAlso [] + + Author [Hyong-kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddPort.c,v 1.14 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * zddPortFromBddStep (DdManager *dd, DdNode *B, int expected); +static DdNode * zddPortToBddStep (DdManager *dd, DdNode *f, int depth); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Converts a BDD into a ZDD.] + + Description [Converts a BDD into a ZDD. This function assumes that + there is a one-to-one correspondence between the BDD variables and the + ZDD variables, and that the variable order is the same for both types + of variables. These conditions are established if the ZDD variables + are created by one call to Cudd_zddVarsFromBddVars with multiplicity = + 1. Returns a pointer to the resulting ZDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddVarsFromBddVars] + +******************************************************************************/ +DdNode * +Cudd_zddPortFromBdd( + DdManager * dd, + DdNode * B) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = zddPortFromBddStep(dd,B,0); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_zddPortFromBdd */ + + +/**Function******************************************************************** + + Synopsis [Converts a ZDD into a BDD.] + + Description [Converts a ZDD into a BDD. Returns a pointer to the resulting + ZDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddPortFromBdd] + +******************************************************************************/ +DdNode * +Cudd_zddPortToBdd( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = zddPortToBddStep(dd,f,0); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_zddPortToBdd */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddPortFromBdd.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +zddPortFromBddStep( + DdManager * dd, + DdNode * B, + int expected) +{ + DdNode *res, *prevZdd, *t, *e; + DdNode *Breg, *Bt, *Be; + int id, level; + + statLine(dd); + /* Terminal cases. */ + if (B == Cudd_Not(DD_ONE(dd))) + return(DD_ZERO(dd)); + if (B == DD_ONE(dd)) { + if (expected >= dd->sizeZ) { + return(DD_ONE(dd)); + } else { + return(dd->univ[expected]); + } + } + + Breg = Cudd_Regular(B); + + /* Computed table look-up. */ + res = cuddCacheLookup1Zdd(dd,Cudd_zddPortFromBdd,B); + if (res != NULL) { + level = cuddI(dd,Breg->index); + /* Adding DC vars. */ + if (expected < level) { + /* Add suppressed variables. */ + cuddRef(res); + for (level--; level >= expected; level--) { + prevZdd = res; + id = dd->invperm[level]; + res = cuddZddGetNode(dd, id, prevZdd, prevZdd); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd, prevZdd); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd, prevZdd); + } + cuddDeref(res); + } + return(res); + } /* end of cache look-up */ + + if (Cudd_IsComplement(B)) { + Bt = Cudd_Not(cuddT(Breg)); + Be = Cudd_Not(cuddE(Breg)); + } else { + Bt = cuddT(Breg); + Be = cuddE(Breg); + } + + id = Breg->index; + level = cuddI(dd,id); + t = zddPortFromBddStep(dd, Bt, level+1); + if (t == NULL) return(NULL); + cuddRef(t); + e = zddPortFromBddStep(dd, Be, level+1); + if (e == NULL) { + Cudd_RecursiveDerefZdd(dd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(dd, id, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd, t); + Cudd_RecursiveDerefZdd(dd, e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd, t); + Cudd_RecursiveDerefZdd(dd, e); + + cuddCacheInsert1(dd,Cudd_zddPortFromBdd,B,res); + + for (level--; level >= expected; level--) { + prevZdd = res; + id = dd->invperm[level]; + res = cuddZddGetNode(dd, id, prevZdd, prevZdd); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd, prevZdd); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd, prevZdd); + } + + cuddDeref(res); + return(res); + +} /* end of zddPortFromBddStep */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddPortToBdd.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +zddPortToBddStep( + DdManager * dd /* manager */, + DdNode * f /* ZDD to be converted */, + int depth /* recursion depth */) +{ + DdNode *one, *zero, *T, *E, *res, *var; + unsigned int index; + unsigned int level; + + statLine(dd); + one = DD_ONE(dd); + zero = DD_ZERO(dd); + if (f == zero) return(Cudd_Not(one)); + + if (depth == dd->sizeZ) return(one); + + index = dd->invpermZ[depth]; + level = cuddIZ(dd,f->index); + var = cuddUniqueInter(dd,index,one,Cudd_Not(one)); + if (var == NULL) return(NULL); + cuddRef(var); + + if (level > (unsigned) depth) { + E = zddPortToBddStep(dd,f,depth+1); + if (E == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(E); + res = cuddBddIteRecur(dd,var,Cudd_Not(one),E); + if (res == NULL) { + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,E); + cuddDeref(res); + return(res); + } + + res = cuddCacheLookup1(dd,Cudd_zddPortToBdd,f); + if (res != NULL) { + Cudd_RecursiveDeref(dd,var); + return(res); + } + + T = zddPortToBddStep(dd,cuddT(f),depth+1); + if (T == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(T); + E = zddPortToBddStep(dd,cuddE(f),depth+1); + if (E == NULL) { + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + + res = cuddBddIteRecur(dd,var,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + cuddDeref(res); + + cuddCacheInsert1(dd,Cudd_zddPortToBdd,f,res); + + return(res); + +} /* end of zddPortToBddStep */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddReord.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddReord.c new file mode 100644 index 000000000..c4b67bf84 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddReord.c @@ -0,0 +1,1664 @@ +/**CFile*********************************************************************** + + FileName [cuddZddReord.c] + + PackageName [cudd] + + Synopsis [Procedures for dynamic variable ordering of ZDDs.] + + Description [External procedures included in this module: +
          +
        • Cudd_zddReduceHeap() +
        • Cudd_zddShuffleHeap() +
        + Internal procedures included in this module: +
          +
        • cuddZddAlignToBdd() +
        • cuddZddNextHigh() +
        • cuddZddNextLow() +
        • cuddZddUniqueCompare() +
        • cuddZddSwapInPlace() +
        • cuddZddSwapping() +
        • cuddZddSifting() +
        + Static procedures included in this module: +
          +
        • zddSwapAny() +
        • cuddZddSiftingAux() +
        • cuddZddSiftingUp() +
        • cuddZddSiftingDown() +
        • cuddZddSiftingBackward() +
        • zddReorderPreprocess() +
        • zddReorderPostprocess() +
        • zddShuffle() +
        • zddSiftUp() +
        + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_MAX_SUBTABLE_SPARSITY 8 +#define DD_SHRINK_FACTOR 2 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddReord.c,v 1.49 2012/02/05 01:07:19 fabio Exp $"; +#endif + +int *zdd_entry; + +int zddTotalNumberSwapping; + +static DdNode *empty; + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static Move * zddSwapAny (DdManager *table, int x, int y); +static int cuddZddSiftingAux (DdManager *table, int x, int x_low, int x_high); +static Move * cuddZddSiftingUp (DdManager *table, int x, int x_low, int initial_size); +static Move * cuddZddSiftingDown (DdManager *table, int x, int x_high, int initial_size); +static int cuddZddSiftingBackward (DdManager *table, Move *moves, int size); +static void zddReorderPreprocess (DdManager *table); +static int zddReorderPostprocess (DdManager *table); +static int zddShuffle (DdManager *table, int *permutation); +static int zddSiftUp (DdManager *table, int x, int xLow); +static void zddFixTree (DdManager *table, MtrNode *treenode); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Main dynamic reordering routine for ZDDs.] + + Description [Main dynamic reordering routine for ZDDs. + Calls one of the possible reordering procedures: +
          +
        • Swapping +
        • Sifting +
        • Symmetric Sifting +
        + + For sifting and symmetric sifting it is possible to request reordering + to convergence.

        + + The core of all methods is the reordering procedure + cuddZddSwapInPlace() which swaps two adjacent variables. + Returns 1 in case of success; 0 otherwise. In the case of symmetric + sifting (with and without convergence) returns 1 plus the number of + symmetric variables, in case of success.] + + SideEffects [Changes the variable order for all ZDDs and clears + the cache.] + +******************************************************************************/ +int +Cudd_zddReduceHeap( + DdManager * table /* DD manager */, + Cudd_ReorderingType heuristic /* method used for reordering */, + int minsize /* bound below which no reordering occurs */) +{ + DdHook *hook; + int result; + unsigned int nextDyn; +#ifdef DD_STATS + unsigned int initialSize; + unsigned int finalSize; +#endif + unsigned long localTime; + + /* Don't reorder if there are too many dead nodes. */ + if (table->keysZ - table->deadZ < (unsigned) minsize) + return(1); + + if (heuristic == CUDD_REORDER_SAME) { + heuristic = table->autoMethodZ; + } + if (heuristic == CUDD_REORDER_NONE) { + return(1); + } + + /* This call to Cudd_zddReduceHeap does initiate reordering. Therefore + ** we count it. + */ + table->reorderings++; + empty = table->zero; + + localTime = util_cpu_time(); + + /* Run the hook functions. */ + hook = table->preReorderingHook; + while (hook != NULL) { + int res = (hook->f)(table, "ZDD", (void *)heuristic); + if (res == 0) return(0); + hook = hook->next; + } + + /* Clear the cache and collect garbage. */ + zddReorderPreprocess(table); + zddTotalNumberSwapping = 0; + +#ifdef DD_STATS + initialSize = table->keysZ; + + switch(heuristic) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + (void) fprintf(table->out,"#:I_RANDOM "); + break; + case CUDD_REORDER_SIFT: + case CUDD_REORDER_SIFT_CONVERGE: + case CUDD_REORDER_SYMM_SIFT: + case CUDD_REORDER_SYMM_SIFT_CONV: + (void) fprintf(table->out,"#:I_SIFTING "); + break; + case CUDD_REORDER_LINEAR: + case CUDD_REORDER_LINEAR_CONVERGE: + (void) fprintf(table->out,"#:I_LINSIFT "); + break; + default: + (void) fprintf(table->err,"Unsupported ZDD reordering method\n"); + return(0); + } + (void) fprintf(table->out,"%8d: initial size",initialSize); +#endif + + result = cuddZddTreeSifting(table,heuristic); + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + finalSize = table->keysZ; + (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n", + ((double)(util_cpu_time() - localTime)/1000.0)); + (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n", + zddTotalNumberSwapping); +#endif + + if (result == 0) + return(0); + + if (!zddReorderPostprocess(table)) + return(0); + + if (table->realignZ) { + if (!cuddBddAlignToZdd(table)) + return(0); + } + + nextDyn = table->keysZ * DD_DYN_RATIO; + if (table->reorderings < 20 || nextDyn > table->nextDyn) + table->nextDyn = nextDyn; + else + table->nextDyn += 20; + + table->reordered = 1; + + /* Run hook functions. */ + hook = table->postReorderingHook; + while (hook != NULL) { + int res = (hook->f)(table, "ZDD", (void *)localTime); + if (res == 0) return(0); + hook = hook->next; + } + /* Update cumulative reordering time. */ + table->reordTime += util_cpu_time() - localTime; + + return(result); + +} /* end of Cudd_zddReduceHeap */ + + +/**Function******************************************************************** + + Synopsis [Reorders ZDD variables according to given permutation.] + + Description [Reorders ZDD variables according to given permutation. + The i-th entry of the permutation array contains the index of the variable + that should be brought to the i-th level. The size of the array should be + equal or greater to the number of variables currently in use. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [Changes the ZDD variable order for all diagrams and clears + the cache.] + + SeeAlso [Cudd_zddReduceHeap] + +******************************************************************************/ +int +Cudd_zddShuffleHeap( + DdManager * table /* DD manager */, + int * permutation /* required variable permutation */) +{ + + int result; + + empty = table->zero; + zddReorderPreprocess(table); + + result = zddShuffle(table,permutation); + + if (!zddReorderPostprocess(table)) return(0); + + return(result); + +} /* end of Cudd_zddShuffleHeap */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Reorders ZDD variables according to the order of the BDD + variables.] + + Description [Reorders ZDD variables according to the order of the + BDD variables. This function can be called at the end of BDD + reordering to insure that the order of the ZDD variables is + consistent with the order of the BDD variables. The number of ZDD + variables must be a multiple of the number of BDD variables. Let + M be the ratio of the two numbers. cuddZddAlignToBdd + then considers the ZDD variables from M*i to + (M+1)*i-1 as corresponding to BDD variable + i. This function should be normally called from + Cudd_ReduceHeap, which clears the cache. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [Changes the ZDD variable order for all diagrams and performs + garbage collection of the ZDD unique table.] + + SeeAlso [Cudd_zddShuffleHeap Cudd_ReduceHeap] + +******************************************************************************/ +int +cuddZddAlignToBdd( + DdManager * table /* DD manager */) +{ + int *invpermZ; /* permutation array */ + int M; /* ratio of ZDD variables to BDD variables */ + int i,j; /* loop indices */ + int result; /* return value */ + + /* We assume that a ratio of 0 is OK. */ + if (table->sizeZ == 0) + return(1); + + empty = table->zero; + M = table->sizeZ / table->size; + /* Check whether the number of ZDD variables is a multiple of the + ** number of BDD variables. + */ + if (M * table->size != table->sizeZ) + return(0); + /* Create and initialize the inverse permutation array. */ + invpermZ = ALLOC(int,table->sizeZ); + if (invpermZ == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < table->size; i++) { + int index = table->invperm[i]; + int indexZ = index * M; + int levelZ = table->permZ[indexZ]; + levelZ = (levelZ / M) * M; + for (j = 0; j < M; j++) { + invpermZ[M * i + j] = table->invpermZ[levelZ + j]; + } + } + /* Eliminate dead nodes. Do not scan the cache again, because we + ** assume that Cudd_ReduceHeap has already cleared it. + */ + cuddGarbageCollect(table,0); + + result = zddShuffle(table, invpermZ); + FREE(invpermZ); + /* Fix the ZDD variable group tree. */ + zddFixTree(table,table->treeZ); + return(result); + +} /* end of cuddZddAlignToBdd */ + + +/**Function******************************************************************** + + Synopsis [Finds the next subtable with a larger index.] + + Description [Finds the next subtable with a larger index. Returns the + index.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddNextHigh( + DdManager * table, + int x) +{ + return(x + 1); + +} /* end of cuddZddNextHigh */ + + +/**Function******************************************************************** + + Synopsis [Finds the next subtable with a smaller index.] + + Description [Finds the next subtable with a smaller index. Returns the + index.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddNextLow( + DdManager * table, + int x) +{ + return(x - 1); + +} /* end of cuddZddNextLow */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddUniqueCompare( + int * ptr_x, + int * ptr_y) +{ + return(zdd_entry[*ptr_y] - zdd_entry[*ptr_x]); + +} /* end of cuddZddUniqueCompare */ + + +/**Function******************************************************************** + + Synopsis [Swaps two adjacent variables.] + + Description [Swaps two adjacent variables. It assumes that no dead + nodes are present on entry to this procedure. The procedure then + guarantees that no dead nodes will be present when it terminates. + cuddZddSwapInPlace assumes that x < y. Returns the number of keys in + the table if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddSwapInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int i; + int posn; + DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; + DdNode *newf1, *newf0, *next; + DdNodePtr g, *lastP, *previousP; + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddZddNextHigh(table,x) == y); + assert(table->subtableZ[x].keys != 0); + assert(table->subtableZ[y].keys != 0); + assert(table->subtableZ[x].dead == 0); + assert(table->subtableZ[y].dead == 0); +#endif + + zddTotalNumberSwapping++; + + /* Get parameters of x subtable. */ + xindex = table->invpermZ[x]; + xlist = table->subtableZ[x].nodelist; + oldxkeys = table->subtableZ[x].keys; + xslots = table->subtableZ[x].slots; + xshift = table->subtableZ[x].shift; + newxkeys = 0; + + yindex = table->invpermZ[y]; + ylist = table->subtableZ[y].nodelist; + oldykeys = table->subtableZ[y].keys; + yslots = table->subtableZ[y].slots; + yshift = table->subtableZ[y].shift; + newykeys = oldykeys; + + /* The nodes in the x layer that don't depend on y directly + ** will stay there; the others are put in a chain. + ** The chain is handled as a FIFO; g points to the beginning and + ** last points to the end. + */ + + g = NULL; + lastP = &g; + for (i = 0; i < xslots; i++) { + previousP = &(xlist[i]); + f = *previousP; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if ((f1->index != (DdHalfWord) yindex) && + (f0->index != (DdHalfWord) yindex)) { /* stays */ + newxkeys++; + *previousP = f; + previousP = &(f->next); + } else { + f->index = yindex; + *lastP = f; + lastP = &(f->next); + } + f = next; + } /* while there are elements in the collision chain */ + *previousP = NULL; + } /* for each slot of the x subtable */ + *lastP = NULL; + + +#ifdef DD_COUNT + table->swapSteps += oldxkeys - newxkeys; +#endif + /* Take care of the x nodes that must be re-expressed. + ** They form a linked list pointed by g. Their index has been + ** changed to yindex already. + */ + f = g; + while (f != NULL) { + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = empty; f10 = f1; + } + f0 = cuddE(f); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = empty; f00 = f0; + } + + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == empty) { + if (f01 != empty) { + newf1 = f01; + cuddSatInc(newf1->ref); + } + /* else case was already handled when finding nodes + ** with both children below level y + */ + } else { + /* Check xlist for triple (xindex, f11, f01). */ + posn = ddHash(f11, f01, xshift); + /* For each element newf1 in collision list xlist[posn]. */ + newf1 = xlist[posn]; + while (newf1 != NULL) { + if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = xindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f01; + /* Insert newf1 in the collision list xlist[pos]; + ** increase the ref counts of f11 and f01 + */ + newxkeys++; + newf1->next = xlist[posn]; + xlist[posn] = newf1; + cuddSatInc(f11->ref); + cuddSatInc(f01->ref); + } + } + cuddT(f) = newf1; + + /* Do the same for f0. */ + /* Decrease ref count of f0. */ + cuddSatDec(f0->ref); + /* Create the new E child. */ + if (f10 == empty) { + newf0 = f00; + cuddSatInc(newf0->ref); + } else { + /* Check xlist for triple (xindex, f10, f00). */ + posn = ddHash(f10, f00, xshift); + /* For each element newf0 in collision list xlist[posn]. */ + newf0 = xlist[posn]; + while (newf0 != NULL) { + if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { + cuddSatInc(newf0->ref); + break; /* match */ + } + newf0 = newf0->next; + } /* while newf0 */ + if (newf0 == NULL) { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto zddSwapOutOfMem; + newf0->index = xindex; newf0->ref = 1; + cuddT(newf0) = f10; cuddE(newf0) = f00; + /* Insert newf0 in the collision list xlist[posn]; + ** increase the ref counts of f10 and f00. + */ + newxkeys++; + newf0->next = xlist[posn]; + xlist[posn] = newf0; + cuddSatInc(f10->ref); + cuddSatInc(f00->ref); + } + } + cuddE(f) = newf0; + + /* Insert the modified f in ylist. + ** The modified f does not already exists in ylist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, yshift); + newykeys++; + f->next = ylist[posn]; + ylist[posn] = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previousP = &(ylist[i]); + f = *previousP; + while (f != NULL) { + next = f->next; + if (f->ref == 0) { + cuddSatDec(cuddT(f)->ref); + cuddSatDec(cuddE(f)->ref); + cuddDeallocNode(table, f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = NULL; + } /* for i */ + + /* Set the appropriate fields in table. */ + table->subtableZ[x].nodelist = ylist; + table->subtableZ[x].slots = yslots; + table->subtableZ[x].shift = yshift; + table->subtableZ[x].keys = newykeys; + table->subtableZ[x].maxKeys = yslots * DD_MAX_SUBTABLE_DENSITY; + + table->subtableZ[y].nodelist = xlist; + table->subtableZ[y].slots = xslots; + table->subtableZ[y].shift = xshift; + table->subtableZ[y].keys = newxkeys; + table->subtableZ[y].maxKeys = xslots * DD_MAX_SUBTABLE_DENSITY; + + table->permZ[xindex] = y; table->permZ[yindex] = x; + table->invpermZ[x] = yindex; table->invpermZ[y] = xindex; + + table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys; + + /* Update univ section; univ[x] remains the same. */ + table->univ[y] = cuddT(table->univ[x]); + + return (table->keysZ); + +zddSwapOutOfMem: + (void) fprintf(table->err, "Error: cuddZddSwapInPlace out of memory\n"); + + return (0); + +} /* end of cuddZddSwapInPlace */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables by a sequence of (non-adjacent) swaps.] + + Description [Implementation of Plessier's algorithm that reorders + variables by a sequence of (non-adjacent) swaps. +

          +
        1. Select two variables (RANDOM or HEURISTIC). +
        2. Permute these variables. +
        3. If the nodes have decreased accept the permutation. +
        4. Otherwise reconstruct the original heap. +
        5. Loop. +
        + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddSwapping( + DdManager * table, + int lower, + int upper, + Cudd_ReorderingType heuristic) +{ + int i, j; + int max, keys; + int nvars; + int x, y; + int iterate; + int previousSize; + Move *moves, *move; + int pivot; + int modulo; + int result; + +#ifdef DD_DEBUG + /* Sanity check */ + assert(lower >= 0 && upper < table->sizeZ && lower <= upper); +#endif + + nvars = upper - lower + 1; + iterate = nvars; + + for (i = 0; i < iterate; i++) { + if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { + /* Find pivot <= id with maximum keys. */ + for (max = -1, j = lower; j <= upper; j++) { + if ((keys = table->subtableZ[j].keys) > max) { + max = keys; + pivot = j; + } + } + + modulo = upper - pivot; + if (modulo == 0) { + y = pivot; /* y = nvars-1 */ + } else { + /* y = random # from {pivot+1 .. nvars-1} */ + y = pivot + 1 + (int) (Cudd_Random() % modulo); + } + + modulo = pivot - lower - 1; + if (modulo < 1) { /* if pivot = 1 or 0 */ + x = lower; + } else { + do { /* x = random # from {0 .. pivot-2} */ + x = (int) Cudd_Random() % modulo; + } while (x == y); + /* Is this condition really needed, since x and y + are in regions separated by pivot? */ + } + } else { + x = (int) (Cudd_Random() % nvars) + lower; + do { + y = (int) (Cudd_Random() % nvars) + lower; + } while (x == y); + } + + previousSize = table->keysZ; + moves = zddSwapAny(table, x, y); + if (moves == NULL) + goto cuddZddSwappingOutOfMem; + + result = cuddZddSiftingBackward(table, moves, previousSize); + if (!result) + goto cuddZddSwappingOutOfMem; + + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + return(1); + +cuddZddSwappingOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(0); + +} /* end of cuddZddSwapping */ + + +/**Function******************************************************************** + + Synopsis [Implementation of Rudell's sifting algorithm.] + + Description [Implementation of Rudell's sifting algorithm. + Assumes that no dead nodes are present. +
          +
        1. Order all the variables according to the number of entries + in each unique table. +
        2. Sift the variable up and down, remembering each time the + total size of the DD heap. +
        3. Select the best permutation. +
        4. Repeat 3 and 4 for all variables. +
        + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; +#ifdef DD_STATS + int previousSize; +#endif + + size = table->sizeZ; + + /* Find order in which to sift variables. */ + var = NULL; + zdd_entry = ALLOC(int, size); + if (zdd_entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; + } + var = ALLOC(int, size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; + } + + qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar, size); i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = cuddZddSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSiftingOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + FREE(var); + FREE(zdd_entry); + + return(1); + +cuddZddSiftingOutOfMem: + + if (zdd_entry != NULL) FREE(zdd_entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddZddSifting */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Swaps any two variables.] + + Description [Swaps any two variables. Returns the set of moves.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +zddSwapAny( + DdManager * table, + int x, + int y) +{ + Move *move, *moves; + int tmp, size; + int x_ref, y_ref; + int x_next, y_next; + int limit_size; + + if (x > y) { /* make x precede y */ + tmp = x; x = y; y = tmp; + } + + x_ref = x; y_ref = y; + + x_next = cuddZddNextHigh(table, x); + y_next = cuddZddNextLow(table, y); + moves = NULL; + limit_size = table->keysZ; + + for (;;) { + if (x_next == y_next) { /* x < x_next = y_next < y */ + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, y_next, y); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + + } else if (x == y_next) { /* x = y_next < y = x_next */ + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + } else { + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, y_next, y); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + x = x_next; y = y_next; + } + + x_next = cuddZddNextHigh(table, x); + y_next = cuddZddNextLow(table, y); + if (x_next > y_ref) + break; /* if x == y_ref */ + + if ((double) size > table->maxGrowth * (double) limit_size) + break; + if (size < limit_size) + limit_size = size; + } + if (y_next >= x_ref) { + size = cuddZddSwapInPlace(table, y_next, y); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + } + + return(moves); + +zddSwapAnyOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of zddSwapAny */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSiftingAux( + DdManager * table, + int x, + int x_low, + int x_high) +{ + Move *move; + Move *moveUp; /* list of up move */ + Move *moveDown; /* list of down move */ + + int initial_size; + int result; + + initial_size = table->keysZ; + +#ifdef DD_DEBUG + assert(table->subtableZ[x].keys > 0); +#endif + + moveDown = NULL; + moveUp = NULL; + + if (x == x_low) { + moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); + /* after that point x --> x_high */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveDown, + initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; + + } + else if (x == x_high) { + moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); + /* after that point x --> x_low */ + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveUp, initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; + } + else if ((x - x_low) > (x_high - x)) { + /* must go down first:shorter */ + moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); + /* after that point x --> x_high */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + moveUp = cuddZddSiftingUp(table, moveDown->y, x_low, + initial_size); + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveUp, initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; + } + else { + moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); + /* after that point x --> x_high */ + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + moveDown = cuddZddSiftingDown(table, moveUp->x, x_high, + initial_size); + /* then move up */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveDown, + initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +cuddZddSiftingAuxOutOfMem: + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(0); + +} /* end of cuddZddSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable up.] + + Description [Sifts a variable up. Moves y up until either it reaches + the bound (x_low) or the size of the ZDD heap increases too much. + Returns the set of moves in case of success; NULL if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddSiftingUp( + DdManager * table, + int x, + int x_low, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddZddNextLow(table, x); + while (y >= x_low) { + size = cuddZddSwapInPlace(table, y, x); + if (size == 0) + goto cuddZddSiftingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSiftingUpOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + + if ((double)size > (double)limit_size * table->maxGrowth) + break; + if (size < limit_size) + limit_size = size; + + x = y; + y = cuddZddNextLow(table, x); + } + return(moves); + +cuddZddSiftingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of cuddZddSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable down.] + + Description [Sifts a variable down. Moves x down until either it + reaches the bound (x_high) or the size of the ZDD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddSiftingDown( + DdManager * table, + int x, + int x_high, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddZddNextHigh(table, x); + while (y <= x_high) { + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddSiftingDownOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + if ((double)size > (double)limit_size * table->maxGrowth) + break; + if (size < limit_size) + limit_size = size; + + x = y; + y = cuddZddNextHigh(table, x); + } + return(moves); + +cuddZddSiftingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of cuddZddSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the ZDD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSiftingBackward( + DdManager * table, + Move * moves, + int size) +{ + int i; + int i_best; + Move *move; + int res; + + /* Find the minimum size among moves. */ + i_best = -1; + for (move = moves, i = 0; move != NULL; move = move->next, i++) { + if (move->size < size) { + i_best = i; + size = move->size; + } + } + + for (move = moves, i = 0; move != NULL; move = move->next, i++) { + if (i == i_best) + break; + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) + return(0); + if (i_best == -1 && res == size) + break; + } + + return(1); + +} /* end of cuddZddSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Prepares the ZDD heap for dynamic reordering.] + + Description [Prepares the ZDD heap for dynamic reordering. Does + garbage collection, to guarantee that there are no dead nodes; + and clears the cache, which is invalidated by dynamic reordering.] + + SideEffects [None] + +******************************************************************************/ +static void +zddReorderPreprocess( + DdManager * table) +{ + + /* Clear the cache. */ + cuddCacheFlush(table); + + /* Eliminate dead nodes. Do not scan the cache again. */ + cuddGarbageCollect(table,0); + + return; + +} /* end of ddReorderPreprocess */ + + +/**Function******************************************************************** + + Synopsis [Shrinks almost empty ZDD subtables at the end of reordering + to guarantee that they have a reasonable load factor.] + + Description [Shrinks almost empty subtables at the end of reordering to + guarantee that they have a reasonable load factor. However, if there many + nodes are being reclaimed, then no resizing occurs. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddReorderPostprocess( + DdManager * table) +{ + int i, j, posn; + DdNodePtr *nodelist, *oldnodelist; + DdNode *node, *next; + unsigned int slots, oldslots; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + +#ifdef DD_VERBOSE + (void) fflush(table->out); +#endif + + /* If we have very many reclaimed nodes, we do not want to shrink + ** the subtables, because this will lead to more garbage + ** collections. More garbage collections mean shorter mean life for + ** nodes with zero reference count; hence lower probability of finding + ** a result in the cache. + */ + if (table->reclaimed > table->allocated * 0.5) return(1); + + /* Resize subtables. */ + for (i = 0; i < table->sizeZ; i++) { + int shift; + oldslots = table->subtableZ[i].slots; + if (oldslots < table->subtableZ[i].keys * DD_MAX_SUBTABLE_SPARSITY || + oldslots <= table->initSlots) continue; + oldnodelist = table->subtableZ[i].nodelist; + slots = oldslots >> 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + return(1); + } + table->subtableZ[i].nodelist = nodelist; + table->subtableZ[i].slots = slots; + table->subtableZ[i].shift++; + table->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; +#ifdef DD_VERBOSE + (void) fprintf(table->err, + "shrunk layer %d (%d keys) from %d to %d slots\n", + i, table->subtableZ[i].keys, oldslots, slots); +#endif + + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + shift = table->subtableZ[i].shift; + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + posn = ddHash(cuddT(node), cuddE(node), shift); + node->next = nodelist[posn]; + nodelist[posn] = node; + node = next; + } + } + FREE(oldnodelist); + + table->memused += (slots - oldslots) * sizeof(DdNode *); + table->slots += slots - oldslots; + table->minDead = (unsigned) (table->gcFrac * (double) table->slots); + table->cacheSlack = (int) ddMin(table->maxCacheHard, + DD_MAX_CACHE_TO_SLOTS_RATIO*table->slots) - + 2 * (int) table->cacheSlots; + } + /* We don't look at the constant subtable, because it is not + ** affected by reordering. + */ + + return(1); + +} /* end of zddReorderPostprocess */ + + +/**Function******************************************************************** + + Synopsis [Reorders ZDD variables according to a given permutation.] + + Description [Reorders ZDD variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. zddShuffle assumes that no + dead nodes are present. The reordering is achieved by a series of + upward sifts. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zddShuffle( + DdManager * table, + int * permutation) +{ + int index; + int level; + int position; + int numvars; + int result; +#ifdef DD_STATS + unsigned long localTime; + int initialSize; + int finalSize; + int previousSize; +#endif + + zddTotalNumberSwapping = 0; +#ifdef DD_STATS + localTime = util_cpu_time(); + initialSize = table->keysZ; + (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n", + initialSize); +#endif + + numvars = table->sizeZ; + + for (level = 0; level < numvars; level++) { + index = permutation[level]; + position = table->permZ[index]; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = zddSiftUp(table,position,level); + if (!result) return(0); +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + finalSize = table->keysZ; + (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:T_SHUFFLE %8g: total time (sec)\n", + ((double)(util_cpu_time() - localTime)/1000.0)); + (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n", + zddTotalNumberSwapping); +#endif + + return(1); + +} /* end of zddShuffle */ + + +/**Function******************************************************************** + + Synopsis [Moves one ZDD variable up.] + + Description [Takes a ZDD variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zddSiftUp( + DdManager * table, + int x, + int xLow) +{ + int y; + int size; + + y = cuddZddNextLow(table,x); + while (y >= xLow) { + size = cuddZddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddZddNextLow(table,x); + } + return(1); + +} /* end of zddSiftUp */ + + +/**Function******************************************************************** + + Synopsis [Fixes the ZDD variable group tree after a shuffle.] + + Description [Fixes the ZDD variable group tree after a + shuffle. Assumes that the order of the variables in a terminal node + has not been changed.] + + SideEffects [Changes the ZDD variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static void +zddFixTree( + DdManager * table, + MtrNode * treenode) +{ + if (treenode == NULL) return; + treenode->low = ((int) treenode->index < table->sizeZ) ? + table->permZ[treenode->index] : treenode->index; + if (treenode->child != NULL) { + zddFixTree(table, treenode->child); + } + if (treenode->younger != NULL) + zddFixTree(table, treenode->younger); + if (treenode->parent != NULL && treenode->low < treenode->parent->low) { + treenode->parent->low = treenode->low; + treenode->parent->index = treenode->index; + } + return; + +} /* end of zddFixTree */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddSetop.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddSetop.c new file mode 100644 index 000000000..18cce2c92 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddSetop.c @@ -0,0 +1,1166 @@ +/**CFile*********************************************************************** + + FileName [cuddZddSetop.c] + + PackageName [cudd] + + Synopsis [Set operations on ZDDs.] + + Description [External procedures included in this module: +
          +
        • Cudd_zddIte() +
        • Cudd_zddUnion() +
        • Cudd_zddIntersect() +
        • Cudd_zddDiff() +
        • Cudd_zddDiffConst() +
        • Cudd_zddSubset1() +
        • Cudd_zddSubset0() +
        • Cudd_zddChange() +
        + Internal procedures included in this module: +
          +
        • cuddZddIte() +
        • cuddZddUnion() +
        • cuddZddIntersect() +
        • cuddZddDiff() +
        • cuddZddChangeAux() +
        • cuddZddSubset1() +
        • cuddZddSubset0() +
        + Static procedures included in this module: +
          +
        • zdd_subset1_aux() +
        • zdd_subset0_aux() +
        • zddVarToConst() +
        + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddSetop.c,v 1.26 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * zdd_subset1_aux (DdManager *zdd, DdNode *P, DdNode *zvar); +static DdNode * zdd_subset0_aux (DdManager *zdd, DdNode *P, DdNode *zvar); +static void zddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *base, DdNode *empty); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the ITE of three ZDDs.] + + Description [Computes the ITE of three ZDDs. Returns a pointer to the + result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddIte(dd, f, g, h); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddIte */ + + +/**Function******************************************************************** + + Synopsis [Computes the union of two ZDDs.] + + Description [Computes the union of two ZDDs. Returns a pointer to the + result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddUnion( + DdManager * dd, + DdNode * P, + DdNode * Q) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddUnion(dd, P, Q); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddUnion */ + + +/**Function******************************************************************** + + Synopsis [Computes the intersection of two ZDDs.] + + Description [Computes the intersection of two ZDDs. Returns a pointer to + the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddIntersect( + DdManager * dd, + DdNode * P, + DdNode * Q) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddIntersect(dd, P, Q); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddIntersect */ + + +/**Function******************************************************************** + + Synopsis [Computes the difference of two ZDDs.] + + Description [Computes the difference of two ZDDs. Returns a pointer to the + result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddDiffConst] + +******************************************************************************/ +DdNode * +Cudd_zddDiff( + DdManager * dd, + DdNode * P, + DdNode * Q) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddDiff(dd, P, Q); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddDiff */ + + +/**Function******************************************************************** + + Synopsis [Performs the inclusion test for ZDDs (P implies Q).] + + Description [Inclusion test for ZDDs (P implies Q). No new nodes are + generated by this procedure. Returns empty if true; + a valid pointer different from empty or DD_NON_CONSTANT otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddDiff] + +******************************************************************************/ +DdNode * +Cudd_zddDiffConst( + DdManager * zdd, + DdNode * P, + DdNode * Q) +{ + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *res; + DdManager *table = zdd; + + statLine(zdd); + if (P == empty) + return(empty); + if (Q == empty) + return(P); + if (P == Q) + return(empty); + + /* Check cache. The cache is shared by cuddZddDiff(). */ + res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) + p_top = P->index; + else + p_top = zdd->permZ[P->index]; + if (cuddIsConstant(Q)) + q_top = Q->index; + else + q_top = zdd->permZ[Q->index]; + if (p_top < q_top) { + res = DD_NON_CONSTANT; + } else if (p_top > q_top) { + res = Cudd_zddDiffConst(zdd, P, cuddE(Q)); + } else { + t = Cudd_zddDiffConst(zdd, cuddT(P), cuddT(Q)); + if (t != empty) + res = DD_NON_CONSTANT; + else + res = Cudd_zddDiffConst(zdd, cuddE(P), cuddE(Q)); + } + + cuddCacheInsert2(table, cuddZddDiff, P, Q, res); + + return(res); + +} /* end of Cudd_zddDiffConst */ + + +/**Function******************************************************************** + + Synopsis [Computes the positive cofactor of a ZDD w.r.t. a variable.] + + Description [Computes the positive cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is asserted. Returns a pointer to + the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddSubset0] + +******************************************************************************/ +DdNode * +Cudd_zddSubset1( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *r; + + do { + dd->reordered = 0; + r = cuddZddSubset1(dd, P, var); + } while (dd->reordered == 1); + + return(r); + +} /* end of Cudd_zddSubset1 */ + + +/**Function******************************************************************** + + Synopsis [Computes the negative cofactor of a ZDD w.r.t. a variable.] + + Description [Computes the negative cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is negated. Returns a pointer to + the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddSubset1] + +******************************************************************************/ +DdNode * +Cudd_zddSubset0( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *r; + + do { + dd->reordered = 0; + r = cuddZddSubset0(dd, P, var); + } while (dd->reordered == 1); + + return(r); + +} /* end of Cudd_zddSubset0 */ + + +/**Function******************************************************************** + + Synopsis [Substitutes a variable with its complement in a ZDD.] + + Description [Substitutes a variable with its complement in a ZDD. + returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddChange( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *res; + + if ((unsigned int) var >= CUDD_MAXINDEX - 1) return(NULL); + + do { + dd->reordered = 0; + res = cuddZddChange(dd, P, var); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddChange */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddIte.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *tautology, *empty; + DdNode *r,*Gv,*Gvn,*Hv,*Hvn,*t,*e; + unsigned int topf,topg,toph,v,top; + int index; + + statLine(dd); + /* Trivial cases. */ + /* One variable cases. */ + if (f == (empty = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ + return(h); + } + topf = cuddIZ(dd,f->index); + topg = cuddIZ(dd,g->index); + toph = cuddIZ(dd,h->index); + v = ddMin(topg,toph); + top = ddMin(topf,v); + + tautology = (top == CUDD_MAXINDEX) ? DD_ONE(dd) : dd->univ[top]; + if (f == tautology) { /* ITE(1,G,H) = G */ + return(g); + } + + /* From now on, f is known to not be a constant. */ + zddVarToConst(f,&g,&h,tautology,empty); + + /* Check remaining one variable cases. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } + + if (g == tautology) { /* ITE(F,1,0) = F */ + if (h == empty) return(f); + } + + /* Check cache. */ + r = cuddCacheLookupZdd(dd,DD_ZDD_ITE_TAG,f,g,h); + if (r != NULL) { + return(r); + } + + /* Recompute these because they may have changed in zddVarToConst. */ + topg = cuddIZ(dd,g->index); + toph = cuddIZ(dd,h->index); + v = ddMin(topg,toph); + + if (topf < v) { + r = cuddZddIte(dd,cuddE(f),g,h); + if (r == NULL) return(NULL); + } else if (topf > v) { + if (topg > v) { + Gvn = g; + index = h->index; + } else { + Gvn = cuddE(g); + index = g->index; + } + if (toph > v) { + Hv = empty; Hvn = h; + } else { + Hv = cuddT(h); Hvn = cuddE(h); + } + e = cuddZddIte(dd,f,Gvn,Hvn); + if (e == NULL) return(NULL); + cuddRef(e); + r = cuddZddGetNode(dd,index,Hv,e); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + return(NULL); + } + cuddDeref(e); + } else { + index = f->index; + if (topg > v) { + Gv = empty; Gvn = g; + } else { + Gv = cuddT(g); Gvn = cuddE(g); + } + if (toph > v) { + Hv = empty; Hvn = h; + } else { + Hv = cuddT(h); Hvn = cuddE(h); + } + e = cuddZddIte(dd,cuddE(f),Gvn,Hvn); + if (e == NULL) return(NULL); + cuddRef(e); + t = cuddZddIte(dd,cuddT(f),Gv,Hv); + if (t == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + return(NULL); + } + cuddRef(t); + r = cuddZddGetNode(dd,index,t,e); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + Cudd_RecursiveDerefZdd(dd,t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert(dd,DD_ZDD_ITE_TAG,f,g,h,r); + + return(r); + +} /* end of cuddZddIte */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddUnion.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddUnion( + DdManager * zdd, + DdNode * P, + DdNode * Q) +{ + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; + + statLine(zdd); + if (P == empty) + return(Q); + if (Q == empty) + return(P); + if (P == Q) + return(P); + + /* Check cache */ + res = cuddCacheLookup2Zdd(table, cuddZddUnion, P, Q); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) + p_top = P->index; + else + p_top = zdd->permZ[P->index]; + if (cuddIsConstant(Q)) + q_top = Q->index; + else + q_top = zdd->permZ[Q->index]; + if (p_top < q_top) { + e = cuddZddUnion(zdd, cuddE(P), Q); + if (e == NULL) return (NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, cuddT(P), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); + } else if (p_top > q_top) { + e = cuddZddUnion(zdd, P, cuddE(Q)); + if (e == NULL) return(NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, Q->index, cuddT(Q), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); + } else { + t = cuddZddUnion(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddUnion(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(table, cuddZddUnion, P, Q, res); + + return(res); + +} /* end of cuddZddUnion */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddIntersect.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddIntersect( + DdManager * zdd, + DdNode * P, + DdNode * Q) +{ + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; + + statLine(zdd); + if (P == empty) + return(empty); + if (Q == empty) + return(empty); + if (P == Q) + return(P); + + /* Check cache. */ + res = cuddCacheLookup2Zdd(table, cuddZddIntersect, P, Q); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) + p_top = P->index; + else + p_top = zdd->permZ[P->index]; + if (cuddIsConstant(Q)) + q_top = Q->index; + else + q_top = zdd->permZ[Q->index]; + if (p_top < q_top) { + res = cuddZddIntersect(zdd, cuddE(P), Q); + if (res == NULL) return(NULL); + } else if (p_top > q_top) { + res = cuddZddIntersect(zdd, P, cuddE(Q)); + if (res == NULL) return(NULL); + } else { + t = cuddZddIntersect(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddIntersect(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(table, cuddZddIntersect, P, Q, res); + + return(res); + +} /* end of cuddZddIntersect */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddDiff.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddDiff( + DdManager * zdd, + DdNode * P, + DdNode * Q) +{ + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; + + statLine(zdd); + if (P == empty) + return(empty); + if (Q == empty) + return(P); + if (P == Q) + return(empty); + + /* Check cache. The cache is shared by Cudd_zddDiffConst(). */ + res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q); + if (res != NULL && res != DD_NON_CONSTANT) + return(res); + + if (cuddIsConstant(P)) + p_top = P->index; + else + p_top = zdd->permZ[P->index]; + if (cuddIsConstant(Q)) + q_top = Q->index; + else + q_top = zdd->permZ[Q->index]; + if (p_top < q_top) { + e = cuddZddDiff(zdd, cuddE(P), Q); + if (e == NULL) return(NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, cuddT(P), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); + } else if (p_top > q_top) { + res = cuddZddDiff(zdd, P, cuddE(Q)); + if (res == NULL) return(NULL); + } else { + t = cuddZddDiff(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddDiff(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(table, cuddZddDiff, P, Q, res); + + return(res); + +} /* end of cuddZddDiff */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddChange.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddChangeAux( + DdManager * zdd, + DdNode * P, + DdNode * zvar) +{ + int top_var, level; + DdNode *res, *t, *e; + DdNode *base = DD_ONE(zdd); + DdNode *empty = DD_ZERO(zdd); + + statLine(zdd); + if (P == empty) + return(empty); + if (P == base) + return(zvar); + + /* Check cache. */ + res = cuddCacheLookup2Zdd(zdd, cuddZddChangeAux, P, zvar); + if (res != NULL) + return(res); + + top_var = zdd->permZ[P->index]; + level = zdd->permZ[zvar->index]; + + if (top_var > level) { + res = cuddZddGetNode(zdd, zvar->index, P, DD_ZERO(zdd)); + if (res == NULL) return(NULL); + } else if (top_var == level) { + res = cuddZddGetNode(zdd, zvar->index, cuddE(P), cuddT(P)); + if (res == NULL) return(NULL); + } else { + t = cuddZddChangeAux(zdd, cuddT(P), zvar); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddChangeAux(zdd, cuddE(P), zvar); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(zdd, cuddZddChangeAux, P, zvar, res); + + return(res); + +} /* end of cuddZddChangeAux */ + + +/**Function******************************************************************** + + Synopsis [Computes the positive cofactor of a ZDD w.r.t. a variable.] + + Description [Computes the positive cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is asserted. Returns a pointer to + the result if successful; NULL otherwise. cuddZddSubset1 performs + the same function as Cudd_zddSubset1, but does not restart if + reordering has taken place. Therefore it can be called from within a + recursive procedure.] + + SideEffects [None] + + SeeAlso [cuddZddSubset0 Cudd_zddSubset1] + +******************************************************************************/ +DdNode * +cuddZddSubset1( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *zvar, *r; + DdNode *base, *empty; + + base = DD_ONE(dd); + empty = DD_ZERO(dd); + + zvar = cuddUniqueInterZdd(dd, var, base, empty); + if (zvar == NULL) { + return(NULL); + } else { + cuddRef(zvar); + r = zdd_subset1_aux(dd, P, zvar); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, zvar); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDerefZdd(dd, zvar); + } + + cuddDeref(r); + return(r); + +} /* end of cuddZddSubset1 */ + + +/**Function******************************************************************** + + Synopsis [Computes the negative cofactor of a ZDD w.r.t. a variable.] + + Description [Computes the negative cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is negated. Returns a pointer to + the result if successful; NULL otherwise. cuddZddSubset0 performs + the same function as Cudd_zddSubset0, but does not restart if + reordering has taken place. Therefore it can be called from within a + recursive procedure.] + + SideEffects [None] + + SeeAlso [cuddZddSubset1 Cudd_zddSubset0] + +******************************************************************************/ +DdNode * +cuddZddSubset0( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *zvar, *r; + DdNode *base, *empty; + + base = DD_ONE(dd); + empty = DD_ZERO(dd); + + zvar = cuddUniqueInterZdd(dd, var, base, empty); + if (zvar == NULL) { + return(NULL); + } else { + cuddRef(zvar); + r = zdd_subset0_aux(dd, P, zvar); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, zvar); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDerefZdd(dd, zvar); + } + + cuddDeref(r); + return(r); + +} /* end of cuddZddSubset0 */ + + +/**Function******************************************************************** + + Synopsis [Substitutes a variable with its complement in a ZDD.] + + Description [Substitutes a variable with its complement in a ZDD. + returns a pointer to the result if successful; NULL + otherwise. cuddZddChange performs the same function as + Cudd_zddChange, but does not restart if reordering has taken + place. Therefore it can be called from within a recursive + procedure.] + + SideEffects [None] + + SeeAlso [Cudd_zddChange] + +******************************************************************************/ +DdNode * +cuddZddChange( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *zvar, *res; + + zvar = cuddUniqueInterZdd(dd, var, DD_ONE(dd), DD_ZERO(dd)); + if (zvar == NULL) return(NULL); + cuddRef(zvar); + + res = cuddZddChangeAux(dd, P, zvar); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd,zvar); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd,zvar); + cuddDeref(res); + return(res); + +} /* end of cuddZddChange */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddSubset1.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +zdd_subset1_aux( + DdManager * zdd, + DdNode * P, + DdNode * zvar) +{ + int top_var, level; + DdNode *res, *t, *e; + DdNode *empty; + + statLine(zdd); + empty = DD_ZERO(zdd); + + /* Check cache. */ + res = cuddCacheLookup2Zdd(zdd, zdd_subset1_aux, P, zvar); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) { + res = empty; + cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res); + return(res); + } + + top_var = zdd->permZ[P->index]; + level = zdd->permZ[zvar->index]; + + if (top_var > level) { + res = empty; + } else if (top_var == level) { + res = cuddT(P); + } else { + t = zdd_subset1_aux(zdd, cuddT(P), zvar); + if (t == NULL) return(NULL); + cuddRef(t); + e = zdd_subset1_aux(zdd, cuddE(P), zvar); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res); + + return(res); + +} /* end of zdd_subset1_aux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddSubset0.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +zdd_subset0_aux( + DdManager * zdd, + DdNode * P, + DdNode * zvar) +{ + int top_var, level; + DdNode *res, *t, *e; + + statLine(zdd); + + /* Check cache. */ + res = cuddCacheLookup2Zdd(zdd, zdd_subset0_aux, P, zvar); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) { + res = P; + cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res); + return(res); + } + + top_var = zdd->permZ[P->index]; + level = zdd->permZ[zvar->index]; + + if (top_var > level) { + res = P; + } + else if (top_var == level) { + res = cuddE(P); + } + else { + t = zdd_subset0_aux(zdd, cuddT(P), zvar); + if (t == NULL) return(NULL); + cuddRef(t); + e = zdd_subset0_aux(zdd, cuddE(P), zvar); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res); + + return(res); + +} /* end of zdd_subset0_aux */ + + +/**Function******************************************************************** + + Synopsis [Replaces variables with constants if possible (part of + canonical form).] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +zddVarToConst( + DdNode * f, + DdNode ** gp, + DdNode ** hp, + DdNode * base, + DdNode * empty) +{ + DdNode *g = *gp; + DdNode *h = *hp; + + if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + *gp = base; + } + + if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + *hp = empty; + } + +} /* end of zddVarToConst */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddSymm.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddSymm.c new file mode 100644 index 000000000..559d1a2a5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddSymm.c @@ -0,0 +1,1711 @@ +/**CFile*********************************************************************** + + FileName [cuddZddSymm.c] + + PackageName [cudd] + + Synopsis [Functions for symmetry-based ZDD variable reordering.] + + Description [External procedures included in this module: +
          +
        • Cudd_zddSymmProfile() +
        + Internal procedures included in this module: +
          +
        • cuddZddSymmCheck() +
        • cuddZddSymmSifting() +
        • cuddZddSymmSiftingConv() +
        + Static procedures included in this module: +
          +
        • cuddZddUniqueCompare() +
        • cuddZddSymmSiftingAux() +
        • cuddZddSymmSiftingConvAux() +
        • cuddZddSymmSifting_up() +
        • cuddZddSymmSifting_down() +
        • zdd_group_move() +
        • cuddZddSymmSiftingBackward() +
        • zdd_group_move_backward() +
        + ] + + SeeAlso [cuddSymmetry.c] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define ZDD_MV_OOM (Move *)1 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddSymm.c,v 1.31 2012/02/05 01:07:19 fabio Exp $"; +#endif + +extern int *zdd_entry; + +extern int zddTotalNumberSwapping; + +static DdNode *empty; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddZddSymmSiftingAux (DdManager *table, int x, int x_low, int x_high); +static int cuddZddSymmSiftingConvAux (DdManager *table, int x, int x_low, int x_high); +static Move * cuddZddSymmSifting_up (DdManager *table, int x, int x_low, int initial_size); +static Move * cuddZddSymmSifting_down (DdManager *table, int x, int x_high, int initial_size); +static int cuddZddSymmSiftingBackward (DdManager *table, Move *moves, int size); +static int zdd_group_move (DdManager *table, int x, int y, Move **moves); +static int zdd_group_move_backward (DdManager *table, int x, int y); +static void cuddZddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints statistics on symmetric ZDD variables.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_zddSymmProfile( + DdManager * table, + int lower, + int upper) +{ + int i, x, gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; + + for (i = lower; i < upper; i++) { + if (table->subtableZ[i].next != (unsigned) i) { + x = i; + (void) fprintf(table->out,"Group:"); + do { + (void) fprintf(table->out," %d", table->invpermZ[x]); + TotalSymm++; + gbot = x; + x = table->subtableZ[x].next; + } while (x != i); + TotalSymmGroups++; +#ifdef DD_DEBUG + assert(table->subtableZ[gbot].next == (unsigned) i); +#endif + i = gbot; + (void) fprintf(table->out,"\n"); + } + } + (void) fprintf(table->out,"Total Symmetric = %d\n", TotalSymm); + (void) fprintf(table->out,"Total Groups = %d\n", TotalSymmGroups); + +} /* end of Cudd_zddSymmProfile */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Checks for symmetry of x and y.] + + Description [Checks for symmetry of x and y. Ignores projection + functions, unless they are isolated. Returns 1 in case of + symmetry; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddSymmCheck( + DdManager * table, + int x, + int y) +{ + int i; + DdNode *f, *f0, *f1, *f01, *f00, *f11, *f10; + int yindex; + int xsymmy = 1; + int xsymmyp = 1; + int arccount = 0; + int TotalRefCount = 0; + int symm_found; + + empty = table->zero; + + yindex = table->invpermZ[y]; + for (i = table->subtableZ[x].slots - 1; i >= 0; i--) { + f = table->subtableZ[x].nodelist[i]; + while (f != NULL) { + /* Find f1, f0, f11, f10, f01, f00 */ + f1 = cuddT(f); + f0 = cuddE(f); + if ((int) f1->index == yindex) { + f11 = cuddT(f1); + f10 = cuddE(f1); + if (f10 != empty) + arccount++; + } else { + if ((int) f0->index != yindex) { + return(0); /* f bypasses layer y */ + } + f11 = empty; + f10 = f1; + } + if ((int) f0->index == yindex) { + f01 = cuddT(f0); + f00 = cuddE(f0); + if (f00 != empty) + arccount++; + } else { + f01 = empty; + f00 = f0; + } + if (f01 != f10) + xsymmy = 0; + if (f11 != f00) + xsymmyp = 0; + if ((xsymmy == 0) && (xsymmyp == 0)) + return(0); + + f = f->next; + } /* for each element of the collision list */ + } /* for each slot of the subtable */ + + /* Calculate the total reference counts of y + ** whose else arc is not empty. + */ + for (i = table->subtableZ[y].slots - 1; i >= 0; i--) { + f = table->subtableZ[y].nodelist[i]; + while (f != NIL(DdNode)) { + if (cuddE(f) != empty) + TotalRefCount += f->ref; + f = f->next; + } + } + + symm_found = (arccount == TotalRefCount); +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (symm_found) { + int xindex = table->invpermZ[x]; + (void) fprintf(table->out, + "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); + } +#endif + + return(symm_found); + +} /* end cuddZddSymmCheck */ + + +/**Function******************************************************************** + + Synopsis [Symmetric sifting algorithm for ZDDs.] + + Description [Symmetric sifting algorithm. + Assumes that no dead nodes are present. +
          +
        1. Order all the variables according to the number of entries in + each unique subtable. +
        2. Sift the variable up and down, remembering each time the total + size of the ZDD heap and grouping variables that are symmetric. +
        3. Select the best permutation. +
        4. Repeat 3 and 4 for all variables. +
        + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddZddSymmSiftingConv] + +******************************************************************************/ +int +cuddZddSymmSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int nvars; + int x; + int result; + int symvars; + int symgroups; + int iteration; +#ifdef DD_STATS + int previousSize; +#endif + + nvars = table->sizeZ; + + /* Find order in which to sift variables. */ + var = NULL; + zdd_entry = ALLOC(int, nvars); + if (zdd_entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingOutOfMem; + } + var = ALLOC(int, nvars); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingOutOfMem; + } + + for (i = 0; i < nvars; i++) { + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; + } + + qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); + + /* Initialize the symmetry of each subtable to itself. */ + for (i = lower; i <= upper; i++) + table->subtableZ[i].next = i; + + iteration = ddMin(table->siftMaxVar, nvars); + for (i = 0; i < iteration; i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + if (x < lower || x > upper) continue; + if (table->subtableZ[x].next == (unsigned) x) { + result = cuddZddSymmSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); +#ifdef DD_VERBOSE + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); +#endif + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } + + FREE(var); + FREE(zdd_entry); + + cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups); + +#ifdef DD_STATS + (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n",symvars); + (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n",symgroups); +#endif + + return(1+symvars); + +cuddZddSymmSiftingOutOfMem: + + if (zdd_entry != NULL) + FREE(zdd_entry); + if (var != NULL) + FREE(var); + + return(0); + +} /* end of cuddZddSymmSifting */ + + +/**Function******************************************************************** + + Synopsis [Symmetric sifting to convergence algorithm for ZDDs.] + + Description [Symmetric sifting to convergence algorithm for ZDDs. + Assumes that no dead nodes are present. +
          +
        1. Order all the variables according to the number of entries in + each unique subtable. +
        2. Sift the variable up and down, remembering each time the total + size of the ZDD heap and grouping variables that are symmetric. +
        3. Select the best permutation. +
        4. Repeat 3 and 4 for all variables. +
        5. Repeat 1-4 until no further improvement. +
        + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddZddSymmSifting] + +******************************************************************************/ +int +cuddZddSymmSiftingConv( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int nvars; + int initialSize; + int x; + int result; + int symvars; + int symgroups; + int classes; + int iteration; +#ifdef DD_STATS + int previousSize; +#endif + + initialSize = table->keysZ; + + nvars = table->sizeZ; + + /* Find order in which to sift variables. */ + var = NULL; + zdd_entry = ALLOC(int, nvars); + if (zdd_entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingConvOutOfMem; + } + var = ALLOC(int, nvars); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingConvOutOfMem; + } + + for (i = 0; i < nvars; i++) { + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; + } + + qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); + + /* Initialize the symmetry of each subtable to itself + ** for first pass of converging symmetric sifting. + */ + for (i = lower; i <= upper; i++) + table->subtableZ[i].next = i; + + iteration = ddMin(table->siftMaxVar, table->sizeZ); + for (i = 0; i < iteration; i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; + /* Only sift if not in symmetry group already. */ + if (table->subtableZ[x].next == (unsigned) x) { +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = cuddZddSymmSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingConvOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); +#ifdef DD_VERBOSE + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); +#endif + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } + + /* Sifting now until convergence. */ + while ((unsigned) initialSize > table->keysZ) { + initialSize = table->keysZ; +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + /* Here we consider only one representative for each symmetry class. */ + for (x = lower, classes = 0; x <= upper; x++, classes++) { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + /* Here x is the largest index in a group. + ** Groups consists of adjacent variables. + ** Hence, the next increment of x will move it to a new group. + */ + i = table->invpermZ[x]; + zdd_entry[i] = table->subtableZ[x].keys; + var[classes] = i; + } + + qsort((void *)var,classes,sizeof(int),(DD_QSFP)cuddZddUniqueCompare); + + /* Now sift. */ + iteration = ddMin(table->siftMaxVar, nvars); + for (i = 0; i < iteration; i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; + if ((unsigned) x >= table->subtableZ[x].next) { +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = cuddZddSymmSiftingConvAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingConvOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); +#ifdef DD_VERBOSE + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); +#endif + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } /* for */ + } + + cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups); + +#ifdef DD_STATS + (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n", + symvars); + (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n", + symgroups); +#endif + + FREE(var); + FREE(zdd_entry); + + return(1+symvars); + +cuddZddSymmSiftingConvOutOfMem: + + if (zdd_entry != NULL) + FREE(zdd_entry); + if (var != NULL) + FREE(var); + + return(0); + +} /* end of cuddZddSymmSiftingConv */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Given x_low <= x <= x_high moves x up and down between the + boundaries.] + + Description [Given x_low <= x <= x_high moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is not part of a symmetry group. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSymmSiftingAux( + DdManager * table, + int x, + int x_low, + int x_high) +{ + Move *move; + Move *move_up; /* list of up move */ + Move *move_down; /* list of down move */ + int initial_size; + int result; + int i; + int topbot; /* index to either top or bottom of symmetry group */ + int init_group_size, final_group_size; + + initial_size = table->keysZ; + + move_down = NULL; + move_up = NULL; + + /* Look for consecutive symmetries above x. */ + for (i = x; i > x_low; i--) { + if (!cuddZddSymmCheck(table, i - 1, i)) + break; + /* find top of i-1's symmetry */ + topbot = table->subtableZ[i - 1].next; + table->subtableZ[i - 1].next = i; + table->subtableZ[x].next = topbot; + /* x is bottom of group so its symmetry is top of i-1's + group */ + i = topbot + 1; /* add 1 for i--, new i is top of symm group */ + } + /* Look for consecutive symmetries below x. */ + for (i = x; i < x_high; i++) { + if (!cuddZddSymmCheck(table, i, i + 1)) + break; + /* find bottom of i+1's symm group */ + topbot = i + 1; + while ((unsigned) topbot < table->subtableZ[topbot].next) + topbot = table->subtableZ[topbot].next; + + table->subtableZ[topbot].next = table->subtableZ[i].next; + table->subtableZ[i].next = i + 1; + i = topbot - 1; /* add 1 for i++, + new i is bottom of symm group */ + } + + /* Now x maybe in the middle of a symmetry group. */ + if (x == x_low) { /* Sift down */ + /* Find bottom of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + + i = table->subtableZ[x].next; + init_group_size = x - i + 1; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) + x = move_down->y; + else + x = table->subtableZ[x].next; + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, + move_down, initial_size); + } + else { + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; + } + else if (x == x_high) { /* Sift up */ + /* Find top of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_low, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) + x = move_up->x; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; + } + else if ((x - x_low) > (x_high - x)) { /* must go down first: + shorter */ + /* Find bottom of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_down != NULL) { + x = move_down->y; + } + else { + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; + } + else { /* moving up first:shorter */ + /* Find top of x's symmetry group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_high, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + init_group_size = x - i + 1; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) { + x = move_down->y; + } + else { + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetries detected, + go back to best position */ + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + else { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; + } + + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + + return(1); + +cuddZddSymmSiftingAuxOutOfMem: + if (move_down != ZDD_MV_OOM) { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + } + if (move_up != ZDD_MV_OOM) { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + } + + return(0); + +} /* end of cuddZddSymmSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Given x_low <= x <= x_high moves x up and down between the + boundaries.] + + Description [Given x_low <= x <= x_high moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is either an isolated variable, or it is the bottom of + a symmetry group. All symmetries may not have been found, because of + exceeded growth limit. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSymmSiftingConvAux( + DdManager * table, + int x, + int x_low, + int x_high) +{ + Move *move; + Move *move_up; /* list of up move */ + Move *move_down; /* list of down move */ + int initial_size; + int result; + int i; + int init_group_size, final_group_size; + + initial_size = table->keysZ; + + move_down = NULL; + move_up = NULL; + + if (x == x_low) { /* Sift down */ + i = table->subtableZ[x].next; + init_group_size = x - i + 1; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) + x = move_down->y; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetries detected, + go back to best position */ + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + else { + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; + } + else if (x == x_high) { /* Sift up */ + /* Find top of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_low, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) + x = move_up->x; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; + } + else if ((x - x_low) > (x_high - x)) { /* must go down first: + shorter */ + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_down != NULL) { + x = move_down->y; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; + } + else { /* moving up first:shorter */ + /* Find top of x's symmetry group */ + x = table->subtableZ[x].next; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_high, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + init_group_size = x - i + 1; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) { + x = move_down->y; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetries detected, + go back to best position */ + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + else { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; + } + + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + + return(1); + +cuddZddSymmSiftingConvAuxOutOfMem: + if (move_down != ZDD_MV_OOM) { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + } + if (move_up != ZDD_MV_OOM) { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + } + + return(0); + +} /* end of cuddZddSymmSiftingConvAux */ + + +/**Function******************************************************************** + + Synopsis [Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much.] + + Description [Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much. Assumes that x is the top + of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; ZDD_MV_OOM if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddSymmSifting_up( + DdManager * table, + int x, + int x_low, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + int i, gytop; + + moves = NULL; + y = cuddZddNextLow(table, x); + while (y >= x_low) { + gytop = table->subtableZ[y].next; + if (cuddZddSymmCheck(table, y, x)) { + /* Symmetry found, attach symm groups */ + table->subtableZ[y].next = x; + i = table->subtableZ[x].next; + while (table->subtableZ[i].next != (unsigned) x) + i = table->subtableZ[i].next; + table->subtableZ[i].next = gytop; + } + else if ((table->subtableZ[x].next == (unsigned) x) && + (table->subtableZ[y].next == (unsigned) y)) { + /* x and y have self symmetry */ + size = cuddZddSwapInPlace(table, y, x); + if (size == 0) + goto cuddZddSymmSifting_upOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSymmSifting_upOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + else { /* Group move */ + size = zdd_group_move(table, y, x, &moves); + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + x = gytop; + y = cuddZddNextLow(table, x); + } + + return(moves); + +cuddZddSymmSifting_upOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(ZDD_MV_OOM); + +} /* end of cuddZddSymmSifting_up */ + + +/**Function******************************************************************** + + Synopsis [Moves x down until either it reaches the bound (x_high) or + the size of the ZDD heap increases too much.] + + Description [Moves x down until either it reaches the bound (x_high) + or the size of the ZDD heap increases too much. Assumes that x is the + bottom of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; ZDD_MV_OOM if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddSymmSifting_down( + DdManager * table, + int x, + int x_high, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + int i, gxtop, gybot; + + moves = NULL; + y = cuddZddNextHigh(table, x); + while (y <= x_high) { + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + if (cuddZddSymmCheck(table, x, y)) { + /* Symmetry found, attach symm groups */ + gxtop = table->subtableZ[x].next; + table->subtableZ[x].next = y; + i = table->subtableZ[y].next; + while (table->subtableZ[i].next != (unsigned) y) + i = table->subtableZ[i].next; + table->subtableZ[i].next = gxtop; + } + else if ((table->subtableZ[x].next == (unsigned) x) && + (table->subtableZ[y].next == (unsigned) y)) { + /* x and y have self symmetry */ + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddSymmSifting_downOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSymmSifting_downOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + x = y; + y = cuddZddNextHigh(table, x); + } + else { /* Group move */ + size = zdd_group_move(table, x, y, &moves); + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + x = gybot; + y = cuddZddNextHigh(table, x); + } + + return(moves); + +cuddZddSymmSifting_downOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(ZDD_MV_OOM); + +} /* end of cuddZddSymmSifting_down */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the ZDD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSymmSiftingBackward( + DdManager * table, + Move * moves, + int size) +{ + int i; + int i_best; + Move *move; + int res; + + i_best = -1; + for (move = moves, i = 0; move != NULL; move = move->next, i++) { + if (move->size < size) { + i_best = i; + size = move->size; + } + } + + for (move = moves, i = 0; move != NULL; move = move->next, i++) { + if (i == i_best) break; + if ((table->subtableZ[move->x].next == move->x) && + (table->subtableZ[move->y].next == move->y)) { + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) return(0); + } + else { /* Group move necessary */ + res = zdd_group_move_backward(table, move->x, move->y); + } + if (i_best == -1 && res == size) + break; + } + + return(1); + +} /* end of cuddZddSymmSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Swaps two groups.] + + Description [Swaps two groups. x is assumed to be the bottom variable + of the first group. y is assumed to be the top variable of the second + group. Updates the list of moves. Returns the number of keys in the + table if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zdd_group_move( + DdManager * table, + int x, + int y, + Move ** moves) +{ + Move *move; + int size; + int i, temp, gxtop, gxbot, gybot, yprev; + int swapx, swapy; + +#ifdef DD_DEBUG + assert(x < y); /* we assume that x < y */ +#endif + /* Find top and bottom for the two groups. */ + gxtop = table->subtableZ[x].next; + gxbot = x; + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + yprev = gybot; + + while (x <= y) { + while (y > gxtop) { + /* Set correct symmetries. */ + temp = table->subtableZ[x].next; + if (temp == x) + temp = y; + i = gxtop; + for (;;) { + if (table->subtableZ[i].next == (unsigned) x) { + table->subtableZ[i].next = y; + break; + } else { + i = table->subtableZ[i].next; + } + } + if (table->subtableZ[y].next != (unsigned) y) { + table->subtableZ[x].next = table->subtableZ[y].next; + } else { + table->subtableZ[x].next = x; + } + + if (yprev != y) { + table->subtableZ[yprev].next = x; + } else { + yprev = x; + } + table->subtableZ[y].next = temp; + + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto zdd_group_moveOutOfMem; + swapx = x; + swapy = y; + y = x; + x--; + } /* while y > gxtop */ + + /* Trying to find the next y. */ + if (table->subtableZ[y].next <= (unsigned) y) { + gybot = y; + } else { + y = table->subtableZ[y].next; + } + + yprev = gxtop; + gxtop++; + gxbot++; + x = gxbot; + } /* while x <= y, end of group movement */ + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zdd_group_moveOutOfMem; + move->x = swapx; + move->y = swapy; + move->size = table->keysZ; + move->next = *moves; + *moves = move; + + return(table->keysZ); + +zdd_group_moveOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of zdd_group_move */ + + +/**Function******************************************************************** + + Synopsis [Undoes the swap of two groups.] + + Description [Undoes the swap of two groups. x is assumed to be the + bottom variable of the first group. y is assumed to be the top + variable of the second group. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zdd_group_move_backward( + DdManager * table, + int x, + int y) +{ + int size; + int i, temp, gxtop, gxbot, gybot, yprev; + +#ifdef DD_DEBUG + assert(x < y); /* we assume that x < y */ +#endif + /* Find top and bottom of the two groups. */ + gxtop = table->subtableZ[x].next; + gxbot = x; + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + yprev = gybot; + + while (x <= y) { + while (y > gxtop) { + /* Set correct symmetries. */ + temp = table->subtableZ[x].next; + if (temp == x) + temp = y; + i = gxtop; + for (;;) { + if (table->subtableZ[i].next == (unsigned) x) { + table->subtableZ[i].next = y; + break; + } else { + i = table->subtableZ[i].next; + } + } + if (table->subtableZ[y].next != (unsigned) y) { + table->subtableZ[x].next = table->subtableZ[y].next; + } else { + table->subtableZ[x].next = x; + } + + if (yprev != y) { + table->subtableZ[yprev].next = x; + } else { + yprev = x; + } + table->subtableZ[y].next = temp; + + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + return(0); + y = x; + x--; + } /* while y > gxtop */ + + /* Trying to find the next y. */ + if (table->subtableZ[y].next <= (unsigned) y) { + gybot = y; + } else { + y = table->subtableZ[y].next; + } + + yprev = gxtop; + gxtop++; + gxbot++; + x = gxbot; + } /* while x <= y, end of group movement backward */ + + return(size); + +} /* end of zdd_group_move_backward */ + + +/**Function******************************************************************** + + Synopsis [Counts numbers of symmetric variables and symmetry + groups.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static void +cuddZddSymmSummary( + DdManager * table, + int lower, + int upper, + int * symvars, + int * symgroups) +{ + int i,x,gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; + + for (i = lower; i <= upper; i++) { + if (table->subtableZ[i].next != (unsigned) i) { + TotalSymmGroups++; + x = i; + do { + TotalSymm++; + gbot = x; + x = table->subtableZ[x].next; + } while (x != i); +#ifdef DD_DEBUG + assert(table->subtableZ[gbot].next == (unsigned) i); +#endif + i = gbot; + } + } + *symvars = TotalSymm; + *symgroups = TotalSymmGroups; + + return; + +} /* end of cuddZddSymmSummary */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddUtil.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddUtil.c new file mode 100644 index 000000000..aecb93ee4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddUtil.c @@ -0,0 +1,1205 @@ +/**CFile*********************************************************************** + + FileName [cuddZddUtil.c] + + PackageName [cudd] + + Synopsis [Utility functions for ZDDs.] + + Description [External procedures included in this module: +
          +
        • Cudd_zddPrintMinterm() +
        • Cudd_zddPrintCover() +
        • Cudd_zddPrintDebug() +
        • Cudd_zddFirstPath() +
        • Cudd_zddNextPath() +
        • Cudd_zddCoverPathToString() +
        • Cudd_zddSupport() +
        • Cudd_zddDumpDot() +
        + Internal procedures included in this module: +
          +
        • cuddZddP() +
        + Static procedures included in this module: +
          +
        • zp2() +
        • zdd_print_minterm_aux() +
        • zddPrintCoverAux() +
        • zddSupportStep() +
        • zddClearFlag() +
        + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.29 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int zp2 (DdManager *zdd, DdNode *f, st_table *t); +static void zdd_print_minterm_aux (DdManager *zdd, DdNode *node, int level, int *list); +static void zddPrintCoverAux (DdManager *zdd, DdNode *node, int level, int *list); +static void zddSupportStep(DdNode * f, int * support); +static void zddClearFlag(DdNode * f); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints a disjoint sum of product form for a ZDD.] + + Description [Prints a disjoint sum of product form for a ZDD. Returns 1 + if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddPrintDebug Cudd_zddPrintCover] + +******************************************************************************/ +int +Cudd_zddPrintMinterm( + DdManager * zdd, + DdNode * node) +{ + int i, size; + int *list; + + size = (int)zdd->sizeZ; + list = ALLOC(int, size); + if (list == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ + zdd_print_minterm_aux(zdd, node, 0, list); + FREE(list); + return(1); + +} /* end of Cudd_zddPrintMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints a sum of products from a ZDD representing a cover.] + + Description [Prints a sum of products from a ZDD representing a cover. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddPrintMinterm] + +******************************************************************************/ +int +Cudd_zddPrintCover( + DdManager * zdd, + DdNode * node) +{ + int i, size; + int *list; + + size = (int)zdd->sizeZ; + if (size % 2 != 0) return(0); /* number of variables should be even */ + list = ALLOC(int, size); + if (list == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ + zddPrintCoverAux(zdd, node, 0, list); + FREE(list); + return(1); + +} /* end of Cudd_zddPrintCover */ + + +/**Function******************************************************************** + + Synopsis [Prints to the standard output a ZDD and its statistics.] + + Description [Prints to the standard output a DD and its statistics. + The statistics include the number of nodes and the number of minterms. + (The number of minterms is also the number of combinations in the set.) + The statistics are printed if pr > 0. Specifically: +
          +
        • pr = 0 : prints nothing +
        • pr = 1 : prints counts of nodes and minterms +
        • pr = 2 : prints counts + disjoint sum of products +
        • pr = 3 : prints counts + list of nodes +
        • pr > 3 : prints counts + disjoint sum of products + list of nodes +
        + Returns 1 if successful; 0 otherwise. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_zddPrintDebug( + DdManager * zdd, + DdNode * f, + int n, + int pr) +{ + DdNode *empty = DD_ZERO(zdd); + int nodes; + double minterms; + int retval = 1; + + if (f == empty && pr > 0) { + (void) fprintf(zdd->out,": is the empty ZDD\n"); + (void) fflush(zdd->out); + return(1); + } + + if (pr > 0) { + nodes = Cudd_zddDagSize(f); + if (nodes == CUDD_OUT_OF_MEM) retval = 0; + minterms = Cudd_zddCountMinterm(zdd, f, n); + if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; + (void) fprintf(zdd->out,": %d nodes %g minterms\n", + nodes, minterms); + if (pr > 2) + if (!cuddZddP(zdd, f)) retval = 0; + if (pr == 2 || pr > 3) { + if (!Cudd_zddPrintMinterm(zdd, f)) retval = 0; + (void) fprintf(zdd->out,"\n"); + } + (void) fflush(zdd->out); + } + return(retval); + +} /* end of Cudd_zddPrintDebug */ + + + +/**Function******************************************************************** + + Synopsis [Finds the first path of a ZDD.] + + Description [Defines an iterator on the paths of a ZDD + and finds its first path. Returns a generator that contains the + information necessary to continue the enumeration if successful; NULL + otherwise.

        + A path is represented as an array of literals, which are integers in + {0, 1, 2}; 0 represents an else arc out of a node, 1 represents a then arc + out of a node, and 2 stands for the absence of a node. + The size of the array equals the number of variables in the manager at + the time Cudd_zddFirstCube is called.

        + The paths that end in the empty terminal are not enumerated.] + + SideEffects [The first path is returned as a side effect.] + + SeeAlso [Cudd_zddForeachPath Cudd_zddNextPath Cudd_GenFree + Cudd_IsGenEmpty] + +******************************************************************************/ +DdGen * +Cudd_zddFirstPath( + DdManager * zdd, + DdNode * f, + int ** path) +{ + DdGen *gen; + DdNode *top, *next, *prev; + int i; + int nvars; + + /* Sanity Check. */ + if (zdd == NULL || f == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ALLOC(DdGen,1); + if (gen == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = zdd; + gen->type = CUDD_GEN_ZDD_PATHS; + gen->status = CUDD_GEN_EMPTY; + gen->gen.cubes.cube = NULL; + gen->gen.cubes.value = DD_ZERO_VAL; + gen->stack.sp = 0; + gen->stack.stack = NULL; + gen->node = NULL; + + nvars = zdd->sizeZ; + gen->gen.cubes.cube = ALLOC(int,nvars); + if (gen->gen.cubes.cube == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + FREE(gen); + return(NULL); + } + for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; + + /* The maximum stack depth is one plus the number of variables. + ** because a path may have nodes at all levels, including the + ** constant level. + */ + gen->stack.stack = ALLOC(DdNodePtr, nvars+1); + if (gen->stack.stack == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + FREE(gen->gen.cubes.cube); + FREE(gen); + return(NULL); + } + for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; + + /* Find the first path of the ZDD. */ + gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; + + while (1) { + top = gen->stack.stack[gen->stack.sp-1]; + if (!cuddIsConstant(Cudd_Regular(top))) { + /* Take the else branch first. */ + gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; + next = cuddE(Cudd_Regular(top)); + gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; + } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { + /* Backtrack. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); + next = cuddT(prev); + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[prev->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[prev->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(Cudd_Regular(top)); + goto done; + } + } + +done: + *path = gen->gen.cubes.cube; + return(gen); + +} /* end of Cudd_zddFirstPath */ + + +/**Function******************************************************************** + + Synopsis [Generates the next path of a ZDD.] + + Description [Generates the next path of a ZDD onset, + using generator gen. Returns 0 if the enumeration is completed; 1 + otherwise.] + + SideEffects [The path is returned as a side effect. The + generator is modified.] + + SeeAlso [Cudd_zddForeachPath Cudd_zddFirstPath Cudd_GenFree + Cudd_IsGenEmpty] + +******************************************************************************/ +int +Cudd_zddNextPath( + DdGen * gen, + int ** path) +{ + DdNode *top, *next, *prev; + DdManager *zdd = gen->manager; + + /* Backtrack from previously reached terminal node. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + top = gen->stack.stack[gen->stack.sp-1]; + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); + next = cuddT(prev); + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[prev->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[prev->index] = 2; + gen->stack.sp--; + } + + while (1) { + top = gen->stack.stack[gen->stack.sp-1]; + if (!cuddIsConstant(Cudd_Regular(top))) { + /* Take the else branch first. */ + gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; + next = cuddE(Cudd_Regular(top)); + gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; + } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { + /* Backtrack. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); + next = cuddT(prev); + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[prev->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[prev->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(Cudd_Regular(top)); + goto done; + } + } + +done: + if (gen->status == CUDD_GEN_EMPTY) return(0); + *path = gen->gen.cubes.cube; + return(1); + +} /* end of Cudd_zddNextPath */ + + +/**Function******************************************************************** + + Synopsis [Converts a path of a ZDD representing a cover to a string.] + + Description [Converts a path of a ZDD representing a cover to a + string. The string represents an implicant of the cover. The path + is typically produced by Cudd_zddForeachPath. Returns a pointer to + the string if successful; NULL otherwise. If the str input is NULL, + it allocates a new string. The string passed to this function must + have enough room for all variables and for the terminator.] + + SideEffects [None] + + SeeAlso [Cudd_zddForeachPath] + +******************************************************************************/ +char * +Cudd_zddCoverPathToString( + DdManager *zdd /* DD manager */, + int *path /* path of ZDD representing a cover */, + char *str /* pointer to string to use if != NULL */ + ) +{ + int nvars = zdd->sizeZ; + int i; + char *res; + + if (nvars & 1) return(NULL); + nvars >>= 1; + if (str == NULL) { + res = ALLOC(char, nvars+1); + if (res == NULL) return(NULL); + } else { + res = str; + } + for (i = 0; i < nvars; i++) { + int v = (path[2*i] << 2) | path[2*i+1]; + switch (v) { + case 0: + case 2: + case 8: + case 10: + res[i] = '-'; + break; + case 1: + case 9: + res[i] = '0'; + break; + case 4: + case 6: + res[i] = '1'; + break; + default: + res[i] = '?'; + } + } + res[nvars] = 0; + + return(res); + +} /* end of Cudd_zddCoverPathToString */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a ZDD depends.] + + Description [Finds the variables on which a ZDD depends. + Returns a BDD consisting of the product of the variables if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Support] + +******************************************************************************/ +DdNode * +Cudd_zddSupport( + DdManager * dd /* manager */, + DdNode * f /* ZDD whose support is sought */) +{ + int *support; + DdNode *res, *tmp, *var; + int i,j; + int size; + + /* Allocate and initialize support array for ddSupportStep. */ + size = ddMax(dd->size, dd->sizeZ); + support = ALLOC(int,size); + if (support == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + support[i] = 0; + } + + /* Compute support and clean up markers. */ + zddSupportStep(Cudd_Regular(f),support); + zddClearFlag(Cudd_Regular(f)); + + /* Transform support from array to cube. */ + do { + dd->reordered = 0; + res = DD_ONE(dd); + cuddRef(res); + for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ + i = (j >= dd->size) ? j : dd->invperm[j]; + if (support[i] == 1) { + /* The following call to cuddUniqueInter is guaranteed + ** not to trigger reordering because the node we look up + ** already exists. */ + var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + cuddRef(var); + tmp = cuddBddAndRecur(dd,res,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + res = NULL; + break; + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + res = tmp; + } + } + } while (dd->reordered == 1); + + FREE(support); + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_zddSupport */ + + +/**Function******************************************************************** + + Synopsis [Writes a dot file representing the argument ZDDs.] + + Description [Writes a file representing the argument ZDDs in a format + suitable for the graph drawing program dot. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, + file system full). + Cudd_zddDumpDot does not close the file: This is the caller + responsibility. Cudd_zddDumpDot uses a minimal unique subset of the + hexadecimal address of a node as name for it. + If the argument inames is non-null, it is assumed to hold the pointers + to the names of the inputs. Similarly for onames. + Cudd_zddDumpDot uses the following convention to draw arcs: +

          +
        • solid line: THEN arcs; +
        • dashed line: ELSE arcs. +
        + The dot options are chosen so that the drawing fits on a letter-size + sheet. + ] + + SideEffects [None] + + SeeAlso [Cudd_DumpDot Cudd_zddPrintDebug] + +******************************************************************************/ +int +Cudd_zddDumpDot( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->sizeZ; + st_table *visited = NULL; + st_generator *gen; + int retval; + int i, j; + int slots; + DdNodePtr *nodelist; + long refAddr, diff, mask; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int,nvars); + if (sorted == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; + } + for (i = 0; i < nvars; i++) sorted[i] = 0; + + /* Take the union of the supports of each output function. */ + for (i = 0; i < n; i++) { + support = Cudd_zddSupport(dd,f[i]); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + } + support = NULL; /* so that we do not try to free it in case of failure */ + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Collect all the nodes of this DD in the symbol table. */ + for (i = 0; i < n; i++) { + retval = cuddCollectNodes(f[i],visited); + if (retval == 0) goto failure; + } + + /* Find how many most significant hex digits are identical + ** in the addresses of all the nodes. Build a mask based + ** on this knowledge, so that digits that carry no information + ** will not be printed. This is done in two steps. + ** 1. We scan the symbol table to find the bits that differ + ** in at least 2 addresses. + ** 2. We choose one of the possible masks. There are 8 possible + ** masks for 32-bit integer, and 16 possible masks for 64-bit + ** integers. + */ + + /* Find the bits that are different. */ + refAddr = (long) f[0]; + diff = 0; + gen = st_init_gen(visited); + while (st_gen(gen, &scan, NULL)) { + diff |= refAddr ^ (long) scan; + } + st_free_gen(gen); + + /* Choose the mask. */ + for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; + } + + /* Write the header and the global attributes. */ + retval = fprintf(fp,"digraph \"ZDD\" {\n"); + if (retval == EOF) return(0); + retval = fprintf(fp, + "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); + if (retval == EOF) return(0); + + /* Write the input name subgraph by scanning the support array. */ + retval = fprintf(fp,"{ node [shape = plaintext];\n"); + if (retval == EOF) goto failure; + retval = fprintf(fp," edge [style = invis];\n"); + if (retval == EOF) goto failure; + /* We use a name ("CONST NODES") with an embedded blank, because + ** it is unlikely to appear as an input name. + */ + retval = fprintf(fp," \"CONST NODES\" [style = invis];\n"); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if (sorted[dd->invpermZ[i]]) { + if (inames == NULL) { + retval = fprintf(fp,"\" %d \" -> ", dd->invpermZ[i]); + } else { + retval = fprintf(fp,"\" %s \" -> ", inames[dd->invpermZ[i]]); + } + if (retval == EOF) goto failure; + } + } + retval = fprintf(fp,"\"CONST NODES\"; \n}\n"); + if (retval == EOF) goto failure; + + /* Write the output node subgraph. */ + retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); + if (retval == EOF) goto failure; + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + if (i == n - 1) { + retval = fprintf(fp,"; }\n"); + } else { + retval = fprintf(fp," -> "); + } + if (retval == EOF) goto failure; + } + + /* Write rank info: All nodes with the same index have the same rank. */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invpermZ[i]]) { + retval = fprintf(fp,"{ rank = same; "); + if (retval == EOF) goto failure; + if (inames == NULL) { + retval = fprintf(fp,"\" %d \";\n", dd->invpermZ[i]); + } else { + retval = fprintf(fp,"\" %s \";\n", inames[dd->invpermZ[i]]); + } + if (retval == EOF) goto failure; + nodelist = dd->subtableZ[i].nodelist; + slots = dd->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", (void *) + ((mask & (ptrint) scan) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; + } + } + + /* All constants have the same rank. */ + retval = fprintf(fp, + "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); + if (retval == EOF) goto failure; + nodelist = dd->constants.nodelist; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", (void *) + ((mask & (ptrint) scan) / sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + retval = fprintf(fp,"}\n}\n"); + if (retval == EOF) goto failure; + + /* Write edge info. */ + /* Edges from the output nodes. */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp," -> \"%p\" [style = solid];\n", + (void *) ((mask & (ptrint) f[i]) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + + /* Edges from internal nodes. */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invpermZ[i]]) { + nodelist = dd->subtableZ[i].nodelist; + slots = dd->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp, + "\"%p\" -> \"%p\";\n", + (void *) ((mask & (ptrint) scan) / sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddT(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + retval = fprintf(fp, + "\"%p\" -> \"%p\" [style = dashed];\n", + (void *) ((mask & (ptrint) scan) + / sizeof(DdNode)), + (void *) ((mask & (ptrint) + cuddE(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + } + } + + /* Write constant labels. */ + nodelist = dd->constants.nodelist; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + cuddV(scan)); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + + /* Write trailer and return. */ + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; + + st_free_table(visited); + FREE(sorted); + return(1); + +failure: + if (sorted != NULL) FREE(sorted); + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_zddDumpBlif */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints a ZDD to the standard output. One line per node is + printed.] + + Description [Prints a ZDD to the standard output. One line per node is + printed. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddPrintDebug] + +******************************************************************************/ +int +cuddZddP( + DdManager * zdd, + DdNode * f) +{ + int retval; + st_table *table = st_init_table(st_ptrcmp, st_ptrhash); + + if (table == NULL) return(0); + + retval = zp2(zdd, f, table); + st_free_table(table); + (void) fputc('\n', zdd->out); + return(retval); + +} /* end of cuddZddP */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of cuddZddP.] + + Description [Performs the recursive step of cuddZddP. Returns 1 in + case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zp2( + DdManager * zdd, + DdNode * f, + st_table * t) +{ + DdNode *n; + int T, E; + DdNode *base = DD_ONE(zdd); + + if (f == NULL) + return(0); + + if (Cudd_IsConstant(f)) { + (void)fprintf(zdd->out, "ID = %d\n", (f == base)); + return(1); + } + if (st_is_member(t, (char *)f) == 1) + return(1); + + if (st_insert(t, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + +#if SIZEOF_VOID_P == 8 + (void) fprintf(zdd->out, "ID = 0x%lx\tindex = %u\tr = %u\t", + (ptruint)f / (ptruint) sizeof(DdNode), f->index, f->ref); +#else + (void) fprintf(zdd->out, "ID = 0x%x\tindex = %hu\tr = %hu\t", + (ptruint)f / (ptruint) sizeof(DdNode), f->index, f->ref); +#endif + + n = cuddT(f); + if (Cudd_IsConstant(n)) { + (void) fprintf(zdd->out, "T = %d\t\t", (n == base)); + T = 1; + } else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(zdd->out, "T = 0x%lx\t", (ptruint) n / + (ptruint) sizeof(DdNode)); +#else + (void) fprintf(zdd->out, "T = 0x%x\t", (ptruint) n / + (ptruint) sizeof(DdNode)); +#endif + T = 0; + } + + n = cuddE(f); + if (Cudd_IsConstant(n)) { + (void) fprintf(zdd->out, "E = %d\n", (n == base)); + E = 1; + } else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(zdd->out, "E = 0x%lx\n", (ptruint) n / + (ptruint) sizeof(DdNode)); +#else + (void) fprintf(zdd->out, "E = 0x%x\n", (ptruint) n / + (ptruint) sizeof(DdNode)); +#endif + E = 0; + } + + if (E == 0) + if (zp2(zdd, cuddE(f), t) == 0) return(0); + if (T == 0) + if (zp2(zdd, cuddT(f), t) == 0) return(0); + return(1); + +} /* end of zp2 */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddPrintMinterm.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +zdd_print_minterm_aux( + DdManager * zdd /* manager */, + DdNode * node /* current node */, + int level /* depth in the recursion */, + int * list /* current recursion path */) +{ + DdNode *Nv, *Nnv; + int i, v; + DdNode *base = DD_ONE(zdd); + + if (Cudd_IsConstant(node)) { + if (node == base) { + /* Check for missing variable. */ + if (level != zdd->sizeZ) { + list[zdd->invpermZ[level]] = 0; + zdd_print_minterm_aux(zdd, node, level + 1, list); + return; + } + /* Terminal case: Print one cube based on the current recursion + ** path. + */ + for (i = 0; i < zdd->sizeZ; i++) { + v = list[i]; + if (v == 0) + (void) fprintf(zdd->out,"0"); + else if (v == 1) + (void) fprintf(zdd->out,"1"); + else if (v == 3) + (void) fprintf(zdd->out,"@"); /* should never happen */ + else + (void) fprintf(zdd->out,"-"); + } + (void) fprintf(zdd->out," 1\n"); + } + } else { + /* Check for missing variable. */ + if (level != cuddIZ(zdd,node->index)) { + list[zdd->invpermZ[level]] = 0; + zdd_print_minterm_aux(zdd, node, level + 1, list); + return; + } + + Nnv = cuddE(node); + Nv = cuddT(node); + if (Nv == Nnv) { + list[node->index] = 2; + zdd_print_minterm_aux(zdd, Nnv, level + 1, list); + return; + } + + list[node->index] = 1; + zdd_print_minterm_aux(zdd, Nv, level + 1, list); + list[node->index] = 0; + zdd_print_minterm_aux(zdd, Nnv, level + 1, list); + } + return; + +} /* end of zdd_print_minterm_aux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddPrintCover.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +zddPrintCoverAux( + DdManager * zdd /* manager */, + DdNode * node /* current node */, + int level /* depth in the recursion */, + int * list /* current recursion path */) +{ + DdNode *Nv, *Nnv; + int i, v; + DdNode *base = DD_ONE(zdd); + + if (Cudd_IsConstant(node)) { + if (node == base) { + /* Check for missing variable. */ + if (level != zdd->sizeZ) { + list[zdd->invpermZ[level]] = 0; + zddPrintCoverAux(zdd, node, level + 1, list); + return; + } + /* Terminal case: Print one cube based on the current recursion + ** path. + */ + for (i = 0; i < zdd->sizeZ; i += 2) { + v = list[i] * 4 + list[i+1]; + if (v == 0) + (void) putc('-',zdd->out); + else if (v == 4) + (void) putc('1',zdd->out); + else if (v == 1) + (void) putc('0',zdd->out); + else + (void) putc('@',zdd->out); /* should never happen */ + } + (void) fprintf(zdd->out," 1\n"); + } + } else { + /* Check for missing variable. */ + if (level != cuddIZ(zdd,node->index)) { + list[zdd->invpermZ[level]] = 0; + zddPrintCoverAux(zdd, node, level + 1, list); + return; + } + + Nnv = cuddE(node); + Nv = cuddT(node); + if (Nv == Nnv) { + list[node->index] = 2; + zddPrintCoverAux(zdd, Nnv, level + 1, list); + return; + } + + list[node->index] = 1; + zddPrintCoverAux(zdd, Nv, level + 1, list); + list[node->index] = 0; + zddPrintCoverAux(zdd, Nnv, level + 1, list); + } + return; + +} /* end of zddPrintCoverAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddSupport.] + + Description [Performs the recursive step of Cudd_zddSupport. Performs a + DFS from f. The support is accumulated in supp as a side effect. Uses + the LSB of the then pointer as visited flag.] + + SideEffects [None] + + SeeAlso [zddClearFlag] + +******************************************************************************/ +static void +zddSupportStep( + DdNode * f, + int * support) +{ + if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) { + return; + } + + support[f->index] = 1; + zddSupportStep(cuddT(f),support); + zddSupportStep(Cudd_Regular(cuddE(f)),support); + /* Mark as visited. */ + f->next = Cudd_Not(f->next); + return; + +} /* end of zddSupportStep */ + + +/**Function******************************************************************** + + Synopsis [Performs a DFS from f, clearing the LSB of the next + pointers.] + + Description [] + + SideEffects [None] + + SeeAlso [zddSupportStep] + +******************************************************************************/ +static void +zddClearFlag( + DdNode * f) +{ + if (!Cudd_IsComplement(f->next)) { + return; + } + /* Clear visited flag. */ + f->next = Cudd_Regular(f->next); + if (cuddIsConstant(f)) { + return; + } + zddClearFlag(cuddT(f)); + zddClearFlag(Cudd_Regular(cuddE(f))); + return; + +} /* end of zddClearFlag */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.doc b/resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.doc new file mode 100644 index 000000000..7a9169b19 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.doc @@ -0,0 +1,6776 @@ +The cudd package + +The University of Colorado decision diagram package. + +Fabio Somenzi + +********************************************************************** + +Cudd_AddHook() Adds a function to a hook. + +Cudd_ApaAdd() Adds two arbitrary precision integers. + +Cudd_ApaCompareRatios() Compares the ratios of two arbitrary precision + integers to two unsigned ints. + +Cudd_ApaCompare() Compares two arbitrary precision integers. + +Cudd_ApaCopy() Makes a copy of an arbitrary precision integer. + +Cudd_ApaCountMinterm() Counts the number of minterms of a DD. + +Cudd_ApaIntDivision() Divides an arbitrary precision integer by an + integer. + +Cudd_ApaNumberOfDigits() Finds the number of digits for an arbitrary + precision integer. + +Cudd_ApaPowerOfTwo() Sets an arbitrary precision integer to a power + of two. + +Cudd_ApaPrintDecimal() Prints an arbitrary precision integer in + decimal format. + +Cudd_ApaPrintDensity() Prints the density of a BDD or ADD using + arbitrary precision arithmetic. + +Cudd_ApaPrintExponential() Prints an arbitrary precision integer in + exponential format. + +Cudd_ApaPrintHex() Prints an arbitrary precision integer in + hexadecimal format. + +Cudd_ApaPrintMintermExp() Prints the number of minterms of a BDD or ADD + in exponential format using arbitrary + precision arithmetic. + +Cudd_ApaPrintMinterm() Prints the number of minterms of a BDD or ADD + using arbitrary precision arithmetic. + +Cudd_ApaSetToLiteral() Sets an arbitrary precision integer to a one- + digit literal. + +Cudd_ApaShiftRight() Shifts right an arbitrary precision integer by + one binary place. + +Cudd_ApaShortDivision() Divides an arbitrary precision integer by a + digit. + +Cudd_ApaSubtract() Subtracts two arbitrary precision integers. + +Cudd_AutodynDisableZdd() Disables automatic dynamic reordering of ZDDs. + +Cudd_AutodynDisable() Disables automatic dynamic reordering. + +Cudd_AutodynEnableZdd() Enables automatic dynamic reordering of ZDDs. + +Cudd_AutodynEnable() Enables automatic dynamic reordering of BDDs + and ADDs. + +Cudd_AverageDistance() Computes the average distance between adjacent + nodes. + +Cudd_BddToAdd() Converts a BDD to a 0-1 ADD. + +Cudd_BddToCubeArray() Builds a positional array from the BDD of a + cube. + +Cudd_BiasedOverApprox() Extracts a dense superset from a BDD with the + biased underapproximation method. + +Cudd_BiasedUnderApprox() Extracts a dense subset from a BDD with the + biased underapproximation method. + +Cudd_CProjection() Computes the compatible projection of R w.r.t. + cube Y. + +Cudd_CheckCube() Checks whether g is the BDD of a cube. + +Cudd_CheckKeys() Checks for several conditions that should not + occur. + +Cudd_CheckZeroRef() Checks the unique table for nodes with non-zero + reference counts. + +Cudd_ClassifySupport() Classifies the variables in the support of two + DDs. + +Cudd_ClearErrorCode() Clear the error code of a manager. + +Cudd_CofMinterm() Computes the fraction of minterms in the on-set + of all the positive cofactors of a BDD or + ADD. + +Cudd_Cofactor() Computes the cofactor of f with respect to g. + +Cudd_CountLeaves() Counts the number of leaves in a DD. + +Cudd_CountMinterm() Counts the number of minterms of a DD. + +Cudd_CountPathsToNonZero() Counts the number of paths to a non-zero + terminal of a DD. + +Cudd_CountPath() Counts the number of paths of a DD. + +Cudd_CubeArrayToBdd() Builds the BDD of a cube from a positional + array. + +Cudd_DagSize() Counts the number of nodes in a DD. + +Cudd_DeadAreCounted() Tells whether dead nodes are counted towards + triggering reordering. + +Cudd_DebugCheck() Checks for inconsistencies in the DD heap. + +Cudd_Decreasing() Determines whether a BDD is negative unate in a + variable. + +Cudd_DelayedDerefBdd() Decreases the reference count of BDD node n. + +Cudd_Density() Computes the density of a BDD or ADD. + +Cudd_Deref() Decreases the reference count of node. + +Cudd_DisableGarbageCollection() + Disables garbage collection. + +Cudd_DisableOrderingMonitoring() + Disables monitoring of ordering. + +Cudd_DisableReorderingReporting() + Disables reporting of reordering stats. + +Cudd_Disequality() Generates a BDD for the function x - y != c. + +Cudd_DumpBlifBody() Writes a blif body representing the argument + BDDs. + +Cudd_DumpBlif() Writes a blif file representing the argument + BDDs. + +Cudd_DumpDDcal() Writes a DDcal file representing the argument + BDDs. + +Cudd_DumpDaVinci() Writes a daVinci file representing the argument + BDDs. + +Cudd_DumpDot() Writes a dot file representing the argument + DDs. + +Cudd_DumpFactoredForm() Writes factored forms representing the argument + BDDs. + +Cudd_Dxygtdxz() Generates a BDD for the function d(x,y) > + d(x,z). + +Cudd_Dxygtdyz() Generates a BDD for the function d(x,y) > + d(y,z). + +Cudd_EnableGarbageCollection() Enables garbage collection. + +Cudd_EnableOrderingMonitoring() + Enables monitoring of ordering. + +Cudd_EnableReorderingReporting() + Enables reporting of reordering stats. + +Cudd_EpdCountMinterm() Counts the number of minterms of a DD with + extended precision. + +Cudd_EqualSupNorm() Compares two ADDs for equality within + tolerance. + +Cudd_EquivDC() Tells whether F and G are identical wherever D + is 0. + +Cudd_EstimateCofactorSimple() Estimates the number of nodes in a cofactor of + a DD. + +Cudd_EstimateCofactor() Estimates the number of nodes in a cofactor of + a DD. + +Cudd_Eval() Returns the value of a DD for a given variable + assignment. + +Cudd_ExpectedUsedSlots() Computes the expected fraction of used slots in + the unique table. + +Cudd_FindEssential() Finds the essential variables of a DD. + +Cudd_FindTwoLiteralClauses() Finds the two literal clauses of a DD. + +Cudd_FirstCube() Finds the first cube of a decision diagram. + +Cudd_FirstNode() Finds the first node of a decision diagram. + +Cudd_FirstPrime() Finds the first prime of a Boolean function. + +Cudd_FreeTree() Frees the variable group tree of the manager. + +Cudd_FreeZddTree() Frees the variable group tree of the manager. + +Cudd_GarbageCollectionEnabled() + Tells whether garbage collection is enabled. + +Cudd_GenFree() Frees a CUDD generator. + +Cudd_IncreaseTimeLimit() Increases the time limit for the manager. + +Cudd_Increasing() Determines whether a BDD is positive unate in a + variable. + +Cudd_IndicesToCube() Builds a cube of BDD variables from an array of + indices. + +Cudd_Inequality() Generates a BDD for the function x - y ≥ c. + +Cudd_Init() Creates a new DD manager. + +Cudd_IsGenEmpty() Queries the status of a generator. + +Cudd_IsInHook() Checks whether a function is in a hook. + +Cudd_IsNonConstant() Returns 1 if a DD node is not constant. + +Cudd_IterDerefBdd() Decreases the reference count of BDD node n. + +Cudd_LargestCube() Finds a largest cube in a DD. + +Cudd_MakeBddFromZddCover() Converts a ZDD cover to a BDD. + +Cudd_MakeTreeNode() Creates a new variable group. + +Cudd_MakeZddTreeNode() Creates a new ZDD variable group. + +Cudd_MinHammingDist() Returns the minimum Hamming distance between f + and minterm. + +Cudd_NewApaNumber() Allocates memory for an arbitrary precision + integer. + +Cudd_NextCube() Generates the next cube of a decision diagram + onset. + +Cudd_NextNode() Finds the next node of a decision diagram. + +Cudd_NextPrime() Generates the next prime of a Boolean function. + +Cudd_NodeReadIndex() Returns the index of the node. + +Cudd_OrderingMonitoring() Returns 1 if monitoring of ordering is enabled. + +Cudd_OutOfMem() Warns that a memory allocation failed. + +Cudd_OverApprox() Extracts a dense superset from a BDD with + Shiple's underapproximation method. + +Cudd_Prime() Returns the next prime >= p. + +Cudd_PrintDebug() Prints to the standard output a DD and its + statistics. + +Cudd_PrintGroupedOrder() Hook function to print the current variable + order. + +Cudd_PrintInfo() Prints out statistics and settings for a CUDD + manager. + +Cudd_PrintLinear() Prints the linear transform matrix. + +Cudd_PrintMinterm() Prints a disjoint sum of products. + +Cudd_PrintTwoLiteralClauses() Prints the two literal clauses of a DD. + +Cudd_PrintVersion() Prints the package version number. + +Cudd_PrioritySelect() Selects pairs from R using a priority function. + +Cudd_Quit() Deletes resources associated with a DD manager. + +Cudd_Random() Portable random number generator. + +Cudd_ReadArcviolation() Returns the current value of the arcviolation + parameter used in group sifting. + +Cudd_ReadBackground() Reads the background constant of the manager. + +Cudd_ReadCacheHits() Returns the number of cache hits. + +Cudd_ReadCacheLookUps() Returns the number of cache look-ups. + +Cudd_ReadCacheSlots() Reads the number of slots in the cache. + +Cudd_ReadCacheUsedSlots() Reads the fraction of used slots in the cache. + +Cudd_ReadDead() Returns the number of dead nodes in the unique + table. + +Cudd_ReadElapsedTime() Returns the time elapsed since the start time + of the manager. + +Cudd_ReadEpsilon() Reads the epsilon parameter of the manager. + +Cudd_ReadErrorCode() Returns the code of the last error. + +Cudd_ReadGarbageCollectionTime() + Returns the time spent in garbage collection. + +Cudd_ReadGarbageCollections() Returns the number of times garbage collection + has occurred. + +Cudd_ReadGroupcheck() Reads the groupcheck parameter of the manager. + +Cudd_ReadInvPermZdd() Returns the index of the ZDD variable currently + in the i-th position of the order. + +Cudd_ReadInvPerm() Returns the index of the variable currently in + the i-th position of the order. + +Cudd_ReadIthClause() Accesses the i-th clause of a DD. + +Cudd_ReadKeys() Returns the number of nodes in the unique + table. + +Cudd_ReadLinear() Reads an entry of the linear transform matrix. + +Cudd_ReadLogicZero() Returns the logic zero constant of the manager. + +Cudd_ReadLooseUpTo() Reads the looseUpTo parameter of the manager. + +Cudd_ReadMaxCacheHard() Reads the maxCacheHard parameter of the + manager. + +Cudd_ReadMaxCache() Returns the soft limit for the cache size. + +Cudd_ReadMaxGrowthAlternate() Reads the maxGrowthAlt parameter of the + manager. + +Cudd_ReadMaxGrowth() Reads the maxGrowth parameter of the manager. + +Cudd_ReadMaxLive() Reads the maximum allowed number of live nodes. + +Cudd_ReadMaxMemory() Reads the maximum allowed memory. + +Cudd_ReadMaxReorderings() Returns the maximum number of times reordering + may be invoked. + +Cudd_ReadMemoryInUse() Returns the memory in use by the manager + measured in bytes. + +Cudd_ReadMinDead() Reads the minDead parameter of the manager. + +Cudd_ReadMinHit() Reads the hit rate that causes resizinig of the + computed table. + +Cudd_ReadMinusInfinity() Reads the minus-infinity constant from the + manager. + +Cudd_ReadNextReordering() Returns the threshold for the next dynamic + reordering. + +Cudd_ReadNodeCount() Reports the number of nodes in BDDs and ADDs. + +Cudd_ReadNodesDropped() Returns the number of nodes dropped. + +Cudd_ReadNodesFreed() Returns the number of nodes freed. + +Cudd_ReadNumberXovers() Reads the current number of crossovers used by + the genetic algorithm for reordering. + +Cudd_ReadOne() Returns the one constant of the manager. + +Cudd_ReadOrderRandomization() Returns the order randomization factor. + +Cudd_ReadPeakLiveNodeCount() Reports the peak number of live nodes. + +Cudd_ReadPeakNodeCount() Reports the peak number of nodes. + +Cudd_ReadPermZdd() Returns the current position of the i-th ZDD + variable in the order. + +Cudd_ReadPerm() Returns the current position of the i-th + variable in the order. + +Cudd_ReadPlusInfinity() Reads the plus-infinity constant from the + manager. + +Cudd_ReadPopulationSize() Reads the current size of the population used + by the genetic algorithm for reordering. + +Cudd_ReadRecomb() Returns the current value of the recombination + parameter used in group sifting. + +Cudd_ReadRecursiveCalls() Returns the number of recursive calls. + +Cudd_ReadReorderingCycle() Reads the reordCycle parameter of the manager. + +Cudd_ReadReorderingTime() Returns the time spent in reordering. + +Cudd_ReadReorderings() Returns the number of times reordering has + occurred. + +Cudd_ReadSiftMaxSwap() Reads the siftMaxSwap parameter of the manager. + +Cudd_ReadSiftMaxVar() Reads the siftMaxVar parameter of the manager. + +Cudd_ReadSize() Returns the number of BDD variables in + existance. + +Cudd_ReadSlots() Returns the total number of slots of the unique + table. + +Cudd_ReadStartTime() Returns the start time of the manager. + +Cudd_ReadStderr() Reads the stderr of a manager. + +Cudd_ReadStdout() Reads the stdout of a manager. + +Cudd_ReadSwapSteps() Reads the number of elementary reordering + steps. + +Cudd_ReadSymmviolation() Returns the current value of the symmviolation + parameter used in group sifting. + +Cudd_ReadTimeLimit() Returns the time limit for the manager. + +Cudd_ReadTree() Returns the variable group tree of the manager. + +Cudd_ReadUniqueLinks() Returns the number of links followed in the + unique table. + +Cudd_ReadUniqueLookUps() Returns the number of look-ups in the unique + table. + +Cudd_ReadUsedSlots() Reads the fraction of used slots in the unique + table. + +Cudd_ReadVars() Returns the i-th element of the vars array. + +Cudd_ReadZddOne() Returns the ZDD for the constant 1 function. + +Cudd_ReadZddSize() Returns the number of ZDD variables in + existance. + +Cudd_ReadZddTree() Returns the variable group tree of the manager. + +Cudd_ReadZero() Returns the zero constant of the manager. + +Cudd_RecursiveDerefZdd() Decreases the reference count of ZDD node n. + +Cudd_RecursiveDeref() Decreases the reference count of node n. + +Cudd_ReduceHeap() Main dynamic reordering routine. + +Cudd_Ref() Increases the reference count of a node, if it + is not saturated. + +Cudd_RemapOverApprox() Extracts a dense superset from a BDD with the + remapping underapproximation method. + +Cudd_RemapUnderApprox() Extracts a dense subset from a BDD with the + remapping underapproximation method. + +Cudd_RemoveHook() Removes a function from a hook. + +Cudd_ReorderingReporting() Returns 1 if reporting of reordering stats is + enabled. + +Cudd_ReorderingStatusZdd() Reports the status of automatic dynamic + reordering of ZDDs. + +Cudd_ReorderingStatus() Reports the status of automatic dynamic + reordering of BDDs and ADDs. + +Cudd_Reserve() Expand manager without creating variables. + +Cudd_ResetStartTime() Resets the start time of the manager. + +Cudd_SetArcviolation() Sets the value of the arcviolation parameter + used in group sifting. + +Cudd_SetBackground() Sets the background constant of the manager. + +Cudd_SetEpsilon() Sets the epsilon parameter of the manager to + ep. + +Cudd_SetGroupcheck() Sets the parameter groupcheck of the manager to + gc. + +Cudd_SetLooseUpTo() Sets the looseUpTo parameter of the manager. + +Cudd_SetMaxCacheHard() Sets the maxCacheHard parameter of the manager. + +Cudd_SetMaxGrowthAlternate() Sets the maxGrowthAlt parameter of the manager. + +Cudd_SetMaxGrowth() Sets the maxGrowth parameter of the manager. + +Cudd_SetMaxLive() Sets the maximum allowed number of live nodes. + +Cudd_SetMaxMemory() Sets the maximum allowed memory. + +Cudd_SetMaxReorderings() Sets the maximum number of times reordering may + be invoked. + +Cudd_SetMinHit() Sets the hit rate that causes resizinig of the + computed table. + +Cudd_SetNextReordering() Sets the threshold for the next dynamic + reordering. + +Cudd_SetNumberXovers() Sets the number of crossovers used by the + genetic algorithm for reordering. + +Cudd_SetOrderRandomization() Sets the order randomization factor. + +Cudd_SetPopulationSize() Sets the size of the population used by the + genetic algorithm for reordering. + +Cudd_SetRecomb() Sets the value of the recombination parameter + used in group sifting. + +Cudd_SetReorderingCycle() Sets the reordCycle parameter of the manager. + +Cudd_SetSiftMaxSwap() Sets the siftMaxSwap parameter of the manager. + +Cudd_SetSiftMaxVar() Sets the siftMaxVar parameter of the manager. + +Cudd_SetStartTime() Sets the start time of the manager. + +Cudd_SetStderr() Sets the stderr of a manager. + +Cudd_SetStdout() Sets the stdout of a manager. + +Cudd_SetSymmviolation() Sets the value of the symmviolation parameter + used in group sifting. + +Cudd_SetTimeLimit() Sets the time limit for the manager. + +Cudd_SetTree() Sets the variable group tree of the manager. + +Cudd_SetVarMap() Registers a variable mapping with the manager. + +Cudd_SetZddTree() Sets the ZDD variable group tree of the + manager. + +Cudd_SharingSize() Counts the number of nodes in an array of DDs. + +Cudd_ShortestLength() Find the length of the shortest path(s) in a + DD. + +Cudd_ShortestPath() Finds a shortest path in a DD. + +Cudd_ShuffleHeap() Reorders variables according to given + permutation. + +Cudd_SolveEqn() Implements the solution of F(x,y) = 0. + +Cudd_SplitSet() Returns m minterms from a BDD. + +Cudd_Srandom() Initializer for the portable random number + generator. + +Cudd_StdPostReordHook() Sample hook function to call after reordering. + +Cudd_StdPreReordHook() Sample hook function to call before reordering. + +Cudd_SubsetCompress() Find a dense subset of BDD f. + +Cudd_SubsetHeavyBranch() Extracts a dense subset from a BDD with the + heavy branch heuristic. + +Cudd_SubsetShortPaths() Extracts a dense subset from a BDD with the + shortest paths heuristic. + +Cudd_SubsetWithMaskVars() Extracts a subset from a BDD. + +Cudd_SupersetCompress() Find a dense superset of BDD f. + +Cudd_SupersetHeavyBranch() Extracts a dense superset from a BDD with the + heavy branch heuristic. + +Cudd_SupersetShortPaths() Extracts a dense superset from a BDD with the + shortest paths heuristic. + +Cudd_SupportIndex() Finds the variables on which a DD depends. + +Cudd_SupportIndices() Finds the variables on which a DD depends. + +Cudd_SupportSize() Counts the variables on which a DD depends. + +Cudd_Support() Finds the variables on which a DD depends. + +Cudd_SymmProfile() Prints statistics on symmetric variables. + +Cudd_TimeLimited() Returns true if the time limit for the manager + is set. + +Cudd_TurnOffCountDead() Causes the dead nodes not to be counted towards + triggering reordering. + +Cudd_TurnOnCountDead() Causes the dead nodes to be counted towards + triggering reordering. + +Cudd_UnderApprox() Extracts a dense subset from a BDD with + Shiple's underapproximation method. + +Cudd_UnsetTimeLimit() Unsets the time limit for the manager. + +Cudd_UpdateTimeLimit() Updates the time limit for the manager. + +Cudd_VectorSupportIndex() Finds the variables on which a set of DDs + depends. + +Cudd_VectorSupportIndices() Finds the variables on which a set of DDs + depends. + +Cudd_VectorSupportSize() Counts the variables on which a set of DDs + depends. + +Cudd_VectorSupport() Finds the variables on which a set of DDs + depends. + +Cudd_VerifySol() Checks the solution of F(x,y) = 0. + +Cudd_Xeqy() Generates a BDD for the function x==y. + +Cudd_Xgty() Generates a BDD for the function x > y. + +Cudd_addAgreement() f if f==g; background if f!=g. + +Cudd_addApply() Applies op to the corresponding discriminants + of f and g. + +Cudd_addBddInterval() Converts an ADD to a BDD. + +Cudd_addBddIthBit() Converts an ADD to a BDD by extracting the i-th + bit from the leaves. + +Cudd_addBddPattern() Converts an ADD to a BDD. + +Cudd_addBddStrictThreshold() Converts an ADD to a BDD. + +Cudd_addBddThreshold() Converts an ADD to a BDD. + +Cudd_addCmpl() Computes the complement of an ADD a la C + language. + +Cudd_addCompose() Substitutes g for x_v in the ADD for f. + +Cudd_addComputeCube() Computes the cube of an array of ADD variables. + +Cudd_addConstrain() Computes f constrain c for ADDs. + +Cudd_addConst() Returns the ADD for constant c. + +Cudd_addDiff() Returns plusinfinity if f=g; returns min(f,g) + if f!=g. + +Cudd_addDivide() Integer and floating point division. + +Cudd_addEvalConst() Checks whether ADD g is constant whenever ADD f + is 1. + +Cudd_addExistAbstract() Existentially Abstracts all the variables in + cube from f. + +Cudd_addFindMax() Finds the maximum discriminant of f. + +Cudd_addFindMin() Finds the minimum discriminant of f. + +Cudd_addGeneralVectorCompose() Composes an ADD with a vector of ADDs. + +Cudd_addHamming() Computes the Hamming distance ADD. + +Cudd_addHarwell() Reads in a matrix in the format of the Harwell- + Boeing benchmark suite. + +Cudd_addIteConstant() Implements ITEconstant for ADDs. + +Cudd_addIte() Implements ITE(f,g,h). + +Cudd_addIthBit() Extracts the i-th bit from an ADD. + +Cudd_addIthVar() Returns the ADD variable with index i. + +Cudd_addLeq() Determines whether f is less than or equal to + g. + +Cudd_addLog() Natural logarithm of an ADD. + +Cudd_addMatrixMultiply() Calculates the product of two matrices + represented as ADDs. + +Cudd_addMaximum() Integer and floating point max. + +Cudd_addMinimum() Integer and floating point min. + +Cudd_addMinus() Integer and floating point subtraction. + +Cudd_addMonadicApply() Applies op to the discriminants of f. + +Cudd_addNand() NAND of two 0-1 ADDs. + +Cudd_addNegate() Computes the additive inverse of an ADD. + +Cudd_addNewVarAtLevel() Returns a new ADD variable at a specified + level. + +Cudd_addNewVar() Returns a new ADD variable. + +Cudd_addNonSimCompose() Composes an ADD with a vector of 0-1 ADDs. + +Cudd_addNor() NOR of two 0-1 ADDs. + +Cudd_addOneZeroMaximum() Returns 1 if f > g and 0 otherwise. + +Cudd_addOrAbstract() Disjunctively abstracts all the variables in + cube from the 0-1 ADD f. + +Cudd_addOr() Disjunction of two 0-1 ADDs. + +Cudd_addOuterSum() Takes the minimum of a matrix and the outer sum + of two vectors. + +Cudd_addPermute() Permutes the variables of an ADD. + +Cudd_addPlus() Integer and floating point addition. + +Cudd_addRead() Reads in a sparse matrix. + +Cudd_addResidue() Builds an ADD for the residue modulo m of an n- + bit number. + +Cudd_addRestrict() ADD restrict according to Coudert and Madre's + algorithm (ICCAD90). + +Cudd_addRoundOff() Rounds off the discriminants of an ADD. + +Cudd_addScalarInverse() Computes the scalar inverse of an ADD. + +Cudd_addSetNZ() This operator sets f to the value of g wherever + g != 0. + +Cudd_addSwapVariables() Swaps two sets of variables of the same size (x + and y) in the ADD f. + +Cudd_addThreshold() f if f>=g; 0 if f d(x,z); x, y, and + z are N-bit numbers, x[0] x[1] ... x[N-1], y[0] y[1] ... y[N-1], and z[0] + z[1] ... z[N-1], with 0 the most significant bit. The distance d(x,y) is + defined as: sum_{i=0}^{N-1}(|x_i - y_i| cdot 2^{N-i-1}). The BDD is built + bottom-up. It has 7*N-3 internal nodes, if the variables are ordered as + follows: x[0] y[0] z[0] x[1] y[1] z[1] ... x[N-1] y[N-1] z[N-1]. + + Side Effects: None + +DdNode * +Cudd_Dxygtdyz( + DdManager * dd, DD manager + int N, number of x, y, and z variables + DdNode ** x, array of x variables + DdNode ** y, array of y variables + DdNode ** z array of z variables +) + This function generates a BDD for the function d(x,y) > d(y,z); x, y, and + z are N-bit numbers, x[0] x[1] ... x[N-1], y[0] y[1] ... y[N-1], and z[0] + z[1] ... z[N-1], with 0 the most significant bit. The distance d(x,y) is + defined as: sum_{i=0}^{N-1}(|x_i - y_i| cdot 2^{N-i-1}). The BDD is built + bottom-up. It has 7*N-3 internal nodes, if the variables are ordered as + follows: x[0] y[0] z[0] x[1] y[1] z[1] ... x[N-1] y[N-1] z[N-1]. + + Side Effects: None + +void +Cudd_EnableGarbageCollection( + DdManager * dd +) + Enables garbage collection. Garbage collection is initially enabled. + Therefore it is necessary to call this function only if garbage collection + has been explicitly disabled. + + Side Effects: None + +int +Cudd_EnableOrderingMonitoring( + DdManager * dd +) + Enables monitoring of ordering. Returns 1 if successful; 0 otherwise. + + Side Effects: Installs functions in the pre-reordering and post-reordering + hooks. + +int +Cudd_EnableReorderingReporting( + DdManager * dd +) + Enables reporting of reordering stats. Returns 1 if successful; 0 otherwise. + + Side Effects: Installs functions in the pre-reordering and post-reordering + hooks. + +int +Cudd_EpdCountMinterm( + DdManager * manager, + DdNode * node, + int nvars, + EpDouble * epd +) + Counts the number of minterms of a DD with extended precision. The function + is assumed to depend on nvars variables. The minterm count is represented as + an EpDouble, to allow any number of variables. Returns 0 if successful; + CUDD_OUT_OF_MEM otherwise. + + Side Effects: None + +int +Cudd_EqualSupNorm( + DdManager * dd, manager + DdNode * f, first ADD + DdNode * g, second ADD + CUDD_VALUE_TYPE tolerance, maximum allowed difference + int pr verbosity level +) + Compares two ADDs for equality within tolerance. Two ADDs are reported to be + equal if the maximum difference between them (the sup norm of their + difference) is less than or equal to the tolerance parameter. Returns 1 if + the two ADDs are equal (within tolerance); 0 otherwise. If parameter + pr is positive the first failure is reported to the standard + output. + + Side Effects: None + +int +Cudd_EquivDC( + DdManager * dd, + DdNode * F, + DdNode * G, + DdNode * D +) + Tells whether F and G are identical wherever D is 0. F and G are either two + ADDs or two BDDs. D is either a 0-1 ADD or a BDD. The function returns 1 if + F and G are equivalent, and 0 otherwise. No new nodes are created. + + Side Effects: None + +int +Cudd_EstimateCofactorSimple( + DdNode * node, + int i +) + Estimates the number of nodes in a cofactor of a DD. Returns an estimate of + the number of nodes in the positive cofactor of the graph rooted at node + with respect to the variable whose index is i. This procedure implements + with minor changes the algorithm of Cabodi et al. (ICCAD96). It does not + allocate any memory, it does not change the state of the manager, and it is + fast. However, it has been observed to overestimate the size of the cofactor + by as much as a factor of 2. + + Side Effects: None + +int +Cudd_EstimateCofactor( + DdManager * dd, manager + DdNode * f, function + int i, index of variable + int phase 1: positive; 0: negative +) + Estimates the number of nodes in a cofactor of a DD. Returns an estimate of + the number of nodes in a cofactor of the graph rooted at node with respect + to the variable whose index is i. In case of failure, returns + CUDD_OUT_OF_MEM. This function uses a refinement of the algorithm of Cabodi + et al. (ICCAD96). The refinement allows the procedure to account for part of + the recombination that may occur in the part of the cofactor above the + cofactoring variable. This procedure does not create any new node. It does + keep a small table of results; therefore it may run out of memory. If this + is a concern, one should use Cudd_EstimateCofactorSimple, which is faster, + does not allocate any memory, but is less accurate. + + Side Effects: None + +DdNode * +Cudd_Eval( + DdManager * dd, + DdNode * f, + int * inputs +) + Finds the value of a DD for a given variable assignment. The variable + assignment is passed in an array of int's, that should specify a zero or a + one for each variable in the support of the function. Returns a pointer to a + constant node. No new nodes are produced. + + Side Effects: None + +double +Cudd_ExpectedUsedSlots( + DdManager * dd +) + Computes the fraction of slots in the unique table that should be in use. + This expected value is based on the assumption that the hash function + distributes the keys randomly; it can be compared with the result of + Cudd_ReadUsedSlots to monitor the performance of the unique table hash + function. + + Side Effects: None + +DdNode * +Cudd_FindEssential( + DdManager * dd, + DdNode * f +) + Returns the cube of the essential variables. A positive literal means that + the variable must be set to 1 for the function to be 1. A negative literal + means that the variable must be set to 0 for the function to be 1. Returns a + pointer to the cube BDD if successful; NULL otherwise. + + Side Effects: None + +DdTlcInfo * +Cudd_FindTwoLiteralClauses( + DdManager * dd, + DdNode * f +) + Returns the one- and two-literal clauses of a DD. Returns a pointer to the + structure holding the clauses if successful; NULL otherwise. For a constant + DD, the empty set of clauses is returned. This is obviously correct for a + non-zero constant. For the constant zero, it is based on the assumption that + only those clauses containing variables in the support of the function are + considered. Since the support of a constant function is empty, no clauses + are returned. + + Side Effects: None + +DdGen * +Cudd_FirstCube( + DdManager * dd, + DdNode * f, + int ** cube, + CUDD_VALUE_TYPE * value +) + Defines an iterator on the onset of a decision diagram and finds its first + cube. Returns a generator that contains the information necessary to + continue the enumeration if successful; NULL otherwise. A cube is + represented as an array of literals, which are integers in {0, 1, 2}; 0 + represents a complemented literal, 1 represents an uncomplemented literal, + and 2 stands for don't care. The enumeration produces a disjoint cover of + the function associated with the diagram. The size of the array equals the + number of variables in the manager at the time Cudd_FirstCube is called. + For each cube, a value is also returned. This value is always 1 for a BDD, + while it may be different from 1 for an ADD. For BDDs, the offset is the set + of cubes whose value is the logical zero. For ADDs, the offset is the set of + cubes whose value is the background value. The cubes of the offset are not + enumerated. + + Side Effects: The first cube and its value are returned as side effects. + +DdGen * +Cudd_FirstNode( + DdManager * dd, + DdNode * f, + DdNode ** node +) + Defines an iterator on the nodes of a decision diagram and finds its first + node. Returns a generator that contains the information necessary to + continue the enumeration if successful; NULL otherwise. The nodes are + enumerated in a reverse topological order, so that a node is always preceded + in the enumeration by its descendants. + + Side Effects: The first node is returned as a side effect. + +DdGen * +Cudd_FirstPrime( + DdManager * dd, + DdNode * l, + DdNode * u, + int ** cube +) + Defines an iterator on a pair of BDDs describing a (possibly incompletely + specified) Boolean functions and finds the first cube of a cover of the + function. Returns a generator that contains the information necessary to + continue the enumeration if successful; NULL otherwise. The two argument + BDDs are the lower and upper bounds of an interval. It is a mistake to call + this function with a lower bound that is not less than or equal to the upper + bound. A cube is represented as an array of literals, which are integers + in {0, 1, 2}; 0 represents a complemented literal, 1 represents an + uncomplemented literal, and 2 stands for don't care. The enumeration + produces a prime and irredundant cover of the function associated with the + two BDDs. The size of the array equals the number of variables in the + manager at the time Cudd_FirstCube is called. This iterator can only be + used on BDDs. + + Side Effects: The first cube is returned as side effect. + +void +Cudd_FreeTree( + DdManager * dd +) + Frees the variable group tree of the manager. + + Side Effects: None + +void +Cudd_FreeZddTree( + DdManager * dd +) + Frees the variable group tree of the manager. + + Side Effects: None + +int +Cudd_GarbageCollectionEnabled( + DdManager * dd +) + Returns 1 if garbage collection is enabled; 0 otherwise. + + Side Effects: None + +int +Cudd_GenFree( + DdGen * gen +) + Frees a CUDD generator. Always returns 0, so that it can be used in mis-like + foreach constructs. + + Side Effects: None + +void +Cudd_IncreaseTimeLimit( + DdManager * unique, + unsigned long increase +) + Increases the time limit for the manager. + + Side Effects: None + +DdNode * +Cudd_Increasing( + DdManager * dd, + DdNode * f, + int i +) + Determines whether the function represented by BDD f is positive unate + (monotonic increasing) in variable i. It is based on Cudd_Decreasing and the + fact that f is monotonic increasing in i if and only if its complement is + monotonic decreasing in i. + + Side Effects: None + +DdNode * +Cudd_IndicesToCube( + DdManager * dd, + int * array, + int n +) + Builds a cube of BDD variables from an array of indices. Returns a pointer + to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_Inequality( + DdManager * dd, DD manager + int N, number of x and y variables + int c, right-hand side constant + DdNode ** x, array of x variables + DdNode ** y array of y variables +) + This function generates a BDD for the function x -y ≥ c. Both x and y are + N-bit numbers, x[0] x[1] ... x[N-1] and y[0] y[1] ... y[N-1], with 0 the + most significant bit. The BDD is built bottom-up. It has a linear number of + nodes if the variables are ordered as follows: x[0] y[0] x[1] y[1] ... x[N- + 1] y[N-1]. + + Side Effects: None + +DdManager * +Cudd_Init( + unsigned int numVars, initial number of BDD variables (i.e., + subtables) + unsigned int numVarsZ, initial number of ZDD variables (i.e., + subtables) + unsigned int numSlots, initial size of the unique tables + unsigned int cacheSize, initial size of the cache + unsigned long maxMemory target maximum memory occupation +) + Creates a new DD manager, initializes the table, the basic constants and the + projection functions. If maxMemory is 0, Cudd_Init decides suitable values + for the maximum size of the cache and for the limit for fast unique table + growth based on the available memory. Returns a pointer to the manager if + successful; NULL otherwise. + + Side Effects: None + +int +Cudd_IsGenEmpty( + DdGen * gen +) + Queries the status of a generator. Returns 1 if the generator is empty or + NULL; 0 otherswise. + + Side Effects: None + +int +Cudd_IsInHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where +) + Checks whether a function is in a hook. A hook is a list of application- + provided functions called on certain occasions by the package. Returns 1 if + the function is found; 0 otherwise. + + Side Effects: None + +int +Cudd_IsNonConstant( + DdNode * f +) + Returns 1 if a DD node is not constant. This function is useful to test the + results of Cudd_bddIteConstant, Cudd_addIteConstant, Cudd_addEvalConst. + These results may be a special value signifying non-constant. In the other + cases the macro Cudd_IsConstant can be used. + + Side Effects: None + +void +Cudd_IterDerefBdd( + DdManager * table, + DdNode * n +) + Decreases the reference count of node n. If n dies, recursively decreases + the reference counts of its children. It is used to dispose of a BDD that is + no longer needed. It is more efficient than Cudd_RecursiveDeref, but it + cannot be used on ADDs. The greater efficiency comes from being able to + assume that no constant node will ever die as a result of a call to this + procedure. + + Side Effects: None + +DdNode * +Cudd_LargestCube( + DdManager * manager, + DdNode * f, + int * length +) + Finds a largest cube in a DD. f is the DD we want to get the largest cube + for. The problem is translated into the one of finding a shortest path in f, + when both THEN and ELSE arcs are assumed to have unit length. This yields a + largest cube in the disjoint cover corresponding to the DD. Therefore, it is + not necessarily the largest implicant of f. Returns the largest cube as a + BDD. + + Side Effects: The number of literals of the cube is returned in the location + pointed by length if it is non-null. + +DdNode * +Cudd_MakeBddFromZddCover( + DdManager * dd, + DdNode * node +) + Converts a ZDD cover to a BDD for the function represented by the cover. If + successful, it returns a BDD node, otherwise it returns NULL. + + +MtrNode * +Cudd_MakeTreeNode( + DdManager * dd, manager + unsigned int low, index of the first group variable + unsigned int size, number of variables in the group + unsigned int type MTR_DEFAULT or MTR_FIXED +) + Creates a new variable group. The group starts at variable low and contains + size variables. The parameter low is the index of the first variable. If the + variable already exists, its current position in the order is known to the + manager. If the variable does not exist yet, the position is assumed to be + the same as the index. The group tree is created if it does not exist yet. + Returns a pointer to the group if successful; NULL otherwise. + + Side Effects: The variable tree is changed. + +MtrNode * +Cudd_MakeZddTreeNode( + DdManager * dd, manager + unsigned int low, index of the first group variable + unsigned int size, number of variables in the group + unsigned int type MTR_DEFAULT or MTR_FIXED +) + Creates a new ZDD variable group. The group starts at variable and contains + size variables. The parameter low is the index of the first variable. If the + variable already exists, its current position in the order is known to the + manager. If the variable does not exist yet, the position is assumed to be + the same as the index. The group tree is created if it does not exist yet. + Returns a pointer to the group if successful; NULL otherwise. + + Side Effects: The ZDD variable tree is changed. + +int +Cudd_MinHammingDist( + DdManager * dd, DD manager + DdNode * f, function to examine + int * minterm, reference minterm + int upperBound distance above which an approximate + answer is OK +) + Returns the minimum Hamming distance between the minterms of a function f + and a reference minterm. The function is given as a BDD; the minterm is + given as an array of integers, one for each variable in the manager. Returns + the minimum distance if it is less than the upper bound; the upper bound if + the minimum distance is at least as large; CUDD_OUT_OF_MEM in case of + failure. + + Side Effects: None + +DdApaNumber +Cudd_NewApaNumber( + int digits +) + Allocates memory for an arbitrary precision integer. Returns a pointer to + the allocated memory if successful; NULL otherwise. + + Side Effects: None + +int +Cudd_NextCube( + DdGen * gen, + int ** cube, + CUDD_VALUE_TYPE * value +) + Generates the next cube of a decision diagram onset, using generator gen. + Returns 0 if the enumeration is completed; 1 otherwise. + + Side Effects: The cube and its value are returned as side effects. The + generator is modified. + +int +Cudd_NextNode( + DdGen * gen, + DdNode ** node +) + Finds the node of a decision diagram, using generator gen. Returns 0 if the + enumeration is completed; 1 otherwise. + + Side Effects: The next node is returned as a side effect. + +int +Cudd_NextPrime( + DdGen * gen, + int ** cube +) + Generates the next cube of a Boolean function, using generator gen. Returns + 0 if the enumeration is completed; 1 otherwise. + + Side Effects: The cube and is returned as side effects. The generator is + modified. + +unsigned int +Cudd_NodeReadIndex( + DdNode * node +) + Returns the index of the node. The node pointer can be either regular or + complemented. + + Side Effects: None + +int +Cudd_OrderingMonitoring( + DdManager * dd +) + Returns 1 if monitoring of ordering is enabled; 0 otherwise. + + Side Effects: none + +void +Cudd_OutOfMem( + long size size of the allocation that failed +) + Warns that a memory allocation failed. This function can be used as + replacement of MMout_of_memory to prevent the safe_mem functions of the util + package from exiting when malloc returns NULL. One possible use is in case + of discretionary allocations; for instance, the allocation of memory to + enlarge the computed table. + + Side Effects: None + +DdNode * +Cudd_OverApprox( + DdManager * dd, manager + DdNode * f, function to be superset + int numVars, number of variables in the support of f + int threshold, when to stop approximation + int safe, enforce safe approximation + double quality minimum improvement for accepted changes +) + Extracts a dense superset from a BDD. The procedure is identical to the + underapproximation procedure except for the fact that it works on the + complement of the given function. Extracting the subset of the complement + function is equivalent to extracting the superset of the function. Returns a + pointer to the BDD of the superset if successful. NULL if intermediate + result causes the procedure to run out of memory. The parameter numVars is + the maximum number of variables to be used in minterm calculation. The + optimal number should be as close as possible to the size of the support of + f. However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is larger + than 1023, it will overflow. If a 0 parameter is passed then the procedure + will compute a value which will avoid overflow but will cause underflow with + 2046 variables or more. + + Side Effects: None + +unsigned int +Cudd_Prime( + unsigned int p +) + Returns the next prime >= p. + + Side Effects: None + +int +Cudd_PrintDebug( + DdManager * dd, + DdNode * f, + int n, + int pr +) + Prints to the standard output a DD and its statistics. The statistics + include the number of nodes, the number of leaves, and the number of + minterms. (The number of minterms is the number of assignments to the + variables that cause the function to be different from the logical zero (for + BDDs) and from the background value (for ADDs.) The statistics are printed + if pr > 0. Specifically: pr = 0 : prints nothing pr = 1 : + prints counts of nodes and minterms pr = 2 : prints counts + disjoint + sum of product pr = 3 : prints counts + list of nodes pr > 3 : + prints counts + disjoint sum of product + list of nodes For the + purpose of counting the number of minterms, the function is supposed to + depend on n variables. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_PrintGroupedOrder( + DdManager * dd, + const char * str, + void * data +) + Hook function to print the current variable order. It may be called before + or after reordering. Prints on the manager's stdout a parenthesized list + that describes the variable groups. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_PrintInfo( + DdManager * dd, + FILE * fp +) + Prints out statistics and settings for a CUDD manager. Returns 1 if + successful; 0 otherwise. + + Side Effects: None + +int +Cudd_PrintLinear( + DdManager * table +) + Prints the linear transform matrix. Returns 1 in case of success; 0 + otherwise. + + Side Effects: none + +int +Cudd_PrintMinterm( + DdManager * manager, + DdNode * node +) + Prints a disjoint sum of product cover for the function rooted at node. Each + product corresponds to a path from node to a leaf node different from the + logical zero, and different from the background value. Uses the package + default output file. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_PrintTwoLiteralClauses( + DdManager * dd, + DdNode * f, + char ** names, + FILE * fp +) + Prints the one- and two-literal clauses. Returns 1 if successful; 0 + otherwise. The argument "names" can be NULL, in which case the variable + indices are printed. + + Side Effects: None + +void +Cudd_PrintVersion( + FILE * fp +) + Prints the package version number. + + Side Effects: None + +DdNode * +Cudd_PrioritySelect( + DdManager * dd, manager + DdNode * R, BDD of the relation + DdNode ** x, array of x variables + DdNode ** y, array of y variables + DdNode ** z, array of z variables (optional: may be + NULL) + DdNode * Pi, BDD of the priority function (optional: + may be NULL) + int n, size of x, y, and z + DD_PRFP Pifunc function used to build Pi if it is NULL +) + Selects pairs from a relation R(x,y) (given as a BDD) in such a way that a + given x appears in one pair only. Uses a priority function to determine + which y should be paired to a given x. Cudd_PrioritySelect returns a pointer + to the selected function if successful; NULL otherwise. Three of the + arguments--x, y, and z--are vectors of BDD variables. The first two are the + variables on which R depends. The third vector is a vector of auxiliary + variables, used during the computation. This vector is optional. If a NULL + value is passed instead, Cudd_PrioritySelect will create the working + variables on the fly. The sizes of x and y (and z if it is not NULL) should + equal n. The priority function Pi can be passed as a BDD, or can be built by + Cudd_PrioritySelect. If NULL is passed instead of a DdNode *, parameter + Pifunc is used by Cudd_PrioritySelect to build a BDD for the priority + function. (Pifunc is a pointer to a C function.) If Pi is not NULL, then + Pifunc is ignored. Pifunc should have the same interface as the standard + priority functions (e.g., Cudd_Dxygtdxz). Cudd_PrioritySelect and + Cudd_CProjection can sometimes be used interchangeably. Specifically, + calling Cudd_PrioritySelect with Cudd_Xgty as Pifunc produces the same + result as calling Cudd_CProjection with the all-zero minterm as reference + minterm. However, depending on the application, one or the other may be + preferable: When extracting representatives from an equivalence + relation, Cudd_CProjection has the advantage of nor requiring the auxiliary + variables. When computing matchings in general bipartite graphs, + Cudd_PrioritySelect normally obtains better results because it can use more + powerful matching schemes (e.g., Cudd_Dxygtdxz). + + Side Effects: If called with z == NULL, will create new variables in the + manager. + +void +Cudd_Quit( + DdManager * unique +) + Deletes resources associated with a DD manager and resets the global + statistical counters. (Otherwise, another manaqger subsequently created + would inherit the stats of this one.) + + Side Effects: None + +long +Cudd_Random( + +) + Portable number generator based on ran2 from "Numerical Recipes in C." It is + a long period (> 2 * 10^18) random number generator of L'Ecuyer with Bays- + Durham shuffle. Returns a long integer uniformly distributed between 0 and + 2147483561 (inclusive of the endpoint values). The random generator can be + explicitly initialized by calling Cudd_Srandom. If no explicit + initialization is performed, then the seed 1 is assumed. + + Side Effects: None + +int +Cudd_ReadArcviolation( + DdManager * dd +) + Returns the current value of the arcviolation parameter. This parameter is + used in group sifting to decide how many arcs into y not coming + from x are tolerable when checking for aggregation due to + extended symmetry. The value should be between 0 and 100. A small value + causes fewer variables to be aggregated. The default value is 0. + + Side Effects: None + +DdNode * +Cudd_ReadBackground( + DdManager * dd +) + Reads the background constant of the manager. + + Side Effects: None + +double +Cudd_ReadCacheHits( + DdManager * dd +) + Returns the number of cache hits. + + Side Effects: None + +double +Cudd_ReadCacheLookUps( + DdManager * dd +) + Returns the number of cache look-ups. + + Side Effects: None + +unsigned int +Cudd_ReadCacheSlots( + DdManager * dd +) + Reads the number of slots in the cache. + + Side Effects: None + +double +Cudd_ReadCacheUsedSlots( + DdManager * dd +) + Reads the fraction of used slots in the cache. The unused slots are those in + which no valid data is stored. Garbage collection, variable reordering, and + cache resizing may cause used slots to become unused. + + Side Effects: None + +unsigned int +Cudd_ReadDead( + DdManager * dd +) + Returns the number of dead nodes in the unique table. + + Side Effects: None + +unsigned long +Cudd_ReadElapsedTime( + DdManager * unique +) + Returns the time elapsed since the start time of the manager. + + Side Effects: None + +CUDD_VALUE_TYPE +Cudd_ReadEpsilon( + DdManager * dd +) + Reads the epsilon parameter of the manager. The epsilon parameter control + the comparison between floating point numbers. + + Side Effects: None + +Cudd_ErrorType +Cudd_ReadErrorCode( + DdManager * dd +) + Returns the code of the last error. The error codes are defined in cudd.h. + + Side Effects: None + +long +Cudd_ReadGarbageCollectionTime( + DdManager * dd +) + Returns the number of milliseconds spent doing garbage collection since the + manager was initialized. + + Side Effects: None + +int +Cudd_ReadGarbageCollections( + DdManager * dd +) + Returns the number of times garbage collection has occurred in the manager. + The number includes both the calls from reordering procedures and those + caused by requests to create new nodes. + + Side Effects: None + +Cudd_AggregationType +Cudd_ReadGroupcheck( + DdManager * dd +) + Reads the groupcheck parameter of the manager. The groupcheck parameter + determines the aggregation criterion in group sifting. + + Side Effects: None + +int +Cudd_ReadInvPermZdd( + DdManager * dd, + int i +) + Returns the index of the ZDD variable currently in the i-th position of the + order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; + otherwise, if the index is out of bounds returns -1. + + Side Effects: None + +int +Cudd_ReadInvPerm( + DdManager * dd, + int i +) + Returns the index of the variable currently in the i-th position of the + order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; + otherwise, if the index is out of bounds returns -1. + + Side Effects: None + +int +Cudd_ReadIthClause( + DdTlcInfo * tlc, + int i, + DdHalfWord * var1, + DdHalfWord * var2, + int * phase1, + int * phase2 +) + Accesses the i-th clause of a DD given the clause set which must be already + computed. Returns 1 if successful; 0 if i is out of range, or in case of + error. + + Side Effects: the four components of a clause are returned as side effects. + +unsigned int +Cudd_ReadKeys( + DdManager * dd +) + Returns the total number of nodes currently in the unique table, including + the dead nodes. + + Side Effects: None + +int +Cudd_ReadLinear( + DdManager * table, CUDD manager + int x, row index + int y column index +) + Reads an entry of the linear transform matrix. + + Side Effects: none + +DdNode * +Cudd_ReadLogicZero( + DdManager * dd +) + Returns the zero constant of the manager. The logic zero constant is the + complement of the one constant, and is distinct from the arithmetic zero. + + Side Effects: None + +unsigned int +Cudd_ReadLooseUpTo( + DdManager * dd +) + Reads the looseUpTo parameter of the manager. + + Side Effects: None + +unsigned int +Cudd_ReadMaxCacheHard( + DdManager * dd +) + Reads the maxCacheHard parameter of the manager. + + Side Effects: None + +unsigned int +Cudd_ReadMaxCache( + DdManager * dd +) + Returns the soft limit for the cache size. + + Side Effects: None + +double +Cudd_ReadMaxGrowthAlternate( + DdManager * dd +) + Reads the maxGrowthAlt parameter of the manager. This parameter is analogous + to the maxGrowth paramter, and is used every given number of reorderings + instead of maxGrowth. The number of reorderings is set with + Cudd_SetReorderingCycle. If the number of reorderings is 0 (default) + maxGrowthAlt is never used. + + Side Effects: None + +double +Cudd_ReadMaxGrowth( + DdManager * dd +) + Reads the maxGrowth parameter of the manager. This parameter determines how + much the number of nodes can grow during sifting of a variable. Overall, + sifting never increases the size of the decision diagrams. This parameter + only refers to intermediate results. A lower value will speed up sifting, + possibly at the expense of quality. + + Side Effects: None + +unsigned int +Cudd_ReadMaxLive( + DdManager * dd +) + Reads the maximum allowed number of live nodes. When this number is + exceeded, the package returns NULL. + + Side Effects: none + +unsigned long +Cudd_ReadMaxMemory( + DdManager * dd +) + Reads the maximum allowed memory. When this number is exceeded, the package + returns NULL. + + Side Effects: none + +unsigned int +Cudd_ReadMaxReorderings( + DdManager * dd +) + Returns the maximum number of times reordering may be invoked in this + manager. + + Side Effects: None + +unsigned long +Cudd_ReadMemoryInUse( + DdManager * dd +) + Returns the memory in use by the manager measured in bytes. + + Side Effects: None + +unsigned int +Cudd_ReadMinDead( + DdManager * dd +) + Reads the minDead parameter of the manager. The minDead parameter is used by + the package to decide whether to collect garbage or resize a subtable of the + unique table when the subtable becomes too full. The application can + indirectly control the value of minDead by setting the looseUpTo parameter. + + Side Effects: None + +unsigned int +Cudd_ReadMinHit( + DdManager * dd +) + Reads the hit rate that causes resizinig of the computed table. + + Side Effects: None + +DdNode * +Cudd_ReadMinusInfinity( + DdManager * dd +) + Reads the minus-infinity constant from the manager. + + Side Effects: None + +unsigned int +Cudd_ReadNextReordering( + DdManager * dd +) + Returns the threshold for the next dynamic reordering. The threshold is in + terms of number of nodes and is in effect only if reordering is enabled. The + count does not include the dead nodes, unless the countDead parameter of the + manager has been changed from its default setting. + + Side Effects: None + +long +Cudd_ReadNodeCount( + DdManager * dd +) + Reports the number of live nodes in BDDs and ADDs. This number does not + include the isolated projection functions and the unused constants. These + nodes that are not counted are not part of the DDs manipulated by the + application. + + Side Effects: None + +double +Cudd_ReadNodesDropped( + DdManager * dd +) + Returns the number of nodes killed by dereferencing if the keeping of this + statistic is enabled; -1 otherwise. This statistic is enabled only if the + package is compiled with DD_STATS defined. + + Side Effects: None + +double +Cudd_ReadNodesFreed( + DdManager * dd +) + Returns the number of nodes returned to the free list if the keeping of this + statistic is enabled; -1 otherwise. This statistic is enabled only if the + package is compiled with DD_STATS defined. + + Side Effects: None + +int +Cudd_ReadNumberXovers( + DdManager * dd +) + Reads the current number of crossovers used by the genetic algorithm for + variable reordering. A larger number of crossovers will cause the genetic + algorithm to take more time, but will generally produce better results. The + default value is 0, in which case the package uses three times the number of + variables as number of crossovers, with a maximum of 60. + + Side Effects: None + +DdNode * +Cudd_ReadOne( + DdManager * dd +) + Returns the one constant of the manager. The one constant is common to ADDs + and BDDs. + + Side Effects: None + +unsigned int +Cudd_ReadOrderRandomization( + DdManager * dd +) + Returns the order randomization factor. If non-zero this factor is used to + determine a perturbation of the next reordering threshold. Larger factors + cause larger perturbations. + + Side Effects: None + +int +Cudd_ReadPeakLiveNodeCount( + DdManager * dd +) + Reports the peak number of live nodes. + + Side Effects: None + +long +Cudd_ReadPeakNodeCount( + DdManager * dd +) + Reports the peak number of nodes. This number includes node on the free + list. At the peak, the number of nodes on the free list is guaranteed to be + less than DD_MEM_CHUNK. + + Side Effects: None + +int +Cudd_ReadPermZdd( + DdManager * dd, + int i +) + Returns the current position of the i-th ZDD variable in the order. If the + index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index + is out of bounds returns -1. + + Side Effects: None + +int +Cudd_ReadPerm( + DdManager * dd, + int i +) + Returns the current position of the i-th variable in the order. If the index + is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index is + out of bounds returns -1. + + Side Effects: None + +DdNode * +Cudd_ReadPlusInfinity( + DdManager * dd +) + Reads the plus-infinity constant from the manager. + + Side Effects: None + +int +Cudd_ReadPopulationSize( + DdManager * dd +) + Reads the current size of the population used by the genetic algorithm for + variable reordering. A larger population size will cause the genetic + algorithm to take more time, but will generally produce better results. The + default value is 0, in which case the package uses three times the number of + variables as population size, with a maximum of 120. + + Side Effects: None + +int +Cudd_ReadRecomb( + DdManager * dd +) + Returns the current value of the recombination parameter used in group + sifting. A larger (positive) value makes the aggregation of variables due to + the second difference criterion more likely. A smaller (negative) value + makes aggregation less likely. + + Side Effects: None + +double +Cudd_ReadRecursiveCalls( + DdManager * dd +) + Returns the number of recursive calls if the package is compiled with + DD_COUNT defined. + + Side Effects: None + +int +Cudd_ReadReorderingCycle( + DdManager * dd +) + Reads the reordCycle parameter of the manager. This parameter determines how + often the alternate threshold on maximum growth is used in reordering. + + Side Effects: None + +long +Cudd_ReadReorderingTime( + DdManager * dd +) + Returns the number of milliseconds spent reordering variables since the + manager was initialized. The time spent in collecting garbage before + reordering is included. + + Side Effects: None + +unsigned int +Cudd_ReadReorderings( + DdManager * dd +) + Returns the number of times reordering has occurred in the manager. The + number includes both the calls to Cudd_ReduceHeap from the application + program and those automatically performed by the package. However, calls + that do not even initiate reordering are not counted. A call may not + initiate reordering if there are fewer than minsize live nodes in the + manager, or if CUDD_REORDER_NONE is specified as reordering method. The + calls to Cudd_ShuffleHeap are not counted. + + Side Effects: None + +int +Cudd_ReadSiftMaxSwap( + DdManager * dd +) + Reads the siftMaxSwap parameter of the manager. This parameter gives the + maximum number of swaps that will be attempted for each invocation of + sifting. The real number of swaps may exceed the set limit because the + package will always complete the sifting of the variable that causes the + limit to be reached. + + Side Effects: None + +int +Cudd_ReadSiftMaxVar( + DdManager * dd +) + Reads the siftMaxVar parameter of the manager. This parameter gives the + maximum number of variables that will be sifted for each invocation of + sifting. + + Side Effects: None + +int +Cudd_ReadSize( + DdManager * dd +) + Returns the number of BDD variables in existance. + + Side Effects: None + +unsigned int +Cudd_ReadSlots( + DdManager * dd +) + Returns the total number of slots of the unique table. This number ismainly + for diagnostic purposes. + + Side Effects: None + +unsigned long +Cudd_ReadStartTime( + DdManager * unique +) + Returns the start time of the manager. This is initially set to the number + of milliseconds since the program started, but may be reset by the + application. + + Side Effects: None + +FILE * +Cudd_ReadStderr( + DdManager * dd +) + Reads the stderr of a manager. This is the file pointer to which messages + normally going to stderr are written. It is initialized to stderr. + Cudd_SetStderr allows the application to redirect it. + + Side Effects: None + +FILE * +Cudd_ReadStdout( + DdManager * dd +) + Reads the stdout of a manager. This is the file pointer to which messages + normally going to stdout are written. It is initialized to stdout. + Cudd_SetStdout allows the application to redirect it. + + Side Effects: None + +double +Cudd_ReadSwapSteps( + DdManager * dd +) + Reads the number of elementary reordering steps. + + Side Effects: none + +int +Cudd_ReadSymmviolation( + DdManager * dd +) + Returns the current value of the symmviolation parameter. This parameter is + used in group sifting to decide how many violations to the symmetry + conditions f10 = f01 or f11 = f00 are tolerable + when checking for aggregation due to extended symmetry. The value should be + between 0 and 100. A small value causes fewer variables to be aggregated. + The default value is 0. + + Side Effects: None + +unsigned long +Cudd_ReadTimeLimit( + DdManager * unique +) + Returns the time limit for the manager. This is initially set to a very + large number, but may be reset by the application. + + Side Effects: None + +MtrNode * +Cudd_ReadTree( + DdManager * dd +) + Returns the variable group tree of the manager. + + Side Effects: None + +double +Cudd_ReadUniqueLinks( + DdManager * dd +) + Returns the number of links followed during look-ups in the unique table if + the keeping of this statistic is enabled; -1 otherwise. If an item is found + in the first position of its collision list, the number of links followed is + taken to be 0. If it is in second position, the number of links is 1, and so + on. This statistic is enabled only if the package is compiled with + DD_UNIQUE_PROFILE defined. + + Side Effects: None + +double +Cudd_ReadUniqueLookUps( + DdManager * dd +) + Returns the number of look-ups in the unique table if the keeping of this + statistic is enabled; -1 otherwise. This statistic is enabled only if the + package is compiled with DD_UNIQUE_PROFILE defined. + + Side Effects: None + +double +Cudd_ReadUsedSlots( + DdManager * dd +) + Reads the fraction of used slots in the unique table. The unused slots are + those in which no valid data is stored. Garbage collection, variable + reordering, and subtable resizing may cause used slots to become unused. + + Side Effects: None + +DdNode * +Cudd_ReadVars( + DdManager * dd, + int i +) + Returns the i-th element of the vars array if it falls within the array + bounds; NULL otherwise. If i is the index of an existing variable, this + function produces the same result as Cudd_bddIthVar. However, if the i-th + var does not exist yet, Cudd_bddIthVar will create it, whereas Cudd_ReadVars + will not. + + Side Effects: None + +DdNode * +Cudd_ReadZddOne( + DdManager * dd, + int i +) + Returns the ZDD for the constant 1 function. The representation of the + constant 1 function as a ZDD depends on how many variables it (nominally) + depends on. The index of the topmost variable in the support is given as + argument i. + + Side Effects: None + +int +Cudd_ReadZddSize( + DdManager * dd +) + Returns the number of ZDD variables in existance. + + Side Effects: None + +MtrNode * +Cudd_ReadZddTree( + DdManager * dd +) + Returns the variable group tree of the manager. + + Side Effects: None + +DdNode * +Cudd_ReadZero( + DdManager * dd +) + Returns the zero constant of the manager. The zero constant is the + arithmetic zero, rather than the logic zero. The latter is the complement of + the one constant. + + Side Effects: None + +void +Cudd_RecursiveDerefZdd( + DdManager * table, + DdNode * n +) + Decreases the reference count of ZDD node n. If n dies, recursively + decreases the reference counts of its children. It is used to dispose of a + ZDD that is no longer needed. + + Side Effects: None + +void +Cudd_RecursiveDeref( + DdManager * table, + DdNode * n +) + Decreases the reference count of node n. If n dies, recursively decreases + the reference counts of its children. It is used to dispose of a DD that is + no longer needed. + + Side Effects: None + +int +Cudd_ReduceHeap( + DdManager * table, DD manager + Cudd_ReorderingTy heuristic, method used for reordering + int minsize bound below which no reordering occurs +) + Main dynamic reordering routine. Calls one of the possible reordering + procedures: Swapping Sifting Symmetric Sifting Group + Sifting Window Permutation Simulated Annealing Genetic Algorithm + Dynamic Programming (exact) For sifting, symmetric sifting, group + sifting, and window permutation it is possible to request reordering to + convergence. The core of all methods is the reordering procedure + cuddSwapInPlace() which swaps two adjacent variables and is based on + Rudell's paper. Returns 1 in case of success; 0 otherwise. In the case of + symmetric sifting (with and without convergence) returns 1 plus the number + of symmetric variables, in case of success. + + Side Effects: Changes the variable order for all diagrams and clears the + cache. + +void +Cudd_Ref( + DdNode * n +) + Increases the reference count of a node, if it is not saturated. + + Side Effects: None + +DdNode * +Cudd_RemapOverApprox( + DdManager * dd, manager + DdNode * f, function to be superset + int numVars, number of variables in the support of f + int threshold, when to stop approximation + double quality minimum improvement for accepted changes +) + Extracts a dense superset from a BDD. The procedure is identical to the + underapproximation procedure except for the fact that it works on the + complement of the given function. Extracting the subset of the complement + function is equivalent to extracting the superset of the function. Returns a + pointer to the BDD of the superset if successful. NULL if intermediate + result causes the procedure to run out of memory. The parameter numVars is + the maximum number of variables to be used in minterm calculation. The + optimal number should be as close as possible to the size of the support of + f. However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is larger + than 1023, it will overflow. If a 0 parameter is passed then the procedure + will compute a value which will avoid overflow but will cause underflow with + 2046 variables or more. + + Side Effects: None + +DdNode * +Cudd_RemapUnderApprox( + DdManager * dd, manager + DdNode * f, function to be subset + int numVars, number of variables in the support of f + int threshold, when to stop approximation + double quality minimum improvement for accepted changes +) + Extracts a dense subset from a BDD. This procedure uses a remapping + technique and density as the cost function. Returns a pointer to the BDD of + the subset if successful. NULL if the procedure runs out of memory. The + parameter numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to the size + of the support of f. However, it is safe to pass the value returned by + Cudd_ReadSize for numVars when the number of variables is under 1023. If + numVars is larger than 1023, it will cause overflow. If a 0 parameter is + passed then the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more. + + Side Effects: None + +int +Cudd_RemoveHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where +) + Removes a function from a hook. A hook is a list of application-provided + functions called on certain occasions by the package. Returns 1 if + successful; 0 the function was not in the list. + + Side Effects: None + +int +Cudd_ReorderingReporting( + DdManager * dd +) + Returns 1 if reporting of reordering stats is enabled; 0 otherwise. + + Side Effects: none + +int +Cudd_ReorderingStatusZdd( + DdManager * unique, + Cudd_ReorderingTy method +) + Reports the status of automatic dynamic reordering of ZDDs. Parameter method + is set to the ZDD reordering method currently selected. Returns 1 if + automatic reordering is enabled; 0 otherwise. + + Side Effects: Parameter method is set to the ZDD reordering method currently + selected. + +int +Cudd_ReorderingStatus( + DdManager * unique, + Cudd_ReorderingTy method +) + Reports the status of automatic dynamic reordering of BDDs and ADDs. + Parameter method is set to the reordering method currently selected. Returns + 1 if automatic reordering is enabled; 0 otherwise. + + Side Effects: Parameter method is set to the reordering method currently + selected. + +int +Cudd_Reserve( + DdManager * manager, + int amount +) + Expand a manager by a specified number of subtables without actually + creating new variables. This function can be used to reduce the frequency of + resizing when an estimate of the number of variables is available. One would + call this function instead of passing the number of variables to Cudd_Init + if variables should not be created right away of if the estimate on their + number became available only after the manager has been created. Returns 1 + if successful; 0 otherwise. + + Side Effects: None + +void +Cudd_ResetStartTime( + DdManager * unique +) + Resets the start time of the manager. + + Side Effects: None + +void +Cudd_SetArcviolation( + DdManager * dd, + int arcviolation +) + Sets the value of the arcviolation parameter. This parameter is used in + group sifting to decide how many arcs into y not coming from + x are tolerable when checking for aggregation due to extended + symmetry. The value should be between 0 and 100. A small value causes fewer + variables to be aggregated. The default value is 0. + + Side Effects: None + +void +Cudd_SetBackground( + DdManager * dd, + DdNode * bck +) + Sets the background constant of the manager. It assumes that the DdNode + pointer bck is already referenced. + + Side Effects: None + +void +Cudd_SetEpsilon( + DdManager * dd, + CUDD_VALUE_TYPE ep +) + Sets the epsilon parameter of the manager to ep. The epsilon parameter + control the comparison between floating point numbers. + + Side Effects: None + +void +Cudd_SetGroupcheck( + DdManager * dd, + Cudd_AggregationT gc +) + Sets the parameter groupcheck of the manager to gc. The groupcheck parameter + determines the aggregation criterion in group sifting. + + Side Effects: None + +void +Cudd_SetLooseUpTo( + DdManager * dd, + unsigned int lut +) + Sets the looseUpTo parameter of the manager. This parameter of the manager + controls the threshold beyond which no fast growth of the unique table is + allowed. The threshold is given as a number of slots. If the value passed to + this function is 0, the function determines a suitable value based on the + available memory. + + Side Effects: None + +void +Cudd_SetMaxCacheHard( + DdManager * dd, + unsigned int mc +) + Sets the maxCacheHard parameter of the manager. The cache cannot grow larger + than maxCacheHard entries. This parameter allows an application to control + the trade-off of memory versus speed. If the value passed to this function + is 0, the function determines a suitable maximum cache size based on the + available memory. + + Side Effects: None + +void +Cudd_SetMaxGrowthAlternate( + DdManager * dd, + double mg +) + Sets the maxGrowthAlt parameter of the manager. This parameter is analogous + to the maxGrowth paramter, and is used every given number of reorderings + instead of maxGrowth. The number of reorderings is set with + Cudd_SetReorderingCycle. If the number of reorderings is 0 (default) + maxGrowthAlt is never used. + + Side Effects: None + +void +Cudd_SetMaxGrowth( + DdManager * dd, + double mg +) + Sets the maxGrowth parameter of the manager. This parameter determines how + much the number of nodes can grow during sifting of a variable. Overall, + sifting never increases the size of the decision diagrams. This parameter + only refers to intermediate results. A lower value will speed up sifting, + possibly at the expense of quality. + + Side Effects: None + +void +Cudd_SetMaxLive( + DdManager * dd, + unsigned int maxLive +) + Sets the maximum allowed number of live nodes. When this number is exceeded, + the package returns NULL. + + Side Effects: none + +void +Cudd_SetMaxMemory( + DdManager * dd, + unsigned long maxMemory +) + Sets the maximum allowed memory. When this number is exceeded, the package + returns NULL. + + Side Effects: none + +void +Cudd_SetMaxReorderings( + DdManager * dd, + unsigned int mr +) + Sets the maximum number of times reordering may be invoked in this manager. + The default value is (practically) infinite. + + Side Effects: None + +void +Cudd_SetMinHit( + DdManager * dd, + unsigned int hr +) + Sets the minHit parameter of the manager. This parameter controls the + resizing of the computed table. If the hit rate is larger than the specified + value, and the cache is not already too large, then its size is doubled. + + Side Effects: None + +void +Cudd_SetNextReordering( + DdManager * dd, + unsigned int next +) + Sets the threshold for the next dynamic reordering. The threshold is in + terms of number of nodes and is in effect only if reordering is enabled. The + count does not include the dead nodes, unless the countDead parameter of the + manager has been changed from its default setting. + + Side Effects: None + +void +Cudd_SetNumberXovers( + DdManager * dd, + int numberXovers +) + Sets the number of crossovers used by the genetic algorithm for variable + reordering. A larger number of crossovers will cause the genetic algorithm + to take more time, but will generally produce better results. The default + value is 0, in which case the package uses three times the number of + variables as number of crossovers, with a maximum of 60. + + Side Effects: None + +void +Cudd_SetOrderRandomization( + DdManager * dd, + unsigned int factor +) + Sets the order randomization factor. + + Side Effects: None + +void +Cudd_SetPopulationSize( + DdManager * dd, + int populationSize +) + Sets the size of the population used by the genetic algorithm for variable + reordering. A larger population size will cause the genetic algorithm to + take more time, but will generally produce better results. The default value + is 0, in which case the package uses three times the number of variables as + population size, with a maximum of 120. + + Side Effects: Changes the manager. + +void +Cudd_SetRecomb( + DdManager * dd, + int recomb +) + Sets the value of the recombination parameter used in group sifting. A + larger (positive) value makes the aggregation of variables due to the second + difference criterion more likely. A smaller (negative) value makes + aggregation less likely. The default value is 0. + + Side Effects: Changes the manager. + +void +Cudd_SetReorderingCycle( + DdManager * dd, + int cycle +) + Sets the reordCycle parameter of the manager. This parameter determines how + often the alternate threshold on maximum growth is used in reordering. + + Side Effects: None + +void +Cudd_SetSiftMaxSwap( + DdManager * dd, + int sms +) + Sets the siftMaxSwap parameter of the manager. This parameter gives the + maximum number of swaps that will be attempted for each invocation of + sifting. The real number of swaps may exceed the set limit because the + package will always complete the sifting of the variable that causes the + limit to be reached. + + Side Effects: None + +void +Cudd_SetSiftMaxVar( + DdManager * dd, + int smv +) + Sets the siftMaxVar parameter of the manager. This parameter gives the + maximum number of variables that will be sifted for each invocation of + sifting. + + Side Effects: None + +void +Cudd_SetStartTime( + DdManager * unique, + unsigned long st +) + Sets the start time of the manager. + + Side Effects: None + +void +Cudd_SetStderr( + DdManager * dd, + FILE * fp +) + Sets the stderr of a manager. + + Side Effects: None + +void +Cudd_SetStdout( + DdManager * dd, + FILE * fp +) + Sets the stdout of a manager. + + Side Effects: None + +void +Cudd_SetSymmviolation( + DdManager * dd, + int symmviolation +) + Sets the value of the symmviolation parameter. This parameter is used in + group sifting to decide how many violations to the symmetry conditions + f10 = f01 or f11 = f00 are tolerable when checking + for aggregation due to extended symmetry. The value should be between 0 and + 100. A small value causes fewer variables to be aggregated. The default + value is 0. + + Side Effects: Changes the manager. + +void +Cudd_SetTimeLimit( + DdManager * unique, + unsigned long tl +) + Sets the time limit for the manager. + + Side Effects: None + +void +Cudd_SetTree( + DdManager * dd, + MtrNode * tree +) + Sets the variable group tree of the manager. + + Side Effects: None + +int +Cudd_SetVarMap( + DdManager * manager, DD manager + DdNode ** x, first array of variables + DdNode ** y, second array of variables + int n length of both arrays +) + Registers with the manager a variable mapping described by two sets of + variables. This variable mapping is then used by functions like + Cudd_bddVarMap. This function is convenient for those applications that + perform the same mapping several times. However, if several different + permutations are used, it may be more efficient not to rely on the + registered mapping, because changing mapping causes the cache to be cleared. + (The initial setting, however, does not clear the cache.) The two sets of + variables (x and y) must have the same size (x and y). The size is given by + n. The two sets of variables are normally disjoint, but this restriction is + not imposeded by the function. When new variables are created, the map is + automatically extended (each new variable maps to itself). The typical use, + however, is to wait until all variables are created, and then create the + map. Returns 1 if the mapping is successfully registered with the manager; 0 + otherwise. + + Side Effects: Modifies the manager. May clear the cache. + +void +Cudd_SetZddTree( + DdManager * dd, + MtrNode * tree +) + Sets the ZDD variable group tree of the manager. + + Side Effects: None + +int +Cudd_SharingSize( + DdNode ** nodeArray, + int n +) + Counts the number of nodes in an array of DDs. Shared nodes are counted only + once. Returns the total number of nodes. + + Side Effects: None + +int +Cudd_ShortestLength( + DdManager * manager, + DdNode * f, + int * weight +) + Find the length of the shortest path(s) in a DD. f is the DD we want to get + the shortest path for; weight[i] is the weight of the THEN edge coming from + the node whose index is i. All ELSE edges have 0 weight. Returns the length + of the shortest path(s) if such a path is found; a large number if the + function is identically 0, and CUDD_OUT_OF_MEM in case of failure. + + Side Effects: None + +DdNode * +Cudd_ShortestPath( + DdManager * manager, + DdNode * f, + int * weight, + int * support, + int * length +) + Finds a shortest path in a DD. f is the DD we want to get the shortest path + for; weight[i] is the weight of the THEN arc coming from the node whose + index is i. If weight is NULL, then unit weights are assumed for all THEN + arcs. All ELSE arcs have 0 weight. If non-NULL, both weight and support + should point to arrays with at least as many entries as there are variables + in the manager. Returns the shortest path as the BDD of a cube. + + Side Effects: support contains on return the true support of f. If support + is NULL on entry, then Cudd_ShortestPath does not compute the true support + info. length contains the length of the path. + +int +Cudd_ShuffleHeap( + DdManager * table, DD manager + int * permutation required variable permutation +) + Reorders variables according to given permutation. The i-th entry of the + permutation array contains the index of the variable that should be brought + to the i-th level. The size of the array should be equal or greater to the + number of variables currently in use. Returns 1 in case of success; 0 + otherwise. + + Side Effects: Changes the variable order for all diagrams and clears the + cache. + +DdNode * +Cudd_SolveEqn( + DdManager * bdd, + DdNode * F, the left-hand side of the equation + DdNode * Y, the cube of the y variables + DdNode ** G, the array of solutions (return parameter) + int ** yIndex, index of y variables + int n numbers of unknowns +) + Implements the solution for F(x,y) = 0. The return value is the consistency + condition. The y variables are the unknowns and the remaining variables are + the parameters. Returns the consistency condition if successful; NULL + otherwise. Cudd_SolveEqn allocates an array and fills it with the indices of + the unknowns. This array is used by Cudd_VerifySol. + + Side Effects: The solution is returned in G; the indices of the y variables + are returned in yIndex. + +DdNode * +Cudd_SplitSet( + DdManager * manager, + DdNode * S, + DdNode ** xVars, + int n, + double m +) + Returns m minterms from a BDD whose support has n + variables at most. The procedure tries to create as few extra nodes as + possible. The function represented by S depends on at most + n of the variables in xVars. Returns a BDD with + m minterms of the on-set of S if successful; NULL otherwise. + + Side Effects: None + +void +Cudd_Srandom( + long seed +) + Initializer for the portable number generator based on ran2 in "Numerical + Recipes in C." The input is the seed for the generator. If it is negative, + its absolute value is taken as seed. If it is 0, then 1 is taken as seed. + The initialized sets up the two recurrences used to generate a long-period + stream, and sets up the shuffle table. + + Side Effects: None + +int +Cudd_StdPostReordHook( + DdManager * dd, + const char * str, + void * data +) + Sample hook function to call after reordering. Prints on the manager's + stdout final size and reordering time. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_StdPreReordHook( + DdManager * dd, + const char * str, + void * data +) + Sample hook function to call before reordering. Prints on the manager's + stdout reordering method and initial size. Returns 1 if successful; 0 + otherwise. + + Side Effects: None + +DdNode * +Cudd_SubsetCompress( + DdManager * dd, manager + DdNode * f, BDD whose subset is sought + int nvars, number of variables in the support of f + int threshold maximum number of nodes in the subset +) + Finds a dense subset of BDD f. Density is the ratio of number + of minterms to number of nodes. Uses several techniques in series. It is + more expensive than other subsetting procedures, but often produces better + results. See Cudd_SubsetShortPaths for a description of the threshold and + nvars parameters. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_SubsetHeavyBranch( + DdManager * dd, manager + DdNode * f, function to be subset + int numVars, number of variables in the support of f + int threshold maximum number of nodes in the subset +) + Extracts a dense subset from a BDD. This procedure builds a subset by + throwing away one of the children of each node, starting from the root, + until the result is small enough. The child that is eliminated from the + result is the one that contributes the fewer minterms. Returns a pointer to + the BDD of the subset if successful. NULL if the procedure runs out of + memory. The parameter numVars is the maximum number of variables to be used + in minterm calculation and node count calculation. The optimal number should + be as close as possible to the size of the support of f. However, it is safe + to pass the value returned by Cudd_ReadSize for numVars when the number of + variables is under 1023. If numVars is larger than 1023, it will overflow. + If a 0 parameter is passed then the procedure will compute a value which + will avoid overflow but will cause underflow with 2046 variables or more. + + Side Effects: None + +DdNode * +Cudd_SubsetShortPaths( + DdManager * dd, manager + DdNode * f, function to be subset + int numVars, number of variables in the support of f + int threshold, maximum number of nodes in the subset + int hardlimit flag: 1 if threshold is a hard limit +) + Extracts a dense subset from a BDD. This procedure tries to preserve the + shortest paths of the input BDD, because they give many minterms and + contribute few nodes. This procedure may increase the number of nodes in + trying to create the subset or reduce the number of nodes due to + recombination as compared to the original BDD. Hence the threshold may not + be strictly adhered to. In practice, recombination overshadows the increase + in the number of nodes and results in small BDDs as compared to the + threshold. The hardlimit specifies whether threshold needs to be strictly + adhered to. If it is set to 1, the procedure ensures that result is never + larger than the specified limit but may be considerably less than the + threshold. Returns a pointer to the BDD for the subset if successful; NULL + otherwise. The value for numVars should be as close as possible to the size + of the support of f for better efficiency. However, it is safe to pass the + value returned by Cudd_ReadSize for numVars. If 0 is passed, then the value + returned by Cudd_ReadSize is used. + + Side Effects: None + +DdNode * +Cudd_SubsetWithMaskVars( + DdManager * dd, manager + DdNode * f, function from which to pick a cube + DdNode ** vars, array of variables + int nvars, size of vars + DdNode ** maskVars, array of variables + int mvars size of maskVars +) + Extracts a subset from a BDD in the following procedure. 1. Compute the + weight for each mask variable by counting the number of minterms for both + positive and negative cofactors of the BDD with respect to each mask + variable. (weight = #positive - #negative) 2. Find a representative cube of + the BDD by using the weight. From the top variable of the BDD, for each + variable, if the weight is greater than 0.0, choose THEN branch, othereise + ELSE branch, until meeting the constant 1. 3. Quantify out the variables not + in maskVars from the representative cube and if a variable in maskVars is + don't care, replace the variable with a constant(1 or 0) depending on the + weight. 4. Make a subset of the BDD by multiplying with the modified cube. + + Side Effects: None + +DdNode * +Cudd_SupersetCompress( + DdManager * dd, manager + DdNode * f, BDD whose superset is sought + int nvars, number of variables in the support of f + int threshold maximum number of nodes in the superset +) + Finds a dense superset of BDD f. Density is the ratio of number + of minterms to number of nodes. Uses several techniques in series. It is + more expensive than other supersetting procedures, but often produces better + results. See Cudd_SupersetShortPaths for a description of the threshold and + nvars parameters. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_SupersetHeavyBranch( + DdManager * dd, manager + DdNode * f, function to be superset + int numVars, number of variables in the support of f + int threshold maximum number of nodes in the superset +) + Extracts a dense superset from a BDD. The procedure is identical to the + subset procedure except for the fact that it receives the complement of the + given function. Extracting the subset of the complement function is + equivalent to extracting the superset of the function. This procedure builds + a superset by throwing away one of the children of each node starting from + the root of the complement function, until the result is small enough. The + child that is eliminated from the result is the one that contributes the + fewer minterms. Returns a pointer to the BDD of the superset if successful. + NULL if intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in minterm + calculation and node count calculation. The optimal number should be as + close as possible to the size of the support of f. However, it is safe to + pass the value returned by Cudd_ReadSize for numVars when the number of + variables is under 1023. If numVars is larger than 1023, it will overflow. + If a 0 parameter is passed then the procedure will compute a value which + will avoid overflow but will cause underflow with 2046 variables or more. + + Side Effects: None + +DdNode * +Cudd_SupersetShortPaths( + DdManager * dd, manager + DdNode * f, function to be superset + int numVars, number of variables in the support of f + int threshold, maximum number of nodes in the subset + int hardlimit flag: 1 if threshold is a hard limit +) + Extracts a dense superset from a BDD. The procedure is identical to the + subset procedure except for the fact that it receives the complement of the + given function. Extracting the subset of the complement function is + equivalent to extracting the superset of the function. This procedure tries + to preserve the shortest paths of the complement BDD, because they give many + minterms and contribute few nodes. This procedure may increase the number of + nodes in trying to create the superset or reduce the number of nodes due to + recombination as compared to the original BDD. Hence the threshold may not + be strictly adhered to. In practice, recombination overshadows the increase + in the number of nodes and results in small BDDs as compared to the + threshold. The hardlimit specifies whether threshold needs to be strictly + adhered to. If it is set to 1, the procedure ensures that result is never + larger than the specified limit but may be considerably less than the + threshold. Returns a pointer to the BDD for the superset if successful; NULL + otherwise. The value for numVars should be as close as possible to the size + of the support of f for better efficiency. However, it is safe to pass the + value returned by Cudd_ReadSize for numVar. If 0 is passed, then the value + returned by Cudd_ReadSize is used. + + Side Effects: None + +int * +Cudd_SupportIndex( + DdManager * dd, manager + DdNode * f DD whose support is sought +) + Finds the variables on which a DD depends. Returns an index array of the + variables if successful; NULL otherwise. The size of the array equals the + number of variables in the manager. Each entry of the array is 1 if the + corresponding variable is in the support of the DD and 0 otherwise. + + Side Effects: None + +int +Cudd_SupportIndices( + DdManager * dd, manager + DdNode * f, DD whose support is sought + int ** indices array containing (on return) the indices +) + Finds the variables on which a DD depends. Returns the number of variables + if successful; CUDD_OUT_OF_MEM otherwise. + + Side Effects: The indices of the support variables are returned as side + effects. If the function is constant, no array is allocated. + +int +Cudd_SupportSize( + DdManager * dd, manager + DdNode * f DD whose support size is sought +) + Returns the variables on which a DD depends. + + Side Effects: None + +DdNode * +Cudd_Support( + DdManager * dd, manager + DdNode * f DD whose support is sought +) + Finds the variables on which a DD depends. Returns a BDD consisting of the + product of the variables if successful; NULL otherwise. + + Side Effects: None + +void +Cudd_SymmProfile( + DdManager * table, + int lower, + int upper +) + Prints statistics on symmetric variables. + + Side Effects: None + +int +Cudd_TimeLimited( + DdManager * unique +) + Returns true if the time limit for the manager is set. + + Side Effects: None + +void +Cudd_TurnOffCountDead( + DdManager * dd +) + Causes the dead nodes not to be counted towards triggering reordering. This + causes less frequent reorderings. By default dead nodes are not counted. + Therefore there is no need to call this function unless Cudd_TurnOnCountDead + has been previously called. + + Side Effects: Changes the manager. + +void +Cudd_TurnOnCountDead( + DdManager * dd +) + Causes the dead nodes to be counted towards triggering reordering. This + causes more frequent reorderings. By default dead nodes are not counted. + + Side Effects: Changes the manager. + +DdNode * +Cudd_UnderApprox( + DdManager * dd, manager + DdNode * f, function to be subset + int numVars, number of variables in the support of f + int threshold, when to stop approximation + int safe, enforce safe approximation + double quality minimum improvement for accepted changes +) + Extracts a dense subset from a BDD. This procedure uses a variant of Tom + Shiple's underapproximation method. The main difference from the original + method is that density is used as cost function. Returns a pointer to the + BDD of the subset if successful. NULL if the procedure runs out of memory. + The parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value returned + by Cudd_ReadSize for numVars when the number of variables is under 1023. If + numVars is larger than 1023, it will cause overflow. If a 0 parameter is + passed then the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more. + + Side Effects: None + +void +Cudd_UnsetTimeLimit( + DdManager * unique +) + Unsets the time limit for the manager. Actually, sets it to a very large + value. + + Side Effects: None + +void +Cudd_UpdateTimeLimit( + DdManager * unique +) + Updates the time limit for the manager by subtracting the elapsed time from + it. + + Side Effects: None + +int * +Cudd_VectorSupportIndex( + DdManager * dd, manager + DdNode ** F, array of DDs whose support is sought + int n size of the array +) + Finds the variables on which a set of DDs depends. The set must contain + either BDDs and ADDs, or ZDDs. Returns an index array of the variables if + successful; NULL otherwise. + + Side Effects: None + +int +Cudd_VectorSupportIndices( + DdManager * dd, manager + DdNode ** F, DD whose support is sought + int n, size of the array + int ** indices array containing (on return) the indices +) + Finds the variables on which a set of DDs depends. The set must contain + either BDDs and ADDs, or ZDDs. Returns the number of variables if + successful; CUDD_OUT_OF_MEM otherwise. + + Side Effects: The indices of the support variables are returned as side + effects. If the function is constant, no array is allocated. + +int +Cudd_VectorSupportSize( + DdManager * dd, manager + DdNode ** F, array of DDs whose support is sought + int n size of the array +) + Returns the variables on which a set of DDs depends. The set must contain + either BDDs and ADDs, or ZDDs. + + Side Effects: None + +DdNode * +Cudd_VectorSupport( + DdManager * dd, manager + DdNode ** F, array of DDs whose support is sought + int n size of the array +) + Finds the variables on which a set of DDs depends. The set must contain + either BDDs and ADDs, or ZDDs. Returns a BDD consisting of the product of + the variables if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_VerifySol( + DdManager * bdd, + DdNode * F, the left-hand side of the equation + DdNode ** G, the array of solutions + int * yIndex, index of y variables + int n numbers of unknowns +) + Checks the solution of F(x,y) = 0. This procedure substitutes the solution + components for the unknowns of F and returns the resulting BDD for F. + + Side Effects: Frees the memory pointed by yIndex. + +DdNode * +Cudd_Xeqy( + DdManager * dd, DD manager + int N, number of x and y variables + DdNode ** x, array of x variables + DdNode ** y array of y variables +) + This function generates a BDD for the function x==y. Both x and y are N-bit + numbers, x[0] x[1] ... x[N-1] and y[0] y[1] ... y[N-1], with 0 the most + significant bit. The BDD is built bottom-up. It has 3*N-1 internal nodes, if + the variables are ordered as follows: x[0] y[0] x[1] y[1] ... x[N-1] y[N-1]. + + Side Effects: None + +DdNode * +Cudd_Xgty( + DdManager * dd, DD manager + int N, number of x and y variables + DdNode ** z, array of z variables: unused + DdNode ** x, array of x variables + DdNode ** y array of y variables +) + This function generates a BDD for the function x > y. Both x and y are N- + bit numbers, x[0] x[1] ... x[N-1] and y[0] y[1] ... y[N-1], with 0 the most + significant bit. The BDD is built bottom-up. It has 3*N-1 internal nodes, if + the variables are ordered as follows: x[0] y[0] x[1] y[1] ... x[N-1] y[N-1]. + Argument z is not used by Cudd_Xgty: it is included to make it call- + compatible to Cudd_Dxygtdxz and Cudd_Dxygtdyz. + + Side Effects: None + +DdNode * +Cudd_addAgreement( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Returns NULL if not a terminal case; f op g otherwise, where f op g is f if + f==g; background if f!=g. + + Side Effects: None + +DdNode * +Cudd_addApply( + DdManager * dd, + DD_AOP op, + DdNode * f, + DdNode * g +) + Applies op to the corresponding discriminants of f and g. Returns a pointer + to the result if succssful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddInterval( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE lower, + CUDD_VALUE_TYPE upper +) + Converts an ADD to a BDD by replacing all discriminants greater than or + equal to lower and less than or equal to upper with 1, and all other + discriminants with 0. Returns a pointer to the resulting BDD if successful; + NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddIthBit( + DdManager * dd, + DdNode * f, + int bit +) + Converts an ADD to a BDD by replacing all discriminants whose i-th bit is + equal to 1 with 1, and all other discriminants with 0. The i-th bit refers + to the integer representation of the leaf value. If the value is has a + fractional part, it is ignored. Repeated calls to this procedure allow one + to transform an integer-valued ADD into an array of BDDs, one for each bit + of the leaf values. Returns a pointer to the resulting BDD if successful; + NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddPattern( + DdManager * dd, + DdNode * f +) + Converts an ADD to a BDD by replacing all discriminants different from 0 + with 1. Returns a pointer to the resulting BDD if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddStrictThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value +) + Converts an ADD to a BDD by replacing all discriminants STRICTLY greater + than value with 1, and all other discriminants with 0. Returns a pointer to + the resulting BDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value +) + Converts an ADD to a BDD by replacing all discriminants greater than or + equal to value with 1, and all other discriminants with 0. Returns a pointer + to the resulting BDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addCmpl( + DdManager * dd, + DdNode * f +) + Computes the complement of an ADD a la C language: The complement of 0 is 1 + and the complement of everything else is 0. Returns a pointer to the + resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addCompose( + DdManager * dd, + DdNode * f, + DdNode * g, + int v +) + Substitutes g for x_v in the ADD for f. v is the index of the variable to be + substituted. g must be a 0-1 ADD. Cudd_bddCompose passes the corresponding + projection function to the recursive procedure, so that the cache may be + used. Returns the composed ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addComputeCube( + DdManager * dd, + DdNode ** vars, + int * phase, + int n +) + Computes the cube of an array of ADD variables. If non-null, the phase + argument indicates which literal of each variable should appear in the cube. + If phase[i] is nonzero, then the positive literal is used. If phase is NULL, + the cube is positive unate. Returns a pointer to the result if successful; + NULL otherwise. + + Side Effects: none + +DdNode * +Cudd_addConstrain( + DdManager * dd, + DdNode * f, + DdNode * c +) + Computes f constrain c (f @ c), for f an ADD and c a 0-1 ADD. List of + special cases: F @ 0 = 0 F @ 1 = F 0 @ c = 0 1 @ c + = 1 F @ F = 1 Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_addConst( + DdManager * dd, + CUDD_VALUE_TYPE c +) + Retrieves the ADD for constant c if it already exists, or creates a new ADD. + Returns a pointer to the ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addDiff( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Returns NULL if not a terminal case; f op g otherwise, where f op g is + plusinfinity if f=g; min(f,g) if f!=g. + + Side Effects: None + +DdNode * +Cudd_addDivide( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point division. Returns NULL if not a terminal case; f + / g otherwise. + + Side Effects: None + +DdNode * +Cudd_addEvalConst( + DdManager * dd, + DdNode * f, + DdNode * g +) + Checks whether ADD g is constant whenever ADD f is 1. f must be a 0-1 ADD. + Returns a pointer to the resulting ADD (which may or may not be constant) or + DD_NON_CONSTANT. If f is identically 0, the check is assumed to be + successful, and the background value is returned. No new nodes are created. + + Side Effects: None + +DdNode * +Cudd_addExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube +) + Abstracts all the variables in cube from f by summing over all possible + values taken by the variables. Returns the abstracted ADD. + + Side Effects: None + +DdNode * +Cudd_addFindMax( + DdManager * dd, + DdNode * f +) + Returns a pointer to a constant ADD. + + Side Effects: None + +DdNode * +Cudd_addFindMin( + DdManager * dd, + DdNode * f +) + Returns a pointer to a constant ADD. + + Side Effects: None + +DdNode * +Cudd_addGeneralVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vectorOn, + DdNode ** vectorOff +) + Given a vector of ADDs, creates a new ADD by substituting the ADDs for the + variables of the ADD f. vectorOn contains ADDs to be substituted for the x_v + and vectorOff the ADDs to be substituted for x_v'. There should be an entry + in vector for each variable in the manager. If no substitution is sought for + a given variable, the corresponding projection function should be specified + in the vector. This function implements simultaneous composition. Returns a + pointer to the resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addHamming( + DdManager * dd, + DdNode ** xVars, + DdNode ** yVars, + int nVars +) + Computes the Hamming distance ADD. Returns an ADD that gives the Hamming + distance between its two arguments if successful; NULL otherwise. The two + vectors xVars and yVars identify the variables that form the two arguments. + + Side Effects: None + +int +Cudd_addHarwell( + FILE * fp, pointer to the input file + DdManager * dd, DD manager + DdNode ** E, characteristic function of the graph + DdNode *** x, array of row variables + DdNode *** y, array of column variables + DdNode *** xn, array of complemented row variables + DdNode *** yn_, array of complemented column variables + int * nx, number or row variables + int * ny, number or column variables + int * m, number of rows + int * n, number of columns + int bx, first index of row variables + int sx, step of row variables + int by, first index of column variables + int sy, step of column variables + int pr verbosity level +) + Reads in a matrix in the format of the Harwell-Boeing benchmark suite. The + variables are ordered as follows: x[0] y[0] x[1] y[1] ... + 0 is the most significant bit. On input, nx and ny hold the + numbers of row and column variables already in existence. On output, they + hold the numbers of row and column variables actually used by the matrix. m + and n are set to the numbers of rows and columns of the matrix. Their values + on input are immaterial. Returns 1 on success; 0 otherwise. The ADD for the + sparse matrix is returned in E, and its reference count is > 0. + + Side Effects: None + +DdNode * +Cudd_addIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Implements ITEconstant for ADDs. f must be a 0-1 ADD. Returns a pointer to + the resulting ADD (which may or may not be constant) or DD_NON_CONSTANT. No + new nodes are created. This function can be used, for instance, to check + that g has a constant value (specified by h) whenever f is 1. If the + constant value is unknown, then one should use Cudd_addEvalConst. + + Side Effects: None + +DdNode * +Cudd_addIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Implements ITE(f,g,h). This procedure assumes that f is a 0-1 ADD. Returns a + pointer to the resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addIthBit( + DdManager * dd, + DdNode * f, + int bit +) + Produces an ADD from another ADD by replacing all discriminants whose i-th + bit is equal to 1 with 1, and all other discriminants with 0. The i-th bit + refers to the integer representation of the leaf value. If the value is has + a fractional part, it is ignored. Repeated calls to this procedure allow one + to transform an integer-valued ADD into an array of ADDs, one for each bit + of the leaf values. Returns a pointer to the resulting ADD if successful; + NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addIthVar( + DdManager * dd, + int i +) + Retrieves the ADD variable with index i if it already exists, or creates a + new ADD variable. Returns a pointer to the variable if successful; NULL + otherwise. An ADD variable differs from a BDD variable because it points to + the arithmetic zero, instead of having a complement pointer to 1. + + Side Effects: None + +int +Cudd_addLeq( + DdManager * dd, + DdNode * f, + DdNode * g +) + Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are + created. This procedure works for arbitrary ADDs. For 0-1 ADDs + Cudd_addEvalConst is more efficient. + + Side Effects: None + +DdNode * +Cudd_addLog( + DdManager * dd, + DdNode * f +) + Natural logarithm of an ADDs. Returns NULL if not a terminal case; log(f) + otherwise. The discriminants of f must be positive double's. + + Side Effects: None + +DdNode * +Cudd_addMatrixMultiply( + DdManager * dd, + DdNode * A, + DdNode * B, + DdNode ** z, + int nz +) + Calculates the product of two matrices, A and B, represented as ADDs. This + procedure implements the quasiring multiplication algorithm. A is assumed to + depend on variables x (rows) and z (columns). B is assumed to depend on + variables z (rows) and y (columns). The product of A and B then depends on x + (rows) and y (columns). Only the z variables have to be explicitly + identified; they are the "summation" variables. Returns a pointer to the + result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addMaximum( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point max for Cudd_addApply. Returns NULL if not a + terminal case; max(f,g) otherwise. + + Side Effects: None + +DdNode * +Cudd_addMinimum( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point min for Cudd_addApply. Returns NULL if not a + terminal case; min(f,g) otherwise. + + Side Effects: None + +DdNode * +Cudd_addMinus( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point subtraction. Returns NULL if not a terminal case; + f - g otherwise. + + Side Effects: None + +DdNode * +Cudd_addMonadicApply( + DdManager * dd, + DD_MAOP op, + DdNode * f +) + Applies op to the discriminants of f. Returns a pointer to the result if + succssful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addNand( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + NAND of two 0-1 ADDs. Returns NULL if not a terminal case; f NAND g + otherwise. + + Side Effects: None + +DdNode * +Cudd_addNegate( + DdManager * dd, + DdNode * f +) + Computes the additive inverse of an ADD. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addNewVarAtLevel( + DdManager * dd, + int level +) + Creates a new ADD variable. The new variable has an index equal to the + largest previous index plus 1 and is positioned at the specified level in + the order. Returns a pointer to the new variable if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_addNewVar( + DdManager * dd +) + Creates a new ADD variable. The new variable has an index equal to the + largest previous index plus 1. Returns a pointer to the new variable if + successful; NULL otherwise. An ADD variable differs from a BDD variable + because it points to the arithmetic zero, instead of having a complement + pointer to 1. + + Side Effects: None + +DdNode * +Cudd_addNonSimCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector +) + Given a vector of 0-1 ADDs, creates a new ADD by substituting the 0-1 ADDs + for the variables of the ADD f. There should be an entry in vector for each + variable in the manager. This function implements non-simultaneous + composition. If any of the functions being composed depends on any of the + variables being substituted, then the result depends on the order of + composition, which in turn depends on the variable order: The variables + farther from the roots in the order are substituted first. Returns a pointer + to the resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addNor( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + NOR of two 0-1 ADDs. Returns NULL if not a terminal case; f NOR g otherwise. + + Side Effects: None + +DdNode * +Cudd_addOneZeroMaximum( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Returns 1 if f > g and 0 otherwise. Used in conjunction with + Cudd_addApply. Returns NULL if not a terminal case. + + Side Effects: None + +DdNode * +Cudd_addOrAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube +) + Abstracts all the variables in cube from the 0-1 ADD f by taking the + disjunction over all possible values taken by the variables. Returns the + abstracted ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addOr( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Disjunction of two 0-1 ADDs. Returns NULL if not a terminal case; f OR g + otherwise. + + Side Effects: None + +DdNode * +Cudd_addOuterSum( + DdManager * dd, + DdNode * M, + DdNode * r, + DdNode * c +) + Takes the pointwise minimum of a matrix and the outer sum of two vectors. + This procedure is used in the Floyd-Warshall all-pair shortest path + algorithm. Returns a pointer to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addPermute( + DdManager * manager, + DdNode * node, + int * permut +) + Given a permutation in array permut, creates a new ADD with permuted + variables. There should be an entry in array permut for each variable in the + manager. The i-th entry of permut holds the index of the variable that is to + substitute the i-th variable. Returns a pointer to the resulting ADD if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addPlus( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point addition. Returns NULL if not a terminal case; + f+g otherwise. + + Side Effects: None + +int +Cudd_addRead( + FILE * fp, input file pointer + DdManager * dd, DD manager + DdNode ** E, characteristic function of the graph + DdNode *** x, array of row variables + DdNode *** y, array of column variables + DdNode *** xn, array of complemented row variables + DdNode *** yn_, array of complemented column variables + int * nx, number or row variables + int * ny, number or column variables + int * m, number of rows + int * n, number of columns + int bx, first index of row variables + int sx, step of row variables + int by, first index of column variables + int sy step of column variables +) + Reads in a sparse matrix specified in a simple format. The first line of the + input contains the numbers of rows and columns. The remaining lines contain + the elements of the matrix, one per line. Given a background value + (specified by the background field of the manager), only the values + different from it are explicitly listed. Each foreground element is + described by two integers, i.e., the row and column number, and a real + number, i.e., the value. Cudd_addRead produces an ADD that depends on two + sets of variables: x and y. The x variables (x[0] ... x[nx-1]) encode the + row index and the y variables (y[0] ... y[ny-1]) encode the column index. + x[0] and y[0] are the most significant bits in the indices. The variables + may already exist or may be created by the function. The index of x[i] is + bx+i*sx, and the index of y[i] is by+i*sy. On input, nx and ny hold the + numbers of row and column variables already in existence. On output, they + hold the numbers of row and column variables actually used by the matrix. + When Cudd_addRead creates the variable arrays, the index of x[i] is bx+i*sx, + and the index of y[i] is by+i*sy. When some variables already exist + Cudd_addRead expects the indices of the existing x variables to be bx+i*sx, + and the indices of the existing y variables to be by+i*sy. m and n are + set to the numbers of rows and columns of the matrix. Their values on input + are immaterial. The ADD for the sparse matrix is returned in E, and its + reference count is > 0. Cudd_addRead returns 1 in case of success; 0 + otherwise. + + Side Effects: nx and ny are set to the numbers of row and column variables. + m and n are set to the numbers of rows and columns. x and y are possibly + extended to represent the array of row and column variables. Similarly for + xn and yn_, which hold on return from Cudd_addRead the complements of the + row and column variables. + +DdNode * +Cudd_addResidue( + DdManager * dd, manager + int n, number of bits + int m, modulus + int options, options + int top index of top variable +) + Builds an ADD for the residue modulo m of an n-bit number. The modulus must + be at least 2, and the number of bits at least 1. Parameter options + specifies whether the MSB should be on top or the LSB; and whther the number + whose residue is computed is in two's complement notation or not. The macro + CUDD_RESIDUE_DEFAULT specifies LSB on top and unsigned number. The macro + CUDD_RESIDUE_MSB specifies MSB on top, and the macro CUDD_RESIDUE_TC + specifies two's complement residue. To request MSB on top and two's + complement residue simultaneously, one can OR the two macros: + CUDD_RESIDUE_MSB | CUDD_RESIDUE_TC. Cudd_addResidue returns a pointer to the + resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addRestrict( + DdManager * dd, + DdNode * f, + DdNode * c +) + ADD restrict according to Coudert and Madre's algorithm (ICCAD90). Returns + the restricted ADD if successful; otherwise NULL. If application of restrict + results in an ADD larger than the input ADD, the input ADD is returned. + + Side Effects: None + +DdNode * +Cudd_addRoundOff( + DdManager * dd, + DdNode * f, + int N +) + Rounds off the discriminants of an ADD. The discriminants are rounded off to + N digits after the decimal. Returns a pointer to the result ADD if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addScalarInverse( + DdManager * dd, + DdNode * f, + DdNode * epsilon +) + Computes an n ADD where the discriminants are the multiplicative inverses of + the corresponding discriminants of the argument ADD. Returns a pointer to + the resulting ADD in case of success. Returns NULL if any discriminants + smaller than epsilon is encountered. + + Side Effects: None + +DdNode * +Cudd_addSetNZ( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + This operator sets f to the value of g wherever g != 0. Returns NULL if not + a terminal case; f op g otherwise. + + Side Effects: None + +DdNode * +Cudd_addSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n +) + Swaps two sets of variables of the same size (x and y) in the ADD f. The + size is given by n. The two sets of variables are assumed to be disjoint. + Returns a pointer to the resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addThreshold( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Threshold operator for Apply (f if f >=g; 0 if fx_id, or if + phase == 0 and f-->x_id'. + + Side Effects: None + +int +Cudd_bddIsVarHardGroup( + DdManager * dd, + int index +) + Checks whether a variable is set to be in a hard group. This function is + used for lazy sifting. Returns 1 if the variable is marked to be in a hard + group; 0 if the variable exists, but it is not marked to be in a hard group; + -1 if the variable does not exist. + + Side Effects: none + +int +Cudd_bddIsVarToBeGrouped( + DdManager * dd, + int index +) + Checks whether a variable is set to be grouped. This function is used for + lazy sifting. + + Side Effects: none + +int +Cudd_bddIsVarToBeUngrouped( + DdManager * dd, + int index +) + Checks whether a variable is set to be ungrouped. This function is used for + lazy sifting. Returns 1 if the variable is marked to be ungrouped; 0 if the + variable exists, but it is not marked to be ungrouped; -1 if the variable + does not exist. + + Side Effects: none + +DdNode * +Cudd_bddIsop( + DdManager * dd, + DdNode * L, + DdNode * U +) + Computes a BDD in the interval between L and U with a simple sum-of-product + cover. This procedure is similar to Cudd_zddIsop, but it does not return the + ZDD for the cover. Returns a pointer to the BDD if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_bddIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Implements ITEconstant(f,g,h). Returns a pointer to the resulting BDD (which + may or may not be constant) or DD_NON_CONSTANT. No new nodes are created. + + Side Effects: None + +DdNode * +Cudd_bddIteLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h, + unsigned int limit +) + Implements ITE(f,g,h). Returns a pointer to the resulting BDD if successful; + NULL if the intermediate result blows up or more new nodes than + limit are required. + + Side Effects: None + +int +Cudd_bddIterConjDecomp( + DdManager * dd, manager + DdNode * f, function to be decomposed + DdNode *** conjuncts address of the array of conjuncts +) + Performs two-way conjunctive decomposition of a BDD. This procedure owes its + name to the iterated use of supersetting to obtain a factor of the given + function. Returns the number of conjuncts produced, that is, 2 if + successful; 1 if no meaningful decomposition was found; 0 otherwise. The + conjuncts produced by this procedure tend to be imbalanced. + + Side Effects: The factors are returned in an array as side effects. The + array is allocated by this function. It is the caller's responsibility to + free it. On successful completion, the conjuncts are already referenced. If + the function returns 0, the array for the conjuncts is not allocated. If the + function returns 1, the only factor equals the function to be decomposed. + +int +Cudd_bddIterDisjDecomp( + DdManager * dd, manager + DdNode * f, function to be decomposed + DdNode *** disjuncts address of the array of the disjuncts +) + Performs two-way disjunctive decomposition of a BDD. Returns the number of + disjuncts produced, that is, 2 if successful; 1 if no meaningful + decomposition was found; 0 otherwise. The disjuncts produced by this + procedure tend to be imbalanced. + + Side Effects: The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already referenced. + If the function returns 0, the array for the disjuncts is not allocated. If + the function returns 1, the only factor equals the function to be + decomposed. + +DdNode * +Cudd_bddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Implements ITE(f,g,h). Returns a pointer to the resulting BDD if successful; + NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddIthVar( + DdManager * dd, + int i +) + Retrieves the BDD variable with index i if it already exists, or creates a + new BDD variable. Returns a pointer to the variable if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_bddLICompaction( + DdManager * dd, manager + DdNode * f, function to be minimized + DdNode * c constraint (care set) +) + Performs safe minimization of a BDD. Given the BDD f of a + function to be minimized and a BDD c representing the care set, + Cudd_bddLICompaction produces the BDD of a function that agrees with + f wherever c is 1. Safe minimization means that + the size of the result is guaranteed not to exceed the size of + f. This function is based on the DAC97 paper by Hong et al.. + Returns a pointer to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddLargestPrimeUnate( + DdManager * dd, manager + DdNode * f, unate function + DdNode * phaseBdd cube of the phases +) + Find a largest prime implicant of a unate function. Returns the BDD for the + prime if succesful; NULL otherwise. The behavior is undefined if f is not + unate. The third argument is used to determine whether f is unate positive + (increasing) or negative (decreasing) in each of the variables in its + support. + + Side Effects: None + +int +Cudd_bddLeqUnless( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * D +) + Tells whether f is less than of equal to G unless D is 1. f, g, and D are + BDDs. The function returns 1 if f is less than of equal to G, and 0 + otherwise. No new nodes are created. + + Side Effects: None + +int +Cudd_bddLeq( + DdManager * dd, + DdNode * f, + DdNode * g +) + Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are + created. + + Side Effects: None + +DdNode * +Cudd_bddLiteralSetIntersection( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the intesection of two sets of literals represented as BDDs. Each + set is represented as a cube of the literals in the set. The empty set is + represented by the constant 1. No variable can be simultaneously present in + both phases in a set. Returns a pointer to the BDD representing the + intersected sets, if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddMakePrime( + DdManager * dd, manager + DdNode * cube, cube to be expanded + DdNode * f function of which the cube is to be made + a prime +) + Expands cube to a prime implicant of f. Returns the prime if successful; + NULL otherwise. In particular, NULL is returned if cube is not a real cube + or is not an implicant of f. + + Side Effects: None + +DdNode * +Cudd_bddMaximallyExpand( + DdManager * dd, manager + DdNode * lb, cube to be expanded + DdNode * ub, upper bound cube + DdNode * f function against which to expand +) + Expands lb to all prime implicants of (f and ub) that contain lb. Assumes + that lb is contained in ub. Returns the disjunction of the primes if lb is + contained in f; returns the zero BDD if lb is not contained in f; returns + NULL in case of failure. In particular, NULL is returned if cube is not a + real cube or is not an implicant of f. Returning the disjunction of all + prime implicants works because the resulting function is unate. + + Side Effects: None + +DdNode * +Cudd_bddMinimize( + DdManager * dd, + DdNode * f, + DdNode * c +) + Finds a small BDD that agrees with f over c. + Returns a pointer to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddNPAnd( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes f non-polluting-and g. The non-polluting AND of f and g is a hybrid + of AND and Restrict. From Restrict, this operation takes the idea of + existentially quantifying the top variable of the second operand if it does + not appear in the first. Therefore, the variables that appear in the result + also appear in f. For the rest, the function behaves like AND. Since the two + operands play different roles, non-polluting AND is not commutative. Returns + a pointer to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddNand( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the NAND of two BDDs f and g. Returns a pointer to the resulting + BDD if successful; NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddNewVarAtLevel( + DdManager * dd, + int level +) + Creates a new BDD variable. The new variable has an index equal to the + largest previous index plus 1 and is positioned at the specified level in + the order. Returns a pointer to the new variable if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_bddNewVar( + DdManager * dd +) + Creates a new BDD variable. The new variable has an index equal to the + largest previous index plus 1. Returns a pointer to the new variable if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddNor( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the NOR of two BDDs f and g. Returns a pointer to the resulting BDD + if successful; NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddOrLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit +) + Computes the disjunction of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up or + more new nodes than limit are required. + + Side Effects: None + +DdNode * +Cudd_bddOr( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the disjunction of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddPermute( + DdManager * manager, + DdNode * node, + int * permut +) + Given a permutation in array permut, creates a new BDD with permuted + variables. There should be an entry in array permut for each variable in the + manager. The i-th entry of permut holds the index of the variable that is to + substitute the i-th variable. Returns a pointer to the resulting BDD if + successful; NULL otherwise. + + Side Effects: None + +DdNode ** +Cudd_bddPickArbitraryMinterms( + DdManager * dd, manager + DdNode * f, function from which to pick k minterms + DdNode ** vars, array of variables + int n, size of vars + int k number of minterms to find +) + Picks k on-set minterms evenly distributed from given DD. The minterms are + in terms of vars. The array vars should contain at + least all variables in the support of f; if this condition is + not met the minterms built by this procedure may not be contained in + f. Builds an array of BDDs for the minterms and returns a + pointer to it if successful; NULL otherwise. There are three reasons why the + procedure may fail: It may run out of memory; the function + f may be the constant 0; the minterms may not be contained + in f. + + Side Effects: None + +int +Cudd_bddPickOneCube( + DdManager * ddm, + DdNode * node, + char * string +) + Picks one on-set cube randomly from the given DD. The cube is written into + an array of characters. The array must have at least as many entries as + there are variables. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +DdNode * +Cudd_bddPickOneMinterm( + DdManager * dd, manager + DdNode * f, function from which to pick one minterm + DdNode ** vars, array of variables + int n size of vars +) + Picks one on-set minterm randomly from the given DD. The minterm is in terms + of vars. The array vars should contain at least + all variables in the support of f; if this condition is not met + the minterm built by this procedure may not be contained in f. + Builds a BDD for the minterm and returns a pointer to it if successful; NULL + otherwise. There are three reasons why the procedure may fail: It + may run out of memory; the function f may be the constant + 0; the minterm may not be contained in f. + + Side Effects: None + +int +Cudd_bddPrintCover( + DdManager * dd, + DdNode * l, + DdNode * u +) + Prints a sum of product cover for an incompletely specified function given + by a lower bound and an upper bound. Each product is a prime implicant + obtained by expanding the product corresponding to a path from node to the + constant one. Uses the package default output file. Returns 1 if successful; + 0 otherwise. + + Side Effects: None + +int +Cudd_bddReadPairIndex( + DdManager * dd, + int index +) + Reads a corresponding pair index for a given index. These pair indices are + present and next state variable. Returns the corresponding variable index if + the variable exists; -1 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddRead( + FILE * fp, input file pointer + DdManager * dd, DD manager + DdNode ** E, characteristic function of the graph + DdNode *** x, array of row variables + DdNode *** y, array of column variables + int * nx, number or row variables + int * ny, number or column variables + int * m, number of rows + int * n, number of columns + int bx, first index of row variables + int sx, step of row variables + int by, first index of column variables + int sy step of column variables +) + Reads in a graph (without labels) given as an adjacency matrix. The first + line of the input contains the numbers of rows and columns of the adjacency + matrix. The remaining lines contain the arcs of the graph, one per line. + Each arc is described by two integers, i.e., the row and column number, or + the indices of the two endpoints. Cudd_bddRead produces a BDD that depends + on two sets of variables: x and y. The x variables (x[0] ... x[nx-1]) encode + the row index and the y variables (y[0] ... y[ny-1]) encode the column + index. x[0] and y[0] are the most significant bits in the indices. The + variables may already exist or may be created by the function. The index of + x[i] is bx+i*sx, and the index of y[i] is by+i*sy. On input, nx and ny + hold the numbers of row and column variables already in existence. On + output, they hold the numbers of row and column variables actually used by + the matrix. When Cudd_bddRead creates the variable arrays, the index of x[i] + is bx+i*sx, and the index of y[i] is by+i*sy. When some variables already + exist, Cudd_bddRead expects the indices of the existing x variables to be + bx+i*sx, and the indices of the existing y variables to be by+i*sy. m and + n are set to the numbers of rows and columns of the matrix. Their values on + input are immaterial. The BDD for the graph is returned in E, and its + reference count is > 0. Cudd_bddRead returns 1 in case of success; 0 + otherwise. + + Side Effects: nx and ny are set to the numbers of row and column variables. + m and n are set to the numbers of rows and columns. x and y are possibly + extended to represent the array of row and column variables. + +void +Cudd_bddRealignDisable( + DdManager * unique +) + Disables realignment of ZDD order to BDD order. + + Side Effects: None + +void +Cudd_bddRealignEnable( + DdManager * unique +) + Enables realignment of the BDD variable order to the ZDD variable order + after the ZDDs have been reordered. The number of ZDD variables must be a + multiple of the number of BDD variables for realignment to make sense. If + this condition is not met, Cudd_zddReduceHeap will return 0. Let + M be the ratio of the two numbers. For the purpose of + realignment, the ZDD variables from M*i to (M+1)*i- + 1 are reagarded as corresponding to BDD variable i. + Realignment is initially disabled. + + Side Effects: None + +int +Cudd_bddRealignmentEnabled( + DdManager * unique +) + Returns 1 if the realignment of BDD order to ZDD order is enabled; 0 + otherwise. + + Side Effects: None + +int +Cudd_bddResetVarToBeGrouped( + DdManager * dd, + int index +) + Resets a variable not to be grouped. This function is used for lazy sifting. + Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +DdNode * +Cudd_bddRestrict( + DdManager * dd, + DdNode * f, + DdNode * c +) + BDD restrict according to Coudert and Madre's algorithm (ICCAD90). Returns + the restricted BDD if successful; otherwise NULL. If application of restrict + results in a BDD larger than the input BDD, the input BDD is returned. + + Side Effects: None + +int +Cudd_bddSetNsVar( + DdManager * dd, manager + int index variable index +) + Sets a variable type to next state. The variable type is used by lazy + sifting. Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetPairIndex( + DdManager * dd, manager + int index, variable index + int pairIndex corresponding variable index +) + Sets a corresponding pair index for a given index. These pair indices are + present and next state variable. Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetPiVar( + DdManager * dd, manager + int index variable index +) + Sets a variable type to primary input. The variable type is used by lazy + sifting. Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetPsVar( + DdManager * dd, manager + int index variable index +) + Sets a variable type to present state. The variable type is used by lazy + sifting. Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetVarHardGroup( + DdManager * dd, + int index +) + Sets a variable to be a hard group. This function is used for lazy sifting. + Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetVarToBeGrouped( + DdManager * dd, + int index +) + Sets a variable to be grouped. This function is used for lazy sifting. + Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetVarToBeUngrouped( + DdManager * dd, + int index +) + Sets a variable to be ungrouped. This function is used for lazy sifting. + Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +DdNode * +Cudd_bddSqueeze( + DdManager * dd, manager + DdNode * l, lower bound + DdNode * u upper bound +) + Finds a small BDD in a function interval. Given BDDs l and + u, representing the lower bound and upper bound of a function + interval, Cudd_bddSqueeze produces the BDD of a function within the interval + with a small BDD. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_bddSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n +) + Swaps two sets of variables of the same size (x and y) in the BDD f. The + size is given by n. The two sets of variables are assumed to be disjoint. + Returns a pointer to the resulting BDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddTransfer( + DdManager * ddSource, + DdManager * ddDestination, + DdNode * f +) + Convert a BDD from a manager to another one. The orders of the variables in + the two managers may be different. Returns a pointer to the BDD in the + destination manager if successful; NULL otherwise. + + Side Effects: None + +int +Cudd_bddUnbindVar( + DdManager * dd, manager + int index variable index +) + This function resets the flag that prevents the sifting of a variable. In + successive variable reorderings, the variable will NOT be skipped, that is, + sifted. Initially all variables can be sifted. It is necessary to call this + function only to re-enable sifting after a call to Cudd_bddBindVar. Returns + 1 if successful; 0 otherwise (i.e., invalid variable index). + + Side Effects: Changes the "bindVar" flag in DdSubtable. + +DdNode * +Cudd_bddUnivAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube +) + Universally abstracts all the variables in cube from f. Returns the + abstracted BDD if successful; NULL otherwise. + + Side Effects: None + +int +Cudd_bddVarConjDecomp( + DdManager * dd, manager + DdNode * f, function to be decomposed + DdNode *** conjuncts address of the array of conjuncts +) + Conjunctively decomposes one BDD according to a variable. If f + is the function of the BDD and x is the variable, the + decomposition is (f+x)(f+x'). The variable is chosen so as to + balance the sizes of the two conjuncts and to keep them small. Returns the + number of conjuncts produced, that is, 2 if successful; 1 if no meaningful + decomposition was found; 0 otherwise. + + Side Effects: The two factors are returned in an array as side effects. The + array is allocated by this function. It is the caller's responsibility to + free it. On successful completion, the conjuncts are already referenced. If + the function returns 0, the array for the conjuncts is not allocated. If the + function returns 1, the only factor equals the function to be decomposed. + +int +Cudd_bddVarDisjDecomp( + DdManager * dd, manager + DdNode * f, function to be decomposed + DdNode *** disjuncts address of the array of the disjuncts +) + Performs two-way disjunctive decomposition of a BDD according to a variable. + If f is the function of the BDD and x is the + variable, the decomposition is f*x + f*x'. The variable is + chosen so as to balance the sizes of the two disjuncts and to keep them + small. Returns the number of disjuncts produced, that is, 2 if successful; 1 + if no meaningful decomposition was found; 0 otherwise. + + Side Effects: The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already referenced. + If the function returns 0, the array for the disjuncts is not allocated. If + the function returns 1, the only factor equals the function to be + decomposed. + +int +Cudd_bddVarIsBound( + DdManager * dd, manager + int index variable index +) + This function returns 1 if a variable is enabled for sifting. Initially all + variables can be sifted. This function returns 0 only if there has been a + previous call to Cudd_bddBindVar for that variable not followed by a call to + Cudd_bddUnbindVar. The function returns 0 also in the case in which the + index of the variable is out of bounds. + + Side Effects: none + +int +Cudd_bddVarIsDependent( + DdManager * dd, + DdNode * f, + DdNode * var variable +) + Checks whether a variable is dependent on others in a function. Returns 1 if + the variable is dependent; 0 otherwise. No new nodes are created. + + Side Effects: None + +DdNode * +Cudd_bddVarMap( + DdManager * manager, DD manager + DdNode * f function in which to remap variables +) + Remaps the variables of a BDD using the default variable map. A typical use + of this function is to swap two sets of variables. The variable map must be + registered with Cudd_SetVarMap. Returns a pointer to the resulting BDD if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector +) + Given a vector of BDDs, creates a new BDD by substituting the BDDs for the + variables of the BDD f. There should be an entry in vector for each variable + in the manager. If no substitution is sought for a given variable, the + corresponding projection function should be specified in the vector. This + function implements simultaneous composition. Returns a pointer to the + resulting BDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddXnorLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit +) + Computes the exclusive NOR of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up or + more new nodes than limit are required. + + Side Effects: None + +DdNode * +Cudd_bddXnor( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the exclusive NOR of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddXorExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube +) + Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddXor( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the exclusive OR of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up. + + Side Effects: None + +void +Cudd_tlcInfoFree( + DdTlcInfo * t +) + Frees a DdTlcInfo Structure as well as the memory pointed by it. + + Side Effects: None + +DdNode * +Cudd_zddChange( + DdManager * dd, + DdNode * P, + int var +) + Substitutes a variable with its complement in a ZDD. returns a pointer to + the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddComplement( + DdManager * dd, + DdNode * node +) + Computes a complement cover for a ZDD node. For lack of a better method, we + first extract the function BDD from the ZDD cover, then make the complement + of the ZDD cover from the complement of the BDD node by using ISOP. Returns + a pointer to the resulting cover if successful; NULL otherwise. The result + depends on current variable order. + + Side Effects: The result depends on current variable order. + +double +Cudd_zddCountDouble( + DdManager * zdd, + DdNode * P +) + Counts the number of minterms of a ZDD. The result is returned as a double. + If the procedure runs out of memory, it returns (double) CUDD_OUT_OF_MEM. + This procedure is used in Cudd_zddCountMinterm. + + Side Effects: None + +double +Cudd_zddCountMinterm( + DdManager * zdd, + DdNode * node, + int path +) + Counts the number of minterms of the ZDD rooted at node. This + procedure takes a parameter path that specifies how many + variables are in the support of the function. If the procedure runs out of + memory, it returns (double) CUDD_OUT_OF_MEM. + + Side Effects: None + +int +Cudd_zddCount( + DdManager * zdd, + DdNode * P +) + Returns an integer representing the number of minterms in a ZDD. + + Side Effects: None + +char * +Cudd_zddCoverPathToString( + DdManager * zdd, DD manager + int * path, path of ZDD representing a cover + char * str pointer to string to use if != NULL +) + Converts a path of a ZDD representing a cover to a string. The string + represents an implicant of the cover. The path is typically produced by + Cudd_zddForeachPath. Returns a pointer to the string if successful; NULL + otherwise. If the str input is NULL, it allocates a new string. The string + passed to this function must have enough room for all variables and for the + terminator. + + Side Effects: None + +int +Cudd_zddDagSize( + DdNode * p_node +) + Counts the number of nodes in a ZDD. This function duplicates Cudd_DagSize + and is only retained for compatibility. + + Side Effects: None + +DdNode * +Cudd_zddDiffConst( + DdManager * zdd, + DdNode * P, + DdNode * Q +) + Inclusion test for ZDDs (P implies Q). No new nodes are generated by this + procedure. Returns empty if true; a valid pointer different from empty or + DD_NON_CONSTANT otherwise. + + Side Effects: None + +DdNode * +Cudd_zddDiff( + DdManager * dd, + DdNode * P, + DdNode * Q +) + Computes the difference of two ZDDs. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddDivideF( + DdManager * dd, + DdNode * f, + DdNode * g +) + Modified version of Cudd_zddDivide. This function may disappear in future + releases. + + Side Effects: None + +DdNode * +Cudd_zddDivide( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the quotient of two unate covers represented by ZDDs. Unate covers + use one ZDD variable for each BDD variable. Returns a pointer to the + resulting ZDD if successful; NULL otherwise. + + Side Effects: None + +int +Cudd_zddDumpDot( + DdManager * dd, manager + int n, number of output nodes to be dumped + DdNode ** f, array of output nodes to be dumped + char ** inames, array of input names (or NULL) + char ** onames, array of output names (or NULL) + FILE * fp pointer to the dump file +) + Writes a file representing the argument ZDDs in a format suitable for the + graph drawing program dot. It returns 1 in case of success; 0 otherwise + (e.g., out-of-memory, file system full). Cudd_zddDumpDot does not close the + file: This is the caller responsibility. Cudd_zddDumpDot uses a minimal + unique subset of the hexadecimal address of a node as name for it. If the + argument inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for onames. Cudd_zddDumpDot uses the following + convention to draw arcs: solid line: THEN arcs; dashed line: + ELSE arcs. The dot options are chosen so that the drawing fits on a + letter-size sheet. + + Side Effects: None + +DdGen * +Cudd_zddFirstPath( + DdManager * zdd, + DdNode * f, + int ** path +) + Defines an iterator on the paths of a ZDD and finds its first path. Returns + a generator that contains the information necessary to continue the + enumeration if successful; NULL otherwise. A path is represented as an + array of literals, which are integers in {0, 1, 2}; 0 represents an else arc + out of a node, 1 represents a then arc out of a node, and 2 stands for the + absence of a node. The size of the array equals the number of variables in + the manager at the time Cudd_zddFirstCube is called. The paths that end + in the empty terminal are not enumerated. + + Side Effects: The first path is returned as a side effect. + +DdNode * +Cudd_zddIntersect( + DdManager * dd, + DdNode * P, + DdNode * Q +) + Computes the intersection of two ZDDs. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddIsop( + DdManager * dd, + DdNode * L, + DdNode * U, + DdNode ** zdd_I +) + Computes an irredundant sum of products (ISOP) in ZDD form from BDDs. The + two BDDs L and U represent the lower bound and the upper bound, + respectively, of the function. The ISOP uses two ZDD variables for each BDD + variable: One for the positive literal, and one for the negative literal. + These two variables should be adjacent in the ZDD order. The two ZDD + variables corresponding to BDD variable i should have indices + 2i and 2i+1. The result of this procedure depends + on the variable order. If successful, Cudd_zddIsop returns the BDD for the + function chosen from the interval. The ZDD representing the irredundant + cover is returned as a side effect in zdd_I. In case of failure, NULL is + returned. + + Side Effects: zdd_I holds the pointer to the ZDD for the ISOP on successful + return. + +DdNode * +Cudd_zddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Computes the ITE of three ZDDs. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddIthVar( + DdManager * dd, + int i +) + Retrieves the ZDD variable with index i if it already exists, or creates a + new ZDD variable. Returns a pointer to the variable if successful; NULL + otherwise. + + Side Effects: None + +int +Cudd_zddNextPath( + DdGen * gen, + int ** path +) + Generates the next path of a ZDD onset, using generator gen. Returns 0 if + the enumeration is completed; 1 otherwise. + + Side Effects: The path is returned as a side effect. The generator is + modified. + +DdNode * +Cudd_zddPortFromBdd( + DdManager * dd, + DdNode * B +) + Converts a BDD into a ZDD. This function assumes that there is a one-to-one + correspondence between the BDD variables and the ZDD variables, and that the + variable order is the same for both types of variables. These conditions are + established if the ZDD variables are created by one call to + Cudd_zddVarsFromBddVars with multiplicity = 1. Returns a pointer to the + resulting ZDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddPortToBdd( + DdManager * dd, + DdNode * f +) + Converts a ZDD into a BDD. Returns a pointer to the resulting ZDD if + successful; NULL otherwise. + + Side Effects: None + +int +Cudd_zddPrintCover( + DdManager * zdd, + DdNode * node +) + Prints a sum of products from a ZDD representing a cover. Returns 1 if + successful; 0 otherwise. + + Side Effects: None + +int +Cudd_zddPrintDebug( + DdManager * zdd, + DdNode * f, + int n, + int pr +) + Prints to the standard output a DD and its statistics. The statistics + include the number of nodes and the number of minterms. (The number of + minterms is also the number of combinations in the set.) The statistics are + printed if pr > 0. Specifically: pr = 0 : prints nothing + pr = 1 : prints counts of nodes and minterms pr = 2 : prints counts + + disjoint sum of products pr = 3 : prints counts + list of nodes pr + > 3 : prints counts + disjoint sum of products + list of nodes + Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_zddPrintMinterm( + DdManager * zdd, + DdNode * node +) + Prints a disjoint sum of product form for a ZDD. Returns 1 if successful; 0 + otherwise. + + Side Effects: None + +void +Cudd_zddPrintSubtable( + DdManager * table +) + Prints the ZDD table for debugging purposes. + + Side Effects: None + +DdNode * +Cudd_zddProduct( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the product of two covers represented by ZDDs. The result is also a + ZDD. Returns a pointer to the result if successful; NULL otherwise. The + covers on which Cudd_zddProduct operates use two ZDD variables for each + function variable (one ZDD variable for each literal of the variable). Those + two ZDD variables should be adjacent in the order. + + Side Effects: None + +long +Cudd_zddReadNodeCount( + DdManager * dd +) + Reports the number of nodes in ZDDs. This number always includes the two + constants 1 and 0. + + Side Effects: None + +void +Cudd_zddRealignDisable( + DdManager * unique +) + Disables realignment of ZDD order to BDD order. + + Side Effects: None + +void +Cudd_zddRealignEnable( + DdManager * unique +) + Enables realignment of the ZDD variable order to the BDD variable order + after the BDDs and ADDs have been reordered. The number of ZDD variables + must be a multiple of the number of BDD variables for realignment to make + sense. If this condition is not met, Cudd_ReduceHeap will return 0. Let + M be the ratio of the two numbers. For the purpose of + realignment, the ZDD variables from M*i to (M+1)*i- + 1 are reagarded as corresponding to BDD variable i. + Realignment is initially disabled. + + Side Effects: None + +int +Cudd_zddRealignmentEnabled( + DdManager * unique +) + Returns 1 if the realignment of ZDD order to BDD order is enabled; 0 + otherwise. + + Side Effects: None + +int +Cudd_zddReduceHeap( + DdManager * table, DD manager + Cudd_ReorderingTy heuristic, method used for reordering + int minsize bound below which no reordering occurs +) + Main dynamic reordering routine for ZDDs. Calls one of the possible + reordering procedures: Swapping Sifting Symmetric Sifting + For sifting and symmetric sifting it is possible to request reordering + to convergence. The core of all methods is the reordering procedure + cuddZddSwapInPlace() which swaps two adjacent variables. Returns 1 in case + of success; 0 otherwise. In the case of symmetric sifting (with and without + convergence) returns 1 plus the number of symmetric variables, in case of + success. + + Side Effects: Changes the variable order for all ZDDs and clears the cache. + +int +Cudd_zddShuffleHeap( + DdManager * table, DD manager + int * permutation required variable permutation +) + Reorders ZDD variables according to given permutation. The i-th entry of the + permutation array contains the index of the variable that should be brought + to the i-th level. The size of the array should be equal or greater to the + number of variables currently in use. Returns 1 in case of success; 0 + otherwise. + + Side Effects: Changes the ZDD variable order for all diagrams and clears the + cache. + +DdNode * +Cudd_zddSubset0( + DdManager * dd, + DdNode * P, + int var +) + Computes the negative cofactor of a ZDD w.r.t. a variable. In terms of + combinations, the result is the set of all combinations in which the + variable is negated. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_zddSubset1( + DdManager * dd, + DdNode * P, + int var +) + Computes the positive cofactor of a ZDD w.r.t. a variable. In terms of + combinations, the result is the set of all combinations in which the + variable is asserted. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_zddSupport( + DdManager * dd, manager + DdNode * f ZDD whose support is sought +) + Finds the variables on which a ZDD depends. Returns a BDD consisting of the + product of the variables if successful; NULL otherwise. + + Side Effects: None + +void +Cudd_zddSymmProfile( + DdManager * table, + int lower, + int upper +) + Prints statistics on symmetric ZDD variables. + + Side Effects: None + +DdNode * +Cudd_zddUnateProduct( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the product of two unate covers represented as ZDDs. Unate covers + use one ZDD variable for each BDD variable. Returns a pointer to the result + if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddUnion( + DdManager * dd, + DdNode * P, + DdNode * Q +) + Computes the union of two ZDDs. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +int +Cudd_zddVarsFromBddVars( + DdManager * dd, DD manager + int multiplicity how many ZDD variables are created for + each BDD variable +) + Creates one or more ZDD variables for each BDD variable. If some ZDD + variables already exist, only the missing variables are created. Parameter + multiplicity allows the caller to control how many variables are created for + each BDD variable in existence. For instance, if ZDDs are used to represent + covers, two ZDD variables are required for each BDD variable. The order of + the BDD variables is transferred to the ZDD variables. If a variable group + tree exists for the BDD variables, a corresponding ZDD variable group tree + is created by expanding the BDD variable tree. In any case, the ZDD + variables derived from the same BDD variable are merged in a ZDD variable + group. If a ZDD variable group tree exists, it is freed. Returns 1 if + successful; 0 otherwise. + + Side Effects: None + +DdNode * +Cudd_zddWeakDivF( + DdManager * dd, + DdNode * f, + DdNode * g +) + Modified version of Cudd_zddWeakDiv. This function may disappear in future + releases. + + Side Effects: None + +DdNode * +Cudd_zddWeakDiv( + DdManager * dd, + DdNode * f, + DdNode * g +) + Applies weak division to two ZDDs representing two covers. Returns a pointer + to the ZDD representing the result if successful; NULL otherwise. The result + of weak division depends on the variable order. The covers on which + Cudd_zddWeakDiv operates use two ZDD variables for each function variable + (one ZDD variable for each literal of the variable). Those two ZDD variables + should be adjacent in the order. + + Side Effects: None + +writing ./cuddTitle.html diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.ps b/resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.ps new file mode 100644 index 000000000..0a12057cc --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.ps @@ -0,0 +1,5036 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.92b Copyright 2002 Radical Eye Software +%%Title: cudd.dvi +%%Pages: 48 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%DocumentFonts: Times-Roman CMMI12 Times-Bold Times-Italic CMSY10 CMR10 +%%+ CMMI10 CMMI8 Courier CMSY8 CMR8 Times-BoldItalic +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -o cudd.ps cudd +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2012.02.04:1929 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% File 8r.enc as of 2002-03-12 for PSNFSS 9 +% +% This is the encoding vector for Type1 and TrueType fonts to be used +% with TeX. This file is part of the PSNFSS bundle, version 9 +% +% Authors: S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry, W. Schmidt +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida + Euro. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both ASCII and Windows. +% +% (6) /Euro is assigned to 128, as in Windows ANSI +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there down to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /Euro /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0 +ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{ +pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get +div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type +/nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end +definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup +sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll +mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[ +exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if} +forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def +end + +%%EndProcSet +%%BeginProcSet: special.pro +%! +TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N +/vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N +/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N +/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ +/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho +X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B +/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ +/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known +{userdict/md get type/dicttype eq{userdict begin md length 10 add md +maxlength ge{/md md dup length 20 add dict copy def}if end md begin +/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S +atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ +itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll +transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll +curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf +pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} +if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 +-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 +get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip +yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub +neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ +noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop +90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get +neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr +1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr +2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 +-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S +TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ +Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale +}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState +save N userdict maxlength dict begin/magscale true def normalscale +currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts +/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x +psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx +psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub +TR/showpage{}N/erasepage{}N/setpagedevice{pop}N/copypage{}N/p 3 def +@MacSetUp}N/doclip{psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll +newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto +closepath clip newpath moveto}N/endTexFig{end psf$SavedState restore}N +/@beginspecial{SDict begin/SpecialSave save N gsave normalscale +currentpoint TR @SpecialDefaults count/ocount X/dcount countdictstack N} +N/@setspecial{CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs +neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate +rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse +scale llx neg lly neg TR}{rhiSeen{rhi ury lly sub div dup scale llx neg +lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx +ury lineto llx ury lineto closepath clip}if/showpage{}N/erasepage{}N +/setpagedevice{pop}N/copypage{}N newpath}N/@endspecial{count ocount sub{ +pop}repeat countdictstack dcount sub{end}repeat grestore SpecialSave +restore end}N/@defspecial{SDict begin}N/@fedspecial{end}B/li{lineto}B +/rl{rlineto}B/rc{rcurveto}B/np{/SaveX currentpoint/SaveY X N 1 +setlinecap newpath}N/st{stroke SaveX SaveY moveto}N/fil{fill SaveX SaveY +moveto}N/ellipse{/endangle X/startangle X/yrad X/xrad X/savematrix +matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc +savematrix setmatrix}N end + +%%EndProcSet +%%BeginProcSet: color.pro +%! +TeXDict begin/setcmykcolor where{pop}{/setcmykcolor{dup 10 eq{pop +setrgbcolor}{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll +}repeat setrgbcolor pop}ifelse}B}ifelse/TeXcolorcmyk{setcmykcolor}def +/TeXcolorrgb{setrgbcolor}def/TeXcolorgrey{setgray}def/TeXcolorgray{ +setgray}def/TeXcolorhsb{sethsbcolor}def/currentcmykcolor where{pop}{ +/currentcmykcolor{currentrgbcolor 10}B}ifelse/DC{exch dup userdict exch +known{pop pop}{X}ifelse}B/GreenYellow{0.15 0 0.69 0 setcmykcolor}DC +/Yellow{0 0 1 0 setcmykcolor}DC/Goldenrod{0 0.10 0.84 0 setcmykcolor}DC +/Dandelion{0 0.29 0.84 0 setcmykcolor}DC/Apricot{0 0.32 0.52 0 +setcmykcolor}DC/Peach{0 0.50 0.70 0 setcmykcolor}DC/Melon{0 0.46 0.50 0 +setcmykcolor}DC/YellowOrange{0 0.42 1 0 setcmykcolor}DC/Orange{0 0.61 +0.87 0 setcmykcolor}DC/BurntOrange{0 0.51 1 0 setcmykcolor}DC +/Bittersweet{0 0.75 1 0.24 setcmykcolor}DC/RedOrange{0 0.77 0.87 0 +setcmykcolor}DC/Mahogany{0 0.85 0.87 0.35 setcmykcolor}DC/Maroon{0 0.87 +0.68 0.32 setcmykcolor}DC/BrickRed{0 0.89 0.94 0.28 setcmykcolor}DC/Red{ +0 1 1 0 setcmykcolor}DC/OrangeRed{0 1 0.50 0 setcmykcolor}DC/RubineRed{ +0 1 0.13 0 setcmykcolor}DC/WildStrawberry{0 0.96 0.39 0 setcmykcolor}DC +/Salmon{0 0.53 0.38 0 setcmykcolor}DC/CarnationPink{0 0.63 0 0 +setcmykcolor}DC/Magenta{0 1 0 0 setcmykcolor}DC/VioletRed{0 0.81 0 0 +setcmykcolor}DC/Rhodamine{0 0.82 0 0 setcmykcolor}DC/Mulberry{0.34 0.90 +0 0.02 setcmykcolor}DC/RedViolet{0.07 0.90 0 0.34 setcmykcolor}DC +/Fuchsia{0.47 0.91 0 0.08 setcmykcolor}DC/Lavender{0 0.48 0 0 +setcmykcolor}DC/Thistle{0.12 0.59 0 0 setcmykcolor}DC/Orchid{0.32 0.64 0 +0 setcmykcolor}DC/DarkOrchid{0.40 0.80 0.20 0 setcmykcolor}DC/Purple{ +0.45 0.86 0 0 setcmykcolor}DC/Plum{0.50 1 0 0 setcmykcolor}DC/Violet{ +0.79 0.88 0 0 setcmykcolor}DC/RoyalPurple{0.75 0.90 0 0 setcmykcolor}DC +/BlueViolet{0.86 0.91 0 0.04 setcmykcolor}DC/Periwinkle{0.57 0.55 0 0 +setcmykcolor}DC/CadetBlue{0.62 0.57 0.23 0 setcmykcolor}DC +/CornflowerBlue{0.65 0.13 0 0 setcmykcolor}DC/MidnightBlue{0.98 0.13 0 +0.43 setcmykcolor}DC/NavyBlue{0.94 0.54 0 0 setcmykcolor}DC/RoyalBlue{1 +0.50 0 0 setcmykcolor}DC/Blue{1 1 0 0 setcmykcolor}DC/Cerulean{0.94 0.11 +0 0 setcmykcolor}DC/Cyan{1 0 0 0 setcmykcolor}DC/ProcessBlue{0.96 0 0 0 +setcmykcolor}DC/SkyBlue{0.62 0 0.12 0 setcmykcolor}DC/Turquoise{0.85 0 +0.20 0 setcmykcolor}DC/TealBlue{0.86 0 0.34 0.02 setcmykcolor}DC +/Aquamarine{0.82 0 0.30 0 setcmykcolor}DC/BlueGreen{0.85 0 0.33 0 +setcmykcolor}DC/Emerald{1 0 0.50 0 setcmykcolor}DC/JungleGreen{0.99 0 +0.52 0 setcmykcolor}DC/SeaGreen{0.69 0 0.50 0 setcmykcolor}DC/Green{1 0 +1 0 setcmykcolor}DC/ForestGreen{0.91 0 0.88 0.12 setcmykcolor}DC +/PineGreen{0.92 0 0.59 0.25 setcmykcolor}DC/LimeGreen{0.50 0 1 0 +setcmykcolor}DC/YellowGreen{0.44 0 0.74 0 setcmykcolor}DC/SpringGreen{ +0.26 0 0.76 0 setcmykcolor}DC/OliveGreen{0.64 0 0.95 0.40 setcmykcolor} +DC/RawSienna{0 0.72 1 0.45 setcmykcolor}DC/Sepia{0 0.83 1 0.70 +setcmykcolor}DC/Brown{0 0.81 1 0.60 setcmykcolor}DC/Tan{0.14 0.42 0.56 0 +setcmykcolor}DC/Gray{0 0 0 0.50 setcmykcolor}DC/Black{0 0 0 1 +setcmykcolor}DC/White{0 0 0 0 setcmykcolor}DC end + +%%EndProcSet +%%BeginFont: CMR8 +%!PS-AdobeFont-1.1: CMR8 1.0 +%%CreationDate: 1991 Aug 20 16:39:40 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.0) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMR8) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle 0 def +/isFixedPitch false def +end readonly def +/FontName /CMR8 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 48 /zero put +dup 49 /one put +dup 50 /two put +dup 51 /three put +readonly def +/FontBBox{-36 -250 1070 750}readonly def +/UniqueID 5000791 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 +016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 +9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F +D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 +469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 +2BDBF16FBC7512FAA308A093FE5CF4E9D2405B169CD5365D6ECED5D768D66D6C +68618B8C482B341F8CA38E9BB9BAFCFAAD9C2F3FD033B62690986ED43D9C9361 +3645B82392D5CAE11A7CB49D7E2E82DCD485CBA1772CE422BB1D7283AD675B65 +48A7EA0069A883EC1DAA3E1F9ECE7586D6CF0A128CD557C7E5D7AA3EA97EBAD3 +9619D1BFCF4A6D64768741EDEA0A5B0EFBBF347CDCBE2E03D756967A16B613DB +0FC45FA2A3312E0C46A5FD0466AB097C58FFEEC40601B8395E52775D0AFCD7DB +8AB317333110531E5C44A4CB4B5ACD571A1A60960B15E450948A5EEA14DD330F +EA209265DB8E1A1FC80DCD3860323FD26C113B041A88C88A21655878680A4466 +FA10403D24BB97152A49B842C180E4D258C9D48F21D057782D90623116830BA3 +9902B3C5F2F2DD01433B0D7099C07DBDE268D0FFED5169BCD03D48B2F058AD62 +D8678C626DC7A3F352152C99BA963EF95F8AD11DB8B0D351210A17E4C2C55AD8 +9EB64172935D3C20A398F3EEEEC31551966A7438EF3FEE422C6D4E05337620D5 +ACC7B52BED984BFAAD36EF9D20748B05D07BE4414A63975125D272FAD83F76E6 +10FFF8363014BE526D580873C5A42B70FA911EC7B86905F13AFE55EB0273F582 +83158793B8CC296B8DE1DCCF1250FD57CB0E035C7EDA3B0092ED940D37A05493 +2EC54E09B984FCA4AB7D2EA182BCF1263AA244B07EC0EA901C077A059F709F30 +4384CB5FA748F2054FAD9A7A43D4EA427918BD414F766531136B60C3477C6632 +BEFE3897B58C19276A301926C2AEF2756B367319772C9B201C49B4D935A8267B +041D6F1783B6AEA4DAC4F5B3507D7032AA640AAB12E343A4E9BDCF419C04A721 +3888B25AF4E293AACED9A6BDC78E61DA1C424C6503CC1885F762BE0618B16C14 +7386EB4C4B9B3142B9662F48CF5B55DC44261F9F0F975611120F7B9846423136 +B3A568B97F5822B76CF10ECD4CD0C64DC55413CC2E843FB37053EAFE985A98CF +9E408707AB2BBD2F036B622F74397BE4BEFA06A0CC51A30C326C3654B5E548B5 +FD5BE6BFFD05A02E81F12A94892139862012A6776D80F0B7C3E90F8E34918601 +8A6B25676CDD71F0DBD7CF514F0363B15B6C7E62EF9BE227EB164481CC0EF812 +8B8B5FDD0FA1815E629760FDEAA026094F96B05BE963194E99D2E5444F62C26B +1BBAD76672EEC98948B7D9C81CAEBBB7C9CBA16CBDFC595D7AD3F92651B63D50 +CC7E92F4E96C4DE2721AFEE94FBFE5843979D30068BC1F11E5374F6F6EF4586C +AB699727770D97A8681D2E75E907027302832D0834FD7BB48EE89D7F0A39E263 +C34F09602BDEF782A7BCF182CB6D8603E31EF82E669B294BBE9B5AD29CD12FA9 +DD1CAAC8AB4DBB663F8C50472C9D7CF3CFB9AE712D83B306991B89F75A87A6C8 +CF7901236E9EE16204F26C79404A6EB87AC532A29C47C9455D0F3DCCA48E2B26 +1240EB3CD115047EC6C4E3F5B3680127DF7509CD26BEF7C542D0332B2A2F680F +ECAC3A2C958DC3F17576DEBDB9478343EE622DF8C8F7C488ED049690697A6B1D +BAFF45A781099100DD7B0A0598A4A93E088E8B44198EB0DE3761F141AEF45C92 +1A71F32189FEFCC7978570BEBD53305BFB9B68829998196345770721ABAE7410 +50A99976446ABBBF31130CE1A85B4F37B85BBCCD2E31C072B96F005E7506BA7B +6AF46E32CEAB608411DACC4D93ECE77BC4C4282DE8FC4189C8661A93F0A3C0CC +B09077804522B3675B87F45E9E0AB99AFC3F6A979FB2030642DB80CBB4A92BA9 +8FEADF534577FE567839008FEB0F6CD811ACB7CEDCEFC98807636A24B6EDAD43 +83CE013C9E660F3F3DB842554D04B5D8277640A931ED4CC700F8BCFF901775C6 +DBE1A76EE8ADC5601FF1DC4EC663E3E960064875BBCA81F5B82118A055D48C9D +C2DC4C00BB1B42B6C3D00354040080ACAD10EE6A464E5F62E5AC4236FF2D2A6A +BBFE55CD6E55990D15C6A13229F0AB706D61C746EF99E2AF9365 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMSY8 +%!PS-AdobeFont-1.1: CMSY8 1.0 +%%CreationDate: 1991 Aug 15 07:22:10 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.0) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMSY8) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.035 def +/isFixedPitch false def +end readonly def +/FontName /CMSY8 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 0 /minus put +dup 48 /prime put +readonly def +/FontBBox{-30 -955 1185 779}readonly def +/UniqueID 5000818 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964 +7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4 +A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85 +E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A +221A37D9A807DD01161779DDE7D5FC1B2109839E5B52DFBB2A7C1B5D8E7E8AA0 +5B10EA43D6A8ED61AF5B23D49920D8F79DAB6A59062134D84AC0100187A6CD1F +80F5DDD9D222ACB1C23326A7656A635C4A241CCD32CBFDF8363206B8AA36E107 +1477F5496111E055C7491002AFF272E46ECC46422F0380D093284870022523FB +DA1716CC4F2E2CCAD5F173FCBE6EDDB874AD255CD5E5C0F86214393FCB5F5C20 +9C3C2BB5886E36FC3CCC21483C3AC193485A46E9D22BD7201894E4D45ADD9BF1 +CC5CF6A5010B5654AC0BE0DA903DB563B13840BA3015F72E51E3BC80156388BA +F83C7D393392BCBC227771CDCB976E93302530FA3F4BEF341997D4302A48384A +CEFFC1559462EA5F60DC05245E8499D8E61397B2C094CEED1AF26EE15A837209 +ECE64FEF41ABE8DDA7BE1F351CF14E07BA8FD40CEFBFC3CE7B9D4912D6FE752D +9CF163084E688DDCC4B5AAEDEB6E94DDDE34330BA35394A8B485E767F0F94A71 +4532F3B89C51AC3FD1C082EF41EA489B9595B4120FDCA2F599C88F5058126CD1 +4C7F96B4FE22BAB1A5E16F215DECBCE4186C68B6263BD5331CDC1FF9F30332A7 +7B831255A41A642C5719272C6B5993171CA395A0D11B6376457EC30E1CDE47A4 +9B9EE95D112C64084901B6357E881C0DEB6836B80F21E57B660388BA4F7B89EB +9AF7DE8AEA702FC5B765552F78058A20E424277F667A4E9955A797593CE44E19 +A98F149CA17D6379040A1C836CA18234278DFDA205EFD55D527C7F38766D4C97 + +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMMI8 +%!PS-AdobeFont-1.1: CMMI8 1.100 +%%CreationDate: 1996 Jul 23 07:53:54 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.100) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMMI8) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.04 def +/isFixedPitch false def +end readonly def +/FontName /CMMI8 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 110 /n put +readonly def +/FontBBox{-24 -250 1110 750}readonly def +/UniqueID 5087383 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE +3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B +532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 +B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B +986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE +D919C2DDD26BDC0D99398B9F4D03D6A8F05B47AF95EF28A9C561DBDC98C47CF5 +5250011D19E9366EB6FD153D3A100CAA6212E3D5D93990737F8D326D347B7EDC +4391C9DF440285B8FC159D0E98D4258FC57892DDF753642CD526A96ACEDA4120 +788F22B1D09F149794E66DD1AC2C2B3BC6FEC59D626F427CD5AE9C54C7F78F62 +C36F49B3C2E5E62AFB56DCEE87445A12A942C14AE618D1FE1B11A9CF9FAA1F32 +617B598CE5058715EF3051E228F72F651040AD99A741F247C68007E68C84E9D1 +D0BF99AA5D777D88A7D3CED2EA67F4AE61E8BC0495E7DA382E82DDB2B009DD63 +532C74E3BE5EC555A014BCBB6AB31B8286D7712E0E926F8696830672B8214E9B +5D0740C16ADF0AFD47C4938F373575C6CA91E46D88DE24E682DEC44B57EA8AF8 +4E57D45646073250D82C4B50CBBB0B369932618301F3D4186277103B53B3C9E6 +DB42D6B30115F67B9D078220D5752644930643BDF9FACF684EBE13E39B65055E +B1BD054C324962025EC79E1D155936FE32D9F2224353F2A46C3558EF216F6BB2 +A304BAF752BEEC36C4440B556AEFECF454BA7CBBA7537BCB10EBC21047333A89 +8936419D857CD9F59EBA20B0A3D9BA4A0D3395336B4CDA4BA6451B6E4D1370FA +D9BDABB7F271BC1C6C48D9DF1E5A6FAE788F5609DE3C48D47A67097C547D9817 +AD3A7CCE2B771843D69F860DA4059A71494281C0AD8D4BAB3F67BB6739723C04 +AE05F9E35B2B2CB9C7874C114F57A185C8563C0DCCA93F8096384D71A2994748 +A3C7C8B8AF54961A8838AD279441D9A5EB6C1FE26C98BD025F353124DA68A827 +AE2AF8D25CA48031C242AA433EEEBB8ABA4B96821786C38BACB5F58C3D5DA011 +85B385124C2B6534F3CD1866AF92009D93B97F763AA3CF46C60636D7FC1564CF +1DDFBC12CA37D27A79B11F2AFF2D70DBEE03CF1DFA5B864A2DC22266E4FA43DC +3F2CC229231F1F72874E6A74A90E8003B9AF1BFAA55C071FDDE5C94E4AE3C5BF +936EDFD4164624881410AB9EF0593F823D40BA7D059992104D08E41EBAD8F276 +A84EE2C9AEBC7CCB72AA6B6E6FE52293DC7BC34C2D1B69418392608FC5920291 +733654FA401E05F3E647B1C6AF4BECC3E802F9963344B05EC3DE8C774293CDB4 +3F057D6F258BD341848FA7FDCFD4D1923FCAB51FA8ADAE6D9F19C1FFA6EB5E9F +ECF844CEC6C1320D3F00C7259EF5812526F58248C61F89A42D9C9288CA8076FA +77E1C950940D8D6A7D852A0D0ABEBF2EDEDCDF6DDE0C8CCAC8DA9B28207D9CF8 +46446E1153D8D8795EE914B12349137D4BE461BCF5A6A3CF15FA5B9E91EB9B90 +0483916D0CD40EDC29EB0B996B16462A64F3B19B57802D9AFE3F1D91D9A8553C +531EB8B4E975037ED620EED3020388BFE705958B1E3AD4638B9CC8644C2F4024 +5DACD97151C3DF7A448CC3 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMMI10 +%!PS-AdobeFont-1.1: CMMI10 1.100 +%%CreationDate: 1996 Jul 23 07:53:57 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.100) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMMI10) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.04 def +/isFixedPitch false def +end readonly def +/FontName /CMMI10 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 59 /comma put +dup 76 /L put +dup 85 /U put +dup 102 /f put +dup 103 /g put +dup 104 /h put +dup 105 /i put +dup 110 /n put +dup 120 /x put +readonly def +/FontBBox{-32 -250 1048 750}readonly def +/UniqueID 5087385 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE +3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B +532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 +B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B +986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE +D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958 +9E394A533A081C36D456A09920001A3D2199583EB9B84B4DEE08E3D12939E321 +990CD249827D9648574955F61BAAA11263A91B6C3D47A5190165B0C25ABF6D3E +6EC187E4B05182126BB0D0323D943170B795255260F9FD25F2248D04F45DFBFB +DEF7FF8B19BFEF637B210018AE02572B389B3F76282BEB29CC301905D388C721 +59616893E774413F48DE0B408BC66DCE3FE17CB9F84D205839D58014D6A88823 +D9320AE93AF96D97A02C4D5A2BB2B8C7925C4578003959C46E3CE1A2F0EAC4BF +8B9B325E46435BDE60BC54D72BC8ACB5C0A34413AC87045DC7B84646A324B808 +6FD8E34217213E131C3B1510415CE45420688ED9C1D27890EC68BD7C1235FAF9 +1DAB3A369DD2FC3BE5CF9655C7B7EDA7361D7E05E5831B6B8E2EEC542A7B38EE +03BE4BAC6079D038ACB3C7C916279764547C2D51976BABA94BA9866D79F13909 +95AA39B0F03103A07CBDF441B8C5669F729020AF284B7FF52A29C6255FCAACF1 +74109050FBA2602E72593FBCBFC26E726EE4AEF97B7632BC4F5F353B5C67FED2 +3EA752A4A57B8F7FEFF1D7341D895F0A3A0BE1D8E3391970457A967EFF84F6D8 +47750B1145B8CC5BD96EE7AA99DDC9E06939E383BDA41175233D58AD263EBF19 +AFC0E2F840512D321166547B306C592B8A01E1FA2564B9A26DAC14256414E4C8 +42616728D918C74D13C349F4186EC7B9708B86467425A6FDB3A396562F7EE4D8 +40B43621744CF8A23A6E532649B66C2A0002DD04F8F39618E4F572819DD34837 +B5A08E643FDCA1505AF6A1FA3DDFD1FA758013CAED8ACDDBBB334D664DFF5B53 +95601766758C197F327101A9C9BF396ED625E27A7791ADF7474135C50F2F927A +5B5E332A003F858399565E4C02931D19AC2866CEFAB2288ACA215F2B7BE37156 +89009B14D623E0A872AC17AA52D29EA6E8D725A05A300AAD937745F61803544E +978846734C4C8FEA576A5D77903920CF4531C051776BBDF99ABD8C09849E586C +ED0E1D51A0047D2FF9097EA10DE0E397D69BC302D7A949CC435EE46C508FB6D6 +DAA66F2EDD3A6881D50A440A702018A99102DE5039F7CA1EF9F4C36D5C66AA4C +97C81079C961F48C6EC9E1C26E3740945443C9A262373410B96043CF52CA074A +D18DAFCE0ADE27C2C4A109C21C1B2A8E2F9DF1F14ED57195984F76A5B4213F69 +53C017777402DB63066D528BD2C690959CFE72FAE34C98CA3E797C3CE2B8544E +143B2BB6D7ED137528BC8BB4AB4BB49A295C43C96E92D2D4AA0157DD37CFE2DA +921259A6876045871A994E1316BD39142279BEED0AFCAE7F8D847650D409C934 +D8D16486AC153C8C6F5849270F71DBB5A744A258D5EF64F8819025F49B5A3D29 +889F9CE6CAFB1A44F503559B63B9BEB727C9FD6F99F1E618DEC55C349E1D24BA +3E4599AC645E89E2852D0E152DC94465071B3835EDC93C2924778DFAC1664734 +98F5583DDF83315203AAF78897CE1768F22083276F6D29D07C72CE4B3FF6F293 +28DC673F80626F8654E4FCF6A0263C1DB7AC8F63790729256F9B969908F3A176 +05D7AD6ED5F8E8AF79890282AE7B4C55AEE6526920983A72C5876DE620CF4E3A +7D1376FEF0B296F62C5C29D8D9BEE6B622AAFB66335001F92DAA1E119CFD5101 +08FCB0F238A64FCF56A62C7C08C0871C8D15DB0374C53D39CCD8B1058BAA3FAF +F9785E2D17FCE278B5179EB8AE77B6F1ADBDA6284B0658A07D91B044ABD82EE8 +C9F1763A966496728615DD1EBAB159D7CF6168DBB2582815DA6733785828DF75 +D6848392D3E479E5527DFC967F36D3D66CA6FE01FC6FA9BF6AD401051013DE6A +C69971B1271DFE6ED6A8B53B394CE11FEE75CB1F9AB278A74FD2765FFA3773F9 +F61B5B11C462CE38287536B946E7BD1F8AE0C8F5804B04AFDBB624A2489DAE07 +903F90656C96D1E1C2101FBB9B48C66BFED1B572CEEA04A16AAFE734E754251F +EC12CAF4D56AA5A936D40CBB44E76FF4780B8594967138A1E3092254DB2D4C2C +CDECE9AF76FAF9B3DED9847C79C1723CDD328E4B0B15566C6CD8490ADFEB9169 +418B34C36EF4FB43EF7FB5F1BFE7F795E85FEBA443DCABD076418BA94DAE6505 +D4E6075D792C0C1A6BDFF56326FBA965DFB9519F072BBB8CA486D4C9AA6FCF62 +3CDACB91B41C69837DB4E6DACD0AC582A044D526E340343720AED1742DC4E52F +67579B3A625C4B5E508BCFF3DA667DAE69B25F9D50996033797C42D7CBD85F99 +AB2CDCF739E3B2C6AEA3C315AC2D0F0D48B293B1397A9C1E304260CD8D0C3497 +27385284419D6B3BFCD701C367149332FA1A58EAA22A193C24375D40482129C0 +55BD4147CF597B64FD1F3F3545A03235B6918790D39B7473FE8AE5ED218500D2 +1F6B8EE7632762D06578544C16D9D3866B4A8295904C95CE224E15044770C7B8 +F7408C215A0FA286CAE554D3C51D6BF20B33F4890784816A1AD1B202C381DA82 +01CBEFC0B043181DCD849BCCF035C87708B6E3A9CE4D68B61E35B9CF54123A30 +0939400BA136E6CD4D30F42259ADDAAC17D613E6998BBE4F37C414F397D802AF +83EB5B4247C648B834C3F59C566F252EACE08706E410299F72BEAB9A49274E5E +74F834B4A5983F4C00932124B5D9DFA54E5EF7C1CB9A97C29B49BBCE6F00AE13 +E9CB172D2033E719841728DAB47C858BA8C0687B844B7FC5C2513F5A88A9E5DF +436A28193F1C9A42F840634CCB6681EFC5249080769728E330520A5D6D50164C +0C9A8456535BC89E45BDA70C62CC42C5E750470EFAE512202D95E5BAF604352E +8001E29161B7D6FB6CAD331E42E636021B2854923894715B496038F4AEDBD1E9 +12CC6F15B440C87B8633C43B5D696AFE0C8ACDDC98503A6B3F8685987D178FD6 +E3E8DC9763CCB10ED3D8E065CF3354496D648053B2F0B7B5596528AA91EB6F7D +F7E856ECB8DDB8523CAB5CB6349827450C58A3B007CB9928AF1E98DF77D84B4A +A97B85CEC023289C82A2189AB947C56BAA64911653C2FFFB4D546F3A08821136 +14E904163C9F1CBC64BCC368CBE5764423BB308364B8CA907F38687A153BB01F +6BAE773B21DB3FFE55F9523A52C6286FA2C090F4B8EA11A7C793AC55AAEDDF0C +5E9219B11A940F1ACDE2E124F42F040C9B29D8A56099B0592E1FC33C42B5BAF5 +5CD5E0997B66D81132C4DEE5A9B34AB0761164E23B1418D9AF2EF466EE648BF7 +B550A0559B37AA4EEFE096D5B7B65A891FBB0364CDB8FAC49A7011152CA04B0C +4A91E982CF0E718DBDCAE97F90BC2D22EEA14CDE4003702563D5E02D758A3839 +4A4DDC3DF05069E1F23CB5B5ED68DBFDD1E26FF41967D5158056D86DE8BFAE94 +407645A693988C796417224C91661505FA3983863E2563E4228A5E76BA5E72B9 +10C08AF95D0C4C29E812EF8B3E2CD401562C1C7A35E49054D492DE9712D89C49 +FCB524E3D479A05DABA3D774E30F247A9287407468809AB93E53C3F9B5F5A6D7 +74F447C46BDA6AC95BBFF5A39268259C1E4A4C16FBE30C2DAD58C1D3F9DF5887 +CFE667D2E29DDBA05CE796355F0E1EC3A10FA0421074651E0B584FBD4A04D4C1 +3B4E8E729EB0F7676958F4A3677504132AEAF0DF00F781E4CC4E055917D0F363 +327C3C8E48E75675D425B02D4387269FC8487A325155B0335D +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMR10 +%!PS-AdobeFont-1.1: CMR10 1.00B +%%CreationDate: 1992 Feb 19 19:54:52 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.00B) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMR10) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle 0 def +/isFixedPitch false def +end readonly def +/FontName /CMR10 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 40 /parenleft put +dup 41 /parenright put +dup 43 /plus put +dup 48 /zero put +dup 49 /one put +dup 50 /two put +dup 53 /five put +dup 61 /equal put +readonly def +/FontBBox{-251 -250 1009 969}readonly def +/UniqueID 5000793 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 +016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 +9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F +D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 +469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 +2BDBF16FBC7512FAA308A093FE5CF7158F1163BC1F3352E22A1452E73FECA8A4 +87100FB1FFC4C8AF409B2067537220E605DA0852CA49839E1386AF9D7A1A455F +D1F017CE45884D76EF2CB9BC5821FD25365DDEA6E45F332B5F68A44AD8A530F0 +92A36FAC8D27F9087AFEEA2096F839A2BC4B937F24E080EF7C0F9374A18D565C +295A05210DB96A23175AC59A9BD0147A310EF49C551A417E0A22703F94FF7B75 +409A5D417DA6730A69E310FA6A4229FC7E4F620B0FC4C63C50E99E179EB51E4C +4BC45217722F1E8E40F1E1428E792EAFE05C5A50D38C52114DFCD24D54027CBF +2512DD116F0463DE4052A7AD53B641A27E81E481947884CE35661B49153FA19E +0A2A860C7B61558671303DE6AE06A80E4E450E17067676E6BBB42A9A24ACBC3E +B0CA7B7A3BFEA84FED39CCFB6D545BB2BCC49E5E16976407AB9D94556CD4F008 +24EF579B6800B6DC3AAF840B3FC6822872368E3B4274DD06CA36AF8F6346C11B +43C772CC242F3B212C4BD7018D71A1A74C9A94ED0093A5FB6557F4E0751047AF +D72098ECA301B8AE68110F983796E581F106144951DF5B750432A230FDA3B575 +5A38B5E7972AABC12306A01A99FCF8189D71B8DBF49550BAEA9CF1B97CBFC7CC +96498ECC938B1A1710B670657DE923A659DB8757147B140A48067328E7E3F9C3 +7D1888B284904301450CE0BC15EEEA00E48CCD6388F3FC390E75D51F36C3E61E +E84B5AD036ADADEBD4F8D399AA559B34270D370DEDF077D1D49253F313C333CB +F22FD740EDE076FE3383503F159888E77132A06528CEBA5BB0E57C07D36B73D7 +C81B71200D95D73A1AD33BBA5CA3E34B94447EAB8D27625CBFF13B56F87A9B74 +4B52A09BAB0AABD5E398B1E5E9868BC080EFC7ECBDA4D6817C3255A51A814A04 +0839172E2CCECB4F6E7B5B6B3B61D5858256AD27D93969EBB34C7EE68BF805D0 +39CA6AC7DECCD1A395E7BA297AB0E97B3290EDAED775EAB0D7D553F222A3B014 +FFA358EE448BBB24E1B44CE0BB474DFA01B0F4C4964248444FCA4DDEA8FDA9B8 +82F96DCBEF94CAC9C8F48922899CB1E7D70F650E6471E5408C44554E72599D97 +BC1D32360ECFB378192605E726A3DDA7E5B02736CEB7BE8A5C27AE952F4946D0 +1DD1D65C1D50D0317984B781D64B6075D35EC1E3507FD4FE2E7097A0EE116EEC +3497D2D84B19F68EBF7125FB02920466AE4FE25A3C3068A83A513556D05359A3 +93B6C6929BA47044787EEBA3A38E8266CF1D13DB69779644DF8AFE2C2C5C81F9 +75CBC9CA07E6CB70211CA62FD7CF596132333970E5233AAFBF984EC110664810 +AEFBADCE663CADF91D36D1587C5D7E7F63E3A674856AD7CDB99CD276D3659ED0 +CA0FDC17251E69BA7F2F3AC57257831C31AFBB0DADF44F7E6EF84D63C03E75FF +886FFDAF8153EA8E0779E46935AB0AEFC84AC2061291D39E5F67FB75BEA48EDA +030512CDB14B16D466CFBC58D3764B83AF5C00D05A3F052F53BBE4E1417773CA +BDBEAC50BB7BFF981255BDA6650870E4D67BCB80A63BA050F2650934CB6E742B +B2B2A115C1F9827C979E8F2E92C0A1F428288643C8A27B7105587366E1BFF1FB +056DE92CAD4A7F391A483DE4E9930E8C5BA9B215F1E3FA4798A1740A9B72810A +44CD1D1ECAC8ED7BA3655C4EEF6BF28A2B0B23B0BF783A4FBDDB1246B5EEA601 +6440F98C0A3B6ED360561479EA83990A78A0F4608698B30FE6476AED9349D11F +FB467D3C19D7A3539B8A2DA0C54454A231B87FB441A1BE6893E0F67081E8FF09 +FC20412C452D8227D4BA7665EA8F14A1987845CF8570EDD926F4EF5F2D85DB99 +736D7A939D4313F589033FA135D6366EB8B63C026357360A9E8717656ADABA76 +11B9D672B7D57F1422CAEA295A774CB1F6BEAE51A7A9F7EACF6F22CC6412F1D6 +9DDF884EB94F91B5F301039EE962C51F7FCEF8319CE80F46A7E3187EE60342DB +4057C2374CF68AAD30B5979B24D41ED8A803A1E6EA845D7E7675031A2D4257D8 +4BE91A75006673CE3C24AA4C4138EED6DE5147FD16049BC523D54F26BF951AAC +85157DB39E8B38798267AE2E5266331CFAA0E4D18D2F5C50277BE056498E569E +90AB0A7127F94F0EEC3FC2DC7BF421A2A855318646BACC78EC03D14CC41AB9CA +61649659F81614F8FA9E052F37445DBAF2B0873A06015E16A268544FB047AD0A +E9EF324844E8CA272D00944D54B691CA137E1CF59B69F59D5F9A40EEA081C9EC +6AD88DB832E588F5AACA900198105A8D59C215DCD387B32FE34E9B8476AB5C7A +B739EEE6840ACBFDC79501A04FFB2A57D3A4D3D181D68F074DFB0E828C41FBE3 +E7D0F2A7CE0AC1C7ED09FD9C6E085C89E8BC46BA83A8CED54EDB6EDE1B55B349 +84C37F33BB71994A8EF29050A902448E21CA0B2B5E9DDCF43ACBB79CC841E7EA +5D8BA0D8C18DDFB3B72559BF6251A5F026FAEB035509D20058FEC5FDB1B7E329 +3E299B4FBDF2BD3A5D27035BB8732C3688C3C203D1664522CEBC8BCAC7D4E643 +6490E8CAE79FB51F9285A64099719EA841CD4710392D94660920608397214CEA +588A9CFC233DA75C7C8F381ECEA4065F431122D472D333B2E260DB32F5CCCB15 +56BB953DEC3B6E451B212ABBE079888B73C48744CF5A9C1DCB47C423C647A94F +2B4358B020B2C5FDF1D4B7BE081BC0F4EA86359DFE9BDCC1CBDA475618A71ED4 +F61834FCC9DAA616C7C8D2407333ECE57AD5F5F43FD077EB12C2310BF7EB1EFC +1EAEE06F0891DEFD32AF69082D203207524CA6DC8005C22C1C1CE2C6CBED42B3 +122148A0A6BAFC0DEEEC37594B68494BB5EF16E510C1CD4BF3F6597F98E5362C +544F51DC368425AD6A867D1E6E9AB208C77982536D56581A539597DC172F1D09 +BF027427518C4CCD96BD4321DD8FF54C8D034F66F32F3A2DDFA05E33E5C5408B +8C8511FE0E8F52F38475B84E2A2F5F7B09F8F92D8E1DE2754E683A39EE71BD78 +EFFA9E0804386F6B98CB37112C4A8844C8E2F26C8920CD18089BE16D20922DD4 +AF2EFCE40BCFFB79A001E1DFF89AC67B02FFB09FD38354B57A5FAD9BA3640064 +E4CB7CFC355B5384699A57E86513CA2F89B938688A3F42A6FDBC6E92D50C050E +B96AFCE7691A96AEC83213FC00BD81EA3895 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMSY10 +%!PS-AdobeFont-1.1: CMSY10 1.0 +%%CreationDate: 1991 Aug 15 07:20:57 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.0) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMSY10) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.035 def +/isFixedPitch false def +end readonly def +/FontName /CMSY10 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /periodcentered put +dup 15 /bullet put +dup 102 /braceleft put +dup 103 /braceright put +readonly def +/FontBBox{-29 -960 1116 775}readonly def +/UniqueID 5000820 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964 +7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4 +A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85 +E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A +221A37D9A807DD01161779DDE7D31FF2B87F97C73D63EECDDA4C49501773468A +27D1663E0B62F461F6E40A5D6676D1D12B51E641C1D4E8E2771864FC104F8CBF +5B78EC1D88228725F1C453A678F58A7E1B7BD7CA700717D288EB8DA1F57C4F09 +0ABF1D42C5DDD0C384C7E22F8F8047BE1D4C1CC8E33368FB1AC82B4E96146730 +DE3302B2E6B819CB6AE455B1AF3187FFE8071AA57EF8A6616B9CB7941D44EC7A +71A7BB3DF755178D7D2E4BB69859EFA4BBC30BD6BB1531133FD4D9438FF99F09 +4ECC068A324D75B5F696B8688EEB2F17E5ED34CCD6D047A4E3806D000C199D7C +515DB70A8D4F6146FE068DC1E5DE8BC57030ACE57A0A31C99BEDB251A0ECAD78 +253AB3339E847FBB1AF693606A973F6ECD887C325CA59C6A4A9AC48AF5551D10 +EE26B8C4DA13F670D3F0C09187B9AB37F2BA6A32F8D363393D22215650EEE7F8 +DFB1378390C44F36098EA2DA6CB943DACFB8AECD62E46F120BE7A15C19200094 +7975CA278BAF5E155531F90FCBFE67D2AC15BA6E3B15FEF09F697956F198D111 +16292151DECACDAF2B2CF42B82DE6D4515735744887745770F8D8656BAEEFC04 +2F6A832F466D4244F1F9998BF49A413F094108FC90F586AEB324888BD885F2A1 +C749504E6DCB10F6A2B797826939AFA46BD208A268FB4C6635264B2B39F6E11E +34ED5B3D02E6C9178BFE61AE0A0B6B789E394F8A33730EC5E4484F2D962268F5 +8FD36EAD6CF68C7120E82FD8B2EA91095227CFF985054557361FD9B1E8FACB8C +A17AD35513D4D69B5D52470A6B4796299442430E66AAB39A574CF4C4D0838C52 +B675FB04C646FE52C599EA039302B200CEA102986E6549225D22F30455B7947B +5DCF0190B5296E12FA026272B1D2076B630CABB8F71589ECB69B95486A650A09 +05D11C00F0909A7228A107C7D27074FC6B5380FB3534816E122D65369D70C68E +98E1951DA9756B3CD665F378B661506661175A89D37889CDB07D1692988875EE +878DC0771EF29DDB382287584FE12E47FD7CEE6C130E2D2B3028C8C54B83C977 +26845C0960D62A50B290605368BE2568340524244ABCEE470B683E92456DEE76 +228DCCBDBC688458DF63F2C1E4D8BA46657CB79B9E28179AD2459603874FC200 +CAB2ABDBD725DB89EB7E7C5DFE03826FC7EA65F57CF87E382A976D70F44596B5 +53C6DC34FE7F2B295D67AA8A550F1DF1D040237352D42F14D1D0E7A23318E53B +BA0958CC11E47508EE8D9DCAB8116452978F0963222D14739F8E890A39AB41BC +B66B92570A18 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMMI12 +%!PS-AdobeFont-1.1: CMMI12 1.100 +%%CreationDate: 1996 Jul 27 08:57:55 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.100) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMMI12) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.04 def +/isFixedPitch false def +end readonly def +/FontName /CMMI12 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 60 /less put +dup 62 /greater put +readonly def +/FontBBox{-30 -250 1026 750}readonly def +/UniqueID 5087386 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE +3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B +532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 +B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B +986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE +D919C2DDD26BDC0D99398B9F4D03D6A8F05B47AF95EF28A9C561DBDC98C47CF5 +5250011D19E9366EB6FD153D3A100CAA6212E3D5D93990737F8D326D347B7EDC +4391C9DF440285B8FC159D0E98D4258FC57892DCC57F7903449E07914FBE9E67 +3C15C2153C061EB541F66C11E7EE77D5D77C0B11E1AC55101DA976CCACAB6993 +EED1406FBB7FF30EAC9E90B90B2AF4EC7C273CA32F11A5C1426FF641B4A2FB2F +4E68635C93DB835737567FAF8471CBC05078DCD4E40E25A2F4E5AF46C234CF59 +2A1CE8F39E1BA1B2A594355637E474167EAD4D97D51AF0A899B44387E1FD933A +323AFDA6BA740534A510B4705C0A15647AFBF3E53A82BF320DD96753639BE49C +2F79A1988863EF977B800C9DB5B42039C23EB86953713F730E03EA22FF7BB2C1 +D97D33FD77B1BDCC2A60B12CF7805CFC90C5B914C0F30A673DF9587F93E47CEA +5932DD1930560C4F0D97547BCD805D6D854455B13A4D7382A22F562D7C55041F +0FD294BDAA1834820F894265A667E5C97D95FF152531EF97258F56374502865D +A1E7C0C5FB7C6FB7D3C43FEB3431095A59FBF6F61CEC6D6DEE09F4EB0FD70D77 +2A8B0A4984C6120293F6B947944BE23259F6EB64303D627353163B6505FC8A60 +00681F7A3968B6CBB49E0420A691258F5E7B07B417157803FCBE9B9FB1F80FD8 +CA0DA1186446DD565542BCCC7D339A1EB34C7F49246E8D72E987EB477C6DB757 +99AF86CEBCD7605C487A00CD2CD093098182DC57B20D78ECE0BECF3A0BF88EBA +C866DB19F34BBBED6634AFC0F08D2AFB2A92578A6F8B4ADCD6594737FF6EED7D +5B536DA9E3E2CADB40DB7C600EA4D100D33C3B92B1CF857E012C4EB370BA8295 +55B50047CD58E912E67E22C1B92F41D0BEE742201DF198F3766AE35EA71D8195 +A8C94D661C40D718CB09497485FAA34204229AECFE644C93FFDA54C789E4F751 +3D2519F7CB9E79B2ABE3101DF2EBFAD375469CDC687FB3DC2833EDC0F946B41F +F28D72FFF2A9B8B0D76DC542537612E2BE0F3FB9601C897386359C55E867A547 +F872005F5C56C6EC5E9685E03D7A82653BE8B69741C4DF332AEEB2AA450B23F3 +EABD5ED060606CC7DB1762632EC3C6C4A66ADAF61A97D949DEA5156B4CF34765 +67AC3F10AE17199A710A882D47979F9D41AA2CB794648BE47479F0B00E18BF04 +923F54CEC1214BAFA39BB65ECB013875899E9901B7882D16D2E2C97AD3353668 +A6070081E4DC627AF9192599F5876369908FBDFA11E8D6CB2E83896E9C897CEC +FD1D25651D66A333AF531FF74E1B0DEB1E3D1B5B7D3FB9D1C8BF60517B31C8D2 +1C264F44BC9AF3D9BA5280D1618EED96C11ED24F789FAA263394C658DFCA8DE9 +D47D9E188E212F9EC1DCF449DFDAB8437FAB9EA9AF01AE1714E8F932855182 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +TeXDict begin 40258431 52099146 1000 600 600 (cudd.dvi) +@start /Fa 137[40 51 1[35 35 8[25 2[30 40 45 40 16[61 +13[66 61 67[{ TeXBase1Encoding ReEncodeFont }12 90.9091 +/Times-BoldItalic rf /Fb 136[50 7[37 2[21 108[{ + TeXBase1Encoding ReEncodeFont }3 74.7198 /Times-Italic +rf /Fc 204[35 35 35 35 48[{}4 66.4176 /CMR8 rf /Fd 207[19 +47[55{}2 66.4176 /CMSY8 rf /Fe 133[33 37 37 54 37 37 +21 29 25 1[37 37 37 58 21 37 1[21 37 37 25 33 37 33 37 +33 9[71 54 54 46 11[54 2[46 54 50 7[21 21 10[21 19 25 +19 41[42 2[{ TeXBase1Encoding ReEncodeFont }39 74.7198 +/Times-Roman rf /Ff 201[25 25 25 25 25 25 49[{ + TeXBase1Encoding ReEncodeFont }6 49.8132 /Times-Roman +rf /Fg 201[33 33 33 33 33 33 49[{ TeXBase1Encoding ReEncodeFont }6 +66.4176 /Times-Roman rf /Fh 130[55 55 55 55 55 55 55 +55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 +55 55 55 55 1[55 1[55 55 55 55 1[55 1[55 55 55 55 55 +55 55 55 55 55 55 2[55 55 55 55 55 55 55 55 55 55 55 +55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 +55 55 55 55 55 2[55 1[55 55 55 33[{ TeXBase1Encoding ReEncodeFont }84 +90.9091 /Courier rf /Fi 133[44 50 1[72 50 55 33 39 44 +55 55 50 55 83 28 55 1[28 55 50 33 44 55 44 55 50 6[66 +2[100 72 72 66 55 72 1[61 78 1[94 66 78 1[39 78 78 61 +1[72 72 66 72 7[50 50 50 50 50 50 50 50 50 50 28 25 46[{ + TeXBase1Encoding ReEncodeFont }56 99.6264 /Times-Bold +rf /Fj 145[43 110[{}1 66.4176 /CMMI8 rf /Fk 135[52 9[55 +4[31 52 43 45 16[62 8[62 16[25 59[{}9 90.9091 /CMMI10 +rf /Fl 194[71 7[45 2[45 45 45 4[71 1[35 35 40[{}8 90.9091 +/CMR10 rf /Fm 152[45 45 86[45 13[25 1[{}4 90.9091 /CMSY10 +rf /Fn 133[35 40 40 61 40 45 25 35 35 45 45 45 45 66 +25 40 25 25 45 45 25 40 45 40 45 45 6[51 1[56 76 56 66 +51 45 56 66 56 66 61 76 51 61 40 30 66 66 56 56 66 61 +56 56 7[45 1[45 3[45 45 45 2[23 30 3[30 30 30 35[45 45 +2[{ TeXBase1Encoding ReEncodeFont }63 90.9091 /Times-Italic +rf /Fo 87[30 16[91 45 1[40 40 24[40 45 45 66 45 45 25 +35 30 45 45 45 45 71 25 45 25 25 45 45 30 40 45 40 45 +40 3[30 1[30 56 66 66 86 66 66 56 51 61 66 51 66 66 81 +56 66 35 30 66 66 51 56 66 61 61 66 5[25 25 45 45 45 +45 45 45 45 45 45 45 25 23 30 23 51 1[30 30 30 1[76 33[51 +51 2[{ TeXBase1Encoding ReEncodeFont }82 90.9091 /Times-Roman +rf /Fp 105[45 27[40 45 45 66 45 51 30 35 40 1[51 45 51 +76 25 51 1[25 51 45 30 40 51 40 51 45 6[61 66 66 91 66 +66 61 51 66 1[56 71 66 86 61 2[35 71 71 56 61 66 66 61 +66 5[30 30 1[45 1[45 45 45 45 45 45 45 1[23 1[23 52 3[30 +36[51 2[{ TeXBase1Encoding ReEncodeFont }63 90.9091 /Times-Bold +rf /Fq 135[60 86 1[66 40 47 53 2[60 66 100 33 66 1[33 +66 60 40 53 66 53 1[60 11[86 80 1[86 1[73 2[113 3[47 +93 93 2[86 86 1[86 10[60 60 60 60 60 60 5[68 3[40 39[{ + TeXBase1Encoding ReEncodeFont }38 119.552 /Times-Bold +rf /Fr 193[76 1[76 60[{}2 99.6264 /CMMI12 rf /Fs 133[44 +50 2[50 50 28 39 33 1[50 50 50 78 28 2[28 1[50 33 44 +50 44 50 44 11[72 1[55 12[55 61 72 66 66 1[92 11[50 1[50 +50 50 1[25 1[25 44[{ TeXBase1Encoding ReEncodeFont }34 +99.6264 /Times-Roman rf /Ft 140[56 48 2[72 72 112 40 +72 1[40 1[72 1[64 1[64 1[64 11[104 2[96 1[80 11[104 96 +8[40 4[72 2[72 1[72 1[36 46[{ TeXBase1Encoding ReEncodeFont }22 +143.462 /Times-Roman rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin + end +%%EndSetup +%%Page: 1 1 +TeXDict begin 1 0 bop Black Black Black Black 804 937 +a Ft(CUDD:)34 b(CU)i(Decision)d(Diagram)h(P)n(ackage)1558 +1120 y(Release)g(2.5.0)1643 1373 y Fs(F)o(abio)25 b(Somenzi)720 +1489 y(Department)f(of)h(Electrical,)g(Computer)l(,)f(and)h(Ener)n(gy)g +(Engineering)1261 1605 y(Uni)n(v)o(ersity)e(of)i(Colorado)f(at)h +(Boulder)1408 1721 y Fr(<)p Fs(F)o(abio@Colorado.EDU)p +Fr(>)1601 1923 y Fs(February)h(4,)e(2012)448 2316 y Fq(Contents)448 +2523 y Fp(1)92 b(Intr)n(oduction)2315 b(4)448 2726 y(2)92 +b(Ho)o(w)22 b(to)i(Get)f(CUDD)2077 b(5)585 2839 y Fo(2.1)96 +b(The)23 b(CUDD)e(P)o(ackage)92 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 171 w(5)p Black 585 2952 a(2.2)96 b(CUDD)21 b(Friends)81 +b(.)45 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(5)p +Black 448 3156 a Fp(3)92 b(User')m(s)23 b(Manual)2238 +b(5)585 3269 y Fo(3.1)96 b(Compiling)24 b(and)g(Linking)53 +b(.)45 b(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(6)p Black 585 3382 +a(3.2)96 b(Basic)23 b(Data)h(Structures)51 b(.)45 b(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +p Black 171 w(6)p Black 794 3495 a(3.2.1)110 b(Nodes)41 +b(.)46 b(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 +w(6)p Black 794 3608 a(3.2.2)110 b(The)23 b(Manager)60 +b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(7)p Black 794 +3721 a(3.2.3)110 b(Cache)46 b(.)g(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +p Black 171 w(8)p Black 585 3833 a(3.3)96 b(Initializing)26 +b(and)e(Shutting)h(Do)n(wn)e(a)g(DdManager)78 b(.)46 +b(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(8)p +Black 585 3946 a(3.4)96 b(Setting)24 b(P)o(arameters)87 +b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(9)p Black +585 4059 a(3.5)96 b(Constant)25 b(Functions)66 b(.)45 +b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(9)p Black 794 +4172 a(3.5.1)110 b(One,)23 b(Logic)g(Zero,)g(and)h(Arithmetic)h(Zero)41 +b(.)46 b(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +171 w(9)p Black 794 4285 a(3.5.2)110 b(Prede\002ned)24 +b(Constants)51 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(10)p Black 794 +4398 a(3.5.3)110 b(Background)36 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(10)p Black 794 4511 a(3.5.4)110 b(Ne)n(w)22 +b(Constants)65 b(.)45 b(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(11)p +Black 585 4624 a(3.6)96 b(Creating)25 b(V)-10 b(ariables)28 +b(.)45 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(11)p +Black 794 4737 a(3.6.1)110 b(Ne)n(w)22 b(BDD)f(and)j(ADD)e(V)-10 +b(ariables)43 b(.)i(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)p Black 125 w(11)p Black 794 4850 a(3.6.2)110 b(Ne)n(w)22 +b(ZDD)f(V)-10 b(ariables)81 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(12)p +Black 585 4963 a(3.7)96 b(Basic)23 b(BDD)f(Manipulation)47 +b(.)f(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)p Black 125 w(12)p Black Black 1920 +5225 a(1)p Black eop end +%%Page: 2 2 +TeXDict begin 2 1 bop Black Black 585 573 a Fo(3.8)96 +b(Basic)23 b(ADD)f(Manipulation)42 b(.)k(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(13)p Black 585 686 a(3.9)96 b(Basic)23 b(ZDD)f +(Manipulation)52 b(.)46 b(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(14)p +Black 585 799 a(3.10)51 b(Con)l(v)o(erting)26 b(ADDs)c(to)h(BDDs)f(and) +i(V)-5 b(ice)23 b(V)-10 b(ersa)85 b(.)45 b(.)h(.)f(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)p Black 125 w(15)p Black 585 912 a(3.11)51 +b(Con)l(v)o(erting)26 b(BDDs)c(to)h(ZDDs)f(and)i(V)-5 +b(ice)23 b(V)-10 b(ersa)27 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)p Black 125 w(15)p Black 585 1024 a(3.12)51 +b(V)-10 b(ariable)24 b(Reordering)i(for)e(BDDs)e(and)i(ADDs)63 +b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(16)p Black 585 1137 a(3.13)51 b(Grouping)25 +b(V)-10 b(ariables)61 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(19)p Black 585 1250 a(3.14)51 b(V)-10 b(ariable)24 +b(Reordering)i(for)e(ZDDs)68 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(20)p +Black 585 1363 a(3.15)51 b(K)n(eeping)24 b(Consistent)i(V)-10 +b(ariable)24 b(Orders)h(for)e(BDDs)f(and)i(ZDDs)46 b(.)f(.)g(.)g(.)g(.) +p Black 125 w(21)p Black 585 1476 a(3.16)51 b(Hooks)k(.)45 +b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(21)p Black 585 1589 a(3.17)51 b(T)m(imeouts)24 +b(and)g(Limits)82 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(22)p Black 585 1702 a(3.18)51 b(The)23 b(SIS/VIS)f(Interf)o(ace) +27 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(22)p Black +794 1815 a(3.18.1)65 b(Using)24 b(the)f(CUDD)f(P)o(ackage)i(in)f(SIS)h +(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(22)p Black 585 1928 a(3.19)51 b(Writing)24 +b(Decision)h(Diagrams)f(to)g(a)f(File)57 b(.)45 b(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(24)p +Black 585 2041 a(3.20)51 b(Sa)n(ving)24 b(and)g(Restoring)h(BDDs)78 +b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)p Black 125 w(24)p Black 448 2245 a Fp(4)92 +b(Pr)n(ogrammer')m(s)25 b(Manual)1870 b(24)585 2357 y +Fo(4.1)96 b(Compiling)24 b(and)g(Linking)53 b(.)45 b(.)h(.)f(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(24)p Black 585 2470 a(4.2)96 b(Reference)25 +b(Counts)53 b(.)45 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(26)p Black 794 2583 a(4.2.1)110 b(NULL)21 b(Return)j(V)-10 +b(alues)42 b(.)j(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)p Black 125 w(27)p Black 794 2696 +a(4.2.2)110 b Fn(Cudd)p 1286 2696 28 4 v 33 w(Recur)o(siveDer)m(ef)40 +b Fo(vs.)23 b Fn(Cudd)p 2239 2696 V 34 w(Der)m(ef)45 +b Fo(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(27)p Black 794 2809 a(4.2.3)110 b(When)23 b(Increasing)k(the)d +(Reference)h(Count)f(is)f(Unnecessary)90 b(.)45 b(.)p +Black 125 w(27)p Black 794 2922 a(4.2.4)110 b(Saturating)25 +b(Increments)h(and)e(Decrements)91 b(.)45 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)p Black 125 w(28)p Black 585 3035 a(4.3)96 b(Complement)24 +b(Arcs)37 b(.)45 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(28)p Black 585 3148 a(4.4)96 b(The)23 b(Cache)37 +b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(29)p Black 794 3261 a(4.4.1)110 b(Cache)24 +b(Sizing)64 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(29)p +Black 794 3374 a(4.4.2)110 b(Local)23 b(Caches)55 b(.)45 +b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(30)p Black 585 3487 +a(4.5)96 b(The)23 b(Unique)h(T)-7 b(able)47 b(.)e(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)p Black 125 w(31)p Black 585 3599 a(4.6)96 b(Allo)n(wing)24 +b(Asynchronous)j(Reordering)64 b(.)45 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(32)p Black 585 +3712 a(4.7)96 b(Deb)n(ugging)28 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)p Black 125 w(33)p Black 585 3825 a(4.8)96 +b(Gathering)25 b(and)f(Interpreting)j(Statistics)64 b(.)45 +b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(34)p Black 794 3938 a(4.8.1)110 b(Non)23 +b(Modi\002able)i(P)o(arameters)89 b(.)45 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(34)p Black +794 4051 a(4.8.2)110 b(Modi\002able)24 b(P)o(arameters)64 +b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)p Black 125 w(37)p Black 794 4164 a(4.8.3)110 +b(Extended)25 b(Statistics)g(and)f(Reporting)63 b(.)45 +b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(39)p Black 585 4277 a(4.9)96 b(Guidelines)25 b(for)f +(Documentation)75 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(39)p Black 448 +4481 a Fp(5)92 b(The)22 b(C++)g(Interface)2044 b(40)585 +4594 y Fo(5.1)96 b(Compiling)24 b(and)g(Linking)53 b(.)45 +b(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)p Black 125 w(40)p Black 585 4707 +a(5.2)96 b(Basic)23 b(Manipulation)58 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +p Black 125 w(40)p Black 448 4910 a Fp(6)92 b(Ackno)o(wledgments)2050 +b(41)p Black 1920 5225 a Fo(2)p Black eop end +%%Page: 3 3 +TeXDict begin 3 2 bop Black Black 585 573 a Fp(Refer)n(ences)2341 +b(41)585 777 y(Index)2539 b(43)p Black 1920 5225 a Fo(3)p +Black eop end +%%Page: 4 4 +TeXDict begin 4 3 bop Black Black 448 573 a Fq(1)120 +b(Intr)n(oduction)448 780 y Fo(The)28 b(CUDD)d(package)30 +b(pro)o(vides)g(functions)g(to)e(manipulate)i(Binary)e(Decision)i +(Diagrams)448 893 y(\(BDDs\))35 b([5,)f(3)q(],)j(Algebraic)g(Decision)g +(Diagrams)e(\(ADDs\))g([1],)j(and)d(Zero-suppressed)448 +1006 y(Binary)f(Decision)g(Diagrams)g(\(ZDDs\))e([12)q(].)56 +b(BDDs)32 b(are)h(used)g(to)g(represent)j(switching)448 +1119 y(functions;)i(ADDs)30 b(are)h(used)h(to)g(represent)h(function)h +(from)d Fm(f)p Fl(0)p Fk(;)15 b Fl(1)p Fm(g)2673 1086 +y Fj(n)2753 1119 y Fo(to)31 b(an)g(arbitrary)i(set.)448 +1231 y(ZDDs)20 b(represent)j(switching)g(functions)g(lik)o(e)f(BDDs;)e +(ho)n(we)n(v)o(er)l(,)i(the)o(y)g(are)f(much)g(more)g(ef)n(\002-)448 +1344 y(cient)27 b(than)f(BDDs)e(when)i(the)g(functions)i(to)d(be)h +(represented)j(are)c(characteristic)30 b(functions)448 +1457 y(of)h(cube)g(sets,)i(or)d(in)h(general,)i(when)e(the)g(ON-set)f +(of)g(the)h(function)i(to)d(be)h(represented)i(is)448 +1570 y(v)o(ery)24 b(sparse.)30 b(The)o(y)23 b(are)h(inferior)i(to)d +(BDDs)f(in)h(other)i(cases.)589 1683 y(The)30 b(package)h(pro)o(vides)h +(a)d(lar)n(ge)i(set)f(of)f(operations)k(on)c(BDDs,)h(ADDs,)f(and)h +(ZDDs,)448 1796 y(functions)d(to)d(con)l(v)o(ert)h(BDDs)e(into)h(ADDs)f +(or)g(ZDDs)g(and)h(vice)g(v)o(ersa,)h(and)f(a)g(lar)n(ge)h(assort-)448 +1909 y(ment)f(of)f(v)n(ariable)j(reordering)g(methods.)589 +2022 y(The)e(CUDD)d(package)k(can)f(be)g(used)g(in)g(three)g(w)o(ays:)p +Black 585 2190 a Fm(\017)p Black 46 w Fo(As)17 b(a)h(black)h(box.)28 +b(In)18 b(this)h(case,)g(the)g(application)i(program)f(that)f(needs)g +(to)f(manipulate)676 2303 y(decision)25 b(diagrams)f(only)g(uses)g(the) +g(e)o(xported)h(functions)g(of)e(the)h(package.)30 b(The)23 +b(rich)676 2416 y(set)g(of)h(functions)i(included)g(in)d(the)h(CUDD)d +(package)26 b(allo)n(ws)e(man)o(y)f(applications)k(to)676 +2529 y(be)21 b(written)i(in)f(this)g(w)o(ay)-6 b(.)28 +b(Section)23 b(3)e(describes)k(ho)n(w)c(to)h(use)g(the)g(e)o(xported)i +(functions)676 2642 y(of)g(the)h(package.)33 b(An)24 +b(application)k(written)d(in)f(terms)h(of)f(the)h(e)o(xported)h +(functions)h(of)676 2755 y(the)f(package)j(needs)e(not)g(concern)i +(itself)e(with)f(the)h(details)h(of)f(v)n(ariable)h(reordering,)676 +2868 y(which)23 b(may)h(tak)o(e)g(place)h(behind)g(the)f(scenes.)p +Black 585 3047 a Fm(\017)p Black 46 w Fo(As)h(a)g(clear)i(box.)36 +b(When)26 b(writing)g(a)g(sophisticated)j(application)g(based)e(on)f +(decision)676 3160 y(diagrams,)35 b(ef)n(\002cienc)o(y)e(often)g +(dictates)h(that)f(some)f(functions)i(be)e(implemented)i(as)676 +3273 y(direct)h(recursi)n(v)o(e)h(manipulation)i(of)c(the)h(diagrams,)j +(instead)e(of)f(being)g(written)g(in)676 3386 y(terms)e(of)g(e)o +(xisting)i(primiti)n(v)o(e)f(functions.)60 b(Section)35 +b(4)d(e)o(xplains)j(ho)n(w)e(to)g(add)h(ne)n(w)676 3499 +y(functions)j(to)f(the)f(CUDD)e(package.)66 b(It)35 b(also)h(details)h +(ho)n(w)d(to)i(write)f(a)g(recursi)n(v)o(e)676 3612 y(function)25 +b(that)f(can)g(be)g(interrupted)i(by)e(dynamic)h(v)n(ariable)g +(reordering.)p Black 585 3792 a Fm(\017)p Black 46 w +Fo(Through)c(an)f(interf)o(ace.)30 b(Object-oriented)23 +b(languages)g(lik)o(e)e(C++)e(and)h(Perl5)g(can)h(free)676 +3905 y(the)k(programmer)h(from)f(the)h(b)n(urden)h(of)e(memory)g +(management.)35 b(A)24 b(C++)g(interf)o(ace)676 4018 +y(is)k(included)i(in)e(the)h(distrib)n(ution)j(of)c(CUDD.)d(It)j +(automatically)k(frees)d(decision)h(di-)676 4131 y(agrams)g(that)f(are) +h(no)f(longer)i(used)f(by)f(the)h(application)i(and)e(o)o(v)o(erloads)h +(operators.)676 4244 y(Almost)i(all)h(the)g(functionality)k(pro)o +(vided)e(by)e(the)g(CUDD)d(e)o(xported)36 b(functions)g(is)676 +4356 y(a)n(v)n(ailable)d(through)g(the)e(C++)f(interf)o(ace,)35 +b(which)c(is)g(especially)j(recommended)f(for)676 4469 +y(f)o(ast)e(prototyping.)56 b(Section)32 b(5)f(e)o(xplains)j(ho)n(w)c +(to)i(use)f(the)h(interf)o(ace.)54 b(A)31 b(Perl5)g(in-)676 +4582 y(terf)o(ace)38 b(also)g(e)o(xists)g(and)f(is)g(ditrib)n(uted)j +(separately)-6 b(.)71 b(\(See)37 b(Section)h(2.2.\))69 +b(Some)676 4695 y(applications)27 b(de\002ne)d(their)g(o)n(wn)f(interf) +o(aces.)31 b(See)23 b(for)h(e)o(xample)g(Section)h(3.18.)448 +4863 y(In)k(the)h(follo)n(wing,)i(the)d(reader)i(is)e(supposed)j(to)d +(be)g(f)o(amiliar)h(with)f(the)h(basic)g(ideas)g(about)448 +4976 y(decision)c(diagrams,)f(as)e(found,)i(for)e(instance,)j(in)d([3)q +(].)p Black 1920 5225 a(4)p Black eop end +%%Page: 5 5 +TeXDict begin 5 4 bop Black Black 448 573 a Fq(2)120 +b(Ho)o(w)29 b(to)h(Get)g(CUDD)448 783 y Fi(2.1)99 b(The)26 +b(CUDD)f(P)o(ackage)448 957 y Fo(The)36 b(CUDD)e(package)39 +b(is)d(a)n(v)n(ailable)j(via)d(anon)o(ymous)j(FTP)34 +b(from)i(vlsi.Colorado.EDU.)448 1070 y(A)29 b(compressed)j(tar)e +(\002le)f(named)h Fh(cudd-2.5.0.tar.)o(gz)22 b Fo(can)31 +b(be)e(found)i(in)f(directory)448 1183 y Fh(pub)p Fo(.)d(Once)c(you)h +(ha)n(v)o(e)h(this)f(\002le,)p Black Black 676 1371 a +Fh(gzip)52 b(-dc)i(cudd-2.5.0.tar)o(.g)o(z)48 b(|)54 +b(tar)g(xvf)f(-)448 1559 y Fo(will)27 b(create)g(directory)j +Fh(cudd-2.5.0)21 b Fo(and)27 b(its)g(subdirectories.)42 +b(These)27 b(directories)j(con-)448 1671 y(tain)h(the)g(decision)i +(diagram)f(package,)i(a)c(fe)n(w)g(support)j(libraries,)h(and)d(a)f(to) +o(y)h(application)448 1784 y(based)23 b(on)f(the)h(decision)h(diagram)f +(package.)30 b(There)22 b(is)g(a)f(README)e(\002le)i(with)h +(instructions)448 1897 y(on)33 b(con\002guration)j(and)d(installation)j +(in)d Fh(cudd-2.5.0)p Fo(.)51 b(Y)-10 b(ou)32 b(can)i(use)f(a)f +(compiler)i(for)448 2010 y(either)25 b(ANSI)d(C)g(or)i(C++.)589 +2123 y(Once)g(you)g(ha)n(v)o(e)g(made)g(the)g(libraries)h(and)f +(program,)h(you)f(can)g(type:)p Black Black 676 2311 +a Fh(cd)53 b(nanotrav)676 2424 y(nanotrav)e(-p)i(1)h(-autodyn)d +(-reordering)f(sifting)h(-trav)676 2537 y(mult32a.blif)448 +2724 y Fo(This)26 b(will)g(run)h(a)e(simple-minded)k(FSM)c(tra)n(v)o +(ersal)j(program.)38 b(\(On)25 b(a)h(2.4)g(GHz)f(Pentium)i(4)448 +2837 y(\(TM\),)g(it)h(tak)o(es)h(about)h(0.5)e(s.\))42 +b(The)28 b(output)i(produced)g(by)f(the)f(program)h(can)g(be)f(check)o +(ed)448 2950 y(against)35 b Fh(cudd-2.5.0/nano)o(tra)o(v/)o(mu)o(lt)o +(32)o(a.o)o(ut)o Fo(.)52 b(More)34 b(information)i(on)e(the)448 +3063 y Fh(nanotrav)19 b Fo(program)25 b(can)f(be)g(found)g(in)g +Fh(cudd-2.5.0/nan)o(otr)o(av)o(/R)o(EA)o(DM)o(E)p Fo(.)589 +3176 y(If)i(you)h(w)o(ant)f(to)g(be)g(noti\002ed)h(of)f(ne)n(w)f +(releases)j(of)e(the)h(CUDD)c(package,)29 b(send)e(a)e(mes-)448 +3289 y(sage)g(to)e Fh(Fabio@Colorado.)o(ED)o(U)p Fo(.)448 +3538 y Fi(2.2)99 b(CUDD)25 b(Friends)448 3712 y Fo(T)-7 +b(w)o(o)18 b(CUDD)g(e)o(xtensions)k(are)e(a)n(v)n(ailable)h(via)f(anon) +o(ymous)i(FTP)17 b(from)i(vlsi.Colorado.EDU.)p Black +585 3900 a Fm(\017)p Black 46 w Fn(P)-7 b(erlDD)27 b +Fo(is)i(an)f(object-oriented)34 b(Perl5)29 b(interf)o(ace)i(to)d(CUDD.) +f(It)h(is)h(or)n(ganized)i(as)e(a)676 4013 y(standard)f(Perl)e(e)o +(xtension)j(module.)39 b(The)26 b(Perl)g(interf)o(ace)j(is)d(at)h(a)f +(some)n(what)h(higher)676 4126 y(le)n(v)o(el)c(than)i(the)e(C++)g +(interf)o(ace,)j(b)n(ut)e(it)f(is)h(not)g(as)f(complete.)p +Black 585 4313 a Fm(\017)p Black 46 w Fn(DDcal)g Fo(is)h(a)g(graphic)h +(BDD)e(calculator)j(based)f(on)f(CUDD,)e(Perl-Tk,)i(and)g(dot.)31 +b(\(See)676 4426 y(Section)24 b(3.19)g(for)g(information)i(on)d +Fn(dot)p Fo(.\))448 4719 y Fq(3)120 b(User')l(s)28 b(Manual)448 +4926 y Fo(This)c(section)h(describes)h(the)e(use)g(of)f(the)h(CUDD)d +(package)26 b(as)d(a)g(black)i(box.)p Black 1920 5225 +a(5)p Black eop end +%%Page: 6 6 +TeXDict begin 6 5 bop Black Black 448 573 a Fi(3.1)99 +b(Compiling)25 b(and)g(Linking)448 747 y Fo(T)-7 b(o)23 +b(b)n(uild)i(an)e(application)k(that)d(uses)g(the)g(CUDD)d(package,)26 +b(you)e(should)h(add)p Black Black 448 935 a Fh(#include)51 +b("util.h")448 1048 y(#include)g("cudd.h")448 1235 y +Fo(to)32 b(your)g(source)h(\002les,)g(and)g(should)g(link)f +Fh(libcudd.a)p Fo(,)d Fh(libmtr.a)p Fo(,)f Fh(libst.a)p +Fo(,)i(and)448 1348 y Fh(libutil.a)23 b Fo(to)28 b(your)h(e)o(x)o +(ecutable.)43 b(\(All)28 b(these)h(libraries)g(are)f(part)h(of)f(the)g +(distrib)n(ution.\))448 1461 y(Some)20 b(platforms)h(require)h +(speci\002c)e(compiler)i(and)e(link)o(er)h(\003ags.)28 +b(Refer)20 b(to)g(the)g Fh(Makefile)448 1574 y Fo(in)k(the)g(top)f(le)n +(v)o(el)h(directory)i(of)e(the)f(distrib)n(ution.)589 +1687 y(K)n(eep)d(in)g(mind)g(that)h(whate)n(v)o(er)g(\003ags)e(af)n +(fect)i(the)g(size)f(of)g(data)h(structures\227for)i(instance)448 +1800 y(the)e(\003ags)f(used)g(to)g(use)h(64-bit)g(pointers)h(where)f(a) +n(v)n(ailable\227must)i(be)d(speci\002ed)h(when)f(com-)448 +1913 y(piling)25 b(both)g(CUDD)c(and)j(the)g(\002les)f(that)h(include)h +(its)f(header)h(\002les.)448 2162 y Fi(3.2)99 b(Basic)25 +b(Data)g(Structur)n(es)448 2336 y Fp(3.2.1)92 b(Nodes)448 +2510 y Fo(BDDs,)24 b(ADDs,)h(and)h(ZDDs)d(are)j(made)g(of)f(DdNode')-5 +b(s.)35 b(A)25 b(DdNode)g(\(node)i(for)f(short\))g(is)g(a)448 +2623 y(structure)j(with)d(se)n(v)o(eral)i(\002elds.)37 +b(Those)27 b(that)g(are)f(of)h(interest)h(to)e(the)h(application)j +(that)d(uses)448 2736 y(the)e(CUDD)d(package)27 b(as)d(a)g(black)i(box) +f(are)f(the)h(v)n(ariable)h(inde)o(x,)g(the)e(reference)j(count,)f(and) +448 2849 y(the)f(v)n(alue.)33 b(The)24 b(remaining)i(\002elds)f(are)f +(pointers)j(that)e(connect)i(nodes)e(among)g(themselv)o(es)448 +2962 y(and)f(that)g(are)g(used)g(to)g(implement)h(the)e(unique)j +(table.)j(\(See)23 b(Section)i(3.2.2.\))589 3075 y(The)h +Fn(inde)n(x)i Fo(\002eld)e(holds)h(the)g(name)f(of)g(the)h(v)n(ariable) +h(that)e(labels)i(the)e(node.)38 b(The)25 b(inde)o(x)448 +3188 y(of)37 b(a)f(v)n(ariable)i(is)f(a)f(permanent)j(attrib)n(ute)g +(that)e(re\003ects)g(the)g(order)h(of)e(creation.)70 +b(Inde)o(x)448 3301 y(0)26 b(corresponds)k(to)c(the)g(v)n(ariable)i +(created)g(\002rst.)36 b(On)25 b(a)h(machine)h(with)f(32-bit)h +(pointers,)i(the)448 3414 y(maximum)21 b(number)h(of)e(v)n(ariables)j +(is)d(the)h(lar)n(gest)i(v)n(alue)e(that)h(can)f(be)f(stored)j(in)d(an) +h(unsigned)448 3527 y(short)27 b(inte)o(ger)g(minus)f(1.)35 +b(The)25 b(lar)n(gest)j(inde)o(x)f(is)e(reserv)o(ed)j(for)e(the)g +(constant)h(nodes.)37 b(When)448 3640 y(64-bit)24 b(pointers)g(are)e +(used,)h(the)f(maximum)g(number)h(of)f(v)n(ariables)i(is)e(the)g(lar)n +(gest)i(v)n(alue)f(that)448 3752 y(can)h(be)g(stored)h(in)e(an)h +(unsigned)i(inte)o(ger)e(minus)g(1.)589 3865 y(When)k(v)n(ariables)i +(are)e(reordered)i(to)e(reduce)h(the)f(size)g(of)f(the)h(decision)i +(diagrams,)g(the)448 3978 y(v)n(ariables)h(may)e(shift)h(in)f(the)g +(order)l(,)i(b)n(ut)f(the)o(y)f(retain)h(their)g(indices.)47 +b(The)28 b(package)j(k)o(eeps)448 4091 y(track)d(of)e(the)h(v)n +(ariable)h(permutation)h(\(and)e(its)g(in)l(v)o(erse\).)40 +b(The)26 b(application)j(is)e(not)g(af)n(fected)448 4204 +y(by)d(v)n(ariable)h(reordering,)h(e)o(xcept)f(in)e(the)h(follo)n(wing) +h(cases.)p Black 585 4392 a Fm(\017)p Black 46 w Fo(If)17 +b(the)i(application)i(uses)e(generators)i(\()p Fn(Cudd)p +2104 4392 28 4 v 34 w(F)-10 b(or)m(eac)o(hCube)20 b Fo(and)e +Fn(Cudd)p 2985 4392 V 34 w(F)-10 b(or)m(eac)o(hNode)p +Fo(\))676 4505 y(and)20 b(reordering)j(is)d(enabled,)j(then)e(it)f +(must)g(tak)o(e)h(care)f(not)h(to)f(call)h(an)o(y)f(operation)j(that) +676 4618 y(may)29 b(create)i(ne)n(w)e(nodes)j(\(and)e(hence)h(possibly) +h(trigger)g(reordering\).)51 b(This)29 b(is)h(be-)676 +4730 y(cause)j(the)g(cubes)h(\(i.e.,)g(paths\))g(and)f(nodes)h(of)e(a)g +(diagram)i(change)g(as)f(a)f(result)h(of)676 4843 y(reordering.)p +Black 1920 5225 a(6)p Black eop end +%%Page: 7 7 +TeXDict begin 7 6 bop Black Black Black 585 573 a Fm(\017)p +Black 46 w Fo(If)26 b(the)h(application)j(uses)d Fn(Cudd)p +1712 573 28 4 v 34 w(bddConstr)o(ain)j Fo(and)d(reordering)i(tak)o(es)f +(place,)h(then)676 686 y(the)23 b(property)j(of)e Fn(Cudd)p +1440 686 V 33 w(bddConstr)o(ain)j Fo(of)c(being)i(an)e(image)h +(restrictor)i(is)e(lost.)589 873 y(The)j(CUDD)f(package)j(relies)g(on)e +(garbage)i(collection)h(to)e(reclaim)g(the)g(memory)f(used)448 +986 y(by)35 b(diagrams)i(that)e(are)h(no)f(longer)h(in)f(use.)64 +b(The)34 b(scheme)i(emplo)o(yed)h(for)e(garbage)i(col-)448 +1099 y(lection)32 b(is)d(based)i(on)f(k)o(eeping)h(a)e(reference)j +(count)f(for)f(each)g(node.)48 b(The)29 b(references)k(that)448 +1212 y(are)26 b(counted)i(are)e(both)h(the)f(internal)h(references)i +(\(references)f(from)e(other)h(nodes\))g(and)f(e)o(x-)448 +1325 y(ternal)37 b(references)h(\(typically)g(references)g(from)d(the)g +(calling)i(en)l(vironment\).)68 b(When)35 b(an)448 1438 +y(application)25 b(creates)f(a)d(ne)n(w)g(BDD,)f(ADD,)f(or)j(ZDD,)d(it) +j(must)f(increase)j(its)e(reference)i(count)448 1551 +y(e)o(xplicitly)-6 b(,)40 b(through)d(a)e(call)g(to)g +Fn(Cudd)p 1707 1551 V 34 w(Ref)13 b Fo(.)62 b(Similarly)-6 +b(,)38 b(when)e(a)e(diagram)i(is)f(no)g(longer)448 1664 +y(needed,)28 b(the)e(application)i(must)e(call)g Fn(Cudd)p +1877 1664 V 34 w(Recur)o(siveDer)m(ef)41 b Fo(\(for)26 +b(BDDs)e(and)i(ADDs\))e(or)448 1777 y Fn(Cudd)p 649 1777 +V 34 w(Recur)o(siveDer)m(efZdd)29 b Fo(\(for)24 b(ZDDs\))e(to)h +(\223rec)o(ycle\224)j(the)e(nodes)h(of)e(the)h(diagram.)589 +1890 y(T)-6 b(erminal)37 b(nodes)h(carry)g(a)e(v)n(alue.)69 +b(This)36 b(is)h(especially)i(important)g(for)d(ADDs.)67 +b(By)448 2002 y(def)o(ault,)29 b(the)f(v)n(alue)f(is)g(a)f(double.)41 +b(T)-7 b(o)25 b(change)k(to)d(something)j(dif)n(ferent)g(\(e.g.,)e(an)g +(inte)o(ger\),)448 2115 y(the)21 b(package)i(must)d(be)h(modi\002ed)g +(and)g(recompiled.)30 b(Support)21 b(for)g(this)g(process)i(is)d +(currently)448 2228 y(v)o(ery)k(rudimentary)-6 b(.)448 +2474 y Fp(3.2.2)92 b(The)22 b(Manager)448 2648 y Fo(All)27 +b(nodes)i(used)g(in)f(BDDs,)f(ADDs,)g(and)h(ZDDs)e(are)i(k)o(ept)g(in)g +(special)h(hash)g(tables)g(called)448 2761 y(the)36 b +Fn(unique)i(tables)p Fo(.)66 b(Speci\002cally)-6 b(,)40 +b(BDDs)35 b(and)h(ADDs)e(share)j(the)f(same)f(unique)j(table,)448 +2874 y(whereas)24 b(ZDDs)d(ha)n(v)o(e)j(their)f(o)n(wn)f(table.)30 +b(As)22 b(the)h(name)f(implies,)i(the)f(main)g(purpose)h(of)f(the)448 +2987 y(unique)i(table)e(is)g(to)f(guarantee)k(that)d(each)g(node)h(is)e +(unique;)j(that)e(is,)g(there)g(is)g(no)g(other)g(node)448 +3100 y(labeled)h(by)e(the)h(same)f(v)n(ariable)i(and)e(with)g(the)g +(same)h(children.)30 b(This)22 b(uniqueness)j(property)448 +3213 y(mak)o(es)34 b(decision)i(diagrams)f(canonical.)61 +b(The)33 b(unique)i(tables)f(and)g(some)g(auxiliary)i(data)448 +3326 y(structures)e(mak)o(e)d(up)g(the)g(DdManager)h(\(manager)h(for)e +(short\).)52 b(Though)32 b(the)f(application)448 3439 +y(that)c(uses)h(only)f(the)g(e)o(xported)h(functions)h(needs)f(not)f +(be)f(concerned)j(with)e(most)f(details)i(of)448 3552 +y(the)20 b(manager)l(,)h(it)e(has)h(to)f(deal)h(with)f(the)h(manager)g +(in)g(the)f(follo)n(wing)i(sense.)28 b(The)19 b(application)448 +3665 y(must)28 b(initialize)h(the)f(manager)h(by)e(calling)i(an)e +(appropriate)k(function.)42 b(\(See)27 b(Section)h(3.3.\))448 +3778 y(Subsequently)-6 b(,)25 b(it)c(must)h(pass)g(a)f(pointer)j(to)d +(the)h(manager)h(to)e(all)h(the)f(functions)j(that)f(operate)448 +3890 y(on)h(decision)i(diagrams.)589 4003 y(W)l(ith)k(the)g(e)o +(xception)i(of)d(a)g(fe)n(w)g(statistical)j(counters,)h(there)d(are)g +(no)f(global)i(v)n(ariables)448 4116 y(in)f(the)g(CUDD)d(package.)50 +b(Therefore,)32 b(it)e(is)f(quite)i(possible)h(to)d(ha)n(v)o(e)i +(multiple)g(managers)448 4229 y(simultaneously)h(acti)n(v)o(e)d(in)f +(the)g(same)g(application.)2140 4196 y Fg(1)2223 4229 +y Fo(It)g(is)g(the)g(pointers)i(to)e(the)h(managers)448 +4342 y(that)24 b(tell)g(the)g(functions)i(on)e(what)f(data)h(the)o(y)g +(should)i(operate.)p Black 448 4423 1196 4 v 554 4479 +a Ff(1)583 4511 y Fe(The)18 b(global)h(statistical)e(counters)i(are)f +(used)h(locally;)g(hence)g(the)o(y)f(are)h(compatible)g(with)e(the)i +(use)f(of)g(multi-)448 4602 y(ple)h(managers.)p Black +Black 1920 5225 a Fo(7)p Black eop end +%%Page: 8 8 +TeXDict begin 8 7 bop Black Black 448 573 a Fp(3.2.3)92 +b(Cache)448 747 y Fo(Ef)n(\002cient)23 b(recursi)n(v)o(e)i +(manipulation)h(of)e(decision)h(diagrams)f(requires)i(the)d(use)h(of)f +(a)f(table)i(to)448 860 y(store)i(computed)g(results.)34 +b(This)24 b(table)i(is)e(called)i(here)g(the)e Fn(cac)o(he)i +Fo(because)g(it)f(is)f(ef)n(fecti)n(v)o(ely)448 973 y(handled)g(lik)o +(e)f(a)e(cache)i(of)f(v)n(ariable)i(b)n(ut)e(limited)h(capacity)-6 +b(.)30 b(The)22 b(CUDD)d(package)24 b(starts)f(by)448 +1086 y(def)o(ault)31 b(with)e(a)g(small)g(cache,)i(and)f(increases)h +(its)e(size)h(until)g(either)g(no)f(further)i(bene\002t)e(is)448 +1199 y(achie)n(v)o(ed,)c(or)f(a)f(limit)g(size)h(is)f(reached.)31 +b(The)23 b(user)h(can)g(in\003uence)h(this)f(polic)o(y)g(by)g(choosing) +448 1312 y(initial)h(and)f(limit)g(v)n(alues)g(for)g(the)g(cache)h +(size.)589 1425 y(T)-7 b(oo)22 b(small)g(a)f(cache)i(will)e(cause)i +(frequent)h(o)o(v)o(erwriting)f(of)f(useful)h(results.)30 +b(T)-7 b(oo)21 b(lar)n(ge)i(a)448 1537 y(cache)h(will)d(cause)j(o)o(v)o +(erhead,)g(because)g(the)e(whole)h(cache)g(is)f(scanned)i(e)n(v)o(ery)f +(time)f(garbage)448 1650 y(collection)27 b(tak)o(es)f(place.)32 +b(The)24 b(optimal)h(parameters)i(depend)f(on)e(the)h(speci\002c)g +(application.)448 1763 y(The)e(def)o(ault)j(parameters)f(w)o(ork)f +(reasonably)i(well)e(for)f(a)g(lar)n(ge)i(spectrum)g(of)f +(applications.)589 1876 y(The)32 b(cache)h(of)f(the)h(CUDD)d(package)k +(is)e(used)h(by)f(most)g(recursi)n(v)o(e)i(functions)h(of)d(the)448 +1989 y(package,)26 b(and)e(can)f(be)h(used)g(by)g(user)n(-supplied)k +(functions)e(as)d(well.)29 b(\(See)23 b(Section)h(4.4.\))448 +2236 y Fi(3.3)99 b(Initializing)24 b(and)i(Shutting)g(Do)o(wn)f(a)g +(DdManager)448 2411 y Fo(T)-7 b(o)27 b(use)g(the)h(functions)i(in)d +(the)h(CUDD)d(package,)30 b(one)e(has)g(\002rst)f(to)g(initialize)j +(the)d(package)448 2524 y(itself)e(by)e(calling)j Fn(Cudd)p +1238 2524 28 4 v 33 w(Init)r Fo(.)j(This)24 b(function)h(tak)o(es)g +(four)f(parameters:)p Black 585 2702 a Fm(\017)p Black +46 w Fo(numV)-10 b(ars:)28 b(It)21 b(is)h(the)f(initial)i(number)f(of)g +(v)n(ariables)h(for)f(BDDs)e(and)i(ADDs.)k(If)21 b(the)h(to-)676 +2815 y(tal)e(number)i(of)f(v)n(ariables)h(needed)h(by)d(the)h +(application)j(is)d(kno)n(wn,)g(then)g(it)g(is)f(slightly)676 +2928 y(more)h(ef)n(\002cient)h(to)f(create)i(a)e(manager)i(with)e(that) +h(number)g(of)f(v)n(ariables.)30 b(If)22 b(the)f(num-)676 +3041 y(ber)g(is)g(unkno)n(wn,)i(it)e(can)h(be)f(set)g(to)g(0,)h(or)f +(to)g(an)o(y)g(other)i(lo)n(wer)e(bound)h(on)g(the)f(number)676 +3154 y(of)28 b(v)n(ariables.)47 b(Requesting)31 b(more)e(v)n(ariables)i +(than)f(are)f(actually)i(needed)f(is)f(not)g(in-)676 +3267 y(correct,)24 b(b)n(ut)g(is)g(not)g(ef)n(\002cient.)p +Black 585 3450 a Fm(\017)p Black 46 w Fo(numV)-10 b(arsZ:)27 +b(It)h(is)f(the)h(initial)h(number)f(of)g(v)n(ariables)i(for)d(ZDDs.)40 +b(See)27 b(Sections)h(3.9)676 3563 y(and)c(3.11)f(for)h(a)f(discussion) +k(of)c(the)h(v)n(alue)g(of)g(this)g(ar)n(gument.)p Black +585 3747 a Fm(\017)p Black 46 w Fo(numSlots:)42 b(Determines)31 +b(the)f(initial)h(size)f(of)g(each)h(subtable)h(of)d(the)h(unique)i +(table.)676 3860 y(There)c(is)g(a)f(subtable)j(for)f(each)f(v)n +(ariable.)44 b(The)28 b(size)g(of)g(each)h(subtable)h(is)e(dynami-)676 +3973 y(cally)e(adjusted)i(to)e(re\003ect)g(the)g(number)h(of)f(nodes.) +37 b(It)25 b(is)h(normally)h(O.K.)d(to)i(use)g(the)676 +4086 y(def)o(ault)f(v)n(alue)f(for)g(this)g(parameter)l(,)h(which)f(is) +g(CUDD)p 2448 4086 V 31 w(UNIQ)o(UE)p 2828 4086 V 31 +w(SLO)l(TS.)p Black 585 4270 a Fm(\017)p Black 46 w Fo(cacheSize:)39 +b(It)28 b(is)g(the)g(initial)h(size)g(\(number)g(of)f(entries\))h(of)f +(the)h(cache.)43 b(Its)28 b(def)o(ault)676 4383 y(v)n(alue)c(is)f(CUDD) +p 1240 4383 V 32 w(CA)l(CHE)p 1578 4383 V 31 w(SLO)l(TS.)p +Black 585 4567 a Fm(\017)p Black 46 w Fo(maxMemory:)29 +b(It)23 b(is)g(the)h(tar)n(get)g(v)n(alue)g(for)f(the)h(maximum)f +(memory)g(occupation)j(\(in)676 4680 y(bytes\).)k(The)23 +b(package)i(uses)g(this)f(v)n(alue)g(to)f(decide)i(tw)o(o)f +(parameters.)p Black 785 4863 a Fp(\226)p Black 46 w +Fo(the)29 b(maximum)f(size)i(to)e(which)i(the)f(cache)h(will)e(gro)n(w) +-6 b(,)30 b(re)o(gardless)g(of)f(the)g(hit)876 4976 y(rate)24 +b(or)f(the)h(size)g(of)f(the)h(unique)h(table.)p Black +1920 5225 a(8)p Black eop end +%%Page: 9 9 +TeXDict begin 9 8 bop Black Black Black 785 573 a Fp(\226)p +Black 46 w Fo(the)19 b(maximum)g(size)h(to)f(which)h(gro)n(wth)f(of)g +(the)h(unique)h(table)f(will)f(be)g(preferred)876 686 +y(to)k(garbage)i(collection.)676 873 y(If)j(maxMemory)h(is)g(set)g(to)f +(0,)h(CUDD)e(tries)i(to)g(guess)g(a)f(good)i(v)n(alue)g(based)f(on)g +(the)676 986 y(a)n(v)n(ailable)c(memory)-6 b(.)448 1174 +y(A)23 b(typical)i(call)f(to)f Fn(Cudd)p 1255 1174 28 +4 v 34 w(Init)j Fo(may)d(look)h(lik)o(e)g(this:)p Black +Black 557 1362 a Fh(manager)52 b(=)i(Cudd_Init\(0,0,)o(CUD)o(D_)o(UN)o +(IQ)o(UE)o(_SL)o(OT)o(S,)o(CU)o(DD)o(_CA)o(CH)o(E_)o(SL)o(OT)o(S,0)o +(\);)448 1549 y Fo(T)-7 b(o)34 b(reclaim)i(all)f(the)g(memory)g +(associated)j(with)d(a)f(manager)l(,)39 b(an)c(application)j(must)d +(call)448 1662 y Fn(Cudd)p 649 1662 V 34 w(Quit)r Fo(.)28 +b(This)c(is)f(normally)i(done)f(before)h(e)o(xiting.)448 +1911 y Fi(3.4)99 b(Setting)26 b(P)o(arameters)448 2086 +y Fo(The)i(package)j(pro)o(vides)f(se)n(v)o(eral)g(functions)h(to)d +(set)h(the)g(parameters)h(that)f(control)i(v)n(arious)448 +2198 y(functions.)g(F)o(or)22 b(instance,)j(the)e(package)i(has)f(an)f +(automatic)h(w)o(ay)f(of)g(determining)i(whether)448 +2311 y(a)f(lar)n(ger)i(unique)f(table)g(w)o(ould)g(mak)o(e)f(the)g +(application)k(run)c(f)o(aster)-5 b(.)32 b(In)24 b(that)g(case,)h(the)f +(pack-)448 2424 y(age)19 b(enters)h(a)e(\223f)o(ast)i(gro)n(wth\224)f +(mode)g(in)g(which)g(resizing)i(of)d(the)h(unique)h(subtables)i(is)c(f) +o(a)n(v)n(ored)448 2537 y(o)o(v)o(er)25 b(garbage)h(collection.)36 +b(When)25 b(the)g(unique)h(table)g(reaches)g(a)f(gi)n(v)o(en)g(size,)h +(ho)n(we)n(v)o(er)l(,)f(the)448 2650 y(package)d(returns)e(to)g(the)f +(normal)h(\223slo)n(w)f(gro)n(wth\224)i(mode,)f(e)n(v)o(en)f(though)i +(the)e(conditions)k(that)448 2763 y(caused)k(the)f(transition)i(to)d(f) +o(ast)h(gro)n(wth)f(still)h(pre)n(v)n(ail.)35 b(The)25 +b(limit)g(size)h(for)f(f)o(ast)h(gro)n(wth)g(can)448 +2876 y(be)k(read)h(by)f Fn(Cudd)p 1070 2876 V 33 w(ReadLooseUpT)-8 +b(o)31 b Fo(and)g(changed)h(by)e Fn(Cudd)p 2544 2876 +V 33 w(SetLooseUpT)-8 b(o)p Fo(.)49 b(Similar)448 2989 +y(pairs)25 b(of)e(functions)j(e)o(xist)e(for)g(se)n(v)o(eral)h(other)f +(parameters.)31 b(See)23 b(also)h(Section)h(4.8.)448 +3238 y Fi(3.5)99 b(Constant)26 b(Functions)448 3412 y +Fo(The)18 b(CUDD)e(P)o(ackage)j(de\002nes)g(se)n(v)o(eral)h(constant)g +(functions.)30 b(These)18 b(functions)j(are)e(created)448 +3525 y(when)24 b(the)g(manager)g(is)g(initialized,)i(and)e(are)g +(accessible)i(through)f(the)f(manager)h(itself.)448 3771 +y Fp(3.5.1)92 b(One,)22 b(Logic)i(Zer)n(o,)g(and)e(Arithmetic)i(Zer)n +(o)448 3945 y Fo(The)36 b(constant)i(1)d(\(returned)j(by)e +Fn(Cudd)p 1738 3945 V 34 w(ReadOne)p Fo(\))g(is)g(common)g(to)g(BDDs,)h +(ADDs,)g(and)448 4058 y(ZDDs.)42 b(Ho)n(we)n(v)o(er)l(,)29 +b(its)f(meaning)i(is)e(dif)n(ferent)i(for)f(ADDs)d(and)j(BDDs,)f(on)g +(the)h(one)g(hand,)448 4171 y(and)c(ZDDs,)f(on)g(the)h(other)h(hand.)33 +b(The)25 b(diagram)g(consisting)j(of)d(the)g(constant)h(1)f(node)g +(only)448 4284 y(represents)33 b(the)d(constant)i(1)e(function)i(for)e +(ADDs)f(and)h(BDDs.)46 b(F)o(or)29 b(ZDDs,)h(its)g(meaning)448 +4397 y(depends)i(on)d(the)g(number)i(of)e(v)n(ariables:)42 +b(It)29 b(is)g(the)h(conjunction)j(of)c(the)g(complements)i(of)448 +4510 y(all)j(v)n(ariables.)63 b(Con)l(v)o(ersely)-6 b(,)38 +b(the)d(representation)j(of)c(the)g(constant)i(1)e(function)i(depends) +448 4623 y(on)28 b(the)f(number)h(of)f(v)n(ariables.)42 +b(The)26 b(constant)k(1)c(function)k(of)d Fk(n)f Fo(v)n(ariables)j(is)e +(returned)i(by)448 4736 y Fn(Cudd)p 649 4736 V 34 w(ReadZddOne)p +Fo(.)p Black 1920 5225 a(9)p Black eop end +%%Page: 10 10 +TeXDict begin 10 9 bop Black Black 589 573 a Fo(The)29 +b(constant)j(0)c(is)h(common)h(to)f(ADDs)f(and)h(ZDDs,)g(b)n(ut)h(not)f +(to)g(BDDs.)44 b(The)29 b(BDD)448 686 y(logic)21 b(0)f(is)g +Fp(not)g Fo(associated)i(with)e(the)h(constant)h(0)e(function:)29 +b(It)20 b(is)g(obtained)i(by)f(complemen-)448 799 y(tation)26 +b(\()p Fn(Cudd)p 910 799 28 4 v 34 w(Not)r Fo(\))e(of)h(the)g(constant) +i(1.)32 b(\(It)24 b(is)h(also)g(returned)i(by)e Fn(Cudd)p +2795 799 V 33 w(ReadLo)o(gicZer)l(o)p Fo(.\))448 912 +y(All)e(other)i(constants)h(are)e(speci\002c)g(to)f(ADDs.)448 +1157 y Fp(3.5.2)92 b(Pr)n(ede\002ned)22 b(Constants)448 +1332 y Fo(Besides)34 b(0)e(\(returned)j(by)d Fn(Cudd)p +1528 1332 V 34 w(ReadZer)l(o)p Fo(\))h(and)g(1,)h(the)f(follo)n(wing)h +(constant)h(functions)448 1445 y(are)24 b(created)h(at)f +(initialization)j(time.)p Black 562 1632 a(1.)p Black +46 w(PlusIn\002nity)f(and)g(MinusIn\002nity:)34 b(On)25 +b(computers)i(implementing)g(the)e(IEEE)e(stan-)676 1745 +y(dard)39 b(754)g(for)f(\003oating-point)k(arithmetic,)h(these)d(tw)o +(o)e(constants)j(are)d(set)h(to)f(the)676 1858 y(signed)19 +b(in\002nities.)29 b(On)17 b(the)h(DEC)e(Alphas,)k(the)e(option)i +Fh(-ieee_with_no_i)o(ne)o(xa)o(ct)676 1971 y Fo(or)33 +b Fh(-ieee_with_inexa)o(ct)26 b Fo(must)34 b(be)g(passed)h(to)f(the)g +(DEC)e(compiler)j(to)f(get)676 2084 y(support)26 b(of)e(the)h(IEEE)d +(standard.)34 b(\(The)24 b(compiler)i(still)f(produces)h(a)e(w)o +(arning,)i(b)n(ut)f(it)676 2197 y(can)30 b(be)h(ignored.\))52 +b(Compiling)32 b(with)e(those)i(options)g(may)e(cause)i(substantial)i +(per)n(-)676 2310 y(formance)39 b(de)o(gradation)j(on)c(the)g(Ev)n +(olution)j(IV)c(CPUs.)71 b(\(Especially)41 b(if)d(the)g(ap-)676 +2423 y(plication)d(does)f(use)f(the)g(in\002nities.\))58 +b(The)33 b(problem)h(is)e(reportedly)k(solv)o(ed)e(in)f(the)676 +2536 y(Ev)n(olution)h(V)d(CPUs.)55 b(If)32 b Fh(gcc)e +Fo(is)j(used)g(to)f(compile)i(CUDD)c(on)j(the)g(Alphas,)i(the)676 +2648 y(symbol)26 b Fh(HAVE)p 1193 2648 V 31 w(IEEE)p +1444 2648 V 31 w(754)d Fo(must)j(be)f(unde\002ned.)37 +b(\(See)25 b(the)h(Mak)o(e\002le)g(for)f(the)h(de-)676 +2761 y(tails.\))39 b(The)26 b(v)n(alues)i(of)e(these)i(constants)h(are) +e(returned)i(by)d Fn(Cudd)p 2802 2761 V 34 w(ReadPlusIn\002nity)676 +2874 y Fo(and)e Fn(Cudd)p 1031 2874 V 33 w(ReadMinusIn\002nity)p +Fo(.)p Black 562 3062 a(2.)p Black 46 w(Epsilon:)38 b(This)28 +b(constant,)j(initially)f(set)e(to)f Fl(10)2183 3029 +y Fd(\000)p Fc(12)2314 3062 y Fo(,)h(is)f(used)i(in)f(comparing)h +(\003oating)676 3175 y(point)e(v)n(alues)g(for)f(equality)-6 +b(.)39 b(Its)26 b(v)n(alue)h(is)f(returned)j(by)d Fn(Cudd)p +2688 3175 V 34 w(ReadEpsilon)p Fo(,)i(and)f(it)676 3288 +y(can)h(be)g(modi\002ed)h(by)g(calling)g Fn(Cudd)p 1887 +3288 V 34 w(SetEpsilon)p Fo(.)45 b(Unlik)o(e)29 b(the)g(other)g +(constants,)j(it)676 3401 y(does)24 b(not)g(correspond)i(to)e(a)f +(node.)448 3646 y Fp(3.5.3)92 b(Backgr)n(ound)448 3821 +y Fo(The)22 b(background)k(v)n(alue)e(is)e(a)g(constant)j(typically)g +(used)e(to)g(represent)h(non-e)o(xisting)i(arcs)d(in)448 +3934 y(graphs.)31 b(Consider)26 b(a)d(shortest)j(path)e(problem.)31 +b(T)-7 b(w)o(o)22 b(nodes)j(that)g(are)f(not)g(connected)i(by)e(an)448 +4047 y(arc)31 b(can)f(be)g(re)o(garded)i(as)e(being)h(joined)h(by)e(an) +g(arc)g(of)g(in\002nite)h(length.)50 b(In)30 b(shortest)j(path)448 +4159 y(problems,)27 b(it)d(is)g(therefore)j(con)l(v)o(enient)h(to)d +(set)g(the)g(background)j(v)n(alue)d(to)g(PlusIn\002nity.)33 +b(In)448 4272 y(netw)o(ork)26 b(\003o)n(w)e(problems,)i(on)f(the)g +(other)h(hand,)g(tw)o(o)e(nodes)i(not)g(connected)h(by)e(an)g(arc)g +(can)448 4385 y(be)j(re)o(garded)h(as)f(joined)h(by)f(an)g(arc)g(of)f +(0)h(capacity)-6 b(.)43 b(F)o(or)27 b(these)i(problems,)h(therefore,)h +(it)c(is)448 4498 y(more)i(con)l(v)o(enient)j(to)c(set)h(the)g +(background)j(v)n(alue)d(to)g(0.)43 b(In)29 b(general,)i(when)e +(representing)448 4611 y(sparse)c(matrices,)g(the)e(background)k(v)n +(alue)e(is)e(the)h(v)n(alue)g(that)g(is)g(assumed)h(implicitly)-6 +b(.)589 4724 y(At)18 b(initialization,)k(the)d(background)i(v)n(alue)e +(is)f(set)g(to)g(0.)27 b(It)18 b(can)g(be)g(read)h(with)f +Fn(Cudd)p 3237 4724 V 34 w(ReadBac)n(kgr)l(ound)r Fo(,)448 +4837 y(and)k(modi\002ed)f(with)f Fn(Cudd)p 1325 4837 +V 34 w(SetBac)n(kgr)l(ound)p Fo(.)31 b(The)21 b(background)j(v)n(alue)d +(af)n(fects)h(procedures)p Black 1897 5225 a(10)p Black +eop end +%%Page: 11 11 +TeXDict begin 11 10 bop Black Black 448 573 a Fo(that)34 +b(read)f(sparse)i(matrices/graphs)h(\()p Fn(Cudd)p 1903 +573 28 4 v 34 w(addRead)h Fo(and)c Fn(Cudd)p 2654 573 +V 34 w(addHarwell)p Fo(\),)k(proce-)448 686 y(dures)31 +b(that)f(print)g(out)f(sum-of-product)34 b(e)o(xpressions)e(for)d(ADDs) +f(\()p Fn(Cudd)p 2855 686 V 34 w(PrintMinterm)p Fo(\),)448 +799 y(generators)43 b(of)d(cubes)h(\()p Fn(Cudd)p 1458 +799 V 34 w(F)-10 b(or)m(eac)o(hCube)p Fo(\),)46 b(and)40 +b(procedures)j(that)e(count)g(minterms)448 912 y(\()p +Fn(Cudd)p 679 912 V 34 w(CountMinterm)p Fo(\).)448 1157 +y Fp(3.5.4)92 b(New)22 b(Constants)448 1332 y Fo(Ne)n(w)d(constant)j +(can)f(be)f(created)i(by)e(calling)i Fn(Cudd)p 2070 1332 +V 34 w(addConst)r Fo(.)29 b(This)20 b(function)i(will)e(retrie)n(v)o(e) +448 1445 y(the)31 b(ADD)e(for)i(the)g(desired)h(constant,)i(if)d(it)f +(already)i(e)o(xist,)h(or)e(it)f(will)g(create)i(a)e(ne)n(w)g(one.)448 +1558 y(Ob)o(viously)-6 b(,)25 b(ne)n(w)e(constants)j(should)f(only)g +(be)e(used)i(when)e(manipulating)k(ADDs.)448 1807 y Fi(3.6)99 +b(Cr)n(eating)26 b(V)-9 b(ariables)448 1981 y Fo(Decision)28 +b(diagrams)g(are)e(typically)j(created)f(by)e(combining)i(simpler)g +(decision)g(diagrams.)448 2094 y(The)22 b(simplest)h(decision)h +(diagrams,)g(of)e(course,)h(cannot)h(be)e(created)h(in)f(that)h(w)o(ay) +-6 b(.)28 b(Constant)448 2207 y(functions)e(ha)n(v)o(e)e(been)g +(discussed)h(in)e(Section)h(3.5.)29 b(In)23 b(this)g(section)i(we)d +(discuss)j(the)f(simple)448 2320 y(v)n(ariable)i(functions,)f(also)g +(kno)n(wn)e(as)h Fn(pr)l(ojection)i(functions)p Fo(.)448 +2566 y Fp(3.6.1)92 b(New)22 b(BDD)g(and)g(ADD)g(V)-8 +b(ariables)448 2740 y Fo(The)27 b(projection)j(functions)g(are)e +(distinct)h(for)f(BDDs)d(and)j(ADDs.)39 b(A)26 b(projection)k(function) +448 2853 y(for)24 b(BDDs)d(consists)k(of)e(an)h(internal)h(node)f(with) +f(both)h(outgoing)h(arcs)f(pointing)h(to)e(the)h(con-)448 +2966 y(stant)h(1.)j(The)23 b Fn(else)h Fo(arc)g(is)f(complemented.)589 +3079 y(An)e(ADD)e(projection)k(function,)h(on)d(the)g(other)h(hand,)g +(has)f(the)g Fn(else)h Fo(pointer)g(directed)h(to)448 +3192 y(the)35 b(arithmetic)h(zero)f(function.)64 b(One)34 +b(should)i(ne)n(v)o(er)f(mix)f(the)h(tw)o(o)f(types)h(of)f(v)n +(ariables.)448 3304 y(BDD)k(v)n(ariables)k(should)g(be)e(used)h(when)f +(manipulating)j(BDDs,)f(and)e(ADD)e(v)n(ariables)448 +3417 y(should)c(be)e(used)h(when)f(manipulating)j(ADDs.)53 +b(Three)33 b(functions)h(are)f(pro)o(vided)h(to)e(cre-)448 +3530 y(ate)24 b(BDD)e(v)n(ariables:)p Black 585 3718 +a Fm(\017)p Black 46 w Fn(Cudd)p 877 3718 V 33 w(bddIthV)-10 +b(ar)r Fo(:)40 b(Returns)29 b(the)f(projection)j(function)f(with)e +(inde)o(x)h Fk(i)p Fo(.)41 b(If)28 b(the)g(func-)676 +3831 y(tion)c(does)g(not)g(e)o(xist,)g(it)f(is)g(created.)p +Black 585 4018 a Fm(\017)p Black 46 w Fn(Cudd)p 877 4018 +V 33 w(bddNe)o(wV)-10 b(ar)r Fo(:)49 b(Returns)35 b(a)d(ne)n(w)h +(projection)j(function,)i(whose)c(inde)o(x)g(is)f(the)676 +4131 y(lar)n(gest)25 b(inde)o(x)f(in)g(use)g(at)f(the)h(time)f(of)h +(the)g(call,)f(plus)i(1.)p Black 585 4319 a Fm(\017)p +Black 46 w Fn(Cudd)p 877 4319 V 33 w(bddNe)o(wV)-10 b(arAtLe)o(vel)p +Fo(:)50 b(Similar)34 b(to)f Fn(Cudd)p 2283 4319 V 34 +w(bddNe)o(wV)-10 b(ar)r Fo(.)59 b(In)34 b(addition)i(it)d(al-)676 +4432 y(lo)n(ws)27 b(to)h(specify)i(the)e(position)i(in)e(the)g(v)n +(ariable)h(order)g(at)f(which)g(the)g(ne)n(w)g(v)n(ariable)676 +4545 y(should)i(be)f(inserted.)47 b(In)29 b(contrast,)j +Fn(Cudd)p 2060 4545 V 33 w(bddNe)o(wV)-10 b(ar)32 b Fo(adds)d(the)h(ne) +n(w)e(v)n(ariable)i(at)676 4658 y(the)23 b(end)h(of)g(the)g(order)-5 +b(.)448 4845 y(The)33 b(analogous)j(functions)g(for)d(ADDs)f(are)i +Fn(Cudd)p 2142 4845 V 33 w(addIthV)-10 b(ar)r Fo(,)38 +b Fn(Cudd)p 2795 4845 V 33 w(addNe)o(wV)-10 b(ar)r Fo(,)36 +b(and)448 4958 y Fn(Cudd)p 649 4958 V 34 w(addNe)o(wV)-10 +b(arAtLe)o(vel)p Fo(.)p Black 1897 5225 a(11)p Black +eop end +%%Page: 12 12 +TeXDict begin 12 11 bop Black Black 448 573 a Fp(3.6.2)92 +b(New)22 b(ZDD)g(V)-8 b(ariables)448 747 y Fo(Unlik)o(e)33 +b(the)f(projection)i(functions)g(of)e(BDDs)e(and)i(ADDs,)g(the)g +(projection)i(functions)g(of)448 860 y(ZDDs)20 b(ha)n(v)o(e)j(diagrams) +g(with)e Fk(n)13 b Fl(+)g(1)22 b Fo(nodes,)h(where)f +Fk(n)e Fo(is)i(the)f(number)i(of)f(v)n(ariables.)30 b(There-)448 +973 y(fore)g(the)f(ZDDs)e(of)h(the)h(projection)j(functions)f(change)g +(when)d(ne)n(w)h(v)n(ariables)h(are)f(added.)448 1086 +y(This)21 b(will)g(be)h(discussed)i(in)d(Section)h(3.9.)28 +b(Here)21 b(we)g(assume)h(that)g(the)g(number)g(of)f(v)n(ariables)448 +1199 y(is)j(\002x)o(ed.)k(The)23 b(ZDD)f(of)h(the)h Fk(i)p +Fo(-th)g(projection)i(function)g(is)d(returned)j(by)e +Fn(Cudd)p 2965 1199 28 4 v 33 w(zddIthV)-10 b(ar)r Fo(.)448 +1448 y Fi(3.7)99 b(Basic)25 b(BDD)h(Manipulation)448 +1622 y Fo(Common)34 b(manipulations)j(of)d(BDDs)e(can)i(be)g +(accomplished)j(by)d(calling)h Fn(Cudd)p 3153 1622 V +34 w(bddIte)p Fo(.)448 1735 y(This)19 b(function)i(tak)o(es)e(three)h +(BDDs,)d Fk(f)10 b Fo(,)18 b Fk(g)s Fo(,)h(and)g Fk(h)p +Fo(,)g(as)g(ar)n(guments)i(and)e(computes)h Fk(f)12 b +Fm(\001)r Fk(g)5 b Fl(+)r Fk(f)3311 1702 y Fd(0)3335 +1735 y Fm(\001)r Fk(h)p Fo(.)448 1848 y(Lik)o(e)29 b(all)g(the)g +(functions)j(that)d(create)h(ne)n(w)f(BDDs)e(or)i(ADDs,)f +Fn(Cudd)p 2698 1848 V 34 w(bddIte)i Fo(returns)h(a)d(re-)448 +1961 y(sult)j(that)g(must)f(be)g(e)o(xplicitly)i(referenced)h(by)d(the) +h(caller)-5 b(.)49 b Fn(Cudd)p 2609 1961 V 34 w(bddIte)32 +b Fo(can)e(be)g(used)h(to)448 2074 y(implement)i(all)e(tw)o(o-ar)n +(gument)k(boolean)e(functions.)55 b(Ho)n(we)n(v)o(er)l(,)33 +b(the)f(package)i(also)e(pro-)448 2187 y(vides)24 b Fn(Cudd)p +863 2187 V 33 w(bddAnd)i Fo(as)c(well)g(as)g(the)h(other)g(tw)o +(o-operand)i(boolean)f(functions,)h(which)d(are)448 2300 +y(slightly)32 b(more)f(ef)n(\002cient)f(when)h(a)e(tw)o(o-operand)k +(function)f(is)e(called)i(for)-5 b(.)48 b(The)30 b(follo)n(wing)448 +2413 y(fragment)24 b(of)f(code)h(illustrates)h(ho)n(w)d(to)h(b)n(uild)h +(the)f(BDD)e(for)h(the)h(function)i Fk(f)35 b Fl(=)25 +b Fk(x)3101 2380 y Fd(0)3101 2436 y Fc(0)3140 2413 y +Fk(x)3192 2380 y Fd(0)3192 2436 y Fc(1)3232 2413 y Fk(x)3284 +2380 y Fd(0)3284 2436 y Fc(2)3323 2413 y Fk(x)3375 2380 +y Fd(0)3375 2436 y Fc(3)3414 2413 y Fo(.)p Black Black +448 2600 a Fh(DdManager)51 b(*manager;)448 2713 y(DdNode)h(*f,)h(*var,) +g(*tmp;)448 2826 y(int)h(i;)448 3052 y(...)448 3278 y(f)g(=)h +(Cudd_ReadOne\(m)o(an)o(ag)o(er)o(\);)448 3391 y(Cudd_Ref\(f\);)448 +3504 y(for)f(\(i)f(=)h(3;)g(i)g(>=)g(0;)f(i--\))g({)667 +3616 y(var)g(=)h(Cudd_bddIthVar)o(\(m)o(ana)o(ge)o(r,)o(i\))o(;)667 +3729 y(tmp)f(=)h(Cudd_bddAnd\(ma)o(na)o(ger)o(,C)o(ud)o(d_)o(No)o(t\(v) +o(ar)o(\),)o(f\))o(;)667 3842 y(Cudd_Ref\(tmp\);)667 +3955 y(Cudd_Recursive)o(De)o(re)o(f\()o(ma)o(nag)o(er)o(,f)o(\);)667 +4068 y(f)g(=)g(tmp;)448 4181 y(})448 4369 y Fo(This)24 +b(e)o(xample)g(illustrates)i(the)e(follo)n(wing)h(points:)p +Black 585 4556 a Fm(\017)p Black 46 w Fo(Intermediate)40 +b(results)g(must)d(be)h(\223referenced\224)k(and)c(\223dereferenced.)-6 +b(\224)76 b(Ho)n(we)n(v)o(er)l(,)676 4669 y Fh(var)25 +b Fo(is)j(a)f(projection)k(function,)g(and)d(its)g(reference)i(count)f +(is)f(al)o(w)o(ays)g(greater)i(than)676 4782 y(0.)e(Therefore,)d(there) +f(is)g(no)f(call)h(to)g Fn(Cudd)p 2026 4782 V 33 w(Ref)13 +b Fo(.)p Black 1897 5225 a(12)p Black eop end +%%Page: 13 13 +TeXDict begin 13 12 bop Black Black Black 585 573 a Fm(\017)p +Black 46 w Fo(The)24 b(ne)n(w)g Fh(f)f Fo(must)i(be)f(assigned)j(to)e +(a)f(temporary)j(v)n(ariable)f(\()p Fh(tmp)d Fo(in)h(this)h(e)o +(xample\).)676 686 y(If)c(the)g(result)i(of)e Fn(Cudd)p +1408 686 28 4 v 34 w(bddAnd)k Fo(were)c(assigned)i(directly)h(to)d +Fh(f)p Fo(,)f(the)i(old)f Fh(f)f Fo(w)o(ould)i(be)676 +799 y(lost,)h(and)h(there)h(w)o(ould)f(be)f(no)h(w)o(ay)f(to)h(free)g +(its)f(nodes.)p Black 585 983 a Fm(\017)p Black 46 w +Fo(The)g(statement)i Fh(f)54 b(=)g(tmp)21 b Fo(has)j(the)g(same)g(ef)n +(fect)g(as:)p Black Black 894 1197 a Fh(f)54 b(=)g(tmp;)894 +1310 y(Cudd_Ref\(f\);)894 1423 y(Cudd_Recursive)o(De)o(ref)o(\(m)o(an)o +(ag)o(er)o(,tm)o(p\))o(;)676 1637 y Fo(b)n(ut)27 b(is)f(more)h(ef)n +(\002cient.)39 b(The)26 b(reference)j(is)d(\223passed\224)j(from)e +Fh(tmp)d Fo(to)j Fh(f)p Fo(,)f(and)h Fh(tmp)d Fo(is)676 +1750 y(no)n(w)f(ready)h(to)g(be)f(reutilized.)p Black +585 1934 a Fm(\017)p Black 46 w Fo(It)31 b(is)g(normally)h(more)g(ef)n +(\002cient)g(to)f(b)n(uild)h(BDDs)e(\223bottom-up.)-6 +b(\224)54 b(This)31 b(is)g(why)g(the)676 2047 y(loop)22 +b(goes)g(from)f(3)g(to)g(0.)28 b(Notice,)22 b(ho)n(we)n(v)o(er)l(,)g +(that)g(after)g(v)n(ariable)h(reordering,)h(higher)676 +2160 y(inde)o(x)30 b(does)h(not)f(necessarily)i(mean)e(\223closer)h(to) +f(the)g(bottom.)-6 b(\224)48 b(Of)29 b(course,)j(in)e(this)676 +2273 y(simple)24 b(e)o(xample,)g(ef)n(\002cienc)o(y)g(is)g(not)g(a)f +(concern.)p Black 585 2457 a Fm(\017)p Black 46 w Fo(Had)31 +b(we)g(w)o(anted)h(to)g(conjoin)i(the)e(v)n(ariables)h(in)f(a)f +(bottom-up)j(f)o(ashion)g(e)n(v)o(en)e(after)676 2569 +y(reordering,)26 b(we)c(should)j(ha)n(v)o(e)f(used)g +Fn(Cudd)p 2074 2569 V 34 w(ReadIn)l(vP)-7 b(erm)p Fo(.)30 +b(One)23 b(has)g(to)h(be)f(careful,)676 2682 y(though,)28 +b(to)e(\002x)f(the)i(order)g(of)f(conjunction)j(before)f(entering)g +(the)e(loop.)38 b(Otherwise,)676 2795 y(if)33 b(reordering)j(tak)o(es)e +(place,)i(it)d(is)h(possible)h(to)e(use)h(one)f(v)n(ariable)i(twice)f +(and)g(skip)676 2908 y(another)25 b(v)n(ariable.)448 +3156 y Fi(3.8)99 b(Basic)25 b(ADD)g(Manipulation)448 +3330 y Fo(The)f(most)f(common)h(w)o(ay)g(to)f(manipulate)j(ADDs)c(is)i +(via)g Fn(Cudd)p 2521 3330 V 34 w(addApply)p Fo(.)31 +b(This)23 b(function)448 3443 y(can)35 b(apply)g(a)e(wide)h(v)n(ariety) +h(of)f(operators)i(to)e(a)f(pair)h(of)g(ADDs.)58 b(Among)34 +b(the)g(a)n(v)n(ailable)448 3556 y(operators)27 b(are)d(addition,)i +(multiplication,)h(di)n(vision,)f(minimum,)d(maximum,)h(and)g(boolean) +448 3669 y(operators)i(that)e(w)o(ork)g(on)g(ADDs)e(whose)i(lea)n(v)o +(es)g(are)g(restricted)i(to)e(0)f(and)h(1)f(\(0-1)h(ADDs\).)589 +3782 y(The)g(follo)n(wing)h(fragment)g(of)f(code)h(illustrates)h(ho)n +(w)d(to)h(b)n(uild)h(the)f(ADD)e(for)i(the)g(func-)448 +3894 y(tion)g Fk(f)35 b Fl(=)25 b(5)p Fk(x)885 3908 y +Fc(0)925 3894 y Fk(x)977 3908 y Fc(1)1016 3894 y Fk(x)1068 +3908 y Fc(2)1108 3894 y Fk(x)1160 3908 y Fc(3)1199 3894 +y Fo(.)p Black Black 448 4073 a Fh(DdManager)51 b(*manager;)448 +4186 y(DdNode)h(*f,)h(*var,)g(*tmp;)448 4299 y(int)h(i;)448 +4525 y(...)448 4751 y(f)g(=)h(Cudd_addConst\()o(ma)o(na)o(ge)o(r,)o +(5\);)448 4863 y(Cudd_Ref\(f\);)448 4976 y(for)f(\(i)f(=)h(3;)g(i)g(>=) +g(0;)f(i--\))g({)p Black 1897 5225 a Fo(13)p Black eop +end +%%Page: 14 14 +TeXDict begin 14 13 bop Black Black 667 573 a Fh(var)53 +b(=)h(Cudd_addIthVar)o(\(m)o(ana)o(ge)o(r,)o(i\))o(;)667 +686 y(Cudd_Ref\(var\);)667 799 y(tmp)f(=)h(Cudd_addApply\()o(ma)o(nag)o +(er)o(,C)o(ud)o(d_)o(add)o(Ti)o(me)o(s,)o(va)o(r,f)o(\);)667 +912 y(Cudd_Ref\(tmp\);)667 1024 y(Cudd_Recursive)o(De)o(re)o(f\()o(ma)o +(nag)o(er)o(,f)o(\);)667 1137 y(Cudd_Recursive)o(De)o(re)o(f\()o(ma)o +(nag)o(er)o(,v)o(ar)o(\);)667 1250 y(f)g(=)g(tmp;)448 +1363 y(})448 1538 y Fo(This)25 b(e)o(xample,)i(contrasted)h(to)d(the)g +(e)o(xample)h(of)g(BDD)d(manipulation,)28 b(illustrates)g(the)e(fol-) +448 1651 y(lo)n(wing)e(points:)p Black 585 1826 a Fm(\017)p +Black 46 w Fo(The)d(ADD)f(projection)25 b(function)f(are)e(not)g +(maintained)i(by)e(the)g(manager)-5 b(.)30 b(It)21 b(is)h(there-)676 +1939 y(fore)i(necessary)i(to)d(reference)j(and)e(dereference)j(them.)p +Black 585 2122 a Fm(\017)p Black 46 w Fo(The)17 b(product)j(of)e(tw)o +(o)g(ADDs)e(is)i(computed)i(by)e(calling)i Fn(Cudd)p +2652 2122 28 4 v 34 w(addApply)g Fo(with)d Fn(Cudd)p +3426 2122 V 34 w(addT)-5 b(imes)676 2235 y Fo(as)19 b(parameter)-5 +b(.)29 b(There)20 b(is)f(no)h(\223apply\224)i(function)f(for)f(BDDs,)f +(because)i Fn(Cudd)p 3123 2235 V 34 w(bddAnd)676 2348 +y Fo(and)g Fn(Cudd)p 1028 2348 V 34 w(bddXor)i Fo(plus)f +(complementation)i(are)d(suf)n(\002cient)h(to)f(implement)h(all)e(tw)o +(o-)676 2461 y(ar)n(gument)25 b(boolean)h(functions.)448 +2707 y Fi(3.9)99 b(Basic)25 b(ZDD)h(Manipulation)448 +2882 y Fo(ZDDs)21 b(are)i(often)h(generated)h(by)e(con)l(v)o(erting)j +(e)o(xisting)e(BDDs.)j(\(See)c(Section)g(3.11.\))29 b(Ho)n(w-)448 +2995 y(e)n(v)o(er)l(,)20 b(it)e(is)g(also)h(possible)h(to)e(b)n(uild)i +(ZDDs)d(by)h(applying)j(boolean)f(operators)h(to)d(other)h(ZDDs,)448 +3108 y(starting)29 b(from)e(constants)i(and)e(projection)j(functions.) +41 b(The)26 b(follo)n(wing)j(fragment)f(of)e(code)448 +3220 y(illustrates)34 b(ho)n(w)d(to)h(b)n(uild)g(the)g(ZDD)d(for)j(the) +g(function)h Fk(f)49 b Fl(=)40 b Fk(x)2562 3187 y Fd(0)2562 +3244 y Fc(0)2627 3220 y Fl(+)26 b Fk(x)2776 3187 y Fd(0)2776 +3244 y Fc(1)2841 3220 y Fl(+)g Fk(x)2990 3187 y Fd(0)2990 +3244 y Fc(2)3056 3220 y Fl(+)f Fk(x)3204 3187 y Fd(0)3204 +3244 y Fc(3)3244 3220 y Fo(.)51 b(W)-7 b(e)448 3333 y(assume)25 +b(that)g(the)f(four)h(v)n(ariables)h(already)f(e)o(xist)g(in)f(the)g +(manager)h(when)g(the)f(ZDD)e(for)i Fk(f)32 b Fo(is)448 +3446 y(b)n(uilt.)e(Note)24 b(the)f(use)h(of)g(De)e(Mor)n(gan')-5 +b(s)26 b(la)o(w)-6 b(.)p Black Black 448 3621 a Fh(DdManager)51 +b(*manager;)448 3734 y(DdNode)h(*f,)h(*var,)g(*tmp;)448 +3847 y(int)h(i;)448 4073 y(manager)e(=)i(Cudd_Init\(0,4,)o(CU)o(DD_)o +(UN)o(IQ)o(UE)o(_S)o(LOT)o(S,)667 4186 y(CUDD_CACHE_SLO)o(TS)o(,0)o +(\);)448 4299 y(...)448 4525 y(tmp)g(=)g(Cudd_ReadZddOn)o(e\()o(ma)o +(na)o(ger)o(,0)o(\);)448 4638 y(Cudd_Ref\(tmp\);)448 +4751 y(for)g(\(i)f(=)h(3;)g(i)g(>=)g(0;)f(i--\))g({)667 +4863 y(var)g(=)h(Cudd_zddIthVar)o(\(m)o(ana)o(ge)o(r,)o(i\))o(;)667 +4976 y(Cudd_Ref\(var\);)p Black 1897 5225 a Fo(14)p Black +eop end +%%Page: 15 15 +TeXDict begin 15 14 bop Black Black 667 573 a Fh(f)54 +b(=)g(Cudd_zddInters)o(ec)o(t\()o(man)o(ag)o(er)o(,v)o(ar)o(,tm)o(p\))o +(;)667 686 y(Cudd_Ref\(f\);)667 799 y(Cudd_Recursive)o(De)o(re)o(fZ)o +(dd)o(\(ma)o(na)o(ge)o(r,)o(tm)o(p\);)667 912 y(Cudd_Recursive)o(De)o +(re)o(fZ)o(dd)o(\(ma)o(na)o(ge)o(r,)o(va)o(r\);)667 1024 +y(tmp)f(=)h(f;)448 1137 y(})448 1250 y(f)g(=)h(Cudd_zddDiff\(m)o(an)o +(ag)o(er)o(,C)o(udd)o(_R)o(ea)o(dZ)o(dd)o(One)o(\(m)o(an)o(ag)o(er)o +(,0\))o(,t)o(mp)o(\);)448 1363 y(Cudd_Ref\(f\);)448 1476 +y(Cudd_RecursiveD)o(ere)o(fZ)o(dd)o(\(m)o(an)o(age)o(r,)o(tm)o(p\))o(;) +448 1664 y Fo(This)24 b(e)o(xample)g(illustrates)i(the)e(follo)n(wing)h +(points:)p Black 585 1851 a Fm(\017)p Black 46 w Fo(The)e(projection)k +(functions)f(are)e(referenced,)j(because)f(the)o(y)e(are)g(not)g +(maintained)i(by)676 1964 y(the)d(manager)-5 b(.)p Black +585 2152 a Fm(\017)p Black 46 w Fo(Complementation)26 +b(is)d(obtained)j(by)e(subtracting)i(from)e(the)g(constant)h(1)f +(function.)p Black 585 2340 a Fm(\017)p Black 46 w Fo(The)f(result)h +(of)g Fn(Cudd)p 1364 2340 28 4 v 34 w(ReadZddOne)g Fo(does)g(not)g +(require)h(referencing.)448 2527 y(CUDD)31 b(pro)o(vides)j(functions)i +(for)d(the)g(manipulation)i(of)e(co)o(v)o(ers)g(represented)j(by)d +(ZDDs.)448 2640 y(F)o(or)40 b(instance,)47 b Fn(Cudd)p +1179 2640 V 33 w(zddIsop)c Fo(b)n(uilds)f(a)e(ZDD)f(representing)44 +b(an)c(irredundant)k(sum)c(of)448 2753 y(products)31 +b(for)e(the)g(incompletely)i(speci\002ed)f(function)h(de\002ned)e(by)f +(the)h(tw)o(o)f(BDDs)f Fk(L)h Fo(and)448 2866 y Fk(U)10 +b Fo(.)45 b Fn(Cudd)p 789 2866 V 33 w(zddW)-8 b(eakDiv)31 +b Fo(performs)f(the)f(weak)g(di)n(vision)i(of)e(tw)o(o)g(co)o(v)o(ers)h +(gi)n(v)o(en)f(as)g(ZDDs.)448 2979 y(These)c(functions)h(e)o(xpect)f +(the)f(tw)o(o)g(ZDD)e(v)n(ariables)k(corresponding)i(to)c(the)g(tw)o(o) +g(literals)h(of)448 3092 y(the)30 b(function)j(v)n(ariable)e(to)f(be)g +(adjacent.)50 b(One)29 b(has)h(to)g(create)h(v)n(ariable)h(groups)f +(\(see)g(Sec-)448 3205 y(tion)23 b(3.14\))g(for)g(reordering)i(of)d +(the)h(ZDD)e(v)n(ariables)j(to)e(w)o(ork.)29 b(BDD)20 +b(automatic)k(reordering)448 3318 y(is)31 b(safe)h(e)n(v)o(en)f +(without)h(groups:)45 b(If)31 b(realignment)i(of)e(ZDD)e(and)i(ADD/BDD) +d(v)n(ariables)33 b(is)448 3430 y(requested)26 b(\(see)e(Section)h +(3.15\))f(groups)h(will)e(be)h(k)o(ept)g(adjacent.)448 +3680 y Fi(3.10)99 b(Con)l(v)o(erting)26 b(ADDs)e(to)h(BDDs)g(and)h(V)l +(ice)f(V)-10 b(ersa)448 3854 y Fo(Se)n(v)o(eral)25 b(procedures)i(are)d +(pro)o(vided)i(to)e(con)l(v)o(ert)i(ADDs)d(to)h(BDDs,)f(according)j(to) +e(dif)n(ferent)448 3967 y(criteria.)29 b(\()p Fn(Cudd)p +986 3967 V 34 w(addBddP)-7 b(attern)p Fo(,)21 b Fn(Cudd)p +1805 3967 V 34 w(addBddInterval)p Fo(,)i(and)18 b Fn(Cudd)p +2795 3967 V 34 w(addBddThr)m(eshold)r Fo(.\))448 4080 +y(The)34 b(con)l(v)o(ersion)i(from)e(BDDs)e(to)h(ADDs)g(\()p +Fn(Cudd)p 2119 4080 V 34 w(BddT)-8 b(oAdd)r Fo(\))34 +b(is)f(based)i(on)f(the)g(simple)448 4193 y(principle)26 +b(of)e(mapping)h(the)f(logical)i(0)d(and)h(1)g(on)f(the)h(arithmetic)i +(0)d(and)i(1.)k(It)23 b(is)h(also)g(possi-)448 4306 y(ble)g(to)g(con)l +(v)o(ert)h(an)f(ADD)e(with)h(inte)o(ger)i(v)n(alues)g(\(more)f +(precisely)-6 b(,)26 b(\003oating)e(point)h(numbers)448 +4418 y(with)f(0)f(fractional)j(part\))e(to)g(an)f(array)i(of)e(BDDs)f +(by)i(repeatedly)i(calling)f Fn(Cudd)p 3012 4418 V 34 +w(addIthBit)r Fo(.)448 4668 y Fi(3.11)99 b(Con)l(v)o(erting)26 +b(BDDs)f(to)g(ZDDs)g(and)g(V)l(ice)g(V)-10 b(ersa)448 +4842 y Fo(Man)o(y)22 b(applications)k(\002rst)21 b(b)n(uild)j(a)d(set)h +(of)g(BDDs)f(and)h(then)h(deri)n(v)o(e)g(ZDDs)d(from)i(the)g(BDDs.)448 +4955 y(These)i(applications)j(should)e(create)f(the)g(manager)g(with)f +(0)g(ZDD)e(v)n(ariables)26 b(and)e(create)g(the)p Black +1897 5225 a(15)p Black eop end +%%Page: 16 16 +TeXDict begin 16 15 bop Black Black 448 573 a Fo(BDDs.)40 +b(Then)27 b(the)o(y)h(should)h(call)f Fn(Cudd)p 1762 +573 28 4 v 34 w(zddV)-10 b(ar)o(sF)-5 b(r)l(omBddV)-10 +b(ar)o(s)30 b Fo(to)d(create)i(the)f(necessary)448 686 +y(ZDD)j(v)n(ariables\227whose)36 b(number)e(is)e(lik)o(ely)i(to)f(be)g +(kno)n(wn)g(once)g(the)g(BDDs)e(are)i(a)n(v)n(ail-)448 +799 y(able.)g(This)24 b(approach)j(eliminates)f(the)f(dif)n +(\002culties)i(that)e(arise)g(when)g(the)f(number)i(of)e(ZDD)448 +912 y(v)n(ariables)i(changes)f(while)f(ZDDs)e(are)i(being)h(b)n(uilt.) +589 1024 y(The)h(simplest)h(con)l(v)o(ersion)h(from)e(BDDs)e(to)h(ZDDs) +f(is)i(a)f(simple)h(change)h(of)f(represen-)448 1137 +y(tation,)39 b(which)c(preserv)o(es)i(the)f(functions.)65 +b(Simply)35 b(put,)j(gi)n(v)o(en)d(a)g(BDD)e(for)i Fk(f)10 +b Fo(,)36 b(a)e(ZDD)448 1250 y(for)g Fk(f)42 b Fo(is)34 +b(requested.)61 b(In)34 b(this)g(case)h(the)e(correspondence)39 +b(between)c(the)e(BDD)f(v)n(ariables)448 1363 y(and)g(ZDD)e(v)n +(ariables)j(is)e(one-to-one.)55 b(Hence,)34 b Fn(Cudd)p +2232 1363 V 34 w(zddV)-10 b(ar)o(sF)-5 b(r)l(omBddV)-10 +b(ar)o(s)33 b Fo(should)g(be)448 1476 y(called)c(with)e(the)g +Fn(multiplicity)j Fo(parameter)f(equal)f(to)g(1.)39 b(The)27 +b(con)l(v)o(ersion)j(proper)f(can)f(then)448 1589 y(be)37 +b(performed)h(by)f(calling)h Fn(Cudd)p 1595 1589 V 33 +w(zddP)-7 b(ortF)i(r)l(omBdd)r Fo(.)69 b(The)36 b(in)l(v)o(erse)j +(transformation)g(is)448 1702 y(performed)26 b(by)d Fn(Cudd)p +1164 1702 V 34 w(zddP)-7 b(ortT)f(oBdd)r Fo(.)589 1815 +y(ZDDs)28 b(are)i(quite)h(often)f(used)h(for)e(the)h(representation)k +(of)c Fn(co)o(ver)o(s)p Fo(.)48 b(This)29 b(is)h(normally)448 +1928 y(done)36 b(by)g(associating)i(tw)o(o)d(ZDD)e(v)n(ariables)38 +b(to)d(each)h(v)n(ariable)h(of)e(the)g(function.)66 b(\(And)448 +2041 y(hence,)28 b(typically)-6 b(,)28 b(to)e(each)g(BDD)e(v)n +(ariable.\))38 b(One)25 b(ZDD)f(v)n(ariable)j(is)f(associated)i(with)e +(the)448 2154 y(positi)n(v)o(e)35 b(literal)f(of)f(the)g(BDD)e(v)n +(ariable,)37 b(while)d(the)f(other)h(ZDD)d(v)n(ariable)k(is)d +(associated)448 2267 y(with)i(the)f(ne)o(gati)n(v)o(e)h(literal.)60 +b(A)32 b(call)i(to)f Fn(Cudd)p 1980 2267 V 34 w(zddV)-10 +b(ar)o(sF)-5 b(r)l(omBddV)-10 b(ar)o(s)36 b Fo(with)d +Fn(multiplicity)448 2379 y Fo(equal)25 b(to)e(2)h(will)f(associate)j +(to)d(BDD)f(v)n(ariable)j Fk(i)e Fo(the)h(tw)o(o)f(ZDD)f(v)n(ariables)j +Fl(2)p Fk(i)f Fo(and)g Fl(2)p Fk(i)d Fl(+)f(1)p Fo(.)589 +2492 y(If)j(a)f(BDD)f(v)n(ariable)j(group)g(tree)f(e)o(xists)h(when)f +Fn(Cudd)p 2300 2492 V 34 w(zddV)-10 b(ar)o(sF)-5 b(r)l(omBddV)-10 +b(ar)o(s)25 b Fo(is)d(called)448 2605 y(\(see)29 b(Section)f(3.13\))g +(the)g(function)i(generates)g(a)e(ZDD)d(v)n(ariable)30 +b(group)f(tree)f(consistent)i(to)448 2718 y(it.)57 b(In)33 +b(an)o(y)h(case,)h(all)f(the)f(ZDD)e(v)n(ariables)k(deri)n(v)o(ed)g +(from)e(the)g(same)g(BDD)e(v)n(ariable)k(are)448 2831 +y(clustered)26 b(into)e(a)f(group.)589 2944 y(If)i(the)f(ZDD)e(for)j +Fk(f)33 b Fo(is)24 b(created)i(and)f(later)g(a)f(ne)n(w)f(ZDD)g(v)n +(ariable)j(is)e(added)h(to)g(the)f(man-)448 3057 y(ager)l(,)f(the)e +(function)i(represented)i(by)c(the)h(e)o(xisting)g(ZDD)e(changes.)29 +b(Suppose,)23 b(for)e(instance,)448 3170 y(that)26 b(tw)o(o)f(v)n +(ariables)i(are)e(initially)i(created,)g(and)e(that)h(the)f(ZDD)e(for)i +Fk(f)38 b Fl(=)27 b Fk(x)2896 3184 y Fc(0)2957 3170 y +Fl(+)21 b Fk(x)3101 3184 y Fc(1)3165 3170 y Fo(is)j(b)n(uilt.)448 +3283 y(If)33 b(a)g(third)h(v)n(ariable)h(is)e(added,)k(say)c +Fk(x)1714 3297 y Fc(2)1753 3283 y Fo(,)i(then)f(the)f(ZDD)e(represents) +36 b Fk(g)47 b Fl(=)c(\()p Fk(x)3054 3297 y Fc(0)3121 +3283 y Fl(+)27 b Fk(x)3271 3297 y Fc(1)3310 3283 y Fl(\))p +Fk(x)3397 3250 y Fd(0)3397 3306 y Fc(2)448 3396 y Fo(instead.)36 +b(This)25 b(change)i(in)e(function)j(ob)o(viously)g(applies)f(re)o +(gardless)g(of)e(what)g(use)h(is)f(made)448 3509 y(of)j(the)g(ZDD.)39 +b(Ho)n(we)n(v)o(er)l(,)29 b(if)e(the)h(ZDD)e(is)h(used)i(to)e +(represent)k(a)c(co)o(v)o(er,)i(the)f(co)o(v)o(er)g(itself)g(is)448 +3621 y(not)i(changed)h(by)e(the)g(addition)j(of)c(ne)n(w)h(v)n +(ariable.)47 b(\(What)29 b(changes)i(is)e(the)g(characteristic)448 +3734 y(function)d(of)d(the)h(co)o(v)o(er)-5 b(.\))448 +3984 y Fi(3.12)99 b(V)-9 b(ariable)25 b(Reordering)h(f)n(or)e(BDDs)h +(and)h(ADDs)448 4158 y Fo(The)20 b(CUDD)d(package)22 +b(pro)o(vides)g(a)d(rich)h(set)g(of)g(dynamic)h(reordering)i +(algorithms.)29 b(Some)19 b(of)448 4271 y(them)24 b(are)g(slight)g(v)n +(ariations)i(of)e(e)o(xisting)h(techniques)i([16)q(,)22 +b(6)q(,)g(2)q(,)g(10)q(,)h(15)q(,)f(11)q(];)h(some)h(others)448 +4384 y(ha)n(v)o(e)h(been)f(de)n(v)o(eloped)i(speci\002cally)f(for)f +(this)g(package)i([14)q(,)c(13)q(].)589 4497 y(Reordering)33 +b(af)n(fects)e(a)f(unique)i(table.)50 b(This)30 b(means)h(that)g(BDDs)e +(and)i(ADDs,)f(which)448 4609 y(share)36 b(the)g(same)f(unique)i(table) +f(are)f(simultaneously)k(reordered.)66 b(ZDDs,)36 b(on)f(the)g(other) +448 4722 y(hand,)22 b(are)f(reordered)i(separately)-6 +b(.)31 b(In)20 b(the)h(follo)n(wing)h(we)e(discuss)i(the)f(reordering)i +(of)e(BDDs)448 4835 y(and)j(ADDs.)j(Reordering)f(for)e(ZDDs)e(is)h(the) +h(subject)h(of)f(Section)g(3.14.)p Black 1897 5225 a(16)p +Black eop end +%%Page: 17 17 +TeXDict begin 17 16 bop Black Black 589 573 a Fo(Reordering)28 +b(of)d(the)g(v)n(ariables)i(can)f(be)f(in)l(v)n(ok)o(ed)j(directly)f +(by)e(the)g(application)j(by)e(call-)448 686 y(ing)g +Fn(Cudd)p 790 686 28 4 v 34 w(ReduceHeap)p Fo(.)35 b(Or)24 +b(it)h(can)h(be)f(automatically)k(triggered)e(by)e(the)h(package)h +(when)448 799 y(the)k(number)g(of)g(nodes)g(has)g(reached)h(a)e(gi)n(v) +o(en)h(threshold.)52 b(\(The)30 b(threshold)j(is)d(initialized)448 +912 y(and)h(automatically)j(adjusted)f(after)e(each)h(reordering)h(by)e +(the)g(package.\))52 b(T)-7 b(o)30 b(enable)i(au-)448 +1024 y(tomatic)c(dynamic)h(reordering)h(\(also)e(called)g +Fn(async)o(hr)l(onous)j Fo(dynamic)e(reordering)h(in)d(this)448 +1137 y(document\))37 b(the)f(application)i(must)d(call)h +Fn(Cudd)p 2033 1137 V 34 w(A)n(utodynEnable)p Fo(.)66 +b(Automatic)36 b(dynamic)448 1250 y(reordering)27 b(can)d(subsequently) +j(be)d(disabled)h(by)f(calling)h Fn(Cudd)p 2515 1250 +V 34 w(A)n(utodynDisable)p Fo(.)589 1363 y(All)18 b(reordering)j +(methods)e(are)f(a)n(v)n(ailable)j(in)d(both)h(the)f(case)h(of)f +(direct)h(call)g(to)f Fn(Cudd)p 3238 1363 V 33 w(ReduceHeap)448 +1476 y Fo(and)23 b(the)g(case)g(of)g(automatic)h(in)l(v)n(ocation.)32 +b(F)o(or)21 b(man)o(y)i(methods,)h(the)e(reordering)k(procedure)448 +1589 y(is)34 b(iterated)h(until)f(no)f(further)i(impro)o(v)o(ement)g +(is)e(obtained.)61 b(W)-7 b(e)32 b(call)i(these)g(methods)h(the)448 +1702 y Fn(con)l(ver)m(ging)40 b Fo(methods.)68 b(When)37 +b(constraints)i(are)e(imposed)g(on)g(the)f(relati)n(v)o(e)i(position)g +(of)448 1815 y(v)n(ariables)31 b(\(see)d(Section)h(3.13\))g(the)f +(reordering)j(methods)f(apply)f(inside)g(the)g(groups.)44 +b(The)448 1928 y(groups)33 b(themselv)o(es)g(are)e(reordered)i(by)e +(sifting.)53 b(Each)31 b(method)h(is)e(identi\002ed)j(by)e(a)g(con-)448 +2041 y(stant)24 b(of)f(the)h(enumerated)h(type)f Fn(Cudd)p +1700 2041 V 34 w(Reor)m(deringT)-7 b(ype)26 b Fo(de\002ned)e(in)f +Fn(cudd.h)h Fo(\(the)g(e)o(xternal)448 2154 y(header)h(\002le)e(of)h +(the)f(CUDD)f(package\):)p Black 448 2366 a Fp(CUDD)p +717 2366 V 32 w(REORDER)p 1206 2366 V 30 w(NONE:)p Black +44 w Fo(This)i(method)g(causes)h(no)f(reordering.)p Black +448 2554 a Fp(CUDD)p 717 2554 V 32 w(REORDER)p 1206 2554 +V 30 w(SAME:)p Black 44 w Fo(If)18 b(passed)i(to)e Fn(Cudd)p +2196 2554 V 33 w(A)n(utodynEnable)p Fo(,)k(this)d(method)g(lea)n(v)o +(es)676 2667 y(the)f(current)i(method)f(for)f(automatic)i(reordering)h +(unchanged.)30 b(If)17 b(passed)j(to)e Fn(Cudd)p 3333 +2667 V 34 w(ReduceHeap)p Fo(,)676 2780 y(this)24 b(method)g(causes)h +(the)f(current)h(method)g(for)e(automatic)j(reordering)g(to)d(be)h +(used.)p Black 448 2967 a Fp(CUDD)p 717 2967 V 32 w(REORDER)p +1206 2967 V 30 w(RANDOM:)p Black 44 w Fo(P)o(airs)17 +b(of)h(v)n(ariables)j(are)d(randomly)i(chosen,)g(and)f(sw)o(apped)676 +3080 y(in)29 b(the)h(order)-5 b(.)48 b(The)29 b(sw)o(ap)h(is)f +(performed)i(by)f(a)f(series)i(of)f(sw)o(aps)g(of)f(adjacent)j(v)n +(ari-)676 3193 y(ables.)c(The)18 b(best)h(order)g(among)g(those)h +(obtained)g(by)f(the)g(series)g(of)f(sw)o(aps)h(is)g(retained.)676 +3306 y(The)24 b(number)i(of)f(pairs)h(chosen)h(for)e(sw)o(apping)i +(equals)f(the)f(number)h(of)f(v)n(ariables)i(in)676 3419 +y(the)c(diagram.)p Black 448 3606 a Fp(CUDD)p 717 3606 +V 32 w(REORDER)p 1206 3606 V 30 w(RANDOM)p 1657 3606 +V 31 w(PIV)l(O)l(T:)p Black 45 w Fo(Same)17 b(as)h(CUDD)p +2615 3606 V 31 w(REORDER)p 3073 3606 V 30 w(RANDOM,)676 +3719 y(b)n(ut)30 b(the)g(tw)o(o)f(v)n(ariables)j(are)d(chosen)j(so)d +(that)h(the)g(\002rst)g(is)f(abo)o(v)o(e)h(the)g(v)n(ariable)h(with)676 +3832 y(the)d(lar)n(gest)h(number)g(of)e(nodes,)j(and)e(the)g(second)i +(is)d(belo)n(w)h(that)g(v)n(ariable.)43 b(In)28 b(case)676 +3945 y(there)h(are)g(se)n(v)o(eral)h(v)n(ariables)h(tied)e(for)g(the)g +(maximum)g(number)g(of)g(nodes,)i(the)e(one)676 4058 +y(closest)c(to)e(the)h(root)g(is)g(used.)p Black 448 +4246 a Fp(CUDD)p 717 4246 V 32 w(REORDER)p 1206 4246 +V 30 w(SIFT:)p Black 45 w Fo(This)g(method)h(is)g(an)f(implementation)k +(of)c(Rudell')-5 b(s)26 b(sifting)676 4359 y(algorithm)i([16)q(].)39 +b(A)26 b(simpli\002ed)i(description)i(of)d(sifting)h(is)f(as)g(follo)n +(ws:)37 b(Each)27 b(v)n(ari-)676 4472 y(able)32 b(is)g(considered)j(in) +d(turn.)55 b(A)30 b(v)n(ariable)k(is)e(mo)o(v)o(ed)g(up)g(and)g(do)n +(wn)g(in)g(the)g(order)676 4584 y(so)26 b(that)h(it)e(tak)o(es)j(all)e +(possible)i(positions.)40 b(The)25 b(best)i(position)i(is)d +(identi\002ed)h(and)g(the)676 4697 y(v)n(ariable)e(is)e(returned)j(to)d +(that)h(position.)676 4848 y(In)30 b(reality)-6 b(,)34 +b(things)e(are)f(a)g(bit)g(more)f(complicated.)53 b(F)o(or)30 +b(instance,)35 b(there)c(is)g(a)f(limit)676 4961 y(on)g(the)g(number)h +(of)f(v)n(ariables)i(that)f(will)f(be)g(sifted.)49 b(This)30 +b(limit)g(can)h(be)f(read)g(with)p Black 1897 5225 a(17)p +Black eop end +%%Page: 18 18 +TeXDict begin 18 17 bop Black Black 676 573 a Fn(Cudd)p +877 573 28 4 v 33 w(ReadSiftMaxV)-10 b(ar)29 b Fo(and)d(set)f(with)g +Fn(Cudd)p 2195 573 V 34 w(SetSiftMaxV)-10 b(ar)r Fo(.)35 +b(In)25 b(addition,)i(if)e(the)676 686 y(diagram)31 b(gro)n(ws)g(too)g +(much)g(while)g(mo)o(ving)h(a)e(v)n(ariable)j(up)d(or)h(do)n(wn,)h +(that)g(mo)o(v)o(e-)676 799 y(ment)37 b(is)f(terminated)j(before)g(the) +e(v)n(ariable)i(has)e(reached)i(one)e(end)g(of)g(the)h(order)-5 +b(.)676 912 y(The)27 b(maximum)g(ratio)i(by)f(which)g(the)g(diagram)h +(is)e(allo)n(wed)i(to)e(gro)n(w)h(while)f(a)h(v)n(ari-)676 +1024 y(able)35 b(is)f(being)h(sifted)h(can)f(be)f(read)h(with)g +Fn(Cudd)p 2292 1024 V 33 w(ReadMaxGr)l(owth)h Fo(and)f(set)f(with)676 +1137 y Fn(Cudd)p 877 1137 V 33 w(SetMaxGr)l(owth)p Fo(.)p +Black 448 1318 a Fp(CUDD)p 717 1318 V 32 w(REORDER)p +1206 1318 V 30 w(SIFT)p 1439 1318 V 32 w(CONVERGE:)p +Black 43 w Fo(This)18 b(is)f(the)i(con)l(v)o(er)n(ging)i(v)n(ariant)f +(of)e(CUDD-)p 676 1431 V 703 1431 a(REORDER)p 1135 1431 +V 30 w(SIFT)-7 b(.)p Black 448 1612 a Fp(CUDD)p 717 1612 +V 32 w(REORDER)p 1206 1612 V 30 w(SYMM)p 1525 1612 V +31 w(SIFT:)p Black 45 w Fo(This)34 b(method)h(is)f(an)g(implementation) +i(of)e(sym-)676 1725 y(metric)27 b(sifting)i([14)q(].)39 +b(It)26 b(is)h(similar)h(to)f(sifting,)i(with)e(one)h(addition:)38 +b(V)-10 b(ariables)29 b(that)676 1837 y(become)23 b(adjacent)i(during)f +(sifting)g(are)f(tested)h(for)f(symmetry.)29 b(If)22 +b(the)o(y)h(are)g(symmet-)676 1950 y(ric,)34 b(the)o(y)f(are)f(link)o +(ed)i(in)f(a)f(group.)56 b(Sifting)33 b(then)g(continues)i(with)e(a)e +(group)j(being)676 2063 y(mo)o(v)o(ed,)d(instead)h(of)f(a)e(single)j(v) +n(ariable.)51 b(After)30 b(symmetric)i(sifting)f(has)g(been)g(run,)676 +2176 y Fn(Cudd)p 877 2176 V 33 w(SymmPr)l(o\002le)h Fo(can)g(be)g +(called)g(to)g(report)h(on)e(the)h(symmetry)g(groups)h(found.)676 +2289 y(\(Both)23 b(positi)n(v)o(e)i(and)f(ne)o(gati)n(v)o(e)h +(symmetries)g(are)e(reported.\))p Black 448 2470 a Fp(CUDD)p +717 2470 V 32 w(REORDER)p 1206 2470 V 30 w(SYMM)p 1525 +2470 V 31 w(SIFT)p 1759 2470 V 32 w(CONV:)p Black 45 +w Fo(This)17 b(is)h(the)h(con)l(v)o(er)n(ging)i(v)n(ariant)f(of)e +(CUDD-)p 676 2583 V 703 2583 a(REORDER)p 1135 2583 V +30 w(SYMM)p 1444 2583 V 31 w(SIFT)-7 b(.)p Black 448 +2763 a Fp(CUDD)p 717 2763 V 32 w(REORDER)p 1206 2763 +V 30 w(GR)m(OUP)p 1563 2763 V 31 w(SIFT:)p Black 45 w +Fo(This)22 b(method)i(is)e(an)h(implementation)i(of)e(group)676 +2876 y(sifting)c([13)r(].)26 b(It)18 b(is)g(similar)h(to)f(symmetric)i +(sifting,)g(b)n(ut)f(aggre)o(gation)i(is)d(not)h(restricted)676 +2989 y(to)k(symmetric)i(v)n(ariables.)p Black 448 3170 +a Fp(CUDD)p 717 3170 V 32 w(REORDER)p 1206 3170 V 30 +w(GR)m(OUP)p 1563 3170 V 31 w(SIFT)p 1797 3170 V 32 w(CONV:)p +Black 44 w Fo(This)36 b(method)h(repeats)g(until)g(con)l(v)o(er)n(-)676 +3283 y(gence)h(the)f(combination)j(of)d(CUDD)p 1938 3283 +V 31 w(REORDER)p 2396 3283 V 30 w(GR)l(OUP)p 2732 3283 +V 32 w(SIFT)e(and)i(CUDD-)p 676 3396 V 703 3396 a(REORDER)p +1135 3396 V 30 w(WINDO)m(W4.)p Black 448 3576 a Fp(CUDD)p +717 3576 V 32 w(REORDER)p 1206 3576 V 30 w(WINDO)-5 b(W2:)p +Black 46 w Fo(This)30 b(method)h(implements)h(the)e(windo)n(w)h(permu-) +676 3689 y(tation)j(approach)i(of)d(Fujita)h([8)q(])f(and)g(Ishiura)j +([10)q(].)57 b(The)33 b(size)h(of)g(the)f(windo)n(w)g(is)676 +3802 y(2.)p Black 448 3983 a Fp(CUDD)p 717 3983 V 32 +w(REORDER)p 1206 3983 V 30 w(WINDO)-5 b(W3:)p Black 46 +w Fo(Similar)18 b(to)g(CUDD)p 2404 3983 V 31 w(REORDER)p +2862 3983 V 30 w(WINDO)m(W2,)f(b)n(ut)676 4096 y(with)23 +b(a)g(windo)n(w)g(of)h(size)g(3.)p Black 448 4276 a Fp(CUDD)p +717 4276 V 32 w(REORDER)p 1206 4276 V 30 w(WINDO)-5 b(W4:)p +Black 46 w Fo(Similar)18 b(to)g(CUDD)p 2404 4276 V 31 +w(REORDER)p 2862 4276 V 30 w(WINDO)m(W2,)f(b)n(ut)676 +4389 y(with)23 b(a)g(windo)n(w)g(of)h(size)g(4.)p Black +448 4570 a Fp(CUDD)p 717 4570 V 32 w(REORDER)p 1206 4570 +V 30 w(WINDO)-5 b(W2)p 1696 4570 V 33 w(CONV:)p Black +44 w Fo(This)18 b(is)g(the)g(con)l(v)o(er)n(ging)k(v)n(ariant)d(of)f +(CUDD-)p 676 4683 V 703 4683 a(REORDER)p 1135 4683 V +30 w(WINDO)m(W2.)p Black 448 4863 a Fp(CUDD)p 717 4863 +V 32 w(REORDER)p 1206 4863 V 30 w(WINDO)-5 b(W3)p 1696 +4863 V 33 w(CONV:)p Black 44 w Fo(This)18 b(is)g(the)g(con)l(v)o(er)n +(ging)k(v)n(ariant)d(of)f(CUDD-)p 676 4976 V 703 4976 +a(REORDER)p 1135 4976 V 30 w(WINDO)m(W3.)p Black 1897 +5225 a(18)p Black eop end +%%Page: 19 19 +TeXDict begin 19 18 bop Black Black Black 448 573 a Fp(CUDD)p +717 573 28 4 v 32 w(REORDER)p 1206 573 V 30 w(WINDO)-5 +b(W4)p 1696 573 V 33 w(CONV:)p Black 44 w Fo(This)18 +b(is)g(the)g(con)l(v)o(er)n(ging)k(v)n(ariant)d(of)f(CUDD-)p +676 686 V 703 686 a(REORDER)p 1135 686 V 30 w(WINDO)m(W4.)p +Black 448 867 a Fp(CUDD)p 717 867 V 32 w(REORDER)p 1206 +867 V 30 w(ANNEALING:)p Black 43 w Fo(This)24 b(method)h(is)f(an)h +(implementation)i(of)d(simu-)676 980 y(lated)e(annealing)h(for)f(v)n +(ariable)h(ordering,)g(v)n(aguely)g(resemblant)g(of)e(the)h(algorithm)g +(of)676 1093 y([2].)28 b(This)c(method)g(is)g(potentially)i(v)o(ery)e +(slo)n(w)-6 b(.)p Black 448 1275 a Fp(CUDD)p 717 1275 +V 32 w(REORDER)p 1206 1275 V 30 w(GENETIC:)p Black 44 +w Fo(This)26 b(method)i(is)e(an)h(implementation)j(of)c(a)h(genetic)676 +1388 y(algorithm)g(for)e(v)n(ariable)j(ordering,)f(inspired)h(by)d(the) +h(w)o(ork)g(of)f(Drechsler)i([6)q(].)33 b(This)676 1501 +y(method)24 b(is)f(potentially)k(v)o(ery)d(slo)n(w)-6 +b(.)p Black 448 1682 a Fp(CUDD)p 717 1682 V 32 w(REORDER)p +1206 1682 V 30 w(EXA)h(CT:)p Black 44 w Fo(This)22 b(method)i +(implements)h(a)d(dynamic)i(programming)676 1795 y(approach)d(to)f(e)o +(xact)g(reordering)i([9)q(,)c(7)q(,)g(10)q(],)h(with)h(impro)o(v)o +(ements)h(described)h(in)d([11)q(].)676 1908 y(It)33 +b(only)h(stores)g(one)g(BDD)d(at)j(the)f(time.)58 b(Therefore,)37 +b(it)c(is)g(relati)n(v)o(ely)i(ef)n(\002cient)f(in)676 +2021 y(terms)29 b(of)g(memory)-6 b(.)45 b(Compared)29 +b(to)g(other)h(reordering)i(strate)o(gies,)g(it)d(is)g(v)o(ery)g(slo)n +(w)-6 b(,)676 2134 y(and)24 b(is)f(not)h(recommended)i(for)d(more)h +(than)g(16)g(v)n(ariables.)448 2329 y(So)f(f)o(ar)h(we)e(ha)n(v)o(e)i +(described)i(methods)f(whereby)g(the)e(package)j(selects)f(an)e(order)i +(automati-)448 2442 y(cally)-6 b(.)28 b(A)17 b(gi)n(v)o(en)i(order)g +(of)f(the)g(v)n(ariables)i(can)f(also)g(be)f(imposed)h(by)f(calling)i +Fn(Cudd)p 3050 2442 V 34 w(Shuf)n(\003eHeap)p Fo(.)448 +2688 y Fi(3.13)99 b(Gr)n(ouping)26 b(V)-9 b(ariables)448 +2862 y Fo(CUDD)29 b(allo)n(ws)i(the)g(application)j(to)d(specify)h +(constraints)i(on)d(the)g(positions)j(of)c(group)i(of)448 +2975 y(v)n(ariables.)63 b(It)34 b(is)g(possible)j(to)d(request)i(that)f +(a)f(group)h(of)f(contiguous)k(v)n(ariables)e(be)e(k)o(ept)448 +3088 y(contiguous)39 b(by)d(the)g(reordering)i(procedures.)68 +b(It)35 b(is)g(also)h(possible)i(to)e(request)h(that)f(the)448 +3201 y(relati)n(v)o(e)31 b(order)f(of)g(some)f(groups)j(of)d(v)n +(ariables)j(be)d(left)h(unchanged.)50 b(The)29 b(constraints)j(on)448 +3314 y(the)24 b(order)h(are)e(speci\002ed)i(by)f(means)g(of)f(a)g +(tree,)h(which)g(is)f(created)j(in)d(one)h(of)g(tw)o(o)f(w)o(ays:)p +Black 585 3486 a Fm(\017)p Black 46 w Fo(By)f(calling)k +Fn(Cudd)p 1276 3486 V 33 w(Mak)o(eT)-5 b(r)m(eeNode)p +Fo(.)p Black 585 3668 a Fm(\017)p Black 46 w Fo(By)21 +b(calling)j(the)f(functions)i(of)d(the)h(MTR)e(library)j(\(part)f(of)f +(the)h(distrib)n(ution\),)j(and)d(by)676 3781 y(re)o(gistering)i(the)d +(result)i(with)e(the)g(manager)i(using)f Fn(Cudd)p 2510 +3781 V 34 w(SetT)-5 b(r)m(ee)p Fo(.)29 b(The)22 b(current)i(tree)676 +3894 y(re)o(gistered)h(with)f(the)g(manager)g(can)g(be)g(read)g(with)f +Fn(Cudd)p 2531 3894 V 34 w(ReadT)-5 b(r)m(ee)p Fo(.)589 +4067 y(Each)36 b(node)h(in)f(the)g(tree)h(represents)h(a)e(range)h(of)f +(v)n(ariables.)68 b(The)35 b(lo)n(wer)h(bound)h(of)448 +4180 y(the)29 b(range)g(is)f(gi)n(v)o(en)h(by)f(the)h +Fn(low)e Fo(\002eld)h(of)g(the)h(node,)h(and)f(the)f(size)h(of)f(the)g +(group)i(is)e(gi)n(v)o(en)448 4293 y(by)33 b(the)g Fn(size)g +Fo(\002eld)g(of)g(the)g(node.)1525 4260 y Fg(2)1619 4293 +y Fo(The)f(v)n(ariables)j(in)e(each)g(range)h(are)f(k)o(ept)g +(contiguous.)448 4405 y(Furthermore,)22 b(if)e(a)f(node)i(is)f(mark)o +(ed)g(with)g(the)g(MTR)p 2159 4405 V 32 w(FIXED)e(\003ag,)i(then)g(the) +g(relati)n(v)o(e)h(order)448 4518 y(of)32 b(the)g(v)n(ariable)i(ranges) +g(associated)g(to)e(its)g(children)i(is)e(not)h(changed.)56 +b(As)31 b(an)h(e)o(xample,)448 4631 y(suppose)26 b(the)e(initial)h(v)n +(ariable)g(order)f(is:)p Black 448 4706 1196 4 v 554 +4762 a Ff(2)583 4794 y Fe(When)18 b(the)g(v)n(ariables)h(in)f(a)g +(group)h(are)f(reordered,)h(the)g(association)g(between)f(the)h +Fb(low)e Fe(\002eld)h(and)h(the)f(inde)o(x)448 4885 y(of)k(the)h +(\002rst)e(v)n(ariable)h(in)g(the)h(group)g(is)f(lost.)32 +b(The)22 b(package)i(updates)f(the)f(tree)g(to)g(k)o(eep)h(track)f(of)h +(the)f(changes.)448 4976 y(Ho)n(we)n(v)o(er)m(,)e(the)f(application)g +(cannot)h(rely)f(on)h Fb(low)e Fe(to)h(determine)g(the)g(position)h(of) +f(v)n(ariables.)p Black Black 1897 5225 a Fo(19)p Black +eop end +%%Page: 20 20 +TeXDict begin 20 19 bop Black Black Black Black 448 573 +a Fh(x0,)54 b(y0,)f(z0,)g(x1,)g(y1,)g(z1,)g(...)h(,)g(x9,)f(y9,)g(z9.) +448 748 y Fo(Suppose)27 b(we)f(w)o(ant)f(to)h(k)o(eep)h(each)g(group)g +(of)f(three)g(v)n(ariables)i(with)e(the)g(same)g(inde)o(x)h(\(e.g.,)448 +861 y Fh(x3,)54 b(y3,)f(z3)p Fo(\))21 b(contiguous,)27 +b(while)c(allo)n(wing)h(the)g(package)h(to)e(change)i(the)f(order)g(of) +f(the)448 974 y(groups.)31 b(W)-7 b(e)22 b(can)i(accomplish)i(this)e +(with)f(the)h(follo)n(wing)h(code:)p Black Black 448 +1150 a Fh(for)54 b(\(i)f(=)h(0;)g(i)g(<)g(10;)f(i++\))g({)667 +1262 y(\(void\))e(Cudd_MakeTreeNo)o(de\()o(ma)o(na)o(ge)o(r,)o(i*3)o +(,3)o(,M)o(TR)o(_D)o(EFA)o(UL)o(T\))o(;)448 1375 y(})448 +1551 y Fo(If)26 b(we)f(w)o(ant)h(to)g(k)o(eep)h(the)f(order)h(within)g +(each)g(group)g(of)f(v)n(ariables)i(\002x)o(ed)e(\(i.e.,)f +Fh(x)g Fo(before)j Fh(y)448 1664 y Fo(before)d Fh(z)p +Fo(\))e(we)f(need)j(to)e(change)i(MTR)p 1710 1664 28 +4 v 32 w(DEF)-7 b(A)i(UL)d(T)20 b(into)k(MTR)p 2521 1664 +V 32 w(FIXED.)589 1777 y(The)32 b Fn(low)f Fo(parameter)i(passed)g(to)f +Fn(Cudd)p 1894 1777 V 33 w(Mak)o(eT)-5 b(r)m(eeNode)33 +b Fo(is)f(the)g(inde)o(x)g(of)f(a)h(v)n(ariable)448 1890 +y(\(as)27 b(opposed)i(to)e(its)f(le)n(v)o(el)h(or)g(position)i(in)d +(the)h(order\).)39 b(The)27 b(group)g(tree)h(can)f(be)f(created)i(at) +448 2003 y(an)o(y)g(time.)40 b(The)27 b(result)h(ob)o(viously)i +(depends)f(on)f(the)f(v)n(ariable)i(order)g(in)e(ef)n(fect)h(at)f +(creation)448 2115 y(time.)589 2228 y(It)20 b(is)g(possible)i(to)e +(create)h(a)e(v)n(ariable)j(group)f(tree)f(also)h(before)g(the)f(v)n +(ariables)i(themselv)o(es)448 2341 y(are)f(created.)29 +b(The)21 b(package)h(assumes)g(in)e(this)i(case)f(that)g(the)g(inde)o +(x)g(of)g(the)f(v)n(ariables)j(not)e(yet)448 2454 y(in)h(e)o(xistence)i +(will)e(equal)g(their)h(position)h(in)e(the)g(order)h(when)f(the)o(y)g +(are)g(created.)30 b(Therefore,)448 2567 y(applications)g(that)c(rely)h +(on)f Fn(Cudd)p 1558 2567 V 34 w(bddNe)o(wV)-10 b(arAtLe)o(vel)26 +b Fo(or)g Fn(Cudd)p 2613 2567 V 34 w(addNe)o(wV)-10 b(arAtLe)o(vel)26 +b Fo(to)448 2680 y(create)f(ne)n(w)e(v)n(ariables)j(ha)n(v)o(e)e(to)f +(create)i(the)f(v)n(ariables)h(before)g(the)o(y)f(group)h(them.)589 +2793 y(The)31 b(reordering)j(procedure)g(will)d(skip)h(all)g(groups)h +(whose)e(v)n(ariables)j(are)d(not)h(yet)f(in)448 2906 +y(e)o(xistence.)h(F)o(or)24 b(groups)h(that)g(are)f(only)h(partially)h +(in)e(e)o(xistence,)i(the)e(reordering)j(procedure)448 +3019 y(will)18 b(try)h(to)f(reorder)i(the)e(v)n(ariables)i(already)g +(instantiated,)j(without)c(violating)i(the)d(adjacenc)o(y)448 +3132 y(constraints.)448 3378 y Fi(3.14)99 b(V)-9 b(ariable)25 +b(Reordering)h(f)n(or)e(ZDDs)448 3553 y Fo(Reordering)h(of)d(ZDDs)f(is) +h(done)h(in)g(much)f(the)h(same)f(w)o(ay)h(as)f(the)g(reordering)k(of)c +(BDDs)f(and)448 3666 y(ADDs.)28 b(The)23 b(functions)j(corresponding)i +(to)c Fn(Cudd)p 2095 3666 V 33 w(ReduceHeap)i Fo(and)e +Fn(Cudd)p 2966 3666 V 33 w(Shuf)n(\003eHeap)448 3778 +y Fo(are)h Fn(Cudd)p 784 3778 V 33 w(zddReduceHeap)i +Fo(and)e Fn(Cudd)p 1782 3778 V 34 w(zddShuf)n(\003eHeap)p +Fo(.)34 b(T)-7 b(o)23 b(enable)j(dynamic)f(reorder)n(-)448 +3891 y(ing,)36 b(the)e(application)j(must)c(call)h Fn(Cudd)p +1777 3891 V 34 w(A)n(utodynEnableZdd)r Fo(,)39 b(and)34 +b(to)g(disable)h(dynamic)448 4004 y(reordering,)29 b(it)d(must)g(call)g +Fn(Cudd)p 1510 4004 V 34 w(A)n(utodynDisableZdd)r Fo(.)39 +b(In)26 b(the)g(current)i(implementation,)448 4117 y(ho)n(we)n(v)o(er)l +(,)c(the)f(choice)h(of)f(reordering)j(methods)e(for)g(ZDDs)d(is)i(more) +g(limited.)29 b(Speci\002cally)-6 b(,)448 4230 y(these)25 +b(methods)g(are)e(a)n(v)n(ailable:)p Black 448 4428 a +Fp(CUDD)p 717 4428 V 32 w(REORDER)p 1206 4428 V 30 w(NONE;)p +Black Black 448 4611 a(CUDD)p 717 4611 V 32 w(REORDER)p +1206 4611 V 30 w(SAME;)p Black Black 448 4794 a(CUDD)p +717 4794 V 32 w(REORDER)p 1206 4794 V 30 w(RANDOM;)p +Black Black 448 4976 a(CUDD)p 717 4976 V 32 w(REORDER)p +1206 4976 V 30 w(RANDOM)p 1657 4976 V 31 w(PIV)l(O)l(T;)p +Black Black 1897 5225 a Fo(20)p Black eop end +%%Page: 21 21 +TeXDict begin 21 20 bop Black Black Black 448 573 a Fp(CUDD)p +717 573 28 4 v 32 w(REORDER)p 1206 573 V 30 w(SIFT;)p +Black Black 448 760 a(CUDD)p 717 760 V 32 w(REORDER)p +1206 760 V 30 w(SIFT)p 1439 760 V 32 w(CONVERGE;)p Black +Black 448 948 a(CUDD)p 717 948 V 32 w(REORDER)p 1206 +948 V 30 w(SYMM)p 1525 948 V 31 w(SIFT;)p Black Black +448 1136 a(CUDD)p 717 1136 V 32 w(REORDER)p 1206 1136 +V 30 w(SYMM)p 1525 1136 V 31 w(SIFT)p 1759 1136 V 32 +w(CONV.)p Black 589 1348 a Fo(T)-7 b(o)20 b(create)j(ZDD)c(v)n(ariable) +k(groups,)g(the)e(application)j(calls)e Fn(Cudd)p 2693 +1348 V 34 w(Mak)o(eZddT)-5 b(r)m(eeNode)p Fo(.)448 1597 +y Fi(3.15)99 b(K)n(eeping)25 b(Consistent)g(V)-9 b(ariable)25 +b(Orders)g(f)n(or)g(BDDs)g(and)g(ZDDs)448 1772 y Fo(Se)n(v)o(eral)f +(applications)i(that)e(manipulate)i(both)e(BDDs)d(and)j(ZDDs)d +(bene\002t)j(from)f(k)o(eeping)j(a)448 1885 y(\002x)o(ed)e +(correspondence)29 b(between)d(the)f(order)g(of)f(the)h(BDD)d(v)n +(ariables)27 b(and)e(the)f(order)i(of)e(the)448 1998 +y(ZDD)k(v)n(ariables.)51 b(If)30 b(each)h(BDD)d(v)n(ariable)k +(corresponds)h(to)d(a)g(group)h(of)f(ZDD)e(v)n(ariables,)448 +2110 y(then)34 b(it)e(is)g(often)i(desirable)h(that)e(the)g(groups)h +(of)f(ZDD)d(v)n(ariables)35 b(be)d(in)h(the)g(same)f(order)448 +2223 y(as)g(the)g(corresponding)37 b(BDD)30 b(v)n(ariables.)55 +b(CUDD)30 b(allo)n(ws)i(the)h(ZDD)c(order)k(to)f(track)h(the)448 +2336 y(BDD)27 b(order)j(and)f(vice)g(v)o(ersa.)45 b(T)-7 +b(o)27 b(ha)n(v)o(e)j(the)f(ZDD)d(order)k(track)f(the)g(BDD)e(order)l +(,)k(the)e(ap-)448 2449 y(plication)g(calls)e Fn(Cudd)p +1185 2449 V 34 w(zddRealignEnable)p Fo(.)41 b(The)26 +b(ef)n(fect)i(of)e(this)h(call)g(can)g(be)f(re)n(v)o(ersed)i(by)448 +2562 y(calling)j Fn(Cudd)p 925 2562 V 34 w(zddRealignDisable)p +Fo(.)48 b(When)29 b(ZDD)e(realignment)k(is)e(in)g(ef)n(fect,)i +(automatic)448 2675 y(reordering)c(of)c(ZDDs)f(should)j(be)f(disabled.) +448 2924 y Fi(3.16)99 b(Hooks)448 3098 y Fo(Hooks)22 +b(in)f(CUDD)d(are)k(lists)f(of)g(application-speci\002ed)27 +b(functions)c(to)e(be)g(run)g(on)h(certain)g(oc-)448 +3211 y(casions.)29 b(Each)18 b(hook)h(is)f(identi\002ed)i(by)e(a)g +(constant)i(of)e(the)g(enumerated)j(type)d Fn(Cudd)p +3125 3211 V 34 w(HookT)-7 b(ype)p Fo(.)448 3324 y(In)24 +b(V)-10 b(ersion)24 b(2.5.0)g(hooks)h(are)e(de\002ned)i(for)e(these)i +(occasions:)p Black 585 3512 a Fm(\017)p Black 46 w Fo(before)f +(garbage)h(collection)i(\(CUDD)p 1916 3512 V 31 w(PRE)p +2115 3512 V 32 w(GC)p 2274 3512 V 32 w(HOOK\);)p Black +585 3700 a Fm(\017)p Black 46 w Fo(after)d(garbage)h(collection)h +(\(CUDD)p 1850 3700 V 32 w(POST)p 2106 3700 V 31 w(GC)p +2264 3700 V 32 w(HOOK\);)p Black 585 3887 a Fm(\017)p +Black 46 w Fo(before)e(v)n(ariable)i(reordering)g(\(CUDD)p +1939 3887 V 32 w(PRE)p 2139 3887 V 31 w(REORDERING)p +2759 3887 V 30 w(HOOK\);)p Black 585 4075 a Fm(\017)p +Black 46 w Fo(after)e(v)n(ariable)h(reordering)h(\(CUDD)p +1873 4075 V 32 w(POST)p 2129 4075 V 31 w(REORDERING)p +2749 4075 V 30 w(HOOK\).)448 4262 y(The)e(current)i(implementation)i +(of)c(hooks)i(is)e(e)o(xperimental.)34 b(A)24 b(function)i(added)g(to)e +(a)g(hook)448 4375 y(recei)n(v)o(es)c(a)e(pointer)i(to)e(the)g(manager) +l(,)j(a)d(pointer)i(to)e(a)g(constant)i(string,)h(and)d(a)g(pointer)i +(to)e(v)n(oid)448 4488 y(as)27 b(ar)n(guments;)j(it)d(must)f(return)i +(1)e(if)g(successful;)31 b(0)c(otherwise.)39 b(The)26 +b(second)i(ar)n(gument)g(is)448 4601 y(one)21 b(of)f(\223DD,)-6 +b(\224)19 b(\223BDD,)-6 b(\224)18 b(and)j(\223ZDD.)-6 +b(\224)18 b(This)i(allo)n(ws)h(the)f(hook)h(functions)i(to)d(tell)h +(the)f(type)h(of)448 4714 y(diagram)f(for)f(which)h(reordering)h(or)e +(garbage)h(collection)i(tak)o(es)e(place.)28 b(The)19 +b(third)g(ar)n(gument)448 4827 y(v)n(aries)30 b(depending)h(on)e(the)g +(hook.)45 b(The)28 b(hook)h(functions)i(called)f(before)g(or)f(after)g +(garbage)448 4940 y(collection)d(do)d(not)g(use)g(it.)28 +b(The)23 b(hook)h(functions)h(called)f(before)g(reordering)i(are)d +(passed,)h(in)p Black 1897 5225 a(21)p Black eop end +%%Page: 22 22 +TeXDict begin 22 21 bop Black Black 448 573 a Fo(addition)32 +b(to)d(the)h(pointer)h(to)f(the)g(manager)l(,)i(also)e(the)g(method)g +(used)h(for)e(reordering.)50 b(The)448 686 y(hook)27 +b(functions)h(called)f(after)f(reordering)j(are)d(passed)h(the)f(start) +g(time.)35 b(T)-7 b(o)25 b(add)h(a)f(function)448 799 +y(to)e(a)g(hook,)g(one)h(uses)f Fn(Cudd)p 1363 799 28 +4 v 34 w(AddHook)r Fo(.)29 b(The)22 b(function)j(of)e(a)g(gi)n(v)o(en)g +(hook)h(are)f(called)h(in)f(the)448 912 y(order)k(in)e(which)h(the)o(y) +g(were)f(added)i(to)f(the)f(hook.)36 b(F)o(or)25 b(sample)h(hook)g +(functions,)j(one)d(may)448 1024 y(look)f(at)e Fn(Cudd)p +922 1024 V 34 w(StdPr)m(eReor)m(dHook)k Fo(and)d Fn(Cudd)p +1990 1024 V 34 w(StdP)-7 b(ostReor)m(dHook)r Fo(.)448 +1274 y Fi(3.17)99 b(T)n(imeouts)26 b(and)f(Limits)448 +1448 y Fo(It)19 b(is)h(possible)h(to)f(set)f(a)g(time)g(limit)h(for)f +(a)g(manger)h(with)g Fn(Cudd)p 2413 1448 V 33 w(SetT)-5 +b(imeLimit)r Fo(.)27 b(Once)20 b(set,)g(the)448 1561 +y(time)g(a)n(v)n(ailable)i(to)e(the)h(manager)g(can)f(be)g(modi\002ed)h +(through)h(other)f(API)d(functions.)31 b(CUDD)448 1674 +y(checks)e(for)e(e)o(xpiration)i(periodically)-6 b(.)43 +b(When)27 b(time)g(has)g(e)o(xpired,)j(it)c(returns)j(NULL)24 +b(from)448 1787 y(the)29 b(call)h(in)e(progress,)k(b)n(ut)e(it)e(lea)n +(v)o(es)i(the)f(manager)h(in)f(a)f(consistent)k(state.)45 +b(The)28 b(in)l(v)n(oking)448 1900 y(application)f(must)d(be)f +(designed)j(to)d(handle)j(the)d(NULL)e(v)n(alues)k(returned.)589 +2013 y(When)35 b(reordering,)k(if)34 b(a)g(timout)h(is)f(approaching,) +41 b(CUDD)31 b(will)j(quit)h(reordering)i(to)448 2125 +y(gi)n(v)o(e)24 b(the)g(application)i(a)e(chance)h(to)e(\002nish)h +(some)g(computation.)589 2238 y(It)31 b(is)h(also)f(possible)j(to)d(in) +l(v)n(ok)o(e)j(some)d(functions)j(that)e(return)g(NULL)d(if)i(the)o(y)h +(cannot)448 2351 y(complete)k(without)f(creating)i(more)d(than)h(a)f +(set)g(number)h(of)g(nodes.)62 b(See,)36 b(for)e(instance,)448 +2464 y Fn(Cudd)p 649 2464 V 34 w(bddAndLimit)r Fo(.)448 +2713 y Fi(3.18)99 b(The)26 b(SIS/VIS)f(Interface)448 +2888 y Fo(The)j(CUDD)d(package)30 b(contains)f(interf)o(ace)h +(functions)h(that)d(emulate)g(the)g(beha)n(vior)i(of)e(the)448 +3001 y(original)i(BDD)c(package)k(used)f(in)f(SIS)e([17)q(])i(and)g(in) +g(the)g(ne)n(wer)g(VIS)2719 2968 y Fg(3)2783 3001 y Fo([4].)42 +b(Ho)n(w)26 b(to)i(b)n(uild)448 3113 y(VIS)i(with)i(CUDD)d(is)i +(described)j(in)e(the)f(installation)k(documents)f(of)d(VIS.)f(\(V)-10 +b(ersion)32 b(1.1)448 3226 y(and)24 b(later)-5 b(.\))448 +3472 y Fp(3.18.1)93 b(Using)22 b(the)h(CUDD)f(P)o(ackage)i(in)e(SIS)448 +3646 y Fo(This)32 b(section)h(describes)h(ho)n(w)d(to)h(b)n(uild)g(SIS) +f(with)g(the)h(CUDD)d(package.)55 b(Let)31 b Fh(SISDIR)448 +3759 y Fo(designate)41 b(the)d(root)h(of)f(the)g(directory)j(hierarchy) +f(where)e(the)h(sources)g(for)g(SIS)d(reside.)448 3872 +y(Let)27 b Fh(CUDDDIR)d Fo(be)j(the)h(root)g(of)g(the)f(directory)j +(hierarchy)g(where)e(the)f(distrib)n(ution)32 b(of)27 +b(the)448 3985 y(CUDD)21 b(package)k(resides.)30 b(T)-7 +b(o)22 b(b)n(uild)i(SIS)d(with)i(the)g(CUDD)e(package,)k(follo)n(w)e +(these)h(steps.)p Black 562 4173 a(1.)p Black 46 w(Create)g +(directories)i Fh(SISDIR/sis/cudd)16 b Fo(and)24 b Fh(SISDIR/sis/mtr)p +Fo(.)p Black 562 4360 a(2.)p Black 46 w(Cop)o(y)18 b(all)g(\002les)g +(from)g Fh(CUDDDIR/cudd)12 b Fo(and)18 b Fh(CUDDDIR/sis)13 +b Fo(to)18 b Fh(SISDIR/sis/cud)o(d)676 4473 y Fo(and)24 +b(all)f(\002les)g(from)h Fh(CUDDDIR/mtr)18 b Fo(to)23 +b Fh(SISDIR/sis/mtr)p Fo(.)p Black 562 4661 a(3.)p Black +46 w(Cop)o(y)35 b Fh(CUDDDIR/cudd/d)o(oc)o(/c)o(ud)o(d.d)o(oc)27 +b Fo(to)35 b Fh(SISDIR/sis/cud)o(d)p Fo(;)f(also)676 +4774 y(cop)o(y)24 b Fh(CUDDDIR/mtr/doc)o(/m)o(tr)o(.do)o(c)16 +b Fo(to)24 b Fh(SISDIR/sis/mtr)o Fo(.)p Black 448 4855 +1196 4 v 554 4911 a Ff(3)583 4942 y Fe(http://vlsi.Colorado.EDU/)18 +b(vis/)p Black Black 1897 5225 a Fo(22)p Black eop end +%%Page: 23 23 +TeXDict begin 23 22 bop Black Black Black 562 573 a Fo(4.)p +Black 46 w(In)38 b Fh(SISDIR/sis/cud)o(d)31 b Fo(mak)o(e)39 +b Fh(bdd.h)c Fo(a)j(symbolic)h(link)g(to)f Fh(cuddBdd.h)p +Fo(.)676 686 y(\(That)23 b(is:)29 b Fh(ln)54 b(-s)g(cuddBdd.h)c(bdd.h)p +Fo(.\))p Black 562 873 a(5.)p Black 46 w(In)27 b Fh(SISDIR/sis/cudd)20 +b Fo(delete)29 b Fh(Makefile)23 b Fo(and)28 b(rename)h +Fh(Makefile.sis)676 986 y Fo(as)23 b Fh(Makefile)p Fo(.)h(Do)f(the)h +(same)f(in)h Fh(SISDIR/sis/mtr)p Fo(.)p Black 562 1174 +a(6.)p Black 46 w(Cop)o(y)18 b Fh(CUDDDIR/sis/st.)o([c)o(h])11 +b Fo(and)18 b Fh(CUDDDIR/st/doc/)o(st)o(.d)o(oc)11 b +Fo(to)18 b Fh(SISDIR/sis/st)p Fo(.)676 1287 y(\(This)29 +b(will)h(o)o(v)o(erwrite)h(the)f(original)h(\002les:)42 +b(Y)-10 b(ou)29 b(may)h(w)o(ant)g(to)g(sa)n(v)o(e)g(them)g(before-)676 +1400 y(hand.\))p Black 562 1587 a(7.)p Black 46 w(From)17 +b Fh(CUDDDIR/util)12 b Fo(cop)o(y)19 b Fh(datalimit.c)12 +b Fo(to)18 b Fh(SISDIR/sis/util)o Fo(.)i(Up-)676 1700 +y(date)30 b Fh(util.h)d Fo(and)k Fh(Makefile)26 b Fo(in)k +Fh(SISDIR/sis/uti)o(l)p Fo(.)42 b(Speci\002cally)-6 b(,)33 +b(add)676 1813 y(the)38 b(declaration)k Fh(EXTERN)52 +b(long)g(getSoftDataLimi)o(t\(\))o(;)39 b Fo(to)f Fh(util.h)676 +1926 y Fo(and)24 b(add)g Fh(datalimit.c)17 b Fo(to)24 +b(the)g(list)f(of)h(source)h(\002les)e(\(PSRC\))f(in)h +Fh(Makefile)p Fo(.)p Black 562 2114 a(8.)p Black 46 w(In)g +Fh(SISDIR/sis)17 b Fo(remo)o(v)o(e)23 b(the)h(link)f(from)g +Fh(bdd)e Fo(to)i Fh(bdd)p 2578 2114 28 4 v 31 w(cmu)e +Fo(or)i Fh(bdd)p 3058 2114 V 32 w(ucb)d Fo(\(that)676 +2227 y(is,)36 b Fh(rm)54 b(bdd)p Fo(\))32 b(and)j(mak)o(e)f +Fh(bdd)e Fo(a)i(symbolic)i(link)f(to)f Fh(cudd)p Fo(.)58 +b(\(That)35 b(is:)50 b Fh(ln)k(-s)676 2340 y(cudd)e(bdd)p +Fo(.\))p Black 562 2527 a(9.)p Black 46 w(Still)17 b(in)h +Fh(SISDIR/sis)p Fo(,)c(edit)19 b Fh(Makefile)p Fo(,)14 +b Fh(Makefile.oct)p Fo(,)f(and)18 b Fh(Makefile.nooct)p +Fo(.)676 2640 y(In)23 b(all)h(three)g(\002les)f(add)h(mtr)f(to)h(the)g +(list)g(of)f(directories)j(to)e(be)f(made)h(\(DIRS\).)p +Black 517 2828 a(10.)p Black 46 w(In)18 b Fh(SISDIR/sis/inc)o(lu)o(de) +11 b Fo(mak)o(e)18 b Fh(mtr.h)d Fo(a)j(symbolic)h(link)g(to)f +Fh(../mtr/mtr.h)p Fo(.)p Black 517 3015 a(11.)p Black +46 w(In)g Fh(SISDIR/sis/doc)10 b Fo(mak)o(e)19 b Fh(cudd.doc)13 +b Fo(a)18 b(symbolic)i(link)e(to)g Fh(../cudd/cudd.doc)676 +3128 y Fo(and)32 b Fh(mtr.doc)d Fo(a)j(symbolic)h(link)g(to)g +Fh(../mtr/mtr.doc)o Fo(.)48 b(\(That)33 b(is:)46 b Fh(ln)54 +b(-s)676 3241 y(../cudd/cudd.d)o(oc)48 b(.;)53 b(ln)h(-s)g +(../mtr/mtr.doc)48 b(.)p Fo(.\))p Black 517 3429 a(12.)p +Black 46 w(From)25 b Fh(SISDIR)e Fo(do)j Fh(make)53 b(clean)23 +b Fo(follo)n(wed)k(by)f Fh(make)53 b(-i)p Fo(.)35 b(This)26 +b(should)i(cre-)676 3542 y(ate)23 b(a)g(w)o(orking)i(cop)o(y)g(of)e +(SIS)f(that)i(uses)h(the)e(CUDD)f(package.)589 3729 y(The)35 +b(replacement)j(for)d(the)h Fh(st)d Fo(library)k(is)e(because)i(the)e +(v)o(ersion)i(shipped)g(with)e(the)448 3842 y(CUDD)22 +b(package)27 b(tests)e(for)f(out-of-memory)j(conditions.)35 +b(Notice)24 b(that)h(the)g(v)o(ersion)h(of)e(the)448 +3955 y Fh(st)32 b Fo(library)k(to)e(be)f(used)i(for)f(replacement)j(is) +c(not)h(the)h(one)f(used)h(for)f(the)g(normal)g(b)n(uild,)448 +4068 y(because)26 b(the)e(latter)g(has)g(been)h(modi\002ed)f(for)g(C++) +f(compatibility)-6 b(.)32 b(The)23 b(abo)o(v)o(e)h(installation)448 +4181 y(procedure)34 b(has)e(been)h(tested)f(on)g(SIS)e(1.3.)52 +b(SIS)30 b(can)i(be)g(obtained)h(via)f(anon)o(ymous)h(FTP)448 +4294 y(from)18 b Fh(ic.eecs.berkele)o(y.e)o(du)o Fo(.)i(T)-7 +b(o)17 b(b)n(uild)j(SIS)c(1.3,)j(you)g(need)g Fh(sis-1.2.tar.Z)448 +4407 y Fo(and)g Fh(sis-1.2.patch1.Z)o Fo(.)12 b(When)19 +b(compiling)h(on)f(a)f(DEC)f(Alpha,)i(you)h(should)g(add)f(the)448 +4520 y Fh(-ieee)p 728 4520 V 31 w(with)p 979 4520 V 31 +w(no)p 1120 4520 V 31 w(inexact)e Fo(\003ag.)27 b(\(See)20 +b(Section)h(3.5.2.\))28 b(Refer)20 b(to)g(the)h Fh(Makefile)15 +b Fo(in)448 4633 y(the)24 b(top)g(le)n(v)o(el)g(directory)i(of)d(the)h +(distrib)n(ution)j(for)d(ho)n(w)f(to)g(compile)i(with)e(32-bit)i +(pointers.)p Black 1897 5225 a(23)p Black eop end +%%Page: 24 24 +TeXDict begin 24 23 bop Black Black 448 573 a Fi(3.19)99 +b(Writing)25 b(Decision)f(Diagrams)g(to)h(a)g(File)448 +747 y Fo(The)c(CUDD)e(package)k(pro)o(vides)g(se)n(v)o(eral)f +(functions)i(to)d(write)g(decision)j(diagrams)e(to)f(a)g(\002le.)448 +860 y Fn(Cudd)p 649 860 28 4 v 34 w(DumpBlif)35 b Fo(writes)23 +b(a)f(\002le)g(in)g Fn(blif)37 b Fo(format.)28 b(It)23 +b(is)f(restricted)j(to)d(BDDs.)27 b(The)22 b(diagrams)448 +973 y(are)j(written)g(as)f(a)g(netw)o(ork)i(of)e(multiple)o(x)o(ers,)i +(one)f(multiple)o(x)o(er)h(for)f(each)g(internal)h(node)f(of)448 +1086 y(the)f(BDD.)589 1199 y Fn(Cudd)p 790 1199 V 34 +w(DumpDot)37 b Fo(produces)i(input)e(suitable)h(to)e(the)g(graph-dra)o +(wing)j(program)e Fn(dot)3399 1166 y Fg(4)448 1312 y +Fo(written)29 b(by)g(Eleftherios)h(K)m(outso\002os)g(and)f(Stephen)g +(C.)e(North.)43 b(An)28 b(e)o(xample)h(of)g(dra)o(wing)448 +1425 y(produced)f(by)d(dot)g(from)g(the)g(output)h(of)f +Fn(Cudd)p 1959 1425 V 34 w(DumpDot)h Fo(is)e(sho)n(wn)i(in)e(Figure)i +(1.)32 b(It)25 b(is)f(re-)448 1537 y(stricted)j(to)d(BDDs)f(and)h +(ADDs.)30 b Fn(Cudd)p 1726 1537 V 34 w(zddDumpDot)d Fo(is)d(the)h +(analog)h(of)e Fn(Cudd)p 3050 1537 V 34 w(DumpDot)448 +1650 y Fo(for)g(ZDDs.)589 1763 y Fn(Cudd)p 790 1763 V +34 w(DumpDaV)-7 b(inci)41 b Fo(produces)i(input)f(suitable)g(to)f(the)g +(graph-dra)o(wing)i(program)448 1876 y Fn(daV)-7 b(inci)722 +1843 y Fg(5)799 1876 y Fo(de)n(v)o(eloped)40 b(at)d(the)i(Uni)n(v)o +(ersity)g(of)f(Bremen.)71 b(It)38 b(is)f(restricted)k(to)d(BDDs)e(and) +448 1989 y(ADDs.)589 2102 y(Functions)f(are)d(also)h(a)n(v)n(ailable)h +(to)f(produce)h(the)e(input)i(format)f(of)f Fn(DDcal)g +Fo(\(see)h(Sec-)448 2215 y(tion)24 b(2.2\))g(and)g(f)o(actored)i +(forms.)448 2464 y Fi(3.20)99 b(Sa)n(ving)25 b(and)g(Restoring)g(BDDs) +448 2638 y Fo(The)e Fn(dddmp)858 2605 y Fg(6)919 2638 +y Fo(library)i(by)e(Gianpiero)i(Cabodi)f(and)g(Stef)o(ano)g(Quer)f +(allo)n(ws)g(a)g(CUDD)e(appli-)448 2751 y(cation)30 b(to)e(sa)n(v)o(e)h +(BDDs)d(to)j(disk)g(in)f(compact)h(form)f(for)h(later)g(retrie)n(v)n +(al.)44 b(See)28 b(the)g(library')-5 b(s)448 2864 y(o)n(wn)23 +b(documentation)k(for)d(the)g(details.)448 3157 y Fq(4)120 +b(Pr)n(ogrammer')l(s)27 b(Manual)448 3364 y Fo(This)g(section)i(pro)o +(vides)g(additional)h(detail)e(on)f(the)g(w)o(orking)i(of)e(the)g(CUDD) +e(package)k(and)448 3477 y(on)37 b(the)g(programming)h(con)l(v)o +(entions)i(follo)n(wed)e(in)e(its)h(writing.)68 b(The)36 +b(additional)j(detail)448 3590 y(should)21 b(help)f(those)h(who)e(w)o +(ant)g(to)h(write)f(procedures)j(that)e(directly)h(manipulate)h(the)e +(CUDD)448 3703 y(data)k(structures.)448 3952 y Fi(4.1)99 +b(Compiling)25 b(and)g(Linking)448 4126 y Fo(If)32 b(you)h(plan)h(to)e +(use)h(the)f(CUDD)f(package)j(as)e(a)g(clear)i(box)f(\(for)f(instance,) +37 b(you)c(w)o(ant)f(to)448 4239 y(write)24 b(a)f(procedure)j(that)e +(tra)n(v)o(erses)i(a)d(decision)j(diagram\))f(you)f(need)g(to)f(add)p +Black Black 448 4427 a Fh(#include)51 b("cuddInt.h")p +Black 448 4491 1196 4 v 554 4546 a Ff(4)583 4578 y Fe(http://www)-5 +b(.research.att.com/sw/tools/graphviz)554 4640 y Ff(5)583 +4671 y Fe(ftp://ftp.uni-bremen.de/pub/graphics/daV)l(inci)554 +4733 y Ff(6)583 4764 y Fe(ftp://ftp.polito.it/pub/research/dddmp/)p +Black Black 1897 5225 a Fo(24)p Black eop end +%%Page: 25 25 +TeXDict begin 25 24 bop Black Black Black 721 4226 a +@beginspecial 66 @llx 36 @lly 547 @urx 757 @ury 4393 +@rhi @setspecial +%%BeginDocument: phase.ps +%!PS-Adobe-2.0 +%%Creator: dot version 95 (4-10-95) +%%For: (fabio) Fabio Somenzi,OT4-11,2-3466,ECE faculty +%%Title: DD +%%Pages: (atend) +%%BoundingBox: 66 36 547 757 +%%EndComments +%%BeginProlog +save +/DotDict 200 dict def +DotDict begin + +%%BeginResource: procset +/coord-font-family /Times-Roman def +/default-font-family /Times-Roman def +/coordfont coord-font-family findfont 8 scalefont def + +/InvScaleFactor 1.0 def +/set_scale { + dup 1 exch div /InvScaleFactor exch def + dup scale +} bind def + +% styles +/solid { } bind def +/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def +/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def +/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def +/bold { 2 setlinewidth } bind def +/filled { } bind def +/unfilled { } bind def +/rounded { } bind def +/diagonals { } bind def + +% hooks for setting color +/nodecolor { sethsbcolor } bind def +/edgecolor { sethsbcolor } bind def +/graphcolor { sethsbcolor } bind def +/nopcolor {pop pop pop} bind def + +/beginpage { % i j npages + /npages exch def + /j exch def + /i exch def + /str 10 string def + npages 1 gt { + gsave + coordfont setfont + 0 0 moveto + (() show i str cvs show (,) show j str cvs show ()) show + grestore + } if +} bind def + +/set_font { + findfont exch + scalefont setfont +} def + +/arrowhead { + /arrowwidth exch def + /arrowlength exch def + gsave + 3 1 roll + translate + rotate + newpath + arrowlength arrowwidth 2 div moveto + 0 0 lineto + arrowlength arrowwidth -2 div lineto + closepath fill + stroke + grestore +} def + +% draw aligned label in bounding box aligned to current point +% alignfactor tells what fraction to place on the left. +% -.5 is centered. +/alignedtext { % text labelwidth fontsz alignfactor + /alignfactor exch def + /fontsz exch def + /width exch def + /text exch def + gsave + % even if node or edge is dashed, don't paint text with dashes + [] 0 setdash + currentpoint newpath moveto + text stringwidth pop + alignfactor mul fontsz -.3 mul rmoveto + text show + grestore +} def + +/boxprim { % xcorner ycorner xsize ysize + 4 2 roll + moveto + 2 copy + exch 0 rlineto + 0 exch rlineto + pop neg 0 rlineto + closepath +} bind def + +/ellipse_path { + /ry exch def + /rx exch def + /y exch def + /x exch def + matrix currentmatrix + newpath + x y translate + rx ry scale + 0 0 1 0 360 arc + setmatrix +} bind def + +/endpage { showpage } bind def + +/layercolorseq + [ % layer color sequence - darkest to lightest + [0 0 0] + [.2 .8 .8] + [.4 .8 .8] + [.6 .8 .8] + [.8 .8 .8] + ] +def + +/setlayer {/maxlayer exch def /curlayer exch def + layercolorseq curlayer get + aload pop sethsbcolor + /nodecolor {nopcolor} def + /edgecolor {nopcolor} def + /graphcolor {nopcolor} def +} bind def + +/onlayer { curlayer ne {invis} if } def + +/onlayers { + /myupper exch def + /mylower exch def + curlayer mylower lt + curlayer myupper gt + or + {invis} if +} def + +/curlayer 0 def + +%%EndResource +%%EndProlog +%%BeginSetup +14 default-font-family set_font +% /arrowlength 10 def +% /arrowwidth 5 def +%%EndSetup +%%Page: 1 (atend) +%%PageBoundingBox: 66 36 547 757 +gsave +65 35 482 722 boxprim clip newpath +66 36 translate +0 0 1 beginpage +0.7407 set_scale +0 0 translate 0 rotate +0.000 0.000 0.000 graphcolor +14.00 /Times-Roman set_font + +% CONST NODES +gsave 10 dict begin +invis +gsave 10 dict begin +55 19 moveto (CONST NODES) 96 14.00 -0.50 alignedtext +end grestore +end grestore + +% a110 +gsave 10 dict begin +gsave 10 dict begin +55 883 moveto (a110) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a111 +gsave 10 dict begin +gsave 10 dict begin +55 811 moveto (a111) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a110 -> a111 +gsave 10 dict begin +invis +newpath 55 864 moveto +55 853 55 839 55 828 curveto +stroke +end grestore + +% a210 +gsave 10 dict begin +gsave 10 dict begin +55 739 moveto (a210) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a111 -> a210 +gsave 10 dict begin +invis +newpath 55 792 moveto +55 781 55 767 55 756 curveto +stroke +end grestore + +% a211 +gsave 10 dict begin +gsave 10 dict begin +55 667 moveto (a211) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a210 -> a211 +gsave 10 dict begin +invis +newpath 55 720 moveto +55 709 55 695 55 684 curveto +stroke +end grestore + +% a310 +gsave 10 dict begin +gsave 10 dict begin +55 595 moveto (a310) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a211 -> a310 +gsave 10 dict begin +invis +newpath 55 648 moveto +55 637 55 623 55 612 curveto +stroke +end grestore + +% a311 +gsave 10 dict begin +gsave 10 dict begin +55 523 moveto (a311) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a310 -> a311 +gsave 10 dict begin +invis +newpath 55 576 moveto +55 565 55 551 55 540 curveto +stroke +end grestore + +% a410 +gsave 10 dict begin +gsave 10 dict begin +55 451 moveto (a410) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a311 -> a410 +gsave 10 dict begin +invis +newpath 55 504 moveto +55 493 55 479 55 468 curveto +stroke +end grestore + +% a411 +gsave 10 dict begin +gsave 10 dict begin +55 379 moveto (a411) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a410 -> a411 +gsave 10 dict begin +invis +newpath 55 432 moveto +55 421 55 407 55 396 curveto +stroke +end grestore + +% a510 +gsave 10 dict begin +gsave 10 dict begin +55 307 moveto (a510) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a411 -> a510 +gsave 10 dict begin +invis +newpath 55 360 moveto +55 349 55 335 55 324 curveto +stroke +end grestore + +% a511 +gsave 10 dict begin +gsave 10 dict begin +55 235 moveto (a511) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a510 -> a511 +gsave 10 dict begin +invis +newpath 55 288 moveto +55 277 55 263 55 252 curveto +stroke +end grestore + +% a610 +gsave 10 dict begin +gsave 10 dict begin +55 163 moveto (a610) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a511 -> a610 +gsave 10 dict begin +invis +newpath 55 216 moveto +55 205 55 191 55 180 curveto +stroke +end grestore + +% a611 +gsave 10 dict begin +gsave 10 dict begin +55 91 moveto (a611) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a610 -> a611 +gsave 10 dict begin +invis +newpath 55 144 moveto +55 133 55 119 55 108 curveto +stroke +end grestore + +% a611 -> CONST NODES +gsave 10 dict begin +invis +newpath 55 72 moveto +55 61 55 47 55 36 curveto +stroke +end grestore + +% o +gsave 10 dict begin +newpath 511 972 moveto +457 972 lineto +457 936 lineto +511 936 lineto +closepath +stroke +gsave 10 dict begin +484 955 moveto (o) 7 14.00 -0.50 alignedtext +end grestore +end grestore + +% a00 +gsave 10 dict begin +484 882 27 18 ellipse_path +stroke +gsave 10 dict begin +484 883 moveto (a00) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% o -> a00 +gsave 10 dict begin +solid +newpath 484 936 moveto +484 925 484 911 484 900 curveto +stroke +end grestore + +% 9fc +gsave 10 dict begin +448 810 27 18 ellipse_path +stroke +gsave 10 dict begin +448 811 moveto (9fc) 17 14.00 -0.50 alignedtext +end grestore +end grestore + +% a00 -> 9fc +newpath 475 865 moveto +470 853 462 839 457 827 curveto +stroke + +% 9ff +gsave 10 dict begin +520 810 27 18 ellipse_path +stroke +gsave 10 dict begin +520 811 moveto (9ff) 16 14.00 -0.50 alignedtext +end grestore +end grestore + +% a00 -> 9ff +gsave 10 dict begin +dashed +newpath 493 865 moveto +498 853 506 839 511 827 curveto +stroke +end grestore + +% 995 +gsave 10 dict begin +453 738 27 18 ellipse_path +stroke +gsave 10 dict begin +453 739 moveto (995) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fc -> 995 +gsave 10 dict begin +dashed +newpath 449 792 moveto +450 781 451 767 452 756 curveto +stroke +end grestore + +% 9fb +gsave 10 dict begin +381 738 27 18 ellipse_path +stroke +gsave 10 dict begin +381 739 moveto (9fb) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fc -> 9fb +newpath 433 794 moveto +422 782 407 765 396 753 curveto +stroke + +% 9fe +gsave 10 dict begin +584 738 27 18 ellipse_path +stroke +gsave 10 dict begin +584 739 moveto (9fe) 17 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ff -> 9fe +gsave 10 dict begin +dashed +newpath 534 794 moveto +545 782 560 765 570 753 curveto +stroke +end grestore + +% 95f +gsave 10 dict begin +512 666 27 18 ellipse_path +stroke +gsave 10 dict begin +512 667 moveto (95f) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ff -> 95f +newpath 519 792 moveto +518 764 515 712 513 684 curveto +stroke + +% 994 +gsave 10 dict begin +347 594 27 18 ellipse_path +stroke +gsave 10 dict begin +347 595 moveto (994) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 995 -> 994 +newpath 432 727 moveto +407 714 370 693 363 684 curveto +356 675 351 636 349 612 curveto +stroke + +% 946 +gsave 10 dict begin +newpath 401 36 moveto +347 36 lineto +347 0 lineto +401 0 lineto +closepath +stroke +gsave 10 dict begin +374 19 moveto (1) 7 14.00 -0.50 alignedtext +end grestore +end grestore + +% 995 -> 946 +gsave 10 dict begin +dotted +newpath 584 594 moveto +589 570 587 545 584 522 curveto +stroke +newpath 453 720 moveto +454 698 458 662 473 648 curveto +498 621 544 628 577 612 curveto +582 609 582 600 584 594 curveto +stroke +end grestore + +% 9f7 +gsave 10 dict begin +292 666 27 18 ellipse_path +stroke +gsave 10 dict begin +292 667 moveto (9f7) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fb -> 9f7 +newpath 363 724 moveto +347 711 325 693 309 680 curveto +stroke + +% 9fa +gsave 10 dict begin +402 666 27 18 ellipse_path +stroke +gsave 10 dict begin +402 667 moveto (9fa) 17 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fb -> 9fa +gsave 10 dict begin +dashed +newpath 386 720 moveto +389 709 393 695 397 684 curveto +stroke +end grestore + +% 9fd +gsave 10 dict begin +584 666 27 18 ellipse_path +stroke +gsave 10 dict begin +584 667 moveto (9fd) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fe -> 9fd +newpath 584 720 moveto +584 709 584 695 584 684 curveto +stroke + +% 9fe -> 946 +gsave 10 dict begin +dotted +newpath 600 723 moveto +611 711 625 696 632 684 curveto +637 673 637 658 632 648 curveto +632 648 584 594 584 594 curveto +stroke +end grestore + +% 9f7 -> 994 +gsave 10 dict begin +dashed +newpath 304 650 moveto +313 638 326 622 335 610 curveto +stroke +end grestore + +% 9f6 +gsave 10 dict begin +275 594 27 18 ellipse_path +stroke +gsave 10 dict begin +275 595 moveto (9f6) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f7 -> 9f6 +newpath 288 648 moveto +285 637 282 623 279 612 curveto +stroke + +% 9f9 +gsave 10 dict begin +529 594 27 18 ellipse_path +stroke +gsave 10 dict begin +529 595 moveto (9f9) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fa -> 9f9 +gsave 10 dict begin +dashed +newpath 423 654 moveto +447 641 485 619 508 606 curveto +stroke +end grestore + +% 95e +gsave 10 dict begin +457 522 27 18 ellipse_path +stroke +gsave 10 dict begin +457 523 moveto (95e) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fa -> 95e +newpath 465 594 moveto +464 579 462 556 460 540 curveto +stroke +newpath 420 652 moveto +439 638 464 614 465 594 curveto +stroke + +% 95f -> 95e +newpath 497 651 moveto +483 636 464 612 465 594 curveto +stroke + +% 95f -> 946 +gsave 10 dict begin +dotted +newpath 531 653 moveto +551 639 579 615 584 594 curveto +stroke +end grestore + +% 9fd -> 9f9 +newpath 572 650 moveto +563 638 550 622 541 610 curveto +stroke + +% 9fd -> 946 +gsave 10 dict begin +dotted +newpath 582 648 moveto +581 631 580 608 584 594 curveto +stroke +end grestore + +% 993 +gsave 10 dict begin +292 450 27 18 ellipse_path +stroke +gsave 10 dict begin +292 451 moveto (993) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 994 -> 993 +newpath 333 578 moveto +323 566 312 551 308 540 curveto +301 521 296 489 294 468 curveto +stroke + +% 994 -> 946 +gsave 10 dict begin +dotted +newpath 357 577 moveto +371 556 396 519 418 504 curveto +447 482 489 484 522 468 curveto +527 465 527 456 529 450 curveto +stroke +newpath 529 450 moveto +534 426 532 401 529 378 curveto +stroke +end grestore + +% 9f5 +gsave 10 dict begin +347 522 27 18 ellipse_path +stroke +gsave 10 dict begin +347 523 moveto (9f5) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f6 -> 9f5 +gsave 10 dict begin +dashed +newpath 290 579 moveto +302 567 319 550 332 537 curveto +stroke +end grestore + +% 9f2 +gsave 10 dict begin +237 522 27 18 ellipse_path +stroke +gsave 10 dict begin +237 523 moveto (9f2) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f6 -> 9f2 +newpath 266 577 moveto +260 566 252 551 246 539 curveto +stroke + +% 9f8 +gsave 10 dict begin +529 522 27 18 ellipse_path +stroke +gsave 10 dict begin +529 523 moveto (9f8) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f9 -> 9f8 +newpath 529 576 moveto +529 565 529 551 529 540 curveto +stroke + +% 9f9 -> 946 +gsave 10 dict begin +dotted +newpath 546 580 moveto +563 565 587 541 584 522 curveto +stroke +newpath 584 522 moveto +579 492 522 479 529 450 curveto +stroke +end grestore + +% 9f4 +gsave 10 dict begin +474 450 27 18 ellipse_path +stroke +gsave 10 dict begin +474 451 moveto (9f4) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f5 -> 9f4 +gsave 10 dict begin +dashed +newpath 368 510 moveto +392 497 430 475 453 462 curveto +stroke +end grestore + +% 95d +gsave 10 dict begin +402 378 27 18 ellipse_path +stroke +gsave 10 dict begin +402 379 moveto (95d) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f5 -> 95d +newpath 365 508 moveto +384 494 409 470 410 450 curveto +stroke +newpath 410 450 moveto +409 435 407 412 405 396 curveto +stroke + +% 9f2 -> 993 +gsave 10 dict begin +dashed +newpath 249 506 moveto +258 494 271 478 280 466 curveto +stroke +end grestore + +% 9f1 +gsave 10 dict begin +220 450 27 18 ellipse_path +stroke +gsave 10 dict begin +220 451 moveto (9f1) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f2 -> 9f1 +newpath 233 504 moveto +230 493 227 479 224 468 curveto +stroke + +% 95e -> 95d +newpath 442 507 moveto +428 492 409 468 410 450 curveto +stroke + +% 95e -> 946 +gsave 10 dict begin +dotted +newpath 476 509 moveto +496 495 524 471 529 450 curveto +stroke +end grestore + +% 9f8 -> 9f4 +newpath 517 506 moveto +508 494 495 478 486 466 curveto +stroke + +% 9f8 -> 946 +gsave 10 dict begin +dotted +newpath 527 504 moveto +526 487 525 464 529 450 curveto +stroke +end grestore + +% 992 +gsave 10 dict begin +237 306 27 18 ellipse_path +stroke +gsave 10 dict begin +237 307 moveto (992) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 993 -> 992 +newpath 278 434 moveto +268 422 257 407 253 396 curveto +246 377 241 345 239 324 curveto +stroke + +% 993 -> 946 +gsave 10 dict begin +dotted +newpath 474 306 moveto +474 306 474 234 474 234 curveto +stroke +newpath 302 433 moveto +316 412 341 375 363 360 curveto +392 338 434 340 467 324 curveto +472 321 472 312 474 306 curveto +stroke +end grestore + +% 9ed +gsave 10 dict begin +182 378 27 18 ellipse_path +stroke +gsave 10 dict begin +182 379 moveto (9ed) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f1 -> 9ed +newpath 211 433 moveto +205 422 197 407 191 395 curveto +stroke + +% 9f0 +gsave 10 dict begin +292 378 27 18 ellipse_path +stroke +gsave 10 dict begin +292 379 moveto (9f0) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f1 -> 9f0 +gsave 10 dict begin +dashed +newpath 235 435 moveto +247 423 264 406 277 393 curveto +stroke +end grestore + +% 9f3 +gsave 10 dict begin +474 378 27 18 ellipse_path +stroke +gsave 10 dict begin +474 379 moveto (9f3) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f4 -> 9f3 +newpath 474 432 moveto +474 421 474 407 474 396 curveto +stroke + +% 9f4 -> 946 +gsave 10 dict begin +dotted +newpath 491 436 moveto +508 421 532 397 529 378 curveto +stroke +newpath 529 378 moveto +528 371 525 365 522 360 curveto +522 360 474 306 474 306 curveto +stroke +end grestore + +% 9ed -> 992 +gsave 10 dict begin +dashed +newpath 194 362 moveto +203 350 216 334 225 322 curveto +stroke +end grestore + +% 9ec +gsave 10 dict begin +165 306 27 18 ellipse_path +stroke +gsave 10 dict begin +165 307 moveto (9ec) 19 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ed -> 9ec +newpath 178 360 moveto +175 349 172 335 169 324 curveto +stroke + +% 9ef +gsave 10 dict begin +419 306 27 18 ellipse_path +stroke +gsave 10 dict begin +419 307 moveto (9ef) 17 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f0 -> 9ef +gsave 10 dict begin +dashed +newpath 313 366 moveto +337 353 375 331 398 318 curveto +stroke +end grestore + +% 95c +gsave 10 dict begin +347 234 27 18 ellipse_path +stroke +gsave 10 dict begin +347 235 moveto (95c) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f0 -> 95c +newpath 310 364 moveto +329 350 354 326 355 306 curveto +stroke +newpath 355 306 moveto +354 291 352 268 350 252 curveto +stroke + +% 95d -> 95c +newpath 387 363 moveto +373 348 354 324 355 306 curveto +stroke + +% 95d -> 946 +gsave 10 dict begin +dotted +newpath 421 365 moveto +441 351 469 327 474 306 curveto +stroke +end grestore + +% 9f3 -> 9ef +newpath 462 362 moveto +453 350 440 334 431 322 curveto +stroke + +% 9f3 -> 946 +gsave 10 dict begin +dotted +newpath 472 360 moveto +471 343 470 320 474 306 curveto +stroke +end grestore + +% 954 +gsave 10 dict begin +165 162 27 18 ellipse_path +stroke +gsave 10 dict begin +165 163 moveto (954) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 992 -> 954 +newpath 220 234 moveto +214 216 194 192 180 177 curveto +stroke +newpath 233 288 moveto +230 272 224 248 220 234 curveto +stroke + +% 992 -> 946 +gsave 10 dict begin +dotted +newpath 220 234 moveto +220 234 213 144 213 144 curveto +213 144 193 90 193 90 curveto +stroke +end grestore + +% 987 +gsave 10 dict begin +165 234 27 18 ellipse_path +stroke +gsave 10 dict begin +165 235 moveto (987) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ec -> 987 +newpath 165 288 moveto +165 277 165 263 165 252 curveto +stroke + +% 9eb +gsave 10 dict begin +275 234 27 18 ellipse_path +stroke +gsave 10 dict begin +275 235 moveto (9eb) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ec -> 9eb +gsave 10 dict begin +dashed +newpath 184 293 moveto +204 280 236 260 256 247 curveto +stroke +end grestore + +% 9ee +gsave 10 dict begin +419 234 27 18 ellipse_path +stroke +gsave 10 dict begin +419 235 moveto (9ee) 19 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ef -> 9ee +newpath 419 288 moveto +419 277 419 263 419 252 curveto +stroke + +% 9ef -> 946 +gsave 10 dict begin +dotted +newpath 474 234 moveto +477 210 461 184 469 162 curveto +stroke +newpath 435 291 moveto +450 276 471 252 474 234 curveto +stroke +end grestore + +% 987 -> 954 +gsave 10 dict begin +dashed +newpath 165 216 moveto +165 205 165 191 165 180 curveto +stroke +end grestore + +% 987 -> 946 +newpath 193 90 moveto +225 56 305 34 347 24 curveto +stroke +newpath 152 218 moveto +136 197 113 162 126 144 curveto +144 120 173 110 193 90 curveto +stroke + +% 9ea +gsave 10 dict begin +410 162 27 18 ellipse_path +stroke +gsave 10 dict begin +410 163 moveto (9ea) 19 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9eb -> 9ea +gsave 10 dict begin +dashed +newpath 296 223 moveto +321 210 363 187 389 174 curveto +stroke +end grestore + +% 955 +gsave 10 dict begin +374 90 27 18 ellipse_path +stroke +gsave 10 dict begin +374 91 moveto (955) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9eb -> 955 +newpath 293 220 moveto +311 206 338 182 347 162 curveto +stroke +newpath 347 162 moveto +353 147 362 124 368 108 curveto +stroke + +% 95c -> 955 +newpath 344 216 moveto +342 199 341 175 347 162 curveto +stroke + +% 95c -> 946 +gsave 10 dict begin +dotted +newpath 368 222 moveto +372 220 376 217 380 216 curveto +407 203 436 195 462 180 curveto +467 176 466 168 469 162 curveto +stroke +newpath 469 162 moveto +476 139 475 113 469 90 curveto +stroke +end grestore + +% 9ee -> 9ea +newpath 417 216 moveto +415 205 414 191 412 180 curveto +stroke + +% 9ee -> 946 +gsave 10 dict begin +dotted +newpath 432 218 moveto +442 206 454 190 462 180 curveto +465 174 466 168 469 162 curveto +stroke +end grestore + +% 954 -> 946 +newpath 169 144 moveto +174 127 182 101 193 90 curveto +stroke + +% 954 -> 946 +gsave 10 dict begin +dotted +end grestore + +% 9ea -> 955 +newpath 401 145 moveto +396 133 388 119 383 107 curveto +stroke + +% 9ea -> 946 +gsave 10 dict begin +dotted +newpath 429 149 moveto +448 133 474 109 469 90 curveto +stroke +newpath 469 90 moveto +462 66 427 44 401 30 curveto +stroke +end grestore + +% 955 -> 946 +newpath 374 72 moveto +374 61 374 47 374 36 curveto +stroke + +% 955 -> 946 +gsave 10 dict begin +dotted +end grestore +endpage +grestore +%%PageTrailer +%%Trailer +%%Pages: 1 +end +restore +%%EOF + +%%EndDocument + @endspecial 448 4422 a Fo(Figure)34 b(1:)49 b(A)32 b(BDD)f +(representing)37 b(a)c(phase)h(constraint)i(for)e(the)f(optimization)j +(of)d(\002x)o(ed-)448 4535 y(polarity)27 b(Reed-Muller)g(forms.)33 +b(The)24 b(label)i(of)f(each)h(node)f(is)g(the)g(unique)i(part)e(of)g +(the)g(node)448 4648 y(address.)31 b(All)21 b(nodes)j(on)f(the)g(same)f +(le)n(v)o(el)h(correspond)i(to)e(the)g(same)f(v)n(ariable,)i(whose)f +(name)448 4761 y(is)f(sho)n(wn)h(at)f(the)g(left)g(of)g(the)h(diagram.) +29 b(Dotted)23 b(lines)g(indicate)h(complement)g(arcs.)k(Dashed)448 +4874 y(lines)d(indicate)g(re)o(gular)g(\223else\224)g(arcs.)p +Black Black 1897 5225 a(25)p Black eop end +%%Page: 26 26 +TeXDict begin 26 25 bop Black Black 448 573 a Fo(to)24 +b(your)h(source)h(\002les.)k(In)24 b(addition,)i(you)f(should)h(link)e +Fh(libcudd.a)19 b Fo(to)24 b(your)h(e)o(x)o(ecutable.)448 +686 y(Some)20 b(platforms)h(require)h(speci\002c)e(compiler)i(and)e +(link)o(er)h(\003ags.)28 b(Refer)20 b(to)g(the)g Fh(Makefile)448 +799 y Fo(in)k(the)g(top)f(le)n(v)o(el)h(directory)i(of)e(the)f(distrib) +n(ution.)448 1040 y Fi(4.2)99 b(Refer)n(ence)27 b(Counts)448 +1214 y Fo(Garbage)d(collection)i(in)d(the)g(CUDD)d(package)25 +b(is)e(based)h(on)f(reference)i(counts.)30 b(Each)22 +b(node)448 1327 y(stores)j(the)f(sum)f(of)g(the)h(e)o(xternal)h +(references)h(and)e(internal)h(references.)31 b(An)23 +b(internal)i(BDD)448 1440 y(or)33 b(ADD)e(node)i(is)g(created)h(by)f(a) +g(call)g(to)f Fn(cuddUniqueInter)r Fo(,)40 b(an)32 b(internal)j(ZDD)c +(node)i(is)448 1553 y(created)c(by)e(a)g(call)g(to)g +Fn(cuddUniqueInterZdd)r Fo(,)33 b(and)28 b(a)e(terminal)j(node)e(is)g +(created)i(by)e(a)g(call)448 1666 y(to)g Fn(cuddUniqueConst)r +Fo(.)40 b(If)27 b(the)f(node)i(returned)g(by)f(these)g(functions)i(is)d +(ne)n(w)-6 b(,)27 b(its)f(reference)448 1779 y(count)32 +b(is)e(zero.)51 b(The)30 b(function)i(that)g(calls)f +Fn(cuddUniqueInter)r Fo(,)36 b Fn(cuddUniqueInterZdd)r +Fo(,)h(or)448 1892 y Fn(cuddUniqueConst)j Fo(is)35 b(responsible)j(for) +d(increasing)i(the)e(reference)i(count)f(of)f(the)g(node.)448 +2005 y(This)24 b(is)f(accomplished)k(by)c(calling)i Fn(Cudd)p +1823 2005 28 4 v 34 w(Ref)13 b Fo(.)589 2118 y(When)22 +b(a)f(function)i(is)e(no)g(longer)i(needed)f(by)g(an)f(application,)j +(the)e(memory)f(used)h(by)f(its)448 2231 y(diagram)32 +b(can)g(be)f(rec)o(ycled)i(by)e(calling)i Fn(Cudd)p 1986 +2231 V 33 w(Recur)o(siveDer)m(ef)47 b Fo(\(BDDs)30 b(and)i(ADDs\))d(or) +448 2344 y Fn(Cudd)p 649 2344 V 34 w(Recur)o(siveDer)m(efZdd)36 +b Fo(\(ZDDs\).)49 b(These)31 b(functions)i(decrease)g(the)e(reference)i +(count)448 2456 y(of)h(the)h(node)g(passed)g(to)f(them.)61 +b(If)34 b(the)g(reference)i(count)g(becomes)f(0,)h(then)f(tw)o(o)f +(things)448 2569 y(happen:)p Black 562 2718 a(1.)p Black +46 w(The)23 b(node)i(is)f(declared)i(\223dead;\224)g(this)e(entails)h +(increasing)i(the)d(counters)i(of)e(the)g(dead)676 2831 +y(nodes.)56 b(\(One)32 b(counter)i(for)f(the)f(subtable)j(to)d(which)h +(the)g(node)g(belongs,)j(and)d(one)676 2944 y(global)f(counter)h(for)f +(the)f(unique)i(table)f(to)f(which)h(the)f(node)i(belongs.\))54 +b(The)30 b(node)676 3057 y(itself)24 b(is)f(not)h(af)n(fected.)p +Black 562 3229 a(2.)p Black 46 w(The)f(function)i(is)f(recursi)n(v)o +(ely)i(called)f(on)e(the)h(tw)o(o)f(children)j(of)d(the)h(node.)448 +3378 y(F)o(or)35 b(instance,)41 b(if)36 b(the)g(diagram)h(of)f(a)f +(function)j(does)f(not)f(share)h(an)o(y)f(nodes)i(with)d(other)448 +3491 y(diagrams,)k(then)c(calling)h Fn(Cudd)p 1513 3491 +V 33 w(Recur)o(siveDer)m(ef)50 b Fo(or)34 b Fn(Cudd)p +2459 3491 V 34 w(Recur)o(siveDer)m(efZdd)40 b Fo(on)34 +b(its)448 3603 y(root)24 b(will)g(cause)g(all)g(the)g(nodes)h(of)e(the) +h(diagram)g(to)g(become)g(dead.)589 3716 y(When)d(the)f(number)g(of)g +(dead)h(nodes)g(reaches)g(a)f(gi)n(v)o(en)g(le)n(v)o(el)g +(\(dynamically)j(determined)448 3829 y(by)33 b(the)f(package\))j +(garbage)e(collection)i(tak)o(es)f(place.)56 b(During)33 +b(garbage)g(collection)i(dead)448 3942 y(nodes)25 b(are)f(returned)h +(to)f(the)g(node)g(free)g(list.)589 4055 y(When)37 b(a)e(ne)n(w)g(node) +i(is)f(created,)k(it)c(is)g(important)h(to)f(increase)i(its)e +(reference)i(count)448 4168 y(before)25 b(one)f(of)g(the)f(tw)o(o)h +(follo)n(wing)h(e)n(v)o(ents)f(occurs:)p Black 562 4317 +a(1.)p Black 46 w(A)19 b(call)j(to)e Fn(cuddUniqueInter)r +Fo(,)26 b(to)21 b Fn(cuddUniqueInterZdd)r Fo(,)26 b(to)21 +b Fn(cuddUniqueConst)r Fo(,)j(or)676 4430 y(to)f(a)g(function)j(that)e +(may)f(e)n(v)o(entually)j(cause)f(a)e(call)h(to)f(them.)p +Black 562 4602 a(2.)p Black 46 w(A)28 b(call)i(to)f Fn(Cudd)p +1230 4602 V 34 w(Recur)o(siveDer)m(ef)13 b Fo(,)33 b(to)c +Fn(Cudd)p 2186 4602 V 34 w(Recur)o(siveDer)m(efZdd)r +Fo(,)34 b(or)29 b(to)g(a)g(func-)676 4715 y(tion)24 b(that)g(may)f(e)n +(v)o(entually)j(cause)f(a)e(call)h(to)f(them.)448 4863 +y(In)31 b(practice,)j(it)d(is)f(recommended)j(to)e(increase)i(the)e +(reference)i(count)f(as)f(soon)g(as)g(the)g(re-)448 4976 +y(turned)25 b(pointer)h(has)d(been)i(tested)g(for)e(not)h(being)h +(NULL.)p Black 1897 5225 a(26)p Black eop end +%%Page: 27 27 +TeXDict begin 27 26 bop Black Black 448 573 a Fp(4.2.1)92 +b(NULL)21 b(Retur)o(n)h(V)-8 b(alues)448 747 y Fo(The)25 +b(interf)o(ace)i(to)e(the)g(memory)g(management)i(functions)g(\(e.g.,)e +(malloc\))h(used)g(by)f(CUDD)448 860 y(intercepts)k(NULL)c(return)i(v)n +(alues)h(and)f(calls)g(a)f(handler)-5 b(.)40 b(The)26 +b(def)o(ault)i(handler)g(e)o(xits)f(with)448 973 y(an)i(error)h +(message.)47 b(If)29 b(the)g(application)k(does)d(not)f(install)i +(another)g(handler)l(,)h(therefore,)h(a)448 1086 y(NULL)21 +b(return)k(v)n(alue)g(from)e(an)h(e)o(xported)h(function)h(of)d(CUDD)e +(signals)26 b(an)d(internal)j(error)-5 b(.)589 1199 y(If)23 +b(the)f(aplication,)j(ho)n(we)n(v)o(er)l(,)e(installs)i(another)f +(handler)g(that)f(lets)g(e)o(x)o(ecution)h(continue,)448 +1312 y(a)i(NULL)f(pointer)j(returned)g(by)f(an)g(e)o(xported)h +(function)h(typically)g(indicates)g(that)e(the)g(pro-)448 +1425 y(cess)32 b(has)g(run)g(out)g(of)f(memory)-6 b(.)53 +b Fn(Cudd)p 1760 1425 28 4 v 33 w(ReadErr)l(orCode)34 +b Fo(can)d(be)h(used)g(to)f(ascertain)j(the)448 1537 +y(nature)25 b(of)f(the)f(problem.)589 1650 y(An)37 b(application)j +(that)d(tests)h(for)f(the)h(result)g(being)g(NULL)c(can)k(try)f(some)g +(remedial)448 1763 y(action,)25 b(if)e(it)g(runs)h(out)g(of)g(memory)-6 +b(.)28 b(F)o(or)23 b(instance,)i(it)e(may)h(free)g(some)f(memory)h +(that)g(is)f(not)448 1876 y(strictly)29 b(necessary)-6 +b(,)31 b(or)c(try)g(a)g(slo)n(wer)g(algorithm)i(that)f(tak)o(es)g(less) +g(space.)40 b(As)27 b(an)g(e)o(xample,)448 1989 y(CUDD)e(o)o(v)o +(errides)k(the)f(def)o(ault)h(handler)g(when)f(trying)g(to)g(enlar)n +(ge)h(the)f(cache)g(or)f(increase)448 2102 y(the)i(number)g(of)f(slots) +h(of)f(the)h(unique)h(table.)43 b(If)28 b(the)h(allocation)h(f)o(ails,) +g(the)f(package)h(prints)448 2215 y(out)24 b(a)f(message)i(and)f +(continues)i(without)f(resizing)g(the)f(cache.)448 2461 +y Fp(4.2.2)92 b Fa(Cudd)p 928 2461 V 33 w(Recursiv)o(eDeref)35 +b Fp(vs.)23 b Fa(Cudd)p 1901 2461 V 33 w(Deref)448 2635 +y Fo(It)36 b(is)f(often)i(the)f(case)g(that)h(a)e(recursi)n(v)o(e)i +(procedure)i(has)d(to)g(protect)h(the)f(result)h(it)e(is)h(go-)448 +2748 y(ing)j(to)g(return,)k(while)c(it)f(disposes)j(of)d(intermediate)j +(results.)75 b(\(See)38 b(the)h(pre)n(vious)i(dis-)448 +2861 y(cussion)i(on)d(when)h(to)f(increase)j(reference)g(counts.\))81 +b(Once)41 b(the)g(intermediate)i(results)448 2974 y(ha)n(v)o(e)37 +b(been)f(properly)i(disposed)f(of,)i(the)c(\002nal)h(result)h(must)e +(be)h(returned)h(to)f(its)f(pristine)448 3087 y(state,)h(in)d(which)g +(the)g(root)h(node)g(may)e(ha)n(v)o(e)i(a)e(reference)k(count)e(of)e +(0.)57 b(One)32 b(cannot)j(use)448 3200 y Fn(Cudd)p 649 +3200 V 34 w(Recur)o(siveDer)m(ef)49 b Fo(\(or)33 b Fn(Cudd)p +1624 3200 V 34 w(Recur)o(siveDer)m(efZdd)r Fo(\))j(for)d(this)h +(purpose,)j(because)e(it)448 3313 y(may)22 b(erroneously)j(mak)o(e)d +(some)g(nodes)h(dead.)29 b(Therefore,)24 b(the)e(package)i(pro)o(vides) +g(a)d(dif)n(fer)n(-)448 3425 y(ent)k(function:)35 b Fn(Cudd)p +1144 3425 V 33 w(Der)m(ef)13 b Fo(.)33 b(This)25 b(function)i(is)d(not) +i(recursi)n(v)o(e,)g(and)g(does)f(not)h(change)g(the)448 +3538 y(dead)g(node)f(counts.)34 b(Its)25 b(use)g(is)f(almost)h(e)o +(xclusi)n(v)o(ely)i(the)e(one)g(just)g(described:)34 +b(Decreasing)448 3651 y(the)26 b(reference)h(count)g(of)e(the)g(root)h +(of)f(the)h(\002nal)f(result)h(before)h(returning)h(from)d(a)g(recursi) +n(v)o(e)448 3764 y(procedure.)448 4010 y Fp(4.2.3)92 +b(When)22 b(Incr)n(easing)j(the)e(Refer)n(ence)i(Count)d(is)h +(Unnecessary)448 4184 y Fo(When)29 b(a)f(cop)o(y)h(of)f(a)g +(prede\002ned)i(constant)h(or)d(of)g(a)g(simple)h(BDD)d(v)n(ariable)k +(is)e(needed)i(for)448 4297 y(comparison)g(purposes,)g(then)f(calling)g +Fn(Cudd)p 1931 4297 V 33 w(Ref)40 b Fo(is)27 b(not)h(necessary)-6 +b(,)31 b(because)e(these)f(sim-)448 4410 y(ple)j(functions)i(are)d +(guaranteed)k(to)c(ha)n(v)o(e)h(reference)i(counts)f(greater)g(than)f +(0)f(at)g(all)g(times.)448 4523 y(If)35 b(no)g(call)g(to)f +Fn(Cudd)p 1138 4523 V 34 w(Ref)47 b Fo(is)35 b(made,)i(then)f(no)f +(attempt)g(to)g(free)g(the)g(diagram)h(by)f(calling)448 +4636 y Fn(Cudd)p 649 4636 V 34 w(Recur)o(siveDer)m(ef)k +Fo(or)24 b Fn(Cudd)p 1575 4636 V 33 w(Recur)o(siveDer)m(efZdd)29 +b Fo(should)c(be)f(made.)p Black 1897 5225 a(27)p Black +eop end +%%Page: 28 28 +TeXDict begin 28 27 bop Black Black 448 573 a Fp(4.2.4)92 +b(Saturating)24 b(Incr)n(ements)g(and)f(Decr)n(ements)448 +747 y Fo(On)30 b(32-bit)i(machines,)i(the)d(CUDD)d(package)33 +b(stores)f(the)f(reference)i(counts)f(in)f(unsigned)448 +860 y(short)38 b(int')-5 b(s.)68 b(F)o(or)36 b(lar)n(ge)i(diagrams,)j +(it)36 b(is)g(possible)j(for)e(some)f(reference)j(counts)f(to)e(e)o(x-) +448 973 y(ceed)27 b(the)g(capacity)h(of)f(an)f(unsigned)j(short)e(int.) +38 b(Therefore,)28 b(increments)g(and)f(decrements)448 +1086 y(of)34 b(reference)j(counts)f(are)e Fn(satur)o(ating)p +Fo(.)64 b(This)34 b(means)g(that)h(once)g(a)f(reference)j(count)e(has) +448 1199 y(reached)24 b(the)e(maximum)f(possible)j(v)n(alue,)f(it)e(is) +h(no)g(longer)h(changed)h(by)d(calls)i(to)e Fn(Cudd)p +3264 1199 28 4 v 34 w(Ref)p Fo(,)448 1312 y Fn(Cudd)p +649 1312 V 34 w(Recur)o(siveDer)m(ef)13 b Fo(,)46 b Fn(Cudd)p +1519 1312 V 34 w(Recur)o(siveDer)m(efZdd)r Fo(,)h(or)40 +b Fn(Cudd)p 2635 1312 V 34 w(Der)m(ef)13 b Fo(.)77 b(As)39 +b(a)h(conse-)448 1425 y(quence,)30 b(some)d(nodes)i(that)e(ha)n(v)o(e)h +(no)f(references)j(may)d(not)h(be)f(declared)i(dead.)41 +b(This)27 b(may)448 1537 y(result)j(in)e(a)g(small)h(w)o(aste)f(of)h +(memory)-6 b(,)29 b(which)g(is)f(normally)i(more)f(than)g(of)n(fset)g +(by)g(the)f(re-)448 1650 y(duction)e(in)d(size)h(of)g(the)g(node)g +(structure.)589 1763 y(When)j(using)h(64-bit)f(pointers,)i(there)f(is)e +(normally)i(no)e(memory)h(adv)n(antage)i(from)d(us-)448 +1876 y(ing)e(short)h(int')-5 b(s)24 b(instead)h(of)e(int')-5 +b(s)25 b(in)e(a)g(DdNode.)29 b(Therefore,)c(increments)g(and)f +(decrements)448 1989 y(are)31 b(not)h(saturating)h(in)e(that)h(case.)51 +b(What)31 b(option)i(is)e(in)f(ef)n(fect)i(depends)h(on)e(tw)o(o)g +(macros,)448 2102 y(SIZEOF)p 763 2102 V 31 w(V)l(OID)p +1018 2102 V 32 w(P)f(and)h(SIZEOF)p 1602 2102 V 30 w(INT,)e(de\002ned)j +(in)e(the)h(e)o(xternal)h(header)g(\002le)e(\()p Fn(cudd.h)p +Fo(\).)448 2215 y(The)g(increments)i(and)e(decrements)i(of)e(the)g +(reference)i(counts)f(are)f(performed)i(using)f(tw)o(o)448 +2328 y(macros:)d Fn(cuddSatInc)21 b Fo(and)d Fn(cuddSatDec)p +Fo(,)k(whose)c(de\002nitions)i(depend)g(on)e(SIZEOF)p +3170 2328 V 31 w(V)l(OID)p 3425 2328 V 33 w(P)448 2441 +y(and)24 b(SIZEOF)p 917 2441 V 31 w(INT.)448 2690 y Fi(4.3)99 +b(Complement)26 b(Ar)n(cs)448 2864 y Fo(If)j(ADDs)f(are)h(restricted)j +(to)d(use)g(only)h(the)g(constants)i(0)c(and)i(1,)g(the)o(y)f(beha)n(v) +o(e)i(lik)o(e)f(BDDs)448 2977 y(without)d(complement)h(arcs.)36 +b(It)25 b(is)h(normally)h(easier)g(to)f(write)g(code)g(that)h +(manipulates)h(0-1)448 3090 y(ADDs,)33 b(than)h(to)e(write)h(code)g +(for)g(BDDs.)54 b(Ho)n(we)n(v)o(er)l(,)34 b(complementation)i(is)d(tri) +n(vial)g(with)448 3203 y(complement)c(arcs,)g(and)f(is)f(not)h(tri)n +(vial)g(without.)41 b(As)27 b(a)g(consequence,)k(with)d(complement)448 +3316 y(arcs)h(it)g(is)f(possible)j(to)d(check)i(for)f(more)f(terminal)i +(cases)g(and)f(it)f(is)g(possible)j(to)d(apply)i(De)448 +3429 y(Mor)n(gan')-5 b(s)25 b(la)o(ws)d(to)g(reduce)j(problems)f(that)f +(are)g(essentially)j(identical)f(to)d(a)h(standard)i(form.)448 +3542 y(This)f(in)f(turn)h(increases)i(the)e(utilization)i(of)e(the)g +(cache.)589 3655 y(The)38 b(complement)h(attrib)n(ute)h(is)d(stored)i +(in)e(the)h(least)h(signi\002cant)g(bit)f(of)f(the)h(\223else\224)448 +3768 y(pointer)25 b(of)f(each)g(node.)29 b(An)23 b(e)o(xternal)i +(pointer)g(to)e(a)g(function)j(can)e(also)g(be)f(complemented.)448 +3880 y(The)d(\223then\224)j(pointer)f(to)e(a)h(node,)g(on)g(the)g +(other)g(hand,)h(is)f(al)o(w)o(ays)g Fn(r)m(e)l(gular)p +Fo(.)30 b(It)20 b(is)h(a)f(mistak)o(e)h(to)448 3993 y(use)f(a)f +(complement)i(pointer)g(as)f(it)f(is)g(to)g(address)j(memory)-6 +b(.)27 b(Instead,)22 b(it)d(is)g(al)o(w)o(ays)i(necessary)448 +4106 y(to)28 b(obtain)i(a)e(re)o(gular)h(v)o(ersion)h(of)e(it.)42 +b(This)28 b(is)g(normally)h(done)g(by)g(calling)g Fn(Cudd)p +3094 4106 V 34 w(Re)l(gular)r Fo(.)448 4219 y(It)f(is)f(also)h(a)f +(mistak)o(e)i(to)e(call)h Fn(cuddUniqueInter)34 b Fo(with)27 +b(a)g(complemented)j(\223then\224)f(child)f(as)448 4332 +y(ar)n(gument.)i(The)22 b(calling)i(procedure)h(must)d(apply)h(De)e +(Mor)n(gan')-5 b(s)24 b(la)o(ws)d(by)h(complementing)448 +4445 y(both)32 b(pointers)i(passed)f(to)e Fn(cuddUniqueInter)38 +b Fo(and)31 b(then)h(taking)h(the)f(complement)h(of)e(the)448 +4558 y(result.)p Black 1897 5225 a(28)p Black eop end +%%Page: 29 29 +TeXDict begin 29 28 bop Black Black 448 573 a Fi(4.4)99 +b(The)26 b(Cache)448 747 y Fo(Each)38 b(entry)g(of)g(the)f(cache)i +(consists)g(of)f(\002)n(v)o(e)e(\002elds:)57 b(The)37 +b(operator)l(,)43 b(three)c(pointers)g(to)448 860 y(operands)d(and)e(a) +f(pointer)i(to)e(the)h(result.)60 b(The)33 b(operator)i(and)f(the)g +(three)g(pointers)i(to)d(the)448 973 y(operands)26 b(are)e(combined)h +(to)f(form)f(three)i(w)o(ords.)k(The)23 b(combination)j(relies)f(on)e +(tw)o(o)h(f)o(acts:)p Black 585 1155 a Fm(\017)p Black +46 w Fo(Most)i(operations)k(ha)n(v)o(e)d(one)h(or)e(tw)o(o)h(operands.) +40 b(A)26 b(fe)n(w)g(bits)h(are)g(suf)n(\002cient)h(to)f(dis-)676 +1268 y(criminate)e(all)e(three-operands)28 b(operations.)p +Black 585 1454 a Fm(\017)p Black 46 w Fo(All)h(nodes)h(are)g(aligned)h +(to)f(16-byte)h(boundaries.)50 b(\(32-byte)32 b(boundaries)h(if)c +(64-bit)676 1567 y(pointers)j(are)f(used.\))51 b(Hence,)33 +b(there)e(are)g(a)g(fe)n(w)e(bits)j(a)n(v)n(ailable)h(to)d(distinguish) +k(the)676 1679 y(three-operand)27 b(operations)g(from)c(te)g(others)i +(and)f(to)g(assign)h(unique)g(codes)g(to)e(them.)589 +1862 y(The)30 b(cache)h(does)f(not)g(contrib)n(ute)j(to)d(the)g +(reference)i(counts)f(of)f(the)g(nodes.)48 b(The)30 b(f)o(act)448 +1975 y(that)h(the)g(cache)g(contains)h(a)e(pointer)i(to)e(a)g(node)h +(does)g(not)f(imply)h(that)g(the)f(node)h(is)f(ali)n(v)o(e.)448 +2088 y(Instead,)k(when)d(garbage)h(collection)h(tak)o(es)e(place,)i +(all)e(entries)h(of)e(the)h(cache)h(pointing)g(to)448 +2201 y(dead)25 b(nodes)f(are)g(cleared.)589 2313 y(The)f(cache)i(is)e +(also)h(cleared)h(\(of)f(all)f(entries\))j(when)d(dynamic)i(reordering) +h(tak)o(es)f(place.)448 2426 y(In)f(both)g(cases,)g(the)g(entries)h +(remo)o(v)o(ed)f(from)g(the)g(cache)g(are)g(about)h(to)e(become)i(in)l +(v)n(alid.)589 2539 y(All)30 b(operands)j(and)e(results)i(in)d(a)g +(cache)i(entry)g(must)e(be)h(pointers)h(to)f(DdNodes.)50 +b(If)31 b(a)448 2652 y(function)f(produces)f(more)f(than)g(one)f +(result,)j(or)d(uses)h(more)f(than)h(three)g(ar)n(guments,)i(there)448 +2765 y(are)24 b(currently)i(tw)o(o)d(solutions:)p Black +585 2947 a Fm(\017)p Black 46 w Fo(Build)g(a)g(separate,)j(local,)e +(cache.)30 b(\(Using,)24 b(for)f(instance,)j(the)e Fn(st)h +Fo(library.\))p Black 585 3133 a Fm(\017)p Black 46 w +Fo(Combine)33 b(multiple)h(results,)i(or)c(multiple)i(operands,)j(into) +c(a)g(single)h(diagram,)h(by)676 3246 y(b)n(uilding)26 +b(a)d(\223multiple)o(xing)j(structure\224)g(with)e(reserv)o(ed)h(v)n +(ariables.)448 3428 y(Support)35 b(of)f(the)h(former)f(solution)j(is)c +(under)j(de)n(v)o(elopment.)62 b(\(See)34 b Fh(cuddLCache.c)p +Fo(..\))448 3541 y(Support)25 b(for)f(the)f(latter)i(solution)h(may)d +(be)h(pro)o(vided)h(in)f(future)g(v)o(ersions)i(of)d(the)h(package.)589 +3654 y(There)e(are)g(three)h(sets)g(of)e(interf)o(ace)j(functions)h(to) +c(the)i(cache.)29 b(The)21 b(\002rst)h(set)g(is)f(for)h(func-)448 +3767 y(tions)31 b(with)f(three)i(operands:)44 b Fn(cuddCac)o(heInsert) +36 b Fo(and)31 b Fn(cuddCac)o(heLookup)p Fo(.)52 b(The)30 +b(second)448 3880 y(set)21 b(is)g(for)g(functions)j(with)c(tw)o(o)h +(operands:)30 b Fn(cuddCac)o(heInsert2)25 b Fo(and)d +Fn(cuddCac)o(heLookup2)p Fo(.)448 3993 y(The)33 b(second)i(set)f(is)f +(for)h(functions)i(with)d(one)h(operand:)51 b Fn(cuddCac)o(heInsert1)38 +b Fo(and)c Fn(cudd-)448 4106 y(Cac)o(heLookup1)p Fo(.)42 +b(The)26 b(second)j(set)e(is)g(slightly)i(f)o(aster)f(than)g(the)f +(\002rst,)h(and)f(the)g(third)h(set)f(is)448 4219 y(slightly)f(f)o +(aster)f(than)f(the)g(second.)448 4463 y Fp(4.4.1)92 +b(Cache)23 b(Sizing)448 4638 y Fo(The)e(size)i(of)e(the)h(cache)h(can)f +(increase)h(during)h(the)d(e)o(x)o(ecution)j(of)e(an)f(application.)31 +b(\(There)22 b(is)448 4751 y(currently)27 b(no)d(w)o(ay)g(to)g +(decrease)i(the)e(size)h(of)f(the)g(cache,)i(though)f(it)f(w)o(ould)h +(not)f(be)g(dif)n(\002cult)448 4863 y(to)33 b(do)g(it.\))57 +b(When)33 b(a)g(cache)h(miss)f(occurs,)j(the)e(package)g(uses)g(the)f +(follo)n(wing)i(criteria)f(to)448 4976 y(decide)25 b(whether)g(to)e +(resize)i(the)f(cache:)p Black 1897 5225 a(29)p Black +eop end +%%Page: 30 30 +TeXDict begin 30 29 bop Black Black Black 562 573 a Fo(1.)p +Black 46 w(If)28 b(the)h(cache)g(already)i(e)o(xceeds)f(the)f(limit)f +(gi)n(v)o(en)h(by)g(the)g Fh(maxCache)24 b Fo(\002eld)29 +b(of)f(the)676 686 y(manager)l(,)i(no)f(resizing)h(tak)o(es)f(place.)44 +b(The)28 b(limit)g(is)g(the)h(minimum)f(of)g(tw)o(o)g(v)n(alues:)676 +799 y(a)k(v)n(alue)i(set)f(at)f(initialization)37 b(time)c(and)g +(possibly)i(modi\002ed)e(by)g(the)g(application,)676 +912 y(which)g(constitutes)i(the)e(hard)h(limit)e(be)o(yond)i(which)f +(the)g(cache)h(will)e(ne)n(v)o(er)h(gro)n(w;)676 1024 +y(and)23 b(a)f(number)i(that)f(depends)i(on)e(the)g(current)h(total)g +(number)g(of)e(slots)i(in)f(the)g(unique)676 1137 y(table.)p +Black 562 1325 a(2.)p Black 46 w(If)f(the)h(cache)h(is)f(not)g(too)g +(lar)n(ge)h(already)-6 b(,)25 b(resizing)g(is)d(decided)j(based)f(on)f +(the)g(hit)g(rate.)676 1438 y(The)28 b(polic)o(y)i(adopted)h(by)e(the)h +(CUDD)c(package)31 b(is)e(\223re)n(w)o(ard-based.)-6 +b(\224)48 b(If)29 b(the)g(cache)676 1551 y(hit)23 b(rate)h(is)g(high,)g +(then)g(it)f(is)h(w)o(orthwhile)h(to)e(increase)j(the)d(size)h(of)g +(the)g(cache.)448 1738 y(When)i(resizing)h(tak)o(es)f(place,)g(the)g +(statistical)h(counters)h(used)e(to)f(compute)h(the)f(hit)h(rate)f(are) +448 1851 y(reinitialized)g(so)c(as)g(to)g(pre)n(v)o(ent)h(immediate)g +(resizing.)30 b(The)21 b(number)h(of)f(entries)i(is)d(doubled.)589 +1964 y(The)k(rationale)i(for)e(the)g(\223re)n(w)o(ard-based\224)j +(polic)o(y)e(is)e(as)h(follo)n(ws.)30 b(In)23 b(man)o(y)h(BDD/ADD)448 +2077 y(applications)j(the)c(hit)g(rate)g(is)g(not)g(v)o(ery)g(sensiti)n +(v)o(e)i(to)d(the)h(size)h(of)e(the)i(cache:)30 b(It)22 +b(is)h(primarily)448 2190 y(a)i(function)j(of)e(the)g(problem)g +(instance)i(at)d(hand.)36 b(If)25 b(a)h(lar)n(ge)g(hit)g(rate)g(is)g +(observ)o(ed,)h(chances)448 2303 y(are)c(that)g(by)g(using)g(a)f(lar)n +(ge)i(cache,)g(the)e(results)i(of)f(lar)n(ge)h(problems)g(\(those)f +(that)h(w)o(ould)f(tak)o(e)448 2416 y(longer)31 b(to)f(solv)o(e\))g +(will)g(survi)n(v)o(e)g(in)g(the)g(cache)h(without)f(being)h(o)o(v)o +(erwritten)g(long)f(enough)448 2529 y(to)i(cause)i(a)d(v)n(aluable)k +(cache)e(hit.)55 b(Notice)32 b(that)h(when)f(a)g(lar)n(ge)i(problem)f +(is)f(solv)o(ed)h(more)448 2642 y(than)c(once,)g(so)f(are)g(its)g +(recursi)n(v)o(ely)i(generated)g(subproblems.)44 b(If)28 +b(the)g(hit)f(rate)i(is)e(lo)n(w)-6 b(,)28 b(the)448 +2755 y(probability)f(of)c(lar)n(ge)i(problems)g(being)g(solv)o(ed)g +(more)e(than)i(once)f(is)f(lo)n(w)-6 b(.)589 2868 y(The)20 +b(other)h(observ)n(ation)j(about)d(the)f(cache)i(sizing)f(polic)o(y)g +(is)f(that)h(there)g(is)f(little)h(point)g(in)448 2980 +y(k)o(eeping)k(a)d(cache)h(which)g(is)f(much)h(lar)n(ger)h(than)f(the)g +(unique)h(table.)29 b(Ev)o(ery)23 b(time)f(the)h(unique)448 +3093 y(table)29 b(\223\002lls)g(up,)-6 b(\224)29 b(garbage)g +(collection)i(is)d(in)l(v)n(ok)o(ed)j(and)e(the)f(cache)h(is)f(cleared) +i(of)e(all)g(dead)448 3206 y(entries.)h(A)19 b(cache)i(that)g(is)f +(much)g(lar)n(ger)i(than)f(the)f(unique)i(table)f(is)f(therefore)i +(less)f(than)f(fully)448 3319 y(utilized.)448 3565 y +Fp(4.4.2)92 b(Local)24 b(Caches)448 3739 y Fo(Sometimes)k(it)f(may)f +(be)i(necessary)h(or)e(con)l(v)o(enient)j(to)d(use)h(a)f(local)h +(cache.)40 b(A)26 b(local)i(cache)448 3852 y(can)f(be)g(lossless)i +(\(no)e(results)h(are)e(e)n(v)o(er)h(o)o(v)o(erwritten\),)i(or)e(it)f +(may)g(store)i(objects)g(for)f(which)448 3965 y(canonical)36 +b(representations)h(are)c(not)g(a)n(v)n(ailable.)59 b(One)33 +b(important)h(f)o(act)g(to)f(k)o(eep)g(in)g(mind)448 +4078 y(when)d(using)g(a)f(local)h(cache)h(is)e(that)h(local)g(caches)h +(are)e(not)h(cleared)h(during)g(garbage)g(col-)448 4191 +y(lection)e(or)e(before)i(reordering.)42 b(Therefore,)29 +b(it)e(is)g(necessary)j(to)d(increment)i(the)e(reference)448 +4304 y(count)22 b(of)d(all)i(nodes)g(pointed)h(by)e(a)g(local)h(cache.) +28 b(\(Unless)21 b(their)g(reference)h(counts)g(are)e(guar)n(-)448 +4417 y(anteed)25 b(positi)n(v)o(e)h(in)d(some)h(other)h(w)o(ay)-6 +b(.)29 b(One)23 b(such)i(w)o(ay)e(is)h(by)f(including)k(all)d(partial)h +(results)448 4530 y(in)i(the)g(global)i(result.\))40 +b(Before)27 b(disposing)j(of)d(the)g(local)h(cache,)g(all)f(elements)i +(stored)f(in)f(it)448 4643 y(must)20 b(be)g(passed)h(to)e +Fn(Cudd)p 1300 4643 28 4 v 34 w(Recur)o(siveDer)m(ef)13 +b Fo(.)30 b(As)19 b(consequence)k(of)d(the)g(f)o(act)g(that)g(all)g +(results)448 4756 y(in)i(a)g(local)h(cache)g(are)g(referenced,)i(it)d +(is)g(generally)i(con)l(v)o(enient)h(to)e(store)g(in)f(the)g(local)h +(cache)448 4868 y(also)h(the)e(result)i(of)f(tri)n(vial)g(problems,)h +(which)f(are)g(not)g(usually)h(stored)g(in)f(the)f(global)i(cache.)p +Black 1897 5225 a(30)p Black eop end +%%Page: 31 31 +TeXDict begin 31 30 bop Black Black 448 573 a Fo(Otherwise,)35 +b(after)d(a)g(recursi)n(v)o(e)h(call,)i(it)c(is)h(dif)n(\002cult)g(to)g +(tell)h(whether)f(the)h(result)g(is)e(in)h(the)448 686 +y(cache,)25 b(and)f(therefore)h(referenced,)h(or)e(not)g(in)f(the)h +(cache,)g(and)g(therefore)i(not)e(referenced.)589 799 +y(An)19 b(alternati)n(v)o(e)i(approach)g(to)e(referencing)j(the)d +(results)i(in)e(the)g(local)h(caches)g(is)f(to)g(install)448 +912 y(hook)25 b(functions)h(\(see)e(Section)g(3.16\))h(to)e(be)h(e)o(x) +o(ecuted)h(before)g(garbage)g(collection.)448 1158 y +Fi(4.5)99 b(The)26 b(Unique)g(T)-9 b(able)448 1333 y +Fo(A)29 b(recursi)n(v)o(e)j(procedure)h(typically)f(splits)g(the)e +(operands)j(by)d(e)o(xpanding)j(with)d(respect)h(to)448 +1445 y(the)d(topmost)h(v)n(ariable.)43 b(T)-7 b(opmost)28 +b(in)g(this)g(conte)o(xt)h(refers)g(to)e(the)h(v)n(ariable)i(that)e(is) +g(closest)448 1558 y(to)i(the)f(roots)i(in)e(the)h(current)h(v)n +(ariable)g(order)-5 b(.)47 b(The)29 b(nodes,)j(on)d(the)h(other)g +(hand,)i(hold)e(the)448 1671 y(inde)o(x,)c(which)f(is)g(in)l(v)n +(ariant)i(with)e(reordering.)36 b(Therefore,)26 b(when)f(splitting,)j +(one)d(must)g(use)448 1784 y(the)j(permutation)i(array)e(maintained)i +(by)d(the)h(package)i(to)d(get)h(the)f(right)i(le)n(v)o(el.)40 +b(Access)28 b(to)448 1897 y(the)22 b(permutation)i(array)e(is)f(pro)o +(vided)i(by)f(the)f(macro)h Fn(cuddI)27 b Fo(for)21 b(BDDs)f(and)i +(ADDs,)d(and)j(by)448 2010 y(the)i(macro)g Fn(cuddIZ)29 +b Fo(for)24 b(ZDDs.)589 2123 y(The)i(unique)i(table)f(consists)h(of)e +(as)g(man)o(y)g(hash)h(tables)h(as)e(there)h(are)f(v)n(ariables)i(in)e +(use.)448 2236 y(These)e(has)f(tables)h(are)g(called)g +Fn(unique)h(subtables)p Fo(.)31 b(The)23 b(sizes)g(of)g(the)h(unique)h +(subtables)g(are)448 2349 y(determined)h(by)e(tw)o(o)f(criteria:)p +Black 562 2524 a(1.)p Black 46 w(The)g(collision)j(lists)e(should)h(be) +f(short)g(to)g(k)o(eep)g(access)h(time)e(do)n(wn.)p Black +562 2707 a(2.)p Black 46 w(There)18 b(should)i(be)e(enough)i(room)e +(for)g(dead)h(nodes,)h(to)e(pre)n(v)o(ent)h(too)g(frequent)h(garbage) +676 2819 y(collections.)448 2995 y(While)30 b(the)g(\002rst)g +(criterion)i(is)d(f)o(airly)i(straightforw)o(ard)j(to)c(implement,)i +(the)e(second)h(lea)n(v)o(es)448 3108 y(more)22 b(room)g(to)f(creati)n +(vity)-6 b(.)31 b(The)21 b(CUDD)e(package)24 b(tries)f(to)e(\002gure)h +(out)g(whether)h(more)e(dead)448 3220 y(node)j(should)h(be)e(allo)n +(wed)g(to)g(increase)i(performance.)31 b(\(See)23 b(also)h(Section)f +(3.4.\))29 b(There)23 b(are)448 3333 y(tw)o(o)k(reasons)h(for)f(not)g +(doing)h(garbage)g(collection)h(too)e(often.)39 b(The)26 +b(ob)o(vious)j(one)e(is)f(that)i(it)448 3446 y(is)21 +b(e)o(xpensi)n(v)o(e.)30 b(The)21 b(second)i(is)e(that)h(dead)g(nodes)g +(may)f(be)g(reclaimed,)j(if)d(the)o(y)g(are)h(the)f(result)448 +3559 y(of)k(a)g(successful)j(cache)f(lookup.)35 b(Hence)26 +b(dead)g(nodes)g(may)f(pro)o(vide)i(a)e(substantial)j(speed-)448 +3672 y(up)35 b(if)f(the)o(y)g(are)h(k)o(ept)g(around)g(long)h(enough.) +62 b(The)34 b(usefulness)j(of)d(k)o(eeping)i(man)o(y)e(dead)448 +3785 y(nodes)g(around)h(v)n(aries)f(from)e(application)k(to)d +(application,)38 b(and)33 b(from)g(problem)h(instance)448 +3898 y(to)d(problem)g(instance.)51 b(As)30 b(in)g(the)h(sizing)g(of)f +(the)h(cache,)i(the)e(CUDD)d(package)k(adopts)g(a)448 +4011 y(\223re)n(w)o(ard-based\224)k(polic)o(y)e(to)e(decide)i(ho)n(w)e +(much)h(room)f(should)i(be)f(used)g(for)g(the)g(unique)448 +4124 y(table.)62 b(If)35 b(the)f(number)h(of)g(dead)g(nodes)h +(reclaimed)g(is)e(lar)n(ge)h(compared)h(to)f(the)f(number)448 +4237 y(of)d(nodes)h(directly)g(requested)h(from)e(the)g(memory)f +(manager)l(,)k(then)d(the)g(CUDD)d(package)448 4350 y(assumes)34 +b(that)g(it)e(will)h(be)f(bene\002cial)j(to)e(allo)n(w)f(more)h(room)g +(for)g(the)g(subtables,)k(thereby)448 4462 y(reducing)31 +b(the)e(frequenc)o(y)i(of)e(garbage)h(collection.)47 +b(The)28 b(package)j(does)e(so)g(by)g(switching)448 4575 +y(between)c(tw)o(o)e(modes)h(of)g(operation:)p Black +562 4751 a(1.)p Black 46 w(F)o(ast)d(gro)n(wth:)30 b(In)22 +b(this)h(mode,)f(the)h(ratio)g(of)g(dead)g(nodes)g(to)g(total)g(nodes)h +(required)g(for)676 4863 y(garbage)k(collection)h(is)e(higher)h(than)g +(in)f(the)g(slo)n(w)f(gro)n(wth)h(mode)g(to)g(f)o(a)n(v)n(or)h +(resizing)676 4976 y(of)23 b(the)h(subtables.)p Black +1897 5225 a(31)p Black eop end +%%Page: 32 32 +TeXDict begin 32 31 bop Black Black Black 562 573 a Fo(2.)p +Black 46 w(Slo)n(w)28 b(gro)n(wth:)42 b(In)29 b(this)h(mode)g(k)o +(eeping)h(man)o(y)f(dead)g(nodes)h(around)g(is)f(not)f(as)h(im-)676 +686 y(portant)25 b(as)e(k)o(eeping)j(memory)e(requirements)i(lo)n(w)-6 +b(.)448 873 y(Switching)25 b(from)e(one)h(mode)g(to)f(the)h(other)h(is) +e(based)i(on)e(the)h(follo)n(wing)h(criteria:)p Black +562 1061 a(1.)p Black 46 w(If)e(the)h(unique)h(table)f(is)g(already)h +(lar)n(ge,)f(only)h(slo)n(w)e(gro)n(wth)h(is)f(possible.)p +Black 562 1249 a(2.)p Black 46 w(If)35 b(the)h(table)h(is)f(small)g +(and)g(man)o(y)g(dead)h(nodes)g(are)f(being)h(reclaimed,)j(then)d(f)o +(ast)676 1362 y(gro)n(wth)24 b(is)f(selected.)448 1549 +y(This)j(polic)o(y)g(is)g(especially)i(ef)n(fecti)n(v)o(e)f(when)f(the) +g(diagrams)h(being)f(manipulated)j(ha)n(v)o(e)d(lots)448 +1662 y(of)f(recombination.)37 b(Notice)25 b(the)h(interplay)h(of)e(the) +h(cache)g(sizing)g(and)g(unique)g(sizing:)34 b(F)o(ast)448 +1775 y(gro)n(wth)24 b(normally)h(occurs)f(when)g(the)f(cache)h(hit)g +(rate)g(is)f(lar)n(ge.)29 b(The)23 b(cache)h(and)g(the)g(unique)448 +1888 y(table)h(then)f(gro)n(w)f(in)h(concert,)h(preserving)h(a)d +(healthy)i(balance)h(between)e(their)h(sizes.)448 2137 +y Fi(4.6)99 b(Allo)o(wing)24 b(Asynchr)n(onous)i(Reordering)448 +2311 y Fo(Asynchronous)36 b(reordering)f(is)d(the)g(reordering)j(that)d +(is)g(triggered)j(automatically)g(by)d(the)448 2424 y(increase)37 +b(of)d(the)h(number)g(of)g(nodes.)62 b(Asynchronous)38 +b(reordering)f(tak)o(es)f(place)f(when)g(a)448 2537 y(ne)n(w)28 +b(internal)i(node)g(must)e(be)g(created,)j(and)e(the)g(number)g(of)f +(nodes)i(has)f(reached)h(a)e(gi)n(v)o(en)448 2650 y(threshold.)49 +b(\(The)29 b(threshold)j(is)d(adjusted)i(by)f(the)f(package)i(e)n(v)o +(ery)f(time)f(reordering)j(tak)o(es)448 2763 y(place.\))589 +2876 y(Those)24 b(procedures)j(that)d(do)g(not)f(create)i(ne)n(w)e +(nodes)i(\(e.g.,)e(procedures)j(that)e(count)h(the)448 +2989 y(number)g(of)e(nodes)h(or)g(minterms\))g(need)g(not)g(w)o(orry)f +(about)i(asynchronous)i(reordering:)32 b(No)448 3102 +y(special)25 b(precaution)i(is)c(necessary)j(in)e(writing)g(them.)589 +3215 y(Procedures)i(that)e(only)g(manipulate)i(decision)f(diagrams)g +(through)g(the)f(e)o(xported)h(func-)448 3328 y(tions)j(of)e(the)h +(CUDD)e(package)j(also)f(need)h(not)f(concern)h(themselv)o(es)h(with)d +(asynchronous)448 3440 y(reordering.)32 b(\(See)23 b(Section)i(3.2.1)e +(for)h(the)g(e)o(xceptions.\))589 3553 y(The)i(remaining)h(class)g(of)e +(procedures)k(is)c(composed)j(of)d(functions)j(that)e(visit)h(the)f +(dia-)448 3666 y(grams)h(and)h(may)e(create)i(ne)n(w)e(nodes.)39 +b(All)26 b(such)i(procedures)h(in)e(the)g(CUDD)d(package)29 +b(are)448 3779 y(written)35 b(so)e(that)h(the)o(y)g(can)g(be)f +(interrupted)k(by)d(dynamic)g(reordering.)62 b(The)33 +b(general)i(ap-)448 3892 y(proach)26 b(follo)n(wed)g(goes)f(under)g +(the)g(name)f(of)h(\223abort)g(and)g(retry.)-6 b(\224)32 +b(As)24 b(the)g(name)h(implies,)g(a)448 4005 y(computation)i(that)d(is) +f(interrupted)k(by)c(dynamic)i(reordering)h(is)e(aborted)h(and)f(tried) +h(again.)589 4118 y(A)e(recursi)n(v)o(e)i(procedure)h(that)e(can)f(be)h +(interrupted)i(by)e(dynamic)g(reordering)i(\(an)e(inter)n(-)448 +4231 y(ruptible)g(procedure)h(from)d(no)n(w)g(on\))h(is)f(composed)i +(of)e(tw)o(o)f(functions.)31 b(One)22 b(is)g(responsible)448 +4344 y(for)30 b(the)f(real)h(computation.)49 b(The)29 +b(other)h(is)f(a)g(simple)h(wrapper,)h(which)f(tests)g(whether)g(re-) +448 4457 y(ordering)c(occurred)g(and)e(restarts)h(the)f(computation)i +(if)d(it)h(did.)589 4570 y(Asynchronous)f(reordering)e(of)e(BDDs)e(and) +i(ADDs)e(can)i(only)h(be)e(triggered)k(inside)e Fn(cud-)448 +4682 y(dUniqueInter)r Fo(,)36 b(when)31 b(a)f(ne)n(w)g(node)i(is)f +(about)h(to)e(be)h(created.)53 b(Lik)o(e)n(wise,)32 b(asynchronous)448 +4795 y(reordering)f(of)d(ZDDs)f(can)h(only)h(be)f(triggered)j(inside)e +Fn(cuddUniqueInterZdd)r Fo(.)48 b(When)28 b(re-)448 4908 +y(ordering)e(is)d(triggered,)j(three)e(things)h(happen:)p +Black 1897 5225 a(32)p Black eop end +%%Page: 33 33 +TeXDict begin 33 32 bop Black Black Black 562 573 a Fo(1.)p +Black 46 w Fn(cuddUniqueInter)29 b Fo(returns)d(a)d(NULL)e(v)n(alue;)p +Black 562 760 a(2.)p Black 46 w(The)i(\003ag)g Fn(r)m(eor)m(der)m(ed)28 +b Fo(of)23 b(the)h(manager)h(is)e(set)h(to)g(1.)29 b(\(0)23 +b(means)h(no)g(reordering,)i(while)676 873 y(2)d(indicates)j(an)d +(error)i(occurred)g(during)g(reordering.\))p Black 562 +1061 a(3.)p Black 46 w(The)g(counter)k Fn(r)m(eor)m(derings)g +Fo(of)d(the)g(manager)i(is)e(incremented.)40 b(The)26 +b(counter)i(is)e(ini-)676 1174 y(tialized)37 b(to)f(0)f(when)h(the)g +(manager)h(is)f(started)h(and)f(can)g(be)g(accessed)i(by)e(calling)676 +1287 y Fn(Cudd)p 877 1287 28 4 v 33 w(ReadReor)m(derings)p +Fo(.)41 b(By)25 b(taking)j(tw)o(o)e(readings)j(of)d(the)h(counter)l(,)i +(an)d(applica-)676 1400 y(tion)32 b(can)g(determine)i(if)d(v)n(ariable) +j(reordering)h(has)d(tak)o(en)h(place)g(between)g(the)f(\002rst)676 +1513 y(and)27 b(the)g(second)h(reading.)41 b(The)26 b(package)j +(itself,)f(ho)n(we)n(v)o(er)l(,)g(does)g(not)f(mak)o(e)g(use)g(of)676 +1626 y(the)c(counter:)31 b(It)24 b(is)f(mentioned)j(here)e(for)g +(completeness.)589 1813 y(The)35 b(recursi)n(v)o(e)h(procedure)i(that)d +(recei)n(v)o(es)h(a)e(NULL)f(v)n(alue)i(from)g Fn(cuddUniqueInter)448 +1926 y Fo(must)g(free)h(all)f(intermediate)j(results)f(that)e(it)g(may) +g(ha)n(v)o(e)h(computed)g(before,)j(and)d(return)448 +2039 y(NULL)21 b(in)j(its)f(turn.)589 2152 y(The)31 b(wrapper)g +(function)i(does)e(not)g(decide)i(whether)e(reordering)j(occurred)e +(based)g(on)448 2265 y(the)37 b(NULL)e(return)j(v)n(alue,)i(because)f +(the)e(NULL)d(v)n(alue)k(may)e(be)h(the)g(result)h(of)f(lack)g(of)448 +2378 y(memory)-6 b(.)29 b(Instead,)c(it)f(checks)h(the)e +Fn(r)m(eor)m(der)m(ed)28 b Fo(\003ag.)589 2491 y(When)h(a)e(recursi)n +(v)o(e)i(procedure)i(calls)e(another)g(recursi)n(v)o(e)h(procedure)g +(that)f(may)e(cause)448 2604 y(reordering,)i(it)d(should)i(bypass)f +(the)f(wrapper)h(and)g(call)f(the)g(recursi)n(v)o(e)i(procedure)h +(directly)-6 b(.)448 2716 y(Otherwise,)29 b(the)f(calling)i(procedure)g +(will)d(not)h(kno)n(w)f(whether)i(reordering)h(occurred,)h(and)448 +2829 y(will)26 b(not)g(be)g(able)g(to)g(restart.)37 b(This)25 +b(is)h(the)g(main)g(reason)h(why)e(most)h(recursi)n(v)o(e)h(procedures) +448 2942 y(are)k(internal,)i(rather)e(than)g(static.)50 +b(\(The)30 b(wrappers,)j(on)d(the)h(other)g(hand,)h(are)e(mostly)h(e)o +(x-)448 3055 y(ported.\))448 3304 y Fi(4.7)99 b(Deb)n(ugging)448 +3479 y Fo(By)35 b(de\002ning)i(the)g(symbol)f(DD)p 1508 +3479 V 32 w(DEB)o(UG)e(during)j(compilation,)k(numerous)d(checks)f(are) +448 3592 y(added)20 b(to)e(the)g(code.)28 b(In)18 b(addition,)j(the)d +(procedures)j Fn(Cudd)p 2297 3592 V 34 w(Deb)n(ugChec)n(k)r +Fo(,)g Fn(Cudd)p 3036 3592 V 33 w(Chec)n(kK)m(e)m(ys)p +Fo(,)448 3704 y(and)g Fn(cuddHeapPr)l(o\002le)i Fo(can)e(be)f(called)h +(at)f(an)o(y)g(point)i(to)e(v)o(erify)h(the)f(consistenc)o(y)j(of)d +(the)h(data)448 3817 y(structure.)44 b(\()p Fn(cuddHeapPr)l(o\002le)31 +b Fo(is)d(an)f(internal)j(procedure.)44 b(It)27 b(is)h(declared)i(in)d +Fn(cuddInt.h)p Fo(.\))448 3930 y(Procedures)37 b Fn(Cudd)p +1087 3930 V 34 w(Deb)n(ugChec)n(k)h Fo(and)d Fn(Cudd)p +1983 3930 V 34 w(Chec)n(kK)m(e)m(ys)h Fo(are)f(especially)i(useful)f +(when)448 4043 y(CUDD)20 b(reports)k(that)e(during)i(garbage)f +(collection)i(the)d(number)h(of)e(nodes)j(actually)g(deleted)448 +4156 y(from)k(the)h(unique)h(table)f(is)f(dif)n(ferent)i(from)f(the)f +(count)i(of)e(dead)h(nodes)g(k)o(ept)g(by)g(the)f(man-)448 +4269 y(ager)-5 b(.)36 b(The)25 b(error)h(causing)h(the)f(discrepanc)o +(y)j(may)c(ha)n(v)o(e)h(occurred)i(much)d(earlier)i(than)f(it)f(is)448 +4382 y(disco)o(v)o(ered.)42 b(A)26 b(fe)n(w)h(strate)o(gicaly)j(placed) +f(calls)f(to)f(the)g(deb)n(ugging)k(procedures)f(can)e(con-)448 +4495 y(siderably)j(narro)n(w)e(do)n(wn)f(the)h(search)g(for)g(the)g +(source)g(of)g(the)f(problem.)45 b(\(F)o(or)27 b(instance,)32 +b(a)448 4608 y(call)23 b(to)g Fn(Cudd)p 895 4608 V 34 +w(Recur)o(siveDer)m(ef)38 b Fo(where)23 b(one)g(to)f +Fn(Cudd)p 2210 4608 V 34 w(Der)m(ef)36 b Fo(w)o(as)22 +b(required)i(may)f(be)f(iden-)448 4721 y(ti\002ed)i(in)f(this)h(w)o(ay) +-6 b(.\))589 4834 y(One)29 b(of)g(the)g(most)g(common)g(problems)i +(encountered)h(in)d(deb)n(ugging)j(code)e(based)g(on)448 +4946 y(the)j(CUDD)e(package)k(is)e(a)f(missing)i(call)f(to)g +Fn(Cudd)p 2158 4946 V 34 w(Recur)o(siveDer)m(ef)13 b +Fo(.)59 b(T)-7 b(o)32 b(help)h(identify)p Black 1897 +5225 a(33)p Black eop end +%%Page: 34 34 +TeXDict begin 34 33 bop Black Black 448 573 a Fo(this)22 +b(type)g(of)f(problems,)i(the)e(package)i(pro)o(vides)g(a)e(function)i +(called)f Fn(Cudd)p 2858 573 28 4 v 34 w(Chec)n(kZer)l(oRef)13 +b Fo(.)448 686 y(This)37 b(function)h(should)h(be)d(called)i +(immediately)g(before)g(shutting)h(do)n(wn)e(the)f(manager)-5 +b(.)448 799 y Fn(Cudd)p 649 799 V 34 w(Chec)n(kZer)l(oRef)34 +b Fo(checks)20 b(that)g(the)f(only)h(nodes)g(left)f(with)g(non-zero)i +(reference)h(counts)448 912 y(are)27 b(the)f(prede\002ned)j(constants,) +g(the)e(BDD)d(projection)29 b(functions,)h(and)c(nodes)i(whose)f(ref-) +448 1024 y(erence)e(counts)g(are)f(saturated.)589 1137 +y(F)o(or)29 b(this)h(function)i(to)e(be)g(ef)n(fecti)n(v)o(e)h(the)f +(application)i(must)e(e)o(xplicitly)i(dispose)g(of)d(all)448 +1250 y(diagrams)c(to)f(which)g(it)f(has)h(pointers)h(before)g(calling)h +(it.)448 1498 y Fi(4.8)99 b(Gathering)26 b(and)f(Inter)o(pr)n(eting)i +(Statistics)448 1673 y Fo(Function)33 b Fn(Cudd)p 1003 +1673 V 34 w(PrintInfo)g Fo(can)f(be)f(called)i(to)e(print)i(out)f(the)f +(v)n(alues)i(of)e(parameters)j(and)448 1786 y(statistics)c(for)e(a)f +(manager)-5 b(.)41 b(The)27 b(output)j(of)d Fn(Cudd)p +2089 1786 V 34 w(PrintInfo)i Fo(is)e(di)n(vided)i(in)e(tw)o(o)g +(sections.)448 1899 y(The)19 b(\002rst)g(reports)i(the)e(v)n(alues)h +(of)f(parameters)j(that)d(are)h(under)g(the)f(application)k(control.)29 +b(The)448 2011 y(second)e(reports)g(the)f(v)n(alues)g(of)f(statistical) +j(counters)f(and)f(other)g(non-modi\002able)i(parame-)448 +2124 y(ters.)j(A)22 b(quick)k(guide)f(to)f(the)g(interpretation)k(of)c +(all)g(these)h(quantities)h(follo)n(ws.)31 b(F)o(or)23 +b(ease)h(of)448 2237 y(e)o(xposition,)30 b(we)25 b(re)n(v)o(erse)j(the) +f(order)g(and)g(describe)i(the)d(non-modi\002able)j(parameters)g +(\002rst.)448 2350 y(W)-7 b(e')o(ll)24 b(use)g(a)f(sample)h(run)g(as)f +(e)o(xample.)30 b(There)24 b(is)f(nothing)j(special)f(about)g(this)f +(run.)448 2595 y Fp(4.8.1)92 b(Non)22 b(Modi\002able)h(P)o(arameters) +448 2769 y Fo(The)g(list)h(of)g(non-modi\002able)i(parameters)g(starts) +e(with:)p Black Black 667 2952 a Fh(****)52 b(CUDD)h(non-modifiable)48 +b(parameters)i(****)667 3065 y(Memory)h(in)j(use:)f(32544220)448 +3247 y Fo(This)25 b(is)f(the)h(memory)g(used)h(by)f(CUDD)d(for)j(three) +h(things)g(mainly:)32 b(Unique)26 b(table)f(\(includ-)448 +3360 y(ing)i(all)g(DD)d(nodes)k(in)e(use\),)i(node)f(free)g(list,)g +(and)g(computed)h(table.)38 b(This)26 b(number)i(almost)448 +3473 y(ne)n(v)o(er)g(decreases)h(in)f(the)f(lifetime)h(of)f(a)g(CUDD)e +(manager)l(,)k(because)g(CUDD)c(does)j(not)f(re-)448 +3586 y(lease)k(memory)f(when)g(it)f(frees)h(nodes.)49 +b(Rather)l(,)32 b(it)d(puts)h(the)g(nodes)h(on)f(its)g(o)n(wn)f(free)h +(list.)448 3699 y(This)h(number)g(is)g(in)f(bytes.)51 +b(It)30 b(does)i(not)f(represent)i(the)e(peak)g(memory)g(occupation,)k +(be-)448 3812 y(cause)d(it)e(does)h(not)g(include)h(the)e(size)h(of)f +(data)h(structures)i(created)f(temporarily)h(by)d(some)448 +3925 y(functions)c(\(e.g.,)d(local)i(look-up)g(tables\).)p +Black Black 667 4131 a Fh(Peak)52 b(number)g(of)i(nodes:)d(837018)448 +4338 y Fo(This)31 b(number)h(is)f(the)g(number)g(of)g(nodes)h(that)g +(the)f(manager)h(has)f(allocated.)54 b(This)30 b(is)h(not)448 +4451 y(the)d(lar)n(gest)h(size)f(of)f(the)h(BDDs,)e(because)j(the)f +(manager)g(will)f(normally)i(ha)n(v)o(e)f(some)f(dead)448 +4563 y(nodes)e(and)f(some)g(nodes)h(on)e(the)h(free)g(list.)p +Black Black 667 4770 a Fh(Peak)52 b(number)g(of)i(live)e(nodes:)g +(836894)448 4976 y Fo(This)20 b(is)g(the)h(lar)n(gest)h(number)f(of)f +(li)n(v)o(e)g(nodes)h(that)g(the)f(manager)i(has)e(held)h(since)g(its)g +(creation.)p Black 1897 5225 a(34)p Black eop end +%%Page: 35 35 +TeXDict begin 35 34 bop Black Black Black Black 667 573 +a Fh(Number)51 b(of)j(BDD)f(variables:)d(198)667 686 +y(Number)h(of)j(ZDD)f(variables:)d(0)448 892 y Fo(These)24 +b(numbers)h(tell)f(us)f(this)h(run)g(w)o(as)g(not)f(using)i(ZDDs.)p +Black Black 667 1099 a Fh(Number)51 b(of)j(cache)e(entries:)f(1048576) +448 1306 y Fo(Current)25 b(number)g(of)f(slots)h(of)f(the)g(computed)i +(table.)31 b(If)24 b(one)g(has)g(a)g(performance)i(problem,)448 +1419 y(this)e(is)g(one)g(of)f(the)h(numbers)h(to)e(look)i(at.)j(The)23 +b(cache)i(size)f(is)f(al)o(w)o(ays)i(a)e(po)n(wer)g(of)h(2.)p +Black Black 667 1625 a Fh(Number)51 b(of)j(cache)e(look-ups:)f(2996536) +667 1738 y(Number)g(of)j(cache)e(hits:)g(1187087)448 +1945 y Fo(These)22 b(numbers)i(gi)n(v)o(e)e(an)g(indication)i(of)e(the) +g(hit)g(rate)h(in)e(the)i(computed)g(table.)29 b(It)22 +b(is)g(not)g(un-)448 2058 y(lik)o(ely)j(for)f(model)g(checking)i(runs)e +(to)g(get)f(hit)h(rates)g(e)n(v)o(en)g(higher)h(than)f(this)h(one)f +(\(39.62\045\).)p Black Black 667 2265 a Fh(Number)51 +b(of)j(cache)e(insertions:)e(1809473)667 2377 y(Number)h(of)j(cache)e +(collisions:)e(961208)667 2490 y(Number)h(of)j(cache)e(deletions:)e(0) +448 2697 y Fo(A)30 b(collision)j(occurs)f(when)f(a)f(cache)i(entry)g +(is)e(o)o(v)o(erwritten.)52 b(A)30 b(deletion)j(occurs)f(when)f(a)448 +2810 y(cache)c(entry)g(is)e(in)l(v)n(alidated)k(\(e.g.,)d(during)h +(garbage)g(collection\).)39 b(If)25 b(the)h(number)h(of)e(dele-)448 +2923 y(tions)d(is)f(high)g(compared)i(to)d(the)h(number)h(of)f +(collisions,)i(it)e(means)g(that)g(garbage)i(collection)448 +3036 y(occurs)32 b(too)e(often.)48 b(In)30 b(this)g(case)h(there)f +(were)g(no)g(garbage)h(collections;)36 b(hence,)d(no)c(dele-)448 +3149 y(tions.)p Black Black 667 3355 a Fh(Cache)52 b(used)g(slots)h(=)h +(80.90\045)e(\(expected)e(82.19\045\))448 3562 y Fo(Percentage)26 +b(of)e(cache)i(slots)f(that)f(contain)i(a)e(v)n(alid)h(entry)-6 +b(.)31 b(If)24 b(this)h(number)g(is)f(small,)g(it)g(may)448 +3675 y(signal)h(one)f(of)g(three)g(conditions:)p Black +562 3858 a(1.)p Black 46 w(The)f(cache)h(may)g(ha)n(v)o(e)g(been)g +(recently)i(resized)f(and)f(it)f(is)g(still)i(\002lling)f(up.)p +Black 562 4043 a(2.)p Black 46 w(The)j(cache)i(is)f(too)h(lar)n(ge)g +(for)f(the)g(BDDs.)41 b(This)28 b(should)i(not)e(happen)i(if)d(the)i +(size)f(of)676 4156 y(the)23 b(cache)i(is)e(determined)j(by)e(CUDD.)p +Black 562 4342 a(3.)p Black 46 w(The)f(hash)i(function)h(is)d(not)i(w)o +(orking)g(properly)-6 b(.)32 b(This)24 b(is)f(accompanied)k(by)d(a)f +(de)o(gra-)676 4455 y(dation)34 b(in)f(performance.)59 +b(Con)l(v)o(ersely)-6 b(,)37 b(a)c(de)o(gradation)j(in)c(performance)k +(may)c(be)676 4568 y(due)24 b(to)f(bad)h(hash)g(function)i(beha)n(vior) +-5 b(.)448 4751 y(The)26 b(e)o(xpected)j(v)n(alue)e(is)f(computed)j +(assuming)f(a)e(uniformly)i(random)f(distrib)n(ution)k(of)26 +b(the)448 4863 y(accesses.)45 b(If)28 b(the)h(dif)n(ference)h(between)g +(the)e(measured)i(v)n(alue)f(and)g(the)f(e)o(xpected)i(v)n(alue)f(is) +448 4976 y(lar)n(ge)c(\(unlik)o(e)g(this)g(case\),)f(the)g(cache)g(is)g +(not)f(w)o(orking)i(properly)-6 b(.)p Black 1897 5225 +a(35)p Black eop end +%%Page: 36 36 +TeXDict begin 36 35 bop Black Black Black Black 667 573 +a Fh(Soft)52 b(limit)g(for)i(cache)e(size:)g(1318912)448 +781 y Fo(This)25 b(number)h(says)f(ho)n(w)g(lar)n(ge)h(the)f(cache)h +(can)f(gro)n(w)-6 b(.)33 b(This)24 b(limit)h(is)g(based)h(on)f(the)g +(size)g(of)448 894 y(the)k(unique)g(table.)43 b(CUDD)26 +b(uses)j(a)e(re)n(w)o(ard-based)k(polic)o(y)e(for)f(gro)n(wing)h(the)f +(cache.)44 b(\(See)448 1007 y(Section)32 b(4.4.1.\))49 +b(The)30 b(def)o(ault)i(hit)e(rate)h(for)g(resizing)h(is)e(30\045)g +(and)h(the)g(v)n(alue)g(in)f(ef)n(fect)h(is)448 1120 +y(reported)26 b(among)e(the)g(modi\002able)h(parameters.)p +Black Black 667 1328 a Fh(Number)51 b(of)j(buckets)d(in)j(unique)e +(table:)g(329728)448 1537 y Fo(This)28 b(number)g(is)g(e)o(xactly)h +(one)f(quarter)i(of)d(the)h(one)g(abo)o(v)o(e.)42 b(This)28 +b(is)f(indeed)j(ho)n(w)d(the)h(soft)448 1650 y(limit)37 +b(is)g(determined)i(currently)-6 b(,)43 b(unless)38 b(the)g(computed)g +(table)g(hits)g(the)f(speci\002ed)i(hard)448 1763 y(limit.)29 +b(\(See)23 b(belo)n(w)-6 b(.\))p Black Black 667 1971 +a Fh(Used)52 b(buckets)g(in)h(unique)f(table:)g(87.96\045)g(\(expected) +e(87.93\045\))448 2180 y Fo(Percentage)27 b(of)e(unique)i(table)f(b)n +(uck)o(ets)h(that)e(contain)i(at)e(least)g(one)h(node.)34 +b(Remarks)25 b(analo-)448 2293 y(gous)g(to)e(those)i(made)e(about)i +(the)f(used)g(cache)h(slots)f(apply)-6 b(.)p Black Black +667 2501 a Fh(Number)51 b(of)j(BDD)f(and)g(ADD)g(nodes:)f(836894)667 +2614 y(Number)f(of)j(ZDD)f(nodes:)f(0)448 2822 y Fo(Ho)n(w)22 +b(man)o(y)i(nodes)h(are)e(currently)j(in)e(the)g(unique)h(table,)f +(either)h(ali)n(v)o(e)e(or)h(dead.)p Black Black 667 +3031 a Fh(Number)51 b(of)j(dead)f(BDD)g(and)g(ADD)g(nodes:)f(0)667 +3144 y(Number)f(of)j(dead)f(ZDD)g(nodes:)f(0)448 3352 +y Fo(Subtract)29 b(these)f(numbers)g(from)f(those)i(abo)o(v)o(e)e(to)h +(get)f(the)g(number)i(of)e(li)n(v)o(e)g(nodes.)41 b(In)27 +b(this)448 3465 y(case)k(there)g(are)g(no)f(dead)h(nodes)g(because)i +(the)d(application)j(uses)e(delayed)h(dereferencing)448 +3578 y Fn(Cudd)p 649 3578 28 4 v 34 w(DelayedDer)m(efBdd)r +Fo(.)p Black Black 667 3786 a Fh(Total)52 b(number)g(of)h(nodes)f +(allocated:)e(836894)448 3995 y Fo(This)29 b(is)g(the)g(total)h(number) +g(of)e(nodes)j(that)e(were)g(requested)i(and)f(obtained)h(from)e(the)g +(free)448 4108 y(list.)52 b(It)31 b(ne)n(v)o(er)h(decreases,)j(and)d +(is)f(not)g(an)g(indication)j(of)e(memory)f(occupation)j(after)e(the) +448 4221 y(\002rst)23 b(garbage)i(collection.)32 b(Rather)l(,)24 +b(it)f(is)h(a)f(measure)h(of)g(the)g(package)h(acti)n(vity)-6 +b(.)p Black Black 667 4429 a Fh(Total)52 b(number)g(of)h(nodes)f +(reclaimed:)e(0)448 4638 y Fo(These)29 b(are)f(the)h(nodes)g(that)g +(were)f(resuscitated)k(from)c(the)h(dead.)43 b(If)28 +b(the)o(y)h(are)f(man)o(y)g(more)448 4751 y(than)23 b(the)e(allocated)j +(nodes,)f(and)f(the)g(total)g(number)h(of)e(slots)h(is)g(lo)n(w)f +(relati)n(v)o(e)h(to)g(the)f(number)448 4863 y(of)26 +b(nodes,)i(then)f(one)g(may)f(w)o(ant)g(to)g(increase)i(the)f(limit)f +(for)g(f)o(ast)h(unique)h(table)f(gro)n(wth.)37 b(In)448 +4976 y(this)24 b(case,)g(the)g(number)h(is)e(0)g(because)j(of)d +(delayed)i(dereferencing.)p Black 1897 5225 a(36)p Black +eop end +%%Page: 37 37 +TeXDict begin 37 36 bop Black Black Black Black 667 573 +a Fh(Garbage)51 b(collections)e(so)54 b(far:)f(0)667 +686 y(Time)f(for)h(garbage)f(collections:)d(0.00)k(sec)667 +799 y(Reorderings)c(so)54 b(far:)e(0)667 912 y(Time)g(for)h +(reordering:)d(0.00)j(sec)448 1124 y Fo(There)26 b(is)f(a)g(GC)f(for)i +(each)g(reordering.)37 b(Hence)26 b(the)f(\002rst)h(count)g(will)f(al)o +(w)o(ays)h(be)g(at)f(least)h(as)448 1237 y(lar)n(ge)f(as)f(the)f +(second.)p Black Black 667 1450 a Fh(Node)52 b(swaps)g(in)i +(reordering:)c(0)448 1662 y Fo(This)31 b(is)g(the)g(number)h(of)e +(elementary)j(reordering)h(steps.)52 b(Each)31 b(step)g(consists)i(of)e +(the)g(re-)448 1775 y(e)o(xpression)g(of)d(one)g(node)h(while)f(sw)o +(apping)i(tw)o(o)e(adjacent)i(v)n(ariables.)44 b(This)28 +b(number)h(is)f(a)448 1888 y(good)d(measure)f(of)g(the)g(amount)g(of)g +(w)o(ork)f(done)i(in)e(reordering.)448 2134 y Fp(4.8.2)92 +b(Modi\002able)23 b(P)o(arameters)448 2308 y Fo(Let)g(us)g(no)n(w)f +(consider)k(the)d(modi\002able)h(parameters,)h(that)f(is,)e(those)i +(settings)h(on)f(which)f(the)448 2421 y(application)k(or)c(the)h(user)g +(has)g(control.)p Black Black 667 2634 a Fh(****)52 b(CUDD)h +(modifiable)d(parameters)g(****)667 2746 y(Hard)i(limit)g(for)i(cache)e +(size:)g(8388608)448 2959 y Fo(This)30 b(number)i(counts)f(entries.)51 +b(Each)30 b(entry)h(is)f(16)h(bytes)g(if)f(CUDD)e(is)i(compiled)i(to)e +(use)448 3072 y(32-bit)25 b(pointers.)31 b(T)-7 b(w)o(o)22 +b(important)j(observ)n(ations)i(are)d(in)g(order:)p Black +562 3259 a(1.)p Black 46 w(If)29 b(the)i(datasize)h(limit)e(is)g(set,)h +(CUDD)d(will)i(use)g(it)g(to)g(determine)h(this)g(number)g(au-)676 +3372 y(tomatically)-6 b(.)39 b(On)26 b(a)g(Unix)g(system,)i(one)f(can)g +(type)g(\223limit\224)g(or)f(\223ulimit\224)i(to)e(v)o(erify)i(if)676 +3485 y(this)e(v)n(alue)h(is)e(set.)36 b(If)26 b(the)g(datasize)i(limit) +e(is)f(not)h(set,)h(CUDD)c(uses)k(a)e(def)o(ault)j(which)676 +3598 y(is)21 b(rather)i(small.)28 b(If)22 b(you)g(ha)n(v)o(e)g(enough)i +(memory)d(\(say)i(64MB)e(or)h(more\))f(you)i(should)676 +3711 y(seriously)29 b(consider)g Fn(not)f Fo(using)g(the)f(def)o(ault.) +40 b(So,)27 b(either)h(set)e(the)h(datasize)i(limit,)e(or)676 +3824 y(o)o(v)o(erride)d(the)g(def)o(ault)i(with)d Fn(Cudd)p +1792 3824 28 4 v 34 w(SetMaxCac)o(heHar)m(d)r Fo(.)p +Black 562 4012 a(2.)p Black 46 w(If)d(a)g(process)j(seems)e(to)g(be)f +(going)i(no)n(where,)g(a)f(small)f(v)n(alue)i(for)f(this)g(parameter)i +(may)676 4125 y(be)29 b(the)h(culprit.)47 b(One)29 b(cannot)i(o)o(v)o +(eremphasize)h(the)e(importance)i(of)d(the)h(computed)676 +4237 y(table)24 b(in)f(BDD)f(algorithms.)448 4425 y(In)i(this)g(case)g +(the)g(limit)f(w)o(as)g(automatically)k(set)d(for)f(a)g(tar)n(get)i +(maximum)f(memory)f(occupa-)448 4538 y(tion)h(of)g(104)g(MB.)p +Black Black 667 4751 a Fh(Cache)52 b(hit)h(threshold)d(for)k(resizing:) +c(15\045)p Black 1897 5225 a Fo(37)p Black eop end +%%Page: 38 38 +TeXDict begin 38 37 bop Black Black 448 573 a Fo(This)25 +b(number)g(can)g(be)f(changed)j(if)d(one)h(suspects)i(performance)g(is) +d(hindered)j(by)d(the)h(small)448 686 y(size)30 b(of)e(the)i(cache,)g +(and)g(the)f(cache)h(is)e(not)i(gro)n(wing)f(to)n(w)o(ards)h(the)f +(soft)g(limit)g(suf)n(\002ciently)448 799 y(f)o(ast.)g(In)21 +b(such)h(a)f(case)h(one)g(can)g(change)h(the)e(def)o(ault)i(30\045)f +(to)f(15\045)g(\(as)g(in)h(this)g(case\))g(or)f(e)n(v)o(en)448 +912 y(1\045.)p Black Black 667 1124 a Fh(Garbage)51 b(collection)f +(enabled:)h(yes)448 1337 y Fo(One)34 b(can)g(disable)i(it,)f(b)n(ut)g +(there)f(are)g(fe)n(w)f(good)i(reasons)h(for)e(doing)h(so.)60 +b(It)33 b(is)h(normally)448 1450 y(preferable)26 b(to)e(raise)g(the)g +(limit)g(for)f(f)o(ast)h(unique)i(table)e(gro)n(wth.)29 +b(\(See)24 b(belo)n(w)-6 b(.\))p Black Black 667 1662 +a Fh(Limit)52 b(for)h(fast)g(unique)e(table)i(growth:)e(1363148)448 +1875 y Fo(See)23 b(Section)i(4.5)f(and)g(the)g(comments)g(abo)o(v)o(e)h +(about)g(reclaimed)g(nodes)g(and)f(hard)g(limit)g(for)448 +1988 y(the)g(cache)h(size.)30 b(This)23 b(v)n(alue)i(w)o(as)e(chosen)i +(automatically)i(by)d(CUDD)d(for)j(a)g(datasize)h(limit)448 +2100 y(of)f(1)f(GB.)p Black Black 667 2313 a Fh(Maximum)51 +b(number)h(of)h(variables)e(sifted)h(per)h(reordering:)c(1000)667 +2426 y(Maximum)i(number)h(of)h(variable)e(swaps)h(per)i(reordering:)49 +b(2000000)667 2539 y(Maximum)i(growth)h(while)g(sifting)f(a)j +(variable:)d(1.2)448 2751 y Fo(Lo)n(wering)29 b(these)f(numbers)i(will) +d(cause)i(reordering)i(to)c(be)h(less)h(accurate)h(and)e(f)o(aster)-5 +b(.)43 b(Re-)448 2864 y(sults)22 b(are)f(some)n(what)g(unpredictable,)k +(because)d(lar)n(ger)g(BDDs)d(after)j(one)f(reordering)i(do)e(not)448 +2977 y(necessarily)27 b(mean)d(the)f(process)j(will)d(go)h(f)o(aster)g +(or)g(slo)n(wer)-5 b(.)p Black Black 667 3190 a Fh(Dynamic)51 +b(reordering)f(of)j(BDDs)g(enabled:)e(yes)667 3303 y(Default)g(BDD)i +(reordering)d(method:)h(4)667 3416 y(Dynamic)g(reordering)f(of)j(ZDDs)g +(enabled:)e(no)667 3528 y(Default)g(ZDD)i(reordering)d(method:)h(4)448 +3741 y Fo(These)38 b(lines)h(tell)f(whether)g(automatic)i(reordering)g +(can)e(tak)o(e)g(place)h(and)f(what)f(method)448 3854 +y(w)o(ould)28 b(be)f(used.)41 b(The)27 b(mapping)i(from)e(numbers)h(to) +f(methods)i(is)e(in)g Fh(cudd.h)p Fo(.)37 b(One)27 b(may)448 +3967 y(w)o(ant)i(to)f(try)g(dif)n(ferent)i(BDD)d(reordering)k(methods.) +44 b(If)28 b(v)n(ariable)i(groups)g(are)f(used,)h(ho)n(w-)448 +4080 y(e)n(v)o(er)l(,)21 b(one)f(should)i(not)e(e)o(xpect)h(to)e(see)h +(big)g(dif)n(ferences,)j(because)f(CUDD)c(uses)i(the)g(reported)448 +4193 y(method)31 b(only)f(to)f(reorder)i(each)f(leaf)g(v)n(ariable)h +(group)f(\(typically)i(corresponding)i(present)448 4306 +y(and)d(ne)o(xt)g(state)g(v)n(ariables\).)51 b(F)o(or)30 +b(the)h(relati)n(v)o(e)g(order)g(of)g(the)f(groups,)k(it)c(al)o(w)o +(ays)h(uses)g(the)448 4418 y(same)24 b(algorithm,)h(which)f(is)f(ef)n +(fecti)n(v)o(ely)j(sifting.)589 4531 y(As)i(for)h(enabling)h(dynamic)g +(reordering)h(or)e(not,)h(a)e(sensible)i(recommendation)i(is)c(the)448 +4644 y(follo)n(wing:)36 b(Unless)27 b(the)f(circuit)h(is)f(rather)h +(small)f(or)g(one)h(has)f(a)g(pretty)h(good)g(idea)f(of)g(what)448 +4757 y(the)e(order)h(should)g(be,)e(reordering)j(should)g(be)d +(enabled.)p Black 1897 5225 a(38)p Black eop end +%%Page: 39 39 +TeXDict begin 39 38 bop Black Black Black Black 667 573 +a Fh(Realignment)49 b(of)54 b(ZDDs)e(to)i(BDDs)f(enabled:)e(no)667 +686 y(Realignment)e(of)54 b(BDDs)e(to)i(ZDDs)f(enabled:)e(no)667 +799 y(Dead)h(nodes)g(counted)g(in)h(triggering)d(reordering:)g(no)667 +912 y(Group)i(checking)f(criterion:)f(7)667 1024 y(Recombination)e +(threshold:)i(0)667 1137 y(Symmetry)g(violation)h(threshold:)f(0)667 +1250 y(Arc)j(violation)d(threshold:)g(0)667 1363 y(GA)j(population)d +(size:)i(0)667 1476 y(Number)f(of)j(crossovers)c(for)j(GA:)g(0)448 +1681 y Fo(P)o(arameters)26 b(for)f(reordering.)37 b(See)24 +b(the)i(documentation)i(of)d(the)h(functions)i(used)e(to)f(control)448 +1794 y(these)g(parameters)g(for)f(the)g(details.)p Black +Black 667 1998 a Fh(Next)52 b(reordering)e(threshold:)g(100000)448 +2203 y Fo(When)25 b(the)g(number)g(of)g(nodes)h(crosses)g(this)f +(threshold,)i(reordering)g(will)e(be)f(triggered.)34 +b(\(If)448 2315 y(enabled;)26 b(in)d(this)h(case)f(it)g(is)g(not.\))30 +b(This)23 b(parameter)h(is)f(updated)j(by)d(the)g(package)i(whene)n(v)o +(er)448 2428 y(reordering)i(tak)o(es)f(place.)32 b(The)24 +b(application)j(can)e(change)h(it,)e(for)g(instance)j(at)d(start-up.)33 +b(An-)448 2541 y(other)24 b(possibility)h(is)e(to)f(use)h(a)f(hook)h +(function)i(\(see)e(Section)h(3.16\))f(to)f(o)o(v)o(erride)i(the)f(def) +o(ault)448 2654 y(updating)j(polic)o(y)-6 b(.)448 2899 +y Fp(4.8.3)92 b(Extended)22 b(Statistics)k(and)c(Reporting)448 +3073 y Fo(The)27 b(follo)n(wing)i(symbols)f(can)f(be)h(de\002ned)g +(during)g(compilation)i(to)d(increase)i(the)e(amount)448 +3186 y(of)d(statistics)i(gathered)f(and)f(the)g(number)g(of)g(messages) +h(produced)h(by)d(the)h(package:)p Black 585 3367 a Fm(\017)p +Black 46 w Fo(DD)p 813 3367 28 4 v 32 w(ST)-8 b(A)e(TS;)p +Black 585 3552 a Fm(\017)p Black 46 w Fo(DD)p 813 3552 +V 32 w(CA)l(CHE)p 1151 3552 V 31 w(PR)l(OFILE;)p Black +585 3737 a Fm(\017)p Black 46 w Fo(DD)p 813 3737 V 32 +w(UNIQ)o(UE)p 1194 3737 V 31 w(PR)l(OFILE.)p Black 585 +3922 a Fm(\017)p Black 46 w Fo(DD)p 813 3922 V 32 w(VERBOSE;)448 +4103 y(De\002ning)27 b(DD)p 929 4103 V 32 w(CA)l(CHE)p +1267 4103 V 32 w(PR)l(OFILE)d(causes)k(each)f(entry)h(of)e(the)h(cache) +h(to)f(include)h(an)f(ac-)448 4215 y(cess)i(counter)l(,)h(which)e(is)g +(used)g(to)g(compute)h(simple)f(statistics)i(on)e(the)g(distrib)n +(ution)j(of)d(the)448 4328 y(k)o(e)o(ys.)448 4576 y Fi(4.9)99 +b(Guidelines)25 b(f)n(or)g(Documentation)448 4751 y Fo(The)36 +b(documentation)j(of)d(the)g(CUDD)d(functions)38 b(is)e(e)o(xtracted)i +(automatically)g(from)e(the)448 4863 y(sources)23 b(by)e(Stephen)h(Edw) +o(ards')-5 b(s)21 b(e)o(xtdoc.)29 b(\(The)21 b(Ext)f(system)i(is)e(a)n +(v)n(ailable)j(via)e(anon)o(ymous)448 4976 y(FTP)27 b(from)i +Fh(ic.eecs.berkele)o(y.)o(ed)o(u)p Fo(.\))38 b(The)29 +b(follo)n(wing)h(guidelines)i(are)d(follo)n(wed)p Black +1897 5225 a(39)p Black eop end +%%Page: 40 40 +TeXDict begin 40 39 bop Black Black 448 573 a Fo(in)28 +b(CUDD)d(to)j(insure)h(consistent)h(and)f(ef)n(fecti)n(v)o(e)f(use)h +(of)e(automatic)i(e)o(xtraction.)44 b(It)27 b(is)h(rec-)448 +686 y(ommended)d(that)f(e)o(xtensions)i(to)e(CUDD)d(follo)n(w)j(the)g +(same)f(documentation)k(guidelines.)p Black 585 873 a +Fm(\017)p Black 46 w Fo(The)j(documentation)35 b(of)c(an)g(e)o(xported) +i(procedure)h(should)f(be)e(suf)n(\002cient)h(to)f(allo)n(w)676 +986 y(one)23 b(to)h(use)f(it)h(without)g(reading)h(the)f(code.)29 +b(It)23 b(is)g(not)h(necessary)i(to)d(e)o(xplain)i(ho)n(w)e(the)676 +1099 y(procedure)j(w)o(orks;)e(only)g(what)g(it)f(does.)p +Black 585 1287 a Fm(\017)p Black 46 w Fo(The)29 b Fn(SeeAlso)i +Fo(\002elds)f(should)i(be)e(space-separated)k(lists)d(of)f(function)i +(names.)49 b(The)676 1400 y Fn(SeeAlso)24 b Fo(\002eld)f(of)g(an)g(e)o +(xported)j(procedure)g(should)e(only)h(reference)g(other)f(e)o(xported) +676 1513 y(procedures.)39 b(The)26 b Fn(SeeAlso)h Fo(\002eld)f(of)h(an) +f(internal)i(procedure)h(may)d(reference)i(other)676 +1626 y(internal)c(procedures)i(as)d(well)f(as)h(e)o(xported)i +(procedures,)g(b)n(ut)f(no)f(static)h(procedures.)p Black +585 1813 a Fm(\017)p Black 46 w Fo(The)30 b(return)i(v)n(alues)g(are)f +(detailed)i(in)e(the)g Fn(Description)i Fo(\002eld,)g(not)e(in)g(the)g +Fn(Synopsis)676 1926 y Fo(\002eld.)p Black 585 2114 a +Fm(\017)p Black 46 w Fo(The)c(parameters)k(are)d(documented)j +(alongside)g(their)e(declarations.)46 b(Further)29 b(com-)676 +2227 y(ments)23 b(may)h(appear)h(in)e(the)h Fn(Description)i +Fo(\002eld.)p Black 585 2414 a Fm(\017)p Black 46 w Fo(If)i(the)i +Fn(Description)h Fo(\002eld)e(is)g(non-empty\227which)j(is)d(the)h +(normal)f(case)h(for)f(an)g(e)o(x-)676 2527 y(ported)19 +b(procedure\227then)j(the)d(synopsis)h(is)e(repeated\227possibly)23 +b(slightly)d(changed\227)676 2640 y(at)25 b(the)h(be)o(ginning)i(of)e +(the)g Fn(Description)i Fo(\002eld.)35 b(This)25 b(is)h(so)f(because)j +(e)o(xtdoc)f(will)e(not)676 2753 y(put)e(the)h(synopsis)i(in)e(the)f +(same)h(HTML)d(\002le)i(as)h(the)f(description.)p Black +585 2941 a Fm(\017)p Black 46 w Fo(The)g Fn(Synopsis)j +Fo(\002eld)d(should)i(be)f(about)g(one)g(line)g(long.)448 +3233 y Fq(5)120 b(The)30 b(C++)g(Interface)448 3444 y +Fi(5.1)99 b(Compiling)25 b(and)g(Linking)448 3618 y Fo(T)-7 +b(o)23 b(b)n(uild)i(an)e(application)k(that)d(uses)g(the)g(CUDD)d(C++)i +(interf)o(ace,)j(you)e(should)h(add)p Black Black 448 +3805 a Fh(#include)51 b("cuddObj.hh")448 3993 y Fo(to)31 +b(your)g(source)i(\002les.)50 b(In)30 b(addition)j(to)e(the)g(normal)g +(CUDD)e(libraries)j(\(see)g(Section)f(3.1\))448 4106 +y(you)22 b(should)g(link)g Fh(libobj.a)16 b Fo(to)21 +b(your)h(e)o(x)o(ecutable.)30 b(Refer)21 b(to)f(the)i +Fh(Makefile)16 b Fo(in)21 b(the)g(top)448 4219 y(le)n(v)o(el)j +(directory)i(of)d(the)h(distrib)n(ution)j(for)d(further)h(details.)448 +4468 y Fi(5.2)99 b(Basic)25 b(Manipulation)448 4642 y +Fo(The)d(follo)n(wing)i(fragment)g(of)f(code)g(illustrates)i(some)e +(simple)g(operations)j(on)c(BDDs)f(using)448 4755 y(the)j(C++)f(interf) +o(ace.)p Black 1897 5225 a(40)p Black eop end +%%Page: 41 41 +TeXDict begin 41 40 bop Black Black Black Black 448 573 +a Fh(Cudd)53 b(mgr\(0,0\);)448 686 y(BDD)h(x)g(=)g(mgr.bddVar\(\);)448 +799 y(BDD)g(y)g(=)g(mgr.bddVar\(\);)448 912 y(BDD)g(f)g(=)g(x)g(*)g(y;) +448 1024 y(BDD)g(g)g(=)g(y)g(+)g(!x;)448 1137 y(cout)f(<<)h("f)f(is")g +(<<)h(\(f)g(<=)f(g)h(?)h("")e(:)h(")g(not"\))721 1250 +y(<<)g(")g(less)e(than)h(or)h(equal)e(to)i(g\\n";)448 +1438 y Fo(This)22 b(code)h(creates)h(a)e(manager)h(called)h +Fh(mgr)c Fo(and)j(tw)o(o)e(v)n(ariables)k(in)d(it.)28 +b(It)22 b(then)h(de\002nes)g(tw)o(o)448 1551 y(functions)31 +b Fh(f)c Fo(and)h Fh(g)f Fo(in)h(terms)g(of)g(the)g(v)n(ariables.)44 +b(Finally)-6 b(,)30 b(it)e(prints)h(a)f(message)h(based)g(on)448 +1664 y(the)h(comparison)j(of)c(the)i(tw)o(o)e(functions.)50 +b(No)30 b(e)o(xplicit)h(referencing)i(or)d(dereferencing)j(is)448 +1777 y(required.)h(The)25 b(operators)i(are)d(o)o(v)o(erloaded)j(in)e +(the)g(intuiti)n(v)o(e)h(w)o(ay)-6 b(.)32 b(BDDs)23 b(are)i(freed)g +(when)448 1890 y(e)o(x)o(ecution)d(lea)n(v)o(es)e(the)g(scope)g(in)g +(which)g(the)o(y)f(are)h(de\002ned)g(or)f(when)h(the)g(v)n(ariables)h +(referring)448 2002 y(to)j(them)f(are)h(o)o(v)o(erwritten.)448 +2295 y Fq(6)120 b(Ackno)o(wledgments)448 2502 y Fo(The)27 +b(contrib)n(utors:)40 b(Iris)27 b(Bahar)l(,)h(Hyunw)o(oo)g(Cho,)f +(Erica)g(Frohm,)g(Charlie)h(Gaona,)g(Cheng)448 2615 y(Hua,)k(Jae-Y)-10 +b(oung)32 b(Jang,)g(Seh-W)-7 b(oong)31 b(Jeong,)i(Balakrishna)g(K)o +(umthekar)l(,)g(Enrico)d(Macii,)448 2728 y(Bobbie)19 +b(Manne,)h(In-Ho)e(Moon,)h(Curt)f(Musfeldt,)j(Shipra)d(P)o(anda,)h +(Abelardo)h(P)o(ardo,)f(Bernard)448 2841 y(Plessier)l(,)28 +b(Ka)n(vita)f(Ra)n(vi,)g(Hyongk)o(yoon)i(Shin,)d(Alan)h(Shuler)l(,)g +(Arun)f(Si)n(v)n(akumaran,)i(Jor)n(gen)448 2954 y(Si)n(v)o(esind.)448 +3067 y(The)k(early)h(adopters:)49 b(Gianpiero)34 b(Cabodi,)h(Jordi)e +(Cortadella,)j(Mario)d(Escobar)l(,)j(Gayani)448 3180 +y(Gamage,)28 b(Gary)f(Hachtel,)i(Mariano)g(Hermida,)f(W)-7 +b(oohyuk)28 b(Lee,)f(Enric)g(P)o(astor)l(,)i(Massimo)448 +3292 y(Poncino,)c(Ellen)e(Sento)o(vich,)i(the)f(students)i(of)d +(ECEN5139.)589 3405 y(I)36 b(am)f(also)h(particularly)k(indebted)e(to)e +(the)g(follo)n(wing)h(people)g(for)g(in-depth)h(discus-)448 +3518 y(sions)23 b(on)f(BDDs:)27 b(Armin)22 b(Biere,)g(Oli)n(vier)g +(Coudert,)h(Arie)f(Gur\002nk)o(el,)h(Geert)f(Janssen,)i(Don)448 +3631 y(Knuth,)39 b(Da)n(vid)d(Long,)i(Jean)f(Christophe)g(Madre,)i(K)n +(en)c(McMillan,)k(Shin-Ichi)e(Minato,)448 3744 y(Jaehong)24 +b(P)o(ark,)c(Rajee)n(v)i(Ranjan,)g(Rick)f(Rudell,)h(Ellen)f(Sento)o +(vich,)i(T)-7 b(om)20 b(Shiple,)i(Christian)448 3857 +y(Stangier)l(,)j(and)f(Bw)o(olen)g(Y)-9 b(ang.)589 3970 +y(Special)28 b(thanks)h(to)e(Norris)h(Ip)f(for)g(guiding)j(my)c(f)o +(altering)k(steps)e(in)f(the)g(design)i(of)e(the)448 +4083 y(C++)h(interf)o(ace.)46 b(Gianpiero)30 b(Cabodi)f(and)g(Stef)o +(ano)g(Quer)g(ha)n(v)o(e)g(graciously)i(agreed)f(to)e(let)448 +4196 y(me)23 b(distrib)n(ute)j(their)f(dddmp)f(library)h(with)f(CUDD.) +589 4309 y(Masahiro)j(Fujita,)e(Gary)g(Hachtel,)h(and)f(Carl)g(Pixle)o +(y)g(ha)n(v)o(e)h(pro)o(vided)h(encouragement)448 4422 +y(and)d(advice.)589 4534 y(The)31 b(National)i(Science)f(F)o(oundation) +h(and)f(the)f(Semiconductor)j(Research)f(Corpora-)448 +4647 y(tion)24 b(ha)n(v)o(e)h(supported)h(in)d(part)h(the)g(de)n(v)o +(elopment)i(of)d(this)i(package.)p Black 1897 5225 a(41)p +Black eop end +%%Page: 42 42 +TeXDict begin 42 41 bop Black Black 448 573 a Fq(Refer)n(ences)p +Black 494 780 a Fo([1])p Black 46 w(R.)27 b(I.)h(Bahar)l(,)i(E.)e(A.)f +(Frohm,)i(C.)e(M.)h(Gaona,)i(G.)d(D.)g(Hachtel,)j(E.)e(Macii,)h(A.)f(P) +o(ardo,)645 893 y(and)d(F)-7 b(.)23 b(Somenzi.)36 b(Algebraic)27 +b(decision)f(diagrams)g(and)f(their)g(applications.)40 +b(In)25 b Fn(Pr)l(o-)645 1006 y(ceedings)30 b(of)d(the)h(International) +k(Confer)m(ence)d(on)e(Computer)n(-Aided)j(Design)p Fo(,)f(pages)645 +1119 y(188\226191,)d(Santa)e(Clara,)f(CA,)f(No)o(v)o(ember)h(1993.)p +Black 494 1306 a([2])p Black 46 w(B.)36 b(Bollig,)41 +b(M.)35 b(L)8 b(\250)-38 b(obbing,)42 b(and)c(I.)e(W)-7 +b(e)o(gener)i(.)77 b(Simulated)38 b(annealing)i(to)d(impro)o(v)o(e)645 +1419 y(v)n(ariable)31 b(orderings)h(for)e(OBDDs.)50 b(Presented)30 +b(at)g(the)f(International)k(W)-7 b(orkshop)31 b(on)645 +1532 y(Logic)24 b(Synthesis,)h(Granlibakk)o(en,)h(CA,)c(May)h(1995.)p +Black 494 1720 a([3])p Black 46 w(K.)29 b(S.)f(Brace,)k(R.)d(L.)f +(Rudell,)k(and)f(R.)d(E.)h(Bryant.)55 b(Ef)n(\002cient)30 +b(implementation)j(of)d(a)645 1833 y(BDD)f(package.)57 +b(In)30 b Fn(Pr)l(oceedings)j(of)e(the)f(27th)h(Design)h(A)n(utomation) +g(Confer)m(ence)p Fo(,)645 1945 y(pages)25 b(40\22645,)g(Orlando,)f +(FL,)e(June)i(1990.)p Black 494 2133 a([4])p Black 46 +w(R.)g(K.)g(Brayton)j(et)e(al.)40 b(VIS:)24 b(A)h(system)h(for)f(v)o +(eri\002cation)j(and)e(synthesis.)42 b(T)-6 b(echnical)645 +2246 y(Report)31 b(UCB/ERL)26 b(M95/104,)33 b(Electronics)f(Research)f +(Lab,)g(Uni)n(v)-6 b(.)29 b(of)h(California,)645 2359 +y(December)24 b(1995.)p Black 494 2547 a([5])p Black +46 w(R.)32 b(E.)g(Bryant.)65 b(Graph-based)36 b(algorithms)g(for)d +(Boolean)i(function)h(manipulation.)645 2659 y Fn(IEEE)22 +b(T)-5 b(r)o(ansactions)26 b(on)e(Computer)o(s)p Fo(,)g +(C-35\(8\):677\226691,)k(August)c(1986.)p Black 494 2847 +a([6])p Black 46 w(R.)32 b(Drechsler)l(,)38 b(B.)32 b(Beck)o(er)l(,)k +(and)e(N.)e(G)8 b(\250)-38 b(ock)o(el.)66 b(A)32 b(genetic)j(algorithm) +g(for)f(v)n(ariable)645 2960 y(ordering)27 b(of)e(OBDDs.)35 +b(Presented)26 b(at)f(the)g(International)j(W)-7 b(orkshop)27 +b(on)d(Logic)h(Syn-)645 3073 y(thesis,)g(Granlibakk)o(en,)h(CA,)c(May)h +(1995.)p Black 494 3261 a([7])p Black 46 w(S.)j(J.)g(Friedman)i(and)g +(K.)e(J.)g(Supo)n(wit.)45 b(Finding)28 b(the)g(optimal)g(v)n(ariable)h +(ordering)g(for)645 3373 y(binary)24 b(decision)h(diagrams.)32 +b Fn(IEEE)21 b(T)-5 b(r)o(ansactions)25 b(on)d(Computer)o(s)p +Fo(,)i(39\(5\):710\226713,)645 3486 y(May)g(1990.)p Black +494 3674 a([8])p Black 46 w(M.)35 b(Fujita,)k(Y)-12 b(.)35 +b(Matsunaga,)40 b(and)d(T)-7 b(.)34 b(Kakuda.)74 b(On)35 +b(v)n(ariable)j(ordering)g(of)e(binary)645 3787 y(decision)30 +b(diagrams)f(for)f(the)g(application)j(of)c(multi-le)n(v)o(el)i(logic)g +(synthesis.)49 b(In)28 b Fn(Pr)l(o-)645 3900 y(ceedings)33 +b(of)e(the)g(Eur)l(opean)h(Confer)m(ence)h(on)e(Design)g(A)n(utomation) +p Fo(,)j(pages)e(50\22654,)645 4013 y(Amsterdam,)24 b(February)h(1991.) +p Black 494 4200 a([9])p Black 46 w(M.)h(Held)g(and)i(R.)d(M.)g(Karp.) +44 b(A)25 b(dynamic)j(programming)h(approach)g(to)e(sequencing)645 +4313 y(problems.)35 b Fn(J)n(.)23 b(SIAM)p Fo(,)f(10\(1\):196\226210,) +28 b(1962.)p Black 448 4501 a([10])p Black 47 w(N.)e(Ishiura,)i(H.)e +(Sa)o(w)o(ada,)h(and)g(S.)e(Y)-9 b(ajima.)43 b(Minimization)29 +b(of)e(binary)h(decision)h(dia-)645 4614 y(grams)f(based)g(on)g(e)o +(xchanges)h(of)e(v)n(ariables.)48 b(In)27 b Fn(Pr)l(oceedings)j(of)d +(the)g(International)645 4727 y(Confer)m(ence)37 b(on)e(Computer)n +(-Aided)j(Design)p Fo(,)g(pages)e(472\226475,)k(Santa)35 +b(Clara,)j(CA,)645 4840 y(No)o(v)o(ember)24 b(1991.)p +Black 1897 5225 a(42)p Black eop end +%%Page: 43 43 +TeXDict begin 43 42 bop Black Black Black 448 573 a Fo([11])p +Black 47 w(S.-W)-8 b(.)31 b(Jeong,)37 b(T)-7 b(.-S.)31 +b(Kim,)k(and)e(F)-7 b(.)32 b(Somenzi.)64 b(An)33 b(ef)n(\002cient)h +(method)g(for)f(optimal)645 686 y(BDD)25 b(ordering)k(computation.)47 +b(In)27 b Fn(International)k(Confer)m(ence)e(on)e(VLSI)f(and)h(CAD)645 +799 y(\(ICVC'93\))p Fo(,)c(T)-7 b(aejon,)24 b(K)m(orea,)f(No)o(v)o +(ember)h(1993.)p Black 448 986 a([12])p Black 47 w(S.-I.)29 +b(Minato.)55 b(Zero-suppressed)35 b(BDDs)28 b(for)j(set)f(manipulation) +j(in)d(combinatorial)645 1099 y(problems.)35 b(In)24 +b Fn(Pr)l(oceedings)i(of)e(the)g(Design)g(A)n(utomation)h(Confer)m +(ence)p Fo(,)g(pages)g(272\226)645 1212 y(277,)f(Dallas,)g(TX,)d(June)k +(1993.)p Black 448 1400 a([13])p Black 47 w(S.)38 b(P)o(anda)i(and)f(F) +-7 b(.)38 b(Somenzi.)85 b(Who)39 b(are)h(the)f(v)n(ariables)j(in)d +(your)h(neighborhood.)645 1513 y(In)28 b Fn(Pr)l(oceedings)i(of)d(the)h +(International)j(Confer)m(ence)e(on)f(Computer)n(-Aided)i(Design)p +Fo(,)645 1626 y(pages)25 b(74\22677,)g(San)e(Jose,)h(CA,)d(No)o(v)o +(ember)j(1995.)p Black 448 1813 a([14])p Black 47 w(S.)41 +b(P)o(anda,)48 b(F)-7 b(.)40 b(Somenzi,)48 b(and)43 b(B.)e(F)-7 +b(.)41 b(Plessier)-5 b(.)96 b(Symmetry)43 b(detection)i(and)e(dy-)645 +1926 y(namic)31 b(v)n(ariable)i(ordering)f(of)f(decision)i(diagrams.)57 +b(In)30 b Fn(Pr)l(oceedings)k(of)c(the)h(Inter)n(-)645 +2039 y(national)h(Confer)m(ence)g(on)e(Computer)n(-Aided)i(Design)p +Fo(,)f(pages)g(628\226631,)j(San)29 b(Jose,)645 2152 +y(CA,)22 b(No)o(v)o(ember)i(1994.)p Black 448 2340 a([15])p +Black 47 w(B.)i(F)-7 b(.)25 b(Plessier)-5 b(.)46 b Fn(A)26 +b(Gener)o(al)i(F)-5 b(r)o(ame)o(work)27 b(for)g(V)-10 +b(eri\002cation)30 b(of)d(Sequential)j(Cir)m(cuits)p +Fo(.)645 2452 y(PhD)24 b(thesis,)i(Uni)n(v)o(ersity)h(of)e(Colorado)h +(at)f(Boulder)l(,)i(Dept.)d(of)h(Electrical)i(and)e(Com-)645 +2565 y(puter)g(Engineering,)h(1993.)p Black 448 2753 +a([16])p Black 47 w(R.)e(Rudell.)41 b(Dynamic)25 b(v)n(ariable)j +(ordering)f(for)f(ordered)h(binary)g(decision)h(diagrams.)645 +2866 y(In)g Fn(Pr)l(oceedings)i(of)d(the)h(International)j(Confer)m +(ence)e(on)f(Computer)n(-Aided)i(Design)p Fo(,)645 2979 +y(pages)25 b(42\22647,)g(Santa)e(Clara,)h(CA,)d(No)o(v)o(ember)j(1993.) +p Black 448 3166 a([17])p Black 47 w(E.)43 b(M.)f(Sento)o(vich,)51 +b(K.)42 b(J.)i(Singh,)49 b(C.)42 b(Moon,)50 b(H.)42 b(Sa)n(v)n(oj,)50 +b(R.)42 b(K.)h(Brayton,)50 b(and)645 3279 y(A.)35 b(Sangio)o(v)n +(anni-V)-5 b(incentelli.)79 b(Sequential)38 b(circuit)g(design)g(using) +f(synthesis)i(and)645 3392 y(optimization.)55 b(In)29 +b Fn(Pr)l(oceedings)j(of)e(the)f(International)34 b(Confer)m(ence)d(on) +e(Computer)645 3505 y(Design)p Fo(,)24 b(pages)h(328\226333,)h +(Cambridge,)e(MA,)e(October)i(1992.)p Black 1897 5225 +a(43)p Black eop end +%%Page: 44 44 +TeXDict begin 44 43 bop Black Black Black 448 705 a Fq(Index)p +Black 448 892 a Fo(ADD,)22 b(4,)h(7,)f(11,)i(13)448 1005 +y(aggre)o(gation,)i(18)448 1118 y(Algebraic)f(Decision)g(Diagram,)f +Fn(see)g Fo(ADD)448 1231 y(arc)614 1344 y(complement,)h(11,)f(25,)f(28) +614 1457 y(re)o(gular)l(,)i(25,)f(28)448 1653 y(background)j(v)n(alue,) +d(10)448 1766 y(BDD,)e(4,)h(7,)f(10,)i(12)448 1878 y(Binary)g(Decision) +h(Diagram,)f Fn(see)g Fo(BDD)448 1991 y(box)614 2104 +y(black,)h(4)614 2217 y(clear)l(,)g(4,)e(24)448 2413 +y(cache,)i(8,)e(28,)g(29)614 2526 y(collision,)j(35)614 +2639 y(collision)g(list,)e(31)614 2752 y(deletion,)i(35)614 +2865 y(local,)f(29,)e(30)614 2978 y(lossless,)j(30)614 +3091 y(re)n(w)o(ard-based)h(resizing,)e(30)614 3204 y(sizing,)g(29)448 +3316 y(cacheSize,)g(8)448 3429 y(canonical,)h(7,)d(30)448 +3542 y(compiling,)i(6,)e(10,)h(24)448 3655 y(con\002guration,)j(5)448 +3768 y(con)l(v)o(ersion)614 3881 y(of)d(ADDs)e(to)h(BDDs,)f(15)614 +3994 y(of)i(BDDs)e(to)h(ADDs,)f(15)614 4107 y(of)i(BDDs)e(to)h(ZDDs,)f +(14,)h(15)614 4220 y(of)h(ZDDs)e(to)h(BDDs,)f(15)448 +4333 y(cube)j(sets,)e(4)448 4446 y(cudd.h,)i(6,)e(17,)g(28)448 +4558 y Fn(Cudd)p 649 4558 28 4 v 34 w(addApply)p Fo(,)i(13,)e(14)448 +4671 y Fn(Cudd)p 649 4671 V 34 w(addBddInterval)p Fo(,)k(15)448 +4784 y Fn(Cudd)p 649 4784 V 34 w(addBddP)-7 b(attern)p +Fo(,)26 b(15)448 4897 y Fn(Cudd)p 649 4897 V 34 w(addBddThr)m(eshold)p +Fo(,)h(15)p Black Black 1984 892 a Fn(Cudd)p 2185 892 +V 34 w(addConst)p Fo(,)e(11)1984 1005 y Fn(Cudd)p 2185 +1005 V 34 w(addHarwell)p Fo(,)g(11)1984 1118 y Fn(Cudd)p +2185 1118 V 34 w(AddHook)p Fo(,)f(22)1984 1231 y Fn(Cudd)p +2185 1231 V 34 w(addIthBit)p Fo(,)h(15)1984 1344 y Fn(Cudd)p +2185 1344 V 34 w(addIthV)-10 b(ar)p Fo(,)25 b(11)1984 +1457 y Fn(Cudd)p 2185 1457 V 34 w(addNe)o(wV)-10 b(ar)p +Fo(,)23 b(11)1984 1570 y Fn(Cudd)p 2185 1570 V 34 w(addNe)o(wV)-10 +b(arAtLe)o(vel)p Fo(,)24 b(11,)f(20)1984 1683 y Fn(Cudd)p +2185 1683 V 34 w(addRead)p Fo(,)i(11)1984 1795 y Fn(Cudd)p +2185 1795 V 34 w(addT)-5 b(imes)p Fo(,)24 b(14)1984 1908 +y Fn(Cudd)p 2185 1908 V 34 w(A)n(utodynDisable)p Fo(,)i(17)1984 +2021 y Fn(Cudd)p 2185 2021 V 34 w(A)n(utodynDisableZdd)p +Fo(,)h(20)1984 2134 y Fn(Cudd)p 2185 2134 V 34 w(A)n(utodynEnable)p +Fo(,)f(17)1984 2247 y Fn(Cudd)p 2185 2247 V 34 w(A)n(utodynEnableZdd)p +Fo(,)h(20)1984 2360 y Fn(Cudd)p 2185 2360 V 34 w(bddAnd)p +Fo(,)d(12\22614)1984 2473 y Fn(Cudd)p 2185 2473 V 34 +w(bddAndLimit)p Fo(,)g(22)1984 2586 y Fn(Cudd)p 2185 +2586 V 34 w(bddConstr)o(ain)p Fo(,)i(7)1984 2699 y Fn(Cudd)p +2185 2699 V 34 w(bddIte)p Fo(,)f(12)1984 2812 y Fn(Cudd)p +2185 2812 V 34 w(bddIthV)-10 b(ar)p Fo(,)25 b(11)1984 +2925 y Fn(Cudd)p 2185 2925 V 34 w(bddNe)o(wV)-10 b(ar)p +Fo(,)23 b(11)1984 3037 y Fn(Cudd)p 2185 3037 V 34 w(bddNe)o(wV)-10 +b(arAtLe)o(vel)p Fo(,)24 b(11,)f(20)1984 3150 y Fn(Cudd)p +2185 3150 V 34 w(BddT)-8 b(oAdd)p Fo(,)23 b(15)1984 3263 +y Fn(Cudd)p 2185 3263 V 34 w(bddXor)p Fo(,)h(14)1984 +3376 y(CUDD)p 2248 3376 V 31 w(CA)l(CHE)p 2585 3376 V +32 w(SLO)l(TS,)c(8)1984 3489 y Fn(Cudd)p 2185 3489 V +34 w(Chec)n(kK)m(e)m(ys)p Fo(,)25 b(33)1984 3602 y Fn(Cudd)p +2185 3602 V 34 w(Chec)n(kZer)l(oRef)p Fo(,)g(34)1984 +3715 y Fn(Cudd)p 2185 3715 V 34 w(CountMinterm)p Fo(,)g(11)1984 +3828 y Fn(Cudd)p 2185 3828 V 34 w(Deb)n(ugChec)n(k)p +Fo(,)g(33)1984 3941 y Fn(Cudd)p 2185 3941 V 34 w(DelayedDer)m(efBdd)p +Fo(,)g(36)1984 4054 y Fn(Cudd)p 2185 4054 V 34 w(Der)m(ef)p +Fo(,)e(27,)g(28)1984 4167 y Fn(Cudd)p 2185 4167 V 34 +w(DumpBlif)p Fo(,)g(24)1984 4279 y Fn(Cudd)p 2185 4279 +V 34 w(DumpDaV)-7 b(inci)p Fo(,)24 b(24)1984 4392 y Fn(Cudd)p +2185 4392 V 34 w(DumpDot)p Fo(,)f(24)1984 4505 y Fn(Cudd)p +2185 4505 V 34 w(F)-10 b(or)m(eac)o(hCube)p Fo(,)25 b(6,)e(11)1984 +4618 y Fn(Cudd)p 2185 4618 V 34 w(F)-10 b(or)m(eac)o(hNode)p +Fo(,)25 b(6)1984 4731 y Fn(Cudd)p 2185 4731 V 34 w(HookT)-7 +b(ype)p Fo(,)24 b(21)1984 4844 y Fn(Cudd)p 2185 4844 +V 34 w(Init)p Fo(,)g(8,)f(9)1984 4957 y Fn(Cudd)p 2185 +4957 V 34 w(Mak)o(eT)-5 b(r)m(eeNode)p Fo(,)25 b(19,)e(20)p +Black 1897 5225 a(44)p Black eop end +%%Page: 45 45 +TeXDict begin 45 44 bop Black Black 448 573 a Fn(Cudd)p +649 573 28 4 v 34 w(Mak)o(eZddT)-5 b(r)m(eeNode)p Fo(,)25 +b(21)448 686 y Fn(Cudd)p 649 686 V 34 w(Not)p Fo(,)e(10)448 +799 y Fn(Cudd)p 649 799 V 34 w(PrintInfo)p Fo(,)i(34)448 +912 y Fn(Cudd)p 649 912 V 34 w(PrintMinterm)p Fo(,)f(11)448 +1024 y Fn(Cudd)p 649 1024 V 34 w(Quit)p Fo(,)f(9)448 +1137 y Fn(Cudd)p 649 1137 V 34 w(ReadBac)n(kgr)l(ound)p +Fo(,)k(10)448 1250 y Fn(Cudd)p 649 1250 V 34 w(ReadEpsilon)p +Fo(,)e(10)448 1363 y Fn(Cudd)p 649 1363 V 34 w(ReadErr)l(orCode)p +Fo(,)g(27)448 1476 y Fn(Cudd)p 649 1476 V 34 w(ReadIn)l(vP)-7 +b(erm)p Fo(,)24 b(13)448 1589 y Fn(Cudd)p 649 1589 V +34 w(ReadLo)o(gicZer)l(o)p Fo(,)h(10)448 1702 y Fn(Cudd)p +649 1702 V 34 w(ReadLooseUpto)p Fo(,)g(9)448 1815 y Fn(Cudd)p +649 1815 V 34 w(ReadMaxGr)l(owth)p Fo(,)g(18)448 1928 +y Fn(Cudd)p 649 1928 V 34 w(ReadMinusIn\002nity)p Fo(,)i(10)448 +2041 y Fn(Cudd)p 649 2041 V 34 w(ReadOne)p Fo(,)d(9)448 +2154 y Fn(Cudd)p 649 2154 V 34 w(ReadPlusIn\002nity)p +Fo(,)i(10)448 2267 y Fn(Cudd)p 649 2267 V 34 w(ReadReor)m(derings)p +Fo(,)g(33)448 2379 y Fn(Cudd)p 649 2379 V 34 w(ReadSiftMaxV)-10 +b(ar)p Fo(,)25 b(18)448 2492 y Fn(Cudd)p 649 2492 V 34 +w(ReadT)-5 b(r)m(ee)p Fo(,)24 b(19)448 2605 y Fn(Cudd)p +649 2605 V 34 w(ReadZddOne)p Fo(,)g(9,)f(15)448 2718 +y Fn(Cudd)p 649 2718 V 34 w(ReadZer)l(o)p Fo(,)h(10)448 +2831 y Fn(Cudd)p 649 2831 V 34 w(Recur)o(siveDer)m(ef)p +Fo(,)i(7,)d(26\22628,)h(30,)g(33)448 2944 y Fn(Cudd)p +649 2944 V 34 w(Recur)o(siveDer)m(efZdd)p Fo(,)i(7,)d(26\22628)448 +3057 y Fn(Cudd)p 649 3057 V 34 w(ReduceHeap)p Fo(,)i(17)448 +3170 y Fn(Cudd)p 649 3170 V 34 w(Ref)p Fo(,)e(7,)g(12,)g(26,)g(27)448 +3283 y Fn(Cudd)p 649 3283 V 34 w(Re)l(gular)p Fo(,)i(28)448 +3396 y(CUDD)p 712 3396 V 32 w(REORDER)p 1171 3396 V 30 +w(ANNEALING,)19 b(19)448 3509 y(CUDD)p 712 3509 V 32 +w(REORDER)p 1171 3509 V 30 w(EXA)l(CT)-7 b(,)21 b(19)448 +3621 y(CUDD)p 712 3621 V 32 w(REORDER)p 1171 3621 V 30 +w(GENETIC,)f(19)448 3734 y(CUDD)p 712 3734 V 32 w(REORDER)p +1171 3734 V 30 w(GR)l(OUP)p 1507 3734 V 31 w(SIFT)-7 +b(,)21 b(18)448 3847 y(CUDD)p 712 3847 V 32 w(REORDER)p +1171 3847 V 30 w(GR)l(OUP)p 1507 3847 V 31 w(SIFT)p 1726 +3847 V 31 w(CONV)-12 b(,)780 3960 y(18)448 4073 y(CUDD)p +712 4073 V 32 w(REORDER)p 1171 4073 V 30 w(NONE,)20 b(17,)k(20)448 +4186 y(CUDD)p 712 4186 V 32 w(REORDER)p 1171 4186 V 30 +w(RANDOM,)c(17,)j(20)448 4299 y(CUDD)p 712 4299 V 32 +w(REORDER)p 1171 4299 V 30 w(RANDOM)p 1607 4299 V 30 +w(PIV)l(O)l(T)-7 b(,)780 4412 y(17,)24 b(20)448 4525 +y(CUDD)p 712 4525 V 32 w(REORDER)p 1171 4525 V 30 w(SAME,)d(17,)i(20) +448 4638 y(CUDD)p 712 4638 V 32 w(REORDER)p 1171 4638 +V 30 w(SIFT)-7 b(,)21 b(17,)j(21)448 4751 y(CUDD)p 712 +4751 V 32 w(REORDER)p 1171 4751 V 30 w(SIFT)p 1389 4751 +V 31 w(CONVERGE,)780 4863 y(18,)g(21)448 4976 y(CUDD)p +712 4976 V 32 w(REORDER)p 1171 4976 V 30 w(SYMM)p 1480 +4976 V 31 w(SIFT)-7 b(,)16 b(18,)j(21)p Black Black 1984 +573 a(CUDD)p 2248 573 V 31 w(REORDER)p 2706 573 V 30 +w(SYMM)p 3015 573 V 32 w(SIFT)p 3235 573 V 32 w(CONV)-12 +b(,)2316 686 y(18,)24 b(21)1984 799 y(CUDD)p 2248 799 +V 31 w(REORDER)p 2706 799 V 30 w(WINDO)m(W2,)e(18)1984 +912 y(CUDD)p 2248 912 V 31 w(REORDER)p 2706 912 V 30 +w(WINDO)m(W2)p 3178 912 V 32 w(CONV)-12 b(,)2316 1024 +y(18)1984 1137 y(CUDD)p 2248 1137 V 31 w(REORDER)p 2706 +1137 V 30 w(WINDO)m(W3,)22 b(18)1984 1250 y(CUDD)p 2248 +1250 V 31 w(REORDER)p 2706 1250 V 30 w(WINDO)m(W3)p 3178 +1250 V 32 w(CONV)-12 b(,)2316 1363 y(18)1984 1476 y(CUDD)p +2248 1476 V 31 w(REORDER)p 2706 1476 V 30 w(WINDO)m(W4,)22 +b(18)1984 1589 y(CUDD)p 2248 1589 V 31 w(REORDER)p 2706 +1589 V 30 w(WINDO)m(W4)p 3178 1589 V 32 w(CONV)-12 b(,)2316 +1702 y(19)1984 1815 y Fn(Cudd)p 2185 1815 V 34 w(SetEpsilon)p +Fo(,)25 b(10)1984 1928 y Fn(Cudd)p 2185 1928 V 34 w(SetLooseUpT)-8 +b(o)p Fo(,)24 b(9)1984 2041 y Fn(Cudd)p 2185 2041 V 34 +w(SetMaxCac)o(heHar)m(d)p Fo(,)h(37)1984 2154 y Fn(Cudd)p +2185 2154 V 34 w(SetMaxGr)l(owth)p Fo(,)g(18)1984 2267 +y Fn(Cudd)p 2185 2267 V 34 w(SetSiftMaxV)-10 b(ar)p Fo(,)26 +b(18)1984 2379 y Fn(Cudd)p 2185 2379 V 34 w(SetT)-5 b(imeLimit)p +Fo(,)23 b(22)1984 2492 y Fn(Cudd)p 2185 2492 V 34 w(SetT)-5 +b(r)m(ee)p Fo(,)24 b(19)1984 2605 y Fn(Cudd)p 2185 2605 +V 34 w(Shuf)n(\003eHeap)p Fo(,)i(19)1984 2718 y Fn(Cudd)p +2185 2718 V 34 w(StdP)-7 b(ostReor)m(dHook)p Fo(,)26 +b(22)1984 2831 y Fn(Cudd)p 2185 2831 V 34 w(StdPr)m(eReor)m(dHook)p +Fo(,)f(22)1984 2944 y Fn(Cudd)p 2185 2944 V 34 w(SymmPr)l(o\002le)p +Fo(,)f(18)1984 3057 y(CUDD)p 2248 3057 V 31 w(UNIQ)o(UE)p +2628 3057 V 32 w(SLO)l(TS,)c(8)1984 3170 y Fn(Cudd)p +2185 3170 V 34 w(zddDumpDot)p Fo(,)k(24)1984 3283 y Fn(Cudd)p +2185 3283 V 34 w(zddIsop)p Fo(,)h(15)1984 3396 y Fn(Cudd)p +2185 3396 V 34 w(zddIthV)-10 b(ar)p Fo(,)25 b(12)1984 +3509 y Fn(Cudd)p 2185 3509 V 34 w(zddP)-7 b(ortF)i(r)l(omBdd)p +Fo(,)24 b(16)1984 3621 y Fn(Cudd)p 2185 3621 V 34 w(zddP)-7 +b(ortT)f(oBdd)p Fo(,)24 b(16)1984 3734 y Fn(Cudd)p 2185 +3734 V 34 w(zddRealignDisable)p Fo(,)j(21)1984 3847 y +Fn(Cudd)p 2185 3847 V 34 w(zddRealignEnable)p Fo(,)g(21)1984 +3960 y Fn(Cudd)p 2185 3960 V 34 w(zddReduceHeap)p Fo(,)f(20)1984 +4073 y Fn(Cudd)p 2185 4073 V 34 w(zddShuf)n(\003eHeap)p +Fo(,)h(20)1984 4186 y Fn(Cudd)p 2185 4186 V 34 w(zddV)-10 +b(ar)o(sF)-5 b(r)l(omBddV)-10 b(ar)o(s)p Fo(,)25 b(16)1984 +4299 y Fn(Cudd)p 2185 4299 V 34 w(zddW)-8 b(eakDiv)p +Fo(,)24 b(15)1984 4412 y Fn(cuddCac)o(heInsert)p Fo(,)j(29)1984 +4525 y Fn(cuddCac)o(heInsert1)p Fo(,)h(29)1984 4638 y +Fn(cuddCac)o(heInsert2)p Fo(,)g(29)1984 4751 y Fn(cuddCac)o(heLookup)p +Fo(,)f(29)1984 4863 y Fn(cuddCac)o(heLookup1)p Fo(,)g(29)1984 +4976 y Fn(cuddCac)o(heLookup2)p Fo(,)g(29)p Black 1897 +5225 a(45)p Black eop end +%%Page: 46 46 +TeXDict begin 46 45 bop Black Black 448 573 a Fo(CUDDDIR,)21 +b(22)448 686 y Fn(cuddHeapPr)l(o\002le)p Fo(,)27 b(33)448 +799 y Fn(cuddI)p Fo(,)e(31)448 912 y(cuddInt.h,)h(33)448 +1024 y Fn(cuddIZ)p Fo(,)e(31)448 1137 y Fn(cuddSatDec)p +Fo(,)i(28)448 1250 y Fn(cuddSatInc)p Fo(,)h(28)448 1363 +y Fn(cuddUniqueConst)p Fo(,)g(26)448 1476 y Fn(cuddUniqueInter)p +Fo(,)h(26,)23 b(28,)h(32,)f(33)448 1589 y Fn(cuddUniqueInterZdd)p +Fo(,)28 b(26,)c(32)448 1777 y(DD)p 585 1777 28 4 v 32 +w(CA)l(CHE)p 923 1777 V 31 w(PR)l(OFILE,)d(39)448 1890 +y(DD)p 585 1890 V 32 w(DEB)o(UG,)g(33)448 2003 y(DD)p +585 2003 V 32 w(ST)-8 b(A)e(TS,)20 b(39)448 2116 y(DD)p +585 2116 V 32 w(UNIQ)o(UE)p 966 2116 V 31 w(PR)l(OFILE,)h(39)448 +2229 y(DD)p 585 2229 V 32 w(VERBOSE,)f(39)448 2342 y(DdManager)l(,)25 +b(7,)e(8)448 2455 y(DdNode,)h(6,)f(29)448 2568 y(deb)n(ugging,)k(33)448 +2681 y(DEC)22 b(Alpha,)h(23)448 2793 y(DEC)f(Alpha,)h(10)448 +2906 y(documentation,)k(39)614 3019 y Fn(Description)p +Fo(,)f(40)614 3132 y(HTML)c(\002les,)h(40)614 3245 y +Fn(SeeAlso)p Fo(,)i(40)614 3358 y Fn(Synopsis)p Fo(,)h(40)448 +3471 y(dot,)e Fn(see)g Fo(graph,)g(dra)o(wing)448 3659 +y(Epsilon,)h(10)448 3772 y(e)o(xtdoc,)g Fn(see)f Fo(documentation)448 +3960 y(\003oating)h(point,)f(10)614 4073 y(double)i(\(C)c(type\),)i(7) +614 4186 y(IEEE)e(Standard)j(754,)f(10)448 4299 y(free)g(list,)g(26)448 +4412 y(FTP)-10 b(,)21 b(5,)i(23,)h(39)448 4525 y(function)614 +4638 y(characteristic,)j(4,)c(16)614 4751 y(co)o(v)o(er)l(,)h(15,)g(16) +697 4863 y(irredundant,)j(15)614 4976 y(minterms,)d(11,)g(32)p +Black Black 2150 573 a(ON-set,)f(4)2150 686 y(sum)h(of)f(products,)j +(11)2150 799 y(switching,)f(4)1984 995 y(garbage)g(collection,)h +(7\2269,)e(26,)f(29\22631)2150 1108 y(hooks,)i(21)1984 +1220 y(gcc,)f(10)1984 1333 y(generator)l(,)i(6)1984 1446 +y(global)f(v)n(ariables,)h(7)1984 1559 y(graph)2150 1672 +y(arc)e(capacity)-6 b(,)25 b(10)2150 1785 y(arc)f(length,)h(10)2150 +1898 y(dra)o(wing,)f(24)1984 2011 y(gro)n(wth,)g(9)1984 +2124 y(gzip,)g(5)1984 2320 y(HA)-12 b(VE)p 2231 2320 +V 31 w(IEEE)p 2460 2320 V 32 w(754,)24 b(10)1984 2433 +y(header)h(\002les,)e(17,)h(28)1984 2545 y(hook,)g(21)1984 +2741 y(in\002nities,)h(10)1984 2854 y(installation,)i(5)1984 +2967 y(Intel)e(Pentium)e(4,)g(5)1984 3080 y(interf)o(ace)2150 +3193 y(cache,)i(29)2150 3306 y(SIS,)d(22)2150 3419 y(VIS,)g(22)1984 +3615 y(libraries,)k(5)2150 3728 y(cudd,)e(6)2150 3841 +y(dddmp,)g(24)2150 3954 y(mtr)l(,)f(6,)g(19)2150 4066 +y(obj,)h(40)2150 4179 y(st,)f(6,)g(29)2150 4292 y(util,)h(6)1984 +4488 y(Mak)o(e\002le,)g(6,)f(10,)g(40)1984 4601 y(manager)l(,)i(7,)e(9) +1984 4714 y(matrix)2150 4827 y(sparse,)i(10)1984 4940 +y(maxCache,)f(30)p Black 1897 5225 a(46)p Black eop end +%%Page: 47 47 +TeXDict begin 47 46 bop Black Black 448 573 a Fo(maxMemory)-6 +b(,)24 b(8)448 686 y(MinusIn\002nity)-6 b(,)26 b(10)448 +799 y(MTR)p 651 799 28 4 v 32 w(DEF)-7 b(A)i(UL)d(T)h(,)20 +b(20)448 912 y(MTR)p 651 912 V 32 w(FIXED,)h(19)448 1100 +y(nanotra)n(v)-6 b(,)26 b(5)448 1213 y(node,)e(6)614 +1326 y(constant,)i(6,)d(9\22611,)h(26,)f(27)697 1438 +y(v)n(alue,)h(7)614 1551 y(dead,)g(26,)g(29,)f(31)614 +1664 y(dereference,)k(14)614 1777 y(reclaimed,)e(31)614 +1890 y(rec)o(ycling,)h(7)614 2003 y(reference,)g(14)614 +2116 y(reference)g(count,)f(26)614 2229 y(reference)c(count,)f(6,)f(7,) +g(12,)g(13,)g(26\22630,)780 2342 y(34)697 2455 y(saturated,)26 +b(34)614 2568 y(terminal,)f Fn(see)f Fo(node,)g(constant)614 +2681 y(v)n(ariable)i(inde)o(x,)e(6)448 2793 y(numSlots,)g(8)448 +2906 y(numV)-10 b(ars,)24 b(8)448 3019 y(numV)-10 b(arsZ,)23 +b(8)448 3207 y(PlusIn\002nity)-6 b(,)25 b(10)448 3320 +y(projection)i(functions,)e(11,)f(12,)f(14,)h(15,)f(34)448 +3509 y(README)e(\002le,)h(5)448 3621 y(reordering,)k(4,)d(6,)g(29)614 +3734 y(abort)i(and)f(retry)-6 b(,)24 b(32)614 3847 y(asynchronous,)k +(17,)23 b(32)614 3960 y(con)l(v)o(er)n(ging,)k(17,)d(18)614 +4073 y(Cudd)p 815 4073 V 34 w(ReorderingT)-7 b(ype,)26 +b(17)614 4186 y(dynamic,)f(4,)e(16,)g(20)614 4299 y(e)o(xact,)h(19)614 +4412 y(function)i(wrapper)l(,)f(32,)e(33)614 4525 y(genetic,)i(19)614 +4638 y(group,)g(17,)e(18)614 4751 y(hooks,)i(21)614 4863 +y(interruptible)j(procedure,)d(32)614 4976 y(of)f(BDDs)e(and)i(ADDs,)e +(16)p Black Black 2150 573 a(of)i(ZDDs,)d(15,)j(20)2150 +686 y(random,)g(17)2150 799 y(sifting,)h(17)2150 912 +y(simulated)h(annealing,)f(19)2150 1024 y(symmetric,)g(18)2150 +1137 y(threshold,)h(17,)d(32)2150 1250 y(windo)n(w)-6 +b(,)23 b(18)1984 1446 y(saturating)2150 1559 y(decrements,)j(28)2150 +1672 y(increments,)g(28)1984 1785 y(SISDIR,)c(22)1984 +1898 y(SIZEOF)p 2299 1898 V 31 w(INT)-7 b(,)22 b(28)1984 +2011 y(SIZEOF)p 2299 2011 V 31 w(V)l(OID)p 2554 2011 +V 32 w(P)-10 b(,)22 b(28)1984 2124 y(statistical)k(counters,)g(7,)d(30) +1984 2237 y(statistical)j(counters,)g(26)1984 2350 y(statistics,)g(34) +1984 2462 y(subtable,)g(8,)d(26)1984 2575 y(symmetry)-6 +b(,)24 b(18)1984 2771 y(table)2150 2884 y(computed,)h(8)2150 +2997 y(gro)n(wth,)f(9)2150 3110 y(hash,)g(7,)f(31)2150 +3223 y(unique,)i(6\2269,)f(16,)f(26,)h(30,)f(31)2233 +3336 y(f)o(ast)h(gro)n(wth,)g(31)2233 3449 y(re)n(w)o(ard-based)i +(resizing,)g(31)2233 3562 y(slo)n(w)d(gro)n(wth,)h(32)1984 +3675 y(timeout,)g(22)1984 3870 y(v)n(ariable)2150 3983 +y(groups,)h(19)2150 4096 y(order)l(,)g(6,)e(11)2150 4209 +y(permutation,)j(6,)d(31)2150 4322 y(tree,)h(19,)f(20)1984 +4518 y(ZDD,)e(4,)i(7,)g(12,)h(14,)f(15)1984 4631 y(zero)2150 +4744 y(arithmetic,)i(9,)e(11,)h(15)2150 4857 y(logical,)h(9,)e(15)p +Black 1897 5225 a(47)p Black eop end +%%Page: 48 48 +TeXDict begin 48 47 bop Black Black 448 573 a Fo(Zero-suppressed)22 +b(Binary)d(Decision)h(Diagram,)780 686 y Fn(see)k Fo(ZDD)p +Black Black Black 1897 5225 a(48)p Black eop end +%%Trailer + +userdict /end-hook known{end-hook}if +%%EOF diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllAbs.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllAbs.html new file mode 100644 index 000000000..969b6e6cc --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllAbs.html @@ -0,0 +1,3114 @@ + +cudd package abstract + + + + + +
        +
        AssessPathLength() +
        Chooses the maximum allowable path length of nodes under the + threshold. + +
        BAapplyBias() +
        Finds don't care nodes. + +
        BAmarkNodes() +
        Marks nodes for remapping. + +
        BuildConjuncts() +
        Builds the conjuncts recursively, bottom up. + +
        BuildSubsetBdd() +
        Builds the BDD with nodes labeled with path length less than or equal to maxpath + +
        BuildSubsetBdd() +
        Builds the subset BDD using the heavy branch method. + +
        CheckInTables() +
        Check if the two pairs exist in the table, If any of the + conjuncts do exist, store in the cache and return the corresponding pair. + +
        CheckTablesCacheAndReturn() +
        Check the tables for the existence of pair and return one + combination, cache the result. + +
        ConjunctsFree() +
        Free factors structure + +
        CorrelCleanUp() +
        Frees memory associated with hash table. + +
        CorrelCompare() +
        Compares two hash table entries. + +
        CorrelHash() +
        Hashes a hash table entry. + +
        CountMinterms() +
        Count the number of minterms of each node ina a BDD and + store it in a hash table. + +
        CreateBotDist() +
        Get longest distance of node from constant. + +
        CreateBotDist() +
        Labels each node with the shortest distance from the constant. + +
        CreatePathTable() +
        The outer procedure to label each node with its shortest + distance from the root and constant + +
        CreateTopDist() +
        Labels each node with its shortest distance from the root + +
        Cudd_AddHook() +
        Adds a function to a hook. + +
        Cudd_ApaAdd() +
        Adds two arbitrary precision integers. + +
        Cudd_ApaCompareRatios() +
        Compares the ratios of two arbitrary precision integers to two + unsigned ints. + +
        Cudd_ApaCompare() +
        Compares two arbitrary precision integers. + +
        Cudd_ApaCopy() +
        Makes a copy of an arbitrary precision integer. + +
        Cudd_ApaCountMinterm() +
        Counts the number of minterms of a DD. + +
        Cudd_ApaIntDivision() +
        Divides an arbitrary precision integer by an integer. + +
        Cudd_ApaNumberOfDigits() +
        Finds the number of digits for an arbitrary precision + integer. + +
        Cudd_ApaPowerOfTwo() +
        Sets an arbitrary precision integer to a power of two. + +
        Cudd_ApaPrintDecimal() +
        Prints an arbitrary precision integer in decimal format. + +
        Cudd_ApaPrintDensity() +
        Prints the density of a BDD or ADD using + arbitrary precision arithmetic. + +
        Cudd_ApaPrintExponential() +
        Prints an arbitrary precision integer in exponential format. + +
        Cudd_ApaPrintHex() +
        Prints an arbitrary precision integer in hexadecimal format. + +
        Cudd_ApaPrintMintermExp() +
        Prints the number of minterms of a BDD or ADD in exponential + format using arbitrary precision arithmetic. + +
        Cudd_ApaPrintMinterm() +
        Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic. + +
        Cudd_ApaSetToLiteral() +
        Sets an arbitrary precision integer to a one-digit literal. + +
        Cudd_ApaShiftRight() +
        Shifts right an arbitrary precision integer by one binary + place. + +
        Cudd_ApaShortDivision() +
        Divides an arbitrary precision integer by a digit. + +
        Cudd_ApaSubtract() +
        Subtracts two arbitrary precision integers. + +
        Cudd_AutodynDisableZdd() +
        Disables automatic dynamic reordering of ZDDs. + +
        Cudd_AutodynDisable() +
        Disables automatic dynamic reordering. + +
        Cudd_AutodynEnableZdd() +
        Enables automatic dynamic reordering of ZDDs. + +
        Cudd_AutodynEnable() +
        Enables automatic dynamic reordering of BDDs and ADDs. + +
        Cudd_AverageDistance() +
        Computes the average distance between adjacent nodes. + +
        Cudd_BddToAdd() +
        Converts a BDD to a 0-1 ADD. + +
        Cudd_BddToCubeArray() +
        Builds a positional array from the BDD of a cube. + +
        Cudd_BiasedOverApprox() +
        Extracts a dense superset from a BDD with the biased + underapproximation method. + +
        Cudd_BiasedUnderApprox() +
        Extracts a dense subset from a BDD with the biased + underapproximation method. + +
        Cudd_CProjection() +
        Computes the compatible projection of R w.r.t. cube Y. + +
        Cudd_CheckCube() +
        Checks whether g is the BDD of a cube. + +
        Cudd_CheckKeys() +
        Checks for several conditions that should not occur. + +
        Cudd_CheckZeroRef() +
        Checks the unique table for nodes with non-zero reference + counts. + +
        Cudd_ClassifySupport() +
        Classifies the variables in the support of two DDs. + +
        Cudd_ClearErrorCode() +
        Clear the error code of a manager. + +
        Cudd_CofMinterm() +
        Computes the fraction of minterms in the on-set of all the + positive cofactors of a BDD or ADD. + +
        Cudd_Cofactor() +
        Computes the cofactor of f with respect to g. + +
        Cudd_CountLeaves() +
        Counts the number of leaves in a DD. + +
        Cudd_CountMinterm() +
        Counts the number of minterms of a DD. + +
        Cudd_CountPathsToNonZero() +
        Counts the number of paths to a non-zero terminal of a DD. + +
        Cudd_CountPath() +
        Counts the number of paths of a DD. + +
        Cudd_CubeArrayToBdd() +
        Builds the BDD of a cube from a positional array. + +
        Cudd_DagSize() +
        Counts the number of nodes in a DD. + +
        Cudd_DeadAreCounted() +
        Tells whether dead nodes are counted towards triggering + reordering. + +
        Cudd_DebugCheck() +
        Checks for inconsistencies in the DD heap. + +
        Cudd_Decreasing() +
        Determines whether a BDD is negative unate in a + variable. + +
        Cudd_DelayedDerefBdd() +
        Decreases the reference count of BDD node n. + +
        Cudd_Density() +
        Computes the density of a BDD or ADD. + +
        Cudd_Deref() +
        Decreases the reference count of node. + +
        Cudd_DisableGarbageCollection() +
        Disables garbage collection. + +
        Cudd_DisableOrderingMonitoring() +
        Disables monitoring of ordering. + +
        Cudd_DisableReorderingReporting() +
        Disables reporting of reordering stats. + +
        Cudd_Disequality() +
        Generates a BDD for the function x - y != c. + +
        Cudd_DumpBlifBody() +
        Writes a blif body representing the argument BDDs. + +
        Cudd_DumpBlif() +
        Writes a blif file representing the argument BDDs. + +
        Cudd_DumpDDcal() +
        Writes a DDcal file representing the argument BDDs. + +
        Cudd_DumpDaVinci() +
        Writes a daVinci file representing the argument BDDs. + +
        Cudd_DumpDot() +
        Writes a dot file representing the argument DDs. + +
        Cudd_DumpFactoredForm() +
        Writes factored forms representing the argument BDDs. + +
        Cudd_Dxygtdxz() +
        Generates a BDD for the function d(x,y) > d(x,z). + +
        Cudd_Dxygtdyz() +
        Generates a BDD for the function d(x,y) > d(y,z). + +
        Cudd_EnableGarbageCollection() +
        Enables garbage collection. + +
        Cudd_EnableOrderingMonitoring() +
        Enables monitoring of ordering. + +
        Cudd_EnableReorderingReporting() +
        Enables reporting of reordering stats. + +
        Cudd_EpdCountMinterm() +
        Counts the number of minterms of a DD with extended precision. + +
        Cudd_EqualSupNorm() +
        Compares two ADDs for equality within tolerance. + +
        Cudd_EquivDC() +
        Tells whether F and G are identical wherever D is 0. + +
        Cudd_EstimateCofactorSimple() +
        Estimates the number of nodes in a cofactor of a DD. + +
        Cudd_EstimateCofactor() +
        Estimates the number of nodes in a cofactor of a DD. + +
        Cudd_Eval() +
        Returns the value of a DD for a given variable assignment. + +
        Cudd_ExpectedUsedSlots() +
        Computes the expected fraction of used slots in the unique + table. + +
        Cudd_FindEssential() +
        Finds the essential variables of a DD. + +
        Cudd_FindTwoLiteralClauses() +
        Finds the two literal clauses of a DD. + +
        Cudd_FirstCube() +
        Finds the first cube of a decision diagram. + +
        Cudd_FirstNode() +
        Finds the first node of a decision diagram. + +
        Cudd_FirstPrime() +
        Finds the first prime of a Boolean function. + +
        Cudd_FreeTree() +
        Frees the variable group tree of the manager. + +
        Cudd_FreeZddTree() +
        Frees the variable group tree of the manager. + +
        Cudd_GarbageCollectionEnabled() +
        Tells whether garbage collection is enabled. + +
        Cudd_GenFree() +
        Frees a CUDD generator. + +
        Cudd_IncreaseTimeLimit() +
        Increases the time limit for the manager. + +
        Cudd_Increasing() +
        Determines whether a BDD is positive unate in a + variable. + +
        Cudd_IndicesToCube() +
        Builds a cube of BDD variables from an array of indices. + +
        Cudd_Inequality() +
        Generates a BDD for the function x - y ≥ c. + +
        Cudd_Init() +
        Creates a new DD manager. + +
        Cudd_IsGenEmpty() +
        Queries the status of a generator. + +
        Cudd_IsInHook() +
        Checks whether a function is in a hook. + +
        Cudd_IsNonConstant() +
        Returns 1 if a DD node is not constant. + +
        Cudd_IterDerefBdd() +
        Decreases the reference count of BDD node n. + +
        Cudd_LargestCube() +
        Finds a largest cube in a DD. + +
        Cudd_MakeBddFromZddCover() +
        Converts a ZDD cover to a BDD. + +
        Cudd_MakeTreeNode() +
        Creates a new variable group. + +
        Cudd_MakeZddTreeNode() +
        Creates a new ZDD variable group. + +
        Cudd_MinHammingDist() +
        Returns the minimum Hamming distance between f and minterm. + +
        Cudd_NewApaNumber() +
        Allocates memory for an arbitrary precision integer. + +
        Cudd_NextCube() +
        Generates the next cube of a decision diagram onset. + +
        Cudd_NextNode() +
        Finds the next node of a decision diagram. + +
        Cudd_NextPrime() +
        Generates the next prime of a Boolean function. + +
        Cudd_NodeReadIndex() +
        Returns the index of the node. + +
        Cudd_OrderingMonitoring() +
        Returns 1 if monitoring of ordering is enabled. + +
        Cudd_OutOfMem() +
        Warns that a memory allocation failed. + +
        Cudd_OverApprox() +
        Extracts a dense superset from a BDD with Shiple's + underapproximation method. + +
        Cudd_Prime() +
        Returns the next prime >= p. + +
        Cudd_PrintDebug() +
        Prints to the standard output a DD and its statistics. + +
        Cudd_PrintGroupedOrder() +
        Hook function to print the current variable order. + +
        Cudd_PrintInfo() +
        Prints out statistics and settings for a CUDD manager. + +
        Cudd_PrintLinear() +
        Prints the linear transform matrix. + +
        Cudd_PrintMinterm() +
        Prints a disjoint sum of products. + +
        Cudd_PrintTwoLiteralClauses() +
        Prints the two literal clauses of a DD. + +
        Cudd_PrintVersion() +
        Prints the package version number. + +
        Cudd_PrioritySelect() +
        Selects pairs from R using a priority function. + +
        Cudd_Quit() +
        Deletes resources associated with a DD manager. + +
        Cudd_Random() +
        Portable random number generator. + +
        Cudd_ReadArcviolation() +
        Returns the current value of the arcviolation parameter used + in group sifting. + +
        Cudd_ReadBackground() +
        Reads the background constant of the manager. + +
        Cudd_ReadCacheHits() +
        Returns the number of cache hits. + +
        Cudd_ReadCacheLookUps() +
        Returns the number of cache look-ups. + +
        Cudd_ReadCacheSlots() +
        Reads the number of slots in the cache. + +
        Cudd_ReadCacheUsedSlots() +
        Reads the fraction of used slots in the cache. + +
        Cudd_ReadDead() +
        Returns the number of dead nodes in the unique table. + +
        Cudd_ReadElapsedTime() +
        Returns the time elapsed since the start time of the manager. + +
        Cudd_ReadEpsilon() +
        Reads the epsilon parameter of the manager. + +
        Cudd_ReadErrorCode() +
        Returns the code of the last error. + +
        Cudd_ReadGarbageCollectionTime() +
        Returns the time spent in garbage collection. + +
        Cudd_ReadGarbageCollections() +
        Returns the number of times garbage collection has occurred. + +
        Cudd_ReadGroupcheck() +
        Reads the groupcheck parameter of the manager. + +
        Cudd_ReadInvPermZdd() +
        Returns the index of the ZDD variable currently in the i-th + position of the order. + +
        Cudd_ReadInvPerm() +
        Returns the index of the variable currently in the i-th + position of the order. + +
        Cudd_ReadIthClause() +
        Accesses the i-th clause of a DD. + +
        Cudd_ReadKeys() +
        Returns the number of nodes in the unique table. + +
        Cudd_ReadLinear() +
        Reads an entry of the linear transform matrix. + +
        Cudd_ReadLogicZero() +
        Returns the logic zero constant of the manager. + +
        Cudd_ReadLooseUpTo() +
        Reads the looseUpTo parameter of the manager. + +
        Cudd_ReadMaxCacheHard() +
        Reads the maxCacheHard parameter of the manager. + +
        Cudd_ReadMaxCache() +
        Returns the soft limit for the cache size. + +
        Cudd_ReadMaxGrowthAlternate() +
        Reads the maxGrowthAlt parameter of the manager. + +
        Cudd_ReadMaxGrowth() +
        Reads the maxGrowth parameter of the manager. + +
        Cudd_ReadMaxLive() +
        Reads the maximum allowed number of live nodes. + +
        Cudd_ReadMaxMemory() +
        Reads the maximum allowed memory. + +
        Cudd_ReadMaxReorderings() +
        Returns the maximum number of times reordering may be invoked. + +
        Cudd_ReadMemoryInUse() +
        Returns the memory in use by the manager measured in bytes. + +
        Cudd_ReadMinDead() +
        Reads the minDead parameter of the manager. + +
        Cudd_ReadMinHit() +
        Reads the hit rate that causes resizinig of the computed + table. + +
        Cudd_ReadMinusInfinity() +
        Reads the minus-infinity constant from the manager. + +
        Cudd_ReadNextReordering() +
        Returns the threshold for the next dynamic reordering. + +
        Cudd_ReadNodeCount() +
        Reports the number of nodes in BDDs and ADDs. + +
        Cudd_ReadNodesDropped() +
        Returns the number of nodes dropped. + +
        Cudd_ReadNodesFreed() +
        Returns the number of nodes freed. + +
        Cudd_ReadNumberXovers() +
        Reads the current number of crossovers used by the + genetic algorithm for reordering. + +
        Cudd_ReadOne() +
        Returns the one constant of the manager. + +
        Cudd_ReadOrderRandomization() +
        Returns the order randomization factor. + +
        Cudd_ReadPeakLiveNodeCount() +
        Reports the peak number of live nodes. + +
        Cudd_ReadPeakNodeCount() +
        Reports the peak number of nodes. + +
        Cudd_ReadPermZdd() +
        Returns the current position of the i-th ZDD variable in the + order. + +
        Cudd_ReadPerm() +
        Returns the current position of the i-th variable in the + order. + +
        Cudd_ReadPlusInfinity() +
        Reads the plus-infinity constant from the manager. + +
        Cudd_ReadPopulationSize() +
        Reads the current size of the population used by the + genetic algorithm for reordering. + +
        Cudd_ReadRecomb() +
        Returns the current value of the recombination parameter used + in group sifting. + +
        Cudd_ReadRecursiveCalls() +
        Returns the number of recursive calls. + +
        Cudd_ReadReorderingCycle() +
        Reads the reordCycle parameter of the manager. + +
        Cudd_ReadReorderingTime() +
        Returns the time spent in reordering. + +
        Cudd_ReadReorderings() +
        Returns the number of times reordering has occurred. + +
        Cudd_ReadSiftMaxSwap() +
        Reads the siftMaxSwap parameter of the manager. + +
        Cudd_ReadSiftMaxVar() +
        Reads the siftMaxVar parameter of the manager. + +
        Cudd_ReadSize() +
        Returns the number of BDD variables in existance. + +
        Cudd_ReadSlots() +
        Returns the total number of slots of the unique table. + +
        Cudd_ReadStartTime() +
        Returns the start time of the manager. + +
        Cudd_ReadStderr() +
        Reads the stderr of a manager. + +
        Cudd_ReadStdout() +
        Reads the stdout of a manager. + +
        Cudd_ReadSwapSteps() +
        Reads the number of elementary reordering steps. + +
        Cudd_ReadSymmviolation() +
        Returns the current value of the symmviolation parameter used + in group sifting. + +
        Cudd_ReadTimeLimit() +
        Returns the time limit for the manager. + +
        Cudd_ReadTree() +
        Returns the variable group tree of the manager. + +
        Cudd_ReadUniqueLinks() +
        Returns the number of links followed in the unique table. + +
        Cudd_ReadUniqueLookUps() +
        Returns the number of look-ups in the unique table. + +
        Cudd_ReadUsedSlots() +
        Reads the fraction of used slots in the unique table. + +
        Cudd_ReadVars() +
        Returns the i-th element of the vars array. + +
        Cudd_ReadZddOne() +
        Returns the ZDD for the constant 1 function. + +
        Cudd_ReadZddSize() +
        Returns the number of ZDD variables in existance. + +
        Cudd_ReadZddTree() +
        Returns the variable group tree of the manager. + +
        Cudd_ReadZero() +
        Returns the zero constant of the manager. + +
        Cudd_RecursiveDerefZdd() +
        Decreases the reference count of ZDD node n. + +
        Cudd_RecursiveDeref() +
        Decreases the reference count of node n. + +
        Cudd_ReduceHeap() +
        Main dynamic reordering routine. + +
        Cudd_Ref() +
        Increases the reference count of a node, if it is not + saturated. + +
        Cudd_RemapOverApprox() +
        Extracts a dense superset from a BDD with the remapping + underapproximation method. + +
        Cudd_RemapUnderApprox() +
        Extracts a dense subset from a BDD with the remapping + underapproximation method. + +
        Cudd_RemoveHook() +
        Removes a function from a hook. + +
        Cudd_ReorderingReporting() +
        Returns 1 if reporting of reordering stats is enabled. + +
        Cudd_ReorderingStatusZdd() +
        Reports the status of automatic dynamic reordering of ZDDs. + +
        Cudd_ReorderingStatus() +
        Reports the status of automatic dynamic reordering of BDDs + and ADDs. + +
        Cudd_Reserve() +
        Expand manager without creating variables. + +
        Cudd_ResetStartTime() +
        Resets the start time of the manager. + +
        Cudd_SetArcviolation() +
        Sets the value of the arcviolation parameter used + in group sifting. + +
        Cudd_SetBackground() +
        Sets the background constant of the manager. + +
        Cudd_SetEpsilon() +
        Sets the epsilon parameter of the manager to ep. + +
        Cudd_SetGroupcheck() +
        Sets the parameter groupcheck of the manager to gc. + +
        Cudd_SetLooseUpTo() +
        Sets the looseUpTo parameter of the manager. + +
        Cudd_SetMaxCacheHard() +
        Sets the maxCacheHard parameter of the manager. + +
        Cudd_SetMaxGrowthAlternate() +
        Sets the maxGrowthAlt parameter of the manager. + +
        Cudd_SetMaxGrowth() +
        Sets the maxGrowth parameter of the manager. + +
        Cudd_SetMaxLive() +
        Sets the maximum allowed number of live nodes. + +
        Cudd_SetMaxMemory() +
        Sets the maximum allowed memory. + +
        Cudd_SetMaxReorderings() +
        Sets the maximum number of times reordering may be invoked. + +
        Cudd_SetMinHit() +
        Sets the hit rate that causes resizinig of the computed + table. + +
        Cudd_SetNextReordering() +
        Sets the threshold for the next dynamic reordering. + +
        Cudd_SetNumberXovers() +
        Sets the number of crossovers used by the + genetic algorithm for reordering. + +
        Cudd_SetOrderRandomization() +
        Sets the order randomization factor. + +
        Cudd_SetPopulationSize() +
        Sets the size of the population used by the + genetic algorithm for reordering. + +
        Cudd_SetRecomb() +
        Sets the value of the recombination parameter used in group + sifting. + +
        Cudd_SetReorderingCycle() +
        Sets the reordCycle parameter of the manager. + +
        Cudd_SetSiftMaxSwap() +
        Sets the siftMaxSwap parameter of the manager. + +
        Cudd_SetSiftMaxVar() +
        Sets the siftMaxVar parameter of the manager. + +
        Cudd_SetStartTime() +
        Sets the start time of the manager. + +
        Cudd_SetStderr() +
        Sets the stderr of a manager. + +
        Cudd_SetStdout() +
        Sets the stdout of a manager. + +
        Cudd_SetSymmviolation() +
        Sets the value of the symmviolation parameter used + in group sifting. + +
        Cudd_SetTimeLimit() +
        Sets the time limit for the manager. + +
        Cudd_SetTree() +
        Sets the variable group tree of the manager. + +
        Cudd_SetVarMap() +
        Registers a variable mapping with the manager. + +
        Cudd_SetZddTree() +
        Sets the ZDD variable group tree of the manager. + +
        Cudd_SharingSize() +
        Counts the number of nodes in an array of DDs. + +
        Cudd_ShortestLength() +
        Find the length of the shortest path(s) in a DD. + +
        Cudd_ShortestPath() +
        Finds a shortest path in a DD. + +
        Cudd_ShuffleHeap() +
        Reorders variables according to given permutation. + +
        Cudd_SolveEqn() +
        Implements the solution of F(x,y) = 0. + +
        Cudd_SplitSet() +
        Returns m minterms from a BDD. + +
        Cudd_Srandom() +
        Initializer for the portable random number generator. + +
        Cudd_StdPostReordHook() +
        Sample hook function to call after reordering. + +
        Cudd_StdPreReordHook() +
        Sample hook function to call before reordering. + +
        Cudd_SubsetCompress() +
        Find a dense subset of BDD f. + +
        Cudd_SubsetHeavyBranch() +
        Extracts a dense subset from a BDD with the heavy branch + heuristic. + +
        Cudd_SubsetShortPaths() +
        Extracts a dense subset from a BDD with the shortest paths + heuristic. + +
        Cudd_SubsetWithMaskVars() +
        Extracts a subset from a BDD. + +
        Cudd_SupersetCompress() +
        Find a dense superset of BDD f. + +
        Cudd_SupersetHeavyBranch() +
        Extracts a dense superset from a BDD with the heavy branch + heuristic. + +
        Cudd_SupersetShortPaths() +
        Extracts a dense superset from a BDD with the shortest paths + heuristic. + +
        Cudd_SupportIndex() +
        Finds the variables on which a DD depends. + +
        Cudd_SupportIndices() +
        Finds the variables on which a DD depends. + +
        Cudd_SupportSize() +
        Counts the variables on which a DD depends. + +
        Cudd_Support() +
        Finds the variables on which a DD depends. + +
        Cudd_SymmProfile() +
        Prints statistics on symmetric variables. + +
        Cudd_TimeLimited() +
        Returns true if the time limit for the manager is set. + +
        Cudd_TurnOffCountDead() +
        Causes the dead nodes not to be counted towards triggering + reordering. + +
        Cudd_TurnOnCountDead() +
        Causes the dead nodes to be counted towards triggering + reordering. + +
        Cudd_UnderApprox() +
        Extracts a dense subset from a BDD with Shiple's + underapproximation method. + +
        Cudd_UnsetTimeLimit() +
        Unsets the time limit for the manager. + +
        Cudd_UpdateTimeLimit() +
        Updates the time limit for the manager. + +
        Cudd_VectorSupportIndex() +
        Finds the variables on which a set of DDs depends. + +
        Cudd_VectorSupportIndices() +
        Finds the variables on which a set of DDs depends. + +
        Cudd_VectorSupportSize() +
        Counts the variables on which a set of DDs depends. + +
        Cudd_VectorSupport() +
        Finds the variables on which a set of DDs depends. + +
        Cudd_VerifySol() +
        Checks the solution of F(x,y) = 0. + +
        Cudd_Xeqy() +
        Generates a BDD for the function x==y. + +
        Cudd_Xgty() +
        Generates a BDD for the function x > y. + +
        Cudd_addAgreement() +
        f if f==g; background if f!=g. + +
        Cudd_addApply() +
        Applies op to the corresponding discriminants of f and g. + +
        Cudd_addBddInterval() +
        Converts an ADD to a BDD. + +
        Cudd_addBddIthBit() +
        Converts an ADD to a BDD by extracting the i-th bit from + the leaves. + +
        Cudd_addBddPattern() +
        Converts an ADD to a BDD. + +
        Cudd_addBddStrictThreshold() +
        Converts an ADD to a BDD. + +
        Cudd_addBddThreshold() +
        Converts an ADD to a BDD. + +
        Cudd_addCmpl() +
        Computes the complement of an ADD a la C language. + +
        Cudd_addCompose() +
        Substitutes g for x_v in the ADD for f. + +
        Cudd_addComputeCube() +
        Computes the cube of an array of ADD variables. + +
        Cudd_addConstrain() +
        Computes f constrain c for ADDs. + +
        Cudd_addConst() +
        Returns the ADD for constant c. + +
        Cudd_addDiff() +
        Returns plusinfinity if f=g; returns min(f,g) if f!=g. + +
        Cudd_addDivide() +
        Integer and floating point division. + +
        Cudd_addEvalConst() +
        Checks whether ADD g is constant whenever ADD f is 1. + +
        Cudd_addExistAbstract() +
        Existentially Abstracts all the variables in cube from f. + +
        Cudd_addFindMax() +
        Finds the maximum discriminant of f. + +
        Cudd_addFindMin() +
        Finds the minimum discriminant of f. + +
        Cudd_addGeneralVectorCompose() +
        Composes an ADD with a vector of ADDs. + +
        Cudd_addHamming() +
        Computes the Hamming distance ADD. + +
        Cudd_addHarwell() +
        Reads in a matrix in the format of the Harwell-Boeing + benchmark suite. + +
        Cudd_addIteConstant() +
        Implements ITEconstant for ADDs. + +
        Cudd_addIte() +
        Implements ITE(f,g,h). + +
        Cudd_addIthBit() +
        Extracts the i-th bit from an ADD. + +
        Cudd_addIthVar() +
        Returns the ADD variable with index i. + +
        Cudd_addLeq() +
        Determines whether f is less than or equal to g. + +
        Cudd_addLog() +
        Natural logarithm of an ADD. + +
        Cudd_addMatrixMultiply() +
        Calculates the product of two matrices represented as + ADDs. + +
        Cudd_addMaximum() +
        Integer and floating point max. + +
        Cudd_addMinimum() +
        Integer and floating point min. + +
        Cudd_addMinus() +
        Integer and floating point subtraction. + +
        Cudd_addMonadicApply() +
        Applies op to the discriminants of f. + +
        Cudd_addNand() +
        NAND of two 0-1 ADDs. + +
        Cudd_addNegate() +
        Computes the additive inverse of an ADD. + +
        Cudd_addNewVarAtLevel() +
        Returns a new ADD variable at a specified level. + +
        Cudd_addNewVar() +
        Returns a new ADD variable. + +
        Cudd_addNonSimCompose() +
        Composes an ADD with a vector of 0-1 ADDs. + +
        Cudd_addNor() +
        NOR of two 0-1 ADDs. + +
        Cudd_addOneZeroMaximum() +
        Returns 1 if f > g and 0 otherwise. + +
        Cudd_addOrAbstract() +
        Disjunctively abstracts all the variables in cube from the + 0-1 ADD f. + +
        Cudd_addOr() +
        Disjunction of two 0-1 ADDs. + +
        Cudd_addOuterSum() +
        Takes the minimum of a matrix and the outer sum of two vectors. + +
        Cudd_addPermute() +
        Permutes the variables of an ADD. + +
        Cudd_addPlus() +
        Integer and floating point addition. + +
        Cudd_addRead() +
        Reads in a sparse matrix. + +
        Cudd_addResidue() +
        Builds an ADD for the residue modulo m of an n-bit + number. + +
        Cudd_addRestrict() +
        ADD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
        Cudd_addRoundOff() +
        Rounds off the discriminants of an ADD. + +
        Cudd_addScalarInverse() +
        Computes the scalar inverse of an ADD. + +
        Cudd_addSetNZ() +
        This operator sets f to the value of g wherever g != 0. + +
        Cudd_addSwapVariables() +
        Swaps two sets of variables of the same size (x and y) in + the ADD f. + +
        Cudd_addThreshold() +
        f if f>=g; 0 if f<g. + +
        Cudd_addTimesPlus() +
        Calculates the product of two matrices represented as + ADDs. + +
        Cudd_addTimes() +
        Integer and floating point multiplication. + +
        Cudd_addTriangle() +
        Performs the triangulation step for the shortest path + computation. + +
        Cudd_addUnivAbstract() +
        Universally Abstracts all the variables in cube from f. + +
        Cudd_addVectorCompose() +
        Composes an ADD with a vector of 0-1 ADDs. + +
        Cudd_addWalsh() +
        Generates a Walsh matrix in ADD form. + +
        Cudd_addXeqy() +
        Generates an ADD for the function x==y. + +
        Cudd_addXnor() +
        XNOR of two 0-1 ADDs. + +
        Cudd_addXor() +
        XOR of two 0-1 ADDs. + +
        Cudd_bddAdjPermuteX() +
        Rearranges a set of variables in the BDD B. + +
        Cudd_bddAndAbstractLimit() +
        Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. Returns NULL if too many nodes are required. + +
        Cudd_bddAndAbstract() +
        Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
        Cudd_bddAndLimit() +
        Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
        Cudd_bddAnd() +
        Computes the conjunction of two BDDs f and g. + +
        Cudd_bddApproxConjDecomp() +
        Performs two-way conjunctive decomposition of a BDD. + +
        Cudd_bddApproxDisjDecomp() +
        Performs two-way disjunctive decomposition of a BDD. + +
        Cudd_bddBindVar() +
        Prevents sifting of a variable. + +
        Cudd_bddBooleanDiff() +
        Computes the boolean difference of f with respect to x. + +
        Cudd_bddCharToVect() +
        Computes a vector whose image equals a non-zero function. + +
        Cudd_bddClippingAndAbstract() +
        Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
        Cudd_bddClippingAnd() +
        Approximates the conjunction of two BDDs f and g. + +
        Cudd_bddClosestCube() +
        Finds a cube of f at minimum Hamming distance from g. + +
        Cudd_bddCompose() +
        Substitutes g for x_v in the BDD for f. + +
        Cudd_bddComputeCube() +
        Computes the cube of an array of BDD variables. + +
        Cudd_bddConstrainDecomp() +
        BDD conjunctive decomposition as in McMillan's CAV96 paper. + +
        Cudd_bddConstrain() +
        Computes f constrain c. + +
        Cudd_bddCorrelationWeights() +
        Computes the correlation of f and g for given input + probabilities. + +
        Cudd_bddCorrelation() +
        Computes the correlation of f and g. + +
        Cudd_bddExistAbstractLimit() +
        Existentially abstracts all the variables in cube from f. + +
        Cudd_bddExistAbstract() +
        Existentially abstracts all the variables in cube from f. + +
        Cudd_bddGenConjDecomp() +
        Performs two-way conjunctive decomposition of a BDD. + +
        Cudd_bddGenDisjDecomp() +
        Performs two-way disjunctive decomposition of a BDD. + +
        Cudd_bddIntersect() +
        Returns a function included in the intersection of f and g. + +
        Cudd_bddInterval() +
        Generates a BDD for the function lowerB ≤ x ≤ upperB. + +
        Cudd_bddIsNsVar() +
        Checks whether a variable is next state. + +
        Cudd_bddIsPiVar() +
        Checks whether a variable is primary input. + +
        Cudd_bddIsPsVar() +
        Checks whether a variable is present state. + +
        Cudd_bddIsVarEssential() +
        Determines whether a given variable is essential with a + given phase in a BDD. + +
        Cudd_bddIsVarHardGroup() +
        Checks whether a variable is set to be in a hard group. + +
        Cudd_bddIsVarToBeGrouped() +
        Checks whether a variable is set to be grouped. + +
        Cudd_bddIsVarToBeUngrouped() +
        Checks whether a variable is set to be ungrouped. + +
        Cudd_bddIsop() +
        Computes a BDD in the interval between L and U with a + simple sum-of-product cover. + +
        Cudd_bddIteConstant() +
        Implements ITEconstant(f,g,h). + +
        Cudd_bddIteLimit() +
        Implements ITE(f,g,h). Returns + NULL if too many nodes are required. + +
        Cudd_bddIterConjDecomp() +
        Performs two-way conjunctive decomposition of a BDD. + +
        Cudd_bddIterDisjDecomp() +
        Performs two-way disjunctive decomposition of a BDD. + +
        Cudd_bddIte() +
        Implements ITE(f,g,h). + +
        Cudd_bddIthVar() +
        Returns the BDD variable with index i. + +
        Cudd_bddLICompaction() +
        Performs safe minimization of a BDD. + +
        Cudd_bddLargestPrimeUnate() +
        Find a largest prime of a unate function. + +
        Cudd_bddLeqUnless() +
        Tells whether f is less than of equal to G unless D is 1. + +
        Cudd_bddLeq() +
        Determines whether f is less than or equal to g. + +
        Cudd_bddLiteralSetIntersection() +
        Computes the intesection of two sets of literals + represented as BDDs. + +
        Cudd_bddMakePrime() +
        Expands cube to a prime implicant of f. + +
        Cudd_bddMaximallyExpand() +
        Expands lb to prime implicants of (f and ub). + +
        Cudd_bddMinimize() +
        Finds a small BDD that agrees with f over + c. + +
        Cudd_bddNPAnd() +
        Computes f non-polluting-and g. + +
        Cudd_bddNand() +
        Computes the NAND of two BDDs f and g. + +
        Cudd_bddNewVarAtLevel() +
        Returns a new BDD variable at a specified level. + +
        Cudd_bddNewVar() +
        Returns a new BDD variable. + +
        Cudd_bddNor() +
        Computes the NOR of two BDDs f and g. + +
        Cudd_bddOrLimit() +
        Computes the disjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
        Cudd_bddOr() +
        Computes the disjunction of two BDDs f and g. + +
        Cudd_bddPermute() +
        Permutes the variables of a BDD. + +
        Cudd_bddPickArbitraryMinterms() +
        Picks k on-set minterms evenly distributed from given DD. + +
        Cudd_bddPickOneCube() +
        Picks one on-set cube randomly from the given DD. + +
        Cudd_bddPickOneMinterm() +
        Picks one on-set minterm randomly from the given DD. + +
        Cudd_bddPrintCover() +
        Prints a sum of prime implicants of a BDD. + +
        Cudd_bddReadPairIndex() +
        Reads a corresponding pair index for a given index. + +
        Cudd_bddRead() +
        Reads in a graph (without labels) given as a list of arcs. + +
        Cudd_bddRealignDisable() +
        Disables realignment of ZDD order to BDD order. + +
        Cudd_bddRealignEnable() +
        Enables realignment of BDD order to ZDD order. + +
        Cudd_bddRealignmentEnabled() +
        Tells whether the realignment of BDD order to ZDD order is + enabled. + +
        Cudd_bddResetVarToBeGrouped() +
        Resets a variable not to be grouped. + +
        Cudd_bddRestrict() +
        BDD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
        Cudd_bddSetNsVar() +
        Sets a variable type to next state. + +
        Cudd_bddSetPairIndex() +
        Sets a corresponding pair index for a given index. + +
        Cudd_bddSetPiVar() +
        Sets a variable type to primary input. + +
        Cudd_bddSetPsVar() +
        Sets a variable type to present state. + +
        Cudd_bddSetVarHardGroup() +
        Sets a variable to be a hard group. + +
        Cudd_bddSetVarToBeGrouped() +
        Sets a variable to be grouped. + +
        Cudd_bddSetVarToBeUngrouped() +
        Sets a variable to be ungrouped. + +
        Cudd_bddSqueeze() +
        Finds a small BDD in a function interval. + +
        Cudd_bddSwapVariables() +
        Swaps two sets of variables of the same size (x and y) in + the BDD f. + +
        Cudd_bddTransfer() +
        Convert a BDD from a manager to another one. + +
        Cudd_bddUnbindVar() +
        Allows the sifting of a variable. + +
        Cudd_bddUnivAbstract() +
        Universally abstracts all the variables in cube from f. + +
        Cudd_bddVarConjDecomp() +
        Performs two-way conjunctive decomposition of a BDD. + +
        Cudd_bddVarDisjDecomp() +
        Performs two-way disjunctive decomposition of a BDD. + +
        Cudd_bddVarIsBound() +
        Tells whether a variable can be sifted. + +
        Cudd_bddVarIsDependent() +
        Checks whether a variable is dependent on others in a + function. + +
        Cudd_bddVarMap() +
        Remaps the variables of a BDD using the default variable map. + +
        Cudd_bddVectorCompose() +
        Composes a BDD with a vector of BDDs. + +
        Cudd_bddXnorLimit() +
        Computes the exclusive NOR of two BDDs f and g. Returns + NULL if too many nodes are required. + +
        Cudd_bddXnor() +
        Computes the exclusive NOR of two BDDs f and g. + +
        Cudd_bddXorExistAbstract() +
        Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
        Cudd_bddXor() +
        Computes the exclusive OR of two BDDs f and g. + +
        Cudd_tlcInfoFree() +
        Frees a DdTlcInfo Structure. + +
        Cudd_zddChange() +
        Substitutes a variable with its complement in a ZDD. + +
        Cudd_zddComplement() +
        Computes a complement cover for a ZDD node. + +
        Cudd_zddCountDouble() +
        Counts the number of minterms of a ZDD. + +
        Cudd_zddCountMinterm() +
        Counts the number of minterms of a ZDD. + +
        Cudd_zddCount() +
        Counts the number of minterms in a ZDD. + +
        Cudd_zddCoverPathToString() +
        Converts a path of a ZDD representing a cover to a string. + +
        Cudd_zddDagSize() +
        Counts the number of nodes in a ZDD. + +
        Cudd_zddDiffConst() +
        Performs the inclusion test for ZDDs (P implies Q). + +
        Cudd_zddDiff() +
        Computes the difference of two ZDDs. + +
        Cudd_zddDivideF() +
        Modified version of Cudd_zddDivide. + +
        Cudd_zddDivide() +
        Computes the quotient of two unate covers. + +
        Cudd_zddDumpDot() +
        Writes a dot file representing the argument ZDDs. + +
        Cudd_zddFirstPath() +
        Finds the first path of a ZDD. + +
        Cudd_zddIntersect() +
        Computes the intersection of two ZDDs. + +
        Cudd_zddIsop() +
        Computes an ISOP in ZDD form from BDDs. + +
        Cudd_zddIte() +
        Computes the ITE of three ZDDs. + +
        Cudd_zddIthVar() +
        Returns the ZDD variable with index i. + +
        Cudd_zddNextPath() +
        Generates the next path of a ZDD. + +
        Cudd_zddPortFromBdd() +
        Converts a BDD into a ZDD. + +
        Cudd_zddPortToBdd() +
        Converts a ZDD into a BDD. + +
        Cudd_zddPrintCover() +
        Prints a sum of products from a ZDD representing a cover. + +
        Cudd_zddPrintDebug() +
        Prints to the standard output a ZDD and its statistics. + +
        Cudd_zddPrintMinterm() +
        Prints a disjoint sum of product form for a ZDD. + +
        Cudd_zddPrintSubtable() +
        Prints the ZDD table. + +
        Cudd_zddProduct() +
        Computes the product of two covers represented by ZDDs. + +
        Cudd_zddReadNodeCount() +
        Reports the number of nodes in ZDDs. + +
        Cudd_zddRealignDisable() +
        Disables realignment of ZDD order to BDD order. + +
        Cudd_zddRealignEnable() +
        Enables realignment of ZDD order to BDD order. + +
        Cudd_zddRealignmentEnabled() +
        Tells whether the realignment of ZDD order to BDD order is + enabled. + +
        Cudd_zddReduceHeap() +
        Main dynamic reordering routine for ZDDs. + +
        Cudd_zddShuffleHeap() +
        Reorders ZDD variables according to given permutation. + +
        Cudd_zddSubset0() +
        Computes the negative cofactor of a ZDD w.r.t. a variable. + +
        Cudd_zddSubset1() +
        Computes the positive cofactor of a ZDD w.r.t. a variable. + +
        Cudd_zddSupport() +
        Finds the variables on which a ZDD depends. + +
        Cudd_zddSymmProfile() +
        Prints statistics on symmetric ZDD variables. + +
        Cudd_zddUnateProduct() +
        Computes the product of two unate covers. + +
        Cudd_zddUnion() +
        Computes the union of two ZDDs. + +
        Cudd_zddVarsFromBddVars() +
        Creates one or more ZDD variables for each BDD variable. + +
        Cudd_zddWeakDivF() +
        Modified version of Cudd_zddWeakDiv. + +
        Cudd_zddWeakDiv() +
        Applies weak division to two covers. + +
        MarkCacheCleanUp() +
        Frees memory associated with computed table of + cuddBddLICMarkEdges. + +
        MarkCacheCompare() +
        Comparison function for the computed table of + cuddBddLICMarkEdges. + +
        MarkCacheHash() +
        Hash function for the computed table of cuddBddLICMarkEdges. + +
        PMX() +
        Performs the crossover between two parents. + +
        PairInTables() +
        Check whether the given pair is in the tables. + +
        PickOnePair() +
        Check the tables for the existence of pair and return one + combination, store in cache. + +
        RAbuildSubset() +
        Builds the subset BDD for cuddRemapUnderApprox. + +
        RAmarkNodes() +
        Marks nodes for remapping. + +
        ResizeCountMintermPages() +
        Resize the number of pages allocated to store the minterm + counts. + +
        ResizeCountNodePages() +
        Resize the number of pages allocated to store the node counts. + +
        ResizeNodeDataPages() +
        Resize the number of pages allocated to store the node data. + +
        ResizeNodeDistPages() +
        Resize the number of pages allocated to store the distances + related to each node. + +
        ResizeQueuePages() +
        Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd . + +
        StoreNodes() +
        Procedure to recursively store nodes that are retained in the subset. + +
        SubsetCountMintermAux() +
        Recursively counts minterms of each node in the DAG. + +
        SubsetCountMinterm() +
        Counts minterms of each node in the DAG + +
        SubsetCountNodesAux() +
        Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node. + +
        SubsetCountNodes() +
        Counts the nodes under the current node and its lighter child + +
        UAbuildSubset() +
        Builds the subset BDD. + +
        UAmarkNodes() +
        Marks nodes for replacement by zero. + +
        ZeroCase() +
        If one child is zero, do explicitly what Restrict does or better + +
        addBddDoInterval() +
        Performs the recursive step for Cudd_addBddInterval. + +
        addBddDoIthBit() +
        Performs the recursive step for Cudd_addBddIthBit. + +
        addBddDoStrictThreshold() +
        Performs the recursive step for Cudd_addBddStrictThreshold. + +
        addBddDoThreshold() +
        Performs the recursive step for Cudd_addBddThreshold. + +
        addCheckPositiveCube() +
        Checks whether cube is an ADD representing the product + of positive literals. + +
        addDoIthBit() +
        Performs the recursive step for Cudd_addIthBit. + +
        addMMRecur() +
        Performs the recursive step of Cudd_addMatrixMultiply. + +
        addMultiplicityGroups() +
        Adds multiplicity groups to a ZDD variable group tree. + +
        addTriangleRecur() +
        Performs the recursive step of Cudd_addTriangle. + +
        addVarToConst() +
        Replaces variables with constants if possible (part of + canonical form). + +
        addWalshInt() +
        Implements the recursive step of Cudd_addWalsh. + +
        array_compare() +
        Comparison function for the computed table. + +
        array_hash() +
        Hash function for the computed table. + +
        bddAnnotateMintermCount() +
        Annotates every node in the BDD node with its minterm count. + +
        bddCheckPositiveCube() +
        Checks whether cube is an BDD representing the product of + positive literals. + +
        bddCorrelationAux() +
        Performs the recursive step of Cudd_bddCorrelation. + +
        bddCorrelationWeightsAux() +
        Performs the recursive step of Cudd_bddCorrelationWeigths. + +
        bddFixTree() +
        Fixes the BDD variable group tree after a shuffle. + +
        bddVarToCanonicalSimple() +
        Picks unique member from equiv expressions. + +
        bddVarToCanonical() +
        Picks unique member from equiv expressions. + +
        bddVarToConst() +
        Replaces variables with constants if possible. + +
        beforep() +
        Returns true iff the first argument precedes the second in + the clause order. + +
        bitVectorAlloc() +
        Allocates a bit vector. + +
        bitVectorFree() +
        Frees a bit vector. + +
        build_dd() +
        Builds a DD from a given order. + +
        checkSymmInfo() +
        Check symmetry condition. + +
        computeClausesWithUniverse() +
        Computes the two-literal clauses for a node. + +
        computeClauses() +
        Computes the two-literal clauses for a node. + +
        computeLB() +
        Computes a lower bound on the size of a BDD. + +
        computeSavings() +
        Counts the nodes that would be eliminated if a given node + were replaced by zero. + +
        copyOrder() +
        Copies the current variable order to array. + +
        createResult() +
        Builds a result for cache storage. + +
        cuddAddApplyRecur() +
        Performs the recursive step of Cudd_addApply. + +
        cuddAddBddDoPattern() +
        Performs the recursive step for Cudd_addBddPattern. + +
        cuddAddCmplRecur() +
        Performs the recursive step of Cudd_addCmpl. + +
        cuddAddComposeRecur() +
        Performs the recursive step of Cudd_addCompose. + +
        cuddAddConstrainRecur() +
        Performs the recursive step of Cudd_addConstrain. + +
        cuddAddExistAbstractRecur() +
        Performs the recursive step of Cudd_addExistAbstract. + +
        cuddAddGeneralVectorComposeRecur() +
        Performs the recursive step of Cudd_addGeneralVectorCompose. + +
        cuddAddIteRecur() +
        Implements the recursive step of Cudd_addIte(f,g,h). + +
        cuddAddMonadicApplyRecur() +
        Performs the recursive step of Cudd_addMonadicApply. + +
        cuddAddNegateRecur() +
        Implements the recursive step of Cudd_addNegate. + +
        cuddAddNonSimComposeRecur() +
        Performs the recursive step of Cudd_addNonSimCompose. + +
        cuddAddOrAbstractRecur() +
        Performs the recursive step of Cudd_addOrAbstract. + +
        cuddAddOuterSumRecur() +
        Performs the recursive step of Cudd_addOuterSum. + +
        cuddAddPermuteRecur() +
        Implements the recursive step of Cudd_addPermute. + +
        cuddAddRestrictRecur() +
        Performs the recursive step of Cudd_addRestrict. + +
        cuddAddRoundOffRecur() +
        Implements the recursive step of Cudd_addRoundOff. + +
        cuddAddScalarInverseRecur() +
        Performs the recursive step of addScalarInverse. + +
        cuddAddUnivAbstractRecur() +
        Performs the recursive step of Cudd_addUnivAbstract. + +
        cuddAddVectorComposeRecur() +
        Performs the recursive step of Cudd_addVectorCompose. + +
        cuddAllocNode() +
        Fast storage allocation for DdNodes in the table. + +
        cuddAnnealing() +
        Get new variable-order by simulated annealing algorithm. + +
        cuddApaCountMintermAux() +
        Performs the recursive step of Cudd_ApaCountMinterm. + +
        cuddApaStCountfree() +
        Frees the memory used to store the minterm counts recorded + in the visited table. + +
        cuddBddAlignToZdd() +
        Reorders BDD variables according to the order of the ZDD + variables. + +
        cuddBddAndAbstractRecur() +
        Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
        cuddBddAndRecur() +
        Implements the recursive step of Cudd_bddAnd. + +
        cuddBddBooleanDiffRecur() +
        Performs the recursive steps of Cudd_bddBoleanDiff. + +
        cuddBddCharToVect() +
        Performs the recursive step of Cudd_bddCharToVect. + +
        cuddBddClipAndAbsRecur() +
        Approximates the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
        cuddBddClippingAndAbstract() +
        Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
        cuddBddClippingAndRecur() +
        Implements the recursive step of Cudd_bddClippingAnd. + +
        cuddBddClippingAnd() +
        Approximates the conjunction of two BDDs f and g. + +
        cuddBddClosestCube() +
        Performs the recursive step of Cudd_bddClosestCube. + +
        cuddBddComposeRecur() +
        Performs the recursive step of Cudd_bddCompose. + +
        cuddBddConstrainDecomp() +
        Performs the recursive step of Cudd_bddConstrainDecomp. + +
        cuddBddConstrainRecur() +
        Performs the recursive step of Cudd_bddConstrain. + +
        cuddBddExistAbstractRecur() +
        Performs the recursive steps of Cudd_bddExistAbstract. + +
        cuddBddIntersectRecur() +
        Implements the recursive step of Cudd_bddIntersect. + +
        cuddBddIsop() +
        Performs the recursive step of Cudd_bddIsop. + +
        cuddBddIteRecur() +
        Implements the recursive step of Cudd_bddIte. + +
        cuddBddLICBuildResult() +
        Builds the result of Cudd_bddLICompaction. + +
        cuddBddLICMarkEdges() +
        Performs the edge marking step of Cudd_bddLICompaction. + +
        cuddBddLICompaction() +
        Performs safe minimization of a BDD. + +
        cuddBddLiteralSetIntersectionRecur() +
        Performs the recursive step of + Cudd_bddLiteralSetIntersection. + +
        cuddBddMakePrime() +
        Performs the recursive step of Cudd_bddMakePrime. + +
        cuddBddNPAndRecur() +
        Implements the recursive step of Cudd_bddAnd. + +
        cuddBddPermuteRecur() +
        Implements the recursive step of Cudd_bddPermute. + +
        cuddBddRestrictRecur() +
        Performs the recursive step of Cudd_bddRestrict. + +
        cuddBddSqueeze() +
        Performs the recursive step of Cudd_bddSqueeze. + +
        cuddBddTransferRecur() +
        Performs the recursive step of Cudd_bddTransfer. + +
        cuddBddTransfer() +
        Convert a BDD from a manager to another one. + +
        cuddBddVarMapRecur() +
        Implements the recursive step of Cudd_bddVarMap. + +
        cuddBddVectorComposeRecur() +
        Performs the recursive step of Cudd_bddVectorCompose. + +
        cuddBddXorExistAbstractRecur() +
        Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
        cuddBddXorRecur() +
        Implements the recursive step of Cudd_bddXor. + +
        cuddBiasedUnderApprox() +
        Applies the biased remapping underappoximation algorithm. + +
        cuddCProjectionRecur() +
        Performs the recursive step of Cudd_CProjection. + +
        cuddCacheFlush() +
        Flushes the cache. + +
        cuddCacheInsert1() +
        Inserts a result in the cache for a function with two + operands. + +
        cuddCacheInsert2() +
        Inserts a result in the cache for a function with two + operands. + +
        cuddCacheInsert() +
        Inserts a result in the cache for a function with three + operands. + +
        cuddCacheLookup1Zdd() +
        Looks up in the cache for the result of op applied to f. + +
        cuddCacheLookup1() +
        Looks up in the cache for the result of op applied to f. + +
        cuddCacheLookup2Zdd() +
        Looks up in the cache for the result of op applied to f + and g. + +
        cuddCacheLookup2() +
        Looks up in the cache for the result of op applied to f + and g. + +
        cuddCacheLookupZdd() +
        Looks up in the cache for the result of op applied to f, + g, and h. + +
        cuddCacheLookup() +
        Looks up in the cache for the result of op applied to f, + g, and h. + +
        cuddCacheProfile() +
        Computes and prints a profile of the cache usage. + +
        cuddCacheResize() +
        Resizes the cache. + +
        cuddCheckCollisionOrdering() +
        Checks whether a collision list is ordered. + +
        cuddClearDeathRow() +
        Clears the death row. + +
        cuddCofactorRecur() +
        Performs the recursive step of Cudd_Cofactor. + +
        cuddCollectNodes() +
        Recursively collects all the nodes of a DD in a symbol + table. + +
        cuddComputeFloorLog2() +
        Returns the floor of the logarithm to the base 2. + +
        cuddConjunctsAux() +
        Procedure to compute two conjunctive factors of f and place in *c1 and *c2. + +
        cuddConstantLookup() +
        Looks up in the cache for the result of op applied to f, + g, and h. + +
        cuddDestroySubtables() +
        Destroys the n most recently created subtables in a unique table. + +
        cuddDoRebalance() +
        Rebalances a red/black tree. + +
        cuddDynamicAllocNode() +
        Dynamically allocates a Node. + +
        cuddEstimateCofactorSimple() +
        Performs the recursive step of Cudd_CofactorEstimateSimple. + +
        cuddEstimateCofactor() +
        Performs the recursive step of Cudd_CofactorEstimate. + +
        cuddExact() +
        Exact variable ordering algorithm. + +
        cuddFindParent() +
        Searches the subtables above node for a parent. + +
        cuddFreeTable() +
        Frees the resources associated to a unique table. + +
        cuddGarbageCollect() +
        Performs garbage collection on the unique tables. + +
        cuddGa() +
        Genetic algorithm for DD reordering. + +
        cuddGetBranches() +
        Computes the children of g. + +
        cuddHashTableGenericInsert() +
        Inserts an item in a hash table. + +
        cuddHashTableGenericLookup() +
        Looks up a key consisting of one pointer in a hash table. + +
        cuddHashTableGenericQuit() +
        Shuts down a hash table. + +
        cuddHashTableInit() +
        Initializes a hash table. + +
        cuddHashTableInsert1() +
        Inserts an item in a hash table. + +
        cuddHashTableInsert2() +
        Inserts an item in a hash table. + +
        cuddHashTableInsert3() +
        Inserts an item in a hash table. + +
        cuddHashTableInsert() +
        Inserts an item in a hash table. + +
        cuddHashTableLookup1() +
        Looks up a key consisting of one pointer in a hash table. + +
        cuddHashTableLookup2() +
        Looks up a key consisting of two pointers in a hash table. + +
        cuddHashTableLookup3() +
        Looks up a key consisting of three pointers in a hash table. + +
        cuddHashTableLookup() +
        Looks up a key in a hash table. + +
        cuddHashTableQuit() +
        Shuts down a hash table. + +
        cuddHashTableResize() +
        Resizes a hash table. + +
        cuddHeapProfile() +
        Prints information about the heap. + +
        cuddInitCache() +
        Initializes the computed table. + +
        cuddInitInteract() +
        Initializes the interaction matrix. + +
        cuddInitLinear() +
        Initializes the linear transform matrix. + +
        cuddInitTable() +
        Creates and initializes the unique table. + +
        cuddInsertSubtables() +
        Inserts n new subtables in a unique table at level. + +
        cuddIsInDeathRow() +
        Checks whether a node is in the death row. + +
        cuddLevelQueueDequeue() +
        Remove an item from the front of a level queue. + +
        cuddLevelQueueEnqueue() +
        Inserts a new key in a level queue. + +
        cuddLevelQueueFirst() +
        Inserts the first key in a level queue. + +
        cuddLevelQueueInit() +
        Initializes a level queue. + +
        cuddLevelQueueQuit() +
        Shuts down a level queue. + +
        cuddLinearAndSifting() +
        BDD reduction based on combination of sifting and linear + transformations. + +
        cuddLinearInPlace() +
        Linearly combines two adjacent variables. + +
        cuddLocalCacheAddToList() +
        Inserts a local cache in the manager list. + +
        cuddLocalCacheClearAll() +
        Clears the local caches of a manager. + +
        cuddLocalCacheClearDead() +
        Clears the dead entries of the local caches of a manager. + +
        cuddLocalCacheInit() +
        Initializes a local computed table. + +
        cuddLocalCacheInsert() +
        Inserts a result in a local cache. + +
        cuddLocalCacheLookup() +
        Looks up in a local cache. + +
        cuddLocalCacheProfile() +
        Computes and prints a profile of a local cache usage. + +
        cuddLocalCacheQuit() +
        Shuts down a local computed table. + +
        cuddLocalCacheRemoveFromList() +
        Removes a local cache from the manager list. + +
        cuddLocalCacheResize() +
        Resizes a local cache. + +
        cuddMakeBddFromZddCover() +
        Converts a ZDD cover to a BDD. + +
        cuddMinHammingDistRecur() +
        Performs the recursive step of Cudd_MinHammingDist. + +
        cuddNextHigh() +
        Finds the next subtable with a larger index. + +
        cuddNextLow() +
        Finds the next subtable with a smaller index. + +
        cuddNodeArrayRecur() +
        Performs the recursive step of cuddNodeArray. + +
        cuddNodeArray() +
        Recursively collects all the nodes of a DD in an array. + +
        cuddOrderedInsert() +
        Inserts a DdNode in a red/black search tree. + +
        cuddOrderedThread() +
        Threads all the nodes of a search tree into a linear list. + +
        cuddPrintNode() +
        Prints out information on a node. + +
        cuddPrintVarGroups() +
        Prints the variable groups as a parenthesized list. + +
        cuddP() +
        Prints a DD to the standard output. One line per node is + printed. + +
        cuddReclaimZdd() +
        Brings children of a dead ZDD node back. + +
        cuddReclaim() +
        Brings children of a dead node back. + +
        cuddRehash() +
        Rehashes a unique subtable. + +
        cuddRemapUnderApprox() +
        Applies the remapping underappoximation algorithm. + +
        cuddResizeLinear() +
        Resizes the linear transform matrix. + +
        cuddResizeTableZdd() +
        Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index. + +
        cuddSetInteract() +
        Set interaction matrix entries. + +
        cuddShrinkDeathRow() +
        Shrinks the death row. + +
        cuddShrinkSubtable() +
        Shrinks a subtable. + +
        cuddSifting() +
        Implementation of Rudell's sifting algorithm. + +
        cuddSlowTableGrowth() +
        Adjusts parameters of a table to slow down its growth. + +
        cuddSolveEqnRecur() +
        Implements the recursive step of Cudd_SolveEqn. + +
        cuddSplitSetRecur() +
        Implements the recursive step of Cudd_SplitSet. + +
        cuddStCountfree() +
        Frees the memory used to store the minterm counts recorded + in the visited table. + +
        cuddSubsetHeavyBranch() +
        The main procedure that returns a subset by choosing the heavier + branch in the BDD. + +
        cuddSubsetShortPaths() +
        The outermost procedure to return a subset of the given BDD + with the shortest path lengths. + +
        cuddSwapInPlace() +
        Swaps two adjacent variables. + +
        cuddSwapping() +
        Reorders variables by a sequence of (non-adjacent) swaps. + +
        cuddSymmCheck() +
        Checks for symmetry of x and y. + +
        cuddSymmSiftingConv() +
        Symmetric sifting to convergence algorithm. + +
        cuddSymmSifting() +
        Symmetric sifting algorithm. + +
        cuddTestInteract() +
        Test interaction matrix entries. + +
        cuddTimesInDeathRow() +
        Counts how many times a node is in the death row. + +
        cuddTreeSifting() +
        Tree sifting algorithm. + +
        cuddUnderApprox() +
        Applies Tom Shiple's underappoximation algorithm. + +
        cuddUniqueConst() +
        Checks the unique table for the existence of a constant node. + +
        cuddUniqueInterIVO() +
        Wrapper for cuddUniqueInter that is independent of variable + ordering. + +
        cuddUniqueInterZdd() +
        Checks the unique table for the existence of an internal + ZDD node. + +
        cuddUniqueInter() +
        Checks the unique table for the existence of an internal node. + +
        cuddUniqueLookup() +
        Checks the unique table for the existence of an internal node. + +
        cuddUpdateInteractionMatrix() +
        Updates the interaction matrix. + +
        cuddVerifySol() +
        Implements the recursive step of Cudd_VerifySol. + +
        cuddWindowReorder() +
        Reorders by applying the method of the sliding window. + +
        cuddXorLinear() +
        XORs two rows of the linear transform matrix. + +
        cuddZddAlignToBdd() +
        Reorders ZDD variables according to the order of the BDD + variables. + +
        cuddZddChangeAux() +
        Performs the recursive step of Cudd_zddChange. + +
        cuddZddChange() +
        Substitutes a variable with its complement in a ZDD. + +
        cuddZddComplement() +
        Computes a complement of a ZDD node. + +
        cuddZddCountDoubleStep() +
        Performs the recursive step of Cudd_zddCountDouble. + +
        cuddZddCountStep() +
        Performs the recursive step of Cudd_zddCount. + +
        cuddZddDagInt() +
        Performs the recursive step of Cudd_zddDagSize. + +
        cuddZddDiff() +
        Performs the recursive step of Cudd_zddDiff. + +
        cuddZddDivideF() +
        Performs the recursive step of Cudd_zddDivideF. + +
        cuddZddDivide() +
        Performs the recursive step of Cudd_zddDivide. + +
        cuddZddFreeUniv() +
        Frees the ZDD universe. + +
        cuddZddGetCofactors2() +
        Computes the two-way decomposition of f w.r.t. v. + +
        cuddZddGetCofactors3() +
        Computes the three-way decomposition of f w.r.t. v. + +
        cuddZddGetNegVarIndex() +
        Returns the index of negative ZDD variable. + +
        cuddZddGetNegVarLevel() +
        Returns the level of negative ZDD variable. + +
        cuddZddGetNodeIVO() +
        Wrapper for cuddUniqueInterZdd that is independent of variable + ordering. + +
        cuddZddGetNode() +
        Wrapper for cuddUniqueInterZdd. + +
        cuddZddGetPosVarIndex() +
        Returns the index of positive ZDD variable. + +
        cuddZddGetPosVarLevel() +
        Returns the level of positive ZDD variable. + +
        cuddZddInitUniv() +
        Initializes the ZDD universe. + +
        cuddZddIntersect() +
        Performs the recursive step of Cudd_zddIntersect. + +
        cuddZddIsop() +
        Performs the recursive step of Cudd_zddIsop. + +
        cuddZddIte() +
        Performs the recursive step of Cudd_zddIte. + +
        cuddZddLinearAux() +
        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
        cuddZddLinearBackward() +
        Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
        cuddZddLinearDown() +
        Sifts a variable down and applies the XOR transformation. + +
        cuddZddLinearInPlace() +
        Linearly combines two adjacent variables. + +
        cuddZddLinearSifting() +
        Implementation of the linear sifting algorithm for ZDDs. + +
        cuddZddLinearUp() +
        Sifts a variable up applying the XOR transformation. + +
        cuddZddNextHigh() +
        Finds the next subtable with a larger index. + +
        cuddZddNextLow() +
        Finds the next subtable with a smaller index. + +
        cuddZddProduct() +
        Performs the recursive step of Cudd_zddProduct. + +
        cuddZddP() +
        Prints a ZDD to the standard output. One line per node is + printed. + +
        cuddZddSiftingAux() +
        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
        cuddZddSiftingBackward() +
        Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
        cuddZddSiftingDown() +
        Sifts a variable down. + +
        cuddZddSiftingUp() +
        Sifts a variable up. + +
        cuddZddSifting() +
        Implementation of Rudell's sifting algorithm. + +
        cuddZddSubset0() +
        Computes the negative cofactor of a ZDD w.r.t. a variable. + +
        cuddZddSubset1() +
        Computes the positive cofactor of a ZDD w.r.t. a variable. + +
        cuddZddSwapInPlace() +
        Swaps two adjacent variables. + +
        cuddZddSwapping() +
        Reorders variables by a sequence of (non-adjacent) swaps. + +
        cuddZddSymmCheck() +
        Checks for symmetry of x and y. + +
        cuddZddSymmSiftingAux() +
        Given x_low <= x <= x_high moves x up and down between the + boundaries. + +
        cuddZddSymmSiftingBackward() +
        Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
        cuddZddSymmSiftingConvAux() +
        Given x_low <= x <= x_high moves x up and down between the + boundaries. + +
        cuddZddSymmSiftingConv() +
        Symmetric sifting to convergence algorithm for ZDDs. + +
        cuddZddSymmSifting_down() +
        Moves x down until either it reaches the bound (x_high) or + the size of the ZDD heap increases too much. + +
        cuddZddSymmSifting_up() +
        Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much. + +
        cuddZddSymmSifting() +
        Symmetric sifting algorithm for ZDDs. + +
        cuddZddSymmSummary() +
        Counts numbers of symmetric variables and symmetry + groups. + +
        cuddZddTreeSifting() +
        Tree sifting algorithm for ZDDs. + +
        cuddZddUnateProduct() +
        Performs the recursive step of Cudd_zddUnateProduct. + +
        cuddZddUndoMoves() +
        Given a set of moves, returns the ZDD heap to the order + in effect before the moves. + +
        cuddZddUnion() +
        Performs the recursive step of Cudd_zddUnion. + +
        cuddZddUniqueCompare() +
        Comparison function used by qsort. + +
        cuddZddWeakDivF() +
        Performs the recursive step of Cudd_zddWeakDivF. + +
        cuddZddWeakDiv() +
        Performs the recursive step of Cudd_zddWeakDiv. + +
        ddBddMaximallyExpand() +
        Performs the recursive step of Cudd_bddMaximallyExpand. + +
        ddBddShortestPathUnate() +
        Performs shortest path computation on a unate function. + +
        ddBddToAddRecur() +
        Performs the recursive step for Cudd_BddToAdd. + +
        ddCheckPermuation() +
        Checks the BDD variable group tree before a shuffle. + +
        ddClearFlag() +
        Performs a DFS from f, clearing the LSB of the next + pointers. + +
        ddClearGlobal() +
        Scans the DD and clears the LSB of the next pointers. + +
        ddClearGlobal() +
        Scans the DD and clears the LSB of the next pointers. + +
        ddClearLocal() +
        Performs a DFS from f, clearing the LSB of the then pointers. + +
        ddClearVars() +
        Clears visited flags for variables. + +
        ddCofMintermAux() +
        Recursive Step for Cudd_CofMinterm function. + +
        ddCountInternalMtrNodes() +
        Counts the number of internal nodes of the group tree. + +
        ddCountMintermAux() +
        Performs the recursive step of Cudd_CountMinterm. + +
        ddCountPathAux() +
        Performs the recursive step of Cudd_CountPath. + +
        ddCountPathsToNonZero() +
        Performs the recursive step of Cudd_CountPathsToNonZero. + +
        ddCountRoots() +
        Counts the number of roots. + +
        ddCreateGroup() +
        Creates a group encompassing variables from x to y in the + DD table. + +
        ddDagInt() +
        Performs the recursive step of Cudd_DagSize. + +
        ddDissolveGroup() +
        Dissolves a group in the DD table. + +
        ddDoDumpBlif() +
        Performs the recursive step of Cudd_DumpBlif. + +
        ddDoDumpDDcal() +
        Performs the recursive step of Cudd_DumpDDcal. + +
        ddDoDumpDaVinci() +
        Performs the recursive step of Cudd_DumpDaVinci. + +
        ddDoDumpFactoredForm() +
        Performs the recursive step of Cudd_DumpFactoredForm. + +
        ddEpdCountMintermAux() +
        Performs the recursive step of Cudd_EpdCountMinterm. + +
        ddEpdFree() +
        Frees the memory used to store the minterm counts recorded + in the visited table. + +
        ddExchange() +
        This function is for exchanging two variables, x and y. + +
        ddExtSymmCheck() +
        Checks for extended symmetry of x and y. + +
        ddFindEssentialRecur() +
        Implements the recursive step of Cudd_FindEssential. + +
        ddFindNodeHiLo() +
        Finds the lower and upper bounds of the group represented + by treenode. + +
        ddFindSupport() +
        Recursively find the support of f. + +
        ddFindTwoLiteralClausesRecur() +
        Implements the recursive step of Cudd_FindTwoLiteralClauses. + +
        ddGetLargestCubeUnate() +
        Extracts largest prime of a unate function. + +
        ddGroupMoveBackward() +
        Undoes the swap two groups. + +
        ddGroupMove() +
        Swaps two groups and records the move. + +
        ddGroupSiftingAux() +
        Sifts one variable up and down until it has taken all + positions. Checks for aggregation. + +
        ddGroupSiftingBackward() +
        Determines the best position for a variables and returns + it there. + +
        ddGroupSiftingDown() +
        Sifts down a variable until it reaches position xHigh. + +
        ddGroupSiftingUp() +
        Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much. + +
        ddGroupSifting() +
        Sifts from treenode->low to treenode->high. + +
        ddIsVarHandled() +
        Checks whether a variables is already handled. + +
        ddJumpingAux() +
        Moves a variable to a specified position. + +
        ddJumpingDown() +
        This function is for jumping down. + +
        ddJumpingUp() +
        This function is for jumping up. + +
        ddLeavesInt() +
        Performs the recursive step of Cudd_CountLeaves. + +
        ddLinearAndSiftingAux() +
        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
        ddLinearAndSiftingBackward() +
        Given a set of moves, returns the DD heap to the order + giving the minimum size. + +
        ddLinearAndSiftingDown() +
        Sifts a variable down and applies linear transformations. + +
        ddLinearAndSiftingUp() +
        Sifts a variable up and applies linear transformations. + +
        ddLinearUniqueCompare() +
        Comparison function used by qsort. + +
        ddMergeGroups() +
        Merges groups in the DD table. + +
        ddNoCheck() +
        Pretends to check two variables for aggregation. + +
        ddPatchTree() +
        Fixes a variable tree after the insertion of new subtables. + +
        ddPermuteWindow3() +
        Tries all the permutations of the three variables between + x and x+2 and retains the best. + +
        ddPermuteWindow4() +
        Tries all the permutations of the four variables between w + and w+3 and retains the best. + +
        ddPickArbitraryMinterms() +
        Performs the recursive step of Cudd_bddPickArbitraryMinterms. + +
        ddPickRepresentativeCube() +
        Finds a representative cube of a BDD. + +
        ddPrintMintermAux() +
        Performs the recursive step of Cudd_PrintMinterm. + +
        ddRehashZdd() +
        Rehashes a ZDD unique subtable. + +
        ddReorderChildren() +
        Reorders the children of a group tree node according to + the options. + +
        ddReorderPostprocess() +
        Cleans up at the end of reordering. + +
        ddReorderPreprocess() +
        Prepares the DD heap for dynamic reordering. + +
        ddReportRefMess() +
        Reports problem in garbage collection. + +
        ddResetVarHandled() +
        Resets a variable to be processed. + +
        ddResizeTable() +
        Increases the number of subtables in a unique table so + that it meets or exceeds index. + +
        ddSecDiffCheck() +
        Checks two variables for aggregation. + +
        ddSetVarHandled() +
        Sets a variable to already handled. + +
        ddShuffle() +
        Reorders variables according to a given permutation. + +
        ddShuffle() +
        Reorders variables according to a given permutation. + +
        ddSiftUp() +
        Moves one variable up. + +
        ddSiftUp() +
        Moves one variable up. + +
        ddSiftingAux() +
        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
        ddSiftingBackward() +
        Given a set of moves, returns the DD heap to the position + giving the minimum size. + +
        ddSiftingDown() +
        Sifts a variable down. + +
        ddSiftingUp() +
        Sifts a variable up. + +
        ddSuppInteract() +
        Find the support of f. + +
        ddSupportStep() +
        Performs the recursive step of Cudd_Support. + +
        ddSwapAny() +
        Swaps any two variables. + +
        ddSymmGroupMoveBackward() +
        Undoes the swap of two groups. + +
        ddSymmGroupMove() +
        Swaps two groups. + +
        ddSymmSiftingAux() +
        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
        ddSymmSiftingBackward() +
        Given a set of moves, returns the DD heap to the position + giving the minimum size. + +
        ddSymmSiftingConvAux() +
        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
        ddSymmSiftingDown() +
        Moves x down until either it reaches the bound (xHigh) or + the size of the DD heap increases too much. + +
        ddSymmSiftingUp() +
        Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much. + +
        ddSymmSummary() +
        Counts numbers of symmetric variables and symmetry + groups. + +
        ddSymmUniqueCompare() +
        Comparison function used by qsort. + +
        ddTreeSiftingAux() +
        Visits the group tree and reorders each group. + +
        ddUndoMoves() +
        Given a set of moves, returns the DD heap to the order + in effect before the moves. + +
        ddUniqueCompareGroup() +
        Comparison function used by qsort. + +
        ddUniqueCompare() +
        Comparison function used by qsort. + +
        ddUpdateInteract() +
        Marks as interacting all pairs of variables that appear in + support. + +
        ddUpdateMtrTree() +
        Updates the BDD variable group tree before a shuffle. + +
        ddVarGroupCheck() +
        Checks for grouping of x and y. + +
        ddWindow2() +
        Reorders by applying a sliding window of width 2. + +
        ddWindow3() +
        Reorders by applying a sliding window of width 3. + +
        ddWindow4() +
        Reorders by applying a sliding window of width 4. + +
        ddWindowConv2() +
        Reorders by repeatedly applying a sliding window of width 2. + +
        ddWindowConv3() +
        Reorders by repeatedly applying a sliding window of width 3. + +
        ddWindowConv4() +
        Reorders by repeatedly applying a sliding window of width 4. + +
        debugCheckParent() +
        Reports an error if a (dead) node has a non-dead parent. + +
        debugFindParent() +
        Searches the subtables above node for its parents. + +
        dp2() +
        Performs the recursive step of cuddP. + +
        emptyClauseSet() +
        Returns an enpty set of clauses. + +
        equalp() +
        Returns true iff the two arguments are identical clauses. + +
        find_best() +
        Returns the index of the fittest individual. + +
        fixVarTree() +
        Fixes a variable group tree. + +
        freeMatrix() +
        Frees a two-dimensional matrix allocated by getMatrix. + +
        freePathPair() +
        Frees the entries of the visited symbol table. + +
        gatherInfoAux() +
        Recursively counts minterms and computes reference counts + of each node in the BDD. + +
        gatherInfo() +
        Gathers information about each node. + +
        gcd() +
        Returns the gcd of two integers. + +
        getCube() +
        Build a BDD for a largest cube of f. + +
        getLargest() +
        Finds the size of the largest cube(s) in a DD. + +
        getLevelKeys() +
        Returns the number of nodes at one level of a unique table. + +
        getMatrix() +
        Allocates a two-dimensional matrix of ints. + +
        getMaxBinomial() +
        Returns the maximum value of (n choose k) for a given n. + +
        getPath() +
        Build a BDD for a shortest path of f. + +
        getShortest() +
        Finds the length of the shortest path(s) in a DD. + +
        hashDelete() +
        Removes an item from the hash table of a level queue. + +
        hashInsert() +
        Inserts an item in the hash table of a level queue. + +
        hashLookup() +
        Looks up a key in the hash table of a level queue. + +
        hashResize() +
        Resizes the hash table of a level queue. + +
        impliedp() +
        Returns true iff either literal of a clause is in a set of + literals. + +
        indexCompare() +
        Compares indices for qsort. + +
        initSymmInfo() +
        Gathers symmetry information. + +
        largest() +
        Finds the largest DD in the population. + +
        make_random() +
        Generates the random sequences for the initial population. + +
        mintermsFromUniverse() +
        Recursive procedure to extract n mintems from constant 1. + +
        oneliteralp() +
        Returns true iff the argument is a one-literal clause. + +
        pushDown() +
        Pushes a variable in the order down to position "level." + +
        rand_int() +
        Generates a random number between 0 and the integer a. + +
        random_generator() +
        Random number generator. + +
        restoreOrder() +
        Restores the variable order in array by a series of sifts up. + +
        roulette() +
        Selects two parents with the roulette wheel method. + +
        selectMintermsFromUniverse() +
        This function prepares an array of variables which have not been + encountered so far when traversing the procedure cuddSplitSetRecur. + +
        sentinelp() +
        Returns true iff the argument is the sentinel clause. + +
        separateCube() +
        Separates cube from distance. + +
        siftBackwardProb() +
        Returns the DD to the best position encountered during + sifting if there was improvement. + +
        sift_up() +
        Moves one variable up. + +
        stPathTableDdFree() +
        Procedure to free te result dds stored in the NodeDist pages. + +
        st_zdd_count_dbl_free() +
        Frees the memory associated with the computed table of + Cudd_zddCountDouble. + +
        st_zdd_countfree() +
        Frees the memory associated with the computed table of + Cudd_zddCount. + +
        stopping_criterion() +
        Checks termination condition. + +
        tlcInfoAlloc() +
        Allocates a DdTlcInfo Structure. + +
        updateEntry() +
        Updates entry for a subset. + +
        updateParity() +
        Recursively update the parity of the paths reaching a node. + +
        updateRefs() +
        Update function reference counts. + +
        updateUB() +
        Updates the upper bound and saves the best order seen so far. + +
        zddClearFlag() +
        Performs a DFS from f, clearing the LSB of the next + pointers. + +
        zddCountInternalMtrNodes() +
        Counts the number of internal nodes of the group tree. + +
        zddFindNodeHiLo() +
        Finds the lower and upper bounds of the group represented + by treenode. + +
        zddFixTree() +
        Fixes the ZDD variable group tree after a shuffle. + +
        zddGroupMoveBackward() +
        Undoes the swap two groups. + +
        zddGroupMove() +
        Swaps two groups and records the move. + +
        zddGroupSiftingAux() +
        Sifts one variable up and down until it has taken all + positions. Checks for aggregation. + +
        zddGroupSiftingBackward() +
        Determines the best position for a variables and returns + it there. + +
        zddGroupSiftingDown() +
        Sifts down a variable until it reaches position xHigh. + +
        zddGroupSiftingUp() +
        Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much. + +
        zddGroupSifting() +
        Sifts from treenode->low to treenode->high. + +
        zddMergeGroups() +
        Merges groups in the DD table. + +
        zddPortFromBddStep() +
        Performs the recursive step of Cudd_zddPortFromBdd. + +
        zddPortToBddStep() +
        Performs the recursive step of Cudd_zddPortToBdd. + +
        zddPrintCoverAux() +
        Performs the recursive step of Cudd_zddPrintCover. + +
        zddReorderChildren() +
        Reorders the children of a group tree node according to + the options. + +
        zddReorderPostprocess() +
        Shrinks almost empty ZDD subtables at the end of reordering + to guarantee that they have a reasonable load factor. + +
        zddReorderPreprocess() +
        Prepares the ZDD heap for dynamic reordering. + +
        zddShuffle() +
        Reorders ZDD variables according to a given permutation. + +
        zddSiftUp() +
        Moves one ZDD variable up. + +
        zddSupportStep() +
        Performs the recursive step of Cudd_zddSupport. + +
        zddSwapAny() +
        Swaps any two variables. + +
        zddTreeSiftingAux() +
        Visits the group tree and reorders each group. + +
        zddUniqueCompareGroup() +
        Comparison function used by qsort. + +
        zddVarToConst() +
        Replaces variables with constants if possible (part of + canonical form). + +
        zdd_group_move_backward() +
        Undoes the swap of two groups. + +
        zdd_group_move() +
        Swaps two groups. + +
        zdd_print_minterm_aux() +
        Performs the recursive step of Cudd_zddPrintMinterm. + +
        zdd_subset0_aux() +
        Performs the recursive step of Cudd_zddSubset0. + +
        zdd_subset1_aux() +
        Performs the recursive step of Cudd_zddSubset1. + +
        zp2() +
        Performs the recursive step of cuddZddP. + +
        () +
        Adds node to the head of the free list. + +
        () +
        Adds node to the head of the free list. + +
        () +
        Adjusts the values of table limits. + +
        () +
        Clears a bit vector. + +
        () +
        Clears the 4 least significant bits of a pointer. + +
        () +
        Comparison of a function to the i-th ADD variable. + +
        () +
        Comparison of a pair of functions to the i-th ADD variable. + +
        () +
        Complements a DD if a condition is true. + +
        () +
        Complements a DD. + +
        () +
        Computes hash function for keys of one operand. + +
        () +
        Computes hash function for keys of three operands. + +
        () +
        Computes hash function for keys of two operands. + +
        () +
        Computes the absolute value of a number. + +
        () +
        Computes the hash value for a local cache. + +
        () +
        Computes the maximum of two numbers. + +
        () +
        Computes the minimum of two numbers. + +
        () +
        Decreases the reference count of a node, if it is not + saturated. + +
        () +
        Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL. + +
        () +
        Extract the least significant digit of a double digit. + +
        () +
        Extract the most significant digit of a double digit. + +
        () +
        Fast storage allocation for items in a hash table. + +
        () +
        Finds the current position of ZDD variable index in the + order. + +
        () +
        Finds the current position of variable index in the + order. + +
        () +
        Hash function for the cache for functions with two + operands. + +
        () +
        Hash function for the cache. + +
        () +
        Hash function for the table of a level queue. + +
        () +
        Hash function for the unique table. + +
        () +
        Increases the reference count of a node, if it is not + saturated. + +
        () +
        Iterates over the cubes of a decision diagram. + +
        () +
        Iterates over the nodes of a decision diagram. + +
        () +
        Iterates over the paths of a ZDD. + +
        () +
        Iterates over the primes of a Boolean function. + +
        () +
        Outputs a line of stats. + +
        () +
        Performs the left rotation for red/black trees. + +
        () +
        Performs the right rotation for red/black trees. + +
        () +
        Returns 1 if a pointer is complemented. + +
        () +
        Returns 1 if the absolute value of the difference of the two + arguments x and y is less than e. + +
        () +
        Returns 1 if the node is a constant node. + +
        () +
        Returns 1 if the node is a constant node. + +
        () +
        Returns the arithmetic 0 constant node. + +
        () +
        Returns the average fitness of the population. + +
        () +
        Returns the complemented version of a pointer. + +
        () +
        Returns the constant 1 node. + +
        () +
        Returns the current position in the order of variable + index. + +
        () +
        Returns the else child of an internal node. + +
        () +
        Returns the else child of an internal node. + +
        () +
        Returns the i-th entry of a bit vector. + +
        () +
        Returns the minus infinity constant node. + +
        () +
        Returns the plus infinity constant node. + +
        () +
        Returns the regular version of a pointer. + +
        () +
        Returns the then child of an internal node. + +
        () +
        Returns the then child of an internal node. + +
        () +
        Returns the value of a constant node. + +
        () +
        Returns the value of a constant node. + +
        () +
        Saturating decrement operator. + +
        () +
        Saturating increment operator. + +
        () +
        Sets the i-th entry of a bit vector to a value. + +
        + +
        + +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFile.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFile.html new file mode 100644 index 000000000..4076ddeae --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFile.html @@ -0,0 +1,13 @@ + +The cudd package for maintainers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFunc.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFunc.html new file mode 100644 index 000000000..76ec3ae05 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFunc.html @@ -0,0 +1,13 @@ + +The cudd package for maintainers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllDet.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllDet.html new file mode 100644 index 000000000..b700560e8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllDet.html @@ -0,0 +1,15754 @@ + +The cudd package: all functions + + + +
        +
        +
        +
        +static unsigned int 
        +AssessPathLength(
        +  unsigned int * pathLengthArray, array determining number of nodes belonging to the different path lengths
        +  int  threshold, threshold to determine maximum allowable nodes in the subset
        +  int  numVars, maximum number of variables
        +  unsigned int * excess, number of nodes labeled maxpath required in the subset
        +  FILE * fp where to write messages
        +)
        +
        +
        Chooses the maximum allowable path length under each node. + The corner cases are when the threshold is larger than the number + of nodes in the BDD iself, in which case 'numVars + 1' is returned. + If all nodes of a particular path length are needed, then the + maxpath returned is the next one with excess nodes = 0; +

        + +

        Side Effects None +

        + +

        Defined in cuddSubsetSP.c + +
        +
        +static int 
        +BAapplyBias(
        +  DdManager * dd, 
        +  DdNode * f, 
        +  DdNode * b, 
        +  ApproxInfo * info, 
        +  DdHashTable * cache 
        +)
        +
        +
        Finds don't care nodes by traversing f and b in parallel. + Returns the care status of the visited f node if successful; CARE_ERROR + otherwise. +

        + +

        Side Effects None +

        + +

        See Also cuddBiasedUnderApprox + + +
        Defined in cuddApprox.c + +
        +
        +static int 
        +BAmarkNodes(
        +  DdManager * dd, manager
        +  DdNode * f, function to be analyzed
        +  ApproxInfo * info, info on BDD
        +  int  threshold, when to stop approximating
        +  double  quality1, minimum improvement for accepted changes when b=1
        +  double  quality0 minimum improvement for accepted changes when b=0
        +)
        +
        +
        Marks nodes for remapping. Returns 1 if successful; 0 + otherwise. +

        + +

        Side Effects None +

        + +

        See Also cuddBiasedUnderApprox + + +
        Defined in cuddApprox.c + +
        +
        +static Conjuncts * 
        +BuildConjuncts(
        +  DdManager * dd, 
        +  DdNode * node, 
        +  st_table * distanceTable, 
        +  st_table * cacheTable, 
        +  int  approxDistance, 
        +  int  maxLocalRef, 
        +  st_table * ghTable, 
        +  st_table * mintermTable 
        +)
        +
        +
        Builds the conjuncts recursively, bottom up. Constants + are returned as (f, f). The cache is checked for previously computed + result. The decomposition points are determined by the local + reference count of this node and the longest distance from the + constant. At the decomposition point, the factors returned are (f, + 1). Recur on the two children. The order is determined by the + heavier branch. Combine the factors of the two children and pick the + one that already occurs in the gh table. Occurence in g is indicated + by value 1, occurence in h by 2, occurence in both 3. +

        + +

        See Also cuddConjunctsAux + + +
        Defined in cuddDecomp.c + +
        +
        +static DdNode * 
        +BuildSubsetBdd(
        +  DdManager * dd, DD manager
        +  GlobalInfo_t * gInfo, global information
        +  st_table * pathTable, path table with path lengths and computed results
        +  DdNode * node, current node
        +  struct AssortedInfo * info, assorted information structure
        +  st_table * subsetNodeTable table storing computed results
        +)
        +
        +
        Builds the BDD with nodes labeled with path length + under maxpath and as many nodes labeled maxpath as determined by the + threshold. The procedure uses the path table to determine which nodes + in the original bdd need to be retained. This procedure picks a + shortest path (tie break decided by taking the child with the shortest + distance to the constant) and recurs down the path till it reaches the + constant. the procedure then starts building the subset upward from + the constant. All nodes labeled by path lengths less than the given + maxpath are used to build the subset. However, in the case of nodes + that have label equal to maxpath, as many are chosen as required by + the threshold. This number is stored in the info structure in the + field thresholdReached. This field is decremented whenever a node + labeled maxpath is encountered and the nodes labeled maxpath are + aggregated in a maxpath table. As soon as the thresholdReached count + goes to 0, the shortest path from this node to the constant is found. + The extraction of nodes with the above labeling is based on the fact + that each node, labeled with a path length, P, has at least one child + labeled P or less. So extracting all nodes labeled a given path length + P ensures complete paths between the root and the constant. Extraction + of a partial number of nodes with a given path length may result in + incomplete paths and hence the additional number of nodes are grabbed + to complete the path. Since the Bdd is built bottom-up, other nodes + labeled maxpath do lie on complete paths. The procedure may cause the + subset to have a larger or smaller number of nodes than the specified + threshold. The increase in the number of nodes is caused by the + building of a subset and the reduction by recombination. However in + most cases, the recombination overshadows the increase and the + procedure returns a result with lower number of nodes than specified. + The subsetNodeTable is NIL when there is no hard limit on the number + of nodes. Further efforts towards keeping the subset closer to the + threshold number were abandoned in favour of keeping the procedure + simple and fast. +

        + +

        Side Effects SubsetNodeTable is changed if it is not NIL. +

        + +

        Defined in cuddSubsetSP.c + +
        +
        +static DdNode * 
        +BuildSubsetBdd(
        +  DdManager * dd, DD manager
        +  DdNode * node, current node
        +  int * size, current size of the subset
        +  st_table * visitedTable, visited table storing all node data
        +  int  threshold, 
        +  st_table * storeTable, 
        +  st_table * approxTable 
        +)
        +
        +
        The procedure carries out the building of the subset BDD + starting at the root. Using the three different counts labelling each node, + the procedure chooses the heavier branch starting from the root and keeps + track of the number of nodes it discards at each step, thus keeping count + of the size of the subset BDD dynamically. Once the threshold is satisfied, + the procedure then calls ITE to build the BDD. +

        + +

        Side Effects None +

        + +

        Defined in cuddSubsetHB.c + +
        +
        + 
        +CUDD_VALUE_TYPE *þvalueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +CUDD_VALUE_TYPE *þvalueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +CUDD_VALUE_TYPE þcþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +CUDD_VALUE_TYPE þepþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +CUDD_VALUE_TYPE þupperþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +CUDD_VALUE_TYPE þvalueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +CUDD_VALUE_TYPE þvalueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        +static Conjuncts * 
        +CheckInTables(
        +  DdNode * node, 
        +  DdNode * g1, 
        +  DdNode * h1, 
        +  DdNode * g2, 
        +  DdNode * h2, 
        +  st_table * ghTable, 
        +  st_table * cacheTable, 
        +  int * outOfMem 
        +)
        +
        +
        Check if the two pairs exist in the table. If any of + the conjuncts do exist, store in the cache and return the + corresponding pair. +

        + +

        See Also ZeroCase +BuildConjuncts + + +
        Defined in cuddDecomp.c + +
        +
        +static Conjuncts * 
        +CheckTablesCacheAndReturn(
        +  DdNode * node, 
        +  DdNode * g, 
        +  DdNode * h, 
        +  st_table * ghTable, 
        +  st_table * cacheTable 
        +)
        +
        +
        Check the tables for the existence of pair and return + one combination, cache the result. The assumption is that one of the + conjuncts is already in the tables. +

        + +

        Side Effects g and h referenced for the cache +

        + +

        See Also ZeroCase + + +
        Defined in cuddDecomp.c + +
        +
        +static void 
        +ConjunctsFree(
        +  DdManager * dd, 
        +  Conjuncts * factors 
        +)
        +
        +
        Free factors structure +

        + +

        Side Effects None +

        + +

        Defined in cuddDecomp.c + +
        +
        +static enum st_retval 
        +CorrelCleanUp(
        +  char * key, 
        +  char * value, 
        +  char * arg 
        +)
        +
        +
        Frees memory associated with hash table. Returns + ST_CONTINUE. +

        + +

        Side Effects None +

        + +

        Defined in cuddBddCorr.c + +
        +
        +static int 
        +CorrelCompare(
        +  const char * key1, 
        +  const char * key2 
        +)
        +
        +
        Compares two hash table entries. Returns 0 if they are + identical; 1 otherwise. +

        + +

        Side Effects None +

        + +

        Defined in cuddBddCorr.c + +
        +
        +static int 
        +CorrelHash(
        +  char * key, 
        +  int  modulus 
        +)
        +
        +
        Hashes a hash table entry. It is patterned after + st_strhash. Returns a value between 0 and modulus. +

        + +

        Side Effects None +

        + +

        Defined in cuddBddCorr.c + +
        +
        +static double 
        +CountMinterms(
        +  DdNode * node, 
        +  double  max, 
        +  st_table * mintermTable, 
        +  FILE * fp 
        +)
        +
        +
        Count the number of minterms of each node ina a BDD and + store it in a hash table. +

        + +

        Side Effects None +

        + +

        Defined in cuddDecomp.c + +
        +
        +static NodeStat * 
        +CreateBotDist(
        +  DdNode * node, 
        +  st_table * distanceTable 
        +)
        +
        +
        Get longest distance of node from constant. Returns the + distance of the root from the constant if successful; CUDD_OUT_OF_MEM + otherwise. +

        + +

        Side Effects None +

        + +

        Defined in cuddDecomp.c + +
        +
        +static int 
        +CreateBotDist(
        +  DdNode * node, current node
        +  st_table * pathTable, path table with path lengths
        +  unsigned int * pathLengthArray, array that stores number of nodes belonging to a particular path length.
        +  FILE * fp where to write messages
        +)
        +
        +
        Labels each node with the shortest distance from the constant. + This is done in a DFS search of the BDD. Each node has an odd + and even parity distance from the sink (since there exists paths to both + zero and one) which is less than MAXSHORTINT. At each node these distances + are updated using the minimum distance of its children from the constant. + SInce now both the length from the root and child is known, the minimum path + length(length of the shortest path between the root and the constant that + this node lies on) of this node can be calculated and used to update the + pathLengthArray +

        + +

        Side Effects Updates Path Table and path length array +

        + +

        See Also CreatePathTable +CreateTopDist +AssessPathLength + + +
        Defined in cuddSubsetSP.c + +
        +
        +static st_table * 
        +CreatePathTable(
        +  DdManager * dd, DD manager
        +  GlobalInfo_t * gInfo, global information
        +  DdNode * node, root of function
        +  unsigned int * pathLengthArray, array of path lengths to store nodes labeled with the various path lengths
        +  FILE * fp where to write messages
        +)
        +
        +
        The outer procedure to label each node with its shortest + distance from the root and constant. Calls CreateTopDist and CreateBotDist. + The basis for computing the distance between root and constant is that + the distance may be the sum of even distances from the node to the root + and constant or the sum of odd distances from the node to the root and + constant. Both CreateTopDist and CreateBotDist create the odd and + even parity distances from the root and constant respectively. +

        + +

        Side Effects None +

        + +

        See Also CreateTopDist +CreateBotDist + + +
        Defined in cuddSubsetSP.c + +
        +
        +static void 
        +CreateTopDist(
        +  DdManager * dd, DD manager
        +  GlobalInfo_t * gInfo, global information
        +  st_table * pathTable, hast table to store path lengths
        +  int  parentPage, the pointer to the page on which the first parent in the queue is to be found.
        +  int  parentQueueIndex, pointer to the first parent on the page
        +  int  topLen, current distance from the root
        +  DdNode ** childPage, pointer to the page on which the first child is to be added.
        +  int  childQueueIndex, pointer to the first child
        +  int  numParents, number of parents to process in this recursive call
        +  FILE * fp where to write messages
        +)
        +
        +
        Labels each node with its shortest distance from the root. + This is done in a BFS search of the BDD. The nodes are processed + in a queue implemented as pages(array) to reduce memory fragmentation. + An entry is created for each node visited. The distance from the root + to the node with the corresponding parity is updated. The procedure + is called recursively each recusion level handling nodes at a given + level from the root. +

        + +

        Side Effects Creates entries in the pathTable +

        + +

        See Also CreatePathTable +CreateBotDist + + +
        Defined in cuddSubsetSP.c + +
        +
        + 
        +Cudd_AggregationType þgcþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +Cudd_HookType þwhereþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +Cudd_HookType þwhereþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +Cudd_HookType þwhereþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +Cudd_ReorderingType *þmethodþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +Cudd_ReorderingType *þmethodþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +Cudd_ReorderingType þmethodþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +Cudd_ReorderingType þmethodþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DD_PRFP þPifuncþfunction used to build Pi if it is NULL(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdApaDigit þliteralþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdApaNumber þbþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdApaNumber þdestþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdApaNumber þdiffþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdApaNumber þnumberþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdApaNumber þnumberþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdApaNumber þquotientþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdApaNumber þquotientþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdApaNumber þsecondþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdApaNumber þsumþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdGen *þgenþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdGen *þgenþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þddþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þmanagerþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þtableþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þtableþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þtableþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þtableþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdManager *þuniqueþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode ***þconjunctsþaddress of the array of conjuncts(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode ***þconjunctsþaddress of the array of conjuncts(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode ***þconjunctsþaddress of the array of conjuncts(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode ***þconjunctsþaddress of the first factor(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þonlyGþcube of variables only in g(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þvectorOffþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þvectorþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þvectorþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þvectorþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þyþarray of y variables(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þyþarray of y variables(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þyþarray of y variables(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þyþarray of y variables(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þyþarray of y variables(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þzdd_Iþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þzþarray of z variables(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode **þzþarray of z variables(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þBþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þBþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þDþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þDþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þPþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þPþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þQþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þQþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þQþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þQþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þUþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þYþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þbckþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcubeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcubeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcubeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcubeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcubeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcubeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcubeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þcþconstraint (care set)(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þepsilonþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþDD whose support is sought(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþDD whose support is sought(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþDD whose support size is sought(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþZDD whose support is sought(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþfunction against which to expand(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþfunction in which to remap variables(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þfþfunction of which the cube is to be made a prime(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þgþsecond operand(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þhþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þhþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þhþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þhþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þhþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þnþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þp_nodeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þphaseBddþcube of the phases(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þuþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þuþupper bound(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdNode *þvarþvariable(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +DdTlcInfo *þtþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +EpDouble *þepdþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +FILE *þfpþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +FILE *þfpþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +FILE *þfpþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +FILE *þfpþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +FILE *þfpþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +FILE *þfpþpointer to the dump file(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +FILE *þfpþpointer to the dump file(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +FILE *þfpþpointer to the dump file(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +FILE *þfpþpointer to the dump file(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +FILE *þfpþpointer to the dump file(
        +    
        +)
        +
        +
        +

        + +

        +
        +static enum st_retval 
        +MarkCacheCleanUp(
        +  char * key, 
        +  char * value, 
        +  char * arg 
        +)
        +
        +
        Frees memory associated with computed table of + cuddBddLICMarkEdges. Returns ST_CONTINUE. +

        + +

        Side Effects None +

        + +

        See Also Cudd_bddLICompaction + + +
        Defined in cuddGenCof.c + +
        +
        +static int 
        +MarkCacheCompare(
        +  const char * ptr1, 
        +  const char * ptr2 
        +)
        +
        +
        Comparison function for the computed table of + cuddBddLICMarkEdges. Returns 0 if the two nodes of the key are equal; 1 + otherwise. +

        + +

        Side Effects None +

        + +

        See Also Cudd_bddLICompaction + + +
        Defined in cuddGenCof.c + +
        +
        +static int 
        +MarkCacheHash(
        +  char * ptr, 
        +  int  modulus 
        +)
        +
        +
        Hash function for the computed table of + cuddBddLICMarkEdges. Returns the bucket number. +

        + +

        Side Effects None +

        + +

        See Also Cudd_bddLICompaction + + +
        Defined in cuddGenCof.c + +
        +
        + 
        +MtrNode *þtreeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +MtrNode *þtreeþ(
        +    
        +)
        +
        +
        +

        + +

        +
        +static int 
        +PMX(
        +  int  maxvar 
        +)
        +
        +
        Performs the crossover between two randomly chosen + parents, and creates two children, x1 and x2. Uses the Partially + Matched Crossover operator. +

        + +

        Side Effects None +

        + +

        Defined in cuddGenetic.c + +
        +
        +static int 
        +PairInTables(
        +  DdNode * g, 
        +  DdNode * h, 
        +  st_table * ghTable 
        +)
        +
        +
        .Check whether the given pair is in the tables. gTable + and hTable are combined. + absence in both is indicated by 0, + presence in gTable is indicated by 1, + presence in hTable by 2 and + presence in both by 3. + The values returned by this function are PAIR_ST, + PAIR_CR, G_ST, G_CR, H_ST, H_CR, BOTH_G, BOTH_H, NONE. + PAIR_ST implies g in gTable and h in hTable + PAIR_CR implies g in hTable and h in gTable + G_ST implies g in gTable and h not in any table + G_CR implies g in hTable and h not in any table + H_ST implies h in hTable and g not in any table + H_CR implies h in gTable and g not in any table + BOTH_G implies both in gTable + BOTH_H implies both in hTable + NONE implies none in table; +

        + +

        See Also CheckTablesCacheAndReturn +CheckInTables + + +
        Defined in cuddDecomp.c + +
        +
        +static Conjuncts * 
        +PickOnePair(
        +  DdNode * node, 
        +  DdNode * g1, 
        +  DdNode * h1, 
        +  DdNode * g2, 
        +  DdNode * h2, 
        +  st_table * ghTable, 
        +  st_table * cacheTable 
        +)
        +
        +
        Check the tables for the existence of pair and return + one combination, store in cache. The pair that has more pointers to + it is picked. An approximation of the number of local pointers is + made by taking the reference count of the pairs sent. +

        + +

        See Also ZeroCase +BuildConjuncts + + +
        Defined in cuddDecomp.c + +
        +
        +static DdNode * 
        +RAbuildSubset(
        +  DdManager * dd, DD manager
        +  DdNode * node, current node
        +  ApproxInfo * info node info
        +)
        +
        +
        Builds the subset BDDfor cuddRemapUnderApprox. Based + on the info table, performs remapping or replacement at selected + nodes. Returns a pointer to the result if successful; NULL + otherwise. +

        + +

        Side Effects None +

        + +

        See Also cuddRemapUnderApprox + + +
        Defined in cuddApprox.c + +
        +
        +static int 
        +RAmarkNodes(
        +  DdManager * dd, manager
        +  DdNode * f, function to be analyzed
        +  ApproxInfo * info, info on BDD
        +  int  threshold, when to stop approximating
        +  double  quality minimum improvement for accepted changes
        +)
        +
        +
        Marks nodes for remapping. Returns 1 if successful; 0 + otherwise. +

        + +

        Side Effects None +

        + +

        See Also cuddRemapUnderApprox + + +
        Defined in cuddApprox.c + +
        +
        +static void 
        +ResizeCountMintermPages(
        +    
        +)
        +
        +
        Resize the number of pages allocated to store the minterm + counts. The procedure moves the counter to the next page when the + end of the page is reached and allocates new pages when necessary. +

        + +

        Side Effects Changes the size of minterm pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

        + +

        Defined in cuddSubsetHB.c + +
        +
        +static void 
        +ResizeCountNodePages(
        +    
        +)
        +
        +
        Resize the number of pages allocated to store the node counts. + The procedure moves the counter to the next page when the end of + the page is reached and allocates new pages when necessary. +

        + +

        Side Effects Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

        + +

        Defined in cuddSubsetHB.c + +
        +
        +static void 
        +ResizeNodeDataPages(
        +    
        +)
        +
        +
        Resize the number of pages allocated to store the node data + The procedure moves the counter to the next page when the end of + the page is reached and allocates new pages when necessary. +

        + +

        Side Effects Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

        + +

        Defined in cuddSubsetHB.c + +
        +
        +static void 
        +ResizeNodeDistPages(
        +  DdManager * dd, DD manager
        +  GlobalInfo_t * gInfo global information
        +)
        +
        +
        Resize the number of pages allocated to store the distances + related to each node. The procedure moves the counter to the + next page when the end of the page is reached and allocates new + pages when necessary. +

        + +

        Side Effects Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

        + +

        Defined in cuddSubsetSP.c + +
        +
        +static void 
        +ResizeQueuePages(
        +  DdManager * dd, DD manager
        +  GlobalInfo_t * gInfo global information
        +)
        +
        +
        Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd. The procedure moves the counter to the + next page when the end of the page is reached and allocates new + pages when necessary. +

        + +

        Side Effects Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

        + +

        Defined in cuddSubsetSP.c + +
        +
        +static void 
        +StoreNodes(
        +  st_table * storeTable, 
        +  DdManager * dd, 
        +  DdNode * node 
        +)
        +
        +
        rocedure to recursively store nodes that are retained in the subset. +

        + +

        Side Effects None +

        + +

        See Also StoreNodes + + +
        Defined in cuddSubsetHB.c + +
        +
        +static double 
        +SubsetCountMintermAux(
        +  DdNode * node, function to analyze
        +  double  max, number of minterms of constant 1
        +  st_table * table visitedTable table
        +)
        +
        +
        Recursively counts minterms of each node in the DAG. + Similar to the cuddCountMintermAux which recursively counts the + number of minterms for the dag rooted at each node in terms of the + total number of variables (max). This procedure creates the node + data structure and stores the minterm count as part of the node + data structure. +

        + +

        Side Effects Creates structures of type node quality and fills the st_table +

        + +

        See Also SubsetCountMinterm + + +
        Defined in cuddSubsetHB.c + +
        +
        +static st_table * 
        +SubsetCountMinterm(
        +  DdNode * node, function to be analyzed
        +  int  nvars number of variables node depends on
        +)
        +
        +
        Counts minterms of each node in the DAG. Similar to the + Cudd_CountMinterm procedure except this returns the minterm count for + all the nodes in the bdd in an st_table. +

        + +

        Side Effects none +

        + +

        See Also SubsetCountMintermAux + + +
        Defined in cuddSubsetHB.c + +
        +
        +static int 
        +SubsetCountNodesAux(
        +  DdNode * node, current node
        +  st_table * table, table to update node count, also serves as visited table.
        +  double  max maximum number of variables
        +)
        +
        +
        Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node. . Note that the same dag may be the lighter child of two + different nodes and have different counts. As with the minterm counts, + the node counts are stored in pages to be space efficient and the + address for these node counts are stored in an st_table associated + to each node. +

        + +

        Side Effects Updates the node data table with node counts +

        + +

        See Also SubsetCountNodes + + +
        Defined in cuddSubsetHB.c + +
        +
        +static int 
        +SubsetCountNodes(
        +  DdNode * node, function to be analyzed
        +  st_table * table, node quality table
        +  int  nvars number of variables node depends on
        +)
        +
        +
        Counts the nodes under the current node and its lighter + child. Calls a recursive procedure to count the number of nodes of + a DAG rooted at a particular node and the number of nodes taken by its + lighter child. +

        + +

        Side Effects None +

        + +

        See Also SubsetCountNodesAux + + +
        Defined in cuddSubsetHB.c + +
        +
        +static DdNode * 
        +UAbuildSubset(
        +  DdManager * dd, DD manager
        +  DdNode * node, current node
        +  ApproxInfo * info node info
        +)
        +
        +
        Builds the subset BDD. Based on the info table, + replaces selected nodes by zero. Returns a pointer to the result if + successful; NULL otherwise. +

        + +

        Side Effects None +

        + +

        See Also cuddUnderApprox + + +
        Defined in cuddApprox.c + +
        +
        +static int 
        +UAmarkNodes(
        +  DdManager * dd, manager
        +  DdNode * f, function to be analyzed
        +  ApproxInfo * info, info on BDD
        +  int  threshold, when to stop approximating
        +  int  safe, enforce safe approximation
        +  double  quality minimum improvement for accepted changes
        +)
        +
        +
        Marks nodes for replacement by zero. Returns 1 if successful; + 0 otherwise. +

        + +

        Side Effects None +

        + +

        See Also cuddUnderApprox + + +
        Defined in cuddApprox.c + +
        +
        +static Conjuncts * 
        +ZeroCase(
        +  DdManager * dd, 
        +  DdNode * node, 
        +  Conjuncts * factorsNv, 
        +  st_table * ghTable, 
        +  st_table * cacheTable, 
        +  int  switched 
        +)
        +
        +
        If one child is zero, do explicitly what Restrict does or better. + First separate a variable and its child in the base case. In case of a cube + times a function, separate the cube and function. As a last resort, look in + tables. +

        + +

        Side Effects Frees the BDDs in factorsNv. factorsNv itself is not freed + because it is freed above. +

        + +

        See Also BuildConjuncts + + +
        Defined in cuddDecomp.c + +
        +
        +static DdNode * 
        +addBddDoInterval(
        +  DdManager * dd, 
        +  DdNode * f, 
        +  DdNode * l, 
        +  DdNode * u 
        +)
        +
        +
        Performs the recursive step for Cudd_addBddInterval. + Returns a pointer to the BDD if successful; NULL otherwise. +

        + +

        Side Effects None +

        + +

        See Also addBddDoThreshold +addBddDoStrictThreshold + + +
        Defined in cuddBridge.c + +
        +
        +static DdNode * 
        +addBddDoIthBit(
        +  DdManager * dd, 
        +  DdNode * f, 
        +  DdNode * index 
        +)
        +
        +
        Performs the recursive step for Cudd_addBddIthBit. + Returns a pointer to the BDD if successful; NULL otherwise. +

        + +

        Side Effects None +

        + +

        Defined in cuddBridge.c + +
        +
        +static DdNode * 
        +addBddDoStrictThreshold(
        +  DdManager * dd, 
        +  DdNode * f, 
        +  DdNode * val 
        +)
        +
        +
        Performs the recursive step for Cudd_addBddStrictThreshold. + Returns a pointer to the BDD if successful; NULL otherwise. +

        + +

        Side Effects None +

        + +

        See Also addBddDoThreshold + + +
        Defined in cuddBridge.c + +
        +
        +static DdNode * 
        +addBddDoThreshold(
        +  DdManager * dd, 
        +  DdNode * f, 
        +  DdNode * val 
        +)
        +
        +
        Performs the recursive step for Cudd_addBddThreshold. + Returns a pointer to the BDD if successful; NULL otherwise. +

        + +

        Side Effects None +

        + +

        See Also addBddDoStrictThreshold + + +
        Defined in cuddBridge.c + +
        +
        +static int 
        +addCheckPositiveCube(
        +  DdManager * manager, 
        +  DdNode * cube 
        +)
        +
        +
        Checks whether cube is an ADD representing the product of + positive literals. Returns 1 in case of success; 0 otherwise. +

        + +

        Side Effects None +

        + +

        Defined in cuddAddAbs.c + +
        +
        +static DdNode * 
        +addDoIthBit(
        +  DdManager * dd, 
        +  DdNode * f, 
        +  DdNode * index 
        +)
        +
        +
        Performs the recursive step for Cudd_addIthBit. + Returns a pointer to the BDD if successful; NULL otherwise. +

        + +

        Side Effects None +

        + +

        Defined in cuddAddFind.c + +
        +
        +static DdNode * 
        +addMMRecur(
        +  DdManager * dd, 
        +  DdNode * A, 
        +  DdNode * B, 
        +  int  topP, 
        +  int * vars 
        +)
        +
        +
        Performs the recursive step of Cudd_addMatrixMultiply. + Returns a pointer to the result if successful; NULL otherwise. +

        + +

        Side Effects None +

        + +

        Defined in cuddMatMult.c + +
        +
        +static int 
        +addMultiplicityGroups(
        +  DdManager * dd, manager
        +  MtrNode * treenode, current tree node
        +  int  multiplicity, how many ZDD vars per BDD var
        +  char * vmask, variable pairs for which a group has been already built
        +  char * lmask levels for which a group has already been built
        +)
        +
        +
        Adds multiplicity groups to a ZDD variable group tree. + Returns 1 if successful; 0 otherwise. This function creates the groups + for set of ZDD variables (whose cardinality is given by parameter + multiplicity) that are created for each BDD variable in + Cudd_zddVarsFromBddVars. The crux of the matter is to determine the index + each new group. (The index of the first variable in the group.) + We first build all the groups for the children of a node, and then deal + with the ZDD variables that are directly attached to the node. The problem + for these is that the tree itself does not provide information on their + position inside the group. While we deal with the children of the node, + therefore, we keep track of all the positions they occupy. The remaining + positions in the tree can be freely used. Also, we keep track of all the + variables placed in the children. All the remaining variables are directly + attached to the group. We can then place any pair of variables not yet + grouped in any pair of available positions in the node. +

        + +

        Side Effects Changes the variable group tree. +

        + +

        See Also Cudd_zddVarsFromBddVars + + +
        Defined in cuddAPI.c + +
        +
        +static DdNode * 
        +addTriangleRecur(
        +  DdManager * dd, 
        +  DdNode * f, 
        +  DdNode * g, 
        +  int * vars, 
        +  DdNode * cube 
        +)
        +
        +
        Performs the recursive step of Cudd_addTriangle. Returns + a pointer to the result if successful; NULL otherwise. +

        + +

        Side Effects None +

        + +

        Defined in cuddMatMult.c + +
        +
        +static void 
        +addVarToConst(
        +  DdNode * f, 
        +  DdNode ** gp, 
        +  DdNode ** hp, 
        +  DdNode * one, 
        +  DdNode * zero 
        +)
        +
        +
        Replaces variables with constants if possible (part of + canonical form). +

        + +

        Side Effects None +

        + +

        Defined in cuddAddIte.c + +
        +
        +static DdNode * 
        +addWalshInt(
        +  DdManager * dd, 
        +  DdNode ** x, 
        +  DdNode ** y, 
        +  int  n 
        +)
        +
        +
        Generates a Walsh matrix in ADD form. Returns a pointer + to the matrixi if successful; NULL otherwise. +

        + +

        Side Effects None +

        + +

        Defined in cuddAddWalsh.c + +
        +
        +static int 
        +array_compare(
        +  const char * array1, 
        +  const char * array2 
        +)
        +
        +
        Comparison function for the computed table. Returns 0 if + the two arrays are equal; 1 otherwise. +

        + +

        Side Effects None +

        + +

        Defined in cuddGenetic.c + +
        +
        +static int 
        +array_hash(
        +  char * array, 
        +  int  modulus 
        +)
        +
        +
        Hash function for the computed table. Returns the bucket + number. +

        + +

        Side Effects None +

        + +

        Defined in cuddGenetic.c + +
        +
        +static double 
        +bddAnnotateMintermCount(
        +  DdManager * manager, 
        +  DdNode * node, 
        +  double  max, 
        +  st_table * table 
        +)
        +
        +
        Annotates every node in the BDD node with its minterm count. + In this function, every node and the minterm count represented by it are + stored in a hash table. +

        + +

        Side Effects Fills up 'table' with the pair . +

        + +

        Defined in cuddSplit.c + +
        +
        +static int 
        +bddCheckPositiveCube(
        +  DdManager * manager, 
        +  DdNode * cube 
        +)
        +
        +
        Returns 1 in case of success; 0 otherwise. +

        + +

        Side Effects None +

        + +

        Defined in cuddBddAbs.c + +
        +
        +static double 
        +bddCorrelationAux(
        +  DdManager * dd, 
        +  DdNode * f, 
        +  DdNode * g, 
        +  st_table * table 
        +)
        +
        +
        Performs the recursive step of Cudd_bddCorrelation. + Returns the fraction of minterms in the ON-set of the EXNOR of f and + g. +

        + +

        Side Effects None +

        + +

        See Also bddCorrelationWeightsAux + + +
        Defined in cuddBddCorr.c + +
        +
        +static double 
        +bddCorrelationWeightsAux(
        +  DdManager * dd, 
        +  DdNode * f, 
        +  DdNode * g, 
        +  double * prob, 
        +  st_table * table 
        +)
        +
        +
        Performs the recursive step of Cudd_bddCorrelationWeigths. +

        + +

        Side Effects None +

        + +

        See Also bddCorrelationAux + + +
        Defined in cuddBddCorr.c + +
        +
        +static void 
        +bddFixTree(
        +  DdManager * table, 
        +  MtrNode * treenode 
        +)
        +
        +
        Fixes the BDD variable group tree after a + shuffle. Assumes that the order of the variables in a terminal node + has not been changed. +

        + +

        Side Effects Changes the BDD variable group tree. +

        + +

        Defined in cuddReorder.c + +
        +
        +static int 
        +bddVarToCanonicalSimple(
        +  DdManager * dd, 
        +  DdNode ** fp, 
        +  DdNode ** gp, 
        +  DdNode ** hp, 
        +  unsigned int * topfp, 
        +  unsigned int * topgp, 
        +  unsigned int * tophp 
        +)
        +
        +
        Makes sure the first two pointers are regular. This + mat require the complementation of the result, which is signaled by + returning 1 instead of 0. This function is simpler than the general + case because it assumes that no two arguments are the same or + complementary, and no argument is constant. +

        + +

        Side Effects None +

        + +

        See Also bddVarToConst +bddVarToCanonical + + +
        Defined in cuddBddIte.c + +
        +
        +static int 
        +bddVarToCanonical(
        +  DdManager * dd, 
        +  DdNode ** fp, 
        +  DdNode ** gp, 
        +  DdNode ** hp, 
        +  unsigned int * topfp, 
        +  unsigned int * topgp, 
        +  unsigned int * tophp 
        +)
        +
        +
        Reduces 2 variable expressions to canonical form. +

        + +

        Side Effects None +

        + +

        See Also bddVarToConst +bddVarToCanonicalSimple + + +
        Defined in cuddBddIte.c + +
        +
        +static void 
        +bddVarToConst(
        +  DdNode * f, 
        +  DdNode ** gp, 
        +  DdNode ** hp, 
        +  DdNode * one 
        +)
        +
        +
        This function performs part of the transformation to + standard form by replacing variables with constants if possible. +

        + +

        Side Effects None +

        + +

        See Also bddVarToCanonical +bddVarToCanonicalSimple + + +
        Defined in cuddBddIte.c + +
        +
        +static int 
        +beforep(
        +  DdHalfWord  var1a, 
        +  short  phase1a, 
        +  DdHalfWord  var1b, 
        +  short  phase1b, 
        +  DdHalfWord  var2a, 
        +  short  phase2a, 
        +  DdHalfWord  var2b, 
        +  short  phase2b 
        +)
        +
        +
        Returns true iff the first argument precedes the second + in the clause order. A clause precedes another if its first lieral + precedes the first literal of the other, or if the first literals + are the same, and its second literal precedes the second literal of + the other clause. A literal precedes another if it has a higher + index, of if it has the same index, but it has lower phase. Phase 0 + is the positive phase, and it is lower than Phase 1 (negative + phase). +

        + +

        Side Effects None +

        + +

        See Also equalp + + +
        Defined in cuddEssent.c + +
        +
        +static BitVector * 
        +bitVectorAlloc(
        +  int  size 
        +)
        +
        +
        Allocates a bit vector. The parameter size gives the + number of bits. This procedure allocates enough long's to hold the + specified number of bits. Returns a pointer to the allocated vector + if successful; NULL otherwise. +

        + +

        Side Effects None +

        + +

        See Also bitVectorClear +bitVectorFree + + +
        Defined in cuddEssent.c + +
        +
        +static void 
        +bitVectorFree(
        +  BitVector * vector 
        +)
        +
        +
        Frees a bit vector. +

        + +

        Side Effects None +

        + +

        See Also bitVectorAlloc + + +
        Defined in cuddEssent.c + +
        +
        +static int 
        +build_dd(
        +  DdManager * table, 
        +  int  num, the index of the individual to be built
        +  int  lower, 
        +  int  upper 
        +)
        +
        +
        Builds a DD from a given order. This procedure also + sifts the final order and inserts into the array the size in nodes + of the result. Returns 1 if successful; 0 otherwise. +

        + +

        Side Effects None +

        + +

        Defined in cuddGenetic.c + +
        +
        + 
        +char *þstringþ(
        +    
        +)
        +
        +
        +

        + +

        +
        + 
        +char *þstrþpointer to string to use if != NULL(
        +    
        +)
        +
        +
        +

        + +

        +
        +static int 
        +checkSymmInfo(
        +  DdManager * table, 
        +  DdHalfWord * symmInfo, 
        +  int  index, 
        +  int  level 
        +)
        +
        +
        Returns 1 if a variable is the one with the highest index + among those belonging to a symmetry group that are in the top part of + the BDD. The top part is given by level. +

        + +

        Side Effects None +

        + +

        See Also initSymmInfo + + +
        Defined in cuddExact.c + +
        +
        +static DdTlcInfo * 
        +computeClausesWithUniverse(
        +  DdTlcInfo * Cres, list of clauses for child
        +  DdHalfWord  label, variable labeling the current node
        +  short  phase 0 if E child is zero; 1 if T child is zero
        +)
        +
        +
        Computes the two-literal clauses for a node with a zero + child, given the clauses for its other child and the label of the + node. Returns a pointer to a TclInfo structure if successful; NULL + otherwise. +

        + +

        Side Effects None +

        + +

        See Also computeClauses + + +
        Defined in cuddEssent.c + +
        +
        +static DdTlcInfo * 
        +computeClauses(
        +  DdTlcInfo * Tres, list of clauses for T child
        +  DdTlcInfo * Eres, list of clauses for E child
        +  DdHalfWord  label, variable labeling the current node
        +  int  size number of variables in the manager
        +)
        +
        +
        Computes the two-literal clauses for a node given the + clauses for its children and the label of the node. Returns a + pointer to a TclInfo structure if successful; NULL otherwise. +

        + +

        Side Effects None +

        + +

        See Also computeClausesWithUniverse + + +
        Defined in cuddEssent.c + +
        +
        +static int 
        +computeLB(
        +  DdManager * table, manager
        +  DdHalfWord * order, optimal order for the subset
        +  int  roots, roots between lower and upper
        +  int  cost, minimum cost for the subset
        +  int  lower, lower level to be reordered
        +  int  upper, upper level to be reordered
        +  int  level offset for the current top bottom var
        +)
        +
        +
        Computes a lower bound on the size of a BDD from the + following factors: +
          +
        • size of the lower part of it; +
        • size of the part of the upper part not subjected to reordering; +
        • number of roots in the part of the BDD subjected to reordering; +
        • variable in the support of the roots in the upper part of the + BDD subjected to reordering. +
            +

            + +

            Side Effects None +

            + +

            Defined in cuddExact.c + +
            +
            +static int 
            +computeSavings(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * skip, 
            +  ApproxInfo * info, 
            +  DdLevelQueue * queue 
            +)
            +
            +
            Counts the nodes that would be eliminated if a given + node were replaced by zero. This procedure uses a queue passed by + the caller for efficiency: since the queue is left empty at the + endof the search, it can be reused as is by the next search. Returns + the count (always striclty positive) if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also UAmarkNodes +RAmarkNodes +BAmarkNodes + + +
            Defined in cuddApprox.c + +
            +
            +static void 
            +copyOrder(
            +  DdManager * table, 
            +  int * array, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Copies the current variable order to array. + At the same time inverts the permutation. +

            + +

            Side Effects None +

            + +

            Defined in cuddAnneal.c + +
            +
            +static DdNode * 
            +createResult(
            +  DdManager * dd, 
            +  unsigned int  index, 
            +  unsigned int  phase, 
            +  DdNode * cube, 
            +  CUDD_VALUE_TYPE  distance 
            +)
            +
            +
            Builds a result for cache storage. Returns a pointer + to the resulting ADD if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddBddClosestCube +separateCube + + +
            Defined in cuddPriority.c + +
            +
            +DdNode * 
            +cuddAddApplyRecur(
            +  DdManager * dd, 
            +  DD_AOP  op, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Performs the recursive step of Cudd_addApply. Returns a + pointer to the result if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddAddMonadicApplyRecur + + +
            Defined in cuddAddApply.c + +
            +
            +DdNode * 
            +cuddAddBddDoPattern(
            +  DdManager * dd, 
            +  DdNode * f 
            +)
            +
            +
            Performs the recursive step for Cudd_addBddPattern. Returns a + pointer to the resulting BDD if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddBridge.c + +
            +
            +DdNode * 
            +cuddAddCmplRecur(
            +  DdManager * dd, 
            +  DdNode * f 
            +)
            +
            +
            Performs the recursive step of Cudd_addCmpl. Returns a + pointer to the resulting ADD if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_addCmpl + + +
            Defined in cuddAddIte.c + +
            +
            +DdNode * 
            +cuddAddComposeRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * proj 
            +)
            +
            +
            Performs the recursive step of Cudd_addCompose. + Returns the composed BDD if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_addCompose + + +
            Defined in cuddCompose.c + +
            +
            +DdNode * 
            +cuddAddConstrainRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * c 
            +)
            +
            +
            Performs the recursive step of Cudd_addConstrain. + Returns a pointer to the result if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_addConstrain + + +
            Defined in cuddGenCof.c + +
            +
            +DdNode * 
            +cuddAddExistAbstractRecur(
            +  DdManager * manager, 
            +  DdNode * f, 
            +  DdNode * cube 
            +)
            +
            +
            Performs the recursive step of Cudd_addExistAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddAddAbs.c + +
            +
            +static DdNode * 
            +cuddAddGeneralVectorComposeRecur(
            +  DdManager * dd, DD manager
            +  DdHashTable * table, computed table
            +  DdNode * f, ADD in which to compose
            +  DdNode ** vectorOn, functions to substitute for x_i
            +  DdNode ** vectorOff, functions to substitute for x_i'
            +  int  deepest depth of deepest substitution
            +)
            +
            +
            Performs the recursive step of Cudd_addGeneralVectorCompose. +

            + +

            Side Effects None +

            + +

            Defined in cuddCompose.c + +
            +
            +DdNode * 
            +cuddAddIteRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * h 
            +)
            +
            +
            Implements the recursive step of Cudd_addIte(f,g,h). + Returns a pointer to the resulting ADD if successful; NULL + otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_addIte + + +
            Defined in cuddAddIte.c + +
            +
            +DdNode * 
            +cuddAddMonadicApplyRecur(
            +  DdManager * dd, 
            +  DD_MAOP  op, 
            +  DdNode * f 
            +)
            +
            +
            Performs the recursive step of Cudd_addMonadicApply. Returns a + pointer to the result if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddAddApplyRecur + + +
            Defined in cuddAddApply.c + +
            +
            +DdNode * 
            +cuddAddNegateRecur(
            +  DdManager * dd, 
            +  DdNode * f 
            +)
            +
            +
            Implements the recursive step of Cudd_addNegate. + Returns a pointer to the result. +

            + +

            Side Effects None +

            + +

            Defined in cuddAddNeg.c + +
            +
            +static DdNode * 
            +cuddAddNonSimComposeRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode ** vector, 
            +  DdNode * key, 
            +  DdNode * cube, 
            +  int  lastsub 
            +)
            +
            +
            Performs the recursive step of Cudd_addNonSimCompose. +

            + +

            Side Effects None +

            + +

            Defined in cuddCompose.c + +
            +
            +DdNode * 
            +cuddAddOrAbstractRecur(
            +  DdManager * manager, 
            +  DdNode * f, 
            +  DdNode * cube 
            +)
            +
            +
            Performs the recursive step of Cudd_addOrAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddAddAbs.c + +
            +
            +static DdNode * 
            +cuddAddOuterSumRecur(
            +  DdManager * dd, 
            +  DdNode * M, 
            +  DdNode * r, 
            +  DdNode * c 
            +)
            +
            +
            Performs the recursive step of Cudd_addOuterSum. + Returns a pointer to the result if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddMatMult.c + +
            +
            +static DdNode * 
            +cuddAddPermuteRecur(
            +  DdManager * manager, DD manager
            +  DdHashTable * table, computed table
            +  DdNode * node, ADD to be reordered
            +  int * permut permutation array
            +)
            +
            +
            Recursively puts the ADD in the order given in the + array permut. Checks for trivial cases to terminate recursion, then + splits on the children of this node. Once the solutions for the + children are obtained, it puts into the current position the node + from the rest of the ADD that should be here. Then returns this ADD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper + position is reached in the recursion tree.

            + The DdNode * that is returned is the same ADD as passed in as node, + but in the new order. +

            + +

            Side Effects None +

            + +

            See Also Cudd_addPermute +cuddBddPermuteRecur + + +
            Defined in cuddCompose.c + +
            +
            +DdNode * 
            +cuddAddRestrictRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * c 
            +)
            +
            +
            Performs the recursive step of Cudd_addRestrict. + Returns the restricted ADD if successful; otherwise NULL. +

            + +

            Side Effects None +

            + +

            See Also Cudd_addRestrict + + +
            Defined in cuddGenCof.c + +
            +
            +DdNode * 
            +cuddAddRoundOffRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  double  trunc 
            +)
            +
            +
            Implements the recursive step of Cudd_addRoundOff. + Returns a pointer to the result. +

            + +

            Side Effects None +

            + +

            Defined in cuddAddNeg.c + +
            +
            +DdNode * 
            +cuddAddScalarInverseRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * epsilon 
            +)
            +
            +
            Returns a pointer to the resulting ADD in case of + success. Returns NULL if any discriminants smaller than epsilon is + encountered. +

            + +

            Side Effects None +

            + +

            Defined in cuddAddInv.c + +
            +
            +DdNode * 
            +cuddAddUnivAbstractRecur(
            +  DdManager * manager, 
            +  DdNode * f, 
            +  DdNode * cube 
            +)
            +
            +
            Performs the recursive step of Cudd_addUnivAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddAddAbs.c + +
            +
            +static DdNode * 
            +cuddAddVectorComposeRecur(
            +  DdManager * dd, DD manager
            +  DdHashTable * table, computed table
            +  DdNode * f, ADD in which to compose
            +  DdNode ** vector, functions to substitute
            +  int  deepest depth of deepest substitution
            +)
            +
            +
            Performs the recursive step of Cudd_addVectorCompose. +

            + +

            Side Effects None +

            + +

            Defined in cuddCompose.c + +
            +
            +DdNode * 
            +cuddAllocNode(
            +  DdManager * unique 
            +)
            +
            +
            Fast storage allocation for DdNodes in the table. The + first 4 bytes of a chunk contain a pointer to the next block; the + rest contains DD_MEM_CHUNK spaces for DdNodes. Returns a pointer to + a new node if successful; NULL is memory is full. +

            + +

            Side Effects None +

            + +

            See Also cuddDynamicAllocNode + + +
            Defined in cuddTable.c + +
            +
            +int 
            +cuddAnnealing(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Get x, y by random selection. Choose either + exchange or jump randomly. In case of jump, choose between jump_up + and jump_down randomly. Do exchange or jump and get optimal case. + Loop until there is no improvement or temperature reaches + minimum. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddAnneal.c + +
            +
            +static DdApaNumber 
            +cuddApaCountMintermAux(
            +  DdNode * node, 
            +  int  digits, 
            +  DdApaNumber  max, 
            +  DdApaNumber  min, 
            +  st_table * table 
            +)
            +
            +
            Performs the recursive step of Cudd_ApaCountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. + Uses the identity |f'| = max - |f|. + The procedure expects the argument "node" to be a regular pointer, and + guarantees this condition is met in the recursive calls. + For efficiency, the result of a call is cached only if the node has + a reference count greater than 1. + Returns the number of minterms of the function rooted at node. +

            + +

            Side Effects None +

            + +

            Defined in cuddApa.c + +
            +
            +static enum st_retval 
            +cuddApaStCountfree(
            +  char * key, 
            +  char * value, 
            +  char * arg 
            +)
            +
            +
            Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE. +

            + +

            Side Effects None +

            + +

            Defined in cuddApa.c + +
            +
            +int 
            +cuddBddAlignToZdd(
            +  DdManager * table DD manager
            +)
            +
            +
            Reorders BDD variables according to the order of the + ZDD variables. This function can be called at the end of ZDD + reordering to insure that the order of the BDD variables is + consistent with the order of the ZDD variables. The number of ZDD + variables must be a multiple of the number of BDD variables. Let + M be the ratio of the two numbers. cuddBddAlignToZdd + then considers the ZDD variables from M*i to + (M+1)*i-1 as corresponding to BDD variable + i. This function should be normally called from + Cudd_zddReduceHeap, which clears the cache. Returns 1 in case of + success; 0 otherwise. +

            + +

            Side Effects Changes the BDD variable order for all diagrams and performs + garbage collection of the BDD unique table. +

            + +

            See Also Cudd_ShuffleHeap +Cudd_zddReduceHeap + + +
            Defined in cuddReorder.c + +
            +
            +DdNode * 
            +cuddBddAndAbstractRecur(
            +  DdManager * manager, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * cube 
            +)
            +
            +
            Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddAndAbstract + + +
            Defined in cuddAndAbs.c + +
            +
            +DdNode * 
            +cuddBddAndRecur(
            +  DdManager * manager, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Implements the recursive step of Cudd_bddAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddAnd + + +
            Defined in cuddBddIte.c + +
            +
            +DdNode * 
            +cuddBddBooleanDiffRecur(
            +  DdManager * manager, 
            +  DdNode * f, 
            +  DdNode * var 
            +)
            +
            +
            Performs the recursive steps of Cudd_bddBoleanDiff. + Returns the BDD obtained by XORing the cofactors of f with respect to + var if successful; NULL otherwise. Exploits the fact that dF/dx = + dF'/dx. +

            + +

            Side Effects None +

            + +

            Defined in cuddBddAbs.c + +
            +
            +static DdNode * 
            +cuddBddCharToVect(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * x 
            +)
            +
            +
            Performs the recursive step of Cudd_bddCharToVect. + This function maintains the invariant that f is non-zero. + Returns the i-th component of the vector if successful; otherwise NULL. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddCharToVect + + +
            Defined in cuddGenCof.c + +
            +
            +static DdNode * 
            +cuddBddClipAndAbsRecur(
            +  DdManager * manager, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * cube, 
            +  int  distance, 
            +  int  direction 
            +)
            +
            +
            Approximates the AND of two BDDs and simultaneously + abstracts the variables in cube. The variables are existentially + abstracted. Returns a pointer to the result is successful; NULL + otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddClippingAndAbstract + + +
            Defined in cuddClip.c + +
            +
            +DdNode * 
            +cuddBddClippingAndAbstract(
            +  DdManager * dd, manager
            +  DdNode * f, first conjunct
            +  DdNode * g, second conjunct
            +  DdNode * cube, cube of variables to be abstracted
            +  int  maxDepth, maximum recursion depth
            +  int  direction under (0) or over (1) approximation
            +)
            +
            +
            Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddClippingAndAbstract + + +
            Defined in cuddClip.c + +
            +
            +static DdNode * 
            +cuddBddClippingAndRecur(
            +  DdManager * manager, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  int  distance, 
            +  int  direction 
            +)
            +
            +
            Implements the recursive step of Cudd_bddClippingAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddBddClippingAnd + + +
            Defined in cuddClip.c + +
            +
            +DdNode * 
            +cuddBddClippingAnd(
            +  DdManager * dd, manager
            +  DdNode * f, first conjunct
            +  DdNode * g, second conjunct
            +  int  maxDepth, maximum recursion depth
            +  int  direction under (0) or over (1) approximation
            +)
            +
            +
            Approximates the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddClippingAnd + + +
            Defined in cuddClip.c + +
            +
            +DdNode * 
            +cuddBddClosestCube(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  CUDD_VALUE_TYPE  bound 
            +)
            +
            +
            Performs the recursive step of Cudd_bddClosestCube. + Returns the cube if succesful; NULL otherwise. The procedure uses a + four-way recursion to examine all four combinations of cofactors of + f and g according to the following formula. +
            +    H(f,g) = min(H(ft,gt), H(fe,ge), H(ft,ge)+1, H(fe,gt)+1)
            +  
            + Bounding is based on the following observations. +
              +
            • If we already found two points at distance 0, there is no point in + continuing. Furthermore, +
            • If F == not(G) then the best we can hope for is a minimum distance + of 1. If we have already found two points at distance 1, there is + no point in continuing. (Indeed, H(F,G) == 1 in this case. We + have to continue, though, to find the cube.) +
            + The variable bound is set at the largest value of the distance + that we are still interested in. Therefore, we desist when +
            +    (bound == -1) and (F != not(G)) or (bound == 0) and (F == not(G)).
            +  
            + If we were maximally aggressive in using the bound, we would always + set the bound to the minimum distance seen thus far minus one. That + is, we would maintain the invariant +
            +    bound < minD,
            +  
            + except at the very beginning, when we have no value for + minD.

            + + However, we do not use bound < minD when examining the + two negative cofactors, because we try to find a large cube at + minimum distance. To do so, we try to find a cube in the negative + cofactors at the same or smaller distance from the cube found in the + positive cofactors.

            + + When we compute H(ft,ge) and H(fe,gt) we + know that we are going to add 1 to the result of the recursive call + to account for the difference in the splitting variable. Therefore, + we decrease the bound correspondingly.

            + + Another important observation concerns the need of examining all + four pairs of cofators only when both f and + g depend on the top variable.

            + + Suppose gt == ge == g. (That is, g does + not depend on the top variable.) Then +

            +    H(f,g) = min(H(ft,g), H(fe,g), H(ft,g)+1, H(fe,g)+1)
            +	   = min(H(ft,g), H(fe,g)) .
            +  
            + Therefore, under these circumstances, we skip the two "cross" cases.

            + + An interesting feature of this function is the scheme used for + caching the results in the global computed table. Since we have a + cube and a distance, we combine them to form an ADD. The + combination replaces the zero child of the top node of the cube with + the negative of the distance. (The use of the negative is to avoid + ambiguity with 1.) The degenerate cases (zero and one) are treated + specially because the distance is known (0 for one, and infinity for + zero). +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddClosestCube + + +
            Defined in cuddPriority.c + +
            +
            +DdNode * 
            +cuddBddComposeRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * proj 
            +)
            +
            +
            Performs the recursive step of Cudd_bddCompose. + Exploits the fact that the composition of f' with g + produces the complement of the composition of f with g to better + utilize the cache. Returns the composed BDD if successful; NULL + otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddCompose + + +
            Defined in cuddCompose.c + +
            +
            +static int 
            +cuddBddConstrainDecomp(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode ** decomp 
            +)
            +
            +
            Performs the recursive step of Cudd_bddConstrainDecomp. + Returns f super (i) if successful; otherwise NULL. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddConstrainDecomp + + +
            Defined in cuddGenCof.c + +
            +
            +DdNode * 
            +cuddBddConstrainRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * c 
            +)
            +
            +
            Performs the recursive step of Cudd_bddConstrain. + Returns a pointer to the result if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddConstrain + + +
            Defined in cuddGenCof.c + +
            +
            +DdNode * 
            +cuddBddExistAbstractRecur(
            +  DdManager * manager, 
            +  DdNode * f, 
            +  DdNode * cube 
            +)
            +
            +
            Performs the recursive steps of Cudd_bddExistAbstract. + Returns the BDD obtained by abstracting the variables + of cube from f if successful; NULL otherwise. It is also used by + Cudd_bddUnivAbstract. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddExistAbstract +Cudd_bddUnivAbstract + + +
            Defined in cuddBddAbs.c + +
            +
            +DdNode * 
            +cuddBddIntersectRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Implements the recursive step of Cudd_bddIntersect. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddIntersect + + +
            Defined in cuddBddIte.c + +
            +
            +DdNode	* 
            +cuddBddIsop(
            +  DdManager * dd, 
            +  DdNode * L, 
            +  DdNode * U 
            +)
            +
            +
            Performs the recursive step of Cudd_bddIsop. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddIsop + + +
            Defined in cuddZddIsop.c + +
            +
            +DdNode * 
            +cuddBddIteRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * h 
            +)
            +
            +
            Implements the recursive step of Cudd_bddIte. Returns a + pointer to the resulting BDD. NULL if the intermediate result blows + up or if reordering occurs. +

            + +

            Side Effects None +

            + +

            Defined in cuddBddIte.c + +
            +
            +static DdNode * 
            +cuddBddLICBuildResult(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  st_table * cache, 
            +  st_table * table 
            +)
            +
            +
            Builds the results of Cudd_bddLICompaction. + Returns a pointer to the minimized BDD if successful; otherwise NULL. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddLICompaction +cuddBddLICMarkEdges + + +
            Defined in cuddGenCof.c + +
            +
            +static int 
            +cuddBddLICMarkEdges(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * c, 
            +  st_table * table, 
            +  st_table * cache 
            +)
            +
            +
            Performs the edge marking step of Cudd_bddLICompaction. + Returns the LUB of the markings of the two outgoing edges of f + if successful; otherwise CUDD_OUT_OF_MEM. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddLICompaction +cuddBddLICBuildResult + + +
            Defined in cuddGenCof.c + +
            +
            +DdNode * 
            +cuddBddLICompaction(
            +  DdManager * dd, manager
            +  DdNode * f, function to be minimized
            +  DdNode * c constraint (care set)
            +)
            +
            +
            Performs safe minimization of a BDD. Given the BDD + f of a function to be minimized and a BDD + c representing the care set, Cudd_bddLICompaction + produces the BDD of a function that agrees with f + wherever c is 1. Safe minimization means that the size + of the result is guaranteed not to exceed the size of + f. This function is based on the DAC97 paper by Hong et + al.. Returns a pointer to the result if successful; NULL + otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddLICompaction + + +
            Defined in cuddGenCof.c + +
            +
            +DdNode * 
            +cuddBddLiteralSetIntersectionRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Performs the recursive step of + Cudd_bddLiteralSetIntersection. Scans the cubes for common variables, + and checks whether they agree in phase. Returns a pointer to the + resulting cube if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddLiteral.c + +
            +
            +DdNode * 
            +cuddBddMakePrime(
            +  DdManager * dd, manager
            +  DdNode * cube, cube to be expanded
            +  DdNode * f function of which the cube is to be made a prime
            +)
            +
            +
            Performs the recursive step of Cudd_bddMakePrime. + Returns the prime if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddSat.c + +
            +
            +DdNode * 
            +cuddBddNPAndRecur(
            +  DdManager * manager, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Implements the recursive step of Cudd_bddNPAnd. + Returns a pointer to the result is successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddNPAnd + + +
            Defined in cuddGenCof.c + +
            +
            +static DdNode * 
            +cuddBddPermuteRecur(
            +  DdManager * manager, DD manager
            +  DdHashTable * table, computed table
            +  DdNode * node, BDD to be reordered
            +  int * permut permutation array
            +)
            +
            +
            Recursively puts the BDD in the order given in the array permut. + Checks for trivial cases to terminate recursion, then splits on the + children of this node. Once the solutions for the children are + obtained, it puts into the current position the node from the rest of + the BDD that should be here. Then returns this BDD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper position + is reached in the recursion tree.

            + The DdNode * that is returned is the same BDD as passed in as node, + but in the new order. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddPermute +cuddAddPermuteRecur + + +
            Defined in cuddCompose.c + +
            +
            +DdNode * 
            +cuddBddRestrictRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * c 
            +)
            +
            +
            Performs the recursive step of Cudd_bddRestrict. + Returns the restricted BDD if successful; otherwise NULL. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddRestrict + + +
            Defined in cuddGenCof.c + +
            +
            +static DdNode * 
            +cuddBddSqueeze(
            +  DdManager * dd, 
            +  DdNode * l, 
            +  DdNode * u 
            +)
            +
            +
            Performs the recursive step of Cudd_bddSqueeze. This + procedure exploits the fact that if we complement and swap the + bounds of the interval we obtain a valid solution by taking the + complement of the solution to the original problem. Therefore, we + can enforce the condition that the upper bound is always regular. + Returns a pointer to the result if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddSqueeze + + +
            Defined in cuddGenCof.c + +
            +
            +static DdNode * 
            +cuddBddTransferRecur(
            +  DdManager * ddS, 
            +  DdManager * ddD, 
            +  DdNode * f, 
            +  st_table * table 
            +)
            +
            +
            Performs the recursive step of Cudd_bddTransfer. + Returns a pointer to the result if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddBddTransfer + + +
            Defined in cuddBridge.c + +
            +
            +DdNode * 
            +cuddBddTransfer(
            +  DdManager * ddS, 
            +  DdManager * ddD, 
            +  DdNode * f 
            +)
            +
            +
            Convert a BDD from a manager to another one. Returns a + pointer to the BDD in the destination manager if successful; NULL + otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddTransfer + + +
            Defined in cuddBridge.c + +
            +
            +static DdNode * 
            +cuddBddVarMapRecur(
            +  DdManager * manager, DD manager
            +  DdNode * f BDD to be remapped
            +)
            +
            +
            Implements the recursive step of Cudd_bddVarMap. + Returns a pointer to the result if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddVarMap + + +
            Defined in cuddCompose.c + +
            +
            +static DdNode * 
            +cuddBddVectorComposeRecur(
            +  DdManager * dd, DD manager
            +  DdHashTable * table, computed table
            +  DdNode * f, BDD in which to compose
            +  DdNode ** vector, functions to be composed
            +  int  deepest depth of the deepest substitution
            +)
            +
            +
            Performs the recursive step of Cudd_bddVectorCompose. +

            + +

            Side Effects None +

            + +

            Defined in cuddCompose.c + +
            +
            +DdNode * 
            +cuddBddXorExistAbstractRecur(
            +  DdManager * manager, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * cube 
            +)
            +
            +
            Takes the exclusive OR of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddAndAbstract + + +
            Defined in cuddBddAbs.c + +
            +
            +DdNode * 
            +cuddBddXorRecur(
            +  DdManager * manager, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Implements the recursive step of Cudd_bddXor by taking + the exclusive OR of two BDDs. Returns a pointer to the result is + successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_bddXor + + +
            Defined in cuddBddIte.c + +
            +
            +DdNode * 
            +cuddBiasedUnderApprox(
            +  DdManager * dd, DD manager
            +  DdNode * f, current DD
            +  DdNode * b, bias function
            +  int  numVars, maximum number of variables
            +  int  threshold, threshold under which approximation stops
            +  double  quality1, minimum improvement for accepted changes when b=1
            +  double  quality0 minimum improvement for accepted changes when b=0
            +)
            +
            +
            Applies the biased remapping underappoximation algorithm. + Proceeds in three phases: +
              +
            • collect information on each node in the BDD; this is done via DFS. +
            • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
            • traverse the BDD via DFS and actually perform the elimination. +
            + Returns the approximated BDD if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_BiasedUnderApprox + + +
            Defined in cuddApprox.c + +
            +
            +DdNode * 
            +cuddCProjectionRecur(
            +  DdManager * dd, 
            +  DdNode * R, 
            +  DdNode * Y, 
            +  DdNode * Ysupp 
            +)
            +
            +
            Performs the recursive step of Cudd_CProjection. Returns + the projection if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_CProjection + + +
            Defined in cuddPriority.c + +
            +
            +void 
            +cuddCacheFlush(
            +  DdManager * table 
            +)
            +
            +
            Flushes the cache. +

            + +

            Side Effects None +

            + +

            Defined in cuddCache.c + +
            +
            +void 
            +cuddCacheInsert1(
            +  DdManager * table, 
            +  DD_CTFP1  op, 
            +  DdNode * f, 
            +  DdNode * data 
            +)
            +
            +
            Inserts a result in the cache for a function with two + operands. +

            + +

            Side Effects None +

            + +

            See Also cuddCacheInsert +cuddCacheInsert2 + + +
            Defined in cuddCache.c + +
            +
            +void 
            +cuddCacheInsert2(
            +  DdManager * table, 
            +  DD_CTFP  op, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * data 
            +)
            +
            +
            Inserts a result in the cache for a function with two + operands. +

            + +

            Side Effects None +

            + +

            See Also cuddCacheInsert +cuddCacheInsert1 + + +
            Defined in cuddCache.c + +
            +
            +void 
            +cuddCacheInsert(
            +  DdManager * table, 
            +  ptruint  op, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * h, 
            +  DdNode * data 
            +)
            +
            +
            Inserts a result in the cache for a function with three + operands. The operator tag (see cuddInt.h for details) is split and stored + into unused bits of the first two pointers. +

            + +

            Side Effects None +

            + +

            See Also cuddCacheInsert2 +cuddCacheInsert1 + + +
            Defined in cuddCache.c + +
            +
            +DdNode * 
            +cuddCacheLookup1Zdd(
            +  DdManager * table, 
            +  DD_CTFP1  op, 
            +  DdNode * f 
            +)
            +
            +
            Returns the result if found; it returns NULL if no + result is found. +

            + +

            Side Effects None +

            + +

            See Also cuddCacheLookupZdd +cuddCacheLookup2Zdd + + +
            Defined in cuddCache.c + +
            +
            +DdNode * 
            +cuddCacheLookup1(
            +  DdManager * table, 
            +  DD_CTFP1  op, 
            +  DdNode * f 
            +)
            +
            +
            Returns the result if found; it returns NULL if no + result is found. +

            + +

            Side Effects None +

            + +

            See Also cuddCacheLookup +cuddCacheLookup2 + + +
            Defined in cuddCache.c + +
            +
            +DdNode * 
            +cuddCacheLookup2Zdd(
            +  DdManager * table, 
            +  DD_CTFP  op, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Returns the result if found; it returns NULL if no + result is found. +

            + +

            Side Effects None +

            + +

            See Also cuddCacheLookupZdd +cuddCacheLookup1Zdd + + +
            Defined in cuddCache.c + +
            +
            +DdNode * 
            +cuddCacheLookup2(
            +  DdManager * table, 
            +  DD_CTFP  op, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Returns the result if found; it returns NULL if no + result is found. +

            + +

            Side Effects None +

            + +

            See Also cuddCacheLookup +cuddCacheLookup1 + + +
            Defined in cuddCache.c + +
            +
            +DdNode * 
            +cuddCacheLookupZdd(
            +  DdManager * table, 
            +  ptruint  op, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * h 
            +)
            +
            +
            Returns the result if found; it returns NULL if no + result is found. +

            + +

            Side Effects None +

            + +

            See Also cuddCacheLookup2Zdd +cuddCacheLookup1Zdd + + +
            Defined in cuddCache.c + +
            +
            +DdNode * 
            +cuddCacheLookup(
            +  DdManager * table, 
            +  ptruint  op, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * h 
            +)
            +
            +
            Returns the result if found; it returns NULL if no + result is found. +

            + +

            Side Effects None +

            + +

            See Also cuddCacheLookup2 +cuddCacheLookup1 + + +
            Defined in cuddCache.c + +
            +
            +int 
            +cuddCacheProfile(
            +  DdManager * table, 
            +  FILE * fp 
            +)
            +
            +
            Computes and prints a profile of the cache usage. + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddCache.c + +
            +
            +void 
            +cuddCacheResize(
            +  DdManager * table 
            +)
            +
            +
            Resizes the cache. +

            + +

            Side Effects None +

            + +

            Defined in cuddCache.c + +
            +
            +static int 
            +cuddCheckCollisionOrdering(
            +  DdManager * unique, 
            +  int  i, 
            +  int  j 
            +)
            +
            +
            Checks whether a collision list is ordered. +

            + +

            Side Effects None +

            + +

            Defined in cuddTable.c + +
            +
            +void 
            +cuddClearDeathRow(
            +  DdManager * table 
            +)
            +
            +
            Clears the death row. +

            + +

            Side Effects None +

            + +

            See Also Cudd_DelayedDerefBdd +Cudd_IterDerefBdd +Cudd_CheckZeroRef +cuddGarbageCollect + + +
            Defined in cuddRef.c + +
            +
            +DdNode * 
            +cuddCofactorRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Performs the recursive step of Cudd_Cofactor. Returns a + pointer to the cofactor if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_Cofactor + + +
            Defined in cuddCof.c + +
            +
            +int 
            +cuddCollectNodes(
            +  DdNode * f, 
            +  st_table * visited 
            +)
            +
            +
            Traverses the DD f and collects all its nodes in a + symbol table. f is assumed to be a regular pointer and + cuddCollectNodes guarantees this assumption in the recursive calls. + Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +int 
            +cuddComputeFloorLog2(
            +  unsigned int  value 
            +)
            +
            +
            Returns the floor of the logarithm to the base 2. + The input value is assumed to be greater than 0. +

            + +

            Side Effects None +

            + +

            Defined in cuddCache.c + +
            +
            +static int 
            +cuddConjunctsAux(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode ** c1, 
            +  DdNode ** c2 
            +)
            +
            +
            Procedure to compute two conjunctive factors of f and + place in *c1 and *c2. Sets up the required data - table of distances + from the constant and local reference count. Also minterm table. +

            + +

            Defined in cuddDecomp.c + +
            +
            +DdNode * 
            +cuddConstantLookup(
            +  DdManager * table, 
            +  ptruint  op, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * h 
            +)
            +
            +
            Looks up in the cache for the result of op applied to f, + g, and h. Assumes that the calling procedure (e.g., + Cudd_bddIteConstant) is only interested in whether the result is + constant or not. Returns the result if found (possibly + DD_NON_CONSTANT); otherwise it returns NULL. +

            + +

            Side Effects None +

            + +

            See Also cuddCacheLookup + + +
            Defined in cuddCache.c + +
            +
            +int 
            +cuddDestroySubtables(
            +  DdManager * unique, 
            +  int  n 
            +)
            +
            +
            Destroys the n most recently created subtables in a unique + table. n should be positive. The subtables should not contain any live + nodes, except the (isolated) projection function. The projection + functions are freed. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects The variable map used for fast variable substitution is + destroyed if it exists. In this case the cache is also cleared. +

            + +

            See Also cuddInsertSubtables +Cudd_SetVarMap + + +
            Defined in cuddTable.c + +
            +
            +static void 
            +cuddDoRebalance(
            +  DdNodePtr ** stack, 
            +  int  stackN 
            +)
            +
            +
            Rebalances a red/black tree. +

            + +

            Side Effects None +

            + +

            Defined in cuddTable.c + +
            +
            +DdNode * 
            +cuddDynamicAllocNode(
            +  DdManager * table 
            +)
            +
            +
            Dynamically allocates a Node. This procedure is similar + to cuddAllocNode in Cudd_Table.c, but it does not attempt garbage + collection, because during reordering there are no dead nodes. + Returns a pointer to a new node if successful; NULL is memory is + full. +

            + +

            Side Effects None +

            + +

            See Also cuddAllocNode + + +
            Defined in cuddReorder.c + +
            +
            +static int 
            +cuddEstimateCofactorSimple(
            +  DdNode * node, 
            +  int  i 
            +)
            +
            +
            Performs the recursive step of Cudd_CofactorEstimateSimple. + Returns an estimate of the number of nodes in the DD of the positive + cofactor of node. Uses the least significant bit of the next field as + visited flag. node is supposed to be regular; the invariant is maintained + by this procedure. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +static int 
            +cuddEstimateCofactor(
            +  DdManager * dd, 
            +  st_table * table, 
            +  DdNode * node, 
            +  int  i, 
            +  int  phase, 
            +  DdNode ** ptr 
            +)
            +
            +
            Performs the recursive step of Cudd_CofactorEstimate. + Returns an estimate of the number of nodes in the DD of a + cofactor of node. Uses the least significant bit of the next field as + visited flag. node is supposed to be regular; the invariant is maintained + by this procedure. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +int 
            +cuddExact(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Exact variable ordering algorithm. Finds an optimum + order for the variables between lower and upper. Returns 1 if + successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddExact.c + +
            +
            +static int 
            +cuddFindParent(
            +  DdManager * table, 
            +  DdNode * node 
            +)
            +
            +
            Searches the subtables above node for a parent. Returns 1 + as soon as one parent is found. Returns 0 is the search is fruitless. +

            + +

            Side Effects None +

            + +

            Defined in cuddTable.c + +
            +
            +void 
            +cuddFreeTable(
            +  DdManager * unique 
            +)
            +
            +
            Frees the resources associated to a unique table. +

            + +

            Side Effects None +

            + +

            See Also cuddInitTable + + +
            Defined in cuddTable.c + +
            +
            +int 
            +cuddGarbageCollect(
            +  DdManager * unique, 
            +  int  clearCache 
            +)
            +
            +
            Performs garbage collection on the BDD and ZDD unique tables. + If clearCache is 0, the cache is not cleared. This should only be + specified if the cache has been cleared right before calling + cuddGarbageCollect. (As in the case of dynamic reordering.) + Returns the total number of deleted nodes. +

            + +

            Side Effects None +

            + +

            Defined in cuddTable.c + +
            +
            +int 
            +cuddGa(
            +  DdManager * table, manager
            +  int  lower, lowest level to be reordered
            +  int  upper highest level to be reorderded
            +)
            +
            +
            Genetic algorithm for DD reordering. + The two children of a crossover will be stored in + storedd[popsize +

            + +

            Side Effects None +

            + +

            Defined in cuddGenetic.c + +
            +
            +void 
            +cuddGetBranches(
            +  DdNode * g, 
            +  DdNode ** g1, 
            +  DdNode ** g0 
            +)
            +
            +
            Computes the children of g. +

            + +

            Side Effects None +

            + +

            Defined in cuddCof.c + +
            +
            +int 
            +cuddHashTableGenericInsert(
            +  DdHashTable * hash, 
            +  DdNode * f, 
            +  void * value 
            +)
            +
            +
            Inserts an item in a hash table when the key is one + pointer and the value is not a DdNode pointer. Returns 1 if + successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddHashTableInsert1 +cuddHashTableGenericLookup + + +
            Defined in cuddLCache.c + +
            +
            +void * 
            +cuddHashTableGenericLookup(
            +  DdHashTable * hash, 
            +  DdNode * f 
            +)
            +
            +
            Looks up a key consisting of one pointer in a hash + table when the value is not a DdNode pointer. Returns the value + associated to the key if there is an entry for the given key in the + table; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddHashTableLookup1 +cuddHashTableGenericInsert + + +
            Defined in cuddLCache.c + +
            +
            +void 
            +cuddHashTableGenericQuit(
            +  DdHashTable * hash 
            +)
            +
            +
            Shuts down a hash table, when the values are not DdNode + pointers. +

            + +

            Side Effects None +

            + +

            See Also cuddHashTableInit + + +
            Defined in cuddLCache.c + +
            +
            +DdHashTable * 
            +cuddHashTableInit(
            +  DdManager * manager, 
            +  unsigned int  keySize, 
            +  unsigned int  initSize 
            +)
            +
            +
            Initializes a hash table. Returns a pointer to the new + table if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddHashTableQuit + + +
            Defined in cuddLCache.c + +
            +
            +int 
            +cuddHashTableInsert1(
            +  DdHashTable * hash, 
            +  DdNode * f, 
            +  DdNode * value, 
            +  ptrint  count 
            +)
            +
            +
            Inserts an item in a hash table when the key is one pointer. + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddHashTableInsert +cuddHashTableInsert2 +cuddHashTableInsert3 +cuddHashTableLookup1 + + +
            Defined in cuddLCache.c + +
            +
            +int 
            +cuddHashTableInsert2(
            +  DdHashTable * hash, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * value, 
            +  ptrint  count 
            +)
            +
            +
            Inserts an item in a hash table when the key is + composed of two pointers. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddHashTableInsert +cuddHashTableInsert1 +cuddHashTableInsert3 +cuddHashTableLookup2 + + +
            Defined in cuddLCache.c + +
            +
            +int 
            +cuddHashTableInsert3(
            +  DdHashTable * hash, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * h, 
            +  DdNode * value, 
            +  ptrint  count 
            +)
            +
            +
            Inserts an item in a hash table when the key is + composed of three pointers. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddHashTableInsert +cuddHashTableInsert1 +cuddHashTableInsert2 +cuddHashTableLookup3 + + +
            Defined in cuddLCache.c + +
            +
            +int 
            +cuddHashTableInsert(
            +  DdHashTable * hash, 
            +  DdNodePtr * key, 
            +  DdNode * value, 
            +  ptrint  count 
            +)
            +
            +
            Inserts an item in a hash table when the key has more than + three pointers. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also [cuddHashTableInsert1 +cuddHashTableInsert2 +cuddHashTableInsert3 +cuddHashTableLookup + + +
            Defined in cuddLCache.c + +
            +
            +DdNode * 
            +cuddHashTableLookup1(
            +  DdHashTable * hash, 
            +  DdNode * f 
            +)
            +
            +
            Looks up a key consisting of one pointer in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list. +

            + +

            Side Effects None +

            + +

            See Also cuddHashTableLookup +cuddHashTableLookup2 +cuddHashTableLookup3 +cuddHashTableInsert1 + + +
            Defined in cuddLCache.c + +
            +
            +DdNode * 
            +cuddHashTableLookup2(
            +  DdHashTable * hash, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Looks up a key consisting of two pointer in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list. +

            + +

            Side Effects None +

            + +

            See Also cuddHashTableLookup +cuddHashTableLookup1 +cuddHashTableLookup3 +cuddHashTableInsert2 + + +
            Defined in cuddLCache.c + +
            +
            +DdNode * 
            +cuddHashTableLookup3(
            +  DdHashTable * hash, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * h 
            +)
            +
            +
            Looks up a key consisting of three pointers in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list. +

            + +

            Side Effects None +

            + +

            See Also cuddHashTableLookup +cuddHashTableLookup1 +cuddHashTableLookup2 +cuddHashTableInsert3 + + +
            Defined in cuddLCache.c + +
            +
            +DdNode * 
            +cuddHashTableLookup(
            +  DdHashTable * hash, 
            +  DdNodePtr * key 
            +)
            +
            +
            Looks up a key consisting of more than three pointers + in a hash table. Returns the value associated to the key if there + is an entry for the given key in the table; NULL otherwise. If the + entry is present, its reference counter is decremented if not + saturated. If the counter reaches 0, the value of the entry is + dereferenced, and the entry is returned to the free list. +

            + +

            Side Effects None +

            + +

            See Also cuddHashTableLookup1 +cuddHashTableLookup2 +cuddHashTableLookup3 +cuddHashTableInsert + + +
            Defined in cuddLCache.c + +
            +
            +void 
            +cuddHashTableQuit(
            +  DdHashTable * hash 
            +)
            +
            +
            Shuts down a hash table, dereferencing all the values. +

            + +

            Side Effects None +

            + +

            See Also cuddHashTableInit + + +
            Defined in cuddLCache.c + +
            +
            +static int 
            +cuddHashTableResize(
            +  DdHashTable * hash 
            +)
            +
            +
            Resizes a hash table. Returns 1 if successful; 0 + otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddHashTableInsert + + +
            Defined in cuddLCache.c + +
            +
            +int 
            +cuddHeapProfile(
            +  DdManager * dd 
            +)
            +
            +
            Prints to the manager's stdout the number of live nodes for each + level of the DD heap that contains at least one live node. It also + prints a summary containing: +
              +
            • total number of tables; +
            • number of tables with live nodes; +
            • table with the largest number of live nodes; +
            • number of nodes in that table. +
            + If more than one table contains the maximum number of live nodes, + only the one of lowest index is reported. Returns 1 in case of success + and 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddCheck.c + +
            +
            +int 
            +cuddInitCache(
            +  DdManager * unique, unique table
            +  unsigned int  cacheSize, initial size of the cache
            +  unsigned int  maxCacheSize cache size beyond which no resizing occurs
            +)
            +
            +
            Initializes the computed table. It is called by + Cudd_Init. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_Init + + +
            Defined in cuddCache.c + +
            +
            +int 
            +cuddInitInteract(
            +  DdManager * table 
            +)
            +
            +
            Initializes the interaction matrix. The interaction + matrix is implemented as a bit vector storing the upper triangle of + the symmetric interaction matrix. The bit vector is kept in an array + of long integers. The computation is based on a series of depth-first + searches, one for each root of the DAG. Two flags are needed: The + local visited flag uses the LSB of the then pointer. The global + visited flag uses the LSB of the next pointer. + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddInteract.c + +
            +
            +int 
            +cuddInitLinear(
            +  DdManager * table 
            +)
            +
            +
            Initializes the linear transform matrix. Returns 1 if + successful; 0 otherwise. +

            + +

            Side Effects none +

            + +

            Defined in cuddLinear.c + +
            +
            +DdManager * 
            +cuddInitTable(
            +  unsigned int  numVars, Initial number of BDD variables (and subtables)
            +  unsigned int  numVarsZ, Initial number of ZDD variables (and subtables)
            +  unsigned int  numSlots, Initial size of the BDD subtables
            +  unsigned int  looseUpTo Limit for fast table growth
            +)
            +
            +
            Creates and initializes the unique table. Returns a pointer + to the table if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_Init +cuddFreeTable + + +
            Defined in cuddTable.c + +
            +
            +int 
            +cuddInsertSubtables(
            +  DdManager * unique, 
            +  int  n, 
            +  int  level 
            +)
            +
            +
            Inserts n new subtables in a unique table at level. + The number n should be positive, and level should be an existing level. + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddDestroySubtables + + +
            Defined in cuddTable.c + +
            +
            +int 
            +cuddIsInDeathRow(
            +  DdManager * dd, 
            +  DdNode * f 
            +)
            +
            +
            Checks whether a node is in the death row. Returns the + position of the first occurrence if the node is present; -1 + otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_DelayedDerefBdd +cuddClearDeathRow + + +
            Defined in cuddRef.c + +
            +
            +void 
            +cuddLevelQueueDequeue(
            +  DdLevelQueue * queue, 
            +  int  level 
            +)
            +
            +
            Remove an item from the front of a level queue. +

            + +

            Side Effects None +

            + +

            See Also cuddLevelQueueEnqueue + + +
            Defined in cuddLevelQ.c + +
            +
            +void * 
            +cuddLevelQueueEnqueue(
            +  DdLevelQueue * queue, level queue
            +  void * key, key to be enqueued
            +  int  level level at which to insert
            +)
            +
            +
            Inserts a new key in a level queue. A new entry is + created in the queue only if the node is not already + enqueued. Returns a pointer to the queue item if successful; NULL + otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddLevelQueueInit +cuddLevelQueueDequeue + + +
            Defined in cuddLevelQ.c + +
            +
            +void * 
            +cuddLevelQueueFirst(
            +  DdLevelQueue * queue, level queue
            +  void * key, key to be enqueued
            +  int  level level at which to insert
            +)
            +
            +
            Inserts the first key in a level queue. Returns a + pointer to the queue item if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddLevelQueueEnqueue + + +
            Defined in cuddLevelQ.c + +
            +
            +DdLevelQueue * 
            +cuddLevelQueueInit(
            +  int  levels, number of levels
            +  int  itemSize, size of the item
            +  int  numBuckets initial number of hash buckets
            +)
            +
            +
            Initializes a level queue. A level queue is a queue + where inserts are based on the levels of the nodes. Within each + level the policy is FIFO. Level queues are useful in traversing a + BDD top-down. Queue items are kept in a free list when dequeued for + efficiency. Returns a pointer to the new queue if successful; NULL + otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddLevelQueueQuit +cuddLevelQueueEnqueue +cuddLevelQueueDequeue + + +
            Defined in cuddLevelQ.c + +
            +
            +void 
            +cuddLevelQueueQuit(
            +  DdLevelQueue * queue 
            +)
            +
            +
            Shuts down a level queue and releases all the + associated memory. +

            + +

            Side Effects None +

            + +

            See Also cuddLevelQueueInit + + +
            Defined in cuddLevelQ.c + +
            +
            +int 
            +cuddLinearAndSifting(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            BDD reduction based on combination of sifting and linear + transformations. Assumes that no dead nodes are present. +
              +
            1. Order all the variables according to the number of entries + in each unique table. +
            2. Sift the variable up and down, remembering each time the + total size of the DD heap. At each position, linear transformation + of the two adjacent variables is tried and is accepted if it reduces + the size of the DD. +
            3. Select the best permutation. +
            4. Repeat 3 and 4 for all variables. +
            + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddLinear.c + +
            +
            +int 
            +cuddLinearInPlace(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Linearly combines two adjacent variables. Specifically, + replaces the top variable with the exclusive nor of the two variables. + It assumes that no dead nodes are present on entry to this + procedure. The procedure then guarantees that no dead nodes will be + present when it terminates. cuddLinearInPlace assumes that x < + y. Returns the number of keys in the table if successful; 0 + otherwise. +

            + +

            Side Effects The two subtables corrresponding to variables x and y are + modified. The global counters of the unique table are also affected. +

            + +

            See Also cuddSwapInPlace + + +
            Defined in cuddLinear.c + +
            +
            +static void 
            +cuddLocalCacheAddToList(
            +  DdLocalCache * cache 
            +)
            +
            +
            Inserts a local cache in the manager list. +

            + +

            Side Effects None +

            + +

            Defined in cuddLCache.c + +
            +
            +void 
            +cuddLocalCacheClearAll(
            +  DdManager * manager 
            +)
            +
            +
            Clears the local caches of a manager. + Used before reordering. +

            + +

            Side Effects None +

            + +

            Defined in cuddLCache.c + +
            +
            +void 
            +cuddLocalCacheClearDead(
            +  DdManager * manager 
            +)
            +
            +
            Clears the dead entries of the local caches of a manager. + Used during garbage collection. +

            + +

            Side Effects None +

            + +

            Defined in cuddLCache.c + +
            +
            +DdLocalCache * 
            +cuddLocalCacheInit(
            +  DdManager * manager, manager
            +  unsigned int  keySize, size of the key (number of operands)
            +  unsigned int  cacheSize, Initial size of the cache
            +  unsigned int  maxCacheSize Size of the cache beyond which no resizing occurs
            +)
            +
            +
            Initializes a computed table. Returns a pointer the + the new local cache in case of success; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddInitCache + + +
            Defined in cuddLCache.c + +
            +
            +void 
            +cuddLocalCacheInsert(
            +  DdLocalCache * cache, 
            +  DdNodePtr * key, 
            +  DdNode * value 
            +)
            +
            +
            Inserts a result in a local cache. +

            + +

            Side Effects None +

            + +

            Defined in cuddLCache.c + +
            +
            +DdNode * 
            +cuddLocalCacheLookup(
            +  DdLocalCache * cache, 
            +  DdNodePtr * key 
            +)
            +
            +
            Looks up in a local cache. Returns the result if found; + it returns NULL if no result is found. +

            + +

            Side Effects None +

            + +

            Defined in cuddLCache.c + +
            +
            +int 
            +cuddLocalCacheProfile(
            +  DdLocalCache * cache 
            +)
            +
            +
            Computes and prints a profile of a local cache usage. + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddLCache.c + +
            +
            +void 
            +cuddLocalCacheQuit(
            +  DdLocalCache * cache cache to be shut down
            +)
            +
            +
            Initializes the computed table. It is called by + Cudd_Init. Returns a pointer the the new local cache in case of + success; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddLocalCacheInit + + +
            Defined in cuddLCache.c + +
            +
            +static void 
            +cuddLocalCacheRemoveFromList(
            +  DdLocalCache * cache 
            +)
            +
            +
            Removes a local cache from the manager list. +

            + +

            Side Effects None +

            + +

            Defined in cuddLCache.c + +
            +
            +static void 
            +cuddLocalCacheResize(
            +  DdLocalCache * cache 
            +)
            +
            +
            Resizes a local cache. +

            + +

            Side Effects None +

            + +

            Defined in cuddLCache.c + +
            +
            +DdNode	* 
            +cuddMakeBddFromZddCover(
            +  DdManager * dd, 
            +  DdNode * node 
            +)
            +
            +
            Converts a ZDD cover to a BDD. If successful, it returns + a BDD node, otherwise it returns NULL. It is a recursive algorithm + that works as follows. First it computes 3 cofactors of a ZDD cover: + f1, f0 and fd. Second, it compute BDDs (b1, b0 and bd) of f1, f0 and fd. + Third, it computes T=b1+bd and E=b0+bd. Fourth, it computes ITE(v,T,E) where + v is the variable which has the index of the top node of the ZDD cover. + In this case, since the index of v can be larger than either the one of T + or the one of E, cuddUniqueInterIVO is called, where IVO stands for + independent from variable ordering. +

            + +

            See Also Cudd_MakeBddFromZddCover + + +
            Defined in cuddZddIsop.c + +
            +
            +static int 
            +cuddMinHammingDistRecur(
            +  DdNode * f, 
            +  int * minterm, 
            +  DdHashTable * table, 
            +  int  upperBound 
            +)
            +
            +
            Performs the recursive step of Cudd_MinHammingDist. + It is based on the following identity. Let H(f) be the + minimum Hamming distance of the minterms of f from the reference + minterm. Then: + + H(f) = min(H(f0)+h0,H(f1)+h1) + + where f0 and f1 are the two cofactors of f with respect to its top + variable; h0 is 1 if the minterm assigns 1 to the top variable of f; + h1 is 1 if the minterm assigns 0 to the top variable of f. + The upper bound on the distance is used to bound the depth of the + recursion. + Returns the minimum distance unless it exceeds the upper bound or + computation fails. +

            + +

            Side Effects None +

            + +

            See Also Cudd_MinHammingDist + + +
            Defined in cuddPriority.c + +
            +
            +int 
            +cuddNextHigh(
            +  DdManager * table, 
            +  int  x 
            +)
            +
            +
            Finds the next subtable with a larger index. Returns the + index. +

            + +

            Side Effects None +

            + +

            See Also cuddNextLow + + +
            Defined in cuddReorder.c + +
            +
            +int 
            +cuddNextLow(
            +  DdManager * table, 
            +  int  x 
            +)
            +
            +
            Finds the next subtable with a smaller index. Returns the + index. +

            + +

            Side Effects None +

            + +

            See Also cuddNextHigh + + +
            Defined in cuddReorder.c + +
            +
            +static int 
            +cuddNodeArrayRecur(
            +  DdNode * f, 
            +  DdNodePtr * table, 
            +  int  index 
            +)
            +
            +
            Performs the recursive step of cuddNodeArray. Returns + an the number of nodes in the DD. Clear the least significant bit + of the next field that was used as visited flag by + cuddNodeArrayRecur when counting the nodes. node is supposed to be + regular; the invariant is maintained by this procedure. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +DdNodePtr * 
            +cuddNodeArray(
            +  DdNode * f, 
            +  int * n 
            +)
            +
            +
            Traverses the DD f and collects all its nodes in an array. + The caller should free the array returned by cuddNodeArray. + Returns a pointer to the array of nodes in case of success; NULL + otherwise. The nodes are collected in reverse topological order, so + that a node is always preceded in the array by all its descendants. +

            + +

            Side Effects The number of nodes is returned as a side effect. +

            + +

            See Also Cudd_FirstNode + + +
            Defined in cuddUtil.c + +
            +
            +static void 
            +cuddOrderedInsert(
            +  DdNodePtr * root, 
            +  DdNodePtr  node 
            +)
            +
            +
            Inserts a DdNode in a red/black search tree. Nodes from + the same "page" (defined by DD_PAGE_MASK) are linked in a LIFO list. +

            + +

            Side Effects None +

            + +

            See Also cuddOrderedThread + + +
            Defined in cuddTable.c + +
            +
            +static DdNode * 
            +cuddOrderedThread(
            +  DdNode * root, 
            +  DdNode * list 
            +)
            +
            +
            Threads all the nodes of a search tree into a linear + list. For each node of the search tree, the "left" child, if non-null, has + a lower address than its parent, and the "right" child, if non-null, has a + higher address than its parent. + The list is sorted in order of increasing addresses. The search + tree is destroyed as a result of this operation. The last element of + the linear list is made to point to the address passed in list. Each + node if the search tree is a linearly-linked list of nodes from the + same memory page (as defined in DD_PAGE_MASK). When a node is added to + the linear list, all the elements of the linked list are added. +

            + +

            Side Effects The search tree is destroyed as a result of this operation. +

            + +

            See Also cuddOrderedInsert + + +
            Defined in cuddTable.c + +
            +
            +void 
            +cuddPrintNode(
            +  DdNode * f, 
            +  FILE * fp 
            +)
            +
            +
            Prints out information on a node. +

            + +

            Side Effects None +

            + +

            Defined in cuddCheck.c + +
            +
            +void 
            +cuddPrintVarGroups(
            +  DdManager * dd, manager
            +  MtrNode * root, root of the group tree
            +  int  zdd, 0: BDD; 1: ZDD
            +  int  silent flag to check tree syntax only
            +)
            +
            +
            Prints the variable groups as a parenthesized list. + For each group the level range that it represents is printed. After + each group, the group's flags are printed, preceded by a `|'. For + each flag (except MTR_TERMINAL) a character is printed. +
              +
            • F: MTR_FIXED +
            • N: MTR_NEWNODE +
            • S: MTR_SOFT +
            + The second argument, silent, if different from 0, causes + Cudd_PrintVarGroups to only check the syntax of the group tree. +

            + +

            Side Effects None +

            + +

            Defined in cuddCheck.c + +
            +
            +int 
            +cuddP(
            +  DdManager * dd, 
            +  DdNode * f 
            +)
            +
            +
            Prints a DD to the standard output. One line per node is + printed. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_PrintDebug + + +
            Defined in cuddUtil.c + +
            +
            +void 
            +cuddReclaimZdd(
            +  DdManager * table, 
            +  DdNode * n 
            +)
            +
            +
            Brings children of a dead ZDD node back. +

            + +

            Side Effects None +

            + +

            See Also cuddReclaim + + +
            Defined in cuddRef.c + +
            +
            +void 
            +cuddReclaim(
            +  DdManager * table, 
            +  DdNode * n 
            +)
            +
            +
            Brings children of a dead node back. +

            + +

            Side Effects None +

            + +

            See Also cuddReclaimZdd + + +
            Defined in cuddRef.c + +
            +
            +void 
            +cuddRehash(
            +  DdManager * unique, 
            +  int  i 
            +)
            +
            +
            Doubles the size of a unique subtable and rehashes its + contents. +

            + +

            Side Effects None +

            + +

            Defined in cuddTable.c + +
            +
            +DdNode * 
            +cuddRemapUnderApprox(
            +  DdManager * dd, DD manager
            +  DdNode * f, current DD
            +  int  numVars, maximum number of variables
            +  int  threshold, threshold under which approximation stops
            +  double  quality minimum improvement for accepted changes
            +)
            +
            +
            Applies the remapping underappoximation algorithm. + Proceeds in three phases: +
              +
            • collect information on each node in the BDD; this is done via DFS. +
            • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
            • traverse the BDD via DFS and actually perform the elimination. +
            + Returns the approximated BDD if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_RemapUnderApprox + + +
            Defined in cuddApprox.c + +
            +
            +int 
            +cuddResizeLinear(
            +  DdManager * table 
            +)
            +
            +
            Resizes the linear transform matrix. Returns 1 if + successful; 0 otherwise. +

            + +

            Side Effects none +

            + +

            Defined in cuddLinear.c + +
            +
            +int 
            +cuddResizeTableZdd(
            +  DdManager * unique, 
            +  int  index 
            +)
            +
            +
            Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index. When new ZDD variables are created, it + is possible to preserve the functions unchanged, or it is possible to + preserve the covers unchanged, but not both. cuddResizeTableZdd preserves + the covers. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also ddResizeTable + + +
            Defined in cuddTable.c + +
            +
            +void 
            +cuddSetInteract(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Given a pair of variables 0 <= x < y < table->size, + sets the corresponding bit of the interaction matrix to 1. +

            + +

            Side Effects None +

            + +

            Defined in cuddInteract.c + +
            +
            +void 
            +cuddShrinkDeathRow(
            +  DdManager * table 
            +)
            +
            +
            Shrinks the death row by a factor of four. +

            + +

            Side Effects None +

            + +

            See Also cuddClearDeathRow + + +
            Defined in cuddRef.c + +
            +
            +void 
            +cuddShrinkSubtable(
            +  DdManager * unique, 
            +  int  i 
            +)
            +
            +
            Shrinks a subtable. +

            + +

            Side Effects None +

            + +

            See Also cuddRehash + + +
            Defined in cuddTable.c + +
            +
            +int 
            +cuddSifting(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Implementation of Rudell's sifting algorithm. + Assumes that no dead nodes are present. +
              +
            1. Order all the variables according to the number of entries + in each unique table. +
            2. Sift the variable up and down, remembering each time the + total size of the DD heap. +
            3. Select the best permutation. +
            4. Repeat 3 and 4 for all variables. +
            + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddReorder.c + +
            +
            +void 
            +cuddSlowTableGrowth(
            +  DdManager * unique 
            +)
            +
            +
            Adjusts parameters of a table to slow down its growth. +

            + +

            Side Effects None +

            + +

            Defined in cuddTable.c + +
            +
            +DdNode * 
            +cuddSolveEqnRecur(
            +  DdManager * bdd, 
            +  DdNode * F, the left-hand side of the equation
            +  DdNode * Y, the cube of remaining y variables
            +  DdNode ** G, the array of solutions
            +  int  n, number of unknowns
            +  int * yIndex, array holding the y variable indices
            +  int  i level of recursion
            +)
            +
            +
            Implements the recursive step of Cudd_SolveEqn. + Returns NULL if the intermediate solution blows up + or reordering occurs. The parametric solutions are + stored in the array G. +

            + +

            Side Effects none +

            + +

            See Also Cudd_SolveEqn +Cudd_VerifySol + + +
            Defined in cuddSolve.c + +
            +
            +DdNode* 
            +cuddSplitSetRecur(
            +  DdManager * manager, 
            +  st_table * mtable, 
            +  int * varSeen, 
            +  DdNode * p, 
            +  double  n, 
            +  double  max, 
            +  int  index 
            +)
            +
            +
            Implements the recursive step of Cudd_SplitSet. The + procedure recursively traverses the BDD and checks to see if any + node satisfies the minterm requirements as specified by 'n'. At any + node X, n is compared to the number of minterms in the onset of X's + children. If either of the child nodes have exactly n minterms, then + that node is returned; else, if n is greater than the onset of one + of the child nodes, that node is retained and the difference in the + number of minterms is extracted from the other child. In case n + minterms can be extracted from constant 1, the algorithm returns the + result with at most log(n) nodes. +

            + +

            Side Effects The array 'varSeen' is updated at every recursive call + to set the variables traversed by the procedure. +

            + +

            Defined in cuddSplit.c + +
            +
            +enum st_retval 
            +cuddStCountfree(
            +  char * key, 
            +  char * value, 
            +  char * arg 
            +)
            +
            +
            Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +DdNode * 
            +cuddSubsetHeavyBranch(
            +  DdManager * dd, DD manager
            +  DdNode * f, current DD
            +  int  numVars, maximum number of variables
            +  int  threshold threshold size for the subset
            +)
            +
            +
            Here a subset BDD is built by throwing away one of the + children. Starting at root, annotate each node with the number of + minterms (in terms of the total number of variables specified - + numVars), number of nodes taken by the DAG rooted at this node and + number of additional nodes taken by the child that has the lesser + minterms. The child with the lower number of minterms is thrown away + and a dyanmic count of the nodes of the subset is kept. Once the + threshold is reached the subset is returned to the calling + procedure. +

            + +

            Side Effects None +

            + +

            See Also Cudd_SubsetHeavyBranch + + +
            Defined in cuddSubsetHB.c + +
            +
            +DdNode * 
            +cuddSubsetShortPaths(
            +  DdManager * dd, DD manager
            +  DdNode * f, function to be subset
            +  int  numVars, total number of variables in consideration
            +  int  threshold, maximum number of nodes allowed in the subset
            +  int  hardlimit flag determining whether threshold should be respected strictly
            +)
            +
            +
            The outermost procedure to return a subset of the given + BDD with the largest cubes. The path lengths are calculated, the maximum + allowable path length is determined and the number of nodes of this + path length that can be used to build a subset. If the threshold is + larger than the size of the original BDD, the original BDD is + returned. +

            + +

            Side Effects None +

            + +

            See Also Cudd_SubsetShortPaths + + +
            Defined in cuddSubsetSP.c + +
            +
            +int 
            +cuddSwapInPlace(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Swaps two adjacent variables. It assumes that no dead + nodes are present on entry to this procedure. The procedure then + guarantees that no dead nodes will be present when it terminates. + cuddSwapInPlace assumes that x < y. Returns the number of keys in + the table if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddReorder.c + +
            +
            +int 
            +cuddSwapping(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper, 
            +  Cudd_ReorderingType  heuristic 
            +)
            +
            +
            Implementation of Plessier's algorithm that reorders + variables by a sequence of (non-adjacent) swaps. +
              +
            1. Select two variables (RANDOM or HEURISTIC). +
            2. Permute these variables. +
            3. If the nodes have decreased accept the permutation. +
            4. Otherwise reconstruct the original heap. +
            5. Loop. +
            + Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddReorder.c + +
            +
            +int 
            +cuddSymmCheck(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Checks for symmetry of x and y. Ignores projection + functions, unless they are isolated. Returns 1 in case of symmetry; 0 + otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddSymmetry.c + +
            +
            +int 
            +cuddSymmSiftingConv(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Symmetric sifting to convergence algorithm. + Assumes that no dead nodes are present. +
              +
            1. Order all the variables according to the number of entries in + each unique subtable. +
            2. Sift the variable up and down, remembering each time the total + size of the DD heap and grouping variables that are symmetric. +
            3. Select the best permutation. +
            4. Repeat 3 and 4 for all variables. +
            5. Repeat 1-4 until no further improvement. +
            + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddSymmSifting + + +
            Defined in cuddSymmetry.c + +
            +
            +int 
            +cuddSymmSifting(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Symmetric sifting algorithm. + Assumes that no dead nodes are present. +
              +
            1. Order all the variables according to the number of entries in + each unique subtable. +
            2. Sift the variable up and down, remembering each time the total + size of the DD heap and grouping variables that are symmetric. +
            3. Select the best permutation. +
            4. Repeat 3 and 4 for all variables. +
            + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddSymmSiftingConv + + +
            Defined in cuddSymmetry.c + +
            +
            +int 
            +cuddTestInteract(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Given a pair of variables 0 <= x < y < table->size, + tests whether the corresponding bit of the interaction matrix is 1. + Returns the value of the bit. +

            + +

            Side Effects None +

            + +

            Defined in cuddInteract.c + +
            +
            +int 
            +cuddTimesInDeathRow(
            +  DdManager * dd, 
            +  DdNode * f 
            +)
            +
            +
            Counts how many times a node is in the death row. +

            + +

            Side Effects None +

            + +

            See Also Cudd_DelayedDerefBdd +cuddClearDeathRow +cuddIsInDeathRow + + +
            Defined in cuddRef.c + +
            +
            +int 
            +cuddTreeSifting(
            +  DdManager * table, DD table
            +  Cudd_ReorderingType  method reordering method for the groups of leaves
            +)
            +
            +
            Tree sifting algorithm. Assumes that a tree representing + a group hierarchy is passed as a parameter. It then reorders each + group in postorder fashion by calling ddTreeSiftingAux. Assumes that + no dead nodes are present. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +DdNode * 
            +cuddUnderApprox(
            +  DdManager * dd, DD manager
            +  DdNode * f, current DD
            +  int  numVars, maximum number of variables
            +  int  threshold, threshold under which approximation stops
            +  int  safe, enforce safe approximation
            +  double  quality minimum improvement for accepted changes
            +)
            +
            +
            Applies Tom Shiple's underappoximation algorithm. Proceeds + in three phases: +
              +
            • collect information on each node in the BDD; this is done via DFS. +
            • traverse the BDD in top-down fashion and compute for each node + whether its elimination increases density. +
            • traverse the BDD via DFS and actually perform the elimination. +
            + Returns the approximated BDD if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_UnderApprox + + +
            Defined in cuddApprox.c + +
            +
            +DdNode * 
            +cuddUniqueConst(
            +  DdManager * unique, 
            +  CUDD_VALUE_TYPE  value 
            +)
            +
            +
            Checks the unique table for the existence of a constant node. + If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. Returns a + pointer to the new node. +

            + +

            Side Effects None +

            + +

            Defined in cuddTable.c + +
            +
            +DdNode * 
            +cuddUniqueInterIVO(
            +  DdManager * unique, 
            +  int  index, 
            +  DdNode * T, 
            +  DdNode * E 
            +)
            +
            +
            Wrapper for cuddUniqueInter that is independent of + variable ordering (IVO). This function does not require parameter + index to precede the indices of the top nodes of T and E in the + variable order. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted. +

            + +

            Side Effects None +

            + +

            See Also cuddUniqueInter +Cudd_MakeBddFromZddCover + + +
            Defined in cuddTable.c + +
            +
            +DdNode * 
            +cuddUniqueInterZdd(
            +  DdManager * unique, 
            +  int  index, 
            +  DdNode * T, 
            +  DdNode * E 
            +)
            +
            +
            Checks the unique table for the existence of an internal + ZDD node. If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. For a newly + created node, increments the reference counts of what T and E point + to. Returns a pointer to the new node if successful; NULL if memory + is exhausted or if reordering took place. +

            + +

            Side Effects None +

            + +

            See Also cuddUniqueInter + + +
            Defined in cuddTable.c + +
            +
            +DdNode * 
            +cuddUniqueInter(
            +  DdManager * unique, 
            +  int  index, 
            +  DdNode * T, 
            +  DdNode * E 
            +)
            +
            +
            Checks the unique table for the existence of an internal + node. If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. For a newly + created node, increments the reference counts of what T and E point + to. Returns a pointer to the new node if successful; NULL if memory + is exhausted or if reordering took place. +

            + +

            Side Effects None +

            + +

            See Also cuddUniqueInterZdd + + +
            Defined in cuddTable.c + +
            +
            +static DdNode * 
            +cuddUniqueLookup(
            +  DdManager * unique, 
            +  int  index, 
            +  DdNode * T, 
            +  DdNode * E 
            +)
            +
            +
            Checks the unique table for the existence of an internal + node. Returns a pointer to the node if it is in the table; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddUniqueInter + + +
            Defined in cuddUtil.c + +
            +
            +void 
            +cuddUpdateInteractionMatrix(
            +  DdManager * table, 
            +  int  xindex, 
            +  int  yindex 
            +)
            +
            +
            Updates the interaction matrix. +

            + +

            Side Effects none +

            + +

            Defined in cuddLinear.c + +
            +
            +DdNode * 
            +cuddVerifySol(
            +  DdManager * bdd, 
            +  DdNode * F, the left-hand side of the equation
            +  DdNode ** G, the array of solutions
            +  int * yIndex, array holding the y variable indices
            +  int  n number of unknowns
            +)
            +
            +
            Implements the recursive step of Cudd_VerifySol. +

            + +

            Side Effects none +

            + +

            See Also Cudd_VerifySol + + +
            Defined in cuddSolve.c + +
            +
            +int 
            +cuddWindowReorder(
            +  DdManager * table, DD table
            +  int  low, lowest index to reorder
            +  int  high, highest index to reorder
            +  Cudd_ReorderingType  submethod window reordering option
            +)
            +
            +
            Reorders by applying the method of the sliding window. + Tries all possible permutations to the variables in a window that + slides from low to high. The size of the window is determined by + submethod. Assumes that no dead nodes are present. Returns 1 in + case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddWindow.c + +
            +
            +static void 
            +cuddXorLinear(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            XORs two rows of the linear transform matrix and replaces + the first row with the result. +

            + +

            Side Effects none +

            + +

            Defined in cuddLinear.c + +
            +
            +int 
            +cuddZddAlignToBdd(
            +  DdManager * table DD manager
            +)
            +
            +
            Reorders ZDD variables according to the order of the + BDD variables. This function can be called at the end of BDD + reordering to insure that the order of the ZDD variables is + consistent with the order of the BDD variables. The number of ZDD + variables must be a multiple of the number of BDD variables. Let + M be the ratio of the two numbers. cuddZddAlignToBdd + then considers the ZDD variables from M*i to + (M+1)*i-1 as corresponding to BDD variable + i. This function should be normally called from + Cudd_ReduceHeap, which clears the cache. Returns 1 in case of + success; 0 otherwise. +

            + +

            Side Effects Changes the ZDD variable order for all diagrams and performs + garbage collection of the ZDD unique table. +

            + +

            See Also Cudd_zddShuffleHeap +Cudd_ReduceHeap + + +
            Defined in cuddZddReord.c + +
            +
            +DdNode * 
            +cuddZddChangeAux(
            +  DdManager * zdd, 
            +  DdNode * P, 
            +  DdNode * zvar 
            +)
            +
            +
            Performs the recursive step of Cudd_zddChange. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSetop.c + +
            +
            +DdNode * 
            +cuddZddChange(
            +  DdManager * dd, 
            +  DdNode * P, 
            +  int  var 
            +)
            +
            +
            Substitutes a variable with its complement in a ZDD. + returns a pointer to the result if successful; NULL + otherwise. cuddZddChange performs the same function as + Cudd_zddChange, but does not restart if reordering has taken + place. Therefore it can be called from within a recursive + procedure. +

            + +

            Side Effects None +

            + +

            See Also Cudd_zddChange + + +
            Defined in cuddZddSetop.c + +
            +
            +DdNode	* 
            +cuddZddComplement(
            +  DdManager * dd, 
            +  DdNode * node 
            +)
            +
            +
            Computes the complement of a ZDD node. So far, since we + couldn't find a direct way to get the complement of a ZDD cover, we first + convert a ZDD cover to a BDD, then make the complement of the ZDD cover + from the complement of the BDD node by using ISOP. +

            + +

            Side Effects The result depends on current variable order. +

            + +

            Defined in cuddZddFuncs.c + +
            +
            +static double 
            +cuddZddCountDoubleStep(
            +  DdNode * P, 
            +  st_table * table, 
            +  DdNode * base, 
            +  DdNode * empty 
            +)
            +
            +
            Performs the recursive step of Cudd_zddCountDouble. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddCount.c + +
            +
            +static int 
            +cuddZddCountStep(
            +  DdNode * P, 
            +  st_table * table, 
            +  DdNode * base, 
            +  DdNode * empty 
            +)
            +
            +
            Performs the recursive step of Cudd_zddCount. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddCount.c + +
            +
            +static int 
            +cuddZddDagInt(
            +  DdNode * n, 
            +  st_table * tab 
            +)
            +
            +
            Performs the recursive step of Cudd_zddDagSize. Does + not check for out-of-memory conditions. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddMisc.c + +
            +
            +DdNode * 
            +cuddZddDiff(
            +  DdManager * zdd, 
            +  DdNode * P, 
            +  DdNode * Q 
            +)
            +
            +
            Performs the recursive step of Cudd_zddDiff. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSetop.c + +
            +
            +DdNode	* 
            +cuddZddDivideF(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Performs the recursive step of Cudd_zddDivideF. +

            + +

            Side Effects None +

            + +

            See Also Cudd_zddDivideF + + +
            Defined in cuddZddFuncs.c + +
            +
            +DdNode	* 
            +cuddZddDivide(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Performs the recursive step of Cudd_zddDivide. +

            + +

            Side Effects None +

            + +

            See Also Cudd_zddDivide + + +
            Defined in cuddZddFuncs.c + +
            +
            +void 
            +cuddZddFreeUniv(
            +  DdManager * zdd 
            +)
            +
            +
            Frees the ZDD universe. +

            + +

            Side Effects None +

            + +

            See Also cuddZddInitUniv + + +
            Defined in cuddInit.c + +
            +
            +int 
            +cuddZddGetCofactors2(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  int  v, 
            +  DdNode ** f1, 
            +  DdNode ** f0 
            +)
            +
            +
            Computes the two-way decomposition of f w.r.t. v. +

            + +

            Side Effects The results are returned in f1 and f0. +

            + +

            See Also cuddZddGetCofactors3 + + +
            Defined in cuddZddFuncs.c + +
            +
            +int 
            +cuddZddGetCofactors3(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  int  v, 
            +  DdNode ** f1, 
            +  DdNode ** f0, 
            +  DdNode ** fd 
            +)
            +
            +
            Computes the three-way decomposition of function f (represented + by a ZDD) wit respect to variable v. Returns 0 if successful; 1 otherwise. +

            + +

            Side Effects The results are returned in f1, f0, and fd. +

            + +

            See Also cuddZddGetCofactors2 + + +
            Defined in cuddZddFuncs.c + +
            +
            +int 
            +cuddZddGetNegVarIndex(
            +  DdManager * dd, 
            +  int  index 
            +)
            +
            +
            Returns the index of negative ZDD variable. +

            + +

            Defined in cuddZddFuncs.c + +
            +
            +int 
            +cuddZddGetNegVarLevel(
            +  DdManager * dd, 
            +  int  index 
            +)
            +
            +
            Returns the level of negative ZDD variable. +

            + +

            Defined in cuddZddFuncs.c + +
            +
            +DdNode * 
            +cuddZddGetNodeIVO(
            +  DdManager * dd, 
            +  int  index, 
            +  DdNode * g, 
            +  DdNode * h 
            +)
            +
            +
            Wrapper for cuddUniqueInterZdd that is independent of + variable ordering (IVO). This function does not require parameter + index to precede the indices of the top nodes of g and h in the + variable order. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted. +

            + +

            Side Effects None +

            + +

            See Also cuddZddGetNode +cuddZddIsop + + +
            Defined in cuddTable.c + +
            +
            +DdNode * 
            +cuddZddGetNode(
            +  DdManager * zdd, 
            +  int  id, 
            +  DdNode * T, 
            +  DdNode * E 
            +)
            +
            +
            Wrapper for cuddUniqueInterZdd, which applies the ZDD + reduction rule. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted. +

            + +

            Side Effects None +

            + +

            See Also cuddUniqueInterZdd + + +
            Defined in cuddTable.c + +
            +
            +int 
            +cuddZddGetPosVarIndex(
            +  DdManager * dd, 
            +  int  index 
            +)
            +
            +
            Returns the index of positive ZDD variable. +

            + +

            Defined in cuddZddFuncs.c + +
            +
            +int 
            +cuddZddGetPosVarLevel(
            +  DdManager * dd, 
            +  int  index 
            +)
            +
            +
            Returns the level of positive ZDD variable. +

            + +

            Defined in cuddZddFuncs.c + +
            +
            +int 
            +cuddZddInitUniv(
            +  DdManager * zdd 
            +)
            +
            +
            Initializes the ZDD universe. Returns 1 if successful; 0 + otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddZddFreeUniv + + +
            Defined in cuddInit.c + +
            +
            +DdNode * 
            +cuddZddIntersect(
            +  DdManager * zdd, 
            +  DdNode * P, 
            +  DdNode * Q 
            +)
            +
            +
            Performs the recursive step of Cudd_zddIntersect. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSetop.c + +
            +
            +DdNode	* 
            +cuddZddIsop(
            +  DdManager * dd, 
            +  DdNode * L, 
            +  DdNode * U, 
            +  DdNode ** zdd_I 
            +)
            +
            +
            Performs the recursive step of Cudd_zddIsop. +

            + +

            Side Effects None +

            + +

            See Also Cudd_zddIsop + + +
            Defined in cuddZddIsop.c + +
            +
            +DdNode * 
            +cuddZddIte(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g, 
            +  DdNode * h 
            +)
            +
            +
            Performs the recursive step of Cudd_zddIte. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSetop.c + +
            +
            +static int 
            +cuddZddLinearAux(
            +  DdManager * table, 
            +  int  x, 
            +  int  xLow, 
            +  int  xHigh 
            +)
            +
            +
            Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddLin.c + +
            +
            +static int 
            +cuddZddLinearBackward(
            +  DdManager * table, 
            +  int  size, 
            +  Move * moves 
            +)
            +
            +
            Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddLin.c + +
            +
            +static Move * 
            +cuddZddLinearDown(
            +  DdManager * table, 
            +  int  x, 
            +  int  xHigh, 
            +  Move * prevMoves 
            +)
            +
            +
            Sifts a variable down. Moves x down until either it + reaches the bound (xHigh) or the size of the ZDD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddLin.c + +
            +
            +static int 
            +cuddZddLinearInPlace(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Linearly combines two adjacent variables. It assumes + that no dead nodes are present on entry to this procedure. The + procedure then guarantees that no dead nodes will be present when it + terminates. cuddZddLinearInPlace assumes that x < y. Returns the + number of keys in the table if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddZddSwapInPlace +cuddLinearInPlace + + +
            Defined in cuddZddLin.c + +
            +
            +int 
            +cuddZddLinearSifting(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Implementation of the linear sifting algorithm for ZDDs. + Assumes that no dead nodes are present. +
              +
            1. Order all the variables according to the number of entries + in each unique table. +
            2. Sift the variable up and down and applies the XOR transformation, + remembering each time the total size of the DD heap. +
            3. Select the best permutation. +
            4. Repeat 3 and 4 for all variables. +
            + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddLin.c + +
            +
            +static Move * 
            +cuddZddLinearUp(
            +  DdManager * table, 
            +  int  y, 
            +  int  xLow, 
            +  Move * prevMoves 
            +)
            +
            +
            Sifts a variable up applying the XOR + transformation. Moves y up until either it reaches the bound (xLow) + or the size of the ZDD heap increases too much. Returns the set of + moves in case of success; NULL if memory is full. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddLin.c + +
            +
            +int 
            +cuddZddNextHigh(
            +  DdManager * table, 
            +  int  x 
            +)
            +
            +
            Finds the next subtable with a larger index. Returns the + index. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +int 
            +cuddZddNextLow(
            +  DdManager * table, 
            +  int  x 
            +)
            +
            +
            Finds the next subtable with a smaller index. Returns the + index. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +DdNode	* 
            +cuddZddProduct(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Performs the recursive step of Cudd_zddProduct. +

            + +

            Side Effects None +

            + +

            See Also Cudd_zddProduct + + +
            Defined in cuddZddFuncs.c + +
            +
            +int 
            +cuddZddP(
            +  DdManager * zdd, 
            +  DdNode * f 
            +)
            +
            +
            Prints a ZDD to the standard output. One line per node is + printed. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_zddPrintDebug + + +
            Defined in cuddZddUtil.c + +
            +
            +static int 
            +cuddZddSiftingAux(
            +  DdManager * table, 
            +  int  x, 
            +  int  x_low, 
            +  int  x_high 
            +)
            +
            +
            Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +static int 
            +cuddZddSiftingBackward(
            +  DdManager * table, 
            +  Move * moves, 
            +  int  size 
            +)
            +
            +
            Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +static Move * 
            +cuddZddSiftingDown(
            +  DdManager * table, 
            +  int  x, 
            +  int  x_high, 
            +  int  initial_size 
            +)
            +
            +
            Sifts a variable down. Moves x down until either it + reaches the bound (x_high) or the size of the ZDD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +static Move * 
            +cuddZddSiftingUp(
            +  DdManager * table, 
            +  int  x, 
            +  int  x_low, 
            +  int  initial_size 
            +)
            +
            +
            Sifts a variable up. Moves y up until either it reaches + the bound (x_low) or the size of the ZDD heap increases too much. + Returns the set of moves in case of success; NULL if memory is full. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +int 
            +cuddZddSifting(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Implementation of Rudell's sifting algorithm. + Assumes that no dead nodes are present. +
              +
            1. Order all the variables according to the number of entries + in each unique table. +
            2. Sift the variable up and down, remembering each time the + total size of the DD heap. +
            3. Select the best permutation. +
            4. Repeat 3 and 4 for all variables. +
            + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +DdNode * 
            +cuddZddSubset0(
            +  DdManager * dd, 
            +  DdNode * P, 
            +  int  var 
            +)
            +
            +
            Computes the negative cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is negated. Returns a pointer to + the result if successful; NULL otherwise. cuddZddSubset0 performs + the same function as Cudd_zddSubset0, but does not restart if + reordering has taken place. Therefore it can be called from within a + recursive procedure. +

            + +

            Side Effects None +

            + +

            See Also cuddZddSubset1 +Cudd_zddSubset0 + + +
            Defined in cuddZddSetop.c + +
            +
            +DdNode * 
            +cuddZddSubset1(
            +  DdManager * dd, 
            +  DdNode * P, 
            +  int  var 
            +)
            +
            +
            Computes the positive cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is asserted. Returns a pointer to + the result if successful; NULL otherwise. cuddZddSubset1 performs + the same function as Cudd_zddSubset1, but does not restart if + reordering has taken place. Therefore it can be called from within a + recursive procedure. +

            + +

            Side Effects None +

            + +

            See Also cuddZddSubset0 +Cudd_zddSubset1 + + +
            Defined in cuddZddSetop.c + +
            +
            +int 
            +cuddZddSwapInPlace(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Swaps two adjacent variables. It assumes that no dead + nodes are present on entry to this procedure. The procedure then + guarantees that no dead nodes will be present when it terminates. + cuddZddSwapInPlace assumes that x < y. Returns the number of keys in + the table if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +int 
            +cuddZddSwapping(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper, 
            +  Cudd_ReorderingType  heuristic 
            +)
            +
            +
            Implementation of Plessier's algorithm that reorders + variables by a sequence of (non-adjacent) swaps. +
              +
            1. Select two variables (RANDOM or HEURISTIC). +
            2. Permute these variables. +
            3. If the nodes have decreased accept the permutation. +
            4. Otherwise reconstruct the original heap. +
            5. Loop. +
            + Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +int 
            +cuddZddSymmCheck(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Checks for symmetry of x and y. Ignores projection + functions, unless they are isolated. Returns 1 in case of + symmetry; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSymm.c + +
            +
            +static int 
            +cuddZddSymmSiftingAux(
            +  DdManager * table, 
            +  int  x, 
            +  int  x_low, 
            +  int  x_high 
            +)
            +
            +
            Given x_low <= x <= x_high moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is not part of a symmetry group. Returns 1 if + successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSymm.c + +
            +
            +static int 
            +cuddZddSymmSiftingBackward(
            +  DdManager * table, 
            +  Move * moves, 
            +  int  size 
            +)
            +
            +
            Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSymm.c + +
            +
            +static int 
            +cuddZddSymmSiftingConvAux(
            +  DdManager * table, 
            +  int  x, 
            +  int  x_low, 
            +  int  x_high 
            +)
            +
            +
            Given x_low <= x <= x_high moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is either an isolated variable, or it is the bottom of + a symmetry group. All symmetries may not have been found, because of + exceeded growth limit. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSymm.c + +
            +
            +int 
            +cuddZddSymmSiftingConv(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Symmetric sifting to convergence algorithm for ZDDs. + Assumes that no dead nodes are present. +
              +
            1. Order all the variables according to the number of entries in + each unique subtable. +
            2. Sift the variable up and down, remembering each time the total + size of the ZDD heap and grouping variables that are symmetric. +
            3. Select the best permutation. +
            4. Repeat 3 and 4 for all variables. +
            5. Repeat 1-4 until no further improvement. +
            + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddZddSymmSifting + + +
            Defined in cuddZddSymm.c + +
            +
            +static Move * 
            +cuddZddSymmSifting_down(
            +  DdManager * table, 
            +  int  x, 
            +  int  x_high, 
            +  int  initial_size 
            +)
            +
            +
            Moves x down until either it reaches the bound (x_high) + or the size of the ZDD heap increases too much. Assumes that x is the + bottom of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; ZDD_MV_OOM if memory is full. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSymm.c + +
            +
            +static Move * 
            +cuddZddSymmSifting_up(
            +  DdManager * table, 
            +  int  x, 
            +  int  x_low, 
            +  int  initial_size 
            +)
            +
            +
            Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much. Assumes that x is the top + of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; ZDD_MV_OOM if memory is full. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSymm.c + +
            +
            +int 
            +cuddZddSymmSifting(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Symmetric sifting algorithm. + Assumes that no dead nodes are present. +
              +
            1. Order all the variables according to the number of entries in + each unique subtable. +
            2. Sift the variable up and down, remembering each time the total + size of the ZDD heap and grouping variables that are symmetric. +
            3. Select the best permutation. +
            4. Repeat 3 and 4 for all variables. +
            + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddZddSymmSiftingConv + + +
            Defined in cuddZddSymm.c + +
            +
            +static void 
            +cuddZddSymmSummary(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper, 
            +  int * symvars, 
            +  int * symgroups 
            +)
            +
            +
            Counts numbers of symmetric variables and symmetry + groups. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSymm.c + +
            +
            +int 
            +cuddZddTreeSifting(
            +  DdManager * table, DD table
            +  Cudd_ReorderingType  method reordering method for the groups of leaves
            +)
            +
            +
            Tree sifting algorithm for ZDDs. Assumes that a tree + representing a group hierarchy is passed as a parameter. It then + reorders each group in postorder fashion by calling + zddTreeSiftingAux. Assumes that no dead nodes are present. Returns + 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddGroup.c + +
            +
            +DdNode	* 
            +cuddZddUnateProduct(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Performs the recursive step of Cudd_zddUnateProduct. +

            + +

            Side Effects None +

            + +

            See Also Cudd_zddUnateProduct + + +
            Defined in cuddZddFuncs.c + +
            +
            +static Move* 
            +cuddZddUndoMoves(
            +  DdManager * table, 
            +  Move * moves 
            +)
            +
            +
            Given a set of moves, returns the ZDD heap to the + order in effect before the moves. Returns 1 in case of success; + 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddLin.c + +
            +
            +DdNode * 
            +cuddZddUnion(
            +  DdManager * zdd, 
            +  DdNode * P, 
            +  DdNode * Q 
            +)
            +
            +
            Performs the recursive step of Cudd_zddUnion. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSetop.c + +
            +
            +int 
            +cuddZddUniqueCompare(
            +  int * ptr_x, 
            +  int * ptr_y 
            +)
            +
            +
            Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +DdNode	* 
            +cuddZddWeakDivF(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Performs the recursive step of Cudd_zddWeakDivF. +

            + +

            Side Effects None +

            + +

            See Also Cudd_zddWeakDivF + + +
            Defined in cuddZddFuncs.c + +
            +
            +DdNode	* 
            +cuddZddWeakDiv(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * g 
            +)
            +
            +
            Performs the recursive step of Cudd_zddWeakDiv. +

            + +

            Side Effects None +

            + +

            See Also Cudd_zddWeakDiv + + +
            Defined in cuddZddFuncs.c + +
            +
            +static DdNode * 
            +ddBddMaximallyExpand(
            +  DdManager * dd, manager
            +  DdNode * lb, cube to be expanded
            +  DdNode * ub, upper bound cube
            +  DdNode * f function against which to expand
            +)
            +
            +
            Performs the recursive step of Cudd_bddMaximallyExpand. + Returns set of primes or zero BDD if successful; NULL otherwise. On entry + to this function, ub and lb should be different from the zero BDD. The + function then maintains this invariant. +

            + +

            Side Effects None +

            + +

            Defined in cuddSat.c + +
            +
            +static int 
            +ddBddShortestPathUnate(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  int * phases, 
            +  st_table * table 
            +)
            +
            +
            Performs shortest path computation on a unate function. + Returns the length of the shortest path to one if successful; + CUDD_OUT_OF_MEM otherwise. This function is based on the observation + that in the BDD of a unate function no node except the constant is + reachable from the root via paths of different parity. +

            + +

            Side Effects None +

            + +

            See Also getShortest + + +
            Defined in cuddSat.c + +
            +
            +static DdNode * 
            +ddBddToAddRecur(
            +  DdManager * dd, 
            +  DdNode * B 
            +)
            +
            +
            Performs the recursive step for Cudd_BddToAdd. Returns a + pointer to the resulting ADD if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddBridge.c + +
            +
            +static int 
            +ddCheckPermuation(
            +  DdManager * table, 
            +  MtrNode * treenode, 
            +  int * perm, 
            +  int * invperm 
            +)
            +
            +
            Checks the BDD variable group tree before a shuffle. + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects Changes the BDD variable group tree. +

            + +

            Defined in cuddReorder.c + +
            +
            +static void 
            +ddClearFlag(
            +  DdNode * f 
            +)
            +
            +
            Performs a DFS from f, clearing the LSB of the next + pointers. +

            + +

            Side Effects None +

            + +

            See Also ddSupportStep +ddFindSupport +ddLeavesInt +ddDagInt + + +
            Defined in cuddUtil.c + +
            +
            +static void 
            +ddClearGlobal(
            +  DdManager * table, 
            +  int  lower, 
            +  int  maxlevel 
            +)
            +
            +
            Scans the DD and clears the LSB of the next pointers. + The LSB of the next pointers are used as markers to tell whether a + node was reached. Once the roots are counted, these flags are + reset. +

            + +

            Side Effects None +

            + +

            See Also ddCountRoots + + +
            Defined in cuddExact.c + +
            +
            +static void 
            +ddClearGlobal(
            +  DdManager * table 
            +)
            +
            +
            The LSB of the next pointers are used as markers to tell + whether a node was reached by at least one DFS. Once the interaction + matrix is built, these flags are reset. +

            + +

            Side Effects None +

            + +

            Defined in cuddInteract.c + +
            +
            +static void 
            +ddClearLocal(
            +  DdNode * f 
            +)
            +
            +
            Performs a DFS from f, clearing the LSB of the then pointers. +

            + +

            Side Effects None +

            + +

            Defined in cuddInteract.c + +
            +
            +static void 
            +ddClearVars(
            +  DdManager * dd, 
            +  int  SP 
            +)
            +
            +
            Clears visited flags for variables. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +static double * 
            +ddCofMintermAux(
            +  DdManager * dd, 
            +  DdNode * node, 
            +  st_table * table 
            +)
            +
            +
            Traverses the DD node and computes the fraction of + minterms in the on-set of all positive cofactors simultaneously. + It allocates an array with two more entries than there are + variables below the one labeling the node. One extra entry (the + first in the array) is for the variable labeling the node. The other + entry (the last one in the array) holds the fraction of minterms of + the function rooted at node. Each other entry holds the value for + one cofactor. The array is put in a symbol table, to avoid repeated + computation, and its address is returned by the procedure, for use + by the caller. Returns a pointer to the array of cofactor measures. +

            + +

            Side Effects None +

            + +

            Defined in cuddSign.c + +
            +
            +static int 
            +ddCountInternalMtrNodes(
            +  DdManager * table, 
            +  MtrNode * treenode 
            +)
            +
            +
            Counts the number of internal nodes of the group tree. + Returns the count. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static double 
            +ddCountMintermAux(
            +  DdNode * node, 
            +  double  max, 
            +  DdHashTable * table 
            +)
            +
            +
            Performs the recursive step of Cudd_CountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. Does not use the + identity |f'| = max - |f|, to minimize loss of accuracy due to + roundoff. Returns the number of minterms of the function rooted at + node. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +static double 
            +ddCountPathAux(
            +  DdNode * node, 
            +  st_table * table 
            +)
            +
            +
            Performs the recursive step of Cudd_CountPath. + It is based on the following identity. Let |f| be the + number of paths of f. Then: + + |f| = |f0|+|f1| + + where f0 and f1 are the two cofactors of f. Uses the + identity |f'| = |f|, to improve the utilization of the (local) cache. + Returns the number of paths of the function rooted at node. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +static double 
            +ddCountPathsToNonZero(
            +  DdNode * N, 
            +  st_table * table 
            +)
            +
            +
            Performs the recursive step of Cudd_CountPathsToNonZero. + It is based on the following identity. Let |f| be the + number of paths of f. Then: + + |f| = |f0|+|f1| + + where f0 and f1 are the two cofactors of f. Returns the number of + paths of the function rooted at node. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +static int 
            +ddCountRoots(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Counts the number of roots at the levels between lower and + upper. The computation is based on breadth-first search. + A node is a root if it is not reachable from any previously visited node. + (All the nodes at level lower are therefore considered roots.) + The visited flag uses the LSB of the next pointer. Returns the root + count. The roots that are constant nodes are always ignored. +

            + +

            Side Effects None +

            + +

            See Also ddClearGlobal + + +
            Defined in cuddExact.c + +
            +
            +static void 
            +ddCreateGroup(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Creates a group encompassing variables from x to y in the + DD table. In the current implementation it must be y == x+1. + Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddDagInt(
            +  DdNode * n 
            +)
            +
            +
            Performs the recursive step of Cudd_DagSize. Returns the + number of nodes in the graph rooted at n. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +static void 
            +ddDissolveGroup(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            x and y are variables in a group to be cut in two. The cut + is to pass between x and y. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddDoDumpBlif(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  FILE * fp, 
            +  st_table * visited, 
            +  char ** names, 
            +  int  mv 
            +)
            +
            +
            Performs the recursive step of Cudd_DumpBlif. Traverses + the BDD f and writes a multiplexer-network description to the file + pointed by fp in blif format. f is assumed to be a regular pointer + and ddDoDumpBlif guarantees this assumption in the recursive calls. +

            + +

            Side Effects None +

            + +

            Defined in cuddExport.c + +
            +
            +static int 
            +ddDoDumpDDcal(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  FILE * fp, 
            +  st_table * visited, 
            +  char ** names, 
            +  ptruint  mask 
            +)
            +
            +
            Performs the recursive step of Cudd_DumpDDcal. Traverses + the BDD f and writes a line for each node to the file + pointed by fp in DDcal format. f is assumed to be a regular pointer + and ddDoDumpDDcal guarantees this assumption in the recursive calls. +

            + +

            Side Effects None +

            + +

            Defined in cuddExport.c + +
            +
            +static int 
            +ddDoDumpDaVinci(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  FILE * fp, 
            +  st_table * visited, 
            +  char ** names, 
            +  ptruint  mask 
            +)
            +
            +
            Performs the recursive step of Cudd_DumpDaVinci. Traverses + the BDD f and writes a term expression to the file + pointed by fp in daVinci format. f is assumed to be a regular pointer + and ddDoDumpDaVinci guarantees this assumption in the recursive calls. +

            + +

            Side Effects None +

            + +

            Defined in cuddExport.c + +
            +
            +static int 
            +ddDoDumpFactoredForm(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  FILE * fp, 
            +  char ** names 
            +)
            +
            +
            Performs the recursive step of + Cudd_DumpFactoredForm. Traverses the BDD f and writes a factored + form for each node to the file pointed by fp in terms of the + factored forms of the children. Constants are propagated, and + absorption is applied. f is assumed to be a regular pointer and + ddDoDumpFActoredForm guarantees this assumption in the recursive + calls. +

            + +

            Side Effects None +

            + +

            See Also Cudd_DumpFactoredForm + + +
            Defined in cuddExport.c + +
            +
            +static int 
            +ddEpdCountMintermAux(
            +  DdNode * node, 
            +  EpDouble * max, 
            +  EpDouble * epd, 
            +  st_table * table 
            +)
            +
            +
            Performs the recursive step of Cudd_EpdCountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. Does not use the + identity |f'| = max - |f|, to minimize loss of accuracy due to + roundoff. Returns the number of minterms of the function rooted at + node. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +static enum st_retval 
            +ddEpdFree(
            +  char * key, 
            +  char * value, 
            +  char * arg 
            +)
            +
            +
            Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +static int 
            +ddExchange(
            +  DdManager * table, 
            +  int  x, 
            +  int  y, 
            +  double  temp 
            +)
            +
            +
            This is the same funcion as ddSwapping except for + comparison expression. Use probability function, exp(-size_change/temp). +

            + +

            Side Effects None +

            + +

            Defined in cuddAnneal.c + +
            +
            +static int 
            +ddExtSymmCheck(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Checks for extended symmetry of x and y. Returns 1 in + case of extended symmetry; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static DdNode * 
            +ddFindEssentialRecur(
            +  DdManager * dd, 
            +  DdNode * f 
            +)
            +
            +
            Implements the recursive step of Cudd_FindEssential. + Returns a pointer to the cube BDD if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddEssent.c + +
            +
            +static void 
            +ddFindNodeHiLo(
            +  DdManager * table, 
            +  MtrNode * treenode, 
            +  int * lower, 
            +  int * upper 
            +)
            +
            +
            Finds the lower and upper bounds of the group + represented by treenode. From the index and size fields we need to + derive the current positions, and find maximum and minimum. +

            + +

            Side Effects The bounds are returned as side effects. +

            + +

            Defined in cuddGroup.c + +
            +
            +static void 
            +ddFindSupport(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  int * SP 
            +)
            +
            +
            Recursively find the support of f. This function uses the + LSB of the next field of the nodes of f as visited flag. It also uses the + LSB of the next field of the variables as flag to remember whether a + certain index has already been seen. Finally, it uses the manager stack + to record all seen indices. +

            + +

            Side Effects The stack pointer SP is modified by side-effect. The next + fields are changed and need to be reset. +

            + +

            Defined in cuddUtil.c + +
            +
            +static DdTlcInfo * 
            +ddFindTwoLiteralClausesRecur(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  st_table * table 
            +)
            +
            +
            Implements the recursive step of + Cudd_FindTwoLiteralClauses. The DD node is assumed to be not + constant. Returns a pointer to a set of clauses if successful; NULL + otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_FindTwoLiteralClauses + + +
            Defined in cuddEssent.c + +
            +
            +static DdNode * 
            +ddGetLargestCubeUnate(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  int * phases, 
            +  st_table * table 
            +)
            +
            +
            Extracts largest prime of a unate function. Returns the BDD of + the prime if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also getPath + + +
            Defined in cuddSat.c + +
            +
            +static int 
            +ddGroupMoveBackward(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Undoes the swap two groups. Returns 1 in case of + success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddGroupMove(
            +  DdManager * table, 
            +  int  x, 
            +  int  y, 
            +  Move ** moves 
            +)
            +
            +
            Swaps two groups and records the move. Returns the + number of keys in the DD table in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddGroupSiftingAux(
            +  DdManager * table, 
            +  int  x, 
            +  int  xLow, 
            +  int  xHigh, 
            +  DD_CHKFP  checkFunction, 
            +  int  lazyFlag 
            +)
            +
            +
            Sifts one variable up and down until it has taken all + positions. Checks for aggregation. There may be at most two sweeps, + even if the group grows. Assumes that x is either an isolated + variable, or it is the bottom of a group. All groups may not have + been found. The variable being moved is returned to the best position + seen during sifting. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddGroupSiftingBackward(
            +  DdManager * table, 
            +  Move * moves, 
            +  int  size, 
            +  int  upFlag, 
            +  int  lazyFlag 
            +)
            +
            +
            Determines the best position for a variables and returns + it there. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddGroupSiftingDown(
            +  DdManager * table, 
            +  int  x, 
            +  int  xHigh, 
            +  DD_CHKFP  checkFunction, 
            +  Move ** moves 
            +)
            +
            +
            Sifts down a variable until it reaches position xHigh. + Assumes that x is the bottom of a group (or a singleton). Records + all the moves. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddGroupSiftingUp(
            +  DdManager * table, 
            +  int  y, 
            +  int  xLow, 
            +  DD_CHKFP  checkFunction, 
            +  Move ** moves 
            +)
            +
            +
            Sifts up a variable until either it reaches position + xLow or the size of the DD heap increases too much. Assumes that y is + the top of a group (or a singleton). Checks y for aggregation to the + adjacent variables. Records all the moves that are appended to the + list of moves received as input and returned as a side effect. + Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddGroupSifting(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper, 
            +  DD_CHKFP  checkFunction, 
            +  int  lazyFlag 
            +)
            +
            +
            Sifts from treenode->low to treenode->high. If + croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the + end of the initial sifting. If a group is created, it is then sifted + again. After sifting one variable, the group that contains it is + dissolved. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddIsVarHandled(
            +  DdManager * dd, 
            +  int  index 
            +)
            +
            +
            Checks whether a variables is already handled. This + function is used for lazy sifting. +

            + +

            Side Effects none +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddJumpingAux(
            +  DdManager * table, 
            +  int  x, 
            +  int  x_low, 
            +  int  x_high, 
            +  double  temp 
            +)
            +
            +
            If x==x_low, it executes jumping_down. If x==x_high, it + executes jumping_up. This funcion is similar to ddSiftingAux. Returns + 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddAnneal.c + +
            +
            +static Move * 
            +ddJumpingDown(
            +  DdManager * table, 
            +  int  x, 
            +  int  x_high, 
            +  int  initial_size 
            +)
            +
            +
            This is a simplified version of ddSiftingDown. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full. +

            + +

            Side Effects None +

            + +

            Defined in cuddAnneal.c + +
            +
            +static Move * 
            +ddJumpingUp(
            +  DdManager * table, 
            +  int  x, 
            +  int  x_low, 
            +  int  initial_size 
            +)
            +
            +
            This is a simplified version of ddSiftingUp. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full. +

            + +

            Side Effects None +

            + +

            Defined in cuddAnneal.c + +
            +
            +static int 
            +ddLeavesInt(
            +  DdNode * n 
            +)
            +
            +
            Performs the recursive step of Cudd_CountLeaves. Returns + the number of leaves in the DD rooted at n. +

            + +

            Side Effects None +

            + +

            See Also Cudd_CountLeaves + + +
            Defined in cuddUtil.c + +
            +
            +static int 
            +ddLinearAndSiftingAux(
            +  DdManager * table, 
            +  int  x, 
            +  int  xLow, 
            +  int  xHigh 
            +)
            +
            +
            Given xLow <= x <= xHigh moves x up and down between the + boundaries. At each step a linear transformation is tried, and, if it + decreases the size of the DD, it is accepted. Finds the best position + and does the required changes. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddLinear.c + +
            +
            +static int 
            +ddLinearAndSiftingBackward(
            +  DdManager * table, 
            +  int  size, 
            +  Move * moves 
            +)
            +
            +
            Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddLinear.c + +
            +
            +static Move * 
            +ddLinearAndSiftingDown(
            +  DdManager * table, 
            +  int  x, 
            +  int  xHigh, 
            +  Move * prevMoves 
            +)
            +
            +
            Sifts a variable down and applies linear + transformations. Moves x down until either it reaches the bound + (xHigh) or the size of the DD heap increases too much. Returns the + set of moves in case of success; NULL if memory is full. +

            + +

            Side Effects None +

            + +

            Defined in cuddLinear.c + +
            +
            +static Move * 
            +ddLinearAndSiftingUp(
            +  DdManager * table, 
            +  int  y, 
            +  int  xLow, 
            +  Move * prevMoves 
            +)
            +
            +
            Sifts a variable up and applies linear transformations. + Moves y up until either it reaches the bound (xLow) or the size of + the DD heap increases too much. Returns the set of moves in case of + success; NULL if memory is full. +

            + +

            Side Effects None +

            + +

            Defined in cuddLinear.c + +
            +
            +static int 
            +ddLinearUniqueCompare(
            +  int * ptrX, 
            +  int * ptrY 
            +)
            +
            +
            Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared. +

            + +

            Side Effects None +

            + +

            Defined in cuddLinear.c + +
            +
            +static void 
            +ddMergeGroups(
            +  DdManager * table, 
            +  MtrNode * treenode, 
            +  int  low, 
            +  int  high 
            +)
            +
            +
            Creates a single group from low to high and adjusts the + index field of the tree node. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddNoCheck(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Pretends to check two variables for aggregation. Always + returns 0. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static void 
            +ddPatchTree(
            +  DdManager * dd, 
            +  MtrNode * treenode 
            +)
            +
            +
            Fixes a variable tree after the insertion of new subtables. + After such an insertion, the low fields of the tree below the insertion + point are inconsistent. +

            + +

            Side Effects None +

            + +

            Defined in cuddTable.c + +
            +
            +static int 
            +ddPermuteWindow3(
            +  DdManager * table, 
            +  int  x 
            +)
            +
            +
            Tries all the permutations of the three variables between + x and x+2 and retains the best. Assumes that no dead nodes are + present. Returns the index of the best permutation (1-6) in case of + success; 0 otherwise.Assumes that no dead nodes are present. Returns + the index of the best permutation (1-6) in case of success; 0 + otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddWindow.c + +
            +
            +static int 
            +ddPermuteWindow4(
            +  DdManager * table, 
            +  int  w 
            +)
            +
            +
            Tries all the permutations of the four variables between + w and w+3 and retains the best. Assumes that no dead nodes are + present. Returns the index of the best permutation (1-24) in case of + success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddWindow.c + +
            +
            +static int 
            +ddPickArbitraryMinterms(
            +  DdManager * dd, 
            +  DdNode * node, 
            +  int  nvars, 
            +  int  nminterms, 
            +  char ** string 
            +)
            +
            +
            Performs the recursive step of Cudd_bddPickArbitraryMinterms. + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects none +

            + +

            See Also Cudd_bddPickArbitraryMinterms + + +
            Defined in cuddUtil.c + +
            +
            +static int 
            +ddPickRepresentativeCube(
            +  DdManager * dd, 
            +  DdNode * node, 
            +  double * weight, 
            +  char * string 
            +)
            +
            +
            Finds a representative cube of a BDD with the weight of + each variable. From the top variable, if the weight is greater than or + equal to 0.0, choose THEN branch unless the child is the constant 0. + Otherwise, choose ELSE branch unless the child is the constant 0. +

            + +

            Side Effects Cudd_SubsetWithMaskVars Cudd_bddPickOneCube +

            + +

            Defined in cuddUtil.c + +
            +
            +static void 
            +ddPrintMintermAux(
            +  DdManager * dd, manager
            +  DdNode * node, current node
            +  int * list current recursion path
            +)
            +
            +
            Performs the recursive step of Cudd_PrintMinterm. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +static void 
            +ddRehashZdd(
            +  DdManager * unique, 
            +  int  i 
            +)
            +
            +
            Rehashes a ZDD unique subtable. +

            + +

            Side Effects None +

            + +

            See Also cuddRehash + + +
            Defined in cuddTable.c + +
            +
            +static int 
            +ddReorderChildren(
            +  DdManager * table, 
            +  MtrNode * treenode, 
            +  Cudd_ReorderingType  method 
            +)
            +
            +
            Reorders the children of a group tree node according to + the options. After reordering puts all the variables in the group + and/or its descendents in a single group. This allows hierarchical + reordering. If the variables in the group do not exist yet, simply + does nothing. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddReorderPostprocess(
            +  DdManager * table 
            +)
            +
            +
            Cleans up at the end of reordering. +

            + +

            Side Effects None +

            + +

            Defined in cuddReorder.c + +
            +
            +static int 
            +ddReorderPreprocess(
            +  DdManager * table 
            +)
            +
            +
            Prepares the DD heap for dynamic reordering. Does + garbage collection, to guarantee that there are no dead nodes; + clears the cache, which is invalidated by dynamic reordering; initializes + the number of isolated projection functions; and initializes the + interaction matrix. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddReorder.c + +
            +
            +static void 
            +ddReportRefMess(
            +  DdManager * unique, manager
            +  int  i, table in which the problem occurred
            +  const char * caller procedure that detected the problem
            +)
            +
            +
            Reports problem in garbage collection. +

            + +

            Side Effects None +

            + +

            See Also cuddGarbageCollect +cuddGarbageCollectZdd + + +
            Defined in cuddTable.c + +
            +
            +static int 
            +ddResetVarHandled(
            +  DdManager * dd, 
            +  int  index 
            +)
            +
            +
            Resets a variable to be processed. This function is used + for lazy sifting. +

            + +

            Side Effects none +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddResizeTable(
            +  DdManager * unique, 
            +  int  index, 
            +  int  amount 
            +)
            +
            +
            Increases the number of subtables in a unique table so + that it meets or exceeds index. The parameter amount determines how + much spare space is allocated to prevent too frequent resizing. If + index is negative, the table is resized, but no new variables are + created. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_Reserve +cuddResizeTableZdd + + +
            Defined in cuddTable.c + +
            +
            +static int 
            +ddSecDiffCheck(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Checks two variables for aggregation. The check is based + on the second difference of the number of nodes as a function of the + layer. If the second difference is lower than a given threshold + (typically negative) then the two variables should be aggregated. + Returns 1 if the two variables pass the test; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddSetVarHandled(
            +  DdManager * dd, 
            +  int  index 
            +)
            +
            +
            Sets a variable to already handled. This function is used + for lazy sifting. +

            + +

            Side Effects none +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddShuffle(
            +  DdManager * table, 
            +  DdHalfWord * permutation, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Reorders variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. ddShuffle assumes that no + dead nodes are present and that the interaction matrix is properly + initialized. The reordering is achieved by a series of upward sifts. + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddExact.c + +
            +
            +static int 
            +ddShuffle(
            +  DdManager * table, 
            +  int * permutation 
            +)
            +
            +
            Reorders variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. ddShuffle assumes that no + dead nodes are present and that the interaction matrix is properly + initialized. The reordering is achieved by a series of upward sifts. + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddReorder.c + +
            +
            +static int 
            +ddSiftUp(
            +  DdManager * table, 
            +  int  x, 
            +  int  xLow 
            +)
            +
            +
            Takes a variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise +

            + +

            Side Effects None +

            + +

            Defined in cuddExact.c + +
            +
            +static int 
            +ddSiftUp(
            +  DdManager * table, 
            +  int  x, 
            +  int  xLow 
            +)
            +
            +
            Takes a variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise +

            + +

            Side Effects None +

            + +

            Defined in cuddReorder.c + +
            +
            +static int 
            +ddSiftingAux(
            +  DdManager * table, 
            +  int  x, 
            +  int  xLow, 
            +  int  xHigh 
            +)
            +
            +
            Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddReorder.c + +
            +
            +static int 
            +ddSiftingBackward(
            +  DdManager * table, 
            +  int  size, 
            +  Move * moves 
            +)
            +
            +
            Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddReorder.c + +
            +
            +static Move * 
            +ddSiftingDown(
            +  DdManager * table, 
            +  int  x, 
            +  int  xHigh 
            +)
            +
            +
            Sifts a variable down. Moves x down until either it + reaches the bound (xHigh) or the size of the DD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full. +

            + +

            Side Effects None +

            + +

            Defined in cuddReorder.c + +
            +
            +static Move * 
            +ddSiftingUp(
            +  DdManager * table, 
            +  int  y, 
            +  int  xLow 
            +)
            +
            +
            Sifts a variable up. Moves y up until either it reaches + the bound (xLow) or the size of the DD heap increases too much. + Returns the set of moves in case of success; NULL if memory is full. +

            + +

            Side Effects None +

            + +

            Defined in cuddReorder.c + +
            +
            +static void 
            +ddSuppInteract(
            +  DdNode * f, 
            +  char * support 
            +)
            +
            +
            Performs a DFS from f. Uses the LSB of the then pointer + as visited flag. +

            + +

            Side Effects Accumulates in support the variables on which f depends. +

            + +

            Defined in cuddInteract.c + +
            +
            +static void 
            +ddSupportStep(
            +  DdNode * f, 
            +  int * support 
            +)
            +
            +
            Performs the recursive step of Cudd_Support. Performs a + DFS from f. The support is accumulated in supp as a side effect. Uses + the LSB of the then pointer as visited flag. +

            + +

            Side Effects None +

            + +

            See Also ddClearFlag + + +
            Defined in cuddUtil.c + +
            +
            +static Move * 
            +ddSwapAny(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Swaps any two variables. Returns the set of moves. +

            + +

            Side Effects None +

            + +

            Defined in cuddReorder.c + +
            +
            +static int 
            +ddSymmGroupMoveBackward(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Undoes the swap of two groups. x is assumed to be the + bottom variable of the first group. y is assumed to be the top + variable of the second group. Returns the number of keys in the table + if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddSymmetry.c + +
            +
            +static int 
            +ddSymmGroupMove(
            +  DdManager * table, 
            +  int  x, 
            +  int  y, 
            +  Move ** moves 
            +)
            +
            +
            Swaps two groups. x is assumed to be the bottom variable + of the first group. y is assumed to be the top variable of the second + group. Updates the list of moves. Returns the number of keys in the + table if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddSymmetry.c + +
            +
            +static int 
            +ddSymmSiftingAux(
            +  DdManager * table, 
            +  int  x, 
            +  int  xLow, 
            +  int  xHigh 
            +)
            +
            +
            Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is not part of a symmetry group. Returns 1 if + successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddSymmetry.c + +
            +
            +static int 
            +ddSymmSiftingBackward(
            +  DdManager * table, 
            +  Move * moves, 
            +  int  size 
            +)
            +
            +
            Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddSymmetry.c + +
            +
            +static int 
            +ddSymmSiftingConvAux(
            +  DdManager * table, 
            +  int  x, 
            +  int  xLow, 
            +  int  xHigh 
            +)
            +
            +
            Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is either an isolated variable, or it is the bottom of + a symmetry group. All symmetries may not have been found, because of + exceeded growth limit. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddSymmetry.c + +
            +
            +static Move * 
            +ddSymmSiftingDown(
            +  DdManager * table, 
            +  int  x, 
            +  int  xHigh 
            +)
            +
            +
            Moves x down until either it reaches the bound (xHigh) + or the size of the DD heap increases too much. Assumes that x is the + bottom of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; MV_OOM if memory is full. +

            + +

            Side Effects None +

            + +

            Defined in cuddSymmetry.c + +
            +
            +static Move * 
            +ddSymmSiftingUp(
            +  DdManager * table, 
            +  int  y, 
            +  int  xLow 
            +)
            +
            +
            Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much. Assumes that x is the top + of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; MV_OOM if memory is full. +

            + +

            Side Effects None +

            + +

            Defined in cuddSymmetry.c + +
            +
            +static void 
            +ddSymmSummary(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper, 
            +  int * symvars, 
            +  int * symgroups 
            +)
            +
            +
            Counts numbers of symmetric variables and symmetry + groups. +

            + +

            Side Effects None +

            + +

            Defined in cuddSymmetry.c + +
            +
            +static int 
            +ddSymmUniqueCompare(
            +  int * ptrX, 
            +  int * ptrY 
            +)
            +
            +
            Comparison function used by qsort to order the variables + according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared. +

            + +

            Side Effects None +

            + +

            Defined in cuddSymmetry.c + +
            +
            +static int 
            +ddTreeSiftingAux(
            +  DdManager * table, 
            +  MtrNode * treenode, 
            +  Cudd_ReorderingType  method 
            +)
            +
            +
            Recursively visits the group tree and reorders each + group in postorder fashion. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static Move* 
            +ddUndoMoves(
            +  DdManager * table, 
            +  Move * moves 
            +)
            +
            +
            Given a set of moves, returns the DD heap to the + order in effect before the moves. Returns 1 in case of success; + 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddLinear.c + +
            +
            +static int 
            +ddUniqueCompareGroup(
            +  int * ptrX, 
            +  int * ptrY 
            +)
            +
            +
            Comparison function used by qsort to order the variables + according to the number of keys in the subtables. Returns the + difference in number of keys between the two variables being + compared. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddUniqueCompare(
            +  int * ptrX, 
            +  int * ptrY 
            +)
            +
            +
            Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared. +

            + +

            Side Effects None +

            + +

            Defined in cuddReorder.c + +
            +
            +static void 
            +ddUpdateInteract(
            +  DdManager * table, 
            +  char * support 
            +)
            +
            +
            If support[i +

            + +

            Side Effects Clears support. +

            + +

            Defined in cuddInteract.c + +
            +
            +static int 
            +ddUpdateMtrTree(
            +  DdManager * table, 
            +  MtrNode * treenode, 
            +  int * perm, 
            +  int * invperm 
            +)
            +
            +
            Updates the BDD variable group tree before a shuffle. + Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects Changes the BDD variable group tree. +

            + +

            Defined in cuddReorder.c + +
            +
            +static int 
            +ddVarGroupCheck(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Checks for grouping of x and y. Returns 1 in + case of grouping; 0 otherwise. This function is used for lazy sifting. +

            + +

            Side Effects None +

            + +

            Defined in cuddGroup.c + +
            +
            +static int 
            +ddWindow2(
            +  DdManager * table, 
            +  int  low, 
            +  int  high 
            +)
            +
            +
            Reorders by applying a sliding window of width 2. + Tries both permutations of the variables in a window + that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddWindow.c + +
            +
            +static int 
            +ddWindow3(
            +  DdManager * table, 
            +  int  low, 
            +  int  high 
            +)
            +
            +
            Reorders by applying a sliding window of width 3. + Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddWindow.c + +
            +
            +static int 
            +ddWindow4(
            +  DdManager * table, 
            +  int  low, 
            +  int  high 
            +)
            +
            +
            Reorders by applying a sliding window of width 4. + Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddWindow.c + +
            +
            +static int 
            +ddWindowConv2(
            +  DdManager * table, 
            +  int  low, 
            +  int  high 
            +)
            +
            +
            Reorders by repeatedly applying a sliding window of width + 2. Tries both permutations of the variables in a window + that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddWindow.c + +
            +
            +static int 
            +ddWindowConv3(
            +  DdManager * table, 
            +  int  low, 
            +  int  high 
            +)
            +
            +
            Reorders by repeatedly applying a sliding window of width + 3. Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddWindow.c + +
            +
            +static int 
            +ddWindowConv4(
            +  DdManager * table, 
            +  int  low, 
            +  int  high 
            +)
            +
            +
            Reorders by repeatedly applying a sliding window of width + 4. Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddWindow.c + +
            +
            +static void 
            +debugCheckParent(
            +  DdManager * table, 
            +  DdNode * node 
            +)
            +
            +
            Searches all the subtables above node. Very expensive. + The same check is now implemented more efficiently in ddDebugCheck. +

            + +

            Side Effects None +

            + +

            See Also debugFindParent + + +
            Defined in cuddCheck.c + +
            +
            +static void 
            +debugFindParent(
            +  DdManager * table, 
            +  DdNode * node 
            +)
            +
            +
            Searches the subtables above node for its parents. +

            + +

            Side Effects None +

            + +

            Defined in cuddCheck.c + +
            +
            + 
            +double *þprobþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +double þmgþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +double þmgþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +double þmþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +double þquality0þminimum improvement for accepted changes when b=0(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +double þquality0þminimum improvement for accepted changes when b=0(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +double þqualityþminimum improvement for accepted changes(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +double þqualityþminimum improvement for accepted changes(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +double þqualityþminimum improvement for accepted changes(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +double þqualityþminimum improvement for accepted changes(
            +    
            +)
            +
            +
            +

            + +

            +
            +static int 
            +dp2(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  st_table * t 
            +)
            +
            +
            Performs the recursive step of cuddP. Returns 1 in case + of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +static DdTlcInfo * 
            +emptyClauseSet(
            +    
            +)
            +
            +
            Returns a pointer to an empty set of clauses if + successful; NULL otherwise. No bit vector for the phases is + allocated. +

            + +

            Side Effects None +

            + +

            Defined in cuddEssent.c + +
            +
            +static int 
            +equalp(
            +  DdHalfWord  var1a, 
            +  short  phase1a, 
            +  DdHalfWord  var1b, 
            +  short  phase1b, 
            +  DdHalfWord  var2a, 
            +  short  phase2a, 
            +  DdHalfWord  var2b, 
            +  short  phase2b 
            +)
            +
            +
            Returns true iff the two arguments are identical + clauses. Since literals are sorted, we only need to compare + literals in the same position. +

            + +

            Side Effects None +

            + +

            See Also beforep + + +
            Defined in cuddEssent.c + +
            +
            +static int 
            +find_best(
            +    
            +)
            +
            +
            Returns the index of the fittest individual. +

            + +

            Side Effects None +

            + +

            Defined in cuddGenetic.c + +
            +
            +static void 
            +fixVarTree(
            +  MtrNode * treenode, 
            +  int * perm, 
            +  int  size 
            +)
            +
            +
            Fixes a variable group tree. +

            + +

            Side Effects Changes the variable group tree. +

            + +

            Defined in cuddAPI.c + +
            +
            +static void 
            +freeMatrix(
            +  DdHalfWord ** matrix 
            +)
            +
            +
            Frees a two-dimensional matrix allocated by getMatrix. +

            + +

            Side Effects None +

            + +

            See Also getMatrix + + +
            Defined in cuddExact.c + +
            +
            +static enum st_retval 
            +freePathPair(
            +  char * key, 
            +  char * value, 
            +  char * arg 
            +)
            +
            +
            Frees the entries of the visited symbol table. Returns + ST_CONTINUE. +

            + +

            Side Effects None +

            + +

            Defined in cuddSat.c + +
            +
            +static NodeData * 
            +gatherInfoAux(
            +  DdNode * node, function to analyze
            +  ApproxInfo * info, info on BDD
            +  int  parity gather parity information
            +)
            +
            +
            Recursively counts minterms and computes reference + counts of each node in the BDD. Similar to the cuddCountMintermAux + which recursively counts the number of minterms for the dag rooted + at each node in terms of the total number of variables (max). It assumes + that the node pointer passed to it is regular and it maintains the + invariant. +

            + +

            Side Effects None +

            + +

            See Also gatherInfo + + +
            Defined in cuddApprox.c + +
            +
            +static ApproxInfo * 
            +gatherInfo(
            +  DdManager * dd, manager
            +  DdNode * node, function to be analyzed
            +  int  numVars, number of variables node depends on
            +  int  parity gather parity information
            +)
            +
            +
            Counts minterms and computes reference counts of each + node in the BDD. The minterm count is separately computed for the + node and its complement. This is to avoid cancellation + errors. Returns a pointer to the data structure holding the + information gathered if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddUnderApprox +gatherInfoAux + + +
            Defined in cuddApprox.c + +
            +
            +static int 
            +gcd(
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Returns the gcd of two integers. Uses the binary GCD + algorithm described in Cormen, Leiserson, and Rivest. +

            + +

            Side Effects None +

            + +

            Defined in cuddExact.c + +
            +
            +static DdNode * 
            +getCube(
            +  DdManager * manager, 
            +  st_table * visited, 
            +  DdNode * f, 
            +  int  cost 
            +)
            +
            +
            Build a BDD for a largest cube of f. + Given the minimum length from the root, and the minimum + lengths for each node (in visited), apply triangulation at each node. + Of the two children of each node on a shortest path, at least one is + on a shortest path. In case of ties the procedure chooses the THEN + children. + Returns a pointer to the cube BDD representing the path if + successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddSat.c + +
            +
            +static cuddPathPair 
            +getLargest(
            +  DdNode * root, 
            +  st_table * visited 
            +)
            +
            +
            Finds the size of the largest cube(s) in a DD. + This problem is translated into finding the shortest paths from a node + when both THEN and ELSE arcs have unit lengths. + Uses a local symbol table to store the lengths for each + node. Only the lengths for the regular nodes are entered in the table, + because those for the complement nodes are simply obtained by swapping + the two lenghts. + Returns a pair of lengths: the length of the shortest path to 1; + and the length of the shortest path to 0. This is done so as to take + complement arcs into account. +

            + +

            Side Effects none +

            + +

            Defined in cuddSat.c + +
            +
            +static int 
            +getLevelKeys(
            +  DdManager * table, 
            +  int  l 
            +)
            +
            +
            Returns the number of nodes at one level of a unique table. + The projection function, if isolated, is not counted. +

            + +

            Side Effects None +

            + +

            Defined in cuddExact.c + +
            +
            +static DdHalfWord ** 
            +getMatrix(
            +  int  rows, number of rows
            +  int  cols number of columns
            +)
            +
            +
            Allocates a two-dimensional matrix of ints. + Returns the pointer to the matrix if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also freeMatrix + + +
            Defined in cuddExact.c + +
            +
            +static int 
            +getMaxBinomial(
            +  int  n 
            +)
            +
            +
            Computes the maximum value of (n choose k) for a given + n. The maximum value occurs for k = n/2 when n is even, or k = + (n-1)/2 when n is odd. The algorithm used in this procedure avoids + intermediate overflow problems. It is based on the identity +
            +    binomial(n,k) = n/k * binomial(n-1,k-1).
            +  
            + Returns the computed value if successful; -1 if out of range. +

            + +

            Side Effects None +

            + +

            Defined in cuddExact.c + +
            +
            +static DdNode * 
            +getPath(
            +  DdManager * manager, 
            +  st_table * visited, 
            +  DdNode * f, 
            +  int * weight, 
            +  int  cost 
            +)
            +
            +
            Build a BDD for a shortest path of f. + Given the minimum length from the root, and the minimum + lengths for each node (in visited), apply triangulation at each node. + Of the two children of each node on a shortest path, at least one is + on a shortest path. In case of ties the procedure chooses the THEN + children. + Returns a pointer to the cube BDD representing the path if + successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddSat.c + +
            +
            +static cuddPathPair 
            +getShortest(
            +  DdNode * root, 
            +  int * cost, 
            +  int * support, 
            +  st_table * visited 
            +)
            +
            +
            Finds the length of the shortest path(s) in a DD. + Uses a local symbol table to store the lengths for each + node. Only the lengths for the regular nodes are entered in the table, + because those for the complement nodes are simply obtained by swapping + the two lenghts. + Returns a pair of lengths: the length of the shortest path to 1; + and the length of the shortest path to 0. This is done so as to take + complement arcs into account. +

            + +

            Side Effects Accumulates the support of the DD in support. +

            + +

            Defined in cuddSat.c + +
            +
            +static void 
            +hashDelete(
            +  DdLevelQueue * queue, 
            +  DdQueueItem * item 
            +)
            +
            +
            Removes an item from the hash table of a level queue. + Nothing is done if the item is not in the table. +

            + +

            Side Effects None +

            + +

            See Also cuddLevelQueueDequeue +hashInsert + + +
            Defined in cuddLevelQ.c + +
            +
            +static int 
            +hashInsert(
            +  DdLevelQueue * queue, 
            +  DdQueueItem * item 
            +)
            +
            +
            Inserts an item in the hash table of a level queue. Returns + 1 if successful; 0 otherwise. No check is performed to see if an item with + the same key is already in the hash table. +

            + +

            Side Effects None +

            + +

            See Also cuddLevelQueueEnqueue + + +
            Defined in cuddLevelQ.c + +
            +
            +static DdQueueItem * 
            +hashLookup(
            +  DdLevelQueue * queue, 
            +  void * key 
            +)
            +
            +
            Looks up a key in the hash table of a level queue. Returns + a pointer to the item with the given key if the key is found; NULL + otherwise. +

            + +

            Side Effects None +

            + +

            See Also cuddLevelQueueEnqueue +hashInsert + + +
            Defined in cuddLevelQ.c + +
            +
            +static int 
            +hashResize(
            +  DdLevelQueue * queue 
            +)
            +
            +
            Resizes the hash table of a level queue. Returns 1 if + successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also hashInsert + + +
            Defined in cuddLevelQ.c + +
            +
            +static int 
            +impliedp(
            +  DdHalfWord  var1, 
            +  short  phase1, 
            +  DdHalfWord  var2, 
            +  short  phase2, 
            +  BitVector * olv, 
            +  BitVector * olp 
            +)
            +
            +
            Returns true iff either literal of a clause is in a set + of literals. The first four arguments specify the clause. The + remaining two arguments specify the literal set. +

            + +

            Side Effects None +

            + +

            Defined in cuddEssent.c + +
            +
            +static int 
            +indexCompare(
            +  const void * a, 
            +  const void * b 
            +)
            +
            +
            Compares indices for qsort. Subtracting these integers + cannot produce overflow, because they are non-negative. +

            + +

            Side Effects None +

            + +

            Defined in cuddUtil.c + +
            +
            +static DdHalfWord * 
            +initSymmInfo(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Translates the symmetry information stored in the next + field of each subtable from level to indices. This procedure is called + immediately after symmetric sifting, so that the next fields are correct. + By translating this informaton in terms of indices, we make it independent + of subsequent reorderings. The format used is that of the next fields: + a circular list where each variable points to the next variable in the + same symmetry group. Only the entries between lower and upper are + considered. The procedure returns a pointer to an array + holding the symmetry information if successful; NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also checkSymmInfo + + +
            Defined in cuddExact.c + +
            +
            + 
            +int **þcubeþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int **þcubeþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int **þindicesþarray containing (on return) the indices(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int **þindicesþarray containing (on return) the indices(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int **þpathþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int **þpathþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int *þarrayþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int *þarrayþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int *þdigitsþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int *þdistanceþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int *þinputsþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int *þlengthþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int *þlengthþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int *þpermutationþrequired variable permutation(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int *þpermutationþrequired variable permutation(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int *þpermutþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int *þpermutþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int *þphase2þ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int *þweightþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þNþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þamountþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þarcviolationþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þbinaryDigitsþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þbitþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þbitþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þcycleþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þdigitsþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þdirectionþunder (0) or over (1) approximation(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þdirectionþunder (0) or over (1) approximation(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þhardlimitþflag: 1 if threshold is a hard limit(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þhardlimitþflag: 1 if threshold is a hard limit(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþvariable index(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþvariable index(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþvariable index(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþvariable index(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþvariable index(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþvariable index(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þindexþvariable index(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þiþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þiþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þiþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þiþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þiþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þiþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þiþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þiþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þiþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þiþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þiþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þiþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þkþnumber of minterms to find(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þlevelþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þlevelþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þminsizeþbound below which no reordering occurs(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þminsizeþbound below which no reordering occurs(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þmultiplicityþhow many ZDD variables are created for each BDD variable(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þmvarsþsize of maskVars(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þmvþ0: blif, 1: blif-MV(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þmvþ0: blif, 1: blif-MV(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnVarsþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnumberXoversþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnvarsþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnvarsþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnvarsþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnvarsþsize of the support of f(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnzþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnzþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnzþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþlength of both arrays(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþnumbers of unknowns(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþnumbers of unknowns(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþsize of vars(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþsize of the array(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþsize of the array(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þnþsize of the array(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þpairIndexþcorresponding variable index(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þpathþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þphaseþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þphaseþ1: positive; 0: negative(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þpopulationSizeþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þpowerþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þprecisionþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þprecisionþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þprþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þprþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þprþverbosity level(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þprþverbosity level(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þrecombþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þsmsþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þsmvþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þsymmviolationþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þsyþstep of column variables(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þsyþstep of column variables(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þthresholdþmaximum number of nodes in the subset(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þthresholdþmaximum number of nodes in the subset(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þthresholdþmaximum number of nodes in the superset(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þthresholdþmaximum number of nodes in the superset(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þtopþindex of top variable(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þupperBoundþdistance above which an approximate answer is OK(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þupperþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þupperþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þvarþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þvarþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þvarþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þvþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þvþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þxþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +int þyþcolumn index(
            +    
            +)
            +
            +
            +

            + +

            +
            +static int 
            +largest(
            +    
            +)
            +
            +
            Finds the largest DD in the population. If an order is + repeated, it avoids choosing the copy that is in the computed table + (it has repeat[i +

            + +

            Side Effects None +

            + +

            Defined in cuddGenetic.c + +
            +
            + 
            +long þseedþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +long þsizeþsize of the allocation that failed(
            +    
            +)
            +
            +
            +

            + +

            +
            +static int 
            +make_random(
            +  DdManager * table, 
            +  int  lower 
            +)
            +
            +
            Generates the random sequences for the initial population. + The sequences are permutations of the indices between lower and + upper in the current order. +

            + +

            Side Effects None +

            + +

            Defined in cuddGenetic.c + +
            +
            +static DdNode * 
            +mintermsFromUniverse(
            +  DdManager * manager, 
            +  DdNode ** vars, 
            +  int  numVars, 
            +  double  n, 
            +  int  index 
            +)
            +
            +
            Recursive procedure to extract n mintems from constant 1. +

            + +

            Side Effects None +

            + +

            Defined in cuddSplit.c + +
            +
            +static int 
            +oneliteralp(
            +  DdHalfWord  var 
            +)
            +
            +
            Returns true iff the argument is a one-literal clause. + A one-litaral clause has the constant FALSE as second literal. + Since the constant TRUE is never used, it is sufficient to test for + a constant. +

            + +

            Side Effects None +

            + +

            Defined in cuddEssent.c + +
            +
            +static void 
            +pushDown(
            +  DdHalfWord * order, 
            +  int  j, 
            +  int  level 
            +)
            +
            +
            Pushes a variable in the order down to position "level." +

            + +

            Side Effects None +

            + +

            Defined in cuddExact.c + +
            +
            +static int 
            +rand_int(
            +  int  a 
            +)
            +
            +
            Generates a random number between 0 and the integer a. +

            + +

            Side Effects None +

            + +

            Defined in cuddGenetic.c + +
            +
            +static double 
            +random_generator(
            +    
            +)
            +
            +
            Returns a double precision value between 0.0 and 1.0. +

            + +

            Side Effects None +

            + +

            Defined in cuddAnneal.c + +
            +
            +static int 
            +restoreOrder(
            +  DdManager * table, 
            +  int * array, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Restores the variable order in array by a series of sifts up. + Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddAnneal.c + +
            +
            +static int 
            +roulette(
            +  int * p1, 
            +  int * p2 
            +)
            +
            +
            Selects two distinct parents with the roulette wheel method. +

            + +

            Side Effects The indices of the selected parents are returned as side + effects. +

            + +

            Defined in cuddGenetic.c + +
            +
            +static DdNode * 
            +selectMintermsFromUniverse(
            +  DdManager * manager, 
            +  int * varSeen, 
            +  double  n 
            +)
            +
            +
            This function prepares an array of variables which have not been + encountered so far when traversing the procedure cuddSplitSetRecur. This + array is then used to extract the required number of minterms from a constant + 1. The algorithm guarantees that the size of BDD will be utmost log(n). +

            + +

            Side Effects None +

            + +

            Defined in cuddSplit.c + +
            +
            +static int 
            +sentinelp(
            +  DdHalfWord  var1, 
            +  DdHalfWord  var2 
            +)
            +
            +
            Returns true iff the argument is the sentinel clause. + A sentinel clause has both variables equal to 0. +

            + +

            Side Effects None +

            + +

            Defined in cuddEssent.c + +
            +
            +static DdNode * 
            +separateCube(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  CUDD_VALUE_TYPE * distance 
            +)
            +
            +
            Separates cube from distance. Returns the cube if + successful; NULL otherwise. +

            + +

            Side Effects The distance is returned as a side effect. +

            + +

            See Also cuddBddClosestCube +createResult + + +
            Defined in cuddPriority.c + +
            +
            +static int 
            +siftBackwardProb(
            +  DdManager * table, 
            +  Move * moves, 
            +  int  size, 
            +  double  temp 
            +)
            +
            +
            Otherwise, "tosses a coin" to decide whether to keep + the current configuration or return the DD to the original + one. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddAnneal.c + +
            +
            +static int 
            +sift_up(
            +  DdManager * table, 
            +  int  x, 
            +  int  x_low 
            +)
            +
            +
            Takes a variable from position x and sifts it up to + position x_low; x_low should be less than x. Returns 1 if successful; + 0 otherwise +

            + +

            Side Effects None +

            + +

            Defined in cuddGenetic.c + +
            +
            +static enum st_retval 
            +stPathTableDdFree(
            +  char * key, 
            +  char * value, 
            +  char * arg 
            +)
            +
            +
            None +

            + +

            Side Effects None +

            + +

            Defined in cuddSubsetSP.c + +
            +
            +static enum st_retval 
            +st_zdd_count_dbl_free(
            +  char * key, 
            +  char * value, 
            +  char * arg 
            +)
            +
            +
            Frees the memory associated with the computed table of + Cudd_zddCountDouble. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddCount.c + +
            +
            +static enum st_retval 
            +st_zdd_countfree(
            +  char * key, 
            +  char * value, 
            +  char * arg 
            +)
            +
            +
            Frees the memory associated with the computed table of + Cudd_zddCount. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddCount.c + +
            +
            +static int 
            +stopping_criterion(
            +  int  c1, 
            +  int  c2, 
            +  int  c3, 
            +  int  c4, 
            +  double  temp 
            +)
            +
            +
            If temperature is STOP_TEMP or there is no improvement + then terminates. Returns 1 if the termination criterion is met; 0 + otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddAnneal.c + +
            +
            +static DdTlcInfo * 
            +tlcInfoAlloc(
            +    
            +)
            +
            +
            Returns a pointer to a DdTlcInfo Structure if successful; + NULL otherwise. +

            + +

            Side Effects None +

            + +

            See Also Cudd_tlcInfoFree + + +
            Defined in cuddEssent.c + +
            +
            + 
            +unsigned int þfactorþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þhrþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þlimitþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þlimitþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þlimitþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þlimitþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þlimitþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þlimitþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þlutþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þmaxLiveþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þmcþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þmrþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þnextþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þpþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þsecondDenþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þtypeþMTR_DEFAULT or MTR_FIXED(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þtypeþMTR_DEFAULT or MTR_FIXED(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned int þupperBþupper bound(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned long þincreaseþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned long þmaxMemoryþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned long þmaxMemoryþtarget maximum memory occupation(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned long þstþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +unsigned long þtlþ(
            +    
            +)
            +
            +
            +

            + +

            +
            +static int 
            +updateEntry(
            +  DdManager * table, 
            +  DdHalfWord * order, 
            +  int  level, 
            +  int  cost, 
            +  DdHalfWord ** orders, 
            +  int * costs, 
            +  int  subsets, 
            +  char * mask, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Updates entry for a subset. Finds the subset, if it exists. + If the new order for the subset has lower cost, or if the subset did not + exist, it stores the new order and cost. Returns the number of subsets + currently in the table. +

            + +

            Side Effects None +

            + +

            Defined in cuddExact.c + +
            +
            +static void 
            +updateParity(
            +  DdNode * node, function to analyze
            +  ApproxInfo * info, info on BDD
            +  int  newparity new parity for node
            +)
            +
            +
            Recursively update the parity of the paths reaching a node. + Assumes that node is regular and propagates the invariant. +

            + +

            Side Effects None +

            + +

            See Also gatherInfoAux + + +
            Defined in cuddApprox.c + +
            +
            +static int 
            +updateRefs(
            +  DdManager * dd, 
            +  DdNode * f, 
            +  DdNode * skip, 
            +  ApproxInfo * info, 
            +  DdLevelQueue * queue 
            +)
            +
            +
            Update function reference counts to account for replacement. + Returns the number of nodes saved if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            See Also UAmarkNodes +RAmarkNodes +BAmarkNodes + + +
            Defined in cuddApprox.c + +
            +
            +static int 
            +updateUB(
            +  DdManager * table, 
            +  int  oldBound, 
            +  DdHalfWord * bestOrder, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Updates the upper bound and saves the best order seen so far. + Returns the current value of the upper bound. +

            + +

            Side Effects None +

            + +

            Defined in cuddExact.c + +
            +
            + 
            +void *þdataþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +void *þdataþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +void *þdataþ(
            +    
            +)
            +
            +
            +

            + +

            +
            +static void 
            +zddClearFlag(
            +  DdNode * f 
            +)
            +
            +
            Performs a DFS from f, clearing the LSB of the next + pointers. +

            + +

            Side Effects None +

            + +

            See Also zddSupportStep + + +
            Defined in cuddZddUtil.c + +
            +
            +static int 
            +zddCountInternalMtrNodes(
            +  DdManager * table, 
            +  MtrNode * treenode 
            +)
            +
            +
            Counts the number of internal nodes of the group tree. + Returns the count. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddGroup.c + +
            +
            +static void 
            +zddFindNodeHiLo(
            +  DdManager * table, 
            +  MtrNode * treenode, 
            +  int * lower, 
            +  int * upper 
            +)
            +
            +
            Finds the lower and upper bounds of the group represented + by treenode. The high and low fields of treenode are indices. From + those we need to derive the current positions, and find maximum and + minimum. +

            + +

            Side Effects The bounds are returned as side effects. +

            + +

            Defined in cuddZddGroup.c + +
            +
            +static void 
            +zddFixTree(
            +  DdManager * table, 
            +  MtrNode * treenode 
            +)
            +
            +
            Fixes the ZDD variable group tree after a + shuffle. Assumes that the order of the variables in a terminal node + has not been changed. +

            + +

            Side Effects Changes the ZDD variable group tree. +

            + +

            Defined in cuddZddReord.c + +
            +
            +static int 
            +zddGroupMoveBackward(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Undoes the swap two groups. Returns 1 in case of + success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddGroup.c + +
            +
            +static int 
            +zddGroupMove(
            +  DdManager * table, 
            +  int  x, 
            +  int  y, 
            +  Move ** moves 
            +)
            +
            +
            Swaps two groups and records the move. Returns the + number of keys in the DD table in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddGroup.c + +
            +
            +static int 
            +zddGroupSiftingAux(
            +  DdManager * table, 
            +  int  x, 
            +  int  xLow, 
            +  int  xHigh 
            +)
            +
            +
            Sifts one variable up and down until it has taken all + positions. Checks for aggregation. There may be at most two sweeps, + even if the group grows. Assumes that x is either an isolated + variable, or it is the bottom of a group. All groups may not have + been found. The variable being moved is returned to the best position + seen during sifting. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddGroup.c + +
            +
            +static int 
            +zddGroupSiftingBackward(
            +  DdManager * table, 
            +  Move * moves, 
            +  int  size 
            +)
            +
            +
            Determines the best position for a variables and returns + it there. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddGroup.c + +
            +
            +static int 
            +zddGroupSiftingDown(
            +  DdManager * table, 
            +  int  x, 
            +  int  xHigh, 
            +  Move ** moves 
            +)
            +
            +
            Sifts down a variable until it reaches position xHigh. + Assumes that x is the bottom of a group (or a singleton). Records + all the moves. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddGroup.c + +
            +
            +static int 
            +zddGroupSiftingUp(
            +  DdManager * table, 
            +  int  y, 
            +  int  xLow, 
            +  Move ** moves 
            +)
            +
            +
            Sifts up a variable until either it reaches position + xLow or the size of the DD heap increases too much. Assumes that y is + the top of a group (or a singleton). Checks y for aggregation to the + adjacent variables. Records all the moves that are appended to the + list of moves received as input and returned as a side effect. + Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddGroup.c + +
            +
            +static int 
            +zddGroupSifting(
            +  DdManager * table, 
            +  int  lower, 
            +  int  upper 
            +)
            +
            +
            Sifts from treenode->low to treenode->high. If + croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the + end of the initial sifting. If a group is created, it is then sifted + again. After sifting one variable, the group that contains it is + dissolved. Returns 1 in case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddGroup.c + +
            +
            +static void 
            +zddMergeGroups(
            +  DdManager * table, 
            +  MtrNode * treenode, 
            +  int  low, 
            +  int  high 
            +)
            +
            +
            Creates a single group from low to high and adjusts the + idex field of the tree node. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddGroup.c + +
            +
            +static DdNode * 
            +zddPortFromBddStep(
            +  DdManager * dd, 
            +  DdNode * B, 
            +  int  expected 
            +)
            +
            +
            Performs the recursive step of Cudd_zddPortFromBdd. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddPort.c + +
            +
            +static DdNode * 
            +zddPortToBddStep(
            +  DdManager * dd, manager
            +  DdNode * f, ZDD to be converted
            +  int  depth recursion depth
            +)
            +
            +
            Performs the recursive step of Cudd_zddPortToBdd. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddPort.c + +
            +
            +static void 
            +zddPrintCoverAux(
            +  DdManager * zdd, manager
            +  DdNode * node, current node
            +  int  level, depth in the recursion
            +  int * list current recursion path
            +)
            +
            +
            Performs the recursive step of Cudd_zddPrintCover. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddUtil.c + +
            +
            +static int 
            +zddReorderChildren(
            +  DdManager * table, 
            +  MtrNode * treenode, 
            +  Cudd_ReorderingType  method 
            +)
            +
            +
            Reorders the children of a group tree node according to + the options. After reordering puts all the variables in the group + and/or its descendents in a single group. This allows hierarchical + reordering. If the variables in the group do not exist yet, simply + does nothing. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddGroup.c + +
            +
            +static int 
            +zddReorderPostprocess(
            +  DdManager * table 
            +)
            +
            +
            Shrinks almost empty subtables at the end of reordering to + guarantee that they have a reasonable load factor. However, if there many + nodes are being reclaimed, then no resizing occurs. Returns 1 in case of + success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +static void 
            +zddReorderPreprocess(
            +  DdManager * table 
            +)
            +
            +
            Prepares the ZDD heap for dynamic reordering. Does + garbage collection, to guarantee that there are no dead nodes; + and clears the cache, which is invalidated by dynamic reordering. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +static int 
            +zddShuffle(
            +  DdManager * table, 
            +  int * permutation 
            +)
            +
            +
            Reorders ZDD variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. zddShuffle assumes that no + dead nodes are present. The reordering is achieved by a series of + upward sifts. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +static int 
            +zddSiftUp(
            +  DdManager * table, 
            +  int  x, 
            +  int  xLow 
            +)
            +
            +
            Takes a ZDD variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +static void 
            +zddSupportStep(
            +  DdNode * f, 
            +  int * support 
            +)
            +
            +
            Performs the recursive step of Cudd_zddSupport. Performs a + DFS from f. The support is accumulated in supp as a side effect. Uses + the LSB of the then pointer as visited flag. +

            + +

            Side Effects None +

            + +

            See Also zddClearFlag + + +
            Defined in cuddZddUtil.c + +
            +
            +static Move * 
            +zddSwapAny(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Swaps any two variables. Returns the set of moves. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddReord.c + +
            +
            +static int 
            +zddTreeSiftingAux(
            +  DdManager * table, 
            +  MtrNode * treenode, 
            +  Cudd_ReorderingType  method 
            +)
            +
            +
            Recursively visits the group tree and reorders each + group in postorder fashion. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddGroup.c + +
            +
            +static int 
            +zddUniqueCompareGroup(
            +  int * ptrX, 
            +  int * ptrY 
            +)
            +
            +
            Comparison function used by qsort to order the variables + according to the number of keys in the subtables. Returns the + difference in number of keys between the two variables being + compared. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddGroup.c + +
            +
            +static void 
            +zddVarToConst(
            +  DdNode * f, 
            +  DdNode ** gp, 
            +  DdNode ** hp, 
            +  DdNode * base, 
            +  DdNode * empty 
            +)
            +
            +
            Replaces variables with constants if possible (part of + canonical form). +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSetop.c + +
            +
            +static int 
            +zdd_group_move_backward(
            +  DdManager * table, 
            +  int  x, 
            +  int  y 
            +)
            +
            +
            Undoes the swap of two groups. x is assumed to be the + bottom variable of the first group. y is assumed to be the top + variable of the second group. Returns 1 if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSymm.c + +
            +
            +static int 
            +zdd_group_move(
            +  DdManager * table, 
            +  int  x, 
            +  int  y, 
            +  Move ** moves 
            +)
            +
            +
            Swaps two groups. x is assumed to be the bottom variable + of the first group. y is assumed to be the top variable of the second + group. Updates the list of moves. Returns the number of keys in the + table if successful; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSymm.c + +
            +
            +static void 
            +zdd_print_minterm_aux(
            +  DdManager * zdd, manager
            +  DdNode * node, current node
            +  int  level, depth in the recursion
            +  int * list current recursion path
            +)
            +
            +
            Performs the recursive step of Cudd_zddPrintMinterm. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddUtil.c + +
            +
            +static DdNode * 
            +zdd_subset0_aux(
            +  DdManager * zdd, 
            +  DdNode * P, 
            +  DdNode * zvar 
            +)
            +
            +
            Performs the recursive step of Cudd_zddSubset0. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSetop.c + +
            +
            +static DdNode * 
            +zdd_subset1_aux(
            +  DdManager * zdd, 
            +  DdNode * P, 
            +  DdNode * zvar 
            +)
            +
            +
            Performs the recursive step of Cudd_zddSubset1. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddSetop.c + +
            +
            +static int 
            +zp2(
            +  DdManager * zdd, 
            +  DdNode * f, 
            +  st_table * t 
            +)
            +
            +
            Performs the recursive step of cuddZddP. Returns 1 in + case of success; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddZddUtil.c + +
            +
            + 
            +þþ(
            +    
            +)
            +
            +
            +

            + +

            +
            + 
            +(
            +    
            +)
            +
            +
            Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions. +

            + +

            Side Effects None +

            + +

            See Also cuddAllocNode +cuddDynamicAllocNode +cuddDeallocMove + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions. +

            + +

            Side Effects None +

            + +

            See Also cuddDeallocNode +cuddDynamicAllocNode + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Adjusts the values of table fields controlling the. + sizes of subtables and computed table. If the computed table is too small + according to the new values, it is resized. +

            + +

            Side Effects Modifies manager fields. May resize computed table. +

            + +

            Defined in cuddTable.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Clears a bit vector. The parameter size gives the + number of bits. +

            + +

            Side Effects None +

            + +

            See Also bitVectorAlloc + + +
            Defined in cuddEssent.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Clears the 4 least significant bits of a pointer. +

            + +

            Side Effects none +

            + +

            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Comparison of a function to the i-th ADD variable. Returns 1 if + the function is the i-th ADD variable; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddCompose.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Comparison of a pair of functions to the i-th ADD + variable. Returns 1 if the functions are the i-th ADD variable and its + complement; 0 otherwise. +

            + +

            Side Effects None +

            + +

            Defined in cuddCompose.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Complements a DD if condition c is true; c should be + either 0 or 1, because it is used directly (for efficiency). If in + doubt on the values c may take, use "(c) ? Cudd_Not(node) : node". +

            + +

            Side Effects none +

            + +

            See Also Cudd_Not + + +
            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Complements a DD by flipping the complement attribute of + the pointer (the least significant bit). +

            + +

            Side Effects none +

            + +

            See Also Cudd_NotCond + + +
            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Computes hash function for keys of one operand. +

            + +

            Side Effects None +

            + +

            See Also ddLCHash3 +ddLCHash + + +
            Defined in cuddLCache.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Computes hash function for keys of three operands. +

            + +

            Side Effects None +

            + +

            See Also ddLCHash2 +ddLCHash + + +
            Defined in cuddLCache.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Computes hash function for keys of two operands. +

            + +

            Side Effects None +

            + +

            See Also ddLCHash3 +ddLCHash + + +
            Defined in cuddLCache.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Computes the absolute value of a number. +

            + +

            Side Effects none +

            + +

            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Computes the hash value for a local cache. Returns the + bucket index. +

            + +

            Side Effects None +

            + +

            Defined in cuddLCache.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Computes the maximum of two numbers. +

            + +

            Side Effects none +

            + +

            See Also ddMin + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Computes the minimum of two numbers. +

            + +

            Side Effects none +

            + +

            See Also ddMax + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Decreases the reference count of node. It is primarily + used in recursive procedures to decrease the ref count of a result + node before returning it. This accomplishes the goal of removing the + protection applied by a previous cuddRef. This being a macro, it is + faster than Cudd_Deref, but it cannot be used in constructs like + cuddDeref(a = b()). +

            + +

            Side Effects none +

            + +

            See Also Cudd_Deref + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL. + Furthermore, if x <= DD_MINUS_INF_VAL/2, x is set to + DD_MINUS_INF_VAL. Similarly, if DD_PLUS_INF_VAL/2 <= x, x is set to + DD_PLUS_INF_VAL. Normally this macro is a NOOP. However, if + HAVE_IEEE_754 is not defined, it makes sure that a value does not + get larger than infinity in absolute value, and once it gets to + infinity, stays there. If the value overflows before this macro is + applied, no recovery is possible. +

            + +

            Side Effects none +

            + +

            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Extract the least significant digit of a double digit. Used + in the manipulation of arbitrary precision integers. +

            + +

            Side Effects None +

            + +

            See Also DD_MSDIGIT + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Extract the most significant digit of a double digit. Used + in the manipulation of arbitrary precision integers. +

            + +

            Side Effects None +

            + +

            See Also DD_LSDIGIT + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Fast storage allocation for items in a hash table. The + first 4 bytes of a chunk contain a pointer to the next block; the + rest contains DD_MEM_CHUNK spaces for hash items. Returns a pointer to + a new item if successful; NULL is memory is full. +

            + +

            Side Effects None +

            + +

            See Also cuddAllocNode +cuddDynamicAllocNode + + +
            Defined in cuddLCache.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Finds the current position of ZDD variable index in the + order. This macro duplicates the functionality of Cudd_ReadPermZdd, + but it does not check for out-of-bounds indices and it is more + efficient. +

            + +

            Side Effects none +

            + +

            See Also Cudd_ReadPermZdd + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Finds the current position of variable index in the + order. This macro duplicates the functionality of Cudd_ReadPerm, + but it does not check for out-of-bounds indices and it is more + efficient. +

            + +

            Side Effects none +

            + +

            See Also Cudd_ReadPerm + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Hash function for the cache for functions with two + operands. +

            + +

            Side Effects none +

            + +

            See Also ddHash +ddCHash + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Hash function for the cache. +

            + +

            Side Effects none +

            + +

            See Also ddHash +ddCHash2 + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Hash function for the table of a level queue. +

            + +

            Side Effects None +

            + +

            See Also hashInsert +hashLookup +hashDelete + + +
            Defined in cuddLevelQ.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Hash function for the unique table. +

            + +

            Side Effects none +

            + +

            See Also ddCHash +ddCHash2 + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Increases the reference count of a node, if it is not + saturated. This being a macro, it is faster than Cudd_Ref, but it + cannot be used in constructs like cuddRef(a = b()). +

            + +

            Side Effects none +

            + +

            See Also Cudd_Ref + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Iterates over the cubes of a decision diagram f. +
              +
            • DdManager *manager; +
            • DdNode *f; +
            • DdGen *gen; +
            • int *cube; +
            • CUDD_VALUE_TYPE value; +
            + Cudd_ForeachCube allocates and frees the generator. Therefore the + application should not try to do that. Also, the cube is freed at the + end of Cudd_ForeachCube and hence is not available outside of the loop.

            + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing. +

            + +

            Side Effects none +

            + +

            See Also Cudd_ForeachNode +Cudd_FirstCube +Cudd_NextCube +Cudd_GenFree +Cudd_IsGenEmpty +Cudd_AutodynDisable + + +
            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Iterates over the nodes of a decision diagram f. +
              +
            • DdManager *manager; +
            • DdNode *f; +
            • DdGen *gen; +
            • DdNode *node; +
            + The nodes are returned in a seemingly random order. + Cudd_ForeachNode allocates and frees the generator. Therefore the + application should not try to do that.

            + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing. +

            + +

            Side Effects none +

            + +

            See Also Cudd_ForeachCube +Cudd_FirstNode +Cudd_NextNode +Cudd_GenFree +Cudd_IsGenEmpty +Cudd_AutodynDisable + + +
            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Iterates over the paths of a ZDD f. +
              +
            • DdManager *manager; +
            • DdNode *f; +
            • DdGen *gen; +
            • int *path; +
            + Cudd_zddForeachPath allocates and frees the generator. Therefore the + application should not try to do that. Also, the path is freed at the + end of Cudd_zddForeachPath and hence is not available outside of the loop.

            + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing. +

            + +

            Side Effects none +

            + +

            See Also Cudd_zddFirstPath +Cudd_zddNextPath +Cudd_GenFree +Cudd_IsGenEmpty +Cudd_AutodynDisable + + +
            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Iterates over the primes of a Boolean function producing + a prime and irredundant cover. +
              +
            • DdManager *manager; +
            • DdNode *l; +
            • DdNode *u; +
            • DdGen *gen; +
            • int *cube; +
            + The Boolean function is described by an upper bound and a lower bound. If + the function is completely specified, the two bounds coincide. + Cudd_ForeachPrime allocates and frees the generator. Therefore the + application should not try to do that. Also, the cube is freed at the + end of Cudd_ForeachPrime and hence is not available outside of the loop.

            + CAUTION: It is a mistake to change a diagram on which generation is ongoing. +

            + +

            Side Effects none +

            + +

            See Also Cudd_ForeachCube +Cudd_FirstPrime +Cudd_NextPrime +Cudd_GenFree +Cudd_IsGenEmpty + + +
            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Outputs a line of stats if DD_COUNT and DD_STATS are + defined. Increments the number of recursive calls if DD_COUNT is + defined. +

            + +

            Side Effects None +

            + +

            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Performs the left rotation for red/black trees. +

            + +

            Side Effects None +

            + +

            See Also cuddRotateRight + + +
            Defined in cuddTable.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Performs the right rotation for red/black trees. +

            + +

            Side Effects None +

            + +

            See Also cuddRotateLeft + + +
            Defined in cuddTable.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns 1 if a pointer is complemented. +

            + +

            Side Effects none +

            + +

            See Also Cudd_Regular +Cudd_Complement + + +
            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns 1 if the absolute value of the difference of the two + arguments x and y is less than e. +

            + +

            Side Effects none +

            + +

            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns 1 if the node is a constant node (rather than an + internal node). All constant nodes have the same index + (CUDD_CONST_INDEX). The pointer passed to Cudd_IsConstant may be either + regular or complemented. +

            + +

            Side Effects none +

            + +

            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns 1 if the node is a constant node (rather than an + internal node). All constant nodes have the same index + (CUDD_CONST_INDEX). The pointer passed to cuddIsConstant must be regular. +

            + +

            Side Effects none +

            + +

            See Also Cudd_IsConstant + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the arithmetic 0 constant node. This is different + from the logical zero. The latter is obtained by + Cudd_Not(DD_ONE(dd)). +

            + +

            Side Effects none +

            + +

            See Also DD_ONE +Cudd_Not +DD_PLUS_INFINITY +DD_MINUS_INFINITY + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the average fitness of the population. +

            + +

            Side Effects None +

            + +

            Defined in cuddGenetic.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the complemented version of a pointer. +

            + +

            Side Effects none +

            + +

            See Also Cudd_Regular +Cudd_IsComplement + + +
            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the constant 1 node. +

            + +

            Side Effects none +

            + +

            See Also DD_ZERO +DD_PLUS_INFINITY +DD_MINUS_INFINITY + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the current position in the order of variable + index. This macro is obsolete and is kept for compatibility. New + applications should use Cudd_ReadPerm instead. +

            + +

            Side Effects none +

            + +

            See Also Cudd_ReadPerm + + +
            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the else child of an internal node. If + node is a constant node, the result is unpredictable. + The pointer passed to cuddE must be regular. +

            + +

            Side Effects none +

            + +

            See Also Cudd_E + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the else child of an internal node. If + node is a constant node, the result is unpredictable. +

            + +

            Side Effects none +

            + +

            See Also Cudd_T +Cudd_V + + +
            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the i-th entry of a bit vector. +

            + +

            Side Effects None +

            + +

            See Also bitVectorSet + + +
            Defined in cuddEssent.c + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the minus infinity constant node. +

            + +

            Side Effects none +

            + +

            See Also DD_ONE +DD_ZERO +DD_PLUS_INFINITY + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the plus infinity constant node. +

            + +

            Side Effects none +

            + +

            See Also DD_ONE +DD_ZERO +DD_MINUS_INFINITY + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the regular version of a pointer. +

            + +

            Side Effects none +

            + +

            See Also Cudd_Complement +Cudd_IsComplement + + +
            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the then child of an internal node. If + node is a constant node, the result is unpredictable. + The pointer passed to cuddT must be regular. +

            + +

            Side Effects none +

            + +

            See Also Cudd_T + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the then child of an internal node. If + node is a constant node, the result is unpredictable. +

            + +

            Side Effects none +

            + +

            See Also Cudd_E +Cudd_V + + +
            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the value of a constant node. If + node is an internal node, the result is unpredictable. + The pointer passed to cuddV must be regular. +

            + +

            Side Effects none +

            + +

            See Also Cudd_V + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Returns the value of a constant node. If + node is an internal node, the result is unpredictable. +

            + +

            Side Effects none +

            + +

            See Also Cudd_T +Cudd_E + + +
            Defined in cudd.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Saturating decrement operator. +

            + +

            Side Effects none +

            + +

            See Also cuddSatInc + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Saturating increment operator. +

            + +

            Side Effects none +

            + +

            See Also cuddSatDec + + +
            Defined in cuddInt.h + +
            +
            + 
            +(
            +    
            +)
            +
            +
            Sets the i-th entry of a bit vector to a value. +

            + +

            Side Effects None +

            + +

            See Also bitVectorRead + + +
            Defined in cuddEssent.c + + +
        +
        +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllFile.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllFile.html new file mode 100644 index 000000000..9293943d3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllFile.html @@ -0,0 +1,4876 @@ + +The cudd package: files + + +
        +
        cuddAddAbs.c +
        Quantification functions for ADDs. +
        cuddAddApply.c +
        Apply functions for ADDs and their operators. +
        cuddAddFind.c +
        Functions to find maximum and minimum in an ADD and to + extract the i-th bit. +
        cuddAddInv.c +
        Function to compute the scalar inverse of an ADD. +
        cuddAddIte.c +
        ADD ITE function and satellites. +
        cuddAddNeg.c +
        Function to compute the negation of an ADD. +
        cuddAddWalsh.c +
        Functions that generate Walsh matrices and residue + functions in ADD form. +
        cuddAndAbs.c +
        Combined AND and existential abstraction for BDDs +
        cuddAnneal.c +
        Reordering of DDs based on simulated annealing +
        cuddApa.c +
        Arbitrary precision arithmetic functions. +
        cuddAPI.c +
        Application interface functions. +
        cuddApprox.c +
        Procedures to approximate a given BDD. +
        cuddBddAbs.c +
        Quantification functions for BDDs. +
        cuddBddCorr.c +
        Correlation between BDDs. +
        cuddBddIte.c +
        BDD ITE function and satellites. +
        cuddBridge.c +
        Translation from BDD to ADD and vice versa and transfer between + different managers. +
        cuddCache.c +
        Functions for cache insertion and lookup. +
        cuddCheck.c +
        Functions to check consistency of data structures. +
        cuddClip.c +
        Clipping functions. +
        cuddCof.c +
        Cofactoring functions. +
        cuddCompose.c +
        Functional composition and variable permutation of DDs. +
        cuddDecomp.c +
        Functions for BDD decomposition. +
        cuddEssent.c +
        Functions for the detection of essential variables. +
        cuddExact.c +
        Functions for exact variable reordering. +
        cuddExport.c +
        Export functions. +
        cuddGenCof.c +
        Generalized cofactors for BDDs and ADDs. +
        cuddGenetic.c +
        Genetic algorithm for variable reordering. +
        cuddGroup.c +
        Functions for group sifting. +
        cuddHarwell.c +
        Function to read a matrix in Harwell format. +
        cuddInit.c +
        Functions to initialize and shut down the DD manager. +
        cuddInteract.c +
        Functions to manipulate the variable interaction matrix. +
        cuddLCache.c +
        Functions for local caches. +
        cuddLevelQ.c +
        Procedure to manage level queues. +
        cuddLinear.c +
        Functions for DD reduction by linear transformations. +
        cuddLiteral.c +
        Functions for manipulation of literal sets represented by + BDDs. +
        cuddMatMult.c +
        Matrix multiplication functions. +
        cuddPriority.c +
        Priority functions. +
        cuddRead.c +
        Functions to read in a matrix +
        cuddRef.c +
        Functions that manipulate the reference counts. +
        cuddReorder.c +
        Functions for dynamic variable reordering. +
        cuddSat.c +
        Functions for the solution of satisfiability related problems. +
        cuddSign.c +
        Computation of signatures. +
        cuddSolve.c +
        Boolean equation solver and related functions. +
        cuddSplit.c +
        Returns a subset of minterms from a boolean function. +
        cuddSubsetHB.c +
        Procedure to subset the given BDD by choosing the heavier + branches. +
        cuddSubsetSP.c +
        Procedure to subset the given BDD choosing the shortest paths + (largest cubes) in the BDD. +
        cuddSymmetry.c +
        Functions for symmetry-based variable reordering. +
        cuddTable.c +
        Unique table management functions. +
        cuddUtil.c +
        Utility functions. +
        cuddWindow.c +
        Functions for variable reordering by window permutation. +
        cuddZddCount.c +
        Procedures to count the number of minterms of a ZDD. +
        cuddZddFuncs.c +
        Functions to manipulate covers represented as ZDDs. +
        cuddZddGroup.c +
        Functions for ZDD group sifting. +
        cuddZddIsop.c +
        Functions to find irredundant SOP covers as ZDDs from BDDs. +
        cuddZddLin.c +
        Procedures for dynamic variable ordering of ZDDs. +
        cuddZddMisc.c +
        Miscellaneous utility functions for ZDDs. +
        cuddZddPort.c +
        Functions that translate BDDs to ZDDs. +
        cuddZddReord.c +
        Procedures for dynamic variable ordering of ZDDs. +
        cuddZddSetop.c +
        Set operations on ZDDs. +
        cuddZddSymm.c +
        Functions for symmetry-based ZDD variable reordering. +
        cuddZddUtil.c +
        Utility functions for ZDDs. +

        +

        cuddAddAbs.c

        +Quantification functions for ADDs.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_addExistAbstract() +
        • Cudd_addUnivAbstract() +
        • Cudd_addOrAbstract() +
        + Internal procedures included in this module: +
          +
        • cuddAddExistAbstractRecur() +
        • cuddAddUnivAbstractRecur() +
        • cuddAddOrAbstractRecur() +
        + Static procedures included in this module: +
          +
        • addCheckPositiveCube() +

        +

        +
        Cudd_addExistAbstract() +
        Existentially Abstracts all the variables in cube from f. + +
        Cudd_addUnivAbstract() +
        Universally Abstracts all the variables in cube from f. + +
        Cudd_addOrAbstract() +
        Disjunctively abstracts all the variables in cube from the + 0-1 ADD f. + +
        cuddAddExistAbstractRecur() +
        Performs the recursive step of Cudd_addExistAbstract. + +
        cuddAddUnivAbstractRecur() +
        Performs the recursive step of Cudd_addUnivAbstract. + +
        cuddAddOrAbstractRecur() +
        Performs the recursive step of Cudd_addOrAbstract. + +
        addCheckPositiveCube() +
        Checks whether cube is an ADD representing the product + of positive literals. + +
        +
        +

        cuddAddApply.c

        +Apply functions for ADDs and their operators.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_addApply() +
        • Cudd_addMonadicApply() +
        • Cudd_addPlus() +
        • Cudd_addTimes() +
        • Cudd_addThreshold() +
        • Cudd_addSetNZ() +
        • Cudd_addDivide() +
        • Cudd_addMinus() +
        • Cudd_addMinimum() +
        • Cudd_addMaximum() +
        • Cudd_addOneZeroMaximum() +
        • Cudd_addDiff() +
        • Cudd_addAgreement() +
        • Cudd_addOr() +
        • Cudd_addNand() +
        • Cudd_addNor() +
        • Cudd_addXor() +
        • Cudd_addXnor() +
        + Internal procedures included in this module: +
          +
        • cuddAddApplyRecur() +
        • cuddAddMonadicApplyRecur() +

        +

        +
        Cudd_addApply() +
        Applies op to the corresponding discriminants of f and g. + +
        Cudd_addPlus() +
        Integer and floating point addition. + +
        Cudd_addTimes() +
        Integer and floating point multiplication. + +
        Cudd_addThreshold() +
        f if f>=g; 0 if f<g. + +
        Cudd_addSetNZ() +
        This operator sets f to the value of g wherever g != 0. + +
        Cudd_addDivide() +
        Integer and floating point division. + +
        Cudd_addMinus() +
        Integer and floating point subtraction. + +
        Cudd_addMinimum() +
        Integer and floating point min. + +
        Cudd_addMaximum() +
        Integer and floating point max. + +
        Cudd_addOneZeroMaximum() +
        Returns 1 if f > g and 0 otherwise. + +
        Cudd_addDiff() +
        Returns plusinfinity if f=g; returns min(f,g) if f!=g. + +
        Cudd_addAgreement() +
        f if f==g; background if f!=g. + +
        Cudd_addOr() +
        Disjunction of two 0-1 ADDs. + +
        Cudd_addNand() +
        NAND of two 0-1 ADDs. + +
        Cudd_addNor() +
        NOR of two 0-1 ADDs. + +
        Cudd_addXor() +
        XOR of two 0-1 ADDs. + +
        Cudd_addXnor() +
        XNOR of two 0-1 ADDs. + +
        Cudd_addMonadicApply() +
        Applies op to the discriminants of f. + +
        Cudd_addLog() +
        Natural logarithm of an ADD. + +
        cuddAddApplyRecur() +
        Performs the recursive step of Cudd_addApply. + +
        cuddAddMonadicApplyRecur() +
        Performs the recursive step of Cudd_addMonadicApply. + +
        +
        +

        cuddAddFind.c

        +Functions to find maximum and minimum in an ADD and to + extract the i-th bit.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_addFindMax() +
        • Cudd_addFindMin() +
        • Cudd_addIthBit() +
        + Static functions included in this module: +
          +
        • addDoIthBit() +

        +

        +
        Cudd_addFindMax() +
        Finds the maximum discriminant of f. + +
        Cudd_addFindMin() +
        Finds the minimum discriminant of f. + +
        Cudd_addIthBit() +
        Extracts the i-th bit from an ADD. + +
        addDoIthBit() +
        Performs the recursive step for Cudd_addIthBit. + +
        +
        +

        cuddAddInv.c

        +Function to compute the scalar inverse of an ADD.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_addScalarInverse() +
        + Internal procedures included in this module: +
          +
        • cuddAddScalarInverseRecur() +

        +

        +
        Cudd_addScalarInverse() +
        Computes the scalar inverse of an ADD. + +
        cuddAddScalarInverseRecur() +
        Performs the recursive step of addScalarInverse. + +
        +
        +

        cuddAddIte.c

        +ADD ITE function and satellites.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_addIte() +
        • Cudd_addIteConstant() +
        • Cudd_addEvalConst() +
        • Cudd_addCmpl() +
        • Cudd_addLeq() +
        + Internal procedures included in this module: +
          +
        • cuddAddIteRecur() +
        • cuddAddCmplRecur() +
        + Static procedures included in this module: +
          +
        • addVarToConst() +

        +

        +
        Cudd_addIte() +
        Implements ITE(f,g,h). + +
        Cudd_addIteConstant() +
        Implements ITEconstant for ADDs. + +
        Cudd_addEvalConst() +
        Checks whether ADD g is constant whenever ADD f is 1. + +
        Cudd_addCmpl() +
        Computes the complement of an ADD a la C language. + +
        Cudd_addLeq() +
        Determines whether f is less than or equal to g. + +
        cuddAddIteRecur() +
        Implements the recursive step of Cudd_addIte(f,g,h). + +
        cuddAddCmplRecur() +
        Performs the recursive step of Cudd_addCmpl. + +
        addVarToConst() +
        Replaces variables with constants if possible (part of + canonical form). + +
        +
        +

        cuddAddNeg.c

        +Function to compute the negation of an ADD.

        +By: Fabio Somenzi, Balakrishna Kumthekar

        +External procedures included in this module: +

          +
        • Cudd_addNegate() +
        • Cudd_addRoundOff() +
        + Internal procedures included in this module: +
          +
        • cuddAddNegateRecur() +
        • cuddAddRoundOffRecur() +

        +

        +
        Cudd_addNegate() +
        Computes the additive inverse of an ADD. + +
        Cudd_addRoundOff() +
        Rounds off the discriminants of an ADD. + +
        cuddAddNegateRecur() +
        Implements the recursive step of Cudd_addNegate. + +
        cuddAddRoundOffRecur() +
        Implements the recursive step of Cudd_addRoundOff. + +
        +
        +

        cuddAddWalsh.c

        +Functions that generate Walsh matrices and residue + functions in ADD form.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_addWalsh() +
        • Cudd_addResidue() +
        + Static procedures included in this module: +
          +
        • addWalshInt() +

        +

        +
        Cudd_addWalsh() +
        Generates a Walsh matrix in ADD form. + +
        Cudd_addResidue() +
        Builds an ADD for the residue modulo m of an n-bit + number. + +
        addWalshInt() +
        Implements the recursive step of Cudd_addWalsh. + +
        +
        +

        cuddAndAbs.c

        +Combined AND and existential abstraction for BDDs

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_bddAndAbstract() +
        • Cudd_bddAndAbstractLimit() +
        + Internal procedures included in this module: +
          +
        • cuddBddAndAbstractRecur() +

        +

        +
        Cudd_bddAndAbstract() +
        Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
        Cudd_bddAndAbstractLimit() +
        Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. Returns NULL if too many nodes are required. + +
        cuddBddAndAbstractRecur() +
        Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
        +
        +

        cuddAnneal.c

        +Reordering of DDs based on simulated annealing

        +By: Jae-Young Jang, Jorgen Sivesind

        +Internal procedures included in this file: +

          +
        • cuddAnnealing() +
        + Static procedures included in this file: +
          +
        • stopping_criterion() +
        • random_generator() +
        • ddExchange() +
        • ddJumpingAux() +
        • ddJumpingUp() +
        • ddJumpingDown() +
        • siftBackwardProb() +
        • copyOrder() +
        • restoreOrder() +

        +

        +
        cuddAnnealing() +
        Get new variable-order by simulated annealing algorithm. + +
        stopping_criterion() +
        Checks termination condition. + +
        random_generator() +
        Random number generator. + +
        ddExchange() +
        This function is for exchanging two variables, x and y. + +
        ddJumpingAux() +
        Moves a variable to a specified position. + +
        ddJumpingUp() +
        This function is for jumping up. + +
        ddJumpingDown() +
        This function is for jumping down. + +
        siftBackwardProb() +
        Returns the DD to the best position encountered during + sifting if there was improvement. + +
        copyOrder() +
        Copies the current variable order to array. + +
        restoreOrder() +
        Restores the variable order in array by a series of sifts up. + +
        +
        +

        cuddApa.c

        +Arbitrary precision arithmetic functions.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_ApaNumberOfDigits() +
        • Cudd_NewApaNumber() +
        • Cudd_ApaCopy() +
        • Cudd_ApaAdd() +
        • Cudd_ApaSubtract() +
        • Cudd_ApaShortDivision() +
        • Cudd_ApaIntDivision() +
        • Cudd_ApaShiftRight() +
        • Cudd_ApaSetToLiteral() +
        • Cudd_ApaPowerOfTwo() +
        • Cudd_ApaCompare() +
        • Cudd_ApaCompareRatios() +
        • Cudd_ApaPrintHex() +
        • Cudd_ApaPrintDecimal() +
        • Cudd_ApaPrintExponential() +
        • Cudd_ApaCountMinterm() +
        • Cudd_ApaPrintMinterm() +
        • Cudd_ApaPrintMintermExp() +
        • Cudd_ApaPrintDensity() +
        + Static procedures included in this module: +
          +
        • cuddApaCountMintermAux() +
        • cuddApaStCountfree() +

        +

        +
        Cudd_ApaNumberOfDigits() +
        Finds the number of digits for an arbitrary precision + integer. + +
        Cudd_NewApaNumber() +
        Allocates memory for an arbitrary precision integer. + +
        Cudd_ApaCopy() +
        Makes a copy of an arbitrary precision integer. + +
        Cudd_ApaAdd() +
        Adds two arbitrary precision integers. + +
        Cudd_ApaSubtract() +
        Subtracts two arbitrary precision integers. + +
        Cudd_ApaShortDivision() +
        Divides an arbitrary precision integer by a digit. + +
        Cudd_ApaIntDivision() +
        Divides an arbitrary precision integer by an integer. + +
        Cudd_ApaShiftRight() +
        Shifts right an arbitrary precision integer by one binary + place. + +
        Cudd_ApaSetToLiteral() +
        Sets an arbitrary precision integer to a one-digit literal. + +
        Cudd_ApaPowerOfTwo() +
        Sets an arbitrary precision integer to a power of two. + +
        Cudd_ApaCompare() +
        Compares two arbitrary precision integers. + +
        Cudd_ApaCompareRatios() +
        Compares the ratios of two arbitrary precision integers to two + unsigned ints. + +
        Cudd_ApaPrintHex() +
        Prints an arbitrary precision integer in hexadecimal format. + +
        Cudd_ApaPrintDecimal() +
        Prints an arbitrary precision integer in decimal format. + +
        Cudd_ApaPrintExponential() +
        Prints an arbitrary precision integer in exponential format. + +
        Cudd_ApaCountMinterm() +
        Counts the number of minterms of a DD. + +
        Cudd_ApaPrintMinterm() +
        Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic. + +
        Cudd_ApaPrintMintermExp() +
        Prints the number of minterms of a BDD or ADD in exponential + format using arbitrary precision arithmetic. + +
        Cudd_ApaPrintDensity() +
        Prints the density of a BDD or ADD using + arbitrary precision arithmetic. + +
        cuddApaCountMintermAux() +
        Performs the recursive step of Cudd_ApaCountMinterm. + +
        cuddApaStCountfree() +
        Frees the memory used to store the minterm counts recorded + in the visited table. + +
        +
        +

        cuddAPI.c

        +Application interface functions.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_addNewVar() +
        • Cudd_addNewVarAtLevel() +
        • Cudd_bddNewVar() +
        • Cudd_bddNewVarAtLevel() +
        • Cudd_addIthVar() +
        • Cudd_bddIthVar() +
        • Cudd_zddIthVar() +
        • Cudd_zddVarsFromBddVars() +
        • Cudd_addConst() +
        • Cudd_IsNonConstant() +
        • Cudd_ReadStartTime() +
        • Cudd_ReadElapsedTime() +
        • Cudd_SetStartTime() +
        • Cudd_ResetStartTime() +
        • Cudd_ReadTimeLimit() +
        • Cudd_SetTimeLimit() +
        • Cudd_UpdateTimeLimit() +
        • Cudd_IncreaseTimeLimit() +
        • Cudd_UnsetTimeLimit() +
        • Cudd_TimeLimited() +
        • Cudd_AutodynEnable() +
        • Cudd_AutodynDisable() +
        • Cudd_ReorderingStatus() +
        • Cudd_AutodynEnableZdd() +
        • Cudd_AutodynDisableZdd() +
        • Cudd_ReorderingStatusZdd() +
        • Cudd_zddRealignmentEnabled() +
        • Cudd_zddRealignEnable() +
        • Cudd_zddRealignDisable() +
        • Cudd_bddRealignmentEnabled() +
        • Cudd_bddRealignEnable() +
        • Cudd_bddRealignDisable() +
        • Cudd_ReadOne() +
        • Cudd_ReadZddOne() +
        • Cudd_ReadZero() +
        • Cudd_ReadLogicZero() +
        • Cudd_ReadPlusInfinity() +
        • Cudd_ReadMinusInfinity() +
        • Cudd_ReadBackground() +
        • Cudd_SetBackground() +
        • Cudd_ReadCacheSlots() +
        • Cudd_ReadCacheUsedSlots() +
        • Cudd_ReadCacheLookUps() +
        • Cudd_ReadCacheHits() +
        • Cudd_ReadMinHit() +
        • Cudd_SetMinHit() +
        • Cudd_ReadLooseUpTo() +
        • Cudd_SetLooseUpTo() +
        • Cudd_ReadMaxCache() +
        • Cudd_ReadMaxCacheHard() +
        • Cudd_SetMaxCacheHard() +
        • Cudd_ReadSize() +
        • Cudd_ReadSlots() +
        • Cudd_ReadUsedSlots() +
        • Cudd_ExpectedUsedSlots() +
        • Cudd_ReadKeys() +
        • Cudd_ReadDead() +
        • Cudd_ReadMinDead() +
        • Cudd_ReadReorderings() +
        • Cudd_ReadMaxReorderings() +
        • Cudd_SetMaxReorderings() +
        • Cudd_ReadReorderingTime() +
        • Cudd_ReadGarbageCollections() +
        • Cudd_ReadGarbageCollectionTime() +
        • Cudd_ReadNodesFreed() +
        • Cudd_ReadNodesDropped() +
        • Cudd_ReadUniqueLookUps() +
        • Cudd_ReadUniqueLinks() +
        • Cudd_ReadSiftMaxVar() +
        • Cudd_SetSiftMaxVar() +
        • Cudd_ReadMaxGrowth() +
        • Cudd_SetMaxGrowth() +
        • Cudd_ReadMaxGrowthAlternate() +
        • Cudd_SetMaxGrowthAlternate() +
        • Cudd_ReadReorderingCycle() +
        • Cudd_SetReorderingCycle() +
        • Cudd_ReadTree() +
        • Cudd_SetTree() +
        • Cudd_FreeTree() +
        • Cudd_ReadZddTree() +
        • Cudd_SetZddTree() +
        • Cudd_FreeZddTree() +
        • Cudd_NodeReadIndex() +
        • Cudd_ReadPerm() +
        • Cudd_ReadInvPerm() +
        • Cudd_ReadVars() +
        • Cudd_ReadEpsilon() +
        • Cudd_SetEpsilon() +
        • Cudd_ReadGroupCheck() +
        • Cudd_SetGroupcheck() +
        • Cudd_GarbageCollectionEnabled() +
        • Cudd_EnableGarbageCollection() +
        • Cudd_DisableGarbageCollection() +
        • Cudd_DeadAreCounted() +
        • Cudd_TurnOnCountDead() +
        • Cudd_TurnOffCountDead() +
        • Cudd_ReadRecomb() +
        • Cudd_SetRecomb() +
        • Cudd_ReadSymmviolation() +
        • Cudd_SetSymmviolation() +
        • Cudd_ReadArcviolation() +
        • Cudd_SetArcviolation() +
        • Cudd_ReadPopulationSize() +
        • Cudd_SetPopulationSize() +
        • Cudd_ReadNumberXovers() +
        • Cudd_SetNumberXovers() +
        • Cudd_ReadOrderRandomization() +
        • Cudd_SetOrderRandomization() +
        • Cudd_ReadMemoryInUse() +
        • Cudd_PrintInfo() +
        • Cudd_ReadPeakNodeCount() +
        • Cudd_ReadPeakLiveNodeCount() +
        • Cudd_ReadNodeCount() +
        • Cudd_zddReadNodeCount() +
        • Cudd_AddHook() +
        • Cudd_RemoveHook() +
        • Cudd_IsInHook() +
        • Cudd_StdPreReordHook() +
        • Cudd_StdPostReordHook() +
        • Cudd_EnableReorderingReporting() +
        • Cudd_DisableReorderingReporting() +
        • Cudd_ReorderingReporting() +
        • Cudd_PrintGroupedOrder() +
        • Cudd_EnableOrderingMonitoring() +
        • Cudd_DisableOrderingMonitoring() +
        • Cudd_OrderingMonitoring() +
        • Cudd_ReadErrorCode() +
        • Cudd_ClearErrorCode() +
        • Cudd_ReadStdout() +
        • Cudd_SetStdout() +
        • Cudd_ReadStderr() +
        • Cudd_SetStderr() +
        • Cudd_ReadNextReordering() +
        • Cudd_SetNextReordering() +
        • Cudd_ReadSwapSteps() +
        • Cudd_ReadMaxLive() +
        • Cudd_SetMaxLive() +
        • Cudd_ReadMaxMemory() +
        • Cudd_SetMaxMemory() +
        • Cudd_bddBindVar() +
        • Cudd_bddUnbindVar() +
        • Cudd_bddVarIsBound() +
        • Cudd_bddSetPiVar() +
        • Cudd_bddSetPsVar() +
        • Cudd_bddSetNsVar() +
        • Cudd_bddIsPiVar() +
        • Cudd_bddIsPsVar() +
        • Cudd_bddIsNsVar() +
        • Cudd_bddSetPairIndex() +
        • Cudd_bddReadPairIndex() +
        • Cudd_bddSetVarToBeGrouped() +
        • Cudd_bddSetVarHardGroup() +
        • Cudd_bddResetVarToBeGrouped() +
        • Cudd_bddIsVarToBeGrouped() +
        • Cudd_bddSetVarToBeUngrouped() +
        • Cudd_bddIsVarToBeUngrouped() +
        • Cudd_bddIsVarHardGroup() +
        + Static procedures included in this module: +
          +
        • fixVarTree() +

        +

        +
        Cudd_addNewVar() +
        Returns a new ADD variable. + +
        Cudd_addNewVarAtLevel() +
        Returns a new ADD variable at a specified level. + +
        Cudd_bddNewVar() +
        Returns a new BDD variable. + +
        Cudd_bddNewVarAtLevel() +
        Returns a new BDD variable at a specified level. + +
        Cudd_addIthVar() +
        Returns the ADD variable with index i. + +
        Cudd_bddIthVar() +
        Returns the BDD variable with index i. + +
        Cudd_zddIthVar() +
        Returns the ZDD variable with index i. + +
        Cudd_zddVarsFromBddVars() +
        Creates one or more ZDD variables for each BDD variable. + +
        Cudd_addConst() +
        Returns the ADD for constant c. + +
        Cudd_IsNonConstant() +
        Returns 1 if a DD node is not constant. + +
        Cudd_ReadStartTime() +
        Returns the start time of the manager. + +
        Cudd_ReadElapsedTime() +
        Returns the time elapsed since the start time of the manager. + +
        Cudd_SetStartTime() +
        Sets the start time of the manager. + +
        Cudd_ResetStartTime() +
        Resets the start time of the manager. + +
        Cudd_ReadTimeLimit() +
        Returns the time limit for the manager. + +
        Cudd_SetTimeLimit() +
        Sets the time limit for the manager. + +
        Cudd_UpdateTimeLimit() +
        Updates the time limit for the manager. + +
        Cudd_IncreaseTimeLimit() +
        Increases the time limit for the manager. + +
        Cudd_UnsetTimeLimit() +
        Unsets the time limit for the manager. + +
        Cudd_TimeLimited() +
        Returns true if the time limit for the manager is set. + +
        Cudd_AutodynEnable() +
        Enables automatic dynamic reordering of BDDs and ADDs. + +
        Cudd_AutodynDisable() +
        Disables automatic dynamic reordering. + +
        Cudd_ReorderingStatus() +
        Reports the status of automatic dynamic reordering of BDDs + and ADDs. + +
        Cudd_AutodynEnableZdd() +
        Enables automatic dynamic reordering of ZDDs. + +
        Cudd_AutodynDisableZdd() +
        Disables automatic dynamic reordering of ZDDs. + +
        Cudd_ReorderingStatusZdd() +
        Reports the status of automatic dynamic reordering of ZDDs. + +
        Cudd_zddRealignmentEnabled() +
        Tells whether the realignment of ZDD order to BDD order is + enabled. + +
        Cudd_zddRealignEnable() +
        Enables realignment of ZDD order to BDD order. + +
        Cudd_zddRealignDisable() +
        Disables realignment of ZDD order to BDD order. + +
        Cudd_bddRealignmentEnabled() +
        Tells whether the realignment of BDD order to ZDD order is + enabled. + +
        Cudd_bddRealignEnable() +
        Enables realignment of BDD order to ZDD order. + +
        Cudd_bddRealignDisable() +
        Disables realignment of ZDD order to BDD order. + +
        Cudd_ReadOne() +
        Returns the one constant of the manager. + +
        Cudd_ReadZddOne() +
        Returns the ZDD for the constant 1 function. + +
        Cudd_ReadZero() +
        Returns the zero constant of the manager. + +
        Cudd_ReadLogicZero() +
        Returns the logic zero constant of the manager. + +
        Cudd_ReadPlusInfinity() +
        Reads the plus-infinity constant from the manager. + +
        Cudd_ReadMinusInfinity() +
        Reads the minus-infinity constant from the manager. + +
        Cudd_ReadBackground() +
        Reads the background constant of the manager. + +
        Cudd_SetBackground() +
        Sets the background constant of the manager. + +
        Cudd_ReadCacheSlots() +
        Reads the number of slots in the cache. + +
        Cudd_ReadCacheUsedSlots() +
        Reads the fraction of used slots in the cache. + +
        Cudd_ReadCacheLookUps() +
        Returns the number of cache look-ups. + +
        Cudd_ReadCacheHits() +
        Returns the number of cache hits. + +
        Cudd_ReadRecursiveCalls() +
        Returns the number of recursive calls. + +
        Cudd_ReadMinHit() +
        Reads the hit rate that causes resizinig of the computed + table. + +
        Cudd_SetMinHit() +
        Sets the hit rate that causes resizinig of the computed + table. + +
        Cudd_ReadLooseUpTo() +
        Reads the looseUpTo parameter of the manager. + +
        Cudd_SetLooseUpTo() +
        Sets the looseUpTo parameter of the manager. + +
        Cudd_ReadMaxCache() +
        Returns the soft limit for the cache size. + +
        Cudd_ReadMaxCacheHard() +
        Reads the maxCacheHard parameter of the manager. + +
        Cudd_SetMaxCacheHard() +
        Sets the maxCacheHard parameter of the manager. + +
        Cudd_ReadSize() +
        Returns the number of BDD variables in existance. + +
        Cudd_ReadZddSize() +
        Returns the number of ZDD variables in existance. + +
        Cudd_ReadSlots() +
        Returns the total number of slots of the unique table. + +
        Cudd_ReadUsedSlots() +
        Reads the fraction of used slots in the unique table. + +
        Cudd_ExpectedUsedSlots() +
        Computes the expected fraction of used slots in the unique + table. + +
        Cudd_ReadKeys() +
        Returns the number of nodes in the unique table. + +
        Cudd_ReadDead() +
        Returns the number of dead nodes in the unique table. + +
        Cudd_ReadMinDead() +
        Reads the minDead parameter of the manager. + +
        Cudd_ReadReorderings() +
        Returns the number of times reordering has occurred. + +
        Cudd_ReadMaxReorderings() +
        Returns the maximum number of times reordering may be invoked. + +
        Cudd_SetMaxReorderings() +
        Sets the maximum number of times reordering may be invoked. + +
        Cudd_ReadReorderingTime() +
        Returns the time spent in reordering. + +
        Cudd_ReadGarbageCollections() +
        Returns the number of times garbage collection has occurred. + +
        Cudd_ReadGarbageCollectionTime() +
        Returns the time spent in garbage collection. + +
        Cudd_ReadNodesFreed() +
        Returns the number of nodes freed. + +
        Cudd_ReadNodesDropped() +
        Returns the number of nodes dropped. + +
        Cudd_ReadUniqueLookUps() +
        Returns the number of look-ups in the unique table. + +
        Cudd_ReadUniqueLinks() +
        Returns the number of links followed in the unique table. + +
        Cudd_ReadSiftMaxVar() +
        Reads the siftMaxVar parameter of the manager. + +
        Cudd_SetSiftMaxVar() +
        Sets the siftMaxVar parameter of the manager. + +
        Cudd_ReadSiftMaxSwap() +
        Reads the siftMaxSwap parameter of the manager. + +
        Cudd_SetSiftMaxSwap() +
        Sets the siftMaxSwap parameter of the manager. + +
        Cudd_ReadMaxGrowth() +
        Reads the maxGrowth parameter of the manager. + +
        Cudd_SetMaxGrowth() +
        Sets the maxGrowth parameter of the manager. + +
        Cudd_ReadMaxGrowthAlternate() +
        Reads the maxGrowthAlt parameter of the manager. + +
        Cudd_SetMaxGrowthAlternate() +
        Sets the maxGrowthAlt parameter of the manager. + +
        Cudd_ReadReorderingCycle() +
        Reads the reordCycle parameter of the manager. + +
        Cudd_SetReorderingCycle() +
        Sets the reordCycle parameter of the manager. + +
        Cudd_ReadTree() +
        Returns the variable group tree of the manager. + +
        Cudd_SetTree() +
        Sets the variable group tree of the manager. + +
        Cudd_FreeTree() +
        Frees the variable group tree of the manager. + +
        Cudd_ReadZddTree() +
        Returns the variable group tree of the manager. + +
        Cudd_SetZddTree() +
        Sets the ZDD variable group tree of the manager. + +
        Cudd_FreeZddTree() +
        Frees the variable group tree of the manager. + +
        Cudd_NodeReadIndex() +
        Returns the index of the node. + +
        Cudd_ReadPerm() +
        Returns the current position of the i-th variable in the + order. + +
        Cudd_ReadPermZdd() +
        Returns the current position of the i-th ZDD variable in the + order. + +
        Cudd_ReadInvPerm() +
        Returns the index of the variable currently in the i-th + position of the order. + +
        Cudd_ReadInvPermZdd() +
        Returns the index of the ZDD variable currently in the i-th + position of the order. + +
        Cudd_ReadVars() +
        Returns the i-th element of the vars array. + +
        Cudd_ReadEpsilon() +
        Reads the epsilon parameter of the manager. + +
        Cudd_SetEpsilon() +
        Sets the epsilon parameter of the manager to ep. + +
        Cudd_ReadGroupcheck() +
        Reads the groupcheck parameter of the manager. + +
        Cudd_SetGroupcheck() +
        Sets the parameter groupcheck of the manager to gc. + +
        Cudd_GarbageCollectionEnabled() +
        Tells whether garbage collection is enabled. + +
        Cudd_EnableGarbageCollection() +
        Enables garbage collection. + +
        Cudd_DisableGarbageCollection() +
        Disables garbage collection. + +
        Cudd_DeadAreCounted() +
        Tells whether dead nodes are counted towards triggering + reordering. + +
        Cudd_TurnOnCountDead() +
        Causes the dead nodes to be counted towards triggering + reordering. + +
        Cudd_TurnOffCountDead() +
        Causes the dead nodes not to be counted towards triggering + reordering. + +
        Cudd_ReadRecomb() +
        Returns the current value of the recombination parameter used + in group sifting. + +
        Cudd_SetRecomb() +
        Sets the value of the recombination parameter used in group + sifting. + +
        Cudd_ReadSymmviolation() +
        Returns the current value of the symmviolation parameter used + in group sifting. + +
        Cudd_SetSymmviolation() +
        Sets the value of the symmviolation parameter used + in group sifting. + +
        Cudd_ReadArcviolation() +
        Returns the current value of the arcviolation parameter used + in group sifting. + +
        Cudd_SetArcviolation() +
        Sets the value of the arcviolation parameter used + in group sifting. + +
        Cudd_ReadPopulationSize() +
        Reads the current size of the population used by the + genetic algorithm for reordering. + +
        Cudd_SetPopulationSize() +
        Sets the size of the population used by the + genetic algorithm for reordering. + +
        Cudd_ReadNumberXovers() +
        Reads the current number of crossovers used by the + genetic algorithm for reordering. + +
        Cudd_SetNumberXovers() +
        Sets the number of crossovers used by the + genetic algorithm for reordering. + +
        Cudd_ReadOrderRandomization() +
        Returns the order randomization factor. + +
        Cudd_SetOrderRandomization() +
        Sets the order randomization factor. + +
        Cudd_ReadMemoryInUse() +
        Returns the memory in use by the manager measured in bytes. + +
        Cudd_PrintInfo() +
        Prints out statistics and settings for a CUDD manager. + +
        Cudd_ReadPeakNodeCount() +
        Reports the peak number of nodes. + +
        Cudd_ReadPeakLiveNodeCount() +
        Reports the peak number of live nodes. + +
        Cudd_ReadNodeCount() +
        Reports the number of nodes in BDDs and ADDs. + +
        Cudd_zddReadNodeCount() +
        Reports the number of nodes in ZDDs. + +
        Cudd_AddHook() +
        Adds a function to a hook. + +
        Cudd_RemoveHook() +
        Removes a function from a hook. + +
        Cudd_IsInHook() +
        Checks whether a function is in a hook. + +
        Cudd_StdPreReordHook() +
        Sample hook function to call before reordering. + +
        Cudd_StdPostReordHook() +
        Sample hook function to call after reordering. + +
        Cudd_EnableReorderingReporting() +
        Enables reporting of reordering stats. + +
        Cudd_DisableReorderingReporting() +
        Disables reporting of reordering stats. + +
        Cudd_ReorderingReporting() +
        Returns 1 if reporting of reordering stats is enabled. + +
        Cudd_PrintGroupedOrder() +
        Hook function to print the current variable order. + +
        Cudd_EnableOrderingMonitoring() +
        Enables monitoring of ordering. + +
        Cudd_DisableOrderingMonitoring() +
        Disables monitoring of ordering. + +
        Cudd_OrderingMonitoring() +
        Returns 1 if monitoring of ordering is enabled. + +
        Cudd_ReadErrorCode() +
        Returns the code of the last error. + +
        Cudd_ClearErrorCode() +
        Clear the error code of a manager. + +
        Cudd_ReadStdout() +
        Reads the stdout of a manager. + +
        Cudd_SetStdout() +
        Sets the stdout of a manager. + +
        Cudd_ReadStderr() +
        Reads the stderr of a manager. + +
        Cudd_SetStderr() +
        Sets the stderr of a manager. + +
        Cudd_ReadNextReordering() +
        Returns the threshold for the next dynamic reordering. + +
        Cudd_SetNextReordering() +
        Sets the threshold for the next dynamic reordering. + +
        Cudd_ReadSwapSteps() +
        Reads the number of elementary reordering steps. + +
        Cudd_ReadMaxLive() +
        Reads the maximum allowed number of live nodes. + +
        Cudd_SetMaxLive() +
        Sets the maximum allowed number of live nodes. + +
        Cudd_ReadMaxMemory() +
        Reads the maximum allowed memory. + +
        Cudd_SetMaxMemory() +
        Sets the maximum allowed memory. + +
        Cudd_bddBindVar() +
        Prevents sifting of a variable. + +
        Cudd_bddUnbindVar() +
        Allows the sifting of a variable. + +
        Cudd_bddVarIsBound() +
        Tells whether a variable can be sifted. + +
        Cudd_bddSetPiVar() +
        Sets a variable type to primary input. + +
        Cudd_bddSetPsVar() +
        Sets a variable type to present state. + +
        Cudd_bddSetNsVar() +
        Sets a variable type to next state. + +
        Cudd_bddIsPiVar() +
        Checks whether a variable is primary input. + +
        Cudd_bddIsPsVar() +
        Checks whether a variable is present state. + +
        Cudd_bddIsNsVar() +
        Checks whether a variable is next state. + +
        Cudd_bddSetPairIndex() +
        Sets a corresponding pair index for a given index. + +
        Cudd_bddReadPairIndex() +
        Reads a corresponding pair index for a given index. + +
        Cudd_bddSetVarToBeGrouped() +
        Sets a variable to be grouped. + +
        Cudd_bddSetVarHardGroup() +
        Sets a variable to be a hard group. + +
        Cudd_bddResetVarToBeGrouped() +
        Resets a variable not to be grouped. + +
        Cudd_bddIsVarToBeGrouped() +
        Checks whether a variable is set to be grouped. + +
        Cudd_bddSetVarToBeUngrouped() +
        Sets a variable to be ungrouped. + +
        Cudd_bddIsVarToBeUngrouped() +
        Checks whether a variable is set to be ungrouped. + +
        Cudd_bddIsVarHardGroup() +
        Checks whether a variable is set to be in a hard group. + +
        fixVarTree() +
        Fixes a variable group tree. + +
        addMultiplicityGroups() +
        Adds multiplicity groups to a ZDD variable group tree. + +
        +
        +

        cuddApprox.c

        +Procedures to approximate a given BDD.

        +By: Fabio Somenzi

        +External procedures provided by this module: +

          +
        • Cudd_UnderApprox() +
        • Cudd_OverApprox() +
        • Cudd_RemapUnderApprox() +
        • Cudd_RemapOverApprox() +
        • Cudd_BiasedUnderApprox() +
        • Cudd_BiasedOverApprox() +
        + Internal procedures included in this module: +
          +
        • cuddUnderApprox() +
        • cuddRemapUnderApprox() +
        • cuddBiasedUnderApprox() +
        + Static procedures included in this module: +
          +
        • updateParity() +
        • gatherInfoAux() +
        • gatherInfo() +
        • computeSavings() +
        • updateRefs() +
        • UAmarkNodes() +
        • UAbuildSubset() +
        • RAmarkNodes() +
        • BAmarkNodes() +
        • RAbuildSubset() +
        • BAapplyBias() +

        +

        See AlsocuddSubsetHB.c +cuddSubsetSP.c +cuddGenCof.c +

        +
        Cudd_UnderApprox() +
        Extracts a dense subset from a BDD with Shiple's + underapproximation method. + +
        Cudd_OverApprox() +
        Extracts a dense superset from a BDD with Shiple's + underapproximation method. + +
        Cudd_RemapUnderApprox() +
        Extracts a dense subset from a BDD with the remapping + underapproximation method. + +
        Cudd_RemapOverApprox() +
        Extracts a dense superset from a BDD with the remapping + underapproximation method. + +
        Cudd_BiasedUnderApprox() +
        Extracts a dense subset from a BDD with the biased + underapproximation method. + +
        Cudd_BiasedOverApprox() +
        Extracts a dense superset from a BDD with the biased + underapproximation method. + +
        cuddUnderApprox() +
        Applies Tom Shiple's underappoximation algorithm. + +
        cuddRemapUnderApprox() +
        Applies the remapping underappoximation algorithm. + +
        cuddBiasedUnderApprox() +
        Applies the biased remapping underappoximation algorithm. + +
        updateParity() +
        Recursively update the parity of the paths reaching a node. + +
        gatherInfoAux() +
        Recursively counts minterms and computes reference counts + of each node in the BDD. + +
        gatherInfo() +
        Gathers information about each node. + +
        computeSavings() +
        Counts the nodes that would be eliminated if a given node + were replaced by zero. + +
        updateRefs() +
        Update function reference counts. + +
        UAmarkNodes() +
        Marks nodes for replacement by zero. + +
        UAbuildSubset() +
        Builds the subset BDD. + +
        RAmarkNodes() +
        Marks nodes for remapping. + +
        BAmarkNodes() +
        Marks nodes for remapping. + +
        RAbuildSubset() +
        Builds the subset BDD for cuddRemapUnderApprox. + +
        BAapplyBias() +
        Finds don't care nodes. + +
        +
        +

        cuddBddAbs.c

        +Quantification functions for BDDs.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_bddExistAbstract() +
        • Cudd_bddExistAbstractLimit() +
        • Cudd_bddXorExistAbstract() +
        • Cudd_bddUnivAbstract() +
        • Cudd_bddBooleanDiff() +
        • Cudd_bddVarIsDependent() +
        + Internal procedures included in this module: +
          +
        • cuddBddExistAbstractRecur() +
        • cuddBddXorExistAbstractRecur() +
        • cuddBddBooleanDiffRecur() +
        + Static procedures included in this module: +
          +
        • bddCheckPositiveCube() +

        +

        +
        Cudd_bddExistAbstract() +
        Existentially abstracts all the variables in cube from f. + +
        Cudd_bddExistAbstractLimit() +
        Existentially abstracts all the variables in cube from f. + +
        Cudd_bddXorExistAbstract() +
        Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
        Cudd_bddUnivAbstract() +
        Universally abstracts all the variables in cube from f. + +
        Cudd_bddBooleanDiff() +
        Computes the boolean difference of f with respect to x. + +
        Cudd_bddVarIsDependent() +
        Checks whether a variable is dependent on others in a + function. + +
        cuddBddExistAbstractRecur() +
        Performs the recursive steps of Cudd_bddExistAbstract. + +
        cuddBddXorExistAbstractRecur() +
        Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
        cuddBddBooleanDiffRecur() +
        Performs the recursive steps of Cudd_bddBoleanDiff. + +
        bddCheckPositiveCube() +
        Checks whether cube is an BDD representing the product of + positive literals. + +
        +
        +

        cuddBddCorr.c

        +Correlation between BDDs.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_bddCorrelation() +
        • Cudd_bddCorrelationWeights() +
        + Static procedures included in this module: +
          +
        • bddCorrelationAux() +
        • bddCorrelationWeightsAux() +
        • CorrelCompare() +
        • CorrelHash() +
        • CorrelCleanUp() +

        +

        +
        Cudd_bddCorrelation() +
        Computes the correlation of f and g. + +
        Cudd_bddCorrelationWeights() +
        Computes the correlation of f and g for given input + probabilities. + +
        bddCorrelationAux() +
        Performs the recursive step of Cudd_bddCorrelation. + +
        bddCorrelationWeightsAux() +
        Performs the recursive step of Cudd_bddCorrelationWeigths. + +
        CorrelCompare() +
        Compares two hash table entries. + +
        CorrelHash() +
        Hashes a hash table entry. + +
        CorrelCleanUp() +
        Frees memory associated with hash table. + +
        +
        +

        cuddBddIte.c

        +BDD ITE function and satellites.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_bddIte() +
        • Cudd_bddIteLimit() +
        • Cudd_bddIteConstant() +
        • Cudd_bddIntersect() +
        • Cudd_bddAnd() +
        • Cudd_bddAndLimit() +
        • Cudd_bddOr() +
        • Cudd_bddOrLimit() +
        • Cudd_bddNand() +
        • Cudd_bddNor() +
        • Cudd_bddXor() +
        • Cudd_bddXnor() +
        • Cudd_bddXnorLimit() +
        • Cudd_bddLeq() +
        + Internal procedures included in this module: +
          +
        • cuddBddIteRecur() +
        • cuddBddIntersectRecur() +
        • cuddBddAndRecur() +
        • cuddBddXorRecur() +
        + Static procedures included in this module: +
          +
        • bddVarToConst() +
        • bddVarToCanonical() +
        • bddVarToCanonicalSimple() +

        +

        +
        Cudd_bddIte() +
        Implements ITE(f,g,h). + +
        Cudd_bddIteLimit() +
        Implements ITE(f,g,h). Returns + NULL if too many nodes are required. + +
        Cudd_bddIteConstant() +
        Implements ITEconstant(f,g,h). + +
        Cudd_bddIntersect() +
        Returns a function included in the intersection of f and g. + +
        Cudd_bddAnd() +
        Computes the conjunction of two BDDs f and g. + +
        Cudd_bddAndLimit() +
        Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
        Cudd_bddOr() +
        Computes the disjunction of two BDDs f and g. + +
        Cudd_bddOrLimit() +
        Computes the disjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
        Cudd_bddNand() +
        Computes the NAND of two BDDs f and g. + +
        Cudd_bddNor() +
        Computes the NOR of two BDDs f and g. + +
        Cudd_bddXor() +
        Computes the exclusive OR of two BDDs f and g. + +
        Cudd_bddXnor() +
        Computes the exclusive NOR of two BDDs f and g. + +
        Cudd_bddXnorLimit() +
        Computes the exclusive NOR of two BDDs f and g. Returns + NULL if too many nodes are required. + +
        Cudd_bddLeq() +
        Determines whether f is less than or equal to g. + +
        cuddBddIteRecur() +
        Implements the recursive step of Cudd_bddIte. + +
        cuddBddIntersectRecur() +
        Implements the recursive step of Cudd_bddIntersect. + +
        cuddBddAndRecur() +
        Implements the recursive step of Cudd_bddAnd. + +
        cuddBddXorRecur() +
        Implements the recursive step of Cudd_bddXor. + +
        bddVarToConst() +
        Replaces variables with constants if possible. + +
        bddVarToCanonical() +
        Picks unique member from equiv expressions. + +
        bddVarToCanonicalSimple() +
        Picks unique member from equiv expressions. + +
        +
        +

        cuddBridge.c

        +Translation from BDD to ADD and vice versa and transfer between + different managers.

        +By: Fabio Somenzi

        +External procedures included in this file: +

          +
        • Cudd_addBddThreshold() +
        • Cudd_addBddStrictThreshold() +
        • Cudd_addBddInterval() +
        • Cudd_addBddIthBit() +
        • Cudd_BddToAdd() +
        • Cudd_addBddPattern() +
        • Cudd_bddTransfer() +
        + Internal procedures included in this file: +
          +
        • cuddBddTransfer() +
        • cuddAddBddDoPattern() +
        + Static procedures included in this file: +
          +
        • addBddDoThreshold() +
        • addBddDoStrictThreshold() +
        • addBddDoInterval() +
        • addBddDoIthBit() +
        • ddBddToAddRecur() +
        • cuddBddTransferRecur() +

        +

        +
        Cudd_addBddThreshold() +
        Converts an ADD to a BDD. + +
        Cudd_addBddStrictThreshold() +
        Converts an ADD to a BDD. + +
        Cudd_addBddInterval() +
        Converts an ADD to a BDD. + +
        Cudd_addBddIthBit() +
        Converts an ADD to a BDD by extracting the i-th bit from + the leaves. + +
        Cudd_BddToAdd() +
        Converts a BDD to a 0-1 ADD. + +
        Cudd_addBddPattern() +
        Converts an ADD to a BDD. + +
        Cudd_bddTransfer() +
        Convert a BDD from a manager to another one. + +
        cuddBddTransfer() +
        Convert a BDD from a manager to another one. + +
        cuddAddBddDoPattern() +
        Performs the recursive step for Cudd_addBddPattern. + +
        addBddDoThreshold() +
        Performs the recursive step for Cudd_addBddThreshold. + +
        addBddDoStrictThreshold() +
        Performs the recursive step for Cudd_addBddStrictThreshold. + +
        addBddDoInterval() +
        Performs the recursive step for Cudd_addBddInterval. + +
        addBddDoIthBit() +
        Performs the recursive step for Cudd_addBddIthBit. + +
        ddBddToAddRecur() +
        Performs the recursive step for Cudd_BddToAdd. + +
        cuddBddTransferRecur() +
        Performs the recursive step of Cudd_bddTransfer. + +
        +
        +

        cuddCache.c

        +Functions for cache insertion and lookup.

        +By: Fabio Somenzi

        +Internal procedures included in this module: +

          +
        • cuddInitCache() +
        • cuddCacheInsert() +
        • cuddCacheInsert2() +
        • cuddCacheLookup() +
        • cuddCacheLookupZdd() +
        • cuddCacheLookup2() +
        • cuddCacheLookup2Zdd() +
        • cuddConstantLookup() +
        • cuddCacheProfile() +
        • cuddCacheResize() +
        • cuddCacheFlush() +
        • cuddComputeFloorLog2() +
        + Static procedures included in this module: +
          +

        +

        +
        cuddInitCache() +
        Initializes the computed table. + +
        cuddCacheInsert() +
        Inserts a result in the cache for a function with three + operands. + +
        cuddCacheInsert2() +
        Inserts a result in the cache for a function with two + operands. + +
        cuddCacheInsert1() +
        Inserts a result in the cache for a function with two + operands. + +
        cuddCacheLookup() +
        Looks up in the cache for the result of op applied to f, + g, and h. + +
        cuddCacheLookupZdd() +
        Looks up in the cache for the result of op applied to f, + g, and h. + +
        cuddCacheLookup2() +
        Looks up in the cache for the result of op applied to f + and g. + +
        cuddCacheLookup1() +
        Looks up in the cache for the result of op applied to f. + +
        cuddCacheLookup2Zdd() +
        Looks up in the cache for the result of op applied to f + and g. + +
        cuddCacheLookup1Zdd() +
        Looks up in the cache for the result of op applied to f. + +
        cuddConstantLookup() +
        Looks up in the cache for the result of op applied to f, + g, and h. + +
        cuddCacheProfile() +
        Computes and prints a profile of the cache usage. + +
        cuddCacheResize() +
        Resizes the cache. + +
        cuddCacheFlush() +
        Flushes the cache. + +
        cuddComputeFloorLog2() +
        Returns the floor of the logarithm to the base 2. + +
        +
        +

        cuddCheck.c

        +Functions to check consistency of data structures.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_DebugCheck() +
        • Cudd_CheckKeys() +
        + Internal procedures included in this module: +
          +
        • cuddHeapProfile() +
        • cuddPrintNode() +
        • cuddPrintVarGroups() +
        + Static procedures included in this module: +
          +
        • debugFindParent() +

        +

        +
        Cudd_DebugCheck() +
        Checks for inconsistencies in the DD heap. + +
        Cudd_CheckKeys() +
        Checks for several conditions that should not occur. + +
        cuddHeapProfile() +
        Prints information about the heap. + +
        cuddPrintNode() +
        Prints out information on a node. + +
        cuddPrintVarGroups() +
        Prints the variable groups as a parenthesized list. + +
        debugFindParent() +
        Searches the subtables above node for its parents. + +
        debugCheckParent() +
        Reports an error if a (dead) node has a non-dead parent. + +
        +
        +

        cuddClip.c

        +Clipping functions.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_bddClippingAnd() +
        • Cudd_bddClippingAndAbstract() +
        + Internal procedures included in this module: +
          +
        • cuddBddClippingAnd() +
        • cuddBddClippingAndAbstract() +
        + Static procedures included in this module: +
          +
        • cuddBddClippingAndRecur() +
        • cuddBddClipAndAbsRecur() +
        + + SeeAlso [

        +

        +
        Cudd_bddClippingAnd() +
        Approximates the conjunction of two BDDs f and g. + +
        Cudd_bddClippingAndAbstract() +
        Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
        cuddBddClippingAnd() +
        Approximates the conjunction of two BDDs f and g. + +
        cuddBddClippingAndAbstract() +
        Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
        cuddBddClippingAndRecur() +
        Implements the recursive step of Cudd_bddClippingAnd. + +
        cuddBddClipAndAbsRecur() +
        Approximates the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
        +
        +

        cuddCof.c

        +Cofactoring functions.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_Cofactor() +
        • Cudd_CheckCube() +
        + Internal procedures included in this module: +
          +
        • cuddGetBranches() +
        • cuddCofactorRecur() +

        +

        +
        Cudd_Cofactor() +
        Computes the cofactor of f with respect to g. + +
        Cudd_CheckCube() +
        Checks whether g is the BDD of a cube. + +
        cuddGetBranches() +
        Computes the children of g. + +
        cuddCofactorRecur() +
        Performs the recursive step of Cudd_Cofactor. + +
        +
        +

        cuddCompose.c

        +Functional composition and variable permutation of DDs.

        +By: Fabio Somenzi and Kavita Ravi

        +External procedures included in this module: +

          +
        • Cudd_bddCompose() +
        • Cudd_addCompose() +
        • Cudd_addPermute() +
        • Cudd_addSwapVariables() +
        • Cudd_bddPermute() +
        • Cudd_bddVarMap() +
        • Cudd_SetVarMap() +
        • Cudd_bddSwapVariables() +
        • Cudd_bddAdjPermuteX() +
        • Cudd_addVectorCompose() +
        • Cudd_addGeneralVectorCompose() +
        • Cudd_addNonSimCompose() +
        • Cudd_bddVectorCompose() +
        + Internal procedures included in this module: +
          +
        • cuddBddComposeRecur() +
        • cuddAddComposeRecur() +
        + Static procedures included in this module: +
          +
        • cuddAddPermuteRecur() +
        • cuddBddPermuteRecur() +
        • cuddBddVarMapRecur() +
        • cuddAddVectorComposeRecur() +
        • cuddAddGeneralVectorComposeRecur() +
        • cuddAddNonSimComposeRecur() +
        • cuddBddVectorComposeRecur() +
        • ddIsIthAddVar() +
        • ddIsIthAddVarPair() +
        + The permutation functions use a local cache because the results to + be remembered depend on the permutation being applied. Since the + permutation is just an array, it cannot be stored in the global + cache. There are different procedured for BDDs and ADDs. This is + because bddPermuteRecur uses cuddBddIteRecur. If this were changed, + the procedures could be merged.

        +

        +
        Cudd_bddCompose() +
        Substitutes g for x_v in the BDD for f. + +
        Cudd_addCompose() +
        Substitutes g for x_v in the ADD for f. + +
        Cudd_addPermute() +
        Permutes the variables of an ADD. + +
        Cudd_addSwapVariables() +
        Swaps two sets of variables of the same size (x and y) in + the ADD f. + +
        Cudd_bddPermute() +
        Permutes the variables of a BDD. + +
        Cudd_bddVarMap() +
        Remaps the variables of a BDD using the default variable map. + +
        Cudd_SetVarMap() +
        Registers a variable mapping with the manager. + +
        Cudd_bddSwapVariables() +
        Swaps two sets of variables of the same size (x and y) in + the BDD f. + +
        Cudd_bddAdjPermuteX() +
        Rearranges a set of variables in the BDD B. + +
        Cudd_addVectorCompose() +
        Composes an ADD with a vector of 0-1 ADDs. + +
        Cudd_addGeneralVectorCompose() +
        Composes an ADD with a vector of ADDs. + +
        Cudd_addNonSimCompose() +
        Composes an ADD with a vector of 0-1 ADDs. + +
        Cudd_bddVectorCompose() +
        Composes a BDD with a vector of BDDs. + +
        cuddBddComposeRecur() +
        Performs the recursive step of Cudd_bddCompose. + +
        cuddAddComposeRecur() +
        Performs the recursive step of Cudd_addCompose. + +
        cuddAddPermuteRecur() +
        Implements the recursive step of Cudd_addPermute. + +
        cuddBddPermuteRecur() +
        Implements the recursive step of Cudd_bddPermute. + +
        cuddBddVarMapRecur() +
        Implements the recursive step of Cudd_bddVarMap. + +
        cuddAddVectorComposeRecur() +
        Performs the recursive step of Cudd_addVectorCompose. + +
        cuddAddGeneralVectorComposeRecur() +
        Performs the recursive step of Cudd_addGeneralVectorCompose. + +
        cuddAddNonSimComposeRecur() +
        Performs the recursive step of Cudd_addNonSimCompose. + +
        cuddBddVectorComposeRecur() +
        Performs the recursive step of Cudd_bddVectorCompose. + +
        () +
        Comparison of a function to the i-th ADD variable. + +
        () +
        Comparison of a pair of functions to the i-th ADD variable. + +
        +
        +

        cuddDecomp.c

        +Functions for BDD decomposition.

        +By: Kavita Ravi, Fabio Somenzi

        +External procedures included in this file: +

          +
        • Cudd_bddApproxConjDecomp() +
        • Cudd_bddApproxDisjDecomp() +
        • Cudd_bddIterConjDecomp() +
        • Cudd_bddIterDisjDecomp() +
        • Cudd_bddGenConjDecomp() +
        • Cudd_bddGenDisjDecomp() +
        • Cudd_bddVarConjDecomp() +
        • Cudd_bddVarDisjDecomp() +
        + Static procedures included in this module: +
          +
        • cuddConjunctsAux() +
        • CreateBotDist() +
        • BuildConjuncts() +
        • ConjunctsFree() +

        +

        +
        Cudd_bddApproxConjDecomp() +
        Performs two-way conjunctive decomposition of a BDD. + +
        Cudd_bddApproxDisjDecomp() +
        Performs two-way disjunctive decomposition of a BDD. + +
        Cudd_bddIterConjDecomp() +
        Performs two-way conjunctive decomposition of a BDD. + +
        Cudd_bddIterDisjDecomp() +
        Performs two-way disjunctive decomposition of a BDD. + +
        Cudd_bddGenConjDecomp() +
        Performs two-way conjunctive decomposition of a BDD. + +
        Cudd_bddGenDisjDecomp() +
        Performs two-way disjunctive decomposition of a BDD. + +
        Cudd_bddVarConjDecomp() +
        Performs two-way conjunctive decomposition of a BDD. + +
        Cudd_bddVarDisjDecomp() +
        Performs two-way disjunctive decomposition of a BDD. + +
        CreateBotDist() +
        Get longest distance of node from constant. + +
        CountMinterms() +
        Count the number of minterms of each node ina a BDD and + store it in a hash table. + +
        ConjunctsFree() +
        Free factors structure + +
        PairInTables() +
        Check whether the given pair is in the tables. + +
        CheckTablesCacheAndReturn() +
        Check the tables for the existence of pair and return one + combination, cache the result. + +
        PickOnePair() +
        Check the tables for the existence of pair and return one + combination, store in cache. + +
        CheckInTables() +
        Check if the two pairs exist in the table, If any of the + conjuncts do exist, store in the cache and return the corresponding pair. + +
        ZeroCase() +
        If one child is zero, do explicitly what Restrict does or better + +
        BuildConjuncts() +
        Builds the conjuncts recursively, bottom up. + +
        cuddConjunctsAux() +
        Procedure to compute two conjunctive factors of f and place in *c1 and *c2. + +
        +
        +

        cuddEssent.c

        +Functions for the detection of essential variables.

        +By: Fabio Somenzi

        +External procedures included in this file: +

          +
        • Cudd_FindEssential() +
        • Cudd_bddIsVarEssential() +
        • Cudd_FindTwoLiteralClauses() +
        • Cudd_ReadIthClause() +
        • Cudd_PrintTwoLiteralClauses() +
        • Cudd_tlcInfoFree() +
        + Static procedures included in this module: +
          +
        • ddFindEssentialRecur() +
        • ddFindTwoLiteralClausesRecur() +
        • computeClauses() +
        • computeClausesWithUniverse() +
        • emptyClauseSet() +
        • sentinelp() +
        • equalp() +
        • beforep() +
        • oneliteralp() +
        • impliedp() +
        • bitVectorAlloc() +
        • bitVectorClear() +
        • bitVectorFree() +
        • bitVectorRead() +
        • bitVectorSet() +
        • tlcInfoAlloc() +

        +

        +
        Cudd_FindEssential() +
        Finds the essential variables of a DD. + +
        Cudd_bddIsVarEssential() +
        Determines whether a given variable is essential with a + given phase in a BDD. + +
        Cudd_FindTwoLiteralClauses() +
        Finds the two literal clauses of a DD. + +
        Cudd_ReadIthClause() +
        Accesses the i-th clause of a DD. + +
        Cudd_PrintTwoLiteralClauses() +
        Prints the two literal clauses of a DD. + +
        Cudd_tlcInfoFree() +
        Frees a DdTlcInfo Structure. + +
        ddFindEssentialRecur() +
        Implements the recursive step of Cudd_FindEssential. + +
        ddFindTwoLiteralClausesRecur() +
        Implements the recursive step of Cudd_FindTwoLiteralClauses. + +
        computeClauses() +
        Computes the two-literal clauses for a node. + +
        computeClausesWithUniverse() +
        Computes the two-literal clauses for a node. + +
        emptyClauseSet() +
        Returns an enpty set of clauses. + +
        sentinelp() +
        Returns true iff the argument is the sentinel clause. + +
        equalp() +
        Returns true iff the two arguments are identical clauses. + +
        beforep() +
        Returns true iff the first argument precedes the second in + the clause order. + +
        oneliteralp() +
        Returns true iff the argument is a one-literal clause. + +
        impliedp() +
        Returns true iff either literal of a clause is in a set of + literals. + +
        bitVectorAlloc() +
        Allocates a bit vector. + +
        () +
        Clears a bit vector. + +
        bitVectorFree() +
        Frees a bit vector. + +
        () +
        Returns the i-th entry of a bit vector. + +
        () +
        Sets the i-th entry of a bit vector to a value. + +
        tlcInfoAlloc() +
        Allocates a DdTlcInfo Structure. + +
        +
        +

        cuddExact.c

        +Functions for exact variable reordering.

        +By: Cheng Hua, Fabio Somenzi

        +External procedures included in this file: +

          +
        + Internal procedures included in this module: +
          +
        • cuddExact() +
        + Static procedures included in this module: +
          +
        • getMaxBinomial() +
        • gcd() +
        • getMatrix() +
        • freeMatrix() +
        • getLevelKeys() +
        • ddShuffle() +
        • ddSiftUp() +
        • updateUB() +
        • ddCountRoots() +
        • ddClearGlobal() +
        • computeLB() +
        • updateEntry() +
        • pushDown() +
        • initSymmInfo() +

        +

        +
        cuddExact() +
        Exact variable ordering algorithm. + +
        getMaxBinomial() +
        Returns the maximum value of (n choose k) for a given n. + +
        gcd() +
        Returns the gcd of two integers. + +
        getMatrix() +
        Allocates a two-dimensional matrix of ints. + +
        freeMatrix() +
        Frees a two-dimensional matrix allocated by getMatrix. + +
        getLevelKeys() +
        Returns the number of nodes at one level of a unique table. + +
        ddShuffle() +
        Reorders variables according to a given permutation. + +
        ddSiftUp() +
        Moves one variable up. + +
        updateUB() +
        Updates the upper bound and saves the best order seen so far. + +
        ddCountRoots() +
        Counts the number of roots. + +
        ddClearGlobal() +
        Scans the DD and clears the LSB of the next pointers. + +
        computeLB() +
        Computes a lower bound on the size of a BDD. + +
        updateEntry() +
        Updates entry for a subset. + +
        pushDown() +
        Pushes a variable in the order down to position "level." + +
        initSymmInfo() +
        Gathers symmetry information. + +
        checkSymmInfo() +
        Check symmetry condition. + +
        +
        +

        cuddExport.c

        +Export functions.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_DumpBlif() +
        • Cudd_DumpBlifBody() +
        • Cudd_DumpDot() +
        • Cudd_DumpDaVinci() +
        • Cudd_DumpDDcal() +
        • Cudd_DumpFactoredForm() +
        + Internal procedures included in this module: +
          +
        + Static procedures included in this module: +
          +
        • ddDoDumpBlif() +
        • ddDoDumpDaVinci() +
        • ddDoDumpDDcal() +
        • ddDoDumpFactoredForm() +

        +

        +
        Cudd_DumpBlif() +
        Writes a blif file representing the argument BDDs. + +
        Cudd_DumpBlifBody() +
        Writes a blif body representing the argument BDDs. + +
        Cudd_DumpDot() +
        Writes a dot file representing the argument DDs. + +
        Cudd_DumpDaVinci() +
        Writes a daVinci file representing the argument BDDs. + +
        Cudd_DumpDDcal() +
        Writes a DDcal file representing the argument BDDs. + +
        Cudd_DumpFactoredForm() +
        Writes factored forms representing the argument BDDs. + +
        ddDoDumpBlif() +
        Performs the recursive step of Cudd_DumpBlif. + +
        ddDoDumpDaVinci() +
        Performs the recursive step of Cudd_DumpDaVinci. + +
        ddDoDumpDDcal() +
        Performs the recursive step of Cudd_DumpDDcal. + +
        ddDoDumpFactoredForm() +
        Performs the recursive step of Cudd_DumpFactoredForm. + +
        +
        +

        cuddGenCof.c

        +Generalized cofactors for BDDs and ADDs.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_bddConstrain() +
        • Cudd_bddRestrict() +
        • Cudd_bddNPAnd() +
        • Cudd_addConstrain() +
        • Cudd_bddConstrainDecomp() +
        • Cudd_addRestrict() +
        • Cudd_bddCharToVect() +
        • Cudd_bddLICompaction() +
        • Cudd_bddSqueeze() +
        • Cudd_bddMinimize() +
        • Cudd_SubsetCompress() +
        • Cudd_SupersetCompress() +
        + Internal procedures included in this module: +
          +
        • cuddBddConstrainRecur() +
        • cuddBddRestrictRecur() +
        • cuddBddNPAndRecur() +
        • cuddAddConstrainRecur() +
        • cuddAddRestrictRecur() +
        • cuddBddLICompaction() +
        + Static procedures included in this module: +
          +
        • cuddBddConstrainDecomp() +
        • cuddBddCharToVect() +
        • cuddBddLICMarkEdges() +
        • cuddBddLICBuildResult() +
        • MarkCacheHash() +
        • MarkCacheCompare() +
        • MarkCacheCleanUp() +
        • cuddBddSqueeze() +

        +

        +
        Cudd_bddConstrain() +
        Computes f constrain c. + +
        Cudd_bddRestrict() +
        BDD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
        Cudd_bddNPAnd() +
        Computes f non-polluting-and g. + +
        Cudd_addConstrain() +
        Computes f constrain c for ADDs. + +
        Cudd_bddConstrainDecomp() +
        BDD conjunctive decomposition as in McMillan's CAV96 paper. + +
        Cudd_addRestrict() +
        ADD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
        Cudd_bddCharToVect() +
        Computes a vector whose image equals a non-zero function. + +
        Cudd_bddLICompaction() +
        Performs safe minimization of a BDD. + +
        Cudd_bddSqueeze() +
        Finds a small BDD in a function interval. + +
        Cudd_bddMinimize() +
        Finds a small BDD that agrees with f over + c. + +
        Cudd_SubsetCompress() +
        Find a dense subset of BDD f. + +
        Cudd_SupersetCompress() +
        Find a dense superset of BDD f. + +
        cuddBddConstrainRecur() +
        Performs the recursive step of Cudd_bddConstrain. + +
        cuddBddRestrictRecur() +
        Performs the recursive step of Cudd_bddRestrict. + +
        cuddBddNPAndRecur() +
        Implements the recursive step of Cudd_bddAnd. + +
        cuddAddConstrainRecur() +
        Performs the recursive step of Cudd_addConstrain. + +
        cuddAddRestrictRecur() +
        Performs the recursive step of Cudd_addRestrict. + +
        cuddBddLICompaction() +
        Performs safe minimization of a BDD. + +
        cuddBddConstrainDecomp() +
        Performs the recursive step of Cudd_bddConstrainDecomp. + +
        cuddBddCharToVect() +
        Performs the recursive step of Cudd_bddCharToVect. + +
        cuddBddLICMarkEdges() +
        Performs the edge marking step of Cudd_bddLICompaction. + +
        cuddBddLICBuildResult() +
        Builds the result of Cudd_bddLICompaction. + +
        MarkCacheHash() +
        Hash function for the computed table of cuddBddLICMarkEdges. + +
        MarkCacheCompare() +
        Comparison function for the computed table of + cuddBddLICMarkEdges. + +
        MarkCacheCleanUp() +
        Frees memory associated with computed table of + cuddBddLICMarkEdges. + +
        cuddBddSqueeze() +
        Performs the recursive step of Cudd_bddSqueeze. + +
        +
        +

        cuddGenetic.c

        +Genetic algorithm for variable reordering.

        +By: Curt Musfeldt, Alan Shuler, Fabio Somenzi

        +Internal procedures included in this file: +

          +
        • cuddGa() +
        + Static procedures included in this module: +
          +
        • make_random() +
        • sift_up() +
        • build_dd() +
        • largest() +
        • rand_int() +
        • array_hash() +
        • array_compare() +
        • find_best() +
        • find_average_fitness() +
        • PMX() +
        • roulette() +
        + + The genetic algorithm implemented here is as follows. We start with + the current DD order. We sift this order and use this as the + reference DD. We only keep 1 DD around for the entire process and + simply rearrange the order of this DD, storing the various orders + and their corresponding DD sizes. We generate more random orders to + build an initial population. This initial population is 3 times the + number of variables, with a maximum of 120. Each random order is + built (from the reference DD) and its size stored. Each random + order is also sifted to keep the DD sizes fairly small. Then a + crossover is performed between two orders (picked randomly) and the + two resulting DDs are built and sifted. For each new order, if its + size is smaller than any DD in the population, it is inserted into + the population and the DD with the largest number of nodes is thrown + out. The crossover process happens up to 50 times, and at this point + the DD in the population with the smallest size is chosen as the + result. This DD must then be built from the reference DD.

        +

        +
        cuddGa() +
        Genetic algorithm for DD reordering. + +
        make_random() +
        Generates the random sequences for the initial population. + +
        sift_up() +
        Moves one variable up. + +
        build_dd() +
        Builds a DD from a given order. + +
        largest() +
        Finds the largest DD in the population. + +
        rand_int() +
        Generates a random number between 0 and the integer a. + +
        array_hash() +
        Hash function for the computed table. + +
        array_compare() +
        Comparison function for the computed table. + +
        find_best() +
        Returns the index of the fittest individual. + +
        () +
        Returns the average fitness of the population. + +
        PMX() +
        Performs the crossover between two parents. + +
        roulette() +
        Selects two parents with the roulette wheel method. + +
        +
        +

        cuddGroup.c

        +Functions for group sifting.

        +By: Shipra Panda, Fabio Somenzi

        +External procedures included in this file: +

          +
        • Cudd_MakeTreeNode() +
        + Internal procedures included in this file: +
          +
        • cuddTreeSifting() +
        + Static procedures included in this module: +
          +
        • ddTreeSiftingAux() +
        • ddCountInternalMtrNodes() +
        • ddReorderChildren() +
        • ddFindNodeHiLo() +
        • ddUniqueCompareGroup() +
        • ddGroupSifting() +
        • ddCreateGroup() +
        • ddGroupSiftingAux() +
        • ddGroupSiftingUp() +
        • ddGroupSiftingDown() +
        • ddGroupMove() +
        • ddGroupMoveBackward() +
        • ddGroupSiftingBackward() +
        • ddMergeGroups() +
        • ddDissolveGroup() +
        • ddNoCheck() +
        • ddSecDiffCheck() +
        • ddExtSymmCheck() +
        • ddVarGroupCheck() +
        • ddSetVarHandled() +
        • ddResetVarHandled() +
        • ddIsVarHandled() +
        • ddFixTree() +

        +

        +
        Cudd_MakeTreeNode() +
        Creates a new variable group. + +
        cuddTreeSifting() +
        Tree sifting algorithm. + +
        ddTreeSiftingAux() +
        Visits the group tree and reorders each group. + +
        ddCountInternalMtrNodes() +
        Counts the number of internal nodes of the group tree. + +
        ddReorderChildren() +
        Reorders the children of a group tree node according to + the options. + +
        ddFindNodeHiLo() +
        Finds the lower and upper bounds of the group represented + by treenode. + +
        ddUniqueCompareGroup() +
        Comparison function used by qsort. + +
        ddGroupSifting() +
        Sifts from treenode->low to treenode->high. + +
        ddCreateGroup() +
        Creates a group encompassing variables from x to y in the + DD table. + +
        ddGroupSiftingAux() +
        Sifts one variable up and down until it has taken all + positions. Checks for aggregation. + +
        ddGroupSiftingUp() +
        Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much. + +
        ddGroupSiftingDown() +
        Sifts down a variable until it reaches position xHigh. + +
        ddGroupMove() +
        Swaps two groups and records the move. + +
        ddGroupMoveBackward() +
        Undoes the swap two groups. + +
        ddGroupSiftingBackward() +
        Determines the best position for a variables and returns + it there. + +
        ddMergeGroups() +
        Merges groups in the DD table. + +
        ddDissolveGroup() +
        Dissolves a group in the DD table. + +
        ddNoCheck() +
        Pretends to check two variables for aggregation. + +
        ddSecDiffCheck() +
        Checks two variables for aggregation. + +
        ddExtSymmCheck() +
        Checks for extended symmetry of x and y. + +
        ddVarGroupCheck() +
        Checks for grouping of x and y. + +
        ddSetVarHandled() +
        Sets a variable to already handled. + +
        ddResetVarHandled() +
        Resets a variable to be processed. + +
        ddIsVarHandled() +
        Checks whether a variables is already handled. + +
        +
        +

        cuddHarwell.c

        +Function to read a matrix in Harwell format.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_addHarwell() +

        +

        +
        Cudd_addHarwell() +
        Reads in a matrix in the format of the Harwell-Boeing + benchmark suite. + +
        +
        +

        cuddInit.c

        +Functions to initialize and shut down the DD manager.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_Init() +
        • Cudd_Quit() +
        + Internal procedures included in this module: +
          +
        • cuddZddInitUniv() +
        • cuddZddFreeUniv() +

        +

        +
        Cudd_Init() +
        Creates a new DD manager. + +
        Cudd_Quit() +
        Deletes resources associated with a DD manager. + +
        cuddZddInitUniv() +
        Initializes the ZDD universe. + +
        cuddZddFreeUniv() +
        Frees the ZDD universe. + +
        +
        +

        cuddInteract.c

        +Functions to manipulate the variable interaction matrix.

        +By: Fabio Somenzi

        +Internal procedures included in this file: +

          +
        • cuddSetInteract() +
        • cuddTestInteract() +
        • cuddInitInteract() +
        + Static procedures included in this file: +
          +
        • ddSuppInteract() +
        • ddClearLocal() +
        • ddUpdateInteract() +
        • ddClearGlobal() +
        + The interaction matrix tells whether two variables are + both in the support of some function of the DD. The main use of the + interaction matrix is in the in-place swapping. Indeed, if two + variables do not interact, there is no arc connecting the two layers; + therefore, the swap can be performed in constant time, without + scanning the subtables. Another use of the interaction matrix is in + the computation of the lower bounds for sifting. Finally, the + interaction matrix can be used to speed up aggregation checks in + symmetric and group sifting.

        + The computation of the interaction matrix is done with a series of + depth-first searches. The searches start from those nodes that have + only external references. The matrix is stored as a packed array of bits; + since it is symmetric, only the upper triangle is kept in memory. + As a final remark, we note that there may be variables that do + interact, but that for a given variable order have no arc connecting + their layers when they are adjacent. For instance, in ite(a,b,c) with + the order a +

        +
        cuddSetInteract() +
        Set interaction matrix entries. + +
        cuddTestInteract() +
        Test interaction matrix entries. + +
        cuddInitInteract() +
        Initializes the interaction matrix. + +
        ddSuppInteract() +
        Find the support of f. + +
        ddClearLocal() +
        Performs a DFS from f, clearing the LSB of the then pointers. + +
        ddUpdateInteract() +
        Marks as interacting all pairs of variables that appear in + support. + +
        ddClearGlobal() +
        Scans the DD and clears the LSB of the next pointers. + +
        +
        +

        cuddLCache.c

        +Functions for local caches.

        +By: Fabio Somenzi

        +Internal procedures included in this module: +

          +
        • cuddLocalCacheInit() +
        • cuddLocalCacheQuit() +
        • cuddLocalCacheInsert() +
        • cuddLocalCacheLookup() +
        • cuddLocalCacheClearDead() +
        • cuddLocalCacheClearAll() +
        • cuddLocalCacheProfile() +
        • cuddHashTableInit() +
        • cuddHashTableQuit() +
        • cuddHashTableGenericQuit() +
        • cuddHashTableInsert() +
        • cuddHashTableLookup() +
        • cuddHashTableGenericInsert() +
        • cuddHashTableGenericLookup() +
        • cuddHashTableInsert2() +
        • cuddHashTableLookup2() +
        • cuddHashTableInsert3() +
        • cuddHashTableLookup3() +
        + Static procedures included in this module: +
          +
        • cuddLocalCacheResize() +
        • ddLCHash() +
        • cuddLocalCacheAddToList() +
        • cuddLocalCacheRemoveFromList() +
        • cuddHashTableResize() +
        • cuddHashTableAlloc() +

        +

        +
        cuddLocalCacheInit() +
        Initializes a local computed table. + +
        cuddLocalCacheQuit() +
        Shuts down a local computed table. + +
        cuddLocalCacheInsert() +
        Inserts a result in a local cache. + +
        cuddLocalCacheLookup() +
        Looks up in a local cache. + +
        cuddLocalCacheClearDead() +
        Clears the dead entries of the local caches of a manager. + +
        cuddLocalCacheClearAll() +
        Clears the local caches of a manager. + +
        cuddLocalCacheProfile() +
        Computes and prints a profile of a local cache usage. + +
        cuddHashTableInit() +
        Initializes a hash table. + +
        cuddHashTableQuit() +
        Shuts down a hash table. + +
        cuddHashTableGenericQuit() +
        Shuts down a hash table. + +
        cuddHashTableInsert() +
        Inserts an item in a hash table. + +
        cuddHashTableLookup() +
        Looks up a key in a hash table. + +
        cuddHashTableInsert1() +
        Inserts an item in a hash table. + +
        cuddHashTableLookup1() +
        Looks up a key consisting of one pointer in a hash table. + +
        cuddHashTableGenericInsert() +
        Inserts an item in a hash table. + +
        cuddHashTableGenericLookup() +
        Looks up a key consisting of one pointer in a hash table. + +
        cuddHashTableInsert2() +
        Inserts an item in a hash table. + +
        cuddHashTableLookup2() +
        Looks up a key consisting of two pointers in a hash table. + +
        cuddHashTableInsert3() +
        Inserts an item in a hash table. + +
        cuddHashTableLookup3() +
        Looks up a key consisting of three pointers in a hash table. + +
        cuddLocalCacheResize() +
        Resizes a local cache. + +
        () +
        Computes the hash value for a local cache. + +
        cuddLocalCacheAddToList() +
        Inserts a local cache in the manager list. + +
        cuddLocalCacheRemoveFromList() +
        Removes a local cache from the manager list. + +
        cuddHashTableResize() +
        Resizes a hash table. + +
        () +
        Fast storage allocation for items in a hash table. + +
        +
        +

        cuddLevelQ.c

        +Procedure to manage level queues.

        +By: Fabio Somenzi

        +The functions in this file allow an application to + easily manipulate a queue where nodes are prioritized by level. The + emphasis is on efficiency. Therefore, the queue items can have + variable size. If the application does not need to attach + information to the nodes, it can declare the queue items to be of + type DdQueueItem. Otherwise, it can declare them to be of a + structure type such that the first three fields are data + pointers. The third pointer points to the node. The first two + pointers are used by the level queue functions. The remaining fields + are initialized to 0 when a new item is created, and are then left + to the exclusive use of the application. On the DEC Alphas the three + pointers must be 32-bit pointers when CUDD is compiled with 32-bit + pointers. The level queue functions make sure that each node + appears at most once in the queue. They do so by keeping a hash + table where the node is used as key. Queue items are recycled via a + free list for efficiency. + + Internal procedures provided by this module: +

          +
        • cuddLevelQueueInit() +
        • cuddLevelQueueQuit() +
        • cuddLevelQueueEnqueue() +
        • cuddLevelQueueDequeue() +
        + Static procedures included in this module: +
          +
        • hashLookup() +
        • hashInsert() +
        • hashDelete() +
        • hashResize() +

        +

        +
        cuddLevelQueueInit() +
        Initializes a level queue. + +
        cuddLevelQueueQuit() +
        Shuts down a level queue. + +
        cuddLevelQueueEnqueue() +
        Inserts a new key in a level queue. + +
        cuddLevelQueueFirst() +
        Inserts the first key in a level queue. + +
        cuddLevelQueueDequeue() +
        Remove an item from the front of a level queue. + +
        hashLookup() +
        Looks up a key in the hash table of a level queue. + +
        hashInsert() +
        Inserts an item in the hash table of a level queue. + +
        hashDelete() +
        Removes an item from the hash table of a level queue. + +
        hashResize() +
        Resizes the hash table of a level queue. + +
        +
        +

        cuddLinear.c

        +Functions for DD reduction by linear transformations.

        +By: Fabio Somenzi

        +Internal procedures included in this module: +

          +
        • cuddLinearAndSifting() +
        • cuddLinearInPlace() +
        • cuddUpdateInteractionMatrix() +
        • cuddInitLinear() +
        • cuddResizeLinear() +
        + Static procedures included in this module: +
          +
        • ddLinearUniqueCompare() +
        • ddLinearAndSiftingAux() +
        • ddLinearAndSiftingUp() +
        • ddLinearAndSiftingDown() +
        • ddLinearAndSiftingBackward() +
        • ddUndoMoves() +
        • cuddXorLinear() +

        +

        +
        Cudd_PrintLinear() +
        Prints the linear transform matrix. + +
        Cudd_ReadLinear() +
        Reads an entry of the linear transform matrix. + +
        cuddLinearAndSifting() +
        BDD reduction based on combination of sifting and linear + transformations. + +
        cuddLinearInPlace() +
        Linearly combines two adjacent variables. + +
        cuddUpdateInteractionMatrix() +
        Updates the interaction matrix. + +
        cuddInitLinear() +
        Initializes the linear transform matrix. + +
        cuddResizeLinear() +
        Resizes the linear transform matrix. + +
        ddLinearUniqueCompare() +
        Comparison function used by qsort. + +
        ddLinearAndSiftingAux() +
        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
        ddLinearAndSiftingUp() +
        Sifts a variable up and applies linear transformations. + +
        ddLinearAndSiftingDown() +
        Sifts a variable down and applies linear transformations. + +
        ddLinearAndSiftingBackward() +
        Given a set of moves, returns the DD heap to the order + giving the minimum size. + +
        ddUndoMoves() +
        Given a set of moves, returns the DD heap to the order + in effect before the moves. + +
        cuddXorLinear() +
        XORs two rows of the linear transform matrix. + +
        +
        +

        cuddLiteral.c

        +Functions for manipulation of literal sets represented by + BDDs.

        +By: Fabio Somenzi

        +External procedures included in this file: +

          +
        • Cudd_bddLiteralSetIntersection() +
        + Internal procedures included in this file: +
          +
        • cuddBddLiteralSetIntersectionRecur() +

        +

        +
        Cudd_bddLiteralSetIntersection() +
        Computes the intesection of two sets of literals + represented as BDDs. + +
        cuddBddLiteralSetIntersectionRecur() +
        Performs the recursive step of + Cudd_bddLiteralSetIntersection. + +
        +
        +

        cuddMatMult.c

        +Matrix multiplication functions.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_addMatrixMultiply() +
        • Cudd_addTimesPlus() +
        • Cudd_addTriangle() +
        • Cudd_addOuterSum() +
        + Static procedures included in this module: +
          +
        • addMMRecur() +
        • addTriangleRecur() +
        • cuddAddOuterSumRecur() +

        +

        +
        Cudd_addMatrixMultiply() +
        Calculates the product of two matrices represented as + ADDs. + +
        Cudd_addTimesPlus() +
        Calculates the product of two matrices represented as + ADDs. + +
        Cudd_addTriangle() +
        Performs the triangulation step for the shortest path + computation. + +
        Cudd_addOuterSum() +
        Takes the minimum of a matrix and the outer sum of two vectors. + +
        addMMRecur() +
        Performs the recursive step of Cudd_addMatrixMultiply. + +
        addTriangleRecur() +
        Performs the recursive step of Cudd_addTriangle. + +
        cuddAddOuterSumRecur() +
        Performs the recursive step of Cudd_addOuterSum. + +
        +
        +

        cuddPriority.c

        +Priority functions.

        +By: Fabio Somenzi

        +External procedures included in this file: +

          +
        • Cudd_PrioritySelect() +
        • Cudd_Xgty() +
        • Cudd_Xeqy() +
        • Cudd_addXeqy() +
        • Cudd_Dxygtdxz() +
        • Cudd_Dxygtdyz() +
        • Cudd_Inequality() +
        • Cudd_Disequality() +
        • Cudd_bddInterval() +
        • Cudd_CProjection() +
        • Cudd_addHamming() +
        • Cudd_MinHammingDist() +
        • Cudd_bddClosestCube() +
        + Internal procedures included in this module: +
          +
        • cuddCProjectionRecur() +
        • cuddBddClosestCube() +
        + Static procedures included in this module: +
          +
        • cuddMinHammingDistRecur() +
        • separateCube() +
        • createResult() +

        +

        +
        Cudd_PrioritySelect() +
        Selects pairs from R using a priority function. + +
        Cudd_Xgty() +
        Generates a BDD for the function x > y. + +
        Cudd_Xeqy() +
        Generates a BDD for the function x==y. + +
        Cudd_addXeqy() +
        Generates an ADD for the function x==y. + +
        Cudd_Dxygtdxz() +
        Generates a BDD for the function d(x,y) > d(x,z). + +
        Cudd_Dxygtdyz() +
        Generates a BDD for the function d(x,y) > d(y,z). + +
        Cudd_Inequality() +
        Generates a BDD for the function x - y ≥ c. + +
        Cudd_Disequality() +
        Generates a BDD for the function x - y != c. + +
        Cudd_bddInterval() +
        Generates a BDD for the function lowerB ≤ x ≤ upperB. + +
        Cudd_CProjection() +
        Computes the compatible projection of R w.r.t. cube Y. + +
        Cudd_addHamming() +
        Computes the Hamming distance ADD. + +
        Cudd_MinHammingDist() +
        Returns the minimum Hamming distance between f and minterm. + +
        Cudd_bddClosestCube() +
        Finds a cube of f at minimum Hamming distance from g. + +
        cuddCProjectionRecur() +
        Performs the recursive step of Cudd_CProjection. + +
        cuddBddClosestCube() +
        Performs the recursive step of Cudd_bddClosestCube. + +
        cuddMinHammingDistRecur() +
        Performs the recursive step of Cudd_MinHammingDist. + +
        separateCube() +
        Separates cube from distance. + +
        createResult() +
        Builds a result for cache storage. + +
        +
        +

        cuddRead.c

        +Functions to read in a matrix

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_addRead() +
        • Cudd_bddRead() +

        +

        See Alsocudd_addHarwell.c +

        +
        Cudd_addRead() +
        Reads in a sparse matrix. + +
        Cudd_bddRead() +
        Reads in a graph (without labels) given as a list of arcs. + +
        +
        +

        cuddRef.c

        +Functions that manipulate the reference counts.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_Ref() +
        • Cudd_RecursiveDeref() +
        • Cudd_IterDerefBdd() +
        • Cudd_DelayedDerefBdd() +
        • Cudd_RecursiveDerefZdd() +
        • Cudd_Deref() +
        • Cudd_CheckZeroRef() +
        + Internal procedures included in this module: +
          +
        • cuddReclaim() +
        • cuddReclaimZdd() +
        • cuddClearDeathRow() +
        • cuddShrinkDeathRow() +
        • cuddIsInDeathRow() +
        • cuddTimesInDeathRow() +

        +

        +
        Cudd_Ref() +
        Increases the reference count of a node, if it is not + saturated. + +
        Cudd_RecursiveDeref() +
        Decreases the reference count of node n. + +
        Cudd_IterDerefBdd() +
        Decreases the reference count of BDD node n. + +
        Cudd_DelayedDerefBdd() +
        Decreases the reference count of BDD node n. + +
        Cudd_RecursiveDerefZdd() +
        Decreases the reference count of ZDD node n. + +
        Cudd_Deref() +
        Decreases the reference count of node. + +
        Cudd_CheckZeroRef() +
        Checks the unique table for nodes with non-zero reference + counts. + +
        cuddReclaim() +
        Brings children of a dead node back. + +
        cuddReclaimZdd() +
        Brings children of a dead ZDD node back. + +
        cuddShrinkDeathRow() +
        Shrinks the death row. + +
        cuddClearDeathRow() +
        Clears the death row. + +
        cuddIsInDeathRow() +
        Checks whether a node is in the death row. + +
        cuddTimesInDeathRow() +
        Counts how many times a node is in the death row. + +
        +
        +

        cuddReorder.c

        +Functions for dynamic variable reordering.

        +By: Shipra Panda, Bernard Plessier, Fabio Somenzi

        +External procedures included in this file: +

          +
        • Cudd_ReduceHeap() +
        • Cudd_ShuffleHeap() +
        + Internal procedures included in this module: +
          +
        • cuddDynamicAllocNode() +
        • cuddSifting() +
        • cuddSwapping() +
        • cuddNextHigh() +
        • cuddNextLow() +
        • cuddSwapInPlace() +
        • cuddBddAlignToZdd() +
        + Static procedures included in this module: +
          +
        • ddUniqueCompare() +
        • ddSwapAny() +
        • ddSiftingAux() +
        • ddSiftingUp() +
        • ddSiftingDown() +
        • ddSiftingBackward() +
        • ddReorderPreprocess() +
        • ddReorderPostprocess() +
        • ddShuffle() +
        • ddSiftUp() +
        • bddFixTree() +

        +

        +
        Cudd_ReduceHeap() +
        Main dynamic reordering routine. + +
        Cudd_ShuffleHeap() +
        Reorders variables according to given permutation. + +
        cuddDynamicAllocNode() +
        Dynamically allocates a Node. + +
        cuddSifting() +
        Implementation of Rudell's sifting algorithm. + +
        cuddSwapping() +
        Reorders variables by a sequence of (non-adjacent) swaps. + +
        cuddNextHigh() +
        Finds the next subtable with a larger index. + +
        cuddNextLow() +
        Finds the next subtable with a smaller index. + +
        cuddSwapInPlace() +
        Swaps two adjacent variables. + +
        cuddBddAlignToZdd() +
        Reorders BDD variables according to the order of the ZDD + variables. + +
        ddUniqueCompare() +
        Comparison function used by qsort. + +
        ddSwapAny() +
        Swaps any two variables. + +
        ddSiftingAux() +
        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
        ddSiftingUp() +
        Sifts a variable up. + +
        ddSiftingDown() +
        Sifts a variable down. + +
        ddSiftingBackward() +
        Given a set of moves, returns the DD heap to the position + giving the minimum size. + +
        ddReorderPreprocess() +
        Prepares the DD heap for dynamic reordering. + +
        ddReorderPostprocess() +
        Cleans up at the end of reordering. + +
        ddShuffle() +
        Reorders variables according to a given permutation. + +
        ddSiftUp() +
        Moves one variable up. + +
        bddFixTree() +
        Fixes the BDD variable group tree after a shuffle. + +
        ddUpdateMtrTree() +
        Updates the BDD variable group tree before a shuffle. + +
        ddCheckPermuation() +
        Checks the BDD variable group tree before a shuffle. + +
        +
        +

        cuddSat.c

        +Functions for the solution of satisfiability related problems.

        +By: Seh-Woong Jeong, Fabio Somenzi

        +External procedures included in this file: +

          +
        • Cudd_Eval() +
        • Cudd_ShortestPath() +
        • Cudd_LargestCube() +
        • Cudd_ShortestLength() +
        • Cudd_Decreasing() +
        • Cudd_Increasing() +
        • Cudd_EquivDC() +
        • Cudd_bddLeqUnless() +
        • Cudd_EqualSupNorm() +
        • Cudd_bddMakePrime() +
        • Cudd_bddMaximallyExpand() +
        • Cudd_bddLargestPrimeUnate() +
        + Internal procedures included in this module: +
          +
        • cuddBddMakePrime() +
        + Static procedures included in this module: +
          +
        • freePathPair() +
        • getShortest() +
        • getPath() +
        • getLargest() +
        • getCube() +
        • ddBddMaximallyExpand() +
        • ddShortestPathUnate() +

        +

        +
        Cudd_Eval() +
        Returns the value of a DD for a given variable assignment. + +
        Cudd_ShortestPath() +
        Finds a shortest path in a DD. + +
        Cudd_LargestCube() +
        Finds a largest cube in a DD. + +
        Cudd_ShortestLength() +
        Find the length of the shortest path(s) in a DD. + +
        Cudd_Decreasing() +
        Determines whether a BDD is negative unate in a + variable. + +
        Cudd_Increasing() +
        Determines whether a BDD is positive unate in a + variable. + +
        Cudd_EquivDC() +
        Tells whether F and G are identical wherever D is 0. + +
        Cudd_bddLeqUnless() +
        Tells whether f is less than of equal to G unless D is 1. + +
        Cudd_EqualSupNorm() +
        Compares two ADDs for equality within tolerance. + +
        Cudd_bddMakePrime() +
        Expands cube to a prime implicant of f. + +
        Cudd_bddMaximallyExpand() +
        Expands lb to prime implicants of (f and ub). + +
        Cudd_bddLargestPrimeUnate() +
        Find a largest prime of a unate function. + +
        cuddBddMakePrime() +
        Performs the recursive step of Cudd_bddMakePrime. + +
        freePathPair() +
        Frees the entries of the visited symbol table. + +
        getShortest() +
        Finds the length of the shortest path(s) in a DD. + +
        getPath() +
        Build a BDD for a shortest path of f. + +
        getLargest() +
        Finds the size of the largest cube(s) in a DD. + +
        getCube() +
        Build a BDD for a largest cube of f. + +
        ddBddMaximallyExpand() +
        Performs the recursive step of Cudd_bddMaximallyExpand. + +
        ddBddShortestPathUnate() +
        Performs shortest path computation on a unate function. + +
        ddGetLargestCubeUnate() +
        Extracts largest prime of a unate function. + +
        +
        +

        cuddSign.c

        +Computation of signatures.

        +By: Fabio Somenzi

        +External procedures included in this module: +

          +
        • Cudd_CofMinterm(); +
        + Static procedures included in this module: +
          +
        • ddCofMintermAux() +

        +

        +
        Cudd_CofMinterm() +
        Computes the fraction of minterms in the on-set of all the + positive cofactors of a BDD or ADD. + +
        ddCofMintermAux() +
        Recursive Step for Cudd_CofMinterm function. + +
        +
        +

        cuddSolve.c

        +Boolean equation solver and related functions.

        +By: Balakrishna Kumthekar

        +External functions included in this modoule: +

          +
        • Cudd_SolveEqn() +
        • Cudd_VerifySol() +
        + Internal functions included in this module: +
          +
        • cuddSolveEqnRecur() +
        • cuddVerifySol() +

        +

        +
        Cudd_SolveEqn() +
        Implements the solution of F(x,y) = 0. + +
        Cudd_VerifySol() +
        Checks the solution of F(x,y) = 0. + +
        cuddSolveEqnRecur() +
        Implements the recursive step of Cudd_SolveEqn. + +
        cuddVerifySol() +
        Implements the recursive step of Cudd_VerifySol. + +
        +
        +

        cuddSplit.c

        +Returns a subset of minterms from a boolean function.

        +By: Balakrishna Kumthekar

        +External functions included in this modoule: +

          +
        • Cudd_SplitSet() +
        + Internal functions included in this module: +
          +
        • cuddSplitSetRecur() + + Static functions included in this module: +
            +
          • selectMintermsFromUniverse() +
          • mintermsFromUniverse() +
          • bddAnnotateMintermCount() +

          +

          +
          Cudd_SplitSet() +
          Returns m minterms from a BDD. + +
          cuddSplitSetRecur() +
          Implements the recursive step of Cudd_SplitSet. + +
          selectMintermsFromUniverse() +
          This function prepares an array of variables which have not been + encountered so far when traversing the procedure cuddSplitSetRecur. + +
          mintermsFromUniverse() +
          Recursive procedure to extract n mintems from constant 1. + +
          bddAnnotateMintermCount() +
          Annotates every node in the BDD node with its minterm count. + +
          +
          +

          cuddSubsetHB.c

          +Procedure to subset the given BDD by choosing the heavier + branches.

          +By: Kavita Ravi

          +External procedures provided by this module: +

            +
          • Cudd_SubsetHeavyBranch() +
          • Cudd_SupersetHeavyBranch() +
          + Internal procedures included in this module: +
            +
          • cuddSubsetHeavyBranch() +
          + Static procedures included in this module: +
            +
          • ResizeCountMintermPages(); +
          • ResizeNodeDataPages() +
          • ResizeCountNodePages() +
          • SubsetCountMintermAux() +
          • SubsetCountMinterm() +
          • SubsetCountNodesAux() +
          • SubsetCountNodes() +
          • BuildSubsetBdd() +

          +

          See AlsocuddSubsetSP.c +

          +
          Cudd_SubsetHeavyBranch() +
          Extracts a dense subset from a BDD with the heavy branch + heuristic. + +
          Cudd_SupersetHeavyBranch() +
          Extracts a dense superset from a BDD with the heavy branch + heuristic. + +
          cuddSubsetHeavyBranch() +
          The main procedure that returns a subset by choosing the heavier + branch in the BDD. + +
          ResizeNodeDataPages() +
          Resize the number of pages allocated to store the node data. + +
          ResizeCountMintermPages() +
          Resize the number of pages allocated to store the minterm + counts. + +
          ResizeCountNodePages() +
          Resize the number of pages allocated to store the node counts. + +
          SubsetCountMintermAux() +
          Recursively counts minterms of each node in the DAG. + +
          SubsetCountMinterm() +
          Counts minterms of each node in the DAG + +
          SubsetCountNodesAux() +
          Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node. + +
          SubsetCountNodes() +
          Counts the nodes under the current node and its lighter child + +
          StoreNodes() +
          Procedure to recursively store nodes that are retained in the subset. + +
          BuildSubsetBdd() +
          Builds the subset BDD using the heavy branch method. + +
          +
          +

          cuddSubsetSP.c

          +Procedure to subset the given BDD choosing the shortest paths + (largest cubes) in the BDD.

          +By: Kavita Ravi

          +External procedures included in this module: +

            +
          • Cudd_SubsetShortPaths() +
          • Cudd_SupersetShortPaths() +
          + Internal procedures included in this module: +
            +
          • cuddSubsetShortPaths() +
          + Static procedures included in this module: +
            +
          • BuildSubsetBdd() +
          • CreatePathTable() +
          • AssessPathLength() +
          • CreateTopDist() +
          • CreateBotDist() +
          • ResizeNodeDistPages() +
          • ResizeQueuePages() +
          • stPathTableDdFree() +

          +

          See AlsocuddSubsetHB.c +

          +
          Cudd_SubsetShortPaths() +
          Extracts a dense subset from a BDD with the shortest paths + heuristic. + +
          Cudd_SupersetShortPaths() +
          Extracts a dense superset from a BDD with the shortest paths + heuristic. + +
          cuddSubsetShortPaths() +
          The outermost procedure to return a subset of the given BDD + with the shortest path lengths. + +
          ResizeNodeDistPages() +
          Resize the number of pages allocated to store the distances + related to each node. + +
          ResizeQueuePages() +
          Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd . + +
          CreateTopDist() +
          Labels each node with its shortest distance from the root + +
          CreateBotDist() +
          Labels each node with the shortest distance from the constant. + +
          CreatePathTable() +
          The outer procedure to label each node with its shortest + distance from the root and constant + +
          AssessPathLength() +
          Chooses the maximum allowable path length of nodes under the + threshold. + +
          BuildSubsetBdd() +
          Builds the BDD with nodes labeled with path length less than or equal to maxpath + +
          stPathTableDdFree() +
          Procedure to free te result dds stored in the NodeDist pages. + +
          +
          +

          cuddSymmetry.c

          +Functions for symmetry-based variable reordering.

          +By: Shipra Panda, Fabio Somenzi

          +External procedures included in this file: +

            +
          • Cudd_SymmProfile() +
          + Internal procedures included in this module: +
            +
          • cuddSymmCheck() +
          • cuddSymmSifting() +
          • cuddSymmSiftingConv() +
          + Static procedures included in this module: +
            +
          • ddSymmUniqueCompare() +
          • ddSymmSiftingAux() +
          • ddSymmSiftingConvAux() +
          • ddSymmSiftingUp() +
          • ddSymmSiftingDown() +
          • ddSymmGroupMove() +
          • ddSymmGroupMoveBackward() +
          • ddSymmSiftingBackward() +
          • ddSymmSummary() +

          +

          +
          Cudd_SymmProfile() +
          Prints statistics on symmetric variables. + +
          cuddSymmCheck() +
          Checks for symmetry of x and y. + +
          cuddSymmSifting() +
          Symmetric sifting algorithm. + +
          cuddSymmSiftingConv() +
          Symmetric sifting to convergence algorithm. + +
          ddSymmUniqueCompare() +
          Comparison function used by qsort. + +
          ddSymmSiftingAux() +
          Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
          ddSymmSiftingConvAux() +
          Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
          ddSymmSiftingUp() +
          Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much. + +
          ddSymmSiftingDown() +
          Moves x down until either it reaches the bound (xHigh) or + the size of the DD heap increases too much. + +
          ddSymmGroupMove() +
          Swaps two groups. + +
          ddSymmGroupMoveBackward() +
          Undoes the swap of two groups. + +
          ddSymmSiftingBackward() +
          Given a set of moves, returns the DD heap to the position + giving the minimum size. + +
          ddSymmSummary() +
          Counts numbers of symmetric variables and symmetry + groups. + +
          +
          +

          cuddTable.c

          +Unique table management functions.

          +By: Fabio Somenzi

          +External procedures included in this module: +

            +
          • Cudd_Prime() +
          • Cudd_Reserve() +
          + Internal procedures included in this module: +
            +
          • cuddAllocNode() +
          • cuddInitTable() +
          • cuddFreeTable() +
          • cuddGarbageCollect() +
          • cuddZddGetNode() +
          • cuddZddGetNodeIVO() +
          • cuddUniqueInter() +
          • cuddUniqueInterIVO() +
          • cuddUniqueInterZdd() +
          • cuddUniqueConst() +
          • cuddRehash() +
          • cuddShrinkSubtable() +
          • cuddInsertSubtables() +
          • cuddDestroySubtables() +
          • cuddResizeTableZdd() +
          • cuddSlowTableGrowth() +
          + Static procedures included in this module: +
            +
          • ddRehashZdd() +
          • ddResizeTable() +
          • cuddFindParent() +
          • cuddOrderedInsert() +
          • cuddOrderedThread() +
          • cuddRotateLeft() +
          • cuddRotateRight() +
          • cuddDoRebalance() +
          • cuddCheckCollisionOrdering() +

          +

          +
          Cudd_Prime() +
          Returns the next prime >= p. + +
          Cudd_Reserve() +
          Expand manager without creating variables. + +
          cuddAllocNode() +
          Fast storage allocation for DdNodes in the table. + +
          cuddInitTable() +
          Creates and initializes the unique table. + +
          cuddFreeTable() +
          Frees the resources associated to a unique table. + +
          cuddGarbageCollect() +
          Performs garbage collection on the unique tables. + +
          cuddZddGetNode() +
          Wrapper for cuddUniqueInterZdd. + +
          cuddZddGetNodeIVO() +
          Wrapper for cuddUniqueInterZdd that is independent of variable + ordering. + +
          cuddUniqueInter() +
          Checks the unique table for the existence of an internal node. + +
          cuddUniqueInterIVO() +
          Wrapper for cuddUniqueInter that is independent of variable + ordering. + +
          cuddUniqueInterZdd() +
          Checks the unique table for the existence of an internal + ZDD node. + +
          cuddUniqueConst() +
          Checks the unique table for the existence of a constant node. + +
          cuddRehash() +
          Rehashes a unique subtable. + +
          cuddShrinkSubtable() +
          Shrinks a subtable. + +
          cuddInsertSubtables() +
          Inserts n new subtables in a unique table at level. + +
          cuddDestroySubtables() +
          Destroys the n most recently created subtables in a unique table. + +
          cuddResizeTableZdd() +
          Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index. + +
          cuddSlowTableGrowth() +
          Adjusts parameters of a table to slow down its growth. + +
          ddRehashZdd() +
          Rehashes a ZDD unique subtable. + +
          ddResizeTable() +
          Increases the number of subtables in a unique table so + that it meets or exceeds index. + +
          cuddFindParent() +
          Searches the subtables above node for a parent. + +
          () +
          Adjusts the values of table limits. + +
          cuddOrderedInsert() +
          Inserts a DdNode in a red/black search tree. + +
          cuddOrderedThread() +
          Threads all the nodes of a search tree into a linear list. + +
          () +
          Performs the left rotation for red/black trees. + +
          () +
          Performs the right rotation for red/black trees. + +
          cuddDoRebalance() +
          Rebalances a red/black tree. + +
          ddPatchTree() +
          Fixes a variable tree after the insertion of new subtables. + +
          cuddCheckCollisionOrdering() +
          Checks whether a collision list is ordered. + +
          ddReportRefMess() +
          Reports problem in garbage collection. + +
          +
          +

          cuddUtil.c

          +Utility functions.

          +By: Fabio Somenzi

          +External procedures included in this module: +

            +
          • Cudd_PrintMinterm() +
          • Cudd_bddPrintCover() +
          • Cudd_PrintDebug() +
          • Cudd_DagSize() +
          • Cudd_EstimateCofactor() +
          • Cudd_EstimateCofactorSimple() +
          • Cudd_SharingSize() +
          • Cudd_CountMinterm() +
          • Cudd_EpdCountMinterm() +
          • Cudd_CountPath() +
          • Cudd_CountPathsToNonZero() +
          • Cudd_SupportIndices() +
          • Cudd_Support() +
          • Cudd_SupportIndex() +
          • Cudd_SupportSize() +
          • Cudd_VectorSupportIndices() +
          • Cudd_VectorSupport() +
          • Cudd_VectorSupportIndex() +
          • Cudd_VectorSupportSize() +
          • Cudd_ClassifySupport() +
          • Cudd_CountLeaves() +
          • Cudd_bddPickOneCube() +
          • Cudd_bddPickOneMinterm() +
          • Cudd_bddPickArbitraryMinterms() +
          • Cudd_SubsetWithMaskVars() +
          • Cudd_FirstCube() +
          • Cudd_NextCube() +
          • Cudd_bddComputeCube() +
          • Cudd_addComputeCube() +
          • Cudd_FirstNode() +
          • Cudd_NextNode() +
          • Cudd_GenFree() +
          • Cudd_IsGenEmpty() +
          • Cudd_IndicesToCube() +
          • Cudd_PrintVersion() +
          • Cudd_AverageDistance() +
          • Cudd_Random() +
          • Cudd_Srandom() +
          • Cudd_Density() +
          + Internal procedures included in this module: +
            +
          • cuddP() +
          • cuddStCountfree() +
          • cuddCollectNodes() +
          • cuddNodeArray() +
          + Static procedures included in this module: +
            +
          • dp2() +
          • ddPrintMintermAux() +
          • ddDagInt() +
          • ddCountMintermAux() +
          • ddEpdCountMintermAux() +
          • ddCountPathAux() +
          • ddSupportStep() +
          • ddClearFlag() +
          • ddLeavesInt() +
          • ddPickArbitraryMinterms() +
          • ddPickRepresentativeCube() +
          • ddEpdFree() +
          • ddFindSupport() +
          • ddClearVars() +
          • indexCompare() +

          +

          +
          Cudd_PrintMinterm() +
          Prints a disjoint sum of products. + +
          Cudd_bddPrintCover() +
          Prints a sum of prime implicants of a BDD. + +
          Cudd_PrintDebug() +
          Prints to the standard output a DD and its statistics. + +
          Cudd_DagSize() +
          Counts the number of nodes in a DD. + +
          Cudd_EstimateCofactor() +
          Estimates the number of nodes in a cofactor of a DD. + +
          Cudd_EstimateCofactorSimple() +
          Estimates the number of nodes in a cofactor of a DD. + +
          Cudd_SharingSize() +
          Counts the number of nodes in an array of DDs. + +
          Cudd_CountMinterm() +
          Counts the number of minterms of a DD. + +
          Cudd_CountPath() +
          Counts the number of paths of a DD. + +
          Cudd_EpdCountMinterm() +
          Counts the number of minterms of a DD with extended precision. + +
          Cudd_CountPathsToNonZero() +
          Counts the number of paths to a non-zero terminal of a DD. + +
          Cudd_SupportIndices() +
          Finds the variables on which a DD depends. + +
          Cudd_Support() +
          Finds the variables on which a DD depends. + +
          Cudd_SupportIndex() +
          Finds the variables on which a DD depends. + +
          Cudd_SupportSize() +
          Counts the variables on which a DD depends. + +
          Cudd_VectorSupportIndices() +
          Finds the variables on which a set of DDs depends. + +
          Cudd_VectorSupport() +
          Finds the variables on which a set of DDs depends. + +
          Cudd_VectorSupportIndex() +
          Finds the variables on which a set of DDs depends. + +
          Cudd_VectorSupportSize() +
          Counts the variables on which a set of DDs depends. + +
          Cudd_ClassifySupport() +
          Classifies the variables in the support of two DDs. + +
          Cudd_CountLeaves() +
          Counts the number of leaves in a DD. + +
          Cudd_bddPickOneCube() +
          Picks one on-set cube randomly from the given DD. + +
          Cudd_bddPickOneMinterm() +
          Picks one on-set minterm randomly from the given DD. + +
          Cudd_bddPickArbitraryMinterms() +
          Picks k on-set minterms evenly distributed from given DD. + +
          Cudd_SubsetWithMaskVars() +
          Extracts a subset from a BDD. + +
          Cudd_FirstCube() +
          Finds the first cube of a decision diagram. + +
          Cudd_NextCube() +
          Generates the next cube of a decision diagram onset. + +
          Cudd_FirstPrime() +
          Finds the first prime of a Boolean function. + +
          Cudd_NextPrime() +
          Generates the next prime of a Boolean function. + +
          Cudd_bddComputeCube() +
          Computes the cube of an array of BDD variables. + +
          Cudd_addComputeCube() +
          Computes the cube of an array of ADD variables. + +
          Cudd_CubeArrayToBdd() +
          Builds the BDD of a cube from a positional array. + +
          Cudd_BddToCubeArray() +
          Builds a positional array from the BDD of a cube. + +
          Cudd_FirstNode() +
          Finds the first node of a decision diagram. + +
          Cudd_NextNode() +
          Finds the next node of a decision diagram. + +
          Cudd_GenFree() +
          Frees a CUDD generator. + +
          Cudd_IsGenEmpty() +
          Queries the status of a generator. + +
          Cudd_IndicesToCube() +
          Builds a cube of BDD variables from an array of indices. + +
          Cudd_PrintVersion() +
          Prints the package version number. + +
          Cudd_AverageDistance() +
          Computes the average distance between adjacent nodes. + +
          Cudd_Random() +
          Portable random number generator. + +
          Cudd_Srandom() +
          Initializer for the portable random number generator. + +
          Cudd_Density() +
          Computes the density of a BDD or ADD. + +
          Cudd_OutOfMem() +
          Warns that a memory allocation failed. + +
          cuddP() +
          Prints a DD to the standard output. One line per node is + printed. + +
          cuddStCountfree() +
          Frees the memory used to store the minterm counts recorded + in the visited table. + +
          cuddCollectNodes() +
          Recursively collects all the nodes of a DD in a symbol + table. + +
          cuddNodeArray() +
          Recursively collects all the nodes of a DD in an array. + +
          dp2() +
          Performs the recursive step of cuddP. + +
          ddPrintMintermAux() +
          Performs the recursive step of Cudd_PrintMinterm. + +
          ddDagInt() +
          Performs the recursive step of Cudd_DagSize. + +
          cuddNodeArrayRecur() +
          Performs the recursive step of cuddNodeArray. + +
          cuddEstimateCofactor() +
          Performs the recursive step of Cudd_CofactorEstimate. + +
          cuddUniqueLookup() +
          Checks the unique table for the existence of an internal node. + +
          cuddEstimateCofactorSimple() +
          Performs the recursive step of Cudd_CofactorEstimateSimple. + +
          ddCountMintermAux() +
          Performs the recursive step of Cudd_CountMinterm. + +
          ddCountPathAux() +
          Performs the recursive step of Cudd_CountPath. + +
          ddEpdCountMintermAux() +
          Performs the recursive step of Cudd_EpdCountMinterm. + +
          ddCountPathsToNonZero() +
          Performs the recursive step of Cudd_CountPathsToNonZero. + +
          ddSupportStep() +
          Performs the recursive step of Cudd_Support. + +
          ddClearFlag() +
          Performs a DFS from f, clearing the LSB of the next + pointers. + +
          ddLeavesInt() +
          Performs the recursive step of Cudd_CountLeaves. + +
          ddPickArbitraryMinterms() +
          Performs the recursive step of Cudd_bddPickArbitraryMinterms. + +
          ddPickRepresentativeCube() +
          Finds a representative cube of a BDD. + +
          ddEpdFree() +
          Frees the memory used to store the minterm counts recorded + in the visited table. + +
          ddFindSupport() +
          Recursively find the support of f. + +
          ddClearVars() +
          Clears visited flags for variables. + +
          indexCompare() +
          Compares indices for qsort. + +
          +
          +

          cuddWindow.c

          +Functions for variable reordering by window permutation.

          +By: Fabio Somenzi

          +Internal procedures included in this module: +

            +
          • cuddWindowReorder() +
          + Static procedures included in this module: +
            +
          • ddWindow2() +
          • ddWindowConv2() +
          • ddPermuteWindow3() +
          • ddWindow3() +
          • ddWindowConv3() +
          • ddPermuteWindow4() +
          • ddWindow4() +
          • ddWindowConv4() +

          +

          +
          cuddWindowReorder() +
          Reorders by applying the method of the sliding window. + +
          ddWindow2() +
          Reorders by applying a sliding window of width 2. + +
          ddWindowConv2() +
          Reorders by repeatedly applying a sliding window of width 2. + +
          ddPermuteWindow3() +
          Tries all the permutations of the three variables between + x and x+2 and retains the best. + +
          ddWindow3() +
          Reorders by applying a sliding window of width 3. + +
          ddWindowConv3() +
          Reorders by repeatedly applying a sliding window of width 3. + +
          ddPermuteWindow4() +
          Tries all the permutations of the four variables between w + and w+3 and retains the best. + +
          ddWindow4() +
          Reorders by applying a sliding window of width 4. + +
          ddWindowConv4() +
          Reorders by repeatedly applying a sliding window of width 4. + +
          +
          +

          cuddZddCount.c

          +Procedures to count the number of minterms of a ZDD.

          +By: Hyong-Kyoon Shin, In-Ho Moon

          +External procedures included in this module: +

            +
          • Cudd_zddCount(); +
          • Cudd_zddCountDouble(); +
          + Internal procedures included in this module: +
            +
          + Static procedures included in this module: +
            +
          • cuddZddCountStep(); +
          • cuddZddCountDoubleStep(); +
          • st_zdd_count_dbl_free() +
          • st_zdd_countfree() +

          +

          +
          Cudd_zddCount() +
          Counts the number of minterms in a ZDD. + +
          Cudd_zddCountDouble() +
          Counts the number of minterms of a ZDD. + +
          cuddZddCountStep() +
          Performs the recursive step of Cudd_zddCount. + +
          cuddZddCountDoubleStep() +
          Performs the recursive step of Cudd_zddCountDouble. + +
          st_zdd_countfree() +
          Frees the memory associated with the computed table of + Cudd_zddCount. + +
          st_zdd_count_dbl_free() +
          Frees the memory associated with the computed table of + Cudd_zddCountDouble. + +
          +
          +

          cuddZddFuncs.c

          +Functions to manipulate covers represented as ZDDs.

          +By: In-Ho Moon

          +External procedures included in this module: +

            +
          • Cudd_zddProduct(); +
          • Cudd_zddUnateProduct(); +
          • Cudd_zddWeakDiv(); +
          • Cudd_zddWeakDivF(); +
          • Cudd_zddDivide(); +
          • Cudd_zddDivideF(); +
          • Cudd_zddComplement(); +
          + Internal procedures included in this module: +
            +
          • cuddZddProduct(); +
          • cuddZddUnateProduct(); +
          • cuddZddWeakDiv(); +
          • cuddZddWeakDivF(); +
          • cuddZddDivide(); +
          • cuddZddDivideF(); +
          • cuddZddGetCofactors3() +
          • cuddZddGetCofactors2() +
          • cuddZddComplement(); +
          • cuddZddGetPosVarIndex(); +
          • cuddZddGetNegVarIndex(); +
          • cuddZddGetPosVarLevel(); +
          • cuddZddGetNegVarLevel(); +
          + Static procedures included in this module: +
            +

          +

          +
          Cudd_zddProduct() +
          Computes the product of two covers represented by ZDDs. + +
          Cudd_zddUnateProduct() +
          Computes the product of two unate covers. + +
          Cudd_zddWeakDiv() +
          Applies weak division to two covers. + +
          Cudd_zddDivide() +
          Computes the quotient of two unate covers. + +
          Cudd_zddWeakDivF() +
          Modified version of Cudd_zddWeakDiv. + +
          Cudd_zddDivideF() +
          Modified version of Cudd_zddDivide. + +
          Cudd_zddComplement() +
          Computes a complement cover for a ZDD node. + +
          cuddZddProduct() +
          Performs the recursive step of Cudd_zddProduct. + +
          cuddZddUnateProduct() +
          Performs the recursive step of Cudd_zddUnateProduct. + +
          cuddZddWeakDiv() +
          Performs the recursive step of Cudd_zddWeakDiv. + +
          cuddZddWeakDivF() +
          Performs the recursive step of Cudd_zddWeakDivF. + +
          cuddZddDivide() +
          Performs the recursive step of Cudd_zddDivide. + +
          cuddZddDivideF() +
          Performs the recursive step of Cudd_zddDivideF. + +
          cuddZddGetCofactors3() +
          Computes the three-way decomposition of f w.r.t. v. + +
          cuddZddGetCofactors2() +
          Computes the two-way decomposition of f w.r.t. v. + +
          cuddZddComplement() +
          Computes a complement of a ZDD node. + +
          cuddZddGetPosVarIndex() +
          Returns the index of positive ZDD variable. + +
          cuddZddGetNegVarIndex() +
          Returns the index of negative ZDD variable. + +
          cuddZddGetPosVarLevel() +
          Returns the level of positive ZDD variable. + +
          cuddZddGetNegVarLevel() +
          Returns the level of negative ZDD variable. + +
          +
          +

          cuddZddGroup.c

          +Functions for ZDD group sifting.

          +By: Fabio Somenzi

          +External procedures included in this file: +

            +
          • Cudd_MakeZddTreeNode() +
          + Internal procedures included in this file: +
            +
          • cuddZddTreeSifting() +
          + Static procedures included in this module: +
            +
          • zddTreeSiftingAux() +
          • zddCountInternalMtrNodes() +
          • zddReorderChildren() +
          • zddFindNodeHiLo() +
          • zddUniqueCompareGroup() +
          • zddGroupSifting() +
          • zddGroupSiftingAux() +
          • zddGroupSiftingUp() +
          • zddGroupSiftingDown() +
          • zddGroupMove() +
          • zddGroupMoveBackward() +
          • zddGroupSiftingBackward() +
          • zddMergeGroups() +

          +

          +
          Cudd_MakeZddTreeNode() +
          Creates a new ZDD variable group. + +
          cuddZddTreeSifting() +
          Tree sifting algorithm for ZDDs. + +
          zddTreeSiftingAux() +
          Visits the group tree and reorders each group. + +
          zddCountInternalMtrNodes() +
          Counts the number of internal nodes of the group tree. + +
          zddReorderChildren() +
          Reorders the children of a group tree node according to + the options. + +
          zddFindNodeHiLo() +
          Finds the lower and upper bounds of the group represented + by treenode. + +
          zddUniqueCompareGroup() +
          Comparison function used by qsort. + +
          zddGroupSifting() +
          Sifts from treenode->low to treenode->high. + +
          zddGroupSiftingAux() +
          Sifts one variable up and down until it has taken all + positions. Checks for aggregation. + +
          zddGroupSiftingUp() +
          Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much. + +
          zddGroupSiftingDown() +
          Sifts down a variable until it reaches position xHigh. + +
          zddGroupMove() +
          Swaps two groups and records the move. + +
          zddGroupMoveBackward() +
          Undoes the swap two groups. + +
          zddGroupSiftingBackward() +
          Determines the best position for a variables and returns + it there. + +
          zddMergeGroups() +
          Merges groups in the DD table. + +
          +
          +

          cuddZddIsop.c

          +Functions to find irredundant SOP covers as ZDDs from BDDs.

          +By: In-Ho Moon

          +External procedures included in this module: +

            +
          • Cudd_bddIsop() +
          • Cudd_zddIsop() +
          • Cudd_MakeBddFromZddCover() +
          + Internal procedures included in this module: +
            +
          • cuddBddIsop() +
          • cuddZddIsop() +
          • cuddMakeBddFromZddCover() +
          + Static procedures included in this module: +
            +

          +

          +
          Cudd_zddIsop() +
          Computes an ISOP in ZDD form from BDDs. + +
          Cudd_bddIsop() +
          Computes a BDD in the interval between L and U with a + simple sum-of-product cover. + +
          Cudd_MakeBddFromZddCover() +
          Converts a ZDD cover to a BDD. + +
          cuddZddIsop() +
          Performs the recursive step of Cudd_zddIsop. + +
          cuddBddIsop() +
          Performs the recursive step of Cudd_bddIsop. + +
          cuddMakeBddFromZddCover() +
          Converts a ZDD cover to a BDD. + +
          +
          +

          cuddZddLin.c

          +Procedures for dynamic variable ordering of ZDDs.

          +By: Fabio Somenzi

          +Internal procedures included in this module: +

            +
          • cuddZddLinearSifting() +
          + Static procedures included in this module: +
            +
          • cuddZddLinearInPlace() +
          • cuddZddLinerAux() +
          • cuddZddLinearUp() +
          • cuddZddLinearDown() +
          • cuddZddLinearBackward() +
          • cuddZddUndoMoves() +

          +

          See AlsocuddLinear.c +cuddZddReord.c +

          +
          cuddZddLinearSifting() +
          Implementation of the linear sifting algorithm for ZDDs. + +
          cuddZddLinearInPlace() +
          Linearly combines two adjacent variables. + +
          cuddZddLinearAux() +
          Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
          cuddZddLinearUp() +
          Sifts a variable up applying the XOR transformation. + +
          cuddZddLinearDown() +
          Sifts a variable down and applies the XOR transformation. + +
          cuddZddLinearBackward() +
          Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
          cuddZddUndoMoves() +
          Given a set of moves, returns the ZDD heap to the order + in effect before the moves. + +
          +
          +

          cuddZddMisc.c

          +Miscellaneous utility functions for ZDDs.

          +By: Hyong-Kyoon Shin, In-Ho Moon

          +External procedures included in this module: +

            +
          • Cudd_zddDagSize() +
          • Cudd_zddCountMinterm() +
          • Cudd_zddPrintSubtable() +
          + Internal procedures included in this module: +
            +
          + Static procedures included in this module: +
            +
          • cuddZddDagInt() +

          +

          +
          Cudd_zddDagSize() +
          Counts the number of nodes in a ZDD. + +
          Cudd_zddCountMinterm() +
          Counts the number of minterms of a ZDD. + +
          Cudd_zddPrintSubtable() +
          Prints the ZDD table. + +
          cuddZddDagInt() +
          Performs the recursive step of Cudd_zddDagSize. + +
          +
          +

          cuddZddPort.c

          +Functions that translate BDDs to ZDDs.

          +By: Hyong-kyoon Shin, In-Ho Moon

          +External procedures included in this module: +

            +
          • Cudd_zddPortFromBdd() +
          • Cudd_zddPortToBdd() +
          + Internal procedures included in this module: +
            +
          + Static procedures included in this module: +
            +
          • zddPortFromBddStep() +
          • zddPortToBddStep() +

          +

          +
          Cudd_zddPortFromBdd() +
          Converts a BDD into a ZDD. + +
          Cudd_zddPortToBdd() +
          Converts a ZDD into a BDD. + +
          zddPortFromBddStep() +
          Performs the recursive step of Cudd_zddPortFromBdd. + +
          zddPortToBddStep() +
          Performs the recursive step of Cudd_zddPortToBdd. + +
          +
          +

          cuddZddReord.c

          +Procedures for dynamic variable ordering of ZDDs.

          +By: Hyong-Kyoon Shin, In-Ho Moon

          +External procedures included in this module: +

            +
          • Cudd_zddReduceHeap() +
          • Cudd_zddShuffleHeap() +
          + Internal procedures included in this module: +
            +
          • cuddZddAlignToBdd() +
          • cuddZddNextHigh() +
          • cuddZddNextLow() +
          • cuddZddUniqueCompare() +
          • cuddZddSwapInPlace() +
          • cuddZddSwapping() +
          • cuddZddSifting() +
          + Static procedures included in this module: +
            +
          • zddSwapAny() +
          • cuddZddSiftingAux() +
          • cuddZddSiftingUp() +
          • cuddZddSiftingDown() +
          • cuddZddSiftingBackward() +
          • zddReorderPreprocess() +
          • zddReorderPostprocess() +
          • zddShuffle() +
          • zddSiftUp() +

          +

          +
          Cudd_zddReduceHeap() +
          Main dynamic reordering routine for ZDDs. + +
          Cudd_zddShuffleHeap() +
          Reorders ZDD variables according to given permutation. + +
          cuddZddAlignToBdd() +
          Reorders ZDD variables according to the order of the BDD + variables. + +
          cuddZddNextHigh() +
          Finds the next subtable with a larger index. + +
          cuddZddNextLow() +
          Finds the next subtable with a smaller index. + +
          cuddZddUniqueCompare() +
          Comparison function used by qsort. + +
          cuddZddSwapInPlace() +
          Swaps two adjacent variables. + +
          cuddZddSwapping() +
          Reorders variables by a sequence of (non-adjacent) swaps. + +
          cuddZddSifting() +
          Implementation of Rudell's sifting algorithm. + +
          zddSwapAny() +
          Swaps any two variables. + +
          cuddZddSiftingAux() +
          Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
          cuddZddSiftingUp() +
          Sifts a variable up. + +
          cuddZddSiftingDown() +
          Sifts a variable down. + +
          cuddZddSiftingBackward() +
          Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
          zddReorderPreprocess() +
          Prepares the ZDD heap for dynamic reordering. + +
          zddReorderPostprocess() +
          Shrinks almost empty ZDD subtables at the end of reordering + to guarantee that they have a reasonable load factor. + +
          zddShuffle() +
          Reorders ZDD variables according to a given permutation. + +
          zddSiftUp() +
          Moves one ZDD variable up. + +
          zddFixTree() +
          Fixes the ZDD variable group tree after a shuffle. + +
          +
          +

          cuddZddSetop.c

          +Set operations on ZDDs.

          +By: Hyong-Kyoon Shin, In-Ho Moon

          +External procedures included in this module: +

            +
          • Cudd_zddIte() +
          • Cudd_zddUnion() +
          • Cudd_zddIntersect() +
          • Cudd_zddDiff() +
          • Cudd_zddDiffConst() +
          • Cudd_zddSubset1() +
          • Cudd_zddSubset0() +
          • Cudd_zddChange() +
          + Internal procedures included in this module: +
            +
          • cuddZddIte() +
          • cuddZddUnion() +
          • cuddZddIntersect() +
          • cuddZddDiff() +
          • cuddZddChangeAux() +
          • cuddZddSubset1() +
          • cuddZddSubset0() +
          + Static procedures included in this module: +
            +
          • zdd_subset1_aux() +
          • zdd_subset0_aux() +
          • zddVarToConst() +

          +

          +
          Cudd_zddIte() +
          Computes the ITE of three ZDDs. + +
          Cudd_zddUnion() +
          Computes the union of two ZDDs. + +
          Cudd_zddIntersect() +
          Computes the intersection of two ZDDs. + +
          Cudd_zddDiff() +
          Computes the difference of two ZDDs. + +
          Cudd_zddDiffConst() +
          Performs the inclusion test for ZDDs (P implies Q). + +
          Cudd_zddSubset1() +
          Computes the positive cofactor of a ZDD w.r.t. a variable. + +
          Cudd_zddSubset0() +
          Computes the negative cofactor of a ZDD w.r.t. a variable. + +
          Cudd_zddChange() +
          Substitutes a variable with its complement in a ZDD. + +
          cuddZddIte() +
          Performs the recursive step of Cudd_zddIte. + +
          cuddZddUnion() +
          Performs the recursive step of Cudd_zddUnion. + +
          cuddZddIntersect() +
          Performs the recursive step of Cudd_zddIntersect. + +
          cuddZddDiff() +
          Performs the recursive step of Cudd_zddDiff. + +
          cuddZddChangeAux() +
          Performs the recursive step of Cudd_zddChange. + +
          cuddZddSubset1() +
          Computes the positive cofactor of a ZDD w.r.t. a variable. + +
          cuddZddSubset0() +
          Computes the negative cofactor of a ZDD w.r.t. a variable. + +
          cuddZddChange() +
          Substitutes a variable with its complement in a ZDD. + +
          zdd_subset1_aux() +
          Performs the recursive step of Cudd_zddSubset1. + +
          zdd_subset0_aux() +
          Performs the recursive step of Cudd_zddSubset0. + +
          zddVarToConst() +
          Replaces variables with constants if possible (part of + canonical form). + +
          +
          +

          cuddZddSymm.c

          +Functions for symmetry-based ZDD variable reordering.

          +By: Hyong-Kyoon Shin, In-Ho Moon

          +External procedures included in this module: +

            +
          • Cudd_zddSymmProfile() +
          + Internal procedures included in this module: +
            +
          • cuddZddSymmCheck() +
          • cuddZddSymmSifting() +
          • cuddZddSymmSiftingConv() +
          + Static procedures included in this module: +
            +
          • cuddZddUniqueCompare() +
          • cuddZddSymmSiftingAux() +
          • cuddZddSymmSiftingConvAux() +
          • cuddZddSymmSifting_up() +
          • cuddZddSymmSifting_down() +
          • zdd_group_move() +
          • cuddZddSymmSiftingBackward() +
          • zdd_group_move_backward() +

          +

          See AlsocuddSymmetry.c +

          +
          Cudd_zddSymmProfile() +
          Prints statistics on symmetric ZDD variables. + +
          cuddZddSymmCheck() +
          Checks for symmetry of x and y. + +
          cuddZddSymmSifting() +
          Symmetric sifting algorithm for ZDDs. + +
          cuddZddSymmSiftingConv() +
          Symmetric sifting to convergence algorithm for ZDDs. + +
          cuddZddSymmSiftingAux() +
          Given x_low <= x <= x_high moves x up and down between the + boundaries. + +
          cuddZddSymmSiftingConvAux() +
          Given x_low <= x <= x_high moves x up and down between the + boundaries. + +
          cuddZddSymmSifting_up() +
          Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much. + +
          cuddZddSymmSifting_down() +
          Moves x down until either it reaches the bound (x_high) or + the size of the ZDD heap increases too much. + +
          cuddZddSymmSiftingBackward() +
          Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
          zdd_group_move() +
          Swaps two groups. + +
          zdd_group_move_backward() +
          Undoes the swap of two groups. + +
          cuddZddSymmSummary() +
          Counts numbers of symmetric variables and symmetry + groups. + +
          +
          +

          cuddZddUtil.c

          +Utility functions for ZDDs.

          +By: Hyong-Kyoon Shin, In-Ho Moon, Fabio Somenzi

          +External procedures included in this module: +

            +
          • Cudd_zddPrintMinterm() +
          • Cudd_zddPrintCover() +
          • Cudd_zddPrintDebug() +
          • Cudd_zddFirstPath() +
          • Cudd_zddNextPath() +
          • Cudd_zddCoverPathToString() +
          • Cudd_zddSupport() +
          • Cudd_zddDumpDot() +
          + Internal procedures included in this module: +
            +
          • cuddZddP() +
          + Static procedures included in this module: +
            +
          • zp2() +
          • zdd_print_minterm_aux() +
          • zddPrintCoverAux() +
          • zddSupportStep() +
          • zddClearFlag() +

          +

          +
          Cudd_zddPrintMinterm() +
          Prints a disjoint sum of product form for a ZDD. + +
          Cudd_zddPrintCover() +
          Prints a sum of products from a ZDD representing a cover. + +
          Cudd_zddPrintDebug() +
          Prints to the standard output a ZDD and its statistics. + +
          Cudd_zddFirstPath() +
          Finds the first path of a ZDD. + +
          Cudd_zddNextPath() +
          Generates the next path of a ZDD. + +
          Cudd_zddCoverPathToString() +
          Converts a path of a ZDD representing a cover to a string. + +
          Cudd_zddSupport() +
          Finds the variables on which a ZDD depends. + +
          Cudd_zddDumpDot() +
          Writes a dot file representing the argument ZDDs. + +
          cuddZddP() +
          Prints a ZDD to the standard output. One line per node is + printed. + +
          zp2() +
          Performs the recursive step of cuddZddP. + +
          zdd_print_minterm_aux() +
          Performs the recursive step of Cudd_zddPrintMinterm. + +
          zddPrintCoverAux() +
          Performs the recursive step of Cudd_zddPrintCover. + +
          zddSupportStep() +
          Performs the recursive step of Cudd_zddSupport. + +
          zddClearFlag() +
          Performs a DFS from f, clearing the LSB of the next + pointers. + +
          +
          +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddDesc.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddDesc.html new file mode 100644 index 000000000..5f27bf530 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddDesc.html @@ -0,0 +1,33 @@ + +The cudd package: Overview + + +

          The cudd package

          +

          The University of Colorado decision diagram package.

          +

          By Fabio Somenzi

          + + + +
          + +External functions and data strucures of the CUDD package. +
            +
          • To turn on the gathering of statistics, define DD_STATS. +
          • To link with mis, define DD_MIS. +
          + Modified by Abelardo Pardo to interface it to VIS. + +
          + +Last updated on 20120204 17h33 + + + +writing ./cuddExt.html diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExt.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExt.html new file mode 100644 index 000000000..24b63634a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExt.html @@ -0,0 +1,14 @@ + +The cudd Package for Programmers + + + + + + + + + + + +writing ./cuddAllByFunc.html diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtAbs.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtAbs.html new file mode 100644 index 000000000..a476db7b1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtAbs.html @@ -0,0 +1,1415 @@ + +cudd package abstract + + + + + +
          +
          Cudd_AddHook() +
          Adds a function to a hook. + +
          Cudd_ApaAdd() +
          Adds two arbitrary precision integers. + +
          Cudd_ApaCompareRatios() +
          Compares the ratios of two arbitrary precision integers to two + unsigned ints. + +
          Cudd_ApaCompare() +
          Compares two arbitrary precision integers. + +
          Cudd_ApaCopy() +
          Makes a copy of an arbitrary precision integer. + +
          Cudd_ApaCountMinterm() +
          Counts the number of minterms of a DD. + +
          Cudd_ApaIntDivision() +
          Divides an arbitrary precision integer by an integer. + +
          Cudd_ApaNumberOfDigits() +
          Finds the number of digits for an arbitrary precision + integer. + +
          Cudd_ApaPowerOfTwo() +
          Sets an arbitrary precision integer to a power of two. + +
          Cudd_ApaPrintDecimal() +
          Prints an arbitrary precision integer in decimal format. + +
          Cudd_ApaPrintDensity() +
          Prints the density of a BDD or ADD using + arbitrary precision arithmetic. + +
          Cudd_ApaPrintExponential() +
          Prints an arbitrary precision integer in exponential format. + +
          Cudd_ApaPrintHex() +
          Prints an arbitrary precision integer in hexadecimal format. + +
          Cudd_ApaPrintMintermExp() +
          Prints the number of minterms of a BDD or ADD in exponential + format using arbitrary precision arithmetic. + +
          Cudd_ApaPrintMinterm() +
          Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic. + +
          Cudd_ApaSetToLiteral() +
          Sets an arbitrary precision integer to a one-digit literal. + +
          Cudd_ApaShiftRight() +
          Shifts right an arbitrary precision integer by one binary + place. + +
          Cudd_ApaShortDivision() +
          Divides an arbitrary precision integer by a digit. + +
          Cudd_ApaSubtract() +
          Subtracts two arbitrary precision integers. + +
          Cudd_AutodynDisableZdd() +
          Disables automatic dynamic reordering of ZDDs. + +
          Cudd_AutodynDisable() +
          Disables automatic dynamic reordering. + +
          Cudd_AutodynEnableZdd() +
          Enables automatic dynamic reordering of ZDDs. + +
          Cudd_AutodynEnable() +
          Enables automatic dynamic reordering of BDDs and ADDs. + +
          Cudd_AverageDistance() +
          Computes the average distance between adjacent nodes. + +
          Cudd_BddToAdd() +
          Converts a BDD to a 0-1 ADD. + +
          Cudd_BddToCubeArray() +
          Builds a positional array from the BDD of a cube. + +
          Cudd_BiasedOverApprox() +
          Extracts a dense superset from a BDD with the biased + underapproximation method. + +
          Cudd_BiasedUnderApprox() +
          Extracts a dense subset from a BDD with the biased + underapproximation method. + +
          Cudd_CProjection() +
          Computes the compatible projection of R w.r.t. cube Y. + +
          Cudd_CheckCube() +
          Checks whether g is the BDD of a cube. + +
          Cudd_CheckKeys() +
          Checks for several conditions that should not occur. + +
          Cudd_CheckZeroRef() +
          Checks the unique table for nodes with non-zero reference + counts. + +
          Cudd_ClassifySupport() +
          Classifies the variables in the support of two DDs. + +
          Cudd_ClearErrorCode() +
          Clear the error code of a manager. + +
          Cudd_CofMinterm() +
          Computes the fraction of minterms in the on-set of all the + positive cofactors of a BDD or ADD. + +
          Cudd_Cofactor() +
          Computes the cofactor of f with respect to g. + +
          Cudd_CountLeaves() +
          Counts the number of leaves in a DD. + +
          Cudd_CountMinterm() +
          Counts the number of minterms of a DD. + +
          Cudd_CountPathsToNonZero() +
          Counts the number of paths to a non-zero terminal of a DD. + +
          Cudd_CountPath() +
          Counts the number of paths of a DD. + +
          Cudd_CubeArrayToBdd() +
          Builds the BDD of a cube from a positional array. + +
          Cudd_DagSize() +
          Counts the number of nodes in a DD. + +
          Cudd_DeadAreCounted() +
          Tells whether dead nodes are counted towards triggering + reordering. + +
          Cudd_DebugCheck() +
          Checks for inconsistencies in the DD heap. + +
          Cudd_Decreasing() +
          Determines whether a BDD is negative unate in a + variable. + +
          Cudd_DelayedDerefBdd() +
          Decreases the reference count of BDD node n. + +
          Cudd_Density() +
          Computes the density of a BDD or ADD. + +
          Cudd_Deref() +
          Decreases the reference count of node. + +
          Cudd_DisableGarbageCollection() +
          Disables garbage collection. + +
          Cudd_DisableOrderingMonitoring() +
          Disables monitoring of ordering. + +
          Cudd_DisableReorderingReporting() +
          Disables reporting of reordering stats. + +
          Cudd_Disequality() +
          Generates a BDD for the function x - y != c. + +
          Cudd_DumpBlifBody() +
          Writes a blif body representing the argument BDDs. + +
          Cudd_DumpBlif() +
          Writes a blif file representing the argument BDDs. + +
          Cudd_DumpDDcal() +
          Writes a DDcal file representing the argument BDDs. + +
          Cudd_DumpDaVinci() +
          Writes a daVinci file representing the argument BDDs. + +
          Cudd_DumpDot() +
          Writes a dot file representing the argument DDs. + +
          Cudd_DumpFactoredForm() +
          Writes factored forms representing the argument BDDs. + +
          Cudd_Dxygtdxz() +
          Generates a BDD for the function d(x,y) > d(x,z). + +
          Cudd_Dxygtdyz() +
          Generates a BDD for the function d(x,y) > d(y,z). + +
          Cudd_EnableGarbageCollection() +
          Enables garbage collection. + +
          Cudd_EnableOrderingMonitoring() +
          Enables monitoring of ordering. + +
          Cudd_EnableReorderingReporting() +
          Enables reporting of reordering stats. + +
          Cudd_EpdCountMinterm() +
          Counts the number of minterms of a DD with extended precision. + +
          Cudd_EqualSupNorm() +
          Compares two ADDs for equality within tolerance. + +
          Cudd_EquivDC() +
          Tells whether F and G are identical wherever D is 0. + +
          Cudd_EstimateCofactorSimple() +
          Estimates the number of nodes in a cofactor of a DD. + +
          Cudd_EstimateCofactor() +
          Estimates the number of nodes in a cofactor of a DD. + +
          Cudd_Eval() +
          Returns the value of a DD for a given variable assignment. + +
          Cudd_ExpectedUsedSlots() +
          Computes the expected fraction of used slots in the unique + table. + +
          Cudd_FindEssential() +
          Finds the essential variables of a DD. + +
          Cudd_FindTwoLiteralClauses() +
          Finds the two literal clauses of a DD. + +
          Cudd_FirstCube() +
          Finds the first cube of a decision diagram. + +
          Cudd_FirstNode() +
          Finds the first node of a decision diagram. + +
          Cudd_FirstPrime() +
          Finds the first prime of a Boolean function. + +
          Cudd_FreeTree() +
          Frees the variable group tree of the manager. + +
          Cudd_FreeZddTree() +
          Frees the variable group tree of the manager. + +
          Cudd_GarbageCollectionEnabled() +
          Tells whether garbage collection is enabled. + +
          Cudd_GenFree() +
          Frees a CUDD generator. + +
          Cudd_IncreaseTimeLimit() +
          Increases the time limit for the manager. + +
          Cudd_Increasing() +
          Determines whether a BDD is positive unate in a + variable. + +
          Cudd_IndicesToCube() +
          Builds a cube of BDD variables from an array of indices. + +
          Cudd_Inequality() +
          Generates a BDD for the function x - y ≥ c. + +
          Cudd_Init() +
          Creates a new DD manager. + +
          Cudd_IsGenEmpty() +
          Queries the status of a generator. + +
          Cudd_IsInHook() +
          Checks whether a function is in a hook. + +
          Cudd_IsNonConstant() +
          Returns 1 if a DD node is not constant. + +
          Cudd_IterDerefBdd() +
          Decreases the reference count of BDD node n. + +
          Cudd_LargestCube() +
          Finds a largest cube in a DD. + +
          Cudd_MakeBddFromZddCover() +
          Converts a ZDD cover to a BDD. + +
          Cudd_MakeTreeNode() +
          Creates a new variable group. + +
          Cudd_MakeZddTreeNode() +
          Creates a new ZDD variable group. + +
          Cudd_MinHammingDist() +
          Returns the minimum Hamming distance between f and minterm. + +
          Cudd_NewApaNumber() +
          Allocates memory for an arbitrary precision integer. + +
          Cudd_NextCube() +
          Generates the next cube of a decision diagram onset. + +
          Cudd_NextNode() +
          Finds the next node of a decision diagram. + +
          Cudd_NextPrime() +
          Generates the next prime of a Boolean function. + +
          Cudd_NodeReadIndex() +
          Returns the index of the node. + +
          Cudd_OrderingMonitoring() +
          Returns 1 if monitoring of ordering is enabled. + +
          Cudd_OutOfMem() +
          Warns that a memory allocation failed. + +
          Cudd_OverApprox() +
          Extracts a dense superset from a BDD with Shiple's + underapproximation method. + +
          Cudd_Prime() +
          Returns the next prime >= p. + +
          Cudd_PrintDebug() +
          Prints to the standard output a DD and its statistics. + +
          Cudd_PrintGroupedOrder() +
          Hook function to print the current variable order. + +
          Cudd_PrintInfo() +
          Prints out statistics and settings for a CUDD manager. + +
          Cudd_PrintLinear() +
          Prints the linear transform matrix. + +
          Cudd_PrintMinterm() +
          Prints a disjoint sum of products. + +
          Cudd_PrintTwoLiteralClauses() +
          Prints the two literal clauses of a DD. + +
          Cudd_PrintVersion() +
          Prints the package version number. + +
          Cudd_PrioritySelect() +
          Selects pairs from R using a priority function. + +
          Cudd_Quit() +
          Deletes resources associated with a DD manager. + +
          Cudd_Random() +
          Portable random number generator. + +
          Cudd_ReadArcviolation() +
          Returns the current value of the arcviolation parameter used + in group sifting. + +
          Cudd_ReadBackground() +
          Reads the background constant of the manager. + +
          Cudd_ReadCacheHits() +
          Returns the number of cache hits. + +
          Cudd_ReadCacheLookUps() +
          Returns the number of cache look-ups. + +
          Cudd_ReadCacheSlots() +
          Reads the number of slots in the cache. + +
          Cudd_ReadCacheUsedSlots() +
          Reads the fraction of used slots in the cache. + +
          Cudd_ReadDead() +
          Returns the number of dead nodes in the unique table. + +
          Cudd_ReadElapsedTime() +
          Returns the time elapsed since the start time of the manager. + +
          Cudd_ReadEpsilon() +
          Reads the epsilon parameter of the manager. + +
          Cudd_ReadErrorCode() +
          Returns the code of the last error. + +
          Cudd_ReadGarbageCollectionTime() +
          Returns the time spent in garbage collection. + +
          Cudd_ReadGarbageCollections() +
          Returns the number of times garbage collection has occurred. + +
          Cudd_ReadGroupcheck() +
          Reads the groupcheck parameter of the manager. + +
          Cudd_ReadInvPermZdd() +
          Returns the index of the ZDD variable currently in the i-th + position of the order. + +
          Cudd_ReadInvPerm() +
          Returns the index of the variable currently in the i-th + position of the order. + +
          Cudd_ReadIthClause() +
          Accesses the i-th clause of a DD. + +
          Cudd_ReadKeys() +
          Returns the number of nodes in the unique table. + +
          Cudd_ReadLinear() +
          Reads an entry of the linear transform matrix. + +
          Cudd_ReadLogicZero() +
          Returns the logic zero constant of the manager. + +
          Cudd_ReadLooseUpTo() +
          Reads the looseUpTo parameter of the manager. + +
          Cudd_ReadMaxCacheHard() +
          Reads the maxCacheHard parameter of the manager. + +
          Cudd_ReadMaxCache() +
          Returns the soft limit for the cache size. + +
          Cudd_ReadMaxGrowthAlternate() +
          Reads the maxGrowthAlt parameter of the manager. + +
          Cudd_ReadMaxGrowth() +
          Reads the maxGrowth parameter of the manager. + +
          Cudd_ReadMaxLive() +
          Reads the maximum allowed number of live nodes. + +
          Cudd_ReadMaxMemory() +
          Reads the maximum allowed memory. + +
          Cudd_ReadMaxReorderings() +
          Returns the maximum number of times reordering may be invoked. + +
          Cudd_ReadMemoryInUse() +
          Returns the memory in use by the manager measured in bytes. + +
          Cudd_ReadMinDead() +
          Reads the minDead parameter of the manager. + +
          Cudd_ReadMinHit() +
          Reads the hit rate that causes resizinig of the computed + table. + +
          Cudd_ReadMinusInfinity() +
          Reads the minus-infinity constant from the manager. + +
          Cudd_ReadNextReordering() +
          Returns the threshold for the next dynamic reordering. + +
          Cudd_ReadNodeCount() +
          Reports the number of nodes in BDDs and ADDs. + +
          Cudd_ReadNodesDropped() +
          Returns the number of nodes dropped. + +
          Cudd_ReadNodesFreed() +
          Returns the number of nodes freed. + +
          Cudd_ReadNumberXovers() +
          Reads the current number of crossovers used by the + genetic algorithm for reordering. + +
          Cudd_ReadOne() +
          Returns the one constant of the manager. + +
          Cudd_ReadOrderRandomization() +
          Returns the order randomization factor. + +
          Cudd_ReadPeakLiveNodeCount() +
          Reports the peak number of live nodes. + +
          Cudd_ReadPeakNodeCount() +
          Reports the peak number of nodes. + +
          Cudd_ReadPermZdd() +
          Returns the current position of the i-th ZDD variable in the + order. + +
          Cudd_ReadPerm() +
          Returns the current position of the i-th variable in the + order. + +
          Cudd_ReadPlusInfinity() +
          Reads the plus-infinity constant from the manager. + +
          Cudd_ReadPopulationSize() +
          Reads the current size of the population used by the + genetic algorithm for reordering. + +
          Cudd_ReadRecomb() +
          Returns the current value of the recombination parameter used + in group sifting. + +
          Cudd_ReadRecursiveCalls() +
          Returns the number of recursive calls. + +
          Cudd_ReadReorderingCycle() +
          Reads the reordCycle parameter of the manager. + +
          Cudd_ReadReorderingTime() +
          Returns the time spent in reordering. + +
          Cudd_ReadReorderings() +
          Returns the number of times reordering has occurred. + +
          Cudd_ReadSiftMaxSwap() +
          Reads the siftMaxSwap parameter of the manager. + +
          Cudd_ReadSiftMaxVar() +
          Reads the siftMaxVar parameter of the manager. + +
          Cudd_ReadSize() +
          Returns the number of BDD variables in existance. + +
          Cudd_ReadSlots() +
          Returns the total number of slots of the unique table. + +
          Cudd_ReadStartTime() +
          Returns the start time of the manager. + +
          Cudd_ReadStderr() +
          Reads the stderr of a manager. + +
          Cudd_ReadStdout() +
          Reads the stdout of a manager. + +
          Cudd_ReadSwapSteps() +
          Reads the number of elementary reordering steps. + +
          Cudd_ReadSymmviolation() +
          Returns the current value of the symmviolation parameter used + in group sifting. + +
          Cudd_ReadTimeLimit() +
          Returns the time limit for the manager. + +
          Cudd_ReadTree() +
          Returns the variable group tree of the manager. + +
          Cudd_ReadUniqueLinks() +
          Returns the number of links followed in the unique table. + +
          Cudd_ReadUniqueLookUps() +
          Returns the number of look-ups in the unique table. + +
          Cudd_ReadUsedSlots() +
          Reads the fraction of used slots in the unique table. + +
          Cudd_ReadVars() +
          Returns the i-th element of the vars array. + +
          Cudd_ReadZddOne() +
          Returns the ZDD for the constant 1 function. + +
          Cudd_ReadZddSize() +
          Returns the number of ZDD variables in existance. + +
          Cudd_ReadZddTree() +
          Returns the variable group tree of the manager. + +
          Cudd_ReadZero() +
          Returns the zero constant of the manager. + +
          Cudd_RecursiveDerefZdd() +
          Decreases the reference count of ZDD node n. + +
          Cudd_RecursiveDeref() +
          Decreases the reference count of node n. + +
          Cudd_ReduceHeap() +
          Main dynamic reordering routine. + +
          Cudd_Ref() +
          Increases the reference count of a node, if it is not + saturated. + +
          Cudd_RemapOverApprox() +
          Extracts a dense superset from a BDD with the remapping + underapproximation method. + +
          Cudd_RemapUnderApprox() +
          Extracts a dense subset from a BDD with the remapping + underapproximation method. + +
          Cudd_RemoveHook() +
          Removes a function from a hook. + +
          Cudd_ReorderingReporting() +
          Returns 1 if reporting of reordering stats is enabled. + +
          Cudd_ReorderingStatusZdd() +
          Reports the status of automatic dynamic reordering of ZDDs. + +
          Cudd_ReorderingStatus() +
          Reports the status of automatic dynamic reordering of BDDs + and ADDs. + +
          Cudd_Reserve() +
          Expand manager without creating variables. + +
          Cudd_ResetStartTime() +
          Resets the start time of the manager. + +
          Cudd_SetArcviolation() +
          Sets the value of the arcviolation parameter used + in group sifting. + +
          Cudd_SetBackground() +
          Sets the background constant of the manager. + +
          Cudd_SetEpsilon() +
          Sets the epsilon parameter of the manager to ep. + +
          Cudd_SetGroupcheck() +
          Sets the parameter groupcheck of the manager to gc. + +
          Cudd_SetLooseUpTo() +
          Sets the looseUpTo parameter of the manager. + +
          Cudd_SetMaxCacheHard() +
          Sets the maxCacheHard parameter of the manager. + +
          Cudd_SetMaxGrowthAlternate() +
          Sets the maxGrowthAlt parameter of the manager. + +
          Cudd_SetMaxGrowth() +
          Sets the maxGrowth parameter of the manager. + +
          Cudd_SetMaxLive() +
          Sets the maximum allowed number of live nodes. + +
          Cudd_SetMaxMemory() +
          Sets the maximum allowed memory. + +
          Cudd_SetMaxReorderings() +
          Sets the maximum number of times reordering may be invoked. + +
          Cudd_SetMinHit() +
          Sets the hit rate that causes resizinig of the computed + table. + +
          Cudd_SetNextReordering() +
          Sets the threshold for the next dynamic reordering. + +
          Cudd_SetNumberXovers() +
          Sets the number of crossovers used by the + genetic algorithm for reordering. + +
          Cudd_SetOrderRandomization() +
          Sets the order randomization factor. + +
          Cudd_SetPopulationSize() +
          Sets the size of the population used by the + genetic algorithm for reordering. + +
          Cudd_SetRecomb() +
          Sets the value of the recombination parameter used in group + sifting. + +
          Cudd_SetReorderingCycle() +
          Sets the reordCycle parameter of the manager. + +
          Cudd_SetSiftMaxSwap() +
          Sets the siftMaxSwap parameter of the manager. + +
          Cudd_SetSiftMaxVar() +
          Sets the siftMaxVar parameter of the manager. + +
          Cudd_SetStartTime() +
          Sets the start time of the manager. + +
          Cudd_SetStderr() +
          Sets the stderr of a manager. + +
          Cudd_SetStdout() +
          Sets the stdout of a manager. + +
          Cudd_SetSymmviolation() +
          Sets the value of the symmviolation parameter used + in group sifting. + +
          Cudd_SetTimeLimit() +
          Sets the time limit for the manager. + +
          Cudd_SetTree() +
          Sets the variable group tree of the manager. + +
          Cudd_SetVarMap() +
          Registers a variable mapping with the manager. + +
          Cudd_SetZddTree() +
          Sets the ZDD variable group tree of the manager. + +
          Cudd_SharingSize() +
          Counts the number of nodes in an array of DDs. + +
          Cudd_ShortestLength() +
          Find the length of the shortest path(s) in a DD. + +
          Cudd_ShortestPath() +
          Finds a shortest path in a DD. + +
          Cudd_ShuffleHeap() +
          Reorders variables according to given permutation. + +
          Cudd_SolveEqn() +
          Implements the solution of F(x,y) = 0. + +
          Cudd_SplitSet() +
          Returns m minterms from a BDD. + +
          Cudd_Srandom() +
          Initializer for the portable random number generator. + +
          Cudd_StdPostReordHook() +
          Sample hook function to call after reordering. + +
          Cudd_StdPreReordHook() +
          Sample hook function to call before reordering. + +
          Cudd_SubsetCompress() +
          Find a dense subset of BDD f. + +
          Cudd_SubsetHeavyBranch() +
          Extracts a dense subset from a BDD with the heavy branch + heuristic. + +
          Cudd_SubsetShortPaths() +
          Extracts a dense subset from a BDD with the shortest paths + heuristic. + +
          Cudd_SubsetWithMaskVars() +
          Extracts a subset from a BDD. + +
          Cudd_SupersetCompress() +
          Find a dense superset of BDD f. + +
          Cudd_SupersetHeavyBranch() +
          Extracts a dense superset from a BDD with the heavy branch + heuristic. + +
          Cudd_SupersetShortPaths() +
          Extracts a dense superset from a BDD with the shortest paths + heuristic. + +
          Cudd_SupportIndex() +
          Finds the variables on which a DD depends. + +
          Cudd_SupportIndices() +
          Finds the variables on which a DD depends. + +
          Cudd_SupportSize() +
          Counts the variables on which a DD depends. + +
          Cudd_Support() +
          Finds the variables on which a DD depends. + +
          Cudd_SymmProfile() +
          Prints statistics on symmetric variables. + +
          Cudd_TimeLimited() +
          Returns true if the time limit for the manager is set. + +
          Cudd_TurnOffCountDead() +
          Causes the dead nodes not to be counted towards triggering + reordering. + +
          Cudd_TurnOnCountDead() +
          Causes the dead nodes to be counted towards triggering + reordering. + +
          Cudd_UnderApprox() +
          Extracts a dense subset from a BDD with Shiple's + underapproximation method. + +
          Cudd_UnsetTimeLimit() +
          Unsets the time limit for the manager. + +
          Cudd_UpdateTimeLimit() +
          Updates the time limit for the manager. + +
          Cudd_VectorSupportIndex() +
          Finds the variables on which a set of DDs depends. + +
          Cudd_VectorSupportIndices() +
          Finds the variables on which a set of DDs depends. + +
          Cudd_VectorSupportSize() +
          Counts the variables on which a set of DDs depends. + +
          Cudd_VectorSupport() +
          Finds the variables on which a set of DDs depends. + +
          Cudd_VerifySol() +
          Checks the solution of F(x,y) = 0. + +
          Cudd_Xeqy() +
          Generates a BDD for the function x==y. + +
          Cudd_Xgty() +
          Generates a BDD for the function x > y. + +
          Cudd_addAgreement() +
          f if f==g; background if f!=g. + +
          Cudd_addApply() +
          Applies op to the corresponding discriminants of f and g. + +
          Cudd_addBddInterval() +
          Converts an ADD to a BDD. + +
          Cudd_addBddIthBit() +
          Converts an ADD to a BDD by extracting the i-th bit from + the leaves. + +
          Cudd_addBddPattern() +
          Converts an ADD to a BDD. + +
          Cudd_addBddStrictThreshold() +
          Converts an ADD to a BDD. + +
          Cudd_addBddThreshold() +
          Converts an ADD to a BDD. + +
          Cudd_addCmpl() +
          Computes the complement of an ADD a la C language. + +
          Cudd_addCompose() +
          Substitutes g for x_v in the ADD for f. + +
          Cudd_addComputeCube() +
          Computes the cube of an array of ADD variables. + +
          Cudd_addConstrain() +
          Computes f constrain c for ADDs. + +
          Cudd_addConst() +
          Returns the ADD for constant c. + +
          Cudd_addDiff() +
          Returns plusinfinity if f=g; returns min(f,g) if f!=g. + +
          Cudd_addDivide() +
          Integer and floating point division. + +
          Cudd_addEvalConst() +
          Checks whether ADD g is constant whenever ADD f is 1. + +
          Cudd_addExistAbstract() +
          Existentially Abstracts all the variables in cube from f. + +
          Cudd_addFindMax() +
          Finds the maximum discriminant of f. + +
          Cudd_addFindMin() +
          Finds the minimum discriminant of f. + +
          Cudd_addGeneralVectorCompose() +
          Composes an ADD with a vector of ADDs. + +
          Cudd_addHamming() +
          Computes the Hamming distance ADD. + +
          Cudd_addHarwell() +
          Reads in a matrix in the format of the Harwell-Boeing + benchmark suite. + +
          Cudd_addIteConstant() +
          Implements ITEconstant for ADDs. + +
          Cudd_addIte() +
          Implements ITE(f,g,h). + +
          Cudd_addIthBit() +
          Extracts the i-th bit from an ADD. + +
          Cudd_addIthVar() +
          Returns the ADD variable with index i. + +
          Cudd_addLeq() +
          Determines whether f is less than or equal to g. + +
          Cudd_addLog() +
          Natural logarithm of an ADD. + +
          Cudd_addMatrixMultiply() +
          Calculates the product of two matrices represented as + ADDs. + +
          Cudd_addMaximum() +
          Integer and floating point max. + +
          Cudd_addMinimum() +
          Integer and floating point min. + +
          Cudd_addMinus() +
          Integer and floating point subtraction. + +
          Cudd_addMonadicApply() +
          Applies op to the discriminants of f. + +
          Cudd_addNand() +
          NAND of two 0-1 ADDs. + +
          Cudd_addNegate() +
          Computes the additive inverse of an ADD. + +
          Cudd_addNewVarAtLevel() +
          Returns a new ADD variable at a specified level. + +
          Cudd_addNewVar() +
          Returns a new ADD variable. + +
          Cudd_addNonSimCompose() +
          Composes an ADD with a vector of 0-1 ADDs. + +
          Cudd_addNor() +
          NOR of two 0-1 ADDs. + +
          Cudd_addOneZeroMaximum() +
          Returns 1 if f > g and 0 otherwise. + +
          Cudd_addOrAbstract() +
          Disjunctively abstracts all the variables in cube from the + 0-1 ADD f. + +
          Cudd_addOr() +
          Disjunction of two 0-1 ADDs. + +
          Cudd_addOuterSum() +
          Takes the minimum of a matrix and the outer sum of two vectors. + +
          Cudd_addPermute() +
          Permutes the variables of an ADD. + +
          Cudd_addPlus() +
          Integer and floating point addition. + +
          Cudd_addRead() +
          Reads in a sparse matrix. + +
          Cudd_addResidue() +
          Builds an ADD for the residue modulo m of an n-bit + number. + +
          Cudd_addRestrict() +
          ADD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
          Cudd_addRoundOff() +
          Rounds off the discriminants of an ADD. + +
          Cudd_addScalarInverse() +
          Computes the scalar inverse of an ADD. + +
          Cudd_addSetNZ() +
          This operator sets f to the value of g wherever g != 0. + +
          Cudd_addSwapVariables() +
          Swaps two sets of variables of the same size (x and y) in + the ADD f. + +
          Cudd_addThreshold() +
          f if f>=g; 0 if f<g. + +
          Cudd_addTimesPlus() +
          Calculates the product of two matrices represented as + ADDs. + +
          Cudd_addTimes() +
          Integer and floating point multiplication. + +
          Cudd_addTriangle() +
          Performs the triangulation step for the shortest path + computation. + +
          Cudd_addUnivAbstract() +
          Universally Abstracts all the variables in cube from f. + +
          Cudd_addVectorCompose() +
          Composes an ADD with a vector of 0-1 ADDs. + +
          Cudd_addWalsh() +
          Generates a Walsh matrix in ADD form. + +
          Cudd_addXeqy() +
          Generates an ADD for the function x==y. + +
          Cudd_addXnor() +
          XNOR of two 0-1 ADDs. + +
          Cudd_addXor() +
          XOR of two 0-1 ADDs. + +
          Cudd_bddAdjPermuteX() +
          Rearranges a set of variables in the BDD B. + +
          Cudd_bddAndAbstractLimit() +
          Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. Returns NULL if too many nodes are required. + +
          Cudd_bddAndAbstract() +
          Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
          Cudd_bddAndLimit() +
          Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
          Cudd_bddAnd() +
          Computes the conjunction of two BDDs f and g. + +
          Cudd_bddApproxConjDecomp() +
          Performs two-way conjunctive decomposition of a BDD. + +
          Cudd_bddApproxDisjDecomp() +
          Performs two-way disjunctive decomposition of a BDD. + +
          Cudd_bddBindVar() +
          Prevents sifting of a variable. + +
          Cudd_bddBooleanDiff() +
          Computes the boolean difference of f with respect to x. + +
          Cudd_bddCharToVect() +
          Computes a vector whose image equals a non-zero function. + +
          Cudd_bddClippingAndAbstract() +
          Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
          Cudd_bddClippingAnd() +
          Approximates the conjunction of two BDDs f and g. + +
          Cudd_bddClosestCube() +
          Finds a cube of f at minimum Hamming distance from g. + +
          Cudd_bddCompose() +
          Substitutes g for x_v in the BDD for f. + +
          Cudd_bddComputeCube() +
          Computes the cube of an array of BDD variables. + +
          Cudd_bddConstrainDecomp() +
          BDD conjunctive decomposition as in McMillan's CAV96 paper. + +
          Cudd_bddConstrain() +
          Computes f constrain c. + +
          Cudd_bddCorrelationWeights() +
          Computes the correlation of f and g for given input + probabilities. + +
          Cudd_bddCorrelation() +
          Computes the correlation of f and g. + +
          Cudd_bddExistAbstractLimit() +
          Existentially abstracts all the variables in cube from f. + +
          Cudd_bddExistAbstract() +
          Existentially abstracts all the variables in cube from f. + +
          Cudd_bddGenConjDecomp() +
          Performs two-way conjunctive decomposition of a BDD. + +
          Cudd_bddGenDisjDecomp() +
          Performs two-way disjunctive decomposition of a BDD. + +
          Cudd_bddIntersect() +
          Returns a function included in the intersection of f and g. + +
          Cudd_bddInterval() +
          Generates a BDD for the function lowerB ≤ x ≤ upperB. + +
          Cudd_bddIsNsVar() +
          Checks whether a variable is next state. + +
          Cudd_bddIsPiVar() +
          Checks whether a variable is primary input. + +
          Cudd_bddIsPsVar() +
          Checks whether a variable is present state. + +
          Cudd_bddIsVarEssential() +
          Determines whether a given variable is essential with a + given phase in a BDD. + +
          Cudd_bddIsVarHardGroup() +
          Checks whether a variable is set to be in a hard group. + +
          Cudd_bddIsVarToBeGrouped() +
          Checks whether a variable is set to be grouped. + +
          Cudd_bddIsVarToBeUngrouped() +
          Checks whether a variable is set to be ungrouped. + +
          Cudd_bddIsop() +
          Computes a BDD in the interval between L and U with a + simple sum-of-product cover. + +
          Cudd_bddIteConstant() +
          Implements ITEconstant(f,g,h). + +
          Cudd_bddIteLimit() +
          Implements ITE(f,g,h). Returns + NULL if too many nodes are required. + +
          Cudd_bddIterConjDecomp() +
          Performs two-way conjunctive decomposition of a BDD. + +
          Cudd_bddIterDisjDecomp() +
          Performs two-way disjunctive decomposition of a BDD. + +
          Cudd_bddIte() +
          Implements ITE(f,g,h). + +
          Cudd_bddIthVar() +
          Returns the BDD variable with index i. + +
          Cudd_bddLICompaction() +
          Performs safe minimization of a BDD. + +
          Cudd_bddLargestPrimeUnate() +
          Find a largest prime of a unate function. + +
          Cudd_bddLeqUnless() +
          Tells whether f is less than of equal to G unless D is 1. + +
          Cudd_bddLeq() +
          Determines whether f is less than or equal to g. + +
          Cudd_bddLiteralSetIntersection() +
          Computes the intesection of two sets of literals + represented as BDDs. + +
          Cudd_bddMakePrime() +
          Expands cube to a prime implicant of f. + +
          Cudd_bddMaximallyExpand() +
          Expands lb to prime implicants of (f and ub). + +
          Cudd_bddMinimize() +
          Finds a small BDD that agrees with f over + c. + +
          Cudd_bddNPAnd() +
          Computes f non-polluting-and g. + +
          Cudd_bddNand() +
          Computes the NAND of two BDDs f and g. + +
          Cudd_bddNewVarAtLevel() +
          Returns a new BDD variable at a specified level. + +
          Cudd_bddNewVar() +
          Returns a new BDD variable. + +
          Cudd_bddNor() +
          Computes the NOR of two BDDs f and g. + +
          Cudd_bddOrLimit() +
          Computes the disjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
          Cudd_bddOr() +
          Computes the disjunction of two BDDs f and g. + +
          Cudd_bddPermute() +
          Permutes the variables of a BDD. + +
          Cudd_bddPickArbitraryMinterms() +
          Picks k on-set minterms evenly distributed from given DD. + +
          Cudd_bddPickOneCube() +
          Picks one on-set cube randomly from the given DD. + +
          Cudd_bddPickOneMinterm() +
          Picks one on-set minterm randomly from the given DD. + +
          Cudd_bddPrintCover() +
          Prints a sum of prime implicants of a BDD. + +
          Cudd_bddReadPairIndex() +
          Reads a corresponding pair index for a given index. + +
          Cudd_bddRead() +
          Reads in a graph (without labels) given as a list of arcs. + +
          Cudd_bddRealignDisable() +
          Disables realignment of ZDD order to BDD order. + +
          Cudd_bddRealignEnable() +
          Enables realignment of BDD order to ZDD order. + +
          Cudd_bddRealignmentEnabled() +
          Tells whether the realignment of BDD order to ZDD order is + enabled. + +
          Cudd_bddResetVarToBeGrouped() +
          Resets a variable not to be grouped. + +
          Cudd_bddRestrict() +
          BDD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
          Cudd_bddSetNsVar() +
          Sets a variable type to next state. + +
          Cudd_bddSetPairIndex() +
          Sets a corresponding pair index for a given index. + +
          Cudd_bddSetPiVar() +
          Sets a variable type to primary input. + +
          Cudd_bddSetPsVar() +
          Sets a variable type to present state. + +
          Cudd_bddSetVarHardGroup() +
          Sets a variable to be a hard group. + +
          Cudd_bddSetVarToBeGrouped() +
          Sets a variable to be grouped. + +
          Cudd_bddSetVarToBeUngrouped() +
          Sets a variable to be ungrouped. + +
          Cudd_bddSqueeze() +
          Finds a small BDD in a function interval. + +
          Cudd_bddSwapVariables() +
          Swaps two sets of variables of the same size (x and y) in + the BDD f. + +
          Cudd_bddTransfer() +
          Convert a BDD from a manager to another one. + +
          Cudd_bddUnbindVar() +
          Allows the sifting of a variable. + +
          Cudd_bddUnivAbstract() +
          Universally abstracts all the variables in cube from f. + +
          Cudd_bddVarConjDecomp() +
          Performs two-way conjunctive decomposition of a BDD. + +
          Cudd_bddVarDisjDecomp() +
          Performs two-way disjunctive decomposition of a BDD. + +
          Cudd_bddVarIsBound() +
          Tells whether a variable can be sifted. + +
          Cudd_bddVarIsDependent() +
          Checks whether a variable is dependent on others in a + function. + +
          Cudd_bddVarMap() +
          Remaps the variables of a BDD using the default variable map. + +
          Cudd_bddVectorCompose() +
          Composes a BDD with a vector of BDDs. + +
          Cudd_bddXnorLimit() +
          Computes the exclusive NOR of two BDDs f and g. Returns + NULL if too many nodes are required. + +
          Cudd_bddXnor() +
          Computes the exclusive NOR of two BDDs f and g. + +
          Cudd_bddXorExistAbstract() +
          Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
          Cudd_bddXor() +
          Computes the exclusive OR of two BDDs f and g. + +
          Cudd_tlcInfoFree() +
          Frees a DdTlcInfo Structure. + +
          Cudd_zddChange() +
          Substitutes a variable with its complement in a ZDD. + +
          Cudd_zddComplement() +
          Computes a complement cover for a ZDD node. + +
          Cudd_zddCountDouble() +
          Counts the number of minterms of a ZDD. + +
          Cudd_zddCountMinterm() +
          Counts the number of minterms of a ZDD. + +
          Cudd_zddCount() +
          Counts the number of minterms in a ZDD. + +
          Cudd_zddCoverPathToString() +
          Converts a path of a ZDD representing a cover to a string. + +
          Cudd_zddDagSize() +
          Counts the number of nodes in a ZDD. + +
          Cudd_zddDiffConst() +
          Performs the inclusion test for ZDDs (P implies Q). + +
          Cudd_zddDiff() +
          Computes the difference of two ZDDs. + +
          Cudd_zddDivideF() +
          Modified version of Cudd_zddDivide. + +
          Cudd_zddDivide() +
          Computes the quotient of two unate covers. + +
          Cudd_zddDumpDot() +
          Writes a dot file representing the argument ZDDs. + +
          Cudd_zddFirstPath() +
          Finds the first path of a ZDD. + +
          Cudd_zddIntersect() +
          Computes the intersection of two ZDDs. + +
          Cudd_zddIsop() +
          Computes an ISOP in ZDD form from BDDs. + +
          Cudd_zddIte() +
          Computes the ITE of three ZDDs. + +
          Cudd_zddIthVar() +
          Returns the ZDD variable with index i. + +
          Cudd_zddNextPath() +
          Generates the next path of a ZDD. + +
          Cudd_zddPortFromBdd() +
          Converts a BDD into a ZDD. + +
          Cudd_zddPortToBdd() +
          Converts a ZDD into a BDD. + +
          Cudd_zddPrintCover() +
          Prints a sum of products from a ZDD representing a cover. + +
          Cudd_zddPrintDebug() +
          Prints to the standard output a ZDD and its statistics. + +
          Cudd_zddPrintMinterm() +
          Prints a disjoint sum of product form for a ZDD. + +
          Cudd_zddPrintSubtable() +
          Prints the ZDD table. + +
          Cudd_zddProduct() +
          Computes the product of two covers represented by ZDDs. + +
          Cudd_zddReadNodeCount() +
          Reports the number of nodes in ZDDs. + +
          Cudd_zddRealignDisable() +
          Disables realignment of ZDD order to BDD order. + +
          Cudd_zddRealignEnable() +
          Enables realignment of ZDD order to BDD order. + +
          Cudd_zddRealignmentEnabled() +
          Tells whether the realignment of ZDD order to BDD order is + enabled. + +
          Cudd_zddReduceHeap() +
          Main dynamic reordering routine for ZDDs. + +
          Cudd_zddShuffleHeap() +
          Reorders ZDD variables according to given permutation. + +
          Cudd_zddSubset0() +
          Computes the negative cofactor of a ZDD w.r.t. a variable. + +
          Cudd_zddSubset1() +
          Computes the positive cofactor of a ZDD w.r.t. a variable. + +
          Cudd_zddSupport() +
          Finds the variables on which a ZDD depends. + +
          Cudd_zddSymmProfile() +
          Prints statistics on symmetric ZDD variables. + +
          Cudd_zddUnateProduct() +
          Computes the product of two unate covers. + +
          Cudd_zddUnion() +
          Computes the union of two ZDDs. + +
          Cudd_zddVarsFromBddVars() +
          Creates one or more ZDD variables for each BDD variable. + +
          Cudd_zddWeakDivF() +
          Modified version of Cudd_zddWeakDiv. + +
          Cudd_zddWeakDiv() +
          Applies weak division to two covers. + +
          + +
          + +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtDet.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtDet.html new file mode 100644 index 000000000..f23e11e4f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtDet.html @@ -0,0 +1,4450 @@ + +The cudd package + + +
          +
          +
          + 
          +CUDD_VALUE_TYPE *þvalueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +CUDD_VALUE_TYPE *þvalueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +CUDD_VALUE_TYPE þcþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +CUDD_VALUE_TYPE þepþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +CUDD_VALUE_TYPE þupperþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +CUDD_VALUE_TYPE þvalueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +CUDD_VALUE_TYPE þvalueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +Cudd_AggregationType þgcþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +Cudd_HookType þwhereþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +Cudd_HookType þwhereþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +Cudd_HookType þwhereþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +Cudd_ReorderingType *þmethodþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +Cudd_ReorderingType *þmethodþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +Cudd_ReorderingType þmethodþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +Cudd_ReorderingType þmethodþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DD_PRFP þPifuncþfunction used to build Pi if it is NULL(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdApaDigit þliteralþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdApaNumber þbþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdApaNumber þdestþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdApaNumber þdiffþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdApaNumber þnumberþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdApaNumber þnumberþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdApaNumber þquotientþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdApaNumber þquotientþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdApaNumber þsecondþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdApaNumber þsumþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdGen *þgenþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdGen *þgenþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þddþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þmanagerþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þtableþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þtableþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þtableþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þtableþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdManager *þuniqueþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode ***þconjunctsþaddress of the array of conjuncts(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode ***þconjunctsþaddress of the array of conjuncts(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode ***þconjunctsþaddress of the array of conjuncts(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode ***þconjunctsþaddress of the first factor(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þonlyGþcube of variables only in g(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þvectorOffþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þvectorþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þvectorþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þvectorþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þyþarray of y variables(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þyþarray of y variables(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þyþarray of y variables(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þyþarray of y variables(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þyþarray of y variables(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þzdd_Iþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þzþarray of z variables(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode **þzþarray of z variables(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þBþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þBþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þDþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þDþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þPþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þPþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þQþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þQþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þQþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þQþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þUþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þYþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þbckþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcubeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcubeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcubeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcubeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcubeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcubeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcubeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þcþconstraint (care set)(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þepsilonþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþDD whose support is sought(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþDD whose support is sought(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþDD whose support size is sought(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþZDD whose support is sought(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþfunction against which to expand(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþfunction in which to remap variables(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þfþfunction of which the cube is to be made a prime(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þgþsecond operand(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þhþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þhþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þhþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þhþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þhþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þnþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þp_nodeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þphaseBddþcube of the phases(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þuþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þuþupper bound(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdNode *þvarþvariable(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +DdTlcInfo *þtþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +EpDouble *þepdþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +FILE *þfpþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +FILE *þfpþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +FILE *þfpþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +FILE *þfpþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +FILE *þfpþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +FILE *þfpþpointer to the dump file(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +FILE *þfpþpointer to the dump file(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +FILE *þfpþpointer to the dump file(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +FILE *þfpþpointer to the dump file(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +FILE *þfpþpointer to the dump file(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +MtrNode *þtreeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +MtrNode *þtreeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +char *þstringþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +char *þstrþpointer to string to use if != NULL(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +double *þprobþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +double þmgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +double þmgþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +double þmþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +double þquality0þminimum improvement for accepted changes when b=0(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +double þquality0þminimum improvement for accepted changes when b=0(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +double þqualityþminimum improvement for accepted changes(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +double þqualityþminimum improvement for accepted changes(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +double þqualityþminimum improvement for accepted changes(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +double þqualityþminimum improvement for accepted changes(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int **þcubeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int **þcubeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int **þindicesþarray containing (on return) the indices(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int **þindicesþarray containing (on return) the indices(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int **þpathþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int **þpathþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int *þarrayþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int *þarrayþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int *þdigitsþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int *þdistanceþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int *þinputsþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int *þlengthþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int *þlengthþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int *þpermutationþrequired variable permutation(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int *þpermutationþrequired variable permutation(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int *þpermutþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int *þpermutþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int *þphase2þ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int *þweightþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þNþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þamountþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þarcviolationþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þbinaryDigitsþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þbitþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þbitþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þcycleþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þdigitsþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þdirectionþunder (0) or over (1) approximation(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þdirectionþunder (0) or over (1) approximation(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þhardlimitþflag: 1 if threshold is a hard limit(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þhardlimitþflag: 1 if threshold is a hard limit(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþvariable index(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþvariable index(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþvariable index(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþvariable index(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþvariable index(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþvariable index(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þindexþvariable index(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þiþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þiþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þiþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þiþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þiþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þiþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þiþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þiþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þiþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þiþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þiþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þiþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þkþnumber of minterms to find(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þlevelþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þlevelþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þminsizeþbound below which no reordering occurs(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þminsizeþbound below which no reordering occurs(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þmultiplicityþhow many ZDD variables are created for each BDD variable(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þmvarsþsize of maskVars(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þmvþ0: blif, 1: blif-MV(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þmvþ0: blif, 1: blif-MV(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnVarsþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnumberXoversþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnvarsþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnvarsþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnvarsþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnvarsþsize of the support of f(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnzþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnzþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnzþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþlength of both arrays(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþnumbers of unknowns(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþnumbers of unknowns(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþsize of vars(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþsize of the array(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþsize of the array(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þnþsize of the array(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þpairIndexþcorresponding variable index(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þpathþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þphaseþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þphaseþ1: positive; 0: negative(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þpopulationSizeþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þpowerþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þprecisionþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þprecisionþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þprþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þprþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þprþverbosity level(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þprþverbosity level(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þrecombþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þsmsþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þsmvþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þsymmviolationþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þsyþstep of column variables(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þsyþstep of column variables(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þthresholdþmaximum number of nodes in the subset(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þthresholdþmaximum number of nodes in the subset(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þthresholdþmaximum number of nodes in the superset(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þthresholdþmaximum number of nodes in the superset(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þtopþindex of top variable(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þupperBoundþdistance above which an approximate answer is OK(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þupperþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þupperþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þvarþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þvarþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þvarþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þvþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þvþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þxþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +int þyþcolumn index(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +long þseedþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +long þsizeþsize of the allocation that failed(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þfactorþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þhrþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þlimitþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þlimitþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þlimitþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þlimitþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þlimitþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þlimitþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þlutþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þmaxLiveþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þmcþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þmrþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þnextþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þpþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þsecondDenþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þtypeþMTR_DEFAULT or MTR_FIXED(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þtypeþMTR_DEFAULT or MTR_FIXED(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned int þupperBþupper bound(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned long þincreaseþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned long þmaxMemoryþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned long þmaxMemoryþtarget maximum memory occupation(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned long þstþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +unsigned long þtlþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +void *þdataþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +void *þdataþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +void *þdataþ(
          +    
          +)
          +
          +
          +

          + +

          +
          + 
          +þþ(
          +    
          +)
          +
          +
          +

          + + +

          +
          +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.css b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.css new file mode 100644 index 000000000..d1824aff4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.css @@ -0,0 +1,30 @@ +/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */ +.MATH { font-family: "Century Schoolbook", serif; } +.MATH I { font-family: "Century Schoolbook", serif; font-style: italic } +.BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold } + +/* implement both fixed-size and relative sizes */ +SMALL.XTINY { font-size : xx-small } +SMALL.TINY { font-size : x-small } +SMALL.SCRIPTSIZE { font-size : smaller } +SMALL.FOOTNOTESIZE { font-size : small } +SMALL.SMALL { } +BIG.LARGE { } +BIG.XLARGE { font-size : large } +BIG.XXLARGE { font-size : x-large } +BIG.HUGE { font-size : larger } +BIG.XHUGE { font-size : xx-large } + +/* heading styles */ +H1 { } +H2 { } +H3 { } +H4 { } +H5 { } + +/* mathematics styles */ +DIV.displaymath { } /* math displays */ +TD.eqno { } /* equation-number cells */ + + +/* document-specific styles come next */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.html new file mode 100644 index 000000000..e74c4fff5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.html @@ -0,0 +1,219 @@ + + + + + +CUDD: CU Decision Diagram Package +Release 2.5.0 + + + + + + + + + + + + + + + + +next +up +previous + +index +
          + Next: Introduction +   Index +
          +
          + + +

          CUDD: CU Decision Diagram Package +
          +Release 2.5.0

          +
          + +

          Fabio Somenzi

          +

          Department of Electrical, Computer, and Energy Engineering

          +

          University of Colorado at Boulder

          +
          + +

          +


          + + + + + +

          +
          +Fabio Somenzi +2012-02-04 +
          + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddTitle.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddTitle.html new file mode 100644 index 000000000..de29df000 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddTitle.html @@ -0,0 +1,18 @@ + +The cudd package: Title + + + + + + + + +
          + Programmer view + Maintainer by function + Maintainer by file
          + + + +writing ./cuddDesc.html diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/footnode.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/footnode.html new file mode 100644 index 000000000..985c42271 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/footnode.html @@ -0,0 +1,109 @@ + + + + + +Footnotes + + + + + + + + + + + + + + + + +
          +
          ... application.1
          +
          The + global statistical counters are used locally; hence they are + compatible with the use of multiple managers. + +
          .
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +
          +
          +
          ... +node.2
          +
          When the variables in a group are reordered, the + association between the low field and the index of the first + variable in the group is lost. The package updates the tree to keep + track of the changes. However, the application cannot rely on + low to determine the position of variables. + +
          .
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +.
          +
          +
          +
          + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/blueball.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/blueball.png new file mode 100644 index 0000000000000000000000000000000000000000..9720c29504ba579244bfbd203fd05240cc94a536 GIT binary patch literal 333 zcmV-T0kZyyP)g#RC9xF*N@U2-YVd{{{fg2mrhj5B~=M<^TXndV0kN0Q~>~TBXMS zYhuj;0K5+mat8pM1^~uFF=$Bu0004WQchC fp6U^O_M`O)E)54>ni*oc00000NkvXXu0mjfsOawM_w&SE@R)n5>xJ5B z1F;(h|BF_wQV4l;JD~8s(vhjgCGtV$Ds2t(5_qDSm6|w|UPxb;>}t1HkZ N22WQ%mvv4FO#oUfIV%7F literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_begin.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_begin.png new file mode 100644 index 0000000000000000000000000000000000000000..0b3a6e230df75ccef0955e1b346f3f5a94bc1a73 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^89*$-0VEh*g05=;X{M4OzhH*_y1vP(Kwi41i(^Q| zoVQaP`4|*An7cnV{yC!lYwO-a3y*wxkhkeenwPBWB3%~WiiqBfgF#DkMW*sCI@ojR z)Qg$b($DLkNv4UkZM&BfndB5)l8PiRLd~xnWZklNF;pM8tvX0WqPPyO z;)-K=4#W4F4}GJq1>p=*HTH~8Bx4Uw@L9auPP7>(8MU{?ml;f$b($DLkNv4UkZM&BfndB5)l8PiRLd~xnWZklNF;pM8tvX0WqPPyO z;)-K=4#W4F4}GJq1>p=*HTH~8Bx4Uw@L9auPP7>(8MU{?ml;fUD+8 zX^gy=OnEK3Q}m;lhza8yZV|7cVql)yXw0 z;)F+4%2HdS18kr6xbR7A&A75Cu)A%7Ys%EgTe~DWM4f D4qP>Q literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/contents.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/contents.png new file mode 100644 index 0000000000000000000000000000000000000000..0c752c66c876acaa2131d43788a7406f5979f746 GIT binary patch literal 278 zcmV+x0qOpUP)n_8B^;cn$O_g|3BG{!1Fj&^JiWpJWLeA$WK=+#U`gfB`ZJpvc?v;;IiS zWN}RlBW%jSmz3^2R|i?JM0KMv+9z;7ee@a!R<*>X0K7&N_)1@@}28%Z6=9 t-O~MHw|5t0`TuI#<-T9Me##YR_J!+(UN4n;@(5@ygQu&X%Q~loCIFb&G|K=0 literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/footnote.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/footnote.png new file mode 100644 index 0000000000000000000000000000000000000000..4591c0eca1231a8dd51f936b46363bcb9c35cefd GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^{2FS zrsoVLnH6~&F0zL+P8GD|SkqyVU@2Hw;H_Hnf}ux6|G)cetK3(c&T7OiHM_`p-Fn|I zk6S7tu`7hSPeski&6e)S+V5Vl<++E- m`l!8MrB+YxvAz2@`46M@GoAfWMa#rMF7kBsb6Mw<&;$UT-9{4t literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/greenball.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/greenball.png new file mode 100644 index 0000000000000000000000000000000000000000..a4d714533a8c5e836f167a2118108d4f68bcf2f6 GIT binary patch literal 333 zcmV-T0kZyyP)&2#{24FFmV07?x2oE8Aa z832?P0IV5GoK*nU90=AYkN=AR&L1KFKLAl@PcFG!4j{1mTA&&;ze)eFnmrpph=4*Wd1;<76Q uRfVXn4m>Ir2oglLH2I2lWqskW{Rg3J}7qSOsCi?q75nH?M zE^{77+Z<+1r-r1Nch|4lthS=d{J1PfXUU1#ym22LZu_2=vAt}Pd}!6<{pzf1?Y4jM u^4(GWO*wx3{4#&$%6k3J$8QJwOy|GN;;5Q**1ZVmMg~t;KbLh*2~7aKlwD!~ literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/next.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/next.png new file mode 100644 index 0000000000000000000000000000000000000000..1628652aac7cff4b24228abd9908c320c6026a7c GIT binary patch literal 245 zcmVQ2aP`rsfsL)H8>rF50IrEKQ7U2mrM!9=R9*Dw1X+@W9RTx^a-#5T6$bi^4|h!q3s vo9V3RdqZP$JTTh9!JZ)`voZLAB<&|;0_>J~#QNZkD16SAR=O4@7anKqmC5&ngT;#rH1+qK z20S~FlZynq-MY=T{~%>KNs884sExd44P^%bf!zNDPxW#x21^f><@$FgzM-=J5cLN5 WGDyh~oC>l40000tyuK1_JOFF_cfRLygYKXs-cjquE z6qZUgCnOS-qR#wjl*#Yu6x>pYvGz*5sgT3Ky$sw{E$HaO|9>UJNF+j;OnPJjVj%;{m_nqs0ZqV}||YZyJu#*Jw}23cUX_af%9 z{uS~*k`LH^Qb$R+lmwPEN^IYqTH-Vq0YzE^cOwaMk&itdVwtMByf}E>Y3%dwD5Z9*>tJ(L)x+ zsQ6o00>F0uiF$f}|EHc` gW14v)`Zh=L1v(Lj=i40@mjD0&07*qoM6N<$f}?G$umAu6 literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/orangeball.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/orangeball.png new file mode 100644 index 0000000000000000000000000000000000000000..10249c668abb037b32a1d537d66e9e2999bbc30e GIT binary patch literal 333 zcmV-T0kZyyP)AS^$Jp5VUCk#in}ymj~{O09rHvS~38OWibEI zrMztboOepzfdEP?07@wUtYiSqpJM--5C4`Aaz_u&dk|_o0L7(x)_4H_#*6==A;xn6 zazX&SY5-z60RN>ilvV(>R1Y8k0004WQchCd@h{G;iGOwP-k9UVO50Hcelh_;^S8s zlr19Cn;yHsWZodf)(Q_M@X|8FKV`iT$$re%Hlc^|+B?5ptZnip-JzW5walZJkLkqq fd#WKa^^evk#2W_K-Vq6^00000NkvXXu0mjf&K`=A literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/pinkball.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/pinkball.png new file mode 100644 index 0000000000000000000000000000000000000000..5b92325708e4bec4699d8b15e7ed285b55e9d6b6 GIT binary patch literal 332 zcmV-S0ki&zP)2P*}kMa>gUTJl$kP*V4^b)U_hOaP4 z(MBY9-{*nl_&|=WXFRCDeMJQS)O6OCS>LQ})^E1QPP=rmVxHz?hoKhgB esft+@KU$ytO$Rt^R9;{J0000fWJ4@hJr9=)Yx5|PDs2VC9?nk002ovPDHLkV1i^Ya=-up literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/prev_g.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/prev_g.png new file mode 100644 index 0000000000000000000000000000000000000000..476d9568c900e2ada6c2019b67eeee166a5f1288 GIT binary patch literal 327 zcmV-N0l5B&P)18~ zIpil5yY|hg&aw;rvXQ~olHp&x|G5Aw{ug* Z|8M28X+2RX!WaMm002ovPDHLkV1gF^iYx#C literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/purpleball.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/purpleball.png new file mode 100644 index 0000000000000000000000000000000000000000..d6d63fb822774678fbdd5da91b990f7b2be62997 GIT binary patch literal 332 zcmV-S0ki&zP)cTL6T*5C5-v#ny}en+VpE0M1bWa-{&~l>pYN0PeN`{l6jq+ok_+0GxpU zv@`%ph5)>_5C4q-#zp{QJ^)&S0K8%lgso!Df=ZlJ4{~V$lyNYNvH<;i0IaZj#WMg( zr9#fQ2meX{YCr&5ln~C}Z~OcJ0004WQchCK~#90#g)sEgfI+5A5%`N^P6zUU=N+dWI!5wkbi)oX1q1EeE{2PAz43` zjUI_tURl5+mNtM{cI5QxcaO3##>=)7a%RRi!C3=ixYOHP-y>bCt&dAl_~Pn=2Yv!r zIRI2Yf3EG_-QgN*3JYpS)}FGLc3w*194)5Q2wO$$?irWMpHpxZimD#{vRQw!W>{2Hx>KfrC3+}RpurNIMf0(44muQU=B5BoHh7m+`5KXsClX!R|pfonPY z@$RA_h4!9T%^dHQNzNCPkzC41E>31^)OKcj5cr=xaE@2f8U}+F0fQ(8 z@xKg#XOpV_8&*XzDC}XdxW?hQg~8w&gJTkdcngEZIj5{{1JAQb&3_p@_b?dT0~)*Z z-7^NqECvN5<(>$jGZ;&P{DK)Ap4~_Ta_T)@978JR)b{1_HyQA>>~8XV&C*`>K*a3H z*Z=>W%#XZaf2{g;vbWxJW{#qdHw)65`X_ZAm|s{r^NV26`?o^#C2y}csF>;cM0&1T zV{EB%-&)()&bP0l+XkKm7#uU literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/up.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/up.png new file mode 100644 index 0000000000000000000000000000000000000000..3937e168f44bc997766dbe3b9383bd1db44f094d GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)h#LU3J`0lmo0U(Dbz$e6Y|Ni~?`T5VEKaXZ$ zILr2UCs3TRB*-tA!Qt7BG$5zc)5S5QVoq$YAz!lrkL&!DV=`*aVJGv=2TrrsUKR?`=XF~0x$5q(BOL&qeQ?X^G$FnGH9 KxvX2RVNRAoooEaAn8>@(e1sRI!V#<^f)p#-WVQt^!{}{R!<_yH~7!&%|GmpxjXG& eckJV{U(78Bbom$-1qlM(%HZkh=d#Wzp$Pz8Iac=o literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/whiteball.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/whiteball.png new file mode 100644 index 0000000000000000000000000000000000000000..9d3056253edcd186983168a96518bf84b7dfee94 GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^d?3sLBp7{FoMr=Qrjj7PV21s=zR9XU-aJni$B>FS zsb?1Q9Wsz`eRz4<$*!ykmsgzhGIFk9xyN|?aY7}F+Qi?6n?06!q!zxu(#FVQ(7fx} z9e>VQZk)e3KXoNpGz(q0`D$5is3xOo$~3v&=wIs&UUDHlX>5E z9S;zGC3EdoszqA)r|Kp{Ii!hv< zN=iup;^qMT{Q&>|5BmK8&COz_tN?Iw0M5-2`~L@zlmPqxAw^06#l?EAv;cyH5SN?) z|NAk|)(C`y0JgjU$Ibv2|F}*70004WQchC))ZYaU)ksQTISgKb3Rb} fo+=PU`=j*<1)c{R%U83*00000NkvXXu0mjfomZ1* literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img1.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img1.png new file mode 100644 index 0000000000000000000000000000000000000000..6082d1b9ad58139a0f3364a2754c623968379213 GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^LO`s*!py+HI4hJj1jx|}@Ck9kPs3Q;^E<8V`F1rV4$L+!o$O}V#SJ8`5V1~x)@7>{DK)Ap4~_Ta(q2q z9780gCMP&BuHksb%2qPrzyV$rOM@el5)lnE?lPQtB62{;$GVEUQ?}r0_?Id56g9l9u^1tybh2Gc(A~U@v?V{pT~#UB9LPc;1lAydGqEKD^|>zGiSnt z2`w!x6%`dZIXMXl2_YdN9v&VxHZ}$Z1}Z8l5)u+TJUl>6uOd&+15%77L4Lsu4$p3+ z0Xc!5E{-7_Gm{e>82G{rP98Y$y`fQ&LF)v+(u~T6BkXo;DF;}mF$m@|DMYd>Y<$2p z!62e-P0wfjDH~;-Hrni+&ah~ww1izlhCN#!r$A;MCo97-W8O3CLO8Ah4QKFl^>bP0 Hl+XkKMA<<` literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img11.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img11.png new file mode 100644 index 0000000000000000000000000000000000000000..9509b94b974ebceda7307b1464cff41d092dd978 GIT binary patch literal 476 zcmV<20VDp2P)RHR400001 zbW%=J06^y0W&i*IT1iAfR5*?8Qol>XKotIB65E(GNjEq1C-ff>`WKYWg3v*9G`mYc zaIUjUKyVYf6`Y)0z12av#Z`jfqUhOscNb401agtq6#GM((*ZSG0@&w*5zR?Vp&JFjHZYw)R1{_DDabix!g7 zN(IK0TlhoZj7&cRCMN4YA+4=D+ufyUsPT{OK+%!xlHHfY^?EQz@`3E<$=wK0#zIu; z?Kmo#9LSUeJ>819WYEjzJZg=MxOW2cC~DL6s2BJ#{L{wJ26OMV89dkC&AB{oS}{a@ zS|*E0000RHR400001 zbW%=J06^y0W&i*IsYygZR5*?8QoBw9K@>d;>@MIw(8|J?>1`-&jC=wywj?wfE3vYb z+5{gzKuD~O)K;1pTeq+^*-i@s8xkypWSu+vU>~4RnsAakb7t?HduPuK;3Ln2@yH-= zXxPW^uxQXtWmewiA%(2TqY%k5F&3>qnxu=-@q+F?qP2}zzC74`36mur+jDlA7po!b z@F>EwPMm`d=DH)ON8iBdWe4m*LPitEpbf4&2AoP8X08BCYkDLY7# zU6v%ZbS15lBu_|?hTDxvjvp^h4x>c*Tz^;UQ9_Ugh@RHR400001 zbW%=J06^y0W&i*Iu1Q2eR5*?8Rl82YP#FH&LR+A47@TXJT>A*jPP~9g-7q1hkHBV} zSO&QRoIk9)L%Y+im3u$m-yS?=LkV7l0n`^iWLJ`qUav>_=ie|0PP1MJE{ z+nQ?aDeF`tQ;eA%vrGG1KcrQ=r1xXtk=hxZ!_qqy^fYx9Yy29nn^K2wmF0bp((0nu zEQK516^9)B&APDr*fzWJUXKJltT&RBAdrcF1{(l&6WIR@gphBk>Wr&fDbxn);m9?3 zUlMsEI&~d<0GnPW6Y=s%5C>6vK}CZr1>`HzmwBnATIno*Vi2eYmB=2N)F|G*c2cWO%q0|3YX0000RHR400001 zbW%=J06^y0W&i*JAxT6*R7i>KR=-OeK@|RWz1utQ_Q%C4MF`v5Sfvy1PdGwa!Aer) zQiW8>)&Ud!2Sl(ItSv-AY;#50z;>|^9fU+kgvq?wnc110lW^F@`{3Ta_vV|AH$NV; zfQ7F3G3AFMVjRf;uP_5bU?QCuC=vaOUXmF!GX*k^ZDhB?zh?DV4y!=)CbJagBPA24 zAS9C@^H{P7&bnk4^~`U=L?gkb9m7{cHY;gAth9&ViShQd(>1A{@d`3x2RZ+P&gjLEJmR8tzuyAn&n?o3&zf7E2h9fFrk}Ln!rr6>qym%+Y|k zMX5;z#w*EO>FC~*mDnR=b~`co+<0_svZ3Vt#}EnUOx*%P^A-rMx-2a%LHa4plC@lO z4#+;?{8rbps2D*W{i-HqE!|5?SQ}L}u;CV9I`I5wtlSIT=ka(nC?z-DlIyKkpZbl9 z1?a2Saq@BEb5{!GM4>-8$Nz}-ftOmi@o8)MY_xTMEFLPStaE36O4I7DuW4g`=t#af z{rq-Q2i1!hT|WI0Z8#~1raHu-1~p)_=LD_-n@CmiWPI_%$YD@ zLQ6|aPEJljLPAJLh=GBDii(Pagai){4^XXaSl_!@p7{W0# z8K@zhp_!S7=L}E50p@hZqm5oOBqYwwi9FE2!zHnxs#2kasU!Npftp7=T}EwZjF&6& uOj8aJ>|@h7e4O#riv}sy5T#u+85vZgc_!?AeDx;KXa-MLKbLh*2~7aK8$K2Q literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img16.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img16.png new file mode 100644 index 0000000000000000000000000000000000000000..2a761cec18c990da32810254f9db52ffe85ad543 GIT binary patch literal 223 zcmeAS@N?(olHy`uVBq!ia0vp^LO{&V!py+Hn6rMEP z6IxnYDk>^+a&i(95<)^kJUl!M3=C9MR3s!MczAe#I-D8z?*>wgB|(0{3=Yq3qyaez zo-U3d95a&>8kh_XPO?7yu+dYS{A9%ziqp)c` zqwmi(<>w{8-3?;c6d`YD&~VkDz&{}&fPM2L5eW$et1u%21J#Dexm;@|H;OR)tmVHj TKVXU#&@Ki~S3j3^P6nbtJynBUmAxRH^~?nCoR&KQSBf4|4Eg#`R) zWcRT9!SJkxMNpnZMM)6 qi?$LrwtEZ)r<)qLKI~#)W@eB+CE3%V^>i=Leg;ohKbLh*2~7Y~L{>Ba literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img18.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img18.png new file mode 100644 index 0000000000000000000000000000000000000000..c08507b88acb3cffbe165f81eed7aedf44e8d0e2 GIT binary patch literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^hCr;q!py+HXlK8-9mp{V@Ck93?s|A38I*di0fMz(B`cdWH4eT>Il zHM|=_k~^9HvfUA26Yu!JaHPiJ4F3^fJDUarhZ%{pn3@isD_}gB$??G<=vc!UiIfF% zKJH;WER{0x-)Dhe^34C)R|wckot<#s;vsXGWFKdb40pqq-~Syx$a=PIZCrS8I_qq? u1(%xsd7n`F_y5230?Wy>P2zc-7#R39RlZ6w8GQh{nZeW5&t;ucLK6TQ_Gl;o literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img19.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img19.png new file mode 100644 index 0000000000000000000000000000000000000000..1b152d483a1e0fd81ba2349625b9a79bfd9b65a1 GIT binary patch literal 409 zcmV;K0cQS*P)RHR400001 zbW%=J06^y0W&i*I7fD1xR5*=eV1NLA1|EhF0$}C`eg+(X9hU?e*Z{-_fCe!nd>~Q> z1H%F&HXG0Ywgw=B?*UYV3F0&cW}?j_9R#589w3-7PXsK0@h(6F5?~4xpc2 z1g3c5wsE7TyNhrZ+hZ7ukNEU7l7O5XVKvC06OSCW5WWH;c>jX{FlRCq0XxoBs^R-~*dc0Az7YU|?7YHHEW*0WNm{$YT7&;NZi+kK!JA1r|7)UjfB* zo@f168Te4upUe0g0Ap`hfyGNa3bGK!1_FK`1rz}Qzxzn9e2?1q00000NkvXXu0mjf DYgU%k literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img2.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img2.png new file mode 100644 index 0000000000000000000000000000000000000000..022cc6a0bc1d2a79493d179c99d8c4c4924471d7 GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^LO`s*!py+HI4hJj1jtbd@Ck9eSqp2OM?7@862M7NCR^GJzX3_B&H?< zH9SagU}803vu2h`Xi4IEz_4(Kdc%pl9IXOo#*SFFgf8A3A>$LAI-DMA!Q3mvm2M=R s<@mOZRbbXm-bXUiR!XnPHe_L7NXcUVTK#DnJJ4tbPgg&ebxsLQ05*3!p8x;= literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img20.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img20.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd4c942bfc89fcf1ca31cd3bc57a7ec99ad4eda GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^VnD3G!py+HICEP z6IxnYDk>^+a&i(95<)^kJUl#XY-|h+3{+H9BqStwczA%CUPYds2c#HFg8YIR9G=}s z19EaaT^vIsrX~ZmC8Qi+6*6f3A=gmC!1;`A&Mk)rOrOIQD(6l;$gtk%kHT_UpN&Ny zV;F*LczBo`y5@H#GP%rPn(WE&Do6dtLm9pWSEX;rH{AThrNhJXhF9U)&Yt~@JZCtW j3{rdE|Ic60nat3>S8&(gLtWfJdl@`k{an^LB{Ts5Hv3VJ literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img21.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img21.png new file mode 100644 index 0000000000000000000000000000000000000000..49c39a27762847710af4a4887c3abb0f11b5fdb7 GIT binary patch literal 614 zcmV-s0-61ZP)RHR400001 zbW%=J06^y0W&i*IKRl82yKomXp`hj;HdzFfU!Zm63574QH_*5UDtW}!7y35+HIUSefL zMlO9m4YT(6BO0A2KgIt;>ntu8dCg(A@)O7o(AZa+RdGRC|A6D7AiwGBc$ATj+>Kw{ zP7}@Zuoa^yZfLD8Qx$+d!<6%LdLJ1Rd?O;+r?>Qj;zw!|iN7__(|5NuweWAwfVupvuZfs6jwL);01Oz#Rtc0kBSMH@@jOlp|s-@CKne1`O(>s|*AG{f4aw0^T=wDOz!UV!ujRB6< zc6T}THck|5sTFv&MO^}OORg_{!Rv;-eWi$ zY6qJUHCJIh2aa8D0E1UFO5$@dXX>%)1<&Z;XaF8riE+YcnaNlKdKjb-M03h(ZVuSJ zQK*LM@o+;h+DTsu3k-*cV#Z29%5n95Dp}bG@2_#Zpf8P&KX%M$thBzEY*vvFrYbSf8`Kt)>05d&Fuo_USeAM&=-q-j-<99mbn~dm^)lfE_+tWv5IUC2gt~S7;)I-Myni25rhdc%8FAy_;P1xQ zie8+Y$N^sVU$bWl?|dcST8yJIizf;53vvc&^ya2tPQDDJ(n$S6P&_P^gd2Oy3Dg3` znTi?5k)o&Do)0x^C&N-@ZK5>OK`0X}7J*eB;!Gpt=Zj+RQM?%uxUUobkYs&NU5%AD z#(BjlR?gE($ehOIRaOZ=Y63s6AhzwSNY$@Cb-ylLEJI=tQd{HD3`&q~`kp`epVXFL z{h0pXeT3H2Ge<2{%#3Qo9A}2-`r8~3+(GK5z>pG-K-Onp9Gwg*W#-90mcg=YJ8YUG7F3ve82K}jA2~g}(bARxMz&p|(e}Geq_n?{ zeIeC({iaR8BXB@50r871KuiqOG?2O+Xgde>L+N8QcD2odd$83*(Q=)PFFmP^Z>}zf zVset^iiJjg0Q*P8JTP{hCKO0d-XR)z7@re4eVJE&Kh(Q2{D8;|Nx-i*;AytHj@v_i zc!U_%t%^pk3r8PKrPjvBWCEmW?Ihh`L|Y4MzZITKy-?^^S~rtHv=yka@Y^l_(Z*)E z5KW6>8MIwD#LOL~hT;9@DG|3!}cQU4AY6kBb*DieI zf-OeQ%IoJ9?Vro8FN`Tv!};qF$X^xvN$S>C813CQE70$Je~q>!vUzl$FezxYkgW#2 z=G3RH`!v5d5wC3oIxqOup7MF{BGt3H#5X}PdR6W}@?E}RH_p{G*x3bmWFYG9BO8^c z&SHgy|1fOY1aC&6$53Gjy#a9yNHJ*o4eqeng`_XWY&~(YBFp%`B)2_jD7svFcYmfn zyh$f-l1BQ&dQ1>}bDvZ@Sp#aBV~nVZ9A*hwhyPG6HG9vWDO>1hR#9%@XM!bS(U5lHxF|#GV}tOjjgApvYCucQZvS@Yw7A{KDTjh zF7TIAUBUm*=TtDy?N~(#KE8S#9CR}ex&Os$0qzy533{=yvmf{ABm3z=2G>1z+ZW7; zTrczZfL~A$ShwxN;!nJgL>D7r)N5$@h#ak1ZCK{oklci#q7Auh`V`H*l>8jTi0bht z???~YVDt3)q%WWr{pu*Jv%SF1v$kHOEdC08ZSFgEu91tu(g?)~D;7W75pcDpGviK( z3b&%hvwvS7Oe&4{7pm19@vx64^b67H$BMbGjK5gVD0FJ^;uY68&w0sn2aihiy?;>w ze+H*U4QODdcQt~$I)8PHf=}66&2lQ+xdoGY(LdcKiC5u?r!vHa08$H2nKp}`!LSKU z@*8ztMi&!y=M@i)G+_^W0qNyNK}p4a+wA7iEf;1W` zsP;GXcPyMDQ}g2}-?*HG-jLR2kCtv4@_}Egg*Q2}4~UALn}qGC;pY^xzsKW#V_nt% zJjNWM;M|a$#FErd70q8>lZ?K^vOt99cl^tUB)-Cud(tuQsF1ES`_f_bMF5I>QlcjZ z{9^rRBH8_VP|u8Imdw9b}FF1XP?AfJ=0k zfruGQ2Fd&BM*h`MN*6yxwM=YMI1qxz@}O3|Af4Xrn>O~Pz(bmR*qaps_wwYR8{@9} zGCkB5bTl?j@^@fg-OqzRNf(buCf}i`BsyjZoTeCGkh?mbv%zaW=1M-RE7SSTQmLus z!S^;U-Mgn+;_2B{a4+h&E7^PLlAgEAy*cP7tZ5l|&yuJ1deJi=!2F~|mL+iu+ z(MVIhbKKyAi!9&AYetPV>j%%VrbzQO=`bebH36bs-drZ^F2Y0U6x`kfRJZ+}IWuiK zyhDnKiF2!(9K>5LH?V~R^N6Pd_@l2tvFI=M3jDib`l4X}Gg7q+nEFmG=0hF>`z^9u zy=0G)M41DIL8^v*VQ|#EAkmQ#Sl?);nZSz&7 zv=;A=;nLKRVzI^SSARE~-bLx=wKAVL->WjkoWnrw)d$#(`{hk{2i}b0E!&_#;*lH< zJ@YW(C2IKJ+#A%Yn;L0`oW&j#sY0cO^n$iw*KedYdT2L#OU4<$(74xHLxa>TF0f*p zdZ&@s(y*k$a-3?2(ebA;uefh#_nhbp2J-d{LMSHBOSb$kpbtmeH%%jb6<7SOm|j7j zH(OGTi^Be1ughBnb;aNa#lp9qZf4s|-UjGJ2Yk{9*xl=psG)XW!$ngwZn_62$L@io zvO)=?ZU~zuq|#D}WD7XfQ^ZMX8SZd>TM)TDrXkkzhyskoE-sx@2BPxr?jVU;7$(iC z@G#cGfXWtQ&FIeqtiKtb-5mo{^vC4g^f(|EPpz$PdFUK&Fz)1|o(r>Oj5C?I6Kjs= zPv1bGM;zjxZK#4kkW4;^eP88R0H5Giv~t^H*C*;M%9rHnXVmaLMqajI-#pfjDK?nj zLF+?98fX_7+9~5$P4{`WZ1fPZf~oA7QgR;N>qlp!MDK?@;*Ks{$KIdOVTOxuiWeuW z6Ga=(Y!4(NNx8EGKZU;i_PfFu2mRR9CgpnXtuM{LFx#S*K_3kfpL-SO~asd$tM_Q`0T5!WxA55 zf>Er7oEfwoGcma*`W{lMdR0XE`XWzjhf>8z$BBkigcsQQ!x)mGrc|2X!@p>Xk{<#q~8 zKPNx26n0&WSha^fzCce*Xnqkcr zN(*EOJv3e+%VDe{w(uVF#0@p`4m`CcAHe0dC^-$+8iMIQaOJ`Qp}^UM1t?uhYFMIe zwfVaLhb?=5cQ# zF@y9RXI=UwYo!V8nHwzGk{ggc>UlfccVHJ0Qx>ts@^lz4=HkS)(=F9C`&#?n#Om-x z2a}yLoz$(HRptTXktMj3fj4UG232z839T-!HbBM3}x7oKZ|!b8(HW+-m;W z*8+GS4I(5)P9d<$*G~jdWisMM7!;SQ^9@)t4aPt2T8H;at6VuFqEU0L`MkvM9PC5A zpN@M3%kf?m-7f+^rl;T5GN7=EVxX@82T@qhqb8(m4+To(U!udu84mJzi+@6$Aw+1b zkD~JS;b4`F9LRXcBA8p`otVl9N@ODZoiiJi_P_n*@^LuMxX*fUvhy*|#ep5#EiPf& zgSm%s0vWpn6HC8rr8D*OcD)z;ct{s2^7>lVErfc9+WwxW|A?A*{qF=KR3C|@%f

          lnIoJ6UeWfl!#R{L6t(hB)q|}^BP`SG} zZHsc1FwMvt^SW)Amg5fF?-Ddn$l&+VtQq@19QEm!DV0am@_-6mN#|^8k#y7wT`2SQ z{|n*YR(UFBZ_(sK>LzA>_=9no#rr08wlk`!XKr)Zy;e)fOl*i*dJcDOBtA zrsZl1>sM;PwO_It&Dui zU+ZxTOjar!6|huubj`4!6b@dlMB*gV(BRKxL8fog{AEVeyD0MOgIh&&+04*Be*bR?v4^Ds~2iL&U?(}lnq7$ zY+gP;Gv7(@Ke+y8E|Xl28v!<3%I)godA5^R{2@J!V=p}s7byS&e!4bodfU2-R(Adk zR|Y>4C<0?hoyCc~3UDuvM{=IWe*j*W4fMTscOpJNyZ?>b5^&qjNh{95$Xwr?^DEe? zDP46r6v2max4U(G^hIsacg(^!c;%-O$qwuWxM^um)nv_Pw!R~Boq#U;{047O1B*S!&O)#c zGMCdHRx(?AXF1xict24t6}D>F=Y3&kO$nlXH(8HO;}7}x5Kf2kvwpfsf|%O+7C4L8 zfK0vL&vfCreqtCC&8^JQj0ih(FaO=&Bsj zS?EsVfEe?Y9L-ZNp)#QzG?3szY318B3kf{2*(O8`6VH5pjEsm@im@u8=8N)5YCOG^ z*7W^dX_^eCRI0WnQ-!A@>LPcPSZUN?kjWX7jJGBMK~zE6JAOj+tmlzwZIC zR?gQJy?$%Ixif(SlPJ^Qyy1%i^=Or!qI{}oFy53S9u&AQ<*Du5M+KQR4!yV)0~6eG zFBVYE;2t4Mmmjttd`bEpjS96q_qJQg{T*4D?J7%J(KiJ-#j#8^dYQZ&Q znX?W-0;{Y0>kl+39S&^f&c_Ttx*_LU3RwDoa2%h_Y()q%pVWduJIFSuE}MTqKR(2~ zk>`IUz<@!AqWaFc+7k+yK^DVkf#QVGLMFWAPyHFI9A^@>q-u^<_&d%n zdE)bH3VTYPPY~Nd3-tyaNIV17D+JeaAeRJbD0ec=f!{gFH)qip$0oCb#&{4m$RqA< zni;!yLY@~rM=4F+Cedp2|Tg3Juqg;T!I(pcj^PD+~Uo^l*B z{aHgt9Oqu=cpld~QiP!NdkMnW%sH4hZD|F9Kh*P9f{v7y&z5ipg{6o|PQ(^sS%fHB zeqx0xP`=#927!xWk97U)FpM;VXUC__?qHw}-e`^nu)w6i_PIQr7jf~gGf&mCFHspwW-gYYP zMlDZ1tKSe^ite4w!%WR1tkP!3mcA2>e(5>@fl0`l7PlYh?wzvGt}m`FdAe(&d}^+C z?iGtJ6v1YOU?(6saX&HYQC!eg>fZ4XCnF*u5cjQZQd&e?jc3AA4xx604-KV=V4;)_ z+8N!yEZUh0vpx{edhWFI!=)%~z{mxCl3c#umx8~GaQYo5*?WB zE1|*rb$ZUCZjn!JoROf?jFE9h={NctaWt_26K1eC>a4$HsLGtKCMvLoX}o5b*2^Ye z5JU4XnPrRMPUtMO;FI6s@5~j2{S~MKk_pBcg^^~|8Sye#f$|7S^bRB z;CO6rOt6fj0?WKrxzjBHR;e)idadD@U9N!VlhW*$5=O|QM{a*J{gw=H28B3LC1QSn zuSb1>{A$a?^u5w!kJI=R@U`NTY$_4fjeQO408c^Ys>M2c2lUE3S8ns|cEd=oa&re9 zc)JRUiWL*Y<~#2$>4)%CJec|A$E?Pma^%gBoLUP^|eA5@(?+bx&wE#W|kw_b)n2(6;=_eNYXY;9xEN@&|N;= zNJY&rq#XHcErV?G!58QjkSG&)gg|`%eIW6l(!oZROo6A2qf%x3K^}kfRSbpjYezgH z8eB%R##cz5WRi5u>wX;El%-G4bC&l&70A-w+Dwl68L7}p_&eja{9EFM{MwyW!0Y`m z_e1Neara4p=gZxN(duzBJx&Y<%aLcLP{7dafHnL&QfQk^-wLtc$8MCSDKQQ&x+7wr zDE|o$M_x6bAv-St$IaaZkb3B;NHY2kC04y%58*jEHtF}`Ux31q`>2Ru39=kLa+NeI zy+UGQDL#!As4x4-uNmBiWUKwmD!u&Gdj6#6>8_MpqnoMCT zlDjxgms>I7j?!-KS_d6Lc64V|u|sJX!&VQjG)&sBTDA0dm(x*6S)oaN!pBBL1E(at z?eD685VkZfr8YPYr*yX!IN!6!E9?^@lCn1lG%V$9n z@~&`Ej%#xgTHo?@4ydTf9lV&EQzg*2s$ag(UAlK^X>L$=%~!$~Bz*xpIf{>$O(b*IV& zeZx|6B0;QZkB{$p_w->z{fEL9^`-y!WdDcwztWHmpTHO<5^tZF=mD~|(@)9rwjgxz z(*D%$+dDkiNRZm)T-NjOl(3_4rTD`KjYmF#@8l_mqGuMk-J6+X>h9{f$GhP)vuI}o zXh+Guogh@>Tto_J~`7B`z`3aW>G&4Vo|^Ad<7Azc)M(~ zprSnz!6VbdDIZh}{So?3+*z@xuVBvS1c{L?JvI6pM%Xgh2P(p_{qS^jQJ)y1*Q1ZU z3a`xP@(vGr_}f2Aa`0`xKeY^Rm5?86|H z`2t$r%m(Z~DCVtCT%e#zC_M|}Gp1$>Kp~hXW=genD!l*TK-8P7#&td@Su~%)s9nqR z<+|PEQN;I@Gy&Y|cg(dm^3FGpBB9@Pm+x-pK3n0i2|4TQNoebOwX@G#=c^~mC4bnQ z@v9_T9pLLTc^Onr(l`6=epMH&1rZnBu14rb%46v2QX$fS8}lo8QQy~@!S(h(%Y_U? z?l%7y{PvD1`#d_oOUKWRHaKJeE$Ry?d>^DA+n&z_sY$tBki`D&4o6Jh&4 zFPfJOX2#3~Z3HJ7;}_8l-;E`nB`)f}B%Y(8S8zdAwA-6|(HBttxm)>??2oydMt*d+ z0<})LW$f!wQ2@#&Hw*pK{jb-fSgVaKSlU0lQrfWx5E`}lsrP%Ng92RdGJ*`(s zA96J)7{$NGfb=jL4`=<<0J5gm_DH02syGcEy9m(>$mC+t9ZS$BGDvK#qu>f_-ByZl zXZrrW@%U_mSQO z*(D{m^K~AXQBp8WQs*jN7lFjG${tbwwd>!3PPvF$LAOv_cMU4bC)cV0%4aqw6B^$4 z-#$Lb&^{jEJ1q+1CQlKqC`!>DinIguo?%5Fz*?ZsB#`A(*07fH0_*o~gdzdixPE?@ zuHyh&Bl0a0ZByZazXBuWv}zCTTnZ;0e|Qtc1B%DbY->U9k6@|uJCIQYcHxn zg-LL#t7lS%<`zrXR*2oL^8ak7d}0x-=0l7$1_lX*@jt`cWKTe>PLGVsTpT?G?Xmsx zX;Js`ESiKA5o+XFF%ikDiNbyn!`IWSr${EA(Vx(zBGtvC@Z*OSHP~N=`$M*g(kGXq zfwqLe`g?%ahHXsts7_uTMNp=TzVW9-?OI+8K`0z_FRyTH$Y znGV@`Om(q2%zZi!%h7OXUc&&zK1^k?6F=D$gQlLeNN4`N8jfENpOZD1yWu*0vDh+o zOX;SVFC*&m+l_<^lhb@!8rSS?B!*fv=zTz1>aRtwg=d=^G%cLody{#GYv_Z61zubO zQBGi?{*0tNeB4P3#{pds^=b15h6dzknC1nulB-e&96la#JlcuvzS)Rv@31#^@!i9a zi75KvkVfT-zDugCDJ_0UMc9#gvmIyZfacGC)qU5Sdg*xn;vgJPg>Cp~2E`Rs9S*Lw zo%MksEbQghsxk`rbU!yU`taVgZop~o3+Q^SZ(lxIl;Oai@p$fmt?tG7D_3cp&ak|$ z=$`wp8@b2?eXp_yD26PhImjaQ$Mm&yuS=y9q1{Hc;O$#GtoA~FK3f7cdjQfC&BL_I zFjCCzs1d&)YudRqDwp(^rT$h4P+s|`IxhRf@J6b`3qi$dL}w!5`r1KM2;mFaY06L> za6$m`Y9tOpXXOsz`cu(fVfI9_U+H_SBd(EKaEP?e2x^tSL1ZH_H%m%Lh!_aWi1;0rx%jvYL$ zzzDIg&1Z{0hHGM!DTRvQNT9MK9J#L9jJjiAc5CtOcXoXdmA5z#9K{a!9tUK)K({NZ z(f6F1gwZ`dgj)}05WEWb9_7>7+C^B<7FYNf+_@UjuNfH{v3+?;i+BychT0QQhaU)A zEgk-P4t9_X)d%QL=-XMG{{+^zrxid?)y0r9$F4f=-oGvzvh-OtARPhhN;r8Q)){`q zS+7902S_{5?4Y)ory|Q&lFMetE^+hEY0^_-uN_8l$WbtZBEHJ)D^Irj>U{ zUcPViYm6WoByPn}yq1c@AHjCe?9ckho8d_$k?>|Th9nwCV>guj@kAH$m~w+h#Il8; z@QxvuNtA!~U97cpy)!2P6Eek8>VNBM^TE#F8e2csEszxG9 zoJ4St_je*E;G)W8`BxMG`A++DuVlhXvjR^n?_}ny9I`!)@qxD*N|n7ClbTfv3dI}H zkcd@wQ_nH zW;oBv2l&^Xt*Rb^a+A|vcPmV!bNYe#6TWqIX0twjnO5|3Ze7Kv7u=Dzz6^iubw6>R z#Phtnbv@LKEC$k#_8O7oE*vgT;9%L|+Vq-0{zC>RJOV4mJ zu|4ZK-(Lb}bHF9Wz0p2#Sf#2Zq?%~WD;nb+2I3mFB$PAKRU3B&QI^}b;FjIM=etoT z(uuhR)9?+BsCV`vAbHErXsf~Hg0PaaC8fEYNCLL2=X8&o)94meh$=#uqynKc)0%^1 zQj~>dov2-BhU7&}+l1zC)2W(}sU5_YTV(L>X?rxQnw6Z&qDufHyi$_sewnGO`u0}K z>7FlZR(9_j92=h9oemkZcmgJu8aC#IbcyaPW8DPZ7uj&3Oy*<6f+yK_z}`88fxa5HtR)M}VjH^~ z9OshFXX`tXnodEkvDLv~l;!s;OLay+doz%2K-m@VJ7GDbMdN{utPGhkbT~T8O+iMCq^i?AX9!~Q>7J6` zWZsvqiMdYXv#*%Lgy=f0Bmi<3tK73nv3Ah$QmKlaP-Js@gBcNJ}#=KKVhEGT}bnH>39dF zE*v|0>o?3XiKwX2Rk>V*`RHtNh{YrSKAJ9?;(Y3 zSUTfr&dEGJb41lUce~nN-m#VDeDC1d9^QiAKHcvKGwxZqN|LXN(2eI}3bv6u}Rk%3>wxLHt>P`z&2GFd0Tf3uvh&#-9DrpyH z3sY^FRgXhv-2lOptf^9^R^G_uYQRF|BUY8$%0+Qg3-)eu@nNj>Hp02Vb5@s4(SwUa znE0+g@gsTWFha67UOcqCn%_n1Xf(4P%#m7d=(Y3eNa*gL z+1B~N`3PQNh45^Mi&&a;d~>MrzFWMsmMQ@@UCcU(y1YkEhxOOnd3wKhvk)~bIo~wL zdB1hXk7mME3n$@EYg{~e`Foc88|_IYBBiK$x;?hK3Mq!b@ec-KqD~6BmcMq@DJ5U8 z+&|lrwO^eB0_6gsmJ5Po1Uw7{mSxG&`}3@S+2t@?=Cw>$Bv~geeq%TJo?=qJk?`F2 z=?nU0VtqvRljk9#-gj|U@925k5d5Jv*?KZYvUYE{F8p=&QUmwoIoOix>_JRe|LZ)t zRVuFP>l!=7FLV>BJ^RHL>oe~bIe-`n&Y&V6*QnS!0_gAia8^Fw9+Xu^Io$kqV*w!} zQv6a37B~Fn5mKdaUA801kko>rBni zq-x~0J9(E4eP)}8j1IZ@951*z(co1V%_6PmE-A8);|j4_e0_p0yg1D2%kNsD6Uo1j zGpWmQ6j`%`it1wkemBAejzMD0UQL9Xb7`6=_PUFoR%u1AD1^&vGYk4Wq25?b2`!d4 zbLgeR!xUL=Jo;kMm7*e|enQf{yjW(ye`3gQgHzgyV7L8R9oUWeIJ-5;&#lYx4S7s9 zo732%zsJc!rv8LdQ`~;zyP0wrRv!T{I;oQ4ZNXIgKD(1FlH>73N(Wy&`{x!5?PVS! zG7Zr0y$)rIG2{C!N8+7UgKzS|T=1HMrVc-ec(Ph)5dW)v=C_Ky&~1Aii56QMIuz_s6}G@5s2N-pT6TW0}eW zqe^WRdQJP3Ua5cwT)ZfzLTgt_-=J`P`Q~!_i%rpwTCw%UzqmAGPzMjD%nO(4z(a&k zS8rgWR=bVjr#-4g*SphN)?Bx3ZFmzn?m~-lyA|iu!_2DiWRhHztm*5+wa^bfEF0g5 zja=#@Woy55` zGEWP!jiBnmUzi-#2Z6zop>Hp4Q|^o-6==dVcB-H8k&81ZK zF(}1UPum9>PO}Cez9IZaIJ-LqYd5z}N>%W`XA7*+_>HwA=w`R=k9)|&$I^#K6BHKer@iC{OxYrkl= zrApV1)~>DzD{y99hbLmAZ$ynI`)5~c*OZ(4^$k~6L|HBMkUWVCVV;_bhex&8ic7Ah z)Uux#W-{7AjWXz{h>B!fn;L)0J{es*>0DaY-_0XEhw#7xN#6HycAVA08H+)s&sZgp zYpKX@guf9jG^RHR400001 zbW%=J06^y0W&i*I4@pEpR49>SV1R%RZ~_Hz!3ivYAE-kBNQ1Bg4mDtqz`($0z`zMI zzW~T(@`s9ZVjOy&j}U(zy?&pAi)m}@(W;6j9USscp_Bqh6~}K(ER}ALNF4S z1;K?H!N5xsUr`A#w=1CVEhZvyfF80{r~xxM{(Jxnu)Xhn2a{y_!oaZr!huLKL^8BN z`0@7&bASH2`tvH!$#j0LjB88Fx9r?UZ9+!!Q=vL6ZNEGO+#w2K4{` vUoa%WAPQXo?EXa%?@oa7Sx#UHjKL28#KSt56Ur~300000NkvXXu0mjfprn~E literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img4.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img4.png new file mode 100644 index 0000000000000000000000000000000000000000..a709c3fd21312df2b667fcf4fe306de3cad16c5b GIT binary patch literal 204 zcmeAS@N?(olHy`uVBq!ia0vp^{2`Pl)U0&6`)OSTSeLoCy;q zw6wHTR8-{T5)u*<5;Pc+*wh5LS$4=uNQfIKFqWB3kcwku%W1gSEbU=Zz%Wx>$l;aMMlI)t ySx0uxb~KrN!;LMnqm_{-`aq8kTi$XeHU^7#TpRHR400001 zbW%=J06^y0W&i*Hxk*GpR2Y?GU;qO)21W>jfeVUZfS&;k{C)r=5*R)R0I3gP5he$8 zH4H%Gcqf2$bAY)Y_<+RzeZL_bUQG44K>^r7@d9uTKSRO-5Stn7JWhrUKn< zg@I!MT!$$`15ASV0|Va&1`NQ@!2baxhed)7$tVQy|Nq}X^8ZmZQ2<3vEJklyxX%Cp N002ovPDHLkV1iYGbMOEF literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img6.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img6.png new file mode 100644 index 0000000000000000000000000000000000000000..732c334023cbfffcb41fb9ca5d7c46ee1e6b1404 GIT binary patch literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^AT~b>GXn!-#I@qpK#p#JPl)U0&6`)OSTSeLoR*fB zii(PyoScM&gpiOB4-XF;8yf=y0~Hk&2?+@v9v+~M%!7WqK#H*>$S;_|;n|HeAjitn z#W93qW^w{UGn>Fc9wiIO9}*K7)CI09eB7xhqRb)A(0SP54~M56_rV_4lbf|{88%kR fI6O%#WMlXLmz$e6Y^XAPfR;-vaXU>EP z6IxnYDk>^+a&i(95<)^kJUl#XY-|h+3{+H9BqStwczA%CUPYds2c#HFg8YIR9G=}s z19DnCT^vI+CMG8^Fy*m@TsYuh^dKoAVfTRp2hJZjz_rkWJ;8TVkH;LAX>2U*Vh#*m zpB-Pe&wn^=qv|JRoqY$I66ANVBs$A_SsxE%Eco-YL5-zGiSnt z2`w!x6%`dZIXMXl2_YdN9v&VxHZ}$Z1}Z8l5)u+TJUl>6uOd&+15%77L4Lsu4$p3+ z0Xb2gE{-7*Q&GgH_oZm^+o=b4C5wuTOV1trFg{G?E3_KgaUm;^pIml$X< zaF$IF;O}_ADk%O@xIZFy7rfdU8wI%-n7Vjk%e{lv Q0BvFLboFyt=akR{0OjmNw*UYD literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img9.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img9.png new file mode 100644 index 0000000000000000000000000000000000000000..1a46e4c82bbd694875097987add2292668562096 GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp@K&-&R%)r3t^WnZBkfR&m6XLpg^X3&RR?L|*XTpRD zEiEk-6%{!-ISB~~At50i9v(I}HU^GJUl=hf3lAN^)oP*1o;IsI6S+N2INF| zx;Tb#%uG&5c#!-c&4F>xikNFmY;8bP0l+XkKcWg(T literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/index.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/index.html new file mode 100644 index 000000000..e74c4fff5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/index.html @@ -0,0 +1,219 @@ + + + + + +CUDD: CU Decision Diagram Package +Release 2.5.0 + + + + + + + + + + + + + + + + +next +up +previous + +index +
          + Next: Introduction +   Index +
          +
          + + +

          CUDD: CU Decision Diagram Package +
          +Release 2.5.0

          +
          + +

          Fabio Somenzi

          +

          Department of Electrical, Computer, and Energy Engineering

          +

          University of Colorado at Boulder

          +
          + +

          +


          + + + + + +

          +
          +Fabio Somenzi +2012-02-04 +
          + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node1.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node1.html new file mode 100644 index 000000000..2398d3652 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node1.html @@ -0,0 +1,174 @@ + + + + + +Introduction + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
          + Next: How to Get CUDD + Up: CUDD: CU Decision Diagram + Previous: CUDD: CU Decision Diagram +   Index +
          +
          + + +

          + +
          +Introduction +

          + +

          +The CUDD package provides functions to manipulate Binary Decision +Diagrams (BDDs) [5,3], +Algebraic Decision Diagrams (ADDs) +[1], and Zero-suppressed Binary Decision +Diagrams (ZDDs) +[12]. BDDs are used to represent +switching functions; ADDs are used to +represent function from $\{0,1\}^n$ to an arbitrary set. ZDDs +represent switching functions like BDDs; +however, they are much more efficient than BDDs when the functions to +be represented are characteristic +functions of cube sets, or in general, when the +ON-set of the function to be represented is +very sparse. They are inferior to BDDs in other cases. + +

          +The package provides a large set of operations on BDDs, ADDs, and +ZDDs, functions to convert BDDs into ADDs or ZDDs and vice versa, and +a large assortment of variable reordering methods. + +

          +The CUDD package can be used in three ways: + +

            +
          • As a black box. In this case, the application + program that needs to manipulate decision diagrams only uses the + exported functions of the package. The rich set of functions + included in the CUDD package allows many applications to be written + in this way. Section 3 describes how to use the + exported functions of the package. An application written in terms + of the exported functions of the package needs not concern itself + with the details of variable reordering, which may + take place behind the scenes. +Click here +for a list of the + exported functions. +
          • +
          • As a clear box. When writing a sophisticated + application based on decision diagrams, efficiency often dictates + that some functions be implemented as direct recursive manipulation + of the diagrams, instead of being written in terms of existing + primitive functions. Section 4 explains how to add new + functions to the CUDD package. It also details how to write a + recursive function that can be interrupted by + dynamic variable reordering. +Click here +for a list of the + exported and internal functions. +
          • +
          • Through an interface. Object-oriented languages like C++ and + Perl5 can free the programmer from the burden of memory management. + A C++ interface is included in the distribution of CUDD. It + automatically frees decision diagrams that are no longer used by the + application and overloads operators. Almost all the functionality + provided by the CUDD exported functions is available through the C++ + interface, which is especially recommended for fast prototyping. + Section 5 explains how to use the interface. A Perl5 + interface also exists and is ditributed separately. (See + Section 2.2.) Some applications define their own + interfaces. See for example Section 3.18. +
          • +
          +In the following, the reader is supposed to be familiar with the basic +ideas about decision diagrams, as found, for instance, in [3]. + +

          +


          + + +next + +up + +previous + +index +
          + Next: How to Get CUDD + Up: CUDD: CU Decision Diagram + Previous: CUDD: CU Decision Diagram +   Index + +
          +Fabio Somenzi +2012-02-04 +
          + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node2.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node2.html new file mode 100644 index 000000000..f36d7ec2a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node2.html @@ -0,0 +1,175 @@ + + + + + +How to Get CUDD + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
          + Next: User's Manual + Up: CUDD: CU Decision Diagram + Previous: Introduction +   Index +
          +
          + + +Subsections + + + +
          + +

          + +
          +How to Get CUDD +

          + +

          + +

          + +
          +The CUDD Package +

          + +

          +The CUDD package is available via anonymous FTP from +vlsi.Colorado.EDU. A compressed tar file named +cudd-2.5.0.tar.gz can be found in directory pub. +Once you have this file, +

          +gzip -dc cudd-2.5.0.tar.gz | tar xvf - + +
          +will create directory cudd-2.5.0 and its subdirectories. +These directories contain the decision diagram package, a few support +libraries, and a toy application based on the +decision diagram package. There is a README file +with instructions on configuration and +installation in cudd-2.5.0. You can use +a compiler for either ANSI C or C++. + +

          +Once you have made the libraries and program, you can type: +

          +cd nanotrav +
          +nanotrav -p 1 -autodyn -reordering sifting -trav mult32a.blif + +
          +This will run a simple-minded FSM traversal program. (On a 2.4 GHz +Pentium 4 (TM), it takes about 0.5 s.) The +output produced by the program can be checked against +cudd-2.5.0/nanotrav/mult32a.out. More information on the +nanotrav program can be found in +cudd-2.5.0/nanotrav/README. + +

          +If you want to be notified of new releases of the CUDD package, send a +message to Fabio@Colorado.EDU. + +

          + +

          + +
          +CUDD Friends +

          + +

          +Two CUDD extensions are available via anonymous FTP from +vlsi.Colorado.EDU. + +

            +
          • PerlDD is an object-oriented Perl5 interface to CUDD. It + is organized as a standard Perl extension module. The Perl interface + is at a somewhat higher level than the C++ interface, but it is not + as complete. +
          • +
          • DDcal is a graphic BDD calculator based on CUDD, Perl-Tk, + and dot. (See Section 3.19 for information on dot.) + +

            +

          • +

          + + +next + +up + +previous + +index +
          + Next: User's Manual + Up: CUDD: CU Decision Diagram + Previous: Introduction +   Index + +
          +Fabio Somenzi +2012-02-04 +
          + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node3.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node3.html new file mode 100644 index 000000000..d91378b2e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node3.html @@ -0,0 +1,1637 @@ + + + + + +User's Manual + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
          + Next: Programmer's Manual + Up: CUDD: CU Decision Diagram + Previous: How to Get CUDD +   Index +
          +
          + + +Subsections + + + +
          + +

          + +
          +User's Manual +

          + +

          +This section describes the use of the CUDD package as a black box. + +

          + +

          + +
          +Compiling and Linking +

          + +

          +To build an application that uses the CUDD package, you should add +

          +#include "util.h"
          +#include "cudd.h"
          +
          + +to your source files, and should link +libcudd.a, +libmtr.a, +libst.a, and +libutil.a to your executable. (All these +libraries are part of the distribution.) Some +platforms require specific compiler and linker flags. Refer to the +Makefile in the top level directory of the +distribution. + +

          +Keep in mind that whatever flags affect the size of data +structures--for instance the flags used to use 64-bit pointers where +available--must be specified when compiling both CUDD and the files +that include its header files. + +

          + +

          + +
          +Basic Data Structures +

          + +

          + +

          + +
          +Nodes +

          + +

          +BDDs, ADDs, and ZDDs are made of DdNode's. A DdNode +(node for short) is a structure with several fields. Those +that are of interest to the application that uses the CUDD package as +a black box are the variable index, the +reference count, and the value. The +remaining fields are pointers that connect nodes among themselves and +that are used to implement the unique table. (See +Section 3.2.2.) + +

          +The index field holds the name of the variable that labels the +node. The index of a variable is a permanent attribute that reflects +the order of creation. Index 0 corresponds to +the variable created first. On a machine with 32-bit pointers, the +maximum number of variables is the largest value that can be stored in +an unsigned short integer minus 1. The largest index is reserved for +the constant nodes. When 64-bit pointers are +used, the maximum number of variables is the largest value that can be +stored in an unsigned integer minus 1. + +

          +When variables are reordered to reduce the size of the decision +diagrams, the variables may shift in the order, but they retain their +indices. The package keeps track of the variable +permutation (and its inverse). The +application is not affected by variable reordering, +except in the following cases. + +

            +
          • If the application uses generators + (Cudd_ForeachCube and + Cudd_ForeachNode) and reordering is + enabled, then it must take care not to call any operation that may + create new nodes (and hence possibly trigger reordering). This is + because the cubes (i.e., paths) and nodes of a diagram change as a + result of reordering. +
          • +
          • If the application uses + Cudd_bddConstrain and reordering + takes place, then the property of Cudd_bddConstrain of + being an image restrictor is lost. +
          • +
          + +

          +The CUDD package relies on garbage +collection to reclaim the memory used by diagrams that are no longer +in use. The scheme employed for garbage collection is based on keeping +a reference count for each node. The +references that are counted are both the internal references +(references from other nodes) and external references (typically +references from the calling environment). When an application creates +a new BDD, ADD, or ZDD, it must +increase its reference count explicitly, through a call to +Cudd_Ref. Similarly, when a diagram is no +longer needed, the application must call +Cudd_RecursiveDeref (for BDDs and +ADDs) or Cudd_RecursiveDerefZdd +(for ZDDs) to ``recycle'' the nodes of the +diagram. + +

          +Terminal nodes carry a value. This is especially +important for ADDs. By default, the value is a double. +To change to something different (e.g., an integer), the +package must be modified and recompiled. Support for this process is +currently very rudimentary. + +

          + +

          + +
          +The Manager +

          + +

          +All nodes used in BDDs, ADDs, and ZDDs are kept in special +hash tables called the +unique tables. Specifically, BDDs and ADDs +share the same unique table, whereas ZDDs have their own table. As +the name implies, the main purpose of the unique table is to guarantee +that each node is unique; that is, there is no other node labeled by +the same variable and with the same children. This uniqueness +property makes decision diagrams canonical. The +unique tables and some auxiliary data structures +make up the DdManager (manager for +short). Though the application that uses only the exported functions +needs not be concerned with most details of the manager, it has to +deal with the manager in the following sense. The application must +initialize the manager by calling an appropriate function. (See +Section 3.3.) Subsequently, it must pass a pointer to the +manager to all the functions that operate on decision diagrams. + +

          +With the exception of a few statistical counters, there are no global variables in +the CUDD package. Therefore, it is quite possible to have multiple +managers simultaneously active in the same application.1 It is the pointers to +the managers that tell the functions on what data they should operate. + +

          + +

          + +
          +Cache +

          + +

          +Efficient recursive manipulation of decision diagrams requires the use +of a table to store computed results. This table +is called here the cache because it is +effectively handled like a cache of variable but limited capacity. The +CUDD package starts by default with a small cache, and increases its +size until either no further benefit is achieved, or a limit size is +reached. The user can influence this policy by choosing initial and +limit values for the cache size. + +

          +Too small a cache will cause frequent overwriting of useful results. +Too large a cache will cause overhead, because the whole cache is +scanned every time garbage collection takes +place. The optimal parameters depend on the specific application. The +default parameters work reasonably well for a large spectrum of +applications. + +

          +The cache of the CUDD package is used by most recursive +functions of the package, and can be used by user-supplied functions +as well. (See Section 4.4.) + +

          + +

          + +
          +Initializing and Shutting Down a DdManager +

          + +

          +To use the functions in the CUDD package, one has first to initialize +the package itself by calling Cudd_Init. +This function takes four parameters: + +

            +
          • numVars: It is the initial number of variables + for BDDs and ADDs. If the total number of variables needed by the + application is known, then it is slightly more efficient to create a + manager with that number of variables. If the number is unknown, it + can be set to 0, or to any other lower bound on the number of + variables. Requesting more variables than are actually needed is + not incorrect, but is not efficient. +
          • +
          • numVarsZ: It is the initial number of variables + for ZDDs. See Sections 3.9 and 3.11 for + a discussion of the value of this argument. +
          • +
          • numSlots: Determines the initial size of each + subtable of the unique table. + There is a subtable for each variable. The size of each subtable is + dynamically adjusted to reflect the number of nodes. It is normally + O.K. to use the default value for this parameter, which is + CUDD_UNIQUE_SLOTS. +
          • +
          • cacheSize: It is the initial size (number of + entries) of the cache. Its default value is + CUDD_CACHE_SLOTS. +
          • +
          • maxMemory: It is the target value for the + maximum memory occupation (in bytes). The package uses this value to + decide two parameters. + +
              +
            • the maximum size to which the cache will grow, regardless of + the hit rate or the size of the unique table. +
            • +
            • the maximum size to which growth of the unique table will be + preferred to garbage collection. + +
            • +
            + If maxMemory is set to 0, CUDD tries to guess a good value based on + the available memory. +
          • +
          +A typical call to Cudd_Init may look +like this: +
          +  manager = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0);
          +
          +To reclaim all the memory associated with a manager, an application +must call Cudd_Quit. This is normally +done before exiting. + +

          + +

          + +
          +Setting Parameters +

          + +

          +The package provides several functions to set the parameters that +control various functions. For instance, the package has an automatic +way of determining whether a larger unique table +would make the application run faster. In that case, the package +enters a ``fast growth'' mode in which resizing of +the unique subtables is favored over garbage +collection. When the unique table reaches a given size, however, the +package returns to the normal ``slow growth'' mode, even though the +conditions that caused the transition to fast growth still prevail. +The limit size for fast growth can be read by +Cudd_ReadLooseUpTo and changed by +Cudd_SetLooseUpTo. Similar pairs of +functions exist for several other parameters. See also +Section 4.8. + +

          + +

          + +
          +Constant Functions +

          + +

          +The CUDD Package defines several constant functions. These functions +are created when the manager is initialized, and are accessible +through the manager itself. + +

          + +

          + +
          +One, Logic Zero, and Arithmetic Zero +

          + +

          +The constant 1 (returned by +Cudd_ReadOne) is common to BDDs, ADDs, and +ZDDs. However, its meaning is different for ADDs and BDDs, on the one +hand, and ZDDs, on the other hand. The diagram consisting of the +constant 1 node only represents the constant 1 function for ADDs and +BDDs. For ZDDs, its meaning depends on the number of variables: It is +the conjunction of the complements of all variables. Conversely, the +representation of the constant 1 function depends on the number of +variables. The constant 1 function of $n$ variables is returned by +Cudd_ReadZddOne. + +

          +The constant 0 is common to ADDs and ZDDs, but not to BDDs. The +BDD logic 0 is not associated with the constant 0 +function: It is obtained by complementation +(Cudd_Not) of the constant 1. (It is also +returned by Cudd_ReadLogicZero.) +All other constants are specific to ADDs. + +

          + +

          + +
          +Predefined Constants +

          + +

          +Besides 0 (returned by Cudd_ReadZero) +and 1, the following constant functions are +created at initialization time. + +

            +
          1. PlusInfinity and + MinusInfinity: On computers implementing the + IEEE standard 754 for + floating-point arithmetic, these two constants + are set to the signed infinities. On the DEC + Alphas, the option -ieee_with_no_inexact or + -ieee_with_inexact must be passed to the DEC compiler to get + support of the IEEE standard. (The compiler still produces a + warning, but it can be ignored.) Compiling with + those options may cause substantial performance degradation on the + Evolution IV CPUs. (Especially if the application does use the + infinities.) The problem is reportedly solved in the Evolution V + CPUs. If gcc is used to compile CUDD on the + Alphas, the symbol HAVE_IEEE_754 + must be undefined. (See the Makefile for the + details.) The values of these constants are returned by + Cudd_ReadPlusInfinity and + Cudd_ReadMinusInfinity. +
          2. +
          3. Epsilon: This constant, initially set to + $10^{-12}$, is used in comparing floating point values for equality. + Its value is returned by + Cudd_ReadEpsilon, and it can be + modified by calling Cudd_SetEpsilon. + Unlike the other constants, it does not correspond to a node. +
          4. +
          + +

          + +

          + +
          +Background +

          + +

          +The background value is a constant typically used +to represent non-existing arcs in graphs. Consider a shortest path +problem. Two nodes that are not connected by an arc can be regarded as +being joined by an arc of infinite length. In +shortest path problems, it is therefore convenient to set the +background value to PlusInfinity. In network flow +problems, on the other hand, two nodes not connected by an arc can be +regarded as joined by an arc of 0 capacity. +For these problems, therefore, it is more convenient to set the +background value to 0. In general, when representing +sparse matrices, the background value is the value that +is assumed implicitly. + +

          +At initialization, the background value is set to 0. It can be read +with Cudd_ReadBackground, and +modified with Cudd_SetBackground. The background value +affects procedures that read sparse matrices/graphs +(Cudd_addRead and +Cudd_addHarwell), procedures that print +out sum-of-product expressions for +ADDs (Cudd_PrintMinterm), generators +of cubes (Cudd_ForeachCube), and +procedures that count minterms +(Cudd_CountMinterm). + +

          + +

          + +
          +New Constants +

          + +

          +New constant can be created by calling +Cudd_addConst. This function will +retrieve the ADD for the desired constant, if it already +exist, or it will create a new one. Obviously, new constants should +only be used when manipulating ADDs. + +

          + +

          + +
          +Creating Variables +

          + +

          +Decision diagrams are typically created by combining simpler decision +diagrams. The simplest decision diagrams, of course, cannot be +created in that way. Constant functions have been discussed in +Section 3.5. In this section we discuss the simple +variable functions, also known as projection functions. + +

          + +

          + +
          +New BDD and ADD Variables +

          + +

          +The projection functions are distinct for +BDDs and ADDs. A projection function for BDDs consists of an internal +node with both outgoing arcs pointing to the constant 1. The +else arc is complemented. + +

          +An ADD projection function, on the other hand, has the else +pointer directed to the arithmetic zero +function. One should never mix the two types of variables. BDD +variables should be used when manipulating BDDs, and ADD variables +should be used when manipulating ADDs. Three functions are provided +to create BDD variables: + +

            +
          • Cudd_bddIthVar: Returns + the projection function with index $i$. + If the function does not exist, it is created. +
          • +
          • Cudd_bddNewVar: Returns a + new projection function, whose index is + the largest index in use at the time of the call, plus 1. +
          • +
          • Cudd_bddNewVarAtLevel: + Similar to Cudd_bddNewVar. In + addition it allows to specify the position in the variable + order at which the new variable should be + inserted. In contrast, Cudd_bddNewVar + adds the new variable at the end of the order. +
          • +
          +The analogous functions for ADDs are +Cudd_addIthVar, +Cudd_addNewVar, and +Cudd_addNewVarAtLevel. + +

          + +

          + +
          +New ZDD Variables +

          + +

          +Unlike the projection functions of BDDs and ADDs, the +projection functions of ZDDs have diagrams +with $n+1$ nodes, where $n$ is the number of variables. Therefore the +ZDDs of the projection functions change when new variables are added. +This will be discussed in Section 3.9. Here we assume +that the number of variables is fixed. The ZDD of the $i$-th +projection function is returned by +Cudd_zddIthVar. + +

          + +

          + +
          +Basic BDD Manipulation +

          + +

          +Common manipulations of BDDs can be accomplished by calling +Cudd_bddIte. This function takes three BDDs, $f$, $g$, and +$h$, as arguments and computes +$f\cdot g + f'\cdot h$. Like all the +functions that create new BDDs or ADDs, Cudd_bddIte returns a result that must be +explicitly referenced by the caller. Cudd_bddIte can be used +to implement all two-argument boolean functions. However, the package +also provides Cudd_bddAnd as well as the +other two-operand boolean functions, which are slightly more efficient +when a two-operand function is called for. The following fragment of +code illustrates how to build the BDD for the function +$f =
+x_0'x_1'x_2'x_3'$. +

          +	DdManager *manager;
          +	DdNode *f, *var, *tmp;
          +	int i;
          +
          +	...
          +
          +	f = Cudd_ReadOne(manager);
          +	Cudd_Ref(f);
          +	for (i = 3; i >= 0; i--) {
          +	    var = Cudd_bddIthVar(manager,i);
          +	    tmp = Cudd_bddAnd(manager,Cudd_Not(var),f);
          +	    Cudd_Ref(tmp);
          +	    Cudd_RecursiveDeref(manager,f);
          +	    f = tmp;
          +	}
          +
          +This example illustrates the following points: + +
            +
          • Intermediate results must be ``referenced'' and + ``dereferenced.'' However, var is a + projection function, and its + reference count is always greater than + 0. Therefore, there is no call to Cudd_Ref. +
          • +
          • The new f must be assigned to a temporary variable + (tmp in this example). If the result of + Cudd_bddAnd were assigned directly to + f, the old f would be lost, and there would be no + way to free its nodes. +
          • +
          • The statement f = tmp has the same effect as: +
            +	    f = tmp;
            +	    Cudd_Ref(f);
            +	    Cudd_RecursiveDeref(manager,tmp);
            +
            + but is more efficient. The reference is + ``passed'' from tmp to f, and tmp is now + ready to be reutilized. +
          • +
          • It is normally more efficient to build BDDs ``bottom-up.'' This + is why the loop goes from 3 to 0. Notice, however, that after + variable reordering, higher index does not necessarily mean ``closer + to the bottom.'' Of course, in this simple example, efficiency is + not a concern. +
          • +
          • Had we wanted to conjoin the variables in a bottom-up fashion + even after reordering, we should have used + Cudd_ReadInvPerm. One has to be + careful, though, to fix the order of conjunction before entering the + loop. Otherwise, if reordering takes place, it is possible to use + one variable twice and skip another variable. +
          • +
          + +

          + +

          + +
          +Basic ADD Manipulation +

          + +

          +The most common way to manipulate ADDs is via +Cudd_addApply. This function can apply a +wide variety of operators to a pair of ADDs. Among the available +operators are addition, multiplication, division, minimum, maximum, +and boolean operators that work on ADDs whose leaves are restricted to +0 and 1 (0-1 ADDs). + +

          +The following fragment of code illustrates how to build the ADD for +the function +$f = 5x_0x_1x_2x_3$. +

          +	DdManager *manager;
          +	DdNode *f, *var, *tmp;
          +	int i;
          +
          +	...
          +
          +	f = Cudd_addConst(manager,5);
          +	Cudd_Ref(f);
          +	for (i = 3; i >= 0; i--) {
          +	    var = Cudd_addIthVar(manager,i);
          +	    Cudd_Ref(var);
          +	    tmp = Cudd_addApply(manager,Cudd_addTimes,var,f);
          +	    Cudd_Ref(tmp);
          +	    Cudd_RecursiveDeref(manager,f);
          +	    Cudd_RecursiveDeref(manager,var);
          +	    f = tmp;
          +	}
          +
          +This example, contrasted to the example of BDD manipulation, +illustrates the following points: + +
            +
          • The ADD projection function are not + maintained by the manager. It is therefore necessary to + reference and + dereference them. +
          • +
          • The product of two ADDs is computed by calling + Cudd_addApply with + Cudd_addTimes as parameter. There is + no ``apply'' function for BDDs, because + Cudd_bddAnd and + Cudd_bddXor plus complementation are + sufficient to implement all two-argument boolean functions. +
          • +
          + +

          + +

          + +
          +Basic ZDD Manipulation +

          + +

          +ZDDs are often generated by converting +existing BDDs. (See Section 3.11.) However, it is also +possible to build ZDDs by applying boolean operators to other ZDDs, +starting from constants and projection +functions. The following fragment of code illustrates how to build +the ZDD for the function +$f = x_0'+x_1'+x_2'+x_3'$. We assume that the +four variables already exist in the manager when the ZDD for $f$ is +built. Note the use of De Morgan's law. +

          +	DdManager *manager;
          +	DdNode *f, *var, *tmp;
          +	int i;
          +
          +	manager = Cudd_Init(0,4,CUDD_UNIQUE_SLOTS,
          +			    CUDD_CACHE_SLOTS,0);
          +	...
          +
          +	tmp = Cudd_ReadZddOne(manager,0);
          +	Cudd_Ref(tmp);
          +	for (i = 3; i >= 0; i--) {
          +	    var = Cudd_zddIthVar(manager,i);
          +	    Cudd_Ref(var);
          +	    f = Cudd_zddIntersect(manager,var,tmp);
          +	    Cudd_Ref(f);
          +	    Cudd_RecursiveDerefZdd(manager,tmp);
          +	    Cudd_RecursiveDerefZdd(manager,var);
          +	    tmp = f;
          +	}
          +	f = Cudd_zddDiff(manager,Cudd_ReadZddOne(manager,0),tmp);
          +	Cudd_Ref(f);
          +	Cudd_RecursiveDerefZdd(manager,tmp);
          +
          +This example illustrates the following points: + +
            +
          • The projection functions are + referenced, because they are not maintained by the manager. +
          • +
          • Complementation is obtained by subtracting from the constant 1 + function. +
          • +
          • The result of Cudd_ReadZddOne + does not require referencing. +
          • +
          +CUDD provides functions for the manipulation of +covers represented by ZDDs. For instance, +Cudd_zddIsop builds a ZDD representing an +irredundant sum of products for the +incompletely specified function defined by the two BDDs $L$ and $U$. +Cudd_zddWeakDiv performs the weak +division of two covers given as ZDDs. These functions expect the two +ZDD variables corresponding to the two literals of the function +variable to be adjacent. One has to create variable groups (see +Section 3.14) for reordering of +the ZDD variables to work. BDD automatic reordering is safe even +without groups: If realignment of ZDD and ADD/BDD variables is +requested (see Section 3.15) groups will be kept +adjacent. + +

          + +

          + + +
          +Converting ADDs to BDDs and Vice Versa +

          + +

          +Several procedures are provided to convert ADDs to BDDs, according to +different criteria. +(Cudd_addBddPattern, +Cudd_addBddInterval, and +Cudd_addBddThreshold.) The +conversion from BDDs to ADDs +(Cudd_BddToAdd) is based on the simple +principle of mapping the logical 0 and 1 on the +arithmetic 0 and 1. It is also possible to +convert an ADD with integer values (more precisely, floating point +numbers with 0 fractional part) to an array of BDDs by repeatedly +calling Cudd_addIthBit. + +

          + +

          + + +
          +Converting BDDs to ZDDs and Vice Versa +

          + +

          +Many applications first build a set of BDDs and then derive ZDDs from +the BDDs. These applications should create the manager with 0 +ZDD variables and create the BDDs. Then they should call +Cudd_zddVarsFromBddVars to +create the necessary ZDD variables--whose number is likely to be +known once the BDDs are available. This approach eliminates the +difficulties that arise when the number of ZDD variables changes while +ZDDs are being built. + +

          +The simplest conversion from BDDs to ZDDs is a simple change of +representation, which preserves the functions. Simply put, given a BDD +for $f$, a ZDD for $f$ is requested. In this case the correspondence +between the BDD variables and ZDD variables is one-to-one. Hence, +Cudd_zddVarsFromBddVars should be called with the +multiplicity parameter equal to 1. The conversion proper can +then be performed by calling +Cudd_zddPortFromBdd. The inverse +transformation is performed by +Cudd_zddPortToBdd. + +

          +ZDDs are quite often used for the representation of +covers. This is normally done by +associating two ZDD variables to each variable of the function. (And +hence, typically, to each BDD variable.) One ZDD variable is +associated with the positive literal of the BDD variable, while the +other ZDD variable is associated with the negative literal. A call to +Cudd_zddVarsFromBddVars with +multiplicity equal to 2 will associate to BDD variable $i$ the +two ZDD variables $2i$ and $2i+1$. + +

          +If a BDD variable group tree exists when +Cudd_zddVarsFromBddVars is called (see +Section 3.13) the function generates a ZDD variable group +tree consistent to it. In any case, all the ZDD variables derived +from the same BDD variable are clustered into a group. + +

          +If the ZDD for $f$ is created and later a new ZDD variable is added to +the manager, the function represented by the existing ZDD changes. +Suppose, for instance, that two variables are initially created, and +that the ZDD for $f = x_0 + x_1$ is built. If a third variable is +added, say $x_2$, then the ZDD represents +$g = (x_0 + x_1) x_2'$ +instead. This change in function obviously applies regardless of what +use is made of the ZDD. However, if the ZDD is used to represent a +cover, the cover itself is not changed by the +addition of new variable. (What changes is the +characteristic function of the cover.) + +

          + +

          + +
          +Variable Reordering for BDDs and ADDs +

          + +

          +The CUDD package provides a rich set of +dynamic reordering algorithms. Some of them +are slight variations of existing techniques +[16,6,2,10,15,11]; some +others have been developed specifically for this package +[14,13]. + +

          +Reordering affects a unique table. This means that +BDDs and ADDs, which share the same unique table are simultaneously +reordered. ZDDs, on the other hand, are reordered separately. In the +following we discuss the reordering of BDDs and ADDs. Reordering for +ZDDs is the subject of Section 3.14. + +

          +Reordering of the variables can be invoked directly by the application +by calling Cudd_ReduceHeap. Or it can +be automatically triggered by the package when the number of nodes has +reached a given threshold. (The threshold +is initialized and automatically adjusted after each reordering by the +package.) To enable automatic dynamic reordering (also called +asynchronous dynamic reordering +in this document) the application must call +Cudd_AutodynEnable. Automatic +dynamic reordering can subsequently be disabled by calling +Cudd_AutodynDisable. + +

          +All reordering methods are available in both the case of direct call +to Cudd_ReduceHeap and the case of +automatic invocation. For many methods, the reordering procedure is +iterated until no further improvement is obtained. We call these +methods the converging methods. +When constraints are imposed on the relative position of variables +(see Section 3.13) the reordering methods apply inside the +groups. The groups themselves are reordered +by sifting. Each method is identified by a +constant of the enumerated type +Cudd_ReorderingType +defined in cudd.h (the external +header file of the CUDD package): + +

          +

          +
          CUDD_REORDER_NONE:
          +
          This method + causes no reordering. +
          +
          CUDD_REORDER_SAME:
          +
          If passed to + Cudd_AutodynEnable, this + method leaves the current method for automatic reordering unchanged. + If passed to Cudd_ReduceHeap, + this method causes the current method for automatic reordering to be + used. +
          +
          CUDD_REORDER_RANDOM:
          +
          Pairs of + variables are randomly chosen, and swapped in the order. The swap is + performed by a series of swaps of adjacent variables. The best order + among those obtained by the series of swaps is retained. The number + of pairs chosen for swapping equals the + number of variables in the diagram. +
          +
          CUDD_REORDER_RANDOM_PIVOT:
          +
          Same as CUDD_REORDER_RANDOM, but the two variables are chosen so + that the first is above the variable with the largest number of + nodes, and the second is below that variable. In case there are + several variables tied for the maximum number of nodes, the one + closest to the root is used. +
          +
          CUDD_REORDER_SIFT:
          +
          This method is + an implementation of Rudell's sifting + algorithm [16]. A simplified description of sifting is as + follows: Each variable is considered in turn. A variable is moved up + and down in the order so that it takes all possible positions. The + best position is identified and the variable is returned to that + position. + +

          +In reality, things are a bit more complicated. For instance, there + is a limit on the number of variables that will be sifted. This + limit can be read with + Cudd_ReadSiftMaxVar and set with + Cudd_SetSiftMaxVar. In addition, + if the diagram grows too much while moving a variable up or down, + that movement is terminated before the variable has reached one end + of the order. The maximum ratio by which the diagram is allowed to + grow while a variable is being sifted can be read with + Cudd_ReadMaxGrowth and set with + Cudd_SetMaxGrowth. +

          +
          CUDD_REORDER_SIFT_CONVERGE:
          +
          This is the converging variant of + CUDD_REORDER_SIFT. +
          +
          CUDD_REORDER_SYMM_SIFT:
          +
          This method is an implementation of + symmetric sifting [14]. It is + similar to sifting, with one addition: Variables that become + adjacent during sifting are tested for symmetry. If + they are symmetric, they are linked in a group. Sifting then + continues with a group being moved, instead of a single variable. + After symmetric sifting has been run, + Cudd_SymmProfile can be called to + report on the symmetry groups found. (Both positive and negative + symmetries are reported.) +
          +
          CUDD_REORDER_SYMM_SIFT_CONV:
          +
          This is the converging variant of + CUDD_REORDER_SYMM_SIFT. +
          +
          CUDD_REORDER_GROUP_SIFT:
          +
          This method is an implementation of group + sifting [13]. It is similar to symmetric sifting, but + aggregation is not restricted to symmetric + variables. +
          +
          CUDD_REORDER_GROUP_SIFT_CONV:
          +
          This method repeats until convergence the combination of + CUDD_REORDER_GROUP_SIFT and CUDD_REORDER_WINDOW4. +
          +
          CUDD_REORDER_WINDOW2:
          +
          This + method implements the window permutation + approach of Fujita [8] and Ishiura [10]. + The size of the window is 2. +
          +
          CUDD_REORDER_WINDOW3:
          +
          Similar + to CUDD_REORDER_WINDOW2, but with a window of size 3. +
          +
          CUDD_REORDER_WINDOW4:
          +
          Similar + to CUDD_REORDER_WINDOW2, but with a window of size 4. +
          +
          CUDD_REORDER_WINDOW2_CONV:
          +
          This is the converging variant of + CUDD_REORDER_WINDOW2. +
          +
          CUDD_REORDER_WINDOW3_CONV:
          +
          This is the converging variant of CUDD_REORDER_WINDOW3. +
          +
          CUDD_REORDER_WINDOW4_CONV:
          +
          This is the converging variant of CUDD_REORDER_WINDOW4. +
          +
          CUDD_REORDER_ANNEALING:
          +
          This + method is an implementation of simulated + annealing for variable + ordering, vaguely resemblant of the algorithm of [2]. + This method is potentially very slow. +
          +
          CUDD_REORDER_GENETIC:
          +
          This + method is an implementation of a genetic + algorithm for variable ordering, inspired by the work of Drechsler + [6]. This method is potentially very slow. +
          +
          CUDD_REORDER_EXACT:
          +
          This method + implements a dynamic programming approach to + exact reordering + [9,7,10], with improvements described in + [11]. It only stores one BDD at the time. Therefore, it is + relatively efficient in terms of memory. Compared to other + reordering strategies, it is very slow, and is not recommended for + more than 16 variables. +
          +
          +So far we have described methods whereby the package selects an order +automatically. A given order of the variables can also be imposed by +calling Cudd_ShuffleHeap. + +

          + +

          + +
          +Grouping Variables +

          + +

          +CUDD allows the application to specify constraints on the positions of +group of variables. It is possible to request that a group of +contiguous variables be kept contiguous by the reordering procedures. +It is also possible to request that the relative order of some groups +of variables be left unchanged. The constraints on the order are +specified by means of a tree, which is created in +one of two ways: + +

            +
          • By calling Cudd_MakeTreeNode. +
          • +
          • By calling the functions of the MTR library + (part of the distribution), and by registering the result with the + manager using Cudd_SetTree. The current + tree registered with the manager can be read with + Cudd_ReadTree. +
          • +
          + +

          +Each node in the tree represents a range of variables. The lower bound +of the range is given by the low field of the node, and the +size of the group is given by the size field of the +node.2 The variables +in each range are kept contiguous. Furthermore, if a node is marked +with the MTR_FIXED flag, then the relative order of +the variable ranges associated to its children is not changed. As an +example, suppose the initial variable order is: +

          +	x0, y0, z0, x1, y1, z1, ... , x9, y9, z9.
          +
          +Suppose we want to keep each group of three variables with the same +index (e.g., x3, y3, z3) contiguous, while allowing the package +to change the order of the groups. We can accomplish this with the +following code: +
          +	for (i = 0; i < 10; i++) {
          +	    (void) Cudd_MakeTreeNode(manager,i*3,3,MTR_DEFAULT);
          +	}
          +
          +If we want to keep the order within each group of variables +fixed (i.e., x before y before z) we need to +change MTR_DEFAULT into MTR_FIXED. + +

          +The low parameter passed to +Cudd_MakeTreeNode is the index of a +variable (as opposed to its level or position in the order). The +group tree can be created at any time. The +result obviously depends on the variable order in effect at creation +time. + +

          +It is possible to create a variable group tree also before the +variables themselves are created. The package assumes in this case +that the index of the variables not yet in existence will equal their +position in the order when they are created. Therefore, applications +that rely on +Cudd_bddNewVarAtLevel or +Cudd_addNewVarAtLevel to create +new variables have to create the variables before they group them. + +

          +The reordering procedure will skip all groups whose variables are not +yet in existence. For groups that are only partially in existence, the +reordering procedure will try to reorder the variables already +instantiated, without violating the adjacency constraints. + +

          + +

          + +
          +Variable Reordering for ZDDs +

          + +

          +Reordering of ZDDs is done in much the same way as the reordering of +BDDs and ADDs. The functions corresponding to Cudd_ReduceHeap +and Cudd_ShuffleHeap are +Cudd_zddReduceHeap and +Cudd_zddShuffleHeap. To enable +dynamic reordering, the application must +call Cudd_AutodynEnableZdd, and +to disable dynamic reordering, it must call +Cudd_AutodynDisableZdd. In the +current implementation, however, the choice of reordering methods for +ZDDs is more limited. Specifically, these methods are available: + +

          +

          +
          CUDD_REORDER_NONE;
          +
          +
          +
          CUDD_REORDER_SAME;
          +
          +
          +
          CUDD_REORDER_RANDOM;
          +
          +
          +
          CUDD_REORDER_RANDOM_PIVOT;
          +
          +
          +
          CUDD_REORDER_SIFT;
          +
          +
          +
          CUDD_REORDER_SIFT_CONVERGE;
          +
          +
          +
          CUDD_REORDER_SYMM_SIFT;
          +
          +
          +
          CUDD_REORDER_SYMM_SIFT_CONV.
          +
          +
          +
          + +

          +To create ZDD variable groups, the application calls +Cudd_MakeZddTreeNode. + +

          + +

          + +
          +Keeping Consistent Variable Orders for BDDs and ZDDs +

          + +

          +Several applications that manipulate both BDDs and ZDDs benefit from +keeping a fixed correspondence between the order of the BDD variables +and the order of the ZDD variables. If each BDD variable corresponds +to a group of ZDD variables, then it is often desirable that the +groups of ZDD variables be in the same order as the corresponding BDD +variables. CUDD allows the ZDD order to track the BDD order and vice +versa. To have the ZDD order track the BDD order, the application +calls Cudd_zddRealignEnable. The +effect of this call can be reversed by calling +Cudd_zddRealignDisable. When +ZDD realignment is in effect, automatic reordering of ZDDs should be +disabled. + +

          + +

          + +
          +Hooks +

          + +

          +Hooks in CUDD are lists of application-specified functions to be run on +certain occasions. Each hook is identified by a constant of the +enumerated type Cudd_HookType. In Version +2.5.0 hooks are defined for these occasions: + +

            +
          • before garbage collection (CUDD_PRE_GC_HOOK); +
          • +
          • after garbage collection (CUDD_POST_GC_HOOK); +
          • +
          • before variable reordering (CUDD_PRE_REORDERING_HOOK); +
          • +
          • after variable reordering (CUDD_POST_REORDERING_HOOK). +
          • +
          +The current implementation of hooks is experimental. A function added +to a hook receives a pointer to the manager, a pointer to a constant +string, and a pointer to void as arguments; it must return 1 if +successful; 0 otherwise. The second argument is one of ``DD,'' +``BDD,'' and ``ZDD.'' This allows the hook functions to tell the type +of diagram for which reordering or garbage collection takes place. The +third argument varies depending on the hook. The hook functions called +before or after garbage collection do +not use it. The hook functions called before +reordering are passed, in addition to the +pointer to the manager, also the method used for reordering. The hook +functions called after reordering are passed the start time. To add a +function to a hook, one uses Cudd_AddHook. +The function of a given hook +are called in the order in which they were added to the hook. For +sample hook functions, one may look at +Cudd_StdPreReordHook and +Cudd_StdPostReordHook. + +

          + +

          + +
          +Timeouts and Limits +

          + +

          +It is possible to set a time limit for a manger with +Cudd_SetTimeLimit. Once set, the +time available to the manager can be modified through other API +functions. CUDD checks for expiration periodically. When time has +expired, it returns NULL from the call in progress, but it leaves the +manager in a consistent state. The invoking application must be +designed to handle the NULL values returned. + +

          +When reordering, if a timout is approaching, CUDD will quit reordering +to give the application a chance to finish some computation. + +

          +It is also possible to invoke some functions that return NULL if they +cannot complete without creating more than a set number of nodes. +See, for instance, Cudd_bddAndLimit. + +

          + +

          + +
          +The SIS/VIS Interface +

          + +

          +The CUDD package contains interface functions that emulate the +behavior of the original BDD package used in SIS [17] and +in the newer +VIS +[4]. How to build VIS with CUDD is described +in the installation documents of VIS. (Version 1.1 and later.) + +

          + +

          + +
          +Using the CUDD Package in SIS +

          + +

          +This section describes how to build SIS with the CUDD package. Let +SISDIR designate the root of the directory +hierarchy where the sources for SIS reside. Let +CUDDDIR be the root of the directory hierarchy +where the distribution of the CUDD package resides. To build SIS with +the CUDD package, follow these steps. + +

            +
          1. Create directories SISDIR/sis/cudd and + SISDIR/sis/mtr. +
          2. +
          3. Copy all files from CUDDDIR/cudd and + CUDDDIR/sis to SISDIR/sis/cudd and all files from + CUDDDIR/mtr to SISDIR/sis/mtr. +
          4. +
          5. Copy CUDDDIR/cudd/doc/cudd.doc to + SISDIR/sis/cudd; also copy CUDDDIR/mtr/doc/mtr.doc + to SISDIR/sis/mtr. +
          6. +
          7. In SISDIR/sis/cudd make bdd.h a symbolic link + to cuddBdd.h. (That is: ln -s cuddBdd.h bdd.h.) +
          8. +
          9. In SISDIR/sis/cudd delete Makefile and rename + Makefile.sis as Makefile. Do the same in + SISDIR/sis/mtr. +
          10. +
          11. Copy CUDDDIR/sis/st.[ch] and CUDDDIR/st/doc/st.doc + to SISDIR/sis/st. (This will overwrite the original files: You + may want to save them beforehand.) +
          12. +
          13. From CUDDDIR/util copy datalimit.c to + SISDIR/sis/util. Update util.h and + Makefile in SISDIR/sis/util. Specifically, add the + declaration EXTERN long getSoftDataLimit(); to + util.h and add datalimit.c to the list of source + files (PSRC) in Makefile. +
          14. +
          15. In SISDIR/sis remove the link from bdd to + bdd_cmu or bdd_ucb (that is, rm bdd) + and make bdd a symbolic link to cudd. (That is: + ln -s cudd bdd.) +
          16. +
          17. Still in SISDIR/sis, edit Makefile, Makefile.oct, and Makefile.nooct. In all three files add + mtr to the list of directories to be made (DIRS). +
          18. +
          19. In SISDIR/sis/include make mtr.h a symbolic + link to ../mtr/mtr.h. +
          20. +
          21. In SISDIR/sis/doc make cudd.doc a symbolic + link to ../cudd/cudd.doc and mtr.doc a symbolic + link to ../mtr/mtr.doc. (That is: ln -s + ../cudd/cudd.doc .; ln -s ../mtr/mtr.doc ..) +
          22. +
          23. From SISDIR do make clean followed by + make -i. This should create a working copy of SIS that + uses the CUDD package. +
          24. +
          + +

          +The replacement for the st library is because the version +shipped with the CUDD package tests for out-of-memory conditions. +Notice that the version of the st library to be used for +replacement is not the one used for the normal build, because the +latter has been modified for C++ compatibility. The above installation +procedure has been tested on SIS 1.3. SIS can be obtained via +anonymous FTP from +ic.eecs.berkeley.edu. +To build SIS 1.3, you need sis-1.2.tar.Z and +sis-1.2.patch1.Z. When compiling on a DEC Alpha, you should add the -ieee_with_no_inexact flag. +(See Section 3.5.2.) Refer to the Makefile +in the top level directory of the distribution for how to compile with +32-bit pointers. + +

          + +

          + +
          +Writing Decision Diagrams to a File +

          + +

          +The CUDD package provides several functions to write decision diagrams +to a file. Cudd_DumpBlif writes a +file in blif format. It is restricted to BDDs. The diagrams +are written as a network of multiplexers, one multiplexer for each +internal node of the BDD. + +

          +Cudd_DumpDot produces input suitable to +the graph-drawing program +dot +written by Eleftherios Koutsofios and Stephen C. North. An example of +drawing produced by dot from the output of Cudd_DumpDot is +shown in Figure 1. It is restricted to BDDs and ADDs. + +

          + + + +
          Figure 1: +A BDD representing a phase constraint for the optimization of + fixed-polarity Reed-Muller forms. The label of each node is the + unique part of the node address. All nodes on the same level + correspond to the same variable, whose name is shown at the left of + the diagram. Dotted lines indicate complement + arcs. Dashed lines indicate regular ``else'' + arcs.
          +
          +\includegraphics[height=15.5cm]{phase.ps}
          +
          + +Cudd_zddDumpDot is the analog of +Cudd_DumpDot for ZDDs. + +

          +Cudd_DumpDaVinci produces input +suitable to the graph-drawing program +daVinci +developed at the University of Bremen. It is restricted to BDDs and +ADDs. + +

          +Functions are also available to produce the input format of +DDcal (see Section 2.2) and factored forms. + +

          + +

          + +
          +Saving and Restoring BDDs +

          + +

          +The +dddmp +library by Gianpiero Cabodi and Stefano Quer +allows a CUDD application to save BDDs to disk in compact form for +later retrieval. See the library's own documentation for the details. + +

          +


          + + +next + +up + +previous + +index +
          + Next: Programmer's Manual + Up: CUDD: CU Decision Diagram + Previous: How to Get CUDD +   Index + +
          +Fabio Somenzi +2012-02-04 +
          + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node4.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node4.html new file mode 100644 index 000000000..e1697b331 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node4.html @@ -0,0 +1,1165 @@ + + + + + +Programmer's Manual + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
          + Next: The C++ Interface + Up: CUDD: CU Decision Diagram + Previous: User's Manual +   Index +
          +
          + + +Subsections + + + +
          + +

          + +
          +Programmer's Manual +

          + +

          +This section provides additional detail on the working of the CUDD +package and on the programming conventions followed in its writing. +The additional detail should help those who want to write procedures +that directly manipulate the CUDD data structures. + +

          + +

          + +
          +Compiling and Linking +

          + +

          +If you plan to use the CUDD package as a clear box +(for instance, you want to write a procedure that traverses a decision +diagram) you need to add +

          +#include "cuddInt.h"
          +
          +to your source files. In addition, you should link libcudd.a to +your executable. Some platforms require specific compiler and linker +flags. Refer to the Makefile in the top level directory of +the distribution. + +

          + +

          + +
          +Reference Counts +

          + +

          +Garbage collection in the CUDD package is +based on reference counts. Each node stores the sum of the external +references and internal references. An internal BDD or ADD node is +created by a call to cuddUniqueInter, an +internal ZDD node is created by a call to +cuddUniqueInterZdd, and a +terminal node is created by a call to +cuddUniqueConst. If the node returned by +these functions is new, its reference count is zero. The function +that calls cuddUniqueInter, +cuddUniqueInterZdd, or +cuddUniqueConst is responsible for +increasing the reference count of the node. This is accomplished by +calling Cudd_Ref. + +

          +When a function is no longer needed by an application, the memory used +by its diagram can be recycled by calling +Cudd_RecursiveDeref (BDDs and ADDs) +or Cudd_RecursiveDerefZdd +(ZDDs). These functions decrease the reference count of the node passed to them. If the reference count +becomes 0, then two things happen: + +

            +
          1. The node is declared ``dead;'' this entails + increasing the counters of the dead + nodes. (One counter for the subtable to which the + node belongs, and one global counter for the + unique table to which the node belongs.) The + node itself is not affected. +
          2. +
          3. The function is recursively called on the two children of the + node. +
          4. +
          +For instance, if the diagram of a function does not share any nodes +with other diagrams, then calling +Cudd_RecursiveDeref or +Cudd_RecursiveDerefZdd on its +root will cause all the nodes of the diagram to become dead. + +

          +When the number of dead nodes reaches a given level (dynamically +determined by the package) garbage collection takes place. During +garbage collection dead nodes are returned +to the node free list. + +

          +When a new node is created, it is important to increase its +reference count before one of the two +following events occurs: + +

            +
          1. A call to cuddUniqueInter, + to cuddUniqueInterZdd, to + cuddUniqueConst, or to a + function that may eventually cause a call to them. +
          2. +
          3. A call to + Cudd_RecursiveDeref, to + Cudd_RecursiveDerefZdd, or to + a function that may eventually cause a call to them. +
          4. +
          +In practice, it is recommended to increase the reference count as soon +as the returned pointer has been tested for not being NULL. + +

          + +

          + +
          +NULL Return Values +

          + +

          +The interface to the memory management functions (e.g., malloc) used +by CUDD intercepts NULL return values and calls a handler. The +default handler exits with an error message. If the application does +not install another handler, therefore, a NULL return value from an +exported function of CUDD signals an internal error. + +

          +If the aplication, however, installs another handler that lets +execution continue, a NULL pointer returned by an exported function +typically indicates that the process has run out of memory. +Cudd_ReadErrorCode can be used to +ascertain the nature of the problem. + +

          +An application that tests for the result being NULL can try some +remedial action, if it runs out of memory. For instance, it may free +some memory that is not strictly necessary, or try a slower algorithm +that takes less space. As an example, CUDD overrides the default +handler when trying to enlarge the cache or increase the number of +slots of the unique table. If the allocation fails, the package prints +out a message and continues without resizing the cache. + +

          + +

          + +
          +Cudd_RecursiveDeref vs. Cudd_Deref +

          + +

          +It is often the case that a recursive procedure has to protect the +result it is going to return, while it disposes of intermediate +results. (See the previous discussion on when to increase reference +counts.) Once the intermediate results have been properly disposed +of, the final result must be returned to its pristine state, in which +the root node may have a reference count of 0. One cannot use +Cudd_RecursiveDeref (or +Cudd_RecursiveDerefZdd) for this purpose, because it may +erroneously make some nodes dead. Therefore, the package provides a +different function: Cudd_Deref. This +function is not recursive, and does not change the dead node counts. +Its use is almost exclusively the one just described: Decreasing the +reference count of the root of the final result before returning from +a recursive procedure. + +

          + +

          + +
          +When Increasing the Reference Count is Unnecessary +

          + +

          +When a copy of a predefined constant or of a +simple BDD variable is needed for comparison purposes, then calling +Cudd_Ref is not necessary, because these +simple functions are guaranteed to have reference counts greater than +0 at all times. If no call to Cudd_Ref is made, then no +attempt to free the diagram by calling +Cudd_RecursiveDeref or +Cudd_RecursiveDerefZdd should be +made. + +

          + +

          + +
          +Saturating Increments and Decrements +

          + +

          +On 32-bit machines, the CUDD package stores the +reference counts in unsigned short int's. +For large diagrams, it is possible for some reference counts to exceed +the capacity of an unsigned short int. Therefore, increments and +decrements of reference counts are saturating. This means that +once a reference count has reached the maximum possible value, it is +no longer changed by calls to Cudd_Ref, +Cudd_RecursiveDeref, +Cudd_RecursiveDerefZdd, or +Cudd_Deref. As a consequence, some nodes +that have no references may not be declared dead. This may result in a +small waste of memory, which is normally more than offset by the +reduction in size of the node structure. + +

          +When using 64-bit pointers, there is normally no memory advantage from +using short int's instead of int's in a DdNode. Therefore, increments +and decrements are not saturating in that case. What option is in +effect depends on two macros, SIZEOF_VOID_P +and SIZEOF_INT, defined in the external +header file (cudd.h). The +increments and decrements of the reference counts are performed using +two macros: cuddSatInc and +cuddSatDec, whose definitions depend on +SIZEOF_VOID_P and +SIZEOF_INT. + +

          + +

          + +
          +Complement Arcs +

          + +

          +If ADDs are restricted to use only the constants 0 and 1, they behave +like BDDs without complement arcs. It is normally easier to write code +that manipulates 0-1 ADDs, than to write code for BDDs. However, +complementation is trivial with complement arcs, and is not trivial +without. As a consequence, with complement arcs it is possible to +check for more terminal cases and it is possible to apply De Morgan's +laws to reduce problems that are essentially identical to a standard +form. This in turn increases the utilization of the cache. + +

          +The complement attribute is stored in the least significant bit of the +``else'' pointer of each node. An external pointer to a function can +also be complemented. The ``then'' pointer to a node, on the other +hand, is always regular. It is a mistake to +use a complement pointer as it is to address +memory. Instead, it is always necessary to obtain a regular version +of it. This is normally done by calling +Cudd_Regular. It is also a mistake to +call cuddUniqueInter with a complemented +``then'' child as argument. The calling procedure must apply De +Morgan's laws by complementing both pointers passed to +cuddUniqueInter and then taking the +complement of the result. + +

          + +

          + +
          +The Cache +

          + +

          +Each entry of the cache consists of five fields: The operator, three +pointers to operands and a pointer to the result. The operator and the +three pointers to the operands are combined to form three words. The +combination relies on two facts: + +

            +
          • Most operations have one or two operands. A few bits are + sufficient to discriminate all three-operands operations. +
          • +
          • All nodes are aligned to 16-byte boundaries. (32-byte boundaries + if 64-bit pointers are used.) Hence, there are a few bits available + to distinguish the three-operand operations from te others and to + assign unique codes to them. +
          • +
          + +

          +The cache does not contribute to the reference + +counts of the nodes. The fact that the cache contains a +pointer to a node does not imply that the node is alive. Instead, when +garbage collection takes place, all entries +of the cache pointing to dead nodes are cleared. + +

          +The cache is also cleared (of all entries) when dynamic +reordering takes place. In both cases, the entries +removed from the cache are about to become invalid. + +

          +All operands and results in a cache entry must be pointers to +DdNodes. If a function produces more than one result, +or uses more than three arguments, there are currently two solutions: + +

            +
          • Build a separate, local, cache. (Using, for + instance, the st library.) +
          • +
          • Combine multiple results, or multiple operands, into a single + diagram, by building a ``multiplexing structure'' with reserved + variables. +
          • +
          +Support of the former solution is under development. (See +cuddLCache.c..) Support for the latter solution may be +provided in future versions of the package. + +

          +There are three sets of interface functions to +the cache. The first set is for functions with three operands: +cuddCacheInsert and +cuddCacheLookup. The second set is for +functions with two operands: +cuddCacheInsert2 and +cuddCacheLookup2. The second set is for +functions with one operand: +cuddCacheInsert1 and +cuddCacheLookup1. The second set is +slightly faster than the first, and the third set is slightly faster +than the second. + +

          + +

          + +
          +Cache Sizing +

          + +

          +The size of the cache can increase during the execution of an +application. (There is currently no way to decrease the size of the +cache, though it would not be difficult to do it.) When a cache miss +occurs, the package uses the following criteria to decide whether to +resize the cache: + +

            +
          1. If the cache already exceeds the limit given by the + maxCache field of the manager, no resizing + takes place. The limit is the minimum of two values: a value set at + initialization time and possibly modified by the application, which + constitutes the hard limit beyond which the cache will never grow; + and a number that depends on the current total number of slots in + the unique table. +
          2. +
          3. If the cache is not too large already, resizing is decided based + on the hit rate. The policy adopted by the CUDD package is + ``reward-based.'' If the cache hit + rate is high, then it is worthwhile to increase the size of the + cache. +
          4. +
          +When resizing takes place, the statistical counters used to compute the hit rate are reinitialized so as to +prevent immediate resizing. The number of entries is doubled. + +

          +The rationale for the ``reward-based'' +policy is as follows. In many BDD/ADD applications the hit rate is +not very sensitive to the size of the cache: It is primarily a +function of the problem instance at hand. If a large hit rate is +observed, chances are that by using a large cache, the results of +large problems (those that would take longer to solve) will survive in +the cache without being overwritten long enough to cause a valuable +cache hit. Notice that when a large problem is solved more than once, +so are its recursively generated subproblems. If the hit rate is +low, the probability of large problems being solved more than once is +low. + +

          +The other observation about the cache sizing policy is that there is +little point in keeping a cache which is much larger than the unique +table. Every time the unique table ``fills up,'' garbage collection is +invoked and the cache is cleared of all dead entries. A cache that is +much larger than the unique table is therefore +less than fully utilized. + +

          + +

          + +
          +Local Caches +

          + +

          +Sometimes it may be necessary or convenient to use a local cache. A +local cache can be lossless (no results are ever +overwritten), or it may store objects for which +canonical representations are not available. One +important fact to keep in mind when using a local cache is that local +caches are not cleared during garbage +collection or before reordering. Therefore, it is necessary to +increment the reference count of all nodes +pointed by a local cache. (Unless their reference counts are +guaranteed positive in some other way. One such way is by including +all partial results in the global result.) Before disposing of the +local cache, all elements stored in it must be passed to +Cudd_RecursiveDeref. As consequence +of the fact that all results in a local cache are referenced, it is +generally convenient to store in the local cache also the result of +trivial problems, which are not usually stored in the global cache. +Otherwise, after a recursive call, it is difficult to tell whether the +result is in the cache, and therefore referenced, or not in the cache, +and therefore not referenced. + +

          +An alternative approach to referencing the results in the local caches +is to install hook functions (see Section 3.16) to be +executed before garbage collection. + +

          + +

          + +
          +The Unique Table +

          + +

          +A recursive procedure typically splits the operands by expanding with +respect to the topmost variable. Topmost in this context refers to the +variable that is closest to the roots in the current variable order. +The nodes, on the other hand, hold the index, which is invariant with +reordering. Therefore, when splitting, one must use the +permutation array maintained by the +package to get the right level. Access to the permutation array is +provided by the macro cuddI for BDDs and ADDs, +and by the macro cuddIZ for ZDDs. + +

          +The unique table consists of as many hash tables as +there are variables in use. These has tables are called unique + subtables. The sizes of the unique subtables are determined by two +criteria: + +

            +
          1. The collision lists should be short + to keep access time down. +
          2. +
          3. There should be enough room for dead nodes, to + prevent too frequent garbage collections. +
          4. +
          +While the first criterion is fairly straightforward to implement, the +second leaves more room to creativity. The CUDD package tries to +figure out whether more dead node should be allowed to increase +performance. (See also Section 3.4.) There are two +reasons for not doing garbage collection too often. The obvious one is +that it is expensive. The second is that dead nodes may be +reclaimed, if they are the result of a +successful cache lookup. Hence dead nodes may provide a substantial +speed-up if they are kept around long enough. The usefulness of +keeping many dead nodes around varies from application to application, +and from problem instance to problem instance. As in the sizing of the +cache, the CUDD package adopts a +``reward-based'' policy to +decide how much room should be used for the unique table. If the +number of dead nodes reclaimed is large compared to the number of +nodes directly requested from the memory manager, then the CUDD +package assumes that it will be beneficial to allow more room for the +subtables, thereby reducing the frequency of garbage collection. The +package does so by switching between two modes of operation: + +
            +
          1. Fast growth: In this mode, the + ratio of dead nodes to total nodes required for garbage collection + is higher than in the slow growth mode to favor resizing + of the subtables. +
          2. +
          3. Slow growth: In this + mode keeping many dead nodes around is not as important as + keeping memory requirements low. +
          4. +
          +Switching from one mode to the other is based on the following +criteria: + +
            +
          1. If the unique table is already large, only slow growth is + possible. +
          2. +
          3. If the table is small and many dead nodes are being reclaimed, + then fast growth is selected. +
          4. +
          +This policy is especially effective when the diagrams being +manipulated have lots of recombination. Notice the interplay of the +cache sizing and unique sizing: Fast growth normally occurs when the +cache hit rate is large. The cache and the unique table then grow in +concert, preserving a healthy balance between their sizes. + +

          + +

          + +
          +Allowing Asynchronous Reordering +

          + +

          +Asynchronous reordering is the reordering that is triggered +automatically by the increase of the number of nodes. Asynchronous +reordering takes place when a new internal node must be created, and +the number of nodes has reached a given +threshold. (The threshold is adjusted by +the package every time reordering takes place.) + +

          +Those procedures that do not create new nodes (e.g., procedures that +count the number of nodes or minterms) need +not worry about asynchronous reordering: No special precaution is +necessary in writing them. + +

          +Procedures that only manipulate decision diagrams through the exported +functions of the CUDD package also need not concern themselves with +asynchronous reordering. (See Section 3.2.1 for the +exceptions.) + +

          +The remaining class of procedures is composed of functions that visit +the diagrams and may create new nodes. All such procedures in the CUDD +package are written so that they can be interrupted by dynamic +reordering. The general approach followed goes under the name of +``abort and retry.'' As the name +implies, a computation that is interrupted by dynamic reordering is +aborted and tried again. + +

          +A recursive procedure that can be interrupted by dynamic reordering +(an interruptible procedure +from now on) is composed of two functions. One is responsible for the +real computation. The other is a simple +wrapper, which tests whether +reordering occurred and restarts the computation if it did. + +

          +Asynchronous reordering of BDDs and ADDs can only be triggered inside +cuddUniqueInter, when a new node is about +to be created. Likewise, asynchronous reordering of ZDDs can only be +triggered inside cuddUniqueInterZdd. +When reordering is triggered, three things happen: + +

            +
          1. cuddUniqueInter returns a NULL + value; +
          2. +
          3. The flag reordered of the manager is set to 1. (0 means + no reordering, while 2 indicates an error occurred during + reordering.) +
          4. +
          5. The counter reorderings of the manager is incremented. + The counter is initialized to 0 when the manager is started and can + be accessed by calling + Cudd_ReadReorderings. By taking + two readings of the counter, an application can determine if + variable reordering has taken place between the first and the second + reading. The package itself, however, does not make use of the + counter: It is mentioned here for completeness. +
          6. +
          + +

          +The recursive procedure that receives a NULL value from +cuddUniqueInter must free all +intermediate results that it may have computed before, and return NULL +in its turn. + +

          +The wrapper function does not +decide whether reordering occurred based on the NULL return value, +because the NULL value may be the result of lack of memory. Instead, +it checks the reordered flag. + +

          +When a recursive procedure calls another recursive procedure that may +cause reordering, it should bypass the wrapper and call the recursive +procedure directly. Otherwise, the calling procedure will not know +whether reordering occurred, and will not be able to restart. This is +the main reason why most recursive procedures are internal, rather +than static. (The wrappers, on the other hand, are mostly exported.) + +

          + +

          + +
          +Debugging +

          + +

          +By defining the symbol DD_DEBUG during compilation, +numerous checks are added to the code. In addition, the procedures +Cudd_DebugCheck, +Cudd_CheckKeys, and +cuddHeapProfile can be called at any +point to verify the consistency of the data structure. +(cuddHeapProfile is an internal procedure. It is declared in +cuddInt.h.) Procedures +Cudd_DebugCheck and Cudd_CheckKeys are especially +useful when CUDD reports that during garbage collection the number of +nodes actually deleted from the unique table is different from the +count of dead nodes kept by the manager. The error causing the +discrepancy may have occurred much earlier than it is discovered. A +few strategicaly placed calls to the debugging procedures can +considerably narrow down the search for the source of the problem. +(For instance, a call to Cudd_RecursiveDeref where one to +Cudd_Deref was required may be identified in this way.) + +

          +One of the most common problems encountered in debugging code based on +the CUDD package is a missing call to +Cudd_RecursiveDeref. To help +identify this type of problems, the package provides a function called +Cudd_CheckZeroRef. This function +should be called immediately before shutting down the manager. +Cudd_CheckZeroRef checks that the only nodes left with +non-zero reference counts are the +predefined constants, the BDD projection +functions, and nodes whose reference counts are +saturated. + +

          +For this function to be effective the application must explicitly +dispose of all diagrams to which it has pointers before calling it. + +

          + +

          + +
          +Gathering and Interpreting Statistics +

          + +

          +Function Cudd_PrintInfo can be called to +print out the values of parameters and statistics for a manager. The +output of Cudd_PrintInfo is divided in two sections. The +first reports the values of parameters that are under the application +control. The second reports the values of statistical counters and +other non-modifiable parameters. A quick guide to the interpretation +of all these quantities follows. For ease of exposition, we reverse +the order and describe the non-modifiable parameters first. We'll use +a sample run as example. There is nothing special about this run. + +

          + +

          + +
          +Non Modifiable Parameters +

          + +

          +The list of non-modifiable parameters starts with: +

          +    **** CUDD non-modifiable parameters ****
          +    Memory in use: 32544220
          +
          +This is the memory used by CUDD for three things mainly: Unique table +(including all DD nodes in use), node free list, and computed table. +This number almost never decreases in the lifetime of a CUDD manager, +because CUDD does not release memory when it frees nodes. Rather, it +puts the nodes on its own free list. This number is in bytes. It does +not represent the peak memory occupation, because it does not include +the size of data structures created temporarily by some functions (e.g., +local look-up tables). + +

          +

          +    Peak number of nodes: 837018
          +
          +This number is the number of nodes that the manager has allocated. +This is not the largest size of the BDDs, because the manager will +normally have some dead nodes and some nodes on the free list. + +

          +

          +    Peak number of live nodes: 836894
          +
          +This is the largest number of live nodes that the manager has held +since its creation. + +

          +

          +    Number of BDD variables: 198
          +    Number of ZDD variables: 0
          +
          +These numbers tell us this run was not using ZDDs. + +

          +

          +    Number of cache entries: 1048576
          +
          +Current number of slots of the computed table. If one has a +performance problem, this is one of the numbers to look at. The cache +size is always a power of 2. + +

          +

          +    Number of cache look-ups: 2996536
          +    Number of cache hits: 1187087
          +
          +These numbers give an indication of the hit rate in the computed +table. It is not unlikely for model checking runs to get +hit rates even higher than this one (39.62%). + +

          +

          +    Number of cache insertions: 1809473
          +    Number of cache collisions: 961208
          +    Number of cache deletions: 0
          +
          +A collision occurs when a cache entry is +overwritten. A deletion +occurs when a cache entry is invalidated (e.g., during garbage +collection). If the number of deletions is high compared to the +number of collisions, it means that garbage collection occurs too +often. In this case there were no garbage collections; hence, no +deletions. + +

          +

          +    Cache used slots = 80.90% (expected 82.19%)
          +
          +Percentage of cache slots that contain a valid entry. If this +number is small, it may signal one of three conditions: + +
            +
          1. The cache may have been recently resized and it is still filling + up. +
          2. +
          3. The cache is too large for the BDDs. This should not happen if + the size of the cache is determined by CUDD. +
          4. +
          5. The hash function is not working properly. This is accompanied + by a degradation in performance. Conversely, a degradation in + performance may be due to bad hash function behavior. +
          6. +
          +The expected value is computed assuming a uniformly random +distribution of the accesses. If the difference between the measured +value and the expected value is large (unlike this case), the cache is +not working properly. + +

          +

          +    Soft limit for cache size: 1318912
          +
          +This number says how large the cache can grow. This limit is based on +the size of the unique table. CUDD uses a reward-based policy for +growing the cache. (See Section 4.4.1.) The default +hit rate for resizing is 30% and the value in effect is reported +among the modifiable parameters. + +

          +

          +    Number of buckets in unique table: 329728
          +
          +This number is exactly one quarter of the one above. This is indeed +how the soft limit is determined currently, unless the computed table +hits the specified hard limit. (See below.) + +

          +

          +    Used buckets in unique table: 87.96% (expected 87.93%)
          +
          +Percentage of unique table buckets that contain at least one +node. Remarks analogous to those made about the used cache slots apply. + +

          +

          +    Number of BDD and ADD nodes: 836894
          +    Number of ZDD nodes: 0
          +
          +How many nodes are currently in the unique table, either alive or dead. + +

          +

          +    Number of dead BDD and ADD nodes: 0
          +    Number of dead ZDD nodes: 0
          +
          +Subtract these numbers from those above to get the number of live +nodes. In this case there are no dead nodes because the application +uses delayed dereferencing +Cudd_DelayedDerefBdd. + +

          +

          +    Total number of nodes allocated: 836894
          +
          +This is the total number of nodes that were requested and obtained +from the free list. It never decreases, and is not an indication of +memory occupation after the first garbage collection. Rather, it is a +measure of the package activity. + +

          +

          +    Total number of nodes reclaimed: 0
          +
          +These are the nodes that were resuscitated from the dead. If they are +many more than the allocated nodes, and the total +number of slots is low relative to the number of nodes, then one may +want to increase the limit for fast unique table growth. In this case, +the number is 0 because of delayed dereferencing. + +

          +

          +    Garbage collections so far: 0
          +    Time for garbage collections: 0.00 sec
          +    Reorderings so far: 0
          +    Time for reordering: 0.00 sec
          +
          +There is a GC for each reordering. Hence the first count will always be +at least as large as the second. + +

          +

          +    Node swaps in reordering: 0
          +
          +This is the number of elementary reordering steps. Each step consists +of the re-expression of one node while swapping two adjacent +variables. This number is a good measure of the amount of work done in +reordering. + +

          + +

          + +
          +Modifiable Parameters +

          + +

          +Let us now consider the modifiable parameters, that is, those settings on +which the application or the user has control. + +

          +

          +    **** CUDD modifiable parameters ****
          +    Hard limit for cache size: 8388608
          +
          +This number counts entries. Each entry is 16 bytes if CUDD is compiled +to use 32-bit pointers. Two important observations are in order: + +
            +
          1. If the datasize limit is set, CUDD will use it to determine this + number automatically. On a Unix system, one can type ``limit'' or + ``ulimit'' to verify if this value is set. If the datasize limit is + not set, CUDD uses a default which is rather small. If you have + enough memory (say 64MB or more) you should seriously consider + not using the default. So, either set the datasize limit, or + override the default with + Cudd_SetMaxCacheHard. +
          2. +
          3. If a process seems to be going nowhere, a small value for + this parameter may be the culprit. One cannot overemphasize the + importance of the computed table in BDD algorithms. +
          4. +
          +In this case the limit was automatically set for a target maximum +memory occupation of 104 MB. + +

          +

          +    Cache hit threshold for resizing: 15%
          +
          +This number can be changed if one suspects performance is hindered by +the small size of the cache, and the cache is not growing towards the +soft limit sufficiently fast. In such a case one can change the +default 30% to 15% (as in this case) or even 1%. + +

          +

          +    Garbage collection enabled: yes
          +
          +One can disable it, but there are few good reasons for doing +so. It is normally preferable to raise the limit for fast unique table +growth. (See below.) + +

          +

          +    Limit for fast unique table growth: 1363148
          +
          +See Section 4.5 and the comments above about reclaimed +nodes and hard limit for the cache size. This value was chosen +automatically by CUDD for a datasize limit of 1 GB. + +

          +

          +    Maximum number of variables sifted per reordering: 1000
          +    Maximum number of variable swaps per reordering: 2000000
          +    Maximum growth while sifting a variable: 1.2
          +
          +Lowering these numbers will cause reordering to be less accurate and +faster. Results are somewhat unpredictable, because larger BDDs after one +reordering do not necessarily mean the process will go faster or slower. + +

          +

          +    Dynamic reordering of BDDs enabled: yes
          +    Default BDD reordering method: 4
          +    Dynamic reordering of ZDDs enabled: no
          +    Default ZDD reordering method: 4
          +
          +These lines tell whether automatic reordering can take place and what +method would be used. The mapping from numbers to methods is in +cudd.h. One may want to try different BDD reordering +methods. If variable groups are used, however, one should not expect +to see big differences, because CUDD uses the reported method only to +reorder each leaf variable group (typically corresponding present and +next state variables). For the relative order of the groups, it +always uses the same algorithm, which is effectively sifting. + +

          +As for enabling dynamic reordering or not, a sensible recommendation is the +following: Unless the circuit is rather small or one has a pretty good +idea of what the order should be, reordering should be enabled. + +

          +

          +    Realignment of ZDDs to BDDs enabled: no
          +    Realignment of BDDs to ZDDs enabled: no
          +    Dead nodes counted in triggering reordering: no
          +    Group checking criterion: 7
          +    Recombination threshold: 0
          +    Symmetry violation threshold: 0
          +    Arc violation threshold: 0
          +    GA population size: 0
          +    Number of crossovers for GA: 0
          +
          +Parameters for reordering. See the documentation of the functions used +to control these parameters for the details. + +

          +

          +    Next reordering threshold: 100000
          +
          +When the number of nodes crosses this threshold, reordering will be +triggered. (If enabled; in this case it is not.) This parameter is +updated by the package whenever reordering takes place. The +application can change it, for instance at start-up. Another +possibility is to use a hook function (see Section 3.16) to +override the default updating policy. + +

          + +

          + +
          +Extended Statistics and Reporting +

          + +

          +The following symbols can be defined during compilation to increase +the amount of statistics gathered and the number of messages produced +by the package: + +

            +
          • DD_STATS; +
          • +
          • DD_CACHE_PROFILE; +
          • +
          • DD_UNIQUE_PROFILE. +
          • +
          • DD_VERBOSE; +
          • +
          +Defining DD_CACHE_PROFILE causes each entry of the cache to include +an access counter, which is used to compute simple statistics on the +distribution of the keys. + +

          + +

          + +
          +Guidelines for Documentation +

          + +

          +The documentation of the CUDD functions is extracted automatically +from the sources by Stephen Edwards's extdoc. (The Ext system is +available via anonymous FTP from +ic.eecs.berkeley.edu.) +The following guidelines are followed in CUDD to insure consistent and +effective use of automatic extraction. It is recommended that +extensions to CUDD follow the same documentation guidelines. + +

            +
          • The documentation of an exported procedure should be sufficient + to allow one to use it without reading the code. It is not necessary + to explain how the procedure works; only what it does. +
          • +
          • The SeeAlso + fields should be space-separated lists of function names. The + SeeAlso field of an exported procedure should only reference + other exported procedures. The SeeAlso field of an internal + procedure may reference other internal procedures as well as + exported procedures, but no static procedures. +
          • +
          • The return values are detailed in the + Description + field, not in the + Synopsis field. +
          • +
          • The parameters are documented alongside their declarations. + Further comments may appear in the Description field. +
          • +
          • If the Description field is non-empty--which is the + normal case for an exported procedure--then the synopsis is + repeated--possibly slightly changed--at the beginning of the + Description field. This is so because extdoc will not put the + synopsis in the same HTML file as + the description. +
          • +
          • The Synopsis field should be about one line long. +
          • +
          + +

          +


          + + +next + +up + +previous + +index +
          + Next: The C++ Interface + Up: CUDD: CU Decision Diagram + Previous: User's Manual +   Index + +
          +Fabio Somenzi +2012-02-04 +
          + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node5.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node5.html new file mode 100644 index 000000000..b519a2f97 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node5.html @@ -0,0 +1,130 @@ + + + + + +The C++ Interface + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
          + Next: Acknowledgments + Up: CUDD: CU Decision Diagram + Previous: Programmer's Manual +   Index +
          +
          + + +Subsections + + + +
          + +

          + +
          +The C++ Interface +

          + +

          + +

          + +
          +Compiling and Linking +

          + +

          +To build an application that uses the CUDD C++ interface, you should +add +

          +#include "cuddObj.hh"
          +
          +to your source files. In addition to the normal CUDD libraries (see +Section 3.1) you should link +libobj.a to your executable. Refer to the +Makefile in the top level directory of the +distribution for further details. + +

          + +

          + +
          +Basic Manipulation +

          + +

          +The following fragment of code illustrates some simple operations on +BDDs using the C++ interface. +

          +	Cudd mgr(0,0);
          +	BDD x = mgr.bddVar();
          +	BDD y = mgr.bddVar();
          +	BDD f = x * y;
          +	BDD g = y + !x;
          +	cout << "f is" << (f <= g ? "" : " not")
          +	     << " less than or equal to g\n";
          +
          +This code creates a manager called mgr and two variables in it. +It then defines two functions f and g in terms of the +variables. Finally, it prints a message based on the comparison of the +two functions. No explicit referencing or dereferencing is required. +The operators are overloaded in the intuitive way. BDDs are freed when +execution leaves the scope in which they are defined or when the +variables referring to them are overwritten. + +

          +


          +
          +Fabio Somenzi +2012-02-04 +
          + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node6.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node6.html new file mode 100644 index 000000000..1f42c860e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node6.html @@ -0,0 +1,132 @@ + + + + + +Acknowledgments + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
          + Next: Bibliography + Up: CUDD: CU Decision Diagram + Previous: The C++ Interface +   Index +
          +
          + + +

          + +
          +Acknowledgments +

          + +

          +The contributors: Iris Bahar, Hyunwoo Cho, Erica Frohm, Charlie Gaona, +Cheng Hua, Jae-Young Jang, Seh-Woong Jeong, Balakrishna Kumthekar, +Enrico Macii, Bobbie Manne, In-Ho Moon, Curt Musfeldt, Shipra Panda, +Abelardo Pardo, Bernard Plessier, Kavita Ravi, Hyongkyoon Shin, Alan +Shuler, Arun Sivakumaran, Jorgen Sivesind. + +

          +The early adopters: Gianpiero Cabodi, Jordi Cortadella, Mario Escobar, +Gayani Gamage, Gary Hachtel, Mariano Hermida, Woohyuk Lee, Enric +Pastor, Massimo Poncino, Ellen Sentovich, the students of ECEN5139. + +

          +I am also particularly indebted to the following people for in-depth +discussions on BDDs: Armin Biere, Olivier Coudert, Arie Gurfinkel, +Geert Janssen, Don Knuth, David Long, Jean Christophe Madre, Ken +McMillan, Shin-Ichi Minato, Jaehong Park, Rajeev Ranjan, Rick Rudell, +Ellen Sentovich, Tom Shiple, Christian Stangier, and Bwolen Yang. + +

          +Special thanks to Norris Ip for guiding my faltering steps +in the design of the C++ interface. +Gianpiero Cabodi and Stefano Quer have graciously agreed to let me +distribute their dddmp library with CUDD. + +

          +Masahiro Fujita, Gary Hachtel, and Carl Pixley have provided +encouragement and advice. + +

          +The National Science Foundation and the Semiconductor Research +Corporation have supported in part the development of this package. + +

          + +


          + + +next + +up + +previous + +index +
          + Next: Bibliography + Up: CUDD: CU Decision Diagram + Previous: The C++ Interface +   Index + +
          +Fabio Somenzi +2012-02-04 +
          + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node7.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node7.html new file mode 100644 index 000000000..d7e967ef5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node7.html @@ -0,0 +1,195 @@ + + + + + +Bibliography + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
          + Next: Index + Up: CUDD: CU Decision Diagram + Previous: Acknowledgments +   Index +

          + + +

          +Bibliography +

          1 +
          +R. I. Bahar, E. A. Frohm, C. M. Gaona, G. D. Hachtel, E. Macii, A. Pardo, and + F. Somenzi. +
          Algebraic decision diagrams and their applications. +
          In Proceedings of the International Conference on Computer-Aided + Design, pages 188-191, Santa Clara, CA, November 1993. + +

          2 +
          +B. Bollig, M. Löbbing, and I. Wegener. +
          Simulated annealing to improve variable orderings for OBDDs. +
          Presented at the International Workshop on Logic Synthesis, + Granlibakken, CA, May 1995. + +

          3 +
          +K. S. Brace, R. L. Rudell, and R. E. Bryant. +
          Efficient implementation of a BDD package. +
          In Proceedings of the 27th Design Automation Conference, pages + 40-45, Orlando, FL, June 1990. + +

          4 +
          +R. K. Brayton et al. +
          VIS: A system for verification and synthesis. +
          Technical Report UCB/ERL M95/104, Electronics Research Lab, Univ. of + California, December 1995. + +

          5 +
          +R. E. Bryant. +
          Graph-based algorithms for Boolean function manipulation. +
          IEEE Transactions on Computers, C-35(8):677-691, August 1986. + +

          6 +
          +R. Drechsler, B. Becker, and N. Göckel. +
          A genetic algorithm for variable ordering of OBDDs. +
          Presented at the International Workshop on Logic Synthesis, + Granlibakken, CA, May 1995. + +

          7 +
          +S. J. Friedman and K. J. Supowit. +
          Finding the optimal variable ordering for binary decision diagrams. +
          IEEE Transactions on Computers, 39(5):710-713, May 1990. + +

          8 +
          +M. Fujita, Y. Matsunaga, and T. Kakuda. +
          On variable ordering of binary decision diagrams for the application + of multi-level logic synthesis. +
          In Proceedings of the European Conference on Design Automation, + pages 50-54, Amsterdam, February 1991. + +

          9 +
          +M. Held and R. M. Karp. +
          A dynamic programming approach to sequencing problems. +
          J. SIAM, 10(1):196-210, 1962. + +

          10 +
          +N. Ishiura, H. Sawada, and S. Yajima. +
          Minimization of binary decision diagrams based on exchanges of + variables. +
          In Proceedings of the International Conference on Computer-Aided + Design, pages 472-475, Santa Clara, CA, November 1991. + +

          11 +
          +S.-W. Jeong, T.-S. Kim, and F. Somenzi. +
          An efficient method for optimal BDD ordering computation. +
          In International Conference on VLSI and CAD (ICVC'93), Taejon, + Korea, November 1993. + +

          12 +
          +S.-I. Minato. +
          Zero-suppressed BDDs for set manipulation in combinatorial + problems. +
          In Proceedings of the Design Automation Conference, pages + 272-277, Dallas, TX, June 1993. + +

          13 +
          +S. Panda and F. Somenzi. +
          Who are the variables in your neighborhood. +
          In Proceedings of the International Conference on Computer-Aided + Design, pages 74-77, San Jose, CA, November 1995. + +

          14 +
          +S. Panda, F. Somenzi, and B. F. Plessier. +
          Symmetry detection and dynamic variable ordering of decision + diagrams. +
          In Proceedings of the International Conference on Computer-Aided + Design, pages 628-631, San Jose, CA, November 1994. + +

          15 +
          +B. F. Plessier. +
          A General Framework for Verification of Sequential Circuits. +
          PhD thesis, University of Colorado at Boulder, Dept. of Electrical + and Computer Engineering, 1993. + +

          16 +
          +R. Rudell. +
          Dynamic variable ordering for ordered binary decision diagrams. +
          In Proceedings of the International Conference on Computer-Aided + Design, pages 42-47, Santa Clara, CA, November 1993. + +

          17 +
          +E. M. Sentovich, K. J. Singh, C. Moon, H. Savoj, R. K. Brayton, and + A. Sangiovanni-Vincentelli. +
          Sequential circuit design using synthesis and optimization. +
          In Proceedings of the International Conference on Computer + Design, pages 328-333, Cambridge, MA, October 1992. +
          + + + + + + + +

          +


          +
          +Fabio Somenzi +2012-02-04 +
          + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node8.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node8.html new file mode 100644 index 000000000..a723fa181 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node8.html @@ -0,0 +1,848 @@ + + + + + +Index + + + + + + + + + + + + + + + + +next + +up + +previous +
          + Up: CUDD: CU Decision Diagram + Previous: Bibliography +
          +
          + +
          + +

          +Index +

          +
          ADD +
          Introduction + | Nodes + | New Constants + | Basic ADD Manipulation +
          aggregation +
          Variable Reordering for BDDs +
          Algebraic Decision Diagram +
          see ADD +
          arc +
          +
          complement +
          New BDD and ADD + | Writing Decision Diagrams to + | Writing Decision Diagrams to + | Complement Arcs + | Complement Arcs +
          regular +
          Writing Decision Diagrams to + | Writing Decision Diagrams to + | Complement Arcs +
          +
          background value +
          Background +
          BDD +
          Introduction + | Nodes + | One, Logic Zero, and + | Basic BDD Manipulation +
          Binary Decision Diagram +
          see BDD +
          box +
          +
          black +
          Introduction +
          clear +
          Introduction + | Compiling and Linking +
          +
          cache +
          Cache + | Cache + | Cache + | Initializing and Shutting Down + | Complement Arcs + | The Cache +
          +
          collision +
          Non Modifiable Parameters +
          collision list +
          The Unique Table +
          deletion +
          Non Modifiable Parameters +
          local +
          The Cache + | Local Caches +
          lossless +
          Local Caches +
          reward-based resizing +
          Cache Sizing + | Cache Sizing +
          sizing +
          Cache Sizing +
          +
          cacheSize +
          Initializing and Shutting Down +
          canonical +
          The Manager + | Local Caches +
          compiling +
          Compiling and Linking + | Predefined Constants + | Compiling and Linking +
          configuration +
          The CUDD Package +
          conversion +
          +
          of ADDs to BDDs +
          Converting ADDs to BDDs +
          of BDDs to ADDs +
          Converting ADDs to BDDs +
          of BDDs to ZDDs +
          Basic ZDD Manipulation + | Converting BDDs to ZDDs +
          of ZDDs to BDDs +
          Converting BDDs to ZDDs +
          +
          cube sets +
          Introduction +
          cudd.h +
          Compiling and Linking + | Variable Reordering for BDDs + | Saturating Increments and Decrements +
          Cudd_addApply +
          Basic ADD Manipulation + | Basic ADD Manipulation +
          Cudd_addBddInterval +
          Converting ADDs to BDDs +
          Cudd_addBddPattern +
          Converting ADDs to BDDs +
          Cudd_addBddThreshold +
          Converting ADDs to BDDs +
          Cudd_addConst +
          New Constants +
          Cudd_addHarwell +
          Background +
          Cudd_AddHook +
          Hooks +
          Cudd_addIthBit +
          Converting ADDs to BDDs +
          Cudd_addIthVar +
          New BDD and ADD +
          Cudd_addNewVar +
          New BDD and ADD +
          Cudd_addNewVarAtLevel +
          New BDD and ADD + | Grouping Variables +
          Cudd_addRead +
          Background +
          Cudd_addTimes +
          Basic ADD Manipulation +
          Cudd_AutodynDisable +
          Variable Reordering for BDDs +
          Cudd_AutodynDisableZdd +
          Variable Reordering for ZDDs +
          Cudd_AutodynEnable +
          Variable Reordering for BDDs + | Variable Reordering for BDDs +
          Cudd_AutodynEnableZdd +
          Variable Reordering for ZDDs +
          Cudd_bddAnd +
          Basic BDD Manipulation + | Basic BDD Manipulation + | Basic ADD Manipulation +
          Cudd_bddAndLimit +
          Timeouts and Limits +
          Cudd_bddConstrain +
          Nodes +
          Cudd_bddIte +
          Basic BDD Manipulation +
          Cudd_bddIthVar +
          New BDD and ADD +
          Cudd_bddNewVar +
          New BDD and ADD + | New BDD and ADD + | New BDD and ADD +
          Cudd_bddNewVarAtLevel +
          New BDD and ADD + | Grouping Variables +
          Cudd_BddToAdd +
          Converting ADDs to BDDs +
          Cudd_bddXor +
          Basic ADD Manipulation +
          CUDD_CACHE_SLOTS +
          Initializing and Shutting Down +
          Cudd_CheckKeys +
          Debugging +
          Cudd_CheckZeroRef +
          Debugging +
          Cudd_CountMinterm +
          Background +
          Cudd_DebugCheck +
          Debugging +
          Cudd_DelayedDerefBdd +
          Non Modifiable Parameters +
          Cudd_Deref +
          Cudd_RecursiveDeref vs. Cudd_Deref + | Saturating Increments and Decrements +
          Cudd_DumpBlif +
          Writing Decision Diagrams to +
          Cudd_DumpDaVinci +
          Writing Decision Diagrams to +
          Cudd_DumpDot +
          Writing Decision Diagrams to +
          Cudd_ForeachCube +
          Nodes + | Background +
          Cudd_ForeachNode +
          Nodes +
          Cudd_HookType +
          Hooks +
          Cudd_Init +
          Initializing and Shutting Down + | Initializing and Shutting Down +
          Cudd_MakeTreeNode +
          Grouping Variables + | Grouping Variables +
          Cudd_MakeZddTreeNode +
          Variable Reordering for ZDDs +
          Cudd_Not +
          One, Logic Zero, and +
          Cudd_PrintInfo +
          Gathering and Interpreting Statistics +
          Cudd_PrintMinterm +
          Background +
          Cudd_Quit +
          Initializing and Shutting Down +
          Cudd_ReadBackground +
          Background +
          Cudd_ReadEpsilon +
          Predefined Constants +
          Cudd_ReadErrorCode +
          NULL Return Values +
          Cudd_ReadInvPerm +
          Basic BDD Manipulation +
          Cudd_ReadLogicZero +
          One, Logic Zero, and +
          Cudd_ReadLooseUpto +
          Setting Parameters +
          Cudd_ReadMaxGrowth +
          Variable Reordering for BDDs +
          Cudd_ReadMinusInfinity +
          Predefined Constants +
          Cudd_ReadOne +
          One, Logic Zero, and +
          Cudd_ReadPlusInfinity +
          Predefined Constants +
          Cudd_ReadReorderings +
          Allowing Asynchronous Reordering +
          Cudd_ReadSiftMaxVar +
          Variable Reordering for BDDs +
          Cudd_ReadTree +
          Grouping Variables +
          Cudd_ReadZddOne +
          One, Logic Zero, and + | Basic ZDD Manipulation +
          Cudd_ReadZero +
          Predefined Constants +
          Cudd_RecursiveDeref +
          Nodes + | Reference Counts + | Reference Counts + | Reference Counts + | Cudd_RecursiveDeref vs. Cudd_Deref + | When Increasing the Reference + | Saturating Increments and Decrements + | Local Caches + | Debugging +
          Cudd_RecursiveDerefZdd +
          Nodes + | Reference Counts + | Reference Counts + | Reference Counts + | When Increasing the Reference + | Saturating Increments and Decrements +
          Cudd_ReduceHeap +
          Variable Reordering for BDDs + | Variable Reordering for BDDs + | Variable Reordering for BDDs +
          Cudd_Ref +
          Nodes + | Basic BDD Manipulation + | Reference Counts + | When Increasing the Reference +
          Cudd_Regular +
          Complement Arcs +
          CUDD_REORDER_ANNEALING +
          Variable Reordering for BDDs +
          CUDD_REORDER_EXACT +
          Variable Reordering for BDDs +
          CUDD_REORDER_GENETIC +
          Variable Reordering for BDDs +
          CUDD_REORDER_GROUP_SIFT +
          Variable Reordering for BDDs +
          CUDD_REORDER_GROUP_SIFT_CONV +
          Variable Reordering for BDDs +
          CUDD_REORDER_NONE +
          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
          CUDD_REORDER_RANDOM +
          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
          CUDD_REORDER_RANDOM_PIVOT +
          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
          CUDD_REORDER_SAME +
          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
          CUDD_REORDER_SIFT +
          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
          CUDD_REORDER_SIFT_CONVERGE +
          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
          CUDD_REORDER_SYMM_SIFT +
          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
          CUDD_REORDER_SYMM_SIFT_CONV +
          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
          CUDD_REORDER_WINDOW2 +
          Variable Reordering for BDDs +
          CUDD_REORDER_WINDOW2_CONV +
          Variable Reordering for BDDs +
          CUDD_REORDER_WINDOW3 +
          Variable Reordering for BDDs +
          CUDD_REORDER_WINDOW3_CONV +
          Variable Reordering for BDDs +
          CUDD_REORDER_WINDOW4 +
          Variable Reordering for BDDs +
          CUDD_REORDER_WINDOW4_CONV +
          Variable Reordering for BDDs +
          Cudd_SetEpsilon +
          Predefined Constants +
          Cudd_SetLooseUpTo +
          Setting Parameters +
          Cudd_SetMaxCacheHard +
          Modifiable Parameters +
          Cudd_SetMaxGrowth +
          Variable Reordering for BDDs +
          Cudd_SetSiftMaxVar +
          Variable Reordering for BDDs +
          Cudd_SetTimeLimit +
          Timeouts and Limits +
          Cudd_SetTree +
          Grouping Variables +
          Cudd_ShuffleHeap +
          Variable Reordering for BDDs +
          Cudd_StdPostReordHook +
          Hooks +
          Cudd_StdPreReordHook +
          Hooks +
          Cudd_SymmProfile +
          Variable Reordering for BDDs +
          CUDD_UNIQUE_SLOTS +
          Initializing and Shutting Down +
          Cudd_zddDumpDot +
          Writing Decision Diagrams to +
          Cudd_zddIsop +
          Basic ZDD Manipulation +
          Cudd_zddIthVar +
          New ZDD Variables +
          Cudd_zddPortFromBdd +
          Converting BDDs to ZDDs +
          Cudd_zddPortToBdd +
          Converting BDDs to ZDDs +
          Cudd_zddRealignDisable +
          Keeping Consistent Variable Orders +
          Cudd_zddRealignEnable +
          Keeping Consistent Variable Orders +
          Cudd_zddReduceHeap +
          Variable Reordering for ZDDs +
          Cudd_zddShuffleHeap +
          Variable Reordering for ZDDs +
          Cudd_zddVarsFromBddVars +
          Converting BDDs to ZDDs + | Converting BDDs to ZDDs +
          Cudd_zddWeakDiv +
          Basic ZDD Manipulation +
          cuddCacheInsert +
          The Cache +
          cuddCacheInsert1 +
          The Cache +
          cuddCacheInsert2 +
          The Cache +
          cuddCacheLookup +
          The Cache +
          cuddCacheLookup1 +
          The Cache +
          cuddCacheLookup2 +
          The Cache +
          CUDDDIR +
          Using the CUDD Package +
          cuddHeapProfile +
          Debugging +
          cuddI +
          The Unique Table +
          cuddInt.h +
          Debugging +
          cuddIZ +
          The Unique Table +
          cuddSatDec +
          Saturating Increments and Decrements +
          cuddSatInc +
          Saturating Increments and Decrements +
          cuddUniqueConst +
          Reference Counts + | Reference Counts + | Reference Counts +
          cuddUniqueInter +
          Reference Counts + | Reference Counts + | Reference Counts + | Complement Arcs + | Complement Arcs + | Allowing Asynchronous Reordering + | Allowing Asynchronous Reordering + | Allowing Asynchronous Reordering +
          cuddUniqueInterZdd +
          Reference Counts + | Reference Counts + | Reference Counts + | Allowing Asynchronous Reordering +
          DD_CACHE_PROFILE +
          Extended Statistics and Reporting +
          DD_DEBUG +
          Debugging +
          DD_STATS +
          Extended Statistics and Reporting +
          DD_UNIQUE_PROFILE +
          Extended Statistics and Reporting +
          DD_VERBOSE +
          Extended Statistics and Reporting +
          DdManager +
          The Manager + | Initializing and Shutting Down +
          DdNode +
          Nodes + | The Cache +
          debugging +
          Debugging +
          DEC Alpha +
          Predefined Constants + | Using the CUDD Package +
          documentation +
          Guidelines for Documentation +
          +
          Description +
          Guidelines for Documentation +
          HTML files +
          Guidelines for Documentation +
          SeeAlso +
          Guidelines for Documentation +
          Synopsis +
          Guidelines for Documentation +
          +
          dot +
          see graph, drawing +
          Epsilon +
          Predefined Constants +
          extdoc +
          see documentation +
          floating point +
          Predefined Constants +
          +
          double (C type) +
          Nodes +
          IEEE Standard 754 +
          Predefined Constants +
          +
          free list +
          Reference Counts +
          FTP +
          The CUDD Package + | CUDD Friends + | Using the CUDD Package + | Guidelines for Documentation +
          function +
          +
          characteristic +
          Introduction + | Converting BDDs to ZDDs +
          cover +
          Basic ZDD Manipulation + | Converting BDDs to ZDDs + | Converting BDDs to ZDDs +
          +
          irredundant +
          Basic ZDD Manipulation +
          +
          minterms +
          Background + | Allowing Asynchronous Reordering +
          ON-set +
          Introduction +
          sum of products +
          Background +
          switching +
          Introduction + | Introduction +
          +
          garbage collection +
          Nodes + | Cache + | Setting Parameters + | Reference Counts + | Reference Counts + | The Cache + | Local Caches + | The Unique Table +
          +
          hooks +
          Hooks +
          +
          gcc +
          Predefined Constants +
          generator +
          Nodes +
          global variables +
          The Manager +
          graph +
          +
          arc capacity +
          Background +
          arc length +
          Background +
          drawing +
          Writing Decision Diagrams to + | Writing Decision Diagrams to +
          +
          growth +
          Setting Parameters +
          gzip +
          The CUDD Package +
          HAVE_IEEE_754 +
          Predefined Constants +
          header files +
          Variable Reordering for BDDs + | Saturating Increments and Decrements +
          hook +
          Hooks +
          infinities +
          Predefined Constants +
          installation +
          The CUDD Package +
          Intel Pentium 4 +
          The CUDD Package +
          interface +
          +
          cache +
          The Cache +
          SIS +
          The SIS/VIS Interface + | Using the CUDD Package +
          VIS +
          The SIS/VIS Interface +
          +
          libraries +
          The CUDD Package +
          +
          cudd +
          Compiling and Linking +
          dddmp +
          Saving and Restoring BDDs +
          mtr +
          Compiling and Linking + | Grouping Variables +
          obj +
          Compiling and Linking +
          st +
          Compiling and Linking + | The Cache +
          util +
          Compiling and Linking +
          +
          Makefile +
          Compiling and Linking + | Predefined Constants + | Compiling and Linking +
          manager +
          The Manager + | The Manager + | Constant Functions +
          matrix +
          +
          sparse +
          Background +
          +
          maxCache +
          Cache Sizing +
          maxMemory +
          Initializing and Shutting Down +
          MinusInfinity +
          Predefined Constants +
          MTR_DEFAULT +
          Grouping Variables +
          MTR_FIXED +
          Grouping Variables +
          nanotrav +
          The CUDD Package + | The CUDD Package +
          node +
          Nodes +
          +
          constant +
          Nodes + | Constant Functions + | One, Logic Zero, and + | Predefined Constants + | Background + | New Constants + | Reference Counts + | When Increasing the Reference +
          +
          value +
          Nodes +
          +
          dead +
          Reference Counts + | The Cache + | The Unique Table +
          dereference +
          Basic ADD Manipulation +
          reclaimed +
          The Unique Table +
          recycling +
          Nodes +
          reference +
          Basic ADD Manipulation +
          reference count +
          Nodes + | Nodes + | Basic BDD Manipulation + | Basic BDD Manipulation + | Reference Counts + | Reference Counts + | Reference Counts + | When Increasing the Reference + | Saturating Increments and Decrements + | The Cache + | Local Caches + | Debugging +
          +
          saturated +
          Debugging +
          +
          terminal +
          see node, constant +
          variable index +
          Nodes +
          +
          numSlots +
          Initializing and Shutting Down +
          numVars +
          Initializing and Shutting Down +
          numVarsZ +
          Initializing and Shutting Down +
          PlusInfinity +
          Predefined Constants + | Background +
          projection functions +
          Creating Variables + | New BDD and ADD + | New BDD and ADD + | New BDD and ADD + | New ZDD Variables + | Basic BDD Manipulation + | Basic ADD Manipulation + | Basic ZDD Manipulation + | Basic ZDD Manipulation + | Debugging +
          README file +
          The CUDD Package + | The CUDD Package +
          reordering +
          Introduction + | Introduction + | Nodes + | The Cache +
          +
          abort and retry +
          Allowing Asynchronous Reordering +
          asynchronous +
          Variable Reordering for BDDs + | Allowing Asynchronous Reordering +
          converging +
          Variable Reordering for BDDs + | Variable Reordering for BDDs + | Variable Reordering for BDDs + | Variable Reordering for BDDs +
          Cudd_ReorderingType +
          Variable Reordering for BDDs +
          dynamic +
          Introduction + | Variable Reordering for BDDs + | Variable Reordering for ZDDs +
          exact +
          Variable Reordering for BDDs +
          function wrapper +
          Allowing Asynchronous Reordering + | Allowing Asynchronous Reordering +
          genetic +
          Variable Reordering for BDDs +
          group +
          Variable Reordering for BDDs + | Variable Reordering for BDDs +
          hooks +
          Hooks +
          interruptible procedure +
          Allowing Asynchronous Reordering +
          of BDDs and ADDs +
          Variable Reordering for BDDs +
          of ZDDs +
          Basic ZDD Manipulation + | Variable Reordering for ZDDs +
          random +
          Variable Reordering for BDDs +
          sifting +
          Variable Reordering for BDDs + | Variable Reordering for BDDs +
          simulated annealing +
          Variable Reordering for BDDs +
          symmetric +
          Variable Reordering for BDDs +
          threshold +
          Variable Reordering for BDDs + | Allowing Asynchronous Reordering +
          window +
          Variable Reordering for BDDs +
          +
          saturating +
          +
          decrements +
          Saturating Increments and Decrements +
          increments +
          Saturating Increments and Decrements +
          +
          SISDIR +
          Using the CUDD Package +
          SIZEOF_INT +
          Saturating Increments and Decrements + | Saturating Increments and Decrements +
          SIZEOF_VOID_P +
          Saturating Increments and Decrements + | Saturating Increments and Decrements +
          statistical counters +
          The Manager + | Reference Counts + | Cache Sizing +
          statistics +
          Gathering and Interpreting Statistics +
          subtable +
          Initializing and Shutting Down + | Reference Counts +
          symmetry +
          Variable Reordering for BDDs +
          table +
          +
          computed +
          Cache +
          growth +
          Setting Parameters +
          hash +
          The Manager + | The Unique Table +
          unique +
          Nodes + | The Manager + | The Manager + | Initializing and Shutting Down + | Initializing and Shutting Down + | Setting Parameters + | Variable Reordering for BDDs + | Reference Counts + | Cache Sizing + | Cache Sizing + | The Unique Table +
          +
          fast growth +
          The Unique Table +
          reward-based resizing +
          The Unique Table +
          slow growth +
          The Unique Table +
          +
          +
          timeout +
          Timeouts and Limits +
          variable +
          +
          groups +
          Grouping Variables +
          order +
          Nodes + | New BDD and ADD +
          permutation +
          Nodes + | The Unique Table +
          tree +
          Grouping Variables + | Grouping Variables +
          +
          ZDD +
          Introduction + | Nodes + | New ZDD Variables + | Basic ZDD Manipulation + | Converting BDDs to ZDDs +
          zero +
          +
          arithmetic +
          One, Logic Zero, and + | New BDD and ADD + | Converting ADDs to BDDs +
          logical +
          One, Logic Zero, and + | Converting ADDs to BDDs +
          +
          Zero-suppressed Binary Decision Diagram +
          see ZDD + +
          +

          +
          +Fabio Somenzi +2012-02-04 +
          + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.mat b/resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.mat new file mode 100644 index 000000000..b0dd0a0a8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.mat @@ -0,0 +1,53 @@ +7 9 +0 0 1 +0 1 1 +0 2 1 +0 3 4 +0 4 3 +0 5 3 +0 6 3 +0 8 3 +1 0 4 +1 1 3 +1 2 2 +1 3 4 +1 4 1 +1 5 2 +1 6 4 +1 8 3 +2 0 1 +2 1 1 +2 2 4 +2 4 2 +2 5 3 +2 6 3 +2 8 3 +3 0 2 +3 1 1 +3 3 4 +3 4 4 +3 5 1 +3 8 1 +4 0 2 +4 1 3 +4 2 2 +4 3 4 +4 4 1 +4 5 1 +4 6 2 +4 8 2 +5 0 3 +5 1 3 +5 2 4 +5 3 4 +5 4 1 +5 5 3 +5 6 3 +5 8 4 +6 1 1 +6 2 1 +6 3 4 +6 4 2 +6 5 4 +6 6 4 +6 8 2 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.out b/resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.out new file mode 100644 index 000000000..4dc72222d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.out @@ -0,0 +1,396 @@ +# TestCudd Version #1.0, Release date 3/17/01 +# ./testcudd -p2 r7x8.1.mat +:name: r7x8.1.mat: 7 rows 9 columns +:1: M: 63 nodes 5 leaves 52 minterms +000000-- 1 +000001-0 1 +000001-1 4 +000010-0 4 +000010-1 3 +000011-0 2 +000011-1 4 +000100-- 3 +000101-0 3 +000110-0 1 +000110-1 2 +000111-0 4 +001000-- 1 +001001-0 4 +001010-0 2 +001010-1 1 +001011-1 4 +001100-0 2 +001100-1 3 +001101-0 3 +001110-0 4 +001110-1 1 +0100-0-0 3 +011000-0 3 +011010-0 1 +100000-0 2 +100000-1 3 +100001-0 2 +100001-1 4 +100010-- 3 +100011-- 4 +100100-- 1 +100101-0 2 +100110-0 1 +100110-1 3 +100111-0 3 +101000-1 1 +101001-0 1 +101001-1 4 +101100-0 2 +101100-1 4 +101101-0 4 +110000-0 2 +110010-0 4 +111000-0 2 + +:2: time to read the matrix = 0.00 sec +:3: C: 22 nodes 1 leaves 52 minterms +0000---- 1 +0001-0-- 1 +0001-1-0 1 +001000-- 1 +001001-0 1 +001010-- 1 +001011-1 1 +001100-- 1 +001101-0 1 +001110-- 1 +01-0-0-0 1 +1000---- 1 +1001-0-- 1 +1001-1-0 1 +101000-1 1 +101001-- 1 +101100-- 1 +101101-0 1 +1100-0-0 1 +111000-0 1 + +Testing iterator on cubes: +000000-- 1 +000001-0 1 +000001-1 4 +000010-0 4 +000010-1 3 +000011-0 2 +000011-1 4 +000100-- 3 +000101-0 3 +000110-0 1 +000110-1 2 +000111-0 4 +001000-- 1 +001001-0 4 +001010-0 2 +001010-1 1 +001011-1 4 +001100-0 2 +001100-1 3 +001101-0 3 +001110-0 4 +001110-1 1 +0100-0-0 3 +011000-0 3 +011010-0 1 +100000-0 2 +100000-1 3 +100001-0 2 +100001-1 4 +100010-- 3 +100011-- 4 +100100-- 1 +100101-0 2 +100110-0 1 +100110-1 3 +100111-0 3 +101000-1 1 +101001-0 1 +101001-1 4 +101100-0 2 +101100-1 4 +101101-0 4 +110000-0 2 +110010-0 4 +111000-0 2 + +Testing prime expansion of cubes: +-000---- 1 +-00--0-- 1 +0--0-0-0 1 +--00-0-0 1 +-0-100-- 1 +10-001-- 1 +-00----0 1 +00---0-- 1 +-1-000-0 1 +-0--01-0 1 +-0--00-1 1 +00-01--1 1 + +Testing iterator on primes (CNF): +-0-0---- 1 +-0---0-- 1 +0-0-0--- 1 +-0-----0 1 +---0-0-0 1 +0101-1-1 1 +--0-00-1 1 +1-0-10-0 1 + +Cache used slots = 58.06% (expected 58.94%) +xor1: 14 nodes 1 leaves 28 minterms +000--1-1 1 +001-11-1 1 +01---0-0 1 +100--1-1 1 +101-00-0 1 +101-01-1 1 +110--0-0 1 +111-00-0 1 + +Chosen minterm for Hamming distance test: : 9 nodes 1 leaves 1 minterms +11110010 1 + +Minimum Hamming distance = 1 +ycube: 5 nodes 1 leaves 8 minterms +-0-0-0-0 1 + +CP: 11 nodes 1 leaves 7 minterms +00-0-0-0 1 +1000-0-0 1 +101000-1 1 + +:4: ineq: 10 nodes 1 leaves 42 minterms +001000-- 1 +00101--- 1 +1000---- 1 +100100-- 1 +10011--- 1 +101----- 1 +111000-- 1 +11101--- 1 + +10------ 1 +-01----- 1 +1-1----- 1 +-0-0---- 1 +1--0---- 1 +-0--10-- 1 +--1010-- 1 +1---10-- 1 + +:4: ess: 1 nodes 1 leaves 128 minterms +-------- 1 + +:5: shortP: 7 nodes 1 leaves 2 minterms +000000-- 1 + +:5b: largest: 4 nodes 1 leaves 16 minterms +01-1---- 1 + +The value of M along the chosen shortest path is 1 +:6: shortP: 5 nodes 1 leaves 8 minterms +0000---- 1 + +Support of f: : 8 nodes 1 leaves 2 minterms +111111-1 1 + +Size of the support of f: 7 +Size of the support of f: 7 +Support of f and g: : 8 nodes 1 leaves 2 minterms +111111-1 1 + +Size of the support of f and g: 7 +Size of the support of f and g: 7 +Support common to f and g: : 5 nodes 1 leaves 16 minterms +-1-1-1-1 1 + +Support private to f: : 4 nodes 1 leaves 32 minterms +1-1-1--- 1 + +Support private to g: : 1 nodes 1 leaves 256 minterms +-------- 1 + +Average distance: 4138.57 +Number of variables = 8 Number of slots = 2304 +Number of keys = 999 Number of min dead = 9216 +walsh1: 16 nodes 2 leaves 256 minterms +-0--0--0--0- 1 +-0--0--0--10 1 +-0--0--0--11 -1 +-0--0--10-0- 1 +-0--0--10-10 1 +-0--0--10-11 -1 +-0--0--11-0- -1 +-0--0--11-10 -1 +-0--0--11-11 1 +-0--10-0--0- 1 +-0--10-0--10 1 +-0--10-0--11 -1 +-0--10-10-0- 1 +-0--10-10-10 1 +-0--10-10-11 -1 +-0--10-11-0- -1 +-0--10-11-10 -1 +-0--10-11-11 1 +-0--11-0--0- -1 +-0--11-0--10 -1 +-0--11-0--11 1 +-0--11-10-0- -1 +-0--11-10-10 -1 +-0--11-10-11 1 +-0--11-11-0- 1 +-0--11-11-10 1 +-0--11-11-11 -1 +-10-0--0--0- 1 +-10-0--0--10 1 +-10-0--0--11 -1 +-10-0--10-0- 1 +-10-0--10-10 1 +-10-0--10-11 -1 +-10-0--11-0- -1 +-10-0--11-10 -1 +-10-0--11-11 1 +-10-10-0--0- 1 +-10-10-0--10 1 +-10-10-0--11 -1 +-10-10-10-0- 1 +-10-10-10-10 1 +-10-10-10-11 -1 +-10-10-11-0- -1 +-10-10-11-10 -1 +-10-10-11-11 1 +-10-11-0--0- -1 +-10-11-0--10 -1 +-10-11-0--11 1 +-10-11-10-0- -1 +-10-11-10-10 -1 +-10-11-10-11 1 +-10-11-11-0- 1 +-10-11-11-10 1 +-10-11-11-11 -1 +-11-0--0--0- -1 +-11-0--0--10 -1 +-11-0--0--11 1 +-11-0--10-0- -1 +-11-0--10-10 -1 +-11-0--10-11 1 +-11-0--11-0- 1 +-11-0--11-10 1 +-11-0--11-11 -1 +-11-10-0--0- -1 +-11-10-0--10 -1 +-11-10-0--11 1 +-11-10-10-0- -1 +-11-10-10-10 -1 +-11-10-10-11 1 +-11-10-11-0- 1 +-11-10-11-10 1 +-11-10-11-11 -1 +-11-11-0--0- 1 +-11-11-0--10 1 +-11-11-0--11 -1 +-11-11-10-0- 1 +-11-11-10-10 1 +-11-11-10-11 -1 +-11-11-11-0- -1 +-11-11-11-10 -1 +-11-11-11-11 1 + +wtw: 14 nodes 2 leaves 16 minterms +0-00-00-00-0 16 +0-00-00-01-1 16 +0-00-01-10-0 16 +0-00-01-11-1 16 +0-01-10-00-0 16 +0-01-10-01-1 16 +0-01-11-10-0 16 +0-01-11-11-1 16 +1-10-00-00-0 16 +1-10-00-01-1 16 +1-10-01-10-0 16 +1-10-01-11-1 16 +1-11-10-00-0 16 +1-11-10-01-1 16 +1-11-11-10-0 16 +1-11-11-11-1 16 + +Average length of non-empty lists = 1 +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000 +Maximum number of variable swaps per reordering: 2000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: no +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: no +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 0 +Arc violation threshold: 0 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 4004 +**** CUDD non-modifiable parameters **** +Memory in use: 4274508 +Peak number of nodes: 2044 +Peak number of live nodes: 119 +Number of BDD variables: 9 +Number of ZDD variables: 0 +Number of cache entries: 2048 +Number of cache look-ups: 2864 +Number of cache hits: 729 +Number of cache insertions: 2301 +Number of cache collisions: 947 +Number of cache deletions: 1351 +Cache used slots = 66.11% (expected 67.49%) +Soft limit for cache size: 13312 +Number of buckets in unique table: 2560 +Used buckets in unique table: 0.51% (expected 0.51%) +Number of BDD and ADD nodes: 13 +Number of ZDD nodes: 0 +Number of dead BDD and ADD nodes: 0 +Number of dead ZDD nodes: 0 +Total number of nodes allocated: 1095 +Total number of nodes reclaimed: 967 +Garbage collections so far: 1 +Time for garbage collection: 0.00 sec +Reorderings so far: 0 +Time for reordering: 0.00 sec +total time = 0.00 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 0.0 seconds +System time 0.0 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131653K +Virtual data size = 152K + data size initialized = 18K + data size uninitialized = 1K + data size sbrk = 133K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 0 +Minor page faults = 1330 +Swaps = 0 +Input blocks = 0 +Output blocks = 16 +Context switch (voluntary) = 0 +Context switch (involuntary) = 1 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/testcudd.c b/resources/3rdparty/cudd-2.5.0/cudd/testcudd.c new file mode 100644 index 000000000..a5d4aa232 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/testcudd.c @@ -0,0 +1,1178 @@ +/**CFile*********************************************************************** + + FileName [testcudd.c] + + PackageName [cudd] + + Synopsis [Sanity check tests for some CUDD functions.] + + Description [testcudd reads a matrix with real coefficients and + transforms it into an ADD. It then performs various operations on + the ADD and on the BDD corresponding to the ADD pattern. Finally, + testcudd tests functions relate to Walsh matrices and matrix + multiplication.] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define TESTCUDD_VERSION "TestCudd Version #1.0, Release date 3/17/01" + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: testcudd.c,v 1.23 2012/02/05 05:30:29 fabio Exp $"; +#endif + +static const char *onames[] = { "C", "M" }; /* names of functions to be dumped */ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void usage (char * prog); +static FILE *open_file (char *filename, const char *mode); +static int testIterators (DdManager *dd, DdNode *M, DdNode *C, int pr); +static int testXor (DdManager *dd, DdNode *f, int pr, int nvars); +static int testHamming (DdManager *dd, DdNode *f, int pr); +static int testWalsh (DdManager *dd, int N, int cmu, int approach, int pr); +static int testSupport(DdManager *dd, DdNode *f, DdNode *g, int pr); + +/**AutomaticEnd***************************************************************/ + + +/**Function******************************************************************** + + Synopsis [Main function for testcudd.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +main(int argc, char * const *argv) +{ + FILE *fp; /* pointer to input file */ + char *file = (char *) ""; /* input file name */ + FILE *dfp = NULL; /* pointer to dump file */ + FILE *savefp = NULL;/* pointer to save current manager's stdout setting */ + char *dfile; /* file for DD dump */ + DdNode *dfunc[2]; /* addresses of the functions to be dumped */ + DdManager *dd; /* pointer to DD manager */ + DdNode *one; /* fast access to constant function */ + DdNode *M; + DdNode **x; /* pointers to variables */ + DdNode **y; /* pointers to variables */ + DdNode **xn; /* complements of row variables */ + DdNode **yn_; /* complements of column variables */ + DdNode **xvars; + DdNode **yvars; + DdNode *C; /* result of converting from ADD to BDD */ + DdNode *ess; /* cube of essential variables */ + DdNode *shortP; /* BDD cube of shortest path */ + DdNode *largest; /* BDD of largest cube */ + DdNode *shortA; /* ADD cube of shortest path */ + DdNode *constN; /* value returned by evaluation of ADD */ + DdNode *ycube; /* cube of the negated y vars for c-proj */ + DdNode *CP; /* C-Projection of C */ + DdNode *CPr; /* C-Selection of C */ + int length; /* length of the shortest path */ + int nx; /* number of variables */ + int ny; + int maxnx; + int maxny; + int m; + int n; + int N; + int cmu; /* use CMU multiplication */ + int pr; /* verbose printout level */ + int harwell; + int multiple; /* read multiple matrices */ + int ok; + int c; /* variable to read in options */ + int approach; /* reordering approach */ + int autodyn; /* automatic reordering */ + int groupcheck; /* option for group sifting */ + int profile; /* print heap profile if != 0 */ + int keepperm; /* keep track of permutation */ + int clearcache; /* clear the cache after each matrix */ + int blifOrDot; /* dump format: 0 -> dot, 1 -> blif, ... */ + int retval; /* return value */ + int i; /* loop index */ + unsigned long startTime; /* initial time */ + unsigned long lapTime; + int size; + unsigned int cacheSize, maxMemory; + unsigned int nvars,nslots; + + startTime = util_cpu_time(); + + approach = CUDD_REORDER_NONE; + autodyn = 0; + pr = 0; + harwell = 0; + multiple = 0; + profile = 0; + keepperm = 0; + cmu = 0; + N = 4; + nvars = 4; + cacheSize = 127; + maxMemory = 0; + nslots = CUDD_UNIQUE_SLOTS; + clearcache = 0; + groupcheck = CUDD_GROUP_CHECK7; + dfile = NULL; + blifOrDot = 0; /* dot format */ + + /* Parse command line. */ + while ((c = getopt(argc, argv, "CDHMPS:a:bcd:g:hkmn:p:v:x:X:")) + != EOF) { + switch(c) { + case 'C': + cmu = 1; + break; + case 'D': + autodyn = 1; + break; + case 'H': + harwell = 1; + break; + case 'M': +#ifdef MNEMOSYNE + (void) mnem_setrecording(0); +#endif + break; + case 'P': + profile = 1; + break; + case 'S': + nslots = atoi(optarg); + break; + case 'X': + maxMemory = atoi(optarg); + break; + case 'a': + approach = atoi(optarg); + break; + case 'b': + blifOrDot = 1; /* blif format */ + break; + case 'c': + clearcache = 1; + break; + case 'd': + dfile = optarg; + break; + case 'g': + groupcheck = atoi(optarg); + break; + case 'k': + keepperm = 1; + break; + case 'm': + multiple = 1; + break; + case 'n': + N = atoi(optarg); + break; + case 'p': + pr = atoi(optarg); + break; + case 'v': + nvars = atoi(optarg); + break; + case 'x': + cacheSize = atoi(optarg); + break; + case 'h': + default: + usage(argv[0]); + break; + } + } + + if (argc - optind == 0) { + file = (char *) "-"; + } else if (argc - optind == 1) { + file = argv[optind]; + } else { + usage(argv[0]); + } + if ((approach<0) || (approach>17)) { + (void) fprintf(stderr,"Invalid approach: %d \n",approach); + usage(argv[0]); + } + + if (pr > 0) { + (void) printf("# %s\n", TESTCUDD_VERSION); + /* Echo command line and arguments. */ + (void) printf("#"); + for (i = 0; i < argc; i++) { + (void) printf(" %s", argv[i]); + } + (void) printf("\n"); + (void) fflush(stdout); + } + + /* Initialize manager and provide easy reference to terminals. */ + dd = Cudd_Init(nvars,0,nslots,cacheSize,maxMemory); + one = DD_ONE(dd); + dd->groupcheck = (Cudd_AggregationType) groupcheck; + if (autodyn) Cudd_AutodynEnable(dd,CUDD_REORDER_SAME); + + /* Open input file. */ + fp = open_file(file, "r"); + + /* Open dump file if requested */ + if (dfile != NULL) { + dfp = open_file(dfile, "w"); + } + + x = y = xn = yn_ = NULL; + do { + /* We want to start anew for every matrix. */ + maxnx = maxny = 0; + nx = maxnx; ny = maxny; + if (pr>0) lapTime = util_cpu_time(); + if (harwell) { + if (pr > 0) (void) printf(":name: "); + ok = Cudd_addHarwell(fp, dd, &M, &x, &y, &xn, &yn_, &nx, &ny, + &m, &n, 0, 2, 1, 2, pr); + } else { + ok = Cudd_addRead(fp, dd, &M, &x, &y, &xn, &yn_, &nx, &ny, + &m, &n, 0, 2, 1, 2); + if (pr > 0) + (void) printf(":name: %s: %d rows %d columns\n", file, m, n); + } + if (!ok) { + (void) fprintf(stderr, "Error reading matrix\n"); + exit(1); + } + + if (nx > maxnx) maxnx = nx; + if (ny > maxny) maxny = ny; + + /* Build cube of negated y's. */ + ycube = DD_ONE(dd); + Cudd_Ref(ycube); + for (i = maxny - 1; i >= 0; i--) { + DdNode *tmpp; + tmpp = Cudd_bddAnd(dd,Cudd_Not(dd->vars[y[i]->index]),ycube); + if (tmpp == NULL) exit(2); + Cudd_Ref(tmpp); + Cudd_RecursiveDeref(dd,ycube); + ycube = tmpp; + } + /* Initialize vectors of BDD variables used by priority func. */ + xvars = ALLOC(DdNode *, nx); + if (xvars == NULL) exit(2); + for (i = 0; i < nx; i++) { + xvars[i] = dd->vars[x[i]->index]; + } + yvars = ALLOC(DdNode *, ny); + if (yvars == NULL) exit(2); + for (i = 0; i < ny; i++) { + yvars[i] = dd->vars[y[i]->index]; + } + + /* Clean up */ + for (i=0; i < maxnx; i++) { + Cudd_RecursiveDeref(dd, x[i]); + Cudd_RecursiveDeref(dd, xn[i]); + } + FREE(x); + FREE(xn); + for (i=0; i < maxny; i++) { + Cudd_RecursiveDeref(dd, y[i]); + Cudd_RecursiveDeref(dd, yn_[i]); + } + FREE(y); + FREE(yn_); + + if (pr>0) {(void) printf(":1: M"); Cudd_PrintDebug(dd,M,nx+ny,pr);} + + if (pr>0) (void) printf(":2: time to read the matrix = %s\n", + util_print_time(util_cpu_time() - lapTime)); + + C = Cudd_addBddPattern(dd, M); + if (C == 0) exit(2); + Cudd_Ref(C); + if (pr>0) {(void) printf(":3: C"); Cudd_PrintDebug(dd,C,nx+ny,pr);} + + /* Test iterators. */ + retval = testIterators(dd,M,C,pr); + if (retval == 0) exit(2); + + if (pr > 0) + cuddCacheProfile(dd,stdout); + + /* Test XOR */ + retval = testXor(dd,C,pr,nx+ny); + if (retval == 0) exit(2); + + /* Test Hamming distance functions. */ + retval = testHamming(dd,C,pr); + if (retval == 0) exit(2); + + /* Test selection functions. */ + CP = Cudd_CProjection(dd,C,ycube); + if (CP == NULL) exit(2); + Cudd_Ref(CP); + if (pr>0) {(void) printf("ycube"); Cudd_PrintDebug(dd,ycube,nx+ny,pr);} + if (pr>0) {(void) printf("CP"); Cudd_PrintDebug(dd,CP,nx+ny,pr);} + + if (nx == ny) { + CPr = Cudd_PrioritySelect(dd,C,xvars,yvars,(DdNode **)NULL, + (DdNode *)NULL,ny,Cudd_Xgty); + if (CPr == NULL) exit(2); + Cudd_Ref(CPr); + if (pr>0) {(void) printf(":4: CPr"); Cudd_PrintDebug(dd,CPr,nx+ny,pr);} + if (CP != CPr) { + (void) printf("CP != CPr!\n"); + } + Cudd_RecursiveDeref(dd, CPr); + } + + /* Test inequality generator. */ + { + int Nmin = ddMin(nx,ny); + int q; + DdGen *gen; + int *cube; + DdNode *f = Cudd_Inequality(dd,Nmin,2,xvars,yvars); + if (f == NULL) exit(2); + Cudd_Ref(f); + if (pr>0) { + (void) printf(":4: ineq"); + Cudd_PrintDebug(dd,f,nx+ny,pr); + if (pr>1) { + Cudd_ForeachPrime(dd,Cudd_Not(f),Cudd_Not(f),gen,cube) { + for (q = 0; q < dd->size; q++) { + switch (cube[q]) { + case 0: + (void) printf("1"); + break; + case 1: + (void) printf("0"); + break; + case 2: + (void) printf("-"); + break; + default: + (void) printf("?"); + } + } + (void) printf(" 1\n"); + } + (void) printf("\n"); + } + } + Cudd_IterDerefBdd(dd, f); + } + FREE(xvars); FREE(yvars); + + Cudd_RecursiveDeref(dd, CP); + + /* Test functions for essential variables. */ + ess = Cudd_FindEssential(dd,C); + if (ess == NULL) exit(2); + Cudd_Ref(ess); + if (pr>0) {(void) printf(":4: ess"); Cudd_PrintDebug(dd,ess,nx+ny,pr);} + Cudd_RecursiveDeref(dd, ess); + + /* Test functions for shortest paths. */ + shortP = Cudd_ShortestPath(dd, M, NULL, NULL, &length); + if (shortP == NULL) exit(2); + Cudd_Ref(shortP); + if (pr>0) { + (void) printf(":5: shortP"); Cudd_PrintDebug(dd,shortP,nx+ny,pr); + } + /* Test functions for largest cubes. */ + largest = Cudd_LargestCube(dd, Cudd_Not(C), &length); + if (largest == NULL) exit(2); + Cudd_Ref(largest); + if (pr>0) { + (void) printf(":5b: largest"); + Cudd_PrintDebug(dd,largest,nx+ny,pr); + } + Cudd_RecursiveDeref(dd, largest); + + /* Test Cudd_addEvalConst and Cudd_addIteConstant. */ + shortA = Cudd_BddToAdd(dd,shortP); + if (shortA == NULL) exit(2); + Cudd_Ref(shortA); + Cudd_RecursiveDeref(dd, shortP); + constN = Cudd_addEvalConst(dd,shortA,M); + if (constN == DD_NON_CONSTANT) exit(2); + if (Cudd_addIteConstant(dd,shortA,M,constN) != constN) exit(2); + if (pr>0) {(void) printf("The value of M along the chosen shortest path is %g\n", cuddV(constN));} + Cudd_RecursiveDeref(dd, shortA); + + shortP = Cudd_ShortestPath(dd, C, NULL, NULL, &length); + if (shortP == NULL) exit(2); + Cudd_Ref(shortP); + if (pr>0) { + (void) printf(":6: shortP"); Cudd_PrintDebug(dd,shortP,nx+ny,pr); + } + + /* Test Cudd_bddIteConstant and Cudd_bddLeq. */ + if (!Cudd_bddLeq(dd,shortP,C)) exit(2); + if (Cudd_bddIteConstant(dd,Cudd_Not(shortP),one,C) != one) exit(2); + Cudd_RecursiveDeref(dd, shortP); + + /* Experiment with support functions. */ + if (!testSupport(dd,M,ycube,pr)) { + exit(2); + } + Cudd_RecursiveDeref(dd, ycube); + + if (profile) { + retval = cuddHeapProfile(dd); + } + + size = dd->size; + + if (pr>0) { + (void) printf("Average distance: %g\n", Cudd_AverageDistance(dd)); + } + + /* Reorder if so requested. */ + if (approach != CUDD_REORDER_NONE) { +#ifndef DD_STATS + retval = Cudd_EnableReorderingReporting(dd); + if (retval == 0) { + (void) fprintf(stderr,"Error reported by Cudd_EnableReorderingReporting\n"); + exit(3); + } +#endif +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + exit(3); + } + retval = Cudd_CheckKeys(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + exit(3); + } +#endif + retval = Cudd_ReduceHeap(dd,(Cudd_ReorderingType)approach,5); + if (retval == 0) { + (void) fprintf(stderr,"Error reported by Cudd_ReduceHeap\n"); + exit(3); + } +#ifndef DD_STATS + retval = Cudd_DisableReorderingReporting(dd); + if (retval == 0) { + (void) fprintf(stderr,"Error reported by Cudd_DisableReorderingReporting\n"); + exit(3); + } +#endif +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + exit(3); + } + retval = Cudd_CheckKeys(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + exit(3); + } +#endif + if (approach == CUDD_REORDER_SYMM_SIFT || + approach == CUDD_REORDER_SYMM_SIFT_CONV) { + Cudd_SymmProfile(dd,0,dd->size-1); + } + + if (pr>0) { + (void) printf("Average distance: %g\n", Cudd_AverageDistance(dd)); + } + + if (keepperm) { + /* Print variable permutation. */ + (void) printf("Variable Permutation:"); + for (i=0; iinvperm[i]); + } + (void) printf("\n"); + (void) printf("Inverse Permutation:"); + for (i=0; iperm[i]); + } + (void) printf("\n"); + } + + if (pr>0) {(void) printf("M"); Cudd_PrintDebug(dd,M,nx+ny,pr);} + + if (profile) { + retval = cuddHeapProfile(dd); + } + + } + + /* Dump DDs of C and M if so requested. */ + if (dfile != NULL) { + dfunc[0] = C; + dfunc[1] = M; + if (blifOrDot == 1) { + /* Only dump C because blif cannot handle ADDs */ + retval = Cudd_DumpBlif(dd,1,dfunc,NULL,(char **)onames, + NULL,dfp,0); + } else { + retval = Cudd_DumpDot(dd,2,dfunc,NULL,(char **)onames,dfp); + } + if (retval != 1) { + (void) fprintf(stderr,"abnormal termination\n"); + exit(2); + } + } + + Cudd_RecursiveDeref(dd, C); + Cudd_RecursiveDeref(dd, M); + + if (clearcache) { + if (pr>0) {(void) printf("Clearing the cache... ");} + for (i = dd->cacheSlots - 1; i>=0; i--) { + dd->cache[i].data = NULL; + } + if (pr>0) {(void) printf("done\n");} + } + if (pr>0) { + (void) printf("Number of variables = %6d\t",dd->size); + (void) printf("Number of slots = %6u\n",dd->slots); + (void) printf("Number of keys = %6u\t",dd->keys); + (void) printf("Number of min dead = %6u\n",dd->minDead); + } + + } while (multiple && !feof(fp)); + + fclose(fp); + if (dfile != NULL) { + fclose(dfp); + } + + /* Second phase: experiment with Walsh matrices. */ + if (!testWalsh(dd,N,cmu,approach,pr)) { + exit(2); + } + + /* Check variable destruction. */ + assert(cuddDestroySubtables(dd,3)); + if (pr == 0) { + savefp = Cudd_ReadStdout(dd); + Cudd_SetStdout(dd,fopen("/dev/null","a")); + } + assert(Cudd_DebugCheck(dd) == 0); + assert(Cudd_CheckKeys(dd) == 0); + if (pr == 0) { + Cudd_SetStdout(dd,savefp); + } + + retval = Cudd_CheckZeroRef(dd); + ok = retval != 0; /* ok == 0 means O.K. */ + if (retval != 0) { + (void) fprintf(stderr, + "%d non-zero DD reference counts after dereferencing\n", retval); + } + + if (pr > 0) { + (void) Cudd_PrintInfo(dd,stdout); + } + + Cudd_Quit(dd); + +#ifdef MNEMOSYNE + mnem_writestats(); +#endif + + if (pr>0) (void) printf("total time = %s\n", + util_print_time(util_cpu_time() - startTime)); + + if (pr > 0) util_print_cpu_stats(stdout); + return ok; + /* NOTREACHED */ + +} /* end of main */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints usage info for testcudd.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +usage(char *prog) +{ + (void) fprintf(stderr, "usage: %s [options] [file]\n", prog); + (void) fprintf(stderr, " -C\t\tuse CMU multiplication algorithm\n"); + (void) fprintf(stderr, " -D\t\tenable automatic dynamic reordering\n"); + (void) fprintf(stderr, " -H\t\tread matrix in Harwell format\n"); + (void) fprintf(stderr, " -M\t\tturns off memory allocation recording\n"); + (void) fprintf(stderr, " -P\t\tprint BDD heap profile\n"); + (void) fprintf(stderr, " -S n\t\tnumber of slots for each subtable\n"); + (void) fprintf(stderr, " -X n\t\ttarget maximum memory in bytes\n"); + (void) fprintf(stderr, " -a n\t\tchoose reordering approach (0-13)\n"); + (void) fprintf(stderr, " \t\t\t0: same as autoMethod\n"); + (void) fprintf(stderr, " \t\t\t1: no reordering (default)\n"); + (void) fprintf(stderr, " \t\t\t2: random\n"); + (void) fprintf(stderr, " \t\t\t3: pivot\n"); + (void) fprintf(stderr, " \t\t\t4: sifting\n"); + (void) fprintf(stderr, " \t\t\t5: sifting to convergence\n"); + (void) fprintf(stderr, " \t\t\t6: symmetric sifting\n"); + (void) fprintf(stderr, " \t\t\t7: symmetric sifting to convergence\n"); + (void) fprintf(stderr, " \t\t\t8-10: window of size 2-4\n"); + (void) fprintf(stderr, " \t\t\t11-13: window of size 2-4 to conv.\n"); + (void) fprintf(stderr, " \t\t\t14: group sifting\n"); + (void) fprintf(stderr, " \t\t\t15: group sifting to convergence\n"); + (void) fprintf(stderr, " \t\t\t16: simulated annealing\n"); + (void) fprintf(stderr, " \t\t\t17: genetic algorithm\n"); + (void) fprintf(stderr, " -b\t\tuse blif as format for dumps\n"); + (void) fprintf(stderr, " -c\t\tclear the cache after each matrix\n"); + (void) fprintf(stderr, " -d file\tdump DDs to file\n"); + (void) fprintf(stderr, " -g\t\tselect aggregation criterion (0,5,7)\n"); + (void) fprintf(stderr, " -h\t\tprints this message\n"); + (void) fprintf(stderr, " -k\t\tprint the variable permutation\n"); + (void) fprintf(stderr, " -m\t\tread multiple matrices (only with -H)\n"); + (void) fprintf(stderr, " -n n\t\tnumber of variables\n"); + (void) fprintf(stderr, " -p n\t\tcontrol verbosity\n"); + (void) fprintf(stderr, " -v n\t\tinitial variables in the unique table\n"); + (void) fprintf(stderr, " -x n\t\tinitial size of the cache\n"); + exit(2); +} /* end of usage */ + + +/**Function******************************************************************** + + Synopsis [Opens a file.] + + Description [Opens a file, or fails with an error message and exits. + Allows '-' as a synonym for standard input.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static FILE * +open_file(char *filename, const char *mode) +{ + FILE *fp; + + if (strcmp(filename, "-") == 0) { + return mode[0] == 'r' ? stdin : stdout; + } else if ((fp = fopen(filename, mode)) == NULL) { + perror(filename); + exit(1); + } + return fp; + +} /* end of open_file */ + + +/**Function******************************************************************** + + Synopsis [Tests Walsh matrix multiplication.] + + Description [Tests Walsh matrix multiplication. Return 1 if successful; + 0 otherwise.] + + SideEffects [May create new variables in the manager.] + + SeeAlso [] + +******************************************************************************/ +static int +testWalsh( + DdManager *dd /* manager */, + int N /* number of variables */, + int cmu /* use CMU approach to matrix multiplication */, + int approach /* reordering approach */, + int pr /* verbosity level */) +{ + DdNode *walsh1, *walsh2, *wtw; + DdNode **x, **v, **z; + int i, retval; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + + if (N > 3) { + x = ALLOC(DdNode *,N); + v = ALLOC(DdNode *,N); + z = ALLOC(DdNode *,N); + + for (i = N-1; i >= 0; i--) { + Cudd_Ref(x[i]=cuddUniqueInter(dd,3*i,one,zero)); + Cudd_Ref(v[i]=cuddUniqueInter(dd,3*i+1,one,zero)); + Cudd_Ref(z[i]=cuddUniqueInter(dd,3*i+2,one,zero)); + } + Cudd_Ref(walsh1 = Cudd_addWalsh(dd,v,z,N)); + if (pr>0) {(void) printf("walsh1"); Cudd_PrintDebug(dd,walsh1,2*N,pr);} + Cudd_Ref(walsh2 = Cudd_addWalsh(dd,x,v,N)); + if (cmu) { + Cudd_Ref(wtw = Cudd_addTimesPlus(dd,walsh2,walsh1,v,N)); + } else { + Cudd_Ref(wtw = Cudd_addMatrixMultiply(dd,walsh2,walsh1,v,N)); + } + if (pr>0) {(void) printf("wtw"); Cudd_PrintDebug(dd,wtw,2*N,pr);} + + if (approach != CUDD_REORDER_NONE) { +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + return(0); + } +#endif + retval = Cudd_ReduceHeap(dd,(Cudd_ReorderingType)approach,5); + if (retval == 0) { + (void) fprintf(stderr,"Error reported by Cudd_ReduceHeap\n"); + return(0); + } +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + return(0); + } +#endif + if (approach == CUDD_REORDER_SYMM_SIFT || + approach == CUDD_REORDER_SYMM_SIFT_CONV) { + Cudd_SymmProfile(dd,0,dd->size-1); + } + } + /* Clean up. */ + Cudd_RecursiveDeref(dd, wtw); + Cudd_RecursiveDeref(dd, walsh1); + Cudd_RecursiveDeref(dd, walsh2); + for (i=0; i < N; i++) { + Cudd_RecursiveDeref(dd, x[i]); + Cudd_RecursiveDeref(dd, v[i]); + Cudd_RecursiveDeref(dd, z[i]); + } + FREE(x); + FREE(v); + FREE(z); + } + return(1); + +} /* end of testWalsh */ + +/**Function******************************************************************** + + Synopsis [Tests iterators.] + + Description [Tests iterators on cubes and nodes.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +testIterators( + DdManager *dd, + DdNode *M, + DdNode *C, + int pr) +{ + int *cube; + CUDD_VALUE_TYPE value; + DdGen *gen; + int q; + + /* Test iterator for cubes. */ + if (pr>1) { + (void) printf("Testing iterator on cubes:\n"); + Cudd_ForeachCube(dd,M,gen,cube,value) { + for (q = 0; q < dd->size; q++) { + switch (cube[q]) { + case 0: + (void) printf("0"); + break; + case 1: + (void) printf("1"); + break; + case 2: + (void) printf("-"); + break; + default: + (void) printf("?"); + } + } + (void) printf(" %g\n",value); + } + (void) printf("\n"); + } + + if (pr>1) { + (void) printf("Testing prime expansion of cubes:\n"); + if (!Cudd_bddPrintCover(dd,C,C)) return(0); + } + + if (pr>1) { + (void) printf("Testing iterator on primes (CNF):\n"); + Cudd_ForeachPrime(dd,Cudd_Not(C),Cudd_Not(C),gen,cube) { + for (q = 0; q < dd->size; q++) { + switch (cube[q]) { + case 0: + (void) printf("1"); + break; + case 1: + (void) printf("0"); + break; + case 2: + (void) printf("-"); + break; + default: + (void) printf("?"); + } + } + (void) printf(" 1\n"); + } + (void) printf("\n"); + } + + /* Test iterator on nodes. */ + if (pr>2) { + DdNode *node; + (void) printf("Testing iterator on nodes:\n"); + Cudd_ForeachNode(dd,M,gen,node) { + if (Cudd_IsConstant(node)) { +#if SIZEOF_VOID_P == 8 + (void) printf("ID = 0x%lx\tvalue = %-9g\n", + (ptruint) node / + (ptruint) sizeof(DdNode), + Cudd_V(node)); +#else + (void) printf("ID = 0x%x\tvalue = %-9g\n", + (ptruint) node / + (ptruint) sizeof(DdNode), + Cudd_V(node)); +#endif + } else { +#if SIZEOF_VOID_P == 8 + (void) printf("ID = 0x%lx\tindex = %u\tr = %u\n", + (ptruint) node / + (ptruint) sizeof(DdNode), + node->index, node->ref); +#else + (void) printf("ID = 0x%x\tindex = %u\tr = %u\n", + (ptruint) node / + (ptruint) sizeof(DdNode), + node->index, node->ref); +#endif + } + } + (void) printf("\n"); + } + return(1); + +} /* end of testIterators */ + + +/**Function******************************************************************** + + Synopsis [Tests the functions related to the exclusive OR.] + + Description [Tests the functions related to the exclusive OR. It + builds the boolean difference of the given function in three + different ways and checks that the results is the same. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +testXor(DdManager *dd, DdNode *f, int pr, int nvars) +{ + DdNode *f1, *f0, *res1, *res2; + int x; + + /* Extract cofactors w.r.t. mid variable. */ + x = nvars / 2; + f1 = Cudd_Cofactor(dd,f,dd->vars[x]); + if (f1 == NULL) return(0); + Cudd_Ref(f1); + + f0 = Cudd_Cofactor(dd,f,Cudd_Not(dd->vars[x])); + if (f0 == NULL) { + Cudd_RecursiveDeref(dd,f1); + return(0); + } + Cudd_Ref(f0); + + /* Compute XOR of cofactors with ITE. */ + res1 = Cudd_bddIte(dd,f1,Cudd_Not(f0),f0); + if (res1 == NULL) return(0); + Cudd_Ref(res1); + + if (pr>0) {(void) printf("xor1"); Cudd_PrintDebug(dd,res1,nvars,pr);} + + /* Compute XOR of cofactors with XOR. */ + res2 = Cudd_bddXor(dd,f1,f0); + if (res2 == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(0); + } + Cudd_Ref(res2); + + if (res1 != res2) { + if (pr>0) {(void) printf("xor2"); Cudd_PrintDebug(dd,res2,nvars,pr);} + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(0); + } + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,f1); + Cudd_RecursiveDeref(dd,f0); + + /* Compute boolean difference directly. */ + res1 = Cudd_bddBooleanDiff(dd,f,x); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd,res2); + return(0); + } + Cudd_Ref(res1); + + if (res1 != res2) { + if (pr>0) {(void) printf("xor3"); Cudd_PrintDebug(dd,res1,nvars,pr);} + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(0); + } + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(1); + +} /* end of testXor */ + + +/**Function******************************************************************** + + Synopsis [Tests the Hamming distance functions.] + + Description [Tests the Hammming distance functions. Returns + 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +testHamming( + DdManager *dd, + DdNode *f, + int pr) +{ + DdNode **vars, *minBdd, *zero, *scan; + int i; + int d; + int *minterm; + int size = Cudd_ReadSize(dd); + + vars = ALLOC(DdNode *, size); + if (vars == NULL) return(0); + for (i = 0; i < size; i++) { + vars[i] = Cudd_bddIthVar(dd,i); + } + + minBdd = Cudd_bddPickOneMinterm(dd,Cudd_Not(f),vars,size); + Cudd_Ref(minBdd); + if (pr > 0) { + (void) printf("Chosen minterm for Hamming distance test: "); + Cudd_PrintDebug(dd,minBdd,size,pr); + } + + minterm = ALLOC(int,size); + if (minterm == NULL) { + FREE(vars); + Cudd_RecursiveDeref(dd,minBdd); + return(0); + } + scan = minBdd; + zero = Cudd_Not(DD_ONE(dd)); + while (!Cudd_IsConstant(scan)) { + DdNode *R = Cudd_Regular(scan); + DdNode *T = Cudd_T(R); + DdNode *E = Cudd_E(R); + if (R != scan) { + T = Cudd_Not(T); + E = Cudd_Not(E); + } + if (T == zero) { + minterm[R->index] = 0; + scan = E; + } else { + minterm[R->index] = 1; + scan = T; + } + } + Cudd_RecursiveDeref(dd,minBdd); + + d = Cudd_MinHammingDist(dd,f,minterm,size); + + if (pr > 0) + (void) printf("Minimum Hamming distance = %d\n", d); + + FREE(vars); + FREE(minterm); + return(1); + +} /* end of testHamming */ + + +/**Function******************************************************************** + + Synopsis [Tests the support functions.] + + Description [Tests the support functions. Returns + 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +testSupport( + DdManager *dd, + DdNode *f, + DdNode *g, + int pr) +{ + DdNode *sb, *common, *onlyF, *onlyG; + DdNode *F[2]; + int *support; + int ret, ssize; + int size = Cudd_ReadSize(dd); + + sb = Cudd_Support(dd, f); + if (sb == NULL) return(0); + Cudd_Ref(sb); + if (pr > 0) { + (void) printf("Support of f: "); + Cudd_PrintDebug(dd,sb,size,pr); + } + Cudd_RecursiveDeref(dd, sb); + + ssize = Cudd_SupportIndices(dd, f, &support); + if (ssize == CUDD_OUT_OF_MEM) return(0); + if (pr > 0) { + (void) printf("Size of the support of f: %d\n", ssize); + } + FREE(support); + + ssize = Cudd_SupportSize(dd, f); + if (pr > 0) { + (void) printf("Size of the support of f: %d\n", ssize); + } + + F[0] = f; + F[1] = g; + sb = Cudd_VectorSupport(dd, F, 2); + if (sb == NULL) return(0); + Cudd_Ref(sb); + if (pr > 0) { + (void) printf("Support of f and g: "); + Cudd_PrintDebug(dd,sb,size,pr); + } + Cudd_RecursiveDeref(dd, sb); + + ssize = Cudd_VectorSupportIndices(dd, F, 2, &support); + if (ssize == CUDD_OUT_OF_MEM) return(0); + if (pr > 0) { + (void) printf("Size of the support of f and g: %d\n", ssize); + } + FREE(support); + + ssize = Cudd_VectorSupportSize(dd, F, 2); + if (pr > 0) { + (void) printf("Size of the support of f and g: %d\n", ssize); + } + + ret = Cudd_ClassifySupport(dd, f, g, &common, &onlyF, &onlyG); + if (ret == 0) return(0); + Cudd_Ref(common); Cudd_Ref(onlyF); Cudd_Ref(onlyG); + if (pr > 0) { + (void) printf("Support common to f and g: "); + Cudd_PrintDebug(dd,common,size,pr); + (void) printf("Support private to f: "); + Cudd_PrintDebug(dd,onlyF,size,pr); + (void) printf("Support private to g: "); + Cudd_PrintDebug(dd,onlyG,size,pr); + } + Cudd_RecursiveDeref(dd, common); + Cudd_RecursiveDeref(dd, onlyF); + Cudd_RecursiveDeref(dd, onlyG); + + return(1); + +} /* end of testSupport */ diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/Makefile b/resources/3rdparty/cudd-2.5.0/dddmp/Makefile new file mode 100644 index 000000000..d84881a16 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/Makefile @@ -0,0 +1,243 @@ +#----------------------------------------------------------------------------# +# Makefile for the dddmp distribution kit # +# dddmp: Decision Diagram DuMP # +# (storage and retrieval of BDDs, ADDs and CNF formulas) # +# Revision: Version 2.0.2, February 01, 2004 # +#----------------------------------------------------------------------------# + +# Commands Available: +# make +# it makes the library libdddmp.a +# make testdddmp +# it makes the testdddmp program, which allows to test the dddmp +# package +# make clean +# it cleans dddmp +# make distclean +# it cleans dddmp (as clean) with libraries and executable +# files + +#----------------------------------------------------------------------------# +# Configuration Section # +# uncomment the desired options/sections # +#----------------------------------------------------------------------------# + +#--------------------# +# Define Directories # +#--------------------# + +# Cudd directory +WHERE = .. +#WHERE = ../cudd-2.4.0 + +# Include directory (Cudd include files) +INCLUDE = $(WHERE)/include + +#------------------------# +# Define C Compiler Used # +#------------------------# + +CC = gcc +#CC = g++ +#CC = cc +#CC = icc +#CC = ecc +#CC = /usr/ucb/cc +#CC = c89 + +.SUFFIXES: .o .c .u + +#---------------# +# Define ranlib # +#---------------# + +# For machines with ranlib and you think it is needed +RANLIB = ranlib +# For machines which either do not have ranlib or can do without it +#RANLIB = : + +#----------------------------------# +# Define Machine Independent Flags # +#----------------------------------# + +# Settings for cc +#ICFLAGS = +#ICFLAGS = -g +#ICFLAGS = -O +# Settings for optimized code with gcc +#ICFLAGS = -g -Wall +#ICFLAGS = -g -O3 -Wall +ICFLAGS = -g -O6 -Wall + +#--------------------------------# +# Define Machine Dependent Flags # +#--------------------------------# + +# When no special flags are needed +#XCFLAGS = -DHAVE_IEEE_754 -DBSD +# Linux with Gcc 2.8.1 or higher on i686. +#XCFLAGS = -mcpu=pentiumpro -malign-double -DHAVE_IEEE_754 -DBSD +# Gcc 3.3.2 or higher on i686. +XCFLAGS = -mcpu=pentium4 -malign-double -DHAVE_IEEE_754 -DBSD +# For Solaris, BSD should not be replaced by UNIX100. +#XCFLAGS = -DHAVE_IEEE_754 -DUNIX100 -DEPD_BIG_ENDIAN +# New native compiler for the Alphas; 64-bit pointers. +#XCFLAGS = -g3 -O4 -std -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# New native compiler for the Alphas; 32-bit pointers. +#XCFLAGS = -g3 -O4 -std -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -xtaso -DSIZEOF_LONG=8 +# Windows95/98/NT/XP with Cygwin tools +#XCFLAGS = -mcpu=pentiumpro -malign-double -DHAVE_IEEE_754 -DHAVE_GETRLIMIT=0 -DRLIMIT_DATA_DEFAULT=67108864 + +#---------------------------------------------# +# Define Level of Self-Checking and Verbosity # +#---------------------------------------------# + +# ... for the CUDD package +#DDDEBUG = -DDD_DEBUG -DDD_VERBOSE -DDD_STATS -DDD_CACHE_PROFILE -DDD_UNIQUE_PROFILE -DDD_COUNT +DDDEBUG = + +# ... for the MTR package +#MTRDEBUG = -DMTR_DEBUG +MTRDEBUG = + +# ... for the DDDMP package +#DDDMPDEBUG = -DDDDMP_DEBUG +DDDMPDEBUG = + +#-----------------------# +# Define Loader Options # +#-----------------------# + +LDFLAGS = +# This may produce faster code on the DECstations. +#LDFLAGS = -jmpopt -Olimit 1000 +# This may be necessary under some old versions of Linux. +#LDFLAGS = -static +# This normally makes the program faster on the DEC Alphas. +#LDFLAGS = -non_shared -om +# This is for 32-bit pointers on the DEC Alphas. +#LDFLAGS = -non_shared -om -taso +#LDFLAGS = -non_shared -taso + +#-------------# +# Define PURE # +#-------------# + +PURE = +# ... as purify to link with purify. +#PURE = purify +# ... as quantify to link with quantify. +#PURE = quantify + +#------------# +# Define EXE # +#------------# + +EXE = +# ... as .exe for MS-DOS and derivatives. +#EXE = .exe + +#----------------------------------------------------------------------------# +# Files for the Package # +#----------------------------------------------------------------------------# + +P = dddmp +PSRC = dddmpStoreBdd.c dddmpStoreAdd.c dddmpStoreCnf.c \ + dddmpLoad.c dddmpLoadCnf.c \ + dddmpNodeBdd.c dddmpNodeAdd.c dddmpNodeCnf.c \ + dddmpStoreMisc.c dddmpUtil.c dddmpBinary.c dddmpConvert.c \ + dddmpDbg.c +PHDR = dddmp.h dddmpInt.h $(INCLUDE)/cudd.h $(INCLUDE)/cuddInt.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +TARGET = test$(P)$(EXE) +TARGETu = test$(P)-u + +# files for the test program +SRC = test$(P).c +OBJ = $(SRC:.c=.o) +UBJ = $(SRC:.c=.u) + +#----------------------------------------------------------------------------# +# Rules to compile and build libraries and executables # +#----------------------------------------------------------------------------# + +#MFLAG = +MFLAG = -DMNEMOSYNE +MNEMLIB = ../mnemosyne/libmnem.a + +# This is to create the lint library +LINTFLAGS = -u -n +LINTSWITCH = -o + +LIBS = ./libdddmp.a $(WHERE)/cudd/libcudd.a $(WHERE)/mtr/libmtr.a \ + $(WHERE)/st/libst.a $(WHERE)/util/libutil.a $(WHERE)/epd/libepd.a + +MNEMLIB = + +BLIBS = -kL. -kldddmp -kL$(WHERE)/cudd -klcudd -kL$(WHERE)/mtr -klmtr \ + -kL$(WHERE)/st -klst -kL$(WHERE)/util -klutil + +LINTLIBS = ./llib-ldddmp.ln $(WHERE)/cudd/llib-lcudd.ln \ + $(WHERE)/mtr/llib-lmtr.ln $(WHERE)/st/llib-lst.ln \ + $(WHERE)/util/llib-lutil.ln + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(ICFLAGS) $(XCFLAGS) $(DDDEBUG) $(MTRDEBUG) $(DDDMPDEBUG) $(LDFLAGS) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PHDR) + cc -c $< -I$(INCLUDE) $(CFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) +$(OBJ): $(PHDR) +$(UBJ): $(PHDR) + +$(TARGET): $(SRC) $(OBJ) $(PHDR) $(LIBS) $(MNEMLIB) + $(PURE) $(CC) $(ICFLAGS) $(XCFLAGS) $(DDDEBUG) $(MTRDEBUG) $(DDDMPDEBUG) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +# optimize (DECstations and Alphas only: uses u-code) +$(TARGETu): $(SRC) $(UBJ) $(PHDR) $(LIBS:.a=.b) + cc -O3 -Olimit 1000 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +lintpgm: lint + lint $(LINTFLAGS) -I$(INCLUDE) $(SRC) $(LINTLIBS) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +programs: $(TARGET) $(TARGETu) lintpgm + +#----------------------------------------------------------------------------# +# Clean the Package # +#----------------------------------------------------------------------------# + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \ + *.bak *~ tags .gdb_history *.qv *.qx + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/README.dddmp b/resources/3rdparty/cudd-2.5.0/dddmp/README.dddmp new file mode 100644 index 000000000..704bd19a0 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/README.dddmp @@ -0,0 +1,64 @@ +README file for the DDDMP-2.0 package +Revision: Version 2.0.2, February 01, 2004 + + + +WHAT IS DDDMP +============= + +The DDDMP package defines formats for DD storage on file, and it contains a +set of functions to dump DDs and DD forests on file. + +In the version 1.0, only BDDs (ROBDDs) of the CUDD package (version 2.2.0 +or higher) were supported. +The version 2.0 includes supports for ADDs and CNF formulas. +The version 2.0.2 is for bug fixes. + + + +MAKE DDDMP +========== + +Before you build the libraries and programs, you need to check the +Makefile in the top directory. +Go through the definitions contained in the configuration section, and +select the desired compiler and compilation flags. +Instructions are provided in the comments of the Makefile. + +Then run "make". +This should produce the dddmplib.a library. + + + +DOCUMENTATION +============= + +Directory dddmp/doc contains HTML documentation for the package. +The recommended starting point is package.html. +Documentation in both postscript format and plain text format is also +provided. + + + +FTP SITE +======== + +The package is singularly available from the author home page: +http://staff.polito.it/{gianpiero.cabodi,stefano.quer} + + + + +FEEDBACK +======== + +Send feedback to: + +Stefano Quer & Gianpiero Cabodi +Politecnico di Torino +Dip. Automatica e Informatica +C.so Duca degli Abruzzi 24 +I-10129 Torino +Italy +E-mail: {gianpiero.cabodi,stefano.quer}@polito.it +WEB page: http://staff.polito.it/{gianpiero.cabodi,stefano.quer} diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/README.testdddmp b/resources/3rdparty/cudd-2.5.0/dddmp/README.testdddmp new file mode 100644 index 000000000..e1e1acfed --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/README.testdddmp @@ -0,0 +1,79 @@ +README file for the test program of the DDDMP-2.0 package +Revision: Version 2.0.2, February 01, 2004 + + + +WHAT IS TESTDDDMP +================= + +testdddmp is a test program for the dddmp package. +Practically, it is a naive user interface to load, store and execute +operations with BDDs. +It is included to provide a sanity check for the installation of the +package and an easy tool to play with BDDs and BDD on files. + + + +MAKE TESTDDDMP +============== + +Run "make testdddmp". +This should produce the testdddmp executable file. + + + +TEST DDDMP +========== + +Run the runAllTest.script file in the exp directory. +This should run all the test?.script files in the same directory. +Each of them is specifically written to check a particular feature of +the package (e.g., store and load of BDDs, store of CNF formulas and +retrieval, etc.). +Each test?.script should terminate with a comparison with a previously +generated set of files, then with the following set of messages: + +Files 0or1.bdd and 0or1.bdd2 are identical +Files 2and3.bdd and 2and3.bdd2 are identical +... + +If so everything is OK. + +Notice that mismatches may be caused by the presence of CR - LF characters at +the end of each BDD file line. + + + +WORK WITH DDDMPTEST +=================== + +To work with dddmptest (once the executable file has been built) it is enough +to run it (no parameter is necessary). +The help command print out the main commands available. +For each command further inputs are eventually required on an interactive +basis. +BDDs and ADDs can be loaded from files by choosing the file name or they +can be directly created (randomly for example). +They can be maintained into the main memory trough an array of BDD pointers. +Operations (logical and re-ordering) can be performed on any BDD into this +array. +Eventually any of them can be stored in a file giving the file name. +BDDs can also be stored in a CNF format using three different possible +solution to store them. + + + +FEEDBACK +======== + +Send feedback to: + +Gianpiero Cabodi and Stefano Quer +Politecnico di Torino +Dip. Automatica e Informatica +C.so Duca degli Abruzzi 24 +I-10129 Torino +Italy +E-mail: {gianpiero.cabodi,stefano.quer}@polito.it +WEB page: http://staff.polito.it/{gianpiero.cabodi,stefano.quer} + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/RELEASE_NOTES b/resources/3rdparty/cudd-2.5.0/dddmp/RELEASE_NOTES new file mode 100644 index 000000000..c8f4b9a6e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/RELEASE_NOTES @@ -0,0 +1,60 @@ +RELEASE NOTES FOR DDDMP +Revision: Version 2.0.2 +Turin, Italy, February 01, 2004 + +dddmp-2.0.2 is now available at +WEB page: http://staff.polito.it/{gianpiero.cabodi,stefano.quer} +dddmp-2.0.2 has a few bug fixes with respect to dddmp-2.0 + +Release 2.0.2 of DDDMP improves DDDMP-1.2 in the following areas: + + 1. Support to store and load ADD has been inserted in the dddmp tool + + 2. Support to store BDDs as CNF formulas has been inserted in the + dddmp tool. + As far as the storing process is concerned three possible formats + are available: + + DDDMP_CNF_MODE_NODE + store a BDD by introducing an auxiliary variable for each BDD node + + DDDMP_CNF_MODE_MAXTERM + store a BDD by following the maxterm of the represented function + + DDDMP_CNF_MODE_BEST + trade-of between the two previous solution, trying to optimize + the number of literals stored. + + As far as the loading process is concerned three possible formats + are available: + + DDDMP_CNF_MODE_NO_CONJ + Return the Clauses without Conjunction + + DDDMP_CNF_MODE_NO_QUANT + Return the sets of BDDs without Quantification + + DDDMP_CNF_MODE_CONJ_QUANT + Return the sets of BDDs AFTER Existential Quantification + + 3. Functions to load the header of a BDD/ADD/CNF file, so collecting + information regarding variables, variable ordering, etc. + This can be seen as a pre-processing step prior a possible BDD/ADD/CNF + load of the entire structure. + Moreover it can be used in a manager initialization phase. + + 4. More precise information are stored in each BDD/ADD header during + the storing phase. + In particular this information may be used to make up the exact + variable ordering present in the manager used during the storing + phase. + Full compatibility with previously versions of the files (from + dddmp-1.0 on) is guaranteed. + + 5. Miscellaneous + Debugging has been performed on different hardware architectures + + 6. The test program, testdddmp has been improved. + Now it allows to perform more operations and to better debug the + different options. + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmp.h b/resources/3rdparty/cudd-2.5.0/dddmp/dddmp.h new file mode 100644 index 000000000..7228fe7ff --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmp.h @@ -0,0 +1,330 @@ +/**CHeaderFile***************************************************************** + + FileName [dddmp.h] + + PackageName [dddmp] + + Synopsis [Functions to read in and write out BDDs, ADDs + and CNF formulas from and to files.] + + Description [] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2002 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#ifndef _DDDMP +#define _DDDMP + +#if 0 +#define DDDMP_DEBUG +#endif + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include "util.h" +#include "cudd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* + * Dddmp format version + */ + +#define DDDMP_VERSION "DDDMP-2.0" + +/* + * Returned values (for theorically ALL the function of the package) + */ + +#define DDDMP_FAILURE ((int) 0) +#define DDDMP_SUCCESS ((int) 1) + +/* + * Format modes for DD (BDD and ADD) files + */ + +#define DDDMP_MODE_TEXT ((int)'A') +#define DDDMP_MODE_BINARY ((int)'B') +#define DDDMP_MODE_DEFAULT ((int)'D') + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/**Enum************************************************************************ + + Synopsis [Format modes for storing CNF files] + + Description [Type supported for storing BDDs into CNF + formulas. + Used internally to select the proper storing format: + DDDMP_CNF_MODE_NODE: create a CNF temporary variables for + each BDD node + DDDMP_CNF_MODE_MAXTERM: no temporary variables + DDDMP_CNF_MODE_BEST: trade-off between the two previous methods + ] + +******************************************************************************/ + +typedef enum { + DDDMP_CNF_MODE_NODE, + DDDMP_CNF_MODE_MAXTERM, + DDDMP_CNF_MODE_BEST +} Dddmp_DecompCnfStoreType; + +/**Enum************************************************************************ + + Synopsis [Format modes for loading CNF files.] + + Description [Type supported for loading CNF formulas into BDDs. + Used internally to select the proper returning format: + ] + +******************************************************************************/ + +typedef enum { + DDDMP_CNF_MODE_NO_CONJ, + DDDMP_CNF_MODE_NO_QUANT, + DDDMP_CNF_MODE_CONJ_QUANT +} Dddmp_DecompCnfLoadType; + +/**Enum************************************************************************ + + Synopsis [Type for supported decomposition types.] + + Description [Type for supported decomposition types. + Used internally to select the proper type (bdd, add, ...). + Given externally as information fule content. + ] + +******************************************************************************/ + +typedef enum { + DDDMP_BDD, + DDDMP_ADD, + DDDMP_CNF, + DDDMP_NONE +} Dddmp_DecompType; + + +/**Enum************************************************************************ + + Synopsis [Type for variable extra info.] + + Description [Type for variable extra info. Used to specify info stored + in text mode.] + +******************************************************************************/ + +typedef enum { + DDDMP_VARIDS, + DDDMP_VARPERMIDS, + DDDMP_VARAUXIDS, + DDDMP_VARNAMES, + DDDMP_VARDEFAULT +} Dddmp_VarInfoType; + +/**Enum************************************************************************ + + Synopsis [Type for variable matching in BDD load.] + + Description [] + +******************************************************************************/ + +typedef enum { + DDDMP_VAR_MATCHIDS, + DDDMP_VAR_MATCHPERMIDS, + DDDMP_VAR_MATCHAUXIDS, + DDDMP_VAR_MATCHNAMES, + DDDMP_VAR_COMPOSEIDS +} Dddmp_VarMatchType; + +/**Enum************************************************************************ + + Synopsis [Type for BDD root matching in BDD load.] + + Description [] + +******************************************************************************/ + +typedef enum { + DDDMP_ROOT_MATCHNAMES, + DDDMP_ROOT_MATCHLIST +} Dddmp_RootMatchType; + +typedef struct Dddmp_Hdr_s Dddmp_Hdr_t; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Checks for fatal bugs] + + Description [Conditional safety assertion. It prints out the file + name and line number where the fatal error occurred. + Messages are printed out on stderr. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#ifdef DDDMP_DEBUG +# define Dddmp_Assert(expr,errMsg) \ + { \ + if ((expr) == 0) { \ + fprintf (stderr, "FATAL ERROR: %s\n", errMsg); \ + fprintf (stderr, " File %s -> Line %d\n", \ + __FILE__, __LINE__); \ + fflush (stderr); \ + exit (DDDMP_FAILURE); \ + } \ + } +#else +# define Dddmp_Assert(expr,errMsg) \ + {} +#endif + +/**Macro*********************************************************************** + + Synopsis [Checks for Warnings: If expr==1 it prints out the warning + on stderr.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#define Dddmp_Warning(expr,errMsg) \ + { \ + if ((expr) == 1) { \ + fprintf (stderr, "WARNING: %s\n", errMsg); \ + fprintf (stderr, " File %s -> Line %d\n", \ + __FILE__, __LINE__); \ + fflush (stderr); \ + } \ + } + +/**Macro*********************************************************************** + + Synopsis [Checks for fatal bugs and return the DDDMP_FAILURE flag.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#define Dddmp_CheckAndReturn(expr,errMsg) \ + { \ + if ((expr) == 1) { \ + fprintf (stderr, "FATAL ERROR: %s\n", errMsg); \ + fprintf (stderr, " File %s -> Line %d\n", \ + __FILE__, __LINE__); \ + fflush (stderr); \ + return (DDDMP_FAILURE); \ + } \ + } + +/**Macro*********************************************************************** + + Synopsis [Checks for fatal bugs and go to the label to deal with + the error. + ] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#define Dddmp_CheckAndGotoLabel(expr,errMsg,label) \ + { \ + if ((expr) == 1) { \ + fprintf (stderr, "FATAL ERROR: %s\n", errMsg); \ + fprintf (stderr, " File %s -> Line %d\n", \ + __FILE__, __LINE__); \ + fflush (stderr); \ + goto label; \ + } \ + } + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern int Dddmp_Text2Bin(char *filein, char *fileout); +extern int Dddmp_Bin2Text(char *filein, char *fileout); +extern int Dddmp_cuddBddDisplayBinary(char *fileIn, char *fileOut); +extern DdNode * Dddmp_cuddBddLoad(DdManager *ddMgr, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp); +extern int Dddmp_cuddBddArrayLoad(DdManager *ddMgr, Dddmp_RootMatchType rootMatchMode, char **rootmatchnames, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***pproots); +extern DdNode * Dddmp_cuddAddLoad(DdManager *ddMgr, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp); +extern int Dddmp_cuddAddArrayLoad(DdManager *ddMgr, Dddmp_RootMatchType rootMatchMode, char **rootmatchnames, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***pproots); +extern int Dddmp_cuddHeaderLoad (Dddmp_DecompType *ddType, int *nVars, int *nsuppvars, char ***suppVarNames, char ***orderedVarNames, int **varIds, int **composeIds, int **auxIds, int *nRoots, char *file, FILE *fp); +extern int Dddmp_cuddBddLoadCnf(DdManager *ddMgr, Dddmp_VarMatchType varmatchmode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***rootsPtrPtr, int *nRoots); +extern int Dddmp_cuddBddArrayLoadCnf(DdManager *ddMgr, Dddmp_RootMatchType rootmatchmode, char **rootmatchnames, Dddmp_VarMatchType varmatchmode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***rootsPtrPtr, int *nRoots); +extern int Dddmp_cuddHeaderLoadCnf (int *nVars, int *nsuppvars, char ***suppVarNames, char ***orderedVarNames, int **varIds, int **composeIds, int **auxIds, int *nRoots, char *file, FILE *fp); +extern int Dddmp_cuddAddStore(DdManager *ddMgr, char *ddname, DdNode *f, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int Dddmp_cuddAddArrayStore(DdManager *ddMgr, char *ddname, int nRoots, DdNode **f, char **rootnames, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int Dddmp_cuddBddStore(DdManager *ddMgr, char *ddname, DdNode *f, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int Dddmp_cuddBddArrayStore(DdManager *ddMgr, char *ddname, int nRoots, DdNode **f, char **rootnames, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int Dddmp_cuddBddStoreCnf(DdManager *ddMgr, DdNode *f, Dddmp_DecompCnfStoreType mode, int noHeader, char **varNames, int *bddIds, int *bddAuxIds, int *cnfIds, int idInitial, int edgeInTh, int pathLengthTh, char *fname, FILE *fp, int *clauseNPtr, int *varNewNPtr); +extern int Dddmp_cuddBddArrayStoreCnf(DdManager *ddMgr, DdNode **f, int rootN, Dddmp_DecompCnfStoreType mode, int noHeader, char **varNames, int *bddIds, int *bddAuxIds, int *cnfIds, int idInitial, int edgeInTh, int pathLengthTh, char *fname, FILE *fp, int *clauseNPtr, int *varNewNPtr); +extern int Dddmp_cuddBddStorePrefix(DdManager *ddMgr, int nRoots, DdNode *f, char **inputNames, char **outputNames, char *modelName, char *fileName, FILE *fp); +extern int Dddmp_cuddBddArrayStorePrefix(DdManager *ddMgr, int nroots, DdNode **f, char **inputNames, char **outputNames, char *modelName, char *fname, FILE *fp); +extern int Dddmp_cuddBddStoreBlif(DdManager *ddMgr, int nRoots, DdNode *f, char **inputNames, char **outputNames, char *modelName, char *fileName, FILE *fp); +extern int Dddmp_cuddBddArrayStoreBlif(DdManager *ddMgr, int nroots, DdNode **f, char **inputNames, char **outputNames, char *modelName, char *fname, FILE *fp); +extern int Dddmp_cuddBddStoreSmv(DdManager *ddMgr, int nRoots, DdNode *f, char **inputNames, char **outputNames, char *modelName, char *fileName, FILE *fp); +extern int Dddmp_cuddBddArrayStoreSmv(DdManager *ddMgr, int nroots, DdNode **f, char **inputNames, char **outputNames, char *modelName, char *fname, FILE *fp); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpBinary.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpBinary.c new file mode 100644 index 000000000..a7cd67482 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpBinary.c @@ -0,0 +1,343 @@ +/**CFile********************************************************************** + + FileName [dddmpBinary.c] + + PackageName [dddmp] + + Synopsis [Input and output BDD codes and integers from/to file] + + Description [Input and output BDD codes and integers from/to file + in binary mode. + DD node codes are written as one byte. + Integers of any length are written as sequences of "linked" bytes. + For each byte 7 bits are used for data and one (MSBit) as link with + a further byte (MSB = 1 means one more byte). + Low level read/write of bytes filter , and + with escape sequences. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int WriteByteBinary(FILE *fp, unsigned char c); +static int ReadByteBinary(FILE *fp, unsigned char *cp); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes 1 byte node code] + + Description [outputs a 1 byte node code using the following format: +
          +     Unused      : 1 bit;
          +     V           : 2 bits;     (variable code)
          +     T           : 2 bits;     (Then code)
          +     Ecompl      : 1 bit;      (Else complemented)
          +     E           : 2 bits;     (Else code)
          +    
          + Ecompl is set with complemented edges. + ] + + SideEffects [None] + + SeeAlso [DddmpReadCode()] + +******************************************************************************/ + +int +DddmpWriteCode ( + FILE *fp /* IN: file where to write the code */, + struct binary_dd_code code /* IN: the code to be written */ + ) +{ + unsigned char c; + int retValue; + + c = (code.Unused<<7)|(code.V<<5)|(code.T<<3)| + (code.Ecompl<<2)|(code.E); + + retValue = WriteByteBinary (fp, c); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Reads a 1 byte node code] + + Description [Reads a 1 byte node code. See DddmpWriteCode() + for code description.] + + SideEffects [None] + + SeeAlso [DddmpWriteCode()] + +******************************************************************************/ + +int +DddmpReadCode ( + FILE *fp /* IN: file where to read the code */, + struct binary_dd_code *pcode /* OUT: the read code */ + ) +{ + unsigned char c; + + if (ReadByteBinary (fp, &c) == EOF) { + return (0); + } + + pcode->Unused = c>>7; + pcode->V = (c>>5) & 3; + pcode->T = (c>>3) & 3; + pcode->Ecompl = (c>>2) & 1; + pcode->E = c & 3; + + return (1); +} + +/**Function******************************************************************** + + Synopsis [Writes a "packed integer"] + + Description [Writes an integer as a sequence of bytes (MSByte first). + For each byte 7 bits are used for data and one (LSBit) as link + with a further byte (LSB = 1 means one more byte). + ] + + SideEffects [None] + + SeeAlso [DddmpReadInt()] + +******************************************************************************/ + +int +DddmpWriteInt ( + FILE *fp /* IN: file where to write the integer */, + int id /* IN: integer to be written */ + ) +{ + char cvet[4]; + int i; + + for (i=0; i<4; i++) { + cvet[i] = (char)((id & 0x0000007f) << 1); + id >>= 7; + } + + for (i=3; (i>0) && (cvet[i] == 0); i--); + + for (; i>0; i--) { + cvet[i] |= (char)1; + if (WriteByteBinary (fp, cvet[i]) == EOF) + return (0); + } + + if (WriteByteBinary (fp, cvet[0]) == EOF) { + return (0); + } + + return (1); +} + + +/**Function******************************************************************** + + Synopsis [Reads a "packed integer"] + + Description [Reads an integer coded on a sequence of bytes. See + DddmpWriteInt() for format.] + + SideEffects [None] + + SeeAlso [DddmpWriteInt()] + +******************************************************************************/ + +int +DddmpReadInt ( + FILE *fp /* IN: file where to read the integer */, + int *pid /* OUT: the read integer */ + ) +{ + unsigned char c; + int i; + unsigned int id; + + id = 0; + for (i=0; i<4; i++) { + if (ReadByteBinary (fp, &c) == EOF) + return (0); + id = (id<<7) | (c>>1); + if ((c & 1) == 0) + break; + } + + /* Check for correct format: last char should + be found before i = 4 */ + assert(i<4); + + *pid = id; + + return (i+1); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a byte to file filtering , and ] + + Description [outputs a byte to file fp. Uses 0x00 as escape character + to filter , and . + This is done for compatibility between unix and dos/windows systems. + ] + + SideEffects [None] + + SeeAlso [ReadByteBinary()] + +******************************************************************************/ + +static int +WriteByteBinary ( + FILE *fp /* IN: file where to write the byte */, + unsigned char c /* IN: the byte to be written */ + ) +{ + unsigned char BinaryEscape; + + switch (c) { + + case 0x00: /* Escape */ + BinaryEscape = 0x00; + if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) + return (0); + c = 0x00; + break; + case 0x0a: /* */ + BinaryEscape = 0x00; + if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) + return (0); + c = 0x01; + break; + case 0x0d: /* */ + BinaryEscape = 0x00; + if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) + return (0); + c = 0x02; + break; + case 0x1a: /* */ + BinaryEscape = 0x00; + if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) + return (0); + c = 0x03; + break; + } + if (fwrite (&c, sizeof(char), 1, fp) != sizeof(char)) + return (0); + + return (1); +} + +/**Function******************************************************************** + + Synopsis [Reads a byte from file with escaped , and ] + + Description [inputs a byte to file fp. 0x00 has been used as escape character + to filter , and . This is done for + compatibility between unix and dos/windows systems. + ] + + SideEffects [None] + + SeeAlso [WriteByteBinary()] + +******************************************************************************/ + +static int +ReadByteBinary ( + FILE *fp /* IN: file where to read the byte */, + unsigned char *cp /* OUT: the read byte */ + ) +{ + + if (fread (cp, sizeof(char), 1, fp) != sizeof(char)) { + return (0); + } + + if (*cp == 0x00) { /* Escape */ + if (fread (cp, sizeof(char), 1, fp) != sizeof(char)) { + return (0); + } + + switch (*cp) { + + case 0x00: /* Escape */ + break; + case 0x01: /* */ + *cp = 0x0a; + break; + case 0x02: /* */ + *cp = 0x0d; + break; + case 0x03: /* */ + *cp = 0x1a; + break; + } + } + + return (1); +} + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpConvert.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpConvert.c new file mode 100644 index 000000000..c24292e8c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpConvert.c @@ -0,0 +1,180 @@ +/**CFile********************************************************************** + + FileName [dddmpConvert.c] + + PackageName [dddmp] + + Synopsis [Conversion between ASCII and binary formats] + + Description [Conversion between ASCII and binary formats is presently + supported by loading a BDD in the source format and storing it + in the target one. We plan to introduce ad hoc procedures + avoiding explicit BDD node generation. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Converts from ASCII to binary format] + + Description [Converts from ASCII to binary format. A BDD array is loaded and + and stored to the target file.] + + SideEffects [None] + + SeeAlso [Dddmp_Bin2Text()] + +******************************************************************************/ + +int +Dddmp_Text2Bin ( + char *filein /* IN: name of ASCII file */, + char *fileout /* IN: name of binary file */ + ) +{ + DdManager *ddMgr; /* pointer to DD manager */ + DdNode **roots; /* array of BDD roots to be loaded */ + int nRoots; /* number of BDD roots */ + int retValue; + + ddMgr = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); + if (ddMgr == NULL) { + return (0); + } + + nRoots = Dddmp_cuddBddArrayLoad(ddMgr,DDDMP_ROOT_MATCHLIST,NULL, + DDDMP_VAR_MATCHIDS,NULL,NULL,NULL, + DDDMP_MODE_TEXT,filein,NULL,&roots); + + Dddmp_CheckAndGotoLabel (nRoots<=0, + "Negative Number of Roots.", failure); + + retValue = Dddmp_cuddBddArrayStore (ddMgr,NULL,nRoots,roots,NULL, + NULL,NULL,DDDMP_MODE_BINARY,DDDMP_VARIDS,fileout,NULL); + + Dddmp_CheckAndGotoLabel (retValue<=0, + "Error code returned.", failure); + + Cudd_Quit(ddMgr); + return (1); + + failure: + printf("error converting BDD format\n"); + Cudd_Quit(ddMgr); + return (0); +} + +/**Function******************************************************************** + + Synopsis [Converts from binary to ASCII format] + + Description [Converts from binary to ASCII format. A BDD array is loaded and + and stored to the target file.] + + SideEffects [None] + + SeeAlso [Dddmp_Text2Bin()] + +******************************************************************************/ + +int +Dddmp_Bin2Text ( + char *filein /* IN: name of binary file */, + char *fileout /* IN: name of ASCII file */ + ) +{ + DdManager *ddMgr; /* pointer to DD manager */ + DdNode **roots; /* array of BDD roots to be loaded */ + int nRoots; /* number of BDD roots */ + int retValue; + + ddMgr = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); + if (ddMgr == NULL) { + return (0); + } + + nRoots = Dddmp_cuddBddArrayLoad(ddMgr,DDDMP_ROOT_MATCHLIST,NULL, + DDDMP_VAR_MATCHIDS,NULL,NULL,NULL, + DDDMP_MODE_BINARY,filein,NULL,&roots); + + Dddmp_CheckAndGotoLabel (nRoots<=0, + "Negative Number of Roots.", failure); + + retValue = Dddmp_cuddBddArrayStore (ddMgr,NULL,nRoots,roots,NULL, + NULL,NULL,DDDMP_MODE_TEXT,DDDMP_VARIDS,fileout,NULL); + + Dddmp_CheckAndGotoLabel (retValue<=0, + "Error code returned.", failure); + + Cudd_Quit(ddMgr); + return (1); + + failure: + printf("error converting BDD format\n"); + Cudd_Quit(ddMgr); + return (0); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDbg.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDbg.c new file mode 100644 index 000000000..88304f5af --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDbg.c @@ -0,0 +1,166 @@ +/**CFile********************************************************************** + + FileName [dddmpDbg.c] + + PackageName [dddmp] + + Synopsis [Functions to display BDD files] + + Description [Functions to display BDD files in binary format + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Display a binary dump file in a text file] + + Description [Display a binary dump file in a text file] + + SideEffects [None] + + SeeAlso [Dddmp_cuddBddStore , Dddmp_cuddBddLoad ] + +******************************************************************************/ + +int +Dddmp_cuddBddDisplayBinary( + char *fileIn /* IN: name of binary file */, + char *fileOut /* IN: name of text file */ + ) +{ + FILE *fp, *fpo; + int id, size; + struct binary_dd_code code; + char buf[1000]; + int nnodes, i; + + fp = fopen (fileIn, "rb"); + if (fp == 0) { + return (0); + } + + fpo = fopen (fileOut, "w"); + if (fpo == 0) { + return (0); + } + + while (fgets(buf, 999,fp)!=NULL) { + fprintf (fpo, "%s", buf); + if (strncmp(buf, ".nnodes", 7) == 0) { + sscanf (buf, "%*s %d", &nnodes); + } + if (strncmp(buf, ".rootids", 8) == 0) { + break; + } + } + + for (i=1; i<=nnodes; i++) { + if (feof(fp)) { + return (0); + } + if (DddmpReadCode(fp,&code) == 0) { + return (0); + } + fprintf (fpo, "c : v %d | T %d | E %d\n", + (int)code.V, (int)code.T, + (code.Ecompl ? -(int)(code.E) : (int)(code.E))); + if (code.V == DDDMP_TERMINAL) { + continue; + } + if (code.V <= DDDMP_RELATIVE_ID) { + size = DddmpReadInt(fp,&id); + if (size == 0) { + return (0); + } + fprintf(fpo, "v(%d): %d\n", size, id); + } + if (code.T <= DDDMP_RELATIVE_ID) { + size = DddmpReadInt(fp,&id); + if (size == 0) { + return (0); + } + fprintf(fpo, "T(%d): %d\n", size, id); + } + if (code.E <= DDDMP_RELATIVE_ID) { + size = DddmpReadInt(fp,&id); + if (size == 0) { + return (0); + } + fprintf(fpo, "E(%d): %d\n", size, id); + } + + } + + fgets(buf, 999,fp); + if (strncmp(buf, ".end", 4) != 0) { + return (0); + } + + fprintf(fpo, ".end"); + + fclose(fp); + fclose(fpo); + + return (1); +} + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeBdd.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeBdd.c new file mode 100644 index 000000000..443ef5dbf --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeBdd.c @@ -0,0 +1,455 @@ +/**CFile********************************************************************** + + FileName [dddmpDdNodeBdd.c] + + PackageName [dddmp] + + Synopsis [Functions to handle BDD node infos and numbering] + + Description [Functions to handle BDD node infos and numbering. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NumberNodeRecur(DdNode *f, int id); +static void RemoveFromUniqueRecur(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecur(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and number them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodes()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecur(), NumberNodeRecur(), + DddmpUnnumberDdNodes()] + +******************************************************************************/ + +int +DddmpNumberDdNodes ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int n /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int id=0, i; + + for (i=0; inext = (struct DdNode *)((ptruint)((id)<<1)); + } + + return; +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndex(), DddmpSetVisited (), DddmpVisited ()] + +******************************************************************************/ + +int +DddmpReadNodeIndex ( + DdNode *f /* IN: BDD node */ + ) +{ + +#if 0 + if (1 || !Cudd_IsConstant (f)) { +#else + if (!Cudd_IsConstant (f)) { +#endif + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisited (), DddmpClearVisited ()] + +******************************************************************************/ + +int +DddmpVisited ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisited (), DddmpClearVisited ()] + +******************************************************************************/ + +void +DddmpSetVisited ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisited (), DddmpSetVisited ()] + +******************************************************************************/ + +void +DddmpClearVisited ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecur( + DdNode *f /* IN: root of the BDD to be numbered */, + int id /* IN/OUT: index to be assigned to the node */ + ) +{ + f = Cudd_Regular(f); + + if (!DddmpVisited (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecur (cuddT (f), id); + id = NumberNodeRecur (cuddE (f), id); + } + + DddmpWriteNodeIndex (f, ++id); + DddmpClearVisited (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecur()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisited (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecur (ddMgr, cuddT (f)); + RemoveFromUniqueRecur (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisited (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursively)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUnique()] + +******************************************************************************/ + +static void +RestoreInUniqueRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + DddmpClearVisited (f); + /*f->next = NULL;*/ + return; + } + + RestoreInUniqueRecur (ddMgr, cuddT (f)); + RestoreInUniqueRecur (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + f->next = *previousP; + *previousP = f; + + return; +} + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeCnf.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeCnf.c new file mode 100644 index 000000000..421d920e9 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeCnf.c @@ -0,0 +1,944 @@ +/**CFile********************************************************************** + + FileName [dddmpDdNodeCnf.c] + + PackageName [dddmp] + + Synopsis [Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs] + + Description [Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMP_DEBUG_CNF 0 + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpWriteNodeIndexCnf(DdNode *f, int *cnfIds, int id); +static int DddmpReadNodeIndexCnf(DdNode *f); +static int DddmpClearVisitedCnfRecur(DdNode *f); +static int DddmpVisitedCnf(DdNode *f); +static void DddmpSetVisitedCnf(DdNode *f); +static void DddmpClearVisitedCnf(DdNode *f); +static int NumberNodeRecurCnf(DdNode *f, int *cnfIds, int id); +static void DddmpDdNodesCheckIncomingAndScanPath(DdNode *f, int pathLengthCurrent, int edgeInTh, int pathLengthTh); +static int DddmpDdNodesNumberEdgesRecur(DdNode *f, int *cnfIds, int id); +static int DddmpDdNodesResetCountRecur(DdNode *f); +static int DddmpDdNodesCountEdgesRecur(DdNode *f); +static void RemoveFromUniqueRecurCnf(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecurCnf(DdManager *ddMgr, DdNode *f); +static int DddmpPrintBddAndNextRecur(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and numbers them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodesCnf()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecurCnf(), NumberNodeRecurCnf(), + DddmpUnnumberDdNodesCnf()] + +******************************************************************************/ + +int +DddmpNumberDdNodesCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int rootN /* IN: number of BDD roots in the array of BDDs */, + int *cnfIds /* OUT: CNF identifiers for variables */, + int id /* OUT: number of Temporary Variables Introduced */ + ) +{ + int i; + + for (i=0; i BDDs After Count Reset:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*----------------------- Count Incoming Edges ----------------------------*/ + + for (i=0; i BDDs After Count Recur:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*------------------------- Count Path Length ----------------------------*/ + + for (i=0; i BDDs After Check Incoming And Scan Path:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*-------------------- Number Nodes and Set Visited -----------------------*/ + + for (i=0; i BDDs After Count Edges Recur:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*---------------------------- Clear Visited ------------------------------*/ + +#if DDDMP_DEBUG_CNF + for (i=0; i BDDs After All Numbering Process:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif +#endif + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Restores nodes in unique table, loosing numbering] + + Description [Node indexes are no more needed. Nodes are re-linked in the + unique table. + ] + + SideEffects [None] + + SeeAlso [DddmpNumberDdNode()] + +******************************************************************************/ + +void +DddmpUnnumberDdNodesCnf( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int rootN /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int i; + + for (i=0; i Bdd %d:\n", i); + fflush (stdout); + DddmpPrintBddAndNextRecur (ddMgr, f[i]); + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Write index to node] + + Description [The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. + ] + + SideEffects [None] + + SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf () + ] + +******************************************************************************/ + +int +DddmpWriteNodeIndexCnfBis ( + DdNode *f /* IN: BDD node */, + int id /* IN: index to be written */ + ) +{ + if (!Cudd_IsConstant (f)) { + f->next = (struct DdNode *)((ptruint)((id)<<1)); + } + + return (DDDMP_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Write index to node] + + Description [The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. The index corresponds to + the BDD node variable if both the node's children are a + constant node, otherwise a new CNF variable is used. + ] + + SideEffects [None] + + SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf ()] + +*****************************************************************************/ + +static int +DddmpWriteNodeIndexCnf ( + DdNode *f /* IN: BDD node */, + int *cnfIds /* IN: possible source for the index to be written */, + int id /* IN: possible source for the index to be written */ + ) +{ + if (!Cudd_IsConstant (f)) { + if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) { + /* If Variable SET ID as Variable ID */ + f->next = (struct DdNode *)((ptruint)((cnfIds[f->index])<<1)); + } else { + f->next = (struct DdNode *)((ptruint)((id)<<1)); + id++; + } + } + + return(id); +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf ()] + +******************************************************************************/ + +static int +DddmpReadNodeIndexCnf ( + DdNode *f /* IN: BDD node */ + ) +{ + if (!Cudd_IsConstant (f)) { + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Mark ALL nodes as not visited] + + Description [Mark ALL nodes as not visited (it recurs on the node children)] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()] + +******************************************************************************/ + +static int +DddmpClearVisitedCnfRecur ( + DdNode *f /* IN: root of the BDD to be marked */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (cuddIsConstant (f)) { + return (DDDMP_SUCCESS); + } + + if (!DddmpVisitedCnf (f)) { + return (DDDMP_SUCCESS); + } + + retValue = DddmpClearVisitedCnfRecur (cuddT (f)); + retValue = DddmpClearVisitedCnfRecur (cuddE (f)); + + DddmpClearVisitedCnf (f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisitedCnf (), DddmpClearVisitedCnf ()] + +******************************************************************************/ + +static int +DddmpVisitedCnf ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpClearVisitedCnf ()] + +******************************************************************************/ + +static void +DddmpSetVisitedCnf ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()] + +******************************************************************************/ + +static void +DddmpClearVisitedCnf ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecurCnf( + DdNode *f /* IN: root of the BDD to be numbered */, + int *cnfIds /* IN: possible source for numbering */, + int id /* IN/OUT: possible source for numbering */ + ) +{ + f = Cudd_Regular(f); + + if (!DddmpVisitedCnf (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecurCnf (cuddT (f), cnfIds, id); + id = NumberNodeRecurCnf (cuddE (f), cnfIds, id); + } + + id = DddmpWriteNodeIndexCnf (f, cnfIds, id); + DddmpClearVisitedCnf (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with the right polarity. + The node is assigned to a new CNF variable only if it is a "shared" + node (i.e. the number of its incoming edges is greater than 1). + ] + + SideEffects ["visited" flags are set.] + + SeeAlso [] + +******************************************************************************/ + +static void +DddmpDdNodesCheckIncomingAndScanPath ( + DdNode *f /* IN: BDD node to be numbered */, + int pathLengthCurrent /* IN: Current Path Length */, + int edgeInTh /* IN: Max # In-Edges, after a Insert Cut Point */, + int pathLengthTh /* IN: Max Path Length (after, Insert a Cut Point) */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (DddmpVisitedCnf (f)) { + return; + } + + if (cuddIsConstant (f)) { + return; + } + + pathLengthCurrent++; + retValue = DddmpReadNodeIndexCnf (f); + + if ( ((edgeInTh >= 0) && (retValue > edgeInTh)) || + ((pathLengthTh >= 0) && (pathLengthCurrent > pathLengthTh)) + ) { + DddmpWriteNodeIndexCnfBis (f, 1); + pathLengthCurrent = 0; + } else { + DddmpWriteNodeIndexCnfBis (f, 0); + } + + DddmpDdNodesCheckIncomingAndScanPath (cuddT (f), pathLengthCurrent, + edgeInTh, pathLengthTh); + DddmpDdNodesCheckIncomingAndScanPath (cuddE (f), pathLengthCurrent, + edgeInTh, pathLengthTh); + + DddmpSetVisitedCnf (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with the inverse polarity. + Numbering follows the subsequent strategy: + * if the index = 0 it remains so + * if the index >= 1 it gets enumerated. + This implies that the node is assigned to a new CNF variable only if + it is not a terminal node otherwise it is assigned the index of + the BDD variable. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesNumberEdgesRecur ( + DdNode *f /* IN: BDD node to be numbered */, + int *cnfIds /* IN: possible source for numbering */, + int id /* IN/OUT: possible source for numbering */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (!DddmpVisitedCnf (f)) { + return (id); + } + + if (cuddIsConstant (f)) { + return (id); + } + + id = DddmpDdNodesNumberEdgesRecur (cuddT (f), cnfIds, id); + id = DddmpDdNodesNumberEdgesRecur (cuddE (f), cnfIds, id); + + retValue = DddmpReadNodeIndexCnf (f); + if (retValue >= 1) { + id = DddmpWriteNodeIndexCnf (f, cnfIds, id); + } else { + DddmpWriteNodeIndexCnfBis (f, 0); + } + + DddmpClearVisitedCnf (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Resets counter and visited flag for ALL nodes of a BDD] + + Description [Resets counter and visited flag for ALL nodes of a BDD (it + recurs on the node children). The index field of the node is + used as counter. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesResetCountRecur ( + DdNode *f /* IN: root of the BDD whose counters are reset */ + ) +{ + int retValue; + + f = Cudd_Regular (f); + + if (!DddmpVisitedCnf (f)) { + return (DDDMP_SUCCESS); + } + + if (!cuddIsConstant (f)) { + retValue = DddmpDdNodesResetCountRecur (cuddT (f)); + retValue = DddmpDdNodesResetCountRecur (cuddE (f)); + } + + DddmpWriteNodeIndexCnfBis (f, 0); + DddmpClearVisitedCnf (f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Counts the number of incoming edges for each node of a BDD] + + Description [Counts (recursively) the number of incoming edges for each + node of a BDD. This number is stored in the index field. + ] + + SideEffects ["visited" flags remain untouched.] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesCountEdgesRecur ( + DdNode *f /* IN: root of the BDD */ + ) +{ + int indexValue, retValue; + + f = Cudd_Regular (f); + + if (cuddIsConstant (f)) { + return (DDDMP_SUCCESS); + } + + if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) { + return (DDDMP_SUCCESS); + } + + indexValue = DddmpReadNodeIndexCnf (f); + + /* IF (first time) THEN recur */ + if (indexValue == 0) { + retValue = DddmpDdNodesCountEdgesRecur (cuddT (f)); + retValue = DddmpDdNodesCountEdgesRecur (cuddE (f)); + } + + /* Increment Incoming-Edge Count Flag */ + indexValue++; + DddmpWriteNodeIndexCnfBis (f, indexValue); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on son nodes. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecurCnf()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecurCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisitedCnf (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecurCnf (ddMgr, cuddT (f)); + RemoveFromUniqueRecurCnf (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisitedCnf (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursive)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUnique()] + +******************************************************************************/ + +static void +RestoreInUniqueRecurCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + DddmpClearVisitedCnf (f); + /*f->next = NULL;*/ + return; + } + + RestoreInUniqueRecurCnf (ddMgr, cuddT (f)); + RestoreInUniqueRecurCnf (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + f->next = *previousP; + *previousP = f; + + return; +} + +/**Function******************************************************************** + + Synopsis [Prints debug info] + + Description [Prints debug info for a BDD on the screen. It recurs on + node's children. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpPrintBddAndNextRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be displayed */ + ) +{ + int retValue; + DdNode *fPtr, *tPtr, *ePtr; + + fPtr = Cudd_Regular (f); + + if (Cudd_IsComplement (f)) { + fprintf (stdout, "sign=- ptr=%ld ", ((long int) fPtr)); + } else { + fprintf (stdout, "sign=+ ptr=%ld ", ((long int) fPtr)); + } + + if (cuddIsConstant (fPtr)) { + fprintf (stdout, "one\n"); + fflush (stdout); + return (DDDMP_SUCCESS); + } + + fprintf (stdout, + "thenPtr=%ld elsePtr=%ld BddId=%d CnfId=%d Visited=%d\n", + ((long int) cuddT (fPtr)), ((long int) cuddE (fPtr)), + fPtr->index, DddmpReadNodeIndexCnf (fPtr), + DddmpVisitedCnf (fPtr)); + + tPtr = cuddT (fPtr); + ePtr = cuddE (fPtr); + if (Cudd_IsComplement (f)) { + tPtr = Cudd_Not (tPtr); + ePtr = Cudd_Not (ePtr); + } + + retValue = DddmpPrintBddAndNextRecur (ddMgr, tPtr); + retValue = DddmpPrintBddAndNextRecur (ddMgr, ePtr); + + return (DDDMP_SUCCESS); +} + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpInt.h b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpInt.h new file mode 100644 index 000000000..7d0f54dfc --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpInt.h @@ -0,0 +1,216 @@ +/**CHeaderFile***************************************************************** + + FileName [dddmpInt.h] + + PackageName [dddmp] + + Synopsis [Low level functions to read in and write out bdds to file] + + Description [A set of internal low-level routines of the dddmp package + doing: +
            +
          • read and write of node codes in binary mode, +
          • read and write of integers in binary mode, +
          • marking/unmarking nodes as visited, +
          • numbering nodes. +
          + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2002 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#ifndef _DDDMPINT +#define _DDDMPINT + +#include "dddmp.h" +#include "cuddInt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* constants for code fields */ +#define DDDMP_TERMINAL 0 +#define DDDMP_ABSOLUTE_ID 1 +#define DDDMP_RELATIVE_ID 2 +#define DDDMP_RELATIVE_1 3 + +#define DDDMP_MAXSTRLEN 500 + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + +/**Struct********************************************************************** + Synopsis [used in binary mode to store code info of a dd node] + Description [V , T , E store the mode used to represent variable, Then + and Else indexes. An index is either an absolute + ( DDDMP_ABSOLUTE_ID ), + a relative numbers ( DDDMP_RELATIVE_ID , DDDMP_RELATIVE_1 ) or + a terminal node ( DDDMP_TERMINAL ) . + Ecomp is used for the complemented edge attribute. + ] + SideEffect [none] + SeeAlso [DddmpWriteCode DddmpReadCode] +******************************************************************************/ + +struct binary_dd_code { + unsigned Unused : 1; + unsigned V : 2; + unsigned T : 2; + unsigned Ecompl : 1; + unsigned E : 2; +}; + +/**Struct********************************************************************* + + Synopsis [BDD file header] + + Description [Structure containing the BDD header file infos] + +******************************************************************************/ + +struct Dddmp_Hdr_s { + char *ver; + char mode; + Dddmp_DecompType ddType; + Dddmp_VarInfoType varinfo; + char *dd; + int nnodes; + int nVars; + int nsuppvars; + char **orderedVarNames; + char **suppVarNames; + int *ids; + int *permids; + int *auxids; + int *cnfids; + int nRoots; + int *rootids; + char **rootnames; + int nAddedCnfVar; + int nVarsCnf; + int nClausesCnf; +}; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Memory Allocation Macro for DDDMP] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#ifdef ALLOC +# define DDDMP_ALLOC(type, num) ALLOC(type,num) +#else +# define DDDMP_ALLOC(type, num) \ + ((type *) malloc(sizeof(type) * (num))) +#endif + +/**Macro*********************************************************************** + + Synopsis [Memory Free Macro for DDDMP] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#ifdef FREE +#define DDDMP_FREE(p) (FREE(p)) +#else +#define DDDMP_FREE(p) \ + ((p)!=NULL)?(free(p)):0) +#endif + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern int DddmpWriteCode(FILE *fp, struct binary_dd_code code); +extern int DddmpReadCode(FILE *fp, struct binary_dd_code *pcode); +extern int DddmpWriteInt(FILE *fp, int id); +extern int DddmpReadInt(FILE *fp, int *pid); +extern int DddmpNumberAddNodes(DdManager *ddMgr, DdNode **f, int n); +extern void DddmpUnnumberAddNodes(DdManager *ddMgr, DdNode **f, int n); +extern void DddmpWriteNodeIndexAdd(DdNode *f, int id); +extern int DddmpReadNodeIndexAdd(DdNode *f); +extern int DddmpVisitedAdd(DdNode *f); +extern void DddmpSetVisitedAdd(DdNode *f); +extern void DddmpClearVisitedAdd(DdNode *f); +extern int DddmpNumberBddNodes(DdManager *ddMgr, DdNode **f, int n); +extern void DddmpUnnumberBddNodes(DdManager *ddMgr, DdNode **f, int n); +extern void DddmpWriteNodeIndexBdd(DdNode *f, int id); +extern int DddmpReadNodeIndexBdd(DdNode *f); +extern int DddmpVisitedBdd(DdNode *f); +extern void DddmpSetVisitedBdd(DdNode *f); +extern void DddmpClearVisitedBdd(DdNode *f); +extern int DddmpNumberDdNodesCnf(DdManager *ddMgr, DdNode **f, int rootN, int *cnfIds, int id); +extern int DddmpDdNodesCountEdgesAndNumber(DdManager *ddMgr, DdNode **f, int rootN, int edgeInTh, int pathLengthTh, int *cnfIds, int id); +extern void DddmpUnnumberDdNodesCnf(DdManager *ddMgr, DdNode **f, int rootN); +extern int DddmpPrintBddAndNext(DdManager *ddMgr, DdNode **f, int rootN); +extern int DddmpWriteNodeIndexCnf(DdNode *f, int id); +extern int DddmpVisitedCnf(DdNode *f); +extern void DddmpSetVisitedCnf(DdNode *f); +extern int DddmpReadNodeIndexCnf(DdNode *f); +extern int DddmpCuddDdArrayStoreBdd(Dddmp_DecompType ddType, DdManager *ddMgr, char *ddname, int nRoots, DdNode **f, char **rootnames, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int DddmpCuddBddArrayStore(Dddmp_DecompType ddType, DdManager *ddMgr, char *ddname, int nRoots, DdNode **f, char **rootnames, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int QsortStrcmp(const void *ps1, const void *ps2); +extern int FindVarname(char *name, char **array, int n); +extern char * DddmpStrDup(char *str); +extern char ** DddmpStrArrayDup(char **array, int n); +extern char ** DddmpStrArrayRead(FILE *fp, int n); +extern int DddmpStrArrayWrite(FILE *fp, char **array, int n); +extern void DddmpStrArrayFree(char **array, int n); +extern int * DddmpIntArrayDup(int *array, int n); +extern int * DddmpIntArrayRead(FILE *fp, int n); +extern int DddmpIntArrayWrite(FILE *fp, int *array, int n); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoad.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoad.c new file mode 100644 index 000000000..27d9f0918 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoad.c @@ -0,0 +1,1486 @@ +/**CFile********************************************************************** + + FileName [dddmpLoad.c] + + PackageName [dddmp] + + Synopsis [Functions to read in bdds to file] + + Description [Functions to read in bdds to file. BDDs + are represended on file either in text or binary format under the + following rules. A file contains a forest of BDDs (a vector of + Boolean functions). BDD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to BDD + functions, followed by the list of nodes. BDD nodes are listed + according to their numbering, and in the present implementation + numbering follows a post-order strategy, in such a way that a node + is never listed before its Then/Else children. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define matchkeywd(str,key) (strncmp(str,key,strlen(key))==0) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpCuddDdArrayLoad(Dddmp_DecompType ddType, DdManager *ddMgr, Dddmp_RootMatchType rootMatchMode, char **rootmatchnames, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***pproots); +static Dddmp_Hdr_t * DddmpBddReadHeader(char *file, FILE *fp); +static void DddmpFreeHeader(Dddmp_Hdr_t *Hdr); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads a dump file representing the argument BDD.] + + Description [Reads a dump file representing the argument BDD. + Dddmp_cuddBddArrayLoad is used through a dummy array (see this + function's description for more details). + Mode, the requested input file format, is checked against + the file format. + The loaded BDDs is referenced before returning it. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddStore, Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +DdNode * +Dddmp_cuddBddLoad ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names - by IDs */, + int *varmatchauxids /* IN: array of variable auxids - by IDs */, + int *varcomposeids /* IN: array of new ids accessed - by IDs */, + int mode /* IN: requested input file format */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + DdNode *f , **tmpArray; + int i, nRoots; + + nRoots = Dddmp_cuddBddArrayLoad(ddMgr,DDDMP_ROOT_MATCHLIST,NULL, + varMatchMode,varmatchnames,varmatchauxids,varcomposeids, + mode,file,fp,&tmpArray); + + if (nRoots == 0) { + return (NULL); + } else { + f = tmpArray[0]; + if (nRoots > 1) { + fprintf (stderr, + "Warning: %d BDD roots found in file. Only first retrieved.\n", + nRoots); + for (i=1; i +
        • varMatchMode=DDDMP_VAR_MATCHIDS

          + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

        • varMatchMode=DDDMP_VAR_MATCHPERMIDS

          + is used to allow variable match according to the position in the + ordering. + +

        • varMatchMode=DDDMP_VAR_MATCHNAMES

          + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

        • varMatchMode=DDDMP_VAR_MATCHIDS

          + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

        • varMatchMode=DDDMP_VAR_COMPOSEIDS

          + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. + + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. + + All the loaded BDDs are referenced before returning them. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddArrayStore] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayLoad ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_RootMatchType rootMatchMode /* IN: storing mode selector */, + char **rootmatchnames /* IN: sorted names for loaded roots */, + Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by ids */, + int *varmatchauxids /* IN: array of variable auxids, by ids */, + int *varcomposeids /* IN: array of new ids, by ids */, + int mode /* IN: requested input file format */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***pproots /* OUT: array of returned BDD roots */ + ) +{ + int retValue; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Load.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Load.\n"); + fflush (stderr); + } + } +#endif +#endif + + retValue = DddmpCuddDdArrayLoad (DDDMP_BDD, ddMgr, rootMatchMode, + rootmatchnames, varMatchMode, varmatchnames, varmatchauxids, + varcomposeids, mode, file, fp, pproots); + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Load.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Load.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Reads a dump file representing the argument ADD.] + + Description [Reads a dump file representing the argument ADD. + Dddmp_cuddAddArrayLoad is used through a dummy array. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddAddStore, Dddmp_cuddAddArrayLoad] + +******************************************************************************/ + +DdNode * +Dddmp_cuddAddLoad ( + DdManager *ddMgr /* IN: Manager */, + Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names by IDs */, + int *varmatchauxids /* IN: array of variable auxids by IDs */, + int *varcomposeids /* IN: array of new ids by IDs */, + int mode /* IN: requested input file format */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + DdNode *f , **tmpArray; + int i, nRoots; + + nRoots = Dddmp_cuddAddArrayLoad (ddMgr, DDDMP_ROOT_MATCHLIST,NULL, + varMatchMode, varmatchnames, varmatchauxids, varcomposeids, + mode, file, fp, &tmpArray); + + if (nRoots == 0) { + return (NULL); + } else { + f = tmpArray[0]; + if (nRoots > 1) { + fprintf (stderr, + "Warning: %d BDD roots found in file. Only first retrieved.\n", + nRoots); + for (i=1; innodes==0, "Zero number of nodes.", + failure); + + /* + * Type, number of variables (tot and support) + */ + + *ddType = Hdr->ddType; + *nVars = Hdr->nVars; + *nsuppvars = Hdr->nsuppvars; + + /* + * Support Varnames + */ + + if (Hdr->suppVarNames != NULL) { + *suppVarNames = DDDMP_ALLOC (char *, *nsuppvars); + Dddmp_CheckAndGotoLabel (*suppVarNames==NULL, + "Error allocating memory.", failure); + + for (i=0; i<*nsuppvars; i++) { + (*suppVarNames)[i] = DDDMP_ALLOC (char, + (strlen (Hdr->suppVarNames[i]) + 1)); + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + strcpy ((*suppVarNames)[i], Hdr->suppVarNames[i]); + } + } else { + *suppVarNames = NULL; + } + + /* + * Ordered Varnames + */ + + if (Hdr->orderedVarNames != NULL) { + *orderedVarNames = DDDMP_ALLOC (char *, *nVars); + Dddmp_CheckAndGotoLabel (*orderedVarNames==NULL, + "Error allocating memory.", failure); + + for (i=0; i<*nVars; i++) { + (*orderedVarNames)[i] = DDDMP_ALLOC (char, + (strlen (Hdr->orderedVarNames[i]) + 1)); + Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + strcpy ((*orderedVarNames)[i], Hdr->orderedVarNames[i]); + } + } else { + *orderedVarNames = NULL; + } + + /* + * Variable Ids + */ + + if (Hdr->ids != NULL) { + tmpVarIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarIds==NULL, "Error allocating memory.", + failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarIds[i] = Hdr->ids[i]; + } + + *varIds = tmpVarIds; + } else { + *varIds = NULL; + } + + /* + * Variable Compose Ids + */ + + if (Hdr->permids != NULL) { + tmpVarComposeIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarComposeIds==NULL, + "Error allocating memory.", failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarComposeIds[i] = Hdr->permids[i]; + } + + *varComposeIds = tmpVarComposeIds; + } else { + *varComposeIds = NULL; + } + + /* + * Variable Auxiliary Ids + */ + + if (Hdr->auxids != NULL) { + tmpVarAuxIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarAuxIds==NULL, + "Error allocating memory.", failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarAuxIds[i] = Hdr->auxids[i]; + } + + *varAuxIds = tmpVarAuxIds; + } else { + *varAuxIds = NULL; + } + + /* + * Number of roots + */ + + *nRoots = Hdr->nRoots; + + /* + * Free and Return + */ + + if (fileToClose == 1) { + fclose (fp); + } + + DddmpFreeHeader(Hdr); + + return (DDDMP_SUCCESS); + + failure: + return (DDDMP_FAILURE); +} + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads a dump file representing the argument BDDs.] + + Description [Reads a dump file representing the argument BDDs. The header is + common to both text and binary mode. The node list is either + in text or binary format. A dynamic vector of DD pointers + is allocated to support conversion from DD indexes to pointers. + Several criteria are supported for variable match between file + and dd manager. Several changes/permutations/compositions are allowed + for variables while loading DDs. Variable of the dd manager are allowed + to match with variables on file on ids, permids, varnames, + varauxids; also direct composition between ids and + composeids is supported. More in detail: +

            +
          1. varMatchMode=DDDMP_VAR_MATCHIDS

            + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

          2. varMatchMode=DDDMP_VAR_MATCHPERMIDS

            + is used to allow variable match according to the position in the ordering. + +

          3. varMatchMode=DDDMP_VAR_MATCHNAMES

            + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

          4. varMatchMode=DDDMP_VAR_MATCHIDS

            + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

          5. varMatchMode=DDDMP_VAR_COMPOSEIDS

            + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. +

          + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddArrayStore] + +******************************************************************************/ + +static int +DddmpCuddDdArrayLoad ( + Dddmp_DecompType ddType /* IN: Selects decomp type */, + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_RootMatchType rootMatchMode /* IN: storing mode selector */, + char **rootmatchnames /* IN: sorted names for loaded roots */, + Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by ids */, + int *varmatchauxids /* IN: array of variable auxids, by ids */, + int *varcomposeids /* IN: array of new ids, by ids */, + int mode /* IN: requested input file format */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***pproots /* OUT: array BDD roots (by reference) */ + ) +{ + Dddmp_Hdr_t *Hdr = NULL; + DdNode *f = NULL; + DdNode *T = NULL; + DdNode *E = NULL; + struct binary_dd_code code; + char buf[DDDMP_MAXSTRLEN]; + int retValue, id, size, maxv; + int i, j, k, maxaux, var, vT, vE, idT, idE; + double addConstant; + int *permsupport = NULL; + int *convertids = NULL; + int *invconvertids = NULL; + int *invauxids = NULL; + char **sortedvarnames = NULL; + int nddvars, nRoots; + DdNode **pnodes = NULL; + unsigned char *pvars1byte = NULL; + unsigned short *pvars2byte = NULL; + DdNode **proots = NULL; + int fileToClose = 0; + + *pproots = NULL; + + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + nddvars = ddMgr->size; + + Hdr = DddmpBddReadHeader (NULL, fp); + + Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.", + failure); + + nRoots = Hdr->nRoots; + + if (Hdr->ddType != ddType) { + (void) fprintf (stderr, "DdLoad Error: ddType mismatch\n"); + + if (Hdr->ddType == DDDMP_BDD) + (void) fprintf (stderr, "BDD found\n"); + if (Hdr->ddType == DDDMP_ADD) + (void) fprintf (stderr, "ADD found\n"); + if (ddType == DDDMP_BDD) + (void) fprintf (stderr, "when loading a BDD\n"); + if (ddType == DDDMP_ADD) + (void) fprintf (stderr, "when loading an ADD\n"); + + fflush (stderr); + goto failure; + } + + if (Hdr->mode != mode) { + Dddmp_CheckAndGotoLabel (mode!=DDDMP_MODE_DEFAULT, + "Mode Mismatch.", failure); + mode = Hdr->mode; + } + + /* + * For each variable in the support + * compute the relative position in the ordering + * (within the support only) + */ + + permsupport = DDDMP_ALLOC (int, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (permsupport==NULL, "Error allocating memory.", + failure); + for (i=0,k=0; i < Hdr->nVars; i++) { + for (j=0; j < Hdr->nsuppvars; j++) { + if (Hdr->permids[j] == i) { + permsupport[j] = k++; + } + } + } + Dddmp_Assert (k==Hdr->nsuppvars, "k==Hdr->nsuppvars"); + + if (Hdr->suppVarNames != NULL) { + /* + * Varnames are sorted for binary search + */ + + sortedvarnames = DDDMP_ALLOC(char *, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (sortedvarnames==NULL, "Error allocating memory.", + failure); + for (i=0; insuppvars; i++) { + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + sortedvarnames[i] = Hdr->suppVarNames[i]; + } + + qsort ((void *) sortedvarnames, Hdr->nsuppvars, + sizeof(char *), QsortStrcmp); + + } + + /* + * Convertids is the array used to convert variable ids from positional + * (shrinked) ids used within the DD file. + * Positions in the file are from 0 to nsuppvars-1. + */ + + convertids = DDDMP_ALLOC (int, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (convertids==NULL, "Error allocating memory.", + failure); + + again_matchmode: + switch (varMatchMode) { + case DDDMP_VAR_MATCHIDS: + for (i=0; insuppvars; i++) { + convertids[permsupport[i]] = Hdr->ids[i]; + } + break; + case DDDMP_VAR_MATCHPERMIDS: + for (i=0; insuppvars; i++) { + convertids[permsupport[i]] = Cudd_ReadInvPerm (ddMgr, + Hdr->permids[i]); + } + break; + case DDDMP_VAR_MATCHAUXIDS: + if (Hdr->auxids == NULL) { + (void) fprintf (stderr, + "DdLoad Error: variable auxids matching requested\n"); + (void) fprintf (stderr, "but .auxids not found in BDD file\n"); + (void) fprintf (stderr, "Matching IDs forced.\n"); + fflush (stderr); + varMatchMode = DDDMP_VAR_MATCHIDS; + goto again_matchmode; + } + /* find max auxid value to alloc invaux array */ + for (i=0,maxaux= -1; imaxaux) { + maxaux = varmatchauxids[i]; + } + } + /* generate invaux array */ + invauxids = DDDMP_ALLOC (int, maxaux+1); + Dddmp_CheckAndGotoLabel (invauxids==NULL, "Error allocating memory.", + failure); + + for (i=0; i<=maxaux; i++) { + invauxids[i] = -1; + } + + for (i=0; insuppvars; i++) { + invauxids[varmatchauxids[Hdr->ids[i]]] = Hdr->ids[i]; + } + + /* generate convertids array */ + for (i=0; insuppvars; i++) { + if ((Hdr->auxids[i]>maxaux) || (invauxids[Hdr->auxids[i]]<0)) { + (void) fprintf (stderr, + "DdLoad Error: auxid %d not found in DD manager.\n", + Hdr->auxids[i]); + (void) fprintf (stderr, "ID matching forced (%d).\n", i); + (void) fprintf (stderr, + "Beware of possible overlappings with other variables\n"); + fflush (stderr); + convertids[permsupport[i]] = i; + } else { + convertids[permsupport[i]] = invauxids[Hdr->auxids[i]]; + } + } + break; + case DDDMP_VAR_MATCHNAMES: + if (Hdr->suppVarNames == NULL) { + (void) fprintf (stderr, + "DdLoad Error: variable names matching requested\n"); + (void) fprintf (stderr, "but .suppvarnames not found in BDD file\n"); + (void) fprintf (stderr, "Matching IDs forced.\n"); + fflush (stderr); + varMatchMode = DDDMP_VAR_MATCHIDS; + goto again_matchmode; + } + + /* generate invaux array */ + invauxids = DDDMP_ALLOC (int, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (invauxids==NULL, "Error allocating memory.", + failure); + + for (i=0; insuppvars; i++) { + invauxids[i] = -1; + } + + for (i=0; insuppvars)) + >=0) { + Dddmp_Assert (jnsuppvars, "jnsuppvars"); + invauxids[j] = i; + } + } + /* generate convertids array */ + for (i=0; insuppvars; i++) { + Dddmp_Assert (Hdr->suppVarNames[i]!=NULL, + "Hdr->suppVarNames[i] != NULL"); + j=FindVarname(Hdr->suppVarNames[i],sortedvarnames,Hdr->nsuppvars); + Dddmp_Assert ((j>=0) && (jnsuppvars), + "(j>=0) && (jnsuppvars)"); + if (invauxids[j]<0) { + fprintf (stderr, + "DdLoad Error: varname %s not found in DD manager.", + Hdr->suppVarNames[i]); + fprintf (stderr, "ID matching forced (%d)\n", i); + fflush (stderr); + convertids[permsupport[i]]=i; + } else { + convertids[permsupport[i]] = invauxids[j]; + } + } + break; + case DDDMP_VAR_COMPOSEIDS: + for (i=0; insuppvars; i++) { + convertids[permsupport[i]] = varcomposeids[Hdr->ids[i]]; + } + break; + } + + maxv = (-1); + for (i=0; insuppvars; i++) { + if (convertids[i] > maxv) { + maxv = convertids[i]; + } + } + + invconvertids = DDDMP_ALLOC (int, maxv+1); + Dddmp_CheckAndGotoLabel (invconvertids==NULL, "Error allocating memory.", + failure); + + for (i=0; i<=maxv; i++) { + invconvertids[i]= -1; + } + + for (i=0; insuppvars; i++) { + invconvertids[convertids[i]] = i; + } + + pnodes = DDDMP_ALLOC(DdNode *,(Hdr->nnodes+1)); + Dddmp_CheckAndGotoLabel (pnodes==NULL, "Error allocating memory.", + failure); + + if (Hdr->nsuppvars < 256) { + pvars1byte = DDDMP_ALLOC(unsigned char,(Hdr->nnodes+1)); + Dddmp_CheckAndGotoLabel (pvars1byte==NULL, "Error allocating memory.", + failure); + } + else if (Hdr->nsuppvars < 0xffff) { + pvars2byte = DDDMP_ALLOC(unsigned short,(Hdr->nnodes+1)); + Dddmp_CheckAndGotoLabel (pvars2byte==NULL, "Error allocating memory.", + failure); + } else { + (void) fprintf (stderr, + "DdLoad Error: more than %d variables. Not supported.\n", 0xffff); + fflush (stderr); + goto failure; + } + + /*-------------- Deal With Nodes ... One Row File at a Time --------------*/ + + for (i=1; i<=Hdr->nnodes; i++) { + + Dddmp_CheckAndGotoLabel (feof(fp), + "Unexpected EOF While Reading DD Nodes.", failure); + + switch (mode) { + + /* + * Text FORMAT + */ + + case DDDMP_MODE_TEXT: + + switch (Hdr->varinfo) { + case DDDMP_VARIDS: + case DDDMP_VARPERMIDS: + case DDDMP_VARAUXIDS: + case DDDMP_VARNAMES: + retValue = fscanf(fp, "%d %*s %s %d %d\n", &id, buf, &idT, &idE); + Dddmp_CheckAndGotoLabel (retValue<4, + "Error Reading Nodes in Text Mode.", failure); + break; + case DDDMP_VARDEFAULT: + retValue = fscanf(fp, "%d %s %d %d\n", &id, buf, &idT, &idE); + Dddmp_CheckAndGotoLabel (retValue<4, + "Error Reading Nodes in Text Mode.", failure); + break; + } +#ifdef DDDMP_DEBUG + Dddmp_Assert (id==i, "id == i"); +#endif + if (idT==0 && idE==0) { + /* leaf node: a constant */ + if (strcmp(buf, "1") == 0) { + pnodes[i] = Cudd_ReadOne (ddMgr); + } else { + /* this is an ADD constant ! */ + if (strcmp(buf, "0") == 0) { + pnodes[i] = Cudd_ReadZero (ddMgr); + } else { + addConstant = atof(buf); + pnodes[i] = Cudd_addConst (ddMgr, + (CUDD_VALUE_TYPE) addConstant); + } + } + + /* StQ 11.02.2004: + Bug fixed --> Reference All Nodes for ADD */ + Cudd_Ref (pnodes[i]); + Dddmp_CheckAndGotoLabel (pnodes[i]==NULL, "NULL pnodes.", + failure); + continue; + } else { +#ifdef DDDMP_DEBUG + Dddmp_Assert (idT>0, "id > 0"); +#endif + var = atoi(buf); + T = pnodes[idT]; + if(idE<0) { + idE = -idE; + E = pnodes[idE]; + E = Cudd_Not(E); + } else { + E = pnodes[idE]; + } + } + + break; + + /* + * Binary FORMAT + */ + + case DDDMP_MODE_BINARY: + + Dddmp_CheckAndGotoLabel (DddmpReadCode(fp,&code) == 0, + "Error Reading witn ReadCode.", failure); + + switch (code.V) { + case DDDMP_TERMINAL: + /* only 1 terminal presently supported */ + pnodes[i] = Cudd_ReadOne (ddMgr); + continue; + break; + case DDDMP_RELATIVE_1: + break; + case DDDMP_RELATIVE_ID: + case DDDMP_ABSOLUTE_ID: + size = DddmpReadInt (fp, &var); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + break; + } + + switch (code.T) { + case DDDMP_TERMINAL: + idT = 1; + break; + case DDDMP_RELATIVE_1: + idT = i-1; + break; + case DDDMP_RELATIVE_ID: + size = DddmpReadInt (fp, &id); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + idT = i-id; + break; + case DDDMP_ABSOLUTE_ID: + size = DddmpReadInt (fp, &idT); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + break; + } + + switch (code.E) { + case DDDMP_TERMINAL: + idE = 1; + break; + case DDDMP_RELATIVE_1: + idE = i-1; + break; + case DDDMP_RELATIVE_ID: + size = DddmpReadInt (fp, &id); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + idE = i-id; + break; + case DDDMP_ABSOLUTE_ID: + size = DddmpReadInt (fp, &idE); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + break; + } + +#ifdef DDDMP_DEBUG + Dddmp_Assert (idTnsuppvars; + else { + if (pvars1byte != NULL) + vT = pvars1byte[idT]; + else if (pvars2byte != NULL) + vT = pvars2byte[idT]; + else + vT = invconvertids[T->index]; + } +#ifdef DDDMP_DEBUG + Dddmp_Assert (vT>0, "vT > 0"); + Dddmp_Assert (vT<=Hdr->nsuppvars, "vT <= Hdr->nsuppvars"); +#endif + +#ifdef DDDMP_DEBUG + Dddmp_Assert (idEnsuppvars; + else { + if (pvars1byte != NULL) + vE = pvars1byte[idE]; + else if (pvars2byte != NULL) + vE = pvars2byte[idE]; + else + vE = invconvertids[E->index]; + } +#ifdef DDDMP_DEBUG + Dddmp_Assert (vE>0, "vE > 0"); + Dddmp_Assert (vE<=Hdr->nsuppvars, "vE <= Hdr->nsuppvars"); +#endif + + switch (code.V) { + case DDDMP_TERMINAL: + case DDDMP_ABSOLUTE_ID: + break; + case DDDMP_RELATIVE_1: + var = (vTnsuppvars, "var < Hdr->nsuppvars"); +#endif + + break; + } + + if (pvars1byte != NULL) { + pvars1byte[i] = (unsigned char) var; + } else { + if (pvars2byte != NULL) { + pvars2byte[i] = (unsigned short) var; + } + } + + var = convertids[var]; + switch (ddType) { + case DDDMP_BDD: + pnodes[i] = Cudd_bddIte (ddMgr, Cudd_bddIthVar (ddMgr, var), + T, E); + break; + case DDDMP_ADD: + { + DdNode *tmp = Cudd_addIthVar (ddMgr, var); + Cudd_Ref (tmp); + pnodes[i] = Cudd_addIte (ddMgr, tmp, T, E); + Cudd_RecursiveDeref (ddMgr, tmp); + break; + } + case DDDMP_CNF: + case DDDMP_NONE: + Dddmp_Warning (1, "Wrong DD Type."); + break; + } + + cuddRef (pnodes[i]); + } + + /*------------------------ Deal With the File Tail -----------------------*/ + + fgets (buf, DDDMP_MAXSTRLEN-1,fp); + Dddmp_CheckAndGotoLabel (!matchkeywd(buf, ".end"), + "Error .end not found.", failure); + + /* Close File IFF Necessary */ + if (fileToClose) { + fclose (fp); + } + + /* BDD Roots */ + proots = DDDMP_ALLOC(DdNode *,nRoots); + Dddmp_CheckAndGotoLabel (proots==NULL, "Error allocating memory.", + failure); + + for(i=0; irootnames[j]) == 0) + break; + } + if (j>=nRoots) { + /* rootname not found */ + fprintf (stderr, "Warning: unable to match root name <%s>\n", + rootmatchnames[i]); + } + break; + case DDDMP_ROOT_MATCHLIST: + j = i; + break; + } + + id = Hdr->rootids[i]; + if (id==0) { + (void) fprintf (stderr, "DdLoad Warning: NULL root found in file\n"); + fflush (stderr); + f = NULL; + } else { + if (id<0) { + f = Cudd_Not(pnodes[-id]); + } else { + f = pnodes[id]; + } + } + proots[i] = f; + + cuddRef (f); + } /* end for i = 0..nRoots */ + + /* + * Decrease Reference for all Nodes + */ + + /* StQ 11.02.2004: + Bug fixed --> De-Reference All Nodes for ADD */ + for (i=1; i<=Hdr->nnodes; i++) { + f = pnodes[i]; + Cudd_RecursiveDeref (ddMgr, f); + } + + /* + * Free Memory: load_end label + */ + +load_end: + + DddmpFreeHeader(Hdr); + + DDDMP_FREE (pnodes); + DDDMP_FREE (pvars1byte); + DDDMP_FREE (pvars2byte); + + /* variable names are not freed because they were shared with varnames */ + DDDMP_FREE (sortedvarnames); + + DDDMP_FREE (permsupport); + DDDMP_FREE (convertids); + DDDMP_FREE (invconvertids); + DDDMP_FREE (invauxids); + + *pproots = proots; + return (nRoots); + + /* + * Failure Condition + */ + +failure: + + if (fileToClose) { + fclose (fp); + } + + nRoots = 0; /* return 0 on error ! */ + + DDDMP_FREE (proots); + + goto load_end; /* this is done to free memory */ +} + +/**Function******************************************************************** + + Synopsis [Reads a the header of a dump file representing the + argument BDDs. + ] + + Description [Reads the header of a dump file. Builds a Dddmp_Hdr_t struct + containing all infos in the header, for next manipulations. + ] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ + +static Dddmp_Hdr_t * +DddmpBddReadHeader ( + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + Dddmp_Hdr_t *Hdr = NULL; + char buf[DDDMP_MAXSTRLEN]; + int retValue, fileToClose = 0; + + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /* START HEADER */ + + Hdr = DDDMP_ALLOC (Dddmp_Hdr_t,1); + if (Hdr == NULL) { + return NULL; + } + Hdr->ver = NULL; + Hdr->mode = 0; + Hdr->ddType = DDDMP_BDD; + Hdr->varinfo = DDDMP_VARIDS; + Hdr->dd = NULL; + Hdr->nnodes = 0; + Hdr->nVars = 0; + Hdr->nsuppvars = 0; + Hdr->suppVarNames = NULL; + Hdr->orderedVarNames = NULL; + Hdr->ids = NULL; + Hdr->permids = NULL; + Hdr->auxids = NULL; + Hdr->cnfids = NULL; + Hdr->nRoots = 0; + Hdr->rootids = NULL; + Hdr->rootnames = NULL; + Hdr->nAddedCnfVar = 0; + Hdr->nVarsCnf = 0; + Hdr->nClausesCnf = 0; + + while (fscanf(fp, "%s", buf)!=EOF) { + + /* comment */ + if (buf[0] == '#') { + fgets(buf,DDDMP_MAXSTRLEN,fp); + continue; + } + + Dddmp_CheckAndGotoLabel (buf[0] != '.', + "Error; line must begin with '.' or '#'.", + failure); + + if (matchkeywd(buf, ".ver")) { + /* this not checked so far: only read */ + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading from file.", + failure); + + Hdr->ver=DddmpStrDup(buf); + Dddmp_CheckAndGotoLabel (Hdr->ver==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".add")) { + Hdr->ddType = DDDMP_ADD; + continue; + } + + if (matchkeywd(buf, ".bdd")) { + Hdr->ddType = DDDMP_BDD; + continue; + } + + if (matchkeywd(buf, ".mode")) { + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading to file.", + failure); + + Hdr->mode = buf[0]; + continue; + } + + if (matchkeywd(buf, ".varinfo")) { + int readMe; + retValue = fscanf (fp, "%d", &readMe); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + Hdr->varinfo = (Dddmp_VarInfoType) readMe; + + continue; + } + + if (matchkeywd(buf, ".dd")) { + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + Hdr->dd = DddmpStrDup (buf); + Dddmp_CheckAndGotoLabel (Hdr->dd==NULL, "Error allocating memory.", + failure); + + continue; + } + + if (matchkeywd(buf, ".nnodes")) { + retValue = fscanf (fp, "%d", &(Hdr->nnodes)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd(buf, ".nvars")) { + retValue = fscanf (fp, "%d", &(Hdr->nVars)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd(buf, ".nsuppvars")) { + retValue = fscanf (fp, "%d", &(Hdr->nsuppvars)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd(buf, ".orderedvarnames")) { + Hdr->orderedVarNames = DddmpStrArrayRead (fp, Hdr->nVars); + Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".suppvarnames") || + ((strcmp (Hdr->ver, "DDDMP-1.0") == 0) && + matchkeywd (buf, ".varnames"))) { + Hdr->suppVarNames = DddmpStrArrayRead (fp, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if matchkeywd(buf, ".ids") { + Hdr->ids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->ids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".permids")) { + Hdr->permids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->permids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".auxids")) { + Hdr->auxids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->auxids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".nroots")) { + retValue = fscanf (fp, "%d", &(Hdr->nRoots)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd(buf, ".rootids")) { + Hdr->rootids = DddmpIntArrayRead(fp,Hdr->nRoots); + Dddmp_CheckAndGotoLabel (Hdr->rootids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".rootnames")) { + Hdr->rootnames = DddmpStrArrayRead(fp,Hdr->nRoots); + Dddmp_CheckAndGotoLabel (Hdr->rootnames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".nodes")) { + fgets(buf,DDDMP_MAXSTRLEN,fp); + break; + } + + } + + /* END HEADER */ + + return (Hdr); + +failure: + + if (fileToClose == 1) { + fclose (fp); + } + + DddmpFreeHeader(Hdr); + + return (NULL); +} + + +/**Function******************************************************************** + + Synopsis [Frees the internal header structure.] + + Description [Frees the internal header structureby freeing all internal + fields first. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +DddmpFreeHeader ( + Dddmp_Hdr_t *Hdr /* IN: pointer to header */ + ) +{ + DDDMP_FREE (Hdr->ver); + DDDMP_FREE (Hdr->dd); + DddmpStrArrayFree (Hdr->orderedVarNames, Hdr->nVars); + DddmpStrArrayFree (Hdr->suppVarNames, Hdr->nsuppvars); + DDDMP_FREE (Hdr->ids); + DDDMP_FREE (Hdr->permids); + DDDMP_FREE (Hdr->auxids); + DDDMP_FREE (Hdr->rootids); + DddmpStrArrayFree (Hdr->rootnames, Hdr->nRoots); + + DDDMP_FREE (Hdr); + + return; +} + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoadCnf.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoadCnf.c new file mode 100644 index 000000000..35bec273b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoadCnf.c @@ -0,0 +1,1072 @@ +/**CFile********************************************************************** + + FileName [dddmpLoadCnf.c] + + PackageName [dddmp] + + Synopsis [Functions to read in CNF from file as BDDs.] + + Description [Functions to read in CNF from file as BDDs. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMP_MAX_CNF_ROW_LENGTH 1000 +#define DDDMP_DEBUG_CNF 0 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define matchkeywd(str,key) (strncmp(str,key,strlen(key))==0) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpCuddDdArrayLoadCnf(DdManager *ddMgr, Dddmp_RootMatchType rootmatchmode, char **rootmatchnames, Dddmp_VarMatchType varmatchmode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***rootsPtrPtr, int *nRoots); +static Dddmp_Hdr_t * DddmpBddReadHeaderCnf(char *file, FILE *fp); +static void DddmpFreeHeaderCnf(Dddmp_Hdr_t *Hdr); +static int DddmpReadCnfClauses(Dddmp_Hdr_t *Hdr, int ***cnfTable, FILE *fp); +static int DddmpCnfClauses2Bdd(Dddmp_Hdr_t *Hdr, DdManager *ddMgr, int **cnfTable, int mode, DdNode ***rootsPtrPtr); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads a dump file in a CNF format.] + + Description [Reads a dump file representing the argument BDD in a + CNF formula. + Dddmp_cuddBddArrayLoadCnf is used through a dummy array. + The results is returned in different formats depending on the + mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddLoad, Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddBddLoadCnf ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_VarMatchType varmatchmode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by IDs */, + int *varmatchauxids /* IN: array of variable auxids, by IDs */, + int *varcomposeids /* IN: array of new ids accessed, by IDs */, + int mode /* IN: computation mode */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots */, + int *nRoots /* OUT: number of BDDs returned */ + ) +{ + int i, retValue; + + retValue = Dddmp_cuddBddArrayLoadCnf (ddMgr, DDDMP_ROOT_MATCHLIST, NULL, + varmatchmode, varmatchnames, varmatchauxids, varcomposeids, mode, + file, fp, rootsPtrPtr, nRoots); + + if (retValue == DDDMP_FAILURE) { + return (DDDMP_FAILURE); + } + + if (*nRoots > 1) { + fprintf (stderr, + "Warning: %d BDD roots found in file. Only first retrieved.\n", + *nRoots); + for (i=1; i<*nRoots; i++) { + Cudd_RecursiveDeref (ddMgr, *rootsPtrPtr[i]); + } + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Reads a dump file in a CNF format.] + + Description [Reads a dump file representing the argument BDD in a + CNF formula. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayLoadCnf ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_RootMatchType rootmatchmode/* IN: storing mode selector */, + char **rootmatchnames /* IN: sorted names for loaded roots */, + Dddmp_VarMatchType varmatchmode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by IDs */, + int *varmatchauxids /* IN: array of variable auxids, by IDs */, + int *varcomposeids /* IN: array of new ids, by IDs */, + int mode /* IN: computation Mode */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots */, + int *nRoots /* OUT: number of BDDs returned */ + ) +{ + int retValue; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During CNF Load.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During CNF Load.\n"); + fflush (stderr); + } + } +#endif +#endif + + retValue = DddmpCuddDdArrayLoadCnf (ddMgr, rootmatchmode, + rootmatchnames, varmatchmode, varmatchnames, varmatchauxids, + varcomposeids, mode, file, fp, rootsPtrPtr, nRoots); + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During CNF Load.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During CNF Load.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Reads the header of a dump file representing the argument BDDs] + + Description [Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddHeaderLoadCnf ( + int *nVars /* OUT: number of DD variables */, + int *nsuppvars /* OUT: number of support variables */, + char ***suppVarNames /* OUT: array of support variable names */, + char ***orderedVarNames /* OUT: array of variable names */, + int **varIds /* OUT: array of variable ids */, + int **varComposeIds /* OUT: array of permids ids */, + int **varAuxIds /* OUT: array of variable aux ids */, + int *nRoots /* OUT: number of root in the file */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + Dddmp_Hdr_t *Hdr; + int i, fileToClose; + char **tmpOrderedVarNames = NULL; + char **tmpSuppVarNames = NULL; + int *tmpVarIds = NULL; + int *tmpVarComposeIds = NULL; + int *tmpVarAuxIds = NULL; + + fileToClose = 0; + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + Hdr = DddmpBddReadHeaderCnf (NULL, fp); + + Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.", + failure); + + /* + * Number of variables (tot and support) + */ + + *nVars = Hdr->nVars; + *nsuppvars = Hdr->nsuppvars; + + /* + * Support Varnames + */ + + if (Hdr->suppVarNames != NULL) { + tmpSuppVarNames = DDDMP_ALLOC (char *, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpSuppVarNames==NULL, "Error allocating memory.", + failure); + + for (i=0; i<*nsuppvars; i++) { + tmpSuppVarNames[i] = DDDMP_ALLOC (char, + (strlen (Hdr->suppVarNames[i]) + 1)); + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + strcpy (tmpSuppVarNames[i], Hdr->suppVarNames[i]); + } + + *suppVarNames = tmpSuppVarNames; + } else { + *suppVarNames = NULL; + } + + /* + * Ordered Varnames + */ + + if (Hdr->orderedVarNames != NULL) { + tmpOrderedVarNames = DDDMP_ALLOC (char *, *nVars); + Dddmp_CheckAndGotoLabel (tmpOrderedVarNames==NULL, + "Error allocating memory.", failure); + + for (i=0; i<*nVars; i++) { + tmpOrderedVarNames[i] = DDDMP_ALLOC (char, + (strlen (Hdr->orderedVarNames[i]) + 1)); + Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + strcpy (tmpOrderedVarNames[i], Hdr->orderedVarNames[i]); + } + + *orderedVarNames = tmpOrderedVarNames; + } else { + *orderedVarNames = NULL; + } + + /* + * Variable Ids + */ + + if (Hdr->ids != NULL) { + tmpVarIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarIds==NULL, "Error allocating memory.", + failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarIds[i] = Hdr->ids[i]; + } + + *varIds = tmpVarIds; + } else { + *varIds = NULL; + } + + /* + * Variable Compose Ids + */ + + if (Hdr->permids != NULL) { + tmpVarComposeIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarComposeIds==NULL, + "Error allocating memory.", failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarComposeIds[i] = Hdr->permids[i]; + } + + *varComposeIds = tmpVarComposeIds; + } else { + *varComposeIds = NULL; + } + + /* + * Variable Auxiliary Ids + */ + + if (Hdr->auxids != NULL) { + tmpVarAuxIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarAuxIds==NULL, + "Error allocating memory.", failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarAuxIds[i] = Hdr->auxids[i]; + } + + *varAuxIds = tmpVarAuxIds; + } else { + *varAuxIds = NULL; + } + + /* + * Number of roots + */ + + *nRoots = Hdr->nRoots; + + /* + * Free and Return + */ + + if (fileToClose == 1) { + fclose (fp); + } + + DddmpFreeHeaderCnf (Hdr); + + return (DDDMP_SUCCESS); + + failure: + return (DDDMP_FAILURE); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads a dump file representing the argument BDDs in CNF + format. + ] + + Description [Reads a dump file representing the argument BDDs in CNF + format. + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +static int +DddmpCuddDdArrayLoadCnf ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_RootMatchType rootmatchmode/* IN: storing mode selector */, + char **rootmatchnames /* IN: sorted names for loaded roots */, + Dddmp_VarMatchType varmatchmode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by ids */, + int *varmatchauxids /* IN: array of variable auxids, by ids */, + int *varcomposeids /* IN: array of new ids, by ids */, + int mode /* IN: computation mode */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***rootsPtrPtr /* OUT: array of BDD roots */, + int *nRoots /* OUT: number of BDDs returned */ + ) +{ + Dddmp_Hdr_t *Hdr = NULL; + int **cnfTable = NULL; + int fileToClose = 0; + int retValue, i; + + fileToClose = 0; + *rootsPtrPtr = NULL; + + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /*--------------------------- Read the Header -----------------------------*/ + + Hdr = DddmpBddReadHeaderCnf (NULL, fp); + + Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.", + failure); + + /*------------------------ Read the CNF Clauses ---------------------------*/ + + retValue = DddmpReadCnfClauses (Hdr, &cnfTable, fp); + + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "Read CNF Clauses Failure.", failure); + + /*------------------------- From Clauses to BDDs --------------------------*/ + + retValue = DddmpCnfClauses2Bdd (Hdr, ddMgr, cnfTable, mode, rootsPtrPtr); + + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "CNF Clauses To BDDs Failure.", failure); + + *nRoots = Hdr->nRoots; + + if (fileToClose) { + fclose (fp); + } + + for (i=0; inClausesCnf; i++) { + DDDMP_FREE (cnfTable[i]); + } + DDDMP_FREE (cnfTable); + + DddmpFreeHeaderCnf (Hdr); + + return (DDDMP_SUCCESS); + + /* + * Failure Condition + */ + +failure: + + if (fileToClose) { + fclose (fp); + } + + for (i=0; inClausesCnf; i++) { + DDDMP_FREE (cnfTable[i]); + } + DDDMP_FREE (cnfTable); + + DddmpFreeHeaderCnf (Hdr); + + /* return 0 on error ! */ + nRoots = 0; + + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Reads a the header of a dump file representing the argument + BDDs. + ] + + Description [Reads the header of a dump file. Builds a Dddmp_Hdr_t struct + containing all infos in the header, for next manipulations. + ] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ + +static Dddmp_Hdr_t * +DddmpBddReadHeaderCnf ( + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + Dddmp_Hdr_t *Hdr = NULL; + char buf[DDDMP_MAXSTRLEN]; + int nv, nc, retValue, fileToClose = 0; + + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /* Start Header */ + Hdr = DDDMP_ALLOC (Dddmp_Hdr_t, 1); + if (Hdr == NULL) { + return NULL; + } + + Hdr->ver = NULL; + Hdr->mode = 0; + Hdr->ddType = DDDMP_CNF; + Hdr->varinfo = DDDMP_VARIDS; + Hdr->dd = NULL; + Hdr->nnodes = 0; + Hdr->nVars = 0; + Hdr->nsuppvars = 0; + Hdr->orderedVarNames = NULL; + Hdr->suppVarNames = NULL; + Hdr->ids = NULL; + Hdr->permids = NULL; + Hdr->auxids = NULL; + Hdr->cnfids = NULL; + Hdr->nRoots = 0; + Hdr->rootids = NULL; + Hdr->rootnames = NULL; + Hdr->nAddedCnfVar = 0; + Hdr->nVarsCnf = 0; + Hdr->nClausesCnf = 0; + + while (fscanf (fp, "%s", buf) != EOF) { + + /* Init Problem Line */ + if (buf[0] == 'p') { + fscanf (fp, "%*s %d %d", &nv, &nc); + Hdr->nVarsCnf = nv; + Hdr->nClausesCnf = nc; + break; + } + + /* CNF Comment Line */ + if (buf[0] == 'c') { + if (fscanf (fp, "%s", buf) == EOF) { + break; + } + } + + /* Skip Comment? */ + if (buf[0] != '.') { + fgets (buf, DDDMP_MAXSTRLEN, fp); + continue; + } + + if (matchkeywd (buf, ".ver")) { + /* this not checked so far: only read */ + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading from file.", + failure); + + Hdr->ver=DddmpStrDup(buf); + Dddmp_CheckAndGotoLabel (Hdr->ver==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".dd")) { + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + Hdr->dd = DddmpStrDup (buf); + Dddmp_CheckAndGotoLabel (Hdr->dd==NULL, "Error allocating memory.", + failure); + + continue; + } + + if (matchkeywd (buf, ".nnodes")) { + retValue = fscanf (fp, "%d", &(Hdr->nnodes)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd (buf, ".nvars")) { + retValue = fscanf (fp, "%d", &(Hdr->nVars)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd (buf, ".nsuppvars")) { + retValue = fscanf (fp, "%d", &(Hdr->nsuppvars)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd (buf, ".orderedvarnames")) { + Hdr->orderedVarNames = DddmpStrArrayRead (fp, Hdr->nVars); + Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".suppvarnames")) { + Hdr->suppVarNames = DddmpStrArrayRead (fp, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if matchkeywd (buf, ".ids") { + Hdr->ids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->ids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".permids")) { + Hdr->permids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->permids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".auxids")) { + Hdr->auxids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->auxids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".cnfids")) { + Hdr->cnfids = DddmpIntArrayRead (fp, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->cnfids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".nroots")) { + retValue = fscanf (fp, "%d", &(Hdr->nRoots)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd (buf, ".rootids")) { + Hdr->rootids = DddmpIntArrayRead(fp,Hdr->nRoots); + Dddmp_CheckAndGotoLabel (Hdr->rootids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".rootnames")) { + Hdr->rootnames = DddmpStrArrayRead(fp,Hdr->nRoots); + Dddmp_CheckAndGotoLabel (Hdr->rootnames==NULL, + "Error allocating memory.", failure); + + continue; + } + + + if (matchkeywd (buf, ".nAddedCnfVar")) { + retValue = fscanf (fp, "%d", &(Hdr->nAddedCnfVar)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + } + + /* END HEADER */ + return (Hdr); + +failure: + + if (fileToClose == 1) { + fclose (fp); + } + + DddmpFreeHeaderCnf (Hdr); + + return (NULL); +} + + +/**Function******************************************************************** + + Synopsis [Frees the internal header structure.] + + Description [Frees the internal header structure by freeing all internal + fields first. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +DddmpFreeHeaderCnf ( + Dddmp_Hdr_t *Hdr /* IN: pointer to header */ + ) +{ + if (Hdr==NULL) { + return; + } + + DDDMP_FREE (Hdr->ver); + DDDMP_FREE (Hdr->dd); + DddmpStrArrayFree (Hdr->orderedVarNames, Hdr->nVars); + DddmpStrArrayFree (Hdr->suppVarNames, Hdr->nsuppvars); + DDDMP_FREE (Hdr->ids); + DDDMP_FREE (Hdr->permids); + DDDMP_FREE (Hdr->auxids); + DDDMP_FREE (Hdr->cnfids); + DDDMP_FREE (Hdr->rootids); + DddmpStrArrayFree (Hdr->rootnames, Hdr->nRoots); + + DDDMP_FREE (Hdr); + + return; +} + +/**Function******************************************************************** + + Synopsis [Read the CNF clauses from the file in the standard DIMACS + format. + ] + + Description [Read the CNF clauses from the file in the standard DIMACS + format. Store all the clauses in an internal structure for + future transformation into BDDs. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpReadCnfClauses ( + Dddmp_Hdr_t *Hdr /* IN: file header */, + int ***cnfTable /* OUT: CNF table for clauses */, + FILE *fp /* IN: source file */ + ) +{ + char word[DDDMP_MAX_CNF_ROW_LENGTH]; + int i, j, var; + int **cnfTableLocal = NULL; + int *clause = NULL; + + cnfTableLocal = DDDMP_ALLOC (int *, Hdr->nClausesCnf); + clause = DDDMP_ALLOC (int, 2*Hdr->nVarsCnf+1); + + for (i=0; inClausesCnf; i++) { + cnfTableLocal[i] = NULL; + } + + for (i=0; i<=2*Hdr->nVarsCnf; i++) { + clause[i] = 0; + } + + i = j = 0; + do { + if (fscanf(fp, "%s", word)==EOF) { + if (j>0) { + /* force last zero */ + strcpy(word,"0"); + } + else break; + } + + /* Check for Comment */ + if (word[0] == 'c') { + /* Comment Found: Skip line */ + fgets (word, DDDMP_MAX_CNF_ROW_LENGTH-1, fp); + break; + } + + var = atoi (word); + Dddmp_Assert ((var>=(-Hdr->nVarsCnf))&&(var<=Hdr->nVarsCnf), + "Wrong num found"); + clause[j++] = var; + if (var == 0) { + cnfTableLocal[i] = DDDMP_ALLOC (int, j); + while (--j >=0) { + cnfTableLocal[i][j] = clause[j]; + } + i++; + j=0; + } + + } while (!feof(fp)); + + Dddmp_Assert (i==Hdr->nClausesCnf, + "Wrong number of clauses in file"); + +#if DDDMP_DEBUG_CNF + for (i=0; inClausesCnf; i++) { + fprintf (stdout, "[%4d] ", i); + j=0; + while ((var = cnfTableLocal[i][j++]) != 0) { + fprintf (stdout, "%d ", var); + } + fprintf (stdout, "0\n"); + } +#endif + + DDDMP_FREE (clause); + + *cnfTable = cnfTableLocal; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Transforms CNF clauses into BDDs.] + + Description [Transforms CNF clauses into BDDs. Clauses are stored in an + internal structure previously read. The results can be given in + different format according to the mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpCnfClauses2Bdd ( + Dddmp_Hdr_t *Hdr /* IN: file header */, + DdManager *ddMgr /* IN: DD Manager */, + int **cnfTable /* IN: CNF table for clauses */, + int mode /* IN: computation mode */, + DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots (by reference) */ + ) +{ + DdNode **rel = NULL; + DdNode *lit = NULL; + DdNode *tmp1 = NULL; + DdNode *tmp2 = NULL; + DdNode **rootsPtr = NULL; + DdNode *cubeAllVar = NULL; + DdNode *cubeBddVar = NULL; + DdNode *cubeCnfVar = NULL; + int i, j, k, n, var1, var2, fromLine, toLine; + + rootsPtr = NULL; + *rootsPtrPtr = NULL; + + /*-------------------------- Read The Clauses -----------------------------*/ + + rel = DDDMP_ALLOC (DdNode *, Hdr->nClausesCnf); + + cubeBddVar = Cudd_ReadOne (ddMgr); + cubeCnfVar = Cudd_ReadOne (ddMgr); + cubeAllVar = Cudd_ReadOne (ddMgr); + Cudd_Ref (cubeBddVar); + Cudd_Ref (cubeCnfVar); + Cudd_Ref (cubeAllVar); + + for (i=0; inClausesCnf; i++) { + rel[i] = Cudd_Not (Cudd_ReadOne (ddMgr)); + Cudd_Ref (rel[i]); + j=0; + while ((var1 = cnfTable[i][j++]) != 0) { + + /* Deal with the Literal */ + var2 = abs (var1); + n = (-1); + for (k=0; knsuppvars; k++) { + if (Hdr->cnfids[k] == var2) { + n = k; + break; + } + } + + if (n == (-1)) { + lit = Cudd_bddIthVar (ddMgr, var2); + + /* Create the cubes of CNF Variables */ + tmp1 = Cudd_bddAnd (ddMgr, cubeCnfVar, lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, cubeCnfVar); + cubeCnfVar = tmp1; + + } else { + lit = Cudd_bddIthVar (ddMgr, Hdr->ids[n]); + + /* Create the cubes of BDD Variables */ + tmp1 = Cudd_bddAnd (ddMgr, cubeBddVar, lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, cubeBddVar); + cubeBddVar = tmp1; + } + + /* Create the cubes of ALL Variables */ + tmp1 = Cudd_bddAnd (ddMgr, cubeAllVar, lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, cubeAllVar); + cubeAllVar = tmp1; + + /* Deal with Relations */ + if (var1<0) { + lit = Cudd_Not (lit); + } + tmp1 = Cudd_bddOr (ddMgr, rel[i], lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, rel[i]); + rel[i] = tmp1; + } + } + + /* + * Mode == 0 Return the Clauses without Conjunction + */ + + if (mode == 0) { + return (DDDMP_SUCCESS); + } + + rootsPtr = DDDMP_ALLOC (DdNode *, Hdr->nRoots); + Dddmp_CheckAndGotoLabel (rootsPtr==NULL, "Error allocating memory.", + failure); + + for (i=0; inRoots; i++) { + if (i == (Hdr->nRoots-1)) { + fromLine = Hdr->rootids[i] - 1; + toLine = Hdr->nClausesCnf; + } else { + fromLine = Hdr->rootids[i] - 1; + toLine = Hdr->rootids[i+1]; + } + + tmp1 = Cudd_ReadOne (ddMgr); + Cudd_Ref (tmp1); + for (j=fromLine; jnsuppvars; i++) { + lit = Cudd_bddIthVar (ddMgr, Hdr->ids[i]); + tmp1 = Cudd_bddAnd (ddMgr, cubeBddVar, lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, cubeBddVar); + cubeBddVar = tmp1; + } + + cubeCnfVar = Cudd_bddExistAbstract (ddMgr, cubeAllVar, cubeBddVar); +#endif + + for (i=0; inRoots; i++) { +#if DDDMP_DEBUG_CNF + fprintf (stdout, "rootsPtr Before Exist:\n"); + Cudd_PrintDebug (ddMgr, rootsPtr[i], 0, 3); +#endif + + tmp1 = Cudd_bddExistAbstract (ddMgr, rootsPtr[i], cubeCnfVar); + Cudd_RecursiveDeref (ddMgr, rootsPtr[i]); + rootsPtr[i] = tmp1; + +#if DDDMP_DEBUG_CNF + fprintf (stdout, "rootsPtr After Exist:\n"); + Cudd_PrintDebug (ddMgr, rootsPtr[i], 0, 3); +#endif + } + +#if DDDMP_DEBUG_CNF + fprintf (stdout, "cubeAllVar:\n"); + Cudd_PrintDebug (ddMgr, cubeAllVar, 0, 3); + fprintf (stdout, "cubeBddVar:\n"); + Cudd_PrintDebug (ddMgr, cubeBddVar, 0, 3); + fprintf (stdout, "cubeCnfVar:\n"); + Cudd_PrintDebug (ddMgr, cubeCnfVar, 0, 3); +#endif + + Cudd_RecursiveDeref (ddMgr, cubeAllVar); + Cudd_RecursiveDeref (ddMgr, cubeBddVar); + Cudd_RecursiveDeref (ddMgr, cubeCnfVar); + *rootsPtrPtr = rootsPtr; + + return (DDDMP_SUCCESS); + + /* + * Failure Condition + */ + +failure: + + DDDMP_FREE (rel); + DDDMP_FREE (rootsPtrPtr); + + return (DDDMP_FAILURE); +} + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeAdd.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeAdd.c new file mode 100644 index 000000000..6fca772f1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeAdd.c @@ -0,0 +1,451 @@ +/**CFile********************************************************************** + + FileName [dddmpNodeAdd.c] + + PackageName [dddmp] + + Synopsis [Functions to handle ADD node infos and numbering] + + Description [Functions to handle ADD node infos and numbering. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NumberNodeRecurAdd(DdNode *f, int id); +static void RemoveFromUniqueRecurAdd(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecurAdd(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and number them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodes()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecurAdd (), NumberNodeRecurAdd (), + DddmpUnnumberDdNodesAdd ()] + +******************************************************************************/ + +int +DddmpNumberAddNodes ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int n /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int id=0, i; + + for (i=0; inext = (struct DdNode *)((ptruint)((id)<<1)); + } + + return; +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndexAdd (), DddmpSetVisitedAdd (), + DddmpVisitedAdd ()] + +******************************************************************************/ + +int +DddmpReadNodeIndexAdd ( + DdNode *f /* IN: BDD node */ + ) +{ + if (1 || !Cudd_IsConstant (f)) { + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisitedAdd (), DddmpClearVisitedAdd ()] + +******************************************************************************/ + +int +DddmpVisitedAdd ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedAdd (), DddmpClearVisitedAdd ()] + +******************************************************************************/ + +void +DddmpSetVisitedAdd ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedAdd (), DddmpSetVisitedAdd ()] + +******************************************************************************/ + +void +DddmpClearVisitedAdd ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecurAdd ( + DdNode *f /* IN: root of the BDD to be numbered */, + int id /* IN/OUT: index to be assigned to the node */ + ) +{ + f = Cudd_Regular(f); + + if (!DddmpVisitedAdd (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecurAdd (cuddT (f), id); + id = NumberNodeRecurAdd (cuddE (f), id); + } + + DddmpWriteNodeIndexAdd (f, ++id); + DddmpClearVisitedAdd (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. Constants remain untouched. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecurAdd ()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecurAdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisitedAdd (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecurAdd (ddMgr, cuddT (f)); + RemoveFromUniqueRecurAdd (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisitedAdd (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursively)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUniqueAdd ()] + +******************************************************************************/ + +static void +RestoreInUniqueRecurAdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + /* StQ 11.02.2004: + Bug fixed --> restore NULL within the next field */ + /*DddmpClearVisitedAdd (f);*/ + f->next = NULL; + + return; + } + + RestoreInUniqueRecurAdd (ddMgr, cuddT (f)); + RestoreInUniqueRecurAdd (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + f->next = *previousP; + *previousP = f; + + return; +} + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeBdd.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeBdd.c new file mode 100644 index 000000000..17f7fe39a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeBdd.c @@ -0,0 +1,452 @@ +/**CFile********************************************************************** + + FileName [dddmpNodeBdd.c] + + PackageName [dddmp] + + Synopsis [Functions to handle BDD node infos and numbering] + + Description [Functions to handle BDD node infos and numbering. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NumberNodeRecurBdd(DdNode *f, int id); +static void RemoveFromUniqueRecurBdd(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecurBdd(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and number them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberBddNodes ()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecur(), NumberNodeRecur(), + DddmpUnnumberBddNodes ()] + +******************************************************************************/ + +int +DddmpNumberBddNodes ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int n /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int id=0, i; + + for (i=0; inext = (struct DdNode *)((ptruint)((id)<<1)); + } + + return; +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndexBdd (), DddmpSetVisitedBdd (), + DddmpVisitedBdd ()] + +******************************************************************************/ + +int +DddmpReadNodeIndexBdd ( + DdNode *f /* IN: BDD node */ + ) +{ + if (!Cudd_IsConstant (f)) { + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisitedBdd (), DddmpClearVisitedBdd ()] + +******************************************************************************/ + +int +DddmpVisitedBdd ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedBdd (), DddmpClearVisitedBdd ()] + +******************************************************************************/ + +void +DddmpSetVisitedBdd ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisited (), DddmpSetVisited ()] + +******************************************************************************/ + +void +DddmpClearVisitedBdd ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecurBdd ( + DdNode *f /* IN: root of the BDD to be numbered */, + int id /* IN/OUT: index to be assigned to the node */ + ) +{ + f = Cudd_Regular (f); + + if (!DddmpVisitedBdd (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecurBdd (cuddT (f), id); + id = NumberNodeRecurBdd (cuddE (f), id); + } + + DddmpWriteNodeIndexBdd (f, ++id); + DddmpClearVisitedBdd (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. Constants remain untouched. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecurBdd ()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecurBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisitedBdd (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecurBdd (ddMgr, cuddT (f)); + RemoveFromUniqueRecurBdd (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisitedBdd (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursively)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUnique()] + +******************************************************************************/ + +static void +RestoreInUniqueRecurBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + /* StQ 11.02.2004: + Bug fixed --> restore NULL within the next field */ + /*DddmpClearVisitedBdd (f);*/ + f->next = NULL; + + return; + } + + RestoreInUniqueRecurBdd (ddMgr, cuddT (f)); + RestoreInUniqueRecurBdd (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + f->next = *previousP; + *previousP = f; + + return; +} + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeCnf.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeCnf.c new file mode 100644 index 000000000..fa61ace69 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeCnf.c @@ -0,0 +1,932 @@ +/**CFile********************************************************************** + + FileName [dddmpNodeCnf.c] + + PackageName [dddmp] + + Synopsis [Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs] + + Description [Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMP_DEBUG_CNF 0 + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpWriteNodeIndexCnfWithTerminalCheck(DdNode *f, int *cnfIds, int id); +static int DddmpClearVisitedCnfRecur(DdNode *f); +static void DddmpClearVisitedCnf(DdNode *f); +static int NumberNodeRecurCnf(DdNode *f, int *cnfIds, int id); +static void DddmpDdNodesCheckIncomingAndScanPath(DdNode *f, int pathLengthCurrent, int edgeInTh, int pathLengthTh); +static int DddmpDdNodesNumberEdgesRecur(DdNode *f, int *cnfIds, int id); +static int DddmpDdNodesResetCountRecur(DdNode *f); +static int DddmpDdNodesCountEdgesRecur(DdNode *f); +static void RemoveFromUniqueRecurCnf(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecurCnf(DdManager *ddMgr, DdNode *f); +static int DddmpPrintBddAndNextRecur(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and numbers them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodesCnf()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecurCnf(), NumberNodeRecurCnf(), + DddmpUnnumberDdNodesCnf()] + +******************************************************************************/ + +int +DddmpNumberDdNodesCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int rootN /* IN: number of BDD roots in the array of BDDs */, + int *cnfIds /* OUT: CNF identifiers for variables */, + int id /* OUT: number of Temporary Variables Introduced */ + ) +{ + int i; + + for (i=0; i BDDs After Count Reset:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*----------------------- Count Incoming Edges ----------------------------*/ + + for (i=0; i BDDs After Count Recur:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*------------------------- Count Path Length ----------------------------*/ + + for (i=0; i BDDs After Check Incoming And Scan Path:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*-------------------- Number Nodes and Set Visited -----------------------*/ + + for (i=0; i BDDs After Count Edges Recur:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Restores nodes in unique table, loosing numbering] + + Description [Node indexes are no more needed. Nodes are re-linked in the + unique table. + ] + + SideEffects [None] + + SeeAlso [DddmpNumberDdNode()] + +******************************************************************************/ + +void +DddmpUnnumberDdNodesCnf( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int rootN /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int i; + + for (i=0; i Bdd %d:\n", i); + fflush (stdout); + DddmpPrintBddAndNextRecur (ddMgr, f[i]); + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Write index to node] + + Description [The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. + ] + + SideEffects [None] + + SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf () + ] + +******************************************************************************/ + +int +DddmpWriteNodeIndexCnf ( + DdNode *f /* IN: BDD node */, + int id /* IN: index to be written */ + ) +{ + if (!Cudd_IsConstant (f)) { + f->next = (struct DdNode *)((ptruint)((id)<<1)); + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisitedCnf (), DddmpClearVisitedCnf ()] + +******************************************************************************/ + +int +DddmpVisitedCnf ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpClearVisitedCnf ()] + +******************************************************************************/ + +void +DddmpSetVisitedCnf ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf ()] + +******************************************************************************/ + +int +DddmpReadNodeIndexCnf ( + DdNode *f /* IN: BDD node */ + ) +{ + if (!Cudd_IsConstant (f)) { + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Write index to node] + + Description [The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. The index corresponds to + the BDD node variable if both the node's children are a + constant node, otherwise a new CNF variable is used. + ] + + SideEffects [None] + + SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf ()] + +*****************************************************************************/ + +static int +DddmpWriteNodeIndexCnfWithTerminalCheck ( + DdNode *f /* IN: BDD node */, + int *cnfIds /* IN: possible source for the index to be written */, + int id /* IN: possible source for the index to be written */ + ) +{ + if (!Cudd_IsConstant (f)) { + if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) { + /* If Variable SET ID as Variable ID */ + f->next = (struct DdNode *)((ptruint)((cnfIds[f->index])<<1)); + } else { + f->next = (struct DdNode *)((ptruint)((id)<<1)); + id++; + } + } + + return(id); +} + +/**Function******************************************************************** + + Synopsis [Mark ALL nodes as not visited] + + Description [Mark ALL nodes as not visited (it recurs on the node children)] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()] + +******************************************************************************/ + +static int +DddmpClearVisitedCnfRecur ( + DdNode *f /* IN: root of the BDD to be marked */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (cuddIsConstant (f)) { + return (DDDMP_SUCCESS); + } + + if (!DddmpVisitedCnf (f)) { + return (DDDMP_SUCCESS); + } + + retValue = DddmpClearVisitedCnfRecur (cuddT (f)); + retValue = DddmpClearVisitedCnfRecur (cuddE (f)); + + DddmpClearVisitedCnf (f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()] + +******************************************************************************/ + +static void +DddmpClearVisitedCnf ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecurCnf( + DdNode *f /* IN: root of the BDD to be numbered */, + int *cnfIds /* IN: possible source for numbering */, + int id /* IN/OUT: possible source for numbering */ + ) +{ + f = Cudd_Regular(f); + + if (!DddmpVisitedCnf (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecurCnf (cuddT (f), cnfIds, id); + id = NumberNodeRecurCnf (cuddE (f), cnfIds, id); + } + + id = DddmpWriteNodeIndexCnfWithTerminalCheck (f, cnfIds, id); + DddmpClearVisitedCnf (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with the right polarity. + The node is assigned to a new CNF variable only if it is a "shared" + node (i.e. the number of its incoming edges is greater than 1). + ] + + SideEffects ["visited" flags are set.] + + SeeAlso [] + +******************************************************************************/ + +static void +DddmpDdNodesCheckIncomingAndScanPath ( + DdNode *f /* IN: BDD node to be numbered */, + int pathLengthCurrent /* IN: Current Path Length */, + int edgeInTh /* IN: Max # In-Edges, after a Insert Cut Point */, + int pathLengthTh /* IN: Max Path Length (after, Insert a Cut Point) */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (DddmpVisitedCnf (f)) { + return; + } + + if (cuddIsConstant (f)) { + return; + } + + pathLengthCurrent++; + retValue = DddmpReadNodeIndexCnf (f); + + if ( ((edgeInTh >= 0) && (retValue > edgeInTh)) || + ((pathLengthTh >= 0) && (pathLengthCurrent > pathLengthTh)) + ) { + DddmpWriteNodeIndexCnf (f, 1); + pathLengthCurrent = 0; + } else { + DddmpWriteNodeIndexCnf (f, 0); + } + + DddmpDdNodesCheckIncomingAndScanPath (cuddT (f), pathLengthCurrent, + edgeInTh, pathLengthTh); + DddmpDdNodesCheckIncomingAndScanPath (cuddE (f), pathLengthCurrent, + edgeInTh, pathLengthTh); + + DddmpSetVisitedCnf (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with the inverse polarity. + Numbering follows the subsequent strategy: + * if the index = 0 it remains so + * if the index >= 1 it gets enumerated. + This implies that the node is assigned to a new CNF variable only if + it is not a terminal node otherwise it is assigned the index of + the BDD variable. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesNumberEdgesRecur ( + DdNode *f /* IN: BDD node to be numbered */, + int *cnfIds /* IN: possible source for numbering */, + int id /* IN/OUT: possible source for numbering */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (!DddmpVisitedCnf (f)) { + return (id); + } + + if (cuddIsConstant (f)) { + return (id); + } + + id = DddmpDdNodesNumberEdgesRecur (cuddT (f), cnfIds, id); + id = DddmpDdNodesNumberEdgesRecur (cuddE (f), cnfIds, id); + + retValue = DddmpReadNodeIndexCnf (f); + if (retValue >= 1) { + id = DddmpWriteNodeIndexCnfWithTerminalCheck (f, cnfIds, id); + } else { + DddmpWriteNodeIndexCnf (f, 0); + } + + DddmpClearVisitedCnf (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Resets counter and visited flag for ALL nodes of a BDD] + + Description [Resets counter and visited flag for ALL nodes of a BDD (it + recurs on the node children). The index field of the node is + used as counter. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesResetCountRecur ( + DdNode *f /* IN: root of the BDD whose counters are reset */ + ) +{ + int retValue; + + f = Cudd_Regular (f); + + if (!DddmpVisitedCnf (f)) { + return (DDDMP_SUCCESS); + } + + if (!cuddIsConstant (f)) { + retValue = DddmpDdNodesResetCountRecur (cuddT (f)); + retValue = DddmpDdNodesResetCountRecur (cuddE (f)); + } + + DddmpWriteNodeIndexCnf (f, 0); + DddmpClearVisitedCnf (f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Counts the number of incoming edges for each node of a BDD] + + Description [Counts (recursively) the number of incoming edges for each + node of a BDD. This number is stored in the index field. + ] + + SideEffects ["visited" flags remain untouched.] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesCountEdgesRecur ( + DdNode *f /* IN: root of the BDD */ + ) +{ + int indexValue, retValue; + + f = Cudd_Regular (f); + + if (cuddIsConstant (f)) { + return (DDDMP_SUCCESS); + } + + if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) { + return (DDDMP_SUCCESS); + } + + indexValue = DddmpReadNodeIndexCnf (f); + + /* IF (first time) THEN recur */ + if (indexValue == 0) { + retValue = DddmpDdNodesCountEdgesRecur (cuddT (f)); + retValue = DddmpDdNodesCountEdgesRecur (cuddE (f)); + } + + /* Increment Incoming-Edge Count Flag */ + indexValue++; + DddmpWriteNodeIndexCnf (f, indexValue); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on on the + children of the node. Constants remain untouched. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecurCnf()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecurCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisitedCnf (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecurCnf (ddMgr, cuddT (f)); + RemoveFromUniqueRecurCnf (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisitedCnf (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursive)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUnique()] + +******************************************************************************/ + +static void +RestoreInUniqueRecurCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + /* StQ 11.02.2004: + Bug fixed --> restore NULL within the next field */ + /*DddmpClearVisitedCnf (f);*/ + f->next = NULL; + + return; + } + + RestoreInUniqueRecurCnf (ddMgr, cuddT (f)); + RestoreInUniqueRecurCnf (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + f->next = *previousP; + *previousP = f; + + return; +} + +/**Function******************************************************************** + + Synopsis [Prints debug info] + + Description [Prints debug info for a BDD on the screen. It recurs on + node's children. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpPrintBddAndNextRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be displayed */ + ) +{ + int retValue; + DdNode *fPtr, *tPtr, *ePtr; + + fPtr = Cudd_Regular (f); + + if (Cudd_IsComplement (f)) { + fprintf (stdout, "sign=- ptr=%ld ", ((long int) fPtr)); + } else { + fprintf (stdout, "sign=+ ptr=%ld ", ((long int) fPtr)); + } + + if (cuddIsConstant (fPtr)) { + fprintf (stdout, "one\n"); + fflush (stdout); + return (DDDMP_SUCCESS); + } + + fprintf (stdout, + "thenPtr=%ld elsePtr=%ld BddId=%d CnfId=%d Visited=%d\n", + ((long int) cuddT (fPtr)), ((long int) cuddE (fPtr)), + fPtr->index, DddmpReadNodeIndexCnf (fPtr), + DddmpVisitedCnf (fPtr)); + + tPtr = cuddT (fPtr); + ePtr = cuddE (fPtr); + if (Cudd_IsComplement (f)) { + tPtr = Cudd_Not (tPtr); + ePtr = Cudd_Not (ePtr); + } + + retValue = DddmpPrintBddAndNextRecur (ddMgr, tPtr); + retValue = DddmpPrintBddAndNextRecur (ddMgr, ePtr); + + return (DDDMP_SUCCESS); +} + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreAdd.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreAdd.c new file mode 100644 index 000000000..a86e39ada --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreAdd.c @@ -0,0 +1,957 @@ +/**CFile********************************************************************** + FileName [dddmpStoreAdd.c] + + PackageName [dddmp] + + Synopsis [Functions to write ADDs to file.] + + Description [Functions to write ADDs to file. + ADDs are represended on file either in text or binary format under the + following rules. A file contains a forest of ADDs (a vector of + Boolean functions). ADD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to ADD + functions, followed by the list of nodes. + ADD nodes are listed according to their numbering, and in the present + implementation numbering follows a post-order strategy, in such a way + that a node is never listed before its Then/Else children. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NodeStoreRecurAdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp); +static int NodeTextStoreAdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp, int idf, int vf, int idT, int idE); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument ADD.] + + Description [Dumps the argument ADD to file. Dumping is done through + Dddmp_cuddAddArrayStore, And a dummy array of 1 ADD root is + used for this purpose. + ] + + SideEffects [Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order.] + + SeeAlso [Dddmp_cuddAddLoad Dddmp_cuddAddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddAddStore ( + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + DdNode *f /* IN: ADD root to be stored */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var ids */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + retValue = Dddmp_cuddAddArrayStore (ddMgr, ddname, 1, tmpArray, NULL, + varnames, auxids, mode, varinfo, fname, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of ADDs.] + + Description [Dumps the argument array of ADDs to file. Dumping is + either in text or binary form. see the corresponding BDD dump + function for further details. + ] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + ] + + SeeAlso [Dddmp_cuddAddStore, Dddmp_cuddAddLoad, + Dddmp_cuddAddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddAddArrayStore ( + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + int nRoots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of ADD roots to be stored */, + char **rootnames /* IN: array of root names (or NULL) */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var IDs */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + +#if 0 +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During ADD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During ADD Store.\n"); + fflush (stderr); + } + } +#endif +#endif +#endif + + retValue = DddmpCuddDdArrayStoreBdd (DDDMP_ADD, ddMgr, ddname, nRoots, f, + rootnames, varnames, auxids, mode, varinfo, fname, fp); + +#if 0 +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During ADD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During ADD Store.\n"); + fflush (stderr); + } + } +#endif +#endif +#endif + + return (retValue); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of + BDDs/ADDs. + ] + + Description [Dumps the argument array of BDDs/ADDs to file. Internal + function doing inner steps of store for BDDs and ADDs. + ADD store is presently supported only with the text format. + ] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + ] + + SeeAlso [Dddmp_cuddBddStore, Dddmp_cuddBddLoad, + Dddmp_cuddBddArrayLoad + ] + +******************************************************************************/ + +int +DddmpCuddDdArrayStoreBdd ( + Dddmp_DecompType ddType /* IN: Selects the decomp type: BDD or ADD */, + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + int nRoots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of DD roots to be stored */, + char **rootnames /* IN: array of root names (or NULL) */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var IDs */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *ids = NULL; + int *permids = NULL; + int *invpermids = NULL; + int *supportids = NULL; + int *outids = NULL; + char **outvarnames = NULL; + int nVars = ddMgr->size; + int nnodes; + int retValue; + int i, var; + int fileToClose = 0; + + /* + * Check DD Type and Mode + */ + + Dddmp_CheckAndGotoLabel (ddType==DDDMP_BDD, + "Error writing to file: BDD Type.", failure); + Dddmp_CheckAndGotoLabel (mode==DDDMP_MODE_BINARY, + "Error writing to file: ADD Type with Binary Mode.", failure); + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /* + * Force binary mode if automatic. + */ + + switch (mode) { + case DDDMP_MODE_TEXT: + case DDDMP_MODE_BINARY: + break; + case DDDMP_MODE_DEFAULT: + mode = DDDMP_MODE_BINARY; + break; + default: + mode = DDDMP_MODE_BINARY; + break; + } + + /* + * Alloc vectors for variable IDs, perm IDs and support IDs. + * +1 to include a slot for terminals. + */ + + ids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (ids==NULL, "Error allocating memory.", failure); + permids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (permids==NULL, "Error allocating memory.", failure); + invpermids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (invpermids==NULL, "Error allocating memory.", + failure); + supportids = DDDMP_ALLOC (int, nVars+1); + Dddmp_CheckAndGotoLabel (supportids==NULL, "Error allocating memory.", + failure); + + for (i=0; iindex] = scan->index; + permids[scan->index] = ddMgr->perm[scan->index]; + invpermids[ddMgr->perm[scan->index]] = scan->index; + scan = cuddT (scan); + } + Cudd_RecursiveDeref (ddMgr, support); + } + /* so that we do not try to free it in case of failure */ + support = NULL; + + /* + * Set supportids to incremental (shrinked) values following the ordering. + */ + + for (i=0, var=0; i= 0) { + supportids[invpermids[i]] = var++; + } + } + /* set a dummy id for terminal nodes */ + supportids[nVars] = var; + + /* + * Select conversion array for extra var info + */ + + switch (mode) { + case DDDMP_MODE_TEXT: + switch (varinfo) { + case DDDMP_VARIDS: + outids = ids; + break; + case DDDMP_VARPERMIDS: + outids = permids; + break; + case DDDMP_VARAUXIDS: + outids = auxids; + break; + case DDDMP_VARNAMES: + outvarnames = varnames; + break; + case DDDMP_VARDEFAULT: + break; + } + break; + case DDDMP_MODE_BINARY: + outids = NULL; + break; + } + + /* + * Number dd nodes and count them (numbering is from 1 to nnodes) + */ + + nnodes = DddmpNumberAddNodes (ddMgr, f, nRoots); + + /* + * Start Header + */ + +#ifdef DDDMP_VERSION + retValue = fprintf (fp, ".ver %s\n", DDDMP_VERSION); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); +#endif + + retValue = fprintf (fp, ".add\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".mode %c\n", mode); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (mode == DDDMP_MODE_TEXT) { + retValue = fprintf (fp, ".varinfo %d\n", varinfo); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + if (ddname != NULL) { + retValue = fprintf (fp, ".dd %s\n",ddname); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, ".nnodes %d\n", nnodes); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nvars %d\n", nVars); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nsuppvars %d\n", var); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /*------------ Write the Var Names by scanning the ids array -------------*/ + + if (varnames != NULL) { + + retValue = fprintf (fp, ".suppvarnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; i= 0) { + if (varnames[ids[i]] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. DUMMY%d generated\n", i); + fflush (stderr); + varnames[ids[i]] = DDDMP_ALLOC (char, 10); + Dddmp_CheckAndGotoLabel (varnames[ids[i]] == NULL, + "Error allocating memory.", failure); + sprintf (varnames[ids[i]], "DUMMY%d", i); + } + retValue = fprintf (fp, " %s", varnames[ids[i]]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /*--------- Write the Var SUPPORT Names by scanning the ids array ---------*/ + + if (varnames != NULL) { + retValue = fprintf (fp, ".orderedvarnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; iinvperm[i]] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. DUMMY%d generated\n", i); + fflush (stderr); + varnames[ddMgr->invperm[i]] = DDDMP_ALLOC (char, 10); + Dddmp_CheckAndGotoLabel (varnames[ddMgr->invperm[i]] == NULL, + "Error allocating memory.", failure); + sprintf (varnames[ddMgr->invperm[i]], "DUMMY%d", i); + } + + retValue = fprintf (fp, " %s", varnames[ddMgr->invperm[i]]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /*------------ Write the var ids by scanning the ids array ---------------*/ + + retValue = fprintf (fp, ".ids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; i= 0) { + retValue = fprintf (fp, " %d", i); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * Write the var permids by scanning the permids array. + */ + + retValue = fprintf (fp, ".permids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + for (i = 0; i < nVars; i++) { + if (permids[i] >= 0) { + retValue = fprintf (fp, " %d", permids[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (auxids != NULL) { + + /* + * Write the var auxids by scanning the ids array. + */ + + retValue = fprintf (fp, ".auxids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + for (i = 0; i < nVars; i++) { + if (ids[i] >= 0) { + retValue = fprintf (fp, " %d", auxids[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /* + * Write the roots info. + */ + + retValue = fprintf (fp, ".nroots %d\n", nRoots); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (rootnames != NULL) { + + /* + * Write the root names. + */ + + retValue = fprintf (fp, ".rootnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i = 0; i < nRoots; i++) { + if (rootnames[i] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. ROOT%d generated\n",i); + fflush (stderr); + rootnames[i] = DDDMP_ALLOC(char,10); + Dddmp_CheckAndGotoLabel (rootnames[i]==NULL, + "Error writing to file.", failure); + sprintf(rootnames[ids[i]], "ROOT%d",i); + } + retValue = fprintf (fp, " %s", rootnames[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, ".rootids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * Write BDD indexes of function roots. + * Use negative integers for complemented edges. + */ + + for (i = 0; i < nRoots; i++) { + if (f[i] == NULL) { + (void) fprintf (stderr, "DdStore Warning: %d-th root is NULL\n",i); + fflush (stderr); + retValue = fprintf (fp, " 0"); + } + if (Cudd_IsComplement(f[i])) { + retValue = fprintf (fp, " -%d", + DddmpReadNodeIndexAdd (Cudd_Regular (f[i]))); + } else { + retValue = fprintf (fp, " %d", + DddmpReadNodeIndexAdd (Cudd_Regular (f[i]))); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nodes\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * END HEADER + */ + + /* + * Call the function that really gets the job done. + */ + + for (i = 0; i < nRoots; i++) { + if (f[i] != NULL) { + retValue = NodeStoreRecurAdd (ddMgr, Cudd_Regular(f[i]), + mode, supportids, outvarnames, outids, fp); + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "Error writing to file.", failure); + } + } + + /* + * Write trailer and return. + */ + + retValue = fprintf (fp, ".end\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (fileToClose) { + fclose (fp); + } + + DddmpUnnumberAddNodes (ddMgr, f, nRoots); + DDDMP_FREE (ids); + DDDMP_FREE (permids); + DDDMP_FREE (invpermids); + DDDMP_FREE (supportids); + + return (DDDMP_SUCCESS); + + failure: + + if (ids != NULL) { + DDDMP_FREE (ids); + } + if (permids != NULL) { + DDDMP_FREE (permids); + } + if (invpermids != NULL) { + DDDMP_FREE (invpermids); + } + if (supportids != NULL) { + DDDMP_FREE (supportids); + } + if (support != NULL) { + Cudd_RecursiveDeref (ddMgr, support); + } + + return (DDDMP_FAILURE); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Dddmp_bddStore.] + + Description [Stores a node to file in either test or binary mode. + In text mode a node is represented (on a text line basis) as +
            +
          • node-index \[var-extrainfo\] var-index Then-index Else-index +
          + + where all indexes are integer numbers and var-extrainfo + (optional redundant field) is either an integer or a string + (variable name). Node-index is redundant (due to the node + ordering) but we keep it for readability.

          + + In binary mode nodes are represented as a sequence of bytes, + representing var-index, Then-index, and Else-index in an + optimized way. Only the first byte (code) is mandatory. + Integer indexes are represented in absolute or relative mode, + where relative means offset wrt. a Then/Else node info. + Suppose Var(NodeId), Then(NodeId) and Else(NodeId) represent + infos about a given node.

          + + The generic "NodeId" node is stored as + +

            +
          • code-byte +
          • \[var-info\] +
          • \[Then-info\] +
          • \[Else-info\] +
          + + where code-byte contains bit fields + +
            +
          • Unused : 1 bit +
          • Variable: 2 bits, one of the following codes +
              +
            • DDDMP_ABSOLUTE_ID var-info = Var(NodeId) follows +
            • DDDMP_RELATIVE_ID Var(NodeId) is represented in relative form as + var-info = Min(Var(Then(NodeId)),Var(Else(NodeId))) -Var(NodeId) +
            • DDDMP_RELATIVE_1 No var-info follows, because + Var(NodeId) = Min(Var(Then(NodeId)),Var(Else(NodeId)))-1 +
            • DDDMP_TERMINAL Node is a terminal, no var info required +
            +
          • T : 2 bits, with codes similar to V +
              +
            • DDDMP_ABSOLUTE_ID Then-info = Then(NodeId) follows +
            • DDDMP_RELATIVE_ID Then(NodeId) is represented in relative form as + Then-info = Nodeid-Then(NodeId) +
            • DDDMP_RELATIVE_1 No info on Then(NodeId) follows, because + Then(NodeId) = NodeId-1 +
            • DDDMP_TERMINAL Then Node is a terminal, no info required (for BDDs) +
            +
          • Ecompl : 1 bit, if 1 means complemented edge +
          • E : 2 bits, with codes and meanings as for the Then edge +
          + var-info, Then-info, Else-info (if required) are represented as unsigned + integer values on a sufficient set of bytes (MSByte first). + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +NodeStoreRecurAdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: store file */ + ) +{ + DdNode *T = NULL; + DdNode *E = NULL; + int idf = (-1); + int idT = (-1); + int idE = (-1); + int vf = (-1); + int vT = (-1); + int vE = (-1); + int retValue; + int nVars; + + nVars = ddMgr->size; + T = E = NULL; + idf = idT = idE = (-1); + +#ifdef DDDMP_DEBUG + assert(!Cudd_IsComplement(f)); + assert(f!=NULL); + assert(supportids!=NULL); +#endif + + /* If already visited, nothing to do. */ + if (DddmpVisitedAdd (f)) { + return (DDDMP_SUCCESS); + } + + /* Mark node as visited. */ + DddmpSetVisitedAdd (f); + + if (Cudd_IsConstant(f)) { + /* Check for special case: don't recur */ + idf = DddmpReadNodeIndexAdd (f); + } else { + +#ifdef DDDMP_DEBUG + /* BDDs! Only one constant supported */ + assert (!cuddIsConstant(f)); +#endif + + /* + * Recursive call for Then edge + */ + + T = cuddT(f); +#ifdef DDDMP_DEBUG + /* ROBDDs! No complemented Then edge */ + assert (!Cudd_IsComplement(T)); +#endif + /* recur */ + retValue = NodeStoreRecurAdd (ddMgr, T, mode, supportids, varnames, outids, + fp); + if (retValue != DDDMP_SUCCESS) { + return (retValue); + } + + /* + * Recursive call for Else edge + */ + + E = Cudd_Regular (cuddE (f)); + retValue = NodeStoreRecurAdd (ddMgr, E, mode, supportids, varnames, outids, + fp); + if (retValue != DDDMP_SUCCESS) { + return (retValue); + } + + /* + * Obtain nodeids and variable ids of f, T, E + */ + + idf = DddmpReadNodeIndexAdd (f); + vf = f->index; + + idT = DddmpReadNodeIndexAdd (T); + if (Cudd_IsConstant(T)) { + vT = nVars; + } else { + vT = T->index; + } + + idE = DddmpReadNodeIndexAdd (E); + if (Cudd_IsConstant(E)) { + vE = nVars; + } else { + vE = E->index; + } + } + + retValue = NodeTextStoreAdd (ddMgr, f, mode, supportids, varnames, + outids, fp, idf, vf, idT, idE); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Store One Single Node in Text Format.] + + Description [Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. + ] + + SideEffects [None] + + SeeAlso [NodeBinaryStore] + +******************************************************************************/ + +static int +NodeTextStoreAdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: Store file */, + int idf /* IN: index of the current node */, + int vf /* IN: variable of the current node */, + int idT /* IN: index of the Then node */, + int idE /* IN: index of the Else node */ + ) +{ + int retValue; + + /* + * Check for Constant + */ + + if (Cudd_IsConstant(f)) { + + if (f == Cudd_ReadOne(ddMgr)) { + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T 1 0 0\n", idf); + } else { + retValue = fprintf (fp, "%d 1 0 0\n", idf); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + if (f == Cudd_ReadZero(ddMgr)) { + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T 0 0 0\n", idf); + } else { + retValue = fprintf (fp, "%d 0 0 0\n", idf); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * A constant node different from 1: an ADD constant + */ + + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T %g 0 0\n",idf,Cudd_V(f)); + } else { + retValue = fprintf (fp, "%d %g 0 0\n",idf, Cudd_V(f)); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * ... Not A Constant + */ + + if (Cudd_IsComplement (cuddE(f))) { + idE = -idE; + } + + if (varnames != NULL) { + retValue = fprintf (fp, "%d %s %d %d %d\n", + idf, varnames[vf], supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + if (outids != NULL) { + retValue = fprintf (fp, "%d %d %d %d %d\n", + idf, outids[vf], supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + retValue = fprintf (fp, "%d %d %d %d\n", + idf, supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } +} diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreBdd.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreBdd.c new file mode 100644 index 000000000..cdc796843 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreBdd.c @@ -0,0 +1,1114 @@ +/**CFile********************************************************************** + + FileName [dddmpStoreBdd.c] + + PackageName [dddmp] + + Synopsis [Functions to write BDDs to file.] + + Description [Functions to write BDDs to file. + BDDs are represended on file either in text or binary format under the + following rules. A file contains a forest of BDDs (a vector of + Boolean functions). BDD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to BDD + functions, followed by the list of nodes. BDD nodes are listed + according to their numbering, and in the present implementation + numbering follows a post-order strategy, in such a way that a node + is never listed before its Then/Else children. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NodeStoreRecurBdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp); +static int NodeTextStoreBdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp, int idf, int vf, int idT, int idE); +static int NodeBinaryStoreBdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp, int idf, int vf, int idT, int idE, int vT, int vE, DdNode *T, DdNode *E); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD.] + + Description [Dumps the argument BDD to file. Dumping is done through + Dddmp_cuddBddArrayStore. A dummy array of 1 BDD root is + used for this purpose. + ] + + SideEffects [Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. + ] + + SeeAlso [Dddmp_cuddBddLoad Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddBddStore ( + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + DdNode *f /* IN: BDD root to be stored */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var ids */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStore (ddMgr,ddname,1,tmpArray,NULL, + varnames, auxids, mode, varinfo, fname, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of BDDs.] + + Description [Dumps the argument array of BDDs to file. Dumping is either + in text or binary form. BDDs are stored to the fp (already + open) file if not NULL. Otherwise the file whose name is + fname is opened in write mode. The header has the same format + for both textual and binary dump. Names are allowed for input + variables (vnames) and for represented functions (rnames). + For sake of generality and because of dynamic variable + ordering both variable IDs and permuted IDs are included. + New IDs are also supported (auxids). Variables are identified + with incremental numbers. according with their positiom in + the support set. In text mode, an extra info may be added, + chosen among the following options: name, ID, PermID, or an + auxiliary id. Since conversion from DD pointers to integers + is required, DD nodes are temporarily removed from the unique + hash table. This allows the use of the next field to store + node IDs. + ] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + ] + + SeeAlso [Dddmp_cuddBddStore, Dddmp_cuddBddLoad, + Dddmp_cuddBddArrayLoad + ] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStore ( + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: dd name (or NULL) */, + int nRoots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of BDD roots to be stored */, + char **rootnames /* IN: array of root names (or NULL) */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var IDs */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + retValue = DddmpCuddBddArrayStore (DDDMP_BDD, ddMgr, ddname, nRoots, f, + rootnames, varnames, auxids, mode, varinfo, fname, fp); + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of + BDDs. + ] + + Description [Dumps the argument array of BDDs to file. + Internal function doing inner steps of store for BDDs. + ] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + ] + + SeeAlso [Dddmp_cuddBddStore, Dddmp_cuddBddLoad, + Dddmp_cuddBddArrayLoad + ] + +******************************************************************************/ + +int +DddmpCuddBddArrayStore ( + Dddmp_DecompType ddType /* IN: Selects the decomp type BDD */, + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + int nRoots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of DD roots to be stored */, + char **rootnames /* IN: array of root names (or NULL) */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var IDs */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *ids = NULL; + int *permids = NULL; + int *invpermids = NULL; + int *supportids = NULL; + int *outids = NULL; + char **outvarnames = NULL; + int nVars = ddMgr->size; + int nnodes; + int retValue; + int i, var; + int fileToClose = 0; + + /* + * Check DD Type + */ + + Dddmp_CheckAndGotoLabel (ddType==DDDMP_ADD, + "Error writing to file: ADD Type.", failure); + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /* + * Force binary mode if automatic. + */ + + switch (mode) { + case DDDMP_MODE_TEXT: + case DDDMP_MODE_BINARY: + break; + case DDDMP_MODE_DEFAULT: + mode = DDDMP_MODE_BINARY; + break; + default: + mode = DDDMP_MODE_BINARY; + break; + } + + /* + * Alloc vectors for variable IDs, perm IDs and support IDs. + * +1 to include a slot for terminals. + */ + + ids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (ids==NULL, "Error allocating memory.", failure); + permids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (permids==NULL, "Error allocating memory.", failure); + invpermids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (invpermids==NULL, "Error allocating memory.", + failure); + supportids = DDDMP_ALLOC (int, nVars+1); + Dddmp_CheckAndGotoLabel (supportids==NULL, "Error allocating memory.", + failure); + + for (i=0; iindex] = scan->index; + permids[scan->index] = ddMgr->perm[scan->index]; + invpermids[ddMgr->perm[scan->index]] = scan->index; + scan = cuddT (scan); + } + Cudd_RecursiveDeref (ddMgr, support); + } + /* so that we do not try to free it in case of failure */ + support = NULL; + + /* + * Set supportids to incremental (shrinked) values following the ordering. + */ + + for (i=0, var=0; i= 0) { + supportids[invpermids[i]] = var++; + } + } + /* set a dummy id for terminal nodes */ + supportids[nVars] = var; + + /* + * Select conversion array for extra var info + */ + + switch (mode) { + case DDDMP_MODE_TEXT: + switch (varinfo) { + case DDDMP_VARIDS: + outids = ids; + break; + case DDDMP_VARPERMIDS: + outids = permids; + break; + case DDDMP_VARAUXIDS: + outids = auxids; + break; + case DDDMP_VARNAMES: + outvarnames = varnames; + break; + case DDDMP_VARDEFAULT: + break; + } + break; + case DDDMP_MODE_BINARY: + outids = NULL; + break; + } + + /* + * Number dd nodes and count them (numbering is from 1 to nnodes) + */ + + nnodes = DddmpNumberBddNodes (ddMgr, f, nRoots); + + /* + * Start Header + */ + +#ifdef DDDMP_VERSION + retValue = fprintf (fp, ".ver %s\n", DDDMP_VERSION); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); +#endif + + retValue = fprintf (fp, ".mode %c\n", mode); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (mode == DDDMP_MODE_TEXT) { + retValue = fprintf (fp, ".varinfo %d\n", varinfo); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + if (ddname != NULL) { + retValue = fprintf (fp, ".dd %s\n",ddname); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, ".nnodes %d\n", nnodes); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nvars %d\n", nVars); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nsuppvars %d\n", var); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /*------------ Write the Var Names by scanning the ids array -------------*/ + + if (varnames != NULL) { + + retValue = fprintf (fp, ".suppvarnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; i= 0) { + if (varnames[ids[i]] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. DUMMY%d generated\n", i); + fflush (stderr); + varnames[ids[i]] = DDDMP_ALLOC (char, 10); + Dddmp_CheckAndGotoLabel (varnames[ids[i]] == NULL, + "Error allocating memory.", failure); + sprintf (varnames[ids[i]], "DUMMY%d", i); + } + retValue = fprintf (fp, " %s", varnames[ids[i]]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /*--------- Write the Var SUPPORT Names by scanning the ids array ---------*/ + + if (varnames != NULL) { + retValue = fprintf (fp, ".orderedvarnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; iinvperm[i]] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. DUMMY%d generated\n", i); + fflush (stderr); + varnames[ddMgr->invperm[i]] = DDDMP_ALLOC (char, 10); + Dddmp_CheckAndGotoLabel (varnames[ddMgr->invperm[i]] == NULL, + "Error allocating memory.", failure); + sprintf (varnames[ddMgr->invperm[i]], "DUMMY%d", i); + } + + retValue = fprintf (fp, " %s", varnames[ddMgr->invperm[i]]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /*------------ Write the var ids by scanning the ids array ---------------*/ + + retValue = fprintf (fp, ".ids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; i= 0) { + retValue = fprintf (fp, " %d", i); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * Write the var permids by scanning the permids array. + */ + + retValue = fprintf (fp, ".permids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + for (i = 0; i < nVars; i++) { + if (permids[i] >= 0) { + retValue = fprintf (fp, " %d", permids[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (auxids != NULL) { + + /* + * Write the var auxids by scanning the ids array. + */ + + retValue = fprintf (fp, ".auxids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + for (i = 0; i < nVars; i++) { + if (ids[i] >= 0) { + retValue = fprintf (fp, " %d", auxids[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /* + * Write the roots info. + */ + + retValue = fprintf (fp, ".nroots %d\n", nRoots); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (rootnames != NULL) { + + /* + * Write the root names. + */ + + retValue = fprintf (fp, ".rootnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i = 0; i < nRoots; i++) { + if (rootnames[i] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. ROOT%d generated\n",i); + fflush (stderr); + rootnames[i] = DDDMP_ALLOC(char,10); + Dddmp_CheckAndGotoLabel (rootnames[i]==NULL, + "Error writing to file.", failure); + sprintf(rootnames[ids[i]], "ROOT%d",i); + } + retValue = fprintf (fp, " %s", rootnames[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, ".rootids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * Write BDD indexes of function roots. + * Use negative integers for complemented edges. + */ + + for (i = 0; i < nRoots; i++) { + if (f[i] == NULL) { + (void) fprintf (stderr, "DdStore Warning: %d-th root is NULL\n",i); + fflush (stderr); + retValue = fprintf (fp, " 0"); + } + if (Cudd_IsComplement(f[i])) { + retValue = fprintf (fp, " -%d", + DddmpReadNodeIndexBdd (Cudd_Regular (f[i]))); + } else { + retValue = fprintf (fp, " %d", + DddmpReadNodeIndexBdd (Cudd_Regular (f[i]))); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nodes\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * END HEADER + */ + + /* + * Call the function that really gets the job done. + */ + + for (i = 0; i < nRoots; i++) { + if (f[i] != NULL) { + retValue = NodeStoreRecurBdd (ddMgr, Cudd_Regular(f[i]), + mode, supportids, outvarnames, outids, fp); + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "Error writing to file.", failure); + } + } + + /* + * Write trailer and return. + */ + + retValue = fprintf (fp, ".end\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (fileToClose) { + fclose (fp); + } + + DddmpUnnumberBddNodes (ddMgr, f, nRoots); + DDDMP_FREE (ids); + DDDMP_FREE (permids); + DDDMP_FREE (invpermids); + DDDMP_FREE (supportids); + + return (DDDMP_SUCCESS); + + failure: + + if (ids != NULL) { + DDDMP_FREE (ids); + } + if (permids != NULL) { + DDDMP_FREE (permids); + } + if (invpermids != NULL) { + DDDMP_FREE (invpermids); + } + if (supportids != NULL) { + DDDMP_FREE (supportids); + } + if (support != NULL) { + Cudd_RecursiveDeref (ddMgr, support); + } + + return (DDDMP_FAILURE); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Dddmp_bddStore.] + + Description [Stores a node to file in either test or binary mode. + In text mode a node is represented (on a text line basis) as +
            +
          • node-index \[var-extrainfo\] var-index Then-index Else-index +
          + + where all indexes are integer numbers and var-extrainfo + (optional redundant field) is either an integer or a string + (variable name). Node-index is redundant (due to the node + ordering) but we keep it for readability.

          + + In binary mode nodes are represented as a sequence of bytes, + representing var-index, Then-index, and Else-index in an + optimized way. Only the first byte (code) is mandatory. + Integer indexes are represented in absolute or relative mode, + where relative means offset wrt. a Then/Else node info. + Suppose Var(NodeId), Then(NodeId) and Else(NodeId) represent + infos about a given node.

          + + The generic "NodeId" node is stored as + +

            +
          • code-byte +
          • \[var-info\] +
          • \[Then-info\] +
          • \[Else-info\] +
          + + where code-byte contains bit fields + +
            +
          • Unused : 1 bit +
          • Variable: 2 bits, one of the following codes +
              +
            • DDDMP_ABSOLUTE_ID var-info = Var(NodeId) follows +
            • DDDMP_RELATIVE_ID Var(NodeId) is represented in relative form as + var-info = Min(Var(Then(NodeId)),Var(Else(NodeId))) -Var(NodeId) +
            • DDDMP_RELATIVE_1 No var-info follows, because + Var(NodeId) = Min(Var(Then(NodeId)),Var(Else(NodeId)))-1 +
            • DDDMP_TERMINAL Node is a terminal, no var info required +
            +
          • T : 2 bits, with codes similar to V +
              +
            • DDDMP_ABSOLUTE_ID Then-info = Then(NodeId) follows +
            • DDDMP_RELATIVE_ID Then(NodeId) is represented in relative form as + Then-info = Nodeid-Then(NodeId) +
            • DDDMP_RELATIVE_1 No info on Then(NodeId) follows, because + Then(NodeId) = NodeId-1 +
            • DDDMP_TERMINAL Then Node is a terminal, no info required (for BDDs) +
            +
          • Ecompl : 1 bit, if 1 means complemented edge +
          • E : 2 bits, with codes and meanings as for the Then edge +
          + var-info, Then-info, Else-info (if required) are represented as unsigned + integer values on a sufficient set of bytes (MSByte first). + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +NodeStoreRecurBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: store file */ + ) +{ + DdNode *T = NULL; + DdNode *E = NULL; + int idf = (-1); + int idT = (-1); + int idE = (-1); + int vf = (-1); + int vT = (-1); + int vE = (-1); + int retValue; + int nVars; + + nVars = ddMgr->size; + T = E = NULL; + idf = idT = idE = (-1); + +#ifdef DDDMP_DEBUG + assert(!Cudd_IsComplement(f)); + assert(f!=NULL); + assert(supportids!=NULL); +#endif + + /* If already visited, nothing to do. */ + if (DddmpVisitedBdd (f)) { + return (DDDMP_SUCCESS); + } + + /* Mark node as visited. */ + DddmpSetVisitedBdd (f); + + if (Cudd_IsConstant(f)) { + /* Check for special case: don't recur */ + idf = DddmpReadNodeIndexBdd (f); + } else { + +#ifdef DDDMP_DEBUG + /* BDDs! Only one constant supported */ + assert (!cuddIsConstant(f)); +#endif + + /* + * Recursive call for Then edge + */ + + T = cuddT(f); +#ifdef DDDMP_DEBUG + /* ROBDDs! No complemented Then edge */ + assert (!Cudd_IsComplement(T)); +#endif + /* recur */ + retValue = NodeStoreRecurBdd (ddMgr, T, mode, supportids, varnames, outids, + fp); + if (retValue != DDDMP_SUCCESS) { + return (retValue); + } + + /* + * Recursive call for Else edge + */ + + E = Cudd_Regular (cuddE (f)); + retValue = NodeStoreRecurBdd (ddMgr, E, mode, supportids, varnames, outids, + fp); + if (retValue != DDDMP_SUCCESS) { + return (retValue); + } + + /* + * Obtain nodeids and variable ids of f, T, E + */ + + idf = DddmpReadNodeIndexBdd (f); + vf = f->index; + + idT = DddmpReadNodeIndexBdd (T); + if (Cudd_IsConstant(T)) { + vT = nVars; + } else { + vT = T->index; + } + + idE = DddmpReadNodeIndexBdd (E); + if (Cudd_IsConstant(E)) { + vE = nVars; + } else { + vE = E->index; + } + } + + switch (mode) { + case DDDMP_MODE_TEXT: + retValue = NodeTextStoreBdd (ddMgr, f, mode, supportids, varnames, + outids, fp, idf, vf, idT, idE); + break; + case DDDMP_MODE_BINARY: + retValue = NodeBinaryStoreBdd (ddMgr, f, mode, supportids, varnames, + outids, fp, idf, vf, idT, idE, vT, vE, T, E); + break; + default: + return (DDDMP_FAILURE); + } + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Store One Single Node in Text Format.] + + Description [Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. + ] + + SideEffects [None] + + SeeAlso [NodeBinaryStoreBdd] + +******************************************************************************/ + +static int +NodeTextStoreBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: Store file */, + int idf /* IN: index of the current node */, + int vf /* IN: variable of the current node */, + int idT /* IN: index of the Then node */, + int idE /* IN: index of the Else node */ + ) +{ + int retValue = EOF; + + /* + * Check for Constant + */ + + if (Cudd_IsConstant(f)) { + + if (f == Cudd_ReadOne(ddMgr)) { + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T 1 0 0\n", idf); + } else { + retValue = fprintf (fp, "%d 1 0 0\n", idf); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + if (f == Cudd_ReadZero(ddMgr)) { + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T 0 0 0\n", idf); + } else { + retValue = fprintf (fp, "%d 0 0 0\n", idf); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * A constant node different from 1: an ADD constant + */ + + Dddmp_CheckAndReturn (((varnames!=NULL)||(outids!=NULL)), + "Error writing to file: ADD Type."); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * ... Not A Constant + */ + + if (Cudd_IsComplement (cuddE(f))) { + idE = -idE; + } + + if (varnames != NULL) { + retValue = fprintf (fp, "%d %s %d %d %d\n", + idf, varnames[vf], supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + if (outids != NULL) { + retValue = fprintf (fp, "%d %d %d %d %d\n", + idf, outids[vf], supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + retValue = fprintf (fp, "%d %d %d %d\n", + idf, supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } +} + +/**Function******************************************************************** + + Synopsis [Store One Single Node in Binary Format.] + + Description [Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. + Store every information as coded binary values.] + + SideEffects [None] + + SeeAlso [NodeTextStoreBdd] + +******************************************************************************/ + +static int +NodeBinaryStoreBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: store file */, + int idf /* IN: index of the node */, + int vf /* IN: variable of the node */, + int idT /* IN: index of the Then node */, + int idE /* IN: index of the Else node */, + int vT /* IN: variable of the Then node */, + int vE /* IN: variable of the Else node */, + DdNode *T /* IN: Then node */, + DdNode *E /* IN: Else node */ + ) +{ + int retValue, diff, var; + struct binary_dd_code code; + + /* + * Check for Constant + */ + + /* only integer ids used, varnames ignored */ + /* Terminal one is coded as DDDMP_TERMINAL, all other fields are 0 */ + if (Cudd_IsConstant(f)) { + code.Unused = 0; + code.V = DDDMP_TERMINAL; + code.T = 0; + code.E = 0; + code.Ecompl = 0; + retValue = DddmpWriteCode (fp,code); + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * Non terminal: output variable id + */ + + var = supportids[vf]; + diff = (supportids[vT] +#include "dddmpInt.h" + +/*-------------------------------1--------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMP_DEBUG_CNF 0 + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define GET_MAX(x,y) (x>y?x:y) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpCuddBddArrayStoreCnf(DdManager *ddMgr, DdNode **f, int rootN, Dddmp_DecompCnfStoreType mode, int noHeader, char **varNames, int *bddIds, int *bddAuxIds, int *cnfIds, int idInitial, int edgeInTh, int pathLengthTh, char *fname, FILE *fp, int *clauseNPtr, int *varNewNPtr); +static int StoreCnfNodeByNode(DdManager *ddMgr, DdNode **f, int rootN, int *bddIds, int *cnfIds, FILE *fp, int *clauseN, int *varMax, int *rootStartLine); +static int StoreCnfNodeByNodeRecur(DdManager *ddMgr, DdNode *f, int *bddIds, int *cnfIds, FILE *fp, int *clauseN, int *varMax); +static int StoreCnfOneNode(DdNode *f, int idf, int vf, int idT, int idE, FILE *fp, int *clauseN, int *varMax); +static int StoreCnfMaxtermByMaxterm(DdManager *ddMgr, DdNode **f, int rootN, int *bddIds, int *cnfIds, int idInitial, FILE *fp, int *varMax, int *clauseN, int *rootStartLine); +static int StoreCnfBest(DdManager *ddMgr, DdNode **f, int rootN, int *bddIds, int *cnfIds, int idInitial, FILE *fp, int *varMax, int *clauseN, int *rootStartLine); +static void StoreCnfMaxtermByMaxtermRecur(DdManager *ddMgr, DdNode *node, int *bddIds, int *cnfIds, FILE *fp, int *list, int *clauseN, int *varMax); +static int StoreCnfBestNotSharedRecur(DdManager *ddMgr, DdNode *node, int idf, int *bddIds, int *cnfIds, FILE *fp, int *list, int *clauseN, int *varMax); +static int StoreCnfBestSharedRecur(DdManager *ddMgr, DdNode *node, int *bddIds, int *cnfIds, FILE *fp, int *list, int *clauseN, int *varMax); +static int printCubeCnf(DdManager *ddMgr, DdNode *node, int *cnfIds, FILE *fp, int *list, int *varMax); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a CNF format. + ] + + Description [Dumps the argument BDD to file. + This task is performed by calling the function + Dddmp_cuddBddArrayStoreCnf. + ] + + SideEffects [Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. + ] + + SeeAlso [Dddmp_cuddBddArrayStoreCnf] + +******************************************************************************/ + +int +Dddmp_cuddBddStoreCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: BDD root to be stored */, + Dddmp_DecompCnfStoreType mode /* IN: format selection */, + int noHeader /* IN: do not store header iff 1 */, + char **varNames /* IN: array of variable names (or NULL) */, + int *bddIds /* IN: array of var ids */, + int *bddAuxIds /* IN: array of BDD node Auxiliary Ids */, + int *cnfIds /* IN: array of CNF var ids */, + int idInitial /* IN: starting id for cutting variables */, + int edgeInTh /* IN: Max # Incoming Edges */, + int pathLengthTh /* IN: Max Path Length */, + char *fname /* IN: file name */, + FILE *fp /* IN: pointer to the store file */, + int *clauseNPtr /* OUT: number of clause stored */, + int *varNewNPtr /* OUT: number of new variable created */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStoreCnf (ddMgr, tmpArray, 1, mode, + noHeader, varNames, bddIds, bddAuxIds, cnfIds, idInitial, edgeInTh, + pathLengthTh, fname, fp, clauseNPtr, varNewNPtr); + + Dddmp_CheckAndReturn (retValue==DDDMP_FAILURE, "Failure."); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument array of BDDs + in CNF format. + ] + + Description [Dumps the argument array of BDDs to file.] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + Three methods are allowed: + * NodeByNode method: Insert a cut-point for each BDD node (but the + terminal nodes) + * MaxtermByMaxterm method: Insert no cut-points, i.e. the off-set of + trhe function is stored + * Best method: Tradeoff between the previous two methods. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. + The stored file can contain a file header or not depending on the + noHeader parameter (IFF 0, usual setting, the header is usually stored. + This option can be useful in storing multiple BDDs, as separate BDDs, + on the same file leaving the opening of the file to the caller. + ] + + SeeAlso [] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStoreCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDD roots to be stored */, + int rootN /* IN: # output BDD roots to be stored */, + Dddmp_DecompCnfStoreType mode /* IN: format selection */, + int noHeader /* IN: do not store header iff 1 */, + char **varNames /* IN: array of variable names (or NULL) */, + int *bddIds /* IN: array of converted var IDs */, + int *bddAuxIds /* IN: array of BDD node Auxiliary Ids */, + int *cnfIds /* IN: array of converted var IDs */, + int idInitial /* IN: starting id for cutting variables */, + int edgeInTh /* IN: Max # Incoming Edges */, + int pathLengthTh /* IN: Max Path Length */, + char *fname /* IN: file name */, + FILE *fp /* IN: pointer to the store file */, + int *clauseNPtr /* OUT: number of clause stored */, + int *varNewNPtr /* OUT: number of new variable created */ + ) +{ + int retValue2; + +#if 0 +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValue1; + + retValue1 = Cudd_DebugCheck (ddMgr); + Dddmp_CheckAndReturn (retValue1==1, + "Inconsistency Found During CNF Store."); + Dddmp_CheckAndReturn (retValue1==CUDD_OUT_OF_MEM, + "Out of Memory During CNF Store."); +#endif +#endif +#endif + + retValue2 = DddmpCuddBddArrayStoreCnf (ddMgr, f, rootN, mode, noHeader, + varNames, bddIds, bddAuxIds, cnfIds, idInitial, edgeInTh, pathLengthTh, + fname, fp, clauseNPtr, varNewNPtr); + +#if 0 +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValue1 = Cudd_DebugCheck (ddMgr); + Dddmp_CheckAndReturn (retValue1==1, + "Inconsistency Found During CNF Store."); + Dddmp_CheckAndReturn (retValue1==CUDD_OUT_OF_MEM, + "Out of Memory During CNF Store."); +#endif +#endif +#endif + + return (retValue2); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of + BDDs in the CNF standard format. + ] + + Description [Dumps the argument array of BDDs/ADDs to file in CNF format. + The following arrays: varNames, bddIds, bddAuxIds, and cnfIds + fix the correspondence among variable names, BDD ids, BDD + auxiliary ids and the ids used to store the CNF problem. + All these arrays are automatically created iff NULL. + Auxiliary variable, iff necessary, are created starting from value + idInitial. + Iff idInitial is <= 0 its value is selected as the number of internal + CUDD variable + 2. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. + ] + + SideEffects [Nodes are temporarily removed from the unique hash table. + They are re-linked after the store operation in a modified + order. + ] + + SeeAlso [Dddmp_cuddBddStore] + +******************************************************************************/ + +static int +DddmpCuddBddArrayStoreCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDD roots to be stored */, + int rootN /* IN: # of output BDD roots to be stored */, + Dddmp_DecompCnfStoreType mode /* IN: format selection */, + int noHeader /* IN: do not store header iff 1 */, + char **varNames /* IN: array of variable names (or NULL) */, + int *bddIds /* IN: array of BDD node Ids (or NULL) */, + int *bddAuxIds /* IN: array of BDD Aux Ids (or NULL) */, + int *cnfIds /* IN: array of CNF ids (or NULL) */, + int idInitial /* IN: starting id for cutting variables */, + int edgeInTh /* IN: Max # Incoming Edges */, + int pathLengthTh /* IN: Max Path Length */, + char *fname /* IN: file name */, + FILE *fp /* IN: pointer to the store file */, + int *clauseNPtr /* OUT: number of clause stored */, + int *varNewNPtr /* OUT: number of new variable created */ + ) +{ + DdNode *support = NULL; + DdNode *scan = NULL; + int *bddIdsInSupport = NULL; + int *permIdsInSupport = NULL; + int *rootStartLine = NULL; + int nVar, nVarInSupport, retValue, i, j, fileToClose; + int varMax, clauseN, flagVar, intStringLength; + int bddIdsToFree = 0; + int bddAuxIdsToFree = 0; + int cnfIdsToFree = 0; + int varNamesToFree = 0; + char intString[DDDMP_MAXSTRLEN]; + char tmpString[DDDMP_MAXSTRLEN]; + fpos_t posFile1, posFile2; + + /*---------------------------- Set Initial Values -------------------------*/ + + support = scan = NULL; + bddIdsInSupport = permIdsInSupport = rootStartLine = NULL; + nVar = ddMgr->size; + fileToClose = 0; + sprintf (intString, "%d", INT_MAX); + intStringLength = strlen (intString); + + /*---------- Check if File needs to be opened in the proper mode ----------*/ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /*--------- Generate Bdd LOCAL IDs and Perm IDs and count them ------------*/ + + /* BDD Ids */ + bddIdsInSupport = DDDMP_ALLOC (int, nVar); + Dddmp_CheckAndGotoLabel (bddIdsInSupport==NULL, "Error allocating memory.", + failure); + /* BDD PermIds */ + permIdsInSupport = DDDMP_ALLOC (int, nVar); + Dddmp_CheckAndGotoLabel (permIdsInSupport==NULL, "Error allocating memory.", + failure); + /* Support Size (Number of BDD Ids-PermIds */ + nVarInSupport = 0; + + for (i=0; iindex] = scan->index; + permIdsInSupport[scan->index] = ddMgr->perm[scan->index]; + scan = cuddT (scan); + } + Cudd_RecursiveDeref (ddMgr, support); + } + /* so that we do not try to free it in case of failure */ + support = NULL; + + /*---------------------------- Start HEADER -------------------------------*/ + + if (noHeader==0) { + + retValue = fprintf (fp, + "c # BDD stored by the DDDMP tool in CNF format\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing on file.", + failure); + fprintf (fp, "c #\n"); + } + + /*-------------------- Generate Bdd IDs IFF necessary ---------------------*/ + + if (bddIds == NULL) { + if (noHeader==0) { + fprintf (fp, "c # Warning: BDD IDs missing ... evaluating them.\n"); + fprintf (fp, "c # \n"); + fflush (fp); + } + + bddIdsToFree = 1; + bddIds = DDDMP_ALLOC (int, nVar); + Dddmp_CheckAndGotoLabel (bddIds==NULL, "Error allocating memory.", + failure); + + /* Get BDD-IDs Directly from Cudd Manager */ + for (i=0; i= 0) { + fprintf (fp, " %s", varNames[i]); + } + } + fprintf (fp, "\n"); + } + + /* Ordered Variable Names */ + if (varNames != NULL) { + fprintf (fp, "c .orderedvarnames"); + for (i=0; i= 0) { + fprintf (fp, " %d", bddIdsInSupport[i]); + } + } + fprintf (fp, "\n"); + + /* BDD Variable Permutation Ids */ + fprintf (fp, "c .permids "); + for (i=0; i= 0) { + fprintf (fp, " %d", permIdsInSupport[i]); + } + } + fprintf (fp, "\n"); + + /* BDD Variable Auxiliary Ids */ + fprintf (fp, "c .auxids "); + for (i=0; i= 0) { + fprintf (fp, " %d", bddAuxIds[i]); + } + } + fprintf (fp, "\n"); + + /* CNF Ids */ + fprintf (fp, "c .cnfids "); + for (i=0; i= 0) { + fprintf (fp, " %d", cnfIds[i]); + } + } + fprintf (fp, "\n"); + + /* Number of Roots */ + fprintf (fp, "c .nroots %d", rootN); + fprintf (fp, "\n"); + + /* Root Starting Line */ + fgetpos (fp, &posFile1); + fprintf (fp, "c .rootids"); + for (i=0; i \n", i); +#endif + if (Cudd_IsComplement (f[i])) { + retValue = fprintf (fp, "-%d 0\n", idf); + } else { + retValue = fprintf (fp, "%d 0\n", idf); + } + *varMax = GET_MAX (*varMax, idf); + *clauseN = *clauseN + 1; + + if (retValue == EOF) { + (void) fprintf (stderr, + "DdStoreCnf: Error in recursive node store\n"); + fflush (stderr); + } + } + } + } + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Dddmp_bddStore.] + + Description [Performs the recursive step of Dddmp_bddStore. + Traverse the BDD and store a CNF formula for each "terminal" node. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +StoreCnfNodeByNodeRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: BDD node to be stored */, + int *bddIds /* IN: BDD ids for variables */, + int *cnfIds /* IN: CNF ids for variables */, + FILE *fp /* IN: store file */, + int *clauseN /* OUT: number of clauses written in the CNF file */, + int *varMax /* OUT: maximum value of id written in the CNF file */ + ) +{ + DdNode *T, *E; + int idf, idT, idE, vf; + int retValue; + +#ifdef DDDMP_DEBUG + assert(!Cudd_IsComplement(f)); + assert(f!=NULL); +#endif + + /* If constant, nothing to do. */ + if (Cudd_IsConstant(f)) { + return (1); + } + + /* If already visited, nothing to do. */ + if (DddmpVisitedCnf (f)) { + return (1); + } + + /* Mark node as visited. */ + DddmpSetVisitedCnf (f); + + /*------------------ Non Terminal Node -------------------------------*/ + +#ifdef DDDMP_DEBUG + /* BDDs! Only one constant supported */ + assert (!cuddIsConstant(f)); +#endif + + /* + * Recursive call for Then edge + */ + + T = cuddT (f); +#ifdef DDDMP_DEBUG + /* ROBDDs! No complemented Then edge */ + assert (!Cudd_IsComplement(T)); +#endif + /* recur */ + retValue = StoreCnfNodeByNodeRecur (ddMgr, T, bddIds, cnfIds, fp, + clauseN, varMax); + if (retValue != 1) { + return(retValue); + } + + /* + * Recursive call for Else edge + */ + + E = Cudd_Regular (cuddE (f)); + retValue = StoreCnfNodeByNodeRecur (ddMgr, E, bddIds, cnfIds, fp, + clauseN, varMax); + if (retValue != 1) { + return (retValue); + } + + /* + * Obtain nodeids and variable ids of f, T, E + */ + + idf = DddmpReadNodeIndexCnf (f); + vf = f->index; + + if (bddIds[vf] != vf) { + (void) fprintf (stderr, "DdStoreCnf: Error writing to file\n"); + fflush (stderr); + return (0); + } + + idT = DddmpReadNodeIndexCnf (T); + + idE = DddmpReadNodeIndexCnf (E); + if (Cudd_IsComplement (cuddE (f))) { + idE = -idE; + } + + retValue = StoreCnfOneNode (f, idf, cnfIds[vf], idT, idE, fp, + clauseN, varMax); + + if (retValue == EOF) { + return (0); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Store One Single BDD Node.] + + Description [Store One Single BDD Node translating it as a multiplexer.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +StoreCnfOneNode ( + DdNode *f /* IN: node to be stored */, + int idf /* IN: node CNF Index */, + int vf /* IN: node BDD Index */, + int idT /* IN: Then CNF Index with sign = inverted edge */, + int idE /* IN: Else CNF Index with sign = inverted edge */, + FILE *fp /* IN: store file */, + int *clauseN /* OUT: number of clauses */, + int *varMax /* OUT: maximun Index of variable stored */ + ) +{ + int retValue = 0; + int idfAbs, idTAbs, idEAbs; + + idfAbs = abs (idf); + idTAbs = abs (idT); + idEAbs = abs (idE); + + /*----------------------------- Check for Constant ------------------------*/ + + assert(!Cudd_IsConstant(f)); + + /*------------------------- Check for terminal nodes ----------------------*/ + + if ((idTAbs==1) && (idEAbs==1)) { + return (1); + } + + /*------------------------------ Internal Node ----------------------------*/ + +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "id=%d var=%d idT=%d idE=%d\n", + idf, vf, idT, idE); +#endif + + /* + * Then to terminal + */ + + if ((idTAbs==1) && (idEAbs!=1)) { +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "CASE 1 -->\n"); +#endif + retValue = fprintf (fp, "%d %d 0\n", + idf, -vf); + retValue = fprintf (fp, "%d %d 0\n", + idf, -idE); + retValue = fprintf (fp, "%d %d %d 0\n", + -idf, vf, idE); + *clauseN = *clauseN + 3; + + *varMax = GET_MAX (*varMax, idfAbs); + *varMax = GET_MAX (*varMax, vf); + *varMax = GET_MAX (*varMax, idEAbs); + } + + /* + * Else to terminal + */ + + if ((idTAbs!=1) && (idEAbs==1)) { + if (idE == 1) { +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "CASE 2 -->\n"); +#endif + retValue = fprintf (fp, "%d %d 0\n", + idf, vf); + retValue = fprintf (fp, "%d %d 0\n", + idf, -idT); + retValue = fprintf (fp, "%d %d %d 0\n", + -idf, -vf, idT); + } else { +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "CASE 3 -->\n"); +#endif + retValue = fprintf (fp, "%d %d 0\n", + -idf, vf); + retValue = fprintf (fp, "%d %d 0\n", + -idf, idT); + retValue = fprintf (fp, "%d %d %d 0\n", + idf, -vf, -idT); + } + + *varMax = GET_MAX (*varMax, idfAbs); + *varMax = GET_MAX (*varMax, vf); + *varMax = GET_MAX (*varMax, idTAbs); + + *clauseN = *clauseN + 3; + } + + /* + * Nor Then or Else to terminal + */ + + if ((idTAbs!=1) && (idEAbs!=1)) { +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "CASE 4 -->\n"); +#endif + retValue = fprintf (fp, "%d %d %d 0\n", + idf, vf, -idE); + retValue = fprintf (fp, "%d %d %d 0\n", + -idf, vf, idE); + retValue = fprintf (fp, "%d %d %d 0\n", + idf, -vf, -idT); + retValue = fprintf (fp, "%d %d %d 0\n", + -idf, -vf, idT); + + *varMax = GET_MAX (*varMax, idfAbs); + *varMax = GET_MAX (*varMax, vf); + *varMax = GET_MAX (*varMax, idTAbs); + *varMax = GET_MAX (*varMax, idEAbs); + + *clauseN = *clauseN + 4; + } + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Prints a disjoint sum of products.] + + Description [Prints a disjoint sum of product cover for the function + rooted at node. Each product corresponds to a path from node a + leaf node different from the logical zero, and different from + the background value. Uses the standard output. Returns 1 if + successful, 0 otherwise. + ] + + SideEffects [None] + + SeeAlso [StoreCnfBest] + +******************************************************************************/ + +static int +StoreCnfMaxtermByMaxterm ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs to store */, + int rootN /* IN: number of BDDs in the array */, + int *bddIds /* IN: BDD Identifiers */, + int *cnfIds /* IN: corresponding CNF Identifiers */, + int idInitial /* IN: initial value for numbering new CNF variables */, + FILE *fp /* IN: file pointer */, + int *varMax /* OUT: maximum identifier of the variables created */, + int *clauseN /* OUT: number of stored clauses */, + int *rootStartLine /* OUT: line where root starts */ + ) +{ + int i, j, *list; + + list = DDDMP_ALLOC (int, ddMgr->size); + if (list == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + return (DDDMP_FAILURE); + } + + for (i=0; isize; j++) { + list[j] = 2; + } + + /* + * Set Starting Line for this Root + */ + + rootStartLine[i] = *clauseN + 1; + + StoreCnfMaxtermByMaxtermRecur (ddMgr, f[i], bddIds, cnfIds, fp, + list, clauseN, varMax); + } + } + } + + FREE (list); + + return (1); +} + +/**Function******************************************************************** + + Synopsis [Prints a disjoint sum of products with intermediate + cutting points.] + + Description [Prints a disjoint sum of product cover for the function + rooted at node intorducing cutting points whenever necessary. + Each product corresponds to a path from node a leaf + node different from the logical zero, and different from the + background value. Uses the standard output. Returns 1 if + successful, 0 otherwise. + ] + + SideEffects [None] + + SeeAlso [StoreCnfMaxtermByMaxterm] + +******************************************************************************/ + +static int +StoreCnfBest ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs to store */, + int rootN /* IN: number of BDD in the array */, + int *bddIds /* IN: BDD identifiers */, + int *cnfIds /* IN: corresponding CNF identifiers */, + int idInitial /* IN: initial value for numbering new CNF variables */, + FILE *fp /* IN: file pointer */, + int *varMax /* OUT: maximum identifier of the variables created */, + int *clauseN /* OUT: number of stored clauses */, + int *rootStartLine /* OUT: line where root starts */ + ) +{ + int i, j, *list; + + list = DDDMP_ALLOC (int, ddMgr->size); + if (list == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + return (DDDMP_FAILURE); + } + + for (i=0; isize; j++) { + list[j] = 2; + } + + /* + * Set Starting Line for this Root + */ + + rootStartLine[i] = *clauseN + 1; + +#if DDDMP_DEBUG_CNF + fprintf (fp, "root NOT shared BDDs %d --> \n", i); +#endif + StoreCnfBestNotSharedRecur (ddMgr, f[i], 0, bddIds, cnfIds, fp, list, + clauseN, varMax); + +#if DDDMP_DEBUG_CNF + fprintf (fp, "root SHARED BDDs %d --> \n", i); +#endif + StoreCnfBestSharedRecur (ddMgr, Cudd_Regular (f[i]), bddIds, cnfIds, + fp, list, clauseN, varMax); + } + } + } + +#if DDDMP_DEBUG_CNF + fprintf (stdout, "###---> BDDs After the Storing Process:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + FREE (list); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Print Maxterm.] + + Description [Performs the recursive step of Print Maxterm. + Traverse a BDD a print out a cube in CNF format each time a terminal + node is reached. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static void +StoreCnfMaxtermByMaxtermRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *node /* IN: BDD to store */, + int *bddIds /* IN: BDD identifiers */, + int *cnfIds /* IN: corresponding CNF identifiers */, + FILE *fp /* IN: file pointer */, + int *list /* IN: temporary array to store cubes */, + int *clauseN /* OUT: number of stored clauses */, + int *varMax /* OUT: maximum identifier of the variables created */ + ) +{ + DdNode *N, *Nv, *Nnv; + int retValue, index; + + N = Cudd_Regular (node); + + /* + * Terminal case: Print one cube based on the current recursion + */ + + if (cuddIsConstant (N)) { + retValue = printCubeCnf (ddMgr, node, cnfIds, fp, list, varMax); + if (retValue == DDDMP_SUCCESS) { + fprintf (fp, "0\n"); + *clauseN = *clauseN + 1; + } + return; + } + + /* + * NON Terminal case: Recur + */ + + Nv = cuddT (N); + Nnv = cuddE (N); + if (Cudd_IsComplement (node)) { + Nv = Cudd_Not (Nv); + Nnv = Cudd_Not (Nnv); + } + index = N->index; + + /* + * StQ 06.05.2003 + * Perform the optimization: + * f = (a + b)' = (a') ^ (a + b') = (a') ^ (b') + * i.e., if the THEN node is the constant ZERO then that variable + * can be forgotten (list[index] = 2) for subsequent ELSE cubes + */ + if (cuddIsConstant (Cudd_Regular (Nv)) && Nv != ddMgr->one) { + list[index] = 2; + } else { + list[index] = 0; + } + StoreCnfMaxtermByMaxtermRecur (ddMgr, Nnv, bddIds, cnfIds, fp, list, + clauseN, varMax); + + /* + * StQ 06.05.2003 + * Perform the optimization: + * f = a ^ b = (a) ^ (a' + b) = (a) ^ (b) + * i.e., if the ELSE node is the constant ZERO then that variable + * can be forgotten (list[index] = 2) for subsequent THEN cubes + */ + if (cuddIsConstant (Cudd_Regular (Nnv)) && Nnv != ddMgr->one) { + list[index] = 2; + } else { + list[index] = 1; + } + StoreCnfMaxtermByMaxtermRecur (ddMgr, Nv, bddIds, cnfIds, fp, list, + clauseN, varMax); + list[index] = 2; + + return; +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Print Best on Not Shared + sub-BDDs.] + + Description [Performs the recursive step of Print Best on Not Shared + sub-BDDs, i.e., print out information for the nodes belonging to + BDDs not shared (whose root has just one incoming edge). + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +StoreCnfBestNotSharedRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *node /* IN: BDD to store */, + int idf /* IN: Id to store */, + int *bddIds /* IN: BDD identifiers */, + int *cnfIds /* IN: corresponding CNF identifiers */, + FILE *fp /* IN: file pointer */, + int *list /* IN: temporary array to store cubes */, + int *clauseN /* OUT: number of stored clauses */, + int *varMax /* OUT: maximum identifier of the variables created */ + ) +{ + DdNode *N, *Nv, *Nnv; + int index, retValue; + DdNode *one; + + one = ddMgr->one; + + N = Cudd_Regular (node); + + /* + * Terminal case or Already Visited: + * Print one cube based on the current recursion + */ + + if (cuddIsConstant (N)) { + retValue = printCubeCnf (ddMgr, node, cnfIds, fp, list, varMax); + if (retValue == DDDMP_SUCCESS) { + if (idf != 0) { + fprintf (fp, "%d ", idf); + } + fprintf (fp, "0\n"); + *varMax = GET_MAX (*varMax, abs(idf)); + *clauseN = *clauseN + 1; + } + return (DDDMP_SUCCESS); + } + + /* + * Shared Sub-Tree: Print Cube + */ + + index = DddmpReadNodeIndexCnf (N); + if (index > 0) { + if (idf != 0) { + fprintf (fp, "%d ", idf); + } + if (Cudd_IsComplement (node)) { + retValue = fprintf (fp, "-%d ", index); + } else { + retValue = fprintf (fp, "%d ", index); + } + retValue = printCubeCnf (ddMgr, node, cnfIds, fp, list, varMax); + fprintf (fp, "0\n"); + *varMax = GET_MAX (*varMax, abs(index)); + *clauseN = *clauseN + 1; + return (DDDMP_SUCCESS); + } + + /* + * NON Terminal case: Recur + */ + + Nv = cuddT (N); + Nnv = cuddE (N); + if (Cudd_IsComplement (node)) { + Nv = Cudd_Not (Nv); + Nnv = Cudd_Not (Nnv); + } + index = N->index; + + /* + * StQ 06.05.2003 + * Perform the optimization: + * f = (a + b)' = (a') ^ (a + b') = (a') ^ (b') + * i.e., if the THEN node is the constant ZERO then that variable + * can be forgotten (list[index] = 2) for subsequent ELSE cubes + */ + if (cuddIsConstant (Cudd_Regular (Nv)) && Nv != ddMgr->one) { + list[index] = 2; + } else { + list[index] = 0; + } + StoreCnfBestNotSharedRecur (ddMgr, Nnv, idf, bddIds, cnfIds, fp, list, + clauseN, varMax); + + /* + * StQ 06.05.2003 + * Perform the optimization: + * f = a ^ b = (a) ^ (a' + b) = (a) ^ (b) + * i.e., if the ELSE node is the constant ZERO then that variable + * can be forgotten (list[index] = 2) for subsequent THEN cubes + */ + if (cuddIsConstant (Cudd_Regular (Nnv)) && Nnv != ddMgr->one) { + list[index] = 2; + } else { + list[index] = 1; + } + StoreCnfBestNotSharedRecur (ddMgr, Nv, idf, bddIds, cnfIds, fp, list, + clauseN, varMax); + list[index] = 2; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Print Best on Shared + sub-BDDs. + ] + + Description [Performs the recursive step of Print Best on Not Shared + sub-BDDs, i.e., print out information for the nodes belonging to + BDDs not shared (whose root has just one incoming edge). + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +StoreCnfBestSharedRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *node /* IN: BDD to store */, + int *bddIds /* IN: BDD identifiers */, + int *cnfIds /* IN: corresponding CNF identifiers */, + FILE *fp /* IN: file pointer */, + int *list /* IN: temporary array to store cubes */, + int *clauseN /* OUT: number of stored clauses */, + int *varMax /* OUT: maximum identifier of the variables created */ + ) +{ + DdNode *nodeThen, *nodeElse; + int i, idf, index; + DdNode *one; + + one = ddMgr->one; + + Dddmp_Assert (node==Cudd_Regular(node), + "Inverted Edge during Shared Printing."); + + /* If constant, nothing to do. */ + if (cuddIsConstant (node)) { + return (DDDMP_SUCCESS); + } + + /* If already visited, nothing to do. */ + if (DddmpVisitedCnf (node)) { + return (DDDMP_SUCCESS); + } + + /* + * Shared Sub-Tree: Print Cube + */ + + idf = DddmpReadNodeIndexCnf (node); + if (idf > 0) { + /* Cheat the Recur Function about the Index of the Current Node */ + DddmpWriteNodeIndexCnf (node, 0); + +#if DDDMP_DEBUG_CNF + fprintf (fp, "Else of XNOR\n"); +#endif + for (i=0; isize; i++) { + list[i] = 2; + } + StoreCnfBestNotSharedRecur (ddMgr, Cudd_Not (node), idf, bddIds, cnfIds, + fp, list, clauseN, varMax); + +#if DDDMP_DEBUG_CNF + fprintf (fp, "Then of XNOR\n"); +#endif + for (i=0; isize; i++) { + list[i] = 2; + } + StoreCnfBestNotSharedRecur (ddMgr, node, -idf, bddIds, cnfIds, + fp, list, clauseN, varMax); + + /* Set Back Index of Current Node */ + DddmpWriteNodeIndexCnf (node, idf); + } + + /* Mark node as visited. */ + DddmpSetVisitedCnf (node); + + /* + * Recur + */ + + nodeThen = cuddT (node); + nodeElse = cuddE (node); + index = node->index; + + StoreCnfBestSharedRecur (ddMgr, Cudd_Regular (nodeThen), bddIds, cnfIds, + fp, list, clauseN, varMax); + StoreCnfBestSharedRecur (ddMgr, Cudd_Regular (nodeElse), bddIds, cnfIds, + fp, list, clauseN, varMax); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Print One Cube in CNF Format.] + + Description [Print One Cube in CNF Format. + Return DDDMP_SUCCESS if something is printed out, DDDMP_FAILURE + is nothing is printed out. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +printCubeCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *node /* IN: BDD to store */, + int *cnfIds /* IN: CNF identifiers */, + FILE *fp /* IN: file pointer */, + int *list /* IN: temporary array to store cubes */, + int *varMax /* OUT: maximum identifier of the variables created */ + ) +{ + int i, retValue; + DdNode *one; + + retValue = DDDMP_FAILURE; + one = ddMgr->one; + + if (node != one) { + for (i=0; isize; i++) { + if (list[i] == 0) { + retValue = DDDMP_SUCCESS; + (void) fprintf (fp, "%d ", cnfIds[i]); + *varMax = GET_MAX(*varMax, cnfIds[i]); + } else { + if (list[i] == 1) { + retValue = DDDMP_SUCCESS; + (void) fprintf (fp, "-%d ", cnfIds[i]); + *varMax = GET_MAX(*varMax, cnfIds[i]); + } + } + } + } + + return (retValue); +} + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreMisc.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreMisc.c new file mode 100644 index 000000000..2dc18f046 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreMisc.c @@ -0,0 +1,1641 @@ +/**CFile********************************************************************** + + FileName [dddmpStoreMisc.c] + + PackageName [dddmp] + + Synopsis [Functions to write out bdds to file in prefixed + and in Blif form.] + + Description [Functions to write out bdds to file. + BDDs are represended on file in text format. + Each node is stored as a multiplexer in a prefix notation format for + the prefix notation file or in PLA format for the blif file. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpCuddDdArrayStorePrefix(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp); +static int DddmpCuddDdArrayStorePrefixBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp); +static int DddmpCuddDdArrayStorePrefixStep(DdManager * ddMgr, DdNode * f, FILE * fp, st_table * visited, char ** names); +static int DddmpCuddDdArrayStoreBlif(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp); +static int DddmpCuddDdArrayStoreBlifBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp); +static int DddmpCuddDdArrayStoreBlifStep(DdManager *ddMgr, DdNode *f, FILE *fp, st_table *visited, char **names); +static int DddmpCuddDdArrayStoreSmv(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp); +static int DddmpCuddDdArrayStoreSmvBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp); +static int DddmpCuddDdArrayStoreSmvStep(DdManager * ddMgr, DdNode * f, FILE * fp, st_table * visited, char ** names); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a prefix notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddStore] + +******************************************************************************/ + +int +Dddmp_cuddBddStorePrefix ( + DdManager *ddMgr /* IN: DD Manager */, + int nRoots /* IN: Number of BDD roots */, + DdNode *f /* IN: BDD root to be stored */, + char **inputNames /* IN: Array of variable names */, + char **outputNames /* IN: Array of root names */, + char *modelName /* IN: Model Name */, + char *fileName /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStorePrefix (ddMgr, 1, tmpArray, + inputNames, outputNames, modelName, fileName, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a prefix notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddArrayStore] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStorePrefix ( + DdManager *ddMgr /* IN: DD Manager */, + int nroots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of BDD roots to be stored */, + char **inputNames /* IN: array of variable names (or NULL) */, + char **outputNames /* IN: array of root names (or NULL) */, + char *modelName /* IN: Model Name */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + int fileToClose = 0; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + retValue = DddmpCuddDdArrayStorePrefix (ddMgr, nroots, f, + inputNames, outputNames, modelName, fp); + + if (fileToClose) { + fclose (fp); + } + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); + + failure: + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a Blif/Exlif notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBlif. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddStorePrefix] + +******************************************************************************/ + +int +Dddmp_cuddBddStoreBlif ( + DdManager *ddMgr /* IN: DD Manager */, + int nRoots /* IN: Number of BDD roots */, + DdNode *f /* IN: BDD root to be stored */, + char **inputNames /* IN: Array of variable names */, + char **outputNames /* IN: Array of root names */, + char *modelName /* IN: Model Name */, + char *fileName /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStoreBlif (ddMgr, 1, tmpArray, + inputNames, outputNames, modelName, fileName, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a Blif/Exlif notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBLif. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddArrayStorePrefix] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStoreBlif ( + DdManager *ddMgr /* IN: DD Manager */, + int nroots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of BDD roots to be stored */, + char **inputNames /* IN: array of variable names (or NULL) */, + char **outputNames /* IN: array of root names (or NULL) */, + char *modelName /* IN: Model Name */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + int fileToClose = 0; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + retValue = DddmpCuddDdArrayStoreBlif (ddMgr, nroots, f, + inputNames, outputNames, modelName, fp); + + if (fileToClose) { + fclose (fp); + } + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); + + failure: + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a prefix notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddStore] + +******************************************************************************/ + +int +Dddmp_cuddBddStoreSmv ( + DdManager *ddMgr /* IN: DD Manager */, + int nRoots /* IN: Number of BDD roots */, + DdNode *f /* IN: BDD root to be stored */, + char **inputNames /* IN: Array of variable names */, + char **outputNames /* IN: Array of root names */, + char *modelName /* IN: Model Name */, + char *fileName /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStoreSmv (ddMgr, 1, tmpArray, + inputNames, outputNames, modelName, fileName, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a prefix notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddArrayStore] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStoreSmv ( + DdManager *ddMgr /* IN: DD Manager */, + int nroots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of BDD roots to be stored */, + char **inputNames /* IN: array of variable names (or NULL) */, + char **outputNames /* IN: array of root names (or NULL) */, + char *modelName /* IN: Model Name */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + int fileToClose = 0; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + retValue = DddmpCuddDdArrayStoreSmv (ddMgr, nroots, f, + inputNames, outputNames, modelName, fp); + + if (fileToClose) { + fclose (fp); + } + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); + + failure: + return (DDDMP_FAILURE); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Internal function to writes a dump file representing the + argument BDD in a prefix notation.] + + Description [One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + Comments (COMMENT) are added at the beginning of the description to + describe inputs and outputs of the design. + A buffer (BUF) is add on the output to cope with complemented functions. + ] + + SideEffects [None] + + SeeAlso [DddmpCuddDdArrayStoreBlif] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStorePrefix ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + char *modelName /* IN: Model name (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nVars = ddMgr->size; + int retValue; + int i; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int, nVars); + if (sorted == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure); + } + for (i = 0; i < nVars; i++) { + sorted[i] = 0; + } + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(ddMgr,f,n); + Dddmp_CheckAndGotoLabel (support==NULL, + "Error in function Cudd_VectorSupport.", failure); + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(ddMgr,support); + /* so that we do not try to free it in case of failure */ + support = NULL; + + /* Write the header (.model .inputs .outputs). */ + if (modelName == NULL) { + retValue = fprintf (fp, "(COMMENT - model name: Unknown )\n"); + } else { + retValue = fprintf (fp, "(COMMENT - model name: %s )\n", modelName); + } + if (retValue == EOF) { + return(0); + } + + retValue = fprintf(fp, "(COMMENT - input names: "); + if (retValue == EOF) { + return(0); + } + /* Write the input list by scanning the support array. */ + for (i = 0; i < nVars; i++) { + if (sorted[i]) { + if (inputNames == NULL) { + retValue = fprintf(fp," inNode%d", i); + } else { + retValue = fprintf(fp," %s", inputNames[i]); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + } + FREE(sorted); + sorted = NULL; + retValue = fprintf(fp, " )\n"); + if (retValue == EOF) { + return(0); + } + + /* Write the .output line. */ + retValue = fprintf(fp,"(COMMENT - output names: "); + if (retValue == EOF) { + return(0); + } + for (i = 0; i < n; i++) { + if (outputNames == NULL) { + retValue = fprintf (fp," outNode%d", i); + } else { + retValue = fprintf (fp," %s", outputNames[i]); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + retValue = fprintf(fp, " )\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + + retValue = DddmpCuddDdArrayStorePrefixBody (ddMgr, n, f, inputNames, + outputNames, fp); + Dddmp_CheckAndGotoLabel (retValue==0, + "Error in function DddmpCuddDdArrayStorePrefixBody.", failure); + + return(1); + +failure: + if (sorted != NULL) { + FREE(sorted); + } + if (support != NULL) { + Cudd_RecursiveDeref(ddMgr,support); + } + return(0); +} + +/**Function******************************************************************** + + Synopsis [Internal function to writes a dump file representing the + argument BDD in a prefix notation. Writes the body of the file.] + + Description [One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + ] + + SideEffects [None] + + SeeAlso [DddmpCuddDdArrayStoreBlif] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStorePrefixBody ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + st_table *visited = NULL; + int retValue; + int i; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + Dddmp_CheckAndGotoLabel (visited==NULL, + "Error if function st_init_table.", failure); + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + retValue = DddmpCuddDdArrayStorePrefixStep (ddMgr, Cudd_Regular(f[i]), + fp, visited, inputNames); + Dddmp_CheckAndGotoLabel (retValue==0, + "Error if function DddmpCuddDdArrayStorePrefixStep.", failure); + } + + /* To account for the possible complement on the root, + ** we put either a buffer or an inverter at the output of + ** the multiplexer representing the top node. + */ + for (i=0; iindex]); + } else { + retValue = fprintf(fp, "inNode%d ", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + retValue = fprintf (fp, "node%lx) (AND (NOT ", + (unsigned long) T / (unsigned long) sizeof(DdNode)); +#else + retValue = fprintf (fp, "node%x) (AND (NOT ", + (unsigned) T / (unsigned) sizeof(DdNode)); +#endif + if (retValue == EOF) { + return(0); + } + + if (names != NULL) { + retValue = fprintf (fp, "%s", names[f->index]); + } else { + retValue = fprintf (fp, "inNode%d", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf (fp, ") (NOT node%lx)))\n", + (unsigned long) E / (unsigned long) sizeof(DdNode)); + } else { + retValue = fprintf (fp, ") node%lx))\n", + (unsigned long) E / (unsigned long) sizeof(DdNode)); + } +#else + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf (fp, ") (NOT node%x)))\n", + (unsigned) E / (unsigned) sizeof(DdNode)); + } else { + retValue = fprintf (fp, ") node%x))\n", + (unsigned) E / (unsigned) sizeof(DdNode)); + } +#endif + + if (retValue == EOF) { + return(0); + } else { + return(1); + } +} + +/**Function******************************************************************** + + Synopsis [Writes a blif file representing the argument BDDs.] + + Description [Writes a blif file representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). + DddmpCuddDdArrayStoreBlif does not close the file: This is the + caller responsibility. + DddmpCuddDdArrayStoreBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for outputNames. + It prefixes the string "NODE" to each nome to have "regular" names + for each elements. + ] + + SideEffects [None] + + SeeAlso [DddmpCuddDdArrayStoreBlifBody,Cudd_DumpBlif] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStoreBlif ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + char *modelName /* IN: Model name (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nVars = ddMgr->size; + int retValue; + int i; + + /* Build a bit array with the support of f. */ + sorted = ALLOC (int, nVars); + if (sorted == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure); + } + for (i = 0; i < nVars; i++) { + sorted[i] = 0; + } + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(ddMgr,f,n); + Dddmp_CheckAndGotoLabel (support==NULL, + "Error in function Cudd_VectorSupport.", failure); + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(ddMgr,support); + support = NULL; + /* so that we do not try to free it in case of failure */ + + /* Write the header (.model .inputs .outputs). */ + if (modelName == NULL) { + retValue = fprintf(fp,".model DD\n.inputs"); + } else { + retValue = fprintf(fp,".model %s\n.inputs", modelName); + } + if (retValue == EOF) { + return(0); + } + + /* Write the input list by scanning the support array. */ + for (i = 0; i < nVars; i++) { + if (sorted[i]) { + if (inputNames == NULL || (inputNames[i] == NULL)) { + retValue = fprintf(fp," inNode%d", i); + } else { + retValue = fprintf(fp," %s", inputNames[i]); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + } + FREE(sorted); + sorted = NULL; + + /* Write the .output line. */ + retValue = fprintf(fp,"\n.outputs"); + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + for (i = 0; i < n; i++) { + if (outputNames == NULL || (outputNames[i] == NULL)) { + retValue = fprintf(fp," outNode%d", i); + } else { + retValue = fprintf(fp," %s", outputNames[i]); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + retValue = fprintf(fp,"\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + + retValue = DddmpCuddDdArrayStoreBlifBody(ddMgr, n, f, inputNames, + outputNames, fp); + Dddmp_CheckAndGotoLabel (retValue==0, + "Error if function DddmpCuddDdArrayStoreBlifBody.", failure); + + /* Write trailer and return. */ + retValue = fprintf (fp, ".end\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + + return(1); + +failure: + if (sorted != NULL) { + FREE(sorted); + } + if (support != NULL) { + Cudd_RecursiveDeref(ddMgr,support); + } + + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Writes a blif body representing the argument BDDs.] + + Description [Writes a blif body representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). + DddmpCuddDdArrayStoreBlif does not close the file: This is the + caller responsibility. + DddmpCuddDdArrayStoreBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inputNames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for outputNames. This function prints out only + .names part. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStoreBlifBody ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + st_table *visited = NULL; + int retValue; + int i; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + Dddmp_CheckAndGotoLabel (visited==NULL, + "Error if function st_init_table.", failure); + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + retValue = DddmpCuddDdArrayStoreBlifStep (ddMgr, Cudd_Regular(f[i]), + fp, visited, inputNames); + Dddmp_CheckAndGotoLabel (retValue==0, + "Error if function DddmpCuddDdArrayStoreBlifStep.", failure); + } + + /* + * To account for the possible complement on the root, + * we put either a buffer or an inverter at the output of + * the multiplexer representing the top node. + */ + + for (i = 0; i < n; i++) { + if (outputNames == NULL) { + retValue = fprintf(fp, +#if SIZEOF_VOID_P == 8 + ".names node%lx outNode%d\n", + (unsigned long) f[i] / (unsigned long) sizeof(DdNode), i); +#else + ".names node%x outNode%d\n", + (unsigned) f[i] / (unsigned) sizeof(DdNode), i); +#endif + } else { + retValue = fprintf(fp, +#if SIZEOF_VOID_P == 8 + ".names node%lx %s\n", + (unsigned long) f[i] / (unsigned long) sizeof(DdNode), outputNames[i]); +#else + ".names node%x %s\n", + (unsigned) f[i] / (unsigned) sizeof(DdNode), outputNames[i]); +#endif + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + if (Cudd_IsComplement(f[i])) { + retValue = fprintf(fp,"0 1\n"); + } else { + retValue = fprintf(fp,"1 1\n"); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + + st_free_table(visited); + return(1); + +failure: + if (visited != NULL) { + st_free_table(visited); + } + return(0); +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of DddmpCuddDdArrayStoreBlif.] + + Description [Performs the recursive step of DddmpCuddDdArrayStoreBlif. + Traverses the BDD f and writes a multiplexer-network description to + the file pointed by fp in blif format. + f is assumed to be a regular pointer and DddmpCuddDdArrayStoreBlifStep + guarantees this assumption in the recursive calls. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStoreBlifStep ( + DdManager *ddMgr, + DdNode *f, + FILE *fp, + st_table *visited, + char **names + ) +{ + DdNode *T, *E; + int retValue; + +#ifdef DDDMP_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + /* If already visited, nothing to do. */ + if (st_is_member(visited, (char *) f) == 1) { + return(1); + } + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) { + return(0); + } + + /* Mark node as visited. */ + if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) { + return(0); + } + + /* Check for special case: If constant node, generate constant 1. */ + if (f == DD_ONE(ddMgr)) { +#if SIZEOF_VOID_P == 8 + retValue = fprintf(fp, ".names node%lx\n1\n", + (unsigned long) f / (unsigned long) sizeof(DdNode)); +#else + retValue = fprintf(fp, ".names node%x\n1\n", + (unsigned) f / (unsigned) sizeof(DdNode)); +#endif + if (retValue == EOF) { + return(0); + } else { + return(1); + } + } + + /* Check whether this is an ADD. We deal with 0-1 ADDs, but not + ** with the general case. + */ + if (f == DD_ZERO(ddMgr)) { +#if SIZEOF_VOID_P == 8 + retValue = fprintf(fp, ".names node%lx\n", + (unsigned long) f / (unsigned long) sizeof(DdNode)); +#else + retValue = fprintf(fp, ".names node%x\n", + (unsigned) f / (unsigned) sizeof(DdNode)); +#endif + if (retValue == EOF) { + return(0); + } else { + return(1); + } + } + if (cuddIsConstant(f)) { + return(0); + } + + /* Recursive calls. */ + T = cuddT(f); + retValue = DddmpCuddDdArrayStoreBlifStep(ddMgr,T,fp,visited,names); + if (retValue != 1) return(retValue); + E = Cudd_Regular(cuddE(f)); + retValue = DddmpCuddDdArrayStoreBlifStep(ddMgr,E,fp,visited,names); + if (retValue != 1) return(retValue); + + /* Write multiplexer taking complement arc into account. */ + if (names != NULL) { + retValue = fprintf(fp,".names %s", names[f->index]); + } else { + retValue = fprintf(fp,".names inNode%d", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf(fp," node%lx node%lx node%lx\n11- 1\n0-0 1\n", + (unsigned long) T / (unsigned long) sizeof(DdNode), + (unsigned long) E / (unsigned long) sizeof(DdNode), + (unsigned long) f / (unsigned long) sizeof(DdNode)); + } else { + retValue = fprintf(fp," node%lx node%lx node%lx\n11- 1\n0-1 1\n", + (unsigned long) T / (unsigned long) sizeof(DdNode), + (unsigned long) E / (unsigned long) sizeof(DdNode), + (unsigned long) f / (unsigned long) sizeof(DdNode)); + } +#else + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf(fp," node%x node%x node%x\n11- 1\n0-0 1\n", + (unsigned) T / (unsigned) sizeof(DdNode), + (unsigned) E / (unsigned) sizeof(DdNode), + (unsigned) f / (unsigned) sizeof(DdNode)); + } else { + retValue = fprintf(fp," node%x node%x node%x\n11- 1\n0-1 1\n", + (unsigned) T / (unsigned) sizeof(DdNode), + (unsigned) E / (unsigned) sizeof(DdNode), + (unsigned) f / (unsigned) sizeof(DdNode)); + } +#endif + if (retValue == EOF) { + return(0); + } else { + return(1); + } +} + +/**Function******************************************************************** + + Synopsis [Internal function to writes a dump file representing the + argument BDD in a SMV notation.] + + Description [One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + Comments (COMMENT) are added at the beginning of the description to + describe inputs and outputs of the design. + A buffer (BUF) is add on the output to cope with complemented functions. + ] + + SideEffects [None] + + SeeAlso [DddmpCuddDdArrayStoreBlif] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStoreSmv ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + char *modelName /* IN: Model name (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nVars = ddMgr->size; + int retValue; + int i; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int, nVars); + if (sorted == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure); + } + for (i = 0; i < nVars; i++) { + sorted[i] = 0; + } + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(ddMgr,f,n); + Dddmp_CheckAndGotoLabel (support==NULL, + "Error in function Cudd_VectorSupport.", failure); + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(ddMgr,support); + /* so that we do not try to free it in case of failure */ + support = NULL; + + /* Write the header */ + if (modelName == NULL) { + retValue = fprintf (fp, "MODULE main -- Unknown\n"); + } else { + retValue = fprintf (fp, "MODULE main -- %s\n", modelName); + } + if (retValue == EOF) { + return(0); + } + + retValue = fprintf(fp, "IVAR\n"); + if (retValue == EOF) { + return(0); + } + + /* Write the input list by scanning the support array. */ + for (i=0; iindex]); + } else { + retValue = fprintf(fp, "inNode%d ", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + retValue = fprintf (fp, "& node%lx | ", + (unsigned long) T / (unsigned long) sizeof(DdNode)); +#else + retValue = fprintf (fp, "& node%x | ", + (unsigned) T / (unsigned) sizeof(DdNode)); +#endif + if (retValue == EOF) { + return(0); + } + + if (names != NULL) { + retValue = fprintf (fp, "!%s ", names[f->index]); + } else { + retValue = fprintf (fp, "!inNode%d ", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf (fp, "& !node%lx\n", + (unsigned long) E / (unsigned long) sizeof(DdNode)); + } else { + retValue = fprintf (fp, "& node%lx\n", + (unsigned long) E / (unsigned long) sizeof(DdNode)); + } +#else + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf (fp, "& !node%x\n", + (unsigned) E / (unsigned) sizeof(DdNode)); + } else { + retValue = fprintf (fp, "& node%x\n", + (unsigned) E / (unsigned) sizeof(DdNode)); + } +#endif + + if (retValue == EOF) { + return(0); + } else { + return(1); + } +} + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpUtil.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpUtil.c new file mode 100644 index 000000000..feff43943 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpUtil.c @@ -0,0 +1,436 @@ +/**CFile********************************************************************** + + FileName [dddmpUtil.c] + + PackageName [dddmp] + + Synopsis [Util Functions for the dddmp package] + + Description [Functions to manipulate arrays.] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [String compare for qsort] + + Description [String compare for qsort] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +int +QsortStrcmp( + const void *ps1 /* IN: pointer to the first string */, + const void *ps2 /* IN: pointer to the second string */ + ) +{ + return (strcmp (*((char**)ps1),*((char **)ps2))); +} + +/**Function******************************************************************** + + Synopsis [Performs binary search of a name within a sorted array] + + Description [Binary search of a name within a sorted array of strings. + Used when matching names of variables. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +int +FindVarname ( + char *name /* IN: name to look for */, + char **array /* IN: search array */, + int n /* IN: size of the array */ + ) +{ + int d, m, u, t; + + d = 0; u = n-1; + + while (u>=d) { + m = (u+d)/2; + t=strcmp(name,array[m]); + if (t==0) + return m; + if (t<0) + u=m-1; + else + d=m+1; + } + + return (-1); +} + + +/**Function******************************************************************** + + Synopsis [Duplicates a string] + + Description [Allocates memory and copies source string] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +char * +DddmpStrDup ( + char *str /* IN: string to be duplicated */ + ) +{ + char *str2; + + str2 = DDDMP_ALLOC(char,strlen(str)+1); + if (str2 != NULL) { + strcpy (str2,str); + } + + return (str2); +} + +/**Function******************************************************************** + + Synopsis [Duplicates an array of strings] + + Description [Allocates memory and copies source array] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +char ** +DddmpStrArrayDup ( + char **array /* IN: array of strings to be duplicated */, + int n /* IN: size of the array */ + ) +{ + char **array2; + int i; + + array2 = DDDMP_ALLOC(char *, n); + if (array2 == NULL) { + (void) fprintf (stderr, "DddmpStrArrayDup: Error allocating memory\n"); + fflush (stderr); + return NULL; + } + + /* + * initialize all slots to NULL for fair FREEing in case of failure + */ + + for (i=0; i +Command Documentation + + +

          Command Documentation


          +
          +
          +Last updated on 1040218 17h15 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/commands.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/commands.html new file mode 100644 index 000000000..2609aafcd --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/commands.html @@ -0,0 +1,12 @@ + +Command Documentation + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/credit.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/credit.html new file mode 100644 index 000000000..868097be4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/credit.html @@ -0,0 +1,15 @@ + +Credit + + + + + + + +
          + Command Documentation + Package Documentation Generated by + the Ext system
          + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-A4.ps b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-A4.ps new file mode 100644 index 000000000..7c1010a10 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-A4.ps @@ -0,0 +1,1261 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software +%%Title: dddmp-2.0.dvi +%%Pages: 10 +%%PageOrder: Ascend +%%BoundingBox: 0 0 596 842 +%%DocumentFonts: Times-Bold Times-Roman Courier Times-Italic Helvetica +%%DocumentPaperSizes: a4 +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -t a4 -f dddmp-2.0 +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2002.12.11:0557 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", +% version = "0.6", +% date = "22 June 1996", +% filename = "8r.enc", +% email = "kb@@mail.tug.org", +% address = "135 Center Hill Rd. // Plymouth, MA 02360", +% codetable = "ISO/ASCII", +% checksum = "119 662 4424", +% docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." +% @} +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both ASCII and Windows. +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there down to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics +exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub +dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} +ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict +end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ +dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 +roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def +dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} +if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} +def end + +%%EndProcSet +%%BeginProcSet: special.pro +%! +TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N +/vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N +/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N +/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ +/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho +X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B +/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ +/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known +{userdict/md get type/dicttype eq{userdict begin md length 10 add md +maxlength ge{/md md dup length 20 add dict copy def}if end md begin +/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S +atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ +itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll +transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll +curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf +pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} +if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 +-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 +get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip +yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub +neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ +noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop +90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get +neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr +1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr +2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 +-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S +TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ +Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale +}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState +save N userdict maxlength dict begin/magscale true def normalscale +currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts +/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x +psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx +psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub +TR/showpage{}N/erasepage{}N/copypage{}N/p 3 def @MacSetUp}N/doclip{ +psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 +roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath +moveto}N/endTexFig{end psf$SavedState restore}N/@beginspecial{SDict +begin/SpecialSave save N gsave normalscale currentpoint TR +@SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{ +CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto +closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx +sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR +}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse +CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury +lineto closepath clip}if/showpage{}N/erasepage{}N/copypage{}N newpath}N +/@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{end} +repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N +/@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX +currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY +moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X +/yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0 +1 startangle endangle arc savematrix setmatrix}N end + +%%EndProcSet +TeXDict begin 39158280 55380996 1000 600 600 (dddmp-2.0.dvi) +@start /Fa 143[55 1[55 7[28 2[50 99[{TeXBase1Encoding ReEncodeFont}4 +99.6264 /Helvetica rf +%DVIPSBitmapFont: Fb cmr12 12 3 +/Fb 3 53 df<14FF010713E090381F81F890383E007C01FC133F4848EB1F8049130F4848 +EB07C04848EB03E0A2000F15F0491301001F15F8A2003F15FCA390C8FC4815FEA54815FF +B3A46C15FEA56D1301003F15FCA3001F15F8A26C6CEB03F0A36C6CEB07E0000315C06D13 +0F6C6CEB1F806C6CEB3F00013E137C90381F81F8903807FFE0010090C7FC28447CC131> +48 D<143014F013011303131F13FFB5FC13E713071200B3B3B0497E497E007FB6FCA320 +4278C131>I52 D E +%EndDVIPSBitmapFont +/Fc 64[50 29[39 12[55 55 25[44 44 66 44 50 28 39 39 1[50 +50 50 72 28 44 1[28 50 50 28 44 50 44 50 50 10[61 2[50 +4[66 83 55 2[33 2[61 1[72 66 61 61 15[50 2[25 33 25 2[33 +33 37[50 2[{TeXBase1Encoding ReEncodeFont}45 99.6264 +/Times-Italic rf +%DVIPSBitmapFont: Fd cmmi12 12 3 +/Fd 3 103 df60 D<127012FCB4FCEA7FC0EA1FF0EA +07FCEA01FF38007FC0EB1FF0EB07FE903801FF809038007FE0EC1FF8EC03FE913800FF80 +ED3FE0ED0FF8ED03FF030013C0EE3FF0EE0FFCEE01FF9338007FC0EF1FF0EF07FCEF01FF +9438007FC0F01FE0A2F07FC0943801FF00EF07FCEF1FF0EF7FC04C48C7FCEE0FFCEE3FF0 +EEFFC0030390C8FCED0FF8ED3FE0EDFF80DA03FEC9FCEC1FF8EC7FE0903801FF80D907FE +CAFCEB1FF0EB7FC04848CBFCEA07FCEA1FF0EA7FC048CCFC12FC12703B3878B44C>62 +D102 +D E +%EndDVIPSBitmapFont +/Fe 134[42 2[42 42 23 32 28 1[42 42 42 65 23 2[23 42 +42 28 37 42 1[42 37 12[51 10[28 4[60 1[55 19[21 28 21 +44[{TeXBase1Encoding ReEncodeFont}26 83.022 /Times-Roman +rf +%DVIPSBitmapFont: Ff cmr7 7 2 +/Ff 2 51 df<13381378EA01F8121F12FE12E01200B3AB487EB512F8A215267BA521>49 +D<13FF000313E0380E03F0381800F848137C48137E00787F12FC6CEB1F80A4127CC7FC15 +005C143E147E147C5C495A495A5C495A010EC7FC5B5B903870018013E0EA018039030003 +0012065A001FB5FC5A485BB5FCA219267DA521>I E +%EndDVIPSBitmapFont +/Fg 103[60 26[60 1[60 60 60 60 60 60 60 60 60 60 60 60 +60 60 60 60 2[60 60 60 60 60 60 60 60 60 3[60 1[60 3[60 +60 1[60 60 1[60 60 1[60 60 3[60 1[60 1[60 60 60 1[60 +60 1[60 1[60 1[60 60 60 60 60 60 60 60 60 60 60 60 60 +60 60 5[60 38[{TeXBase1Encoding ReEncodeFont}62 99.6264 +/Courier rf +%DVIPSBitmapFont: Fh cmr8 8 2 +/Fh 2 51 df<130C133C137CEA03FC12FFEAFC7C1200B3B113FE387FFFFEA2172C7AAB23 +>49 DI E +%EndDVIPSBitmapFont +/Fi 105[50 28[50 50 2[55 33 39 44 1[55 50 55 83 28 2[28 +1[50 33 44 55 44 55 50 10[72 1[66 55 3[78 72 94 66 3[78 +1[61 66 72 72 66 72 13[50 50 50 1[28 25 33 45[{ +TeXBase1Encoding ReEncodeFont}40 99.6264 /Times-Bold +rf /Fj 139[40 1[53 1[66 60 66 100 33 2[33 3[53 3[60 23[47 +2[73 18[60 60 60 2[30 46[{TeXBase1Encoding ReEncodeFont}16 +119.552 /Times-Bold rf +%DVIPSBitmapFont: Fk cmsy10 12 1 +/Fk 1 16 df<49B4FC010F13E0013F13F8497F48B6FC4815804815C04815E04815F0A248 +15F8A24815FCA3B712FEA96C15FCA36C15F8A26C15F0A26C15E06C15C06C15806C15006C +6C13FC6D5B010F13E0010190C7FC27277BAB32>15 D E +%EndDVIPSBitmapFont +/Fl 64[44 42[44 44 24[44 50 50 72 50 50 28 39 33 50 50 +50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 6[61 1[72 +94 72 72 61 55 66 72 55 72 72 89 61 1[39 33 72 72 55 +61 72 66 66 72 3[56 1[28 28 50 50 50 50 50 50 50 50 50 +50 28 25 33 25 2[33 33 36[55 55 2[{TeXBase1Encoding ReEncodeFont}74 +99.6264 /Times-Roman rf +%DVIPSBitmapFont: Fm cmsy10 14.4 2 +/Fm 2 104 df102 +DI E +%EndDVIPSBitmapFont +/Fn 105[60 27[53 4[60 33 47 40 60 60 60 60 93 33 2[33 +1[60 40 53 60 53 60 53 7[86 4[73 66 1[86 66 3[73 2[40 +1[86 1[73 86 80 1[86 110 5[33 60 4[60 1[60 60 60 1[30 +40 30 44[{TeXBase1Encoding ReEncodeFont}42 119.552 /Times-Roman +rf /Fo 136[104 1[80 48 56 64 1[80 72 80 120 40 80 1[40 +1[72 1[64 80 64 80 72 12[96 80 104 1[88 1[104 135 3[56 +2[88 1[104 104 96 104 6[48 1[72 72 72 72 72 72 72 72 +72 1[36 46[{TeXBase1Encoding ReEncodeFont}41 143.462 +/Times-Bold rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin +%%BeginPaperSize: a4 +a4 +%%EndPaperSize + +%%EndSetup +%%Page: 1 1 +1 0 bop 472 600 a Fo(DDDMP:)35 b(Decision)f(Diagram)f(DuMP)j(package) +1480 830 y(Release)e(2.0)462 1230 y Fn(Gianpiero)c(Cabodi)2402 +1232 y(Stef)o(ano)g(Quer)1316 1506 y(Politecnico)g(di)g(T)-10 +b(orino)1024 1656 y(Dip.)30 b(di)g(Automatica)g(e)g(Informatica)1119 +1805 y(Corso)f(Duca)h(de)n(gli)g(Abruzzi)g(24)1277 1955 +y(I\22610129)e(T)-5 b(urin,)29 b(IT)-11 b(AL)f(Y)1038 +2104 y(E-mail:)38 b Fm(f)p Fn(cabodi,quer)p Fm(g)p Fn(@polito.it)-189 +2614 y Fo(1)143 b(Intr)m(oduction)-189 2837 y Fl(The)27 +b(DDDMP)h(package)f(de\002nes)h(formats)f(and)g(rules)g(to)g(store)g +(DD)g(on)g(\002le.)39 b(More)27 b(in)g(particular)g(it)g(contains)g(a) +-189 2958 y(set)e(of)g(functions)e(to)i(dump)e(\(store)i(and)g(load\))g +(DDs)f(and)h(DD)g(forests)f(on)h(\002le)g(in)f(dif)n(ferent)h(formats.) +47 3078 y(In)30 b(the)g(present)g(implementation,)f(BDDs)h(\(R)l +(OBDDs\))h(and)f(ADD)g(\(Algebraic)g(Decision)g(Diagram\))g(of)-189 +3199 y(the)g(CUDD)g(package)g(\(v)o(ersion)f(2.3.0)g(or)h(higher\))g +(are)g(supported.)45 b(These)30 b(structures)f(can)h(be)g(represented)g +(on)-189 3319 y(\002les)25 b(either)g(in)f(te)o(xt,)g(binary)-6 +b(,)24 b(or)h(CNF)g(\(DIMA)l(CS\))h(formats.)47 3439 +y(The)f(main)f(rules)h(used)f(are)i(follo)n(wing)d(rules:)-44 +3643 y Fk(\017)49 b Fl(A)30 b(\002le)h(contains)e(a)i(single)e(BDD/ADD) +h(or)g(a)h(forest)f(of)g(BDDs/ADD,)g(i.e.,)i(a)e(v)o(ector)g(of)g +(Boolean)h(func-)55 3763 y(tions.)-44 3966 y Fk(\017)49 +b Fl(Inte)o(ger)21 b(inde)o(x)o(es)f(are)i(used)f(instead)g(of)g +(pointers)g(to)g(reference)i(nodes.)29 b(BDD/ADD)21 b(nodes)g(are)h +(numbered)55 4087 y(with)j(contiguous)g(numbers,)g(from)h(1)g(to)f +(NNodes)h(\(total)f(number)h(of)g(nodes)g(on)f(a)i(\002le\).)35 +b(0)26 b(is)f(not)h(used)f(to)55 4207 y(allo)n(w)f(ne)o(gati)n(v)o(e)e +(inde)o(x)o(es)h(for)i(complemented)f(edges.)-44 4411 +y Fk(\017)49 b Fl(A)23 b(\002le)g(contains)f(a)h(header)l(,)h +(including)d(se)n(v)o(eral)h(informations)f(about)h(v)n(ariables)h(and) +f(roots)g(of)h(BDD)h(func-)55 4531 y(tions,)32 b(then)e(the)h(list)g +(of)g(nodes.)49 b(The)32 b(header)f(is)g(al)o(w)o(ays)g(represented)h +(in)f(te)o(xt)f(format)h(\(also)g(for)g(binary)55 4651 +y(\002les\).)g(BDDs,)25 b(ADDs,)f(and)h(CNF)h(\002les)f(share)g(a)g +(similar)f(format)g(header)-5 b(.)-44 4855 y Fk(\017)49 +b Fl(BDD/ADD)40 b(nodes)g(are)h(listed)f(follo)n(wing)e(their)i +(numbering,)j(which)d(is)g(produced)g(by)h(a)f(post-order)55 +4975 y(tra)n(v)o(ersal,)24 b(in)h(such)f(a)h(w)o(ay)g(that)g(a)g(node)f +(is)h(al)o(w)o(ays)f(listed)g(after)h(its)f(Then/Else)g(children.)47 +5179 y(In)32 b(the)f(sequel)g(we)g(describe)h(more)f(in)g(detail)f(the) +h(dif)n(ferent)g(formats)g(and)g(procedures)h(a)n(v)n(ailable.)49 +b(First)-189 5299 y(of)26 b(all,)f(we)h(describe)f(BDDs)h(and)g(ADDs)f +(formats)g(and)g(procedure.)33 b(Secondly)-6 b(,)26 b(we)f(concentrate) +h(on)f(CNF)i(\002les,)-189 5419 y(i.e.,)e(ho)n(w)f(to)g(translate)g(a)i +(BDD)f(or)g(a)g(forest)g(of)f(BDDs)h(into)f(a)h(CNF)h(formula)e(and)h +(vice-v)o(ersa.)1794 5800 y(1)p eop +%%Page: 2 2 +2 1 bop -189 218 a Fo(2)143 b(BDD)35 b(and)g(ADD)g(Support)-189 +441 y Fl(In)23 b(this)f(section)g(we)g(describe)h(format)g(and)f +(procedure)h(re)o(garding)f(BDDs)h(and)f(ADDs.)30 b(W)-8 +b(e)23 b(speci\002cally)g(refer)g(to)-189 562 y(BDDs)h(in)g(the)g +(description)e(as)j(ADD)e(may)h(be)g(seen)g(as)h(an)f(e)o(xtension)e +(and)i(will)f(be)h(described)g(later)-5 b(.)30 b(First)24 +b(of)g(all,)-189 682 y(we)29 b(concentrate)f(on)g(the)g(format)g(used)g +(to)g(store)g(these)g(structure,)h(then)f(we)g(describe)h(the)f +(procedure)h(a)n(v)n(ailable)-189 802 y(to)24 b(store)h(and)g(load)f +(them.)-189 1094 y Fj(2.1)119 b(F)m(ormat)-189 1281 y +Fl(BDD)30 b(dump)f(\002les)g(are)i(composed)e(of)g(tw)o(o)g(sections:) +40 b(The)29 b(header)h(and)g(the)f(list)g(of)h(nodes.)44 +b(The)30 b(header)g(has)g(a)-189 1402 y(common)c(\(te)o(xt\))h(format,) +h(while)e(the)i(list)e(of)h(nodes)g(is)g(either)g(in)g(te)o(xt)g(or)g +(binary)g(format.)38 b(In)28 b(te)o(xt)e(format)h(nodes)-189 +1522 y(are)33 b(represented)f(with)f(redundant)g(informations,)h(where) +h(the)f(main)f(goal)g(is)h(readability)-6 b(,)32 b(while)g(the)f +(purpose)-189 1642 y(of)i(binary)f(format)g(is)g(minimizing)e(the)i(o)o +(v)o(erall)f(storage)h(size)h(for)g(BDD)f(nodes.)54 b(The)32 +b(header)h(format)f(is)g(k)o(ept)-189 1763 y(common)h(to)h(te)o(xt)g +(and)g(binary)g(formats)g(for)h(sak)o(e)f(of)h(simplicity:)47 +b(No)34 b(particular)g(optimization)f(is)h(presently)-189 +1883 y(done)29 b(on)f(binary)h(\002le)g(headers,)h(whose)f(size)g(is)f +(by)h(f)o(ar)g(dominated)f(by)h(node)f(lists)g(in)g(the)h(case)g(of)g +(lar)n(ge)h(BDDs)-189 2003 y(\(se)n(v)o(eral)24 b(thousands)g(of)h(DD)f +(nodes\).)-189 2266 y Fi(2.1.1)99 b(Header)-189 2453 +y Fl(The)23 b(header)h(has)f(the)g(same)g(format)g(both)g(for)g(te)o +(xtual)f(and)i(binary)e(dump.)30 b(F)o(or)23 b(sak)o(e)g(of)h +(generality)e(and)h(because)-189 2574 y(of)f(dynamic)g(v)n(ariable)g +(ordering)g(both)f(v)n(ariable)h(IDs)g(and)g(permutations)2377 +2537 y Fh(1)2438 2574 y Fl(are)h(included.)29 b(Names)22 +b(are)h(optionally)-189 2694 y(listed)35 b(for)h(input)f(v)n(ariables)g +(and)h(for)h(the)e(stored)h(functions.)63 b(Ne)n(w)36 +b(auxiliary)f(IDs)h(are)h(also)e(allo)n(wed.)64 b(Only)-189 +2814 y(the)34 b(v)n(ariables)f(in)g(the)h(true)g(support)f(of)h(the)f +(stored)h(BDDs)g(are)h(listed.)56 b(All)34 b(information)e(on)i(v)n +(ariables)f(\(IDs,)-189 2935 y(permutations,)c(names,)i(auxiliary)e +(IDs\))h(sorted)g(by)g(IDs,)h(and)e(the)o(y)h(are)g(restricted)g(to)f +(the)h(true)g(support)f(of)h(the)-189 3055 y(dumped)22 +b(BDD,)h(while)g(IDs)g(and)f(permutations)g(are)h(referred)i(to)d(the)h +(writing)f(BDD)h(manager)-5 b(.)30 b(Names)22 b(can)i(thus)-189 +3175 y(be)h(sorted)f(by)h(v)n(ariable)f(ordering)h(by)f(permuting)g +(them)g(according)h(to)f(the)h(permutations)e(stored)h(in)h(the)f +(\002le.)47 3296 y(As)h(an)g(e)o(xample,)f(the)g(header)i(\(in)e(te)o +(xt)g(mode\))h(of)f(the)h(ne)o(xt)f(state)h(functions)e(of)i(circuit)g +(s27)f(follo)n(ws:)-189 3494 y Fg(.ver)59 b(DDDMP-2.0)-189 +3615 y(.mode)g(A)-189 3735 y(.varinfo)f(3)-189 3855 y(.dd)h(s27-delta) +-189 3976 y(.nnodes)f(16)-189 4096 y(.nvars)g(10)-189 +4216 y(.nsuppvars)g(7)-189 4337 y(.varnames)g(G0)h(G1)g(G2)h(G3)f(G5)g +(G6)h(G7)-189 4457 y(.orderedvarnames)c(G0)k(G1)f(G2)g(G3)h(G5)f(G6)g +(G7)-189 4578 y(.ids)g(0)g(1)h(2)g(3)f(4)h(5)f(6)-189 +4698 y(.permids)f(0)i(1)f(2)h(3)f(5)h(7)f(9)-189 4818 +y(.auxids)f(1)i(2)f(3)h(4)f(5)h(6)g(7)-189 4939 y(.nroots)e(3)-189 +5059 y(.rootids)g(6)i(-13)f(-16)-189 5179 y(.rootnames)f(G10)h(G11)g +(G13)47 5378 y Fl(The)25 b(lines)f(contain)g(the)h(follo)n(wing)e +(informations:)p -189 5460 1607 4 v -77 5521 a Ff(1)-40 +5551 y Fe(The)d(permutation)e(of)i(the)g(i-th)h(v)n(ariable)e(ID)h(is)h +(the)f(relati)n(v)o(e)g(position)f(of)h(the)g(v)n(ariable)f(in)i(the)f +(ordering.)1794 5800 y Fl(2)p eop +%%Page: 3 3 +3 2 bop -44 218 a Fk(\017)49 b Fl(Dddmp)24 b(v)o(ersion)f(information.) +-44 411 y Fk(\017)49 b Fl(File)25 b(mode)f(\(A)h(for)g(ASCII)h(te)o +(xt,)e(B)h(for)g(binary)g(mode\).)-44 604 y Fk(\017)49 +b Fl(V)-11 b(ar)n(-e)o(xtra-info)25 b(\(0:)30 b(v)n(ariable)24 +b(ID,)h(1:)31 b(permID,)24 b(2:)31 b(aux)25 b(ID,)g(3:)30 +b(v)n(ariable)24 b(name,)h(4)g(no)f(e)o(xtra)h(info\).)-44 +797 y Fk(\017)49 b Fl(Name)25 b(of)g(dd)f(\(optional\).)-44 +990 y Fk(\017)49 b Fl(T)-8 b(otal)24 b(number)g(of)h(nodes)g(in)f(the)h +(\002le.)-44 1183 y Fk(\017)49 b Fl(Number)24 b(of)h(v)n(ariables)f(of) +h(the)g(writing)f(DD)g(manager)-5 b(.)-44 1375 y Fk(\017)49 +b Fl(Number)24 b(of)h(v)n(ariables)f(in)h(the)f(true)h(support)f(of)h +(the)f(stored)h(DDs.)-44 1568 y Fk(\017)49 b Fl(V)-11 +b(ariable)25 b(names)f(\(optional\))g(for)h(all)g(the)f(v)n(ariables)g +(in)h(the)f(BDD/ADD)h(support.)-44 1761 y Fk(\017)49 +b Fl(V)-11 b(ariable)20 b(names)g(for)h(all)f(the)g(v)n(ariables)f(in)h +(the)g(DD)h(manager)f(during)g(the)g(storing)f(phase.)29 +b(Notice)20 b(that)g(this)55 1882 y(information)k(w)o(as)h(not)g +(stored)g(by)g(pre)n(vious)f(v)o(ersions)g(of)i(the)f(same)g(tool.)32 +b(Full)25 b(backw)o(ard)g(compatibility)55 2002 y(is)f(guaranteed)h(by) +g(the)f(present)h(implementation)d(of)j(the)g(tool.)-44 +2195 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(IDs.)-44 +2388 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(permuted)f(IDs.)-44 +2581 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(auxiliary)f(IDs)h +(\(optional\).)-44 2774 y Fk(\017)49 b Fl(Number)24 b(of)h(BDD)g +(roots.)-44 2967 y Fk(\017)49 b Fl(Inde)o(x)o(es)24 b(of)h(BDD)g(roots) +f(\(complemented)g(edges)g(allo)n(wed\).)-44 3160 y Fk(\017)49 +b Fl(Names)24 b(of)h(BDD)h(roots)e(\(optional\).)-189 +3332 y(Notice)h(that)f(a)h(\002eld)-189 3504 y Fg(.add)-189 +3676 y Fl(is)f(present)h(after)g(the)g(dddmp)f(v)o(ersion)f(for)j +(\002les)e(containing)g(ADDs.)-189 3936 y Fi(2.1.2)99 +b(T)-9 b(ext)25 b(F)n(ormat)-189 4124 y Fl(In)g(te)o(xt)f(mode)g(nodes) +g(are)i(listed)e(on)g(a)h(te)o(xt)f(line)h(basis.)30 +b(Each)25 b(a)g(node)f(is)h(represented)g(as)-189 4296 +y Fg()57 b([])f()588 +4416 y()h()-189 4588 y Fl(where)25 +b(all)g(inde)o(x)o(es)e(are)j(inte)o(ger)e(numbers.)47 +4709 y(This)h(format)g(is)g(redundant)f(\(due)i(to)f(the)g(node)g +(ordering,)g Fd(<)p Fl(Node-inde)o(x)p Fd(>)f Fl(is)g(and)i +(incremental)e(inte)o(ger\))-189 4829 y(b)n(ut)g(we)h(k)o(eep)g(it)g +(for)g(readability)-6 b(.)47 4949 y Fd(<)p Fl(V)-11 b(ar)n(-e)o +(xtra-info)p Fd(>)34 b Fl(\(optional)e(redundant)i(\002eld\))g(is)f +(either)h(an)g(inte)o(ger)f(\(ID,)h(PermID,)g(or)g(auxID\))g(or)g(a) +-189 5070 y(string)k(\(v)n(ariable)h(name\).)75 b Fd(<)p +Fl(V)-11 b(ar)n(-internal-inde)o(x)p Fd(>)38 b Fl(is)h(an)g(internal)g +(v)n(ariable)g(inde)o(x:)59 b(V)-11 b(ariables)39 b(in)g(the)g(true) +-189 5190 y(support)25 b(of)h(the)g(stored)g(BDDs)g(are)h(numbered)e +(with)g(ascending)h(inte)o(gers)f(starting)g(from)h(0,)g(and)g(follo)n +(wing)e(the)-189 5311 y(v)n(ariable)g(ordering.)31 b +Fd(<)p Fl(Then-inde)o(x)p Fd(>)23 b Fl(and)i Fd(<)p Fl(Else-inde)o(x)p +Fd(>)e Fl(are)j(signed)e(inde)o(x)o(es)f(of)i(children)f(nodes.)47 +5431 y(In)h(the)f(follo)n(wing,)f(we)i(report)f(the)g(list)g(of)h +(nodes)f(of)g(the)h(s27)f(ne)o(xt)f(state)i(functions)e(\(see)i(pre)n +(vious)e(header)-189 5551 y(e)o(xample\):)1794 5800 y(3)p +eop +%%Page: 4 4 +4 3 bop -189 218 a Fg(.nodes)-189 338 y(1)60 b(T)f(1)h(0)f(0)-189 +459 y(2)h(G7)f(6)g(1)h(-1)-189 579 y(3)g(G5)f(4)g(1)h(2)-189 +699 y(4)g(G3)f(3)g(3)h(1)-189 820 y(5)g(G1)f(1)g(1)h(4)-189 +940 y(6)g(G0)f(0)g(5)h(-1)-189 1061 y(7)g(G6)f(5)g(1)h(-1)-189 +1181 y(8)g(G5)f(4)g(1)h(-7)-189 1301 y(9)g(G6)f(5)g(1)h(-2)-189 +1422 y(10)f(G5)h(4)f(1)h(-9)-189 1542 y(11)f(G3)h(3)f(10)h(8)-189 +1662 y(12)f(G1)h(1)f(8)h(11)-189 1783 y(13)f(G0)h(0)f(5)h(12)-189 +1903 y(14)f(G2)h(2)f(1)h(-1)-189 2024 y(15)f(G2)h(2)f(1)h(-2)-189 +2144 y(16)f(G1)h(1)f(14)h(15)-189 2264 y(.end)-189 2468 +y Fl(The)27 b(list)f(is)h(enclosed)g(between)g(the)g +Fg(.nodes)f Fl(and)h Fg(.end)f Fl(lines.)37 b(First)27 +b(node)g(is)g(the)g(one)g(constant,)f(each)i(node)-189 +2588 y(contains)c(the)h(optional)e(v)n(ariable)h(name.)47 +2708 y(F)o(or)29 b(ADDs)f(more)h(than)f(one)h(constant)e(is)i(stored)f +(in)g(the)g(\002le.)43 b(Each)29 b(constant)f(has)g(the)h(same)f +(format)h(we)-189 2829 y(ha)n(v)o(e)c(just)e(analyzed)i(for)g(the)g +(BDD)g(b)n(ut)g(the)f(represented)h(v)n(alue)f(is)h(stored)f(as)h(a)g +(\003oat)g(number)-5 b(.)-189 3095 y Fi(2.1.3)99 b(Binary)25 +b(F)n(ormat)-189 3283 y Fl(The)h(binary)g(format)f(is)h(not)f(allo)n +(wed)g(for)i(ADDs.)33 b(As)26 b(a)h(consequence)f(we)g(concentrate)g +(only)f(on)h(BDDs)g(in)g(this)-189 3403 y(section.)k(In)25 +b(binary)f(mode)h(nodes)f(are)i(represented)f(as)g(a)g(sequence)g(of)g +(bytes,)f(encoding)g(tuples)-189 3606 y Fg()-189 +3727 y([])-189 3847 y([])-189 +3968 y([])-189 4171 y Fl(in)30 b(an)g(optimized)f(w)o(ay)-6 +b(.)46 b(Only)29 b(the)h(\002rst)g(byte)g(\(code\))h(is)e(mandatory)-6 +b(,)30 b(while)g(inte)o(ger)f(inde)o(x)o(es)g(are)i(represented)-189 +4291 y(in)c(absolute)f(or)h(relati)n(v)o(e)f(mode,)h(where)h(relati)n +(v)o(e)e(means)g(of)n(fset)h(with)f(respect)i(to)e(a)i(Then/Else)e +(node)h(info.)37 b(The)-189 4412 y(best)23 b(between)g(absolute)f(and)h +(relati)n(v)o(e)e(representation)i(is)f(chosen)h(and)g(relati)n(v)o(e)f +(1)h(is)f(directly)g(coded)h(in)g Fd(<)p Fl(Node-)-189 +4532 y(code)p Fd(>)e Fl(without)f(an)o(y)g(e)o(xtra)h(info.)29 +b(Suppose)21 b(V)-11 b(ar\(NodeId\),)22 b(Then\(NodeId\))f(and)g +(Else\(NodeId\))f(represent)i(infos)-189 4652 y(about)i(a)h(gi)n(v)o +(en)f(node.)30 b Fd(<)p Fl(Node-code)p Fd(>)25 b Fl(is)f(a)h(byte)g +(which)f(contains)g(the)h(follo)n(wing)e(bit)h(\002elds)h(\(MSB)g(to)g +(LSB\))-44 4856 y Fk(\017)49 b Fl(Unused)24 b(:)31 b(1)24 +b(bit)-44 5059 y Fk(\017)49 b Fl(V)-11 b(ariable:)30 +b(2)25 b(bits,)f(one)h(of)g(the)f(follo)n(wing)f(codes)171 +5288 y Fi(\226)49 b Fl(DDDMP)p 636 5288 30 4 v 35 w(ABSOLUTE)p +1191 5288 V 36 w(ID:)22 b(V)-11 b(ar\(NodeId\))22 b(is)f(represented)h +(in)g(absolute)f(form)g(as)h Fd(<)p Fl(V)-11 b(ar)n(-internal-)270 +5408 y(info)p Fd(>)24 b Fl(=)h(V)-11 b(ar\(NodeId\))25 +b(follo)n(ws)e(\(absolute)i(info\))1794 5800 y(4)p eop +%%Page: 5 5 +5 4 bop 171 218 a Fi(\226)49 b Fl(DDDMP)p 636 218 30 +4 v 35 w(RELA)-11 b(TIVE)p 1147 218 V 36 w(ID:)32 b(V)-11 +b(ar\(NodeId\))32 b(is)g(represented)g(in)f(relati)n(v)o(e)g(form)h(as) +g Fd(<)p Fl(V)-11 b(ar)n(-internal-)270 338 y(info\277)24 +b(=)h(Min\(V)-11 b(ar\(Then\(NodeId\)\),V)g(ar\(Else\(NodeId\)\)\)-V)g +(ar\(NodeId\))171 500 y Fi(\226)49 b Fl(DDDMP)p 636 500 +V 35 w(RELA)-11 b(TIVE)p 1147 500 V 36 w(1:)27 b(the)19 +b(\002eld)g Fd(<)p Fl(V)-11 b(ar)n(-internal-info)p Fd(>)18 +b Fl(does)h(not)f(follo)n(w)-6 b(,)18 b(because)h(V)-11 +b(ar\(NodeId\))270 620 y(=)25 b(Min\(V)-11 b(ar\(Then\(NodeId\)\),V)g +(ar\(Else\(NodeId\)\)\)-1)171 782 y Fi(\226)49 b Fl(DDDMP)p +636 782 V 35 w(TERMIN)m(AL:)24 b(Node)h(is)f(a)h(terminal,)f(no)g(v)n +(ar)h(info)g(required)-44 1011 y Fk(\017)49 b Fl(T)25 +b(:)f(2)h(bits,)f(with)g(codes)h(similar)e(to)i(V)171 +1214 y Fi(\226)49 b Fl(DDDMP)p 636 1214 V 35 w(ABSOLUTE)p +1191 1214 V 36 w(ID:)20 b Fd(<)p Fl(Then-info)p Fd(>)f +Fl(is)h(represented)g(in)g(absolute)f(form)h(as)g Fd(<)p +Fl(Then-info)p Fd(>)270 1334 y Fl(=)25 b(Then\(NodeId\))171 +1496 y Fi(\226)49 b Fl(DDDMP)p 636 1496 V 35 w(RELA)-11 +b(TIVE)p 1147 1496 V 36 w(ID:)28 b(Then\(NodeId\))f(is)g(represented)h +(in)g(relati)n(v)o(e)e(form)i(as)g Fd(<)p Fl(Then-info)p +Fd(>)270 1617 y Fl(=)d(Nodeid-Then\(NodeId\))171 1779 +y Fi(\226)49 b Fl(DDDMP)p 636 1779 V 35 w(RELA)-11 b(TIVE)p +1147 1779 V 36 w(1:)30 b(no)25 b Fd(<)p Fl(Then-info)p +Fd(>)f Fl(follo)n(ws,)f(because)i(Then\(NodeId\))g(=)g(NodeId-1)171 +1941 y Fi(\226)49 b Fl(DDDMP)p 636 1941 V 35 w(TERMIN)m(AL:)24 +b(Then)h(Node)f(is)h(a)g(terminal,)f(no)g(info)h(required)f(\(for)i(R)l +(OBDDs\))-44 2144 y Fk(\017)49 b Fl(Ecompl)24 b(:)30 +b(1)25 b(bit,)f(if)h(1)g(means)f(that)g(the)h(else)g(edge)g(is)f +(complemented)-44 2347 y Fk(\017)49 b Fl(E)25 b(:)f(2)h(bits,)f(with)g +(codes)h(and)f(meanings)g(as)h(for)g(the)g(Then)f(edge)-189 +2551 y(DD)35 b(node)f(codes)h(are)h(written)e(as)h(one)g(byte.)60 +b Fd(<)p Fl(V)-11 b(ar)n(-internal-inde)o(x)p Fd(>)p +Fl(,)36 b Fd(<)p Fl(Then-inde)o(x)p Fd(>)p Fl(,)g Fd(<)p +Fl(Else-inde)o(x)p Fd(>)e Fl(\(if)-189 2671 y(required\))25 +b(are)h(represented)f(as)g(unsigned)e(inte)o(ger)h(v)n(alues)g(on)h(a)g +(suf)n(\002cient)f(set)h(of)g(bytes)f(\(MSByte)h(\002rst\).)47 +2792 y(Inte)o(gers)h(of)f(an)o(y)h(length)e(are)j(written)e(as)h +(sequences)g(of)g(\224link)o(ed\224)f(bytes)g(\(MSByte)h(\002rst\).)34 +b(F)o(or)26 b(each)g(byte)-189 2912 y(7)f(bits)f(are)h(used)g(for)g +(data)g(and)f(one)h(\(MSBit\))g(as)g(link)f(with)g(a)h(further)g(byte)g +(\(MSB)g(=)g(1)g(means)f(one)h(more)g(byte\).)47 3032 +y(Lo)n(w)f(le)n(v)o(el)g(read/write)h(of)g(bytes)f(\002lters)h +Fd(<)p Fl(CR)p Fd(>)p Fl(,)g Fd(<)p Fl(LF)p Fd(>)g Fl(and)g +Fd(<)p Fl(ctrl-Z)p Fd(>)f Fl(through)g(escape)h(sequences.)-189 +3327 y Fj(2.2)119 b(Implementation)-189 3515 y Fl(Store)24 +b(and)g(load)g(for)g(single)g(Boolean)g(functions)f(and)h(arrays)g(of)g +(Boolean)g(functions)f(are)i(implemented.)k(More-)-189 +3635 y(o)o(v)o(er)l(,)37 b(the)e(current)h(presentation)f(includes)f +(functions)h(to)g(retrie)n(v)o(e)g(v)n(ariables)f(names,)k(auxiliary)d +(identi\002erss,)-189 3756 y(and)c(all)g(the)g(information)f(contained) +h(in)f(the)h(header)h(of)f(the)h(\002les.)50 b(This)30 +b(information)g(can)h(be)h(used)f(as)g(a)g(pre-)-189 +3876 y(processing)19 b(step)g(for)i(load)e(operations.)28 +b(These)20 b(functions)f(allo)n(w)f(to)i(o)o(v)o(ercome)f(fe)n(w)g +(limitations)f(of)h(the)h(pre)n(vious)-189 3997 y(implementations.)-189 +4263 y Fi(2.2.1)99 b(Storing)25 b(Decision)g(Diagrams)-189 +4450 y Fc(Dddmp)p 111 4450 V 35 w(cuddBddStor)l(e)f Fl(and)h +Fc(Dddmp)p 1195 4450 V 35 w(cuddBddArr)o(ayStor)l(e)e +Fl(are)j(the)f(tw)o(o)f(store)h(functions,)f(used)h(to)g(store)f(sin-) +-189 4571 y(gle)f(BDD)h(or)g(a)f(forest)h(of)f(BDDs,)h(respecti)n(v)o +(ely)-6 b(.)28 b(Internally)-6 b(,)23 b Fc(Dddmp)p 2275 +4571 V 35 w(cuddBddStor)l(e)f Fl(b)n(uilds)g(a)i(dummy)e(1)h(entry)-189 +4691 y(array)j(of)e(BDDs,)h(and)g(calls)g Fc(dddmp)p +1102 4691 V 35 w(cuddBddArr)o(ayStor)l(e)p Fl(.)47 4811 +y(Since)30 b(con)l(v)o(ersion)e(from)h(DD)h(pointers)e(to)h(inte)o(ger) +f(is)h(required,)i(DD)e(nodes)g(are)h(temporarily)e(remo)o(v)o(ed)-189 +4932 y(from)23 b(the)f(unique)h(hash.)29 b(This)23 b(mak)o(es)f(room)g +(in)h(their)f Fc(ne)n(xt)h Fl(\002eld)h(to)e(store)h(node)f(IDs.)30 +b(Nodes)23 b(are)h(re-link)o(ed)e(after)-189 5052 y(the)i(store)g +(operation,)g(possible)f(in)g(a)i(modi\002ed)e(order)-5 +b(.)31 b(Dumping)22 b(is)i(either)g(in)g(te)o(xt)f(or)i(binary)f(form.) +30 b(Both)24 b(a)g(\002le)-189 5173 y(pointer)31 b(\()p +Fc(fp)p Fl(\))g(and)g(a)h(\002le)g(name)f(\()p Fc(fname)p +Fl(\))h(are)g(pro)o(vided)e(as)h(inputs)f(parameters)i(to)f(store)g +(routines.)50 b(BDDs)31 b(are)-189 5293 y(stored)c(to)g(the)g(already)g +(open)h(\002le)f Fc(fp)p Fl(,)h(if)f(not)g(NULL.)g(Otherwise)f(\002le)i +(whose)f(name)g(is)g Fc(fname)g Fl(is)g(opened.)38 b(This)-189 +5413 y(is)24 b(intended)g(to)h(allo)n(w)f(either)g(DD)h(storage)g +(within)e(\002les)i(containing)f(other)g(data,)h(or)g(to)g(speci\002c)g +(\002les.)1794 5800 y(5)p eop +%%Page: 6 6 +6 5 bop -189 218 a Fi(2.2.2)99 b(Loading)25 b(Decision)g(Diagrams)-189 +405 y Fc(Dddmp)p 111 405 30 4 v 35 w(cuddBddLoad)37 b +Fl(and)h Fc(Dddmp)p 1219 405 V 35 w(cuddBddArr)o(ayLoad)f +Fl(are)h(the)g(load)g(functions,)i(which)e(read)g(a)g(BDD)-189 +526 y(dump)24 b(\002le.)47 646 y(F)o(ollo)n(wing)34 b(the)h(store)h +(function,)h(the)f(main)f(BDD)h(load)f(function,)j Fc(Dddmp)p +2813 646 V 35 w(cuddBddLoad)p Fl(,)f(is)f(imple-)-189 +767 y(mented)g(by)g(calling)f(the)h(main)g(BDD-array)h(loading)f +(function)f Fc(Dddmp)p 2466 767 V 35 w(cuddBddArr)o(ayLoad)p +Fl(.)63 b(A)37 b(dynamic)-189 887 y(v)o(ector)24 b(of)h(DD)g(pointers)f +(is)g(temporarily)g(allocated)h(to)f(support)g(con)l(v)o(ersion)f(from) +i(DD)g(inde)o(x)o(es)e(to)h(pointers.)47 1007 y(Se)n(v)o(eral)40 +b(criteria)f(are)i(supported)d(for)i(v)n(ariable)f(match)g(between)g +(\002le)h(and)g(DD)f(manager)l(,)k(practically)-189 1128 +y(allo)n(wing)37 b(v)n(ariable)h(permutations)f(or)i(compositions)d +(while)i(loading)g(DDs.)71 b(V)-11 b(ariable)39 b(match)f(between)h +(the)-189 1248 y(DD)32 b(manager)g(and)g(the)g(BDD)g(\002le)g(is)g +(optionally)e(based)i(in)f Fc(IDs)p Fl(,)j Fc(perids)p +Fl(,)f Fc(varnames)p Fl(,)g Fc(var)o(auxids)p Fl(;)g(also)f(direct)-189 +1369 y(composition)j(between)j Fc(IDs)g Fl(and)f Fc(composeids)g +Fl(is)g(supported.)68 b(The)38 b Fc(varmatc)o(hmode)e +Fl(parameter)i(is)f(used)g(to)-189 1489 y(select)27 b(mathing)e(mode.) +37 b(More)27 b(in)f(detail,)h(tw)o(o)f(match)h(modes)f(use)h(the)f +(information)g(within)f(the)i(DD)g(manager)l(,)-189 1609 +y(the)e(other)f(ones)h(use)g(e)o(xtra)f(information,)f(which)i(support) +f(an)o(y)g(v)n(ariable)g(remap)h(or)g(change)g(in)f(the)h(ordering.)-44 +1813 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 1813 +V 35 w(V)-13 b(AR)p 1272 1813 V 35 w(MA)i(TCHIDS)19 b(allo)n(ws)f +(loading)g(a)h(DD)g(k)o(eeping)f(v)n(ariable)g(IDs)h(unchanged)55 +1933 y(\(re)o(gardless)24 b(of)h(the)f(v)n(ariable)h(ordering)f(of)h +(the)g(reading)f(manager)-5 b(.)55 2095 y(This)24 b(is)g(useful,)g(for) +h(e)o(xample,)f(when)g(sw)o(apping)g(DDs)g(to)h(\002le)g(and)f +(restoring)g(them)g(later)h(from)f(\002le,)h(after)55 +2215 y(possible)e(v)n(ariable)i(reordering)g(acti)n(v)n(ations.)-44 +2419 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 2419 +V 35 w(V)-13 b(AR)p 1272 2419 V 35 w(MA)i(TCHPERMIDS)36 +b(is)e(used)h(to)f(allo)n(w)g(v)n(ariable)g(match)h(according)55 +2539 y(to)h(the)h(position)e(in)i(the)g(ordering)f(\(retrie)n(v)o(ed)g +(by)h(array)h(of)f(permutations)e(stored)h(on)h(\002le)g(and)g(within) +55 2660 y(the)h(reading)g(DD)h(manager\).)72 b(A)38 b(possible)f +(application)h(is)g(retrie)n(ving)f(BDDs)i(stored)f(after)h(dynamic)55 +2780 y(reordering,)28 b(from)g(a)g(DD)g(manager)g(where)h(all)e(v)n +(ariable)h(IDs)f(map)h(their)f(position)g(in)g(the)h(ordering,)g(and)55 +2900 y(the)d(loaded)f(BDD)h(k)o(eeps)g(the)g(ordering)f(as)h(stored)f +(on)h(\002le.)-44 3104 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p +1040 3104 V 35 w(V)-13 b(AR)p 1272 3104 V 35 w(MA)i(TCHN)m(AMES)26 +b(requires)h(a)h(not)e(NULL)h(v)n(armatchmodes)f(param-)55 +3224 y(eter;)34 b(this)c(is)g(a)h(v)o(ector)g(of)g(strings)e(in)i +(one-to-one)f(correspondence)h(with)f(v)n(ariable)h(IDs)f(of)h(the)g +(reading)55 3344 y(manager)-5 b(.)40 b(V)-11 b(ariables)28 +b(in)g(the)g(DD)g(\002le)g(read)h(are)g(matched)f(with)f(manager)h(v)n +(ariables)f(according)h(to)g(their)55 3465 y(name)35 +b(\(a)h(not)f(NULL)g(v)n(arnames)g(parameter)h(w)o(as)f(required)h +(while)f(storing)f(the)h(DD)g(\002le\).)64 b(The)35 b(most)55 +3585 y(common)c(usage)h(of)g(this)f(feature)i(is)e(in)h(combination)e +(with)i(a)g(v)n(ariable)g(ordering)g(stored)f(on)h(a)g(\002le)h(and)55 +3706 y(based)28 b(on)h(v)n(ariables)f(names.)41 b(Names)29 +b(must)e(be)i(loaded)f(in)g(an)h(array)g(of)g(strings)e(and)i(passed)f +(to)g(the)h(DD)55 3826 y(load)24 b(procedure.)-44 4029 +y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 4029 V +35 w(V)-13 b(AR)p 1272 4029 V 35 w(MA)i(TCHIDS)25 b(has)g(a)g(meaning)f +(similar)g(to)55 4150 y(DDDMP)p 421 4150 V 36 w(V)-13 +b(AR)p 654 4150 V 35 w(MA)i(TCHN)m(AMES)26 b(b)n(ut)h(inte)o(ger)f +(auxiliary)g(IDs)h(are)h(used)f(instead)f(of)h(strings.)36 +b(The)28 b(ad-)55 4270 y(ditional)23 b(not)h(NULL)h(v)n(armathauxids)e +(parameter)i(is)g(needed.)-44 4474 y Fk(\017)49 b Fl(v)n +(armatchnode=DDDMP)p 1040 4474 V 35 w(V)-13 b(AR)p 1272 +4474 V 35 w(COMPOSEIDS,)38 b(uses)f(the)f(additional)f(v)n +(arcomposeids)g(parameter)55 4594 y(as)25 b(an)g(array)g(of)g(v)n +(ariable)f(IDs)h(to)g(be)g(composed)f(with)g(IDs)g(stored)h(in)f +(\002le.)-189 4860 y Fi(2.2.3)99 b(DD)25 b(Load/Stor)n(e)h(and)f(V)-9 +b(ariable)25 b(Ordering)-189 5048 y Fl(Loading)31 b(of)i(Decision)e +(Diagrams)h(from)g(\002le)g(supports)f(dif)n(ferent)h(v)n(ariables)g +(ordering)f(strate)o(gies,)i(as)g(already)-189 5168 y(pointed)23 +b(out)h(in)g(the)h(pre)n(vious)e(section.)30 b(This)24 +b(allo)n(ws)f(or)h(e)o(xample)g(storing)f(dif)n(ferent)i(BDDs)f(each)h +(with)f(its)g(o)n(wn)-189 5288 y(v)n(ariable)29 b(ordering,)h(and)g(to) +f(mer)n(ge)h(them)f(within)f(the)i(same)f(DD)h(manager)f(by)h(means)f +(of)g(proper)h(load)f(opera-)-189 5409 y(tions.)44 b(W)-8 +b(e)30 b(suggest)f(using)f(DDDMP)p 1175 5409 V 36 w(V)-13 +b(AR)p 1408 5409 V 36 w(MA)i(TCHIDS)30 b(whene)n(v)o(er)f(IDs)g(k)o +(eeps)h(on)f(representing)h(the)f(same)-189 5529 y(entities)24 +b(while)h(changing)f(v)n(ariable)h(ordering.)31 b(If)25 +b(this)f(is)h(not)f(true,)h(v)n(ariable)g(names)g(\(if)g(a)n(v)n +(ailable\))f(or)i(auxiliary)1794 5800 y(6)p eop +%%Page: 7 7 +7 6 bop -189 218 a Fl(IDs)34 b(are)h(a)g(good)e(w)o(ay)i(to)f +(represent)g(in)l(v)n(ariant)f(attrib)n(uted)g(of)i(v)n(ariables)e +(across)h(se)n(v)o(eral)g(runs)g(with)f(dif)n(ferent)-189 +338 y(orderings.)50 b(DDDMP)p 629 338 30 4 v 35 w(V)-13 +b(AR)p 861 338 V 36 w(COMPOSEIDS)32 b(is)f(an)h(alternati)n(v)o(e)e +(solution,)h(that)g(practically)f(corresponds)h(to)-189 +459 y(cascading)23 b(DDDMP)p 593 459 V 36 w(V)-13 b(AR)p +826 459 V 36 w(MA)i(TCHIDS)23 b(and)h(v)n(ariable)f(composition)e(with) +h(a)i(gi)n(v)o(en)e(array)i(of)g(ne)n(w)f(v)n(ariables.)-189 +797 y Fo(3)143 b(CNF)35 b(Support)-189 1050 y Fj(3.1)119 +b(F)m(ormat)-189 1237 y Fl(Gi)n(v)o(en)30 b(a)h(BDD)g(representing)g(a) +g(function)f Fd(f)11 b Fl(,)32 b(we)f(de)n(v)o(elop)f(three)h(basic)g +(possible)e(w)o(ays)i(to)g(store)f(it)h(as)g(a)g(CNF)-189 +1358 y(formula.)54 b(In)33 b(each)h(method)d(the)i(set)g(of)f(clauses)h +(is)f(written)h(after)g(an)g(header)g(part.)55 b(Only)32 +b(the)h(te)o(xt)f(format)g(is)-189 1478 y(allo)n(wed.)-189 +1743 y Fi(3.1.1)99 b(Header)-189 1931 y Fl(The)23 b(header)h(part)f(of) +g(each)h(CNF)g(\002le)f(has)g(basically)g(the)f(same)h(format)g +(analyzed)g(for)h(the)f(BDD/ADD)g(\002les.)30 b(F)o(or)-189 +2051 y(e)o(xample)h(the)g Fg(.rootids)f Fl(line)h(indicates)f(the)i(be) +o(ginning)d(of)j(each)g(CNF)g(formula)f(represented)h(by)f(a)h(single) +-189 2172 y(BDD.)j(T)-8 b(o)34 b(be)g(compatible)f(with)h(the)g(DIMA)l +(CS)h(format)f(each)h(header)f(line)g(start)g(with)g(the)g(character)h +(\223c\224)g(to)-189 2292 y(indicate)24 b(a)h(comment.)-189 +2557 y Fi(3.1.2)99 b(T)-9 b(ext)25 b(F)n(ormat)-189 2745 +y Fl(The)j(\002rst)g(method,)g(which)f(we)h(call)g Fi(Single-Node-Cut)p +Fl(,)j(models)26 b(each)j(BDD)f(nodes,)h(b)n(ut)e(the)h(ones)f(with)h +(both)-189 2865 y(the)c(children)g(equal)h(to)f(the)g(constant)g(node)g +Fb(1)p Fl(,)g(as)h(a)g(multiple)o(x)o(er)-5 b(.)27 b(Each)e(multiple)o +(x)o(er)d(has)i(tw)o(o)g(data)h(inputs)e(\(i.e.,)-189 +2985 y(the)k(node)h(children\),)f(a)h(selection)f(input)f(\(i.e.,)i +(the)g(node)f(v)n(ariable\))g(and)h(one)f(output)f(\(i.e.,)i(the)g +(function)e(v)n(alue\))-189 3106 y(whose)h(v)n(alue)f(is)h(assigned)f +(to)h(an)g(additional)f(CNF)i(v)n(ariable.)37 b(The)27 +b(\002nal)h(number)e(of)h(v)n(ariables)g(is)f(equal)h(to)g(the)-189 +3226 y(number)d(of)h(original)f(BDD)h(v)n(ariables)f(plus)g(the)h +(number)f(of)h(\223internal\224)g(nodes)f(of)h(the)g(BDD.)47 +3346 y(The)k(second)f(method,)g(which)h(we)f(call)h Fi(Maxterm-Cut)p +Fl(,)h(create)g(clauses)e(starting)g(from)g Fd(f)39 b +Fl(corresponds)-189 3467 y(to)25 b(the)h(of)n(f-set)g(\(i.e.,)f(all)h +(the)g(paths-cubes)f(from)g(the)h(root)g(node)f(to)h(the)f(terminal)g +Fg(0)p Fl(\))h(of)g(the)g(function)e Fd(f)11 b Fl(.)34 +b(W)l(ithin)-189 3587 y(the)29 b(BDD)g(for)g Fd(f)11 +b Fl(,)30 b(such)f(clauses)f(are)i(found)e(by)h(follo)n(wing)e(all)i +(the)f(paths)h(from)f(the)h(root)g(node)f(of)h(the)g(BDD)g(to)-189 +3708 y(the)c(constant)f(node)g Fb(0)p Fl(.)31 b(The)25 +b(\002nal)g(number)f(of)h(v)n(ariables)f(is)g(equal)h(to)f(the)h +(number)f(of)h(original)f(BDD)h(v)n(ariables.)47 3828 +y(The)k(third)g(method,)g(which)g(we)g(call)g Fi(A)-5 +b(uxiliary-V)c(ariable-Cut)p Fl(,)30 b(is)f(a)h(trade-of)n(f)f(between) +g(the)g(\002rst)g(tw)o(o)-189 3948 y(strate)o(gies.)69 +b(Internal)37 b(v)n(ariables,)j(i.e.,)h(cutting)c(points,)j(are)e +(added)g(in)f(order)h(to)g(decompose)f(the)h(BDD)g(into)-189 +4069 y(multiple)27 b(sub-trees)i(each)h(of)f(which)f(is)h(stored)g +(follo)n(wing)e(the)h(second)h(strate)o(gy)-6 b(.)42 +b(The)29 b(trade-of)n(f)g(is)g(guided)f(by)-189 4189 +y(the)23 b(cutting)f(point)g(selection)g(strate)o(gy)-6 +b(,)22 b(and)h(we)g(e)o(xperiment)f(with)g(tw)o(o)g(methodologies.)28 +b(In)23 b(the)g(\002rst)g(method,)g(a)-189 4310 y(ne)n(w)f(CNF)h(v)n +(ariable)f(is)f(inserted)h(in)g(correspondence)g(to)g(the)g(shared)g +(nodes)g(of)g(the)h(BDD,)f(i.e.,)h(the)f(nodes)f(which)-189 +4430 y(ha)n(v)o(e)29 b(more)g(than)h(one)f(incoming)f(edge.)45 +b(This)29 b(technique,)h(albeit)e(optimizing)g(the)h(number)g(of)h +(literals)e(stored,)-189 4550 y(can)35 b(produce)g(clauses)f(with)g(a)h +(high)f(number)h(of)f(literals)1894 4514 y Fh(2)1933 +4550 y Fl(.)60 b(T)-8 b(o)35 b(a)n(v)n(oid)f(this)g(dra)o(wback,)j(the) +e(second)f(method,)-189 4671 y(introduces)28 b(all)g(the)g(pre)n +(viously)e(indicated)i(cutting)f(points)g(more)h(the)h(ones)f +(necessary)g(to)g(break)h(the)f(length)g(of)-189 4791 +y(the)d(path)f(to)h(a)g(maximum)e(\(user\))i(selected)g(v)n(alue.)47 +4911 y(Actually)-6 b(,)37 b(all)f(the)f(methods)g(described)h(abo)o(v)o +(e)e(can)j(be)e(re-conducted)h(to)g(the)f(basic)h(idea)g(of)g(possibly) +-189 5032 y(breaking)24 b(the)h(BDD)g(through)f(the)g(use)h(of)f +(additional)g(cutting)f(v)n(ariables)h(and)h(dumping)e(the)h(paths)g +(between)h(the)-189 5152 y(root)34 b(of)h(the)f(BDD,)h(the)g(cutting)e +(v)n(ariables)h(and)g(the)h(terminal)e(nodes.)60 b(Such)35 +b(internal)f(cutting)f(v)n(ariables)h(are)-189 5273 y(added)25 +b(al)o(w)o(ays)f(\(for)i(each)f(node\),)g(ne)n(v)o(er)f(or)h(sometimes) +e(respecti)n(v)o(ely)-6 b(.)p -189 5360 1607 4 v -77 +5422 a Ff(2)-40 5452 y Fe(This)27 b(v)n(alue)f(is)i(superiorly)d +(limited)h(by)g(the)h(number)e(of)h(v)n(ariables)g(of)g(the)h(BDD,)g +(i.e.,)h(the)f(longest)f(path)g(from)g(the)h(root)f(to)g(the)-189 +5551 y(terminal)19 b(node.)1794 5800 y Fl(7)p eop +%%Page: 8 8 +8 7 bop 47 218 a Fl(While)33 b(the)f Fc(Single-Node-Cut)h +Fl(method)f(minimizes)f(the)i(length)f(of)h(the)f(clauses)h(produced,)i +(b)n(ut)d(it)g(also)-189 338 y(requires)d(the)h(higher)f(number)g(of)g +(CNF)i(v)n(ariables,)e(the)h Fc(Maxterm-Cut)f Fl(technique)g(minimizes) +f(the)h(number)g(of)-189 459 y(CNF)36 b(v)n(ariables)d(required.)61 +b(This)34 b(adv)n(antage)g(is)g(counter)n(-balanced)h(by)f(the)h(f)o +(act)g(that)f(in)g(the)h(w)o(orst)f(case)h(the)-189 579 +y(number)23 b(of)g(clauses,)g(as)h(well)e(as)i(the)f(total)f(number)h +(of)g(literals,)g(produced)g(is)g(e)o(xponential)e(in)i(the)g(BDD)h +(size)f(\(in)-189 699 y(terms)28 b(of)i(number)e(of)h(nodes\).)43 +b(The)29 b(application)f(of)h(this)f(method)g(is)g(then)h(limited)e(to) +i(the)g(cases)g(in)f(which)h(the)-189 820 y(\223of)n(f-set\224)c(of)f +(the)g(represented)h(function)f Fd(f)35 b Fl(has)24 b(a)h(small)f +(cardinality)-6 b(.)29 b(The)c Fc(A)n(uxiliary-V)-11 +b(ariable-Cut)22 b Fl(strate)o(gy)h(is)-189 940 y(a)k(trade-of)n(f)h +(between)f(the)g(\002rst)g(tw)o(o)g(methods)f(and)h(the)g(ones)f(which) +h(gi)n(v)o(es)f(more)h(compact)f(results.)37 b(As)27 +b(a)h(\002nal)-189 1061 y(remark)f(notice)e(that)h(the)g(method)g(is)f +(able)i(to)f(store)g(both)f(monolithic)f(BDDs)j(and)f(conjuncti)n(v)o +(e)e(forms.)35 b(In)26 b(each)-189 1181 y(case)f(we)g(generate)h(CNF)f +(\002les)g(using)f(the)h(standard)f(DIMA)l(CS)i(format.)-189 +1365 y Fi(Example)f(1)49 b Fc(F)l(igur)l(e)20 b(1)h(shows)f(an)h(e)n +(xample)g(of)f(how)h(our)f(pr)l(ocedur)l(e)h(works)f(to)h(stor)l(e)f(a) +h(small)f(monolithic)f(BDD.)-189 1486 y(F)l(igur)l(e)j(1\(a\))h(r)l +(epr)l(esents)g(a)g(BDD)g(with)g Fb(4)g Fc(nodes.)30 +b(BDD)23 b(variables)f(ar)l(e)h(named)g(after)f(inte)l(g)o(er)g(number) +o(s)h(r)o(anging)-189 1606 y(fr)l(om)k Fb(1)h Fc(to)g +Fb(4)p Fc(,)h(to)f(have)g(an)g(easy-to-follow)f(corr)l(espondence)h +(with)g(the)g(CNF)h(variables.)40 b(F)l(igur)l(e)27 b(1\(b\),)i(\(c\))g +(and)-189 1727 y(\(d\))c(show)g(the)f(corr)l(esponding)f(CNF)j(r)l(epr) +l(esentations)d(g)o(ener)o(ated)h(by)h(our)f(thr)l(ee)h(methods.)30 +b(As)24 b(in)h(the)f(standar)l(d)-189 1847 y(format)i +Fa(p)i Fc(indicates)e(the)h(total)f(number)g(of)h(variables)f(used)h +(\()p Fb(4)g Fc(is)g(the)g(minimum)f(value)h(as)g(the)g(BDD)g(itself)f +(has)-189 1967 y Fb(4)f Fc(variables\),)e(and)i Fa(cnf)g +Fc(the)f(total)g(number)g(of)h(clauses.)47 2088 y(As)i(a)g(\002nal)f(r) +l(emark)h(notice)f(that)g(for)g(this)g(speci\002c)h(e)n(xample)g(the)f +(\223Maxterm-Cut\224)i(appr)l(oac)o(h)d(is)h(the)h(one)-189 +2208 y(whic)o(h)36 b(gives)g(the)g(most)f(compact)h(CNF)h(r)l(epr)l +(esentation)e(b)n(ut)h(also)f(the)h(clause)g(with)g(the)g(lar)l(g)o +(est)g(number)f(of)-189 2328 y(liter)o(als)23 b(\()p +Fb(4)p Fc(\).)188 2471 y + 6339814 10777681 0 0 11709153 19997655 startTexFig + 188 2471 a +%%BeginDocument: bdd.eps +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: bdd.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3c +%%CreationDate: Mon Sep 9 14:21:26 2002 +%%For: quer@pcsq (Stefano Quer) +%%BoundingBox: 0 0 178 304 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 304 moveto 0 0 lineto 178 0 lineto 178 304 lineto closepath clip newpath +-51.0 319.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawEllipse { + /endangle exch def + /startangle exch def + /yrad exch def + /xrad exch def + /y exch def + /x exch def + /savematrix mtrx currentmatrix def + x y tr xrad yrad sc 0 0 1 startangle endangle arc + closepath + savematrix setmatrix + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06299 0.06299 sc +% +% Fig objects follow +% +% Polyline +15.000 slw +n 2010 4515 m 2550 4515 l 2550 5040 l 2010 5040 l + cp gs col0 s gr +/Times-Roman ff 300.00 scf sf +2205 4875 m +gs 1 -1 sc (1) col0 sh gr +% Ellipse +n 1515 1800 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2250 900 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2970 2715 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2280 3705 270 270 0 360 DrawEllipse gs col0 s gr + +7.500 slw +% Ellipse +n 3555 3555 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2712 1726 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2430 4230 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Polyline +15.000 slw +n 2805 2910 m + 2250 3450 l gs col0 s gr +% Polyline + [90] 0 sd +gs clippath +2940 2472 m 3010 2445 l 2931 2239 l 2957 2411 l 2861 2266 l cp +eoclip +n 2460 1110 m + 2970 2445 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 2861 2266 m 2957 2411 l 2931 2239 l 2908 2284 l 2861 2266 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +1478 1511 m 1528 1568 l 1693 1422 l 1542 1506 l 1643 1366 l cp +eoclip +n 2025 1080 m + 1515 1530 l gs col0 s gr gr + +% arrowhead +n 1643 1366 m 1542 1506 l 1693 1422 l 1643 1416 l 1643 1366 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +2212 645 m 2287 645 l 2287 425 l 2250 594 l 2212 425 l cp +eoclip +n 2250 270 m + 2250 630 l gs col0 s gr gr + +% arrowhead +n 2212 425 m 2250 594 l 2287 425 l 2250 459 l 2212 425 l + cp gs 0.00 setgray ef gr col0 s +% Polyline + [90] 0 sd +gs clippath +2692 2664 m 2732 2601 l 2546 2485 l 2670 2606 l 2506 2548 l cp +eoclip +n 1710 2010 m + 2700 2625 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 2506 2548 m 2670 2606 l 2546 2485 l 2555 2534 l 2506 2548 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj + [90] 0 sd +gs clippath +2504 4653 m 2539 4720 l 2733 4616 l 2567 4663 l 2698 4550 l cp +eoclip +n 3180 2910 m 3181 2911 l 3183 2913 l 3186 2916 l 3192 2921 l 3200 2929 l + 3210 2939 l 3223 2951 l 3238 2966 l 3255 2984 l 3274 3003 l + 3295 3025 l 3317 3049 l 3339 3075 l 3362 3103 l 3385 3131 l + 3407 3161 l 3429 3192 l 3450 3225 l 3470 3258 l 3488 3293 l + 3504 3329 l 3519 3367 l 3531 3406 l 3541 3447 l 3548 3490 l + 3552 3536 l 3552 3583 l 3548 3634 l 3540 3686 l 3528 3740 l + 3510 3795 l 3490 3844 l 3467 3892 l 3441 3939 l 3413 3985 l + 3382 4028 l 3350 4070 l 3317 4110 l 3283 4148 l 3248 4184 l + 3211 4219 l 3174 4253 l 3136 4285 l 3098 4316 l 3059 4347 l + 3020 4376 l 2980 4405 l 2941 4432 l 2901 4459 l 2862 4484 l + 2824 4509 l 2787 4532 l 2751 4554 l 2717 4575 l 2686 4593 l + 2657 4610 l 2631 4626 l 2608 4639 l 2589 4650 l 2572 4659 l + 2559 4666 l 2550 4672 l + 2535 4680 l gs col0 s gr gr + [] 0 sd +% arrowhead +0 slj +n 2698 4550 m 2567 4663 l 2733 4616 l 2686 4599 l 2698 4550 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +1985 4734 m 2028 4672 l 1847 4548 l 1965 4675 l 1804 4609 l cp +eoclip +n 1350 2025 m 1349 2026 l 1348 2027 l 1345 2030 l 1340 2035 l 1334 2042 l + 1325 2051 l 1314 2063 l 1301 2078 l 1286 2095 l 1268 2114 l + 1249 2137 l 1227 2161 l 1205 2188 l 1181 2218 l 1156 2249 l + 1131 2282 l 1105 2316 l 1080 2352 l 1054 2390 l 1029 2428 l + 1005 2468 l 981 2509 l 959 2552 l 938 2595 l 918 2640 l + 900 2687 l 884 2736 l 870 2786 l 858 2839 l 848 2894 l + 841 2951 l 837 3011 l 836 3074 l 838 3139 l 845 3206 l + 855 3275 l 870 3345 l 888 3412 l 910 3477 l 934 3542 l + 961 3604 l 990 3665 l 1022 3723 l 1054 3779 l 1088 3833 l + 1124 3885 l 1160 3935 l 1198 3983 l 1236 4029 l 1275 4074 l + 1315 4118 l 1356 4160 l 1397 4201 l 1438 4241 l 1480 4280 l + 1522 4318 l 1563 4355 l 1605 4390 l 1645 4424 l 1685 4457 l + 1723 4488 l 1760 4517 l 1795 4545 l 1827 4570 l 1857 4593 l + 1884 4613 l 1909 4632 l 1930 4647 l 1947 4660 l 1962 4671 l + 1973 4679 l 1982 4686 l + 1995 4695 l gs col0 s gr gr + +% arrowhead +0 slj +n 1804 4609 m 1965 4675 l 1847 4548 l 1854 4598 l 1804 4609 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj + [90] 0 sd +gs clippath +2300 4492 m 2363 4532 l 2481 4347 l 2359 4470 l 2417 4307 l cp +eoclip +n 2340 3960 m 2341 3962 l 2344 3966 l 2348 3973 l 2354 3982 l 2362 3995 l + 2370 4010 l 2379 4028 l 2389 4046 l 2397 4066 l 2406 4088 l + 2413 4111 l 2420 4137 l 2425 4165 l 2429 4197 l 2430 4230 l + 2429 4263 l 2425 4295 l 2420 4323 l 2413 4349 l 2406 4372 l + 2397 4394 l 2389 4414 l 2379 4433 l 2370 4450 l 2362 4465 l + 2354 4478 l + 2340 4500 l gs col0 s gr gr + [] 0 sd +% arrowhead +0 slj +n 2417 4307 m 2359 4470 l 2481 4347 l 2431 4356 l 2417 4307 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +2136 4532 m 2199 4492 l 2082 4307 l 2141 4470 l 2018 4347 l cp +eoclip +n 2160 3960 m 2159 3962 l 2156 3966 l 2152 3973 l 2146 3982 l 2138 3995 l + 2130 4010 l 2121 4028 l 2111 4046 l 2103 4066 l 2094 4088 l + 2087 4111 l 2080 4137 l 2075 4165 l 2071 4197 l 2070 4230 l + 2071 4263 l 2075 4295 l 2080 4323 l 2087 4349 l 2094 4372 l + 2103 4394 l 2111 4414 l 2121 4433 l 2130 4450 l 2138 4465 l + 2146 4478 l + 2160 4500 l gs col0 s gr gr + +% arrowhead +0 slj +n 2018 4347 m 2141 4470 l 2082 4307 l 2068 4356 l 2018 4347 l + cp gs 0.00 setgray ef gr col0 s +/Times-Roman ff 300.00 scf sf +2175 990 m +gs 1 -1 sc (1) col0 sh gr +/Times-Roman ff 300.00 scf sf +1440 1890 m +gs 1 -1 sc (2) col0 sh gr +/Times-Roman ff 300.00 scf sf +2895 2805 m +gs 1 -1 sc (3) col0 sh gr +/Times-Roman ff 300.00 scf sf +2205 3795 m +gs 1 -1 sc (4) col0 sh gr +$F2psEnd +rs + +%%EndDocument + + endTexFig + 531 3990 a Fc(\(a\))1512 2504 y Fg(p)60 b(cnf)f(7)g(11)1512 +2624 y(-5)g(3)h(0)1512 2745 y(-5)f(4)h(0)1512 2865 y(5)g(-3)f(-4)g(0) +1512 2985 y(6)h(-2)f(0)1512 3106 y(6)h(-5)f(0)1512 3226 +y(-6)g(2)h(5)f(0)1512 3347 y(7)h(1)f(5)h(0)1512 3467 +y(-7)f(1)h(-5)f(0)1512 3587 y(7)h(-1)f(-6)g(0)1512 3708 +y(-7)g(-1)h(6)f(0)1512 3828 y(7)h(0)1836 3990 y Fc(\(b\))2541 +2525 y Fg(p)f(cnf)g(4)h(3)2541 2645 y(1)f(-3)h(-4)f(0)2541 +2766 y(-1)g(2)h(3)f(0)2541 2886 y(-1)g(2)h(-3)f(4)h(0)2868 +3048 y Fc(\(c\))2541 3251 y Fg(p)f(cnf)g(5)h(5)2541 3371 +y(-5)f(1)h(0)2541 3492 y(5)f(-1)h(2)f(0)2541 3612 y(-3)g(-4)g(5)h(0) +2541 3733 y(3)f(-5)h(0)2541 3853 y(-3)f(4)h(-5)f(0)2865 +3990 y Fc(\(d\))-189 4138 y Fl(Figure)46 b(1:)71 b(\(a\))47 +b(BDD;)e(\(b\))h(\223Single-Node-Cut\224)g(format;)55 +b(\(c\))46 b(\223Maxterm-Cut\224)g(format;)55 b(\(d\))45 +b(\223)-8 b(Auxiliary-)-189 4258 y(V)d(ariable-Cut\224)25 +b(F)o(ormat.)-189 4625 y Fj(3.2)119 b(Implementation)-189 +4813 y Fl(Store)25 b(and)g(Load)g(for)g(a)g(single)f(BDD)h(or)g(a)g +(forest)g(of)g(BDDs)g(is)f(currently)h(implemented.)-189 +5073 y Fi(3.2.1)99 b(Storing)25 b(Decision)g(Diagrams)f(as)g(CNF)h(F)n +(ormulas)-189 5260 y Fl(As)g(f)o(ar)g(as)g(the)g(storing)e(process)i +(is)f(concerned)i(three)f(possible)e(formats)h(are)i(a)n(v)n(ailable:) +-44 5431 y Fk(\017)49 b Fl(DDDMP)p 421 5431 30 4 v 36 +w(CNF)p 650 5431 V 36 w(MODE)p 980 5431 V 35 w(NODE:)21 +b(store)f(a)h(BDD)h(by)e(introducing)f(an)i(auxiliary)g(v)n(ariable)f +(for)h(each)g(BDD)55 5551 y(node)1794 5800 y(8)p eop +%%Page: 9 9 +9 8 bop -44 218 a Fk(\017)49 b Fl(DDDMP)p 421 218 30 +4 v 36 w(CNF)p 650 218 V 36 w(MODE)p 980 218 V 35 w(MAXTERM:)20 +b(store)g(a)h(BDD)h(by)e(follo)n(wing)f(the)h(maxterm)g(of)h(the)g +(represented)55 338 y(function)-44 542 y Fk(\017)49 b +Fl(DDDMP)p 421 542 V 36 w(CNF)p 650 542 V 36 w(MODE)p +980 542 V 35 w(BEST)-5 b(:)32 b(trade-of)f(between)h(the)f(tw)o(o)f +(pre)n(vious)g(solution,)h(trying)f(to)h(optimize)55 +662 y(the)25 b(number)f(of)h(literals)f(stored.)-189 +865 y(See)c(procedures)f(Dddmp)p 736 865 V 35 w(cuddBddStoreCnf)g(\(to) +g(store)f(a)h(single)f(BDD)i(as)e(a)i(CNF)f(formula\))g(and)g(Dddmp)p +3609 865 V 34 w(cuddBddArrayStoreCnf)-189 986 y(\(to)25 +b(store)f(an)h(array)h(of)f(BDDs)g(as)f(a)i(CNF)f(formula\).)-189 +1252 y Fi(3.2.2)99 b(Loadinf)26 b(CNF)e(F)n(ormulas)g(as)h(BDDs)-189 +1439 y Fl(As)g(f)o(ar)g(as)g(the)g(loading)e(process)i(is)f(concerned)i +(three)f(possible)e(formats)i(are)g(a)n(v)n(ailable:)-44 +1643 y Fk(\017)49 b Fl(DDDMP)p 421 1643 V 36 w(CNF)p +650 1643 V 36 w(MODE)p 980 1643 V 35 w(NO)p 1159 1643 +V 36 w(CONJ:)25 b(Return)g(the)f(Clauses)h(without)f(Conjunction)-44 +1846 y Fk(\017)49 b Fl(DDDMP)p 421 1846 V 36 w(CNF)p +650 1846 V 36 w(MODE)p 980 1846 V 35 w(NO)p 1159 1846 +V 36 w(Q)o(U)l(ANT)-5 b(:)24 b(Return)h(the)g(sets)f(of)h(BDDs)g +(without)f(Quanti\002cation)-44 2050 y Fk(\017)49 b Fl(DDDMP)p +421 2050 V 36 w(CNF)p 650 2050 V 36 w(MODE)p 980 2050 +V 35 w(CONJ)p 1264 2050 V 36 w(Q)o(U)l(ANT)-5 b(:)23 +b(Return)h(the)g(sets)f(of)h(BDDs)g(AFTER)g(Existential)e(Quanti\002-) +55 2170 y(cation)-189 2373 y(See)e(procedures)f(Dddmp)p +736 2373 V 35 w(cuddBddLoadCnf)f(\(to)h(load)f(a)i(CNF)f(formula)g(as)g +(a)g(single)f(BDD\))h(and)g(Dddmp)p 3581 2373 V 35 w +(cuddBddArrayLoadCnf)-189 2494 y(\(to)35 b(load)h(a)g(CNF)g(formula)f +(as)h(an)g(array)g(of)g(BDDs\).)63 b(See)36 b(also)g(Dddmp)p +2485 2494 V 34 w(cuddHeaderLoadCnf)h(to)e(load)g(the)-189 +2614 y(header)25 b(of)g(a)g(CNF)h(\002le)f(to)g(gather)f(information)f +(on)i(the)g(sa)n(v)o(ed)f(structure.)-189 2954 y Fo(4)143 +b(T)-13 b(est)35 b(Pr)m(ogram)f(and)h(Regr)m(ession)f(T)-13 +b(ests)-189 3177 y Fl(The)20 b Fc(testddmp.c)e Fl(\002le,)j(pro)o +(vided)d(with)h(this)f(distrib)n(ution,)g(e)o(x)o(empli\002es)g(some)h +(of)h(the)f(abo)o(v)o(e)g(features.)29 b(Moreo)o(v)o(er)l(,)-189 +3298 y(in)d(the)h Fc(e)n(xp)g Fl(e)o(xperiments)e(a)j(fe)n(w)e +(scripts,)h(named)f Fc(test\241n\277.script)f Fl(are)i(a)n(v)n(ailable) +f(for)h(a)g(sanity)f(check)h(of)g(the)g(tool)-189 3418 +y(and)e(to)f(tak)o(e)h(a)g(look)f(at)h(some)f(runs)h(e)o(x)o +(empli\002cation.)-189 3758 y Fo(5)143 b(Documentation)-189 +3981 y Fl(F)o(or)27 b(further)f(documentation)f(on)i(the)f(package)h +(see)g(the)g(on-line)f(documentation)f(automatically)g(created)i(from) +-189 4102 y(the)e(source)g(code)g(\002les.)-189 4441 +y Fo(6)143 b(Ackno)o(wledgments)-189 4665 y Fl(W)-8 b(e)19 +b(are)h(particular)f(indebted)f(with)g(F)o(abio)g(Somenzi,)i(for)f +(discussions,)f(advice,)i(and)f(for)g(including)e(the)i(DDDMP)-189 +4785 y(package)28 b(into)f(the)h(CUDD)g(distrib)n(ution.)37 +b(W)-8 b(e)29 b(also)e(thank)g(all)h(the)g(user)g(of)g(the)f(package)i +(for)f(their)f(useful)h(indi-)-189 4905 y(cation)c(and)h(comments)f(on) +g(the)h(it.)1794 5800 y(9)p eop +%%Page: 10 10 +10 9 bop -189 218 a Fo(7)143 b(FTP)35 b(Site)-189 441 +y Fl(The)25 b(package)g(is)f(singularly)g(a)n(v)n(ailable)g(from:)-189 +645 y Fg(site:)59 b(ftp.polito.it)-189 765 y(user:)g(anonymous)-189 +885 y(directory:)f(/pub/research/dddmp)-189 1089 y Fl(or)25 +b(directly)f(from)h(the)f(author)h(WEB)g(pages:)-189 +1292 y Fg(WWW:)59 b(http://www.polito.it/\230{cabodi)o(,quer)o(})-189 +1632 y Fo(8)143 b(F)l(eedback)-189 1855 y Fl(Send)25 +b(feedback)h(to:)-189 2059 y Fg(Gianpiero)58 b(Cabodi)g(&)i(Stefano)e +(Quer)-189 2179 y(Politecnico)f(di)j(Torino)-189 2300 +y(Dipartimento)d(di)i(Automatica)f(e)i(Informatica)-189 +2420 y(Corso)f(Duca)g(degli)f(Abruzzi,)g(24)-189 2540 +y(I-10129)g(Torino)-189 2661 y(Italy)-189 2781 y(E-mail:)g +({cabodi,quer}@polito.it)-189 2901 y(WWW:)h +(http://www.polito.it/\230{cabodi)o(,quer)o(})1769 5800 +y Fl(10)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-Letter.ps b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-Letter.ps new file mode 100644 index 000000000..ad51df7c2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-Letter.ps @@ -0,0 +1,1260 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software +%%Title: dddmp-2.0.dvi +%%Pages: 10 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%DocumentFonts: Times-Bold Times-Roman Courier Times-Italic Helvetica +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -t letter -f dddmp-2.0 +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2002.12.11:0557 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", +% version = "0.6", +% date = "22 June 1996", +% filename = "8r.enc", +% email = "kb@@mail.tug.org", +% address = "135 Center Hill Rd. // Plymouth, MA 02360", +% codetable = "ISO/ASCII", +% checksum = "119 662 4424", +% docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." +% @} +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both ASCII and Windows. +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there down to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics +exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub +dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} +ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict +end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ +dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 +roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def +dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} +if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} +def end + +%%EndProcSet +%%BeginProcSet: special.pro +%! +TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N +/vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N +/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N +/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ +/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho +X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B +/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ +/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known +{userdict/md get type/dicttype eq{userdict begin md length 10 add md +maxlength ge{/md md dup length 20 add dict copy def}if end md begin +/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S +atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ +itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll +transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll +curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf +pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} +if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 +-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 +get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip +yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub +neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ +noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop +90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get +neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr +1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr +2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 +-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S +TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ +Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale +}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState +save N userdict maxlength dict begin/magscale true def normalscale +currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts +/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x +psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx +psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub +TR/showpage{}N/erasepage{}N/copypage{}N/p 3 def @MacSetUp}N/doclip{ +psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 +roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath +moveto}N/endTexFig{end psf$SavedState restore}N/@beginspecial{SDict +begin/SpecialSave save N gsave normalscale currentpoint TR +@SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{ +CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto +closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx +sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR +}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse +CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury +lineto closepath clip}if/showpage{}N/erasepage{}N/copypage{}N newpath}N +/@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{end} +repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N +/@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX +currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY +moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X +/yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0 +1 startangle endangle arc savematrix setmatrix}N end + +%%EndProcSet +TeXDict begin 40258431 52099146 1000 600 600 (dddmp-2.0.dvi) +@start /Fa 143[55 1[55 7[28 2[50 99[{TeXBase1Encoding ReEncodeFont}4 +99.6264 /Helvetica rf +%DVIPSBitmapFont: Fb cmr12 12 3 +/Fb 3 53 df<14FF010713E090381F81F890383E007C01FC133F4848EB1F8049130F4848 +EB07C04848EB03E0A2000F15F0491301001F15F8A2003F15FCA390C8FC4815FEA54815FF +B3A46C15FEA56D1301003F15FCA3001F15F8A26C6CEB03F0A36C6CEB07E0000315C06D13 +0F6C6CEB1F806C6CEB3F00013E137C90381F81F8903807FFE0010090C7FC28447CC131> +48 D<143014F013011303131F13FFB5FC13E713071200B3B3B0497E497E007FB6FCA320 +4278C131>I52 D E +%EndDVIPSBitmapFont +/Fc 64[50 29[39 12[55 55 25[44 44 66 44 50 28 39 39 1[50 +50 50 72 28 44 1[28 50 50 28 44 50 44 50 50 10[61 2[50 +4[66 83 55 2[33 2[61 1[72 66 61 61 15[50 2[25 33 25 2[33 +33 37[50 2[{TeXBase1Encoding ReEncodeFont}45 99.6264 +/Times-Italic rf +%DVIPSBitmapFont: Fd cmmi12 12 3 +/Fd 3 103 df60 D<127012FCB4FCEA7FC0EA1FF0EA +07FCEA01FF38007FC0EB1FF0EB07FE903801FF809038007FE0EC1FF8EC03FE913800FF80 +ED3FE0ED0FF8ED03FF030013C0EE3FF0EE0FFCEE01FF9338007FC0EF1FF0EF07FCEF01FF +9438007FC0F01FE0A2F07FC0943801FF00EF07FCEF1FF0EF7FC04C48C7FCEE0FFCEE3FF0 +EEFFC0030390C8FCED0FF8ED3FE0EDFF80DA03FEC9FCEC1FF8EC7FE0903801FF80D907FE +CAFCEB1FF0EB7FC04848CBFCEA07FCEA1FF0EA7FC048CCFC12FC12703B3878B44C>62 +D102 +D E +%EndDVIPSBitmapFont +/Fe 134[42 2[42 42 23 32 28 1[42 42 42 65 23 2[23 42 +42 28 37 42 1[42 37 12[51 10[28 4[60 1[55 19[21 28 21 +44[{TeXBase1Encoding ReEncodeFont}26 83.022 /Times-Roman +rf +%DVIPSBitmapFont: Ff cmr7 7 2 +/Ff 2 51 df<13381378EA01F8121F12FE12E01200B3AB487EB512F8A215267BA521>49 +D<13FF000313E0380E03F0381800F848137C48137E00787F12FC6CEB1F80A4127CC7FC15 +005C143E147E147C5C495A495A5C495A010EC7FC5B5B903870018013E0EA018039030003 +0012065A001FB5FC5A485BB5FCA219267DA521>I E +%EndDVIPSBitmapFont +/Fg 103[60 26[60 1[60 60 60 60 60 60 60 60 60 60 60 60 +60 60 60 60 2[60 60 60 60 60 60 60 60 60 3[60 1[60 3[60 +60 1[60 60 1[60 60 1[60 60 3[60 1[60 1[60 60 60 1[60 +60 1[60 1[60 1[60 60 60 60 60 60 60 60 60 60 60 60 60 +60 60 5[60 38[{TeXBase1Encoding ReEncodeFont}62 99.6264 +/Courier rf +%DVIPSBitmapFont: Fh cmr8 8 2 +/Fh 2 51 df<130C133C137CEA03FC12FFEAFC7C1200B3B113FE387FFFFEA2172C7AAB23 +>49 DI E +%EndDVIPSBitmapFont +/Fi 105[50 28[50 50 2[55 33 39 44 1[55 50 55 83 28 2[28 +1[50 33 44 55 44 55 50 10[72 1[66 55 3[78 72 94 66 3[78 +1[61 66 72 72 66 72 13[50 50 50 1[28 25 33 45[{ +TeXBase1Encoding ReEncodeFont}40 99.6264 /Times-Bold +rf /Fj 139[40 1[53 1[66 60 66 100 33 2[33 3[53 3[60 23[47 +2[73 18[60 60 60 2[30 46[{TeXBase1Encoding ReEncodeFont}16 +119.552 /Times-Bold rf +%DVIPSBitmapFont: Fk cmsy10 12 1 +/Fk 1 16 df<49B4FC010F13E0013F13F8497F48B6FC4815804815C04815E04815F0A248 +15F8A24815FCA3B712FEA96C15FCA36C15F8A26C15F0A26C15E06C15C06C15806C15006C +6C13FC6D5B010F13E0010190C7FC27277BAB32>15 D E +%EndDVIPSBitmapFont +/Fl 64[44 42[44 44 24[44 50 50 72 50 50 28 39 33 50 50 +50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 6[61 1[72 +94 72 72 61 55 66 72 55 72 72 89 61 1[39 33 72 72 55 +61 72 66 66 72 3[56 1[28 28 50 50 50 50 50 50 50 50 50 +50 28 25 33 25 2[33 33 36[55 55 2[{TeXBase1Encoding ReEncodeFont}74 +99.6264 /Times-Roman rf +%DVIPSBitmapFont: Fm cmsy10 14.4 2 +/Fm 2 104 df102 +DI E +%EndDVIPSBitmapFont +/Fn 105[60 27[53 4[60 33 47 40 60 60 60 60 93 33 2[33 +1[60 40 53 60 53 60 53 7[86 4[73 66 1[86 66 3[73 2[40 +1[86 1[73 86 80 1[86 110 5[33 60 4[60 1[60 60 60 1[30 +40 30 44[{TeXBase1Encoding ReEncodeFont}42 119.552 /Times-Roman +rf /Fo 136[104 1[80 48 56 64 1[80 72 80 120 40 80 1[40 +1[72 1[64 80 64 80 72 12[96 80 104 1[88 1[104 135 3[56 +2[88 1[104 104 96 104 6[48 1[72 72 72 72 72 72 72 72 +72 1[36 46[{TeXBase1Encoding ReEncodeFont}41 143.462 +/Times-Bold rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin +%%BeginPaperSize: Letter +letter +%%EndPaperSize + +%%EndSetup +%%Page: 1 1 +1 0 bop 472 600 a Fo(DDDMP:)35 b(Decision)f(Diagram)f(DuMP)j(package) +1480 830 y(Release)e(2.0)462 1230 y Fn(Gianpiero)c(Cabodi)2402 +1232 y(Stef)o(ano)g(Quer)1316 1506 y(Politecnico)g(di)g(T)-10 +b(orino)1024 1656 y(Dip.)30 b(di)g(Automatica)g(e)g(Informatica)1119 +1805 y(Corso)f(Duca)h(de)n(gli)g(Abruzzi)g(24)1277 1955 +y(I\22610129)e(T)-5 b(urin,)29 b(IT)-11 b(AL)f(Y)1038 +2104 y(E-mail:)38 b Fm(f)p Fn(cabodi,quer)p Fm(g)p Fn(@polito.it)-189 +2614 y Fo(1)143 b(Intr)m(oduction)-189 2837 y Fl(The)27 +b(DDDMP)h(package)f(de\002nes)h(formats)f(and)g(rules)g(to)g(store)g +(DD)g(on)g(\002le.)39 b(More)27 b(in)g(particular)g(it)g(contains)g(a) +-189 2958 y(set)e(of)g(functions)e(to)i(dump)e(\(store)i(and)g(load\))g +(DDs)f(and)h(DD)g(forests)f(on)h(\002le)g(in)f(dif)n(ferent)h(formats.) +47 3078 y(In)30 b(the)g(present)g(implementation,)f(BDDs)h(\(R)l +(OBDDs\))h(and)f(ADD)g(\(Algebraic)g(Decision)g(Diagram\))g(of)-189 +3199 y(the)g(CUDD)g(package)g(\(v)o(ersion)f(2.3.0)g(or)h(higher\))g +(are)g(supported.)45 b(These)30 b(structures)f(can)h(be)g(represented)g +(on)-189 3319 y(\002les)25 b(either)g(in)f(te)o(xt,)g(binary)-6 +b(,)24 b(or)h(CNF)g(\(DIMA)l(CS\))h(formats.)47 3439 +y(The)f(main)f(rules)h(used)f(are)i(follo)n(wing)d(rules:)-44 +3643 y Fk(\017)49 b Fl(A)30 b(\002le)h(contains)e(a)i(single)e(BDD/ADD) +h(or)g(a)h(forest)f(of)g(BDDs/ADD,)g(i.e.,)i(a)e(v)o(ector)g(of)g +(Boolean)h(func-)55 3763 y(tions.)-44 3966 y Fk(\017)49 +b Fl(Inte)o(ger)21 b(inde)o(x)o(es)f(are)i(used)f(instead)g(of)g +(pointers)g(to)g(reference)i(nodes.)29 b(BDD/ADD)21 b(nodes)g(are)h +(numbered)55 4087 y(with)j(contiguous)g(numbers,)g(from)h(1)g(to)f +(NNodes)h(\(total)f(number)h(of)g(nodes)g(on)f(a)i(\002le\).)35 +b(0)26 b(is)f(not)h(used)f(to)55 4207 y(allo)n(w)f(ne)o(gati)n(v)o(e)e +(inde)o(x)o(es)h(for)i(complemented)f(edges.)-44 4411 +y Fk(\017)49 b Fl(A)23 b(\002le)g(contains)f(a)h(header)l(,)h +(including)d(se)n(v)o(eral)h(informations)f(about)h(v)n(ariables)h(and) +f(roots)g(of)h(BDD)h(func-)55 4531 y(tions,)32 b(then)e(the)h(list)g +(of)g(nodes.)49 b(The)32 b(header)f(is)g(al)o(w)o(ays)g(represented)h +(in)f(te)o(xt)f(format)h(\(also)g(for)g(binary)55 4651 +y(\002les\).)g(BDDs,)25 b(ADDs,)f(and)h(CNF)h(\002les)f(share)g(a)g +(similar)f(format)g(header)-5 b(.)-44 4855 y Fk(\017)49 +b Fl(BDD/ADD)40 b(nodes)g(are)h(listed)f(follo)n(wing)e(their)i +(numbering,)j(which)d(is)g(produced)g(by)h(a)f(post-order)55 +4975 y(tra)n(v)o(ersal,)24 b(in)h(such)f(a)h(w)o(ay)g(that)g(a)g(node)f +(is)h(al)o(w)o(ays)f(listed)g(after)h(its)f(Then/Else)g(children.)47 +5179 y(In)32 b(the)f(sequel)g(we)g(describe)h(more)f(in)g(detail)f(the) +h(dif)n(ferent)g(formats)g(and)g(procedures)h(a)n(v)n(ailable.)49 +b(First)-189 5299 y(of)26 b(all,)f(we)h(describe)f(BDDs)h(and)g(ADDs)f +(formats)g(and)g(procedure.)33 b(Secondly)-6 b(,)26 b(we)f(concentrate) +h(on)f(CNF)i(\002les,)-189 5419 y(i.e.,)e(ho)n(w)f(to)g(translate)g(a)i +(BDD)f(or)g(a)g(forest)g(of)f(BDDs)h(into)f(a)h(CNF)h(formula)e(and)h +(vice-v)o(ersa.)1794 5800 y(1)p eop +%%Page: 2 2 +2 1 bop -189 218 a Fo(2)143 b(BDD)35 b(and)g(ADD)g(Support)-189 +441 y Fl(In)23 b(this)f(section)g(we)g(describe)h(format)g(and)f +(procedure)h(re)o(garding)f(BDDs)h(and)f(ADDs.)30 b(W)-8 +b(e)23 b(speci\002cally)g(refer)g(to)-189 562 y(BDDs)h(in)g(the)g +(description)e(as)j(ADD)e(may)h(be)g(seen)g(as)h(an)f(e)o(xtension)e +(and)i(will)f(be)h(described)g(later)-5 b(.)30 b(First)24 +b(of)g(all,)-189 682 y(we)29 b(concentrate)f(on)g(the)g(format)g(used)g +(to)g(store)g(these)g(structure,)h(then)f(we)g(describe)h(the)f +(procedure)h(a)n(v)n(ailable)-189 802 y(to)24 b(store)h(and)g(load)f +(them.)-189 1094 y Fj(2.1)119 b(F)m(ormat)-189 1281 y +Fl(BDD)30 b(dump)f(\002les)g(are)i(composed)e(of)g(tw)o(o)g(sections:) +40 b(The)29 b(header)h(and)g(the)f(list)g(of)h(nodes.)44 +b(The)30 b(header)g(has)g(a)-189 1402 y(common)c(\(te)o(xt\))h(format,) +h(while)e(the)i(list)e(of)h(nodes)g(is)g(either)g(in)g(te)o(xt)g(or)g +(binary)g(format.)38 b(In)28 b(te)o(xt)e(format)h(nodes)-189 +1522 y(are)33 b(represented)f(with)f(redundant)g(informations,)h(where) +h(the)f(main)f(goal)g(is)h(readability)-6 b(,)32 b(while)g(the)f +(purpose)-189 1642 y(of)i(binary)f(format)g(is)g(minimizing)e(the)i(o)o +(v)o(erall)f(storage)h(size)h(for)g(BDD)f(nodes.)54 b(The)32 +b(header)h(format)f(is)g(k)o(ept)-189 1763 y(common)h(to)h(te)o(xt)g +(and)g(binary)g(formats)g(for)h(sak)o(e)f(of)h(simplicity:)47 +b(No)34 b(particular)g(optimization)f(is)h(presently)-189 +1883 y(done)29 b(on)f(binary)h(\002le)g(headers,)h(whose)f(size)g(is)f +(by)h(f)o(ar)g(dominated)f(by)h(node)f(lists)g(in)g(the)h(case)g(of)g +(lar)n(ge)h(BDDs)-189 2003 y(\(se)n(v)o(eral)24 b(thousands)g(of)h(DD)f +(nodes\).)-189 2266 y Fi(2.1.1)99 b(Header)-189 2453 +y Fl(The)23 b(header)h(has)f(the)g(same)g(format)g(both)g(for)g(te)o +(xtual)f(and)i(binary)e(dump.)30 b(F)o(or)23 b(sak)o(e)g(of)h +(generality)e(and)h(because)-189 2574 y(of)f(dynamic)g(v)n(ariable)g +(ordering)g(both)f(v)n(ariable)h(IDs)g(and)g(permutations)2377 +2537 y Fh(1)2438 2574 y Fl(are)h(included.)29 b(Names)22 +b(are)h(optionally)-189 2694 y(listed)35 b(for)h(input)f(v)n(ariables)g +(and)h(for)h(the)e(stored)h(functions.)63 b(Ne)n(w)36 +b(auxiliary)f(IDs)h(are)h(also)e(allo)n(wed.)64 b(Only)-189 +2814 y(the)34 b(v)n(ariables)f(in)g(the)h(true)g(support)f(of)h(the)f +(stored)h(BDDs)g(are)h(listed.)56 b(All)34 b(information)e(on)i(v)n +(ariables)f(\(IDs,)-189 2935 y(permutations,)c(names,)i(auxiliary)e +(IDs\))h(sorted)g(by)g(IDs,)h(and)e(the)o(y)h(are)g(restricted)g(to)f +(the)h(true)g(support)f(of)h(the)-189 3055 y(dumped)22 +b(BDD,)h(while)g(IDs)g(and)f(permutations)g(are)h(referred)i(to)d(the)h +(writing)f(BDD)h(manager)-5 b(.)30 b(Names)22 b(can)i(thus)-189 +3175 y(be)h(sorted)f(by)h(v)n(ariable)f(ordering)h(by)f(permuting)g +(them)g(according)h(to)f(the)h(permutations)e(stored)h(in)h(the)f +(\002le.)47 3296 y(As)h(an)g(e)o(xample,)f(the)g(header)i(\(in)e(te)o +(xt)g(mode\))h(of)f(the)h(ne)o(xt)f(state)h(functions)e(of)i(circuit)g +(s27)f(follo)n(ws:)-189 3494 y Fg(.ver)59 b(DDDMP-2.0)-189 +3615 y(.mode)g(A)-189 3735 y(.varinfo)f(3)-189 3855 y(.dd)h(s27-delta) +-189 3976 y(.nnodes)f(16)-189 4096 y(.nvars)g(10)-189 +4216 y(.nsuppvars)g(7)-189 4337 y(.varnames)g(G0)h(G1)g(G2)h(G3)f(G5)g +(G6)h(G7)-189 4457 y(.orderedvarnames)c(G0)k(G1)f(G2)g(G3)h(G5)f(G6)g +(G7)-189 4578 y(.ids)g(0)g(1)h(2)g(3)f(4)h(5)f(6)-189 +4698 y(.permids)f(0)i(1)f(2)h(3)f(5)h(7)f(9)-189 4818 +y(.auxids)f(1)i(2)f(3)h(4)f(5)h(6)g(7)-189 4939 y(.nroots)e(3)-189 +5059 y(.rootids)g(6)i(-13)f(-16)-189 5179 y(.rootnames)f(G10)h(G11)g +(G13)47 5378 y Fl(The)25 b(lines)f(contain)g(the)h(follo)n(wing)e +(informations:)p -189 5460 1607 4 v -77 5521 a Ff(1)-40 +5551 y Fe(The)d(permutation)e(of)i(the)g(i-th)h(v)n(ariable)e(ID)h(is)h +(the)f(relati)n(v)o(e)g(position)f(of)h(the)g(v)n(ariable)f(in)i(the)f +(ordering.)1794 5800 y Fl(2)p eop +%%Page: 3 3 +3 2 bop -44 218 a Fk(\017)49 b Fl(Dddmp)24 b(v)o(ersion)f(information.) +-44 411 y Fk(\017)49 b Fl(File)25 b(mode)f(\(A)h(for)g(ASCII)h(te)o +(xt,)e(B)h(for)g(binary)g(mode\).)-44 604 y Fk(\017)49 +b Fl(V)-11 b(ar)n(-e)o(xtra-info)25 b(\(0:)30 b(v)n(ariable)24 +b(ID,)h(1:)31 b(permID,)24 b(2:)31 b(aux)25 b(ID,)g(3:)30 +b(v)n(ariable)24 b(name,)h(4)g(no)f(e)o(xtra)h(info\).)-44 +797 y Fk(\017)49 b Fl(Name)25 b(of)g(dd)f(\(optional\).)-44 +990 y Fk(\017)49 b Fl(T)-8 b(otal)24 b(number)g(of)h(nodes)g(in)f(the)h +(\002le.)-44 1183 y Fk(\017)49 b Fl(Number)24 b(of)h(v)n(ariables)f(of) +h(the)g(writing)f(DD)g(manager)-5 b(.)-44 1375 y Fk(\017)49 +b Fl(Number)24 b(of)h(v)n(ariables)f(in)h(the)f(true)h(support)f(of)h +(the)f(stored)h(DDs.)-44 1568 y Fk(\017)49 b Fl(V)-11 +b(ariable)25 b(names)f(\(optional\))g(for)h(all)g(the)f(v)n(ariables)g +(in)h(the)f(BDD/ADD)h(support.)-44 1761 y Fk(\017)49 +b Fl(V)-11 b(ariable)20 b(names)g(for)h(all)f(the)g(v)n(ariables)f(in)h +(the)g(DD)h(manager)f(during)g(the)g(storing)f(phase.)29 +b(Notice)20 b(that)g(this)55 1882 y(information)k(w)o(as)h(not)g +(stored)g(by)g(pre)n(vious)f(v)o(ersions)g(of)i(the)f(same)g(tool.)32 +b(Full)25 b(backw)o(ard)g(compatibility)55 2002 y(is)f(guaranteed)h(by) +g(the)f(present)h(implementation)d(of)j(the)g(tool.)-44 +2195 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(IDs.)-44 +2388 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(permuted)f(IDs.)-44 +2581 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(auxiliary)f(IDs)h +(\(optional\).)-44 2774 y Fk(\017)49 b Fl(Number)24 b(of)h(BDD)g +(roots.)-44 2967 y Fk(\017)49 b Fl(Inde)o(x)o(es)24 b(of)h(BDD)g(roots) +f(\(complemented)g(edges)g(allo)n(wed\).)-44 3160 y Fk(\017)49 +b Fl(Names)24 b(of)h(BDD)h(roots)e(\(optional\).)-189 +3332 y(Notice)h(that)f(a)h(\002eld)-189 3504 y Fg(.add)-189 +3676 y Fl(is)f(present)h(after)g(the)g(dddmp)f(v)o(ersion)f(for)j +(\002les)e(containing)g(ADDs.)-189 3936 y Fi(2.1.2)99 +b(T)-9 b(ext)25 b(F)n(ormat)-189 4124 y Fl(In)g(te)o(xt)f(mode)g(nodes) +g(are)i(listed)e(on)g(a)h(te)o(xt)f(line)h(basis.)30 +b(Each)25 b(a)g(node)f(is)h(represented)g(as)-189 4296 +y Fg()57 b([])f()588 +4416 y()h()-189 4588 y Fl(where)25 +b(all)g(inde)o(x)o(es)e(are)j(inte)o(ger)e(numbers.)47 +4709 y(This)h(format)g(is)g(redundant)f(\(due)i(to)f(the)g(node)g +(ordering,)g Fd(<)p Fl(Node-inde)o(x)p Fd(>)f Fl(is)g(and)i +(incremental)e(inte)o(ger\))-189 4829 y(b)n(ut)g(we)h(k)o(eep)g(it)g +(for)g(readability)-6 b(.)47 4949 y Fd(<)p Fl(V)-11 b(ar)n(-e)o +(xtra-info)p Fd(>)34 b Fl(\(optional)e(redundant)i(\002eld\))g(is)f +(either)h(an)g(inte)o(ger)f(\(ID,)h(PermID,)g(or)g(auxID\))g(or)g(a) +-189 5070 y(string)k(\(v)n(ariable)h(name\).)75 b Fd(<)p +Fl(V)-11 b(ar)n(-internal-inde)o(x)p Fd(>)38 b Fl(is)h(an)g(internal)g +(v)n(ariable)g(inde)o(x:)59 b(V)-11 b(ariables)39 b(in)g(the)g(true) +-189 5190 y(support)25 b(of)h(the)g(stored)g(BDDs)g(are)h(numbered)e +(with)g(ascending)h(inte)o(gers)f(starting)g(from)h(0,)g(and)g(follo)n +(wing)e(the)-189 5311 y(v)n(ariable)g(ordering.)31 b +Fd(<)p Fl(Then-inde)o(x)p Fd(>)23 b Fl(and)i Fd(<)p Fl(Else-inde)o(x)p +Fd(>)e Fl(are)j(signed)e(inde)o(x)o(es)f(of)i(children)f(nodes.)47 +5431 y(In)h(the)f(follo)n(wing,)f(we)i(report)f(the)g(list)g(of)h +(nodes)f(of)g(the)h(s27)f(ne)o(xt)f(state)i(functions)e(\(see)i(pre)n +(vious)e(header)-189 5551 y(e)o(xample\):)1794 5800 y(3)p +eop +%%Page: 4 4 +4 3 bop -189 218 a Fg(.nodes)-189 338 y(1)60 b(T)f(1)h(0)f(0)-189 +459 y(2)h(G7)f(6)g(1)h(-1)-189 579 y(3)g(G5)f(4)g(1)h(2)-189 +699 y(4)g(G3)f(3)g(3)h(1)-189 820 y(5)g(G1)f(1)g(1)h(4)-189 +940 y(6)g(G0)f(0)g(5)h(-1)-189 1061 y(7)g(G6)f(5)g(1)h(-1)-189 +1181 y(8)g(G5)f(4)g(1)h(-7)-189 1301 y(9)g(G6)f(5)g(1)h(-2)-189 +1422 y(10)f(G5)h(4)f(1)h(-9)-189 1542 y(11)f(G3)h(3)f(10)h(8)-189 +1662 y(12)f(G1)h(1)f(8)h(11)-189 1783 y(13)f(G0)h(0)f(5)h(12)-189 +1903 y(14)f(G2)h(2)f(1)h(-1)-189 2024 y(15)f(G2)h(2)f(1)h(-2)-189 +2144 y(16)f(G1)h(1)f(14)h(15)-189 2264 y(.end)-189 2468 +y Fl(The)27 b(list)f(is)h(enclosed)g(between)g(the)g +Fg(.nodes)f Fl(and)h Fg(.end)f Fl(lines.)37 b(First)27 +b(node)g(is)g(the)g(one)g(constant,)f(each)i(node)-189 +2588 y(contains)c(the)h(optional)e(v)n(ariable)h(name.)47 +2708 y(F)o(or)29 b(ADDs)f(more)h(than)f(one)h(constant)e(is)i(stored)f +(in)g(the)g(\002le.)43 b(Each)29 b(constant)f(has)g(the)h(same)f +(format)h(we)-189 2829 y(ha)n(v)o(e)c(just)e(analyzed)i(for)g(the)g +(BDD)g(b)n(ut)g(the)f(represented)h(v)n(alue)f(is)h(stored)f(as)h(a)g +(\003oat)g(number)-5 b(.)-189 3095 y Fi(2.1.3)99 b(Binary)25 +b(F)n(ormat)-189 3283 y Fl(The)h(binary)g(format)f(is)h(not)f(allo)n +(wed)g(for)i(ADDs.)33 b(As)26 b(a)h(consequence)f(we)g(concentrate)g +(only)f(on)h(BDDs)g(in)g(this)-189 3403 y(section.)k(In)25 +b(binary)f(mode)h(nodes)f(are)i(represented)f(as)g(a)g(sequence)g(of)g +(bytes,)f(encoding)g(tuples)-189 3606 y Fg()-189 +3727 y([])-189 3847 y([])-189 +3968 y([])-189 4171 y Fl(in)30 b(an)g(optimized)f(w)o(ay)-6 +b(.)46 b(Only)29 b(the)h(\002rst)g(byte)g(\(code\))h(is)e(mandatory)-6 +b(,)30 b(while)g(inte)o(ger)f(inde)o(x)o(es)g(are)i(represented)-189 +4291 y(in)c(absolute)f(or)h(relati)n(v)o(e)f(mode,)h(where)h(relati)n +(v)o(e)e(means)g(of)n(fset)h(with)f(respect)i(to)e(a)i(Then/Else)e +(node)h(info.)37 b(The)-189 4412 y(best)23 b(between)g(absolute)f(and)h +(relati)n(v)o(e)e(representation)i(is)f(chosen)h(and)g(relati)n(v)o(e)f +(1)h(is)f(directly)g(coded)h(in)g Fd(<)p Fl(Node-)-189 +4532 y(code)p Fd(>)e Fl(without)f(an)o(y)g(e)o(xtra)h(info.)29 +b(Suppose)21 b(V)-11 b(ar\(NodeId\),)22 b(Then\(NodeId\))f(and)g +(Else\(NodeId\))f(represent)i(infos)-189 4652 y(about)i(a)h(gi)n(v)o +(en)f(node.)30 b Fd(<)p Fl(Node-code)p Fd(>)25 b Fl(is)f(a)h(byte)g +(which)f(contains)g(the)h(follo)n(wing)e(bit)h(\002elds)h(\(MSB)g(to)g +(LSB\))-44 4856 y Fk(\017)49 b Fl(Unused)24 b(:)31 b(1)24 +b(bit)-44 5059 y Fk(\017)49 b Fl(V)-11 b(ariable:)30 +b(2)25 b(bits,)f(one)h(of)g(the)f(follo)n(wing)f(codes)171 +5288 y Fi(\226)49 b Fl(DDDMP)p 636 5288 30 4 v 35 w(ABSOLUTE)p +1191 5288 V 36 w(ID:)22 b(V)-11 b(ar\(NodeId\))22 b(is)f(represented)h +(in)g(absolute)f(form)g(as)h Fd(<)p Fl(V)-11 b(ar)n(-internal-)270 +5408 y(info)p Fd(>)24 b Fl(=)h(V)-11 b(ar\(NodeId\))25 +b(follo)n(ws)e(\(absolute)i(info\))1794 5800 y(4)p eop +%%Page: 5 5 +5 4 bop 171 218 a Fi(\226)49 b Fl(DDDMP)p 636 218 30 +4 v 35 w(RELA)-11 b(TIVE)p 1147 218 V 36 w(ID:)32 b(V)-11 +b(ar\(NodeId\))32 b(is)g(represented)g(in)f(relati)n(v)o(e)g(form)h(as) +g Fd(<)p Fl(V)-11 b(ar)n(-internal-)270 338 y(info\277)24 +b(=)h(Min\(V)-11 b(ar\(Then\(NodeId\)\),V)g(ar\(Else\(NodeId\)\)\)-V)g +(ar\(NodeId\))171 500 y Fi(\226)49 b Fl(DDDMP)p 636 500 +V 35 w(RELA)-11 b(TIVE)p 1147 500 V 36 w(1:)27 b(the)19 +b(\002eld)g Fd(<)p Fl(V)-11 b(ar)n(-internal-info)p Fd(>)18 +b Fl(does)h(not)f(follo)n(w)-6 b(,)18 b(because)h(V)-11 +b(ar\(NodeId\))270 620 y(=)25 b(Min\(V)-11 b(ar\(Then\(NodeId\)\),V)g +(ar\(Else\(NodeId\)\)\)-1)171 782 y Fi(\226)49 b Fl(DDDMP)p +636 782 V 35 w(TERMIN)m(AL:)24 b(Node)h(is)f(a)h(terminal,)f(no)g(v)n +(ar)h(info)g(required)-44 1011 y Fk(\017)49 b Fl(T)25 +b(:)f(2)h(bits,)f(with)g(codes)h(similar)e(to)i(V)171 +1214 y Fi(\226)49 b Fl(DDDMP)p 636 1214 V 35 w(ABSOLUTE)p +1191 1214 V 36 w(ID:)20 b Fd(<)p Fl(Then-info)p Fd(>)f +Fl(is)h(represented)g(in)g(absolute)f(form)h(as)g Fd(<)p +Fl(Then-info)p Fd(>)270 1334 y Fl(=)25 b(Then\(NodeId\))171 +1496 y Fi(\226)49 b Fl(DDDMP)p 636 1496 V 35 w(RELA)-11 +b(TIVE)p 1147 1496 V 36 w(ID:)28 b(Then\(NodeId\))f(is)g(represented)h +(in)g(relati)n(v)o(e)e(form)i(as)g Fd(<)p Fl(Then-info)p +Fd(>)270 1617 y Fl(=)d(Nodeid-Then\(NodeId\))171 1779 +y Fi(\226)49 b Fl(DDDMP)p 636 1779 V 35 w(RELA)-11 b(TIVE)p +1147 1779 V 36 w(1:)30 b(no)25 b Fd(<)p Fl(Then-info)p +Fd(>)f Fl(follo)n(ws,)f(because)i(Then\(NodeId\))g(=)g(NodeId-1)171 +1941 y Fi(\226)49 b Fl(DDDMP)p 636 1941 V 35 w(TERMIN)m(AL:)24 +b(Then)h(Node)f(is)h(a)g(terminal,)f(no)g(info)h(required)f(\(for)i(R)l +(OBDDs\))-44 2144 y Fk(\017)49 b Fl(Ecompl)24 b(:)30 +b(1)25 b(bit,)f(if)h(1)g(means)f(that)g(the)h(else)g(edge)g(is)f +(complemented)-44 2347 y Fk(\017)49 b Fl(E)25 b(:)f(2)h(bits,)f(with)g +(codes)h(and)f(meanings)g(as)h(for)g(the)g(Then)f(edge)-189 +2551 y(DD)35 b(node)f(codes)h(are)h(written)e(as)h(one)g(byte.)60 +b Fd(<)p Fl(V)-11 b(ar)n(-internal-inde)o(x)p Fd(>)p +Fl(,)36 b Fd(<)p Fl(Then-inde)o(x)p Fd(>)p Fl(,)g Fd(<)p +Fl(Else-inde)o(x)p Fd(>)e Fl(\(if)-189 2671 y(required\))25 +b(are)h(represented)f(as)g(unsigned)e(inte)o(ger)h(v)n(alues)g(on)h(a)g +(suf)n(\002cient)f(set)h(of)g(bytes)f(\(MSByte)h(\002rst\).)47 +2792 y(Inte)o(gers)h(of)f(an)o(y)h(length)e(are)j(written)e(as)h +(sequences)g(of)g(\224link)o(ed\224)f(bytes)g(\(MSByte)h(\002rst\).)34 +b(F)o(or)26 b(each)g(byte)-189 2912 y(7)f(bits)f(are)h(used)g(for)g +(data)g(and)f(one)h(\(MSBit\))g(as)g(link)f(with)g(a)h(further)g(byte)g +(\(MSB)g(=)g(1)g(means)f(one)h(more)g(byte\).)47 3032 +y(Lo)n(w)f(le)n(v)o(el)g(read/write)h(of)g(bytes)f(\002lters)h +Fd(<)p Fl(CR)p Fd(>)p Fl(,)g Fd(<)p Fl(LF)p Fd(>)g Fl(and)g +Fd(<)p Fl(ctrl-Z)p Fd(>)f Fl(through)g(escape)h(sequences.)-189 +3327 y Fj(2.2)119 b(Implementation)-189 3515 y Fl(Store)24 +b(and)g(load)g(for)g(single)g(Boolean)g(functions)f(and)h(arrays)g(of)g +(Boolean)g(functions)f(are)i(implemented.)k(More-)-189 +3635 y(o)o(v)o(er)l(,)37 b(the)e(current)h(presentation)f(includes)f +(functions)h(to)g(retrie)n(v)o(e)g(v)n(ariables)f(names,)k(auxiliary)d +(identi\002erss,)-189 3756 y(and)c(all)g(the)g(information)f(contained) +h(in)f(the)h(header)h(of)f(the)h(\002les.)50 b(This)30 +b(information)g(can)h(be)h(used)f(as)g(a)g(pre-)-189 +3876 y(processing)19 b(step)g(for)i(load)e(operations.)28 +b(These)20 b(functions)f(allo)n(w)f(to)i(o)o(v)o(ercome)f(fe)n(w)g +(limitations)f(of)h(the)h(pre)n(vious)-189 3997 y(implementations.)-189 +4263 y Fi(2.2.1)99 b(Storing)25 b(Decision)g(Diagrams)-189 +4450 y Fc(Dddmp)p 111 4450 V 35 w(cuddBddStor)l(e)f Fl(and)h +Fc(Dddmp)p 1195 4450 V 35 w(cuddBddArr)o(ayStor)l(e)e +Fl(are)j(the)f(tw)o(o)f(store)h(functions,)f(used)h(to)g(store)f(sin-) +-189 4571 y(gle)f(BDD)h(or)g(a)f(forest)h(of)f(BDDs,)h(respecti)n(v)o +(ely)-6 b(.)28 b(Internally)-6 b(,)23 b Fc(Dddmp)p 2275 +4571 V 35 w(cuddBddStor)l(e)f Fl(b)n(uilds)g(a)i(dummy)e(1)h(entry)-189 +4691 y(array)j(of)e(BDDs,)h(and)g(calls)g Fc(dddmp)p +1102 4691 V 35 w(cuddBddArr)o(ayStor)l(e)p Fl(.)47 4811 +y(Since)30 b(con)l(v)o(ersion)e(from)h(DD)h(pointers)e(to)h(inte)o(ger) +f(is)h(required,)i(DD)e(nodes)g(are)h(temporarily)e(remo)o(v)o(ed)-189 +4932 y(from)23 b(the)f(unique)h(hash.)29 b(This)23 b(mak)o(es)f(room)g +(in)h(their)f Fc(ne)n(xt)h Fl(\002eld)h(to)e(store)h(node)f(IDs.)30 +b(Nodes)23 b(are)h(re-link)o(ed)e(after)-189 5052 y(the)i(store)g +(operation,)g(possible)f(in)g(a)i(modi\002ed)e(order)-5 +b(.)31 b(Dumping)22 b(is)i(either)g(in)g(te)o(xt)f(or)i(binary)f(form.) +30 b(Both)24 b(a)g(\002le)-189 5173 y(pointer)31 b(\()p +Fc(fp)p Fl(\))g(and)g(a)h(\002le)g(name)f(\()p Fc(fname)p +Fl(\))h(are)g(pro)o(vided)e(as)h(inputs)f(parameters)i(to)f(store)g +(routines.)50 b(BDDs)31 b(are)-189 5293 y(stored)c(to)g(the)g(already)g +(open)h(\002le)f Fc(fp)p Fl(,)h(if)f(not)g(NULL.)g(Otherwise)f(\002le)i +(whose)f(name)g(is)g Fc(fname)g Fl(is)g(opened.)38 b(This)-189 +5413 y(is)24 b(intended)g(to)h(allo)n(w)f(either)g(DD)h(storage)g +(within)e(\002les)i(containing)f(other)g(data,)h(or)g(to)g(speci\002c)g +(\002les.)1794 5800 y(5)p eop +%%Page: 6 6 +6 5 bop -189 218 a Fi(2.2.2)99 b(Loading)25 b(Decision)g(Diagrams)-189 +405 y Fc(Dddmp)p 111 405 30 4 v 35 w(cuddBddLoad)37 b +Fl(and)h Fc(Dddmp)p 1219 405 V 35 w(cuddBddArr)o(ayLoad)f +Fl(are)h(the)g(load)g(functions,)i(which)e(read)g(a)g(BDD)-189 +526 y(dump)24 b(\002le.)47 646 y(F)o(ollo)n(wing)34 b(the)h(store)h +(function,)h(the)f(main)f(BDD)h(load)f(function,)j Fc(Dddmp)p +2813 646 V 35 w(cuddBddLoad)p Fl(,)f(is)f(imple-)-189 +767 y(mented)g(by)g(calling)f(the)h(main)g(BDD-array)h(loading)f +(function)f Fc(Dddmp)p 2466 767 V 35 w(cuddBddArr)o(ayLoad)p +Fl(.)63 b(A)37 b(dynamic)-189 887 y(v)o(ector)24 b(of)h(DD)g(pointers)f +(is)g(temporarily)g(allocated)h(to)f(support)g(con)l(v)o(ersion)f(from) +i(DD)g(inde)o(x)o(es)e(to)h(pointers.)47 1007 y(Se)n(v)o(eral)40 +b(criteria)f(are)i(supported)d(for)i(v)n(ariable)f(match)g(between)g +(\002le)h(and)g(DD)f(manager)l(,)k(practically)-189 1128 +y(allo)n(wing)37 b(v)n(ariable)h(permutations)f(or)i(compositions)d +(while)i(loading)g(DDs.)71 b(V)-11 b(ariable)39 b(match)f(between)h +(the)-189 1248 y(DD)32 b(manager)g(and)g(the)g(BDD)g(\002le)g(is)g +(optionally)e(based)i(in)f Fc(IDs)p Fl(,)j Fc(perids)p +Fl(,)f Fc(varnames)p Fl(,)g Fc(var)o(auxids)p Fl(;)g(also)f(direct)-189 +1369 y(composition)j(between)j Fc(IDs)g Fl(and)f Fc(composeids)g +Fl(is)g(supported.)68 b(The)38 b Fc(varmatc)o(hmode)e +Fl(parameter)i(is)f(used)g(to)-189 1489 y(select)27 b(mathing)e(mode.) +37 b(More)27 b(in)f(detail,)h(tw)o(o)f(match)h(modes)f(use)h(the)f +(information)g(within)f(the)i(DD)g(manager)l(,)-189 1609 +y(the)e(other)f(ones)h(use)g(e)o(xtra)f(information,)f(which)i(support) +f(an)o(y)g(v)n(ariable)g(remap)h(or)g(change)g(in)f(the)h(ordering.)-44 +1813 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 1813 +V 35 w(V)-13 b(AR)p 1272 1813 V 35 w(MA)i(TCHIDS)19 b(allo)n(ws)f +(loading)g(a)h(DD)g(k)o(eeping)f(v)n(ariable)g(IDs)h(unchanged)55 +1933 y(\(re)o(gardless)24 b(of)h(the)f(v)n(ariable)h(ordering)f(of)h +(the)g(reading)f(manager)-5 b(.)55 2095 y(This)24 b(is)g(useful,)g(for) +h(e)o(xample,)f(when)g(sw)o(apping)g(DDs)g(to)h(\002le)g(and)f +(restoring)g(them)g(later)h(from)f(\002le,)h(after)55 +2215 y(possible)e(v)n(ariable)i(reordering)g(acti)n(v)n(ations.)-44 +2419 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 2419 +V 35 w(V)-13 b(AR)p 1272 2419 V 35 w(MA)i(TCHPERMIDS)36 +b(is)e(used)h(to)f(allo)n(w)g(v)n(ariable)g(match)h(according)55 +2539 y(to)h(the)h(position)e(in)i(the)g(ordering)f(\(retrie)n(v)o(ed)g +(by)h(array)h(of)f(permutations)e(stored)h(on)h(\002le)g(and)g(within) +55 2660 y(the)h(reading)g(DD)h(manager\).)72 b(A)38 b(possible)f +(application)h(is)g(retrie)n(ving)f(BDDs)i(stored)f(after)h(dynamic)55 +2780 y(reordering,)28 b(from)g(a)g(DD)g(manager)g(where)h(all)e(v)n +(ariable)h(IDs)f(map)h(their)f(position)g(in)g(the)h(ordering,)g(and)55 +2900 y(the)d(loaded)f(BDD)h(k)o(eeps)g(the)g(ordering)f(as)h(stored)f +(on)h(\002le.)-44 3104 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p +1040 3104 V 35 w(V)-13 b(AR)p 1272 3104 V 35 w(MA)i(TCHN)m(AMES)26 +b(requires)h(a)h(not)e(NULL)h(v)n(armatchmodes)f(param-)55 +3224 y(eter;)34 b(this)c(is)g(a)h(v)o(ector)g(of)g(strings)e(in)i +(one-to-one)f(correspondence)h(with)f(v)n(ariable)h(IDs)f(of)h(the)g +(reading)55 3344 y(manager)-5 b(.)40 b(V)-11 b(ariables)28 +b(in)g(the)g(DD)g(\002le)g(read)h(are)g(matched)f(with)f(manager)h(v)n +(ariables)f(according)h(to)g(their)55 3465 y(name)35 +b(\(a)h(not)f(NULL)g(v)n(arnames)g(parameter)h(w)o(as)f(required)h +(while)f(storing)f(the)h(DD)g(\002le\).)64 b(The)35 b(most)55 +3585 y(common)c(usage)h(of)g(this)f(feature)i(is)e(in)h(combination)e +(with)i(a)g(v)n(ariable)g(ordering)g(stored)f(on)h(a)g(\002le)h(and)55 +3706 y(based)28 b(on)h(v)n(ariables)f(names.)41 b(Names)29 +b(must)e(be)i(loaded)f(in)g(an)h(array)g(of)g(strings)e(and)i(passed)f +(to)g(the)h(DD)55 3826 y(load)24 b(procedure.)-44 4029 +y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 4029 V +35 w(V)-13 b(AR)p 1272 4029 V 35 w(MA)i(TCHIDS)25 b(has)g(a)g(meaning)f +(similar)g(to)55 4150 y(DDDMP)p 421 4150 V 36 w(V)-13 +b(AR)p 654 4150 V 35 w(MA)i(TCHN)m(AMES)26 b(b)n(ut)h(inte)o(ger)f +(auxiliary)g(IDs)h(are)h(used)f(instead)f(of)h(strings.)36 +b(The)28 b(ad-)55 4270 y(ditional)23 b(not)h(NULL)h(v)n(armathauxids)e +(parameter)i(is)g(needed.)-44 4474 y Fk(\017)49 b Fl(v)n +(armatchnode=DDDMP)p 1040 4474 V 35 w(V)-13 b(AR)p 1272 +4474 V 35 w(COMPOSEIDS,)38 b(uses)f(the)f(additional)f(v)n +(arcomposeids)g(parameter)55 4594 y(as)25 b(an)g(array)g(of)g(v)n +(ariable)f(IDs)h(to)g(be)g(composed)f(with)g(IDs)g(stored)h(in)f +(\002le.)-189 4860 y Fi(2.2.3)99 b(DD)25 b(Load/Stor)n(e)h(and)f(V)-9 +b(ariable)25 b(Ordering)-189 5048 y Fl(Loading)31 b(of)i(Decision)e +(Diagrams)h(from)g(\002le)g(supports)f(dif)n(ferent)h(v)n(ariables)g +(ordering)f(strate)o(gies,)i(as)g(already)-189 5168 y(pointed)23 +b(out)h(in)g(the)h(pre)n(vious)e(section.)30 b(This)24 +b(allo)n(ws)f(or)h(e)o(xample)g(storing)f(dif)n(ferent)i(BDDs)f(each)h +(with)f(its)g(o)n(wn)-189 5288 y(v)n(ariable)29 b(ordering,)h(and)g(to) +f(mer)n(ge)h(them)f(within)f(the)i(same)f(DD)h(manager)f(by)h(means)f +(of)g(proper)h(load)f(opera-)-189 5409 y(tions.)44 b(W)-8 +b(e)30 b(suggest)f(using)f(DDDMP)p 1175 5409 V 36 w(V)-13 +b(AR)p 1408 5409 V 36 w(MA)i(TCHIDS)30 b(whene)n(v)o(er)f(IDs)g(k)o +(eeps)h(on)f(representing)h(the)f(same)-189 5529 y(entities)24 +b(while)h(changing)f(v)n(ariable)h(ordering.)31 b(If)25 +b(this)f(is)h(not)f(true,)h(v)n(ariable)g(names)g(\(if)g(a)n(v)n +(ailable\))f(or)i(auxiliary)1794 5800 y(6)p eop +%%Page: 7 7 +7 6 bop -189 218 a Fl(IDs)34 b(are)h(a)g(good)e(w)o(ay)i(to)f +(represent)g(in)l(v)n(ariant)f(attrib)n(uted)g(of)i(v)n(ariables)e +(across)h(se)n(v)o(eral)g(runs)g(with)f(dif)n(ferent)-189 +338 y(orderings.)50 b(DDDMP)p 629 338 30 4 v 35 w(V)-13 +b(AR)p 861 338 V 36 w(COMPOSEIDS)32 b(is)f(an)h(alternati)n(v)o(e)e +(solution,)h(that)g(practically)f(corresponds)h(to)-189 +459 y(cascading)23 b(DDDMP)p 593 459 V 36 w(V)-13 b(AR)p +826 459 V 36 w(MA)i(TCHIDS)23 b(and)h(v)n(ariable)f(composition)e(with) +h(a)i(gi)n(v)o(en)e(array)i(of)g(ne)n(w)f(v)n(ariables.)-189 +797 y Fo(3)143 b(CNF)35 b(Support)-189 1050 y Fj(3.1)119 +b(F)m(ormat)-189 1237 y Fl(Gi)n(v)o(en)30 b(a)h(BDD)g(representing)g(a) +g(function)f Fd(f)11 b Fl(,)32 b(we)f(de)n(v)o(elop)f(three)h(basic)g +(possible)e(w)o(ays)i(to)g(store)f(it)h(as)g(a)g(CNF)-189 +1358 y(formula.)54 b(In)33 b(each)h(method)d(the)i(set)g(of)f(clauses)h +(is)f(written)h(after)g(an)g(header)g(part.)55 b(Only)32 +b(the)h(te)o(xt)f(format)g(is)-189 1478 y(allo)n(wed.)-189 +1743 y Fi(3.1.1)99 b(Header)-189 1931 y Fl(The)23 b(header)h(part)f(of) +g(each)h(CNF)g(\002le)f(has)g(basically)g(the)f(same)h(format)g +(analyzed)g(for)h(the)f(BDD/ADD)g(\002les.)30 b(F)o(or)-189 +2051 y(e)o(xample)h(the)g Fg(.rootids)f Fl(line)h(indicates)f(the)i(be) +o(ginning)d(of)j(each)g(CNF)g(formula)f(represented)h(by)f(a)h(single) +-189 2172 y(BDD.)j(T)-8 b(o)34 b(be)g(compatible)f(with)h(the)g(DIMA)l +(CS)h(format)f(each)h(header)f(line)g(start)g(with)g(the)g(character)h +(\223c\224)g(to)-189 2292 y(indicate)24 b(a)h(comment.)-189 +2557 y Fi(3.1.2)99 b(T)-9 b(ext)25 b(F)n(ormat)-189 2745 +y Fl(The)j(\002rst)g(method,)g(which)f(we)h(call)g Fi(Single-Node-Cut)p +Fl(,)j(models)26 b(each)j(BDD)f(nodes,)h(b)n(ut)e(the)h(ones)f(with)h +(both)-189 2865 y(the)c(children)g(equal)h(to)f(the)g(constant)g(node)g +Fb(1)p Fl(,)g(as)h(a)g(multiple)o(x)o(er)-5 b(.)27 b(Each)e(multiple)o +(x)o(er)d(has)i(tw)o(o)g(data)h(inputs)e(\(i.e.,)-189 +2985 y(the)k(node)h(children\),)f(a)h(selection)f(input)f(\(i.e.,)i +(the)g(node)f(v)n(ariable\))g(and)h(one)f(output)f(\(i.e.,)i(the)g +(function)e(v)n(alue\))-189 3106 y(whose)h(v)n(alue)f(is)h(assigned)f +(to)h(an)g(additional)f(CNF)i(v)n(ariable.)37 b(The)27 +b(\002nal)h(number)e(of)h(v)n(ariables)g(is)f(equal)h(to)g(the)-189 +3226 y(number)d(of)h(original)f(BDD)h(v)n(ariables)f(plus)g(the)h +(number)f(of)h(\223internal\224)g(nodes)f(of)h(the)g(BDD.)47 +3346 y(The)k(second)f(method,)g(which)h(we)f(call)h Fi(Maxterm-Cut)p +Fl(,)h(create)g(clauses)e(starting)g(from)g Fd(f)39 b +Fl(corresponds)-189 3467 y(to)25 b(the)h(of)n(f-set)g(\(i.e.,)f(all)h +(the)g(paths-cubes)f(from)g(the)h(root)g(node)f(to)h(the)f(terminal)g +Fg(0)p Fl(\))h(of)g(the)g(function)e Fd(f)11 b Fl(.)34 +b(W)l(ithin)-189 3587 y(the)29 b(BDD)g(for)g Fd(f)11 +b Fl(,)30 b(such)f(clauses)f(are)i(found)e(by)h(follo)n(wing)e(all)i +(the)f(paths)h(from)f(the)h(root)g(node)f(of)h(the)g(BDD)g(to)-189 +3708 y(the)c(constant)f(node)g Fb(0)p Fl(.)31 b(The)25 +b(\002nal)g(number)f(of)h(v)n(ariables)f(is)g(equal)h(to)f(the)h +(number)f(of)h(original)f(BDD)h(v)n(ariables.)47 3828 +y(The)k(third)g(method,)g(which)g(we)g(call)g Fi(A)-5 +b(uxiliary-V)c(ariable-Cut)p Fl(,)30 b(is)f(a)h(trade-of)n(f)f(between) +g(the)g(\002rst)g(tw)o(o)-189 3948 y(strate)o(gies.)69 +b(Internal)37 b(v)n(ariables,)j(i.e.,)h(cutting)c(points,)j(are)e +(added)g(in)f(order)h(to)g(decompose)f(the)h(BDD)g(into)-189 +4069 y(multiple)27 b(sub-trees)i(each)h(of)f(which)f(is)h(stored)g +(follo)n(wing)e(the)h(second)h(strate)o(gy)-6 b(.)42 +b(The)29 b(trade-of)n(f)g(is)g(guided)f(by)-189 4189 +y(the)23 b(cutting)f(point)g(selection)g(strate)o(gy)-6 +b(,)22 b(and)h(we)g(e)o(xperiment)f(with)g(tw)o(o)g(methodologies.)28 +b(In)23 b(the)g(\002rst)g(method,)g(a)-189 4310 y(ne)n(w)f(CNF)h(v)n +(ariable)f(is)f(inserted)h(in)g(correspondence)g(to)g(the)g(shared)g +(nodes)g(of)g(the)h(BDD,)f(i.e.,)h(the)f(nodes)f(which)-189 +4430 y(ha)n(v)o(e)29 b(more)g(than)h(one)f(incoming)f(edge.)45 +b(This)29 b(technique,)h(albeit)e(optimizing)g(the)h(number)g(of)h +(literals)e(stored,)-189 4550 y(can)35 b(produce)g(clauses)f(with)g(a)h +(high)f(number)h(of)f(literals)1894 4514 y Fh(2)1933 +4550 y Fl(.)60 b(T)-8 b(o)35 b(a)n(v)n(oid)f(this)g(dra)o(wback,)j(the) +e(second)f(method,)-189 4671 y(introduces)28 b(all)g(the)g(pre)n +(viously)e(indicated)i(cutting)f(points)g(more)h(the)h(ones)f +(necessary)g(to)g(break)h(the)f(length)g(of)-189 4791 +y(the)d(path)f(to)h(a)g(maximum)e(\(user\))i(selected)g(v)n(alue.)47 +4911 y(Actually)-6 b(,)37 b(all)f(the)f(methods)g(described)h(abo)o(v)o +(e)e(can)j(be)e(re-conducted)h(to)g(the)f(basic)h(idea)g(of)g(possibly) +-189 5032 y(breaking)24 b(the)h(BDD)g(through)f(the)g(use)h(of)f +(additional)g(cutting)f(v)n(ariables)h(and)h(dumping)e(the)h(paths)g +(between)h(the)-189 5152 y(root)34 b(of)h(the)f(BDD,)h(the)g(cutting)e +(v)n(ariables)h(and)g(the)h(terminal)e(nodes.)60 b(Such)35 +b(internal)f(cutting)f(v)n(ariables)h(are)-189 5273 y(added)25 +b(al)o(w)o(ays)f(\(for)i(each)f(node\),)g(ne)n(v)o(er)f(or)h(sometimes) +e(respecti)n(v)o(ely)-6 b(.)p -189 5360 1607 4 v -77 +5422 a Ff(2)-40 5452 y Fe(This)27 b(v)n(alue)f(is)i(superiorly)d +(limited)h(by)g(the)h(number)e(of)h(v)n(ariables)g(of)g(the)h(BDD,)g +(i.e.,)h(the)f(longest)f(path)g(from)g(the)h(root)f(to)g(the)-189 +5551 y(terminal)19 b(node.)1794 5800 y Fl(7)p eop +%%Page: 8 8 +8 7 bop 47 218 a Fl(While)33 b(the)f Fc(Single-Node-Cut)h +Fl(method)f(minimizes)f(the)i(length)f(of)h(the)f(clauses)h(produced,)i +(b)n(ut)d(it)g(also)-189 338 y(requires)d(the)h(higher)f(number)g(of)g +(CNF)i(v)n(ariables,)e(the)h Fc(Maxterm-Cut)f Fl(technique)g(minimizes) +f(the)h(number)g(of)-189 459 y(CNF)36 b(v)n(ariables)d(required.)61 +b(This)34 b(adv)n(antage)g(is)g(counter)n(-balanced)h(by)f(the)h(f)o +(act)g(that)f(in)g(the)h(w)o(orst)f(case)h(the)-189 579 +y(number)23 b(of)g(clauses,)g(as)h(well)e(as)i(the)f(total)f(number)h +(of)g(literals,)g(produced)g(is)g(e)o(xponential)e(in)i(the)g(BDD)h +(size)f(\(in)-189 699 y(terms)28 b(of)i(number)e(of)h(nodes\).)43 +b(The)29 b(application)f(of)h(this)f(method)g(is)g(then)h(limited)e(to) +i(the)g(cases)g(in)f(which)h(the)-189 820 y(\223of)n(f-set\224)c(of)f +(the)g(represented)h(function)f Fd(f)35 b Fl(has)24 b(a)h(small)f +(cardinality)-6 b(.)29 b(The)c Fc(A)n(uxiliary-V)-11 +b(ariable-Cut)22 b Fl(strate)o(gy)h(is)-189 940 y(a)k(trade-of)n(f)h +(between)f(the)g(\002rst)g(tw)o(o)g(methods)f(and)h(the)g(ones)f(which) +h(gi)n(v)o(es)f(more)h(compact)f(results.)37 b(As)27 +b(a)h(\002nal)-189 1061 y(remark)f(notice)e(that)h(the)g(method)g(is)f +(able)i(to)f(store)g(both)f(monolithic)f(BDDs)j(and)f(conjuncti)n(v)o +(e)e(forms.)35 b(In)26 b(each)-189 1181 y(case)f(we)g(generate)h(CNF)f +(\002les)g(using)f(the)h(standard)f(DIMA)l(CS)i(format.)-189 +1365 y Fi(Example)f(1)49 b Fc(F)l(igur)l(e)20 b(1)h(shows)f(an)h(e)n +(xample)g(of)f(how)h(our)f(pr)l(ocedur)l(e)h(works)f(to)h(stor)l(e)f(a) +h(small)f(monolithic)f(BDD.)-189 1486 y(F)l(igur)l(e)j(1\(a\))h(r)l +(epr)l(esents)g(a)g(BDD)g(with)g Fb(4)g Fc(nodes.)30 +b(BDD)23 b(variables)f(ar)l(e)h(named)g(after)f(inte)l(g)o(er)g(number) +o(s)h(r)o(anging)-189 1606 y(fr)l(om)k Fb(1)h Fc(to)g +Fb(4)p Fc(,)h(to)f(have)g(an)g(easy-to-follow)f(corr)l(espondence)h +(with)g(the)g(CNF)h(variables.)40 b(F)l(igur)l(e)27 b(1\(b\),)i(\(c\))g +(and)-189 1727 y(\(d\))c(show)g(the)f(corr)l(esponding)f(CNF)j(r)l(epr) +l(esentations)d(g)o(ener)o(ated)h(by)h(our)f(thr)l(ee)h(methods.)30 +b(As)24 b(in)h(the)f(standar)l(d)-189 1847 y(format)i +Fa(p)i Fc(indicates)e(the)h(total)f(number)g(of)h(variables)f(used)h +(\()p Fb(4)g Fc(is)g(the)g(minimum)f(value)h(as)g(the)g(BDD)g(itself)f +(has)-189 1967 y Fb(4)f Fc(variables\),)e(and)i Fa(cnf)g +Fc(the)f(total)g(number)g(of)h(clauses.)47 2088 y(As)i(a)g(\002nal)f(r) +l(emark)h(notice)f(that)g(for)g(this)g(speci\002c)h(e)n(xample)g(the)f +(\223Maxterm-Cut\224)i(appr)l(oac)o(h)d(is)h(the)h(one)-189 +2208 y(whic)o(h)36 b(gives)g(the)g(most)f(compact)h(CNF)h(r)l(epr)l +(esentation)e(b)n(ut)h(also)f(the)h(clause)g(with)g(the)g(lar)l(g)o +(est)g(number)f(of)-189 2328 y(liter)o(als)23 b(\()p +Fb(4)p Fc(\).)188 2471 y + 6339814 10777681 0 0 11709153 19997655 startTexFig + 188 2471 a +%%BeginDocument: bdd.eps +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: bdd.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3c +%%CreationDate: Mon Sep 9 14:21:26 2002 +%%For: quer@pcsq (Stefano Quer) +%%BoundingBox: 0 0 178 304 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 304 moveto 0 0 lineto 178 0 lineto 178 304 lineto closepath clip newpath +-51.0 319.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawEllipse { + /endangle exch def + /startangle exch def + /yrad exch def + /xrad exch def + /y exch def + /x exch def + /savematrix mtrx currentmatrix def + x y tr xrad yrad sc 0 0 1 startangle endangle arc + closepath + savematrix setmatrix + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06299 0.06299 sc +% +% Fig objects follow +% +% Polyline +15.000 slw +n 2010 4515 m 2550 4515 l 2550 5040 l 2010 5040 l + cp gs col0 s gr +/Times-Roman ff 300.00 scf sf +2205 4875 m +gs 1 -1 sc (1) col0 sh gr +% Ellipse +n 1515 1800 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2250 900 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2970 2715 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2280 3705 270 270 0 360 DrawEllipse gs col0 s gr + +7.500 slw +% Ellipse +n 3555 3555 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2712 1726 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2430 4230 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Polyline +15.000 slw +n 2805 2910 m + 2250 3450 l gs col0 s gr +% Polyline + [90] 0 sd +gs clippath +2940 2472 m 3010 2445 l 2931 2239 l 2957 2411 l 2861 2266 l cp +eoclip +n 2460 1110 m + 2970 2445 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 2861 2266 m 2957 2411 l 2931 2239 l 2908 2284 l 2861 2266 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +1478 1511 m 1528 1568 l 1693 1422 l 1542 1506 l 1643 1366 l cp +eoclip +n 2025 1080 m + 1515 1530 l gs col0 s gr gr + +% arrowhead +n 1643 1366 m 1542 1506 l 1693 1422 l 1643 1416 l 1643 1366 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +2212 645 m 2287 645 l 2287 425 l 2250 594 l 2212 425 l cp +eoclip +n 2250 270 m + 2250 630 l gs col0 s gr gr + +% arrowhead +n 2212 425 m 2250 594 l 2287 425 l 2250 459 l 2212 425 l + cp gs 0.00 setgray ef gr col0 s +% Polyline + [90] 0 sd +gs clippath +2692 2664 m 2732 2601 l 2546 2485 l 2670 2606 l 2506 2548 l cp +eoclip +n 1710 2010 m + 2700 2625 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 2506 2548 m 2670 2606 l 2546 2485 l 2555 2534 l 2506 2548 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj + [90] 0 sd +gs clippath +2504 4653 m 2539 4720 l 2733 4616 l 2567 4663 l 2698 4550 l cp +eoclip +n 3180 2910 m 3181 2911 l 3183 2913 l 3186 2916 l 3192 2921 l 3200 2929 l + 3210 2939 l 3223 2951 l 3238 2966 l 3255 2984 l 3274 3003 l + 3295 3025 l 3317 3049 l 3339 3075 l 3362 3103 l 3385 3131 l + 3407 3161 l 3429 3192 l 3450 3225 l 3470 3258 l 3488 3293 l + 3504 3329 l 3519 3367 l 3531 3406 l 3541 3447 l 3548 3490 l + 3552 3536 l 3552 3583 l 3548 3634 l 3540 3686 l 3528 3740 l + 3510 3795 l 3490 3844 l 3467 3892 l 3441 3939 l 3413 3985 l + 3382 4028 l 3350 4070 l 3317 4110 l 3283 4148 l 3248 4184 l + 3211 4219 l 3174 4253 l 3136 4285 l 3098 4316 l 3059 4347 l + 3020 4376 l 2980 4405 l 2941 4432 l 2901 4459 l 2862 4484 l + 2824 4509 l 2787 4532 l 2751 4554 l 2717 4575 l 2686 4593 l + 2657 4610 l 2631 4626 l 2608 4639 l 2589 4650 l 2572 4659 l + 2559 4666 l 2550 4672 l + 2535 4680 l gs col0 s gr gr + [] 0 sd +% arrowhead +0 slj +n 2698 4550 m 2567 4663 l 2733 4616 l 2686 4599 l 2698 4550 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +1985 4734 m 2028 4672 l 1847 4548 l 1965 4675 l 1804 4609 l cp +eoclip +n 1350 2025 m 1349 2026 l 1348 2027 l 1345 2030 l 1340 2035 l 1334 2042 l + 1325 2051 l 1314 2063 l 1301 2078 l 1286 2095 l 1268 2114 l + 1249 2137 l 1227 2161 l 1205 2188 l 1181 2218 l 1156 2249 l + 1131 2282 l 1105 2316 l 1080 2352 l 1054 2390 l 1029 2428 l + 1005 2468 l 981 2509 l 959 2552 l 938 2595 l 918 2640 l + 900 2687 l 884 2736 l 870 2786 l 858 2839 l 848 2894 l + 841 2951 l 837 3011 l 836 3074 l 838 3139 l 845 3206 l + 855 3275 l 870 3345 l 888 3412 l 910 3477 l 934 3542 l + 961 3604 l 990 3665 l 1022 3723 l 1054 3779 l 1088 3833 l + 1124 3885 l 1160 3935 l 1198 3983 l 1236 4029 l 1275 4074 l + 1315 4118 l 1356 4160 l 1397 4201 l 1438 4241 l 1480 4280 l + 1522 4318 l 1563 4355 l 1605 4390 l 1645 4424 l 1685 4457 l + 1723 4488 l 1760 4517 l 1795 4545 l 1827 4570 l 1857 4593 l + 1884 4613 l 1909 4632 l 1930 4647 l 1947 4660 l 1962 4671 l + 1973 4679 l 1982 4686 l + 1995 4695 l gs col0 s gr gr + +% arrowhead +0 slj +n 1804 4609 m 1965 4675 l 1847 4548 l 1854 4598 l 1804 4609 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj + [90] 0 sd +gs clippath +2300 4492 m 2363 4532 l 2481 4347 l 2359 4470 l 2417 4307 l cp +eoclip +n 2340 3960 m 2341 3962 l 2344 3966 l 2348 3973 l 2354 3982 l 2362 3995 l + 2370 4010 l 2379 4028 l 2389 4046 l 2397 4066 l 2406 4088 l + 2413 4111 l 2420 4137 l 2425 4165 l 2429 4197 l 2430 4230 l + 2429 4263 l 2425 4295 l 2420 4323 l 2413 4349 l 2406 4372 l + 2397 4394 l 2389 4414 l 2379 4433 l 2370 4450 l 2362 4465 l + 2354 4478 l + 2340 4500 l gs col0 s gr gr + [] 0 sd +% arrowhead +0 slj +n 2417 4307 m 2359 4470 l 2481 4347 l 2431 4356 l 2417 4307 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +2136 4532 m 2199 4492 l 2082 4307 l 2141 4470 l 2018 4347 l cp +eoclip +n 2160 3960 m 2159 3962 l 2156 3966 l 2152 3973 l 2146 3982 l 2138 3995 l + 2130 4010 l 2121 4028 l 2111 4046 l 2103 4066 l 2094 4088 l + 2087 4111 l 2080 4137 l 2075 4165 l 2071 4197 l 2070 4230 l + 2071 4263 l 2075 4295 l 2080 4323 l 2087 4349 l 2094 4372 l + 2103 4394 l 2111 4414 l 2121 4433 l 2130 4450 l 2138 4465 l + 2146 4478 l + 2160 4500 l gs col0 s gr gr + +% arrowhead +0 slj +n 2018 4347 m 2141 4470 l 2082 4307 l 2068 4356 l 2018 4347 l + cp gs 0.00 setgray ef gr col0 s +/Times-Roman ff 300.00 scf sf +2175 990 m +gs 1 -1 sc (1) col0 sh gr +/Times-Roman ff 300.00 scf sf +1440 1890 m +gs 1 -1 sc (2) col0 sh gr +/Times-Roman ff 300.00 scf sf +2895 2805 m +gs 1 -1 sc (3) col0 sh gr +/Times-Roman ff 300.00 scf sf +2205 3795 m +gs 1 -1 sc (4) col0 sh gr +$F2psEnd +rs + +%%EndDocument + + endTexFig + 531 3990 a Fc(\(a\))1512 2504 y Fg(p)60 b(cnf)f(7)g(11)1512 +2624 y(-5)g(3)h(0)1512 2745 y(-5)f(4)h(0)1512 2865 y(5)g(-3)f(-4)g(0) +1512 2985 y(6)h(-2)f(0)1512 3106 y(6)h(-5)f(0)1512 3226 +y(-6)g(2)h(5)f(0)1512 3347 y(7)h(1)f(5)h(0)1512 3467 +y(-7)f(1)h(-5)f(0)1512 3587 y(7)h(-1)f(-6)g(0)1512 3708 +y(-7)g(-1)h(6)f(0)1512 3828 y(7)h(0)1836 3990 y Fc(\(b\))2541 +2525 y Fg(p)f(cnf)g(4)h(3)2541 2645 y(1)f(-3)h(-4)f(0)2541 +2766 y(-1)g(2)h(3)f(0)2541 2886 y(-1)g(2)h(-3)f(4)h(0)2868 +3048 y Fc(\(c\))2541 3251 y Fg(p)f(cnf)g(5)h(5)2541 3371 +y(-5)f(1)h(0)2541 3492 y(5)f(-1)h(2)f(0)2541 3612 y(-3)g(-4)g(5)h(0) +2541 3733 y(3)f(-5)h(0)2541 3853 y(-3)f(4)h(-5)f(0)2865 +3990 y Fc(\(d\))-189 4138 y Fl(Figure)46 b(1:)71 b(\(a\))47 +b(BDD;)e(\(b\))h(\223Single-Node-Cut\224)g(format;)55 +b(\(c\))46 b(\223Maxterm-Cut\224)g(format;)55 b(\(d\))45 +b(\223)-8 b(Auxiliary-)-189 4258 y(V)d(ariable-Cut\224)25 +b(F)o(ormat.)-189 4625 y Fj(3.2)119 b(Implementation)-189 +4813 y Fl(Store)25 b(and)g(Load)g(for)g(a)g(single)f(BDD)h(or)g(a)g +(forest)g(of)g(BDDs)g(is)f(currently)h(implemented.)-189 +5073 y Fi(3.2.1)99 b(Storing)25 b(Decision)g(Diagrams)f(as)g(CNF)h(F)n +(ormulas)-189 5260 y Fl(As)g(f)o(ar)g(as)g(the)g(storing)e(process)i +(is)f(concerned)i(three)f(possible)e(formats)h(are)i(a)n(v)n(ailable:) +-44 5431 y Fk(\017)49 b Fl(DDDMP)p 421 5431 30 4 v 36 +w(CNF)p 650 5431 V 36 w(MODE)p 980 5431 V 35 w(NODE:)21 +b(store)f(a)h(BDD)h(by)e(introducing)f(an)i(auxiliary)g(v)n(ariable)f +(for)h(each)g(BDD)55 5551 y(node)1794 5800 y(8)p eop +%%Page: 9 9 +9 8 bop -44 218 a Fk(\017)49 b Fl(DDDMP)p 421 218 30 +4 v 36 w(CNF)p 650 218 V 36 w(MODE)p 980 218 V 35 w(MAXTERM:)20 +b(store)g(a)h(BDD)h(by)e(follo)n(wing)f(the)h(maxterm)g(of)h(the)g +(represented)55 338 y(function)-44 542 y Fk(\017)49 b +Fl(DDDMP)p 421 542 V 36 w(CNF)p 650 542 V 36 w(MODE)p +980 542 V 35 w(BEST)-5 b(:)32 b(trade-of)f(between)h(the)f(tw)o(o)f +(pre)n(vious)g(solution,)h(trying)f(to)h(optimize)55 +662 y(the)25 b(number)f(of)h(literals)f(stored.)-189 +865 y(See)c(procedures)f(Dddmp)p 736 865 V 35 w(cuddBddStoreCnf)g(\(to) +g(store)f(a)h(single)f(BDD)i(as)e(a)i(CNF)f(formula\))g(and)g(Dddmp)p +3609 865 V 34 w(cuddBddArrayStoreCnf)-189 986 y(\(to)25 +b(store)f(an)h(array)h(of)f(BDDs)g(as)f(a)i(CNF)f(formula\).)-189 +1252 y Fi(3.2.2)99 b(Loadinf)26 b(CNF)e(F)n(ormulas)g(as)h(BDDs)-189 +1439 y Fl(As)g(f)o(ar)g(as)g(the)g(loading)e(process)i(is)f(concerned)i +(three)f(possible)e(formats)i(are)g(a)n(v)n(ailable:)-44 +1643 y Fk(\017)49 b Fl(DDDMP)p 421 1643 V 36 w(CNF)p +650 1643 V 36 w(MODE)p 980 1643 V 35 w(NO)p 1159 1643 +V 36 w(CONJ:)25 b(Return)g(the)f(Clauses)h(without)f(Conjunction)-44 +1846 y Fk(\017)49 b Fl(DDDMP)p 421 1846 V 36 w(CNF)p +650 1846 V 36 w(MODE)p 980 1846 V 35 w(NO)p 1159 1846 +V 36 w(Q)o(U)l(ANT)-5 b(:)24 b(Return)h(the)g(sets)f(of)h(BDDs)g +(without)f(Quanti\002cation)-44 2050 y Fk(\017)49 b Fl(DDDMP)p +421 2050 V 36 w(CNF)p 650 2050 V 36 w(MODE)p 980 2050 +V 35 w(CONJ)p 1264 2050 V 36 w(Q)o(U)l(ANT)-5 b(:)23 +b(Return)h(the)g(sets)f(of)h(BDDs)g(AFTER)g(Existential)e(Quanti\002-) +55 2170 y(cation)-189 2373 y(See)e(procedures)f(Dddmp)p +736 2373 V 35 w(cuddBddLoadCnf)f(\(to)h(load)f(a)i(CNF)f(formula)g(as)g +(a)g(single)f(BDD\))h(and)g(Dddmp)p 3581 2373 V 35 w +(cuddBddArrayLoadCnf)-189 2494 y(\(to)35 b(load)h(a)g(CNF)g(formula)f +(as)h(an)g(array)g(of)g(BDDs\).)63 b(See)36 b(also)g(Dddmp)p +2485 2494 V 34 w(cuddHeaderLoadCnf)h(to)e(load)g(the)-189 +2614 y(header)25 b(of)g(a)g(CNF)h(\002le)f(to)g(gather)f(information)f +(on)i(the)g(sa)n(v)o(ed)f(structure.)-189 2954 y Fo(4)143 +b(T)-13 b(est)35 b(Pr)m(ogram)f(and)h(Regr)m(ession)f(T)-13 +b(ests)-189 3177 y Fl(The)20 b Fc(testddmp.c)e Fl(\002le,)j(pro)o +(vided)d(with)h(this)f(distrib)n(ution,)g(e)o(x)o(empli\002es)g(some)h +(of)h(the)f(abo)o(v)o(e)g(features.)29 b(Moreo)o(v)o(er)l(,)-189 +3298 y(in)d(the)h Fc(e)n(xp)g Fl(e)o(xperiments)e(a)j(fe)n(w)e +(scripts,)h(named)f Fc(test\241n\277.script)f Fl(are)i(a)n(v)n(ailable) +f(for)h(a)g(sanity)f(check)h(of)g(the)g(tool)-189 3418 +y(and)e(to)f(tak)o(e)h(a)g(look)f(at)h(some)f(runs)h(e)o(x)o +(empli\002cation.)-189 3758 y Fo(5)143 b(Documentation)-189 +3981 y Fl(F)o(or)27 b(further)f(documentation)f(on)i(the)f(package)h +(see)g(the)g(on-line)f(documentation)f(automatically)g(created)i(from) +-189 4102 y(the)e(source)g(code)g(\002les.)-189 4441 +y Fo(6)143 b(Ackno)o(wledgments)-189 4665 y Fl(W)-8 b(e)19 +b(are)h(particular)f(indebted)f(with)g(F)o(abio)g(Somenzi,)i(for)f +(discussions,)f(advice,)i(and)f(for)g(including)e(the)i(DDDMP)-189 +4785 y(package)28 b(into)f(the)h(CUDD)g(distrib)n(ution.)37 +b(W)-8 b(e)29 b(also)e(thank)g(all)h(the)g(user)g(of)g(the)f(package)i +(for)f(their)f(useful)h(indi-)-189 4905 y(cation)c(and)h(comments)f(on) +g(the)h(it.)1794 5800 y(9)p eop +%%Page: 10 10 +10 9 bop -189 218 a Fo(7)143 b(FTP)35 b(Site)-189 441 +y Fl(The)25 b(package)g(is)f(singularly)g(a)n(v)n(ailable)g(from:)-189 +645 y Fg(site:)59 b(ftp.polito.it)-189 765 y(user:)g(anonymous)-189 +885 y(directory:)f(/pub/research/dddmp)-189 1089 y Fl(or)25 +b(directly)f(from)h(the)f(author)h(WEB)g(pages:)-189 +1292 y Fg(WWW:)59 b(http://www.polito.it/\230{cabodi)o(,quer)o(})-189 +1632 y Fo(8)143 b(F)l(eedback)-189 1855 y Fl(Send)25 +b(feedback)h(to:)-189 2059 y Fg(Gianpiero)58 b(Cabodi)g(&)i(Stefano)e +(Quer)-189 2179 y(Politecnico)f(di)j(Torino)-189 2300 +y(Dipartimento)d(di)i(Automatica)f(e)i(Informatica)-189 +2420 y(Corso)f(Duca)g(degli)f(Abruzzi,)g(24)-189 2540 +y(I-10129)g(Torino)-189 2661 y(Italy)-189 2781 y(E-mail:)g +({cabodi,quer}@polito.it)-189 2901 y(WWW:)h +(http://www.polito.it/\230{cabodi)o(,quer)o(})1769 5800 +y Fl(10)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllAbs.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllAbs.html new file mode 100644 index 000000000..5cd6c2a3e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllAbs.html @@ -0,0 +1,483 @@ + +dddmp package abstract + + + + + +
          +
          DddmpBddReadHeaderCnf() +
          Reads a the header of a dump file representing the argument + BDDs. + +
          DddmpBddReadHeader() +
          Reads a the header of a dump file representing the + argument BDDs. + +
          DddmpClearVisitedAdd() +
          Marks a node as not visited + +
          DddmpClearVisitedBdd() +
          Marks a node as not visited + +
          DddmpClearVisitedCnfRecur() +
          Mark ALL nodes as not visited + +
          DddmpClearVisitedCnfRecur() +
          Mark ALL nodes as not visited + +
          DddmpClearVisitedCnf() +
          Marks a node as not visited + +
          DddmpClearVisitedCnf() +
          Marks a node as not visited + +
          DddmpClearVisited() +
          Marks a node as not visited + +
          DddmpCnfClauses2Bdd() +
          Transforms CNF clauses into BDDs. + +
          DddmpCuddBddArrayStoreCnf() +
          Writes a dump file representing the argument Array of + BDDs in the CNF standard format. + +
          DddmpCuddBddArrayStore() +
          Writes a dump file representing the argument Array of + BDDs. + +
          DddmpCuddDdArrayLoadCnf() +
          Reads a dump file representing the argument BDDs in CNF + format. + +
          DddmpCuddDdArrayLoad() +
          Reads a dump file representing the argument BDDs. + +
          DddmpCuddDdArrayStoreBdd() +
          Writes a dump file representing the argument Array of + BDDs/ADDs. + +
          DddmpCuddDdArrayStoreBlifBody() +
          Writes a blif body representing the argument BDDs. + +
          DddmpCuddDdArrayStoreBlifStep() +
          Performs the recursive step of DddmpCuddDdArrayStoreBlif. + +
          DddmpCuddDdArrayStoreBlif() +
          Writes a blif file representing the argument BDDs. + +
          DddmpCuddDdArrayStorePrefixBody() +
          Internal function to writes a dump file representing the + argument BDD in a prefix notation. Writes the body of the file. + +
          DddmpCuddDdArrayStorePrefixStep() +
          Performs the recursive step of + DddmpCuddDdArrayStorePrefixBody. + +
          DddmpCuddDdArrayStorePrefix() +
          Internal function to writes a dump file representing the + argument BDD in a prefix notation. + +
          DddmpCuddDdArrayStoreSmvBody() +
          Internal function to writes a dump file representing the + argument BDD in a SMV notation. Writes the body of the file. + +
          DddmpCuddDdArrayStoreSmvStep() +
          Performs the recursive step of + DddmpCuddDdArrayStoreSmvBody. + +
          DddmpCuddDdArrayStoreSmv() +
          Internal function to writes a dump file representing the + argument BDD in a SMV notation. + +
          DddmpDdNodesCheckIncomingAndScanPath() +
          Number nodes recursively in post-order + +
          DddmpDdNodesCheckIncomingAndScanPath() +
          Number nodes recursively in post-order + +
          DddmpDdNodesCountEdgesAndNumber() +
          Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. + +
          DddmpDdNodesCountEdgesAndNumber() +
          Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. + +
          DddmpDdNodesCountEdgesRecur() +
          Counts the number of incoming edges for each node of a BDD + +
          DddmpDdNodesCountEdgesRecur() +
          Counts the number of incoming edges for each node of a BDD + +
          DddmpDdNodesNumberEdgesRecur() +
          Number nodes recursively in post-order + +
          DddmpDdNodesNumberEdgesRecur() +
          Number nodes recursively in post-order + +
          DddmpDdNodesResetCountRecur() +
          Resets counter and visited flag for ALL nodes of a BDD + +
          DddmpDdNodesResetCountRecur() +
          Resets counter and visited flag for ALL nodes of a BDD + +
          DddmpFreeHeaderCnf() +
          Frees the internal header structure. + +
          DddmpFreeHeader() +
          Frees the internal header structure. + +
          DddmpIntArrayDup() +
          Duplicates an array of ints + +
          DddmpIntArrayRead() +
          Inputs an array of ints + +
          DddmpIntArrayWrite() +
          Outputs an array of ints + +
          DddmpNumberAddNodes() +
          Removes nodes from unique table and number them + +
          DddmpNumberBddNodes() +
          Removes nodes from unique table and number them + +
          DddmpNumberDdNodesCnf() +
          Removes nodes from unique table and numbers them + +
          DddmpNumberDdNodesCnf() +
          Removes nodes from unique table and numbers them + +
          DddmpNumberDdNodes() +
          Removes nodes from unique table and number them + +
          DddmpPrintBddAndNextRecur() +
          Prints debug info + +
          DddmpPrintBddAndNextRecur() +
          Prints debug info + +
          DddmpPrintBddAndNext() +
          Prints debug information + +
          DddmpPrintBddAndNext() +
          Prints debug information + +
          DddmpReadCnfClauses() +
          Read the CNF clauses from the file in the standard DIMACS + format. + +
          DddmpReadCode() +
          Reads a 1 byte node code + +
          DddmpReadInt() +
          Reads a "packed integer" + +
          DddmpReadNodeIndexAdd() +
          Reads the index of a node + +
          DddmpReadNodeIndexBdd() +
          Reads the index of a node + +
          DddmpReadNodeIndexCnf() +
          Reads the index of a node + +
          DddmpReadNodeIndexCnf() +
          Reads the index of a node + +
          DddmpReadNodeIndex() +
          Reads the index of a node + +
          DddmpSetVisitedAdd() +
          Marks a node as visited + +
          DddmpSetVisitedBdd() +
          Marks a node as visited + +
          DddmpSetVisitedCnf() +
          Marks a node as visited + +
          DddmpSetVisitedCnf() +
          Marks a node as visited + +
          DddmpSetVisited() +
          Marks a node as visited + +
          DddmpStrArrayDup() +
          Duplicates an array of strings + +
          DddmpStrArrayFree() +
          Frees an array of strings + +
          DddmpStrArrayRead() +
          Inputs an array of strings + +
          DddmpStrArrayWrite() +
          Outputs an array of strings + +
          DddmpStrDup() +
          Duplicates a string + +
          DddmpUnnumberAddNodes() +
          Restores nodes in unique table, loosing numbering + +
          DddmpUnnumberBddNodes() +
          Restores nodes in unique table, loosing numbering + +
          DddmpUnnumberDdNodesCnf() +
          Restores nodes in unique table, loosing numbering + +
          DddmpUnnumberDdNodesCnf() +
          Restores nodes in unique table, loosing numbering + +
          DddmpUnnumberDdNodes() +
          Restores nodes in unique table, loosing numbering + +
          DddmpVisitedAdd() +
          Returns true if node is visited + +
          DddmpVisitedBdd() +
          Returns true if node is visited + +
          DddmpVisitedCnf() +
          Returns true if node is visited + +
          DddmpVisitedCnf() +
          Returns true if node is visited + +
          DddmpVisited() +
          Returns true if node is visited + +
          DddmpWriteCode() +
          Writes 1 byte node code + +
          DddmpWriteInt() +
          Writes a "packed integer" + +
          DddmpWriteNodeIndexAdd() +
          Write index to node + +
          DddmpWriteNodeIndexBdd() +
          Write index to node + +
          DddmpWriteNodeIndexCnfBis() +
          Write index to node + +
          DddmpWriteNodeIndexCnfWithTerminalCheck() +
          Write index to node + +
          DddmpWriteNodeIndexCnf() +
          Write index to node + +
          DddmpWriteNodeIndexCnf() +
          Write index to node + +
          DddmpWriteNodeIndex() +
          Write index to node + +
          Dddmp_Bin2Text() +
          Converts from binary to ASCII format + +
          Dddmp_Text2Bin() +
          Converts from ASCII to binary format + +
          Dddmp_cuddAddArrayLoad() +
          Reads a dump file representing the argument ADDs. + +
          Dddmp_cuddAddArrayStore() +
          Writes a dump file representing the argument Array of ADDs. + +
          Dddmp_cuddAddLoad() +
          Reads a dump file representing the argument ADD. + +
          Dddmp_cuddAddStore() +
          Writes a dump file representing the argument ADD. + +
          Dddmp_cuddBddArrayLoadCnf() +
          Reads a dump file in a CNF format. + +
          Dddmp_cuddBddArrayLoad() +
          Reads a dump file representing the argument BDDs. + +
          Dddmp_cuddBddArrayStoreBlif() +
          Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
          Dddmp_cuddBddArrayStoreCnf() +
          Writes a dump file representing the argument array of BDDs + in CNF format. + +
          Dddmp_cuddBddArrayStorePrefix() +
          Writes a dump file representing the argument BDD in + a prefix notation. + +
          Dddmp_cuddBddArrayStoreSmv() +
          Writes a dump file representing the argument BDD in + a prefix notation. + +
          Dddmp_cuddBddArrayStore() +
          Writes a dump file representing the argument Array of BDDs. + +
          Dddmp_cuddBddDisplayBinary() +
          Display a binary dump file in a text file + +
          Dddmp_cuddBddLoadCnf() +
          Reads a dump file in a CNF format. + +
          Dddmp_cuddBddLoad() +
          Reads a dump file representing the argument BDD. + +
          Dddmp_cuddBddStoreBlif() +
          Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
          Dddmp_cuddBddStoreCnf() +
          Writes a dump file representing the argument BDD in + a CNF format. + +
          Dddmp_cuddBddStorePrefix() +
          Writes a dump file representing the argument BDD in + a prefix notation. + +
          Dddmp_cuddBddStoreSmv() +
          Writes a dump file representing the argument BDD in + a prefix notation. + +
          Dddmp_cuddBddStore() +
          Writes a dump file representing the argument BDD. + +
          Dddmp_cuddHeaderLoadCnf() +
          Reads the header of a dump file representing the argument BDDs + +
          Dddmp_cuddHeaderLoad() +
          Reads the header of a dump file representing the argument BDDs + +
          FindVarname() +
          Performs binary search of a name within a sorted array + +
          NodeBinaryStoreBdd() +
          Store One Single Node in Binary Format. + +
          NodeStoreRecurAdd() +
          Performs the recursive step of Dddmp_bddStore. + +
          NodeStoreRecurBdd() +
          Performs the recursive step of Dddmp_bddStore. + +
          NodeTextStoreAdd() +
          Store One Single Node in Text Format. + +
          NodeTextStoreBdd() +
          Store One Single Node in Text Format. + +
          NumberNodeRecurAdd() +
          Number nodes recursively in post-order + +
          NumberNodeRecurBdd() +
          Number nodes recursively in post-order + +
          NumberNodeRecurCnf() +
          Number nodes recursively in post-order + +
          NumberNodeRecurCnf() +
          Number nodes recursively in post-order + +
          NumberNodeRecur() +
          Number nodes recursively in post-order + +
          QsortStrcmp() +
          String compare for qsort + +
          ReadByteBinary() +
          Reads a byte from file with escaped , and + +
          RemoveFromUniqueRecurAdd() +
          Removes a node from unique table + +
          RemoveFromUniqueRecurBdd() +
          Removes a node from unique table + +
          RemoveFromUniqueRecurCnf() +
          Removes a node from unique table + +
          RemoveFromUniqueRecurCnf() +
          Removes a node from unique table + +
          RemoveFromUniqueRecur() +
          Removes a node from unique table + +
          RestoreInUniqueRecurAdd() +
          Restores a node in unique table + +
          RestoreInUniqueRecurBdd() +
          Restores a node in unique table + +
          RestoreInUniqueRecurCnf() +
          Restores a node in unique table + +
          RestoreInUniqueRecurCnf() +
          Restores a node in unique table + +
          RestoreInUniqueRecur() +
          Restores a node in unique table + +
          StoreCnfBestNotSharedRecur() +
          Performs the recursive step of Print Best on Not Shared + sub-BDDs. + +
          StoreCnfBestSharedRecur() +
          Performs the recursive step of Print Best on Shared + sub-BDDs. + +
          StoreCnfBest() +
          Prints a disjoint sum of products with intermediate + cutting points. + +
          StoreCnfMaxtermByMaxtermRecur() +
          Performs the recursive step of Print Maxterm. + +
          StoreCnfMaxtermByMaxterm() +
          Prints a disjoint sum of products. + +
          StoreCnfNodeByNodeRecur() +
          Performs the recursive step of Dddmp_bddStore. + +
          StoreCnfNodeByNode() +
          Store the BDD as CNF clauses. + +
          StoreCnfOneNode() +
          Store One Single BDD Node. + +
          WriteByteBinary() +
          Writes a byte to file filtering , and + +
          printCubeCnf() +
          Print One Cube in CNF Format. + +
          () +
          Checks for Warnings: If expr==1 it prints out the warning + on stderr. + +
          () +
          Checks for fatal bugs + +
          () +
          Checks for fatal bugs and go to the label to deal with + the error. + +
          () +
          Checks for fatal bugs and return the DDDMP_FAILURE flag. + +
          () +
          Memory Allocation Macro for DDDMP + +
          () +
          Memory Free Macro for DDDMP + +
          + +
          + +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFile.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFile.html new file mode 100644 index 000000000..f414ee60d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFile.html @@ -0,0 +1,13 @@ + +The dddmp package for maintainers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFunc.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFunc.html new file mode 100644 index 000000000..76671dac0 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFunc.html @@ -0,0 +1,13 @@ + +The dddmp package for maintainers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllDet.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllDet.html new file mode 100644 index 000000000..9d8e7ba33 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllDet.html @@ -0,0 +1,3704 @@ + +The dddmp package: all functions + + +A set of internal low-level routines of the dddmp package + doing: +
            +
          • read and write of node codes in binary mode, +
          • read and write of integers in binary mode, +
          • marking/unmarking nodes as visited, +
          • numbering nodes. +
          +
          +
          +
          +
          +static Dddmp_Hdr_t * 
          +DddmpBddReadHeaderCnf(
          +  char * file, IN: file name
          +  FILE * fp IN: file pointer
          +)
          +
          +
          Reads the header of a dump file. Builds a Dddmp_Hdr_t struct + containing all infos in the header, for next manipulations. +

          + +

          Side Effects none +

          + +

          Defined in dddmpLoadCnf.c + +
          +
          +static Dddmp_Hdr_t * 
          +DddmpBddReadHeader(
          +  char * file, IN: file name
          +  FILE * fp IN: file pointer
          +)
          +
          +
          Reads the header of a dump file. Builds a Dddmp_Hdr_t struct + containing all infos in the header, for next manipulations. +

          + +

          Side Effects none +

          + +

          Defined in dddmpLoad.c + +
          +
          +void 
          +DddmpClearVisitedAdd(
          +  DdNode * f IN: BDD node to be marked (as not visited)
          +)
          +
          +
          Marks a node as not visited +

          + +

          Side Effects None +

          + +

          See Also DddmpVisitedAdd +() +DddmpSetVisitedAdd +() + + +
          Defined in dddmpNodeAdd.c + +
          +
          +void 
          +DddmpClearVisitedBdd(
          +  DdNode * f IN: BDD node to be marked (as not visited)
          +)
          +
          +
          Marks a node as not visited +

          + +

          Side Effects None +

          + +

          See Also DddmpVisited +() +DddmpSetVisited +() + + +
          Defined in dddmpNodeBdd.c + +
          +
          +static int 
          +DddmpClearVisitedCnfRecur(
          +  DdNode * f IN: root of the BDD to be marked
          +)
          +
          +
          Mark ALL nodes as not visited (it recurs on the node children) +

          + +

          Side Effects None +

          + +

          See Also DddmpVisitedCnf +() +DddmpSetVisitedCnf +() + + +
          Defined in dddmpDdNodeCnf.c + +
          +
          +static int 
          +DddmpClearVisitedCnfRecur(
          +  DdNode * f IN: root of the BDD to be marked
          +)
          +
          +
          Mark ALL nodes as not visited (it recurs on the node children) +

          + +

          Side Effects None +

          + +

          See Also DddmpVisitedCnf +() +DddmpSetVisitedCnf +() + + +
          Defined in dddmpNodeCnf.c + +
          +
          +static void 
          +DddmpClearVisitedCnf(
          +  DdNode * f IN: BDD node to be marked (as not visited)
          +)
          +
          +
          Marks a node as not visited +

          + +

          Side Effects None +

          + +

          See Also DddmpVisitedCnf +() +DddmpSetVisitedCnf +() + + +
          Defined in dddmpDdNodeCnf.c + +
          +
          +static void 
          +DddmpClearVisitedCnf(
          +  DdNode * f IN: BDD node to be marked (as not visited)
          +)
          +
          +
          Marks a node as not visited +

          + +

          Side Effects None +

          + +

          See Also DddmpVisitedCnf +() +DddmpSetVisitedCnf +() + + +
          Defined in dddmpNodeCnf.c + +
          +
          +void 
          +DddmpClearVisited(
          +  DdNode * f IN: BDD node to be marked (as not visited)
          +)
          +
          +
          Marks a node as not visited +

          + +

          Side Effects None +

          + +

          See Also DddmpVisited +() +DddmpSetVisited +() + + +
          Defined in dddmpDdNodeBdd.c + +
          +
          +static int 
          +DddmpCnfClauses2Bdd(
          +  Dddmp_Hdr_t * Hdr, IN: file header
          +  DdManager * ddMgr, IN: DD Manager
          +  int ** cnfTable, IN: CNF table for clauses
          +  int  mode, IN: computation mode
          +  DdNode *** rootsPtrPtr OUT: array of returned BDD roots (by reference)
          +)
          +
          +
          Transforms CNF clauses into BDDs. Clauses are stored in an + internal structure previously read. The results can be given in + different format according to the mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification +

          + +

          Defined in dddmpLoadCnf.c + +
          +
          +static int 
          +DddmpCuddBddArrayStoreCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDD roots to be stored
          +  int  rootN, IN: # of output BDD roots to be stored
          +  Dddmp_DecompCnfStoreType  mode, IN: format selection
          +  int  noHeader, IN: do not store header iff 1
          +  char ** varNames, IN: array of variable names (or NULL)
          +  int * bddIds, IN: array of BDD node Ids (or NULL)
          +  int * bddAuxIds, IN: array of BDD Aux Ids (or NULL)
          +  int * cnfIds, IN: array of CNF ids (or NULL)
          +  int  idInitial, IN: starting id for cutting variables
          +  int  edgeInTh, IN: Max # Incoming Edges
          +  int  pathLengthTh, IN: Max Path Length
          +  char * fname, IN: file name
          +  FILE * fp, IN: pointer to the store file
          +  int * clauseNPtr, OUT: number of clause stored
          +  int * varNewNPtr OUT: number of new variable created
          +)
          +
          +
          Dumps the argument array of BDDs/ADDs to file in CNF format. + The following arrays: varNames, bddIds, bddAuxIds, and cnfIds + fix the correspondence among variable names, BDD ids, BDD + auxiliary ids and the ids used to store the CNF problem. + All these arrays are automatically created iff NULL. + Auxiliary variable, iff necessary, are created starting from value + idInitial. + Iff idInitial is <= 0 its value is selected as the number of internal + CUDD variable + 2. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. +

          + +

          Side Effects Nodes are temporarily removed from the unique hash table. + They are re-linked after the store operation in a modified + order. +

          + +

          See Also Dddmp_cuddBddStore + + +
          Defined in dddmpStoreCnf.c + +
          +
          +int 
          +DddmpCuddBddArrayStore(
          +  Dddmp_DecompType  ddType, IN: Selects the decomp type BDD
          +  DdManager * ddMgr, IN: DD Manager
          +  char * ddname, IN: DD name (or NULL)
          +  int  nRoots, IN: number of output BDD roots to be stored
          +  DdNode ** f, IN: array of DD roots to be stored
          +  char ** rootnames, IN: array of root names (or NULL)
          +  char ** varnames, IN: array of variable names (or NULL)
          +  int * auxids, IN: array of converted var IDs
          +  int  mode, IN: storing mode selector
          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument array of BDDs to file. + Internal function doing inner steps of store for BDDs. +

          + +

          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

          + +

          See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
          Defined in dddmpStoreBdd.c + +
          +
          +static int 
          +DddmpCuddDdArrayLoadCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  Dddmp_RootMatchType  rootmatchmode, IN: storing mode selector
          +  char ** rootmatchnames, IN: sorted names for loaded roots
          +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names, by ids
          +  int * varmatchauxids, IN: array of variable auxids, by ids
          +  int * varcomposeids, IN: array of new ids, by ids
          +  int  mode, IN: computation mode
          +  char * file, IN: file name
          +  FILE * fp, IN: file pointer
          +  DdNode *** rootsPtrPtr, OUT: array of BDD roots
          +  int * nRoots OUT: number of BDDs returned
          +)
          +
          +
          Reads a dump file representing the argument BDDs in CNF + format. + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddBddArrayLoad + + +
          Defined in dddmpLoadCnf.c + +
          +
          +static int 
          +DddmpCuddDdArrayLoad(
          +  Dddmp_DecompType  ddType, IN: Selects decomp type
          +  DdManager * ddMgr, IN: DD Manager
          +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
          +  char ** rootmatchnames, IN: sorted names for loaded roots
          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names, by ids
          +  int * varmatchauxids, IN: array of variable auxids, by ids
          +  int * varcomposeids, IN: array of new ids, by ids
          +  int  mode, IN: requested input file format
          +  char * file, IN: file name
          +  FILE * fp, IN: file pointer
          +  DdNode *** pproots OUT: array BDD roots (by reference)
          +)
          +
          +
          Reads a dump file representing the argument BDDs. The header is + common to both text and binary mode. The node list is either + in text or binary format. A dynamic vector of DD pointers + is allocated to support conversion from DD indexes to pointers. + Several criteria are supported for variable match between file + and dd manager. Several changes/permutations/compositions are allowed + for variables while loading DDs. Variable of the dd manager are allowed + to match with variables on file on ids, permids, varnames, + varauxids; also direct composition between ids and + composeids is supported. More in detail: +
            +
          1. varMatchMode=DDDMP_VAR_MATCHIDS

            + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

          2. varMatchMode=DDDMP_VAR_MATCHPERMIDS

            + is used to allow variable match according to the position in the ordering. + +

          3. varMatchMode=DDDMP_VAR_MATCHNAMES

            + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

          4. varMatchMode=DDDMP_VAR_MATCHIDS

            + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

          5. varMatchMode=DDDMP_VAR_COMPOSEIDS

            + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. +

          + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddBddArrayStore + + +
          Defined in dddmpLoad.c + +
          +
          +int 
          +DddmpCuddDdArrayStoreBdd(
          +  Dddmp_DecompType  ddType, IN: Selects the decomp type: BDD or ADD
          +  DdManager * ddMgr, IN: DD Manager
          +  char * ddname, IN: DD name (or NULL)
          +  int  nRoots, IN: number of output BDD roots to be stored
          +  DdNode ** f, IN: array of DD roots to be stored
          +  char ** rootnames, IN: array of root names (or NULL)
          +  char ** varnames, IN: array of variable names (or NULL)
          +  int * auxids, IN: array of converted var IDs
          +  int  mode, IN: storing mode selector
          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument array of BDDs/ADDs to file. Internal + function doing inner steps of store for BDDs and ADDs. + ADD store is presently supported only with the text format. +

          + +

          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

          + +

          See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
          Defined in dddmpStoreAdd.c + +
          +
          +static int 
          +DddmpCuddDdArrayStoreBlifBody(
          +  DdManager * ddMgr, IN: Manager
          +  int  n, IN: Number of output nodes to be dumped
          +  DdNode ** f, IN: Array of output nodes to be dumped
          +  char ** inputNames, IN: Array of input names (or NULL)
          +  char ** outputNames, IN: Array of output names (or NULL)
          +  FILE * fp IN: Pointer to the dump file
          +)
          +
          +
          Writes a blif body representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). + DddmpCuddDdArrayStoreBlif does not close the file: This is the + caller responsibility. + DddmpCuddDdArrayStoreBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inputNames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for outputNames. This function prints out only + .names part. +

          + +

          Side Effects None +

          + +

          Defined in dddmpStoreMisc.c + +
          +
          +static int 
          +DddmpCuddDdArrayStoreBlifStep(
          +  DdManager * ddMgr, 
          +  DdNode * f, 
          +  FILE * fp, 
          +  st_table * visited, 
          +  char ** names 
          +)
          +
          +
          Performs the recursive step of DddmpCuddDdArrayStoreBlif. + Traverses the BDD f and writes a multiplexer-network description to + the file pointed by fp in blif format. + f is assumed to be a regular pointer and DddmpCuddDdArrayStoreBlifStep + guarantees this assumption in the recursive calls. +

          + +

          Side Effects None +

          + +

          Defined in dddmpStoreMisc.c + +
          +
          +static int 
          +DddmpCuddDdArrayStoreBlif(
          +  DdManager * ddMgr, IN: Manager
          +  int  n, IN: Number of output nodes to be dumped
          +  DdNode ** f, IN: Array of output nodes to be dumped
          +  char ** inputNames, IN: Array of input names (or NULL)
          +  char ** outputNames, IN: Array of output names (or NULL)
          +  char * modelName, IN: Model name (or NULL)
          +  FILE * fp IN: Pointer to the dump file
          +)
          +
          +
          Writes a blif file representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). + DddmpCuddDdArrayStoreBlif does not close the file: This is the + caller responsibility. + DddmpCuddDdArrayStoreBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for outputNames. + It prefixes the string "NODE" to each nome to have "regular" names + for each elements. +

          + +

          Side Effects None +

          + +

          See Also DddmpCuddDdArrayStoreBlifBody +Cudd_DumpBlif + + +
          Defined in dddmpStoreMisc.c + +
          +
          +static int 
          +DddmpCuddDdArrayStorePrefixBody(
          +  DdManager * ddMgr, IN: Manager
          +  int  n, IN: Number of output nodes to be dumped
          +  DdNode ** f, IN: Array of output nodes to be dumped
          +  char ** inputNames, IN: Array of input names (or NULL)
          +  char ** outputNames, IN: Array of output names (or NULL)
          +  FILE * fp IN: Pointer to the dump file
          +)
          +
          +
          One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) +

          + +

          Side Effects None +

          + +

          See Also DddmpCuddDdArrayStoreBlif + + +
          Defined in dddmpStoreMisc.c + +
          +
          +static int 
          +DddmpCuddDdArrayStorePrefixStep(
          +  DdManager * ddMgr, 
          +  DdNode * f, 
          +  FILE * fp, 
          +  st_table * visited, 
          +  char ** names 
          +)
          +
          +
          Performs the recursive step of + DddmpCuddDdArrayStorePrefixBody. + Traverses the BDD f and writes a multiplexer-network description to the + file pointed by fp. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + f is assumed to be a regular pointer and the function guarantees this + assumption in the recursive calls. +

          + +

          Side Effects None +

          + +

          Defined in dddmpStoreMisc.c + +
          +
          +static int 
          +DddmpCuddDdArrayStorePrefix(
          +  DdManager * ddMgr, IN: Manager
          +  int  n, IN: Number of output nodes to be dumped
          +  DdNode ** f, IN: Array of output nodes to be dumped
          +  char ** inputNames, IN: Array of input names (or NULL)
          +  char ** outputNames, IN: Array of output names (or NULL)
          +  char * modelName, IN: Model name (or NULL)
          +  FILE * fp IN: Pointer to the dump file
          +)
          +
          +
          One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + Comments (COMMENT) are added at the beginning of the description to + describe inputs and outputs of the design. + A buffer (BUF) is add on the output to cope with complemented functions. +

          + +

          Side Effects None +

          + +

          See Also DddmpCuddDdArrayStoreBlif + + +
          Defined in dddmpStoreMisc.c + +
          +
          +static int 
          +DddmpCuddDdArrayStoreSmvBody(
          +  DdManager * ddMgr, IN: Manager
          +  int  n, IN: Number of output nodes to be dumped
          +  DdNode ** f, IN: Array of output nodes to be dumped
          +  char ** inputNames, IN: Array of input names (or NULL)
          +  char ** outputNames, IN: Array of output names (or NULL)
          +  FILE * fp IN: Pointer to the dump file
          +)
          +
          +
          One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) +

          + +

          Side Effects None +

          + +

          See Also DddmpCuddDdArrayStoreBlif + + +
          Defined in dddmpStoreMisc.c + +
          +
          +static int 
          +DddmpCuddDdArrayStoreSmvStep(
          +  DdManager * ddMgr, 
          +  DdNode * f, 
          +  FILE * fp, 
          +  st_table * visited, 
          +  char ** names 
          +)
          +
          +
          Performs the recursive step of + DddmpCuddDdArrayStoreSmvBody. + Traverses the BDD f and writes a multiplexer-network description to the + file pointed by fp. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + f is assumed to be a regular pointer and the function guarantees this + assumption in the recursive calls. +

          + +

          Side Effects None +

          + +

          Defined in dddmpStoreMisc.c + +
          +
          +static int 
          +DddmpCuddDdArrayStoreSmv(
          +  DdManager * ddMgr, IN: Manager
          +  int  n, IN: Number of output nodes to be dumped
          +  DdNode ** f, IN: Array of output nodes to be dumped
          +  char ** inputNames, IN: Array of input names (or NULL)
          +  char ** outputNames, IN: Array of output names (or NULL)
          +  char * modelName, IN: Model name (or NULL)
          +  FILE * fp IN: Pointer to the dump file
          +)
          +
          +
          One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + Comments (COMMENT) are added at the beginning of the description to + describe inputs and outputs of the design. + A buffer (BUF) is add on the output to cope with complemented functions. +

          + +

          Side Effects None +

          + +

          See Also DddmpCuddDdArrayStoreBlif + + +
          Defined in dddmpStoreMisc.c + +
          +
          +static void 
          +DddmpDdNodesCheckIncomingAndScanPath(
          +  DdNode * f, IN: BDD node to be numbered
          +  int  pathLengthCurrent, IN: Current Path Length
          +  int  edgeInTh, IN: Max # In-Edges, after a Insert Cut Point
          +  int  pathLengthTh IN: Max Path Length (after, Insert a Cut Point)
          +)
          +
          +
          Number nodes recursively in post-order. + The "visited" flag is used with the right polarity. + The node is assigned to a new CNF variable only if it is a "shared" + node (i.e. the number of its incoming edges is greater than 1). +

          + +

          Side Effects "visited" flags are set. +

          + +

          Defined in dddmpDdNodeCnf.c + +
          +
          +static void 
          +DddmpDdNodesCheckIncomingAndScanPath(
          +  DdNode * f, IN: BDD node to be numbered
          +  int  pathLengthCurrent, IN: Current Path Length
          +  int  edgeInTh, IN: Max # In-Edges, after a Insert Cut Point
          +  int  pathLengthTh IN: Max Path Length (after, Insert a Cut Point)
          +)
          +
          +
          Number nodes recursively in post-order. + The "visited" flag is used with the right polarity. + The node is assigned to a new CNF variable only if it is a "shared" + node (i.e. the number of its incoming edges is greater than 1). +

          + +

          Side Effects "visited" flags are set. +

          + +

          Defined in dddmpNodeCnf.c + +
          +
          +int 
          +DddmpDdNodesCountEdgesAndNumber(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: Array of BDDs
          +  int  rootN, IN: Number of BDD roots in the array of BDDs
          +  int  edgeInTh, IN: Max # In-Edges, after a Insert Cut Point
          +  int  pathLengthTh, IN: Max Path Length (after, Insert a Cut Point)
          +  int * cnfIds, OUT: CNF identifiers for variables
          +  int  id OUT: Number of Temporary Variables Introduced
          +)
          +
          +
          Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. +

          + +

          Side Effects Nodes are temporarily removed from unique table +

          + +

          See Also RemoveFromUniqueRecurCnf() + + +
          Defined in dddmpDdNodeCnf.c + +
          +
          +int 
          +DddmpDdNodesCountEdgesAndNumber(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: Array of BDDs
          +  int  rootN, IN: Number of BDD roots in the array of BDDs
          +  int  edgeInTh, IN: Max # In-Edges, after a Insert Cut Point
          +  int  pathLengthTh, IN: Max Path Length (after, Insert a Cut Point)
          +  int * cnfIds, OUT: CNF identifiers for variables
          +  int  id OUT: Number of Temporary Variables Introduced
          +)
          +
          +
          Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. +

          + +

          Side Effects Nodes are temporarily removed from unique table +

          + +

          See Also RemoveFromUniqueRecurCnf() + + +
          Defined in dddmpNodeCnf.c + +
          +
          +static int 
          +DddmpDdNodesCountEdgesRecur(
          +  DdNode * f IN: root of the BDD
          +)
          +
          +
          Counts (recursively) the number of incoming edges for each + node of a BDD. This number is stored in the index field. +

          + +

          Side Effects "visited" flags remain untouched. +

          + +

          Defined in dddmpDdNodeCnf.c + +
          +
          +static int 
          +DddmpDdNodesCountEdgesRecur(
          +  DdNode * f IN: root of the BDD
          +)
          +
          +
          Counts (recursively) the number of incoming edges for each + node of a BDD. This number is stored in the index field. +

          + +

          Side Effects "visited" flags remain untouched. +

          + +

          Defined in dddmpNodeCnf.c + +
          +
          +static int 
          +DddmpDdNodesNumberEdgesRecur(
          +  DdNode * f, IN: BDD node to be numbered
          +  int * cnfIds, IN: possible source for numbering
          +  int  id IN/OUT: possible source for numbering
          +)
          +
          +
          Number nodes recursively in post-order. + The "visited" flag is used with the inverse polarity. + Numbering follows the subsequent strategy: + * if the index = 0 it remains so + * if the index >= 1 it gets enumerated. + This implies that the node is assigned to a new CNF variable only if + it is not a terminal node otherwise it is assigned the index of + the BDD variable. +

          + +

          Side Effects "visited" flags are reset. +

          + +

          Defined in dddmpDdNodeCnf.c + +
          +
          +static int 
          +DddmpDdNodesNumberEdgesRecur(
          +  DdNode * f, IN: BDD node to be numbered
          +  int * cnfIds, IN: possible source for numbering
          +  int  id IN/OUT: possible source for numbering
          +)
          +
          +
          Number nodes recursively in post-order. + The "visited" flag is used with the inverse polarity. + Numbering follows the subsequent strategy: + * if the index = 0 it remains so + * if the index >= 1 it gets enumerated. + This implies that the node is assigned to a new CNF variable only if + it is not a terminal node otherwise it is assigned the index of + the BDD variable. +

          + +

          Side Effects "visited" flags are reset. +

          + +

          Defined in dddmpNodeCnf.c + +
          +
          +static int 
          +DddmpDdNodesResetCountRecur(
          +  DdNode * f IN: root of the BDD whose counters are reset
          +)
          +
          +
          Resets counter and visited flag for ALL nodes of a BDD (it + recurs on the node children). The index field of the node is + used as counter. +

          + +

          Defined in dddmpDdNodeCnf.c + +
          +
          +static int 
          +DddmpDdNodesResetCountRecur(
          +  DdNode * f IN: root of the BDD whose counters are reset
          +)
          +
          +
          Resets counter and visited flag for ALL nodes of a BDD (it + recurs on the node children). The index field of the node is + used as counter. +

          + +

          Defined in dddmpNodeCnf.c + +
          +
          +static void 
          +DddmpFreeHeaderCnf(
          +  Dddmp_Hdr_t * Hdr IN: pointer to header
          +)
          +
          +
          Frees the internal header structure by freeing all internal + fields first. +

          + +

          Defined in dddmpLoadCnf.c + +
          +
          +static void 
          +DddmpFreeHeader(
          +  Dddmp_Hdr_t * Hdr IN: pointer to header
          +)
          +
          +
          Frees the internal header structureby freeing all internal + fields first. +

          + +

          Defined in dddmpLoad.c + +
          +
          +int * 
          +DddmpIntArrayDup(
          +  int * array, IN: array of ints to be duplicated
          +  int  n IN: size of the array
          +)
          +
          +
          Allocates memory and copies source array +

          + +

          Side Effects None +

          + +

          Defined in dddmpUtil.c + +
          +
          +int * 
          +DddmpIntArrayRead(
          +  FILE * fp, IN: input file
          +  int  n IN: size of the array
          +)
          +
          +
          Allocates memory and inputs source array +

          + +

          Side Effects None +

          + +

          Defined in dddmpUtil.c + +
          +
          +int 
          +DddmpIntArrayWrite(
          +  FILE * fp, IN: output file
          +  int * array, IN: array of ints
          +  int  n IN: size of the array
          +)
          +
          +
          Outputs an array of ints to a specified file +

          + +

          Side Effects None +

          + +

          Defined in dddmpUtil.c + +
          +
          +int 
          +DddmpNumberAddNodes(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDDs
          +  int  n IN: number of BDD roots in the array of BDDs
          +)
          +
          +
          Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodes()). +

          + +

          Side Effects Nodes are temporarily removed from unique table +

          + +

          See Also RemoveFromUniqueRecurAdd +() +NumberNodeRecurAdd +() +DddmpUnnumberDdNodesAdd +() + + +
          Defined in dddmpNodeAdd.c + +
          +
          +int 
          +DddmpNumberBddNodes(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDDs
          +  int  n IN: number of BDD roots in the array of BDDs
          +)
          +
          +
          Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberBddNodes ()). +

          + +

          Side Effects Nodes are temporarily removed from unique table +

          + +

          See Also RemoveFromUniqueRecur() +NumberNodeRecur() +DddmpUnnumberBddNodes +() + + +
          Defined in dddmpNodeBdd.c + +
          +
          +int 
          +DddmpNumberDdNodesCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDDs
          +  int  rootN, IN: number of BDD roots in the array of BDDs
          +  int * cnfIds, OUT: CNF identifiers for variables
          +  int  id OUT: number of Temporary Variables Introduced
          +)
          +
          +
          Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodesCnf()). +

          + +

          Side Effects Nodes are temporarily removed from unique table +

          + +

          See Also RemoveFromUniqueRecurCnf() +NumberNodeRecurCnf() +DddmpUnnumberDdNodesCnf() + + +
          Defined in dddmpDdNodeCnf.c + +
          +
          +int 
          +DddmpNumberDdNodesCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDDs
          +  int  rootN, IN: number of BDD roots in the array of BDDs
          +  int * cnfIds, OUT: CNF identifiers for variables
          +  int  id OUT: number of Temporary Variables Introduced
          +)
          +
          +
          Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodesCnf()). +

          + +

          Side Effects Nodes are temporarily removed from unique table +

          + +

          See Also RemoveFromUniqueRecurCnf() +NumberNodeRecurCnf() +DddmpUnnumberDdNodesCnf() + + +
          Defined in dddmpNodeCnf.c + +
          +
          +int 
          +DddmpNumberDdNodes(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDDs
          +  int  n IN: number of BDD roots in the array of BDDs
          +)
          +
          +
          Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodes()). +

          + +

          Side Effects Nodes are temporarily removed from unique table +

          + +

          See Also RemoveFromUniqueRecur() +NumberNodeRecur() +DddmpUnnumberDdNodes() + + +
          Defined in dddmpDdNodeBdd.c + +
          +
          +static int 
          +DddmpPrintBddAndNextRecur(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f IN: root of the BDD to be displayed
          +)
          +
          +
          Prints debug info for a BDD on the screen. It recurs on + node's children. +

          + +

          Defined in dddmpDdNodeCnf.c + +
          +
          +static int 
          +DddmpPrintBddAndNextRecur(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f IN: root of the BDD to be displayed
          +)
          +
          +
          Prints debug info for a BDD on the screen. It recurs on + node's children. +

          + +

          Defined in dddmpNodeCnf.c + +
          +
          +int 
          +DddmpPrintBddAndNext(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: Array of BDDs to be displayed
          +  int  rootN IN: Number of BDD roots in the array of BDDs
          +)
          +
          +
          Prints debug information for an array of BDDs on the screen +

          + +

          Side Effects None +

          + +

          Defined in dddmpDdNodeCnf.c + +
          +
          +int 
          +DddmpPrintBddAndNext(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: Array of BDDs to be displayed
          +  int  rootN IN: Number of BDD roots in the array of BDDs
          +)
          +
          +
          Prints debug information for an array of BDDs on the screen +

          + +

          Side Effects None +

          + +

          Defined in dddmpNodeCnf.c + +
          +
          +static int 
          +DddmpReadCnfClauses(
          +  Dddmp_Hdr_t * Hdr, IN: file header
          +  int *** cnfTable, OUT: CNF table for clauses
          +  FILE * fp IN: source file
          +)
          +
          +
          Read the CNF clauses from the file in the standard DIMACS + format. Store all the clauses in an internal structure for + future transformation into BDDs. +

          + +

          Defined in dddmpLoadCnf.c + +
          +
          +int 
          +DddmpReadCode(
          +  FILE * fp, IN: file where to read the code
          +  struct binary_dd_code * pcode OUT: the read code
          +)
          +
          +
          Reads a 1 byte node code. See DddmpWriteCode() + for code description. +

          + +

          Side Effects None +

          + +

          See Also DddmpWriteCode() + + +
          Defined in dddmpBinary.c + +
          +
          +int 
          +DddmpReadInt(
          +  FILE * fp, IN: file where to read the integer
          +  int * pid OUT: the read integer
          +)
          +
          +
          Reads an integer coded on a sequence of bytes. See + DddmpWriteInt() for format. +

          + +

          Side Effects None +

          + +

          See Also DddmpWriteInt() + + +
          Defined in dddmpBinary.c + +
          +
          +int 
          +DddmpReadNodeIndexAdd(
          +  DdNode * f IN: BDD node
          +)
          +
          +
          Reads the index of a node. LSB is skipped (used as visited + flag). +

          + +

          Side Effects None +

          + +

          See Also DddmpWriteNodeIndexAdd +() +DddmpSetVisitedAdd +() +DddmpVisitedAdd +() + + +
          Defined in dddmpNodeAdd.c + +
          +
          +int 
          +DddmpReadNodeIndexBdd(
          +  DdNode * f IN: BDD node
          +)
          +
          +
          Reads the index of a node. LSB is skipped (used as visited + flag). +

          + +

          Side Effects None +

          + +

          See Also DddmpWriteNodeIndexBdd +() +DddmpSetVisitedBdd +() +DddmpVisitedBdd +() + + +
          Defined in dddmpNodeBdd.c + +
          +
          +int 
          +DddmpReadNodeIndexCnf(
          +  DdNode * f IN: BDD node
          +)
          +
          +
          Reads the index of a node. LSB is skipped (used as visited + flag). +

          + +

          Side Effects None +

          + +

          See Also DddmpWriteNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
          Defined in dddmpNodeCnf.c + +
          +
          +static int 
          +DddmpReadNodeIndexCnf(
          +  DdNode * f IN: BDD node
          +)
          +
          +
          Reads the index of a node. LSB is skipped (used as visited + flag). +

          + +

          Side Effects None +

          + +

          See Also DddmpWriteNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
          Defined in dddmpDdNodeCnf.c + +
          +
          +int 
          +DddmpReadNodeIndex(
          +  DdNode * f IN: BDD node
          +)
          +
          +
          Reads the index of a node. LSB is skipped (used as visited + flag). +

          + +

          Side Effects None +

          + +

          See Also DddmpWriteNodeIndex() +DddmpSetVisited +() +DddmpVisited +() + + +
          Defined in dddmpDdNodeBdd.c + +
          +
          +void 
          +DddmpSetVisitedAdd(
          +  DdNode * f IN: BDD node to be marked (as visited)
          +)
          +
          +
          Marks a node as visited +

          + +

          Side Effects None +

          + +

          See Also DddmpVisitedAdd +() +DddmpClearVisitedAdd +() + + +
          Defined in dddmpNodeAdd.c + +
          +
          +void 
          +DddmpSetVisitedBdd(
          +  DdNode * f IN: BDD node to be marked (as visited)
          +)
          +
          +
          Marks a node as visited +

          + +

          Side Effects None +

          + +

          See Also DddmpVisitedBdd +() +DddmpClearVisitedBdd +() + + +
          Defined in dddmpNodeBdd.c + +
          +
          +static void 
          +DddmpSetVisitedCnf(
          +  DdNode * f IN: BDD node to be marked (as visited)
          +)
          +
          +
          Marks a node as visited +

          + +

          Side Effects None +

          + +

          See Also DddmpVisitedCnf +() +DddmpClearVisitedCnf +() + + +
          Defined in dddmpDdNodeCnf.c + +
          +
          +void 
          +DddmpSetVisitedCnf(
          +  DdNode * f IN: BDD node to be marked (as visited)
          +)
          +
          +
          Marks a node as visited +

          + +

          Side Effects None +

          + +

          See Also DddmpVisitedCnf +() +DddmpClearVisitedCnf +() + + +
          Defined in dddmpNodeCnf.c + +
          +
          +void 
          +DddmpSetVisited(
          +  DdNode * f IN: BDD node to be marked (as visited)
          +)
          +
          +
          Marks a node as visited +

          + +

          Side Effects None +

          + +

          See Also DddmpVisited +() +DddmpClearVisited +() + + +
          Defined in dddmpDdNodeBdd.c + +
          +
          +char ** 
          +DddmpStrArrayDup(
          +  char ** array, IN: array of strings to be duplicated
          +  int  n IN: size of the array
          +)
          +
          +
          Allocates memory and copies source array +

          + +

          Side Effects None +

          + +

          Defined in dddmpUtil.c + +
          +
          +void 
          +DddmpStrArrayFree(
          +  char ** array, IN: array of strings
          +  int  n IN: size of the array
          +)
          +
          +
          Frees memory for strings and the array of pointers +

          + +

          Side Effects None +

          + +

          Defined in dddmpUtil.c + +
          +
          +char ** 
          +DddmpStrArrayRead(
          +  FILE * fp, IN: input file
          +  int  n IN: size of the array
          +)
          +
          +
          Allocates memory and inputs source array +

          + +

          Side Effects None +

          + +

          Defined in dddmpUtil.c + +
          +
          +int 
          +DddmpStrArrayWrite(
          +  FILE * fp, IN: output file
          +  char ** array, IN: array of strings
          +  int  n IN: size of the array
          +)
          +
          +
          Outputs an array of strings to a specified file +

          + +

          Side Effects None +

          + +

          Defined in dddmpUtil.c + +
          +
          +char * 
          +DddmpStrDup(
          +  char * str IN: string to be duplicated
          +)
          +
          +
          Allocates memory and copies source string +

          + +

          Side Effects None +

          + +

          Defined in dddmpUtil.c + +
          +
          +void 
          +DddmpUnnumberAddNodes(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDDs
          +  int  n IN: number of BDD roots in the array of BDDs
          +)
          +
          +
          Node indexes are no more needed. Nodes are re-linked in the + unique table. +

          + +

          Side Effects None +

          + +

          See Also DddmpNumberDdNodeAdd +() + + +
          Defined in dddmpNodeAdd.c + +
          +
          +void 
          +DddmpUnnumberBddNodes(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDDs
          +  int  n IN: number of BDD roots in the array of BDDs
          +)
          +
          +
          Node indexes are no more needed. Nodes are re-linked in the + unique table. +

          + +

          Side Effects None +

          + +

          See Also DddmpNumberBddNode +() + + +
          Defined in dddmpNodeBdd.c + +
          +
          +void 
          +DddmpUnnumberDdNodesCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDDs
          +  int  rootN IN: number of BDD roots in the array of BDDs
          +)
          +
          +
          Node indexes are no more needed. Nodes are re-linked in the + unique table. +

          + +

          Side Effects None +

          + +

          See Also DddmpNumberDdNode() + + +
          Defined in dddmpDdNodeCnf.c + +
          +
          +void 
          +DddmpUnnumberDdNodesCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDDs
          +  int  rootN IN: number of BDD roots in the array of BDDs
          +)
          +
          +
          Node indexes are no more needed. Nodes are re-linked in the + unique table. +

          + +

          Side Effects None +

          + +

          See Also DddmpNumberDdNode() + + +
          Defined in dddmpNodeCnf.c + +
          +
          +void 
          +DddmpUnnumberDdNodes(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDDs
          +  int  n IN: number of BDD roots in the array of BDDs
          +)
          +
          +
          Node indexes are no more needed. Nodes are re-linked in the + unique table. +

          + +

          Side Effects None +

          + +

          See Also DddmpNumberDdNode() + + +
          Defined in dddmpDdNodeBdd.c + +
          +
          +int 
          +DddmpVisitedAdd(
          +  DdNode * f IN: BDD node to be tested
          +)
          +
          +
          Returns true if node is visited +

          + +

          Side Effects None +

          + +

          See Also DddmpSetVisitedAdd +() +DddmpClearVisitedAdd +() + + +
          Defined in dddmpNodeAdd.c + +
          +
          +int 
          +DddmpVisitedBdd(
          +  DdNode * f IN: BDD node to be tested
          +)
          +
          +
          Returns true if node is visited +

          + +

          Side Effects None +

          + +

          See Also DddmpSetVisitedBdd +() +DddmpClearVisitedBdd +() + + +
          Defined in dddmpNodeBdd.c + +
          +
          +int 
          +DddmpVisitedCnf(
          +  DdNode * f IN: BDD node to be tested
          +)
          +
          +
          Returns true if node is visited +

          + +

          Side Effects None +

          + +

          See Also DddmpSetVisitedCnf +() +DddmpClearVisitedCnf +() + + +
          Defined in dddmpNodeCnf.c + +
          +
          +static int 
          +DddmpVisitedCnf(
          +  DdNode * f IN: BDD node to be tested
          +)
          +
          +
          Returns true if node is visited +

          + +

          Side Effects None +

          + +

          See Also DddmpSetVisitedCnf +() +DddmpClearVisitedCnf +() + + +
          Defined in dddmpDdNodeCnf.c + +
          +
          +int 
          +DddmpVisited(
          +  DdNode * f IN: BDD node to be tested
          +)
          +
          +
          Returns true if node is visited +

          + +

          Side Effects None +

          + +

          See Also DddmpSetVisited +() +DddmpClearVisited +() + + +
          Defined in dddmpDdNodeBdd.c + +
          +
          +int 
          +DddmpWriteCode(
          +  FILE * fp, IN: file where to write the code
          +  struct binary_dd_code  code IN: the code to be written
          +)
          +
          +
          outputs a 1 byte node code using the following format: +
          +     Unused      : 1 bit;
          +     V           : 2 bits;     (variable code)
          +     T           : 2 bits;     (Then code)
          +     Ecompl      : 1 bit;      (Else complemented)
          +     E           : 2 bits;     (Else code)
          +    
          + Ecompl is set with complemented edges. +

          + +

          Side Effects None +

          + +

          See Also DddmpReadCode() + + +
          Defined in dddmpBinary.c + +
          +
          +int 
          +DddmpWriteInt(
          +  FILE * fp, IN: file where to write the integer
          +  int  id IN: integer to be written
          +)
          +
          +
          Writes an integer as a sequence of bytes (MSByte first). + For each byte 7 bits are used for data and one (LSBit) as link + with a further byte (LSB = 1 means one more byte). +

          + +

          Side Effects None +

          + +

          See Also DddmpReadInt() + + +
          Defined in dddmpBinary.c + +
          +
          +void 
          +DddmpWriteNodeIndexAdd(
          +  DdNode * f, IN: BDD node
          +  int  id IN: index to be written
          +)
          +
          +
          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

          + +

          Side Effects None +

          + +

          See Also DddmpReadNodeIndexAdd +() +DddmpSetVisitedAdd +() +DddmpVisitedAdd +() + + +
          Defined in dddmpNodeAdd.c + +
          +
          +void 
          +DddmpWriteNodeIndexBdd(
          +  DdNode * f, IN: BDD node
          +  int  id IN: index to be written
          +)
          +
          +
          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

          + +

          Side Effects None +

          + +

          See Also DddmpReadNodeIndexBdd() +DddmpSetVisitedBdd +() +DddmpVisitedBdd +() + + +
          Defined in dddmpNodeBdd.c + +
          +
          +int 
          +DddmpWriteNodeIndexCnfBis(
          +  DdNode * f, IN: BDD node
          +  int  id IN: index to be written
          +)
          +
          +
          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

          + +

          Side Effects None +

          + +

          See Also DddmpReadNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
          Defined in dddmpDdNodeCnf.c + +
          +
          +static int 
          +DddmpWriteNodeIndexCnfWithTerminalCheck(
          +  DdNode * f, IN: BDD node
          +  int * cnfIds, IN: possible source for the index to be written
          +  int  id IN: possible source for the index to be written
          +)
          +
          +
          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. The index corresponds to + the BDD node variable if both the node's children are a + constant node, otherwise a new CNF variable is used. +

          + +

          Side Effects None +

          + +

          See Also DddmpReadNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
          Defined in dddmpNodeCnf.c + +
          +
          +int 
          +DddmpWriteNodeIndexCnf(
          +  DdNode * f, IN: BDD node
          +  int  id IN: index to be written
          +)
          +
          +
          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

          + +

          Side Effects None +

          + +

          See Also DddmpReadNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
          Defined in dddmpNodeCnf.c + +
          +
          +static int 
          +DddmpWriteNodeIndexCnf(
          +  DdNode * f, IN: BDD node
          +  int * cnfIds, IN: possible source for the index to be written
          +  int  id IN: possible source for the index to be written
          +)
          +
          +
          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. The index corresponds to + the BDD node variable if both the node's children are a + constant node, otherwise a new CNF variable is used. +

          + +

          Side Effects None +

          + +

          See Also DddmpReadNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
          Defined in dddmpDdNodeCnf.c + +
          +
          +void 
          +DddmpWriteNodeIndex(
          +  DdNode * f, IN: BDD node
          +  int  id IN: index to be written
          +)
          +
          +
          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

          + +

          Side Effects None +

          + +

          See Also DddmpReadNodeIndex() +DddmpSetVisited +() +DddmpVisited +() + + +
          Defined in dddmpDdNodeBdd.c + +
          +
          +int 
          +Dddmp_Bin2Text(
          +  char * filein, IN: name of binary file
          +  char * fileout IN: name of ASCII file
          +)
          +
          +
          Converts from binary to ASCII format. A BDD array is loaded and + and stored to the target file. +

          + +

          Side Effects None +

          + +

          See Also Dddmp_Text2Bin() + + +
          Defined in dddmpConvert.c + +
          +
          +int 
          +Dddmp_Text2Bin(
          +  char * filein, IN: name of ASCII file
          +  char * fileout IN: name of binary file
          +)
          +
          +
          Converts from ASCII to binary format. A BDD array is loaded and + and stored to the target file. +

          + +

          Side Effects None +

          + +

          See Also Dddmp_Bin2Text() + + +
          Defined in dddmpConvert.c + +
          +
          +int 
          +Dddmp_cuddAddArrayLoad(
          +  DdManager * ddMgr, IN: DD Manager
          +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
          +  char ** rootmatchnames, IN: sorted names for loaded roots
          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names, by ids
          +  int * varmatchauxids, IN: array of variable auxids, by ids
          +  int * varcomposeids, IN: array of new ids, by ids
          +  int  mode, IN: requested input file format
          +  char * file, IN: file name
          +  FILE * fp, IN: file pointer
          +  DdNode *** pproots OUT: array of returned BDD roots
          +)
          +
          +
          Reads a dump file representing the argument ADDs. See + BDD load functions for detailed explanation. +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddBddArrayStore + + +
          Defined in dddmpLoad.c + +
          +
          +int 
          +Dddmp_cuddAddArrayStore(
          +  DdManager * ddMgr, IN: DD Manager
          +  char * ddname, IN: DD name (or NULL)
          +  int  nRoots, IN: number of output BDD roots to be stored
          +  DdNode ** f, IN: array of ADD roots to be stored
          +  char ** rootnames, IN: array of root names (or NULL)
          +  char ** varnames, IN: array of variable names (or NULL)
          +  int * auxids, IN: array of converted var IDs
          +  int  mode, IN: storing mode selector
          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument array of ADDs to file. Dumping is + either in text or binary form. see the corresponding BDD dump + function for further details. +

          + +

          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

          + +

          See Also Dddmp_cuddAddStore +Dddmp_cuddAddLoad +Dddmp_cuddAddArrayLoad + + +
          Defined in dddmpStoreAdd.c + +
          +
          +DdNode * 
          +Dddmp_cuddAddLoad(
          +  DdManager * ddMgr, IN: Manager
          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names by IDs
          +  int * varmatchauxids, IN: array of variable auxids by IDs
          +  int * varcomposeids, IN: array of new ids by IDs
          +  int  mode, IN: requested input file format
          +  char * file, IN: file name
          +  FILE * fp IN: file pointer
          +)
          +
          +
          Reads a dump file representing the argument ADD. + Dddmp_cuddAddArrayLoad is used through a dummy array. +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddAddStore +Dddmp_cuddAddArrayLoad + + +
          Defined in dddmpLoad.c + +
          +
          +int 
          +Dddmp_cuddAddStore(
          +  DdManager * ddMgr, IN: DD Manager
          +  char * ddname, IN: DD name (or NULL)
          +  DdNode * f, IN: ADD root to be stored
          +  char ** varnames, IN: array of variable names (or NULL)
          +  int * auxids, IN: array of converted var ids
          +  int  mode, IN: storing mode selector
          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument ADD to file. Dumping is done through + Dddmp_cuddAddArrayStore, And a dummy array of 1 ADD root is + used for this purpose. +

          + +

          Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

          + +

          See Also Dddmp_cuddAddLoad +Dddmp_cuddAddArrayLoad + + +
          Defined in dddmpStoreAdd.c + +
          +
          +int 
          +Dddmp_cuddBddArrayLoadCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  Dddmp_RootMatchType  rootmatchmode, IN: storing mode selector
          +  char ** rootmatchnames, IN: sorted names for loaded roots
          +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names, by IDs
          +  int * varmatchauxids, IN: array of variable auxids, by IDs
          +  int * varcomposeids, IN: array of new ids, by IDs
          +  int  mode, IN: computation Mode
          +  char * file, IN: file name
          +  FILE * fp, IN: file pointer
          +  DdNode *** rootsPtrPtr, OUT: array of returned BDD roots
          +  int * nRoots OUT: number of BDDs returned
          +)
          +
          +
          Reads a dump file representing the argument BDD in a + CNF formula. +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddBddArrayLoad + + +
          Defined in dddmpLoadCnf.c + +
          +
          +int 
          +Dddmp_cuddBddArrayLoad(
          +  DdManager * ddMgr, IN: DD Manager
          +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
          +  char ** rootmatchnames, IN: sorted names for loaded roots
          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names, by ids
          +  int * varmatchauxids, IN: array of variable auxids, by ids
          +  int * varcomposeids, IN: array of new ids, by ids
          +  int  mode, IN: requested input file format
          +  char * file, IN: file name
          +  FILE * fp, IN: file pointer
          +  DdNode *** pproots OUT: array of returned BDD roots
          +)
          +
          +
          Reads a dump file representing the argument BDDs. The header is + common to both text and binary mode. The node list is either + in text or binary format. A dynamic vector of DD pointers + is allocated to support conversion from DD indexes to pointers. + Several criteria are supported for variable match between file + and dd manager. Several changes/permutations/compositions are allowed + for variables while loading DDs. Variable of the dd manager are allowed + to match with variables on file on ids, permids, varnames, + varauxids; also direct composition between ids and + composeids is supported. More in detail: +
            +
          1. varMatchMode=DDDMP_VAR_MATCHIDS

            + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

          2. varMatchMode=DDDMP_VAR_MATCHPERMIDS

            + is used to allow variable match according to the position in the + ordering. + +

          3. varMatchMode=DDDMP_VAR_MATCHNAMES

            + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

          4. varMatchMode=DDDMP_VAR_MATCHIDS

            + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

          5. varMatchMode=DDDMP_VAR_COMPOSEIDS

            + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. +

          + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. + + All the loaded BDDs are referenced before returning them. +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddBddArrayStore + + +
          Defined in dddmpLoad.c + +
          +
          +int 
          +Dddmp_cuddBddArrayStoreBlif(
          +  DdManager * ddMgr, IN: DD Manager
          +  int  nroots, IN: number of output BDD roots to be stored
          +  DdNode ** f, IN: array of BDD roots to be stored
          +  char ** inputNames, IN: array of variable names (or NULL)
          +  char ** outputNames, IN: array of root names (or NULL)
          +  char * modelName, IN: Model Name
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBLif. + A dummy array of 1 BDD root is used for this purpose. +

          + +

          See Also Dddmp_cuddBddArrayStorePrefix + + +
          Defined in dddmpStoreMisc.c + +
          +
          +int 
          +Dddmp_cuddBddArrayStoreCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDD roots to be stored
          +  int  rootN, IN: # output BDD roots to be stored
          +  Dddmp_DecompCnfStoreType  mode, IN: format selection
          +  int  noHeader, IN: do not store header iff 1
          +  char ** varNames, IN: array of variable names (or NULL)
          +  int * bddIds, IN: array of converted var IDs
          +  int * bddAuxIds, IN: array of BDD node Auxiliary Ids
          +  int * cnfIds, IN: array of converted var IDs
          +  int  idInitial, IN: starting id for cutting variables
          +  int  edgeInTh, IN: Max # Incoming Edges
          +  int  pathLengthTh, IN: Max Path Length
          +  char * fname, IN: file name
          +  FILE * fp, IN: pointer to the store file
          +  int * clauseNPtr, OUT: number of clause stored
          +  int * varNewNPtr OUT: number of new variable created
          +)
          +
          +
          Dumps the argument array of BDDs to file. +

          + +

          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + Three methods are allowed: + * NodeByNode method: Insert a cut-point for each BDD node (but the + terminal nodes) + * MaxtermByMaxterm method: Insert no cut-points, i.e. the off-set of + trhe function is stored + * Best method: Tradeoff between the previous two methods. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. + The stored file can contain a file header or not depending on the + noHeader parameter (IFF 0, usual setting, the header is usually stored. + This option can be useful in storing multiple BDDs, as separate BDDs, + on the same file leaving the opening of the file to the caller. +

          + +

          Defined in dddmpStoreCnf.c + +
          +
          +int 
          +Dddmp_cuddBddArrayStorePrefix(
          +  DdManager * ddMgr, IN: DD Manager
          +  int  nroots, IN: number of output BDD roots to be stored
          +  DdNode ** f, IN: array of BDD roots to be stored
          +  char ** inputNames, IN: array of variable names (or NULL)
          +  char ** outputNames, IN: array of root names (or NULL)
          +  char * modelName, IN: Model Name
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

          + +

          See Also Dddmp_cuddBddArrayStore + + +
          Defined in dddmpStoreMisc.c + +
          +
          +int 
          +Dddmp_cuddBddArrayStoreSmv(
          +  DdManager * ddMgr, IN: DD Manager
          +  int  nroots, IN: number of output BDD roots to be stored
          +  DdNode ** f, IN: array of BDD roots to be stored
          +  char ** inputNames, IN: array of variable names (or NULL)
          +  char ** outputNames, IN: array of root names (or NULL)
          +  char * modelName, IN: Model Name
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

          + +

          See Also Dddmp_cuddBddArrayStore + + +
          Defined in dddmpStoreMisc.c + +
          +
          +int 
          +Dddmp_cuddBddArrayStore(
          +  DdManager * ddMgr, IN: DD Manager
          +  char * ddname, IN: dd name (or NULL)
          +  int  nRoots, IN: number of output BDD roots to be stored
          +  DdNode ** f, IN: array of BDD roots to be stored
          +  char ** rootnames, IN: array of root names (or NULL)
          +  char ** varnames, IN: array of variable names (or NULL)
          +  int * auxids, IN: array of converted var IDs
          +  int  mode, IN: storing mode selector
          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument array of BDDs to file. Dumping is either + in text or binary form. BDDs are stored to the fp (already + open) file if not NULL. Otherwise the file whose name is + fname is opened in write mode. The header has the same format + for both textual and binary dump. Names are allowed for input + variables (vnames) and for represented functions (rnames). + For sake of generality and because of dynamic variable + ordering both variable IDs and permuted IDs are included. + New IDs are also supported (auxids). Variables are identified + with incremental numbers. according with their positiom in + the support set. In text mode, an extra info may be added, + chosen among the following options: name, ID, PermID, or an + auxiliary id. Since conversion from DD pointers to integers + is required, DD nodes are temporarily removed from the unique + hash table. This allows the use of the next field to store + node IDs. +

          + +

          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

          + +

          See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
          Defined in dddmpStoreBdd.c + +
          +
          +int 
          +Dddmp_cuddBddDisplayBinary(
          +  char * fileIn, IN: name of binary file
          +  char * fileOut IN: name of text file
          +)
          +
          +
          Display a binary dump file in a text file +

          + +

          Side Effects None +

          + +

          See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad + + +
          Defined in dddmpDbg.c + +
          +
          +int 
          +Dddmp_cuddBddLoadCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names, by IDs
          +  int * varmatchauxids, IN: array of variable auxids, by IDs
          +  int * varcomposeids, IN: array of new ids accessed, by IDs
          +  int  mode, IN: computation mode
          +  char * file, IN: file name
          +  FILE * fp, IN: file pointer
          +  DdNode *** rootsPtrPtr, OUT: array of returned BDD roots
          +  int * nRoots OUT: number of BDDs returned
          +)
          +
          +
          Reads a dump file representing the argument BDD in a + CNF formula. + Dddmp_cuddBddArrayLoadCnf is used through a dummy array. + The results is returned in different formats depending on the + mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
          Defined in dddmpLoadCnf.c + +
          +
          +DdNode * 
          +Dddmp_cuddBddLoad(
          +  DdManager * ddMgr, IN: DD Manager
          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names - by IDs
          +  int * varmatchauxids, IN: array of variable auxids - by IDs
          +  int * varcomposeids, IN: array of new ids accessed - by IDs
          +  int  mode, IN: requested input file format
          +  char * file, IN: file name
          +  FILE * fp IN: file pointer
          +)
          +
          +
          Reads a dump file representing the argument BDD. + Dddmp_cuddBddArrayLoad is used through a dummy array (see this + function's description for more details). + Mode, the requested input file format, is checked against + the file format. + The loaded BDDs is referenced before returning it. +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddBddStore +Dddmp_cuddBddArrayLoad + + +
          Defined in dddmpLoad.c + +
          +
          +int 
          +Dddmp_cuddBddStoreBlif(
          +  DdManager * ddMgr, IN: DD Manager
          +  int  nRoots, IN: Number of BDD roots
          +  DdNode * f, IN: BDD root to be stored
          +  char ** inputNames, IN: Array of variable names
          +  char ** outputNames, IN: Array of root names
          +  char * modelName, IN: Model Name
          +  char * fileName, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBlif. + A dummy array of 1 BDD root is used for this purpose. +

          + +

          See Also Dddmp_cuddBddStorePrefix + + +
          Defined in dddmpStoreMisc.c + +
          +
          +int 
          +Dddmp_cuddBddStoreCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f, IN: BDD root to be stored
          +  Dddmp_DecompCnfStoreType  mode, IN: format selection
          +  int  noHeader, IN: do not store header iff 1
          +  char ** varNames, IN: array of variable names (or NULL)
          +  int * bddIds, IN: array of var ids
          +  int * bddAuxIds, IN: array of BDD node Auxiliary Ids
          +  int * cnfIds, IN: array of CNF var ids
          +  int  idInitial, IN: starting id for cutting variables
          +  int  edgeInTh, IN: Max # Incoming Edges
          +  int  pathLengthTh, IN: Max Path Length
          +  char * fname, IN: file name
          +  FILE * fp, IN: pointer to the store file
          +  int * clauseNPtr, OUT: number of clause stored
          +  int * varNewNPtr OUT: number of new variable created
          +)
          +
          +
          Dumps the argument BDD to file. + This task is performed by calling the function + Dddmp_cuddBddArrayStoreCnf. +

          + +

          Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

          + +

          See Also Dddmp_cuddBddArrayStoreCnf + + +
          Defined in dddmpStoreCnf.c + +
          +
          +int 
          +Dddmp_cuddBddStorePrefix(
          +  DdManager * ddMgr, IN: DD Manager
          +  int  nRoots, IN: Number of BDD roots
          +  DdNode * f, IN: BDD root to be stored
          +  char ** inputNames, IN: Array of variable names
          +  char ** outputNames, IN: Array of root names
          +  char * modelName, IN: Model Name
          +  char * fileName, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

          + +

          See Also Dddmp_cuddBddStore + + +
          Defined in dddmpStoreMisc.c + +
          +
          +int 
          +Dddmp_cuddBddStoreSmv(
          +  DdManager * ddMgr, IN: DD Manager
          +  int  nRoots, IN: Number of BDD roots
          +  DdNode * f, IN: BDD root to be stored
          +  char ** inputNames, IN: Array of variable names
          +  char ** outputNames, IN: Array of root names
          +  char * modelName, IN: Model Name
          +  char * fileName, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

          + +

          See Also Dddmp_cuddBddStore + + +
          Defined in dddmpStoreMisc.c + +
          +
          +int 
          +Dddmp_cuddBddStore(
          +  DdManager * ddMgr, IN: DD Manager
          +  char * ddname, IN: DD name (or NULL)
          +  DdNode * f, IN: BDD root to be stored
          +  char ** varnames, IN: array of variable names (or NULL)
          +  int * auxids, IN: array of converted var ids
          +  int  mode, IN: storing mode selector
          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. Dumping is done through + Dddmp_cuddBddArrayStore. A dummy array of 1 BDD root is + used for this purpose. +

          + +

          Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

          + +

          See Also Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
          Defined in dddmpStoreBdd.c + +
          +
          +int 
          +Dddmp_cuddHeaderLoadCnf(
          +  int * nVars, OUT: number of DD variables
          +  int * nsuppvars, OUT: number of support variables
          +  char *** suppVarNames, OUT: array of support variable names
          +  char *** orderedVarNames, OUT: array of variable names
          +  int ** varIds, OUT: array of variable ids
          +  int ** varComposeIds, OUT: array of permids ids
          +  int ** varAuxIds, OUT: array of variable aux ids
          +  int * nRoots, OUT: number of root in the file
          +  char * file, IN: file name
          +  FILE * fp IN: file pointer
          +)
          +
          +
          Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. +

          + +

          See Also Dddmp_cuddBddArrayLoad + + +
          Defined in dddmpLoadCnf.c + +
          +
          +int 
          +Dddmp_cuddHeaderLoad(
          +  Dddmp_DecompType * ddType, OUT: selects the proper decomp type
          +  int * nVars, OUT: number of DD variables
          +  int * nsuppvars, OUT: number of support variables
          +  char *** suppVarNames, OUT: array of support variable names
          +  char *** orderedVarNames, OUT: array of variable names
          +  int ** varIds, OUT: array of variable ids
          +  int ** varComposeIds, OUT: array of permids ids
          +  int ** varAuxIds, OUT: array of variable aux ids
          +  int * nRoots, OUT: number of root in the file
          +  char * file, IN: file name
          +  FILE * fp IN: file pointer
          +)
          +
          +
          Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. +

          + +

          See Also Dddmp_cuddBddArrayLoad + + +
          Defined in dddmpLoad.c + +
          +
          +int 
          +FindVarname(
          +  char * name, IN: name to look for
          +  char ** array, IN: search array
          +  int  n IN: size of the array
          +)
          +
          +
          Binary search of a name within a sorted array of strings. + Used when matching names of variables. +

          + +

          Side Effects None +

          + +

          Defined in dddmpUtil.c + +
          +
          +static int 
          +NodeBinaryStoreBdd(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f, IN: DD node to be stored
          +  int  mode, IN: store mode
          +  int * supportids, IN: internal ids for variables
          +  char ** varnames, IN: names of variables: to be stored with nodes
          +  int * outids, IN: output ids for variables
          +  FILE * fp, IN: store file
          +  int  idf, IN: index of the node
          +  int  vf, IN: variable of the node
          +  int  idT, IN: index of the Then node
          +  int  idE, IN: index of the Else node
          +  int  vT, IN: variable of the Then node
          +  int  vE, IN: variable of the Else node
          +  DdNode * T, IN: Then node
          +  DdNode * E IN: Else node
          +)
          +
          +
          Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. + Store every information as coded binary values. +

          + +

          Side Effects None +

          + +

          See Also NodeTextStoreBdd + + +
          Defined in dddmpStoreBdd.c + +
          +
          +static int 
          +NodeStoreRecurAdd(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f, IN: DD node to be stored
          +  int  mode, IN: store mode
          +  int * supportids, IN: internal ids for variables
          +  char ** varnames, IN: names of variables: to be stored with nodes
          +  int * outids, IN: output ids for variables
          +  FILE * fp IN: store file
          +)
          +
          +
          Stores a node to file in either test or binary mode. + In text mode a node is represented (on a text line basis) as +
            +
          • node-index [var-extrainfo] var-index Then-index Else-index +
          + + where all indexes are integer numbers and var-extrainfo + (optional redundant field) is either an integer or a string + (variable name). Node-index is redundant (due to the node + ordering) but we keep it for readability.

          + + In binary mode nodes are represented as a sequence of bytes, + representing var-index, Then-index, and Else-index in an + optimized way. Only the first byte (code) is mandatory. + Integer indexes are represented in absolute or relative mode, + where relative means offset wrt. a Then/Else node info. + Suppose Var(NodeId), Then(NodeId) and Else(NodeId) represent + infos about a given node.

          + + The generic "NodeId" node is stored as + +

            +
          • code-byte +
          • [var-info] +
          • [Then-info] +
          • [Else-info] +
          + + where code-byte contains bit fields + +
            +
          • Unused : 1 bit +
          • Variable: 2 bits, one of the following codes +
              +
            • DDDMP_ABSOLUTE_ID var-info = Var(NodeId) follows +
            • DDDMP_RELATIVE_ID Var(NodeId) is represented in relative form as + var-info = Min(Var(Then(NodeId)),Var(Else(NodeId))) -Var(NodeId) +
            • DDDMP_RELATIVE_1 No var-info follows, because + Var(NodeId) = Min(Var(Then(NodeId)),Var(Else(NodeId)))-1 +
            • DDDMP_TERMINAL Node is a terminal, no var info required +
            +
          • T : 2 bits, with codes similar to V +
              +
            • DDDMP_ABSOLUTE_ID Then-info = Then(NodeId) follows +
            • DDDMP_RELATIVE_ID Then(NodeId) is represented in relative form as + Then-info = Nodeid-Then(NodeId) +
            • DDDMP_RELATIVE_1 No info on Then(NodeId) follows, because + Then(NodeId) = NodeId-1 +
            • DDDMP_TERMINAL Then Node is a terminal, no info required (for BDDs) +
            +
          • Ecompl : 1 bit, if 1 means complemented edge +
          • E : 2 bits, with codes and meanings as for the Then edge +
          + var-info, Then-info, Else-info (if required) are represented as unsigned + integer values on a sufficient set of bytes (MSByte first). +

          + +

          Side Effects None +

          + +

          Defined in dddmpStoreAdd.c + +
          +
          +static int 
          +NodeStoreRecurBdd(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f, IN: DD node to be stored
          +  int  mode, IN: store mode
          +  int * supportids, IN: internal ids for variables
          +  char ** varnames, IN: names of variables: to be stored with nodes
          +  int * outids, IN: output ids for variables
          +  FILE * fp IN: store file
          +)
          +
          +
          Stores a node to file in either test or binary mode. + In text mode a node is represented (on a text line basis) as +
            +
          • node-index [var-extrainfo] var-index Then-index Else-index +
          + + where all indexes are integer numbers and var-extrainfo + (optional redundant field) is either an integer or a string + (variable name). Node-index is redundant (due to the node + ordering) but we keep it for readability.

          + + In binary mode nodes are represented as a sequence of bytes, + representing var-index, Then-index, and Else-index in an + optimized way. Only the first byte (code) is mandatory. + Integer indexes are represented in absolute or relative mode, + where relative means offset wrt. a Then/Else node info. + Suppose Var(NodeId), Then(NodeId) and Else(NodeId) represent + infos about a given node.

          + + The generic "NodeId" node is stored as + +

            +
          • code-byte +
          • [var-info] +
          • [Then-info] +
          • [Else-info] +
          + + where code-byte contains bit fields + +
            +
          • Unused : 1 bit +
          • Variable: 2 bits, one of the following codes +
              +
            • DDDMP_ABSOLUTE_ID var-info = Var(NodeId) follows +
            • DDDMP_RELATIVE_ID Var(NodeId) is represented in relative form as + var-info = Min(Var(Then(NodeId)),Var(Else(NodeId))) -Var(NodeId) +
            • DDDMP_RELATIVE_1 No var-info follows, because + Var(NodeId) = Min(Var(Then(NodeId)),Var(Else(NodeId)))-1 +
            • DDDMP_TERMINAL Node is a terminal, no var info required +
            +
          • T : 2 bits, with codes similar to V +
              +
            • DDDMP_ABSOLUTE_ID Then-info = Then(NodeId) follows +
            • DDDMP_RELATIVE_ID Then(NodeId) is represented in relative form as + Then-info = Nodeid-Then(NodeId) +
            • DDDMP_RELATIVE_1 No info on Then(NodeId) follows, because + Then(NodeId) = NodeId-1 +
            • DDDMP_TERMINAL Then Node is a terminal, no info required (for BDDs) +
            +
          • Ecompl : 1 bit, if 1 means complemented edge +
          • E : 2 bits, with codes and meanings as for the Then edge +
          + var-info, Then-info, Else-info (if required) are represented as unsigned + integer values on a sufficient set of bytes (MSByte first). +

          + +

          Side Effects None +

          + +

          Defined in dddmpStoreBdd.c + +
          +
          +static int 
          +NodeTextStoreAdd(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f, IN: DD node to be stored
          +  int  mode, IN: store mode
          +  int * supportids, IN: internal ids for variables
          +  char ** varnames, IN: names of variables: to be stored with nodes
          +  int * outids, IN: output ids for variables
          +  FILE * fp, IN: Store file
          +  int  idf, IN: index of the current node
          +  int  vf, IN: variable of the current node
          +  int  idT, IN: index of the Then node
          +  int  idE IN: index of the Else node
          +)
          +
          +
          Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. +

          + +

          Side Effects None +

          + +

          See Also NodeBinaryStore + + +
          Defined in dddmpStoreAdd.c + +
          +
          +static int 
          +NodeTextStoreBdd(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f, IN: DD node to be stored
          +  int  mode, IN: store mode
          +  int * supportids, IN: internal ids for variables
          +  char ** varnames, IN: names of variables: to be stored with nodes
          +  int * outids, IN: output ids for variables
          +  FILE * fp, IN: Store file
          +  int  idf, IN: index of the current node
          +  int  vf, IN: variable of the current node
          +  int  idT, IN: index of the Then node
          +  int  idE IN: index of the Else node
          +)
          +
          +
          Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. +

          + +

          Side Effects None +

          + +

          See Also NodeBinaryStoreBdd + + +
          Defined in dddmpStoreBdd.c + +
          +
          +static int 
          +NumberNodeRecurAdd(
          +  DdNode * f, IN: root of the BDD to be numbered
          +  int  id IN/OUT: index to be assigned to the node
          +)
          +
          +
          Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

          + +

          Side Effects "visited" flags are reset. +

          + +

          Defined in dddmpNodeAdd.c + +
          +
          +static int 
          +NumberNodeRecurBdd(
          +  DdNode * f, IN: root of the BDD to be numbered
          +  int  id IN/OUT: index to be assigned to the node
          +)
          +
          +
          Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

          + +

          Side Effects "visited" flags are reset. +

          + +

          Defined in dddmpNodeBdd.c + +
          +
          +static int 
          +NumberNodeRecurCnf(
          +  DdNode * f, IN: root of the BDD to be numbered
          +  int * cnfIds, IN: possible source for numbering
          +  int  id IN/OUT: possible source for numbering
          +)
          +
          +
          Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

          + +

          Side Effects "visited" flags are reset. +

          + +

          Defined in dddmpDdNodeCnf.c + +
          +
          +static int 
          +NumberNodeRecurCnf(
          +  DdNode * f, IN: root of the BDD to be numbered
          +  int * cnfIds, IN: possible source for numbering
          +  int  id IN/OUT: possible source for numbering
          +)
          +
          +
          Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

          + +

          Side Effects "visited" flags are reset. +

          + +

          Defined in dddmpNodeCnf.c + +
          +
          +static int 
          +NumberNodeRecur(
          +  DdNode * f, IN: root of the BDD to be numbered
          +  int  id IN/OUT: index to be assigned to the node
          +)
          +
          +
          Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

          + +

          Side Effects "visited" flags are reset. +

          + +

          Defined in dddmpDdNodeBdd.c + +
          +
          +int 
          +QsortStrcmp(
          +  const void * ps1, IN: pointer to the first string
          +  const void * ps2 IN: pointer to the second string
          +)
          +
          +
          String compare for qsort +

          + +

          Side Effects None +

          + +

          Defined in dddmpUtil.c + +
          +
          +static int 
          +ReadByteBinary(
          +  FILE * fp, IN: file where to read the byte
          +  unsigned char * cp OUT: the read byte
          +)
          +
          +
          inputs a byte to file fp. 0x00 has been used as escape character + to filter , and . This is done for + compatibility between unix and dos/windows systems. +

          + +

          Side Effects None +

          + +

          See Also WriteByteBinary() + + +
          Defined in dddmpBinary.c + +
          +
          +static void 
          +RemoveFromUniqueRecurAdd(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f IN: root of the BDD to be extracted
          +)
          +
          +
          Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. Constants remain untouched. +

          + +

          Side Effects Nodes are left with the "visited" flag true. +

          + +

          See Also RestoreInUniqueRecurAdd +() + + +
          Defined in dddmpNodeAdd.c + +
          +
          +static void 
          +RemoveFromUniqueRecurBdd(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f IN: root of the BDD to be extracted
          +)
          +
          +
          Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. Constants remain untouched. +

          + +

          Side Effects Nodes are left with the "visited" flag true. +

          + +

          See Also RestoreInUniqueRecurBdd +() + + +
          Defined in dddmpNodeBdd.c + +
          +
          +static void 
          +RemoveFromUniqueRecurCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f IN: root of the BDD to be extracted
          +)
          +
          +
          Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on on the + children of the node. Constants remain untouched. +

          + +

          Side Effects Nodes are left with the "visited" flag true. +

          + +

          See Also RestoreInUniqueRecurCnf() + + +
          Defined in dddmpNodeCnf.c + +
          +
          +static void 
          +RemoveFromUniqueRecurCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f IN: root of the BDD to be extracted
          +)
          +
          +
          Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on son nodes. +

          + +

          Side Effects Nodes are left with the "visited" flag true. +

          + +

          See Also RestoreInUniqueRecurCnf() + + +
          Defined in dddmpDdNodeCnf.c + +
          +
          +static void 
          +RemoveFromUniqueRecur(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f IN: root of the BDD to be extracted
          +)
          +
          +
          Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. +

          + +

          Side Effects Nodes are left with the "visited" flag true. +

          + +

          See Also RestoreInUniqueRecur() + + +
          Defined in dddmpDdNodeBdd.c + +
          +
          +static void 
          +RestoreInUniqueRecurAdd(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f IN: root of the BDD to be restored
          +)
          +
          +
          Restores a node in unique table (recursively) +

          + +

          Side Effects Nodes are not restored in the same order as before removal +

          + +

          See Also RemoveFromUniqueAdd +() + + +
          Defined in dddmpNodeAdd.c + +
          +
          +static void 
          +RestoreInUniqueRecurBdd(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f IN: root of the BDD to be restored
          +)
          +
          +
          Restores a node in unique table (recursively) +

          + +

          Side Effects Nodes are not restored in the same order as before removal +

          + +

          See Also RemoveFromUnique() + + +
          Defined in dddmpNodeBdd.c + +
          +
          +static void 
          +RestoreInUniqueRecurCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f IN: root of the BDD to be restored
          +)
          +
          +
          Restores a node in unique table (recursive) +

          + +

          Side Effects Nodes are not restored in the same order as before removal +

          + +

          See Also RemoveFromUnique() + + +
          Defined in dddmpDdNodeCnf.c + +
          +
          +static void 
          +RestoreInUniqueRecurCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f IN: root of the BDD to be restored
          +)
          +
          +
          Restores a node in unique table (recursive) +

          + +

          Side Effects Nodes are not restored in the same order as before removal +

          + +

          See Also RemoveFromUnique() + + +
          Defined in dddmpNodeCnf.c + +
          +
          +static void 
          +RestoreInUniqueRecur(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f IN: root of the BDD to be restored
          +)
          +
          +
          Restores a node in unique table (recursively) +

          + +

          Side Effects Nodes are not restored in the same order as before removal +

          + +

          See Also RemoveFromUnique() + + +
          Defined in dddmpDdNodeBdd.c + +
          +
          +static int 
          +StoreCnfBestNotSharedRecur(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * node, IN: BDD to store
          +  int  idf, IN: Id to store
          +  int * bddIds, IN: BDD identifiers
          +  int * cnfIds, IN: corresponding CNF identifiers
          +  FILE * fp, IN: file pointer
          +  int * list, IN: temporary array to store cubes
          +  int * clauseN, OUT: number of stored clauses
          +  int * varMax OUT: maximum identifier of the variables created
          +)
          +
          +
          Performs the recursive step of Print Best on Not Shared + sub-BDDs, i.e., print out information for the nodes belonging to + BDDs not shared (whose root has just one incoming edge). +

          + +

          Side Effects None +

          + +

          Defined in dddmpStoreCnf.c + +
          +
          +static int 
          +StoreCnfBestSharedRecur(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * node, IN: BDD to store
          +  int * bddIds, IN: BDD identifiers
          +  int * cnfIds, IN: corresponding CNF identifiers
          +  FILE * fp, IN: file pointer
          +  int * list, IN: temporary array to store cubes
          +  int * clauseN, OUT: number of stored clauses
          +  int * varMax OUT: maximum identifier of the variables created
          +)
          +
          +
          Performs the recursive step of Print Best on Not Shared + sub-BDDs, i.e., print out information for the nodes belonging to + BDDs not shared (whose root has just one incoming edge). +

          + +

          Side Effects None +

          + +

          Defined in dddmpStoreCnf.c + +
          +
          +static int 
          +StoreCnfBest(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDDs to store
          +  int  rootN, IN: number of BDD in the array
          +  int * bddIds, IN: BDD identifiers
          +  int * cnfIds, IN: corresponding CNF identifiers
          +  int  idInitial, IN: initial value for numbering new CNF variables
          +  FILE * fp, IN: file pointer
          +  int * varMax, OUT: maximum identifier of the variables created
          +  int * clauseN, OUT: number of stored clauses
          +  int * rootStartLine OUT: line where root starts
          +)
          +
          +
          Prints a disjoint sum of product cover for the function + rooted at node intorducing cutting points whenever necessary. + Each product corresponds to a path from node a leaf + node different from the logical zero, and different from the + background value. Uses the standard output. Returns 1 if + successful, 0 otherwise. +

          + +

          Side Effects None +

          + +

          See Also StoreCnfMaxtermByMaxterm + + +
          Defined in dddmpStoreCnf.c + +
          +
          +static void 
          +StoreCnfMaxtermByMaxtermRecur(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * node, IN: BDD to store
          +  int * bddIds, IN: BDD identifiers
          +  int * cnfIds, IN: corresponding CNF identifiers
          +  FILE * fp, IN: file pointer
          +  int * list, IN: temporary array to store cubes
          +  int * clauseN, OUT: number of stored clauses
          +  int * varMax OUT: maximum identifier of the variables created
          +)
          +
          +
          Performs the recursive step of Print Maxterm. + Traverse a BDD a print out a cube in CNF format each time a terminal + node is reached. +

          + +

          Side Effects None +

          + +

          Defined in dddmpStoreCnf.c + +
          +
          +static int 
          +StoreCnfMaxtermByMaxterm(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDDs to store
          +  int  rootN, IN: number of BDDs in the array
          +  int * bddIds, IN: BDD Identifiers
          +  int * cnfIds, IN: corresponding CNF Identifiers
          +  int  idInitial, IN: initial value for numbering new CNF variables
          +  FILE * fp, IN: file pointer
          +  int * varMax, OUT: maximum identifier of the variables created
          +  int * clauseN, OUT: number of stored clauses
          +  int * rootStartLine OUT: line where root starts
          +)
          +
          +
          Prints a disjoint sum of product cover for the function + rooted at node. Each product corresponds to a path from node a + leaf node different from the logical zero, and different from + the background value. Uses the standard output. Returns 1 if + successful, 0 otherwise. +

          + +

          Side Effects None +

          + +

          See Also StoreCnfBest + + +
          Defined in dddmpStoreCnf.c + +
          +
          +static int 
          +StoreCnfNodeByNodeRecur(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f, IN: BDD node to be stored
          +  int * bddIds, IN: BDD ids for variables
          +  int * cnfIds, IN: CNF ids for variables
          +  FILE * fp, IN: store file
          +  int * clauseN, OUT: number of clauses written in the CNF file
          +  int * varMax OUT: maximum value of id written in the CNF file
          +)
          +
          +
          Performs the recursive step of Dddmp_bddStore. + Traverse the BDD and store a CNF formula for each "terminal" node. +

          + +

          Side Effects None +

          + +

          Defined in dddmpStoreCnf.c + +
          +
          +static int 
          +StoreCnfNodeByNode(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: BDD array to be stored
          +  int  rootN, IN: number of BDDs in the array
          +  int * bddIds, IN: BDD ids for variables
          +  int * cnfIds, IN: CNF ids for variables
          +  FILE * fp, IN: store file
          +  int * clauseN, IN/OUT: number of clauses written in the CNF file
          +  int * varMax, IN/OUT: maximum value of id written in the CNF file
          +  int * rootStartLine OUT: CNF line where root starts
          +)
          +
          +
          Store the BDD as CNF clauses. + Use a multiplexer description for each BDD node. +

          + +

          Side Effects None +

          + +

          Defined in dddmpStoreCnf.c + +
          +
          +static int 
          +StoreCnfOneNode(
          +  DdNode * f, IN: node to be stored
          +  int  idf, IN: node CNF Index
          +  int  vf, IN: node BDD Index
          +  int  idT, IN: Then CNF Index with sign = inverted edge
          +  int  idE, IN: Else CNF Index with sign = inverted edge
          +  FILE * fp, IN: store file
          +  int * clauseN, OUT: number of clauses
          +  int * varMax OUT: maximun Index of variable stored
          +)
          +
          +
          Store One Single BDD Node translating it as a multiplexer. +

          + +

          Side Effects None +

          + +

          Defined in dddmpStoreCnf.c + +
          +
          +static int 
          +WriteByteBinary(
          +  FILE * fp, IN: file where to write the byte
          +  unsigned char  c IN: the byte to be written
          +)
          +
          +
          outputs a byte to file fp. Uses 0x00 as escape character + to filter , and . + This is done for compatibility between unix and dos/windows systems. +

          + +

          Side Effects None +

          + +

          See Also ReadByteBinary() + + +
          Defined in dddmpBinary.c + +
          +
          +static int 
          +printCubeCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * node, IN: BDD to store
          +  int * cnfIds, IN: CNF identifiers
          +  FILE * fp, IN: file pointer
          +  int * list, IN: temporary array to store cubes
          +  int * varMax OUT: maximum identifier of the variables created
          +)
          +
          +
          Print One Cube in CNF Format. + Return DDDMP_SUCCESS if something is printed out, DDDMP_FAILURE + is nothing is printed out. +

          + +

          Side Effects None +

          + +

          Defined in dddmpStoreCnf.c + +
          +
          + 
          +(
          +    
          +)
          +
          +
          Checks for Warnings: If expr==1 it prints out the warning + on stderr. +

          + +

          Side Effects None +

          + +

          Defined in dddmp.h + +
          +
          + 
          +(
          +    
          +)
          +
          +
          Checks for fatal bugs and go to the label to deal with + the error. +

          + +

          Side Effects None +

          + +

          Defined in dddmp.h + +
          +
          + 
          +(
          +    
          +)
          +
          +
          Checks for fatal bugs and return the DDDMP_FAILURE flag. +

          + +

          Side Effects None +

          + +

          Defined in dddmp.h + +
          +
          + 
          +(
          +    
          +)
          +
          +
          Conditional safety assertion. It prints out the file + name and line number where the fatal error occurred. + Messages are printed out on stderr. +

          + +

          Side Effects None +

          + +

          Defined in dddmp.h + +
          +
          + 
          +(
          +    
          +)
          +
          +
          Memory Allocation Macro for DDDMP +

          + +

          Side Effects None +

          + +

          Defined in dddmpInt.h + +
          +
          + 
          +(
          +    
          +)
          +
          +
          Memory Free Macro for DDDMP +

          + +

          Side Effects None +

          + +

          Defined in dddmpInt.h + + +
          +
          +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllFile.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllFile.html new file mode 100644 index 000000000..2664d07f4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllFile.html @@ -0,0 +1,679 @@ + +The dddmp package: files + + +
          +
          dddmp.h +
          External header file +
          dddmpInt.h +
          Internal header file +
          dddmpBinary.c +
          Input and output BDD codes and integers from/to file +
          dddmpConvert.c +
          Conversion between ASCII and binary formats +
          dddmpDbg.c +
          Functions to display BDD files +
          dddmpDdNodeBdd.c +
          Functions to handle BDD node infos and numbering +
          dddmpDdNodeCnf.c +
          Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs +
          dddmpLoad.c +
          Functions to read in bdds to file +
          dddmpLoadCnf.c +
          Functions to read in CNF from file as BDDs. +
          dddmpNodeAdd.c +
          Functions to handle ADD node infos and numbering +
          dddmpNodeBdd.c +
          Functions to handle BDD node infos and numbering +
          dddmpNodeCnf.c +
          Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs +
          dddmpStoreAdd.c +
          Functions to write ADDs to file. +
          dddmpStoreBdd.c +
          Functions to write BDDs to file. +
          dddmpStoreCnf.c +
          Functions to write out BDDs to file in a CNF format +
          dddmpStoreMisc.c +
          Functions to write out bdds to file in prefixed + and in Blif form. +
          dddmpUtil.c +
          Util Functions for the dddmp package +

          +

          dddmp.h

          +External header file

          +By: Gianpiero Cabodi and Stefano Quer

          +

          +
          () +
          Checks for fatal bugs + +
          () +
          Checks for Warnings: If expr==1 it prints out the warning + on stderr. + +
          () +
          Checks for fatal bugs and return the DDDMP_FAILURE flag. + +
          () +
          Checks for fatal bugs and go to the label to deal with + the error. + +
          +
          +

          dddmpInt.h

          +Internal header file

          +By: Gianpiero Cabodi and Stefano Quer

          +

          +
          () +
          Memory Allocation Macro for DDDMP + +
          () +
          Memory Free Macro for DDDMP + +
          +
          +

          dddmpBinary.c

          +Input and output BDD codes and integers from/to file

          +By: Gianpiero Cabodi and Stefano Quer

          +Input and output BDD codes and integers from/to file + in binary mode. + DD node codes are written as one byte. + Integers of any length are written as sequences of "linked" bytes. + For each byte 7 bits are used for data and one (MSBit) as link with + a further byte (MSB = 1 means one more byte). + Low level read/write of bytes filter , and + with escape sequences.

          +

          +
          DddmpWriteCode() +
          Writes 1 byte node code + +
          DddmpReadCode() +
          Reads a 1 byte node code + +
          DddmpWriteInt() +
          Writes a "packed integer" + +
          DddmpReadInt() +
          Reads a "packed integer" + +
          WriteByteBinary() +
          Writes a byte to file filtering , and + +
          ReadByteBinary() +
          Reads a byte from file with escaped , and + +
          +
          +

          dddmpConvert.c

          +Conversion between ASCII and binary formats

          +By: Gianpiero Cabodi and Stefano Quer

          +Conversion between ASCII and binary formats is presently + supported by loading a BDD in the source format and storing it + in the target one. We plan to introduce ad hoc procedures + avoiding explicit BDD node generation.

          +

          +
          Dddmp_Text2Bin() +
          Converts from ASCII to binary format + +
          Dddmp_Bin2Text() +
          Converts from binary to ASCII format + +
          +
          +

          dddmpDbg.c

          +Functions to display BDD files

          +By: Gianpiero Cabodi and Stefano Quer

          +Functions to display BDD files in binary format

          +

          +
          Dddmp_cuddBddDisplayBinary() +
          Display a binary dump file in a text file + +
          +
          +

          dddmpDdNodeBdd.c

          +Functions to handle BDD node infos and numbering

          +By: Gianpiero Cabodi and Stefano Quer

          +Functions to handle BDD node infos and numbering.

          +

          +
          DddmpNumberDdNodes() +
          Removes nodes from unique table and number them + +
          DddmpUnnumberDdNodes() +
          Restores nodes in unique table, loosing numbering + +
          DddmpWriteNodeIndex() +
          Write index to node + +
          DddmpReadNodeIndex() +
          Reads the index of a node + +
          DddmpVisited() +
          Returns true if node is visited + +
          DddmpSetVisited() +
          Marks a node as visited + +
          DddmpClearVisited() +
          Marks a node as not visited + +
          NumberNodeRecur() +
          Number nodes recursively in post-order + +
          RemoveFromUniqueRecur() +
          Removes a node from unique table + +
          RestoreInUniqueRecur() +
          Restores a node in unique table + +
          +
          +

          dddmpDdNodeCnf.c

          +Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs

          +By: Gianpiero Cabodi and Stefano Quer

          +Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs.

          +

          +
          DddmpNumberDdNodesCnf() +
          Removes nodes from unique table and numbers them + +
          DddmpDdNodesCountEdgesAndNumber() +
          Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. + +
          DddmpUnnumberDdNodesCnf() +
          Restores nodes in unique table, loosing numbering + +
          DddmpPrintBddAndNext() +
          Prints debug information + +
          DddmpWriteNodeIndexCnfBis() +
          Write index to node + +
          DddmpWriteNodeIndexCnf() +
          Write index to node + +
          DddmpReadNodeIndexCnf() +
          Reads the index of a node + +
          DddmpClearVisitedCnfRecur() +
          Mark ALL nodes as not visited + +
          DddmpVisitedCnf() +
          Returns true if node is visited + +
          DddmpSetVisitedCnf() +
          Marks a node as visited + +
          DddmpClearVisitedCnf() +
          Marks a node as not visited + +
          NumberNodeRecurCnf() +
          Number nodes recursively in post-order + +
          DddmpDdNodesCheckIncomingAndScanPath() +
          Number nodes recursively in post-order + +
          DddmpDdNodesNumberEdgesRecur() +
          Number nodes recursively in post-order + +
          DddmpDdNodesResetCountRecur() +
          Resets counter and visited flag for ALL nodes of a BDD + +
          DddmpDdNodesCountEdgesRecur() +
          Counts the number of incoming edges for each node of a BDD + +
          RemoveFromUniqueRecurCnf() +
          Removes a node from unique table + +
          RestoreInUniqueRecurCnf() +
          Restores a node in unique table + +
          DddmpPrintBddAndNextRecur() +
          Prints debug info + +
          +
          +

          dddmpLoad.c

          +Functions to read in bdds to file

          +By: Gianpiero Cabodi and Stefano Quer

          +Functions to read in bdds to file. BDDs + are represended on file either in text or binary format under the + following rules. A file contains a forest of BDDs (a vector of + Boolean functions). BDD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to BDD + functions, followed by the list of nodes. BDD nodes are listed + according to their numbering, and in the present implementation + numbering follows a post-order strategy, in such a way that a node + is never listed before its Then/Else children.

          +

          +
          Dddmp_cuddBddLoad() +
          Reads a dump file representing the argument BDD. + +
          Dddmp_cuddBddArrayLoad() +
          Reads a dump file representing the argument BDDs. + +
          Dddmp_cuddAddLoad() +
          Reads a dump file representing the argument ADD. + +
          Dddmp_cuddAddArrayLoad() +
          Reads a dump file representing the argument ADDs. + +
          Dddmp_cuddHeaderLoad() +
          Reads the header of a dump file representing the argument BDDs + +
          DddmpCuddDdArrayLoad() +
          Reads a dump file representing the argument BDDs. + +
          DddmpBddReadHeader() +
          Reads a the header of a dump file representing the + argument BDDs. + +
          DddmpFreeHeader() +
          Frees the internal header structure. + +
          +
          +

          dddmpLoadCnf.c

          +Functions to read in CNF from file as BDDs.

          +By: Gianpiero Cabodi and Stefano Quer

          +Functions to read in CNF from file as BDDs.

          +

          +
          Dddmp_cuddBddLoadCnf() +
          Reads a dump file in a CNF format. + +
          Dddmp_cuddBddArrayLoadCnf() +
          Reads a dump file in a CNF format. + +
          Dddmp_cuddHeaderLoadCnf() +
          Reads the header of a dump file representing the argument BDDs + +
          DddmpCuddDdArrayLoadCnf() +
          Reads a dump file representing the argument BDDs in CNF + format. + +
          DddmpBddReadHeaderCnf() +
          Reads a the header of a dump file representing the argument + BDDs. + +
          DddmpFreeHeaderCnf() +
          Frees the internal header structure. + +
          DddmpReadCnfClauses() +
          Read the CNF clauses from the file in the standard DIMACS + format. + +
          DddmpCnfClauses2Bdd() +
          Transforms CNF clauses into BDDs. + +
          +
          +

          dddmpNodeAdd.c

          +Functions to handle ADD node infos and numbering

          +By: Gianpiero Cabodi and Stefano Quer

          +Functions to handle ADD node infos and numbering.

          +

          +
          DddmpNumberAddNodes() +
          Removes nodes from unique table and number them + +
          DddmpUnnumberAddNodes() +
          Restores nodes in unique table, loosing numbering + +
          DddmpWriteNodeIndexAdd() +
          Write index to node + +
          DddmpReadNodeIndexAdd() +
          Reads the index of a node + +
          DddmpVisitedAdd() +
          Returns true if node is visited + +
          DddmpSetVisitedAdd() +
          Marks a node as visited + +
          DddmpClearVisitedAdd() +
          Marks a node as not visited + +
          NumberNodeRecurAdd() +
          Number nodes recursively in post-order + +
          RemoveFromUniqueRecurAdd() +
          Removes a node from unique table + +
          RestoreInUniqueRecurAdd() +
          Restores a node in unique table + +
          +
          +

          dddmpNodeBdd.c

          +Functions to handle BDD node infos and numbering

          +By: Gianpiero Cabodi and Stefano Quer

          +Functions to handle BDD node infos and numbering.

          +

          +
          DddmpNumberBddNodes() +
          Removes nodes from unique table and number them + +
          DddmpUnnumberBddNodes() +
          Restores nodes in unique table, loosing numbering + +
          DddmpWriteNodeIndexBdd() +
          Write index to node + +
          DddmpReadNodeIndexBdd() +
          Reads the index of a node + +
          DddmpVisitedBdd() +
          Returns true if node is visited + +
          DddmpSetVisitedBdd() +
          Marks a node as visited + +
          DddmpClearVisitedBdd() +
          Marks a node as not visited + +
          NumberNodeRecurBdd() +
          Number nodes recursively in post-order + +
          RemoveFromUniqueRecurBdd() +
          Removes a node from unique table + +
          RestoreInUniqueRecurBdd() +
          Restores a node in unique table + +
          +
          +

          dddmpNodeCnf.c

          +Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs

          +By: Gianpiero Cabodi and Stefano Quer

          +Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs.

          +

          +
          DddmpNumberDdNodesCnf() +
          Removes nodes from unique table and numbers them + +
          DddmpDdNodesCountEdgesAndNumber() +
          Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. + +
          DddmpUnnumberDdNodesCnf() +
          Restores nodes in unique table, loosing numbering + +
          DddmpPrintBddAndNext() +
          Prints debug information + +
          DddmpWriteNodeIndexCnf() +
          Write index to node + +
          DddmpVisitedCnf() +
          Returns true if node is visited + +
          DddmpSetVisitedCnf() +
          Marks a node as visited + +
          DddmpReadNodeIndexCnf() +
          Reads the index of a node + +
          DddmpWriteNodeIndexCnfWithTerminalCheck() +
          Write index to node + +
          DddmpClearVisitedCnfRecur() +
          Mark ALL nodes as not visited + +
          DddmpClearVisitedCnf() +
          Marks a node as not visited + +
          NumberNodeRecurCnf() +
          Number nodes recursively in post-order + +
          DddmpDdNodesCheckIncomingAndScanPath() +
          Number nodes recursively in post-order + +
          DddmpDdNodesNumberEdgesRecur() +
          Number nodes recursively in post-order + +
          DddmpDdNodesResetCountRecur() +
          Resets counter and visited flag for ALL nodes of a BDD + +
          DddmpDdNodesCountEdgesRecur() +
          Counts the number of incoming edges for each node of a BDD + +
          RemoveFromUniqueRecurCnf() +
          Removes a node from unique table + +
          RestoreInUniqueRecurCnf() +
          Restores a node in unique table + +
          DddmpPrintBddAndNextRecur() +
          Prints debug info + +
          +
          +

          dddmpStoreAdd.c

          +Functions to write ADDs to file.

          +By: Gianpiero Cabodi and Stefano Quer

          +Functions to write ADDs to file. + ADDs are represended on file either in text or binary format under the + following rules. A file contains a forest of ADDs (a vector of + Boolean functions). ADD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to ADD + functions, followed by the list of nodes. + ADD nodes are listed according to their numbering, and in the present + implementation numbering follows a post-order strategy, in such a way + that a node is never listed before its Then/Else children.

          +

          +
          Dddmp_cuddAddStore() +
          Writes a dump file representing the argument ADD. + +
          Dddmp_cuddAddArrayStore() +
          Writes a dump file representing the argument Array of ADDs. + +
          DddmpCuddDdArrayStoreBdd() +
          Writes a dump file representing the argument Array of + BDDs/ADDs. + +
          NodeStoreRecurAdd() +
          Performs the recursive step of Dddmp_bddStore. + +
          NodeTextStoreAdd() +
          Store One Single Node in Text Format. + +
          +
          +

          dddmpStoreBdd.c

          +Functions to write BDDs to file.

          +By: Gianpiero Cabodi and Stefano Quer

          +Functions to write BDDs to file. + BDDs are represended on file either in text or binary format under the + following rules. A file contains a forest of BDDs (a vector of + Boolean functions). BDD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to BDD + functions, followed by the list of nodes. BDD nodes are listed + according to their numbering, and in the present implementation + numbering follows a post-order strategy, in such a way that a node + is never listed before its Then/Else children.

          +

          +
          Dddmp_cuddBddStore() +
          Writes a dump file representing the argument BDD. + +
          Dddmp_cuddBddArrayStore() +
          Writes a dump file representing the argument Array of BDDs. + +
          DddmpCuddBddArrayStore() +
          Writes a dump file representing the argument Array of + BDDs. + +
          NodeStoreRecurBdd() +
          Performs the recursive step of Dddmp_bddStore. + +
          NodeTextStoreBdd() +
          Store One Single Node in Text Format. + +
          NodeBinaryStoreBdd() +
          Store One Single Node in Binary Format. + +
          +
          +

          dddmpStoreCnf.c

          +Functions to write out BDDs to file in a CNF format

          +By: Gianpiero Cabodi and Stefano Quer

          +Functions to write out BDDs to file in a CNF format.

          +

          +
          Dddmp_cuddBddStoreCnf() +
          Writes a dump file representing the argument BDD in + a CNF format. + +
          Dddmp_cuddBddArrayStoreCnf() +
          Writes a dump file representing the argument array of BDDs + in CNF format. + +
          DddmpCuddBddArrayStoreCnf() +
          Writes a dump file representing the argument Array of + BDDs in the CNF standard format. + +
          StoreCnfNodeByNode() +
          Store the BDD as CNF clauses. + +
          StoreCnfNodeByNodeRecur() +
          Performs the recursive step of Dddmp_bddStore. + +
          StoreCnfOneNode() +
          Store One Single BDD Node. + +
          StoreCnfMaxtermByMaxterm() +
          Prints a disjoint sum of products. + +
          StoreCnfBest() +
          Prints a disjoint sum of products with intermediate + cutting points. + +
          StoreCnfMaxtermByMaxtermRecur() +
          Performs the recursive step of Print Maxterm. + +
          StoreCnfBestNotSharedRecur() +
          Performs the recursive step of Print Best on Not Shared + sub-BDDs. + +
          StoreCnfBestSharedRecur() +
          Performs the recursive step of Print Best on Shared + sub-BDDs. + +
          printCubeCnf() +
          Print One Cube in CNF Format. + +
          +
          +

          dddmpStoreMisc.c

          +Functions to write out bdds to file in prefixed + and in Blif form.

          +By: Gianpiero Cabodi and Stefano Quer

          +Functions to write out bdds to file. + BDDs are represended on file in text format. + Each node is stored as a multiplexer in a prefix notation format for + the prefix notation file or in PLA format for the blif file.

          +

          +
          Dddmp_cuddBddStorePrefix() +
          Writes a dump file representing the argument BDD in + a prefix notation. + +
          Dddmp_cuddBddArrayStorePrefix() +
          Writes a dump file representing the argument BDD in + a prefix notation. + +
          Dddmp_cuddBddStoreBlif() +
          Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
          Dddmp_cuddBddArrayStoreBlif() +
          Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
          Dddmp_cuddBddStoreSmv() +
          Writes a dump file representing the argument BDD in + a prefix notation. + +
          Dddmp_cuddBddArrayStoreSmv() +
          Writes a dump file representing the argument BDD in + a prefix notation. + +
          DddmpCuddDdArrayStorePrefix() +
          Internal function to writes a dump file representing the + argument BDD in a prefix notation. + +
          DddmpCuddDdArrayStorePrefixBody() +
          Internal function to writes a dump file representing the + argument BDD in a prefix notation. Writes the body of the file. + +
          DddmpCuddDdArrayStorePrefixStep() +
          Performs the recursive step of + DddmpCuddDdArrayStorePrefixBody. + +
          DddmpCuddDdArrayStoreBlif() +
          Writes a blif file representing the argument BDDs. + +
          DddmpCuddDdArrayStoreBlifBody() +
          Writes a blif body representing the argument BDDs. + +
          DddmpCuddDdArrayStoreBlifStep() +
          Performs the recursive step of DddmpCuddDdArrayStoreBlif. + +
          DddmpCuddDdArrayStoreSmv() +
          Internal function to writes a dump file representing the + argument BDD in a SMV notation. + +
          DddmpCuddDdArrayStoreSmvBody() +
          Internal function to writes a dump file representing the + argument BDD in a SMV notation. Writes the body of the file. + +
          DddmpCuddDdArrayStoreSmvStep() +
          Performs the recursive step of + DddmpCuddDdArrayStoreSmvBody. + +
          +
          +

          dddmpUtil.c

          +Util Functions for the dddmp package

          +By: Gianpiero Cabodi and Stefano Quer

          +Functions to manipulate arrays.

          +

          +
          QsortStrcmp() +
          String compare for qsort + +
          FindVarname() +
          Performs binary search of a name within a sorted array + +
          DddmpStrDup() +
          Duplicates a string + +
          DddmpStrArrayDup() +
          Duplicates an array of strings + +
          DddmpStrArrayRead() +
          Inputs an array of strings + +
          DddmpStrArrayWrite() +
          Outputs an array of strings + +
          DddmpStrArrayFree() +
          Frees an array of strings + +
          DddmpIntArrayDup() +
          Duplicates an array of ints + +
          DddmpIntArrayRead() +
          Inputs an array of ints + +
          DddmpIntArrayWrite() +
          Outputs an array of ints + +
          +
          +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDesc.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDesc.html new file mode 100644 index 000000000..a27b1847f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDesc.html @@ -0,0 +1,28 @@ + +The dddmp package: Overview + + +

          The dddmp package

          +

          Functions to read in and write out BDDs, ADDs + and CNF formulas from and to files.

          +

          By Gianpiero Cabodi and Stefano Quer

          + + + +
          + + + +
          + +Last updated on 1040218 17h14 + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDoc.txt b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDoc.txt new file mode 100644 index 0000000000000000000000000000000000000000..5912f35f54c29c1caf93c15e3b802fc8e0e0aba1 GIT binary patch literal 32768 zcmeHQ|9f0TxnI3j_Bnc`T$)1fFAiUn05y%+N`z3;BrOS~CAI;AB4(4_G;24z%kHM6 z-d^t(Dy&!_Xw|5dE?P7|ivbD*sP=hg{;~V{yfd?3l5A#y`sfdxWY5l=_kBO}&dhse z&b()K&e%*!C6me7yvir0jwBAJqG;b-cB+)lWs9nmQ-xF_snS`M$R^cOg>)&Ua&sls zKR8(2uJ+)l7)TsAuuo0r3bS*WL{Uu_a#!Pr&EQT8c0m$l4)T-R7y=J zvN`p=xl|!iA;8E3Ql;s1CROZ0wtDeyrBYpLa3<0}N4hsz+O2vMYNn8yzVBu!)t*dd zFjeZBDa}TiTLxLqA5G0AlS3#~sxXpEByUz@dk)^eckI5K_eXn%58S-FcPf`m?OuQ|)L=Jw`B8;*wlpv|nHtDW zt3q^4B~vOjHCI5vcuZ##nSq(q)DeXS>AD>?g^<*LReef5B?*7%Voe;|9(Ce`)W-hQ zY_4!j?JJ~GYJXx1)lX#x2M445qx`}Vib>>0`}PcvJbZAkn$9E+cSTehZDng~HC^wtV9%iGdRPrzz12jspX{bo_zfj_L(4=>83{A2}4ISLOuenJg zv`OZchU&MqKk(4t-rb$I_wE>YC_=1v#~##ft%fYYokwesXpa=LF{OMwQc`tILaeSQ z@v%l3ZD5sPLIIOsAbP-4HOs~^qtm1)l6b;KAkL@XFi7#m<9coQbQ=p zv^tt7q!W{wlmbH}JloZzc{LVm;4;tXe}Hc)H=EBDQv##^F&q&N-v{n7Ct{7DPbshf zjB)78BKBu8swGO4Kh~tP$R4;yYBmC2HZe=Q z%ln2$9&2J04wcU_`)nyyAk$#-KrZYr69v-_#B?^T^gwHW{tc6r* zu8>V7rNIli9Qxpcd-vw;Sg^ZmM>03H!w+`**a6diaV-f0vrwv(&U8(wgcXr9axfRo zA2-F_+1@(Uj_Qt2FRQ+24-&WIGo#GkHg7|uIG0Zqic^JjzEng9Se%1c$SS z=JNT>T}r=ch0SmE`-KQ&l9kVAQnRUSDUm^Gb59i$7&6YIK9=>HUMGi;5(2Z=i|Wv{ z7e}2p%1?q^#pe`{3?d!nGrN?2LrD)f{`ix-ZUP0$*D{|?aJ-vMl+sg)Ob&%glyU`M z0ZxJFTcQCwQT>k6XNcYiQaF|`q@$yWQfjW4O5m0WWx=h0zQ8Z1NItVO;t7JNTOQ5@DH+#6ompF+af$QmN<+$I;=+7Pz-mPU+I_3 zYuChJVx&d(3oKG$WP!|NBKuTA=?l?M%%9BJ9-alaJ<9~ba29+hVz+)PVxPdEKhT$x z=EE<cD*ZPrVJ>dc@0rs~lt?GYvahhQRA%n*9J!Yr_c{G% z^GlkQDhVwD88+nUW2pjea}pV)-?sLv^jrGuPSzSOVj<;ut2_tW$)U<%8mz0gZG(-0 zZ)_%!$R^lmAW1N%%q!-?7h{01G-ay#olTMb5*7%h5$W&K?@Ah^U0*e?eZk74VXZ=E zx9Awg(vzuDBCERfMJu6S>4|#olz7R}l&6j0?wyvQ^n1{dSA+T86MDg1zLxczE@e_v ziDD{~Dxr+54U0ICwNflRjM1g))@7d8uj+G;k~o)56pK+YeVARAgyHPN+4OW8moaRN z_HQnm3;ImyX5=_0l;o83O|?Wek;J3{vxP$XFq@!wER(@Nn4S_VP|D&ZhsDZR2K|OP zdq7ts0~N*xRA)tSPdYN$EA&uMQB8O&McX?%^Tlk0^NZS{q-|47r{_iOK4AA zfKp3Ko4;)Scx@xMt)$3Tl{3QO>?0h?N@8b}RBF4eHW}h%W`+8ls&_Mw&ZJ9G>QEln z2rP}koG`E5Yfez?DG*ad%p6ioJ(l*Z=PW8wM8*G|GRM+j7|uSHK8VT_W8_)0R5ZWr zwe$iA=;R{QCr?=JL#SFsOOitV>{|1>E`JHMW9edq4=Wy{G6ZNqdO=@|qC2igh$1`5 z>Q86y8cWTWI^{|fz3gEimpz&)V6>CT-z4k+LkDiO_Z%7+9(JR$t=I;k)zNk4H(+U+ z;RG?(nE|by00l8tO^`&*Rg@OgU`iQdn&XP3d+V7$G&?hrfYL`yZhLqZt5H05sA&q>$umV_{zH^t9c*PXJ4FyL*mjkTe- zWo>&lo#{ksV`q%NPj3=yPHg0>@jY3nG_8F(e!>h_M{~AoQtP{V>~tE;c0wHjS(25+rKq_8Ht+z1FvL+CbYQKqhUODN z{}%lR%_3`3LH7c@3n7eFo?Ge4Fny)>A%qd~PFSZx%{38%Lpkfd1^NuudN7(j7a>6J zGg;5QvD&c_!fH~k?)X^G=@EkRYBjn=TKhyoXq=&l_eI<$0iQ_-tl6>B(y0=Hq1VM( zZ7a7+2m&5Xh7G+kE{j%QO-`FuOgtaF^#G5X2v`_;dTdOoJ&14soC%d^1Ba0H4g~>f z4w6-#qE&vP5YGCJB$lVyjTFLxK$DxPg_kJ=<7dt;^A=915Q_6~!9CU5M-{@bZn&Te zD+B`fRuP9boW(g%q(aw$}bJo4@yuh0p?CG|n{OQ4FCl&$SLVt4Ynp76NJE zg2VVBK2f5J*InSgsRgk_zJ?RgJvhAofnI2YkO3~AJ^?@{y^3-|Nl&fLf|Ngz5ULyB$W zwrp@(hG5|ET+gW)@M(rnLk`e3JA>8!(Dl8cA!Ro5m#*s~g@-hRS#zgu=uHiwh_{su zzOlbG1Ota`oBmklwLxg#T??aePf%LJiRXI*cdket4HZtjz+6YO*4yixy&(kTv#uxD zYTn=r4gvY+4~^bp3)0{)4uMdcwcg~luH+ET`p)L{9L?52Oy}@j@Dc|c#MUhg|FH8E zb1_n)|biyHcpNDL4vy35L>6+^Z}gqL+9hs82H?CrH(& zKvw3(j!+9LESiA0(&sEcj!Zzh2hysCYdK1ANJ&a)mt>8D@U=MTOAw#H6JuEkVovLq zY?AEeG-&gnnF^sZ_c0Yx66_*-e&=RP6d_yH=Qk;HUcYstq=mXmsZP+wISbWQF0cp$ zFj)~VKC#~|%hBghVx|~&?g~Q9gVikQ3!4;OWK1!PK%*h^>kg>%7Lt2yDhLMFBqS#& zIZsJ*-kjTF(}X<^qN$RK=j|XTu@XVjA!N@-5ZDW0Rsa)^bCPS8AHFee(=n3Ilf0xq z+KM>HJ7w_|)1h1_+$4Y#fI100r9Z}Jk>vb6E-Az_;VL#~sL+Cb5eRlxe!ou(#Km2k z> zQzTY{h>+H0nXs5YY@vX~Hs`**84W`HRhX!XAiK>_}Gi zE9hv<-?zrGCP^v$u0RsHqTk&FFGG(@lUU-NEkgIVsA#Bu>Y&YX@LQSFKSC@GK zLDLmh6goqUP{`>x=K%XdP~fgY3_f;bU6xfv)jcjvRJ}qfE*e}w?}6pqeK#T*L=_3j zn*|oJf;CK|lpoTsx}*@7?%oUz^8xB*AJ0D$0(NY~rIZAi16GfHuvHBbW64yvxU{Fj zM$w{|Kn;#kVp=tB43;8`wpZOC^&pqHISruWyv!vDk{SYSl(doiLj?eLvjB1^nDu7D;b zkYq@4CnXrmJ)7fLUHQkYN>>T8WM19kPLR$gfj9@U8b^w@s+Yp}bzTv5Kp5Q5Y>jt= zXv*lEY%&I74{}kW!_s&Nypb0|=gb>htSmDbrMi_IPLz?0zJ!TCk|9X&Gt5x9ibT(2 z09cgKz>#zrG+ba6Wbs%C4p86q+{D$36kalw4rMBU&g+kSTFA>FEAw+utB-~6mTR20 z{Uu2lQvnP*X>^$5-$(2eZrRvrBQ50WchIp^^gRrsFm-)X3D18 z5jW>2JJiIzV3DNIgLfmV*ddG_sv}M>4J>g9TH7?xI&qUWZ(it7$3eu}L8ZVuS7NcxN?cE})*-flSB^ z{sJ>;<7NSOKDa9#gd?q6T1t`xH%s^6_GeMnoK1cq85o70f()PMGA zfySD2==lI{CDCg?ZazdsmCc7C?b@Jp|T}eJM3HljX|idiEo;b{+NOKM3K7 z%%LNy9~~Ya1;0=SVQe@%@Z%!`xo;`_)}?2zuCwc2FF1C-2d*s-A!H zdrKQ_I95yrE8Z`e*ROA9FtkwRCp~5ZkmONMdu{c?OxyZ4Y3l$?btmrem*Fs;nNjKy zmZtn<2oWr>wM*vB>v6XZi3RiaweinU)@kX$)x5h4@#$cn;TT0zT#B}0y)=3yJPc5y z4zvwLy`=rduO8&jYxy6z!>87!!fU4?G-V&E43TS+Xh6ak#>rlJhduWRRc@uQUin62 z9;g;1eRZ{=ZzH=0%5P^y+{V^);Gam@)v9iCb^F;=T~EbEkFHa_Niu)etuL!R7c@U0s-mFK>=x zo>dF*-uwcI_SE)#JD*Yt_wQ=xaUA%uKW9P20xeKqf6avS^?a+piN;`-P4&9CjoafV z(%Hg#alL3>xehlA=InK_T~mc0)l|L!3#P`sX5~8Ro@(Wxa7cd(?X~wA&FkO#sQvzg zN_*iU-eSV6euG|&kPYf~ucK}|%6e5l`*$d}&z{3-gsVB$FRayd^Xb!9YxQcaemd*9 zYB^Ue=c?tjs)4Il$JMK&m2GT%{;K6%wVaJDq!snbS&o{-E+Yv2>16sKzDCXY_FPiO z^vk>9JgrHp;}0_hC+Wa6*D|Z)Atk}9Pds>FqEU!zHC#HE#f}(Z4D*5hSidYQ#E>(E z;DY+n_3`UsqDmow9pBWTMK!-RFXha;5xi624PrO53ljGeVHg}pXVay0!lrB`gz%(_ zNA{`=yuJ*k{Gc+wz6LQ*QI3Li2#n1&@(`W_-Ak`7r?r>*zHto-X0aZ^896WML&)Os z5MnYdY)%Z@p`0^s>pyRbS@l4J#+O;Iu^97s^bkC?Jh2TY%!m5f-kZMYcpp6!%4=h3 z*ah}IaaqAteFUY#qtVM$0h^pap;3H7c^m=HS}BX6)NSUBxd?-=HDw46jqUx^X#8R> zgPla2#j7qXVfh&WJS7B%ErIZ$f?;rA7Q3PV+BLm?8eRan+iH{$lvfH!SoDSsn>^Cc zjJ`yi8X<%v%$7gbUq~gq1>N1I;NU=UHi1n`CTdnuF(;1ecdm(12TQA&5KcTfhb@`p z1WjoBf15ui^J{thKQ$s1;HrvQpPg)Mkg|GY;_nu~|$ zzbIfr;qxe$(O~*;P(Sdb(c^MIp69lR|L&2m-^S$~$jXv%F;|$x){fXa&Bj_D!NRS9 z`e(e%txw!#{=mw26p=I^!bPuF4&YH|2#`F$!z1Euy#!$n1Tw^!_qWB-lgNn~EC4Vs z#c)^%FRdUGJ1G5{efV_;K!$J;j^GZ|wRzkUYie6R*>Q}g;{8)!}vj#9Z6Y_e1T%p;;|%eF7ApJ@@pTDb z*lI$`e9#f!ENzEV6Zyx=QLp%j zE{yWZc44BO$I|GGpY{T%?vy>I&epq~M{e)}SlsdB zdO}w*GWnnv!_x=PYsw9lV-^|{i^2PRg80Eu0QK^u2L@$nqMk4d!8Hnv+|`MC*~|(? zRP!OQ#xdrgZTkzi1qZP0lJ&SQmKxlQg4W57xRcQp#M6@O*WVawQLG zlcX}>(P-K?>{$!SAIbKZr?FD^oVj4{9H?&y z%L;dP;oGeplC_`uJQc!f^Xua_&6{I$Za>#iBK!6{kabq(BB`3*k|R$uungwZ%^_XE zV)i=6pQt zNW$KPQT=<@kRC&(((JFTzWqFp0TP|K59n-9Y>9{On<;2ny`=AUneJ;$m`bpl70;Xn zGRp@y$2}&yOdtA!-J<0*Rdjq_2wI|BsD;Kv9}*!mQDmw~Pc$Yl8EPP5opc*$H6(03 zj`*$k=w-%yfQtePim}nVKhgSohKo)y#B<;NTDS?ZKJ$+)@x!o zDE=M-Bo7J(?md)P;MH{-Vx9OfX!?pxIVQB*H;JT0TGsIPpBVSv0TKn@bih-VMHB|13X&qf*K|yG=cY@9#6d zoV+1!Z)~1Hasqu=H@?3aD)u+QB))_@@x2|NPDFegndJ$9K994qdeD?nyTRU%Jdj|6 zWAcis_o=-8W!+(hb?g{T?g*)8J!#|S#cj2E8#kA?#q|qt80!~t80V({QdDHvhhMFX z<2(FIl^Q3w<@Y~*h|rXj`PDY1&my9$ILx5A+N#96D6vFgcA*3Kpn+e*IoLeLaY>`q z`ViR@E;TLsgL>8JMS#{@7rwK1l;Rx)t{PmR=It%24X@7uFypZhkWOHJhi_`hZmL6C zi=!NzOmFcwiJu4T%i%5`JdjzI--JS%VTMhPW{}YhtqdFWtz(vtZi_zS(Z_yFuY6Vr3vI_rUW!^DoH^rQ!oU;en!ymO01Y^BP zFfZZB-1F9z?4&(OJ(?>dkqDyI!Cv?}cC34e08X}sHEth51hKrpqxu&&o7cY>qaVaS zzCZ);c>{+%{9Nn$el*anW-;h(Ymdukj0T2X-Gn5vQS-d8UC?Djb_A=ISJ@2u1YRnb z)~eAR_In@V<2-?2{`A!t?qKf^fq}&e@M2bZjt4I2GPe-GMIrm4dyWQ@}lxZ+8<10VEwNPQuMC`@2y7-C26f~oBCQ512}Twb-k3HOik zd+k`pwfhl$ioKA~wN^W7t%^DB-z_-Jk(-I|{wFx_%RrxRd^$8PKP9(NZ49H1QG{rJ zG&}iu`~!$^G#C$6D|l=$3kk?R6T{(T@QEIOpUPPUTUJ-l%(W4xBClexknJ4xB0DY@ z^hzFA2NJv5P+NZINW1~oa^*6VdXXS582LFj z&2t!^Huj*kZ2a}J?=c7$jn1$gmmC`gjq$5(aYQ6^&-fU+{{A+e4%g-mvR#3{ z#)dfgHy>esXm4W7tN5Mi3xL)yhN`K775w+&V}AE}%t+Shw)`egR^_$b)@Rv9O$HGQ zy#5it?{P1+;dX=AXRT?AHIccJn^QGy_x0KLSrcWOy8VBevY&c?HPO*;t@h8Y(9gDi znkeeGPW!i4wCSq3!mZA$hW*j)GDnrFu(KBzm9M6K^y;s(X|P6nDRVo{8F_gx-;CI5 z*UnIX@<}%J@w5X(@siajSy}LbG zB}(JQpkEy55995g*nA$ZW!|u&Jkh?|yXnQ$eAQBW!hA!x>K#R$VQ)!PJp z3>>B8)oooCh3^Y*PdMRTDlTt9#fz-5{WrJnY)`np!KdgBrMcFjpVI3aH(zpI3ysF@ zUOv~pZP!qGBhEY9d8u6&T!b9k?bf8}qRL=ChRWs($M`97J7Ly2Han)#m9Rl^ikAy7 zOZ24h!Eo{A-sx$)Ww3aUI*`lSEAb{NxOw+lZUKWMJbdpq`24x?lM8l=4Byg4@Y-Y9 zRKDCtGTv~xlPzB<^s;k5i|Pt8nZ(6yRb+2EeM{9 z0;La|g7uM#tyA=KAj`L7$JCsvD<169Cd_{%$YUDw7H9}8>W*Z(c;w+C%U(8Vq#C5JT z-Gd`eGQ#}(SbH%<;JZYLK`%00_`rk1zDk~%j3E;64pcd2Gh4Ba@X b|H3R}$q;wm<>{I!fLyZ%TR+|Ay=(s;!vX;I literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExt.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExt.html new file mode 100644 index 000000000..fe026ec6f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExt.html @@ -0,0 +1,13 @@ + +The dddmp Package for Programmers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtAbs.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtAbs.html new file mode 100644 index 000000000..612554f58 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtAbs.html @@ -0,0 +1,91 @@ + +dddmp package abstract + + + + + +
          +
          Dddmp_Bin2Text() +
          Converts from binary to ASCII format + +
          Dddmp_Text2Bin() +
          Converts from ASCII to binary format + +
          Dddmp_cuddAddArrayLoad() +
          Reads a dump file representing the argument ADDs. + +
          Dddmp_cuddAddArrayStore() +
          Writes a dump file representing the argument Array of ADDs. + +
          Dddmp_cuddAddLoad() +
          Reads a dump file representing the argument ADD. + +
          Dddmp_cuddAddStore() +
          Writes a dump file representing the argument ADD. + +
          Dddmp_cuddBddArrayLoadCnf() +
          Reads a dump file in a CNF format. + +
          Dddmp_cuddBddArrayLoad() +
          Reads a dump file representing the argument BDDs. + +
          Dddmp_cuddBddArrayStoreBlif() +
          Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
          Dddmp_cuddBddArrayStoreCnf() +
          Writes a dump file representing the argument array of BDDs + in CNF format. + +
          Dddmp_cuddBddArrayStorePrefix() +
          Writes a dump file representing the argument BDD in + a prefix notation. + +
          Dddmp_cuddBddArrayStoreSmv() +
          Writes a dump file representing the argument BDD in + a prefix notation. + +
          Dddmp_cuddBddArrayStore() +
          Writes a dump file representing the argument Array of BDDs. + +
          Dddmp_cuddBddDisplayBinary() +
          Display a binary dump file in a text file + +
          Dddmp_cuddBddLoadCnf() +
          Reads a dump file in a CNF format. + +
          Dddmp_cuddBddLoad() +
          Reads a dump file representing the argument BDD. + +
          Dddmp_cuddBddStoreBlif() +
          Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
          Dddmp_cuddBddStoreCnf() +
          Writes a dump file representing the argument BDD in + a CNF format. + +
          Dddmp_cuddBddStorePrefix() +
          Writes a dump file representing the argument BDD in + a prefix notation. + +
          Dddmp_cuddBddStoreSmv() +
          Writes a dump file representing the argument BDD in + a prefix notation. + +
          Dddmp_cuddBddStore() +
          Writes a dump file representing the argument BDD. + +
          Dddmp_cuddHeaderLoadCnf() +
          Reads the header of a dump file representing the argument BDDs + +
          Dddmp_cuddHeaderLoad() +
          Reads the header of a dump file representing the argument BDDs + +
          + +
          + +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtDet.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtDet.html new file mode 100644 index 000000000..38fb590a4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtDet.html @@ -0,0 +1,693 @@ + +The dddmp package + + +
          +
          +
          +int 
          +Dddmp_Bin2Text(
          +  char * filein, IN: name of binary file
          +  char * fileout IN: name of ASCII file
          +)
          +
          +
          Converts from binary to ASCII format. A BDD array is loaded and + and stored to the target file. +

          + +

          Side Effects None +

          + +

          See Also Dddmp_Text2Bin() + + +
          +
          +int 
          +Dddmp_Text2Bin(
          +  char * filein, IN: name of ASCII file
          +  char * fileout IN: name of binary file
          +)
          +
          +
          Converts from ASCII to binary format. A BDD array is loaded and + and stored to the target file. +

          + +

          Side Effects None +

          + +

          See Also Dddmp_Bin2Text() + + +
          +
          +int 
          +Dddmp_cuddAddArrayLoad(
          +  DdManager * ddMgr, IN: DD Manager
          +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
          +  char ** rootmatchnames, IN: sorted names for loaded roots
          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names, by ids
          +  int * varmatchauxids, IN: array of variable auxids, by ids
          +  int * varcomposeids, IN: array of new ids, by ids
          +  int  mode, IN: requested input file format
          +  char * file, IN: file name
          +  FILE * fp, IN: file pointer
          +  DdNode *** pproots OUT: array of returned BDD roots
          +)
          +
          +
          Reads a dump file representing the argument ADDs. See + BDD load functions for detailed explanation. +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddBddArrayStore + + +
          +
          +int 
          +Dddmp_cuddAddArrayStore(
          +  DdManager * ddMgr, IN: DD Manager
          +  char * ddname, IN: DD name (or NULL)
          +  int  nRoots, IN: number of output BDD roots to be stored
          +  DdNode ** f, IN: array of ADD roots to be stored
          +  char ** rootnames, IN: array of root names (or NULL)
          +  char ** varnames, IN: array of variable names (or NULL)
          +  int * auxids, IN: array of converted var IDs
          +  int  mode, IN: storing mode selector
          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument array of ADDs to file. Dumping is + either in text or binary form. see the corresponding BDD dump + function for further details. +

          + +

          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

          + +

          See Also Dddmp_cuddAddStore +Dddmp_cuddAddLoad +Dddmp_cuddAddArrayLoad + + +
          +
          +DdNode * 
          +Dddmp_cuddAddLoad(
          +  DdManager * ddMgr, IN: Manager
          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names by IDs
          +  int * varmatchauxids, IN: array of variable auxids by IDs
          +  int * varcomposeids, IN: array of new ids by IDs
          +  int  mode, IN: requested input file format
          +  char * file, IN: file name
          +  FILE * fp IN: file pointer
          +)
          +
          +
          Reads a dump file representing the argument ADD. + Dddmp_cuddAddArrayLoad is used through a dummy array. +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddAddStore +Dddmp_cuddAddArrayLoad + + +
          +
          +int 
          +Dddmp_cuddAddStore(
          +  DdManager * ddMgr, IN: DD Manager
          +  char * ddname, IN: DD name (or NULL)
          +  DdNode * f, IN: ADD root to be stored
          +  char ** varnames, IN: array of variable names (or NULL)
          +  int * auxids, IN: array of converted var ids
          +  int  mode, IN: storing mode selector
          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument ADD to file. Dumping is done through + Dddmp_cuddAddArrayStore, And a dummy array of 1 ADD root is + used for this purpose. +

          + +

          Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

          + +

          See Also Dddmp_cuddAddLoad +Dddmp_cuddAddArrayLoad + + +
          +
          +int 
          +Dddmp_cuddBddArrayLoadCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  Dddmp_RootMatchType  rootmatchmode, IN: storing mode selector
          +  char ** rootmatchnames, IN: sorted names for loaded roots
          +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names, by IDs
          +  int * varmatchauxids, IN: array of variable auxids, by IDs
          +  int * varcomposeids, IN: array of new ids, by IDs
          +  int  mode, IN: computation Mode
          +  char * file, IN: file name
          +  FILE * fp, IN: file pointer
          +  DdNode *** rootsPtrPtr, OUT: array of returned BDD roots
          +  int * nRoots OUT: number of BDDs returned
          +)
          +
          +
          Reads a dump file representing the argument BDD in a + CNF formula. +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddBddArrayLoad + + +
          +
          +int 
          +Dddmp_cuddBddArrayLoad(
          +  DdManager * ddMgr, IN: DD Manager
          +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
          +  char ** rootmatchnames, IN: sorted names for loaded roots
          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names, by ids
          +  int * varmatchauxids, IN: array of variable auxids, by ids
          +  int * varcomposeids, IN: array of new ids, by ids
          +  int  mode, IN: requested input file format
          +  char * file, IN: file name
          +  FILE * fp, IN: file pointer
          +  DdNode *** pproots OUT: array of returned BDD roots
          +)
          +
          +
          Reads a dump file representing the argument BDDs. The header is + common to both text and binary mode. The node list is either + in text or binary format. A dynamic vector of DD pointers + is allocated to support conversion from DD indexes to pointers. + Several criteria are supported for variable match between file + and dd manager. Several changes/permutations/compositions are allowed + for variables while loading DDs. Variable of the dd manager are allowed + to match with variables on file on ids, permids, varnames, + varauxids; also direct composition between ids and + composeids is supported. More in detail: +
            +
          1. varMatchMode=DDDMP_VAR_MATCHIDS

            + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

          2. varMatchMode=DDDMP_VAR_MATCHPERMIDS

            + is used to allow variable match according to the position in the + ordering. + +

          3. varMatchMode=DDDMP_VAR_MATCHNAMES

            + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

          4. varMatchMode=DDDMP_VAR_MATCHIDS

            + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

          5. varMatchMode=DDDMP_VAR_COMPOSEIDS

            + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. +

          + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. + + All the loaded BDDs are referenced before returning them. +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddBddArrayStore + + +
          +
          +int 
          +Dddmp_cuddBddArrayStoreBlif(
          +  DdManager * ddMgr, IN: DD Manager
          +  int  nroots, IN: number of output BDD roots to be stored
          +  DdNode ** f, IN: array of BDD roots to be stored
          +  char ** inputNames, IN: array of variable names (or NULL)
          +  char ** outputNames, IN: array of root names (or NULL)
          +  char * modelName, IN: Model Name
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBLif. + A dummy array of 1 BDD root is used for this purpose. +

          + +

          See Also Dddmp_cuddBddArrayStorePrefix + + +
          +
          +int 
          +Dddmp_cuddBddArrayStoreCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode ** f, IN: array of BDD roots to be stored
          +  int  rootN, IN: # output BDD roots to be stored
          +  Dddmp_DecompCnfStoreType  mode, IN: format selection
          +  int  noHeader, IN: do not store header iff 1
          +  char ** varNames, IN: array of variable names (or NULL)
          +  int * bddIds, IN: array of converted var IDs
          +  int * bddAuxIds, IN: array of BDD node Auxiliary Ids
          +  int * cnfIds, IN: array of converted var IDs
          +  int  idInitial, IN: starting id for cutting variables
          +  int  edgeInTh, IN: Max # Incoming Edges
          +  int  pathLengthTh, IN: Max Path Length
          +  char * fname, IN: file name
          +  FILE * fp, IN: pointer to the store file
          +  int * clauseNPtr, OUT: number of clause stored
          +  int * varNewNPtr OUT: number of new variable created
          +)
          +
          +
          Dumps the argument array of BDDs to file. +

          + +

          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + Three methods are allowed: + * NodeByNode method: Insert a cut-point for each BDD node (but the + terminal nodes) + * MaxtermByMaxterm method: Insert no cut-points, i.e. the off-set of + trhe function is stored + * Best method: Tradeoff between the previous two methods. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. + The stored file can contain a file header or not depending on the + noHeader parameter (IFF 0, usual setting, the header is usually stored. + This option can be useful in storing multiple BDDs, as separate BDDs, + on the same file leaving the opening of the file to the caller. +

          + +

          +
          +int 
          +Dddmp_cuddBddArrayStorePrefix(
          +  DdManager * ddMgr, IN: DD Manager
          +  int  nroots, IN: number of output BDD roots to be stored
          +  DdNode ** f, IN: array of BDD roots to be stored
          +  char ** inputNames, IN: array of variable names (or NULL)
          +  char ** outputNames, IN: array of root names (or NULL)
          +  char * modelName, IN: Model Name
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

          + +

          See Also Dddmp_cuddBddArrayStore + + +
          +
          +int 
          +Dddmp_cuddBddArrayStoreSmv(
          +  DdManager * ddMgr, IN: DD Manager
          +  int  nroots, IN: number of output BDD roots to be stored
          +  DdNode ** f, IN: array of BDD roots to be stored
          +  char ** inputNames, IN: array of variable names (or NULL)
          +  char ** outputNames, IN: array of root names (or NULL)
          +  char * modelName, IN: Model Name
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

          + +

          See Also Dddmp_cuddBddArrayStore + + +
          +
          +int 
          +Dddmp_cuddBddArrayStore(
          +  DdManager * ddMgr, IN: DD Manager
          +  char * ddname, IN: dd name (or NULL)
          +  int  nRoots, IN: number of output BDD roots to be stored
          +  DdNode ** f, IN: array of BDD roots to be stored
          +  char ** rootnames, IN: array of root names (or NULL)
          +  char ** varnames, IN: array of variable names (or NULL)
          +  int * auxids, IN: array of converted var IDs
          +  int  mode, IN: storing mode selector
          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument array of BDDs to file. Dumping is either + in text or binary form. BDDs are stored to the fp (already + open) file if not NULL. Otherwise the file whose name is + fname is opened in write mode. The header has the same format + for both textual and binary dump. Names are allowed for input + variables (vnames) and for represented functions (rnames). + For sake of generality and because of dynamic variable + ordering both variable IDs and permuted IDs are included. + New IDs are also supported (auxids). Variables are identified + with incremental numbers. according with their positiom in + the support set. In text mode, an extra info may be added, + chosen among the following options: name, ID, PermID, or an + auxiliary id. Since conversion from DD pointers to integers + is required, DD nodes are temporarily removed from the unique + hash table. This allows the use of the next field to store + node IDs. +

          + +

          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

          + +

          See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
          +
          +int 
          +Dddmp_cuddBddDisplayBinary(
          +  char * fileIn, IN: name of binary file
          +  char * fileOut IN: name of text file
          +)
          +
          +
          Display a binary dump file in a text file +

          + +

          Side Effects None +

          + +

          See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad + + +
          +
          +int 
          +Dddmp_cuddBddLoadCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names, by IDs
          +  int * varmatchauxids, IN: array of variable auxids, by IDs
          +  int * varcomposeids, IN: array of new ids accessed, by IDs
          +  int  mode, IN: computation mode
          +  char * file, IN: file name
          +  FILE * fp, IN: file pointer
          +  DdNode *** rootsPtrPtr, OUT: array of returned BDD roots
          +  int * nRoots OUT: number of BDDs returned
          +)
          +
          +
          Reads a dump file representing the argument BDD in a + CNF formula. + Dddmp_cuddBddArrayLoadCnf is used through a dummy array. + The results is returned in different formats depending on the + mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
          +
          +DdNode * 
          +Dddmp_cuddBddLoad(
          +  DdManager * ddMgr, IN: DD Manager
          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
          +  char ** varmatchnames, IN: array of variable names - by IDs
          +  int * varmatchauxids, IN: array of variable auxids - by IDs
          +  int * varcomposeids, IN: array of new ids accessed - by IDs
          +  int  mode, IN: requested input file format
          +  char * file, IN: file name
          +  FILE * fp IN: file pointer
          +)
          +
          +
          Reads a dump file representing the argument BDD. + Dddmp_cuddBddArrayLoad is used through a dummy array (see this + function's description for more details). + Mode, the requested input file format, is checked against + the file format. + The loaded BDDs is referenced before returning it. +

          + +

          Side Effects A vector of pointers to DD nodes is allocated and freed. +

          + +

          See Also Dddmp_cuddBddStore +Dddmp_cuddBddArrayLoad + + +
          +
          +int 
          +Dddmp_cuddBddStoreBlif(
          +  DdManager * ddMgr, IN: DD Manager
          +  int  nRoots, IN: Number of BDD roots
          +  DdNode * f, IN: BDD root to be stored
          +  char ** inputNames, IN: Array of variable names
          +  char ** outputNames, IN: Array of root names
          +  char * modelName, IN: Model Name
          +  char * fileName, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBlif. + A dummy array of 1 BDD root is used for this purpose. +

          + +

          See Also Dddmp_cuddBddStorePrefix + + +
          +
          +int 
          +Dddmp_cuddBddStoreCnf(
          +  DdManager * ddMgr, IN: DD Manager
          +  DdNode * f, IN: BDD root to be stored
          +  Dddmp_DecompCnfStoreType  mode, IN: format selection
          +  int  noHeader, IN: do not store header iff 1
          +  char ** varNames, IN: array of variable names (or NULL)
          +  int * bddIds, IN: array of var ids
          +  int * bddAuxIds, IN: array of BDD node Auxiliary Ids
          +  int * cnfIds, IN: array of CNF var ids
          +  int  idInitial, IN: starting id for cutting variables
          +  int  edgeInTh, IN: Max # Incoming Edges
          +  int  pathLengthTh, IN: Max Path Length
          +  char * fname, IN: file name
          +  FILE * fp, IN: pointer to the store file
          +  int * clauseNPtr, OUT: number of clause stored
          +  int * varNewNPtr OUT: number of new variable created
          +)
          +
          +
          Dumps the argument BDD to file. + This task is performed by calling the function + Dddmp_cuddBddArrayStoreCnf. +

          + +

          Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

          + +

          See Also Dddmp_cuddBddArrayStoreCnf + + +
          +
          +int 
          +Dddmp_cuddBddStorePrefix(
          +  DdManager * ddMgr, IN: DD Manager
          +  int  nRoots, IN: Number of BDD roots
          +  DdNode * f, IN: BDD root to be stored
          +  char ** inputNames, IN: Array of variable names
          +  char ** outputNames, IN: Array of root names
          +  char * modelName, IN: Model Name
          +  char * fileName, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

          + +

          See Also Dddmp_cuddBddStore + + +
          +
          +int 
          +Dddmp_cuddBddStoreSmv(
          +  DdManager * ddMgr, IN: DD Manager
          +  int  nRoots, IN: Number of BDD roots
          +  DdNode * f, IN: BDD root to be stored
          +  char ** inputNames, IN: Array of variable names
          +  char ** outputNames, IN: Array of root names
          +  char * modelName, IN: Model Name
          +  char * fileName, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

          + +

          See Also Dddmp_cuddBddStore + + +
          +
          +int 
          +Dddmp_cuddBddStore(
          +  DdManager * ddMgr, IN: DD Manager
          +  char * ddname, IN: DD name (or NULL)
          +  DdNode * f, IN: BDD root to be stored
          +  char ** varnames, IN: array of variable names (or NULL)
          +  int * auxids, IN: array of converted var ids
          +  int  mode, IN: storing mode selector
          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
          +  char * fname, IN: File name
          +  FILE * fp IN: File pointer to the store file
          +)
          +
          +
          Dumps the argument BDD to file. Dumping is done through + Dddmp_cuddBddArrayStore. A dummy array of 1 BDD root is + used for this purpose. +

          + +

          Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

          + +

          See Also Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
          +
          +int 
          +Dddmp_cuddHeaderLoadCnf(
          +  int * nVars, OUT: number of DD variables
          +  int * nsuppvars, OUT: number of support variables
          +  char *** suppVarNames, OUT: array of support variable names
          +  char *** orderedVarNames, OUT: array of variable names
          +  int ** varIds, OUT: array of variable ids
          +  int ** varComposeIds, OUT: array of permids ids
          +  int ** varAuxIds, OUT: array of variable aux ids
          +  int * nRoots, OUT: number of root in the file
          +  char * file, IN: file name
          +  FILE * fp IN: file pointer
          +)
          +
          +
          Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. +

          + +

          See Also Dddmp_cuddBddArrayLoad + + +
          +
          +int 
          +Dddmp_cuddHeaderLoad(
          +  Dddmp_DecompType * ddType, OUT: selects the proper decomp type
          +  int * nVars, OUT: number of DD variables
          +  int * nsuppvars, OUT: number of support variables
          +  char *** suppVarNames, OUT: array of support variable names
          +  char *** orderedVarNames, OUT: array of variable names
          +  int ** varIds, OUT: array of variable ids
          +  int ** varComposeIds, OUT: array of permids ids
          +  int ** varAuxIds, OUT: array of variable aux ids
          +  int * nRoots, OUT: number of root in the file
          +  char * file, IN: file name
          +  FILE * fp IN: file pointer
          +)
          +
          +
          Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. +

          + +

          See Also Dddmp_cuddBddArrayLoad + + + +
          +
          +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpTitle.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpTitle.html new file mode 100644 index 000000000..25a369433 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpTitle.html @@ -0,0 +1,17 @@ + +The dddmp package: Title + + + + + + + + +
          + Programmer view + Maintainer by function + Maintainer by file
          + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/packages.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/packages.html new file mode 100644 index 000000000..27e4ace19 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/packages.html @@ -0,0 +1,12 @@ + +Package Documentation + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/pkgIndex.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/pkgIndex.html new file mode 100644 index 000000000..f2efd6bc8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/pkgIndex.html @@ -0,0 +1,13 @@ + +Package Documentation + +

          Package Documentation


          + + + + +
          dddmpFunctions to read in and write out BDDs, ADDs +
          +
          +Last updated on 1040218 17h15 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/0.add b/resources/3rdparty/cudd-2.5.0/dddmp/exp/0.add new file mode 100644 index 000000000..ba6bb3dcf --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/0.add @@ -0,0 +1,21 @@ +.ver DDDMP-2.0 +.add +.mode A +.varinfo 0 +.nnodes 5 +.nvars 3 +.nsuppvars 2 +.suppvarnames DUMMY1 DUMMY2 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 +.ids 1 2 +.permids 1 2 +.auxids 1 2 +.nroots 1 +.rootids 5 +.nodes +1 T 1 0 0 +2 T 2 0 0 +3 T 0 0 0 +4 2 1 2 3 +5 1 0 1 4 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/0.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/0.bdd new file mode 100644 index 000000000..5092978ef --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/0.bdd @@ -0,0 +1,19 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 5 +.nvars 50 +.nsuppvars 3 +.suppvarnames DUMMY1 DUMMY2 DUMMY3 +.ids 1 2 3 +.permids 1 2 3 +.auxids 1 2 3 +.nroots 1 +.rootids -5 +.nodes +1 T 1 0 0 +2 3 2 1 -1 +3 2 1 1 2 +4 2 1 1 -2 +5 1 0 3 4 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/0or1.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/0or1.bdd new file mode 100644 index 000000000..4fda5f20f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/0or1.bdd @@ -0,0 +1,119 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 104 +.nvars 50 +.nsuppvars 16 +.suppvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY6 DUMMY7 DUMMY8 DUMMY9 DUMMY10 DUMMY11 DUMMY12 DUMMY13 DUMMY14 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 +.ids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -104 +.nodes +1 T 1 0 0 +2 22 15 1 -1 +3 21 14 1 -2 +4 20 13 1 3 +5 19 12 1 4 +6 20 13 3 1 +7 21 14 1 2 +8 20 13 1 7 +9 19 12 6 8 +10 18 11 5 9 +11 17 10 1 10 +12 18 11 1 9 +13 17 10 1 12 +14 16 9 11 13 +15 20 13 7 -1 +16 21 14 2 -1 +17 20 13 16 -3 +18 19 12 15 -17 +19 21 14 2 1 +20 20 13 19 7 +21 19 12 6 20 +22 18 11 18 21 +23 17 10 1 22 +24 16 9 23 13 +25 18 11 18 9 +26 17 10 1 25 +27 16 9 26 13 +28 15 8 24 27 +29 12 7 28 27 +30 11 6 28 29 +31 11 6 28 27 +32 10 5 30 31 +33 4 4 14 32 +34 3 3 33 -1 +35 2 2 33 34 +36 19 12 1 8 +37 18 11 5 36 +38 17 10 1 37 +39 16 9 38 1 +40 19 12 1 20 +41 18 11 18 40 +42 17 10 1 41 +43 16 9 42 1 +44 18 11 18 36 +45 17 10 1 44 +46 16 9 45 1 +47 15 8 43 46 +48 12 7 47 46 +49 11 6 47 48 +50 11 6 47 46 +51 10 5 49 50 +52 4 4 39 51 +53 3 3 1 -52 +54 2 2 52 -53 +55 1 1 35 54 +56 20 13 16 -1 +57 21 14 1 -1 +58 20 13 1 57 +59 19 12 56 -58 +60 18 11 59 -9 +61 17 10 1 -60 +62 19 12 56 -8 +63 18 11 62 -9 +64 17 10 1 -63 +65 16 9 61 64 +66 21 14 2 -2 +67 20 13 66 1 +68 20 13 16 -57 +69 19 12 67 68 +70 18 11 69 -21 +71 17 10 1 -70 +72 16 9 71 64 +73 18 11 69 -9 +74 17 10 1 -73 +75 16 9 74 64 +76 15 8 72 75 +77 12 7 76 75 +78 11 6 76 77 +79 11 6 76 75 +80 10 5 78 79 +81 4 4 65 80 +82 3 3 81 -1 +83 2 2 81 82 +84 18 11 59 -36 +85 17 10 1 -84 +86 18 11 62 -1 +87 17 10 1 -86 +88 16 9 85 87 +89 18 11 69 -40 +90 17 10 1 -89 +91 16 9 90 87 +92 18 11 69 -36 +93 17 10 1 -92 +94 16 9 93 87 +95 15 8 91 94 +96 12 7 95 94 +97 11 6 95 96 +98 11 6 95 94 +99 10 5 97 98 +100 4 4 88 99 +101 3 3 1 -100 +102 2 2 100 -101 +103 1 1 83 102 +104 0 0 55 103 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/1.add b/resources/3rdparty/cudd-2.5.0/dddmp/exp/1.add new file mode 100644 index 000000000..ab6ab4d94 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/1.add @@ -0,0 +1,28 @@ +.ver DDDMP-2.0 +.add +.mode A +.varinfo 0 +.nnodes 12 +.nvars 50 +.nsuppvars 4 +.suppvarnames DUMMY1 DUMMY2 DUMMY3 DUMMY4 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY6 DUMMY7 DUMMY8 DUMMY9 DUMMY10 DUMMY11 DUMMY12 DUMMY13 DUMMY14 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 +.ids 1 2 3 4 +.permids 1 2 3 4 +.auxids 2 3 4 0 +.nroots 1 +.rootids 12 +.nodes +1 T 0 0 0 +2 T 2 0 0 +3 4 3 1 2 +4 T 1 0 0 +5 4 3 4 1 +6 3 2 3 5 +7 4 3 2 4 +8 3 2 7 3 +9 2 1 6 8 +10 3 2 5 7 +11 2 1 10 6 +12 1 0 9 11 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/1.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/1.bdd new file mode 100644 index 000000000..b7139aa06 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/1.bdd @@ -0,0 +1,110 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 96 +.nvars 50 +.nsuppvars 14 +.suppvarnames DUMMY0 DUMMY1 DUMMY4 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.ids 0 1 4 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 4 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 4 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -96 +.nodes +1 T 1 0 0 +2 22 13 1 -1 +3 21 12 1 -2 +4 20 11 1 3 +5 19 10 1 4 +6 20 11 3 1 +7 21 12 1 2 +8 20 11 1 7 +9 19 10 6 8 +10 18 9 5 9 +11 17 8 1 10 +12 18 9 1 9 +13 17 8 1 12 +14 16 7 11 13 +15 20 11 7 -1 +16 21 12 2 -1 +17 20 11 16 -3 +18 19 10 15 -17 +19 21 12 2 1 +20 20 11 19 7 +21 19 10 6 20 +22 18 9 18 21 +23 17 8 1 22 +24 16 7 23 13 +25 18 9 18 9 +26 17 8 1 25 +27 16 7 26 13 +28 15 6 24 27 +29 12 5 28 27 +30 11 4 28 29 +31 11 4 28 27 +32 10 3 30 31 +33 4 2 14 32 +34 19 10 1 8 +35 18 9 5 34 +36 17 8 1 35 +37 16 7 36 1 +38 19 10 1 20 +39 18 9 18 38 +40 17 8 1 39 +41 16 7 40 1 +42 18 9 18 34 +43 17 8 1 42 +44 16 7 43 1 +45 15 6 41 44 +46 12 5 45 44 +47 11 4 45 46 +48 11 4 45 44 +49 10 3 47 48 +50 4 2 37 49 +51 1 1 33 50 +52 20 11 16 -1 +53 21 12 1 -1 +54 20 11 1 53 +55 19 10 52 -54 +56 18 9 55 -9 +57 17 8 1 -56 +58 19 10 52 -8 +59 18 9 58 -9 +60 17 8 1 -59 +61 16 7 57 60 +62 21 12 2 -2 +63 20 11 62 1 +64 20 11 16 -53 +65 19 10 63 64 +66 18 9 65 -21 +67 17 8 1 -66 +68 16 7 67 60 +69 18 9 65 -9 +70 17 8 1 -69 +71 16 7 70 60 +72 15 6 68 71 +73 12 5 72 71 +74 11 4 72 73 +75 11 4 72 71 +76 10 3 74 75 +77 4 2 61 76 +78 18 9 55 -34 +79 17 8 1 -78 +80 18 9 58 -1 +81 17 8 1 -80 +82 16 7 79 81 +83 18 9 65 -38 +84 17 8 1 -83 +85 16 7 84 81 +86 18 9 65 -34 +87 17 8 1 -86 +88 16 7 87 81 +89 15 6 85 88 +90 12 5 89 88 +91 11 4 89 90 +92 11 4 89 88 +93 10 3 91 92 +94 4 2 82 93 +95 1 1 77 94 +96 0 0 51 95 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/2.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/2.bdd new file mode 100644 index 000000000..c23a16081 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/2.bdd @@ -0,0 +1,118 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 104 +.nvars 50 +.nsuppvars 16 +.suppvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.ids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -104 +.nodes +1 T 1 0 0 +2 22 15 1 -1 +3 21 14 1 -2 +4 20 13 1 3 +5 19 12 1 4 +6 20 13 3 1 +7 21 14 1 2 +8 20 13 1 7 +9 19 12 6 8 +10 18 11 5 9 +11 17 10 1 10 +12 18 11 1 9 +13 17 10 1 12 +14 16 9 11 13 +15 20 13 7 -1 +16 21 14 2 -1 +17 20 13 16 -3 +18 19 12 15 -17 +19 21 14 2 1 +20 20 13 19 7 +21 19 12 6 20 +22 18 11 18 21 +23 17 10 1 22 +24 16 9 23 13 +25 18 11 18 9 +26 17 10 1 25 +27 16 9 26 13 +28 15 8 24 27 +29 12 7 28 27 +30 11 6 28 29 +31 11 6 28 27 +32 10 5 30 31 +33 4 4 14 32 +34 3 3 1 33 +35 2 2 1 34 +36 19 12 1 8 +37 18 11 5 36 +38 17 10 1 37 +39 16 9 38 1 +40 19 12 1 20 +41 18 11 18 40 +42 17 10 1 41 +43 16 9 42 1 +44 18 11 18 36 +45 17 10 1 44 +46 16 9 45 1 +47 15 8 43 46 +48 12 7 47 46 +49 11 6 47 48 +50 11 6 47 46 +51 10 5 49 50 +52 4 4 39 51 +53 3 3 52 1 +54 2 2 1 53 +55 1 1 35 54 +56 20 13 16 -1 +57 21 14 1 -1 +58 20 13 1 57 +59 19 12 56 -58 +60 18 11 59 -9 +61 17 10 1 -60 +62 19 12 56 -8 +63 18 11 62 -9 +64 17 10 1 -63 +65 16 9 61 64 +66 21 14 2 -2 +67 20 13 66 1 +68 20 13 16 -57 +69 19 12 67 68 +70 18 11 69 -21 +71 17 10 1 -70 +72 16 9 71 64 +73 18 11 69 -9 +74 17 10 1 -73 +75 16 9 74 64 +76 15 8 72 75 +77 12 7 76 75 +78 11 6 76 77 +79 11 6 76 75 +80 10 5 78 79 +81 4 4 65 80 +82 3 3 1 81 +83 2 2 1 82 +84 18 11 59 -36 +85 17 10 1 -84 +86 18 11 62 -1 +87 17 10 1 -86 +88 16 9 85 87 +89 18 11 69 -40 +90 17 10 1 -89 +91 16 9 90 87 +92 18 11 69 -36 +93 17 10 1 -92 +94 16 9 93 87 +95 15 8 91 94 +96 12 7 95 94 +97 11 6 95 96 +98 11 6 95 94 +99 10 5 97 98 +100 4 4 88 99 +101 3 3 100 1 +102 2 2 1 101 +103 1 1 83 102 +104 0 0 55 103 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/2and3.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/2and3.bdd new file mode 100644 index 000000000..650c45492 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/2and3.bdd @@ -0,0 +1,76 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 61 +.nvars 50 +.nsuppvars 16 +.suppvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY6 DUMMY7 DUMMY8 DUMMY9 DUMMY10 DUMMY11 DUMMY12 DUMMY13 DUMMY14 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 +.ids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -61 +.nodes +1 T 1 0 0 +2 22 15 1 -1 +3 21 14 1 2 +4 20 13 3 -1 +5 21 14 2 -1 +6 20 13 5 -1 +7 19 12 4 -6 +8 21 14 2 1 +9 20 13 8 1 +10 19 12 1 9 +11 18 11 7 10 +12 17 10 1 11 +13 16 9 12 1 +14 19 12 4 1 +15 18 11 14 1 +16 17 10 1 15 +17 16 9 16 1 +18 15 8 13 17 +19 18 11 7 1 +20 17 10 1 19 +21 16 9 20 1 +22 15 8 21 17 +23 12 7 18 22 +24 11 6 18 23 +25 11 6 23 22 +26 10 5 24 25 +27 4 4 1 26 +28 3 3 1 27 +29 2 2 1 28 +30 3 3 27 1 +31 2 2 1 30 +32 1 1 29 31 +33 19 12 6 -1 +34 18 11 33 -1 +35 17 10 1 -34 +36 21 14 2 -2 +37 20 13 36 1 +38 19 12 37 6 +39 18 11 38 -10 +40 17 10 1 -39 +41 16 9 40 35 +42 19 12 37 -1 +43 18 11 42 -1 +44 17 10 1 -43 +45 16 9 44 35 +46 15 8 41 45 +47 18 11 38 -1 +48 17 10 1 -47 +49 16 9 48 35 +50 15 8 49 45 +51 12 7 46 50 +52 11 6 46 51 +53 11 6 51 50 +54 10 5 52 53 +55 4 4 35 54 +56 3 3 1 55 +57 2 2 1 56 +58 3 3 55 1 +59 2 2 1 58 +60 1 1 57 59 +61 0 0 32 60 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/3.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/3.bdd new file mode 100644 index 000000000..33d6ddf54 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/3.bdd @@ -0,0 +1,304 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 290 +.nvars 50 +.nsuppvars 17 +.suppvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.ids 0 1 2 3 4 5 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 2 3 4 5 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 2 3 4 5 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -290 +.nodes +1 T 1 0 0 +2 22 16 1 -1 +3 21 15 2 1 +4 20 14 3 1 +5 19 13 4 1 +6 18 12 1 5 +7 17 11 1 6 +8 20 14 2 1 +9 19 13 8 1 +10 18 12 1 9 +11 17 11 1 10 +12 5 5 7 11 +13 21 15 1 2 +14 20 14 13 -1 +15 21 15 2 -1 +16 20 14 15 -1 +17 19 13 14 -16 +18 20 14 3 -1 +19 21 15 1 -1 +20 20 14 19 -1 +21 19 13 18 -20 +22 18 12 17 21 +23 17 11 1 22 +24 20 14 13 -15 +25 19 13 24 1 +26 20 14 3 -15 +27 19 13 26 1 +28 18 12 25 27 +29 17 11 1 28 +30 16 10 23 29 +31 19 13 14 1 +32 19 13 18 1 +33 18 12 31 32 +34 17 11 1 33 +35 16 10 34 29 +36 15 9 30 35 +37 19 13 18 -16 +38 18 12 17 37 +39 17 11 1 38 +40 16 10 39 29 +41 15 9 40 35 +42 12 8 36 41 +43 11 7 36 42 +44 11 7 42 36 +45 10 6 43 44 +46 20 14 2 -1 +47 19 13 46 -20 +48 18 12 17 47 +49 17 11 1 48 +50 20 14 2 -15 +51 19 13 50 1 +52 18 12 25 51 +53 17 11 1 52 +54 16 10 49 53 +55 19 13 46 1 +56 18 12 31 55 +57 17 11 1 56 +58 16 10 57 53 +59 15 9 54 58 +60 19 13 46 -16 +61 18 12 17 60 +62 17 11 1 61 +63 16 10 62 53 +64 15 9 63 58 +65 12 8 59 64 +66 11 7 59 65 +67 11 7 65 59 +68 10 6 66 67 +69 5 5 45 68 +70 4 4 12 69 +71 21 15 2 -2 +72 20 14 71 1 +73 19 13 72 1 +74 18 12 1 73 +75 17 11 1 74 +76 20 14 1 13 +77 19 13 72 76 +78 18 12 1 77 +79 17 11 1 78 +80 16 10 75 79 +81 20 14 15 1 +82 19 13 81 1 +83 18 12 1 82 +84 17 11 1 83 +85 19 13 81 76 +86 18 12 1 85 +87 17 11 1 86 +88 16 10 84 87 +89 5 5 80 88 +90 20 14 71 -1 +91 19 13 90 -20 +92 18 12 17 91 +93 17 11 1 92 +94 20 14 71 -15 +95 19 13 94 76 +96 18 12 25 95 +97 17 11 1 96 +98 16 10 93 97 +99 19 13 90 1 +100 18 12 31 99 +101 17 11 1 100 +102 16 10 101 97 +103 15 9 98 102 +104 19 13 90 -16 +105 18 12 17 104 +106 17 11 1 105 +107 16 10 106 97 +108 15 9 107 102 +109 12 8 103 108 +110 11 7 103 109 +111 11 7 109 103 +112 10 6 110 111 +113 19 13 16 -20 +114 18 12 17 113 +115 17 11 1 114 +116 20 14 15 -15 +117 19 13 116 76 +118 18 12 25 117 +119 17 11 1 118 +120 16 10 115 119 +121 19 13 16 1 +122 18 12 31 121 +123 17 11 1 122 +124 16 10 123 119 +125 15 9 120 124 +126 19 13 16 -16 +127 18 12 17 126 +128 17 11 1 127 +129 16 10 128 119 +130 15 9 129 124 +131 12 8 125 130 +132 11 7 125 131 +133 11 7 131 125 +134 10 6 132 133 +135 5 5 112 134 +136 4 4 89 135 +137 3 3 70 136 +138 5 5 75 84 +139 19 13 94 1 +140 18 12 25 139 +141 17 11 1 140 +142 16 10 93 141 +143 16 10 101 141 +144 15 9 142 143 +145 16 10 106 141 +146 15 9 145 143 +147 12 8 144 146 +148 11 7 144 147 +149 11 7 147 144 +150 10 6 148 149 +151 19 13 116 1 +152 18 12 25 151 +153 17 11 1 152 +154 16 10 115 153 +155 16 10 123 153 +156 15 9 154 155 +157 16 10 128 153 +158 15 9 157 155 +159 12 8 156 158 +160 11 7 156 159 +161 11 7 159 156 +162 10 6 160 161 +163 5 5 150 162 +164 4 4 138 163 +165 3 3 70 164 +166 2 2 137 165 +167 1 1 70 166 +168 19 13 16 -1 +169 18 12 168 -5 +170 17 11 1 -169 +171 18 12 168 -9 +172 17 11 1 -171 +173 5 5 170 172 +174 19 13 72 16 +175 18 12 174 -21 +176 17 11 1 -175 +177 20 14 71 15 +178 19 13 177 -1 +179 18 12 178 -27 +180 17 11 1 -179 +181 16 10 176 180 +182 19 13 72 -1 +183 18 12 182 -32 +184 17 11 1 -183 +185 16 10 184 180 +186 15 9 181 185 +187 18 12 174 -37 +188 17 11 1 -187 +189 16 10 188 180 +190 15 9 189 185 +191 12 8 186 190 +192 11 7 186 191 +193 11 7 191 186 +194 10 6 192 193 +195 18 12 174 -47 +196 17 11 1 -195 +197 18 12 178 -51 +198 17 11 1 -197 +199 16 10 196 198 +200 18 12 182 -55 +201 17 11 1 -200 +202 16 10 201 198 +203 15 9 199 202 +204 18 12 174 -60 +205 17 11 1 -204 +206 16 10 205 198 +207 15 9 206 202 +208 12 8 203 207 +209 11 7 203 208 +210 11 7 208 203 +211 10 6 209 210 +212 5 5 194 211 +213 4 4 173 212 +214 18 12 168 -73 +215 17 11 1 -214 +216 18 12 168 -77 +217 17 11 1 -216 +218 16 10 215 217 +219 18 12 168 -82 +220 17 11 1 -219 +221 18 12 168 -85 +222 17 11 1 -221 +223 16 10 220 222 +224 5 5 218 223 +225 18 12 174 -91 +226 17 11 1 -225 +227 18 12 178 -95 +228 17 11 1 -227 +229 16 10 226 228 +230 18 12 182 -99 +231 17 11 1 -230 +232 16 10 231 228 +233 15 9 229 232 +234 18 12 174 -104 +235 17 11 1 -234 +236 16 10 235 228 +237 15 9 236 232 +238 12 8 233 237 +239 11 7 233 238 +240 11 7 238 233 +241 10 6 239 240 +242 18 12 174 -113 +243 17 11 1 -242 +244 18 12 178 -117 +245 17 11 1 -244 +246 16 10 243 245 +247 18 12 182 -121 +248 17 11 1 -247 +249 16 10 248 245 +250 15 9 246 249 +251 18 12 174 -126 +252 17 11 1 -251 +253 16 10 252 245 +254 15 9 253 249 +255 12 8 250 254 +256 11 7 250 255 +257 11 7 255 250 +258 10 6 256 257 +259 5 5 241 258 +260 4 4 224 259 +261 3 3 213 260 +262 5 5 215 220 +263 18 12 178 -139 +264 17 11 1 -263 +265 16 10 226 264 +266 16 10 231 264 +267 15 9 265 266 +268 16 10 235 264 +269 15 9 268 266 +270 12 8 267 269 +271 11 7 267 270 +272 11 7 270 267 +273 10 6 271 272 +274 18 12 178 -151 +275 17 11 1 -274 +276 16 10 243 275 +277 16 10 248 275 +278 15 9 276 277 +279 16 10 252 275 +280 15 9 279 277 +281 12 8 278 280 +282 11 7 278 281 +283 11 7 281 278 +284 10 6 282 283 +285 5 5 273 284 +286 4 4 262 285 +287 3 3 213 286 +288 2 2 261 287 +289 1 1 213 288 +290 0 0 167 289 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd new file mode 100644 index 000000000..fb774baab --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 3 +.nnodes 35 +.nvars 50 +.nsuppvars 15 +.suppvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +.orderedvarnames V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 3 5 15 17 19 23 43 45 47 73 75 77 95 97 99 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 V50 14 1 -1 +3 V49 13 1 2 +4 V48 12 3 1 +5 V48 12 1 -1 +6 V48 12 2 1 +7 V39 11 5 -6 +8 V49 13 1 -1 +9 V48 12 8 1 +10 V39 11 9 4 +11 V38 10 7 -10 +12 V37 9 1 -11 +13 V38 10 5 -9 +14 V37 9 1 -13 +15 V24 8 12 14 +16 V37 9 1 -7 +17 V37 9 1 -5 +18 V24 8 16 17 +19 V23 7 15 18 +20 V22 6 19 1 +21 V23 7 14 17 +22 V22 6 21 1 +23 V12 5 20 22 +24 V10 4 23 1 +25 V22 6 18 1 +26 V12 5 20 25 +27 V10 4 26 1 +28 V9 3 24 27 +29 V12 5 20 1 +30 V10 4 29 1 +31 V10 4 20 1 +32 V9 3 30 31 +33 V8 2 28 32 +34 V3 1 4 33 +35 V2 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis1 b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis1 new file mode 100644 index 000000000..220059d0c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis1 @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 35 +.nvars 150 +.nsuppvars 15 +.suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 49 14 1 -1 +3 48 13 1 2 +4 47 12 3 1 +5 47 12 1 -1 +6 47 12 2 1 +7 38 11 5 -6 +8 48 13 1 -1 +9 47 12 8 1 +10 38 11 9 4 +11 37 10 7 -10 +12 36 9 1 -11 +13 37 10 5 -9 +14 36 9 1 -13 +15 23 8 12 14 +16 36 9 1 -7 +17 36 9 1 -5 +18 23 8 16 17 +19 22 7 15 18 +20 21 6 19 1 +21 22 7 14 17 +22 21 6 21 1 +23 11 5 20 22 +24 9 4 23 1 +25 21 6 18 1 +26 11 5 20 25 +27 9 4 26 1 +28 8 3 24 27 +29 11 5 20 1 +30 9 4 29 1 +31 9 4 20 1 +32 8 3 30 31 +33 7 2 28 32 +34 2 1 4 33 +35 1 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis2 b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis2 new file mode 100644 index 000000000..220059d0c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis2 @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 35 +.nvars 150 +.nsuppvars 15 +.suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 49 14 1 -1 +3 48 13 1 2 +4 47 12 3 1 +5 47 12 1 -1 +6 47 12 2 1 +7 38 11 5 -6 +8 48 13 1 -1 +9 47 12 8 1 +10 38 11 9 4 +11 37 10 7 -10 +12 36 9 1 -11 +13 37 10 5 -9 +14 36 9 1 -13 +15 23 8 12 14 +16 36 9 1 -7 +17 36 9 1 -5 +18 23 8 16 17 +19 22 7 15 18 +20 21 6 19 1 +21 22 7 14 17 +22 21 6 21 1 +23 11 5 20 22 +24 9 4 23 1 +25 21 6 18 1 +26 11 5 20 25 +27 9 4 26 1 +28 8 3 24 27 +29 11 5 20 1 +30 9 4 29 1 +31 9 4 20 1 +32 8 3 30 31 +33 7 2 28 32 +34 2 1 4 33 +35 1 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis3 b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis3 new file mode 100644 index 000000000..220059d0c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis3 @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 35 +.nvars 150 +.nsuppvars 15 +.suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 49 14 1 -1 +3 48 13 1 2 +4 47 12 3 1 +5 47 12 1 -1 +6 47 12 2 1 +7 38 11 5 -6 +8 48 13 1 -1 +9 47 12 8 1 +10 38 11 9 4 +11 37 10 7 -10 +12 36 9 1 -11 +13 37 10 5 -9 +14 36 9 1 -13 +15 23 8 12 14 +16 36 9 1 -7 +17 36 9 1 -5 +18 23 8 16 17 +19 22 7 15 18 +20 21 6 19 1 +21 22 7 14 17 +22 21 6 21 1 +23 11 5 20 22 +24 9 4 23 1 +25 21 6 18 1 +26 11 5 20 25 +27 9 4 26 1 +28 8 3 24 27 +29 11 5 20 1 +30 9 4 29 1 +31 9 4 20 1 +32 8 3 30 31 +33 7 2 28 32 +34 2 1 4 33 +35 1 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis4 b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis4 new file mode 100644 index 000000000..220059d0c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis4 @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 35 +.nvars 150 +.nsuppvars 15 +.suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 49 14 1 -1 +3 48 13 1 2 +4 47 12 3 1 +5 47 12 1 -1 +6 47 12 2 1 +7 38 11 5 -6 +8 48 13 1 -1 +9 47 12 8 1 +10 38 11 9 4 +11 37 10 7 -10 +12 36 9 1 -11 +13 37 10 5 -9 +14 36 9 1 -13 +15 23 8 12 14 +16 36 9 1 -7 +17 36 9 1 -5 +18 23 8 16 17 +19 22 7 15 18 +20 21 6 19 1 +21 22 7 14 17 +22 21 6 21 1 +23 11 5 20 22 +24 9 4 23 1 +25 21 6 18 1 +26 11 5 20 25 +27 9 4 26 1 +28 8 3 24 27 +29 11 5 20 1 +30 9 4 29 1 +31 9 4 20 1 +32 8 3 30 31 +33 7 2 28 32 +34 2 1 4 33 +35 1 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf new file mode 100644 index 000000000..d1a946c2d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf @@ -0,0 +1,130 @@ +c # BDD stored by the DDDMP tool in CNF format +c # +c # Warning: AUX IDs missing ... equal to BDD IDs. +c # +c .ver DDDMP-2.0 +c .nnodes 35 +c .nvars 50 +c .nsuppvars 15 +c .suppvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +c .orderedvarnames V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +c .ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .cnfids 2 3 8 9 10 12 22 23 24 37 38 39 48 49 50 +c .nroots 1 +c .rootids 1 +c .nAddedCnfVar 31 +c # +c # Init CNF Clauses +c # +p cnf 130 108 +100 -49 0 +100 -50 0 +-100 49 50 0 +101 48 0 +101 -100 0 +-101 -48 100 0 +102 48 0 +102 -50 0 +-102 -48 50 0 +103 39 102 0 +-103 39 -102 0 +103 -39 -48 0 +-103 -39 48 0 +104 48 0 +104 -49 0 +-104 -48 49 0 +105 39 -101 0 +-105 39 101 0 +105 -39 -104 0 +-105 -39 104 0 +106 38 105 0 +-106 38 -105 0 +106 -38 -103 0 +-106 -38 103 0 +107 -37 0 +107 106 0 +-107 37 -106 0 +108 38 104 0 +-108 38 -104 0 +108 -38 -48 0 +-108 -38 48 0 +109 -37 0 +109 108 0 +-109 37 -108 0 +110 24 -109 0 +-110 24 109 0 +110 -24 -107 0 +-110 -24 107 0 +111 -37 0 +111 103 0 +-111 37 -103 0 +112 -37 0 +112 48 0 +-112 37 -48 0 +113 24 -112 0 +-113 24 112 0 +113 -24 -111 0 +-113 -24 111 0 +114 23 -113 0 +-114 23 113 0 +114 -23 -110 0 +-114 -23 110 0 +115 22 0 +115 -114 0 +-115 -22 114 0 +116 23 -112 0 +-116 23 112 0 +116 -23 -109 0 +-116 -23 109 0 +117 22 0 +117 -116 0 +-117 -22 116 0 +118 12 -117 0 +-118 12 117 0 +118 -12 -115 0 +-118 -12 115 0 +119 10 0 +119 -118 0 +-119 -10 118 0 +120 22 0 +120 -113 0 +-120 -22 113 0 +121 12 -120 0 +-121 12 120 0 +121 -12 -115 0 +-121 -12 115 0 +122 10 0 +122 -121 0 +-122 -10 121 0 +123 9 -122 0 +-123 9 122 0 +123 -9 -119 0 +-123 -9 119 0 +124 12 0 +124 -115 0 +-124 -12 115 0 +125 10 0 +125 -124 0 +-125 -10 124 0 +126 10 0 +126 -115 0 +-126 -10 115 0 +127 9 -126 0 +-127 9 126 0 +127 -9 -125 0 +-127 -9 125 0 +128 8 -127 0 +-128 8 127 0 +128 -8 -123 0 +-128 -8 123 0 +129 3 -128 0 +-129 3 128 0 +129 -3 -101 0 +-129 -3 101 0 +130 -2 0 +130 -129 0 +-130 2 129 0 +-130 0 +c # End of Cnf From dddmp-2.0 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf.bis b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf.bis new file mode 100644 index 000000000..d4faf78e8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf.bis @@ -0,0 +1,130 @@ +c # BDD stored by the DDDMP tool in CNF format +c # +c # Warning: AUX IDs missing ... equal to BDD IDs. +c # +c .ver DDDMP-2.0 +c .nnodes 35 +c .nvars 150 +c .nsuppvars 15 +c .suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +c .orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +c .ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .cnfids 2 3 8 9 10 12 22 23 24 37 38 39 48 49 50 +c .nroots 1 +c .rootids 1 +c .nAddedCnfVar 31 +c # +c # Init CNF Clauses +c # +p cnf 130 108 +100 -49 0 +100 -50 0 +-100 49 50 0 +101 48 0 +101 -100 0 +-101 -48 100 0 +102 48 0 +102 -50 0 +-102 -48 50 0 +103 39 102 0 +-103 39 -102 0 +103 -39 -48 0 +-103 -39 48 0 +104 48 0 +104 -49 0 +-104 -48 49 0 +105 39 -101 0 +-105 39 101 0 +105 -39 -104 0 +-105 -39 104 0 +106 38 105 0 +-106 38 -105 0 +106 -38 -103 0 +-106 -38 103 0 +107 -37 0 +107 106 0 +-107 37 -106 0 +108 38 104 0 +-108 38 -104 0 +108 -38 -48 0 +-108 -38 48 0 +109 -37 0 +109 108 0 +-109 37 -108 0 +110 24 -109 0 +-110 24 109 0 +110 -24 -107 0 +-110 -24 107 0 +111 -37 0 +111 103 0 +-111 37 -103 0 +112 -37 0 +112 48 0 +-112 37 -48 0 +113 24 -112 0 +-113 24 112 0 +113 -24 -111 0 +-113 -24 111 0 +114 23 -113 0 +-114 23 113 0 +114 -23 -110 0 +-114 -23 110 0 +115 22 0 +115 -114 0 +-115 -22 114 0 +116 23 -112 0 +-116 23 112 0 +116 -23 -109 0 +-116 -23 109 0 +117 22 0 +117 -116 0 +-117 -22 116 0 +118 12 -117 0 +-118 12 117 0 +118 -12 -115 0 +-118 -12 115 0 +119 10 0 +119 -118 0 +-119 -10 118 0 +120 22 0 +120 -113 0 +-120 -22 113 0 +121 12 -120 0 +-121 12 120 0 +121 -12 -115 0 +-121 -12 115 0 +122 10 0 +122 -121 0 +-122 -10 121 0 +123 9 -122 0 +-123 9 122 0 +123 -9 -119 0 +-123 -9 119 0 +124 12 0 +124 -115 0 +-124 -12 115 0 +125 10 0 +125 -124 0 +-125 -10 124 0 +126 10 0 +126 -115 0 +-126 -10 115 0 +127 9 -126 0 +-127 9 126 0 +127 -9 -125 0 +-127 -9 125 0 +128 8 -127 0 +-128 8 127 0 +128 -8 -123 0 +-128 -8 123 0 +129 3 -128 0 +-129 3 128 0 +129 -3 -101 0 +-129 -3 101 0 +130 -2 0 +130 -129 0 +-130 2 129 0 +-130 0 +c # End of Cnf From dddmp-2.0 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max1 b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max1 new file mode 100644 index 000000000..d9a498414 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max1 @@ -0,0 +1,125 @@ +c # BDD stored by the DDDMP tool in CNF format +c # +c # Warning: AUX IDs missing ... equal to BDD IDs. +c # +c .ver DDDMP-2.0 +c .nnodes 35 +c .nvars 150 +c .nsuppvars 15 +c .suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +c .orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +c .ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .cnfids 2 3 8 9 10 12 22 23 24 37 38 39 48 49 50 +c .nroots 1 +c .rootids 1 +c .nAddedCnfVar 0 +c # +c # Init CNF Clauses +c # +p cnf 50 103 +3 8 9 10 0 +3 8 9 22 0 +3 8 9 23 24 48 0 +3 8 9 23 24 -37 0 +3 8 9 23 -24 39 48 0 +3 8 9 23 -24 39 -50 0 +3 8 9 23 -24 -39 48 0 +3 8 9 23 -24 -37 0 +3 8 9 -23 24 38 48 0 +3 8 9 -23 24 38 -49 0 +3 8 9 -23 24 -38 48 0 +3 8 9 -23 24 -37 0 +3 8 9 -23 -24 38 39 48 0 +3 8 9 -23 -24 38 39 -50 0 +3 8 9 -23 -24 38 39 -49 0 +3 8 9 -23 -24 38 -39 48 0 +3 8 9 -23 -24 38 -39 -49 0 +3 8 9 -23 -24 -38 39 48 0 +3 8 9 -23 -24 -38 39 -50 0 +3 8 9 -23 -24 -38 -39 48 0 +3 8 9 -23 -24 -37 0 +3 8 -9 10 0 +3 8 -9 12 0 +3 8 -9 22 0 +3 8 -9 23 24 48 0 +3 8 -9 23 24 -37 0 +3 8 -9 23 -24 39 48 0 +3 8 -9 23 -24 39 -50 0 +3 8 -9 23 -24 -39 48 0 +3 8 -9 23 -24 -37 0 +3 8 -9 -23 24 38 48 0 +3 8 -9 -23 24 38 -49 0 +3 8 -9 -23 24 -38 48 0 +3 8 -9 -23 24 -37 0 +3 8 -9 -23 -24 38 39 48 0 +3 8 -9 -23 -24 38 39 -50 0 +3 8 -9 -23 -24 38 39 -49 0 +3 8 -9 -23 -24 38 -39 48 0 +3 8 -9 -23 -24 38 -39 -49 0 +3 8 -9 -23 -24 -38 39 48 0 +3 8 -9 -23 -24 -38 39 -50 0 +3 8 -9 -23 -24 -38 -39 48 0 +3 8 -9 -23 -24 -37 0 +3 -8 9 10 0 +3 -8 9 12 22 0 +3 -8 9 12 24 48 0 +3 -8 9 12 24 -37 0 +3 -8 9 12 -24 39 48 0 +3 -8 9 12 -24 39 -50 0 +3 -8 9 12 -24 -39 48 0 +3 -8 9 12 -24 -37 0 +3 -8 9 -12 22 0 +3 -8 9 -12 23 24 48 0 +3 -8 9 -12 23 24 -37 0 +3 -8 9 -12 23 -24 39 48 0 +3 -8 9 -12 23 -24 39 -50 0 +3 -8 9 -12 23 -24 -39 48 0 +3 -8 9 -12 23 -24 -37 0 +3 -8 9 -12 -23 24 38 48 0 +3 -8 9 -12 -23 24 38 -49 0 +3 -8 9 -12 -23 24 -38 48 0 +3 -8 9 -12 -23 24 -37 0 +3 -8 9 -12 -23 -24 38 39 48 0 +3 -8 9 -12 -23 -24 38 39 -50 0 +3 -8 9 -12 -23 -24 38 39 -49 0 +3 -8 9 -12 -23 -24 38 -39 48 0 +3 -8 9 -12 -23 -24 38 -39 -49 0 +3 -8 9 -12 -23 -24 -38 39 48 0 +3 -8 9 -12 -23 -24 -38 39 -50 0 +3 -8 9 -12 -23 -24 -38 -39 48 0 +3 -8 9 -12 -23 -24 -37 0 +3 -8 -9 10 0 +3 -8 -9 12 22 0 +3 -8 -9 12 23 48 0 +3 -8 -9 12 23 -37 0 +3 -8 -9 12 -23 38 48 0 +3 -8 -9 12 -23 38 -49 0 +3 -8 -9 12 -23 -38 48 0 +3 -8 -9 12 -23 -37 0 +3 -8 -9 -12 22 0 +3 -8 -9 -12 23 24 48 0 +3 -8 -9 -12 23 24 -37 0 +3 -8 -9 -12 23 -24 39 48 0 +3 -8 -9 -12 23 -24 39 -50 0 +3 -8 -9 -12 23 -24 -39 48 0 +3 -8 -9 -12 23 -24 -37 0 +3 -8 -9 -12 -23 24 38 48 0 +3 -8 -9 -12 -23 24 38 -49 0 +3 -8 -9 -12 -23 24 -38 48 0 +3 -8 -9 -12 -23 24 -37 0 +3 -8 -9 -12 -23 -24 38 39 48 0 +3 -8 -9 -12 -23 -24 38 39 -50 0 +3 -8 -9 -12 -23 -24 38 39 -49 0 +3 -8 -9 -12 -23 -24 38 -39 48 0 +3 -8 -9 -12 -23 -24 38 -39 -49 0 +3 -8 -9 -12 -23 -24 -38 39 48 0 +3 -8 -9 -12 -23 -24 -38 39 -50 0 +3 -8 -9 -12 -23 -24 -38 -39 48 0 +3 -8 -9 -12 -23 -24 -37 0 +-3 48 0 +-3 -50 0 +-3 -49 0 +-2 0 +c # End of Cnf From dddmp-2.0 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max2 b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max2 new file mode 100644 index 000000000..d9a498414 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max2 @@ -0,0 +1,125 @@ +c # BDD stored by the DDDMP tool in CNF format +c # +c # Warning: AUX IDs missing ... equal to BDD IDs. +c # +c .ver DDDMP-2.0 +c .nnodes 35 +c .nvars 150 +c .nsuppvars 15 +c .suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +c .orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +c .ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .cnfids 2 3 8 9 10 12 22 23 24 37 38 39 48 49 50 +c .nroots 1 +c .rootids 1 +c .nAddedCnfVar 0 +c # +c # Init CNF Clauses +c # +p cnf 50 103 +3 8 9 10 0 +3 8 9 22 0 +3 8 9 23 24 48 0 +3 8 9 23 24 -37 0 +3 8 9 23 -24 39 48 0 +3 8 9 23 -24 39 -50 0 +3 8 9 23 -24 -39 48 0 +3 8 9 23 -24 -37 0 +3 8 9 -23 24 38 48 0 +3 8 9 -23 24 38 -49 0 +3 8 9 -23 24 -38 48 0 +3 8 9 -23 24 -37 0 +3 8 9 -23 -24 38 39 48 0 +3 8 9 -23 -24 38 39 -50 0 +3 8 9 -23 -24 38 39 -49 0 +3 8 9 -23 -24 38 -39 48 0 +3 8 9 -23 -24 38 -39 -49 0 +3 8 9 -23 -24 -38 39 48 0 +3 8 9 -23 -24 -38 39 -50 0 +3 8 9 -23 -24 -38 -39 48 0 +3 8 9 -23 -24 -37 0 +3 8 -9 10 0 +3 8 -9 12 0 +3 8 -9 22 0 +3 8 -9 23 24 48 0 +3 8 -9 23 24 -37 0 +3 8 -9 23 -24 39 48 0 +3 8 -9 23 -24 39 -50 0 +3 8 -9 23 -24 -39 48 0 +3 8 -9 23 -24 -37 0 +3 8 -9 -23 24 38 48 0 +3 8 -9 -23 24 38 -49 0 +3 8 -9 -23 24 -38 48 0 +3 8 -9 -23 24 -37 0 +3 8 -9 -23 -24 38 39 48 0 +3 8 -9 -23 -24 38 39 -50 0 +3 8 -9 -23 -24 38 39 -49 0 +3 8 -9 -23 -24 38 -39 48 0 +3 8 -9 -23 -24 38 -39 -49 0 +3 8 -9 -23 -24 -38 39 48 0 +3 8 -9 -23 -24 -38 39 -50 0 +3 8 -9 -23 -24 -38 -39 48 0 +3 8 -9 -23 -24 -37 0 +3 -8 9 10 0 +3 -8 9 12 22 0 +3 -8 9 12 24 48 0 +3 -8 9 12 24 -37 0 +3 -8 9 12 -24 39 48 0 +3 -8 9 12 -24 39 -50 0 +3 -8 9 12 -24 -39 48 0 +3 -8 9 12 -24 -37 0 +3 -8 9 -12 22 0 +3 -8 9 -12 23 24 48 0 +3 -8 9 -12 23 24 -37 0 +3 -8 9 -12 23 -24 39 48 0 +3 -8 9 -12 23 -24 39 -50 0 +3 -8 9 -12 23 -24 -39 48 0 +3 -8 9 -12 23 -24 -37 0 +3 -8 9 -12 -23 24 38 48 0 +3 -8 9 -12 -23 24 38 -49 0 +3 -8 9 -12 -23 24 -38 48 0 +3 -8 9 -12 -23 24 -37 0 +3 -8 9 -12 -23 -24 38 39 48 0 +3 -8 9 -12 -23 -24 38 39 -50 0 +3 -8 9 -12 -23 -24 38 39 -49 0 +3 -8 9 -12 -23 -24 38 -39 48 0 +3 -8 9 -12 -23 -24 38 -39 -49 0 +3 -8 9 -12 -23 -24 -38 39 48 0 +3 -8 9 -12 -23 -24 -38 39 -50 0 +3 -8 9 -12 -23 -24 -38 -39 48 0 +3 -8 9 -12 -23 -24 -37 0 +3 -8 -9 10 0 +3 -8 -9 12 22 0 +3 -8 -9 12 23 48 0 +3 -8 -9 12 23 -37 0 +3 -8 -9 12 -23 38 48 0 +3 -8 -9 12 -23 38 -49 0 +3 -8 -9 12 -23 -38 48 0 +3 -8 -9 12 -23 -37 0 +3 -8 -9 -12 22 0 +3 -8 -9 -12 23 24 48 0 +3 -8 -9 -12 23 24 -37 0 +3 -8 -9 -12 23 -24 39 48 0 +3 -8 -9 -12 23 -24 39 -50 0 +3 -8 -9 -12 23 -24 -39 48 0 +3 -8 -9 -12 23 -24 -37 0 +3 -8 -9 -12 -23 24 38 48 0 +3 -8 -9 -12 -23 24 38 -49 0 +3 -8 -9 -12 -23 24 -38 48 0 +3 -8 -9 -12 -23 24 -37 0 +3 -8 -9 -12 -23 -24 38 39 48 0 +3 -8 -9 -12 -23 -24 38 39 -50 0 +3 -8 -9 -12 -23 -24 38 39 -49 0 +3 -8 -9 -12 -23 -24 38 -39 48 0 +3 -8 -9 -12 -23 -24 38 -39 -49 0 +3 -8 -9 -12 -23 -24 -38 39 48 0 +3 -8 -9 -12 -23 -24 -38 39 -50 0 +3 -8 -9 -12 -23 -24 -38 -39 48 0 +3 -8 -9 -12 -23 -24 -37 0 +-3 48 0 +-3 -50 0 +-3 -49 0 +-2 0 +c # End of Cnf From dddmp-2.0 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4bis.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4bis.bdd new file mode 100644 index 000000000..fc242f3c1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4bis.bdd @@ -0,0 +1,47 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 3 +.nnodes 35 +.nvars 50 +.nsuppvars 15 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 1 0 0 +2 14 1 -1 +3 13 1 2 +4 12 3 1 +5 12 1 -1 +6 12 2 1 +7 11 5 -6 +8 13 1 -1 +9 12 8 1 +10 11 9 4 +11 10 7 -10 +12 9 1 -11 +13 10 5 -9 +14 9 1 -13 +15 8 12 14 +16 9 1 -7 +17 9 1 -5 +18 8 16 17 +19 7 15 18 +20 6 19 1 +21 7 14 17 +22 6 21 1 +23 5 20 22 +24 4 23 1 +25 6 18 1 +26 5 20 25 +27 4 26 1 +28 3 24 27 +29 5 20 1 +30 4 29 1 +31 4 20 1 +32 3 30 31 +33 2 28 32 +34 1 4 33 +35 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4xor5.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4xor5.bdd new file mode 100644 index 000000000..9967a6767 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4xor5.bdd @@ -0,0 +1,120 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 105 +.nvars 50 +.nsuppvars 18 +.suppvarnames DUMMY1 DUMMY2 DUMMY7 DUMMY8 DUMMY9 DUMMY11 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY6 DUMMY7 DUMMY8 DUMMY9 DUMMY10 DUMMY11 DUMMY12 DUMMY13 DUMMY14 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 +.ids 1 2 7 8 9 11 19 20 21 22 23 24 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 19 20 21 22 23 24 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 19 20 21 22 23 24 36 37 38 47 48 49 +.nroots 1 +.rootids 105 +.nodes +1 T 1 0 0 +2 24 11 1 -1 +3 23 10 1 -2 +4 22 9 3 -2 +5 21 8 4 -2 +6 23 10 1 -1 +7 22 9 6 -1 +8 21 8 7 -1 +9 20 7 5 8 +10 23 10 2 -1 +11 22 9 2 10 +12 21 8 11 2 +13 23 10 2 -2 +14 22 9 3 -13 +15 21 8 4 14 +16 20 7 12 15 +17 19 6 9 -16 +18 49 17 1 -1 +19 48 16 1 18 +20 47 15 19 1 +21 24 11 20 -20 +22 23 10 20 -21 +23 22 9 22 -21 +24 21 8 23 -21 +25 23 10 20 -20 +26 22 9 25 -20 +27 21 8 26 -20 +28 20 7 24 27 +29 23 10 21 -20 +30 22 9 21 29 +31 21 8 30 21 +32 23 10 21 -21 +33 22 9 22 -32 +34 21 8 23 33 +35 20 7 31 34 +36 19 6 28 -35 +37 47 15 1 -1 +38 47 15 18 1 +39 38 14 37 -38 +40 48 16 1 -1 +41 47 15 40 1 +42 38 14 41 20 +43 37 13 39 -42 +44 36 12 1 -43 +45 37 13 37 -41 +46 36 12 1 -45 +47 24 11 46 -46 +48 23 10 44 -47 +49 36 12 1 -39 +50 24 11 49 -49 +51 36 12 1 -37 +52 24 11 51 -51 +53 23 10 50 52 +54 22 9 48 -53 +55 21 8 54 -2 +56 23 10 44 -46 +57 23 10 49 51 +58 22 9 56 -57 +59 21 8 58 -1 +60 20 7 55 59 +61 24 11 44 -44 +62 23 10 61 47 +63 23 10 50 -51 +64 22 9 62 63 +65 21 8 64 2 +66 21 8 54 14 +67 20 7 65 66 +68 19 6 60 -67 +69 23 10 46 -47 +70 22 9 69 -52 +71 21 8 70 -2 +72 23 10 46 -46 +73 22 9 72 -51 +74 21 8 73 -1 +75 20 7 71 74 +76 23 10 52 -51 +77 22 9 47 76 +78 21 8 77 2 +79 21 8 70 14 +80 20 7 78 79 +81 19 6 75 -80 +82 11 5 68 81 +83 9 4 82 17 +84 23 10 49 -52 +85 22 9 84 -53 +86 21 8 85 -2 +87 23 10 49 -51 +88 22 9 87 -57 +89 21 8 88 -1 +90 20 7 86 89 +91 22 9 53 63 +92 21 8 91 2 +93 21 8 85 14 +94 20 7 92 93 +95 19 6 90 -94 +96 11 5 68 95 +97 9 4 96 17 +98 8 3 83 97 +99 11 5 68 17 +100 9 4 99 17 +101 9 4 68 17 +102 8 3 100 101 +103 7 2 98 102 +104 2 1 36 103 +105 1 0 17 104 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/5.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/5.bdd new file mode 100644 index 000000000..198f6bfa7 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/5.bdd @@ -0,0 +1,31 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 17 +.nvars 50 +.nsuppvars 6 +.suppvarnames DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 +.ids 19 20 21 22 23 24 +.permids 19 20 21 22 23 24 +.auxids 19 20 21 22 23 24 +.nroots 1 +.rootids 17 +.nodes +1 T 1 0 0 +2 24 5 1 -1 +3 23 4 1 -2 +4 22 3 3 -2 +5 21 2 4 -2 +6 23 4 1 -1 +7 22 3 6 -1 +8 21 2 7 -1 +9 20 1 5 8 +10 23 4 2 -1 +11 22 3 2 10 +12 21 2 11 2 +13 23 4 2 -2 +14 22 3 3 -13 +15 21 2 4 14 +16 20 1 12 15 +17 19 0 9 -16 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/composeids.txt b/resources/3rdparty/cudd-2.5.0/dddmp/exp/composeids.txt new file mode 100644 index 000000000..0e1340fed --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/composeids.txt @@ -0,0 +1,20 @@ +0 +2 +4 +6 +8 +10 +12 +14 +16 +18 +20 +22 +24 +26 +28 +30 +32 +34 +36 +38 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/one.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/one.bdd new file mode 100644 index 000000000..836566fbe --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/one.bdd @@ -0,0 +1,13 @@ +.ver DDDMP-1.0 +.mode A +.varinfo 0 +.nnodes 1 +.nvars 100 +.nsuppvars 0 +.ids +.permids +.nroots 1 +.rootids 1 +.nodes +1 T 1 0 0 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.out new file mode 100644 index 000000000..321532e3c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.out @@ -0,0 +1,269 @@ +--------------------------------------------------------------------------- +--------------------- TESTING Load and Write Header ----------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> DD TYPE: DDDMP_BDD +Number of variables: 50 +Number of support variables: 15 +suppVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +orderedVarNames: V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varAuxIds: 3 5 15 17 19 23 43 45 47 73 75 77 95 97 99 +varAuxIds for ALL Manager Variables: -1 3 5 -1 -1 -1 -1 15 17 19 -1 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 43 45 47 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 73 75 77 -1 -1 -1 -1 -1 -1 -1 -1 95 97 99 +Number of roots: 1 +TestDddmp> File : TestDddmp> DD TYPE: DDDMP_ADD +Number of variables: 3 +Number of support variables: 2 +suppVarNames: DUMMY1 DUMMY2 +orderedVarNames: DUMMY0 DUMMY1 DUMMY2 +varIds: 1 2 +varIds for ALL Manager Variables: -1 1 2 +varComposeIds: 1 2 +varComposeIds for ALL Manager Variables: -1 1 2 +varAuxIds: 1 2 +varAuxIds for ALL Manager Variables: -1 1 2 +Number of roots: 1 +TestDddmp> File : TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 50 +Number of support variables: 15 +suppVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +orderedVarNames: V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +Number of roots: 1 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +-------------------- TESTING Load BDD from DDDMP-1.0 ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> DD TYPE: DDDMP_BDD +Number of variables: 10 +Number of support variables: 7 +suppVarNames: G0 G1 G2 G3 G5 G6 G7 +orderedVarNames: G0 G1 G2 G3 G5 G6 G7 DUMMY7 DUMMY8 DUMMY9 +varIds: 0 1 2 3 4 5 6 +varIds for ALL Manager Variables: 0 1 2 3 4 5 6 -1 -1 -1 +varComposeIds: 0 1 2 3 4 6 8 +varComposeIds for ALL Manager Variables: 0 1 2 3 4 6 8 -1 -1 -1 +varAuxIds: 0 1 2 3 4 5 6 +varAuxIds for ALL Manager Variables: 0 1 2 3 4 5 6 -1 -1 -1 +Number of roots: 3 +TestDddmp> File : Which Array of BDDs [0..19]: TestDddmp> File : Which Array of BDDs [0..19]: Storing Array of BDDs in file s27deltaDddmp1.bdd.tmp ... +done. +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +----------------------- TESTING basic Load/Store ... ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 0.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 1.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 0or1.bdd.tmp ... +TestDddmp> File : Which BDDs [0..19]: Loading 2.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 3.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 2and3.bdd.tmp ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 5.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 4xor5.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +---------- TESTING Load/Store with sifting, varnames & varauxids ---------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Storing 4a.bdd.tmp ... +TestDddmp> Reordering Approach (1..17): TestDddmp> File : Which BDDs [0..19]: Storing 4b.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +------------------------- ... END PHASE 1 ... ----------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> Variable matchmode: +Match IDs (1) +Match permIDs (2) +Match names (must have been loaded) (3) +Match auxids (must have been loaded) (4) +Match composeids (must have been loaded) (5) +Your choice: TestDddmp> File : Which BDDs [0..19]: Loading 4b.bdd.tmp ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Storing 4c.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load ADD and Store ADD ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 0.add ... +Load: +-01 2 +-1- 1 +TestDddmp> File : Which BDDs [0..19]: Storing 0.add.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 1.add ... +Load: +-0001--------------------------------------------- 1 +-0010--------------------------------------------- 2 +-0100--------------------------------------------- 1 +-0101--------------------------------------------- 2 +-0111--------------------------------------------- 1 +-1000--------------------------------------------- 2 +-1010--------------------------------------------- 1 +-1011--------------------------------------------- 2 +-1101--------------------------------------------- 1 +-1110--------------------------------------------- 2 +TestDddmp> File : Which BDDs [0..19]: Storing 1.add.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load BDD and Store CNF ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.cnf.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +--------------------- TESTING Load CNF and Store BDD ---------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.cnf.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load BDD and Store CNF ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.node1.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.max1.tmp ... +Number of Clauses Stored = 103 +Number of New Variable Created Storing = 0 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.node2.tmp ... +Number of Clauses Stored = 114 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.node3.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.max2.tmp ... +Number of Clauses Stored = 103 +Number of New Variable Created Storing = 0 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.best1.tmp ... +Number of Clauses Stored = 53 +Number of New Variable Created Storing = 7 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.best2.tmp ... +Number of Clauses Stored = 69 +Number of New Variable Created Storing = 12 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +--------------------------------------------------------------------------- +--------------------- TESTING Load CNF and Store BDD ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.node2.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.node2.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.node3.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.node3.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.best1.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.best1.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.best2.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.best2.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.script new file mode 100755 index 000000000..8d792ef42 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.script @@ -0,0 +1,11 @@ +# !/bin/sh +# +# Run All Test Files +# +./test1.script +./test2.script +./test3.script +./test4.script +./test5.script +./test6.script +./test7.script diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27RP1.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27RP1.bdd new file mode 100644 index 000000000..56532603a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27RP1.bdd @@ -0,0 +1,18 @@ +# MONO +.ver DDDMP-1.0 +.mode A +.varinfo 3 +.nnodes 3 +.nvars 10 +.nsuppvars 2 +.varnames G5 G6 +.ids 4 5 +.permids 4 6 +.auxids 4 5 +.nroots 1 +.rootids -3 +.nodes +1 T 1 0 0 +2 5 1 1 -1 +3 4 0 2 -1 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd new file mode 100644 index 000000000..11a595687 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd @@ -0,0 +1,31 @@ +.ver DDDMP-1.0 +.mode A +.varinfo 0 +.dd s27adelta.bdd +.nnodes 16 +.nvars 10 +.nsuppvars 7 +.varnames G0 G1 G2 G3 G5 G6 G7 +.ids 0 1 2 3 4 5 6 +.permids 0 1 2 3 4 6 8 +.auxids 0 1 2 3 4 5 6 +.nroots 3 +.rootids 6 -13 -16 +.nodes +1 T 1 0 0 +2 6 6 1 -1 +3 4 4 1 2 +4 3 3 3 1 +5 1 1 1 4 +6 0 0 5 -1 +7 5 5 1 -1 +8 4 4 1 -7 +9 5 5 1 -2 +10 4 4 1 -9 +11 3 3 10 8 +12 1 1 8 11 +13 0 0 5 12 +14 2 2 1 -1 +15 2 2 1 -2 +16 1 1 14 15 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd.bis b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd.bis new file mode 100644 index 000000000..b7fb86bfe --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd.bis @@ -0,0 +1,31 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 16 +.nvars 10 +.nsuppvars 7 +.suppvarnames G0 G1 G2 G3 G5 G6 G7 +.orderedvarnames G0 G1 G2 G3 G5 G6 G7 DUMMY7 DUMMY8 DUMMY9 +.ids 0 1 2 3 4 5 6 +.permids 0 1 2 3 4 5 6 +.auxids 0 1 2 3 4 5 6 +.nroots 3 +.rootids 6 -13 -16 +.nodes +1 T 1 0 0 +2 6 6 1 -1 +3 4 4 1 2 +4 3 3 3 1 +5 1 1 1 4 +6 0 0 5 -1 +7 5 5 1 -1 +8 4 4 1 -7 +9 5 5 1 -2 +10 4 4 1 -9 +11 3 3 10 8 +12 1 1 8 11 +13 0 0 5 12 +14 2 2 1 -1 +15 2 2 1 -2 +16 1 1 14 15 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp2.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp2.bdd new file mode 100644 index 000000000..d247bd1fd --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp2.bdd @@ -0,0 +1,32 @@ +.ver DDDMP-1.0 +.mode A +.varinfo 0 +.dd s27adelta.bdd +.nnodes 16 +.nvars 10 +.nsuppvars 7 +.orderedvarnames G0 G1 G2 G3 G5 G6 G7 TMP1 TMP2 TMP3 +.suppvarnames G0 G1 G2 G3 G5 G6 G7 +.ids 0 1 2 3 4 5 6 +.permids 0 1 2 3 4 6 8 +.auxids 0 1 2 3 4 5 6 +.nroots 3 +.rootids 6 -13 -16 +.nodes +1 T 1 0 0 +2 6 6 1 -1 +3 4 4 1 2 +4 3 3 3 1 +5 1 1 1 4 +6 0 0 5 -1 +7 5 5 1 -1 +8 4 4 1 -7 +9 5 5 1 -2 +10 4 4 1 -9 +11 3 3 10 8 +12 1 1 8 11 +13 0 0 5 12 +14 2 2 1 -1 +15 2 2 1 -2 +16 1 1 14 15 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.out new file mode 100644 index 000000000..96b2a3ac3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.out @@ -0,0 +1,44 @@ +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load and Write Header ----------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> DD TYPE: DDDMP_BDD +Number of variables: 50 +Number of support variables: 15 +suppVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +orderedVarNames: V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varAuxIds: 3 5 15 17 19 23 43 45 47 73 75 77 95 97 99 +varAuxIds for ALL Manager Variables: -1 3 5 -1 -1 -1 -1 15 17 19 -1 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 43 45 47 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 73 75 77 -1 -1 -1 -1 -1 -1 -1 -1 95 97 99 +Number of roots: 1 +TestDddmp> File : TestDddmp> DD TYPE: DDDMP_ADD +Number of variables: 3 +Number of support variables: 2 +suppVarNames: DUMMY1 DUMMY2 +orderedVarNames: DUMMY0 DUMMY1 DUMMY2 +varIds: 1 2 +varIds for ALL Manager Variables: -1 1 2 +varComposeIds: 1 2 +varComposeIds for ALL Manager Variables: -1 1 2 +varAuxIds: 1 2 +varAuxIds for ALL Manager Variables: -1 1 2 +Number of roots: 1 +TestDddmp> File : TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 50 +Number of support variables: 15 +suppVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +orderedVarNames: V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +Number of roots: 1 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.script new file mode 100755 index 000000000..843e3650c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.script @@ -0,0 +1,26 @@ +# !/bin/sh +# +# Check Header Load/Store for BDD/ADD/CNFs: +# Load Header +# Write Information on Standard Output +# +rm -f *.*.tmp +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load and Write Header -----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END +mi +50 +hlb +4.bdd +hw +hlb +0.add +hw +hlc +4.cnf +hw +mq +quit +END +echo "-------------------------------- ... END ----------------------------------" diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.out new file mode 100644 index 000000000..22d6e39d1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.out @@ -0,0 +1,23 @@ +rm: No match. +--------------------------------------------------------------------------- +-------------------- TESTING Load BDD from DDDMP-1.0 ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> DD TYPE: DDDMP_BDD +Number of variables: 10 +Number of support variables: 7 +suppVarNames: G0 G1 G2 G3 G5 G6 G7 +orderedVarNames: G0 G1 G2 G3 G5 G6 G7 DUMMY7 DUMMY8 DUMMY9 +varIds: 0 1 2 3 4 5 6 +varIds for ALL Manager Variables: 0 1 2 3 4 5 6 -1 -1 -1 +varComposeIds: 0 1 2 3 4 6 8 +varComposeIds for ALL Manager Variables: 0 1 2 3 4 6 8 -1 -1 -1 +varAuxIds: 0 1 2 3 4 5 6 +varAuxIds for ALL Manager Variables: 0 1 2 3 4 5 6 -1 -1 -1 +Number of roots: 3 +TestDddmp> File : Which Array of BDDs [0..19]: TestDddmp> File : Which Array of BDDs [0..19]: Storing Array of BDDs in file s27deltaDddmp1.bdd.tmp ... +done. +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.script new file mode 100755 index 000000000..f719ed2bb --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.script @@ -0,0 +1,30 @@ +# !/bin/sh +# +# Check BDDs from DDDMP-1.0: +# Load an Array of BDDs from DDDMP-1.0 +# Store them +# +rm -f *.*.tmp +echo "---------------------------------------------------------------------------" +echo "-------------------- TESTING Load BDD from DDDMP-1.0 ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END +mi +10 +hlb +s27deltaDddmp1.bdd +hw +bal +s27deltaDddmp1.bdd +0 +bas +s27deltaDddmp1.bdd.tmp +0 +mq +quit +END +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief s27deltaDddmp1.bdd.tmp s27deltaDddmp1.bdd.bis +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.out new file mode 100644 index 000000000..0c296c095 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.out @@ -0,0 +1,18 @@ +rm: No match. +--------------------------------------------------------------------------- +----------------------- TESTING basic Load/Store ... ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 0.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 1.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 0or1.bdd.tmp ... +TestDddmp> File : Which BDDs [0..19]: Loading 2.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 3.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 2and3.bdd.tmp ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 5.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 4xor5.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.script new file mode 100755 index 000000000..408496c2d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.script @@ -0,0 +1,69 @@ +# !/bin/sh +# +# BDD check: +# Load BDDs +# Make some operations +# Store BDDs +# +rm -f *.*.tmp +echo "---------------------------------------------------------------------------" +echo "----------------------- TESTING basic Load/Store ... ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END +mi +50 +hlb +0or1.bdd +bl +0.bdd +0 +bl +1.bdd +1 +op +or +0 +1 +2 +bs +0or1.bdd.tmp +2 +bl +2.bdd +2 +bl +3.bdd +3 +op +and +2 +3 +4 +bs +2and3.bdd.tmp +4 +hlb +4xor5.bdd +bl +4.bdd +4 +bl +5.bdd +5 +op +xor +4 +5 +6 +bs +4xor5.bdd.tmp +6 +mq +quit +END +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 0or1.bdd 0or1.bdd.tmp +diff --brief 2and3.bdd 2and3.bdd.tmp +diff --brief 4xor5.bdd 4xor5.bdd.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.out new file mode 100644 index 000000000..367602d90 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.out @@ -0,0 +1,24 @@ +rm: No match. +--------------------------------------------------------------------------- +---------- TESTING Load/Store with sifting, varnames & varauxids ---------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Storing 4a.bdd.tmp ... +TestDddmp> Reordering Approach (1..17): TestDddmp> File : Which BDDs [0..19]: Storing 4b.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +------------------------- ... END PHASE 1 ... ----------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> Variable matchmode: +Match IDs (1) +Match permIDs (2) +Match names (must have been loaded) (3) +Match auxids (must have been loaded) (4) +Match composeids (must have been loaded) (5) +Your choice: TestDddmp> File : Which BDDs [0..19]: Loading 4b.bdd.tmp ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Storing 4c.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.script new file mode 100755 index 000000000..2c50992b1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.script @@ -0,0 +1,56 @@ +# !/bin/sh +# +# BDD Check: +# Load BDDs +# Make some operations (with reordering) +# Store BDDs +# +rm -f *.*/tmp +echo "---------------------------------------------------------------------------" +echo "---------- TESTING Load/Store with sifting, varnames & varauxids ----------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END1 +mi +50 +onl +varnames.ord +bl +4.bdd +4 +oil +varauxids.ord +bs +4a.bdd.tmp +4 +dr +4 +bs +4b.bdd.tmp +4 +mq +quit +END1 +echo "------------------------- ... END PHASE 1 ... -----------------------------" +./../testdddmp << END2 +mi +50 +onl +varnames.ord +slm +3 +bl +4b.bdd.tmp +4 +oil +varauxids.ord +bs +4c.bdd.tmp +4 +mq +quit +END2 +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 4.bdd 4a.bdd.tmp +diff --brief 4a.bdd.tmp 4c.bdd.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.out new file mode 100644 index 000000000..a883f515f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.out @@ -0,0 +1,28 @@ +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load ADD and Store ADD ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 0.add ... +Load: +-01 2 +-1- 1 +TestDddmp> File : Which BDDs [0..19]: Storing 0.add.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 1.add ... +Load: +-0001--------------------------------------------- 1 +-0010--------------------------------------------- 2 +-0100--------------------------------------------- 1 +-0101--------------------------------------------- 2 +-0111--------------------------------------------- 1 +-1000--------------------------------------------- 2 +-1010--------------------------------------------- 1 +-1011--------------------------------------------- 2 +-1101--------------------------------------------- 1 +-1110--------------------------------------------- 2 +TestDddmp> File : Which BDDs [0..19]: Storing 1.add.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.script new file mode 100755 index 000000000..9676c944e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.script @@ -0,0 +1,42 @@ +# !/bin/sh +# +# Check ADD: +# Load an ADD +# Store the same ADD +# Compare the two +# (done twice on a small - 0.add - and a medium - 1.add - ADD). +# +rm -f *.tmp* +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load ADD and Store ADD ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END1 +mi +3 +hlb +0.add +al +0.add +0 +as +0.add.tmp +0 +mq +mi +50 +hlb +1.add +al +1.add +1 +as +1.add.tmp +1 +mq +quit +END1 +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 0.add 0.add.tmp +diff --brief 1.add 1.add.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.out new file mode 100644 index 000000000..f10b48490 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.out @@ -0,0 +1,31 @@ +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load BDD and Store CNF ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.cnf.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +--------------------- TESTING Load CNF and Store BDD ---------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.cnf.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.script new file mode 100755 index 000000000..0b4295e29 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.script @@ -0,0 +1,50 @@ +# !/bin/sh +# +# Check CNF (short check - only NodeByNode method involved): +# Load BDDs +# Store corresponding CNF +# Read CNF +# Store corresponding BDD +# Compare original and final BDDs +# +rm -f *.tmp* +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load BDD and Store CNF ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END1 +mi +150 +hlc +4.cnf.bis +bl +4.bdd +0 +cs +4.cnf.tmp +0 +N +100 +mq +quit +END1 +echo "--------------------- TESTING Load CNF and Store BDD ----------------------" +./../testdddmp << END2 +mi +150 +hlc +4.cnf.bis +cl +4.cnf.tmp +0 +hw +bs +4.bdd.tmp +0 +mq +quit +END2 +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 4.cnf.bis 4.cnf.tmp +diff --brief 4.bdd.bis1 4.bdd.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.out new file mode 100644 index 000000000..d5cd7d3e0 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.out @@ -0,0 +1,102 @@ +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load BDD and Store CNF ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.node1.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.max1.tmp ... +Number of Clauses Stored = 103 +Number of New Variable Created Storing = 0 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.node2.tmp ... +Number of Clauses Stored = 114 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.node3.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.max2.tmp ... +Number of Clauses Stored = 103 +Number of New Variable Created Storing = 0 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.best1.tmp ... +Number of Clauses Stored = 53 +Number of New Variable Created Storing = 7 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.best2.tmp ... +Number of Clauses Stored = 69 +Number of New Variable Created Storing = 12 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +--------------------------------------------------------------------------- +--------------------- TESTING Load CNF and Store BDD ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.node2.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.node2.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.node3.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.node3.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.best1.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.best1.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.best2.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.best2.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.script new file mode 100755 index 000000000..dcef83f49 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.script @@ -0,0 +1,150 @@ +# !/bin/sh +# +# Check CNF (long check - all methods involved): +# Load BDDs +# Store corresponding CNF in different format: +# NodeByNode method -> file 4.node1.tmp +# MaxtermByMaxterm -> file 4.max1.tmp +# Best with different options: +# MaxEdge=-1 MaxPath= 0 -> similar to NodeByNode -> file 4.node2.tmp +# MaxEdge= 0 MaxPath=-1 -> similar to NodeByNode -> file 4.node3.tmp +# MaxEdge=-1 MaxPath=-1 -> = MaxtermByMaxterm -> file 4.max2.tmp +# MaxEdge= 1 MaxPath=-1 -> = Original Best -> file 4.best1.tmp +# MaxEdge= 1 MaxPath= 2 -> = Original Best, With Path Shorter than 3 +# file 4.best2.tmp +# Read CNF +# Store corresponding BDD +# Compare original and final BDDs +# +rm -f *.tmp* +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load BDD and Store CNF ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END1 +mi +150 +hlc +4.cnf.bis +bl +4.bdd +0 +cs +4.node1.tmp +0 +N +100 +cs +4.max1.tmp +0 +M +100 +cs +4.node2.tmp +0 +B +-1 +0 +100 +cs +4.node3.tmp +0 +B +0 +-1 +100 +cs +4.max2.tmp +0 +B +-1 +-1 +100 +cs +4.best1.tmp +0 +B +1 +-1 +100 +cs +4.best2.tmp +0 +B +1 +2 +100 +mq +quit +END1 +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load CNF and Store BDD ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END2 +mi +150 +hlc +4.node2.tmp +cl +4.node2.tmp +0 +hw +bs +4.node2.bdd.tmp +0 +mq +quit +END2 +./../testdddmp << END3 +mi +150 +hlc +4.node3.tmp +cl +4.node3.tmp +0 +hw +bs +4.node3.bdd.tmp +0 +mq +quit +END3 +./../testdddmp << END4 +mi +150 +hlc +4.best1.tmp +cl +4.best1.tmp +0 +hw +bs +4.best1.bdd.tmp +0 +mq +quit +END4 +./../testdddmp << END5 +mi +150 +hlc +4.best2.tmp +cl +4.best2.tmp +0 +hw +bs +4.best2.bdd.tmp +0 +mq +quit +END5 +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 4.max1 4.max1.tmp +diff --brief 4.max2 4.max2.tmp +diff --brief 4.bdd.bis1 4.node2.bdd.tmp +diff --brief 4.bdd.bis2 4.node3.bdd.tmp +diff --brief 4.bdd.bis3 4.best1.bdd.tmp +diff --brief 4.bdd.bis4 4.best2.bdd.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.tmp* diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/varauxids.ord b/resources/3rdparty/cudd-2.5.0/dddmp/exp/varauxids.ord new file mode 100644 index 000000000..9dc88561e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/varauxids.ord @@ -0,0 +1,50 @@ +1 +3 +5 +7 +9 +11 +13 +15 +17 +19 +21 +23 +25 +27 +29 +31 +33 +35 +37 +39 +41 +43 +45 +47 +49 +51 +53 +55 +57 +59 +61 +63 +65 +67 +69 +71 +73 +75 +77 +79 +81 +83 +85 +87 +89 +91 +93 +95 +97 +99 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/varnames.ord b/resources/3rdparty/cudd-2.5.0/dddmp/exp/varnames.ord new file mode 100644 index 000000000..541f21e65 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/varnames.ord @@ -0,0 +1,50 @@ +V1 +V2 +V3 +V4 +V5 +V6 +V7 +V8 +V9 +V10 +V11 +V12 +V13 +V14 +V15 +V16 +V17 +V18 +V19 +V20 +V21 +V22 +V23 +V24 +V25 +V26 +V27 +V28 +V29 +V30 +V31 +V32 +V33 +V34 +V35 +V36 +V37 +V38 +V39 +V40 +V41 +V42 +V43 +V44 +V45 +V46 +V47 +V48 +V49 +V50 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/zero.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/zero.bdd new file mode 100644 index 000000000..4c229f757 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/zero.bdd @@ -0,0 +1,13 @@ +.ver DDDMP-1.0 +.mode A +.varinfo 0 +.nnodes 1 +.nvars 100 +.nsuppvars 0 +.ids +.permids +.nroots 1 +.rootids -1 +.nodes +1 T 1 0 0 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/testdddmp.c b/resources/3rdparty/cudd-2.5.0/dddmp/testdddmp.c new file mode 100644 index 000000000..6879dccb6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/testdddmp.c @@ -0,0 +1,2279 @@ +/**CFile********************************************************************** + + FileName [testdddmp.c] + + PackageName [dddmp] + + Synopsis [A simple test function for Dddmp package] + + Description [This program constitutes a simple test program + for the dddmp library (version 2.0). + A simple interactive command selection allow the users to perform the + main operation on BDDs, ADDs, and CNF, such as loading and storing. + It can work also as a BDD calculators. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include +#include +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMPTEST_MAX_FILENAME_LENGTH 256 +#define DDDMPTEST_MAX_STRING_LENGTH 80 +#define DDDMPTEST_MAX_OPERAND 20 +#define DDDMPTEST_MAX_VARIABLE 50 +#define DDDMP_MAX_BDDARRAY_LEN 1000 + +/**Enum************************************************************************ + + Synopsis [Message type for output messages] + + Description [Type supported by the output function to print-out + the proper message. + ] + +******************************************************************************/ + +typedef enum { + /* Int Messages */ + DDDMP_MESSAGE_MANAGER_VAR, + DDDMP_MESSAGE_BDD, + DDDMP_MESSAGE_BDD_ARRAY, + DDDMP_MESSAGE_SOURCE1, + DDDMP_MESSAGE_SOURCE2, + DDDMP_MESSAGE_DESTINATION, + DDDMP_MESSAGE_CUBE, + DDDMP_MESSAGE_INDEX, + DDDMP_MESSAGE_I_ID, + DDDMP_MESSAGE_EDGE_MAX, + DDDMP_MESSAGE_LENGHT_MAX, + DDDMP_MESSAGE_REORDERING, + /* String Messages */ + DDDMP_MESSAGE_PROMPT, + DDDMP_MESSAGE_FILE, + DDDMP_MESSAGE_OP, + DDDMP_MESSAGE_FORMAT +} Dddmp_MessageType; + +#if !defined(RAND_MAX) && defined(sun) && defined(sparc) +#define RAND_MAX 2147483647 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct dddmpVarInfo { + /* + * Local Information + */ + + int nDdVars; /* Local Manager Number of Variables */ + char **rootNames; /* Root Names */ + + /* + * Header File Information + */ + + Dddmp_DecompType ddType; + + int nVars; /* File Manager Number of Variables */ + int nSuppVars; /* File Structure Number of Variables */ + + int varNamesFlagUpdate; /* 0 to NOT Update */ + char **suppVarNames; + char **orderedVarNames; + + int varIdsFlagUpdate; /* 0 to NOT Update */ + int *varIds; /* File ids - nSuppVars size */ + int *varIdsAll; /* ALL ids - nVars size */ + + int varComposeIdsFlagUpdate; /* 0 to NOT Update */ + int *varComposeIds; /* File permids - nSuppVars size */ + int *varComposeIdsAll; /* ALL permids - nVars size */ + + int varAuxIdsFlagUpdate; /* 0 to NOT Update */ + int *varAuxIds; /* File auxids - nSuppVars size */ + int *varAuxIdsAll; /* ALL auxids - nVars size */ + + int nRoots; +} dddmpVarInfo_t; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +Dddmp_RootMatchType rootmatchmode; +Dddmp_VarMatchType varmatchmode; +Dddmp_VarInfoType varoutinfo; +char varname[DDDMPTEST_MAX_STRING_LENGTH]; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdManager *ManagerInit (dddmpVarInfo_t *varInfo); +static void ManagerQuit (DdManager **ddMgr, dddmpVarInfo_t *varInfo); +static int OneCreate(DdManager *ddMgr, DdNode **operandBdd); +static int BddZeroCreate(DdManager *ddMgr, DdNode **operandBdd); +static int LeafCreate(DdManager *ddMgr, DdNode **operandBdd); +static int BddCreate(DdManager *ddMgr, DdNode **operandBdd); +static int A2B(void); +static int B2A(void); +static int HeaderLoadBdd(dddmpVarInfo_t *varInfo); +static int HeaderLoadCnf(dddmpVarInfo_t *varInfo); +static int HeaderWrite(dddmpVarInfo_t *varInfo); +static int Help(void); +static int OrderNamesLoad(dddmpVarInfo_t *varInfo); +static int IntArrayLoad(dddmpVarInfo_t *varInfo, const char *mode); +static int BddLoad(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int BddArrayLoad(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int AddLoad(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int AddArrayLoad(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int BddLoadCnf(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int BddArrayLoadCnf(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int Operation(DdManager *ddMgr, DdNode **operandBdd); +static int BddStore(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int BddArrayStore(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int AddStore(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int AddArrayStore(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int BddStoreCnf(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int BddArrayStoreCnf(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int DynamicReordering(DdManager *ddMgr); +static int SetLoadMatchmode(); +static int CompleteInfoStruct(Dddmp_DecompType ddType, int nVars, int nSuppVars, char **suppVarNames, char **orderedVarNames, int *varIds, int *varComposeIds, int *varAuxIds, int nRoots, dddmpVarInfo_t *varInfo); +static void ReadInt(Dddmp_MessageType message, int *i); +static void ReadString(Dddmp_MessageType message, char string[]); + +/**AutomaticEnd***************************************************************/ + +int +main( + int argc, + char **argv + ) +{ + DdManager *ddMgr = NULL; + DdNode **operandBdd = NULL; + DdNode ***operandBddArray = NULL; + int *operandBddArraySize = NULL; + char *row = NULL; + dddmpVarInfo_t varInfo; + int i; + + /*--------------------- Echo command line and arguments -------------------*/ + + fprintf (stdout, "#"); + for (i=0; i1) { + Help(); + } + + /*-------------------------- Init Array of BDDs ---------------------------*/ + + rootmatchmode = DDDMP_ROOT_MATCHLIST; +#if 1 + varmatchmode = DDDMP_VAR_MATCHIDS; +#else + varmatchmode = DDDMP_VAR_MATCHNAMES; +#endif + varoutinfo = DDDMP_VARIDS; + + row = DDDMP_ALLOC (char, DDDMPTEST_MAX_STRING_LENGTH); + Dddmp_CheckAndReturn (row==NULL, "Allocation error."); + + operandBdd = DDDMP_ALLOC (DdNode *, DDDMPTEST_MAX_OPERAND); + Dddmp_CheckAndReturn (operandBdd==NULL, "Allocation error."); + + operandBddArray = DDDMP_ALLOC (DdNode **, DDDMPTEST_MAX_OPERAND); + Dddmp_CheckAndReturn (operandBddArray==NULL, "Allocation error."); + + operandBddArraySize = DDDMP_ALLOC (int, DDDMPTEST_MAX_OPERAND); + Dddmp_CheckAndReturn (operandBddArraySize==NULL, "Allocation error."); + + for (i=0; inDdVars = nVars; + + varInfo->rootNames = NULL; + varInfo->ddType = DDDMP_NONE; + varInfo->nVars = (-1); + varInfo->nSuppVars = (-1); + varInfo->varNamesFlagUpdate = 1; + varInfo->suppVarNames = NULL; + varInfo->orderedVarNames = NULL; + varInfo->varIdsFlagUpdate = 1; + varInfo->varIds = NULL; + varInfo->varIdsAll = NULL; + varInfo->varComposeIdsFlagUpdate = 1; + varInfo->varComposeIds = NULL; + varInfo->varComposeIdsAll = NULL; + varInfo->varAuxIdsFlagUpdate = 1; + varInfo->varAuxIds = NULL; + varInfo->varAuxIdsAll = NULL; + varInfo->nRoots = (-1); + + /*------------------------------ Init DD Manager --------------------------*/ + + ddMgr = Cudd_Init (nVars, 0, CUDD_UNIQUE_SLOTS, + CUDD_CACHE_SLOTS, 0); + + Dddmp_CheckAndReturn (ddMgr==NULL, "DdManager NOT inizializated."); + + return (ddMgr); +} + +/**Function******************************************************************** + + Synopsis [Quit a CUDD Manager.] + + Description [Quit a CUDD Manager.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +ManagerQuit ( + DdManager **ddMgrPtr /* IN: CUDD Manager */, + dddmpVarInfo_t *varInfo /* IN: Internal Manager */ + ) +{ + if (*ddMgrPtr == NULL) { + return; + } + + fprintf (stdout, "Quitting CUDD Manager.\n"); + Cudd_Quit (*ddMgrPtr); + *ddMgrPtr = NULL; + + DddmpStrArrayFree (varInfo->rootNames, varInfo->nRoots); + DddmpStrArrayFree (varInfo->suppVarNames, varInfo->nSuppVars); + DddmpStrArrayFree (varInfo->orderedVarNames, varInfo->nVars); + DDDMP_FREE (varInfo->varIds); + DDDMP_FREE (varInfo->varIdsAll); + DDDMP_FREE (varInfo->varComposeIds); + DDDMP_FREE (varInfo->varComposeIdsAll); + DDDMP_FREE (varInfo->varAuxIds); + DDDMP_FREE (varInfo->varAuxIdsAll); + + varInfo->nDdVars = (-1); + varInfo->rootNames = NULL; + varInfo->ddType = DDDMP_NONE; + varInfo->nVars = (-1); + varInfo->nSuppVars = (-1); + varInfo->varNamesFlagUpdate = 1; + varInfo->suppVarNames = NULL; + varInfo->orderedVarNames = NULL; + varInfo->varIdsFlagUpdate = 1; + varInfo->varIds = NULL; + varInfo->varIdsAll = NULL; + varInfo->varComposeIdsFlagUpdate = 1; + varInfo->varComposeIds = NULL; + varInfo->varComposeIdsAll = NULL; + varInfo->varAuxIdsFlagUpdate = 1; + varInfo->varAuxIds = NULL; + varInfo->varAuxIdsAll = NULL; + varInfo->nRoots = (-1); + + return; +} + +/**Function******************************************************************** + + Synopsis [Create a One-BDD Leaf.] + + Description [Create a One-BDD Leaf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +OneCreate( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* In/OUT: Array of operand */ + ) +{ + int i; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_BDD, &i); + + operandBdd[i] = Cudd_ReadOne (ddMgr); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Create a Zero-BDD Leaf.] + + Description [Create a Zero-BDD Leaf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddZeroCreate( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN/OUT: array of operand */ + ) +{ + int i; + DdNode *one = NULL; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_BDD, &i); + + one = Cudd_ReadOne(ddMgr); + operandBdd[i] = Cudd_Not(one); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Create a One-Node BDD.] + + Description [Create a One-Node BDD.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +LeafCreate( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN/OUT: Array of operandBdd */ + ) +{ + int i, j; + DdNode *f = NULL; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_BDD, &i); + ReadInt (DDDMP_MESSAGE_INDEX, &j); + + f = Cudd_bddIthVar (ddMgr, j); + Cudd_Ref(f); + operandBdd[i] = f; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Create a BDD.] + + Description [Create a BDD: Variable index and number of cubes selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddCreate ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* array of operandBdd */ + ) +{ + DdNode **vet, *f, *g, *h; + int nb, nv, vi0, vi1, nc, i, j; + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_BDD, &nb); + + fprintf (stdout, "Variables Index [n-m] (m-n = number of variables): "); + fgets (row, DDDMPTEST_MAX_STRING_LENGTH, stdin); + sscanf (row, "%d-%d", &vi0, &vi1); + nv = vi1-vi0+1; + + ReadInt (DDDMP_MESSAGE_CUBE, &nc); + + /* Leaf Creation */ + vet = DDDMP_ALLOC (DdNode *, nv); + for (i=0; i 0.5 ) { + h = Cudd_bddAnd (ddMgr, g, vet[j]); + } else { + h = Cudd_bddAnd (ddMgr, g, Cudd_Not (vet[j])); + } + Cudd_Ref (h); + Cudd_RecursiveDeref (ddMgr, g); + g = h; + } + h = Cudd_bddOr (ddMgr, f, g); + Cudd_Ref (h); + Cudd_RecursiveDeref (ddMgr, f); + Cudd_RecursiveDeref (ddMgr, g); + f = h; + } + + operandBdd[nb] = f; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Transform a BDD from the ASCII to the Binary format].] + + Description [Input and Output file selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +A2B( + void +) +{ + fprintf (stderr, "Not yet Implemented!!!\n"); + + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Transform a BDD from the Binary to the ASCII format].] + + Description [Input and Output file selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +B2A( + void +) +{ + fprintf (stderr, "Not yet Implemented!!!\n"); + + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Read the Header of a file containing a BDD.] + + Description [File name Selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +HeaderLoadBdd ( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + Dddmp_DecompType ddType; + int retValue, nRoots, nVars, nSuppVars; + int *tmpVarIds = NULL; + int *tmpVarAuxIds = NULL; + int *tmpVarComposeIds = NULL; + char **tmpOrderedVarNames = NULL; + char **tmpSuppVarNames = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + + retValue = Dddmp_cuddHeaderLoad (&ddType, &nVars, &nSuppVars, + &tmpSuppVarNames, &tmpOrderedVarNames, &tmpVarIds, &tmpVarComposeIds, + &tmpVarAuxIds, &nRoots, fileName, NULL); + + if (retValue == DDDMP_FAILURE) { + return (DDDMP_FAILURE); + } + + /*---------------------------- Tail Operations ----------------------------*/ + + CompleteInfoStruct (ddType, nVars, nSuppVars, + tmpSuppVarNames, tmpOrderedVarNames, tmpVarIds, tmpVarComposeIds, + tmpVarAuxIds, nRoots, varInfo); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Read the Header of a file containing a CNF formula.] + + Description [File name Selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +HeaderLoadCnf ( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + int retValue, nRoots, nVars, nSuppVars; + int *tmpVarIds = NULL; + int *tmpVarComposeIds = NULL; + int *tmpVarAuxIds = NULL; + char **tmpOrderedVarNames = NULL; + char **tmpSuppVarNames = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + + retValue = Dddmp_cuddHeaderLoadCnf (&nVars, &nSuppVars, + &tmpSuppVarNames, &tmpOrderedVarNames, &tmpVarIds, &tmpVarComposeIds, + &tmpVarAuxIds, &nRoots, fileName, NULL); + + if (retValue == DDDMP_FAILURE) { + return (DDDMP_FAILURE); + } + + /*---------------------------- Tail Operations ----------------------------*/ + + CompleteInfoStruct (DDDMP_CNF, nVars, nSuppVars, + tmpSuppVarNames, tmpOrderedVarNames, tmpVarIds, tmpVarComposeIds, + tmpVarAuxIds, nRoots, varInfo); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Read the Header of a filke containing a BDD.] + + Description [File name Selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +HeaderWrite( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + int i; + + switch (varInfo->ddType) { + case DDDMP_BDD: + fprintf (stdout, "DD TYPE: DDDMP_BDD\n"); + break; + case DDDMP_ADD: + fprintf (stdout, "DD TYPE: DDDMP_ADD\n"); + break; + case DDDMP_CNF: + fprintf (stdout, "DD TYPE: DDDMP_CNF\n"); + break; + case DDDMP_NONE: + fprintf (stdout, "DD TYPE: NONE - Error\n"); + break; + } + + fprintf (stdout, "Number of variables: %d\n", varInfo->nVars); + fprintf (stdout, "Number of support variables: %d\n", varInfo->nSuppVars); + + if (varInfo->suppVarNames != NULL) { + fprintf (stdout, "suppVarNames: "); + for (i=0; inSuppVars; i++) { + if (varInfo->suppVarNames[i] != NULL) { + fprintf (stdout, "%s ", varInfo->suppVarNames[i]); + } + } + fprintf (stdout, "\n"); + } + + if (varInfo->orderedVarNames != NULL) { + fprintf (stdout, "orderedVarNames: "); + for (i=0; inVars; i++) { + if (varInfo->orderedVarNames[i] != NULL) { + fprintf (stdout, "%s ", varInfo->orderedVarNames[i]); + } + } + fprintf (stdout, "\n"); + } + + if (varInfo->varIds != NULL) { + fprintf (stdout, "varIds: "); + for (i=0; inSuppVars; i++) { + fprintf (stdout, "%d ", varInfo->varIds[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varIdsAll != NULL) { + fprintf (stdout, "varIds for ALL Manager Variables: "); + for (i=0; inVars; i++) { + fprintf (stdout, "%d ", varInfo->varIdsAll[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varComposeIds != NULL) { + fprintf (stdout, "varComposeIds: "); + for (i=0; inSuppVars; i++) { + fprintf (stdout, "%d ", varInfo->varComposeIds[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varComposeIdsAll != NULL) { + fprintf (stdout, "varComposeIds for ALL Manager Variables: "); + for (i=0; inVars; i++) { + fprintf (stdout, "%d ", varInfo->varComposeIdsAll[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varAuxIds != NULL) { + fprintf (stdout, "varAuxIds: "); + for (i=0; inSuppVars; i++) { + fprintf (stdout, "%d ", varInfo->varAuxIds[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varAuxIdsAll != NULL) { + fprintf (stdout, "varAuxIds for ALL Manager Variables: "); + for (i=0; inVars; i++) { + fprintf (stdout, "%d ", varInfo->varAuxIdsAll[i]); + } + fprintf (stdout, "\n"); + } + + fprintf (stdout, "Number of roots: %d\n", varInfo->nRoots); + + fflush (stdout); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Print the Help messages.] + + Description [Print the Help messages.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +Help( + void + ) +{ + fprintf (stdout, "Commands:\n"); + fprintf (stdout, "MAIN\n"); + + fprintf (stdout, "\thelp : Print this set of messages.\n"); + fprintf (stdout, "\tquit : Quit the test program.\n"); + + fprintf (stdout, "MANAGER OPERATIONs\n"); + + fprintf (stdout, + "\thmi : Manager Init (To do BEFORE any BDD/ADD operation).\n"); + fprintf (stdout, "\thmq : Manager Quit.\n"); + + fprintf (stdout, "LOAD\n"); + + fprintf (stdout, "\thlb : Load the header from a BDD/ADD file.\n"); + fprintf (stdout, "\thlc : Load the header from a CNF file.\n"); + fprintf (stdout, "\tbl : Load a BDD from a file.\n"); + fprintf (stdout, "\tbal : Load an Array-BDD from a file.\n"); + fprintf (stdout, "\tal : Load an ADD from a file.\n"); + fprintf (stdout, "\taal : Load an Array-ADD from a file.\n"); + fprintf (stdout, "\tcl : Load a CNF Formula from a file.\n"); + fprintf (stdout, "\tcal : Load an Array of CNF Formulas from a file.\n"); + + fprintf (stdout, "STORE\n"); + + fprintf (stdout, + "\thw : (Header) Write variable information on stdout.\n"); + fprintf (stdout, "\tbs : Store a BDD into a file.\n"); + fprintf (stdout, "\tbas : Store an Array-BDD from a file.\n"); + fprintf (stdout, "\tas : Store an ADD into a file.\n"); + fprintf (stdout, "\taas : Store an Array-ADD into a file.\n"); + fprintf (stdout, "\tcs : Store BDD as a CNF formula.\n"); + fprintf (stdout, "\tcas : Store and Array of BDDs as a CNF formula.\n"); + + fprintf (stdout, "MISC\n"); + + fprintf (stdout, "\tdr : Activate Dynamic Reordering.\n"); + fprintf (stdout, "\tonl : Load the order from a file (varNames).\n"); + fprintf (stdout, "\toil : Load the order from a file (varAuxIds).\n"); + fprintf (stdout, "\tcil : Load compose IDs from a file.\n"); + fprintf (stdout, "\tslm : Set Load matchmode for variables.\n"); + fprintf (stdout, + "\top : Operation (or, and, xor, not, =) between BDDs.\n"); + fprintf (stdout, "\toc : Create a terminal-one BDD.\n"); + fprintf (stdout, "\tzc : Create a terminal-zero BDD.\n"); + fprintf (stdout, "\tlc : Create a single variable BDD (1 node).\n"); + fprintf (stdout, "\tbc : Create a random BDD.\n"); + + fprintf (stdout, "NOT YET IMPLEMENTED\n"); + + fprintf (stdout, + "\ta2b : Convert a file from the ASCII format to the binary one.\n"); + fprintf (stdout, + "\tb2a : Convert a file from the binary format to the ASCII one.\n"); + + fprintf (stdout, "HINT\n"); + + fprintf (stdout, + " Command 'mi' has to be the first instruction to build:\n"); + fprintf (stdout, " a) The CUDD manager.\n"); + fprintf (stdout, + " b) The internal manager (containing name and variable IDs).\n"); + fprintf (stdout, + " After that load an header file with 'hlb' or 'hlc' to have proper\n"); + fprintf (stdout, + " names and ids for each subsequent load/store operation.\n"); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load the BDD order from a file (varNames).] + + Description [Load the BDD order from a file (varNames). + Force the orderedVarNames field of the varInfo structure, + i.e., the local manager, to be stucked to this array of values. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +OrderNamesLoad( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + FILE *fp = NULL; + int i; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + char tmpBuf[DDDMPTEST_MAX_STRING_LENGTH]; + char tmpName[DDDMPTEST_MAX_STRING_LENGTH]; + char **tmpOrderedVarNames = NULL; + + /*------------------------- Red New Var Names Array ----------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + + fp = fopen (fileName, "r"); + Dddmp_CheckAndReturn (fp==NULL, "Cannot open file."); + + varoutinfo = DDDMP_VARNAMES; + tmpOrderedVarNames = DDDMP_ALLOC (char *, varInfo->nDdVars); + + i=0; + while (fgets (tmpBuf, DDDMPTEST_MAX_STRING_LENGTH, fp)!=NULL) { + if (tmpBuf[0]=='#') { + continue; + } + + if (i>=varInfo->nDdVars) { + fprintf (stdout, + "Number of variables in files higher than DD manager vars (%d)\n", + varInfo->nDdVars); + fprintf (stdout, "Exceeding variables ignored\n"); + fprintf (stdout, + "You might increase the DDDMPTEST_MAX_VARIABLE constant\n"); + break; + } + + sscanf (tmpBuf, "%s", tmpName); + tmpOrderedVarNames[i] = DDDMP_ALLOC (char, (strlen (tmpName) + 1)); + if (tmpOrderedVarNames[i]==NULL) { + fprintf (stdout, "Error allocating memory\n"); + } else { + strcpy (tmpOrderedVarNames[i], tmpName); + } + i++; + } + + for ( ;inDdVars; i++) { + tmpOrderedVarNames[i] = NULL; + } + + fclose(fp); + + /*----------------------- Free and Set Var Names Array --------------------*/ + + DddmpStrArrayFree (varInfo->orderedVarNames, varInfo->nVars); + varInfo->orderedVarNames = tmpOrderedVarNames; + varInfo->nVars = varInfo->nDdVars; + + /* DO NOT ALLOW FURTHER UPDATES */ + varInfo->varNamesFlagUpdate = 0; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load the BDD order from a file (varauxids).] + + Description [Load the BDD order from a file (varauxids). + Force the + varAuxIds and varAuxIdsAll + or the + varComposeIds and varComposeIdsAll + fields of the varInfo structure, i.e., the local manager, to be + stucked to this array of values. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +IntArrayLoad ( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */, + const char *mode + ) +{ + FILE *fp = NULL; + int i; + int *tmpArray1 = NULL; + int *tmpArray2 = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + char buf[DDDMPTEST_MAX_STRING_LENGTH]; + + ReadString (DDDMP_MESSAGE_FILE, fileName); + + fp = fopen(fileName, "r"); + Dddmp_CheckAndReturn (fp==NULL, "Cannot open file."); + + tmpArray1 = DDDMP_ALLOC (int, varInfo->nDdVars); + tmpArray2 = DDDMP_ALLOC (int, varInfo->nDdVars); + Dddmp_CheckAndReturn (tmpArray1==NULL, "Error allocating memory."); + Dddmp_CheckAndReturn (tmpArray2==NULL, "Error allocating memory."); + + i=0; + while (fgets(buf, DDDMPTEST_MAX_STRING_LENGTH, fp)!=NULL) { + if (buf[0]=='#') { + continue; + } + if (i>=varInfo->nDdVars) { + fprintf (stdout, + "Number of variables in files higher than DD manager vars (%d)\n", + varInfo->nDdVars); + fprintf (stdout, "Exceeding variables ignored.\n"); + fprintf (stdout, "(Increase the DDDMPTEST_MAX_VARIABLE constant.)\n"); + break; + } + sscanf(buf, "%d", &tmpArray1[i]); + sscanf(buf, "%d", &tmpArray2[i++]); + } + + for (;inDdVars;i++) { + tmpArray1[i]= -1; + tmpArray2[i]= -1; + } + + fclose(fp); + + if (strcmp (mode, "oil") == 0) { + varInfo->varAuxIds = tmpArray1; + varInfo->varAuxIdsAll = tmpArray2; + + /* DO NOT ALLOW FURTHER UPDATES */ + varInfo->varAuxIdsFlagUpdate = 0; + } else { + if (strcmp (mode, "cil") == 0) { + varInfo->varComposeIds = tmpArray1; + varInfo->varComposeIdsAll = tmpArray2; + + /* DO NOT ALLOW FURTHER UPDATES */ + varInfo->varComposeIdsFlagUpdate = 0; + } + } + + varInfo->nVars = varInfo->nDdVars; + varInfo->nSuppVars = varInfo->nDdVars; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load a BDD from a file.] + + Description [Load a BDD from a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddLoad ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN: Operand BDD */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode *f = NULL; + int i; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD, &i); + + /*-------------------------------- Load BDD -------------------------------*/ + + fprintf (stdout, "Loading %s ...\n", fileName); + + f = Dddmp_cuddBddLoad (ddMgr, varmatchmode, varInfo->orderedVarNames, + varInfo->varIdsAll, varInfo->varComposeIdsAll, DDDMP_MODE_DEFAULT, + fileName, NULL); + + if (f==NULL) { + fprintf (stderr, "Dddmp Test Error : %s is not loaded from file\n", + fileName); + } else { + operandBdd[i] = f; + } + + /*---------------------------- Tail Operations ----------------------------*/ + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load an array of BDDs from a file.] + + Description [Load an array of BDDs from a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddArrayLoad( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand BDD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode **bddArray = NULL; + int i, j, nRoots; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + /*---------------------------- Load BDDs ----------------------------------*/ + + nRoots = Dddmp_cuddBddArrayLoad (ddMgr, rootmatchmode, + varInfo->rootNames, varmatchmode, + varInfo->orderedVarNames, varInfo->varIdsAll, varInfo->varComposeIdsAll, + DDDMP_MODE_DEFAULT, fileName, NULL, &bddArray); + + Dddmp_CheckAndReturn (nRoots>DDDMP_MAX_BDDARRAY_LEN, + "DDDMP_MAX_BDDARRAY_LEN exceeded by BDD array len (increase it)."); + + if (nRoots<=0) { + return (DDDMP_FAILURE); + } + + varInfo->nRoots = nRoots; + operandBddArray[i] = DDDMP_ALLOC (DdNode *, nRoots); + Dddmp_CheckAndReturn (operandBddArray[i]==NULL, "Allocation error."); + + for (j=0; jorderedVarNames, + varInfo->varIdsAll, varInfo->varComposeIdsAll, DDDMP_MODE_DEFAULT, + fileName, NULL); + + if (f==NULL) { + fprintf (stderr, "Dddmp Test Error : %s is not loaded from file\n", + fileName); + } else { + operandBdd[i] = f; + } + + /*---------------------------- Tail Operations ----------------------------*/ + + fprintf (stdout, "Load:\n"); + Cudd_PrintMinterm (ddMgr, f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load an array of ADDs from a file.] + + Description [Load an array of ADDs from a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +AddArrayLoad( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand BDD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + int i, j, nRoots; + DdNode **bddArray = NULL; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + /*------------------------------- Load ADDs -------------------------------*/ + + nRoots = Dddmp_cuddAddArrayLoad (ddMgr, rootmatchmode, + varInfo->rootNames, varmatchmode, + varInfo->orderedVarNames, varInfo->varIdsAll, varInfo->varComposeIdsAll, + DDDMP_MODE_DEFAULT, fileName, NULL, &bddArray); + + Dddmp_CheckAndReturn (nRoots>DDDMP_MAX_BDDARRAY_LEN, + "DDDMP_MAX_BDDARRAY_LEN exceeded by BDD array len (increase it)."); + + if (nRoots<=0) { + return (DDDMP_FAILURE); + } + + varInfo->nRoots = nRoots; + operandBddArray[i] = DDDMP_ALLOC (DdNode *, nRoots); + Dddmp_CheckAndReturn (operandBddArray[i]==NULL, "Allocation error."); + + for (j=0; jorderedVarNames, varInfo->varAuxIdsAll, varInfo->varComposeIdsAll, + loadingMode, fileName, NULL, &rootsPtr, &nRoots); + + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "Dddmp Test: Load From File Error.\n", failure); + + operandBdd[i] = rootsPtr[0]; + + /*---------------------------- Tail Operations ----------------------------*/ + + /* Free array */ + DDDMP_FREE (rootsPtr); + + return (DDDMP_SUCCESS); + + failure: + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Load a CNF formula from a file, and create an array of + BDDs. + ] + + Description [Load a CNF formula from a file, and create an array of + BDDs. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddArrayLoadCnf ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand BDD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode **rootsPtr = NULL; + Dddmp_DecompCnfLoadType loadingMode = DDDMP_CNF_MODE_CONJ_QUANT; + int i, j, nRoots, retValue; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + /*--------------------------- Loading BDDs --------------------------------*/ + + retValue = Dddmp_cuddBddArrayLoadCnf (ddMgr, rootmatchmode, + varInfo->rootNames, varmatchmode, + varInfo->orderedVarNames, varInfo->varIdsAll, varInfo->varComposeIdsAll, + loadingMode, fileName, NULL, &rootsPtr, &nRoots); + + Dddmp_CheckAndReturn (nRoots>DDDMP_MAX_BDDARRAY_LEN, + "DDDMP_MAX_BDDARRAY_LEN exceeded by BDD array len (increase it)."); + + if (nRoots<=0) { + return (DDDMP_FAILURE); + } + + varInfo->nRoots = nRoots; + operandBddArray[i] = DDDMP_ALLOC (DdNode *, nRoots); + Dddmp_CheckAndReturn (operandBddArray[i]==NULL, "Allocation error."); + + for (j=0; jorderedVarNames, + varInfo->varAuxIdsAll, DDDMP_MODE_TEXT, varoutinfo, fileName, NULL); + + Dddmp_CheckAndGotoLabel (retValue!=DDDMP_SUCCESS, "BDD NOT stored.", + failure); + + return (DDDMP_SUCCESS); + + failure: + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Store an Array of BDD in a file.] + + Description [Store an Array of BDD in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddArrayStore ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand BDD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + int i, retValue, nRoots; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + nRoots = operandBddArraySize[i]; + + /*----------------------------- Store BDDs -------------------------------*/ + + fprintf (stdout, "Storing Array of BDDs in file %s ...\n", fileName); + fflush (stdout); + + retValue = Dddmp_cuddBddArrayStore (ddMgr, NULL, nRoots, operandBddArray[i], + NULL, varInfo->orderedVarNames, varInfo->varAuxIdsAll, DDDMP_MODE_TEXT, + DDDMP_VARIDS, fileName, NULL); + + Dddmp_CheckAndGotoLabel (retValue!=DDDMP_SUCCESS, "BDD NOT stored.", + failure); + fprintf (stdout, "done.\n"); + + return (DDDMP_SUCCESS); + + failure: + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Store an ADD in a file.] + + Description [Store an ADD in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +AddStore( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN: operand Bdd */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode *f; + int i, retValue; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD, &i); + + fprintf (stdout, "Storing %s ...\n", fileName); + fflush (stdout); + f = operandBdd[i]; + +#if 0 + /* StQ Patch - CREATE temporary ADD to Store */ + f = Cudd_addResidue (ddMgr, 4, 3, 1, 1); + fprintf (stderr, "Store:\n"); + Cudd_PrintMinterm (ddMgr, f); + /* end ... StQ Patch */ +#endif + + retValue = Dddmp_cuddAddStore (ddMgr, NULL, f, varInfo->orderedVarNames, + varInfo->varAuxIdsAll, DDDMP_MODE_TEXT, varoutinfo, fileName, NULL); + + Dddmp_CheckAndReturn (retValue!=DDDMP_SUCCESS, "BDD NOT stored."); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Store a BDD in a file.] + + Description [Store a BDD in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +AddArrayStore ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand ADD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo + ) +{ + int i, retValue, nRoots; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + nRoots = operandBddArraySize[i]; + + fprintf (stdout, "Storing Array of BDDs in file %s ...\n", fileName); + fflush (stdout); + + retValue = Dddmp_cuddAddArrayStore (ddMgr, NULL, nRoots, operandBddArray[i], + NULL, varInfo->orderedVarNames, varInfo->varAuxIdsAll, DDDMP_MODE_TEXT, + DDDMP_VARIDS, fileName, NULL); + + Dddmp_CheckAndReturn (retValue!=DDDMP_SUCCESS, "BDD NOT stored."); + + fprintf (stdout, "done.\n"); + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Store a BDD as CNF format in a file.] + + Description [Store a BDD as CNF format in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddStoreCnf( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN: Array of operand ADD */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode *f = NULL; + Dddmp_DecompCnfStoreType storingMode = DDDMP_CNF_MODE_BEST; + int noHeader = 0; + int i, nVars, retValue, idInitial, varNewN, clauseNewN; + int edgeInTh = (-1); + int pathLengthTh = (-1); + int *tmpBddIds = NULL; + int *tmpCnfIds = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD, &i); + ReadString (DDDMP_MESSAGE_FORMAT, row); + + switch (row[0]) { + case 'N': + storingMode = DDDMP_CNF_MODE_NODE; + break; + case 'M': + storingMode = DDDMP_CNF_MODE_MAXTERM; + break; + case 'B': + storingMode = DDDMP_CNF_MODE_BEST; + ReadInt (DDDMP_MESSAGE_EDGE_MAX, &edgeInTh); + ReadInt (DDDMP_MESSAGE_LENGHT_MAX, &pathLengthTh); + break; + } + ReadInt (DDDMP_MESSAGE_I_ID, &idInitial); + + fprintf (stdout, "Storing %s ...\n", fileName); + fflush (stdout); + + f = operandBdd[i]; + + nVars = varInfo->nDdVars; + + /*------------ From BDD and CNF ids to Proper Array of ids ----------------*/ + + tmpBddIds = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (tmpBddIds==NULL, "Error allocating memory.", + failure); + tmpCnfIds = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (tmpBddIds==NULL, "Error allocating memory.", + failure); + + for (i=0; iorderedVarNames, tmpBddIds, NULL, tmpCnfIds, idInitial, + edgeInTh, pathLengthTh, fileName, NULL, &clauseNewN, &varNewN); + + Dddmp_CheckAndGotoLabel (retValue!=DDDMP_SUCCESS, "BDD NOT stored.", + failure); + + fprintf (stdout, "Number of Clauses Stored = %d\n", clauseNewN); + fprintf (stdout, "Number of New Variable Created Storing = %d\n", + varNewN); + fflush (stdout); + + DDDMP_FREE (tmpBddIds); + DDDMP_FREE (tmpCnfIds); + + return (DDDMP_SUCCESS); + + failure: + DDDMP_FREE (tmpBddIds); + DDDMP_FREE (tmpCnfIds); + + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Store a BDD as CNF format in a file.] + + Description [Store a BDD as CNF format in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddArrayStoreCnf( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand ADD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + Dddmp_DecompCnfStoreType storingMode = DDDMP_CNF_MODE_BEST; + int noHeader = 0; + int i, nVars, bddN, retValue, idInitial, varNewN, clauseNewN; + int edgeInTh = (-1); + int pathLengthTh = (-1); + int *tmpBddIds = NULL; + int *tmpCnfIds = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &bddN); + ReadString (DDDMP_MESSAGE_FORMAT, row); + switch (row[0]) { + case 'N': + storingMode = DDDMP_CNF_MODE_NODE; + break; + case 'M': + storingMode = DDDMP_CNF_MODE_MAXTERM; + break; + case 'B': + storingMode = DDDMP_CNF_MODE_BEST; + ReadInt (DDDMP_MESSAGE_EDGE_MAX, &edgeInTh); + ReadInt (DDDMP_MESSAGE_LENGHT_MAX, &pathLengthTh); + break; + } + ReadInt (DDDMP_MESSAGE_I_ID, &idInitial); + + nVars = varInfo->nDdVars; + + /*------------ From BDD and CNF ids to Proper Array of ids ----------------*/ + + tmpBddIds = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (tmpBddIds==NULL, "Allocation error."); + tmpCnfIds = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (tmpCnfIds==NULL, "Allocation error."); + + for (i=0; iorderedVarNames, + tmpBddIds, NULL, tmpCnfIds, idInitial, edgeInTh, pathLengthTh, fileName, + NULL, &varNewN, &clauseNewN); + + Dddmp_CheckAndGotoLabel (retValue!=DDDMP_SUCCESS, "BDD NOT stored.", + failure); + + fprintf (stdout, "Number of Clauses Stored = %d\n", clauseNewN); + fprintf (stdout, "Number of New Variable Created Storing = %d\n", + varNewN); + fflush (stdout); + + DDDMP_FREE (tmpBddIds); + DDDMP_FREE (tmpCnfIds); + + return (DDDMP_SUCCESS); + + failure: + DDDMP_FREE (tmpBddIds); + DDDMP_FREE (tmpCnfIds); + + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Dynamic Reordering BDDs.] + + Description [Dynamic Reordering BDDs using one of the allowed CUDD + methods.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DynamicReordering ( + DdManager *ddMgr /* IN: CUDD Manager */ + ) +{ + Cudd_ReorderingType approach = CUDD_REORDER_SIFT; + int method; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_REORDERING, &method); + approach = (Cudd_ReorderingType) method; + + Cudd_ReduceHeap (ddMgr, approach, 5); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Selects variable matching mode.] + + Description [Selects variable matching mode.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +SetLoadMatchmode ( + ) +{ + int sel; + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + fprintf (stdout, "Variable matchmode:\n"); + fprintf (stdout, "Match IDs (1)\n"); + fprintf (stdout, "Match permIDs (2)\n"); + fprintf (stdout, "Match names (must have been loaded) (3)\n"); + fprintf (stdout, "Match auxids (must have been loaded) (4)\n"); + fprintf (stdout, "Match composeids (must have been loaded) (5)\n"); + fprintf (stdout, "Your choice: "); + fflush (stdout); + + fgets (row, DDDMPTEST_MAX_STRING_LENGTH, stdin); + sscanf (row, "%d", &sel); + + switch (sel) { + case 1: + varmatchmode = DDDMP_VAR_MATCHIDS; + break; + case 2: + varmatchmode = DDDMP_VAR_MATCHPERMIDS; + break; + case 3: + varmatchmode = DDDMP_VAR_MATCHNAMES; + break; + case 4: + varmatchmode = DDDMP_VAR_MATCHAUXIDS; + break; + case 5: + varmatchmode = DDDMP_VAR_COMPOSEIDS; + break; + default: + fprintf (stderr, "Wrong choice!\n"); + break; + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Complete the internal manager structure for subsequent + BDD/ADD/CNF operations. + ] + + Description [Complete the internal manager structure for subsequent + BDD/ADD/CNF operations. + The phylosophy is simple: to have proper names and ids it is necessary + to load an header before each actual load/store operation. + An header load should initialize variable names, variable ids, + variable compose ids, and variable auxiliary ids for all variables + stored in the file. + This information has to be extended for all variables in the + *current* CUDD manager (before any store operation). + CompleteInfoStruct does this job. + Arrays varIds, varComposeIds, and varAuxIds contain information for + all the variable in the BDD/ADD/CNF while arrays varIdsAll, + varComposeIdsAll, and varAuxIdsAll contain information for *all* + variable in the current CUDD manager. + ] + + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +CompleteInfoStruct ( + Dddmp_DecompType ddType /* IN: selects the proper decomp type */, + int nVars /* IN: number of DD variables */, + int nSuppVars /* IN: number of support variables */, + char **suppVarNames /* IN: array of support variable names */, + char **orderedVarNames /* IN: array of variable names */, + int *varIds /* IN: array of variable ids */, + int *varComposeIds /* IN: array of permids ids */, + int *varAuxIds /* IN: array of variable aux ids */, + int nRoots /* IN: number of root in the file */, + dddmpVarInfo_t *varInfo /* IN: Variable Information */ + ) +{ + int i; + char tmpString[DDDMPTEST_MAX_STRING_LENGTH]; + + /*------------------------- Updates Variable Names ------------------------*/ + + DddmpStrArrayFree (varInfo->suppVarNames, varInfo->nSuppVars); + varInfo->suppVarNames = suppVarNames; + + if (varInfo->varNamesFlagUpdate == 1) { + + DddmpStrArrayFree (varInfo->orderedVarNames, varInfo->nVars); + + if (orderedVarNames != NULL) { + varInfo->orderedVarNames = orderedVarNames; + } else { + varInfo->orderedVarNames = DDDMP_ALLOC (char *, nVars); + Dddmp_CheckAndReturn (varInfo->orderedVarNames==NULL, + "Allocation error."); + + for (i=0; iorderedVarNames[i] = NULL; + } + + if (varInfo->suppVarNames != NULL) { + for (i=0; iorderedVarNames[i] = DDDMP_ALLOC (char, + (strlen (varInfo->suppVarNames[i]) + 1)); + strcpy (varInfo->orderedVarNames[i], varInfo->suppVarNames[i]); + } + } + + for (i=0; iorderedVarNames[i] == NULL) { + sprintf (tmpString, "DUMMY%d", i); + varInfo->orderedVarNames[i] = DDDMP_ALLOC (char, + (strlen (tmpString) + 1)); + strcpy (varInfo->orderedVarNames[i], tmpString); + } + } + } + } + + /*------------------------------ Updates IDs ------------------------------*/ + + DDDMP_FREE (varInfo->varIds); + varInfo->varIds = varIds; + + if (varInfo->varIdsFlagUpdate == 1) { + + /* Free Previously Allocated Memory */ + DDDMP_FREE (varInfo->varIdsAll); + + /* Allocate New Memory and Check */ + varInfo->varIdsAll = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (varInfo->varIdsAll==NULL, "Allocation error."); + + /* Set New Values */ + for (i=0; ivarIdsAll[i] = (-1); + } + + if (varInfo->varIds != NULL) { + for (i=0; ivarIdsAll[varInfo->varIds[i]] = varInfo->varIds[i]; + } + } + } + + + /*-------------------------- Updates Compose IDs --------------------------*/ + + DDDMP_FREE (varInfo->varComposeIds); + varInfo->varComposeIds = varComposeIds; + + if (varInfo->varComposeIdsFlagUpdate == 1) { + + /* Free Previously Allocated Memory */ + DDDMP_FREE (varInfo->varComposeIdsAll); + + /* Allocate New Memory and Check */ + varInfo->varComposeIdsAll = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (varInfo->varComposeIdsAll==NULL, + "Allocation error."); + + /* Set New Values */ + for (i=0; ivarComposeIdsAll[i] = (-1); + } + + if (varInfo->varComposeIds != NULL) { + for (i=0; ivarComposeIdsAll[varInfo->varIds[i]] = + varInfo->varComposeIds[i]; + } + } + } + + /*------------------------- Updates Auxiliary IDs -------------------------*/ + + DDDMP_FREE (varInfo->varAuxIds); + varInfo->varAuxIds = varAuxIds; + + if (varInfo->varAuxIdsFlagUpdate == 1) { + + /* Free Previously Allocated Memory */ + DDDMP_FREE (varInfo->varAuxIdsAll); + + /* Allocate New Memory and Check */ + varInfo->varAuxIdsAll = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (varInfo->varAuxIdsAll==NULL, "Allocation error."); + + /* Set New Values */ + for (i=0; ivarAuxIdsAll[i] = (-1); + } + + if (varInfo->varAuxIds != NULL) { + for (i=0; ivarAuxIdsAll[varInfo->varIds[i]] = varInfo->varAuxIds[i]; + } + } + } + + /*----------------------------- Updates Sizes -----------------------------*/ + + varInfo->ddType = ddType; + varInfo->nVars = nVars; + varInfo->nSuppVars = nSuppVars; + Dddmp_CheckAndReturn (varInfo->nDdVarsnVars, + "Local Manager with Not Enough Variables."); + varInfo->nRoots = nRoots; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Reads an integer value from standard input.] + + Description [Reads an integer value from standard input.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +ReadInt ( + Dddmp_MessageType message, + int *i + ) +{ + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + switch (message) { + case DDDMP_MESSAGE_MANAGER_VAR: + fprintf (stdout, "Number of Variables: "); + break; + case DDDMP_MESSAGE_BDD: + fprintf (stdout, "Which BDDs [0..%d]: ", + DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_BDD_ARRAY: + fprintf (stdout, "Which Array of BDDs [0..%d]: ", + DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_CUBE: + fprintf (stdout, "How many cubes [1..]: "); + break; + case DDDMP_MESSAGE_INDEX: + fprintf (stdout, "Index: "); + break; + case DDDMP_MESSAGE_SOURCE1: + fprintf (stdout, "Source1 [0..%d]: ", DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_SOURCE2: + fprintf (stdout, "Source2 [0..%d]: ", DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_DESTINATION: + fprintf (stdout, "Destination [0..%d]: ", DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_I_ID: + fprintf (stdout, "Initial ID : "); + break; + case DDDMP_MESSAGE_EDGE_MAX: + fprintf (stdout, + "Max Number of Edges (Insert cut-point from there on) : "); + break; + case DDDMP_MESSAGE_LENGHT_MAX: + fprintf (stdout, + "Max BDD-Path Length (Insert cut-point from there on) : "); + break; + case DDDMP_MESSAGE_REORDERING: + fprintf (stdout, "Reordering Approach (1..17): "); + break; + default: + fprintf (stdout, "Input Generic Integer: "); + break; + } + fflush (stdout); + + fgets (row, DDDMPTEST_MAX_STRING_LENGTH, stdin); + sscanf (row, "%d", i); + fflush (stdin); + + return; +} + + +/**Function******************************************************************** + + Synopsis [Reads a string from standard input.] + + Description [Reads a string from standard input.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +ReadString ( + Dddmp_MessageType message, + char string[] + ) +{ + char localString[DDDMPTEST_MAX_STRING_LENGTH]; + + switch (message) { + case DDDMP_MESSAGE_PROMPT: + fprintf (stdout, "TestDddmp> "); + break; + case DDDMP_MESSAGE_FILE: + fprintf (stdout, "File : "); + break; + case DDDMP_MESSAGE_OP: + fprintf (stdout, "Operation [or,and,xor,!,buf(=)] : "); + break; + case DDDMP_MESSAGE_FORMAT: + fprintf (stdout, "Format (Node=N, Maxterm=M, Best=B) : "); + break; + default: + fprintf (stdout, "Input Generic String : "); + break; + } + fflush (stdout); + + fgets (localString, DDDMPTEST_MAX_STRING_LENGTH, stdin); + sscanf (localString, "%s", string); + fflush (stdin); + + return; +} + + + + diff --git a/resources/3rdparty/cudd-2.5.0/epd/Makefile b/resources/3rdparty/cudd-2.5.0/epd/Makefile new file mode 100644 index 000000000..3b26bc9a9 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/epd/Makefile @@ -0,0 +1,64 @@ +# $Id$ +# +# epd -- extended precision +#--------------------------------------------------------------------------- +.SUFFIXES: .c .o .u + +CC = gcc +RANLIB = ranlib + +MFLAG = +ICFLAGS = -g -O6 -Wall +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) + +LINTFLAGS = -u -n + +# this is to create the lint library +LINTSWITCH = -o + +P = epd +PSRC = epd.c +PHDR = epd.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) + +WHERE = .. +INCLUDE = $(WHERE)/include + +#--------------------------- + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PSRC) $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +clean: + rm -f *.o *.u .pure *.warnings + +distclean: clean + rm -f lib*.a lib$(P).b llib-l$(P).ln tags *~ *.bak *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/epd/epd.c b/resources/3rdparty/cudd-2.5.0/epd/epd.c new file mode 100644 index 000000000..14f314fab --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/epd/epd.c @@ -0,0 +1,1344 @@ +/**CFile*********************************************************************** + + FileName [epd.c] + + PackageName [epd] + + Synopsis [Arithmetic functions with extended double precision.] + + Description [] + + SeeAlso [] + + Author [In-Ho Moon] + + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: epd.c,v 1.10 2004/08/13 18:20:30 fabio Exp $] + +******************************************************************************/ + +#include +#include +#include +#include +#include "util.h" +#include "epd.h" + + +/**Function******************************************************************** + + Synopsis [Allocates an EpDouble struct.] + + Description [Allocates an EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +EpDouble * +EpdAlloc(void) +{ + EpDouble *epd; + + epd = ALLOC(EpDouble, 1); + return(epd); +} + + +/**Function******************************************************************** + + Synopsis [Compares two EpDouble struct.] + + Description [Compares two EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdCmp(const char *key1, const char *key2) +{ + EpDouble *epd1 = (EpDouble *) key1; + EpDouble *epd2 = (EpDouble *) key2; + if (epd1->type.value != epd2->type.value || + epd1->exponent != epd2->exponent) { + return(1); + } + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Frees an EpDouble struct.] + + Description [Frees an EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdFree(EpDouble *epd) +{ + FREE(epd); +} + + +/**Function******************************************************************** + + Synopsis [Converts an arbitrary precision double value to a string.] + + Description [Converts an arbitrary precision double value to a string.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdGetString(EpDouble *epd, char *str) +{ + double value; + int exponent; + char *pos; + + if (IsNanDouble(epd->type.value)) { + sprintf(str, "NaN"); + return; + } else if (IsInfDouble(epd->type.value)) { + if (epd->type.bits.sign == 1) + sprintf(str, "-Inf"); + else + sprintf(str, "Inf"); + return; + } + + assert(epd->type.bits.exponent == EPD_MAX_BIN || + epd->type.bits.exponent == 0); + + EpdGetValueAndDecimalExponent(epd, &value, &exponent); + sprintf(str, "%e", value); + pos = strstr(str, "e"); + if (exponent >= 0) { + if (exponent < 10) + sprintf(pos + 1, "+0%d", exponent); + else + sprintf(pos + 1, "+%d", exponent); + } else { + exponent *= -1; + if (exponent < 10) + sprintf(pos + 1, "-0%d", exponent); + else + sprintf(pos + 1, "-%d", exponent); + } +} + + +/**Function******************************************************************** + + Synopsis [Converts double to EpDouble struct.] + + Description [Converts double to EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdConvert(double value, EpDouble *epd) +{ + epd->type.value = value; + epd->exponent = 0; + EpdNormalize(epd); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply(EpDouble *epd1, double value) +{ + EpDouble epd2; + double tmp; + int exponent; + + if (EpdIsNan(epd1) || IsNanDouble(value)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || IsInfDouble(value)) { + int sign; + + EpdConvert(value, &epd2); + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + EpdMakeInf(epd1, sign); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + + EpdConvert(value, &epd2); + tmp = epd1->type.value * epd2.type.value; + exponent = epd1->exponent + epd2.exponent; + epd1->type.value = tmp; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply2(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd1, sign); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + value = epd1->type.value * epd2->type.value; + exponent = epd1->exponent + epd2->exponent; + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply2Decimal(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd1, sign); + return; + } + + value = epd1->type.value * epd2->type.value; + exponent = epd1->exponent + epd2->exponent; + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalizeDecimal(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd3, sign); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + epd3->type.value = epd1->type.value * epd2->type.value; + epd3->exponent = epd1->exponent + epd2->exponent; + EpdNormalize(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply3Decimal(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd3, sign); + return; + } + + epd3->type.value = epd1->type.value * epd2->type.value; + epd3->exponent = epd1->exponent + epd2->exponent; + EpdNormalizeDecimal(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Divides two arbitrary precision double values.] + + Description [Divides two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdDivide(EpDouble *epd1, double value) +{ + EpDouble epd2; + double tmp; + int exponent; + + if (EpdIsNan(epd1) || IsNanDouble(value)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || IsInfDouble(value)) { + int sign; + + EpdConvert(value, &epd2); + if (EpdIsInf(epd1) && IsInfDouble(value)) { + EpdMakeNan(epd1); + } else if (EpdIsInf(epd1)) { + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + EpdMakeInf(epd1, sign); + } else { + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + EpdMakeZero(epd1, sign); + } + return; + } + + if (value == 0.0) { + EpdMakeNan(epd1); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + + EpdConvert(value, &epd2); + tmp = epd1->type.value / epd2.type.value; + exponent = epd1->exponent - epd2.exponent; + epd1->type.value = tmp; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Divides two arbitrary precision double values.] + + Description [Divides two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdDivide2(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + EpdMakeNan(epd1); + } else if (EpdIsInf(epd1)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd1, sign); + } else { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeZero(epd1, sign); + } + return; + } + + if (epd2->type.value == 0.0) { + EpdMakeNan(epd1); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + value = epd1->type.value / epd2->type.value; + exponent = epd1->exponent - epd2->exponent; + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Divides two arbitrary precision double values.] + + Description [Divides two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdDivide3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd3); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + EpdMakeNan(epd3); + } else if (EpdIsInf(epd1)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd3, sign); + } else { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeZero(epd3, sign); + } + return; + } + + if (epd2->type.value == 0.0) { + EpdMakeNan(epd3); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + epd3->type.value = epd1->type.value / epd2->type.value; + epd3->exponent = epd1->exponent - epd2->exponent; + EpdNormalize(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Adds two arbitrary precision double values.] + + Description [Adds two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdAdd(EpDouble *epd1, double value) +{ + EpDouble epd2; + double tmp; + int exponent, diff; + + if (EpdIsNan(epd1) || IsNanDouble(value)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || IsInfDouble(value)) { + int sign; + + EpdConvert(value, &epd2); + if (EpdIsInf(epd1) && IsInfDouble(value)) { + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + if (sign == 1) + EpdMakeNan(epd1); + } else if (EpdIsInf(&epd2)) { + EpdCopy(&epd2, epd1); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + + EpdConvert(value, &epd2); + if (epd1->exponent > epd2.exponent) { + diff = epd1->exponent - epd2.exponent; + if (diff <= EPD_MAX_BIN) + tmp = epd1->type.value + epd2.type.value / pow((double)2.0, (double)diff); + else + tmp = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2.exponent) { + diff = epd2.exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) + tmp = epd1->type.value / pow((double)2.0, (double)diff) + epd2.type.value; + else + tmp = epd2.type.value; + exponent = epd2.exponent; + } else { + tmp = epd1->type.value + epd2.type.value; + exponent = epd1->exponent; + } + epd1->type.value = tmp; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Adds two arbitrary precision double values.] + + Description [Adds two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdAdd2(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent, diff; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + if (sign == 1) + EpdMakeNan(epd1); + } else if (EpdIsInf(epd2)) { + EpdCopy(epd2, epd1); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + if (epd1->exponent > epd2->exponent) { + diff = epd1->exponent - epd2->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value + + epd2->type.value / pow((double)2.0, (double)diff); + } else + value = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2->exponent) { + diff = epd2->exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value / pow((double)2.0, (double)diff) + + epd2->type.value; + } else + value = epd2->type.value; + exponent = epd2->exponent; + } else { + value = epd1->type.value + epd2->type.value; + exponent = epd1->exponent; + } + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Adds two arbitrary precision double values.] + + Description [Adds two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + double value; + int exponent, diff; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd3); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + if (sign == 1) + EpdMakeNan(epd3); + else + EpdCopy(epd1, epd3); + } else if (EpdIsInf(epd1)) { + EpdCopy(epd1, epd3); + } else { + EpdCopy(epd2, epd3); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + if (epd1->exponent > epd2->exponent) { + diff = epd1->exponent - epd2->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value + + epd2->type.value / pow((double)2.0, (double)diff); + } else + value = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2->exponent) { + diff = epd2->exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value / pow((double)2.0, (double)diff) + + epd2->type.value; + } else + value = epd2->type.value; + exponent = epd2->exponent; + } else { + value = epd1->type.value + epd2->type.value; + exponent = epd1->exponent; + } + epd3->type.value = value; + epd3->exponent = exponent; + EpdNormalize(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Subtracts two arbitrary precision double values.] + + Description [Subtracts two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdSubtract(EpDouble *epd1, double value) +{ + EpDouble epd2; + double tmp; + int exponent, diff; + + if (EpdIsNan(epd1) || IsNanDouble(value)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || IsInfDouble(value)) { + int sign; + + EpdConvert(value, &epd2); + if (EpdIsInf(epd1) && IsInfDouble(value)) { + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + if (sign == 0) + EpdMakeNan(epd1); + } else if (EpdIsInf(&epd2)) { + EpdCopy(&epd2, epd1); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + + EpdConvert(value, &epd2); + if (epd1->exponent > epd2.exponent) { + diff = epd1->exponent - epd2.exponent; + if (diff <= EPD_MAX_BIN) + tmp = epd1->type.value - epd2.type.value / pow((double)2.0, (double)diff); + else + tmp = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2.exponent) { + diff = epd2.exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) + tmp = epd1->type.value / pow((double)2.0, (double)diff) - epd2.type.value; + else + tmp = epd2.type.value * (double)(-1.0); + exponent = epd2.exponent; + } else { + tmp = epd1->type.value - epd2.type.value; + exponent = epd1->exponent; + } + epd1->type.value = tmp; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Subtracts two arbitrary precision double values.] + + Description [Subtracts two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdSubtract2(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent, diff; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + if (sign == 0) + EpdMakeNan(epd1); + } else if (EpdIsInf(epd2)) { + EpdCopy(epd2, epd1); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + if (epd1->exponent > epd2->exponent) { + diff = epd1->exponent - epd2->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value - + epd2->type.value / pow((double)2.0, (double)diff); + } else + value = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2->exponent) { + diff = epd2->exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value / pow((double)2.0, (double)diff) - + epd2->type.value; + } else + value = epd2->type.value * (double)(-1.0); + exponent = epd2->exponent; + } else { + value = epd1->type.value - epd2->type.value; + exponent = epd1->exponent; + } + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Subtracts two arbitrary precision double values.] + + Description [Subtracts two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + double value; + int exponent, diff; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd3); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + if (sign == 0) + EpdCopy(epd1, epd3); + else + EpdMakeNan(epd3); + } else if (EpdIsInf(epd1)) { + EpdCopy(epd1, epd1); + } else { + sign = epd2->type.bits.sign ^ 0x1; + EpdMakeInf(epd3, sign); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + if (epd1->exponent > epd2->exponent) { + diff = epd1->exponent - epd2->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value - + epd2->type.value / pow((double)2.0, (double)diff); + } else + value = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2->exponent) { + diff = epd2->exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value / pow((double)2.0, (double)diff) - + epd2->type.value; + } else + value = epd2->type.value * (double)(-1.0); + exponent = epd2->exponent; + } else { + value = epd1->type.value - epd2->type.value; + exponent = epd1->exponent; + } + epd3->type.value = value; + epd3->exponent = exponent; + EpdNormalize(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Computes arbitrary precision pow of base 2.] + + Description [Computes arbitrary precision pow of base 2.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdPow2(int n, EpDouble *epd) +{ + if (n <= EPD_MAX_BIN) { + EpdConvert(pow((double)2.0, (double)n), epd); + } else { + EpDouble epd1, epd2; + int n1, n2; + + n1 = n / 2; + n2 = n - n1; + EpdPow2(n1, &epd1); + EpdPow2(n2, &epd2); + EpdMultiply3(&epd1, &epd2, epd); + } +} + + +/**Function******************************************************************** + + Synopsis [Computes arbitrary precision pow of base 2.] + + Description [Computes arbitrary precision pow of base 2.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdPow2Decimal(int n, EpDouble *epd) +{ + if (n <= EPD_MAX_BIN) { + epd->type.value = pow((double)2.0, (double)n); + epd->exponent = 0; + EpdNormalizeDecimal(epd); + } else { + EpDouble epd1, epd2; + int n1, n2; + + n1 = n / 2; + n2 = n - n1; + EpdPow2Decimal(n1, &epd1); + EpdPow2Decimal(n2, &epd2); + EpdMultiply3Decimal(&epd1, &epd2, epd); + } +} + + +/**Function******************************************************************** + + Synopsis [Normalize an arbitrary precision double value.] + + Description [Normalize an arbitrary precision double value.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdNormalize(EpDouble *epd) +{ + int exponent; + + if (IsNanOrInfDouble(epd->type.value)) { + epd->exponent = 0; + return; + } + + exponent = EpdGetExponent(epd->type.value); + if (exponent == EPD_MAX_BIN) + return; + exponent -= EPD_MAX_BIN; + epd->type.bits.exponent = EPD_MAX_BIN; + epd->exponent += exponent; +} + + +/**Function******************************************************************** + + Synopsis [Normalize an arbitrary precision double value.] + + Description [Normalize an arbitrary precision double value.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdNormalizeDecimal(EpDouble *epd) +{ + int exponent; + + if (IsNanOrInfDouble(epd->type.value)) { + epd->exponent = 0; + return; + } + + exponent = EpdGetExponentDecimal(epd->type.value); + epd->type.value /= pow((double)10.0, (double)exponent); + epd->exponent += exponent; +} + + +/**Function******************************************************************** + + Synopsis [Returns value and decimal exponent of EpDouble.] + + Description [Returns value and decimal exponent of EpDouble.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdGetValueAndDecimalExponent(EpDouble *epd, double *value, int *exponent) +{ + EpDouble epd1, epd2; + + if (EpdIsNanOrInf(epd)) + return; + + if (EpdIsZero(epd)) { + *value = 0.0; + *exponent = 0; + return; + } + + epd1.type.value = epd->type.value; + epd1.exponent = 0; + EpdPow2Decimal(epd->exponent, &epd2); + EpdMultiply2Decimal(&epd1, &epd2); + + *value = epd1.type.value; + *exponent = epd1.exponent; +} + +/**Function******************************************************************** + + Synopsis [Returns the exponent value of a double.] + + Description [Returns the exponent value of a double.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdGetExponent(double value) +{ + int exponent; + EpDouble epd; + + epd.type.value = value; + exponent = epd.type.bits.exponent; + return(exponent); +} + + +/**Function******************************************************************** + + Synopsis [Returns the decimal exponent value of a double.] + + Description [Returns the decimal exponent value of a double.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdGetExponentDecimal(double value) +{ + char *pos, str[24]; + int exponent; + + sprintf(str, "%E", value); + pos = strstr(str, "E"); + sscanf(pos, "E%d", &exponent); + return(exponent); +} + + +/**Function******************************************************************** + + Synopsis [Makes EpDouble Inf.] + + Description [Makes EpDouble Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMakeInf(EpDouble *epd, int sign) +{ + epd->type.bits.mantissa1 = 0; + epd->type.bits.mantissa0 = 0; + epd->type.bits.exponent = EPD_EXP_INF; + epd->type.bits.sign = sign; + epd->exponent = 0; +} + + +/**Function******************************************************************** + + Synopsis [Makes EpDouble Zero.] + + Description [Makes EpDouble Zero.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMakeZero(EpDouble *epd, int sign) +{ + epd->type.bits.mantissa1 = 0; + epd->type.bits.mantissa0 = 0; + epd->type.bits.exponent = 0; + epd->type.bits.sign = sign; + epd->exponent = 0; +} + + +/**Function******************************************************************** + + Synopsis [Makes EpDouble NaN.] + + Description [Makes EpDouble NaN.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMakeNan(EpDouble *epd) +{ + epd->type.nan.mantissa1 = 0; + epd->type.nan.mantissa0 = 0; + epd->type.nan.quiet_bit = 1; + epd->type.nan.exponent = EPD_EXP_INF; + epd->type.nan.sign = 1; + epd->exponent = 0; +} + + +/**Function******************************************************************** + + Synopsis [Copies a EpDouble struct.] + + Description [Copies a EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdCopy(EpDouble *from, EpDouble *to) +{ + to->type.value = from->type.value; + to->exponent = from->exponent; +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is Inf.] + + Description [Checks whether the value is Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdIsInf(EpDouble *epd) +{ + return(IsInfDouble(epd->type.value)); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is Zero.] + + Description [Checks whether the value is Zero.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdIsZero(EpDouble *epd) +{ + if (epd->type.value == 0.0) + return(1); + else + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is NaN.] + + Description [Checks whether the value is NaN.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdIsNan(EpDouble *epd) +{ + return(IsNanDouble(epd->type.value)); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is NaN or Inf.] + + Description [Checks whether the value is NaN or Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdIsNanOrInf(EpDouble *epd) +{ + return(IsNanOrInfDouble(epd->type.value)); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is Inf.] + + Description [Checks whether the value is Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +IsInfDouble(double value) +{ + EpType val; + + val.value = value; + if (val.bits.exponent == EPD_EXP_INF && + val.bits.mantissa0 == 0 && + val.bits.mantissa1 == 0) { + if (val.bits.sign == 0) + return(1); + else + return(-1); + } + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is NaN.] + + Description [Checks whether the value is NaN.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +IsNanDouble(double value) +{ + EpType val; + + val.value = value; + if (val.nan.exponent == EPD_EXP_INF && + val.nan.sign == 1 && + val.nan.quiet_bit == 1 && + val.nan.mantissa0 == 0 && + val.nan.mantissa1 == 0) { + return(1); + } + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is NaN or Inf.] + + Description [Checks whether the value is NaN or Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +IsNanOrInfDouble(double value) +{ + EpType val; + + val.value = value; + if (val.nan.exponent == EPD_EXP_INF && + val.nan.mantissa0 == 0 && + val.nan.mantissa1 == 0 && + (val.nan.sign == 1 || val.nan.quiet_bit == 0)) { + return(1); + } + return(0); +} diff --git a/resources/3rdparty/cudd-2.5.0/epd/epd.h b/resources/3rdparty/cudd-2.5.0/epd/epd.h new file mode 100644 index 000000000..4b538c016 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/epd/epd.h @@ -0,0 +1,200 @@ +/**CHeaderFile***************************************************************** + + FileName [epd.h] + + PackageName [epd] + + Synopsis [The University of Colorado extended double precision package.] + + Description [arithmetic functions with extended double precision.] + + SeeAlso [] + + Author [In-Ho Moon] + + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: epd.h,v 1.9 2004/08/13 18:20:30 fabio Exp $] + +******************************************************************************/ + +#ifndef _EPD +#define _EPD + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define EPD_MAX_BIN 1023 +#define EPD_MAX_DEC 308 +#define EPD_EXP_INF 0x7ff + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + +/**Struct********************************************************************** + + Synopsis [IEEE double struct.] + + Description [IEEE double struct.] + + SeeAlso [] + +******************************************************************************/ +#ifdef EPD_BIG_ENDIAN +struct IeeeDoubleStruct { /* BIG_ENDIAN */ + unsigned int sign: 1; + unsigned int exponent: 11; + unsigned int mantissa0: 20; + unsigned int mantissa1: 32; +}; +#else +struct IeeeDoubleStruct { /* LITTLE_ENDIAN */ + unsigned int mantissa1: 32; + unsigned int mantissa0: 20; + unsigned int exponent: 11; + unsigned int sign: 1; +}; +#endif + +/**Struct********************************************************************** + + Synopsis [IEEE double NaN struct.] + + Description [IEEE double NaN struct.] + + SeeAlso [] + +******************************************************************************/ +#ifdef EPD_BIG_ENDIAN +struct IeeeNanStruct { /* BIG_ENDIAN */ + unsigned int sign: 1; + unsigned int exponent: 11; + unsigned int quiet_bit: 1; + unsigned int mantissa0: 19; + unsigned int mantissa1: 32; +}; +#else +struct IeeeNanStruct { /* LITTLE_ENDIAN */ + unsigned int mantissa1: 32; + unsigned int mantissa0: 19; + unsigned int quiet_bit: 1; + unsigned int exponent: 11; + unsigned int sign: 1; +}; +#endif + +/**Struct********************************************************************** + + Synopsis [Extended precision double to keep very large value.] + + Description [Extended precision double to keep very large value.] + + SeeAlso [] + +******************************************************************************/ +union EpTypeUnion { + double value; + struct IeeeDoubleStruct bits; + struct IeeeNanStruct nan; +}; + +struct EpDoubleStruct { + union EpTypeUnion type; + int exponent; +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ +typedef struct EpDoubleStruct EpDouble; +typedef struct IeeeDoubleStruct IeeeDouble; +typedef struct IeeeNanStruct IeeeNan; +typedef union EpTypeUnion EpType; + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern EpDouble *EpdAlloc(void); +extern int EpdCmp(const char *key1, const char *key2); +extern void EpdFree(EpDouble *epd); +extern void EpdGetString(EpDouble *epd, char *str); +extern void EpdConvert(double value, EpDouble *epd); +extern void EpdMultiply(EpDouble *epd1, double value); +extern void EpdMultiply2(EpDouble *epd1, EpDouble *epd2); +extern void EpdMultiply2Decimal(EpDouble *epd1, EpDouble *epd2); +extern void EpdMultiply3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdMultiply3Decimal(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdDivide(EpDouble *epd1, double value); +extern void EpdDivide2(EpDouble *epd1, EpDouble *epd2); +extern void EpdDivide3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdAdd(EpDouble *epd1, double value); +extern void EpdAdd2(EpDouble *epd1, EpDouble *epd2); +extern void EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdSubtract(EpDouble *epd1, double value); +extern void EpdSubtract2(EpDouble *epd1, EpDouble *epd2); +extern void EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdPow2(int n, EpDouble *epd); +extern void EpdPow2Decimal(int n, EpDouble *epd); +extern void EpdNormalize(EpDouble *epd); +extern void EpdNormalizeDecimal(EpDouble *epd); +extern void EpdGetValueAndDecimalExponent(EpDouble *epd, double *value, int *exponent); +extern int EpdGetExponent(double value); +extern int EpdGetExponentDecimal(double value); +extern void EpdMakeInf(EpDouble *epd, int sign); +extern void EpdMakeZero(EpDouble *epd, int sign); +extern void EpdMakeNan(EpDouble *epd); +extern void EpdCopy(EpDouble *from, EpDouble *to); +extern int EpdIsInf(EpDouble *epd); +extern int EpdIsZero(EpDouble *epd); +extern int EpdIsNan(EpDouble *epd); +extern int EpdIsNanOrInf(EpDouble *epd); +extern int IsInfDouble(double value); +extern int IsNanDouble(double value); +extern int IsNanOrInfDouble(double value); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* _EPD */ diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/Makefile b/resources/3rdparty/cudd-2.5.0/mnemosyne/Makefile new file mode 100644 index 000000000..3c593a2a3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/Makefile @@ -0,0 +1,53 @@ +# $Id$ +# +# Makefile for the Mnemosyne memory allocation tracker. +# +# Marcus J. Ranum, 1990 +# +#Options: +# define MALLOC_IS_VOIDSTAR if your system's malloc is declared as a (void *) +# otherwise, it is assumed to be a (char *). a "mall_t" is typedeffed in +# mnemconf.h and mnemosyne.h to implement this. +OPTNS = -DMALLOC_IS_VOIDSTAR +#OPTNS = + +CC = cc +RANLIB = ranlib + +#compiler flags +CFLAGS = -g $(OPTNS) $(XCFLAGS) + +#loader flags +LDFLGS = + +HDRS = mnemosyne.h mnemconf.h + +all: mnemalyse libmnem.a + +mnemalyse: mnemalyse.o + $(CC) $(LDFLGS) -o $@ mnemalyse.o + +libmnem.a: mnemosyne.o + ar rcv $@ mnemosyne.o + $(RANLIB) $@ + +mtest: mtest.o libmnem.a + $(CC) $(LDFLGS) -o $@ mtest.o libmnem.a + +runmtest: all mtest + @echo "running memory waster" + mtest + @echo "press return for symbol list"; read ff + @cat mnem.syms + @echo "press return for waste analysis"; read ff + mnemalyse + +clean: + rm -f mtest core *.o mnem.dat mnem.syms + +distclean: clean + rm -f *.bak *~ libmnem.a mnemalyse + + +mnemosyne.o: Makefile mnemosyne.c $(HDRS) +mnemalyse.o: Makefile mnemalyse.c $(HDRS) diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/README b/resources/3rdparty/cudd-2.5.0/mnemosyne/README new file mode 100644 index 000000000..182bbd29e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/README @@ -0,0 +1,39 @@ + + This is a set of tools designed to help find memory leaks in +programs, and to locate memory-hogging functions. It's implemented as +a wrapper library that goes around malloc/free/etc, and an include file +that "intercepts" calls to malloc/free/etc and makes them call the +wrappers. Thus, you can get extensive memory profiling and leak +detection by just adding one #include directive at the top of your +file and recompiling/linking. + + Unlike some similar tools I've seen in the past, this makes +sure that it keeps its on-disk data current, so that if the program +is crashed or interrupted, the results still have some validity. The +on-disk data is as compacted as I could make it, to give a chance of +this being useable in debugging big memory pigs. It adds some cost +in performance and memory size (since it keeps its own in-memory +symbol tables) but since it's only a debugging tool, I think the +cost is worth the benefit. This library can also be used to track +only allocations in a single module, or set of modules, and doesn't +interfere with calls to the "real" malloc() that are made in other +library routines. + + Every effort has been made to ensure that the code is +portable and won't interfere with running code - it should just +plug in or out. The biggest hindrances are forward declarations of +malloc() [which the preprocessor gleefully turns into syntax errors +for you] and structure elements named "free". The code has been +tested under Ultrix on DEC Risc and VAX systems, and under SunOS +on a Motorola platform. Please send patches, suggestions, etc, +to the author, who will probably not have time to do anything with +them. + +Compiling and building: + You may wish to edit the Makefile and glance at mnemconf.h, +then simply type "make". "make mtest" will build a simple test program +that will give you an idea of how things work. "make runmtest" will +run the test and do analysis on it. + +Marcus J. Ranum +mjr@decuac.dec.com diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemalyse.c b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemalyse.c new file mode 100644 index 000000000..60d2b914e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemalyse.c @@ -0,0 +1,197 @@ +/************************************************************************ + * * + * Copyright (c) 1985 by * + * Digital Equipment Corporation, Maynard, MA * + * All rights reserved. * + * * + * The information in this software is subject to change without * + * notice and should not be construed as a commitment by Digital * + * Equipment Corporation. * + * * + * Digital assumes no responsibility for the use or reliability * + * of its software on equipment which is not supplied by Digital. * + * * + * Redistribution and use in source and binary forms are permitted * + * provided that the above copyright notice and this paragraph are * + * duplicated in all such forms and that any documentation, * + * advertising materials, and other materials related to such * + * distribution and use acknowledge that the software was developed * + * by Digital Equipment Corporation. The name of Digital Equipment * + * Corporation may not be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.* + * Do not take internally. In case of accidental ingestion, contact * + * your physician immediately. * + * * + ************************************************************************/ + +/* DO NOT INCLUDE "mnemosyne.h" !!! */ +#include +#include +#include +#include + +static char rcsid[] = "/fats/tools/hsv/mnemosyne/mnemalyse.c,v 1.1.1.1 1995/06/06 18:18:28 fabio Exp"; + +#include "mnemconf.h" + +extern char *index(); + +/* +post-processor to interpret memory allocation maps and search for +pointers that were allocated but never freed. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + +/* +simple and braindead, read in the ".lines" file, and store it in a +table by number. then read the pointer map, and crossref any unfreed +pointers. simple as dereferencing NULL... + +this could use some cleaning and buffing, but it's damn effective as +it is. again, fancier symbol table routines would make this faster, +but who gives a damn? it only has to be faster than finding memory +leaks by hand... +*/ + +struct xsym { + char *dat; + int lnum; + int map; + struct xsym *nxt; +}; + + + +main() +{ + register struct xsym *sp; + register struct xsym *zp; + struct ptr p; + struct xsym *shash[HASHSIZ]; + char inbuf[BUFSIZ]; + FILE *lp; + int fd; + + /* statistics */ + int ptrcnt = 0; + int ptrbad = 0; + int ptrlos = 0; + + /* to chop up lines */ + char *cpmap; + char *cpcalls; + char *cpave; + char *cplnum; + char *cpfnam; + + for(fd = 0; fd < HASHSIZ; fd++) + shash[fd] = (struct xsym *)0; + + if((lp = fopen(LINESFILE,"r")) == (FILE *)0) { + perror(LINESFILE); + exit(1); + } + + if((fd = open(PTRFILE,O_RDONLY|O_RDWR)) < 0) { + perror(PTRFILE); + exit(1); + } + + /* this is ugly, but I refuse to trust !@(#&U!@#&! sscanf() */ + while((cpmap = fgets(inbuf,sizeof(inbuf),lp)) != (char *)0) { + if(inbuf[0] == '#') + continue; + + sp = (struct xsym *)malloc(sizeof(struct xsym)); + if(sp == (struct xsym *)0) { + perror("malloc"); + exit(1); + } + sp->lnum = sp->map = 0; + + if((cpcalls = index(cpmap,'\t')) != (char *)0) + *cpcalls++ = '\0'; + + if((cpave = index(cpcalls,'\t')) != (char *)0) + *cpave++ = '\0'; + + if((cplnum = index(cpave,'\t')) != (char *)0) + *cplnum++ = '\0'; + + if((cpfnam = index(cplnum,'\t')) != (char *)0) + *cpfnam++ = '\0'; + + /* setup symbol */ + sp->map = atoi(cpmap); + + if(cplnum == (char *)0) + sp->lnum = -1; + else + sp->lnum = atoi(cplnum); + + if(cpfnam != (char *)0) { + char *x; + if((x = index(cpfnam,'\n')) != (char *)0) + *x = '\0'; + + sp->dat = malloc((unsigned)(strlen(cpfnam) + 1)); + if(sp->dat == (char *)0) { + perror("malloc"); + exit(1); + } + (void)strcpy(sp->dat,cpfnam); + } else + sp->dat = "unknown"; + + /* check to make sure it is not already in table */ + zp = shash[sp->map % HASHSIZ]; + while(zp != (struct xsym *)0) { + if(zp->map == sp->map) { + (void)fprintf(stderr, + "mnemalyse: duplicate map entry ignored"); + (void)fprintf(stderr, + " (point at both %s and %s)\n",sp->dat,zp->dat); + (void)free(sp); + + /* can't free dat - may not be malloced! */ + sp = (struct xsym *)0; + break; + } + zp = zp->nxt; + } + + /* shrug, link it in */ + if(sp != (struct xsym *)0) { + sp->nxt = shash[sp->map % HASHSIZ]; + shash[sp->map % HASHSIZ] = sp; + } + } + (void)fclose(lp); + + while(read(fd,(char *)&(p.dsk),sizeof(p.dsk)) == sizeof(p.dsk)) { + + /* if the pointer was not deallocated, note it */ + if(p.dsk.siz != 0) { + zp = shash[p.dsk.smap % HASHSIZ]; + while(zp != (struct xsym *)0) { + if(zp->map == p.dsk.smap) { + printf("%d bytes missing %s line:%d\n", + p.dsk.siz,zp->dat,zp->lnum); + } + zp = zp->nxt; + } + ptrbad++; + ptrlos += p.dsk.siz; + } + ptrcnt++; + } + + printf("%d pointers, %d lost totalling %d bytes\n", + ptrcnt,ptrbad,ptrlos); + exit(0); +} diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemconf.h b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemconf.h new file mode 100644 index 000000000..9ea8f75bf --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemconf.h @@ -0,0 +1,89 @@ +/************************************************************************ + * * + * Copyright (c) 1985 by * + * Digital Equipment Corporation, Maynard, MA * + * All rights reserved. * + * * + * The information in this software is subject to change without * + * notice and should not be construed as a commitment by Digital * + * Equipment Corporation. * + * * + * Digital assumes no responsibility for the use or reliability * + * of its software on equipment which is not supplied by Digital. * + * * + * Redistribution and use in source and binary forms are permitted * + * provided that the above copyright notice and this paragraph are * + * duplicated in all such forms and that any documentation, * + * advertising materials, and other materials related to such * + * distribution and use acknowledge that the software was developed * + * by Digital Equipment Corporation. The name of Digital Equipment * + * Corporation may not be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.* + * Do not take internally. In case of accidental ingestion, contact * + * your physician immediately. * + * * + ************************************************************************/ + +#ifndef _INCL_MNEMCONF_H + +/* +/fats/tools/hsv/mnemosyne/mnemconf.h,v 1.1.1.1 1995/06/06 18:18:29 fabio Exp +*/ + +/* +site specific and shared internal data structures used by mnemosyne. +the only data structure that may need to be shared is the struct ptr, +which is defined herein. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + + +/* if your machine has malloc and all declared as a (void *) not a (char *) */ +#ifdef MALLOC_IS_VOIDSTAR +typedef void *mall_t; +#else +typedef char *mall_t; +#endif + + +/* size of internal hash tables - don't go wild - this is slow anyhow */ +#define HASHSIZ 2027 + + +/* names of files to write */ +#define LINESFILE "mnem.syms" +#define PTRFILE "mnem.dat" + + +extern mall_t malloc(); +extern mall_t realloc(); +extern mall_t calloc(); +extern void free(); + + +/* +storage for a pointer map entry - the only data structure we share +a whole mess of these get written to mnem.dat as calls to malloc and +whatnot are made. the distinction between an *allocated* pointer and +and unallocated one is that 'siz' is 0 in freed ptrs. this is used +by the post-processor to look for memory leaks. +*/ +struct ptr { + mall_t ptr; /* pointer to allocated memory */ + int map; /* this pointer's map # */ + struct ptr *next; + + /* only part that gets written to the disk */ + struct { + unsigned siz; /* size allocated (or 0) */ + int smap; /* symbol map # */ + } dsk; +}; + +#define _INCL_MNEMCONF_H +#endif diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.c b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.c new file mode 100644 index 000000000..0d759da18 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.c @@ -0,0 +1,670 @@ +/************************************************************************ + * * + * Copyright (c) 1985 by * + * Digital Equipment Corporation, Maynard, MA * + * All rights reserved. * + * * + * The information in this software is subject to change without * + * notice and should not be construed as a commitment by Digital * + * Equipment Corporation. * + * * + * Digital assumes no responsibility for the use or reliability * + * of its software on equipment which is not supplied by Digital. * + * * + * Redistribution and use in source and binary forms are permitted * + * provided that the above copyright notice and this paragraph are * + * duplicated in all such forms and that any documentation, * + * advertising materials, and other materials related to such * + * distribution and use acknowledge that the software was developed * + * by Digital Equipment Corporation. The name of Digital Equipment * + * Corporation may not be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.* + * Do not take internally. In case of accidental ingestion, contact * + * your physician immediately. * + * * + ************************************************************************/ + +/* DO NOT INCLUDE "mnemosyne.h" !!! */ +#include +#include +#include + +/* shared stuff - and decl of struct ptr */ +#include "mnemconf.h" + +static char rcsid[] = "/fats/tools/hsv/mnemosyne/mnemosyne.c,v 1.1.1.1 1995/06/06 18:18:28 fabio Exp"; + + +/* +malloc() realloc() and family wrappers - these functions manage a set +of data files that are updated whenever a pointer is allocated or freed, +as well as gathering stats about dynamic memory use and leakage. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + +/* +there is some egregious use of globals, void functions, and whatnot +in this code. it is mostly due to the constraint that nothing must +be visible to the outside, and that the code must be structurally +simple. error checking is pitched out the window in spots, since an +error in the mnemosyne code should not affect whatever is being +instrumented if at all possible. this means no errors, no signals, +nothing. (this message brought to you by my ego, in case you think +I don't know how to write better code than this) :) + +mjr, hacking on Christmas, 1990. +*/ + +#define REC_UNINIT 000 +#define REC_INITTED 001 +#define REC_ERR 002 +#define REC_ON 010 +#define REC_ONOFF 020 +static int rec_state = REC_UNINIT; + +/* +this method of storing the symbol maps is not the most efficient, but +then that's not important here, since all we're trying to do is find +memory leaks. if you choose to improve the symbol management to use +bucketed hash tables, please contact the author and the code will be +updated :) - besides, since we do file I/O every time you malloc or +free something, there's no way in hell this is going to set any new +records for speed. +*/ + + +/* storage for code/line # entry */ +struct sym { + char *labl; + int lineno; + int mapno; + int mallcnt; + float avsiz; + struct sym *next; +}; + + + +/* static symbol map */ +static struct { + FILE *fp; + FILE *log; + int fd; + + long nalloc; /* count of allocations */ + long nrlloc; /* count of re-allocations */ + long nfree; /* count of frees */ + long nbfree; /* count of bad frees */ + long ninuse; /* known allocated memory in use */ + float avgsiz; /* average malloc size */ + + /* one entry per pointer returned by malloc */ + int pmap; /* current next ptr map to alloc */ + struct ptr *phash[HASHSIZ]; + + /* one entry per line of code that calls malloc/realloc, etc */ + int lmap; /* current next line map to alloc */ + struct sym *shash[HASHSIZ]; /* hash access */ +} map; + + + + +/* print a locale record with checks for closed log file */ +static void +ploc(lab,lin,siz) +char *lab; +int lin; +int siz; +{ + if(map.log == (FILE *)0) + return; + if(lab != (char *)0) + (void)fprintf(map.log," \"%s\"",lab); + else + (void)fprintf(map.log," unknown"); + if(lin != -1) + (void)fprintf(map.log," line:%d",lin); + if(siz != -1) + (void)fprintf(map.log," size:%d",siz); +} + + + + +/* print a symbol map entry with checks for closed log file */ +static void +psym(s) +struct sym *s; +{ + if(map.log == (FILE *)0) + return; + (void)fprintf(map.log," \"%s\"",s->labl); + if(s->lineno != -1) + (void)fprintf(map.log," line:%d",s->lineno); +} + + + + +/* output a warning message with checks for closed log file */ +static void +pmsg(s) +char *s; +{ + if(map.log == (FILE *)0) + return; + (void)fprintf(map.log,"%s",s); +} + + + + +/* save an entry to the .lines file */ +static void +savesym(s) +struct sym *s; +{ + if(map.fp == (FILE *)0) + return; + + (void)fprintf(map.fp,"%d\t%d\t%.1f\t%d\t%s\n", + s->mapno,s->mallcnt,s->avsiz,s->lineno,s->labl); +} + + + + +/* save an entry in the pointer map file */ +static void +saveptr(p) +register struct ptr *p; +{ + if(lseek(map.fd,(off_t)(p->map * sizeof(p->dsk)),0) != + (off_t)(p->map * sizeof(p->dsk))) { + pmsg("mnemosyne: cannot seek in pointer map file\n"); + rec_state |= REC_ERR; + return; + } + + if(write(map.fd,(char *)&(p->dsk),sizeof(p->dsk)) != sizeof(p->dsk)) { + pmsg("mnemosyne: cannot write in pointer map file\n"); + rec_state |= REC_ERR; + return; + } +} + + + + +/* initialize everything - symbol tables, files, and maps */ +static void +initmap() +{ + register int xp; + + if(rec_state & REC_INITTED) + return; + + if((map.fp = fopen(LINESFILE,"w")) == (FILE *)0) + return; + if((map.fd = open(PTRFILE,O_RDWR|O_CREAT|O_TRUNC,0600)) < 0) { + (void)fclose(map.fp); + return; + } + + map.log = stderr; + map.lmap = map.pmap = 0; + map.nalloc = map.nrlloc = map.nfree = map.nbfree = 0L; + map.ninuse = 0L; + map.avgsiz = 0.0; + + for(xp = 0; xp < HASHSIZ; xp++) { + map.phash[xp] = (struct ptr *)0; + map.shash[xp] = (struct sym *)0; + } + + rec_state = REC_INITTED | REC_ON; +} + + + + +/* set logging to a FILE * */ +void +mnem_setlog(fp) +FILE *fp; +{ + map.log = fp; +} + + + + +/* return state of the recorder */ +int +mnem_recording() +{ + return((rec_state & REC_ON) && !(rec_state & REC_ERR)); +} + + + + +/* turn on or off recording */ +int +mnem_setrecording(val) +int val; +{ + if(!(rec_state & REC_INITTED)) + initmap(); + + if(val) + rec_state |= REC_ON; + else + rec_state &= ~REC_ON; + + if(map.fp != (FILE *)0) + (void)fflush(map.fp); + + rec_state |= REC_ONOFF; + return(0); +} + + + + +/* lookup a pointer record - search pointer hash table */ +static struct ptr * +lookupptr(ptr) +mall_t ptr; +{ + register struct ptr *p; + + /* this probably give simply terrible hash performance */ + p = map.phash[(unsigned long)ptr % HASHSIZ]; + while(p != (struct ptr *)0) { + if(ptr == p->ptr) + return(p); + p = p->next; + } + return((struct ptr *)0); +} + + + + +/* + * polynomial conversion ignoring overflows + * [this seems to work remarkably well, in fact better + * then the ndbm hash function. Replace at your own risk] + * use: 65599 nice. + * 65587 even better. + * author: oz@nexus.yorku.ca + */ +static unsigned int +dbm_hash(str) +register char *str; +{ + register unsigned int n = 0; + + while(*str != '\0') + n = *str++ + 65599 * n; + return(n); +} + + + + +/* lookup a line/source entry by name (search hash table) */ +static struct sym * +lookupsymbyname(nam,lin) +char *nam; +int lin; +{ + register struct sym *s; + char *p = nam; + + if(p == (char *)0) + p = "unknown"; + + s = map.shash[(dbm_hash(p) + lin) % HASHSIZ]; + while(s != (struct sym *)0) { + if(!strcmp(s->labl,nam) && s->lineno == lin) + return(s); + s = s->next; + } + + return((struct sym *)0); +} + + + + +/* lookup a line/source entry by number (exhaustively search hash table) */ +static struct sym * +lookupsymbynum(num) +int num; +{ + register struct sym *s; + register int x; + + for(x = 0; x < HASHSIZ; x++) { + s = map.shash[x]; + while(s != (struct sym *)0) { + if(s->mapno == num) + return(s); + s = s->next; + } + } + return((struct sym *)0); +} + + + +/* stuff a pointer's value in the pointer map table */ +static void +storeptr(ptr,siz,lab,lin) +mall_t ptr; +int siz; +char *lab; +int lin; +{ + register struct ptr *p; + register struct sym *s; + int hv; + + /* + is there is no existing symbol entry for this line of code... + we must needs make one - and painful it is... + */ + if((s = lookupsymbyname(lab,lin)) == (struct sym *)0) { + s = (struct sym *)malloc(sizeof(struct sym)); + if(s == (struct sym *)0) { + pmsg("mnemosyne: cannot allocate sym entry\n"); + rec_state |= REC_ERR; + return; + } + + /* + this is funky - since we know the label is (?) + compiled-in, we can just keep a pointer to it, + rather than copying our own version of it. + */ + if(lab != (char *)0) + s->labl = lab; + else + s->labl = "unknown"; + + s->mapno = map.lmap++; + + /* add sym to hash table */ + s->next = map.shash[hv = ((dbm_hash(s->labl) + lin) % HASHSIZ)]; + map.shash[hv] = s; + + s->lineno = lin; + s->mallcnt = 1; + s->avsiz = siz; + savesym(s); + } else { + /* found an already defined symbol. store some averages */ + s->avsiz = ((s->avsiz * s->mallcnt) + siz) / (s->mallcnt + 1); + (s->mallcnt)++; + } + + p = lookupptr(ptr); + if(p != (struct ptr *)0 && p->dsk.siz != 0) { + struct sym *x; + + pmsg("pointer re-allocated without being freed"); + ploc(lab,lin,(int)siz); + if((x = lookupsymbynum(p->dsk.smap)) != (struct sym *)0) { + pmsg(" last allocated "); + psym(x); + } + pmsg("\n"); + } + + /* heavy sigh. no entry for this pointer. make one. */ + if(p == (struct ptr *)0) { + p = (struct ptr *)malloc(sizeof(struct ptr)); + if(p == (struct ptr *)0) { + pmsg("mnemosyne: cannot expand pointer table\n"); + rec_state |= REC_ERR; + return; + } + + /* link it in */ + p->next = map.phash[(unsigned long)ptr % HASHSIZ]; + map.phash[(unsigned long)ptr % HASHSIZ] = p; + } + + /* if we get to here (hazoo! hazaa!) both 's' and 'p' are OK */ + p->ptr = ptr; + p->dsk.siz = siz; + p->dsk.smap = s->mapno; + p->map = map.pmap++; + + /* store the size */ + map.ninuse += siz; + + saveptr(p); +} + + + + +/* +mark a pointer as now being free. note that a 1 is returned IF +the actual value should NOT be really passed to free() +*/ +static int +freeptr(ptr,lab,lin) +mall_t ptr; +char *lab; +int lin; +{ + register struct ptr *p; + + p = lookupptr(ptr); + if(p == (struct ptr *)0) { + pmsg("pointer freed that was never allocated"); + ploc(lab,lin,-1); + pmsg("\n"); + return(1); + } + + if(p != (struct ptr *)0 && p->dsk.siz == 0) { + struct sym *x; + + pmsg("pointer re-freed when already free"); + ploc(lab,lin,-1); + if((x = lookupsymbynum(p->dsk.smap)) != (struct sym *)0) { + pmsg(" last allocated:"); + psym(x); + } + pmsg("\n"); + return(1); + } + + /* get some free */ + map.ninuse -= p->dsk.siz; + + /* write in the map that it is free */ + p->dsk.siz = 0; + saveptr(p); + + return(0); +} + + + + +/* pretend we are malloc() */ +mall_t +mnem_malloc(siz,lab,lin) +unsigned siz; +char *lab; +int lin; +{ + mall_t ret; + + if(!(rec_state & REC_INITTED)) + initmap(); + + if((ret = malloc(siz)) == (mall_t)0) { + pmsg("malloc returned null pointer at"); + ploc(lab,lin,(int)siz); + pmsg("\n"); + return(ret); + } + + if((rec_state & REC_ON) && !(rec_state & REC_ERR)) + storeptr(ret,(int)siz,lab,lin); + + map.avgsiz = ((map.avgsiz * map.nalloc) + siz) / (map.nalloc + 1); + map.nalloc++; + return(ret); +} + + + + +/* pretend we are calloc() */ +mall_t +mnem_calloc(cnt,siz,lab,lin) +unsigned cnt; +unsigned siz; +char *lab; +int lin; +{ + mall_t ret; + + if(!(rec_state & REC_INITTED)) + initmap(); + + if((ret = calloc(cnt,siz)) == (mall_t)0) { + pmsg("calloc returned null pointer at"); + ploc(lab,lin,(int)(siz * cnt)); + pmsg("\n"); + return(ret); + } + + if((rec_state & REC_ON) && !(rec_state & REC_ERR)) + storeptr(ret,(int)(cnt * siz),lab,lin); + + map.avgsiz = ((map.avgsiz * map.nalloc) + siz) / (map.nalloc + 1); + map.nalloc++; + return(ret); +} + + + + +/* pretend we are realloc() */ +mall_t +mnem_realloc(ptr,siz,lab,lin) +mall_t ptr; +unsigned siz; +char *lab; +int lin; +{ + mall_t ret; + + if(!(rec_state & REC_INITTED)) + initmap(); + + if((ret = realloc(ptr,siz)) == (mall_t)0) { + pmsg("realloc returned null pointer at"); + ploc(lab,lin,(int)siz); + pmsg("\n"); + return(ret); + } + + if((rec_state & REC_ON) && !(rec_state & REC_ERR)) { + if(!freeptr(ptr,lab,lin)) + storeptr(ret,(int)siz,lab,lin); + } + + map.nrlloc++; + return(ret); +} + + + + + +/* pretend we are free() */ +void +mnem_free(ptr,lab,lin) +mall_t ptr; +char *lab; +int lin; +{ + if(!(rec_state & REC_INITTED)) + initmap(); + + if((rec_state & REC_ON) && !(rec_state & REC_ERR)) + if(freeptr(ptr,lab,lin) == 0) { + (void)free(ptr); + map.nfree++; + } else + map.nbfree++; +} + + + + +/* dump everything we know about nothing in particular */ +int +mnem_writestats() +{ + register struct sym *s; + register int x; + + if(map.fp == (FILE *)0) + return(-1); + + (void)fseek(map.fp,0L,0); + + /* dump our life's story */ + (void)fprintf(map.fp,"#total allocations:%ld\n",map.nalloc); + (void)fprintf(map.fp,"#total re-allocations:%ld\n",map.nrlloc); + (void)fprintf(map.fp,"#total frees:%ld\n",map.nfree); + + if(map.nbfree != 0L) + (void)fprintf(map.fp,"#bad/dup frees:%ld\n",map.nbfree); + + (void)fprintf(map.fp,"#total allocated never freed:%ld\n",map.ninuse); + + (void)fprintf(map.fp,"#average size of allocations:%.1f\n",map.avgsiz); + + /* note if we detected an internal error */ + if(rec_state & REC_ERR) + (void)fprintf(map.fp, + "#(figures likely inaccurate due to error)\n"); + + /* note if the system was on all the time ? */ + if(!(rec_state & REC_ON) || (rec_state & REC_ONOFF)) + (void)fprintf(map.fp, + "#(figures likely inaccurate as recording was off)\n"); + + /* write the legend */ + (void)fprintf(map.fp,"#map#\tcalls\tave\tline#\tfile\n"); + + for(x = 0; x < HASHSIZ; x++) { + s = map.shash[x]; + while(s != (struct sym *)0) { + savesym(s); + s = s->next; + } + } + + (void)fflush(map.fp); + return(0); +} diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.h b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.h new file mode 100644 index 000000000..910af91d5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.h @@ -0,0 +1,73 @@ +/************************************************************************ + * * + * Copyright (c) 1985 by * + * Digital Equipment Corporation, Maynard, MA * + * All rights reserved. * + * * + * The information in this software is subject to change without * + * notice and should not be construed as a commitment by Digital * + * Equipment Corporation. * + * * + * Digital assumes no responsibility for the use or reliability * + * of its software on equipment which is not supplied by Digital. * + * * + * Redistribution and use in source and binary forms are permitted * + * provided that the above copyright notice and this paragraph are * + * duplicated in all such forms and that any documentation, * + * advertising materials, and other materials related to such * + * distribution and use acknowledge that the software was developed * + * by Digital Equipment Corporation. The name of Digital Equipment * + * Corporation may not be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.* + * Do not take internally. In case of accidental ingestion, contact * + * your physician immediately. * + * * + ************************************************************************/ + +#ifndef _INCL_MNEMOSYNE_H + +/* +/fats/tools/hsv/mnemosyne/mnemosyne.h,v 1.1.1.1 1995/06/06 18:18:28 fabio Exp +*/ + + +/* +main include file for the mnemosyne memory allocation tracker. this file +provides some pre-processor fakes for malloc(), realloc() and family, +as well as forward declarations for the mnemosyne functions. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + +/* these disguise mnemosyne calls as calls to malloc and family */ +#ifndef NOFAKEMALLOC +#define malloc(siz) mnem_malloc(siz,__FILE__,__LINE__) +#define calloc(siz,cnt) mnem_calloc(siz,cnt,__FILE__,__LINE__) +#define realloc(ptr,siz) mnem_realloc(ptr,siz,__FILE__,__LINE__) +#define free(ptr) mnem_free(ptr,__FILE__,__LINE__) +#endif + + +#ifdef MALLOC_IS_VOIDSTAR +typedef void *mall_t; +#else +typedef char *mall_t; +#endif + +extern mall_t mnem_malloc(); +extern mall_t mnem_calloc(); +extern mall_t mnem_realloc(); +extern void mnem_free(); + +/* some internal functions and oddimentia */ +extern int mnem_recording(); +extern int mnem_setrecording(); +extern void mnem_setlog(); +extern int mnem_writestats(); + +#define _INCL_MNEMOSYNE_H +#endif diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/mtest.c b/resources/3rdparty/cudd-2.5.0/mnemosyne/mtest.c new file mode 100644 index 000000000..5a51a0a04 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/mtest.c @@ -0,0 +1,38 @@ +#include "mnemosyne.h" + +static char rcsid[] = "/fats/tools/hsv/mnemosyne/mtest.c,v 1.1.1.1 1995/06/06 18:18:27 fabio Exp"; + +/* +test harness/demo of mnemosyne library. deliberately leaks memory on the +floor, double frees, frees unallocated memory, etc. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + +main() +{ + char *d = "foobar"; + char *xx; + int x; + + xx = malloc(922); + xx = malloc(123); + + /* huh ? */ + xx = malloc(-9); + + /* waste some memory */ + for(x = 1; x < 8; x++) + xx = malloc(x); + + /* free something we don't own */ + free(d); + + /* double free something */ + free(xx); + free(xx); + + /* not necessary - this triggers a better printout of statistics */ + mnem_writestats(); +} diff --git a/resources/3rdparty/cudd-2.5.0/mtr/Makefile b/resources/3rdparty/cudd-2.5.0/mtr/Makefile new file mode 100644 index 000000000..b62b7c5da --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/Makefile @@ -0,0 +1,96 @@ +# $Id: Makefile,v 1.2 1994/10/03 23:30:34 fabio Exp fabio $ +# +# mtr - multiway-branching tree package +#--------------------------- +.SUFFIXES: .o .c .u + +CC = cc +RANLIB = ranlib +PURE = +# Define EXE as .exe for MS-DOS and derivatives. +EXE = +#EXE = .exe + +MFLAG = +ICFLAGS = -g +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) +MTRDEBUG = -DMTR_STATS -DMTR_VERBOSE -DMTR_DEBUG + +LINTFLAGS = -u -n -DMTR_STATS -DMTR_VERBOSE -DMTR_DEBUG + +# this is to create the lint library +LINTSWITCH = -o + +LDFLAGS = + +WHERE = .. + +INCLUDE = $(WHERE)/include + +P = mtr +PSRC = mtrBasic.c mtrGroup.c +PHDR = mtr.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +SRC = test$(P).c +HDR = +OBJ = $(SRC:.c=.o) +UBJ = $(SRC:.c=.u) +TARGET = test$(P)$(EXE) +TARGETu = test$(P)-u + +LIBS = ./libmtr.a $(WHERE)/util/libutil.a + +BLIBS = -kL. -klmtr -kL$(WHERE)/util -klutil + +MNEMLIB = + +LINTLIBS = llib-l$(P).ln + +#--------------------------- + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PSRC) $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) $(MTRDEBUG) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) +$(OBJ): $(PHDR) +$(UBJ): $(PHDR) + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +$(TARGET): $(POBJ) $(OBJ) $(LIBS) $(MNEMLIB) + $(PURE) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +$(TARGETu): $(SRC) $(PSRC) $(PHDR) $(UBJ) $(PUBJ) $(LIBS:.a=.b) + cc -O3 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \ + *.bak *~ tags *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/mtr/Makefile.sis b/resources/3rdparty/cudd-2.5.0/mtr/Makefile.sis new file mode 100644 index 000000000..d920cabf7 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/Makefile.sis @@ -0,0 +1,83 @@ +# $Id$ +# +# Cudd - DD package +#--------------------------- +.SUFFIXES: .o .c .u + +RANLIB = ranlib + +CAD = /projects/octtools/octtools/$(MACHINE) +SIS = .. +LINTCREATEFLAG = -C + +# files for the package +P = mtr +PSRC = mtrBasic.c mtrGroup.c +PHDR = mtr.h +POBJ = $(PSRC:.c=.o) + +# files for the test program +TARGET = test$(P) +SRC = test$(P).c +OBJ = $(SRC:.c=.o) +HDR = + +LIBS = ../util/libutil.a +LINTLIBS= ../util/llib-lutil.ln +INCLUDE = -I$(CAD)/include -I$(SIS)/include + +CFLAGS = -g $(INCLUDE) +LDFLAGS = -g +LINTFLAGS = $(INCLUDE) ${LINTEXTRAS} + +#------------------------------------------------------ + +$(TARGET): $(PHDR) $(OBJ) $(POBJ) $(LIBS) + $(CC) $(LDFLAGS) -o $(TARGET) $(OBJ) $(POBJ) $(LIBS) + +lint: $(PSRC) $(PHDR) $(SRC) $(HDR) + lint $(LINTFLAGS) $(SRC) $(PSRC) $(LINTLIBS) + +install: lib$(P).a llib-l$(P).ln + +lib$(P).a: $(POBJ) + ar cr $@ $? + $(RANLIB) $@ + +unpack: lib$(P).a + @for i in $(POBJ); do \ + ln -s $(SIS)/$(P)/$$i $(SIS)/unpack; \ + done + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) ${LINTCREATEFLAG}$(P) -n $(PSRC) + +clean: + rm -f $(TARGET) *.a *.ln *.o \ + [Tt]ags [Mm]ake.out lint malloc.out gmon.out __.SYMDEF + +tags: _force + @for i in $(PSRC) $(PHDR); do \ + cwd=`pwd`; ctags -a $$cwd/$$i; + done; + +strip_depend: + sed '/^#--DO NOT CHANGE ANYTHING AFTER THIS LINE/,$$d' Makefile >mktemp + mv mktemp Makefile + +depend: + sed '/^#--DO NOT CHANGE ANYTHING AFTER THIS LINE/,$$d' Makefile >mktemp + echo '#--DO NOT CHANGE ANYTHING AFTER THIS LINE' >>mktemp + $(CAD)/bin/cc-M $(CFLAGS) $(PSRC) | \ + sed 's|$(CAD)|$$(CAD)|g' | \ + grep -v '/usr/include' >>mktemp + mv mktemp Makefile + +#-------------------------- IBM 3090 support ----------------- +IBMHOST = opua +IBMDIST = /users2/sis +ibmdist: $(PSRC) $(PHDR) + rdist -Richw $(PSRC) $(PHDR) $(IBMHOST):$(IBMDIST) +#------------------------------------------------------------- +_force: + diff --git a/resources/3rdparty/cudd-2.5.0/mtr/doc/mtr.doc b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtr.doc new file mode 100644 index 000000000..2815d2948 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtr.doc @@ -0,0 +1,252 @@ +The mtr package + +Multiway-branch tree manipulation + +Fabio Somenzi + +********************************************************************** + +Mtr_AllocNode() Allocates new tree node. + +Mtr_CopyTree() Makes a copy of tree. + +Mtr_CreateFirstChild() Creates a new node and makes it the first child + of parent. + +Mtr_CreateLastChild() Creates a new node and makes it the last child + of parent. + +Mtr_DeallocNode() Deallocates tree node. + +Mtr_DissolveGroup() Merges the children of `group' with the + children of its parent. + +Mtr_FindGroup() Finds a group with size leaves starting at low, + if it exists. + +Mtr_FreeTree() Disposes of tree rooted at node. + +Mtr_InitGroupTree() Allocate new tree. + +Mtr_InitTree() Initializes tree with one node. + +Mtr_MakeFirstChild() Makes child the first child of parent. + +Mtr_MakeGroup() Makes a new group with size leaves starting at + low. + +Mtr_MakeLastChild() Makes child the last child of parent. + +Mtr_MakeNextSibling() Makes second the next sibling of first. + +Mtr_PrintGroups() Prints the groups as a parenthesized list. + +Mtr_PrintTree() Prints a tree, one node per line. + +Mtr_ReadGroups() Reads groups from a file and creates a group + tree. + +Mtr_SwapGroups() Swaps two children of a tree node. + +********************************************************************** + +This package provides two layers of functions. Functions of the lower level +manipulate multiway-branch trees, implemented according to the classical +scheme whereby each node points to its first child and its previous and +next siblings. These functions are collected in mtrBasic.c. Functions +of the upper layer deal with group trees, that is the trees used by group +sifting to represent the grouping of variables. These functions are +collected in mtrGroup.c. + +MtrNode * +Mtr_AllocNode( + +) + Allocates new tree node. Returns pointer to node. + + Side Effects: None + +MtrNode * +Mtr_CopyTree( + MtrNode * node, + int expansion +) + Makes a copy of tree. If parameter expansion is greater than 1, it will + expand the tree by that factor. It is an error for expansion to be less than + 1. Returns a pointer to the copy if successful; NULL otherwise. + + Side Effects: None + +MtrNode * +Mtr_CreateFirstChild( + MtrNode * parent +) + Creates a new node and makes it the first child of parent. Returns pointer + to new child. + + Side Effects: None + +MtrNode * +Mtr_CreateLastChild( + MtrNode * parent +) + Creates a new node and makes it the last child of parent. Returns pointer to + new child. + + Side Effects: None + +void +Mtr_DeallocNode( + MtrNode * node node to be deallocated +) + Deallocates tree node. + + Side Effects: None + +MtrNode * +Mtr_DissolveGroup( + MtrNode * group group to be dissolved +) + Merges the children of `group' with the children of its parent. Disposes of + the node pointed by group. If group is the root of the group tree, this + procedure leaves the tree unchanged. Returns the pointer to the parent of + `group' upon successful termination; NULL otherwise. + + Side Effects: None + +MtrNode * +Mtr_FindGroup( + MtrNode * root, root of the group tree + unsigned int low, lower bound of the group + unsigned int size upper bound of the group +) + Finds a group with size leaves starting at low, if it exists. This procedure + relies on the low and size fields of each node. It also assumes that the + children of each node are sorted in order of increasing low. Returns the + pointer to the root of the group upon successful termination; NULL + otherwise. + + Side Effects: None + +void +Mtr_FreeTree( + MtrNode * node +) + Disposes of tree rooted at node. + + Side Effects: None + +MtrNode * +Mtr_InitGroupTree( + int lower, + int size +) + Allocate new tree with one node, whose low and size fields are specified by + the lower and size parameters. Returns pointer to tree root. + + Side Effects: None + +MtrNode * +Mtr_InitTree( + +) + Initializes tree with one node. Returns pointer to node. + + Side Effects: None + +void +Mtr_MakeFirstChild( + MtrNode * parent, + MtrNode * child +) + Makes child the first child of parent. + + Side Effects: None + +MtrNode * +Mtr_MakeGroup( + MtrNode * root, root of the group tree + unsigned int low, lower bound of the group + unsigned int size, upper bound of the group + unsigned int flags flags for the new group +) + Makes a new group with size leaves starting at low. If the new group + intersects an existing group, it must either contain it or be contained by + it. This procedure relies on the low and size fields of each node. It also + assumes that the children of each node are sorted in order of increasing + low. In case of a valid request, the flags of the new group are set to the + value passed in `flags.' This can also be used to change the flags of an + existing group. Returns the pointer to the root of the new group upon + successful termination; NULL otherwise. If the group already exists, the + pointer to its root is returned. + + Side Effects: None + +void +Mtr_MakeLastChild( + MtrNode * parent, + MtrNode * child +) + Makes child the last child of parent. + + Side Effects: None + +void +Mtr_MakeNextSibling( + MtrNode * first, + MtrNode * second +) + Makes second the next sibling of first. Second becomes a child of the parent + of first. + + Side Effects: None + +void +Mtr_PrintGroups( + MtrNode * root, root of the group tree + int silent flag to check tree syntax only +) + Prints the groups as a parenthesized list. After each group, the group's + flag are printed, preceded by a `|'. For each flag (except MTR_TERMINAL) a + character is printed. F: MTR_FIXED N: MTR_NEWNODE S: + MTR_SOFT The second argument, silent, if different from 0, causes + Mtr_PrintGroups to only check the syntax of the group tree. + + Side Effects: None + +void +Mtr_PrintTree( + MtrNode * node +) + Prints a tree, one node per line. + + Side Effects: None + +MtrNode * +Mtr_ReadGroups( + FILE * fp, file pointer + int nleaves number of leaves of the new tree +) + Reads groups from a file and creates a group tree. Each group is specified + by three fields: low size flags. Low and size are (short) + integers. Flags is a string composed of the following characters (with + associated translation): D: MTR_DEFAULT F: MTR_FIXED N: + MTR_NEWNODE S: MTR_SOFT T: MTR_TERMINAL Normally, the only + flags that are needed are D and F. Groups and fields are separated by white + space (spaces, tabs, and newlines). Returns a pointer to the group tree if + successful; NULL otherwise. + + Side Effects: None + +int +Mtr_SwapGroups( + MtrNode * first, first node to be swapped + MtrNode * second second node to be swapped +) + Swaps two children of a tree node. Adjusts the high and low fields of the + two nodes and their descendants. The two children must be adjacent. However, + first may be the younger sibling of second. Returns 1 in case of success; 0 + otherwise. + + Side Effects: None + diff --git a/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllAbs.html b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllAbs.html new file mode 100644 index 000000000..9a59faada --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllAbs.html @@ -0,0 +1,72 @@ + +mtr package abstract (Internal) + + +

          mtr package abstract (Internal)

          +

          Internal data structures of the mtr package

          +
          + + + +
          +
          Mtr_AllocNode() +
          Allocates new tree node. + +
          Mtr_CopyTree() +
          Makes a copy of tree. + +
          Mtr_CreateFirstChild() +
          Creates a new node and makes it the first child of parent. + +
          Mtr_CreateLastChild() +
          Creates a new node and makes it the last child of parent. + +
          Mtr_DeallocNode() +
          Deallocates tree node. + +
          Mtr_DissolveGroup() +
          Merges the children of `group' with the children of its parent. + +
          Mtr_FindGroup() +
          Finds a group with size leaves starting at low, if it exists. + +
          Mtr_FreeTree() +
          Disposes of tree rooted at node. + +
          Mtr_InitGroupTree() +
          Allocate new tree. + +
          Mtr_InitTree() +
          Initializes tree with one node. + +
          Mtr_MakeFirstChild() +
          Makes child the first child of parent. + +
          Mtr_MakeGroup() +
          Makes a new group with size leaves starting at low. + +
          Mtr_MakeLastChild() +
          Makes child the last child of parent. + +
          Mtr_MakeNextSibling() +
          Makes second the next sibling of first. + +
          Mtr_PrintGroups() +
          Prints the groups as a parenthesized list. + +
          Mtr_PrintTree() +
          Prints a tree, one node per line. + +
          Mtr_ReadGroups() +
          Reads groups from a file and creates a group tree. + +
          Mtr_SwapGroups() +
          Swaps two children of a tree node. + +
          + +
          + +Generated automatically by extdoc on 970123 + + diff --git a/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllDet.html b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllDet.html new file mode 100644 index 000000000..e7b789074 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllDet.html @@ -0,0 +1,317 @@ + +The mtr package (Internal) + + +

          The mtr package (Internal)

          +

          Internal data structures of the mtr package

          +

          +
          + + +
          + + +In this package all definitions are external. + + +
          + + +
          + +
          +MtrNode * 
          +Mtr_AllocNode(
          +    
          +)
          +
          +
          Allocates new tree node. Returns pointer to node. +

          + +

          Side Effects None +

          + +

          See Also Mtr_DeallocNode + + +
          +MtrNode * 
          +Mtr_CopyTree(
          +  MtrNode * node, 
          +  int  expansion 
          +)
          +
          +
          Makes a copy of tree. If parameter expansion is greater than 1, it will expand the tree by that factor. It is an error for expansion to be less than 1. Returns a pointer to the copy if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          See Also Mtr_InitTree + + +
          +MtrNode * 
          +Mtr_CreateFirstChild(
          +  MtrNode * parent 
          +)
          +
          +
          Creates a new node and makes it the first child of parent. Returns pointer to new child. +

          + +

          Side Effects None +

          + +

          See Also Mtr_MakeFirstChild +Mtr_CreateLastChild + + +
          +MtrNode * 
          +Mtr_CreateLastChild(
          +  MtrNode * parent 
          +)
          +
          +
          Creates a new node and makes it the last child of parent. Returns pointer to new child. +

          + +

          Side Effects None +

          + +

          See Also Mtr_MakeLastChild +Mtr_CreateFirstChild + + +
          +void 
          +Mtr_DeallocNode(
          +  MtrNode * node node to be deallocated
          +)
          +
          +
          Deallocates tree node. +

          + +

          Side Effects None +

          + +

          See Also Mtr_AllocNode + + +
          +MtrNode * 
          +Mtr_DissolveGroup(
          +  MtrNode * group group to be dissolved
          +)
          +
          +
          Merges the children of `group' with the children of its parent. Disposes of the node pointed by group. If group is the root of the group tree, this procedure leaves the tree unchanged. Returns the pointer to the parent of `group' upon successful termination; NULL otherwise. +

          + +

          Side Effects None +

          + +

          See Also Mtr_MakeGroup + + +
          +MtrNode * 
          +Mtr_FindGroup(
          +  MtrNode * root, root of the group tree
          +  unsigned int  low, lower bound of the group
          +  unsigned int  size upper bound of the group
          +)
          +
          +
          Finds a group with size leaves starting at low, if it exists. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. Returns the pointer to the root of the group upon successful termination; NULL otherwise. +

          + +

          Side Effects None +

          + +

          +void 
          +Mtr_FreeTree(
          +  MtrNode * node 
          +)
          +
          +
          Disposes of tree rooted at node. +

          + +

          Side Effects None +

          + +

          See Also Mtr_InitTree + + +
          +MtrNode * 
          +Mtr_InitGroupTree(
          +  int  lower, 
          +  int  size 
          +)
          +
          +
          Allocate new tree with one node, whose low and size fields are specified by the lower and size parameters. Returns pointer to tree root. +

          + +

          Side Effects None +

          + +

          See Also Mtr_InitTree +Mtr_FreeTree + + +
          +MtrNode * 
          +Mtr_InitTree(
          +    
          +)
          +
          +
          Initializes tree with one node. Returns pointer to node. +

          + +

          Side Effects None +

          + +

          See Also Mtr_FreeTree +Mtr_InitGroupTree + + +
          +void 
          +Mtr_MakeFirstChild(
          +  MtrNode * parent, 
          +  MtrNode * child 
          +)
          +
          +
          Makes child the first child of parent. +

          + +

          Side Effects None +

          + +

          See Also Mtr_MakeLastChild +Mtr_CreateFirstChild + + +
          +MtrNode * 
          +Mtr_MakeGroup(
          +  MtrNode * root, root of the group tree
          +  unsigned int  low, lower bound of the group
          +  unsigned int  size, upper bound of the group
          +  unsigned int  flags flags for the new group
          +)
          +
          +
          Makes a new group with size leaves starting at low. If the new group intersects an existing group, it must either contain it or be contained by it. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. In case of a valid request, the flags of the new group are set to the value passed in `flags.' This can also be used to change the flags of an existing group. Returns the pointer to the root of the new group upon successful termination; NULL otherwise. If the group already exists, the pointer to its root is returned. +

          + +

          Side Effects None +

          + +

          See Also Mtr_DissolveGroup +Mtr_ReadGroups +Mtr_FindGroup + + +
          +void 
          +Mtr_MakeLastChild(
          +  MtrNode * parent, 
          +  MtrNode * child 
          +)
          +
          +
          Makes child the last child of parent. +

          + +

          Side Effects None +

          + +

          See Also Mtr_MakeFirstChild +Mtr_CreateLastChild + + +
          +void 
          +Mtr_MakeNextSibling(
          +  MtrNode * first, 
          +  MtrNode * second 
          +)
          +
          +
          Makes second the next sibling of first. Second becomes a child of the parent of first. +

          + +

          Side Effects None +

          + +

          +void 
          +Mtr_PrintGroups(
          +  MtrNode * root, root of the group tree
          +  int  silent flag to check tree syntax only
          +)
          +
          +
          Prints the groups as a parenthesized list. After each group, the group's flag are printed, preceded by a `|'. For each flag (except MTR_TERMINAL) a character is printed.
          • F: MTR_FIXED
          • N: MTR_NEWNODE
          • S: MTR_SOFT
          The second argument, silent, if different from 0, causes Mtr_PrintGroups to only check the syntax of the group tree. +

          + +

          Side Effects None +

          + +

          See Also Mtr_PrintTree + + +
          +void 
          +Mtr_PrintTree(
          +  MtrNode * node 
          +)
          +
          +
          Prints a tree, one node per line. +

          + +

          Side Effects None +

          + +

          See Also Mtr_PrintGroups + + +
          +MtrNode * 
          +Mtr_ReadGroups(
          +  FILE * fp, file pointer
          +  int  nleaves number of leaves of the new tree
          +)
          +
          +
          Reads groups from a file and creates a group tree. Each group is specified by three fields: low size flags. Low and size are (short) integers. Flags is a string composed of the following characters (with associated translation):
          • D: MTR_DEFAULT
          • F: MTR_FIXED
          • N: MTR_NEWNODE
          • S: MTR_SOFT
          • T: MTR_TERMINAL
          Normally, the only flags that are needed are D and F. Groups and fields are separated by white space (spaces, tabs, and newlines). Returns a pointer to the group tree if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          See Also Mtr_InitGroupTree +Mtr_MakeGroup + + +
          +int 
          +Mtr_SwapGroups(
          +  MtrNode * first, first node to be swapped
          +  MtrNode * second second node to be swapped
          +)
          +
          +
          Swaps two children of a tree node. Adjusts the high and low fields of the two nodes and their descendants. The two children must be adjacent. However, first may be the younger sibling of second. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + + +

          + +
          + +Generated automatically by extdoc on 970123 + + diff --git a/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtAbs.html b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtAbs.html new file mode 100644 index 000000000..9f48acbad --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtAbs.html @@ -0,0 +1,72 @@ + +mtr package abstract + + +

          mtr package abstract

          +

          Multiway-branch tree manipulation

          +
          + + + +
          +
          Mtr_AllocNode() +
          Allocates new tree node. + +
          Mtr_CopyTree() +
          Makes a copy of tree. + +
          Mtr_CreateFirstChild() +
          Creates a new node and makes it the first child of parent. + +
          Mtr_CreateLastChild() +
          Creates a new node and makes it the last child of parent. + +
          Mtr_DeallocNode() +
          Deallocates tree node. + +
          Mtr_DissolveGroup() +
          Merges the children of `group' with the children of its parent. + +
          Mtr_FindGroup() +
          Finds a group with size leaves starting at low, if it exists. + +
          Mtr_FreeTree() +
          Disposes of tree rooted at node. + +
          Mtr_InitGroupTree() +
          Allocate new tree. + +
          Mtr_InitTree() +
          Initializes tree with one node. + +
          Mtr_MakeFirstChild() +
          Makes child the first child of parent. + +
          Mtr_MakeGroup() +
          Makes a new group with size leaves starting at low. + +
          Mtr_MakeLastChild() +
          Makes child the last child of parent. + +
          Mtr_MakeNextSibling() +
          Makes second the next sibling of first. + +
          Mtr_PrintGroups() +
          Prints the groups as a parenthesized list. + +
          Mtr_PrintTree() +
          Prints a tree, one node per line. + +
          Mtr_ReadGroups() +
          Reads groups from a file and creates a group tree. + +
          Mtr_SwapGroups() +
          Swaps two children of a tree node. + +
          + +
          + +Generated automatically by extdoc on 970123 + + diff --git a/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtDet.html b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtDet.html new file mode 100644 index 000000000..8300c3d6a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtDet.html @@ -0,0 +1,324 @@ + +The mtr package + + +

          The mtr package

          +

          Multiway-branch tree manipulation

          +

          +
          + + +
          + + +This package provides two layers of functions. Functions + of the lower level manipulate multiway-branch trees, implemented + according to the classical scheme whereby each node points to its + first child and its previous and next siblings. These functions are + collected in mtrBasic.c.

          + Functions of the upper layer deal with group trees, that is the trees + used by group sifting to represent the grouping of variables. These + functions are collected in mtrGroup.c. + + +


          + + +
          + +
          +MtrNode * 
          +Mtr_AllocNode(
          +    
          +)
          +
          +
          Allocates new tree node. Returns pointer to node. +

          + +

          Side Effects None +

          + +

          See Also Mtr_DeallocNode + + +
          +MtrNode * 
          +Mtr_CopyTree(
          +  MtrNode * node, 
          +  int  expansion 
          +)
          +
          +
          Makes a copy of tree. If parameter expansion is greater than 1, it will expand the tree by that factor. It is an error for expansion to be less than 1. Returns a pointer to the copy if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          See Also Mtr_InitTree + + +
          +MtrNode * 
          +Mtr_CreateFirstChild(
          +  MtrNode * parent 
          +)
          +
          +
          Creates a new node and makes it the first child of parent. Returns pointer to new child. +

          + +

          Side Effects None +

          + +

          See Also Mtr_MakeFirstChild +Mtr_CreateLastChild + + +
          +MtrNode * 
          +Mtr_CreateLastChild(
          +  MtrNode * parent 
          +)
          +
          +
          Creates a new node and makes it the last child of parent. Returns pointer to new child. +

          + +

          Side Effects None +

          + +

          See Also Mtr_MakeLastChild +Mtr_CreateFirstChild + + +
          +void 
          +Mtr_DeallocNode(
          +  MtrNode * node node to be deallocated
          +)
          +
          +
          Deallocates tree node. +

          + +

          Side Effects None +

          + +

          See Also Mtr_AllocNode + + +
          +MtrNode * 
          +Mtr_DissolveGroup(
          +  MtrNode * group group to be dissolved
          +)
          +
          +
          Merges the children of `group' with the children of its parent. Disposes of the node pointed by group. If group is the root of the group tree, this procedure leaves the tree unchanged. Returns the pointer to the parent of `group' upon successful termination; NULL otherwise. +

          + +

          Side Effects None +

          + +

          See Also Mtr_MakeGroup + + +
          +MtrNode * 
          +Mtr_FindGroup(
          +  MtrNode * root, root of the group tree
          +  unsigned int  low, lower bound of the group
          +  unsigned int  size upper bound of the group
          +)
          +
          +
          Finds a group with size leaves starting at low, if it exists. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. Returns the pointer to the root of the group upon successful termination; NULL otherwise. +

          + +

          Side Effects None +

          + +

          +void 
          +Mtr_FreeTree(
          +  MtrNode * node 
          +)
          +
          +
          Disposes of tree rooted at node. +

          + +

          Side Effects None +

          + +

          See Also Mtr_InitTree + + +
          +MtrNode * 
          +Mtr_InitGroupTree(
          +  int  lower, 
          +  int  size 
          +)
          +
          +
          Allocate new tree with one node, whose low and size fields are specified by the lower and size parameters. Returns pointer to tree root. +

          + +

          Side Effects None +

          + +

          See Also Mtr_InitTree +Mtr_FreeTree + + +
          +MtrNode * 
          +Mtr_InitTree(
          +    
          +)
          +
          +
          Initializes tree with one node. Returns pointer to node. +

          + +

          Side Effects None +

          + +

          See Also Mtr_FreeTree +Mtr_InitGroupTree + + +
          +void 
          +Mtr_MakeFirstChild(
          +  MtrNode * parent, 
          +  MtrNode * child 
          +)
          +
          +
          Makes child the first child of parent. +

          + +

          Side Effects None +

          + +

          See Also Mtr_MakeLastChild +Mtr_CreateFirstChild + + +
          +MtrNode * 
          +Mtr_MakeGroup(
          +  MtrNode * root, root of the group tree
          +  unsigned int  low, lower bound of the group
          +  unsigned int  size, upper bound of the group
          +  unsigned int  flags flags for the new group
          +)
          +
          +
          Makes a new group with size leaves starting at low. If the new group intersects an existing group, it must either contain it or be contained by it. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. In case of a valid request, the flags of the new group are set to the value passed in `flags.' This can also be used to change the flags of an existing group. Returns the pointer to the root of the new group upon successful termination; NULL otherwise. If the group already exists, the pointer to its root is returned. +

          + +

          Side Effects None +

          + +

          See Also Mtr_DissolveGroup +Mtr_ReadGroups +Mtr_FindGroup + + +
          +void 
          +Mtr_MakeLastChild(
          +  MtrNode * parent, 
          +  MtrNode * child 
          +)
          +
          +
          Makes child the last child of parent. +

          + +

          Side Effects None +

          + +

          See Also Mtr_MakeFirstChild +Mtr_CreateLastChild + + +
          +void 
          +Mtr_MakeNextSibling(
          +  MtrNode * first, 
          +  MtrNode * second 
          +)
          +
          +
          Makes second the next sibling of first. Second becomes a child of the parent of first. +

          + +

          Side Effects None +

          + +

          +void 
          +Mtr_PrintGroups(
          +  MtrNode * root, root of the group tree
          +  int  silent flag to check tree syntax only
          +)
          +
          +
          Prints the groups as a parenthesized list. After each group, the group's flag are printed, preceded by a `|'. For each flag (except MTR_TERMINAL) a character is printed.
          • F: MTR_FIXED
          • N: MTR_NEWNODE
          • S: MTR_SOFT
          The second argument, silent, if different from 0, causes Mtr_PrintGroups to only check the syntax of the group tree. +

          + +

          Side Effects None +

          + +

          See Also Mtr_PrintTree + + +
          +void 
          +Mtr_PrintTree(
          +  MtrNode * node 
          +)
          +
          +
          Prints a tree, one node per line. +

          + +

          Side Effects None +

          + +

          See Also Mtr_PrintGroups + + +
          +MtrNode * 
          +Mtr_ReadGroups(
          +  FILE * fp, file pointer
          +  int  nleaves number of leaves of the new tree
          +)
          +
          +
          Reads groups from a file and creates a group tree. Each group is specified by three fields: low size flags. Low and size are (short) integers. Flags is a string composed of the following characters (with associated translation):
          • D: MTR_DEFAULT
          • F: MTR_FIXED
          • N: MTR_NEWNODE
          • S: MTR_SOFT
          • T: MTR_TERMINAL
          Normally, the only flags that are needed are D and F. Groups and fields are separated by white space (spaces, tabs, and newlines). Returns a pointer to the group tree if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          See Also Mtr_InitGroupTree +Mtr_MakeGroup + + +
          +int 
          +Mtr_SwapGroups(
          +  MtrNode * first, first node to be swapped
          +  MtrNode * second second node to be swapped
          +)
          +
          +
          Swaps two children of a tree node. Adjusts the high and low fields of the two nodes and their descendants. The two children must be adjacent. However, first may be the younger sibling of second. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + + +

          + +
          + +Generated automatically by extdoc on 970123 + + diff --git a/resources/3rdparty/cudd-2.5.0/mtr/mtr.h b/resources/3rdparty/cudd-2.5.0/mtr/mtr.h new file mode 100644 index 000000000..9cbb2d3a4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/mtr.h @@ -0,0 +1,187 @@ +/**CHeaderFile***************************************************************** + + FileName [mtr.h] + + PackageName [mtr] + + Synopsis [Multiway-branch tree manipulation] + + Description [This package provides two layers of functions. Functions + of the lower level manipulate multiway-branch trees, implemented + according to the classical scheme whereby each node points to its + first child and its previous and next siblings. These functions are + collected in mtrBasic.c.

          + Functions of the upper layer deal with group trees, that is the trees + used by group sifting to represent the grouping of variables. These + functions are collected in mtrGroup.c.] + + SeeAlso [The CUDD package documentation; specifically on group + sifting.] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: mtr.h,v 1.17 2012/02/05 01:06:19 fabio Exp $] + +******************************************************************************/ + +#ifndef __MTR +#define __MTR + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef SIZEOF_VOID_P +#define SIZEOF_VOID_P 4 +#endif +#ifndef SIZEOF_INT +#define SIZEOF_INT 4 +#endif + +#if defined(__GNUC__) +#define MTR_INLINE __inline__ +# if (__GNUC__ >2 || __GNUC_MINOR__ >=7) +# define MTR_UNUSED __attribute__ ((unused)) +# else +# define MTR_UNUSED +# endif +#else +#define MTR_INLINE +#define MTR_UNUSED +#endif + +/* Flag definitions */ +#define MTR_DEFAULT 0x00000000 +#define MTR_TERMINAL 0x00000001 +#define MTR_SOFT 0x00000002 +#define MTR_FIXED 0x00000004 +#define MTR_NEWNODE 0x00000008 + +/* MTR_MAXHIGH is defined in such a way that on 32-bit and 64-bit +** machines one can cast a value to (int) without generating a negative +** number. +*/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define MTR_MAXHIGH (((MtrHalfWord) ~0) >> 1) +#else +#define MTR_MAXHIGH ((MtrHalfWord) ~0) +#endif + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +typedef unsigned int MtrHalfWord; +#else +typedef unsigned short MtrHalfWord; +#endif + +typedef struct MtrNode { + MtrHalfWord flags; + MtrHalfWord low; + MtrHalfWord size; + MtrHalfWord index; + struct MtrNode *parent; + struct MtrNode *child; + struct MtrNode *elder; + struct MtrNode *younger; +} MtrNode; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/* Flag manipulation macros */ +#define MTR_SET(node, flag) (node->flags |= (flag)) +#define MTR_RESET(node, flag) (node->flags &= ~ (flag)) +#define MTR_TEST(node, flag) (node->flags & (flag)) + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern MtrNode * Mtr_AllocNode (void); +extern void Mtr_DeallocNode (MtrNode *node); +extern MtrNode * Mtr_InitTree (void); +extern void Mtr_FreeTree (MtrNode *node); +extern MtrNode * Mtr_CopyTree (MtrNode *node, int expansion); +extern void Mtr_MakeFirstChild (MtrNode *parent, MtrNode *child); +extern void Mtr_MakeLastChild (MtrNode *parent, MtrNode *child); +extern MtrNode * Mtr_CreateFirstChild (MtrNode *parent); +extern MtrNode * Mtr_CreateLastChild (MtrNode *parent); +extern void Mtr_MakeNextSibling (MtrNode *first, MtrNode *second); +extern void Mtr_PrintTree (MtrNode *node); +extern MtrNode * Mtr_InitGroupTree (int lower, int size); +extern MtrNode * Mtr_MakeGroup (MtrNode *root, unsigned int low, unsigned int high, unsigned int flags); +extern MtrNode * Mtr_DissolveGroup (MtrNode *group); +extern MtrNode * Mtr_FindGroup (MtrNode *root, unsigned int low, unsigned int high); +extern int Mtr_SwapGroups (MtrNode *first, MtrNode *second); +extern void Mtr_ReorderGroups(MtrNode *treenode, int *permutation); + +extern void Mtr_PrintGroups (MtrNode *root, int silent); + extern int Mtr_PrintGroupedOrder(MtrNode * root, int *invperm, FILE *fp); +extern MtrNode * Mtr_ReadGroups (FILE *fp, int nleaves); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* __MTR */ diff --git a/resources/3rdparty/cudd-2.5.0/mtr/mtrBasic.c b/resources/3rdparty/cudd-2.5.0/mtr/mtrBasic.c new file mode 100644 index 000000000..f91c63430 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/mtrBasic.c @@ -0,0 +1,450 @@ +/**CFile*********************************************************************** + + FileName [mtrBasic.c] + + PackageName [mtr] + + Synopsis [Basic manipulation of multiway branching trees.] + + Description [External procedures included in this module: +

            +
          • Mtr_AllocNode() +
          • Mtr_DeallocNode() +
          • Mtr_InitTree() +
          • Mtr_FreeTree() +
          • Mtr_CopyTree() +
          • Mtr_MakeFirstChild() +
          • Mtr_MakeLastChild() +
          • Mtr_CreateFirstChild() +
          • Mtr_CreateLastChild() +
          • Mtr_MakeNextSibling() +
          • Mtr_PrintTree() +
          + ] + + SeeAlso [cudd package] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "mtrInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] MTR_UNUSED = "$Id: mtrBasic.c,v 1.15 2012/02/05 01:06:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Allocates new tree node.] + + Description [Allocates new tree node. Returns pointer to node.] + + SideEffects [None] + + SeeAlso [Mtr_DeallocNode] + +******************************************************************************/ +MtrNode * +Mtr_AllocNode(void) +{ + MtrNode *node; + + node = ALLOC(MtrNode,1); + return node; + +} /* Mtr_AllocNode */ + + +/**Function******************************************************************** + + Synopsis [Deallocates tree node.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_AllocNode] + +******************************************************************************/ +void +Mtr_DeallocNode( + MtrNode * node /* node to be deallocated */) +{ + FREE(node); + return; + +} /* end of Mtr_DeallocNode */ + + +/**Function******************************************************************** + + Synopsis [Initializes tree with one node.] + + Description [Initializes tree with one node. Returns pointer to node.] + + SideEffects [None] + + SeeAlso [Mtr_FreeTree Mtr_InitGroupTree] + +******************************************************************************/ +MtrNode * +Mtr_InitTree(void) +{ + MtrNode *node; + + node = Mtr_AllocNode(); + if (node == NULL) return(NULL); + + node->parent = node->child = node->elder = node->younger = NULL; + node->flags = 0; + + return(node); + +} /* end of Mtr_InitTree */ + + +/**Function******************************************************************** + + Synopsis [Disposes of tree rooted at node.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_InitTree] + +******************************************************************************/ +void +Mtr_FreeTree( + MtrNode * node) +{ + if (node == NULL) return; + if (! MTR_TEST(node,MTR_TERMINAL)) Mtr_FreeTree(node->child); + Mtr_FreeTree(node->younger); + Mtr_DeallocNode(node); + return; + +} /* end of Mtr_FreeTree */ + + +/**Function******************************************************************** + + Synopsis [Makes a copy of tree.] + + Description [Makes a copy of tree. If parameter expansion is greater + than 1, it will expand the tree by that factor. It is an error for + expansion to be less than 1. Returns a pointer to the copy if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Mtr_InitTree] + +******************************************************************************/ +MtrNode * +Mtr_CopyTree( + MtrNode * node, + int expansion) +{ + MtrNode *copy; + + if (node == NULL) return(NULL); + if (expansion < 1) return(NULL); + copy = Mtr_AllocNode(); + if (copy == NULL) return(NULL); + copy->parent = copy->elder = copy->child = copy->younger = NULL; + if (node->child != NULL) { + copy->child = Mtr_CopyTree(node->child, expansion); + if (copy->child == NULL) { + Mtr_DeallocNode(copy); + return(NULL); + } + } + if (node->younger != NULL) { + copy->younger = Mtr_CopyTree(node->younger, expansion); + if (copy->younger == NULL) { + Mtr_FreeTree(copy); + return(NULL); + } + } + copy->flags = node->flags; + copy->low = node->low * expansion; + copy->size = node->size * expansion; + copy->index = node->index * expansion; + if (copy->younger) copy->younger->elder = copy; + if (copy->child) { + MtrNode *auxnode = copy->child; + while (auxnode != NULL) { + auxnode->parent = copy; + auxnode = auxnode->younger; + } + } + return(copy); + +} /* end of Mtr_CopyTree */ + + +/**Function******************************************************************** + + Synopsis [Makes child the first child of parent.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_MakeLastChild Mtr_CreateFirstChild] + +******************************************************************************/ +void +Mtr_MakeFirstChild( + MtrNode * parent, + MtrNode * child) +{ + child->parent = parent; + child->younger = parent->child; + child->elder = NULL; + if (parent->child != NULL) { +#ifdef MTR_DEBUG + assert(parent->child->elder == NULL); +#endif + parent->child->elder = child; + } + parent->child = child; + return; + +} /* end of Mtr_MakeFirstChild */ + + +/**Function******************************************************************** + + Synopsis [Makes child the last child of parent.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_MakeFirstChild Mtr_CreateLastChild] + +******************************************************************************/ +void +Mtr_MakeLastChild( + MtrNode * parent, + MtrNode * child) +{ + MtrNode *node; + + child->younger = NULL; + + if (parent->child == NULL) { + parent->child = child; + child->elder = NULL; + } else { + for (node = parent->child; + node->younger != NULL; + node = node->younger); + node->younger = child; + child->elder = node; + } + child->parent = parent; + return; + +} /* end of Mtr_MakeLastChild */ + + +/**Function******************************************************************** + + Synopsis [Creates a new node and makes it the first child of parent.] + + Description [Creates a new node and makes it the first child of + parent. Returns pointer to new child.] + + SideEffects [None] + + SeeAlso [Mtr_MakeFirstChild Mtr_CreateLastChild] + +******************************************************************************/ +MtrNode * +Mtr_CreateFirstChild( + MtrNode * parent) +{ + MtrNode *child; + + child = Mtr_AllocNode(); + if (child == NULL) return(NULL); + + child->child = NULL; + child->flags = 0; + Mtr_MakeFirstChild(parent,child); + return(child); + +} /* end of Mtr_CreateFirstChild */ + + +/**Function******************************************************************** + + Synopsis [Creates a new node and makes it the last child of parent.] + + Description [Creates a new node and makes it the last child of parent. + Returns pointer to new child.] + + SideEffects [None] + + SeeAlso [Mtr_MakeLastChild Mtr_CreateFirstChild] + +******************************************************************************/ +MtrNode * +Mtr_CreateLastChild( + MtrNode * parent) +{ + MtrNode *child; + + child = Mtr_AllocNode(); + if (child == NULL) return(NULL); + + child->child = NULL; + child->flags = 0; + Mtr_MakeLastChild(parent,child); + return(child); + +} /* end of Mtr_CreateLastChild */ + + +/**Function******************************************************************** + + Synopsis [Makes second the next sibling of first.] + + Description [Makes second the next sibling of first. Second becomes a + child of the parent of first.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Mtr_MakeNextSibling( + MtrNode * first, + MtrNode * second) +{ + second->parent = first->parent; + second->elder = first; + second->younger = first->younger; + if (first->younger != NULL) { + first->younger->elder = second; + } + first->younger = second; + return; + +} /* end of Mtr_MakeNextSibling */ + + +/**Function******************************************************************** + + Synopsis [Prints a tree, one node per line.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_PrintGroups] + +******************************************************************************/ +void +Mtr_PrintTree( + MtrNode * node) +{ + if (node == NULL) return; + (void) fprintf(stdout, +#if SIZEOF_VOID_P == 8 + "N=0x%-8lx C=0x%-8lx Y=0x%-8lx E=0x%-8lx P=0x%-8lx F=%x L=%u S=%u\n", + (unsigned long) node, (unsigned long) node->child, + (unsigned long) node->younger, (unsigned long) node->elder, + (unsigned long) node->parent, node->flags, node->low, node->size); +#else + "N=0x%-8x C=0x%-8x Y=0x%-8x E=0x%-8x P=0x%-8x F=%x L=%hu S=%hu\n", + (unsigned) node, (unsigned) node->child, + (unsigned) node->younger, (unsigned) node->elder, + (unsigned) node->parent, node->flags, node->low, node->size); +#endif + if (!MTR_TEST(node,MTR_TERMINAL)) Mtr_PrintTree(node->child); + Mtr_PrintTree(node->younger); + return; + +} /* end of Mtr_PrintTree */ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/mtr/mtrGroup.c b/resources/3rdparty/cudd-2.5.0/mtr/mtrGroup.c new file mode 100644 index 000000000..4269cf848 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/mtrGroup.c @@ -0,0 +1,877 @@ +/**CFile*********************************************************************** + + FileName [mtrGroup.c] + + PackageName [mtr] + + Synopsis [Functions to support group specification for reordering.] + + Description [External procedures included in this module: +
            +
          • Mtr_InitGroupTree() +
          • Mtr_MakeGroup() +
          • Mtr_DissolveGroup() +
          • Mtr_FindGroup() +
          • Mtr_SwapGroups() +
          • Mtr_ReorderGroups() +
          • Mtr_PrintGroups() +
          • Mtr_ReadGroups() +
          + Static procedures included in this module: +
            +
          • mtrShiftHL +
          + ] + + SeeAlso [cudd package] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "mtrInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] MTR_UNUSED = "$Id: mtrGroup.c,v 1.21 2012/02/05 01:06:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int mtrShiftHL (MtrNode *node, int shift); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Allocate new tree.] + + Description [Allocate new tree with one node, whose low and size + fields are specified by the lower and size parameters. + Returns pointer to tree root.] + + SideEffects [None] + + SeeAlso [Mtr_InitTree Mtr_FreeTree] + +******************************************************************************/ +MtrNode * +Mtr_InitGroupTree( + int lower, + int size) +{ + MtrNode *root; + + root = Mtr_InitTree(); + if (root == NULL) return(NULL); + root->flags = MTR_DEFAULT; + root->low = lower; + root->size = size; + return(root); + +} /* end of Mtr_InitGroupTree */ + + +/**Function******************************************************************** + + Synopsis [Makes a new group with size leaves starting at low.] + + Description [Makes a new group with size leaves starting at low. + If the new group intersects an existing group, it must + either contain it or be contained by it. This procedure relies on + the low and size fields of each node. It also assumes that the + children of each node are sorted in order of increasing low. In + case of a valid request, the flags of the new group are set to the + value passed in `flags.' Returns the pointer to the root of the new + group upon successful termination; NULL otherwise. If the group + already exists, the pointer to its root is returned.] + + SideEffects [None] + + SeeAlso [Mtr_DissolveGroup Mtr_ReadGroups Mtr_FindGroup] + +******************************************************************************/ +MtrNode * +Mtr_MakeGroup( + MtrNode * root /* root of the group tree */, + unsigned int low /* lower bound of the group */, + unsigned int size /* size of the group */, + unsigned int flags /* flags for the new group */) +{ + MtrNode *node, + *first, + *last, + *previous, + *newn; + + /* Sanity check. */ + if (size == 0) + return(NULL); + + /* Check whether current group includes new group. This check is + ** necessary at the top-level call. In the subsequent calls it is + ** redundant. */ + if (low < (unsigned int) root->low || + low + size > (unsigned int) (root->low + root->size)) + return(NULL); + + /* At this point we know that the new group is contained + ** in the group of root. We have two possible cases here: + ** - root is a terminal node; + ** - root has children. */ + + /* Root has no children: create a new group. */ + if (root->child == NULL) { + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->parent = root; + newn->elder = newn->younger = newn->child = NULL; + root->child = newn; + return(newn); + } + + /* Root has children: Find all children of root that are included + ** in the new group. If the group of any child entirely contains + ** the new group, call Mtr_MakeGroup recursively. */ + previous = NULL; + first = root->child; /* guaranteed to be non-NULL */ + while (first != NULL && low >= (unsigned int) (first->low + first->size)) { + previous = first; + first = first->younger; + } + if (first == NULL) { + /* We have scanned the entire list and we need to append a new + ** child at the end of it. Previous points to the last child + ** of root. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->parent = root; + newn->elder = previous; + previous->younger = newn; + newn->younger = newn->child = NULL; + return(newn); + } + /* Here first is non-NULL and low < first->low + first->size. */ + if (low >= (unsigned int) first->low && + low + size <= (unsigned int) (first->low + first->size)) { + /* The new group is contained in the group of first. */ + newn = Mtr_MakeGroup(first, low, size, flags); + return(newn); + } else if (low + size <= first->low) { + /* The new group is entirely contained in the gap between + ** previous and first. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->child = NULL; + newn->parent = root; + newn->elder = previous; + newn->younger = first; + first->elder = newn; + if (previous != NULL) { + previous->younger = newn; + } else { + root->child = newn; + } + return(newn); + } else if (low < (unsigned int) first->low && + low + size < (unsigned int) (first->low + first->size)) { + /* Trying to cut an existing group: not allowed. */ + return(NULL); + } else if (low > first->low) { + /* The new group neither is contained in the group of first + ** (this was tested above) nor contains it. It is therefore + ** trying to cut an existing group: not allowed. */ + return(NULL); + } + + /* First holds the pointer to the first child contained in the new + ** group. Here low <= first->low and low + size >= first->low + + ** first->size. One of the two inequalities is strict. */ + last = first->younger; + while (last != NULL && + (unsigned int) (last->low + last->size) < low + size) { + last = last->younger; + } + if (last == NULL) { + /* All the chilren of root from first onward become children + ** of the new group. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->child = first; + newn->parent = root; + newn->elder = previous; + newn->younger = NULL; + first->elder = NULL; + if (previous != NULL) { + previous->younger = newn; + } else { + root->child = newn; + } + last = first; + while (last != NULL) { + last->parent = newn; + last = last->younger; + } + return(newn); + } + + /* Here last != NULL and low + size <= last->low + last->size. */ + if (low + size - 1 >= (unsigned int) last->low && + low + size < (unsigned int) (last->low + last->size)) { + /* Trying to cut an existing group: not allowed. */ + return(NULL); + } + + /* First and last point to the first and last of the children of + ** root that are included in the new group. Allocate a new node + ** and make all children of root between first and last chidren of + ** the new node. Previous points to the child of root immediately + ** preceeding first. If it is NULL, then first is the first child + ** of root. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->child = first; + newn->parent = root; + if (previous == NULL) { + root->child = newn; + } else { + previous->younger = newn; + } + newn->elder = previous; + newn->younger = last->younger; + if (last->younger != NULL) { + last->younger->elder = newn; + } + last->younger = NULL; + first->elder = NULL; + for (node = first; node != NULL; node = node->younger) { + node->parent = newn; + } + + return(newn); + +} /* end of Mtr_MakeGroup */ + + +/**Function******************************************************************** + + Synopsis [Merges the children of `group' with the children of its + parent.] + + Description [Merges the children of `group' with the children of its + parent. Disposes of the node pointed by group. If group is the + root of the group tree, this procedure leaves the tree unchanged. + Returns the pointer to the parent of `group' upon successful + termination; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Mtr_MakeGroup] + +******************************************************************************/ +MtrNode * +Mtr_DissolveGroup( + MtrNode * group /* group to be dissolved */) +{ + MtrNode *parent; + MtrNode *last; + + parent = group->parent; + + if (parent == NULL) return(NULL); + if (MTR_TEST(group,MTR_TERMINAL) || group->child == NULL) return(NULL); + + /* Make all children of group children of its parent, and make + ** last point to the last child of group. */ + for (last = group->child; last->younger != NULL; last = last->younger) { + last->parent = parent; + } + last->parent = parent; + + last->younger = group->younger; + if (group->younger != NULL) { + group->younger->elder = last; + } + + group->child->elder = group->elder; + if (group == parent->child) { + parent->child = group->child; + } else { + group->elder->younger = group->child; + } + + Mtr_DeallocNode(group); + return(parent); + +} /* end of Mtr_DissolveGroup */ + + +/**Function******************************************************************** + + Synopsis [Finds a group with size leaves starting at low, if it exists.] + + Description [Finds a group with size leaves starting at low, if it + exists. This procedure relies on the low and size fields of each + node. It also assumes that the children of each node are sorted in + order of increasing low. Returns the pointer to the root of the + group upon successful termination; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +MtrNode * +Mtr_FindGroup( + MtrNode * root /* root of the group tree */, + unsigned int low /* lower bound of the group */, + unsigned int size /* upper bound of the group */) +{ + MtrNode *node; + +#ifdef MTR_DEBUG + /* We cannot have a non-empty proper subgroup of a singleton set. */ + assert(!MTR_TEST(root,MTR_TERMINAL)); +#endif + + /* Sanity check. */ + if (size < 1) return(NULL); + + /* Check whether current group includes the group sought. This + ** check is necessary at the top-level call. In the subsequent + ** calls it is redundant. */ + if (low < (unsigned int) root->low || + low + size > (unsigned int) (root->low + root->size)) + return(NULL); + + if (root->size == size && root->low == low) + return(root); + + if (root->child == NULL) + return(NULL); + + /* Find all chidren of root that are included in the new group. If + ** the group of any child entirely contains the new group, call + ** Mtr_MakeGroup recursively. */ + node = root->child; + while (low >= (unsigned int) (node->low + node->size)) { + node = node->younger; + } + if (low + size <= (unsigned int) (node->low + node->size)) { + /* The group is contained in the group of node. */ + node = Mtr_FindGroup(node, low, size); + return(node); + } else { + return(NULL); + } + +} /* end of Mtr_FindGroup */ + + +/**Function******************************************************************** + + Synopsis [Swaps two children of a tree node.] + + Description [Swaps two children of a tree node. Adjusts the high and + low fields of the two nodes and their descendants. The two children + must be adjacent. However, first may be the younger sibling of second. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Mtr_SwapGroups( + MtrNode * first /* first node to be swapped */, + MtrNode * second /* second node to be swapped */) +{ + MtrNode *node; + MtrNode *parent; + int sizeFirst; + int sizeSecond; + + if (second->younger == first) { /* make first first */ + node = first; + first = second; + second = node; + } else if (first->younger != second) { /* non-adjacent */ + return(0); + } + + sizeFirst = first->size; + sizeSecond = second->size; + + /* Swap the two nodes. */ + parent = first->parent; + if (parent == NULL || second->parent != parent) return(0); + if (parent->child == first) { + parent->child = second; + } else { /* first->elder != NULL */ + first->elder->younger = second; + } + if (second->younger != NULL) { + second->younger->elder = first; + } + first->younger = second->younger; + second->elder = first->elder; + first->elder = second; + second->younger = first; + + /* Adjust the high and low fields. */ + if (!mtrShiftHL(first,sizeSecond)) return(0); + if (!mtrShiftHL(second,-sizeFirst)) return(0); + + return(1); + +} /* end of Mtr_SwapGroups */ + + +/**Function******************************************************************** + + Synopsis [Fix variable tree at the end of tree sifting.] + + Description [Fix the levels in the variable tree sorting siblings + according to them. It should be called on a non-NULL tree. It then + maintains this invariant. It applies insertion sorting to the list of + siblings The order is determined by permutation, which is used to find + the new level of the node index. Index must refer to the first variable + in the group.] + + SideEffects [The tree is modified.] + + SeeAlso [] + +******************************************************************************/ +void +Mtr_ReorderGroups( + MtrNode *treenode, + int *permutation) +{ + MtrNode *auxnode; + /* Initialize sorted list to first element. */ + MtrNode *sorted = treenode; + sorted->low = permutation[sorted->index]; + if (sorted->child != NULL) + Mtr_ReorderGroups(sorted->child, permutation); + + auxnode = treenode->younger; + while (auxnode != NULL) { + MtrNode *rightplace; + MtrNode *moving = auxnode; + auxnode->low = permutation[auxnode->index]; + if (auxnode->child != NULL) + Mtr_ReorderGroups(auxnode->child, permutation); + rightplace = auxnode->elder; + /* Find insertion point. */ + while (rightplace != NULL && auxnode->low < rightplace->low) + rightplace = rightplace->elder; + auxnode = auxnode->younger; + if (auxnode != NULL) { + auxnode->elder = moving->elder; + auxnode->elder->younger = auxnode; + } else { + moving->elder->younger = NULL; + } + if (rightplace == NULL) { /* Move to head of sorted list. */ + sorted->elder = moving; + moving->elder = NULL; + moving->younger = sorted; + sorted = moving; + } else { /* Splice. */ + moving->elder = rightplace; + moving->younger = rightplace->younger; + if (rightplace->younger != NULL) + rightplace->younger->elder = moving; + rightplace->younger = moving; + } + } + /* Fix parent. */ + if (sorted->parent != NULL) + sorted->parent->child = sorted; + +} /* end of Mtr_ReorderGroups */ + + +/**Function******************************************************************** + + Synopsis [Prints the groups as a parenthesized list.] + + Description [Prints the groups as a parenthesized list. After each + group, the group's flag are printed, preceded by a `|'. For each + flag (except MTR_TERMINAL) a character is printed. +
            +
          • F: MTR_FIXED +
          • N: MTR_NEWNODE +
          • S: MTR_SOFT +
          + The second argument, silent, if different from 0, causes + Mtr_PrintGroups to only check the syntax of the group tree. + ] + + SideEffects [None] + + SeeAlso [Mtr_PrintTree] + +******************************************************************************/ +void +Mtr_PrintGroups( + MtrNode * root /* root of the group tree */, + int silent /* flag to check tree syntax only */) +{ + MtrNode *node; + + assert(root != NULL); + assert(root->younger == NULL || root->younger->elder == root); + assert(root->elder == NULL || root->elder->younger == root); +#if SIZEOF_VOID_P == 8 + if (!silent) (void) printf("(%u",root->low); +#else + if (!silent) (void) printf("(%hu",root->low); +#endif + if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) { + if (!silent) (void) printf(","); + } else { + node = root->child; + while (node != NULL) { + assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size)); + assert(node->parent == root); + Mtr_PrintGroups(node,silent); + node = node->younger; + } + } + if (!silent) { +#if SIZEOF_VOID_P == 8 + (void) printf("%u", root->low + root->size - 1); +#else + (void) printf("%hu", root->low + root->size - 1); +#endif + if (root->flags != MTR_DEFAULT) { + (void) printf("|"); + if (MTR_TEST(root,MTR_FIXED)) (void) printf("F"); + if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N"); + if (MTR_TEST(root,MTR_SOFT)) (void) printf("S"); + } + (void) printf(")"); + if (root->parent == NULL) (void) printf("\n"); + } + assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0); + return; + +} /* end of Mtr_PrintGroups */ + + +/**Function******************************************************************** + + Synopsis [Prints the variable order as a parenthesized list.] + + Description [Prints the variable order as a parenthesized list. After each + group, the group's flag are printed, preceded by a `|'. For each + flag (except MTR_TERMINAL) a character is printed. +
            +
          • F: MTR_FIXED +
          • N: MTR_NEWNODE +
          • S: MTR_SOFT +
          + The second argument, gives the map from levels to variable indices. + ] + + SideEffects [None] + + SeeAlso [Mtr_PrintGroups] + +******************************************************************************/ +int +Mtr_PrintGroupedOrder( + MtrNode * root /* root of the group tree */, + int *invperm /* map from levels to indices */, + FILE *fp /* output file */) +{ + MtrNode *child; + MtrHalfWord level; + int retval; + + assert(root != NULL); + assert(root->younger == NULL || root->younger->elder == root); + assert(root->elder == NULL || root->elder->younger == root); + retval = fprintf(fp,"("); + if (retval == EOF) return(0); + level = root->low; + child = root->child; + while (child != NULL) { + assert(child->low >= root->low && (child->low + child->size) <= (root->low + root->size)); + assert(child->parent == root); + while (level < child->low) { + retval = fprintf(fp,"%d%s", invperm[level], (level < root->low + root->size - 1) ? "," : ""); + if (retval == EOF) return(0); + level++; + } + retval = Mtr_PrintGroupedOrder(child,invperm,fp); + if (retval == 0) return(0); + level += child->size; + if (level < root->low + root->size - 1) { + retval = fprintf(fp,","); + if (retval == EOF) return(0); + } + child = child->younger; + } + while (level < root->low + root->size) { + retval = fprintf(fp,"%d%s", invperm[level], (level < root->low + root->size - 1) ? "," : ""); + if (retval == EOF) return(0); + level++; + } + if (root->flags != MTR_DEFAULT) { + retval = fprintf(fp,"|"); + if (retval == EOF) return(0); + if (MTR_TEST(root,MTR_FIXED)) { + retval = fprintf(fp,"F"); + if (retval == EOF) return(0); + } + if (MTR_TEST(root,MTR_NEWNODE)) { + retval = fprintf(fp,"N"); + if (retval == EOF) return(0); + } + if (MTR_TEST(root,MTR_SOFT)) { + retval = fprintf(fp,"S"); + if (retval == EOF) return(0); + } + } + retval = fprintf(fp,")"); + if (retval == EOF) return(0); + if (root->parent == NULL) { + retval = fprintf(fp,"\n"); + if (retval == EOF) return(0); + } + assert((root->flags &~(MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0); + return(1); + +} /* end of Mtr_PrintGroupedOrder */ + + +/**Function******************************************************************** + + Synopsis [Reads groups from a file and creates a group tree.] + + Description [Reads groups from a file and creates a group tree. + Each group is specified by three fields: + + low size flags. + + Low and size are (short) integers. Flags is a string composed of the + following characters (with associated translation): +
            +
          • D: MTR_DEFAULT +
          • F: MTR_FIXED +
          • N: MTR_NEWNODE +
          • S: MTR_SOFT +
          • T: MTR_TERMINAL +
          + Normally, the only flags that are needed are D and F. Groups and + fields are separated by white space (spaces, tabs, and newlines). + Returns a pointer to the group tree if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Mtr_InitGroupTree Mtr_MakeGroup] + +******************************************************************************/ +MtrNode * +Mtr_ReadGroups( + FILE * fp /* file pointer */, + int nleaves /* number of leaves of the new tree */) +{ + int low; + int size; + int err; + unsigned int flags; + MtrNode *root; + MtrNode *node; + char attrib[8*sizeof(unsigned int)+1]; + char *c; + + root = Mtr_InitGroupTree(0,nleaves); + if (root == NULL) return NULL; + + while (! feof(fp)) { + /* Read a triple and check for consistency. */ + err = fscanf(fp, "%d %d %s", &low, &size, attrib); + if (err == EOF) { + break; + } else if (err != 3) { + Mtr_FreeTree(root); + return(NULL); + } else if (low < 0 || low+size > nleaves || size < 1) { + Mtr_FreeTree(root); + return(NULL); + } else if (strlen(attrib) > 8 * sizeof(MtrHalfWord)) { + /* Not enough bits in the flags word to store these many + ** attributes. */ + Mtr_FreeTree(root); + return(NULL); + } + + /* Parse the flag string. Currently all flags are permitted, + ** to make debugging easier. Normally, specifying NEWNODE + ** wouldn't be allowed. */ + flags = MTR_DEFAULT; + for (c=attrib; *c != 0; c++) { + switch (*c) { + case 'D': + break; + case 'F': + flags |= MTR_FIXED; + break; + case 'N': + flags |= MTR_NEWNODE; + break; + case 'S': + flags |= MTR_SOFT; + break; + case 'T': + flags |= MTR_TERMINAL; + break; + default: + return NULL; + } + } + node = Mtr_MakeGroup(root, (MtrHalfWord) low, (MtrHalfWord) size, + flags); + if (node == NULL) { + Mtr_FreeTree(root); + return(NULL); + } + } + + return(root); + +} /* end of Mtr_ReadGroups */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Adjusts the low fields of a node and its descendants.] + + Description [Adjusts the low fields of a node and its + descendants. Adds shift to low of each node. Checks that no + out-of-bounds values result. Returns 1 in case of success; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +mtrShiftHL( + MtrNode * node /* group tree node */, + int shift /* amount by which low should be changed */) +{ + MtrNode *auxnode; + int low; + + low = (int) node->low; + + + low += shift; + + if (low < 0 || low + (int) (node->size - 1) > (int) MTR_MAXHIGH) return(0); + + node->low = (MtrHalfWord) low; + + if (!MTR_TEST(node,MTR_TERMINAL) && node->child != NULL) { + auxnode = node->child; + do { + if (!mtrShiftHL(auxnode,shift)) return(0); + auxnode = auxnode->younger; + } while (auxnode != NULL); + } + + return(1); + +} /* end of mtrShiftHL */ diff --git a/resources/3rdparty/cudd-2.5.0/mtr/mtrInt.h b/resources/3rdparty/cudd-2.5.0/mtr/mtrInt.h new file mode 100644 index 000000000..00b2e9969 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/mtrInt.h @@ -0,0 +1,92 @@ +/**CHeaderFile***************************************************************** + + FileName [mtrInt.h] + + PackageName [mtr] + + Synopsis [Internal data structures of the mtr package] + + Description [In this package all definitions are external.] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: mtrInt.h,v 1.3 2012/02/05 01:06:19 fabio Exp $] + +******************************************************************************/ + +#ifndef _MTRINT +#define _MTRINT + +#include "mtr.h" + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + +#endif /* _MTRINT */ diff --git a/resources/3rdparty/cudd-2.5.0/mtr/test.groups b/resources/3rdparty/cudd-2.5.0/mtr/test.groups new file mode 100644 index 000000000..fbedcaf1e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/test.groups @@ -0,0 +1,5 @@ +0 6 D +6 6 F +0 2 D +2 2 D +4 2 D diff --git a/resources/3rdparty/cudd-2.5.0/mtr/testmtr.c b/resources/3rdparty/cudd-2.5.0/mtr/testmtr.c new file mode 100644 index 000000000..54f069d56 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/testmtr.c @@ -0,0 +1,270 @@ +/**CFile*********************************************************************** + + FileName [testmtr.c] + + PackageName [mtr] + + Synopsis [Test program for the mtr package.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "mtr.h" + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] MTR_UNUSED = "$Id: testmtr.c,v 1.5 2012/02/05 06:10:35 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define TESTMTR_VERSION\ + "TestMtr Version #0.6, Release date 2/6/12" + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void usage (char *prog); +static FILE * open_file (const char *filename, const char *mode); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Main program for testmtr.] + + Description [Main program for testmtr. Performs initialization. + Reads command line options and network(s). Builds some simple trees + and prints them out.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +main( + int argc, + char ** argv) +{ + MtrNode *root, + *node; + int i, + c, + pr = 0; + FILE *fp; + const char *file = NULL; + + (void) printf("# %s\n", TESTMTR_VERSION); + /* Echo command line and arguments. */ + (void) printf("#"); + for(i = 0; i < argc; i++) { + (void) printf(" %s", argv[i]); + } + (void) printf("\n"); + (void) fflush(stdout); + + while ((c = getopt(argc, argv, "Mhp:")) != EOF) { + switch(c) { + case 'M': +#ifdef MNEMOSYNE + (void) mnem_setrecording(0); +#endif + break; + case 'p': + pr = atoi(optarg); + break; + case 'h': + default: + usage(argv[0]); + break; + } + } + + if (argc - optind == 0) { + file = "-"; + } else if (argc - optind == 1) { + file = argv[optind]; + } else { + usage(argv[0]); + } + + /* Create and print a simple tree. */ + root = Mtr_InitTree(); + root->flags = 0; + node = Mtr_CreateFirstChild(root); + node->flags = 1; + node = Mtr_CreateLastChild(root); + node->flags = 2; + node = Mtr_CreateFirstChild(root); + node->flags = 3; + node = Mtr_AllocNode(); + node->flags = 4; + Mtr_MakeNextSibling(root->child,node); + Mtr_PrintTree(root); + Mtr_FreeTree(root); + (void) printf("#------------------------\n"); + + /* Create an initial tree in which all variables belong to one group. */ + root = Mtr_InitGroupTree(0,12); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + node = Mtr_MakeGroup(root,0,6,MTR_DEFAULT); + node = Mtr_MakeGroup(root,6,6,MTR_DEFAULT); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + for (i = 0; i < 6; i+=2) { + node = Mtr_MakeGroup(root,(unsigned) i,(unsigned) 2,MTR_DEFAULT); + } + node = Mtr_MakeGroup(root,0,12,MTR_FIXED); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + /* Print a partial tree. */ + (void) printf("# "); + Mtr_PrintGroups(root->child,pr == 0); (void) printf("\n"); + node = Mtr_FindGroup(root,0,6); + node = Mtr_DissolveGroup(node); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + node = Mtr_FindGroup(root,4,2); + if (!Mtr_SwapGroups(node,node->younger)) { + (void) printf("error in Mtr_SwapGroups\n"); + exit(3); + } + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); + Mtr_FreeTree(root); + (void) printf("#------------------------\n"); + + /* Create a group tree with fixed subgroups. */ + root = Mtr_InitGroupTree(0,4); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + node = Mtr_MakeGroup(root,0,2,MTR_FIXED); + node = Mtr_MakeGroup(root,2,2,MTR_FIXED); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + Mtr_FreeTree(root); + (void) printf("#------------------------\n"); + + /* Open input file. */ + fp = open_file(file, "r"); + root = Mtr_ReadGroups(fp,12); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + + Mtr_FreeTree(root); + +#ifdef MNEMOSYNE + mnem_writestats(); +#endif + + exit(0); + /* NOTREACHED */ + +} /* end of main */ + + +/**Function******************************************************************** + + Synopsis [Prints usage message and exits.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static void +usage( + char * prog) +{ + (void) fprintf(stderr, "usage: %s [options] [file]\n", prog); + (void) fprintf(stderr, " -M\t\tturns off memory allocation recording\n"); + (void) fprintf(stderr, " -h\t\tprints this message\n"); + (void) fprintf(stderr, " -p n\t\tcontrols verbosity\n"); + exit(2); + +} /* end of usage */ + + +/**Function******************************************************************** + + Synopsis [Opens a file.] + + Description [Opens a file, or fails with an error message and exits. + Allows '-' as a synonym for standard input.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static FILE * +open_file( + const char * filename, + const char * mode) +{ + FILE *fp; + + if (strcmp(filename, "-") == 0) { + return mode[0] == 'r' ? stdin : stdout; + } else if ((fp = fopen(filename, mode)) == NULL) { + perror(filename); + exit(1); + } + return(fp); + +} /* end of open_file */ + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/C17.blif b/resources/3rdparty/cudd-2.5.0/nanotrav/C17.blif new file mode 100644 index 000000000..b022c7f95 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/C17.blif @@ -0,0 +1,16 @@ +.model C17.iscas +.inputs 1GAT(0) 2GAT(1) 3GAT(2) 6GAT(3) 7GAT(4) +.outputs 22GAT(10) 23GAT(9) +.names 3GAT(2) 6GAT(3) 11GAT(5) +11 0 +.names 1GAT(0) 3GAT(2) 10GAT(6) +11 0 +.names 11GAT(5) 7GAT(4) 19GAT(7) +11 0 +.names 2GAT(1) 11GAT(5) 16GAT(8) +11 0 +.names 16GAT(8) 19GAT(7) 23GAT(9) +11 0 +.names 10GAT(6) 16GAT(8) 22GAT(10) +11 0 +.end diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/C17.out b/resources/3rdparty/cudd-2.5.0/nanotrav/C17.out new file mode 100644 index 000000000..dd7302744 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/C17.out @@ -0,0 +1,101 @@ +# Nanotrav Version #0.12, Release date 2003/12/31 +# ./nanotrav -p 1 -cover C17.blif +# CUDD Version 2.4.2 +Order before final reordering +1GAT(0) 2GAT(1) 3GAT(2) 6GAT(3) 7GAT(4) +22GAT(10): 8 nodes 18 minterms +23GAT(9): 8 nodes 18 minterms +22GAT(10): 5 nodes 3 minterms +Testing iterator on ZDD paths: +-1-0- 1 +-10-- 1 +1-1-- 1 + +1-1-- 1 +-10-- 1 +-1-0- 1 +23GAT(9): 6 nodes 4 minterms +Testing iterator on ZDD paths: +---01 1 +--0-1 1 +-1-0- 1 +-10-- 1 + +-10-- 1 +-1-0- 1 +--0-1 1 +---01 1 +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000 +Maximum number of variable swaps per reordering: 2000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: no +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: yes +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 10 +Arc violation threshold: 10 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 4004 +**** CUDD non-modifiable parameters **** +Memory in use: 4737732 +Peak number of nodes: 1022 +Peak number of live nodes: 19 +Number of BDD variables: 5 +Number of ZDD variables: 10 +Number of cache entries: 32768 +Number of cache look-ups: 125 +Number of cache hits: 21 +Number of cache insertions: 117 +Number of cache collisions: 0 +Number of cache deletions: 35 +Cache used slots = 0.33% (expected 0.25%) +Soft limit for cache size: 16384 +Number of buckets in unique table: 4096 +Used buckets in unique table: 1.22% (expected 1.24%) +Number of BDD and ADD nodes: 24 +Number of ZDD nodes: 27 +Number of dead BDD and ADD nodes: 8 +Number of dead ZDD nodes: 17 +Total number of nodes allocated: 67 +Total number of nodes reclaimed: 8 +Garbage collections so far: 1 +Time for garbage collection: 0.00 sec +Reorderings so far: 0 +Time for reordering: 0.00 sec +Final size: 11 +total time = 0.00 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 0.0 seconds +System time 0.0 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131815K +Virtual data size = 297K + data size initialized = 25K + data size uninitialized = 137K + data size sbrk = 135K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 8 +Minor page faults = 1413 +Swaps = 0 +Input blocks = 0 +Output blocks = 0 +Context switch (voluntary) = 12 +Context switch (involuntary) = 0 diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/C880.blif b/resources/3rdparty/cudd-2.5.0/nanotrav/C880.blif new file mode 100644 index 000000000..38ee2c965 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/C880.blif @@ -0,0 +1,770 @@ +.model C880.iscas +.inputs 1GAT(0) 8GAT(1) 13GAT(2) 17GAT(3) 26GAT(4) 29GAT(5) 36GAT(6) 42GAT(7) 51GAT(8) 55GAT(9) 59GAT(10) 68GAT(11) 72GAT(12) 73GAT(13) 74GAT(14) 75GAT(15) 80GAT(16) 85GAT(17) 86GAT(18) 87GAT(19) 88GAT(20) 89GAT(21) 90GAT(22) 91GAT(23) 96GAT(24) 101GAT(25) 106GAT(26) 111GAT(27) 116GAT(28) 121GAT(29) 126GAT(30) 130GAT(31) 135GAT(32) 138GAT(33) 143GAT(34) 146GAT(35) 149GAT(36) 152GAT(37) 153GAT(38) 156GAT(39) 159GAT(40) 165GAT(41) 171GAT(42) 177GAT(43) 183GAT(44) 189GAT(45) 195GAT(46) 201GAT(47) 207GAT(48) 210GAT(49) 219GAT(50) 228GAT(51) 237GAT(52) 246GAT(53) 255GAT(54) 259GAT(55) 260GAT(56) 261GAT(57) 267GAT(58) 268GAT(59) +.outputs 388GAT(133) 389GAT(132) 390GAT(131) 391GAT(124) 418GAT(168) 419GAT(164) 420GAT(158) 421GAT(162) 422GAT(161) 423GAT(155) 446GAT(183) 447GAT(182) 448GAT(179) 449GAT(176) 450GAT(173) 767GAT(349) 768GAT(334) 850GAT(404) 863GAT(424) 864GAT(423) 865GAT(422) 866GAT(426) 874GAT(433) 878GAT(442) 879GAT(441) 880GAT(440) +.names 268GAT(59) 310GAT(60) +1 0 +.names 255GAT(54) 267GAT(58) 341GAT(61) +11 1 +.names 255GAT(54) 260GAT(56) 339GAT(62) +11 1 +.names 255GAT(54) 259GAT(55) 337GAT(63) +11 1 +.names 195GAT(46) 201GAT(47) 331GAT(64) +00 0 +.names 195GAT(46) 201GAT(47) 330GAT(65) +11 0 +.names 183GAT(44) 189GAT(45) 329GAT(66) +00 0 +.names 183GAT(44) 189GAT(45) 328GAT(67) +11 0 +.names 171GAT(42) 177GAT(43) 327GAT(68) +00 0 +.names 171GAT(42) 177GAT(43) 326GAT(69) +11 0 +.names 159GAT(40) 165GAT(41) 325GAT(70) +00 0 +.names 159GAT(40) 165GAT(41) 324GAT(71) +11 0 +.names 152GAT(37) 138GAT(33) 318GAT(72) +11 1 +.names 210GAT(49) 121GAT(29) 340GAT(73) +11 1 +.names 121GAT(29) 126GAT(30) 308GAT(74) +00 0 +.names 121GAT(29) 126GAT(30) 307GAT(75) +11 0 +.names 210GAT(49) 116GAT(28) 338GAT(76) +11 1 +.names 210GAT(49) 111GAT(27) 336GAT(77) +11 1 +.names 111GAT(27) 116GAT(28) 306GAT(78) +00 0 +.names 111GAT(27) 116GAT(28) 305GAT(79) +11 0 +.names 210GAT(49) 106GAT(26) 335GAT(80) +11 1 +.names 210GAT(49) 101GAT(25) 334GAT(81) +11 1 +.names 101GAT(25) 106GAT(26) 304GAT(82) +00 0 +.names 101GAT(25) 106GAT(26) 303GAT(83) +11 0 +.names 210GAT(49) 96GAT(24) 333GAT(84) +11 1 +.names 210GAT(49) 91GAT(23) 332GAT(85) +11 1 +.names 91GAT(23) 96GAT(24) 302GAT(86) +00 0 +.names 91GAT(23) 96GAT(24) 301GAT(87) +11 0 +.names 87GAT(19) 88GAT(20) 298GAT(88) +00 0 +.names 85GAT(17) 86GAT(18) 297GAT(89) +11 1 +.names 59GAT(10) 156GAT(39) 319GAT(90) +11 0 +.names 59GAT(10) 75GAT(15) 80GAT(16) 293GAT(91) +111 1 +.names 59GAT(10) 68GAT(11) 74GAT(14) 286GAT(92) +111 0 +.names 51GAT(8) 138GAT(33) 316GAT(93) +11 1 +.names 59GAT(10) 75GAT(15) 42GAT(7) 294GAT(94) +111 1 +.names 59GAT(10) 42GAT(7) 68GAT(11) 72GAT(12) 284GAT(95) +1111 0 +.names 59GAT(10) 36GAT(6) 42GAT(7) 296GAT(96) +111 1 +.names 59GAT(10) 36GAT(6) 80GAT(16) 295GAT(97) +111 1 +.names 29GAT(5) 36GAT(6) 42GAT(7) 292GAT(98) +111 1 +.names 29GAT(5) 36GAT(6) 80GAT(16) 291GAT(99) +111 1 +.names 29GAT(5) 75GAT(15) 42GAT(7) 290GAT(100) +111 1 +.names 29GAT(5) 75GAT(15) 80GAT(16) 287GAT(101) +111 1 +.names 29GAT(5) 68GAT(11) 285GAT(102) +11 0 +.names 29GAT(5) 36GAT(6) 42GAT(7) 273GAT(103) +111 1 +.names 17GAT(3) 42GAT(7) 323GAT(104) +11 1 +.names 17GAT(3) 42GAT(7) 322GAT(105) +00 1 +.names 17GAT(3) 138GAT(33) 317GAT(106) +11 1 +.names 8GAT(1) 138GAT(33) 309GAT(107) +11 1 +.names 1GAT(0) 8GAT(1) 13GAT(2) 55GAT(9) 280GAT(108) +1111 0 +.names 1GAT(0) 8GAT(1) 51GAT(8) 17GAT(3) 279GAT(109) +1111 0 +.names 1GAT(0) 26GAT(4) 51GAT(8) 276GAT(110) +111 1 +.names 1GAT(0) 26GAT(4) 13GAT(2) 17GAT(3) 270GAT(111) +1111 0 +.names 1GAT(0) 8GAT(1) 13GAT(2) 17GAT(3) 269GAT(112) +1111 0 +.names 310GAT(60) 369GAT(113) +1 0 +.names 330GAT(65) 331GAT(64) 385GAT(114) +11 0 +.names 328GAT(67) 329GAT(66) 382GAT(115) +11 0 +.names 326GAT(69) 327GAT(68) 379GAT(116) +11 0 +.names 324GAT(71) 325GAT(70) 376GAT(117) +11 0 +.names 307GAT(75) 308GAT(74) 366GAT(118) +11 0 +.names 305GAT(79) 306GAT(78) 363GAT(119) +11 0 +.names 303GAT(83) 304GAT(82) 360GAT(120) +11 0 +.names 301GAT(87) 302GAT(86) 357GAT(121) +11 0 +.names 90GAT(22) 298GAT(88) 356GAT(122) +11 1 +.names 89GAT(21) 298GAT(88) 355GAT(123) +11 0 +.names 297GAT(89) 391GAT(124) +1 1 +.names 293GAT(91) 351GAT(125) +1 0 +.names 280GAT(108) 286GAT(92) 350GAT(126) +00 0 +.names 294GAT(94) 352GAT(127) +1 0 +.names 280GAT(108) 284GAT(95) 348GAT(128) +00 1 +.names 296GAT(96) 354GAT(129) +1 0 +.names 295GAT(97) 353GAT(130) +1 0 +.names 292GAT(98) 390GAT(131) +1 1 +.names 291GAT(99) 389GAT(132) +1 1 +.names 290GAT(100) 388GAT(133) +1 1 +.names 280GAT(108) 285GAT(102) 349GAT(134) +00 0 +.names 273GAT(103) 343GAT(135) +1 0 +.names 270GAT(111) 273GAT(103) 344GAT(136) +00 0 +.names 322GAT(105) 323GAT(104) 375GAT(137) +00 1 +.names 279GAT(109) 347GAT(138) +1 0 +.names 276GAT(110) 345GAT(139) +1 0 +.names 276GAT(110) 346GAT(140) +1 0 +.names 269GAT(112) 342GAT(141) +1 0 +.names 210GAT(49) 369GAT(113) 417GAT(142) +11 1 +.names 385GAT(114) 415GAT(143) +1 0 +.names 382GAT(115) 385GAT(114) 416GAT(144) +11 1 +.names 382GAT(115) 414GAT(145) +1 0 +.names 379GAT(116) 412GAT(146) +1 0 +.names 376GAT(117) 379GAT(116) 413GAT(147) +11 1 +.names 376GAT(117) 411GAT(148) +1 0 +.names 366GAT(118) 408GAT(149) +1 0 +.names 363GAT(119) 366GAT(118) 409GAT(150) +11 1 +.names 363GAT(119) 407GAT(151) +1 0 +.names 360GAT(120) 405GAT(152) +1 0 +.names 357GAT(121) 360GAT(120) 406GAT(153) +11 1 +.names 357GAT(121) 404GAT(154) +1 0 +.names 356GAT(122) 423GAT(155) +1 1 +.names 355GAT(123) 403GAT(156) +1 0 +.names 348GAT(128) 73GAT(13) 400GAT(157) +11 1 +.names 351GAT(125) 420GAT(158) +1 1 +.names 350GAT(126) 402GAT(159) +1 0 +.names 347GAT(138) 352GAT(127) 410GAT(160) +11 0 +.names 354GAT(129) 422GAT(161) +1 1 +.names 353GAT(130) 421GAT(162) +1 1 +.names 349GAT(134) 401GAT(163) +1 0 +.names 344GAT(136) 419GAT(164) +1 1 +.names 345GAT(139) 393GAT(165) +1 0 +.names 346GAT(140) 399GAT(166) +1 0 +.names 270GAT(111) 343GAT(135) 392GAT(167) +00 0 +.names 342GAT(141) 418GAT(168) +1 1 +.names 414GAT(145) 415GAT(143) 445GAT(169) +11 1 +.names 411GAT(148) 412GAT(146) 444GAT(170) +11 1 +.names 407GAT(151) 408GAT(149) 426GAT(171) +11 1 +.names 404GAT(154) 405GAT(152) 425GAT(172) +11 1 +.names 403GAT(156) 450GAT(173) +1 1 +.names 400GAT(157) 424GAT(174) +1 0 +.names 375GAT(137) 59GAT(10) 156GAT(39) 393GAT(165) 442GAT(175) +1111 0 +.names 402GAT(159) 449GAT(176) +1 1 +.names 393GAT(165) 287GAT(101) 55GAT(9) 437GAT(177) +111 0 +.names 319GAT(90) 393GAT(165) 55GAT(9) 427GAT(178) +111 1 +.names 401GAT(163) 448GAT(179) +1 1 +.names 393GAT(165) 319GAT(90) 17GAT(3) 443GAT(180) +111 0 +.names 393GAT(165) 17GAT(3) 287GAT(101) 432GAT(181) +111 1 +.names 399GAT(166) 447GAT(182) +1 1 +.names 392GAT(167) 446GAT(183) +1 1 +.names 369GAT(113) 437GAT(177) 488GAT(184) +00 0 +.names 369GAT(113) 437GAT(177) 489GAT(185) +00 0 +.names 369GAT(113) 437GAT(177) 490GAT(186) +00 0 +.names 369GAT(113) 437GAT(177) 491GAT(187) +00 0 +.names 310GAT(60) 432GAT(181) 476GAT(188) +11 1 +.names 310GAT(60) 432GAT(181) 478GAT(189) +11 1 +.names 310GAT(60) 432GAT(181) 480GAT(190) +11 1 +.names 310GAT(60) 432GAT(181) 482GAT(191) +11 1 +.names 416GAT(144) 445GAT(169) 495GAT(192) +00 1 +.names 413GAT(147) 444GAT(170) 492GAT(193) +00 1 +.names 153GAT(38) 427GAT(178) 481GAT(194) +11 1 +.names 149GAT(36) 427GAT(178) 479GAT(195) +11 1 +.names 146GAT(35) 427GAT(178) 477GAT(196) +11 1 +.names 143GAT(34) 427GAT(178) 475GAT(197) +11 1 +.names 409GAT(150) 426GAT(171) 463GAT(198) +00 1 +.names 406GAT(153) 425GAT(172) 460GAT(199) +00 1 +.names 424GAT(174) 451GAT(200) +1 0 +.names 442GAT(175) 410GAT(160) 466GAT(201) +11 0 +.names 443GAT(180) 1GAT(0) 483GAT(202) +11 0 +.names 475GAT(197) 476GAT(188) 503GAT(203) +00 1 +.names 477GAT(196) 478GAT(189) 505GAT(204) +00 1 +.names 479GAT(195) 480GAT(190) 507GAT(205) +00 1 +.names 481GAT(194) 482GAT(191) 509GAT(206) +00 1 +.names 495GAT(192) 207GAT(48) 521GAT(207) +00 0 +.names 495GAT(192) 207GAT(48) 520GAT(208) +11 0 +.names 451GAT(200) 201GAT(47) 529GAT(209) +11 0 +.names 451GAT(200) 195GAT(46) 528GAT(210) +11 0 +.names 451GAT(200) 189GAT(45) 527GAT(211) +11 0 +.names 451GAT(200) 183GAT(44) 526GAT(212) +11 1 +.names 451GAT(200) 177GAT(43) 525GAT(213) +11 1 +.names 451GAT(200) 171GAT(42) 524GAT(214) +11 1 +.names 451GAT(200) 165GAT(41) 523GAT(215) +11 1 +.names 451GAT(200) 159GAT(40) 522GAT(216) +11 1 +.names 153GAT(38) 483GAT(202) 516GAT(217) +11 1 +.names 149GAT(36) 483GAT(202) 514GAT(218) +11 1 +.names 146GAT(35) 483GAT(202) 512GAT(219) +11 1 +.names 143GAT(34) 483GAT(202) 510GAT(220) +11 1 +.names 463GAT(198) 135GAT(32) 501GAT(221) +00 0 +.names 463GAT(198) 135GAT(32) 500GAT(222) +11 0 +.names 130GAT(31) 492GAT(193) 519GAT(223) +00 0 +.names 130GAT(31) 492GAT(193) 518GAT(224) +11 0 +.names 130GAT(31) 460GAT(199) 499GAT(225) +00 0 +.names 130GAT(31) 460GAT(199) 498GAT(226) +11 0 +.names 126GAT(30) 466GAT(201) 517GAT(227) +11 1 +.names 121GAT(29) 466GAT(201) 515GAT(228) +11 1 +.names 116GAT(28) 466GAT(201) 513GAT(229) +11 1 +.names 111GAT(27) 466GAT(201) 511GAT(230) +11 1 +.names 106GAT(26) 466GAT(201) 508GAT(231) +11 1 +.names 101GAT(25) 466GAT(201) 506GAT(232) +11 1 +.names 96GAT(24) 466GAT(201) 504GAT(233) +11 1 +.names 91GAT(23) 466GAT(201) 502GAT(234) +11 1 +.names 520GAT(208) 521GAT(207) 547GAT(235) +11 0 +.names 516GAT(217) 517GAT(227) 543GAT(236) +00 1 +.names 514GAT(218) 515GAT(228) 542GAT(237) +00 1 +.names 512GAT(219) 513GAT(229) 541GAT(238) +00 1 +.names 510GAT(220) 511GAT(230) 540GAT(239) +00 1 +.names 318GAT(72) 508GAT(231) 539GAT(240) +00 1 +.names 500GAT(222) 501GAT(221) 533GAT(241) +11 0 +.names 518GAT(224) 519GAT(223) 544GAT(242) +11 0 +.names 498GAT(226) 499GAT(225) 530GAT(243) +11 0 +.names 316GAT(93) 504GAT(233) 537GAT(244) +00 1 +.names 317GAT(106) 506GAT(232) 538GAT(245) +00 1 +.names 309GAT(107) 502GAT(234) 536GAT(246) +00 1 +.names 488GAT(184) 540GAT(239) 569GAT(247) +11 0 +.names 489GAT(185) 541GAT(238) 573GAT(248) +11 0 +.names 490GAT(186) 542GAT(237) 577GAT(249) +11 0 +.names 491GAT(187) 543GAT(236) 581GAT(250) +11 0 +.names 536GAT(246) 503GAT(203) 553GAT(251) +11 0 +.names 537GAT(244) 505GAT(204) 557GAT(252) +11 0 +.names 538GAT(245) 507GAT(205) 561GAT(253) +11 0 +.names 539GAT(240) 509GAT(206) 565GAT(254) +11 0 +.names 547GAT(235) 586GAT(255) +1 0 +.names 544GAT(242) 547GAT(235) 587GAT(256) +11 1 +.names 533GAT(241) 551GAT(257) +1 0 +.names 530GAT(243) 533GAT(241) 552GAT(258) +11 1 +.names 544GAT(242) 585GAT(259) +1 0 +.names 530GAT(243) 550GAT(260) +1 0 +.names 246GAT(53) 581GAT(250) 659GAT(261) +11 1 +.names 246GAT(53) 577GAT(249) 650GAT(262) +11 1 +.names 246GAT(53) 573GAT(248) 640GAT(263) +11 1 +.names 246GAT(53) 569GAT(247) 631GAT(264) +11 1 +.names 246GAT(53) 565GAT(254) 624GAT(265) +11 1 +.names 246GAT(53) 561GAT(253) 615GAT(266) +11 1 +.names 246GAT(53) 557GAT(252) 605GAT(267) +11 1 +.names 246GAT(53) 553GAT(251) 596GAT(268) +11 1 +.names 585GAT(259) 586GAT(255) 589GAT(269) +11 1 +.names 581GAT(250) 201GAT(47) 654GAT(270) +00 0 +.names 581GAT(250) 201GAT(47) 651GAT(271) +11 0 +.names 577GAT(249) 195GAT(46) 644GAT(272) +00 0 +.names 577GAT(249) 195GAT(46) 641GAT(273) +11 0 +.names 573GAT(248) 189GAT(45) 635GAT(274) +00 0 +.names 573GAT(248) 189GAT(45) 632GAT(275) +11 0 +.names 569GAT(247) 183GAT(44) 628GAT(276) +00 0 +.names 569GAT(247) 183GAT(44) 625GAT(277) +11 0 +.names 565GAT(254) 177GAT(43) 619GAT(278) +00 0 +.names 565GAT(254) 177GAT(43) 616GAT(279) +11 0 +.names 561GAT(253) 171GAT(42) 609GAT(280) +00 0 +.names 561GAT(253) 171GAT(42) 606GAT(281) +11 0 +.names 557GAT(252) 165GAT(41) 600GAT(282) +00 0 +.names 557GAT(252) 165GAT(41) 597GAT(283) +11 0 +.names 553GAT(251) 159GAT(40) 593GAT(284) +00 0 +.names 553GAT(251) 159GAT(40) 590GAT(285) +11 0 +.names 550GAT(260) 551GAT(257) 588GAT(286) +11 1 +.names 635GAT(274) 644GAT(272) 654GAT(270) 261GAT(57) 734GAT(287) +1111 0 +.names 644GAT(272) 654GAT(270) 261GAT(57) 733GAT(288) +111 0 +.names 654GAT(270) 261GAT(57) 732GAT(289) +11 0 +.names 341GAT(61) 659GAT(261) 731GAT(290) +00 1 +.names 339GAT(62) 650GAT(262) 721GAT(291) +00 1 +.names 337GAT(63) 640GAT(263) 712GAT(292) +00 1 +.names 587GAT(256) 589GAT(269) 661GAT(293) +00 1 +.names 654GAT(270) 651GAT(271) 727GAT(294) +11 1 +.names 651GAT(271) 722GAT(295) +1 0 +.names 644GAT(272) 641GAT(273) 717GAT(296) +11 1 +.names 641GAT(273) 713GAT(297) +1 0 +.names 635GAT(274) 632GAT(275) 708GAT(298) +11 1 +.names 632GAT(275) 705GAT(299) +1 0 +.names 628GAT(276) 625GAT(277) 700GAT(300) +11 1 +.names 625GAT(277) 697GAT(301) +1 0 +.names 631GAT(264) 526GAT(212) 704GAT(302) +00 1 +.names 619GAT(278) 616GAT(279) 692GAT(303) +11 1 +.names 616GAT(279) 687GAT(304) +1 0 +.names 624GAT(265) 525GAT(213) 696GAT(305) +00 1 +.names 609GAT(280) 606GAT(281) 682GAT(306) +11 1 +.names 606GAT(281) 678GAT(307) +1 0 +.names 615GAT(266) 524GAT(214) 686GAT(308) +00 1 +.names 600GAT(282) 597GAT(283) 673GAT(309) +11 1 +.names 597GAT(283) 670GAT(310) +1 0 +.names 605GAT(267) 523GAT(215) 677GAT(311) +00 1 +.names 593GAT(284) 590GAT(285) 665GAT(312) +11 1 +.names 590GAT(285) 662GAT(313) +1 0 +.names 596GAT(268) 522GAT(216) 669GAT(314) +00 1 +.names 552GAT(258) 588GAT(286) 660GAT(315) +00 1 +.names 727GAT(294) 261GAT(57) 758GAT(316) +11 1 +.names 727GAT(294) 261GAT(57) 757GAT(317) +00 1 +.names 237GAT(52) 722GAT(295) 760GAT(318) +11 1 +.names 237GAT(52) 713GAT(297) 755GAT(319) +11 1 +.names 237GAT(52) 705GAT(299) 752GAT(320) +11 1 +.names 237GAT(52) 697GAT(301) 749GAT(321) +11 1 +.names 237GAT(52) 687GAT(304) 746GAT(322) +11 1 +.names 237GAT(52) 678GAT(307) 743GAT(323) +11 1 +.names 237GAT(52) 670GAT(310) 740GAT(324) +11 1 +.names 237GAT(52) 662GAT(313) 737GAT(325) +11 1 +.names 228GAT(51) 727GAT(294) 759GAT(326) +11 1 +.names 228GAT(51) 717GAT(296) 754GAT(327) +11 1 +.names 228GAT(51) 708GAT(298) 751GAT(328) +11 1 +.names 228GAT(51) 700GAT(300) 748GAT(329) +11 1 +.names 228GAT(51) 692GAT(303) 745GAT(330) +11 1 +.names 228GAT(51) 682GAT(306) 742GAT(331) +11 1 +.names 228GAT(51) 673GAT(309) 739GAT(332) +11 1 +.names 228GAT(51) 665GAT(312) 736GAT(333) +11 1 +.names 661GAT(293) 768GAT(334) +1 1 +.names 722GAT(295) 756GAT(335) +1 0 +.names 644GAT(272) 722GAT(295) 761GAT(336) +11 0 +.names 635GAT(274) 644GAT(272) 722GAT(295) 763GAT(337) +111 0 +.names 713GAT(297) 753GAT(338) +1 0 +.names 635GAT(274) 713GAT(297) 762GAT(339) +11 0 +.names 705GAT(299) 750GAT(340) +1 0 +.names 697GAT(301) 747GAT(341) +1 0 +.names 687GAT(304) 744GAT(342) +1 0 +.names 609GAT(280) 687GAT(304) 764GAT(343) +11 0 +.names 600GAT(282) 609GAT(280) 687GAT(304) 766GAT(344) +111 0 +.names 678GAT(307) 741GAT(345) +1 0 +.names 600GAT(282) 678GAT(307) 765GAT(346) +11 0 +.names 670GAT(310) 738GAT(347) +1 0 +.names 662GAT(313) 735GAT(348) +1 0 +.names 660GAT(315) 767GAT(349) +1 1 +.names 757GAT(317) 758GAT(316) 786GAT(350) +00 1 +.names 750GAT(340) 762GAT(339) 763GAT(337) 734GAT(287) 773GAT(351) +1111 0 +.names 753GAT(338) 761GAT(336) 733GAT(288) 778GAT(352) +111 0 +.names 756GAT(335) 732GAT(289) 782GAT(353) +11 0 +.names 759GAT(326) 760GAT(318) 787GAT(354) +00 1 +.names 754GAT(327) 755GAT(319) 785GAT(355) +00 1 +.names 751GAT(328) 752GAT(320) 781GAT(356) +00 1 +.names 748GAT(329) 749GAT(321) 777GAT(357) +00 1 +.names 745GAT(330) 746GAT(322) 772GAT(358) +00 1 +.names 742GAT(331) 743GAT(323) 771GAT(359) +00 1 +.names 739GAT(332) 740GAT(324) 770GAT(360) +00 1 +.names 736GAT(333) 737GAT(325) 769GAT(361) +00 1 +.names 219GAT(50) 786GAT(350) 794GAT(362) +11 1 +.names 717GAT(296) 782GAT(353) 792GAT(363) +00 1 +.names 717GAT(296) 782GAT(353) 793GAT(364) +11 1 +.names 708GAT(298) 778GAT(352) 790GAT(365) +00 1 +.names 708GAT(298) 778GAT(352) 791GAT(366) +11 1 +.names 700GAT(300) 773GAT(351) 788GAT(367) +00 1 +.names 700GAT(300) 773GAT(351) 789GAT(368) +11 1 +.names 628GAT(276) 773GAT(351) 795GAT(369) +11 0 +.names 792GAT(363) 793GAT(364) 804GAT(370) +00 1 +.names 790GAT(365) 791GAT(366) 803GAT(371) +00 1 +.names 788GAT(367) 789GAT(368) 802GAT(372) +00 1 +.names 795GAT(369) 747GAT(341) 796GAT(373) +11 0 +.names 340GAT(73) 794GAT(362) 805GAT(374) +00 1 +.names 219GAT(50) 804GAT(370) 810GAT(375) +11 1 +.names 219GAT(50) 803GAT(371) 809GAT(376) +11 1 +.names 219GAT(50) 802GAT(372) 808GAT(377) +11 1 +.names 805GAT(374) 787GAT(354) 731GAT(290) 529GAT(209) 811GAT(378) +1111 0 +.names 692GAT(303) 796GAT(373) 806GAT(379) +00 1 +.names 692GAT(303) 796GAT(373) 807GAT(380) +11 1 +.names 619GAT(278) 796GAT(373) 812GAT(381) +11 0 +.names 609GAT(280) 619GAT(278) 796GAT(373) 813GAT(382) +111 0 +.names 600GAT(282) 609GAT(280) 619GAT(278) 796GAT(373) 814GAT(383) +1111 0 +.names 811GAT(378) 829GAT(384) +1 0 +.names 806GAT(379) 807GAT(380) 825GAT(385) +00 1 +.names 744GAT(342) 812GAT(381) 822GAT(386) +11 0 +.names 741GAT(345) 764GAT(343) 813GAT(382) 819GAT(387) +111 0 +.names 738GAT(347) 765GAT(346) 766GAT(344) 814GAT(383) 815GAT(388) +1111 0 +.names 338GAT(76) 810GAT(375) 828GAT(389) +00 1 +.names 336GAT(77) 809GAT(376) 827GAT(390) +00 1 +.names 335GAT(80) 808GAT(377) 826GAT(391) +00 1 +.names 219GAT(50) 825GAT(385) 836GAT(392) +11 1 +.names 829GAT(384) 840GAT(393) +1 0 +.names 828GAT(389) 785GAT(355) 721GAT(291) 528GAT(210) 839GAT(394) +1111 0 +.names 827GAT(390) 781GAT(356) 712GAT(292) 527GAT(211) 838GAT(395) +1111 0 +.names 826GAT(391) 777GAT(357) 704GAT(302) 837GAT(396) +111 0 +.names 682GAT(306) 822GAT(386) 834GAT(397) +00 1 +.names 682GAT(306) 822GAT(386) 835GAT(398) +11 1 +.names 673GAT(309) 819GAT(387) 832GAT(399) +00 1 +.names 673GAT(309) 819GAT(387) 833GAT(400) +11 1 +.names 665GAT(312) 815GAT(388) 830GAT(401) +00 1 +.names 665GAT(312) 815GAT(388) 831GAT(402) +11 1 +.names 815GAT(388) 593GAT(284) 841GAT(403) +11 0 +.names 840GAT(393) 850GAT(404) +1 1 +.names 839GAT(394) 848GAT(405) +1 0 +.names 838GAT(395) 847GAT(406) +1 0 +.names 837GAT(396) 846GAT(407) +1 0 +.names 834GAT(397) 835GAT(398) 844GAT(408) +00 1 +.names 832GAT(399) 833GAT(400) 843GAT(409) +00 1 +.names 830GAT(401) 831GAT(402) 842GAT(410) +00 1 +.names 735GAT(348) 841GAT(403) 849GAT(411) +11 1 +.names 334GAT(81) 836GAT(392) 845GAT(412) +00 1 +.names 219GAT(50) 844GAT(408) 853GAT(413) +11 1 +.names 219GAT(50) 843GAT(409) 852GAT(414) +11 1 +.names 219GAT(50) 842GAT(410) 851GAT(415) +11 1 +.names 848GAT(405) 857GAT(416) +1 0 +.names 847GAT(406) 856GAT(417) +1 0 +.names 846GAT(407) 855GAT(418) +1 0 +.names 845GAT(412) 772GAT(358) 696GAT(305) 854GAT(419) +111 0 +.names 849GAT(411) 858GAT(420) +1 0 +.names 417GAT(142) 851GAT(415) 859GAT(421) +00 1 +.names 857GAT(416) 865GAT(422) +1 1 +.names 856GAT(417) 864GAT(423) +1 1 +.names 855GAT(418) 863GAT(424) +1 1 +.names 854GAT(419) 862GAT(425) +1 0 +.names 858GAT(420) 866GAT(426) +1 1 +.names 333GAT(84) 853GAT(413) 861GAT(427) +00 1 +.names 332GAT(85) 852GAT(414) 860GAT(428) +00 1 +.names 862GAT(425) 870GAT(429) +1 0 +.names 861GAT(427) 771GAT(359) 686GAT(308) 869GAT(430) +111 0 +.names 860GAT(428) 770GAT(360) 677GAT(311) 868GAT(431) +111 0 +.names 859GAT(421) 769GAT(361) 669GAT(314) 867GAT(432) +111 0 +.names 870GAT(429) 874GAT(433) +1 1 +.names 869GAT(430) 873GAT(434) +1 0 +.names 868GAT(431) 872GAT(435) +1 0 +.names 867GAT(432) 871GAT(436) +1 0 +.names 873GAT(434) 877GAT(437) +1 0 +.names 872GAT(435) 876GAT(438) +1 0 +.names 871GAT(436) 875GAT(439) +1 0 +.names 877GAT(437) 880GAT(440) +1 1 +.names 876GAT(438) 879GAT(441) +1 1 +.names 875GAT(439) 878GAT(442) +1 1 +.end diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/C880.out b/resources/3rdparty/cudd-2.5.0/nanotrav/C880.out new file mode 100644 index 000000000..71dcb6295 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/C880.out @@ -0,0 +1,101 @@ +# Nanotrav Version #0.12, Release date 2003/12/31 +# ./nanotrav -p 1 -ordering dfs -autodyn -automethod sifting -reordering sifting -drop C880.blif +# CUDD Version 2.4.2 +BDD reordering with sifting: from 3974 to ... 2432 nodes in 0.039 sec +BDD reordering with sifting: from 4893 to ... 3549 nodes in 0.044 sec +BDD reordering with sifting: from 7133 to ... 6246 nodes in 0.072 sec +BDD reordering with sifting: from 12522 to ... 6465 nodes in 0.113 sec +Order before final reordering +86GAT(18) 85GAT(17) 90GAT(22) 89GAT(21) 88GAT(20) 87GAT(19) 1GAT(0) 51GAT(8) +75GAT(15) 26GAT(4) 268GAT(59) 36GAT(6) 29GAT(5) 80GAT(16) 59GAT(10) 42GAT(7) +156GAT(39) 17GAT(3) 74GAT(14) 55GAT(9) 8GAT(1) 219GAT(50) 210GAT(49) 91GAT(23) +101GAT(25) 138GAT(33) 96GAT(24) 171GAT(42) 152GAT(37) 146GAT(35) 116GAT(28) 189GAT(45) +149GAT(36) 121GAT(29) 195GAT(46) 153GAT(38) 126GAT(30) 261GAT(57) 201GAT(47) 143GAT(34) +111GAT(27) 183GAT(44) 130GAT(31) 135GAT(32) 106GAT(26) 177GAT(43) 165GAT(41) 207GAT(48) +159GAT(40) 228GAT(51) 237GAT(52) 246GAT(53) 73GAT(13) 72GAT(12) 68GAT(11) 13GAT(2) +260GAT(56) 267GAT(58) 259GAT(55) 255GAT(54) +Number of inputs = 60 +BDD reordering with sifting: from 6204 to ... 4623 nodes in 0.07 sec +New order +135GAT(32) 207GAT(48) 130GAT(31) 86GAT(18) 85GAT(17) 89GAT(21) 90GAT(22) 88GAT(20) +87GAT(19) 1GAT(0) 51GAT(8) 26GAT(4) 268GAT(59) 29GAT(5) 80GAT(16) 59GAT(10) +42GAT(7) 75GAT(15) 156GAT(39) 36GAT(6) 17GAT(3) 74GAT(14) 55GAT(9) 8GAT(1) +210GAT(49) 91GAT(23) 138GAT(33) 165GAT(41) 96GAT(24) 159GAT(40) 101GAT(25) 171GAT(42) +152GAT(37) 149GAT(36) 146GAT(35) 116GAT(28) 189GAT(45) 121GAT(29) 195GAT(46) 153GAT(38) +143GAT(34) 126GAT(30) 201GAT(47) 261GAT(57) 111GAT(27) 106GAT(26) 183GAT(44) 177GAT(43) +219GAT(50) 246GAT(53) 237GAT(52) 228GAT(51) 73GAT(13) 72GAT(12) 68GAT(11) 13GAT(2) +260GAT(56) 267GAT(58) 259GAT(55) 255GAT(54) +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000000 +Maximum number of variable swaps per reordering: 1000000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: yes +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: no +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 10 +Arc violation threshold: 10 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 9340 +**** CUDD non-modifiable parameters **** +Memory in use: 5611044 +Peak number of nodes: 19418 +Peak number of live nodes: 12568 +Number of BDD variables: 60 +Number of ZDD variables: 0 +Number of cache entries: 65536 +Number of cache look-ups: 59167 +Number of cache hits: 28642 +Number of cache insertions: 30604 +Number of cache collisions: 2547 +Number of cache deletions: 28057 +Cache used slots = 18.04% (expected 0.00%) +Soft limit for cache size: 62464 +Number of buckets in unique table: 15616 +Used buckets in unique table: 20.84% (expected 20.96%) +Number of BDD and ADD nodes: 4671 +Number of ZDD nodes: 0 +Number of dead BDD and ADD nodes: 0 +Number of dead ZDD nodes: 0 +Total number of nodes allocated: 32671 +Total number of nodes reclaimed: 1974 +Garbage collections so far: 5 +Time for garbage collection: 0.00 sec +Reorderings so far: 5 +Time for reordering: 0.34 sec +Final size: 4623 +total time = 0.36 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 0.4 seconds +System time 0.0 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131815K +Virtual data size = 297K + data size initialized = 25K + data size uninitialized = 137K + data size sbrk = 135K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 0 +Minor page faults = 1778 +Swaps = 0 +Input blocks = 0 +Output blocks = 0 +Context switch (voluntary) = 1 +Context switch (involuntary) = 6 diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/Makefile b/resources/3rdparty/cudd-2.5.0/nanotrav/Makefile new file mode 100644 index 000000000..b40b547bd --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/Makefile @@ -0,0 +1,98 @@ +# $Id: Makefile,v 1.12 1999/08/31 19:10:05 fabio Exp fabio $ +# +# nanotrav: simple FSM traversal program +#--------------------------------------------------------------------------- +.SUFFIXES: .o .c .u + +CC = gcc +#CC = cc +RANLIB = ranlib +#RANLIB = : +PURE = + +EXE = +#EXE = .exe +TARGET = nanotrav$(EXE) +TARGETu = nanotrav-u + +WHERE = .. + +INCLUDE = $(WHERE)/include + +LIBS = $(WHERE)/dddmp/libdddmp.a $(WHERE)/cudd/libcudd.a \ + $(WHERE)/mtr/libmtr.a $(WHERE)/st/libst.a $(WHERE)/util/libutil.a \ + $(WHERE)/epd/libepd.a + +MNEMLIB = +#MNEMLIB = $(WHERE)/mnemosyne/libmnem.a + +BLIBS = -kL$(WHERE)/dddmp -kldddmp -kL$(WHERE)/cudd -klcudd -kL$(WHERE)/mtr \ + -klmtr -kL$(WHERE)/st -klst -kL$(WHERE)/util -klutil \ + -kL$(WHERE)/epd -klepd + +LINTLIBS = $(WHERE)/llib-ldddmp.a $(WHERE)/cudd/llib-lcudd.ln \ + $(WHERE)/mtr/llib-lmtr.ln $(WHERE)/st/llib-lst.ln \ + $(WHERE)/util/llib-lutil.ln $(WHERE)/epd/llib-lepd.ln + +SRC = main.c bnet.c ntr.c ntrHeap.c ntrBddTest.c ntrMflow.c ntrZddTest.c \ + ntrShort.c chkMterm.c ucbqsort.c +HDR = bnet.h ntr.h $(WHERE)/include/dddmp.h $(WHERE)/include/cudd.h \ + $(WHERE)/include/cuddInt.h + +OBJ = $(SRC:.c=.o) +UBJ = $(SRC:.c=.u) + +MFLAG = +#MFLAG = -DMNEMOSYNE +ICFLAGS = -g -O6 -Wall +#ICFLAGS = -g -Wall +XCFLAGS = -DHAVE_IEEE_754 -DBSD +#XCFLAGS = -xtaso -ieee_with_no_inexact -tune host +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) +DDDEBUG = +#DDDEBUG = -DDD_STATS -DDD_VERBOSE -DDD_CACHE_PROFILE -DDD_UNIQUE_PROFILE -DDD_DEBUG + +LDFLAGS = +#LDFLAGS = -jmpopt +#LDFLAGS = -non_shared -om -taso + +LINTFLAGS = -u -n -DDD_STATS -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_DEBUG -DDD_UNIQUE_PROFILE + +#------------------------------------------------------ + +$(TARGET): $(SRC) $(OBJ) $(HDR) $(LIBS) $(MNEMLIB) + $(PURE) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +.c.o: $(HDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) $(DDDEBUG) + +# if the header files change, recompile +$(OBJ): $(HDR) +$(UBJ): $(HDR) + +optimize_dec: $(TARGETu) + +# optimize (DECstations only: uses u-code) +$(TARGETu): $(SRC) $(UBJ) $(HDR) $(LIBS:.a=.b) + cc -O3 $(XCFLAGS) $(LDFLAGS) $(UBJ) -o $@ $(BLIBS) -lm + +.c.u: $(SRC) $(HDR) + cc -j -I$(INCLUDE) $(XCFLAGS) $< + +lint: $(SRC) $(HDR) $(LINTLIBS) + lint $(LINTFLAGS) -I$(INCLUDE) $(SRC) $(LINTLIBS) + +tags: $(SRC) $(HDR) + ctags $(SRC) $(HDR) + +all: $(TARGET) $(TARGETu) lint tags + +pixie: $(TARGETu) + pixie $(TARGETu) + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) *.bak *~ .gdb_history *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/README b/resources/3rdparty/cudd-2.5.0/nanotrav/README new file mode 100644 index 000000000..cf09d9c12 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/README @@ -0,0 +1,47 @@ +$Id: README,v 1.8 1997/01/23 07:33:22 fabio Exp fabio $ + +WHAT IS NANOTRAV +================ + +This directory contains nanotrav, a simple reachability analysis program +based on the CUDD package. Nanotrav uses a very naive approach and is +only included to provide a sanity check for the installation of the +CUDD package. + +Nanotrav reads a circuit written in a small subset of blif. This +format is described in the comments in bnet.c. Nanotrav then creates +BDDs for the primary outputs and the next state functions (if any) of +the circuit. + +If, passed the -trav option, nanotrav builds a BDD for the +characteristic function of the transition relation of the graph. It then +builds a BDD for the initial state(s), and performs reachability +analysis. Reachability analysys is performed with either the method +known as "monolithic transition relation method," whose main virtue is +simplicity, or with a unsophisticated partitioned transition relation +method. + +Once it has completed reachability analysis, nanotrav prints results and +exits. The amount of information printed, as well as several other +features are controlled by the options. For a complete list of the +options, consult the man page. Here, we only mention that the options allow +the user of nanotrav to select among different reordering options. + +TEST CIRCUITS +============= + +Five test circuits are contained in this directory: C17.blif, +C880.blif, s27.blif, mult32a.blif, and rcn25.blif. The first two are +combinational, while the last three are sequential. The results or +running + + nanotrav -p 1 -cover C17.blif > C17.out + nanotrav -p 1 -ordering dfs -autodyn -automethod sifting -reordering sifting -drop C880.blif > C880.out + nanotrav -p 1 -trav s27.blif > s27.out + nanotrav -p 1 -autodyn -reordering sifting -trav mult32a.blif > mult32a.out + nanotrav -p 1 -envelope rcn25.blif > rcn25.out + +are also included. They have been obtained on a 200 MHz P6-based +machine with 128MB of memory. These tests can be run with the shell +script tst.sh. Notice that rcn25 requires approximately 500 sec. All +other tests run in a few seconds. diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/bnet.c b/resources/3rdparty/cudd-2.5.0/nanotrav/bnet.c new file mode 100644 index 000000000..d1b3f0987 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/bnet.c @@ -0,0 +1,2252 @@ +/**CFile*********************************************************************** + + FileName [bnet.c] + + PackageName [bnet] + + Synopsis [Functions to read in a boolean network.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "bnet.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define MAXLENGTH 131072 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: bnet.c,v 1.26 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +static char BuffLine[MAXLENGTH]; +static char *CurPos; +static int newNameNumber = 0; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static char * readString (FILE *fp); +static char ** readList (FILE *fp, int *n); +static void printList (char **list, int n); +static char ** bnetGenerateNewNames (st_table *hash, int n); +static int bnetDumpReencodingLogic (DdManager *dd, char *mname, int noutputs, DdNode **outputs, char **inames, char **altnames, char **onames, FILE *fp); +#if 0 +static int bnetBlifXnorTable (FILE *fp, int n); +#endif +static int bnetBlifWriteReencode (DdManager *dd, char *mname, char **inames, char **altnames, int *support, FILE *fp); +static int * bnetFindVectorSupport (DdManager *dd, DdNode **list, int n); +static int buildExorBDD (DdManager *dd, BnetNode *nd, st_table *hash, int params, int nodrop); +static int buildMuxBDD (DdManager * dd, BnetNode * nd, st_table * hash, int params, int nodrop); +static int bnetSetLevel (BnetNetwork *net); +static int bnetLevelDFS (BnetNetwork *net, BnetNode *node); +static BnetNode ** bnetOrderRoots (BnetNetwork *net, int *nroots); +static int bnetLevelCompare (BnetNode **x, BnetNode **y); +static int bnetDfsOrder (DdManager *dd, BnetNetwork *net, BnetNode *node); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Reads boolean network from blif file.] + + Description [Reads a boolean network from a blif file. A very restricted + subset of blif is supported. Specifically: +
            +
          • The only directives recognized are: +
              +
            • .model +
            • .inputs +
            • .outputs +
            • .latch +
            • .names +
            • .exdc +
            • .wire_load_slope +
            • .end +
            +
          • Latches must have an initial values and no other parameters + specified. +
          • Lines must not exceed MAXLENGTH-1 characters, and individual names must + not exceed 1023 characters. +
          + Caveat emptor: There may be other limitations as well. One should + check the syntax of the blif file with some other tool before relying + on this parser. Bnet_ReadNetwork returns a pointer to the network if + successful; NULL otherwise. + ] + + SideEffects [None] + + SeeAlso [Bnet_PrintNetwork Bnet_FreeNetwork] + +******************************************************************************/ +BnetNetwork * +Bnet_ReadNetwork( + FILE * fp /* pointer to the blif file */, + int pr /* verbosity level */) +{ + char *savestring; + char **list; + int i, j, n; + BnetNetwork *net; + BnetNode *newnode; + BnetNode *lastnode = NULL; + BnetTabline *newline; + BnetTabline *lastline; + char ***latches = NULL; + int maxlatches = 0; + int exdc = 0; + BnetNode *node; + int count; + + /* Allocate network object and initialize symbol table. */ + net = ALLOC(BnetNetwork,1); + if (net == NULL) goto failure; + memset((char *) net, 0, sizeof(BnetNetwork)); + net->hash = st_init_table(strcmp,st_strhash); + if (net->hash == NULL) goto failure; + + savestring = readString(fp); + if (savestring == NULL) goto failure; + net->nlatches = 0; + while (strcmp(savestring, ".model") == 0 || + strcmp(savestring, ".inputs") == 0 || + strcmp(savestring, ".outputs") == 0 || + strcmp(savestring, ".latch") == 0 || + strcmp(savestring, ".wire_load_slope") == 0 || + strcmp(savestring, ".exdc") == 0 || + strcmp(savestring, ".names") == 0 || strcmp(savestring,".end") == 0) { + if (strcmp(savestring, ".model") == 0) { + /* Read .model directive. */ + FREE(savestring); + /* Read network name. */ + savestring = readString(fp); + if (savestring == NULL) goto failure; + net->name = savestring; + } else if (strcmp(savestring, ".inputs") == 0) { + /* Read .inputs directive. */ + FREE(savestring); + /* Read input names. */ + list = readList(fp,&n); + if (list == NULL) goto failure; + if (pr > 2) printList(list,n); + /* Expect at least one input. */ + if (n < 1) { + (void) fprintf(stdout,"Empty input list.\n"); + goto failure; + } + if (exdc) { + for (i = 0; i < n; i++) + FREE(list[i]); + FREE(list); + savestring = readString(fp); + if (savestring == NULL) goto failure; + continue; + } + if (net->ninputs) { + net->inputs = REALLOC(char *, net->inputs, + (net->ninputs + n) * sizeof(char *)); + for (i = 0; i < n; i++) + net->inputs[net->ninputs + i] = list[i]; + } + else + net->inputs = list; + /* Create a node for each primary input. */ + for (i = 0; i < n; i++) { + newnode = ALLOC(BnetNode,1); + memset((char *) newnode, 0, sizeof(BnetNode)); + if (newnode == NULL) goto failure; + newnode->name = list[i]; + newnode->inputs = NULL; + newnode->type = BNET_INPUT_NODE; + newnode->active = FALSE; + newnode->nfo = 0; + newnode->ninp = 0; + newnode->f = NULL; + newnode->polarity = 0; + newnode->dd = NULL; + newnode->next = NULL; + if (lastnode == NULL) { + net->nodes = newnode; + } else { + lastnode->next = newnode; + } + lastnode = newnode; + } + net->npis += n; + net->ninputs += n; + } else if (strcmp(savestring, ".outputs") == 0) { + /* Read .outputs directive. We do not create nodes for the primary + ** outputs, because the nodes will be created when the same names + ** appear as outputs of some gates. + */ + FREE(savestring); + /* Read output names. */ + list = readList(fp,&n); + if (list == NULL) goto failure; + if (pr > 2) printList(list,n); + if (n < 1) { + (void) fprintf(stdout,"Empty .outputs list.\n"); + goto failure; + } + if (exdc) { + for (i = 0; i < n; i++) + FREE(list[i]); + FREE(list); + savestring = readString(fp); + if (savestring == NULL) goto failure; + continue; + } + if (net->noutputs) { + net->outputs = REALLOC(char *, net->outputs, + (net->noutputs + n) * sizeof(char *)); + for (i = 0; i < n; i++) + net->outputs[net->noutputs + i] = list[i]; + } else { + net->outputs = list; + } + net->npos += n; + net->noutputs += n; + } else if (strcmp(savestring,".wire_load_slope") == 0) { + FREE(savestring); + savestring = readString(fp); + net->slope = savestring; + } else if (strcmp(savestring,".latch") == 0) { + FREE(savestring); + newnode = ALLOC(BnetNode,1); + if (newnode == NULL) goto failure; + memset((char *) newnode, 0, sizeof(BnetNode)); + newnode->type = BNET_PRESENT_STATE_NODE; + list = readList(fp,&n); + if (list == NULL) goto failure; + if (pr > 2) printList(list,n); + /* Expect three names. */ + if (n != 3) { + (void) fprintf(stdout, + ".latch not followed by three tokens.\n"); + goto failure; + } + newnode->name = list[1]; + newnode->inputs = NULL; + newnode->ninp = 0; + newnode->f = NULL; + newnode->active = FALSE; + newnode->nfo = 0; + newnode->polarity = 0; + newnode->dd = NULL; + newnode->next = NULL; + if (lastnode == NULL) { + net->nodes = newnode; + } else { + lastnode->next = newnode; + } + lastnode = newnode; + /* Add next state variable to list. */ + if (maxlatches == 0) { + maxlatches = 20; + latches = ALLOC(char **,maxlatches); + } else if (maxlatches <= net->nlatches) { + maxlatches += 20; + latches = REALLOC(char **,latches,maxlatches); + } + latches[net->nlatches] = list; + net->nlatches++; + savestring = readString(fp); + if (savestring == NULL) goto failure; + } else if (strcmp(savestring,".names") == 0) { + FREE(savestring); + newnode = ALLOC(BnetNode,1); + memset((char *) newnode, 0, sizeof(BnetNode)); + if (newnode == NULL) goto failure; + list = readList(fp,&n); + if (list == NULL) goto failure; + if (pr > 2) printList(list,n); + /* Expect at least one name (the node output). */ + if (n < 1) { + (void) fprintf(stdout,"Missing output name.\n"); + goto failure; + } + newnode->name = list[n-1]; + newnode->inputs = list; + newnode->ninp = n-1; + newnode->active = FALSE; + newnode->nfo = 0; + newnode->polarity = 0; + if (newnode->ninp > 0) { + newnode->type = BNET_INTERNAL_NODE; + for (i = 0; i < net->noutputs; i++) { + if (strcmp(net->outputs[i], newnode->name) == 0) { + newnode->type = BNET_OUTPUT_NODE; + break; + } + } + } else { + newnode->type = BNET_CONSTANT_NODE; + } + newnode->dd = NULL; + newnode->next = NULL; + if (lastnode == NULL) { + net->nodes = newnode; + } else { + lastnode->next = newnode; + } + lastnode = newnode; + /* Read node function. */ + newnode->f = NULL; + if (exdc) { + newnode->exdc_flag = 1; + node = net->nodes; + while (node) { + if (node->type == BNET_OUTPUT_NODE && + strcmp(node->name, newnode->name) == 0) { + node->exdc = newnode; + break; + } + node = node->next; + } + } + savestring = readString(fp); + if (savestring == NULL) goto failure; + lastline = NULL; + while (savestring[0] != '.') { + /* Reading a table line. */ + newline = ALLOC(BnetTabline,1); + if (newline == NULL) goto failure; + newline->next = NULL; + if (lastline == NULL) { + newnode->f = newline; + } else { + lastline->next = newline; + } + lastline = newline; + if (newnode->type == BNET_INTERNAL_NODE || + newnode->type == BNET_OUTPUT_NODE) { + newline->values = savestring; + /* Read output 1 or 0. */ + savestring = readString(fp); + if (savestring == NULL) goto failure; + } else { + newline->values = NULL; + } + if (savestring[0] == '0') newnode->polarity = 1; + FREE(savestring); + savestring = readString(fp); + if (savestring == NULL) goto failure; + } + } else if (strcmp(savestring,".exdc") == 0) { + FREE(savestring); + exdc = 1; + } else if (strcmp(savestring,".end") == 0) { + FREE(savestring); + break; + } + if ((!savestring) || savestring[0] != '.') + savestring = readString(fp); + if (savestring == NULL) goto failure; + } + + /* Put nodes in symbol table. */ + newnode = net->nodes; + while (newnode != NULL) { + int retval = st_insert(net->hash,newnode->name,(char *) newnode); + if (retval == ST_OUT_OF_MEM) { + goto failure; + } else if (retval == 1) { + printf("Error: Multiple drivers for node %s\n", newnode->name); + goto failure; + } else { + if (pr > 2) printf("Inserted %s\n",newnode->name); + } + newnode = newnode->next; + } + + if (latches) { + net->latches = latches; + + count = 0; + net->outputs = REALLOC(char *, net->outputs, + (net->noutputs + net->nlatches) * sizeof(char *)); + for (i = 0; i < net->nlatches; i++) { + for (j = 0; j < net->noutputs; j++) { + if (strcmp(latches[i][0], net->outputs[j]) == 0) + break; + } + if (j < net->noutputs) + continue; + savestring = ALLOC(char, strlen(latches[i][0]) + 1); + strcpy(savestring, latches[i][0]); + net->outputs[net->noutputs + count] = savestring; + count++; + if (st_lookup(net->hash, savestring, &node)) { + if (node->type == BNET_INTERNAL_NODE) { + node->type = BNET_OUTPUT_NODE; + } + } + } + net->noutputs += count; + + net->inputs = REALLOC(char *, net->inputs, + (net->ninputs + net->nlatches) * sizeof(char *)); + for (i = 0; i < net->nlatches; i++) { + savestring = ALLOC(char, strlen(latches[i][1]) + 1); + strcpy(savestring, latches[i][1]); + net->inputs[net->ninputs + i] = savestring; + } + net->ninputs += net->nlatches; + } + + /* Compute fanout counts. For each node in the linked list, fetch + ** all its fanins using the symbol table, and increment the fanout of + ** each fanin. + */ + newnode = net->nodes; + while (newnode != NULL) { + BnetNode *auxnd; + for (i = 0; i < newnode->ninp; i++) { + if (!st_lookup(net->hash,newnode->inputs[i],&auxnd)) { + (void) fprintf(stdout,"%s not driven\n", newnode->inputs[i]); + goto failure; + } + auxnd->nfo++; + } + newnode = newnode->next; + } + + if (!bnetSetLevel(net)) goto failure; + + return(net); + +failure: + /* Here we should clean up the mess. */ + (void) fprintf(stdout,"Error in reading network from file.\n"); + return(NULL); + +} /* end of Bnet_ReadNetwork */ + + +/**Function******************************************************************** + + Synopsis [Prints a boolean network created by readNetwork.] + + Description [Prints to the standard output a boolean network created + by Bnet_ReadNetwork. Uses the blif format; this way, one can verify the + equivalence of the input and the output with, say, sis.] + + SideEffects [None] + + SeeAlso [Bnet_ReadNetwork] + +******************************************************************************/ +void +Bnet_PrintNetwork( + BnetNetwork * net /* boolean network */) +{ + BnetNode *nd; + BnetTabline *tl; + int i; + + if (net == NULL) return; + + (void) fprintf(stdout,".model %s\n", net->name); + (void) fprintf(stdout,".inputs"); + printList(net->inputs,net->npis); + (void) fprintf(stdout,".outputs"); + printList(net->outputs,net->npos); + for (i = 0; i < net->nlatches; i++) { + (void) fprintf(stdout,".latch"); + printList(net->latches[i],3); + } + nd = net->nodes; + while (nd != NULL) { + if (nd->type != BNET_INPUT_NODE && nd->type != BNET_PRESENT_STATE_NODE) { + (void) fprintf(stdout,".names"); + for (i = 0; i < nd->ninp; i++) { + (void) fprintf(stdout," %s",nd->inputs[i]); + } + (void) fprintf(stdout," %s\n",nd->name); + tl = nd->f; + while (tl != NULL) { + if (tl->values != NULL) { + (void) fprintf(stdout,"%s %d\n",tl->values, + 1 - nd->polarity); + } else { + (void) fprintf(stdout,"%d\n", 1 - nd->polarity); + } + tl = tl->next; + } + } + nd = nd->next; + } + (void) fprintf(stdout,".end\n"); + +} /* end of Bnet_PrintNetwork */ + + +/**Function******************************************************************** + + Synopsis [Frees a boolean network created by Bnet_ReadNetwork.] + + Description [] + + SideEffects [None] + + SeeAlso [Bnet_ReadNetwork] + +******************************************************************************/ +void +Bnet_FreeNetwork( + BnetNetwork * net) +{ + BnetNode *node, *nextnode; + BnetTabline *line, *nextline; + int i; + + FREE(net->name); + /* The input name strings are already pointed by the input nodes. + ** Here we only need to free the latch names and the array that + ** points to them. + */ + for (i = 0; i < net->nlatches; i++) { + FREE(net->inputs[net->npis + i]); + } + FREE(net->inputs); + /* Free the output name strings and then the array pointing to them. */ + for (i = 0; i < net->noutputs; i++) { + FREE(net->outputs[i]); + } + FREE(net->outputs); + + for (i = 0; i < net->nlatches; i++) { + FREE(net->latches[i][0]); + FREE(net->latches[i][1]); + FREE(net->latches[i][2]); + FREE(net->latches[i]); + } + if (net->nlatches) FREE(net->latches); + node = net->nodes; + while (node != NULL) { + nextnode = node->next; + if (node->type != BNET_PRESENT_STATE_NODE) + FREE(node->name); + for (i = 0; i < node->ninp; i++) { + FREE(node->inputs[i]); + } + if (node->inputs != NULL) { + FREE(node->inputs); + } + /* Free the function table. */ + line = node->f; + while (line != NULL) { + nextline = line->next; + FREE(line->values); + FREE(line); + line = nextline; + } + FREE(node); + node = nextnode; + } + st_free_table(net->hash); + if (net->slope != NULL) FREE(net->slope); + FREE(net); + +} /* end of Bnet_FreeNetwork */ + + +/**Function******************************************************************** + + Synopsis [Builds the BDD for the function of a node.] + + Description [Builds the BDD for the function of a node and stores a + pointer to it in the dd field of the node itself. The reference count + of the BDD is incremented. If params is BNET_LOCAL_DD, then the BDD is + built in terms of the local inputs to the node; otherwise, if params + is BNET_GLOBAL_DD, the BDD is built in terms of the network primary + inputs. To build the global BDD of a node, the BDDs for its local + inputs must exist. If that is not the case, Bnet_BuildNodeBDD + recursively builds them. Likewise, to create the local BDD for a node, + the local inputs must have variables assigned to them. If that is not + the case, Bnet_BuildNodeBDD recursively assigns variables to nodes. + Bnet_BuildNodeBDD returns 1 in case of success; 0 otherwise.] + + SideEffects [Sets the dd field of the node.] + + SeeAlso [] + +******************************************************************************/ +int +Bnet_BuildNodeBDD( + DdManager * dd /* DD manager */, + BnetNode * nd /* node of the boolean network */, + st_table * hash /* symbol table of the boolean network */, + int params /* type of DD to be built */, + int nodrop /* retain the intermediate node DDs until the end */) +{ + DdNode *func; + BnetNode *auxnd; + DdNode *tmp; + DdNode *prod, *var; + BnetTabline *line; + int i; + + if (nd->dd != NULL) return(1); + + if (nd->type == BNET_CONSTANT_NODE) { + if (nd->f == NULL) { /* constant 0 */ + func = Cudd_ReadLogicZero(dd); + } else { /* either constant depending on the polarity */ + func = Cudd_ReadOne(dd); + } + Cudd_Ref(func); + } else if (nd->type == BNET_INPUT_NODE || + nd->type == BNET_PRESENT_STATE_NODE) { + if (nd->active == TRUE) { /* a variable is already associated: use it */ + func = Cudd_ReadVars(dd,nd->var); + if (func == NULL) goto failure; + } else { /* no variable associated: get a new one */ + func = Cudd_bddNewVar(dd); + if (func == NULL) goto failure; + nd->var = func->index; + nd->active = TRUE; + } + Cudd_Ref(func); + } else if (buildExorBDD(dd,nd,hash,params,nodrop)) { + func = nd->dd; + } else if (buildMuxBDD(dd,nd,hash,params,nodrop)) { + func = nd->dd; + } else { /* type == BNET_INTERNAL_NODE or BNET_OUTPUT_NODE */ + /* Initialize the sum to logical 0. */ + func = Cudd_ReadLogicZero(dd); + Cudd_Ref(func); + + /* Build a term for each line of the table and add it to the + ** accumulator (func). + */ + line = nd->f; + while (line != NULL) { +#ifdef BNET_DEBUG + (void) fprintf(stdout,"line = %s\n", line->values); +#endif + /* Initialize the product to logical 1. */ + prod = Cudd_ReadOne(dd); + Cudd_Ref(prod); + /* Scan the table line. */ + for (i = 0; i < nd->ninp; i++) { + if (line->values[i] == '-') continue; + if (!st_lookup(hash,nd->inputs[i],&auxnd)) { + goto failure; + } + if (params == BNET_LOCAL_DD) { + if (auxnd->active == FALSE) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + var = Cudd_ReadVars(dd,auxnd->var); + if (var == NULL) goto failure; + Cudd_Ref(var); + if (line->values[i] == '0') { + var = Cudd_Not(var); + } + } else { /* params == BNET_GLOBAL_DD */ + if (auxnd->dd == NULL) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + if (line->values[i] == '1') { + var = auxnd->dd; + } else { /* line->values[i] == '0' */ + var = Cudd_Not(auxnd->dd); + } + } + tmp = Cudd_bddAnd(dd,prod,var); + if (tmp == NULL) goto failure; + Cudd_Ref(tmp); + Cudd_IterDerefBdd(dd,prod); + if (params == BNET_LOCAL_DD) { + Cudd_IterDerefBdd(dd,var); + } + prod = tmp; + } + tmp = Cudd_bddOr(dd,func,prod); + if (tmp == NULL) goto failure; + Cudd_Ref(tmp); + Cudd_IterDerefBdd(dd,func); + Cudd_IterDerefBdd(dd,prod); + func = tmp; + line = line->next; + } + /* Associate a variable to this node if local BDDs are being + ** built. This is done at the end, so that the primary inputs tend + ** to get lower indices. + */ + if (params == BNET_LOCAL_DD && nd->active == FALSE) { + DdNode *auxfunc = Cudd_bddNewVar(dd); + if (auxfunc == NULL) goto failure; + Cudd_Ref(auxfunc); + nd->var = auxfunc->index; + nd->active = TRUE; + Cudd_IterDerefBdd(dd,auxfunc); + } + } + if (nd->polarity == 1) { + nd->dd = Cudd_Not(func); + } else { + nd->dd = func; + } + + if (params == BNET_GLOBAL_DD && nodrop == FALSE) { + /* Decrease counters for all faninis. + ** When count reaches 0, the DD is freed. + */ + for (i = 0; i < nd->ninp; i++) { + if (!st_lookup(hash,nd->inputs[i],&auxnd)) { + goto failure; + } + auxnd->count--; + if (auxnd->count == 0) { + Cudd_IterDerefBdd(dd,auxnd->dd); + if (auxnd->type == BNET_INTERNAL_NODE || + auxnd->type == BNET_CONSTANT_NODE) auxnd->dd = NULL; + } + } + } + return(1); + +failure: + /* Here we should clean up the mess. */ + return(0); + +} /* end of Bnet_BuildNodeBDD */ + + +/**Function******************************************************************** + + Synopsis [Orders the BDD variables by DFS.] + + Description [Orders the BDD variables by DFS. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [Uses the visited flags of the nodes.] + + SeeAlso [] + +******************************************************************************/ +int +Bnet_DfsVariableOrder( + DdManager * dd, + BnetNetwork * net) +{ + BnetNode **roots; + BnetNode *node; + int nroots; + int i; + + roots = bnetOrderRoots(net,&nroots); + if (roots == NULL) return(0); + for (i = 0; i < nroots; i++) { + if (!bnetDfsOrder(dd,net,roots[i])) { + FREE(roots); + return(0); + } + } + /* Clear visited flags. */ + node = net->nodes; + while (node != NULL) { + node->visited = 0; + node = node->next; + } + FREE(roots); + return(1); + +} /* end of Bnet_DfsVariableOrder */ + + +/**Function******************************************************************** + + Synopsis [Writes the network BDDs to a file in dot, blif, or daVinci + format.] + + Description [Writes the network BDDs to a file in dot, blif, or daVinci + format. If "-" is passed as file name, the BDDs are dumped to the + standard output. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Bnet_bddDump( + DdManager * dd /* DD manager */, + BnetNetwork * network /* network whose BDDs should be dumped */, + char * dfile /* file name */, + int dumpFmt /* 0 -> dot */, + int reencoded /* whether variables have been reencoded */) +{ + int noutputs; + FILE *dfp = NULL; + DdNode **outputs = NULL; + char **inames = NULL; + char **onames = NULL; + char **altnames = NULL; + BnetNode *node; + int i; + int retval = 0; /* 0 -> failure; 1 -> success */ + + /* Open dump file. */ + if (strcmp(dfile, "-") == 0) { + dfp = stdout; + } else { + dfp = fopen(dfile,"w"); + } + if (dfp == NULL) goto endgame; + + /* Initialize data structures. */ + noutputs = network->noutputs; + outputs = ALLOC(DdNode *,noutputs); + if (outputs == NULL) goto endgame; + onames = ALLOC(char *,noutputs); + if (onames == NULL) goto endgame; + inames = ALLOC(char *,Cudd_ReadSize(dd)); + if (inames == NULL) goto endgame; + + /* Find outputs and their names. */ + for (i = 0; i < network->nlatches; i++) { + onames[i] = network->latches[i][0]; + if (!st_lookup(network->hash,network->latches[i][0],&node)) { + goto endgame; + } + outputs[i] = node->dd; + } + for (i = 0; i < network->npos; i++) { + onames[i + network->nlatches] = network->outputs[i]; + if (!st_lookup(network->hash,network->outputs[i],&node)) { + goto endgame; + } + outputs[i + network->nlatches] = node->dd; + } + + /* Find the input names. */ + for (i = 0; i < network->ninputs; i++) { + if (!st_lookup(network->hash,network->inputs[i],&node)) { + goto endgame; + } + inames[node->var] = network->inputs[i]; + } + for (i = 0; i < network->nlatches; i++) { + if (!st_lookup(network->hash,network->latches[i][1],&node)) { + goto endgame; + } + inames[node->var] = network->latches[i][1]; + } + + if (reencoded == 1 && dumpFmt == 1) { + altnames = bnetGenerateNewNames(network->hash,network->ninputs); + if (altnames == NULL) { + retval = 0; + goto endgame; + } + retval = bnetDumpReencodingLogic(dd,network->name,noutputs,outputs, + inames,altnames,onames,dfp); + for (i = 0; i < network->ninputs; i++) { + FREE(altnames[i]); + } + FREE(altnames); + if (retval == 0) goto endgame; + } + + /* Dump the BDDs. */ + if (dumpFmt == 1) { + retval = Cudd_DumpBlif(dd,noutputs,outputs,inames,onames, + network->name,dfp,0); + } else if (dumpFmt == 2) { + retval = Cudd_DumpDaVinci(dd,noutputs,outputs,inames,onames,dfp); + } else if (dumpFmt == 3) { + retval = Cudd_DumpDDcal(dd,noutputs,outputs,inames,onames,dfp); + } else if (dumpFmt == 4) { + retval = Cudd_DumpFactoredForm(dd,noutputs,outputs,inames,onames,dfp); + } else if (dumpFmt == 5) { + retval = Cudd_DumpBlif(dd,noutputs,outputs,inames,onames, + network->name,dfp,1); + } else { + retval = Cudd_DumpDot(dd,noutputs,outputs,inames,onames,dfp); + } + +endgame: + if (dfp != stdout && dfp != NULL) { + if (fclose(dfp) == EOF) retval = 0; + } + if (outputs != NULL) FREE(outputs); + if (onames != NULL) FREE(onames); + if (inames != NULL) FREE(inames); + + return(retval); + +} /* end of Bnet_bddDump */ + + +/**Function******************************************************************** + + Synopsis [Writes an array of BDDs to a file in dot, blif, DDcal, + factored-form, daVinci, or blif-MV format.] + + Description [Writes an array of BDDs to a file in dot, blif, DDcal, + factored-form, daVinci, or blif-MV format. The BDDs and their names + are passed as arguments. The inputs and their names are taken from + the network. If "-" is passed as file name, the BDDs are dumped to + the standard output. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Bnet_bddArrayDump( + DdManager * dd /* DD manager */, + BnetNetwork * network /* network whose BDDs should be dumped */, + char * dfile /* file name */, + DdNode ** outputs /* BDDs to be dumped */, + char ** onames /* names of the BDDs to be dumped */, + int noutputs /* number of BDDs to be dumped */, + int dumpFmt /* 0 -> dot */) +{ + FILE *dfp = NULL; + char **inames = NULL; + BnetNode *node; + int i; + int retval = 0; /* 0 -> failure; 1 -> success */ + + /* Open dump file. */ + if (strcmp(dfile, "-") == 0) { + dfp = stdout; + } else { + dfp = fopen(dfile,"w"); + } + if (dfp == NULL) goto endgame; + + /* Initialize data structures. */ + inames = ALLOC(char *,Cudd_ReadSize(dd)); + if (inames == NULL) goto endgame; + for (i = 0; i < Cudd_ReadSize(dd); i++) { + inames[i] = NULL; + } + + /* Find the input names. */ + for (i = 0; i < network->ninputs; i++) { + if (!st_lookup(network->hash,network->inputs[i],&node)) { + goto endgame; + } + inames[node->var] = network->inputs[i]; + } + for (i = 0; i < network->nlatches; i++) { + if (!st_lookup(network->hash,network->latches[i][1],&node)) { + goto endgame; + } + inames[node->var] = network->latches[i][1]; + } + + /* Dump the BDDs. */ + if (dumpFmt == 1) { + retval = Cudd_DumpBlif(dd,noutputs,outputs,inames,onames, + network->name,dfp,0); + } else if (dumpFmt == 2) { + retval = Cudd_DumpDaVinci(dd,noutputs,outputs,inames,onames,dfp); + } else if (dumpFmt == 3) { + retval = Cudd_DumpDDcal(dd,noutputs,outputs,inames,onames,dfp); + } else if (dumpFmt == 4) { + retval = Cudd_DumpFactoredForm(dd,noutputs,outputs,inames,onames,dfp); + } else if (dumpFmt == 5) { + retval = Cudd_DumpBlif(dd,noutputs,outputs,inames,onames, + network->name,dfp,1); + } else { + retval = Cudd_DumpDot(dd,noutputs,outputs,inames,onames,dfp); + } + +endgame: + if (dfp != stdout && dfp != NULL) { + if (fclose(dfp) == EOF) retval = 0; + } + if (inames != NULL) FREE(inames); + + return(retval); + +} /* end of Bnet_bddArrayDump */ + + +/**Function******************************************************************** + + Synopsis [Reads the variable order from a file.] + + Description [Reads the variable order from a file. + Returns 1 if successful; 0 otherwise.] + + SideEffects [The BDDs for the primary inputs and present state variables + are built.] + + SeeAlso [] + +*****************************************************************************/ +int +Bnet_ReadOrder( + DdManager * dd, + char * ordFile, + BnetNetwork * net, + int locGlob, + int nodrop) +{ + FILE *fp; + st_table *dict; + int result; + BnetNode *node; + char name[MAXLENGTH]; + + if (ordFile == NULL) { + return(0); + } + + dict = st_init_table(strcmp,st_strhash); + if (dict == NULL) { + return(0); + } + + if ((fp = fopen(ordFile,"r")) == NULL) { + (void) fprintf(stderr,"Unable to open %s\n",ordFile); + st_free_table(dict); + return(0); + } + + while (!feof(fp)) { + result = fscanf(fp, "%s", name); + if (result == EOF) { + break; + } else if (result != 1) { + st_free_table(dict); + return(0); + } else if (strlen(name) > MAXLENGTH) { + st_free_table(dict); + return(0); + } + /* There should be a node named "name" in the network. */ + if (!st_lookup(net->hash,name,&node)) { + (void) fprintf(stderr,"Unknown name in order file (%s)\n", name); + st_free_table(dict); + return(0); + } + /* A name should not appear more than once in the order. */ + if (st_is_member(dict,name)) { + (void) fprintf(stderr,"Duplicate name in order file (%s)\n", name); + st_free_table(dict); + return(0); + } + /* The name should correspond to a primary input or present state. */ + if (node->type != BNET_INPUT_NODE && + node->type != BNET_PRESENT_STATE_NODE) { + (void) fprintf(stderr,"%s has the wrong type (%d)\n", name, + node->type); + st_free_table(dict); + return(0); + } + /* Insert in table. Use node->name rather than name, because the + ** latter gets overwritten. + */ + if (st_insert(dict,node->name,NULL) == ST_OUT_OF_MEM) { + (void) fprintf(stderr,"Out of memory in Bnet_ReadOrder\n"); + st_free_table(dict); + return(0); + } + result = Bnet_BuildNodeBDD(dd,node,net->hash,locGlob,nodrop); + if (result == 0) { + (void) fprintf(stderr,"Construction of BDD failed\n"); + st_free_table(dict); + return(0); + } + } /* while (!feof(fp)) */ + result = fclose(fp); + if (result == EOF) { + (void) fprintf(stderr,"Error closing order file %s\n", ordFile); + st_free_table(dict); + return(0); + } + + /* The number of names in the order file should match exactly the + ** number of primary inputs and present states. + */ + if (st_count(dict) != net->ninputs) { + (void) fprintf(stderr,"Order incomplete: %d names instead of %d\n", + st_count(dict), net->ninputs); + st_free_table(dict); + return(0); + } + + st_free_table(dict); + return(1); + +} /* end of Bnet_ReadOrder */ + + +/**Function******************************************************************** + + Synopsis [Prints the order of the DD variables of a network.] + + Description [Prints the order of the DD variables of a network. + Only primary inputs and present states are printed. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +int +Bnet_PrintOrder( + BnetNetwork * net, + DdManager *dd) +{ + char **names; /* array used to print variable orders */ + int level; /* position of a variable in current order */ + BnetNode *node; /* auxiliary pointer to network node */ + int i,j; + int retval; + int nvars; + + nvars = Cudd_ReadSize(dd); + names = ALLOC(char *, nvars); + if (names == NULL) return(0); + for (i = 0; i < nvars; i++) { + names[i] = NULL; + } + for (i = 0; i < net->npis; i++) { + if (!st_lookup(net->hash,net->inputs[i],&node)) { + FREE(names); + return(0); + } + if (node->dd == NULL) { + FREE(names); + return(0); + } + level = Cudd_ReadPerm(dd,node->var); + names[level] = node->name; + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + FREE(names); + return(0); + } + if (node->dd == NULL) { + FREE(names); + return(0); + } + level = Cudd_ReadPerm(dd,node->var); + names[level] = node->name; + } + for (i = 0, j = 0; i < nvars; i++) { + if (names[i] == NULL) continue; + if ((j%8 == 0)&&j) { + retval = printf("\n"); + if (retval == EOF) { + FREE(names); + return(0); + } + } + retval = printf("%s ",names[i]); + if (retval == EOF) { + FREE(names); + return(0); + } + j++; + } + FREE(names); + retval = printf("\n"); + if (retval == EOF) { + return(0); + } + return(1); + +} /* end of Bnet_PrintOrder */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Reads a string from a file.] + + Description [Reads a string from a file. The string can be MAXLENGTH-1 + characters at most. readString allocates memory to hold the string and + returns a pointer to the result if successful. It returns NULL + otherwise.] + + SideEffects [None] + + SeeAlso [readList] + +******************************************************************************/ +static char * +readString( + FILE * fp /* pointer to the file from which the string is read */) +{ + char *savestring; + int length; + + while (!CurPos) { + if (!fgets(BuffLine, MAXLENGTH, fp)) + return(NULL); + BuffLine[strlen(BuffLine) - 1] = '\0'; + CurPos = strtok(BuffLine, " \t"); + if (CurPos && CurPos[0] == '#') CurPos = (char *)NULL; + } + length = strlen(CurPos); + savestring = ALLOC(char,length+1); + if (savestring == NULL) + return(NULL); + strcpy(savestring,CurPos); + CurPos = strtok(NULL, " \t"); + return(savestring); + +} /* end of readString */ + + +/**Function******************************************************************** + + Synopsis [Reads a list of strings from a file.] + + Description [Reads a list of strings from a line of a file. + The strings are sequences of characters separated by spaces or tabs. + The total length of the list, white space included, must not exceed + MAXLENGTH-1 characters. readList allocates memory for the strings and + creates an array of pointers to the individual lists. Only two pieces + of memory are allocated by readList: One to hold all the strings, + and one to hold the pointers to them. Therefore, when freeing the + memory allocated by readList, only the pointer to the list of + pointers, and the pointer to the beginning of the first string should + be freed. readList returns the pointer to the list of pointers if + successful; NULL otherwise.] + + SideEffects [n is set to the number of strings in the list.] + + SeeAlso [readString printList] + +******************************************************************************/ +static char ** +readList( + FILE * fp /* pointer to the file from which the list is read */, + int * n /* on return, number of strings in the list */) +{ + char *savestring; + int length; + char *stack[8192]; + char **list; + int i, count = 0; + + while (CurPos) { + if (strcmp(CurPos, "\\") == 0) { + CurPos = (char *)NULL; + while (!CurPos) { + if (!fgets(BuffLine, MAXLENGTH, fp)) return(NULL); + BuffLine[strlen(BuffLine) - 1] = '\0'; + CurPos = strtok(BuffLine, " \t"); + } + } + length = strlen(CurPos); + savestring = ALLOC(char,length+1); + if (savestring == NULL) return(NULL); + strcpy(savestring,CurPos); + stack[count] = savestring; + count++; + CurPos = strtok(NULL, " \t"); + } + list = ALLOC(char *, count); + for (i = 0; i < count; i++) + list[i] = stack[i]; + *n = count; + return(list); + +} /* end of readList */ + + +/**Function******************************************************************** + + Synopsis [Prints a list of strings to the standard output.] + + Description [Prints a list of strings to the standard output. The list + is in the format created by readList.] + + SideEffects [None] + + SeeAlso [readList Bnet_PrintNetwork] + +******************************************************************************/ +static void +printList( + char ** list /* list of pointers to strings */, + int n /* length of the list */) +{ + int i; + + for (i = 0; i < n; i++) { + (void) fprintf(stdout," %s",list[i]); + } + (void) fprintf(stdout,"\n"); + +} /* end of printList */ + + +/**Function******************************************************************** + + Synopsis [Generates names not currently in a symbol table.] + + Description [Generates n names not currently in the symbol table hash. + The pointer to the symbol table may be NULL, in which case no test is + made. The names generated by the procedure are unique. So, if there is + no possibility of conflict with pre-existing names, NULL can be passed + for the hash table. Returns an array of names if succesful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static char ** +bnetGenerateNewNames( + st_table * hash /* table of existing names (or NULL) */, + int n /* number of names to be generated */) +{ + char **list; + char name[256]; + int i; + + if (n < 1) return(NULL); + + list = ALLOC(char *,n); + if (list == NULL) return(NULL); + for (i = 0; i < n; i++) { + do { + sprintf(name, "var%d", newNameNumber); + newNameNumber++; + } while (hash != NULL && st_is_member(hash,name)); + list[i] = util_strsav(name); + } + + return(list); + +} /* bnetGenerateNewNames */ + + +/**Function******************************************************************** + + Synopsis [Writes blif for the reencoding logic.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +bnetDumpReencodingLogic( + DdManager * dd /* DD manager */, + char * mname /* model name */, + int noutputs /* number of outputs */, + DdNode ** outputs /* array of network outputs */, + char ** inames /* array of network input names */, + char ** altnames /* array of names of reencoded inputs */, + char ** onames /* array of network output names */, + FILE * fp /* file pointer */) +{ + int i; + int retval; + int nvars = Cudd_ReadSize(dd); + int *support = NULL; + + support = bnetFindVectorSupport(dd,outputs,noutputs); + if (support == NULL) return(0); + + /* Write the header (.model .inputs .outputs). */ + retval = fprintf(fp,".model %s.global\n.inputs",mname); + if (retval == EOF) goto failure; + + for (i = 0; i < nvars; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + retval = fprintf(fp," %s", inames[i]); + if (retval == EOF) goto failure; + } + + /* Write the .output line. */ + retval = fprintf(fp,"\n.outputs"); + if (retval == EOF) goto failure; + for (i = 0; i < noutputs; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + retval = fprintf(fp," %s", onames[i]); + if (retval == EOF) goto failure; + } + retval = fprintf(fp,"\n"); + if (retval == EOF) goto failure; + + /* Instantiate main subcircuit. */ + retval = fprintf(fp,"\n.subckt %s", mname); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + if (support[i] == 1) { + retval = fprintf(fp," %s=%s", inames[i], altnames[i]); + if (retval == EOF) goto failure; + } + } + for (i = 0; i < noutputs; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + retval = fprintf(fp," %s=%s", onames[i], onames[i]); + if (retval == EOF) goto failure; + } + retval = fprintf(fp,"\n"); + if (retval == EOF) goto failure; + + /* Instantiate reencoding subcircuit. */ + retval = fprintf(fp,"\n.subckt %s.reencode",mname); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + retval = fprintf(fp," %s=%s", inames[i], inames[i]); + if (retval == EOF) goto failure; + } + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + if (support[i] == 1) { + retval = fprintf(fp," %s=%s", altnames[i],altnames[i]); + if (retval == EOF) goto failure; + } + } + retval = fprintf(fp,"\n"); + if (retval == EOF) goto failure; + + /* Write trailer. */ + retval = fprintf(fp,".end\n\n"); + if (retval == EOF) goto failure; + + /* Write reencoding subcircuit. */ + retval = bnetBlifWriteReencode(dd,mname,inames,altnames,support,fp); + if (retval == EOF) goto failure; + + FREE(support); + return(1); + +failure: + if (support != NULL) FREE(support); + return(0); + +} /* end of bnetDumpReencodingLogic */ + + +/**Function******************************************************************** + + Synopsis [Writes blif for the truth table of an n-input xnor.] + + Description [Writes blif for the truth table of an n-input + xnor. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +#if 0 +static int +bnetBlifXnorTable( + FILE * fp /* file pointer */, + int n /* number of inputs */) +{ + int power; /* 2 to the power n */ + int i,j,k; + int nzeroes; + int retval; + char *line; + + line = ALLOC(char,n+1); + if (line == NULL) return(0); + line[n] = '\0'; + + for (i = 0, power = 1; i < n; i++) { + power *= 2; + } + + for (i = 0; i < power; i++) { + k = i; + nzeroes = 0; + for (j = 0; j < n; j++) { + if (k & 1) { + line[j] = '1'; + } else { + line[j] = '0'; + nzeroes++; + } + k >>= 1; + } + if ((nzeroes & 1) == 0) { + retval = fprintf(fp,"%s 1\n",line); + if (retval == 0) return(0); + } + } + return(1); + +} /* end of bnetBlifXnorTable */ +#endif + + +/**Function******************************************************************** + + Synopsis [Writes blif for the reencoding logic.] + + Description [Writes blif for the reencoding logic. Exclusive NORs + with more than two inputs are decomposed into cascaded two-input + gates. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +bnetBlifWriteReencode( + DdManager * dd, + char * mname, + char ** inames, + char ** altnames, + int * support, + FILE * fp) +{ + int retval; + int nvars = Cudd_ReadSize(dd); + int i,j; + int ninp; + + /* Write the header (.model .inputs .outputs). */ + retval = fprintf(fp,".model %s.reencode\n.inputs",mname); + if (retval == EOF) return(0); + + for (i = 0; i < nvars; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + retval = fprintf(fp," %s", inames[i]); + if (retval == EOF) goto failure; + } + + /* Write the .output line. */ + retval = fprintf(fp,"\n.outputs"); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + if (support[i] == 1) { + retval = fprintf(fp," %s", altnames[i]); + if (retval == EOF) goto failure; + } + } + retval = fprintf(fp,"\n"); + if (retval == EOF) goto failure; + + /* Instantiate exclusive nors. */ + for (i = 0; i < nvars; i++) { + char *in1 = NULL; + char *in2 = NULL; + char **oname; + if (support[i] == 0) continue; + ninp = 0; + for (j = 0; j < nvars; j++) { + if (Cudd_ReadLinear(dd,i,j)) { + switch (ninp) { + case 0: + in1 = inames[j]; + ninp++; + break; + case 1: + in2 = inames[j]; + ninp++; + break; + case 2: + oname = bnetGenerateNewNames(NULL,1); + retval = fprintf(fp,".names %s %s %s\n11 1\n00 1\n", + in1, in2, oname[0]); + if (retval == EOF) goto failure; + in1 = oname[0]; + in2 = inames[j]; + FREE(oname); + break; + default: + goto failure; + } + } + } + switch (ninp) { + case 1: + retval = fprintf(fp,".names %s %s\n1 1\n", in1, altnames[i]); + if (retval == EOF) goto failure; + break; + case 2: + retval = fprintf(fp,".names %s %s %s\n11 1\n00 1\n", + in1, in2, altnames[i]); + if (retval == EOF) goto failure; + break; + default: + goto failure; + } + } + + /* Write trailer. */ + retval = fprintf(fp,"\n.end\n\n"); + if (retval == EOF) goto failure; + + return(1); + +failure: + return(0); + +} /* end of bnetBlifWriteReencode */ + + +/**Function******************************************************************** + + Synopsis [Finds the support of a list of DDs.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int * +bnetFindVectorSupport( + DdManager * dd, + DdNode ** list, + int n) +{ + DdNode *support = NULL; + DdNode *scan; + int *array = NULL; + int nvars = Cudd_ReadSize(dd); + int i; + + /* Build an array with the support of the functions in list. */ + array = ALLOC(int,nvars); + if (array == NULL) return(NULL); + for (i = 0; i < nvars; i++) { + array[i] = 0; + } + + /* Take the union of the supports of each output function. */ + for (i = 0; i < n; i++) { + support = Cudd_Support(dd,list[i]); + if (support == NULL) { + FREE(array); + return(NULL); + } + Cudd_Ref(support); + scan = support; + while (!Cudd_IsConstant(scan)) { + array[scan->index] = 1; + scan = Cudd_T(scan); + } + Cudd_IterDerefBdd(dd,support); + } + + return(array); + +} /* end of bnetFindVectorSupport */ + + +/**Function******************************************************************** + + Synopsis [Builds BDD for a XOR function.] + + Description [Checks whether a function is a XOR with 2 or 3 inputs. If so, + it builds the BDD. Returns 1 if the BDD has been built; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +buildExorBDD( + DdManager * dd, + BnetNode * nd, + st_table * hash, + int params, + int nodrop) +{ + int check[8]; + int i; + int nlines; + BnetTabline *line; + DdNode *func, *var, *tmp; + BnetNode *auxnd; + + if (nd->ninp < 2 || nd->ninp > 3) return(0); + + nlines = 1 << (nd->ninp - 1); + for (i = 0; i < 8; i++) check[i] = 0; + line = nd->f; + while (line != NULL) { + int num = 0; + int count = 0; + nlines--; + for (i = 0; i < nd->ninp; i++) { + num <<= 1; + if (line->values[i] == '-') { + return(0); + } else if (line->values[i] == '1') { + count++; + num++; + } + } + if ((count & 1) == 0) return(0); + if (check[num]) return(0); + line = line->next; + } + if (nlines != 0) return(0); + + /* Initialize the exclusive sum to logical 0. */ + func = Cudd_ReadLogicZero(dd); + Cudd_Ref(func); + + /* Scan the inputs. */ + for (i = 0; i < nd->ninp; i++) { + if (!st_lookup(hash, nd->inputs[i], &auxnd)) { + goto failure; + } + if (params == BNET_LOCAL_DD) { + if (auxnd->active == FALSE) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + var = Cudd_ReadVars(dd,auxnd->var); + if (var == NULL) goto failure; + Cudd_Ref(var); + } else { /* params == BNET_GLOBAL_DD */ + if (auxnd->dd == NULL) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + var = auxnd->dd; + } + tmp = Cudd_bddXor(dd,func,var); + if (tmp == NULL) goto failure; + Cudd_Ref(tmp); + Cudd_IterDerefBdd(dd,func); + if (params == BNET_LOCAL_DD) { + Cudd_IterDerefBdd(dd,var); + } + func = tmp; + } + nd->dd = func; + + /* Associate a variable to this node if local BDDs are being + ** built. This is done at the end, so that the primary inputs tend + ** to get lower indices. + */ + if (params == BNET_LOCAL_DD && nd->active == FALSE) { + DdNode *auxfunc = Cudd_bddNewVar(dd); + if (auxfunc == NULL) goto failure; + Cudd_Ref(auxfunc); + nd->var = auxfunc->index; + nd->active = TRUE; + Cudd_IterDerefBdd(dd,auxfunc); + } + + return(1); +failure: + return(0); + +} /* end of buildExorBDD */ + + +/**Function******************************************************************** + + Synopsis [Builds BDD for a multiplexer.] + + Description [Checks whether a function is a 2-to-1 multiplexer. If so, + it builds the BDD. Returns 1 if the BDD has been built; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +buildMuxBDD( + DdManager * dd, + BnetNode * nd, + st_table * hash, + int params, + int nodrop) +{ + BnetTabline *line; + char *values[2]; + int mux[2]; + int phase[2]; + int j; + int nlines = 0; + int controlC = -1; + int controlR = -1; + DdNode *func, *f, *g, *h; + BnetNode *auxnd; + + if (nd->ninp != 3) return(0); + + for (line = nd->f; line != NULL; line = line->next) { + int dc = 0; + if (nlines > 1) return(0); + values[nlines] = line->values; + for (j = 0; j < 3; j++) { + if (values[nlines][j] == '-') { + if (dc) return(0); + dc = 1; + } + } + if (!dc) return(0); + nlines++; + } + /* At this point we know we have: + ** 3 inputs + ** 2 lines + ** 1 dash in each line + ** If the two dashes are not in the same column, then there is + ** exaclty one column without dashes: the control column. + */ + for (j = 0; j < 3; j++) { + if (values[0][j] == '-' && values[1][j] == '-') return(0); + if (values[0][j] != '-' && values[1][j] != '-') { + if (values[0][j] == values[1][j]) return(0); + controlC = j; + controlR = values[0][j] == '0'; + } + } + assert(controlC != -1 && controlR != -1); + /* At this point we know that there is indeed no column with two + ** dashes. The control column has been identified, and we know that + ** its two elelments are different. */ + for (j = 0; j < 3; j++) { + if (j == controlC) continue; + if (values[controlR][j] == '1') { + mux[0] = j; + phase[0] = 0; + } else if (values[controlR][j] == '0') { + mux[0] = j; + phase[0] = 1; + } else if (values[1-controlR][j] == '1') { + mux[1] = j; + phase[1] = 0; + } else if (values[1-controlR][j] == '0') { + mux[1] = j; + phase[1] = 1; + } + } + + /* Get the inputs. */ + if (!st_lookup(hash, nd->inputs[controlC], &auxnd)) { + goto failure; + } + if (params == BNET_LOCAL_DD) { + if (auxnd->active == FALSE) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + f = Cudd_ReadVars(dd,auxnd->var); + if (f == NULL) goto failure; + Cudd_Ref(f); + } else { /* params == BNET_GLOBAL_DD */ + if (auxnd->dd == NULL) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + f = auxnd->dd; + } + if (!st_lookup(hash, nd->inputs[mux[0]], &auxnd)) { + goto failure; + } + if (params == BNET_LOCAL_DD) { + if (auxnd->active == FALSE) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + g = Cudd_ReadVars(dd,auxnd->var); + if (g == NULL) goto failure; + Cudd_Ref(g); + } else { /* params == BNET_GLOBAL_DD */ + if (auxnd->dd == NULL) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + g = auxnd->dd; + } + g = Cudd_NotCond(g,phase[0]); + if (!st_lookup(hash, nd->inputs[mux[1]], &auxnd)) { + goto failure; + } + if (params == BNET_LOCAL_DD) { + if (auxnd->active == FALSE) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + h = Cudd_ReadVars(dd,auxnd->var); + if (h == NULL) goto failure; + Cudd_Ref(h); + } else { /* params == BNET_GLOBAL_DD */ + if (auxnd->dd == NULL) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + h = auxnd->dd; + } + h = Cudd_NotCond(h,phase[1]); + func = Cudd_bddIte(dd,f,g,h); + if (func == NULL) goto failure; + Cudd_Ref(func); + if (params == BNET_LOCAL_DD) { + Cudd_IterDerefBdd(dd,f); + Cudd_IterDerefBdd(dd,g); + Cudd_IterDerefBdd(dd,h); + } + nd->dd = func; + + /* Associate a variable to this node if local BDDs are being + ** built. This is done at the end, so that the primary inputs tend + ** to get lower indices. + */ + if (params == BNET_LOCAL_DD && nd->active == FALSE) { + DdNode *auxfunc = Cudd_bddNewVar(dd); + if (auxfunc == NULL) goto failure; + Cudd_Ref(auxfunc); + nd->var = auxfunc->index; + nd->active = TRUE; + Cudd_IterDerefBdd(dd,auxfunc); + } + + return(1); +failure: + return(0); + +} /* end of buildExorBDD */ + + +/**Function******************************************************************** + + Synopsis [Sets the level of each node.] + + Description [Sets the level of each node. Returns 1 if successful; 0 + otherwise.] + + SideEffects [Changes the level and visited fields of the nodes it + visits.] + + SeeAlso [bnetLevelDFS] + +******************************************************************************/ +static int +bnetSetLevel( + BnetNetwork * net) +{ + BnetNode *node; + + /* Recursively visit nodes. This is pretty inefficient, because we + ** visit all nodes in this loop, and most of them in the recursive + ** calls to bnetLevelDFS. However, this approach guarantees that + ** all nodes will be reached ven if there are dangling outputs. */ + node = net->nodes; + while (node != NULL) { + if (!bnetLevelDFS(net,node)) return(0); + node = node->next; + } + + /* Clear visited flags. */ + node = net->nodes; + while (node != NULL) { + node->visited = 0; + node = node->next; + } + return(1); + +} /* end of bnetSetLevel */ + + +/**Function******************************************************************** + + Synopsis [Does a DFS from a node setting the level field.] + + Description [Does a DFS from a node setting the level field. Returns + 1 if successful; 0 otherwise.] + + SideEffects [Changes the level and visited fields of the nodes it + visits.] + + SeeAlso [bnetSetLevel] + +******************************************************************************/ +static int +bnetLevelDFS( + BnetNetwork * net, + BnetNode * node) +{ + int i; + BnetNode *auxnd; + + if (node->visited == 1) { + return(1); + } + + node->visited = 1; + + /* Graphical sources have level 0. This is the final value if the + ** node has no fan-ins. Otherwise the successive loop will + ** increase the level. */ + node->level = 0; + for (i = 0; i < node->ninp; i++) { + if (!st_lookup(net->hash, node->inputs[i], &auxnd)) { + return(0); + } + if (!bnetLevelDFS(net,auxnd)) { + return(0); + } + if (auxnd->level >= node->level) node->level = 1 + auxnd->level; + } + return(1); + +} /* end of bnetLevelDFS */ + + +/**Function******************************************************************** + + Synopsis [Orders network roots for variable ordering.] + + Description [Orders network roots for variable ordering. Returns + an array with the ordered outputs and next state variables if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static BnetNode ** +bnetOrderRoots( + BnetNetwork * net, + int * nroots) +{ + int i, noutputs; + BnetNode *node; + BnetNode **nodes = NULL; + + /* Initialize data structures. */ + noutputs = net->noutputs; + nodes = ALLOC(BnetNode *, noutputs); + if (nodes == NULL) goto endgame; + + /* Find output names and levels. */ + for (i = 0; i < net->noutputs; i++) { + if (!st_lookup(net->hash,net->outputs[i],&node)) { + goto endgame; + } + nodes[i] = node; + } + + qsort((void *)nodes, noutputs, sizeof(BnetNode *), + (DD_QSFP)bnetLevelCompare); + *nroots = noutputs; + return(nodes); + +endgame: + if (nodes != NULL) FREE(nodes); + return(NULL); + +} /* end of bnetOrderRoots */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + +******************************************************************************/ +static int +bnetLevelCompare( + BnetNode ** x, + BnetNode ** y) +{ + return((*y)->level - (*x)->level); + +} /* end of bnetLevelCompare */ + + +/**Function******************************************************************** + + Synopsis [Does a DFS from a node ordering the inputs.] + + Description [Does a DFS from a node ordering the inputs. Returns + 1 if successful; 0 otherwise.] + + SideEffects [Changes visited fields of the nodes it visits.] + + SeeAlso [Bnet_DfsVariableOrder] + +******************************************************************************/ +static int +bnetDfsOrder( + DdManager * dd, + BnetNetwork * net, + BnetNode * node) +{ + int i; + BnetNode *auxnd; + BnetNode **fanins; + + if (node->visited == 1) { + return(1); + } + + node->visited = 1; + if (node->type == BNET_INPUT_NODE || + node->type == BNET_PRESENT_STATE_NODE) { + node->dd = Cudd_bddNewVar(dd); + if (node->dd == NULL) return(0); + Cudd_Ref(node->dd); + node->active = TRUE; + node->var = node->dd->index; + return(1); + } + + fanins = ALLOC(BnetNode *, node->ninp); + if (fanins == NULL) return(0); + + for (i = 0; i < node->ninp; i++) { + if (!st_lookup(net->hash, node->inputs[i], &auxnd)) { + FREE(fanins); + return(0); + } + fanins[i] = auxnd; + } + + qsort((void *)fanins, node->ninp, sizeof(BnetNode *), + (DD_QSFP)bnetLevelCompare); + for (i = 0; i < node->ninp; i++) { + /* for (i = node->ninp - 1; i >= 0; i--) { */ + int res = bnetDfsOrder(dd,net,fanins[i]); + if (res == 0) { + FREE(fanins); + return(0); + } + } + FREE(fanins); + return(1); + +} /* end of bnetLevelDFS */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/bnet.h b/resources/3rdparty/cudd-2.5.0/nanotrav/bnet.h new file mode 100644 index 000000000..ec468abce --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/bnet.h @@ -0,0 +1,187 @@ +/**CHeaderFile***************************************************************** + + FileName [bnet.h] + + PackageName [bnet] + + Synopsis [Simple-minded package to read a blif file.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: bnet.h,v 1.13 2012/02/05 01:53:01 fabio Exp fabio $] + +******************************************************************************/ + +#ifndef _BNET +#define _BNET + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include "util.h" +#include "st.h" +#include "cudd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Different types of nodes. (Used in the "BnetNode" type.) */ +#define BNET_CONSTANT_NODE 0 +#define BNET_INPUT_NODE 1 +#define BNET_PRESENT_STATE_NODE 2 +#define BNET_INTERNAL_NODE 3 +#define BNET_OUTPUT_NODE 4 +#define BNET_NEXT_STATE_NODE 5 + +/* Type of DD of a node. */ +#define BNET_LOCAL_DD 0 +#define BNET_GLOBAL_DD 1 + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/* The following types implement a very simple data structure for a boolean +** network. The intent is to be able to read a minimal subset of the blif +** format in a data structure from which it's easy to build DDs for the +** circuit. +*/ + +/* Type to store a line of the truth table of a node. The entire truth table +** implemented as a linked list of objects of this type. +*/ +typedef struct BnetTabline { + char *values; /* string of 1, 0, and - */ + struct BnetTabline *next; /* pointer to next table line */ +} BnetTabline; + +/* Node of the boolean network. There is one node in the network for each +** primary input and for each .names directive. This structure +** has a field to point to the DD of the node function. The function may +** be either in terms of primary inputs, or it may be in terms of the local +** inputs. The latter implies that each node has a variable index +** associated to it at some point in time. The field "var" stores that +** variable index, and "active" says if the association is currently valid. +** (It is indeed possible for an index to be associated to different nodes +** at different times.) +*/ +typedef struct BnetNode { + char *name; /* name of the output signal */ + int type; /* input, internal, constant, ... */ + int ninp; /* number of inputs to the node */ + int nfo; /* number of fanout nodes for this node */ + char **inputs; /* input names */ + BnetTabline *f; /* truth table for this node */ + int polarity; /* f is the onset (0) or the offset (1) */ + int active; /* node has variable associated to it (1) or not (0) */ + int var; /* DD variable index associated to this node */ + DdNode *dd; /* decision diagram for the function of this node */ + int exdc_flag; /* whether an exdc node or not */ + struct BnetNode *exdc; /* pointer to exdc of dd node */ + int count; /* auxiliary field for DD dropping */ + int level; /* maximum distance from the inputs */ + int visited; /* flag for search */ + struct BnetNode *next; /* pointer to implement the linked list of nodes */ +} BnetNode; + +/* Very simple boolean network data structure. */ +typedef struct BnetNetwork { + char *name; /* network name: from the .model directive */ + int npis; /* number of primary inputs */ + int ninputs; /* number of inputs */ + char **inputs; /* primary input names: from the .inputs directive */ + int npos; /* number of primary outputs */ + int noutputs; /* number of outputs */ + char **outputs; /* primary output names: from the .outputs directive */ + int nlatches; /* number of latches */ + char ***latches; /* next state names: from the .latch directives */ + BnetNode *nodes; /* linked list of the nodes */ + st_table *hash; /* symbol table to access nodes by name */ + char *slope; /* wire_load_slope */ +} BnetNetwork; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef TRUE +# define TRUE 1 +#endif +#ifndef FALSE +# define FALSE 0 +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern BnetNetwork * Bnet_ReadNetwork (FILE *fp, int pr); +extern void Bnet_PrintNetwork (BnetNetwork *net); +extern void Bnet_FreeNetwork (BnetNetwork *net); +extern int Bnet_BuildNodeBDD (DdManager *dd, BnetNode *nd, st_table *hash, int params, int nodrop); +extern int Bnet_DfsVariableOrder (DdManager *dd, BnetNetwork *net); +extern int Bnet_bddDump (DdManager *dd, BnetNetwork *network, char *dfile, int dumpFmt, int reencoded); +extern int Bnet_bddArrayDump (DdManager *dd, BnetNetwork *network, char *dfile, DdNode **outputs, char **onames, int noutputs, int dumpFmt); +extern int Bnet_ReadOrder (DdManager *dd, char *ordFile, BnetNetwork *net, int locGlob, int nodrop); +extern int Bnet_PrintOrder (BnetNetwork * net, DdManager *dd); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _BNET */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/chkMterm.c b/resources/3rdparty/cudd-2.5.0/nanotrav/chkMterm.c new file mode 100644 index 000000000..a5ef2f36e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/chkMterm.c @@ -0,0 +1,235 @@ +/**CFile*********************************************************************** + + FileName [chkMterm.c] + + PackageName [ntr] + + Synopsis [Functions to check that the minterm counts have not + changed.] + + Description [Functions to check that the minterm counts have not + changed during reordering.

          + Internal procedures included in this module: +

            +
          • check_minterms() +
          + Static procedures included in this module: +
            +
          • stFree() +
          ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: chkMterm.c,v 1.9 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static enum st_retval stFree (char *key, char *value, char *arg); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Check that minterm counts have not changed.] + + Description [Counts the minterms in the global functions of the + primary outputs of the network passed as argument. + When it is calld with the second argument set to NULL, it allocates + a symbol table and stores, for each output, the minterm count. If + an output does not have a BDD, it stores a NULL pointer for it. + If it is called with a non-null second argument, it assumes that + the symbol table contains the minterm counts measured previously + and it compares the new counts to the old ones. Finally, it frees + the symbol table. + check_minterms is designed so that it can be called twice: once before + reordering, and once after reordering. + Returns a pointer to the symbol table on the first invocation and NULL + on the second invocation.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +st_table * +checkMinterms( + BnetNetwork * net, + DdManager * dd, + st_table * previous) +{ + BnetNode *po; + int numPi; + char *name; + double *count, newcount, *oldcount; + int flag,err,i; + + numPi = net->ninputs; + + if (previous == NULL) { + previous = st_init_table(strcmp,st_strhash); + if (previous == NULL) { + (void) printf("checkMinterms out-of-memory\n"); + return(NULL); + } + for (i = 0; i < net->noutputs; i++) { + if (!st_lookup(net->hash,net->outputs[i],&po)) { + exit(2); + } + name = net->outputs[i]; + if (po->dd != NULL) { + count = ALLOC(double,1); + *count = Cudd_CountMinterm(dd,po->dd,numPi); + err = st_insert(previous, name, (char *) count); + } else { + err = st_insert(previous, name, NULL); + } + if (err) { + (void) printf("Duplicate input name (%s)\n",name); + return(NULL); + } + } + return(previous); + } else { + flag = 0; + if (st_count(previous) != net->noutputs) { + (void) printf("Number of outputs has changed from %d to %d\n", + st_count(previous), net->noutputs); + flag = 1; + } + for (i = 0; i < net->noutputs; i++) { + if (!st_lookup(net->hash,net->outputs[i],&po)) { + exit(2); + } + name = net->outputs[i]; + if (st_lookup(previous,name,&oldcount)) { + if (po->dd != NULL) { + newcount = Cudd_CountMinterm(dd,po->dd,numPi); + if (newcount != *oldcount) { + (void) printf("Number of minterms of %s has changed from %g to %g\n",name,*oldcount,newcount); + flag = 1; + } + } else { + if (oldcount != NULL) { + (void) printf("Output %s lost its BDD!\n",name); + flag = 1; + } + } + } else { + (void) printf("Output %s is new!\n",name); + flag = 1; + } + } + /*st_foreach(previous,(enum st_retval)stFree,NULL);*/ + st_foreach(previous,(ST_PFSR)stFree,NULL); + st_free_table(previous); + if (flag) { + return((st_table *) 1); + } else { + return(NULL); + } + } + +} /* end of checkMinterms */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Frees the data of the symbol table.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +static enum st_retval +stFree( + char *key, + char *value, + char *arg) +{ + if (value != NULL) { + FREE(value); + } + return(ST_CONTINUE); + +} /* end of stFree */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllAbs.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllAbs.html new file mode 100644 index 000000000..22ddf6667 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllAbs.html @@ -0,0 +1,45 @@ + +bnet package abstract (Internal) + + +

          bnet package abstract (Internal)

          +

          +
          + + + +
          +
          Bnet_BuildNodeBDD() +
          Builds the BDD for the function of a node. + +
          Bnet_DfsVariableOrder() +
          Orders the BDD variables by DFS. + +
          Bnet_FreeNetwork() +
          Frees a boolean network created by Bnet_ReadNetwork. + +
          Bnet_PrintNetwork() +
          Prints a boolean network created by readNetwork. + +
          Bnet_PrintOrder() +
          Prints the order of the DD variables of a network. + +
          Bnet_ReadNetwork() +
          Reads boolean network from blif file. + +
          Bnet_ReadOrder() +
          Reads the variable order from a file. + +
          Bnet_bddArrayDump() +
          Writes an array of BDDs to a file in dot, blif, DDcal, factored-form, or daVinci format. + +
          Bnet_bddDump() +
          Writes the network BDDs to a file in dot, blif, or daVinci format. + +
          + +
          + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllDet.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllDet.html new file mode 100644 index 000000000..352011e23 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllDet.html @@ -0,0 +1,173 @@ + +The bnet package (Internal) + + +

          The bnet package (Internal)

          +

          +

          +
          + + +
          + + + + + +
          + + +
          + +
          +int 
          +Bnet_BuildNodeBDD(
          +  DdManager * dd, DD manager
          +  BnetNode * nd, node of the boolean network
          +  st_table * hash, symbol table of the boolean network
          +  int  params, type of DD to be built
          +  int  nodrop retain the intermediate node DDs until the end
          +)
          +
          +
          Builds the BDD for the function of a node and stores a pointer to it in the dd field of the node itself. The reference count of the BDD is incremented. If params is BNET_LOCAL_DD, then the BDD is built in terms of the local inputs to the node; otherwise, if params is BNET_GLOBAL_DD, the BDD is built in terms of the network primary inputs. To build the global BDD of a node, the BDDs for its local inputs must exist. If that is not the case, Bnet_BuildNodeBDD recursively builds them. Likewise, to create the local BDD for a node, the local inputs must have variables assigned to them. If that is not the case, Bnet_BuildNodeBDD recursively assigns variables to nodes. Bnet_BuildNodeBDD returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects Sets the dd field of the node. +

          + +

          +int 
          +Bnet_DfsVariableOrder(
          +  DdManager * dd, 
          +  BnetNetwork * net 
          +)
          +
          +
          Orders the BDD variables by DFS. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects Uses the visited flags of the nodes. +

          + +

          +void 
          +Bnet_FreeNetwork(
          +  BnetNetwork * net 
          +)
          +
          +
          Frees a boolean network created by Bnet_ReadNetwork. +

          + +

          Side Effects None +

          + +

          See Also Bnet_ReadNetwork + + +
          +void 
          +Bnet_PrintNetwork(
          +  BnetNetwork * net boolean network
          +)
          +
          +
          Prints to the standard output a boolean network created by Bnet_ReadNetwork. Uses the blif format; this way, one can verify the equivalence of the input and the output with, say, sis. +

          + +

          Side Effects None +

          + +

          See Also Bnet_ReadNetwork + + +
          +int 
          +Bnet_PrintOrder(
          +  BnetNetwork * net, 
          +  DdManager * dd 
          +)
          +
          +
          Prints the order of the DD variables of a network. Only primary inputs and present states are printed. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +BnetNetwork * 
          +Bnet_ReadNetwork(
          +  FILE * fp, pointer to the blif file
          +  int  pr verbosity level
          +)
          +
          +
          Reads a boolean network from a blif file. A very restricted subset of blif is supported. Specifically:
          • The only directives recognized are:
            • .model
            • .inputs
            • .outputs
            • .latch
            • .names
            • .exdc
            • .wire_load_slope
            • .end
          • Latches must have an initial values and no other parameters specified.
          • Lines must not exceed MAXLENGTH-1 characters, and individual names must not exceed 1023 characters.
          Caveat emptor: There may be other limitations as well. One should check the syntax of the blif file with some other tool before relying on this parser. Bnet_ReadNetwork returns a pointer to the network if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          See Also Bnet_PrintNetwork +Bnet_FreeNetwork + + +
          +int 
          +Bnet_ReadOrder(
          +  DdManager * dd, 
          +  char * ordFile, 
          +  BnetNetwork * net, 
          +  int  locGlob, 
          +  int  nodrop 
          +)
          +
          +
          Reads the variable order from a file. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects The BDDs for the primary inputs and present state variables are built. +

          + +

          +int 
          +Bnet_bddArrayDump(
          +  DdManager * dd, DD manager
          +  BnetNetwork * network, network whose BDDs should be dumped
          +  char * dfile, file name
          +  DdNode ** outputs, BDDs to be dumped
          +  char ** onames, names of the BDDs to be dumped
          +  int  noutputs, number of BDDs to be dumped
          +  int  dumpFmt 0 -> dot
          +)
          +
          +
          Writes an array of BDDs to a file in dot, blif, DDcal, factored-form, or daVinci format. The BDDs and their names are passed as arguments. The inputs and their names are taken from the network. If "-" is passed as file name, the BDDs are dumped to the standard output. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Bnet_bddDump(
          +  DdManager * dd, DD manager
          +  BnetNetwork * network, network whose BDDs should be dumped
          +  char * dfile, file name
          +  int  dumpFmt, 0 -> dot
          +  int  reencoded whether variables have been reencoded
          +)
          +
          +
          Writes the network BDDs to a file in dot, blif, or daVinci format. If "-" is passed as file name, the BDDs are dumped to the standard output. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + + +

          + +
          + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtAbs.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtAbs.html new file mode 100644 index 000000000..d8f645ce4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtAbs.html @@ -0,0 +1,45 @@ + +bnet package abstract + + +

          bnet package abstract

          +

          Simple-minded package to read a blif file.

          +
          + + + +
          +
          Bnet_BuildNodeBDD() +
          Builds the BDD for the function of a node. + +
          Bnet_DfsVariableOrder() +
          Orders the BDD variables by DFS. + +
          Bnet_FreeNetwork() +
          Frees a boolean network created by Bnet_ReadNetwork. + +
          Bnet_PrintNetwork() +
          Prints a boolean network created by readNetwork. + +
          Bnet_PrintOrder() +
          Prints the order of the DD variables of a network. + +
          Bnet_ReadNetwork() +
          Reads boolean network from blif file. + +
          Bnet_ReadOrder() +
          Reads the variable order from a file. + +
          Bnet_bddArrayDump() +
          Writes an array of BDDs to a file in dot, blif, DDcal, factored-form, or daVinci format. + +
          Bnet_bddDump() +
          Writes the network BDDs to a file in dot, blif, or daVinci format. + +
          + +
          + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtDet.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtDet.html new file mode 100644 index 000000000..aee62c09d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtDet.html @@ -0,0 +1,173 @@ + +The bnet package + + +

          The bnet package

          +

          Simple-minded package to read a blif file.

          +

          +
          + + +
          + + + + + +
          + + +
          + +
          +int 
          +Bnet_BuildNodeBDD(
          +  DdManager * dd, DD manager
          +  BnetNode * nd, node of the boolean network
          +  st_table * hash, symbol table of the boolean network
          +  int  params, type of DD to be built
          +  int  nodrop retain the intermediate node DDs until the end
          +)
          +
          +
          Builds the BDD for the function of a node and stores a pointer to it in the dd field of the node itself. The reference count of the BDD is incremented. If params is BNET_LOCAL_DD, then the BDD is built in terms of the local inputs to the node; otherwise, if params is BNET_GLOBAL_DD, the BDD is built in terms of the network primary inputs. To build the global BDD of a node, the BDDs for its local inputs must exist. If that is not the case, Bnet_BuildNodeBDD recursively builds them. Likewise, to create the local BDD for a node, the local inputs must have variables assigned to them. If that is not the case, Bnet_BuildNodeBDD recursively assigns variables to nodes. Bnet_BuildNodeBDD returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects Sets the dd field of the node. +

          + +

          +int 
          +Bnet_DfsVariableOrder(
          +  DdManager * dd, 
          +  BnetNetwork * net 
          +)
          +
          +
          Orders the BDD variables by DFS. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects Uses the visited flags of the nodes. +

          + +

          +void 
          +Bnet_FreeNetwork(
          +  BnetNetwork * net 
          +)
          +
          +
          Frees a boolean network created by Bnet_ReadNetwork. +

          + +

          Side Effects None +

          + +

          See Also Bnet_ReadNetwork + + +
          +void 
          +Bnet_PrintNetwork(
          +  BnetNetwork * net boolean network
          +)
          +
          +
          Prints to the standard output a boolean network created by Bnet_ReadNetwork. Uses the blif format; this way, one can verify the equivalence of the input and the output with, say, sis. +

          + +

          Side Effects None +

          + +

          See Also Bnet_ReadNetwork + + +
          +int 
          +Bnet_PrintOrder(
          +  BnetNetwork * net, 
          +  DdManager * dd 
          +)
          +
          +
          Prints the order of the DD variables of a network. Only primary inputs and present states are printed. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +BnetNetwork * 
          +Bnet_ReadNetwork(
          +  FILE * fp, pointer to the blif file
          +  int  pr verbosity level
          +)
          +
          +
          Reads a boolean network from a blif file. A very restricted subset of blif is supported. Specifically:
          • The only directives recognized are:
            • .model
            • .inputs
            • .outputs
            • .latch
            • .names
            • .exdc
            • .wire_load_slope
            • .end
          • Latches must have an initial values and no other parameters specified.
          • Lines must not exceed MAXLENGTH-1 characters, and individual names must not exceed 1023 characters.
          Caveat emptor: There may be other limitations as well. One should check the syntax of the blif file with some other tool before relying on this parser. Bnet_ReadNetwork returns a pointer to the network if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          See Also Bnet_PrintNetwork +Bnet_FreeNetwork + + +
          +int 
          +Bnet_ReadOrder(
          +  DdManager * dd, 
          +  char * ordFile, 
          +  BnetNetwork * net, 
          +  int  locGlob, 
          +  int  nodrop 
          +)
          +
          +
          Reads the variable order from a file. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects The BDDs for the primary inputs and present state variables are built. +

          + +

          +int 
          +Bnet_bddArrayDump(
          +  DdManager * dd, DD manager
          +  BnetNetwork * network, network whose BDDs should be dumped
          +  char * dfile, file name
          +  DdNode ** outputs, BDDs to be dumped
          +  char ** onames, names of the BDDs to be dumped
          +  int  noutputs, number of BDDs to be dumped
          +  int  dumpFmt 0 -> dot
          +)
          +
          +
          Writes an array of BDDs to a file in dot, blif, DDcal, factored-form, or daVinci format. The BDDs and their names are passed as arguments. The inputs and their names are taken from the network. If "-" is passed as file name, the BDDs are dumped to the standard output. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Bnet_bddDump(
          +  DdManager * dd, DD manager
          +  BnetNetwork * network, network whose BDDs should be dumped
          +  char * dfile, file name
          +  int  dumpFmt, 0 -> dot
          +  int  reencoded whether variables have been reencoded
          +)
          +
          +
          Writes the network BDDs to a file in dot, blif, or daVinci format. If "-" is passed as file name, the BDDs are dumped to the standard output. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + + +

          + +
          + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllAbs.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllAbs.html new file mode 100644 index 000000000..360a4e748 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllAbs.html @@ -0,0 +1,114 @@ + +ntr package abstract (Internal) + + +

          ntr package abstract (Internal)

          +

          +
          + + + +
          +
          Ntr_ClosureTrav() +
          Transitive closure traversal procedure. + +
          Ntr_Envelope() +
          Poor man's outer envelope computation. + +
          Ntr_FreeHeap() +
          Frees a priority queue. + +
          Ntr_HeapClone() +
          Clones a priority queue. + +
          Ntr_HeapCount() +
          Returns the number of items in a priority queue. + +
          Ntr_HeapExtractMin() +
          Extracts the element with the minimum key from a priority queue. + +
          Ntr_HeapInsert() +
          Inserts an item in a priority queue. + +
          Ntr_InitHeap() +
          Initializes a priority queue. + +
          Ntr_SCC() +
          Computes the SCCs of the STG. + +
          Ntr_ShortestPaths() +
          Computes shortest paths in a state graph. + +
          Ntr_TestClipping() +
          Tests BDD clipping functions. + +
          Ntr_TestClosestCube() +
          Tests the Cudd_bddClosestCube function. + +
          Ntr_TestCofactorEstimate() +
          Tests BDD cofactor estimate functions. + +
          Ntr_TestDecomp() +
          Tests BDD decomposition functions. + +
          Ntr_TestDensity() +
          Tests BDD density-related functions. + +
          Ntr_TestEquivAndContain() +
          Tests BDD equivalence and containment with don't cares. + +
          Ntr_TestHeap() +
          Tests the heap property of a priority queue. + +
          Ntr_TestMinimization() +
          Tests BDD minimization functions. + +
          Ntr_TransitiveClosure() +
          Builds the transitive closure of a transition relation. + +
          Ntr_Trav() +
          Poor man's traversal procedure. + +
          Ntr_VerifyEquivalence() +
          Verify equivalence of combinational networks. + +
          Ntr_buildDDs() +
          Builds DDs for a network outputs and next state functions. + +
          Ntr_buildTR() +
          Builds the transition relation for a network. + +
          Ntr_cloneTR() +
          Makes a copy of a transition relation. + +
          Ntr_freeTR() +
          Frees the transition relation for a network. + +
          Ntr_getStateCube() +
          Reads a state cube from a file or creates a random one. + +
          Ntr_initState() +
          Builds the BDD of the initial state(s). + +
          Ntr_maxflow() +
          Maximum 0-1 flow between source and sink states. + +
          Ntr_maximum01Flow() +
          + +
          Ntr_testISOP() +
          Builds ZDD covers. + +
          Ntr_testZDD() +
          Tests ZDDs. + +
          STRING_EQUAL() +
          Returns 1 if the two arguments are identical strings. + +
          + +
          + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllDet.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllDet.html new file mode 100644 index 000000000..5daa930d8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllDet.html @@ -0,0 +1,513 @@ + +The ntr package (Internal) + + +

          The ntr package (Internal)

          +

          +

          +
          + + +
          + + + + + +
          + + +
          + +
          +int 
          +Ntr_ClosureTrav(
          +  DdManager * dd, DD manager
          +  BnetNetwork * net, network
          +  NtrOptions * option options
          +)
          +
          +
          Traversal procedure. based on the transitive closure of the transition relation. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + +

          See Also Ntr_Trav + + +
          +int 
          +Ntr_Envelope(
          +  DdManager * dd, DD manager
          +  NtrPartTR * TR, transition relation
          +  FILE * dfp, pointer to file for DD dump
          +  NtrOptions * option program options
          +)
          +
          +
          Poor man's outer envelope computation based on the monolithic transition relation. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +void 
          +Ntr_FreeHeap(
          +  NtrHeap * heap 
          +)
          +
          +
          Frees a priority queue. +

          + +

          Side Effects None +

          + +

          See Also Ntr_InitHeap + + +
          +NtrHeap * 
          +Ntr_HeapClone(
          +  NtrHeap * source 
          +)
          +
          +
          Clones a priority queue. +

          + +

          Side Effects None +

          + +

          See Also Ntr_InitHeap + + +
          +int 
          +Ntr_HeapCount(
          +  NtrHeap * heap 
          +)
          +
          +
          Returns the number of items in a priority queue. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_HeapExtractMin(
          +  NtrHeap * heap, 
          +  void ** item, 
          +  int * key 
          +)
          +
          +
          Extracts the element with the minimum key from a priority queue. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects The minimum key and the associated item are returned as side effects. +

          + +

          See Also Ntr_HeapInsert + + +
          +int 
          +Ntr_HeapInsert(
          +  NtrHeap * heap, 
          +  void * item, 
          +  int  key 
          +)
          +
          +
          Inserts an item in a priority queue. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          See Also Ntr_HeapExtractMin + + +
          +NtrHeap * 
          +Ntr_InitHeap(
          +  int  size 
          +)
          +
          +
          Initializes a priority queue. Returns a pointer to the heap if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          See Also Ntr_FreeHeap + + +
          +int 
          +Ntr_SCC(
          +  DdManager * dd, DD manager
          +  BnetNetwork * net, network
          +  NtrOptions * option options
          +)
          +
          +
          Computes the strongly connected components of the state transition graph. Only the first 10 SCCs are computed. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + +

          See Also Ntr_Trav + + +
          +int 
          +Ntr_ShortestPaths(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Computes shortest paths in the state transition graph of a network. Three methods are availabe:
          • Bellman-Ford algorithm for single-source shortest paths; the algorithm computes the distance (number of transitions) from the initial states to all states.
          • Floyd-Warshall algorithm for all-pair shortest paths.
          • Repeated squaring algorithm for all-pair shortest paths.
          The function returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects ADD variables are created in the manager. +

          + +

          +int 
          +Ntr_TestClipping(
          +  DdManager * dd, 
          +  BnetNetwork * net1, 
          +  BnetNetwork * net2, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests BDD clipping functions. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestClosestCube(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests the Cudd_bddClosestCube function. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestCofactorEstimate(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests BDD cofactor estimate functions. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestDecomp(
          +  DdManager * dd, 
          +  BnetNetwork * net1, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests BDD decomposition functions. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestDensity(
          +  DdManager * dd, 
          +  BnetNetwork * net1, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests BDD density-related functions. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestEquivAndContain(
          +  DdManager * dd, 
          +  BnetNetwork * net1, 
          +  BnetNetwork * net2, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests functions for BDD equivalence and containment with don't cares, including Cudd_EquivDC and Cudd_bddLeqUnless. This function uses as care set the first output of net2 and checkes equivalence and containment for of all the output pairs of net1. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestHeap(
          +  NtrHeap * heap, 
          +  int  i 
          +)
          +
          +
          Tests the heap property of a priority queue. Returns 1 if Successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestMinimization(
          +  DdManager * dd, 
          +  BnetNetwork * net1, 
          +  BnetNetwork * net2, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests BDD minimization functions, including leaf-identifying compaction, squeezing, and restrict. This function uses as constraint the first output of net2 and computes positive and negative cofactors of all the outputs of net1. For each cofactor, it checks whether compaction was safe (cofactor not larger than original function) and that the expansion based on each minimization function (used as a generalized cofactor) equals the original function. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +DdNode * 
          +Ntr_TransitiveClosure(
          +  DdManager * dd, 
          +  NtrPartTR * TR, 
          +  NtrOptions * option 
          +)
          +
          +
          Builds the transitive closure of a transition relation. Returns a BDD if successful; NULL otherwise. Uses a simple squaring algorithm. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_Trav(
          +  DdManager * dd, DD manager
          +  BnetNetwork * net, network
          +  NtrOptions * option options
          +)
          +
          +
          Poor man's traversal procedure. based on the monolithic transition relation. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + +

          See Also Ntr_ClosureTrav + + +
          +int 
          +Ntr_VerifyEquivalence(
          +  DdManager * dd, 
          +  BnetNetwork * net1, 
          +  BnetNetwork * net2, 
          +  NtrOptions * option 
          +)
          +
          +
          Verify equivalence of combinational networks. Returns 1 if successful and if the networks are equivalent; -1 if successful, but the networks are not equivalent; 0 otherwise. The two networks are supposed to have the same names for inputs and outputs. The only exception is that the second network may miss output buffers that are present in the first network. This function tries to match both the output and the input of the buffer. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_buildDDs(
          +  BnetNetwork * net, network for which DDs are to be built
          +  DdManager * dd, DD manager
          +  NtrOptions * option, option structure
          +  BnetNetwork * net2 companion network with which inputs may be shared
          +)
          +
          +
          Builds DDs for a network outputs and next state functions. The method is really brain-dead, but it is very simple. Returns 1 in case of success; 0 otherwise. Some inputs to the network may be shared with another network whose DDs have already been built. In this case we want to share the DDs as well. +

          + +

          Side Effects the dd fields of the network nodes are modified. Uses the count fields of the nodes. +

          + +

          +NtrPartTR * 
          +Ntr_buildTR(
          +  DdManager * dd, manager
          +  BnetNetwork * net, network
          +  NtrOptions * option, options
          +  int  image image type: monolithic ...
          +)
          +
          +
          Builds the transition relation for a network. Returns a pointer to the transition relation structure if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          +NtrPartTR * 
          +Ntr_cloneTR(
          +  NtrPartTR * TR 
          +)
          +
          +
          Makes a copy of a transition relation. Returns a pointer to the copy if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          See Also Ntr_buildTR +Ntr_freeTR + + +
          +void 
          +Ntr_freeTR(
          +  DdManager * dd, 
          +  NtrPartTR * TR 
          +)
          +
          +
          Frees the transition relation for a network. +

          + +

          Side Effects None +

          + +

          +DdNode * 
          +Ntr_getStateCube(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  char * filename, 
          +  int  pr 
          +)
          +
          +
          Reads a state cube from a file or create a random one. Returns a pointer to the BDD of the sink nodes if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          +DdNode * 
          +Ntr_initState(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Builds the BDD of the initial state(s). Returns a BDD if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_maxflow(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Maximum 0-1 flow between source and sink states. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects Creates two new sets of variables. +

          + +

          +double 
          +Ntr_maximum01Flow(
          +  DdManager * bdd, manager
          +  DdNode * sx, source node
          +  DdNode * ty, sink node
          +  DdNode * E, edge relation
          +  DdNode ** F, flow relation
          +  DdNode ** cut, cutset relation
          +  DdNode ** x, array of row variables
          +  DdNode ** y, array of column variables
          +  DdNode ** z, arrays of auxiliary variables
          +  int  n, number of variables in each array
          +  int  pr verbosity level
          +)
          +
          +
          This function implements Dinits's algorithm for (0-1) max flow, using BDDs and a symbolic technique to trace multiple edge-disjoint augmenting paths to complete a phase. The outer forever loop is over phases, and the inner forever loop is to propagate a (not yet) maximal flow of edge-disjoint augmenting paths from one layer to the previous. The subprocedure call implements a least fixed point iteration to compute a (not yet) maximal flow update between layers. At the end of each phase (except the last one) the flow is actually pushed from the source to the sink. Data items:
          • sx(ty) BDD representations of s(t).
          • x(y) The variables encoding the from(to)-node u(v) of an edge (u,v) in the given digraph.
          • z Another set of variables.
          • E(x,y) The edge relation.
          • F(x,y) BDD representation of the current flow, initialized to 0 for each arc, and updated by +1, -1, or 0 at the end of each phase.
          • Ms Mt The maximum flow, that is, the cardinality of a minimum cut, measured at the source and at the sink, respectively. The two values should be identical.
          • reached The set of nodes already visited in the BFS of the digraph.
          • fos fanout of the source node s.
          • fit fanin of the sink node t.
          +

          + +

          Side Effects The flow realtion F and the cutset relation cut are returned as side effects. +

          + +

          +int 
          +Ntr_testISOP(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Builds ZDD covers. +

          + +

          Side Effects Creates ZDD variables in the manager. +

          + +

          +int 
          +Ntr_testZDD(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests ZDDs. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects Creates ZDD variables in the manager. +

          + +

          + 
          +STRING_EQUAL(
          +   s1, 
          +   s2 
          +)
          +
          +
          Returns 1 if the two arguments are identical strings. +

          + +

          Side Effects none +

          + + +

          + +
          + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtAbs.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtAbs.html new file mode 100644 index 000000000..485d34676 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtAbs.html @@ -0,0 +1,111 @@ + +ntr package abstract + + +

          ntr package abstract

          +

          Simple-minded package to do traversal.

          +
          + + + +
          +
          Ntr_ClosureTrav() +
          Transitive closure traversal procedure. + +
          Ntr_Envelope() +
          Poor man's outer envelope computation. + +
          Ntr_FreeHeap() +
          Frees a priority queue. + +
          Ntr_HeapClone() +
          Clones a priority queue. + +
          Ntr_HeapCount() +
          Returns the number of items in a priority queue. + +
          Ntr_HeapExtractMin() +
          Extracts the element with the minimum key from a priority queue. + +
          Ntr_HeapInsert() +
          Inserts an item in a priority queue. + +
          Ntr_InitHeap() +
          Initializes a priority queue. + +
          Ntr_SCC() +
          Computes the SCCs of the STG. + +
          Ntr_ShortestPaths() +
          Computes shortest paths in a state graph. + +
          Ntr_TestClipping() +
          Tests BDD clipping functions. + +
          Ntr_TestClosestCube() +
          Tests the Cudd_bddClosestCube function. + +
          Ntr_TestCofactorEstimate() +
          Tests BDD cofactor estimate functions. + +
          Ntr_TestDecomp() +
          Tests BDD decomposition functions. + +
          Ntr_TestDensity() +
          Tests BDD density-related functions. + +
          Ntr_TestEquivAndContain() +
          Tests BDD equivalence and containment with don't cares. + +
          Ntr_TestHeap() +
          Tests the heap property of a priority queue. + +
          Ntr_TestMinimization() +
          Tests BDD minimization functions. + +
          Ntr_TransitiveClosure() +
          Builds the transitive closure of a transition relation. + +
          Ntr_Trav() +
          Poor man's traversal procedure. + +
          Ntr_VerifyEquivalence() +
          Verify equivalence of combinational networks. + +
          Ntr_buildDDs() +
          Builds DDs for a network outputs and next state functions. + +
          Ntr_buildTR() +
          Builds the transition relation for a network. + +
          Ntr_cloneTR() +
          Makes a copy of a transition relation. + +
          Ntr_freeTR() +
          Frees the transition relation for a network. + +
          Ntr_getStateCube() +
          Reads a state cube from a file or creates a random one. + +
          Ntr_initState() +
          Builds the BDD of the initial state(s). + +
          Ntr_maxflow() +
          Maximum 0-1 flow between source and sink states. + +
          Ntr_maximum01Flow() +
          + +
          Ntr_testISOP() +
          Builds ZDD covers. + +
          Ntr_testZDD() +
          Tests ZDDs. + +
          + +
          + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtDet.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtDet.html new file mode 100644 index 000000000..ae06139ec --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtDet.html @@ -0,0 +1,500 @@ + +The ntr package + + +

          The ntr package

          +

          Simple-minded package to do traversal.

          +

          +
          + + +
          + + + + + +
          + + +
          + +
          +int 
          +Ntr_ClosureTrav(
          +  DdManager * dd, DD manager
          +  BnetNetwork * net, network
          +  NtrOptions * option options
          +)
          +
          +
          Traversal procedure. based on the transitive closure of the transition relation. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + +

          See Also Ntr_Trav + + +
          +int 
          +Ntr_Envelope(
          +  DdManager * dd, DD manager
          +  NtrPartTR * TR, transition relation
          +  FILE * dfp, pointer to file for DD dump
          +  NtrOptions * option program options
          +)
          +
          +
          Poor man's outer envelope computation based on the monolithic transition relation. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +void 
          +Ntr_FreeHeap(
          +  NtrHeap * heap 
          +)
          +
          +
          Frees a priority queue. +

          + +

          Side Effects None +

          + +

          See Also Ntr_InitHeap + + +
          +NtrHeap * 
          +Ntr_HeapClone(
          +  NtrHeap * source 
          +)
          +
          +
          Clones a priority queue. +

          + +

          Side Effects None +

          + +

          See Also Ntr_InitHeap + + +
          +int 
          +Ntr_HeapCount(
          +  NtrHeap * heap 
          +)
          +
          +
          Returns the number of items in a priority queue. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_HeapExtractMin(
          +  NtrHeap * heap, 
          +  void ** item, 
          +  int * key 
          +)
          +
          +
          Extracts the element with the minimum key from a priority queue. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects The minimum key and the associated item are returned as side effects. +

          + +

          See Also Ntr_HeapInsert + + +
          +int 
          +Ntr_HeapInsert(
          +  NtrHeap * heap, 
          +  void * item, 
          +  int  key 
          +)
          +
          +
          Inserts an item in a priority queue. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          See Also Ntr_HeapExtractMin + + +
          +NtrHeap * 
          +Ntr_InitHeap(
          +  int  size 
          +)
          +
          +
          Initializes a priority queue. Returns a pointer to the heap if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          See Also Ntr_FreeHeap + + +
          +int 
          +Ntr_SCC(
          +  DdManager * dd, DD manager
          +  BnetNetwork * net, network
          +  NtrOptions * option options
          +)
          +
          +
          Computes the strongly connected components of the state transition graph. Only the first 10 SCCs are computed. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + +

          See Also Ntr_Trav + + +
          +int 
          +Ntr_ShortestPaths(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Computes shortest paths in the state transition graph of a network. Three methods are availabe:
          • Bellman-Ford algorithm for single-source shortest paths; the algorithm computes the distance (number of transitions) from the initial states to all states.
          • Floyd-Warshall algorithm for all-pair shortest paths.
          • Repeated squaring algorithm for all-pair shortest paths.
          The function returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects ADD variables are created in the manager. +

          + +

          +int 
          +Ntr_TestClipping(
          +  DdManager * dd, 
          +  BnetNetwork * net1, 
          +  BnetNetwork * net2, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests BDD clipping functions. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestClosestCube(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests the Cudd_bddClosestCube function. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestCofactorEstimate(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests BDD cofactor estimate functions. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestDecomp(
          +  DdManager * dd, 
          +  BnetNetwork * net1, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests BDD decomposition functions. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestDensity(
          +  DdManager * dd, 
          +  BnetNetwork * net1, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests BDD density-related functions. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestEquivAndContain(
          +  DdManager * dd, 
          +  BnetNetwork * net1, 
          +  BnetNetwork * net2, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests functions for BDD equivalence and containment with don't cares, including Cudd_EquivDC and Cudd_bddLeqUnless. This function uses as care set the first output of net2 and checkes equivalence and containment for of all the output pairs of net1. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestHeap(
          +  NtrHeap * heap, 
          +  int  i 
          +)
          +
          +
          Tests the heap property of a priority queue. Returns 1 if Successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_TestMinimization(
          +  DdManager * dd, 
          +  BnetNetwork * net1, 
          +  BnetNetwork * net2, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests BDD minimization functions, including leaf-identifying compaction, squeezing, and restrict. This function uses as constraint the first output of net2 and computes positive and negative cofactors of all the outputs of net1. For each cofactor, it checks whether compaction was safe (cofactor not larger than original function) and that the expansion based on each minimization function (used as a generalized cofactor) equals the original function. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects None +

          + +

          +DdNode * 
          +Ntr_TransitiveClosure(
          +  DdManager * dd, 
          +  NtrPartTR * TR, 
          +  NtrOptions * option 
          +)
          +
          +
          Builds the transitive closure of a transition relation. Returns a BDD if successful; NULL otherwise. Uses a simple squaring algorithm. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_Trav(
          +  DdManager * dd, DD manager
          +  BnetNetwork * net, network
          +  NtrOptions * option options
          +)
          +
          +
          Poor man's traversal procedure. based on the monolithic transition relation. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects None +

          + +

          See Also Ntr_ClosureTrav + + +
          +int 
          +Ntr_VerifyEquivalence(
          +  DdManager * dd, 
          +  BnetNetwork * net1, 
          +  BnetNetwork * net2, 
          +  NtrOptions * option 
          +)
          +
          +
          Verify equivalence of combinational networks. Returns 1 if successful and if the networks are equivalent; -1 if successful, but the networks are not equivalent; 0 otherwise. The two networks are supposed to have the same names for inputs and outputs. The only exception is that the second network may miss output buffers that are present in the first network. This function tries to match both the output and the input of the buffer. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_buildDDs(
          +  BnetNetwork * net, network for which DDs are to be built
          +  DdManager * dd, DD manager
          +  NtrOptions * option, option structure
          +  BnetNetwork * net2 companion network with which inputs may be shared
          +)
          +
          +
          Builds DDs for a network outputs and next state functions. The method is really brain-dead, but it is very simple. Returns 1 in case of success; 0 otherwise. Some inputs to the network may be shared with another network whose DDs have already been built. In this case we want to share the DDs as well. +

          + +

          Side Effects the dd fields of the network nodes are modified. Uses the count fields of the nodes. +

          + +

          +NtrPartTR * 
          +Ntr_buildTR(
          +  DdManager * dd, manager
          +  BnetNetwork * net, network
          +  NtrOptions * option, options
          +  int  image image type: monolithic ...
          +)
          +
          +
          Builds the transition relation for a network. Returns a pointer to the transition relation structure if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          +NtrPartTR * 
          +Ntr_cloneTR(
          +  NtrPartTR * TR 
          +)
          +
          +
          Makes a copy of a transition relation. Returns a pointer to the copy if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          See Also Ntr_buildTR +Ntr_freeTR + + +
          +void 
          +Ntr_freeTR(
          +  DdManager * dd, 
          +  NtrPartTR * TR 
          +)
          +
          +
          Frees the transition relation for a network. +

          + +

          Side Effects None +

          + +

          +DdNode * 
          +Ntr_getStateCube(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  char * filename, 
          +  int  pr 
          +)
          +
          +
          Reads a state cube from a file or create a random one. Returns a pointer to the BDD of the sink nodes if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          +DdNode * 
          +Ntr_initState(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Builds the BDD of the initial state(s). Returns a BDD if successful; NULL otherwise. +

          + +

          Side Effects None +

          + +

          +int 
          +Ntr_maxflow(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Maximum 0-1 flow between source and sink states. Returns 1 in case of success; 0 otherwise. +

          + +

          Side Effects Creates two new sets of variables. +

          + +

          +double 
          +Ntr_maximum01Flow(
          +  DdManager * bdd, manager
          +  DdNode * sx, source node
          +  DdNode * ty, sink node
          +  DdNode * E, edge relation
          +  DdNode ** F, flow relation
          +  DdNode ** cut, cutset relation
          +  DdNode ** x, array of row variables
          +  DdNode ** y, array of column variables
          +  DdNode ** z, arrays of auxiliary variables
          +  int  n, number of variables in each array
          +  int  pr verbosity level
          +)
          +
          +
          This function implements Dinits's algorithm for (0-1) max flow, using BDDs and a symbolic technique to trace multiple edge-disjoint augmenting paths to complete a phase. The outer forever loop is over phases, and the inner forever loop is to propagate a (not yet) maximal flow of edge-disjoint augmenting paths from one layer to the previous. The subprocedure call implements a least fixed point iteration to compute a (not yet) maximal flow update between layers. At the end of each phase (except the last one) the flow is actually pushed from the source to the sink. Data items:
          • sx(ty) BDD representations of s(t).
          • x(y) The variables encoding the from(to)-node u(v) of an edge (u,v) in the given digraph.
          • z Another set of variables.
          • E(x,y) The edge relation.
          • F(x,y) BDD representation of the current flow, initialized to 0 for each arc, and updated by +1, -1, or 0 at the end of each phase.
          • Ms Mt The maximum flow, that is, the cardinality of a minimum cut, measured at the source and at the sink, respectively. The two values should be identical.
          • reached The set of nodes already visited in the BFS of the digraph.
          • fos fanout of the source node s.
          • fit fanin of the sink node t.
          +

          + +

          Side Effects The flow realtion F and the cutset relation cut are returned as side effects. +

          + +

          +int 
          +Ntr_testISOP(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Builds ZDD covers. +

          + +

          Side Effects Creates ZDD variables in the manager. +

          + +

          +int 
          +Ntr_testZDD(
          +  DdManager * dd, 
          +  BnetNetwork * net, 
          +  NtrOptions * option 
          +)
          +
          +
          Tests ZDDs. Returns 1 if successful; 0 otherwise. +

          + +

          Side Effects Creates ZDD variables in the manager. +

          + + +

          + +
          + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/main.c b/resources/3rdparty/cudd-2.5.0/nanotrav/main.c new file mode 100644 index 000000000..f0a37d660 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/main.c @@ -0,0 +1,1394 @@ +/**CFile*********************************************************************** + + FileName [main.c] + + PackageName [ntr] + + Synopsis [Main program for the nanotrav program.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define NTR_VERSION\ + "Nanotrav Version #0.12, Release date 2003/12/31" + +#define BUFLENGTH 8192 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: main.c,v 1.41 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +static char buffer[BUFLENGTH]; +#ifdef DD_DEBUG +extern st_table *checkMinterms (BnetNetwork *net, DdManager *dd, st_table *previous); +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static NtrOptions * mainInit (); +static void ntrReadOptions (int argc, char **argv, NtrOptions *option); +static void ntrReadOptionsFile (char *name, char ***argv, int *argc); +static char* readLine (FILE *fp); +static FILE * open_file (char *filename, const char *mode); +static int reorder (BnetNetwork *net, DdManager *dd, NtrOptions *option); +static void freeOption (NtrOptions *option); +static DdManager * startCudd (NtrOptions *option, int nvars); +static int ntrReadTree (DdManager *dd, char *treefile, int nvars); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Main program for ntr.] + + Description [Main program for ntr. Performs initialization. Reads command + line options and network(s). Builds BDDs with reordering, and optionally + does reachability analysis. Prints stats.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +main( + int argc, + char ** argv) +{ + NtrOptions *option; /* options */ + FILE *fp1; /* first network file pointer */ + BnetNetwork *net1 = NULL; /* first network */ + FILE *fp2; /* second network file pointer */ + BnetNetwork *net2 = NULL; /* second network */ + DdManager *dd; /* pointer to DD manager */ + int exitval; /* return value of Cudd_CheckZeroRef */ + int ok; /* overall return value from main() */ + int result; /* stores the return value of functions */ + BnetNode *node; /* auxiliary pointer to network node */ + int i; /* loop index */ + int j; /* loop index */ + double *signatures; /* array of signatures */ + int pr; /* verbosity level */ + int reencoded; /* linear transformations attempted */ + + /* Initialize. */ + option = mainInit(); + ntrReadOptions(argc,argv,option); + pr = option->verb; + reencoded = option->reordering == CUDD_REORDER_LINEAR || + option->reordering == CUDD_REORDER_LINEAR_CONVERGE || + option->autoMethod == CUDD_REORDER_LINEAR || + option->autoMethod == CUDD_REORDER_LINEAR_CONVERGE; + /* Currently traversal requires global BDDs. Override whatever + ** was specified for locGlob. + */ + if (option->traverse == TRUE || option->envelope == TRUE || + option->scc == TRUE) { + option->locGlob = BNET_GLOBAL_DD; + } + + /* Read the first network... */ + fp1 = open_file(option->file1, "r"); + net1 = Bnet_ReadNetwork(fp1,pr); + (void) fclose(fp1); + if (net1 == NULL) { + (void) fprintf(stderr,"Syntax error in %s.\n",option->file1); + exit(2); + } + /* ... and optionally echo it to the standard output. */ + if (pr > 2) { + Bnet_PrintNetwork(net1); + } + + /* Read the second network... */ + if (option->verify == TRUE || option->second == TRUE || + option->clip > 0.0 || option->dontcares) { + fp2 = open_file(option->file2, "r"); + net2 = Bnet_ReadNetwork(fp2,pr); + (void) fclose(fp2); + if (net2 == NULL) { + (void) fprintf(stderr,"Syntax error in %s.\n",option->file2); + exit(2); + } + /* ... and optionally echo it to the standard output. */ + if (pr > 2) { + Bnet_PrintNetwork(net2); + } + } + + /* Initialize manager. We start with 0 variables, because + ** Ntr_buildDDs will create new variables rather than using + ** whatever already exists. + */ + dd = startCudd(option,net1->ninputs); + if (dd == NULL) { exit(2); } + + /* Build the BDDs for the nodes of the first network. */ + result = Ntr_buildDDs(net1,dd,option,NULL); + if (result == 0) { exit(2); } + + /* Build the BDDs for the nodes of the second network if requested. */ + if (option->verify == TRUE || option->second == TRUE || + option->clip > 0.0 || option->dontcares == TRUE) { + char *nodesave = option->node; + option->node = NULL; + result = Ntr_buildDDs(net2,dd,option,net1); + option->node = nodesave; + if (result == 0) { exit(2); } + } + + if (option->noBuild == TRUE) { + Bnet_FreeNetwork(net1); + if (option->verify == TRUE || option->second == TRUE || + option->clip > 0.0) { + Bnet_FreeNetwork(net2); + } + freeOption(option); + exit(0); + } + if (option->locGlob != BNET_LOCAL_DD) { + /* Print the order before the final reordering. */ + (void) printf("Order before final reordering\n"); + result = Bnet_PrintOrder(net1,dd); + if (result == 0) exit(2); + } + + /* Perform final reordering */ + if (option->zddtest == FALSE) { + result = reorder(net1,dd,option); + if (result == 0) exit(2); + + /* Print final order. */ + if ((option->reordering != CUDD_REORDER_NONE || option->gaOnOff) && + option->locGlob != BNET_LOCAL_DD) { + (void) printf("New order\n"); + result = Bnet_PrintOrder(net1,dd); + if (result == 0) exit(2); + } + + /* Print the re-encoded inputs. */ + if (pr >= 1 && reencoded == 1) { + for (i = 0; i < net1->npis; i++) { + if (!st_lookup(net1->hash,net1->inputs[i],&node)) { + exit(2); + } + (void) fprintf(stdout,"%s:",node->name); + Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr); + } + for (i = 0; i < net1->nlatches; i++) { + if (!st_lookup(net1->hash,net1->latches[i][1],&node)) { + exit(2); + } + (void) fprintf(stdout,"%s:",node->name); + Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr); + } + if (pr >= 3) { + result = Cudd_PrintLinear(dd); + if (result == 0) exit(2); + } + } + } + + /* Verify (combinational) equivalence. */ + if (option->verify == TRUE) { + result = Ntr_VerifyEquivalence(dd,net1,net2,option); + if (result == 0) { + (void) printf("Verification abnormally terminated\n"); + exit(2); + } else if (result == -1) { + (void) printf("Combinational verification failed\n"); + } else { + (void) printf("Verification succeeded\n"); + } + } + + /* Traverse if requested and if the circuit is sequential. */ + result = Ntr_Trav(dd,net1,option); + if (result == 0) exit(2); + + /* Traverse with trasitive closure. */ + result = Ntr_ClosureTrav(dd,net1,option); + if (result == 0) exit(2); + + /* Compute outer envelope if requested and if the circuit is sequential. */ + if (option->envelope == TRUE && net1->nlatches > 0) { + NtrPartTR *T; + T = Ntr_buildTR(dd,net1,option,option->image); + result = Ntr_Envelope(dd,T,NULL,option); + Ntr_freeTR(dd,T); + } + + /* Compute SCCs if requested and if the circuit is sequential. */ + result = Ntr_SCC(dd,net1,option); + if (result == 0) exit(2); + + /* Test Constrain Decomposition. */ + if (option->partition == TRUE && net1->nlatches > 0) { + NtrPartTR *T; + DdNode *product; + DdNode **decomp; + int sharingSize; + T = Ntr_buildTR(dd,net1,option,NTR_IMAGE_MONO); + decomp = Cudd_bddConstrainDecomp(dd,T->part[0]); + if (decomp == NULL) exit(2); + sharingSize = Cudd_SharingSize(decomp, Cudd_ReadSize(dd)); + (void) fprintf(stdout, "Decomposition Size: %d components %d nodes\n", + Cudd_ReadSize(dd), sharingSize); + product = Cudd_ReadOne(dd); + Cudd_Ref(product); + for (i = 0; i < Cudd_ReadSize(dd); i++) { + DdNode *intermediate = Cudd_bddAnd(dd, product, decomp[i]); + if (intermediate == NULL) { + exit(2); + } + Cudd_Ref(intermediate); + Cudd_IterDerefBdd(dd, product); + product = intermediate; + } + if (product != T->part[0]) + exit(2); + Cudd_IterDerefBdd(dd, product); + for (i = 0; i < Cudd_ReadSize(dd); i++) { + Cudd_IterDerefBdd(dd, decomp[i]); + } + FREE(decomp); + Ntr_freeTR(dd,T); + } + + /* Test char-to-vect conversion. */ + result = Ntr_TestCharToVect(dd,net1,option); + if (result == 0) exit(2); + + /* Test extraction of two-literal clauses. */ + result = Ntr_TestTwoLiteralClauses(dd,net1,option); + if (result == 0) exit(2); + + /* Test BDD minimization functions. */ + result = Ntr_TestMinimization(dd,net1,net2,option); + if (result == 0) exit(2); + + /* Test density-related functions. */ + result = Ntr_TestDensity(dd,net1,option); + if (result == 0) exit(2); + + /* Test decomposition functions. */ + result = Ntr_TestDecomp(dd,net1,option); + if (result == 0) exit(2); + + /* Test cofactor estimation functions. */ + result = Ntr_TestCofactorEstimate(dd,net1,option); + if (result == 0) exit(2); + + /* Test BDD clipping functions. */ + result = Ntr_TestClipping(dd,net1,net2,option); + if (result == 0) exit(2); + + /* Test BDD equivalence and containment under DC functions. */ + result = Ntr_TestEquivAndContain(dd,net1,net2,option); + if (result == 0) exit(2); + + /* Test BDD Cudd_bddClosestCube. */ + result = Ntr_TestClosestCube(dd,net1,option); + if (result == 0) exit(2); + + /* Test ZDDs if requested. */ + if (option->stateOnly == FALSE && option->zddtest == TRUE) { + result = Ntr_testZDD(dd,net1,option); + if (result == 0) + (void) fprintf(stdout,"ZDD test failed.\n"); + result = Ntr_testISOP(dd,net1,option); + if (result == 0) + (void) fprintf(stdout,"ISOP test failed.\n"); + } + + /* Compute maximum flow if requested and if the circuit is sequential. */ + if (option->maxflow == TRUE && net1->nlatches > 0) { + result = Ntr_maxflow(dd,net1,option); + if (result == 0) + (void) fprintf(stdout,"Maxflow computation failed.\n"); + } + + /* Compute shortest paths if requested and if the circuit is sequential. */ + if (option->shortPath != NTR_SHORT_NONE && net1->nlatches > 0) { + result = Ntr_ShortestPaths(dd,net1,option); + if (result == 0) + (void) fprintf(stdout,"Shortest paths computation failed.\n"); + } + + /* Compute output signatures if so requested. */ + if (option->signatures) { + (void) printf("Positive cofactor measures\n"); + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + exit(2); + } + signatures = Cudd_CofMinterm(dd, node->dd); + if (signatures) { + (void) printf("%s:\n", node->name); + for (j = 0; j < Cudd_ReadSize(dd); j++) { + if((j%5 == 0)&&i) (void) printf("\n"); + (void) printf("%5d: %-#8.4g ", j, signatures[j]); + } + (void) printf("\n"); + FREE(signatures); + } else { + (void) printf("Signature computation failed.\n"); + } + } + } + + /* Dump BDDs if so requested. */ + if (option->bdddump && option->second == FALSE && + option->density == FALSE && option->decomp == FALSE && + option->cofest == FALSE && option->clip < 0.0 && + option->scc == FALSE) { + (void) printf("Dumping BDDs to %s\n", option->dumpfile); + if (option->node != NULL) { + if (!st_lookup(net1->hash,option->node,&node)) { + exit(2); + } + result = Bnet_bddArrayDump(dd,net1,option->dumpfile,&(node->dd), + &(node->name),1,option->dumpFmt); + } else { + result = Bnet_bddDump(dd, net1, option->dumpfile, + option->dumpFmt, reencoded); + } + if (result != 1) { + (void) printf("BDD dump failed.\n"); + } + } + + /* Print stats and clean up. */ + if (pr >= 0) { + result = Cudd_PrintInfo(dd,stdout); + if (result != 1) { + (void) printf("Cudd_PrintInfo failed.\n"); + } + } + +#if defined(DD_DEBUG) && !defined(DD_NO_DEATH_ROW) + (void) fprintf(dd->err,"%d empty slots in death row\n", + cuddTimesInDeathRow(dd,NULL)); +#endif + (void) printf("Final size: %ld\n", Cudd_ReadNodeCount(dd)); + + /* Dispose of node BDDs. */ + node = net1->nodes; + while (node != NULL) { + if (node->dd != NULL && + node->type != BNET_INPUT_NODE && + node->type != BNET_PRESENT_STATE_NODE) { + Cudd_IterDerefBdd(dd,node->dd); + } + node = node->next; + } + /* Dispose of network. */ + Bnet_FreeNetwork(net1); + /* Do the same cleanup for the second network if it was created. */ + if (option->verify == TRUE || option->second == TRUE || + option->clip > 0.0 || option->dontcares == TRUE) { + node = net2->nodes; + while (node != NULL) { + if (node->dd != NULL && + node->type != BNET_INPUT_NODE && + node->type != BNET_PRESENT_STATE_NODE) { + Cudd_IterDerefBdd(dd,node->dd); + } + node = node->next; + } + Bnet_FreeNetwork(net2); + } + + /* Check reference counts: At this point we should have dereferenced + ** everything we had, except in the case of re-encoding. + */ + exitval = Cudd_CheckZeroRef(dd); + ok = exitval != 0; /* ok == 0 means O.K. */ + if (exitval != 0) { + (void) fflush(stdout); + (void) fprintf(stderr, + "%d non-zero DD reference counts after dereferencing\n", exitval); + } + +#ifdef DD_DEBUG + Cudd_CheckKeys(dd); +#endif + + Cudd_Quit(dd); + + if (pr >= 0) (void) printf("total time = %s\n", + util_print_time(util_cpu_time() - option->initialTime)); + freeOption(option); + if (pr >= 0) util_print_cpu_stats(stdout); + +#ifdef MNEMOSYNE + mnem_writestats(); +#endif + + exit(ok); + /* NOTREACHED */ + +} /* end of main */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Allocates the option structure and initializes it.] + + Description [] + + SideEffects [none] + + SeeAlso [ntrReadOptions] + +******************************************************************************/ +static NtrOptions * +mainInit( + ) +{ + NtrOptions *option; + + /* Initialize option structure. */ + option = ALLOC(NtrOptions,1); + option->initialTime = util_cpu_time(); + option->verify = FALSE; + option->second = FALSE; + option->file1 = NULL; + option->file2 = NULL; + option->traverse = FALSE; + option->depend = FALSE; + option->image = NTR_IMAGE_MONO; + option->imageClip = 1.0; + option->approx = NTR_UNDER_APPROX; + option->threshold = -1; + option->from = NTR_FROM_NEW; + option->groupnsps = NTR_GROUP_NONE; + option->closure = FALSE; + option->closureClip = 1.0; + option->envelope = FALSE; + option->scc = FALSE; + option->maxflow = FALSE; + option->shortPath = NTR_SHORT_NONE; + option->selectiveTrace = FALSE; + option->zddtest = FALSE; + option->printcover = FALSE; + option->sinkfile = NULL; + option->partition = FALSE; + option->char2vect = FALSE; + option->density = FALSE; + option->quality = 1.0; + option->decomp = FALSE; + option->cofest = FALSE; + option->clip = -1.0; + option->dontcares = FALSE; + option->closestCube = FALSE; + option->clauses = FALSE; + option->noBuild = FALSE; + option->stateOnly = FALSE; + option->node = NULL; + option->locGlob = BNET_GLOBAL_DD; + option->progress = FALSE; + option->cacheSize = 32768; + option->maxMemory = 0; /* set automatically */ + option->maxMemHard = 0; /* don't set */ + option->maxLive = ~0; /* very large number */ + option->slots = CUDD_UNIQUE_SLOTS; + option->ordering = PI_PS_FROM_FILE; + option->orderPiPs = NULL; + option->reordering = CUDD_REORDER_NONE; + option->autoMethod = CUDD_REORDER_SIFT; + option->autoDyn = 0; + option->treefile = NULL; + option->firstReorder = DD_FIRST_REORDER; + option->countDead = FALSE; + option->maxGrowth = 20; + option->groupcheck = CUDD_GROUP_CHECK7; + option->arcviolation = 10; + option->symmviolation = 10; + option->recomb = DD_DEFAULT_RECOMB; + option->nodrop = TRUE; + option->signatures = FALSE; + option->verb = 0; + option->gaOnOff = 0; + option->populationSize = 0; /* use default */ + option->numberXovers = 0; /* use default */ + option->bdddump = FALSE; + option->dumpFmt = 0; /* dot */ + option->dumpfile = NULL; + option->store = -1; /* do not store */ + option->storefile = NULL; + option->load = FALSE; + option->loadfile = NULL; + + return(option); + +} /* end of mainInit */ + + +/**Function******************************************************************** + + Synopsis [Reads the command line options.] + + Description [Reads the command line options. Scans the command line + one argument at a time and performs a switch on each arguement it + hits. Some arguemnts also read in the following arg from the list + (i.e., -f also gets the filename which should folow.) + Gives a usage message and exits if any unrecognized args are found.] + + SideEffects [May initialize the random number generator.] + + SeeAlso [mainInit ntrReadOptionsFile] + +******************************************************************************/ +static void +ntrReadOptions( + int argc, + char ** argv, + NtrOptions * option) +{ + int i = 0; + + if (argc < 2) goto usage; + + if (STRING_EQUAL(argv[1],"-f")) { + ntrReadOptionsFile(argv[2],&argv,&argc); + } + + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-' ) { + if (option->file1 == NULL) { + option->file1 = util_strsav(argv[i]); + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-second")) { + i++; + option->file2 = util_strsav(argv[i]); + option->second = TRUE; + } else if (STRING_EQUAL(argv[i],"-verify")) { + i++; + option->file2 = util_strsav(argv[i]); + option->verify = TRUE; + } else if (STRING_EQUAL(argv[i],"-trav")) { + option->traverse = TRUE; + } else if (STRING_EQUAL(argv[i],"-depend")) { + option->traverse = TRUE; + option->depend = TRUE; + } else if (STRING_EQUAL(argv[i],"-image")) { + i++; + if (STRING_EQUAL(argv[i],"part")) { + option->image = NTR_IMAGE_PART; + } else if (STRING_EQUAL(argv[i],"clip")) { + option->image = NTR_IMAGE_CLIP; + } else if (STRING_EQUAL(argv[i],"depend")) { + option->image = NTR_IMAGE_DEPEND; + } else if (STRING_EQUAL(argv[i],"mono")) { + option->image = NTR_IMAGE_MONO; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-depth")) { + i++; + option->imageClip = (double) atof(argv[i]); + } else if (STRING_EQUAL(argv[i],"-cdepth")) { + i++; + option->closureClip = (double) atof(argv[i]); + } else if (STRING_EQUAL(argv[i],"-approx")) { + i++; + if (STRING_EQUAL(argv[i],"under")) { + option->approx = NTR_UNDER_APPROX; + } else if (STRING_EQUAL(argv[i],"over")) { + option->approx = NTR_OVER_APPROX; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-threshold")) { + i++; + option->threshold = (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-from")) { + i++; + if (STRING_EQUAL(argv[i],"new")) { + option->from = NTR_FROM_NEW; + } else if (STRING_EQUAL(argv[i],"reached")) { + option->from = NTR_FROM_REACHED; + } else if (STRING_EQUAL(argv[i],"restrict")) { + option->from = NTR_FROM_RESTRICT; + } else if (STRING_EQUAL(argv[i],"compact")) { + option->from = NTR_FROM_COMPACT; + } else if (STRING_EQUAL(argv[i],"squeeze")) { + option->from = NTR_FROM_SQUEEZE; + } else if (STRING_EQUAL(argv[i],"subset")) { + option->from = NTR_FROM_UNDERAPPROX; + } else if (STRING_EQUAL(argv[i],"superset")) { + option->from = NTR_FROM_OVERAPPROX; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-groupnsps")) { + i++; + if (STRING_EQUAL(argv[i],"none")) { + option->groupnsps = NTR_GROUP_NONE; + } else if (STRING_EQUAL(argv[i],"default")) { + option->groupnsps = NTR_GROUP_DEFAULT; + } else if (STRING_EQUAL(argv[i],"fixed")) { + option->groupnsps = NTR_GROUP_FIXED; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-closure")) { + option->closure = TRUE; + } else if (STRING_EQUAL(argv[i],"-envelope")) { + option->envelope = TRUE; + } else if (STRING_EQUAL(argv[i],"-scc")) { + option->scc = TRUE; + } else if (STRING_EQUAL(argv[i],"-maxflow")) { + option->maxflow = TRUE; + } else if (STRING_EQUAL(argv[i],"-shortpaths")) { + i++; + if (STRING_EQUAL(argv[i],"none")) { + option->shortPath = NTR_SHORT_NONE; + } else if (STRING_EQUAL(argv[i],"bellman")) { + option->shortPath = NTR_SHORT_BELLMAN; + } else if (STRING_EQUAL(argv[i],"floyd")) { + option->shortPath = NTR_SHORT_FLOYD; + } else if (STRING_EQUAL(argv[i],"square")) { + option->shortPath = NTR_SHORT_SQUARE; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-selective")) { + option->selectiveTrace = TRUE; + } else if (STRING_EQUAL(argv[i],"-zdd")) { + option->zddtest = TRUE; + } else if (STRING_EQUAL(argv[i],"-cover")) { + option->zddtest = TRUE; + option->printcover = TRUE; + } else if (STRING_EQUAL(argv[i],"-sink")) { + i++; + option->maxflow = TRUE; + option->sinkfile = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-part")) { + option->partition = TRUE; + } else if (STRING_EQUAL(argv[i],"-char2vect")) { + option->char2vect = TRUE; + } else if (STRING_EQUAL(argv[i],"-density")) { + option->density = TRUE; + } else if (STRING_EQUAL(argv[i],"-quality")) { + i++; + option->quality = (double) atof(argv[i]); + } else if (STRING_EQUAL(argv[i],"-decomp")) { + option->decomp = TRUE; + } else if (STRING_EQUAL(argv[i],"-cofest")) { + option->cofest = TRUE; + } else if (STRING_EQUAL(argv[i],"-clip")) { + i++; + option->clip = (double) atof(argv[i]); + i++; + option->file2 = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-dctest")) { + option->dontcares = TRUE; + i++; + option->file2 = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-closest")) { + option->closestCube = TRUE; + } else if (STRING_EQUAL(argv[i],"-clauses")) { + option->clauses = TRUE; + } else if (STRING_EQUAL(argv[i],"-nobuild")) { + option->noBuild = TRUE; + option->reordering = CUDD_REORDER_NONE; + } else if (STRING_EQUAL(argv[i],"-delta")) { + option->stateOnly = TRUE; + } else if (STRING_EQUAL(argv[i],"-node")) { + i++; + option->node = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-local")) { + option->locGlob = BNET_LOCAL_DD; + } else if (STRING_EQUAL(argv[i],"-progress")) { + option->progress = TRUE; + } else if (STRING_EQUAL(argv[i],"-cache")) { + i++; + option->cacheSize = (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-maxmem")) { + i++; + option->maxMemory = 1048576 * (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-memhard")) { + i++; + option->maxMemHard = 1048576 * (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-maxlive")) { + i++; + option->maxLive = (unsigned int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-slots")) { + i++; + option->slots = (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-ordering")) { + i++; + if (STRING_EQUAL(argv[i],"dfs")) { + option->ordering = PI_PS_DFS; + } else if (STRING_EQUAL(argv[i],"hw")) { + option->ordering = PI_PS_FROM_FILE; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-order")) { + i++; + option->ordering = PI_PS_GIVEN; + option->orderPiPs = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-reordering")) { + i++; + if (STRING_EQUAL(argv[i],"none")) { + option->reordering = CUDD_REORDER_NONE; + } else if (STRING_EQUAL(argv[i],"random")) { + option->reordering = CUDD_REORDER_RANDOM; + } else if (STRING_EQUAL(argv[i],"bernard") || + STRING_EQUAL(argv[i],"pivot")) { + option->reordering = CUDD_REORDER_RANDOM_PIVOT; + } else if (STRING_EQUAL(argv[i],"sifting")) { + option->reordering = CUDD_REORDER_SIFT; + } else if (STRING_EQUAL(argv[i],"converge")) { + option->reordering = CUDD_REORDER_SIFT_CONVERGE; + } else if (STRING_EQUAL(argv[i],"symm")) { + option->reordering = CUDD_REORDER_SYMM_SIFT; + } else if (STRING_EQUAL(argv[i],"cosymm")) { + option->reordering = CUDD_REORDER_SYMM_SIFT_CONV; + } else if (STRING_EQUAL(argv[i],"tree") || + STRING_EQUAL(argv[i],"group")) { + option->reordering = CUDD_REORDER_GROUP_SIFT; + } else if (STRING_EQUAL(argv[i],"cotree") || + STRING_EQUAL(argv[i],"cogroup")) { + option->reordering = CUDD_REORDER_GROUP_SIFT_CONV; + } else if (STRING_EQUAL(argv[i],"win2")) { + option->reordering = CUDD_REORDER_WINDOW2; + } else if (STRING_EQUAL(argv[i],"win3")) { + option->reordering = CUDD_REORDER_WINDOW3; + } else if (STRING_EQUAL(argv[i],"win4")) { + option->reordering = CUDD_REORDER_WINDOW4; + } else if (STRING_EQUAL(argv[i],"win2conv")) { + option->reordering = CUDD_REORDER_WINDOW2_CONV; + } else if (STRING_EQUAL(argv[i],"win3conv")) { + option->reordering = CUDD_REORDER_WINDOW3_CONV; + } else if (STRING_EQUAL(argv[i],"win4conv")) { + option->reordering = CUDD_REORDER_WINDOW4_CONV; + } else if (STRING_EQUAL(argv[i],"annealing")) { + option->reordering = CUDD_REORDER_ANNEALING; + } else if (STRING_EQUAL(argv[i],"genetic")) { + option->reordering = CUDD_REORDER_GENETIC; + } else if (STRING_EQUAL(argv[i],"linear")) { + option->reordering = CUDD_REORDER_LINEAR; + } else if (STRING_EQUAL(argv[i],"linconv")) { + option->reordering = CUDD_REORDER_LINEAR_CONVERGE; + } else if (STRING_EQUAL(argv[i],"exact")) { + option->reordering = CUDD_REORDER_EXACT; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-autodyn")) { + option->autoDyn = 3; + } else if (STRING_EQUAL(argv[i],"-autodynB")) { + option->autoDyn |= 1; + } else if (STRING_EQUAL(argv[i],"-autodynZ")) { + option->autoDyn |= 2; + } else if (STRING_EQUAL(argv[i],"-automethod")) { + i++; + if (STRING_EQUAL(argv[i],"none")) { + option->autoMethod = CUDD_REORDER_NONE; + } else if (STRING_EQUAL(argv[i],"random")) { + option->autoMethod = CUDD_REORDER_RANDOM; + } else if (STRING_EQUAL(argv[i],"bernard") || + STRING_EQUAL(argv[i],"pivot")) { + option->autoMethod = CUDD_REORDER_RANDOM_PIVOT; + } else if (STRING_EQUAL(argv[i],"sifting")) { + option->autoMethod = CUDD_REORDER_SIFT; + } else if (STRING_EQUAL(argv[i],"converge")) { + option->autoMethod = CUDD_REORDER_SIFT_CONVERGE; + } else if (STRING_EQUAL(argv[i],"symm")) { + option->autoMethod = CUDD_REORDER_SYMM_SIFT; + } else if (STRING_EQUAL(argv[i],"cosymm")) { + option->autoMethod = CUDD_REORDER_SYMM_SIFT_CONV; + } else if (STRING_EQUAL(argv[i],"tree") || + STRING_EQUAL(argv[i],"group")) { + option->autoMethod = CUDD_REORDER_GROUP_SIFT; + } else if (STRING_EQUAL(argv[i],"cotree") || + STRING_EQUAL(argv[i],"cogroup")) { + option->autoMethod = CUDD_REORDER_GROUP_SIFT_CONV; + } else if (STRING_EQUAL(argv[i],"win2")) { + option->autoMethod = CUDD_REORDER_WINDOW2; + } else if (STRING_EQUAL(argv[i],"win3")) { + option->autoMethod = CUDD_REORDER_WINDOW3; + } else if (STRING_EQUAL(argv[i],"win4")) { + option->autoMethod = CUDD_REORDER_WINDOW4; + } else if (STRING_EQUAL(argv[i],"win2conv")) { + option->autoMethod = CUDD_REORDER_WINDOW2_CONV; + } else if (STRING_EQUAL(argv[i],"win3conv")) { + option->autoMethod = CUDD_REORDER_WINDOW3_CONV; + } else if (STRING_EQUAL(argv[i],"win4conv")) { + option->autoMethod = CUDD_REORDER_WINDOW4_CONV; + } else if (STRING_EQUAL(argv[i],"annealing")) { + option->autoMethod = CUDD_REORDER_ANNEALING; + } else if (STRING_EQUAL(argv[i],"genetic")) { + option->autoMethod = CUDD_REORDER_GENETIC; + } else if (STRING_EQUAL(argv[i],"linear")) { + option->autoMethod = CUDD_REORDER_LINEAR; + } else if (STRING_EQUAL(argv[i],"linconv")) { + option->autoMethod = CUDD_REORDER_LINEAR_CONVERGE; + } else if (STRING_EQUAL(argv[i],"exact")) { + option->autoMethod = CUDD_REORDER_EXACT; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-tree")) { + i++; + option->treefile = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-first")) { + i++; + option->firstReorder = (int)atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-countdead")) { + option->countDead = TRUE; + } else if (STRING_EQUAL(argv[i],"-growth")) { + i++; + option->maxGrowth = (int)atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-groupcheck")) { + i++; + if (STRING_EQUAL(argv[i],"check")) { + option->groupcheck = CUDD_GROUP_CHECK; + } else if (STRING_EQUAL(argv[i],"nocheck")) { + option->groupcheck = CUDD_NO_CHECK; + } else if (STRING_EQUAL(argv[i],"check2")) { + option->groupcheck = CUDD_GROUP_CHECK2; + } else if (STRING_EQUAL(argv[i],"check3")) { + option->groupcheck = CUDD_GROUP_CHECK3; + } else if (STRING_EQUAL(argv[i],"check4")) { + option->groupcheck = CUDD_GROUP_CHECK4; + } else if (STRING_EQUAL(argv[i],"check5")) { + option->groupcheck = CUDD_GROUP_CHECK5; + } else if (STRING_EQUAL(argv[i],"check6")) { + option->groupcheck = CUDD_GROUP_CHECK6; + } else if (STRING_EQUAL(argv[i],"check7")) { + option->groupcheck = CUDD_GROUP_CHECK7; + } else if (STRING_EQUAL(argv[i],"check8")) { + option->groupcheck = CUDD_GROUP_CHECK8; + } else if (STRING_EQUAL(argv[i],"check9")) { + option->groupcheck = CUDD_GROUP_CHECK9; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-arcviolation")) { + i++; + option->arcviolation = (int)atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-symmviolation")) { + i++; + option->symmviolation = (int)atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-recomb")) { + i++; + option->recomb = (int)atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-drop")) { + option->nodrop = FALSE; + } else if (STRING_EQUAL(argv[i],"-sign")) { + option->signatures = TRUE; + } else if (STRING_EQUAL(argv[i],"-genetic")) { + option->gaOnOff = 1; + } else if (STRING_EQUAL(argv[i],"-genepop")) { + option->gaOnOff = 1; + i++; + option->populationSize = (int)atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-genexover")) { + option->gaOnOff = 1; + i++; + option->numberXovers = (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-seed")) { + i++; + Cudd_Srandom((long)atoi(argv[i])); + } else if (STRING_EQUAL(argv[i],"-dumpfile")) { + i++; + option->bdddump = TRUE; + option->dumpfile = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-dumpblif")) { + option->dumpFmt = 1; /* blif */ + } else if (STRING_EQUAL(argv[i],"-dumpdaVinci")) { + option->dumpFmt = 2; /* daVinci */ + } else if (STRING_EQUAL(argv[i],"-dumpddcal")) { + option->dumpFmt = 3; /* DDcal */ + } else if (STRING_EQUAL(argv[i],"-dumpfact")) { + option->dumpFmt = 4; /* factored form */ + } else if (STRING_EQUAL(argv[i],"-dumpmv")) { + option->dumpFmt = 5; /* blif-MV */ + } else if (STRING_EQUAL(argv[i],"-store")) { + i++; + option->store = (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-storefile")) { + i++; + option->storefile = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-loadfile")) { + i++; + option->load = 1; + option->loadfile = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-p")) { + i++; + option->verb = (int) atoi(argv[i]); + } else { + goto usage; + } + } + + if (option->store >= 0 && option->storefile == NULL) { + (void) fprintf(stdout,"-storefile mandatory with -store\n"); + exit(-1); + } + + if (option->verb >= 0) { + (void) printf("# %s\n", NTR_VERSION); + /* echo command line and arguments */ + (void) printf("#"); + for (i = 0; i < argc; i++) { + (void) printf(" %s", argv[i]); + } + (void) printf("\n"); + (void) printf("# CUDD Version "); + Cudd_PrintVersion(stdout); + (void) fflush(stdout); + } + + return; + +usage: /* convenient goto */ + printf("Usage: please read man page\n"); + if (i == 0) { + (void) fprintf(stdout,"too few arguments\n"); + } else { + (void) fprintf(stdout,"option: %s is not defined\n",argv[i]); + } + exit(-1); + +} /* end of ntrReadOptions */ + + +/**Function******************************************************************** + + Synopsis [Reads the program options from a file.] + + Description [Reads the program options from a file. Opens file. Reads + the command line from the otpions file using the read_line func. Scans + the line looking for spaces, each space is a searator and demarks a + new option. When a space is found, it is changed to a \0 to terminate + that string; then the next value of slot points to the next non-space + character. There is a limit of 1024 options. + Should produce an error (presently doesn't) on overrun of options, but + this is very unlikely to happen.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static void +ntrReadOptionsFile( + char * name, + char *** argv, + int * argc) +{ + char **slot; + char *line; + char c; + int index,flag; + FILE *fp; + + if ((fp = fopen(name,"r")) == NULL) { + fprintf(stderr,"Error: can not find cmd file %s\n",name); + exit(-1); + } + + slot = ALLOC(char *,1024); + index = 1; + line = readLine(fp); + flag = TRUE; + + do { + c = *line; + if ( c == ' ') { + flag = TRUE; + *line = '\0'; + } else if ( c != ' ' && flag == TRUE) { + flag = FALSE; + slot[index] = line; + index++; + } + line++; + } while ( *line != '\0'); + + + *argv = slot; + *argc = index; + + fclose(fp); + +} /* end of ntrReadOptionsFile */ + + +/**Function******************************************************************** + + Synopsis [Reads a line from the option file.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static char* +readLine( + FILE * fp) +{ + int c; + char *pbuffer; + + pbuffer = buffer; + + /* Strip white space from beginning of line. */ + for(;;) { + c = getc(fp); + if ( c == EOF) return(NULL); + if ( c == '\n') { + *pbuffer = '\0'; + return(buffer); /* got a blank line */ + } + if ( c != ' ') break; + } + do { + if ( c == '\\' ) { /* if we have a continuation character.. */ + do { /* scan to end of line */ + c = getc(fp); + if ( c == '\n' ) break; + } while ( c != EOF); + if ( c != EOF) { + *pbuffer = ' '; + pbuffer++; + } else return( buffer); + c = getc(fp); + continue; + } + *pbuffer = (char) c; + pbuffer++; + c = getc(fp); + } while( c != '\n' && c != EOF); + *pbuffer = '\0'; + return(buffer); + +} /* end of readLine */ + + +/**Function******************************************************************** + + Synopsis [Opens a file.] + + Description [Opens a file, or fails with an error message and exits. + Allows '-' as a synonym for standard input.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static FILE * +open_file( + char * filename, + const char * mode) +{ + FILE *fp; + + if (strcmp(filename, "-") == 0) { + return mode[0] == 'r' ? stdin : stdout; + } else if ((fp = fopen(filename, mode)) == NULL) { + perror(filename); + exit(1); + } + return(fp); + +} /* end of open_file */ + + +/**Function******************************************************************** + + Synopsis [Applies reordering to the DDs.] + + Description [Explicitly applies reordering to the DDs. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +static int +reorder( + BnetNetwork * net, + DdManager * dd /* DD Manager */, + NtrOptions * option) +{ +#ifdef DD_DEBUG + st_table *mintermTable; /* minterm counts for each output */ +#endif + int result; /* return value from functions */ + + (void) printf("Number of inputs = %d\n",net->ninputs); + + /* Perform the final reordering */ + if (option->reordering != CUDD_REORDER_NONE) { +#ifdef DD_DEBUG + result = Cudd_DebugCheck(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + return(0); + } + result = Cudd_CheckKeys(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + return(0); + } + mintermTable = checkMinterms(net,dd,NULL); + if (mintermTable == NULL) exit(2); +#endif + + dd->siftMaxVar = 1000000; + dd->siftMaxSwap = 1000000000; + result = Cudd_ReduceHeap(dd,option->reordering,1); + if (result == 0) return(0); +#ifdef DD_DEBUG + result = Cudd_DebugCheck(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + return(0); + } + result = Cudd_CheckKeys(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + return(0); + } + mintermTable = checkMinterms(net,dd,mintermTable); +#endif + + /* Print symmetry stats if pertinent */ + if (dd->tree == NULL && + (option->reordering == CUDD_REORDER_SYMM_SIFT || + option->reordering == CUDD_REORDER_SYMM_SIFT_CONV)) + Cudd_SymmProfile(dd,0,dd->size - 1); + } + + if (option->gaOnOff) { + result = Cudd_ReduceHeap(dd,CUDD_REORDER_GENETIC,1); + if (result == 0) { + (void) printf("Something went wrong in cuddGa\n"); + return(0); + } + } + + return(1); + +} /* end of reorder */ + + +/**Function******************************************************************** + + Synopsis [Frees the option structure and its appendages.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +static void +freeOption( + NtrOptions * option) +{ + if (option->file1 != NULL) FREE(option->file1); + if (option->file2 != NULL) FREE(option->file2); + if (option->orderPiPs != NULL) FREE(option->orderPiPs); + if (option->treefile != NULL) FREE(option->treefile); + if (option->sinkfile != NULL) FREE(option->sinkfile); + if (option->dumpfile != NULL) FREE(option->dumpfile); + if (option->loadfile != NULL) FREE(option->loadfile); + if (option->storefile != NULL) FREE(option->storefile); + if (option->node != NULL) FREE(option->node); + FREE(option); + +} /* end of freeOption */ + + +/**Function******************************************************************** + + Synopsis [Starts the CUDD manager with the desired options.] + + Description [Starts the CUDD manager with the desired options. + We start with 0 variables, because Ntr_buildDDs will create new + variables rather than using whatever already exists.] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +static DdManager * +startCudd( + NtrOptions * option, + int nvars) +{ + DdManager *dd; + int result; + + dd = Cudd_Init(0, 0, option->slots, option->cacheSize, option->maxMemory); + if (dd == NULL) return(NULL); + + if (option->maxMemHard != 0) { + Cudd_SetMaxMemory(dd,option->maxMemHard); + } + Cudd_SetMaxLive(dd,option->maxLive); + Cudd_SetGroupcheck(dd,option->groupcheck); + if (option->autoDyn & 1) { + Cudd_AutodynEnable(dd,option->autoMethod); + } + dd->nextDyn = option->firstReorder; + dd->countDead = (option->countDead == FALSE) ? ~0 : 0; + dd->maxGrowth = 1.0 + ((float) option->maxGrowth / 100.0); + dd->recomb = option->recomb; + dd->arcviolation = option->arcviolation; + dd->symmviolation = option->symmviolation; + dd->populationSize = option->populationSize; + dd->numberXovers = option->numberXovers; + result = ntrReadTree(dd,option->treefile,nvars); + if (result == 0) { + Cudd_Quit(dd); + return(NULL); + } +#ifndef DD_STATS + result = Cudd_EnableReorderingReporting(dd); + if (result == 0) { + (void) fprintf(stderr, + "Error reported by Cudd_EnableReorderingReporting\n"); + Cudd_Quit(dd); + return(NULL); + } +#endif + + return(dd); + +} /* end of startCudd */ + + +/**Function******************************************************************** + + Synopsis [Reads the variable group tree from a file.] + + Description [Reads the variable group tree from a file. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +static int +ntrReadTree( + DdManager * dd, + char * treefile, + int nvars) +{ + FILE *fp; + MtrNode *root; + + if (treefile == NULL) { + return(1); + } + + if ((fp = fopen(treefile,"r")) == NULL) { + (void) fprintf(stderr,"Unable to open %s\n",treefile); + return(0); + } + + root = Mtr_ReadGroups(fp,ddMax(Cudd_ReadSize(dd),nvars)); + if (root == NULL) { + return(0); + } + + Cudd_SetTree(dd,root); + + return(1); + +} /* end of ntrReadTree */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.blif b/resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.blif new file mode 100644 index 000000000..5fafc00d9 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.blif @@ -0,0 +1,745 @@ +.model MultiplierA_32 +.inputs 1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 +.outputs 68 +.latch 67 2 0 +.latch 69 36 0 +.latch 70 37 0 +.latch 71 38 0 +.latch 72 39 0 +.latch 73 40 0 +.latch 74 41 0 +.latch 75 42 0 +.latch 76 43 0 +.latch 77 44 0 +.latch 78 45 0 +.latch 79 46 0 +.latch 80 47 0 +.latch 81 48 0 +.latch 82 49 0 +.latch 83 50 0 +.latch 84 51 0 +.latch 85 52 0 +.latch 86 53 0 +.latch 87 54 0 +.latch 88 55 0 +.latch 89 56 0 +.latch 90 57 0 +.latch 91 58 0 +.latch 92 59 0 +.latch 93 60 0 +.latch 94 61 0 +.latch 95 62 0 +.latch 96 63 0 +.latch 97 64 0 +.latch 98 65 0 +.latch 99 66 0 +.names 101 100 +0 1 +.names 1 204 101 +00 1 +11 1 +.names 3 102 +1 1 +.names 4 103 +1 1 +.names 5 104 +1 1 +.names 6 105 +1 1 +.names 7 106 +1 1 +.names 8 107 +1 1 +.names 9 108 +1 1 +.names 10 109 +1 1 +.names 11 110 +1 1 +.names 12 111 +1 1 +.names 13 112 +1 1 +.names 14 113 +1 1 +.names 15 114 +1 1 +.names 16 115 +1 1 +.names 17 116 +1 1 +.names 18 117 +1 1 +.names 19 118 +1 1 +.names 20 119 +1 1 +.names 21 120 +1 1 +.names 22 121 +1 1 +.names 23 122 +1 1 +.names 24 123 +1 1 +.names 25 124 +1 1 +.names 26 125 +1 1 +.names 27 126 +1 1 +.names 28 127 +1 1 +.names 29 128 +1 1 +.names 30 129 +1 1 +.names 31 130 +1 1 +.names 32 131 +1 1 +.names 33 132 +1 1 +.names 34 133 +1 1 +.names 134 +.names 135 +.names 136 +.names 137 +.names 138 +.names 139 +.names 140 +.names 141 +.names 142 +.names 143 +.names 144 +.names 145 +.names 146 +.names 147 +.names 148 +.names 149 +.names 150 +.names 151 +.names 152 +.names 153 +.names 154 +.names 155 +.names 156 +.names 157 +.names 158 +.names 159 +.names 160 +.names 161 +.names 162 +.names 163 +.names 164 +.names 165 +.names 66 265 266 166 +-11 1 +1-1 1 +11- 1 +.names 36 205 206 167 +010 1 +001 1 +100 1 +111 1 +.names 37 207 208 168 +010 1 +001 1 +100 1 +111 1 +.names 38 209 210 169 +010 1 +001 1 +100 1 +111 1 +.names 39 211 212 170 +010 1 +001 1 +100 1 +111 1 +.names 40 213 214 171 +010 1 +001 1 +100 1 +111 1 +.names 41 215 216 172 +010 1 +001 1 +100 1 +111 1 +.names 42 217 218 173 +010 1 +001 1 +100 1 +111 1 +.names 43 219 220 174 +010 1 +001 1 +100 1 +111 1 +.names 44 221 222 175 +010 1 +001 1 +100 1 +111 1 +.names 45 223 224 176 +010 1 +001 1 +100 1 +111 1 +.names 46 225 226 177 +010 1 +001 1 +100 1 +111 1 +.names 47 227 228 178 +010 1 +001 1 +100 1 +111 1 +.names 48 229 230 179 +010 1 +001 1 +100 1 +111 1 +.names 49 231 232 180 +010 1 +001 1 +100 1 +111 1 +.names 50 233 234 181 +010 1 +001 1 +100 1 +111 1 +.names 51 235 236 182 +010 1 +001 1 +100 1 +111 1 +.names 52 237 238 183 +010 1 +001 1 +100 1 +111 1 +.names 53 239 240 184 +010 1 +001 1 +100 1 +111 1 +.names 54 241 242 185 +010 1 +001 1 +100 1 +111 1 +.names 55 243 244 186 +010 1 +001 1 +100 1 +111 1 +.names 56 245 246 187 +010 1 +001 1 +100 1 +111 1 +.names 57 247 248 188 +010 1 +001 1 +100 1 +111 1 +.names 58 249 250 189 +010 1 +001 1 +100 1 +111 1 +.names 59 251 252 190 +010 1 +001 1 +100 1 +111 1 +.names 60 253 254 191 +010 1 +001 1 +100 1 +111 1 +.names 61 255 256 192 +010 1 +001 1 +100 1 +111 1 +.names 62 257 258 193 +010 1 +001 1 +100 1 +111 1 +.names 63 259 260 194 +010 1 +001 1 +100 1 +111 1 +.names 64 261 262 195 +010 1 +001 1 +100 1 +111 1 +.names 65 263 264 196 +010 1 +001 1 +100 1 +111 1 +.names 66 265 266 197 +010 1 +001 1 +100 1 +111 1 +.names 2 268 198 +10 1 +01 1 +.names 269 270 199 +11 1 +.names 166 272 200 +11 1 +.names 166 274 201 +11 1 +.names 166 275 202 +11 1 +.names 276 277 203 +-1 1 +1- 1 +.names 204 +.names 205 +.names 340 341 206 +-1 1 +1- 1 +.names 36 205 206 207 +-11 1 +1-1 1 +11- 1 +.names 338 339 208 +-1 1 +1- 1 +.names 37 207 208 209 +-11 1 +1-1 1 +11- 1 +.names 336 337 210 +-1 1 +1- 1 +.names 38 209 210 211 +-11 1 +1-1 1 +11- 1 +.names 334 335 212 +-1 1 +1- 1 +.names 39 211 212 213 +-11 1 +1-1 1 +11- 1 +.names 332 333 214 +-1 1 +1- 1 +.names 40 213 214 215 +-11 1 +1-1 1 +11- 1 +.names 330 331 216 +-1 1 +1- 1 +.names 41 215 216 217 +-11 1 +1-1 1 +11- 1 +.names 328 329 218 +-1 1 +1- 1 +.names 42 217 218 219 +-11 1 +1-1 1 +11- 1 +.names 326 327 220 +-1 1 +1- 1 +.names 43 219 220 221 +-11 1 +1-1 1 +11- 1 +.names 324 325 222 +-1 1 +1- 1 +.names 44 221 222 223 +-11 1 +1-1 1 +11- 1 +.names 322 323 224 +-1 1 +1- 1 +.names 45 223 224 225 +-11 1 +1-1 1 +11- 1 +.names 320 321 226 +-1 1 +1- 1 +.names 46 225 226 227 +-11 1 +1-1 1 +11- 1 +.names 318 319 228 +-1 1 +1- 1 +.names 47 227 228 229 +-11 1 +1-1 1 +11- 1 +.names 316 317 230 +-1 1 +1- 1 +.names 48 229 230 231 +-11 1 +1-1 1 +11- 1 +.names 314 315 232 +-1 1 +1- 1 +.names 49 231 232 233 +-11 1 +1-1 1 +11- 1 +.names 312 313 234 +-1 1 +1- 1 +.names 50 233 234 235 +-11 1 +1-1 1 +11- 1 +.names 310 311 236 +-1 1 +1- 1 +.names 51 235 236 237 +-11 1 +1-1 1 +11- 1 +.names 308 309 238 +-1 1 +1- 1 +.names 52 237 238 239 +-11 1 +1-1 1 +11- 1 +.names 306 307 240 +-1 1 +1- 1 +.names 53 239 240 241 +-11 1 +1-1 1 +11- 1 +.names 304 305 242 +-1 1 +1- 1 +.names 54 241 242 243 +-11 1 +1-1 1 +11- 1 +.names 302 303 244 +-1 1 +1- 1 +.names 55 243 244 245 +-11 1 +1-1 1 +11- 1 +.names 300 301 246 +-1 1 +1- 1 +.names 56 245 246 247 +-11 1 +1-1 1 +11- 1 +.names 298 299 248 +-1 1 +1- 1 +.names 57 247 248 249 +-11 1 +1-1 1 +11- 1 +.names 296 297 250 +-1 1 +1- 1 +.names 58 249 250 251 +-11 1 +1-1 1 +11- 1 +.names 294 295 252 +-1 1 +1- 1 +.names 59 251 252 253 +-11 1 +1-1 1 +11- 1 +.names 292 293 254 +-1 1 +1- 1 +.names 60 253 254 255 +-11 1 +1-1 1 +11- 1 +.names 290 291 256 +-1 1 +1- 1 +.names 61 255 256 257 +-11 1 +1-1 1 +11- 1 +.names 288 289 258 +-1 1 +1- 1 +.names 62 257 258 259 +-11 1 +1-1 1 +11- 1 +.names 286 287 260 +-1 1 +1- 1 +.names 63 259 260 261 +-11 1 +1-1 1 +11- 1 +.names 284 285 262 +-1 1 +1- 1 +.names 64 261 262 263 +-11 1 +1-1 1 +11- 1 +.names 282 283 264 +-1 1 +1- 1 +.names 65 263 264 265 +-11 1 +1-1 1 +11- 1 +.names 280 281 266 +-1 1 +1- 1 +.names 278 279 267 +-1 1 +1- 1 +.names 166 267 268 +01 1 +10 1 +.names 2 267 269 +11 1 +.names 166 270 +0 1 +.names 267 271 +0 1 +.names 2 271 272 +11 1 +.names 2 273 +0 1 +.names 267 273 274 +11 1 +.names 2 267 275 +11 1 +.names 199 200 276 +-1 1 +1- 1 +.names 201 202 277 +-1 1 +1- 1 +.names 203 67 +1 1 +.names 167 68 +1 1 +.names 168 69 +1 1 +.names 169 70 +1 1 +.names 170 71 +1 1 +.names 171 72 +1 1 +.names 172 73 +1 1 +.names 173 74 +1 1 +.names 174 75 +1 1 +.names 175 76 +1 1 +.names 176 77 +1 1 +.names 177 78 +1 1 +.names 178 79 +1 1 +.names 179 80 +1 1 +.names 180 81 +1 1 +.names 181 82 +1 1 +.names 182 83 +1 1 +.names 183 84 +1 1 +.names 184 85 +1 1 +.names 185 86 +1 1 +.names 186 87 +1 1 +.names 187 88 +1 1 +.names 188 89 +1 1 +.names 189 90 +1 1 +.names 190 91 +1 1 +.names 191 92 +1 1 +.names 192 93 +1 1 +.names 193 94 +1 1 +.names 194 95 +1 1 +.names 195 96 +1 1 +.names 196 97 +1 1 +.names 197 98 +1 1 +.names 198 99 +1 1 +.names 100 133 278 +11 1 +.names 101 165 279 +11 1 +.names 100 132 280 +11 1 +.names 101 164 281 +11 1 +.names 100 131 282 +11 1 +.names 101 163 283 +11 1 +.names 100 130 284 +11 1 +.names 101 162 285 +11 1 +.names 100 129 286 +11 1 +.names 101 161 287 +11 1 +.names 100 128 288 +11 1 +.names 101 160 289 +11 1 +.names 100 127 290 +11 1 +.names 101 159 291 +11 1 +.names 100 126 292 +11 1 +.names 101 158 293 +11 1 +.names 100 125 294 +11 1 +.names 101 157 295 +11 1 +.names 100 124 296 +11 1 +.names 101 156 297 +11 1 +.names 100 123 298 +11 1 +.names 101 155 299 +11 1 +.names 100 122 300 +11 1 +.names 101 154 301 +11 1 +.names 100 121 302 +11 1 +.names 101 153 303 +11 1 +.names 100 120 304 +11 1 +.names 101 152 305 +11 1 +.names 100 119 306 +11 1 +.names 101 151 307 +11 1 +.names 100 118 308 +11 1 +.names 101 150 309 +11 1 +.names 100 117 310 +11 1 +.names 101 149 311 +11 1 +.names 100 116 312 +11 1 +.names 101 148 313 +11 1 +.names 100 115 314 +11 1 +.names 101 147 315 +11 1 +.names 100 114 316 +11 1 +.names 101 146 317 +11 1 +.names 100 113 318 +11 1 +.names 101 145 319 +11 1 +.names 100 112 320 +11 1 +.names 101 144 321 +11 1 +.names 100 111 322 +11 1 +.names 101 143 323 +11 1 +.names 100 110 324 +11 1 +.names 101 142 325 +11 1 +.names 100 109 326 +11 1 +.names 101 141 327 +11 1 +.names 100 108 328 +11 1 +.names 101 140 329 +11 1 +.names 100 107 330 +11 1 +.names 101 139 331 +11 1 +.names 100 106 332 +11 1 +.names 101 138 333 +11 1 +.names 100 105 334 +11 1 +.names 101 137 335 +11 1 +.names 100 104 336 +11 1 +.names 101 136 337 +11 1 +.names 100 103 338 +11 1 +.names 101 135 339 +11 1 +.names 100 102 340 +11 1 +.names 101 134 341 +11 1 +.end diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.out b/resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.out new file mode 100644 index 000000000..f0933305e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.out @@ -0,0 +1,258 @@ +# Nanotrav Version #0.12, Release date 2003/12/31 +# ./nanotrav -p 1 -autodyn -reordering sifting -trav mult32a.blif +# CUDD Version 2.4.2 +BDD reordering with sifting: from 4001 to ... 268 nodes in 0.005 sec +BDD reordering with sifting: from 537 to ... 246 nodes in 0.006 sec +BDD reordering with sifting: from 493 to ... 250 nodes in 0.009 sec +BDD reordering with sifting: from 501 to ... 280 nodes in 0.012 sec +BDD reordering with sifting: from 561 to ... 296 nodes in 0.015 sec +Order before final reordering +2 34 33 66 32 65 31 64 +63 30 62 29 28 61 27 60 +26 59 25 58 24 57 23 56 +22 55 21 54 20 53 19 52 +51 18 50 17 49 16 48 15 +47 14 46 13 45 12 36 3 +37 4 38 5 39 6 40 7 +41 8 42 9 43 10 44 11 +1 +Number of inputs = 65 +BDD reordering with sifting: from 380 to ... 317 nodes in 0.012 sec +New order +1 2 34 66 33 65 32 64 +31 63 30 62 29 61 28 60 +27 59 26 58 25 57 24 56 +23 55 22 54 21 53 20 52 +19 51 18 50 17 49 16 48 +15 47 14 46 13 45 12 36 +3 4 37 5 38 6 39 7 +40 8 41 9 42 10 43 44 +11 +Building transition relation. Time = 0.06 sec +BDD reordering with sifting: from 670 to ... 453 nodes in 0.029 sec +@@BDD reordering with sifting: from 940 to ... 700 nodes in 0.03 sec +@@BDD reordering with sifting: from 1433 to ... 832 nodes in 0.039 sec +@@BDD reordering with sifting: from 1697 to ... 1063 nodes in 0.045 sec +@@@BDD reordering with sifting: from 2159 to ... 786 nodes in 0.049 sec +@@@@BDD reordering with sifting: from 1605 to ... 893 nodes in 0.043 sec +@@@@BDD reordering with sifting: from 1819 to ... 951 nodes in 0.048 sec +@@@@@BDD reordering with sifting: from 1935 to ... 965 nodes in 0.055 sec +@@@@@BDD reordering with sifting: from 1963 to ... 1055 nodes in 0.059 sec +@@@@@ +Transition relation: 1 parts 32 latches 199 nodes +Traversing. Time = 0.46 sec +S0: 33 nodes 1 leaves 1 minterms +From[1]: 33 nodes 1 leaves 2.14748e+09 minterms +Reached[1]: 2 nodes 1 leaves 2.14748e+09 minterms +2147483648 +2.14748e+9 +From[2]: 3 nodes 1 leaves 1.07374e+09 minterms +Reached[2]: 3 nodes 1 leaves 3.22123e+09 minterms +3221225472 +3.22122e+9 +From[3]: 4 nodes 1 leaves 5.36871e+08 minterms +Reached[3]: 4 nodes 1 leaves 3.7581e+09 minterms +3758096384 +3.75809e+9 +From[4]: 5 nodes 1 leaves 2.68435e+08 minterms +Reached[4]: 5 nodes 1 leaves 4.02653e+09 minterms +4026531840 +4.02653e+9 +From[5]: 6 nodes 1 leaves 1.34218e+08 minterms +Reached[5]: 6 nodes 1 leaves 4.16075e+09 minterms +4160749568 +4.16074e+9 +From[6]: 7 nodes 1 leaves 6.71089e+07 minterms +Reached[6]: 7 nodes 1 leaves 4.22786e+09 minterms +4227858432 +4.22785e+9 +From[7]: 8 nodes 1 leaves 3.35544e+07 minterms +Reached[7]: 8 nodes 1 leaves 4.26141e+09 minterms +4261412864 +4.26141e+9 +From[8]: 9 nodes 1 leaves 1.67772e+07 minterms +Reached[8]: 9 nodes 1 leaves 4.27819e+09 minterms +4278190080 +4.27819e+9 +From[9]: 10 nodes 1 leaves 8.38861e+06 minterms +Reached[9]: 10 nodes 1 leaves 4.28658e+09 minterms +4286578688 +4.28657e+9 +From[10]: 11 nodes 1 leaves 4.1943e+06 minterms +Reached[10]: 11 nodes 1 leaves 4.29077e+09 minterms +4290772992 +4.29077e+9 +From[11]: 12 nodes 1 leaves 2.09715e+06 minterms +Reached[11]: 12 nodes 1 leaves 4.29287e+09 minterms +4292870144 +4.29287e+9 +From[12]: 13 nodes 1 leaves 1.04858e+06 minterms +Reached[12]: 13 nodes 1 leaves 4.29392e+09 minterms +4293918720 +4.29391e+9 +From[13]: 14 nodes 1 leaves 524288 minterms +Reached[13]: 14 nodes 1 leaves 4.29444e+09 minterms +4294443008 +4.29444e+9 +From[14]: 15 nodes 1 leaves 262144 minterms +Reached[14]: 15 nodes 1 leaves 4.29471e+09 minterms +4294705152 +4.29470e+9 +From[15]: 16 nodes 1 leaves 131072 minterms +Reached[15]: 16 nodes 1 leaves 4.29484e+09 minterms +4294836224 +4.29483e+9 +From[16]: 17 nodes 1 leaves 65536 minterms +Reached[16]: 17 nodes 1 leaves 4.2949e+09 minterms +4294901760 +4.29490e+9 +From[17]: 18 nodes 1 leaves 32768 minterms +Reached[17]: 18 nodes 1 leaves 4.29493e+09 minterms +4294934528 +4.29493e+9 +From[18]: 19 nodes 1 leaves 16384 minterms +Reached[18]: 19 nodes 1 leaves 4.29495e+09 minterms +4294950912 +4.29495e+9 +From[19]: 20 nodes 1 leaves 8192 minterms +Reached[19]: 20 nodes 1 leaves 4.29496e+09 minterms +4294959104 +4.29495e+9 +From[20]: 21 nodes 1 leaves 4096 minterms +Reached[20]: 21 nodes 1 leaves 4.29496e+09 minterms +4294963200 +4.29496e+9 +From[21]: 22 nodes 1 leaves 2048 minterms +Reached[21]: 22 nodes 1 leaves 4.29497e+09 minterms +4294965248 +4.29496e+9 +From[22]: 23 nodes 1 leaves 1024 minterms +Reached[22]: 23 nodes 1 leaves 4.29497e+09 minterms +4294966272 +4.29496e+9 +From[23]: 24 nodes 1 leaves 512 minterms +Reached[23]: 24 nodes 1 leaves 4.29497e+09 minterms +4294966784 +4.29496e+9 +From[24]: 25 nodes 1 leaves 256 minterms +Reached[24]: 25 nodes 1 leaves 4.29497e+09 minterms +4294967040 +4.29496e+9 +From[25]: 26 nodes 1 leaves 128 minterms +Reached[25]: 26 nodes 1 leaves 4.29497e+09 minterms +4294967168 +4.29496e+9 +From[26]: 27 nodes 1 leaves 64 minterms +Reached[26]: 27 nodes 1 leaves 4.29497e+09 minterms +4294967232 +4.29496e+9 +From[27]: 28 nodes 1 leaves 32 minterms +Reached[27]: 28 nodes 1 leaves 4.29497e+09 minterms +4294967264 +4.29496e+9 +From[28]: 29 nodes 1 leaves 16 minterms +Reached[28]: 29 nodes 1 leaves 4.29497e+09 minterms +4294967280 +4.29496e+9 +From[29]: 30 nodes 1 leaves 8 minterms +Reached[29]: 30 nodes 1 leaves 4.29497e+09 minterms +4294967288 +4.29496e+9 +From[30]: 31 nodes 1 leaves 4 minterms +Reached[30]: 31 nodes 1 leaves 4.29497e+09 minterms +4294967292 +4.29496e+9 +From[31]: 32 nodes 1 leaves 2 minterms +Reached[31]: 32 nodes 1 leaves 4.29497e+09 minterms +4294967294 +4.29496e+9 +From[32]: 33 nodes 1 leaves 1 minterms +Reached[32]: 33 nodes 1 leaves 4.29497e+09 minterms +4294967295 +4.29496e+9 +depth = 32 +R: 33 nodes 1 leaves 4.29497e+09 minterms +Order at the end of reachability analysis +1 2 34 33 66 32 65 31 +64 63 30 29 62 28 61 60 +27 59 26 58 25 57 24 56 +23 55 22 54 21 20 53 19 +52 18 51 17 50 16 49 15 +48 14 47 13 46 12 45 11 +44 10 43 3 36 4 37 5 +38 6 39 7 40 8 41 42 +9 +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000000 +Maximum number of variable swaps per reordering: 1000000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: yes +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: no +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 10 +Arc violation threshold: 10 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 2178 +**** CUDD non-modifiable parameters **** +Memory in use: 5461692 +Peak number of nodes: 7154 +Peak number of live nodes: 4004 +Number of BDD variables: 97 +Number of ZDD variables: 0 +Number of cache entries: 65536 +Number of cache look-ups: 48730 +Number of cache hits: 20857 +Number of cache insertions: 27828 +Number of cache collisions: 997 +Number of cache deletions: 20076 +Cache used slots = 17.56% (expected 10.31%) +Soft limit for cache size: 100352 +Number of buckets in unique table: 25088 +Used buckets in unique table: 12.29% (expected 12.30%) +Number of BDD and ADD nodes: 3533 +Number of ZDD nodes: 0 +Number of dead BDD and ADD nodes: 3186 +Number of dead ZDD nodes: 0 +Total number of nodes allocated: 23948 +Total number of nodes reclaimed: 3937 +Garbage collections so far: 15 +Time for garbage collection: 0.00 sec +Reorderings so far: 15 +Time for reordering: 0.46 sec +Final size: 275 +total time = 0.47 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 0.5 seconds +System time 0.0 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131815K +Virtual data size = 297K + data size initialized = 25K + data size uninitialized = 137K + data size sbrk = 135K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 0 +Minor page faults = 1754 +Swaps = 0 +Input blocks = 0 +Output blocks = 0 +Context switch (voluntary) = 1 +Context switch (involuntary) = 21 diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/nanotrav.1 b/resources/3rdparty/cudd-2.5.0/nanotrav/nanotrav.1 new file mode 100644 index 000000000..ba50f469b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/nanotrav.1 @@ -0,0 +1,379 @@ +.\" $Id: nanotrav.1,v 1.23 2009/02/21 06:00:31 fabio Exp fabio $ +.\" +.TH NANOTRAV 1 "18 June 2002" "Release 0.11" +.SH NAME +nanotrav \- a simple state graph traversal program +.SH SYNOPSIS +.B nanotrav +[option ...] +.SH DESCRIPTION + +nanotrav builds the BDDs of a circuit and applies various reordering +methods to the BDDs. It then traverses the state transition graph of +the circuit if the circuit is sequential, and if the user so requires. +nanotrav is based on the CUDD package. The ordering of the variables +is affected by three sets of options: the options that specify the +initial order (-order -ordering); the options that specify the +reordering while the BDDs are being built (-autodyn -automethod); and +the options to specify the final reordering (-reordering +-genetic). Notice that both -autodyn and -automethod must be specified +to get dynamic reordering. The first enables reordering, while the +second says what method to use. +.SH OPTIONS +.TP 10 +.B \fIfile\fB +read input in blif format from \fIfile\fR. +.TP 10 +.B \-f \fIfile\fB +read options from \fIfile\fR. +.TP 10 +.B \-trav +traverse the state transition graph after building the BDDs. This +option has effect only if the circuit is sequential. The initial +states for traversal are taken from the blif file. +.TP 10 +.B \-depend +perform dependent variable analysis after traversal. +.TP 10 +.B \-from \fImethod\fB +use \fImethod\fR to choose the frontier states for image computation +during traversal. Allowed methods are: \fInew\fR (default), \fIreached\fR, +\fIrestrict\fR, \fIcompact\fR, \fIsqueeze\fR, \fIsubset\fR, \fIsuperset\fR. +.TP 10 +.B \-groupnsps \fImethod\fB +use \fImethod\fR to group the corresponding current and next state +variables. Allowed methods are: \fInone\fR (default), \fIdefault\fR, +\fIfixed\fR. +.TP 10 +.B \-image \fImethod\fB +use \fImethod\fR for image computation during traversal. Allowed +methods are: \fImono\fR (default), \fIpart\fR, \fIdepend\fR, and +\fIclip\fR. +.TP 10 +.B \-depth \fIn\fB +use \fIn\fR to derive the clipping depth for image +computation. It should be a number between 0 and 1. The default value +is 1 (no clipping). +.TP 10 +.B \-verify \fIfile\fB +perform combinational verification checking for equivalence to +the network in \fIfile\fR. The two networks being compared must use +the same names for inputs, outputs, and present and next state +variables. The method used for verification is extremely +simplistic. BDDs are built for all outputs of both networks, and are +then compared. +.TP 10 +.B \-closure +perform reachability analysis using the transitive closure of the +transition relation. +.TP 10 +.B \-cdepth \fIn\fB +use \fIn\fR to derive the clipping depth for transitive closure +computation. It should be a number between 0 and 1. The default value +is 1 (no clipping). +.TP 10 +.B \-envelope +compute the greatest fixed point of the state transition +relation. (This greatest fixed point is also called the outer envelope +of the graph.) +.TP 10 +.B \-scc +compute the strongly connected components of the state transition +graph. The algorithm enumerates the SCCs; therefore it stops after a +small number of them has been computed. +.TP 10 +.B \-maxflow +compute the maximum flow in the network defined by the state graph. +.TP 10 +.B \-sink \fIfile\fB +read the sink for maximum flow computation from \fIfile\fR. The source +is given by the initial states. +.TP 10 +.B \-shortpaths \fImethod\fB +compute the distances between states. Allowed methods are: \fInone\fR +(default), \fIbellman\fR, \fIfloyd\fR, and \fIsquare\fR. +.TP 10 +.B \-selective +use selective tracing variant of the \fIsquare\fR method for shortest +paths. +.TP 10 +.B \-part +compute the conjunctive decomposition of the transition relation. The +network must be sequential for the test to take place. +.TP 10 +.B \-sign +compute signatures. For each output of the circuit, all inputs are +assigned a signature. The signature is the fraction of minterms in the +ON\-set of the positive cofactor of the output with respect to the +input. Signatures are useful in identifying the equivalence of circuits +with unknown input or output correspondence. +.TP 10 +.B \-zdd +perform a simple test of ZDD functions. This test is not executed if +-delta is also specified, because it uses the BDDs of the primary +outputs of the circuit. These are converted to ZDDs and the ZDDs are +then converted back to BDDs and checked against the original ones. A +few more functions are exercised and reordering is applied if it is +enabled. Then irredundant sums of products are produced for the +primary outputs. +.TP 10 +.B \-cover +print irredundant sums of products for the primary outputs. This +option implies \fB\-zdd\fR. +.TP 10 +.B \-second \fIfile\fB +read a second network from \fIfile\fR. Currently, if this option is +specified, a test of BDD minimization algorithms is performed using +the largest output of the second network as constraint. Inputs of the +two networks with the same names are merged. +.TP 10 +.B \-density +test BDD approximation functions. +.TP 10 +.B \-approx \fImethod\fB +if \fImethod\fR is \fIunder\fR (default) perform underapproximation +when BDDs are approximated. If \fImethod\fR is \fIover\fR perform +overapproximation when BDDs are approximated. +.TP 10 +.B \-threshold \fIn\fB +Use \fIn\fR as threshold when approximating BDDs. +.TP 10 +.B \-quality \fIn\fB +Use \fIn\fR (a floating point number) as quality factor when +approximating BDDs. Default value is 1. +.TP 10 +.B \-decomp +test BDD decomposition functions. +.TP 10 +.B \-cofest +test cofactor estimation functions. +.TP 10 +.B \-clip \fIn file\fB +test clipping functions using \fIn\fR to determine the clipping depth +and taking one operand from the network in \fIfile\fR. +.TP 10 +.B \-dctest \fIfile\fB +test functions for equality and containment under don't care +conditions taking the don't care conditions from \fIfile\fR. +.TP 10 +.B \-closest +test function that finds a cube in a BDD at minimum Hamming distance +from another BDD. +.TP 10 +.B \-clauses +test function that extracts two-literal clauses from a DD. +.TP 10 +.B \-char2vect +perform a simple test of the conversion from characteristic function +to functional vector. If the network is sequential, the test is +applied to the monolithic transition relation; otherwise to the primary +outputs. +.TP 10 +.B \-local +build local BDDs for each gate of the circuit. This option is not in +effect if traversal, outer envelope computation, or maximum flow +computation are requested. The local BDD of a gate is in terms of its +local inputs. +.TP 10 +.B \-cache \fIn\fB +set the initial size of the computed table to \fIn\fR. +.TP 10 +.B \-slots \fIn\fB +set the initial size of each unique subtable to \fIn\fR. +.TP 10 +.B \-maxmem \fIn\fB +set the target maximum memory occupation to \fIn\fR MB. If this +parameter is not specified or if \fIn\fR is 0, then a suitable value +is computed automatically. +.TP 10 +.B \-memhard \fIn\fB +set the hard limit to memory occupation to \fIn\fR MB. If this +parameter is not specified or if \fIn\fR is 0, no hard limit is +enforced by the program. +.TP 10 +.B \-maxlive \fIn\fB +set the hard limit to the number of live BDD nodes to \fIn\fR. If +this parameter is not specified, the limit is four billion nodes. +.TP 10 +.B \-dumpfile \fIfile\fB +dump BDDs to \fIfile\fR. The BDDs are dumped just before program +termination. (Hence, after reordering, if reordering is specified.) +.TP 10 +.B \-dumpblif +use blif format for dump of BDDs (default is dot format). If blif is +used, the BDDs are dumped as a network of multiplexers. The dot format +is suitable for input to the dot program, which produces a +drawing of the BDDs. +.TP 10 +.B \-dumpmv +use blif-MV format for dump of BDDs. The BDDs are dumped as a network +of multiplexers. +.TP 10 +.B \-dumpdaVinci +use daVinci format for dump of BDDs. +.TP 10 +.B \-dumpddcal +use DDcal format for dump of BDDs. This option may produce an invalid +output if the variable and output names of the BDDs being dumped do +not comply with the restrictions imposed by the DDcal format. +.TP 10 +.B \-dumpfact +use factored form format for dump of BDDs. This option must be used +with caution because the size of the output is proportional to the +number of paths in the BDD. +.TP 10 +.B \-storefile \fIfile\fB +Save the BDD of the reachable states to \fIfile\fR. The BDD is stored at +the iteration specified by \fB\-store\fR. This option uses the format of +the \fIdddmp\fR library. Together with \fB\-loadfile\fR, it implements a +primitive checkpointing capability. It is primitive because the transition +relation is not saved; because the frontier states are not saved; and +because only one check point can be specified. +.TP 10 +.B \-store \fIn\fB +Save the BDD of the reached states at iteration \fIn\fR. This option +requires \fB\-storefile\fR. +.TP 10 +.B \-loadfile \fIfile\fB +Load the BDD of the initial states from \fIfile\fR. This option uses the +format of the \fIdddmp\fR library. Together with \fB\-storefile\fR, it +implements a primitive checkpointing capability. +.TP 10 +.B \-nobuild +do not build the BDDs. Quit after determining the initial variable +order. +.TP 10 +.B \-drop +drop BDDs for intermediate nodes as soon as possible. If this option is +not specified, the BDDs for the intermediate nodes of the circuit are +dropped just before the final reordering. +.TP 10 +.B \-delta +build BDDs only for the next state functions of a sequential circuit. +.TP 10 +.B \-node +build BDD only for \fInode\fR. +.TP 10 +.B \-order \fIfile\fB +read the variable order from \fIfile\fR. This file must contain the +names of the inputs (and present state variables) in the desired order. +Names must be separated by white space or newlines. +.TP 10 +.B \-ordering \fImethod\fB +use \fImethod\fR to derive an initial variable order. \fImethod\fR can +be one of \fIhw\fR, \fIdfs\fR. Method \fIhw\fR uses the order in which the +inputs are listed in the circuit description. +.TP 10 +.B \-autodyn +enable dynamic reordering. By default, dynamic reordering is disabled. +If enabled, the default method is sifting. +.TP 10 +.B \-first \fIn\fB +do first dynamic reordering when the BDDs reach \fIn\fR nodes. +The default value is 4004. (Don't ask why.) +.TP 10 +.B \-countdead +include dead nodes in node count when deciding whether to reorder +dynamically. By default, only live nodes are counted. +.TP 10 +.B \-growth \fIn\fB +maximum percentage by which the BDDs may grow while sifting one +variable. The default value is 20. +.TP 10 +.B \-automethod \fImethod\fB +use \fImethod\fR for dynamic reordering of the BDDs. \fImethod\fR can +be one of none, random, pivot, sifting, converge, symm, cosymm, group, +cogroup, win2, win3, win4, win2conv, win3conv, win4conv, annealing, +genetic, exact. The default method is sifting. +.TP 10 +.B \-reordering \fImethod\fB +use \fImethod\fR for the final reordering of the BDDs. \fImethod\fR can +be one of none, random, pivot, sifting, converge, symm, cosymm, group, +cogroup, win2, win3, win4, win2conv, win3conv, win4conv, annealing, +genetic, exact. The default method is none. +.TP 10 +.B \-genetic +run the genetic algorithm after the final reordering (which in this case +is no longer final). This allows the genetic algorithm to have one good +solution generated by, say, sifting, in the initial population. +.TP 10 +.B \-groupcheck \fImethod\fB +use \fImethod\fR for the the creation of groups in group sifting. +\fImethod\fR can be one of nocheck, check5, check7. Method check5 uses +extended symmetry as aggregation criterion; group7, in addition, also +uses the second difference criterion. The default value is check7. +.TP 10 +.B \-arcviolation \fIn\fB +percentage of arcs that violate the symmetry condition in the aggregation +check of group sifting. Should be between 0 and 100. The default value is +10. A larger value causes more aggregation. +.TP 10 +.B \-symmviolation \fIn\fB +percentage of nodes that violate the symmetry condition in the aggregation +check of group sifting. Should be between 0 and 100. The default value is +10. A larger value causes more aggregation. +.TP 10 +.B \-recomb \fIn\fB +threshold used in the second difference criterion for aggregation. (Used +by check7.) The default value is 0. A larger value causes more +aggregation. It can be either positive or negative. +.TP 10 +.B \-tree \fIfile\fB +read the variable group tree from \fIfile\fR. The format of this file is +a sequence of triplets: \fIlb ub flag\fR. Each triplet describes a +group: \fIlb\fR is the lowest index of the group; \fIub\fR is the +highest index of the group; \fIflag\fR can be either D (default) or F +(fixed). Fixed groups are not reordered. +.TP 10 +.B \-genepop \fIn\fB +size of the population for genetic algorithm. By default, the size of +the population is 3 times the number of variables, with a maximum of 120. +.TP 10 +.B \-genexover \fIn\fB +number of crossovers at each generation for the genetic algorithm. By +default, the number of crossovers is 3 times the number of variables, +with a maximum of 50. +.TP 10 +.B \-seed \fIn\fB +random number generator seed for the genetic algorithm and the random +and pivot reordering methods. +.TP 10 +.B \-progress +report progress when building the BDDs for a network. This option +causes the name of each primary output or next state function to be +printed after its BDD is built. It does not take effect if local BDDs +are requested. +.TP 10 +.B -p \fIn\fB +verbosity level. If negative, the program is very quiet. Larger values cause +more information to be printed. +.SH SEE ALSO +The documentation for the CUDD package explains the various +reordering methods. + +The documentation for the MTR package provides details on the variable +groups. + +dot(1) +.SH REFERENCES +F. Somenzi, +"Efficient Manipulation of Decision Diagrams," +Software Tools for Technology Transfer, +vol. 3, no. 2, pp. 171-181, 2001. + +S. Panda, F. Somenzi, and B. F. Plessier, +"Symmetry Detection and Dynamic Variable Ordering of Decision Diagrams," +IEEE International Conference on Computer-Aided Design, +pp. 628-631, November 1994. + +S. Panda and F. Somenzi, +"Who Are the Variables in Your Neighborhood," +IEEE International Conference on Computer-Aided Design, +pp. 74-77, November 1995. + +G. D. Hachtel and F. Somenzi, +"A Symbolic Algorithm for Maximum Flow in 0-1 Networks," +IEEE International Conference on Computer-Aided Design, +pp. 403-406, November 1993. +.SH AUTHOR +Fabio Somenzi, University of Colorado at Boulder. diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntr.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ntr.c new file mode 100644 index 000000000..3e07cd55b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntr.c @@ -0,0 +1,2988 @@ +/**CFile*********************************************************************** + + FileName [ntr.c] + + PackageName [ntr] + + Synopsis [A very simple reachability analysis program.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define NTR_MAX_DEP_SIZE 20 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: ntr.c,v 1.28 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +static const char *onames[] = { "T", "R" }; /* names of functions to be dumped */ +static double *signatures; /* signatures for all variables */ +static BnetNetwork *staticNet; /* pointer to network used by qsort + ** comparison function */ +static DdNode **staticPart; /* pointer to parts used by qsort + ** comparison function */ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * makecube (DdManager *dd, DdNode **x, int n); +static void ntrInitializeCount (BnetNetwork *net, NtrOptions *option); +static void ntrCountDFS (BnetNetwork *net, BnetNode *node); +static DdNode * ntrImage (DdManager *dd, NtrPartTR *TR, DdNode *from, NtrOptions *option); +static DdNode * ntrPreimage (DdManager *dd, NtrPartTR *T, DdNode *from); +static DdNode * ntrChooseFrom (DdManager *dd, DdNode *neW, DdNode *reached, NtrOptions *option); +static DdNode * ntrUpdateReached (DdManager *dd, DdNode *oldreached, DdNode *to); +static int ntrLatchDependencies (DdManager *dd, DdNode *reached, BnetNetwork *net, NtrOptions *option); +static NtrPartTR * ntrEliminateDependencies (DdManager *dd, NtrPartTR *TR, DdNode **states, NtrOptions *option); +static int ntrUpdateQuantificationSchedule (DdManager *dd, NtrPartTR *T); +static int ntrSignatureCompare (int * ptrX, int * ptrY); +static int ntrSignatureCompare2 (int * ptrX, int * ptrY); +static int ntrPartCompare (int * ptrX, int * ptrY); +static char ** ntrAllocMatrix (int nrows, int ncols); +static void ntrFreeMatrix (char **matrix); +static void ntrPermuteParts (DdNode **a, DdNode **b, int *comesFrom, int *goesTo, int size); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Builds DDs for a network outputs and next state + functions.] + + Description [Builds DDs for a network outputs and next state + functions. The method is really brain-dead, but it is very simple. + Returns 1 in case of success; 0 otherwise. Some inputs to the network + may be shared with another network whose DDs have already been built. + In this case we want to share the DDs as well.] + + SideEffects [the dd fields of the network nodes are modified. Uses the + count fields of the nodes.] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_buildDDs( + BnetNetwork * net /* network for which DDs are to be built */, + DdManager * dd /* DD manager */, + NtrOptions * option /* option structure */, + BnetNetwork * net2 /* companion network with which inputs may be shared */) +{ + int pr = option->verb; + int result; + int i; + BnetNode *node, *node2; + + /* If some inputs or present state variables are shared with + ** another network, we initialize their BDDs from that network. + */ + if (net2 != NULL) { + for (i = 0; i < net->npis; i++) { + if (!st_lookup(net->hash,net->inputs[i],&node)) { + return(0); + } + if (!st_lookup(net2->hash,net->inputs[i],&node2)) { + /* This input is not shared. */ + result = Bnet_BuildNodeBDD(dd,node,net->hash, + option->locGlob,option->nodrop); + if (result == 0) return(0); + } else { + if (node2->dd == NULL) return(0); + node->dd = node2->dd; + Cudd_Ref(node->dd); + node->var = node2->var; + node->active = node2->active; + } + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + return(0); + } + if (!st_lookup(net2->hash,net->latches[i][1],&node2)) { + /* This present state variable is not shared. */ + result = Bnet_BuildNodeBDD(dd,node,net->hash, + option->locGlob,option->nodrop); + if (result == 0) return(0); + } else { + if (node2->dd == NULL) return(0); + node->dd = node2->dd; + Cudd_Ref(node->dd); + node->var = node2->var; + node->active = node2->active; + } + } + } else { + /* First assign variables to inputs if the order is provided. + ** (Either in the .blif file or in an order file.) + */ + if (option->ordering == PI_PS_FROM_FILE) { + /* Follow order given in input file. First primary inputs + ** and then present state variables. + */ + for (i = 0; i < net->npis; i++) { + if (!st_lookup(net->hash,net->inputs[i],&node)) { + return(0); + } + result = Bnet_BuildNodeBDD(dd,node,net->hash, + option->locGlob,option->nodrop); + if (result == 0) return(0); + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + return(0); + } + result = Bnet_BuildNodeBDD(dd,node,net->hash, + option->locGlob,option->nodrop); + if (result == 0) return(0); + } + } else if (option->ordering == PI_PS_GIVEN) { + result = Bnet_ReadOrder(dd,option->orderPiPs,net,option->locGlob, + option->nodrop); + if (result == 0) return(0); + } else { + result = Bnet_DfsVariableOrder(dd,net); + if (result == 0) return(0); + } + } + /* At this point the BDDs of all primary inputs and present state + ** variables have been built. */ + + /* Currently noBuild doesn't do much. */ + if (option->noBuild == TRUE) + return(1); + + if (option->locGlob == BNET_LOCAL_DD) { + node = net->nodes; + while (node != NULL) { + result = Bnet_BuildNodeBDD(dd,node,net->hash,BNET_LOCAL_DD,TRUE); + if (result == 0) { + return(0); + } + if (pr > 2) { + (void) fprintf(stdout,"%s",node->name); + Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr); + } + node = node->next; + } + } else { /* option->locGlob == BNET_GLOBAL_DD */ + /* Create BDDs with DFS from the primary outputs and the next + ** state functions. If the inputs had not been ordered yet, + ** this would result in a DFS order for the variables. + */ + + ntrInitializeCount(net,option); + + if (option->node != NULL && + option->closestCube == FALSE && option->dontcares == FALSE) { + if (!st_lookup(net->hash,option->node,&node)) { + return(0); + } + result = Bnet_BuildNodeBDD(dd,node,net->hash,BNET_GLOBAL_DD, + option->nodrop); + if (result == 0) return(0); + } else { + if (option->stateOnly == FALSE) { + for (i = 0; i < net->npos; i++) { + if (!st_lookup(net->hash,net->outputs[i],&node)) { + continue; + } + result = Bnet_BuildNodeBDD(dd,node,net->hash, + BNET_GLOBAL_DD,option->nodrop); + if (result == 0) return(0); + if (option->progress) { + (void) fprintf(stdout,"%s\n",node->name); + } +#if 0 + Cudd_PrintDebug(dd,node->dd,net->ninputs,option->verb); +#endif + } + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][0],&node)) { + continue; + } + result = Bnet_BuildNodeBDD(dd,node,net->hash,BNET_GLOBAL_DD, + option->nodrop); + if (result == 0) return(0); + if (option->progress) { + (void) fprintf(stdout,"%s\n",node->name); + } +#if 0 + Cudd_PrintDebug(dd,node->dd,net->ninputs,option->verb); +#endif + } + } + /* Make sure all inputs have a DD and dereference the DDs of + ** the nodes that are not reachable from the outputs. + */ + for (i = 0; i < net->npis; i++) { + if (!st_lookup(net->hash,net->inputs[i],&node)) { + return(0); + } + result = Bnet_BuildNodeBDD(dd,node,net->hash,BNET_GLOBAL_DD, + option->nodrop); + if (result == 0) return(0); + if (node->count == -1) Cudd_RecursiveDeref(dd,node->dd); + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + return(0); + } + result = Bnet_BuildNodeBDD(dd,node,net->hash,BNET_GLOBAL_DD, + option->nodrop); + if (result == 0) return(0); + if (node->count == -1) Cudd_RecursiveDeref(dd,node->dd); + } + + /* Dispose of the BDDs of the internal nodes if they have not + ** been dropped already. + */ + if (option->nodrop == TRUE) { + for (node = net->nodes; node != NULL; node = node->next) { + if (node->dd != NULL && node->count != -1 && + (node->type == BNET_INTERNAL_NODE || + node->type == BNET_INPUT_NODE || + node->type == BNET_PRESENT_STATE_NODE)) { + Cudd_RecursiveDeref(dd,node->dd); + if (node->type == BNET_INTERNAL_NODE) node->dd = NULL; + } + } + } + } + + return(1); + +} /* end of buildDD */ + + +/**Function******************************************************************** + + Synopsis [Builds the transition relation for a network.] + + Description [Builds the transition relation for a network. Returns a + pointer to the transition relation structure if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +NtrPartTR * +Ntr_buildTR( + DdManager * dd /* manager */, + BnetNetwork * net /* network */, + NtrOptions * option /* options */, + int image /* image type: monolithic ... */) +{ + NtrPartTR *TR; + DdNode *T, *delta, *support, *scan, *tmp, *preiabs, *prepabs; + DdNode **part, **absicubes, **abspcubes, **nscube, *mnscube; + DdNode **x, **y; + DdNode **pi; + int i; + int xlevel; + BnetNode *node; + int *schedule; + int depth = 0; + + /* Initialize transition relation structure. */ + TR = ALLOC(NtrPartTR,1); + if (TR == NULL) goto endgame; + TR->nlatches = net->nlatches; + if (image == NTR_IMAGE_MONO) { + TR->nparts = 1; + } else if (image == NTR_IMAGE_PART || image == NTR_IMAGE_CLIP || + image == NTR_IMAGE_DEPEND) { + TR->nparts = net->nlatches; + } else { + (void) fprintf(stderr,"Unrecognized image method (%d). Using part.\n", + image); + TR->nparts = net->nlatches; + } + TR->factors = Ntr_InitHeap(TR->nlatches); + if (TR->factors == NULL) goto endgame; + /* Allocate arrays for present state and next state variables. */ + TR->x = x = ALLOC(DdNode *,TR->nlatches); + if (x == NULL) goto endgame; + TR->y = y = ALLOC(DdNode *,TR->nlatches); + if (y == NULL) goto endgame; + /* Allocate array for primary input variables. */ + pi = ALLOC(DdNode *,net->npis); + if (pi == NULL) goto endgame; + /* Allocate array for partitioned transition relation. */ + part = ALLOC(DdNode *,net->nlatches); + if (part == NULL) goto endgame; + /* Allocate array of next state cubes. */ + nscube = ALLOC(DdNode *,net->nlatches); + if (nscube == NULL) goto endgame; + /* Allocate array for quantification schedule and initialize it. */ + schedule = ALLOC(int,Cudd_ReadSize(dd)); + if (schedule == NULL) goto endgame; + for (i = 0; i < Cudd_ReadSize(dd); i++) { + schedule[i] = -1; + } + + /* Create partitioned transition relation from network. */ + TR->xw = Cudd_ReadOne(dd); + Cudd_Ref(TR->xw); + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + goto endgame; + } + x[i] = node->dd; + Cudd_Ref(x[i]); + /* Add present state variable to cube TR->xw. */ + tmp = Cudd_bddAnd(dd,TR->xw,x[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,TR->xw); + TR->xw = tmp; + /* Create new y variable immediately above the x variable. */ + xlevel = Cudd_ReadPerm(dd,x[i]->index); + y[i] = Cudd_bddNewVarAtLevel(dd,xlevel); + Cudd_Ref(y[i]); + /* Initialize cube of next state variables for this part. */ + nscube[i] = y[i]; + Cudd_Ref(nscube[i]); + /* Group present and next state variable if so requested. */ + if (option->groupnsps != NTR_GROUP_NONE) { + int method = option->groupnsps == NTR_GROUP_DEFAULT ? + MTR_DEFAULT : MTR_FIXED; + if (Cudd_MakeTreeNode(dd,y[i]->index,2,method) == NULL) + goto endgame; + } + /* Get next state function and create transition relation part. */ + if (!st_lookup(net->hash,net->latches[i][0],&node)) { + goto endgame; + } + delta = node->dd; + if (image != NTR_IMAGE_DEPEND) { + part[i] = Cudd_bddXnor(dd,delta,y[i]); + if (part[i] == NULL) goto endgame; + } else { + part[i] = delta; + } + Cudd_Ref(part[i]); + /* Collect scheduling info for this delta. At the end of this loop + ** schedule[i] == j means that the variable of index i does not + ** appear in any part with index greater than j, unless j == -1, + ** in which case the variable appears in no part. + */ + support = Cudd_Support(dd,delta); + Cudd_Ref(support); + scan = support; + while (!Cudd_IsConstant(scan)) { + schedule[scan->index] = i; + scan = Cudd_T(scan); + } + Cudd_RecursiveDeref(dd,support); + } + + /* Collect primary inputs. */ + for (i = 0; i < net->npis; i++) { + if (!st_lookup(net->hash,net->inputs[i],&node)) { + goto endgame; + } + pi[i] = node->dd; + tmp = Cudd_bddAnd(dd,TR->xw,pi[i]); + if (tmp == NULL) goto endgame; Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,TR->xw); + TR->xw = tmp; + } + + /* Build abstraction cubes. First primary input variables that go + ** in the abstraction cubes for both monolithic and partitioned + ** transition relations. */ + absicubes = ALLOC(DdNode *, net->nlatches); + if (absicubes == NULL) goto endgame; + abspcubes = ALLOC(DdNode *, net->nlatches); + if (abspcubes == NULL) goto endgame; + + for (i = 0; i < net->nlatches; i++) { + absicubes[i] = Cudd_ReadOne(dd); + Cudd_Ref(absicubes[i]); + } + preiabs = Cudd_ReadOne(dd); + Cudd_Ref(preiabs); + + for (i = 0; i < net->npis; i++) { + int j = pi[i]->index; + int k = schedule[j]; + if (k >= 0) { + tmp = Cudd_bddAnd(dd,absicubes[k],pi[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,absicubes[k]); + absicubes[k] = tmp; + } else { + tmp = Cudd_bddAnd(dd,preiabs,pi[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,preiabs); + preiabs = tmp; + } + } + FREE(pi); + + /* Build preimage abstraction cubes from image abstraction cubes. */ + for (i = 0; i < net->nlatches; i++) { + abspcubes[i] = Cudd_bddAnd(dd,absicubes[i],nscube[i]); + if (abspcubes[i] == NULL) return(NULL); + Cudd_Ref(abspcubes[i]); + } + Cudd_Ref(prepabs = preiabs); + + /* For partitioned transition relations we add present state variables + ** to the image abstraction cubes. */ + if (image != NTR_IMAGE_MONO) { + for (i = 0; i < net->nlatches; i++) { + int j = x[i]->index; + int k = schedule[j]; + if (k >= 0) { + tmp = Cudd_bddAnd(dd,absicubes[k],x[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,absicubes[k]); + absicubes[k] = tmp; + } else { + tmp = Cudd_bddAnd(dd,preiabs,x[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,preiabs); + preiabs = tmp; + } + } + } + FREE(schedule); + + if (image != NTR_IMAGE_MONO) { + TR->part = part; + TR->icube = absicubes; + TR->pcube = abspcubes; + TR->nscube = nscube; + TR->preiabs = preiabs; + TR->prepabs = prepabs; + return(TR); + } + + /* Here we are building a monolithic TR. */ + + /* Reinitialize the cube of variables to be quantified before + ** image computation. */ + Cudd_RecursiveDeref(dd,preiabs); + preiabs = Cudd_ReadOne(dd); + Cudd_Ref(preiabs); + + if (option->imageClip != 1.0) { + depth = (int) ((double) Cudd_ReadSize(dd) * option->imageClip); + } + + /* Collapse transition relation. */ + T = Cudd_ReadOne(dd); + Cudd_Ref(T); + mnscube = Cudd_ReadOne(dd); + Cudd_Ref(mnscube); + for (i = 0; i < net->nlatches; i++) { + /* Eliminate the primary inputs that do not appear in other parts. */ + if (depth != 0) { + tmp = Cudd_bddClippingAndAbstract(dd,T,part[i],absicubes[i], + depth,option->approx); + } else { + tmp = Cudd_bddAndAbstract(dd,T,part[i],absicubes[i]); + } + Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,part[i]); + Cudd_RecursiveDeref(dd,absicubes[i]); + Cudd_RecursiveDeref(dd,abspcubes[i]); + if (option->threshold >= 0) { + if (option->approx) { + T = Cudd_RemapOverApprox(dd,tmp,2*net->nlatches, + option->threshold,option->quality); + } else { + T = Cudd_RemapUnderApprox(dd,tmp,2*net->nlatches, + option->threshold,option->quality); + } + } else { + T = tmp; + } + if (T == NULL) return(NULL); + Cudd_Ref(T); + Cudd_RecursiveDeref(dd,tmp); + /* Add the next state variables of this part to the cube of all + ** next state variables. */ + tmp = Cudd_bddAnd(dd,mnscube,nscube[i]); + if (tmp == NULL) return(NULL); + Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,mnscube); + mnscube = tmp; + Cudd_RecursiveDeref(dd,nscube[i]); + (void) printf("@"); fflush(stdout); + } + (void) printf("\n"); +#if 0 + (void) printf("T"); Cudd_PrintDebug(dd,T,2*net->nlatches,2); +#endif + + /* Clean up. */ + FREE(absicubes); + FREE(abspcubes); + FREE(part); + FREE(nscube); + + TR->part = part = ALLOC(DdNode *,1); + if (part == NULL) goto endgame; + part[0] = T; + + /* Build cube of x (present state) variables for abstraction. */ + TR->icube = absicubes = ALLOC(DdNode *,1); + if (absicubes == NULL) goto endgame; + absicubes[0] = makecube(dd,x,TR->nlatches); + if (absicubes[0] == NULL) return(0); + Cudd_Ref(absicubes[0]); + /* Build cube of y (next state) variables for abstraction. */ + TR->pcube = abspcubes = ALLOC(DdNode *,1); + if (abspcubes == NULL) goto endgame; + abspcubes[0] = makecube(dd,y,TR->nlatches); + if (abspcubes[0] == NULL) return(0); + Cudd_Ref(abspcubes[0]); + TR->preiabs = preiabs; + TR->prepabs = prepabs; + + TR->nscube = ALLOC(DdNode *,1); + if (TR->nscube == NULL) return(NULL); + TR->nscube[0] = mnscube; + + return(TR); + +endgame: + + return(NULL); + +} /* end of Ntr_buildTR */ + + +/**Function******************************************************************** + + Synopsis [Frees the transition relation for a network.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Ntr_freeTR( + DdManager * dd, + NtrPartTR * TR) +{ + int i; + for (i = 0; i < TR->nlatches; i++) { + Cudd_RecursiveDeref(dd,TR->x[i]); + Cudd_RecursiveDeref(dd,TR->y[i]); + } + FREE(TR->x); + FREE(TR->y); + for (i = 0; i < TR->nparts; i++) { + Cudd_RecursiveDeref(dd,TR->part[i]); + Cudd_RecursiveDeref(dd,TR->icube[i]); + Cudd_RecursiveDeref(dd,TR->pcube[i]); + Cudd_RecursiveDeref(dd,TR->nscube[i]); + } + FREE(TR->part); + FREE(TR->icube); + FREE(TR->pcube); + FREE(TR->nscube); + Cudd_RecursiveDeref(dd,TR->preiabs); + Cudd_RecursiveDeref(dd,TR->prepabs); + Cudd_RecursiveDeref(dd,TR->xw); + for (i = 0; i < TR->factors->nslots; i++) { + Cudd_RecursiveDeref(dd, (DdNode *) TR->factors->slots[i].item); + } + Ntr_FreeHeap(TR->factors); + FREE(TR); + + return; + +} /* end of Ntr_freeTR */ + + +/**Function******************************************************************** + + Synopsis [Makes a copy of a transition relation.] + + Description [Makes a copy of a transition relation. Returns a pointer + to the copy if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_buildTR Ntr_freeTR] + +******************************************************************************/ +NtrPartTR * +Ntr_cloneTR( + NtrPartTR *TR) +{ + NtrPartTR *T; + int nparts, nlatches, i; + + T = ALLOC(NtrPartTR,1); + if (T == NULL) return(NULL); + nparts = T->nparts = TR->nparts; + nlatches = T->nlatches = TR->nlatches; + T->part = ALLOC(DdNode *,nparts); + if (T->part == NULL) { + FREE(T); + return(NULL); + } + T->icube = ALLOC(DdNode *,nparts); + if (T->icube == NULL) { + FREE(T->part); + FREE(T); + return(NULL); + } + T->pcube = ALLOC(DdNode *,nparts); + if (T->pcube == NULL) { + FREE(T->icube); + FREE(T->part); + FREE(T); + return(NULL); + } + T->x = ALLOC(DdNode *,nlatches); + if (T->x == NULL) { + FREE(T->pcube); + FREE(T->icube); + FREE(T->part); + FREE(T); + return(NULL); + } + T->y = ALLOC(DdNode *,nlatches); + if (T->y == NULL) { + FREE(T->x); + FREE(T->pcube); + FREE(T->icube); + FREE(T->part); + FREE(T); + return(NULL); + } + T->nscube = ALLOC(DdNode *,nparts); + if (T->nscube == NULL) { + FREE(T->y); + FREE(T->x); + FREE(T->pcube); + FREE(T->icube); + FREE(T->part); + FREE(T); + return(NULL); + } + T->factors = Ntr_HeapClone(TR->factors); + if (T->factors == NULL) { + FREE(T->nscube); + FREE(T->y); + FREE(T->x); + FREE(T->pcube); + FREE(T->icube); + FREE(T->part); + FREE(T); + return(NULL); + } + for (i = 0; i < T->factors->nslots; i++) { + Cudd_Ref((DdNode *) T->factors->slots[i].item); + } + for (i = 0; i < nparts; i++) { + T->part[i] = TR->part[i]; + Cudd_Ref(T->part[i]); + T->icube[i] = TR->icube[i]; + Cudd_Ref(T->icube[i]); + T->pcube[i] = TR->pcube[i]; + Cudd_Ref(T->pcube[i]); + T->nscube[i] = TR->nscube[i]; + Cudd_Ref(T->nscube[i]); + } + T->preiabs = TR->preiabs; + Cudd_Ref(T->preiabs); + T->prepabs = TR->prepabs; + Cudd_Ref(T->prepabs); + T->xw = TR->xw; + Cudd_Ref(T->xw); + for (i = 0; i < nlatches; i++) { + T->x[i] = TR->x[i]; + Cudd_Ref(T->x[i]); + T->y[i] = TR->y[i]; + Cudd_Ref(T->y[i]); + } + + return(T); + +} /* end of Ntr_cloneTR */ + + +/**Function******************************************************************** + + Synopsis [Poor man's traversal procedure.] + + Description [Poor man's traversal procedure. based on the monolithic + transition relation. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_ClosureTrav] + +******************************************************************************/ +int +Ntr_Trav( + DdManager * dd /* DD manager */, + BnetNetwork * net /* network */, + NtrOptions * option /* options */) +{ + NtrPartTR *TR; /* Transition relation */ + DdNode *init; /* initial state(s) */ + DdNode *from; + DdNode *to; + DdNode *reached; + DdNode *neW; + DdNode *one, *zero; + int depth; + int retval; + int pr = option->verb; + int initReord = Cudd_ReadReorderings(dd); + + if (option->traverse == FALSE || net->nlatches == 0) return(1); + (void) printf("Building transition relation. Time = %s\n", + util_print_time(util_cpu_time() - option->initialTime)); + one = Cudd_ReadOne(dd); + zero = Cudd_Not(one); + + /* Build transition relation and initial states. */ + TR = Ntr_buildTR(dd,net,option,option->image); + if (TR == NULL) return(0); + retval = Cudd_SetVarMap(dd,TR->x,TR->y,TR->nlatches); + (void) printf("Transition relation: %d parts %d latches %d nodes\n", + TR->nparts, TR->nlatches, + Cudd_SharingSize(TR->part, TR->nparts)); + (void) printf("Traversing. Time = %s\n", + util_print_time(util_cpu_time() - option->initialTime)); + init = Ntr_initState(dd,net,option); + if (init == NULL) return(0); + + /* Initialize From. */ + Cudd_Ref(from = init); + (void) printf("S0"); Cudd_PrintDebug(dd,from,TR->nlatches,pr); + + /* Initialize Reached. */ + Cudd_Ref(reached = from); + + /* Start traversal. */ + for (depth = 0; ; depth++) { + /* Image computation. */ + to = ntrImage(dd,TR,from,option); + if (to == NULL) { + Cudd_RecursiveDeref(dd,reached); + Cudd_RecursiveDeref(dd,from); + return(0); + } + Cudd_RecursiveDeref(dd,from); + + /* Find new states. */ + neW = Cudd_bddAnd(dd,to,Cudd_Not(reached)); + if (neW == NULL) { + Cudd_RecursiveDeref(dd,reached); + Cudd_RecursiveDeref(dd,to); + return(0); + } + Cudd_Ref(neW); + Cudd_RecursiveDeref(dd,to); + + /* Check for convergence. */ + if (neW == zero) break; + + /* Dump current reached states if requested. */ + if (option->store == depth) { + int ok = Dddmp_cuddBddStore(dd, NULL, reached, NULL, + NULL, DDDMP_MODE_TEXT, DDDMP_VARIDS, + option->storefile, NULL); + if (ok == 0) return(0); + (void) printf("Storing reached in %s after %i iterations.\n", + option->storefile, depth); + break; + } + + /* Update reached. */ + reached = ntrUpdateReached(dd,reached,neW); + if (reached == NULL) { + Cudd_RecursiveDeref(dd,neW); + return(0); + } + + /* Prepare for new iteration. */ + from = ntrChooseFrom(dd,neW,reached,option); + if (from == NULL) { + Cudd_RecursiveDeref(dd,reached); + Cudd_RecursiveDeref(dd,neW); + return(0); + } + Cudd_RecursiveDeref(dd,neW); + (void) printf("From[%d]",depth+1); + Cudd_PrintDebug(dd,from,TR->nlatches,pr); + (void) printf("Reached[%d]",depth+1); + Cudd_PrintDebug(dd,reached,TR->nlatches,pr); + if (pr > 0) { + if (!Cudd_ApaPrintMinterm(stdout, dd, reached, TR->nlatches)) + return(0); + if (!Cudd_ApaPrintMintermExp(stdout, dd, reached, TR->nlatches, 6)) + return(0); + } else { + (void) printf("\n"); + } + } + + /* Print out result. */ + (void) printf("depth = %d\n", depth); + (void) printf("R"); Cudd_PrintDebug(dd,reached,TR->nlatches,pr); + + /* Dump to file if requested. */ + if (option->bdddump) { + DdNode *dfunc[2]; /* addresses of the functions to be dumped */ + char *onames[2]; /* names of the functions to be dumped */ + dfunc[0] = TR->part[0]; onames[0] = (char *) "T"; + dfunc[1] = reached; onames[1] = (char *) "R"; + retval = Bnet_bddArrayDump(dd, net, option->dumpfile, dfunc, + onames, 2, option->dumpFmt); + if (retval == 0) return(0); + } + + if (option->depend) { + retval = ntrLatchDependencies(dd, reached, net, option); + if (retval == -1) return(0); + (void) printf("%d latches are redundant\n", retval); + } + /* Clean up. */ + Cudd_RecursiveDeref(dd,reached); + Cudd_RecursiveDeref(dd,neW); + Cudd_RecursiveDeref(dd,init); + Ntr_freeTR(dd,TR); + + if (Cudd_ReadReorderings(dd) > initReord) { + (void) printf("Order at the end of reachability analysis\n"); + retval = Bnet_PrintOrder(net,dd); + if (retval == 0) return(0); + } + return(1); + +} /* end of Ntr_Trav */ + + +/**Function******************************************************************** + + Synopsis [Computes the SCCs of the STG.] + + Description [Computes the strongly connected components of the state + transition graph. Only the first 10 SCCs are computed. Returns 1 in + case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_Trav] + +******************************************************************************/ +int +Ntr_SCC( + DdManager * dd /* DD manager */, + BnetNetwork * net /* network */, + NtrOptions * option /* options */) +{ + NtrPartTR *TR; /* Transition relation */ + DdNode *init; /* initial state(s) */ + DdNode *from; + DdNode *to; + DdNode *reached, *reaching; + DdNode *neW; + DdNode *one, *zero; + DdNode *states, *scc; + DdNode *tmp; + DdNode *SCCs[10]; + int depth; + int nscc = 0; + int retval; + int pr = option->verb; + int i; + + if (option->scc == FALSE || net->nlatches == 0) return(1); + (void) printf("Building transition relation. Time = %s\n", + util_print_time(util_cpu_time() - option->initialTime)); + one = Cudd_ReadOne(dd); + zero = Cudd_Not(one); + + /* Build transition relation and initial states. */ + TR = Ntr_buildTR(dd,net,option,option->image); + if (TR == NULL) return(0); + retval = Cudd_SetVarMap(dd,TR->x,TR->y,TR->nlatches); + (void) printf("Transition relation: %d parts %d latches %d nodes\n", + TR->nparts, TR->nlatches, + Cudd_SharingSize(TR->part, TR->nparts)); + (void) printf("Computing SCCs. Time = %s\n", + util_print_time(util_cpu_time() - option->initialTime)); + + /* Consider all SCCs, including those not reachable. */ + states = one; + Cudd_Ref(states); + + while (states != zero) { + if (nscc == 0) { + tmp = Ntr_initState(dd,net,option); + if (tmp == NULL) return(0); + init = Cudd_bddPickOneMinterm(dd,tmp,TR->x,TR->nlatches); + } else { + init = Cudd_bddPickOneMinterm(dd,states,TR->x,TR->nlatches); + } + if (init == NULL) return(0); + Cudd_Ref(init); + if (nscc == 0) { + Cudd_RecursiveDeref(dd,tmp); + } + /* Initialize From. */ + Cudd_Ref(from = init); + (void) printf("S0"); Cudd_PrintDebug(dd,from,TR->nlatches,pr); + + /* Initialize Reached. */ + Cudd_Ref(reached = from); + + /* Start forward traversal. */ + for (depth = 0; ; depth++) { + /* Image computation. */ + to = ntrImage(dd,TR,from,option); + if (to == NULL) { + return(0); + } + Cudd_RecursiveDeref(dd,from); + + /* Find new states. */ + tmp = Cudd_bddAnd(dd,to,states); + if (tmp == NULL) return(0); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,to); + neW = Cudd_bddAnd(dd,tmp,Cudd_Not(reached)); + if (neW == NULL) return(0); Cudd_Ref(neW); + Cudd_RecursiveDeref(dd,tmp); + + /* Check for convergence. */ + if (neW == zero) break; + + /* Update reached. */ + reached = ntrUpdateReached(dd,reached,neW); + if (reached == NULL) { + return(0); + } + + /* Prepare for new iteration. */ + from = ntrChooseFrom(dd,neW,reached,option); + if (from == NULL) { + return(0); + } + Cudd_RecursiveDeref(dd,neW); + (void) printf("From[%d]",depth+1); + Cudd_PrintDebug(dd,from,TR->nlatches,pr); + (void) printf("Reached[%d]",depth+1); + Cudd_PrintDebug(dd,reached,TR->nlatches,pr); + if (pr <= 0) { + (void) printf("\n"); + } + } + Cudd_RecursiveDeref(dd,neW); + + /* Express reached in terms of y variables. This allows us to + ** efficiently test for termination during the backward traversal. */ + tmp = Cudd_bddVarMap(dd,reached); + if (tmp == NULL) return(0); + Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,reached); + reached = tmp; + + /* Initialize from and reaching. */ + from = Cudd_bddVarMap(dd,init); + Cudd_Ref(from); + (void) printf("S0"); Cudd_PrintDebug(dd,from,TR->nlatches,pr); + Cudd_Ref(reaching = from); + + /* Start backward traversal. */ + for (depth = 0; ; depth++) { + /* Preimage computation. */ + to = ntrPreimage(dd,TR,from); + if (to == NULL) { + return(0); + } + Cudd_RecursiveDeref(dd,from); + + /* Find new states. */ + tmp = Cudd_bddAnd(dd,to,reached); + if (tmp == NULL) return(0); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,to); + neW = Cudd_bddAnd(dd,tmp,Cudd_Not(reaching)); + if (neW == NULL) return(0); Cudd_Ref(neW); + Cudd_RecursiveDeref(dd,tmp); + + /* Check for convergence. */ + if (neW == zero) break; + + /* Update reaching. */ + reaching = ntrUpdateReached(dd,reaching,neW); + if (reaching == NULL) { + return(0); + } + + /* Prepare for new iteration. */ + from = ntrChooseFrom(dd,neW,reaching,option); + if (from == NULL) { + return(0); + } + Cudd_RecursiveDeref(dd,neW); + (void) printf("From[%d]",depth+1); + Cudd_PrintDebug(dd,from,TR->nlatches,pr); + (void) printf("Reaching[%d]",depth+1); + Cudd_PrintDebug(dd,reaching,TR->nlatches,pr); + if (pr <= 0) { + (void) printf("\n"); + } + } + + scc = Cudd_bddAnd(dd,reached,reaching); + if (scc == NULL) { + return(0); + } + Cudd_Ref(scc); + SCCs[nscc] = Cudd_bddVarMap(dd,scc); + if (SCCs[nscc] == NULL) return(0); + Cudd_Ref(SCCs[nscc]); + Cudd_RecursiveDeref(dd,scc); + /* Print out result. */ + (void) printf("SCC[%d]",nscc); + Cudd_PrintDebug(dd,SCCs[nscc],TR->nlatches,pr); + tmp = Cudd_bddAnd(dd,states,Cudd_Not(SCCs[nscc])); + if (tmp == NULL) { + return(0); + } + Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,states); + states = tmp; + Cudd_RecursiveDeref(dd,reached); + Cudd_RecursiveDeref(dd,reaching); + Cudd_RecursiveDeref(dd,neW); + Cudd_RecursiveDeref(dd,init); + nscc++; + if (nscc > 9) break; + } + + if (states != zero) { + (void) fprintf(stdout,"More than 10 SCCs. Only the first 10 are computed.\n"); + } + + /* Dump to file if requested. */ + if (option->bdddump) { + char *sccnames[10]; /* names of the SCCs */ + sccnames[0] = (char *) "SCC0"; + sccnames[1] = (char *) "SCC1"; + sccnames[2] = (char *) "SCC2"; + sccnames[3] = (char *) "SCC3"; + sccnames[4] = (char *) "SCC4"; + sccnames[5] = (char *) "SCC5"; + sccnames[6] = (char *) "SCC6"; + sccnames[7] = (char *) "SCC7"; + sccnames[8] = (char *) "SCC8"; + sccnames[9] = (char *) "SCC9"; + retval = Bnet_bddArrayDump(dd, net, option->dumpfile, SCCs, + sccnames, nscc, option->dumpFmt); + if (retval == 0) return(0); + } + + /* Verify that the SCCs form a partition of the universe. */ + scc = zero; + Cudd_Ref(scc); + for (i = 0; i < nscc; i++) { + assert(Cudd_bddLeq(dd,SCCs[i],Cudd_Not(scc))); + tmp = Cudd_bddOr(dd,SCCs[i],scc); + if (tmp == NULL) return(0); + Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,scc); + scc = tmp; + Cudd_RecursiveDeref(dd,SCCs[i]); + } + assert(scc == Cudd_Not(states)); + + /* Clean up. */ + Cudd_RecursiveDeref(dd,scc); + Cudd_RecursiveDeref(dd,states); + Ntr_freeTR(dd,TR); + + return(1); + +} /* end of Ntr_SCC */ + + +/**Function******************************************************************** + + Synopsis [Transitive closure traversal procedure.] + + Description [Traversal procedure. based on the transitive closure of the + transition relation. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_Trav] + +******************************************************************************/ +int +Ntr_ClosureTrav( + DdManager * dd /* DD manager */, + BnetNetwork * net /* network */, + NtrOptions * option /* options */) +{ + DdNode *init; + DdNode *T; + NtrPartTR *TR; + int retval; + int pr = option->verb; /* verbosity level */ + DdNode *dfunc[2]; /* addresses of the functions to be dumped */ + char *onames[2]; /* names of the functions to be dumped */ + DdNode *reached, *reachedy, *reachedx; + + /* Traverse if requested and if the circuit is sequential. */ + if (option->closure == FALSE || net->nlatches == 0) return(1); + + TR = Ntr_buildTR(dd,net,option,NTR_IMAGE_MONO); + if (TR == NULL) return(0); + (void) printf("TR"); Cudd_PrintDebug(dd,TR->part[0],2*TR->nlatches,pr); + T = Ntr_TransitiveClosure(dd,TR,option); + if (T == NULL) return(0); + Cudd_Ref(T); + (void) printf("TC"); Cudd_PrintDebug(dd,T,2*TR->nlatches,pr); + + init = Ntr_initState(dd,net,option); + if (init == NULL) return(0); + (void) printf("S0"); Cudd_PrintDebug(dd,init,TR->nlatches,pr); + + /* Image computation. */ + if (option->closureClip != 1.0) { + int depth = (int) ((double) Cudd_ReadSize(dd) * option->closureClip); + reachedy = Cudd_bddClippingAndAbstract(dd,T,init,TR->icube[0], + depth,option->approx); + } else { + reachedy = Cudd_bddAndAbstract(dd,T,init,TR->icube[0]); + } + if (reachedy == NULL) return(0); + Cudd_Ref(reachedy); + + /* Express in terms of present state variables. */ + reachedx = Cudd_bddSwapVariables(dd,reachedy,TR->x,TR->y,TR->nlatches); + if (reachedx == NULL) return(0); + Cudd_Ref(reachedx); + Cudd_RecursiveDeref(dd,reachedy); + + /* Add initial state. */ + reached = Cudd_bddOr(dd,reachedx,init); + if (reached == NULL) return(0); + Cudd_Ref(reached); + Cudd_RecursiveDeref(dd,reachedx); + + /* Print out result. */ + (void) printf("R"); Cudd_PrintDebug(dd,reached,TR->nlatches,pr); + + /* Dump to file if requested. */ + if (option->bdddump) { + dfunc[0] = T; onames[0] = (char *) "TC"; + dfunc[1] = reached; onames[1] = (char *) "R"; + retval = Bnet_bddArrayDump(dd, net, option->dumpfile, dfunc, + onames, 2, option->dumpFmt); + if (retval == 0) return(0); + } + + /* Clean up. */ + Cudd_RecursiveDeref(dd,reached); + Cudd_RecursiveDeref(dd,init); + Cudd_RecursiveDeref(dd,T); + Ntr_freeTR(dd,TR); + + return(1); + +} /* end of Ntr_ClosureTrav */ + + +/**Function******************************************************************** + + Synopsis [Builds the transitive closure of a transition relation.] + + Description [Builds the transitive closure of a transition relation. + Returns a BDD if successful; NULL otherwise. Uses a simple squaring + algorithm.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Ntr_TransitiveClosure( + DdManager * dd, + NtrPartTR * TR, + NtrOptions * option) +{ + DdNode *T,*oldT,*Txz,*Tzy,*Tred,*square,*zcube; + DdNode **z; + int i; + int depth = 0; + int ylevel; + int done; + + if (option->image != NTR_IMAGE_MONO) return(NULL); + + /* Create array of auxiliary variables. */ + z = ALLOC(DdNode *,TR->nlatches); + if (z == NULL) + return(NULL); + for (i = 0; i < TR->nlatches; i++) { + ylevel = Cudd_ReadIndex(dd,TR->y[i]->index); + z[i] = Cudd_bddNewVarAtLevel(dd,ylevel); + if (z[i] == NULL) + return(NULL); + } + /* Build cube of auxiliary variables. */ + zcube = makecube(dd,z,TR->nlatches); + if (zcube == NULL) return(NULL); + Cudd_Ref(zcube); + + if (option->closureClip != 1.0) { + depth = (int) ((double) Cudd_ReadSize(dd) * option->imageClip); + } + + T = TR->part[0]; + Cudd_Ref(T); + for (i = 0; ; i++) { + if (option->threshold >= 0) { + if (option->approx) { + Tred = Cudd_RemapOverApprox(dd,T,TR->nlatches*2, + option->threshold, + option->quality); + } else { + Tred = Cudd_RemapUnderApprox(dd,T,TR->nlatches*2, + option->threshold, + option->quality); + } + } else { + Tred = T; + } + if (Tred == NULL) return(NULL); + Cudd_Ref(Tred); + /* Express T in terms of z and y variables. */ + Tzy = Cudd_bddSwapVariables(dd,Tred,TR->x,z,TR->nlatches); + if (Tzy == NULL) return(NULL); + Cudd_Ref(Tzy); + /* Express T in terms of x and z variables. */ + Txz = Cudd_bddSwapVariables(dd,Tred,TR->y,z,TR->nlatches); + if (Txz == NULL) return(NULL); + Cudd_Ref(Txz); + Cudd_RecursiveDeref(dd,Tred); + /* Square */ + if (depth == 0) { + square = Cudd_bddAndAbstract(dd,Txz,Tzy,zcube); + } else { + square = Cudd_bddClippingAndAbstract(dd,Txz,Tzy,zcube,depth, + option->approx); + } + if (square == NULL) return(NULL); + Cudd_Ref(square); + Cudd_RecursiveDeref(dd,Tzy); + Cudd_RecursiveDeref(dd,Txz); + oldT = T; + T = Cudd_bddOr(dd,square,TR->part[0]); + if (T == NULL) return(NULL); + Cudd_Ref(T); + Cudd_RecursiveDeref(dd,square); + done = T == oldT; + Cudd_RecursiveDeref(dd,oldT); + if (done) break; + (void) fprintf(stdout,"@"); fflush(stdout); + } + (void) fprintf(stdout, "\n"); + + Cudd_RecursiveDeref(dd,zcube); + Cudd_Deref(T); + FREE(z); + return(T); + +} /* end of Ntr_TransitiveClosure */ + + +/**Function******************************************************************** + + Synopsis [Builds the BDD of the initial state(s).] + + Description [Builds the BDD of the initial state(s). Returns a BDD + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Ntr_initState( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + DdNode *res, *x, *w, *one; + BnetNode *node; + int i; + + if (option->load) { + res = Dddmp_cuddBddLoad(dd, DDDMP_VAR_MATCHIDS, NULL, NULL, NULL, + DDDMP_MODE_DEFAULT, option->loadfile, NULL); + } else { + one = Cudd_ReadOne(dd); + Cudd_Ref(res = one); + + if (net->nlatches == 0) return(res); + + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + goto endgame; + } + x = node->dd; + switch (net->latches[i][2][0]) { + case '0': + w = Cudd_bddAnd(dd,res,Cudd_Not(x)); + break; + case '1': + w = Cudd_bddAnd(dd,res,x); + break; + default: /* don't care */ + w = res; + break; + } + + if (w == NULL) { + Cudd_RecursiveDeref(dd,res); + return(NULL); + } + Cudd_Ref(w); + Cudd_RecursiveDeref(dd,res); + res = w; + } + } + return(res); + +endgame: + + return(NULL); + +} /* end of Ntr_initState */ + + +/**Function******************************************************************** + + Synopsis [Reads a state cube from a file or creates a random one.] + + Description [Reads a state cube from a file or create a random one. + Returns a pointer to the BDD of the sink nodes if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +DdNode * +Ntr_getStateCube( + DdManager * dd, + BnetNetwork * net, + char * filename, + int pr) +{ + FILE *fp; + DdNode *cube; + DdNode *w; + char *state; + int i; + int err; + BnetNode *node; + DdNode *x; + char c[2]; + + cube = Cudd_ReadOne(dd); + if (net->nlatches == 0) { + Cudd_Ref(cube); + return(cube); + } + + state = ALLOC(char,net->nlatches+1); + if (state == NULL) + return(NULL); + state[net->nlatches] = 0; + + if (filename == NULL) { + /* Pick one random minterm. */ + for (i = 0; i < net->nlatches; i++) { + state[i] = (char) ((Cudd_Random() & 0x2000) ? '1' : '0'); + } + } else { + if ((fp = fopen(filename,"r")) == NULL) { + (void) fprintf(stderr,"Unable to open %s\n",filename); + return(NULL); + } + + /* Read string from file. Allow arbitrary amount of white space. */ + for (i = 0; !feof(fp); i++) { + err = fscanf(fp, "%1s", c); + state[i] = c[0]; + if (err == EOF || i == net->nlatches - 1) { + break; + } else if (err != 1 || strchr("012xX-", c[0]) == NULL ) { + FREE(state); + return(NULL); + } + } + err = fclose(fp); + if (err == EOF) { + FREE(state); + return(NULL); + } + } + + /* Echo the chosen state(s). */ + if (pr > 0) {(void) fprintf(stdout,"%s\n", state);} + + Cudd_Ref(cube); + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + Cudd_RecursiveDeref(dd,cube); + FREE(state); + return(NULL); + } + x = node->dd; + switch (state[i]) { + case '0': + w = Cudd_bddAnd(dd,cube,Cudd_Not(x)); + break; + case '1': + w = Cudd_bddAnd(dd,cube,x); + break; + default: /* don't care */ + w = cube; + break; + } + + if (w == NULL) { + Cudd_RecursiveDeref(dd,cube); + FREE(state); + return(NULL); + } + Cudd_Ref(w); + Cudd_RecursiveDeref(dd,cube); + cube = w; + } + + FREE(state); + return(cube); + +} /* end of Ntr_getStateCube */ + + +/**Function******************************************************************** + + Synopsis [Poor man's outer envelope computation.] + + Description [ Poor man's outer envelope computation based on the + monolithic transition relation. Returns 1 in case of success; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_Envelope( + DdManager * dd /* DD manager */, + NtrPartTR * TR /* transition relation */, + FILE * dfp /* pointer to file for DD dump */, + NtrOptions * option /* program options */) +{ + DdNode **x; /* array of x variables */ + DdNode **y; /* array of y variables */ + int ns; /* number of x and y variables */ + DdNode *dfunc[2]; /* addresses of the functions to be dumped */ + DdNode *envelope, *oldEnvelope; + DdNode *one; + int depth; + int retval; + int pr = option->verb; + int dumpFmt = option->dumpFmt; + + x = TR->x; + y = TR->y; + ns = TR->nlatches; + + one = Cudd_ReadOne(dd); + retval = Cudd_SetVarMap(dd,x,y,ns); + + /* Initialize From. */ + envelope = one; + if (envelope == NULL) return(0); + Cudd_Ref(envelope); + (void) printf("S0"); Cudd_PrintDebug(dd,envelope,ns,pr); + + /* Start traversal. */ + for (depth = 0; ; depth++) { + oldEnvelope = envelope; + /* Image computation. */ + envelope = ntrImage(dd,TR,oldEnvelope,option); + if (envelope == NULL) { + Cudd_RecursiveDeref(dd,oldEnvelope); + return(0); + } + + /* Check for convergence. */ + if (envelope == oldEnvelope) break; + + /* Prepare for new iteration. */ + Cudd_RecursiveDeref(dd,oldEnvelope); + (void) fprintf(stdout,"Envelope[%d]%s",depth+1,(pr>0)? "" : "\n"); + Cudd_PrintDebug(dd,envelope,ns,pr); + + } + /* Clean up. */ + Cudd_RecursiveDeref(dd,oldEnvelope); + + /* Print out result. */ + (void) printf("depth = %d\n", depth); + (void) printf("Envelope"); Cudd_PrintDebug(dd,envelope,ns,pr); + + /* Write dump file if requested. */ + if (dfp != NULL) { + dfunc[0] = TR->part[0]; + dfunc[1] = envelope; + if (dumpFmt == 1) { + retval = Cudd_DumpBlif(dd,2,dfunc,NULL,(char **)onames,NULL,dfp,0); + } else if (dumpFmt == 2) { + retval = Cudd_DumpDaVinci(dd,2,dfunc,NULL,(char **)onames,dfp); + } else if (dumpFmt == 3) { + retval = Cudd_DumpDDcal(dd,2,dfunc,NULL,(char **)onames,dfp); + } else if (dumpFmt == 4) { + retval = Cudd_DumpFactoredForm(dd,2,dfunc,NULL, + (char **)onames,dfp); + } else if (dumpFmt == 5) { + retval = Cudd_DumpBlif(dd,2,dfunc,NULL,(char **)onames,NULL,dfp,1); + } else { + retval = Cudd_DumpDot(dd,2,dfunc,NULL,(char **)onames,dfp); + } + if (retval != 1) { + (void) fprintf(stderr,"abnormal termination\n"); + return(0); + } + fclose(dfp); + } + + /* Clean up. */ + Cudd_RecursiveDeref(dd,envelope); + + return(1); + +} /* end of Ntr_Envelope */ + + +/**Function******************************************************************** + + Synopsis [Maximum 0-1 flow between source and sink states.] + + Description [Maximum 0-1 flow between source and sink + states. Returns 1 in case of success; 0 otherwise.] + + SideEffects [Creates two new sets of variables.] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_maxflow( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + DdNode **x = NULL; + DdNode **y = NULL; + DdNode **z = NULL; + DdNode *E = NULL; + DdNode *F = NULL; + DdNode *cut = NULL; + DdNode *sx = NULL; + DdNode *ty = NULL; + DdNode *tx = NULL; + int n; + int pr; + int ylevel; + int i; + double flow; + int result = 0; + NtrPartTR *TR; + + n = net->nlatches; + pr = option->verb; + TR = Ntr_buildTR(dd,net,option,NTR_IMAGE_MONO); + if (TR == NULL) + goto endgame; + E = TR->part[0]; + x = TR->x; + y = TR->y; + /* Create array of auxiliary variables. */ + z = ALLOC(DdNode *,n); + if (z == NULL) + goto endgame; + for (i = 0; i < n; i++) { + ylevel = Cudd_ReadIndex(dd,y[i]->index); + z[i] = Cudd_bddNewVarAtLevel(dd,ylevel); + if (z[i] == NULL) + goto endgame; + Cudd_Ref(z[i]); + } + /* Create BDDs for source and sink. */ + sx = Ntr_initState(dd,net,option); + if (sx == NULL) + goto endgame; + if (pr > 0) (void) fprintf(stdout, "Sink(s): "); + tx = Ntr_getStateCube(dd,net,option->sinkfile,pr); + if (tx == NULL) + goto endgame; + ty = Cudd_bddSwapVariables(dd,tx,x,y,n); + if (ty == NULL) + goto endgame; + Cudd_Ref(ty); + Cudd_RecursiveDeref(dd,tx); + tx = NULL; + + flow = Ntr_maximum01Flow(dd, sx, ty, E, &F, &cut, x, y, z, n, pr); + if (flow >= 0.0) + result = 1; + if (pr >= 0) { + (void) fprintf(stdout,"Maximum flow = %g\n", flow); + (void) fprintf(stdout,"E"); Cudd_PrintDebug(dd,E,2*n,pr); + (void) fprintf(stdout,"F"); Cudd_PrintDebug(dd,F,2*n,pr); + (void) fprintf(stdout,"cut"); Cudd_PrintDebug(dd,cut,2*n,pr); + } +endgame: + /* Clean up. */ + if (TR != NULL) Ntr_freeTR(dd,TR); + for (i = 0; i < n; i++) { + if (z != NULL && z[i] != NULL) Cudd_RecursiveDeref(dd,z[i]); + } + if (z != NULL) FREE(z); + if (F != NULL) Cudd_RecursiveDeref(dd,F); + if (cut != NULL) Cudd_RecursiveDeref(dd,cut); + if (sx != NULL) Cudd_RecursiveDeref(dd,sx); + if (ty != NULL) Cudd_RecursiveDeref(dd,ty); + return(result); + +} /* end of Ntr_Maxflow */ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Builds a positive cube of all the variables in x.] + + Description [Builds a positive cube of all the variables in x. Returns + a BDD for the cube if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +makecube( + DdManager * dd, + DdNode ** x, + int n) +{ + DdNode *res, *w, *one; + int i; + + one = Cudd_ReadOne(dd); + Cudd_Ref(res = one); + + for (i = n-1; i >= 0; i--) { + w = Cudd_bddAnd(dd,res,x[i]); + if (w == NULL) { + Cudd_RecursiveDeref(dd,res); + return(NULL); + } + Cudd_Ref(w); + Cudd_RecursiveDeref(dd,res); + res = w; + } + Cudd_Deref(res); + return(res); + +} /* end of makecube */ + + +/**Function******************************************************************** + + Synopsis [Initializes the count fields used to drop DDs.] + + Description [Initializes the count fields used to drop DDs. + Before actually building the BDDs, we perform a DFS from the outputs + to initialize the count fields of the nodes. The initial value of the + count field will normally coincide with the fanout of the node. + However, if there are nodes with no path to any primary output or next + state variable, then the initial value of count for some nodes will be + less than the fanout. For primary outputs and next state functions we + add 1, so that we will never try to free their DDs. The count fields + of the nodes that are not reachable from the outputs are set to -1.] + + SideEffects [Changes the count fields of the network nodes. Uses the + visited fields.] + + SeeAlso [] + +******************************************************************************/ +static void +ntrInitializeCount( + BnetNetwork * net, + NtrOptions * option) +{ + BnetNode *node; + int i; + + if (option->node != NULL && + option->closestCube == FALSE && option->dontcares == FALSE) { + if (!st_lookup(net->hash,option->node,&node)) { + (void) fprintf(stdout, "Warning: node %s not found!\n", + option->node); + } else { + ntrCountDFS(net,node); + node->count++; + } + } else { + if (option->stateOnly == FALSE) { + for (i = 0; i < net->npos; i++) { + if (!st_lookup(net->hash,net->outputs[i],&node)) { + (void) fprintf(stdout, + "Warning: output %s is not driven!\n", + net->outputs[i]); + continue; + } + ntrCountDFS(net,node); + node->count++; + } + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][0],&node)) { + (void) fprintf(stdout, + "Warning: latch input %s is not driven!\n", + net->outputs[i]); + continue; + } + ntrCountDFS(net,node); + node->count++; + } + } + + /* Clear visited flags. */ + node = net->nodes; + while (node != NULL) { + if (node->visited == 0) { + node->count = -1; + } else { + node->visited = 0; + } + node = node->next; + } + +} /* end of ntrInitializeCount */ + + +/**Function******************************************************************** + + Synopsis [Does a DFS from a node setting the count field.] + + Description [] + + SideEffects [Changes the count and visited fields of the nodes it + visits.] + + SeeAlso [ntrLevelDFS] + +******************************************************************************/ +static void +ntrCountDFS( + BnetNetwork * net, + BnetNode * node) +{ + int i; + BnetNode *auxnd; + + node->count++; + + if (node->visited == 1) { + return; + } + + node->visited = 1; + + for (i = 0; i < node->ninp; i++) { + if (!st_lookup(net->hash, node->inputs[i], &auxnd)) { + exit(2); + } + ntrCountDFS(net,auxnd); + } + +} /* end of ntrCountDFS */ + + +/**Function******************************************************************** + + Synopsis [Computes the image of a set given a transition relation.] + + Description [Computes the image of a set given a transition relation. + Returns a pointer to the result if successful; NULL otherwise. The image is + returned in terms of the present state variables; its reference count is + already increased.] + + SideEffects [None] + + SeeAlso [Ntr_Trav] + +******************************************************************************/ +static DdNode * +ntrImage( + DdManager * dd, + NtrPartTR * TR, + DdNode * from, + NtrOptions * option) +{ + int i; + DdNode *image; + DdNode *to; + NtrPartTR *T; + int depth = 0; + + if (option->image == NTR_IMAGE_CLIP) { + depth = (int) ((double) Cudd_ReadSize(dd) * option->imageClip); + } + + /* Existentially quantify the present state variables that are not + ** in the support of any next state function. */ + image = Cudd_bddExistAbstract(dd,from,TR->preiabs); + if (image == NULL) return(NULL); + Cudd_Ref(image); + if (option->image == NTR_IMAGE_DEPEND) { + /* Simplify the transition relation based on dependencies + ** and build the conjuncts from the deltas. */ + T = ntrEliminateDependencies(dd,TR,&image,option); + } else { + T = TR; + } + if (T == NULL) return(NULL); + for (i = 0; i < T->nparts; i++) { +#if 0 + (void) printf(" Intermediate product[%d]: %d nodes\n", + i,Cudd_DagSize(image)); +#endif + if (option->image == NTR_IMAGE_CLIP) { + to = Cudd_bddClippingAndAbstract(dd,T->part[i],image,T->icube[i], + depth,option->approx); + } else { + to = Cudd_bddAndAbstract(dd,T->part[i],image,T->icube[i]); + } + if (to == NULL) return(NULL); + Cudd_Ref(to); + if (option->image == NTR_IMAGE_DEPEND) { + /* Extract dependencies from intermediate product. */ + DdNode *abs, *positive, *absabs, *phi, *exnor, *tmp; + abs = Cudd_bddExistAbstract(dd,to,T->xw); + if (abs == NULL) return(NULL); Cudd_Ref(abs); + if (Cudd_bddVarIsDependent(dd,abs,T->nscube[i]) && + Cudd_EstimateCofactor(dd,abs,T->nscube[i]->index,1) <= + T->nlatches) { + int retval, sizex; + positive = Cudd_Cofactor(dd,abs,T->nscube[i]); + if (positive == NULL) return(NULL); Cudd_Ref(positive); + absabs = Cudd_bddExistAbstract(dd,abs,T->nscube[i]); + if (absabs == NULL) return(NULL); Cudd_Ref(absabs); + Cudd_RecursiveDeref(dd,abs); + phi = Cudd_bddLICompaction(dd,positive,absabs); + if (phi == NULL) return(NULL); Cudd_Ref(phi); + Cudd_RecursiveDeref(dd,positive); + Cudd_RecursiveDeref(dd,absabs); + exnor = Cudd_bddXnor(dd,T->nscube[i],phi); + if (exnor == NULL) return(NULL); Cudd_Ref(exnor); + Cudd_RecursiveDeref(dd,phi); + sizex = Cudd_DagSize(exnor); + (void) printf("new factor of %d nodes\n", sizex); + retval = Ntr_HeapInsert(T->factors,exnor,sizex); + if (retval == 0) return(NULL); + tmp = Cudd_bddExistAbstract(dd,to,T->nscube[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,to); + to = tmp; + } else { + Cudd_RecursiveDeref(dd,abs); + } + } + Cudd_RecursiveDeref(dd,image); + image = to; + } + if (option->image == NTR_IMAGE_DEPEND) { + int size1, size2; + DdNode *factor1, *factor2, *tmp; + int retval; + size1 = Cudd_DagSize(image); + retval = Ntr_HeapInsert(T->factors,image,size1); + if (retval == 0) return(NULL); + (void) printf("Merging %d factors. Independent image: %d nodes\n", + Ntr_HeapCount(T->factors), size1); + while (Ntr_HeapCount(T->factors) > 1) { + retval = Ntr_HeapExtractMin(T->factors,&factor1,&size1); + if (retval == 0) return(NULL); + retval = Ntr_HeapExtractMin(T->factors,&factor2,&size2); + if (retval == 0) return(NULL); + tmp = Cudd_bddAnd(dd,factor1,factor2); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + size1 = Cudd_DagSize(tmp); + (void) printf("new factor %d nodes\n", size1); + Cudd_RecursiveDeref(dd,factor1); + Cudd_RecursiveDeref(dd,factor2); + retval = Ntr_HeapInsert(T->factors,tmp,size1); + if (retval == 0) return(NULL); + } + retval = Ntr_HeapExtractMin(T->factors,&image,&size1); + if (retval == 0) return(NULL); + Ntr_freeTR(dd,T); + } + + /* Express image in terms of x variables. */ + to = Cudd_bddVarMap(dd,image); + if (to == NULL) { + Cudd_RecursiveDeref(dd,image); + return(NULL); + } + Cudd_Ref(to); + Cudd_RecursiveDeref(dd,image); + return(to); + +} /* end of ntrImage */ + + +/**Function******************************************************************** + + Synopsis [Computes the preimage of a set given a transition relation.] + + Description [Computes the preimage of a set given a transition relation. + Returns a pointer to the result if successful; NULL otherwise. The preimage + is returned in terms of the next state variables; its reference count is + already increased.] + + SideEffects [None] + + SeeAlso [ntrImage Ntr_SCC] + +******************************************************************************/ +static DdNode * +ntrPreimage( + DdManager * dd, + NtrPartTR * T, + DdNode * from) +{ + int i; + DdNode *preimage; + DdNode *to; + + /* Existentially quantify the present state variables that are not + ** in the support of any next state function. */ + preimage = Cudd_bddExistAbstract(dd,from,T->prepabs); + if (preimage == NULL) return(NULL); + Cudd_Ref(preimage); + for (i = 0; i < T->nparts; i++) { +#if 0 + (void) printf(" Intermediate product[%d]: %d nodes\n", + i,Cudd_DagSize(preimage)); +#endif + to = Cudd_bddAndAbstract(dd,T->part[i],preimage,T->pcube[i]); + if (to == NULL) return(NULL); + Cudd_Ref(to); + Cudd_RecursiveDeref(dd,preimage); + preimage = to; + } + + /* Express preimage in terms of x variables. */ + to = Cudd_bddVarMap(dd,preimage); + if (to == NULL) { + Cudd_RecursiveDeref(dd,preimage); + return(NULL); + } + Cudd_Ref(to); + Cudd_RecursiveDeref(dd,preimage); + return(to); + +} /* end of ntrPreimage */ + + +/**Function******************************************************************** + + Synopsis [Chooses the initial states for a BFS step.] + + Description [Chooses the initial states for a BFS step. Returns a + pointer to the chose set if successful; NULL otherwise. The + reference count of the result is already incremented.] + + SideEffects [none] + + SeeAlso [Ntr_Trav] + +******************************************************************************/ +static DdNode * +ntrChooseFrom( + DdManager * dd, + DdNode * neW, + DdNode * reached, + NtrOptions * option) +{ + DdNode *min, *c; + int threshold; + + switch (option->from) { + case NTR_FROM_NEW: + Cudd_Ref(neW); + return(neW); + case NTR_FROM_REACHED: + Cudd_Ref(reached); + return(reached); + case NTR_FROM_RESTRICT: + c = Cudd_bddOr(dd, neW, Cudd_Not(reached)); + if (c == NULL) return(NULL); + Cudd_Ref(c); + min = Cudd_bddRestrict(dd,neW,c); + if (min == NULL) { + Cudd_RecursiveDeref(dd, c); + return(NULL); + } + Cudd_Ref(min); + Cudd_RecursiveDeref(dd, c); + return(min); + case NTR_FROM_COMPACT: + c = Cudd_bddOr(dd, neW, Cudd_Not(reached)); + if (c == NULL) return(NULL); + Cudd_Ref(c); + min = Cudd_bddLICompaction(dd,neW,c); + if (min == NULL) { + Cudd_RecursiveDeref(dd, c); + return(NULL); + } + Cudd_Ref(min); + Cudd_RecursiveDeref(dd, c); + return(min); + case NTR_FROM_SQUEEZE: + min = Cudd_bddSqueeze(dd,neW,reached); + if (min == NULL) return(NULL); + Cudd_Ref(min); + return(min); + case NTR_FROM_UNDERAPPROX: + threshold = (option->threshold < 0) ? 0 : option->threshold; + min = Cudd_RemapUnderApprox(dd,neW,Cudd_SupportSize(dd,neW), + threshold,option->quality); + if (min == NULL) return(NULL); + Cudd_Ref(min); + return(min); + case NTR_FROM_OVERAPPROX: + threshold = (option->threshold < 0) ? 0 : option->threshold; + min = Cudd_RemapOverApprox(dd,neW,Cudd_SupportSize(dd,neW), + threshold,option->quality); + if (min == NULL) return(NULL); + Cudd_Ref(min); + return(min); + default: + return(NULL); + } + +} /* end of ntrChooseFrom */ + + +/**Function******************************************************************** + + Synopsis [Updates the reached states after a traversal step.] + + Description [Updates the reached states after a traversal + step. Returns a pointer to the new reached set if successful; NULL + otherwise. The reference count of the result is already incremented.] + + SideEffects [The old reached set is dereferenced.] + + SeeAlso [Ntr_Trav] + +******************************************************************************/ +static DdNode * +ntrUpdateReached( + DdManager * dd /* manager */, + DdNode * oldreached /* old reached state set */, + DdNode * to /* result of last image computation */) +{ + DdNode *reached; + + reached = Cudd_bddOr(dd,oldreached,to); + if (reached == NULL) { + Cudd_RecursiveDeref(dd,oldreached); + return(NULL); + } + Cudd_Ref(reached); + Cudd_RecursiveDeref(dd,oldreached); + return(reached); + +} /* end of ntrUpdateReached */ + + +/**Function******************************************************************** + + Synopsis [Analyzes the reached states after traversal to find + dependent latches.] + + Description [Analyzes the reached states after traversal to find + dependent latches. Returns the number of latches that can be + eliminated because they are stuck at a constant value or are + dependent on others if successful; -1 otherwise. The algorithm is + greedy and determines a local optimum, not a global one.] + + SideEffects [] + + SeeAlso [Ntr_Trav] + +******************************************************************************/ +static int +ntrLatchDependencies( + DdManager *dd, + DdNode *reached, + BnetNetwork *net, + NtrOptions *option) +{ + int i; + int howMany; /* number of latches that can be eliminated */ + DdNode *var, *newreached, *abs, *positive, *phi; + char *name; + BnetNode *node; + int initVars, finalVars; + double initStates, finalStates; + DdNode **roots; + char **onames; + int howManySmall = 0; + int *candidates; + double minStates; + int totalVars; + + (void) printf("Analyzing latch dependencies\n"); + roots = ALLOC(DdNode *, net->nlatches); + if (roots == NULL) return(-1); + onames = ALLOC(char *, net->nlatches); + if (onames == NULL) return(-1); + + candidates = ALLOC(int,net->nlatches); + if (candidates == NULL) return(-1); + for (i = 0; i < net->nlatches; i++) { + candidates[i] = i; + } + /* The signatures of the variables in a function are the number + ** of minterms of the positive cofactors with respect to the + ** variables themselves. */ + newreached = reached; + Cudd_Ref(newreached); + signatures = Cudd_CofMinterm(dd,newreached); + if (signatures == NULL) return(-1); + /* We now extract a positive quantity which is higher for those + ** variables that are closer to being essential. */ + totalVars = Cudd_ReadSize(dd); + minStates = signatures[totalVars]; +#if 0 + (void) printf("Raw signatures (minStates = %g)\n", minStates); + for (i = 0; i < net->nlatches; i++) { + int j = candidates[i]; + if (!st_lookup(net->hash,net->latches[j][1],(char **) &node)) { + return(-1); + } + (void) printf("%s -> %g\n", node->name, signatures[node->dd->index]); + } +#endif + for (i = 0; i < totalVars; i++) { + double z = signatures[i] / minStates - 1.0; + signatures[i] = (z >= 0.0) ? z : -z; /* make positive */ + } + staticNet = net; + qsort((void *)candidates,net->nlatches,sizeof(int), + (DD_QSFP)ntrSignatureCompare2); +#if 0 + (void) printf("Cooked signatures\n"); + for (i = 0; i < net->nlatches; i++) { + int j = candidates[i]; + if (!st_lookup(net->hash,net->latches[j][1],(char **) &node)) { + return(-1); + } + (void) printf("%s -> %g\n", node->name, signatures[node->dd->index]); + } +#endif + FREE(signatures); + + /* Extract simple dependencies. */ + for (i = 0; i < net->nlatches; i++) { + int j = candidates[i]; + if (!st_lookup(net->hash,net->latches[j][1],&node)) { + return(-1); + } + var = node->dd; + name = node->name; + if (Cudd_bddVarIsDependent(dd,newreached,var)) { + positive = Cudd_Cofactor(dd,newreached,var); + if (positive == NULL) return(-1); Cudd_Ref(positive); + abs = Cudd_bddExistAbstract(dd,newreached,var); + if (abs == NULL) return(-1); Cudd_Ref(abs); + phi = Cudd_bddLICompaction(dd,positive,abs); + if (phi == NULL) return(-1); Cudd_Ref(phi); + Cudd_RecursiveDeref(dd,positive); + if (Cudd_DagSize(phi) < NTR_MAX_DEP_SIZE) { + if (Cudd_bddLeq(dd,newreached,var)) { + (void) printf("%s is stuck at 1\n",name); + } else if (Cudd_bddLeq(dd,newreached,Cudd_Not(var))) { + (void) printf("%s is stuck at 0\n",name); + } else { + (void) printf("%s depends on the other variables\n",name); + } + roots[howManySmall] = phi; + onames[howManySmall] = util_strsav(name); + Cudd_RecursiveDeref(dd,newreached); + newreached = abs; + howManySmall++; + candidates[i] = -1; /* do not reconsider */ + } else { + Cudd_RecursiveDeref(dd,abs); + Cudd_RecursiveDeref(dd,phi); + } + } else { + candidates[i] = -1; /* do not reconsider */ + } + } + /* Now remove remaining dependent variables. */ + howMany = howManySmall; + for (i = 0; i < net->nlatches; i++) { + int j = candidates[i]; + if (j == -1) continue; + if (!st_lookup(net->hash,net->latches[j][1],&node)) { + return(-1); + } + var = node->dd; + name = node->name; + if (Cudd_bddVarIsDependent(dd,newreached,var)) { + if (Cudd_bddLeq(dd,newreached,var)) { + (void) printf("%s is stuck at 1\n",name); + } else if (Cudd_bddLeq(dd,newreached,Cudd_Not(var))) { + (void) printf("%s is stuck at 0\n",name); + } else { + (void) printf("%s depends on the other variables\n",name); + } + abs = Cudd_bddExistAbstract(dd,newreached,var); + if (abs == NULL) return(-1); Cudd_Ref(abs); + Cudd_RecursiveDeref(dd,newreached); + newreached = abs; + howMany++; + } + } + FREE(candidates); + if (howManySmall > 0) { + if (!Bnet_bddArrayDump(dd,net,(char *)"-",roots,onames,howManySmall,1)) + return(-1); + } + for (i = 0; i < howManySmall; i++) { + Cudd_RecursiveDeref(dd,roots[i]); + FREE(onames[i]); + } + FREE(roots); + FREE(onames); + + initVars = net->nlatches; + initStates = Cudd_CountMinterm(dd,reached,initVars); + finalVars = initVars - howMany; + finalStates = Cudd_CountMinterm(dd,newreached,finalVars); + if (initStates != finalStates) { + (void) printf("Error: the number of states changed from %g to %g\n", + initStates, finalStates); + return(-1); + } + (void) printf("new reached"); + Cudd_PrintDebug(dd,newreached,finalVars,option->verb); + Cudd_RecursiveDeref(dd,newreached); + return(howMany); + +} /* end of ntrLatchDependencies */ + + +/**Function******************************************************************** + + Synopsis [Eliminates dependent variables from a transition relation.] + + Description [Eliminates dependent variables from a transition + relation. Returns a simplified copy of the given transition + relation if successful; NULL otherwise.] + + SideEffects [The modified set of states is returned as a side effect.] + + SeeAlso [ntrImage] + +******************************************************************************/ +static NtrPartTR * +ntrEliminateDependencies( + DdManager *dd, + NtrPartTR *TR, + DdNode **states, + NtrOptions *option) +{ + NtrPartTR *T; /* new TR without dependent vars */ + int pr = option->verb; + int i, j; + int howMany = 0; /* number of latches that can be eliminated */ + DdNode *var, *newstates, *abs, *positive, *phi; + DdNode *support, *scan, *tmp; + int finalSize; /* size of the TR after substitutions */ + int nvars; /* vars in the support of the state set */ + int *candidates; /* vars to be considered for elimination */ + int totalVars; + double minStates; + + /* Initialize the new transition relation by copying the old one. */ + T = Ntr_cloneTR(TR); + if (T == NULL) return(NULL); + newstates = *states; + Cudd_Ref(newstates); + + /* Find and rank the candidate variables. */ + support = Cudd_Support(dd,newstates); + if (support == NULL) { + Ntr_freeTR(dd,T); + return(NULL); + } + Cudd_Ref(support); + nvars = Cudd_DagSize(support) - 1; + candidates = ALLOC(int,nvars); + if (candidates == NULL) { + Cudd_RecursiveDeref(dd,support); + Ntr_freeTR(dd,T); + return(NULL); + } + scan = support; + for (i = 0; i < nvars; i++) { + candidates[i] = scan->index; + scan = Cudd_T(scan); + } + Cudd_RecursiveDeref(dd,support); + /* The signatures of the variables in a function are the number + ** of minterms of the positive cofactors with respect to the + ** variables themselves. */ + signatures = Cudd_CofMinterm(dd,newstates); + if (signatures == NULL) { + FREE(candidates); + Ntr_freeTR(dd,T); + return(NULL); + } + /* We now extract a positive quantity which is higher for those + ** variables that are closer to being essential. */ + totalVars = Cudd_ReadSize(dd); + minStates = signatures[totalVars]; + for (i = 0; i < totalVars; i++) { + double z = signatures[i] / minStates - 1.0; + signatures[i] = (z < 0.0) ? -z : z; /* make positive */ + } + /* Sort candidates in decreasing order of signature. */ + qsort((void *)candidates,nvars,sizeof(int), + (DD_QSFP)ntrSignatureCompare); + FREE(signatures); + + /* Now process the candidates in the given order. */ + for (i = 0; i < nvars; i++) { + var = Cudd_bddIthVar(dd,candidates[i]); + if (Cudd_bddVarIsDependent(dd,newstates,var)) { + abs = Cudd_bddExistAbstract(dd,newstates,var); + if (abs == NULL) return(NULL); Cudd_Ref(abs); + positive = Cudd_Cofactor(dd,newstates,var); + if (positive == NULL) return(NULL); Cudd_Ref(positive); + phi = Cudd_bddLICompaction(dd,positive,abs); + if (phi == NULL) return(NULL); Cudd_Ref(phi); + Cudd_RecursiveDeref(dd,positive); +#if 0 + if (pr > 0) { + (void) printf("Phi"); + Cudd_PrintDebug(dd,phi,T->nlatches,pr); + } +#endif + if (Cudd_DagSize(phi) < NTR_MAX_DEP_SIZE) { + howMany++; + for (j = 0; j < T->nparts; j++) { + tmp = Cudd_bddCompose(dd,T->part[j],phi,candidates[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,T->part[j]); + T->part[j] = tmp; + } + Cudd_RecursiveDeref(dd,newstates); + newstates = abs; + } else { + Cudd_RecursiveDeref(dd,abs); + } + Cudd_RecursiveDeref(dd,phi); + } + } + FREE(candidates); + + if (pr > 0) { + finalSize = Cudd_SharingSize(T->part,T->nparts); + (void) printf("Eliminated %d vars. Transition function %d nodes.\n", + howMany,finalSize); + } + + if (!ntrUpdateQuantificationSchedule(dd,T)) return(NULL); + + /* Quantify out of states variables that no longer appear in any part. */ + Cudd_RecursiveDeref(dd,*states); + *states = Cudd_bddExistAbstract(dd,newstates,T->preiabs); + if (*states == NULL) return(NULL); Cudd_Ref(*states); + Cudd_RecursiveDeref(dd,newstates); + return(T); + +} /* end of ntrEliminateDependencies */ + + +/**Function******************************************************************** + + Synopsis [Updates the quantification schedule of a transition relation.] + + Description [Updates the quantification schedule of a transition relation. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [ntrEliminateDependencies] + +******************************************************************************/ +static int +ntrUpdateQuantificationSchedule( + DdManager *dd, + NtrPartTR *T) +{ + int i, j, k; + int *schedule; + DdNode *one, *support, *scan, *var, *tmp; + char **matrix; + int *position, *row; + char *flags; + int nparts, nvars; + int extracted; +#if 0 + int schedcost; +#endif + + nparts = T->nparts; + nvars = Cudd_ReadSize(dd); + one = Cudd_ReadOne(dd); + + /* Reinitialize the abstraction cubes. */ + Cudd_RecursiveDeref(dd,T->preiabs); + T->preiabs = one; + Cudd_Ref(one); + for (i = 0; i < nparts; i++) { + Cudd_RecursiveDeref(dd,T->icube[i]); + T->icube[i] = one; + Cudd_Ref(one); + } + + /* Initialize row permutations to the identity. */ + position = ALLOC(int,nparts); + if (position == NULL) return(0); + for (i = 0; i < nparts; i++) { + position[i] = i; + } + /* Sort parts so that parts that differ only + ** in the index of the next state variable are contiguous. */ + staticPart = T->part; + qsort((void *)position,nparts,sizeof(int), (DD_QSFP)ntrPartCompare); + /* Extract repeated parts. */ + extracted = 0; + for (i = 0; i < nparts - 1; i += j) { + int pi, pij; + DdNode *eq; + j = 1; + pi = position[i]; + eq = one; + Cudd_Ref(eq); + pij = position[i+j]; + while (Cudd_Regular(staticPart[pij]) == Cudd_Regular(staticPart[pi])) { + int comple = staticPart[pij] != staticPart[pi]; + DdNode *xnor = Cudd_bddXnor(dd,T->nscube[pi], + Cudd_NotCond(T->nscube[pij],comple)); + if (xnor == NULL) return(0); Cudd_Ref(xnor); + tmp = Cudd_bddAnd(dd,xnor,eq); + if (tmp == NULL) return(0); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,xnor); + Cudd_RecursiveDeref(dd,eq); + eq = tmp; + Cudd_RecursiveDeref(dd,T->part[pij]); + Cudd_RecursiveDeref(dd,T->icube[pij]); + Cudd_RecursiveDeref(dd,T->nscube[pij]); + T->part[pij] = NULL; + j++; + if (i+j == nparts) break; + pij = position[i+j]; + } + if (eq != one) { + int retval = Ntr_HeapInsert(T->factors,eq,Cudd_DagSize(eq)); + if (retval == 0) return(0); + extracted += j - 1; + } else { + Cudd_RecursiveDeref(dd,eq); + } + } + /* Compact the part array by removing extracted parts. */ + for (i = 0, j = 0; i < nparts; i++) { + if (T->part[i] != NULL) { + T->part[j] = T->part[i]; + T->icube[j] = T->icube[i]; + T->nscube[j] = T->nscube[i]; + j++; + } + } + nparts = T->nparts -= extracted; + (void) printf("Extracted %d repeated parts in %d factors.\n", + extracted, Ntr_HeapCount(T->factors)); + + /* Build the support matrix. Each row corresponds to a part of the + ** transition relation; each column corresponds to a variable in + ** the manager. A 1 in position (i,j) means that Part i depends + ** on Variable j. */ + matrix = ntrAllocMatrix(nparts,nvars); + if (matrix == NULL) return(0); + + /* Allocate array for quantification schedule and initialize it. */ + schedule = ALLOC(int,nvars); + if (schedule == NULL) return(0); + for (i = 0; i < nvars; i++) { + schedule[i] = -1; + } + /* Collect scheduling info for this part. At the end of this loop + ** schedule[i] == j means that the variable of index i does not + ** appear in any part with index greater than j, unless j == -1, + ** in which case the variable appears in no part. + */ + for (i = 0; i < nparts; i++) { + support = Cudd_Support(dd,T->part[i]); + if (support == NULL) return(0); Cudd_Ref(support); + scan = support; + while (!Cudd_IsConstant(scan)) { + int index = scan->index; + schedule[index] = i; + matrix[i][index] = 1; + scan = Cudd_T(scan); + } + Cudd_RecursiveDeref(dd,support); + } +#if 0 + (void) printf("Initial schedule:"); + schedcost = 0; + for (i = 0; i < nvars; i++) { + (void) printf(" %d", schedule[i]); + if (schedule[i] != -1) schedcost += schedule[i]; + } + (void) printf("\nCost = %d\n", schedcost); +#endif + + /* Initialize direct and inverse row permutations to the identity + ** permutation. */ + row = ALLOC(int,nparts); + if (row == NULL) return(0); + for (i = 0; i < nparts; i++) { + position[i] = row[i] = i; + } + + /* Sift the matrix. */ + flags = ALLOC(char,nvars); + if (flags == NULL) return(0); + for (i = 0; i < nparts; i++) { + int cost = 0; /* cost of moving the row */ + int bestcost = 0; + int posn = position[i]; + int bestposn = posn; + /* Sift up. */ + /* Initialize the flags to one is for the variables that are + ** currently scheduled to be quantified after this part gets + ** multiplied. When we cross a row of a part that depends on + ** a variable whose flag is 1, we know that the row being sifted + ** is no longer responsible for that variable. */ + for (k = 0; k < nvars; k++) { + flags[k] = (char) (schedule[k] == i); + } + for (j = posn - 1; j >= 0; j--) { + for (k = 0; k < nvars; k++) { + if (schedule[k] == row[j]) { + cost++; + } else { + flags[k] &= matrix[row[j]][k] == 0; + cost -= flags[k]; + } + } + if (cost < bestcost) { + bestposn = j; + bestcost = cost; + } + } + /* Sift down. */ + /* Reinitialize the flags. (We are implicitly undoing the sift + ** down step.) */ + for (k = 0; k < nvars; k++) { + flags[k] = (char) (schedule[k] == i); + } + for (j = posn + 1; j < nparts; j++) { + for (k = 0; k < nvars; k++) { + if (schedule[k] == row[j]) { + flags[k] |= matrix[i][k] == 1; + cost -= flags[k] == 0; + } else { + cost += flags[k]; + } + } + if (cost < bestcost) { + bestposn = j; + bestcost = cost; + } + } + /* Move to best position. */ + if (bestposn < posn) { + for (j = posn; j >= bestposn; j--) { + k = row[j]; + if (j > 0) row[j] = row[j-1]; + position[k]++; + } + } else { + for (j = posn; j <= bestposn; j++) { + k = row[j]; + if (j < nparts - 1) row[j] = row[j+1]; + position[k]--; + } + } + position[i] = bestposn; + row[bestposn] = i; + /* Fix the schedule. */ + for (k = 0; k < nvars; k++) { + if (matrix[i][k] == 1) { + if (position[schedule[k]] < bestposn) { + schedule[k] = i; + } else { + for (j = nparts - 1; j >= position[i]; j--) { + if (matrix[row[j]][k] == 1) break; + } + schedule[k] = row[j]; + } + } + } + } + ntrFreeMatrix(matrix); + FREE(flags); + + /* Update schedule to account for the permutation. */ + for (i = 0; i < nvars; i++) { + if (schedule[i] >= 0) { + schedule[i] = position[schedule[i]]; + } + } + /* Sort parts. */ + ntrPermuteParts(T->part,T->nscube,row,position,nparts); + FREE(position); + FREE(row); +#if 0 + (void) printf("New schedule:"); + schedcost = 0; + for (i = 0; i < nvars; i++) { + (void) printf(" %d", schedule[i]); + if (schedule[i] != -1) schedcost += schedule[i]; + } + (void) printf("\nCost = %d\n", schedcost); +#endif + + /* Mark the next state varibles so that they do not go in the + ** abstraction cubes. */ + for (i = 0; i < T->nlatches; i++) { + schedule[T->y[i]->index] = -2; + } + + /* Rebuild the cubes from the schedule. */ + for (i = 0; i < nvars; i++) { + k = schedule[i]; + var = Cudd_bddIthVar(dd,i); + if (k >= 0) { + tmp = Cudd_bddAnd(dd,T->icube[k],var); + if (tmp == NULL) return(0); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,T->icube[k]); + T->icube[k] = tmp; + } else if (k != -2) { + tmp = Cudd_bddAnd(dd,T->preiabs,var); + if (tmp == NULL) return(0); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,T->preiabs); + T->preiabs = tmp; + } + } + FREE(schedule); + + /* Build the conjuncts. */ + for (i = 0; i < nparts; i++) { + tmp = Cudd_bddXnor(dd,T->nscube[i],T->part[i]); + if (tmp == NULL) return(0); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,T->part[i]); + T->part[i] = tmp; + } + + return(1); + +} /* end of ntrUpdateQuantificationSchedule */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to their signatures.] + + SideEffects [None] + +******************************************************************************/ +static int +ntrSignatureCompare( + int * ptrX, + int * ptrY) +{ + if (signatures[*ptrY] > signatures[*ptrX]) return(1); + if (signatures[*ptrY] < signatures[*ptrX]) return(-1); + return(0); + +} /* end of ntrSignatureCompare */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to their signatures.] + + SideEffects [None] + +******************************************************************************/ +static int +ntrSignatureCompare2( + int * ptrX, + int * ptrY) +{ + BnetNode *node; + int x,y; + if (!st_lookup(staticNet->hash,staticNet->latches[*ptrX][1],&node)) { + return(0); + } + x = node->dd->index; + if (!st_lookup(staticNet->hash,staticNet->latches[*ptrY][1],&node)) { + return(0); + } + y = node->dd->index; + if (signatures[x] < signatures[y]) return(1); + if (signatures[x] > signatures[y]) return(-1); + return(0); + +} /* end of ntrSignatureCompare2 */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + parts according to the BDD addresses.] + + SideEffects [None] + +******************************************************************************/ +static int +ntrPartCompare( + int * ptrX, + int * ptrY) +{ + if (staticPart[*ptrY] > staticPart[*ptrX]) return(1); + if (staticPart[*ptrY] < staticPart[*ptrX]) return(-1); + return(0); + +} /* end of ntrPartCompare */ + + +/**Function******************************************************************** + + Synopsis [Allocates a matrix.] + + Description [Allocates a matrix of char's. Returns a pointer to the matrix + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static char ** +ntrAllocMatrix( + int nrows, + int ncols) +{ + int i; + char **matrix; + + matrix = ALLOC(char *,nrows); + if (matrix == NULL) return(NULL); + matrix[0] = ALLOC(char,nrows * ncols); + if (matrix[0] == NULL) { + FREE(matrix); + return(NULL); + } + for (i = 1; i < nrows; i++) { + matrix[i] = matrix[i-1] + ncols; + } + for (i = 0; i < nrows * ncols; i++) { + matrix[0][i] = 0; + } + return(matrix); + +} /* end of ntrAllocMatrix */ + + +/**Function******************************************************************** + + Synopsis [Frees a matrix of char's.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ntrFreeMatrix( + char **matrix) +{ + FREE(matrix[0]); + FREE(matrix); + return; + +} /* end of ntrFreeMatrix */ + + +/**Function******************************************************************** + + Synopsis [Sorts parts according to given permutation.] + + Description [] + + SideEffects [The permutation arrays are turned into the identity + permutations.] + + SeeAlso [] + +******************************************************************************/ +static void +ntrPermuteParts( + DdNode **a, + DdNode **b, + int *comesFrom, + int *goesTo, + int size) +{ + int i, j; + DdNode *tmp; + + for (i = 0; i < size; i++) { + if (comesFrom[i] == i) continue; + j = comesFrom[i]; + tmp = a[i]; a[i] = a[j]; a[j] = tmp; + tmp = b[i]; b[i] = b[j]; b[j] = tmp; + comesFrom[goesTo[i]] = j; + comesFrom[i] = i; + goesTo[j] = goesTo[i]; + goesTo[i] = i; + } + return; + +} /* end of ntrPermuteParts */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntr.h b/resources/3rdparty/cudd-2.5.0/nanotrav/ntr.h new file mode 100644 index 000000000..e70b42100 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntr.h @@ -0,0 +1,283 @@ +/**CHeaderFile***************************************************************** + + FileName [ntr.h] + + PackageName [ntr] + + Synopsis [Simple-minded package to do traversal.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: ntr.h,v 1.28 2012/02/05 01:53:01 fabio Exp fabio $] + +******************************************************************************/ + +#ifndef _NTR +#define _NTR + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include "dddmp.h" +#include "bnet.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define PI_PS_FROM_FILE 0 +#define PI_PS_DFS 1 +#define PI_PS_GIVEN 2 + +#define NTR_IMAGE_MONO 0 +#define NTR_IMAGE_PART 1 +#define NTR_IMAGE_CLIP 2 +#define NTR_IMAGE_DEPEND 3 + +#define NTR_UNDER_APPROX 0 +#define NTR_OVER_APPROX 1 + +#define NTR_FROM_NEW 0 +#define NTR_FROM_REACHED 1 +#define NTR_FROM_RESTRICT 2 +#define NTR_FROM_COMPACT 3 +#define NTR_FROM_SQUEEZE 4 +#define NTR_FROM_UNDERAPPROX 5 +#define NTR_FROM_OVERAPPROX 6 + +#define NTR_GROUP_NONE 0 +#define NTR_GROUP_DEFAULT 1 +#define NTR_GROUP_FIXED 2 + +#define NTR_SHORT_NONE 0 +#define NTR_SHORT_BELLMAN 1 +#define NTR_SHORT_FLOYD 2 +#define NTR_SHORT_SQUARE 3 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct NtrOptions { + long initialTime; /* this is here for convenience */ + int verify; /* read two networks and compare them */ + char *file1; /* first network file name */ + char *file2; /* second network file name */ + int second; /* a second network is given */ + int traverse; /* do reachability analysis */ + int depend; /* do latch dependence analysis */ + int image; /* monolithic, partitioned, or clip */ + double imageClip; /* clipping depth in image computation */ + int approx; /* under or over approximation */ + int threshold; /* approximation threshold */ + int from; /* method to compute from states */ + int groupnsps; /* group present state and next state vars */ + int closure; /* use transitive closure */ + double closureClip; /* clipping depth in closure computation */ + int envelope; /* compute outer envelope */ + int scc; /* compute strongly connected components */ + int zddtest; /* do zdd test */ + int printcover; /* print ISOP covers when testing ZDDs */ + int maxflow; /* compute maximum flow in network */ + int shortPath; /* compute shortest paths in network */ + int selectiveTrace; /* use selective trace in shortest paths */ + char *sinkfile; /* file for externally provided sink node */ + int partition; /* test McMillan conjunctive partitioning */ + int char2vect; /* test char-to-vect decomposition */ + int density; /* test density-related functions */ + double quality; /* quality parameter for density functions */ + int decomp; /* test decomposition functions */ + int cofest; /* test cofactor estimation */ + double clip; /* test clipping functions */ + int dontcares; /* test equivalence and containment with DCs */ + int closestCube; /* test Cudd_bddClosestCube */ + int clauses; /* test extraction of two-literal clauses */ + int noBuild; /* do not build BDDs; just echo order */ + int stateOnly; /* ignore primary outputs */ + char *node; /* only node for which to build BDD */ + int locGlob; /* build global or local BDDs */ + int progress; /* report output names while building BDDs */ + int cacheSize; /* computed table initial size */ + unsigned long maxMemory; /* target maximum memory */ + unsigned long maxMemHard; /* maximum allowed memory */ + unsigned int maxLive; /* maximum number of nodes */ + int slots; /* unique subtable initial slots */ + int ordering; /* FANIN DFS ... */ + char *orderPiPs; /* file for externally provided order */ + Cudd_ReorderingType reordering; /* NONE RANDOM PIVOT SIFTING ... */ + int autoDyn; /* ON OFF */ + Cudd_ReorderingType autoMethod; /* RANDOM PIVOT SIFTING CONVERGE ... */ + char *treefile; /* file name for variable tree */ + int firstReorder; /* when to do first reordering */ + int countDead; /* count dead nodes toward triggering + reordering */ + int maxGrowth; /* maximum growth during reordering (%) */ + Cudd_AggregationType groupcheck; /* grouping function */ + int arcviolation; /* percent violation of arcs in + extended symmetry check */ + int symmviolation; /* percent symm violation in + extended symmetry check */ + int recomb; /* recombination parameter for grouping */ + int nodrop; /* don't drop intermediate BDDs ASAP */ + int signatures; /* computation of signatures */ + int gaOnOff; /* whether to run GA at the end */ + int populationSize; /* population size for GA */ + int numberXovers; /* number of crossovers for GA */ + int bdddump; /* ON OFF */ + int dumpFmt; /* 0 -> dot 1 -> blif 2 ->daVinci 3 -> DDcal + ** 4 -> factored form */ + char *dumpfile; /* filename for dump */ + int store; /* iteration at which to store Reached */ + char *storefile; /* filename for storing Reached */ + int load; /* load initial states from file */ + char *loadfile; /* filename for loading states */ + int verb; /* level of verbosity */ +} NtrOptions; + +typedef struct NtrHeapSlot { + void *item; + int key; +} NtrHeapSlot; + +typedef struct NtrHeap { + int size; + int nslots; + NtrHeapSlot *slots; +} NtrHeap; + +typedef struct NtrPartTR { + int nparts; /* number of parts */ + DdNode **part; /* array of parts */ + DdNode **icube; /* quantification cubes for image */ + DdNode **pcube; /* quantification cubes for preimage */ + DdNode **nscube; /* next state variables in each part */ + DdNode *preiabs; /* present state vars and inputs in no part */ + DdNode *prepabs; /* inputs in no part */ + DdNode *xw; /* cube of all present states and PIs */ + NtrHeap *factors; /* factors extracted from the image */ + int nlatches; /* number of latches */ + DdNode **x; /* array of present state variables */ + DdNode **y; /* array of next state variables */ +} NtrPartTR; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef TRUE +# define TRUE 1 +#endif +#ifndef FALSE +# define FALSE 0 +#endif + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if the two arguments are identical strings.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define STRING_EQUAL(s1,s2) (strcmp((s1),(s2)) == 0) + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern int Ntr_buildDDs (BnetNetwork *net, DdManager *dd, NtrOptions *option, BnetNetwork *net2); +extern NtrPartTR * Ntr_buildTR (DdManager *dd, BnetNetwork *net, NtrOptions *option, int image); +extern DdNode * Ntr_TransitiveClosure (DdManager *dd, NtrPartTR *TR, NtrOptions *option); +extern int Ntr_Trav (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern int Ntr_SCC (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern int Ntr_ClosureTrav (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern void Ntr_freeTR (DdManager *dd, NtrPartTR *TR); +extern NtrPartTR * Ntr_cloneTR (NtrPartTR *TR); +extern DdNode * Ntr_initState (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern DdNode * Ntr_getStateCube (DdManager *dd, BnetNetwork *net, char *filename, int pr); +extern int Ntr_Envelope (DdManager *dd, NtrPartTR *TR, FILE *dfp, NtrOptions *option); +extern int Ntr_TestMinimization (DdManager *dd, BnetNetwork *net1, BnetNetwork *net2, NtrOptions *option); +extern int Ntr_TestDensity (DdManager *dd, BnetNetwork *net1, NtrOptions *option); +extern int Ntr_TestDecomp (DdManager *dd, BnetNetwork *net1, NtrOptions *option); +extern int Ntr_VerifyEquivalence (DdManager *dd, BnetNetwork *net1, BnetNetwork *net2, NtrOptions *option); +extern int Ntr_TestCofactorEstimate (DdManager * dd, BnetNetwork * net, NtrOptions * option); +extern int Ntr_TestClipping (DdManager *dd, BnetNetwork *net1, BnetNetwork *net2, NtrOptions *option); +extern int Ntr_TestEquivAndContain (DdManager *dd, BnetNetwork *net1, BnetNetwork *net2, NtrOptions *option); +extern int Ntr_TestClosestCube (DdManager * dd, BnetNetwork * net, NtrOptions * option); +extern int Ntr_TestTwoLiteralClauses (DdManager * dd, BnetNetwork * net1, NtrOptions * option); +extern int Ntr_TestCharToVect(DdManager * dd, BnetNetwork * net1, NtrOptions * option); +extern int Ntr_maxflow (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern double Ntr_maximum01Flow (DdManager *bdd, DdNode *sx, DdNode *ty, DdNode *E, DdNode **F, DdNode **cut, DdNode **x, DdNode **y, DdNode **z, int n, int pr); +extern int Ntr_testZDD (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern int Ntr_testISOP (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern NtrHeap * Ntr_InitHeap (int size); +extern void Ntr_FreeHeap (NtrHeap *heap); +extern int Ntr_HeapInsert (NtrHeap *heap, void *item, int key); +extern int Ntr_HeapExtractMin (NtrHeap *heap, void *item, int *key); +extern int Ntr_HeapCount (NtrHeap *heap); +extern NtrHeap * Ntr_HeapClone (NtrHeap *source); +extern int Ntr_TestHeap (NtrHeap *heap, int i); +extern int Ntr_ShortestPaths (DdManager *dd, BnetNetwork *net, NtrOptions *option); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* _NTR */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntrBddTest.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrBddTest.c new file mode 100644 index 000000000..a5e1ae190 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrBddTest.c @@ -0,0 +1,2315 @@ +/**CFile*********************************************************************** + + FileName [ntrBddTest.c] + + PackageName [ntr] + + Synopsis [BDD test functions for the nanotrav program.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: ntrBddTest.c,v 1.22 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ntrTestMinimizationAux (DdManager *dd, BnetNetwork *net1, DdNode *f, char *name, DdNode *c, char *cname, NtrOptions *option); +static int ntrTestDensityAux (DdManager *dd, BnetNetwork *net, DdNode *f, char *name, NtrOptions *option); +static int ntrTestDecompAux (DdManager *dd, BnetNetwork *net, DdNode *f, char *name, NtrOptions *option); +static int ntrTestCofEstAux (DdManager * dd, BnetNetwork * net, DdNode * f, char * name, NtrOptions * option); +static int ntrTestClippingAux (DdManager *dd, BnetNetwork *net1, DdNode *f, char *name, DdNode *g, char *gname, NtrOptions *option); +static int ntrTestEquivAndContainAux (DdManager *dd, BnetNetwork *net1, DdNode *f, char *fname, DdNode *g, char *gname, DdNode *d, char *dname, NtrOptions *option); +static int ntrTestClosestCubeAux (DdManager *dd, BnetNetwork *net, DdNode *f, char *fname, DdNode *g, char *gname, DdNode **vars, NtrOptions *option); +static int ntrTestCharToVect(DdManager * dd, DdNode * f, NtrOptions *option); +#if 0 +static DdNode * ntrCompress1 (DdManager *dd, DdNode *f, int nvars, int threshold); +#endif +static DdNode * ntrCompress2 (DdManager *dd, DdNode *f, int nvars, int threshold); +static BnetNode * ntrNodeIsBuffer (BnetNode *nd, st_table *hash); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Tests BDD minimization functions.] + + Description [Tests BDD minimization functions, including + leaf-identifying compaction, squeezing, and restrict. This function + uses as constraint the first output of net2 and computes positive + and negative cofactors of all the outputs of net1. For each + cofactor, it checks whether compaction was safe (cofactor not larger + than original function) and that the expansion based on each + minimization function (used as a generalized cofactor) equals the + original function. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestMinimization( + DdManager * dd, + BnetNetwork * net1, + BnetNetwork * net2, + NtrOptions * option) +{ + DdNode *f; + DdNode *c = NULL; + char *cname = NULL; + BnetNode *node; + int i; + int result; + int nsize, csize; + + if (option->second == FALSE) return(1); + + (void) printf("Testing BDD minimization algorithms\n"); + /* Use largest output of second network as constraint. */ + csize = -1; + for (i = 0; i < net2->noutputs; i++) { + if (!st_lookup(net2->hash,net2->outputs[i],&node)) { + return(0); + } + nsize = Cudd_DagSize(node->dd); + if (nsize > csize) { + c = node->dd; + cname = node->name; + csize = nsize; + } + } + if (c == NULL || cname == NULL) return(0); + (void) printf("TEST-MINI: Constrain (%s) %d nodes\n", + cname, Cudd_DagSize(c)); + + if (option->node == NULL) { + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestMinimizationAux(dd,net1,f,node->name,c,cname, + option); + if (result == 0) return(0); + } + } else { + if (!st_lookup(net1->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestMinimizationAux(dd,net1,f,option->node,c,cname,option); + if (result == 0) return(0); + } + + return(1); + +} /* end of Ntr_TestMinimization */ + + +/**Function******************************************************************** + + Synopsis [Tests BDD density-related functions.] + + Description [Tests BDD density-related functions. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestDensity( + DdManager * dd, + BnetNetwork * net1, + NtrOptions * option) +{ + DdNode *f; + BnetNode *node; + int i; + int result; + + if (option->density == FALSE) return(1); + + (void) printf("Testing BDD density-related algorithms\n"); + if (option->node == NULL) { + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestDensityAux(dd,net1,f,node->name,option); + if (result == 0) return(0); + } + } else { + if (!st_lookup(net1->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestDensityAux(dd,net1,f,option->node,option); + if (result == 0) return(0); + } + + return(1); + +} /* end of Ntr_TestDensity */ + + +/**Function******************************************************************** + + Synopsis [Tests BDD decomposition functions.] + + Description [Tests BDD decomposition functions. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestDecomp( + DdManager * dd, + BnetNetwork * net1, + NtrOptions * option) +{ + DdNode *f; + BnetNode *node; + int i; + int result; + + if (option->decomp == FALSE) return(1); + + (void) printf("Testing BDD decomposition algorithms\n"); + if (option->node == NULL) { + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestDecompAux(dd,net1,f,node->name,option); + if (result == 0) return(0); + } + } else { + if (!st_lookup(net1->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestDecompAux(dd,net1,f,option->node,option); + if (result == 0) return(0); + } + + return(1); + +} /* end of ntrTestDecomp */ + + +/**Function******************************************************************** + + Synopsis [Verify equivalence of combinational networks.] + + Description [Verify equivalence of combinational networks. + Returns 1 if successful and if the networks are equivalent; -1 if + successful, but the networks are not equivalent; 0 otherwise. + The two networks are supposed to have the same names for inputs and + outputs. The only exception is that the second network may miss + output buffers that are present in the first network. This function tries + to match both the output and the input of the buffer.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_VerifyEquivalence( + DdManager * dd, + BnetNetwork * net1, + BnetNetwork * net2, + NtrOptions * option) +{ + BnetNode *node; + char *oname; + DdNode *odd1, *odd2; + int i; + int pr; + + (void) printf("Testing equivalence\n"); + if (net2->noutputs != net1->noutputs) { + (void) printf("The two networks have different number of outputs\n"); + (void) printf(" %s has %d outputs\n %s has %d outputs\n", + net1->name, net1->noutputs, net2->name, net2->noutputs); + return(-1); + } + if (net2->nlatches != net1->nlatches) { + (void) printf("The two networks have different number of latches\n"); + (void) printf(" %s has %d latches\n %s has %d latches\n", + net1->name, net1->nlatches, net2->name, net2->nlatches); + return(-1); + } + + pr = option->verb; + for (i = 0; i < net1->noutputs; i++) { + oname = net1->outputs[i]; + if (!st_lookup(net1->hash,oname,&node)) { + return(0); + } + odd1 = node->dd; + (void) printf("%s", oname); + Cudd_PrintDebug(dd, node->dd, Cudd_ReadSize(dd), pr); + if (!st_lookup(net2->hash,oname,&node)) { + BnetNode *inpnd; + if ((inpnd = ntrNodeIsBuffer(node,net1->hash)) == NULL || + !st_lookup(net2->hash,inpnd->name,&node)) { + (void) printf("Output %s missing from network %s\n", + oname, net2->name); + return(-1); + } else { + odd2 = inpnd->dd; + } + } else { + odd2 = node->dd; + } + if (odd1 != odd2) { + (void) printf("Output %s is not equivalent\n", oname); + return(-1); + } + } + return(1); + +} /* end of Ntr_VerifyEquivalence */ + + +/**Function******************************************************************** + + Synopsis [Tests BDD cofactor estimate functions.] + + Description [Tests BDD cofactor estimate functions. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestCofactorEstimate( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + DdNode *f; + BnetNode *node; + int i; + int result; + + if (option->cofest == FALSE) return(1); + + (void) printf("Testing BDD cofactor estimation algorithms\n"); + if (option->node == NULL) { + for (i = 0; i < net->noutputs; i++) { + if (!st_lookup(net->hash,net->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestCofEstAux(dd,net,f,node->name,option); + if (result == 0) return(0); + } + } else { + if (!st_lookup(net->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestCofEstAux(dd,net,f,option->node,option); + if (result == 0) return(0); + } + + return(1); + +} /* end of Ntr_TestCofactorEstimate */ + + +/**Function******************************************************************** + + Synopsis [Tests BDD clipping functions.] + + Description [Tests BDD clipping functions. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestClipping( + DdManager * dd, + BnetNetwork * net1, + BnetNetwork * net2, + NtrOptions * option) +{ + DdNode *f; + DdNode *g = NULL; + char *gname = NULL; + BnetNode *node; + int i; + int result; + int nsize, gsize; + + if (option->clip < 0.0) return(1); + + (void) printf("Testing BDD clipping algorithms\n"); + /* Use largest output of second network as second operand. */ + gsize = -1; + for (i = 0; i < net2->noutputs; i++) { + if (!st_lookup(net2->hash,net2->outputs[i],&node)) { + return(0); + } + nsize = Cudd_DagSize(node->dd); + if (nsize > gsize) { + g = node->dd; + gname = node->name; + gsize = nsize; + } + } + if (g == NULL || gname == NULL) return(0); + (void) printf("TEST-CLIP: Second operand (%s) %d nodes\n", + gname, Cudd_DagSize(g)); + + if (option->node == NULL) { + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestClippingAux(dd,net1,f,node->name,g,gname,option); + if (result == 0) return(0); + } + } else { + if (!st_lookup(net1->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestClippingAux(dd,net1,f,option->node,g,gname,option); + if (result == 0) return(0); + } + + return(1); + +} /* end of Ntr_TestClipping */ + + +/**Function******************************************************************** + + Synopsis [Tests BDD equivalence and containment with don't cares.] + + Description [Tests functions for BDD equivalence and containment + with don't cares, including Cudd_EquivDC and Cudd_bddLeqUnless. This + function uses as care set the first output of net2 and checkes + equivalence and containment for of all the output pairs of net1. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestEquivAndContain( + DdManager *dd, + BnetNetwork *net1, + BnetNetwork *net2, + NtrOptions *option) +{ + DdNode *f, *g; + DdNode *d = NULL; + char *dname = NULL; + BnetNode *node1, *node2; + int i, j; + int result; + int nsize, dsize; + + if (option->dontcares == FALSE) return(1); + + (void) printf("Testing BDD equivalence and containment algorithms\n"); + /* Use largest output of second network as constraint. */ + dsize = -1; + for (i = 0; i < net2->noutputs; i++) { + if (!st_lookup(net2->hash,net2->outputs[i],&node1)) { + return(0); + } + nsize = Cudd_DagSize(node1->dd); + if (nsize > dsize) { + d = node1->dd; + dname = node1->name; + dsize = nsize; + } + } + if (d == NULL || dname == NULL) return(0); + (void) printf("TEST-DC: Don't care set (%s) %d nodes\n", + dname, Cudd_DagSize(d)); + + if (option->node == NULL) { + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node1)) { + return(0); + } + f = node1->dd; + if (f == NULL) return(0); + for (j = 0; j < net1->noutputs; j++) { + if (!st_lookup(net1->hash,net1->outputs[j],&node2)) { + return(0); + } + g = node2->dd; + if (g == NULL) return(0); + result = ntrTestEquivAndContainAux(dd,net1,f,node1->name,g, + node2->name,d,dname,option); + if (result == 0) return(0); + } + } + } else { + if (!st_lookup(net1->hash,option->node,&node1)) { + return(0); + } + f = node1->dd; + if (f == NULL) return(0); + for (j = 0; j < net1->noutputs; j++) { + if (!st_lookup(net1->hash,net1->outputs[j],&node2)) { + return(0); + } + g = node2->dd; + if (g == NULL) return(0); + result = ntrTestEquivAndContainAux(dd,net1,f,option->node, + g,node2->name,d,dname,option); + if (result == 0) return(0); + } + } + + return(1); + +} /* end of Ntr_TestEquivAndContain */ + + +/**Function******************************************************************** + + Synopsis [Tests the Cudd_bddClosestCube function.] + + Description [Tests the Cudd_bddClosestCube function. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestClosestCube( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + DdNode *f, *g; + BnetNode *node1, *node2; + int i, j, nvars; + int result; + DdNode **vars; + double calls; + + if (option->closestCube == FALSE) return(1); + + (void) printf("Testing Cudd_bddClosestCube\n"); + nvars = Cudd_ReadSize(dd); + vars = ALLOC(DdNode *, nvars); + if (vars == NULL) return(0); + for (i = 0; i < nvars; i++) { + vars[i] = Cudd_bddIthVar(dd,i); + } + calls = Cudd_ReadRecursiveCalls(dd); + if (option->node == NULL) { + for (i = 0; i < net->noutputs; i++) { + if (!st_lookup(net->hash,net->outputs[i],&node1)) { + FREE(vars); + return(0); + } + f = node1->dd; + if (f == NULL) { + FREE(vars); + return(0); + } + for (j = 0; j < net->noutputs; j++) { + if (!st_lookup(net->hash,net->outputs[j],&node2)) { + FREE(vars); + return(0); + } + g = node2->dd; + if (g == NULL) { + FREE(vars); + return(0); + } + result = ntrTestClosestCubeAux(dd,net,f,node1->name,g, + node2->name,vars,option); + if (result == 0) { + FREE(vars); + return(0); + } + } + } + } else { + if (!st_lookup(net->hash,option->node,&node1)) { + FREE(vars); + return(0); + } + f = node1->dd; + if (f == NULL) { + FREE(vars); + return(0); + } + for (j = 0; j < net->noutputs; j++) { + if (!st_lookup(net->hash,net->outputs[j],&node2)) { + FREE(vars); + return(0); + } + g = node2->dd; + if (g == NULL) { + FREE(vars); + return(0); + } + result = ntrTestClosestCubeAux(dd,net,f,option->node,g, + node2->name,vars,option); + if (result == 0) { + FREE(vars); + return(0); + } + } + } + (void) printf("End of test. Performed %.0f recursive calls.\n", + Cudd_ReadRecursiveCalls(dd) - calls); + FREE(vars); + return(1); + +} /* end of Ntr_TestClosestCube */ + + +/**Function******************************************************************** + + Synopsis [Tests extraction of two-literal clauses.] + + Description [Tests extraction of two-literal clauses. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestTwoLiteralClauses( + DdManager * dd, + BnetNetwork * net1, + NtrOptions * option) +{ + DdNode *f; + BnetNode *node; + int result; + char **inames = NULL; + int i; + + if (option->clauses == FALSE) return(1); + + /* Initialize data structures. */ + inames = ALLOC(char *,Cudd_ReadSize(dd)); + if (inames == NULL) return(0); + for (i = 0; i < Cudd_ReadSize(dd); i++) { + inames[i] = NULL; + } + + /* Find the input names. */ + for (i = 0; i < net1->ninputs; i++) { + if (!st_lookup(net1->hash,net1->inputs[i],&node)) { + FREE(inames); + return(0); + } + inames[node->var] = net1->inputs[i]; + } + for (i = 0; i < net1->nlatches; i++) { + if (!st_lookup(net1->hash,net1->latches[i][1],&node)) { + FREE(inames); + return(0); + } + inames[node->var] = net1->latches[i][1]; + } + + (void) printf("Testing extraction of two literal clauses\n"); + if (option->node == NULL) { + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) { + FREE(inames); + return(0); + } + (void) printf("*** %s ***\n", net1->outputs[i]); + result = Cudd_PrintTwoLiteralClauses(dd, f, inames, NULL); + if (result == 0) { + FREE(inames); + return(0); + } + } + } else { + if (!st_lookup(net1->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) { + FREE(inames); + return(0); + } + (void) printf("*** %s ***\n", option->node); + result = Cudd_PrintTwoLiteralClauses(dd, f, inames, NULL); + if (result == 0) { + FREE(inames); + return(0); + } + } + + FREE(inames); + return(1); + +} /* end of Ntr_TestTwoLiteralClauses */ + + +/**Function******************************************************************** + + Synopsis [Test char-to-vect conversion.] + + Description [Test char-to-vect conversion. Returns 1 if successful; + 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestCharToVect( + DdManager * dd, + BnetNetwork * net1, + NtrOptions * option) +{ + DdNode *f; + int result; + BnetNode *node; + int i; + + if (option->char2vect == FALSE) return(1); + + (void) printf("Testing char-to-vect\n"); + if (net1->nlatches > 0) { + NtrPartTR *T; + T = Ntr_buildTR(dd,net1,option,NTR_IMAGE_MONO); + result = ntrTestCharToVect(dd,T->part[0],option); + Ntr_freeTR(dd,T); + } else if (option->node == NULL) { + result = 1; + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + (void) printf("*** %s ***\n", net1->outputs[i]); + result = ntrTestCharToVect(dd,f,option); + if (result == 0) return(0); + } + } else { + if (!st_lookup(net1->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestCharToVect(dd,f,option); + } + return(result); + +} /* end of Ntr_TestCharToVect */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Processes one BDD for Ntr_TestMinimization.] + + Description [Processes one BDD for Ntr_TestMinimization. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestMinimization] + +******************************************************************************/ +static int +ntrTestMinimizationAux( + DdManager * dd, + BnetNetwork * net1, + DdNode * f, + char * name, + DdNode * c, + char * cname, + NtrOptions * option) +{ + DdNode *com1, *com0, *min1, *min0, *sq1, *sq0; + DdNode *rs1, *rs0, *cs1, *cs0, *na1, *na0, *a1, *a0; + DdNode *g, *u1, *l1, *u0, *l0; + int pr, nvars; + int sizeF, sizeMin1, sizeMin0, sizeSq1, sizeSq0, sizeCom1, sizeCom0; + int sizeRs1, sizeRs0, sizeCs1, sizeCs0, sizeNa1, sizeNa0, sizeA1, sizeA0; + static char *onames[11]; + DdNode *outputs[11]; + DdNode *fc[2]; + + pr = option->verb; + fc[0] = f; fc[1] = c; + nvars = Cudd_VectorSupportSize(dd,fc,2); + if (nvars == CUDD_OUT_OF_MEM) return(0); + (void) printf("TEST-MINI:: %s\n", name); + (void) printf("T-M "); + Cudd_PrintDebug(dd, f, nvars, pr); + sizeF = Cudd_DagSize(f); + + /* Compute positive generalized cofactor. */ + com1 = Cudd_bddLICompaction(dd, f, c); + if (com1 == NULL) { + (void) printf("TEST-MINI: LI-compaction failed (1).\n"); + return(0); + } + Cudd_Ref(com1); + (void) printf("T-M L1 "); + Cudd_PrintDebug(dd, com1, nvars, pr); + sizeCom1 = Cudd_DagSize(com1); + if (sizeCom1 > sizeF) { + (void) printf("TEST-MINI: LI-compaction not safe (1).\n"); + return(0); + } + min1 = Cudd_bddMinimize(dd, f, c); + if (min1 == NULL) { + (void) printf("TEST-MINI: minimize failed (1).\n"); + return(0); + } + Cudd_Ref(min1); + (void) printf("T-M M1 "); + Cudd_PrintDebug(dd, min1, nvars, pr); + sizeMin1 = Cudd_DagSize(min1); + if (sizeMin1 > sizeF) { + (void) printf("TEST-MINI: minimize not safe (1).\n"); + return(0); + } + rs1 = Cudd_bddRestrict(dd, f, c); + if (rs1 == NULL) { + (void) printf("TEST-MINI: restrict failed (1).\n"); + return(0); + } + Cudd_Ref(rs1); + (void) printf("T-M R1 "); + Cudd_PrintDebug(dd, rs1, nvars, pr); + sizeRs1 = Cudd_DagSize(rs1); + cs1 = Cudd_bddConstrain(dd, f, c); + if (cs1 == NULL) { + (void) printf("TEST-MINI: constrain failed (1).\n"); + return(0); + } + Cudd_Ref(cs1); + (void) printf("T-M C1 "); + Cudd_PrintDebug(dd, cs1, nvars, pr); + sizeCs1 = Cudd_DagSize(cs1); + l1 = Cudd_bddAnd(dd, f, c); + if (l1 == NULL) { + (void) printf("TEST-MINI: lower bound failed (1).\n"); + return(0); + } + Cudd_Ref(l1); + u1 = Cudd_bddOr(dd, f, Cudd_Not(c)); + if (u1 == NULL) { + (void) printf("TEST-MINI: upper bound failed (1).\n"); + return(0); + } + Cudd_Ref(u1); + (void) printf("TEST-MINI: (lb,ub) : (%d,%d) nodes\n", + Cudd_DagSize(l1), Cudd_DagSize(u1)); + sq1 = Cudd_bddSqueeze(dd, l1, u1); + if (sq1 == NULL) { + (void) printf("TEST-MINI: squeezing failed (1).\n"); + return(0); + } + Cudd_Ref(sq1); + sizeSq1 = Cudd_DagSize(sq1); + if (sizeSq1 > sizeF) { + Cudd_RecursiveDeref(dd,sq1); + sq1 = f; + Cudd_Ref(sq1); + sizeSq1 = sizeF; + } + (void) printf("T-M S1 "); + Cudd_PrintDebug(dd, sq1, nvars, pr); + na1 = Cudd_bddNPAnd(dd, f, c); + if (na1 == NULL) { + (void) printf("TEST-MINI: NPand failed (1).\n"); + return(0); + } + Cudd_Ref(na1); + (void) printf("T-M N1 "); + Cudd_PrintDebug(dd, na1, nvars, pr); + sizeNa1 = Cudd_DagSize(na1); + a1 = Cudd_bddAnd(dd, f, c); + if (a1 == NULL) { + (void) printf("TEST-MINI: and failed (1).\n"); + return(0); + } + Cudd_Ref(a1); + (void) printf("T-M A1 "); + Cudd_PrintDebug(dd, a1, nvars, pr); + sizeA1 = Cudd_DagSize(a1); + (void) printf("TEST-MINI: f %d comp %d mini %d rest %d cons %d sque %d na %d and %d\n", + sizeF, sizeCom1, sizeMin1, sizeRs1, sizeCs1, sizeSq1, sizeNa1, sizeA1); + if (option->bdddump) { + onames[0] = name; outputs[0] = f; + onames[1] = cname; outputs[1] = c; + onames[2] = (char *) "cons"; outputs[2] = cs1; + onames[3] = (char *) "rest"; outputs[3] = rs1; + onames[4] = (char *) "comp"; outputs[4] = com1; + onames[5] = (char *) "mini"; outputs[5] = min1; + onames[6] = (char *) "sqee"; outputs[6] = sq1; + onames[7] = (char *) "lb"; outputs[7] = l1; + onames[8] = (char *) "ub"; outputs[8] = u1; + onames[9] = (char *) "na"; outputs[9] = na1; + onames[10] = (char *) "and"; outputs[10] = a1; + if (!Bnet_bddArrayDump(dd, net1, option->dumpfile, outputs, onames, + 11, option->dumpFmt)) + return(0); + } + Cudd_RecursiveDeref(dd,l1); + Cudd_RecursiveDeref(dd,u1); + + /* Compute negative generalized cofactor. */ + (void) printf("TEST-MINI:: %s\n", name); + (void) printf("T-M "); + Cudd_PrintDebug(dd, f, nvars, pr); + + com0 = Cudd_bddLICompaction(dd, f, Cudd_Not(c)); + if (com0 == NULL) { + (void) printf("TEST-MINI: LI-compaction failed (2).\n"); + return(0); + } + Cudd_Ref(com0); + (void) printf("T-M L0 "); + Cudd_PrintDebug(dd, com0, nvars, pr); + sizeCom0 = Cudd_DagSize(com0); + if (sizeCom0 > sizeF) { + (void) printf("TEST-MINI: LI-compaction not safe (2).\n"); + return(0); + } + min0 = Cudd_bddMinimize(dd, f, Cudd_Not(c)); + if (min0 == NULL) { + (void) printf("TEST-MINI: minimize failed (2).\n"); + return(0); + } + Cudd_Ref(min0); + (void) printf("T-M M0 "); + Cudd_PrintDebug(dd, min0, nvars, pr); + sizeMin0 = Cudd_DagSize(min0); + if (sizeMin0 > sizeF) { + (void) printf("TEST-MINI: minimize not safe (2).\n"); + return(0); + } + rs0 = Cudd_bddRestrict(dd, f, Cudd_Not(c)); + if (rs0 == NULL) { + (void) printf("TEST-MINI: restrict failed (2).\n"); + return(0); + } + Cudd_Ref(rs0); + (void) printf("T-M R0 "); + Cudd_PrintDebug(dd, rs0, nvars, pr); + sizeRs0 = Cudd_DagSize(rs0); + cs0 = Cudd_bddConstrain(dd, f, Cudd_Not(c)); + if (cs0 == NULL) { + (void) printf("TEST-MINI: constrain failed (2).\n"); + return(0); + } + Cudd_Ref(cs0); + (void) printf("T-M C0 "); + Cudd_PrintDebug(dd, cs0, nvars, pr); + sizeCs0 = Cudd_DagSize(cs0); + + l0 = Cudd_bddAnd(dd, f, Cudd_Not(c)); + if (l0 == NULL) { + (void) printf("TEST-MINI: lower bound failed (2).\n"); + return(0); + } + Cudd_Ref(l0); + u0 = Cudd_bddOr(dd, f, c); + if (u0 == NULL) { + (void) printf("TEST-MINI: upper bound failed (2).\n"); + return(0); + } + Cudd_Ref(u0); + (void) printf("TEST-MINI: (lb,ub) : (%d,%d) nodes\n", + Cudd_DagSize(l0), Cudd_DagSize(u0)); + sq0 = Cudd_bddSqueeze(dd, l0, u0); + if (sq0 == NULL) { + (void) printf("TEST-MINI: squeezing failed (2).\n"); + return(0); + } + Cudd_Ref(sq0); + Cudd_RecursiveDeref(dd,l0); + Cudd_RecursiveDeref(dd,u0); + sizeSq0 = Cudd_DagSize(sq0); + if (sizeSq0 > sizeF) { + Cudd_RecursiveDeref(dd,sq0); + sq0 = f; + Cudd_Ref(sq0); + sizeSq0 = sizeF; + } + (void) printf("T-M S0 "); + Cudd_PrintDebug(dd, sq0, nvars, pr); + na0 = Cudd_bddNPAnd(dd, f, Cudd_Not(c)); + if (na0 == NULL) { + (void) printf("TEST-MINI: NPand failed (2).\n"); + return(0); + } + Cudd_Ref(na0); + (void) printf("T-M N0 "); + Cudd_PrintDebug(dd, na0, nvars, pr); + sizeNa0 = Cudd_DagSize(na0); + a0 = Cudd_bddAnd(dd, f, Cudd_Not(c)); + if (a0 == NULL) { + (void) printf("TEST-MINI: and failed (2).\n"); + return(0); + } + Cudd_Ref(a0); + (void) printf("T-M A0 "); + Cudd_PrintDebug(dd, a0, nvars, pr); + sizeA0 = Cudd_DagSize(a0); + (void) printf("TEST-MINI: f %d comp %d mini %d rest %d cons %d sque %d na %d, and %d\n", + sizeF, sizeCom0, sizeMin0, sizeRs0, sizeCs0, sizeSq0, sizeNa0, sizeA0); + + /* Check fundamental identity. */ + g = Cudd_bddIte(dd,c,com1,com0); + if (g == NULL) { + (void) printf("TEST-MINI: LI-compaction failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: LI-compaction failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,com1); + Cudd_RecursiveDeref(dd,com0); + Cudd_RecursiveDeref(dd,g); + g = Cudd_bddIte(dd,c,min1,min0); + if (g == NULL) { + (void) printf("TEST-MINI: minimize failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: minimize failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,min1); + Cudd_RecursiveDeref(dd,min0); + Cudd_RecursiveDeref(dd,g); + g = Cudd_bddIte(dd,c,sq1,sq0); + if (g == NULL) { + (void) printf("TEST-MINI: squeezing failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: squeezing failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,sq1); + Cudd_RecursiveDeref(dd,sq0); + Cudd_RecursiveDeref(dd,g); + g = Cudd_bddIte(dd,c,rs1,rs0); + if (g == NULL) { + (void) printf("TEST-MINI: restrict failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: restrict failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,rs1); + Cudd_RecursiveDeref(dd,rs0); + Cudd_RecursiveDeref(dd,g); + g = Cudd_bddIte(dd,c,cs1,cs0); + if (g == NULL) { + (void) printf("TEST-MINI: constrain failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: constrain failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,cs1); + Cudd_RecursiveDeref(dd,cs0); + Cudd_RecursiveDeref(dd,g); + g = Cudd_bddIte(dd,c,na1,na0); + if (g == NULL) { + (void) printf("TEST-MINI: NPand failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: NPand failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,na1); + Cudd_RecursiveDeref(dd,na0); + Cudd_RecursiveDeref(dd,g); + g = Cudd_bddIte(dd,c,a1,a0); + if (g == NULL) { + (void) printf("TEST-MINI: and failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: and failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,a1); + Cudd_RecursiveDeref(dd,a0); + Cudd_RecursiveDeref(dd,g); + + return(1); + +} /* end of ntrTestMinimizationAux */ + + +/**Function******************************************************************** + + Synopsis [Processes one BDD for Ntr_TestDensity.] + + Description [Processes one BDD for Ntr_TestDensity. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestDensity ntrCompress1] + +******************************************************************************/ +static int +ntrTestDensityAux( + DdManager * dd, + BnetNetwork * net, + DdNode * f, + char * name, + NtrOptions * option) +{ + DdNode *s, *b, *hb, *sp, *ua, *c1, *c2; + int pr; + int result; + int nvars; + int size, sizeS; + double densityF, densityB, densityS, densityHB, densitySP, densityUA; + double densityC1, densityC2; + char *onames[8]; + DdNode *outputs[8]; + + result = 1; + pr = option->verb; + nvars = Cudd_SupportSize(dd,f); + if (nvars == CUDD_OUT_OF_MEM) return(0); + densityF = Cudd_Density(dd,f,nvars); + (void) printf("TEST-DENSITY:: %s (%d variables)\n", name, nvars); + if (pr > 0) { + (void) printf("T-D (%g)", densityF); + Cudd_PrintDebug(dd, f, nvars, pr); + (void) printf("T-D APA "); + if (!Cudd_ApaPrintMinterm(stdout, dd, f, nvars)) + result = 0; + } + /* Test remapping underapproximation. */ + /* s = Cudd_SubsetRemap(dd,f); */ + s = Cudd_RemapUnderApprox(dd,f,nvars,0,option->quality); + if (s == NULL) { + (void) printf("TEST-DENSITY: computation failed\n"); + return(0); + } + Cudd_Ref(s); + sizeS = Cudd_DagSize(s); + densityS = Cudd_Density(dd,s,nvars); + if (pr > 0) { + (void) printf("T-D ID (%g)", densityS); + Cudd_PrintDebug(dd, s, nvars, pr); + } + if (!Cudd_bddLeq(dd,s,f)) { + (void) printf("TEST-DENSITY: result not a subset\n"); + result = 0; + } + if (densityF > densityS) { + (void) printf("TEST-DENSITY: result less dense\n"); + /* result = 0; */ + } + size = sizeS; + /* Test biased underapproximation. */ + b = Cudd_BiasedUnderApprox(dd,f,Cudd_Not(s),nvars,0, + option->quality*1.1,option->quality*0.5); + if (b == NULL) { + (void) printf("TEST-DENSITY: computation failed\n"); + return(0); + } + Cudd_Ref(b); + densityB = Cudd_Density(dd,b,nvars); + if (pr > 0) { + (void) printf("T-D BU (%g)", densityB); + Cudd_PrintDebug(dd, b, nvars, pr); + } + if (!Cudd_bddLeq(dd,b,f)) { + (void) printf("TEST-DENSITY: result not a subset\n"); + result = 0; + } + if (densityF > densityB) { + (void) printf("TEST-DENSITY: result less dense\n"); + /* result = 0; */ + } + /* Test heavy-branch subsetting. */ + hb = Cudd_SubsetHeavyBranch(dd, f, nvars, size); + if (hb == NULL) { + (void) printf("TEST-DENSITY: HB computation failed\n"); + Cudd_RecursiveDeref(dd,s); + return(0); + } + Cudd_Ref(hb); + densityHB = Cudd_Density(dd,hb,nvars); + if (pr > 0) { + (void) printf("T-D HB (%g)", densityHB); + Cudd_PrintDebug(dd, hb, nvars, pr); + } + if (!Cudd_bddLeq(dd,hb,f)) { + (void) printf("TEST-DENSITY: HB not a subset\n"); + result = 0; + } + /* Test short paths subsetting. */ + sp = Cudd_SubsetShortPaths(dd, f, nvars, size, 0); + if (sp == NULL) { + (void) printf("TEST-DENSITY: SP computation failed\n"); + Cudd_RecursiveDeref(dd,s); + Cudd_RecursiveDeref(dd,hb); + return(0); + } + Cudd_Ref(sp); + densitySP = Cudd_Density(dd,sp,nvars); + if (pr > 0) { + (void) printf("T-D SP (%g)", densitySP); + Cudd_PrintDebug(dd, sp, nvars, pr); + } + if (!Cudd_bddLeq(dd,sp,f)) { + (void) printf("TEST-DENSITY: SP not a subset\n"); + result = 0; + } + /* Test underapproximation. */ + ua = Cudd_UnderApprox(dd,f,nvars,0,FALSE,option->quality); + if (ua == NULL) { + (void) printf("TEST-DENSITY: computation failed\n"); + Cudd_RecursiveDeref(dd,s); + Cudd_RecursiveDeref(dd,hb); + Cudd_RecursiveDeref(dd,sp); + return(0); + } + Cudd_Ref(ua); + densityUA = Cudd_Density(dd,ua,nvars); + if (pr > 0) { + (void) printf("T-D UA (%g)", densityUA); + Cudd_PrintDebug(dd, ua, nvars, pr); + } + if (!Cudd_bddLeq(dd,ua,f)) { + (void) printf("TEST-DENSITY: result not a subset\n"); + result = 0; + } + if (densityF > densityUA) { + (void) printf("TEST-DENSITY: result less dense\n"); + } + /* Test compress 2 method. */ + c1 = ntrCompress2(dd, f, nvars, size); + if (c1 == NULL) { + (void) printf("TEST-DENSITY: C1 computation failed\n"); + Cudd_RecursiveDeref(dd,s); + Cudd_RecursiveDeref(dd,hb); + Cudd_RecursiveDeref(dd,sp); + Cudd_RecursiveDeref(dd,ua); + return(0); + } + densityC1 = Cudd_Density(dd,c1,nvars); + if (pr > 0) { + (void) printf("T-D C1 (%g)", densityC1); + Cudd_PrintDebug(dd, c1, nvars, pr); + } + if (!Cudd_bddLeq(dd,c1,f)) { + (void) printf("TEST-DENSITY: C1 not a subset\n"); + result = 0; + } + /* Test compress subsetting. */ + c2 = Cudd_SubsetCompress(dd, f, nvars, size); + if (c2 == NULL) { + (void) printf("TEST-DENSITY: C2 computation failed\n"); + Cudd_RecursiveDeref(dd,s); + Cudd_RecursiveDeref(dd,hb); + Cudd_RecursiveDeref(dd,sp); + Cudd_RecursiveDeref(dd,ua); + Cudd_RecursiveDeref(dd,c1); + return(0); + } + Cudd_Ref(c2); + densityC2 = Cudd_Density(dd,c2,nvars); + if (pr > 0) { + (void) printf("T-D C2 (%g)", densityC2); + Cudd_PrintDebug(dd, c2, nvars, pr); + } + if (!Cudd_bddLeq(dd,c2,f)) { + (void) printf("TEST-DENSITY: C2 not a subset\n"); + result = 0; + } + /* Dump results if so requested. */ + if (option->bdddump) { + onames[0] = name; outputs[0] = f; + onames[1] = (char *) "id"; outputs[1] = s; + onames[2] = (char *) "bu"; outputs[2] = b; + onames[3] = (char *) "hb"; outputs[3] = hb; + onames[4] = (char *) "sp"; outputs[4] = sp; + onames[5] = (char *) "ua"; outputs[5] = ua; + onames[6] = (char *) "c1"; outputs[6] = c1; + onames[7] = (char *) "c2"; outputs[7] = c2; + result &= Bnet_bddArrayDump(dd, net, option->dumpfile, outputs, + onames, 8, option->dumpFmt); + } + + Cudd_RecursiveDeref(dd,s); + Cudd_RecursiveDeref(dd,b); + Cudd_RecursiveDeref(dd,hb); + Cudd_RecursiveDeref(dd,sp); + Cudd_RecursiveDeref(dd,ua); + Cudd_RecursiveDeref(dd,c1); + Cudd_RecursiveDeref(dd,c2); + + return(result); + +} /* end of ntrTestDensityAux */ + + +/**Function******************************************************************** + + Synopsis [Processes one BDD for Ntr_TestDecomp.] + + Description [Processes one BDD for Ntr_TestDecomp. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestDecomp] + +******************************************************************************/ +static int +ntrTestDecompAux( + DdManager * dd, + BnetNetwork * net, + DdNode * f, + char * name, + NtrOptions * option) +{ + DdNode *one, *g, *h, *product; + DdNode **A, **I, **G, **V; + int pr; + int i, result; + int nA, nI, nG, nV; + int nvars; + int sizeSa; + int sizeSi, sizeSg, sizeSv; + char *onames[9]; + DdNode *outputs[9]; + + result = 1; + pr = option->verb; + nvars = Cudd_SupportSize(dd,f); + if (nvars == CUDD_OUT_OF_MEM) return(0); + (void) printf("TEST-DECOMP:: %s (%d variables)\n", name, nvars); + if (pr > 0) { + (void) printf("T-d "); + Cudd_PrintDebug(dd, f, nvars, pr); + } + one = Cudd_ReadOne(dd); + + /* Test Cudd_bddApproxConjDecomp */ + nA = Cudd_bddApproxConjDecomp(dd,f,&A); + if (nA == 0) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + g = A[0]; + h = (nA == 2) ? A[1] : one; + sizeSa = Cudd_SharingSize(A,nA); + if (pr > 0) { + (void) printf("T-d SS : %d nodes\n", sizeSa); + (void) printf("T-d GS "); + Cudd_PrintDebug(dd, g, nvars, pr); + (void) printf("T-d HS "); + Cudd_PrintDebug(dd, h, nvars, pr); + } + product = Cudd_bddAnd(dd,g,h); + if (product == NULL) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + Cudd_Ref(product); + if (product != f) { + (void) printf("TEST-DECOMP: result not a decomposition\n"); + result = 0; + } + Cudd_RecursiveDeref(dd,product); + + /* Test Cudd_bddIterConjDecomp */ + nI = Cudd_bddIterConjDecomp(dd,f,&I); + if (nI == 0) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + g = I[0]; + h = (nI == 2) ? I[1] : one; + sizeSi = Cudd_SharingSize(I,nI); + if (pr > 0) { + (void) printf("T-d SI : %d nodes\n", sizeSi); + (void) printf("T-d GI "); + Cudd_PrintDebug(dd, g, nvars, pr); + (void) printf("T-d HI "); + Cudd_PrintDebug(dd, h, nvars, pr); + } + product = Cudd_bddAnd(dd,g,h); + if (product == NULL) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + Cudd_Ref(product); + if (product != f) { + (void) printf("TEST-DECOMP: result not a decomposition\n"); + result = 0; + } + Cudd_RecursiveDeref(dd,product); + + /* Test Cudd_bddGenConjDecomp */ + nG = Cudd_bddGenConjDecomp(dd,f,&G); + if (nG == 0) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + g = G[0]; + h = (nG == 2) ? G[1] : one; + sizeSg = Cudd_SharingSize(G,nG); + if (pr > 0) { + (void) printf("T-d SD : %d nodes\n", sizeSg); + (void) printf("T-d GD "); + Cudd_PrintDebug(dd, g, nvars, pr); + (void) printf("T-d HD "); + Cudd_PrintDebug(dd, h, nvars, pr); + } + product = Cudd_bddAnd(dd,g,h); + if (product == NULL) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + Cudd_Ref(product); + if (product != f) { + (void) printf("TEST-DECOMP: result not a decomposition\n"); + result = 0; + } + Cudd_RecursiveDeref(dd,product); + + /* Test Cudd_bddVarConjDecomp */ + nV = Cudd_bddVarConjDecomp(dd,f,&V); + if (nV == 0) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + g = V[0]; + h = (nV == 2) ? V[1] : one; + sizeSv = Cudd_SharingSize(V,nV); + if (pr > 0) { + (void) printf("T-d SQ : %d nodes\n", sizeSv); + (void) printf("T-d GQ "); + Cudd_PrintDebug(dd, g, nvars, pr); + (void) printf("T-d HQ "); + Cudd_PrintDebug(dd, h, nvars, pr); + } + product = Cudd_bddAnd(dd,g,h); + if (product == NULL) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + Cudd_Ref(product); + if (product != f) { + (void) printf("TEST-DECOMP: result not a decomposition\n"); + result = 0; + } + Cudd_RecursiveDeref(dd,product); + + /* Dump to file if requested. */ + if (option->bdddump) { + onames[0] = name; outputs[0] = f; + onames[1] = (char *) "ga"; outputs[1] = A[0]; + onames[2] = (char *) "ha"; outputs[2] = (nA == 2) ? A[1] : one; + onames[3] = (char *) "gi"; outputs[3] = I[0]; + onames[4] = (char *) "hi"; outputs[4] = (nI == 2) ? I[1] : one; + onames[5] = (char *) "gg"; outputs[5] = G[0]; + onames[6] = (char *) "hg"; outputs[6] = (nG == 2) ? G[1] : one; + onames[7] = (char *) "gv"; outputs[7] = V[0]; + onames[8] = (char *) "hv"; outputs[8] = (nV == 2) ? V[1] : one; + result &= Bnet_bddArrayDump(dd, net, option->dumpfile, outputs, + onames, 9, option->dumpFmt); + } + + /* Clean up. */ + for (i = 0; i < nA; i++) { + Cudd_RecursiveDeref(dd,A[i]); + } + for (i = 0; i < nI; i++) { + Cudd_RecursiveDeref(dd,I[i]); + } + for (i = 0; i < nG; i++) { + Cudd_RecursiveDeref(dd,G[i]); + } + for (i = 0; i < nV; i++) { + Cudd_RecursiveDeref(dd,V[i]); + } + FREE(A); + FREE(I); + FREE(G); + FREE(V); + + return(result); + +} /* end of ntrTestDecompAux */ + + +/**Function******************************************************************** + + Synopsis [Processes one BDD for Ntr_TestCofactorEstimate.] + + Description [Processes one BDD for Ntr_TestCofactorEstimate. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ntrTestCofEstAux( + DdManager * dd, + BnetNetwork * net, + DdNode * f, + char * name, + NtrOptions * option) +{ + DdNode *support, *scan, *cof; + int pr; + int nvars; + int exactSize, estimate, estimateS; + int totalExactSize = 0; + int totalEstimate = 0; + int totalEstimateS = 0; + int largestError = -1; + int largestErrorS = -1; + DdNode *errorVar = NULL; + + pr = option->verb; + support = Cudd_Support(dd,f); + if (support == NULL) return(0); + Cudd_Ref(support); + nvars = Cudd_DagSize(support) - 1; + scan = support; + while (!Cudd_IsConstant(scan)) { + DdNode *var = Cudd_bddIthVar(dd,scan->index); + cof = Cudd_Cofactor(dd,f,var); + if (cof == NULL) return(0); + Cudd_Ref(cof); + exactSize = Cudd_DagSize(cof); + totalExactSize += exactSize; + estimate = Cudd_EstimateCofactor(dd,f,scan->index,1); + totalEstimate += estimate; + if (estimate < exactSize) + (void) printf("Optimistic estimate!\n"); + if (estimate - exactSize > largestError) { + largestError = estimate - exactSize; + errorVar = var; + } + estimateS = Cudd_EstimateCofactorSimple(f,scan->index); + totalEstimateS += estimateS; + if (estimateS < exactSize) + (void) printf("Optimistic estimateS!\n"); + if (estimateS - exactSize > largestErrorS) + largestErrorS = estimateS - exactSize; + Cudd_RecursiveDeref(dd,cof); + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + (void) printf("TEST-COF:: %s (%d vars)", name, nvars); + Cudd_PrintDebug(dd, f, nvars, pr); + (void) printf("T-c : %d\n", totalExactSize); + (void) printf("T-c E : %d %d\n", totalEstimate, largestError); + (void) printf("T-c S : %d %d\n", totalEstimateS, largestErrorS); + + /* Dump to file if requested. */ + if (option->bdddump) { + char *onames[3]; + DdNode *outputs[3]; + int result; + cof = Cudd_Cofactor(dd,f,errorVar); + if (cof == NULL) return(0); + Cudd_Ref(cof); + onames[0] = name; outputs[0] = f; + onames[1] = (char *) "var"; outputs[1] = errorVar; + onames[2] = (char *) "cof"; outputs[2] = cof; + result = Bnet_bddArrayDump(dd, net, option->dumpfile, outputs, + onames, 3, option->dumpFmt); + Cudd_RecursiveDeref(dd,cof); + if (result == 0) return(0); + } + + return(1); + +} /* end of ntrTestCofEstAux */ + + +/**Function******************************************************************** + + Synopsis [Processes one BDD for Ntr_TestClipping.] + + Description [Processes one BDD for Ntr_TestClipping. It checks whether + clipping was correct. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestClipping] + +******************************************************************************/ +static int +ntrTestClippingAux( + DdManager * dd, + BnetNetwork * net1, + DdNode * f, + char * name, + DdNode * g, + char * gname, + NtrOptions * option) +{ + DdNode *prod, *sub, *sup; + DdNode *subF, *subG, *psub; + DdNode *supF, *supG, *psup; + int pr, nvars, depth; + int sizeProd, sizeSub, sizeSup; + static char *onames[7]; + DdNode *outputs[7]; + DdNode *operands[2]; + int retval = 1; + int threshold = (option->threshold < 0) ? 0 : option->threshold; + + pr = option->verb; + operands[0] = f; operands[1] = g; + nvars = Cudd_VectorSupportSize(dd,operands,2); + if (nvars == CUDD_OUT_OF_MEM) return(0); + depth = (int) ((double) nvars * option->clip); + (void) printf("TEST-CLIP:: %s depth = %d\n", name, depth); + (void) printf("T-C "); + Cudd_PrintDebug(dd, f, nvars, pr); + + /* Compute product. */ + prod = Cudd_bddAnd(dd, f, g); + if (prod == NULL) { + (void) printf("TEST-CLIP: product failed.\n"); + return(0); + } + Cudd_Ref(prod); + (void) printf("T-C P= "); + Cudd_PrintDebug(dd, prod, nvars, pr); + sizeProd = Cudd_DagSize(prod); + + /* Compute subset of product. */ + sub = Cudd_bddClippingAnd(dd, f, g, depth, 0); + if (sub == NULL) { + (void) printf("TEST-CLIP: subsetting product failed.\n"); + return(0); + } + Cudd_Ref(sub); + (void) printf("T-C P- "); + Cudd_PrintDebug(dd, sub, nvars, pr); + sizeSub = Cudd_DagSize(sub); + if (sizeSub > sizeProd) { + (void) printf("TEST-CLIP: subsetting product not safe.\n"); + } + + /* Compute product of subsets. */ + subF = Cudd_RemapUnderApprox(dd,f,nvars,threshold,option->quality); + if (subF == NULL) { + (void) printf("TEST-CLIP: subsetting of f failed.\n"); + return(0); + } + Cudd_Ref(subF); + subG = Cudd_RemapUnderApprox(dd,g,nvars,threshold,option->quality); + if (subF == NULL) { + (void) printf("TEST-CLIP: subsetting of g failed.\n"); + return(0); + } + Cudd_Ref(subG); + psub = Cudd_bddAnd(dd,subF,subG); + if (psub == NULL) { + (void) printf("TEST-CLIP: product of subsets failed.\n"); + return(0); + } + Cudd_Ref(psub); + Cudd_RecursiveDeref(dd,subF); + Cudd_RecursiveDeref(dd,subG); + (void) printf("T-C P< "); + Cudd_PrintDebug(dd, psub, nvars, pr); + + /* Compute superset of product. */ + sup = Cudd_bddClippingAnd(dd, f, g, depth, 1); + if (sup == NULL) { + (void) printf("TEST-CLIP: supersetting product failed.\n"); + return(0); + } + Cudd_Ref(sup); + (void) printf("T-C P+ "); + Cudd_PrintDebug(dd, sup, nvars, pr); + sizeSup = Cudd_DagSize(sup); + if (sizeSup > sizeProd) { + (void) printf("TEST-CLIP: supersetting product not safe.\n"); + } + + /* Compute product of supersets. */ + supF = Cudd_RemapOverApprox(dd,f,nvars,threshold,option->quality); + if (supF == NULL) { + (void) printf("TEST-CLIP: supersetting of f failed.\n"); + return(0); + } + Cudd_Ref(supF); + supG = Cudd_RemapOverApprox(dd,g,nvars,threshold,option->quality); + if (supF == NULL) { + (void) printf("TEST-CLIP: supersetting of g failed.\n"); + return(0); + } + Cudd_Ref(supG); + psup = Cudd_bddAnd(dd,supF,supG); + if (psup == NULL) { + (void) printf("TEST-CLIP: product of supersets failed.\n"); + return(0); + } + Cudd_Ref(psup); + Cudd_RecursiveDeref(dd,supF); + Cudd_RecursiveDeref(dd,supG); + (void) printf("T-C P> "); + Cudd_PrintDebug(dd, psup, nvars, pr); + + if (option->bdddump) { + onames[0] = name; outputs[0] = f; + onames[1] = gname; outputs[1] = g; + onames[2] = (char *) "prod"; outputs[2] = prod; + onames[3] = (char *) "sub"; outputs[3] = sub; + onames[4] = (char *) "sup"; outputs[4] = sup; + onames[5] = (char *) "psub"; outputs[5] = psub; + onames[6] = (char *) "psup"; outputs[6] = psup; + retval &= Bnet_bddArrayDump(dd, net1, option->dumpfile, outputs, + onames, 7, option->dumpFmt); + } + + /* Check correctness. */ + if (!Cudd_bddLeq(dd,sub,prod)) { + (void) printf("TEST-CLIP: subsetting product not a subset.\n"); + return(0); + } + if (!Cudd_bddLeq(dd,prod,sup)) { + (void) printf("TEST-CLIP: supersetting product not a superset.\n"); + return(0); + } + if (!Cudd_bddLeq(dd,psub,prod)) { + (void) printf("TEST-CLIP: product of subsets not a subset.\n"); + return(0); + } + if (!Cudd_bddLeq(dd,prod,psup)) { + (void) printf("TEST-CLIP: product of supersets not a superset.\n"); + return(0); + } + + Cudd_RecursiveDeref(dd,prod); + Cudd_RecursiveDeref(dd,sub); + Cudd_RecursiveDeref(dd,sup); + Cudd_RecursiveDeref(dd,psub); + Cudd_RecursiveDeref(dd,psup); + + return(retval); + +} /* end of ntrTestClippingAux */ + + + +/**Function******************************************************************** + + Synopsis [Processes one triplet of BDDs for Ntr_TestEquivAndContain.] + + Description [Processes one triplet of BDDs for Ntr_TestEquivAndContain. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestEquivAndContain] + +******************************************************************************/ +static int +ntrTestEquivAndContainAux( + DdManager *dd, + BnetNetwork *net1, + DdNode *f, + char *fname, + DdNode *g, + char *gname, + DdNode *d, + char *dname, + NtrOptions *option) +{ + DdNode *xor_, *diff, *ndiff; + int pr, nvars; + int equiv, implies; + static char *onames[6]; + DdNode *outputs[6]; + DdNode *fgd[3]; + + pr = option->verb; + fgd[0] = f; fgd[1] = g; fgd[2] = d; + nvars = Cudd_VectorSupportSize(dd,fgd,3); + if (nvars == CUDD_OUT_OF_MEM) return(0); + (void) printf("TEST-DC:: %s [=<]= %s unless %s\n", fname, gname, dname); + (void) printf("T-F "); + Cudd_PrintDebug(dd, f, nvars, pr); + (void) printf("T-G "); + Cudd_PrintDebug(dd, g, nvars, pr); + (void) printf("T-D "); + Cudd_PrintDebug(dd, d, nvars, pr); + + /* Check equivalence unless don't cares. */ + xor_ = Cudd_bddXor(dd, f, g); + if (xor_ == NULL) { + (void) printf("TEST-DC: XOR computation failed (1).\n"); + return(0); + } + Cudd_Ref(xor_); + equiv = Cudd_EquivDC(dd, f, g, d); + if (equiv != Cudd_bddLeq(dd,xor_,d)) { + (void) printf("TEST-DC: EquivDC computation incorrect (1).\n"); + (void) printf(" EquivDC states that %s and %s are %s\n", + fname, gname, equiv ? "equivalent" : "not equivalent"); + (void) printf("T-X "); + Cudd_PrintDebug(dd, xor_, nvars, pr); + return(0); + } + equiv = Cudd_EquivDC(dd, f, g, Cudd_Not(d)); + if (equiv != Cudd_bddLeq(dd,xor_,Cudd_Not(d))) { + (void) printf("TEST-DC: EquivDC computation incorrect (2).\n"); + (void) printf(" EquivDC states that %s and %s are %s\n", + fname, gname, equiv ? "equivalent" : "not equivalent"); + (void) printf("T-X "); + Cudd_PrintDebug(dd, xor_, nvars, pr); + return(0); + } + equiv = Cudd_EquivDC(dd, f, Cudd_Not(g), d); + if (equiv != Cudd_bddLeq(dd,Cudd_Not(xor_),d)) { + (void) printf("TEST-DC: EquivDC computation incorrect (3).\n"); + (void) printf(" EquivDC states that %s and not %s are %s\n", + fname, gname, equiv ? "equivalent" : "not equivalent"); + (void) printf("T-X "); + Cudd_PrintDebug(dd, Cudd_Not(xor_), nvars, pr); + return(0); + } + equiv = Cudd_EquivDC(dd, f, Cudd_Not(g), Cudd_Not(d)); + if (equiv != Cudd_bddLeq(dd,d,xor_)) { + (void) printf("TEST-DC: EquivDC computation incorrect (4).\n"); + (void) printf(" EquivDC states that %s and not %s are %s\n", + fname, gname, equiv ? "equivalent" : "not equivalent"); + (void) printf("T-X "); + Cudd_PrintDebug(dd, Cudd_Not(xor_), nvars, pr); + return(0); + } + + /* Check containment unless don't cares. */ + diff = Cudd_bddAnd(dd, f, Cudd_Not(g)); + if (diff == NULL) { + (void) printf("TEST-DC: AND/NOT computation failed (1).\n"); + return(0); + } + Cudd_Ref(diff); + implies = Cudd_bddLeqUnless(dd, f, g, d); + if (implies != Cudd_bddLeq(dd,diff,d)) { + (void) printf("TEST-DC: LeqUnless computation incorrect (1).\n"); + (void) printf(" LeqUnless states that %s %s %s\n", + fname, implies ? "implies" : "does not imply", gname); + (void) printf("T-I "); + Cudd_PrintDebug(dd, diff, nvars, pr); + return(0); + } + implies = Cudd_bddLeqUnless(dd, f, g, Cudd_Not(d)); + if (implies != Cudd_bddLeq(dd,diff,Cudd_Not(d))) { + (void) printf("TEST-DC: LeqUnless computation incorrect (2).\n"); + (void) printf(" LeqUnless states that %s %s %s\n", + fname, implies ? "implies" : "does not imply", gname); + (void) printf("T-I "); + Cudd_PrintDebug(dd, diff, nvars, pr); + return(0); + } + ndiff = Cudd_bddAnd(dd, f, g); + if (ndiff == NULL) { + (void) printf("TEST-DC: AND computation failed (3).\n"); + return(0); + } + Cudd_Ref(ndiff); + implies = Cudd_bddLeqUnless(dd, f, Cudd_Not(g), d); + if (implies != Cudd_bddLeq(dd,ndiff,d)) { + (void) printf("TEST-DC: LeqUnless computation incorrect (3).\n"); + (void) printf(" LeqUnless states that %s %s not(%s)\n", + fname, implies ? "implies" : "does not imply", gname); + (void) printf("T-I "); + Cudd_PrintDebug(dd, ndiff, nvars, pr); + return(0); + } + implies = Cudd_bddLeqUnless(dd, f, Cudd_Not(g), Cudd_Not(d)); + if (implies != Cudd_bddLeq(dd,ndiff,Cudd_Not(d))) { + (void) printf("TEST-DC: LeqUnless computation incorrect (3).\n"); + (void) printf(" LeqUnless states that %s %s not(%s)\n", + fname, implies ? "implies" : "does not imply", gname); + (void) printf("T-I "); + Cudd_PrintDebug(dd, ndiff, nvars, pr); + return(0); + } + if (option->bdddump) { + onames[0] = fname; outputs[0] = f; + onames[1] = gname; outputs[1] = g; + onames[2] = dname; outputs[2] = d; + onames[3] = (char *) "xor"; outputs[3] = xor_; + onames[4] = (char *) "diff"; outputs[4] = diff; + onames[5] = (char *) "ndiff"; outputs[5] = ndiff; + if (!Bnet_bddArrayDump(dd, net1, option->dumpfile, outputs, onames, + 6, option->dumpFmt)) + return(0); + } + Cudd_RecursiveDeref(dd,xor_); + Cudd_RecursiveDeref(dd,diff); + Cudd_RecursiveDeref(dd,ndiff); + + return(1); + +} /* end of ntrTestEquivAndContainAux */ + + +/**Function******************************************************************** + + Synopsis [Processes one pair of BDDs for Ntr_TestClosestCube.] + + Description [Processes one pair of BDDs for Ntr_TestClosestCube. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestClosestCube] + +******************************************************************************/ +static int +ntrTestClosestCubeAux( + DdManager *dd, + BnetNetwork *net, + DdNode *f, + char *fname, + DdNode *g, + char *gname, + DdNode **vars, + NtrOptions *option) +{ + DdNode *cube, *cubeN; + int distance, pr, nvars; + DdNode *fg[2]; + static char *onames[4]; + DdNode *outputs[4]; + + pr = option->verb; + fg[0] = f; fg[1] = g; + nvars = Cudd_VectorSupportSize(dd,fg,2); + if (nvars == CUDD_OUT_OF_MEM) return(0); + (void) printf("TEST-CC:: H(%s, %s)\n", fname, gname); + (void) printf("T-F "); + Cudd_PrintDebug(dd, f, nvars, pr); + (void) printf("T-G "); + Cudd_PrintDebug(dd, g, nvars, pr); + + cube = Cudd_bddClosestCube(dd, f, g, &distance); + if (cube == NULL) { + (void) printf("TEST-CC: computation failed (1).\n"); + return(0); + } + Cudd_Ref(cube); + (void) printf("T-C (%d) ", distance); + Cudd_PrintDebug(dd, cube, nvars, pr); + if (distance == 0) { + if (!Cudd_bddLeq(dd,cube,g)) { + (void) printf("TEST-CC: distance-0 cube not in g (2).\n"); + return(0); + } + } + + (void) printf("T-GN "); + Cudd_PrintDebug(dd, Cudd_Not(g), nvars, pr); + cubeN = Cudd_bddClosestCube(dd, f, Cudd_Not(g), &distance); + if (cubeN == NULL) { + (void) printf("TEST-CC: computation failed (3).\n"); + return(0); + } + Cudd_Ref(cubeN); + (void) printf("T-N (%d) ", distance); + Cudd_PrintDebug(dd, cubeN, nvars, pr); + if (distance == 0) { + if (!Cudd_bddLeq(dd,cubeN,Cudd_Not(g))) { + (void) printf("TEST-CC: distance-0 cube not in not(g) (4).\n"); + return(0); + } + } else { + int d, *minterm; + int numvars = Cudd_ReadSize(dd); + DdNode *scan, *zero; + DdNode *minBdd = Cudd_bddPickOneMinterm(dd,cubeN,vars,numvars); + if (minBdd == NULL) { + (void) printf("TEST-CC: minterm selection failed (5).\n"); + return(0); + } + Cudd_Ref(minBdd); + minterm = ALLOC(int,numvars); + if (minterm == NULL) { + (void) printf("TEST-CC: allocation failed (6).\n"); + Cudd_RecursiveDeref(dd,minBdd); + return(0); + } + scan = minBdd; + zero = Cudd_Not(DD_ONE(dd)); + while (!Cudd_IsConstant(scan)) { + DdNode *R = Cudd_Regular(scan); + DdNode *T = Cudd_T(R); + DdNode *E = Cudd_E(R); + if (R != scan) { + T = Cudd_Not(T); + E = Cudd_Not(E); + } + if (T == zero) { + minterm[Cudd_NodeReadIndex(R)] = 0; + scan = E; + } else { + minterm[Cudd_NodeReadIndex(R)] = 1; + scan = T; + } + } + Cudd_RecursiveDeref(dd,minBdd); + d = Cudd_MinHammingDist(dd,Cudd_Not(g),minterm,numvars); + FREE(minterm); + if (d != distance) { + (void) printf("TEST-CC: distance disagreement (7).\n"); + return(0); + } + } + + if (option->bdddump) { + onames[0] = fname; outputs[0] = f; + onames[1] = gname; outputs[1] = g; + onames[2] = (char *) "cube"; outputs[2] = cube; + onames[3] = (char *) "cubeN"; outputs[3] = cubeN; + if (!Bnet_bddArrayDump(dd, net, option->dumpfile, outputs, onames, + 4, option->dumpFmt)) + return(0); + } + Cudd_RecursiveDeref(dd,cube); + Cudd_RecursiveDeref(dd,cubeN); + + return(1); + +} /* end of ntrTestClosestCubeAux */ + + +/**Function******************************************************************** + + Synopsis [Processes one BDDs for Ntr_TestCharToVect.] + + Description [Processes one BDD for Ntr_TestCharToVect. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestCharToVect] + +******************************************************************************/ +static int +ntrTestCharToVect( + DdManager * dd, + DdNode * f, + NtrOptions *option) +{ + DdNode **vector; + int sharingSize; + DdNode *verify; + int pr = option->verb; + int i; + + (void) fprintf(stdout,"f"); + Cudd_PrintDebug(dd, f, Cudd_ReadSize(dd), 1); + if (pr > 1) { + Cudd_bddPrintCover(dd, f, f); + } + vector = Cudd_bddCharToVect(dd,f); + if (vector == NULL) return(0); + sharingSize = Cudd_SharingSize(vector, Cudd_ReadSize(dd)); + (void) fprintf(stdout, "Vector Size: %d components %d nodes\n", + Cudd_ReadSize(dd), sharingSize); + for (i = 0; i < Cudd_ReadSize(dd); i++) { + (void) fprintf(stdout,"v[%d]",i); + Cudd_PrintDebug(dd, vector[i], Cudd_ReadSize(dd), 1); + if (pr > 1) { + Cudd_bddPrintCover(dd, vector[i], vector[i]); + } + } + verify = Cudd_bddVectorCompose(dd,f,vector); + if (verify != Cudd_ReadOne(dd)) { + (void) fprintf(stdout, "Verification failed!\n"); + return(0); + } + Cudd_Ref(verify); + Cudd_IterDerefBdd(dd, verify); + for (i = 0; i < Cudd_ReadSize(dd); i++) { + Cudd_IterDerefBdd(dd, vector[i]); + } + FREE(vector); + return(1); + +} /* end of ntrTestCharToVect */ + + +#if 0 +/**Function******************************************************************** + + Synopsis [Try hard to squeeze a BDD.] + + Description [Try hard to squeeze a BDD. + Returns a pointer to the squeezed BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [ntrTestDensityAux Cudd_SubsetCompress] + +******************************************************************************/ +static DdNode * +ntrCompress1( + DdManager * dd, + DdNode * f, + int nvars, + int threshold) +{ + DdNode *res, *tmp1, *tmp2; + int sizeI, size; + + tmp1 = Cudd_RemapUnderApprox(dd,f,nvars,0,1.0); + if (tmp1 == NULL) return(NULL); + Cudd_Ref(tmp1); + sizeI = Cudd_DagSize(tmp1); + size = (sizeI < threshold) ? sizeI : threshold; + tmp2 = Cudd_SubsetShortPaths(dd, tmp1, nvars, size, 0); + if (tmp2 == NULL) { + Cudd_RecursiveDeref(dd,tmp1); + return(NULL); + } + Cudd_Ref(tmp2); + Cudd_RecursiveDeref(dd,tmp1); + res = Cudd_bddSqueeze(dd,tmp2,f); + if (res == NULL) { + Cudd_RecursiveDeref(dd,tmp2); + return(NULL); + } + Cudd_Ref(res); + Cudd_RecursiveDeref(dd,tmp2); + return(res); + +} /* end of ntrCompress1 */ +#endif + + +/**Function******************************************************************** + + Synopsis [Try hard to squeeze a BDD.] + + Description [Try hard to squeeze a BDD. + Returns a pointer to the squeezed BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [ntrTestDensityAux Cudd_SubsetCompress] + +******************************************************************************/ +static DdNode * +ntrCompress2( + DdManager * dd, + DdNode * f, + int nvars, + int threshold) +{ + DdNode *res, *tmp1, *tmp2; + int sizeI; + + tmp1 = Cudd_RemapUnderApprox(dd,f,nvars,0,1.0); + if (tmp1 == NULL) return(NULL); + Cudd_Ref(tmp1); + sizeI = Cudd_DagSize(tmp1); + if (sizeI > threshold) { + tmp2 = Cudd_SubsetShortPaths(dd, tmp1, nvars, threshold, 0); + if (tmp2 == NULL) { + Cudd_RecursiveDeref(dd,tmp1); + return(NULL); + } + Cudd_Ref(tmp2); + Cudd_RecursiveDeref(dd,tmp1); + } else { + tmp2 = tmp1; + } + res = Cudd_bddSqueeze(dd,tmp2,f); + if (res == NULL) { + Cudd_RecursiveDeref(dd,tmp2); + return(NULL); + } + Cudd_Ref(res); + if (Cudd_Density(dd,res,nvars) < Cudd_Density(dd,tmp2,nvars)) { + Cudd_RecursiveDeref(dd,res); + return(tmp2); + } else { + Cudd_RecursiveDeref(dd,tmp2); + return(res); + } + +} /* end of ntrCompress2 */ + + +/**Function******************************************************************** + + Synopsis [Checks whether node is a buffer.] + + Description [Checks whether node is a buffer. Returns a pointer to the + input node if nd is a buffer; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static BnetNode * +ntrNodeIsBuffer( + BnetNode *nd, + st_table *hash) +{ + BnetNode *inpnd; + + if (nd->ninp != 1) return(0); + if (!st_lookup(hash, nd->inputs[0], &inpnd)) return(0); + + return(nd->dd == inpnd->dd ? inpnd : NULL); + +} /* end of ntrNodeIsBuffer */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntrHeap.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrHeap.c new file mode 100644 index 000000000..801b3f8d6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrHeap.c @@ -0,0 +1,390 @@ +/**CFile*********************************************************************** + + FileName [ntrHeap.c] + + PackageName [ntr] + + Synopsis [Functions for heap-based priority queue.] + + Description [The functions in this file manage a priority queue implemented + as a heap. The first element of the heap is the one with the smallest key. + Refer to Chapter 7 of Cormen, Leiserson, and Rivest for the theory.] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: ntrHeap.c,v 1.6 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define PARENT(i) (((i)-1)>>1) +#define RIGHT(i) (((i)+1)<<1) +#define LEFT(i) (((i)<<1)|1) +#define ITEM(p,i) ((p)[i].item) +#define KEY(p,i) ((p)[i].key) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void ntrHeapify (NtrHeap *heap, int i); +static int ntrHeapResize (NtrHeap *heap); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes a priority queue.] + + Description [Initializes a priority queue. Returns a pointer to the heap + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_FreeHeap] + +******************************************************************************/ +NtrHeap * +Ntr_InitHeap( + int size) +{ + NtrHeap *heap; + + heap = ALLOC(NtrHeap,1); + if (heap == NULL) return(NULL); + heap->size = size; + heap->nslots = 0; + heap->slots = ALLOC(NtrHeapSlot,size); + if (heap->slots == NULL) { + FREE(heap); + return(NULL); + } + return(heap); + +} /* end of Ntr_InitHeap */ + + +/**Function******************************************************************** + + Synopsis [Frees a priority queue.] + + Description [] + + SideEffects [None] + + SeeAlso [Ntr_InitHeap] + +******************************************************************************/ +void +Ntr_FreeHeap( + NtrHeap *heap) +{ + FREE(heap->slots); + FREE(heap); + return; + +} /* end of Ntr_FreeHeap */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a priority queue.] + + Description [Inserts an item in a priority queue. Returns 1 if successful; + 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_HeapExtractMin] + +******************************************************************************/ +int +Ntr_HeapInsert( + NtrHeap *heap, + void *item, + int key) +{ + NtrHeapSlot *slots; + int i = heap->nslots; + + if (i == heap->size && !ntrHeapResize(heap)) return(0); + slots = heap->slots; + heap->nslots++; + while (i > 0 && KEY(slots,PARENT(i)) > key) { + ITEM(slots,i) = ITEM(slots,PARENT(i)); + KEY(slots,i) = KEY(slots,PARENT(i)); + i = PARENT(i); + } + ITEM(slots,i) = item; + KEY(slots,i) = key; + return(1); + +} /* end of Ntr_HeapInsert */ + + +/**Function******************************************************************** + + Synopsis [Extracts the element with the minimum key from a priority + queue.] + + Description [Extracts the element with the minimum key from a priority + queue. Returns 1 if successful; 0 otherwise.] + + SideEffects [The minimum key and the associated item are returned as + side effects.] + + SeeAlso [Ntr_HeapInsert] + +******************************************************************************/ +int +Ntr_HeapExtractMin( + NtrHeap *heap, + void *item, + int *key) +{ + NtrHeapSlot *slots = heap->slots; + + if (heap->nslots == 0) return(0); + *(void **)item = ITEM(slots,0); + *key = KEY(slots,0); + heap->nslots--; + ITEM(slots,0) = ITEM(slots,heap->nslots); + KEY(slots,0) = KEY(slots,heap->nslots); + ntrHeapify(heap,0); + + return(1); + +} /* end of Ntr_HeapExtractMin */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of items in a priority queue.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_HeapCount( + NtrHeap *heap) +{ + return(heap->nslots); + +} /* end of Ntr_HeapCount */ + + +/**Function******************************************************************** + + Synopsis [Clones a priority queue.] + + Description [] + + SideEffects [None] + + SeeAlso [Ntr_InitHeap] + +******************************************************************************/ +NtrHeap * +Ntr_HeapClone( + NtrHeap *source) +{ + NtrHeap *dest; + int i; + int nslots = source->nslots; + NtrHeapSlot *sslots = source->slots; + NtrHeapSlot *dslots; + + dest = Ntr_InitHeap(source->size); + if (dest == NULL) return(NULL); + dest->nslots = nslots; + dslots = dest->slots; + for (i = 0; i < nslots; i++) { + KEY(dslots,i) = KEY(sslots,i); + ITEM(dslots,i) = ITEM(sslots,i); + } + return(dest); + +} /* end of Ntr_HeapClone */ + + +/**Function******************************************************************** + + Synopsis [Tests the heap property of a priority queue.] + + Description [Tests the heap property of a priority queue. Returns 1 if + Successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestHeap( + NtrHeap *heap, + int i) +{ + NtrHeapSlot *slots = heap->slots; + int nslots = heap->nslots; + + if (i > 0 && KEY(slots,i) < KEY(slots,PARENT(i))) + return(0); + if (LEFT(i) < nslots) { + if (!Ntr_TestHeap(heap,LEFT(i))) + return(0); + } + if (RIGHT(i) < nslots) { + if (!Ntr_TestHeap(heap,RIGHT(i))) + return(0); + } + return(1); + +} /* end of Ntr_TestHeap */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Maintains the heap property of a priority queue.] + + Description [] + + SideEffects [None] + + SeeAlso [Ntr_HeapExtractMin] + +******************************************************************************/ +static void +ntrHeapify( + NtrHeap *heap, + int i) +{ + int smallest; + int left = LEFT(i); + int right = RIGHT(i); + int nslots = heap->nslots; + NtrHeapSlot *slots = heap->slots; + int key = KEY(slots,i); + + if (left < nslots && KEY(slots,left) < key) { + smallest = left; + } else { + smallest = i; + } + if (right < nslots && KEY(slots,right) < KEY(slots,smallest)) { + smallest = right; + } + if (smallest != i) { + void *item = ITEM(slots,i); + KEY(slots,i) = KEY(slots,smallest); + ITEM(slots,i) = ITEM(slots,smallest); + KEY(slots,smallest) = key; + ITEM(slots,smallest) = item; + ntrHeapify(heap,smallest); + } + + return; + +} /* end of ntrHeapify */ + + +/**Function******************************************************************** + + Synopsis [Resizes a priority queue.] + + Description [Resizes a priority queue by doubling the number of + available slots. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_HeapInsert] + +******************************************************************************/ +static int +ntrHeapResize( + NtrHeap *heap) +{ + int oldlength = heap->size; + int newlength = 2 * oldlength; + NtrHeapSlot *oldslots = heap->slots; + NtrHeapSlot *newslots = REALLOC(NtrHeapSlot, oldslots, newlength); + if (newslots == NULL) return 0; + heap->size = newlength; + heap->slots = newslots; + assert(Ntr_TestHeap(heap, 0)); + return 1; + +} /* end of ntrHeapResize */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntrMflow.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrMflow.c new file mode 100644 index 000000000..a8893c927 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrMflow.c @@ -0,0 +1,1581 @@ +/**CFile*********************************************************************** + + FileName [ntrMflow.c] + + PackageName [ntr] + + Synopsis [Symbolic maxflow algorithm.] + + Description [This file contains the functions that implement the + symbolic version of Dinits's maxflow algorithm described in the + ICCAD93 paper. The present implementation differs from the algorithm + described in the paper in that more than one matching techniques is + used. The technique of the paper is the one applied to + hourglass-type bilayers here.] + + Author [Fabio Somenzi, Gary Hachtel] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define MAXPHASE 1000 +#define MAXLAYER 1000 +#define MAXFPIT 100000 +#define MANY_TIMES 3.0 + +#define PRUNE /* If defined, enables pruning of E */ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct flowStatsStruct { + int pr; /* level of verbosity */ + long start_time; /* cpu time when the covering started */ + int phases; /* number of phases */ + int layers; /* number of layers */ + int fpit; /* number of fixed point iterations */ +} flowStats; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: ntrMflow.c,v 1.8 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +static DdNode *xcube, *ycube, *zcube; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void maximal_pull (DdManager *bdd, int l, DdNode *ty, DdNode **neW, DdNode **U, DdNode *E, DdNode **F, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void propagate_maximal_flow (DdManager *bdd, int m, DdNode **neW, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void trellis (DdManager *bdd, int m, DdNode **neW, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void rhombus (DdManager *bdd, int m, DdNode **neW, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void hourglass (DdManager *bdd, int m, DdNode **neW, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void maximal_push (DdManager *bdd, int l, DdNode **U, DdNode **F, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void trellisPush (DdManager *bdd, int m, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void rhombusPush (DdManager *bdd, int m, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void hourglassPush (DdManager *bdd, int m, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [] + + Description [This function implements Dinits's algorithm for (0-1) + max flow, using BDDs and a symbolic technique to trace multiple + edge-disjoint augmenting paths to complete a phase. The outer + forever loop is over phases, and the inner forever loop is to + propagate a (not yet) maximal flow of edge-disjoint augmenting paths + from one layer to the previous. The subprocedure call implements a + least fixed point iteration to compute a (not yet) maximal flow + update between layers. At the end of each phase (except the last + one) the flow is actually pushed from the source to the sink. + + Data items: +
            +
          • sx(ty) BDD representations of s(t). +
          • x(y) The variables encoding the from(to)-node u(v) of an + edge (u,v) in the given digraph. +
          • z Another set of variables. +
          • E(x,y) The edge relation. +
          • F(x,y) BDD representation of the current flow, initialized to 0 + for each arc, and updated by +1, -1, or 0 at the + end of each phase. +
          • Ms Mt The maximum flow, that is, the cardinality of a minimum cut, + measured at the source and at the sink, respectively. + The two values should be identical. +
          • reached The set of nodes already visited in the BFS of the digraph. +
          • fos fanout of the source node s. +
          • fit fanin of the sink node t. +
          + ] + + SideEffects [The flow realtion F and the cutset relation cut are returned + as side effects.] + + SeeAlso [] + +******************************************************************************/ +double +Ntr_maximum01Flow( + DdManager * bdd /* manager */, + DdNode * sx /* source node */, + DdNode * ty /* sink node */, + DdNode * E /* edge relation */, + DdNode ** F /* flow relation */, + DdNode ** cut /* cutset relation */, + DdNode ** x /* array of row variables */, + DdNode ** y /* array of column variables */, + DdNode ** z /* arrays of auxiliary variables */, + int n /* number of variables in each array */, + int pr /* verbosity level */) +{ + flowStats stats; + DdNode *one, *zero, +#ifdef PRUNE + *EDC, /* Edge don't care set */ +#endif + *reached, /* states reached through useful edges */ + *fos, *fit, /* fanout of source, fanin of sink */ + *rF, *rB, *tx, + *I, *P, + *w, *p, *q, *r,/* intemediate results */ + *pryz, *prxz, /* priority functions for disjoint path tracing */ + **neW, **U; /* arrays of BDDs for flow propagation */ + int i, j, l; + double Ms, Mt; + + /* Initialize debugging structure. */ + stats.pr = pr; + stats.start_time = util_cpu_time(); + stats.phases = 0; + stats.layers = 0; + stats.fpit = 0; + + /* Allocate arrays for new (just reached vertex sets) + ** and U (useful edge sets). + */ + U = ALLOC(DdNode *, ((unsigned) MAXLAYER)); + neW = ALLOC(DdNode *, ((unsigned) MAXLAYER)); + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /* Initialize xcube, ycube, and zcube (for abstractions). */ + Cudd_Ref(xcube = Cudd_bddComputeCube(bdd,x,NULL,n)); + Cudd_Ref(ycube = Cudd_bddComputeCube(bdd,y,NULL,n)); + Cudd_Ref(zcube = Cudd_bddComputeCube(bdd,z,NULL,n)); + + /* Build the BDD for the priority functions. */ + Cudd_Ref(pryz = Cudd_Dxygtdxz(bdd, n, x, y, z)); + Cudd_Ref(prxz = Cudd_Dxygtdyz(bdd, n, x, y, z)); + /* Now "randomize" by shuffling the x variables in pryz and the y + ** variables in prxz. + */ + Cudd_Ref(p = Cudd_bddAdjPermuteX(bdd,pryz,x,n)); + Cudd_RecursiveDeref(bdd,pryz); + pryz = p; + if(pr>2){(void) fprintf(stdout,"pryz");Cudd_PrintDebug(bdd,pryz,n*3,pr);} + Cudd_Ref(p = Cudd_bddAdjPermuteX(bdd,prxz,y,n)); + Cudd_RecursiveDeref(bdd,prxz); + prxz = p; + if(pr>2){(void) fprintf(stdout,"prxz");Cudd_PrintDebug(bdd,prxz,n*3,pr);} + +#ifdef PRUNE + /* Build the edge don't care set and prune E. The edge don't care + ** set consists of the edges into the source(s), the edges out of the + ** sink(s), and the self-loops. These edges cannot contribute to the + ** maximum flow. + */ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, sx, x, y, n)); + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, ty, x, y, n)); + Cudd_Ref(r = Cudd_bddOr(bdd, p, q)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,q); + Cudd_Ref(p = Cudd_Xeqy(bdd, n, x, y)); + Cudd_Ref(EDC = Cudd_bddOr(bdd, p, r)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,r); + if(pr>2){(void) fprintf(stdout,"EDC");Cudd_PrintDebug(bdd,EDC,n<<1,pr);} + Cudd_Ref(p = Cudd_bddAnd(bdd, E, Cudd_Not(EDC))); + Cudd_RecursiveDeref(bdd,EDC); + if(pr>0){(void) fprintf(stdout,"Given E");Cudd_PrintDebug(bdd,E,n<<1,pr);} + E = p; + if(pr>0){(void) fprintf(stdout,"Pruned E");Cudd_PrintDebug(bdd,E,n<<1,pr);} +#endif + + /* Compute fanin of sink node t: it is an upper bound for the flow. */ + Cudd_Ref(fit = Cudd_bddAnd(bdd, E, ty)); + if (pr>2) { + /* Compute fanout of source node s. */ + Cudd_Ref(fos = Cudd_bddAnd(bdd, E, sx)); + (void) fprintf(stdout,"fos");Cudd_PrintDebug(bdd,fos,n<<1,pr); + Cudd_RecursiveDeref(bdd,fos); + + (void) fprintf(stdout,"fit");Cudd_PrintDebug(bdd,fit,n<<1,pr); + } + /* t(x) is used to check for termination of forward traversal. */ + Cudd_Ref(tx = Cudd_bddSwapVariables(bdd, ty, x, y, n)); + + /* \KW{Procedure}\ \ \PC{maximum\_flow}$(s,t,E(x,y)) */ + Cudd_Ref(*F = zero); + + for (i = 1; i < MAXPHASE; i++) { + stats.phases++; + if(pr>0){(void) fprintf(stdout,"## Starting Phase %d at time = %s\n",i, + util_print_time(util_cpu_time() - stats.start_time));} + /* new[0](x) = s(x);U^0(x,y)=E(x,y)\cdot s(x) \cdot \overline{F(x,y)}; + ** reached=s; new[1](x)=\exists_xU^0(x,y); + */ + Cudd_Ref(neW[0] = sx); + Cudd_Ref(p = Cudd_bddAnd(bdd, sx, Cudd_Not(*F))); + Cudd_Ref(U[0] = Cudd_bddAnd(bdd, p, E)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(reached = sx); + Cudd_Ref(r = Cudd_bddExistAbstract(bdd, U[0], xcube)); + Cudd_RecursiveDeref(bdd,U[0]); + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, r, x, y, n)); + Cudd_RecursiveDeref(bdd,r); + Cudd_Ref(neW[1] = Cudd_bddAnd(bdd, q, Cudd_Not(reached))); + Cudd_RecursiveDeref(bdd,q); + if(pr>0) { + (void) fprintf(stdout,"neW[1]");Cudd_PrintDebug(bdd,neW[1],n,pr); + } + for (l = 1; l < MAXLAYER; l++) { + if (neW[l] == zero) { /* flow is maximum */ + /* cut=reached(x) \cdot E(x,y) \cdot \overline{reached(y)} */ + Cudd_Ref(p = Cudd_bddAnd(bdd, reached, E)); + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, reached, x, y, n)); + Cudd_Ref(*cut = Cudd_bddAnd(bdd, p, Cudd_Not(q))); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,q); + Cudd_RecursiveDeref(bdd,reached); + for (j = 0; j <= l; j++) + Cudd_RecursiveDeref(bdd,neW[j]); + goto endPhases; + } + /* As soon as we touch one sink node we stop traversal. + ** \KW{if} ($t\cdot new^{l} \neq 0$) + */ + if (!Cudd_bddLeq(bdd, tx, Cudd_Not(neW[l]))) { + Cudd_RecursiveDeref(bdd,reached); + maximal_pull(bdd,l-1,ty,neW,U,E,F,x,y,z,n,pryz,prxz,&stats); + goto endLayers; + } + stats.layers++; + if(pr>2){(void) fprintf(stdout,"===== Layer %d =====\n",l);} + /* reached(x) = reached(x) + new^l(x) */ + Cudd_Ref(w = Cudd_bddOr(bdd, reached, neW[l])); + Cudd_RecursiveDeref(bdd,reached); + reached = w; + /* I(y) = \exists_x((E(x,y) \cdot \overline{F(x,y)}) + ** \cdot new^l(x)) + */ + Cudd_Ref(p = Cudd_bddAnd(bdd, E, Cudd_Not(*F))); + Cudd_Ref(I = Cudd_bddAndAbstract(bdd, p, neW[l], xcube)); + if(pr>3){(void) fprintf(stdout,"I");Cudd_PrintDebug(bdd,I,n,pr);} + Cudd_RecursiveDeref(bdd,p); + /* rF(x)= I(x) \cdot \overline{reached(x)}) */ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, I, x, y, n)); + Cudd_RecursiveDeref(bdd,I); + Cudd_Ref(rF = Cudd_bddAnd(bdd, p, Cudd_Not(reached))); + Cudd_RecursiveDeref(bdd,p); + if(pr>2){(void) fprintf(stdout,"rF");Cudd_PrintDebug(bdd,rF,n,pr);} + /* P(x) = \exists_{y}(F(x,y) \cdot new^l(y)) */ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, neW[l], x, y, n)); + Cudd_Ref(P = Cudd_bddAndAbstract(bdd, *F, p, ycube)); + Cudd_RecursiveDeref(bdd,p); + /* rB(x) = P(x) \cdot \overline{reached(x)}) */ + Cudd_Ref(rB = Cudd_bddAnd(bdd, P, Cudd_Not(reached))); + Cudd_RecursiveDeref(bdd,P); + if(pr>2){(void) fprintf(stdout,"rB");Cudd_PrintDebug(bdd,rB,n,pr);} + /* new^{l+1}(x) = rF(x) + rB(x) */ + Cudd_Ref(neW[l+1] = Cudd_bddOr(bdd, rF, rB)); + Cudd_RecursiveDeref(bdd,rB); + Cudd_RecursiveDeref(bdd,rF); + if(pr>0) { + (void) fprintf(stdout,"new[%d]",l+1); + Cudd_PrintDebug(bdd,neW[l+1],n,pr); + } + } /* start next layer */ + if (l==MAXLAYER) (void) fprintf(stderr,"ERROR! MAXLAYER exceeded.\n"); + exit(3); +endLayers: + maximal_push(bdd, l-1, U, F, x, y, z, n, pryz, prxz, &stats); + for (j = 0; j < l; j++) { + Cudd_RecursiveDeref(bdd,U[j]); + Cudd_RecursiveDeref(bdd,neW[j]); + } + Cudd_RecursiveDeref(bdd,neW[l]); + if (pr > 0) { + Cudd_Ref(p = Cudd_bddAnd(bdd, sx, *F)); + Ms=Cudd_CountMinterm(bdd, p, n<<1); + (void) fprintf(stdout,"# Flow out of s: %g\n", Ms); + Cudd_RecursiveDeref(bdd,p); + } + if (Cudd_bddLeq(bdd, fit, *F)) { + Cudd_Ref(*cut = fit); + goto endPhases; + } + } /* start next phase */ + if (i == MAXPHASE) (void) fprintf(stderr,"ERROR! MAXPHASE exceeded.\n"); + + /* Last phase is completed --- print flow results. */ +endPhases: + Cudd_RecursiveDeref(bdd,tx); + + Cudd_Ref(q = Cudd_bddAnd(bdd, *F, sx)); + Ms = Cudd_CountMinterm(bdd, q, n<<1); + Cudd_RecursiveDeref(bdd,q); + + Cudd_Ref(q = Cudd_bddAnd(bdd, *F, ty)); + Mt = Cudd_CountMinterm(bdd, q, n<<1); + Cudd_RecursiveDeref(bdd,q); + + if (pr>1) (void) fprintf(stdout,"Mt= %g, Ms= %g \n", Mt, Ms); + + if (pr>3){(void) fprintf(stdout,"pryz");Cudd_PrintDebug(bdd,pryz,n*3,pr);} + if (pr>3){(void) fprintf(stdout,"prxz");Cudd_PrintDebug(bdd,prxz,n*3,pr);} + + if (pr>0) { + (void) fprintf(stdout,"#### Stats for maximum_flow ####\n"); + (void) fprintf(stdout,"%d variables %d of which x[i]\n", Cudd_ReadSize(bdd), n); + (void) fprintf(stdout,"time = %s\n", + util_print_time(util_cpu_time() - stats.start_time)); + (void) fprintf(stdout,"phases = %d\n", stats.phases); + (void) fprintf(stdout,"layers = %d\n", stats.layers); + (void) fprintf(stdout,"FP iter. = %d\n", stats.fpit); + } + + Cudd_RecursiveDeref(bdd,fit); + Cudd_RecursiveDeref(bdd,pryz); + Cudd_RecursiveDeref(bdd,prxz); + Cudd_RecursiveDeref(bdd,xcube); + Cudd_RecursiveDeref(bdd,ycube); + Cudd_RecursiveDeref(bdd,zcube); +#ifdef PRUNE + Cudd_RecursiveDeref(bdd,E); +#endif + + FREE(U); + FREE(neW); + + return(Ms); + +} /* end of Ntr_maximum01Flow */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Selects set of edge-disjoint paths from layered network.] + + Description [Selects set of edge-disjoint paths from layered + network. maximal_pull is called when the BFS constructing the + layered graph reaches a sink. At this point the new sets of the + BFS have been formed, and we know every vertex in these sets is + reachable from the source vertex (or vertices) s. The new sets are + used to compute the set of useful edges exiting each layer to the + right. In each layer, propagate_maximal_flow is called to select a + maximal subset of these useful edges. This subset is then used to + prune new and U.] + + SideEffects [None] + + SeeAlso [maximal_push] + +******************************************************************************/ +static void +maximal_pull( + DdManager * bdd /* manager */, + int l /* depth of layered network for current phase */, + DdNode * ty /* sink node */, + DdNode ** neW /* array of BFS layers */, + DdNode ** U /* array of useful edges */, + DdNode * E /* edge relation */, + DdNode ** F /* flow relation */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* arrays of variables for rows and columns */, + int n /* number of x variables */, + DdNode * pryz, + DdNode * prxz /* priority functions */, + flowStats * stats) +{ + DdNode *p, *q, *r, + *UF, *UB; + int m, + pr; /* Print control */ + + pr = stats->pr; + + /* The useful edges of the last layer are all the empty edges into + ** the sink(s) from new[l]. + ** U^{l}(x,y) = t(y)\cdot \overline{F(x,y)}\cdot E(x,y)\cdot new^{l}(x) + */ + Cudd_Ref(p = Cudd_bddAnd(bdd, E, Cudd_Not(*F))); + Cudd_Ref(q = Cudd_bddAnd(bdd, neW[l], p)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(U[l] = Cudd_bddAnd(bdd, ty, q)); + Cudd_RecursiveDeref(bdd,q); + if(pr>1){(void) fprintf(stdout,"U[%d]",l);Cudd_PrintDebug(bdd,U[l],n<<1,pr);} + /* Eliminate from new[l] the states with no paths to the sink(s). + ** new^{l}(x)=\exists_y U^{l}(x,y) + */ + Cudd_RecursiveDeref(bdd,neW[l]); + Cudd_Ref(neW[l] = Cudd_bddExistAbstract(bdd, U[l], ycube)); + + for (m = l; m >= 1; m--) { + /* Find usable backward edges from level m-1 to level m. + ** UB(x,y) = new^{m}(x) \cdot F(x,y) \cdot new^{m-1}(y) + */ + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, neW[m-1], x, y, n)); + Cudd_Ref(q = Cudd_bddAnd(bdd, r, *F)); + Cudd_RecursiveDeref(bdd,r); + Cudd_Ref(UB = Cudd_bddAnd(bdd, neW[m], q)); + Cudd_RecursiveDeref(bdd,q); + if(pr>2){(void) fprintf(stdout,"UB");Cudd_PrintDebug(bdd,UB,n<<1,pr);} + /* Find usable forward edges. + ** UF(x,y) = new^{m}(y) \cdot \overline{F(x,y)} \cdot E(x,y) + ** \cdot new^{m-1}(x) + */ + Cudd_Ref(p = Cudd_bddAnd(bdd, E, Cudd_Not(*F))); + Cudd_Ref(q = Cudd_bddAnd(bdd, neW[m-1], p)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, neW[m], x, y, n)); + Cudd_Ref(UF = Cudd_bddAnd(bdd, r, q)); + Cudd_RecursiveDeref(bdd,q); + Cudd_RecursiveDeref(bdd,r); + if(pr>2){(void) fprintf(stdout,"UF");Cudd_PrintDebug(bdd,UF,n<<1,pr);} + /* U^{m-1}(x,y) = UB(y,x) + UF(x,y) */ + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, UB, x, y, n)); + Cudd_RecursiveDeref(bdd,UB); + Cudd_Ref(U[m-1] = Cudd_bddOr(bdd, UF, r)); + Cudd_RecursiveDeref(bdd,UF); + Cudd_RecursiveDeref(bdd,r); + if(pr>2){(void)fprintf(stdout,"U[%d]",m-1); + Cudd_PrintDebug(bdd,U[m-1],n<<1,pr);} + /* new[m-1](x) = \exists_{y}U^{m-1}(x,y) */ + Cudd_RecursiveDeref(bdd,neW[m-1]); + Cudd_Ref(neW[m-1] = Cudd_bddExistAbstract(bdd, U[m-1], ycube)); + /* Compute maximal disjoint interlayer edge set. */ + propagate_maximal_flow(bdd, m, neW, U, x, y, z, n, pryz, prxz, stats); + if(pr>0) { + (void)fprintf(stdout,"U[%d]",m-1); + Cudd_PrintDebug(bdd,U[m-1],n<<1,pr); + } + } /* prune next layer */ + + return; + +} /* end of maximal_pull */ + + +/**Function******************************************************************** + + Synopsis [Pulls flow though a layer.] + + Description [Pulls flow though a layer. propagate_maximal_flow only + affects U[m-1] and new[m-1]. At the end of this function, the edges + in U[m] are guaranteed to drain all the flow supplied by the edges + in U[m-1]. This effect is obtained by pruning U[m-1]. After the + pruned U[m-1] is computed, new[m-1] is updated to keep track of what + nodes are still useful. + + The pruning is performed without actually measuring the in-potential + and the out-potential of each node. Instead, pairs of nodes from U[m-1] + and U[m] are matched. To avoid counting, the procedure computes sets of + paths that connect layer m-1 to layer m+1 and are edge-disjoint. + + Two paths from layer m-1 to layer m+1 are disjoint if they have distinct + end-point or if they have distinct middle points. What condition to + enforce depends on the "shape" of the layers.] + + SideEffects [Changes U[m-1] and new[m-1]] + + SeeAlso [trellis rhombus hourglass] + +******************************************************************************/ +static void +propagate_maximal_flow( + DdManager * bdd, + int m /* center of current bilayer */, + DdNode ** neW /* array of reachable or useful nodes */, + DdNode ** U /* array of usable or useful edges */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* arrays of variables for rows and columns */, + int n /* number of x variables */, + DdNode * pryz, + DdNode * prxz /* priority functions */, + flowStats * stats) +{ + DdNode *rN; + double mtl, mtc, mtr; /* minterms for left, center, right levels */ + int pr; /* print control */ + + pr = stats->pr; + + mtl = Cudd_CountMinterm(bdd, neW[m-1], n); + mtc = Cudd_CountMinterm(bdd, neW[m], n); + + /* rN(y) = \exists_x U^{m}(x,y) */ + Cudd_Ref(rN = Cudd_bddExistAbstract(bdd, U[m], xcube)); + mtr = Cudd_CountMinterm(bdd, rN, n); + Cudd_RecursiveDeref(bdd,rN); + + if (pr > 0) { + (void) fprintf(stdout, "layer = %d mtl = %g mtc = %g mtr = %g", + m, mtl, mtc, mtr); + } + + if ((mtc > MANY_TIMES * mtl) || (mtc > MANY_TIMES * mtr)) { + if (pr>0) (void) fprintf(stdout, " R\n"); + rhombus(bdd, m, neW, U, x, y, z, n, pryz, prxz, stats); + } else if (mtr > MANY_TIMES * mtc) { + if (pr>0) (void) fprintf(stdout, " H\n"); + hourglass(bdd, m, neW, U, x, y, z, n, pryz, prxz, stats); + } else { + if (pr>0) (void) fprintf(stdout, " T\n"); + trellis(bdd, m, neW, U, x, y, z, n, pryz, prxz, stats); + } + return; + +} /* end of propagate_maximal_flow */ + + +/**Function******************************************************************** + + Synopsis [Selects edges from a trellis-type bilayer.] + + Description [Selects edges from a trellis-type bilayer. Used to pull flow. + First a matching is found in the left layer. Then the paths are extended + (if possible) through the right layer. This process is repeated until a + maximal flow is found.] + + SideEffects [None] + + SeeAlso [rhombus hourglass trellisPush] + +******************************************************************************/ +static void +trellis( + DdManager * bdd, + int m /* center level of current bilayer */, + DdNode ** neW /* array of node levels */, + DdNode ** U /* array of edge layers */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* arrays of variables for rows and columns */, + int n /* number of x variables */, + DdNode * pryz, + DdNode * prxz /* priority functions */, + flowStats * stats) +{ + DdNode *one, *zero, + *p, *q, *r, + *Uin, /* edges to be matched from U[m-1] */ + *Uout, /* edges to be matched from U[m] */ + *P, + *LU, *RU, /* left-unique and right-unique sets of edges */ + *D, + *Ml, *Mr; /* nodes matched from left and right */ + int k, + pr; /* print control */ + + pr = stats->pr; + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /*Uout(x,y)=U^m(x,y)*/ + Cudd_Ref(Uout = U[m]); + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + /*Uin(x,y)=U^{m-1}(x,y)*/ + Cudd_Ref(Uin = U[m-1]); + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + for(k = 0; k < MAXFPIT; k++) { + stats->fpit++; + /*LU(x,y)=Uin(x,y)\cdot\overline{\exists_{z}(Uin(z,y)\cdot\Pi(x,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Uin, x, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, prxz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(LU = Cudd_bddAnd(bdd, Uin, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + if(pr>3){(void)fprintf(stdout,"LU");Cudd_PrintDebug(bdd,LU,n<<1,pr);} + /*D(x,y)= LU(x,y)\cdot \overline{\exists_{z}(LU(x,z)\cdot \Pi(y,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, LU, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, pryz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(D = Cudd_bddAnd(bdd, LU, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,LU); + if(pr>3){(void)fprintf(stdout,"D");Cudd_PrintDebug(bdd,D,n<<1,pr);} + /*Ml(y)=\exists_{x}D(x,y)*/ + Cudd_Ref(Ml = Cudd_bddExistAbstract(bdd, D, xcube)); + if(pr>3){(void)fprintf(stdout,"Ml");Cudd_PrintDebug(bdd,Ml,n,pr);} + /*P(x,y)=Ml(x)\cdot Uout(x,y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Ml, x, y, n)); + Cudd_Ref(P = Cudd_bddAnd(bdd, p, Uout)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Ml); + if(pr>3){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n<<1,pr);} + /*RU(x,y)= P(x,y)\cdot \overline{\exists_{z}(P(x,z)\cdot \Pi(y,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, P, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, pryz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(RU = Cudd_bddAnd(bdd, P, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,P); + if(pr>3){(void)fprintf(stdout,"RU");Cudd_PrintDebug(bdd,RU,n<<1,pr);} + /*Mr(x)=\exists_{y}RU(x,y)*/ + Cudd_Ref(Mr = Cudd_bddExistAbstract(bdd, RU, ycube)); + if(pr>3){(void)fprintf(stdout,"Mr");Cudd_PrintDebug(bdd,Mr,n,pr);} + /*D(x,y)=D(x,y)\cdot Mr(y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Mr, x, y, n)); + Cudd_RecursiveDeref(bdd,Mr); + Cudd_Ref(q = Cudd_bddAnd(bdd, D, p)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,D); + D = q; + if(pr>3){(void)fprintf(stdout,"D");Cudd_PrintDebug(bdd,D,n<<1,pr);} + /*Uin(x,y)=Uin(x,y)-D(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uin, Cudd_Not(D))); + Cudd_RecursiveDeref(bdd,Uin); + Uin = p; + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + /*Uout(x,y)=Uout(x,y)-RU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uout, Cudd_Not(RU))); + Cudd_RecursiveDeref(bdd,Uout); + Cudd_RecursiveDeref(bdd,RU); + Uout = p; + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + /*\KW{if}(($D(x,y)=zero$)~~\KW{or}~~($Uin(x,y)=zero$)~~\KW{or} + ($Uout(x,y)=zero$))~~KW{break}*/ + if ((D == zero)||(Uin == zero)||(Uout == zero)) { + Cudd_RecursiveDeref(bdd,D); + break; + } + Cudd_RecursiveDeref(bdd,D); + + } /* Next least fixed point iteration with smaller Uin and Uout */ + if (k == MAXFPIT) (void) fprintf(stderr, + "Trellis: WARNING! MAXFPIT (%d) exceeded processing Layer %d.\n", + MAXFPIT, m); + + if (Uin != zero) { + /* $U^{m-1}(x,y) = U^{m-1}(x,y)-Uin(x,y)$*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, U[m-1], Cudd_Not(Uin))); + Cudd_RecursiveDeref(bdd,U[m-1]); + U[m-1] = p; + /* $new^{m-1}(x,y) = \esists_yU^{m-1}(x,y)$*/ + Cudd_RecursiveDeref(bdd,neW[m-1]); + Cudd_Ref(neW[m-1] = Cudd_bddExistAbstract(bdd, U[m-1], ycube)); + } + if(pr>2){(void)fprintf(stdout,"U[%d]",m-1); Cudd_PrintDebug(bdd,U[m-1],n<<1,pr);} + if(pr>2){(void)fprintf(stdout,"new[%d]",m-1); + Cudd_PrintDebug(bdd,neW[m-1],n,pr);} + + Cudd_RecursiveDeref(bdd,Uin); + Cudd_RecursiveDeref(bdd,Uout); + + return; + +} /* end of trellis */ + + +/**Function******************************************************************** + + Synopsis [Selects edges from a rhombus-type bilayer.] + + Description [Selects edges from a rhombus-type bilayer. Used to pull flow. + Makes the left layer left-unique and the right layer right-unique. Prunes + and repeats until convergence to a maximal flow. It makes sure that all + intermediate points of the two-arc paths are disjoint at each iteration.] + + SideEffects [None] + + SeeAlso [trellis hourglass rhombusPush] + +******************************************************************************/ +static void +rhombus( + DdManager * bdd, + int m /* center of current bilayer */, + DdNode ** neW, + DdNode ** U /* arrays for flow propagation */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* arrays of variables for rows and columns */, + int n /* number of x variables */, + DdNode * pryz, + DdNode * prxz /* priority functions */, + flowStats * stats) +{ + DdNode *one, *zero, + *p, *q, *r, + *Uin, /* edges to be matched from U[m-1] */ + *Uout, /* edges to be matched from U[m] */ + *P, + *LU, *RU, /* left-unique and right-unique sets of edges */ + *Ml, *Mr; /* nodes matched from left and right */ + int k, + pr; /* print control */ + + pr = stats->pr; + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /*Uout(x,y)=U^m(x,y)*/ + Cudd_Ref(Uout = U[m]); + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*Uin(x,y)=U^{m-1}(x,y)*/ + Cudd_Ref(Uin = U[m-1]); + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + for(k = 0; k < MAXFPIT; k++) { + stats->fpit++; + /*LU(x,y)=Uin(x,y)\cdot\overline{\exists_{z}(Uin(z,y)\cdot\Pi(x,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Uin, x, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, prxz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(LU = Cudd_bddAnd(bdd, Uin, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + if(pr>3){(void)fprintf(stdout,"LU");Cudd_PrintDebug(bdd,LU,n<<1,pr);} + /*Ml(y)=\exists_{x}LU(x,y)*/ + Cudd_Ref(Ml = Cudd_bddExistAbstract(bdd, LU, xcube)); + if(pr>3){(void)fprintf(stdout,"Ml");Cudd_PrintDebug(bdd,Ml,n,pr);} + /*P(x,y)=Ml(x)\cdot Uout(x,y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Ml, x, y, n)); + Cudd_Ref(P = Cudd_bddAnd(bdd, p, Uout)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Ml); + if(pr>3){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n<<1,pr);} + /*RU(x,y)= P(x,y)\cdot \overline{\exists_{z}(P(x,z)\cdot \Pi(y,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, P, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, pryz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(RU = Cudd_bddAnd(bdd, P, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,P); + if(pr>3){(void)fprintf(stdout,"RU");Cudd_PrintDebug(bdd,RU,n<<1,pr);} + /*Mr(x)=\exists_{y}RU(x,y)*/ + Cudd_Ref(Mr = Cudd_bddExistAbstract(bdd, RU, ycube)); + if(pr>3){(void)fprintf(stdout,"Mr");Cudd_PrintDebug(bdd,Mr,n,pr);} + /*LU(x,y)=LU(x,y)\cdot Mr(y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Mr, x, y, n)); + Cudd_RecursiveDeref(bdd,Mr); + Cudd_Ref(q = Cudd_bddAnd(bdd, LU, p)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,LU); + LU = q; + if(pr>3){(void)fprintf(stdout,"LU");Cudd_PrintDebug(bdd,LU,n<<1,pr);} + /*Uin(x,y)=Uin(x,y)-LU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uin, Cudd_Not(LU))); + Cudd_RecursiveDeref(bdd,Uin); + Uin = p; + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + /*Uout(x,y)=Uout(x,y)-RU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uout, Cudd_Not(RU))); + Cudd_RecursiveDeref(bdd,Uout); + Cudd_RecursiveDeref(bdd,RU); + Uout = p; + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + /*\KW{if}(($LU(x,y)=zero$)~~\KW{or}~~($Uin(x,y)=zero$)~~\KW{or} + ($Uout(x,y)=zero$))~~KW{break}*/ + if((LU == zero)||(Uin == zero)||(Uout == zero)) { + Cudd_RecursiveDeref(bdd,LU); + break; + } + Cudd_RecursiveDeref(bdd,LU); + + } /* Next least fixed point iteration with smaller Uin and Uout */ + if (k == MAXFPIT) (void) fprintf(stderr, + "Rhombus: WARNING! MAXFPIT (%d) exceeded processing Layer %d.\n", + MAXFPIT, m); + + if (Uin != zero) { + /* $U^{m-1}(x,y) = U^{m-1}(x,y)-Uin(x,y)$*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, U[m-1], Cudd_Not(Uin))); + Cudd_RecursiveDeref(bdd,U[m-1]); + U[m-1] = p; + /* $new^{m-1}(x,y) = \esists_yU^{m-1}(x,y)$*/ + Cudd_RecursiveDeref(bdd,neW[m-1]); + Cudd_Ref(neW[m-1] = Cudd_bddExistAbstract(bdd, U[m-1], ycube)); + } + if(pr>2){(void)fprintf(stdout,"U[%d]",m-1); Cudd_PrintDebug(bdd,U[m-1],n<<1,pr);} + if(pr>2){ + (void)fprintf(stdout,"new[%d]",m-1); + Cudd_PrintDebug(bdd,neW[m-1],n,pr); + } + Cudd_RecursiveDeref(bdd,Uin); + Cudd_RecursiveDeref(bdd,Uout); + + return; + +} /* end of rhombus */ + + +/**Function******************************************************************** + + Synopsis [Selects edges from a hourglass-type bilayer.] + + Description [Selects edges from a hourglass-type bilayer. Used to + pull flow. Method described in paper. More general, but more + expensive than the others.] + + SideEffects [None] + + SeeAlso [trellis rhombus hourglassPush] + +******************************************************************************/ +static void +hourglass( + DdManager * bdd, + int m /* center level of current bilayer */, + DdNode ** neW, + DdNode ** U /* arrays for flow propagation */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* arrays of variables for rows and columns */, + int n /* number of x variables */, + DdNode * pryz, + DdNode * prxz /* priority functions */, + flowStats * stats) +{ + DdNode *one, *zero, + *przy, + *p, *q, *r, + *Uin, /* edges to be matched from U[m-1] */ + *Uout, /* edges to be matched from U[m] */ + *P, *Q, + *PA, *D; + int k, + pr; /* print control */ + + pr = stats->pr; + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /* Build priority function. */ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, pryz, y, z, n)); + Cudd_Ref(przy = Cudd_bddAdjPermuteX(bdd,p,x,n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>2){(void)fprintf(stdout,"przy");Cudd_PrintDebug(bdd,przy,n*3,pr);} + + /*Uout(x,y)=U^m(x,y)*/ + Cudd_Ref(Uout = U[m]); + if(pr>1){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*Uin(x,y)=U^{m-1}(x,y)*/ + Cudd_Ref(Uin = U[m-1]); + if(pr>1){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + for(k = 0; k < MAXFPIT; k++) { + stats->fpit++; + /*P(x,y,z)=Uin(x,y)\cdot Uout(y,z)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Uout, y, z, n)); + if(pr>2){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n<<1,pr);} + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, p, x, y, n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>2){(void)fprintf(stdout,"q");Cudd_PrintDebug(bdd,q,n<<1,pr);} + Cudd_Ref(P = Cudd_bddAnd(bdd, Uin, q)); + Cudd_RecursiveDeref(bdd,q); + if(pr>1){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n*3,pr);} + /*PA(x,z)=\exists_yP(x,y,z)*/ + Cudd_Ref(PA = Cudd_bddExistAbstract(bdd, P, ycube)); + if(pr>2){(void)fprintf(stdout,"PA");Cudd_PrintDebug(bdd,PA,n<<1,pr);} + if(pr>3) { + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, PA, xcube)); + (void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, PA, zcube)); + (void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr); + Cudd_RecursiveDeref(bdd,p); + } + /*Q(x,z)= PA(x,z)\cdot \overline{\exists_{y}(PA(x,y)\cdot \Pi(z,y))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, PA, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, przy, ycube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(Q = Cudd_bddAnd(bdd, PA, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,PA); + if(pr>2){(void)fprintf(stdout,"Q");Cudd_PrintDebug(bdd,Q,n<<1,pr);} + if(pr>3) { + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, Q, xcube)); + (void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr); + Cudd_RecursiveDeref(bdd,p); + } + /*D(x,z)= Q(x,z)\cdot \overline{\exists_{y}(Q(y,z)\cdot \Pi(x,y))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Q, x, y, n)); + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, prxz, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, q, ycube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,q); + Cudd_Ref(D = Cudd_bddAnd(bdd, Q, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,Q); + if(pr>1){(void)fprintf(stdout,"D");Cudd_PrintDebug(bdd,D,n<<1,pr);} + /*P(x,y,z)=P(x,y,z)\cdot D(x,z)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, P, D)); + Cudd_RecursiveDeref(bdd,D); + Cudd_RecursiveDeref(bdd,P); + P = p; + if(pr>2){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n*3,pr);} + /*Uin(x,y)=Uin(x,y)-\exists_zP(x,y,z)*/ + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, P, zcube)); + if(pr>3){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n<<1,pr);} + Cudd_Ref(q = Cudd_bddAnd(bdd, Uin, Cudd_Not(p))); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Uin); + Uin = q; + if(pr>1){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + /*Uout(x,y)=Uout(x,y)-\exists_zP(z,x,y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, P, x, y, n)); + if(pr>3){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n*3,pr);} + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, p, y, z, n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>3){(void)fprintf(stdout,"r");Cudd_PrintDebug(bdd,r,n*3,pr);} + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, r, zcube)); + Cudd_RecursiveDeref(bdd,r); + if(pr>3){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n<<1,pr);} + Cudd_Ref(q = Cudd_bddAnd(bdd, Uout, Cudd_Not(p))); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Uout); + Uout = q; + if(pr>1){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + /*\KW{if}(($P(x,y,z)=zero$)~~\KW{or}~~($Uin(x,y)=zero$)~~\KW{or} + ($Uout(x,y)=zero$))~~KW{break}*/ + if((P == zero)||(Uin == zero)||(Uout == zero)) { + Cudd_RecursiveDeref(bdd,P); + break; + } + Cudd_RecursiveDeref(bdd,P); + + } /* Next least fixed point iteration with smaller P */ + if (k == MAXFPIT) (void) fprintf(stderr, + "Hourglass: WARNING! MAXFPIT (%d) exceeded processing Layer %d.\n", + MAXFPIT, m); + + if (Uin != zero) { + /* $U^{m-1}(x,y) = U^{m-1}(x,y)-Uin(x,y)$*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, U[m-1], Cudd_Not(Uin))); + Cudd_RecursiveDeref(bdd,U[m-1]); + U[m-1] = p; + /* $new^{m-1}(x,y) = \esists_yU^{m-1}(x,y)$*/ + Cudd_RecursiveDeref(bdd,neW[m-1]); + Cudd_Ref(neW[m-1] = Cudd_bddExistAbstract(bdd, U[m-1], ycube)); + } + if(pr>1){(void)fprintf(stdout,"U[%d]",m-1); Cudd_PrintDebug(bdd,U[m-1],n<<1,pr);} + if(pr>1){(void)fprintf(stdout,"new[%d]",m-1); + Cudd_PrintDebug(bdd,neW[m-1],n,pr);} + + Cudd_RecursiveDeref(bdd,Uin); + Cudd_RecursiveDeref(bdd,Uout); + Cudd_RecursiveDeref(bdd,przy); + + return; + +} /* end of hourglass */ + + +/**Function******************************************************************** + + Synopsis [Pushes flow through useful edges.] + + Description [Pushes flow from the source(s) to the sink(s) through + useful edges.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +maximal_push( + DdManager * bdd, + int l /* Depth of layered network for current phase */, + DdNode ** U /* array of edge sets for flow propagation */, + DdNode ** F /* edge and flow relations */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* arrays of variables for rows and columns */, + int n /* number of x variables */, + DdNode * pryz, + DdNode * prxz /* priority functions */, + flowStats * stats) +{ + DdNode *p, *q, *r, + *UT, + *lN, *cN, *rN; /* left, center, right nodes of bilayer */ + double mtl, mtc, mtr; + int m, + pr; /* print control */ + + pr = stats->pr; + + if (l == 0) { + /* F(x,y) = F(x,y) + U^{0}(x,y) */ + Cudd_Ref(q = Cudd_bddOr(bdd, *F, U[0])); + Cudd_RecursiveDeref(bdd,*F); + *F = q; + if(pr>3){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + return; + } + + for (m = 1; m < l; m++) { + /* lN(x) = \exists_y U^{m-1}(x,y) */ + Cudd_Ref(lN = Cudd_bddExistAbstract(bdd, U[m-1], ycube)); + mtl = Cudd_CountMinterm(bdd, lN, n); + Cudd_RecursiveDeref(bdd,lN); + + /* cN(y) = \exists_x U^{m-1}(x,y) */ + Cudd_Ref(cN = Cudd_bddExistAbstract(bdd, U[m-1], xcube)); + mtc = Cudd_CountMinterm(bdd, cN, n); + Cudd_RecursiveDeref(bdd,cN); + + /* rN(y) = \exists_x U^{m}(x,y) */ + Cudd_Ref(rN = Cudd_bddExistAbstract(bdd, U[m], xcube)); + mtr = Cudd_CountMinterm(bdd, rN, n); + Cudd_RecursiveDeref(bdd,rN); + + if (pr > 0) { + (void) fprintf(stdout, "layer = %d mtl = %g mtc = %g mtr = %g", + m, mtl, mtc, mtr); + } + if ((mtc > MANY_TIMES * mtl) && !(mtr > MANY_TIMES * mtl)) { + if (pr>0) (void) fprintf(stdout, " R\n"); + rhombusPush(bdd, m, U, x, y, z, n, pryz, prxz, stats); + } else if (mtl > MANY_TIMES * mtc) { + if (pr>0) (void) fprintf(stdout, " H\n"); + hourglassPush(bdd, m, U, x, y, z, n, pryz, prxz, stats); + } else { + if (pr>0) (void) fprintf(stdout, " T\n"); + trellisPush(bdd, m, U, x, y, z, n, pryz, prxz, stats); + } + + /* F(x,y) = F(x,y) + U^{m-1}(x,y) \cdot \overline{F(y,x)} */ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, *F, x, y, n)); + Cudd_Ref(q = Cudd_bddAnd(bdd, Cudd_Not(p), U[m-1])); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(r = Cudd_bddOr(bdd, *F, q)); + Cudd_RecursiveDeref(bdd,q); + Cudd_RecursiveDeref(bdd,*F); + *F = r; + if(pr>3){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + + /* F(x,y) = F(x,y) - U^{m-1}(y,x) */ + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, U[m-1], x, y, n)); + Cudd_Ref(q = Cudd_bddAnd(bdd, *F, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,*F); + *F = q; + if(pr>3){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + + } /* Push maximal flow to next layer */ + + /*F(x,y)=F(x,y)+U^{l-1}(x,y)\cdot\overline{F(y,x)}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, *F, x, y, n)); + Cudd_Ref(q = Cudd_bddAnd(bdd, Cudd_Not(p), U[l-1])); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(r = Cudd_bddOr(bdd, *F, q)); + Cudd_RecursiveDeref(bdd,q); + Cudd_RecursiveDeref(bdd,*F); + *F = r; + if(pr>3){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + + /*F(y,x)=F(y,x)-U^{l-1}(x,y)*/ + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, U[l-1], x, y, n)); + Cudd_Ref(q = Cudd_bddAnd(bdd, *F, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,*F); + *F = q; + if(pr>1){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + + /*UT(x,y)=\exists_y(U^{l-1}(y,x))\cdot U^{l}(x,y)*/ + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, U[l-1], xcube)); + if(pr>4){(void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr);} + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, p, x, y, n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>4){(void) fprintf(stdout,"q");Cudd_PrintDebug(bdd,q,n,pr);} + Cudd_Ref(UT = Cudd_bddAnd(bdd, U[l], q)); + Cudd_RecursiveDeref(bdd,q); + if(pr>2){(void) fprintf(stdout,"UT");Cudd_PrintDebug(bdd,UT,n<<1,pr);} + + /*F(x,y)=F(x,y)+UT(x,y)\cdot\overline{F(y,x)}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, *F, x, y, n)); + Cudd_Ref(q = Cudd_bddAnd(bdd, Cudd_Not(p), UT)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(r = Cudd_bddOr(bdd, *F, q)); + Cudd_RecursiveDeref(bdd,q); + Cudd_RecursiveDeref(bdd,*F); + *F = r; + if(pr>3){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + + /*F(y,x)=F(y,x)-UT(x,y)*/ + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, UT, x, y, n)); + Cudd_RecursiveDeref(bdd,UT); + Cudd_Ref(q = Cudd_bddAnd(bdd, *F, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,*F); + *F = q; + if(pr>1){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + + return; + +} /* end of maximal_push */ + + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +trellisPush( + DdManager * bdd, + int m /* Current layer */, + DdNode ** U /* Array of edge sets for flow propagation */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* Arrays of variables for rows and columns */, + int n /* Number of x variables */, + DdNode * pryz, + DdNode * prxz /* Priority functions */, + flowStats * stats) +{ + DdNode *one, *zero, + *p, *r, + *Uin, /* Edges to be matched from U[m-1] */ + *Uout, /* Edges to be matched from U[m] */ + *RU, *LU, + *P, + *Ml; + + int i, + pr; /* Print control */ + + pr = stats->pr; + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /*Uout(x,y)=U^m(x,y)*/ + Cudd_Ref(Uout = U[m]); + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*Uin(x,y)=U^{m-1}(x,y)*/ + Cudd_Ref(Uin = U[m-1]); + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + for(i=0; ifpit++; + /*LU(x,y)=Uin(x,y)\cdot\overline{\exists_{z}(Uin(z,y)\cdot\Pi(x,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Uin, x, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, prxz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(LU = Cudd_bddAnd(bdd, Uin, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + if(pr>3){(void)fprintf(stdout,"LU");Cudd_PrintDebug(bdd,LU,n<<1,pr);} + + /*Ml(y)=\exists_{x}LU(x,y)*/ + Cudd_Ref(Ml = Cudd_bddExistAbstract(bdd, LU, xcube)); + if(pr>3){(void)fprintf(stdout,"Ml");Cudd_PrintDebug(bdd,Ml,n,pr);} + + /*P(x,y)=Ml(x)\cdot Uout(x,y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Ml, x, y, n)); + Cudd_Ref(P = Cudd_bddAnd(bdd, p, Uout)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Ml); + if(pr>3){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n<<1,pr);} + + /*RU(x,y)= P(x,y)\cdot \overline{\exists_{z}(P(x,z)\cdot \Pi(y,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, P, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, pryz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(RU = Cudd_bddAnd(bdd, P, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,P); + if(pr>3){(void)fprintf(stdout,"RU");Cudd_PrintDebug(bdd,RU,n<<1,pr);} + + /*Uin(x,y)=Uin(x,y)-LU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uin, Cudd_Not(LU))); + Cudd_RecursiveDeref(bdd,Uin); + Uin = p; + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + /*Uout(x,y)=Uout(x,y)-RU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uout, Cudd_Not(RU))); + Cudd_RecursiveDeref(bdd,Uout); + Cudd_RecursiveDeref(bdd,RU); + Uout = p; + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*\KW{if}(($LU(x,y)=zero$)~~\KW{or}~~($Uin(x,y)=zero$))~~KW{break}*/ + if((LU == zero)||(Uin == zero)) { + Cudd_RecursiveDeref(bdd,LU); + break; + } + + Cudd_RecursiveDeref(bdd,LU); + + } /* Next least fixed point iteration with smaller Uin and Uout */ + if (i == MAXFPIT) (void) fprintf(stderr, + "TrellisPush: ERROR! MAXFPIT (%d) exceeded at layer %d.\n", + MAXFPIT, m); + + /* $U^{m}(x,y) = U^{m}(x,y)-Uout(x,y)$*/ + if (Uout != zero) { + Cudd_Ref(p = Cudd_bddAnd(bdd, U[m], Cudd_Not(Uout))); + Cudd_RecursiveDeref(bdd,U[m]); + U[m] = p; + if(pr>3){(void)fprintf(stdout,"U[%d]",m); + Cudd_PrintDebug(bdd,U[m],n<<1,pr);} + } + + Cudd_RecursiveDeref(bdd,Uin); + Cudd_RecursiveDeref(bdd,Uout); + +} /* end of trellisPush */ + + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +rhombusPush( + DdManager * bdd, + int m /* Current layer */, + DdNode ** U /* Array of edge sets for flow propagation */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* Arrays of variables for rows and columns */, + int n /* Number of x variables */, + DdNode * pryz, + DdNode * prxz /* Priority functions */, + flowStats * stats) +{ + DdNode *one, *zero, + *p, *r, + *Uin, /* Edges to be matched from U[m-1] */ + *Uout, /* Edges to be matched from U[m] */ + *RU, *LU, + *P, + *Ml; + + int i, + pr; /* Print control */ + + pr = stats->pr; + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /*Uout(x,y)=U^m(x,y)*/ + Cudd_Ref(Uout = U[m]); + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*Uin(x,y)=U^{m-1}(x,y)*/ + Cudd_Ref(Uin = U[m-1]); + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + for(i = 0; i < MAXFPIT; i++) { + stats->fpit++; + /*RU(x,y)=Uin(x,y)\cdot\overline{\exists_{z}(Uin(x,z)\cdot\Pi(y,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Uin, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, pryz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(RU = Cudd_bddAnd(bdd, Uin, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + if(pr>3){(void)fprintf(stdout,"RU");Cudd_PrintDebug(bdd,RU,n<<1,pr);} + + /*Ml(y)=\exists_{x}RU(x,y)*/ + Cudd_Ref(Ml = Cudd_bddExistAbstract(bdd, RU, xcube)); + if(pr>3){(void)fprintf(stdout,"Ml");Cudd_PrintDebug(bdd,Ml,n,pr);} + + /*P(x,y)=Ml(x)\cdot Uout(x,y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Ml, x, y, n)); + Cudd_Ref(P = Cudd_bddAnd(bdd, p, Uout)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Ml); + if(pr>3){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n<<1,pr);} + + /*LU(x,y)= P(x,y)\cdot \overline{\exists_{z}(P(z,y)\cdot \Pi(x,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, P, x, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, prxz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(LU = Cudd_bddAnd(bdd, P, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,P); + if(pr>3){(void)fprintf(stdout,"LU");Cudd_PrintDebug(bdd,LU,n<<1,pr);} + + /*Uin(x,y)=Uin(x,y)-RU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uin, Cudd_Not(RU))); + Cudd_RecursiveDeref(bdd,Uin); + Uin = p; + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + /*Uout(x,y)=Uout(x,y)-LU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uout, Cudd_Not(LU))); + Cudd_RecursiveDeref(bdd,Uout); + Cudd_RecursiveDeref(bdd,LU); + Uout = p; + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*\KW{if}(($RU(x,y)=zero$)~~\KW{or}~~($Uin(x,y)=zero$))~~KW{break}*/ + if((RU == zero)||(Uin == zero)) { + Cudd_RecursiveDeref(bdd,RU); + break; + } + + Cudd_RecursiveDeref(bdd,RU); + + } /* Next least fixed point iteration with smaller Uin and Uout */ + if (i == MAXFPIT) (void) fprintf(stderr, + "RhombusPush: ERROR! MAXFPIT (%d) exceeded at layer %d.\n", + MAXFPIT, m); + + /* $U^{m}(x,y) = U^{m}(x,y)-Uout(x,y)$*/ + if (Uout != zero) { + Cudd_Ref(p = Cudd_bddAnd(bdd, U[m], Cudd_Not(Uout))); + Cudd_RecursiveDeref(bdd,U[m]); + U[m] = p; + if(pr>3){(void)fprintf(stdout,"U[%d]",m); + Cudd_PrintDebug(bdd,U[m],n<<1,pr);} + } + + Cudd_RecursiveDeref(bdd,Uin); + Cudd_RecursiveDeref(bdd,Uout); + + return; + +} /* end of rhombusPush */ + + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +hourglassPush( + DdManager * bdd, + int m /* Current layer */, + DdNode ** U /* Array of edge sets for flow propagation */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* Arrays of variables for rows and columns */, + int n /* Number of x variables */, + DdNode * pryz, + DdNode * prxz /* Priority functions */, + flowStats * stats) +{ + DdNode *one, *zero, + *przy, + *p, *q, *r, + *Uin, /* Edges to be matched from U[m-1] */ + *Uout, /* Edges to be matched from U[m] */ + *P, *Q, + *PA, *D; + + int i, + pr; /* Print control */ + + pr = stats->pr; + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /* Build priority function. */ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, pryz, y, z, n)); + Cudd_Ref(przy = Cudd_bddAdjPermuteX(bdd,p,x,n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>2){(void)fprintf(stdout,"przy");Cudd_PrintDebug(bdd,przy,n*3,pr);} + + /*Uout(x,y)=U^m(x,y)*/ + Cudd_Ref(Uout = U[m]); + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*Uin(x,y)=U^{m-1}(x,y)*/ + Cudd_Ref(Uin = U[m-1]); + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + for(i = 0; i < MAXFPIT; i++) { + stats->fpit++; + /*P(x,y,z)=Uin(x,y)\cdot Uout(y,z)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Uout, y, z, n)); + if(pr>2){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n<<1,pr);} + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, p, x, y, n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>2){(void)fprintf(stdout,"q");Cudd_PrintDebug(bdd,q,n<<1,pr);} + Cudd_Ref(P = Cudd_bddAnd(bdd, Uin, q)); + Cudd_RecursiveDeref(bdd,q); + if(pr>1){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n*3,pr);} + + /*PA(x,z)=\exists_yP(x,y,z)*/ + Cudd_Ref(PA = Cudd_bddExistAbstract(bdd, P, ycube)); + if(pr>2){(void)fprintf(stdout,"PA");Cudd_PrintDebug(bdd,PA,n<<1,pr);} + if(pr>3) { + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, PA, xcube)); + (void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, PA, zcube)); + (void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr); + Cudd_RecursiveDeref(bdd,p); + } + + /*Q(x,z)= PA(x,z)\cdot \overline{\exists_{y}(PA(x,y)\cdot \Pi(z,y))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, PA, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, przy, ycube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(Q = Cudd_bddAnd(bdd, PA, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,PA); + if(pr>2){(void)fprintf(stdout,"Q");Cudd_PrintDebug(bdd,Q,n<<1,pr);} + if(pr>3) { + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, Q, xcube)); + (void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr); + Cudd_RecursiveDeref(bdd,p); + } + + /*D(x,z)= Q(x,z)\cdot \overline{\exists_{y}(Q(y,z)\cdot \Pi(x,y))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Q, x, y, n)); + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, prxz, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, q, ycube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,q); + Cudd_Ref(D = Cudd_bddAnd(bdd, Q, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,Q); + if(pr>1){(void)fprintf(stdout,"D");Cudd_PrintDebug(bdd,D,n<<1,pr);} + + /*P(x,y,z)=P(x,y,z)\cdot D(x,z)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, P, D)); + Cudd_RecursiveDeref(bdd,D); + Cudd_RecursiveDeref(bdd,P); + P = p; + if(pr>2){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n*3,pr);} + + /*Uin(x,y)=Uin(x,y)-\exists_zP(x,y,z)*/ + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, P, zcube)); + if(pr>3){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n<<1,pr);} + Cudd_Ref(q = Cudd_bddAnd(bdd, Uin, Cudd_Not(p))); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Uin); + Uin = q; + if(pr>1){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + /*Uout(x,y)=Uout(x,y)-\exists_zP(z,x,y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, P, x, y, n)); + if(pr>3){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n*3,pr);} + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, p, y, z, n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>3){(void)fprintf(stdout,"r");Cudd_PrintDebug(bdd,r,n*3,pr);} + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, r, zcube)); + Cudd_RecursiveDeref(bdd,r); + if(pr>3){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n<<1,pr);} + Cudd_Ref(q = Cudd_bddAnd(bdd, Uout, Cudd_Not(p))); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Uout); + Uout = q; + if(pr>1){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*\KW{if}(($P(x,y,z)=zero$)~~\KW{or}~~($Uin(x,y)=zero$)~~\KW{or} + ($Uout(x,y)=zero$))~~KW{break}*/ + if((P == zero)||(Uin == zero)||(Uout == zero)) { + Cudd_RecursiveDeref(bdd,P); + break; + } + + Cudd_RecursiveDeref(bdd,P); + + } /* Next least fixed point iteration with smaller P */ + if (i == MAXFPIT) (void) fprintf(stderr, + "HourglassPush: ERROR! MAXFPIT (%d) exceeded at layer %d.\n", + MAXFPIT, m); + + /* $U^{m}(x,y) = U^{m}(x,y)-Uout(x,y)$*/ + if (Uout != zero) { + Cudd_Ref(p = Cudd_bddAnd(bdd, U[m], Cudd_Not(Uout))); + Cudd_RecursiveDeref(bdd,U[m]); + U[m] = p; + } + if(pr>1){(void)fprintf(stdout,"U[%d]",m); Cudd_PrintDebug(bdd,U[m],n<<1,pr);} + + Cudd_RecursiveDeref(bdd,Uin); + Cudd_RecursiveDeref(bdd,Uout); + Cudd_RecursiveDeref(bdd,przy); + + return; + +} /* end of hourglassPush */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntrShort.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrShort.c new file mode 100644 index 000000000..61ed980d3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrShort.c @@ -0,0 +1,578 @@ +/**CFile*********************************************************************** + + FileName [ntrShort.c] + + PackageName [ntr] + + Synopsis [Symbolic shortest paths algorithms.] + + Description [This file contains the functions that implement the + symbolic version of several shortest path algorithms described in the + JFM paper on ADDs.] + + Author [Fabio Somenzi, Iris Bahar] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: ntrShort.c,v 1.5 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * ntrBellman (DdManager *dd, DdNode *D, DdNode *source, DdNode **x, DdNode **y, int vars, int pr); +static DdNode * ntrWarshall (DdManager *dd, DdNode *D, DdNode **x, DdNode **y, int vars, int pr); +static DdNode * ntrSquare (DdManager *dd, DdNode *D, DdNode **x, DdNode **y, DdNode **z, int vars, int pr, int st); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Computes shortest paths in a state graph.] + + Description [Computes shortest paths in the state transition graph of + a network. Three methods are availabe: +
            +
          • Bellman-Ford algorithm for single-source shortest paths; the + algorithm computes the distance (number of transitions) from the initial + states to all states. +
          • Floyd-Warshall algorithm for all-pair shortest paths. +
          • Repeated squaring algorithm for all-pair shortest paths. +
          + The function returns 1 in case of success; 0 otherwise. + ] + + SideEffects [ADD variables are created in the manager.] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_ShortestPaths( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + NtrPartTR *TR; + DdNode *edges, *source, *res, *r, *q, *bddSource; + DdNode **xadd, **yadd, **zadd; + int i; + int pr = option->verb; + int algorithm = option->shortPath; + int selectiveTrace = option->selectiveTrace; + int nvars = net->nlatches; + + /* Set background to infinity for shortest paths. */ + Cudd_SetBackground(dd,Cudd_ReadPlusInfinity(dd)); + + /* Build the monolithic TR. */ + TR = Ntr_buildTR(dd,net,option,NTR_IMAGE_MONO); + + /* Build the ADD variable vectors for x and y. */ + xadd = ALLOC(DdNode *, nvars); + yadd = ALLOC(DdNode *, nvars); + for(i = 0; i < nvars; i++) { + q = Cudd_addIthVar(dd,TR->x[i]->index); + Cudd_Ref(q); + xadd[i] = q; + q = Cudd_addIthVar(dd,TR->y[i]->index); + Cudd_Ref(q); + yadd[i] = q; + } + + /* Convert the transition relation BDD into an ADD... */ + q = Cudd_BddToAdd(dd,TR->part[0]); + Cudd_Ref(q); + /* ...replacing zeroes with infinities... */ + r = Cudd_addIte(dd,q,Cudd_ReadOne(dd),Cudd_ReadPlusInfinity(dd)); + Cudd_Ref(r); + Cudd_RecursiveDeref(dd,q); + /* ...and zeroing the diagonal. */ + q = Cudd_addXeqy(dd,nvars,xadd,yadd); + Cudd_Ref(q); + edges = Cudd_addIte(dd,q,Cudd_ReadZero(dd),r); + Cudd_Ref(edges); + Cudd_RecursiveDeref(dd,r); + Cudd_RecursiveDeref(dd,q); + + switch(algorithm) { + case NTR_SHORT_BELLMAN: + bddSource = Ntr_initState(dd,net,option); + source = Cudd_BddToAdd(dd,bddSource); + Cudd_Ref(source); + res = ntrBellman(dd,edges,source,xadd,yadd,nvars,pr); + if (res == NULL) return(0); + Cudd_Ref(res); + Cudd_RecursiveDeref(dd,source); + Cudd_RecursiveDeref(dd,bddSource); + if (pr >= 0) { + (void) fprintf(stdout,"Distance Matrix"); + Cudd_PrintDebug(dd,res,nvars,pr); + } + break; + case NTR_SHORT_FLOYD: + res = ntrWarshall(dd,edges,xadd,yadd,nvars,pr); + if (res == NULL) return(0); + Cudd_Ref(res); + if (pr >= 0) { + (void) fprintf(stdout,"Distance Matrix"); + Cudd_PrintDebug(dd,res,2*nvars,pr); + } + break; + case NTR_SHORT_SQUARE: + /* Create a third set of ADD variables. */ + zadd = ALLOC(DdNode *, nvars); + for(i = 0; i < nvars; i++) { + int level; + level = Cudd_ReadIndex(dd,TR->x[i]->index); + q = Cudd_addNewVarAtLevel(dd,level); + Cudd_Ref(q); + zadd[i] = q; + } + /* Compute the shortest paths. */ + res = ntrSquare(dd,edges,zadd,yadd,xadd,nvars,pr,selectiveTrace); + if (res == NULL) return(0); + Cudd_Ref(res); + /* Dispose of the extra variables. */ + for(i = 0; i < nvars; i++) { + Cudd_RecursiveDeref(dd,zadd[i]); + } + FREE(zadd); + if (pr >= 0) { + (void) fprintf(stdout,"Distance Matrix"); + Cudd_PrintDebug(dd,res,2*nvars,pr); + } + break; + default: + (void) printf("Unrecognized method. Try again.\n"); + return(0); + } + + /* Here we should compute the paths. */ + + /* Clean up. */ + Ntr_freeTR(dd,TR); + Cudd_RecursiveDeref(dd,edges); + Cudd_RecursiveDeref(dd,res); + for(i = 0; i < nvars; i++) { + Cudd_RecursiveDeref(dd,xadd[i]); + Cudd_RecursiveDeref(dd,yadd[i]); + } + FREE(xadd); + FREE(yadd); + + if (option->autoDyn & 1) { + (void) printf("Order after short path computation\n"); + if (!Bnet_PrintOrder(net,dd)) return(0); + } + + return(1); + +} /* end of Ntr_ShortestPaths */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Bellman-Ford algorithm for single-source shortest paths.] + + Description [Bellman-Ford algorithm for single-source shortest + paths. Returns the vector of the distances of all states from the + initial states. In case of multiple initial states the distance for + each state is from the nearest initial state. Negative-weight + cycles are detected, though only in the naive way. (Lack of + convergence after nodes-1 iterations.) In such a case, a constant + ADD with value minus infinity is returned. Bellman-Ford is based on + matrix-vector multiplication. The matrix is the distance matrix + D(x,y), such that D(a,b) is the length of the arc connecting state a + to state b. The vector V(x) stores the distances of all states from + the initial states. The actual vector used in the matrix-vector + multiplication is diff(x), that holds those distances that have + changed during the last update.] + + SideEffects [] + + SeeAlso [ntrWarshall ntrSquare] + +******************************************************************************/ +static DdNode * +ntrBellman( + DdManager *dd, + DdNode *D, + DdNode *source, + DdNode **x, + DdNode **y, + int vars, + int pr) +{ + DdNode *u, *w, *V, *min, *diff; + DdApaNumber i, nodes, one; + int digits = vars + 1; + + /* To avoid overflow when there are many variables, use APA. */ + nodes = Cudd_NewApaNumber(digits); + Cudd_ApaPowerOfTwo(digits,nodes,vars); + i = Cudd_NewApaNumber(digits); + one = Cudd_NewApaNumber(digits); + Cudd_ApaSetToLiteral(digits,one,1); + +#if 0 + /* Find the distances from the initial state along paths using one + ** arc. */ + w = Cudd_Cofactor(dd,D,source); /* works only if source is a cube */ + Cudd_Ref(w); + V = Cudd_addSwapVariables(dd,w,x,y,vars); + Cudd_Ref(V); + Cudd_RecursiveDeref(dd,w); +#endif + + /* The initial states are at distance 0. The other states are + ** initially at infinite distance. */ + V = Cudd_addIte(dd,source,Cudd_ReadZero(dd),Cudd_ReadPlusInfinity(dd)); + Cudd_Ref(V); + + /* Selective trace algorithm. For the next update, only consider the + ** nodes whose distance has changed in the last update. */ + diff = V; + Cudd_Ref(diff); + + for (Cudd_ApaSetToLiteral(digits,i,1); + Cudd_ApaCompare(digits,i,digits,nodes) < 0; + Cudd_ApaAdd(digits,i,one,i)) { + if (pr>2) {(void) printf("V"); Cudd_PrintDebug(dd,V,vars,pr);} + /* Compute the distances via triangulation as a function of x. */ + w = Cudd_addTriangle(dd,diff,D,x,vars); + Cudd_Ref(w); + Cudd_RecursiveDeref(dd,diff); + u = Cudd_addSwapVariables(dd,w,x,y,vars); + Cudd_Ref(u); + Cudd_RecursiveDeref(dd,w); + if (pr>2) {(void) printf("u"); Cudd_PrintDebug(dd,u,vars,pr);} + + /* Take the minimum of the previous distances and those just + ** computed. */ + min = Cudd_addApply(dd,Cudd_addMinimum,V,u); + Cudd_Ref(min); + Cudd_RecursiveDeref(dd,u); + if (pr>2) {(void) printf("min"); Cudd_PrintDebug(dd,min,vars,pr);} + + if (V == min) { /* convergence */ + Cudd_RecursiveDeref(dd,min); + if (pr>0) { + (void) printf("Terminating after "); + Cudd_ApaPrintDecimal(stdout,digits,i); + (void) printf(" iterations\n"); + } + break; + } + /* Find the distances that decreased. */ + diff = Cudd_addApply(dd,Cudd_addDiff,V,min); + Cudd_Ref(diff); + if (pr>2) {(void) printf("diff"); Cudd_PrintDebug(dd,diff,vars,pr);} + Cudd_RecursiveDeref(dd,V); + V = min; + } + /* Negative cycle detection. */ + if (Cudd_ApaCompare(digits,i,digits,nodes) == 0 && + diff != Cudd_ReadPlusInfinity(dd)) { + (void) printf("Negative cycle\n"); + Cudd_RecursiveDeref(dd,diff); + Cudd_RecursiveDeref(dd,V); + V = Cudd_ReadMinusInfinity(dd); + Cudd_Ref(V); + } + + Cudd_Deref(V); + FREE(i); + FREE(nodes); + FREE(one); + return(V); + +} /* end of ntrBellman */ + + +/**Function******************************************************************** + + Synopsis [Floyd-Warshall algorithm for all-pair shortest paths.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +ntrWarshall( + DdManager *dd, + DdNode *D, + DdNode **x, + DdNode **y, + int vars, + int pr) +{ + DdNode *one, *zero; + DdNode *xminterm, *w, *V, *V2; + DdNode *P, *R; + int i; + int nodes; + int k,u; + long start_time; + if (vars > 30) + nodes = 1000000000; + else + nodes = 1 << vars; + + one = DD_ONE(dd); + zero = DD_ZERO(dd); + Cudd_Ref(R = D); /* make copy of original matrix */ + + /* Extract pivot row and column from D */ + start_time = util_cpu_time(); + for (k = 0; k < nodes; k++) { + if (k % 10000 == 0) { + (void) printf("Starting iteration %d at time %s\n", + k,util_print_time(util_cpu_time() - start_time)); + } + Cudd_Ref(xminterm = one); + u = k; + for (i = vars-1; i >= 0; i--) { + if (u&1) { + Cudd_Ref(w = Cudd_addIte(dd,x[i],xminterm,zero)); + } else { + Cudd_Ref(w = Cudd_addIte(dd,x[i],zero,xminterm)); + } + Cudd_RecursiveDeref(dd,xminterm); + xminterm = w; + u >>= 1; + } + + Cudd_Ref(V = Cudd_Cofactor(dd,R,xminterm)); + Cudd_RecursiveDeref(dd,xminterm); + if (pr>2) {(void) printf("V"); Cudd_PrintDebug(dd,V,vars,pr);} + + + Cudd_Ref(xminterm = one); + u = k; + for (i = vars-1; i >= 0; i--) { + if (u&1) { + Cudd_Ref(w = Cudd_addIte(dd,y[i],xminterm,zero)); + } else { + Cudd_Ref(w = Cudd_addIte(dd,y[i],zero,xminterm)); + } + Cudd_RecursiveDeref(dd,xminterm); + xminterm = w; + u >>= 1; + } + + Cudd_Ref(V2 = Cudd_Cofactor(dd,R,xminterm)); + Cudd_RecursiveDeref(dd,xminterm); + if (pr>2) {(void) printf("V2"); Cudd_PrintDebug(dd,V2,vars,pr);} + + Cudd_Ref(P = Cudd_addOuterSum(dd,R,V,V2)); + + Cudd_RecursiveDeref(dd,V); + Cudd_RecursiveDeref(dd,V2); + Cudd_RecursiveDeref(dd,R); + R = P; + if (pr>2) {(void) printf("R"); Cudd_PrintDebug(dd,R,vars,pr);} + } + + Cudd_Deref(R); + return(R); + +} /* end of ntrWarshall */ + + +/**Function******************************************************************** + + Synopsis [Repeated squaring algorithm for all-pairs shortest paths.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +ntrSquare( + DdManager *dd /* manager */, + DdNode *D /* D(z,y): distance matrix */, + DdNode **x /* array of x variables */, + DdNode **y /* array of y variables */, + DdNode **z /* array of z variables */, + int vars /* number of variables in each of the three arrays */, + int pr /* verbosity level */, + int st /* use the selective trace algorithm */) +{ + DdNode *zero; + DdNode *I; /* identity matirix */ + DdNode *w, *V, *P, *M, *R, *RT; + DdNode *diff, *min, *minDiag; + int n; + int neg; + long start_time; + + zero = Cudd_ReadZero(dd); + /* Make a working copy of the original matrix. */ + R = D; + Cudd_Ref(R); + I = Cudd_addXeqy(dd,vars,z,y); /* identity matrix */ + Cudd_Ref(I); + + /* Make a copy of the matrix for the selective trace algorithm. */ + diff = R; + Cudd_Ref(diff); + + start_time = util_cpu_time(); + for (n = vars; n >= 0; n--) { + printf("Starting iteration %d at time %s\n",vars-n, + util_print_time(util_cpu_time() - start_time)); + + /* Check for negative cycles: They are identified by negative + ** elements on the diagonal. + */ + + /* Extract values from the diagonal. */ + Cudd_Ref(w = Cudd_addIte(dd,I,R,zero)); + minDiag = Cudd_addFindMin(dd,w); /* no need to ref */ + neg = Cudd_V(minDiag) < 0; + Cudd_RecursiveDeref(dd,w); + if (neg) { + Cudd_RecursiveDeref(dd,diff); + (void) printf("Negative cycle after %d iterations!\n",vars-n); + break; + } + + /* Prepare the first operand of matrix multiplication: + ** diff(z,y) -> RT(x,y) -> V(x,z) + */ + + /* RT(x,y) */ + Cudd_Ref(RT = Cudd_addSwapVariables(dd,diff,x,z,vars)); + Cudd_RecursiveDeref(dd,diff); + /* V(x,z) */ + Cudd_Ref(V = Cudd_addSwapVariables(dd,RT,y,z,vars)); + Cudd_RecursiveDeref(dd,RT); + if (pr > 0) { + double pathcount; + (void) printf("V"); Cudd_PrintDebug(dd,V,2*vars,pr); + pathcount = Cudd_CountPath(V); + (void) printf("Path count = %g\n", pathcount); + } + + /* V(x,z) * R(z,y) -> P(x,y) */ + Cudd_Ref(P = Cudd_addTriangle(dd,V,R,z,vars)); + Cudd_RecursiveDeref(dd,V); + /* P(x,y) => M(z,y) */ + Cudd_Ref(M = Cudd_addSwapVariables(dd,P,x,z,vars)); + Cudd_RecursiveDeref(dd,P); + if (pr>0) {(void) printf("M"); Cudd_PrintDebug(dd,M,2*vars,pr);} + + /* min(z,y) */ + Cudd_Ref(min = Cudd_addApply(dd,Cudd_addMinimum,R,M)); + Cudd_RecursiveDeref(dd,M); + + if (R == min) { + Cudd_RecursiveDeref(dd,min); + if (pr>0) {printf("Done after %d iterations\n",vars-n+1); } + break; + } + /* diff(z,y) */ + if (st) { + Cudd_Ref(diff = Cudd_addApply(dd,Cudd_addDiff,min,R)); + } else { + Cudd_Ref(diff = min); + } + Cudd_RecursiveDeref(dd,R); + R = min; /* keep a copy of matrix at current iter. */ + if (pr > 0) { + double pathcount; + (void) printf("R"); Cudd_PrintDebug(dd,R,2*vars,pr); + pathcount = Cudd_CountPath(R); + (void) printf("Path count = %g\n", pathcount); + } + + if (n == 0) { + (void) printf("Negative cycle!\n"); + break; + } + + } + Cudd_RecursiveDeref(dd,I); + Cudd_Deref(R); + return(R); + +} /* end of ntrSquare */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntrZddTest.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrZddTest.c new file mode 100644 index 000000000..d1a8d83d3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrZddTest.c @@ -0,0 +1,468 @@ +/**CFile*********************************************************************** + + FileName [ntrZddTest.c] + + PackageName [ntr] + + Synopsis [ZDD test functions.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: ntrZddTest.c,v 1.15 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int reorderZdd (BnetNetwork *net, DdManager *dd, NtrOptions *option); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Tests ZDDs.] + + Description [Tests ZDDs. Returns 1 if successful; 0 otherwise.] + + SideEffects [Creates ZDD variables in the manager.] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_testZDD( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + DdNode **zdd; /* array of converted outputs */ + int nz; /* actual number of ZDDs */ + int result; + int i, j; + BnetNode *node; /* auxiliary pointer to network node */ + int pr = option->verb; + int level; /* aux. var. used to print variable orders */ + char **names; /* array used to print variable orders */ + int nvars; + + /* Build an array of ZDDs for the output functions or for the + ** specified node. */ + Cudd_AutodynDisable(dd); + Cudd_AutodynDisableZdd(dd); + zdd = ALLOC(DdNode *,net->noutputs); + result = Cudd_zddVarsFromBddVars(dd,1); + if (result == 0) return(0); + if (option->node == NULL) { + for (nz = 0; nz < net->noutputs; nz++) { + if (!st_lookup(net->hash,net->outputs[nz],&node)) { + return(0); + } + zdd[nz] = Cudd_zddPortFromBdd(dd, node->dd); + if (zdd[nz]) { + Cudd_Ref(zdd[nz]); + (void) printf("%s", node->name); + result = Cudd_zddPrintDebug(dd,zdd[nz],Cudd_ReadZddSize(dd),pr); + if (result == 0) return(0); + } else { + (void) printf("Conversion to ZDD failed.\n"); + } + } + } else { + if (!st_lookup(net->hash,option->node,&node)) { + return(0); + } + zdd[0] = Cudd_zddPortFromBdd(dd, node->dd); + if (zdd[0]) { + Cudd_Ref(zdd[0]); + (void) printf("%s", node->name); + result = Cudd_zddPrintDebug(dd,zdd[0],Cudd_ReadZddSize(dd),pr); + if (result == 0) return(0); + } else { + (void) printf("Conversion to ZDD failed.\n"); + } + nz = 1; + } + +#ifdef DD_DEBUG + result = Cudd_CheckKeys(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + return(0); + } +#endif + + if (option->autoDyn & 1) { + Cudd_AutodynEnable(dd,CUDD_REORDER_SAME); + } + if (option->autoDyn & 2) { + Cudd_AutodynEnableZdd(dd,CUDD_REORDER_SAME); + } + + /* Convert the ZDDs back to BDDs and check identity. */ + for (i = 0; i < nz; i++) { + DdNode *checkBdd; + checkBdd = Cudd_zddPortToBdd(dd,zdd[i]); + if (checkBdd) { + Cudd_Ref(checkBdd); + if (option->node == NULL) { + if (!st_lookup(net->hash,net->outputs[i],&node)) { + return(0); + } + } else { + if (!st_lookup(net->hash,option->node,&node)) { + return(0); + } + } + if (checkBdd != node->dd) { + (void) fprintf(stdout,"Equivalence failed at node %s", + node->name); + result = Cudd_PrintDebug(dd,checkBdd,Cudd_ReadZddSize(dd),pr); + if (result == 0) return(0); + } + Cudd_RecursiveDeref(dd,checkBdd); + } else { + (void) printf("Conversion to BDD failed.\n"); + } + } + +#ifdef DD_DEBUG + result = Cudd_CheckKeys(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + return(0); + } +#endif + + /* Play with the ZDDs a little. */ + if (nz > 2) { + DdNode *f; + DdNode *g1, *g2, *g; + f = Cudd_zddIte(dd,zdd[0],zdd[1],zdd[2]); + if (f == NULL) return(0); + cuddRef(f); + g1 = Cudd_zddIntersect(dd,zdd[0],zdd[1]); + if (g1 == NULL) { + Cudd_RecursiveDerefZdd(dd,f); + return(0); + } + cuddRef(g1); + g2 = Cudd_zddDiff(dd,zdd[2],zdd[0]); + if (g2 == NULL) { + Cudd_RecursiveDerefZdd(dd,f); + Cudd_RecursiveDerefZdd(dd,g1); + return(0); + } + cuddRef(g2); + g = Cudd_zddUnion(dd,g1,g2); + if (g == NULL) { + Cudd_RecursiveDerefZdd(dd,f); + Cudd_RecursiveDerefZdd(dd,g1); + Cudd_RecursiveDerefZdd(dd,g2); + return(0); + } + cuddRef(g); + Cudd_RecursiveDerefZdd(dd,g1); + Cudd_RecursiveDerefZdd(dd,g2); + if (g != f) { + (void) fprintf(stderr,"f != g!\n"); + } + Cudd_RecursiveDerefZdd(dd,g); + Cudd_RecursiveDerefZdd(dd,f); + } + +#ifdef DD_DEBUG + result = Cudd_CheckKeys(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + return(0); + } +#endif + + /* Perform ZDD reordering. */ + result = reorderZdd(net,dd,option); + if (result == 0) return(0); + + /* Print final ZDD order. */ + nvars = Cudd_ReadZddSize(dd); + names = ALLOC(char *, nvars); + if (names == NULL) return(0); + for (i = 0; i < nvars; i++) { + names[i] = NULL; + } + if (option->reordering != CUDD_REORDER_NONE) { + for (i = 0; i < net->npis; i++) { + if (!st_lookup(net->hash,net->inputs[i],&node)) { + FREE(names); + return(0); + } + level = Cudd_ReadPermZdd(dd,node->var); + names[level] = node->name; + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + FREE(names); + return(0); + } + level = Cudd_ReadPermZdd(dd,node->var); + names[level] = node->name; + } + (void) printf("New order\n"); + for (i = 0, j = 0; i < nvars; i++) { + if (names[i] == NULL) continue; + if((j%8 == 0)&&j) (void) printf("\n"); + (void) printf("%s ",names[i]); + j++; + } + (void) printf("\n"); + } + FREE(names); + + /* Dispose of ZDDs. */ + for (i = 0; i < nz; i++) { + Cudd_RecursiveDerefZdd(dd,zdd[i]); + } + FREE(zdd); + return(1); + +} /* end of Ntr_testZDD */ + + +/**Function******************************************************************** + + Synopsis [Builds ZDD covers.] + + Description [] + + SideEffects [Creates ZDD variables in the manager.] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_testISOP( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + DdNode **zdd; /* array of converted outputs */ + DdNode *bdd; /* return value of Cudd_zddIsop */ + int nz; /* actual number of ZDDs */ + int result; + int i; + BnetNode *node; /* auxiliary pointer to network node */ + int pr = option->verb; + + /* Build an array of ZDDs for the output functions or the specified + ** node. */ + Cudd_zddRealignEnable(dd); + Cudd_AutodynDisableZdd(dd); + zdd = ALLOC(DdNode *,net->noutputs); + result = Cudd_zddVarsFromBddVars(dd,2); + if (result == 0) return(0); + if (option->node == NULL) { + nz = net->noutputs; + for (i = 0; i < nz; i++) { + if (!st_lookup(net->hash,net->outputs[i],&node)) { + return(0); + } + bdd = Cudd_zddIsop(dd, node->dd, node->dd, &zdd[i]); + if (bdd != node->dd) return(0); + Cudd_Ref(bdd); + Cudd_RecursiveDeref(dd,bdd); + if (zdd[i]) { + Cudd_Ref(zdd[i]); + (void) printf("%s", node->name); + result = Cudd_zddPrintDebug(dd,zdd[i],Cudd_ReadZddSize(dd),pr); + if (result == 0) return(0); + if (option->printcover) { + int *path; + DdGen *gen; + char *str = ALLOC(char,Cudd_ReadSize(dd)+1); + if (str == NULL) return(0); + (void) printf("Testing iterator on ZDD paths:\n"); + Cudd_zddForeachPath(dd,zdd[i],gen,path) { + str = Cudd_zddCoverPathToString(dd,path,str); + (void) printf("%s 1\n", str); + } + (void) printf("\n"); + FREE(str); + result = Cudd_zddPrintCover(dd,zdd[i]); + + if (result == 0) return(0); + } + } else { + (void) printf("Conversion to ISOP failed.\n"); + return(0); + } + } + } else { + nz = 1; + if (!st_lookup(net->hash,option->node,&node)) { + return(0); + } + bdd = Cudd_zddIsop(dd, node->dd, node->dd, &zdd[0]); + if (bdd != node->dd) return(0); + Cudd_Ref(bdd); + Cudd_RecursiveDeref(dd,bdd); + if (zdd[0]) { + Cudd_Ref(zdd[0]); + (void) printf("%s", node->name); + result = Cudd_zddPrintDebug(dd,zdd[0],Cudd_ReadZddSize(dd),pr); + if (result == 0) return(0); + if (option->printcover) { + int *path; + DdGen *gen; + char *str = ALLOC(char,Cudd_ReadSize(dd)+1); + if (str == NULL) return(0); + (void) printf("Testing iterator on ZDD paths:\n"); + Cudd_zddForeachPath(dd,zdd[0],gen,path) { + str = Cudd_zddCoverPathToString(dd,path,str); + (void) printf("%s 1\n", str); + } + (void) printf("\n"); + FREE(str); + + result = Cudd_zddPrintCover(dd,zdd[0]); + if (result == 0) return(0); + } + } else { + (void) printf("Conversion to ISOP failed.\n"); + return(0); + } + } + if (option->autoDyn) { + Cudd_AutodynEnableZdd(dd,CUDD_REORDER_SAME); + } + + /* Perform ZDD reordering. */ + result = reorderZdd(net,dd,option); + if (result == 0) return(0); + + /* Dispose of ZDDs. */ + for (i = 0; i < nz; i++) { + Cudd_RecursiveDerefZdd(dd,zdd[i]); + } + FREE(zdd); + + return(1); + +} /* end of Ntr_testISOP */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Applies reordering to the ZDDs.] + + Description [Explicitly applies reordering to the ZDDs. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +static int +reorderZdd( + BnetNetwork * net, + DdManager * dd /* DD Manager */, + NtrOptions * option) +{ + int result; /* return value from functions */ + + /* Perform the final reordering. */ + if (option->reordering != CUDD_REORDER_NONE) { + (void) printf("Number of inputs = %d\n",net->ninputs); + + dd->siftMaxVar = 1000000; + result = Cudd_zddReduceHeap(dd,option->reordering,1); + if (result == 0) return(0); + + /* Print symmetry stats if pertinent */ + if (option->reordering == CUDD_REORDER_SYMM_SIFT || + option->reordering == CUDD_REORDER_SYMM_SIFT_CONV) + Cudd_zddSymmProfile(dd, 0, dd->sizeZ - 1); + } + + return(1); + +} /* end of reorderZdd */ + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.blif b/resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.blif new file mode 100644 index 000000000..c11dbe070 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.blif @@ -0,0 +1,335 @@ +.model rcn25 +.outputs n0 n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 n13 n14 n15 n16 n17 \ +n18 n19 n20 n21 n22 n23 n24 + +.latch nn0 n0 2 +.latch nn1 n1 2 +.latch nn2 n2 2 +.latch nn3 n3 2 +.latch nn4 n4 2 +.latch nn5 n5 2 +.latch nn6 n6 2 +.latch nn7 n7 2 +.latch nn8 n8 2 +.latch nn9 n9 2 +.latch nn10 n10 2 +.latch nn11 n11 2 +.latch nn12 n12 2 +.latch nn13 n13 2 +.latch nn14 n14 2 +.latch nn15 n15 2 +.latch nn16 n16 2 +.latch nn17 n17 2 +.latch nn18 n18 2 +.latch nn19 n19 2 +.latch nn20 n20 2 +.latch nn21 n21 2 +.latch nn22 n22 2 +.latch nn23 n23 2 +.latch nn24 n24 2 + +.names n0 s0 +0 1 +.names n0 c1 +1 1 +.names n1 n0 c1 s1 +100 1 +010 1 +001 1 +111 1 +.names n1 n0 c1 c2 +11- 1 +1-1 1 +-11 1 +.names n2 n1 c2 s2 +100 1 +010 1 +001 1 +111 1 +.names n2 n1 c2 c3 +11- 1 +1-1 1 +-11 1 +.names n3 n2 c3 s3 +100 1 +010 1 +001 1 +111 1 +.names n3 n2 c3 c4 +11- 1 +1-1 1 +-11 1 +.names n4 n3 c4 s4 +100 1 +010 1 +001 1 +111 1 +.names n4 n3 c4 c5 +11- 1 +1-1 1 +-11 1 +.names n5 n4 c5 s5 +100 1 +010 1 +001 1 +111 1 +.names n5 n4 c5 c6 +11- 1 +1-1 1 +-11 1 +.names n6 n5 c6 s6 +100 1 +010 1 +001 1 +111 1 +.names n6 n5 c6 c7 +11- 1 +1-1 1 +-11 1 +.names n7 n6 c7 s7 +100 1 +010 1 +001 1 +111 1 +.names n7 n6 c7 c8 +11- 1 +1-1 1 +-11 1 +.names n8 n7 c8 s8 +100 1 +010 1 +001 1 +111 1 +.names n8 n7 c8 c9 +11- 1 +1-1 1 +-11 1 +.names n9 n8 c9 s9 +100 1 +010 1 +001 1 +111 1 +.names n9 n8 c9 c10 +11- 1 +1-1 1 +-11 1 +.names n10 n9 c10 s10 +100 1 +010 1 +001 1 +111 1 +.names n10 n9 c10 c11 +11- 1 +1-1 1 +-11 1 +.names n11 n10 c11 s11 +100 1 +010 1 +001 1 +111 1 +.names n11 n10 c11 c12 +11- 1 +1-1 1 +-11 1 +.names n12 n11 c12 s12 +100 1 +010 1 +001 1 +111 1 +.names n12 n11 c12 c13 +11- 1 +1-1 1 +-11 1 +.names n13 n12 c13 s13 +100 1 +010 1 +001 1 +111 1 +.names n13 n12 c13 c14 +11- 1 +1-1 1 +-11 1 +.names n14 n13 c14 s14 +100 1 +010 1 +001 1 +111 1 +.names n14 n13 c14 c15 +11- 1 +1-1 1 +-11 1 +.names n15 n14 c15 s15 +100 1 +010 1 +001 1 +111 1 +.names n15 n14 c15 c16 +11- 1 +1-1 1 +-11 1 +.names n16 n15 c16 s16 +100 1 +010 1 +001 1 +111 1 +.names n16 n15 c16 c17 +11- 1 +1-1 1 +-11 1 +.names n17 n16 c17 s17 +100 1 +010 1 +001 1 +111 1 +.names n17 n16 c17 c18 +11- 1 +1-1 1 +-11 1 +.names n18 n17 c18 s18 +100 1 +010 1 +001 1 +111 1 +.names n18 n17 c18 c19 +11- 1 +1-1 1 +-11 1 +.names n19 n18 c19 s19 +100 1 +010 1 +001 1 +111 1 +.names n19 n18 c19 c20 +11- 1 +1-1 1 +-11 1 +.names n20 n19 c20 s20 +100 1 +010 1 +001 1 +111 1 +.names n20 n19 c20 c21 +11- 1 +1-1 1 +-11 1 +.names n21 n20 c21 s21 +100 1 +010 1 +001 1 +111 1 +.names n21 n20 c21 c22 +11- 1 +1-1 1 +-11 1 +.names n22 n21 c22 s22 +100 1 +010 1 +001 1 +111 1 +.names n22 n21 c22 c23 +11- 1 +1-1 1 +-11 1 +.names n23 n22 c23 s23 +100 1 +010 1 +001 1 +111 1 +.names n23 n22 c23 c24 +11- 1 +1-1 1 +-11 1 +.names n24 n23 c24 s24 +100 1 +010 1 +001 1 +111 1 +.names n24 n23 c24 c25 +11- 1 +1-1 1 +-11 1 +.names n24 c25 s25 +10 1 +01 1 +.names n24 c25 s26 +11 1 + +.names s25 s26 of +00 0 + +.names n0 of s0 n1 nn0 +101- 1 +0--1 1 +.names n0 of s1 n2 nn1 +101- 1 +0--1 1 +.names n0 of s2 n3 nn2 +101- 1 +0--1 1 +.names n0 of s3 n4 nn3 +101- 1 +0--1 1 +.names n0 of s4 n5 nn4 +101- 1 +0--1 1 +.names n0 of s5 n6 nn5 +101- 1 +0--1 1 +.names n0 of s6 n7 nn6 +101- 1 +0--1 1 +.names n0 of s7 n8 nn7 +101- 1 +0--1 1 +.names n0 of s8 n9 nn8 +101- 1 +0--1 1 +.names n0 of s9 n10 nn9 +101- 1 +0--1 1 +.names n0 of s10 n11 nn10 +101- 1 +0--1 1 +.names n0 of s11 n12 nn11 +101- 1 +0--1 1 +.names n0 of s12 n13 nn12 +101- 1 +0--1 1 +.names n0 of s13 n14 nn13 +101- 1 +0--1 1 +.names n0 of s14 n15 nn14 +101- 1 +0--1 1 +.names n0 of s15 n16 nn15 +101- 1 +0--1 1 +.names n0 of s16 n17 nn16 +101- 1 +0--1 1 +.names n0 of s17 n18 nn17 +101- 1 +0--1 1 +.names n0 of s18 n19 nn18 +101- 1 +0--1 1 +.names n0 of s19 n20 nn19 +101- 1 +0--1 1 +.names n0 of s20 n21 nn20 +101- 1 +0--1 1 +.names n0 of s21 n22 nn21 +101- 1 +0--1 1 +.names n0 of s22 n23 nn22 +101- 1 +0--1 1 +.names n0 of s23 n24 nn23 +101- 1 +0--1 1 +.names n0 of s24 nn24 +101 1 + +.end diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.out b/resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.out new file mode 100644 index 000000000..a44f9703c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.out @@ -0,0 +1,521 @@ +# Nanotrav Version #0.12, Release date 2003/12/31 +# ./nanotrav -p 1 -envelope rcn25.blif +# CUDD Version 2.4.2 +Order before final reordering +n0 n1 n2 n3 n4 n5 n6 n7 +n8 n9 n10 n11 n12 n13 n14 n15 +n16 n17 n18 n19 n20 n21 n22 n23 +n24 +Number of inputs = 25 +@@@@@@@@@@@@@@@@@@@@@@@@@ +S0: 1 nodes 1 leaves 3.35544e+07 minterms +Envelope[1]: 68 nodes 1 leaves 1.95734e+07 minterms +Envelope[2]: 131 nodes 1 leaves 1.53791e+07 minterms +Envelope[3]: 240 nodes 1 leaves 1.30489e+07 minterms +Envelope[4]: 351 nodes 1 leaves 1.07188e+07 minterms +Envelope[5]: 365 nodes 1 leaves 9.08766e+06 minterms +Envelope[6]: 672 nodes 1 leaves 7.88374e+06 minterms +Envelope[7]: 977 nodes 1 leaves 6.85458e+06 minterms +Envelope[8]: 1697 nodes 1 leaves 6.16039e+06 minterms +Envelope[9]: 2507 nodes 1 leaves 5.53173e+06 minterms +Envelope[10]: 2728 nodes 1 leaves 4.99328e+06 minterms +Envelope[11]: 4877 nodes 1 leaves 4.56022e+06 minterms +Envelope[12]: 7131 nodes 1 leaves 4.15173e+06 minterms +Envelope[13]: 10837 nodes 1 leaves 3.83181e+06 minterms +Envelope[14]: 16376 nodes 1 leaves 3.53694e+06 minterms +Envelope[15]: 18686 nodes 1 leaves 3.26485e+06 minterms +Envelope[16]: 27175 nodes 1 leaves 3.03016e+06 minterms +Envelope[17]: 37624 nodes 1 leaves 2.81134e+06 minterms +Envelope[18]: 42091 nodes 1 leaves 2.62598e+06 minterms +Envelope[19]: 64761 nodes 1 leaves 2.45532e+06 minterms +Envelope[20]: 88199 nodes 1 leaves 2.29512e+06 minterms +Envelope[21]: 112012 nodes 1 leaves 2.15501e+06 minterms +Envelope[22]: 148131 nodes 1 leaves 2.02284e+06 minterms +Envelope[23]: 178957 nodes 1 leaves 1.90343e+06 minterms +Envelope[24]: 213207 nodes 1 leaves 1.79426e+06 minterms +Envelope[25]: 251015 nodes 1 leaves 1.69064e+06 minterms +Envelope[26]: 278969 nodes 1 leaves 1.59836e+06 minterms +Envelope[27]: 298983 nodes 1 leaves 1.51117e+06 minterms +Envelope[28]: 310186 nodes 1 leaves 1.4295e+06 minterms +Envelope[29]: 314312 nodes 1 leaves 1.35474e+06 minterms +Envelope[30]: 312346 nodes 1 leaves 1.2838e+06 minterms +Envelope[31]: 308909 nodes 1 leaves 1.21948e+06 minterms +Envelope[32]: 304183 nodes 1 leaves 1.15867e+06 minterms +Envelope[33]: 298541 nodes 1 leaves 1.10083e+06 minterms +Envelope[34]: 292868 nodes 1 leaves 1.04754e+06 minterms +Envelope[35]: 286698 nodes 1 leaves 996946 minterms +Envelope[36]: 280610 nodes 1 leaves 949953 minterms +Envelope[37]: 274275 nodes 1 leaves 905778 minterms +Envelope[38]: 267711 nodes 1 leaves 863616 minterms +Envelope[39]: 261513 nodes 1 leaves 824606 minterms +Envelope[40]: 255196 nodes 1 leaves 787378 minterms +Envelope[41]: 248890 nodes 1 leaves 752197 minterms +Envelope[42]: 242617 nodes 1 leaves 719152 minterms +Envelope[43]: 236080 nodes 1 leaves 687560 minterms +Envelope[44]: 230130 nodes 1 leaves 658155 minterms +Envelope[45]: 224259 nodes 1 leaves 629967 minterms +Envelope[46]: 218166 nodes 1 leaves 603079 minterms +Envelope[47]: 212397 nodes 1 leaves 577815 minterms +Envelope[48]: 206597 nodes 1 leaves 553658 minterms +Envelope[49]: 201169 nodes 1 leaves 531033 minterms +Envelope[50]: 195784 nodes 1 leaves 509531 minterms +Envelope[51]: 190388 nodes 1 leaves 488904 minterms +Envelope[52]: 185402 nodes 1 leaves 469490 minterms +Envelope[53]: 180396 nodes 1 leaves 450891 minterms +Envelope[54]: 175724 nodes 1 leaves 433247 minterms +Envelope[55]: 171253 nodes 1 leaves 416458 minterms +Envelope[56]: 166524 nodes 1 leaves 400345 minterms +Envelope[57]: 162304 nodes 1 leaves 385129 minterms +Envelope[58]: 158158 nodes 1 leaves 370518 minterms +Envelope[59]: 154136 nodes 1 leaves 356541 minterms +Envelope[60]: 150218 nodes 1 leaves 343262 minterms +Envelope[61]: 146293 nodes 1 leaves 330504 minterms +Envelope[62]: 142731 nodes 1 leaves 318444 minterms +Envelope[63]: 139152 nodes 1 leaves 306873 minterms +Envelope[64]: 135570 nodes 1 leaves 295766 minterms +Envelope[65]: 132114 nodes 1 leaves 285183 minterms +Envelope[66]: 128777 nodes 1 leaves 275032 minterms +Envelope[67]: 125644 nodes 1 leaves 265348 minterms +Envelope[68]: 122532 nodes 1 leaves 256089 minterms +Envelope[69]: 119388 nodes 1 leaves 247191 minterms +Envelope[70]: 116557 nodes 1 leaves 238707 minterms +Envelope[71]: 113576 nodes 1 leaves 230531 minterms +Envelope[72]: 110737 nodes 1 leaves 222700 minterms +Envelope[73]: 107964 nodes 1 leaves 215170 minterms +Envelope[74]: 105272 nodes 1 leaves 207896 minterms +Envelope[75]: 102720 nodes 1 leaves 200935 minterms +Envelope[76]: 100098 nodes 1 leaves 194214 minterms +Envelope[77]: 97630 nodes 1 leaves 187719 minterms +Envelope[78]: 95248 nodes 1 leaves 181488 minterms +Envelope[79]: 92891 nodes 1 leaves 175479 minterms +Envelope[80]: 90738 nodes 1 leaves 169733 minterms +Envelope[81]: 88566 nodes 1 leaves 164201 minterms +Envelope[82]: 86372 nodes 1 leaves 158855 minterms +Envelope[83]: 84200 nodes 1 leaves 153722 minterms +Envelope[84]: 82108 nodes 1 leaves 148752 minterms +Envelope[85]: 80162 nodes 1 leaves 143977 minterms +Envelope[86]: 78254 nodes 1 leaves 139369 minterms +Envelope[87]: 76349 nodes 1 leaves 134921 minterms +Envelope[88]: 74645 nodes 1 leaves 130668 minterms +Envelope[89]: 72849 nodes 1 leaves 126558 minterms +Envelope[90]: 71140 nodes 1 leaves 122588 minterms +Envelope[91]: 69484 nodes 1 leaves 118779 minterms +Envelope[92]: 67898 nodes 1 leaves 115076 minterms +Envelope[93]: 66429 nodes 1 leaves 111539 minterms +Envelope[94]: 64879 nodes 1 leaves 108113 minterms +Envelope[95]: 63332 nodes 1 leaves 104807 minterms +Envelope[96]: 61892 nodes 1 leaves 101634 minterms +Envelope[97]: 60487 nodes 1 leaves 98554 minterms +Envelope[98]: 59076 nodes 1 leaves 95579 minterms +Envelope[99]: 57675 nodes 1 leaves 92712 minterms +Envelope[100]: 56346 nodes 1 leaves 89943 minterms +Envelope[101]: 55101 nodes 1 leaves 87270 minterms +Envelope[102]: 53857 nodes 1 leaves 84669 minterms +Envelope[103]: 52673 nodes 1 leaves 82155 minterms +Envelope[104]: 51498 nodes 1 leaves 79722 minterms +Envelope[105]: 50375 nodes 1 leaves 77355 minterms +Envelope[106]: 49253 nodes 1 leaves 75077 minterms +Envelope[107]: 48157 nodes 1 leaves 72867 minterms +Envelope[108]: 47096 nodes 1 leaves 70729 minterms +Envelope[109]: 46100 nodes 1 leaves 68652 minterms +Envelope[110]: 45047 nodes 1 leaves 66635 minterms +Envelope[111]: 44107 nodes 1 leaves 64689 minterms +Envelope[112]: 43198 nodes 1 leaves 62806 minterms +Envelope[113]: 42227 nodes 1 leaves 60981 minterms +Envelope[114]: 41297 nodes 1 leaves 59228 minterms +Envelope[115]: 40371 nodes 1 leaves 57524 minterms +Envelope[116]: 39479 nodes 1 leaves 55874 minterms +Envelope[117]: 38623 nodes 1 leaves 54279 minterms +Envelope[118]: 37792 nodes 1 leaves 52739 minterms +Envelope[119]: 37000 nodes 1 leaves 51264 minterms +Envelope[120]: 36185 nodes 1 leaves 49837 minterms +Envelope[121]: 35400 nodes 1 leaves 48443 minterms +Envelope[122]: 34580 nodes 1 leaves 47093 minterms +Envelope[123]: 33793 nodes 1 leaves 45782 minterms +Envelope[124]: 33084 nodes 1 leaves 44519 minterms +Envelope[125]: 32388 nodes 1 leaves 43292 minterms +Envelope[126]: 31710 nodes 1 leaves 42089 minterms +Envelope[127]: 31025 nodes 1 leaves 40920 minterms +Envelope[128]: 30350 nodes 1 leaves 39778 minterms +Envelope[129]: 29683 nodes 1 leaves 38664 minterms +Envelope[130]: 29050 nodes 1 leaves 37589 minterms +Envelope[131]: 28418 nodes 1 leaves 36551 minterms +Envelope[132]: 27804 nodes 1 leaves 35547 minterms +Envelope[133]: 27184 nodes 1 leaves 34573 minterms +Envelope[134]: 26621 nodes 1 leaves 33636 minterms +Envelope[135]: 26074 nodes 1 leaves 32724 minterms +Envelope[136]: 25528 nodes 1 leaves 31831 minterms +Envelope[137]: 24996 nodes 1 leaves 30967 minterms +Envelope[138]: 24472 nodes 1 leaves 30133 minterms +Envelope[139]: 23993 nodes 1 leaves 29324 minterms +Envelope[140]: 23514 nodes 1 leaves 28535 minterms +Envelope[141]: 23008 nodes 1 leaves 27769 minterms +Envelope[142]: 22525 nodes 1 leaves 27029 minterms +Envelope[143]: 22039 nodes 1 leaves 26318 minterms +Envelope[144]: 21561 nodes 1 leaves 25624 minterms +Envelope[145]: 21094 nodes 1 leaves 24950 minterms +Envelope[146]: 20685 nodes 1 leaves 24289 minterms +Envelope[147]: 20249 nodes 1 leaves 23651 minterms +Envelope[148]: 19794 nodes 1 leaves 23023 minterms +Envelope[149]: 19369 nodes 1 leaves 22418 minterms +Envelope[150]: 18976 nodes 1 leaves 21837 minterms +Envelope[151]: 18589 nodes 1 leaves 21272 minterms +Envelope[152]: 18201 nodes 1 leaves 20723 minterms +Envelope[153]: 17806 nodes 1 leaves 20198 minterms +Envelope[154]: 17419 nodes 1 leaves 19684 minterms +Envelope[155]: 17049 nodes 1 leaves 19180 minterms +Envelope[156]: 16672 nodes 1 leaves 18691 minterms +Envelope[157]: 16315 nodes 1 leaves 18214 minterms +Envelope[158]: 16005 nodes 1 leaves 17741 minterms +Envelope[159]: 15679 nodes 1 leaves 17284 minterms +Envelope[160]: 15341 nodes 1 leaves 16836 minterms +Envelope[161]: 14999 nodes 1 leaves 16397 minterms +Envelope[162]: 14667 nodes 1 leaves 15962 minterms +Envelope[163]: 14365 nodes 1 leaves 15544 minterms +Envelope[164]: 14066 nodes 1 leaves 15138 minterms +Envelope[165]: 13792 nodes 1 leaves 14743 minterms +Envelope[166]: 13539 nodes 1 leaves 14361 minterms +Envelope[167]: 13283 nodes 1 leaves 13992 minterms +Envelope[168]: 13022 nodes 1 leaves 13632 minterms +Envelope[169]: 12765 nodes 1 leaves 13280 minterms +Envelope[170]: 12497 nodes 1 leaves 12938 minterms +Envelope[171]: 12257 nodes 1 leaves 12605 minterms +Envelope[172]: 11990 nodes 1 leaves 12279 minterms +Envelope[173]: 11716 nodes 1 leaves 11958 minterms +Envelope[174]: 11436 nodes 1 leaves 11646 minterms +Envelope[175]: 11180 nodes 1 leaves 11345 minterms +Envelope[176]: 10939 nodes 1 leaves 11056 minterms +Envelope[177]: 10717 nodes 1 leaves 10771 minterms +Envelope[178]: 10488 nodes 1 leaves 10493 minterms +Envelope[179]: 10255 nodes 1 leaves 10221 minterms +Envelope[180]: 10013 nodes 1 leaves 9957 minterms +Envelope[181]: 9810 nodes 1 leaves 9699 minterms +Envelope[182]: 9568 nodes 1 leaves 9449 minterms +Envelope[183]: 9355 nodes 1 leaves 9206 minterms +Envelope[184]: 9176 nodes 1 leaves 8967 minterms +Envelope[185]: 8990 nodes 1 leaves 8733 minterms +Envelope[186]: 8810 nodes 1 leaves 8512 minterms +Envelope[187]: 8621 nodes 1 leaves 8297 minterms +Envelope[188]: 8421 nodes 1 leaves 8091 minterms +Envelope[189]: 8200 nodes 1 leaves 7895 minterms +Envelope[190]: 7992 nodes 1 leaves 7705 minterms +Envelope[191]: 7816 nodes 1 leaves 7519 minterms +Envelope[192]: 7641 nodes 1 leaves 7338 minterms +Envelope[193]: 7475 nodes 1 leaves 7161 minterms +Envelope[194]: 7307 nodes 1 leaves 6986 minterms +Envelope[195]: 7137 nodes 1 leaves 6814 minterms +Envelope[196]: 6956 nodes 1 leaves 6644 minterms +Envelope[197]: 6784 nodes 1 leaves 6477 minterms +Envelope[198]: 6642 nodes 1 leaves 6315 minterms +Envelope[199]: 6515 nodes 1 leaves 6157 minterms +Envelope[200]: 6377 nodes 1 leaves 6000 minterms +Envelope[201]: 6221 nodes 1 leaves 5847 minterms +Envelope[202]: 6069 nodes 1 leaves 5699 minterms +Envelope[203]: 5919 nodes 1 leaves 5555 minterms +Envelope[204]: 5797 nodes 1 leaves 5417 minterms +Envelope[205]: 5662 nodes 1 leaves 5282 minterms +Envelope[206]: 5535 nodes 1 leaves 5149 minterms +Envelope[207]: 5414 nodes 1 leaves 5018 minterms +Envelope[208]: 5293 nodes 1 leaves 4890 minterms +Envelope[209]: 5170 nodes 1 leaves 4765 minterms +Envelope[210]: 5057 nodes 1 leaves 4644 minterms +Envelope[211]: 4948 nodes 1 leaves 4526 minterms +Envelope[212]: 4856 nodes 1 leaves 4410 minterms +Envelope[213]: 4763 nodes 1 leaves 4296 minterms +Envelope[214]: 4651 nodes 1 leaves 4183 minterms +Envelope[215]: 4568 nodes 1 leaves 4076 minterms +Envelope[216]: 4488 nodes 1 leaves 3972 minterms +Envelope[217]: 4406 nodes 1 leaves 3869 minterms +Envelope[218]: 4322 nodes 1 leaves 3771 minterms +Envelope[219]: 4249 nodes 1 leaves 3677 minterms +Envelope[220]: 4177 nodes 1 leaves 3586 minterms +Envelope[221]: 4102 nodes 1 leaves 3496 minterms +Envelope[222]: 4021 nodes 1 leaves 3408 minterms +Envelope[223]: 3949 nodes 1 leaves 3322 minterms +Envelope[224]: 3871 nodes 1 leaves 3238 minterms +Envelope[225]: 3800 nodes 1 leaves 3158 minterms +Envelope[226]: 3740 nodes 1 leaves 3079 minterms +Envelope[227]: 3674 nodes 1 leaves 3002 minterms +Envelope[228]: 3618 nodes 1 leaves 2926 minterms +Envelope[229]: 3552 nodes 1 leaves 2852 minterms +Envelope[230]: 3485 nodes 1 leaves 2780 minterms +Envelope[231]: 3428 nodes 1 leaves 2711 minterms +Envelope[232]: 3370 nodes 1 leaves 2643 minterms +Envelope[233]: 3304 nodes 1 leaves 2575 minterms +Envelope[234]: 3244 nodes 1 leaves 2510 minterms +Envelope[235]: 3177 nodes 1 leaves 2447 minterms +Envelope[236]: 3112 nodes 1 leaves 2385 minterms +Envelope[237]: 3054 nodes 1 leaves 2324 minterms +Envelope[238]: 2999 nodes 1 leaves 2268 minterms +Envelope[239]: 2947 nodes 1 leaves 2212 minterms +Envelope[240]: 2892 nodes 1 leaves 2157 minterms +Envelope[241]: 2831 nodes 1 leaves 2104 minterms +Envelope[242]: 2769 nodes 1 leaves 2052 minterms +Envelope[243]: 2709 nodes 1 leaves 2001 minterms +Envelope[244]: 2644 nodes 1 leaves 1952 minterms +Envelope[245]: 2569 nodes 1 leaves 1903 minterms +Envelope[246]: 2505 nodes 1 leaves 1855 minterms +Envelope[247]: 2432 nodes 1 leaves 1807 minterms +Envelope[248]: 2361 nodes 1 leaves 1760 minterms +Envelope[249]: 2289 nodes 1 leaves 1715 minterms +Envelope[250]: 2215 nodes 1 leaves 1673 minterms +Envelope[251]: 2169 nodes 1 leaves 1632 minterms +Envelope[252]: 2114 nodes 1 leaves 1591 minterms +Envelope[253]: 2063 nodes 1 leaves 1551 minterms +Envelope[254]: 2011 nodes 1 leaves 1512 minterms +Envelope[255]: 1957 nodes 1 leaves 1473 minterms +Envelope[256]: 1902 nodes 1 leaves 1434 minterms +Envelope[257]: 1852 nodes 1 leaves 1396 minterms +Envelope[258]: 1805 nodes 1 leaves 1359 minterms +Envelope[259]: 1763 nodes 1 leaves 1322 minterms +Envelope[260]: 1711 nodes 1 leaves 1287 minterms +Envelope[261]: 1653 nodes 1 leaves 1255 minterms +Envelope[262]: 1604 nodes 1 leaves 1223 minterms +Envelope[263]: 1557 nodes 1 leaves 1193 minterms +Envelope[264]: 1515 nodes 1 leaves 1164 minterms +Envelope[265]: 1482 nodes 1 leaves 1136 minterms +Envelope[266]: 1447 nodes 1 leaves 1108 minterms +Envelope[267]: 1416 nodes 1 leaves 1081 minterms +Envelope[268]: 1383 nodes 1 leaves 1054 minterms +Envelope[269]: 1353 nodes 1 leaves 1028 minterms +Envelope[270]: 1323 nodes 1 leaves 1003 minterms +Envelope[271]: 1290 nodes 1 leaves 978 minterms +Envelope[272]: 1252 nodes 1 leaves 954 minterms +Envelope[273]: 1215 nodes 1 leaves 931 minterms +Envelope[274]: 1174 nodes 1 leaves 908 minterms +Envelope[275]: 1144 nodes 1 leaves 887 minterms +Envelope[276]: 1120 nodes 1 leaves 867 minterms +Envelope[277]: 1102 nodes 1 leaves 848 minterms +Envelope[278]: 1082 nodes 1 leaves 830 minterms +Envelope[279]: 1061 nodes 1 leaves 812 minterms +Envelope[280]: 1045 nodes 1 leaves 795 minterms +Envelope[281]: 1031 nodes 1 leaves 778 minterms +Envelope[282]: 1015 nodes 1 leaves 763 minterms +Envelope[283]: 1004 nodes 1 leaves 748 minterms +Envelope[284]: 996 nodes 1 leaves 733 minterms +Envelope[285]: 983 nodes 1 leaves 719 minterms +Envelope[286]: 964 nodes 1 leaves 705 minterms +Envelope[287]: 949 nodes 1 leaves 691 minterms +Envelope[288]: 938 nodes 1 leaves 677 minterms +Envelope[289]: 925 nodes 1 leaves 663 minterms +Envelope[290]: 913 nodes 1 leaves 650 minterms +Envelope[291]: 907 nodes 1 leaves 637 minterms +Envelope[292]: 901 nodes 1 leaves 624 minterms +Envelope[293]: 887 nodes 1 leaves 611 minterms +Envelope[294]: 878 nodes 1 leaves 598 minterms +Envelope[295]: 872 nodes 1 leaves 585 minterms +Envelope[296]: 860 nodes 1 leaves 573 minterms +Envelope[297]: 852 nodes 1 leaves 561 minterms +Envelope[298]: 842 nodes 1 leaves 549 minterms +Envelope[299]: 834 nodes 1 leaves 537 minterms +Envelope[300]: 826 nodes 1 leaves 526 minterms +Envelope[301]: 819 nodes 1 leaves 515 minterms +Envelope[302]: 808 nodes 1 leaves 505 minterms +Envelope[303]: 797 nodes 1 leaves 495 minterms +Envelope[304]: 789 nodes 1 leaves 485 minterms +Envelope[305]: 773 nodes 1 leaves 475 minterms +Envelope[306]: 758 nodes 1 leaves 465 minterms +Envelope[307]: 742 nodes 1 leaves 455 minterms +Envelope[308]: 727 nodes 1 leaves 445 minterms +Envelope[309]: 711 nodes 1 leaves 435 minterms +Envelope[310]: 698 nodes 1 leaves 425 minterms +Envelope[311]: 677 nodes 1 leaves 415 minterms +Envelope[312]: 662 nodes 1 leaves 405 minterms +Envelope[313]: 653 nodes 1 leaves 395 minterms +Envelope[314]: 638 nodes 1 leaves 386 minterms +Envelope[315]: 625 nodes 1 leaves 377 minterms +Envelope[316]: 611 nodes 1 leaves 368 minterms +Envelope[317]: 603 nodes 1 leaves 359 minterms +Envelope[318]: 598 nodes 1 leaves 350 minterms +Envelope[319]: 588 nodes 1 leaves 342 minterms +Envelope[320]: 581 nodes 1 leaves 334 minterms +Envelope[321]: 576 nodes 1 leaves 326 minterms +Envelope[322]: 566 nodes 1 leaves 318 minterms +Envelope[323]: 555 nodes 1 leaves 311 minterms +Envelope[324]: 546 nodes 1 leaves 305 minterms +Envelope[325]: 537 nodes 1 leaves 299 minterms +Envelope[326]: 526 nodes 1 leaves 293 minterms +Envelope[327]: 515 nodes 1 leaves 287 minterms +Envelope[328]: 505 nodes 1 leaves 281 minterms +Envelope[329]: 493 nodes 1 leaves 275 minterms +Envelope[330]: 481 nodes 1 leaves 270 minterms +Envelope[331]: 468 nodes 1 leaves 265 minterms +Envelope[332]: 455 nodes 1 leaves 260 minterms +Envelope[333]: 446 nodes 1 leaves 255 minterms +Envelope[334]: 438 nodes 1 leaves 250 minterms +Envelope[335]: 433 nodes 1 leaves 245 minterms +Envelope[336]: 430 nodes 1 leaves 240 minterms +Envelope[337]: 421 nodes 1 leaves 235 minterms +Envelope[338]: 415 nodes 1 leaves 230 minterms +Envelope[339]: 405 nodes 1 leaves 225 minterms +Envelope[340]: 397 nodes 1 leaves 220 minterms +Envelope[341]: 390 nodes 1 leaves 215 minterms +Envelope[342]: 382 nodes 1 leaves 210 minterms +Envelope[343]: 374 nodes 1 leaves 205 minterms +Envelope[344]: 368 nodes 1 leaves 200 minterms +Envelope[345]: 357 nodes 1 leaves 195 minterms +Envelope[346]: 349 nodes 1 leaves 190 minterms +Envelope[347]: 345 nodes 1 leaves 185 minterms +Envelope[348]: 343 nodes 1 leaves 180 minterms +Envelope[349]: 338 nodes 1 leaves 175 minterms +Envelope[350]: 329 nodes 1 leaves 170 minterms +Envelope[351]: 318 nodes 1 leaves 165 minterms +Envelope[352]: 312 nodes 1 leaves 160 minterms +Envelope[353]: 305 nodes 1 leaves 156 minterms +Envelope[354]: 298 nodes 1 leaves 152 minterms +Envelope[355]: 291 nodes 1 leaves 148 minterms +Envelope[356]: 284 nodes 1 leaves 144 minterms +Envelope[357]: 274 nodes 1 leaves 140 minterms +Envelope[358]: 267 nodes 1 leaves 136 minterms +Envelope[359]: 258 nodes 1 leaves 132 minterms +Envelope[360]: 250 nodes 1 leaves 129 minterms +Envelope[361]: 242 nodes 1 leaves 126 minterms +Envelope[362]: 239 nodes 1 leaves 123 minterms +Envelope[363]: 230 nodes 1 leaves 120 minterms +Envelope[364]: 224 nodes 1 leaves 117 minterms +Envelope[365]: 218 nodes 1 leaves 114 minterms +Envelope[366]: 217 nodes 1 leaves 111 minterms +Envelope[367]: 216 nodes 1 leaves 108 minterms +Envelope[368]: 214 nodes 1 leaves 105 minterms +Envelope[369]: 213 nodes 1 leaves 102 minterms +Envelope[370]: 213 nodes 1 leaves 99 minterms +Envelope[371]: 210 nodes 1 leaves 96 minterms +Envelope[372]: 206 nodes 1 leaves 93 minterms +Envelope[373]: 203 nodes 1 leaves 90 minterms +Envelope[374]: 199 nodes 1 leaves 87 minterms +Envelope[375]: 195 nodes 1 leaves 84 minterms +Envelope[376]: 191 nodes 1 leaves 81 minterms +Envelope[377]: 188 nodes 1 leaves 78 minterms +Envelope[378]: 186 nodes 1 leaves 75 minterms +Envelope[379]: 184 nodes 1 leaves 72 minterms +Envelope[380]: 183 nodes 1 leaves 70 minterms +Envelope[381]: 183 nodes 1 leaves 68 minterms +Envelope[382]: 182 nodes 1 leaves 66 minterms +Envelope[383]: 181 nodes 1 leaves 64 minterms +Envelope[384]: 179 nodes 1 leaves 62 minterms +Envelope[385]: 179 nodes 1 leaves 60 minterms +Envelope[386]: 178 nodes 1 leaves 58 minterms +Envelope[387]: 177 nodes 1 leaves 56 minterms +Envelope[388]: 175 nodes 1 leaves 54 minterms +Envelope[389]: 171 nodes 1 leaves 52 minterms +Envelope[390]: 168 nodes 1 leaves 50 minterms +Envelope[391]: 164 nodes 1 leaves 48 minterms +Envelope[392]: 159 nodes 1 leaves 46 minterms +Envelope[393]: 153 nodes 1 leaves 45 minterms +Envelope[394]: 148 nodes 1 leaves 44 minterms +Envelope[395]: 144 nodes 1 leaves 43 minterms +Envelope[396]: 140 nodes 1 leaves 42 minterms +Envelope[397]: 135 nodes 1 leaves 41 minterms +Envelope[398]: 132 nodes 1 leaves 40 minterms +Envelope[399]: 127 nodes 1 leaves 39 minterms +Envelope[400]: 122 nodes 1 leaves 38 minterms +Envelope[401]: 118 nodes 1 leaves 37 minterms +Envelope[402]: 114 nodes 1 leaves 36 minterms +Envelope[403]: 107 nodes 1 leaves 35 minterms +Envelope[404]: 100 nodes 1 leaves 34 minterms +Envelope[405]: 95 nodes 1 leaves 33 minterms +Envelope[406]: 92 nodes 1 leaves 32 minterms +Envelope[407]: 89 nodes 1 leaves 31 minterms +Envelope[408]: 84 nodes 1 leaves 30 minterms +Envelope[409]: 81 nodes 1 leaves 29 minterms +Envelope[410]: 78 nodes 1 leaves 28 minterms +Envelope[411]: 73 nodes 1 leaves 27 minterms +Envelope[412]: 70 nodes 1 leaves 26 minterms +Envelope[413]: 67 nodes 1 leaves 25 minterms +Envelope[414]: 63 nodes 1 leaves 24 minterms +Envelope[415]: 59 nodes 1 leaves 23 minterms +Envelope[416]: 56 nodes 1 leaves 22 minterms +Envelope[417]: 55 nodes 1 leaves 21 minterms +Envelope[418]: 54 nodes 1 leaves 20 minterms +Envelope[419]: 53 nodes 1 leaves 19 minterms +Envelope[420]: 52 nodes 1 leaves 18 minterms +Envelope[421]: 52 nodes 1 leaves 17 minterms +Envelope[422]: 50 nodes 1 leaves 16 minterms +Envelope[423]: 47 nodes 1 leaves 15 minterms +Envelope[424]: 44 nodes 1 leaves 14 minterms +Envelope[425]: 40 nodes 1 leaves 13 minterms +Envelope[426]: 36 nodes 1 leaves 12 minterms +Envelope[427]: 33 nodes 1 leaves 11 minterms +Envelope[428]: 31 nodes 1 leaves 10 minterms +Envelope[429]: 30 nodes 1 leaves 9 minterms +Envelope[430]: 29 nodes 1 leaves 8 minterms +Envelope[431]: 29 nodes 1 leaves 7 minterms +Envelope[432]: 29 nodes 1 leaves 6 minterms +Envelope[433]: 28 nodes 1 leaves 5 minterms +Envelope[434]: 27 nodes 1 leaves 4 minterms +depth = 434 +Envelope: 27 nodes 1 leaves 4 minterms +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000 +Maximum number of variable swaps per reordering: 2000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: no +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: no +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 10 +Arc violation threshold: 10 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 4004 +**** CUDD non-modifiable parameters **** +Memory in use: 240456716 +Peak number of nodes: 9643592 +Peak number of live nodes: 3171948 +Number of BDD variables: 50 +Number of ZDD variables: 0 +Number of cache entries: 4194304 +Number of cache look-ups: 53170021 +Number of cache hits: 30653976 +Number of cache insertions: 22515985 +Number of cache collisions: 15665382 +Number of cache deletions: 3483568 +Cache used slots = 97.84% (expected 98.41%) +Soft limit for cache size: 7645866 +Number of buckets in unique table: 3677184 +Used buckets in unique table: 71.16% (expected 71.15%) +Number of BDD and ADD nodes: 5843265 +Number of ZDD nodes: 0 +Number of dead BDD and ADD nodes: 4325974 +Number of dead ZDD nodes: 0 +Total number of nodes allocated: 15264438 +Total number of nodes reclaimed: 7806126 +Garbage collections so far: 2 +Time for garbage collection: 2.38 sec +Reorderings so far: 0 +Time for reordering: 0.00 sec +Final size: 869 +total time = 66.53 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 66.5 seconds +System time 0.6 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131815K +Virtual data size = 297K + data size initialized = 25K + data size uninitialized = 137K + data size sbrk = 135K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 5 +Minor page faults = 80223 +Swaps = 0 +Input blocks = 0 +Output blocks = 0 +Context switch (voluntary) = 6 +Context switch (involuntary) = 1991 diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/s27.blif b/resources/3rdparty/cudd-2.5.0/nanotrav/s27.blif new file mode 100644 index 000000000..42861a8ea --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/s27.blif @@ -0,0 +1,30 @@ +.model s27.bench +.inputs G0 G1 G2 G3 +.outputs G17 +.latch G10 G5 0 +.latch G11 G6 0 +.latch G13 G7 0 +.names G11 G17 +0 1 +.names G14 G11 G10 +00 1 +.names G5 G9 G11 +00 1 +.names G2 G12 G13 +00 1 +.names G0 G14 +0 1 +.names G14 G6 G8 +11 1 +.names G1 G7 G12 +00 1 +.names G12 G8 G15 +1- 1 +-1 1 +.names G3 G8 G16 +1- 1 +-1 1 +.names G16 G15 G9 +0- 1 +-0 1 +.end diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/s27.out b/resources/3rdparty/cudd-2.5.0/nanotrav/s27.out new file mode 100644 index 000000000..b9746f6c2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/s27.out @@ -0,0 +1,95 @@ +# Nanotrav Version #0.12, Release date 2003/12/31 +# ./nanotrav -p 1 -trav s27.blif +# CUDD Version 2.4.2 +Order before final reordering +G0 G1 G2 G3 G5 G6 G7 +Number of inputs = 7 +Building transition relation. Time = 0.00 sec +@@@ +Transition relation: 1 parts 3 latches 9 nodes +Traversing. Time = 0.00 sec +S0: 4 nodes 1 leaves 1 minterms +From[1]: 5 nodes 1 leaves 4 minterms +Reached[1]: 5 nodes 1 leaves 5 minterms +5 +5e+0 +From[2]: 4 nodes 1 leaves 1 minterms +Reached[2]: 3 nodes 1 leaves 6 minterms +6 +6e+0 +depth = 2 +R: 3 nodes 1 leaves 6 minterms +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000 +Maximum number of variable swaps per reordering: 2000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: no +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: no +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 10 +Arc violation threshold: 10 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 4004 +**** CUDD non-modifiable parameters **** +Memory in use: 4737772 +Peak number of nodes: 1022 +Peak number of live nodes: 95 +Number of BDD variables: 10 +Number of ZDD variables: 0 +Number of cache entries: 32768 +Number of cache look-ups: 180 +Number of cache hits: 26 +Number of cache insertions: 151 +Number of cache collisions: 1 +Number of cache deletions: 0 +Cache used slots = 0.46% (expected 0.46%) +Soft limit for cache size: 11264 +Number of buckets in unique table: 2816 +Used buckets in unique table: 4.97% (expected 5.15%) +Number of BDD and ADD nodes: 150 +Number of ZDD nodes: 0 +Number of dead BDD and ADD nodes: 75 +Number of dead ZDD nodes: 0 +Total number of nodes allocated: 150 +Total number of nodes reclaimed: 12 +Garbage collections so far: 0 +Time for garbage collection: 0.00 sec +Reorderings so far: 0 +Time for reordering: 0.00 sec +Final size: 16 +total time = 0.00 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 0.0 seconds +System time 0.0 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131815K +Virtual data size = 297K + data size initialized = 25K + data size uninitialized = 137K + data size sbrk = 135K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 0 +Minor page faults = 1424 +Swaps = 0 +Input blocks = 0 +Output blocks = 0 +Context switch (voluntary) = 1 +Context switch (involuntary) = 0 diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/tst.sh b/resources/3rdparty/cudd-2.5.0/nanotrav/tst.sh new file mode 100755 index 000000000..c51e67e29 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/tst.sh @@ -0,0 +1,9 @@ +#! /bin/sh +# +# $Id: tst.sh,v 1.2 1998/05/03 08:41:38 fabio Exp fabio $ +# +./nanotrav -p 1 -cover C17.blif > C17.tst +./nanotrav -p 1 -ordering dfs -autodyn -automethod sifting -reordering sifting -drop C880.blif > C880.tst +./nanotrav -p 1 -trav s27.blif > s27.tst +./nanotrav -p 1 -autodyn -reordering sifting -trav mult32a.blif > mult32a.tst +./nanotrav -p 1 -envelope rcn25.blif > rcn25.tst diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ucbqsort.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ucbqsort.c new file mode 100644 index 000000000..4a7348d5c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ucbqsort.c @@ -0,0 +1,228 @@ +#if defined(__GNUC__) && (__GNUC__ >2 || __GNUC_MINOR__ >=7) +#define UNUSED __attribute__ ((unused)) +#else +#define UNUSED +#endif + +#ifndef lint +static char rcsid[] UNUSED = "$Id: ucbqsort.c,v 1.4 2004/01/01 07:06:06 fabio Exp $"; +#endif + +/* @(#)qsort.c 4.2 (Berkeley) 3/9/83 */ + +/* + * qsort.c: + * Our own version of the system qsort routine which is faster by an average + * of 25%, with lows and highs of 10% and 50%. + * The THRESHold below is the insertion sort threshold, and has been adjusted + * for records of size 48 bytes. + * The MTHREShold is where we stop finding a better median. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int (*QSFP)(const void *, const void *); +extern void qsort ( char *base, int n, int size, QSFP compar); + +#define THRESH 4 /* threshold for insertion */ +#define MTHRESH 6 /* threshold for median */ + +static QSFP qcmp; /* the comparison routine */ +static int qsz; /* size of each record */ +static int thresh; /* THRESHold in chars */ +static int mthresh; /* MTHRESHold in chars */ + +static void qst (char *base, char *max); + +#ifdef __cplusplus +} +#endif + +/* + * qsort: + * First, set up some global parameters for qst to share. Then, quicksort + * with qst(), and then a cleanup insertion sort ourselves. Sound simple? + * It's not... + */ +#undef min +#undef max +void +qsort( + char *base, + int n, + int size, + QSFP compar) +{ + register char c, *i, *j, *lo, *hi; + char *min, *max; + + if (n <= 1) + return; + qsz = size; + qcmp = compar; + thresh = qsz * THRESH; + mthresh = qsz * MTHRESH; + max = base + n * qsz; + if (n >= THRESH) { + qst(base, max); + hi = base + thresh; + } else { + hi = max; + } + /* + * First put smallest element, which must be in the first THRESH, in + * the first position as a sentinel. This is done just by searching + * the first THRESH elements (or the first n if n < THRESH), finding + * the min, and swapping it into the first position. + */ + for (j = lo = base; (lo += qsz) < hi; ) + if ((*qcmp)(j, lo) > 0) + j = lo; + if (j != base) { + /* swap j into place */ + for (i = base, hi = base + qsz; i < hi; ) { + c = *j; + *j++ = *i; + *i++ = c; + } + } + /* + * With our sentinel in place, we now run the following hyper-fast + * insertion sort. For each remaining element, min, from [1] to [n-1], + * set hi to the index of the element AFTER which this one goes. + * Then, do the standard insertion sort shift on a character at a time + * basis for each element in the frob. + */ + for (min = base; (hi = min += qsz) < max; ) { + while ((*qcmp)(hi -= qsz, min) > 0) + /* void */; + if ((hi += qsz) != min) { + for (lo = min + qsz; --lo >= min; ) { + c = *lo; + for (i = j = lo; (j -= qsz) >= hi; i = j) + *i = *j; + *i = c; + } + } + } +} + +/* + * qst: + * Do a quicksort + * First, find the median element, and put that one in the first place as the + * discriminator. (This "median" is just the median of the first, last and + * middle elements). (Using this median instead of the first element is a big + * win). Then, the usual partitioning/swapping, followed by moving the + * discriminator into the right place. Then, figure out the sizes of the two + * partions, do the smaller one recursively and the larger one via a repeat of + * this code. Stopping when there are less than THRESH elements in a partition + * and cleaning up with an insertion sort (in our caller) is a huge win. + * All data swaps are done in-line, which is space-losing but time-saving. + * (And there are only three places where this is done). + */ + +static void +qst(char *base, char *max) +{ + register char c, *i, *j, *jj; + register int ii; + char *mid, *tmp; + int lo, hi; + + /* + * At the top here, lo is the number of characters of elements in the + * current partition. (Which should be max - base). + * Find the median of the first, last, and middle element and make + * that the middle element. Set j to largest of first and middle. + * If max is larger than that guy, then it's that guy, else compare + * max with loser of first and take larger. Things are set up to + * prefer the middle, then the first in case of ties. + */ + lo = max - base; /* number of elements as chars */ + do { + mid = i = base + qsz * ((lo / qsz) >> 1); + if (lo >= mthresh) { + j = ((*qcmp)((jj = base), i) > 0 ? jj : i); + if ((*qcmp)(j, (tmp = max - qsz)) > 0) { + /* switch to first loser */ + j = (j == jj ? i : jj); + if ((*qcmp)(j, tmp) < 0) + j = tmp; + } + if (j != i) { + ii = qsz; + do { + c = *i; + *i++ = *j; + *j++ = c; + } while (--ii); + } + } + /* + * Semi-standard quicksort partitioning/swapping + */ + for (i = base, j = max - qsz; ; ) { + while (i < mid && (*qcmp)(i, mid) <= 0) + i += qsz; + while (j > mid) { + if ((*qcmp)(mid, j) <= 0) { + j -= qsz; + continue; + } + tmp = i + qsz; /* value of i after swap */ + if (i == mid) { + /* j <-> mid, new mid is j */ + mid = jj = j; + } else { + /* i <-> j */ + jj = j; + j -= qsz; + } + goto swap; + } + if (i == mid) { + break; + } else { + /* i <-> mid, new mid is i */ + jj = mid; + tmp = mid = i; /* value of i after swap */ + j -= qsz; + } + swap: + ii = qsz; + do { + c = *i; + *i++ = *jj; + *jj++ = c; + } while (--ii); + i = tmp; + } + /* + * Look at sizes of the two partitions, do the smaller + * one first by recursion, then do the larger one by + * making sure lo is its size, base and max are update + * correctly, and branching back. But only repeat + * (recursively or by branching) if the partition is + * of at least size THRESH. + */ + i = (j = mid) + qsz; + if ((lo = j - base) <= (hi = max - i)) { + if (lo >= thresh) + qst(base, j); + base = i; + lo = hi; + } else { + if (hi >= thresh) + qst(i, max); + max = j; + } + } while (lo >= thresh); +} + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/setup.sh b/resources/3rdparty/cudd-2.5.0/setup.sh new file mode 100755 index 000000000..cb4003236 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/setup.sh @@ -0,0 +1,18 @@ +#! /bin/sh +CREATE="ln -s" +if test -d include + then + : + else + mkdir include + cd include + $CREATE ../cudd/cudd.h . + $CREATE ../cudd/cuddInt.h . + $CREATE ../epd/epd.h . + $CREATE ../dddmp/dddmp.h . + $CREATE ../mtr/mtr.h . + $CREATE ../obj/cuddObj.hh . + $CREATE ../st/st.h . + $CREATE ../util/util.h . + $CREATE ../mnemosyne/mnemosyne.h . +fi diff --git a/resources/3rdparty/cudd-2.5.0/shutdown.sh b/resources/3rdparty/cudd-2.5.0/shutdown.sh new file mode 100755 index 000000000..724917d7c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/shutdown.sh @@ -0,0 +1,2 @@ +#! /bin/sh +rm -rf include *.bak *~ diff --git a/resources/3rdparty/cudd-2.5.0/sis/Makefile.sis b/resources/3rdparty/cudd-2.5.0/sis/Makefile.sis new file mode 100644 index 000000000..fb0c3e64d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/sis/Makefile.sis @@ -0,0 +1,97 @@ +# $Id$ +# +# Cudd - DD package +#--------------------------- +.SUFFIXES: .o .c .u + +RANLIB = ranlib + +CAD = /projects/octtools/octtools/$(MACHINE) +SIS = .. +LINTCREATEFLAG = -C + +# files for the package +P = bdd +PSRC = cuddAPI.c cuddAddAbs.c cuddAddApply.c cuddAddFind.c cuddAddIte.c \ + cuddAddInv.c cuddAddNeg.c cuddAddWalsh.c cuddAndAbs.c \ + cuddAnneal.c cuddApa.c cuddApprox.c cuddBddAbs.c cuddBddCorr.c \ + cuddBddIte.c cuddBddPort.c cuddBridge.c cuddCache.c cuddCheck.c \ + cuddClip.c cuddCof.c cuddCompose.c cuddDecomp.c cuddEssent.c \ + cuddExact.c cuddExport.c cuddGenCof.c \ + cuddGenetic.c cuddGroup.c cuddHarwell.c cuddInit.c cuddInteract.c \ + cuddLCache.c cuddLevelQ.c cuddLinear.c cuddLiteral.c \ + cuddMatMult.c cuddPriority.c cuddPwPt.c \ + cuddRead.c cuddRef.c cuddReorder.c cuddSat.c cuddSign.c \ + cuddSolve.c cuddSplit.c cuddSubsetHB.c cuddSubsetSP.c cuddSymmetry.c \ + cuddTable.c cuddUtil.c cuddWindow.c cuddZddCount.c cuddZddFuncs.c \ + cuddZddGroup.c cuddZddIsop.c cuddZddLin.c cuddZddMisc.c \ + cuddZddPort.c cuddZddReord.c cuddZddSetop.c cuddZddSymm.c \ + cuddZddUtil.c +POBJ = $(PSRC:.c=.o) +PHDR = cudd.h cuddInt.h cuddBdd.h + +# files for the test program +TARGET = testcudd +SRC = testcudd.c +OBJ = $(SRC:.c=.o) +HDR = + +LIBS = ../util/libutil.a ../st/libst.a +LINTLIBS= ../util/llib-lutil.ln ../st/llib-lst.ln +INCLUDE = -I$(CAD)/include -I$(SIS)/include + +CFLAGS = -g $(INCLUDE) +LDFLAGS = -g +LINTFLAGS = $(INCLUDE) ${LINTEXTRAS} + +#------------------------------------------------------ + +$(TARGET): $(PHDR) $(OBJ) $(POBJ) $(LIBS) + $(CC) $(LDFLAGS) -o $(TARGET) $(OBJ) $(POBJ) $(LIBS) + +lint: $(PSRC) $(PHDR) $(SRC) $(HDR) + lint $(LINTFLAGS) $(SRC) $(PSRC) $(LINTLIBS) + +install: lib$(P).a llib-l$(P).ln + +lib$(P).a: $(POBJ) + ar cr $@ $? + $(RANLIB) $@ + +unpack: lib$(P).a + @for i in $(POBJ); do \ + ln -s $(SIS)/$(P)/$$i $(SIS)/unpack; \ + done + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) ${LINTCREATEFLAG}$(P) -n $(PSRC) + +clean: + rm -f $(TARGET) *.a *.ln *.o \ + [Tt]ags [Mm]ake.out lint malloc.out gmon.out __.SYMDEF *~ + +tags: _force + @for i in $(PSRC) $(PHDR); do \ + cwd=`pwd`; ctags -a $$cwd/$$i; + done; + +strip_depend: + sed '/^#--DO NOT CHANGE ANYTHING AFTER THIS LINE/,$$d' Makefile >mktemp + mv mktemp Makefile + +depend: + sed '/^#--DO NOT CHANGE ANYTHING AFTER THIS LINE/,$$d' Makefile >mktemp + echo '#--DO NOT CHANGE ANYTHING AFTER THIS LINE' >>mktemp + $(CAD)/bin/cc-M $(CFLAGS) $(PSRC) | \ + sed 's|$(CAD)|$$(CAD)|g' | \ + grep -v '/usr/include' >>mktemp + mv mktemp Makefile + +#-------------------------- IBM 3090 support ----------------- +IBMHOST = opua +IBMDIST = /users2/sis +ibmdist: $(PSRC) $(PHDR) + rdist -Richw $(PSRC) $(PHDR) $(IBMHOST):$(IBMDIST) +#------------------------------------------------------------- +_force: + diff --git a/resources/3rdparty/cudd-2.5.0/sis/cuddBdd.h b/resources/3rdparty/cudd-2.5.0/sis/cuddBdd.h new file mode 100644 index 000000000..2a688d761 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/sis/cuddBdd.h @@ -0,0 +1,382 @@ +/**CHeaderFile***************************************************************** + + FileName [cuddBdd.h] + + PackageName [cudd] + + Synopsis [Defines interface for the CU package to work with the + ucb interface.] + + Description [] + + Author [Abelardo Pardo] + + Copyright [Copyright (c) 1994-1996 The Univ. of Colorado. + All rights reserved. + + Permission is hereby granted, without written agreement and without license + or royalty fees, to use, copy, modify, and distribute this software and its + documentation for any purpose, provided that the above copyright notice and + the following two paragraphs appear in all copies of this software. + + IN NO EVENT SHALL THE UNIVERSITY OF COLORADO BE LIABLE TO ANY PARTY FOR + DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + COLORADO HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + THE UNIVERSITY OF COLORADO SPECIFICALLY DISCLAIMS ANY WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN + "AS IS" BASIS, AND THE UNIVERSITY OF COLORADO HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.] + + Revision [$Id: cuddBdd.h,v 1.2 1996/07/30 20:42:04 bobbie Exp $] + +******************************************************************************/ + +#ifndef _BDD +#define _BDD + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include "var_set.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +#define boolean int +/* + * foreach macro in the most misesque tradition + * bdd_gen_free always returns 0 + * + * CAUTION: in the context of the port to the CUDD package, it is assumed that + * dynamic reordering will not occur while there are open generators. It is + * the user's responsibility to make sure dynamic reordering doesn't occur. + * As long as new nodes are not created during generation, and you don't + * explicitly call dynamic reordering, you should be okay. + */ + +/* + * foreach_bdd_cube(fn, gen, cube) + * bdd_t *fn; + * bdd_gen *gen; + * array_t *cube; - return + * + * foreach_bdd_cube(fn, gen, cube) { + * ... + * } + */ +#define foreach_bdd_cube(fn, gen, cube)\ + for((gen) = bdd_first_cube(fn, &cube);\ + bdd_is_gen_empty(gen) ? bdd_gen_free(gen) : TRUE;\ + (void) bdd_next_cube(gen, &cube)) + +/* + * foreach_bdd_node(fn, gen, node) + * bdd_t *fn; + * bdd_gen *gen; + * bdd_node *node; - return + */ +#define foreach_bdd_node(fn, gen, node)\ + for((gen) = bdd_first_node(fn, &node);\ + bdd_is_gen_empty(gen) ? bdd_gen_free(gen) : TRUE;\ + (void) bdd_next_node(gen, &node)) + +/* + * Default settings. + */ +#define BDD_NO_LIMIT ((1<<30)-2) +#define BDD_DFLT_ITE_ON TRUE +#define BDD_DFLT_ITE_RESIZE_AT 75 +#define BDD_DFLT_ITE_MAX_SIZE 1000000 +#define BDD_DFLT_ITE_CONST_ON TRUE +#define BDD_DFLT_ITE_CONST_RESIZE_AT 75 +#define BDD_DFLT_ITE_CONST_MAX_SIZE 1000000 +#define BDD_DFLT_ADHOC_ON TRUE +#define BDD_DFLT_ADHOC_RESIZE_AT 0 +#define BDD_DFLT_ADHOC_MAX_SIZE 10000000 +#define BDD_DFLT_GARB_COLLECT_ON TRUE +#define BDD_DFLT_DAEMON NIL(void) +#define BDD_DFLT_MEMORY_LIMIT BDD_NO_LIMIT +#define BDD_DFLT_NODE_RATIO 2.0 +#define BDD_DFLT_INIT_BLOCKS 10 + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct DdManager bdd_manager; /* referenced via a pointer only */ +typedef unsigned int bdd_variableId; /* the id of the variable in a bdd node */ +typedef struct DdNode bdd_node; /* referenced via a pointer only */ +typedef int bdd_literal; /* integers in the set { 0, 1, 2 } */ + +/* This is to avoid problems with the mnemosyne library, which redefines +** free. +*/ +#ifdef MNEMOSYNE +#undef free +#endif + +typedef struct bdd_t { + boolean free; /* TRUE if this is free, FALSE otherwise ... */ + bdd_node *node; /* ptr to the top node of the function */ + bdd_manager *mgr; /* the manager */ +} bdd_t; + +/* + * Initialization data structure. Not supported in CMU package. + */ +typedef struct bdd_mgr_init { + struct { + boolean on; /* TRUE/FALSE: is the cache on */ + unsigned int resize_at; /* percentage at which to resize (e.g. 85% is 85); doesn't apply to adhoc */ + unsigned int max_size; /* max allowable number of buckets; for adhoc, max allowable number of entries */ + } ITE_cache, + ITE_const_cache, + adhoc_cache; + struct { + boolean on; /* TRUE/FALSE: is the garbage collector on */ + } garbage_collector; + struct { + void (*daemon)(); /* used for callback when memory limit exceeded */ + unsigned int limit; /* upper bound on memory allocated by the manager; in megabytes */ + } memory; + struct { + float ratio; /* allocate new bdd_nodes to achieve ratio of used to unused nodes */ + unsigned int init_blocks; /* number of bdd_nodeBlocks initially allocated */ + } nodes; +} bdd_mgr_init; + +/* + * Match types for BDD minimization. + */ +typedef enum { + BDD_MIN_TSM, /* two-side match */ + BDD_MIN_OSM, /* one-side match */ + BDD_MIN_OSDM /* one-side DC match */ +} bdd_min_match_type_t; + +/* + * Statistics and Other Queries + */ +typedef struct bdd_cache_stats { + unsigned int hits; + unsigned int misses; + unsigned int collisions; + unsigned int inserts; +} bdd_cache_stats; + +typedef struct bdd_stats { + struct { + bdd_cache_stats hashtable; /* the unique table; collisions and inserts fields not used */ + bdd_cache_stats itetable; + bdd_cache_stats consttable; + bdd_cache_stats adhoc; + } cache; /* various cache statistics */ + struct { + unsigned int calls; + struct { + unsigned int trivial; + unsigned int cached; + unsigned int full; + } returns; + } ITE_ops, + ITE_constant_ops, + adhoc_ops; + struct { + unsigned int total; + } blocks; /* bdd_nodeBlock count */ + struct { + unsigned int used; + unsigned int unused; + unsigned int total; + unsigned int peak; + } nodes; /* bdd_node count */ + struct { + unsigned int used; + unsigned int unused; + unsigned int total; + unsigned int blocks; + } extptrs; /* bdd_t count */ + struct { + unsigned int times; /* the number of times the garbage-collector has run */ + unsigned int nodes_collected; /* cumulative number of nodes collected over life of manager */ + long runtime; /* cumulative CPU time spent garbage collecting */ + } gc; + struct { + int first_sbrk; /* value of sbrk at start of manager; used to analyze memory usage */ + int last_sbrk; /* value of last sbrk (see "man sbrk") fetched; used to analyze memory usage */ + unsigned int manager; + unsigned int nodes; + unsigned int hashtable; + unsigned int ext_ptrs; + unsigned int ITE_cache; + unsigned int ITE_const_cache; + unsigned int adhoc_cache; + unsigned int total; + } memory; /* memory usage */ +} bdd_stats; + +/* + * Traversal of BDD Formulas + */ + +typedef struct bdd_gen bdd_gen; + +/* + * These are the hooks for stuff that uses bdd's + * + * There are three hooks, and users may use them in whatever + * way they wish; these hooks are guaranteed to never be used + * by the bdd package. + */ +typedef struct bdd_external_hooks { + char *network; + char *mdd; + char *undef1; +} bdd_external_hooks; + +/* + * Dynamic reordering. + */ +typedef enum { + BDD_REORDER_SIFT, + BDD_REORDER_WINDOW, + BDD_REORDER_NONE, + BDD_REORDER_SAME, + BDD_REORDER_RANDOM, + BDD_REORDER_RANDOM_PIVOT, + BDD_REORDER_SIFT_CONVERGE, + BDD_REORDER_SYMM_SIFT, + BDD_REORDER_SYMM_SIFT_CONV, + BDD_REORDER_WINDOW2, + BDD_REORDER_WINDOW3, + BDD_REORDER_WINDOW4, + BDD_REORDER_WINDOW2_CONV, + BDD_REORDER_WINDOW3_CONV, + BDD_REORDER_WINDOW4_CONV, + BDD_REORDER_GROUP_SIFT, + BDD_REORDER_GROUP_SIFT_CONV, + BDD_REORDER_ANNEALING, + BDD_REORDER_GENETIC +} bdd_reorder_type_t; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/* + * BDD Manager Allocation And Destruction + */ +extern void bdd_end (bdd_manager *); +extern void bdd_register_daemon (bdd_manager *, void (*daemon)()); +extern void bdd_set_mgr_init_dflts (bdd_mgr_init *); +extern bdd_manager *bdd_start (int); +extern bdd_manager *bdd_start_with_params (int, bdd_mgr_init *); + +/* + * BDD Variable Allocation + */ +extern bdd_t *bdd_create_variable (bdd_manager *); +extern bdd_t *bdd_get_variable (bdd_manager *, bdd_variableId); + +/* + * BDD Formula Management + */ +extern bdd_t *bdd_dup (bdd_t *); +extern void bdd_free (bdd_t *); + +/* + * Operations on BDD Formulas + */ +extern bdd_t *bdd_and (bdd_t *, bdd_t *, boolean, boolean); +extern bdd_t *bdd_and_smooth (bdd_t *, bdd_t *, array_t *); +extern bdd_t *bdd_between (bdd_t *, bdd_t *); +extern bdd_t *bdd_cofactor (bdd_t *, bdd_t *); +extern bdd_t *bdd_compose (bdd_t *, bdd_t *, bdd_t *); +extern bdd_t *bdd_consensus (bdd_t *, array_t *); +extern bdd_t *bdd_cproject (bdd_t *, array_t *); +extern bdd_t *bdd_else (bdd_t *); +extern bdd_t *bdd_ite (bdd_t *, bdd_t *, bdd_t *, boolean, boolean, boolean); +extern bdd_t *bdd_minimize (bdd_t *, bdd_t *); +extern bdd_t *bdd_minimize_with_params (bdd_t *, bdd_t *, bdd_min_match_type_t, boolean, boolean, boolean); +extern bdd_t *bdd_not (bdd_t *); +extern bdd_t *bdd_one (bdd_manager *); +extern bdd_t *bdd_or (bdd_t *, bdd_t *, boolean, boolean); +extern bdd_t *bdd_smooth (bdd_t *, array_t *); +extern bdd_t *bdd_substitute (bdd_t *, array_t *, array_t *); +extern bdd_t *bdd_then (bdd_t *); +extern bdd_t *bdd_top_var (bdd_t *); +extern bdd_t *bdd_xnor (bdd_t *, bdd_t *); +extern bdd_t *bdd_xor (bdd_t *, bdd_t *); +extern bdd_t *bdd_zero (bdd_manager *); + +/* + * Queries about BDD Formulas + */ +extern boolean bdd_equal (bdd_t *, bdd_t *); +extern boolean bdd_is_cube (bdd_t *); +extern boolean bdd_is_tautology (bdd_t *, boolean); +extern boolean bdd_leq (bdd_t *, bdd_t *, boolean, boolean); + +extern double bdd_count_onset (bdd_t *, array_t *); +extern bdd_manager *bdd_get_manager (bdd_t *); +extern bdd_node *bdd_get_node (bdd_t *, boolean *); +extern void bdd_get_stats (bdd_manager *, bdd_stats *); +extern var_set_t *bdd_get_support (bdd_t *); +extern array_t *bdd_get_varids (array_t *); +extern unsigned int bdd_num_vars (bdd_manager *); +extern void bdd_print (bdd_t *); +extern void bdd_print_stats (bdd_stats, FILE *); +extern int bdd_size (bdd_t *); +extern bdd_variableId bdd_top_var_id (bdd_t *); +extern bdd_t *bdd_create_variable_after (bdd_manager *, bdd_variableId); +extern bdd_variableId bdd_get_id_from_level (bdd_manager *, long); +extern long bdd_top_var_level (bdd_manager *, bdd_t *); + +extern int bdd_gen_free (bdd_gen *); + +/* + * These are NOT to be used directly; only indirectly in the macros. + */ +extern bdd_gen *bdd_first_cube (bdd_t *, array_t **); +extern boolean bdd_next_cube (bdd_gen *, array_t **); +extern bdd_gen *bdd_first_node (bdd_t *, bdd_node **); +extern boolean bdd_next_node (bdd_gen *, bdd_node **); +extern boolean bdd_is_gen_empty (bdd_gen *); + +/* + * Miscellaneous + */ +extern void bdd_set_gc_mode (bdd_manager *, boolean); + +extern bdd_external_hooks *bdd_get_external_hooks (bdd_manager *); + +extern void bdd_dynamic_reordering (bdd_manager *, bdd_reorder_type_t); + +extern int bdd_read_reordering_flag (bdd_manager *); + +#ifdef __cplusplus +} +#endif + +#endif /* _BDD */ diff --git a/resources/3rdparty/cudd-2.5.0/sis/cuddBddPort.c b/resources/3rdparty/cudd-2.5.0/sis/cuddBddPort.c new file mode 100644 index 000000000..7b97956c6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/sis/cuddBddPort.c @@ -0,0 +1,1954 @@ +/**CFile*********************************************************************** + + FileName [cuddBddPort.c] + + PackageName [cudd] + + Synopsis [SIS interface to the Decision Diagram Package of the + University of Colorado.] + + Description [This file implements an interface between the functions in + the Berkeley BDD package and the functions provided by the CUDD (decision + diagram) package from the University of Colorado. The CUDD package is a + generic implementation of a decision diagram data structure. For the time + being, only Boole expansion is implemented and the leaves in the + in the nodes can be the constants zero, one or any arbitrary value.] + + Author [Abelardo Pardo] + + Copyright [Copyright (c) 1994-1996 The Univ. of Colorado. + All rights reserved. + + Permission is hereby granted, without written agreement and without license + or royalty fees, to use, copy, modify, and distribute this software and its + documentation for any purpose, provided that the above copyright notice and + the following two paragraphs appear in all copies of this software. + + IN NO EVENT SHALL THE UNIVERSITY OF COLORADO BE LIABLE TO ANY PARTY FOR + DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + COLORADO HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + THE UNIVERSITY OF COLORADO SPECIFICALLY DISCLAIMS ANY WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN + "AS IS" BASIS, AND THE UNIVERSITY OF COLORADO HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.] + +******************************************************************************/ + +#include "util.h" +#include "array.h" +#include "st.h" + +#ifdef EXTERN +#undef EXTERN +#endif +#define EXTERN +#include "cuddInt.h" +#include "cuddBdd.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +struct bdd_gen { + bdd_manager *manager; + DdGen *ddGen; + array_t *cube; +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBddPort.c,v 1.11 1996/05/08 06:13:08 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static bdd_t * bdd_construct_bdd_t (DdManager *mgr, DdNode * fn); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Terminates the bdd package.] + + SideEffects [] + +******************************************************************************/ +void +bdd_end(mgr) +bdd_manager *mgr; +{ + if (mgr->hooks != NULL) FREE(mgr->hooks); + Cudd_Quit(mgr); + +} /* end of bdd_end */ + + +/**Function******************************************************************** + + Synopsis [Initialize manager with the options given in mgr_init.] + + SideEffects [] + +******************************************************************************/ +void +bdd_set_mgr_init_dflts(mgr_init) +bdd_mgr_init *mgr_init; +{ + fprintf(stderr,"CU DD Package: bdd_set_mgr_init_dflts translated to no-op\n"); + return; + +} /* end of bdd_set_mgr_init_dflts */ + + +/**Function******************************************************************** + + Synopsis [Starts the manager with nvariables variables.] + + SideEffects [] + +******************************************************************************/ +bdd_manager * +bdd_start(nvariables) +int nvariables; +{ + DdManager *mgr; + bdd_external_hooks *hooks; + + mgr = Cudd_Init((unsigned int)nvariables,0,CUDD_UNIQUE_SLOTS, + CUDD_CACHE_SLOTS,0); + + hooks = ALLOC(bdd_external_hooks,1); + hooks->mdd = hooks->network = hooks->undef1 = (char *) 0; + mgr->hooks = (char *) hooks; + + return (bdd_manager *)mgr; + +} /* end of bdd_start */ + + +/**Function******************************************************************** + + Synopsis [Starts the manager with parameters.] + + SideEffects [] + +******************************************************************************/ +bdd_manager * +bdd_start_with_params(nvariables, mgr_init) +int nvariables; +bdd_mgr_init *mgr_init; +{ + fprintf(stderr,"CU DD Package: bdd_start_with_parameters bypassed\n"); + return (bdd_manager *)Cudd_Init((unsigned int)nvariables,0, + CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); + +} /* end of bdd_start_with_params */ + + +/**Function******************************************************************** + + Synopsis [Creates a new variable in the manager.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_create_variable(mgr) +bdd_manager *mgr; +{ + DdNode *var; + DdManager *dd = (DdManager *) mgr; + DdNode *one = DD_ONE(dd); + + if (dd->size >= CUDD_MAXINDEX -1) return(NULL); + do { + dd->reordered = 0; + var = cuddUniqueInter(dd,dd->size,one,Cudd_Not(one)); + } while (dd->reordered == 1); + + if (var == NULL) return(NULL); + cuddRef(var); + return(bdd_construct_bdd_t(dd,var)); + +} /* end of bdd_create_variable */ + + +/**Function******************************************************************** + + Synopsis [Creates a new variable and positions it after the + variable with the specified index.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_create_variable_after(mgr, after_id) +bdd_manager *mgr; +bdd_variableId after_id; +{ + DdNode *var; + DdManager *dd = (DdManager *) mgr; + int level; + + if (after_id >= dd->size) return(NULL); + level = 1 + dd->perm[after_id]; + var = Cudd_bddNewVarAtLevel(dd,level); + if (var == NULL) return(NULL); + cuddRef(var); + return(bdd_construct_bdd_t(dd,var)); + +} /* end of bdd_create_variable_after */ + + +/**Function******************************************************************** + + Synopsis [Returns the BDD representing the variable with given ID.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_get_variable(mgr, variable_ID) +bdd_manager *mgr; +bdd_variableId variable_ID; /* unsigned int */ +{ + DdNode *var; + DdManager *dd = (DdManager *) mgr; + DdNode *one = DD_ONE(dd); + + if (variable_ID >= CUDD_MAXINDEX -1) return(NULL); + do { + dd->reordered = 0; + var = cuddUniqueInter(dd,(int)variable_ID,one,Cudd_Not(one)); + } while (dd->reordered == 1); + + if (var == NULL) return(NULL); + cuddRef(var); + return(bdd_construct_bdd_t(dd,var)); + +} /* end of bdd_get_variable */ + + +/**Function******************************************************************** + + Synopsis [Creates a copy of the BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_dup(f) +bdd_t *f; +{ + cuddRef(f->node); + return(bdd_construct_bdd_t((DdManager *)f->mgr,f->node)); + +} /* end of bdd_dup */ + + +/**Function******************************************************************** + + Synopsis [Deletes the BDD of f.] + + SideEffects [] + +******************************************************************************/ +void +bdd_free(f) +bdd_t *f; +{ + if (f == NULL) { + fail("bdd_free: trying to free a NULL bdd_t"); + } + + if (f->free == TRUE) { + fail("bdd_free: trying to free a freed bdd_t"); + } + + Cudd_RecursiveDeref((DdManager *)f->mgr,f->node); + /* This is a bit overconservative. */ + f->node = 0; + f->mgr = 0; + f->free = 0; + FREE(f); + return; + +} /* end of bdd_free */ + + +/**Function******************************************************************** + + Synopsis [And of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_and(f, g, f_phase, g_phase) +bdd_t *f; +bdd_t *g; +boolean f_phase; +boolean g_phase; +{ + DdManager *dd; + DdNode *newf,*newg,*fandg; + bdd_t *result; + + /* Make sure both BDDs belong to the same manager. */ + assert(f->mgr == g->mgr); + + /* Modify the phases of the operands according to the parameters. */ + if (!f_phase) { + newf = Cudd_Not(f->node); + } else { + newf = f->node; + } + if (!g_phase) { + newg = Cudd_Not(g->node); + } else { + newg = g->node; + } + + /* Perform the AND operation */ + dd = (DdManager *)f->mgr; + fandg = Cudd_bddAnd((DdManager *)f->mgr,newf,newg); + if (fandg == NULL) return(NULL); + cuddRef(fandg); + result = bdd_construct_bdd_t(dd,fandg); + + return(result); + +} /* end of bdd_and */ + + +/**Function******************************************************************** + + Synopsis [Abstracts variables from the product of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_and_smooth(f, g, smoothing_vars) +bdd_t *f; +bdd_t *g; +array_t *smoothing_vars; /* of bdd_t *'s */ +{ + int i; + bdd_t *variable; + DdNode *cube,*tmpDd,*result; + DdManager *mgr; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + /* The Boulder package needs the smothing variables passed as a cube. + ** Therefore we must build that cube from the indices of variables + ** in the array before calling the procedure. + */ + mgr = (DdManager *)f->mgr; + Cudd_Ref(cube = DD_ONE(mgr)); + for (i = 0; i < array_n(smoothing_vars); i++) { + variable = array_fetch(bdd_t *,smoothing_vars,i); + + /* Make sure the variable belongs to the same manager. */ + assert(mgr == variable->mgr); + + tmpDd = Cudd_bddAnd(mgr,cube,variable->node); + if (tmpDd == NULL) { + Cudd_RecursiveDeref(mgr,cube); + return(NULL); + } + cuddRef(tmpDd); + Cudd_RecursiveDeref(mgr, cube); + cube = tmpDd; + } + + /* Perform the smoothing */ + result = Cudd_bddAndAbstract(mgr,f->node,g->node,cube); + if (result == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(result); + /* Get rid of temporary results. */ + Cudd_RecursiveDeref(mgr, cube); + + /* Build the bdd_t structure for the result */ + return(bdd_construct_bdd_t(mgr,result)); + +} /* end of bdd_and_smooth */ + + +/**Function******************************************************************** + + Synopsis [Return a minimum size BDD between bounds.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_between(f_min, f_max) +bdd_t *f_min; +bdd_t *f_max; +{ + bdd_t *temp, *ret; + + temp = bdd_or(f_min, f_max, 1, 0); + ret = bdd_minimize(f_min, temp); + bdd_free(temp); + return(ret); + +} /* end of bdd_between */ + + +/**Function******************************************************************** + + Synopsis [Computes the cofactor of f with respect to g.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_cofactor(f, g) +bdd_t *f; +bdd_t *g; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager */ + assert(f->mgr == g->mgr); + + /* We use Cudd_bddConstrain instead of Cudd_Cofactor for generality. */ + result = Cudd_bddConstrain((DdManager *)f->mgr,f->node,g->node); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t((DdManager *)f->mgr,result)); + +} /* end of bdd_cofactor */ + + +/**Function******************************************************************** + + Synopsis [Functional composition of a function by a variable.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_compose(f, v, g) +bdd_t *f; +bdd_t *v; +bdd_t *g; +{ + DdNode *result; + + /* Make sure all operands belong to the same manager. */ + assert(f->mgr == g->mgr); + assert(f->mgr == v->mgr); + + result = Cudd_bddCompose(f->mgr,f->node,g->node,(int)Cudd_Regular(v->node)->index); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_compose */ + + +/**Function******************************************************************** + + Synopsis [Universal Abstraction of Variables.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_consensus(f, quantifying_vars) +bdd_t *f; +array_t *quantifying_vars; /* of bdd_t *'s */ +{ + int i; + bdd_t *variable; + DdNode *cube,*tmpDd,*result; + bdd_manager *mgr; + + /* The Boulder package needs the smothing variables passed as a cube. + ** Therefore we must build that cube from the indices of the variables + ** in the array before calling the procedure. + */ + mgr = f->mgr; + Cudd_Ref(cube = DD_ONE(mgr)); + for (i = 0; i < array_n(quantifying_vars); i++) { + variable = array_fetch(bdd_t *,quantifying_vars,i); + + /* Make sure the variable belongs to the same manager */ + assert(mgr == variable->mgr); + + tmpDd = Cudd_bddAnd(mgr,cube,variable->node); + if (tmpDd == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(tmpDd); + Cudd_RecursiveDeref(mgr, cube); + cube = tmpDd; + } + + /* Perform the consensus */ + result = Cudd_bddUnivAbstract(mgr,f->node,cube); + if (result == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(result); + /* Get rid of temporary results */ + Cudd_RecursiveDeref(mgr, cube); + + /* Build the bdd_t structure for the result */ + return(bdd_construct_bdd_t(mgr,result)); + +} /* end of bdd_consensus */ + + +/**Function******************************************************************** + + Synopsis [The compatible projection function.] + + Description [The compatible projection function. The reference minterm + is chosen based on the phases of the quantifying variables. If all + variables are in positive phase, the minterm 111...111 is used as + reference.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_cproject(f, quantifying_vars) +bdd_t *f; +array_t *quantifying_vars; /* of bdd_t* */ +{ + DdManager *dd; + DdNode *cube; + DdNode *res; + bdd_t *fi; + int nvars, i; + + if (f == NULL) { + fail ("bdd_cproject: invalid BDD"); + } + + nvars = array_n(quantifying_vars); + if (nvars <= 0) { + fail("bdd_cproject: no projection variables"); + } + dd = f->mgr; + + cube = DD_ONE(dd); + cuddRef(cube); + for (i = nvars - 1; i >= 0; i--) { + DdNode *tmpp; + fi = array_fetch(bdd_t *, quantifying_vars, i); + tmpp = Cudd_bddAnd(dd,fi->node,cube); + if (tmpp == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(tmpp); + Cudd_RecursiveDeref(dd,cube); + cube = tmpp; + } + + res = Cudd_CProjection(dd,f->node,cube); + if (res == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,cube); + + return(bdd_construct_bdd_t(dd,res)); + +} /* end of bdd_cproject */ + + +/**Function******************************************************************** + + Synopsis [ITE.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_ite(i, t, e, i_phase, t_phase, e_phase) +bdd_t *i; +bdd_t *t; +bdd_t *e; +boolean i_phase; +boolean t_phase; +boolean e_phase; +{ + DdNode *newi,*newt,*newe,*ite; + + /* Make sure both bdds belong to the same mngr */ + assert(i->mgr == t->mgr); + assert(i->mgr == e->mgr); + + /* Modify the phases of the operands according to the parameters */ + if (!i_phase) { + newi = Cudd_Not(i->node); + } else { + newi = i->node; + } + if (!t_phase) { + newt = Cudd_Not(t->node); + } else { + newt = t->node; + } + if (!e_phase) { + newe = Cudd_Not(e->node); + } else { + newe = e->node; + } + + /* Perform the ITE operation */ + ite = Cudd_bddIte(i->mgr,newi,newt,newe); + if (ite == NULL) return(NULL); + cuddRef(ite); + return(bdd_construct_bdd_t(i->mgr,ite)); + +} /* end of bdd_ite */ + + +/**Function******************************************************************** + + Synopsis [Restric operator as described in Coudert et al. ICCAD90.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_minimize(f, c) +bdd_t *f; +bdd_t *c; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == c->mgr); + + result = Cudd_bddRestrict(f->mgr,f->node,c->node); + if (result == NULL) return(NULL); + cuddRef(result); + + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_minimize */ + + +/**Function******************************************************************** + + Synopsis [Parametrized version of the Restrict operator.] + + Description [Parametrized version of the Restrict operator. Currently + defaults to bdd_minimize.] + + SideEffects [] + +******************************************************************************/ +/*ARGSUSED*/ +bdd_t * +bdd_minimize_with_params(f, c, match_type, compl, no_new_vars, return_min) +bdd_t *f; +bdd_t *c; +bdd_min_match_type_t match_type; +boolean compl; +boolean no_new_vars; +boolean return_min; +{ + return(bdd_minimize(f,c)); + +} /* end of bdd_minimize_with_params */ + + +/**Function******************************************************************** + + Synopsis [Negation.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_not(f) +bdd_t *f; +{ + DdNode *result; + + Cudd_Ref(result = Cudd_Not(f->node)); + return(bdd_construct_bdd_t((DdManager *)f->mgr,result)); + +} /* end of bdd_not */ + + +/**Function******************************************************************** + + Synopsis [Returns the one BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_one(mgr) +bdd_manager *mgr; +{ + DdNode *result; + + Cudd_Ref(result = DD_ONE((DdManager *)mgr)); + return(bdd_construct_bdd_t((DdManager *)mgr,result)); + +} /* end of bdd_one */ + + +/**Function******************************************************************** + + Synopsis [Or of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_or(f, g, f_phase, g_phase) +bdd_t *f; +bdd_t *g; +boolean f_phase; +boolean g_phase; +{ + DdNode *newf,*newg,*forg; + bdd_t *result; + + /* Make sure both bdds belong to the same mngr */ + assert(f->mgr == g->mgr); + + /* Modify the phases of the operands according to the parameters */ + if (f_phase) { + newf = Cudd_Not(f->node); + } else { + newf = f->node; + } + if (g_phase) { + newg = Cudd_Not(g->node); + } else { + newg = g->node; + } + + /* Perform the OR operation */ + forg = Cudd_bddAnd(f->mgr,newf,newg); + if (forg == NULL) return(NULL); + forg = Cudd_Not(forg); + cuddRef(forg); + result = bdd_construct_bdd_t(f->mgr,forg); + + return(result); + +} /* end of bdd_or */ + + +/**Function******************************************************************** + + Synopsis [Existential abstraction of variables.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_smooth(f, smoothing_vars) +bdd_t *f; +array_t *smoothing_vars; /* of bdd_t *'s */ +{ + int i; + bdd_t *variable; + DdNode *cube,*tmpDd,*result; + bdd_manager *mgr; + + /* The Boulder package needs the smothing variables passed as a cube. + ** Therefore we must build that cube from the indices of the variables + ** in the array before calling the procedure. + */ + mgr = f->mgr; + Cudd_Ref(cube = DD_ONE(mgr)); + for (i = 0; i < array_n(smoothing_vars); i++) { + variable = array_fetch(bdd_t *,smoothing_vars,i); + + /* Make sure the variable belongs to the same manager. */ + assert(mgr == variable->mgr); + + tmpDd = Cudd_bddAnd(mgr,cube,variable->node); + if (tmpDd == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(tmpDd); + Cudd_RecursiveDeref(mgr, cube); + cube = tmpDd; + } + + /* Perform the smoothing */ + result = Cudd_bddExistAbstract(mgr,f->node,cube); + if (result == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(result); + + /* Get rid of temporary results */ + Cudd_RecursiveDeref(mgr, cube); + + /* Build the bdd_t structure for the result */ + return(bdd_construct_bdd_t(mgr,result)); + +} /* end of bdd_smooth */ + + +/**Function******************************************************************** + + Synopsis [Permutes the variables.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_substitute(f, old_array, new_array) +bdd_t *f; +array_t *old_array; /* of bdd_t *'s */ +array_t *new_array; /* of bdd_t *'s */ +{ + int maxOld; + int i,varIndex,from,to; + int *permut; + bdd_t *variable; + DdNode *result; + + /* Make sure both arrays have the same number of elements. */ + assert(array_n(old_array) == array_n(new_array)); + + /* Detect what is the highest index of variable to rename. */ + maxOld = 0; + for (i = 0; i < array_n(old_array); i++) { + variable = array_fetch(bdd_t *, old_array, i); + /* Make sure the variable belongs to this manager. */ + assert(f->mgr == variable->mgr); + + varIndex = Cudd_Regular(variable->node)->index; + if (varIndex > maxOld) { + maxOld = varIndex; + } + } + maxOld++; + + /* Allocate and fill the array with the trivial permutation. */ + permut = ALLOC(int, maxOld); + for (i = 0; i < maxOld; i++) permut[i] = i; + + /* Modify the permutation by looking at both arrays old and new. */ + for (i = 0; i < array_n(old_array); i++) { + variable = array_fetch(bdd_t *, old_array, i); + from = Cudd_Regular(variable->node)->index; + variable = array_fetch(bdd_t *, new_array, i); + /* Make sure the variable belongs to this manager. */ + assert(f->mgr == variable->mgr); + + to = Cudd_Regular(variable->node)->index; + permut[from] = to; + } + + result = Cudd_bddPermute(f->mgr,f->node,permut); + FREE(permut); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_substitute */ + + +/**Function******************************************************************** + + Synopsis [Returns the Then branch of the BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_then(f) +bdd_t *f; +{ + DdNode *result; + + result = Cudd_T(f->node); + result = Cudd_NotCond(result,Cudd_IsComplement(f->node)); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_then */ + + +/**Function******************************************************************** + + Synopsis [Returns the else branch of a BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_else(f) +bdd_t *f; +{ + DdNode *result; + + result = Cudd_E(f->node); + result = Cudd_NotCond(result,Cudd_IsComplement(f->node)); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_else */ + + +/**Function******************************************************************** + + Synopsis [Returns the BDD of the top variable.] + + Description [Returns the BDD of the top variable of the argument. If + the argument is constant, it returns the constant function itself.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_top_var(f) +bdd_t *f; +{ + DdNode *result; + + if (Cudd_IsConstant(f->node)) { + result = f->node; + } else { + result = f->mgr->vars[Cudd_Regular(f->node)->index]; + } + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_top_var */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive nor of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_xnor(f, g) +bdd_t *f; +bdd_t *g; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + result = Cudd_bddIte(f->mgr,f->node,g->node,Cudd_Not(g->node)); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_xnor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive or of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_xor(f, g) +bdd_t *f; +bdd_t *g; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + result = Cudd_bddIte(f->mgr,f->node,Cudd_Not(g->node),g->node); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_xor */ + + +/**Function******************************************************************** + + Synopsis [Returns the constant zero BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_zero(mgr) +bdd_manager *mgr; +{ + DdNode *result; + + Cudd_Ref(result = Cudd_Not(DD_ONE((mgr)))); + return(bdd_construct_bdd_t(mgr,result)); + +} /* end of bdd_zero */ + + +/**Function******************************************************************** + + Synopsis [Equality check.] + + SideEffects [] + +******************************************************************************/ +boolean +bdd_equal(f, g) +bdd_t *f; +bdd_t *g; +{ + return(f->node == g->node); + +} /* end of bdd_equal */ + + +/**Function******************************************************************** + + Synopsis [Returns a BDD included in the intersection of f and g.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_intersects(f, g) +bdd_t *f; +bdd_t *g; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + result = Cudd_bddIntersect(f->mgr,f->node,g->node); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_intersects */ + + +/**Function******************************************************************** + + Synopsis [Checks a BDD for tautology.] + + SideEffects [] + +******************************************************************************/ +boolean +bdd_is_tautology(f, phase) +bdd_t *f; +boolean phase; +{ + if (phase) { + return(f->node == DD_ONE(f->mgr)); + } else { + return(f->node == Cudd_Not(DD_ONE(f->mgr))); + } + +} /* end of bdd_is_tautology */ + + +/**Function******************************************************************** + + Synopsis [Tests for containment of f in g.] + + SideEffects [] + +******************************************************************************/ +boolean +bdd_leq(f, g, f_phase, g_phase) +bdd_t *f; +bdd_t *g; +boolean f_phase; +boolean g_phase; +{ + DdNode *newf, *newg; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + if (f_phase) { + newf = f->node; + } else { + newf = Cudd_Not(f->node); + } + if (g_phase) { + newg = g->node; + } else { + newg = Cudd_Not(g->node); + } + + return(Cudd_bddLeq(f->mgr,newf,newg)); + +} /* end of bdd_leq */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms in the on set.] + + SideEffects [] + +******************************************************************************/ +double +bdd_count_onset(f, var_array) +bdd_t *f; +array_t *var_array; /* of bdd_t *'s */ +{ + return(Cudd_CountMinterm(f->mgr,f->node,array_n(var_array))); + +} /* end of bdd_count_onset */ + + +/**Function******************************************************************** + + Synopsis [Obtains the manager of the BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_manager * +bdd_get_manager(f) +bdd_t *f; +{ + return(f->mgr); + +} /* end of bdd_get_manager */ + + +/**Function******************************************************************** + + Synopsis [Returns the node of the BDD.] + + SideEffects [Sets is_complemented.] + +******************************************************************************/ +bdd_node * +bdd_get_node(f, is_complemented) +bdd_t *f; +boolean *is_complemented; /* return */ +{ + if (Cudd_IsComplement(f->node)) { + *is_complemented = TRUE; + return(Cudd_Regular(f->node)); + } + *is_complemented = FALSE; + return(f->node); + +} /* end of bdd_get_node */ + + +/**Function******************************************************************** + + Synopsis [Returns the free field of the BDD.] + + SideEffects [] + +******************************************************************************/ +int +bdd_get_free(f) +bdd_t *f; +{ + return (f->free); + +} /* end of bdd_get_free */ + + +/**Function******************************************************************** + + Synopsis [Obtains some statistics of the BDD package.] + + SideEffects [Sets stats.] + +******************************************************************************/ +/*ARGSUSED*/ +void +bdd_get_stats(mgr, stats) +bdd_manager *mgr; +bdd_stats *stats; /* return */ +{ + stats->nodes.total = mgr->keys; + stats->nodes.used = mgr->keys - mgr->dead; + stats->nodes.unused = mgr->dead; + stats->cache.itetable.hits = (unsigned int) Cudd_ReadCacheHits(mgr); + stats->cache.itetable.misses = (unsigned int) + (Cudd_ReadCacheLookUps(mgr) - Cudd_ReadCacheHits(mgr)); + stats->cache.itetable.collisions = mgr->cachecollisions; + stats->cache.itetable.inserts = mgr->cacheinserts; + stats->gc.times = Cudd_ReadGarbageCollections(mgr); + return; + +} /* end of bdd_get_stats */ + + +/**Function******************************************************************** + + Synopsis [Obtains the support of the BDD.] + + SideEffects [] + +******************************************************************************/ +var_set_t * +bdd_get_support(f) +bdd_t *f; +{ + DdNode *support, *scan; + var_set_t *result; + + support = Cudd_Support(f->mgr,f->node); + if (support == NULL) return(NULL); + cuddRef(support); + + result = var_set_new((int) f->mgr->size); + scan = support; + while (!cuddIsConstant(scan)) { + var_set_set_elt(result, scan->index); + scan = cuddT(scan); + } + Cudd_RecursiveDeref(f->mgr,support); + + return(result); + +} /* end of bdd_get_support */ + + +/**Function******************************************************************** + + Synopsis [Obtains the array of indices of an array of variables.] + + SideEffects [] + +******************************************************************************/ +array_t * +bdd_get_varids(var_array) +array_t *var_array; +{ + int i; + int index; + bdd_t *var; + array_t *result = array_alloc(int,array_n(var_array)); + + for (i = 0; i < array_n(var_array); i++) { + var = array_fetch(bdd_t *, var_array, i); + index = Cudd_Regular(var->node)->index; + (void) array_insert_last(int, result, index); + } + return(result); + +} /* end of bdd_get_varids */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of variables in the manager.] + + SideEffects [] + +******************************************************************************/ +unsigned int +bdd_num_vars(mgr) +bdd_manager *mgr; +{ + return(mgr->size); + +} /* end of bdd_num_vars */ + + +/**Function******************************************************************** + + Synopsis [Prints the BDD.] + + SideEffects [] + +******************************************************************************/ +void +bdd_print(f) +bdd_t *f; +{ + (void) cuddP(f->mgr,f->node); + +} /* end of bdd_print */ + + +/**Function******************************************************************** + + Synopsis [Prints statistics about the package.] + + SideEffects [] + +******************************************************************************/ +void +bdd_print_stats(stats, file) +bdd_stats stats; +FILE *file; +{ +#ifndef DD_STATS + fprintf(stderr,"CU DD package: bdd_print_stats: Statistics turned off. No output\n"); +#else + fprintf(file,"CU DD Package Statistics\n"); + fprintf(file," Cache hits : %d\n",stats.cache.itetable.hits); + fprintf(file," Cache misses : %d\n",stats.cache.itetable.misses); + fprintf(file," Cache collisions : %d\n",stats.cache.itetable.collisions); + fprintf(file," Cache inserts: %d\n",stats.cache.itetable.inserts); +#endif + return; + +} /* end of bdd_print_stats */ + + +/**Function******************************************************************** + + Synopsis [Computes the number of nodes of a BDD.] + + SideEffects [] + +******************************************************************************/ +int +bdd_size(f) +bdd_t *f; +{ + return(Cudd_DagSize(f->node)); + +} /* end of bdd_size */ + + +/**Function******************************************************************** + + Synopsis [Accesses the id of the top variable.] + + SideEffects [] + +******************************************************************************/ +bdd_variableId +bdd_top_var_id(f) +bdd_t *f; +{ + return(Cudd_Regular(f->node)->index); + +} /* end of bdd_top_var_id */ + + +/**Function******************************************************************** + + Synopsis [Accesses the external_hooks field of the manager.] + + SideEffects [] + +******************************************************************************/ +bdd_external_hooks * +bdd_get_external_hooks(mgr) +bdd_manager *mgr; +{ + return((bdd_external_hooks *)(mgr->hooks)); + +} /* end of bdd_get_external_hooks */ + + +/**Function******************************************************************** + + Synopsis [Registers a new hook with the manager.] + + SideEffects [] + +******************************************************************************/ +/*ARGSUSED*/ +void +bdd_register_daemon(mgr, daemon) +bdd_manager *mgr; +void (*daemon)(); +{ + fprintf(stderr,"CU DD Package: bdd_register_daemon translated to no-op.\n"); + return; + +} /* end of bdd_register_daemon */ + + +/**Function******************************************************************** + + Synopsis [Turns on or off garbage collection.] + + SideEffects [] + +******************************************************************************/ +void +bdd_set_gc_mode(mgr, no_gc) +bdd_manager *mgr; +boolean no_gc; +{ + if (no_gc) { + Cudd_DisableGarbageCollection(mgr); + } else { + Cudd_EnableGarbageCollection(mgr); + } + return; + +} /* end of bdd_set_gc_mode */ + + +/**Function******************************************************************** + + Synopsis [Reorders the BDD pool.] + + SideEffects [] + +******************************************************************************/ +void +bdd_dynamic_reordering(mgr, algorithm_type) +bdd_manager *mgr; +bdd_reorder_type_t algorithm_type; +{ + switch (algorithm_type) { + case BDD_REORDER_SIFT: + mgr->autoMethod = CUDD_REORDER_SIFT; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW: + case BDD_REORDER_WINDOW4: + mgr->autoMethod = CUDD_REORDER_WINDOW4; + mgr->autoDyn = 1; + break; + case BDD_REORDER_NONE: + mgr->autoDyn = 0; + break; + case BDD_REORDER_SAME: + mgr->autoDyn = 1; + break; + case BDD_REORDER_RANDOM: + mgr->autoMethod = CUDD_REORDER_RANDOM; + mgr->autoDyn = 1; + break; + case BDD_REORDER_RANDOM_PIVOT: + mgr->autoMethod = CUDD_REORDER_RANDOM_PIVOT; + mgr->autoDyn = 1; + break; + case BDD_REORDER_SIFT_CONVERGE: + mgr->autoMethod = CUDD_REORDER_SIFT_CONVERGE; + mgr->autoDyn = 1; + break; + case BDD_REORDER_SYMM_SIFT: + mgr->autoMethod = CUDD_REORDER_SYMM_SIFT; + mgr->autoDyn = 1; + break; + case BDD_REORDER_SYMM_SIFT_CONV: + mgr->autoMethod = CUDD_REORDER_SYMM_SIFT_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW2: + mgr->autoMethod = CUDD_REORDER_WINDOW2; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW3: + mgr->autoMethod = CUDD_REORDER_WINDOW3; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW2_CONV: + mgr->autoMethod = CUDD_REORDER_WINDOW2_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW3_CONV: + mgr->autoMethod = CUDD_REORDER_WINDOW3_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW4_CONV: + mgr->autoMethod = CUDD_REORDER_WINDOW4_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_GROUP_SIFT: + mgr->autoMethod = CUDD_REORDER_GROUP_SIFT; + mgr->autoDyn = 1; + break; + case BDD_REORDER_GROUP_SIFT_CONV: + mgr->autoMethod = CUDD_REORDER_GROUP_SIFT_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_ANNEALING: + mgr->autoMethod = CUDD_REORDER_ANNEALING; + mgr->autoDyn = 1; + break; + case BDD_REORDER_GENETIC: + mgr->autoMethod = CUDD_REORDER_GENETIC; + mgr->autoDyn = 1; + break; + default: + fprintf(stderr,"CU DD Package: Reordering algorithm not considered\n"); + } + +} /* end of bdd_dynamic_reordering */ + + +/**Function******************************************************************** + + Synopsis [Calls reordering explicitly.] + + SideEffects [] + +******************************************************************************/ +void +bdd_reorder(mgr) +bdd_manager *mgr; +{ + (void) Cudd_ReduceHeap(mgr,mgr->autoMethod,10); /* 10 = whatever (Verbatim from file ddTable.c) */ + return; + +} /* end of bdd_reorder */ + + +/**Function******************************************************************** + + Synopsis [Read the number of reorderings the package has performed + so far.] + + SideEffects [] + +******************************************************************************/ +int +bdd_read_reorderings(mgr) +bdd_manager *mgr; +{ + return Cudd_ReadReorderings((DdManager *)mgr); + +} /* end of bdd_read_reorderings */ + + +/**Function******************************************************************** + + Synopsis [Gets the id variable for one level in the BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_variableId +bdd_get_id_from_level(mgr, level) +bdd_manager *mgr; +long level; +{ + return(mgr->invperm[level]); + +} /* end of bdd_get_id_from_level */ + + +/**Function******************************************************************** + + Synopsis [Gets the level of the top variable of the BDD.] + + SideEffects [] + +******************************************************************************/ +long +bdd_top_var_level(mgr, fn) +bdd_manager *mgr; +bdd_t *fn; +{ + return((long) cuddI(mgr,Cudd_Regular(fn->node)->index)); + +} /* end of bdd_top_var_level */ + + +/**Function******************************************************************** + + Synopsis [Returns TRUE if the argument BDD is a cube; FALSE + otherwise.] + + SideEffects [] + +******************************************************************************/ +boolean +bdd_is_cube(f) +bdd_t *f; +{ + struct DdManager *manager; + + if (f == NULL) { + fail("bdd_is_cube: invalid BDD"); + } + if (f->free) fail ("Freed BDD passed to bdd_is_cube"); + manager = (DdManager *) f->mgr; + return((boolean)cuddCheckCube(manager,f->node)); + +} /* end of bdd_is_cube */ + + +/**Function******************************************************************** + + Synopsis [Calls the garbage collector explicitly.] + + SideEffects [] + +******************************************************************************/ +void +bdd_gc(mgr) +bdd_manager *mgr; +{ + cuddGarbageCollect(mgr,1); + +} /* end of bdd_gc */ + + +/**Function******************************************************************** + + Synopsis [Computes the shared size of an array of BDDs.] + + Description [Computes the shared size of an array of BDDs. Returns + CUDD_OUT_OF_MEM in case of failure.] + + SideEffects [] + +******************************************************************************/ +long +bdd_size_multiple(bddArray) +array_t *bddArray; +{ + DdNode **nodeArray; + bdd_t *bddUnit; + long result; + int i; + + nodeArray = ALLOC(DdNode *, array_n(bddArray)); + if (nodeArray == NULL) return(CUDD_OUT_OF_MEM); + for (i = 0; i < array_n(bddArray); i++) { + bddUnit = array_fetch(bdd_t *, bddArray, i); + nodeArray[i] = bddUnit->node; + } + + result = Cudd_SharingSize(nodeArray,array_n(bddArray)); + + /* Clean up */ + FREE(nodeArray); + + return(result); + +} /* end of bdd_size_multiple */ + + +/**Function******************************************************************** + + Synopsis [Returns the first cube of the function. + A generator is also returned, which will iterate over the rest.] + + Description [Defines an iterator on the onset of a BDD. Two routines + are provided: bdd_first_cube, which extracts one cube from a BDD and + returns a bdd_gen structure containing the information necessary to + continue the enumeration; and bdd_next_cube, which returns 1 if + another cube was found, and 0 otherwise. A cube is represented as an + array of bdd_literal (which are integers in {0, 1, 2}), where 0 + represents negated literal, 1 for literal, and 2 for don't care. + Returns a disjoint cover. A third routine is there to clean up.] + + SideEffects [] + + SeeAlso [bdd_next_cube bdd_gen_free] + +******************************************************************************/ +bdd_gen * +bdd_first_cube(fn, cube) +bdd_t *fn; +array_t **cube; /* of bdd_literal */ +{ + bdd_manager *manager; + bdd_gen *gen; + int i; + int *icube; + CUDD_VALUE_TYPE value; + + /* Make sure we receive a valid bdd_t. (So to speak.) */ + assert(fn != 0); + + manager = fn->mgr; + + /* Initialize the generator. */ + gen = ALLOC(bdd_gen,1); + if (gen == NULL) return(NULL); + gen->manager = manager; + + gen->cube = array_alloc(bdd_literal, manager->size); + if (gen->cube == NULL) { + fail("Bdd Package: Out of memory in bdd_first_cube"); + } + + gen->ddGen = Cudd_FirstCube(manager,fn->node,&icube,&value); + if (gen->ddGen == NULL) { + fail("Cudd Package: Out of memory in bdd_first_cube"); + } + + if (!Cudd_IsGenEmpty(gen->ddGen)) { + /* Copy icube to the array_t cube. */ + for (i = 0; i < manager->size; i++) { + int myconst = icube[i]; + array_insert(bdd_literal, gen->cube, i, myconst); + } + *cube = gen->cube; + } + + return(gen); + +} /* end of bdd_first_cube */ + + +/**Function******************************************************************** + + Synopsis [Gets the next cube on the generator. Returns {TRUE, + FALSE} when {more, no more}.] + + SideEffects [] + + SeeAlso [bdd_first_cube bdd_gen_free] + +******************************************************************************/ +boolean +bdd_next_cube(gen, cube) +bdd_gen *gen; +array_t **cube; /* of bdd_literal */ +{ + int retval; + int *icube; + CUDD_VALUE_TYPE value; + int i; + + retval = Cudd_NextCube(gen->ddGen,&icube,&value); + if (!Cudd_IsGenEmpty(gen->ddGen)) { + /* Copy icube to the array_t cube. */ + for (i = 0; i < gen->manager->size; i++) { + int myconst = icube[i]; + array_insert(bdd_literal, gen->cube, i, myconst); + } + *cube = gen->cube; + } + + return(retval); + +} /* end of bdd_next_cube */ + + +/**Function******************************************************************** + + Synopsis [Gets the first node in the BDD and returns a generator.] + + SideEffects [] + + SeeAlso [bdd_next_node] + +******************************************************************************/ +bdd_gen * +bdd_first_node(fn, node) +bdd_t *fn; +bdd_node **node; /* return */ +{ + bdd_manager *manager; + bdd_gen *gen; + + /* Make sure we receive a valid bdd_t. (So to speak.) */ + assert(fn != 0); + + manager = fn->mgr; + + /* Initialize the generator. */ + gen = ALLOC(bdd_gen,1); + if (gen == NULL) return(NULL); + gen->manager = manager; + gen->cube = NULL; + + gen->ddGen = Cudd_FirstNode(manager,fn->node,node); + if (gen->ddGen == NULL) { + fail("Cudd Package: Out of memory in bdd_first_node"); + } + + return(gen); + +} /* end of bdd_first_node */ + + +/**Function******************************************************************** + + Synopsis [Gets the next node in the BDD. Returns {TRUE, FALSE} when + {more, no more}.] + + SideEffects [] + + SeeAlso [bdd_first_node] + +******************************************************************************/ +boolean +bdd_next_node(gen, node) +bdd_gen *gen; +bdd_node **node; /* return */ +{ + return(Cudd_NextNode(gen->ddGen,node)); + +} /* end of bdd_next_node */ + + +/**Function******************************************************************** + + Synopsis [Frees up the space used by the generator. Returns an int + so that it is easier to fit in a foreach macro. Returns 0 (to make it + easy to put in expressions).] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +bdd_gen_free(gen) +bdd_gen *gen; +{ + if (gen->cube != NULL) array_free(gen->cube); + Cudd_GenFree(gen->ddGen); + FREE(gen); + return(0); + +} /* end of bdd_gen_free */ + + +/**Function******************************************************************** + + Synopsis [Queries the status of a generator.] + + Description [Queries the status of a generator. Returns 1 if the + generator is empty or NULL; 0 otherswise.] + + SideEffects [] + + SeeAlso [bdd_first_cube bdd_next_cube bdd_first_node bdd_next_node + bdd_gen_free] + +******************************************************************************/ +boolean +bdd_is_gen_empty(gen) +bdd_gen *gen; +{ + return(Cudd_IsGenEmpty(gen->ddGen)); + +} /* end of bdd_is_gen_empty */ + + +/**Function******************************************************************** + + Synopsis [Function that creates a variable of a given index.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_var_with_index(manager, index) +bdd_manager *manager; +int index; +{ + DdNode *var; + + var = Cudd_bddIthVar(manager, index); + cuddRef(var); + return(bdd_construct_bdd_t(manager, var)); + +} /* end of bdd_var_with_index */ + + +/**Function******************************************************************** + + Synopsis [Temporary function that is empty.] + + SideEffects [] + +******************************************************************************/ +/*ARGSUSED*/ +void +bdd_new_var_block(f, n) +bdd_t *f; +long n; +{ + return; + +} /* end of bdd_new_var_block */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Builds the bdd_t structure.] + + Description [Builds the bdd_t structure from manager and node. + Assumes that the reference count of the node has already been + increased.] + + SideEffects [] + +******************************************************************************/ +static bdd_t * +bdd_construct_bdd_t(mgr,fn) +DdManager *mgr; +DdNode * fn; +{ + bdd_t *result; + + result = ALLOC(bdd_t, 1); + if (result == NULL) { + Cudd_RecursiveDeref(mgr,fn); + return(NULL); + } + result->mgr = mgr; + result->node = fn; + result->free = FALSE; + return(result); + +} /* end of bdd_construct_bdd_t */ diff --git a/resources/3rdparty/cudd-2.5.0/sis/cuddPwPt.c b/resources/3rdparty/cudd-2.5.0/sis/cuddPwPt.c new file mode 100644 index 000000000..823f7b966 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/sis/cuddPwPt.c @@ -0,0 +1,147 @@ +/**CFile*********************************************************************** + + FileName [cuddPwPt.c] + + PackageName [cudd] + + Synopsis [Emulation functions for the power package in SIS.] + + Description [This file contains functions that are necessary for the + power package in SIS. This package directly calls a few functions of + the CMU BDD package. Therefore, functions with identical names and + equivalent functionality are provided here. + External procedures included in this file: +
            +
          • cmu_bdd_zero() +
          • cmu_bdd_one() +
          • cmu_bdd_if_index() +
          + Internal procedures included in this module: +
            +
          • +
          ] + + Author [Fabio Somenzi] + + Copyright [This file was created at the University of Colorado at + Boulder. The University of Colorado at Boulder makes no warranty + about the suitability of this software for any purpose. It is + presented on an AS IS basis.] + +******************************************************************************/ + +#include "util.h" +#include "array.h" +#include "st.h" +#include "cuddInt.h" +#include "cuddBdd.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddPwPt.c,v 1.3 1997/01/18 19:43:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns a pointer to the one constant.] + + Description [Returns a pointer to the one constant. Used by the power + package in SIS. For new code, use Cudd_ReadOne instead.] + + SideEffects [None] + + SeeAlso [Cudd_ReadOne] + +******************************************************************************/ +bdd_node * +cmu_bdd_one(dd) +bdd_manager *dd; +{ + return((bdd_node *)((DdManager *)dd)->one); + +} /* end of cmu_bdd_one */ + + +/**Function******************************************************************** + + Synopsis [Returns a pointer to the zero constant.] + + Description [Returns a pointer to the zero constant. Used by the power + package in SIS. For new code, use Cudd_ReadZero instead.] + + SideEffects [None] + + SeeAlso [Cudd_ReadZero] + +******************************************************************************/ +bdd_node * +cmu_bdd_zero(dd) +bdd_manager *dd; +{ + return((bdd_node *)Cudd_Not(((DdManager *)dd)->one)); + +} /* end of cmu_bdd_zero */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the top variable in a BDD.] + + Description [Returns the index of the top variable in a BDD. Used by + the power package in SIS. For new code, use Cudd_ReadIndex instead.] + + SideEffects [None] + + SeeAlso [Cudd_ReadIndex] + +******************************************************************************/ +int +cmu_bdd_if_index(dd, node) +bdd_manager *dd; +bdd_node *node; +{ + return(Cudd_Regular(node)->index); + +} /* end of cmu_bdd_if_index */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/sis/st.c b/resources/3rdparty/cudd-2.5.0/sis/st.c new file mode 100644 index 000000000..426c79c5a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/sis/st.c @@ -0,0 +1,554 @@ +/* + * Revision Control Information + * + * /projects/hsis/CVS/utilities/st/st.c,v + * serdar + * 1.1 + * 1993/07/29 01:00:13 + * + */ +#include +#include "util.h" +#include "st.h" + +#define ST_NUMCMP(x,y) ((x) != (y)) +#define ST_NUMHASH(x,size) (ABS((long)x)%(size)) +#define ST_PTRHASH(x,size) ((int)((unsigned long)(x)>>2)%size) +#define EQUAL(func, x, y) \ + ((((func) == st_numcmp) || ((func) == st_ptrcmp)) ?\ + (ST_NUMCMP((x),(y)) == 0) : ((*func)((x), (y)) == 0)) + + +#define do_hash(key, table)\ + ((int)((table->hash == st_ptrhash) ? ST_PTRHASH((key),(table)->num_bins) :\ + (table->hash == st_numhash) ? ST_NUMHASH((key), (table)->num_bins) :\ + (*table->hash)((key), (table)->num_bins))) + +static int rehash (st_table *); + +st_table * +st_init_table_with_params( + ST_PFICPCP compare, + ST_PFICPI hash, + int size, + int density, + double grow_factor, + int reorder_flag) +{ + int i; + st_table *newt; + + newt = ALLOC(st_table, 1); + if (newt == NIL(st_table)) { + return NIL(st_table); + } + newt->compare = (int (*)(const char *, const char *)) compare; + newt->hash = (int (*)(char *, int)) hash; + newt->num_entries = 0; + newt->max_density = density; + newt->grow_factor = grow_factor; + newt->reorder_flag = reorder_flag; + if (size <= 0) { + size = 1; + } + newt->num_bins = size; + newt->bins = ALLOC(st_table_entry *, size); + if (newt->bins == NIL(st_table_entry *)) { + FREE(newt); + return NIL(st_table); + } + for(i = 0; i < size; i++) { + newt->bins[i] = 0; + } + return newt; +} + +st_table * +st_init_table(ST_PFICPCP compare, ST_PFICPI hash) +{ + return st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE, + ST_DEFAULT_MAX_DENSITY, + ST_DEFAULT_GROW_FACTOR, + ST_DEFAULT_REORDER_FLAG); +} + +void +st_free_table(st_table *table) +{ + register st_table_entry *ptr, *next; + int i; + + for(i = 0; i < table->num_bins ; i++) { + ptr = table->bins[i]; + while (ptr != NIL(st_table_entry)) { + next = ptr->next; + FREE(ptr); + ptr = next; + } + } + FREE(table->bins); + FREE(table); +} + +#define PTR_NOT_EQUAL(table, ptr, user_key)\ +(ptr != NULL && !EQUAL(table->compare, user_key, (ptr)->key)) + +#define FIND_ENTRY(table, hash_val, key, ptr, last) \ + (last) = &(table)->bins[hash_val];\ + (ptr) = *(last);\ + while (PTR_NOT_EQUAL((table), (ptr), (key))) {\ + (last) = &(ptr)->next; (ptr) = *(last);\ + }\ + if ((ptr) != NULL && (table)->reorder_flag) {\ + *(last) = (ptr)->next;\ + (ptr)->next = (table)->bins[hash_val];\ + (table)->bins[hash_val] = (ptr);\ + } + +int +st_lookup(st_table *table, char *key, char **value) +{ + int hash_val; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (value != NIL(char *)) { + *value = ptr->record; + } + return 1; + } +} + +int +st_lookup_int(st_table *table, char *key, int *value) +{ + int hash_val; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (value != NIL(int)) { + *value = (int) (util_ptrint) ptr->record; + } + return 1; + } +} + +/* This macro does not check if memory allocation fails. Use at you own risk */ +#define ADD_DIRECT(table, key, value, hash_val, newt)\ +{\ + if (table->num_entries/table->num_bins >= table->max_density) {\ + rehash(table);\ + hash_val = do_hash(key,table);\ + }\ + \ + newt = ALLOC(st_table_entry, 1);\ + \ + newt->key = key;\ + newt->record = value;\ + newt->next = table->bins[hash_val];\ + table->bins[hash_val] = newt;\ + table->num_entries++;\ +} + +int +st_insert(st_table *table, char *key, char *value) +{ + int hash_val; + st_table_entry *newt; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + if (table->num_entries/table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + hash_val = do_hash(key, table); + } + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = key; + newt->record = value; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + return 0; + } else { + ptr->record = value; + return 1; + } +} + +int +st_add_direct(st_table *table, char *key, char *value) +{ + int hash_val; + st_table_entry *newt; + + hash_val = do_hash(key, table); + if (table->num_entries / table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + } + hash_val = do_hash(key, table); + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = key; + newt->record = value; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + return 1; +} + +int +st_find_or_add(st_table *table, char *key, char ***slot) +{ + int hash_val; + st_table_entry *newt, *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + if (table->num_entries / table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + hash_val = do_hash(key, table); + } + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = key; + newt->record = (char *) 0; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + if (slot != NIL(char **)) *slot = &newt->record; + return 0; + } else { + if (slot != NIL(char **)) *slot = &ptr->record; + return 1; + } +} + +int +st_find(st_table *table, char *key, char ***slot) +{ + int hash_val; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (slot != NIL(char **)) { + *slot = &ptr->record; + } + return 1; + } +} + +static int +rehash(st_table *table) +{ + register st_table_entry *ptr, *next, **old_bins; + int i, old_num_bins, hash_val, old_num_entries; + + /* save old values */ + old_bins = table->bins; + old_num_bins = table->num_bins; + old_num_entries = table->num_entries; + + /* rehash */ + table->num_bins = (int) (table->grow_factor * old_num_bins); + if (table->num_bins % 2 == 0) { + table->num_bins += 1; + } + table->num_entries = 0; + table->bins = ALLOC(st_table_entry *, table->num_bins); + if (table->bins == NIL(st_table_entry *)) { + table->bins = old_bins; + table->num_bins = old_num_bins; + table->num_entries = old_num_entries; + return ST_OUT_OF_MEM; + } + /* initialize */ + for (i = 0; i < table->num_bins; i++) { + table->bins[i] = 0; + } + + /* copy data over */ + for (i = 0; i < old_num_bins; i++) { + ptr = old_bins[i]; + while (ptr != NIL(st_table_entry)) { + next = ptr->next; + hash_val = do_hash(ptr->key, table); + ptr->next = table->bins[hash_val]; + table->bins[hash_val] = ptr; + table->num_entries++; + ptr = next; + } + } + FREE(old_bins); + + return 1; +} + +st_table * +st_copy(st_table *old_table) +{ + st_table *new_table; + st_table_entry *ptr, *newptr, *next, *newt; + int i, j, num_bins = old_table->num_bins; + + new_table = ALLOC(st_table, 1); + if (new_table == NIL(st_table)) { + return NIL(st_table); + } + + *new_table = *old_table; + new_table->bins = ALLOC(st_table_entry *, num_bins); + if (new_table->bins == NIL(st_table_entry *)) { + FREE(new_table); + return NIL(st_table); + } + for(i = 0; i < num_bins ; i++) { + new_table->bins[i] = NIL(st_table_entry); + ptr = old_table->bins[i]; + while (ptr != NIL(st_table_entry)) { + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + for (j = 0; j <= i; j++) { + newptr = new_table->bins[j]; + while (newptr != NIL(st_table_entry)) { + next = newptr->next; + FREE(newptr); + newptr = next; + } + } + FREE(new_table->bins); + FREE(new_table); + return NIL(st_table); + } + *newt = *ptr; + newt->next = new_table->bins[i]; + new_table->bins[i] = newt; + ptr = ptr->next; + } + } + return new_table; +} + +int +st_delete(st_table *table, char **keyp, char **value) +{ + int hash_val; + char *key = *keyp; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr ,last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } + + *last = ptr->next; + if (value != NIL(char *)) *value = ptr->record; + *keyp = ptr->key; + FREE(ptr); + table->num_entries--; + return 1; +} + +int +st_delete_int(st_table *table, int *keyp, char **value) +{ + int hash_val; + char *key = (char *) (util_ptrint) *keyp; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr ,last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } + + *last = ptr->next; + if (value != NIL(char *)) *value = ptr->record; + *keyp = (int) (util_ptrint) ptr->key; + FREE(ptr); + table->num_entries--; + return 1; +} + +int +st_foreach(st_table *table, ST_PFSR func, char *arg) +{ + st_table_entry *ptr, **last; + enum st_retval retval; + int i; + + for(i = 0; i < table->num_bins; i++) { + last = &table->bins[i]; ptr = *last; + while (ptr != NIL(st_table_entry)) { + retval = (*func)(ptr->key, ptr->record, arg); + switch (retval) { + case ST_CONTINUE: + last = &ptr->next; ptr = *last; + break; + case ST_STOP: + return 0; + case ST_DELETE: + *last = ptr->next; + table->num_entries--; /* cstevens@ic */ + FREE(ptr); + ptr = *last; + } + } + } + return 1; +} + +int +st_strhash(char *string, int modulus) +{ + register int val = 0; + register int c; + + while ((c = *string++) != '\0') { + val = val*997 + c; + } + + return ((val < 0) ? -val : val)%modulus; +} + +int +st_numhash(char *x, int size) +{ + return ST_NUMHASH(x, size); +} + +int +st_ptrhash(char *x, int size) +{ + return ST_PTRHASH(x, size); +} + +int +st_numcmp(const char *x, const char *y) +{ + return ST_NUMCMP(x, y); +} + +int +st_ptrcmp(const char *x, const char *y) +{ + return ST_NUMCMP(x, y); +} + +st_generator * +st_init_gen(st_table *table) +{ + st_generator *gen; + + gen = ALLOC(st_generator, 1); + if (gen == NIL(st_generator)) { + return NIL(st_generator); + } + gen->table = table; + gen->entry = NIL(st_table_entry); + gen->index = 0; + return gen; +} + + +int +st_gen(st_generator *gen, char **key_p, char **value_p) +{ + register int i; + + if (gen->entry == NIL(st_table_entry)) { + /* try to find next entry */ + for(i = gen->index; i < gen->table->num_bins; i++) { + if (gen->table->bins[i] != NIL(st_table_entry)) { + gen->index = i+1; + gen->entry = gen->table->bins[i]; + break; + } + } + if (gen->entry == NIL(st_table_entry)) { + return 0; /* that's all folks ! */ + } + } + *key_p = gen->entry->key; + if (value_p != 0) { + *value_p = gen->entry->record; + } + gen->entry = gen->entry->next; + return 1; +} + + +int +st_gen_int(st_generator *gen, char **key_p, long *value_p) +{ + register int i; + + if (gen->entry == NIL(st_table_entry)) { + /* try to find next entry */ + for(i = gen->index; i < gen->table->num_bins; i++) { + if (gen->table->bins[i] != NIL(st_table_entry)) { + gen->index = i+1; + gen->entry = gen->table->bins[i]; + break; + } + } + if (gen->entry == NIL(st_table_entry)) { + return 0; /* that's all folks ! */ + } + } + *key_p = gen->entry->key; + if (value_p != NIL(long)) { + *value_p = (long) gen->entry->record; + } + gen->entry = gen->entry->next; + return 1; +} + + +void +st_free_gen(st_generator *gen) +{ + FREE(gen); +} diff --git a/resources/3rdparty/cudd-2.5.0/sis/st.h b/resources/3rdparty/cudd-2.5.0/sis/st.h new file mode 100644 index 000000000..a1d86192e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/sis/st.h @@ -0,0 +1,97 @@ +/* + * Revision Control Information + * + * /projects/hsis/CVS/utilities/st/st.h,v + * serdar + * 1.1 + * 1993/07/29 01:00:21 + * + */ +/* LINTLIBRARY */ + +/* /projects/hsis/CVS/utilities/st/st.h,v 1.1 1993/07/29 01:00:21 serdar Exp */ + +#ifndef ST_INCLUDED +#define ST_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct st_table_entry st_table_entry; +struct st_table_entry { + char *key; + char *record; + st_table_entry *next; +}; + +typedef struct st_table st_table; +struct st_table { + int (*compare)(const char *, const char *); + int (*hash)(char *, int); + int num_bins; + int num_entries; + int max_density; + int reorder_flag; + double grow_factor; + st_table_entry **bins; +}; + +typedef struct st_generator st_generator; +struct st_generator { + st_table *table; + st_table_entry *entry; + int index; +}; + +#define st_is_member(table,key) st_lookup(table,key,(char **) 0) +#define st_count(table) ((table)->num_entries) + +enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE}; + +typedef enum st_retval (*ST_PFSR)(char *, char *, char *); +typedef int (*ST_PFICPCP)(const char *, const char *); /* type for comparison function */ +typedef int (*ST_PFICPI)(char *, int); /* type for hash function */ + +extern st_table *st_init_table_with_params (ST_PFICPCP, ST_PFICPI, int, int, double, int); +extern st_table *st_init_table (ST_PFICPCP, ST_PFICPI); +extern void st_free_table (st_table *); +extern int st_lookup (st_table *, char *, char **); +extern int st_lookup_int (st_table *, char *, int *); +extern int st_insert (st_table *, char *, char *); +extern int st_add_direct (st_table *, char *, char *); +extern int st_find_or_add (st_table *, char *, char ***); +extern int st_find (st_table *, char *, char ***); +extern st_table *st_copy (st_table *); +extern int st_delete (st_table *, char **, char **); +extern int st_delete_int (st_table *, int *, char **); +extern int st_foreach (st_table *, ST_PFSR, char *); +extern int st_strhash (char *, int); +extern int st_numhash (char *, int); +extern int st_ptrhash (char *, int); +extern int st_numcmp (const char *, const char *); +extern int st_ptrcmp (const char *, const char *); +extern st_generator *st_init_gen (st_table *); +extern int st_gen (st_generator *, char **, char **); +extern int st_gen_int (st_generator *, char **, long *); +extern void st_free_gen (st_generator *); + + +#define ST_DEFAULT_MAX_DENSITY 5 +#define ST_DEFAULT_INIT_TABLE_SIZE 11 +#define ST_DEFAULT_GROW_FACTOR 2.0 +#define ST_DEFAULT_REORDER_FLAG 0 + +#define st_foreach_item(table, gen, key, value) \ + for(gen=st_init_gen(table); st_gen(gen,key,value) || (st_free_gen(gen),0);) + +#define st_foreach_item_int(table, gen, key, value) \ + for(gen=st_init_gen(table); st_gen_int(gen,key,value) || (st_free_gen(gen),0);) + +#define ST_OUT_OF_MEM -10000 + +#ifdef __cplusplus +} +#endif + +#endif /* ST_INCLUDED */ diff --git a/resources/3rdparty/cudd-2.5.0/st/Makefile b/resources/3rdparty/cudd-2.5.0/st/Makefile new file mode 100644 index 000000000..5fdc949c6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/Makefile @@ -0,0 +1,64 @@ +# $Id: Makefile,v 1.3 2004/01/01 06:53:06 fabio Exp fabio $ +# +# st -- hash table package +#--------------------------------------------------------------------------- +.SUFFIXES: .c .o .u + +CC = gcc +RANLIB = ranlib + +MFLAG = +ICFLAGS = -g -O6 -Wall +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) + +LINTFLAGS = -u -n + +# this is to create the lint library +LINTSWITCH = -o + +P = st +PSRC = st.c +PHDR = st.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) + +WHERE = .. +INCLUDE = $(WHERE)/include + +#--------------------------- + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +clean: + rm -f *.o *.u .pure *.warnings + +distclean: clean + rm -f lib*.a lib$(P).b llib-l$(P).ln tags *~ *.bak *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/st/doc/stAllAbs.html b/resources/3rdparty/cudd-2.5.0/st/doc/stAllAbs.html new file mode 100644 index 000000000..927c116bc --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/doc/stAllAbs.html @@ -0,0 +1,96 @@ + +st package abstract (Internal) + + +

          st package abstract (Internal)

          +

          +
          + + + +
          +
          st_add_direct() +
          Place 'value' in 'table' under the key 'key'. + +
          st_copy() +
          Return a copy of old_table and all its members. + +
          st_count() +
          Returns the number of entries in the table `table'. + +
          st_delete_int() +
          Delete the entry with the key pointed to by `keyp'. + +
          st_delete() +
          Delete the entry with the key pointed to by `keyp'. + +
          st_find_or_add() +
          Lookup `key' in `table'. + +
          st_find() +
          Lookup `key' in `table'. + +
          st_foreach_item_int() +
          Iteration macro. + +
          st_foreach_item() +
          Iteration macro. + +
          st_foreach() +
          Iterates over the elements of a table. + +
          st_free_gen() +
          Reclaims the resources associated with `gen'. + +
          st_free_table() +
          Free a table. + +
          st_gen_int() +
          Returns the next (key, value) pair in the generation sequence. + +
          st_gen() +
          returns the next (key, value) pair in the generation sequence. + +
          st_init_gen() +
          Initializes a generator. + +
          st_init_table_with_params() +
          Create a table with given parameters. + +
          st_init_table() +
          Create and initialize a table. + +
          st_insert() +
          Insert value in table under the key 'key'. + +
          st_is_member() +
          Checks whethere `key' is in `table'. + +
          st_lookup_int() +
          Lookup up `key' in `table'. + +
          st_lookup() +
          Lookup up `key' in `table'. + +
          st_numcmp() +
          Number comparison function. + +
          st_numhash() +
          Number hash function. + +
          st_ptrcmp() +
          Pointer comparison function. + +
          st_ptrhash() +
          Pointer hash function. + +
          st_strhash() +
          String hash function. + +
          + +
          + +Generated automatically by extdoc on 20040102 + + diff --git a/resources/3rdparty/cudd-2.5.0/st/doc/stAllDet.html b/resources/3rdparty/cudd-2.5.0/st/doc/stAllDet.html new file mode 100644 index 000000000..e56d8834d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/doc/stAllDet.html @@ -0,0 +1,462 @@ + +The st package (Internal) + + +

          The st package (Internal)

          +

          +

          +
          + + +
          + + + + + +
          + + +
          + +
          +int 
          +st_add_direct(
          +  st_table * table, 
          +  void * key, 
          +  void * value 
          +)
          +
          +
          Place 'value' in 'table' under the key 'key'. This is done without checking if 'key' is in 'table' already. This should only be used if you are sure there is not already an entry for 'key', since it is undefined which entry you would later get from st_lookup or st_find_or_add. Returns 1 if successful; ST_OUT_OF_MEM otherwise. +

          + +

          Side Effects None +

          + +

          +st_table * 
          +st_copy(
          +  st_table * old_table 
          +)
          +
          +
          Return a copy of old_table and all its members. (st_table *) 0 is returned if there was insufficient memory to do the copy. +

          + +

          Side Effects None +

          + +

          + 
          +st_count(
          +   table 
          +)
          +
          +
          Returns the number of entries in the table `table'. +

          + +

          Side Effects None +

          + +

          +int 
          +st_delete_int(
          +  st_table * table, 
          +  void * keyp, 
          +  int * value 
          +)
          +
          +
          Delete the entry with the key pointed to by `keyp'. `value' must be a pointer to an integer. If the entry is found, 1 is returned, the variable pointed by `keyp' is set to the actual key and the variable pointed by `value' is set to the corresponding entry. (This allows the freeing of the associated storage.) If the entry is not found, then 0 is returned and nothing is changed. +

          + +

          Side Effects None +

          + +

          See Also st_delete + + +
          +int 
          +st_delete(
          +  st_table * table, 
          +  void * keyp, 
          +  void * value 
          +)
          +
          +
          Delete the entry with the key pointed to by `keyp'. If the entry is found, 1 is returned, the variable pointed by `keyp' is set to the actual key and the variable pointed by `value' is set to the corresponding entry. (This allows the freeing of the associated storage.) If the entry is not found, then 0 is returned and nothing is changed. +

          + +

          Side Effects None +

          + +

          See Also st_delete_int + + +
          +int 
          +st_find_or_add(
          +  st_table * table, 
          +  void * key, 
          +  void * slot 
          +)
          +
          +
          Lookup `key' in `table'. If not found, create an entry. In either case set slot to point to the field in the entry where the value is stored. The value associated with `key' may then be changed by accessing directly through slot. Returns 1 if an entry already existed, 0 if it did not exist and creation was successful; ST_OUT_OF_MEM otherwise. As an example:
           char **slot; 
           char *key; 
           char *value = (char *) item_ptr <-- ptr to a malloc'd structure 
           if (st_find_or_add(table, key, &slot) == 1) { 
           FREE(*slot); <-- free the old value of the record 
           } 
           *slot = value; <-- attach the new value to the record 
          This replaces the equivelent code:
           if (st_lookup(table, key, &ovalue) == 1) { 
           FREE(ovalue); 
           } 
           st_insert(table, key, value); 
          +

          + +

          Side Effects None +

          + +

          See Also st_find + + +
          +int 
          +st_find(
          +  st_table * table, 
          +  void * key, 
          +  void * slot 
          +)
          +
          +
          Like st_find_or_add, but does not create an entry if one is not found. +

          + +

          Side Effects None +

          + +

          See Also st_find_or_add + + +
          + 
          +st_foreach_item_int(
          +   table, 
          +   gen, 
          +   key, 
          +   value 
          +)
          +
          +
          An iteration macro which loops over all the entries in `table', setting `key' to point to the key and `value' to the associated value (if it is not nil). `value' is assumed to be a pointer to an integer. `gen' is a generator variable used internally. Sample usage:
           char *key; 
           int value; 
           st_generator *gen; 
           st_foreach_item_int(table, gen, &key, &value) { 
           process_item(value); 
           } 
          +

          + +

          Side Effects None +

          + +

          See Also st_foreach_item +st_foreach + + +
          + 
          +st_foreach_item(
          +   table, 
          +   gen, 
          +   key, 
          +   value 
          +)
          +
          +
          An iteration macro which loops over all the entries in `table', setting `key' to point to the key and `value' to the associated value (if it is not nil). `gen' is a generator variable used internally. Sample usage:
           char *key, *value; 
           st_generator *gen; 
           st_foreach_item(table, gen, &key, &value) { 
           process_item(value); 
           } 
          +

          + +

          Side Effects None +

          + +

          See Also st_foreach_item_int +st_foreach + + +
          +int 
          +st_foreach(
          +  st_table * table, 
          +  ST_PFSR  func, 
          +  char * arg 
          +)
          +
          +
          For each (key, value) record in `table', st_foreach call func with the arguments
           (*func)(key, value, arg) 
          If func returns ST_CONTINUE, st_foreach continues processing entries. If func returns ST_STOP, st_foreach stops processing and returns immediately. If func returns ST_DELETE, then the entry is deleted from the symbol table and st_foreach continues. In the case of ST_DELETE, it is func's responsibility to free the key and value, if necessary.

          The routine returns 1 if all items in the table were generated and 0 if the generation sequence was aborted using ST_STOP. The order in which the records are visited will be seemingly random. +

          + +

          Side Effects None +

          + +

          See Also st_foreach_item +st_foreach_item_int + + +
          +void 
          +st_free_gen(
          +  st_generator * gen 
          +)
          +
          +
          After generating all items in a generation sequence, this routine must be called to reclaim the resources associated with `gen'. +

          + +

          Side Effects None +

          + +

          See Also st_init_gen + + +
          +void 
          +st_free_table(
          +  st_table * table 
          +)
          +
          +
          Any internal storage associated with table is freed. It is the user's responsibility to free any storage associated with the pointers he placed in the table (by perhaps using st_foreach). +

          + +

          Side Effects None +

          + +

          See Also st_init_table +st_init_table_with_params + + +
          +int 
          +st_gen_int(
          +  st_generator * gen, 
          +  void * key_p, 
          +  int * value_p 
          +)
          +
          +
          Given a generator returned by st_init_gen(), this routine returns the next (key, value) pair in the generation sequence. `value_p' must be a pointer to an integer. The pointer `value_p' can be zero which means no value will be returned. When there are no more items in the generation sequence, the routine returns 0. +

          + +

          Side Effects None +

          + +

          See Also st_gen + + +
          +int 
          +st_gen(
          +  st_generator * gen, 
          +  void * key_p, 
          +  void * value_p 
          +)
          +
          +
          Given a generator returned by st_init_gen(), this routine returns the next (key, value) pair in the generation sequence. The pointer `value_p' can be zero which means no value will be returned. When there are no more items in the generation sequence, the routine returns 0. While using a generation sequence, deleting any (key, value) pair other than the one just generated may cause a fatal error when st_gen() is called later in the sequence and is therefore not recommended. +

          + +

          Side Effects None +

          + +

          See Also st_gen_int + + +
          +st_generator * 
          +st_init_gen(
          +  st_table * table 
          +)
          +
          +
          Returns a generator handle which when used with st_gen() will progressively return each (key, value) record in `table'. +

          + +

          Side Effects None +

          + +

          See Also st_free_gen + + +
          +st_table * 
          +st_init_table_with_params(
          +  ST_PFICPCP  compare, 
          +  ST_PFICPI  hash, 
          +  int  size, 
          +  int  density, 
          +  double  grow_factor, 
          +  int  reorder_flag 
          +)
          +
          +
          The full blown table initializer. compare and hash are the same as in st_init_table. density is the largest the average number of entries per hash bin there should be before the table is grown. grow_factor is the factor the table is grown by when it becomes too full. size is the initial number of bins to be allocated for the hash table. If reorder_flag is non-zero, then every time an entry is found, it is moved to the top of the chain.

          st_init_table(compare, hash) is equivelent to

           st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE, ST_DEFAULT_MAX_DENSITY, ST_DEFAULT_GROW_FACTOR, ST_DEFAULT_REORDER_FLAG); 
          +

          + +

          Side Effects None +

          + +

          See Also st_init_table +st_free_table + + +
          +st_table * 
          +st_init_table(
          +  ST_PFICPCP  compare, 
          +  ST_PFICPI  hash 
          +)
          +
          +
          Create and initialize a table with the comparison function compare_fn and hash function hash_fn. compare_fn is
           int compare_fn(const char *key1, const char *key2) 
          It returns <,=,> 0 depending on whether key1 <,=,> key2 by some measure.

          hash_fn is

           int hash_fn(char *key, int modulus) 
          It returns a integer between 0 and modulus-1 such that if compare_fn(key1,key2) == 0 then hash_fn(key1) == hash_fn(key2).

          There are five predefined hash and comparison functions in st. For keys as numbers:

           st_numhash(key, modulus) { return (unsigned int) key % modulus; } 
           st_numcmp(x,y) { return (int) x - (int) y; } 
          For keys as pointers:
           st_ptrhash(key, modulus) { return ((unsigned int) key/4) % modulus } 
           st_ptrcmp(x,y) { return (int) x - (int) y; } 
          For keys as strings:
           st_strhash(x,y) - a reasonable hashing function for strings 
           strcmp(x,y) - the standard library function 
          It is recommended to use these particular functions if they fit your needs, since st will recognize certain of them and run more quickly because of it. +

          + +

          Side Effects None +

          + +

          See Also st_init_table_with_params +st_free_table + + +
          +int 
          +st_insert(
          +  st_table * table, 
          +  void * key, 
          +  void * value 
          +)
          +
          +
          Insert value in table under the key 'key'. Returns 1 if there was an entry already under the key; 0 if there was no entry under the key and insertion was successful; ST_OUT_OF_MEM otherwise. In either of the first two cases the new value is added. +

          + +

          Side Effects None +

          + +

          + 
          +st_is_member(
          +   table, 
          +   key 
          +)
          +
          +
          Returns 1 if there is an entry under `key' in `table', 0 otherwise. +

          + +

          Side Effects None +

          + +

          See Also st_lookup + + +
          +int 
          +st_lookup_int(
          +  st_table * table, 
          +  void * key, 
          +  int * value 
          +)
          +
          +
          Lookup up `key' in `table'. If an entry is found, 1 is returned and if `value' is not nil, the variable it points to is set to the associated integer value. If an entry is not found, 0 is return and the variable pointed by `value' is unchanged. +

          + +

          Side Effects None +

          + +

          See Also st_lookup + + +
          +int 
          +st_lookup(
          +  st_table * table, 
          +  void * key, 
          +  void * value 
          +)
          +
          +
          Lookup up `key' in `table'. If an entry is found, 1 is returned and if `value' is not nil, the variable it points to is set to the associated value. If an entry is not found, 0 is returned and the variable pointed by value is unchanged. +

          + +

          Side Effects None +

          + +

          See Also st_lookup_int + + +
          +int 
          +st_numcmp(
          +  const char * x, 
          +  const char * y 
          +)
          +
          +
          integer number comparison function. +

          + +

          Side Effects None +

          + +

          See Also st_init_table +st_numhash + + +
          +int 
          +st_numhash(
          +  char * x, 
          +  int  size 
          +)
          +
          +
          Integer number hash function. +

          + +

          Side Effects None +

          + +

          See Also st_init_table +st_numcmp + + +
          +int 
          +st_ptrcmp(
          +  const char * x, 
          +  const char * y 
          +)
          +
          +
          Pointer comparison function. +

          + +

          Side Effects None +

          + +

          See Also st_init_table +st_ptrhash + + +
          +int 
          +st_ptrhash(
          +  char * x, 
          +  int  size 
          +)
          +
          +
          Pointer hash function. +

          + +

          Side Effects None +

          + +

          See Also st_init_table +st_ptrcmp + + +
          +int 
          +st_strhash(
          +  char * string, 
          +  int  modulus 
          +)
          +
          +
          String hash function. +

          + +

          Side Effects None +

          + +

          See Also st_init_table + + + +
          + +
          + +Generated automatically by extdoc on 20040102 + + diff --git a/resources/3rdparty/cudd-2.5.0/st/doc/stExtAbs.html b/resources/3rdparty/cudd-2.5.0/st/doc/stExtAbs.html new file mode 100644 index 000000000..5302461fa --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/doc/stExtAbs.html @@ -0,0 +1,96 @@ + +st package abstract + + +

          st package abstract

          +

          Symbol table package.

          +
          + + + +
          +
          st_add_direct() +
          Place 'value' in 'table' under the key 'key'. + +
          st_copy() +
          Return a copy of old_table and all its members. + +
          st_count() +
          Returns the number of entries in the table `table'. + +
          st_delete_int() +
          Delete the entry with the key pointed to by `keyp'. + +
          st_delete() +
          Delete the entry with the key pointed to by `keyp'. + +
          st_find_or_add() +
          Lookup `key' in `table'. + +
          st_find() +
          Lookup `key' in `table'. + +
          st_foreach_item_int() +
          Iteration macro. + +
          st_foreach_item() +
          Iteration macro. + +
          st_foreach() +
          Iterates over the elements of a table. + +
          st_free_gen() +
          Reclaims the resources associated with `gen'. + +
          st_free_table() +
          Free a table. + +
          st_gen_int() +
          Returns the next (key, value) pair in the generation sequence. + +
          st_gen() +
          returns the next (key, value) pair in the generation sequence. + +
          st_init_gen() +
          Initializes a generator. + +
          st_init_table_with_params() +
          Create a table with given parameters. + +
          st_init_table() +
          Create and initialize a table. + +
          st_insert() +
          Insert value in table under the key 'key'. + +
          st_is_member() +
          Checks whethere `key' is in `table'. + +
          st_lookup_int() +
          Lookup up `key' in `table'. + +
          st_lookup() +
          Lookup up `key' in `table'. + +
          st_numcmp() +
          Number comparison function. + +
          st_numhash() +
          Number hash function. + +
          st_ptrcmp() +
          Pointer comparison function. + +
          st_ptrhash() +
          Pointer hash function. + +
          st_strhash() +
          String hash function. + +
          + +
          + +Generated automatically by extdoc on 20040102 + + diff --git a/resources/3rdparty/cudd-2.5.0/st/doc/stExtDet.html b/resources/3rdparty/cudd-2.5.0/st/doc/stExtDet.html new file mode 100644 index 000000000..43cb6f464 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/doc/stExtDet.html @@ -0,0 +1,463 @@ + +The st package + + +

          The st package

          +

          Symbol table package.

          +

          +
          + + +
          + + +The st library provides functions to create, maintain, + and query symbol tables. + + +
          + + +
          + +
          +int 
          +st_add_direct(
          +  st_table * table, 
          +  void * key, 
          +  void * value 
          +)
          +
          +
          Place 'value' in 'table' under the key 'key'. This is done without checking if 'key' is in 'table' already. This should only be used if you are sure there is not already an entry for 'key', since it is undefined which entry you would later get from st_lookup or st_find_or_add. Returns 1 if successful; ST_OUT_OF_MEM otherwise. +

          + +

          Side Effects None +

          + +

          +st_table * 
          +st_copy(
          +  st_table * old_table 
          +)
          +
          +
          Return a copy of old_table and all its members. (st_table *) 0 is returned if there was insufficient memory to do the copy. +

          + +

          Side Effects None +

          + +

          + 
          +st_count(
          +   table 
          +)
          +
          +
          Returns the number of entries in the table `table'. +

          + +

          Side Effects None +

          + +

          +int 
          +st_delete_int(
          +  st_table * table, 
          +  void * keyp, 
          +  int * value 
          +)
          +
          +
          Delete the entry with the key pointed to by `keyp'. `value' must be a pointer to an integer. If the entry is found, 1 is returned, the variable pointed by `keyp' is set to the actual key and the variable pointed by `value' is set to the corresponding entry. (This allows the freeing of the associated storage.) If the entry is not found, then 0 is returned and nothing is changed. +

          + +

          Side Effects None +

          + +

          See Also st_delete + + +
          +int 
          +st_delete(
          +  st_table * table, 
          +  void * keyp, 
          +  void * value 
          +)
          +
          +
          Delete the entry with the key pointed to by `keyp'. If the entry is found, 1 is returned, the variable pointed by `keyp' is set to the actual key and the variable pointed by `value' is set to the corresponding entry. (This allows the freeing of the associated storage.) If the entry is not found, then 0 is returned and nothing is changed. +

          + +

          Side Effects None +

          + +

          See Also st_delete_int + + +
          +int 
          +st_find_or_add(
          +  st_table * table, 
          +  void * key, 
          +  void * slot 
          +)
          +
          +
          Lookup `key' in `table'. If not found, create an entry. In either case set slot to point to the field in the entry where the value is stored. The value associated with `key' may then be changed by accessing directly through slot. Returns 1 if an entry already existed, 0 if it did not exist and creation was successful; ST_OUT_OF_MEM otherwise. As an example:
           char **slot; 
           char *key; 
           char *value = (char *) item_ptr <-- ptr to a malloc'd structure 
           if (st_find_or_add(table, key, &slot) == 1) { 
           FREE(*slot); <-- free the old value of the record 
           } 
           *slot = value; <-- attach the new value to the record 
          This replaces the equivelent code:
           if (st_lookup(table, key, &ovalue) == 1) { 
           FREE(ovalue); 
           } 
           st_insert(table, key, value); 
          +

          + +

          Side Effects None +

          + +

          See Also st_find + + +
          +int 
          +st_find(
          +  st_table * table, 
          +  void * key, 
          +  void * slot 
          +)
          +
          +
          Like st_find_or_add, but does not create an entry if one is not found. +

          + +

          Side Effects None +

          + +

          See Also st_find_or_add + + +
          + 
          +st_foreach_item_int(
          +   table, 
          +   gen, 
          +   key, 
          +   value 
          +)
          +
          +
          An iteration macro which loops over all the entries in `table', setting `key' to point to the key and `value' to the associated value (if it is not nil). `value' is assumed to be a pointer to an integer. `gen' is a generator variable used internally. Sample usage:
           char *key; 
           int value; 
           st_generator *gen; 
           st_foreach_item_int(table, gen, &key, &value) { 
           process_item(value); 
           } 
          +

          + +

          Side Effects None +

          + +

          See Also st_foreach_item +st_foreach + + +
          + 
          +st_foreach_item(
          +   table, 
          +   gen, 
          +   key, 
          +   value 
          +)
          +
          +
          An iteration macro which loops over all the entries in `table', setting `key' to point to the key and `value' to the associated value (if it is not nil). `gen' is a generator variable used internally. Sample usage:
           char *key, *value; 
           st_generator *gen; 
           st_foreach_item(table, gen, &key, &value) { 
           process_item(value); 
           } 
          +

          + +

          Side Effects None +

          + +

          See Also st_foreach_item_int +st_foreach + + +
          +int 
          +st_foreach(
          +  st_table * table, 
          +  ST_PFSR  func, 
          +  char * arg 
          +)
          +
          +
          For each (key, value) record in `table', st_foreach call func with the arguments
           (*func)(key, value, arg) 
          If func returns ST_CONTINUE, st_foreach continues processing entries. If func returns ST_STOP, st_foreach stops processing and returns immediately. If func returns ST_DELETE, then the entry is deleted from the symbol table and st_foreach continues. In the case of ST_DELETE, it is func's responsibility to free the key and value, if necessary.

          The routine returns 1 if all items in the table were generated and 0 if the generation sequence was aborted using ST_STOP. The order in which the records are visited will be seemingly random. +

          + +

          Side Effects None +

          + +

          See Also st_foreach_item +st_foreach_item_int + + +
          +void 
          +st_free_gen(
          +  st_generator * gen 
          +)
          +
          +
          After generating all items in a generation sequence, this routine must be called to reclaim the resources associated with `gen'. +

          + +

          Side Effects None +

          + +

          See Also st_init_gen + + +
          +void 
          +st_free_table(
          +  st_table * table 
          +)
          +
          +
          Any internal storage associated with table is freed. It is the user's responsibility to free any storage associated with the pointers he placed in the table (by perhaps using st_foreach). +

          + +

          Side Effects None +

          + +

          See Also st_init_table +st_init_table_with_params + + +
          +int 
          +st_gen_int(
          +  st_generator * gen, 
          +  void * key_p, 
          +  int * value_p 
          +)
          +
          +
          Given a generator returned by st_init_gen(), this routine returns the next (key, value) pair in the generation sequence. `value_p' must be a pointer to an integer. The pointer `value_p' can be zero which means no value will be returned. When there are no more items in the generation sequence, the routine returns 0. +

          + +

          Side Effects None +

          + +

          See Also st_gen + + +
          +int 
          +st_gen(
          +  st_generator * gen, 
          +  void * key_p, 
          +  void * value_p 
          +)
          +
          +
          Given a generator returned by st_init_gen(), this routine returns the next (key, value) pair in the generation sequence. The pointer `value_p' can be zero which means no value will be returned. When there are no more items in the generation sequence, the routine returns 0. While using a generation sequence, deleting any (key, value) pair other than the one just generated may cause a fatal error when st_gen() is called later in the sequence and is therefore not recommended. +

          + +

          Side Effects None +

          + +

          See Also st_gen_int + + +
          +st_generator * 
          +st_init_gen(
          +  st_table * table 
          +)
          +
          +
          Returns a generator handle which when used with st_gen() will progressively return each (key, value) record in `table'. +

          + +

          Side Effects None +

          + +

          See Also st_free_gen + + +
          +st_table * 
          +st_init_table_with_params(
          +  ST_PFICPCP  compare, 
          +  ST_PFICPI  hash, 
          +  int  size, 
          +  int  density, 
          +  double  grow_factor, 
          +  int  reorder_flag 
          +)
          +
          +
          The full blown table initializer. compare and hash are the same as in st_init_table. density is the largest the average number of entries per hash bin there should be before the table is grown. grow_factor is the factor the table is grown by when it becomes too full. size is the initial number of bins to be allocated for the hash table. If reorder_flag is non-zero, then every time an entry is found, it is moved to the top of the chain.

          st_init_table(compare, hash) is equivelent to

           st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE, ST_DEFAULT_MAX_DENSITY, ST_DEFAULT_GROW_FACTOR, ST_DEFAULT_REORDER_FLAG); 
          +

          + +

          Side Effects None +

          + +

          See Also st_init_table +st_free_table + + +
          +st_table * 
          +st_init_table(
          +  ST_PFICPCP  compare, 
          +  ST_PFICPI  hash 
          +)
          +
          +
          Create and initialize a table with the comparison function compare_fn and hash function hash_fn. compare_fn is
           int compare_fn(const char *key1, const char *key2) 
          It returns <,=,> 0 depending on whether key1 <,=,> key2 by some measure.

          hash_fn is

           int hash_fn(char *key, int modulus) 
          It returns a integer between 0 and modulus-1 such that if compare_fn(key1,key2) == 0 then hash_fn(key1) == hash_fn(key2).

          There are five predefined hash and comparison functions in st. For keys as numbers:

           st_numhash(key, modulus) { return (unsigned int) key % modulus; } 
           st_numcmp(x,y) { return (int) x - (int) y; } 
          For keys as pointers:
           st_ptrhash(key, modulus) { return ((unsigned int) key/4) % modulus } 
           st_ptrcmp(x,y) { return (int) x - (int) y; } 
          For keys as strings:
           st_strhash(x,y) - a reasonable hashing function for strings 
           strcmp(x,y) - the standard library function 
          It is recommended to use these particular functions if they fit your needs, since st will recognize certain of them and run more quickly because of it. +

          + +

          Side Effects None +

          + +

          See Also st_init_table_with_params +st_free_table + + +
          +int 
          +st_insert(
          +  st_table * table, 
          +  void * key, 
          +  void * value 
          +)
          +
          +
          Insert value in table under the key 'key'. Returns 1 if there was an entry already under the key; 0 if there was no entry under the key and insertion was successful; ST_OUT_OF_MEM otherwise. In either of the first two cases the new value is added. +

          + +

          Side Effects None +

          + +

          + 
          +st_is_member(
          +   table, 
          +   key 
          +)
          +
          +
          Returns 1 if there is an entry under `key' in `table', 0 otherwise. +

          + +

          Side Effects None +

          + +

          See Also st_lookup + + +
          +int 
          +st_lookup_int(
          +  st_table * table, 
          +  void * key, 
          +  int * value 
          +)
          +
          +
          Lookup up `key' in `table'. If an entry is found, 1 is returned and if `value' is not nil, the variable it points to is set to the associated integer value. If an entry is not found, 0 is return and the variable pointed by `value' is unchanged. +

          + +

          Side Effects None +

          + +

          See Also st_lookup + + +
          +int 
          +st_lookup(
          +  st_table * table, 
          +  void * key, 
          +  void * value 
          +)
          +
          +
          Lookup up `key' in `table'. If an entry is found, 1 is returned and if `value' is not nil, the variable it points to is set to the associated value. If an entry is not found, 0 is returned and the variable pointed by value is unchanged. +

          + +

          Side Effects None +

          + +

          See Also st_lookup_int + + +
          +int 
          +st_numcmp(
          +  const char * x, 
          +  const char * y 
          +)
          +
          +
          integer number comparison function. +

          + +

          Side Effects None +

          + +

          See Also st_init_table +st_numhash + + +
          +int 
          +st_numhash(
          +  char * x, 
          +  int  size 
          +)
          +
          +
          Integer number hash function. +

          + +

          Side Effects None +

          + +

          See Also st_init_table +st_numcmp + + +
          +int 
          +st_ptrcmp(
          +  const char * x, 
          +  const char * y 
          +)
          +
          +
          Pointer comparison function. +

          + +

          Side Effects None +

          + +

          See Also st_init_table +st_ptrhash + + +
          +int 
          +st_ptrhash(
          +  char * x, 
          +  int  size 
          +)
          +
          +
          Pointer hash function. +

          + +

          Side Effects None +

          + +

          See Also st_init_table +st_ptrcmp + + +
          +int 
          +st_strhash(
          +  char * string, 
          +  int  modulus 
          +)
          +
          +
          String hash function. +

          + +

          Side Effects None +

          + +

          See Also st_init_table + + + +
          + +
          + +Generated automatically by extdoc on 20040102 + + diff --git a/resources/3rdparty/cudd-2.5.0/st/st.c b/resources/3rdparty/cudd-2.5.0/st/st.c new file mode 100644 index 000000000..dd76fa591 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/st.c @@ -0,0 +1,1065 @@ +/**CFile*********************************************************************** + + FileName [st.c] + + PackageName [st] + + Synopsis [Symbol table package.] + + Description [The st library provides functions to create, maintain, + and query symbol tables.] + + SeeAlso [] + + Author [] + + Copyright [] + +******************************************************************************/ + +#include "util.h" +#include "st.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = " $Id: st.c,v 1.12 2010/04/22 19:00:55 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define ST_NUMCMP(x,y) ((x) != (y)) + +#define ST_NUMHASH(x,size) ((unsigned long)(x)%(size)) + +#if SIZEOF_VOID_P == 8 +#define st_shift 3 +#else +#define st_shift 2 +#endif + +#define ST_PTRHASH(x,size) ((unsigned int)((unsigned long)(x)>>st_shift)%size) + +#define EQUAL(func, x, y) \ + ((((func) == st_numcmp) || ((func) == st_ptrcmp)) ?\ + (ST_NUMCMP((x),(y)) == 0) : ((*func)((x), (y)) == 0)) + +#define do_hash(key, table)\ + ((int)((table->hash == st_ptrhash) ? ST_PTRHASH((char *)(key),(table)->num_bins) :\ + (table->hash == st_numhash) ? ST_NUMHASH((char *)(key), (table)->num_bins) :\ + (*table->hash)((char *)(key), (table)->num_bins))) + +#define PTR_NOT_EQUAL(table, ptr, user_key)\ +(ptr != NIL(st_table_entry) && !EQUAL(table->compare, (char *)user_key, (ptr)->key)) + +#define FIND_ENTRY(table, hash_val, key, ptr, last) \ + (last) = &(table)->bins[hash_val];\ + (ptr) = *(last);\ + while (PTR_NOT_EQUAL((table), (ptr), (key))) {\ + (last) = &(ptr)->next; (ptr) = *(last);\ + }\ + if ((ptr) != NIL(st_table_entry) && (table)->reorder_flag) {\ + *(last) = (ptr)->next;\ + (ptr)->next = (table)->bins[hash_val];\ + (table)->bins[hash_val] = (ptr);\ + } + +/* This macro does not check if memory allocation fails. Use at you own risk */ +#define ADD_DIRECT(table, key, value, hash_val, newt)\ +{\ + if (table->num_entries/table->num_bins >= table->max_density) {\ + rehash(table);\ + hash_val = do_hash(key,table);\ + }\ + \ + newt = ALLOC(st_table_entry, 1);\ + \ + newt->key = (char *)key;\ + newt->record = value;\ + newt->next = table->bins[hash_val];\ + table->bins[hash_val] = newt;\ + table->num_entries++;\ +} + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int rehash (st_table *); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Create and initialize a table.] + + Description [Create and initialize a table with the comparison function + compare_fn and hash function hash_fn. compare_fn is +
          +	int compare_fn(const char *key1, const char *key2)
          +  
          + It returns <,=,> 0 depending on whether key1 <,=,> key2 by some measure.

          + hash_fn is +

          +	int hash_fn(char *key, int modulus)
          +  
          + It returns a integer between 0 and modulus-1 such that if + compare_fn(key1,key2) == 0 then hash_fn(key1) == hash_fn(key2).

          + There are five predefined hash and comparison functions in st. + For keys as numbers: +

          +	 st_numhash(key, modulus) { return (unsigned int) key % modulus; }
          +  
          +
          +	 st_numcmp(x,y) { return (int) x - (int) y; }
          +  
          + For keys as pointers: +
          +	 st_ptrhash(key, modulus) { return ((unsigned int) key/4) % modulus }
          +  
          +
          +	 st_ptrcmp(x,y) { return (int) x - (int) y; }
          +  
          + For keys as strings: +
          +         st_strhash(x,y) - a reasonable hashing function for strings
          +  
          +
          +	 strcmp(x,y) - the standard library function
          +  
          + It is recommended to use these particular functions if they fit your + needs, since st will recognize certain of them and run more quickly + because of it.] + + SideEffects [None] + + SeeAlso [st_init_table_with_params st_free_table] + +******************************************************************************/ +st_table * +st_init_table(ST_PFICPCP compare, ST_PFICPI hash) +{ + return st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE, + ST_DEFAULT_MAX_DENSITY, + ST_DEFAULT_GROW_FACTOR, + ST_DEFAULT_REORDER_FLAG); + +} /* st_init_table */ + + +/**Function******************************************************************** + + Synopsis [Create a table with given parameters.] + + Description [The full blown table initializer. compare and hash are + the same as in st_init_table. density is the largest the average + number of entries per hash bin there should be before the table is + grown. grow_factor is the factor the table is grown by when it + becomes too full. size is the initial number of bins to be allocated + for the hash table. If reorder_flag is non-zero, then every time an + entry is found, it is moved to the top of the chain.

          + st_init_table(compare, hash) is equivelent to +

          +  st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE,
          +			    ST_DEFAULT_MAX_DENSITY,
          +			    ST_DEFAULT_GROW_FACTOR,
          +			    ST_DEFAULT_REORDER_FLAG);
          +  
          + ] + + SideEffects [None] + + SeeAlso [st_init_table st_free_table] + +******************************************************************************/ +st_table * +st_init_table_with_params( + ST_PFICPCP compare, + ST_PFICPI hash, + int size, + int density, + double grow_factor, + int reorder_flag) +{ + int i; + st_table *newt; + + newt = ALLOC(st_table, 1); + if (newt == NIL(st_table)) { + return NIL(st_table); + } + newt->compare = compare; + newt->hash = hash; + newt->num_entries = 0; + newt->max_density = density; + newt->grow_factor = grow_factor; + newt->reorder_flag = reorder_flag; + if (size <= 0) { + size = 1; + } + newt->num_bins = size; + newt->bins = ALLOC(st_table_entry *, size); + if (newt->bins == NIL(st_table_entry *)) { + FREE(newt); + return NIL(st_table); + } + for(i = 0; i < size; i++) { + newt->bins[i] = 0; + } + return newt; + +} /* st_init_table_with_params */ + + +/**Function******************************************************************** + + Synopsis [Free a table.] + + Description [Any internal storage associated with table is freed. + It is the user's responsibility to free any storage associated + with the pointers he placed in the table (by perhaps using + st_foreach).] + + SideEffects [None] + + SeeAlso [st_init_table st_init_table_with_params] + +******************************************************************************/ +void +st_free_table(st_table *table) +{ + st_table_entry *ptr, *next; + int i; + + for(i = 0; i < table->num_bins ; i++) { + ptr = table->bins[i]; + while (ptr != NIL(st_table_entry)) { + next = ptr->next; + FREE(ptr); + ptr = next; + } + } + FREE(table->bins); + FREE(table); + +} /* st_free_table */ + + +/**Function******************************************************************** + + Synopsis [Lookup up `key' in `table'.] + + Description [Lookup up `key' in `table'. If an entry is found, 1 is + returned and if `value' is not nil, the variable it points to is set + to the associated value. If an entry is not found, 0 is returned + and the variable pointed by value is unchanged.] + + SideEffects [None] + + SeeAlso [st_lookup_int] + +******************************************************************************/ +int +st_lookup(st_table *table, void *key, void *value) +{ + int hash_val; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (value != NIL(void)) { + *(char **)value = ptr->record; + } + return 1; + } + +} /* st_lookup */ + + +/**Function******************************************************************** + + Synopsis [Lookup up `key' in `table'.] + + Description [Lookup up `key' in `table'. If an entry is found, 1 is + returned and if `value' is not nil, the variable it points to is + set to the associated integer value. If an entry is not found, 0 is + return and the variable pointed by `value' is unchanged.] + + SideEffects [None] + + SeeAlso [st_lookup] + +******************************************************************************/ +int +st_lookup_int(st_table *table, void *key, int *value) +{ + int hash_val; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (value != NIL(int)) { + *value = (int) (long) ptr->record; + } + return 1; + } + +} /* st_lookup_int */ + + +/**Function******************************************************************** + + Synopsis [Insert value in table under the key 'key'.] + + Description [Insert value in table under the key 'key'. Returns 1 + if there was an entry already under the key; 0 if there was no entry + under the key and insertion was successful; ST_OUT_OF_MEM otherwise. + In either of the first two cases the new value is added.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +st_insert(st_table *table, void *key, void *value) +{ + int hash_val; + st_table_entry *newt; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + if (table->num_entries/table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + hash_val = do_hash(key, table); + } + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = (char *)key; + newt->record = (char *)value; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + return 0; + } else { + ptr->record = (char *)value; + return 1; + } + +} /* st_insert */ + + +/**Function******************************************************************** + + Synopsis [Place 'value' in 'table' under the key 'key'.] + + Description [Place 'value' in 'table' under the key 'key'. This is + done without checking if 'key' is in 'table' already. This should + only be used if you are sure there is not already an entry for + 'key', since it is undefined which entry you would later get from + st_lookup or st_find_or_add. Returns 1 if successful; ST_OUT_OF_MEM + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +st_add_direct(st_table *table, void *key, void *value) +{ + int hash_val; + st_table_entry *newt; + + hash_val = do_hash(key, table); + if (table->num_entries / table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + } + hash_val = do_hash(key, table); + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = (char *)key; + newt->record = (char *)value; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + return 1; + +} /* st_add_direct */ + + +/**Function******************************************************************** + + Synopsis [Lookup `key' in `table'.] + + Description [Lookup `key' in `table'. If not found, create an + entry. In either case set slot to point to the field in the entry + where the value is stored. The value associated with `key' may then + be changed by accessing directly through slot. Returns 1 if an + entry already existed, 0 if it did not exist and creation was + successful; ST_OUT_OF_MEM otherwise. As an example: +
          +      char **slot;
          +  
          +
          +      char *key;
          +  
          +
          +      char *value = (char *) item_ptr <-- ptr to a malloc'd structure
          +  
          +
          +      if (st_find_or_add(table, key, &slot) == 1) {
          +  
          +
          +	 FREE(*slot); <-- free the old value of the record
          +  
          +
          +      }
          +  
          +
          +      *slot = value;  <-- attach the new value to the record
          +  
          + This replaces the equivelent code: +
          +      if (st_lookup(table, key, &ovalue) == 1) {
          +  
          +
          +         FREE(ovalue);
          +  
          +
          +      }
          +  
          +
          +      st_insert(table, key, value);
          +  
          + ] + + SideEffects [None] + + SeeAlso [st_find] + +******************************************************************************/ +int +st_find_or_add(st_table *table, void *key, void *slot) +{ + int hash_val; + st_table_entry *newt, *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + if (table->num_entries / table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + hash_val = do_hash(key, table); + } + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = (char *)key; + newt->record = (char *) 0; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + if (slot != NIL(void)) *(char ***)slot = &newt->record; + return 0; + } else { + if (slot != NIL(void)) *(char ***)slot = &ptr->record; + return 1; + } + +} /* st_find_or_add */ + + +/**Function******************************************************************** + + Synopsis [Lookup `key' in `table'.] + + Description [Like st_find_or_add, but does not create an entry if + one is not found.] + + SideEffects [None] + + SeeAlso [st_find_or_add] + +******************************************************************************/ +int +st_find(st_table *table, void *key, void *slot) +{ + int hash_val; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (slot != NIL(void)) { + *(char ***)slot = &ptr->record; + } + return 1; + } + +} /* st_find */ + + +/**Function******************************************************************** + + Synopsis [Return a copy of old_table and all its members.] + + Description [Return a copy of old_table and all its members. + (st_table *) 0 is returned if there was insufficient memory to do + the copy.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +st_table * +st_copy(st_table *old_table) +{ + st_table *new_table; + st_table_entry *ptr, *newptr, *next, *newt; + int i, j, num_bins = old_table->num_bins; + + new_table = ALLOC(st_table, 1); + if (new_table == NIL(st_table)) { + return NIL(st_table); + } + + *new_table = *old_table; + new_table->bins = ALLOC(st_table_entry *, num_bins); + if (new_table->bins == NIL(st_table_entry *)) { + FREE(new_table); + return NIL(st_table); + } + for(i = 0; i < num_bins ; i++) { + new_table->bins[i] = NIL(st_table_entry); + ptr = old_table->bins[i]; + while (ptr != NIL(st_table_entry)) { + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + for (j = 0; j <= i; j++) { + newptr = new_table->bins[j]; + while (newptr != NIL(st_table_entry)) { + next = newptr->next; + FREE(newptr); + newptr = next; + } + } + FREE(new_table->bins); + FREE(new_table); + return NIL(st_table); + } + *newt = *ptr; + newt->next = new_table->bins[i]; + new_table->bins[i] = newt; + ptr = ptr->next; + } + } + return new_table; + +} /* st_copy */ + + +/**Function******************************************************************** + + Synopsis [Delete the entry with the key pointed to by `keyp'.] + + Description [Delete the entry with the key pointed to by `keyp'. If + the entry is found, 1 is returned, the variable pointed by `keyp' is + set to the actual key and the variable pointed by `value' is set to + the corresponding entry. (This allows the freeing of the associated + storage.) If the entry is not found, then 0 is returned and nothing + is changed.] + + SideEffects [None] + + SeeAlso [st_delete_int] + +******************************************************************************/ +int +st_delete(st_table *table, void *keyp, void *value) +{ + int hash_val; + char *key = *(char **)keyp; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr ,last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } + + *last = ptr->next; + if (value != NIL(void)) *(char **)value = ptr->record; + *(char **)keyp = ptr->key; + FREE(ptr); + table->num_entries--; + return 1; + +} /* st_delete */ + + +/**Function******************************************************************** + + Synopsis [Delete the entry with the key pointed to by `keyp'.] + + Description [Delete the entry with the key pointed to by `keyp'. + `value' must be a pointer to an integer. If the entry is found, 1 + is returned, the variable pointed by `keyp' is set to the actual key + and the variable pointed by `value' is set to the corresponding + entry. (This allows the freeing of the associated storage.) If the + entry is not found, then 0 is returned and nothing is changed.] + + SideEffects [None] + + SeeAlso [st_delete] + +******************************************************************************/ +int +st_delete_int(st_table *table, void *keyp, int *value) +{ + int hash_val; + char *key = *(char **)keyp; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr ,last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } + + *last = ptr->next; + if (value != NIL(int)) *value = (int) (long) ptr->record; + *(char **)keyp = ptr->key; + FREE(ptr); + table->num_entries--; + return 1; + +} /* st_delete_int */ + + +/**Function******************************************************************** + + Synopsis [Iterates over the elements of a table.] + + Description [For each (key, value) record in `table', st_foreach + call func with the arguments +
          +	  (*func)(key, value, arg)
          +  
          + If func returns ST_CONTINUE, st_foreach continues processing + entries. If func returns ST_STOP, st_foreach stops processing and + returns immediately. If func returns ST_DELETE, then the entry is + deleted from the symbol table and st_foreach continues. In the case + of ST_DELETE, it is func's responsibility to free the key and value, + if necessary.

          + + The routine returns 1 if all items in the table were generated and 0 + if the generation sequence was aborted using ST_STOP. The order in + which the records are visited will be seemingly random.] + + SideEffects [None] + + SeeAlso [st_foreach_item st_foreach_item_int] + +******************************************************************************/ +int +st_foreach(st_table *table, ST_PFSR func, char *arg) +{ + st_table_entry *ptr, **last; + enum st_retval retval; + int i; + + for(i = 0; i < table->num_bins; i++) { + last = &table->bins[i]; ptr = *last; + while (ptr != NIL(st_table_entry)) { + retval = (*func)(ptr->key, ptr->record, arg); + switch (retval) { + case ST_CONTINUE: + last = &ptr->next; ptr = *last; + break; + case ST_STOP: + return 0; + case ST_DELETE: + *last = ptr->next; + table->num_entries--; /* cstevens@ic */ + FREE(ptr); + ptr = *last; + } + } + } + return 1; + +} /* st_foreach */ + + +/**Function******************************************************************** + + Synopsis [String hash function.] + + Description [String hash function.] + + SideEffects [None] + + SeeAlso [st_init_table] + +******************************************************************************/ +int +st_strhash(char *string, int modulus) +{ + int val = 0; + int c; + + while ((c = *string++) != '\0') { + val = val*997 + c; + } + + return ((val < 0) ? -val : val)%modulus; + +} /* st_strhash */ + + +/**Function******************************************************************** + + Synopsis [Number hash function.] + + Description [Integer number hash function.] + + SideEffects [None] + + SeeAlso [st_init_table st_numcmp] + +******************************************************************************/ +int +st_numhash(char *x, int size) +{ + return ST_NUMHASH(x, size); + +} /* st_numhash */ + + +/**Function******************************************************************** + + Synopsis [Pointer hash function.] + + Description [Pointer hash function.] + + SideEffects [None] + + SeeAlso [st_init_table st_ptrcmp] + +******************************************************************************/ +int +st_ptrhash(char *x, int size) +{ + return ST_PTRHASH(x, size); + +} /* st_ptrhash */ + + +/**Function******************************************************************** + + Synopsis [Number comparison function.] + + Description [integer number comparison function.] + + SideEffects [None] + + SeeAlso [st_init_table st_numhash] + +******************************************************************************/ +int +st_numcmp(const char *x, const char *y) +{ + return ST_NUMCMP(x, y); + +} /* st_numcmp */ + + +/**Function******************************************************************** + + Synopsis [Pointer comparison function.] + + Description [Pointer comparison function.] + + SideEffects [None] + + SeeAlso [st_init_table st_ptrhash] + +******************************************************************************/ +int +st_ptrcmp(const char *x, const char *y) +{ + return ST_NUMCMP(x, y); + +} /* st_ptrcmp */ + + +/**Function******************************************************************** + + Synopsis [Initializes a generator.] + + Description [Returns a generator handle which when used with + st_gen() will progressively return each (key, value) record in + `table'.] + + SideEffects [None] + + SeeAlso [st_free_gen] + +******************************************************************************/ +st_generator * +st_init_gen(st_table *table) +{ + st_generator *gen; + + gen = ALLOC(st_generator, 1); + if (gen == NIL(st_generator)) { + return NIL(st_generator); + } + gen->table = table; + gen->entry = NIL(st_table_entry); + gen->index = 0; + return gen; + +} /* st_init_gen */ + + +/**Function******************************************************************** + + Synopsis [returns the next (key, value) pair in the generation + sequence. ] + + Description [Given a generator returned by st_init_gen(), this + routine returns the next (key, value) pair in the generation + sequence. The pointer `value_p' can be zero which means no value + will be returned. When there are no more items in the generation + sequence, the routine returns 0. + + While using a generation sequence, deleting any (key, value) pair + other than the one just generated may cause a fatal error when + st_gen() is called later in the sequence and is therefore not + recommended.] + + SideEffects [None] + + SeeAlso [st_gen_int] + +******************************************************************************/ +int +st_gen(st_generator *gen, void *key_p, void *value_p) +{ + int i; + + if (gen->entry == NIL(st_table_entry)) { + /* try to find next entry */ + for(i = gen->index; i < gen->table->num_bins; i++) { + if (gen->table->bins[i] != NIL(st_table_entry)) { + gen->index = i+1; + gen->entry = gen->table->bins[i]; + break; + } + } + if (gen->entry == NIL(st_table_entry)) { + return 0; /* that's all folks ! */ + } + } + *(char **)key_p = gen->entry->key; + if (value_p != NIL(void)) { + *(char **)value_p = gen->entry->record; + } + gen->entry = gen->entry->next; + return 1; + +} /* st_gen */ + + +/**Function******************************************************************** + + Synopsis [Returns the next (key, value) pair in the generation + sequence.] + + Description [Given a generator returned by st_init_gen(), this + routine returns the next (key, value) pair in the generation + sequence. `value_p' must be a pointer to an integer. The pointer + `value_p' can be zero which means no value will be returned. When + there are no more items in the generation sequence, the routine + returns 0.] + + SideEffects [None] + + SeeAlso [st_gen] + +******************************************************************************/ +int +st_gen_int(st_generator *gen, void *key_p, int *value_p) +{ + int i; + + if (gen->entry == NIL(st_table_entry)) { + /* try to find next entry */ + for(i = gen->index; i < gen->table->num_bins; i++) { + if (gen->table->bins[i] != NIL(st_table_entry)) { + gen->index = i+1; + gen->entry = gen->table->bins[i]; + break; + } + } + if (gen->entry == NIL(st_table_entry)) { + return 0; /* that's all folks ! */ + } + } + *(char **)key_p = gen->entry->key; + if (value_p != NIL(int)) { + *value_p = (int) (long) gen->entry->record; + } + gen->entry = gen->entry->next; + return 1; + +} /* st_gen_int */ + + +/**Function******************************************************************** + + Synopsis [Reclaims the resources associated with `gen'.] + + Description [After generating all items in a generation sequence, + this routine must be called to reclaim the resources associated with + `gen'.] + + SideEffects [None] + + SeeAlso [st_init_gen] + +******************************************************************************/ +void +st_free_gen(st_generator *gen) +{ + FREE(gen); + +} /* st_free_gen */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Rehashes a symbol table.] + + Description [Rehashes a symbol table.] + + SideEffects [None] + + SeeAlso [st_insert] + +******************************************************************************/ +static int +rehash(st_table *table) +{ + st_table_entry *ptr, *next, **old_bins; + int i, old_num_bins, hash_val, old_num_entries; + + /* save old values */ + old_bins = table->bins; + old_num_bins = table->num_bins; + old_num_entries = table->num_entries; + + /* rehash */ + table->num_bins = (int) (table->grow_factor * old_num_bins); + if (table->num_bins % 2 == 0) { + table->num_bins += 1; + } + table->num_entries = 0; + table->bins = ALLOC(st_table_entry *, table->num_bins); + if (table->bins == NIL(st_table_entry *)) { + table->bins = old_bins; + table->num_bins = old_num_bins; + table->num_entries = old_num_entries; + return ST_OUT_OF_MEM; + } + /* initialize */ + for (i = 0; i < table->num_bins; i++) { + table->bins[i] = 0; + } + + /* copy data over */ + for (i = 0; i < old_num_bins; i++) { + ptr = old_bins[i]; + while (ptr != NIL(st_table_entry)) { + next = ptr->next; + hash_val = do_hash(ptr->key, table); + ptr->next = table->bins[hash_val]; + table->bins[hash_val] = ptr; + table->num_entries++; + ptr = next; + } + } + FREE(old_bins); + + return 1; + +} /* rehash */ diff --git a/resources/3rdparty/cudd-2.5.0/st/st.h b/resources/3rdparty/cudd-2.5.0/st/st.h new file mode 100644 index 000000000..dbb14bbeb --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/st.h @@ -0,0 +1,232 @@ +/**CHeaderFile***************************************************************** + + FileName [st.h] + + PackageName [st] + + Synopsis [Symbol table package.] + + Description [The st library provides functions to create, maintain, + and query symbol tables.] + + SeeAlso [] + + Author [] + + Copyright [] + + Revision [$Id: st.h,v 1.10 2004/01/02 07:40:31 fabio Exp fabio $] + +******************************************************************************/ + +#ifndef ST_INCLUDED +#define ST_INCLUDED + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define ST_DEFAULT_MAX_DENSITY 5 +#define ST_DEFAULT_INIT_TABLE_SIZE 11 +#define ST_DEFAULT_GROW_FACTOR 2.0 +#define ST_DEFAULT_REORDER_FLAG 0 +#define ST_OUT_OF_MEM -10000 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct st_table_entry st_table_entry; +struct st_table_entry { + char *key; + char *record; + st_table_entry *next; +}; + +typedef struct st_table st_table; +struct st_table { + int (*compare)(const char *, const char *); + int (*hash)(char *, int); + int num_bins; + int num_entries; + int max_density; + int reorder_flag; + double grow_factor; + st_table_entry **bins; +}; + +typedef struct st_generator st_generator; +struct st_generator { + st_table *table; + st_table_entry *entry; + int index; +}; + +enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE}; + +typedef enum st_retval (*ST_PFSR)(char *, char *, char *); + +typedef int (*ST_PFICPCP)(const char *, const char *); /* type for comparison function */ + +typedef int (*ST_PFICPI)(char *, int); /* type for hash function */ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Checks whethere `key' is in `table'.] + + Description [Returns 1 if there is an entry under `key' in `table', 0 + otherwise.] + + SideEffects [None] + + SeeAlso [st_lookup] + +******************************************************************************/ +#define st_is_member(table,key) st_lookup(table,key,(char **) 0) + + +/**Macro*********************************************************************** + + Synopsis [Returns the number of entries in the table `table'.] + + Description [Returns the number of entries in the table `table'.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +#define st_count(table) ((table)->num_entries) + + +/**Macro*********************************************************************** + + Synopsis [Iteration macro.] + + Description [An iteration macro which loops over all the entries in + `table', setting `key' to point to the key and `value' to the + associated value (if it is not nil). `gen' is a generator variable + used internally. Sample usage: +

          +     	char *key, *value;
          +  
          +
          +	st_generator *gen;
          +  
          +
          +
          +	st_foreach_item(table, gen, &key, &value) {
          +  
          +
          +	    process_item(value);
          +  
          +
          +	}
          +  
          + ] + + SideEffects [None] + + SeeAlso [st_foreach_item_int st_foreach] + +******************************************************************************/ +#define st_foreach_item(table, gen, key, value) \ + for(gen=st_init_gen(table); st_gen(gen,key,value) || (st_free_gen(gen),0);) + + +/**Macro*********************************************************************** + + Synopsis [Iteration macro.] + + Description [An iteration macro which loops over all the entries in + `table', setting `key' to point to the key and `value' to the + associated value (if it is not nil). `value' is assumed to be a + pointer to an integer. `gen' is a generator variable used + internally. Sample usage: +
          +     	char *key;
          +  
          +
          +	int value;
          +  
          +
          +	st_generator *gen;
          +  
          +
          +
          +	st_foreach_item_int(table, gen, &key, &value) {
          +  
          +
          +	    process_item(value);
          +  
          +
          +	}
          +  
          + ] + + SideEffects [None] + + SeeAlso [st_foreach_item st_foreach] + +******************************************************************************/ +#define st_foreach_item_int(table, gen, key, value) \ + for(gen=st_init_gen(table); st_gen_int(gen,key,value) || (st_free_gen(gen),0);) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern st_table *st_init_table_with_params (ST_PFICPCP, ST_PFICPI, int, int, double, int); +extern st_table *st_init_table (ST_PFICPCP, ST_PFICPI); +extern void st_free_table (st_table *); +extern int st_lookup (st_table *, void *, void *); +extern int st_lookup_int (st_table *, void *, int *); +extern int st_insert (st_table *, void *, void *); +extern int st_add_direct (st_table *, void *, void *); +extern int st_find_or_add (st_table *, void *, void *); +extern int st_find (st_table *, void *, void *); +extern st_table *st_copy (st_table *); +extern int st_delete (st_table *, void *, void *); +extern int st_delete_int (st_table *, void *, int *); +extern int st_foreach (st_table *, ST_PFSR, char *); +extern int st_strhash (char *, int); +extern int st_numhash (char *, int); +extern int st_ptrhash (char *, int); +extern int st_numcmp (const char *, const char *); +extern int st_ptrcmp (const char *, const char *); +extern st_generator *st_init_gen (st_table *); +extern int st_gen (st_generator *, void *, void *); +extern int st_gen_int (st_generator *, void *, int *); +extern void st_free_gen (st_generator *); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* ST_INCLUDED */ diff --git a/resources/3rdparty/cudd-2.5.0/util/Makefile b/resources/3rdparty/cudd-2.5.0/util/Makefile new file mode 100644 index 000000000..61543baee --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/Makefile @@ -0,0 +1,64 @@ +# $Id$ +# +# util -- miscellaneous utility routines +#--------------------------------------------------------------------------- +.SUFFIXES: .c .o .u + +CC = gcc +RANLIB = ranlib + +FLAGS = -DUNIX +MFLAG = +ICFLAGS = -g +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) + +LINTFLAGS = -u -n + +# this is to create the lint library +LINTSWITCH = -o + +P = util +PSRC = cpu_time.c cpu_stats.c safe_mem.c strsav.c texpand.c \ + ptime.c prtime.c pipefork.c pathsearch.c stub.c datalimit.c +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +PHDR = util.h + +WHERE = .. +INCLUDE = $(WHERE)/include + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(FLAGS) $(CFLAGS) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PHDR) + cc -j $< -I$(INCLUDE) $(FLAGS) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +clean: + rm -f *.o *.u core *.warnings + +distclean: clean + rm -f lib$(P).a lib$(P).b llib-l$(P).ln tags *.bak *~ .pure diff --git a/resources/3rdparty/cudd-2.5.0/util/cpu_stats.c b/resources/3rdparty/cudd-2.5.0/util/cpu_stats.c new file mode 100644 index 000000000..40117d463 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/cpu_stats.c @@ -0,0 +1,89 @@ +/* LINTLIBRARY */ + +#include "util.h" + + +#ifdef BSD +#include +#include +#include + +#if defined(_IBMR2) +#define etext _etext +#define edata _edata +#define end _end +#endif + +extern int end, etext, edata; + +#endif + +void +util_print_cpu_stats(FILE *fp) +{ +#ifdef BSD + struct rusage rusage; + struct rlimit rlp; + long text, data, vm_limit, vm_soft_limit; + double user, system, scale; + char hostname[257]; + long vm_text, vm_init_data, vm_uninit_data, vm_sbrk_data; + + /* Get the hostname */ + (void) gethostname(hostname, 256); + hostname[256] = '\0'; /* just in case */ + + /* Get the virtual memory sizes */ + vm_text = (long) (((long) (&etext)) / 1024.0 + 0.5); + vm_init_data = (long) (((long) (&edata) - (long) (&etext)) / 1024.0 + 0.5); + vm_uninit_data = (long) (((long) (&end) - (long) (&edata)) / 1024.0 + 0.5); + vm_sbrk_data = (long) (((long) sbrk(0) - (long) (&end)) / 1024.0 + 0.5); + + /* Get virtual memory limits */ + (void) getrlimit(RLIMIT_DATA, &rlp); + vm_limit = (long) (rlp.rlim_max / 1024.0 + 0.5); + vm_soft_limit = (long) (rlp.rlim_cur / 1024.0 + 0.5); + + /* Get usage stats */ + (void) getrusage(RUSAGE_SELF, &rusage); + user = rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec/1.0e6; + system = rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec/1.0e6; + scale = (user + system)*100.0; + if (scale == 0.0) scale = 0.001; + + (void) fprintf(fp, "Runtime Statistics\n"); + (void) fprintf(fp, "------------------\n"); + (void) fprintf(fp, "Machine name: %s\n", hostname); + (void) fprintf(fp, "User time %6.1f seconds\n", user); + (void) fprintf(fp, "System time %6.1f seconds\n\n", system); + + text = (int) (rusage.ru_ixrss / scale + 0.5); + data = (int) ((rusage.ru_idrss + rusage.ru_isrss) / scale + 0.5); + (void) fprintf(fp, "Average resident text size = %5ldK\n", text); + (void) fprintf(fp, "Average resident data+stack size = %5ldK\n", data); + (void) fprintf(fp, "Maximum resident size = %5ldK\n\n", + rusage.ru_maxrss/2); + (void) fprintf(fp, "Virtual text size = %5ldK\n", + vm_text); + (void) fprintf(fp, "Virtual data size = %5ldK\n", + vm_init_data + vm_uninit_data + vm_sbrk_data); + (void) fprintf(fp, " data size initialized = %5ldK\n", + vm_init_data); + (void) fprintf(fp, " data size uninitialized = %5ldK\n", + vm_uninit_data); + (void) fprintf(fp, " data size sbrk = %5ldK\n", + vm_sbrk_data); + (void) fprintf(fp, "Virtual memory limit = %5ldK (%ldK)\n\n", + vm_soft_limit, vm_limit); + + (void) fprintf(fp, "Major page faults = %ld\n", rusage.ru_majflt); + (void) fprintf(fp, "Minor page faults = %ld\n", rusage.ru_minflt); + (void) fprintf(fp, "Swaps = %ld\n", rusage.ru_nswap); + (void) fprintf(fp, "Input blocks = %ld\n", rusage.ru_inblock); + (void) fprintf(fp, "Output blocks = %ld\n", rusage.ru_oublock); + (void) fprintf(fp, "Context switch (voluntary) = %ld\n", rusage.ru_nvcsw); + (void) fprintf(fp, "Context switch (involuntary) = %ld\n", rusage.ru_nivcsw); +#else + (void) fprintf(fp, "Usage statistics not available\n"); +#endif +} diff --git a/resources/3rdparty/cudd-2.5.0/util/cpu_time.c b/resources/3rdparty/cudd-2.5.0/util/cpu_time.c new file mode 100644 index 000000000..2a4be9240 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/cpu_time.c @@ -0,0 +1,76 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + +#ifdef IBM_WATC /* IBM Waterloo-C compiler (same as bsd 4.2) */ +#define void int +#define BSD +#endif + +#ifdef BSD +#include +#include +#include +#endif + +#if defined(UNIX60) || defined(UNIX100) || defined(__CYGWIN32__) +#include +#include +#endif + +#ifdef vms /* VAX/C compiler -- times() with 100 HZ clock */ +#include +#include +#endif + + + +/* + * util_cpu_time -- return a long which represents the elapsed processor + * time in milliseconds since some constant reference + */ +long +util_cpu_time() +{ + long t = 0; + +#ifdef BSD + struct rusage rusage; + (void) getrusage(RUSAGE_SELF, &rusage); + t = (long) rusage.ru_utime.tv_sec*1000 + rusage.ru_utime.tv_usec/1000; +#endif + +#ifdef IBMPC + long ltime; + (void) time(<ime); + t = ltime * 1000; +#endif + +#ifdef UNIX60 /* times() with 60 Hz resolution */ + struct tms buffer; + times(&buffer); + t = buffer.tms_utime * 16.6667; +#endif + +#ifdef UNIX100 + struct tms buffer; /* times() with 100 Hz resolution */ + times(&buffer); + t = buffer.tms_utime * 10; +#endif + +#ifdef __CYGWIN32__ + /* Works under Windows NT but not Windows 95. */ + struct tms buffer; /* times() with 1000 Hz resolution */ + times(&buffer); + t = buffer.tms_utime; +#endif + +#ifdef vms + tbuffer_t buffer; /* times() with 100 Hz resolution */ + times(&buffer); + t = buffer.proc_user_time * 10; +#endif + + return t; +} diff --git a/resources/3rdparty/cudd-2.5.0/util/datalimit.c b/resources/3rdparty/cudd-2.5.0/util/datalimit.c new file mode 100644 index 000000000..f140414d3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/datalimit.c @@ -0,0 +1,50 @@ +/* $Id: datalimit.c,v 1.5 2007/08/24 18:17:31 fabio Exp fabio $ */ + +#ifndef HAVE_SYS_RESOURCE_H +#define HAVE_SYS_RESOURCE_H 1 +#endif +#ifndef HAVE_SYS_TIME_H +#define HAVE_SYS_TIME_H 1 +#endif +#ifndef HAVE_GETRLIMIT +#define HAVE_GETRLIMIT 1 +#endif + +#if HAVE_SYS_RESOURCE_H == 1 +#if HAVE_SYS_TIME_H == 1 +#include +#endif +#include +#endif + +#ifndef RLIMIT_DATA_DEFAULT +#define RLIMIT_DATA_DEFAULT 67108864 /* assume 64MB by default */ +#endif + +#ifndef EXTERN +# ifdef __cplusplus +# define EXTERN extern "C" +# else +# define EXTERN extern +# endif +#endif + +EXTERN unsigned long getSoftDataLimit(void); + +unsigned long +getSoftDataLimit(void) +{ +#if HAVE_SYS_RESOURCE_H == 1 && HAVE_GETRLIMIT == 1 && defined(RLIMIT_DATA) + struct rlimit rl; + int result; + + result = getrlimit(RLIMIT_DATA, &rl); + if (result != 0 || rl.rlim_cur == RLIM_INFINITY) + return((unsigned long) RLIMIT_DATA_DEFAULT); + else + return((unsigned long) rl.rlim_cur); +#else + return((unsigned long) RLIMIT_DATA_DEFAULT); +#endif + +} /* end of getSoftDataLimit */ diff --git a/resources/3rdparty/cudd-2.5.0/util/pathsearch.c b/resources/3rdparty/cudd-2.5.0/util/pathsearch.c new file mode 100644 index 000000000..67c34b868 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/pathsearch.c @@ -0,0 +1,94 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + +static int check_file (char const *, char const *); + +char * +util_path_search(char const *prog) +{ +#ifdef UNIX + return util_file_search(prog, getenv("PATH"), (char *) "x"); +#else + return util_file_search(prog, NIL(char), (char *) "x"); +#endif +} + + +char * +util_file_search( + char const *file, /* file we're looking for */ + char *path, /* search path, colon separated */ + char const *mode /* "r", "w", or "x" */) +{ + int quit; + char *buffer, *filename, *save_path, *cp; + + if (path == 0 || strcmp(path, "") == 0) { + path = (char *) "."; /* just look in the current directory */ + } + + save_path = path = strsav(path); + quit = 0; + do { + cp = strchr(path, ':'); + if (cp != 0) { + *cp = '\0'; + } else { + quit = 1; + } + + /* cons up the filename out of the path and file name */ + if (strcmp(path, ".") == 0) { + buffer = strsav(file); + } else { + buffer = ALLOC(char, strlen(path) + strlen(file) + 4); + (void) sprintf(buffer, "%s/%s", path, file); + } + filename = util_tilde_expand(buffer); + FREE(buffer); + + /* see if we can access it */ + if (check_file(filename, mode)) { + FREE(save_path); + return filename; + } + FREE(filename); + path = ++cp; + } while (! quit); + + FREE(save_path); + return 0; +} + + +static int +check_file(char const *filename, char const *mode) +{ +#ifdef UNIX + int access_mode = /*F_OK*/ 0; + + if (strcmp(mode, "r") == 0) { + access_mode = /*R_OK*/ 4; + } else if (strcmp(mode, "w") == 0) { + access_mode = /*W_OK*/ 2; + } else if (strcmp(mode, "x") == 0) { + access_mode = /*X_OK*/ 1; + } + return access(filename, access_mode) == 0; +#else + FILE *fp; + int got_file; + + if (strcmp(mode, "x") == 0) { + mode = "r"; + } + fp = fopen(filename, mode); + got_file = (fp != 0); + if (fp != 0) { + (void) fclose(fp); + } + return got_file; +#endif +} diff --git a/resources/3rdparty/cudd-2.5.0/util/pipefork.c b/resources/3rdparty/cudd-2.5.0/util/pipefork.c new file mode 100644 index 000000000..ead02d43b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/pipefork.c @@ -0,0 +1,93 @@ +/* + * Revision Control Information + * + * $Id: pipefork.c,v 1.7 2012/02/05 05:34:04 fabio Exp fabio $ + * + */ +/* LINTLIBRARY */ + +#include "util.h" +#include + +/* + * util_pipefork - fork a command and set up pipes to and from + * + * Rick L Spickelmier, 3/23/86 + * Richard Rudell, 4/6/86 + * Rick L Spickelmier, 4/30/90, got rid of slimey vfork semantics + * + * Returns: + * 1 for success, with toCommand and fromCommand pointing to the streams + * 0 for failure + */ + +/* ARGSUSED */ +int +util_pipefork( + char * const *argv, /* normal argv argument list */ + FILE **toCommand, /* pointer to the sending stream */ + FILE **fromCommand, /* pointer to the reading stream */ + int *pid) +{ +#ifdef UNIX + int forkpid, waitPid; + int topipe[2], frompipe[2]; + char buffer[1024]; + int status; + + /* create the PIPES... + * fildes[0] for reading from command + * fildes[1] for writing to command + */ + if (pipe(topipe)) return(0); + if (pipe(frompipe)) return(0); + +#ifdef __CYGWIN32__ + if ((forkpid = fork()) == 0) { +#else + if ((forkpid = vfork()) == 0) { +#endif + /* child here, connect the pipes */ + (void) dup2(topipe[0], fileno(stdin)); + (void) dup2(frompipe[1], fileno(stdout)); + + (void) close(topipe[0]); + (void) close(topipe[1]); + (void) close(frompipe[0]); + (void) close(frompipe[1]); + + (void) execvp(argv[0], argv); + (void) sprintf(buffer, "util_pipefork: can not exec %s", argv[0]); + perror(buffer); + (void) _exit(1); + } + + if (pid) { + *pid = forkpid; + } + +#ifdef __CYGWIN32__ + waitPid = waitpid(-1, &status, WNOHANG); +#else + waitPid = wait3(&status, WNOHANG, NULL); +#endif + + /* parent here, use slimey vfork() semantics to get return status */ + if (waitPid == forkpid && WIFEXITED(status)) { + return 0; + } + if ((*toCommand = fdopen(topipe[1], "w")) == NULL) { + return 0; + } + if ((*fromCommand = fdopen(frompipe[0], "r")) == NULL) { + return 0; + } + (void) close(topipe[0]); + (void) close(frompipe[1]); + return 1; +#else + (void) fprintf(stderr, + "util_pipefork: not implemented on your operating system\n"); + return 0; +#endif +} diff --git a/resources/3rdparty/cudd-2.5.0/util/prtime.c b/resources/3rdparty/cudd-2.5.0/util/prtime.c new file mode 100644 index 000000000..236eafb75 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/prtime.c @@ -0,0 +1,21 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + + +/* + * util_print_time -- massage a long which represents a time interval in + * milliseconds, into a string suitable for output + * + * Hack for IBM/PC -- avoids using floating point + */ + +char * +util_print_time(unsigned long t) +{ + static char s[40]; + + (void) sprintf(s, "%lu.%02lu sec", t/1000, (t%1000)/10); + return s; +} diff --git a/resources/3rdparty/cudd-2.5.0/util/ptime.c b/resources/3rdparty/cudd-2.5.0/util/ptime.c new file mode 100644 index 000000000..4510857be --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/ptime.c @@ -0,0 +1,9 @@ +/* LINTLIBRARY */ +#include "util.h" + +/* backwards compatibility */ +long +ptime() +{ + return util_cpu_time(); +} diff --git a/resources/3rdparty/cudd-2.5.0/util/restart.c b/resources/3rdparty/cudd-2.5.0/util/restart.c new file mode 100644 index 000000000..b81dcb8c8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/restart.c @@ -0,0 +1,137 @@ +#include +#include "util.h" + +#if (defined(sun) && ! defined(sparc)) || defined(vax) + +#include +#include +#include + +static char *save_stack_base; +static char *stack_lo_addr; +static char *stack_hi_addr; +static int stack_size; + +static int restart_global_flag; +static char *old_file_name; +static char *new_file_name; + +char *util_save_sp; /* set by util_restart_save_state() */ +extern char *sbrk(); + +static void +grow_stack() +{ + int i, space[256]; + + for(i = 0; i < 256; i++) { + space[i] = 0; + } + if ((char *) &i > stack_lo_addr) { + grow_stack(); + } +} + + +/* ARGSUSED */ +static int +handle_sigquit(int sig, int code, struct sigcontext *scp) +{ + if (util_restart_save_state()) { + /* we are restarting ! -- return from signal */ + + } else { + /* copy stack to user data space */ + stack_lo_addr = util_save_sp; + stack_size = stack_hi_addr - stack_lo_addr + 1; + save_stack_base = sbrk(stack_size); + (void) memcpy(save_stack_base, stack_lo_addr, stack_size); + + /* write a new executable */ + (void) fprintf(stderr, "Writing executable %s ...\n", new_file_name); + (void) util_save_image(old_file_name, new_file_name); + + /* terminate if signal was a QUIT */ + if (sig == SIGQUIT) { + (void) _exit(1); + } + } +} + + +static void +restart_program() +{ + (void) fprintf(stderr, "Continuing execution ...\n"); + + /* create the stack */ + grow_stack(); + +#ifdef vax + asm("movl _util_save_sp,sp"); +#endif +#ifdef sun + asm("movl _util_save_sp,sp"); +#endif + + /* copy the stack back from user space */ + (void) memcpy(stack_lo_addr, save_stack_base, stack_size); + + /* remove the sbrk for the stack */ + if (sbrk(-stack_size) < 0) { + perror("sbrk"); + } + + util_restart_restore_state(); /* jump back into handle_sigquit() */ +} + +void +util_restart(char const *old, char const *neW, int interval) +{ + struct itimerval itimer; + +#ifdef vax +#ifdef ultrix + stack_hi_addr = (char *) 0x7fffe3ff; /* ultrix */ +#else + stack_hi_addr = (char *) 0x7fffebff; /* bsd 4.3 */ +#endif +#endif +#ifdef sun + stack_hi_addr = (char *) 0x0effffff; /* Sun OS 3.2, 3.4 */ +#endif + + old_file_name = old; + new_file_name = neW; + + (void) signal(SIGQUIT, handle_sigquit); + + if (interval > 0) { + (void) signal(SIGVTALRM, handle_sigquit); + itimer.it_interval.tv_sec = interval; + itimer.it_interval.tv_usec = 0; + itimer.it_value.tv_sec = interval; + itimer.it_value.tv_usec = 0; + if (setitimer(ITIMER_VIRTUAL, &itimer, (struct itimerval *) 0) < 0) { + perror("setitimer"); + exit(1); + } + } + + if (restart_global_flag) { + restart_program(); + } + restart_global_flag = 1; +} + +#else + +/* ARGSUSED */ +void +util_restart(char const *old, char const *neW, int interval) +{ + (void) fprintf(stderr, + "util_restart: not supported on your operating system/hardware\n"); +} + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/util/safe_mem.c b/resources/3rdparty/cudd-2.5.0/util/safe_mem.c new file mode 100644 index 000000000..597cc892b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/safe_mem.c @@ -0,0 +1,97 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + +/* + * These are interface routines to be placed between a program and the + * system memory allocator. + * + * It forces well-defined semantics for several 'borderline' cases: + * + * malloc() of a 0 size object is guaranteed to return something + * which is not 0, and can safely be freed (but not dereferenced) + * free() accepts (silently) an 0 pointer + * realloc of a 0 pointer is allowed, and is equiv. to malloc() + * For the IBM/PC it forces no object > 64K; note that the size argument + * to malloc/realloc is a 'long' to catch this condition + * + * The function pointer MMoutOfMemory() contains a vector to handle a + * 'out-of-memory' error (which, by default, points at a simple wrap-up + * and exit routine). + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern char *MMalloc(long); +extern void MMout_of_memory(long); +extern char *MMrealloc(char *, long); + +void (*MMoutOfMemory)(long) = MMout_of_memory; + +#ifdef __cplusplus +} +#endif + + +/* MMout_of_memory -- out of memory for lazy people, flush and exit */ +void +MMout_of_memory(long size) +{ + (void) fflush(stdout); + (void) fprintf(stderr, "\nout of memory allocating %lu bytes\n", + (unsigned long) size); + exit(1); +} + + +char * +MMalloc(long size) +{ + char *p; + +#ifdef IBMPC + if (size > 65000L) { + if (MMoutOfMemory != (void (*)(long)) 0 ) (*MMoutOfMemory)(size); + return NIL(char); + } +#endif + if (size == 0) size = sizeof(long); + if ((p = (char *) malloc((unsigned long) size)) == NIL(char)) { + if (MMoutOfMemory != 0 ) (*MMoutOfMemory)(size); + return NIL(char); + } + return p; +} + + +char * +MMrealloc(char *obj, long size) +{ + char *p; + +#ifdef IBMPC + if (size > 65000L) { + if (MMoutOfMemory != 0 ) (*MMoutOfMemory)(size); + return NIL(char); + } +#endif + if (obj == NIL(char)) return MMalloc(size); + if (size <= 0) size = sizeof(long); + if ((p = (char *) realloc(obj, (unsigned long) size)) == NIL(char)) { + if (MMoutOfMemory != 0 ) (*MMoutOfMemory)(size); + return NIL(char); + } + return p; +} + + +void +MMfree(char *obj) +{ + if (obj != 0) { + free(obj); + } +} diff --git a/resources/3rdparty/cudd-2.5.0/util/saveimage.c b/resources/3rdparty/cudd-2.5.0/util/saveimage.c new file mode 100644 index 000000000..32332ef40 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/saveimage.c @@ -0,0 +1,229 @@ +/* LINTLIBRARY */ + + +/* + * saveimage.c -- + * + * Function to save an executable copy of the current process's + * image in a file. + * + */ + +#include +#include "util.h" + +#ifdef BSD +#include +#include +#include +#include + +extern int errno; + +#define BUFSIZE 8192 + +extern long lseek(); /* For lint */ +extern int getpagesize(); +extern char *sbrk(); + +static int copy_file(); +static int pad_file(); + + +int +util_save_image(char const *orig_file_name, char const *save_file_name) +{ + int origFd = -1, saveFd = -1; + char *start_data, *end_data, *start_text, *end_round; + struct exec old_hdr, new_hdr; + struct stat old_stat; + int n, page_size, length_text, length_data; + + if ((origFd = open(orig_file_name, 0)) < 0) { + perror(orig_file_name); + (void) fprintf(stderr, "Cannot open original a.out file\n"); + goto bad; + } + + if (fstat(origFd, &old_stat) < 0) { + perror(orig_file_name); + (void) fprintf(stderr, "Cannot stat original a.out file\n"); + goto bad; + } + + /* + * Read the a.out header from the original file. + */ + if (read(origFd, (char *) &old_hdr, sizeof(old_hdr)) != sizeof(old_hdr)) { + perror(orig_file_name); + (void) fprintf(stderr, "Cannot read original a.out header\n"); + goto bad; + } + if (N_BADMAG(old_hdr)) { + (void) fprintf(stderr, "File %s has a bad magic number (%o)\n", + orig_file_name, old_hdr.a_magic); + goto bad; + } + if (old_hdr.a_magic != ZMAGIC) { + (void) fprintf(stderr, "File %s is not demand-paged\n", orig_file_name); + goto bad; + } + + /* + * Open the output file. + */ + if (access(save_file_name, /* F_OK */ 0) == 0) { + (void) unlink(save_file_name); + } + if ((saveFd = creat(save_file_name, 0777)) < 0) { + if (errno == ETXTBSY) { + (void) unlink(save_file_name); + saveFd = creat(save_file_name, 0777); + } + if (saveFd < 0) { + perror(save_file_name); + (void) fprintf(stderr, "Cannot create save file.\n"); + goto bad; + } + } + + /* + * Find out how far the data segment extends. + */ + new_hdr = old_hdr; + end_data = sbrk(0); + page_size = getpagesize(); + n = ((((int) end_data) + page_size - 1) / page_size) * page_size; + end_round = (char *) n; + if (end_round > end_data) { + end_data = sbrk(end_round - end_data); + } + +#ifdef vax + start_text = 0; + length_text = new_hdr.a_text; + start_data = (char *) old_hdr.a_text; + length_data = end_data - start_data; +#endif vax +#ifdef sun + start_text = (char *) N_TXTADDR(old_hdr) + sizeof(old_hdr); + length_text = old_hdr.a_text - sizeof(old_hdr); + start_data = (char *) N_DATADDR(old_hdr); + length_data = end_data - start_data; +#endif sun + new_hdr.a_data = end_data - start_data; + new_hdr.a_bss = 0; + + /* + * First, the header plus enough pad to extend up to N_TXTOFF. + */ + if (write(saveFd, (char *) &new_hdr, (int) sizeof(new_hdr)) != + sizeof(new_hdr)) { + perror("write"); + (void) fprintf(stderr, "Error while copying header.\n"); + goto bad; + } + if (! pad_file(saveFd, N_TXTOFF(old_hdr) - sizeof(new_hdr))) { + (void) fprintf(stderr, "Error while padding.\n"); + goto bad; + } + + + /* + * Copy our text segment + */ + if (write(saveFd, start_text, length_text) != length_text) { + perror("write"); + (void) fprintf(stderr, "Error while copying text segment.\n"); + goto bad; + } + + + /* + * Copy our data segment + */ + if (write(saveFd, start_data, length_data) != length_data) { + perror("write"); + (void) fprintf(stderr, "Error while copying data segment.\n"); + goto bad; + } + + /* + * Copy the symbol table and everything else. + * This takes us to the end of the original file. + */ + (void) lseek(origFd, (long) N_SYMOFF(old_hdr), 0); + if (! copy_file(origFd, saveFd, old_stat.st_size - N_SYMOFF(old_hdr))) { + (void) fprintf(stderr, "Error while copying symbol table.\n"); + goto bad; + } + (void) close(origFd); + (void) close(saveFd); + return 1; + +bad: + if (origFd >= 0) (void) close(origFd); + if (saveFd >= 0) (void) close(saveFd); + return 0; +} + + +static int +copy_file(inFd, outFd, nbytes) +int inFd, outFd; +unsigned long nbytes; +{ + char buf[BUFSIZE]; + int nread, ntoread; + + while (nbytes > 0) { + ntoread = nbytes; + if (ntoread > sizeof buf) ntoread = sizeof buf; + if ((nread = read(inFd, buf, ntoread)) != ntoread) { + perror("read"); + return (0); + } + if (write(outFd, buf, nread) != nread) { + perror("write"); + return (0); + } + nbytes -= nread; + } + + return (1); +} + + +static int +pad_file(outFd, nbytes) +int outFd; +int nbytes; +{ + char buf[BUFSIZE]; + int nzero; + + nzero = (nbytes > sizeof(buf)) ? sizeof(buf) : nbytes; + bzero(buf, nzero); + while (nbytes > 0) { + nzero = (nbytes > sizeof(buf)) ? sizeof(buf) : nbytes; + if (write(outFd, buf, nzero) != nzero) { + perror("write"); + return (0); + } + nbytes -= nzero; + } + + return (1); +} +#else + +/* ARGSUSED */ +int +util_save_image(char const *orig_file_name, char const *save_file_name) +{ + (void) fprintf(stderr, + "util_save_image: not implemented on your operating system\n"); + return 0; +} + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/util/state.c b/resources/3rdparty/cudd-2.5.0/util/state.c new file mode 100644 index 000000000..ef830aa74 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/state.c @@ -0,0 +1,82 @@ +#ifdef lint +util_restart_save_state() +{ + return 0; +} + + +util_restart_restore_state() +{ +} + +#else + +static char rcsid[] = "$Id: state.c,v 1.1 1997/11/04 22:38:50 fabio Exp $"; + +#ifdef vax +int util_restart_state[32]; + +util_restart_save_state() +{ + asm("movl sp,_util_save_sp"); + asm("movl r1,_util_restart_state"); + asm("movl r2,_util_restart_state+4"); + asm("movl r3,_util_restart_state+8"); + asm("movl r4,_util_restart_state+12"); + asm("movl r5,_util_restart_state+16"); + asm("movl r6,_util_restart_state+20"); + asm("movl r7,_util_restart_state+24"); + asm("movl r8,_util_restart_state+28"); + asm("movl r9,_util_restart_state+32"); + asm("movl r10,_util_restart_state+36"); + asm("movl r11,_util_restart_state+40"); + asm("movl 8(fp),_util_restart_state+44"); + asm("movl 12(fp),_util_restart_state+48"); + asm("movl 16(fp),_util_restart_state+52"); + asm("movl $0,r0"); +} + +util_restart_restore_state() +{ + asm("movl _util_restart_state,r1"); + asm("movl _util_restart_state+4,r2"); + asm("movl _util_restart_state+8,r3"); + asm("movl _util_restart_state+12,r4"); + asm("movl _util_restart_state+16,r5"); + asm("movl _util_restart_state+20,r6"); + asm("movl _util_restart_state+24,r7"); + asm("movl _util_restart_state+28,r8"); + asm("movl _util_restart_state+32,r9"); + asm("movl _util_restart_state+36,r10"); + asm("movl _util_restart_state+40,r11"); + asm("movl _util_restart_state+44,ap"); + asm("movl _util_restart_state+48,fp"); + asm("addl3 fp,$4,sp"); + asm("movl _util_restart_state+52,r0"); + asm("jmp (r0)"); +} +#endif + + +#if defined(sun) && ! defined(sparc) +int util_restart_state[32]; + +util_restart_save_state() +{ + asm("movel sp,_util_save_sp"); + asm("movel sp@,_util_restart_state"); + asm("movel sp@(0x4),_util_restart_state+4"); + asm("moveml #0xFFFF,_util_restart_state+8"); + return 0; +} + +util_restart_restore_state() +{ + asm("moveml _util_restart_state+8,#0xFFFF"); + asm("movel _util_restart_state+4,sp@(0x4)"); + asm("movel _util_restart_state,sp@"); + return 1; +} +#endif + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/util/strsav.c b/resources/3rdparty/cudd-2.5.0/util/strsav.c new file mode 100644 index 000000000..454e237c4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/strsav.c @@ -0,0 +1,14 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + + +/* + * util_strsav -- save a copy of a string + */ +char * +util_strsav(char const *s) +{ + return strcpy(ALLOC(char, strlen(s)+1), s); +} diff --git a/resources/3rdparty/cudd-2.5.0/util/stub.c b/resources/3rdparty/cudd-2.5.0/util/stub.c new file mode 100644 index 000000000..93f57e67f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/stub.c @@ -0,0 +1,82 @@ +/* LINTLIBRARY */ + +#ifdef LACK_SYS5 + +char * +memcpy(s1, s2, n) +char *s1, *s2; +int n; +{ + extern bcopy(); + bcopy(s2, s1, n); + return s1; +} + +char * +memset(s, c, n) +char *s; +int c; +int n; +{ + extern bzero(); + register int i; + + if (c == 0) { + bzero(s, n); + } else { + for(i = n-1; i >= 0; i--) { + *s++ = c; + } + } + return s; +} + +char * +strchr(s, c) +char *s; +int c; +{ + extern char *index(); + return index(s, c); +} + +char * +strrchr(s, c) +char *s; +int c; +{ + extern char *rindex(); + return rindex(s, c); +} + + +#endif + +#ifndef UNIX +#include + +FILE * +popen(string, mode) +const char *string; +const char *mode; +{ + (void) fprintf(stderr, "popen not supported on your operating system\n"); + return NULL; +} + + +int +pclose(fp) +FILE *fp; +{ + (void) fprintf(stderr, "pclose not supported on your operating system\n"); + return -1; +} +#endif + +/* put something here in case some compilers abort on empty files ... */ +int +util_do_nothing() +{ + return 1; +} diff --git a/resources/3rdparty/cudd-2.5.0/util/test-res.c b/resources/3rdparty/cudd-2.5.0/util/test-res.c new file mode 100644 index 000000000..e7af9c9fd --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/test-res.c @@ -0,0 +1,57 @@ +#include +#include "util.h" + + +main(argc, argv, environ) +int argc; +char **argv; +char **environ; +{ + int i; + char **ep, *prog; + + prog = util_path_search(argv[0]); + if (prog == NIL(char)) { + (void) fprintf(stderr, "Cannot find current executable\n"); + exit(1); + } + util_restart(prog, "a.out", 0); + + i = recur(10); + (void) fprintf(stderr, "terminated normally with i = %d\n", i); + + (void) printf("argc is %d\n", argc); + + for(i = 0, ep = argv; *ep != 0; i++, ep++) { + (void) printf("%08x (%08x-%08x)\targv[%d]:\t%s\n", + ep, *ep, *ep + strlen(*ep), i, *ep); + } + + i = 0; + for(i = 0, ep = environ; *ep != 0; ep++, i++) { + (void) printf("%08x (%08x-%08x)\tenviron[%d]:\t%s\n", + ep, *ep, *ep + strlen(*ep), i, *ep); + } + + (void) fprintf(stderr, "returning with status=4\n"); + return 4; +} + + +recur(cnt) +{ + int i, j, sum; + + if (cnt > 0) { + return recur(cnt-1); + } else { + sum = 0; + for(j = 0; j < 20; j++) { + for(i = 0; i < 100000; i++) { + sum += 1; + } + (void) printf("done loop %d\n", j); + } + return sum; + } +} diff --git a/resources/3rdparty/cudd-2.5.0/util/test-sav.c b/resources/3rdparty/cudd-2.5.0/util/test-sav.c new file mode 100644 index 000000000..3140671be --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/test-sav.c @@ -0,0 +1,39 @@ +#include +#include "util.h" + + +/* ARGSUSED */ +static int +saveit(prog, file2) +char *prog, *file2; +{ + char *file1; + + /* get current executable name by searching the path ... */ + file1 = util_path_search(prog); + if (file1 == 0) { + (void) fprintf(stderr, "cannot locate current executable\n"); + return 1; + } + + /* users name for the new executable -- perform tilde-expansion */ + if (! util_save_image(file1, file2)) { + (void) fprintf(stderr, "error occured during save ...\n"); + return 1; + } + FREE(file1); + return 0; +} + +int restart; + +main(argc, argv) +char **argv; +{ + if (restart) { + (void) printf("restarted ...\n"); + exit(0); + } + restart = 1; + exit(saveit(argv[0], "foobar")); +} diff --git a/resources/3rdparty/cudd-2.5.0/util/texpand.c b/resources/3rdparty/cudd-2.5.0/util/texpand.c new file mode 100644 index 000000000..c14defee8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/texpand.c @@ -0,0 +1,57 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + +#ifdef BSD +#include +#endif + + +char * +util_tilde_expand(char const *fname) +{ +#ifdef BSD + struct passwd *userRecord; + char username[256], *filename; + register int i, j; + + filename = ALLOC(char, strlen(fname) + 256); + + /* Clear the return string */ + i = 0; + filename[0] = '\0'; + + /* Tilde? */ + if (fname[0] == '~') { + j = 0; + i = 1; + while ((fname[i] != '\0') && (fname[i] != '/')) { + username[j++] = fname[i++]; + } + username[j] = '\0'; + + if (username[0] == '\0') { + /* ~/ resolves to home directory of current user */ + if ((userRecord = getpwuid(getuid())) != 0) { + (void) strcat(filename, userRecord->pw_dir); + } else { + i = 0; + } + } else { + /* ~user/ resolves to home directory of 'user' */ + if ((userRecord = getpwnam(username)) != 0) { + (void) strcat(filename, userRecord->pw_dir); + } else { + i = 0; + } + } + } + + /* Concantenate remaining portion of file name */ + (void) strcat(filename, fname + i); + return filename; +#else + return strsav(fname); +#endif +} diff --git a/resources/3rdparty/cudd-2.5.0/util/util.h b/resources/3rdparty/cudd-2.5.0/util/util.h new file mode 100644 index 000000000..410720379 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/util.h @@ -0,0 +1,204 @@ +/* $Id: util.h,v 1.10 2012/02/05 05:34:04 fabio Exp fabio $ */ + +#ifndef UTIL_H +#define UTIL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) +# define UTIL_INLINE __inline__ +# if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +# define UTIL_UNUSED __attribute__ ((unused)) +# else +# define UTIL_UNUSED +# endif +#else +# define UTIL_INLINE +# define UTIL_UNUSED +#endif + +#ifndef SIZEOF_VOID_P +#define SIZEOF_VOID_P 4 +#endif +#ifndef SIZEOF_INT +#define SIZEOF_INT 4 +#endif +#ifndef SIZEOF_LONG +#define SIZEOF_LONG 4 +#endif + +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +typedef long util_ptrint; +#else +typedef int util_ptrint; +#endif + +/* #define USE_MM */ /* choose libmm.a as the memory allocator */ + +/* these are too entrenched to get away with changing the name */ +#define strsav util_strsav +#include + +#define NIL(type) ((type *) 0) + +#if defined(USE_MM) || defined(MNEMOSYNE) +/* + * assumes the memory manager is either libmm.a or libmnem.a + * libmm.a: + * - allows malloc(0) or realloc(obj, 0) + * - catches out of memory (and calls MMout_of_memory()) + * - catch free(0) and realloc(0, size) in the macros + * libmnem.a: + * - reports memory leaks + * - is used in conjunction with the mnemalyse postprocessor + */ +#ifdef MNEMOSYNE +#include "mnemosyne.h" +#define ALLOC(type, num) \ + ((num) ? ((type *) malloc(sizeof(type) * (num))) : \ + ((type *) malloc(sizeof(long)))) +#else +#define ALLOC(type, num) \ + ((type *) malloc(sizeof(type) * (num))) +#endif +#define REALLOC(type, obj, num) \ + (obj) ? ((type *) realloc((char *) obj, sizeof(type) * (num))) : \ + ((type *) malloc(sizeof(type) * (num))) +#define FREE(obj) \ + ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) +#else +/* + * enforce strict semantics on the memory allocator + * - when in doubt, delete the '#define USE_MM' above + */ +#define ALLOC(type, num) \ + ((type *) MMalloc((long) sizeof(type) * (long) (num))) +#define REALLOC(type, obj, num) \ + ((type *) MMrealloc((char *) (obj), (long) sizeof(type) * (long) (num))) +#define FREE(obj) \ + ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) +#endif + + +/* Ultrix (and SABER) have 'fixed' certain functions which used to be int */ +#if defined(ultrix) || defined(SABER) || defined(aiws) || defined(hpux) || defined(apollo) || defined(__osf__) || defined(__SVR4) || defined(__GNUC__) +#define VOID_OR_INT void +#define VOID_OR_CHAR void +#else +#define VOID_OR_INT int +#define VOID_OR_CHAR char +#endif + + +/* No machines seem to have much of a problem with these */ +#include +#include + + +/* Some machines fail to define some functions in stdio.h */ +#if !defined(__STDC__) && !defined(__cplusplus) +extern FILE *popen(), *tmpfile(); +extern int pclose(); +#endif + + +/* most machines don't give us a header file for these */ +#if (defined(__STDC__) || defined(__cplusplus) || defined(ultrix)) && !defined(MNEMOSYNE) || defined(__SVR4) +# include +#else +# ifndef _IBMR2 + extern VOID_OR_INT abort(), exit(); +# endif +# if !defined(MNEMOSYNE) && !defined(_IBMR2) + extern VOID_OR_INT free (void *); + extern VOID_OR_CHAR *malloc(), *realloc(); +# endif + extern char *getenv(); + extern int system(); + extern double atof(); +#endif + + +/* some call it strings.h, some call it string.h; others, also have memory.h */ +#if defined(__STDC__) || defined(__cplusplus) || defined(_IBMR2) || defined(ultrix) +#include +#else +/* ANSI C string.h -- 1/11/88 Draft Standard */ +extern char *strcpy(), *strncpy(), *strcat(), *strncat(), *strerror(); +extern char *strpbrk(), *strtok(), *strchr(), *strrchr(), *strstr(); +extern int strcoll(), strxfrm(), strncmp(), strlen(), strspn(), strcspn(); +extern char *memmove(), *memccpy(), *memchr(), *memcpy(), *memset(); +extern int memcmp(), strcmp(); +#endif + + +#ifdef __STDC__ +#include +#else +#ifndef NDEBUG +#define assert(ex) {\ + if (! (ex)) {\ + (void) fprintf(stderr,\ + "Assertion failed: file %s, line %d\n\"%s\"\n",\ + __FILE__, __LINE__, "ex");\ + (void) fflush(stdout);\ + abort();\ + }\ +} +#else +#define assert(ex) ; +#endif +#endif + + +#define fail(why) {\ + (void) fprintf(stderr, "Fatal error: file %s, line %d\n%s\n",\ + __FILE__, __LINE__, why);\ + (void) fflush(stdout);\ + abort();\ +} + + +#ifdef lint +#undef putc /* correct lint '_flsbuf' bug */ +#undef ALLOC /* allow for lint -h flag */ +#undef REALLOC +#define ALLOC(type, num) (((type *) 0) + (num)) +#define REALLOC(type, obj, num) ((obj) + (num)) +#endif + + +/* These arguably do NOT belong in util.h */ +#define ABS(a) ((a) < 0 ? -(a) : (a)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + + +#ifndef USE_MM +extern char *MMalloc (long); +extern void MMout_of_memory (long); +extern void (*MMoutOfMemory) (long); +extern char *MMrealloc (char *, long); +#endif + +extern long util_cpu_time (void); +extern char *util_path_search (char const *); +extern char *util_file_search (char const *, char *, char const *); +extern int util_pipefork (char * const *, FILE **, FILE **, int *); +extern void util_print_cpu_stats (FILE *); +extern char *util_print_time (unsigned long); +extern int util_save_image (char const *, char const *); +extern char *util_strsav (char const *); +extern char *util_tilde_expand (char const *); +extern void util_restart (char const *, char const *, int); + + +extern unsigned long getSoftDataLimit (void); + +#ifdef __cplusplus +} +#endif + +#endif /* UTIL_H */ From 1485eae477cd06fbd30705d6c96b5707f39b784b Mon Sep 17 00:00:00 2001 From: dehnert Date: Fri, 25 Jan 2013 16:47:59 +0100 Subject: [PATCH 022/152] Added cudd to gitignore so the changes to cudd (e.g. compiling) will not be committed to repo. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 6f15a4cb4..e15342bf5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ resources/3rdparty/log4cplus-1.1.0/ resources/3rdparty/gtest-1.6.0/ resources/3rdparty/eigen/ resources/3rdparty/gmm-4.2/ +resources/3rdparty/cudd-2.5.0/ #Visual Studio files *.[Oo]bj *.user From edd3a9a20e8e6c85a22d08fcfee841be26d387e8 Mon Sep 17 00:00:00 2001 From: dehnert Date: Fri, 25 Jan 2013 19:43:32 +0100 Subject: [PATCH 023/152] Added possibility to evaluate expressions without concrete variables. Fixed some minor things in CUDD Makefiles. Renamed IR adapter. --- CMakeLists.txt | 17 +++ resources/3rdparty/cudd-2.5.0/Makefile | 14 ++- resources/3rdparty/cudd-2.5.0/obj/Makefile | 113 ++++++++++++++++++ ...tationAdapter.h => ExplicitModelAdapter.h} | 37 +++--- src/ir/IntegerVariable.cpp | 11 ++ src/ir/IntegerVariable.h | 12 ++ src/ir/expressions/BaseExpression.h | 6 +- .../BinaryBooleanFunctionExpression.h | 2 +- .../BinaryNumericalFunctionExpression.h | 4 +- src/ir/expressions/BinaryRelationExpression.h | 2 +- .../expressions/BooleanConstantExpression.h | 2 +- src/ir/expressions/BooleanLiteral.h | 2 +- src/ir/expressions/DoubleConstantExpression.h | 2 +- src/ir/expressions/DoubleLiteral.h | 2 +- .../expressions/IntegerConstantExpression.h | 2 +- src/ir/expressions/IntegerLiteral.h | 2 +- .../UnaryBooleanFunctionExpression.h | 2 +- .../UnaryNumericalFunctionExpression.h | 4 +- src/ir/expressions/VariableExpression.h | 20 +++- src/storm.cpp | 8 +- 20 files changed, 214 insertions(+), 50 deletions(-) create mode 100644 resources/3rdparty/cudd-2.5.0/obj/Makefile rename src/adapters/{IntermediateRepresentationAdapter.h => ExplicitModelAdapter.h} (93%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 360907867..0c8983239 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,12 @@ message(STATUS "EIGEN3_INCLUDE_DIR is ${EIGEN3_INCLUDE_DIR}") set(GMMXX_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/resources/3rdparty/gmm-4.2/include) message(STATUS "GMMXX_INCLUDE_DIR is ${GMMXX_INCLUDE_DIR}") +# Set all CUDD references to the version in the repository +set(CUDD_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/include) +set(CUDD_LIBRARY_DIRS ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/cudd ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/mtr ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/util ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/st ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/epd ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/obj) +message(STATUS "CUDD_INCLUDE_DIR is ${CUDD_INCLUDE_DIR}") +message(STATUS "CUDD_LIBRARY_DIRS is ${CUDD_LIBRARY_DIRS}") + # Now define all available custom options option(DEBUG "Sets whether the DEBUG mode is used" ON) option(USE_POPCNT "Sets whether the popcnt instruction is going to be used." ON) @@ -160,6 +166,13 @@ if (ADDITIONAL_LINK_DIRS) link_directories(${ADDITIONAL_LINK_DIRS}) endif(ADDITIONAL_LINK_DIRS) +if (CUDD_INCLUDE_DIR) + include_directories(${CUDD_INCLUDE_DIR}) +endif(CUDD_INCLUDE_DIR) +if (CUDD_LIBRARY_DIRS) + link_directories(${CUDD_LIBRARY_DIRS}) +endif(CUDD_LIBRARY_DIRS) + # Add the executables # Must be created *after* Boost was added because of LINK_DIRECTORIES add_executable(storm ${STORM_SOURCES} ${STORM_HEADERS}) @@ -211,6 +224,10 @@ if (LOG4CPLUS_INCLUDE_DIR) endif(UNIX AND NOT APPLE) endif(LOG4CPLUS_INCLUDE_DIR) +if (CUDD_LIBRARY_DIRS) + target_link_libraries(storm "-lcudd -lmtr -lst -lutil -lepd -lobj") +endif(CUDD_LIBRARY_DIRS) + if (THREADS_FOUND) include_directories(${THREADS_INCLUDE_DIRS}) target_link_libraries (storm ${CMAKE_THREAD_LIBS_INIT}) diff --git a/resources/3rdparty/cudd-2.5.0/Makefile b/resources/3rdparty/cudd-2.5.0/Makefile index e38ffa6ec..b1b5f32c8 100644 --- a/resources/3rdparty/cudd-2.5.0/Makefile +++ b/resources/3rdparty/cudd-2.5.0/Makefile @@ -7,15 +7,16 @@ # be overridden from the command line. # C++ compiler -CXX = g++ +#CXX = g++ #CXX = icpc #CXX = ecpc #CXX = CC #CXX = /usr/local/opt/SUNWspro/bin/CC #CXX = cxx +CXX = clang++ # Specific options for compilation of C++ files. -CXXFLAGS = +CXXFLAGS = -std=c++11 -stdlib=libc++ # Stricter standard conformance for g++. #CXXFLAGS = -std=c++98 # For Sun CC version 5, this invokes compatibility mode. @@ -27,12 +28,13 @@ CXXFLAGS = # C compiler used for all targets except optimize_dec, which always uses cc. #CC = cc #CC = /usr/local/opt/SUNWspro/bin/cc -CC = gcc +#CC = gcc #CC = icc #CC = ecc #CC = /usr/ucb/cc #CC = c89 #CC = $(CXX) +CC = clang # On some machines ranlib is either non-existent or redundant. # Use the following definition if your machine has ranlib and you think @@ -49,7 +51,7 @@ RANLIB = ranlib #ICFLAGS = # These two are typical settings for optimized code with gcc. #ICFLAGS = -g -O3 -Wall -ICFLAGS = -g -O3 +ICFLAGS = -O3 # Use XCFLAGS to specify machine-dependent compilation flags. # For some platforms no special flags are needed. @@ -59,7 +61,7 @@ ICFLAGS = -g -O3 # Linux # # Gcc 4.2.4 or higher on i686. -XCFLAGS = -mtune=native -malign-double -DHAVE_IEEE_754 -DBSD +XCFLAGS = -arch x86_64 -DHAVE_IEEE_754 -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 # Gcc 3.2.2 or higher on i686. #XCFLAGS = -mtune=pentium4 -malign-double -DHAVE_IEEE_754 -DBSD # Gcc 2.8.1 on i686. @@ -198,7 +200,7 @@ DDWDIR = . IDIR = $(DDWDIR)/include INCLUDE = -I$(IDIR) -BDIRS = cudd dddmp mtr st util epd +BDIRS = cudd dddmp mtr st util epd obj DIRS = $(BDIRS) nanotrav #------------------------------------------------------------------------ diff --git a/resources/3rdparty/cudd-2.5.0/obj/Makefile b/resources/3rdparty/cudd-2.5.0/obj/Makefile new file mode 100644 index 000000000..d3f62e1ad --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/obj/Makefile @@ -0,0 +1,113 @@ +# $Id: Makefile,v 1.3 2001/03/19 07:34:37 fabio Exp fabio $ +# +# obj: CUDD's C++ interface +#--------------------------------------------------------------------------- +.SUFFIXES: .o .cc .u + +#CXX = g++ +CXX = clang++ +RANLIB = ranlib +# Define EXE as .exe for MS-DOS and derivatives. +PURE = +EXE = +#EXE = .exe + +MFLAG = +#ICFLAGS = -g +ICFLAGS = +XCFLAGS = +#CXXFLAGS = +CXXFLAGS = -O3 -std=c++11 -stdlib=libc++ +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) $(CXXFLAGS) +DDDEBUG = + +LINTFLAGS = -u -n -DDD_STATS -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_DEBUG -DDD_UNIQUE_PROFILE + +# this is to create the lint library +LINTSWITCH = -o + +WHERE = .. + +INCLUDE = $(WHERE)/include + +LIBS = ./libobj.a $(WHERE)/cudd/libcudd.a $(WHERE)/mtr/libmtr.a \ + $(WHERE)/st/libst.a $(WHERE)/util/libutil.a $(WHERE)/epd/libepd.a + +MNEMLIB = + +BLIBS = -kL. -klobj -kL$(WHERE)/cudd -klcudd -kL$(WHERE)/mtr -klmtr \ + -kL$(WHERE)/st -klst -kL$(WHERE)/util -klutil -kL$(WHERE)/epd -klepd + +LINTLIBS = ./llib-lobj.ln $(WHERE)/cudd/llib-lcudd.ln \ + $(WHERE)/mtr/llib-lmtr.ln $(WHERE)/st/llib-lst.ln \ + $(WHERE)/util/llib-lutil.ln $(WHERE)/epd/llib-lepd.ln + +LDFLAGS = + +# files for the package +P = obj +PSRC = cuddObj.cc +PHDR = cuddObj.hh $(INCLUDE)/cudd.h +POBJ = $(PSRC:.cc=.o) +PUBJ = $(PSRC:.cc=.u) +TARGET = test$(P)$(EXE) +TARGETu = test$(P)-u + +# files for the test program +SRC = test$(P).cc +OBJ = $(SRC:.cc=.o) +UBJ = $(SRC:.cc=.u) + +#------------------------------------------------------ + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.cc.o: $(PHDR) + $(CXX) -c $< -I$(INCLUDE) $(CFLAGS) $(DDDEBUG) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.cc.u: $(PHDR) + cxx -j $< -I$(INCLUDE) $(CFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) +$(OBJ): $(PHDR) +$(UBJ): $(PHDR) + +$(TARGET): $(SRC) $(OBJ) $(HDR) $(LIBS) $(MNEMLIB) + $(PURE) $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +# optimize (DECstations and Alphas only: uses u-code) +$(TARGETu): $(SRC) $(UBJ) $(HDR) $(LIBS:.a=.b) + cxx -O3 -Olimit 1000 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +lintpgm: lint + lint $(LINTFLAGS) -I$(INCLUDE) $(SRC) $(LINTLIBS) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +programs: $(TARGET) $(TARGETu) lintpgm + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \ + *.bak *~ tags .gdb_history *.qv *.qx diff --git a/src/adapters/IntermediateRepresentationAdapter.h b/src/adapters/ExplicitModelAdapter.h similarity index 93% rename from src/adapters/IntermediateRepresentationAdapter.h rename to src/adapters/ExplicitModelAdapter.h index 6c5774bfc..d056f6849 100644 --- a/src/adapters/IntermediateRepresentationAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -5,8 +5,8 @@ * Author: Christian Dehnert */ -#ifndef STORM_IR_INTERMEDIATEREPRESENTATIONADAPTER_H_ -#define STORM_IR_INTERMEDIATEREPRESENTATIONADAPTER_H_ +#ifndef STORM_IR_EXPLICITMODELADAPTER_H_ +#define STORM_IR_EXPLICITMODELADAPTER_H_ #include "src/storage/SparseMatrix.h" #include "src/utility/Settings.h" @@ -49,7 +49,7 @@ public: } }; -class IntermediateRepresentationAdapter { +class ExplicitModelAdapter { public: template static storm::storage::SparseMatrix* toSparseMatrix(storm::ir::Program const& program) { @@ -89,12 +89,12 @@ public: StateType* initialState = getNewState(numberOfBooleanVariables, numberOfIntegerVariables); for (uint_fast64_t i = 0; i < numberOfBooleanVariables; ++i) { - bool initialValue = booleanVariables[i].getInitialValue()->getValueAsBool(*initialState); + bool initialValue = booleanVariables[i].getInitialValue()->getValueAsBool(initialState); std::get<0>(*initialState)[i] = initialValue; } for (uint_fast64_t i = 0; i < numberOfIntegerVariables; ++i) { - int_fast64_t initialValue = integerVariables[i].getInitialValue()->getValueAsInt(*initialState); + int_fast64_t initialValue = integerVariables[i].getInitialValue()->getValueAsInt(initialState); std::get<1>(*initialState)[i] = initialValue; } @@ -124,7 +124,7 @@ public: storm::ir::Command const& command = module.getCommand(j); // Check if this command is enabled in the current state. - if (command.getGuard()->getValueAsBool(*currentState)) { + if (command.getGuard()->getValueAsBool(currentState)) { hasTransition = true; std::unordered_map stateToProbabilityMap; std::queue statesToDelete; @@ -135,12 +135,12 @@ public: // std::cout << "took state: " << newState->first << "/" << newState->second << std::endl; std::map const& booleanAssignmentMap = update.getBooleanAssignments(); for (auto assignedVariable : booleanAssignmentMap) { - setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(*currentState)); + setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(currentState)); } std::map const& integerAssignmentMap = update.getIntegerAssignments(); for (auto assignedVariable : integerAssignmentMap) { // std::cout << "evaluting " << assignedVariable.second.getExpression()->toString() << " as " << assignedVariable.second.getExpression()->getValueAsInt(*currentState) << std::endl; - setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(*currentState)); + setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(currentState)); } // std::cout << "applied: " << update.toString() << std::endl; @@ -148,10 +148,10 @@ public: auto probIt = stateToProbabilityMap.find(newState); if (probIt != stateToProbabilityMap.end()) { - stateToProbabilityMap[newState] += update.getLikelihoodExpression()->getValueAsDouble(*currentState); + stateToProbabilityMap[newState] += update.getLikelihoodExpression()->getValueAsDouble(currentState); } else { ++totalNumberOfTransitions; - stateToProbabilityMap[newState] = update.getLikelihoodExpression()->getValueAsDouble(*currentState); + stateToProbabilityMap[newState] = update.getLikelihoodExpression()->getValueAsDouble(currentState); } auto it = stateToIndexMap.find(newState); @@ -204,7 +204,7 @@ public: storm::ir::Command const& command = module.getCommand(j); // Check if this command is enabled in the current state. - if (command.getGuard()->getValueAsBool(*currentState)) { + if (command.getGuard()->getValueAsBool(currentState)) { hasTransition = true; std::map stateIndexToProbabilityMap; for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { @@ -214,11 +214,11 @@ public: std::map const& booleanAssignmentMap = update.getBooleanAssignments(); for (auto assignedVariable : booleanAssignmentMap) { - setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(*currentState)); + setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(currentState)); } std::map const& integerAssignmentMap = update.getIntegerAssignments(); for (auto assignedVariable : integerAssignmentMap) { - setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(*currentState)); + setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(currentState)); } uint_fast64_t targetIndex = (*stateToIndexMap.find(newState)).second; @@ -226,9 +226,9 @@ public: auto probIt = stateIndexToProbabilityMap.find(targetIndex); if (probIt != stateIndexToProbabilityMap.end()) { - stateIndexToProbabilityMap[targetIndex] += update.getLikelihoodExpression()->getValueAsDouble(*currentState); + stateIndexToProbabilityMap[targetIndex] += update.getLikelihoodExpression()->getValueAsDouble(currentState); } else { - stateIndexToProbabilityMap[targetIndex] = update.getLikelihoodExpression()->getValueAsDouble(*currentState); + stateIndexToProbabilityMap[targetIndex] = update.getLikelihoodExpression()->getValueAsDouble(currentState); } } @@ -275,9 +275,8 @@ private: } }; -} +} // namespace adapters -} +} // namespace storm - -#endif /* STORM_IR_INTERMEDIATEREPRESENTATIONADAPTER_H_ */ +#endif /* STORM_IR_EXPLICITMODELADAPTER_H_ */ diff --git a/src/ir/IntegerVariable.cpp b/src/ir/IntegerVariable.cpp index 8374551a9..b07316b65 100644 --- a/src/ir/IntegerVariable.cpp +++ b/src/ir/IntegerVariable.cpp @@ -27,6 +27,17 @@ IntegerVariable::IntegerVariable(uint_fast64_t index, std::string variableName, } } +// Return lower bound for variable. +std::shared_ptr IntegerVariable::getLowerBound() const { + return this->lowerBound; +} + +// Return upper bound for variable. +std::shared_ptr IntegerVariable::getUpperBound() const { + return this->upperBound; +} + + // Build a string representation of the variable. std::string IntegerVariable::toString() const { std::stringstream result; diff --git a/src/ir/IntegerVariable.h b/src/ir/IntegerVariable.h index 86e2dfc1b..a05ef1d7e 100644 --- a/src/ir/IntegerVariable.h +++ b/src/ir/IntegerVariable.h @@ -37,6 +37,18 @@ public: */ IntegerVariable(uint_fast64_t index, std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue = std::shared_ptr(nullptr)); + /*! + * Retrieves the lower bound for this integer variable. + * @returns the lower bound for this integer variable. + */ + std::shared_ptr getLowerBound() const; + + /*! + * Retrieves the upper bound for this integer variable. + * @returns the upper bound for this integer variable. + */ + std::shared_ptr getUpperBound() const; + /*! * Retrieves a string representation of this variable. * @returns a string representation of this variable. diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h index 3e228d5cf..27704b64b 100644 --- a/src/ir/expressions/BaseExpression.h +++ b/src/ir/expressions/BaseExpression.h @@ -37,7 +37,7 @@ public: } - virtual int_fast64_t getValueAsInt(std::pair, std::vector> const& variableValues) const { + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { if (type != int_) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '" << this->getTypeName() << "' as 'int'."; @@ -46,7 +46,7 @@ public: << this->getTypeName() << " because evaluation implementation is missing."; } - virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { + virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { if (type != bool_) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '" << this->getTypeName() << "' as 'bool'."; @@ -55,7 +55,7 @@ public: << this->getTypeName() << " because evaluation implementation is missing."; } - virtual double getValueAsDouble(std::pair, std::vector> const& variableValues) const { + virtual double getValueAsDouble(std::pair, std::vector> const* variableValues) const { if (type != bool_) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '" << this->getTypeName() << "' as 'double'."; diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.h b/src/ir/expressions/BinaryBooleanFunctionExpression.h index 957c08658..c7b5a0bdc 100644 --- a/src/ir/expressions/BinaryBooleanFunctionExpression.h +++ b/src/ir/expressions/BinaryBooleanFunctionExpression.h @@ -31,7 +31,7 @@ public: } - virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { + virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { bool resultLeft = left->getValueAsBool(variableValues); bool resultRight = right->getValueAsBool(variableValues); switch(functionType) { diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h index 7a76320a9..0d710e785 100644 --- a/src/ir/expressions/BinaryNumericalFunctionExpression.h +++ b/src/ir/expressions/BinaryNumericalFunctionExpression.h @@ -28,7 +28,7 @@ public: } - virtual int_fast64_t getValueAsInt(std::pair, std::vector> const& variableValues) const { + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { if (this->getType() != int_) { BaseExpression::getValueAsInt(variableValues); } @@ -45,7 +45,7 @@ public: } } - virtual double getValueAsDouble(std::pair, std::vector> const& variableValues) const { + virtual double getValueAsDouble(std::pair, std::vector> const* variableValues) const { if (this->getType() != double_) { BaseExpression::getValueAsDouble(variableValues); } diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h index fe07f0749..83556fa8f 100644 --- a/src/ir/expressions/BinaryRelationExpression.h +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -28,7 +28,7 @@ public: } - virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { + virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { int_fast64_t resultLeft = left->getValueAsInt(variableValues); int_fast64_t resultRight = right->getValueAsInt(variableValues); switch(relationType) { diff --git a/src/ir/expressions/BooleanConstantExpression.h b/src/ir/expressions/BooleanConstantExpression.h index 58204fee4..c4a168838 100644 --- a/src/ir/expressions/BooleanConstantExpression.h +++ b/src/ir/expressions/BooleanConstantExpression.h @@ -29,7 +29,7 @@ public: } - virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { + virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { if (!defined) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " << "Boolean constant '" << this->getConstantName() << "' is undefined."; diff --git a/src/ir/expressions/BooleanLiteral.h b/src/ir/expressions/BooleanLiteral.h index b7ee88997..55027d6cc 100644 --- a/src/ir/expressions/BooleanLiteral.h +++ b/src/ir/expressions/BooleanLiteral.h @@ -28,7 +28,7 @@ public: } - virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { + virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { return value; } diff --git a/src/ir/expressions/DoubleConstantExpression.h b/src/ir/expressions/DoubleConstantExpression.h index c852329c1..573aeffd3 100644 --- a/src/ir/expressions/DoubleConstantExpression.h +++ b/src/ir/expressions/DoubleConstantExpression.h @@ -26,7 +26,7 @@ public: } - virtual double getValueAsDouble(std::pair, std::vector> const& variableValues) const { + virtual double getValueAsDouble(std::pair, std::vector> const* variableValues) const { if (!defined) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " << "Double constant '" << this->getConstantName() << "' is undefined."; diff --git a/src/ir/expressions/DoubleLiteral.h b/src/ir/expressions/DoubleLiteral.h index 2679a7a5d..4963ff9c2 100644 --- a/src/ir/expressions/DoubleLiteral.h +++ b/src/ir/expressions/DoubleLiteral.h @@ -30,7 +30,7 @@ public: } - virtual double getValueAsDouble(std::pair, std::vector> const& variableValues) const { + virtual double getValueAsDouble(std::pair, std::vector> const* variableValues) const { return value; } diff --git a/src/ir/expressions/IntegerConstantExpression.h b/src/ir/expressions/IntegerConstantExpression.h index 250b085a3..7cb25afd9 100644 --- a/src/ir/expressions/IntegerConstantExpression.h +++ b/src/ir/expressions/IntegerConstantExpression.h @@ -26,7 +26,7 @@ public: } - virtual int_fast64_t getValueAsInt(std::pair, std::vector> const& variableValues) const { + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { if (!defined) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " << "Integer constant '" << this->getConstantName() << "' is undefined."; diff --git a/src/ir/expressions/IntegerLiteral.h b/src/ir/expressions/IntegerLiteral.h index c5cd06119..e5883e358 100644 --- a/src/ir/expressions/IntegerLiteral.h +++ b/src/ir/expressions/IntegerLiteral.h @@ -28,7 +28,7 @@ public: } - virtual int_fast64_t getValueAsInt(std::pair, std::vector> const& variableValues) const { + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { return value; } diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.h b/src/ir/expressions/UnaryBooleanFunctionExpression.h index e0fae6c5b..9a924d7da 100644 --- a/src/ir/expressions/UnaryBooleanFunctionExpression.h +++ b/src/ir/expressions/UnaryBooleanFunctionExpression.h @@ -28,7 +28,7 @@ public: } - virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { + virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { bool resultChild = child->getValueAsBool(variableValues); switch(functionType) { case NOT: return !resultChild; break; diff --git a/src/ir/expressions/UnaryNumericalFunctionExpression.h b/src/ir/expressions/UnaryNumericalFunctionExpression.h index 8b746c1c7..a4498aa08 100644 --- a/src/ir/expressions/UnaryNumericalFunctionExpression.h +++ b/src/ir/expressions/UnaryNumericalFunctionExpression.h @@ -28,7 +28,7 @@ public: } - virtual int_fast64_t getValueAsInt(std::pair, std::vector> const& variableValues) const { + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { if (this->getType() != int_) { BaseExpression::getValueAsInt(variableValues); } @@ -41,7 +41,7 @@ public: } } - virtual double getValueAsDouble(std::pair, std::vector> const& variableValues) const { + virtual double getValueAsDouble(std::pair, std::vector> const* variableValues) const { if (this->getType() != double_) { BaseExpression::getValueAsDouble(variableValues); } diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index 47b2087cd..5ef38313c 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -32,23 +32,33 @@ public: return variableName; } - virtual int_fast64_t getValueAsInt(std::pair, std::vector> const& variableValues) const { + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { if (this->getType() != int_) { BaseExpression::getValueAsInt(variableValues); } - return variableValues.second[index]; + if (variableValues != nullptr) { + return variableValues->second[index]; + } else { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression" + << " involving variables without variable values."; + } } - virtual bool getValueAsBool(std::pair, std::vector> const& variableValues) const { + virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { if (this->getType() != bool_) { BaseExpression::getValueAsBool(variableValues); } - return variableValues.first[index]; + if (variableValues != nullptr) { + return variableValues->first[index]; + } else { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression" + << " involving variables without variable values."; + } } - virtual double getValueAsDouble(std::pair, std::vector> const& variableValues) const { + virtual double getValueAsDouble(std::pair, std::vector> const* variableValues) const { if (this->getType() != double_) { BaseExpression::getValueAsDouble(variableValues); } diff --git a/src/storm.cpp b/src/storm.cpp index b34529d94..35b25459d 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -36,7 +36,8 @@ #include "log4cplus/fileappender.h" #include "src/parser/PrismParser.h" -#include "src/adapters/IntermediateRepresentationAdapter.h" +#include "src/adapters/ExplicitModelAdapter.h" +#include "src/adapters/SymbolicModelAdapter.h" #include "src/exceptions/InvalidSettingsException.h" @@ -245,9 +246,8 @@ int main(const int argc, const char* argv[]) { storm::parser::PrismParser parser; std::shared_ptr program = parser.parseFile("test.input"); - storm::storage::SparseMatrix* result = storm::adapters::IntermediateRepresentationAdapter::toSparseMatrix(*program); - // result->print(); - delete result; + storm::adapters::SymbolicModelAdapter symbolicAdapter; + symbolicAdapter.toMTBDD(*program); cleanUp(); return 0; From 278b425a35710b5d572f79b232b5d06a6bb33394 Mon Sep 17 00:00:00 2001 From: dehnert Date: Sat, 26 Jan 2013 14:05:54 +0100 Subject: [PATCH 024/152] Switched to die example. --- test.input | 105 ++++++++++------------------------------------------- 1 file changed, 20 insertions(+), 85 deletions(-) diff --git a/test.input b/test.input index 522d107da..700951a05 100644 --- a/test.input +++ b/test.input @@ -1,89 +1,24 @@ +// Knuth's model of a fair die using only fair coins dtmc -// probability of forwarding -const double PF = 0.8; -const double notPF = .2; // must be 1-PF -// probability that a crowd member is bad -const double badC = .167; - // probability that a crowd member is good -const double goodC = 0.833; -// Total number of protocol runs to analyze -const int TotalRuns = 5; -// size of the crowd -const int CrowdSize = 10; - -module crowds - // protocol phase - phase: [0..4] init 0; - - // crowd member good (or bad) - good: bool init false; - - // number of protocol runs - runCount: [0..TotalRuns] init 0; - - // observe_i is the number of times the attacker observed crowd member i - observe0: [0..TotalRuns] init 0; - - observe1: [0..TotalRuns] init 0; - - observe2: [0..TotalRuns] init 0; - - observe3: [0..TotalRuns] init 0; - - observe4: [0..TotalRuns] init 0; - - observe5: [0..TotalRuns] init 0; - - observe6: [0..TotalRuns] init 0; - - observe7: [0..TotalRuns] init 0; - - observe8: [0..TotalRuns] init 0; - - observe9: [0..TotalRuns] init 0; - - // the last seen crowd member - lastSeen: [0..CrowdSize - 1] init 0; - - // get the protocol started - [] phase=0 & runCount 1: (phase'=1) & (runCount'=runCount+1) & (lastSeen'=0); - - // decide whether crowd member is good or bad according to given probabilities - [] phase=1 -> goodC : (phase'=2) & (good'=true) + badC : (phase'=2) & (good'=false); - - // if the current member is a good member, update the last seen index (chosen uniformly) - [] phase=2 & good -> 1/10 : (lastSeen'=0) & (phase'=3) + 1/10 : (lastSeen'=1) & (phase'=3) + 1/10 : (lastSeen'=2) & (phase'=3) + 1/10 : (lastSeen'=3) & (phase'=3) + 1/10 : (lastSeen'=4) & (phase'=3) + 1/10 : (lastSeen'=5) & (phase'=3) + 1/10 : (lastSeen'=6) & (phase'=3) + 1/10 : (lastSeen'=7) & (phase'=3) + 1/10 : (lastSeen'=8) & (phase'=3) + 1/10 : (lastSeen'=9) & (phase'=3); - - // if the current member is a bad member, record the most recently seen index - [] phase=2 & !good & lastSeen=0 & observe0 < TotalRuns -> 1: (observe0'=observe0+1) & (phase'=4); - [] phase=2 & !good & lastSeen=1 & observe1 < TotalRuns -> 1: (observe1'=observe1+1) & (phase'=4); - [] phase=2 & !good & lastSeen=2 & observe2 < TotalRuns -> 1: (observe2'=observe2+1) & (phase'=4); - [] phase=2 & !good & lastSeen=3 & observe3 < TotalRuns -> 1: (observe3'=observe3+1) & (phase'=4); - [] phase=2 & !good & lastSeen=4 & observe4 < TotalRuns -> 1: (observe4'=observe4+1) & (phase'=4); - [] phase=2 & !good & lastSeen=5 & observe5 < TotalRuns -> 1: (observe5'=observe5+1) & (phase'=4); - [] phase=2 & !good & lastSeen=6 & observe6 < TotalRuns -> 1: (observe6'=observe6+1) & (phase'=4); - [] phase=2 & !good & lastSeen=7 & observe7 < TotalRuns -> 1: (observe7'=observe7+1) & (phase'=4); - [] phase=2 & !good & lastSeen=8 & observe8 < TotalRuns -> 1: (observe8'=observe8+1) & (phase'=4); - [] phase=2 & !good & lastSeen=9 & observe9 < TotalRuns -> 1: (observe9'=observe9+1) & (phase'=4); - - // good crowd members forward with probability PF and deliver otherwise - [] phase=3 -> PF : (phase'=1) + notPF : (phase'=4); - - // deliver the message and start over - [] phase=4 -> 1: (phase'=0); - +module die + + // local state + s : [0..7] init 0; + // value of the dice + d : [0..6] init 0; + + [] s=0 -> 0.5 : (s'=1) + 0.5 : (s'=2); + [] s=1 -> 0.5 : (s'=3) + 0.5 : (s'=4); + [] s=2 -> 0.5 : (s'=5) + 0.5 : (s'=6); + [] s=3 -> 0.5 : (s'=1) + 0.5 : (s'=7) & (d'=1); + [] s=4 -> 0.5 : (s'=7) & (d'=2) + 0.5 : (s'=7) & (d'=3); + [] s=5 -> 0.5 : (s'=7) & (d'=4) + 0.5 : (s'=7) & (d'=5); + [] s=6 -> 0.5 : (s'=2) + 0.5 : (s'=7) & (d'=6); + [] s=7 -> 1: (s'=7); + endmodule -label "observe0Greater1" = observe0>1; -label "observe1Greater1" = observe1>1; -label "observe2Greater1" = observe2>1; -label "observe3Greater1" = observe3>1; -label "observe4Greater1" = observe4>1; -label "observe5Greater1" = observe5>1; -label "observe6Greater1" = observe6>1; -label "observe7Greater1" = observe7>1; -label "observe8Greater1" = observe8>1; -label "observe9Greater1" = observe9>1; -label "observeIGreater1" = observe1>1|observe2>1|observe3>1|observe4>1|observe5>1|observe6>1|observe7>1|observe8>1|observe9>1; -label "observeOnlyTrueSender" = observe0>1&observe1<=1&observe2<=1&observe3<=1&observe4<=1&observe5<=1&observe6<=1&observe7<=1&observe8<=1&observe9<=1; \ No newline at end of file +rewards "coin_flips" + [] s<7 : 1; +endrewards From 5b0af74fa6c79d6247d4801dbdc5e6a35ca13e54 Mon Sep 17 00:00:00 2001 From: dehnert Date: Sat, 26 Jan 2013 22:47:19 +0100 Subject: [PATCH 025/152] Integrated a few more functions to CUDD which are necessary (PRISM adds them as well). --- resources/3rdparty/cudd-2.5.0/Makefile | 2 +- resources/3rdparty/cudd-2.5.0/cudd/cudd.h | 6 + .../3rdparty/cudd-2.5.0/cudd/cuddAddApply.c | 180 ++++++++++++++++++ 3 files changed, 187 insertions(+), 1 deletion(-) diff --git a/resources/3rdparty/cudd-2.5.0/Makefile b/resources/3rdparty/cudd-2.5.0/Makefile index b1b5f32c8..6c7fbb4d3 100644 --- a/resources/3rdparty/cudd-2.5.0/Makefile +++ b/resources/3rdparty/cudd-2.5.0/Makefile @@ -201,7 +201,7 @@ IDIR = $(DDWDIR)/include INCLUDE = -I$(IDIR) BDIRS = cudd dddmp mtr st util epd obj -DIRS = $(BDIRS) nanotrav +DIRS = $(BDIRS) #------------------------------------------------------------------------ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cudd.h b/resources/3rdparty/cudd-2.5.0/cudd/cudd.h index 4a54f8e05..2493cbae0 100644 --- a/resources/3rdparty/cudd-2.5.0/cudd/cudd.h +++ b/resources/3rdparty/cudd-2.5.0/cudd/cudd.h @@ -786,6 +786,12 @@ extern DdNode * Cudd_addXor (DdManager *dd, DdNode **f, DdNode **g); extern DdNode * Cudd_addXnor (DdManager *dd, DdNode **f, DdNode **g); extern DdNode * Cudd_addMonadicApply (DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f); extern DdNode * Cudd_addLog (DdManager * dd, DdNode * f); +extern DdNode * Cudd_addEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addNotEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addGreaterThan (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addGreaterThanEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addLessThan (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addLessThanEquals (DdManager *dd, DdNode **f, DdNode **g); extern DdNode * Cudd_addFindMax (DdManager *dd, DdNode *f); extern DdNode * Cudd_addFindMin (DdManager *dd, DdNode *f); extern DdNode * Cudd_addIthBit (DdManager *dd, DdNode *f, int bit); diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddApply.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddApply.c index 4ef228a99..9a4d2179d 100644 --- a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddApply.c +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddApply.c @@ -783,7 +783,187 @@ Cudd_addLog( } /* end of Cudd_addLog */ +/**Function******************************************************************** + + Synopsis [1 if f==g; 0 otherwise.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is 1 if f==g; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addEquals( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addEquals */ + + +/**Function******************************************************************** + + Synopsis [1 if f!=g; 0 otherwise.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is 1 if f!=g; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addNotEquals( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ZERO(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ONE(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addNotEquals */ + +/**Function******************************************************************** + + Synopsis [1 if f>g; 0 otherwise.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is 1 if f>g; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addGreaterThan( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ZERO(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F)>cuddV(G)) return (DD_ONE(dd)); else return (DD_ZERO(dd)); + } + return(NULL); + +} /* end of Cudd_addGreaterThan */ + + +/**Function******************************************************************** + + Synopsis [1 if f>=g; 0 otherwise.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is 1 if f>=g; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addGreaterThanEquals( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F)>=cuddV(G)) return (DD_ONE(dd)); else return (DD_ZERO(dd)); + } + return(NULL); + +} /* end of Cudd_addGreaterThanEquals */ + + +/**Function******************************************************************** + + Synopsis [1 if f Date: Sat, 26 Jan 2013 22:49:17 +0100 Subject: [PATCH 026/152] Added singleton utility class for CUDD-based things. Added some first methods to expression classes to generate ADDs, but this should be moved to a separate class implementing the expression visitor pattern. --- src/adapters/SymbolicModelAdapter.h | 115 ++++++++++++++++ src/ir/expressions/BaseExpression.h | 4 + .../BinaryBooleanFunctionExpression.h | 14 ++ .../BinaryNumericalFunctionExpression.h | 16 +++ src/ir/expressions/BinaryRelationExpression.h | 22 ++- .../expressions/BooleanConstantExpression.h | 12 ++ src/ir/expressions/BooleanLiteral.h | 5 + src/ir/expressions/DoubleConstantExpression.h | 10 ++ src/ir/expressions/DoubleLiteral.h | 5 + src/ir/expressions/ExpressionVisitor.h | 44 ++++++ src/ir/expressions/Expressions.h | 9 +- .../expressions/IntegerConstantExpression.h | 10 ++ src/ir/expressions/IntegerLiteral.h | 5 + .../UnaryBooleanFunctionExpression.h | 5 + .../UnaryNumericalFunctionExpression.h | 7 + src/ir/expressions/VariableExpression.h | 26 +++- src/parser/PrismParser.cpp | 2 +- src/storm.cpp | 1 + src/utility/CuddUtility.cpp | 125 ++++++++++++++++++ src/utility/CuddUtility.h | 57 ++++++++ 20 files changed, 487 insertions(+), 7 deletions(-) create mode 100644 src/adapters/SymbolicModelAdapter.h create mode 100644 src/ir/expressions/ExpressionVisitor.h create mode 100644 src/utility/CuddUtility.cpp create mode 100644 src/utility/CuddUtility.h diff --git a/src/adapters/SymbolicModelAdapter.h b/src/adapters/SymbolicModelAdapter.h new file mode 100644 index 000000000..1cdbe7c04 --- /dev/null +++ b/src/adapters/SymbolicModelAdapter.h @@ -0,0 +1,115 @@ +/* + * SymbolicModelAdapter.h + * + * Created on: 25.01.2013 + * Author: Christian Dehnert + */ + +#ifndef STORM_ADAPTERS_SYMBOLICMODELADAPTER_H_ +#define STORM_ADAPTERS_SYMBOLICMODELADAPTER_H_ + +#include "src/exceptions/WrongFileFormatException.h" + +#include "src/utility/CuddUtility.h" +#include "src/ir/expressions/ExpressionVisitor.h" + +#include "cuddObj.hh" +#include + +namespace storm { + +namespace adapters { + +class SymbolicModelAdapter { +public: + + SymbolicModelAdapter() : cuddUtility(storm::utility::cuddUtilityInstance()) { + + } + + void toMTBDD(storm::ir::Program const& program) { + LOG4CPLUS_INFO(logger, "Creating MTBDD representation for probabilistic program."); + createDecisionDiagramVariables(program); + + for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { + storm::ir::Module const& module = program.getModule(i); + + for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { + storm::ir::Command const& command = module.getCommand(j); + + + } + } + + LOG4CPLUS_INFO(logger, "Done creating MTBDD representation for probabilistic program."); + } + +private: + storm::utility::CuddUtility* cuddUtility; + + std::vector allDecisionDiagramVariables; + std::vector allRowDecisionDiagramVariables; + std::vector allColumnDecisionDiagramVariables; + std::vector booleanRowDecisionDiagramVariables; + std::vector integerRowDecisionDiagramVariables; + std::vector booleanColumnDecisionDiagramVariables; + std::vector integerColumnDecisionDiagramVariables; + std::unordered_map> variableToRowDecisionDiagramVariableMap; + std::unordered_map> variableToColumnDecisionDiagramVariableMap; + + void createDecisionDiagramVariables(storm::ir::Program const& program) { + for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { + storm::ir::Module const& module = program.getModule(i); + + for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { + storm::ir::BooleanVariable const& booleanVariable = module.getBooleanVariable(j); + + ADD* newRowDecisionDiagramVariable = cuddUtility->getNewAddVariable(); + variableToRowDecisionDiagramVariableMap[booleanVariable.getName()].push_back(newRowDecisionDiagramVariable); + booleanRowDecisionDiagramVariables.push_back(newRowDecisionDiagramVariable); + allRowDecisionDiagramVariables.push_back(newRowDecisionDiagramVariable); + allDecisionDiagramVariables.push_back(newRowDecisionDiagramVariable); + + ADD* newColumnDecisionDiagramVariable = cuddUtility->getNewAddVariable(); + variableToColumnDecisionDiagramVariableMap[booleanVariable.getName()].push_back(newColumnDecisionDiagramVariable); + booleanColumnDecisionDiagramVariables.push_back(newColumnDecisionDiagramVariable); + allColumnDecisionDiagramVariables.push_back(newColumnDecisionDiagramVariable); + allDecisionDiagramVariables.push_back(newColumnDecisionDiagramVariable); + } + + for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) { + storm::ir::IntegerVariable const& integerVariable = module.getIntegerVariable(j); + uint_fast64_t integerRange = integerVariable.getUpperBound()->getValueAsInt(nullptr) - integerVariable.getLowerBound()->getValueAsInt(nullptr); + if (integerRange <= 0) { + throw storm::exceptions::WrongFileFormatException() << "Range of variable " + << integerVariable.getName() << " is empty or negativ."; + } + uint_fast64_t numberOfDecisionDiagramVariables = static_cast(std::ceil(std::log2(integerRange))); + + std::vector allRowDecisionDiagramVariablesForVariable; + std::vector allColumnDecisionDiagramVariablesForVariable; + for (uint_fast64_t k = 0; k < numberOfDecisionDiagramVariables; ++k) { + ADD* newRowDecisionDiagramVariable = cuddUtility->getNewAddVariable(); + allRowDecisionDiagramVariablesForVariable.push_back(newRowDecisionDiagramVariable); + integerRowDecisionDiagramVariables.push_back(newRowDecisionDiagramVariable); + allRowDecisionDiagramVariables.push_back(newRowDecisionDiagramVariable); + allDecisionDiagramVariables.push_back(newRowDecisionDiagramVariable); + + ADD* newColumnDecisionDiagramVariable = cuddUtility->getNewAddVariable(); + allColumnDecisionDiagramVariablesForVariable.push_back(newColumnDecisionDiagramVariable); + integerColumnDecisionDiagramVariables.push_back(newColumnDecisionDiagramVariable); + allColumnDecisionDiagramVariables.push_back(newColumnDecisionDiagramVariable); + allDecisionDiagramVariables.push_back(newColumnDecisionDiagramVariable); + } + variableToRowDecisionDiagramVariableMap[integerVariable.getName()] = allRowDecisionDiagramVariablesForVariable; + variableToColumnDecisionDiagramVariableMap[integerVariable.getName()] = allColumnDecisionDiagramVariablesForVariable; + } + } + } +}; + +} // namespace adapters + +} // namespace storm + +#endif /* STORM_ADAPTERS_SYMBOLICMODELADAPTER_H_ */ diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h index 27704b64b..8324f372a 100644 --- a/src/ir/expressions/BaseExpression.h +++ b/src/ir/expressions/BaseExpression.h @@ -11,6 +11,8 @@ #include "src/exceptions/ExpressionEvaluationException.h" #include "src/exceptions/NotImplementedException.h" +#include "src/utility/CuddUtility.h" + #include #include @@ -64,6 +66,8 @@ public: << this->getTypeName() << " because evaluation implementation is missing."; } + virtual ADD* toAdd() const = 0; + virtual std::string toString() const = 0; std::string getTypeName() const { diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.h b/src/ir/expressions/BinaryBooleanFunctionExpression.h index c7b5a0bdc..9c54362c2 100644 --- a/src/ir/expressions/BinaryBooleanFunctionExpression.h +++ b/src/ir/expressions/BinaryBooleanFunctionExpression.h @@ -10,6 +10,8 @@ #include "src/ir/expressions/BaseExpression.h" +#include "src/utility/CuddUtility.h" + #include #include @@ -42,6 +44,18 @@ public: } } + virtual ADD* toAdd() const { + ADD* leftAdd = left->toAdd(); + ADD* rightAdd = right->toAdd(); + + switch(functionType) { + case AND: return new ADD(leftAdd->Times(*rightAdd)); break; + case OR: return new ADD(leftAdd->Plus(*rightAdd)); break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown boolean binary operator: '" << functionType << "'."; + } + } + virtual std::string toString() const { std::stringstream result; result << left->toString(); diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h index 0d710e785..b2dd12e9c 100644 --- a/src/ir/expressions/BinaryNumericalFunctionExpression.h +++ b/src/ir/expressions/BinaryNumericalFunctionExpression.h @@ -10,6 +10,8 @@ #include "src/ir/expressions/BaseExpression.h" +#include "src/utility/CuddUtility.h" + namespace storm { namespace ir { @@ -62,6 +64,20 @@ public: } } + virtual ADD* toAdd() const { + ADD* leftAdd = left->toAdd(); + ADD* rightAdd = right->toAdd(); + + switch(functionType) { + case PLUS: return new ADD(leftAdd->Plus(*rightAdd)); break; + case MINUS: return new ADD(leftAdd->Minus(*rightAdd)); break; + case TIMES: return new ADD(leftAdd->Times(*rightAdd)); break; + case DIVIDE: return new ADD(leftAdd->Divide(*rightAdd)); break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown boolean binary operator: '" << functionType << "'."; + } + } + virtual std::string toString() const { std::string result = left->toString(); switch (functionType) { diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h index 83556fa8f..02907dfc5 100644 --- a/src/ir/expressions/BinaryRelationExpression.h +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -10,6 +10,8 @@ #include "src/ir/expressions/BaseExpression.h" +#include "src/utility/CuddUtility.h" + namespace storm { namespace ir { @@ -18,7 +20,7 @@ namespace expressions { class BinaryRelationExpression : public BaseExpression { public: - enum RelationType {EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL}; + enum RelationType {EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL}; BinaryRelationExpression(std::shared_ptr left, std::shared_ptr right, RelationType relationType) : BaseExpression(bool_), left(left), right(right), relationType(relationType) { @@ -33,6 +35,7 @@ public: int_fast64_t resultRight = right->getValueAsInt(variableValues); switch(relationType) { case EQUAL: return resultLeft == resultRight; break; + case NOT_EQUAL: return resultLeft != resultRight; break; case LESS: return resultLeft < resultRight; break; case LESS_OR_EQUAL: return resultLeft <= resultRight; break; case GREATER: return resultLeft > resultRight; break; @@ -42,10 +45,27 @@ public: } } + virtual ADD* toAdd() const { + ADD* leftAdd = left->toAdd(); + ADD* rightAdd = right->toAdd(); + + switch(relationType) { + case EQUAL: return new ADD(leftAdd->Equals(*rightAdd)); break; + case NOT_EQUAL: return new ADD(leftAdd->NotEquals(*rightAdd)); break; + case LESS: return new ADD(leftAdd->LessThan(*rightAdd)); break; + case LESS_OR_EQUAL: return new ADD(leftAdd->LessThanOrEqual(*rightAdd)); break; + case GREATER: return new ADD(leftAdd->GreaterThan(*rightAdd)); break; + case GREATER_OR_EQUAL: return new ADD(leftAdd->GreaterThanOrEqual(*rightAdd)); break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown boolean binary operator: '" << relationType << "'."; + } + } + virtual std::string toString() const { std::string result = left->toString(); switch (relationType) { case EQUAL: result += " = "; break; + case NOT_EQUAL: result += " != "; break; case LESS: result += " < "; break; case LESS_OR_EQUAL: result += " <= "; break; case GREATER: result += " > "; break; diff --git a/src/ir/expressions/BooleanConstantExpression.h b/src/ir/expressions/BooleanConstantExpression.h index c4a168838..b16cd5ad7 100644 --- a/src/ir/expressions/BooleanConstantExpression.h +++ b/src/ir/expressions/BooleanConstantExpression.h @@ -10,6 +10,8 @@ #include "ConstantExpression.h" +#include "src/utility/CuddUtility.h" + #include namespace storm { @@ -38,6 +40,16 @@ public: } } + virtual ADD* toAdd() const { + if (!defined) { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Boolean constant '" << this->getConstantName() << "' is undefined."; + } + + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + return new ADD(*cuddUtility->getConstant(value ? 1 : 0)); + } + virtual std::string toString() const { std::string result = this->constantName; if (defined) { diff --git a/src/ir/expressions/BooleanLiteral.h b/src/ir/expressions/BooleanLiteral.h index 55027d6cc..6b92e4b7b 100644 --- a/src/ir/expressions/BooleanLiteral.h +++ b/src/ir/expressions/BooleanLiteral.h @@ -32,6 +32,11 @@ public: return value; } + virtual ADD* toAdd() const { + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + return new ADD(*cuddUtility->getConstant(value ? 1 : 0)); + } + virtual std::string toString() const { if (value) { return std::string("true"); diff --git a/src/ir/expressions/DoubleConstantExpression.h b/src/ir/expressions/DoubleConstantExpression.h index 573aeffd3..9e3471f19 100644 --- a/src/ir/expressions/DoubleConstantExpression.h +++ b/src/ir/expressions/DoubleConstantExpression.h @@ -35,6 +35,16 @@ public: } } + virtual ADD* toAdd() const { + if (!defined) { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Double constant '" << this->getConstantName() << "' is undefined."; + } + + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + return new ADD(*cuddUtility->getConstant(value)); + } + virtual std::string toString() const { std::string result = this->constantName; if (defined) { diff --git a/src/ir/expressions/DoubleLiteral.h b/src/ir/expressions/DoubleLiteral.h index 4963ff9c2..1f447f7fb 100644 --- a/src/ir/expressions/DoubleLiteral.h +++ b/src/ir/expressions/DoubleLiteral.h @@ -34,6 +34,11 @@ public: return value; } + virtual ADD* toAdd() const { + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + return new ADD(*cuddUtility->getConstant(value)); + } + virtual std::string toString() const { return boost::lexical_cast(value); } diff --git a/src/ir/expressions/ExpressionVisitor.h b/src/ir/expressions/ExpressionVisitor.h new file mode 100644 index 000000000..7fc05b79b --- /dev/null +++ b/src/ir/expressions/ExpressionVisitor.h @@ -0,0 +1,44 @@ +/* + * ExpressionVisitor.h + * + * Created on: 26.01.2013 + * Author: Christian Dehnert + */ + +#ifndef STORM_IR_EXPRESSIONS_EXPRESSIONVISITOR_H_ +#define STORM_IR_EXPRESSIONS_EXPRESSIONVISITOR_H_ + +#include "Expressions.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class ExpressionVisitor { +public: + virtual void visit(BaseExpression expression) = 0; + virtual void visit(BinaryBooleanFunctionExpression expression) = 0; + virtual void visit(BinaryNumericalFunctionExpression expression) = 0; + virtual void visit(BinaryRelationExpression expression) = 0; + virtual void visit(BooleanConstantExpression expression) = 0; + virtual void visit(BooleanLiteral expression) = 0; + virtual void visit(ConstantExpression expression) = 0; + virtual void visit(DoubleConstantExpression expression) = 0; + virtual void visit(DoubleLiteral expression) = 0; + virtual void visit(IntegerConstantExpression expression) = 0; + virtual void visit(IntegerLiteral expression) = 0; + virtual void visit(UnaryBooleanFunctionExpression expression) = 0; + virtual void visit(UnaryNumericalFunctionExpression expression) = 0; + virtual void visit(VariableExpression expression) = 0; +}; + +} // namespace expressions + +} // namespace ir + +} // namespace storm + + +#endif /* STORM_IR_EXPRESSIONS_EXPRESSIONVISITOR_H_ */ diff --git a/src/ir/expressions/Expressions.h b/src/ir/expressions/Expressions.h index b52474459..0de025b9f 100644 --- a/src/ir/expressions/Expressions.h +++ b/src/ir/expressions/Expressions.h @@ -2,11 +2,11 @@ * Expressions.h * * Created on: 03.01.2013 - * Author: chris + * Author: Christian Dehnert */ -#ifndef EXPRESSIONS_H_ -#define EXPRESSIONS_H_ +#ifndef STORM_IR_EXPRESSIONS_EXPRESSIONS_H_ +#define STORM_IR_EXPRESSIONS_EXPRESSIONS_H_ #include "BaseExpression.h" #include "BinaryBooleanFunctionExpression.h" @@ -18,8 +18,9 @@ #include "UnaryBooleanFunctionExpression.h" #include "UnaryNumericalFunctionExpression.h" #include "VariableExpression.h" +#include "ConstantExpression.h" #include "BooleanConstantExpression.h" #include "IntegerConstantExpression.h" #include "DoubleConstantExpression.h" -#endif /* EXPRESSIONS_H_ */ +#endif /* STORM_IR_EXPRESSIONS_EXPRESSIONS_H_ */ diff --git a/src/ir/expressions/IntegerConstantExpression.h b/src/ir/expressions/IntegerConstantExpression.h index 7cb25afd9..615aa2adf 100644 --- a/src/ir/expressions/IntegerConstantExpression.h +++ b/src/ir/expressions/IntegerConstantExpression.h @@ -35,6 +35,16 @@ public: } } + virtual ADD* toAdd() const { + if (!defined) { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Integer constant '" << this->getConstantName() << "' is undefined."; + } + + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + return new ADD(*cuddUtility->getConstant(value)); + } + virtual std::string toString() const { std::string result = this->constantName; if (defined) { diff --git a/src/ir/expressions/IntegerLiteral.h b/src/ir/expressions/IntegerLiteral.h index e5883e358..6399813c3 100644 --- a/src/ir/expressions/IntegerLiteral.h +++ b/src/ir/expressions/IntegerLiteral.h @@ -32,6 +32,11 @@ public: return value; } + virtual ADD* toAdd() const { + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + return new ADD(*cuddUtility->getConstant(value)); + } + virtual std::string toString() const { return boost::lexical_cast(value); } diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.h b/src/ir/expressions/UnaryBooleanFunctionExpression.h index 9a924d7da..2322a323b 100644 --- a/src/ir/expressions/UnaryBooleanFunctionExpression.h +++ b/src/ir/expressions/UnaryBooleanFunctionExpression.h @@ -37,6 +37,11 @@ public: } } + virtual ADD* toAdd() const { + ADD* childResult = child->toAdd(); + return new ADD(~(*childResult)); + } + virtual std::string toString() const { std::string result = ""; switch (functionType) { diff --git a/src/ir/expressions/UnaryNumericalFunctionExpression.h b/src/ir/expressions/UnaryNumericalFunctionExpression.h index a4498aa08..3ab8fe355 100644 --- a/src/ir/expressions/UnaryNumericalFunctionExpression.h +++ b/src/ir/expressions/UnaryNumericalFunctionExpression.h @@ -54,6 +54,13 @@ public: } } + virtual ADD* toAdd() const { + ADD* childResult = child->toAdd(); + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + ADD* result = cuddUtility->getConstant(0); + return new ADD(result->Minus(*childResult)); + } + virtual std::string toString() const { std::string result = ""; switch (functionType) { diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index 5ef38313c..87374f080 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -10,6 +10,7 @@ #include "src/ir/expressions/BaseExpression.h" +#include #include namespace storm { @@ -20,7 +21,11 @@ namespace expressions { class VariableExpression : public BaseExpression { public: - VariableExpression(ReturnType type, uint_fast64_t index, std::string variableName) : BaseExpression(type), index(index), variableName(variableName) { + VariableExpression(ReturnType type, uint_fast64_t index, std::string variableName, + std::shared_ptr lowerBound = std::shared_ptr(nullptr), + std::shared_ptr upperBound = std::shared_ptr(nullptr)) + : BaseExpression(type), index(index), variableName(variableName), + lowerBound(lowerBound), upperBound(upperBound) { } @@ -67,9 +72,28 @@ public: << " variable '" << variableName << "' of type double."; } + virtual ADD* toAdd() const { + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + + return nullptr; + + if (this->getType() == bool_) { + ADD* result = cuddUtility->getConstant(0); + //cuddUtility->addValueForEncodingOfConstant(result, 1, ) + } else { + int64_t low = lowerBound->getValueAsInt(nullptr); + int64_t high = upperBound->getValueAsInt(nullptr); + } + + return new ADD(); + } + private: uint_fast64_t index; std::string variableName; + + std::shared_ptr lowerBound; + std::shared_ptr upperBound; }; } diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 78795388e..19eed26ae 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -188,7 +188,7 @@ struct PrismParser::PrismGrammar : qi::grammar> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextBooleanVariableIndex), phoenix::val(qi::_1), qi::_b)), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextBooleanVariableIndex))), qi::_a = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::bool_, phoenix::ref(nextBooleanVariableIndex), qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localBooleanVariables_.add, qi::_1, qi::_1), phoenix::ref(nextBooleanVariableIndex) = phoenix::ref(nextBooleanVariableIndex) + 1]; booleanVariableDefinition.name("boolean variable declaration"); - integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3, qi::_b)), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextIntegerVariableIndex))), qi::_a = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, phoenix::ref(nextIntegerVariableIndex), qi::_1)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localIntegerVariables_.add, qi::_1, qi::_1), phoenix::ref(nextIntegerVariableIndex) = phoenix::ref(nextIntegerVariableIndex) + 1]; + integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3, qi::_b)), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextIntegerVariableIndex))), qi::_a = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localIntegerVariables_.add, qi::_1, qi::_1), phoenix::ref(nextIntegerVariableIndex) = phoenix::ref(nextIntegerVariableIndex) + 1]; integerVariableDefinition.name("integer variable declaration"); variableDefinition = (booleanVariableDefinition(qi::_r1, qi::_r3) | integerVariableDefinition(qi::_r2, qi::_r4)); variableDefinition.name("variable declaration"); diff --git a/src/storm.cpp b/src/storm.cpp index 35b25459d..b9fd2819f 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -140,6 +140,7 @@ void cleanUp() { if (storm::settings::instance() != nullptr) { delete storm::settings::instance(); } + delete storm::utility::cuddUtilityInstance(); } void testCheckingDie(storm::models::Dtmc& dtmc) { diff --git a/src/utility/CuddUtility.cpp b/src/utility/CuddUtility.cpp new file mode 100644 index 000000000..c9ab7aba6 --- /dev/null +++ b/src/utility/CuddUtility.cpp @@ -0,0 +1,125 @@ +/* + * CuddUtility.cpp + * + * Created on: 26.01.2013 + * Author: Christian Dehnert + */ + +#include "CuddUtility.h" +#include "src/exceptions/InvalidArgumentException.h" + +#include "log4cplus/logger.h" +#include "log4cplus/loggingmacros.h" + +extern log4cplus::Logger logger; + +#include +#include + +namespace storm { + +namespace utility { + +storm::utility::CuddUtility* storm::utility::CuddUtility::instance = nullptr; + +ADD* CuddUtility::getNewAddVariable() { + ADD* result = new ADD(manager.addVar()); + allDecisionDiagramVariables.push_back(result); + return result; +} + +ADD* CuddUtility::getAddVariable(int index) const { + return new ADD(manager.addVar(index)); +} + +ADD* CuddUtility::getConstantEncoding(uint_fast64_t constant, std::vector& variables) const { + if ((constant >> variables.size()) != 0) { + LOG4CPLUS_ERROR(logger, "Cannot create encoding for constant " << constant << " with " + << variables.size() << " variables."); + throw storm::exceptions::InvalidArgumentException() << "Cannot create encoding" + << " for constant " << constant << " with " << variables.size() + << " variables."; + } + + // Determine whether the new ADD will be rooted by the first variable or its complement. + ADD initialNode; + if ((constant & (1 << (variables.size() - 1))) != 0) { + initialNode = *variables[0]; + } else { + initialNode = ~(*variables[0]); + } + ADD* result = new ADD(initialNode); + + // Add (i.e. multiply) the other variables as well according to whether their bit is set or not. + for (uint_fast64_t i = 1; i < variables.size(); ++i) { + if ((constant & (1 << (variables.size() - i - 1))) != 0) { + *result *= *variables[i]; + } else { + *result *= ~(*variables[i]); + } + } + + return result; +} + +ADD* CuddUtility::addValueForEncodingOfConstant(ADD* add, uint_fast64_t constant, std::vector& variables, double value) const { + if ((constant >> variables.size()) != 0) { + LOG4CPLUS_ERROR(logger, "Cannot create encoding for constant " << constant << " with " + << variables.size() << " variables."); + throw storm::exceptions::InvalidArgumentException() << "Cannot create encoding" + << " for constant " << constant << " with " << variables.size() + << " variables."; + } + + // Determine whether the new ADD will be rooted by the first variable or its complement. + ADD initialNode; + if ((constant & (1 << (variables.size() - 1))) != 0) { + initialNode = *variables[0]; + } else { + initialNode = ~(*variables[0]); + } + ADD* encoding = new ADD(initialNode); + + // Add (i.e. multiply) the other variables as well according to whether their bit is set or not. + for (uint_fast64_t i = 1; i < variables.size(); ++i) { + if ((constant & (1 << (variables.size() - i - 1))) != 0) { + *encoding *= *variables[i]; + } else { + *encoding *= ~(*variables[i]); + } + } + + ADD* result = new ADD(add->Ite(manager.constant(value), *add)); + return result; +} + +ADD* CuddUtility::getConstant(double value) const { + return new ADD(manager.constant(value)); +} + +void CuddUtility::dumpDotToFile(ADD* add, std::string filename) const { + std::vector nodes; + nodes.push_back(*add); + + FILE* filePtr; + filePtr = fopen(filename.c_str(), "w"); + manager.DumpDot(nodes, 0, 0, filePtr); + fclose(filePtr); +} + +Cudd const& CuddUtility::getManager() const { + return manager; +} + +CuddUtility* cuddUtilityInstance() { + if (CuddUtility::instance != nullptr) { + CuddUtility::instance = new CuddUtility(); + } + return CuddUtility::instance; +} + +} // namespace utility + +} // namespace storm + + diff --git a/src/utility/CuddUtility.h b/src/utility/CuddUtility.h new file mode 100644 index 000000000..ae2b56bb6 --- /dev/null +++ b/src/utility/CuddUtility.h @@ -0,0 +1,57 @@ +/* + * CuddUtility.h + * + * Created on: 26.01.2013 + * Author: Christian Dehnert + */ + +#ifndef STORM_UTILITY_CUDDUTILITY_H_ +#define STORM_UTILITY_CUDDUTILITY_H_ + +#include "cuddObj.hh" + +namespace storm { + +namespace utility { + +class CuddUtility { +public: + ~CuddUtility() { + for (auto element : allDecisionDiagramVariables) { + delete element; + } + } + + ADD* getNewAddVariable(); + ADD* getAddVariable(int index) const; + + ADD* getConstantEncoding(uint_fast64_t constant, std::vector& variables) const; + + ADD* addValueForEncodingOfConstant(ADD* add, uint_fast64_t constant, std::vector& variables, double value) const; + + ADD* getConstant(double value) const; + + void dumpDotToFile(ADD* add, std::string filename) const; + + Cudd const& getManager() const; + + friend CuddUtility* cuddUtilityInstance(); + +private: + CuddUtility() : manager(0, 0), allDecisionDiagramVariables() { + + } + + Cudd manager; + std::vector allDecisionDiagramVariables; + + static CuddUtility* instance; +}; + +CuddUtility* cuddUtilityInstance(); + +} // namespace utility + +} // namespace storm + +#endif /* STORM_UTILITY_CUDDUTILITY_H_ */ From 4d813999e328458804df26e7df89a7dd0c16b1f1 Mon Sep 17 00:00:00 2001 From: dehnert Date: Sun, 27 Jan 2013 21:48:11 +0100 Subject: [PATCH 027/152] Backup commit. On my way of buidling appropriate BDDs. --- src/adapters/SymbolicExpressionAdapter.h | 231 ++++++++++++++++++ src/adapters/SymbolicModelAdapter.h | 182 +++++++++++++- src/ir/Module.cpp | 22 ++ src/ir/Module.h | 14 ++ src/ir/expressions/BaseExpression.h | 5 +- .../BinaryBooleanFunctionExpression.h | 30 +-- src/ir/expressions/BinaryExpression.h | 44 ++++ .../BinaryNumericalFunctionExpression.h | 36 ++- src/ir/expressions/BinaryRelationExpression.h | 34 +-- .../expressions/BooleanConstantExpression.h | 10 +- src/ir/expressions/BooleanLiteral.h | 5 +- src/ir/expressions/DoubleConstantExpression.h | 10 +- src/ir/expressions/DoubleLiteral.h | 5 +- src/ir/expressions/ExpressionVisitor.h | 43 ++-- .../expressions/IntegerConstantExpression.h | 10 +- src/ir/expressions/IntegerLiteral.h | 5 +- .../UnaryBooleanFunctionExpression.h | 20 +- src/ir/expressions/UnaryExpression.h | 39 +++ .../UnaryNumericalFunctionExpression.h | 24 +- src/ir/expressions/VariableExpression.h | 24 +- src/utility/CuddUtility.cpp | 90 ++++++- src/utility/CuddUtility.h | 12 +- 22 files changed, 735 insertions(+), 160 deletions(-) create mode 100644 src/adapters/SymbolicExpressionAdapter.h create mode 100644 src/ir/expressions/BinaryExpression.h create mode 100644 src/ir/expressions/UnaryExpression.h diff --git a/src/adapters/SymbolicExpressionAdapter.h b/src/adapters/SymbolicExpressionAdapter.h new file mode 100644 index 000000000..2e07bae83 --- /dev/null +++ b/src/adapters/SymbolicExpressionAdapter.h @@ -0,0 +1,231 @@ +/* + * SymbolicExpressionAdapter.h + * + * Created on: 27.01.2013 + * Author: Christian Dehnert + */ + +#ifndef STORM_ADAPTERS_SYMBOLICEXPRESSIONADAPTER_H_ +#define STORM_ADAPTERS_SYMBOLICEXPRESSIONADAPTER_H_ + +#include "src/ir/expressions/ExpressionVisitor.h" +#include "src/exceptions/ExpressionEvaluationException.h" + +#include "cuddObj.hh" + +#include +#include + +namespace storm { + +namespace adapters { + +class SymbolicExpressionAdapter : public storm::ir::expressions::ExpressionVisitor { +public: + SymbolicExpressionAdapter(std::unordered_map>& variableToDecisionDiagramVariableMap) : stack(), variableToDecisionDiagramVariableMap(variableToDecisionDiagramVariableMap) { + + } + + ADD* translateExpression(std::shared_ptr expression) { + expression->accept(this); + return stack.top(); + } + + virtual void visit(storm::ir::expressions::BaseExpression* expression) { + std::cout << expression->toString() << std::endl; + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression " + << " of abstract superclass type."; + } + + virtual void visit(storm::ir::expressions::BinaryBooleanFunctionExpression* expression) { + expression->getLeft()->accept(this); + expression->getRight()->accept(this); + + ADD* rightResult = stack.top(); + stack.pop(); + ADD* leftResult = stack.top(); + stack.pop(); + + switch(expression->getFunctionType()) { + case storm::ir::expressions::BinaryBooleanFunctionExpression::AND: + stack.push(new ADD(leftResult->Times(*rightResult))); + break; + case storm::ir::expressions::BinaryBooleanFunctionExpression::OR: + stack.push(new ADD(leftResult->Plus(*rightResult))); + break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown boolean binary operator: '" << expression->getFunctionType() << "'."; + } + + // delete leftResult; + // delete rightResult; + } + + virtual void visit(storm::ir::expressions::BinaryNumericalFunctionExpression* expression) { + expression->getLeft()->accept(this); + expression->getRight()->accept(this); + + ADD* rightResult = stack.top(); + stack.pop(); + ADD* leftResult = stack.top(); + stack.pop(); + + switch(expression->getFunctionType()) { + case storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS: + stack.push(new ADD(leftResult->Plus(*rightResult))); + break; + case storm::ir::expressions::BinaryNumericalFunctionExpression::MINUS: + stack.push(new ADD(leftResult->Minus(*rightResult))); + break; + case storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES: + stack.push(new ADD(leftResult->Times(*rightResult))); + break; + case storm::ir::expressions::BinaryNumericalFunctionExpression::DIVIDE: + stack.push(new ADD(leftResult->Divide(*rightResult))); + break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown boolean binary operator: '" << expression->getFunctionType() << "'."; + } + } + + virtual void visit(storm::ir::expressions::BinaryRelationExpression* expression) { + expression->getLeft()->accept(this); + expression->getRight()->accept(this); + + ADD* rightResult = stack.top(); + stack.pop(); + ADD* leftResult = stack.top(); + stack.pop(); + + switch(expression->getRelationType()) { + case storm::ir::expressions::BinaryRelationExpression::EQUAL: + stack.push(new ADD(leftResult->Equals(*rightResult))); + break; + case storm::ir::expressions::BinaryRelationExpression::NOT_EQUAL: + stack.push(new ADD(leftResult->NotEquals(*rightResult))); + break; + case storm::ir::expressions::BinaryRelationExpression::LESS: + stack.push(new ADD(leftResult->LessThan(*rightResult))); + break; + case storm::ir::expressions::BinaryRelationExpression::LESS_OR_EQUAL: + stack.push(new ADD(leftResult->LessThanOrEqual(*rightResult))); + break; + case storm::ir::expressions::BinaryRelationExpression::GREATER: + stack.push(new ADD(leftResult->GreaterThan(*rightResult))); + break; + case storm::ir::expressions::BinaryRelationExpression::GREATER_OR_EQUAL: + stack.push(new ADD(leftResult->GreaterThanOrEqual(*rightResult))); + break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown boolean binary operator: '" << expression->getRelationType() << "'."; + } + } + + virtual void visit(storm::ir::expressions::BooleanConstantExpression* expression) { + if (!expression->isDefined()) { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Boolean constant '" << expression->getConstantName() << "' is undefined."; + } + + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + stack.push(new ADD(*cuddUtility->getConstant(expression->getValue() ? 1 : 0))); + } + + virtual void visit(storm::ir::expressions::BooleanLiteral* expression) { + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + stack.push(new ADD(*cuddUtility->getConstant(expression->getValueAsBool(nullptr) ? 1 : 0))); + } + + virtual void visit(storm::ir::expressions::DoubleConstantExpression* expression) { + if (expression->isDefined()) { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Double constant '" << expression->getConstantName() << "' is undefined."; + } + + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + stack.push(new ADD(*cuddUtility->getConstant(expression->getValue()))); + } + + virtual void visit(storm::ir::expressions::DoubleLiteral* expression) { + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + stack.push(new ADD(*cuddUtility->getConstant(expression->getValueAsDouble(nullptr)))); + } + + virtual void visit(storm::ir::expressions::IntegerConstantExpression* expression) { + if (!expression->isDefined()) { + throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Integer constant '" << expression->getConstantName() << "' is undefined."; + } + + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + stack.push(new ADD(*cuddUtility->getConstant(expression->getValue()))); + } + + virtual void visit(storm::ir::expressions::IntegerLiteral* expression) { + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + stack.push(new ADD(*cuddUtility->getConstant(expression->getValueAsInt(nullptr)))); + } + + virtual void visit(storm::ir::expressions::UnaryBooleanFunctionExpression* expression) { + expression->getChild()->accept(this); + + ADD* childResult = stack.top(); + stack.pop(); + + switch (expression->getFunctionType()) { + case storm::ir::expressions::UnaryBooleanFunctionExpression::NOT: + stack.push(new ADD(~(*childResult))); + break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown boolean unary operator: '" << expression->getFunctionType() << "'."; + } + } + + virtual void visit(storm::ir::expressions::UnaryNumericalFunctionExpression* expression) { + expression->getChild()->accept(this); + + ADD* childResult = stack.top(); + stack.pop(); + + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + ADD* result = cuddUtility->getConstant(0); + switch(expression->getFunctionType()) { + case storm::ir::expressions::UnaryNumericalFunctionExpression::MINUS: + stack.push(new ADD(result->Minus(*childResult))); + break; + default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " + << "Unknown numerical unary operator: '" << expression->getFunctionType() << "'."; + } + + } + + virtual void visit(storm::ir::expressions::VariableExpression* expression) { + storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); + + std::vector const& variables = variableToDecisionDiagramVariableMap[expression->getVariableName()]; + + ADD* result = cuddUtility->getConstant(0); + if (expression->getType() == storm::ir::expressions::BaseExpression::bool_) { + cuddUtility->setValueAtIndex(result, 1, variables, 1); + } else { + int64_t low = expression->getLowerBound()->getValueAsInt(nullptr); + int64_t high = expression->getUpperBound()->getValueAsInt(nullptr); + + for (uint_fast64_t i = low; i <= high; ++i) { + cuddUtility->setValueAtIndex(result, i - low, variables, i); + } + } + + stack.push(result); + } + +private: + std::stack stack; + std::unordered_map>& variableToDecisionDiagramVariableMap; +}; + +} // namespace adapters + +} // namespace storm + +#endif /* STORM_ADAPTERS_SYMBOLICEXPRESSIONADAPTER_H_ */ diff --git a/src/adapters/SymbolicModelAdapter.h b/src/adapters/SymbolicModelAdapter.h index 1cdbe7c04..7e8674dae 100644 --- a/src/adapters/SymbolicModelAdapter.h +++ b/src/adapters/SymbolicModelAdapter.h @@ -11,10 +11,11 @@ #include "src/exceptions/WrongFileFormatException.h" #include "src/utility/CuddUtility.h" -#include "src/ir/expressions/ExpressionVisitor.h" +#include "SymbolicExpressionAdapter.h" #include "cuddObj.hh" #include +#include namespace storm { @@ -23,24 +24,99 @@ namespace adapters { class SymbolicModelAdapter { public: - SymbolicModelAdapter() : cuddUtility(storm::utility::cuddUtilityInstance()) { + SymbolicModelAdapter() : cuddUtility(storm::utility::cuddUtilityInstance()), allDecisionDiagramVariables(), + allRowDecisionDiagramVariables(), allColumnDecisionDiagramVariables(), booleanRowDecisionDiagramVariables(), + integerRowDecisionDiagramVariables(), booleanColumnDecisionDiagramVariables(), integerColumnDecisionDiagramVariables(), + variableToRowDecisionDiagramVariableMap(), variableToColumnDecisionDiagramVariableMap(), + variableToIdentityDecisionDiagramMap(), + rowExpressionAdapter(variableToRowDecisionDiagramVariableMap), columnExpressionAdapter(variableToColumnDecisionDiagramVariableMap) { } void toMTBDD(storm::ir::Program const& program) { LOG4CPLUS_INFO(logger, "Creating MTBDD representation for probabilistic program."); createDecisionDiagramVariables(program); + createIdentityDecisionDiagrams(program); + ADD* systemAdd = cuddUtility->getZero(); for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { storm::ir::Module const& module = program.getModule(i); + ADD* moduleAdd = cuddUtility->getZero(); for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { storm::ir::Command const& command = module.getCommand(j); + ADD* commandAdd = cuddUtility->getZero(); + ADD* guard = rowExpressionAdapter.translateExpression(command.getGuard()); + if (*guard != *cuddUtility->getZero()) { + for (uint_fast64_t i = 0; i < command.getNumberOfUpdates(); ++i) { + ADD* updateAdd = cuddUtility->getOne(); + + storm::ir::Update const& update = command.getUpdate(i); + + std::map booleanAssignments = update.getBooleanAssignments(); + for (auto assignmentPair : booleanAssignments) { + ADD* updateExpr = rowExpressionAdapter.translateExpression(assignmentPair.second.getExpression()); + + ADD* temporary = cuddUtility->getZero(); + cuddUtility->setValueAtIndex(temporary, 0, variableToColumnDecisionDiagramVariableMap[assignmentPair.first], 0); + cuddUtility->setValueAtIndex(temporary, 1, variableToColumnDecisionDiagramVariableMap[assignmentPair.first], 1); + + ADD* result = new ADD(*updateExpr * *guard); + result = new ADD(result->Equals(*temporary)); + + *updateAdd = *updateAdd * *result; + } + + std::map integerAssignments = update.getIntegerAssignments(); + for (auto assignmentPair : integerAssignments) { + ADD* updateExpr = rowExpressionAdapter.translateExpression(assignmentPair.second.getExpression()); + + ADD* temporary = cuddUtility->getZero(); + + uint_fast64_t variableIndex = module.getIntegerVariableIndex(assignmentPair.first); + storm::ir::IntegerVariable integerVariable = module.getIntegerVariable(variableIndex); + int_fast64_t low = integerVariable.getLowerBound()->getValueAsInt(nullptr); + int_fast64_t high = integerVariable.getUpperBound()->getValueAsInt(nullptr); + + for (uint_fast64_t i = low; i <= high; ++i) { + cuddUtility->setValueAtIndex(temporary, i - low, variableToColumnDecisionDiagramVariableMap[assignmentPair.first], i); + } + + ADD* result = new ADD(*updateExpr * *guard); + result = new ADD(result->Equals(*temporary)); + *result *= *guard; + + *updateAdd = *updateAdd * *result; + } + for (uint_fast64_t i = 0; i < module.getNumberOfBooleanVariables(); ++i) { + storm::ir::BooleanVariable const& booleanVariable = module.getBooleanVariable(i); + + if (update.getBooleanAssignments().find(booleanVariable.getName()) == update.getBooleanAssignments().end()) { + *updateAdd = *updateAdd * *variableToIdentityDecisionDiagramMap[booleanVariable.getName()]; + } + } + for (uint_fast64_t i = 0; i < module.getNumberOfIntegerVariables(); ++i) { + storm::ir::IntegerVariable const& integerVariable = module.getIntegerVariable(i); + + if (update.getIntegerAssignments().find(integerVariable.getName()) == update.getIntegerAssignments().end()) { + *updateAdd = *updateAdd * *variableToIdentityDecisionDiagramMap[integerVariable.getName()]; + } + } + + *commandAdd += *updateAdd * *cuddUtility->getConstant(update.getLikelihoodExpression()->getValueAsDouble(nullptr)); + } + *moduleAdd += *commandAdd; + } else { + LOG4CPLUS_WARN(logger, "Guard " << command.getGuard()->toString() << " is unsatisfiable."); + } } + *systemAdd += *moduleAdd; } + performReachability(program, systemAdd); + LOG4CPLUS_INFO(logger, "Done creating MTBDD representation for probabilistic program."); } @@ -57,6 +133,108 @@ private: std::unordered_map> variableToRowDecisionDiagramVariableMap; std::unordered_map> variableToColumnDecisionDiagramVariableMap; + std::unordered_map variableToIdentityDecisionDiagramMap; + + SymbolicExpressionAdapter rowExpressionAdapter; + SymbolicExpressionAdapter columnExpressionAdapter; + + ADD* getInitialStateDecisionDiagram(storm::ir::Program const& program) { + ADD* initialStates = cuddUtility->getOne(); + for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { + storm::ir::Module const& module = program.getModule(i); + + for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { + storm::ir::BooleanVariable const& booleanVariable = module.getBooleanVariable(j); + bool initialValue = booleanVariable.getInitialValue()->getValueAsBool(nullptr); + *initialStates *= *cuddUtility->getConstantEncoding(1, variableToRowDecisionDiagramVariableMap[booleanVariable.getName()]); + } + for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) { + storm::ir::IntegerVariable const& integerVariable = module.getIntegerVariable(j); + int_fast64_t initialValue = integerVariable.getInitialValue()->getValueAsInt(nullptr); + int_fast64_t low = integerVariable.getLowerBound()->getValueAsInt(nullptr); + *initialStates *= *cuddUtility->getConstantEncoding(initialValue - low, variableToRowDecisionDiagramVariableMap[integerVariable.getName()]); + } + } + + cuddUtility->dumpDotToFile(initialStates, "initstates.add"); + return initialStates; + } + + void performReachability(storm::ir::Program const& program, ADD* systemAdd) { + cuddUtility->dumpDotToFile(systemAdd, "reachtransold.add"); + ADD* reachableStates = getInitialStateDecisionDiagram(program); + ADD* newReachableStates = reachableStates; + + ADD* rowCube = cuddUtility->getOne(); + for (auto variablePtr : allRowDecisionDiagramVariables) { + *rowCube *= *variablePtr; + } + + bool changed; + int iter = 0; + do { + changed = false; + std::cout << "iter " << ++iter << std::endl; + + *newReachableStates = *reachableStates * *systemAdd; + newReachableStates->ExistAbstract(*rowCube); + + cuddUtility->dumpDotToFile(newReachableStates, "reach1.add"); + + cuddUtility->permuteVariables(newReachableStates, allColumnDecisionDiagramVariables, allRowDecisionDiagramVariables, allDecisionDiagramVariables.size()); + + cuddUtility->dumpDotToFile(newReachableStates, "reach2.add"); + cuddUtility->dumpDotToFile(reachableStates, "reachplus.add"); + *newReachableStates += *reachableStates; + + cuddUtility->dumpDotToFile(newReachableStates, "reach3.add"); + cuddUtility->dumpDotToFile(reachableStates, "reach4.add"); + + if (*newReachableStates != *reachableStates) { + std::cout << "changed ..." << std::endl; + changed = true; + } + *reachableStates = *newReachableStates; + } while (changed); + + *systemAdd *= *reachableStates; + cuddUtility->dumpDotToFile(systemAdd, "reachtrans.add"); + } + + void createIdentityDecisionDiagrams(storm::ir::Program const& program) { + for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { + storm::ir::Module const& module = program.getModule(i); + + for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { + storm::ir::BooleanVariable const& booleanVariable = module.getBooleanVariable(j); + ADD* identity = cuddUtility->getZero(); + cuddUtility->setValueAtIndices(identity, 0, 0, + variableToRowDecisionDiagramVariableMap[booleanVariable.getName()], + variableToColumnDecisionDiagramVariableMap[booleanVariable.getName()], 1); + cuddUtility->setValueAtIndices(identity, 1, 1, + variableToRowDecisionDiagramVariableMap[booleanVariable.getName()], + variableToColumnDecisionDiagramVariableMap[booleanVariable.getName()], 1); + variableToIdentityDecisionDiagramMap[booleanVariable.getName()] = identity; + } + + for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) { + storm::ir::IntegerVariable const& integerVariable = module.getIntegerVariable(j); + + ADD* identity = cuddUtility->getZero(); + + int_fast64_t low = integerVariable.getLowerBound()->getValueAsInt(nullptr); + int_fast64_t high = integerVariable.getUpperBound()->getValueAsInt(nullptr); + + for (uint_fast64_t i = low; i <= high; ++i) { + cuddUtility->setValueAtIndices(identity, i - low, i - low, + variableToRowDecisionDiagramVariableMap[integerVariable.getName()], + variableToColumnDecisionDiagramVariableMap[integerVariable.getName()], 1); + } + variableToIdentityDecisionDiagramMap[integerVariable.getName()] = identity; + } + } + } + void createDecisionDiagramVariables(storm::ir::Program const& program) { for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { storm::ir::Module const& module = program.getModule(i); diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index f76a53b88..d800256c8 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -7,6 +7,8 @@ #include "Module.h" +#include "src/exceptions/InvalidArgumentException.h" + #include namespace storm { @@ -56,6 +58,26 @@ uint_fast64_t Module::getNumberOfCommands() const { return this->commands.size(); } +// Return the index of the variable if it exists and throw exception otherwise. +uint_fast64_t Module::getBooleanVariableIndex(std::string variableName) const { + auto it = booleanVariablesToIndexMap.find(variableName); + if (it != booleanVariablesToIndexMap.end()) { + return it->second; + } + throw storm::exceptions::InvalidArgumentException() << "Cannot retrieve index of unknown " + << "boolean variable " << variableName << "."; +} + +// Return the index of the variable if it exists and throw exception otherwise. +uint_fast64_t Module::getIntegerVariableIndex(std::string variableName) const { + auto it = integerVariablesToIndexMap.find(variableName); + if (it != integerVariablesToIndexMap.end()) { + return it->second; + } + throw storm::exceptions::InvalidArgumentException() << "Cannot retrieve index of unknown " + << "variable " << variableName << "."; +} + // Return the requested command. storm::ir::Command const& Module::getCommand(uint_fast64_t index) const { return this->commands[index]; diff --git a/src/ir/Module.h b/src/ir/Module.h index 0ed2ed010..2c362da41 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -73,6 +73,20 @@ public: */ uint_fast64_t getNumberOfCommands() const; + /*! + * Retrieves the index of the boolean variable with the given name. + * @param variableName the name of the variable whose index to retrieve. + * @returns the index of the boolean variable with the given name. + */ + uint_fast64_t getBooleanVariableIndex(std::string variableName) const; + + /*! + * Retrieves the index of the integer variable with the given name. + * @param variableName the name of the variable whose index to retrieve. + * @returns the index of the integer variable with the given name. + */ + uint_fast64_t getIntegerVariableIndex(std::string variableName) const; + /*! * Retrieves a reference to the command with the given index. * @returns a reference to the command with the given index. diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h index 8324f372a..fae7f270a 100644 --- a/src/ir/expressions/BaseExpression.h +++ b/src/ir/expressions/BaseExpression.h @@ -11,6 +11,7 @@ #include "src/exceptions/ExpressionEvaluationException.h" #include "src/exceptions/NotImplementedException.h" +#include "ExpressionVisitor.h" #include "src/utility/CuddUtility.h" #include @@ -66,7 +67,9 @@ public: << this->getTypeName() << " because evaluation implementation is missing."; } - virtual ADD* toAdd() const = 0; + virtual void accept(ExpressionVisitor* visitor) { + visitor->visit(this); + } virtual std::string toString() const = 0; diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.h b/src/ir/expressions/BinaryBooleanFunctionExpression.h index 9c54362c2..0cf866f74 100644 --- a/src/ir/expressions/BinaryBooleanFunctionExpression.h +++ b/src/ir/expressions/BinaryBooleanFunctionExpression.h @@ -8,7 +8,7 @@ #ifndef STORM_IR_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_ #define STORM_IR_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_ -#include "src/ir/expressions/BaseExpression.h" +#include "src/ir/expressions/BinaryExpression.h" #include "src/utility/CuddUtility.h" @@ -21,11 +21,11 @@ namespace ir { namespace expressions { -class BinaryBooleanFunctionExpression : public BaseExpression { +class BinaryBooleanFunctionExpression : public BinaryExpression { public: enum FunctionType {AND, OR}; - BinaryBooleanFunctionExpression(std::shared_ptr left, std::shared_ptr right, FunctionType functionType) : BaseExpression(bool_), left(left), right(right), functionType(functionType) { + BinaryBooleanFunctionExpression(std::shared_ptr left, std::shared_ptr right, FunctionType functionType) : BinaryExpression(bool_, left, right), functionType(functionType) { } @@ -34,8 +34,8 @@ public: } virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { - bool resultLeft = left->getValueAsBool(variableValues); - bool resultRight = right->getValueAsBool(variableValues); + bool resultLeft = this->getLeft()->getValueAsBool(variableValues); + bool resultRight = this->getRight()->getValueAsBool(variableValues); switch(functionType) { case AND: return resultLeft & resultRight; break; case OR: return resultLeft | resultRight; break; @@ -44,33 +44,27 @@ public: } } - virtual ADD* toAdd() const { - ADD* leftAdd = left->toAdd(); - ADD* rightAdd = right->toAdd(); + FunctionType getFunctionType() const { + return functionType; + } - switch(functionType) { - case AND: return new ADD(leftAdd->Times(*rightAdd)); break; - case OR: return new ADD(leftAdd->Plus(*rightAdd)); break; - default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " - << "Unknown boolean binary operator: '" << functionType << "'."; - } + virtual void accept(ExpressionVisitor* visitor) { + visitor->visit(this); } virtual std::string toString() const { std::stringstream result; - result << left->toString(); + result << this->getLeft()->toString(); switch (functionType) { case AND: result << " & "; break; case OR: result << " | "; break; } - result << right->toString(); + result << this->getRight()->toString(); return result.str(); } private: - std::shared_ptr left; - std::shared_ptr right; FunctionType functionType; }; diff --git a/src/ir/expressions/BinaryExpression.h b/src/ir/expressions/BinaryExpression.h new file mode 100644 index 000000000..03b933c48 --- /dev/null +++ b/src/ir/expressions/BinaryExpression.h @@ -0,0 +1,44 @@ +/* + * BinaryExpression.h + * + * Created on: 27.01.2013 + * Author: Christian Dehnert + */ + +#ifndef STORM_IR_EXPRESSIONS_BINARYEXPRESSION_H_ +#define STORM_IR_EXPRESSIONS_BINARYEXPRESSION_H_ + +#include "BaseExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class BinaryExpression : public BaseExpression { +public: + BinaryExpression(ReturnType type, std::shared_ptr left, std::shared_ptr right) : BaseExpression(type), left(left), right(right) { + + } + + std::shared_ptr const& getLeft() const { + return left; + } + + std::shared_ptr const& getRight() const { + return right; + } + +private: + std::shared_ptr left; + std::shared_ptr right; +}; + +} // namespace expressions + +} // namespace ir + +} // namespace storm + +#endif /* STORM_IR_EXPRESSIONS_BINARYEXPRESSION_H_ */ diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h index b2dd12e9c..539cb3114 100644 --- a/src/ir/expressions/BinaryNumericalFunctionExpression.h +++ b/src/ir/expressions/BinaryNumericalFunctionExpression.h @@ -18,11 +18,11 @@ namespace ir { namespace expressions { -class BinaryNumericalFunctionExpression : public BaseExpression { +class BinaryNumericalFunctionExpression : public BinaryExpression { public: enum FunctionType {PLUS, MINUS, TIMES, DIVIDE}; - BinaryNumericalFunctionExpression(ReturnType type, std::shared_ptr left, std::shared_ptr right, FunctionType functionType) : BaseExpression(type), left(left), right(right), functionType(functionType) { + BinaryNumericalFunctionExpression(ReturnType type, std::shared_ptr left, std::shared_ptr right, FunctionType functionType) : BinaryExpression(type, left, right), functionType(functionType) { } @@ -30,13 +30,17 @@ public: } + FunctionType getFunctionType() const { + return functionType; + } + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { if (this->getType() != int_) { BaseExpression::getValueAsInt(variableValues); } - int_fast64_t resultLeft = left->getValueAsInt(variableValues); - int_fast64_t resultRight = right->getValueAsInt(variableValues); + int_fast64_t resultLeft = this->getLeft()->getValueAsInt(variableValues); + int_fast64_t resultRight = this->getRight()->getValueAsInt(variableValues); switch(functionType) { case PLUS: return resultLeft + resultRight; break; case MINUS: return resultLeft - resultRight; break; @@ -52,8 +56,8 @@ public: BaseExpression::getValueAsDouble(variableValues); } - double resultLeft = left->getValueAsDouble(variableValues); - double resultRight = right->getValueAsDouble(variableValues); + double resultLeft = this->getLeft()->getValueAsDouble(variableValues); + double resultRight = this->getRight()->getValueAsDouble(variableValues); switch(functionType) { case PLUS: return resultLeft + resultRight; break; case MINUS: return resultLeft - resultRight; break; @@ -64,35 +68,23 @@ public: } } - virtual ADD* toAdd() const { - ADD* leftAdd = left->toAdd(); - ADD* rightAdd = right->toAdd(); - - switch(functionType) { - case PLUS: return new ADD(leftAdd->Plus(*rightAdd)); break; - case MINUS: return new ADD(leftAdd->Minus(*rightAdd)); break; - case TIMES: return new ADD(leftAdd->Times(*rightAdd)); break; - case DIVIDE: return new ADD(leftAdd->Divide(*rightAdd)); break; - default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " - << "Unknown boolean binary operator: '" << functionType << "'."; - } + virtual void accept(ExpressionVisitor* visitor) { + visitor->visit(this); } virtual std::string toString() const { - std::string result = left->toString(); + std::string result = this->getLeft()->toString(); switch (functionType) { case PLUS: result += " + "; break; case MINUS: result += " - "; break; case TIMES: result += " * "; break; case DIVIDE: result += " / "; break; } - result += right->toString(); + result += this->getRight()->toString(); return result; } private: - std::shared_ptr left; - std::shared_ptr right; FunctionType functionType; }; diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h index 02907dfc5..d71072b13 100644 --- a/src/ir/expressions/BinaryRelationExpression.h +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -8,7 +8,7 @@ #ifndef BINARYRELATIONEXPRESSION_H_ #define BINARYRELATIONEXPRESSION_H_ -#include "src/ir/expressions/BaseExpression.h" +#include "src/ir/expressions/BinaryExpression.h" #include "src/utility/CuddUtility.h" @@ -18,11 +18,11 @@ namespace ir { namespace expressions { -class BinaryRelationExpression : public BaseExpression { +class BinaryRelationExpression : public BinaryExpression { public: enum RelationType {EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL}; - BinaryRelationExpression(std::shared_ptr left, std::shared_ptr right, RelationType relationType) : BaseExpression(bool_), left(left), right(right), relationType(relationType) { + BinaryRelationExpression(std::shared_ptr left, std::shared_ptr right, RelationType relationType) : BinaryExpression(bool_, left, right), relationType(relationType) { } @@ -31,8 +31,8 @@ public: } virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { - int_fast64_t resultLeft = left->getValueAsInt(variableValues); - int_fast64_t resultRight = right->getValueAsInt(variableValues); + int_fast64_t resultLeft = this->getLeft()->getValueAsInt(variableValues); + int_fast64_t resultRight = this->getRight()->getValueAsInt(variableValues); switch(relationType) { case EQUAL: return resultLeft == resultRight; break; case NOT_EQUAL: return resultLeft != resultRight; break; @@ -45,24 +45,16 @@ public: } } - virtual ADD* toAdd() const { - ADD* leftAdd = left->toAdd(); - ADD* rightAdd = right->toAdd(); + RelationType getRelationType() const { + return relationType; + } - switch(relationType) { - case EQUAL: return new ADD(leftAdd->Equals(*rightAdd)); break; - case NOT_EQUAL: return new ADD(leftAdd->NotEquals(*rightAdd)); break; - case LESS: return new ADD(leftAdd->LessThan(*rightAdd)); break; - case LESS_OR_EQUAL: return new ADD(leftAdd->LessThanOrEqual(*rightAdd)); break; - case GREATER: return new ADD(leftAdd->GreaterThan(*rightAdd)); break; - case GREATER_OR_EQUAL: return new ADD(leftAdd->GreaterThanOrEqual(*rightAdd)); break; - default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " - << "Unknown boolean binary operator: '" << relationType << "'."; - } + virtual void accept(ExpressionVisitor* visitor) { + visitor->visit(this); } virtual std::string toString() const { - std::string result = left->toString(); + std::string result = this->getLeft()->toString(); switch (relationType) { case EQUAL: result += " = "; break; case NOT_EQUAL: result += " != "; break; @@ -71,14 +63,12 @@ public: case GREATER: result += " > "; break; case GREATER_OR_EQUAL: result += " >= "; break; } - result += right->toString(); + result += this->getRight()->toString(); return result; } private: - std::shared_ptr left; - std::shared_ptr right; RelationType relationType; }; diff --git a/src/ir/expressions/BooleanConstantExpression.h b/src/ir/expressions/BooleanConstantExpression.h index b16cd5ad7..9181a5449 100644 --- a/src/ir/expressions/BooleanConstantExpression.h +++ b/src/ir/expressions/BooleanConstantExpression.h @@ -40,14 +40,8 @@ public: } } - virtual ADD* toAdd() const { - if (!defined) { - throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " - << "Boolean constant '" << this->getConstantName() << "' is undefined."; - } - - storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); - return new ADD(*cuddUtility->getConstant(value ? 1 : 0)); + virtual void accept(ExpressionVisitor* visitor) { + visitor->visit(this); } virtual std::string toString() const { diff --git a/src/ir/expressions/BooleanLiteral.h b/src/ir/expressions/BooleanLiteral.h index 6b92e4b7b..04f40285f 100644 --- a/src/ir/expressions/BooleanLiteral.h +++ b/src/ir/expressions/BooleanLiteral.h @@ -32,9 +32,8 @@ public: return value; } - virtual ADD* toAdd() const { - storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); - return new ADD(*cuddUtility->getConstant(value ? 1 : 0)); + virtual void accept(ExpressionVisitor* visitor) { + visitor->visit(this); } virtual std::string toString() const { diff --git a/src/ir/expressions/DoubleConstantExpression.h b/src/ir/expressions/DoubleConstantExpression.h index 9e3471f19..a027afa17 100644 --- a/src/ir/expressions/DoubleConstantExpression.h +++ b/src/ir/expressions/DoubleConstantExpression.h @@ -35,14 +35,8 @@ public: } } - virtual ADD* toAdd() const { - if (!defined) { - throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " - << "Double constant '" << this->getConstantName() << "' is undefined."; - } - - storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); - return new ADD(*cuddUtility->getConstant(value)); + virtual void accept(ExpressionVisitor* visitor) { + visitor->visit(this); } virtual std::string toString() const { diff --git a/src/ir/expressions/DoubleLiteral.h b/src/ir/expressions/DoubleLiteral.h index 1f447f7fb..72c464100 100644 --- a/src/ir/expressions/DoubleLiteral.h +++ b/src/ir/expressions/DoubleLiteral.h @@ -34,9 +34,8 @@ public: return value; } - virtual ADD* toAdd() const { - storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); - return new ADD(*cuddUtility->getConstant(value)); + virtual void accept(ExpressionVisitor* visitor) { + visitor->visit(this); } virtual std::string toString() const { diff --git a/src/ir/expressions/ExpressionVisitor.h b/src/ir/expressions/ExpressionVisitor.h index 7fc05b79b..6a8d9d813 100644 --- a/src/ir/expressions/ExpressionVisitor.h +++ b/src/ir/expressions/ExpressionVisitor.h @@ -8,30 +8,41 @@ #ifndef STORM_IR_EXPRESSIONS_EXPRESSIONVISITOR_H_ #define STORM_IR_EXPRESSIONS_EXPRESSIONVISITOR_H_ -#include "Expressions.h" - namespace storm { namespace ir { namespace expressions { +class BaseExpression; +class BinaryBooleanFunctionExpression; +class BinaryNumericalFunctionExpression; +class BinaryRelationExpression; +class BooleanConstantExpression; +class BooleanLiteral; +class DoubleConstantExpression; +class DoubleLiteral; +class IntegerConstantExpression; +class IntegerLiteral; +class UnaryBooleanFunctionExpression; +class UnaryNumericalFunctionExpression; +class VariableExpression; + class ExpressionVisitor { public: - virtual void visit(BaseExpression expression) = 0; - virtual void visit(BinaryBooleanFunctionExpression expression) = 0; - virtual void visit(BinaryNumericalFunctionExpression expression) = 0; - virtual void visit(BinaryRelationExpression expression) = 0; - virtual void visit(BooleanConstantExpression expression) = 0; - virtual void visit(BooleanLiteral expression) = 0; - virtual void visit(ConstantExpression expression) = 0; - virtual void visit(DoubleConstantExpression expression) = 0; - virtual void visit(DoubleLiteral expression) = 0; - virtual void visit(IntegerConstantExpression expression) = 0; - virtual void visit(IntegerLiteral expression) = 0; - virtual void visit(UnaryBooleanFunctionExpression expression) = 0; - virtual void visit(UnaryNumericalFunctionExpression expression) = 0; - virtual void visit(VariableExpression expression) = 0; + virtual void visit(BaseExpression* expression) = 0; + virtual void visit(BinaryBooleanFunctionExpression* expression) = 0; + virtual void visit(BinaryNumericalFunctionExpression* expression) = 0; + virtual void visit(BinaryRelationExpression* expression) = 0; + virtual void visit(BooleanConstantExpression* expression) = 0; + virtual void visit(BooleanLiteral* expression) = 0; + virtual void visit(DoubleConstantExpression* expression) = 0; + virtual void visit(DoubleLiteral* expression) = 0; + virtual void visit(IntegerConstantExpression* expression) = 0; + virtual void visit(IntegerLiteral* expression) = 0; + virtual void visit(UnaryBooleanFunctionExpression* expression) = 0; + virtual void visit(UnaryNumericalFunctionExpression* expression) = 0; + virtual void visit(VariableExpression* expression) = 0; }; } // namespace expressions diff --git a/src/ir/expressions/IntegerConstantExpression.h b/src/ir/expressions/IntegerConstantExpression.h index 615aa2adf..8c58260f6 100644 --- a/src/ir/expressions/IntegerConstantExpression.h +++ b/src/ir/expressions/IntegerConstantExpression.h @@ -35,14 +35,8 @@ public: } } - virtual ADD* toAdd() const { - if (!defined) { - throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " - << "Integer constant '" << this->getConstantName() << "' is undefined."; - } - - storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); - return new ADD(*cuddUtility->getConstant(value)); + virtual void accept(ExpressionVisitor* visitor) { + visitor->visit(this); } virtual std::string toString() const { diff --git a/src/ir/expressions/IntegerLiteral.h b/src/ir/expressions/IntegerLiteral.h index 6399813c3..a5130bd5e 100644 --- a/src/ir/expressions/IntegerLiteral.h +++ b/src/ir/expressions/IntegerLiteral.h @@ -32,9 +32,8 @@ public: return value; } - virtual ADD* toAdd() const { - storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); - return new ADD(*cuddUtility->getConstant(value)); + virtual void accept(ExpressionVisitor* visitor) { + visitor->visit(this); } virtual std::string toString() const { diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.h b/src/ir/expressions/UnaryBooleanFunctionExpression.h index 2322a323b..26b448548 100644 --- a/src/ir/expressions/UnaryBooleanFunctionExpression.h +++ b/src/ir/expressions/UnaryBooleanFunctionExpression.h @@ -8,7 +8,7 @@ #ifndef UNARYBOOLEANFUNCTIONEXPRESSION_H_ #define UNARYBOOLEANFUNCTIONEXPRESSION_H_ -#include "src/ir/expressions/BaseExpression.h" +#include "src/ir/expressions/UnaryExpression.h" namespace storm { @@ -16,11 +16,11 @@ namespace ir { namespace expressions { -class UnaryBooleanFunctionExpression : public BaseExpression { +class UnaryBooleanFunctionExpression : public UnaryExpression { public: enum FunctionType {NOT}; - UnaryBooleanFunctionExpression(std::shared_ptr child, FunctionType functionType) : BaseExpression(bool_), child(child), functionType(functionType) { + UnaryBooleanFunctionExpression(std::shared_ptr child, FunctionType functionType) : UnaryExpression(bool_, child), functionType(functionType) { } @@ -28,8 +28,12 @@ public: } + FunctionType getFunctionType() const { + return functionType; + } + virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { - bool resultChild = child->getValueAsBool(variableValues); + bool resultChild = this->getChild()->getValueAsBool(variableValues); switch(functionType) { case NOT: return !resultChild; break; default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " @@ -37,9 +41,8 @@ public: } } - virtual ADD* toAdd() const { - ADD* childResult = child->toAdd(); - return new ADD(~(*childResult)); + virtual void accept(ExpressionVisitor* visitor) { + visitor->visit(this); } virtual std::string toString() const { @@ -47,13 +50,12 @@ public: switch (functionType) { case NOT: result += "!"; break; } - result += child->toString(); + result += this->getChild()->toString(); return result; } private: - std::shared_ptr child; FunctionType functionType; }; diff --git a/src/ir/expressions/UnaryExpression.h b/src/ir/expressions/UnaryExpression.h new file mode 100644 index 000000000..177b5593e --- /dev/null +++ b/src/ir/expressions/UnaryExpression.h @@ -0,0 +1,39 @@ +/* + * UnaryExpression.h + * + * Created on: 27.01.2013 + * Author: Christian Dehnert + */ + +#ifndef STORM_IR_EXPRESSIONS_UNARYEXPRESSION_H_ +#define STORM_IR_EXPRESSIONS_UNARYEXPRESSION_H_ + +#include "BaseExpression.h" + +namespace storm { + +namespace ir { + +namespace expressions { + +class UnaryExpression : public BaseExpression { +public: + UnaryExpression(ReturnType type, std::shared_ptr child) : BaseExpression(type), child(child) { + + } + + std::shared_ptr const& getChild() const { + return child; + } + +private: + std::shared_ptr child; +}; + +} // namespace expressions + +} // namespace ir + +} // namespace storm + +#endif /* STORM_IR_EXPRESSIONS_UNARYEXPRESSION_H_ */ diff --git a/src/ir/expressions/UnaryNumericalFunctionExpression.h b/src/ir/expressions/UnaryNumericalFunctionExpression.h index 3ab8fe355..2a1f02125 100644 --- a/src/ir/expressions/UnaryNumericalFunctionExpression.h +++ b/src/ir/expressions/UnaryNumericalFunctionExpression.h @@ -8,7 +8,7 @@ #ifndef UNARYFUNCTIONEXPRESSION_H_ #define UNARYFUNCTIONEXPRESSION_H_ -#include "src/ir/expressions/BaseExpression.h" +#include "src/ir/expressions/UnaryExpression.h" namespace storm { @@ -16,11 +16,11 @@ namespace ir { namespace expressions { -class UnaryNumericalFunctionExpression : public BaseExpression { +class UnaryNumericalFunctionExpression : public UnaryExpression { public: enum FunctionType {MINUS}; - UnaryNumericalFunctionExpression(ReturnType type, std::shared_ptr child, FunctionType functionType) : BaseExpression(type), child(child), functionType(functionType) { + UnaryNumericalFunctionExpression(ReturnType type, std::shared_ptr child, FunctionType functionType) : UnaryExpression(type, child), functionType(functionType) { } @@ -33,7 +33,7 @@ public: BaseExpression::getValueAsInt(variableValues); } - int_fast64_t resultChild = child->getValueAsInt(variableValues); + int_fast64_t resultChild = this->getChild()->getValueAsInt(variableValues); switch(functionType) { case MINUS: return -resultChild; break; default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " @@ -46,7 +46,7 @@ public: BaseExpression::getValueAsDouble(variableValues); } - double resultChild = child->getValueAsDouble(variableValues); + double resultChild = this->getChild()->getValueAsDouble(variableValues); switch(functionType) { case MINUS: return -resultChild; break; default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " @@ -54,11 +54,12 @@ public: } } - virtual ADD* toAdd() const { - ADD* childResult = child->toAdd(); - storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); - ADD* result = cuddUtility->getConstant(0); - return new ADD(result->Minus(*childResult)); + FunctionType getFunctionType() const { + return functionType; + } + + virtual void accept(ExpressionVisitor* visitor) { + visitor->visit(this); } virtual std::string toString() const { @@ -66,13 +67,12 @@ public: switch (functionType) { case MINUS: result += "-"; break; } - result += child->toString(); + result += this->getChild()->toString(); return result; } private: - std::shared_ptr child; FunctionType functionType; }; diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index 87374f080..1b9dfd46b 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -33,6 +33,10 @@ public: } + virtual void accept(ExpressionVisitor* visitor) { + visitor->visit(this); + } + virtual std::string toString() const { return variableName; } @@ -72,20 +76,16 @@ public: << " variable '" << variableName << "' of type double."; } - virtual ADD* toAdd() const { - storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); - - return nullptr; + std::string const& getVariableName() const { + return variableName; + } - if (this->getType() == bool_) { - ADD* result = cuddUtility->getConstant(0); - //cuddUtility->addValueForEncodingOfConstant(result, 1, ) - } else { - int64_t low = lowerBound->getValueAsInt(nullptr); - int64_t high = upperBound->getValueAsInt(nullptr); - } + std::shared_ptr const& getLowerBound() const { + return lowerBound; + } - return new ADD(); + std::shared_ptr const& getUpperBound() const { + return upperBound; } private: diff --git a/src/utility/CuddUtility.cpp b/src/utility/CuddUtility.cpp index c9ab7aba6..ec9726b18 100644 --- a/src/utility/CuddUtility.cpp +++ b/src/utility/CuddUtility.cpp @@ -32,7 +32,15 @@ ADD* CuddUtility::getAddVariable(int index) const { return new ADD(manager.addVar(index)); } -ADD* CuddUtility::getConstantEncoding(uint_fast64_t constant, std::vector& variables) const { +ADD* CuddUtility::getOne() const { + return new ADD(manager.addOne()); +} + +ADD* CuddUtility::getZero() const { + return new ADD(manager.addZero()); +} + +ADD* CuddUtility::getConstantEncoding(uint_fast64_t constant, std::vector const& variables) const { if ((constant >> variables.size()) != 0) { LOG4CPLUS_ERROR(logger, "Cannot create encoding for constant " << constant << " with " << variables.size() << " variables."); @@ -62,18 +70,18 @@ ADD* CuddUtility::getConstantEncoding(uint_fast64_t constant, std::vector& return result; } -ADD* CuddUtility::addValueForEncodingOfConstant(ADD* add, uint_fast64_t constant, std::vector& variables, double value) const { - if ((constant >> variables.size()) != 0) { - LOG4CPLUS_ERROR(logger, "Cannot create encoding for constant " << constant << " with " +void CuddUtility::setValueAtIndex(ADD* add, uint_fast64_t index, std::vector const& variables, double value) const { + if ((index >> variables.size()) != 0) { + LOG4CPLUS_ERROR(logger, "Cannot create encoding for index " << index << " with " << variables.size() << " variables."); throw storm::exceptions::InvalidArgumentException() << "Cannot create encoding" - << " for constant " << constant << " with " << variables.size() + << " for index " << index << " with " << variables.size() << " variables."; } // Determine whether the new ADD will be rooted by the first variable or its complement. ADD initialNode; - if ((constant & (1 << (variables.size() - 1))) != 0) { + if ((index & (1 << (variables.size() - 1))) != 0) { initialNode = *variables[0]; } else { initialNode = ~(*variables[0]); @@ -82,21 +90,83 @@ ADD* CuddUtility::addValueForEncodingOfConstant(ADD* add, uint_fast64_t constant // Add (i.e. multiply) the other variables as well according to whether their bit is set or not. for (uint_fast64_t i = 1; i < variables.size(); ++i) { - if ((constant & (1 << (variables.size() - i - 1))) != 0) { + if ((index & (1 << (variables.size() - i - 1))) != 0) { *encoding *= *variables[i]; } else { *encoding *= ~(*variables[i]); } } - ADD* result = new ADD(add->Ite(manager.constant(value), *add)); - return result; + *add = encoding->Ite(manager.constant(value), *add); +} + +void CuddUtility::setValueAtIndices(ADD* add, uint_fast64_t rowIndex, uint_fast64_t columnIndex, std::vector const& rowVariables, std::vector const& columnVariables, double value) const { + if ((rowIndex >> rowVariables.size()) != 0) { + LOG4CPLUS_ERROR(logger, "Cannot create encoding for index " << rowIndex << " with " + << rowVariables.size() << " variables."); + throw storm::exceptions::InvalidArgumentException() << "Cannot create encoding" + << " for index " << rowIndex << " with " << rowVariables.size() + << " variables."; + } + if ((columnIndex >> columnVariables.size()) != 0) { + LOG4CPLUS_ERROR(logger, "Cannot create encoding for index " << columnIndex << " with " + << columnVariables.size() << " variables."); + throw storm::exceptions::InvalidArgumentException() << "Cannot create encoding" + << " for index " << columnIndex << " with " << columnVariables.size() + << " variables."; + } + if (rowVariables.size() != columnVariables.size()) { + LOG4CPLUS_ERROR(logger, "Number of variables for indices encodings does not match."); + throw storm::exceptions::InvalidArgumentException() + << "Number of variables for indices encodings does not match."; + } + + ADD initialNode; + if ((rowIndex & (1 << (rowVariables.size() - 1))) != 0) { + initialNode = *rowVariables[0]; + } else { + initialNode = ~(*rowVariables[0]); + } + ADD* encoding = new ADD(initialNode); + if ((columnIndex & (1 << (rowVariables.size() - 1))) != 0) { + *encoding *= *columnVariables[0]; + } else { + *encoding *= ~(*columnVariables[0]); + } + + for (uint_fast64_t i = 1; i < rowVariables.size(); ++i) { + if ((rowIndex & (1 << (rowVariables.size() - i - 1))) != 0) { + *encoding *= *rowVariables[i]; + } else { + *encoding *= ~(*rowVariables[i]); + } + if ((columnIndex & (1 << (columnVariables.size() - i - 1))) != 0) { + *encoding *= *columnVariables[i]; + } else { + *encoding *= ~(*columnVariables[i]); + } + } + + *add = encoding->Ite(manager.constant(value), *add); } + ADD* CuddUtility::getConstant(double value) const { return new ADD(manager.constant(value)); } +void CuddUtility::permuteVariables(ADD* add, std::vector fromVariables, std::vector toVariables, uint_fast64_t totalNumberOfVariables) const { + std::vector permutation; + permutation.resize(totalNumberOfVariables); + for (uint_fast64_t i = 0; i < totalNumberOfVariables; ++i) { + permutation[i] = i; + } + for (uint_fast64_t i = 0; i < fromVariables.size(); ++i) { + permutation[fromVariables[i]->NodeReadIndex()] = toVariables[i]->NodeReadIndex(); + } + add->Permute(&permutation[0]); +} + void CuddUtility::dumpDotToFile(ADD* add, std::string filename) const { std::vector nodes; nodes.push_back(*add); @@ -112,7 +182,7 @@ Cudd const& CuddUtility::getManager() const { } CuddUtility* cuddUtilityInstance() { - if (CuddUtility::instance != nullptr) { + if (CuddUtility::instance == nullptr) { CuddUtility::instance = new CuddUtility(); } return CuddUtility::instance; diff --git a/src/utility/CuddUtility.h b/src/utility/CuddUtility.h index ae2b56bb6..7eb679c82 100644 --- a/src/utility/CuddUtility.h +++ b/src/utility/CuddUtility.h @@ -25,12 +25,18 @@ public: ADD* getNewAddVariable(); ADD* getAddVariable(int index) const; - ADD* getConstantEncoding(uint_fast64_t constant, std::vector& variables) const; + ADD* getOne() const; + ADD* getZero() const; - ADD* addValueForEncodingOfConstant(ADD* add, uint_fast64_t constant, std::vector& variables, double value) const; + ADD* getConstantEncoding(uint_fast64_t constant, std::vector const& variables) const; + + void setValueAtIndex(ADD* add, uint_fast64_t index, std::vector const& variables, double value) const; + void setValueAtIndices(ADD* add, uint_fast64_t rowIndex, uint_fast64_t columnIndex, std::vector const& rowVariables, std::vector const& columnVariables, double value) const; ADD* getConstant(double value) const; + void permuteVariables(ADD* add, std::vector fromVariables, std::vector toVariables, uint_fast64_t totalNumberOfVariables) const; + void dumpDotToFile(ADD* add, std::string filename) const; Cudd const& getManager() const; @@ -38,7 +44,7 @@ public: friend CuddUtility* cuddUtilityInstance(); private: - CuddUtility() : manager(0, 0), allDecisionDiagramVariables() { + CuddUtility() : manager(), allDecisionDiagramVariables() { } From 5f57cbb12a67016d1c9bdace1e4d0560fff475a4 Mon Sep 17 00:00:00 2001 From: dehnert Date: Mon, 28 Jan 2013 19:58:41 +0100 Subject: [PATCH 028/152] Now able to build the BDD for the die example, including the reachability analysis! Booyah --- src/adapters/SymbolicModelAdapter.h | 28 ++++++++++++---------------- src/utility/CuddUtility.cpp | 4 ++-- src/utility/CuddUtility.h | 2 +- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/adapters/SymbolicModelAdapter.h b/src/adapters/SymbolicModelAdapter.h index 7e8674dae..f42d8f873 100644 --- a/src/adapters/SymbolicModelAdapter.h +++ b/src/adapters/SymbolicModelAdapter.h @@ -161,9 +161,13 @@ private: } void performReachability(storm::ir::Program const& program, ADD* systemAdd) { + ADD* systemAdd01 = new ADD(systemAdd->GreaterThan(*cuddUtility->getZero())); + cuddUtility->dumpDotToFile(systemAdd01, "system01.add"); + cuddUtility->dumpDotToFile(systemAdd, "reachtransold.add"); ADD* reachableStates = getInitialStateDecisionDiagram(program); - ADD* newReachableStates = reachableStates; + cuddUtility->dumpDotToFile(reachableStates, "init.add"); + ADD* newReachableStates = new ADD(*reachableStates); ADD* rowCube = cuddUtility->getOne(); for (auto variablePtr : allRowDecisionDiagramVariables) { @@ -174,31 +178,23 @@ private: int iter = 0; do { changed = false; - std::cout << "iter " << ++iter << std::endl; - - *newReachableStates = *reachableStates * *systemAdd; - newReachableStates->ExistAbstract(*rowCube); + *newReachableStates = *reachableStates * *systemAdd01; + newReachableStates = new ADD(newReachableStates->ExistAbstract(*rowCube)); cuddUtility->dumpDotToFile(newReachableStates, "reach1.add"); - cuddUtility->permuteVariables(newReachableStates, allColumnDecisionDiagramVariables, allRowDecisionDiagramVariables, allDecisionDiagramVariables.size()); + newReachableStates = cuddUtility->permuteVariables(newReachableStates, allColumnDecisionDiagramVariables, allRowDecisionDiagramVariables, allDecisionDiagramVariables.size()); - cuddUtility->dumpDotToFile(newReachableStates, "reach2.add"); - cuddUtility->dumpDotToFile(reachableStates, "reachplus.add"); *newReachableStates += *reachableStates; + newReachableStates = new ADD(newReachableStates->GreaterThan(*cuddUtility->getZero())); - cuddUtility->dumpDotToFile(newReachableStates, "reach3.add"); - cuddUtility->dumpDotToFile(reachableStates, "reach4.add"); - - if (*newReachableStates != *reachableStates) { - std::cout << "changed ..." << std::endl; - changed = true; - } + if (*newReachableStates != *reachableStates) changed = true; *reachableStates = *newReachableStates; } while (changed); *systemAdd *= *reachableStates; - cuddUtility->dumpDotToFile(systemAdd, "reachtrans.add"); + std::cout << "got " << systemAdd->nodeCount() << " nodes" << std::endl; + std::cout << "and " << systemAdd->CountMinterm(allRowDecisionDiagramVariables.size() + allColumnDecisionDiagramVariables.size()) << std::endl; } void createIdentityDecisionDiagrams(storm::ir::Program const& program) { diff --git a/src/utility/CuddUtility.cpp b/src/utility/CuddUtility.cpp index ec9726b18..ab3d85797 100644 --- a/src/utility/CuddUtility.cpp +++ b/src/utility/CuddUtility.cpp @@ -155,7 +155,7 @@ ADD* CuddUtility::getConstant(double value) const { return new ADD(manager.constant(value)); } -void CuddUtility::permuteVariables(ADD* add, std::vector fromVariables, std::vector toVariables, uint_fast64_t totalNumberOfVariables) const { +ADD* CuddUtility::permuteVariables(ADD* add, std::vector fromVariables, std::vector toVariables, uint_fast64_t totalNumberOfVariables) const { std::vector permutation; permutation.resize(totalNumberOfVariables); for (uint_fast64_t i = 0; i < totalNumberOfVariables; ++i) { @@ -164,7 +164,7 @@ void CuddUtility::permuteVariables(ADD* add, std::vector fromVariables, st for (uint_fast64_t i = 0; i < fromVariables.size(); ++i) { permutation[fromVariables[i]->NodeReadIndex()] = toVariables[i]->NodeReadIndex(); } - add->Permute(&permutation[0]); + return new ADD(add->Permute(&permutation[0])); } void CuddUtility::dumpDotToFile(ADD* add, std::string filename) const { diff --git a/src/utility/CuddUtility.h b/src/utility/CuddUtility.h index 7eb679c82..8102eb012 100644 --- a/src/utility/CuddUtility.h +++ b/src/utility/CuddUtility.h @@ -35,7 +35,7 @@ public: ADD* getConstant(double value) const; - void permuteVariables(ADD* add, std::vector fromVariables, std::vector toVariables, uint_fast64_t totalNumberOfVariables) const; + ADD* permuteVariables(ADD* add, std::vector fromVariables, std::vector toVariables, uint_fast64_t totalNumberOfVariables) const; void dumpDotToFile(ADD* add, std::string filename) const; From 0a6a0b9fd3257162ca90376f15a49906b44f2a66 Mon Sep 17 00:00:00 2001 From: dehnert Date: Tue, 29 Jan 2013 21:11:23 +0100 Subject: [PATCH 029/152] Eliminated warning of clang by introducing proper getter. --- src/ir/Variable.cpp | 4 ++++ src/ir/Variable.h | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/src/ir/Variable.cpp b/src/ir/Variable.cpp index d051b9ca1..85ae21005 100644 --- a/src/ir/Variable.cpp +++ b/src/ir/Variable.cpp @@ -28,6 +28,10 @@ std::string const& Variable::getName() const { return variableName; } +uint_fast64_t getIndex() const { + return index; +} + // Return the expression for the initial value of the variable. std::shared_ptr const& Variable::getInitialValue() const { return initialValue; diff --git a/src/ir/Variable.h b/src/ir/Variable.h index 2c065a004..6f31280e2 100644 --- a/src/ir/Variable.h +++ b/src/ir/Variable.h @@ -41,6 +41,12 @@ public: */ std::string const& getName() const; + /*! + * Retrieves the index of the variable. + * @returns the index of the variable. + */ + uint_fast64_t getIndex() const; + /*! * Retrieves the expression defining the initial value of the variable. * @returns the expression defining the initial value of the variable. From 777aa3a914f369aadb14d5ace23a8f9468ed92c7 Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 6 Feb 2013 09:53:05 +0100 Subject: [PATCH 030/152] Intermediate commit to switch workplace. --- src/adapters/ExplicitModelAdapter.h | 189 +++++++++++++++------------- src/ir/Program.cpp | 4 + src/ir/Program.h | 6 + src/ir/Variable.cpp | 2 +- src/storm.cpp | 8 +- 5 files changed, 115 insertions(+), 94 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index d056f6849..1c2d9365e 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -17,6 +17,7 @@ #include #include #include +#include typedef std::pair, std::vector> StateType; @@ -52,8 +53,102 @@ public: class ExplicitModelAdapter { public: template - static storm::storage::SparseMatrix* toSparseMatrix(storm::ir::Program const& program) { + std::shared_ptr> toSparseMatrix(storm::ir::Program const& program) { LOG4CPLUS_INFO(logger, "Creating sparse matrix for probabilistic program."); + + this->computeReachableStateSpace(program); + + + + std::shared_ptr> resultMatrix(new storm::storage::SparseMatrix(allStates.size())); + resultMatrix->initialize(totalNumberOfTransitions); + + uint_fast64_t currentIndex = 0; + for (StateType* currentState : allStates) { + bool hasTransition = false; + + // Iterate over all modules. + for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { + storm::ir::Module const& module = program.getModule(i); + + // Iterate over all commands. + for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { + storm::ir::Command const& command = module.getCommand(j); + + // Check if this command is enabled in the current state. + if (command.getGuard()->getValueAsBool(currentState)) { + hasTransition = true; + std::map stateIndexToProbabilityMap; + for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { + storm::ir::Update const& update = command.getUpdate(k); + + StateType* newState = new StateType(*currentState); + + std::map const& booleanAssignmentMap = update.getBooleanAssignments(); + for (auto assignedVariable : booleanAssignmentMap) { + setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(currentState)); + } + std::map const& integerAssignmentMap = update.getIntegerAssignments(); + for (auto assignedVariable : integerAssignmentMap) { + setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(currentState)); + } + + uint_fast64_t targetIndex = (*stateToIndexMap.find(newState)).second; + delete newState; + + auto probIt = stateIndexToProbabilityMap.find(targetIndex); + if (probIt != stateIndexToProbabilityMap.end()) { + stateIndexToProbabilityMap[targetIndex] += update.getLikelihoodExpression()->getValueAsDouble(currentState); + } else { + stateIndexToProbabilityMap[targetIndex] = update.getLikelihoodExpression()->getValueAsDouble(currentState); + } + } + + // Now insert the actual values into the matrix. + for (auto targetIndex : stateIndexToProbabilityMap) { + resultMatrix->addNextValue(currentIndex, targetIndex.first, targetIndex.second); + } + } + } + } + if (!hasTransition) { + resultMatrix->addNextValue(currentIndex, currentIndex, 1); + } + + ++currentIndex; + } + + resultMatrix->finalize(); + + LOG4CPLUS_INFO(logger, "Created sparse matrix with " << allStates.size() << " reachable states and " << totalNumberOfTransitions << " transitions."); + + // Now free all the elements we allocated. + for (auto element : allStates) { + delete element; + } + + return resultMatrix; + } + +private: + static StateType* getNewState(uint_fast64_t numberOfBooleanVariables, uint_fast64_t numberOfIntegerVariables) { + StateType* result = new StateType(); + result->first.resize(numberOfBooleanVariables); + result->second.resize(numberOfIntegerVariables); + return result; + } + + static void setValue(StateType* state, uint_fast64_t index, bool value) { + std::get<0>(*state)[index] = value; + } + + static void setValue(StateType* state, uint_fast64_t index, int_fast64_t value) { + std::get<1>(*state)[index] = value; + } + + void computeReachableStateSpace(storm::ir::Program const& program) { + bool nondeterministicModel = program.getModelType() == storm::ir::Program::MDP || program.getModelType() == storm::ir::Program::CTMDP; + uint_fast64_t numberOfIntegerVariables = 0; uint_fast64_t numberOfBooleanVariables = 0; for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { @@ -132,20 +227,15 @@ public: storm::ir::Update const& update = command.getUpdate(k); StateType* newState = new StateType(*currentState); - // std::cout << "took state: " << newState->first << "/" << newState->second << std::endl; std::map const& booleanAssignmentMap = update.getBooleanAssignments(); for (auto assignedVariable : booleanAssignmentMap) { setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(currentState)); } std::map const& integerAssignmentMap = update.getIntegerAssignments(); for (auto assignedVariable : integerAssignmentMap) { - // std::cout << "evaluting " << assignedVariable.second.getExpression()->toString() << " as " << assignedVariable.second.getExpression()->getValueAsInt(*currentState) << std::endl; setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(currentState)); } - // std::cout << "applied: " << update.toString() << std::endl; - // std::cout << "got: " << newState->first << "/" << newState->second << std::endl; - auto probIt = stateToProbabilityMap.find(newState); if (probIt != stateToProbabilityMap.end()) { stateToProbabilityMap[newState] += update.getLikelihoodExpression()->getValueAsDouble(currentState); @@ -187,92 +277,11 @@ public: } } } - - storm::storage::SparseMatrix* resultMatrix = new storm::storage::SparseMatrix(allStates.size()); - resultMatrix->initialize(totalNumberOfTransitions); - - uint_fast64_t currentIndex = 0; - for (StateType* currentState : allStates) { - bool hasTransition = false; - - // Iterate over all modules. - for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { - storm::ir::Module const& module = program.getModule(i); - - // Iterate over all commands. - for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { - storm::ir::Command const& command = module.getCommand(j); - - // Check if this command is enabled in the current state. - if (command.getGuard()->getValueAsBool(currentState)) { - hasTransition = true; - std::map stateIndexToProbabilityMap; - for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { - storm::ir::Update const& update = command.getUpdate(k); - - StateType* newState = new StateType(*currentState); - - std::map const& booleanAssignmentMap = update.getBooleanAssignments(); - for (auto assignedVariable : booleanAssignmentMap) { - setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(currentState)); - } - std::map const& integerAssignmentMap = update.getIntegerAssignments(); - for (auto assignedVariable : integerAssignmentMap) { - setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(currentState)); - } - - uint_fast64_t targetIndex = (*stateToIndexMap.find(newState)).second; - delete newState; - - auto probIt = stateIndexToProbabilityMap.find(targetIndex); - if (probIt != stateIndexToProbabilityMap.end()) { - stateIndexToProbabilityMap[targetIndex] += update.getLikelihoodExpression()->getValueAsDouble(currentState); - } else { - stateIndexToProbabilityMap[targetIndex] = update.getLikelihoodExpression()->getValueAsDouble(currentState); - } - } - - // Now insert the actual values into the matrix. - for (auto targetIndex : stateIndexToProbabilityMap) { - resultMatrix->addNextValue(currentIndex, targetIndex.first, targetIndex.second); - } - } - } - } - if (!hasTransition) { - resultMatrix->addNextValue(currentIndex, currentIndex, 1); - } - - ++currentIndex; - } - - resultMatrix->finalize(); - - LOG4CPLUS_INFO(logger, "Created sparse matrix with " << allStates.size() << " reachable states and " << totalNumberOfTransitions << " transitions."); - - // Now free all the elements we allocated. - for (auto element : allStates) { - delete element; - } - - return resultMatrix; } -private: - static StateType* getNewState(uint_fast64_t numberOfBooleanVariables, uint_fast64_t numberOfIntegerVariables) { - StateType* result = new StateType(); - result->first.resize(numberOfBooleanVariables); - result->second.resize(numberOfIntegerVariables); - return result; - } - - static void setValue(StateType* state, uint_fast64_t index, bool value) { - std::get<0>(*state)[index] = value; - } - - static void setValue(StateType* state, uint_fast64_t index, int_fast64_t value) { - std::get<1>(*state)[index] = value; - } + std::vector allStates; + uint_fast64_t numberOfTransitions; + std::vector numbersOfNondeterministicChoices; }; } // namespace adapters diff --git a/src/ir/Program.cpp b/src/ir/Program.cpp index e5dfa9ce3..73bb62e9c 100644 --- a/src/ir/Program.cpp +++ b/src/ir/Program.cpp @@ -24,6 +24,10 @@ Program::Program(ModelType modelType, std::mapisSet("test-prctl")) { // storm::parser::PrctlParser parser(s->getString("test-prctl").c_str()); - delete s; return false; } @@ -243,8 +242,11 @@ int main(const int argc, const char* argv[]) { storm::parser::PrismParser parser; std::shared_ptr program = parser.parseFile("test.input"); - storm::adapters::SymbolicModelAdapter symbolicAdapter; - symbolicAdapter.toMTBDD(*program); + + std::shared_ptr> matrix = storm::adapters::ExplicitModelAdapter::toSparseMatrix(*program); + + //storm::adapters::SymbolicModelAdapter symbolicModelAdapter; + //symbolicAdapter.toMTBDD(*program); cleanUp(); return 0; From 34aff4cbd95981ff64f43e1b5fbe8dba17baae0c Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 6 Feb 2013 16:04:27 +0100 Subject: [PATCH 031/152] Added constructor for ExplicitModelAdapter class. --- src/adapters/ExplicitModelAdapter.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 1c2d9365e..b05acaff6 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -52,12 +52,14 @@ public: class ExplicitModelAdapter { public: + ExplicitModelAdapter(storm::ir::Program const& program) : program(program) + template std::shared_ptr> toSparseMatrix(storm::ir::Program const& program) { LOG4CPLUS_INFO(logger, "Creating sparse matrix for probabilistic program."); this->computeReachableStateSpace(program); - + this->buildMatrix(program) std::shared_ptr> resultMatrix(new storm::storage::SparseMatrix(allStates.size())); @@ -279,6 +281,7 @@ private: } } + storm::ir::Program const& program; std::vector allStates; uint_fast64_t numberOfTransitions; std::vector numbersOfNondeterministicChoices; From db01eb92d97e0e0fb4530865fda5d60e613f93d4 Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 6 Feb 2013 19:51:58 +0100 Subject: [PATCH 032/152] Splitted explicit model adapter into several logical functions. --- examples/dtmc/crowds/crowds5_5.pm | 69 +++++++ test.input => examples/dtmc/die/die.pm | 0 src/adapters/ExplicitModelAdapter.h | 256 +++++++++++++++---------- src/ir/Program.cpp | 2 +- src/storm.cpp | 11 +- 5 files changed, 229 insertions(+), 109 deletions(-) create mode 100644 examples/dtmc/crowds/crowds5_5.pm rename test.input => examples/dtmc/die/die.pm (100%) diff --git a/examples/dtmc/crowds/crowds5_5.pm b/examples/dtmc/crowds/crowds5_5.pm new file mode 100644 index 000000000..5ce2bab9c --- /dev/null +++ b/examples/dtmc/crowds/crowds5_5.pm @@ -0,0 +1,69 @@ +dtmc + +// probability of forwarding +const double PF = 0.8; +const double notPF = .2; // must be 1-PF +// probability that a crowd member is bad +const double badC = .167; + // probability that a crowd member is good +const double goodC = 0.833; +// Total number of protocol runs to analyze +const int TotalRuns = 5; +// size of the crowd +const int CrowdSize = 5; + +module crowds + // protocol phase + phase: [0..4] init 0; + + // crowd member good (or bad) + good: bool init false; + + // number of protocol runs + runCount: [0..TotalRuns] init 0; + + // observe_i is the number of times the attacker observed crowd member i + observe0: [0..TotalRuns] init 0; + + observe1: [0..TotalRuns] init 0; + + observe2: [0..TotalRuns] init 0; + + observe3: [0..TotalRuns] init 0; + + observe4: [0..TotalRuns] init 0; + + // the last seen crowd member + lastSeen: [0..CrowdSize - 1] init 0; + + // get the protocol started + [] phase=0 & runCount 1: (phase'=1) & (runCount'=runCount+1) & (lastSeen'=0); + + // decide whether crowd member is good or bad according to given probabilities + [] phase=1 -> goodC : (phase'=2) & (good'=true) + badC : (phase'=2) & (good'=false); + + // if the current member is a good member, update the last seen index (chosen uniformly) + [] phase=2 & good -> 1/5 : (lastSeen'=0) & (phase'=3) + 1/5 : (lastSeen'=1) & (phase'=3) + 1/5 : (lastSeen'=2) & (phase'=3) + 1/5 : (lastSeen'=3) & (phase'=3) + 1/5 : (lastSeen'=4) & (phase'=3); + + // if the current member is a bad member, record the most recently seen index + [] phase=2 & !good & lastSeen=0 & observe0 < TotalRuns -> 1: (observe0'=observe0+1) & (phase'=4); + [] phase=2 & !good & lastSeen=1 & observe1 < TotalRuns -> 1: (observe1'=observe1+1) & (phase'=4); + [] phase=2 & !good & lastSeen=2 & observe2 < TotalRuns -> 1: (observe2'=observe2+1) & (phase'=4); + [] phase=2 & !good & lastSeen=3 & observe3 < TotalRuns -> 1: (observe3'=observe3+1) & (phase'=4); + [] phase=2 & !good & lastSeen=4 & observe4 < TotalRuns -> 1: (observe4'=observe4+1) & (phase'=4); + + // good crowd members forward with probability PF and deliver otherwise + [] phase=3 -> PF : (phase'=1) + notPF : (phase'=4); + + // deliver the message and start over + [] phase=4 -> 1: (phase'=0); + +endmodule + +label "observe0Greater1" = observe0>1; +label "observe1Greater1" = observe1>1; +label "observe2Greater1" = observe2>1; +label "observe3Greater1" = observe3>1; +label "observe4Greater1" = observe4>1; +label "observeIGreater1" = observe1>1|observe2>1|observe3>1|observe4>1; +label "observeOnlyTrueSender" = observe0>1&observe1<=1 & observe2<=1 & observe3<=1 & observe4<=1; \ No newline at end of file diff --git a/test.input b/examples/dtmc/die/die.pm similarity index 100% rename from test.input rename to examples/dtmc/die/die.pm diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 1c2d9365e..40e0fc056 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -52,92 +52,27 @@ public: class ExplicitModelAdapter { public: - template - std::shared_ptr> toSparseMatrix(storm::ir::Program const& program) { - LOG4CPLUS_INFO(logger, "Creating sparse matrix for probabilistic program."); - - this->computeReachableStateSpace(program); - - - - std::shared_ptr> resultMatrix(new storm::storage::SparseMatrix(allStates.size())); - resultMatrix->initialize(totalNumberOfTransitions); - - uint_fast64_t currentIndex = 0; - for (StateType* currentState : allStates) { - bool hasTransition = false; - - // Iterate over all modules. - for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { - storm::ir::Module const& module = program.getModule(i); - - // Iterate over all commands. - for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { - storm::ir::Command const& command = module.getCommand(j); - - // Check if this command is enabled in the current state. - if (command.getGuard()->getValueAsBool(currentState)) { - hasTransition = true; - std::map stateIndexToProbabilityMap; - for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { - storm::ir::Update const& update = command.getUpdate(k); - - StateType* newState = new StateType(*currentState); - - std::map const& booleanAssignmentMap = update.getBooleanAssignments(); - for (auto assignedVariable : booleanAssignmentMap) { - setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(currentState)); - } - std::map const& integerAssignmentMap = update.getIntegerAssignments(); - for (auto assignedVariable : integerAssignmentMap) { - setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(currentState)); - } + ExplicitModelAdapter(std::shared_ptr program) : program(program), allStates(), + stateToIndexMap(), booleanVariables(), integerVariables(), booleanVariableToIndexMap(), + integerVariableToIndexMap(), numberOfTransitions(0) { - uint_fast64_t targetIndex = (*stateToIndexMap.find(newState)).second; - delete newState; - - auto probIt = stateIndexToProbabilityMap.find(targetIndex); - if (probIt != stateIndexToProbabilityMap.end()) { - stateIndexToProbabilityMap[targetIndex] += update.getLikelihoodExpression()->getValueAsDouble(currentState); - } else { - stateIndexToProbabilityMap[targetIndex] = update.getLikelihoodExpression()->getValueAsDouble(currentState); - } - } - - // Now insert the actual values into the matrix. - for (auto targetIndex : stateIndexToProbabilityMap) { - resultMatrix->addNextValue(currentIndex, targetIndex.first, targetIndex.second); - } - } - } - } - if (!hasTransition) { - resultMatrix->addNextValue(currentIndex, currentIndex, 1); - } + } - ++currentIndex; - } + template + std::shared_ptr> toSparseMatrix() { + LOG4CPLUS_INFO(logger, "Creating sparse matrix for probabilistic program."); - resultMatrix->finalize(); + this->computeReachableStateSpace(); + std::shared_ptr> resultMatrix = this->buildMatrix(); - LOG4CPLUS_INFO(logger, "Created sparse matrix with " << allStates.size() << " reachable states and " << totalNumberOfTransitions << " transitions."); + LOG4CPLUS_INFO(logger, "Created sparse matrix with " << resultMatrix->getRowCount() << " reachable states and " << resultMatrix->getNonZeroEntryCount() << " transitions."); - // Now free all the elements we allocated. - for (auto element : allStates) { - delete element; - } + this->clearReachableStateSpace(); return resultMatrix; } private: - static StateType* getNewState(uint_fast64_t numberOfBooleanVariables, uint_fast64_t numberOfIntegerVariables) { - StateType* result = new StateType(); - result->first.resize(numberOfBooleanVariables); - result->second.resize(numberOfIntegerVariables); - return result; - } - static void setValue(StateType* state, uint_fast64_t index, bool value) { std::get<0>(*state)[index] = value; } @@ -146,28 +81,21 @@ private: std::get<1>(*state)[index] = value; } - void computeReachableStateSpace(storm::ir::Program const& program) { - bool nondeterministicModel = program.getModelType() == storm::ir::Program::MDP || program.getModelType() == storm::ir::Program::CTMDP; - + void prepareAuxiliaryDatastructures() { uint_fast64_t numberOfIntegerVariables = 0; uint_fast64_t numberOfBooleanVariables = 0; - for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { - numberOfIntegerVariables += program.getModule(i).getNumberOfIntegerVariables(); - numberOfBooleanVariables += program.getModule(i).getNumberOfBooleanVariables(); + for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { + numberOfIntegerVariables += program->getModule(i).getNumberOfIntegerVariables(); + numberOfBooleanVariables += program->getModule(i).getNumberOfBooleanVariables(); } - std::vector booleanVariables; - std::vector integerVariables; booleanVariables.resize(numberOfBooleanVariables); integerVariables.resize(numberOfIntegerVariables); - std::unordered_map booleanVariableToIndexMap; - std::unordered_map integerVariableToIndexMap; - uint_fast64_t nextBooleanVariableIndex = 0; uint_fast64_t nextIntegerVariableIndex = 0; - for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { - storm::ir::Module const& module = program.getModule(i); + for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { + storm::ir::Module const& module = program->getModule(i); for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { booleanVariables[nextBooleanVariableIndex] = module.getBooleanVariable(j); @@ -180,39 +108,53 @@ private: ++nextIntegerVariableIndex; } } + } + + void computeReachableStateSpace() { + bool nondeterministicModel = program->getModelType() == storm::ir::Program::MDP || program->getModelType() == storm::ir::Program::CTMDP; + + // Prepare some internal data structures, such as mappings from variables to indices and so on. + this->prepareAuxiliaryDatastructures(); - StateType* initialState = getNewState(numberOfBooleanVariables, numberOfIntegerVariables); + // Create a fresh state which can hold as many boolean and integer variables as there are. + StateType* initialState = new StateType(); + initialState->first.resize(booleanVariables.size()); + initialState->second.resize(integerVariables.size()); - for (uint_fast64_t i = 0; i < numberOfBooleanVariables; ++i) { + // Now initialize all fields in the value vectors of the state according to the initial + // values provided by the input program. + for (uint_fast64_t i = 0; i < booleanVariables.size(); ++i) { bool initialValue = booleanVariables[i].getInitialValue()->getValueAsBool(initialState); std::get<0>(*initialState)[i] = initialValue; } - - for (uint_fast64_t i = 0; i < numberOfIntegerVariables; ++i) { + for (uint_fast64_t i = 0; i < integerVariables.size(); ++i) { int_fast64_t initialValue = integerVariables[i].getInitialValue()->getValueAsInt(initialState); std::get<1>(*initialState)[i] = initialValue; } + // Now set up the environment for a breadth-first search starting from the initial state. uint_fast64_t nextIndex = 1; - std::unordered_map stateToIndexMap; - std::vector allStates; + allStates.clear(); + stateToIndexMap.clear(); std::queue stateQueue; allStates.push_back(initialState); stateQueue.push(initialState); stateToIndexMap[initialState] = 0; - uint_fast64_t totalNumberOfTransitions = 0; + numberOfTransitions = 0; while (!stateQueue.empty()) { // Get first state in queue. StateType* currentState = stateQueue.front(); stateQueue.pop(); + // Remember whether the state has at least one transition such that transitions can be + // inserted upon detection of a deadlock state. bool hasTransition = false; // Iterate over all modules. - for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { - storm::ir::Module const& module = program.getModule(i); + for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { + storm::ir::Module const& module = program->getModule(i); // Iterate over all commands. for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { @@ -221,11 +163,26 @@ private: // Check if this command is enabled in the current state. if (command.getGuard()->getValueAsBool(currentState)) { hasTransition = true; + + // Remember what states are targeted by an update of the current command + // in order to be able to sum those probabilities and not increase the + // transition count. std::unordered_map stateToProbabilityMap; + + // Keep a queue of states to delete after the current command. When one + // command is processed and states are encountered which were already found + // before, we can only delete them after the command has been processed, + // because the stateToProbabilityMap will contain illegal values otherwise. std::queue statesToDelete; + + // Now iterate over all updates to see where the updates take the current + // state. for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { storm::ir::Update const& update = command.getUpdate(k); + // Now copy the current state and only overwrite the entries in the + // vectors if there is an assignment to that variable in the current + // update. StateType* newState = new StateType(*currentState); std::map const& booleanAssignmentMap = update.getBooleanAssignments(); for (auto assignedVariable : booleanAssignmentMap) { @@ -236,23 +193,29 @@ private: setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(currentState)); } + // If we have already found the target state of the update, we must not + // increase the transition count. auto probIt = stateToProbabilityMap.find(newState); if (probIt != stateToProbabilityMap.end()) { stateToProbabilityMap[newState] += update.getLikelihoodExpression()->getValueAsDouble(currentState); } else { - ++totalNumberOfTransitions; + ++numberOfTransitions; stateToProbabilityMap[newState] = update.getLikelihoodExpression()->getValueAsDouble(currentState); } + // Depending on whether the state was found previously, we mark it for + // deletion or add it to the reachable state space and mark it for + // further exploration. auto it = stateToIndexMap.find(newState); if (it != stateToIndexMap.end()) { - // Delete the state object directly as we have already seen that state. + // Queue the state object for deletion as we have already seen that + // state. statesToDelete.push(newState); } else { // Add state to the queue of states that are still to be explored. stateQueue.push(newState); - // Add state to list of all states so that we can delete it at the end. + // Add state to list of all reachable states. allStates.push_back(newState); // Give a unique index to the newly found state. @@ -260,6 +223,8 @@ private: ++nextIndex; } } + + // Now delete all states queued for deletion. while (!statesToDelete.empty()) { delete statesToDelete.front(); statesToDelete.pop(); @@ -268,9 +233,12 @@ private: } } + // If the state is a deadlock state, and the corresponding flag is set, we tolerate that + // and increase the number of transitions by one, because a self-loop is going to be + // inserted in the next step. If the flag is not set, an exception is thrown. if (!hasTransition) { if (storm::settings::instance()->isSet("fix-deadlocks")) { - ++totalNumberOfTransitions; + ++numberOfTransitions; } else { LOG4CPLUS_ERROR(logger, "Error while creating sparse matrix from probabilistic program: found deadlock state."); throw storm::exceptions::WrongFileFormatException() << "Error while creating sparse matrix from probabilistic program: found deadlock state."; @@ -279,9 +247,91 @@ private: } } + template + std::shared_ptr> buildMatrix() { + std::shared_ptr> resultMatrix(new storm::storage::SparseMatrix(allStates.size())); + resultMatrix->initialize(numberOfTransitions); + + // Keep track of the running index to insert values into correct matrix row. + uint_fast64_t currentIndex = 0; + + // Determine the matrix content for every row (i.e. reachable state). + for (StateType* currentState : allStates) { + bool hasTransition = false; + + // Iterate over all modules. + for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { + storm::ir::Module const& module = program->getModule(i); + + // Iterate over all commands. + for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { + storm::ir::Command const& command = module.getCommand(j); + + // Check if this command is enabled in the current state. + if (command.getGuard()->getValueAsBool(currentState)) { + hasTransition = true; + std::map stateIndexToProbabilityMap; + for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { + storm::ir::Update const& update = command.getUpdate(k); + + StateType* newState = new StateType(*currentState); + + std::map const& booleanAssignmentMap = update.getBooleanAssignments(); + for (auto assignedVariable : booleanAssignmentMap) { + setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(currentState)); + } + std::map const& integerAssignmentMap = update.getIntegerAssignments(); + for (auto assignedVariable : integerAssignmentMap) { + setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(currentState)); + } + + uint_fast64_t targetIndex = (*stateToIndexMap.find(newState)).second; + delete newState; + + auto probIt = stateIndexToProbabilityMap.find(targetIndex); + if (probIt != stateIndexToProbabilityMap.end()) { + stateIndexToProbabilityMap[targetIndex] += update.getLikelihoodExpression()->getValueAsDouble(currentState); + } else { + stateIndexToProbabilityMap[targetIndex] = update.getLikelihoodExpression()->getValueAsDouble(currentState); + } + } + + // Now insert the actual values into the matrix. + for (auto targetIndex : stateIndexToProbabilityMap) { + resultMatrix->addNextValue(currentIndex, targetIndex.first, targetIndex.second); + } + } + } + } + + // If the state is a deadlock state, a self-loop is inserted. Note that we do not have + // to check whether --fix-deadlocks is set, because if this was not the case an + // exception would have been thrown earlier. + if (!hasTransition) { + resultMatrix->addNextValue(currentIndex, currentIndex, 1); + } + + ++currentIndex; + } + + // Finalize matrix and return it. + resultMatrix->finalize(); + return resultMatrix; + } + + void clearReachableStateSpace() { + allStates.clear(); + stateToIndexMap.clear(); + } + + std::shared_ptr program; std::vector allStates; + std::unordered_map stateToIndexMap; + std::vector booleanVariables; + std::vector integerVariables; + std::unordered_map booleanVariableToIndexMap; + std::unordered_map integerVariableToIndexMap; uint_fast64_t numberOfTransitions; - std::vector numbersOfNondeterministicChoices; }; } // namespace adapters diff --git a/src/ir/Program.cpp b/src/ir/Program.cpp index 73bb62e9c..9792451d4 100644 --- a/src/ir/Program.cpp +++ b/src/ir/Program.cpp @@ -24,7 +24,7 @@ Program::Program(ModelType modelType, std::map program = parser.parseFile("test.input"); + std::shared_ptr program = parser.parseFile("examples/dtmc/die/die.pm"); + storm::adapters::ExplicitModelAdapter explicitModelAdapter(program); + std::shared_ptr> matrix = explicitModelAdapter.toSparseMatrix(); - std::shared_ptr> matrix = storm::adapters::ExplicitModelAdapter::toSparseMatrix(*program); - - //storm::adapters::SymbolicModelAdapter symbolicModelAdapter; - //symbolicAdapter.toMTBDD(*program); + std::shared_ptr secondProgram = parser.parseFile("examples/dtmc/crowds/crowds5_5.pm"); + storm::adapters::ExplicitModelAdapter secondExplicitModelAdapter(secondProgram); + std::shared_ptr> secondMatrix = secondExplicitModelAdapter.toSparseMatrix(); cleanUp(); return 0; From 18b6e812a7fccf4bc8285fdf57d296364f658a6f Mon Sep 17 00:00:00 2001 From: gereon Date: Sun, 24 Feb 2013 17:49:04 +0100 Subject: [PATCH 033/152] Added #include , as std::shared_ptr is used within this file --- src/ir/expressions/BinaryExpression.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ir/expressions/BinaryExpression.h b/src/ir/expressions/BinaryExpression.h index 03b933c48..c5b4ba9f5 100644 --- a/src/ir/expressions/BinaryExpression.h +++ b/src/ir/expressions/BinaryExpression.h @@ -9,6 +9,7 @@ #define STORM_IR_EXPRESSIONS_BINARYEXPRESSION_H_ #include "BaseExpression.h" +#include namespace storm { From 03ca1e880ddbb9c03affbb2077f62d6f9f6a355a Mon Sep 17 00:00:00 2001 From: gereon Date: Sun, 24 Feb 2013 17:49:37 +0100 Subject: [PATCH 034/152] Renamed commandName to actionName, added getter for actionName --- src/ir/Command.cpp | 13 +++++++++---- src/ir/Command.h | 12 +++++++++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/ir/Command.cpp b/src/ir/Command.cpp index 5cb4c6354..bec67d4bf 100644 --- a/src/ir/Command.cpp +++ b/src/ir/Command.cpp @@ -14,16 +14,21 @@ namespace storm { namespace ir { // Initializes all members with their default constructors. -Command::Command() : commandName(), guardExpression(), updates() { +Command::Command() : actionName(), guardExpression(), updates() { // Nothing to do here. } // Initializes all members according to the given values. -Command::Command(std::string commandName, std::shared_ptr guardExpression, std::vector updates) - : commandName(commandName), guardExpression(guardExpression), updates(updates) { +Command::Command(std::string actionName, std::shared_ptr guardExpression, std::vector updates) + : actionName(actionName), guardExpression(guardExpression), updates(updates) { // Nothing to do here. } +// Return the action name. +std::string const& Command::getActionName() const { + return this->actionName; +} + // Return the expression for the guard. std::shared_ptr const& Command::getGuard() const { return guardExpression; @@ -42,7 +47,7 @@ storm::ir::Update const& Command::getUpdate(uint_fast64_t index) const { // Build a string representation of the command. std::string Command::toString() const { std::stringstream result; - result << "[" << commandName << "] " << guardExpression->toString() << " -> "; + result << "[" << actionName << "] " << guardExpression->toString() << " -> "; for (uint_fast64_t i = 0; i < updates.size(); ++i) { result << updates[i].toString(); if (i < updates.size() - 1) { diff --git a/src/ir/Command.h b/src/ir/Command.h index 2ac54b525..9207c76f0 100644 --- a/src/ir/Command.h +++ b/src/ir/Command.h @@ -30,10 +30,16 @@ public: /*! * Creates a command with the given name, guard and updates. - * @param commandName the name of the command. + * @param actionName the action name of the command. * @param guardExpression the expression that defines the guard of the command. */ - Command(std::string commandName, std::shared_ptr guardExpression, std::vector updates); + Command(std::string actionName, std::shared_ptr guardExpression, std::vector updates); + + /*! + * Retrieves the action name of this command. + * @returns the action name of this command. + */ + std::string const& getActionName() const; /*! * Retrieves a reference to the guard of the command. @@ -61,7 +67,7 @@ public: private: // The name of the command. - std::string commandName; + std::string actionName; // The expression that defines the guard of the command. std::shared_ptr guardExpression; From 00ce70d411e828f145b3cf9b8cb4a6a889e8096d Mon Sep 17 00:00:00 2001 From: gereon Date: Sun, 24 Feb 2013 17:50:14 +0100 Subject: [PATCH 035/152] Added actionsToCommandIndexMap, initialization and getter. This map maps an action name to the set of Commands labelled with this action name. --- src/ir/Module.cpp | 22 +++++++++++++++++++--- src/ir/Module.h | 13 +++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index d800256c8..98e7b1275 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -17,7 +17,7 @@ namespace ir { // Initializes all members with their default constructors. Module::Module() : moduleName(), booleanVariables(), integerVariables(), booleanVariablesToIndexMap(), - integerVariablesToIndexMap(), commands() { + integerVariablesToIndexMap(), commands(), actionsToCommandIndexMap() { // Nothing to do here. } @@ -29,8 +29,14 @@ Module::Module(std::string moduleName, std::vector b std::vector commands) : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), booleanVariablesToIndexMap(booleanVariableToIndexMap), - integerVariablesToIndexMap(integerVariableToIndexMap), commands(commands) { - // Nothing to do here. + integerVariablesToIndexMap(integerVariableToIndexMap), commands(commands), actionsToCommandIndexMap() { + // Build actionsToCommandIndexMap + for (unsigned int id = 0; id < this->commands.size(); id++) { + std::string action = this->commands[id].getActionName(); + if (action != "") { + this->actionsToCommandIndexMap[action]->insert(id); + } + } } // Return the number of boolean variables. @@ -100,6 +106,16 @@ std::string Module::toString() const { return result.str(); } +// Return Commands with given action. +std::shared_ptr> const Module::getCommandsByAction(std::string const& action) const { + auto res = this->actionsToCommandIndexMap.find(action); + if (res == this->actionsToCommandIndexMap.end()) { + return std::shared_ptr>(new std::set()); + } else { + return res->second; + } +} + } // namespace ir } // namespace storm diff --git a/src/ir/Module.h b/src/ir/Module.h index 2c362da41..d07350b80 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -13,8 +13,10 @@ #include "Command.h" #include +#include #include #include +#include namespace storm { @@ -98,6 +100,14 @@ public: * @returns a string representation of this variable. */ std::string toString() const; + + /*! + * Retrieves the indices of all Commands within this module that are labelled + * by the given action. + * @param action Name of the action + * @returns Indices of all matching Commands. + */ + std::shared_ptr> const getCommandsByAction(std::string const& action) const; private: // The name of the module. @@ -117,6 +127,9 @@ private: // The commands associated with the module. std::vector commands; + + // A map of actions to the set of commands labelled with this action. + std::map>> actionsToCommandIndexMap; }; } // namespace ir From 845af3f12eb717f86041b0c95b02411333ca3e0e Mon Sep 17 00:00:00 2001 From: gereon Date: Sun, 24 Feb 2013 18:44:50 +0100 Subject: [PATCH 036/152] Added actionMap to Program, added set of actions to Module and Program. --- src/ir/Module.cpp | 12 +++++++++--- src/ir/Module.h | 15 ++++++++++++--- src/ir/Program.cpp | 27 ++++++++++++++++++++++++--- src/ir/Program.h | 23 ++++++++++++++++++++++- 4 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index 98e7b1275..c09351037 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -17,7 +17,7 @@ namespace ir { // Initializes all members with their default constructors. Module::Module() : moduleName(), booleanVariables(), integerVariables(), booleanVariablesToIndexMap(), - integerVariablesToIndexMap(), commands(), actionsToCommandIndexMap() { + integerVariablesToIndexMap(), commands(), actions(), actionsToCommandIndexMap() { // Nothing to do here. } @@ -29,12 +29,13 @@ Module::Module(std::string moduleName, std::vector b std::vector commands) : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), booleanVariablesToIndexMap(booleanVariableToIndexMap), - integerVariablesToIndexMap(integerVariableToIndexMap), commands(commands), actionsToCommandIndexMap() { + integerVariablesToIndexMap(integerVariableToIndexMap), commands(commands), actions(), actionsToCommandIndexMap() { // Build actionsToCommandIndexMap for (unsigned int id = 0; id < this->commands.size(); id++) { std::string action = this->commands[id].getActionName(); if (action != "") { this->actionsToCommandIndexMap[action]->insert(id); + this->actions.insert(action); } } } @@ -106,7 +107,12 @@ std::string Module::toString() const { return result.str(); } -// Return Commands with given action. +// Return set of actions. +std::set const& Module::getActions() const { + return this->actions; +} + +// Return commands with given action. std::shared_ptr> const Module::getCommandsByAction(std::string const& action) const { auto res = this->actionsToCommandIndexMap.find(action); if (res == this->actionsToCommandIndexMap.end()) { diff --git a/src/ir/Module.h b/src/ir/Module.h index d07350b80..4070846f5 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -102,10 +102,16 @@ public: std::string toString() const; /*! - * Retrieves the indices of all Commands within this module that are labelled + * Retrieves the set of actions present in this module. + * @returns the set of actions present in this module. + */ + std::set const& getActions() const; + + /*! + * Retrieves the indices of all commands within this module that are labelled * by the given action. - * @param action Name of the action - * @returns Indices of all matching Commands. + * @param action Name of the action. + * @returns Indices of all matching commands. */ std::shared_ptr> const getCommandsByAction(std::string const& action) const; @@ -128,6 +134,9 @@ private: // The commands associated with the module. std::vector commands; + // The set of actions present in this module. + std::set actions; + // A map of actions to the set of commands labelled with this action. std::map>> actionsToCommandIndexMap; }; diff --git a/src/ir/Program.cpp b/src/ir/Program.cpp index 9792451d4..5ce464fda 100644 --- a/src/ir/Program.cpp +++ b/src/ir/Program.cpp @@ -14,14 +14,20 @@ namespace storm { namespace ir { // Initializes all members with their default constructors. -Program::Program() : modelType(UNDEFINED), booleanUndefinedConstantExpressions(), integerUndefinedConstantExpressions(), doubleUndefinedConstantExpressions(), modules(), rewards() { +Program::Program() : modelType(UNDEFINED), booleanUndefinedConstantExpressions(), integerUndefinedConstantExpressions(), doubleUndefinedConstantExpressions(), modules(), rewards(), actions(), actionsToModuleIndexMap() { // Nothing to do here. } // Initializes all members according to the given values. Program::Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector modules, std::map rewards, std::map> labels) - : modelType(modelType), booleanUndefinedConstantExpressions(booleanUndefinedConstantExpressions), integerUndefinedConstantExpressions(integerUndefinedConstantExpressions), doubleUndefinedConstantExpressions(doubleUndefinedConstantExpressions), modules(modules), rewards(rewards), labels(labels) { - // Nothing to do here. + : modelType(modelType), booleanUndefinedConstantExpressions(booleanUndefinedConstantExpressions), integerUndefinedConstantExpressions(integerUndefinedConstantExpressions), doubleUndefinedConstantExpressions(doubleUndefinedConstantExpressions), modules(modules), rewards(rewards), labels(labels), actionsToModuleIndexMap() { + // Build actionsToModuleIndexMap + for (unsigned int id = 0; id < this->modules.size(); id++) { + for (auto action : this->modules[id].getActions()) { + this->actionsToModuleIndexMap[action]->insert(id); + this->actions.insert(action); + } + } } Program::ModelType Program::getModelType() const { @@ -74,6 +80,21 @@ storm::ir::Module const& Program::getModule(uint_fast64_t index) const { return this->modules[index]; } +// Return set of actions. +std::set const& Program::getActions() const { + return this->actions; +} + +// Return modules with given action. +std::shared_ptr> const Program::getModulesByAction(std::string const& action) const { + auto res = this->actionsToModuleIndexMap.find(action); + if (res == this->actionsToModuleIndexMap.end()) { + return std::shared_ptr>(new std::set()); + } else { + return res->second; + } +} + } // namespace ir diff --git a/src/ir/Program.h b/src/ir/Program.h index bb352130f..3ce3f3af9 100644 --- a/src/ir/Program.h +++ b/src/ir/Program.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace storm { @@ -77,6 +78,20 @@ public: * @returns a string representation of this program. */ std::string toString() const; + + /*! + * Retrieves the set of actions present in this module. + * @returns the set of actions present in this module. + */ + std::set const& getActions() const; + + /*! + * Retrieved the indices of all Modules within this program that contain + * commands that are labelled with the given action. + * @param action Name of the action. + * @returns Indices of all matching modules. + */ + std::shared_ptr> const getModulesByAction(std::string const& action) const; private: // The type of the model. @@ -88,7 +103,7 @@ private: // A map of undefined integer constants to their expressions nodes. std::map> integerUndefinedConstantExpressions; - // A mpa of undefined double constants to their expressions nodes. + // A map of undefined double constants to their expressions nodes. std::map> doubleUndefinedConstantExpressions; // The modules associated with the program. @@ -99,6 +114,12 @@ private: // The labels that are defined for this model. std::map> labels; + + // The set of actions present in this program. + std::set actions; + + // A map of actions to the set of modules containing commands labelled with this action. + std::map>> actionsToModuleIndexMap; }; } // namespace ir From e69c9db26672f8369538ac892a0cc55c1ade9fe5 Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 25 Feb 2013 12:14:49 +0100 Subject: [PATCH 037/152] Implemented synchronization within computeReachableStateSpace. Added new helper routines: * getActiveCommandsByAction() retrieves commands that are active (i.e. guard is true) for some action. * applyUpdate() copies a given state and updates it with a given update. Added state expansion for synchronized commands. Made former loop only consider unsynchronized commands. --- src/adapters/ExplicitModelAdapter.h | 175 +++++++++++++++++++++++----- 1 file changed, 143 insertions(+), 32 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 40e0fc056..498b755f2 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -18,6 +18,7 @@ #include #include #include +#include typedef std::pair, std::vector> StateType; @@ -89,8 +90,8 @@ private: numberOfBooleanVariables += program->getModule(i).getNumberOfBooleanVariables(); } - booleanVariables.resize(numberOfBooleanVariables); - integerVariables.resize(numberOfIntegerVariables); + this->booleanVariables.resize(numberOfBooleanVariables); + this->integerVariables.resize(numberOfIntegerVariables); uint_fast64_t nextBooleanVariableIndex = 0; uint_fast64_t nextIntegerVariableIndex = 0; @@ -98,17 +99,59 @@ private: storm::ir::Module const& module = program->getModule(i); for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { - booleanVariables[nextBooleanVariableIndex] = module.getBooleanVariable(j); - booleanVariableToIndexMap[module.getBooleanVariable(j).getName()] = nextBooleanVariableIndex; + this->booleanVariables[nextBooleanVariableIndex] = module.getBooleanVariable(j); + this->booleanVariableToIndexMap[module.getBooleanVariable(j).getName()] = nextBooleanVariableIndex; ++nextBooleanVariableIndex; } for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) { - integerVariables[nextIntegerVariableIndex] = module.getIntegerVariable(j); - integerVariableToIndexMap[module.getIntegerVariable(j).getName()] = nextIntegerVariableIndex; + this->integerVariables[nextIntegerVariableIndex] = module.getIntegerVariable(j); + this->integerVariableToIndexMap[module.getIntegerVariable(j).getName()] = nextIntegerVariableIndex; ++nextIntegerVariableIndex; } } } + + std::unique_ptr>> getActiveCommandsByAction(StateType const * state, std::string& action) { + std::unique_ptr>> res = std::unique_ptr>>(new std::list>()); + + // Iterate over all modules. + for (uint_fast64_t i = 0; i < this->program->getNumberOfModules(); ++i) { + storm::ir::Module const& module = this->program->getModule(i); + + std::shared_ptr> ids = module.getCommandsByAction(action); + std::list commands; + + // Look up commands by their id. Add, if guard holds. + for (uint_fast64_t id : *ids) { + storm::ir::Command cmd = module.getCommand(id); + if (cmd.getGuard()->getValueAsBool(state)) { + commands.push_back(module.getCommand(id)); + } + } + res->push_back(commands); + } + // Sort the result in the vague hope that having small lists at the beginning will speed up the expanding. + // This is how lambdas may look like in C++... + res->sort([](const std::list& a, const std::list& b){ return a.size() < b.size(); }); + return res; + } + + /*! + * Apply an update to the given state and return resulting state. + * @params state Current state. + * @params update Update to be applied. + * @return Resulting state. + */ + StateType* applyUpdate(StateType const * state, storm::ir::Update const & update) { + StateType* newState = new StateType(*state); + for (auto assignedVariable : update.getBooleanAssignments()) { + setValue(newState, this->booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(state)); + } + for (auto assignedVariable : update.getIntegerAssignments()) { + setValue(newState, this->integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(state)); + } + return newState; + } void computeReachableStateSpace() { bool nondeterministicModel = program->getModelType() == storm::ir::Program::MDP || program->getModelType() == storm::ir::Program::CTMDP; @@ -124,25 +167,25 @@ private: // Now initialize all fields in the value vectors of the state according to the initial // values provided by the input program. for (uint_fast64_t i = 0; i < booleanVariables.size(); ++i) { - bool initialValue = booleanVariables[i].getInitialValue()->getValueAsBool(initialState); + bool initialValue = this->booleanVariables[i].getInitialValue()->getValueAsBool(initialState); std::get<0>(*initialState)[i] = initialValue; } for (uint_fast64_t i = 0; i < integerVariables.size(); ++i) { - int_fast64_t initialValue = integerVariables[i].getInitialValue()->getValueAsInt(initialState); + int_fast64_t initialValue = this->integerVariables[i].getInitialValue()->getValueAsInt(initialState); std::get<1>(*initialState)[i] = initialValue; } // Now set up the environment for a breadth-first search starting from the initial state. uint_fast64_t nextIndex = 1; - allStates.clear(); - stateToIndexMap.clear(); + this->allStates.clear(); + this->stateToIndexMap.clear(); std::queue stateQueue; - allStates.push_back(initialState); + this->allStates.push_back(initialState); stateQueue.push(initialState); - stateToIndexMap[initialState] = 0; + this->stateToIndexMap[initialState] = 0; - numberOfTransitions = 0; + this->numberOfTransitions = 0; while (!stateQueue.empty()) { // Get first state in queue. StateType* currentState = stateQueue.front(); @@ -151,7 +194,91 @@ private: // Remember whether the state has at least one transition such that transitions can be // inserted upon detection of a deadlock state. bool hasTransition = false; + + // First expand all transitions for commands labelled with some + // action. For every module, we determine all commands with this + // action whose guard holds. Then, we add a transition for each + // combination of all updates of those commands. + for (std::string action : this->program->getActions()) { + // Get list of all commands. + // This list contains a list for every module that has commands labelled by action. + // Each such list contains all commands whose guards are fulfilled. + // If no guard is fulfilled (i.e. there is no way to perform this action), the list will be empty! + std::unique_ptr>> cmds = this->getActiveCommandsByAction(currentState, action); + + // Start with current state. + std::unordered_map resultStates; + resultStates[currentState] = 1; + std::queue deleteQueue; + + // Iterate over all modules (represented by the list of commands with the current action). + // We will now combine every state in resultStates with every additional update in the next module. + // The final result will be this map after we are done with all modules. + for (std::list module : *cmds) { + // If no states are left, we are done. + // This happens, if there is a module where commands existed, but no guard was fulfilled. + if (resultStates.size() == 0) break; + // Put all new states in this new map. + std::unordered_map newStates; + + // Iterate over all commands within this module. + for (storm::ir::Command command : module) { + // Iterate over all updates of this command. + for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { + storm::ir::Update const& update = command.getUpdate(k); + + // Iterate over all resultStates. + for (auto it : resultStates) { + // Apply the new update and get resulting state. + StateType* newState = this->applyUpdate(it.first, update); + // Insert the new state into newStates array. + // Take care of calculation of likelihood, combine identical states. + auto s = newStates.find(newState); + if (s == newStates.end()) { + newStates[newState] = it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); + } else { + newStates[newState] += it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); + } + // No matter what happened, we must delete the states of the previous iteration. + deleteQueue.push(it.first); + } + } + } + // Move new states to resultStates. + resultStates = newStates; + // Delete old result states. + while (!deleteQueue.empty()) { + delete deleteQueue.front(); + deleteQueue.pop(); + } + } + + // Now add our final result states to our global result. + for (auto it : resultStates) { + auto s = stateToIndexMap.find(it.first); + if (s == stateToIndexMap.end()) { + stateQueue.push(it.first); + // Add state to list of all reachable states. + allStates.push_back(it.first); + // Give a unique index to the newly found state. + stateToIndexMap[it.first] = nextIndex; + ++nextIndex; + } else { + deleteQueue.push(it.first); + } + } + // Delete states we already had. + while (!deleteQueue.empty()) { + delete deleteQueue.front(); + deleteQueue.pop(); + } + this->numberOfTransitions += resultStates.size(); + } + + // Now, expand all transitions for commands not labelled with + // some action. Those commands each build a transition for + // themselves. // Iterate over all modules. for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { storm::ir::Module const& module = program->getModule(i); @@ -159,6 +286,7 @@ private: // Iterate over all commands. for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { storm::ir::Command const& command = module.getCommand(j); + if (command.getActionName() != "") continue; // Check if this command is enabled in the current state. if (command.getGuard()->getValueAsBool(currentState)) { @@ -183,15 +311,7 @@ private: // Now copy the current state and only overwrite the entries in the // vectors if there is an assignment to that variable in the current // update. - StateType* newState = new StateType(*currentState); - std::map const& booleanAssignmentMap = update.getBooleanAssignments(); - for (auto assignedVariable : booleanAssignmentMap) { - setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(currentState)); - } - std::map const& integerAssignmentMap = update.getIntegerAssignments(); - for (auto assignedVariable : integerAssignmentMap) { - setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(currentState)); - } + StateType* newState = this->applyUpdate(currentState, update); // If we have already found the target state of the update, we must not // increase the transition count. @@ -274,16 +394,7 @@ private: for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { storm::ir::Update const& update = command.getUpdate(k); - StateType* newState = new StateType(*currentState); - - std::map const& booleanAssignmentMap = update.getBooleanAssignments(); - for (auto assignedVariable : booleanAssignmentMap) { - setValue(newState, booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(currentState)); - } - std::map const& integerAssignmentMap = update.getIntegerAssignments(); - for (auto assignedVariable : integerAssignmentMap) { - setValue(newState, integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(currentState)); - } + StateType* newState = this->applyUpdate(*currentState, update); uint_fast64_t targetIndex = (*stateToIndexMap.find(newState)).second; delete newState; From de268ec3e8474bcfebd2d2b0a42d12f2a5249761 Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 25 Feb 2013 12:28:45 +0100 Subject: [PATCH 038/152] Forgot to remove a *... --- src/adapters/ExplicitModelAdapter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 498b755f2..84a1f52fd 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -394,7 +394,7 @@ private: for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { storm::ir::Update const& update = command.getUpdate(k); - StateType* newState = this->applyUpdate(*currentState, update); + StateType* newState = this->applyUpdate(currentState, update); uint_fast64_t targetIndex = (*stateToIndexMap.find(newState)).second; delete newState; From 270c3125b510ccef404083c09d23f85f3b7e3612 Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 25 Feb 2013 12:45:58 +0100 Subject: [PATCH 039/152] Adding new simple example pm file. sync.pm contains a very simple model that uses the synchronization feature of prism. --- examples/dtmc/sync/sync.pm | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 examples/dtmc/sync/sync.pm diff --git a/examples/dtmc/sync/sync.pm b/examples/dtmc/sync/sync.pm new file mode 100644 index 000000000..8bc7f94ce --- /dev/null +++ b/examples/dtmc/sync/sync.pm @@ -0,0 +1,22 @@ +// A simple model using synchronization +dtmc + +module generator + + s : [0..2] init 0; + + [] s=0 -> 0.2 : (s'=1) + 0.8 : (s'=0); + [yield] s=1 -> 1 : (s'=2); + [] s=2 -> 0.5 : (s'=0) + 0.5 : (s'=2); + +endmodule + +module consumer + + t : [0..2] init 0; + + [] t=0 -> 0.8 : (t'=1) + 0.2 : (t'=0); + [yield] t=1 -> 1 : (t'=2); + [] t=2 -> 0.2 : (t'=0) + 0.8 : (t'=2); + +endmodule From 42693bf0f272242cd6752ed25ec522f212cdec4b Mon Sep 17 00:00:00 2001 From: dehnert Date: Mon, 25 Feb 2013 13:33:58 +0100 Subject: [PATCH 040/152] Fixed wrong includes of cuddObj.hh in expression classes. Added missing files of cudd. --- resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc | 5699 +++++++++++++++++ resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh | 762 +++ resources/3rdparty/cudd-2.5.0/obj/testobj.cc | 607 ++ src/ir/expressions/BaseExpression.h | 1 - .../BinaryBooleanFunctionExpression.h | 2 - .../BinaryNumericalFunctionExpression.h | 2 - src/ir/expressions/BinaryRelationExpression.h | 2 - .../expressions/BooleanConstantExpression.h | 2 - 8 files changed, 7068 insertions(+), 9 deletions(-) create mode 100644 resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc create mode 100644 resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh create mode 100644 resources/3rdparty/cudd-2.5.0/obj/testobj.cc diff --git a/resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc b/resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc new file mode 100644 index 000000000..8722ca82f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc @@ -0,0 +1,5699 @@ +/**CFile*********************************************************************** + + FileName [cuddObj.cc] + + PackageName [cuddObj] + + Synopsis [Functions for the C++ object-oriented encapsulation of CUDD.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ +#include +#include +#include +#include +#include +#include "cuddObj.hh" + +using std::cout; +using std::cerr; +using std::endl; +using std::hex; +using std::string; +using std::vector; +using std::sort; + +// --------------------------------------------------------------------------- +// Variable declarations +// --------------------------------------------------------------------------- + +#ifndef lint +static char rcsid[] UNUSED = "$Id: cuddObj.cc,v 1.15 2012/02/05 01:06:40 fabio Exp fabio $"; +#endif + +// --------------------------------------------------------------------------- +// Members of class DD +// --------------------------------------------------------------------------- + + +DD::DD() : p(0), node(0) {} + + +DD::DD(Capsule *cap, DdNode *ddNode) : p(cap), node(ddNode) { + if (node != 0) Cudd_Ref(node); + if (p->verbose) { + cout << "Standard DD constructor for node " << hex << long(node) << + " ref = " << Cudd_Regular(node)->ref << "\n"; + } + +} // DD::DD + + +DD::DD(Cudd const & manager, DdNode *ddNode) : p(manager.p), node(ddNode) { + checkReturnValue(ddNode); + if (node != 0) Cudd_Ref(node); + if (p->verbose) { + cout << "Standard DD constructor for node " << hex << long(node) << + " ref = " << Cudd_Regular(node)->ref << "\n"; + } + +} // DD::DD + + +DD::DD(const DD &from) { + p = from.p; + node = from.node; + if (node != 0) { + Cudd_Ref(node); + if (p->verbose) { + cout << "Copy DD constructor for node " << hex << long(node) << + " ref = " << Cudd_Regular(node)->ref << "\n"; + } + } + +} // DD::DD + + +DD::~DD() {} + + +inline DdManager * +DD::checkSameManager( + const DD &other) const +{ + DdManager *mgr = p->manager; + if (mgr != other.p->manager) { + p->errorHandler("Operands come from different manager."); + } + return mgr; + +} // DD::checkSameManager + + +inline void +DD::checkReturnValue( + const DdNode *result) const +{ + if (result == 0) { + DdManager *mgr = p->manager; + Cudd_ErrorType errType = Cudd_ReadErrorCode(mgr); + switch (errType) { + case CUDD_MEMORY_OUT: + p->errorHandler("Out of memory."); + break; + case CUDD_TOO_MANY_NODES: + break; + case CUDD_MAX_MEM_EXCEEDED: + p->errorHandler("Maximum memory exceeded."); + break; + case CUDD_TIMEOUT_EXPIRED: + { + std::ostringstream msg; + unsigned long lag = + Cudd_ReadElapsedTime(mgr) - Cudd_ReadTimeLimit(mgr); + msg << "Timeout expired. Lag = " << lag << " ms.\n"; + p->timeoutHandler(msg.str()); + } + break; + case CUDD_INVALID_ARG: + p->errorHandler("Invalid argument."); + break; + case CUDD_INTERNAL_ERROR: + p->errorHandler("Internal error."); + break; + case CUDD_NO_ERROR: + default: + p->errorHandler("Unexpected error."); + break; + } + } + +} // DD::checkReturnValue + + +inline void +DD::checkReturnValue( + const int result, + const int expected) const +{ + if (result != expected) { + DdManager *mgr = p->manager; + Cudd_ErrorType errType = Cudd_ReadErrorCode(mgr); + switch (errType) { + case CUDD_MEMORY_OUT: + p->errorHandler("Out of memory."); + break; + case CUDD_TOO_MANY_NODES: + break; + case CUDD_MAX_MEM_EXCEEDED: + p->errorHandler("Maximum memory exceeded."); + break; + case CUDD_TIMEOUT_EXPIRED: + { + std::ostringstream msg; + unsigned long lag = + Cudd_ReadElapsedTime(mgr) - Cudd_ReadTimeLimit(mgr); + msg << "Timeout expired. Lag = " << lag << " ms.\n"; + p->timeoutHandler(msg.str()); + } + break; + case CUDD_INVALID_ARG: + p->errorHandler("Invalid argument."); + break; + case CUDD_INTERNAL_ERROR: + p->errorHandler("Internal error."); + break; + case CUDD_NO_ERROR: + default: + p->errorHandler("Unexpected error."); + break; + } + } + +} // DD::checkReturnValue + + +DdManager * +DD::manager() const +{ + return p->manager; + +} // DD::manager + + +DdNode * +DD::getNode() const +{ + return node; + +} // DD::getNode + + +DdNode * +DD::getRegularNode() const +{ + return Cudd_Regular(node); + +} // DD::getRegularNode + + +int +DD::nodeCount() const +{ + return Cudd_DagSize(node); + +} // DD::nodeCount + + +unsigned int +DD::NodeReadIndex() const +{ + return Cudd_NodeReadIndex(node); + +} // DD::NodeReadIndex + + +// --------------------------------------------------------------------------- +// Members of class ABDD +// --------------------------------------------------------------------------- + + +ABDD::ABDD() : DD() {} +ABDD::ABDD(Capsule *cap, DdNode *bddNode) : DD(cap,bddNode) {} +ABDD::ABDD(Cudd const & manager, DdNode *bddNode) : DD(manager,bddNode) {} +ABDD::ABDD(const ABDD &from) : DD(from) {} + + +ABDD::~ABDD() { + if (node != 0) { + Cudd_RecursiveDeref(p->manager,node); + if (p->verbose) { + cout << "ADD/BDD destructor called for node " << hex << + long(node) << " ref = " << Cudd_Regular(node)->ref << "\n"; + } + } + +} // ABDD::~ABDD + + +bool +ABDD::operator==( + const ABDD& other) const +{ + checkSameManager(other); + return node == other.node; + +} // ABDD::operator== + + +bool +ABDD::operator!=( + const ABDD& other) const +{ + checkSameManager(other); + return node != other.node; + +} // ABDD::operator!= + + +bool +ABDD::IsOne() const +{ + return node == Cudd_ReadOne(p->manager); + +} // ABDD::IsOne + + +void +ABDD::print( + int nvars, + int verbosity) const +{ + cout.flush(); + int retval = Cudd_PrintDebug(p->manager,node,nvars,verbosity); + if (retval == 0) p->errorHandler("print failed"); + +} // ABDD::print + + +// --------------------------------------------------------------------------- +// Members of class BDD +// --------------------------------------------------------------------------- + +BDD::BDD() : ABDD() {} +BDD::BDD(Capsule *cap, DdNode *bddNode) : ABDD(cap,bddNode) {} +BDD::BDD(Cudd const & manager, DdNode *bddNode) : ABDD(manager,bddNode) {} +BDD::BDD(const BDD &from) : ABDD(from) {} + + +BDD +BDD::operator=( + const BDD& right) +{ + if (this == &right) return *this; + if (right.node != 0) Cudd_Ref(right.node); + if (node != 0) { + Cudd_RecursiveDeref(p->manager,node); + if (p->verbose) { + cout << "BDD dereferencing for node " << hex << long(node) << + " ref = " << Cudd_Regular(node)->ref << "\n"; + } + } + node = right.node; + p = right.p; + if (node != 0 && p->verbose) { + cout << "BDD assignment for node " << hex << long(node) << + " ref = " << Cudd_Regular(node)->ref << "\n"; + } + return *this; + +} // BDD::operator= + + +bool +BDD::operator<=( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return Cudd_bddLeq(mgr,node,other.node); + +} // BDD::operator<= + + +bool +BDD::operator>=( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return Cudd_bddLeq(mgr,other.node,node); + +} // BDD::operator>= + + +bool +BDD::operator<( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return node != other.node && Cudd_bddLeq(mgr,node,other.node); + +} // BDD::operator< + + +bool +BDD::operator>( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return node != other.node && Cudd_bddLeq(mgr,other.node,node); + +} // BDD::operator> + + +BDD +BDD::operator!() const +{ + return BDD(p, Cudd_Not(node)); + +} // BDD::operator! + + +BDD +BDD::operator~() const +{ + return BDD(p, Cudd_Not(node)); + +} // BDD::operator~ + + +BDD +BDD::operator*( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddAnd(mgr,node,other.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::operator* + + +BDD +BDD::operator*=( + const BDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddAnd(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // BDD::operator*= + + +BDD +BDD::operator&( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddAnd(mgr,node,other.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::operator& + + +BDD +BDD::operator&=( + const BDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddAnd(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // BDD::operator&= + + +BDD +BDD::operator+( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddOr(mgr,node,other.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::operator+ + + +BDD +BDD::operator+=( + const BDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddOr(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // BDD::operator+= + + +BDD +BDD::operator|( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddOr(mgr,node,other.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::operator| + + +BDD +BDD::operator|=( + const BDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddOr(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // BDD::operator|= + + +BDD +BDD::operator^( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddXor(mgr,node,other.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::operator^ + + +BDD +BDD::operator^=( + const BDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddXor(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // BDD::operator^= + + +BDD +BDD::operator-( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddAnd(mgr,node,Cudd_Not(other.node)); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::operator- + + +BDD +BDD::operator-=( + const BDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddAnd(mgr,node,Cudd_Not(other.node)); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // BDD::operator-= + + +bool +BDD::IsZero() const +{ + return node == Cudd_ReadLogicZero(p->manager); + +} // BDD::IsZero + + +// --------------------------------------------------------------------------- +// Members of class ADD +// --------------------------------------------------------------------------- + + +ADD::ADD() : ABDD() {} +ADD::ADD(Capsule *cap, DdNode *bddNode) : ABDD(cap,bddNode) {} +ADD::ADD(Cudd const & manager, DdNode *bddNode) : ABDD(manager,bddNode) {} +ADD::ADD(const ADD &from) : ABDD(from) {} + + +ADD +ADD::operator=( + const ADD& right) +{ + if (this == &right) return *this; + if (right.node != 0) Cudd_Ref(right.node); + if (node != 0) { + Cudd_RecursiveDeref(p->manager,node); + } + node = right.node; + p = right.p; + return *this; + +} // ADD::operator= + + +bool +ADD::operator<=( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + return Cudd_addLeq(mgr,node,other.node); + +} // ADD::operator<= + + +bool +ADD::operator>=( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + return Cudd_addLeq(mgr,other.node,node); + +} // ADD::operator>= + + +bool +ADD::operator<( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + return node != other.node && Cudd_addLeq(mgr,node,other.node); + +} // ADD::operator< + + +bool +ADD::operator>( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + return node != other.node && Cudd_addLeq(mgr,other.node,node); + +} // ADD::operator> + + +ADD +ADD::operator-() const +{ + return ADD(p, Cudd_addNegate(p->manager,node)); + +} // ADD::operator- + + +ADD +ADD::operator*( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addTimes,node,other.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::operator* + + +ADD +ADD::operator*=( + const ADD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addTimes,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // ADD::operator*= + + +ADD +ADD::operator+( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addPlus,node,other.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::operator+ + + +ADD +ADD::operator+=( + const ADD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addPlus,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // ADD::operator+= + + +ADD +ADD::operator-( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addMinus,node,other.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::operator- + + +ADD +ADD::operator-=( + const ADD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addMinus,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // ADD::operator-= + + +ADD +ADD::operator~() const +{ + return ADD(p, Cudd_addCmpl(p->manager,node)); + +} // ADD::operator~ + + +ADD +ADD::operator&( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addTimes,node,other.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::operator& + + +ADD +ADD::operator&=( + const ADD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addTimes,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // ADD::operator&= + + +ADD +ADD::operator|( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addOr,node,other.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::operator| + + +ADD +ADD::operator|=( + const ADD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addOr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // ADD::operator|= + + +bool +ADD::IsZero() const +{ + return node == Cudd_ReadZero(p->manager); + +} // ADD::IsZero + + +// --------------------------------------------------------------------------- +// Members of class ZDD +// --------------------------------------------------------------------------- + + +ZDD::ZDD(Capsule *cap, DdNode *bddNode) : DD(cap,bddNode) {} +ZDD::ZDD() : DD() {} +ZDD::ZDD(const ZDD &from) : DD(from) {} + + +ZDD::~ZDD() { + if (node != 0) { + Cudd_RecursiveDerefZdd(p->manager,node); + if (p->verbose) { + cout << "ZDD destructor called for node " << hex << long(node) << + " ref = " << Cudd_Regular(node)->ref << "\n"; + } + } + +} // ZDD::~ZDD + + +ZDD +ZDD::operator=( + const ZDD& right) +{ + if (this == &right) return *this; + if (right.node != 0) Cudd_Ref(right.node); + if (node != 0) { + Cudd_RecursiveDerefZdd(p->manager,node); + if (p->verbose) { + cout << "ZDD dereferencing for node " << hex << long(node) << + " ref = " << node->ref << "\n"; + } + } + node = right.node; + p = right.p; + if (node != 0 && p->verbose) { + cout << "ZDD assignment for node " << hex << long(node) << + " ref = " << node->ref << "\n"; + } + return *this; + +} // ZDD::operator= + + +bool +ZDD::operator==( + const ZDD& other) const +{ + checkSameManager(other); + return node == other.node; + +} // ZDD::operator== + + +bool +ZDD::operator!=( + const ZDD& other) const +{ + checkSameManager(other); + return node != other.node; + +} // ZDD::operator!= + + +bool +ZDD::operator<=( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return Cudd_zddDiffConst(mgr,node,other.node) == Cudd_ReadZero(mgr); + +} // ZDD::operator<= + + +bool +ZDD::operator>=( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return Cudd_zddDiffConst(mgr,other.node,node) == Cudd_ReadZero(mgr); + +} // ZDD::operator>= + + +bool +ZDD::operator<( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return node != other.node && + Cudd_zddDiffConst(mgr,node,other.node) == Cudd_ReadZero(mgr); + +} // ZDD::operator< + + +bool +ZDD::operator>( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return node != other.node && + Cudd_zddDiffConst(mgr,other.node,node) == Cudd_ReadZero(mgr); + +} // ZDD::operator> + + +void +ZDD::print( + int nvars, + int verbosity) const +{ + cout.flush(); + int retval = Cudd_zddPrintDebug(p->manager,node,nvars,verbosity); + if (retval == 0) p->errorHandler("print failed"); + +} // ZDD::print + + +ZDD +ZDD::operator*( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddIntersect(mgr,node,other.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::operator* + + +ZDD +ZDD::operator*=( + const ZDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddIntersect(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDerefZdd(mgr,node); + node = result; + return *this; + +} // ZDD::operator*= + + +ZDD +ZDD::operator&( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddIntersect(mgr,node,other.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::operator& + + +ZDD +ZDD::operator&=( + const ZDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddIntersect(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDerefZdd(mgr,node); + node = result; + return *this; + +} // ZDD::operator&= + + +ZDD +ZDD::operator+( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddUnion(mgr,node,other.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::operator+ + + +ZDD +ZDD::operator+=( + const ZDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddUnion(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDerefZdd(mgr,node); + node = result; + return *this; + +} // ZDD::operator+= + + +ZDD +ZDD::operator|( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddUnion(mgr,node,other.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::operator| + + +ZDD +ZDD::operator|=( + const ZDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddUnion(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDerefZdd(mgr,node); + node = result; + return *this; + +} // ZDD::operator|= + + +ZDD +ZDD::operator-( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddDiff(mgr,node,other.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::operator- + + +ZDD +ZDD::operator-=( + const ZDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddDiff(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDerefZdd(mgr,node); + node = result; + return *this; + +} // ZDD::operator-= + + +// --------------------------------------------------------------------------- +// Members of class Cudd +// --------------------------------------------------------------------------- + + +Cudd::Cudd( + unsigned int numVars, + unsigned int numVarsZ, + unsigned int numSlots, + unsigned int cacheSize, + unsigned long maxMemory) +{ + p = new Capsule; + p->manager = Cudd_Init(numVars,numVarsZ,numSlots,cacheSize,maxMemory); + p->errorHandler = defaultError; + p->timeoutHandler = defaultError; + p->verbose = 0; // initially terse + p->ref = 1; + +} // Cudd::Cudd + + +Cudd::Cudd( + const Cudd& x) +{ + p = x.p; + x.p->ref++; + if (p->verbose) + cout << "Cudd Copy Constructor" << endl; + +} // Cudd::Cudd + + +Cudd::~Cudd() +{ + if (--p->ref == 0) { +#ifdef DD_DEBUG + int retval = Cudd_CheckZeroRef(p->manager); + if (retval != 0) { + cerr << retval << " unexpected non-zero reference counts" << endl; + } else if (p->verbose) { + cerr << "All went well" << endl; + } +#endif + Cudd_Quit(p->manager); + delete p; + } + +} // Cudd::~Cudd + + +Cudd& +Cudd::operator=( + const Cudd& right) +{ + right.p->ref++; + if (--p->ref == 0) { // disconnect self + int retval = Cudd_CheckZeroRef(p->manager); + if (retval != 0) { + cerr << retval << " unexpected non-zero reference counts" << endl; + } else if (p->verbose) { + cerr << "All went well\n"; + } + Cudd_Quit(p->manager); + delete p; + } + p = right.p; + return *this; + +} // Cudd::operator= + + +PFC +Cudd::setHandler( + PFC newHandler) const +{ + PFC oldHandler = p->errorHandler; + p->errorHandler = newHandler; + return oldHandler; + +} // Cudd::setHandler + + +PFC +Cudd::getHandler() const +{ + return p->errorHandler; + +} // Cudd::getHandler + + +PFC +Cudd::setTimeoutHandler( + PFC newHandler) const +{ + PFC oldHandler = p->timeoutHandler; + p->timeoutHandler = newHandler; + return oldHandler; + +} // Cudd::setTimeoutHandler + + +PFC +Cudd::getTimeoutHandler() const +{ + return p->timeoutHandler; + +} // Cudd::getTimeourHandler + + +inline void +Cudd::checkReturnValue( + const DdNode *result) const +{ + if (result == 0) { + if (Cudd_ReadErrorCode(p->manager) == CUDD_MEMORY_OUT) { + p->errorHandler("Out of memory."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_TOO_MANY_NODES) { + p->errorHandler("Too many nodes."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_MAX_MEM_EXCEEDED) { + p->errorHandler("Maximum memory exceeded."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_TIMEOUT_EXPIRED) { + std::ostringstream msg; + DdManager *mgr = p->manager; + unsigned long lag = + Cudd_ReadElapsedTime(mgr) - Cudd_ReadTimeLimit(mgr); + msg << "Timeout expired. Lag = " << lag << " ms.\n"; + p->timeoutHandler(msg.str()); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_INVALID_ARG) { + p->errorHandler("Invalid argument."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_INTERNAL_ERROR) { + p->errorHandler("Internal error."); + } else { + p->errorHandler("Unexpected error."); + } + } + +} // Cudd::checkReturnValue + + +inline void +Cudd::checkReturnValue( + const int result) const +{ + if (result == 0) { + if (Cudd_ReadErrorCode(p->manager) == CUDD_MEMORY_OUT) { + p->errorHandler("Out of memory."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_TOO_MANY_NODES) { + p->errorHandler("Too many nodes."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_MAX_MEM_EXCEEDED) { + p->errorHandler("Maximum memory exceeded."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_TIMEOUT_EXPIRED) { + std::ostringstream msg; + DdManager *mgr = p->manager; + unsigned long lag = + Cudd_ReadElapsedTime(mgr) - Cudd_ReadTimeLimit(mgr); + msg << "Timeout expired. Lag = " << lag << " ms.\n"; + p->timeoutHandler(msg.str()); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_INVALID_ARG) { + p->errorHandler("Invalid argument."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_INTERNAL_ERROR) { + p->errorHandler("Internal error."); + } else { + p->errorHandler("Unexpected error."); + } + } + +} // Cudd::checkReturnValue + + +void +Cudd::info() const +{ + cout.flush(); + int retval = Cudd_PrintInfo(p->manager,stdout); + checkReturnValue(retval); + +} // Cudd::info + + +BDD +Cudd::bddVar() const +{ + DdNode *result = Cudd_bddNewVar(p->manager); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::bddVar + + +BDD +Cudd::bddVar( + int index) const +{ + DdNode *result = Cudd_bddIthVar(p->manager,index); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::bddVar + + +BDD +Cudd::bddOne() const +{ + DdNode *result = Cudd_ReadOne(p->manager); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::bddOne + + +BDD +Cudd::bddZero() const +{ + DdNode *result = Cudd_ReadLogicZero(p->manager); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::bddZero + + +ADD +Cudd::addVar() const +{ + DdNode *result = Cudd_addNewVar(p->manager); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addVar + + +ADD +Cudd::addVar( + int index) const +{ + DdNode *result = Cudd_addIthVar(p->manager,index); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addVar + + +ADD +Cudd::addOne() const +{ + DdNode *result = Cudd_ReadOne(p->manager); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addOne + + +ADD +Cudd::addZero() const +{ + DdNode *result = Cudd_ReadZero(p->manager); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addZero + + +ADD +Cudd::constant( + CUDD_VALUE_TYPE c) const +{ + DdNode *result = Cudd_addConst(p->manager, c); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::constant + + +ADD +Cudd::plusInfinity() const +{ + DdNode *result = Cudd_ReadPlusInfinity(p->manager); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::plusInfinity + + +ADD +Cudd::minusInfinity() const +{ + DdNode *result = Cudd_ReadMinusInfinity(p->manager); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::minusInfinity + + +ZDD +Cudd::zddVar( + int index) const +{ + DdNode *result = Cudd_zddIthVar(p->manager,index); + checkReturnValue(result); + return ZDD(p, result); + +} // Cudd::zddVar + + +ZDD +Cudd::zddOne( + int i) const +{ + DdNode *result = Cudd_ReadZddOne(p->manager,i); + checkReturnValue(result); + return ZDD(p, result); + +} // Cudd::zddOne + + +ZDD +Cudd::zddZero() const +{ + DdNode *result = Cudd_ReadZero(p->manager); + checkReturnValue(result); + return ZDD(p, result); + +} // Cudd::zddZero + + +void +defaultError( + string message) +{ + cerr << message << endl; + assert(false); + +} // defaultError + + +// --------------------------------------------------------------------------- +// All the rest +// --------------------------------------------------------------------------- + + + +ADD +Cudd::addNewVarAtLevel( + int level) const +{ + DdNode *result = Cudd_addNewVarAtLevel(p->manager, level); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addNewVarAtLevel + + +BDD +Cudd::bddNewVarAtLevel( + int level) const +{ + DdNode *result = Cudd_bddNewVarAtLevel(p->manager, level); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::bddNewVarAtLevel + + +void +Cudd::zddVarsFromBddVars( + int multiplicity) const +{ + int result = Cudd_zddVarsFromBddVars(p->manager, multiplicity); + checkReturnValue(result); + +} // Cudd::zddVarsFromBddVars + + +unsigned long +Cudd::ReadStartTime() const +{ + return Cudd_ReadStartTime(p->manager); + +} // Cudd::ReadStartTime + + +unsigned long +Cudd::ReadElapsedTime() const +{ + return Cudd_ReadElapsedTime(p->manager); + +} // Cudd::ReadElapsedTime + + +void +Cudd::SetStartTime( + unsigned long st) const +{ + Cudd_SetStartTime(p->manager, st); + +} // Cudd::SetStartTime + + +void +Cudd::ResetStartTime() const +{ + Cudd_ResetStartTime(p->manager); + +} // Cudd::ResetStartTime + + +unsigned long +Cudd::ReadTimeLimit() const +{ + return Cudd_ReadTimeLimit(p->manager); + +} // Cudd::ReadTimeLimit + + +void +Cudd::SetTimeLimit( + unsigned long tl) const +{ + Cudd_SetTimeLimit(p->manager, tl); + +} // Cudd::SetTimeLimit + + +void +Cudd::UpdateTimeLimit() const +{ + Cudd_UpdateTimeLimit(p->manager); + +} // Cudd::UpdateTimeLimit + + +void +Cudd::IncreaseTimeLimit( + unsigned long increase) const +{ + Cudd_IncreaseTimeLimit(p->manager, increase); + +} // Cudd::IncreaseTimeLimit + + +void +Cudd::UnsetTimeLimit() const +{ + Cudd_UnsetTimeLimit(p->manager); + +} // Cudd::UnsetTimeLimit + + +bool +Cudd::TimeLimited() const +{ + return Cudd_TimeLimited(p->manager); + +} // Cudd::TimeLimited + + +void +Cudd::AutodynEnable( + Cudd_ReorderingType method) const +{ + Cudd_AutodynEnable(p->manager, method); + +} // Cudd::AutodynEnable + + +void +Cudd::AutodynDisable() const +{ + Cudd_AutodynDisable(p->manager); + +} // Cudd::AutodynDisable + + +bool +Cudd::ReorderingStatus( + Cudd_ReorderingType * method) const +{ + return Cudd_ReorderingStatus(p->manager, method); + +} // Cudd::ReorderingStatus + + +void +Cudd::AutodynEnableZdd( + Cudd_ReorderingType method) const +{ + Cudd_AutodynEnableZdd(p->manager, method); + +} // Cudd::AutodynEnableZdd + + +void +Cudd::AutodynDisableZdd() const +{ + Cudd_AutodynDisableZdd(p->manager); + +} // Cudd::AutodynDisableZdd + + +bool +Cudd::ReorderingStatusZdd( + Cudd_ReorderingType * method) const +{ + return Cudd_ReorderingStatusZdd(p->manager, method); + +} // Cudd::ReorderingStatusZdd + + +bool +Cudd::zddRealignmentEnabled() const +{ + return Cudd_zddRealignmentEnabled(p->manager); + +} // Cudd::zddRealignmentEnabled + + +void +Cudd::zddRealignEnable() const +{ + Cudd_zddRealignEnable(p->manager); + +} // Cudd::zddRealignEnable + + +void +Cudd::zddRealignDisable() const +{ + Cudd_zddRealignDisable(p->manager); + +} // Cudd::zddRealignDisable + + +bool +Cudd::bddRealignmentEnabled() const +{ + return Cudd_bddRealignmentEnabled(p->manager); + +} // Cudd::bddRealignmentEnabled + + +void +Cudd::bddRealignEnable() const +{ + Cudd_bddRealignEnable(p->manager); + +} // Cudd::bddRealignEnable + + +void +Cudd::bddRealignDisable() const +{ + Cudd_bddRealignDisable(p->manager); + +} // Cudd::bddRealignDisable + + +ADD +Cudd::background() const +{ + DdNode *result = Cudd_ReadBackground(p->manager); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::background + + +void +Cudd::SetBackground( + ADD bg) const +{ + DdManager *mgr = p->manager; + if (mgr != bg.manager()) { + p->errorHandler("Background comes from different manager."); + } + Cudd_SetBackground(mgr, bg.getNode()); + +} // Cudd::SetBackground + + +unsigned int +Cudd::ReadCacheSlots() const +{ + return Cudd_ReadCacheSlots(p->manager); + +} // Cudd::ReadCacheSlots + + +double +Cudd::ReadCacheLookUps() const +{ + return Cudd_ReadCacheLookUps(p->manager); + +} // Cudd::ReadCacheLookUps + + +double +Cudd::ReadCacheUsedSlots() const +{ + return Cudd_ReadCacheUsedSlots(p->manager); + +} // Cudd::ReadCacheUsedSlots + + +double +Cudd::ReadCacheHits() const +{ + return Cudd_ReadCacheHits(p->manager); + +} // Cudd::ReadCacheHits + + +unsigned int +Cudd::ReadMinHit() const +{ + return Cudd_ReadMinHit(p->manager); + +} // Cudd::ReadMinHit + + +void +Cudd::SetMinHit( + unsigned int hr) const +{ + Cudd_SetMinHit(p->manager, hr); + +} // Cudd::SetMinHit + + +unsigned int +Cudd::ReadLooseUpTo() const +{ + return Cudd_ReadLooseUpTo(p->manager); + +} // Cudd::ReadLooseUpTo + + +void +Cudd::SetLooseUpTo( + unsigned int lut) const +{ + Cudd_SetLooseUpTo(p->manager, lut); + +} // Cudd::SetLooseUpTo + + +unsigned int +Cudd::ReadMaxCache() const +{ + return Cudd_ReadMaxCache(p->manager); + +} // Cudd::ReadMaxCache + + +unsigned int +Cudd::ReadMaxCacheHard() const +{ + return Cudd_ReadMaxCacheHard(p->manager); + +} // Cudd::ReadMaxCacheHard + + +void +Cudd::SetMaxCacheHard( + unsigned int mc) const +{ + Cudd_SetMaxCacheHard(p->manager, mc); + +} // Cudd::SetMaxCacheHard + + +int +Cudd::ReadSize() const +{ + return Cudd_ReadSize(p->manager); + +} // Cudd::ReadSize + + +int +Cudd::ReadZddSize() const +{ + return Cudd_ReadZddSize(p->manager); + +} // Cudd::ReadZddSize + + +unsigned int +Cudd::ReadSlots() const +{ + return Cudd_ReadSlots(p->manager); + +} // Cudd::ReadSlots + + +unsigned int +Cudd::ReadKeys() const +{ + return Cudd_ReadKeys(p->manager); + +} // Cudd::ReadKeys + + +unsigned int +Cudd::ReadDead() const +{ + return Cudd_ReadDead(p->manager); + +} // Cudd::ReadDead + + +unsigned int +Cudd::ReadMinDead() const +{ + return Cudd_ReadMinDead(p->manager); + +} // Cudd::ReadMinDead + + +unsigned int +Cudd::ReadReorderings() const +{ + return Cudd_ReadReorderings(p->manager); + +} // Cudd::ReadReorderings + + +unsigned int +Cudd::ReadMaxReorderings() const +{ + return Cudd_ReadMaxReorderings(p->manager); + +} // Cudd::ReadMaxReorderings + +void +Cudd::SetMaxReorderings( + unsigned int mr) const +{ + Cudd_SetMaxReorderings(p->manager, mr); + +} // Cudd::SetMaxReorderings + +long +Cudd::ReadReorderingTime() const +{ + return Cudd_ReadReorderingTime(p->manager); + +} // Cudd::ReadReorderingTime + + +int +Cudd::ReadGarbageCollections() const +{ + return Cudd_ReadGarbageCollections(p->manager); + +} // Cudd::ReadGarbageCollections + + +long +Cudd::ReadGarbageCollectionTime() const +{ + return Cudd_ReadGarbageCollectionTime(p->manager); + +} // Cudd::ReadGarbageCollectionTime + + +int +Cudd::ReadSiftMaxVar() const +{ + return Cudd_ReadSiftMaxVar(p->manager); + +} // Cudd::ReadSiftMaxVar + + +void +Cudd::SetSiftMaxVar( + int smv) const +{ + Cudd_SetSiftMaxVar(p->manager, smv); + +} // Cudd::SetSiftMaxVar + + +int +Cudd::ReadSiftMaxSwap() const +{ + return Cudd_ReadSiftMaxSwap(p->manager); + +} // Cudd::ReadSiftMaxSwap + + +void +Cudd::SetSiftMaxSwap( + int sms) const +{ + Cudd_SetSiftMaxSwap(p->manager, sms); + +} // Cudd::SetSiftMaxSwap + + +double +Cudd::ReadMaxGrowth() const +{ + return Cudd_ReadMaxGrowth(p->manager); + +} // Cudd::ReadMaxGrowth + + +void +Cudd::SetMaxGrowth( + double mg) const +{ + Cudd_SetMaxGrowth(p->manager, mg); + +} // Cudd::SetMaxGrowth + + +MtrNode * +Cudd::ReadTree() const +{ + return Cudd_ReadTree(p->manager); + +} // Cudd::ReadTree + + +void +Cudd::SetTree( + MtrNode * tree) const +{ + Cudd_SetTree(p->manager, tree); + +} // Cudd::SetTree + + +void +Cudd::FreeTree() const +{ + Cudd_FreeTree(p->manager); + +} // Cudd::FreeTree + + +MtrNode * +Cudd::ReadZddTree() const +{ + return Cudd_ReadZddTree(p->manager); + +} // Cudd::ReadZddTree + + +void +Cudd::SetZddTree( + MtrNode * tree) const +{ + Cudd_SetZddTree(p->manager, tree); + +} // Cudd::SetZddTree + + +void +Cudd::FreeZddTree() const +{ + Cudd_FreeZddTree(p->manager); + +} // Cudd::FreeZddTree + + +int +Cudd::ReadPerm( + int i) const +{ + return Cudd_ReadPerm(p->manager, i); + +} // Cudd::ReadPerm + + +int +Cudd::ReadPermZdd( + int i) const +{ + return Cudd_ReadPermZdd(p->manager, i); + +} // Cudd::ReadPermZdd + + +int +Cudd::ReadInvPerm( + int i) const +{ + return Cudd_ReadInvPerm(p->manager, i); + +} // Cudd::ReadInvPerm + + +int +Cudd::ReadInvPermZdd( + int i) const +{ + return Cudd_ReadInvPermZdd(p->manager, i); + +} // Cudd::ReadInvPermZdd + + +BDD +Cudd::ReadVars( + int i) const +{ + DdNode *result = Cudd_ReadVars(p->manager, i); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::ReadVars + + +CUDD_VALUE_TYPE +Cudd::ReadEpsilon() const +{ + return Cudd_ReadEpsilon(p->manager); + +} // Cudd::ReadEpsilon + + +void +Cudd::SetEpsilon( + CUDD_VALUE_TYPE ep) const +{ + Cudd_SetEpsilon(p->manager, ep); + +} // Cudd::SetEpsilon + + +Cudd_AggregationType +Cudd::ReadGroupcheck() const +{ + return Cudd_ReadGroupcheck(p->manager); + +} // Cudd::ReadGroupcheck + + +void +Cudd::SetGroupcheck( + Cudd_AggregationType gc) const +{ + Cudd_SetGroupcheck(p->manager, gc); + +} // Cudd::SetGroupcheck + + +bool +Cudd::GarbageCollectionEnabled() const +{ + return Cudd_GarbageCollectionEnabled(p->manager); + +} // Cudd::GarbageCollectionEnabled + + +void +Cudd::EnableGarbageCollection() const +{ + Cudd_EnableGarbageCollection(p->manager); + +} // Cudd::EnableGarbageCollection + + +void +Cudd::DisableGarbageCollection() const +{ + Cudd_DisableGarbageCollection(p->manager); + +} // Cudd::DisableGarbageCollection + + +bool +Cudd::DeadAreCounted() const +{ + return Cudd_DeadAreCounted(p->manager); + +} // Cudd::DeadAreCounted + + +void +Cudd::TurnOnCountDead() const +{ + Cudd_TurnOnCountDead(p->manager); + +} // Cudd::TurnOnCountDead + + +void +Cudd::TurnOffCountDead() const +{ + Cudd_TurnOffCountDead(p->manager); + +} // Cudd::TurnOffCountDead + + +int +Cudd::ReadRecomb() const +{ + return Cudd_ReadRecomb(p->manager); + +} // Cudd::ReadRecomb + + +void +Cudd::SetRecomb( + int recomb) const +{ + Cudd_SetRecomb(p->manager, recomb); + +} // Cudd::SetRecomb + + +int +Cudd::ReadSymmviolation() const +{ + return Cudd_ReadSymmviolation(p->manager); + +} // Cudd::ReadSymmviolation + + +void +Cudd::SetSymmviolation( + int symmviolation) const +{ + Cudd_SetSymmviolation(p->manager, symmviolation); + +} // Cudd::SetSymmviolation + + +int +Cudd::ReadArcviolation() const +{ + return Cudd_ReadArcviolation(p->manager); + +} // Cudd::ReadArcviolation + + +void +Cudd::SetArcviolation( + int arcviolation) const +{ + Cudd_SetArcviolation(p->manager, arcviolation); + +} // Cudd::SetArcviolation + + +int +Cudd::ReadPopulationSize() const +{ + return Cudd_ReadPopulationSize(p->manager); + +} // Cudd::ReadPopulationSize + + +void +Cudd::SetPopulationSize( + int populationSize) const +{ + Cudd_SetPopulationSize(p->manager, populationSize); + +} // Cudd::SetPopulationSize + + +int +Cudd::ReadNumberXovers() const +{ + return Cudd_ReadNumberXovers(p->manager); + +} // Cudd::ReadNumberXovers + + +void +Cudd::SetNumberXovers( + int numberXovers) const +{ + Cudd_SetNumberXovers(p->manager, numberXovers); + +} // Cudd::SetNumberXovers + + +unsigned int +Cudd::ReadOrderRandomization() const +{ + return Cudd_ReadOrderRandomization(p->manager); + +} // Cudd::ReadOrderRandomization + + +void +Cudd::SetOrderRandomization( + unsigned int factor) const +{ + Cudd_SetOrderRandomization(p->manager, factor); + +} // Cudd::SetOrderRandomization + + +unsigned long +Cudd::ReadMemoryInUse() const +{ + return Cudd_ReadMemoryInUse(p->manager); + +} // Cudd::ReadMemoryInUse + + +long +Cudd::ReadPeakNodeCount() const +{ + return Cudd_ReadPeakNodeCount(p->manager); + +} // Cudd::ReadPeakNodeCount + + +long +Cudd::ReadNodeCount() const +{ + return Cudd_ReadNodeCount(p->manager); + +} // Cudd::ReadNodeCount + + +long +Cudd::zddReadNodeCount() const +{ + return Cudd_zddReadNodeCount(p->manager); + +} // Cudd::zddReadNodeCount + + +void +Cudd::AddHook( + DD_HFP f, + Cudd_HookType where) const +{ + int result = Cudd_AddHook(p->manager, f, where); + checkReturnValue(result); + +} // Cudd::AddHook + + +void +Cudd::RemoveHook( + DD_HFP f, + Cudd_HookType where) const +{ + int result = Cudd_RemoveHook(p->manager, f, where); + checkReturnValue(result); + +} // Cudd::RemoveHook + + +bool +Cudd::IsInHook( + DD_HFP f, + Cudd_HookType where) const +{ + return Cudd_IsInHook(p->manager, f, where); + +} // Cudd::IsInHook + + +void +Cudd::EnableReorderingReporting() const +{ + int result = Cudd_EnableReorderingReporting(p->manager); + checkReturnValue(result); + +} // Cudd::EnableReorderingReporting + + +void +Cudd::DisableReorderingReporting() const +{ + int result = Cudd_DisableReorderingReporting(p->manager); + checkReturnValue(result); + +} // Cudd::DisableReorderingReporting + + +bool +Cudd::ReorderingReporting() const +{ + return Cudd_ReorderingReporting(p->manager); + +} // Cudd::ReorderingReporting + + +int +Cudd::ReadErrorCode() const +{ + return Cudd_ReadErrorCode(p->manager); + +} // Cudd::ReadErrorCode + + +void +Cudd::ClearErrorCode() const +{ + Cudd_ClearErrorCode(p->manager); + +} // Cudd::ClearErrorCode + + +FILE * +Cudd::ReadStdout() const +{ + return Cudd_ReadStdout(p->manager); + +} // Cudd::ReadStdout + + +void +Cudd::SetStdout(FILE *fp) const +{ + Cudd_SetStdout(p->manager, fp); + +} // Cudd::SetStdout + + +FILE * +Cudd::ReadStderr() const +{ + return Cudd_ReadStderr(p->manager); + +} // Cudd::ReadStderr + + +void +Cudd::SetStderr(FILE *fp) const +{ + Cudd_SetStderr(p->manager, fp); + +} // Cudd::SetStderr + + +unsigned int +Cudd::ReadNextReordering() const +{ + return Cudd_ReadNextReordering(p->manager); + +} // Cudd::ReadNextReordering + + +void +Cudd::SetNextReordering( + unsigned int next) const +{ + Cudd_SetNextReordering(p->manager, next); + +} // Cudd::SetNextReordering + + +double +Cudd::ReadSwapSteps() const +{ + return Cudd_ReadSwapSteps(p->manager); + +} // Cudd::ReadSwapSteps + + +unsigned int +Cudd::ReadMaxLive() const +{ + return Cudd_ReadMaxLive(p->manager); + +} // Cudd::ReadMaxLive + + +void +Cudd::SetMaxLive(unsigned int maxLive) const +{ + Cudd_SetMaxLive(p->manager, maxLive); + +} // Cudd::SetMaxLive + + +unsigned long +Cudd::ReadMaxMemory() const +{ + return Cudd_ReadMaxMemory(p->manager); + +} // Cudd::ReadMaxMemory + + +void +Cudd::SetMaxMemory(unsigned long maxMem) const +{ + Cudd_SetMaxMemory(p->manager, maxMem); + +} // Cudd::SetMaxMemory + + +int +Cudd::bddBindVar(int index) const +{ + return Cudd_bddBindVar(p->manager, index); + +} // Cudd::bddBindVar + + +int +Cudd::bddUnbindVar(int index) const +{ + return Cudd_bddUnbindVar(p->manager, index); + +} // Cudd::bddUnbindVar + + +bool +Cudd::bddVarIsBound(int index) const +{ + return Cudd_bddVarIsBound(p->manager, index); + +} // Cudd::bddVarIsBound + + +ADD +ADD::ExistAbstract( + const ADD& cube) const +{ + DdManager *mgr = checkSameManager(cube); + DdNode *result = Cudd_addExistAbstract(mgr, node, cube.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::ExistAbstract + + +ADD +ADD::UnivAbstract( + const ADD& cube) const +{ + DdManager *mgr = checkSameManager(cube); + DdNode *result = Cudd_addUnivAbstract(mgr, node, cube.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::UnivAbstract + + +ADD +ADD::OrAbstract( + const ADD& cube) const +{ + DdManager *mgr = checkSameManager(cube); + DdNode *result = Cudd_addOrAbstract(mgr, node, cube.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::OrAbstract + + +ADD +ADD::Plus( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addPlus, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Plus + + +ADD +ADD::Times( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addTimes, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Times + + +ADD +ADD::Threshold( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addThreshold, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Threshold + + +ADD +ADD::SetNZ( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addSetNZ, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::SetNZ + + +ADD +ADD::Divide( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addDivide, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Divide + + +ADD +ADD::Minus( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addMinus, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Minus + + +ADD +ADD::Minimum( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addMinimum, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Minimum + + +ADD +ADD::Maximum( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addMaximum, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Maximum + + +ADD +ADD::OneZeroMaximum( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addOneZeroMaximum, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::OneZeroMaximum + + +ADD +ADD::Diff( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addDiff, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Diff + + +ADD +ADD::Agreement( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addAgreement, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Agreement + + +ADD +ADD::Or( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addOr, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Or + + +ADD +ADD::Nand( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addNand, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Nand + + +ADD +ADD::Nor( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addNor, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Nor + + +ADD +ADD::Xor( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addXor, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Xor + + +ADD +ADD::Xnor( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addXnor, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Xnor + + +ADD +ADD::Log() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addMonadicApply(mgr, Cudd_addLog, node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Log + + +ADD +ADD::FindMax() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addFindMax(mgr, node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::FindMax + + +ADD +ADD::FindMin() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addFindMin(mgr, node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::FindMin + + +ADD +ADD::IthBit( + int bit) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addIthBit(mgr, node, bit); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::IthBit + + +ADD +ADD::ScalarInverse( + const ADD& epsilon) const +{ + DdManager *mgr = checkSameManager(epsilon); + DdNode *result = Cudd_addScalarInverse(mgr, node, epsilon.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::ScalarInverse + + +ADD +ADD::Ite( + const ADD& g, + const ADD& h) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(h); + DdNode *result = Cudd_addIte(mgr, node, g.node, h.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Ite + + +ADD +ADD::IteConstant( + const ADD& g, + const ADD& h) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(h); + DdNode *result = Cudd_addIteConstant(mgr, node, g.node, h.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::IteConstant + + +ADD +ADD::EvalConst( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addEvalConst(mgr, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::EvalConst + + +bool +ADD::Leq( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + return Cudd_addLeq(mgr, node, g.node); + +} // ADD::Leq + + +ADD +ADD::Cmpl() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addCmpl(mgr, node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Cmpl + + +ADD +ADD::Negate() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addNegate(mgr, node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Negate + + +ADD +ADD::RoundOff( + int N) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addRoundOff(mgr, node, N); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::RoundOff + + +ADD +Cudd::Walsh( + vector x, + vector y) +{ + int n = x.size(); + DdNode **X = new DdNode *[n]; + DdNode **Y = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + } + DdNode *result = Cudd_addWalsh(p->manager, X, Y, n); + delete [] X; + delete [] Y; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Walsh + + +ADD +Cudd::addResidue( + int n, + int m, + int options, + int top) +{ + DdNode *result = Cudd_addResidue(p->manager, n, m, options, top); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addResidue + + +BDD +BDD::AndAbstract( + const BDD& g, + const BDD& cube, + unsigned int limit) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(cube); + DdNode *result; + if (limit == 0) + result = Cudd_bddAndAbstract(mgr, node, g.node, cube.node); + else + result = Cudd_bddAndAbstractLimit(mgr, node, g.node, + cube.node, limit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::AndAbstract + + +int +Cudd::ApaNumberOfDigits( + int binaryDigits) const +{ + return Cudd_ApaNumberOfDigits(binaryDigits); + +} // Cudd::ApaNumberOfDigits + + +DdApaNumber +Cudd::NewApaNumber( + int digits) const +{ + return Cudd_NewApaNumber(digits); + +} // Cudd::NewApaNumber + + +void +Cudd::ApaCopy( + int digits, + DdApaNumber source, + DdApaNumber dest) const +{ + Cudd_ApaCopy(digits, source, dest); + +} // Cudd::ApaCopy + + +DdApaDigit +Cudd::ApaAdd( + int digits, + DdApaNumber a, + DdApaNumber b, + DdApaNumber sum) const +{ + return Cudd_ApaAdd(digits, a, b, sum); + +} // Cudd::ApaAdd + + +DdApaDigit +Cudd::ApaSubtract( + int digits, + DdApaNumber a, + DdApaNumber b, + DdApaNumber diff) const +{ + return Cudd_ApaSubtract(digits, a, b, diff); + +} // Cudd::ApaSubtract + + +DdApaDigit +Cudd::ApaShortDivision( + int digits, + DdApaNumber dividend, + DdApaDigit divisor, + DdApaNumber quotient) const +{ + return Cudd_ApaShortDivision(digits, dividend, divisor, quotient); + +} // Cudd::ApaShortDivision + + +void +Cudd::ApaShiftRight( + int digits, + DdApaDigit in, + DdApaNumber a, + DdApaNumber b) const +{ + Cudd_ApaShiftRight(digits, in, a, b); + +} // Cudd::ApaShiftRight + + +void +Cudd::ApaSetToLiteral( + int digits, + DdApaNumber number, + DdApaDigit literal) const +{ + Cudd_ApaSetToLiteral(digits, number, literal); + +} // Cudd::ApaSetToLiteral + + +void +Cudd::ApaPowerOfTwo( + int digits, + DdApaNumber number, + int power) const +{ + Cudd_ApaPowerOfTwo(digits, number, power); + +} // Cudd::ApaPowerOfTwo + + +void +Cudd::ApaPrintHex( + FILE * fp, + int digits, + DdApaNumber number) const +{ + cout.flush(); + int result = Cudd_ApaPrintHex(fp, digits, number); + checkReturnValue(result); + +} // Cudd::ApaPrintHex + + +void +Cudd::ApaPrintDecimal( + FILE * fp, + int digits, + DdApaNumber number) const +{ + cout.flush(); + int result = Cudd_ApaPrintDecimal(fp, digits, number); + checkReturnValue(result); + +} // Cudd::ApaPrintDecimal + + +DdApaNumber +ABDD::ApaCountMinterm( + int nvars, + int * digits) const +{ + DdManager *mgr = p->manager; + return Cudd_ApaCountMinterm(mgr, node, nvars, digits); + +} // ABDD::ApaCountMinterm + + +void +ABDD::ApaPrintMinterm( + int nvars, + FILE * fp) const +{ + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_ApaPrintMinterm(fp, mgr, node, nvars); + checkReturnValue(result); + +} // ABDD::ApaPrintMinterm + + +void +ABDD::EpdPrintMinterm( + int nvars, + FILE * fp) const +{ + EpDouble count; + char str[24]; + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_EpdCountMinterm(mgr, node, nvars, &count); + checkReturnValue(result,0); + EpdGetString(&count, str); + fprintf(fp, "%s\n", str); + +} // ABDD::ApaPrintMinterm + + +BDD +BDD::UnderApprox( + int numVars, + int threshold, + bool safe, + double quality) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_UnderApprox(mgr, node, numVars, threshold, safe, quality); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::UnderApprox + + +BDD +BDD::OverApprox( + int numVars, + int threshold, + bool safe, + double quality) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_OverApprox(mgr, node, numVars, threshold, safe, quality); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::OverApprox + + +BDD +BDD::RemapUnderApprox( + int numVars, + int threshold, + double quality) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_RemapUnderApprox(mgr, node, numVars, threshold, quality); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::RemapUnderApprox + + +BDD +BDD::RemapOverApprox( + int numVars, + int threshold, + double quality) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_RemapOverApprox(mgr, node, numVars, threshold, quality); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::RemapOverApprox + + +BDD +BDD::BiasedUnderApprox( + const BDD& bias, + int numVars, + int threshold, + double quality1, + double quality0) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_BiasedUnderApprox(mgr, node, bias.node, numVars, + threshold, quality1, quality0); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::BiasedUnderApprox + + +BDD +BDD::BiasedOverApprox( + const BDD& bias, + int numVars, + int threshold, + double quality1, + double quality0) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_BiasedOverApprox(mgr, node, bias.node, numVars, + threshold, quality1, quality0); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::BiasedOverApprox + + +BDD +BDD::ExistAbstract( + const BDD& cube, + unsigned int limit) const +{ + DdManager *mgr = checkSameManager(cube); + DdNode *result; + if (limit == 0) + result = Cudd_bddExistAbstract(mgr, node, cube.node); + else + result = Cudd_bddExistAbstractLimit(mgr, node, cube.node, limit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::ExistAbstract + + +BDD +BDD::XorExistAbstract( + const BDD& g, + const BDD& cube) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(cube); + DdNode *result = Cudd_bddXorExistAbstract(mgr, node, g.node, cube.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::XorExistAbstract + + +BDD +BDD::UnivAbstract( + const BDD& cube) const +{ + DdManager *mgr = checkSameManager(cube); + DdNode *result = Cudd_bddUnivAbstract(mgr, node, cube.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::UnivAbstract + + +BDD +BDD::BooleanDiff( + int x) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_bddBooleanDiff(mgr, node, x); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::BooleanDiff + + +bool +BDD::VarIsDependent( + const BDD& var) const +{ + DdManager *mgr = p->manager; + return Cudd_bddVarIsDependent(mgr, node, var.node); + +} // BDD::VarIsDependent + + +double +BDD::Correlation( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + return Cudd_bddCorrelation(mgr, node, g.node); + +} // BDD::Correlation + + +double +BDD::CorrelationWeights( + const BDD& g, + double * prob) const +{ + DdManager *mgr = checkSameManager(g); + return Cudd_bddCorrelationWeights(mgr, node, g.node, prob); + +} // BDD::CorrelationWeights + + +BDD +BDD::Ite( + const BDD& g, + const BDD& h, + unsigned int limit) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(h); + DdNode *result; + if (limit == 0) + result = Cudd_bddIte(mgr, node, g.node, h.node); + else + result = Cudd_bddIteLimit(mgr, node, g.node, h.node, limit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Ite + + +BDD +BDD::IteConstant( + const BDD& g, + const BDD& h) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(h); + DdNode *result = Cudd_bddIteConstant(mgr, node, g.node, h.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::IteConstant + + +BDD +BDD::Intersect( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddIntersect(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Intersect + + +BDD +BDD::And( + const BDD& g, + unsigned int limit) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result; + if (limit == 0) + result = Cudd_bddAnd(mgr, node, g.node); + else + result = Cudd_bddAndLimit(mgr, node, g.node, limit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::And + + +BDD +BDD::Or( + const BDD& g, + unsigned int limit) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result; + if (limit == 0) + result = Cudd_bddOr(mgr, node, g.node); + else + result = Cudd_bddOrLimit(mgr, node, g.node, limit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Or + + +BDD +BDD::Nand( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddNand(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Nand + + +BDD +BDD::Nor( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddNor(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Nor + + +BDD +BDD::Xor( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddXor(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Xor + + +BDD +BDD::Xnor( + const BDD& g, + unsigned int limit) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result; + if (limit == 0) + result = Cudd_bddXnor(mgr, node, g.node); + else + result = Cudd_bddXnorLimit(mgr, node, g.node, limit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Xnor + + +bool +BDD::Leq( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + return Cudd_bddLeq(mgr, node, g.node); + +} // BDD::Leq + + +BDD +ADD::BddThreshold( + CUDD_VALUE_TYPE value) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addBddThreshold(mgr, node, value); + checkReturnValue(result); + return BDD(p, result); + +} // ADD::BddThreshold + + +BDD +ADD::BddStrictThreshold( + CUDD_VALUE_TYPE value) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addBddStrictThreshold(mgr, node, value); + checkReturnValue(result); + return BDD(p, result); + +} // ADD::BddStrictThreshold + + +BDD +ADD::BddInterval( + CUDD_VALUE_TYPE lower, + CUDD_VALUE_TYPE upper) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addBddInterval(mgr, node, lower, upper); + checkReturnValue(result); + return BDD(p, result); + +} // ADD::BddInterval + + +BDD +ADD::BddIthBit( + int bit) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addBddIthBit(mgr, node, bit); + checkReturnValue(result); + return BDD(p, result); + +} // ADD::BddIthBit + + +ADD +BDD::Add() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_BddToAdd(mgr, node); + checkReturnValue(result); + return ADD(p, result); + +} // BDD::Add + + +BDD +ADD::BddPattern() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addBddPattern(mgr, node); + checkReturnValue(result); + return BDD(p, result); + +} // ADD::BddPattern + + +BDD +BDD::Transfer( + Cudd& destination) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_bddTransfer(mgr, destination.p->manager, node); + checkReturnValue(result); + return BDD(destination.p, result); + +} // BDD::Transfer + + +void +Cudd::DebugCheck() +{ + int result = Cudd_DebugCheck(p->manager); + checkReturnValue(result == 0); + +} // Cudd::DebugCheck + + +void +Cudd::CheckKeys() +{ + int result = Cudd_CheckKeys(p->manager); + checkReturnValue(result == 0); + +} // Cudd::CheckKeys + + +BDD +BDD::ClippingAnd( + const BDD& g, + int maxDepth, + int direction) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddClippingAnd(mgr, node, g.node, maxDepth, + direction); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::ClippingAnd + + +BDD +BDD::ClippingAndAbstract( + const BDD& g, + const BDD& cube, + int maxDepth, + int direction) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(cube); + DdNode *result = Cudd_bddClippingAndAbstract(mgr, node, g.node, cube.node, + maxDepth, direction); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::ClippingAndAbstract + + +ADD +ADD::Cofactor( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_Cofactor(mgr, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Cofactor + + +BDD +BDD::Cofactor( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_Cofactor(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Cofactor + + +BDD +BDD::Compose( + const BDD& g, + int v) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddCompose(mgr, node, g.node, v); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Compose + + +ADD +ADD::Compose( + const ADD& g, + int v) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addCompose(mgr, node, g.node, v); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Compose + + +ADD +ADD::Permute( + int * permut) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addPermute(mgr, node, permut); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Permute + + +ADD +ADD::SwapVariables( + vector x, + vector y) const +{ + int n = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[n]; + DdNode **Y = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = x[i].node; + Y[i] = y[i].node; + } + DdNode *result = Cudd_addSwapVariables(mgr, node, X, Y, n); + delete [] X; + delete [] Y; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::SwapVariables + + +BDD +BDD::Permute( + int * permut) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_bddPermute(mgr, node, permut); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Permute + + +BDD +BDD::SwapVariables( + std::vector x, + std::vector y) const +{ + int n = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[n]; + DdNode **Y = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = x[i].node; + Y[i] = y[i].node; + } + DdNode *result = Cudd_bddSwapVariables(mgr, node, X, Y, n); + delete [] X; + delete [] Y; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SwapVariables + + +BDD +BDD::AdjPermuteX( + vector x) const +{ + int n = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = x[i].node; + } + DdNode *result = Cudd_bddAdjPermuteX(mgr, node, X, n); + delete [] X; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::AdjPermuteX + + +ADD +ADD::VectorCompose( + vector vector) const +{ + DdManager *mgr = p->manager; + int n = Cudd_ReadSize(mgr); + DdNode **X = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = vector[i].node; + } + DdNode *result = Cudd_addVectorCompose(mgr, node, X); + delete [] X; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::VectorCompose + + +ADD +ADD::NonSimCompose( + vector vector) const +{ + DdManager *mgr = p->manager; + int n = Cudd_ReadSize(mgr); + DdNode **X = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = vector[i].node; + } + DdNode *result = Cudd_addNonSimCompose(mgr, node, X); + delete [] X; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::NonSimCompose + + +BDD +BDD::VectorCompose( + vector vector) const +{ + DdManager *mgr = p->manager; + int n = Cudd_ReadSize(mgr); + DdNode **X = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = vector[i].node; + } + DdNode *result = Cudd_bddVectorCompose(mgr, node, X); + delete [] X; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::VectorCompose + + +void +BDD::ApproxConjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddApproxConjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::ApproxConjDecomp + + +void +BDD::ApproxDisjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddApproxDisjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::ApproxDisjDecomp + + +void +BDD::IterConjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddIterConjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::IterConjDecomp + + +void +BDD::IterDisjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddIterDisjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::IterDisjDecomp + + +void +BDD::GenConjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddGenConjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::GenConjDecomp + + +void +BDD::GenDisjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddGenDisjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::GenDisjDecomp + + +void +BDD::VarConjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddVarConjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::VarConjDecomp + + +void +BDD::VarDisjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddVarDisjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::VarDisjDecomp + + +bool +ABDD::IsCube() const +{ + DdManager *mgr = p->manager; + return Cudd_CheckCube(mgr, node); + +} // ABDD::IsCube + + +BDD +ABDD::FindEssential() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_FindEssential(mgr, node); + checkReturnValue(result); + return BDD(p, result); + +} // ABDD::FindEssential + + +bool +BDD::IsVarEssential( + int id, + int phase) const +{ + DdManager *mgr = p->manager; + return Cudd_bddIsVarEssential(mgr, node, id, phase); + +} // BDD::IsVarEssential + + +void +ABDD::PrintTwoLiteralClauses( + char **names, + FILE *fp) const +{ + DdManager *mgr = p->manager; + int result = Cudd_PrintTwoLiteralClauses(mgr, node, names, fp); + checkReturnValue(result); + +} // ABDD::PrintTwoLiteralClauses + + +void +Cudd::DumpBlif( + const vector& nodes, + char ** inames, + char ** onames, + char * mname, + FILE * fp, + int mv) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpBlif(mgr, n, F, inames, onames, mname, fp, mv); + delete [] F; + checkReturnValue(result); + +} // vector::DumpBlif + + +void +Cudd::DumpDot( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpDot(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpDot + + +void +Cudd::DumpDot( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpDot(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpDot + + +void +Cudd::DumpDaVinci( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpDaVinci(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpDaVinci + + +void +Cudd::DumpDaVinci( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpDaVinci(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpDaVinci + + +void +Cudd::DumpDDcal( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpDDcal(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpDDcal + + +void +Cudd::DumpFactoredForm( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpFactoredForm(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpFactoredForm + + +BDD +BDD::Constrain( + const BDD& c) const +{ + DdManager *mgr = checkSameManager(c); + DdNode *result = Cudd_bddConstrain(mgr, node, c.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Constrain + + +BDD +BDD::Restrict( + const BDD& c) const +{ + DdManager *mgr = checkSameManager(c); + DdNode *result = Cudd_bddRestrict(mgr, node, c.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Restrict + + +BDD +BDD::NPAnd( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddNPAnd(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::NPAnd + + +ADD +ADD::Constrain( + const ADD& c) const +{ + DdManager *mgr = checkSameManager(c); + DdNode *result = Cudd_addConstrain(mgr, node, c.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Constrain + + +vector +BDD::ConstrainDecomp() const +{ + DdManager *mgr = p->manager; + DdNode **result = Cudd_bddConstrainDecomp(mgr, node); + checkReturnValue((DdNode *)result); + int size = Cudd_ReadSize(mgr); + vector vect; + for (int i = 0; i < size; i++) { + Cudd_Deref(result[i]); + vect.push_back(BDD(p, result[i])); + } + free(result); + return vect; + +} // BDD::ConstrainDecomp + + +ADD +ADD::Restrict( + const ADD& c) const +{ + DdManager *mgr = checkSameManager(c); + DdNode *result = Cudd_addRestrict(mgr, node, c.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Restrict + + +vector +BDD::CharToVect() const +{ + DdManager *mgr = p->manager; + DdNode **result = Cudd_bddCharToVect(mgr, node); + checkReturnValue((DdNode *)result); + int size = Cudd_ReadSize(mgr); + vector vect; + for (int i = 0; i < size; i++) { + Cudd_Deref(result[i]); + vect.push_back(BDD(p, result[i])); + } + free(result); + return vect; + +} // BDD::CharToVect + + +BDD +BDD::LICompaction( + const BDD& c) const +{ + DdManager *mgr = checkSameManager(c); + DdNode *result = Cudd_bddLICompaction(mgr, node, c.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::LICompaction + + +BDD +BDD::Squeeze( + const BDD& u) const +{ + DdManager *mgr = checkSameManager(u); + DdNode *result = Cudd_bddSqueeze(mgr, node, u.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Squeeze + + +BDD +BDD::Minimize( + const BDD& c) const +{ + DdManager *mgr = checkSameManager(c); + DdNode *result = Cudd_bddMinimize(mgr, node, c.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Minimize + + +BDD +BDD::SubsetCompress( + int nvars, + int threshold) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_SubsetCompress(mgr, node, nvars, threshold); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SubsetCompress + + +BDD +BDD::SupersetCompress( + int nvars, + int threshold) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_SupersetCompress(mgr, node, nvars, threshold); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SupersetCompress + + +MtrNode * +Cudd::MakeTreeNode( + unsigned int low, + unsigned int size, + unsigned int type) const +{ + return Cudd_MakeTreeNode(p->manager, low, size, type); + +} // Cudd::MakeTreeNode + + +/* This is incorrect, but we'll wait for this one. +void +Cudd::Harwell( + FILE * fp, + DdManager * dd, + ADD* E, + ADD** x, + ADD** y, + ADD** xn, + ADD** yn_, + int * nx, + int * ny, + int * m, + int * n, + int bx, + int sx, + int by, + int sy, + int pr) +{ + DdManager *mgr = p->manager; + int result = Cudd_addHarwell(fp, mgr, E, x, y, xn, yn_, nx, ny, m, n, bx, sx, by, sy, pr); + checkReturnValue(result); + +} // Cudd::Harwell +*/ + + +void +Cudd::PrintLinear() +{ + cout.flush(); + int result = Cudd_PrintLinear(p->manager); + checkReturnValue(result); + +} // Cudd::PrintLinear + + +int +Cudd::ReadLinear( + int x, + int y) +{ + return Cudd_ReadLinear(p->manager, x, y); + +} // Cudd::ReadLinear + + +BDD +BDD::LiteralSetIntersection( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddLiteralSetIntersection(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::LiteralSetIntersection + + +ADD +ADD::MatrixMultiply( + const ADD& B, + vector z) const +{ + int nz = z.size(); + DdManager *mgr = checkSameManager(B); + DdNode **Z = new DdNode *[nz]; + for (int i = 0; i < nz; i++) { + Z[i] = z[i].node; + } + DdNode *result = Cudd_addMatrixMultiply(mgr, node, B.node, Z, nz); + delete [] Z; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::MatrixMultiply + + +ADD +ADD::TimesPlus( + const ADD& B, + vector z) const +{ + int nz = z.size(); + DdManager *mgr = checkSameManager(B); + DdNode **Z = new DdNode *[nz]; + for (int i = 0; i < nz; i++) { + Z[i] = z[i].node; + } + DdNode *result = Cudd_addTimesPlus(mgr, node, B.node, Z, nz); + delete [] Z; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::TimesPlus + + +ADD +ADD::Triangle( + const ADD& g, + vector z) const +{ + int nz = z.size(); + DdManager *mgr = checkSameManager(g); + DdNode **Z = new DdNode *[nz]; + for (int i = 0; i < nz; i++) { + Z[i] = z[i].node; + } + DdNode *result = Cudd_addTriangle(mgr, node, g.node, Z, nz); + delete [] Z; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Triangle + + +BDD +BDD::PrioritySelect( + vector x, + vector y, + vector z, + const BDD& Pi, + DD_PRFP Pifunc) const +{ + int n = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[n]; + DdNode **Y = new DdNode *[n]; + DdNode **Z = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = x[i].node; + Y[i] = y[i].node; + Z[i] = z[i].node; + } + DdNode *result = Cudd_PrioritySelect(mgr, node, X, Y, Z, Pi.node, n, Pifunc); + delete [] X; + delete [] Y; + delete [] Z; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::PrioritySelect + + +BDD +Cudd::Xgty( + vector z, + vector x, + vector y) +{ + int N = z.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + DdNode **Z = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + Z[i] = z[i].getNode(); + } + DdNode *result = Cudd_Xgty(mgr, N, Z, X, Y); + delete [] X; + delete [] Y; + delete [] Z; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::Xgty + + +BDD +Cudd::Xeqy( + vector x, + vector y) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + } + DdNode *result = Cudd_Xeqy(mgr, N, X, Y); + delete [] X; + delete [] Y; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Xeqy + + +ADD +Cudd::Xeqy( + vector x, + vector y) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + } + DdNode *result = Cudd_addXeqy(mgr, N, X, X); + delete [] X; + delete [] Y; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Xeqy + + +BDD +Cudd::Dxygtdxz( + vector x, + vector y, + vector z) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + DdNode **Z = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + Z[i] = z[i].getNode(); + } + DdNode *result = Cudd_Dxygtdxz(mgr, N, X, Y, Z); + delete [] X; + delete [] Y; + delete [] Z; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::Dxygtdxz + + +BDD +Cudd::Dxygtdyz( + vector x, + vector y, + vector z) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + DdNode **Z = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + Z[i] = z[i].getNode(); + } + DdNode *result = Cudd_Dxygtdyz(mgr, N, X, Y, Z); + delete [] X; + delete [] Y; + delete [] Z; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::Dxygtdyz + + +BDD +Cudd::Inequality( + int c, + vector x, + vector y) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + } + DdNode *result = Cudd_Inequality(mgr, N, c, X, Y); + delete [] X; + delete [] Y; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::Inequality + + +BDD +Cudd::Disequality( + int c, + vector x, + vector y) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + } + DdNode *result = Cudd_Disequality(mgr, N, c, X, Y); + delete [] X; + delete [] Y; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::Disequality + + +BDD +Cudd::Interval( + vector x, + unsigned int lowerB, + unsigned int upperB) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + } + DdNode *result = Cudd_bddInterval(mgr, N, X, lowerB, upperB); + delete [] X; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::Interval + + +BDD +BDD::CProjection( + const BDD& Y) const +{ + DdManager *mgr = checkSameManager(Y); + DdNode *result = Cudd_CProjection(mgr, node, Y.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::CProjection + + +int +BDD::MinHammingDist( + int *minterm, + int upperBound) const +{ + DdManager *mgr = p->manager; + int result = Cudd_MinHammingDist(mgr, node, minterm, upperBound); + return result; + +} // BDD::MinHammingDist + + +ADD +Cudd::Hamming( + vector xVars, + vector yVars) +{ + int nVars = xVars.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[nVars]; + DdNode **Y = new DdNode *[nVars]; + for (int i = 0; i < nVars; i++) { + X[i] = xVars[i].getNode(); + Y[i] = yVars[i].getNode(); + } + DdNode *result = Cudd_addHamming(mgr, X, Y, nVars); + delete [] X; + delete [] Y; + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::Hamming + + +/* We'll leave these two out for the time being. +void +Cudd::Read( + FILE * fp, + ADD* E, + ADD** x, + ADD** y, + ADD** xn, + ADD** yn_, + int * nx, + int * ny, + int * m, + int * n, + int bx, + int sx, + int by, + int sy) +{ + DdManager *mgr = p->manager; + int result = Cudd_addRead(fp, mgr, E, x, y, xn, yn_, nx, ny, m, n, bx, sx, by, sy); + checkReturnValue(result); + +} // Cudd::Read + + +void +Cudd::Read( + FILE * fp, + BDD* E, + BDD** x, + BDD** y, + int * nx, + int * ny, + int * m, + int * n, + int bx, + int sx, + int by, + int sy) +{ + DdManager *mgr = p->manager; + int result = Cudd_bddRead(fp, mgr, E, x, y, nx, ny, m, n, bx, sx, by, sy); + checkReturnValue(result); + +} // Cudd::Read +*/ + + +void +Cudd::ReduceHeap( + Cudd_ReorderingType heuristic, + int minsize) +{ + int result = Cudd_ReduceHeap(p->manager, heuristic, minsize); + checkReturnValue(result); + +} // Cudd::ReduceHeap + + +void +Cudd::ShuffleHeap( + int * permutation) +{ + int result = Cudd_ShuffleHeap(p->manager, permutation); + checkReturnValue(result); + +} // Cudd::ShuffleHeap + + +ADD +ADD::Eval( + int * inputs) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_Eval(mgr, node, inputs); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Eval + + +BDD +BDD::Eval( + int * inputs) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_Eval(mgr, node, inputs); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Eval + + +BDD +ABDD::ShortestPath( + int * weight, + int * support, + int * length) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_ShortestPath(mgr, node, weight, support, length); + checkReturnValue(result); + return BDD(p, result); + +} // ABDD::ShortestPath + + +BDD +ABDD::LargestCube( + int * length) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_LargestCube(mgr, node, length); + checkReturnValue(result); + return BDD(p, result); + +} // ABDD::LargestCube + + +int +ABDD::ShortestLength( + int * weight) const +{ + DdManager *mgr = p->manager; + int result = Cudd_ShortestLength(mgr, node, weight); + checkReturnValue(result != CUDD_OUT_OF_MEM); + return result; + +} // ABDD::ShortestLength + + +BDD +BDD::Decreasing( + int i) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_Decreasing(mgr, node, i); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Decreasing + + +BDD +BDD::Increasing( + int i) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_Increasing(mgr, node, i); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Increasing + + +bool +ABDD::EquivDC( + const ABDD& G, + const ABDD& D) const +{ + DdManager *mgr = checkSameManager(G); + checkSameManager(D); + return Cudd_EquivDC(mgr, node, G.node, D.node); + +} // ABDD::EquivDC + +bool +BDD::LeqUnless( + const BDD& G, + const BDD& D) const +{ + DdManager *mgr = checkSameManager(G); + checkSameManager(D); + int res = Cudd_bddLeqUnless(mgr, node, G.node, D.node); + return res; + +} // BDD::LeqUnless + + +bool +ADD::EqualSupNorm( + const ADD& g, + CUDD_VALUE_TYPE tolerance, + int pr) const +{ + DdManager *mgr = checkSameManager(g); + return Cudd_EqualSupNorm(mgr, node, g.node, tolerance, pr); + +} // ADD::EqualSupNorm + + +BDD +BDD::MakePrime( + const BDD& F) const +{ + DdManager *mgr = checkSameManager(F); + if (!Cudd_CheckCube(mgr, node)) { + p->errorHandler("Invalid argument."); + } + DdNode *result = Cudd_bddMakePrime(mgr, node, F.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD:MakePrime + + +BDD +BDD::MaximallyExpand( + const BDD& ub, + const BDD& f) +{ + DdManager *mgr = checkSameManager(ub); + checkSameManager(f); + DdNode *result = Cudd_bddMaximallyExpand(mgr, node, ub.node, f.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::MaximallyExpand + + +BDD +BDD::LargestPrimeUnate( + const BDD& phases) +{ + DdManager *mgr = checkSameManager(phases); + DdNode *result = Cudd_bddLargestPrimeUnate(mgr, node, phases.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::LargestPrimeUnate + + +double * +ABDD::CofMinterm() const +{ + DdManager *mgr = p->manager; + double *result = Cudd_CofMinterm(mgr, node); + checkReturnValue((DdNode *)result); + return result; + +} // ABDD::CofMinterm + + +BDD +BDD::SolveEqn( + const BDD& Y, + BDD* G, + int ** yIndex, + int n) const +{ + DdManager *mgr = checkSameManager(Y); + DdNode **g = new DdNode *[n]; + DdNode *result = Cudd_SolveEqn(mgr, node, Y.node, g, yIndex, n); + checkReturnValue(result); + for (int i = 0; i < n; i++) { + G[i] = BDD(p, g[i]); + Cudd_RecursiveDeref(mgr,g[i]); + } + delete [] g; + return BDD(p, result); + +} // BDD::SolveEqn + + +BDD +BDD::VerifySol( + BDD* G, + int * yIndex, + int n) const +{ + DdManager *mgr = p->manager; + DdNode **g = new DdNode *[n]; + for (int i = 0; i < n; i++) { + g[i] = G[i].node; + } + DdNode *result = Cudd_VerifySol(mgr, node, g, yIndex, n); + delete [] g; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::VerifySol + + +BDD +BDD::SplitSet( + vector xVars, + double m) const +{ + int n = xVars.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = xVars[i].node; + } + DdNode *result = Cudd_SplitSet(mgr, node, X, n, m); + delete [] X; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SplitSet + + +BDD +BDD::SubsetHeavyBranch( + int numVars, + int threshold) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_SubsetHeavyBranch(mgr, node, numVars, threshold); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SubsetHeavyBranch + + +BDD +BDD::SupersetHeavyBranch( + int numVars, + int threshold) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_SupersetHeavyBranch(mgr, node, numVars, threshold); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SupersetHeavyBranch + + +BDD +BDD::SubsetShortPaths( + int numVars, + int threshold, + bool hardlimit) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_SubsetShortPaths(mgr, node, numVars, threshold, hardlimit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SubsetShortPaths + + +BDD +BDD::SupersetShortPaths( + int numVars, + int threshold, + bool hardlimit) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_SupersetShortPaths(mgr, node, numVars, threshold, hardlimit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SupersetShortPaths + + +void +Cudd::SymmProfile( + int lower, + int upper) const +{ + Cudd_SymmProfile(p->manager, lower, upper); + +} // Cudd::SymmProfile + + +unsigned int +Cudd::Prime( + unsigned int pr) const +{ + return Cudd_Prime(pr); + +} // Cudd::Prime + + +void +Cudd::Reserve( + int amount) const +{ + int result = Cudd_Reserve(p->manager, amount); + checkReturnValue(result); + +} // Cudd::Reserve + + +void +ABDD::PrintMinterm() const +{ + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_PrintMinterm(mgr, node); + checkReturnValue(result); + +} // ABDD::PrintMinterm + + +void +BDD::PrintCover() const +{ + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_bddPrintCover(mgr, node, node); + checkReturnValue(result); + +} // BDD::PrintCover + + +void +BDD::PrintCover( + const BDD& u) const +{ + checkSameManager(u); + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_bddPrintCover(mgr, node, u.node); + checkReturnValue(result); + +} // BDD::PrintCover + + +int +BDD::EstimateCofactor( + int i, + int phase) const +{ + DdManager *mgr = p->manager; + int result = Cudd_EstimateCofactor(mgr, node, i, phase); + checkReturnValue(result != CUDD_OUT_OF_MEM); + return result; + +} // BDD::EstimateCofactor + + +int +BDD::EstimateCofactorSimple( + int i) const +{ + int result = Cudd_EstimateCofactorSimple(node, i); + return result; + +} // BDD::EstimateCofactorSimple + + +int +Cudd::SharingSize( + DD* nodes, + int n) const +{ + DdNode **nodeArray = new DdNode *[n]; + for (int i = 0; i < n; i++) { + nodeArray[i] = nodes[i].getNode(); + } + int result = Cudd_SharingSize(nodeArray, n); + delete [] nodeArray; + checkReturnValue(n == 0 || result > 0); + return result; + +} // Cudd::SharingSize + + +int +Cudd::SharingSize( + const vector& v) const +{ + vector::size_type n = v.size(); + DdNode **nodeArray = new DdNode *[n]; + for (vector::size_type i = 0; i != n; ++i) { + nodeArray[i] = v[i].getNode(); + } + int result = Cudd_SharingSize(nodeArray, n); + delete [] nodeArray; + checkReturnValue(n == 0 || result > 0); + return result; + +} // Cudd::SharingSize + + +double +ABDD::CountMinterm( + int nvars) const +{ + DdManager *mgr = p->manager; + double result = Cudd_CountMinterm(mgr, node, nvars); + checkReturnValue(result != (double) CUDD_OUT_OF_MEM); + return result; + +} // ABDD::CountMinterm + + +double +ABDD::CountPath() const +{ + double result = Cudd_CountPath(node); + checkReturnValue(result != (double) CUDD_OUT_OF_MEM); + return result; + +} // ABDD::CountPath + + +BDD +ABDD::Support() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_Support(mgr, node); + checkReturnValue(result); + return BDD(p, result); + +} // ABDD::Support + + +int +ABDD::SupportSize() const +{ + DdManager *mgr = p->manager; + int result = Cudd_SupportSize(mgr, node); + checkReturnValue(result != CUDD_OUT_OF_MEM); + return result; + +} // ABDD::SupportSize + + +BDD +Cudd::VectorSupport(const vector& roots) const +{ + int n = roots.size(); + DdManager *mgr = p->manager; + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i++) { + F[i] = roots[i].getNode(); + } + DdNode *result = Cudd_VectorSupport(mgr, F, n); + delete [] F; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::VectorSupport + + +vector +ABDD::SupportIndices() const +{ + unsigned int *support; + DdManager *mgr = p->manager; + int size = Cudd_SupportIndices(mgr, node, (int **)&support); + checkReturnValue(size >= 0); + // size could be 0, in which case support is 0 too! + vector indices(support, support+size); + if (support) free(support); + return indices; + +} // ABDD::SupportIndices + + +vector +Cudd::SupportIndices(const vector& roots) const +{ + unsigned int *support; + int n = roots.size(); + DdManager *mgr = p->manager; + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i++) { + F[i] = roots[i].getNode(); + } + int size = Cudd_VectorSupportIndices(mgr, F, n, (int **)&support); + delete [] F; + checkReturnValue(size >= 0); + // size could be 0, in which case support is 0 too! + vector indices(support, support+size); + if (support) free(support); + return indices; + +} // Cudd::SupportIndices + + +int +Cudd::nodeCount(const vector& roots) const +{ + int n = roots.size(); + DdNode **nodeArray = new DdNode *[n]; + for (int i = 0; i < n; i++) { + nodeArray[i] = roots[i].getNode(); + } + int result = Cudd_SharingSize(nodeArray, n); + delete [] nodeArray; + checkReturnValue(result > 0); + return result; + +} // vector::nodeCount + + +BDD +Cudd::VectorSupport(const vector& roots) const +{ + int n = roots.size(); + DdManager *mgr = p->manager; + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i++) { + F[i] = roots[i].getNode(); + } + DdNode *result = Cudd_VectorSupport(mgr, F, n); + delete [] F; + checkReturnValue(result); + return BDD(p, result); + +} // vector::VectorSupport + + +int +Cudd::VectorSupportSize(const vector& roots) const +{ + int n = roots.size(); + DdManager *mgr = p->manager; + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i++) { + F[i] = roots[i].getNode(); + } + int result = Cudd_VectorSupportSize(mgr, F, n); + delete [] F; + checkReturnValue(result != CUDD_OUT_OF_MEM); + return result; + +} // vector::VectorSupportSize + + +int +Cudd::VectorSupportSize(const vector& roots) const +{ + int n = roots.size(); + DdManager *mgr = p->manager; + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i++) { + F[i] = roots[i].getNode(); + } + int result = Cudd_VectorSupportSize(mgr, F, n); + delete [] F; + checkReturnValue(result != CUDD_OUT_OF_MEM); + return result; + +} // vector::VectorSupportSize + + +void +ABDD::ClassifySupport( + const ABDD& g, + BDD* common, + BDD* onlyF, + BDD* onlyG) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *C, *F, *G; + int result = Cudd_ClassifySupport(mgr, node, g.node, &C, &F, &G); + checkReturnValue(result); + *common = BDD(p, C); + *onlyF = BDD(p, F); + *onlyG = BDD(p, G); + +} // ABDD::ClassifySupport + + +int +ABDD::CountLeaves() const +{ + return Cudd_CountLeaves(node); + +} // ABDD::CountLeaves + + +void +BDD::PickOneCube( + char * string) const +{ + DdManager *mgr = p->manager; + int result = Cudd_bddPickOneCube(mgr, node, string); + checkReturnValue(result); + +} // BDD::PickOneCube + + +BDD +BDD::PickOneMinterm( + vector vars) const +{ + int n = vars.size(); + DdManager *mgr = p->manager; + DdNode **V = new DdNode *[n]; + for (int i = 0; i < n; i++) { + V[i] = vars[i].node; + } + DdNode *result = Cudd_bddPickOneMinterm(mgr, node, V, n); + delete [] V; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::PickOneMinterm + + +DdGen * +ABDD::FirstCube( + int ** cube, + CUDD_VALUE_TYPE * value) const +{ + DdManager *mgr = p->manager; + DdGen *result = Cudd_FirstCube(mgr, node, cube, value); + checkReturnValue((DdNode *)result); + return result; + +} // ABDD::FirstCube + + +int +NextCube( + DdGen * gen, + int ** cube, + CUDD_VALUE_TYPE * value) +{ + return Cudd_NextCube(gen, cube, value); + +} // NextCube + + +BDD +Cudd::bddComputeCube( + BDD * vars, + int * phase, + int n) const +{ + DdManager *mgr = p->manager; + DdNode **V = new DdNode *[n]; + for (int i = 0; i < n; i++) { + V[i] = vars[i].getNode(); + } + DdNode *result = Cudd_bddComputeCube(mgr, V, phase, n); + delete [] V; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::bddComputeCube + + +ADD +Cudd::addComputeCube( + ADD * vars, + int * phase, + int n) +{ + DdManager *mgr = p->manager; + DdNode **V = new DdNode *[n]; + for (int i = 0; i < n; i++) { + V[i] = vars[i].getNode(); + } + DdNode *result = Cudd_addComputeCube(mgr, V, phase, n); + delete [] V; + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addComputeCube + + +DdGen * +BDD::FirstNode( + BDD* fnode) const +{ + DdManager *mgr = p->manager; + DdNode *Fn; + DdGen *result = Cudd_FirstNode(mgr, node, &Fn); + checkReturnValue((DdNode *)result); + *fnode = BDD(p, Fn); + return result; + +} // DD::FirstNode + + +int +Cudd::NextNode( + DdGen * gen, + BDD * nnode) +{ + DdNode *nn; + int result = Cudd_NextNode(gen, &nn); + *nnode = BDD(p, nn); + return result; + +} // Cudd::NextNode + + +int +GenFree( + DdGen * gen) +{ + return Cudd_GenFree(gen); + +} // GenFree + + +int +IsGenEmpty( + DdGen * gen) +{ + return Cudd_IsGenEmpty(gen); + +} // IsGenEmpty + + +BDD +Cudd::IndicesToCube( + int * array, + int n) +{ + DdNode *result = Cudd_IndicesToCube(p->manager, array, n); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::IndicesToCube + + +void +Cudd::PrintVersion( + FILE * fp) const +{ + cout.flush(); + Cudd_PrintVersion(fp); + +} // Cudd::PrintVersion + + +double +Cudd::AverageDistance() const +{ + return Cudd_AverageDistance(p->manager); + +} // Cudd::AverageDistance + + +long +Cudd::Random() const +{ + return Cudd_Random(); + +} // Cudd::Random + + +void +Cudd::Srandom( + long seed) const +{ + Cudd_Srandom(seed); + +} // Cudd::Srandom + + +double +ABDD::Density( + int nvars) const +{ + DdManager *mgr = p->manager; + double result = Cudd_Density(mgr, node, nvars); + checkReturnValue(result != (double) CUDD_OUT_OF_MEM); + return result; + +} // ABDD::Density + + +int +ZDD::Count() const +{ + DdManager *mgr = p->manager; + int result = Cudd_zddCount(mgr, node); + checkReturnValue(result != CUDD_OUT_OF_MEM); + return result; + +} // ZDD::Count + + +double +ZDD::CountDouble() const +{ + DdManager *mgr = p->manager; + double result = Cudd_zddCountDouble(mgr, node); + checkReturnValue(result != (double) CUDD_OUT_OF_MEM); + return result; + +} // ZDD::CountDouble + + +ZDD +ZDD::Product( + const ZDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_zddProduct(mgr, node, g.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Product + + +ZDD +ZDD::UnateProduct( + const ZDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_zddUnateProduct(mgr, node, g.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::UnateProduct + + +ZDD +ZDD::WeakDiv( + const ZDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_zddWeakDiv(mgr, node, g.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::WeakDiv + + +ZDD +ZDD::Divide( + const ZDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_zddDivide(mgr, node, g.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Divide + + +ZDD +ZDD::WeakDivF( + const ZDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_zddWeakDivF(mgr, node, g.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::WeakDivF + + +ZDD +ZDD::DivideF( + const ZDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_zddDivideF(mgr, node, g.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::DivideF + + +MtrNode * +Cudd::MakeZddTreeNode( + unsigned int low, + unsigned int size, + unsigned int type) +{ + return Cudd_MakeZddTreeNode(p->manager, low, size, type); + +} // Cudd::MakeZddTreeNode + + +BDD +BDD::zddIsop( + const BDD& U, + ZDD* zdd_I) const +{ + DdManager *mgr = checkSameManager(U); + DdNode *Z; + DdNode *result = Cudd_zddIsop(mgr, node, U.node, &Z); + checkReturnValue(result); + *zdd_I = ZDD(p, Z); + return BDD(p, result); + +} // BDD::Isop + + +BDD +BDD::Isop( + const BDD& U) const +{ + DdManager *mgr = checkSameManager(U); + DdNode *result = Cudd_bddIsop(mgr, node, U.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Isop + + +double +ZDD::CountMinterm( + int path) const +{ + DdManager *mgr = p->manager; + double result = Cudd_zddCountMinterm(mgr, node, path); + checkReturnValue(result != (double) CUDD_OUT_OF_MEM); + return result; + +} // ZDD::CountMinterm + + +void +Cudd::zddPrintSubtable() const +{ + cout.flush(); + Cudd_zddPrintSubtable(p->manager); + +} // Cudd::zddPrintSubtable + + +ZDD +BDD::PortToZdd() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_zddPortFromBdd(mgr, node); + checkReturnValue(result); + return ZDD(p, result); + +} // BDD::PortToZdd + + +BDD +ZDD::PortToBdd() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_zddPortToBdd(mgr, node); + checkReturnValue(result); + return BDD(p, result); + +} // ZDD::PortToBdd + + +void +Cudd::zddReduceHeap( + Cudd_ReorderingType heuristic, + int minsize) +{ + int result = Cudd_zddReduceHeap(p->manager, heuristic, minsize); + checkReturnValue(result); + +} // Cudd::zddReduceHeap + + +void +Cudd::zddShuffleHeap( + int * permutation) +{ + int result = Cudd_zddShuffleHeap(p->manager, permutation); + checkReturnValue(result); + +} // Cudd::zddShuffleHeap + + +ZDD +ZDD::Ite( + const ZDD& g, + const ZDD& h) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(h); + DdNode *result = Cudd_zddIte(mgr, node, g.node, h.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Ite + + +ZDD +ZDD::Union( + const ZDD& Q) const +{ + DdManager *mgr = checkSameManager(Q); + DdNode *result = Cudd_zddUnion(mgr, node, Q.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Union + + +ZDD +ZDD::Intersect( + const ZDD& Q) const +{ + DdManager *mgr = checkSameManager(Q); + DdNode *result = Cudd_zddIntersect(mgr, node, Q.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Intersect + + +ZDD +ZDD::Diff( + const ZDD& Q) const +{ + DdManager *mgr = checkSameManager(Q); + DdNode *result = Cudd_zddDiff(mgr, node, Q.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Diff + + +ZDD +ZDD::DiffConst( + const ZDD& Q) const +{ + DdManager *mgr = checkSameManager(Q); + DdNode *result = Cudd_zddDiffConst(mgr, node, Q.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::DiffConst + + +ZDD +ZDD::Subset1( + int var) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_zddSubset1(mgr, node, var); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Subset1 + + +ZDD +ZDD::Subset0( + int var) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_zddSubset0(mgr, node, var); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Subset0 + + +ZDD +ZDD::Change( + int var) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_zddChange(mgr, node, var); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Change + + +void +Cudd::zddSymmProfile( + int lower, + int upper) const +{ + Cudd_zddSymmProfile(p->manager, lower, upper); + +} // Cudd::zddSymmProfile + + +void +ZDD::PrintMinterm() const +{ + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_zddPrintMinterm(mgr, node); + checkReturnValue(result); + +} // ZDD::PrintMinterm + + +void +ZDD::PrintCover() const +{ + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_zddPrintCover(mgr, node); + checkReturnValue(result); + +} // ZDD::PrintCover + + +BDD +ZDD::Support() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_zddSupport(mgr, node); + checkReturnValue(result); + return BDD(p, result); + +} // ZDD::Support + + +void +Cudd::DumpDot( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_zddDumpDot(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpDot diff --git a/resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh b/resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh new file mode 100644 index 000000000..83a0a924a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh @@ -0,0 +1,762 @@ +/**CHeaderFile*************************************************************** + + FileName [cuddObj.hh] + + PackageName [cudd] + + Synopsis [Class definitions for C++ object-oriented encapsulation of + CUDD.] + + Description [Class definitions for C++ object-oriented encapsulation of + CUDD.] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: cuddObj.hh,v 1.13 2012/02/05 01:06:40 fabio Exp fabio $] + +******************************************************************************/ + +#ifndef _CPPCUDD +#define _CPPCUDD + +#if defined (__GNUC__) +#if (__GNUC__ >2 || __GNUC_MINOR__ >=7) && !defined(UNUSED) +#define UNUSED __attribute__ ((unused)) +#else +#define UNUSED +#endif +#else +#define UNUSED +#endif + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include +#include +#include +#include "cudd.h" + +/*---------------------------------------------------------------------------*/ +/* Type definitions */ +/*---------------------------------------------------------------------------*/ +class BDD; +class ADD; +class ZDD; +class Cudd; + +typedef void (*PFC)(std::string); // handler function type + +/*---------------------------------------------------------------------------*/ +/* Class definitions */ +/*---------------------------------------------------------------------------*/ + +/**Class*********************************************************************** + + Synopsis [Class for reference counting of CUDD managers.] + + Description [] + + SeeAlso [Cudd DD ABDD ADD BDD ZDD] + +******************************************************************************/ +class Capsule { + friend class DD; + friend class ABDD; + friend class BDD; + friend class ADD; + friend class ZDD; + friend class Cudd; +private: + DdManager *manager; + PFC errorHandler; + PFC timeoutHandler; + bool verbose; + int ref; +}; + + +/**Class*********************************************************************** + + Synopsis [Base class for all decision diagrams in CUDD.] + + Description [] + + SeeAlso [Cudd ABDD ADD BDD ZDD] + +******************************************************************************/ +class DD { + friend class ABDD; + friend class BDD; + friend class ADD; + friend class ZDD; +private: + Capsule *p; + DdNode *node; + inline DdManager * checkSameManager(const DD &other) const; + inline void checkReturnValue(const DdNode *result) const; + inline void checkReturnValue(const int result, const int expected = 1) + const; +public: + DD(); + DD(Capsule *cap, DdNode *ddNode); + DD(Cudd const & manager, DdNode *ddNode); + DD(const DD &from); + virtual ~DD(); + operator bool() const { return node; } + DdManager *manager() const; + DdNode * getNode() const; + DdNode * getRegularNode() const; + int nodeCount() const; + unsigned int NodeReadIndex() const; + +}; // DD + + +/**Class*********************************************************************** + + Synopsis [Class for ADDs and BDDs.] + + Description [] + + SeeAlso [Cudd ADD BDD] + +******************************************************************************/ +class ABDD : public DD { + friend class BDD; + friend class ADD; + friend class Cudd; +public: + ABDD(); + ABDD(Capsule *cap, DdNode *bddNode); + ABDD(Cudd const & manager, DdNode *ddNode); + ABDD(const ABDD &from); + virtual ~ABDD(); + bool operator==(const ABDD &other) const; + bool operator!=(const ABDD &other) const; + void print(int nvars, int verbosity = 1) const; + DdApaNumber ApaCountMinterm(int nvars, int * digits) const; + void ApaPrintMinterm(int nvars, FILE * fp = stdout) const; + void EpdPrintMinterm(int nvars, FILE * fp = stdout) const; + bool IsOne() const; + bool IsCube() const; + BDD FindEssential() const; + void PrintTwoLiteralClauses(char ** names, FILE * fp = stdout) const; + BDD ShortestPath(int * weight, int * support, int * length) const; + BDD LargestCube(int * length = 0) const; + int ShortestLength(int * weight) const; + bool EquivDC(const ABDD& G, const ABDD& D) const; + double * CofMinterm() const; + void PrintMinterm() const; + double CountMinterm(int nvars) const; + double CountPath() const; + BDD Support() const; + int SupportSize() const; + std::vector SupportIndices() const; + void ClassifySupport(const ABDD& g, BDD* common, BDD* onlyF, BDD* onlyG) + const; + int CountLeaves() const; + DdGen * FirstCube(int ** cube, CUDD_VALUE_TYPE * value) const; + double Density(int nvars) const; + +}; // ABDD + + +/**Class*********************************************************************** + + Synopsis [Class for BDDs.] + + Description [] + + SeeAlso [Cudd] + +******************************************************************************/ +class BDD : public ABDD { + friend class Cudd; +public: + BDD(); + BDD(Capsule *cap, DdNode *bddNode); + BDD(Cudd const & manager, DdNode *ddNode); + BDD(const BDD &from); + BDD operator=(const BDD& right); + bool operator<=(const BDD& other) const; + bool operator>=(const BDD& other) const; + bool operator<(const BDD& other) const; + bool operator>(const BDD& other) const; + BDD operator!() const; + BDD operator~() const; + BDD operator*(const BDD& other) const; + BDD operator*=(const BDD& other); + BDD operator&(const BDD& other) const; + BDD operator&=(const BDD& other); + BDD operator+(const BDD& other) const; + BDD operator+=(const BDD& other); + BDD operator|(const BDD& other) const; + BDD operator|=(const BDD& other); + BDD operator^(const BDD& other) const; + BDD operator^=(const BDD& other); + BDD operator-(const BDD& other) const; + BDD operator-=(const BDD& other); + bool IsZero() const; + BDD AndAbstract(const BDD& g, const BDD& cube, unsigned int limit = 0) + const; + BDD UnderApprox( + int numVars, + int threshold = 0, + bool safe = false, + double quality = 1.0) const; + BDD OverApprox( + int numVars, + int threshold = 0, + bool safe = false, + double quality = 1.0) const; + BDD RemapUnderApprox(int numVars, int threshold = 0, double quality = 1.0) + const; + BDD RemapOverApprox(int numVars, int threshold = 0, double quality = 1.0) + const; + BDD BiasedUnderApprox(const BDD& bias, int numVars, int threshold = 0, + double quality1 = 1.0, double quality0 = 1.0) const; + BDD BiasedOverApprox(const BDD& bias, int numVars, int threshold = 0, + double quality1 = 1.0, double quality0 = 1.0) const; + BDD ExistAbstract(const BDD& cube, unsigned int limit = 0) const; + BDD XorExistAbstract(const BDD& g, const BDD& cube) const; + BDD UnivAbstract(const BDD& cube) const; + BDD BooleanDiff(int x) const; + bool VarIsDependent(const BDD& var) const; + double Correlation(const BDD& g) const; + double CorrelationWeights(const BDD& g, double * prob) const; + BDD Ite(const BDD& g, const BDD& h, unsigned int limit = 0) const; + BDD IteConstant(const BDD& g, const BDD& h) const; + BDD Intersect(const BDD& g) const; + BDD And(const BDD& g, unsigned int limit = 0) const; + BDD Or(const BDD& g, unsigned int limit = 0) const; + BDD Nand(const BDD& g) const; + BDD Nor(const BDD& g) const; + BDD Xor(const BDD& g) const; + BDD Xnor(const BDD& g, unsigned int limit = 0) const; + bool Leq(const BDD& g) const; + ADD Add() const; + BDD Transfer(Cudd& destination) const; + BDD ClippingAnd(const BDD& g, int maxDepth, int direction) const; + BDD ClippingAndAbstract(const BDD& g, const BDD& cube, int maxDepth, + int direction) const; + BDD Cofactor(const BDD& g) const; + BDD Compose(const BDD& g, int v) const; + BDD Permute(int * permut) const; + BDD SwapVariables(std::vector x, std::vector y) const; + BDD AdjPermuteX(std::vector x) const; + BDD VectorCompose(std::vector vector) const; + void ApproxConjDecomp(BDD* g, BDD* h) const; + void ApproxDisjDecomp(BDD* g, BDD* h) const; + void IterConjDecomp(BDD* g, BDD* h) const; + void IterDisjDecomp(BDD* g, BDD* h) const; + void GenConjDecomp(BDD* g, BDD* h) const; + void GenDisjDecomp(BDD* g, BDD* h) const; + void VarConjDecomp(BDD* g, BDD* h) const; + void VarDisjDecomp(BDD* g, BDD* h) const; + bool IsVarEssential(int id, int phase) const; + BDD Constrain(const BDD& c) const; + BDD Restrict(const BDD& c) const; + BDD NPAnd(const BDD& g) const; + std::vector ConstrainDecomp() const; + std::vector CharToVect() const; + BDD LICompaction(const BDD& c) const; + BDD Squeeze(const BDD& u) const; + BDD Minimize(const BDD& c) const; + BDD SubsetCompress(int nvars, int threshold) const; + BDD SupersetCompress(int nvars, int threshold) const; + BDD LiteralSetIntersection(const BDD& g) const; + BDD PrioritySelect(std::vector x, std::vector y, + std::vector z, const BDD& Pi, DD_PRFP Pifunc) const; + BDD CProjection(const BDD& Y) const; + int MinHammingDist(int *minterm, int upperBound) const; + BDD Eval(int * inputs) const; + BDD Decreasing(int i) const; + BDD Increasing(int i) const; + bool LeqUnless(const BDD& G, const BDD& D) const; + BDD MakePrime(const BDD& F) const; + BDD MaximallyExpand(const BDD& ub, const BDD& f); + BDD LargestPrimeUnate(const BDD& phases); + BDD SolveEqn(const BDD& Y, BDD* G, int ** yIndex, int n) const; + BDD VerifySol(BDD* G, int * yIndex, int n) const; + BDD SplitSet(std::vector xVars, double m) const; + BDD SubsetHeavyBranch(int numVars, int threshold) const; + BDD SupersetHeavyBranch(int numVars, int threshold) const; + BDD SubsetShortPaths(int numVars, int threshold, bool hardlimit = false) const; + BDD SupersetShortPaths(int numVars, int threshold, bool hardlimit = false) const; + void PrintCover() const; + void PrintCover(const BDD& u) const; + int EstimateCofactor(int i, int phase) const; + int EstimateCofactorSimple(int i) const; + void PickOneCube(char * string) const; + BDD PickOneMinterm(std::vector vars) const; + DdGen * FirstNode(BDD* fnode) const; + BDD zddIsop(const BDD& U, ZDD* zdd_I) const; + BDD Isop(const BDD& U) const; + ZDD PortToZdd() const; + +}; // BDD + + +/**Class*********************************************************************** + + Synopsis [Class for ADDs.] + + Description [] + + SeeAlso [Cudd] + +******************************************************************************/ +class ADD : public ABDD { + friend class Cudd; +public: + ADD(); + ADD(Capsule *cap, DdNode *bddNode); + ADD(Cudd const & manager, DdNode *ddNode); + ADD(const ADD &from); + ADD operator=(const ADD& right); + // Relational operators + bool operator<=(const ADD& other) const; + bool operator>=(const ADD& other) const; + bool operator<(const ADD& other) const; + bool operator>(const ADD& other) const; + // Arithmetic operators + ADD operator-() const; + ADD operator*(const ADD& other) const; + ADD operator*=(const ADD& other); + ADD operator+(const ADD& other) const; + ADD operator+=(const ADD& other); + ADD operator-(const ADD& other) const; + ADD operator-=(const ADD& other); + // Logical operators + ADD operator~() const; + ADD operator&(const ADD& other) const; + ADD operator&=(const ADD& other); + ADD operator|(const ADD& other) const; + ADD operator|=(const ADD& other); + bool IsZero() const; + ADD ExistAbstract(const ADD& cube) const; + ADD UnivAbstract(const ADD& cube) const; + ADD OrAbstract(const ADD& cube) const; + ADD Plus(const ADD& g) const; + ADD Times(const ADD& g) const; + ADD Threshold(const ADD& g) const; + ADD SetNZ(const ADD& g) const; + ADD Divide(const ADD& g) const; + ADD Minus(const ADD& g) const; + ADD Minimum(const ADD& g) const; + ADD Maximum(const ADD& g) const; + ADD OneZeroMaximum(const ADD& g) const; + ADD Diff(const ADD& g) const; + ADD Agreement(const ADD& g) const; + ADD Or(const ADD& g) const; + ADD Nand(const ADD& g) const; + ADD Nor(const ADD& g) const; + ADD Xor(const ADD& g) const; + ADD Xnor(const ADD& g) const; + ADD Log() const; + ADD FindMax() const; + ADD FindMin() const; + ADD IthBit(int bit) const; + ADD ScalarInverse(const ADD& epsilon) const; + ADD Ite(const ADD& g, const ADD& h) const; + ADD IteConstant(const ADD& g, const ADD& h) const; + ADD EvalConst(const ADD& g) const; + bool Leq(const ADD& g) const; + ADD Cmpl() const; + ADD Negate() const; + ADD RoundOff(int N) const; + BDD BddThreshold(CUDD_VALUE_TYPE value) const; + BDD BddStrictThreshold(CUDD_VALUE_TYPE value) const; + BDD BddInterval(CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper) const; + BDD BddIthBit(int bit) const; + BDD BddPattern() const; + ADD Cofactor(const ADD& g) const; + ADD Compose(const ADD& g, int v) const; + ADD Permute(int * permut) const; + ADD SwapVariables(std::vector x, std::vector y) const; + ADD VectorCompose(std::vector vector) const; + ADD NonSimCompose(std::vector vector) const; + ADD Constrain(const ADD& c) const; + ADD Restrict(const ADD& c) const; + ADD MatrixMultiply(const ADD& B, std::vector z) const; + ADD TimesPlus(const ADD& B, std::vector z) const; + ADD Triangle(const ADD& g, std::vector z) const; + ADD Eval(int * inputs) const; + bool EqualSupNorm(const ADD& g, CUDD_VALUE_TYPE tolerance, int pr) const; + +}; // ADD + + +/**Class*********************************************************************** + + Synopsis [Class for ZDDs.] + + Description [] + + SeeAlso [Cudd] + +******************************************************************************/ +class ZDD : public DD { + friend class Cudd; +public: + ZDD(Capsule *cap, DdNode *bddNode); + ZDD(); + ZDD(const ZDD &from); + ~ZDD(); + ZDD operator=(const ZDD& right); + bool operator==(const ZDD& other) const; + bool operator!=(const ZDD& other) const; + bool operator<=(const ZDD& other) const; + bool operator>=(const ZDD& other) const; + bool operator<(const ZDD& other) const; + bool operator>(const ZDD& other) const; + void print(int nvars, int verbosity = 1) const; + ZDD operator*(const ZDD& other) const; + ZDD operator*=(const ZDD& other); + ZDD operator&(const ZDD& other) const; + ZDD operator&=(const ZDD& other); + ZDD operator+(const ZDD& other) const; + ZDD operator+=(const ZDD& other); + ZDD operator|(const ZDD& other) const; + ZDD operator|=(const ZDD& other); + ZDD operator-(const ZDD& other) const; + ZDD operator-=(const ZDD& other); + int Count() const; + double CountDouble() const; + ZDD Product(const ZDD& g) const; + ZDD UnateProduct(const ZDD& g) const; + ZDD WeakDiv(const ZDD& g) const; + ZDD Divide(const ZDD& g) const; + ZDD WeakDivF(const ZDD& g) const; + ZDD DivideF(const ZDD& g) const; + double CountMinterm(int path) const; + BDD PortToBdd() const; + ZDD Ite(const ZDD& g, const ZDD& h) const; + ZDD Union(const ZDD& Q) const; + ZDD Intersect(const ZDD& Q) const; + ZDD Diff(const ZDD& Q) const; + ZDD DiffConst(const ZDD& Q) const; + ZDD Subset1(int var) const; + ZDD Subset0(int var) const; + ZDD Change(int var) const; + void PrintMinterm() const; + void PrintCover() const; + BDD Support() const; + +}; // ZDD + + +/**Class*********************************************************************** + + Synopsis [Class for CUDD managers.] + + Description [] + + SeeAlso [DD] + +******************************************************************************/ +class Cudd { + friend class DD; + friend class ABDD; + friend class BDD; + friend class ADD; + friend class ZDD; +private: + Capsule *p; +public: + Cudd( + unsigned int numVars = 0, + unsigned int numVarsZ = 0, + unsigned int numSlots = CUDD_UNIQUE_SLOTS, + unsigned int cacheSize = CUDD_CACHE_SLOTS, + unsigned long maxMemory = 0); + Cudd(const Cudd& x); + ~Cudd(); + PFC setHandler(PFC newHandler) const; + PFC getHandler() const; + PFC setTimeoutHandler(PFC newHandler) const; + PFC getTimeoutHandler() const; + DdManager *getManager() const {return p->manager;} + inline void makeVerbose() const {p->verbose = 1;} + inline void makeTerse() {p->verbose = 0;} + inline bool isVerbose() const {return p->verbose;} + inline void checkReturnValue(const DdNode *result) const; + inline void checkReturnValue(const int result) const; + Cudd& operator=(const Cudd& right); + void info() const; + BDD bddVar() const; + BDD bddVar(int index) const; + BDD bddOne() const; + BDD bddZero() const; + ADD addVar() const; + ADD addVar(int index) const; + ADD addOne() const; + ADD addZero() const; + ADD constant(CUDD_VALUE_TYPE c) const; + ADD plusInfinity() const; + ADD minusInfinity() const; + ZDD zddVar(int index) const; + ZDD zddOne(int i) const; + ZDD zddZero() const; + ADD addNewVarAtLevel(int level) const; + BDD bddNewVarAtLevel(int level) const; + void zddVarsFromBddVars(int multiplicity) const; + unsigned long ReadStartTime() const; + unsigned long ReadElapsedTime() const; + void SetStartTime(unsigned long st) const; + void ResetStartTime() const; + unsigned long ReadTimeLimit() const; + void SetTimeLimit(unsigned long tl) const; + void UpdateTimeLimit() const; + void IncreaseTimeLimit(unsigned long increase) const; + void UnsetTimeLimit() const; + bool TimeLimited() const; + void AutodynEnable(Cudd_ReorderingType method) const; + void AutodynDisable() const; + bool ReorderingStatus(Cudd_ReorderingType * method) const; + void AutodynEnableZdd(Cudd_ReorderingType method) const; + void AutodynDisableZdd() const; + bool ReorderingStatusZdd(Cudd_ReorderingType * method) const; + bool zddRealignmentEnabled() const; + void zddRealignEnable() const; + void zddRealignDisable() const; + bool bddRealignmentEnabled() const; + void bddRealignEnable() const; + void bddRealignDisable() const; + ADD background() const; + void SetBackground(ADD bg) const; + unsigned int ReadCacheSlots() const; + double ReadCacheUsedSlots() const; + double ReadCacheLookUps() const; + double ReadCacheHits() const; + unsigned int ReadMinHit() const; + void SetMinHit(unsigned int hr) const; + unsigned int ReadLooseUpTo() const; + void SetLooseUpTo(unsigned int lut) const; + unsigned int ReadMaxCache() const; + unsigned int ReadMaxCacheHard() const; + void SetMaxCacheHard(unsigned int mc) const; + int ReadSize() const; + int ReadZddSize() const; + unsigned int ReadSlots() const; + unsigned int ReadKeys() const; + unsigned int ReadDead() const; + unsigned int ReadMinDead() const; + unsigned int ReadReorderings() const; + unsigned int ReadMaxReorderings() const; + void SetMaxReorderings(unsigned int mr) const; + long ReadReorderingTime() const; + int ReadGarbageCollections() const; + long ReadGarbageCollectionTime() const; + int ReadSiftMaxVar() const; + void SetSiftMaxVar(int smv) const; + int ReadSiftMaxSwap() const; + void SetSiftMaxSwap(int sms) const; + double ReadMaxGrowth() const; + void SetMaxGrowth(double mg) const; + MtrNode * ReadTree() const; + void SetTree(MtrNode * tree) const; + void FreeTree() const; + MtrNode * ReadZddTree() const; + void SetZddTree(MtrNode * tree) const; + void FreeZddTree() const; + int ReadPerm(int i) const; + int ReadPermZdd(int i) const; + int ReadInvPerm(int i) const; + int ReadInvPermZdd(int i) const; + BDD ReadVars(int i) const; + CUDD_VALUE_TYPE ReadEpsilon() const; + void SetEpsilon(CUDD_VALUE_TYPE ep) const; + Cudd_AggregationType ReadGroupcheck() const; + void SetGroupcheck(Cudd_AggregationType gc) const; + bool GarbageCollectionEnabled() const; + void EnableGarbageCollection() const; + void DisableGarbageCollection() const; + bool DeadAreCounted() const; + void TurnOnCountDead() const; + void TurnOffCountDead() const; + int ReadRecomb() const; + void SetRecomb(int recomb) const; + int ReadSymmviolation() const; + void SetSymmviolation(int symmviolation) const; + int ReadArcviolation() const; + void SetArcviolation(int arcviolation) const; + int ReadPopulationSize() const; + void SetPopulationSize(int populationSize) const; + int ReadNumberXovers() const; + void SetNumberXovers(int numberXovers) const; + unsigned int ReadOrderRandomization() const; + void SetOrderRandomization(unsigned int factor) const; + unsigned long ReadMemoryInUse() const; + long ReadPeakNodeCount() const; + long ReadNodeCount() const; + long zddReadNodeCount() const; + void AddHook(DD_HFP f, Cudd_HookType where) const; + void RemoveHook(DD_HFP f, Cudd_HookType where) const; + bool IsInHook(DD_HFP f, Cudd_HookType where) const; + void EnableReorderingReporting() const; + void DisableReorderingReporting() const; + bool ReorderingReporting() const; + int ReadErrorCode() const; + void ClearErrorCode() const; + FILE *ReadStdout() const; + void SetStdout(FILE *) const; + FILE *ReadStderr() const; + void SetStderr(FILE *) const; + unsigned int ReadNextReordering() const; + void SetNextReordering(unsigned int) const; + double ReadSwapSteps() const; + unsigned int ReadMaxLive() const; + void SetMaxLive(unsigned int) const; + unsigned long ReadMaxMemory() const; + void SetMaxMemory(unsigned long) const; + int bddBindVar(int) const; + int bddUnbindVar(int) const; + bool bddVarIsBound(int) const; + ADD Walsh(std::vector x, std::vector y); + ADD addResidue(int n, int m, int options, int top); + int ApaNumberOfDigits(int binaryDigits) const; + DdApaNumber NewApaNumber(int digits) const; + void ApaCopy(int digits, DdApaNumber source, DdApaNumber dest) const; + DdApaDigit ApaAdd(int digits, DdApaNumber a, DdApaNumber b, DdApaNumber + sum) const; + DdApaDigit ApaSubtract(int digits, DdApaNumber a, DdApaNumber b, + DdApaNumber diff) const; + DdApaDigit ApaShortDivision(int digits, DdApaNumber dividend, DdApaDigit + divisor, DdApaNumber quotient) const; + void ApaShiftRight(int digits, DdApaDigit in, DdApaNumber a, DdApaNumber + b) const; + void ApaSetToLiteral(int digits, DdApaNumber number, DdApaDigit literal) + const; + void ApaPowerOfTwo(int digits, DdApaNumber number, int power) const; + void ApaPrintHex(FILE * fp, int digits, DdApaNumber number) const; + void ApaPrintDecimal(FILE * fp, int digits, DdApaNumber number) const; + void DebugCheck(); + void CheckKeys(); + MtrNode * MakeTreeNode(unsigned int low, unsigned int size, unsigned int type) const; + // void Harwell(FILE * fp, ADD* E, ADD** x, ADD** y, ADD** xn, ADD** yn_, int * nx, int * ny, int * m, int * n, int bx, int sx, int by, int sy, int pr); + void PrintLinear(); + int ReadLinear(int x, int y); + BDD Xgty(std::vector z, std::vector x, std::vector y); + BDD Xeqy(std::vector x, std::vector y); + ADD Xeqy(std::vector x, std::vector y); + BDD Dxygtdxz(std::vector x, std::vector y, std::vector z); + BDD Dxygtdyz(std::vector x, std::vector y, std::vector z); + BDD Inequality(int c, std::vector x, std::vector y); + BDD Disequality(int c, std::vector x, std::vector y); + BDD Interval(std::vector x, unsigned int lowerB, unsigned int upperB); + ADD Hamming(std::vector xVars, std::vector yVars); + // void Read(FILE * fp, ADD* E, ADD** x, ADD** y, ADD** xn, ADD** yn_, int * nx, int * ny, int * m, int * n, int bx, int sx, int by, int sy); + // void Read(FILE * fp, BDD* E, BDD** x, BDD** y, int * nx, int * ny, int * m, int * n, int bx, int sx, int by, int sy); + void ReduceHeap(Cudd_ReorderingType heuristic, int minsize); + void ShuffleHeap(int * permutation); + void SymmProfile(int lower, int upper) const; + unsigned int Prime(unsigned int pr) const; + void Reserve(int amount) const; + int SharingSize(DD* nodes, int n) const; + int SharingSize(const std::vector& v) const; + BDD bddComputeCube(BDD * vars, int * phase, int n) const; + ADD addComputeCube(ADD * vars, int * phase, int n); + int NextNode(DdGen * gen, BDD * nnode); + BDD IndicesToCube(int * array, int n); + void PrintVersion(FILE * fp) const; + double AverageDistance() const; + long Random() const; + void Srandom(long seed) const; + MtrNode * MakeZddTreeNode(unsigned int low, unsigned int size, unsigned int type); + void zddPrintSubtable() const; + void zddReduceHeap(Cudd_ReorderingType heuristic, int minsize); + void zddShuffleHeap(int * permutation); + void zddSymmProfile(int lower, int upper) const; + void DumpDot( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + void DumpDaVinci( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + void DumpBlif( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + char * mname = 0, + FILE * fp = stdout, + int mv = 0) const; + void DumpDDcal( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + void DumpFactoredForm( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + BDD VectorSupport(const std::vector& roots) const; + std::vector + SupportIndices(const std::vector& roots) const; + int nodeCount(const std::vector& roots) const; + int VectorSupportSize(const std::vector& roots) const; + void DumpDot( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + void DumpDaVinci( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + BDD VectorSupport(const std::vector& roots) const; + int VectorSupportSize(const std::vector& roots) const; + void DumpDot( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + +}; // Cudd + + +extern void defaultError(std::string message); + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/obj/testobj.cc b/resources/3rdparty/cudd-2.5.0/obj/testobj.cc new file mode 100644 index 000000000..633e82337 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/obj/testobj.cc @@ -0,0 +1,607 @@ +/**CFile*********************************************************************** + + FileName [testobj.cc] + + PackageName [cuddObj] + + Synopsis [Test program for the C++ object-oriented encapsulation of CUDD.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "cuddObj.hh" +#include +#include +#include + +using namespace std; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UNUSED = "$Id: testobj.cc,v 1.7 2012/02/05 01:06:40 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void testBdd(Cudd& mgr, int verbosity); +static void testAdd(Cudd& mgr, int verbosity); +static void testAdd2(Cudd& mgr, int verbosity); +static void testZdd(Cudd& mgr, int verbosity); +static void testBdd2(Cudd& mgr, int verbosity); +static void testBdd3(Cudd& mgr, int verbosity); +static void testZdd2(Cudd& mgr, int verbosity); +static void testBdd4(Cudd& mgr, int verbosity); +static void testBdd5(Cudd& mgr, int verbosity); + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Main program for testobj.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +main(int argc, char **argv) +{ + int verbosity = 0; + + if (argc == 2) { + int retval = sscanf(argv[1], "%d", &verbosity); + if (retval != 1) + return 1; + } else if (argc != 1) { + return 1; + } + + Cudd mgr(0,2); + // mgr.makeVerbose(); // trace constructors and destructors + testBdd(mgr,verbosity); + testAdd(mgr,verbosity); + testAdd2(mgr,verbosity); + testZdd(mgr,verbosity); + testBdd2(mgr,verbosity); + testBdd3(mgr,verbosity); + testZdd2(mgr,verbosity); + testBdd4(mgr,verbosity); + testBdd5(mgr,verbosity); + if (verbosity) mgr.info(); + return 0; + +} // main + + +/**Function******************************************************************** + + Synopsis [Test basic operators on BDDs.] + + Description [Test basic operators on BDDs. The function returns void + because it relies on the error handling done by the interface. The + default error handler causes program termination.] + + SideEffects [Creates BDD variables in the manager.] + + SeeAlso [testBdd2 testBdd3 testBdd4 testBdd5] + +******************************************************************************/ +static void +testBdd( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testBdd\n"; + // Create two new variables in the manager. If testBdd is called before + // any variable is created in mgr, then x gets index 0 and y gets index 1. + BDD x = mgr.bddVar(); + BDD y = mgr.bddVar(); + + BDD f = x * y; + if (verbosity) cout << "f"; f.print(2,verbosity); + + BDD g = y + !x; + if (verbosity) cout << "g"; g.print(2,verbosity); + + if (verbosity) + cout << "f and g are" << (f == !g ? "" : " not") << " complementary\n"; + if (verbosity) + cout << "f is" << (f <= g ? "" : " not") << " less than or equal to g\n"; + + g = f | ~g; + if (verbosity) cout << "g"; g.print(2,verbosity); + + BDD h = f = y; + if (verbosity) cout << "h"; h.print(2,verbosity); + + if (verbosity) cout << "x + h has " << (x+h).nodeCount() << " nodes\n"; + + h += x; + if (verbosity) cout << "h"; h.print(2,verbosity); + +} // testBdd + + +/**Function******************************************************************** + + Synopsis [Test basic operators on ADDs.] + + Description [Test basic operators on ADDs. The function returns void + because it relies on the error handling done by the interface. The + default error handler causes program termination.] + + SideEffects [May create ADD variables in the manager.] + + SeeAlso [testAdd2] + +******************************************************************************/ +static void +testAdd( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testAdd\n"; + // Create two ADD variables. If we called method addVar without an + // argument, we would get two new indices. If testAdd is indeed called + // after testBdd, then those indices would be 2 and 3. By specifying the + // arguments, on the other hand, we avoid creating new unnecessary BDD + // variables. + ADD p = mgr.addVar(0); + ADD q = mgr.addVar(1); + + // Test arithmetic operators. + ADD r = p + q; + if (verbosity) cout << "r"; r.print(2,verbosity); + + // CUDD_VALUE_TYPE is double. + ADD s = mgr.constant(3.0); + s *= p * q; + if (verbosity) cout << "s"; s.print(2,verbosity); + + s += mgr.plusInfinity(); + if (verbosity) cout << "s"; s.print(2,verbosity); + + // Test relational operators. + if (verbosity) + cout << "p is" << (p <= r ? "" : " not") << " less than or equal to r\n"; + + // Test logical operators. + r = p | q; + if (verbosity) cout << "r"; r.print(2,verbosity); + +} // testAdd + + +/**Function******************************************************************** + + Synopsis [Test some more operators on ADDs.] + + Description [Test some more operators on ADDs. The function returns void + because it relies on the error handling done by the interface. The + default error handler causes program termination.] + + SideEffects [May create ADD variables in the manager.] + + SeeAlso [testAdd] + +******************************************************************************/ +static void +testAdd2( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testAdd2\n"; + // Create two ADD variables. If we called method addVar without an + // argument, we would get two new indices. + int i; + vector x(2); + for (i = 0; i < 2; i++) { + x[i] = mgr.addVar(i); + } + + // Build a probability density function: [0.1, 0.2, 0.3, 0.4]. + ADD f0 = x[1].Ite(mgr.constant(0.2), mgr.constant(0.1)); + ADD f1 = x[1].Ite(mgr.constant(0.4), mgr.constant(0.3)); + ADD f = x[0].Ite(f1, f0); + if (verbosity) cout << "f"; f.print(2,verbosity); + + // Compute the entropy. + ADD l = f.Log(); + if (verbosity) cout << "l"; l.print(2,verbosity); + ADD r = f * l; + if (verbosity) cout << "r"; r.print(2,verbosity); + + ADD e = r.MatrixMultiply(mgr.constant(-1.0/log(2.0)),x); + if (verbosity) cout << "e"; e.print(2,verbosity); + +} // testAdd2 + + +/**Function******************************************************************** + + Synopsis [Test basic operators on ZDDs.] + + Description [Test basic operators on ZDDs. The function returns void + because it relies on the error handling done by the interface. The + default error handler causes program termination.] + + SideEffects [May create ZDD variables in the manager.] + + SeeAlso [testZdd2] + +******************************************************************************/ +static void +testZdd( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testZdd\n"; + ZDD v = mgr.zddVar(0); + ZDD w = mgr.zddVar(1); + + ZDD s = v + w; + if (verbosity) cout << "s"; s.print(2,verbosity); + + if (verbosity) cout << "v is" << (v < s ? "" : " not") << " less than s\n"; + + s -= v; + if (verbosity) cout << "s"; s.print(2,verbosity); + +} // testZdd + + +/**Function******************************************************************** + + Synopsis [Test vector operators on BDDs.] + + Description [Test vector operators on BDDs. The function returns void + because it relies on the error handling done by the interface. The + default error handler causes program termination.] + + SideEffects [May create BDD variables in the manager.] + + SeeAlso [testBdd testBdd3 testBdd4 testBdd5] + +******************************************************************************/ +static void +testBdd2( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testBdd2\n"; + vector x(4); + for (int i = 0; i < 4; i++) { + x[i] = mgr.bddVar(i); + } + + // Create the BDD for the Achilles' Heel function. + BDD p1 = x[0] * x[2]; + BDD p2 = x[1] * x[3]; + BDD f = p1 + p2; + const char* inames[] = {"x0", "x1", "x2", "x3"}; + if (verbosity) { + cout << "f"; f.print(4,verbosity); + cout << "Irredundant cover of f:" << endl; f.PrintCover(); + cout << "Number of minterms (arbitrary precision): "; f.ApaPrintMinterm(4); + cout << "Number of minterms (extended precision): "; f.EpdPrintMinterm(4); + cout << "Two-literal clauses of f:" << endl; + f.PrintTwoLiteralClauses((char **)inames); cout << endl; + } + + vector vect = f.CharToVect(); + if (verbosity) { + for (size_t i = 0; i < vect.size(); i++) { + cout << "vect[" << i << "]" << endl; vect[i].PrintCover(); + } + } + + // v0,...,v3 suffice if testBdd2 is called before testBdd3. + if (verbosity) { + const char* onames[] = {"v0", "v1", "v2", "v3", "v4", "v5"}; + mgr.DumpDot(vect, (char **)inames,(char **)onames); + } + +} // testBdd2 + + +/**Function******************************************************************** + + Synopsis [Test additional operators on BDDs.] + + Description [Test additional operators on BDDs. The function returns + void because it relies on the error handling done by the + interface. The default error handler causes program termination.] + + SideEffects [May create BDD variables in the manager.] + + SeeAlso [testBdd testBdd2 testBdd4 testBdd5] + +******************************************************************************/ +static void +testBdd3( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testBdd3\n"; + vector x(6); + for (int i = 0; i < 6; i++) { + x[i] = mgr.bddVar(i); + } + + BDD G = x[4] + !x[5]; + BDD H = x[4] * x[5]; + BDD E = x[3].Ite(G,!x[5]); + BDD F = x[3] + !H; + BDD D = x[2].Ite(F,!H); + BDD C = x[2].Ite(E,!F); + BDD B = x[1].Ite(C,!F); + BDD A = x[0].Ite(B,!D); + BDD f = !A; + if (verbosity) cout << "f"; f.print(6,verbosity); + + BDD f1 = f.RemapUnderApprox(6); + if (verbosity) cout << "f1"; f1.print(6,verbosity); + if (verbosity) + cout << "f1 is" << (f1 <= f ? "" : " not") << " less than or equal to f\n"; + + BDD g; + BDD h; + f.GenConjDecomp(&g,&h); + if (verbosity) { + cout << "g"; g.print(6,verbosity); + cout << "h"; h.print(6,verbosity); + cout << "g * h " << (g * h == f ? "==" : "!=") << " f\n"; + } + +} // testBdd3 + + +/**Function******************************************************************** + + Synopsis [Test cover manipulation with BDDs and ZDDs.] + + Description [Test cover manipulation with BDDs and ZDDs. The + function returns void because it relies on the error handling done by + the interface. The default error handler causes program + termination. This function builds the BDDs for a transformed adder: + one in which the inputs are transformations of the original + inputs. It then creates ZDDs for the covers from the BDDs.] + + SideEffects [May create BDD and ZDD variables in the manager.] + + SeeAlso [testZdd] + +******************************************************************************/ +static void +testZdd2( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testZdd2\n"; + int N = 3; // number of bits + // Create variables. + vector a(N); + vector b(N); + vector c(N+1); + for (int i = 0; i < N; i++) { + a[N-1-i] = mgr.bddVar(2*i); + b[N-1-i] = mgr.bddVar(2*i+1); + } + c[0] = mgr.bddVar(2*N); + // Build functions. + vector s(N); + for (int i = 0; i < N; i++) { + s[i] = a[i].Xnor(c[i]); + c[i+1] = a[i].Ite(b[i],c[i]); + } + + // Create array of outputs and print it. + vector p(N+1); + for (int i = 0; i < N; i++) { + p[i] = s[i]; + } + p[N] = c[N]; + if (verbosity) { + for (size_t i = 0; i < p.size(); i++) { + cout << "p[" << i << "]"; p[i].print(2*N+1,verbosity); + } + } + const char* onames[] = {"s0", "s1", "s2", "c3"}; + if (verbosity) { + const char* inames[] = {"a2", "b2", "a1", "b1", "a0", "b0", "c0"}; + mgr.DumpDot(p, (char **)inames,(char **)onames); + } + + // Create ZDD variables and build ZDD covers from BDDs. + mgr.zddVarsFromBddVars(2); + vector z(N+1); + for (int i = 0; i < N+1; i++) { + ZDD temp; + BDD dummy = p[i].zddIsop(p[i],&temp); + z[i] = temp; + } + + // Print out covers. + if (verbosity) { + for (size_t i = 0; i < z.size(); i++) { + cout << "z[" << i << "]"; z[i].print(4*N+2,verbosity); + } + for (size_t i = 0; i < z.size(); i++) { + cout << "z[" << i << "]\n"; z[i].PrintCover(); + } + const char* znames[] = {"a2+", "a2-", "b2+", "b2-", "a1+", "a1-", "b1+", + "b1-", "a0+", "a0-", "b0+", "b0-", "c0+", "c0-"}; + mgr.DumpDot(z, (char **)znames,(char **)onames); + } + +} // testZdd2 + + +/**Function******************************************************************** + + Synopsis [Test transfer between BDD managers.] + + Description [Test transfer between BDD managers. The + function returns void because it relies on the error handling done by + the interface. The default error handler causes program + termination.] + + SideEffects [May create BDD variables in the manager.] + + SeeAlso [testBdd testBdd2 testBdd3 testBdd5] + +******************************************************************************/ +static void +testBdd4( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testBdd4\n"; + BDD x = mgr.bddVar(0); + BDD y = mgr.bddVar(1); + BDD z = mgr.bddVar(2); + + BDD f = !x * !y * !z + x * y; + if (verbosity) cout << "f"; f.print(3,verbosity); + + Cudd otherMgr(0,0); + BDD g = f.Transfer(otherMgr); + if (verbosity) cout << "g"; g.print(3,verbosity); + + BDD h = g.Transfer(mgr); + if (verbosity) + cout << "f and h are" << (f == h ? "" : " not") << " identical\n"; + +} // testBdd4 + + + +/**Function******************************************************************** + + Synopsis [Test maximal expansion of cubes.] + + Description [Test maximal expansion of cubes. The function returns + void because it relies on the error handling done by the interface. + The default error handler causes program termination.] + + SideEffects [May create BDD variables in the manager.] + + SeeAlso [testBdd testBdd2 testBdd3 testBdd4] + +******************************************************************************/ +static void +testBdd5( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testBdd5\n"; + vector x; + x.reserve(4); + for (int i = 0; i < 4; i++) { + x.push_back(mgr.bddVar(i)); + } + const char* inames[] = {"a", "b", "c", "d"}; + BDD f = (x[1] & x[3]) | (x[0] & !x[2] & x[3]) | (!x[0] & x[1] & !x[2]); + BDD lb = x[1] & !x[2] & x[3]; + BDD ub = x[3]; + BDD primes = lb.MaximallyExpand(ub,f); + assert(primes == (x[1] & x[3])); + BDD lprime = primes.LargestPrimeUnate(lb); + assert(lprime == primes); + if (verbosity) { + const char * onames[] = {"lb", "ub", "f", "primes", "lprime"}; + vector z; + z.reserve(5); + z.push_back(lb); + z.push_back(ub); + z.push_back(f); + z.push_back(primes); + z.push_back(lprime); + mgr.DumpDot(z, (char **)inames, (char **)onames); + cout << "primes(1)"; primes.print(4,verbosity); + } + + lb = !x[0] & x[2] & x[3]; + primes = lb.MaximallyExpand(ub,f); + assert(primes == mgr.bddZero()); + if (verbosity) { + cout << "primes(2)"; primes.print(4,verbosity); + } + + lb = x[0] & !x[2] & x[3]; + primes = lb.MaximallyExpand(ub,f); + assert(primes == lb); + lprime = primes.LargestPrimeUnate(lb); + assert(lprime == primes); + if (verbosity) { + cout << "primes(3)"; primes.print(4,verbosity); + } + + lb = !x[0] & x[1] & !x[2] & x[3]; + ub = mgr.bddOne(); + primes = lb.MaximallyExpand(ub,f); + assert(primes == ((x[1] & x[3]) | (!x[0] & x[1] & !x[2]))); + lprime = primes.LargestPrimeUnate(lb); + assert(lprime == (x[1] & x[3])); + if (verbosity) { + cout << "primes(4)"; primes.print(4,1); primes.PrintCover(); + } + + ub = !x[0] & x[3]; + primes = lb.MaximallyExpand(ub,f); + assert(primes == (!x[0] & x[1] & x[3])); + lprime = primes.LargestPrimeUnate(lb); + assert(lprime == primes); + if (verbosity) { + cout << "primes(5)"; primes.print(4,verbosity); + } + +} // testBdd5 diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h index fae7f270a..3f93607ba 100644 --- a/src/ir/expressions/BaseExpression.h +++ b/src/ir/expressions/BaseExpression.h @@ -12,7 +12,6 @@ #include "src/exceptions/NotImplementedException.h" #include "ExpressionVisitor.h" -#include "src/utility/CuddUtility.h" #include #include diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.h b/src/ir/expressions/BinaryBooleanFunctionExpression.h index 0cf866f74..85c927c60 100644 --- a/src/ir/expressions/BinaryBooleanFunctionExpression.h +++ b/src/ir/expressions/BinaryBooleanFunctionExpression.h @@ -10,8 +10,6 @@ #include "src/ir/expressions/BinaryExpression.h" -#include "src/utility/CuddUtility.h" - #include #include diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h index 539cb3114..153f4331d 100644 --- a/src/ir/expressions/BinaryNumericalFunctionExpression.h +++ b/src/ir/expressions/BinaryNumericalFunctionExpression.h @@ -10,8 +10,6 @@ #include "src/ir/expressions/BaseExpression.h" -#include "src/utility/CuddUtility.h" - namespace storm { namespace ir { diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h index d71072b13..1a60cd34d 100644 --- a/src/ir/expressions/BinaryRelationExpression.h +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -10,8 +10,6 @@ #include "src/ir/expressions/BinaryExpression.h" -#include "src/utility/CuddUtility.h" - namespace storm { namespace ir { diff --git a/src/ir/expressions/BooleanConstantExpression.h b/src/ir/expressions/BooleanConstantExpression.h index 9181a5449..858fe0c12 100644 --- a/src/ir/expressions/BooleanConstantExpression.h +++ b/src/ir/expressions/BooleanConstantExpression.h @@ -10,8 +10,6 @@ #include "ConstantExpression.h" -#include "src/utility/CuddUtility.h" - #include namespace storm { From 4df73785caeef1151ead7c0061d054784d5abdd9 Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 25 Feb 2013 14:28:06 +0100 Subject: [PATCH 041/152] Modified cudd's libobj Makefile to work for me. First: added CXXFLAGS line for g++ Second: added all necessary object files to libobj.a --- resources/3rdparty/cudd-2.5.0/obj/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/3rdparty/cudd-2.5.0/obj/Makefile b/resources/3rdparty/cudd-2.5.0/obj/Makefile index d3f62e1ad..54d0c92ce 100644 --- a/resources/3rdparty/cudd-2.5.0/obj/Makefile +++ b/resources/3rdparty/cudd-2.5.0/obj/Makefile @@ -18,6 +18,7 @@ ICFLAGS = XCFLAGS = #CXXFLAGS = CXXFLAGS = -O3 -std=c++11 -stdlib=libc++ +#CXXFLAGS = -O3 -std=c++0x CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) $(CXXFLAGS) DDDEBUG = @@ -61,7 +62,7 @@ UBJ = $(SRC:.cc=.u) #------------------------------------------------------ lib$(P).a: $(POBJ) - ar rv $@ $? + ar rv $@ $? ../cudd/*.o ../dddmp/*.o ../epd/*.o ../mtr/*.o ../st/*.o ../util/*.o $(RANLIB) $@ .cc.o: $(PHDR) From 490f037259b533ac1e416e420c8cb65cceee4397 Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 25 Feb 2013 14:48:52 +0100 Subject: [PATCH 042/152] Kind of undoing the previous commit. gcc can only link, if -lobj is the first cudd lib to be linked... Now, all the object files can be removed from libobj.a --- CMakeLists.txt | 2 +- resources/3rdparty/cudd-2.5.0/obj/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 92b6b03e2..bed5cc152 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -224,7 +224,7 @@ if (LOG4CPLUS_INCLUDE_DIR) endif(LOG4CPLUS_INCLUDE_DIR) if (CUDD_LIBRARY_DIRS) - target_link_libraries(storm "-lcudd -lmtr -lst -lutil -lepd -lobj") + target_link_libraries(storm "-lobj -lcudd -lmtr -lst -lutil -lepd") endif(CUDD_LIBRARY_DIRS) if (THREADS_FOUND) diff --git a/resources/3rdparty/cudd-2.5.0/obj/Makefile b/resources/3rdparty/cudd-2.5.0/obj/Makefile index 54d0c92ce..ffc656452 100644 --- a/resources/3rdparty/cudd-2.5.0/obj/Makefile +++ b/resources/3rdparty/cudd-2.5.0/obj/Makefile @@ -62,7 +62,7 @@ UBJ = $(SRC:.cc=.u) #------------------------------------------------------ lib$(P).a: $(POBJ) - ar rv $@ $? ../cudd/*.o ../dddmp/*.o ../epd/*.o ../mtr/*.o ../st/*.o ../util/*.o + ar rv $@ $? $(RANLIB) $@ .cc.o: $(PHDR) From 05cc90cece59a0b844fbb79b157fa148b0f0a24a Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 25 Feb 2013 14:59:45 +0100 Subject: [PATCH 043/152] Now also creating a std::set before inserting stuff... --- src/ir/Module.cpp | 3 +++ src/ir/Program.cpp | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index c09351037..9a2337f8a 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -34,6 +34,9 @@ Module::Module(std::string moduleName, std::vector b for (unsigned int id = 0; id < this->commands.size(); id++) { std::string action = this->commands[id].getActionName(); if (action != "") { + if (this->actionsToCommandIndexMap.count(action) == 0) { + this->actionsToCommandIndexMap[action] = std::shared_ptr>(new std::set()); + } this->actionsToCommandIndexMap[action]->insert(id); this->actions.insert(action); } diff --git a/src/ir/Program.cpp b/src/ir/Program.cpp index 5ce464fda..7a11f31d2 100644 --- a/src/ir/Program.cpp +++ b/src/ir/Program.cpp @@ -24,6 +24,9 @@ Program::Program(ModelType modelType, std::mapmodules.size(); id++) { for (auto action : this->modules[id].getActions()) { + if (this->actionsToModuleIndexMap.count(action) == 0) { + this->actionsToModuleIndexMap[action] = std::shared_ptr>(new std::set()); + } this->actionsToModuleIndexMap[action]->insert(id); this->actions.insert(action); } From c33d319ac358f6c7c3cbad76091160fc578b4807 Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 25 Feb 2013 15:50:20 +0100 Subject: [PATCH 044/152] some minor fixes, now with less memory errors :) --- src/adapters/ExplicitModelAdapter.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 84a1f52fd..d0070eefe 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -142,7 +142,7 @@ private: * @params update Update to be applied. * @return Resulting state. */ - StateType* applyUpdate(StateType const * state, storm::ir::Update const & update) { + StateType* applyUpdate(StateType const * const state, storm::ir::Update const & update) { StateType* newState = new StateType(*state); for (auto assignedVariable : update.getBooleanAssignments()) { setValue(newState, this->booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(state)); @@ -245,16 +245,20 @@ private: } } // Move new states to resultStates. - resultStates = newStates; + // resultStates = newStates; + resultStates.clear(); + resultStates.insert(newStates.begin(), newStates.end()); // Delete old result states. while (!deleteQueue.empty()) { - delete deleteQueue.front(); + if (deleteQueue.front() != currentState) { + delete deleteQueue.front(); + } deleteQueue.pop(); } } - // Now add our final result states to our global result. for (auto it : resultStates) { + hasTransition = true; auto s = stateToIndexMap.find(it.first); if (s == stateToIndexMap.end()) { stateQueue.push(it.first); From 58cf018371434c08587f84192f1c7a358e2009be Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 25 Feb 2013 16:08:52 +0100 Subject: [PATCH 045/152] Implemented synchronization in ExplicitModelChecker::buildMatrix(). This seems to produce the correct number of states and produces no valgrind errors. :-) --- src/adapters/ExplicitModelAdapter.h | 56 ++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index d0070eefe..01c5805cf 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -245,7 +245,6 @@ private: } } // Move new states to resultStates. - // resultStates = newStates; resultStates.clear(); resultStates.insert(newStates.begin(), newStates.end()); // Delete old result states. @@ -382,6 +381,60 @@ private: // Determine the matrix content for every row (i.e. reachable state). for (StateType* currentState : allStates) { bool hasTransition = false; + + std::map stateIndexToProbabilityMap; + + for (std::string action : this->program->getActions()) { + std::unique_ptr>> cmds = this->getActiveCommandsByAction(currentState, action); + std::unordered_map resultStates; + resultStates[currentState] = 1; + std::queue deleteQueue; + + for (std::list module : *cmds) { + std::unordered_map newStates; + for (storm::ir::Command command : module) { + for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { + storm::ir::Update const& update = command.getUpdate(k); + for (auto it : resultStates) { + StateType* newState = this->applyUpdate(it.first, update); + auto s = newStates.find(newState); + if (s == newStates.end()) { + newStates[newState] = it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); + } else { + newStates[newState] += it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); + } + deleteQueue.push(it.first); + } + } + } + resultStates.clear(); + resultStates.insert(newStates.begin(), newStates.end()); + while (!deleteQueue.empty()) { + if (deleteQueue.front() != currentState) { + delete deleteQueue.front(); + } + deleteQueue.pop(); + } + } + for (auto it : resultStates) { + hasTransition = true; + uint_fast64_t targetIndex = stateToIndexMap[it.first]; + auto s = stateIndexToProbabilityMap.find(targetIndex); + if (s == stateIndexToProbabilityMap.end()) { + stateIndexToProbabilityMap[targetIndex] = it.second; + } else { + stateIndexToProbabilityMap[targetIndex] += it.second; + deleteQueue.push(it.first); + } + } + while (!deleteQueue.empty()) { + delete deleteQueue.front(); + deleteQueue.pop(); + } + } + for (auto targetIndex : stateIndexToProbabilityMap) { + resultMatrix->addNextValue(currentIndex, targetIndex.first, targetIndex.second); + } // Iterate over all modules. for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { @@ -390,6 +443,7 @@ private: // Iterate over all commands. for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { storm::ir::Command const& command = module.getCommand(j); + if (command.getActionName() != "") continue; // Check if this command is enabled in the current state. if (command.getGuard()->getValueAsBool(currentState)) { From 34ca097eb317c5a82d830b7480cf6db0174ce168 Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 25 Feb 2013 16:13:28 +0100 Subject: [PATCH 046/152] fixed another more memory leak. One still missing... --- src/adapters/ExplicitModelAdapter.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 01c5805cf..308e2528d 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -489,6 +489,9 @@ private: } void clearReachableStateSpace() { + for (auto it : allStates) { + delete it; + } allStates.clear(); stateToIndexMap.clear(); } From 8f4f39d510740a5a47bc6c8adde2b4fbc15d2ab8 Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 25 Feb 2013 16:17:00 +0100 Subject: [PATCH 047/152] closed last memory leak... --- src/adapters/ExplicitModelAdapter.h | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 308e2528d..96a76d178 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -421,16 +421,12 @@ private: uint_fast64_t targetIndex = stateToIndexMap[it.first]; auto s = stateIndexToProbabilityMap.find(targetIndex); if (s == stateIndexToProbabilityMap.end()) { - stateIndexToProbabilityMap[targetIndex] = it.second; - } else { - stateIndexToProbabilityMap[targetIndex] += it.second; - deleteQueue.push(it.first); - } + stateIndexToProbabilityMap[targetIndex] = it.second; + } else { + stateIndexToProbabilityMap[targetIndex] += it.second; + } + delete it.first; } - while (!deleteQueue.empty()) { - delete deleteQueue.front(); - deleteQueue.pop(); - } } for (auto targetIndex : stateIndexToProbabilityMap) { resultMatrix->addNextValue(currentIndex, targetIndex.first, targetIndex.second); From 22d8ec76bce5dc9ad6631e684550fc4bdbf37759 Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 25 Feb 2013 17:08:30 +0100 Subject: [PATCH 048/152] fixed position indication in PrismParser in case of an error. --- src/parser/PrismParser.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 19eed26ae..e893dd28c 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -449,9 +449,11 @@ std::shared_ptr PrismParser::parse(std::istream& inputStream // Construct the error message including a caret display of the position in the // erroneous line. std::stringstream msg; + std::string line = e.first.get_currentline(); + while (line.find('\t') != std::string::npos) line.replace(line.find('\t'),1," "); msg << pos.file << ", line " << pos.line << ", column " << pos.column << ": parse error: expected " << e.what_ << std::endl << "\t" - << e.first.get_currentline() << std::endl << "\t"; + << line << std::endl << "\t"; int i = 0; for (i = 0; i < pos.column; ++i) { msg << "-"; From 351421e9e7dc18813912f5ad373da4ca1060c834 Mon Sep 17 00:00:00 2001 From: dehnert Date: Fri, 1 Mar 2013 10:53:55 +0100 Subject: [PATCH 049/152] Corrected typo. --- src/parser/PrismParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 19eed26ae..bf8d03cce 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -115,7 +115,7 @@ struct PrismParser::PrismGrammar : qi::grammar> relations_ >> integerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; - relativeExpression.name("boolean expression"); + relativeExpression.name("relative expression"); atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")") | booleanConstantExpression); atomicBooleanExpression.name("boolean expression"); notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::NOT))]; From ba49792d29e1ac25a8c82ba4b4607b24dd34e79e Mon Sep 17 00:00:00 2001 From: gereon Date: Thu, 7 Mar 2013 13:54:13 +0100 Subject: [PATCH 050/152] Perform two runs in PrismParser. First run collects all variables, second run uses the declared variables. --- src/parser/PrismParser.cpp | 308 +++++++++++++++++++++++-------------- 1 file changed, 192 insertions(+), 116 deletions(-) diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index e893dd28c..d84d79088 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -23,6 +23,7 @@ // Needed for file IO. #include #include +#include // Some typedefs and namespace definitions to reduce code size. typedef std::string::const_iterator BaseIteratorType; @@ -34,9 +35,12 @@ namespace storm { namespace parser { +using namespace storm::ir; +using namespace storm::ir::expressions; + // The Boost spirit grammar used for parsing the input. template -struct PrismParser::PrismGrammar : qi::grammar>, std::map>, std::map>, std::map, std::map>>, Skipper> { +struct PrismParser::PrismGrammar : qi::grammar>, std::map>, std::map>, std::map, std::map>>, Skipper> { /* * The constructor of the grammar. It defines all rules of the grammar and the corresponding @@ -52,24 +56,30 @@ struct PrismParser::PrismGrammar : qi::grammar> *(qi::alnum | qi::char_('_'))) - allConstantNames_ - keywords_]]; + identifierName.name("identifier"); freeIdentifierName %= qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_'))) - booleanVariableNames_ - integerVariableNames_ - allConstantNames_ - labelNames_ - moduleNames_ - keywords_]]; freeIdentifierName.name("unused identifier"); // This block defines all literal expressions. - booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; booleanLiteralExpression.name("boolean literal"); - integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; integerLiteralExpression.name("integer literal"); - doubleLiteralExpression = qi::double_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + doubleLiteralExpression = qi::double_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; doubleLiteralExpression.name("double literal"); literalExpression %= (booleanLiteralExpression | integerLiteralExpression | doubleLiteralExpression); literalExpression.name("literal"); - + + // This block defines all expressions that are variables. - integerVariableExpression %= integerVariables_; + std::shared_ptr intvarexpr = std::shared_ptr(new VariableExpression(BaseExpression::int_, std::numeric_limits::max(), "int", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); + std::shared_ptr boolvarexpr = std::shared_ptr(new VariableExpression(BaseExpression::bool_, std::numeric_limits::max(), "int", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); + integerVariableExpression = identifierName[qi::_val = intvarexpr]; integerVariableExpression.name("integer variable"); - booleanVariableExpression %= booleanVariables_; + booleanVariableExpression = identifierName[qi::_val = boolvarexpr]; booleanVariableExpression.name("boolean variable"); + variableExpression %= (integerVariableExpression | booleanVariableExpression); variableExpression.name("variable"); @@ -86,9 +96,9 @@ struct PrismParser::PrismGrammar : qi::grammar> integerExpression >> qi::lit(")") | integerConstantExpression); atomicIntegerExpression.name("integer expression"); - integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::TIMES))]; integerMultExpression.name("integer expression"); - integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> integerMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::MINUS))]]; + integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> integerMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::MINUS))]]; integerPlusExpression.name("integer expression"); integerExpression %= integerPlusExpression; integerExpression.name("integer expression"); @@ -96,9 +106,9 @@ struct PrismParser::PrismGrammar : qi::grammar> constantIntegerExpression >> qi::lit(")") | integerConstantExpression); constantAtomicIntegerExpression.name("constant integer expression"); - constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES))]; + constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::TIMES))]; constantIntegerMultExpression.name("constant integer expression"); - constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantIntegerMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::MINUS))]]; + constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantIntegerMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::MINUS))]]; constantIntegerPlusExpression.name("constant integer expression"); constantIntegerExpression %= constantIntegerPlusExpression; constantIntegerExpression.name("constant integer expression"); @@ -106,37 +116,37 @@ struct PrismParser::PrismGrammar : qi::grammar> constantDoubleExpression >> qi::lit(")") | doubleConstantExpression); constantAtomicDoubleExpression.name("constant double expression"); - constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> constantAtomicDoubleExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::double_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::double_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::DIVIDE))]]; + constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> constantAtomicDoubleExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::double_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::TIMES)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::double_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::DIVIDE))]]; constantDoubleMultExpression.name("constant double expression"); - constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantDoubleMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::double_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::double_, qi::_val, qi::_1, storm::ir::expressions::BinaryNumericalFunctionExpression::MINUS))]]; + constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantDoubleMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::double_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::double_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::MINUS))]]; constantDoublePlusExpression.name("constant double expression"); constantDoubleExpression %= constantDoublePlusExpression; constantDoubleExpression.name("constant double expression"); // This block defines all expressions of type boolean. - relativeExpression = (integerExpression >> relations_ >> integerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; + relativeExpression = (integerExpression >> relations_ >> integerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; relativeExpression.name("boolean expression"); atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")") | booleanConstantExpression); atomicBooleanExpression.name("boolean expression"); - notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::NOT))]; + notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, UnaryBooleanFunctionExpression::NOT))]; notExpression.name("boolean expression"); - andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; + andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::AND))]; andExpression.name("boolean expression"); - orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::OR))]; + orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::OR))]; orExpression.name("boolean expression"); booleanExpression %= orExpression; booleanExpression.name("boolean expression"); // This block defines all expressions of type boolean that are by syntax constant. That is, they are evaluable given the values for all constants. - constantRelativeExpression = (constantIntegerExpression >> relations_ >> constantIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; + constantRelativeExpression = (constantIntegerExpression >> relations_ >> constantIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; constantRelativeExpression.name("constant boolean expression"); constantAtomicBooleanExpression %= (constantRelativeExpression | qi::lit("(") >> constantBooleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression); constantAtomicBooleanExpression.name("constant boolean expression"); - constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, storm::ir::expressions::UnaryBooleanFunctionExpression::NOT))]; + constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, UnaryBooleanFunctionExpression::NOT))]; constantNotExpression.name("constant boolean expression"); - constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::AND))]; + constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::AND))]; constantAndExpression.name("constant boolean expression"); - constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, storm::ir::expressions::BinaryBooleanFunctionExpression::OR))]; + constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::OR))]; constantOrExpression.name("constant boolean expression"); constantBooleanExpression %= constantOrExpression; constantBooleanExpression.name("constant boolean expression"); @@ -146,17 +156,17 @@ struct PrismParser::PrismGrammar : qi::grammar> -qi::lit("\"") >> freeIdentifierName >> -qi::lit("\"") >> qi::lit("=") >> booleanExpression >> qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_2)), phoenix::bind(labelNames_.add, qi::_1, qi::_1)]; + labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> freeIdentifierName >> -qi::lit("\"") >> qi::lit("=") >> booleanExpression >> qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_2)), phoenix::bind(labelNames_.add, qi::_1, qi::_1)]; labelDefinition.name("label declaration"); labelDefinitionList %= *labelDefinition(qi::_r1); labelDefinitionList.name("label declaration list"); // This block defines all entities that are needed for parsing a reward model. - stateRewardDefinition = (booleanExpression > qi::lit(":") > constantDoubleExpression >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; + stateRewardDefinition = (booleanExpression > qi::lit(":") > constantDoubleExpression >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; stateRewardDefinition.name("state reward definition"); - transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit(":") > constantDoubleExpression > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; + transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit(":") > constantDoubleExpression > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; transitionRewardDefinition.name("transition reward definition"); - rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > freeIdentifierName > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> qi::lit("endrewards"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_a, qi::_b)))]; + rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > freeIdentifierName > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> qi::lit("endrewards"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_a, qi::_b)))]; rewardDefinition.name("reward definition"); rewardDefinitionList = *rewardDefinition(qi::_r1); rewardDefinitionList.name("reward definition list"); @@ -174,27 +184,45 @@ struct PrismParser::PrismGrammar : qi::grammar> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > integerExpression > qi::lit(")"))[phoenix::bind(assignedLocalIntegerVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))] | (qi::lit("(") > unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > booleanExpression > qi::lit(")"))[phoenix::bind(assignedLocalBooleanVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))]; + assignmentDefinition = (qi::lit("(") >> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > integerExpression > qi::lit(")"))[phoenix::bind(assignedLocalIntegerVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))] | (qi::lit("(") > unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > booleanExpression > qi::lit(")"))[phoenix::bind(assignedLocalBooleanVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))]; assignmentDefinition.name("assignment"); assignmentDefinitionList = assignmentDefinition(qi::_r1, qi::_r2) % "&"; assignmentDefinitionList.name("assignment list"); - updateDefinition = (constantDoubleExpression > qi::lit(":")[phoenix::clear(phoenix::ref(assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b)]; + updateDefinition = (constantDoubleExpression > qi::lit(":")[phoenix::clear(phoenix::ref(assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b)]; updateDefinition.name("update"); updateListDefinition = +updateDefinition % "+"; updateListDefinition.name("update list"); - commandDefinition = (qi::lit("[") > -((freeIdentifierName[phoenix::bind(commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit("->") > updateListDefinition > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; + commandDefinition = (qi::lit("[") > -((freeIdentifierName[phoenix::bind(commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit("->") > updateListDefinition > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; commandDefinition.name("command"); - // This block defines all entities that are neede for parsing variable definitions. - booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextBooleanVariableIndex), phoenix::val(qi::_1), qi::_b)), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextBooleanVariableIndex))), qi::_a = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::bool_, phoenix::ref(nextBooleanVariableIndex), qi::_1)), phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localBooleanVariables_.add, qi::_1, qi::_1), phoenix::ref(nextBooleanVariableIndex) = phoenix::ref(nextBooleanVariableIndex) + 1]; + // This block defines all entities that are needed for parsing variable definitions. + booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) + [ + phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextBooleanVariableIndex), phoenix::val(qi::_1), qi::_b)), + phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextBooleanVariableIndex))), + qi::_a = phoenix::construct>(phoenix::new_(BaseExpression::bool_, phoenix::ref(nextBooleanVariableIndex), qi::_1)), + phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), + phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), + phoenix::bind(localBooleanVariables_.add, qi::_1, qi::_1), + phoenix::ref(nextBooleanVariableIndex) = phoenix::ref(nextBooleanVariableIndex) + 1 + ]; booleanVariableDefinition.name("boolean variable declaration"); - integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";"))[phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3, qi::_b)), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextIntegerVariableIndex))), qi::_a = phoenix::construct>(phoenix::new_(storm::ir::expressions::BaseExpression::int_, phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3)), phoenix::bind(integerVariables_.add, qi::_1, qi::_a), phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), phoenix::bind(localIntegerVariables_.add, qi::_1, qi::_1), phoenix::ref(nextIntegerVariableIndex) = phoenix::ref(nextIntegerVariableIndex) + 1]; + integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) + [ + phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3, qi::_b)), + phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextIntegerVariableIndex))), + qi::_a = phoenix::construct>(phoenix::new_(BaseExpression::int_, phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3)), + phoenix::bind(integerVariables_.add, qi::_1, qi::_a), + phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), + phoenix::bind(localIntegerVariables_.add, qi::_1, qi::_1), + phoenix::ref(nextIntegerVariableIndex) = phoenix::ref(nextIntegerVariableIndex) + 1 + ]; integerVariableDefinition.name("integer variable declaration"); variableDefinition = (booleanVariableDefinition(qi::_r1, qi::_r3) | integerVariableDefinition(qi::_r2, qi::_r4)); variableDefinition.name("variable declaration"); // This block defines all entities that are needed for parsing a module. - moduleDefinition = (qi::lit("module")[phoenix::clear(phoenix::ref(localBooleanVariables_)), phoenix::clear(phoenix::ref(localIntegerVariables_))] > freeIdentifierName > *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) > +commandDefinition > qi::lit("endmodule"))[phoenix::bind(moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2)]; + moduleDefinition = ((qi::lit("module")[phoenix::clear(phoenix::ref(localBooleanVariables_)), phoenix::clear(phoenix::ref(localIntegerVariables_))] > freeIdentifierName > *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) > +commandDefinition > qi::lit("endmodule"))[phoenix::bind(moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2)]; moduleDefinition.name("module"); moduleDefinitionList %= +moduleDefinition; moduleDefinitionList.name("module list"); @@ -206,11 +234,11 @@ struct PrismParser::PrismGrammar : qi::grammar> qi::lit("double") >> freeIdentifierName >> qi::lit("=") > doubleLiteralExpression > qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; definedDoubleConstantDefinition.name("defined double constant declaration"); - undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; + undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; undefinedBooleanConstantDefinition.name("undefined boolean constant declaration"); - undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(integerConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; + undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(integerConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; undefinedIntegerConstantDefinition.name("undefined integer constant declaration"); - undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; + undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; undefinedDoubleConstantDefinition.name("undefined double constant declaration"); definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); definedConstantDefinition.name("defined constant declaration"); @@ -222,30 +250,71 @@ struct PrismParser::PrismGrammar : qi::grammar constantDefinitionList(qi::_a, qi::_b, qi::_c) > moduleDefinitionList > rewardDefinitionList(qi::_d) > labelDefinitionList(qi::_e))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_d, qi::_e)]; + start = (modelTypeDefinition > constantDefinitionList(qi::_a, qi::_b, qi::_c) > moduleDefinitionList > rewardDefinitionList(qi::_d) > labelDefinitionList(qi::_e))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_d, qi::_e)]; start.name("probabilistic program declaration"); } + + void prepareForSecondRun() { + // Clear constants. + integerConstants_.clear(); + booleanConstants_.clear(); + doubleConstants_.clear(); + // Reset variable indices. + nextIntegerVariableIndex = 0; + nextBooleanVariableIndex = 0; + + // Override variable expressions: only allow declared variables. + integerVariableExpression %= integerVariables_; + integerVariableExpression.name("integer variable"); + booleanVariableExpression %= booleanVariables_; + booleanVariableExpression.name("boolean variable"); + + // Override variable definition: don't register variables again globally. + booleanVariableDefinition = (identifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression) > qi::lit(";")) + [ + phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextBooleanVariableIndex), phoenix::val(qi::_1), qi::_b)), + phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextBooleanVariableIndex))), + qi::_a = phoenix::construct>(phoenix::new_(BaseExpression::bool_, phoenix::ref(nextBooleanVariableIndex), qi::_1)), + phoenix::bind(localBooleanVariables_.add, qi::_1, qi::_1), + phoenix::ref(nextBooleanVariableIndex) = phoenix::ref(nextBooleanVariableIndex) + 1 + ]; + booleanVariableDefinition.name("boolean variable declaration"); + integerVariableDefinition = (identifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression) > qi::lit(";")) + [ + phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3, qi::_b)), + phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextIntegerVariableIndex))), + qi::_a = phoenix::construct>(phoenix::new_(BaseExpression::int_, phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3)), + phoenix::bind(localIntegerVariables_.add, qi::_1, qi::_1), + phoenix::ref(nextIntegerVariableIndex) = phoenix::ref(nextIntegerVariableIndex) + 1 + ]; + integerVariableDefinition.name("integer variable declaration"); + + // Override module definition: allow already registered module names. + moduleDefinition = ((qi::lit("module")[phoenix::clear(phoenix::ref(localBooleanVariables_)), phoenix::clear(phoenix::ref(localIntegerVariables_))] > identifierName > *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) > +commandDefinition > qi::lit("endmodule"))[phoenix::bind(moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2)]; + moduleDefinition.name("module"); + } + // The starting point of the grammar. - qi::rule>, std::map>, std::map>, std::map, std::map>>, Skipper> start; - qi::rule modelTypeDefinition; - qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; - qi::rule(), Skipper> moduleDefinitionList; + qi::rule>, std::map>, std::map>, std::map, std::map>>, Skipper> start; + qi::rule modelTypeDefinition; + qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; + qi::rule(), Skipper> moduleDefinitionList; // Rules for module definition. - qi::rule, std::vector, std::map, std::map>, Skipper> moduleDefinition; + qi::rule, std::vector, std::map, std::map>, Skipper> moduleDefinition; // Rules for variable definitions. - qi::rule&, std::vector&, std::map&, std::map&), Skipper> variableDefinition; - qi::rule&, std::map&), qi::locals, std::shared_ptr>, Skipper> booleanVariableDefinition; - qi::rule&, std::map&), qi::locals, std::shared_ptr>, Skipper> integerVariableDefinition; + qi::rule&, std::vector&, std::map&, std::map&), Skipper> variableDefinition; + qi::rule&, std::map&), qi::locals, std::shared_ptr>, Skipper> booleanVariableDefinition; + qi::rule&, std::map&), qi::locals, std::shared_ptr>, Skipper> integerVariableDefinition; // Rules for command definitions. - qi::rule, Skipper> commandDefinition; - qi::rule(), Skipper> updateListDefinition; - qi::rule, std::map>, Skipper> updateDefinition; - qi::rule&, std::map&), Skipper> assignmentDefinitionList; - qi::rule&, std::map&), Skipper> assignmentDefinition; + qi::rule, Skipper> commandDefinition; + qi::rule(), Skipper> updateListDefinition; + qi::rule, std::map>, Skipper> updateDefinition; + qi::rule&, std::map&), Skipper> assignmentDefinitionList; + qi::rule&, std::map&), Skipper> assignmentDefinition; // Rules for variable/command names. qi::rule integerVariableName; @@ -255,78 +324,80 @@ struct PrismParser::PrismGrammar : qi::grammar unassignedLocalIntegerVariableName; // Rules for reward definitions. - qi::rule&), Skipper> rewardDefinitionList; - qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; - qi::rule stateRewardDefinition; - qi::rule, Skipper> transitionRewardDefinition; + qi::rule&), Skipper> rewardDefinitionList; + qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; + qi::rule stateRewardDefinition; + qi::rule, Skipper> transitionRewardDefinition; // Rules for label definitions. - qi::rule>&), Skipper> labelDefinitionList; - qi::rule>&), Skipper> labelDefinition; + qi::rule>&), Skipper> labelDefinitionList; + qi::rule>&), Skipper> labelDefinition; // Rules for constant definitions. - qi::rule(), Skipper> constantDefinition; - qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; - qi::rule(), Skipper> definedConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedBooleanConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedIntegerConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedDoubleConstantDefinition; - qi::rule(), Skipper> definedBooleanConstantDefinition; - qi::rule(), Skipper> definedIntegerConstantDefinition; - qi::rule(), Skipper> definedDoubleConstantDefinition; + qi::rule(), Skipper> constantDefinition; + qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; + qi::rule(), Skipper> definedConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedBooleanConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedIntegerConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedDoubleConstantDefinition; + qi::rule(), Skipper> definedBooleanConstantDefinition; + qi::rule(), Skipper> definedIntegerConstantDefinition; + qi::rule(), Skipper> definedDoubleConstantDefinition; qi::rule freeIdentifierName; qi::rule identifierName; // The starting point for arbitrary expressions. - qi::rule(), Skipper> expression; + qi::rule(), Skipper> expression; // Rules with boolean result type. - qi::rule(), Skipper> booleanExpression; - qi::rule(), Skipper> orExpression; - qi::rule(), Skipper> andExpression; - qi::rule(), Skipper> notExpression; - qi::rule(), Skipper> atomicBooleanExpression; - qi::rule(), Skipper> relativeExpression; - qi::rule(), Skipper> constantBooleanExpression; - qi::rule(), Skipper> constantOrExpression; - qi::rule(), Skipper> constantAndExpression; - qi::rule(), Skipper> constantNotExpression; - qi::rule(), Skipper> constantAtomicBooleanExpression; - qi::rule(), Skipper> constantRelativeExpression; + qi::rule(), Skipper> booleanExpression; + qi::rule(), Skipper> orExpression; + qi::rule(), Skipper> andExpression; + qi::rule(), Skipper> notExpression; + qi::rule(), Skipper> atomicBooleanExpression; + qi::rule(), Skipper> relativeExpression; + qi::rule(), Skipper> constantBooleanExpression; + qi::rule(), Skipper> constantOrExpression; + qi::rule(), Skipper> constantAndExpression; + qi::rule(), Skipper> constantNotExpression; + qi::rule(), Skipper> constantAtomicBooleanExpression; + qi::rule(), Skipper> constantRelativeExpression; // Rules with integer result type. - qi::rule(), Skipper> integerExpression; - qi::rule(), qi::locals, Skipper> integerPlusExpression; - qi::rule(), Skipper> integerMultExpression; - qi::rule(), Skipper> atomicIntegerExpression; - qi::rule(), Skipper> constantIntegerExpression; - qi::rule(), qi::locals, Skipper> constantIntegerPlusExpression; - qi::rule(), Skipper> constantIntegerMultExpression; - qi::rule(), Skipper> constantAtomicIntegerExpression; + qi::rule(), Skipper> integerExpression; + qi::rule(), qi::locals, Skipper> integerPlusExpression; + qi::rule(), Skipper> integerMultExpression; + qi::rule(), Skipper> atomicIntegerExpression; + qi::rule(), Skipper> constantIntegerExpression; + qi::rule(), qi::locals, Skipper> constantIntegerPlusExpression; + qi::rule(), Skipper> constantIntegerMultExpression; + qi::rule(), Skipper> constantAtomicIntegerExpression; // Rules with double result type. - qi::rule(), Skipper> constantDoubleExpression; - qi::rule(), qi::locals, Skipper> constantDoublePlusExpression; - qi::rule(), qi::locals, Skipper> constantDoubleMultExpression; - qi::rule(), Skipper> constantAtomicDoubleExpression; + qi::rule(), Skipper> constantDoubleExpression; + qi::rule(), qi::locals, Skipper> constantDoublePlusExpression; + qi::rule(), qi::locals, Skipper> constantDoubleMultExpression; + qi::rule(), Skipper> constantAtomicDoubleExpression; // Rules for variable recognition. - qi::rule(), Skipper> variableExpression; - qi::rule(), Skipper> booleanVariableExpression; - qi::rule(), Skipper> integerVariableExpression; + qi::rule(), Skipper> variableExpression; + qi::rule(), Skipper> booleanVariableExpression; + qi::rule(), Skipper> booleanVariableCreatorExpression; + qi::rule(), Skipper> integerVariableExpression; + qi::rule(), qi::locals>, Skipper> integerVariableCreatorExpression; // Rules for constant recognition. - qi::rule(), Skipper> constantExpression; - qi::rule(), Skipper> booleanConstantExpression; - qi::rule(), Skipper> integerConstantExpression; - qi::rule(), Skipper> doubleConstantExpression; + qi::rule(), Skipper> constantExpression; + qi::rule(), Skipper> booleanConstantExpression; + qi::rule(), Skipper> integerConstantExpression; + qi::rule(), Skipper> doubleConstantExpression; // Rules for literal recognition. - qi::rule(), Skipper> literalExpression; - qi::rule(), Skipper> booleanLiteralExpression; - qi::rule(), Skipper> integerLiteralExpression; - qi::rule(), Skipper> doubleLiteralExpression; + qi::rule(), Skipper> literalExpression; + qi::rule(), Skipper> booleanLiteralExpression; + qi::rule(), Skipper> integerLiteralExpression; + qi::rule(), Skipper> doubleLiteralExpression; // A structure defining the keywords that are not allowed to be chosen as identifiers. struct keywordsStruct : qi::symbols { @@ -351,27 +422,27 @@ struct PrismParser::PrismGrammar : qi::grammar { + struct modelTypeStruct : qi::symbols { modelTypeStruct() { add - ("dtmc", storm::ir::Program::ModelType::DTMC) - ("ctmc", storm::ir::Program::ModelType::CTMC) - ("mdp", storm::ir::Program::ModelType::MDP) - ("ctmdp", storm::ir::Program::ModelType::CTMDP) + ("dtmc", Program::ModelType::DTMC) + ("ctmc", Program::ModelType::CTMC) + ("mdp", Program::ModelType::MDP) + ("ctmdp", Program::ModelType::CTMDP) ; } } modelType_; // A structure mapping the textual representation of a binary relation to the representation // of the intermediate representation. - struct relationalOperatorStruct : qi::symbols { + struct relationalOperatorStruct : qi::symbols { relationalOperatorStruct() { add - ("=", storm::ir::expressions::BinaryRelationExpression::EQUAL) - ("<", storm::ir::expressions::BinaryRelationExpression::LESS) - ("<=", storm::ir::expressions::BinaryRelationExpression::LESS_OR_EQUAL) - (">", storm::ir::expressions::BinaryRelationExpression::GREATER) - (">=", storm::ir::expressions::BinaryRelationExpression::GREATER_OR_EQUAL) + ("=", BinaryRelationExpression::EQUAL) + ("<", BinaryRelationExpression::LESS) + ("<=", BinaryRelationExpression::LESS_OR_EQUAL) + (">", BinaryRelationExpression::GREATER) + (">=", BinaryRelationExpression::GREATER_OR_EQUAL) ; } } relations_; @@ -382,8 +453,8 @@ struct PrismParser::PrismGrammar : qi::grammar> integerVariables_, booleanVariables_; - struct qi::symbols> integerConstants_, booleanConstants_, doubleConstants_; + struct qi::symbols> integerVariables_, booleanVariables_; + struct qi::symbols> integerConstants_, booleanConstants_, doubleConstants_; // A structure representing the identity function over identifier names. struct variableNamesStruct : qi::symbols { } integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_, @@ -429,6 +500,7 @@ std::shared_ptr PrismParser::parse(std::istream& inputStream BaseIteratorType stringIteratorBegin = fileContent.begin(); BaseIteratorType stringIteratorEnd = fileContent.end(); PositionIteratorType positionIteratorBegin(stringIteratorBegin, stringIteratorEnd, filename); + PositionIteratorType positionIteratorBegin2(stringIteratorBegin, stringIteratorEnd, filename); PositionIteratorType positionIteratorEnd; // Prepare resulting intermediate representation of input. @@ -438,9 +510,13 @@ std::shared_ptr PrismParser::parse(std::istream& inputStream // As this is more complex, we let Boost figure out the actual type for us. PrismGrammar> *(qi::char_ - qi::eol) >> qi::eol)> grammar; try { - // Now parse the content using phrase_parse in order to be able to supply a skipping - // parser. + // Now parse the content using phrase_parse in order to be able to supply a skipping parser. + // First run. qi::phrase_parse(positionIteratorBegin, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, *result); + grammar.prepareForSecondRun(); + result = std::shared_ptr(new storm::ir::Program()); + // Second run. + qi::phrase_parse(positionIteratorBegin2, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, *result); } catch(const qi::expectation_failure& e) { // If the parser expected content different than the one provided, display information // about the location of the error. @@ -455,7 +531,7 @@ std::shared_ptr PrismParser::parse(std::istream& inputStream << ": parse error: expected " << e.what_ << std::endl << "\t" << line << std::endl << "\t"; int i = 0; - for (i = 0; i < pos.column; ++i) { + for (i = 1; i < pos.column; ++i) { msg << "-"; } msg << "^"; From 6d0d7e21c59333191df437d735afb3f26cc10ba4 Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 11 Mar 2013 19:20:05 +0100 Subject: [PATCH 051/152] First chunk of code for new ExplicitModelAdapter. The new adapter will generate an intermediate datastructure that holds all transitions to be inserted. This will combine the two phases (computing the state space and actually generating the matrix) and can also be used for dtmc and mdp models. This datastructure is only a list of maps for each state. Each map represents a nondeterministic choice and maps target node ids to their probability. --- src/adapters/ExplicitModelAdapter.h | 120 +++++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 10 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 96a76d178..a831a8528 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -63,6 +63,7 @@ public: std::shared_ptr> toSparseMatrix() { LOG4CPLUS_INFO(logger, "Creating sparse matrix for probabilistic program."); + this->computeReachableStateSpace2(); this->computeReachableStateSpace(); std::shared_ptr> resultMatrix = this->buildMatrix(); @@ -153,27 +154,126 @@ private: return newState; } - void computeReachableStateSpace() { - bool nondeterministicModel = program->getModelType() == storm::ir::Program::MDP || program->getModelType() == storm::ir::Program::CTMDP; - - // Prepare some internal data structures, such as mappings from variables to indices and so on. - this->prepareAuxiliaryDatastructures(); - + /*! + * Create a new state and initialize with initial values. + * @return Pointer to initial state. + */ + StateType* buildInitialState() { // Create a fresh state which can hold as many boolean and integer variables as there are. StateType* initialState = new StateType(); - initialState->first.resize(booleanVariables.size()); - initialState->second.resize(integerVariables.size()); + initialState->first.resize(this->booleanVariables.size()); + initialState->second.resize(this->integerVariables.size()); // Now initialize all fields in the value vectors of the state according to the initial // values provided by the input program. - for (uint_fast64_t i = 0; i < booleanVariables.size(); ++i) { + for (uint_fast64_t i = 0; i < this->booleanVariables.size(); ++i) { bool initialValue = this->booleanVariables[i].getInitialValue()->getValueAsBool(initialState); std::get<0>(*initialState)[i] = initialValue; } - for (uint_fast64_t i = 0; i < integerVariables.size(); ++i) { + for (uint_fast64_t i = 0; i < this->integerVariables.size(); ++i) { int_fast64_t initialValue = this->integerVariables[i].getInitialValue()->getValueAsInt(initialState); std::get<1>(*initialState)[i] = initialValue; } + return initialState; + } + + /*! + * Retrieves the state id of the given state. + * If the state has not been hit yet, it will be added to allStates and given a new id. + * In this case, the pointer must not be deleted, as it is used within allStates. + * If the state is already known, the pointer is deleted and the old state id is returned. + * Hence, the given state pointer should not be used afterwards. + * @param state Pointer to state, shall not be used afterwards. + * @returns State id of given state. + */ + uint_fast64_t getOrAddStateId(StateType * state) { + // Check, if we already know this state at all. + auto indexIt = this->stateToIndexMap.find(state); + if (indexIt == this->stateToIndexMap.end()) { + // No, add to allStates, initialize index. + allStates.push_back(state); + stateToIndexMap[state] = allStates.size()-1; + return allStates.size()-1; + } else { + // Yes, obtain index and delete state object. + delete state; + return indexIt->second; + } + } + + /*! + * Expands all unlabeled transitions for a given state and adds them to the given list of results. + * There will be an additional map for each Command that is active. + * Each such map will contain a probability distribution over the reachable states using this Command. + * @params state State to be expanded + * @params res List of + */ + void addUnlabeledTransitions(const StateType* state, std::list>& res) { + std::cout << "exploring ( "; + for (auto it : state->first) std::cout << it << ", "; + for (auto it : state->second) std::cout << it << ", "; + std::cout << ")" << std::endl; + + // Iterate over all modules. + for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { + storm::ir::Module const& module = program->getModule(i); + // Iterate over all commands. + for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { + storm::ir::Command const& command = module.getCommand(j); + // Only consider unlabeled commands. + if (command.getActionName() != "") continue; + // Omit, if command is not active. + if (!command.getGuard()->getValueAsBool(state)) continue; + + // Add a new map and get pointer. + res.emplace_back(); + std::map* states = &res.back(); + + // Iterate over all updates. + for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { + // Obtain new state id. + storm::ir::Update const& update = command.getUpdate(k); + uint_fast64_t newStateId = this->getOrAddStateId(this->applyUpdate(state, update)); + + // Check, if we already know this state, add up probabilities for every state. + auto stateIt = states->find(newStateId); + if (stateIt == states->end()) { + (*states)[newStateId] = update.getLikelihoodExpression()->getValueAsDouble(state); + } else { + (*states)[newStateId] += update.getLikelihoodExpression()->getValueAsDouble(state); + } + } + } + } + } + + void dump(std::map& obj) { + std::cout << "Some map:" << std::endl; + for (auto it: obj) { + std::cout << "\t" << it.first << ": " << it.second << std::endl; + } + } + + void computeReachableStateSpace2() { + this->prepareAuxiliaryDatastructures(); + this->allStates.clear(); + this->stateToIndexMap.clear(); + + for (uint_fast64_t curIndex = this->getOrAddStateId(this->buildInitialState()); curIndex < this->allStates.size(); curIndex++) + { + std::list> choices; + this->addUnlabeledTransitions(this->allStates[curIndex], choices); + std::cout << "Output:" << std::endl; + for (auto it: choices) this->dump(it); + } + std::cout << "got " << this->allStates.size() << " states" << std::endl; + } + + void computeReachableStateSpace() { + // Prepare some internal data structures, such as mappings from variables to indices and so on. + this->prepareAuxiliaryDatastructures(); + // Build initial state. + StateType* initialState = this->buildInitialState(); // Now set up the environment for a breadth-first search starting from the initial state. uint_fast64_t nextIndex = 1; From 3464ef20c52913a213366a30e476c7957bce65dc Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 11 Mar 2013 20:11:15 +0100 Subject: [PATCH 052/152] next chunk of code for new ExplicitModelAdapter. now we have routines to create a result matrix from the intermediate representation, one for DTMCs and one for MDPs. --- src/adapters/ExplicitModelAdapter.h | 89 ++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 7 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index a831a8528..995bc296e 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -63,7 +63,7 @@ public: std::shared_ptr> toSparseMatrix() { LOG4CPLUS_INFO(logger, "Creating sparse matrix for probabilistic program."); - this->computeReachableStateSpace2(); + this->buildMatrix2(); this->computeReachableStateSpace(); std::shared_ptr> resultMatrix = this->buildMatrix(); @@ -254,19 +254,94 @@ private: } } - void computeReachableStateSpace2() { + /*! + * Create matrix from intermediate mapping, assuming it is a dtmc model. + * @param intermediate Intermediate representation of transition mapping. + * @return result matrix. + */ + template + std::shared_ptr> buildDTMCMatrix(std::map>> intermediate) { + std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size())); + result->initialize(numberOfTransitions); + for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { + //if (intermediate[state].size() > 1) WARNING; + double factor = 1.0 / intermediate[state].size(); + std::map map; + for (auto choice : intermediate[state]) { + for (auto elem : choice) { + map[elem.first] += elem.second * factor; + } + } + for (auto it : map) { + result->addNextValue(state, it.first, it.second); + } + + } + result->finalize(); + return result; + } + + /*! + * Create matrix from intermediate mapping, assuming it is a mdp model. + * @param intermediate Intermediate representation of transition mapping. + * @return result matrix. + */ + template + std::shared_ptr> buildMDPMatrix(std::map>> intermediate, uint_fast64_t choices) { + std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size(), choices)); + result->initialize(numberOfTransitions); + uint_fast64_t nextRow = 0; + for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { + for (auto choice : intermediate[state]) { + for (auto it : choice) { + result->addNextValue(nextRow, it.first, it.second); + } + nextRow++; + } + } + result->finalize(); + return result; + } + + template + std::shared_ptr> buildMatrix2() { this->prepareAuxiliaryDatastructures(); this->allStates.clear(); this->stateToIndexMap.clear(); + uint_fast64_t choices; + std::map>> intermediate; for (uint_fast64_t curIndex = this->getOrAddStateId(this->buildInitialState()); curIndex < this->allStates.size(); curIndex++) { - std::list> choices; - this->addUnlabeledTransitions(this->allStates[curIndex], choices); - std::cout << "Output:" << std::endl; - for (auto it: choices) this->dump(it); + this->addUnlabeledTransitions(this->allStates[curIndex], intermediate[curIndex]); + + choices += intermediate[curIndex].size(); + if (intermediate[curIndex].size() == 0) { + // This is a deadlock state. + if (storm::settings::instance()->isSet("fix-deadlocks")) { + this->numberOfTransitions++; + intermediate[curIndex].emplace_back(); + intermediate[curIndex].back()[curIndex] = 1; + } else { + LOG4CPLUS_ERROR(logger, "Error while creating sparse matrix from probabilistic program: found deadlock state."); + throw storm::exceptions::WrongFileFormatException() << "Error while creating sparse matrix from probabilistic program: found deadlock state."; + } + } + } + + switch (this->program->getModelType()) { + case storm::ir::Program::DTMC: + case storm::ir::Program::CTMC: + return this->buildDTMCMatrix(intermediate); + case storm::ir::Program::MDP: + case storm::ir::Program::CTMDP: + return this->buildMDPMatrix(intermediate, choices); + default: + LOG4CPLUS_ERROR(logger, "Error while creating sparse matrix from probabilistic program: We can't handle this model type."); + throw storm::exceptions::WrongFileFormatException() << "Error while creating sparse matrix from probabilistic program: We can't handle this model type."; + break; } - std::cout << "got " << this->allStates.size() << " states" << std::endl; + return std::shared_ptr>(nullptr); } void computeReachableStateSpace() { From 17d57e742a7924cc994147cfc2ae1c8f211a6354 Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 11 Mar 2013 20:55:50 +0100 Subject: [PATCH 053/152] Added code for labeled transitions. New Adapter is basically finished, but not really tested ;-) --- src/adapters/ExplicitModelAdapter.h | 84 ++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 8 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 995bc296e..1cb8151ff 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -208,12 +209,8 @@ private: * @params state State to be expanded * @params res List of */ - void addUnlabeledTransitions(const StateType* state, std::list>& res) { - std::cout << "exploring ( "; - for (auto it : state->first) std::cout << it << ", "; - for (auto it : state->second) std::cout << it << ", "; - std::cout << ")" << std::endl; - + void addUnlabeledTransitions(const uint_fast64_t stateID, std::list>& res) { + const StateType* state = this->allStates[stateID]; // Iterate over all modules. for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { storm::ir::Module const& module = program->getModule(i); @@ -241,12 +238,69 @@ private: (*states)[newStateId] = update.getLikelihoodExpression()->getValueAsDouble(state); } else { (*states)[newStateId] += update.getLikelihoodExpression()->getValueAsDouble(state); - } + } } } } } + void addLabeledTransitions(const uint_fast64_t stateID, std::list>& res) { + // Create a copy of the current state, as we will free intermediate states... + StateType* state = new StateType(*this->allStates[stateID]); + for (std::string action : this->program->getActions()) { + std::unique_ptr>> cmds = this->getActiveCommandsByAction(state, action); + + // Start with current state + std::unordered_map resultStates; + resultStates[state] = 1.0; + + for (std::list module : *cmds) { + if (resultStates.size() == 0) break; + std::unordered_map newStates; + + // Iterate over all commands within this module. + for (storm::ir::Command command : module) { + // Iterate over all updates of this command. + for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { + storm::ir::Update const& update = command.getUpdate(k); + + // Iterate over all resultStates. + for (auto it : resultStates) { + // Apply the new update and get resulting state. + StateType* newState = this->applyUpdate(it.first, update); + // Insert the new state into newStates array. + // Take care of calculation of likelihood, combine identical states. + auto s = newStates.find(newState); + if (s == newStates.end()) { + newStates[newState] = it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); + } else { + newStates[newState] += it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); + } + } + } + } + for (auto it: resultStates) { + delete it.first; + } + // Move new states to resultStates. + resultStates.clear(); + resultStates.insert(newStates.begin(), newStates.end()); + + } + + res.emplace_back(); + std::map* states = &res.back(); + + // Now add our final result states to our global result. + for (auto it : resultStates) { + uint_fast64_t newStateID = this->getOrAddStateId(it.first); + (*states)[newStateID] = it.second; + } + this->numberOfTransitions += states->size(); + } + + } + void dump(std::map& obj) { std::cout << "Some map:" << std::endl; for (auto it: obj) { @@ -262,6 +316,16 @@ private: template std::shared_ptr> buildDTMCMatrix(std::map>> intermediate) { std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size())); + uint_fast64_t numberOfTransitions = 0; + for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { + std::set set; + for (auto choice : intermediate[state]) { + for (auto elem : choice) { + set.insert(elem.first); + } + } + numberOfTransitions += set.size(); + } result->initialize(numberOfTransitions); for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { //if (intermediate[state].size() > 1) WARNING; @@ -272,6 +336,7 @@ private: map[elem.first] += elem.second * factor; } } + std::cout << "adding " << map.size() << " elements" << std::endl; for (auto it : map) { result->addNextValue(state, it.first, it.second); } @@ -284,6 +349,7 @@ private: /*! * Create matrix from intermediate mapping, assuming it is a mdp model. * @param intermediate Intermediate representation of transition mapping. + * @param choices Overall number of choices for all nodes. * @return result matrix. */ template @@ -313,7 +379,8 @@ private: std::map>> intermediate; for (uint_fast64_t curIndex = this->getOrAddStateId(this->buildInitialState()); curIndex < this->allStates.size(); curIndex++) { - this->addUnlabeledTransitions(this->allStates[curIndex], intermediate[curIndex]); + this->addUnlabeledTransitions(curIndex, intermediate[curIndex]); + this->addLabeledTransitions(curIndex, intermediate[curIndex]); choices += intermediate[curIndex].size(); if (intermediate[curIndex].size() == 0) { @@ -329,6 +396,7 @@ private: } } + std::cout << "number of Transitions: " << this->numberOfTransitions << std::endl; switch (this->program->getModelType()) { case storm::ir::Program::DTMC: case storm::ir::Program::CTMC: From 018e7ce056ff6e1acee775aad7920d7ad1fa152a Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 12 Mar 2013 09:43:58 +0100 Subject: [PATCH 054/152] some minor fixes. Adapter now produces same result as prism for examples/dtmc/sync/sync.pm except order of nodes. --- src/adapters/ExplicitModelAdapter.h | 40 +++++++++++++++++------------ 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 1cb8151ff..23b4e0a5f 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -64,9 +64,9 @@ public: std::shared_ptr> toSparseMatrix() { LOG4CPLUS_INFO(logger, "Creating sparse matrix for probabilistic program."); - this->buildMatrix2(); - this->computeReachableStateSpace(); - std::shared_ptr> resultMatrix = this->buildMatrix(); + //this->buildMatrix2(); + //this->computeReachableStateSpace(); + std::shared_ptr> resultMatrix = this->buildMatrix2(); LOG4CPLUS_INFO(logger, "Created sparse matrix with " << resultMatrix->getRowCount() << " reachable states and " << resultMatrix->getNonZeroEntryCount() << " transitions."); @@ -236,6 +236,7 @@ private: auto stateIt = states->find(newStateId); if (stateIt == states->end()) { (*states)[newStateId] = update.getLikelihoodExpression()->getValueAsDouble(state); + this->numberOfTransitions++; } else { (*states)[newStateId] += update.getLikelihoodExpression()->getValueAsDouble(state); } @@ -288,15 +289,17 @@ private: } - res.emplace_back(); - std::map* states = &res.back(); + if (resultStates.size() > 0) { + res.emplace_back(); + std::map* states = &res.back(); - // Now add our final result states to our global result. - for (auto it : resultStates) { - uint_fast64_t newStateID = this->getOrAddStateId(it.first); - (*states)[newStateID] = it.second; + // Now add our final result states to our global result. + for (auto it : resultStates) { + uint_fast64_t newStateID = this->getOrAddStateId(it.first); + (*states)[newStateID] = it.second; + } + this->numberOfTransitions += states->size(); } - this->numberOfTransitions += states->size(); } } @@ -315,6 +318,7 @@ private: */ template std::shared_ptr> buildDTMCMatrix(std::map>> intermediate) { + std::cout << "Building DTMC matrix" << std::endl; std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size())); uint_fast64_t numberOfTransitions = 0; for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { @@ -326,19 +330,21 @@ private: } numberOfTransitions += set.size(); } + std::cout << "number of Transitions: " << numberOfTransitions << std::endl; result->initialize(numberOfTransitions); for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { - //if (intermediate[state].size() > 1) WARNING; - double factor = 1.0 / intermediate[state].size(); + if (intermediate[state].size() > 1) { + std::cout << "Warning: state " << state << " has " << intermediate[state].size() << " overlapping guards in dtmc" << std::endl; + } std::map map; for (auto choice : intermediate[state]) { for (auto elem : choice) { - map[elem.first] += elem.second * factor; + map[elem.first] += elem.second; } } - std::cout << "adding " << map.size() << " elements" << std::endl; + double factor = 1.0 / intermediate[state].size(); for (auto it : map) { - result->addNextValue(state, it.first, it.second); + result->addNextValue(state, it.first, it.second * factor); } } @@ -354,8 +360,9 @@ private: */ template std::shared_ptr> buildMDPMatrix(std::map>> intermediate, uint_fast64_t choices) { + std::cout << "Building MDP matrix" << std::endl; std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size(), choices)); - result->initialize(numberOfTransitions); + result->initialize(this->numberOfTransitions); uint_fast64_t nextRow = 0; for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { for (auto choice : intermediate[state]) { @@ -374,6 +381,7 @@ private: this->prepareAuxiliaryDatastructures(); this->allStates.clear(); this->stateToIndexMap.clear(); + this->numberOfTransitions = 0; uint_fast64_t choices; std::map>> intermediate; From 752dda42527913ecca1add007978e65dcd2c4256 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 12 Mar 2013 12:54:51 +0100 Subject: [PATCH 055/152] fixing error with difference operator in freeIdentifier --- src/parser/PrismParser.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 7b17e5588..e9bd368eb 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -56,9 +56,9 @@ struct PrismParser::PrismGrammar : qi::grammar> *(qi::alnum | qi::char_('_'))) - allConstantNames_ - keywords_]]; + identifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&PrismGrammar::isIdentifier, this, qi::_1) ]; identifierName.name("identifier"); - freeIdentifierName %= qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_'))) - booleanVariableNames_ - integerVariableNames_ - allConstantNames_ - labelNames_ - moduleNames_ - keywords_]]; + freeIdentifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&PrismGrammar::isFreeIdentifier, this, qi::_1) ]; freeIdentifierName.name("unused identifier"); // This block defines all literal expressions. @@ -254,14 +254,32 @@ struct PrismParser::PrismGrammar : qi::grammar identifierName > *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) > +commandDefinition > qi::lit("endmodule"))[phoenix::bind(moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2)]; - moduleDefinition.name("module"); } // The starting point of the grammar. From 772c03c070b4e927c508a8f95e126eb731bad47f Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 12 Mar 2013 13:32:05 +0100 Subject: [PATCH 056/152] Added routine to create all initial states. Variables that have no explicit initial value will cause initial state for all possible values. --- src/adapters/ExplicitModelAdapter.h | 64 ++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 23b4e0a5f..55bb839f9 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -178,6 +178,65 @@ private: return initialState; } + /*! + * Generates all initial states and adds them to allStates. + */ + void generateInitialStates() { + // Create a fresh state which can hold as many boolean and integer variables as there are. + std::vector states; + states.emplace_back(); + states.back()->first.resize(this->booleanVariables.size()); + states.back()->second.resize(this->integerVariables.size()); + + // Start with boolean variables. + for (uint_fast64_t i = 0; i < this->booleanVariables.size(); ++i) { + // Check if an initial value is given + if (this->booleanVariables[i].getInitialValue().get() == nullptr) { + // No initial value was given. + uint_fast64_t size = states.size(); + for (uint_fast64_t pos = 0; pos < size; pos++) { + // Duplicate each state, one with true and one with false. + states.emplace_back(states[pos]); + std::get<0>(*states[pos])[i] = false; + std::get<0>(*states[size + pos])[i] = true; + } + } else { + // Initial value was given. + bool initialValue = this->booleanVariables[i].getInitialValue()->getValueAsBool(states[0]); + for (auto it : states) { + std::get<0>(*it)[i] = initialValue; + } + } + } + // Now process integer variables. + for (uint_fast64_t i = 0; i < this->integerVariables.size(); ++i) { + // Check if an initial value was given. + if (this->integerVariables[i].getInitialValue().get() == nullptr) { + // No initial value was given. + uint_fast64_t size = states.size(); + int_fast64_t lower = this->integerVariables[i].getLowerBound()->getValueAsInt(states[0]); + int_fast64_t upper = this->integerVariables[i].getUpperBound()->getValueAsInt(states[0]); + + // Duplicate all states for all values in variable interval. + for (int_fast64_t value = lower; value <= upper; value++) { + for (uint_fast64_t pos = 0; pos < size; pos++) { + // If value is lower bound, we reuse the existing state, otherwise we create a new one. + if (value > lower) states.emplace_back(states[pos]); + // Set value to current state. + std::get<1>(*states[(value - lower) * size + pos])[i] = value; + } + } + } else { + // Initial value was given. + int_fast64_t initialValue = this->integerVariables[i].getInitialValue()->getValueAsInt(states[0]); + for (auto it : states) { + std::get<1>(*it)[i] = initialValue; + } + } + } + + } + /*! * Retrieves the state id of the given state. * If the state has not been hit yet, it will be added to allStates and given a new id. @@ -385,7 +444,8 @@ private: uint_fast64_t choices; std::map>> intermediate; - for (uint_fast64_t curIndex = this->getOrAddStateId(this->buildInitialState()); curIndex < this->allStates.size(); curIndex++) + this->generateInitialStates(); + for (uint_fast64_t curIndex = 0; curIndex < this->allStates.size(); curIndex++) { this->addUnlabeledTransitions(curIndex, intermediate[curIndex]); this->addLabeledTransitions(curIndex, intermediate[curIndex]); @@ -404,7 +464,7 @@ private: } } - std::cout << "number of Transitions: " << this->numberOfTransitions << std::endl; + switch (this->program->getModelType()) { case storm::ir::Program::DTMC: case storm::ir::Program::CTMC: From 52225ecf9c99c9834ccb4cf782ab1dc7943bc31b Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 12 Mar 2013 13:47:42 +0100 Subject: [PATCH 057/152] Fixes to buildInitialStates. --- src/adapters/ExplicitModelAdapter.h | 35 ++++++++++++++--------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 55bb839f9..ff04feb33 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -183,27 +183,27 @@ private: */ void generateInitialStates() { // Create a fresh state which can hold as many boolean and integer variables as there are. - std::vector states; - states.emplace_back(); - states.back()->first.resize(this->booleanVariables.size()); - states.back()->second.resize(this->integerVariables.size()); + this->allStates.clear(); + this->allStates.push_back(new StateType()); + this->allStates[0]->first.resize(this->booleanVariables.size()); + this->allStates[0]->second.resize(this->integerVariables.size()); // Start with boolean variables. for (uint_fast64_t i = 0; i < this->booleanVariables.size(); ++i) { // Check if an initial value is given if (this->booleanVariables[i].getInitialValue().get() == nullptr) { // No initial value was given. - uint_fast64_t size = states.size(); + uint_fast64_t size = this->allStates.size(); for (uint_fast64_t pos = 0; pos < size; pos++) { // Duplicate each state, one with true and one with false. - states.emplace_back(states[pos]); - std::get<0>(*states[pos])[i] = false; - std::get<0>(*states[size + pos])[i] = true; + this->allStates.push_back(new StateType(*this->allStates[pos])); + std::get<0>(*this->allStates[pos])[i] = false; + std::get<0>(*this->allStates[size + pos])[i] = true; } } else { // Initial value was given. - bool initialValue = this->booleanVariables[i].getInitialValue()->getValueAsBool(states[0]); - for (auto it : states) { + bool initialValue = this->booleanVariables[i].getInitialValue()->getValueAsBool(this->allStates[0]); + for (auto it : this->allStates) { std::get<0>(*it)[i] = initialValue; } } @@ -213,28 +213,27 @@ private: // Check if an initial value was given. if (this->integerVariables[i].getInitialValue().get() == nullptr) { // No initial value was given. - uint_fast64_t size = states.size(); - int_fast64_t lower = this->integerVariables[i].getLowerBound()->getValueAsInt(states[0]); - int_fast64_t upper = this->integerVariables[i].getUpperBound()->getValueAsInt(states[0]); + uint_fast64_t size = this->allStates.size(); + int_fast64_t lower = this->integerVariables[i].getLowerBound()->getValueAsInt(this->allStates[0]); + int_fast64_t upper = this->integerVariables[i].getUpperBound()->getValueAsInt(this->allStates[0]); // Duplicate all states for all values in variable interval. for (int_fast64_t value = lower; value <= upper; value++) { for (uint_fast64_t pos = 0; pos < size; pos++) { // If value is lower bound, we reuse the existing state, otherwise we create a new one. - if (value > lower) states.emplace_back(states[pos]); + if (value > lower) this->allStates.push_back(new StateType(*this->allStates[pos])); // Set value to current state. - std::get<1>(*states[(value - lower) * size + pos])[i] = value; + std::get<1>(*this->allStates[(value - lower) * size + pos])[i] = value; } } } else { // Initial value was given. - int_fast64_t initialValue = this->integerVariables[i].getInitialValue()->getValueAsInt(states[0]); - for (auto it : states) { + int_fast64_t initialValue = this->integerVariables[i].getInitialValue()->getValueAsInt(this->allStates[0]); + for (auto it : this->allStates) { std::get<1>(*it)[i] = initialValue; } } } - } /*! From e711d16ebfbe7fe191f6a79d7578a6c533678028 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 12 Mar 2013 13:48:12 +0100 Subject: [PATCH 058/152] Changed default initial value for BooleanVariable. Was false (suggesting that no initial value would be equivalent to specifying false), is nullptr now. --- src/ir/BooleanVariable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ir/BooleanVariable.h b/src/ir/BooleanVariable.h index e12506b67..9c5ba17c0 100644 --- a/src/ir/BooleanVariable.h +++ b/src/ir/BooleanVariable.h @@ -33,7 +33,7 @@ public: * @param variableName the name of the variable. * @param initialValue the expression that defines the initial value of the variable. */ - BooleanVariable(uint_fast64_t index, std::string variableName, std::shared_ptr initialValue = std::shared_ptr(new storm::ir::expressions::BooleanLiteral(false))); + BooleanVariable(uint_fast64_t index, std::string variableName, std::shared_ptr initialValue = std::shared_ptr(nullptr)); /*! * Retrieves a string representation of this variable. From dfd601e126b7e8f54162620cdf7c7999f6bd56b0 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 12 Mar 2013 14:01:40 +0100 Subject: [PATCH 059/152] fixed memory leak in addLabeledTransition and removed now obsolete functions. --- src/adapters/ExplicitModelAdapter.h | 348 +--------------------------- 1 file changed, 4 insertions(+), 344 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index ff04feb33..c0a52cd94 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -64,9 +64,7 @@ public: std::shared_ptr> toSparseMatrix() { LOG4CPLUS_INFO(logger, "Creating sparse matrix for probabilistic program."); - //this->buildMatrix2(); - //this->computeReachableStateSpace(); - std::shared_ptr> resultMatrix = this->buildMatrix2(); + std::shared_ptr> resultMatrix = this->buildMatrix(); LOG4CPLUS_INFO(logger, "Created sparse matrix with " << resultMatrix->getRowCount() << " reachable states and " << resultMatrix->getNonZeroEntryCount() << " transitions."); @@ -155,29 +153,6 @@ private: return newState; } - /*! - * Create a new state and initialize with initial values. - * @return Pointer to initial state. - */ - StateType* buildInitialState() { - // Create a fresh state which can hold as many boolean and integer variables as there are. - StateType* initialState = new StateType(); - initialState->first.resize(this->booleanVariables.size()); - initialState->second.resize(this->integerVariables.size()); - - // Now initialize all fields in the value vectors of the state according to the initial - // values provided by the input program. - for (uint_fast64_t i = 0; i < this->booleanVariables.size(); ++i) { - bool initialValue = this->booleanVariables[i].getInitialValue()->getValueAsBool(initialState); - std::get<0>(*initialState)[i] = initialValue; - } - for (uint_fast64_t i = 0; i < this->integerVariables.size(); ++i) { - int_fast64_t initialValue = this->integerVariables[i].getInitialValue()->getValueAsInt(initialState); - std::get<1>(*initialState)[i] = initialValue; - } - return initialState; - } - /*! * Generates all initial states and adds them to allStates. */ @@ -305,8 +280,8 @@ private: void addLabeledTransitions(const uint_fast64_t stateID, std::list>& res) { // Create a copy of the current state, as we will free intermediate states... - StateType* state = new StateType(*this->allStates[stateID]); for (std::string action : this->program->getActions()) { + StateType* state = new StateType(*this->allStates[stateID]); std::unique_ptr>> cmds = this->getActiveCommandsByAction(state, action); // Start with current state @@ -435,14 +410,14 @@ private: } template - std::shared_ptr> buildMatrix2() { + std::shared_ptr> buildMatrix() { this->prepareAuxiliaryDatastructures(); this->allStates.clear(); this->stateToIndexMap.clear(); this->numberOfTransitions = 0; uint_fast64_t choices; - std::map>> intermediate; + this->generateInitialStates(); for (uint_fast64_t curIndex = 0; curIndex < this->allStates.size(); curIndex++) { @@ -479,321 +454,6 @@ private: return std::shared_ptr>(nullptr); } - void computeReachableStateSpace() { - // Prepare some internal data structures, such as mappings from variables to indices and so on. - this->prepareAuxiliaryDatastructures(); - // Build initial state. - StateType* initialState = this->buildInitialState(); - - // Now set up the environment for a breadth-first search starting from the initial state. - uint_fast64_t nextIndex = 1; - this->allStates.clear(); - this->stateToIndexMap.clear(); - std::queue stateQueue; - - this->allStates.push_back(initialState); - stateQueue.push(initialState); - this->stateToIndexMap[initialState] = 0; - - this->numberOfTransitions = 0; - while (!stateQueue.empty()) { - // Get first state in queue. - StateType* currentState = stateQueue.front(); - stateQueue.pop(); - - // Remember whether the state has at least one transition such that transitions can be - // inserted upon detection of a deadlock state. - bool hasTransition = false; - - // First expand all transitions for commands labelled with some - // action. For every module, we determine all commands with this - // action whose guard holds. Then, we add a transition for each - // combination of all updates of those commands. - for (std::string action : this->program->getActions()) { - // Get list of all commands. - // This list contains a list for every module that has commands labelled by action. - // Each such list contains all commands whose guards are fulfilled. - // If no guard is fulfilled (i.e. there is no way to perform this action), the list will be empty! - std::unique_ptr>> cmds = this->getActiveCommandsByAction(currentState, action); - - // Start with current state. - std::unordered_map resultStates; - resultStates[currentState] = 1; - std::queue deleteQueue; - - // Iterate over all modules (represented by the list of commands with the current action). - // We will now combine every state in resultStates with every additional update in the next module. - // The final result will be this map after we are done with all modules. - for (std::list module : *cmds) { - // If no states are left, we are done. - // This happens, if there is a module where commands existed, but no guard was fulfilled. - if (resultStates.size() == 0) break; - // Put all new states in this new map. - std::unordered_map newStates; - - // Iterate over all commands within this module. - for (storm::ir::Command command : module) { - // Iterate over all updates of this command. - for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { - storm::ir::Update const& update = command.getUpdate(k); - - // Iterate over all resultStates. - for (auto it : resultStates) { - // Apply the new update and get resulting state. - StateType* newState = this->applyUpdate(it.first, update); - // Insert the new state into newStates array. - // Take care of calculation of likelihood, combine identical states. - auto s = newStates.find(newState); - if (s == newStates.end()) { - newStates[newState] = it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); - } else { - newStates[newState] += it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); - } - // No matter what happened, we must delete the states of the previous iteration. - deleteQueue.push(it.first); - } - } - } - // Move new states to resultStates. - resultStates.clear(); - resultStates.insert(newStates.begin(), newStates.end()); - // Delete old result states. - while (!deleteQueue.empty()) { - if (deleteQueue.front() != currentState) { - delete deleteQueue.front(); - } - deleteQueue.pop(); - } - } - // Now add our final result states to our global result. - for (auto it : resultStates) { - hasTransition = true; - auto s = stateToIndexMap.find(it.first); - if (s == stateToIndexMap.end()) { - stateQueue.push(it.first); - // Add state to list of all reachable states. - allStates.push_back(it.first); - // Give a unique index to the newly found state. - stateToIndexMap[it.first] = nextIndex; - ++nextIndex; - } else { - deleteQueue.push(it.first); - } - } - // Delete states we already had. - while (!deleteQueue.empty()) { - delete deleteQueue.front(); - deleteQueue.pop(); - } - this->numberOfTransitions += resultStates.size(); - } - - - // Now, expand all transitions for commands not labelled with - // some action. Those commands each build a transition for - // themselves. - // Iterate over all modules. - for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { - storm::ir::Module const& module = program->getModule(i); - - // Iterate over all commands. - for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { - storm::ir::Command const& command = module.getCommand(j); - if (command.getActionName() != "") continue; - - // Check if this command is enabled in the current state. - if (command.getGuard()->getValueAsBool(currentState)) { - hasTransition = true; - - // Remember what states are targeted by an update of the current command - // in order to be able to sum those probabilities and not increase the - // transition count. - std::unordered_map stateToProbabilityMap; - - // Keep a queue of states to delete after the current command. When one - // command is processed and states are encountered which were already found - // before, we can only delete them after the command has been processed, - // because the stateToProbabilityMap will contain illegal values otherwise. - std::queue statesToDelete; - - // Now iterate over all updates to see where the updates take the current - // state. - for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { - storm::ir::Update const& update = command.getUpdate(k); - - // Now copy the current state and only overwrite the entries in the - // vectors if there is an assignment to that variable in the current - // update. - StateType* newState = this->applyUpdate(currentState, update); - - // If we have already found the target state of the update, we must not - // increase the transition count. - auto probIt = stateToProbabilityMap.find(newState); - if (probIt != stateToProbabilityMap.end()) { - stateToProbabilityMap[newState] += update.getLikelihoodExpression()->getValueAsDouble(currentState); - } else { - ++numberOfTransitions; - stateToProbabilityMap[newState] = update.getLikelihoodExpression()->getValueAsDouble(currentState); - } - - // Depending on whether the state was found previously, we mark it for - // deletion or add it to the reachable state space and mark it for - // further exploration. - auto it = stateToIndexMap.find(newState); - if (it != stateToIndexMap.end()) { - // Queue the state object for deletion as we have already seen that - // state. - statesToDelete.push(newState); - } else { - // Add state to the queue of states that are still to be explored. - stateQueue.push(newState); - - // Add state to list of all reachable states. - allStates.push_back(newState); - - // Give a unique index to the newly found state. - stateToIndexMap[newState] = nextIndex; - ++nextIndex; - } - } - - // Now delete all states queued for deletion. - while (!statesToDelete.empty()) { - delete statesToDelete.front(); - statesToDelete.pop(); - } - } - } - } - - // If the state is a deadlock state, and the corresponding flag is set, we tolerate that - // and increase the number of transitions by one, because a self-loop is going to be - // inserted in the next step. If the flag is not set, an exception is thrown. - if (!hasTransition) { - if (storm::settings::instance()->isSet("fix-deadlocks")) { - ++numberOfTransitions; - } else { - LOG4CPLUS_ERROR(logger, "Error while creating sparse matrix from probabilistic program: found deadlock state."); - throw storm::exceptions::WrongFileFormatException() << "Error while creating sparse matrix from probabilistic program: found deadlock state."; - } - } - } - } - - template - std::shared_ptr> buildMatrix() { - std::shared_ptr> resultMatrix(new storm::storage::SparseMatrix(allStates.size())); - resultMatrix->initialize(numberOfTransitions); - - // Keep track of the running index to insert values into correct matrix row. - uint_fast64_t currentIndex = 0; - - // Determine the matrix content for every row (i.e. reachable state). - for (StateType* currentState : allStates) { - bool hasTransition = false; - - std::map stateIndexToProbabilityMap; - - for (std::string action : this->program->getActions()) { - std::unique_ptr>> cmds = this->getActiveCommandsByAction(currentState, action); - std::unordered_map resultStates; - resultStates[currentState] = 1; - std::queue deleteQueue; - - for (std::list module : *cmds) { - std::unordered_map newStates; - for (storm::ir::Command command : module) { - for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { - storm::ir::Update const& update = command.getUpdate(k); - for (auto it : resultStates) { - StateType* newState = this->applyUpdate(it.first, update); - auto s = newStates.find(newState); - if (s == newStates.end()) { - newStates[newState] = it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); - } else { - newStates[newState] += it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); - } - deleteQueue.push(it.first); - } - } - } - resultStates.clear(); - resultStates.insert(newStates.begin(), newStates.end()); - while (!deleteQueue.empty()) { - if (deleteQueue.front() != currentState) { - delete deleteQueue.front(); - } - deleteQueue.pop(); - } - } - for (auto it : resultStates) { - hasTransition = true; - uint_fast64_t targetIndex = stateToIndexMap[it.first]; - auto s = stateIndexToProbabilityMap.find(targetIndex); - if (s == stateIndexToProbabilityMap.end()) { - stateIndexToProbabilityMap[targetIndex] = it.second; - } else { - stateIndexToProbabilityMap[targetIndex] += it.second; - } - delete it.first; - } - } - for (auto targetIndex : stateIndexToProbabilityMap) { - resultMatrix->addNextValue(currentIndex, targetIndex.first, targetIndex.second); - } - - // Iterate over all modules. - for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { - storm::ir::Module const& module = program->getModule(i); - - // Iterate over all commands. - for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { - storm::ir::Command const& command = module.getCommand(j); - if (command.getActionName() != "") continue; - - // Check if this command is enabled in the current state. - if (command.getGuard()->getValueAsBool(currentState)) { - hasTransition = true; - std::map stateIndexToProbabilityMap; - for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { - storm::ir::Update const& update = command.getUpdate(k); - - StateType* newState = this->applyUpdate(currentState, update); - - uint_fast64_t targetIndex = (*stateToIndexMap.find(newState)).second; - delete newState; - - auto probIt = stateIndexToProbabilityMap.find(targetIndex); - if (probIt != stateIndexToProbabilityMap.end()) { - stateIndexToProbabilityMap[targetIndex] += update.getLikelihoodExpression()->getValueAsDouble(currentState); - } else { - stateIndexToProbabilityMap[targetIndex] = update.getLikelihoodExpression()->getValueAsDouble(currentState); - } - } - - // Now insert the actual values into the matrix. - for (auto targetIndex : stateIndexToProbabilityMap) { - resultMatrix->addNextValue(currentIndex, targetIndex.first, targetIndex.second); - } - } - } - } - - // If the state is a deadlock state, a self-loop is inserted. Note that we do not have - // to check whether --fix-deadlocks is set, because if this was not the case an - // exception would have been thrown earlier. - if (!hasTransition) { - resultMatrix->addNextValue(currentIndex, currentIndex, 1); - } - - ++currentIndex; - } - - // Finalize matrix and return it. - resultMatrix->finalize(); - return resultMatrix; - } - void clearReachableStateSpace() { for (auto it : allStates) { delete it; From 84993d24f8b6c8d3b317a0722b3afe10a10b22af Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 12 Mar 2013 15:08:37 +0100 Subject: [PATCH 060/152] Add documentation for ExplicitModelAdapter. --- src/adapters/ExplicitModelAdapter.h | 58 +++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index c0a52cd94..4a5cec58c 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -81,7 +81,10 @@ private: static void setValue(StateType* state, uint_fast64_t index, int_fast64_t value) { std::get<1>(*state)[index] = value; } - + + /*! + * Initializes all internal variables. + */ void prepareAuxiliaryDatastructures() { uint_fast64_t numberOfIntegerVariables = 0; uint_fast64_t numberOfBooleanVariables = 0; @@ -111,6 +114,19 @@ private: } } + /*! + * Retrieves all active command labeled by some label, ordered by modules. + * + * This function will iterate over all modules and retrieve all commands that are labeled with the given action and active for the current state. + * The result will be a list of lists of commands. + * + * For each module that has appropriately labeled commands, there will be a list. + * If none of these commands is active, this list is empty. + * Note the difference between *no list* and *empty list*: Modules that produce no list are not relevant for this action while an empty list means, that it is not possible to do anything with this label. + * @param state Current state. + * @param action Action label. + * @return Active commands. + */ std::unique_ptr>> getActiveCommandsByAction(StateType const * state, std::string& action) { std::unique_ptr>> res = std::unique_ptr>>(new std::list>()); @@ -237,10 +253,8 @@ private: /*! * Expands all unlabeled transitions for a given state and adds them to the given list of results. - * There will be an additional map for each Command that is active. - * Each such map will contain a probability distribution over the reachable states using this Command. - * @params state State to be expanded - * @params res List of + * @params state State to be explored. + * @params res Intermediate transition map. */ void addUnlabeledTransitions(const uint_fast64_t stateID, std::list>& res) { const StateType* state = this->allStates[stateID]; @@ -278,6 +292,12 @@ private: } } + /*! + * Explores reachable state from given state by using labeled transitions. + * Found transitions are stored in given map. + * @param stateID State to be explored. + * @param res Intermediate transition map. + */ void addLabeledTransitions(const uint_fast64_t stateID, std::list>& res) { // Create a copy of the current state, as we will free intermediate states... for (std::string action : this->program->getActions()) { @@ -337,13 +357,6 @@ private: } - void dump(std::map& obj) { - std::cout << "Some map:" << std::endl; - for (auto it: obj) { - std::cout << "\t" << it.first << ": " << it.second << std::endl; - } - } - /*! * Create matrix from intermediate mapping, assuming it is a dtmc model. * @param intermediate Intermediate representation of transition mapping. @@ -351,10 +364,12 @@ private: */ template std::shared_ptr> buildDTMCMatrix(std::map>> intermediate) { - std::cout << "Building DTMC matrix" << std::endl; std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size())); + // this->numberOfTransitions is meaningless, as we combine all choices into one for each state. + // Hence, we compute the correct number of transitions now. uint_fast64_t numberOfTransitions = 0; for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { + // Collect all target nodes in a set to get number of distinct nodes. std::set set; for (auto choice : intermediate[state]) { for (auto elem : choice) { @@ -363,18 +378,21 @@ private: } numberOfTransitions += set.size(); } - std::cout << "number of Transitions: " << numberOfTransitions << std::endl; + std::cout << "Building DTMC matrix with " << numberOfTransitions << " transitions." << std::endl; + // Now build matrix. result->initialize(numberOfTransitions); for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { if (intermediate[state].size() > 1) { std::cout << "Warning: state " << state << " has " << intermediate[state].size() << " overlapping guards in dtmc" << std::endl; } + // Combine choices to one map. std::map map; for (auto choice : intermediate[state]) { for (auto elem : choice) { map[elem.first] += elem.second; } } + // Scale probabilities by number of choices. double factor = 1.0 / intermediate[state].size(); for (auto it : map) { result->addNextValue(state, it.first, it.second * factor); @@ -393,8 +411,9 @@ private: */ template std::shared_ptr> buildMDPMatrix(std::map>> intermediate, uint_fast64_t choices) { - std::cout << "Building MDP matrix" << std::endl; + std::cout << "Building MDP matrix with " << this->numberOfTransitions << " transitions." << std::endl; std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size(), choices)); + // Build matrix. result->initialize(this->numberOfTransitions); uint_fast64_t nextRow = 0; for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { @@ -409,6 +428,12 @@ private: return result; } + /*! + * Build matrix from model. Starts with all initial states and explores the reachable state space. + * While exploring, the transitions are stored in a temporary map. + * Afterwards, we transform this map into the actual matrix. + * @return result matrix. + */ template std::shared_ptr> buildMatrix() { this->prepareAuxiliaryDatastructures(); @@ -454,6 +479,9 @@ private: return std::shared_ptr>(nullptr); } + /*! + * Free all StateType objects and clear maps. + */ void clearReachableStateSpace() { for (auto it : allStates) { delete it; From 2005eb7e73e3a78131126eb452d6743a529ec4d6 Mon Sep 17 00:00:00 2001 From: gereon Date: Thu, 14 Mar 2013 20:20:16 +0100 Subject: [PATCH 061/152] Added getter routines, so we can retrieve the reward models --- src/ir/Program.cpp | 12 ++++++++++++ src/ir/Program.h | 13 +++++++++++++ src/ir/RewardModel.cpp | 8 ++++++++ src/ir/RewardModel.h | 12 ++++++++++++ src/ir/StateReward.cpp | 7 +++++++ src/ir/StateReward.h | 8 ++++++++ src/ir/TransitionReward.cpp | 8 ++++++++ src/ir/TransitionReward.h | 6 ++++++ 8 files changed, 74 insertions(+) diff --git a/src/ir/Program.cpp b/src/ir/Program.cpp index 7a11f31d2..691951f48 100644 --- a/src/ir/Program.cpp +++ b/src/ir/Program.cpp @@ -98,6 +98,18 @@ std::shared_ptr> const Program::getModulesByAction(std:: } } +storm::ir::RewardModel Program::getRewardModel(std::string const & name) const { + auto it = this->rewards.find(name); + if (it == this->rewards.end()) { + // throw some exception here... + } else { + return it->second; + } +} + +std::map> Program::getLabels() const { + return this->labels; +} } // namespace ir diff --git a/src/ir/Program.h b/src/ir/Program.h index 3ce3f3af9..b6daecdd7 100644 --- a/src/ir/Program.h +++ b/src/ir/Program.h @@ -93,6 +93,19 @@ public: */ std::shared_ptr> const getModulesByAction(std::string const& action) const; + /*! + * Retrieve reward model with given name. + * @param name Name of the reward model. + * @return Reward model with given name. + */ + storm::ir::RewardModel getRewardModel(std::string const & name) const; + + /*! + * Retrieves all labels. + * @return All labels. + */ + std::map> getLabels() const; + private: // The type of the model. ModelType modelType; diff --git a/src/ir/RewardModel.cpp b/src/ir/RewardModel.cpp index d8549db6e..bd3ce1e16 100644 --- a/src/ir/RewardModel.cpp +++ b/src/ir/RewardModel.cpp @@ -37,6 +37,14 @@ std::string RewardModel::toString() const { return result.str(); } +std::vector RewardModel::getStateRewards() const { + return this->stateRewards; +} + +std::vector RewardModel::getTransitionRewards() const { + return this->transitionRewards; +} + } // namespace ir } // namespace storm diff --git a/src/ir/RewardModel.h b/src/ir/RewardModel.h index fcf8dcf01..5cd7f2767 100644 --- a/src/ir/RewardModel.h +++ b/src/ir/RewardModel.h @@ -42,6 +42,18 @@ public: */ std::string toString() const; + /*! + * Retrieve state rewards. + * @return State rewards. + */ + std::vector getStateRewards() const; + + /*! + * Retrieve transition rewards. + * @return Transition rewards. + */ + std::vector getTransitionRewards() const; + private: // The name of the reward model. std::string rewardModelName; diff --git a/src/ir/StateReward.cpp b/src/ir/StateReward.cpp index 28ed4b72f..93bf738db 100644 --- a/src/ir/StateReward.cpp +++ b/src/ir/StateReward.cpp @@ -30,6 +30,13 @@ std::string StateReward::toString() const { return result.str(); } +double StateReward::getReward(std::pair, std::vector> const * state) const { + if (this->statePredicate->getValueAsBool(state)) { + return this->rewardValue->getValueAsDouble(state); + } + return 0; +} + } // namespace ir } // namespace storm diff --git a/src/ir/StateReward.h b/src/ir/StateReward.h index 0a127fd0c..638b42ed7 100644 --- a/src/ir/StateReward.h +++ b/src/ir/StateReward.h @@ -42,6 +42,14 @@ public: */ std::string toString() const; + /*! + * Returns the reward for the given state. + * It the state fulfills the predicate, the reward value is returned, zero otherwise. + * @param state State object. + * @return Reward for given state. + */ + double getReward(std::pair, std::vector> const * state) const; + private: // The predicate that characterizes the states that obtain this reward. std::shared_ptr statePredicate; diff --git a/src/ir/TransitionReward.cpp b/src/ir/TransitionReward.cpp index 6052f8b37..680df77e6 100644 --- a/src/ir/TransitionReward.cpp +++ b/src/ir/TransitionReward.cpp @@ -30,6 +30,14 @@ std::string TransitionReward::toString() const { return result.str(); } +double TransitionReward::getReward(std::string const & label, std::pair, std::vector> const * state) const { + if (this->commandName != label) return 0; + if (this->statePredicate->getValueAsBool(state)) { + return this->rewardValue->getValueAsDouble(state); + } + return 0; +} + } // namespace ir } // namespace storm diff --git a/src/ir/TransitionReward.h b/src/ir/TransitionReward.h index 07e0084e0..89480109a 100644 --- a/src/ir/TransitionReward.h +++ b/src/ir/TransitionReward.h @@ -43,6 +43,12 @@ public: */ std::string toString() const; + /*! + * Retrieves reward for given transition. + * Returns reward value if source state fulfills predicate and the transition is labeled correctly, zero otherwise. + */ + double getReward(std::string const & label, std::pair, std::vector> const * state) const; + private: // The name of the command this transition-based reward is attached to. std::string commandName; From 5976c9e81d68342ec032da622e982a1c986258b2 Mon Sep 17 00:00:00 2001 From: gereon Date: Thu, 14 Mar 2013 20:21:11 +0100 Subject: [PATCH 062/152] More work for ExplicitModelAdapter * Removed templates from various functions, as we can only produce double models anyway. * Added methods to compute state rewards and state labelings * Added toModel() routine --- src/adapters/ExplicitModelAdapter.h | 100 ++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 14 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 4a5cec58c..8b8e5dee3 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -11,6 +11,15 @@ #include "src/storage/SparseMatrix.h" #include "src/utility/Settings.h" +#include "src/ir/RewardModel.h" +#include "src/ir/StateReward.h" +#include "src/ir/TransitionReward.h" + +#include "src/models/AbstractModel.h" +#include "src/models/Dtmc.h" +#include "src/models/Ctmc.h" +#include "src/models/Mdp.h" + #include #include #include @@ -25,6 +34,7 @@ typedef std::pair, std::vector> StateType; #include "log4cplus/logger.h" #include "log4cplus/loggingmacros.h" +#include "ir/Program.h" extern log4cplus::Logger logger; namespace storm { @@ -60,11 +70,51 @@ public: } - template - std::shared_ptr> toSparseMatrix() { + std::shared_ptr toModel(std::string const & rewardModelName = "") { + + std::shared_ptr> matrix = this->toSparseMatrix(); + + std::shared_ptr stateLabeling = this->getStateLabeling(this->program->getLabels()); + std::shared_ptr> stateRewards = nullptr; + std::shared_ptr> transitionRewardMatrix = nullptr; + + if (rewardModelName != "") { + storm::ir::RewardModel rewardModel = this->program->getRewardModel(rewardModelName); + stateRewards = this->getStateRewards(rewardModel.getStateRewards()); + } + + switch (this->program->getModelType()) + { +/* std::shared_ptr> probabilityMatrix, + std::shared_ptr stateLabeling, + std::shared_ptr> stateRewards = nullptr, + std::shared_ptr> transitionRewardMatrix = nullptr +*/ + case storm::ir::Program::DTMC: + return std::shared_ptr(new storm::models::Dtmc(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); + break; + case storm::ir::Program::CTMC: + return std::shared_ptr(new storm::models::Ctmc(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); + break; + case storm::ir::Program::MDP: + return std::shared_ptr(new storm::models::Mdp(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); + break; + case storm::ir::Program::CTMDP: + // Todo + //return std::shared_ptr(new storm::models::Ctmdp(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); + break; + default: + // ERROR + break; + } + + return std::shared_ptr(nullptr); + } + + std::shared_ptr> toSparseMatrix() { LOG4CPLUS_INFO(logger, "Creating sparse matrix for probabilistic program."); - std::shared_ptr> resultMatrix = this->buildMatrix(); + std::shared_ptr> resultMatrix = this->buildMatrix(); LOG4CPLUS_INFO(logger, "Created sparse matrix with " << resultMatrix->getRowCount() << " reachable states and " << resultMatrix->getNonZeroEntryCount() << " transitions."); @@ -81,6 +131,31 @@ private: static void setValue(StateType* state, uint_fast64_t index, int_fast64_t value) { std::get<1>(*state)[index] = value; } + + std::shared_ptr> getStateRewards(std::vector const & rewards) { + std::shared_ptr> results(new std::vector(this->allStates.size())); + for (uint_fast64_t index = 0; index < this->allStates.size(); index++) { + for (auto reward: rewards) { + (*results)[index] = reward.getReward(this->allStates[index]); + } + } + return results; + } + + std::shared_ptr getStateLabeling(std::map> labels) { + std::shared_ptr results(new storm::models::AtomicPropositionsLabeling(this->allStates.size(), labels.size())); + for (auto it: labels) { + results->addAtomicProposition(it.first); + } + for (uint_fast64_t index = 0; index < this->allStates.size(); index++) { + for (auto label: labels) { + if (label.second->getValueAsBool(this->allStates[index])) { + results->addAtomicPropositionToState(label.first, index); + } + } + } + return results; + } /*! * Initializes all internal variables. @@ -362,9 +437,8 @@ private: * @param intermediate Intermediate representation of transition mapping. * @return result matrix. */ - template - std::shared_ptr> buildDTMCMatrix(std::map>> intermediate) { - std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size())); + std::shared_ptr> buildDTMCMatrix(std::map>> intermediate) { + std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size())); // this->numberOfTransitions is meaningless, as we combine all choices into one for each state. // Hence, we compute the correct number of transitions now. uint_fast64_t numberOfTransitions = 0; @@ -409,10 +483,9 @@ private: * @param choices Overall number of choices for all nodes. * @return result matrix. */ - template - std::shared_ptr> buildMDPMatrix(std::map>> intermediate, uint_fast64_t choices) { + std::shared_ptr> buildMDPMatrix(std::map>> intermediate, uint_fast64_t choices) { std::cout << "Building MDP matrix with " << this->numberOfTransitions << " transitions." << std::endl; - std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size(), choices)); + std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size(), choices)); // Build matrix. result->initialize(this->numberOfTransitions); uint_fast64_t nextRow = 0; @@ -434,8 +507,7 @@ private: * Afterwards, we transform this map into the actual matrix. * @return result matrix. */ - template - std::shared_ptr> buildMatrix() { + std::shared_ptr> buildMatrix() { this->prepareAuxiliaryDatastructures(); this->allStates.clear(); this->stateToIndexMap.clear(); @@ -467,16 +539,16 @@ private: switch (this->program->getModelType()) { case storm::ir::Program::DTMC: case storm::ir::Program::CTMC: - return this->buildDTMCMatrix(intermediate); + return this->buildDTMCMatrix(intermediate); case storm::ir::Program::MDP: case storm::ir::Program::CTMDP: - return this->buildMDPMatrix(intermediate, choices); + return this->buildMDPMatrix(intermediate, choices); default: LOG4CPLUS_ERROR(logger, "Error while creating sparse matrix from probabilistic program: We can't handle this model type."); throw storm::exceptions::WrongFileFormatException() << "Error while creating sparse matrix from probabilistic program: We can't handle this model type."; break; } - return std::shared_ptr>(nullptr); + return std::shared_ptr>(nullptr); } /*! From fd30e8ca25b7060f339928dc62d661c3aeab0d00 Mon Sep 17 00:00:00 2001 From: gereon Date: Fri, 15 Mar 2013 12:52:20 +0100 Subject: [PATCH 063/152] Cleaned up handling of --verbose, proposing correct use of log levels from now on... FATAL_LOG_LEVEL: Use, if we are going to crash. ERROR_LOG_LEVEL: Use, if there is no reasonable way to continue. WARN_LOG_LEVEL: Use, if we got something the average user should read. INFO_LOG_LEVEL: Use, if this might in some cases be of interest. DEBUG_LOG_LEVEL: Use, if this should usually not be relevant to a user. TRACE_LOG_LEVEL: Use only during development. There are three levels of verbosity: - default: WARN and above - verbose: INFO and above - debug: DEBUG and above --- src/storm.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/storm.cpp b/src/storm.cpp index 55819560b..2fc723034 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -48,7 +48,7 @@ log4cplus::Logger logger; */ void initializeLogger() { logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main")); - logger.setLogLevel(log4cplus::INFO_LOG_LEVEL); + logger.setLogLevel(log4cplus::WARN_LOG_LEVEL); log4cplus::SharedAppenderPtr consoleLogAppender(new log4cplus::ConsoleAppender()); consoleLogAppender->setName("mainConsoleAppender"); consoleLogAppender->setLayout(std::auto_ptr(new log4cplus::PatternLayout("%-5p - %D{%H:%M:%S} (%r ms) - %b:%L: %m%n"))); @@ -115,18 +115,17 @@ bool parseOptions(const int argc, const char* argv[]) { return false; } - if (!s->isSet("verbose") && !s->isSet("logfile")) { - logger.setLogLevel(log4cplus::FATAL_LOG_LEVEL); - } else if (!s->isSet("verbose")) { - logger.removeAppender("mainConsoleAppender"); - setUpFileLogging(); - } else if (!s->isSet("logfile")) { + if (s->isSet("verbose")) { + logger.setLogLevel(log4cplus::INFO_LOG_LEVEL); LOG4CPLUS_INFO(logger, "Enable verbose mode, log output gets printed to console."); - } else { + } + if (s->isSet("debug")) { + logger.setLogLevel(log4cplus::DEBUG_LOG_LEVEL); + LOG4CPLUS_INFO(logger, "Enable very verbose mode, log output gets printed to console."); + } + if (s->isSet("logfile")) { setUpFileLogging(); - LOG4CPLUS_INFO(logger, "Enable verbose mode, log output gets printed to console."); } - return true; } From f52d4eb7a8314fd8f5466116accfe6a8376cc507 Mon Sep 17 00:00:00 2001 From: gereon Date: Fri, 15 Mar 2013 13:02:53 +0100 Subject: [PATCH 064/152] Added new option --debug. --- src/utility/Settings.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utility/Settings.cpp b/src/utility/Settings.cpp index 26f733071..d6e2f5bc3 100644 --- a/src/utility/Settings.cpp +++ b/src/utility/Settings.cpp @@ -131,6 +131,7 @@ void Settings::initDescriptions() { Settings::desc->add_options() ("help,h", "produce help message") ("verbose,v", "be verbose") + ("debug", "be very verbose, intended for debugging") ("logfile,l", bpo::value(), "name of the log file") ("configfile,c", bpo::value(), "name of config file") ("test-prctl", bpo::value(), "name of prctl file") From 5f64fd168b374387eb0106f22c8832de3b70759a Mon Sep 17 00:00:00 2001 From: gereon Date: Fri, 15 Mar 2013 13:03:59 +0100 Subject: [PATCH 065/152] Cleaned up structure of ExplicitModelAdapter. - added cpp file - returns complete models now (missing transition rewards...) --- src/adapters/ExplicitModelAdapter.h | 544 ++++------------------------ 1 file changed, 75 insertions(+), 469 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 8b8e5dee3..1010929a5 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -1,55 +1,44 @@ -/* - * IntermediateRepresentationAdapter.h +/* + * File: ExplicitModelAdapter.h + * Author: Gereon Kremer * - * Created on: 13.01.2013 - * Author: Christian Dehnert + * Created on March 15, 2013, 11:42 AM */ -#ifndef STORM_IR_EXPLICITMODELADAPTER_H_ -#define STORM_IR_EXPLICITMODELADAPTER_H_ +#ifndef EXPLICITMODELADAPTER_H +#define EXPLICITMODELADAPTER_H -#include "src/storage/SparseMatrix.h" -#include "src/utility/Settings.h" +#include +#include +#include +#include +#include -#include "src/ir/RewardModel.h" +#include "src/ir/Program.h" #include "src/ir/StateReward.h" #include "src/ir/TransitionReward.h" #include "src/models/AbstractModel.h" -#include "src/models/Dtmc.h" -#include "src/models/Ctmc.h" -#include "src/models/Mdp.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef std::pair, std::vector> StateType; - -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" -#include "ir/Program.h" -extern log4cplus::Logger logger; +#include "src/models/AtomicPropositionsLabeling.h" +#include "src/storage/SparseMatrix.h" namespace storm { - namespace adapters { +/*! + * Model state, represented by the values of all variables. + */ +typedef std::pair, std::vector> StateType; + class StateHash { public: std::size_t operator()(StateType* state) const { size_t seed = 0; - for (auto it = state->first.begin(); it != state->first.end(); ++it) { - boost::hash_combine(seed, *it); + for (auto it : state->first) { + boost::hash_combine(seed, it); } - for (auto it = state->second.begin(); it != state->second.end(); ++it) { - boost::hash_combine(seed, *it); + for (auto it : state->second) { + boost::hash_combine(seed, it); } return seed; } @@ -64,131 +53,47 @@ public: class ExplicitModelAdapter { public: - ExplicitModelAdapter(std::shared_ptr program) : program(program), allStates(), - stateToIndexMap(), booleanVariables(), integerVariables(), booleanVariableToIndexMap(), - integerVariableToIndexMap(), numberOfTransitions(0) { - - } - - std::shared_ptr toModel(std::string const & rewardModelName = "") { - - std::shared_ptr> matrix = this->toSparseMatrix(); - - std::shared_ptr stateLabeling = this->getStateLabeling(this->program->getLabels()); - std::shared_ptr> stateRewards = nullptr; - std::shared_ptr> transitionRewardMatrix = nullptr; - - if (rewardModelName != "") { - storm::ir::RewardModel rewardModel = this->program->getRewardModel(rewardModelName); - stateRewards = this->getStateRewards(rewardModel.getStateRewards()); - } - - switch (this->program->getModelType()) - { -/* std::shared_ptr> probabilityMatrix, - std::shared_ptr stateLabeling, - std::shared_ptr> stateRewards = nullptr, - std::shared_ptr> transitionRewardMatrix = nullptr -*/ - case storm::ir::Program::DTMC: - return std::shared_ptr(new storm::models::Dtmc(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); - break; - case storm::ir::Program::CTMC: - return std::shared_ptr(new storm::models::Ctmc(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); - break; - case storm::ir::Program::MDP: - return std::shared_ptr(new storm::models::Mdp(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); - break; - case storm::ir::Program::CTMDP: - // Todo - //return std::shared_ptr(new storm::models::Ctmdp(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); - break; - default: - // ERROR - break; - } - - return std::shared_ptr(nullptr); - } - - std::shared_ptr> toSparseMatrix() { - LOG4CPLUS_INFO(logger, "Creating sparse matrix for probabilistic program."); - - std::shared_ptr> resultMatrix = this->buildMatrix(); + ExplicitModelAdapter(std::shared_ptr program); + ~ExplicitModelAdapter(); - LOG4CPLUS_INFO(logger, "Created sparse matrix with " << resultMatrix->getRowCount() << " reachable states and " << resultMatrix->getNonZeroEntryCount() << " transitions."); - - this->clearReachableStateSpace(); - - return resultMatrix; - } + std::shared_ptr getModel(std::string const & rewardModelName = ""); private: - static void setValue(StateType* state, uint_fast64_t index, bool value) { - std::get<0>(*state)[index] = value; - } - static void setValue(StateType* state, uint_fast64_t index, int_fast64_t value) { - std::get<1>(*state)[index] = value; - } - - std::shared_ptr> getStateRewards(std::vector const & rewards) { - std::shared_ptr> results(new std::vector(this->allStates.size())); - for (uint_fast64_t index = 0; index < this->allStates.size(); index++) { - for (auto reward: rewards) { - (*results)[index] = reward.getReward(this->allStates[index]); - } - } - return results; - } + // First some generic routines to operate on states. - std::shared_ptr getStateLabeling(std::map> labels) { - std::shared_ptr results(new storm::models::AtomicPropositionsLabeling(this->allStates.size(), labels.size())); - for (auto it: labels) { - results->addAtomicProposition(it.first); - } - for (uint_fast64_t index = 0; index < this->allStates.size(); index++) { - for (auto label: labels) { - if (label.second->getValueAsBool(this->allStates[index])) { - results->addAtomicPropositionToState(label.first, index); - } - } - } - return results; - } - /*! - * Initializes all internal variables. + * Set some boolean variable in the given state object. + * @param state State to be changed. + * @param index Index of boolean variable. + * @param value New value. */ - void prepareAuxiliaryDatastructures() { - uint_fast64_t numberOfIntegerVariables = 0; - uint_fast64_t numberOfBooleanVariables = 0; - for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { - numberOfIntegerVariables += program->getModule(i).getNumberOfIntegerVariables(); - numberOfBooleanVariables += program->getModule(i).getNumberOfBooleanVariables(); - } + static void setValue(StateType* const state, uint_fast64_t const index, bool const value); + /*! + * Set some integer variable in the given state object. + * @param state State to be changed. + * @param index Index of integer variable. + * @param value New value. + */ + static void setValue(StateType* const state, uint_fast64_t const index, int_fast64_t const value); + /*! + * Apply an update to the given state and return the resulting new state object. + * This methods creates a copy of the given state. + * @params state Current state. + * @params update Update to be applied. + * @return Resulting state. + */ + StateType* applyUpdate(StateType const * const state, storm::ir::Update const & update) const; - this->booleanVariables.resize(numberOfBooleanVariables); - this->integerVariables.resize(numberOfIntegerVariables); + /*! + * Reads and combines variables from all program modules and stores them. + * Also creates a map to obtain a variable index from a variable map efficiently. + */ + void initializeVariables(); - uint_fast64_t nextBooleanVariableIndex = 0; - uint_fast64_t nextIntegerVariableIndex = 0; - for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { - storm::ir::Module const& module = program->getModule(i); + std::shared_ptr> getStateRewards(std::vector const & rewards); + std::shared_ptr getStateLabeling(std::map> labels); - for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { - this->booleanVariables[nextBooleanVariableIndex] = module.getBooleanVariable(j); - this->booleanVariableToIndexMap[module.getBooleanVariable(j).getName()] = nextBooleanVariableIndex; - ++nextBooleanVariableIndex; - } - for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) { - this->integerVariables[nextIntegerVariableIndex] = module.getIntegerVariable(j); - this->integerVariableToIndexMap[module.getIntegerVariable(j).getName()] = nextIntegerVariableIndex; - ++nextIntegerVariableIndex; - } - } - } - /*! * Retrieves all active command labeled by some label, ordered by modules. * @@ -202,106 +107,13 @@ private: * @param action Action label. * @return Active commands. */ - std::unique_ptr>> getActiveCommandsByAction(StateType const * state, std::string& action) { - std::unique_ptr>> res = std::unique_ptr>>(new std::list>()); - - // Iterate over all modules. - for (uint_fast64_t i = 0; i < this->program->getNumberOfModules(); ++i) { - storm::ir::Module const& module = this->program->getModule(i); - - std::shared_ptr> ids = module.getCommandsByAction(action); - std::list commands; - - // Look up commands by their id. Add, if guard holds. - for (uint_fast64_t id : *ids) { - storm::ir::Command cmd = module.getCommand(id); - if (cmd.getGuard()->getValueAsBool(state)) { - commands.push_back(module.getCommand(id)); - } - } - res->push_back(commands); - } - // Sort the result in the vague hope that having small lists at the beginning will speed up the expanding. - // This is how lambdas may look like in C++... - res->sort([](const std::list& a, const std::list& b){ return a.size() < b.size(); }); - return res; - } - - /*! - * Apply an update to the given state and return resulting state. - * @params state Current state. - * @params update Update to be applied. - * @return Resulting state. - */ - StateType* applyUpdate(StateType const * const state, storm::ir::Update const & update) { - StateType* newState = new StateType(*state); - for (auto assignedVariable : update.getBooleanAssignments()) { - setValue(newState, this->booleanVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsBool(state)); - } - for (auto assignedVariable : update.getIntegerAssignments()) { - setValue(newState, this->integerVariableToIndexMap[assignedVariable.first], assignedVariable.second.getExpression()->getValueAsInt(state)); - } - return newState; - } + std::unique_ptr>> getActiveCommandsByAction(StateType const * state, std::string& action); /*! * Generates all initial states and adds them to allStates. */ - void generateInitialStates() { - // Create a fresh state which can hold as many boolean and integer variables as there are. - this->allStates.clear(); - this->allStates.push_back(new StateType()); - this->allStates[0]->first.resize(this->booleanVariables.size()); - this->allStates[0]->second.resize(this->integerVariables.size()); - - // Start with boolean variables. - for (uint_fast64_t i = 0; i < this->booleanVariables.size(); ++i) { - // Check if an initial value is given - if (this->booleanVariables[i].getInitialValue().get() == nullptr) { - // No initial value was given. - uint_fast64_t size = this->allStates.size(); - for (uint_fast64_t pos = 0; pos < size; pos++) { - // Duplicate each state, one with true and one with false. - this->allStates.push_back(new StateType(*this->allStates[pos])); - std::get<0>(*this->allStates[pos])[i] = false; - std::get<0>(*this->allStates[size + pos])[i] = true; - } - } else { - // Initial value was given. - bool initialValue = this->booleanVariables[i].getInitialValue()->getValueAsBool(this->allStates[0]); - for (auto it : this->allStates) { - std::get<0>(*it)[i] = initialValue; - } - } - } - // Now process integer variables. - for (uint_fast64_t i = 0; i < this->integerVariables.size(); ++i) { - // Check if an initial value was given. - if (this->integerVariables[i].getInitialValue().get() == nullptr) { - // No initial value was given. - uint_fast64_t size = this->allStates.size(); - int_fast64_t lower = this->integerVariables[i].getLowerBound()->getValueAsInt(this->allStates[0]); - int_fast64_t upper = this->integerVariables[i].getUpperBound()->getValueAsInt(this->allStates[0]); - - // Duplicate all states for all values in variable interval. - for (int_fast64_t value = lower; value <= upper; value++) { - for (uint_fast64_t pos = 0; pos < size; pos++) { - // If value is lower bound, we reuse the existing state, otherwise we create a new one. - if (value > lower) this->allStates.push_back(new StateType(*this->allStates[pos])); - // Set value to current state. - std::get<1>(*this->allStates[(value - lower) * size + pos])[i] = value; - } - } - } else { - // Initial value was given. - int_fast64_t initialValue = this->integerVariables[i].getInitialValue()->getValueAsInt(this->allStates[0]); - for (auto it : this->allStates) { - std::get<1>(*it)[i] = initialValue; - } - } - } - } - + void generateInitialStates(); + /*! * Retrieves the state id of the given state. * If the state has not been hit yet, it will be added to allStates and given a new id. @@ -311,171 +123,29 @@ private: * @param state Pointer to state, shall not be used afterwards. * @returns State id of given state. */ - uint_fast64_t getOrAddStateId(StateType * state) { - // Check, if we already know this state at all. - auto indexIt = this->stateToIndexMap.find(state); - if (indexIt == this->stateToIndexMap.end()) { - // No, add to allStates, initialize index. - allStates.push_back(state); - stateToIndexMap[state] = allStates.size()-1; - return allStates.size()-1; - } else { - // Yes, obtain index and delete state object. - delete state; - return indexIt->second; - } - } + uint_fast64_t getOrAddStateId(StateType * state); /*! * Expands all unlabeled transitions for a given state and adds them to the given list of results. * @params state State to be explored. * @params res Intermediate transition map. */ - void addUnlabeledTransitions(const uint_fast64_t stateID, std::list>& res) { - const StateType* state = this->allStates[stateID]; - // Iterate over all modules. - for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { - storm::ir::Module const& module = program->getModule(i); - // Iterate over all commands. - for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { - storm::ir::Command const& command = module.getCommand(j); - // Only consider unlabeled commands. - if (command.getActionName() != "") continue; - // Omit, if command is not active. - if (!command.getGuard()->getValueAsBool(state)) continue; - - // Add a new map and get pointer. - res.emplace_back(); - std::map* states = &res.back(); - - // Iterate over all updates. - for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { - // Obtain new state id. - storm::ir::Update const& update = command.getUpdate(k); - uint_fast64_t newStateId = this->getOrAddStateId(this->applyUpdate(state, update)); - - // Check, if we already know this state, add up probabilities for every state. - auto stateIt = states->find(newStateId); - if (stateIt == states->end()) { - (*states)[newStateId] = update.getLikelihoodExpression()->getValueAsDouble(state); - this->numberOfTransitions++; - } else { - (*states)[newStateId] += update.getLikelihoodExpression()->getValueAsDouble(state); - } - } - } - } - } - + void addUnlabeledTransitions(const uint_fast64_t stateID, std::list>& res); + /*! * Explores reachable state from given state by using labeled transitions. * Found transitions are stored in given map. * @param stateID State to be explored. * @param res Intermediate transition map. */ - void addLabeledTransitions(const uint_fast64_t stateID, std::list>& res) { - // Create a copy of the current state, as we will free intermediate states... - for (std::string action : this->program->getActions()) { - StateType* state = new StateType(*this->allStates[stateID]); - std::unique_ptr>> cmds = this->getActiveCommandsByAction(state, action); - - // Start with current state - std::unordered_map resultStates; - resultStates[state] = 1.0; - - for (std::list module : *cmds) { - if (resultStates.size() == 0) break; - std::unordered_map newStates; - - // Iterate over all commands within this module. - for (storm::ir::Command command : module) { - // Iterate over all updates of this command. - for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { - storm::ir::Update const& update = command.getUpdate(k); - - // Iterate over all resultStates. - for (auto it : resultStates) { - // Apply the new update and get resulting state. - StateType* newState = this->applyUpdate(it.first, update); - // Insert the new state into newStates array. - // Take care of calculation of likelihood, combine identical states. - auto s = newStates.find(newState); - if (s == newStates.end()) { - newStates[newState] = it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); - } else { - newStates[newState] += it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); - } - } - } - } - for (auto it: resultStates) { - delete it.first; - } - // Move new states to resultStates. - resultStates.clear(); - resultStates.insert(newStates.begin(), newStates.end()); - - } - - if (resultStates.size() > 0) { - res.emplace_back(); - std::map* states = &res.back(); - - // Now add our final result states to our global result. - for (auto it : resultStates) { - uint_fast64_t newStateID = this->getOrAddStateId(it.first); - (*states)[newStateID] = it.second; - } - this->numberOfTransitions += states->size(); - } - } - - } + void addLabeledTransitions(const uint_fast64_t stateID, std::list>& res); /*! * Create matrix from intermediate mapping, assuming it is a dtmc model. * @param intermediate Intermediate representation of transition mapping. * @return result matrix. */ - std::shared_ptr> buildDTMCMatrix(std::map>> intermediate) { - std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size())); - // this->numberOfTransitions is meaningless, as we combine all choices into one for each state. - // Hence, we compute the correct number of transitions now. - uint_fast64_t numberOfTransitions = 0; - for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { - // Collect all target nodes in a set to get number of distinct nodes. - std::set set; - for (auto choice : intermediate[state]) { - for (auto elem : choice) { - set.insert(elem.first); - } - } - numberOfTransitions += set.size(); - } - std::cout << "Building DTMC matrix with " << numberOfTransitions << " transitions." << std::endl; - // Now build matrix. - result->initialize(numberOfTransitions); - for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { - if (intermediate[state].size() > 1) { - std::cout << "Warning: state " << state << " has " << intermediate[state].size() << " overlapping guards in dtmc" << std::endl; - } - // Combine choices to one map. - std::map map; - for (auto choice : intermediate[state]) { - for (auto elem : choice) { - map[elem.first] += elem.second; - } - } - // Scale probabilities by number of choices. - double factor = 1.0 / intermediate[state].size(); - for (auto it : map) { - result->addNextValue(state, it.first, it.second * factor); - } - - } - result->finalize(); - return result; - } + std::shared_ptr> buildDeterministicMatrix(); /*! * Create matrix from intermediate mapping, assuming it is a mdp model. @@ -483,23 +153,7 @@ private: * @param choices Overall number of choices for all nodes. * @return result matrix. */ - std::shared_ptr> buildMDPMatrix(std::map>> intermediate, uint_fast64_t choices) { - std::cout << "Building MDP matrix with " << this->numberOfTransitions << " transitions." << std::endl; - std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size(), choices)); - // Build matrix. - result->initialize(this->numberOfTransitions); - uint_fast64_t nextRow = 0; - for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { - for (auto choice : intermediate[state]) { - for (auto it : choice) { - result->addNextValue(nextRow, it.first, it.second); - } - nextRow++; - } - } - result->finalize(); - return result; - } + std::shared_ptr> buildNondeterministicMatrix(); /*! * Build matrix from model. Starts with all initial states and explores the reachable state space. @@ -507,73 +161,25 @@ private: * Afterwards, we transform this map into the actual matrix. * @return result matrix. */ - std::shared_ptr> buildMatrix() { - this->prepareAuxiliaryDatastructures(); - this->allStates.clear(); - this->stateToIndexMap.clear(); - this->numberOfTransitions = 0; - uint_fast64_t choices; - std::map>> intermediate; - - this->generateInitialStates(); - for (uint_fast64_t curIndex = 0; curIndex < this->allStates.size(); curIndex++) - { - this->addUnlabeledTransitions(curIndex, intermediate[curIndex]); - this->addLabeledTransitions(curIndex, intermediate[curIndex]); - - choices += intermediate[curIndex].size(); - if (intermediate[curIndex].size() == 0) { - // This is a deadlock state. - if (storm::settings::instance()->isSet("fix-deadlocks")) { - this->numberOfTransitions++; - intermediate[curIndex].emplace_back(); - intermediate[curIndex].back()[curIndex] = 1; - } else { - LOG4CPLUS_ERROR(logger, "Error while creating sparse matrix from probabilistic program: found deadlock state."); - throw storm::exceptions::WrongFileFormatException() << "Error while creating sparse matrix from probabilistic program: found deadlock state."; - } - } - } - - - switch (this->program->getModelType()) { - case storm::ir::Program::DTMC: - case storm::ir::Program::CTMC: - return this->buildDTMCMatrix(intermediate); - case storm::ir::Program::MDP: - case storm::ir::Program::CTMDP: - return this->buildMDPMatrix(intermediate, choices); - default: - LOG4CPLUS_ERROR(logger, "Error while creating sparse matrix from probabilistic program: We can't handle this model type."); - throw storm::exceptions::WrongFileFormatException() << "Error while creating sparse matrix from probabilistic program: We can't handle this model type."; - break; - } - return std::shared_ptr>(nullptr); - } - - /*! - * Free all StateType objects and clear maps. - */ - void clearReachableStateSpace() { - for (auto it : allStates) { - delete it; - } - allStates.clear(); - stateToIndexMap.clear(); - } + void buildIntermediateRepresentation(); + // Program that should be converted. std::shared_ptr program; - std::vector allStates; - std::unordered_map stateToIndexMap; std::vector booleanVariables; std::vector integerVariables; - std::unordered_map booleanVariableToIndexMap; - std::unordered_map integerVariableToIndexMap; + std::map booleanVariableToIndexMap; + std::map integerVariableToIndexMap; + + // Members that are filled during the conversion. + std::vector allStates; + std::unordered_map stateToIndexMap; uint_fast64_t numberOfTransitions; + uint_fast64_t numberOfChoices; + std::map>> transitionMap; }; } // namespace adapters - } // namespace storm -#endif /* STORM_IR_EXPLICITMODELADAPTER_H_ */ +#endif /* EXPLICITMODELADAPTER_H */ + From 75ce91082a9495100ac3db3ac232711caf5f7c38 Mon Sep 17 00:00:00 2001 From: gereon Date: Fri, 15 Mar 2013 13:34:49 +0100 Subject: [PATCH 066/152] Forgot to commit actual cpp file... --- src/adapters/ExplicitModelAdapter.cpp | 501 ++++++++++++++++++++++++++ 1 file changed, 501 insertions(+) create mode 100644 src/adapters/ExplicitModelAdapter.cpp diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp new file mode 100644 index 000000000..9b42f9846 --- /dev/null +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -0,0 +1,501 @@ +#include "src/adapters/ExplicitModelAdapter.h" + +#include "src/storage/SparseMatrix.h" +#include "src/utility/Settings.h" +#include "src/exceptions/WrongFileFormatException.h" + +#include "src/ir/Program.h" +#include "src/ir/RewardModel.h" +#include "src/ir/StateReward.h" +#include "src/ir/TransitionReward.h" + +#include "src/models/AbstractModel.h" +#include "src/models/Dtmc.h" +#include "src/models/Ctmc.h" +#include "src/models/Mdp.h" + +typedef std::pair, std::vector> StateType; + +#include "log4cplus/logger.h" +#include "log4cplus/loggingmacros.h" +extern log4cplus::Logger logger; + +namespace storm { + +namespace adapters { + +ExplicitModelAdapter::ExplicitModelAdapter(std::shared_ptr program) : program(program), + booleanVariables(), integerVariables(), booleanVariableToIndexMap(), integerVariableToIndexMap(), + allStates(), stateToIndexMap(), numberOfTransitions(0), numberOfChoices(0), transitionMap() { + this->initializeVariables(); +} + +ExplicitModelAdapter::~ExplicitModelAdapter() { + for (auto it : allStates) { + delete it; + } + allStates.clear(); + stateToIndexMap.clear(); +} + + std::shared_ptr ExplicitModelAdapter::getModel(std::string const & rewardModelName) { + + this->buildIntermediateRepresentation(); + + std::shared_ptr stateLabeling = this->getStateLabeling(this->program->getLabels()); + std::shared_ptr> stateRewards = nullptr; + std::shared_ptr> transitionRewardMatrix = nullptr; + + if (rewardModelName != "") { + storm::ir::RewardModel rewardModel = this->program->getRewardModel(rewardModelName); + stateRewards = this->getStateRewards(rewardModel.getStateRewards()); + } + + switch (this->program->getModelType()) + { + case storm::ir::Program::DTMC: + { + std::shared_ptr> matrix = this->buildDeterministicMatrix(); + return std::shared_ptr(new storm::models::Dtmc(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); + break; + } + case storm::ir::Program::CTMC: + { + std::shared_ptr> matrix = this->buildDeterministicMatrix(); + return std::shared_ptr(new storm::models::Ctmc(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); + break; + } + case storm::ir::Program::MDP: + { + std::shared_ptr> matrix = this->buildNondeterministicMatrix(); + return std::shared_ptr(new storm::models::Mdp(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); + break; + } + case storm::ir::Program::CTMDP: + // Todo + //return std::shared_ptr(new storm::models::Ctmdp(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); + break; + default: + LOG4CPLUS_ERROR(logger, "Error while creating model from probabilistic program: We can't handle this model type."); + throw storm::exceptions::WrongFileFormatException() << "Error while creating model from probabilistic program: We can't handle this model type."; + break; + } + + return std::shared_ptr(nullptr); + } + + void ExplicitModelAdapter::setValue(StateType* const state, uint_fast64_t const index, bool const value) { + std::get<0>(*state)[index] = value; + } + + void ExplicitModelAdapter::setValue(StateType* const state, uint_fast64_t const index, int_fast64_t const value) { + std::get<1>(*state)[index] = value; + } + + std::shared_ptr> ExplicitModelAdapter::getStateRewards(std::vector const & rewards) { + std::shared_ptr> results(new std::vector(this->allStates.size())); + for (uint_fast64_t index = 0; index < this->allStates.size(); index++) { + for (auto reward: rewards) { + (*results)[index] = reward.getReward(this->allStates[index]); + } + } + return results; + } + + std::shared_ptr ExplicitModelAdapter::getStateLabeling(std::map> labels) { + std::shared_ptr results(new storm::models::AtomicPropositionsLabeling(this->allStates.size(), labels.size())); + for (auto it: labels) { + results->addAtomicProposition(it.first); + } + for (uint_fast64_t index = 0; index < this->allStates.size(); index++) { + for (auto label: labels) { + if (label.second->getValueAsBool(this->allStates[index])) { + results->addAtomicPropositionToState(label.first, index); + } + } + } + return results; + } + + void ExplicitModelAdapter::initializeVariables() { + uint_fast64_t numberOfIntegerVariables = 0; + uint_fast64_t numberOfBooleanVariables = 0; + for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { + numberOfIntegerVariables += program->getModule(i).getNumberOfIntegerVariables(); + numberOfBooleanVariables += program->getModule(i).getNumberOfBooleanVariables(); + } + + this->booleanVariables.resize(numberOfBooleanVariables); + this->integerVariables.resize(numberOfIntegerVariables); + + uint_fast64_t nextBooleanVariableIndex = 0; + uint_fast64_t nextIntegerVariableIndex = 0; + for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { + storm::ir::Module const& module = program->getModule(i); + + for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { + this->booleanVariables[nextBooleanVariableIndex] = module.getBooleanVariable(j); + this->booleanVariableToIndexMap[module.getBooleanVariable(j).getName()] = nextBooleanVariableIndex; + ++nextBooleanVariableIndex; + } + for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) { + this->integerVariables[nextIntegerVariableIndex] = module.getIntegerVariable(j); + this->integerVariableToIndexMap[module.getIntegerVariable(j).getName()] = nextIntegerVariableIndex; + ++nextIntegerVariableIndex; + } + } + } + + /*! + * Retrieves all active command labeled by some label, ordered by modules. + * + * This function will iterate over all modules and retrieve all commands that are labeled with the given action and active for the current state. + * The result will be a list of lists of commands. + * + * For each module that has appropriately labeled commands, there will be a list. + * If none of these commands is active, this list is empty. + * Note the difference between *no list* and *empty list*: Modules that produce no list are not relevant for this action while an empty list means, that it is not possible to do anything with this label. + * @param state Current state. + * @param action Action label. + * @return Active commands. + */ + std::unique_ptr>> ExplicitModelAdapter::getActiveCommandsByAction(StateType const * state, std::string& action) { + std::unique_ptr>> res = std::unique_ptr>>(new std::list>()); + + // Iterate over all modules. + for (uint_fast64_t i = 0; i < this->program->getNumberOfModules(); ++i) { + storm::ir::Module const& module = this->program->getModule(i); + + std::shared_ptr> ids = module.getCommandsByAction(action); + std::list commands; + + // Look up commands by their id. Add, if guard holds. + for (uint_fast64_t id : *ids) { + storm::ir::Command cmd = module.getCommand(id); + if (cmd.getGuard()->getValueAsBool(state)) { + commands.push_back(module.getCommand(id)); + } + } + res->push_back(commands); + } + // Sort the result in the vague hope that having small lists at the beginning will speed up the expanding. + // This is how lambdas may look like in C++... + res->sort([](const std::list& a, const std::list& b){ return a.size() < b.size(); }); + return res; + } + + /*! + * Apply an update to the given state and return resulting state. + * @params state Current state. + * @params update Update to be applied. + * @return Resulting state. + */ + StateType* ExplicitModelAdapter::applyUpdate(StateType const * const state, storm::ir::Update const & update) const { + StateType* newState = new StateType(*state); + for (auto assignedVariable : update.getBooleanAssignments()) { + setValue(newState, this->booleanVariableToIndexMap.at(assignedVariable.first), assignedVariable.second.getExpression()->getValueAsBool(state)); + } + for (auto assignedVariable : update.getIntegerAssignments()) { + setValue(newState, this->integerVariableToIndexMap.at(assignedVariable.first), assignedVariable.second.getExpression()->getValueAsInt(state)); + } + return newState; + } + + /*! + * Generates all initial states and adds them to allStates. + */ + void ExplicitModelAdapter::generateInitialStates() { + // Create a fresh state which can hold as many boolean and integer variables as there are. + this->allStates.clear(); + this->allStates.push_back(new StateType()); + this->allStates[0]->first.resize(this->booleanVariables.size()); + this->allStates[0]->second.resize(this->integerVariables.size()); + + // Start with boolean variables. + for (uint_fast64_t i = 0; i < this->booleanVariables.size(); ++i) { + // Check if an initial value is given + if (this->booleanVariables[i].getInitialValue().get() == nullptr) { + // No initial value was given. + uint_fast64_t size = this->allStates.size(); + for (uint_fast64_t pos = 0; pos < size; pos++) { + // Duplicate each state, one with true and one with false. + this->allStates.push_back(new StateType(*this->allStates[pos])); + std::get<0>(*this->allStates[pos])[i] = false; + std::get<0>(*this->allStates[size + pos])[i] = true; + } + } else { + // Initial value was given. + bool initialValue = this->booleanVariables[i].getInitialValue()->getValueAsBool(this->allStates[0]); + for (auto it : this->allStates) { + std::get<0>(*it)[i] = initialValue; + } + } + } + // Now process integer variables. + for (uint_fast64_t i = 0; i < this->integerVariables.size(); ++i) { + // Check if an initial value was given. + if (this->integerVariables[i].getInitialValue().get() == nullptr) { + // No initial value was given. + uint_fast64_t size = this->allStates.size(); + int_fast64_t lower = this->integerVariables[i].getLowerBound()->getValueAsInt(this->allStates[0]); + int_fast64_t upper = this->integerVariables[i].getUpperBound()->getValueAsInt(this->allStates[0]); + + // Duplicate all states for all values in variable interval. + for (int_fast64_t value = lower; value <= upper; value++) { + for (uint_fast64_t pos = 0; pos < size; pos++) { + // If value is lower bound, we reuse the existing state, otherwise we create a new one. + if (value > lower) this->allStates.push_back(new StateType(*this->allStates[pos])); + // Set value to current state. + std::get<1>(*this->allStates[(value - lower) * size + pos])[i] = value; + } + } + } else { + // Initial value was given. + int_fast64_t initialValue = this->integerVariables[i].getInitialValue()->getValueAsInt(this->allStates[0]); + for (auto it : this->allStates) { + std::get<1>(*it)[i] = initialValue; + } + } + } + LOG4CPLUS_DEBUG(logger, "Generated " << this->allStates.size() << " initial states."); + } + + /*! + * Retrieves the state id of the given state. + * If the state has not been hit yet, it will be added to allStates and given a new id. + * In this case, the pointer must not be deleted, as it is used within allStates. + * If the state is already known, the pointer is deleted and the old state id is returned. + * Hence, the given state pointer should not be used afterwards. + * @param state Pointer to state, shall not be used afterwards. + * @returns State id of given state. + */ + uint_fast64_t ExplicitModelAdapter::getOrAddStateId(StateType * state) { + // Check, if we already know this state at all. + auto indexIt = this->stateToIndexMap.find(state); + if (indexIt == this->stateToIndexMap.end()) { + // No, add to allStates, initialize index. + allStates.push_back(state); + stateToIndexMap[state] = allStates.size()-1; + return allStates.size()-1; + } else { + // Yes, obtain index and delete state object. + delete state; + return indexIt->second; + } + } + + /*! + * Expands all unlabeled transitions for a given state and adds them to the given list of results. + * @params state State to be explored. + * @params res Intermediate transition map. + */ + void ExplicitModelAdapter::addUnlabeledTransitions(const uint_fast64_t stateID, std::list>& res) { + const StateType* state = this->allStates[stateID]; + // Iterate over all modules. + for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { + storm::ir::Module const& module = program->getModule(i); + // Iterate over all commands. + for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { + storm::ir::Command const& command = module.getCommand(j); + // Only consider unlabeled commands. + if (command.getActionName() != "") continue; + // Omit, if command is not active. + if (!command.getGuard()->getValueAsBool(state)) continue; + + // Add a new map and get pointer. + res.emplace_back(); + std::map* states = &res.back(); + + // Iterate over all updates. + for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { + // Obtain new state id. + storm::ir::Update const& update = command.getUpdate(k); + uint_fast64_t newStateId = this->getOrAddStateId(this->applyUpdate(state, update)); + + // Check, if we already know this state, add up probabilities for every state. + auto stateIt = states->find(newStateId); + if (stateIt == states->end()) { + (*states)[newStateId] = update.getLikelihoodExpression()->getValueAsDouble(state); + this->numberOfTransitions++; + } else { + (*states)[newStateId] += update.getLikelihoodExpression()->getValueAsDouble(state); + } + } + } + } + } + + /*! + * Explores reachable state from given state by using labeled transitions. + * Found transitions are stored in given map. + * @param stateID State to be explored. + * @param res Intermediate transition map. + */ + void ExplicitModelAdapter::addLabeledTransitions(const uint_fast64_t stateID, std::list>& res) { + // Create a copy of the current state, as we will free intermediate states... + for (std::string action : this->program->getActions()) { + StateType* state = new StateType(*this->allStates[stateID]); + std::unique_ptr>> cmds = this->getActiveCommandsByAction(state, action); + + // Start with current state + std::unordered_map resultStates; + resultStates[state] = 1.0; + + for (std::list module : *cmds) { + if (resultStates.size() == 0) break; + std::unordered_map newStates; + + // Iterate over all commands within this module. + for (storm::ir::Command command : module) { + // Iterate over all updates of this command. + for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { + storm::ir::Update const& update = command.getUpdate(k); + + // Iterate over all resultStates. + for (auto it : resultStates) { + // Apply the new update and get resulting state. + StateType* newState = this->applyUpdate(it.first, update); + // Insert the new state into newStates array. + // Take care of calculation of likelihood, combine identical states. + auto s = newStates.find(newState); + if (s == newStates.end()) { + newStates[newState] = it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); + } else { + newStates[newState] += it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); + } + } + } + } + for (auto it: resultStates) { + delete it.first; + } + // Move new states to resultStates. + resultStates.clear(); + resultStates.insert(newStates.begin(), newStates.end()); + + } + + if (resultStates.size() > 0) { + res.emplace_back(); + std::map* states = &res.back(); + + // Now add our final result states to our global result. + for (auto it : resultStates) { + uint_fast64_t newStateID = this->getOrAddStateId(it.first); + (*states)[newStateID] = it.second; + } + this->numberOfTransitions += states->size(); + } + } + + } + + /*! + * Create matrix from intermediate mapping, assuming it is a dtmc model. + * @param intermediate Intermediate representation of transition mapping. + * @return result matrix. + */ + std::shared_ptr> ExplicitModelAdapter::buildDeterministicMatrix() { + std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size())); + // ***** ATTENTION ***** + // this->numberOfTransitions is meaningless, as we combine all choices into one for each state. + // Hence, we compute the correct number of transitions now. + uint_fast64_t numberOfTransitions = 0; + for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { + // Collect all target nodes in a set to get number of distinct nodes. + std::set set; + for (auto choice : transitionMap[state]) { + for (auto elem : choice) { + set.insert(elem.first); + } + } + numberOfTransitions += set.size(); + } + LOG4CPLUS_DEBUG(logger, "Building deterministic transition matrix with " << numberOfTransitions << " transitions now."); + // Now build matrix. + result->initialize(numberOfTransitions); + for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { + if (transitionMap[state].size() > 1) { + std::cout << "Warning: state " << state << " has " << transitionMap[state].size() << " overlapping guards in dtmc" << std::endl; + } + // Combine choices to one map. + std::map map; + for (auto choice : transitionMap[state]) { + for (auto elem : choice) { + map[elem.first] += elem.second; + } + } + // Scale probabilities by number of choices. + double factor = 1.0 / transitionMap[state].size(); + for (auto it : map) { + result->addNextValue(state, it.first, it.second * factor); + } + + } + result->finalize(); + return result; + } + + /*! + * Create matrix from intermediate mapping, assuming it is a mdp model. + * @param intermediate Intermediate representation of transition mapping. + * @param choices Overall number of choices for all nodes. + * @return result matrix. + */ + std::shared_ptr> ExplicitModelAdapter::buildNondeterministicMatrix() { + LOG4CPLUS_DEBUG(logger, "Building nondeterministic transition matrix with " << this->numberOfChoices << " choices and " << this->numberOfTransitions << " transitions now."); + std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size(), this->numberOfChoices)); + // Build matrix. + result->initialize(this->numberOfTransitions); + uint_fast64_t nextRow = 0; + for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { + for (auto choice : transitionMap[state]) { + for (auto it : choice) { + result->addNextValue(nextRow, it.first, it.second); + } + nextRow++; + } + } + result->finalize(); + return result; + } + + /*! + * Build matrix from model. Starts with all initial states and explores the reachable state space. + * While exploring, the transitions are stored in a temporary map. + * Afterwards, we transform this map into the actual matrix. + * @return result matrix. + */ + void ExplicitModelAdapter::buildIntermediateRepresentation() { + LOG4CPLUS_DEBUG(logger, "Starting to create transition map from program..."); + this->allStates.clear(); + this->stateToIndexMap.clear(); + this->numberOfTransitions = 0; + this->numberOfChoices = 0; + this->transitionMap.clear(); + + this->generateInitialStates(); + for (uint_fast64_t curIndex = 0; curIndex < this->allStates.size(); curIndex++) + { + this->addUnlabeledTransitions(curIndex, this->transitionMap[curIndex]); + this->addLabeledTransitions(curIndex, this->transitionMap[curIndex]); + + this->numberOfChoices += this->transitionMap[curIndex].size(); + if (this->transitionMap[curIndex].size() == 0) { + // This is a deadlock state. + if (storm::settings::instance()->isSet("fix-deadlocks")) { + this->numberOfTransitions++; + this->transitionMap[curIndex].emplace_back(); + this->transitionMap[curIndex].back()[curIndex] = 1; + } else { + LOG4CPLUS_ERROR(logger, "Error while creating sparse matrix from probabilistic program: found deadlock state."); + throw storm::exceptions::WrongFileFormatException() << "Error while creating sparse matrix from probabilistic program: found deadlock state."; + } + } + } + LOG4CPLUS_DEBUG(logger, "Finished creating transition map."); + } + +} // namespace adapters + +} // namespace storm From 7dc5324a65e8192c32da64a629b2981c82039023 Mon Sep 17 00:00:00 2001 From: gereon Date: Fri, 15 Mar 2013 15:05:14 +0100 Subject: [PATCH 067/152] Program returns empty RewardModel and emits error, if invalid model is given. --- src/ir/Program.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ir/Program.cpp b/src/ir/Program.cpp index 691951f48..8e5306e71 100644 --- a/src/ir/Program.cpp +++ b/src/ir/Program.cpp @@ -6,9 +6,14 @@ */ #include "Program.h" +#include "exceptions/InvalidArgumentException.h" #include +#include "log4cplus/logger.h" +#include "log4cplus/loggingmacros.h" +extern log4cplus::Logger logger; + namespace storm { namespace ir { @@ -101,7 +106,8 @@ std::shared_ptr> const Program::getModulesByAction(std:: storm::ir::RewardModel Program::getRewardModel(std::string const & name) const { auto it = this->rewards.find(name); if (it == this->rewards.end()) { - // throw some exception here... + LOG4CPLUS_ERROR(logger, "The given reward model \"" << name << "\" does not exist. We will proceed without rewards."); + return RewardModel(); } else { return it->second; } From d9e833680aa1d47da845d1881eaa40cb2a415bb8 Mon Sep 17 00:00:00 2001 From: gereon Date: Fri, 15 Mar 2013 15:06:03 +0100 Subject: [PATCH 068/152] Added convenience methods RewardModel::hasStateRewards() and RewardModel::hasTransitionRewards() --- src/ir/RewardModel.cpp | 8 ++++++++ src/ir/RewardModel.h | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/ir/RewardModel.cpp b/src/ir/RewardModel.cpp index bd3ce1e16..d6611e4ec 100644 --- a/src/ir/RewardModel.cpp +++ b/src/ir/RewardModel.cpp @@ -37,10 +37,18 @@ std::string RewardModel::toString() const { return result.str(); } +bool RewardModel::hasStateRewards() const { + return this->stateRewards.size() > 0; +} + std::vector RewardModel::getStateRewards() const { return this->stateRewards; } +bool RewardModel::hasTransitionRewards() const { + return this->transitionRewards.size() > 0; +} + std::vector RewardModel::getTransitionRewards() const { return this->transitionRewards; } diff --git a/src/ir/RewardModel.h b/src/ir/RewardModel.h index 5cd7f2767..cb538f173 100644 --- a/src/ir/RewardModel.h +++ b/src/ir/RewardModel.h @@ -42,12 +42,24 @@ public: */ std::string toString() const; + /*! + * Check, if there are any state rewards. + * @return True, iff there are any state rewards. + */ + bool hasStateRewards() const; + /*! * Retrieve state rewards. * @return State rewards. */ std::vector getStateRewards() const; + /*! + * Check, if there are any transition rewards. + * @return True, iff there are any transition rewards. + */ + bool hasTransitionRewards() const; + /*! * Retrieve transition rewards. * @return Transition rewards. From 5c25116a246c479957181bf39c2464e31e436c71 Mon Sep 17 00:00:00 2001 From: gereon Date: Fri, 15 Mar 2013 15:06:38 +0100 Subject: [PATCH 069/152] First version of ExplicitModelAdapter that supports transition rewards. --- src/adapters/ExplicitModelAdapter.cpp | 91 +++++++++++++++++---------- src/adapters/ExplicitModelAdapter.h | 19 ++++-- 2 files changed, 73 insertions(+), 37 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index 9b42f9846..9f2b6ff10 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -26,29 +26,25 @@ namespace adapters { ExplicitModelAdapter::ExplicitModelAdapter(std::shared_ptr program) : program(program), booleanVariables(), integerVariables(), booleanVariableToIndexMap(), integerVariableToIndexMap(), - allStates(), stateToIndexMap(), numberOfTransitions(0), numberOfChoices(0), transitionMap() { + allStates(), stateToIndexMap(), numberOfTransitions(0), numberOfChoices(0), transitionRewards(nullptr), transitionMap() { this->initializeVariables(); } ExplicitModelAdapter::~ExplicitModelAdapter() { - for (auto it : allStates) { - delete it; - } - allStates.clear(); - stateToIndexMap.clear(); + this->clearInternalState(); } std::shared_ptr ExplicitModelAdapter::getModel(std::string const & rewardModelName) { - this->buildIntermediateRepresentation(); + this->rewardModel = this->program->getRewardModel(rewardModelName); + + this->buildTransitionMap(); std::shared_ptr stateLabeling = this->getStateLabeling(this->program->getLabels()); std::shared_ptr> stateRewards = nullptr; - std::shared_ptr> transitionRewardMatrix = nullptr; - if (rewardModelName != "") { - storm::ir::RewardModel rewardModel = this->program->getRewardModel(rewardModelName); - stateRewards = this->getStateRewards(rewardModel.getStateRewards()); + if (this->rewardModel.hasStateRewards()) { + stateRewards = this->getStateRewards(this->rewardModel.getStateRewards()); } switch (this->program->getModelType()) @@ -56,19 +52,19 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { case storm::ir::Program::DTMC: { std::shared_ptr> matrix = this->buildDeterministicMatrix(); - return std::shared_ptr(new storm::models::Dtmc(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); + return std::shared_ptr(new storm::models::Dtmc(matrix, stateLabeling, stateRewards, this->transitionRewards)); break; } case storm::ir::Program::CTMC: { std::shared_ptr> matrix = this->buildDeterministicMatrix(); - return std::shared_ptr(new storm::models::Ctmc(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); + return std::shared_ptr(new storm::models::Ctmc(matrix, stateLabeling, stateRewards, this->transitionRewards)); break; } case storm::ir::Program::MDP: { std::shared_ptr> matrix = this->buildNondeterministicMatrix(); - return std::shared_ptr(new storm::models::Mdp(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); + return std::shared_ptr(new storm::models::Mdp(matrix, stateLabeling, stateRewards, this->transitionRewards)); break; } case storm::ir::Program::CTMDP: @@ -289,7 +285,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { * @params state State to be explored. * @params res Intermediate transition map. */ - void ExplicitModelAdapter::addUnlabeledTransitions(const uint_fast64_t stateID, std::list>& res) { + void ExplicitModelAdapter::addUnlabeledTransitions(const uint_fast64_t stateID, std::list>>& res) { const StateType* state = this->allStates[stateID]; // Iterate over all modules. for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { @@ -304,7 +300,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { // Add a new map and get pointer. res.emplace_back(); - std::map* states = &res.back(); + std::map* states = &res.back().second; // Iterate over all updates. for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { @@ -331,7 +327,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { * @param stateID State to be explored. * @param res Intermediate transition map. */ - void ExplicitModelAdapter::addLabeledTransitions(const uint_fast64_t stateID, std::list>& res) { + void ExplicitModelAdapter::addLabeledTransitions(const uint_fast64_t stateID, std::list>>& res) { // Create a copy of the current state, as we will free intermediate states... for (std::string action : this->program->getActions()) { StateType* state = new StateType(*this->allStates[stateID]); @@ -376,8 +372,8 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { } if (resultStates.size() > 0) { - res.emplace_back(); - std::map* states = &res.back(); + res.push_back(std::make_pair(action, std::map())); + std::map* states = &res.back().second; // Now add our final result states to our global result. for (auto it : resultStates) { @@ -396,7 +392,6 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { * @return result matrix. */ std::shared_ptr> ExplicitModelAdapter::buildDeterministicMatrix() { - std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size())); // ***** ATTENTION ***** // this->numberOfTransitions is meaningless, as we combine all choices into one for each state. // Hence, we compute the correct number of transitions now. @@ -405,7 +400,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { // Collect all target nodes in a set to get number of distinct nodes. std::set set; for (auto choice : transitionMap[state]) { - for (auto elem : choice) { + for (auto elem : choice.second) { set.insert(elem.first); } } @@ -413,22 +408,35 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { } LOG4CPLUS_DEBUG(logger, "Building deterministic transition matrix with " << numberOfTransitions << " transitions now."); // Now build matrix. + + std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size())); result->initialize(numberOfTransitions); + if (this->rewardModel.hasTransitionRewards()) { + this->transitionRewards = std::shared_ptr>(new storm::storage::SparseMatrix(allStates.size())); + this->transitionRewards->initialize(numberOfTransitions); + } for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { if (transitionMap[state].size() > 1) { - std::cout << "Warning: state " << state << " has " << transitionMap[state].size() << " overlapping guards in dtmc" << std::endl; + LOG4CPLUS_WARN(logger, "State " << state << " has " << transitionMap[state].size() << " overlapping guards in deterministic model."); } // Combine choices to one map. std::map map; + std::map rewardMap; for (auto choice : transitionMap[state]) { - for (auto elem : choice) { + for (auto elem : choice.second) { map[elem.first] += elem.second; + if (this->rewardModel.hasTransitionRewards()) { + for (storm::ir::TransitionReward reward : this->rewardModel.getTransitionRewards()) { + rewardMap[elem.first] += reward.getReward(choice.first, this->allStates[state]); + } + } } } // Scale probabilities by number of choices. double factor = 1.0 / transitionMap[state].size(); for (auto it : map) { result->addNextValue(state, it.first, it.second * factor); + this->transitionRewards->addNextValue(state, it.first, rewardMap[it.first] * factor); } } @@ -445,13 +453,24 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { std::shared_ptr> ExplicitModelAdapter::buildNondeterministicMatrix() { LOG4CPLUS_DEBUG(logger, "Building nondeterministic transition matrix with " << this->numberOfChoices << " choices and " << this->numberOfTransitions << " transitions now."); std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size(), this->numberOfChoices)); - // Build matrix. result->initialize(this->numberOfTransitions); + if (this->rewardModel.hasTransitionRewards()) { + this->transitionRewards = std::shared_ptr>(new storm::storage::SparseMatrix(allStates.size(), this->numberOfChoices)); + this->transitionRewards->initialize(this->numberOfTransitions); + } + // Build matrix. uint_fast64_t nextRow = 0; for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { for (auto choice : transitionMap[state]) { - for (auto it : choice) { + for (auto it : choice.second) { result->addNextValue(nextRow, it.first, it.second); + if (this->rewardModel.hasTransitionRewards()) { + double rewardValue = 0; + for (storm::ir::TransitionReward reward : this->rewardModel.getTransitionRewards()) { + rewardValue = reward.getReward(choice.first, this->allStates[state]); + } + this->transitionRewards->addNextValue(nextRow, it.first, rewardValue); + } } nextRow++; } @@ -466,13 +485,9 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { * Afterwards, we transform this map into the actual matrix. * @return result matrix. */ - void ExplicitModelAdapter::buildIntermediateRepresentation() { + void ExplicitModelAdapter::buildTransitionMap() { LOG4CPLUS_DEBUG(logger, "Starting to create transition map from program..."); - this->allStates.clear(); - this->stateToIndexMap.clear(); - this->numberOfTransitions = 0; - this->numberOfChoices = 0; - this->transitionMap.clear(); + this->clearInternalState(); this->generateInitialStates(); for (uint_fast64_t curIndex = 0; curIndex < this->allStates.size(); curIndex++) @@ -486,7 +501,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { if (storm::settings::instance()->isSet("fix-deadlocks")) { this->numberOfTransitions++; this->transitionMap[curIndex].emplace_back(); - this->transitionMap[curIndex].back()[curIndex] = 1; + this->transitionMap[curIndex].back().second[curIndex] = 1; } else { LOG4CPLUS_ERROR(logger, "Error while creating sparse matrix from probabilistic program: found deadlock state."); throw storm::exceptions::WrongFileFormatException() << "Error while creating sparse matrix from probabilistic program: found deadlock state."; @@ -496,6 +511,18 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { LOG4CPLUS_DEBUG(logger, "Finished creating transition map."); } + void ExplicitModelAdapter::clearInternalState() { + for (auto it : allStates) { + delete it; + } + allStates.clear(); + stateToIndexMap.clear(); + this->numberOfTransitions = 0; + this->numberOfChoices = 0; + this->transitionRewards = nullptr; + this->transitionMap.clear(); + } + } // namespace adapters } // namespace storm diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 1010929a5..03214d165 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -130,7 +130,7 @@ private: * @params state State to be explored. * @params res Intermediate transition map. */ - void addUnlabeledTransitions(const uint_fast64_t stateID, std::list>& res); + void addUnlabeledTransitions(const uint_fast64_t stateID, std::list>>& res); /*! * Explores reachable state from given state by using labeled transitions. @@ -138,7 +138,7 @@ private: * @param stateID State to be explored. * @param res Intermediate transition map. */ - void addLabeledTransitions(const uint_fast64_t stateID, std::list>& res); + void addLabeledTransitions(const uint_fast64_t stateID, std::list>>& res); /*! * Create matrix from intermediate mapping, assuming it is a dtmc model. @@ -161,7 +161,9 @@ private: * Afterwards, we transform this map into the actual matrix. * @return result matrix. */ - void buildIntermediateRepresentation(); + void buildTransitionMap(); + + void clearInternalState(); // Program that should be converted. std::shared_ptr program; @@ -171,15 +173,22 @@ private: std::map integerVariableToIndexMap; // Members that are filled during the conversion. + storm::ir::RewardModel rewardModel; std::vector allStates; std::unordered_map stateToIndexMap; uint_fast64_t numberOfTransitions; uint_fast64_t numberOfChoices; - std::map>> transitionMap; + std::shared_ptr> transitionRewards; + + /*! + * Maps a source node to a list of probability distributions over target nodes. + * Each such distribution corresponds to an unlabeled command or a feasible combination of labeled commands. + * Therefore, each distribution is represented by a label and a mapping from target nodes to their probabilities. + */ + std::map>>> transitionMap; }; } // namespace adapters } // namespace storm #endif /* EXPLICITMODELADAPTER_H */ - From e4129c37d9595b2383084f1d9bf5da5c5330c5dd Mon Sep 17 00:00:00 2001 From: gereon Date: Fri, 15 Mar 2013 15:33:31 +0100 Subject: [PATCH 070/152] fixed two bugs in ExplicitModelAdapter. --- src/adapters/ExplicitModelAdapter.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index 9f2b6ff10..24dba6d27 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -36,7 +36,9 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { std::shared_ptr ExplicitModelAdapter::getModel(std::string const & rewardModelName) { - this->rewardModel = this->program->getRewardModel(rewardModelName); + if (rewardModelName != "") { + this->rewardModel = this->program->getRewardModel(rewardModelName); + } this->buildTransitionMap(); @@ -436,7 +438,9 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { double factor = 1.0 / transitionMap[state].size(); for (auto it : map) { result->addNextValue(state, it.first, it.second * factor); - this->transitionRewards->addNextValue(state, it.first, rewardMap[it.first] * factor); + if (this->rewardModel.hasTransitionRewards()) { + this->transitionRewards->addNextValue(state, it.first, rewardMap[it.first] * factor); + } } } From 7ce537adca2dc4c6d6633d6bdf263688eae9a385 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 26 Mar 2013 10:05:24 +0100 Subject: [PATCH 071/152] Adding testbed for prismparser --- src/storm.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/storm.cpp b/src/storm.cpp index 2fc723034..bcdf399d7 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -41,6 +41,18 @@ #include "src/exceptions/InvalidSettingsException.h" +#include +#include +#include + +void printUsage() { + struct rusage ru; + getrusage(RUSAGE_SELF, &ru); + + std::cout << "Memory Usage: " << ru.ru_maxrss << "kB" << std::endl; +} + + log4cplus::Logger logger; /*! @@ -238,16 +250,17 @@ int main(const int argc, const char* argv[]) { // printHeader(argc, argv); // testChecking(); - + storm::settings::Settings* s = storm::settings::instance(); storm::parser::PrismParser parser; - std::shared_ptr program = parser.parseFile("examples/dtmc/die/die.pm"); + std::shared_ptr program = parser.parseFile(s->getString("trafile")); storm::adapters::ExplicitModelAdapter explicitModelAdapter(program); - std::shared_ptr> matrix = explicitModelAdapter.toSparseMatrix(); - - std::shared_ptr secondProgram = parser.parseFile("examples/dtmc/crowds/crowds5_5.pm"); - storm::adapters::ExplicitModelAdapter secondExplicitModelAdapter(secondProgram); - std::shared_ptr> secondMatrix = secondExplicitModelAdapter.toSparseMatrix(); + std::shared_ptr model = explicitModelAdapter.getModel(); + if (model->getType() == storm::models::DTMC) { + std::shared_ptr> dtmc = model->as>(); + dtmc->printModelInformationToStream(std::cout); + } + printUsage(); cleanUp(); return 0; } From e55fca38364f7046f9c2572f80ad8cf3556deb55 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 26 Mar 2013 18:59:05 +0100 Subject: [PATCH 072/152] Implemented module renaming. This includes clone() routines (that accept the renaming information) for all ir::expressions classes, additional constructors for all ir classes and additional rules in PrismParser. This is the first version that has the chance to work and actually compiles. (Insert some swearing here...) Testing is to be done, as this will most probably not work yet. --- src/ir/Assignment.cpp | 7 +++ src/ir/Assignment.h | 2 + src/ir/BooleanVariable.cpp | 3 ++ src/ir/BooleanVariable.h | 8 +-- src/ir/Command.cpp | 13 ++++- src/ir/Command.h | 4 +- src/ir/IntegerVariable.cpp | 3 ++ src/ir/IntegerVariable.h | 4 +- src/ir/Module.cpp | 53 +++++++++++++++---- src/ir/Module.h | 22 +++++++- src/ir/Update.cpp | 18 +++++++ src/ir/Update.h | 2 + src/ir/Variable.cpp | 5 ++ src/ir/Variable.h | 7 +++ src/ir/expressions/BaseExpression.h | 6 ++- .../BinaryBooleanFunctionExpression.h | 4 ++ src/ir/expressions/BinaryExpression.h | 5 +- .../BinaryNumericalFunctionExpression.h | 4 ++ src/ir/expressions/BinaryRelationExpression.h | 4 ++ .../expressions/BooleanConstantExpression.h | 4 ++ src/ir/expressions/BooleanLiteral.h | 6 ++- src/ir/expressions/DoubleConstantExpression.h | 4 ++ src/ir/expressions/DoubleLiteral.h | 4 ++ .../expressions/IntegerConstantExpression.h | 4 ++ src/ir/expressions/IntegerLiteral.h | 6 ++- .../UnaryBooleanFunctionExpression.h | 4 ++ .../UnaryNumericalFunctionExpression.h | 4 ++ src/ir/expressions/VariableExpression.h | 17 ++++++ src/parser/PrismParser.cpp | 46 +++++++++++++++- src/parser/PrismParser.h | 1 + 30 files changed, 248 insertions(+), 26 deletions(-) diff --git a/src/ir/Assignment.cpp b/src/ir/Assignment.cpp index 095a922f3..232472857 100644 --- a/src/ir/Assignment.cpp +++ b/src/ir/Assignment.cpp @@ -24,6 +24,13 @@ Assignment::Assignment(std::string variableName, std::shared_ptr& renaming, const std::map& bools, const std::map& ints) + : variableName(assignment.variableName), expression(assignment.expression->clone(renaming, bools, ints)) { + if (renaming.count(assignment.variableName) > 0) { + this->variableName = renaming.at(assignment.variableName); + } +} + // Returns the name of the variable associated with this assignment. std::string const& Assignment::getVariableName() const { return variableName; diff --git a/src/ir/Assignment.h b/src/ir/Assignment.h index 019cc55eb..b17693bf0 100644 --- a/src/ir/Assignment.h +++ b/src/ir/Assignment.h @@ -33,6 +33,8 @@ public: */ Assignment(std::string variableName, std::shared_ptr expression); + Assignment(const Assignment& assignment, const std::map& renaming, const std::map& bools, const std::map& ints); + /*! * Retrieves the name of the variable that this assignment targets. * @returns the name of the variable that this assignment targets. diff --git a/src/ir/BooleanVariable.cpp b/src/ir/BooleanVariable.cpp index b867a1aa1..4ef83a879 100644 --- a/src/ir/BooleanVariable.cpp +++ b/src/ir/BooleanVariable.cpp @@ -25,6 +25,9 @@ BooleanVariable::BooleanVariable(uint_fast64_t index, std::string variableName, // Nothing to do here. } +BooleanVariable::BooleanVariable(const BooleanVariable& var, const std::string& newName) : Variable(var, newName) { +} + // Build a string representation of the variable. std::string BooleanVariable::toString() const { std::stringstream result; diff --git a/src/ir/BooleanVariable.h b/src/ir/BooleanVariable.h index 9c5ba17c0..fcf5ce602 100644 --- a/src/ir/BooleanVariable.h +++ b/src/ir/BooleanVariable.h @@ -8,10 +8,9 @@ #ifndef STORM_IR_BOOLEANVARIABLE_H_ #define STORM_IR_BOOLEANVARIABLE_H_ -#include "expressions/BooleanLiteral.h" - -#include "Variable.h" +#include "src/ir/Variable.h" #include +#include namespace storm { @@ -35,6 +34,9 @@ public: */ BooleanVariable(uint_fast64_t index, std::string variableName, std::shared_ptr initialValue = std::shared_ptr(nullptr)); + + BooleanVariable(const BooleanVariable& var, const std::string& newName); + /*! * Retrieves a string representation of this variable. * @returns a string representation of this variable. diff --git a/src/ir/Command.cpp b/src/ir/Command.cpp index bec67d4bf..b34ab60ed 100644 --- a/src/ir/Command.cpp +++ b/src/ir/Command.cpp @@ -20,10 +20,21 @@ Command::Command() : actionName(), guardExpression(), updates() { // Initializes all members according to the given values. Command::Command(std::string actionName, std::shared_ptr guardExpression, std::vector updates) - : actionName(actionName), guardExpression(guardExpression), updates(updates) { + : actionName(actionName), guardExpression(guardExpression), updates(updates) { // Nothing to do here. } +Command::Command(const Command& cmd, const std::map& renaming, const std::map& bools, const std::map& ints) + : actionName(cmd.actionName), guardExpression(cmd.guardExpression->clone(renaming, bools, ints)) { + if (renaming.count(this->actionName) > 0) { + this->actionName = renaming.at(this->actionName); + } + this->updates.reserve(cmd.updates.size()); + for (Update u : cmd.updates) { + this->updates.emplace_back(u, renaming, bools, ints); + } +} + // Return the action name. std::string const& Command::getActionName() const { return this->actionName; diff --git a/src/ir/Command.h b/src/ir/Command.h index 9207c76f0..b4049307c 100644 --- a/src/ir/Command.h +++ b/src/ir/Command.h @@ -13,6 +13,7 @@ #include #include +#include namespace storm { @@ -34,7 +35,8 @@ public: * @param guardExpression the expression that defines the guard of the command. */ Command(std::string actionName, std::shared_ptr guardExpression, std::vector updates); - + + Command(const Command& cmd, const std::map& renaming, const std::map& bools, const std::map& ints); /*! * Retrieves the action name of this command. * @returns the action name of this command. diff --git a/src/ir/IntegerVariable.cpp b/src/ir/IntegerVariable.cpp index b07316b65..d96b2221b 100644 --- a/src/ir/IntegerVariable.cpp +++ b/src/ir/IntegerVariable.cpp @@ -27,6 +27,9 @@ IntegerVariable::IntegerVariable(uint_fast64_t index, std::string variableName, } } +IntegerVariable::IntegerVariable(const IntegerVariable& var, const std::string& newName) : Variable(var, newName) { +} + // Return lower bound for variable. std::shared_ptr IntegerVariable::getLowerBound() const { return this->lowerBound; diff --git a/src/ir/IntegerVariable.h b/src/ir/IntegerVariable.h index a05ef1d7e..a31ece3e5 100644 --- a/src/ir/IntegerVariable.h +++ b/src/ir/IntegerVariable.h @@ -9,7 +9,7 @@ #define STORM_IR_INTEGERVARIABLE_H_ #include "expressions/BaseExpression.h" -#include "Variable.h" +#include "src/ir/Variable.h" #include namespace storm { @@ -37,6 +37,8 @@ public: */ IntegerVariable(uint_fast64_t index, std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue = std::shared_ptr(nullptr)); + IntegerVariable(const IntegerVariable& var, const std::string& newName); + /*! * Retrieves the lower bound for this integer variable. * @returns the lower bound for this integer variable. diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index 9a2337f8a..dcacfe198 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -10,6 +10,7 @@ #include "src/exceptions/InvalidArgumentException.h" #include +#include namespace storm { @@ -30,17 +31,34 @@ Module::Module(std::string moduleName, std::vector b : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), booleanVariablesToIndexMap(booleanVariableToIndexMap), integerVariablesToIndexMap(integerVariableToIndexMap), commands(commands), actions(), actionsToCommandIndexMap() { - // Build actionsToCommandIndexMap - for (unsigned int id = 0; id < this->commands.size(); id++) { - std::string action = this->commands[id].getActionName(); - if (action != "") { - if (this->actionsToCommandIndexMap.count(action) == 0) { - this->actionsToCommandIndexMap[action] = std::shared_ptr>(new std::set()); - } - this->actionsToCommandIndexMap[action]->insert(id); - this->actions.insert(action); - } - } + this->collectActions(); +} + +Module::Module(const Module& module, const std::string& moduleName, const std::map& renaming, const VariableAdder& adder) + : moduleName(moduleName) { + this->booleanVariables.reserve(module.booleanVariables.size()); + for (BooleanVariable it: module.booleanVariables) { + if (renaming.count(it.getName()) > 0) { + this->booleanVariables.emplace_back(it, renaming.at(it.getName())); + //this->booleanVariablesToIndexMap[renaming.at(it.getName())] = (*boolAdder)(it.getName(), it.getInitialValue()); + this->booleanVariablesToIndexMap[renaming.at(it.getName())] = adder.addBooleanVariable(it.getName(), it.getInitialValue()); + } else std::cerr << "ERROR: " << moduleName << "." << it.getName() << " was not renamed!" << std::endl; + } + this->integerVariables.reserve(module.integerVariables.size()); + for (IntegerVariable it: module.integerVariables) { + if (renaming.count(it.getName()) > 0) { + this->integerVariables.emplace_back(it, renaming.at(it.getName())); + //this->integerVariablesToIndexMap[renaming.at(it.getName())] = (*intAdder)(it.getName(), it.getLowerBound(), it.getUpperBound(), it.getInitialValue()); + this->integerVariablesToIndexMap[renaming.at(it.getName())] = adder.addIntegerVariable(it.getName(), it.getLowerBound(), it.getUpperBound(), it.getInitialValue()); + } else std::cerr << "ERROR: " << moduleName << "." << it.getName() << " was not renamed!" << std::endl; + } + + this->commands.reserve(module.commands.size()); + for (Command cmd: module.commands) { + this->commands.emplace_back(cmd, renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap); + } + + this->collectActions(); } // Return the number of boolean variables. @@ -125,6 +143,19 @@ std::shared_ptr> const Module::getCommandsByAction(std:: } } +void Module::collectActions() { + for (unsigned int id = 0; id < this->commands.size(); id++) { + std::string action = this->commands[id].getActionName(); + if (action != "") { + if (this->actionsToCommandIndexMap.count(action) == 0) { + this->actionsToCommandIndexMap[action] = std::shared_ptr>(new std::set()); + } + this->actionsToCommandIndexMap[action]->insert(id); + this->actions.insert(action); + } + } +} + } // namespace ir } // namespace storm diff --git a/src/ir/Module.h b/src/ir/Module.h index 4070846f5..8991062ec 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -22,6 +22,11 @@ namespace storm { namespace ir { + struct VariableAdder { + virtual uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init) const = 0; + virtual uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init) const = 0; + }; + /*! * A class representing a module. */ @@ -45,6 +50,18 @@ public: std::map integerVariableToIndexMap, std::vector commands); + typedef uint_fast64_t (*addIntegerVariablePtr)(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init); + typedef uint_fast64_t (*addBooleanVariablePtr)(const std::string& name, const std::shared_ptr init); + + /*! + * Special copy constructor, implementing the module renaming functionality. + * This will create a new module having all identifier renamed according to the given map. + * @param module Module to be copied. + * @param moduleName Name of the new module. + * @param renaming Renaming map. + */ + Module(const Module& module, const std::string& moduleName, const std::map& renaming, const VariableAdder& adder); + /*! * Retrieves the number of boolean variables in the module. * @returns the number of boolean variables in the module. @@ -116,6 +133,9 @@ public: std::shared_ptr> const getCommandsByAction(std::string const& action) const; private: + + void collectActions(); + // The name of the module. std::string moduleName; @@ -137,7 +157,7 @@ private: // The set of actions present in this module. std::set actions; - // A map of actions to the set of commands labelled with this action. + // A map of actions to the set of commands labeled with this action. std::map>> actionsToCommandIndexMap; }; diff --git a/src/ir/Update.cpp b/src/ir/Update.cpp index edacb6fe9..2d0dc5d2a 100644 --- a/src/ir/Update.cpp +++ b/src/ir/Update.cpp @@ -26,6 +26,24 @@ Update::Update(std::shared_ptr likelihoo // Nothing to do here. } +Update::Update(const Update& update, const std::map& renaming, const std::map& bools, const std::map& ints) { + for (auto it : update.booleanAssignments) { + if (renaming.count(it.first) > 0) { + this->booleanAssignments[renaming.at(it.first)] = Assignment(it.second, renaming, bools, ints); + } else { + this->booleanAssignments[it.first] = Assignment(it.second, renaming, bools, ints); + } + } + for (auto it : update.integerAssignments) { + if (renaming.count(it.first) > 0) { + this->integerAssignments[renaming.at(it.first)] = Assignment(it.second, renaming, bools, ints); + } else { + this->integerAssignments[it.first] = Assignment(it.second, renaming, bools, ints); + } + } + this->likelihoodExpression = update.likelihoodExpression->clone(renaming, bools, ints); +} + // Return the expression for the likelihood of the update. std::shared_ptr const& Update::getLikelihoodExpression() const { return likelihoodExpression; diff --git a/src/ir/Update.h b/src/ir/Update.h index 54ddc5cd8..4ce6a2fbf 100644 --- a/src/ir/Update.h +++ b/src/ir/Update.h @@ -36,6 +36,8 @@ public: */ Update(std::shared_ptr likelihoodExpression, std::map booleanAssignments, std::map integerAssignments); + Update(const Update& update, const std::map& renaming, const std::map& bools, const std::map& ints); + /*! * Retrieves the expression for the likelihood of this update. * @returns the expression for the likelihood of this update. diff --git a/src/ir/Variable.cpp b/src/ir/Variable.cpp index 19d7f211f..caef3aad0 100644 --- a/src/ir/Variable.cpp +++ b/src/ir/Variable.cpp @@ -8,6 +8,7 @@ #include "Variable.h" #include +#include namespace storm { @@ -23,6 +24,10 @@ Variable::Variable(uint_fast64_t index, std::string variableName, std::shared_pt // Nothing to do here. } +Variable::Variable(const Variable& var, const std::string& newName) : Variable(var.index, newName, var.initialValue) { + // Nothing to do here +} + // Return the name of the variable. std::string const& Variable::getName() const { return variableName; diff --git a/src/ir/Variable.h b/src/ir/Variable.h index 6f31280e2..2348346c3 100644 --- a/src/ir/Variable.h +++ b/src/ir/Variable.h @@ -35,6 +35,13 @@ public: */ Variable(uint_fast64_t index, std::string variableName, std::shared_ptr initialValue = std::shared_ptr()); + /*! + * Creates a copy of the given Variable and gives it a new name. + * @param var Variable to copy. + * @param newName New name of this variable. + */ + Variable(const Variable& var, const std::string& newName); + /*! * Retrieves the name of the variable. * @returns the name of the variable. diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h index 3f93607ba..563037266 100644 --- a/src/ir/expressions/BaseExpression.h +++ b/src/ir/expressions/BaseExpression.h @@ -15,11 +15,11 @@ #include #include +#include +#include namespace storm { - namespace ir { - namespace expressions { class BaseExpression { @@ -39,6 +39,8 @@ public: } + virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) = 0; + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { if (type != int_) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '" diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.h b/src/ir/expressions/BinaryBooleanFunctionExpression.h index 85c927c60..dc1dc1147 100644 --- a/src/ir/expressions/BinaryBooleanFunctionExpression.h +++ b/src/ir/expressions/BinaryBooleanFunctionExpression.h @@ -31,6 +31,10 @@ public: } + virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + return std::shared_ptr(new BinaryBooleanFunctionExpression(this->getLeft()->clone(renaming, bools, ints), this->getRight()->clone(renaming, bools, ints), this->functionType)); + } + virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { bool resultLeft = this->getLeft()->getValueAsBool(variableValues); bool resultRight = this->getRight()->getValueAsBool(variableValues); diff --git a/src/ir/expressions/BinaryExpression.h b/src/ir/expressions/BinaryExpression.h index c5b4ba9f5..de0b1d8ab 100644 --- a/src/ir/expressions/BinaryExpression.h +++ b/src/ir/expressions/BinaryExpression.h @@ -8,7 +8,7 @@ #ifndef STORM_IR_EXPRESSIONS_BINARYEXPRESSION_H_ #define STORM_IR_EXPRESSIONS_BINARYEXPRESSION_H_ -#include "BaseExpression.h" +#include "src/ir/expressions/BaseExpression.h" #include namespace storm { @@ -19,7 +19,8 @@ namespace expressions { class BinaryExpression : public BaseExpression { public: - BinaryExpression(ReturnType type, std::shared_ptr left, std::shared_ptr right) : BaseExpression(type), left(left), right(right) { + BinaryExpression(ReturnType type, std::shared_ptr left, std::shared_ptr right) + : BaseExpression(type), left(left), right(right) { } diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h index 153f4331d..49d2c9494 100644 --- a/src/ir/expressions/BinaryNumericalFunctionExpression.h +++ b/src/ir/expressions/BinaryNumericalFunctionExpression.h @@ -24,6 +24,10 @@ public: } + virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + return std::shared_ptr(new BinaryNumericalFunctionExpression(this->getType(), this->getLeft()->clone(renaming, bools, ints), this->getRight()->clone(renaming, bools, ints), this->functionType)); + } + virtual ~BinaryNumericalFunctionExpression() { } diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h index 1a60cd34d..38a09b179 100644 --- a/src/ir/expressions/BinaryRelationExpression.h +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -28,6 +28,10 @@ public: } + virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + return std::shared_ptr(new BinaryRelationExpression(this->getLeft()->clone(renaming, bools, ints), this->getRight()->clone(renaming, bools, ints), this->relationType)); + } + virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { int_fast64_t resultLeft = this->getLeft()->getValueAsInt(variableValues); int_fast64_t resultRight = this->getRight()->getValueAsInt(variableValues); diff --git a/src/ir/expressions/BooleanConstantExpression.h b/src/ir/expressions/BooleanConstantExpression.h index 858fe0c12..15dcd9d4b 100644 --- a/src/ir/expressions/BooleanConstantExpression.h +++ b/src/ir/expressions/BooleanConstantExpression.h @@ -29,6 +29,10 @@ public: } + virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + return std::shared_ptr(this); + } + virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { if (!defined) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " diff --git a/src/ir/expressions/BooleanLiteral.h b/src/ir/expressions/BooleanLiteral.h index 04f40285f..696deb787 100644 --- a/src/ir/expressions/BooleanLiteral.h +++ b/src/ir/expressions/BooleanLiteral.h @@ -11,9 +11,7 @@ #include "src/ir/expressions/BaseExpression.h" namespace storm { - namespace ir { - namespace expressions { class BooleanLiteral : public BaseExpression { @@ -28,6 +26,10 @@ public: } + virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + return std::shared_ptr(this); + } + virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { return value; } diff --git a/src/ir/expressions/DoubleConstantExpression.h b/src/ir/expressions/DoubleConstantExpression.h index a027afa17..a0c31efbe 100644 --- a/src/ir/expressions/DoubleConstantExpression.h +++ b/src/ir/expressions/DoubleConstantExpression.h @@ -26,6 +26,10 @@ public: } + virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + return std::shared_ptr(this); + } + virtual double getValueAsDouble(std::pair, std::vector> const* variableValues) const { if (!defined) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " diff --git a/src/ir/expressions/DoubleLiteral.h b/src/ir/expressions/DoubleLiteral.h index 72c464100..efa0d1bb5 100644 --- a/src/ir/expressions/DoubleLiteral.h +++ b/src/ir/expressions/DoubleLiteral.h @@ -30,6 +30,10 @@ public: } + virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + return std::shared_ptr(this); + } + virtual double getValueAsDouble(std::pair, std::vector> const* variableValues) const { return value; } diff --git a/src/ir/expressions/IntegerConstantExpression.h b/src/ir/expressions/IntegerConstantExpression.h index 8c58260f6..01d8f2d71 100644 --- a/src/ir/expressions/IntegerConstantExpression.h +++ b/src/ir/expressions/IntegerConstantExpression.h @@ -26,6 +26,10 @@ public: } + virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + return std::shared_ptr(this); + } + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { if (!defined) { throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: " diff --git a/src/ir/expressions/IntegerLiteral.h b/src/ir/expressions/IntegerLiteral.h index a5130bd5e..8911f640a 100644 --- a/src/ir/expressions/IntegerLiteral.h +++ b/src/ir/expressions/IntegerLiteral.h @@ -28,6 +28,10 @@ public: } + virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + return std::shared_ptr(this); + } + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { return value; } @@ -35,7 +39,7 @@ public: virtual void accept(ExpressionVisitor* visitor) { visitor->visit(this); } - + virtual std::string toString() const { return boost::lexical_cast(value); } diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.h b/src/ir/expressions/UnaryBooleanFunctionExpression.h index 26b448548..73b9969a7 100644 --- a/src/ir/expressions/UnaryBooleanFunctionExpression.h +++ b/src/ir/expressions/UnaryBooleanFunctionExpression.h @@ -28,6 +28,10 @@ public: } + virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + return std::shared_ptr(new UnaryBooleanFunctionExpression(this->getChild()->clone(renaming, bools, ints), this->functionType)); + } + FunctionType getFunctionType() const { return functionType; } diff --git a/src/ir/expressions/UnaryNumericalFunctionExpression.h b/src/ir/expressions/UnaryNumericalFunctionExpression.h index 2a1f02125..0556892f2 100644 --- a/src/ir/expressions/UnaryNumericalFunctionExpression.h +++ b/src/ir/expressions/UnaryNumericalFunctionExpression.h @@ -28,6 +28,10 @@ public: } + virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + return std::shared_ptr(new UnaryNumericalFunctionExpression(this->getType(), this->getChild()->clone(renaming, bools, ints), this->functionType)); + } + virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { if (this->getType() != int_) { BaseExpression::getValueAsInt(variableValues); diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index 1b9dfd46b..bbdb11ea6 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -33,6 +33,23 @@ public: } + virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + if (renaming.count(this->variableName) > 0) { + std::string newName = renaming.at(this->variableName); + if (this->getType() == bool_) { + return std::shared_ptr(new VariableExpression(bool_, bools.at(newName), newName, this->lowerBound, this->upperBound)); + } else if (this->getType() == int_) { + return std::shared_ptr(new VariableExpression(int_, ints.at(newName), newName, this->lowerBound, this->upperBound)); + } else { + std::cerr << "ERROR: Renaming variable " << this->variableName << " that is neither bool nor int." << std::endl; + return std::shared_ptr(this); + } + } else { + return std::shared_ptr(this); + } + } + + virtual void accept(ExpressionVisitor* visitor) { visitor->visit(this); } diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index e9bd368eb..948f32ad6 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -222,8 +222,28 @@ struct PrismParser::PrismGrammar : qi::grammar freeIdentifierName > *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) > +commandDefinition > qi::lit("endmodule"))[phoenix::bind(moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2)]; + moduleDefinition = (qi::lit("module") + [phoenix::clear(phoenix::ref(localBooleanVariables_)), phoenix::clear(phoenix::ref(localIntegerVariables_))] + >> freeIdentifierName >> *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) > +commandDefinition > qi::lit("endmodule")) + [ + phoenix::bind(moduleNames_.add, qi::_1, qi::_1), + qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2), + phoenix::bind(moduleMap_.add, qi::_1, qi::_val) + ]; + + Module const * (qi::symbols::*moduleFinder)(const std::string&) const = &qi::symbols::find; moduleDefinition.name("module"); + moduleRenaming = (qi::lit("module") + [phoenix::clear(phoenix::ref(localRenamings_))] + >> freeIdentifierName >> qi::lit("=") > moduleNames_ > qi::lit("[") > *( + (identifierName > qi::lit("=") > identifierName)[phoenix::insert(phoenix::ref(localRenamings_), phoenix::construct>(qi::_1, qi::_2))] + ) > qi::lit("]") > qi::lit("endmodule")) + [ + phoenix::bind(moduleNames_.add, qi::_1, qi::_1), + qi::_val = phoenix::construct(*phoenix::bind(moduleFinder, moduleMap_, qi::_2), qi::_1, localRenamings_, VariableAdder(this)), + phoenix::bind(moduleMap_.add, qi::_1, qi::_val) + + ]; moduleDefinitionList %= +moduleDefinition; moduleDefinitionList.name("module list"); @@ -268,6 +288,26 @@ struct PrismParser::PrismGrammar : qi::grammar lower, const std::shared_ptr upper, const std::shared_ptr init) const { + std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::int_, grammar->nextIntegerVariableIndex, name, lower, upper)); + grammar->integerVariables_.add(name, varExpr); + grammar->integerVariableNames_.add(name, name); + grammar->nextIntegerVariableIndex++; + return grammar->nextIntegerVariableIndex-1; + } + + uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init) const { + std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::bool_, grammar->nextBooleanVariableIndex, name)); + grammar->integerVariables_.add(name, varExpr); + grammar->integerVariableNames_.add(name, name); + grammar->nextBooleanVariableIndex++; + return grammar->nextBooleanVariableIndex-1; + } + }; void prepareForSecondRun() { // Clear constants. @@ -317,6 +357,7 @@ struct PrismParser::PrismGrammar : qi::grammar, std::vector, std::map, std::map>, Skipper> moduleDefinition; + qi::rule, std::vector, std::map, std::map>, Skipper> moduleRenaming; // Rules for variable definitions. qi::rule&, std::vector&, std::map&, std::map&), Skipper> variableDefinition; @@ -469,6 +510,9 @@ struct PrismParser::PrismGrammar : qi::grammar> integerVariables_, booleanVariables_; struct qi::symbols> integerConstants_, booleanConstants_, doubleConstants_; + struct qi::symbols moduleMap_; + + std::map localRenamings_; // A structure representing the identity function over identifier names. struct variableNamesStruct : qi::symbols { } integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_, diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index f4a563e37..1fca04c55 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -13,6 +13,7 @@ // Used for file input. #include +#include namespace storm { From 840a9b6e078035dd8b887c11984cf7f8b0313642 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 26 Mar 2013 20:15:12 +0100 Subject: [PATCH 073/152] Somewhat works now. Still has at least one bug and segfaults afterwards :-) --- src/ir/BooleanVariable.cpp | 3 ++- src/ir/BooleanVariable.h | 2 +- src/ir/IntegerVariable.cpp | 8 ++++--- src/ir/IntegerVariable.h | 2 +- src/ir/Module.cpp | 20 ++++++++++++++---- src/ir/Variable.cpp | 6 ++++-- src/ir/Variable.h | 2 +- src/ir/expressions/BinaryRelationExpression.h | 2 ++ src/ir/expressions/VariableExpression.h | 1 + src/parser/PrismParser.cpp | 21 +++++++++---------- 10 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/ir/BooleanVariable.cpp b/src/ir/BooleanVariable.cpp index 4ef83a879..f233100cd 100644 --- a/src/ir/BooleanVariable.cpp +++ b/src/ir/BooleanVariable.cpp @@ -25,7 +25,8 @@ BooleanVariable::BooleanVariable(uint_fast64_t index, std::string variableName, // Nothing to do here. } -BooleanVariable::BooleanVariable(const BooleanVariable& var, const std::string& newName) : Variable(var, newName) { +BooleanVariable::BooleanVariable(const BooleanVariable& var, const std::string& newName, const std::map& renaming, const std::map& bools, const std::map& ints) + : Variable(var, newName, renaming, bools, ints) { } // Build a string representation of the variable. diff --git a/src/ir/BooleanVariable.h b/src/ir/BooleanVariable.h index fcf5ce602..bf70f01d1 100644 --- a/src/ir/BooleanVariable.h +++ b/src/ir/BooleanVariable.h @@ -35,7 +35,7 @@ public: BooleanVariable(uint_fast64_t index, std::string variableName, std::shared_ptr initialValue = std::shared_ptr(nullptr)); - BooleanVariable(const BooleanVariable& var, const std::string& newName); + BooleanVariable(const BooleanVariable& var, const std::string& newName, const std::map& renaming, const std::map& bools, const std::map& ints); /*! * Retrieves a string representation of this variable. diff --git a/src/ir/IntegerVariable.cpp b/src/ir/IntegerVariable.cpp index d96b2221b..f98ff8861 100644 --- a/src/ir/IntegerVariable.cpp +++ b/src/ir/IntegerVariable.cpp @@ -21,13 +21,15 @@ IntegerVariable::IntegerVariable() : lowerBound(), upperBound() { } // Initializes all members according to the given values. -IntegerVariable::IntegerVariable(uint_fast64_t index, std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue) : Variable(index, variableName, initialValue), lowerBound(lowerBound), upperBound(upperBound) { +IntegerVariable::IntegerVariable(uint_fast64_t index, std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue) + : Variable(index, variableName, initialValue), lowerBound(lowerBound), upperBound(upperBound) { if (this->getInitialValue() == nullptr) { this->setInitialValue(lowerBound); } } -IntegerVariable::IntegerVariable(const IntegerVariable& var, const std::string& newName) : Variable(var, newName) { +IntegerVariable::IntegerVariable(const IntegerVariable& var, const std::string& newName, const std::map& renaming, const std::map& bools, const std::map& ints) + : Variable(var, newName, renaming, bools, ints), lowerBound(var.lowerBound->clone(renaming, bools, ints)), upperBound(var.upperBound->clone(renaming, bools, ints)) { } // Return lower bound for variable. @@ -44,7 +46,7 @@ std::shared_ptr IntegerVariable::getUppe // Build a string representation of the variable. std::string IntegerVariable::toString() const { std::stringstream result; - result << this->getName() << ": [" << lowerBound->toString() << ".." << upperBound->toString() << "]"; + result << "int_" << this->getName() << ": [" << lowerBound->toString() << ".." << upperBound->toString() << "]"; if (this->getInitialValue() != nullptr) { result << " init " + this->getInitialValue()->toString(); } diff --git a/src/ir/IntegerVariable.h b/src/ir/IntegerVariable.h index a31ece3e5..8233cbe09 100644 --- a/src/ir/IntegerVariable.h +++ b/src/ir/IntegerVariable.h @@ -37,7 +37,7 @@ public: */ IntegerVariable(uint_fast64_t index, std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue = std::shared_ptr(nullptr)); - IntegerVariable(const IntegerVariable& var, const std::string& newName); + IntegerVariable(const IntegerVariable& var, const std::string& newName, const std::map& renaming, const std::map& bools, const std::map& ints); /*! * Retrieves the lower bound for this integer variable. diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index dcacfe198..592c92164 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -36,22 +36,34 @@ Module::Module(std::string moduleName, std::vector b Module::Module(const Module& module, const std::string& moduleName, const std::map& renaming, const VariableAdder& adder) : moduleName(moduleName) { + std::cout << "Renaming module " << module.moduleName << " to " << moduleName << " with " << renaming.size() << " renamings:" << std::endl; + for (auto it: renaming) { + std::cout << "\t" << it.first << " -> " << it.second << std::endl; + } this->booleanVariables.reserve(module.booleanVariables.size()); for (BooleanVariable it: module.booleanVariables) { if (renaming.count(it.getName()) > 0) { - this->booleanVariables.emplace_back(it, renaming.at(it.getName())); - //this->booleanVariablesToIndexMap[renaming.at(it.getName())] = (*boolAdder)(it.getName(), it.getInitialValue()); this->booleanVariablesToIndexMap[renaming.at(it.getName())] = adder.addBooleanVariable(it.getName(), it.getInitialValue()); } else std::cerr << "ERROR: " << moduleName << "." << it.getName() << " was not renamed!" << std::endl; } this->integerVariables.reserve(module.integerVariables.size()); for (IntegerVariable it: module.integerVariables) { if (renaming.count(it.getName()) > 0) { - this->integerVariables.emplace_back(it, renaming.at(it.getName())); - //this->integerVariablesToIndexMap[renaming.at(it.getName())] = (*intAdder)(it.getName(), it.getLowerBound(), it.getUpperBound(), it.getInitialValue()); this->integerVariablesToIndexMap[renaming.at(it.getName())] = adder.addIntegerVariable(it.getName(), it.getLowerBound(), it.getUpperBound(), it.getInitialValue()); } else std::cerr << "ERROR: " << moduleName << "." << it.getName() << " was not renamed!" << std::endl; } + this->booleanVariables.reserve(module.booleanVariables.size()); + for (BooleanVariable it: module.booleanVariables) { + if (renaming.count(it.getName()) > 0) { + this->booleanVariables.emplace_back(it, renaming.at(it.getName()), renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap); + } else std::cerr << "ERROR: " << moduleName << "." << it.getName() << " was not renamed!" << std::endl; + } + this->integerVariables.reserve(module.integerVariables.size()); + for (IntegerVariable it: module.integerVariables) { + if (renaming.count(it.getName()) > 0) { + this->integerVariables.emplace_back(it, renaming.at(it.getName()), renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap); + } else std::cerr << "ERROR: " << moduleName << "." << it.getName() << " was not renamed!" << std::endl; + } this->commands.reserve(module.commands.size()); for (Command cmd: module.commands) { diff --git a/src/ir/Variable.cpp b/src/ir/Variable.cpp index caef3aad0..1d762b4b4 100644 --- a/src/ir/Variable.cpp +++ b/src/ir/Variable.cpp @@ -9,6 +9,7 @@ #include #include +#include namespace storm { @@ -24,8 +25,9 @@ Variable::Variable(uint_fast64_t index, std::string variableName, std::shared_pt // Nothing to do here. } -Variable::Variable(const Variable& var, const std::string& newName) : Variable(var.index, newName, var.initialValue) { - // Nothing to do here +Variable::Variable(const Variable& var, const std::string& newName, const std::map& renaming, const std::map& bools, const std::map& ints) + : Variable(var.index, newName, var.initialValue->clone(renaming, bools, ints)) { + std::cout << "Cloning Variable " << var.variableName << " to " << newName << std::endl; } // Return the name of the variable. diff --git a/src/ir/Variable.h b/src/ir/Variable.h index 2348346c3..e144d06aa 100644 --- a/src/ir/Variable.h +++ b/src/ir/Variable.h @@ -40,7 +40,7 @@ public: * @param var Variable to copy. * @param newName New name of this variable. */ - Variable(const Variable& var, const std::string& newName); + Variable(const Variable& var, const std::string& newName, const std::map& renaming, const std::map& bools, const std::map& ints); /*! * Retrieves the name of the variable. diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h index 38a09b179..76471c17e 100644 --- a/src/ir/expressions/BinaryRelationExpression.h +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -9,6 +9,7 @@ #define BINARYRELATIONEXPRESSION_H_ #include "src/ir/expressions/BinaryExpression.h" +#include namespace storm { @@ -29,6 +30,7 @@ public: } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + std::cout << "Cloning " << this->getLeft()->toString() << " ~ " << this->getRight()->toString() << std::endl; return std::shared_ptr(new BinaryRelationExpression(this->getLeft()->clone(renaming, bools, ints), this->getRight()->clone(renaming, bools, ints), this->relationType)); } diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index bbdb11ea6..b7160f929 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -34,6 +34,7 @@ public: } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + std::cout << "Cloning VarExpr " << this->variableName << std::endl; if (renaming.count(this->variableName) > 0) { std::string newName = renaming.at(this->variableName); if (this->getType() == bool_) { diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 948f32ad6..8930f251e 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -222,9 +222,9 @@ struct PrismParser::PrismGrammar : qi::grammar> freeIdentifierName [phoenix::clear(phoenix::ref(localBooleanVariables_)), phoenix::clear(phoenix::ref(localIntegerVariables_))] - >> freeIdentifierName >> *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) > +commandDefinition > qi::lit("endmodule")) + >> *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) >> +commandDefinition > qi::lit("endmodule")) [ phoenix::bind(moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2), @@ -233,18 +233,18 @@ struct PrismParser::PrismGrammar : qi::grammar::*moduleFinder)(const std::string&) const = &qi::symbols::find; moduleDefinition.name("module"); - moduleRenaming = (qi::lit("module") - [phoenix::clear(phoenix::ref(localRenamings_))] - >> freeIdentifierName >> qi::lit("=") > moduleNames_ > qi::lit("[") > *( - (identifierName > qi::lit("=") > identifierName)[phoenix::insert(phoenix::ref(localRenamings_), phoenix::construct>(qi::_1, qi::_2))] + moduleRenaming = (qi::lit("module") >> freeIdentifierName >> qi::lit("=") + > moduleNames_ > qi::lit("[") > *( + (identifierName > qi::lit("=") > identifierName >> -qi::lit(","))[phoenix::insert(qi::_a, phoenix::construct>(qi::_1, qi::_2))] ) > qi::lit("]") > qi::lit("endmodule")) [ phoenix::bind(moduleNames_.add, qi::_1, qi::_1), - qi::_val = phoenix::construct(*phoenix::bind(moduleFinder, moduleMap_, qi::_2), qi::_1, localRenamings_, VariableAdder(this)), + qi::_val = phoenix::construct(*phoenix::bind(moduleFinder, moduleMap_, qi::_2), qi::_1, qi::_a, VariableAdder(this)), phoenix::bind(moduleMap_.add, qi::_1, qi::_val) ]; - moduleDefinitionList %= +moduleDefinition; + moduleRenaming.name("renamed module"); + moduleDefinitionList %= +(moduleDefinition | moduleRenaming); moduleDefinitionList.name("module list"); // This block defines all entities that are needed for parsing constant definitions. @@ -357,7 +357,7 @@ struct PrismParser::PrismGrammar : qi::grammar, std::vector, std::map, std::map>, Skipper> moduleDefinition; - qi::rule, std::vector, std::map, std::map>, Skipper> moduleRenaming; + qi::rule>, Skipper> moduleRenaming; // Rules for variable definitions. qi::rule&, std::vector&, std::map&, std::map&), Skipper> variableDefinition; @@ -512,8 +512,6 @@ struct PrismParser::PrismGrammar : qi::grammar> integerConstants_, booleanConstants_, doubleConstants_; struct qi::symbols moduleMap_; - std::map localRenamings_; - // A structure representing the identity function over identifier names. struct variableNamesStruct : qi::symbols { } integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_, localBooleanVariables_, localIntegerVariables_, assignedLocalBooleanVariables_, assignedLocalIntegerVariables_; @@ -575,6 +573,7 @@ std::shared_ptr PrismParser::parse(std::istream& inputStream result = std::shared_ptr(new storm::ir::Program()); // Second run. qi::phrase_parse(positionIteratorBegin2, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, *result); + std::cout << "Here is the parsed grammar: " << std::endl << result->toString() << std::endl; } catch(const qi::expectation_failure& e) { // If the parser expected content different than the one provided, display information // about the location of the error. From bb37bc49f285474b234fdb6017722bca8fb927a2 Mon Sep 17 00:00:00 2001 From: gereon Date: Wed, 10 Apr 2013 18:58:59 +0200 Subject: [PATCH 074/152] Compiling version of PrismParser. --- src/parser/PrismParser.cpp | 429 +++--------------- src/parser/PrismParser.h | 111 ++++- .../PrismParser/BooleanExpressionGrammar.cpp | 55 +++ .../PrismParser/BooleanExpressionGrammar.h | 66 +++ .../ConstBooleanExpressionGrammar.cpp | 32 ++ .../ConstBooleanExpressionGrammar.h | 49 ++ .../ConstIntegerExpressionGrammar.cpp | 30 ++ .../ConstIntegerExpressionGrammar.h | 38 ++ src/parser/PrismParser/Includes.h | 35 ++ .../PrismParser/IntegerExpressionGrammar.cpp | 46 ++ .../PrismParser/IntegerExpressionGrammar.h | 61 +++ src/parser/PrismParser/UtilityGrammars.h | 69 +++ src/parser/PrismParser/VariableState.h | 96 ++++ 13 files changed, 745 insertions(+), 372 deletions(-) create mode 100644 src/parser/PrismParser/BooleanExpressionGrammar.cpp create mode 100644 src/parser/PrismParser/BooleanExpressionGrammar.h create mode 100644 src/parser/PrismParser/ConstBooleanExpressionGrammar.cpp create mode 100644 src/parser/PrismParser/ConstBooleanExpressionGrammar.h create mode 100644 src/parser/PrismParser/ConstIntegerExpressionGrammar.cpp create mode 100644 src/parser/PrismParser/ConstIntegerExpressionGrammar.h create mode 100644 src/parser/PrismParser/Includes.h create mode 100644 src/parser/PrismParser/IntegerExpressionGrammar.cpp create mode 100644 src/parser/PrismParser/IntegerExpressionGrammar.h create mode 100644 src/parser/PrismParser/UtilityGrammars.h create mode 100644 src/parser/PrismParser/VariableState.h diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 8930f251e..e1aaacaab 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -7,6 +7,11 @@ #include "PrismParser.h" #include "src/utility/OsDetection.h" +#include "src/parser/PrismParser/VariableState.h" +#include "src/parser/PrismParser/IntegerExpressionGrammar.h" +#include "src/parser/PrismParser/ConstIntegerExpressionGrammar.h" +#include "src/parser/PrismParser/BooleanExpressionGrammar.h" +#include "src/parser/PrismParser/ConstBooleanExpressionGrammar.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFileFormatException.h" @@ -35,41 +40,25 @@ namespace storm { namespace parser { -using namespace storm::ir; -using namespace storm::ir::expressions; - -// The Boost spirit grammar used for parsing the input. -template -struct PrismParser::PrismGrammar : qi::grammar>, std::map>, std::map>, std::map, std::map>>, Skipper> { - - /* - * The constructor of the grammar. It defines all rules of the grammar and the corresponding - * semantic actions that take care of constructing the intermediate representation during - * parsing. - * - * Note: The grammar takes care of some semantic checks already. For example, in places - * where we necessarily require a constant expression, this is enforced by not allowing - * variables as subexpressions. Also, variable names are by definition unique and it is - * ensured that variables and constants are properly declared. - * TODO: It should be ensured that updates of a command only refer to variables of the - * current module. - */ - PrismGrammar() : PrismGrammar::base_type(start), nextBooleanVariableIndex(0), nextIntegerVariableIndex(0) { +PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type(start) { + + this->state = std::shared_ptr(new storm::parser::prism::VariableState()); + storm::parser::prism::IntegerExpressionGrammar intExpr(this->state); + storm::parser::prism::ConstIntegerExpressionGrammar constIntExpr(this->state); + storm::parser::prism::BooleanExpressionGrammar boolExpr(this->state); + storm::parser::prism::ConstBooleanExpressionGrammar constBoolExpr(this->state); + // This rule defines all identifiers that have not been previously used. - identifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&PrismGrammar::isIdentifier, this, qi::_1) ]; + identifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&storm::parser::prism::VariableState::isIdentifier, this->state.get(), qi::_1) ]; identifierName.name("identifier"); - freeIdentifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&PrismGrammar::isFreeIdentifier, this, qi::_1) ]; + freeIdentifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&storm::parser::prism::VariableState::isFreeIdentifier, this->state.get(), qi::_1) ]; freeIdentifierName.name("unused identifier"); // This block defines all literal expressions. booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; booleanLiteralExpression.name("boolean literal"); - integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; - integerLiteralExpression.name("integer literal"); doubleLiteralExpression = qi::double_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; doubleLiteralExpression.name("double literal"); - literalExpression %= (booleanLiteralExpression | integerLiteralExpression | doubleLiteralExpression); - literalExpression.name("literal"); // This block defines all expressions that are variables. @@ -80,38 +69,11 @@ struct PrismParser::PrismGrammar : qi::grammarstate->booleanConstants_ | booleanLiteralExpression); booleanConstantExpression.name("boolean constant or literal"); - integerConstantExpression %= (integerConstants_ | integerLiteralExpression); - integerConstantExpression.name("integer constant or literal"); - doubleConstantExpression %= (doubleConstants_ | doubleLiteralExpression); + doubleConstantExpression %= (this->state->doubleConstants_ | doubleLiteralExpression); doubleConstantExpression.name("double constant or literal"); - constantExpression %= (booleanConstantExpression | integerConstantExpression | doubleConstantExpression); - constantExpression.name("constant or literal"); - - // This block defines all expressions of integral type. - atomicIntegerExpression %= (integerVariableExpression | qi::lit("(") >> integerExpression >> qi::lit(")") | integerConstantExpression); - atomicIntegerExpression.name("integer expression"); - integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::TIMES))]; - integerMultExpression.name("integer expression"); - integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> integerMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::MINUS))]]; - integerPlusExpression.name("integer expression"); - integerExpression %= integerPlusExpression; - integerExpression.name("integer expression"); - - // This block defines all expressions of integral type that are by syntax constant. That is, they are evaluable given the values for all constants. - constantAtomicIntegerExpression %= (qi::lit("(") >> constantIntegerExpression >> qi::lit(")") | integerConstantExpression); - constantAtomicIntegerExpression.name("constant integer expression"); - constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::TIMES))]; - constantIntegerMultExpression.name("constant integer expression"); - constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantIntegerMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::MINUS))]]; - constantIntegerPlusExpression.name("constant integer expression"); - constantIntegerExpression %= constantIntegerPlusExpression; - constantIntegerExpression.name("constant integer expression"); // This block defines all expressions of type double that are by syntax constant. That is, they are evaluable given the values for all constants. constantAtomicDoubleExpression %= (qi::lit("(") >> constantDoubleExpression >> qi::lit(")") | doubleConstantExpression); @@ -123,48 +85,16 @@ struct PrismParser::PrismGrammar : qi::grammar> relations_ >> integerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; - relativeExpression.name("relative expression"); - atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")") | booleanConstantExpression); - atomicBooleanExpression.name("boolean expression"); - notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, UnaryBooleanFunctionExpression::NOT))]; - notExpression.name("boolean expression"); - andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::AND))]; - andExpression.name("boolean expression"); - orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::OR))]; - orExpression.name("boolean expression"); - booleanExpression %= orExpression; - booleanExpression.name("boolean expression"); - - // This block defines all expressions of type boolean that are by syntax constant. That is, they are evaluable given the values for all constants. - constantRelativeExpression = (constantIntegerExpression >> relations_ >> constantIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; - constantRelativeExpression.name("constant boolean expression"); - constantAtomicBooleanExpression %= (constantRelativeExpression | qi::lit("(") >> constantBooleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression); - constantAtomicBooleanExpression.name("constant boolean expression"); - constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, UnaryBooleanFunctionExpression::NOT))]; - constantNotExpression.name("constant boolean expression"); - constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::AND))]; - constantAndExpression.name("constant boolean expression"); - constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::OR))]; - constantOrExpression.name("constant boolean expression"); - constantBooleanExpression %= constantOrExpression; - constantBooleanExpression.name("constant boolean expression"); - - // This block defines the general root of all expressions. Most of the time, however, you may want to start with a more specialized rule. - expression %= (booleanExpression | integerExpression | constantDoubleExpression); - expression.name("expression"); - // This block defines all entities that are needed for parsing labels. - labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> freeIdentifierName >> -qi::lit("\"") >> qi::lit("=") >> booleanExpression >> qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_2)), phoenix::bind(labelNames_.add, qi::_1, qi::_1)]; + labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> freeIdentifierName >> -qi::lit("\"") >> qi::lit("=") >> boolExpr >> qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_2)), phoenix::bind(this->state->labelNames_.add, qi::_1, qi::_1)]; labelDefinition.name("label declaration"); labelDefinitionList %= *labelDefinition(qi::_r1); labelDefinitionList.name("label declaration list"); // This block defines all entities that are needed for parsing a reward model. - stateRewardDefinition = (booleanExpression > qi::lit(":") > constantDoubleExpression >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; + stateRewardDefinition = (boolExpr > qi::lit(":") > constantDoubleExpression >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; stateRewardDefinition.name("state reward definition"); - transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit(":") > constantDoubleExpression > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; + transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > boolExpr > qi::lit(":") > constantDoubleExpression > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; transitionRewardDefinition.name("transition reward definition"); rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > freeIdentifierName > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> qi::lit("endrewards"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_a, qi::_b)))]; rewardDefinition.name("reward definition"); @@ -172,50 +102,45 @@ struct PrismParser::PrismGrammar : qi::grammarstate->booleanVariableNames_; booleanVariableName.name("boolean variable"); - integerVariableName %= integerVariableNames_; + integerVariableName %= this->state->integerVariableNames_; integerVariableName.name("integer variable"); - commandName %= commandNames_; + commandName %= this->state->commandNames_; commandName.name("command name"); - unassignedLocalBooleanVariableName %= localBooleanVariables_ - assignedLocalBooleanVariables_; + unassignedLocalBooleanVariableName %= this->state->localBooleanVariables_ - this->state->assignedLocalBooleanVariables_; unassignedLocalBooleanVariableName.name("unassigned local boolean variable"); - unassignedLocalIntegerVariableName %= localIntegerVariables_ - assignedLocalIntegerVariables_; + unassignedLocalIntegerVariableName %= this->state->localIntegerVariables_ - this->state->assignedLocalIntegerVariables_; unassignedLocalIntegerVariableName.name("unassigned local integer variable"); // This block defines all entities that are needed for parsing a single command. - assignmentDefinition = (qi::lit("(") >> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > integerExpression > qi::lit(")"))[phoenix::bind(assignedLocalIntegerVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))] | (qi::lit("(") > unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > booleanExpression > qi::lit(")"))[phoenix::bind(assignedLocalBooleanVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))]; + assignmentDefinition = (qi::lit("(") >> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > intExpr > qi::lit(")"))[phoenix::bind(this->state->assignedLocalIntegerVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))] | (qi::lit("(") > unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > boolExpr > qi::lit(")"))[phoenix::bind(this->state->assignedLocalBooleanVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))]; assignmentDefinition.name("assignment"); assignmentDefinitionList = assignmentDefinition(qi::_r1, qi::_r2) % "&"; assignmentDefinitionList.name("assignment list"); - updateDefinition = (constantDoubleExpression > qi::lit(":")[phoenix::clear(phoenix::ref(assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b)]; + updateDefinition = (constantDoubleExpression > qi::lit(":")[phoenix::clear(phoenix::ref(this->state->assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(this->state->assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b)]; updateDefinition.name("update"); updateListDefinition = +updateDefinition % "+"; updateListDefinition.name("update list"); - commandDefinition = (qi::lit("[") > -((freeIdentifierName[phoenix::bind(commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit("->") > updateListDefinition > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; + commandDefinition = (qi::lit("[") > -((freeIdentifierName[phoenix::bind(this->state->commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1]) > qi::lit("]") > boolExpr > qi::lit("->") > updateListDefinition > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; commandDefinition.name("command"); // This block defines all entities that are needed for parsing variable definitions. - booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) + booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constBoolExpr[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) [ - phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextBooleanVariableIndex), phoenix::val(qi::_1), qi::_b)), - phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextBooleanVariableIndex))), - qi::_a = phoenix::construct>(phoenix::new_(BaseExpression::bool_, phoenix::ref(nextBooleanVariableIndex), qi::_1)), - phoenix::bind(booleanVariables_.add, qi::_1, qi::_a), - phoenix::bind(booleanVariableNames_.add, qi::_1, qi::_1), - phoenix::bind(localBooleanVariables_.add, qi::_1, qi::_1), - phoenix::ref(nextBooleanVariableIndex) = phoenix::ref(nextBooleanVariableIndex) + 1 + //qi::_a = phoenix::bind(&VariableState::addBooleanVariable, *this->state.get(), qi::_1), + qi::_a = phoenix::bind(&storm::parser::prism::VariableState::addBooleanVariable, *this->state, qi::_1, qi::_b), + phoenix::push_back(qi::_r1, phoenix::construct(qi::_a, phoenix::val(qi::_1), qi::_b)), + phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, qi::_a)), + phoenix::bind(this->state->localBooleanVariables_.add, qi::_1, qi::_1) ]; booleanVariableDefinition.name("boolean variable declaration"); - integerVariableDefinition = (freeIdentifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) + integerVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("[") > constIntExpr > qi::lit("..") > constIntExpr > qi::lit("]") > -(qi::lit("init") > constIntExpr[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) [ - phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3, qi::_b)), - phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextIntegerVariableIndex))), - qi::_a = phoenix::construct>(phoenix::new_(BaseExpression::int_, phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3)), - phoenix::bind(integerVariables_.add, qi::_1, qi::_a), - phoenix::bind(integerVariableNames_.add, qi::_1, qi::_1), - phoenix::bind(localIntegerVariables_.add, qi::_1, qi::_1), - phoenix::ref(nextIntegerVariableIndex) = phoenix::ref(nextIntegerVariableIndex) + 1 + qi::_a = phoenix::bind(&storm::parser::prism::VariableState::addIntegerVariable, *this->state, qi::_1, qi::_2, qi::_3, qi::_b), + phoenix::push_back(qi::_r1, phoenix::construct(qi::_a, qi::_1, qi::_2, qi::_3, qi::_b)), + phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, qi::_a)), + phoenix::bind(this->state->localIntegerVariables_.add, qi::_1, qi::_1) ]; integerVariableDefinition.name("integer variable declaration"); variableDefinition = (booleanVariableDefinition(qi::_r1, qi::_r3) | integerVariableDefinition(qi::_r2, qi::_r4)); @@ -223,42 +148,44 @@ struct PrismParser::PrismGrammar : qi::grammar> freeIdentifierName - [phoenix::clear(phoenix::ref(localBooleanVariables_)), phoenix::clear(phoenix::ref(localIntegerVariables_))] + [phoenix::clear(phoenix::ref(this->state->localBooleanVariables_)), phoenix::clear(phoenix::ref(this->state->localIntegerVariables_))] >> *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) >> +commandDefinition > qi::lit("endmodule")) [ - phoenix::bind(moduleNames_.add, qi::_1, qi::_1), + phoenix::bind(this->state->moduleNames_.add, qi::_1, qi::_1), qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2), - phoenix::bind(moduleMap_.add, qi::_1, qi::_val) + phoenix::bind(this->state->moduleMap_.add, qi::_1, qi::_val) ]; Module const * (qi::symbols::*moduleFinder)(const std::string&) const = &qi::symbols::find; moduleDefinition.name("module"); moduleRenaming = (qi::lit("module") >> freeIdentifierName >> qi::lit("=") - > moduleNames_ > qi::lit("[") > *( + > this->state->moduleNames_ > qi::lit("[") > *( (identifierName > qi::lit("=") > identifierName >> -qi::lit(","))[phoenix::insert(qi::_a, phoenix::construct>(qi::_1, qi::_2))] ) > qi::lit("]") > qi::lit("endmodule")) [ - phoenix::bind(moduleNames_.add, qi::_1, qi::_1), - qi::_val = phoenix::construct(*phoenix::bind(moduleFinder, moduleMap_, qi::_2), qi::_1, qi::_a, VariableAdder(this)), - phoenix::bind(moduleMap_.add, qi::_1, qi::_val) + phoenix::bind(this->state->moduleNames_.add, qi::_1, qi::_1), + qi::_val = phoenix::construct(*phoenix::bind(moduleFinder, this->state->moduleMap_, qi::_2), qi::_1, qi::_a, this->state), + phoenix::bind(this->state->moduleMap_.add, qi::_1, qi::_val) ]; moduleRenaming.name("renamed module"); moduleDefinitionList %= +(moduleDefinition | moduleRenaming); moduleDefinitionList.name("module list"); - + + integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + integerLiteralExpression.name("integer literal"); // This block defines all entities that are needed for parsing constant definitions. - definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") > booleanLiteralExpression > qi::lit(";"))[phoenix::bind(booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; + definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") > booleanLiteralExpression > qi::lit(";"))[phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; definedBooleanConstantDefinition.name("defined boolean constant declaration"); - definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") > integerLiteralExpression > qi::lit(";"))[phoenix::bind(integerConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; + definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") > integerLiteralExpression > qi::lit(";"))[phoenix::bind(this->state->integerConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; definedIntegerConstantDefinition.name("defined integer constant declaration"); - definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") > doubleLiteralExpression > qi::lit(";"))[phoenix::bind(doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; + definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") > doubleLiteralExpression > qi::lit(";"))[phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; definedDoubleConstantDefinition.name("defined double constant declaration"); - undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; + undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; undefinedBooleanConstantDefinition.name("undefined boolean constant declaration"); - undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(integerConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; + undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->integerConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; undefinedIntegerConstantDefinition.name("undefined integer constant declaration"); - undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(allConstantNames_.add, qi::_1, qi::_1)]; + undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; undefinedDoubleConstantDefinition.name("undefined double constant declaration"); definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); definedConstantDefinition.name("defined constant declaration"); @@ -274,248 +201,19 @@ struct PrismParser::PrismGrammar : qi::grammar lower, const std::shared_ptr upper, const std::shared_ptr init) const { - std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::int_, grammar->nextIntegerVariableIndex, name, lower, upper)); - grammar->integerVariables_.add(name, varExpr); - grammar->integerVariableNames_.add(name, name); - grammar->nextIntegerVariableIndex++; - return grammar->nextIntegerVariableIndex-1; - } - - uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init) const { - std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::bool_, grammar->nextBooleanVariableIndex, name)); - grammar->integerVariables_.add(name, varExpr); - grammar->integerVariableNames_.add(name, name); - grammar->nextBooleanVariableIndex++; - return grammar->nextBooleanVariableIndex-1; - } - }; - - void prepareForSecondRun() { + void PrismParser::PrismGrammar::prepareForSecondRun() { // Clear constants. - integerConstants_.clear(); - booleanConstants_.clear(); - doubleConstants_.clear(); - allConstantNames_.clear(); - // Reset variable indices. - nextIntegerVariableIndex = 0; - nextBooleanVariableIndex = 0; - // Clear module names - moduleNames_.clear(); + storm::parser::prism::IntegerExpressionGrammar intExpr(this->state); + storm::parser::prism::ConstIntegerExpressionGrammar constIntExpr(this->state); + + this->state->prepareForSecondRun(); // Override variable expressions: only allow declared variables. - integerVariableExpression %= integerVariables_; + integerVariableExpression %= this->state->integerVariables_; integerVariableExpression.name("integer variable"); - booleanVariableExpression %= booleanVariables_; + booleanVariableExpression %= this->state->booleanVariables_; booleanVariableExpression.name("boolean variable"); - - // Override variable definition: don't register variables again globally. - booleanVariableDefinition = (identifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constantBooleanExpression) > qi::lit(";")) - [ - phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextBooleanVariableIndex), phoenix::val(qi::_1), qi::_b)), - phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextBooleanVariableIndex))), - qi::_a = phoenix::construct>(phoenix::new_(BaseExpression::bool_, phoenix::ref(nextBooleanVariableIndex), qi::_1)), - phoenix::bind(localBooleanVariables_.add, qi::_1, qi::_1), - phoenix::ref(nextBooleanVariableIndex) = phoenix::ref(nextBooleanVariableIndex) + 1 - ]; - booleanVariableDefinition.name("boolean variable declaration"); - - integerVariableDefinition = (identifierName > qi::lit(":") > qi::lit("[") > constantIntegerExpression > qi::lit("..") > constantIntegerExpression > qi::lit("]") > -(qi::lit("init") > constantIntegerExpression) > qi::lit(";")) - [ - phoenix::push_back(qi::_r1, phoenix::construct(phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3, qi::_b)), - phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::ref(nextIntegerVariableIndex))), - qi::_a = phoenix::construct>(phoenix::new_(BaseExpression::int_, phoenix::ref(nextIntegerVariableIndex), qi::_1, qi::_2, qi::_3)), - phoenix::bind(localIntegerVariables_.add, qi::_1, qi::_1), - phoenix::ref(nextIntegerVariableIndex) = phoenix::ref(nextIntegerVariableIndex) + 1 - ]; - integerVariableDefinition.name("integer variable declaration"); } - - // The starting point of the grammar. - qi::rule>, std::map>, std::map>, std::map, std::map>>, Skipper> start; - qi::rule modelTypeDefinition; - qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; - qi::rule(), Skipper> moduleDefinitionList; - - // Rules for module definition. - qi::rule, std::vector, std::map, std::map>, Skipper> moduleDefinition; - qi::rule>, Skipper> moduleRenaming; - - // Rules for variable definitions. - qi::rule&, std::vector&, std::map&, std::map&), Skipper> variableDefinition; - qi::rule&, std::map&), qi::locals, std::shared_ptr>, Skipper> booleanVariableDefinition; - qi::rule&, std::map&), qi::locals, std::shared_ptr>, Skipper> integerVariableDefinition; - - // Rules for command definitions. - qi::rule, Skipper> commandDefinition; - qi::rule(), Skipper> updateListDefinition; - qi::rule, std::map>, Skipper> updateDefinition; - qi::rule&, std::map&), Skipper> assignmentDefinitionList; - qi::rule&, std::map&), Skipper> assignmentDefinition; - - // Rules for variable/command names. - qi::rule integerVariableName; - qi::rule booleanVariableName; - qi::rule commandName; - qi::rule unassignedLocalBooleanVariableName; - qi::rule unassignedLocalIntegerVariableName; - - // Rules for reward definitions. - qi::rule&), Skipper> rewardDefinitionList; - qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; - qi::rule stateRewardDefinition; - qi::rule, Skipper> transitionRewardDefinition; - - // Rules for label definitions. - qi::rule>&), Skipper> labelDefinitionList; - qi::rule>&), Skipper> labelDefinition; - - // Rules for constant definitions. - qi::rule(), Skipper> constantDefinition; - qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; - qi::rule(), Skipper> definedConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedBooleanConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedIntegerConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedDoubleConstantDefinition; - qi::rule(), Skipper> definedBooleanConstantDefinition; - qi::rule(), Skipper> definedIntegerConstantDefinition; - qi::rule(), Skipper> definedDoubleConstantDefinition; - - qi::rule freeIdentifierName; - qi::rule identifierName; - - // The starting point for arbitrary expressions. - qi::rule(), Skipper> expression; - - // Rules with boolean result type. - qi::rule(), Skipper> booleanExpression; - qi::rule(), Skipper> orExpression; - qi::rule(), Skipper> andExpression; - qi::rule(), Skipper> notExpression; - qi::rule(), Skipper> atomicBooleanExpression; - qi::rule(), Skipper> relativeExpression; - qi::rule(), Skipper> constantBooleanExpression; - qi::rule(), Skipper> constantOrExpression; - qi::rule(), Skipper> constantAndExpression; - qi::rule(), Skipper> constantNotExpression; - qi::rule(), Skipper> constantAtomicBooleanExpression; - qi::rule(), Skipper> constantRelativeExpression; - - // Rules with integer result type. - qi::rule(), Skipper> integerExpression; - qi::rule(), qi::locals, Skipper> integerPlusExpression; - qi::rule(), Skipper> integerMultExpression; - qi::rule(), Skipper> atomicIntegerExpression; - qi::rule(), Skipper> constantIntegerExpression; - qi::rule(), qi::locals, Skipper> constantIntegerPlusExpression; - qi::rule(), Skipper> constantIntegerMultExpression; - qi::rule(), Skipper> constantAtomicIntegerExpression; - - // Rules with double result type. - qi::rule(), Skipper> constantDoubleExpression; - qi::rule(), qi::locals, Skipper> constantDoublePlusExpression; - qi::rule(), qi::locals, Skipper> constantDoubleMultExpression; - qi::rule(), Skipper> constantAtomicDoubleExpression; - - // Rules for variable recognition. - qi::rule(), Skipper> variableExpression; - qi::rule(), Skipper> booleanVariableExpression; - qi::rule(), Skipper> booleanVariableCreatorExpression; - qi::rule(), Skipper> integerVariableExpression; - qi::rule(), qi::locals>, Skipper> integerVariableCreatorExpression; - - // Rules for constant recognition. - qi::rule(), Skipper> constantExpression; - qi::rule(), Skipper> booleanConstantExpression; - qi::rule(), Skipper> integerConstantExpression; - qi::rule(), Skipper> doubleConstantExpression; - - // Rules for literal recognition. - qi::rule(), Skipper> literalExpression; - qi::rule(), Skipper> booleanLiteralExpression; - qi::rule(), Skipper> integerLiteralExpression; - qi::rule(), Skipper> doubleLiteralExpression; - - // A structure defining the keywords that are not allowed to be chosen as identifiers. - struct keywordsStruct : qi::symbols { - keywordsStruct() { - add - ("dtmc", 1) - ("ctmc", 2) - ("mdp", 3) - ("ctmdp", 4) - ("const", 5) - ("int", 6) - ("bool", 7) - ("module", 8) - ("endmodule", 9) - ("rewards", 10) - ("endrewards", 11) - ("true", 12) - ("false", 13) - ; - } - } keywords_; - - // A structure mapping the textual representation of a model type to the model type - // representation of the intermediate representation. - struct modelTypeStruct : qi::symbols { - modelTypeStruct() { - add - ("dtmc", Program::ModelType::DTMC) - ("ctmc", Program::ModelType::CTMC) - ("mdp", Program::ModelType::MDP) - ("ctmdp", Program::ModelType::CTMDP) - ; - } - } modelType_; - - // A structure mapping the textual representation of a binary relation to the representation - // of the intermediate representation. - struct relationalOperatorStruct : qi::symbols { - relationalOperatorStruct() { - add - ("=", BinaryRelationExpression::EQUAL) - ("<", BinaryRelationExpression::LESS) - ("<=", BinaryRelationExpression::LESS_OR_EQUAL) - (">", BinaryRelationExpression::GREATER) - (">=", BinaryRelationExpression::GREATER_OR_EQUAL) - ; - } - } relations_; - - // Used for indexing the variables. - uint_fast64_t nextBooleanVariableIndex; - uint_fast64_t nextIntegerVariableIndex; - - // Structures mapping variable and constant names to the corresponding expression nodes of - // the intermediate representation. - struct qi::symbols> integerVariables_, booleanVariables_; - struct qi::symbols> integerConstants_, booleanConstants_, doubleConstants_; - struct qi::symbols moduleMap_; - - // A structure representing the identity function over identifier names. - struct variableNamesStruct : qi::symbols { } integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_, - localBooleanVariables_, localIntegerVariables_, assignedLocalBooleanVariables_, assignedLocalIntegerVariables_; -}; /*! * Opens the given file for parsing, invokes the helper function to parse the actual content and @@ -564,13 +262,14 @@ std::shared_ptr PrismParser::parse(std::istream& inputStream // In order to instantiate the grammar, we have to pass the type of the skipping parser. // As this is more complex, we let Boost figure out the actual type for us. - PrismGrammar> *(qi::char_ - qi::eol) >> qi::eol)> grammar; + PrismGrammar grammar; try { // Now parse the content using phrase_parse in order to be able to supply a skipping parser. // First run. qi::phrase_parse(positionIteratorBegin, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, *result); grammar.prepareForSecondRun(); result = std::shared_ptr(new storm::ir::Program()); + std::cout << "Now we start the second run..." << std::endl; // Second run. qi::phrase_parse(positionIteratorBegin2, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, *result); std::cout << "Here is the parsed grammar: " << std::endl << result->toString() << std::endl; diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 1fca04c55..86b7eb4d7 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -10,6 +10,9 @@ // All classes of the intermediate representation are used. #include "src/ir/IR.h" +#include "src/parser/PrismParser/Includes.h" +#include "src/parser/PrismParser/UtilityGrammars.h" +#include "src/parser/PrismParser/VariableState.h" // Used for file input. #include @@ -19,6 +22,9 @@ namespace storm { namespace parser { +using namespace storm::ir; +using namespace storm::ir::expressions; + /*! * This class parses the format of the PRISM model checker into an intermediate representation. */ @@ -32,6 +38,104 @@ public: */ std::shared_ptr parseFile(std::string const& filename) const; + /*! + * The Boost spirit grammar for the PRISM language. Returns the intermediate representation of + * the input that complies with the PRISM syntax. + */ + class PrismGrammar : public qi::grammar>, std::map>, std::map>, std::map, std::map>>, Skipper> { + public: + PrismGrammar(); + void prepareForSecondRun(); + + private: + + std::shared_ptr state; + + // The starting point of the grammar. + qi::rule>, std::map>, std::map>, std::map, std::map>>, Skipper> start; + qi::rule modelTypeDefinition; + qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; + qi::rule(), Skipper> moduleDefinitionList; + + // Rules for module definition. + qi::rule, std::vector, std::map, std::map>, Skipper> moduleDefinition; + qi::rule>, Skipper> moduleRenaming; + + // Rules for variable definitions. + qi::rule&, std::vector&, std::map&, std::map&), Skipper> variableDefinition; + qi::rule&, std::map&), qi::locals>, Skipper> booleanVariableDefinition; + qi::rule&, std::map&), qi::locals>, Skipper> integerVariableDefinition; + + // Rules for command definitions. + qi::rule, Skipper> commandDefinition; + qi::rule(), Skipper> updateListDefinition; + qi::rule, std::map>, Skipper> updateDefinition; + qi::rule&, std::map&), Skipper> assignmentDefinitionList; + qi::rule&, std::map&), Skipper> assignmentDefinition; + + // Rules for variable/command names. + qi::rule integerVariableName; + qi::rule booleanVariableName; + qi::rule commandName; + qi::rule unassignedLocalBooleanVariableName; + qi::rule unassignedLocalIntegerVariableName; + + // Rules for reward definitions. + qi::rule&), Skipper> rewardDefinitionList; + qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; + qi::rule stateRewardDefinition; + qi::rule, Skipper> transitionRewardDefinition; + + // Rules for label definitions. + qi::rule>&), Skipper> labelDefinitionList; + qi::rule>&), Skipper> labelDefinition; + + // Rules for constant definitions. + qi::rule(), Skipper> integerLiteralExpression; + qi::rule(), Skipper> constantDefinition; + qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; + qi::rule(), Skipper> definedConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedBooleanConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedIntegerConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedDoubleConstantDefinition; + qi::rule(), Skipper> definedBooleanConstantDefinition; + qi::rule(), Skipper> definedIntegerConstantDefinition; + qi::rule(), Skipper> definedDoubleConstantDefinition; + + qi::rule freeIdentifierName; + qi::rule identifierName; + + // The starting point for arbitrary expressions. + qi::rule(), Skipper> expression; + // Rules with double result type. + qi::rule(), Skipper> constantDoubleExpression; + qi::rule(), qi::locals, Skipper> constantDoublePlusExpression; + qi::rule(), qi::locals, Skipper> constantDoubleMultExpression; + qi::rule(), Skipper> constantAtomicDoubleExpression; + + // Rules for variable recognition. + qi::rule(), Skipper> booleanVariableExpression; + qi::rule(), Skipper> booleanVariableCreatorExpression; + qi::rule(), Skipper> integerVariableExpression; + qi::rule(), qi::locals>, Skipper> integerVariableCreatorExpression; + + // Rules for constant recognition. + qi::rule(), Skipper> constantExpression; + qi::rule(), Skipper> booleanConstantExpression; + qi::rule(), Skipper> integerConstantExpression; + qi::rule(), Skipper> doubleConstantExpression; + + // Rules for literal recognition. + qi::rule(), Skipper> literalExpression; + qi::rule(), Skipper> booleanLiteralExpression; + qi::rule(), Skipper> doubleLiteralExpression; + + storm::parser::prism::keywordsStruct keywords_; + storm::parser::prism::modelTypeStruct modelType_; + storm::parser::prism::relationalOperatorStruct relations_; + + }; + private: /*! * Parses the given input stream into the intermediate representation assuming it complies with @@ -41,13 +145,6 @@ private: * @return a shared pointer to the intermediate representation of the PRISM file. */ std::shared_ptr parse(std::istream& inputStream, std::string const& filename) const; - - /*! - * The Boost spirit grammar for the PRISM language. Returns the intermediate representation of - * the input that complies with the PRISM syntax. - */ - template - struct PrismGrammar; }; } // namespace parser diff --git a/src/parser/PrismParser/BooleanExpressionGrammar.cpp b/src/parser/PrismParser/BooleanExpressionGrammar.cpp new file mode 100644 index 000000000..3ad148c08 --- /dev/null +++ b/src/parser/PrismParser/BooleanExpressionGrammar.cpp @@ -0,0 +1,55 @@ +#include "BooleanExpressionGrammar.h" + +namespace storm { +namespace parser { +namespace prism { + +BooleanExpressionGrammar::BooleanExpressionGrammar(std::shared_ptr& state) + : BooleanExpressionGrammar::base_type(booleanExpression), state(state) { + + IntegerExpressionGrammar intExpr(this->state); + + // This rule defines all identifiers that have not been previously used. + identifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&storm::parser::prism::VariableState::isIdentifier, this->state.get(), qi::_1) ]; + identifierName.name("identifier"); + freeIdentifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&storm::parser::prism::VariableState::isFreeIdentifier, this->state.get(), qi::_1) ]; + freeIdentifierName.name("unused identifier"); + + // This block defines all literal expressions. + booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + booleanLiteralExpression.name("boolean literal"); + + + // This block defines all expressions that are variables. + std::shared_ptr boolvarexpr = std::shared_ptr(new VariableExpression(BaseExpression::bool_, std::numeric_limits::max(), "bool", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); + booleanVariableExpression = identifierName[qi::_val = boolvarexpr]; + booleanVariableExpression.name("boolean variable"); + + // This block defines all atomic expressions that are constant, i.e. literals and constants. + booleanConstantExpression %= (this->state->booleanConstants_ | booleanLiteralExpression); + booleanConstantExpression.name("boolean constant or literal"); + + // This block defines all expressions of type boolean. + relativeExpression = (intExpr >> relations_ >> intExpr)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; + relativeExpression.name("relative expression"); + atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")") | booleanConstantExpression); + atomicBooleanExpression.name("boolean expression"); + notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, UnaryBooleanFunctionExpression::NOT))]; + notExpression.name("boolean expression"); + andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::AND))]; + andExpression.name("boolean expression"); + orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::OR))]; + orExpression.name("boolean expression"); + booleanExpression %= orExpression; + booleanExpression.name("boolean expression"); + + // This block defines auxiliary entities that are used to check whether a certain variable exist. + booleanVariableName %= this->state->booleanVariableNames_; + booleanVariableName.name("boolean variable"); + unassignedLocalBooleanVariableName %= this->state->localBooleanVariables_ - this->state->assignedLocalBooleanVariables_; + unassignedLocalBooleanVariableName.name("unassigned local boolean variable"); + } + +} +} +} \ No newline at end of file diff --git a/src/parser/PrismParser/BooleanExpressionGrammar.h b/src/parser/PrismParser/BooleanExpressionGrammar.h new file mode 100644 index 000000000..db5ad0951 --- /dev/null +++ b/src/parser/PrismParser/BooleanExpressionGrammar.h @@ -0,0 +1,66 @@ +/* + * File: BooleanExpressionGrammar.h + * Author: nafur + * + * Created on April 10, 2013, 6:27 PM + */ + +#ifndef BOOLEANEXPRESSIONGRAMMAR_H +#define BOOLEANEXPRESSIONGRAMMAR_H + +#include "Includes.h" +#include "VariableState.h" +#include "IntegerExpressionGrammar.h" + +namespace storm { +namespace parser { +namespace prism { + +class BooleanExpressionGrammar : public qi::grammar(), Skipper, Skipper> { +public: + BooleanExpressionGrammar(std::shared_ptr& state); + +private: + // Rules for variable/command names. + qi::rule integerVariableName; + qi::rule booleanVariableName; + qi::rule unassignedLocalBooleanVariableName; + qi::rule unassignedLocalIntegerVariableName; + + qi::rule freeIdentifierName; + qi::rule identifierName; + + // The starting point for arbitrary expressions. + qi::rule(), Skipper> expression; + + // Rules with boolean result type. + qi::rule(), Skipper, Skipper> booleanExpression; + qi::rule(), Skipper> orExpression; + qi::rule(), Skipper> andExpression; + qi::rule(), Skipper> notExpression; + qi::rule(), Skipper> atomicBooleanExpression; + qi::rule(), Skipper> relativeExpression; + + // Rules for variable recognition. + qi::rule(), Skipper> booleanVariableExpression; + qi::rule(), Skipper> booleanVariableCreatorExpression; + + // Rules for constant recognition. + qi::rule(), Skipper> booleanConstantExpression; + + // Rules for literal recognition. + qi::rule(), Skipper> booleanLiteralExpression; + + // A structure mapping the textual representation of a binary relation to the representation + // of the intermediate representation. + storm::parser::prism::relationalOperatorStruct relations_; + + std::shared_ptr state; +}; + + +} +} +} + +#endif /* BOOLEANEXPRESSIONGRAMMAR_H */ diff --git a/src/parser/PrismParser/ConstBooleanExpressionGrammar.cpp b/src/parser/PrismParser/ConstBooleanExpressionGrammar.cpp new file mode 100644 index 000000000..53a5f5a96 --- /dev/null +++ b/src/parser/PrismParser/ConstBooleanExpressionGrammar.cpp @@ -0,0 +1,32 @@ +#include "ConstBooleanExpressionGrammar.h" + +namespace storm { +namespace parser { +namespace prism { + + + ConstBooleanExpressionGrammar::ConstBooleanExpressionGrammar(std::shared_ptr& state) + : ConstBooleanExpressionGrammar::base_type(constantBooleanExpression), state(state) { + + ConstIntegerExpressionGrammar constIntExpr(this->state); + + booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + booleanLiteralExpression.name("boolean literal"); + booleanConstantExpression %= (this->state->booleanConstants_ | booleanLiteralExpression); + booleanConstantExpression.name("boolean constant or literal"); + constantRelativeExpression = (constIntExpr >> relations_ >> constIntExpr)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; + constantRelativeExpression.name("constant boolean expression"); + constantAtomicBooleanExpression %= (constantRelativeExpression | qi::lit("(") >> constantBooleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression); + constantAtomicBooleanExpression.name("constant boolean expression"); + constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, UnaryBooleanFunctionExpression::NOT))]; + constantNotExpression.name("constant boolean expression"); + constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::AND))]; + constantAndExpression.name("constant boolean expression"); + constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::OR))]; + constantOrExpression.name("constant boolean expression"); + constantBooleanExpression %= constantOrExpression; + constantBooleanExpression.name("constant boolean expression"); + } +} +} +} \ No newline at end of file diff --git a/src/parser/PrismParser/ConstBooleanExpressionGrammar.h b/src/parser/PrismParser/ConstBooleanExpressionGrammar.h new file mode 100644 index 000000000..24166035e --- /dev/null +++ b/src/parser/PrismParser/ConstBooleanExpressionGrammar.h @@ -0,0 +1,49 @@ +/* + * File: ConstBooleanExpressionGrammar.h + * Author: nafur + * + * Created on April 10, 2013, 6:34 PM + */ + +#ifndef CONSTBOOLEANEXPRESSIONGRAMMAR_H +#define CONSTBOOLEANEXPRESSIONGRAMMAR_H + +#include "Includes.h" +#include "ConstIntegerExpressionGrammar.h" +#include "VariableState.h" +#include "UtilityGrammars.h" + +namespace storm { +namespace parser { +namespace prism { + +class ConstBooleanExpressionGrammar : public qi::grammar(), Skipper, Skipper> { +public: + ConstBooleanExpressionGrammar(std::shared_ptr& state); + +private: + + qi::rule(), Skipper> booleanLiteralExpression; + qi::rule(), Skipper> booleanConstantExpression; + qi::rule(), Skipper> relativeExpression; + qi::rule(), Skipper, Skipper> constantBooleanExpression; + qi::rule(), Skipper> constantOrExpression; + qi::rule(), Skipper> constantAndExpression; + qi::rule(), Skipper> constantNotExpression; + qi::rule(), Skipper> constantAtomicBooleanExpression; + qi::rule(), Skipper> constantRelativeExpression; + + + storm::parser::prism::relationalOperatorStruct relations_; + + std::shared_ptr state; + +}; + + +} +} +} + +#endif /* CONSTBOOLEANEXPRESSIONGRAMMAR_H */ + diff --git a/src/parser/PrismParser/ConstIntegerExpressionGrammar.cpp b/src/parser/PrismParser/ConstIntegerExpressionGrammar.cpp new file mode 100644 index 000000000..ef9d8c91f --- /dev/null +++ b/src/parser/PrismParser/ConstIntegerExpressionGrammar.cpp @@ -0,0 +1,30 @@ +#include "ConstIntegerExpressionGrammar.h" + + +namespace storm { +namespace parser { +namespace prism { + +ConstIntegerExpressionGrammar::ConstIntegerExpressionGrammar(std::shared_ptr& state) + : ConstIntegerExpressionGrammar::base_type(constantIntegerExpression), state(state) { + + integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + integerLiteralExpression.name("integer literal"); + integerConstantExpression %= (this->state->integerConstants_ | integerLiteralExpression); + integerConstantExpression.name("integer constant or literal"); + + constantAtomicIntegerExpression %= (qi::lit("(") >> constantIntegerExpression >> qi::lit(")") | integerConstantExpression); + constantAtomicIntegerExpression.name("constant integer expression"); + constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::TIMES))]; + constantIntegerMultExpression.name("constant integer expression"); + constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantIntegerMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::MINUS))]]; + constantIntegerPlusExpression.name("constant integer expression"); + constantIntegerExpression %= constantIntegerPlusExpression; + constantIntegerExpression.name("constant integer expression"); + + +} + +} +} +} \ No newline at end of file diff --git a/src/parser/PrismParser/ConstIntegerExpressionGrammar.h b/src/parser/PrismParser/ConstIntegerExpressionGrammar.h new file mode 100644 index 000000000..2c1a3420c --- /dev/null +++ b/src/parser/PrismParser/ConstIntegerExpressionGrammar.h @@ -0,0 +1,38 @@ +/* + * File: ConstIntegerExpressionGrammar.h + * Author: nafur + * + * Created on April 10, 2013, 6:02 PM + */ + +#ifndef CONSTINTEGEREXPRESSIONGRAMMAR_H +#define CONSTINTEGEREXPRESSIONGRAMMAR_H + +#include "Includes.h" +#include "VariableState.h" + +namespace storm { +namespace parser { +namespace prism { + +class ConstIntegerExpressionGrammar : public qi::grammar(), Skipper, Skipper> { +public: + ConstIntegerExpressionGrammar(std::shared_ptr& state); + +private: + qi::rule(), Skipper> integerLiteralExpression; + qi::rule(), Skipper> integerConstantExpression; + qi::rule(), Skipper, Skipper> constantIntegerExpression; + qi::rule(), qi::locals, Skipper> constantIntegerPlusExpression; + qi::rule(), Skipper> constantIntegerMultExpression; + qi::rule(), Skipper> constantAtomicIntegerExpression; + + std::shared_ptr state; +}; + + +} +} +} + +#endif /* CONSTINTEGEREXPRESSIONGRAMMAR_H */ diff --git a/src/parser/PrismParser/Includes.h b/src/parser/PrismParser/Includes.h new file mode 100644 index 000000000..39eb5a450 --- /dev/null +++ b/src/parser/PrismParser/Includes.h @@ -0,0 +1,35 @@ +/* + * File: BoostIncludes.h + * Author: nafur + * + * Created on April 10, 2013, 4:46 PM + */ + +#ifndef BOOSTINCLUDES_H +#define BOOSTINCLUDES_H + +// Used for Boost spirit. +#include +#include +#include + +// Include headers for spirit iterators. Needed for diagnostics and input stream iteration. +#include +#include + +namespace qi = boost::spirit::qi; +namespace phoenix = boost::phoenix; + +typedef std::string::const_iterator BaseIteratorType; +typedef boost::spirit::classic::position_iterator2 PositionIteratorType; +typedef PositionIteratorType Iterator; +typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol) Skipper; + +#include "src/ir/IR.h" +using namespace storm::ir; +using namespace storm::ir::expressions; + +#include "UtilityGrammars.h" + +#endif /* BOOSTINCLUDES_H */ + diff --git a/src/parser/PrismParser/IntegerExpressionGrammar.cpp b/src/parser/PrismParser/IntegerExpressionGrammar.cpp new file mode 100644 index 000000000..1d4c2cd19 --- /dev/null +++ b/src/parser/PrismParser/IntegerExpressionGrammar.cpp @@ -0,0 +1,46 @@ +#include "IntegerExpressionGrammar.h" + +namespace storm { +namespace parser { +namespace prism { + +IntegerExpressionGrammar::IntegerExpressionGrammar(std::shared_ptr& state) + : IntegerExpressionGrammar::base_type(integerExpression), state(state) { + + // This rule defines all identifiers that have not been previously used. + identifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&VariableState::isIdentifier, this->state.get(), qi::_1) ]; + identifierName.name("identifier"); + + // This block defines all literal expressions. + integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + integerLiteralExpression.name("integer literal"); + + // This block defines all expressions that are variables. + std::shared_ptr intvarexpr = std::shared_ptr(new VariableExpression(BaseExpression::int_, std::numeric_limits::max(), "int", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); + integerVariableExpression = identifierName[qi::_val = intvarexpr]; + integerVariableExpression.name("integer variable"); + + // This block defines all atomic expressions that are constant, i.e. literals and constants. + integerConstantExpression %= (this->state->integerConstants_ | integerLiteralExpression); + integerConstantExpression.name("integer constant or literal"); + + // This block defines all expressions of integral type. + atomicIntegerExpression %= (integerVariableExpression | qi::lit("(") >> integerExpression >> qi::lit(")") | integerConstantExpression); + atomicIntegerExpression.name("integer expression"); + integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::TIMES))]; + integerMultExpression.name("integer expression"); + integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> integerMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::MINUS))]]; + integerPlusExpression.name("integer expression"); + integerExpression %= integerPlusExpression; + integerExpression.name("integer expression"); +} + +void IntegerExpressionGrammar::prepareForSecondRun() { + // Override variable expressions: only allow declared variables. + integerVariableExpression %= this->state->integerVariables_; + integerVariableExpression.name("integer variable"); +} + +} +} +} \ No newline at end of file diff --git a/src/parser/PrismParser/IntegerExpressionGrammar.h b/src/parser/PrismParser/IntegerExpressionGrammar.h new file mode 100644 index 000000000..7a240809b --- /dev/null +++ b/src/parser/PrismParser/IntegerExpressionGrammar.h @@ -0,0 +1,61 @@ +/* + * File: IntegerExpressionGrammar.h + * Author: nafur + * + * Created on April 10, 2013, 4:39 PM + */ + +#ifndef INTEGEREXPRESSIONGRAMMAR_H +#define INTEGEREXPRESSIONGRAMMAR_H + +#include "src/ir/IR.h" +#include "VariableState.h" +#include "Includes.h" + +#include + +namespace storm { +namespace parser { +namespace prism { + +class IntegerExpressionGrammar : public qi::grammar(), Skipper, Skipper> { +public: + IntegerExpressionGrammar(std::shared_ptr& state); + void prepareForSecondRun(); + +private: + + qi::rule identifierName; + + // The starting point for arbitrary expressions. + qi::rule(), Skipper> expression; + + // Rules with integer result type. + qi::rule(), Skipper, Skipper> integerExpression; + qi::rule(), qi::locals, Skipper> integerPlusExpression; + qi::rule(), Skipper> integerMultExpression; + qi::rule(), Skipper> atomicIntegerExpression; + qi::rule(), Skipper> constantIntegerExpression; + qi::rule(), qi::locals, Skipper> constantIntegerPlusExpression; + qi::rule(), Skipper> constantIntegerMultExpression; + qi::rule(), Skipper> constantAtomicIntegerExpression; + + // Rules for variable recognition. + qi::rule(), Skipper> integerVariableExpression; + qi::rule(), qi::locals>, Skipper> integerVariableCreatorExpression; + + // Rules for constant recognition. + qi::rule(), Skipper> integerConstantExpression; + + // Rules for literal recognition. + qi::rule(), Skipper> integerLiteralExpression; + + std::shared_ptr state; +}; + +} +} +} + +#endif /* INTEGEREXPRESSIONGRAMMAR_H */ + diff --git a/src/parser/PrismParser/UtilityGrammars.h b/src/parser/PrismParser/UtilityGrammars.h new file mode 100644 index 000000000..e6c7e9707 --- /dev/null +++ b/src/parser/PrismParser/UtilityGrammars.h @@ -0,0 +1,69 @@ +/* + * File: Keywords.h + * Author: nafur + * + * Created on April 10, 2013, 6:03 PM + */ + +#ifndef KEYWORDS_H +#define KEYWORDS_H + +#include "Includes.h" + +namespace storm { +namespace parser { +namespace prism { + +// A structure defining the keywords that are not allowed to be chosen as identifiers. + struct keywordsStruct : qi::symbols { + keywordsStruct() { + add + ("dtmc", 1) + ("ctmc", 2) + ("mdp", 3) + ("ctmdp", 4) + ("const", 5) + ("int", 6) + ("bool", 7) + ("module", 8) + ("endmodule", 9) + ("rewards", 10) + ("endrewards", 11) + ("true", 12) + ("false", 13) + ; + } + }; + + // A structure mapping the textual representation of a model type to the model type + // representation of the intermediate representation. + struct modelTypeStruct : qi::symbols { + modelTypeStruct() { + add + ("dtmc", Program::ModelType::DTMC) + ("ctmc", Program::ModelType::CTMC) + ("mdp", Program::ModelType::MDP) + ("ctmdp", Program::ModelType::CTMDP) + ; + } + }; + + // A structure mapping the textual representation of a binary relation to the representation + // of the intermediate representation. + struct relationalOperatorStruct : qi::symbols { + relationalOperatorStruct() { + add + ("=", BinaryRelationExpression::EQUAL) + ("<", BinaryRelationExpression::LESS) + ("<=", BinaryRelationExpression::LESS_OR_EQUAL) + (">", BinaryRelationExpression::GREATER) + (">=", BinaryRelationExpression::GREATER_OR_EQUAL) + ; + } + }; + +} +} +} +#endif /* KEYWORDS_H */ + diff --git a/src/parser/PrismParser/VariableState.h b/src/parser/PrismParser/VariableState.h new file mode 100644 index 000000000..dd8fb0d80 --- /dev/null +++ b/src/parser/PrismParser/VariableState.h @@ -0,0 +1,96 @@ +/* + * File: VariableState.h + * Author: nafur + * + * Created on April 10, 2013, 4:43 PM + */ + +#ifndef VARIABLESTATE_H +#define VARIABLESTATE_H + +#include "src/ir/IR.h" +#include "Includes.h" + +namespace storm { +namespace parser { +namespace prism { + +using namespace storm::ir; +using namespace storm::ir::expressions; + +struct VariableState : public storm::ir::VariableAdder { + + public: + VariableState() + : keywords(), nextBooleanVariableIndex(0), nextIntegerVariableIndex(0) + { + } + + keywordsStruct keywords; + + // Used for indexing the variables. + uint_fast64_t nextBooleanVariableIndex; + uint_fast64_t nextIntegerVariableIndex; + + // Structures mapping variable and constant names to the corresponding expression nodes of + // the intermediate representation. + struct qi::symbols> integerVariables_, booleanVariables_; + struct qi::symbols> integerConstants_, booleanConstants_, doubleConstants_; + struct qi::symbols moduleMap_; + + // A structure representing the identity function over identifier names. + struct variableNamesStruct : qi::symbols { } integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_, + localBooleanVariables_, localIntegerVariables_, assignedLocalBooleanVariables_, assignedLocalIntegerVariables_; + + uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init) { + std::shared_ptr res = this->booleanVariables_.at(name); + if (res != nullptr) { + return res->getVariableIndex(); + } + std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::bool_, this->nextBooleanVariableIndex, name)); + this->booleanVariables_.add(name, varExpr); + this->booleanVariableNames_.add(name, name); + this->nextBooleanVariableIndex++; + return this->nextBooleanVariableIndex-1; + } + + uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init) { + std::shared_ptr res = this->integerVariables_.at(name); + if (res != nullptr) { + return res->getVariableIndex(); + } + std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::int_, this->nextIntegerVariableIndex, name, lower, upper)); + this->integerVariables_.add(name, varExpr); + this->integerVariableNames_.add(name, name); + this->nextIntegerVariableIndex++; + return this->nextIntegerVariableIndex-1; + } + + bool isFreeIdentifier(std::string& s) const { + if (this->integerVariableNames_.find(s) != nullptr) return false; + if (this->allConstantNames_.find(s) != nullptr) return false; + if (this->labelNames_.find(s) != nullptr) return false; + if (this->moduleNames_.find(s) != nullptr) return false; + if (this->keywords.find(s) != nullptr) return false; + return true; + } + bool isIdentifier(std::string& s) const { + if (this->allConstantNames_.find(s) != nullptr) return false; + if (this->keywords.find(s) != nullptr) return false; + return true; + } + + void prepareForSecondRun() { + integerConstants_.clear(); + booleanConstants_.clear(); + doubleConstants_.clear(); + allConstantNames_.clear(); + } +}; + +} +} +} + +#endif /* VARIABLESTATE_H */ + From b92260fed0c433769bef6e9ee559fa78fca3c7b9 Mon Sep 17 00:00:00 2001 From: gereon Date: Sat, 20 Apr 2013 01:18:17 +0200 Subject: [PATCH 075/152] A lot of work on PrismParser: * Created a distinct parser for each expression type and for identifiers * Removed all expression rules from PrismParser, using new parsers instead * Reduced excessive usage of boost::lambda, using semantic actions only for single calls * Moved actual state to new class (-> VariableState, whole two-run-logic can probably implemented there) * Much cleanup Work should be finished on expression parser, but not yet on prism parser... --- src/parser/PrismParser.cpp | 132 ++++++++---------- src/parser/PrismParser.h | 36 ++--- src/parser/PrismParser/BaseGrammar.h | 98 +++++++++++++ .../PrismParser/BooleanExpressionGrammar.cpp | 54 +++---- .../PrismParser/BooleanExpressionGrammar.h | 35 +---- .../ConstBooleanExpressionGrammar.cpp | 54 ++++--- .../ConstBooleanExpressionGrammar.h | 23 +-- .../ConstDoubleExpressionGrammar.cpp | 53 +++++++ .../ConstDoubleExpressionGrammar.h | 43 ++++++ .../ConstIntegerExpressionGrammar.cpp | 29 ++-- .../ConstIntegerExpressionGrammar.h | 11 +- src/parser/PrismParser/IdentifierGrammars.cpp | 23 +++ src/parser/PrismParser/IdentifierGrammars.h | 36 +++++ src/parser/PrismParser/Includes.h | 6 +- .../PrismParser/IntegerExpressionGrammar.cpp | 55 +++----- .../PrismParser/IntegerExpressionGrammar.h | 28 +--- .../{UtilityGrammars.h => Tokens.h} | 46 +++--- src/parser/PrismParser/VariableState.h | 90 +++++++++--- 18 files changed, 540 insertions(+), 312 deletions(-) create mode 100644 src/parser/PrismParser/BaseGrammar.h create mode 100644 src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp create mode 100644 src/parser/PrismParser/ConstDoubleExpressionGrammar.h create mode 100644 src/parser/PrismParser/IdentifierGrammars.cpp create mode 100644 src/parser/PrismParser/IdentifierGrammars.h rename src/parser/PrismParser/{UtilityGrammars.h => Tokens.h} (85%) diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index e1aaacaab..e31e31b8a 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -6,12 +6,15 @@ */ #include "PrismParser.h" + #include "src/utility/OsDetection.h" -#include "src/parser/PrismParser/VariableState.h" -#include "src/parser/PrismParser/IntegerExpressionGrammar.h" -#include "src/parser/PrismParser/ConstIntegerExpressionGrammar.h" + #include "src/parser/PrismParser/BooleanExpressionGrammar.h" #include "src/parser/PrismParser/ConstBooleanExpressionGrammar.h" +#include "src/parser/PrismParser/ConstDoubleExpressionGrammar.h" +#include "src/parser/PrismParser/ConstIntegerExpressionGrammar.h" +#include "src/parser/PrismParser/IntegerExpressionGrammar.h" +#include "src/parser/PrismParser/VariableState.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFileFormatException.h" @@ -40,72 +43,44 @@ namespace storm { namespace parser { -PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type(start) { + void dump(const std::string& s) { + std::cerr << "Dump: " << s << std::endl; + } + /*void dump(const std::string& s, ) { + std::cerr << "Dump: " << s << std::endl; + }*/ + + std::shared_ptr addIntegerConstant(const std::string& name, const std::shared_ptr value, std::shared_ptr state) { + std::cerr << "addIntegerConstant: " << name << std::endl; + state->integerConstants_.add(name, value); + state->allConstantNames_.add(name, name); + return value; + } - this->state = std::shared_ptr(new storm::parser::prism::VariableState()); - storm::parser::prism::IntegerExpressionGrammar intExpr(this->state); - storm::parser::prism::ConstIntegerExpressionGrammar constIntExpr(this->state); - storm::parser::prism::BooleanExpressionGrammar boolExpr(this->state); - storm::parser::prism::ConstBooleanExpressionGrammar constBoolExpr(this->state); +PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type(start), state(new storm::parser::prism::VariableState()) { // This rule defines all identifiers that have not been previously used. - identifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&storm::parser::prism::VariableState::isIdentifier, this->state.get(), qi::_1) ]; + identifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&storm::parser::prism::VariableState::isIdentifier, *this->state, qi::_1) ]; identifierName.name("identifier"); - freeIdentifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&storm::parser::prism::VariableState::isFreeIdentifier, this->state.get(), qi::_1) ]; + freeIdentifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&storm::parser::prism::VariableState::isFreeIdentifier, *this->state, qi::_1) ]; freeIdentifierName.name("unused identifier"); - - // This block defines all literal expressions. - booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; - booleanLiteralExpression.name("boolean literal"); - doubleLiteralExpression = qi::double_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; - doubleLiteralExpression.name("double literal"); - - // This block defines all expressions that are variables. - std::shared_ptr intvarexpr = std::shared_ptr(new VariableExpression(BaseExpression::int_, std::numeric_limits::max(), "int", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); - std::shared_ptr boolvarexpr = std::shared_ptr(new VariableExpression(BaseExpression::bool_, std::numeric_limits::max(), "int", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); - integerVariableExpression = identifierName[qi::_val = intvarexpr]; - integerVariableExpression.name("integer variable"); - booleanVariableExpression = identifierName[qi::_val = boolvarexpr]; - booleanVariableExpression.name("boolean variable"); - - // This block defines all atomic expressions that are constant, i.e. literals and constants. - booleanConstantExpression %= (this->state->booleanConstants_ | booleanLiteralExpression); - booleanConstantExpression.name("boolean constant or literal"); - doubleConstantExpression %= (this->state->doubleConstants_ | doubleLiteralExpression); - doubleConstantExpression.name("double constant or literal"); - - // This block defines all expressions of type double that are by syntax constant. That is, they are evaluable given the values for all constants. - constantAtomicDoubleExpression %= (qi::lit("(") >> constantDoubleExpression >> qi::lit(")") | doubleConstantExpression); - constantAtomicDoubleExpression.name("constant double expression"); - constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> constantAtomicDoubleExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::double_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::TIMES)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::double_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::DIVIDE))]]; - constantDoubleMultExpression.name("constant double expression"); - constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantDoubleMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::double_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::double_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::MINUS))]]; - constantDoublePlusExpression.name("constant double expression"); - constantDoubleExpression %= constantDoublePlusExpression; - constantDoubleExpression.name("constant double expression"); - // This block defines all entities that are needed for parsing labels. - labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> freeIdentifierName >> -qi::lit("\"") >> qi::lit("=") >> boolExpr >> qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_2)), phoenix::bind(this->state->labelNames_.add, qi::_1, qi::_1)]; + labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> freeIdentifierName >> -qi::lit("\"") >> qi::lit("=") >> prism::BooleanExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_2)), phoenix::bind(this->state->labelNames_.add, qi::_1, qi::_1)]; labelDefinition.name("label declaration"); labelDefinitionList %= *labelDefinition(qi::_r1); labelDefinitionList.name("label declaration list"); // This block defines all entities that are needed for parsing a reward model. - stateRewardDefinition = (boolExpr > qi::lit(":") > constantDoubleExpression >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; + stateRewardDefinition = (prism::BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > prism::ConstDoubleExpressionGrammar::instance(this->state) >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; stateRewardDefinition.name("state reward definition"); - transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > boolExpr > qi::lit(":") > constantDoubleExpression > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; + transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > prism::BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; transitionRewardDefinition.name("transition reward definition"); rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > freeIdentifierName > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> qi::lit("endrewards"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_a, qi::_b)))]; rewardDefinition.name("reward definition"); rewardDefinitionList = *rewardDefinition(qi::_r1); rewardDefinitionList.name("reward definition list"); - // This block defines auxiliary entities that are used to check whether a certain variable exist. - booleanVariableName %= this->state->booleanVariableNames_; - booleanVariableName.name("boolean variable"); - integerVariableName %= this->state->integerVariableNames_; - integerVariableName.name("integer variable"); commandName %= this->state->commandNames_; commandName.name("command name"); unassignedLocalBooleanVariableName %= this->state->localBooleanVariables_ - this->state->assignedLocalBooleanVariables_; @@ -114,19 +89,23 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type unassignedLocalIntegerVariableName.name("unassigned local integer variable"); // This block defines all entities that are needed for parsing a single command. - assignmentDefinition = (qi::lit("(") >> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > intExpr > qi::lit(")"))[phoenix::bind(this->state->assignedLocalIntegerVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))] | (qi::lit("(") > unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > boolExpr > qi::lit(")"))[phoenix::bind(this->state->assignedLocalBooleanVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))]; + assignmentDefinition = (qi::lit("(") >> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > prism::IntegerExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(this->state->assignedLocalIntegerVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))] | (qi::lit("(") > unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > prism::BooleanExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(this->state->assignedLocalBooleanVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))]; assignmentDefinition.name("assignment"); assignmentDefinitionList = assignmentDefinition(qi::_r1, qi::_r2) % "&"; assignmentDefinitionList.name("assignment list"); - updateDefinition = (constantDoubleExpression > qi::lit(":")[phoenix::clear(phoenix::ref(this->state->assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(this->state->assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b)]; + updateDefinition = (prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(":")[phoenix::clear(phoenix::ref(this->state->assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(this->state->assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b)]; updateDefinition.name("update"); updateListDefinition = +updateDefinition % "+"; updateListDefinition.name("update list"); - commandDefinition = (qi::lit("[") > -((freeIdentifierName[phoenix::bind(this->state->commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1]) > qi::lit("]") > boolExpr > qi::lit("->") > updateListDefinition > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; + commandDefinition = ( + qi::lit("[") > -( + (freeIdentifierName[phoenix::bind(this->state->commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1] + ) > qi::lit("]") > prism::BooleanExpressionGrammar::instance(this->state) > qi::lit("->") > updateListDefinition > qi::lit(";") + )[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; commandDefinition.name("command"); // This block defines all entities that are needed for parsing variable definitions. - booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > constBoolExpr[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) + booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > prism::ConstBooleanExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) [ //qi::_a = phoenix::bind(&VariableState::addBooleanVariable, *this->state.get(), qi::_1), qi::_a = phoenix::bind(&storm::parser::prism::VariableState::addBooleanVariable, *this->state, qi::_1, qi::_b), @@ -135,7 +114,10 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type phoenix::bind(this->state->localBooleanVariables_.add, qi::_1, qi::_1) ]; booleanVariableDefinition.name("boolean variable declaration"); - integerVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("[") > constIntExpr > qi::lit("..") > constIntExpr > qi::lit("]") > -(qi::lit("init") > constIntExpr[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) + + integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; + integerLiteralExpression.name("integer literal"); + integerVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("[") > integerLiteralExpression > qi::lit("..") > integerLiteralExpression > qi::lit("]") > -(qi::lit("init") > prism::ConstIntegerExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) [ qi::_a = phoenix::bind(&storm::parser::prism::VariableState::addIntegerVariable, *this->state, qi::_1, qi::_2, qi::_3, qi::_b), phoenix::push_back(qi::_r1, phoenix::construct(qi::_a, qi::_1, qi::_2, qi::_3, qi::_b)), @@ -148,7 +130,7 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type // This block defines all entities that are needed for parsing a module. moduleDefinition = (qi::lit("module") >> freeIdentifierName - [phoenix::clear(phoenix::ref(this->state->localBooleanVariables_)), phoenix::clear(phoenix::ref(this->state->localIntegerVariables_))] + [phoenix::bind(&prism::VariableState::startModule, *this->state)] >> *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) >> +commandDefinition > qi::lit("endmodule")) [ phoenix::bind(this->state->moduleNames_.add, qi::_1, qi::_1), @@ -172,14 +154,20 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type moduleDefinitionList %= +(moduleDefinition | moduleRenaming); moduleDefinitionList.name("module list"); - integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; - integerLiteralExpression.name("integer literal"); // This block defines all entities that are needed for parsing constant definitions. - definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") > booleanLiteralExpression > qi::lit(";"))[phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; + definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") > prism::ConstBooleanExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; definedBooleanConstantDefinition.name("defined boolean constant declaration"); - definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> freeIdentifierName >> qi::lit("=") > integerLiteralExpression > qi::lit(";"))[phoenix::bind(this->state->integerConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; + definedIntegerConstantDefinition = ( + qi::lit("const") >> + qi::lit("int")[phoenix::bind(&dump, "const int")] >> + freeIdentifierName >> + qi::lit("=")[phoenix::bind(&dump, "const int = ")] >> + //constIntExpr.integerLiteralExpression[phoenix::bind(&dump, "const int = ")] >> + prism::ConstIntegerExpressionGrammar::instance(this->state)[phoenix::bind(&dump, "const int = ")] >> + qi::lit(";")[phoenix::bind(&dump, "const int = ;")] + )[ qi::_val = phoenix::bind(&addIntegerConstant, qi::_1, qi::_2, this->state) ]; definedIntegerConstantDefinition.name("defined integer constant declaration"); - definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") > doubleLiteralExpression > qi::lit(";"))[phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; + definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") > prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; definedDoubleConstantDefinition.name("defined double constant declaration"); undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; undefinedBooleanConstantDefinition.name("undefined boolean constant declaration"); @@ -187,32 +175,28 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type undefinedIntegerConstantDefinition.name("undefined integer constant declaration"); undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; undefinedDoubleConstantDefinition.name("undefined double constant declaration"); - definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); + definedConstantDefinition %= (definedBooleanConstantDefinition[phoenix::bind(&dump, "")] | definedIntegerConstantDefinition[phoenix::bind(&dump, "")] | definedDoubleConstantDefinition[phoenix::bind(&dump, "")]); definedConstantDefinition.name("defined constant declaration"); undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3)); undefinedConstantDefinition.name("undefined constant declaration"); - constantDefinitionList = *(definedConstantDefinition | undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3)); + constantDefinitionList = *(definedConstantDefinition[phoenix::bind(&dump, "")] | undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3)[phoenix::bind(&dump, "")]); constantDefinitionList.name("constant declaration list"); // This block defines all entities that are needed for parsing a program. modelTypeDefinition = modelType_; modelTypeDefinition.name("model type"); - start = (modelTypeDefinition > constantDefinitionList(qi::_a, qi::_b, qi::_c) > moduleDefinitionList > rewardDefinitionList(qi::_d) > labelDefinitionList(qi::_e))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_d, qi::_e)]; + start = ( + modelTypeDefinition[phoenix::bind(&dump, "")] > + constantDefinitionList(qi::_a, qi::_b, qi::_c)[phoenix::bind(&dump, "")] > + moduleDefinitionList[phoenix::bind(&dump, "")] > + rewardDefinitionList(qi::_d)[phoenix::bind(&dump, "")] > + labelDefinitionList(qi::_e)[phoenix::bind(&dump, "")] + )[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_d, qi::_e)]; start.name("probabilistic program declaration"); } void PrismParser::PrismGrammar::prepareForSecondRun() { - // Clear constants. - storm::parser::prism::IntegerExpressionGrammar intExpr(this->state); - storm::parser::prism::ConstIntegerExpressionGrammar constIntExpr(this->state); - this->state->prepareForSecondRun(); - - // Override variable expressions: only allow declared variables. - integerVariableExpression %= this->state->integerVariables_; - integerVariableExpression.name("integer variable"); - booleanVariableExpression %= this->state->booleanVariables_; - booleanVariableExpression.name("boolean variable"); } /*! diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 86b7eb4d7..a32487c78 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -11,8 +11,14 @@ // All classes of the intermediate representation are used. #include "src/ir/IR.h" #include "src/parser/PrismParser/Includes.h" -#include "src/parser/PrismParser/UtilityGrammars.h" +#include "src/parser/PrismParser/Tokens.h" +#include "src/parser/PrismParser/IdentifierGrammars.h" #include "src/parser/PrismParser/VariableState.h" +#include "src/parser/PrismParser/ConstBooleanExpressionGrammar.h" +#include "src/parser/PrismParser/ConstDoubleExpressionGrammar.h" +#include "src/parser/PrismParser/ConstIntegerExpressionGrammar.h" +#include "src/parser/PrismParser/BooleanExpressionGrammar.h" +#include "src/parser/PrismParser/IntegerExpressionGrammar.h" // Used for file input. #include @@ -62,6 +68,7 @@ public: qi::rule>, Skipper> moduleRenaming; // Rules for variable definitions. + qi::rule(), Skipper> integerLiteralExpression; qi::rule&, std::vector&, std::map&, std::map&), Skipper> variableDefinition; qi::rule&, std::map&), qi::locals>, Skipper> booleanVariableDefinition; qi::rule&, std::map&), qi::locals>, Skipper> integerVariableDefinition; @@ -74,8 +81,6 @@ public: qi::rule&, std::map&), Skipper> assignmentDefinition; // Rules for variable/command names. - qi::rule integerVariableName; - qi::rule booleanVariableName; qi::rule commandName; qi::rule unassignedLocalBooleanVariableName; qi::rule unassignedLocalIntegerVariableName; @@ -91,7 +96,6 @@ public: qi::rule>&), Skipper> labelDefinition; // Rules for constant definitions. - qi::rule(), Skipper> integerLiteralExpression; qi::rule(), Skipper> constantDefinition; qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; qi::rule(), Skipper> definedConstantDefinition; @@ -102,34 +106,14 @@ public: qi::rule(), Skipper> definedIntegerConstantDefinition; qi::rule(), Skipper> definedDoubleConstantDefinition; - qi::rule freeIdentifierName; - qi::rule identifierName; + qi::rule freeIdentifierName; + qi::rule identifierName; - // The starting point for arbitrary expressions. - qi::rule(), Skipper> expression; - // Rules with double result type. - qi::rule(), Skipper> constantDoubleExpression; - qi::rule(), qi::locals, Skipper> constantDoublePlusExpression; - qi::rule(), qi::locals, Skipper> constantDoubleMultExpression; - qi::rule(), Skipper> constantAtomicDoubleExpression; // Rules for variable recognition. - qi::rule(), Skipper> booleanVariableExpression; qi::rule(), Skipper> booleanVariableCreatorExpression; - qi::rule(), Skipper> integerVariableExpression; qi::rule(), qi::locals>, Skipper> integerVariableCreatorExpression; - // Rules for constant recognition. - qi::rule(), Skipper> constantExpression; - qi::rule(), Skipper> booleanConstantExpression; - qi::rule(), Skipper> integerConstantExpression; - qi::rule(), Skipper> doubleConstantExpression; - - // Rules for literal recognition. - qi::rule(), Skipper> literalExpression; - qi::rule(), Skipper> booleanLiteralExpression; - qi::rule(), Skipper> doubleLiteralExpression; - storm::parser::prism::keywordsStruct keywords_; storm::parser::prism::modelTypeStruct modelType_; storm::parser::prism::relationalOperatorStruct relations_; diff --git a/src/parser/PrismParser/BaseGrammar.h b/src/parser/PrismParser/BaseGrammar.h new file mode 100644 index 000000000..bcc5f3d44 --- /dev/null +++ b/src/parser/PrismParser/BaseGrammar.h @@ -0,0 +1,98 @@ +/* + * File: Keywords.h + * Author: nafur + * + * Created on April 10, 2013, 6:03 PM + */ + +#ifndef BASEGRAMMAR_H +#define BASEGRAMMAR_H + +#include "Includes.h" + +#include "VariableState.h" + +namespace storm { +namespace parser { +namespace prism { + + template + class BaseGrammar { + public: + BaseGrammar(std::shared_ptr& state) : state(state) {} + + static T& instance(std::shared_ptr& state = nullptr) { + if (BaseGrammar::instanceObject == nullptr) { + BaseGrammar::instanceObject = std::shared_ptr(new T(state)); + } + return *BaseGrammar::instanceObject; + } + + std::shared_ptr createBoolLiteral(const bool value) { + return std::shared_ptr(new BooleanLiteral(value)); + } + std::shared_ptr createDoubleLiteral(const double value) { + return std::shared_ptr(new DoubleLiteral(value)); + } + std::shared_ptr createIntLiteral(const int_fast64_t value) { + return std::shared_ptr(new IntegerLiteral(value)); + } + + std::shared_ptr createPlus(const std::shared_ptr left, bool addition, const std::shared_ptr right, BaseExpression::ReturnType type) { + if (addition) { + return std::shared_ptr(new BinaryNumericalFunctionExpression(type, left, right, BinaryNumericalFunctionExpression::PLUS)); + } else { + return std::shared_ptr(new BinaryNumericalFunctionExpression(type, left, right, BinaryNumericalFunctionExpression::MINUS)); + } + } + std::shared_ptr createDoublePlus(const std::shared_ptr left, bool addition, const std::shared_ptr right) { + return this->createPlus(left, addition, right, BaseExpression::double_); + } + std::shared_ptr createIntPlus(const std::shared_ptr left, bool addition, const std::shared_ptr right) { + return this->createPlus(left, addition, right, BaseExpression::int_); + } + + std::shared_ptr createIntMult(const std::shared_ptr left, const std::shared_ptr right) { + return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::int_, left, right, BinaryNumericalFunctionExpression::TIMES)); + } + std::shared_ptr createDoubleMult(const std::shared_ptr left, bool multiplication, const std::shared_ptr right) { + if (multiplication) { + return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::TIMES)); + } else { + return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::DIVIDE)); + } + } + + std::shared_ptr createRelation(std::shared_ptr left, BinaryRelationExpression::RelationType relationType, std::shared_ptr right) { + return std::shared_ptr(new BinaryRelationExpression(left, right, relationType)); + } + std::shared_ptr createNot(std::shared_ptr child) { + return std::shared_ptr(new UnaryBooleanFunctionExpression(child, UnaryBooleanFunctionExpression::NOT)); + } + std::shared_ptr createAnd(std::shared_ptr left, std::shared_ptr right) { + return std::shared_ptr(new BinaryBooleanFunctionExpression(left, right, BinaryBooleanFunctionExpression::AND)); + } + std::shared_ptr createOr(std::shared_ptr left, std::shared_ptr right) { + return std::shared_ptr(new BinaryBooleanFunctionExpression(left, right, BinaryBooleanFunctionExpression::OR)); + } + std::shared_ptr getBoolVariable(const std::string name) { + return state->getBooleanVariable(name); + } + std::shared_ptr getIntVariable(const std::string name) { + return state->getIntegerVariable(name); + } + + protected: + std::shared_ptr state; + + private: + static std::shared_ptr instanceObject; + }; + + template + std::shared_ptr BaseGrammar::instanceObject; +} +} +} +#endif /* BASEGRAMMAR_H */ + diff --git a/src/parser/PrismParser/BooleanExpressionGrammar.cpp b/src/parser/PrismParser/BooleanExpressionGrammar.cpp index 3ad148c08..101db9cce 100644 --- a/src/parser/PrismParser/BooleanExpressionGrammar.cpp +++ b/src/parser/PrismParser/BooleanExpressionGrammar.cpp @@ -1,53 +1,35 @@ #include "BooleanExpressionGrammar.h" +#include "IntegerExpressionGrammar.h" +#include "ConstBooleanExpressionGrammar.h" + namespace storm { namespace parser { namespace prism { BooleanExpressionGrammar::BooleanExpressionGrammar(std::shared_ptr& state) - : BooleanExpressionGrammar::base_type(booleanExpression), state(state) { - - IntegerExpressionGrammar intExpr(this->state); + : BooleanExpressionGrammar::base_type(booleanExpression), BaseGrammar(state) { - // This rule defines all identifiers that have not been previously used. - identifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&storm::parser::prism::VariableState::isIdentifier, this->state.get(), qi::_1) ]; - identifierName.name("identifier"); - freeIdentifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&storm::parser::prism::VariableState::isFreeIdentifier, this->state.get(), qi::_1) ]; - freeIdentifierName.name("unused identifier"); - - // This block defines all literal expressions. - booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; - booleanLiteralExpression.name("boolean literal"); + booleanExpression %= orExpression; + booleanExpression.name("boolean expression"); + orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::bind(&BaseGrammar::createOr, this, qi::_val, qi::_1)]; + orExpression.name("boolean expression"); - // This block defines all expressions that are variables. - std::shared_ptr boolvarexpr = std::shared_ptr(new VariableExpression(BaseExpression::bool_, std::numeric_limits::max(), "bool", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); - booleanVariableExpression = identifierName[qi::_val = boolvarexpr]; - booleanVariableExpression.name("boolean variable"); + andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = phoenix::bind(&BaseGrammar::createAnd, this, qi::_val, qi::_1)]; + andExpression.name("boolean expression"); - // This block defines all atomic expressions that are constant, i.e. literals and constants. - booleanConstantExpression %= (this->state->booleanConstants_ | booleanLiteralExpression); - booleanConstantExpression.name("boolean constant or literal"); + notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::bind(&BaseGrammar::createNot, this, qi::_1)]; + notExpression.name("boolean expression"); - // This block defines all expressions of type boolean. - relativeExpression = (intExpr >> relations_ >> intExpr)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; - relativeExpression.name("relative expression"); - atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")") | booleanConstantExpression); + atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")") | ConstBooleanExpressionGrammar::instance(this->state)); atomicBooleanExpression.name("boolean expression"); - notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, UnaryBooleanFunctionExpression::NOT))]; - notExpression.name("boolean expression"); - andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::AND))]; - andExpression.name("boolean expression"); - orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::OR))]; - orExpression.name("boolean expression"); - booleanExpression %= orExpression; - booleanExpression.name("boolean expression"); - // This block defines auxiliary entities that are used to check whether a certain variable exist. - booleanVariableName %= this->state->booleanVariableNames_; - booleanVariableName.name("boolean variable"); - unassignedLocalBooleanVariableName %= this->state->localBooleanVariables_ - this->state->assignedLocalBooleanVariables_; - unassignedLocalBooleanVariableName.name("unassigned local boolean variable"); + relativeExpression = (IntegerExpressionGrammar::instance(this->state) >> relations_ >> IntegerExpressionGrammar::instance(this->state))[qi::_val = phoenix::bind(&BaseGrammar::createRelation, this, qi::_1, qi::_2, qi::_3)]; + relativeExpression.name("relative expression"); + + booleanVariableExpression = IdentifierGrammar::instance(this->state)[qi::_val = phoenix::bind(&BaseGrammar::getBoolVariable, this, qi::_1)]; + booleanVariableExpression.name("boolean variable"); } } diff --git a/src/parser/PrismParser/BooleanExpressionGrammar.h b/src/parser/PrismParser/BooleanExpressionGrammar.h index db5ad0951..9d14c5ec3 100644 --- a/src/parser/PrismParser/BooleanExpressionGrammar.h +++ b/src/parser/PrismParser/BooleanExpressionGrammar.h @@ -10,52 +10,29 @@ #include "Includes.h" #include "VariableState.h" -#include "IntegerExpressionGrammar.h" +#include "IdentifierGrammars.h" +#include "Tokens.h" + +#include namespace storm { namespace parser { namespace prism { -class BooleanExpressionGrammar : public qi::grammar(), Skipper, Skipper> { +class BooleanExpressionGrammar : public qi::grammar(), Skipper, Unused>, public BaseGrammar { public: BooleanExpressionGrammar(std::shared_ptr& state); private: - // Rules for variable/command names. - qi::rule integerVariableName; - qi::rule booleanVariableName; - qi::rule unassignedLocalBooleanVariableName; - qi::rule unassignedLocalIntegerVariableName; - - qi::rule freeIdentifierName; - qi::rule identifierName; - - // The starting point for arbitrary expressions. - qi::rule(), Skipper> expression; - - // Rules with boolean result type. - qi::rule(), Skipper, Skipper> booleanExpression; + qi::rule(), Skipper, Unused> booleanExpression; qi::rule(), Skipper> orExpression; qi::rule(), Skipper> andExpression; qi::rule(), Skipper> notExpression; qi::rule(), Skipper> atomicBooleanExpression; qi::rule(), Skipper> relativeExpression; - - // Rules for variable recognition. qi::rule(), Skipper> booleanVariableExpression; - qi::rule(), Skipper> booleanVariableCreatorExpression; - - // Rules for constant recognition. - qi::rule(), Skipper> booleanConstantExpression; - // Rules for literal recognition. - qi::rule(), Skipper> booleanLiteralExpression; - - // A structure mapping the textual representation of a binary relation to the representation - // of the intermediate representation. storm::parser::prism::relationalOperatorStruct relations_; - - std::shared_ptr state; }; diff --git a/src/parser/PrismParser/ConstBooleanExpressionGrammar.cpp b/src/parser/PrismParser/ConstBooleanExpressionGrammar.cpp index 53a5f5a96..203894638 100644 --- a/src/parser/PrismParser/ConstBooleanExpressionGrammar.cpp +++ b/src/parser/PrismParser/ConstBooleanExpressionGrammar.cpp @@ -1,31 +1,53 @@ #include "ConstBooleanExpressionGrammar.h" +#include "ConstIntegerExpressionGrammar.h" + namespace storm { namespace parser { namespace prism { + std::shared_ptr ConstBooleanExpressionGrammar::createRelation(std::shared_ptr left, BinaryRelationExpression::RelationType relationType, std::shared_ptr right) { + return std::shared_ptr(new BinaryRelationExpression(left, right, relationType)); + } + std::shared_ptr ConstBooleanExpressionGrammar::createNot(std::shared_ptr child) { + return std::shared_ptr(new UnaryBooleanFunctionExpression(child, UnaryBooleanFunctionExpression::NOT)); + } + std::shared_ptr ConstBooleanExpressionGrammar::createAnd(std::shared_ptr left, std::shared_ptr right) { + return std::shared_ptr(new BinaryBooleanFunctionExpression(left, right, BinaryBooleanFunctionExpression::AND)); + } + std::shared_ptr ConstBooleanExpressionGrammar::createOr(std::shared_ptr left, std::shared_ptr right) { + return std::shared_ptr(new BinaryBooleanFunctionExpression(left, right, BinaryBooleanFunctionExpression::OR)); + } + std::shared_ptr ConstBooleanExpressionGrammar::createLiteral(const bool value) { + return std::shared_ptr(new BooleanLiteral(value)); + } ConstBooleanExpressionGrammar::ConstBooleanExpressionGrammar(std::shared_ptr& state) - : ConstBooleanExpressionGrammar::base_type(constantBooleanExpression), state(state) { + : ConstBooleanExpressionGrammar::base_type(constantBooleanExpression), BaseGrammar(state) { - ConstIntegerExpressionGrammar constIntExpr(this->state); + constantBooleanExpression %= constantOrExpression; + constantBooleanExpression.name("constant boolean expression"); + + constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::bind(&ConstBooleanExpressionGrammar::createOr, this, qi::_val, qi::_1)]; + constantOrExpression.name("constant boolean expression"); + + constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::bind(&ConstBooleanExpressionGrammar::createAnd, this, qi::_val, qi::_1)]; + constantAndExpression.name("constant boolean expression"); + + constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::bind(&ConstBooleanExpressionGrammar::createNot, this, qi::_1)]; + constantNotExpression.name("constant boolean expression"); - booleanLiteralExpression = qi::bool_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; - booleanLiteralExpression.name("boolean literal"); - booleanConstantExpression %= (this->state->booleanConstants_ | booleanLiteralExpression); - booleanConstantExpression.name("boolean constant or literal"); - constantRelativeExpression = (constIntExpr >> relations_ >> constIntExpr)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, qi::_3, qi::_2))]; - constantRelativeExpression.name("constant boolean expression"); constantAtomicBooleanExpression %= (constantRelativeExpression | qi::lit("(") >> constantBooleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression); constantAtomicBooleanExpression.name("constant boolean expression"); - constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_1, UnaryBooleanFunctionExpression::NOT))]; - constantNotExpression.name("constant boolean expression"); - constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::AND))]; - constantAndExpression.name("constant boolean expression"); - constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::construct>(phoenix::new_(qi::_val, qi::_1, BinaryBooleanFunctionExpression::OR))]; - constantOrExpression.name("constant boolean expression"); - constantBooleanExpression %= constantOrExpression; - constantBooleanExpression.name("constant boolean expression"); + + constantRelativeExpression = (ConstIntegerExpressionGrammar::instance(this->state) >> relations_ >> ConstIntegerExpressionGrammar::instance(this->state))[qi::_val = phoenix::bind(&ConstBooleanExpressionGrammar::createRelation, this, qi::_1, qi::_2, qi::_3)]; + constantRelativeExpression.name("constant boolean expression"); + + booleanConstantExpression %= (this->state->booleanConstants_ | booleanLiteralExpression); + booleanConstantExpression.name("boolean constant or literal"); + + booleanLiteralExpression = qi::bool_[qi::_val = phoenix::bind(&ConstBooleanExpressionGrammar::createLiteral, this, qi::_1)]; + booleanLiteralExpression.name("boolean literal"); } } } diff --git a/src/parser/PrismParser/ConstBooleanExpressionGrammar.h b/src/parser/PrismParser/ConstBooleanExpressionGrammar.h index 24166035e..4c8a5f7fb 100644 --- a/src/parser/PrismParser/ConstBooleanExpressionGrammar.h +++ b/src/parser/PrismParser/ConstBooleanExpressionGrammar.h @@ -9,35 +9,36 @@ #define CONSTBOOLEANEXPRESSIONGRAMMAR_H #include "Includes.h" -#include "ConstIntegerExpressionGrammar.h" #include "VariableState.h" -#include "UtilityGrammars.h" +#include "IdentifierGrammars.h" +#include "Tokens.h" namespace storm { namespace parser { namespace prism { -class ConstBooleanExpressionGrammar : public qi::grammar(), Skipper, Skipper> { +class ConstBooleanExpressionGrammar : public qi::grammar(), Skipper, Unused>, public BaseGrammar { public: ConstBooleanExpressionGrammar(std::shared_ptr& state); + private: - - qi::rule(), Skipper> booleanLiteralExpression; - qi::rule(), Skipper> booleanConstantExpression; - qi::rule(), Skipper> relativeExpression; - qi::rule(), Skipper, Skipper> constantBooleanExpression; + qi::rule(), Skipper, Unused> constantBooleanExpression; qi::rule(), Skipper> constantOrExpression; qi::rule(), Skipper> constantAndExpression; qi::rule(), Skipper> constantNotExpression; qi::rule(), Skipper> constantAtomicBooleanExpression; qi::rule(), Skipper> constantRelativeExpression; - + qi::rule(), Skipper> booleanConstantExpression; + qi::rule(), Skipper> booleanLiteralExpression; storm::parser::prism::relationalOperatorStruct relations_; - std::shared_ptr state; - + std::shared_ptr createRelation(std::shared_ptr left, BinaryRelationExpression::RelationType relationType, std::shared_ptr right); + std::shared_ptr createNot(std::shared_ptr child); + std::shared_ptr createAnd(std::shared_ptr left, std::shared_ptr right); + std::shared_ptr createOr(std::shared_ptr left, std::shared_ptr right); + std::shared_ptr createLiteral(const bool value); }; diff --git a/src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp b/src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp new file mode 100644 index 000000000..e569d329c --- /dev/null +++ b/src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp @@ -0,0 +1,53 @@ +#include "ConstDoubleExpressionGrammar.h" + +namespace storm { +namespace parser { +namespace prism { + + + std::shared_ptr ConstDoubleExpressionGrammar::createLiteral(double value) { + return std::shared_ptr(new DoubleLiteral(value)); + } + std::shared_ptr ConstDoubleExpressionGrammar::createPlus(const std::shared_ptr left, bool addition, const std::shared_ptr right) { + if (addition) { + return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::PLUS)); + } else { + return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::MINUS)); + } + } + std::shared_ptr ConstDoubleExpressionGrammar::createMult(const std::shared_ptr left, bool multiplication, const std::shared_ptr right) { + if (multiplication) { + return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::TIMES)); + } else { + return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::DIVIDE)); + } + } + +ConstDoubleExpressionGrammar::ConstDoubleExpressionGrammar(std::shared_ptr& state) + : ConstDoubleExpressionGrammar::base_type(constantDoubleExpression), BaseGrammar(state) { + + constantDoubleExpression %= constantDoublePlusExpression; + constantDoubleExpression.name("constant double expression"); + + constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantDoubleMultExpression) + [phoenix::bind(&ConstDoubleExpressionGrammar::createPlus, this, qi::_val, qi::_a, qi::_1)]; + constantDoublePlusExpression.name("constant double expression"); + + constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> constantAtomicDoubleExpression) + [phoenix::bind(&ConstDoubleExpressionGrammar::createMult, this, qi::_val, qi::_a, qi::_1)]; + constantDoubleMultExpression.name("constant double expression"); + + constantAtomicDoubleExpression %= (qi::lit("(") >> constantDoubleExpression >> qi::lit(")") | doubleConstantExpression); + constantAtomicDoubleExpression.name("constant double expression"); + + doubleConstantExpression %= (this->state->doubleConstants_ | doubleLiteralExpression); + doubleConstantExpression.name("double constant or literal"); + + doubleLiteralExpression = qi::double_[qi::_val = phoenix::bind(&ConstDoubleExpressionGrammar::createLiteral, this, qi::_1)]; + doubleLiteralExpression.name("double literal"); +} + + +} +} +} \ No newline at end of file diff --git a/src/parser/PrismParser/ConstDoubleExpressionGrammar.h b/src/parser/PrismParser/ConstDoubleExpressionGrammar.h new file mode 100644 index 000000000..9d70f9877 --- /dev/null +++ b/src/parser/PrismParser/ConstDoubleExpressionGrammar.h @@ -0,0 +1,43 @@ +/* + * File: ConstDoubleExpressionGrammar.h + * Author: nafur + * + * Created on April 10, 2013, 7:04 PM + */ + +#ifndef CONSTDOUBLEEXPRESSIONGRAMMAR_H +#define CONSTDOUBLEEXPRESSIONGRAMMAR_H + +#include "Includes.h" +#include "VariableState.h" +#include "IdentifierGrammars.h" + +namespace storm { +namespace parser { +namespace prism { + +class ConstDoubleExpressionGrammar : public qi::grammar(), Skipper, Unused>, public BaseGrammar { +public: + ConstDoubleExpressionGrammar(std::shared_ptr& state); + + +private: + qi::rule(), Skipper, Unused> constantDoubleExpression; + qi::rule(), qi::locals, Skipper> constantDoublePlusExpression; + qi::rule(), qi::locals, Skipper> constantDoubleMultExpression; + qi::rule(), Skipper> constantAtomicDoubleExpression; + qi::rule(), Skipper> doubleConstantExpression; + qi::rule(), Skipper> doubleLiteralExpression; + + std::shared_ptr createLiteral(double value); + std::shared_ptr createPlus(const std::shared_ptr left, bool addition, const std::shared_ptr right); + std::shared_ptr createMult(const std::shared_ptr left, bool multiplication, const std::shared_ptr right); +}; + + +} +} +} + +#endif /* CONSTDOUBLEEXPRESSIONGRAMMAR_H */ + diff --git a/src/parser/PrismParser/ConstIntegerExpressionGrammar.cpp b/src/parser/PrismParser/ConstIntegerExpressionGrammar.cpp index ef9d8c91f..233b4492a 100644 --- a/src/parser/PrismParser/ConstIntegerExpressionGrammar.cpp +++ b/src/parser/PrismParser/ConstIntegerExpressionGrammar.cpp @@ -1,27 +1,32 @@ #include "ConstIntegerExpressionGrammar.h" - namespace storm { namespace parser { namespace prism { + ConstIntegerExpressionGrammar::ConstIntegerExpressionGrammar(std::shared_ptr& state) - : ConstIntegerExpressionGrammar::base_type(constantIntegerExpression), state(state) { + : ConstIntegerExpressionGrammar::base_type(constantIntegerExpression), BaseGrammar(state) { - integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; - integerLiteralExpression.name("integer literal"); - integerConstantExpression %= (this->state->integerConstants_ | integerLiteralExpression); - integerConstantExpression.name("integer constant or literal"); + constantIntegerExpression %= constantIntegerPlusExpression; + constantIntegerExpression.name("constant integer expression"); + + constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantIntegerMultExpression) + [qi::_val = phoenix::bind(&BaseGrammar::createIntPlus, this, qi::_val, qi::_a, qi::_1)]; + constantIntegerPlusExpression.name("constant integer expression"); + + constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression) + [qi::_val = phoenix::bind(&BaseGrammar::createIntMult, this, qi::_val, qi::_1)]; + constantIntegerMultExpression.name("constant integer expression"); constantAtomicIntegerExpression %= (qi::lit("(") >> constantIntegerExpression >> qi::lit(")") | integerConstantExpression); constantAtomicIntegerExpression.name("constant integer expression"); - constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::TIMES))]; - constantIntegerMultExpression.name("constant integer expression"); - constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantIntegerMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::MINUS))]]; - constantIntegerPlusExpression.name("constant integer expression"); - constantIntegerExpression %= constantIntegerPlusExpression; - constantIntegerExpression.name("constant integer expression"); + integerConstantExpression %= (this->state->integerConstants_ | integerLiteralExpression); + integerConstantExpression.name("integer constant or literal"); + + integerLiteralExpression = qi::int_[qi::_val = phoenix::bind(&BaseGrammar::createIntLiteral, this, qi::_1)]; + integerLiteralExpression.name("integer literal"); } diff --git a/src/parser/PrismParser/ConstIntegerExpressionGrammar.h b/src/parser/PrismParser/ConstIntegerExpressionGrammar.h index 2c1a3420c..847892e10 100644 --- a/src/parser/PrismParser/ConstIntegerExpressionGrammar.h +++ b/src/parser/PrismParser/ConstIntegerExpressionGrammar.h @@ -10,24 +10,23 @@ #include "Includes.h" #include "VariableState.h" +#include "IdentifierGrammars.h" namespace storm { namespace parser { namespace prism { -class ConstIntegerExpressionGrammar : public qi::grammar(), Skipper, Skipper> { +class ConstIntegerExpressionGrammar : public qi::grammar(), Skipper, Unused>, public BaseGrammar { public: ConstIntegerExpressionGrammar(std::shared_ptr& state); private: - qi::rule(), Skipper> integerLiteralExpression; - qi::rule(), Skipper> integerConstantExpression; - qi::rule(), Skipper, Skipper> constantIntegerExpression; + qi::rule(), Skipper, Unused> constantIntegerExpression; qi::rule(), qi::locals, Skipper> constantIntegerPlusExpression; qi::rule(), Skipper> constantIntegerMultExpression; qi::rule(), Skipper> constantAtomicIntegerExpression; - - std::shared_ptr state; + qi::rule(), Skipper> integerConstantExpression; + qi::rule(), Skipper> integerLiteralExpression; }; diff --git a/src/parser/PrismParser/IdentifierGrammars.cpp b/src/parser/PrismParser/IdentifierGrammars.cpp new file mode 100644 index 000000000..552b6e2c0 --- /dev/null +++ b/src/parser/PrismParser/IdentifierGrammars.cpp @@ -0,0 +1,23 @@ +#include "IdentifierGrammars.h" + +namespace storm { +namespace parser { +namespace prism { + +IdentifierGrammar::IdentifierGrammar(std::shared_ptr& state) + : IdentifierGrammar::base_type(identifierName), BaseGrammar(state) { + + identifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&VariableState::isIdentifier, this->state.get(), qi::_1) ]; + identifierName.name("identifier"); +} + +FreeIdentifierGrammar::FreeIdentifierGrammar(std::shared_ptr& state) + : FreeIdentifierGrammar::base_type(freeIdentifierName), BaseGrammar(state) { + + freeIdentifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&VariableState::isFreeIdentifier, this->state.get(), qi::_1) ]; + freeIdentifierName.name("identifier"); +} + +} +} +} \ No newline at end of file diff --git a/src/parser/PrismParser/IdentifierGrammars.h b/src/parser/PrismParser/IdentifierGrammars.h new file mode 100644 index 000000000..936ee732a --- /dev/null +++ b/src/parser/PrismParser/IdentifierGrammars.h @@ -0,0 +1,36 @@ +/* + * File: Keywords.h + * Author: nafur + * + * Created on April 10, 2013, 6:03 PM + */ + +#ifndef IDENTIFIERGRAMMARS_H +#define IDENTIFIERGRAMMARS_H + +#include "Includes.h" +#include "BaseGrammar.h" +#include "VariableState.h" + +namespace storm { +namespace parser { +namespace prism { + + class IdentifierGrammar : public qi::grammar, public BaseGrammar { + public: + IdentifierGrammar(std::shared_ptr& state); + private: + qi::rule identifierName; + }; + + class FreeIdentifierGrammar : public qi::grammar, public BaseGrammar { + public: + FreeIdentifierGrammar(std::shared_ptr& state); + private: + qi::rule freeIdentifierName; + }; +} +} +} +#endif /* IDENTIFIERGRAMMARS_H */ + diff --git a/src/parser/PrismParser/Includes.h b/src/parser/PrismParser/Includes.h index 39eb5a450..fe3418b2c 100644 --- a/src/parser/PrismParser/Includes.h +++ b/src/parser/PrismParser/Includes.h @@ -8,6 +8,8 @@ #ifndef BOOSTINCLUDES_H #define BOOSTINCLUDES_H +#define DEBUGPRISM + // Used for Boost spirit. #include #include @@ -24,12 +26,12 @@ typedef std::string::const_iterator BaseIteratorType; typedef boost::spirit::classic::position_iterator2 PositionIteratorType; typedef PositionIteratorType Iterator; typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol) Skipper; +typedef BOOST_TYPEOF(qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol | boost::spirit::ascii::space) Skipper2; +typedef boost::spirit::unused_type Unused; #include "src/ir/IR.h" using namespace storm::ir; using namespace storm::ir::expressions; -#include "UtilityGrammars.h" - #endif /* BOOSTINCLUDES_H */ diff --git a/src/parser/PrismParser/IntegerExpressionGrammar.cpp b/src/parser/PrismParser/IntegerExpressionGrammar.cpp index 1d4c2cd19..89933aeb3 100644 --- a/src/parser/PrismParser/IntegerExpressionGrammar.cpp +++ b/src/parser/PrismParser/IntegerExpressionGrammar.cpp @@ -1,45 +1,30 @@ #include "IntegerExpressionGrammar.h" +#include "IdentifierGrammars.h" +#include "ConstIntegerExpressionGrammar.h" + namespace storm { namespace parser { namespace prism { -IntegerExpressionGrammar::IntegerExpressionGrammar(std::shared_ptr& state) - : IntegerExpressionGrammar::base_type(integerExpression), state(state) { - - // This rule defines all identifiers that have not been previously used. - identifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&VariableState::isIdentifier, this->state.get(), qi::_1) ]; - identifierName.name("identifier"); - - // This block defines all literal expressions. - integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; - integerLiteralExpression.name("integer literal"); - - // This block defines all expressions that are variables. - std::shared_ptr intvarexpr = std::shared_ptr(new VariableExpression(BaseExpression::int_, std::numeric_limits::max(), "int", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); - integerVariableExpression = identifierName[qi::_val = intvarexpr]; - integerVariableExpression.name("integer variable"); - - // This block defines all atomic expressions that are constant, i.e. literals and constants. - integerConstantExpression %= (this->state->integerConstants_ | integerLiteralExpression); - integerConstantExpression.name("integer constant or literal"); - - // This block defines all expressions of integral type. - atomicIntegerExpression %= (integerVariableExpression | qi::lit("(") >> integerExpression >> qi::lit(")") | integerConstantExpression); - atomicIntegerExpression.name("integer expression"); - integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression)[qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::TIMES))]; - integerMultExpression.name("integer expression"); - integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> integerMultExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::PLUS)) ] .else_ [qi::_val = phoenix::construct>(phoenix::new_(BaseExpression::int_, qi::_val, qi::_1, BinaryNumericalFunctionExpression::MINUS))]]; - integerPlusExpression.name("integer expression"); - integerExpression %= integerPlusExpression; - integerExpression.name("integer expression"); -} + IntegerExpressionGrammar::IntegerExpressionGrammar(std::shared_ptr& state) + : IntegerExpressionGrammar::base_type(integerExpression), BaseGrammar(state) { -void IntegerExpressionGrammar::prepareForSecondRun() { - // Override variable expressions: only allow declared variables. - integerVariableExpression %= this->state->integerVariables_; - integerVariableExpression.name("integer variable"); -} + integerExpression %= integerPlusExpression; + integerExpression.name("integer expression"); + + integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> integerMultExpression)[qi::_val = phoenix::bind(&BaseGrammar::createIntPlus, this, qi::_val, qi::_a, qi::_1)]; + integerPlusExpression.name("integer expression"); + + integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression[qi::_val = phoenix::bind(&BaseGrammar::createIntMult, this, qi::_val, qi::_1)]); + integerMultExpression.name("integer expression"); + + atomicIntegerExpression %= (integerVariableExpression | qi::lit("(") >> integerExpression >> qi::lit(")") | ConstIntegerExpressionGrammar::instance(this->state)); + atomicIntegerExpression.name("integer expression"); + + integerVariableExpression = IdentifierGrammar::instance(this->state)[qi::_val = phoenix::bind(&BaseGrammar::getIntVariable, this, qi::_1)]; + integerVariableExpression.name("integer variable"); + } } } diff --git a/src/parser/PrismParser/IntegerExpressionGrammar.h b/src/parser/PrismParser/IntegerExpressionGrammar.h index 7a240809b..5c253e437 100644 --- a/src/parser/PrismParser/IntegerExpressionGrammar.h +++ b/src/parser/PrismParser/IntegerExpressionGrammar.h @@ -11,6 +11,7 @@ #include "src/ir/IR.h" #include "VariableState.h" #include "Includes.h" +#include "IdentifierGrammars.h" #include @@ -18,39 +19,16 @@ namespace storm { namespace parser { namespace prism { -class IntegerExpressionGrammar : public qi::grammar(), Skipper, Skipper> { +class IntegerExpressionGrammar : public qi::grammar(), Skipper, Unused>, public BaseGrammar { public: IntegerExpressionGrammar(std::shared_ptr& state); - void prepareForSecondRun(); private: - - qi::rule identifierName; - - // The starting point for arbitrary expressions. - qi::rule(), Skipper> expression; - - // Rules with integer result type. - qi::rule(), Skipper, Skipper> integerExpression; + qi::rule(), Skipper, Unused> integerExpression; qi::rule(), qi::locals, Skipper> integerPlusExpression; qi::rule(), Skipper> integerMultExpression; qi::rule(), Skipper> atomicIntegerExpression; - qi::rule(), Skipper> constantIntegerExpression; - qi::rule(), qi::locals, Skipper> constantIntegerPlusExpression; - qi::rule(), Skipper> constantIntegerMultExpression; - qi::rule(), Skipper> constantAtomicIntegerExpression; - - // Rules for variable recognition. qi::rule(), Skipper> integerVariableExpression; - qi::rule(), qi::locals>, Skipper> integerVariableCreatorExpression; - - // Rules for constant recognition. - qi::rule(), Skipper> integerConstantExpression; - - // Rules for literal recognition. - qi::rule(), Skipper> integerLiteralExpression; - - std::shared_ptr state; }; } diff --git a/src/parser/PrismParser/UtilityGrammars.h b/src/parser/PrismParser/Tokens.h similarity index 85% rename from src/parser/PrismParser/UtilityGrammars.h rename to src/parser/PrismParser/Tokens.h index e6c7e9707..cf0392f32 100644 --- a/src/parser/PrismParser/UtilityGrammars.h +++ b/src/parser/PrismParser/Tokens.h @@ -1,20 +1,33 @@ /* - * File: Keywords.h + * File: Tokens.h * Author: nafur * - * Created on April 10, 2013, 6:03 PM + * Created on April 19, 2013, 11:17 PM */ -#ifndef KEYWORDS_H -#define KEYWORDS_H - -#include "Includes.h" +#ifndef TOKENS_H +#define TOKENS_H namespace storm { namespace parser { namespace prism { -// A structure defining the keywords that are not allowed to be chosen as identifiers. + + // A structure mapping the textual representation of a model type to the model type + // representation of the intermediate representation. + struct modelTypeStruct : qi::symbols { + modelTypeStruct() { + add + ("dtmc", Program::ModelType::DTMC) + ("ctmc", Program::ModelType::CTMC) + ("mdp", Program::ModelType::MDP) + ("ctmdp", Program::ModelType::CTMDP) + ; + } + }; + + + // A structure defining the keywords that are not allowed to be chosen as identifiers. struct keywordsStruct : qi::symbols { keywordsStruct() { add @@ -34,20 +47,7 @@ namespace prism { ; } }; - - // A structure mapping the textual representation of a model type to the model type - // representation of the intermediate representation. - struct modelTypeStruct : qi::symbols { - modelTypeStruct() { - add - ("dtmc", Program::ModelType::DTMC) - ("ctmc", Program::ModelType::CTMC) - ("mdp", Program::ModelType::MDP) - ("ctmdp", Program::ModelType::CTMDP) - ; - } - }; - + // A structure mapping the textual representation of a binary relation to the representation // of the intermediate representation. struct relationalOperatorStruct : qi::symbols { @@ -61,9 +61,9 @@ namespace prism { ; } }; - } } } -#endif /* KEYWORDS_H */ + +#endif /* TOKENS_H */ diff --git a/src/parser/PrismParser/VariableState.h b/src/parser/PrismParser/VariableState.h index dd8fb0d80..1076d2764 100644 --- a/src/parser/PrismParser/VariableState.h +++ b/src/parser/PrismParser/VariableState.h @@ -10,6 +10,7 @@ #include "src/ir/IR.h" #include "Includes.h" +#include "Tokens.h" namespace storm { namespace parser { @@ -18,14 +19,15 @@ namespace prism { using namespace storm::ir; using namespace storm::ir::expressions; + struct VariableState : public storm::ir::VariableAdder { - public: - VariableState() - : keywords(), nextBooleanVariableIndex(0), nextIntegerVariableIndex(0) - { +public: + VariableState(bool firstRun = true) + : firstRun(firstRun), keywords(), nextBooleanVariableIndex(0), nextIntegerVariableIndex(0) { } + bool firstRun; keywordsStruct keywords; // Used for indexing the variables. @@ -43,30 +45,81 @@ struct VariableState : public storm::ir::VariableAdder { localBooleanVariables_, localIntegerVariables_, assignedLocalBooleanVariables_, assignedLocalIntegerVariables_; uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init) { + std::cerr << "adding boolean variable " << name << std::endl; + if (firstRun) { + std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::bool_, this->nextBooleanVariableIndex, name)); + this->booleanVariables_.add(name, varExpr); + this->booleanVariableNames_.add(name, name); + this->nextBooleanVariableIndex++; + return this->nextBooleanVariableIndex-1; + } else { + std::shared_ptr res = this->booleanVariables_.at(name); + if (res != nullptr) { + return res->getVariableIndex(); + } else { + std::cerr << "Variable " << name << " was not created in first run" << std::endl; + return 0; + } + } + } + + uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init) { + std::cerr << "adding integer variable " << name << std::endl; + if (firstRun) { + std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::int_, this->nextIntegerVariableIndex, name, lower, upper)); + this->integerVariables_.add(name, varExpr); + this->integerVariableNames_.add(name, name); + this->nextIntegerVariableIndex++; + return this->nextIntegerVariableIndex-1; + } else { + std::shared_ptr res = this->integerVariables_.at(name); + if (res != nullptr) { + return res->getVariableIndex(); + } else { + std::cerr << "Variable " << name << " was not created in first run" << std::endl; + return 0; + } + } + } + + std::shared_ptr getBooleanVariable(const std::string& name) { + std::cerr << "getting boolen variable " << name << std::endl; std::shared_ptr res = this->booleanVariables_.at(name); if (res != nullptr) { - return res->getVariableIndex(); + return res; + } else { + if (firstRun) { + return std::shared_ptr(new VariableExpression(BaseExpression::bool_, std::numeric_limits::max(), "bool", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); + } else { + std::cerr << "Variable " << name << " was not created in first run" << std::endl; + return std::shared_ptr(nullptr); + } } - std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::bool_, this->nextBooleanVariableIndex, name)); - this->booleanVariables_.add(name, varExpr); - this->booleanVariableNames_.add(name, name); - this->nextBooleanVariableIndex++; - return this->nextBooleanVariableIndex-1; } - uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init) { + std::shared_ptr getIntegerVariable(const std::string& name) { + std::cerr << "getting integer variable " << name << std::endl; std::shared_ptr res = this->integerVariables_.at(name); if (res != nullptr) { - return res->getVariableIndex(); + return res; + } else { + if (firstRun) { + return std::shared_ptr(new VariableExpression(BaseExpression::int_, std::numeric_limits::max(), "int", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); + } else { + std::cerr << "Variable " << name << " was not created in first run" << std::endl; + return std::shared_ptr(nullptr); + } } - std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::int_, this->nextIntegerVariableIndex, name, lower, upper)); - this->integerVariables_.add(name, varExpr); - this->integerVariableNames_.add(name, name); - this->nextIntegerVariableIndex++; - return this->nextIntegerVariableIndex-1; + } + + void startModule() { + std::cerr << "starting new module" << std::endl; + this->localBooleanVariables_.clear(); + this->localIntegerVariables_.clear(); } bool isFreeIdentifier(std::string& s) const { + std::cerr << "Checking if " << s << " is free" << std::endl; if (this->integerVariableNames_.find(s) != nullptr) return false; if (this->allConstantNames_.find(s) != nullptr) return false; if (this->labelNames_.find(s) != nullptr) return false; @@ -75,16 +128,19 @@ struct VariableState : public storm::ir::VariableAdder { return true; } bool isIdentifier(std::string& s) const { + std::cerr << "Checking if " << s << " is identifier" << std::endl; if (this->allConstantNames_.find(s) != nullptr) return false; if (this->keywords.find(s) != nullptr) return false; return true; } void prepareForSecondRun() { + std::cerr << "starting second run" << std::endl; integerConstants_.clear(); booleanConstants_.clear(); doubleConstants_.clear(); allConstantNames_.clear(); + this->firstRun = false; } }; From 152bcd2f20d0debf7a36d1ca0c8b925d790ef6ed Mon Sep 17 00:00:00 2001 From: gereon Date: Sat, 20 Apr 2013 16:52:19 +0200 Subject: [PATCH 076/152] Porting Program datastructures to use shared_ptr (at least for the moment...) some more cleanups --- src/adapters/ExplicitModelAdapter.cpp | 100 +++++------ src/adapters/ExplicitModelAdapter.h | 8 +- src/ir/Command.cpp | 14 +- src/ir/Command.h | 6 +- src/ir/Module.cpp | 21 ++- src/ir/Module.h | 12 +- src/ir/Program.cpp | 22 +-- src/ir/Program.h | 17 +- src/ir/RewardModel.cpp | 10 +- src/ir/RewardModel.h | 10 +- src/ir/expressions/BaseExpression.h | 2 + .../BinaryBooleanFunctionExpression.h | 12 ++ .../BinaryNumericalFunctionExpression.h | 14 ++ src/ir/expressions/BinaryRelationExpression.h | 22 ++- .../expressions/BooleanConstantExpression.h | 6 + src/ir/expressions/BooleanLiteral.h | 6 + src/ir/expressions/ConstantExpression.h | 6 + src/ir/expressions/DoubleConstantExpression.h | 6 + src/ir/expressions/DoubleLiteral.h | 6 + .../expressions/IntegerConstantExpression.h | 6 +- src/ir/expressions/IntegerLiteral.h | 6 +- .../UnaryBooleanFunctionExpression.h | 9 + .../UnaryNumericalFunctionExpression.h | 10 ++ src/ir/expressions/VariableExpression.h | 31 +++- src/parser/PrismParser.cpp | 170 ++++++++++-------- src/parser/PrismParser.h | 45 +++-- src/parser/PrismParser/VariableState.h | 16 +- 27 files changed, 386 insertions(+), 207 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index 24dba6d27..e9f4263d6 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -45,8 +45,8 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { std::shared_ptr stateLabeling = this->getStateLabeling(this->program->getLabels()); std::shared_ptr> stateRewards = nullptr; - if (this->rewardModel.hasStateRewards()) { - stateRewards = this->getStateRewards(this->rewardModel.getStateRewards()); + if (this->rewardModel->hasStateRewards()) { + stateRewards = this->getStateRewards(this->rewardModel->getStateRewards()); } switch (this->program->getModelType()) @@ -90,11 +90,11 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { std::get<1>(*state)[index] = value; } - std::shared_ptr> ExplicitModelAdapter::getStateRewards(std::vector const & rewards) { + std::shared_ptr> ExplicitModelAdapter::getStateRewards(std::vector> const & rewards) { std::shared_ptr> results(new std::vector(this->allStates.size())); for (uint_fast64_t index = 0; index < this->allStates.size(); index++) { for (auto reward: rewards) { - (*results)[index] = reward.getReward(this->allStates[index]); + (*results)[index] = reward->getReward(this->allStates[index]); } } return results; @@ -119,8 +119,8 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { uint_fast64_t numberOfIntegerVariables = 0; uint_fast64_t numberOfBooleanVariables = 0; for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { - numberOfIntegerVariables += program->getModule(i).getNumberOfIntegerVariables(); - numberOfBooleanVariables += program->getModule(i).getNumberOfBooleanVariables(); + numberOfIntegerVariables += program->getModule(i)->getNumberOfIntegerVariables(); + numberOfBooleanVariables += program->getModule(i)->getNumberOfBooleanVariables(); } this->booleanVariables.resize(numberOfBooleanVariables); @@ -129,16 +129,16 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { uint_fast64_t nextBooleanVariableIndex = 0; uint_fast64_t nextIntegerVariableIndex = 0; for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { - storm::ir::Module const& module = program->getModule(i); + std::shared_ptr const module = program->getModule(i); - for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { - this->booleanVariables[nextBooleanVariableIndex] = module.getBooleanVariable(j); - this->booleanVariableToIndexMap[module.getBooleanVariable(j).getName()] = nextBooleanVariableIndex; + for (uint_fast64_t j = 0; j < module->getNumberOfBooleanVariables(); ++j) { + this->booleanVariables[nextBooleanVariableIndex] = module->getBooleanVariable(j); + this->booleanVariableToIndexMap[module->getBooleanVariable(j).getName()] = nextBooleanVariableIndex; ++nextBooleanVariableIndex; } - for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) { - this->integerVariables[nextIntegerVariableIndex] = module.getIntegerVariable(j); - this->integerVariableToIndexMap[module.getIntegerVariable(j).getName()] = nextIntegerVariableIndex; + for (uint_fast64_t j = 0; j < module->getNumberOfIntegerVariables(); ++j) { + this->integerVariables[nextIntegerVariableIndex] = module->getIntegerVariable(j); + this->integerVariableToIndexMap[module->getIntegerVariable(j).getName()] = nextIntegerVariableIndex; ++nextIntegerVariableIndex; } } @@ -157,28 +157,28 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { * @param action Action label. * @return Active commands. */ - std::unique_ptr>> ExplicitModelAdapter::getActiveCommandsByAction(StateType const * state, std::string& action) { - std::unique_ptr>> res = std::unique_ptr>>(new std::list>()); + std::unique_ptr>>> ExplicitModelAdapter::getActiveCommandsByAction(StateType const * state, std::string& action) { + std::unique_ptr>>> res = std::unique_ptr>>>(new std::list>>()); // Iterate over all modules. for (uint_fast64_t i = 0; i < this->program->getNumberOfModules(); ++i) { - storm::ir::Module const& module = this->program->getModule(i); + std::shared_ptr const module = this->program->getModule(i); - std::shared_ptr> ids = module.getCommandsByAction(action); - std::list commands; + std::shared_ptr> ids = module->getCommandsByAction(action); + std::list> commands; // Look up commands by their id. Add, if guard holds. for (uint_fast64_t id : *ids) { - storm::ir::Command cmd = module.getCommand(id); - if (cmd.getGuard()->getValueAsBool(state)) { - commands.push_back(module.getCommand(id)); + std::shared_ptr cmd = module->getCommand(id); + if (cmd->getGuard()->getValueAsBool(state)) { + commands.push_back(module->getCommand(id)); } } res->push_back(commands); } // Sort the result in the vague hope that having small lists at the beginning will speed up the expanding. // This is how lambdas may look like in C++... - res->sort([](const std::list& a, const std::list& b){ return a.size() < b.size(); }); + res->sort([](const std::list>& a, const std::list>& b){ return a.size() < b.size(); }); return res; } @@ -188,12 +188,12 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { * @params update Update to be applied. * @return Resulting state. */ - StateType* ExplicitModelAdapter::applyUpdate(StateType const * const state, storm::ir::Update const & update) const { + StateType* ExplicitModelAdapter::applyUpdate(StateType const * const state, std::shared_ptr const update) const { StateType* newState = new StateType(*state); - for (auto assignedVariable : update.getBooleanAssignments()) { + for (auto assignedVariable : update->getBooleanAssignments()) { setValue(newState, this->booleanVariableToIndexMap.at(assignedVariable.first), assignedVariable.second.getExpression()->getValueAsBool(state)); } - for (auto assignedVariable : update.getIntegerAssignments()) { + for (auto assignedVariable : update->getIntegerAssignments()) { setValue(newState, this->integerVariableToIndexMap.at(assignedVariable.first), assignedVariable.second.getExpression()->getValueAsInt(state)); } return newState; @@ -291,32 +291,32 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { const StateType* state = this->allStates[stateID]; // Iterate over all modules. for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { - storm::ir::Module const& module = program->getModule(i); + std::shared_ptr const module = program->getModule(i); // Iterate over all commands. - for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { - storm::ir::Command const& command = module.getCommand(j); + for (uint_fast64_t j = 0; j < module->getNumberOfCommands(); ++j) { + std::shared_ptr const command = module->getCommand(j); // Only consider unlabeled commands. - if (command.getActionName() != "") continue; + if (command->getActionName() != "") continue; // Omit, if command is not active. - if (!command.getGuard()->getValueAsBool(state)) continue; + if (!command->getGuard()->getValueAsBool(state)) continue; // Add a new map and get pointer. res.emplace_back(); std::map* states = &res.back().second; // Iterate over all updates. - for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { + for (uint_fast64_t k = 0; k < command->getNumberOfUpdates(); ++k) { // Obtain new state id. - storm::ir::Update const& update = command.getUpdate(k); + std::shared_ptr const update = command->getUpdate(k); uint_fast64_t newStateId = this->getOrAddStateId(this->applyUpdate(state, update)); // Check, if we already know this state, add up probabilities for every state. auto stateIt = states->find(newStateId); if (stateIt == states->end()) { - (*states)[newStateId] = update.getLikelihoodExpression()->getValueAsDouble(state); + (*states)[newStateId] = update->getLikelihoodExpression()->getValueAsDouble(state); this->numberOfTransitions++; } else { - (*states)[newStateId] += update.getLikelihoodExpression()->getValueAsDouble(state); + (*states)[newStateId] += update->getLikelihoodExpression()->getValueAsDouble(state); } } } @@ -333,21 +333,21 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { // Create a copy of the current state, as we will free intermediate states... for (std::string action : this->program->getActions()) { StateType* state = new StateType(*this->allStates[stateID]); - std::unique_ptr>> cmds = this->getActiveCommandsByAction(state, action); + std::unique_ptr>>> cmds = this->getActiveCommandsByAction(state, action); // Start with current state std::unordered_map resultStates; resultStates[state] = 1.0; - for (std::list module : *cmds) { + for (std::list> module : *cmds) { if (resultStates.size() == 0) break; std::unordered_map newStates; // Iterate over all commands within this module. - for (storm::ir::Command command : module) { + for (std::shared_ptr command : module) { // Iterate over all updates of this command. - for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { - storm::ir::Update const& update = command.getUpdate(k); + for (uint_fast64_t k = 0; k < command->getNumberOfUpdates(); ++k) { + std::shared_ptr const update = command->getUpdate(k); // Iterate over all resultStates. for (auto it : resultStates) { @@ -357,9 +357,9 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { // Take care of calculation of likelihood, combine identical states. auto s = newStates.find(newState); if (s == newStates.end()) { - newStates[newState] = it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); + newStates[newState] = it.second * update->getLikelihoodExpression()->getValueAsDouble(it.first); } else { - newStates[newState] += it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); + newStates[newState] += it.second * update->getLikelihoodExpression()->getValueAsDouble(it.first); } } } @@ -413,7 +413,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size())); result->initialize(numberOfTransitions); - if (this->rewardModel.hasTransitionRewards()) { + if (this->rewardModel->hasTransitionRewards()) { this->transitionRewards = std::shared_ptr>(new storm::storage::SparseMatrix(allStates.size())); this->transitionRewards->initialize(numberOfTransitions); } @@ -427,9 +427,9 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { for (auto choice : transitionMap[state]) { for (auto elem : choice.second) { map[elem.first] += elem.second; - if (this->rewardModel.hasTransitionRewards()) { - for (storm::ir::TransitionReward reward : this->rewardModel.getTransitionRewards()) { - rewardMap[elem.first] += reward.getReward(choice.first, this->allStates[state]); + if (this->rewardModel->hasTransitionRewards()) { + for (auto reward : this->rewardModel->getTransitionRewards()) { + rewardMap[elem.first] += reward->getReward(choice.first, this->allStates[state]); } } } @@ -438,7 +438,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { double factor = 1.0 / transitionMap[state].size(); for (auto it : map) { result->addNextValue(state, it.first, it.second * factor); - if (this->rewardModel.hasTransitionRewards()) { + if (this->rewardModel->hasTransitionRewards()) { this->transitionRewards->addNextValue(state, it.first, rewardMap[it.first] * factor); } } @@ -458,7 +458,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { LOG4CPLUS_DEBUG(logger, "Building nondeterministic transition matrix with " << this->numberOfChoices << " choices and " << this->numberOfTransitions << " transitions now."); std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size(), this->numberOfChoices)); result->initialize(this->numberOfTransitions); - if (this->rewardModel.hasTransitionRewards()) { + if (this->rewardModel->hasTransitionRewards()) { this->transitionRewards = std::shared_ptr>(new storm::storage::SparseMatrix(allStates.size(), this->numberOfChoices)); this->transitionRewards->initialize(this->numberOfTransitions); } @@ -468,10 +468,10 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { for (auto choice : transitionMap[state]) { for (auto it : choice.second) { result->addNextValue(nextRow, it.first, it.second); - if (this->rewardModel.hasTransitionRewards()) { + if (this->rewardModel->hasTransitionRewards()) { double rewardValue = 0; - for (storm::ir::TransitionReward reward : this->rewardModel.getTransitionRewards()) { - rewardValue = reward.getReward(choice.first, this->allStates[state]); + for (auto reward : this->rewardModel->getTransitionRewards()) { + rewardValue = reward->getReward(choice.first, this->allStates[state]); } this->transitionRewards->addNextValue(nextRow, it.first, rewardValue); } diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 03214d165..962bfa6d8 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -83,7 +83,7 @@ private: * @params update Update to be applied. * @return Resulting state. */ - StateType* applyUpdate(StateType const * const state, storm::ir::Update const & update) const; + StateType* applyUpdate(StateType const * const state, std::shared_ptr const update) const; /*! * Reads and combines variables from all program modules and stores them. @@ -91,7 +91,7 @@ private: */ void initializeVariables(); - std::shared_ptr> getStateRewards(std::vector const & rewards); + std::shared_ptr> getStateRewards(std::vector> const & rewards); std::shared_ptr getStateLabeling(std::map> labels); /*! @@ -107,7 +107,7 @@ private: * @param action Action label. * @return Active commands. */ - std::unique_ptr>> getActiveCommandsByAction(StateType const * state, std::string& action); + std::unique_ptr>>> getActiveCommandsByAction(StateType const * state, std::string& action); /*! * Generates all initial states and adds them to allStates. @@ -173,7 +173,7 @@ private: std::map integerVariableToIndexMap; // Members that are filled during the conversion. - storm::ir::RewardModel rewardModel; + std::shared_ptr rewardModel; std::vector allStates; std::unordered_map stateToIndexMap; uint_fast64_t numberOfTransitions; diff --git a/src/ir/Command.cpp b/src/ir/Command.cpp index b34ab60ed..ea2141bf0 100644 --- a/src/ir/Command.cpp +++ b/src/ir/Command.cpp @@ -8,6 +8,7 @@ #include "Command.h" #include +#include namespace storm { @@ -19,19 +20,22 @@ Command::Command() : actionName(), guardExpression(), updates() { } // Initializes all members according to the given values. -Command::Command(std::string actionName, std::shared_ptr guardExpression, std::vector updates) +Command::Command(std::string actionName, std::shared_ptr guardExpression, std::vector> updates) : actionName(actionName), guardExpression(guardExpression), updates(updates) { // Nothing to do here. } Command::Command(const Command& cmd, const std::map& renaming, const std::map& bools, const std::map& ints) : actionName(cmd.actionName), guardExpression(cmd.guardExpression->clone(renaming, bools, ints)) { + std::cout << "Cloning command" << std::endl; + std::cout << cmd.guardExpression->dump("\t"); + std::cout << this->guardExpression->dump("\t"); if (renaming.count(this->actionName) > 0) { this->actionName = renaming.at(this->actionName); } this->updates.reserve(cmd.updates.size()); - for (Update u : cmd.updates) { - this->updates.emplace_back(u, renaming, bools, ints); + for (std::shared_ptr u : cmd.updates) { + this->updates.emplace_back(new Update(*u, renaming, bools, ints)); } } @@ -51,7 +55,7 @@ uint_fast64_t Command::getNumberOfUpdates() const { } // Return the requested update. -storm::ir::Update const& Command::getUpdate(uint_fast64_t index) const { +std::shared_ptr const& Command::getUpdate(uint_fast64_t index) const { return this->updates[index]; } @@ -60,7 +64,7 @@ std::string Command::toString() const { std::stringstream result; result << "[" << actionName << "] " << guardExpression->toString() << " -> "; for (uint_fast64_t i = 0; i < updates.size(); ++i) { - result << updates[i].toString(); + result << updates[i]->toString(); if (i < updates.size() - 1) { result << " + "; } diff --git a/src/ir/Command.h b/src/ir/Command.h index b4049307c..4e3da7f65 100644 --- a/src/ir/Command.h +++ b/src/ir/Command.h @@ -34,7 +34,7 @@ public: * @param actionName the action name of the command. * @param guardExpression the expression that defines the guard of the command. */ - Command(std::string actionName, std::shared_ptr guardExpression, std::vector updates); + Command(std::string actionName, std::shared_ptr guardExpression, std::vector> updates); Command(const Command& cmd, const std::map& renaming, const std::map& bools, const std::map& ints); /*! @@ -59,7 +59,7 @@ public: * Retrieves a reference to the update with the given index. * @returns a reference to the update with the given index. */ - storm::ir::Update const& getUpdate(uint_fast64_t index) const; + std::shared_ptr const& getUpdate(uint_fast64_t index) const; /*! * Retrieves a string representation of this command. @@ -75,7 +75,7 @@ private: std::shared_ptr guardExpression; // The list of updates of the command. - std::vector updates; + std::vector> updates; }; } // namespace ir diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index 592c92164..c3049a0ea 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -27,29 +27,31 @@ Module::Module(std::string moduleName, std::vector b std::vector integerVariables, std::map booleanVariableToIndexMap, std::map integerVariableToIndexMap, - std::vector commands) + std::vector> commands) : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), booleanVariablesToIndexMap(booleanVariableToIndexMap), integerVariablesToIndexMap(integerVariableToIndexMap), commands(commands), actions(), actionsToCommandIndexMap() { + std::cout << "Created module " << this << ":" << std::endl << this->toString() << std::endl; this->collectActions(); } -Module::Module(const Module& module, const std::string& moduleName, const std::map& renaming, const VariableAdder& adder) +Module::Module(const Module& module, const std::string& moduleName, const std::map& renaming, std::shared_ptr adder) : moduleName(moduleName) { std::cout << "Renaming module " << module.moduleName << " to " << moduleName << " with " << renaming.size() << " renamings:" << std::endl; for (auto it: renaming) { std::cout << "\t" << it.first << " -> " << it.second << std::endl; } + std::cout << "Current module " << &module << ":" << std::endl << module.toString() << std::endl; this->booleanVariables.reserve(module.booleanVariables.size()); for (BooleanVariable it: module.booleanVariables) { if (renaming.count(it.getName()) > 0) { - this->booleanVariablesToIndexMap[renaming.at(it.getName())] = adder.addBooleanVariable(it.getName(), it.getInitialValue()); + this->booleanVariablesToIndexMap[renaming.at(it.getName())] = adder->addBooleanVariable(renaming.at(it.getName()), it.getInitialValue()); } else std::cerr << "ERROR: " << moduleName << "." << it.getName() << " was not renamed!" << std::endl; } this->integerVariables.reserve(module.integerVariables.size()); for (IntegerVariable it: module.integerVariables) { if (renaming.count(it.getName()) > 0) { - this->integerVariablesToIndexMap[renaming.at(it.getName())] = adder.addIntegerVariable(it.getName(), it.getLowerBound(), it.getUpperBound(), it.getInitialValue()); + this->integerVariablesToIndexMap[renaming.at(it.getName())] = adder->addIntegerVariable(renaming.at(it.getName()), it.getLowerBound(), it.getUpperBound(), it.getInitialValue()); } else std::cerr << "ERROR: " << moduleName << "." << it.getName() << " was not renamed!" << std::endl; } this->booleanVariables.reserve(module.booleanVariables.size()); @@ -66,8 +68,9 @@ Module::Module(const Module& module, const std::string& moduleName, const std::m } this->commands.reserve(module.commands.size()); - for (Command cmd: module.commands) { - this->commands.emplace_back(cmd, renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap); + for (std::shared_ptr cmd: module.commands) { + std::cout << "2: Current command: " << cmd->toString() << std::endl; + this->commands.emplace_back(new Command(*cmd, renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap)); } this->collectActions(); @@ -119,7 +122,7 @@ uint_fast64_t Module::getIntegerVariableIndex(std::string variableName) const { } // Return the requested command. -storm::ir::Command const& Module::getCommand(uint_fast64_t index) const { +std::shared_ptr const Module::getCommand(uint_fast64_t index) const { return this->commands[index]; } @@ -134,7 +137,7 @@ std::string Module::toString() const { result << "\t" << variable.toString() << std::endl; } for (auto command : commands) { - result << "\t" << command.toString() << std::endl; + result << "\t" << command->toString() << std::endl; } result << "endmodule" << std::endl; return result.str(); @@ -157,7 +160,7 @@ std::shared_ptr> const Module::getCommandsByAction(std:: void Module::collectActions() { for (unsigned int id = 0; id < this->commands.size(); id++) { - std::string action = this->commands[id].getActionName(); + std::string action = this->commands[id]->getActionName(); if (action != "") { if (this->actionsToCommandIndexMap.count(action) == 0) { this->actionsToCommandIndexMap[action] = std::shared_ptr>(new std::set()); diff --git a/src/ir/Module.h b/src/ir/Module.h index 8991062ec..2a97a2ab3 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -23,8 +23,8 @@ namespace storm { namespace ir { struct VariableAdder { - virtual uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init) const = 0; - virtual uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init) const = 0; + virtual uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init) = 0; + virtual uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init) = 0; }; /*! @@ -48,7 +48,7 @@ public: std::vector integerVariables, std::map booleanVariableToIndexMap, std::map integerVariableToIndexMap, - std::vector commands); + std::vector> commands); typedef uint_fast64_t (*addIntegerVariablePtr)(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init); typedef uint_fast64_t (*addBooleanVariablePtr)(const std::string& name, const std::shared_ptr init); @@ -60,7 +60,7 @@ public: * @param moduleName Name of the new module. * @param renaming Renaming map. */ - Module(const Module& module, const std::string& moduleName, const std::map& renaming, const VariableAdder& adder); + Module(const Module& module, const std::string& moduleName, const std::map& renaming, std::shared_ptr adder); /*! * Retrieves the number of boolean variables in the module. @@ -110,7 +110,7 @@ public: * Retrieves a reference to the command with the given index. * @returns a reference to the command with the given index. */ - storm::ir::Command const& getCommand(uint_fast64_t index) const; + std::shared_ptr const getCommand(uint_fast64_t index) const; /*! * Retrieves a string representation of this variable. @@ -152,7 +152,7 @@ private: std::map integerVariablesToIndexMap; // The commands associated with the module. - std::vector commands; + std::vector> commands; // The set of actions present in this module. std::set actions; diff --git a/src/ir/Program.cpp b/src/ir/Program.cpp index 8e5306e71..01a77298f 100644 --- a/src/ir/Program.cpp +++ b/src/ir/Program.cpp @@ -24,11 +24,11 @@ Program::Program() : modelType(UNDEFINED), booleanUndefinedConstantExpressions() } // Initializes all members according to the given values. -Program::Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector modules, std::map rewards, std::map> labels) +Program::Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector> modules, std::map> rewards, std::map> labels) : modelType(modelType), booleanUndefinedConstantExpressions(booleanUndefinedConstantExpressions), integerUndefinedConstantExpressions(integerUndefinedConstantExpressions), doubleUndefinedConstantExpressions(doubleUndefinedConstantExpressions), modules(modules), rewards(rewards), labels(labels), actionsToModuleIndexMap() { // Build actionsToModuleIndexMap for (unsigned int id = 0; id < this->modules.size(); id++) { - for (auto action : this->modules[id].getActions()) { + for (auto action : this->modules[id]->getActions()) { if (this->actionsToModuleIndexMap.count(action) == 0) { this->actionsToModuleIndexMap[action] = std::shared_ptr>(new std::set()); } @@ -55,22 +55,22 @@ std::string Program::toString() const { result << std::endl; for (auto element : booleanUndefinedConstantExpressions) { - result << "const bool " << element.first << ";" << std::endl; + result << "const bool " << element.first << " [" << element.second->toString() << "]" << ";" << std::endl; } for (auto element : integerUndefinedConstantExpressions) { - result << "const int " << element.first << ";" << std::endl; + result << "const int " << element.first << " [" << element.second->toString() << "]" << ";" << std::endl; } for (auto element : doubleUndefinedConstantExpressions) { - result << "const double " << element.first << ";" << std::endl; + result << "const double " << element.first << " [" << element.second->toString() << "]" << ";" << std::endl; } result << std::endl; - for (auto mod : modules) { - result << mod.toString() << std::endl; + for (auto module : modules) { + result << module->toString() << std::endl; } for (auto rewardModel : rewards) { - result << rewardModel.second.toString() << std::endl; + result << rewardModel.first << ": " << rewardModel.second->toString() << std::endl; } for (auto label : labels) { @@ -84,7 +84,7 @@ uint_fast64_t Program::getNumberOfModules() const { return this->modules.size(); } -storm::ir::Module const& Program::getModule(uint_fast64_t index) const { +std::shared_ptr const& Program::getModule(uint_fast64_t index) const { return this->modules[index]; } @@ -103,11 +103,11 @@ std::shared_ptr> const Program::getModulesByAction(std:: } } -storm::ir::RewardModel Program::getRewardModel(std::string const & name) const { +std::shared_ptr Program::getRewardModel(std::string const & name) const { auto it = this->rewards.find(name); if (it == this->rewards.end()) { LOG4CPLUS_ERROR(logger, "The given reward model \"" << name << "\" does not exist. We will proceed without rewards."); - return RewardModel(); + return nullptr; } else { return it->second; } diff --git a/src/ir/Program.h b/src/ir/Program.h index b6daecdd7..d51ebeb0e 100644 --- a/src/ir/Program.h +++ b/src/ir/Program.h @@ -53,7 +53,14 @@ public: * @param rewards The reward models of the program. * @param labels The labels defined for this model. */ - Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector modules, std::map rewards, std::map> labels); + Program( + ModelType modelType, + std::map> booleanUndefinedConstantExpressions, + std::map> integerUndefinedConstantExpressions, + std::map> doubleUndefinedConstantExpressions, + std::vector> modules, + std::map> rewards, + std::map> labels); /*! * Retrieves the number of modules in the program. @@ -65,7 +72,7 @@ public: * Retrieves a reference to the module with the given index. * @param index the index of the module to retrieve. */ - storm::ir::Module const& getModule(uint_fast64_t index) const; + std::shared_ptr const& getModule(uint_fast64_t index) const; /*! * Retrieves the model type of the model. @@ -98,7 +105,7 @@ public: * @param name Name of the reward model. * @return Reward model with given name. */ - storm::ir::RewardModel getRewardModel(std::string const & name) const; + std::shared_ptr getRewardModel(std::string const & name) const; /*! * Retrieves all labels. @@ -120,10 +127,10 @@ private: std::map> doubleUndefinedConstantExpressions; // The modules associated with the program. - std::vector modules; + std::vector> modules; // The reward models associated with the program. - std::map rewards; + std::map> rewards; // The labels that are defined for this model. std::map> labels; diff --git a/src/ir/RewardModel.cpp b/src/ir/RewardModel.cpp index d6611e4ec..352c8614c 100644 --- a/src/ir/RewardModel.cpp +++ b/src/ir/RewardModel.cpp @@ -19,7 +19,7 @@ RewardModel::RewardModel() : rewardModelName(), stateRewards(), transitionReward } // Initializes all members according to the given values. -RewardModel::RewardModel(std::string rewardModelName, std::vector stateRewards, std::vector transitionRewards) : rewardModelName(rewardModelName), stateRewards(stateRewards), transitionRewards(transitionRewards) { +RewardModel::RewardModel(std::string rewardModelName, std::vector> stateRewards, std::vector> transitionRewards) : rewardModelName(rewardModelName), stateRewards(stateRewards), transitionRewards(transitionRewards) { // Nothing to do here. } @@ -28,10 +28,10 @@ std::string RewardModel::toString() const { std::stringstream result; result << "rewards \"" << rewardModelName << "\"" << std::endl; for (auto reward : stateRewards) { - result << reward.toString() << std::endl; + result << reward->toString() << std::endl; } for (auto reward : transitionRewards) { - result << reward.toString() << std::endl; + result << reward->toString() << std::endl; } result << "endrewards" << std::endl; return result.str(); @@ -41,7 +41,7 @@ bool RewardModel::hasStateRewards() const { return this->stateRewards.size() > 0; } -std::vector RewardModel::getStateRewards() const { +std::vector> RewardModel::getStateRewards() const { return this->stateRewards; } @@ -49,7 +49,7 @@ bool RewardModel::hasTransitionRewards() const { return this->transitionRewards.size() > 0; } -std::vector RewardModel::getTransitionRewards() const { +std::vector> RewardModel::getTransitionRewards() const { return this->transitionRewards; } diff --git a/src/ir/RewardModel.h b/src/ir/RewardModel.h index cb538f173..29029a4db 100644 --- a/src/ir/RewardModel.h +++ b/src/ir/RewardModel.h @@ -34,7 +34,7 @@ public: * @param stateRewards A vector of state-based reward. * @param transitionRewards A vector of transition-based reward. */ - RewardModel(std::string rewardModelName, std::vector stateRewards, std::vector transitionRewards); + RewardModel(std::string rewardModelName, std::vector> stateRewards, std::vector> transitionRewards); /*! * Retrieves a string representation of this variable. @@ -52,7 +52,7 @@ public: * Retrieve state rewards. * @return State rewards. */ - std::vector getStateRewards() const; + std::vector> getStateRewards() const; /*! * Check, if there are any transition rewards. @@ -64,17 +64,17 @@ public: * Retrieve transition rewards. * @return Transition rewards. */ - std::vector getTransitionRewards() const; + std::vector> getTransitionRewards() const; private: // The name of the reward model. std::string rewardModelName; // The state-based rewards associated with this reward model. - std::vector stateRewards; + std::vector> stateRewards; // The transition-based rewards associated with this reward model. - std::vector transitionRewards; + std::vector> transitionRewards; }; } // namespace ir diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h index 563037266..a8d3377a9 100644 --- a/src/ir/expressions/BaseExpression.h +++ b/src/ir/expressions/BaseExpression.h @@ -86,6 +86,8 @@ public: ReturnType getType() const { return type; } + + virtual std::string dump(std::string prefix) const = 0; private: ReturnType type; diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.h b/src/ir/expressions/BinaryBooleanFunctionExpression.h index dc1dc1147..4882c0d92 100644 --- a/src/ir/expressions/BinaryBooleanFunctionExpression.h +++ b/src/ir/expressions/BinaryBooleanFunctionExpression.h @@ -65,6 +65,18 @@ public: return result.str(); } + + virtual std::string dump(std::string prefix) const { + std::stringstream result; + result << prefix << "BinaryBooleanFunctionExpression" << std::endl; + result << this->getLeft()->dump(prefix + "\t"); + switch (functionType) { + case AND: result << prefix << "&" << std::endl; break; + case OR: result << prefix << "|" << std::endl; break; + } + result << this->getRight()->dump(prefix + "\t"); + return result.str(); + } private: FunctionType functionType; diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h index 49d2c9494..151c10062 100644 --- a/src/ir/expressions/BinaryNumericalFunctionExpression.h +++ b/src/ir/expressions/BinaryNumericalFunctionExpression.h @@ -86,6 +86,20 @@ public: return result; } + + virtual std::string dump(std::string prefix) const { + std::stringstream result; + result << prefix << "BinaryNumericalFunctionExpression" << std::endl; + result << this->getLeft()->dump(prefix + "\t"); + switch (functionType) { + case PLUS: result << prefix << "+" << std::endl; break; + case MINUS: result << prefix << "-" << std::endl; break; + case TIMES: result << prefix << "*" << std::endl; break; + case DIVIDE: result << prefix << "/" << std::endl; break; + } + result << this->getRight()->dump(prefix + "\t"); + return result.str(); + } private: FunctionType functionType; }; diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h index 76471c17e..99e4232c2 100644 --- a/src/ir/expressions/BinaryRelationExpression.h +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -22,7 +22,7 @@ public: enum RelationType {EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL}; BinaryRelationExpression(std::shared_ptr left, std::shared_ptr right, RelationType relationType) : BinaryExpression(bool_, left, right), relationType(relationType) { - + std::cerr << "BinaryRelationExpression: " << left.get() << " " << relationType << " " << right.get() << " ?" << std::endl; } virtual ~BinaryRelationExpression() { @@ -30,8 +30,9 @@ public: } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { - std::cout << "Cloning " << this->getLeft()->toString() << " ~ " << this->getRight()->toString() << std::endl; - return std::shared_ptr(new BinaryRelationExpression(this->getLeft()->clone(renaming, bools, ints), this->getRight()->clone(renaming, bools, ints), this->relationType)); + auto res = std::shared_ptr(new BinaryRelationExpression(this->getLeft()->clone(renaming, bools, ints), this->getRight()->clone(renaming, bools, ints), this->relationType)); + std::cout << "Cloning " << this->toString() << " to " << res->toString() << std::endl; + return res; } virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { @@ -71,6 +72,21 @@ public: return result; } + virtual std::string dump(std::string prefix) const { + std::stringstream result; + result << prefix << "BinaryRelationExpression" << std::endl; + result << this->getLeft()->dump(prefix + "\t"); + switch (relationType) { + case EQUAL: result << prefix << "=" << std::endl; break; + case NOT_EQUAL: result << prefix << "!=" << std::endl; break; + case LESS: result << prefix << "<" << std::endl; break; + case LESS_OR_EQUAL: result << prefix << "<=" << std::endl; break; + case GREATER: result << prefix << ">" << std::endl; break; + case GREATER_OR_EQUAL: result << prefix << ">=" << std::endl; break; + } + result << this->getRight()->dump(prefix + "\t"); + return result.str(); + } private: RelationType relationType; diff --git a/src/ir/expressions/BooleanConstantExpression.h b/src/ir/expressions/BooleanConstantExpression.h index 15dcd9d4b..2a01a600a 100644 --- a/src/ir/expressions/BooleanConstantExpression.h +++ b/src/ir/expressions/BooleanConstantExpression.h @@ -53,6 +53,12 @@ public: } return result; } + + virtual std::string dump(std::string prefix) const { + std::stringstream result; + result << prefix << "BooleanConstantExpression " << this->toString() << std::endl; + return result.str(); + } bool isDefined() { return defined; diff --git a/src/ir/expressions/BooleanLiteral.h b/src/ir/expressions/BooleanLiteral.h index 696deb787..e2d17fb0f 100644 --- a/src/ir/expressions/BooleanLiteral.h +++ b/src/ir/expressions/BooleanLiteral.h @@ -45,6 +45,12 @@ public: return std::string("false"); } } + + virtual std::string dump(std::string prefix) const { + std::stringstream result; + result << prefix << "BooleanLiteral " << this->toString() << std::endl; + return result.str(); + } }; } diff --git a/src/ir/expressions/ConstantExpression.h b/src/ir/expressions/ConstantExpression.h index 79c356dba..b1be49e58 100644 --- a/src/ir/expressions/ConstantExpression.h +++ b/src/ir/expressions/ConstantExpression.h @@ -35,6 +35,12 @@ public: virtual std::string toString() const { return constantName; } + + virtual std::string dump(std::string prefix) const { + std::stringstream result; + result << prefix << "ConstantExpression " << this->toString() << std::endl; + return result.str(); + } }; } diff --git a/src/ir/expressions/DoubleConstantExpression.h b/src/ir/expressions/DoubleConstantExpression.h index a0c31efbe..dc8cd7920 100644 --- a/src/ir/expressions/DoubleConstantExpression.h +++ b/src/ir/expressions/DoubleConstantExpression.h @@ -50,6 +50,12 @@ public: } return result; } + + virtual std::string dump(std::string prefix) const { + std::stringstream result; + result << prefix << "DoubleConstantExpression " << this->toString() << std::endl; + return result.str(); + } bool isDefined() { return defined; diff --git a/src/ir/expressions/DoubleLiteral.h b/src/ir/expressions/DoubleLiteral.h index efa0d1bb5..20d43d464 100644 --- a/src/ir/expressions/DoubleLiteral.h +++ b/src/ir/expressions/DoubleLiteral.h @@ -45,6 +45,12 @@ public: virtual std::string toString() const { return boost::lexical_cast(value); } + + virtual std::string dump(std::string prefix) const { + std::stringstream result; + result << prefix << "DoubleLiteral " << this->toString() << std::endl; + return result.str(); + } }; } diff --git a/src/ir/expressions/IntegerConstantExpression.h b/src/ir/expressions/IntegerConstantExpression.h index 01d8f2d71..8d916bf7f 100644 --- a/src/ir/expressions/IntegerConstantExpression.h +++ b/src/ir/expressions/IntegerConstantExpression.h @@ -19,7 +19,6 @@ namespace expressions { class IntegerConstantExpression : public ConstantExpression { public: IntegerConstantExpression(std::string constantName) : ConstantExpression(int_, constantName), defined(false), value(0) { - } virtual ~IntegerConstantExpression() { @@ -50,6 +49,11 @@ public: } return result; } + virtual std::string dump(std::string prefix) const { + std::stringstream result; + result << prefix << "IntegerConstantExpression " << this->toString() << std::endl; + return result.str(); + } bool isDefined() { return defined; diff --git a/src/ir/expressions/IntegerLiteral.h b/src/ir/expressions/IntegerLiteral.h index 8911f640a..7ff615ee4 100644 --- a/src/ir/expressions/IntegerLiteral.h +++ b/src/ir/expressions/IntegerLiteral.h @@ -21,7 +21,6 @@ public: int_fast64_t value; IntegerLiteral(int_fast64_t value) : BaseExpression(int_), value(value) { - } virtual ~IntegerLiteral() { @@ -43,6 +42,11 @@ public: virtual std::string toString() const { return boost::lexical_cast(value); } + virtual std::string dump(std::string prefix) const { + std::stringstream result; + result << prefix << "IntegerLiteral " << this->toString() << std::endl; + return result.str(); + } }; } diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.h b/src/ir/expressions/UnaryBooleanFunctionExpression.h index 73b9969a7..03dd1d87c 100644 --- a/src/ir/expressions/UnaryBooleanFunctionExpression.h +++ b/src/ir/expressions/UnaryBooleanFunctionExpression.h @@ -58,6 +58,15 @@ public: return result; } + virtual std::string dump(std::string prefix) const { + std::stringstream result; + result << prefix << "UnaryBooleanFunctionExpression" << std::endl; + switch (functionType) { + case NOT: result << prefix << "!" << std::endl; break; + } + result << this->getChild()->dump(prefix + "\t"); + return result.str(); + } private: FunctionType functionType; diff --git a/src/ir/expressions/UnaryNumericalFunctionExpression.h b/src/ir/expressions/UnaryNumericalFunctionExpression.h index 0556892f2..d0a770494 100644 --- a/src/ir/expressions/UnaryNumericalFunctionExpression.h +++ b/src/ir/expressions/UnaryNumericalFunctionExpression.h @@ -75,6 +75,16 @@ public: return result; } + + virtual std::string dump(std::string prefix) const { + std::stringstream result; + result << prefix << "UnaryNumericalFunctionExpression" << std::endl; + switch (functionType) { + case MINUS: result << prefix << "-" << std::endl; break; + } + result << this->getChild()->dump(prefix + "\t"); + return result.str(); + } private: FunctionType functionType; diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index b7160f929..3aa57ee3e 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -26,7 +26,7 @@ public: std::shared_ptr upperBound = std::shared_ptr(nullptr)) : BaseExpression(type), index(index), variableName(variableName), lowerBound(lowerBound), upperBound(upperBound) { - + std::cerr << "VariableExpression " << this->variableName << std::endl; } virtual ~VariableExpression() { @@ -34,9 +34,13 @@ public: } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { - std::cout << "Cloning VarExpr " << this->variableName << std::endl; + std::cout << this << " Cloning VarExpr " << this->variableName << " (" << renaming.size() << " renamings)" << std::endl; + for (auto it: renaming) { + std::cout << "\t" << it.first << " -> " << it.second << std::endl; + } if (renaming.count(this->variableName) > 0) { std::string newName = renaming.at(this->variableName); + std::cout << "index of " << newName << " are " << bools.at(newName) << " and " << ints.at(newName) << std::endl; if (this->getType() == bool_) { return std::shared_ptr(new VariableExpression(bool_, bools.at(newName), newName, this->lowerBound, this->upperBound)); } else if (this->getType() == int_) { @@ -52,11 +56,28 @@ public: virtual void accept(ExpressionVisitor* visitor) { + std::cout << "Visitor!" << std::endl; visitor->visit(this); } virtual std::string toString() const { - return variableName; + std::stringstream result; + result << variableName << "(" << this->index << ")"; + return result.str(); + } + + virtual std::string dump(std::string prefix) const { + std::stringstream result; + result << prefix << this->variableName << " " << index << std::endl; + if (this->lowerBound != nullptr) { + result << prefix << "lower bound" << std::endl; + result << this->lowerBound->dump(prefix + "\t"); + } + if (this->upperBound != nullptr) { + result << prefix << "upper bound" << std::endl; + result << this->upperBound->dump(prefix + "\t"); + } + return result.str(); } virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { @@ -106,6 +127,10 @@ public: return upperBound; } + uint_fast64_t getVariableIndex() const { + return this->index; + } + private: uint_fast64_t index; std::string variableName; diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index e31e31b8a..2714d369e 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -9,25 +9,18 @@ #include "src/utility/OsDetection.h" +#include "src/parser/PrismParser/Includes.h" #include "src/parser/PrismParser/BooleanExpressionGrammar.h" #include "src/parser/PrismParser/ConstBooleanExpressionGrammar.h" #include "src/parser/PrismParser/ConstDoubleExpressionGrammar.h" #include "src/parser/PrismParser/ConstIntegerExpressionGrammar.h" #include "src/parser/PrismParser/IntegerExpressionGrammar.h" +#include "src/parser/PrismParser/IdentifierGrammars.h" #include "src/parser/PrismParser/VariableState.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFileFormatException.h" -// Used for Boost spirit. -#include -#include -#include - -// Include headers for spirit iterators. Needed for diagnostics and input stream iteration. -#include -#include - // Needed for file IO. #include #include @@ -46,37 +39,84 @@ namespace parser { void dump(const std::string& s) { std::cerr << "Dump: " << s << std::endl; } - /*void dump(const std::string& s, ) { - std::cerr << "Dump: " << s << std::endl; - }*/ - std::shared_ptr addIntegerConstant(const std::string& name, const std::shared_ptr value, std::shared_ptr state) { - std::cerr << "addIntegerConstant: " << name << std::endl; - state->integerConstants_.add(name, value); - state->allConstantNames_.add(name, name); + std::shared_ptr PrismParser::PrismGrammar::addIntegerConstant(const std::string& name, const std::shared_ptr value) { + this->state->integerConstants_.add(name, value); + this->state->allConstantNames_.add(name, name); return value; } -PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type(start), state(new storm::parser::prism::VariableState()) { + void PrismParser::PrismGrammar::addLabel(const std::string& name, std::shared_ptr value, std::map>& mapping) { + this->state->labelNames_.add(name, name); + mapping[name] = value; + } + void PrismParser::PrismGrammar::addIntAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping) { + this->state->assignedLocalIntegerVariables_.add(variable, variable); + mapping[variable] = Assignment(variable, value); + } + void PrismParser::PrismGrammar::addBoolAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping) { + this->state->assignedLocalBooleanVariables_.add(variable, variable); + mapping[variable] = Assignment(variable, value); + } + std::shared_ptr PrismParser::PrismGrammar::renameModule(const std::string& name, const std::string& oldname, std::map& mapping) { + this->state->moduleNames_.add(name, name); + std::shared_ptr old = this->state->moduleMap_.at(oldname); + if (old == nullptr) { + std::cerr << "Renaming module failed: module " << oldname << " does not exist!" << std::endl; + return nullptr; + } + std::shared_ptr res = std::shared_ptr(new Module(*old, name, mapping, this->state)); + this->state->moduleMap_.add(name, res); + return res; + } + std::shared_ptr PrismParser::PrismGrammar::createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector> commands) { + this->state->moduleNames_.add(name, name); + std::shared_ptr res = std::shared_ptr(new Module(name, bools, ints, boolids, intids, commands)); + this->state->moduleMap_.add(name, res); + return res; + } - // This rule defines all identifiers that have not been previously used. - identifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&storm::parser::prism::VariableState::isIdentifier, *this->state, qi::_1) ]; - identifierName.name("identifier"); - freeIdentifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&storm::parser::prism::VariableState::isFreeIdentifier, *this->state, qi::_1) ]; - freeIdentifierName.name("unused identifier"); + std::shared_ptr createStateReward(std::shared_ptr guard, std::shared_ptr reward) { + return std::shared_ptr(new StateReward(guard, reward)); + } + std::shared_ptr createTransitionReward(std::string label, std::shared_ptr guard, std::shared_ptr reward) { + return std::shared_ptr(new TransitionReward(label, guard, reward)); + } + void createRewardModel(std::string name, std::vector>& stateRewards, std::vector>& transitionRewards, std::map>& mapping) { + mapping[name] = std::shared_ptr(new RewardModel(name, stateRewards, transitionRewards)); + } + std::shared_ptr createUpdate(std::shared_ptr likelihood, std::map& bools, std::map ints) { + return std::shared_ptr(new Update(likelihood, bools, ints)); + } + std::shared_ptr createCommand(std::string& label, std::shared_ptr guard, std::vector>& updates) { + return std::shared_ptr(new Command(label, guard, updates)); + } + std::shared_ptr createProgram( + Program::ModelType modelType, + std::map> undefBoolConst, + std::map> undefIntConst, + std::map> undefDoubleConst, + std::vector> modules, + std::map> rewards, + std::map> labels) { + return std::shared_ptr(new Program(modelType, undefBoolConst, undefIntConst, undefDoubleConst, modules, rewards, labels)); + } + +PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type(start), state(new storm::parser::prism::VariableState()) { - // This block defines all entities that are needed for parsing labels. - labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> freeIdentifierName >> -qi::lit("\"") >> qi::lit("=") >> prism::BooleanExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_2)), phoenix::bind(this->state->labelNames_.add, qi::_1, qi::_1)]; + labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> prism::FreeIdentifierGrammar::instance(this->state) >> -qi::lit("\"") >> qi::lit("=") >> prism::BooleanExpressionGrammar::instance(this->state) >> qi::lit(";")) + [phoenix::bind(&PrismParser::PrismGrammar::addLabel, this, qi::_1, qi::_2, qi::_r1)]; labelDefinition.name("label declaration"); labelDefinitionList %= *labelDefinition(qi::_r1); labelDefinitionList.name("label declaration list"); // This block defines all entities that are needed for parsing a reward model. - stateRewardDefinition = (prism::BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > prism::ConstDoubleExpressionGrammar::instance(this->state) >> qi::lit(";"))[qi::_val = phoenix::construct(qi::_1, qi::_2)]; + stateRewardDefinition = (prism::BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > prism::ConstDoubleExpressionGrammar::instance(this->state) >> qi::lit(";"))[qi::_val = phoenix::bind(&createStateReward, qi::_1, qi::_2)]; stateRewardDefinition.name("state reward definition"); - transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > prism::BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; + transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > prism::BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[qi::_val = phoenix::bind(&createTransitionReward, qi::_a, qi::_2, qi::_3)]; transitionRewardDefinition.name("transition reward definition"); - rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > freeIdentifierName > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> qi::lit("endrewards"))[phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_a, qi::_b)))]; + rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > prism::FreeIdentifierGrammar::instance(this->state) > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> qi::lit("endrewards")) + [phoenix::bind(&createRewardModel, qi::_1, qi::_a, qi::_b, qi::_r1)]; rewardDefinition.name("reward definition"); rewardDefinitionList = *rewardDefinition(qi::_r1); rewardDefinitionList.name("reward definition list"); @@ -89,23 +129,25 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type unassignedLocalIntegerVariableName.name("unassigned local integer variable"); // This block defines all entities that are needed for parsing a single command. - assignmentDefinition = (qi::lit("(") >> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > prism::IntegerExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(this->state->assignedLocalIntegerVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))] | (qi::lit("(") > unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > prism::BooleanExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(this->state->assignedLocalBooleanVariables_.add, qi::_1, qi::_1), phoenix::insert(qi::_r1, phoenix::construct>(qi::_1, phoenix::construct(qi::_1, qi::_2)))]; + assignmentDefinition = + (qi::lit("(") >> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > prism::IntegerExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(&PrismParser::PrismGrammar::addIntAssignment, this, qi::_1, qi::_2, qi::_r2)] | + (qi::lit("(") >> unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > prism::BooleanExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(&PrismParser::PrismGrammar::addBoolAssignment, this, qi::_1, qi::_2, qi::_r1)]; assignmentDefinition.name("assignment"); assignmentDefinitionList = assignmentDefinition(qi::_r1, qi::_r2) % "&"; assignmentDefinitionList.name("assignment list"); - updateDefinition = (prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(":")[phoenix::clear(phoenix::ref(this->state->assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(this->state->assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b)]; + updateDefinition = (prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(":")[phoenix::clear(phoenix::ref(this->state->assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(this->state->assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::bind(&createUpdate, qi::_1, qi::_a, qi::_b)]; updateDefinition.name("update"); updateListDefinition = +updateDefinition % "+"; updateListDefinition.name("update list"); commandDefinition = ( qi::lit("[") > -( - (freeIdentifierName[phoenix::bind(this->state->commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1] + (prism::FreeIdentifierGrammar::instance(this->state)[phoenix::bind(this->state->commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1] ) > qi::lit("]") > prism::BooleanExpressionGrammar::instance(this->state) > qi::lit("->") > updateListDefinition > qi::lit(";") - )[qi::_val = phoenix::construct(qi::_a, qi::_2, qi::_3)]; + )[qi::_val = phoenix::bind(&createCommand, qi::_a, qi::_2, qi::_3)]; commandDefinition.name("command"); // This block defines all entities that are needed for parsing variable definitions. - booleanVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > prism::ConstBooleanExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) + booleanVariableDefinition = (prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > prism::ConstBooleanExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) [ //qi::_a = phoenix::bind(&VariableState::addBooleanVariable, *this->state.get(), qi::_1), qi::_a = phoenix::bind(&storm::parser::prism::VariableState::addBooleanVariable, *this->state, qi::_1, qi::_b), @@ -117,7 +159,7 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; integerLiteralExpression.name("integer literal"); - integerVariableDefinition = (freeIdentifierName >> qi::lit(":") >> qi::lit("[") > integerLiteralExpression > qi::lit("..") > integerLiteralExpression > qi::lit("]") > -(qi::lit("init") > prism::ConstIntegerExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) + integerVariableDefinition = (prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit(":") >> qi::lit("[") > integerLiteralExpression > qi::lit("..") > integerLiteralExpression > qi::lit("]") > -(qi::lit("init") > prism::ConstIntegerExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) [ qi::_a = phoenix::bind(&storm::parser::prism::VariableState::addIntegerVariable, *this->state, qi::_1, qi::_2, qi::_3, qi::_b), phoenix::push_back(qi::_r1, phoenix::construct(qi::_a, qi::_1, qi::_2, qi::_3, qi::_b)), @@ -129,69 +171,53 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type variableDefinition.name("variable declaration"); // This block defines all entities that are needed for parsing a module. - moduleDefinition = (qi::lit("module") >> freeIdentifierName - [phoenix::bind(&prism::VariableState::startModule, *this->state)] + moduleDefinition = (qi::lit("module") >> prism::FreeIdentifierGrammar::instance(this->state)[phoenix::bind(&prism::VariableState::startModule, *this->state)] >> *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) >> +commandDefinition > qi::lit("endmodule")) - [ - phoenix::bind(this->state->moduleNames_.add, qi::_1, qi::_1), - qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2), - phoenix::bind(this->state->moduleMap_.add, qi::_1, qi::_val) - ]; + [phoenix::bind(&PrismParser::PrismGrammar::createModule, this, qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2)]; - Module const * (qi::symbols::*moduleFinder)(const std::string&) const = &qi::symbols::find; moduleDefinition.name("module"); - moduleRenaming = (qi::lit("module") >> freeIdentifierName >> qi::lit("=") + moduleRenaming = (qi::lit("module") >> prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > this->state->moduleNames_ > qi::lit("[") > *( - (identifierName > qi::lit("=") > identifierName >> -qi::lit(","))[phoenix::insert(qi::_a, phoenix::construct>(qi::_1, qi::_2))] + (prism::IdentifierGrammar::instance(this->state) > qi::lit("=") > prism::IdentifierGrammar::instance(this->state) >> -qi::lit(","))[phoenix::insert(qi::_a, phoenix::construct>(qi::_1, qi::_2))] ) > qi::lit("]") > qi::lit("endmodule")) - [ - phoenix::bind(this->state->moduleNames_.add, qi::_1, qi::_1), - qi::_val = phoenix::construct(*phoenix::bind(moduleFinder, this->state->moduleMap_, qi::_2), qi::_1, qi::_a, this->state), - phoenix::bind(this->state->moduleMap_.add, qi::_1, qi::_val) - - ]; + [phoenix::bind(&PrismParser::PrismGrammar::renameModule, this, qi::_1, qi::_2, qi::_a)]; moduleRenaming.name("renamed module"); moduleDefinitionList %= +(moduleDefinition | moduleRenaming); moduleDefinitionList.name("module list"); // This block defines all entities that are needed for parsing constant definitions. - definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> freeIdentifierName >> qi::lit("=") > prism::ConstBooleanExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; + definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > prism::ConstBooleanExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; definedBooleanConstantDefinition.name("defined boolean constant declaration"); definedIntegerConstantDefinition = ( - qi::lit("const") >> - qi::lit("int")[phoenix::bind(&dump, "const int")] >> - freeIdentifierName >> - qi::lit("=")[phoenix::bind(&dump, "const int = ")] >> - //constIntExpr.integerLiteralExpression[phoenix::bind(&dump, "const int = ")] >> - prism::ConstIntegerExpressionGrammar::instance(this->state)[phoenix::bind(&dump, "const int = ")] >> - qi::lit(";")[phoenix::bind(&dump, "const int = ;")] - )[ qi::_val = phoenix::bind(&addIntegerConstant, qi::_1, qi::_2, this->state) ]; + qi::lit("const") >> qi::lit("int") >> prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> + prism::ConstIntegerExpressionGrammar::instance(this->state) >> qi::lit(";") + )[ qi::_val = phoenix::bind(&PrismParser::PrismGrammar::addIntegerConstant, this, qi::_1, qi::_2) ]; definedIntegerConstantDefinition.name("defined integer constant declaration"); - definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> freeIdentifierName >> qi::lit("=") > prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; + definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; definedDoubleConstantDefinition.name("defined double constant declaration"); - undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; + undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > prism::FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; undefinedBooleanConstantDefinition.name("undefined boolean constant declaration"); - undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->integerConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; + undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > prism::FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->integerConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; undefinedIntegerConstantDefinition.name("undefined integer constant declaration"); - undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > freeIdentifierName > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; + undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > prism::FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; undefinedDoubleConstantDefinition.name("undefined double constant declaration"); - definedConstantDefinition %= (definedBooleanConstantDefinition[phoenix::bind(&dump, "")] | definedIntegerConstantDefinition[phoenix::bind(&dump, "")] | definedDoubleConstantDefinition[phoenix::bind(&dump, "")]); + definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); definedConstantDefinition.name("defined constant declaration"); undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3)); undefinedConstantDefinition.name("undefined constant declaration"); - constantDefinitionList = *(definedConstantDefinition[phoenix::bind(&dump, "")] | undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3)[phoenix::bind(&dump, "")]); + constantDefinitionList = *(definedConstantDefinition | undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3)); constantDefinitionList.name("constant declaration list"); // This block defines all entities that are needed for parsing a program. modelTypeDefinition = modelType_; modelTypeDefinition.name("model type"); start = ( - modelTypeDefinition[phoenix::bind(&dump, "")] > - constantDefinitionList(qi::_a, qi::_b, qi::_c)[phoenix::bind(&dump, "")] > - moduleDefinitionList[phoenix::bind(&dump, "")] > - rewardDefinitionList(qi::_d)[phoenix::bind(&dump, "")] > - labelDefinitionList(qi::_e)[phoenix::bind(&dump, "")] - )[qi::_val = phoenix::construct(qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_d, qi::_e)]; + modelTypeDefinition > + constantDefinitionList(qi::_a, qi::_b, qi::_c) > + moduleDefinitionList > + rewardDefinitionList(qi::_d) > + labelDefinitionList(qi::_e) + )[qi::_val = phoenix::bind(&createProgram, qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_d, qi::_e)]; start.name("probabilistic program declaration"); } @@ -250,12 +276,12 @@ std::shared_ptr PrismParser::parse(std::istream& inputStream try { // Now parse the content using phrase_parse in order to be able to supply a skipping parser. // First run. - qi::phrase_parse(positionIteratorBegin, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, *result); + qi::phrase_parse(positionIteratorBegin, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result); grammar.prepareForSecondRun(); result = std::shared_ptr(new storm::ir::Program()); std::cout << "Now we start the second run..." << std::endl; // Second run. - qi::phrase_parse(positionIteratorBegin2, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, *result); + qi::phrase_parse(positionIteratorBegin2, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result); std::cout << "Here is the parsed grammar: " << std::endl << result->toString() << std::endl; } catch(const qi::expectation_failure& e) { // If the parser expected content different than the one provided, display information diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index a32487c78..b08777c65 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -48,7 +48,13 @@ public: * The Boost spirit grammar for the PRISM language. Returns the intermediate representation of * the input that complies with the PRISM syntax. */ - class PrismGrammar : public qi::grammar>, std::map>, std::map>, std::map, std::map>>, Skipper> { + class PrismGrammar : public qi::grammar< + Iterator, + std::shared_ptr(), + qi::locals< + std::map>, + std::map>, + std::map>, std::map>, std::map>>, Skipper> { public: PrismGrammar(); void prepareForSecondRun(); @@ -58,14 +64,18 @@ public: std::shared_ptr state; // The starting point of the grammar. - qi::rule>, std::map>, std::map>, std::map, std::map>>, Skipper> start; + qi::rule< + Iterator, + std::shared_ptr(), + qi::locals>, std::map>, std::map>, std::map>, std::map>>, + Skipper> start; qi::rule modelTypeDefinition; qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; - qi::rule(), Skipper> moduleDefinitionList; + qi::rule>(), Skipper> moduleDefinitionList; // Rules for module definition. - qi::rule, std::vector, std::map, std::map>, Skipper> moduleDefinition; - qi::rule>, Skipper> moduleRenaming; + qi::rule(), qi::locals, std::vector, std::map, std::map>, Skipper> moduleDefinition; + qi::rule(), qi::locals>, Skipper> moduleRenaming; // Rules for variable definitions. qi::rule(), Skipper> integerLiteralExpression; @@ -74,9 +84,9 @@ public: qi::rule&, std::map&), qi::locals>, Skipper> integerVariableDefinition; // Rules for command definitions. - qi::rule, Skipper> commandDefinition; - qi::rule(), Skipper> updateListDefinition; - qi::rule, std::map>, Skipper> updateDefinition; + qi::rule(), qi::locals, Skipper> commandDefinition; + qi::rule>(), Skipper> updateListDefinition; + qi::rule(), qi::locals, std::map>, Skipper> updateDefinition; qi::rule&, std::map&), Skipper> assignmentDefinitionList; qi::rule&, std::map&), Skipper> assignmentDefinition; @@ -86,10 +96,10 @@ public: qi::rule unassignedLocalIntegerVariableName; // Rules for reward definitions. - qi::rule&), Skipper> rewardDefinitionList; - qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; - qi::rule stateRewardDefinition; - qi::rule, Skipper> transitionRewardDefinition; + qi::rule>&), Skipper> rewardDefinitionList; + qi::rule>&), qi::locals>, std::vector>>, Skipper> rewardDefinition; + qi::rule(), Skipper> stateRewardDefinition; + qi::rule(), qi::locals, Skipper> transitionRewardDefinition; // Rules for label definitions. qi::rule>&), Skipper> labelDefinitionList; @@ -106,10 +116,6 @@ public: qi::rule(), Skipper> definedIntegerConstantDefinition; qi::rule(), Skipper> definedDoubleConstantDefinition; - qi::rule freeIdentifierName; - qi::rule identifierName; - - // Rules for variable recognition. qi::rule(), Skipper> booleanVariableCreatorExpression; qi::rule(), qi::locals>, Skipper> integerVariableCreatorExpression; @@ -118,6 +124,13 @@ public: storm::parser::prism::modelTypeStruct modelType_; storm::parser::prism::relationalOperatorStruct relations_; + std::shared_ptr addIntegerConstant(const std::string& name, const std::shared_ptr value); + void addLabel(const std::string& name, std::shared_ptr value, std::map>& mapping); + void addBoolAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); + void addIntAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); + std::shared_ptr renameModule(const std::string& name, const std::string& oldname, std::map& mapping); + std::shared_ptr createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector> commands); + }; private: diff --git a/src/parser/PrismParser/VariableState.h b/src/parser/PrismParser/VariableState.h index 1076d2764..6b2c9a9b3 100644 --- a/src/parser/PrismParser/VariableState.h +++ b/src/parser/PrismParser/VariableState.h @@ -38,14 +38,14 @@ public: // the intermediate representation. struct qi::symbols> integerVariables_, booleanVariables_; struct qi::symbols> integerConstants_, booleanConstants_, doubleConstants_; - struct qi::symbols moduleMap_; + struct qi::symbols> moduleMap_; // A structure representing the identity function over identifier names. struct variableNamesStruct : qi::symbols { } integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_, localBooleanVariables_, localIntegerVariables_, assignedLocalBooleanVariables_, assignedLocalIntegerVariables_; uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init) { - std::cerr << "adding boolean variable " << name << std::endl; + //std::cerr << "adding boolean variable " << name << std::endl; if (firstRun) { std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::bool_, this->nextBooleanVariableIndex, name)); this->booleanVariables_.add(name, varExpr); @@ -64,7 +64,7 @@ public: } uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init) { - std::cerr << "adding integer variable " << name << std::endl; + //std::cerr << "adding integer variable " << name << std::endl; if (firstRun) { std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::int_, this->nextIntegerVariableIndex, name, lower, upper)); this->integerVariables_.add(name, varExpr); @@ -83,7 +83,7 @@ public: } std::shared_ptr getBooleanVariable(const std::string& name) { - std::cerr << "getting boolen variable " << name << std::endl; + //std::cerr << "getting boolen variable " << name << std::endl; std::shared_ptr res = this->booleanVariables_.at(name); if (res != nullptr) { return res; @@ -98,7 +98,7 @@ public: } std::shared_ptr getIntegerVariable(const std::string& name) { - std::cerr << "getting integer variable " << name << std::endl; + //std::cerr << "getting integer variable " << name << std::endl; std::shared_ptr res = this->integerVariables_.at(name); if (res != nullptr) { return res; @@ -113,13 +113,13 @@ public: } void startModule() { - std::cerr << "starting new module" << std::endl; + //std::cerr << "starting new module" << std::endl; this->localBooleanVariables_.clear(); this->localIntegerVariables_.clear(); } bool isFreeIdentifier(std::string& s) const { - std::cerr << "Checking if " << s << " is free" << std::endl; + //std::cerr << "Checking if " << s << " is free" << std::endl; if (this->integerVariableNames_.find(s) != nullptr) return false; if (this->allConstantNames_.find(s) != nullptr) return false; if (this->labelNames_.find(s) != nullptr) return false; @@ -128,7 +128,7 @@ public: return true; } bool isIdentifier(std::string& s) const { - std::cerr << "Checking if " << s << " is identifier" << std::endl; + //std::cerr << "Checking if " << s << " is identifier" << std::endl; if (this->allConstantNames_.find(s) != nullptr) return false; if (this->keywords.find(s) != nullptr) return false; return true; From 3c1cf4819cded7607cb0b9e9609754a3d0d123fa Mon Sep 17 00:00:00 2001 From: gereon Date: Sat, 20 Apr 2013 19:35:16 +0200 Subject: [PATCH 077/152] Fixed a few other issues. Module renaming seems to work now! (However, there is still a segfault at some later point...) --- src/ir/Command.cpp | 3 --- src/ir/Module.cpp | 9 ++++----- src/ir/Program.cpp | 1 + src/ir/expressions/BinaryRelationExpression.h | 5 +---- src/ir/expressions/VariableExpression.h | 6 ------ src/parser/PrismParser.cpp | 4 ++-- 6 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/ir/Command.cpp b/src/ir/Command.cpp index ea2141bf0..673a1bd14 100644 --- a/src/ir/Command.cpp +++ b/src/ir/Command.cpp @@ -27,9 +27,6 @@ Command::Command(std::string actionName, std::shared_ptr& renaming, const std::map& bools, const std::map& ints) : actionName(cmd.actionName), guardExpression(cmd.guardExpression->clone(renaming, bools, ints)) { - std::cout << "Cloning command" << std::endl; - std::cout << cmd.guardExpression->dump("\t"); - std::cout << this->guardExpression->dump("\t"); if (renaming.count(this->actionName) > 0) { this->actionName = renaming.at(this->actionName); } diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index c3049a0ea..2d1482846 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -23,7 +23,8 @@ Module::Module() : moduleName(), booleanVariables(), integerVariables(), boolean } // Initializes all members according to the given values. -Module::Module(std::string moduleName, std::vector booleanVariables, +Module::Module(std::string moduleName, + std::vector booleanVariables, std::vector integerVariables, std::map booleanVariableToIndexMap, std::map integerVariableToIndexMap, @@ -41,7 +42,6 @@ Module::Module(const Module& module, const std::string& moduleName, const std::m for (auto it: renaming) { std::cout << "\t" << it.first << " -> " << it.second << std::endl; } - std::cout << "Current module " << &module << ":" << std::endl << module.toString() << std::endl; this->booleanVariables.reserve(module.booleanVariables.size()); for (BooleanVariable it: module.booleanVariables) { if (renaming.count(it.getName()) > 0) { @@ -69,10 +69,9 @@ Module::Module(const Module& module, const std::string& moduleName, const std::m this->commands.reserve(module.commands.size()); for (std::shared_ptr cmd: module.commands) { - std::cout << "2: Current command: " << cmd->toString() << std::endl; - this->commands.emplace_back(new Command(*cmd, renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap)); + Command* c = new Command(*cmd, renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap); + this->commands.emplace_back(c); } - this->collectActions(); } diff --git a/src/ir/Program.cpp b/src/ir/Program.cpp index 01a77298f..d153a1bc6 100644 --- a/src/ir/Program.cpp +++ b/src/ir/Program.cpp @@ -9,6 +9,7 @@ #include "exceptions/InvalidArgumentException.h" #include +#include #include "log4cplus/logger.h" #include "log4cplus/loggingmacros.h" diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h index 99e4232c2..8d6184ff7 100644 --- a/src/ir/expressions/BinaryRelationExpression.h +++ b/src/ir/expressions/BinaryRelationExpression.h @@ -22,7 +22,6 @@ public: enum RelationType {EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL}; BinaryRelationExpression(std::shared_ptr left, std::shared_ptr right, RelationType relationType) : BinaryExpression(bool_, left, right), relationType(relationType) { - std::cerr << "BinaryRelationExpression: " << left.get() << " " << relationType << " " << right.get() << " ?" << std::endl; } virtual ~BinaryRelationExpression() { @@ -30,9 +29,7 @@ public: } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { - auto res = std::shared_ptr(new BinaryRelationExpression(this->getLeft()->clone(renaming, bools, ints), this->getRight()->clone(renaming, bools, ints), this->relationType)); - std::cout << "Cloning " << this->toString() << " to " << res->toString() << std::endl; - return res; + return std::shared_ptr(new BinaryRelationExpression(this->getLeft()->clone(renaming, bools, ints), this->getRight()->clone(renaming, bools, ints), this->relationType)); } virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index 3aa57ee3e..d0fc4cf30 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -30,17 +30,11 @@ public: } virtual ~VariableExpression() { - } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { - std::cout << this << " Cloning VarExpr " << this->variableName << " (" << renaming.size() << " renamings)" << std::endl; - for (auto it: renaming) { - std::cout << "\t" << it.first << " -> " << it.second << std::endl; - } if (renaming.count(this->variableName) > 0) { std::string newName = renaming.at(this->variableName); - std::cout << "index of " << newName << " are " << bools.at(newName) << " and " << ints.at(newName) << std::endl; if (this->getType() == bool_) { return std::shared_ptr(new VariableExpression(bool_, bools.at(newName), newName, this->lowerBound, this->upperBound)); } else if (this->getType() == int_) { diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 2714d369e..5b29913bc 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -173,14 +173,14 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type // This block defines all entities that are needed for parsing a module. moduleDefinition = (qi::lit("module") >> prism::FreeIdentifierGrammar::instance(this->state)[phoenix::bind(&prism::VariableState::startModule, *this->state)] >> *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) >> +commandDefinition > qi::lit("endmodule")) - [phoenix::bind(&PrismParser::PrismGrammar::createModule, this, qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2)]; + [qi::_val = phoenix::bind(&PrismParser::PrismGrammar::createModule, this, qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2)]; moduleDefinition.name("module"); moduleRenaming = (qi::lit("module") >> prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > this->state->moduleNames_ > qi::lit("[") > *( (prism::IdentifierGrammar::instance(this->state) > qi::lit("=") > prism::IdentifierGrammar::instance(this->state) >> -qi::lit(","))[phoenix::insert(qi::_a, phoenix::construct>(qi::_1, qi::_2))] ) > qi::lit("]") > qi::lit("endmodule")) - [phoenix::bind(&PrismParser::PrismGrammar::renameModule, this, qi::_1, qi::_2, qi::_a)]; + [qi::_val = phoenix::bind(&PrismParser::PrismGrammar::renameModule, this, qi::_1, qi::_2, qi::_a)]; moduleRenaming.name("renamed module"); moduleDefinitionList %= +(moduleDefinition | moduleRenaming); moduleDefinitionList.name("module list"); From d03f8eeb9d958f1e24ae26f6a4eb3d77079427fb Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 23 Apr 2013 16:57:20 +0200 Subject: [PATCH 078/152] Added checks, if we actually have a model before accessing it... --- src/adapters/ExplicitModelAdapter.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index e9f4263d6..dd5fb247e 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -35,18 +35,21 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { } std::shared_ptr ExplicitModelAdapter::getModel(std::string const & rewardModelName) { - - if (rewardModelName != "") { - this->rewardModel = this->program->getRewardModel(rewardModelName); - } + this->buildTransitionMap(); std::shared_ptr stateLabeling = this->getStateLabeling(this->program->getLabels()); std::shared_ptr> stateRewards = nullptr; - if (this->rewardModel->hasStateRewards()) { - stateRewards = this->getStateRewards(this->rewardModel->getStateRewards()); + this->rewardModel = nullptr; + if (rewardModelName != "") { + this->rewardModel = this->program->getRewardModel(rewardModelName); + if (this->rewardModel != nullptr) { + if (this->rewardModel->hasStateRewards()) { + stateRewards = this->getStateRewards(this->rewardModel->getStateRewards()); + } + } } switch (this->program->getModelType()) @@ -413,7 +416,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size())); result->initialize(numberOfTransitions); - if (this->rewardModel->hasTransitionRewards()) { + if ((this->rewardModel != nullptr) && (this->rewardModel->hasTransitionRewards())) { this->transitionRewards = std::shared_ptr>(new storm::storage::SparseMatrix(allStates.size())); this->transitionRewards->initialize(numberOfTransitions); } @@ -427,7 +430,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { for (auto choice : transitionMap[state]) { for (auto elem : choice.second) { map[elem.first] += elem.second; - if (this->rewardModel->hasTransitionRewards()) { + if ((this->rewardModel != nullptr) && (this->rewardModel->hasTransitionRewards())) { for (auto reward : this->rewardModel->getTransitionRewards()) { rewardMap[elem.first] += reward->getReward(choice.first, this->allStates[state]); } @@ -438,7 +441,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { double factor = 1.0 / transitionMap[state].size(); for (auto it : map) { result->addNextValue(state, it.first, it.second * factor); - if (this->rewardModel->hasTransitionRewards()) { + if ((this->rewardModel != nullptr) && (this->rewardModel->hasTransitionRewards())) { this->transitionRewards->addNextValue(state, it.first, rewardMap[it.first] * factor); } } @@ -468,7 +471,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { for (auto choice : transitionMap[state]) { for (auto it : choice.second) { result->addNextValue(nextRow, it.first, it.second); - if (this->rewardModel->hasTransitionRewards()) { + if ((this->rewardModel != nullptr) && (this->rewardModel->hasTransitionRewards())) { double rewardValue = 0; for (auto reward : this->rewardModel->getTransitionRewards()) { rewardValue = reward->getReward(choice.first, this->allStates[state]); From 1878962dea3eb99bbf35b34dae8b5a7359dc60a5 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 23 Apr 2013 17:24:13 +0200 Subject: [PATCH 079/152] Fixed another nullptr, removed shared_ptr for Update and Command objects. --- src/adapters/ExplicitModelAdapter.cpp | 48 +++++++++++++-------------- src/adapters/ExplicitModelAdapter.h | 4 +-- src/ir/Command.cpp | 10 +++--- src/ir/Command.h | 6 ++-- src/ir/Module.cpp | 13 ++++---- src/ir/Module.h | 6 ++-- src/parser/PrismParser.cpp | 10 +++--- src/parser/PrismParser.h | 8 ++--- 8 files changed, 52 insertions(+), 53 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index dd5fb247e..39d7bfe8b 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -160,20 +160,20 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { * @param action Action label. * @return Active commands. */ - std::unique_ptr>>> ExplicitModelAdapter::getActiveCommandsByAction(StateType const * state, std::string& action) { - std::unique_ptr>>> res = std::unique_ptr>>>(new std::list>>()); + std::unique_ptr>> ExplicitModelAdapter::getActiveCommandsByAction(StateType const * state, std::string& action) { + std::unique_ptr>> res = std::unique_ptr>>(new std::list>()); // Iterate over all modules. for (uint_fast64_t i = 0; i < this->program->getNumberOfModules(); ++i) { std::shared_ptr const module = this->program->getModule(i); std::shared_ptr> ids = module->getCommandsByAction(action); - std::list> commands; + std::list commands; // Look up commands by their id. Add, if guard holds. for (uint_fast64_t id : *ids) { - std::shared_ptr cmd = module->getCommand(id); - if (cmd->getGuard()->getValueAsBool(state)) { + storm::ir::Command cmd = module->getCommand(id); + if (cmd.getGuard()->getValueAsBool(state)) { commands.push_back(module->getCommand(id)); } } @@ -181,7 +181,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { } // Sort the result in the vague hope that having small lists at the beginning will speed up the expanding. // This is how lambdas may look like in C++... - res->sort([](const std::list>& a, const std::list>& b){ return a.size() < b.size(); }); + res->sort([](const std::list& a, const std::list& b){ return a.size() < b.size(); }); return res; } @@ -191,12 +191,12 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { * @params update Update to be applied. * @return Resulting state. */ - StateType* ExplicitModelAdapter::applyUpdate(StateType const * const state, std::shared_ptr const update) const { + StateType* ExplicitModelAdapter::applyUpdate(StateType const * const state, storm::ir::Update const& update) const { StateType* newState = new StateType(*state); - for (auto assignedVariable : update->getBooleanAssignments()) { + for (auto assignedVariable : update.getBooleanAssignments()) { setValue(newState, this->booleanVariableToIndexMap.at(assignedVariable.first), assignedVariable.second.getExpression()->getValueAsBool(state)); } - for (auto assignedVariable : update->getIntegerAssignments()) { + for (auto assignedVariable : update.getIntegerAssignments()) { setValue(newState, this->integerVariableToIndexMap.at(assignedVariable.first), assignedVariable.second.getExpression()->getValueAsInt(state)); } return newState; @@ -297,29 +297,29 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { std::shared_ptr const module = program->getModule(i); // Iterate over all commands. for (uint_fast64_t j = 0; j < module->getNumberOfCommands(); ++j) { - std::shared_ptr const command = module->getCommand(j); + storm::ir::Command const& command = module->getCommand(j); // Only consider unlabeled commands. - if (command->getActionName() != "") continue; + if (command.getActionName() != "") continue; // Omit, if command is not active. - if (!command->getGuard()->getValueAsBool(state)) continue; + if (!command.getGuard()->getValueAsBool(state)) continue; // Add a new map and get pointer. res.emplace_back(); std::map* states = &res.back().second; // Iterate over all updates. - for (uint_fast64_t k = 0; k < command->getNumberOfUpdates(); ++k) { + for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { // Obtain new state id. - std::shared_ptr const update = command->getUpdate(k); + storm::ir::Update const& update = command.getUpdate(k); uint_fast64_t newStateId = this->getOrAddStateId(this->applyUpdate(state, update)); // Check, if we already know this state, add up probabilities for every state. auto stateIt = states->find(newStateId); if (stateIt == states->end()) { - (*states)[newStateId] = update->getLikelihoodExpression()->getValueAsDouble(state); + (*states)[newStateId] = update.getLikelihoodExpression()->getValueAsDouble(state); this->numberOfTransitions++; } else { - (*states)[newStateId] += update->getLikelihoodExpression()->getValueAsDouble(state); + (*states)[newStateId] += update.getLikelihoodExpression()->getValueAsDouble(state); } } } @@ -336,21 +336,21 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { // Create a copy of the current state, as we will free intermediate states... for (std::string action : this->program->getActions()) { StateType* state = new StateType(*this->allStates[stateID]); - std::unique_ptr>>> cmds = this->getActiveCommandsByAction(state, action); + std::unique_ptr>> cmds = this->getActiveCommandsByAction(state, action); // Start with current state std::unordered_map resultStates; resultStates[state] = 1.0; - for (std::list> module : *cmds) { + for (std::list module : *cmds) { if (resultStates.size() == 0) break; std::unordered_map newStates; // Iterate over all commands within this module. - for (std::shared_ptr command : module) { + for (storm::ir::Command command : module) { // Iterate over all updates of this command. - for (uint_fast64_t k = 0; k < command->getNumberOfUpdates(); ++k) { - std::shared_ptr const update = command->getUpdate(k); + for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { + storm::ir::Update const update = command.getUpdate(k); // Iterate over all resultStates. for (auto it : resultStates) { @@ -360,9 +360,9 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { // Take care of calculation of likelihood, combine identical states. auto s = newStates.find(newState); if (s == newStates.end()) { - newStates[newState] = it.second * update->getLikelihoodExpression()->getValueAsDouble(it.first); + newStates[newState] = it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); } else { - newStates[newState] += it.second * update->getLikelihoodExpression()->getValueAsDouble(it.first); + newStates[newState] += it.second * update.getLikelihoodExpression()->getValueAsDouble(it.first); } } } @@ -461,7 +461,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { LOG4CPLUS_DEBUG(logger, "Building nondeterministic transition matrix with " << this->numberOfChoices << " choices and " << this->numberOfTransitions << " transitions now."); std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size(), this->numberOfChoices)); result->initialize(this->numberOfTransitions); - if (this->rewardModel->hasTransitionRewards()) { + if ((this->rewardModel != nullptr) && (this->rewardModel->hasTransitionRewards())) { this->transitionRewards = std::shared_ptr>(new storm::storage::SparseMatrix(allStates.size(), this->numberOfChoices)); this->transitionRewards->initialize(this->numberOfTransitions); } diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 962bfa6d8..73a705e33 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -83,7 +83,7 @@ private: * @params update Update to be applied. * @return Resulting state. */ - StateType* applyUpdate(StateType const * const state, std::shared_ptr const update) const; + StateType* applyUpdate(StateType const * const state, storm::ir::Update const& update) const; /*! * Reads and combines variables from all program modules and stores them. @@ -107,7 +107,7 @@ private: * @param action Action label. * @return Active commands. */ - std::unique_ptr>>> getActiveCommandsByAction(StateType const * state, std::string& action); + std::unique_ptr>> getActiveCommandsByAction(StateType const * state, std::string& action); /*! * Generates all initial states and adds them to allStates. diff --git a/src/ir/Command.cpp b/src/ir/Command.cpp index 673a1bd14..05fe1084c 100644 --- a/src/ir/Command.cpp +++ b/src/ir/Command.cpp @@ -20,7 +20,7 @@ Command::Command() : actionName(), guardExpression(), updates() { } // Initializes all members according to the given values. -Command::Command(std::string actionName, std::shared_ptr guardExpression, std::vector> updates) +Command::Command(std::string actionName, std::shared_ptr guardExpression, std::vector updates) : actionName(actionName), guardExpression(guardExpression), updates(updates) { // Nothing to do here. } @@ -31,8 +31,8 @@ Command::Command(const Command& cmd, const std::map& r this->actionName = renaming.at(this->actionName); } this->updates.reserve(cmd.updates.size()); - for (std::shared_ptr u : cmd.updates) { - this->updates.emplace_back(new Update(*u, renaming, bools, ints)); + for (Update u : cmd.updates) { + this->updates.emplace_back(u, renaming, bools, ints); } } @@ -52,7 +52,7 @@ uint_fast64_t Command::getNumberOfUpdates() const { } // Return the requested update. -std::shared_ptr const& Command::getUpdate(uint_fast64_t index) const { +storm::ir::Update const& Command::getUpdate(uint_fast64_t index) const { return this->updates[index]; } @@ -61,7 +61,7 @@ std::string Command::toString() const { std::stringstream result; result << "[" << actionName << "] " << guardExpression->toString() << " -> "; for (uint_fast64_t i = 0; i < updates.size(); ++i) { - result << updates[i]->toString(); + result << updates[i].toString(); if (i < updates.size() - 1) { result << " + "; } diff --git a/src/ir/Command.h b/src/ir/Command.h index 4e3da7f65..b4049307c 100644 --- a/src/ir/Command.h +++ b/src/ir/Command.h @@ -34,7 +34,7 @@ public: * @param actionName the action name of the command. * @param guardExpression the expression that defines the guard of the command. */ - Command(std::string actionName, std::shared_ptr guardExpression, std::vector> updates); + Command(std::string actionName, std::shared_ptr guardExpression, std::vector updates); Command(const Command& cmd, const std::map& renaming, const std::map& bools, const std::map& ints); /*! @@ -59,7 +59,7 @@ public: * Retrieves a reference to the update with the given index. * @returns a reference to the update with the given index. */ - std::shared_ptr const& getUpdate(uint_fast64_t index) const; + storm::ir::Update const& getUpdate(uint_fast64_t index) const; /*! * Retrieves a string representation of this command. @@ -75,7 +75,7 @@ private: std::shared_ptr guardExpression; // The list of updates of the command. - std::vector> updates; + std::vector updates; }; } // namespace ir diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index 2d1482846..6bb8aa1aa 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -28,7 +28,7 @@ Module::Module(std::string moduleName, std::vector integerVariables, std::map booleanVariableToIndexMap, std::map integerVariableToIndexMap, - std::vector> commands) + std::vector commands) : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), booleanVariablesToIndexMap(booleanVariableToIndexMap), integerVariablesToIndexMap(integerVariableToIndexMap), commands(commands), actions(), actionsToCommandIndexMap() { @@ -68,9 +68,8 @@ Module::Module(const Module& module, const std::string& moduleName, const std::m } this->commands.reserve(module.commands.size()); - for (std::shared_ptr cmd: module.commands) { - Command* c = new Command(*cmd, renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap); - this->commands.emplace_back(c); + for (Command cmd: module.commands) { + this->commands.emplace_back(cmd, renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap); } this->collectActions(); } @@ -121,7 +120,7 @@ uint_fast64_t Module::getIntegerVariableIndex(std::string variableName) const { } // Return the requested command. -std::shared_ptr const Module::getCommand(uint_fast64_t index) const { +storm::ir::Command const Module::getCommand(uint_fast64_t index) const { return this->commands[index]; } @@ -136,7 +135,7 @@ std::string Module::toString() const { result << "\t" << variable.toString() << std::endl; } for (auto command : commands) { - result << "\t" << command->toString() << std::endl; + result << "\t" << command.toString() << std::endl; } result << "endmodule" << std::endl; return result.str(); @@ -159,7 +158,7 @@ std::shared_ptr> const Module::getCommandsByAction(std:: void Module::collectActions() { for (unsigned int id = 0; id < this->commands.size(); id++) { - std::string action = this->commands[id]->getActionName(); + std::string action = this->commands[id].getActionName(); if (action != "") { if (this->actionsToCommandIndexMap.count(action) == 0) { this->actionsToCommandIndexMap[action] = std::shared_ptr>(new std::set()); diff --git a/src/ir/Module.h b/src/ir/Module.h index 2a97a2ab3..8bc465b44 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -48,7 +48,7 @@ public: std::vector integerVariables, std::map booleanVariableToIndexMap, std::map integerVariableToIndexMap, - std::vector> commands); + std::vector commands); typedef uint_fast64_t (*addIntegerVariablePtr)(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init); typedef uint_fast64_t (*addBooleanVariablePtr)(const std::string& name, const std::shared_ptr init); @@ -110,7 +110,7 @@ public: * Retrieves a reference to the command with the given index. * @returns a reference to the command with the given index. */ - std::shared_ptr const getCommand(uint_fast64_t index) const; + storm::ir::Command const getCommand(uint_fast64_t index) const; /*! * Retrieves a string representation of this variable. @@ -152,7 +152,7 @@ private: std::map integerVariablesToIndexMap; // The commands associated with the module. - std::vector> commands; + std::vector commands; // The set of actions present in this module. std::set actions; diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 5b29913bc..7340d9d3a 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -69,7 +69,7 @@ namespace parser { this->state->moduleMap_.add(name, res); return res; } - std::shared_ptr PrismParser::PrismGrammar::createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector> commands) { + std::shared_ptr PrismParser::PrismGrammar::createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands) { this->state->moduleNames_.add(name, name); std::shared_ptr res = std::shared_ptr(new Module(name, bools, ints, boolids, intids, commands)); this->state->moduleMap_.add(name, res); @@ -85,11 +85,11 @@ namespace parser { void createRewardModel(std::string name, std::vector>& stateRewards, std::vector>& transitionRewards, std::map>& mapping) { mapping[name] = std::shared_ptr(new RewardModel(name, stateRewards, transitionRewards)); } - std::shared_ptr createUpdate(std::shared_ptr likelihood, std::map& bools, std::map ints) { - return std::shared_ptr(new Update(likelihood, bools, ints)); + Update createUpdate(std::shared_ptr likelihood, std::map& bools, std::map ints) { + return Update(likelihood, bools, ints); } - std::shared_ptr createCommand(std::string& label, std::shared_ptr guard, std::vector>& updates) { - return std::shared_ptr(new Command(label, guard, updates)); + Command createCommand(std::string& label, std::shared_ptr guard, std::vector& updates) { + return Command(label, guard, updates); } std::shared_ptr createProgram( Program::ModelType modelType, diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index b08777c65..0da0e0821 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -84,9 +84,9 @@ public: qi::rule&, std::map&), qi::locals>, Skipper> integerVariableDefinition; // Rules for command definitions. - qi::rule(), qi::locals, Skipper> commandDefinition; - qi::rule>(), Skipper> updateListDefinition; - qi::rule(), qi::locals, std::map>, Skipper> updateDefinition; + qi::rule, Skipper> commandDefinition; + qi::rule(), Skipper> updateListDefinition; + qi::rule, std::map>, Skipper> updateDefinition; qi::rule&, std::map&), Skipper> assignmentDefinitionList; qi::rule&, std::map&), Skipper> assignmentDefinition; @@ -129,7 +129,7 @@ public: void addBoolAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); void addIntAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); std::shared_ptr renameModule(const std::string& name, const std::string& oldname, std::map& mapping); - std::shared_ptr createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector> commands); + std::shared_ptr createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands); }; From 9613d099bb8d02d6fd538383bc0ed5e2ca8d2955 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 23 Apr 2013 18:20:05 +0200 Subject: [PATCH 080/152] Removed shared_ptr for module, program and rewardmodel objects. --- src/adapters/ExplicitModelAdapter.cpp | 58 +++++++++++++------------- src/adapters/ExplicitModelAdapter.h | 8 ++-- src/ir/Program.cpp | 22 +++++----- src/ir/Program.h | 16 +++---- src/ir/RewardModel.cpp | 10 ++--- src/ir/RewardModel.h | 10 ++--- src/parser/PrismParser.cpp | 46 ++++++++++---------- src/parser/PrismParser.h | 43 +++++++++++-------- src/parser/PrismParser/VariableState.h | 2 +- 9 files changed, 112 insertions(+), 103 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index 39d7bfe8b..d5f9be117 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -24,7 +24,7 @@ namespace storm { namespace adapters { -ExplicitModelAdapter::ExplicitModelAdapter(std::shared_ptr program) : program(program), +ExplicitModelAdapter::ExplicitModelAdapter(storm::ir::Program program) : program(program), booleanVariables(), integerVariables(), booleanVariableToIndexMap(), integerVariableToIndexMap(), allStates(), stateToIndexMap(), numberOfTransitions(0), numberOfChoices(0), transitionRewards(nullptr), transitionMap() { this->initializeVariables(); @@ -39,12 +39,12 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { this->buildTransitionMap(); - std::shared_ptr stateLabeling = this->getStateLabeling(this->program->getLabels()); + std::shared_ptr stateLabeling = this->getStateLabeling(this->program.getLabels()); std::shared_ptr> stateRewards = nullptr; this->rewardModel = nullptr; if (rewardModelName != "") { - this->rewardModel = this->program->getRewardModel(rewardModelName); + this->rewardModel = std::unique_ptr(new storm::ir::RewardModel(this->program.getRewardModel(rewardModelName)));; if (this->rewardModel != nullptr) { if (this->rewardModel->hasStateRewards()) { stateRewards = this->getStateRewards(this->rewardModel->getStateRewards()); @@ -52,7 +52,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { } } - switch (this->program->getModelType()) + switch (this->program.getModelType()) { case storm::ir::Program::DTMC: { @@ -93,11 +93,11 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { std::get<1>(*state)[index] = value; } - std::shared_ptr> ExplicitModelAdapter::getStateRewards(std::vector> const & rewards) { + std::shared_ptr> ExplicitModelAdapter::getStateRewards(std::vector const & rewards) { std::shared_ptr> results(new std::vector(this->allStates.size())); for (uint_fast64_t index = 0; index < this->allStates.size(); index++) { for (auto reward: rewards) { - (*results)[index] = reward->getReward(this->allStates[index]); + (*results)[index] = reward.getReward(this->allStates[index]); } } return results; @@ -121,9 +121,9 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { void ExplicitModelAdapter::initializeVariables() { uint_fast64_t numberOfIntegerVariables = 0; uint_fast64_t numberOfBooleanVariables = 0; - for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { - numberOfIntegerVariables += program->getModule(i)->getNumberOfIntegerVariables(); - numberOfBooleanVariables += program->getModule(i)->getNumberOfBooleanVariables(); + for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { + numberOfIntegerVariables += program.getModule(i).getNumberOfIntegerVariables(); + numberOfBooleanVariables += program.getModule(i).getNumberOfBooleanVariables(); } this->booleanVariables.resize(numberOfBooleanVariables); @@ -131,17 +131,17 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { uint_fast64_t nextBooleanVariableIndex = 0; uint_fast64_t nextIntegerVariableIndex = 0; - for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { - std::shared_ptr const module = program->getModule(i); + for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { + storm::ir::Module const& module = program.getModule(i); - for (uint_fast64_t j = 0; j < module->getNumberOfBooleanVariables(); ++j) { - this->booleanVariables[nextBooleanVariableIndex] = module->getBooleanVariable(j); - this->booleanVariableToIndexMap[module->getBooleanVariable(j).getName()] = nextBooleanVariableIndex; + for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { + this->booleanVariables[nextBooleanVariableIndex] = module.getBooleanVariable(j); + this->booleanVariableToIndexMap[module.getBooleanVariable(j).getName()] = nextBooleanVariableIndex; ++nextBooleanVariableIndex; } - for (uint_fast64_t j = 0; j < module->getNumberOfIntegerVariables(); ++j) { - this->integerVariables[nextIntegerVariableIndex] = module->getIntegerVariable(j); - this->integerVariableToIndexMap[module->getIntegerVariable(j).getName()] = nextIntegerVariableIndex; + for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) { + this->integerVariables[nextIntegerVariableIndex] = module.getIntegerVariable(j); + this->integerVariableToIndexMap[module.getIntegerVariable(j).getName()] = nextIntegerVariableIndex; ++nextIntegerVariableIndex; } } @@ -164,17 +164,17 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { std::unique_ptr>> res = std::unique_ptr>>(new std::list>()); // Iterate over all modules. - for (uint_fast64_t i = 0; i < this->program->getNumberOfModules(); ++i) { - std::shared_ptr const module = this->program->getModule(i); + for (uint_fast64_t i = 0; i < this->program.getNumberOfModules(); ++i) { + storm::ir::Module const& module = this->program.getModule(i); - std::shared_ptr> ids = module->getCommandsByAction(action); + std::shared_ptr> ids = module.getCommandsByAction(action); std::list commands; // Look up commands by their id. Add, if guard holds. for (uint_fast64_t id : *ids) { - storm::ir::Command cmd = module->getCommand(id); + storm::ir::Command cmd = module.getCommand(id); if (cmd.getGuard()->getValueAsBool(state)) { - commands.push_back(module->getCommand(id)); + commands.push_back(module.getCommand(id)); } } res->push_back(commands); @@ -293,11 +293,11 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { void ExplicitModelAdapter::addUnlabeledTransitions(const uint_fast64_t stateID, std::list>>& res) { const StateType* state = this->allStates[stateID]; // Iterate over all modules. - for (uint_fast64_t i = 0; i < program->getNumberOfModules(); ++i) { - std::shared_ptr const module = program->getModule(i); + for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { + storm::ir::Module const& module = program.getModule(i); // Iterate over all commands. - for (uint_fast64_t j = 0; j < module->getNumberOfCommands(); ++j) { - storm::ir::Command const& command = module->getCommand(j); + for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { + storm::ir::Command const& command = module.getCommand(j); // Only consider unlabeled commands. if (command.getActionName() != "") continue; // Omit, if command is not active. @@ -334,7 +334,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { */ void ExplicitModelAdapter::addLabeledTransitions(const uint_fast64_t stateID, std::list>>& res) { // Create a copy of the current state, as we will free intermediate states... - for (std::string action : this->program->getActions()) { + for (std::string action : this->program.getActions()) { StateType* state = new StateType(*this->allStates[stateID]); std::unique_ptr>> cmds = this->getActiveCommandsByAction(state, action); @@ -432,7 +432,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { map[elem.first] += elem.second; if ((this->rewardModel != nullptr) && (this->rewardModel->hasTransitionRewards())) { for (auto reward : this->rewardModel->getTransitionRewards()) { - rewardMap[elem.first] += reward->getReward(choice.first, this->allStates[state]); + rewardMap[elem.first] += reward.getReward(choice.first, this->allStates[state]); } } } @@ -474,7 +474,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { if ((this->rewardModel != nullptr) && (this->rewardModel->hasTransitionRewards())) { double rewardValue = 0; for (auto reward : this->rewardModel->getTransitionRewards()) { - rewardValue = reward->getReward(choice.first, this->allStates[state]); + rewardValue = reward.getReward(choice.first, this->allStates[state]); } this->transitionRewards->addNextValue(nextRow, it.first, rewardValue); } diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 73a705e33..f97f76c5e 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -53,7 +53,7 @@ public: class ExplicitModelAdapter { public: - ExplicitModelAdapter(std::shared_ptr program); + ExplicitModelAdapter(storm::ir::Program program); ~ExplicitModelAdapter(); std::shared_ptr getModel(std::string const & rewardModelName = ""); @@ -91,7 +91,7 @@ private: */ void initializeVariables(); - std::shared_ptr> getStateRewards(std::vector> const & rewards); + std::shared_ptr> getStateRewards(std::vector const & rewards); std::shared_ptr getStateLabeling(std::map> labels); /*! @@ -166,14 +166,14 @@ private: void clearInternalState(); // Program that should be converted. - std::shared_ptr program; + storm::ir::Program program; std::vector booleanVariables; std::vector integerVariables; std::map booleanVariableToIndexMap; std::map integerVariableToIndexMap; // Members that are filled during the conversion. - std::shared_ptr rewardModel; + std::unique_ptr rewardModel; std::vector allStates; std::unordered_map stateToIndexMap; uint_fast64_t numberOfTransitions; diff --git a/src/ir/Program.cpp b/src/ir/Program.cpp index d153a1bc6..fd75d9b3e 100644 --- a/src/ir/Program.cpp +++ b/src/ir/Program.cpp @@ -25,15 +25,15 @@ Program::Program() : modelType(UNDEFINED), booleanUndefinedConstantExpressions() } // Initializes all members according to the given values. -Program::Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector> modules, std::map> rewards, std::map> labels) +Program::Program(ModelType modelType, std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, std::vector modules, std::map rewards, std::map> labels) : modelType(modelType), booleanUndefinedConstantExpressions(booleanUndefinedConstantExpressions), integerUndefinedConstantExpressions(integerUndefinedConstantExpressions), doubleUndefinedConstantExpressions(doubleUndefinedConstantExpressions), modules(modules), rewards(rewards), labels(labels), actionsToModuleIndexMap() { // Build actionsToModuleIndexMap for (unsigned int id = 0; id < this->modules.size(); id++) { - for (auto action : this->modules[id]->getActions()) { + for (auto action : this->modules[id].getActions()) { if (this->actionsToModuleIndexMap.count(action) == 0) { - this->actionsToModuleIndexMap[action] = std::shared_ptr>(new std::set()); + this->actionsToModuleIndexMap[action] = std::set(); } - this->actionsToModuleIndexMap[action]->insert(id); + this->actionsToModuleIndexMap[action].insert(id); this->actions.insert(action); } } @@ -67,11 +67,11 @@ std::string Program::toString() const { result << std::endl; for (auto module : modules) { - result << module->toString() << std::endl; + result << module.toString() << std::endl; } for (auto rewardModel : rewards) { - result << rewardModel.first << ": " << rewardModel.second->toString() << std::endl; + result << rewardModel.first << ": " << rewardModel.second.toString() << std::endl; } for (auto label : labels) { @@ -85,7 +85,7 @@ uint_fast64_t Program::getNumberOfModules() const { return this->modules.size(); } -std::shared_ptr const& Program::getModule(uint_fast64_t index) const { +storm::ir::Module const& Program::getModule(uint_fast64_t index) const { return this->modules[index]; } @@ -95,20 +95,20 @@ std::set const& Program::getActions() const { } // Return modules with given action. -std::shared_ptr> const Program::getModulesByAction(std::string const& action) const { +std::set const Program::getModulesByAction(std::string const& action) const { auto res = this->actionsToModuleIndexMap.find(action); if (res == this->actionsToModuleIndexMap.end()) { - return std::shared_ptr>(new std::set()); + return std::set(); } else { return res->second; } } -std::shared_ptr Program::getRewardModel(std::string const & name) const { +storm::ir::RewardModel Program::getRewardModel(std::string const & name) const { auto it = this->rewards.find(name); if (it == this->rewards.end()) { LOG4CPLUS_ERROR(logger, "The given reward model \"" << name << "\" does not exist. We will proceed without rewards."); - return nullptr; + throw "Rewardmodel does not exist."; } else { return it->second; } diff --git a/src/ir/Program.h b/src/ir/Program.h index d51ebeb0e..a181bbcc3 100644 --- a/src/ir/Program.h +++ b/src/ir/Program.h @@ -58,8 +58,8 @@ public: std::map> booleanUndefinedConstantExpressions, std::map> integerUndefinedConstantExpressions, std::map> doubleUndefinedConstantExpressions, - std::vector> modules, - std::map> rewards, + std::vector modules, + std::map rewards, std::map> labels); /*! @@ -72,7 +72,7 @@ public: * Retrieves a reference to the module with the given index. * @param index the index of the module to retrieve. */ - std::shared_ptr const& getModule(uint_fast64_t index) const; + storm::ir::Module const& getModule(uint_fast64_t index) const; /*! * Retrieves the model type of the model. @@ -98,14 +98,14 @@ public: * @param action Name of the action. * @returns Indices of all matching modules. */ - std::shared_ptr> const getModulesByAction(std::string const& action) const; + std::set const getModulesByAction(std::string const& action) const; /*! * Retrieve reward model with given name. * @param name Name of the reward model. * @return Reward model with given name. */ - std::shared_ptr getRewardModel(std::string const & name) const; + storm::ir::RewardModel getRewardModel(std::string const & name) const; /*! * Retrieves all labels. @@ -127,10 +127,10 @@ private: std::map> doubleUndefinedConstantExpressions; // The modules associated with the program. - std::vector> modules; + std::vector modules; // The reward models associated with the program. - std::map> rewards; + std::map rewards; // The labels that are defined for this model. std::map> labels; @@ -139,7 +139,7 @@ private: std::set actions; // A map of actions to the set of modules containing commands labelled with this action. - std::map>> actionsToModuleIndexMap; + std::map> actionsToModuleIndexMap; }; } // namespace ir diff --git a/src/ir/RewardModel.cpp b/src/ir/RewardModel.cpp index 352c8614c..d6611e4ec 100644 --- a/src/ir/RewardModel.cpp +++ b/src/ir/RewardModel.cpp @@ -19,7 +19,7 @@ RewardModel::RewardModel() : rewardModelName(), stateRewards(), transitionReward } // Initializes all members according to the given values. -RewardModel::RewardModel(std::string rewardModelName, std::vector> stateRewards, std::vector> transitionRewards) : rewardModelName(rewardModelName), stateRewards(stateRewards), transitionRewards(transitionRewards) { +RewardModel::RewardModel(std::string rewardModelName, std::vector stateRewards, std::vector transitionRewards) : rewardModelName(rewardModelName), stateRewards(stateRewards), transitionRewards(transitionRewards) { // Nothing to do here. } @@ -28,10 +28,10 @@ std::string RewardModel::toString() const { std::stringstream result; result << "rewards \"" << rewardModelName << "\"" << std::endl; for (auto reward : stateRewards) { - result << reward->toString() << std::endl; + result << reward.toString() << std::endl; } for (auto reward : transitionRewards) { - result << reward->toString() << std::endl; + result << reward.toString() << std::endl; } result << "endrewards" << std::endl; return result.str(); @@ -41,7 +41,7 @@ bool RewardModel::hasStateRewards() const { return this->stateRewards.size() > 0; } -std::vector> RewardModel::getStateRewards() const { +std::vector RewardModel::getStateRewards() const { return this->stateRewards; } @@ -49,7 +49,7 @@ bool RewardModel::hasTransitionRewards() const { return this->transitionRewards.size() > 0; } -std::vector> RewardModel::getTransitionRewards() const { +std::vector RewardModel::getTransitionRewards() const { return this->transitionRewards; } diff --git a/src/ir/RewardModel.h b/src/ir/RewardModel.h index 29029a4db..cb538f173 100644 --- a/src/ir/RewardModel.h +++ b/src/ir/RewardModel.h @@ -34,7 +34,7 @@ public: * @param stateRewards A vector of state-based reward. * @param transitionRewards A vector of transition-based reward. */ - RewardModel(std::string rewardModelName, std::vector> stateRewards, std::vector> transitionRewards); + RewardModel(std::string rewardModelName, std::vector stateRewards, std::vector transitionRewards); /*! * Retrieves a string representation of this variable. @@ -52,7 +52,7 @@ public: * Retrieve state rewards. * @return State rewards. */ - std::vector> getStateRewards() const; + std::vector getStateRewards() const; /*! * Check, if there are any transition rewards. @@ -64,17 +64,17 @@ public: * Retrieve transition rewards. * @return Transition rewards. */ - std::vector> getTransitionRewards() const; + std::vector getTransitionRewards() const; private: // The name of the reward model. std::string rewardModelName; // The state-based rewards associated with this reward model. - std::vector> stateRewards; + std::vector stateRewards; // The transition-based rewards associated with this reward model. - std::vector> transitionRewards; + std::vector transitionRewards; }; } // namespace ir diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 7340d9d3a..980853300 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -58,32 +58,32 @@ namespace parser { this->state->assignedLocalBooleanVariables_.add(variable, variable); mapping[variable] = Assignment(variable, value); } - std::shared_ptr PrismParser::PrismGrammar::renameModule(const std::string& name, const std::string& oldname, std::map& mapping) { + Module PrismParser::PrismGrammar::renameModule(const std::string& name, const std::string& oldname, std::map& mapping) { this->state->moduleNames_.add(name, name); - std::shared_ptr old = this->state->moduleMap_.at(oldname); + Module* old = this->state->moduleMap_.find(oldname); if (old == nullptr) { std::cerr << "Renaming module failed: module " << oldname << " does not exist!" << std::endl; - return nullptr; + throw "Renaming module failed"; } - std::shared_ptr res = std::shared_ptr(new Module(*old, name, mapping, this->state)); + Module res(*old, name, mapping, this->state); this->state->moduleMap_.add(name, res); return res; } - std::shared_ptr PrismParser::PrismGrammar::createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands) { + Module PrismParser::PrismGrammar::createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands) { this->state->moduleNames_.add(name, name); - std::shared_ptr res = std::shared_ptr(new Module(name, bools, ints, boolids, intids, commands)); + Module res(name, bools, ints, boolids, intids, commands); this->state->moduleMap_.add(name, res); return res; } - std::shared_ptr createStateReward(std::shared_ptr guard, std::shared_ptr reward) { - return std::shared_ptr(new StateReward(guard, reward)); + StateReward createStateReward(std::shared_ptr guard, std::shared_ptr reward) { + return StateReward(guard, reward); } - std::shared_ptr createTransitionReward(std::string label, std::shared_ptr guard, std::shared_ptr reward) { - return std::shared_ptr(new TransitionReward(label, guard, reward)); + TransitionReward createTransitionReward(std::string label, std::shared_ptr guard, std::shared_ptr reward) { + return TransitionReward(label, guard, reward); } - void createRewardModel(std::string name, std::vector>& stateRewards, std::vector>& transitionRewards, std::map>& mapping) { - mapping[name] = std::shared_ptr(new RewardModel(name, stateRewards, transitionRewards)); + void createRewardModel(std::string name, std::vector& stateRewards, std::vector& transitionRewards, std::map& mapping) { + mapping[name] = RewardModel(name, stateRewards, transitionRewards); } Update createUpdate(std::shared_ptr likelihood, std::map& bools, std::map ints) { return Update(likelihood, bools, ints); @@ -91,15 +91,15 @@ namespace parser { Command createCommand(std::string& label, std::shared_ptr guard, std::vector& updates) { return Command(label, guard, updates); } - std::shared_ptr createProgram( + Program createProgram( Program::ModelType modelType, std::map> undefBoolConst, std::map> undefIntConst, std::map> undefDoubleConst, - std::vector> modules, - std::map> rewards, + std::vector modules, + std::map rewards, std::map> labels) { - return std::shared_ptr(new Program(modelType, undefBoolConst, undefIntConst, undefDoubleConst, modules, rewards, labels)); + return Program(modelType, undefBoolConst, undefIntConst, undefDoubleConst, modules, rewards, labels); } PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type(start), state(new storm::parser::prism::VariableState()) { @@ -230,14 +230,14 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type * closes the file properly, even if an exception is thrown in the parser. In this case, the * exception is passed on to the caller. */ -std::shared_ptr PrismParser::parseFile(std::string const& filename) const { +storm::ir::Program PrismParser::parseFile(std::string const& filename) const { // Open file and initialize result. std::ifstream inputFileStream(filename, std::ios::in); - std::shared_ptr result(nullptr); + storm::ir::Program result; // Now try to parse the contents of the file. try { - result = std::shared_ptr(parse(inputFileStream, filename)); + result = parse(inputFileStream, filename); } catch(std::exception& e) { // In case of an exception properly close the file before passing exception. inputFileStream.close(); @@ -254,7 +254,7 @@ std::shared_ptr PrismParser::parseFile(std::string const& fi * If the parser throws an expectation failure exception, i.e. expected input different than the one * provided, this is caught and displayed properly before the exception is passed on. */ -std::shared_ptr PrismParser::parse(std::istream& inputStream, std::string const& filename) const { +storm::ir::Program PrismParser::parse(std::istream& inputStream, std::string const& filename) const { // Prepare iterators to input. // TODO: Right now, this parses the whole contents of the file into a string first. // While this is usually not necessary, because there exist adapters that make an input stream @@ -268,7 +268,7 @@ std::shared_ptr PrismParser::parse(std::istream& inputStream PositionIteratorType positionIteratorEnd; // Prepare resulting intermediate representation of input. - std::shared_ptr result(new storm::ir::Program()); + storm::ir::Program result; // In order to instantiate the grammar, we have to pass the type of the skipping parser. // As this is more complex, we let Boost figure out the actual type for us. @@ -278,11 +278,11 @@ std::shared_ptr PrismParser::parse(std::istream& inputStream // First run. qi::phrase_parse(positionIteratorBegin, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result); grammar.prepareForSecondRun(); - result = std::shared_ptr(new storm::ir::Program()); + result = storm::ir::Program(); std::cout << "Now we start the second run..." << std::endl; // Second run. qi::phrase_parse(positionIteratorBegin2, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result); - std::cout << "Here is the parsed grammar: " << std::endl << result->toString() << std::endl; + std::cout << "Here is the parsed grammar: " << std::endl << result.toString() << std::endl; } catch(const qi::expectation_failure& e) { // If the parser expected content different than the one provided, display information // about the location of the error. diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 0da0e0821..10cdeb895 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -1,5 +1,4 @@ -/* - * PrismParser.h +/* * PrismParser.h * * Created on: Jan 3, 2013 * Author: Christian Dehnert @@ -42,7 +41,7 @@ public: * @param filename the name of the file to parse. * @return a shared pointer to the intermediate representation of the PRISM file. */ - std::shared_ptr parseFile(std::string const& filename) const; + storm::ir::Program parseFile(std::string const& filename) const; /*! * The Boost spirit grammar for the PRISM language. Returns the intermediate representation of @@ -50,11 +49,15 @@ public: */ class PrismGrammar : public qi::grammar< Iterator, - std::shared_ptr(), + Program(), qi::locals< std::map>, std::map>, - std::map>, std::map>, std::map>>, Skipper> { + std::map>, + std::map, + std::map> + >, + Skipper> { public: PrismGrammar(); void prepareForSecondRun(); @@ -66,16 +69,22 @@ public: // The starting point of the grammar. qi::rule< Iterator, - std::shared_ptr(), - qi::locals>, std::map>, std::map>, std::map>, std::map>>, + Program(), + qi::locals< + std::map>, + std::map>, + std::map>, + std::map, + std::map> + >, Skipper> start; qi::rule modelTypeDefinition; qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; - qi::rule>(), Skipper> moduleDefinitionList; + qi::rule(), Skipper> moduleDefinitionList; // Rules for module definition. - qi::rule(), qi::locals, std::vector, std::map, std::map>, Skipper> moduleDefinition; - qi::rule(), qi::locals>, Skipper> moduleRenaming; + qi::rule, std::vector, std::map, std::map>, Skipper> moduleDefinition; + qi::rule>, Skipper> moduleRenaming; // Rules for variable definitions. qi::rule(), Skipper> integerLiteralExpression; @@ -96,10 +105,10 @@ public: qi::rule unassignedLocalIntegerVariableName; // Rules for reward definitions. - qi::rule>&), Skipper> rewardDefinitionList; - qi::rule>&), qi::locals>, std::vector>>, Skipper> rewardDefinition; - qi::rule(), Skipper> stateRewardDefinition; - qi::rule(), qi::locals, Skipper> transitionRewardDefinition; + qi::rule&), Skipper> rewardDefinitionList; + qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; + qi::rule stateRewardDefinition; + qi::rule, Skipper> transitionRewardDefinition; // Rules for label definitions. qi::rule>&), Skipper> labelDefinitionList; @@ -128,8 +137,8 @@ public: void addLabel(const std::string& name, std::shared_ptr value, std::map>& mapping); void addBoolAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); void addIntAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); - std::shared_ptr renameModule(const std::string& name, const std::string& oldname, std::map& mapping); - std::shared_ptr createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands); + Module renameModule(const std::string& name, const std::string& oldname, std::map& mapping); + Module createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands); }; @@ -141,7 +150,7 @@ private: * @param filename the name of the file the input stream belongs to. Used for diagnostics. * @return a shared pointer to the intermediate representation of the PRISM file. */ - std::shared_ptr parse(std::istream& inputStream, std::string const& filename) const; + storm::ir::Program parse(std::istream& inputStream, std::string const& filename) const; }; } // namespace parser diff --git a/src/parser/PrismParser/VariableState.h b/src/parser/PrismParser/VariableState.h index 6b2c9a9b3..58a716fd1 100644 --- a/src/parser/PrismParser/VariableState.h +++ b/src/parser/PrismParser/VariableState.h @@ -38,7 +38,7 @@ public: // the intermediate representation. struct qi::symbols> integerVariables_, booleanVariables_; struct qi::symbols> integerConstants_, booleanConstants_, doubleConstants_; - struct qi::symbols> moduleMap_; + struct qi::symbols moduleMap_; // A structure representing the identity function over identifier names. struct variableNamesStruct : qi::symbols { } integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_, From a9edf2aa8cff8c319e1b643d079b23542e3cde0d Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 23 Apr 2013 18:54:50 +0200 Subject: [PATCH 081/152] Removed some debug output. --- src/ir/IntegerVariable.cpp | 2 +- src/ir/Module.cpp | 5 ----- src/ir/Variable.cpp | 1 - src/ir/expressions/VariableExpression.h | 5 +---- src/parser/PrismParser/VariableState.h | 1 - 5 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/ir/IntegerVariable.cpp b/src/ir/IntegerVariable.cpp index f98ff8861..0e6e2a4fe 100644 --- a/src/ir/IntegerVariable.cpp +++ b/src/ir/IntegerVariable.cpp @@ -46,7 +46,7 @@ std::shared_ptr IntegerVariable::getUppe // Build a string representation of the variable. std::string IntegerVariable::toString() const { std::stringstream result; - result << "int_" << this->getName() << ": [" << lowerBound->toString() << ".." << upperBound->toString() << "]"; + result << this->getName() << ": [" << lowerBound->toString() << ".." << upperBound->toString() << "]"; if (this->getInitialValue() != nullptr) { result << " init " + this->getInitialValue()->toString(); } diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index 6bb8aa1aa..80aa288c3 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -32,16 +32,11 @@ Module::Module(std::string moduleName, : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), booleanVariablesToIndexMap(booleanVariableToIndexMap), integerVariablesToIndexMap(integerVariableToIndexMap), commands(commands), actions(), actionsToCommandIndexMap() { - std::cout << "Created module " << this << ":" << std::endl << this->toString() << std::endl; this->collectActions(); } Module::Module(const Module& module, const std::string& moduleName, const std::map& renaming, std::shared_ptr adder) : moduleName(moduleName) { - std::cout << "Renaming module " << module.moduleName << " to " << moduleName << " with " << renaming.size() << " renamings:" << std::endl; - for (auto it: renaming) { - std::cout << "\t" << it.first << " -> " << it.second << std::endl; - } this->booleanVariables.reserve(module.booleanVariables.size()); for (BooleanVariable it: module.booleanVariables) { if (renaming.count(it.getName()) > 0) { diff --git a/src/ir/Variable.cpp b/src/ir/Variable.cpp index 1d762b4b4..4edc93b2f 100644 --- a/src/ir/Variable.cpp +++ b/src/ir/Variable.cpp @@ -27,7 +27,6 @@ Variable::Variable(uint_fast64_t index, std::string variableName, std::shared_pt Variable::Variable(const Variable& var, const std::string& newName, const std::map& renaming, const std::map& bools, const std::map& ints) : Variable(var.index, newName, var.initialValue->clone(renaming, bools, ints)) { - std::cout << "Cloning Variable " << var.variableName << " to " << newName << std::endl; } // Return the name of the variable. diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index d0fc4cf30..f7811e3e4 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -26,7 +26,6 @@ public: std::shared_ptr upperBound = std::shared_ptr(nullptr)) : BaseExpression(type), index(index), variableName(variableName), lowerBound(lowerBound), upperBound(upperBound) { - std::cerr << "VariableExpression " << this->variableName << std::endl; } virtual ~VariableExpression() { @@ -55,9 +54,7 @@ public: } virtual std::string toString() const { - std::stringstream result; - result << variableName << "(" << this->index << ")"; - return result.str(); + return this->variableName; } virtual std::string dump(std::string prefix) const { diff --git a/src/parser/PrismParser/VariableState.h b/src/parser/PrismParser/VariableState.h index 58a716fd1..e6c99d9ab 100644 --- a/src/parser/PrismParser/VariableState.h +++ b/src/parser/PrismParser/VariableState.h @@ -135,7 +135,6 @@ public: } void prepareForSecondRun() { - std::cerr << "starting second run" << std::endl; integerConstants_.clear(); booleanConstants_.clear(); doubleConstants_.clear(); From dffe274f64427adc081b6085567ea5b629ac584b Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 23 Apr 2013 19:15:09 +0200 Subject: [PATCH 082/152] Fixed error in MDP builder: swapped number of columns and rows. --- src/adapters/ExplicitModelAdapter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index d5f9be117..7b496b66d 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -458,11 +458,11 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { * @return result matrix. */ std::shared_ptr> ExplicitModelAdapter::buildNondeterministicMatrix() { - LOG4CPLUS_DEBUG(logger, "Building nondeterministic transition matrix with " << this->numberOfChoices << " choices and " << this->numberOfTransitions << " transitions now."); - std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size(), this->numberOfChoices)); + LOG4CPLUS_DEBUG(logger, "Building nondeterministic transition matrix: " << this->numberOfChoices << " x " << allStates.size() << " with " << this->numberOfTransitions << " transitions now."); + std::shared_ptr> result(new storm::storage::SparseMatrix(this->numberOfChoices, allStates.size())); result->initialize(this->numberOfTransitions); if ((this->rewardModel != nullptr) && (this->rewardModel->hasTransitionRewards())) { - this->transitionRewards = std::shared_ptr>(new storm::storage::SparseMatrix(allStates.size(), this->numberOfChoices)); + this->transitionRewards = std::shared_ptr>(new storm::storage::SparseMatrix(this->numberOfChoices, allStates.size())); this->transitionRewards->initialize(this->numberOfTransitions); } // Build matrix. From 766a92db3ab372a3c88f7827f4c3f0e6049b514d Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 23 Apr 2013 20:28:31 +0200 Subject: [PATCH 083/152] Fixed error in *Literal::clone() --- src/ir/expressions/BooleanLiteral.h | 2 +- src/ir/expressions/DoubleLiteral.h | 2 +- src/ir/expressions/IntegerLiteral.h | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ir/expressions/BooleanLiteral.h b/src/ir/expressions/BooleanLiteral.h index e2d17fb0f..f6bcd3ab3 100644 --- a/src/ir/expressions/BooleanLiteral.h +++ b/src/ir/expressions/BooleanLiteral.h @@ -27,7 +27,7 @@ public: } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { - return std::shared_ptr(this); + return std::shared_ptr(new BooleanLiteral(this->value)); } virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { diff --git a/src/ir/expressions/DoubleLiteral.h b/src/ir/expressions/DoubleLiteral.h index 20d43d464..4717b6708 100644 --- a/src/ir/expressions/DoubleLiteral.h +++ b/src/ir/expressions/DoubleLiteral.h @@ -31,7 +31,7 @@ public: } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { - return std::shared_ptr(this); + return std::shared_ptr(new DoubleLiteral(this->value)); } virtual double getValueAsDouble(std::pair, std::vector> const* variableValues) const { diff --git a/src/ir/expressions/IntegerLiteral.h b/src/ir/expressions/IntegerLiteral.h index 7ff615ee4..5a42671cd 100644 --- a/src/ir/expressions/IntegerLiteral.h +++ b/src/ir/expressions/IntegerLiteral.h @@ -24,11 +24,10 @@ public: } virtual ~IntegerLiteral() { - } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { - return std::shared_ptr(this); + return std::shared_ptr(new IntegerLiteral(this->value)); } virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { From c1801b4ecc5fb3cb41bac7bb79c30b6c1879380a Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 23 Apr 2013 20:50:45 +0200 Subject: [PATCH 084/152] Changed debug output to use LOG4CPLUS --- src/parser/PrismParser.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 980853300..1df11819e 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -26,6 +26,11 @@ #include #include + +#include "log4cplus/logger.h" +#include "log4cplus/loggingmacros.h" +extern log4cplus::Logger logger; + // Some typedefs and namespace definitions to reduce code size. typedef std::string::const_iterator BaseIteratorType; typedef boost::spirit::classic::position_iterator2 PositionIteratorType; @@ -276,13 +281,14 @@ storm::ir::Program PrismParser::parse(std::istream& inputStream, std::string con try { // Now parse the content using phrase_parse in order to be able to supply a skipping parser. // First run. + LOG4CPLUS_INFO(logger, "Start parsing..."); qi::phrase_parse(positionIteratorBegin, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result); grammar.prepareForSecondRun(); result = storm::ir::Program(); - std::cout << "Now we start the second run..." << std::endl; + LOG4CPLUS_INFO(logger, "Start second parsing run..."); // Second run. qi::phrase_parse(positionIteratorBegin2, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result); - std::cout << "Here is the parsed grammar: " << std::endl << result.toString() << std::endl; + LOG4CPLUS_INFO(logger, "Finished parsing, here is the parsed program:" << std::endl << result.toString()); } catch(const qi::expectation_failure& e) { // If the parser expected content different than the one provided, display information // about the location of the error. From 014ecd85977b3349653826dd28d803af1817652f Mon Sep 17 00:00:00 2001 From: gereon Date: Sun, 28 Apr 2013 16:01:11 +0200 Subject: [PATCH 085/152] Fixed some glitches, producing meaningful error if sum of probabilities for a command is not one --- src/adapters/ExplicitModelAdapter.cpp | 25 +++ src/adapters/ExplicitModelAdapter.h | 2 + src/parser/PrismParser.cpp | 40 +++-- src/parser/PrismParser.h | 153 +++++++++--------- src/parser/PrismParser/BaseGrammar.h | 11 ++ .../PrismParser/BooleanExpressionGrammar.cpp | 11 +- .../PrismParser/BooleanExpressionGrammar.h | 3 +- .../PrismParser/IntegerExpressionGrammar.cpp | 5 + .../PrismParser/IntegerExpressionGrammar.h | 1 + src/parser/PrismParser/VariableState.h | 10 +- 10 files changed, 162 insertions(+), 99 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index 7b496b66d..3a8bc878e 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -28,6 +28,8 @@ ExplicitModelAdapter::ExplicitModelAdapter(storm::ir::Program program) : program booleanVariables(), integerVariables(), booleanVariableToIndexMap(), integerVariableToIndexMap(), allStates(), stateToIndexMap(), numberOfTransitions(0), numberOfChoices(0), transitionRewards(nullptr), transitionMap() { this->initializeVariables(); + storm::settings::Settings* s = storm::settings::instance(); + this->precision = s->get("precision"); } ExplicitModelAdapter::~ExplicitModelAdapter() { @@ -57,6 +59,11 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { case storm::ir::Program::DTMC: { std::shared_ptr> matrix = this->buildDeterministicMatrix(); + std::cerr << "Row 2: "; + for (const double* val = matrix->beginConstIterator(2); val != matrix->endConstIterator(2); val++) { + std::cerr << *val << ", "; + } + std::cerr << std::endl; return std::shared_ptr(new storm::models::Dtmc(matrix, stateLabeling, stateRewards, this->transitionRewards)); break; } @@ -306,6 +313,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { // Add a new map and get pointer. res.emplace_back(); std::map* states = &res.back().second; + double probSum = 0; // Iterate over all updates. for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { @@ -313,6 +321,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { storm::ir::Update const& update = command.getUpdate(k); uint_fast64_t newStateId = this->getOrAddStateId(this->applyUpdate(state, update)); + probSum += update.getLikelihoodExpression()->getValueAsDouble(state); // Check, if we already know this state, add up probabilities for every state. auto stateIt = states->find(newStateId); if (stateIt == states->end()) { @@ -322,6 +331,10 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { (*states)[newStateId] += update.getLikelihoodExpression()->getValueAsDouble(state); } } + if (std::abs(1 - probSum) > this->precision) { + LOG4CPLUS_ERROR(logger, "Sum of update probabilities should be one for command:\n\t" << command.toString()); + throw storm::exceptions::WrongFileFormatException() << "Sum of update probabilities should be one for command:\n\t" << command.toString(); + } } } } @@ -349,6 +362,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { // Iterate over all commands within this module. for (storm::ir::Command command : module) { // Iterate over all updates of this command. + double probSum = 0; for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) { storm::ir::Update const update = command.getUpdate(k); @@ -356,6 +370,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { for (auto it : resultStates) { // Apply the new update and get resulting state. StateType* newState = this->applyUpdate(it.first, update); + probSum += update.getLikelihoodExpression()->getValueAsDouble(it.first); // Insert the new state into newStates array. // Take care of calculation of likelihood, combine identical states. auto s = newStates.find(newState); @@ -366,6 +381,10 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { } } } + if (std::abs(1 - probSum) > this->precision) { + LOG4CPLUS_ERROR(logger, "Sum of update probabilities should be one for command:\n\t" << command.toString()); + throw storm::exceptions::WrongFileFormatException() << "Sum of update probabilities should be one for command:\n\t" << command.toString(); + } } for (auto it: resultStates) { delete it.first; @@ -437,6 +456,12 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { } } } + if (state < 5) { + std::cerr << "From " << state << std::endl; + for (auto it: map) { + std::cerr << "\t" << it.first << ": " << it.second << std::endl; + } + } // Scale probabilities by number of choices. double factor = 1.0 / transitionMap[state].size(); for (auto it : map) { diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index f97f76c5e..272d79c10 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -60,6 +60,8 @@ public: private: + double precision; + // First some generic routines to operate on states. /*! diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 1df11819e..4a9678827 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -56,10 +56,12 @@ namespace parser { mapping[name] = value; } void PrismParser::PrismGrammar::addIntAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping) { + //std::cout << "Adding int assignment for " << variable << std::endl; this->state->assignedLocalIntegerVariables_.add(variable, variable); mapping[variable] = Assignment(variable, value); } void PrismParser::PrismGrammar::addBoolAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping) { + //std::cout << "Adding bool assignment for " << variable << std::endl; this->state->assignedLocalBooleanVariables_.add(variable, variable); mapping[variable] = Assignment(variable, value); } @@ -81,6 +83,21 @@ namespace parser { return res; } + void PrismParser::PrismGrammar::createIntegerVariable(const std::string name, std::shared_ptr lower, std::shared_ptr upper, std::shared_ptr init, std::vector& vars, std::map& varids) { + //std::cout << "Creating int " << name << " = " << init << std::endl; + uint_fast64_t id = this->state->addIntegerVariable(name, lower, upper, init); + vars.emplace_back(id, name, lower, upper, init); + varids[name] = id; + this->state->localIntegerVariables_.add(name, name); + } + void PrismParser::PrismGrammar::createBooleanVariable(const std::string name, std::shared_ptr init, std::vector& vars, std::map& varids) { + //std::cout << "Creating bool " << name << std::endl; + uint_fast64_t id = this->state->addBooleanVariable(name, init); + vars.emplace_back(id, name, init); + varids[name] = id; + this->state->localBooleanVariables_.add(name, name); + } + StateReward createStateReward(std::shared_ptr guard, std::shared_ptr reward) { return StateReward(guard, reward); } @@ -140,7 +157,8 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type assignmentDefinition.name("assignment"); assignmentDefinitionList = assignmentDefinition(qi::_r1, qi::_r2) % "&"; assignmentDefinitionList.name("assignment list"); - updateDefinition = (prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(":")[phoenix::clear(phoenix::ref(this->state->assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(this->state->assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::bind(&createUpdate, qi::_1, qi::_a, qi::_b)]; + updateDefinition = ( + prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(":")[phoenix::clear(phoenix::ref(this->state->assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(this->state->assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::bind(&createUpdate, qi::_1, qi::_a, qi::_b)]; updateDefinition.name("update"); updateListDefinition = +updateDefinition % "+"; updateListDefinition.name("update list"); @@ -154,22 +172,13 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type // This block defines all entities that are needed for parsing variable definitions. booleanVariableDefinition = (prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > prism::ConstBooleanExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) [ - //qi::_a = phoenix::bind(&VariableState::addBooleanVariable, *this->state.get(), qi::_1), - qi::_a = phoenix::bind(&storm::parser::prism::VariableState::addBooleanVariable, *this->state, qi::_1, qi::_b), - phoenix::push_back(qi::_r1, phoenix::construct(qi::_a, phoenix::val(qi::_1), qi::_b)), - phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, qi::_a)), - phoenix::bind(this->state->localBooleanVariables_.add, qi::_1, qi::_1) + phoenix::bind(&PrismParser::PrismGrammar::createBooleanVariable, this, qi::_1, qi::_b, qi::_r1, qi::_r2) ]; booleanVariableDefinition.name("boolean variable declaration"); - integerLiteralExpression = qi::int_[qi::_val = phoenix::construct>(phoenix::new_(qi::_1))]; - integerLiteralExpression.name("integer literal"); - integerVariableDefinition = (prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit(":") >> qi::lit("[") > integerLiteralExpression > qi::lit("..") > integerLiteralExpression > qi::lit("]") > -(qi::lit("init") > prism::ConstIntegerExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) + integerVariableDefinition = (prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit(":") >> qi::lit("[") > prism::ConstIntegerExpressionGrammar::instance(this->state) > qi::lit("..") > prism::ConstIntegerExpressionGrammar::instance(this->state) > qi::lit("]") > -(qi::lit("init") > prism::ConstIntegerExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) [ - qi::_a = phoenix::bind(&storm::parser::prism::VariableState::addIntegerVariable, *this->state, qi::_1, qi::_2, qi::_3, qi::_b), - phoenix::push_back(qi::_r1, phoenix::construct(qi::_a, qi::_1, qi::_2, qi::_3, qi::_b)), - phoenix::insert(qi::_r2, phoenix::construct>(qi::_1, qi::_a)), - phoenix::bind(this->state->localIntegerVariables_.add, qi::_1, qi::_1) + phoenix::bind(&PrismParser::PrismGrammar::createIntegerVariable, this, qi::_1, qi::_2, qi::_3, qi::_b, qi::_r1, qi::_r2) ]; integerVariableDefinition.name("integer variable declaration"); variableDefinition = (booleanVariableDefinition(qi::_r1, qi::_r3) | integerVariableDefinition(qi::_r2, qi::_r4)); @@ -228,6 +237,11 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type void PrismParser::PrismGrammar::prepareForSecondRun() { this->state->prepareForSecondRun(); + prism::BooleanExpressionGrammar::secondRun(); + prism::ConstBooleanExpressionGrammar::secondRun(); + prism::ConstDoubleExpressionGrammar::secondRun(); + prism::ConstIntegerExpressionGrammar::secondRun(); + prism::IntegerExpressionGrammar::secondRun(); } /*! diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 10cdeb895..32a797adf 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -64,82 +64,83 @@ public: private: - std::shared_ptr state; - - // The starting point of the grammar. - qi::rule< - Iterator, - Program(), - qi::locals< - std::map>, - std::map>, - std::map>, - std::map, - std::map> - >, - Skipper> start; - qi::rule modelTypeDefinition; - qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; - qi::rule(), Skipper> moduleDefinitionList; - - // Rules for module definition. - qi::rule, std::vector, std::map, std::map>, Skipper> moduleDefinition; - qi::rule>, Skipper> moduleRenaming; - - // Rules for variable definitions. - qi::rule(), Skipper> integerLiteralExpression; - qi::rule&, std::vector&, std::map&, std::map&), Skipper> variableDefinition; - qi::rule&, std::map&), qi::locals>, Skipper> booleanVariableDefinition; - qi::rule&, std::map&), qi::locals>, Skipper> integerVariableDefinition; - - // Rules for command definitions. - qi::rule, Skipper> commandDefinition; - qi::rule(), Skipper> updateListDefinition; - qi::rule, std::map>, Skipper> updateDefinition; - qi::rule&, std::map&), Skipper> assignmentDefinitionList; - qi::rule&, std::map&), Skipper> assignmentDefinition; - - // Rules for variable/command names. - qi::rule commandName; - qi::rule unassignedLocalBooleanVariableName; - qi::rule unassignedLocalIntegerVariableName; - - // Rules for reward definitions. - qi::rule&), Skipper> rewardDefinitionList; - qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; - qi::rule stateRewardDefinition; - qi::rule, Skipper> transitionRewardDefinition; - - // Rules for label definitions. - qi::rule>&), Skipper> labelDefinitionList; - qi::rule>&), Skipper> labelDefinition; - - // Rules for constant definitions. - qi::rule(), Skipper> constantDefinition; - qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; - qi::rule(), Skipper> definedConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedBooleanConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedIntegerConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedDoubleConstantDefinition; - qi::rule(), Skipper> definedBooleanConstantDefinition; - qi::rule(), Skipper> definedIntegerConstantDefinition; - qi::rule(), Skipper> definedDoubleConstantDefinition; - - // Rules for variable recognition. - qi::rule(), Skipper> booleanVariableCreatorExpression; - qi::rule(), qi::locals>, Skipper> integerVariableCreatorExpression; - - storm::parser::prism::keywordsStruct keywords_; - storm::parser::prism::modelTypeStruct modelType_; - storm::parser::prism::relationalOperatorStruct relations_; - - std::shared_ptr addIntegerConstant(const std::string& name, const std::shared_ptr value); - void addLabel(const std::string& name, std::shared_ptr value, std::map>& mapping); - void addBoolAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); - void addIntAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); - Module renameModule(const std::string& name, const std::string& oldname, std::map& mapping); - Module createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands); - + std::shared_ptr state; + + // The starting point of the grammar. + qi::rule< + Iterator, + Program(), + qi::locals< + std::map>, + std::map>, + std::map>, + std::map, + std::map> + >, + Skipper> start; + qi::rule modelTypeDefinition; + qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; + qi::rule(), Skipper> moduleDefinitionList; + + // Rules for module definition. + qi::rule, std::vector, std::map, std::map>, Skipper> moduleDefinition; + qi::rule>, Skipper> moduleRenaming; + + // Rules for variable definitions. + qi::rule&, std::vector&, std::map&, std::map&), Skipper> variableDefinition; + qi::rule&, std::map&), qi::locals>, Skipper> booleanVariableDefinition; + qi::rule&, std::map&), qi::locals>, Skipper> integerVariableDefinition; + + // Rules for command definitions. + qi::rule, Skipper> commandDefinition; + qi::rule(), Skipper> updateListDefinition; + qi::rule, std::map>, Skipper> updateDefinition; + qi::rule&, std::map&), Skipper> assignmentDefinitionList; + qi::rule&, std::map&), Skipper> assignmentDefinition; + + // Rules for variable/command names. + qi::rule commandName; + qi::rule unassignedLocalBooleanVariableName; + qi::rule unassignedLocalIntegerVariableName; + + // Rules for reward definitions. + qi::rule&), Skipper> rewardDefinitionList; + qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; + qi::rule stateRewardDefinition; + qi::rule, Skipper> transitionRewardDefinition; + + // Rules for label definitions. + qi::rule>&), Skipper> labelDefinitionList; + qi::rule>&), Skipper> labelDefinition; + + // Rules for constant definitions. + qi::rule(), Skipper> constantDefinition; + qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; + qi::rule(), Skipper> definedConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedBooleanConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedIntegerConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedDoubleConstantDefinition; + qi::rule(), Skipper> definedBooleanConstantDefinition; + qi::rule(), Skipper> definedIntegerConstantDefinition; + qi::rule(), Skipper> definedDoubleConstantDefinition; + + // Rules for variable recognition. + qi::rule(), Skipper> booleanVariableCreatorExpression; + qi::rule(), qi::locals>, Skipper> integerVariableCreatorExpression; + + storm::parser::prism::keywordsStruct keywords_; + storm::parser::prism::modelTypeStruct modelType_; + storm::parser::prism::relationalOperatorStruct relations_; + + std::shared_ptr addIntegerConstant(const std::string& name, const std::shared_ptr value); + void addLabel(const std::string& name, std::shared_ptr value, std::map>& mapping); + void addBoolAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); + void addIntAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); + Module renameModule(const std::string& name, const std::string& oldname, std::map& mapping); + Module createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands); + + void createIntegerVariable(const std::string name, std::shared_ptr lower, std::shared_ptr upper, std::shared_ptr init, std::vector& vars, std::map& varids); + void createBooleanVariable(const std::string name, std::shared_ptr init, std::vector& vars, std::map& varids); }; private: diff --git a/src/parser/PrismParser/BaseGrammar.h b/src/parser/PrismParser/BaseGrammar.h index bcc5f3d44..0846eb12c 100644 --- a/src/parser/PrismParser/BaseGrammar.h +++ b/src/parser/PrismParser/BaseGrammar.h @@ -24,10 +24,18 @@ namespace prism { static T& instance(std::shared_ptr& state = nullptr) { if (BaseGrammar::instanceObject == nullptr) { BaseGrammar::instanceObject = std::shared_ptr(new T(state)); + if (!state->firstRun) BaseGrammar::instanceObject->secondRun(); } return *BaseGrammar::instanceObject; } + static void secondRun() { + if (BaseGrammar::instanceObject != nullptr) { + BaseGrammar::instanceObject->prepareSecondRun(); + } + + } + std::shared_ptr createBoolLiteral(const bool value) { return std::shared_ptr(new BooleanLiteral(value)); } @@ -70,6 +78,7 @@ namespace prism { return std::shared_ptr(new UnaryBooleanFunctionExpression(child, UnaryBooleanFunctionExpression::NOT)); } std::shared_ptr createAnd(std::shared_ptr left, std::shared_ptr right) { + //std::cerr << "Creating " << left->toString() << " & " << right->toString() << std::endl; return std::shared_ptr(new BinaryBooleanFunctionExpression(left, right, BinaryBooleanFunctionExpression::AND)); } std::shared_ptr createOr(std::shared_ptr left, std::shared_ptr right) { @@ -82,11 +91,13 @@ namespace prism { return state->getIntegerVariable(name); } + virtual void prepareSecondRun() {} protected: std::shared_ptr state; private: static std::shared_ptr instanceObject; + static bool inSecondRun; }; template diff --git a/src/parser/PrismParser/BooleanExpressionGrammar.cpp b/src/parser/PrismParser/BooleanExpressionGrammar.cpp index 101db9cce..00ca2fe40 100644 --- a/src/parser/PrismParser/BooleanExpressionGrammar.cpp +++ b/src/parser/PrismParser/BooleanExpressionGrammar.cpp @@ -7,10 +7,10 @@ namespace storm { namespace parser { namespace prism { -BooleanExpressionGrammar::BooleanExpressionGrammar(std::shared_ptr& state) - : BooleanExpressionGrammar::base_type(booleanExpression), BaseGrammar(state) { + BooleanExpressionGrammar::BooleanExpressionGrammar(std::shared_ptr& state) + : BooleanExpressionGrammar::base_type(booleanExpression), BaseGrammar(state) { - booleanExpression %= orExpression; + booleanExpression %= orExpression; booleanExpression.name("boolean expression"); orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::bind(&BaseGrammar::createOr, this, qi::_val, qi::_1)]; @@ -32,6 +32,11 @@ BooleanExpressionGrammar::BooleanExpressionGrammar(std::shared_ptrstate->booleanVariables_; + booleanVariableExpression.name("boolean variable"); + } + } } } \ No newline at end of file diff --git a/src/parser/PrismParser/BooleanExpressionGrammar.h b/src/parser/PrismParser/BooleanExpressionGrammar.h index 9d14c5ec3..9e976e64d 100644 --- a/src/parser/PrismParser/BooleanExpressionGrammar.h +++ b/src/parser/PrismParser/BooleanExpressionGrammar.h @@ -22,7 +22,8 @@ namespace prism { class BooleanExpressionGrammar : public qi::grammar(), Skipper, Unused>, public BaseGrammar { public: BooleanExpressionGrammar(std::shared_ptr& state); - + virtual void prepareSecondRun(); + private: qi::rule(), Skipper, Unused> booleanExpression; qi::rule(), Skipper> orExpression; diff --git a/src/parser/PrismParser/IntegerExpressionGrammar.cpp b/src/parser/PrismParser/IntegerExpressionGrammar.cpp index 89933aeb3..e0e363030 100644 --- a/src/parser/PrismParser/IntegerExpressionGrammar.cpp +++ b/src/parser/PrismParser/IntegerExpressionGrammar.cpp @@ -26,6 +26,11 @@ namespace prism { integerVariableExpression.name("integer variable"); } + void IntegerExpressionGrammar::prepareSecondRun() { + integerVariableExpression = this->state->integerVariables_; + integerVariableExpression.name("integer variable"); + } + } } } \ No newline at end of file diff --git a/src/parser/PrismParser/IntegerExpressionGrammar.h b/src/parser/PrismParser/IntegerExpressionGrammar.h index 5c253e437..0f44b0d01 100644 --- a/src/parser/PrismParser/IntegerExpressionGrammar.h +++ b/src/parser/PrismParser/IntegerExpressionGrammar.h @@ -22,6 +22,7 @@ namespace prism { class IntegerExpressionGrammar : public qi::grammar(), Skipper, Unused>, public BaseGrammar { public: IntegerExpressionGrammar(std::shared_ptr& state); + virtual void prepareSecondRun(); private: qi::rule(), Skipper, Unused> integerExpression; diff --git a/src/parser/PrismParser/VariableState.h b/src/parser/PrismParser/VariableState.h index e6c99d9ab..e94d44056 100644 --- a/src/parser/PrismParser/VariableState.h +++ b/src/parser/PrismParser/VariableState.h @@ -45,13 +45,12 @@ public: localBooleanVariables_, localIntegerVariables_, assignedLocalBooleanVariables_, assignedLocalIntegerVariables_; uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init) { - //std::cerr << "adding boolean variable " << name << std::endl; if (firstRun) { std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::bool_, this->nextBooleanVariableIndex, name)); this->booleanVariables_.add(name, varExpr); this->booleanVariableNames_.add(name, name); this->nextBooleanVariableIndex++; - return this->nextBooleanVariableIndex-1; + return varExpr->getVariableIndex(); } else { std::shared_ptr res = this->booleanVariables_.at(name); if (res != nullptr) { @@ -70,7 +69,7 @@ public: this->integerVariables_.add(name, varExpr); this->integerVariableNames_.add(name, name); this->nextIntegerVariableIndex++; - return this->nextIntegerVariableIndex-1; + return varExpr->getVariableIndex(); } else { std::shared_ptr res = this->integerVariables_.at(name); if (res != nullptr) { @@ -83,7 +82,6 @@ public: } std::shared_ptr getBooleanVariable(const std::string& name) { - //std::cerr << "getting boolen variable " << name << std::endl; std::shared_ptr res = this->booleanVariables_.at(name); if (res != nullptr) { return res; @@ -91,7 +89,7 @@ public: if (firstRun) { return std::shared_ptr(new VariableExpression(BaseExpression::bool_, std::numeric_limits::max(), "bool", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); } else { - std::cerr << "Variable " << name << " was not created in first run" << std::endl; + std::cerr << "bool Variable " << name << " was not created in first run" << std::endl; return std::shared_ptr(nullptr); } } @@ -106,7 +104,7 @@ public: if (firstRun) { return std::shared_ptr(new VariableExpression(BaseExpression::int_, std::numeric_limits::max(), "int", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); } else { - std::cerr << "Variable " << name << " was not created in first run" << std::endl; + std::cerr << "int Variable " << name << " was not created in first run" << std::endl; return std::shared_ptr(nullptr); } } From ac313cb997b995ab796f0987a62c7353e0c2e6f6 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 30 Apr 2013 10:14:10 +0200 Subject: [PATCH 086/152] Removed debug output, fixed DoubleExpressionGrammar --- src/adapters/ExplicitModelAdapter.cpp | 11 ----------- .../expressions/BinaryNumericalFunctionExpression.h | 1 - .../PrismParser/ConstDoubleExpressionGrammar.cpp | 4 ++-- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index 3a8bc878e..be8a24e3e 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -59,11 +59,6 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { case storm::ir::Program::DTMC: { std::shared_ptr> matrix = this->buildDeterministicMatrix(); - std::cerr << "Row 2: "; - for (const double* val = matrix->beginConstIterator(2); val != matrix->endConstIterator(2); val++) { - std::cerr << *val << ", "; - } - std::cerr << std::endl; return std::shared_ptr(new storm::models::Dtmc(matrix, stateLabeling, stateRewards, this->transitionRewards)); break; } @@ -456,12 +451,6 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { } } } - if (state < 5) { - std::cerr << "From " << state << std::endl; - for (auto it: map) { - std::cerr << "\t" << it.first << ": " << it.second << std::endl; - } - } // Scale probabilities by number of choices. double factor = 1.0 / transitionMap[state].size(); for (auto it : map) { diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h index 151c10062..54239c46a 100644 --- a/src/ir/expressions/BinaryNumericalFunctionExpression.h +++ b/src/ir/expressions/BinaryNumericalFunctionExpression.h @@ -83,7 +83,6 @@ public: case DIVIDE: result += " / "; break; } result += this->getRight()->toString(); - return result; } diff --git a/src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp b/src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp index e569d329c..82798fe3d 100644 --- a/src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp +++ b/src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp @@ -30,11 +30,11 @@ ConstDoubleExpressionGrammar::ConstDoubleExpressionGrammar(std::shared_ptr> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantDoubleMultExpression) - [phoenix::bind(&ConstDoubleExpressionGrammar::createPlus, this, qi::_val, qi::_a, qi::_1)]; + [qi::_val = phoenix::bind(&ConstDoubleExpressionGrammar::createPlus, this, qi::_val, qi::_a, qi::_1)]; constantDoublePlusExpression.name("constant double expression"); constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> constantAtomicDoubleExpression) - [phoenix::bind(&ConstDoubleExpressionGrammar::createMult, this, qi::_val, qi::_a, qi::_1)]; + [qi::_val = phoenix::bind(&ConstDoubleExpressionGrammar::createMult, this, qi::_val, qi::_a, qi::_1)]; constantDoubleMultExpression.name("constant double expression"); constantAtomicDoubleExpression %= (qi::lit("(") >> constantDoubleExpression >> qi::lit(")") | doubleConstantExpression); From f09be5c3b4909b774a1cd2a318a0e1a37ca83fc3 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 30 Apr 2013 10:35:35 +0200 Subject: [PATCH 087/152] Made BaseGrammar constructor clang-compatible, fixed ms output of CPU usage --- src/parser/PrismParser/BaseGrammar.h | 2 +- src/storm.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/parser/PrismParser/BaseGrammar.h b/src/parser/PrismParser/BaseGrammar.h index 0846eb12c..4bf4f3265 100644 --- a/src/parser/PrismParser/BaseGrammar.h +++ b/src/parser/PrismParser/BaseGrammar.h @@ -21,7 +21,7 @@ namespace prism { public: BaseGrammar(std::shared_ptr& state) : state(state) {} - static T& instance(std::shared_ptr& state = nullptr) { + static T& instance(std::shared_ptr state = nullptr) { if (BaseGrammar::instanceObject == nullptr) { BaseGrammar::instanceObject = std::shared_ptr(new T(state)); if (!state->firstRun) BaseGrammar::instanceObject->secondRun(); diff --git a/src/storm.cpp b/src/storm.cpp index bcdf399d7..b01d21951 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -44,12 +44,14 @@ #include #include #include +#include void printUsage() { struct rusage ru; getrusage(RUSAGE_SELF, &ru); std::cout << "Memory Usage: " << ru.ru_maxrss << "kB" << std::endl; + std::cout << "CPU time: " << ru.ru_utime.tv_sec << "." << std::setw(3) << std::setfill('0') << ru.ru_utime.tv_usec/1000 << " seconds" << std::endl; } From 1642c5f66c302d07a74c583597191005ce032d90 Mon Sep 17 00:00:00 2001 From: david Date: Tue, 30 Apr 2013 10:50:40 +0200 Subject: [PATCH 088/152] Added missing functions to CUDDs cpp interface --- CMakeLists.txt | 10 ++-- resources/3rdparty/cudd-2.5.0/cudd/cudd.h | 6 ++ resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc | 60 ++++++++++++++++++++ resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh | 6 ++ 4 files changed, 77 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bed5cc152..ba522f0e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,9 +45,9 @@ set(GMMXX_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/resources/3rdparty/gmm-4.2/include) message(STATUS "GMMXX_INCLUDE_DIR is ${GMMXX_INCLUDE_DIR}") # Set all CUDD references to the version in the repository -set(CUDD_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/include) +set(CUDD_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/include ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/obj ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/cudd ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/mtr ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/epd) set(CUDD_LIBRARY_DIRS ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/cudd ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/mtr ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/util ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/st ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/epd ${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/obj) -message(STATUS "CUDD_INCLUDE_DIR is ${CUDD_INCLUDE_DIR}") +message(STATUS "CUDD_INCLUDE_DIRS is ${CUDD_INCLUDE_DIRS}") message(STATUS "CUDD_LIBRARY_DIRS is ${CUDD_LIBRARY_DIRS}") # Now define all available custom options @@ -165,9 +165,9 @@ if (ADDITIONAL_LINK_DIRS) link_directories(${ADDITIONAL_LINK_DIRS}) endif(ADDITIONAL_LINK_DIRS) -if (CUDD_INCLUDE_DIR) - include_directories(${CUDD_INCLUDE_DIR}) -endif(CUDD_INCLUDE_DIR) +if (CUDD_INCLUDE_DIRS) + include_directories(${CUDD_INCLUDE_DIRS}) +endif(CUDD_INCLUDE_DIRS) if (CUDD_LIBRARY_DIRS) link_directories(${CUDD_LIBRARY_DIRS}) endif(CUDD_LIBRARY_DIRS) diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cudd.h b/resources/3rdparty/cudd-2.5.0/cudd/cudd.h index 2493cbae0..d60d0c8f8 100644 --- a/resources/3rdparty/cudd-2.5.0/cudd/cudd.h +++ b/resources/3rdparty/cudd-2.5.0/cudd/cudd.h @@ -784,6 +784,12 @@ extern DdNode * Cudd_addNand (DdManager *dd, DdNode **f, DdNode **g); extern DdNode * Cudd_addNor (DdManager *dd, DdNode **f, DdNode **g); extern DdNode * Cudd_addXor (DdManager *dd, DdNode **f, DdNode **g); extern DdNode * Cudd_addXnor (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addNotEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addGreaterThan (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addGreaterThanEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addLessThan (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addLessThanEquals (DdManager *dd, DdNode **f, DdNode **g); extern DdNode * Cudd_addMonadicApply (DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f); extern DdNode * Cudd_addLog (DdManager * dd, DdNode * f); extern DdNode * Cudd_addEquals (DdManager *dd, DdNode **f, DdNode **g); diff --git a/resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc b/resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc index 8722ca82f..b8a7f2179 100644 --- a/resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc +++ b/resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc @@ -2773,6 +2773,66 @@ Cudd::addResidue( } // Cudd::addResidue +ADD +ADD::Equals(const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addEquals, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Equals + +ADD +ADD::NotEquals(const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addNotEquals, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::NotEquals + +ADD +ADD::LessThan(const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addLessThan, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::LessThan + +ADD +ADD::LessThanOrEqual(const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addLessThanEquals, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::LessThanOrEqual + +ADD +ADD::GreaterThan(const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addGreaterThan, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::GreaterThan + +ADD +ADD::GreaterThanOrEqual(const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addGreaterThanEquals, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::GreaterThanOrEqual + BDD BDD::AndAbstract( diff --git a/resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh b/resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh index 83a0a924a..726476448 100644 --- a/resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh +++ b/resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh @@ -401,6 +401,12 @@ public: ADD Cmpl() const; ADD Negate() const; ADD RoundOff(int N) const; + ADD Equals(const ADD& g) const; + ADD NotEquals(const ADD& g) const; + ADD LessThan(const ADD& g) const; + ADD LessThanOrEqual(const ADD& g) const; + ADD GreaterThan(const ADD& g) const; + ADD GreaterThanOrEqual(const ADD& g) const; BDD BddThreshold(CUDD_VALUE_TYPE value) const; BDD BddStrictThreshold(CUDD_VALUE_TYPE value) const; BDD BddInterval(CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper) const; From 12745d466e2c2c9bdba67f5bb71010fb9323eee1 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 30 Apr 2013 10:53:08 +0200 Subject: [PATCH 089/152] Fixing main, removing shared_ptr --- src/storm.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/storm.cpp b/src/storm.cpp index b01d21951..4cc2f5e41 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -254,7 +254,8 @@ int main(const int argc, const char* argv[]) { // testChecking(); storm::settings::Settings* s = storm::settings::instance(); storm::parser::PrismParser parser; - std::shared_ptr program = parser.parseFile(s->getString("trafile")); + std::cout << "Building model for " << s->getString("trafile") << std::endl; + storm::ir::Program program = parser.parseFile(s->getString("trafile")); storm::adapters::ExplicitModelAdapter explicitModelAdapter(program); std::shared_ptr model = explicitModelAdapter.getModel(); if (model->getType() == storm::models::DTMC) { From 4c0d7f6d95429dfa97e90d424776f24857fd320f Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 30 Apr 2013 11:09:00 +0200 Subject: [PATCH 090/152] adding cudd linker options for storm-tests --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ba522f0e6..6eaa1c632 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -225,6 +225,7 @@ endif(LOG4CPLUS_INCLUDE_DIR) if (CUDD_LIBRARY_DIRS) target_link_libraries(storm "-lobj -lcudd -lmtr -lst -lutil -lepd") + target_link_libraries(storm-tests "-lobj -lcudd -lmtr -lst -lutil -lepd") endif(CUDD_LIBRARY_DIRS) if (THREADS_FOUND) From 7fe4c8c813c9771c2b0ed46942e5c633fff8744c Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 30 Apr 2013 11:12:37 +0200 Subject: [PATCH 091/152] fixing signed/unsigned comparisons in ParseMdpTest --- test/parser/ParseMdpTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/parser/ParseMdpTest.cpp b/test/parser/ParseMdpTest.cpp index 4147c0122..4d77d7e54 100644 --- a/test/parser/ParseMdpTest.cpp +++ b/test/parser/ParseMdpTest.cpp @@ -20,10 +20,10 @@ TEST(ParseMdpTest, parseAndOutput) { std::shared_ptr> mdp = mdpParser->getMdp(); std::shared_ptr> matrix = mdp->getTransitionProbabilityMatrix(); - ASSERT_EQ(mdp->getNumberOfStates(), 3); - ASSERT_EQ(mdp->getNumberOfTransitions(), 11); - ASSERT_EQ(matrix->getRowCount(), 2 * 3); - ASSERT_EQ(matrix->getColumnCount(), 3); + ASSERT_EQ(mdp->getNumberOfStates(), (uint_fast64_t)3); + ASSERT_EQ(mdp->getNumberOfTransitions(), (uint_fast64_t)11); + ASSERT_EQ(matrix->getRowCount(), (uint_fast64_t)(2 * 3)); + ASSERT_EQ(matrix->getColumnCount(), (uint_fast64_t)3); delete mdpParser; From 63e9ad1f0ae695b1dc0d13c5ed51bc3a406b6fb0 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 30 Apr 2013 15:04:39 +0200 Subject: [PATCH 092/152] Adding test for prism parser --- test/parser/ParsePrismTest.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 test/parser/ParsePrismTest.cpp diff --git a/test/parser/ParsePrismTest.cpp b/test/parser/ParsePrismTest.cpp new file mode 100644 index 000000000..4f59be220 --- /dev/null +++ b/test/parser/ParsePrismTest.cpp @@ -0,0 +1,20 @@ +#include "gtest/gtest.h" +#include "storm-config.h" +#include "src/parser/PrismParser.h" +#include "src/utility/IoUtility.h" +#include "src/ir/Program.h" +#include "src/adapters/ExplicitModelAdapter.h" + +TEST(ParsePrismTest, parseAndOutput) { + storm::parser::PrismParser parser; + storm::ir::Program program; + ASSERT_NO_THROW(program = parser.parseFile("examples/dtmc/crowds/crowds5_5.pm")); + storm::adapters::ExplicitModelAdapter adapter(program); + + std::shared_ptr> model = adapter.getModel()->as>(); + + ASSERT_EQ(model->getNumberOfStates(), (uint_fast64_t)8607); + ASSERT_EQ(model->getNumberOfTransitions(), (uint_fast64_t)15113); +} + + From c3cfc5404c9ac090caa20e939bdcc09149a3284f Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 30 Apr 2013 15:05:42 +0200 Subject: [PATCH 093/152] Somewhat fixed weird issue during module renaming. The "fix" is very weird (see VariableState.cpp:55 and following) and still seems to lead to a segfault upon program termination... --- src/ir/Module.cpp | 15 +- src/ir/expressions/BinaryExpression.h | 7 +- src/ir/expressions/VariableExpression.h | 2 + src/parser/PrismParser.cpp | 12 +- .../PrismParser/BooleanExpressionGrammar.cpp | 2 +- src/parser/PrismParser/Includes.h | 4 + .../PrismParser/IntegerExpressionGrammar.cpp | 2 +- src/parser/PrismParser/VariableState.cpp | 135 ++++++++++++++++++ src/parser/PrismParser/VariableState.h | 117 +++------------ 9 files changed, 189 insertions(+), 107 deletions(-) create mode 100644 src/parser/PrismParser/VariableState.cpp diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index 80aa288c3..40d40fb2f 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -12,6 +12,10 @@ #include #include +#include "log4cplus/logger.h" +#include "log4cplus/loggingmacros.h" +extern log4cplus::Logger logger; + namespace storm { namespace ir { @@ -37,29 +41,30 @@ Module::Module(std::string moduleName, Module::Module(const Module& module, const std::string& moduleName, const std::map& renaming, std::shared_ptr adder) : moduleName(moduleName) { + LOG4CPLUS_DEBUG(logger, "Start renaming " << module.moduleName << " to " << moduleName); this->booleanVariables.reserve(module.booleanVariables.size()); for (BooleanVariable it: module.booleanVariables) { if (renaming.count(it.getName()) > 0) { this->booleanVariablesToIndexMap[renaming.at(it.getName())] = adder->addBooleanVariable(renaming.at(it.getName()), it.getInitialValue()); - } else std::cerr << "ERROR: " << moduleName << "." << it.getName() << " was not renamed!" << std::endl; + } else LOG4CPLUS_ERROR(logger, moduleName << "." << it.getName() << " was not renamed!"); } this->integerVariables.reserve(module.integerVariables.size()); for (IntegerVariable it: module.integerVariables) { if (renaming.count(it.getName()) > 0) { this->integerVariablesToIndexMap[renaming.at(it.getName())] = adder->addIntegerVariable(renaming.at(it.getName()), it.getLowerBound(), it.getUpperBound(), it.getInitialValue()); - } else std::cerr << "ERROR: " << moduleName << "." << it.getName() << " was not renamed!" << std::endl; + } else LOG4CPLUS_ERROR(logger, moduleName << "." << it.getName() << " was not renamed!"); } this->booleanVariables.reserve(module.booleanVariables.size()); for (BooleanVariable it: module.booleanVariables) { if (renaming.count(it.getName()) > 0) { this->booleanVariables.emplace_back(it, renaming.at(it.getName()), renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap); - } else std::cerr << "ERROR: " << moduleName << "." << it.getName() << " was not renamed!" << std::endl; + } else LOG4CPLUS_ERROR(logger, moduleName << "." << it.getName() << " was not renamed!"); } this->integerVariables.reserve(module.integerVariables.size()); for (IntegerVariable it: module.integerVariables) { if (renaming.count(it.getName()) > 0) { this->integerVariables.emplace_back(it, renaming.at(it.getName()), renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap); - } else std::cerr << "ERROR: " << moduleName << "." << it.getName() << " was not renamed!" << std::endl; + } else LOG4CPLUS_ERROR(logger, moduleName << "." << it.getName() << " was not renamed!"); } this->commands.reserve(module.commands.size()); @@ -67,6 +72,8 @@ Module::Module(const Module& module, const std::string& moduleName, const std::m this->commands.emplace_back(cmd, renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap); } this->collectActions(); + + LOG4CPLUS_DEBUG(logger, "Finished renaming..."); } // Return the number of boolean variables. diff --git a/src/ir/expressions/BinaryExpression.h b/src/ir/expressions/BinaryExpression.h index de0b1d8ab..3897c0cc6 100644 --- a/src/ir/expressions/BinaryExpression.h +++ b/src/ir/expressions/BinaryExpression.h @@ -10,6 +10,7 @@ #include "src/ir/expressions/BaseExpression.h" #include +#include namespace storm { @@ -21,7 +22,11 @@ class BinaryExpression : public BaseExpression { public: BinaryExpression(ReturnType type, std::shared_ptr left, std::shared_ptr right) : BaseExpression(type), left(left), right(right) { - + if (left == nullptr || right == nullptr) { + std::cerr << "BinaryExpression" << std::endl; + if (left != nullptr) std::cerr << "\tleft: " << left->toString() << std::endl; + if (right != nullptr) std::cerr << "\tright: " << right->toString() << std::endl; + } } std::shared_ptr const& getLeft() const { diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index f7811e3e4..e14e33d7e 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -26,9 +26,11 @@ public: std::shared_ptr upperBound = std::shared_ptr(nullptr)) : BaseExpression(type), index(index), variableName(variableName), lowerBound(lowerBound), upperBound(upperBound) { + std::cerr << "Creating " << this << std::endl; } virtual ~VariableExpression() { + std::cerr << "Destroying " << this << std::endl; } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 4a9678827..08f534691 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -26,7 +26,6 @@ #include #include - #include "log4cplus/logger.h" #include "log4cplus/loggingmacros.h" extern log4cplus::Logger logger; @@ -69,7 +68,7 @@ namespace parser { this->state->moduleNames_.add(name, name); Module* old = this->state->moduleMap_.find(oldname); if (old == nullptr) { - std::cerr << "Renaming module failed: module " << oldname << " does not exist!" << std::endl; + LOG4CPLUS_ERROR(logger, "Renaming module failed: module " << oldname << " does not exist!"); throw "Renaming module failed"; } Module res(*old, name, mapping, this->state); @@ -236,7 +235,16 @@ PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type } void PrismParser::PrismGrammar::prepareForSecondRun() { + LOG4CPLUS_INFO(logger, "Preparing parser for second run."); + this->state->getIntegerVariable("d1"); + this->state->getIntegerVariable("d2"); + this->state->getIntegerVariable("s1"); + this->state->getIntegerVariable("s2"); this->state->prepareForSecondRun(); + this->state->getIntegerVariable("d1"); + this->state->getIntegerVariable("d2"); + this->state->getIntegerVariable("s1"); + this->state->getIntegerVariable("s2"); prism::BooleanExpressionGrammar::secondRun(); prism::ConstBooleanExpressionGrammar::secondRun(); prism::ConstDoubleExpressionGrammar::secondRun(); diff --git a/src/parser/PrismParser/BooleanExpressionGrammar.cpp b/src/parser/PrismParser/BooleanExpressionGrammar.cpp index 00ca2fe40..6a2d421bb 100644 --- a/src/parser/PrismParser/BooleanExpressionGrammar.cpp +++ b/src/parser/PrismParser/BooleanExpressionGrammar.cpp @@ -33,7 +33,7 @@ namespace prism { } void BooleanExpressionGrammar::prepareSecondRun() { - booleanVariableExpression = this->state->booleanVariables_; + booleanVariableExpression %= this->state->booleanVariables_; booleanVariableExpression.name("boolean variable"); } diff --git a/src/parser/PrismParser/Includes.h b/src/parser/PrismParser/Includes.h index fe3418b2c..3bce26d00 100644 --- a/src/parser/PrismParser/Includes.h +++ b/src/parser/PrismParser/Includes.h @@ -33,5 +33,9 @@ typedef boost::spirit::unused_type Unused; using namespace storm::ir; using namespace storm::ir::expressions; +#include "log4cplus/logger.h" +#include "log4cplus/loggingmacros.h" +extern log4cplus::Logger logger; + #endif /* BOOSTINCLUDES_H */ diff --git a/src/parser/PrismParser/IntegerExpressionGrammar.cpp b/src/parser/PrismParser/IntegerExpressionGrammar.cpp index e0e363030..ba1a35eb6 100644 --- a/src/parser/PrismParser/IntegerExpressionGrammar.cpp +++ b/src/parser/PrismParser/IntegerExpressionGrammar.cpp @@ -27,7 +27,7 @@ namespace prism { } void IntegerExpressionGrammar::prepareSecondRun() { - integerVariableExpression = this->state->integerVariables_; + integerVariableExpression %= this->state->integerVariables_; integerVariableExpression.name("integer variable"); } diff --git a/src/parser/PrismParser/VariableState.cpp b/src/parser/PrismParser/VariableState.cpp new file mode 100644 index 000000000..91d41be77 --- /dev/null +++ b/src/parser/PrismParser/VariableState.cpp @@ -0,0 +1,135 @@ +#include "VariableState.h" + +namespace storm { +namespace parser { +namespace prism { + +using namespace storm::ir; +using namespace storm::ir::expressions; + +template +struct SymbolDump { + SymbolDump(std::ostream& out) : out(out) {} + void operator() (std::basic_string s, T elem) { + this->out << "\t" << s << " -> " << elem << std::endl; + } +private: + std::ostream& out; +}; +template +std::ostream& operator<<(std::ostream& out, qi::symbols& symbols) { + out << "Dumping symbol table" << std::endl; + SymbolDump dump(out); + symbols.for_each(dump); + return out; +} + + +VariableState::VariableState(bool firstRun) + : firstRun(firstRun), keywords(), nextBooleanVariableIndex(0), nextIntegerVariableIndex(0) { +} + +uint_fast64_t VariableState::addBooleanVariable(const std::string& name, const std::shared_ptr init) { + if (firstRun) { + std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::bool_, this->nextBooleanVariableIndex, name)); + LOG4CPLUS_DEBUG(logger, "Adding boolean variable " << name << " with new id " << this->nextBooleanVariableIndex); + this->booleanVariables_.add(name, varExpr); + this->booleanVariableNames_.add(name, name); + this->nextBooleanVariableIndex++; + return varExpr->getVariableIndex(); + } else { + std::shared_ptr res = this->booleanVariables_.at(name); + if (res != nullptr) { + return res->getVariableIndex(); + } else { + LOG4CPLUS_ERROR(logger, "Boolean variable " << name << " was not created in first run."); + return 0; + } + } +} + +uint_fast64_t VariableState::addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init) { + if (firstRun) { + std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::int_, this->nextIntegerVariableIndex, name, lower, upper)); + LOG4CPLUS_DEBUG(logger, "Adding integer variable " << name << " with new id " << this->nextIntegerVariableIndex); + this->integerVariables_.add(name, varExpr); + LOG4CPLUS_DEBUG(logger, "Int variables: " << this->integerVariables_); + this->integerVariables_.at(name) = varExpr; + LOG4CPLUS_DEBUG(logger, "Int variables: " << this->integerVariables_); + this->integerVariableNames_.add(name, name); + this->nextIntegerVariableIndex++; + return varExpr->getVariableIndex(); + } else { + std::shared_ptr res = this->integerVariables_.at(name); + if (res != nullptr) { + return res->getVariableIndex(); + } else { + + LOG4CPLUS_ERROR(logger, "Integer variable " << name << " was not created in first run."); + return 0; + } + } +} + +std::shared_ptr VariableState::getBooleanVariable(const std::string& name) { + std::shared_ptr res = this->booleanVariables_.at(name); + if (res != nullptr) { + LOG4CPLUS_DEBUG(logger, "Getting boolean variable " << name << ", was found at " << res); + return res; + } else { + if (firstRun) { + LOG4CPLUS_DEBUG(logger, "Getting boolean variable " << name << ", was not yet created."); + return std::shared_ptr(new VariableExpression(BaseExpression::bool_, std::numeric_limits::max(), "bool", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); + } else { + LOG4CPLUS_ERROR(logger, "Getting boolean variable " << name << ", but was not found. This variable does not exist."); + return std::shared_ptr(nullptr); + } + } +} + +std::shared_ptr VariableState::getIntegerVariable(const std::string& name) { + std::shared_ptr res = this->integerVariables_.at(name); + if (res != nullptr) { + LOG4CPLUS_DEBUG(logger, "Getting integer variable " << name << ", was found at " << res); + return res; + } else { + if (firstRun) { + LOG4CPLUS_DEBUG(logger, "Getting integer variable " << name << ", was not yet created."); + return std::shared_ptr(new VariableExpression(BaseExpression::int_, std::numeric_limits::max(), "int", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); + } else { + LOG4CPLUS_ERROR(logger, "Getting integer variable " << name << ", but was not found. This variable does not exist."); + return std::shared_ptr(nullptr); + } + } +} + +void VariableState::startModule() { + this->localBooleanVariables_.clear(); + this->localIntegerVariables_.clear(); +} + +bool VariableState::isFreeIdentifier(std::string& s) const { + if (this->integerVariableNames_.find(s) != nullptr) return false; + if (this->allConstantNames_.find(s) != nullptr) return false; + if (this->labelNames_.find(s) != nullptr) return false; + if (this->moduleNames_.find(s) != nullptr) return false; + if (this->keywords.find(s) != nullptr) return false; + return true; +} +bool VariableState::isIdentifier(std::string& s) const { + if (this->allConstantNames_.find(s) != nullptr) return false; + if (this->keywords.find(s) != nullptr) return false; + return true; +} + +void VariableState::prepareForSecondRun() { + integerConstants_.clear(); + booleanConstants_.clear(); + doubleConstants_.clear(); + allConstantNames_.clear(); + this->firstRun = false; +} + +} +} +} diff --git a/src/parser/PrismParser/VariableState.h b/src/parser/PrismParser/VariableState.h index e94d44056..6293da58b 100644 --- a/src/parser/PrismParser/VariableState.h +++ b/src/parser/PrismParser/VariableState.h @@ -11,6 +11,7 @@ #include "src/ir/IR.h" #include "Includes.h" #include "Tokens.h" +#include namespace storm { namespace parser { @@ -19,14 +20,15 @@ namespace prism { using namespace storm::ir; using namespace storm::ir::expressions; +template +std::ostream& operator<<(std::ostream& out, qi::symbols& symbols); struct VariableState : public storm::ir::VariableAdder { public: - VariableState(bool firstRun = true) - : firstRun(firstRun), keywords(), nextBooleanVariableIndex(0), nextIntegerVariableIndex(0) { - } + VariableState(bool firstRun = true); +public: bool firstRun; keywordsStruct keywords; @@ -43,102 +45,21 @@ public: // A structure representing the identity function over identifier names. struct variableNamesStruct : qi::symbols { } integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_, localBooleanVariables_, localIntegerVariables_, assignedLocalBooleanVariables_, assignedLocalIntegerVariables_; +public: + uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init); + + uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init); + + std::shared_ptr getBooleanVariable(const std::string& name); + + std::shared_ptr getIntegerVariable(const std::string& name); + + void startModule(); + + bool isFreeIdentifier(std::string& s) const; + bool isIdentifier(std::string& s) const; - uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init) { - if (firstRun) { - std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::bool_, this->nextBooleanVariableIndex, name)); - this->booleanVariables_.add(name, varExpr); - this->booleanVariableNames_.add(name, name); - this->nextBooleanVariableIndex++; - return varExpr->getVariableIndex(); - } else { - std::shared_ptr res = this->booleanVariables_.at(name); - if (res != nullptr) { - return res->getVariableIndex(); - } else { - std::cerr << "Variable " << name << " was not created in first run" << std::endl; - return 0; - } - } - } - - uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init) { - //std::cerr << "adding integer variable " << name << std::endl; - if (firstRun) { - std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::int_, this->nextIntegerVariableIndex, name, lower, upper)); - this->integerVariables_.add(name, varExpr); - this->integerVariableNames_.add(name, name); - this->nextIntegerVariableIndex++; - return varExpr->getVariableIndex(); - } else { - std::shared_ptr res = this->integerVariables_.at(name); - if (res != nullptr) { - return res->getVariableIndex(); - } else { - std::cerr << "Variable " << name << " was not created in first run" << std::endl; - return 0; - } - } - } - - std::shared_ptr getBooleanVariable(const std::string& name) { - std::shared_ptr res = this->booleanVariables_.at(name); - if (res != nullptr) { - return res; - } else { - if (firstRun) { - return std::shared_ptr(new VariableExpression(BaseExpression::bool_, std::numeric_limits::max(), "bool", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); - } else { - std::cerr << "bool Variable " << name << " was not created in first run" << std::endl; - return std::shared_ptr(nullptr); - } - } - } - - std::shared_ptr getIntegerVariable(const std::string& name) { - //std::cerr << "getting integer variable " << name << std::endl; - std::shared_ptr res = this->integerVariables_.at(name); - if (res != nullptr) { - return res; - } else { - if (firstRun) { - return std::shared_ptr(new VariableExpression(BaseExpression::int_, std::numeric_limits::max(), "int", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); - } else { - std::cerr << "int Variable " << name << " was not created in first run" << std::endl; - return std::shared_ptr(nullptr); - } - } - } - - void startModule() { - //std::cerr << "starting new module" << std::endl; - this->localBooleanVariables_.clear(); - this->localIntegerVariables_.clear(); - } - - bool isFreeIdentifier(std::string& s) const { - //std::cerr << "Checking if " << s << " is free" << std::endl; - if (this->integerVariableNames_.find(s) != nullptr) return false; - if (this->allConstantNames_.find(s) != nullptr) return false; - if (this->labelNames_.find(s) != nullptr) return false; - if (this->moduleNames_.find(s) != nullptr) return false; - if (this->keywords.find(s) != nullptr) return false; - return true; - } - bool isIdentifier(std::string& s) const { - //std::cerr << "Checking if " << s << " is identifier" << std::endl; - if (this->allConstantNames_.find(s) != nullptr) return false; - if (this->keywords.find(s) != nullptr) return false; - return true; - } - - void prepareForSecondRun() { - integerConstants_.clear(); - booleanConstants_.clear(); - doubleConstants_.clear(); - allConstantNames_.clear(); - this->firstRun = false; - } + void prepareForSecondRun(); }; } From 5840ca5babe9de28fc51af8ca2e83275882cf4b9 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 30 Apr 2013 15:20:35 +0200 Subject: [PATCH 094/152] Fixed weird error from previous commit. --- src/parser/PrismParser/VariableState.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/parser/PrismParser/VariableState.cpp b/src/parser/PrismParser/VariableState.cpp index 91d41be77..117edf954 100644 --- a/src/parser/PrismParser/VariableState.cpp +++ b/src/parser/PrismParser/VariableState.cpp @@ -53,9 +53,6 @@ uint_fast64_t VariableState::addIntegerVariable(const std::string& name, const s std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::int_, this->nextIntegerVariableIndex, name, lower, upper)); LOG4CPLUS_DEBUG(logger, "Adding integer variable " << name << " with new id " << this->nextIntegerVariableIndex); this->integerVariables_.add(name, varExpr); - LOG4CPLUS_DEBUG(logger, "Int variables: " << this->integerVariables_); - this->integerVariables_.at(name) = varExpr; - LOG4CPLUS_DEBUG(logger, "Int variables: " << this->integerVariables_); this->integerVariableNames_.add(name, name); this->nextIntegerVariableIndex++; return varExpr->getVariableIndex(); @@ -72,10 +69,9 @@ uint_fast64_t VariableState::addIntegerVariable(const std::string& name, const s } std::shared_ptr VariableState::getBooleanVariable(const std::string& name) { - std::shared_ptr res = this->booleanVariables_.at(name); + std::shared_ptr* res = this->booleanVariables_.find(name); if (res != nullptr) { - LOG4CPLUS_DEBUG(logger, "Getting boolean variable " << name << ", was found at " << res); - return res; + return *res; } else { if (firstRun) { LOG4CPLUS_DEBUG(logger, "Getting boolean variable " << name << ", was not yet created."); @@ -88,10 +84,9 @@ std::shared_ptr VariableState::getBooleanVariable(const std: } std::shared_ptr VariableState::getIntegerVariable(const std::string& name) { - std::shared_ptr res = this->integerVariables_.at(name); + std::shared_ptr* res = this->integerVariables_.find(name); if (res != nullptr) { - LOG4CPLUS_DEBUG(logger, "Getting integer variable " << name << ", was found at " << res); - return res; + return *res; } else { if (firstRun) { LOG4CPLUS_DEBUG(logger, "Getting integer variable " << name << ", was not yet created."); From 4222130524008554e183dd85a6b23f802de9d394 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 30 Apr 2013 17:16:37 +0200 Subject: [PATCH 095/152] Fixed a few more bugs in clone() of various Expression classes and some in the module renaming. --- src/ir/Module.cpp | 25 +++++++++++++++---- src/ir/Module.h | 2 ++ src/ir/expressions/BaseExpression.h | 3 +++ src/ir/expressions/BinaryExpression.h | 5 ---- .../expressions/BooleanConstantExpression.h | 5 +++- src/ir/expressions/ConstantExpression.h | 3 +++ src/ir/expressions/DoubleConstantExpression.h | 7 ++++-- .../expressions/IntegerConstantExpression.h | 5 +++- src/ir/expressions/VariableExpression.h | 19 ++++++++------ src/parser/PrismParser.cpp | 4 +-- src/parser/PrismParser/VariableState.cpp | 14 +++++++++++ src/parser/PrismParser/VariableState.h | 3 +-- 12 files changed, 70 insertions(+), 25 deletions(-) diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index 40d40fb2f..be2ec770f 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -42,18 +42,32 @@ Module::Module(std::string moduleName, Module::Module(const Module& module, const std::string& moduleName, const std::map& renaming, std::shared_ptr adder) : moduleName(moduleName) { LOG4CPLUS_DEBUG(logger, "Start renaming " << module.moduleName << " to " << moduleName); - this->booleanVariables.reserve(module.booleanVariables.size()); + + // First step: Create new Variables via the adder. for (BooleanVariable it: module.booleanVariables) { if (renaming.count(it.getName()) > 0) { - this->booleanVariablesToIndexMap[renaming.at(it.getName())] = adder->addBooleanVariable(renaming.at(it.getName()), it.getInitialValue()); + adder->addBooleanVariable(renaming.at(it.getName()), it.getInitialValue()); } else LOG4CPLUS_ERROR(logger, moduleName << "." << it.getName() << " was not renamed!"); } - this->integerVariables.reserve(module.integerVariables.size()); for (IntegerVariable it: module.integerVariables) { if (renaming.count(it.getName()) > 0) { - this->integerVariablesToIndexMap[renaming.at(it.getName())] = adder->addIntegerVariable(renaming.at(it.getName()), it.getLowerBound(), it.getUpperBound(), it.getInitialValue()); + adder->addIntegerVariable(renaming.at(it.getName()), it.getLowerBound(), it.getUpperBound(), it.getInitialValue()); } else LOG4CPLUS_ERROR(logger, moduleName << "." << it.getName() << " was not renamed!"); } + + // Second step: Get all indices of variables that are produced by the renaming. + for (auto it: renaming) { + std::shared_ptr var = adder->getVariable(it.second); + if (var != nullptr) { + if (var->getType() == expressions::BaseExpression::bool_) { + this->booleanVariablesToIndexMap[it.second] = var->getVariableIndex(); + } else if (var->getType() == expressions::BaseExpression::int_) { + this->integerVariablesToIndexMap[it.second] = var->getVariableIndex(); + } + } + } + + // Third step: Create new Variable objects. this->booleanVariables.reserve(module.booleanVariables.size()); for (BooleanVariable it: module.booleanVariables) { if (renaming.count(it.getName()) > 0) { @@ -66,7 +80,8 @@ Module::Module(const Module& module, const std::string& moduleName, const std::m this->integerVariables.emplace_back(it, renaming.at(it.getName()), renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap); } else LOG4CPLUS_ERROR(logger, moduleName << "." << it.getName() << " was not renamed!"); } - + + // Fourth step: Clone commands. this->commands.reserve(module.commands.size()); for (Command cmd: module.commands) { this->commands.emplace_back(cmd, renaming, this->booleanVariablesToIndexMap, this->integerVariablesToIndexMap); diff --git a/src/ir/Module.h b/src/ir/Module.h index 8bc465b44..6e653ce47 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -10,6 +10,7 @@ #include "BooleanVariable.h" #include "IntegerVariable.h" +#include "expressions/VariableExpression.h" #include "Command.h" #include @@ -25,6 +26,7 @@ namespace ir { struct VariableAdder { virtual uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init) = 0; virtual uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init) = 0; + virtual std::shared_ptr getVariable(const std::string& name) = 0; }; /*! diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h index a8d3377a9..98f8f2ee2 100644 --- a/src/ir/expressions/BaseExpression.h +++ b/src/ir/expressions/BaseExpression.h @@ -34,6 +34,9 @@ public: BaseExpression(ReturnType type) : type(type) { } + BaseExpression(const BaseExpression& be) + : type(be.type) { + } virtual ~BaseExpression() { diff --git a/src/ir/expressions/BinaryExpression.h b/src/ir/expressions/BinaryExpression.h index 3897c0cc6..529f6ea90 100644 --- a/src/ir/expressions/BinaryExpression.h +++ b/src/ir/expressions/BinaryExpression.h @@ -22,11 +22,6 @@ class BinaryExpression : public BaseExpression { public: BinaryExpression(ReturnType type, std::shared_ptr left, std::shared_ptr right) : BaseExpression(type), left(left), right(right) { - if (left == nullptr || right == nullptr) { - std::cerr << "BinaryExpression" << std::endl; - if (left != nullptr) std::cerr << "\tleft: " << left->toString() << std::endl; - if (right != nullptr) std::cerr << "\tright: " << right->toString() << std::endl; - } } std::shared_ptr const& getLeft() const { diff --git a/src/ir/expressions/BooleanConstantExpression.h b/src/ir/expressions/BooleanConstantExpression.h index 2a01a600a..2f3889b01 100644 --- a/src/ir/expressions/BooleanConstantExpression.h +++ b/src/ir/expressions/BooleanConstantExpression.h @@ -24,13 +24,16 @@ public: defined = false; value = false; } + BooleanConstantExpression(const BooleanConstantExpression& bce) + : ConstantExpression(bce), value(bce.value), defined(bce.defined) { + } virtual ~BooleanConstantExpression() { } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { - return std::shared_ptr(this); + return std::shared_ptr(new BooleanConstantExpression(*this)); } virtual bool getValueAsBool(std::pair, std::vector> const* variableValues) const { diff --git a/src/ir/expressions/ConstantExpression.h b/src/ir/expressions/ConstantExpression.h index b1be49e58..239dca81c 100644 --- a/src/ir/expressions/ConstantExpression.h +++ b/src/ir/expressions/ConstantExpression.h @@ -21,6 +21,9 @@ public: std::string constantName; ConstantExpression(ReturnType type, std::string constantName) : BaseExpression(type), constantName(constantName) { + } + ConstantExpression(const ConstantExpression& ce) + : BaseExpression(ce), constantName(ce.constantName) { } diff --git a/src/ir/expressions/DoubleConstantExpression.h b/src/ir/expressions/DoubleConstantExpression.h index dc8cd7920..f6e26271d 100644 --- a/src/ir/expressions/DoubleConstantExpression.h +++ b/src/ir/expressions/DoubleConstantExpression.h @@ -19,7 +19,10 @@ namespace expressions { class DoubleConstantExpression : public ConstantExpression { public: DoubleConstantExpression(std::string constantName) : ConstantExpression(double_, constantName), defined(false), value(0) { - + } + + DoubleConstantExpression(const DoubleConstantExpression& dce) + : ConstantExpression(dce), defined(dce.defined), value(dce.value) { } virtual ~DoubleConstantExpression() { @@ -27,7 +30,7 @@ public: } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { - return std::shared_ptr(this); + return std::shared_ptr(new DoubleConstantExpression(*this)); } virtual double getValueAsDouble(std::pair, std::vector> const* variableValues) const { diff --git a/src/ir/expressions/IntegerConstantExpression.h b/src/ir/expressions/IntegerConstantExpression.h index 8d916bf7f..c4ad56ed7 100644 --- a/src/ir/expressions/IntegerConstantExpression.h +++ b/src/ir/expressions/IntegerConstantExpression.h @@ -20,13 +20,16 @@ class IntegerConstantExpression : public ConstantExpression { public: IntegerConstantExpression(std::string constantName) : ConstantExpression(int_, constantName), defined(false), value(0) { } + IntegerConstantExpression(const IntegerConstantExpression& ice) + : ConstantExpression(ice), defined(ice.defined), value(ice.value) { + } virtual ~IntegerConstantExpression() { } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { - return std::shared_ptr(this); + return std::shared_ptr(new IntegerConstantExpression(*this)); } virtual int_fast64_t getValueAsInt(std::pair, std::vector> const* variableValues) const { diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h index e14e33d7e..54bebce72 100644 --- a/src/ir/expressions/VariableExpression.h +++ b/src/ir/expressions/VariableExpression.h @@ -13,6 +13,10 @@ #include #include +#include "log4cplus/logger.h" +#include "log4cplus/loggingmacros.h" +extern log4cplus::Logger logger; + namespace storm { namespace ir { @@ -26,26 +30,27 @@ public: std::shared_ptr upperBound = std::shared_ptr(nullptr)) : BaseExpression(type), index(index), variableName(variableName), lowerBound(lowerBound), upperBound(upperBound) { - std::cerr << "Creating " << this << std::endl; } virtual ~VariableExpression() { - std::cerr << "Destroying " << this << std::endl; } virtual std::shared_ptr clone(const std::map& renaming, const std::map& bools, const std::map& ints) { + std::shared_ptr lower = this->lowerBound, upper = this->upperBound; + if (lower != nullptr) lower = lower->clone(renaming, bools, ints); + if (upper != nullptr) upper = upper->clone(renaming, bools, ints); if (renaming.count(this->variableName) > 0) { std::string newName = renaming.at(this->variableName); if (this->getType() == bool_) { - return std::shared_ptr(new VariableExpression(bool_, bools.at(newName), newName, this->lowerBound, this->upperBound)); + return std::shared_ptr(new VariableExpression(bool_, bools.at(newName), newName, lower, upper)); } else if (this->getType() == int_) { - return std::shared_ptr(new VariableExpression(int_, ints.at(newName), newName, this->lowerBound, this->upperBound)); + return std::shared_ptr(new VariableExpression(int_, ints.at(newName), newName, lower, upper)); } else { - std::cerr << "ERROR: Renaming variable " << this->variableName << " that is neither bool nor int." << std::endl; - return std::shared_ptr(this); + LOG4CPLUS_ERROR(logger, "ERROR: Renaming variable " << this->variableName << " that is neither bool nor int."); + return std::shared_ptr(nullptr); } } else { - return std::shared_ptr(this); + return std::shared_ptr(new VariableExpression(this->getType(), this->index, this->variableName, lower, upper)); } } diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 08f534691..903a02d6a 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -72,13 +72,13 @@ namespace parser { throw "Renaming module failed"; } Module res(*old, name, mapping, this->state); - this->state->moduleMap_.add(name, res); + this->state->moduleMap_.at(name) = res; return res; } Module PrismParser::PrismGrammar::createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands) { this->state->moduleNames_.add(name, name); Module res(name, bools, ints, boolids, intids, commands); - this->state->moduleMap_.add(name, res); + this->state->moduleMap_.at(name) = res; return res; } diff --git a/src/parser/PrismParser/VariableState.cpp b/src/parser/PrismParser/VariableState.cpp index 117edf954..dee14bcb3 100644 --- a/src/parser/PrismParser/VariableState.cpp +++ b/src/parser/PrismParser/VariableState.cpp @@ -97,6 +97,20 @@ std::shared_ptr VariableState::getIntegerVariable(const std: } } } +std::shared_ptr VariableState::getVariable(const std::string& name) { + std::shared_ptr* res = this->integerVariables_.find(name); + if (res != nullptr) { + return *res; + } else { + res = this->booleanVariables_.find(name); + if (res != nullptr) { + return *res; + } else { + LOG4CPLUS_ERROR(logger, "Getting variable " << name << ", but was not found. This variable does not exist."); + return std::shared_ptr(nullptr); + } + } +} void VariableState::startModule() { this->localBooleanVariables_.clear(); diff --git a/src/parser/PrismParser/VariableState.h b/src/parser/PrismParser/VariableState.h index 6293da58b..c4046e658 100644 --- a/src/parser/PrismParser/VariableState.h +++ b/src/parser/PrismParser/VariableState.h @@ -47,12 +47,11 @@ public: localBooleanVariables_, localIntegerVariables_, assignedLocalBooleanVariables_, assignedLocalIntegerVariables_; public: uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init); - uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init); std::shared_ptr getBooleanVariable(const std::string& name); - std::shared_ptr getIntegerVariable(const std::string& name); + std::shared_ptr getVariable(const std::string& name); void startModule(); From 3b76126f6bb5feeb0d24be253bb3a2855c5aa724 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 30 Apr 2013 17:50:21 +0200 Subject: [PATCH 096/152] Split PrismParser and PrismGrammar in differenc object files. Added reset method for grammars, now we can parse multiple files in one program execution. Added test for mdp parsing. --- src/models/Mdp.h | 8 + src/parser/PrismParser.cpp | 236 +--------------------- src/parser/PrismParser.h | 109 ---------- src/parser/PrismParser/BaseGrammar.h | 5 +- src/parser/PrismParser/PrismGrammar.cpp | 258 ++++++++++++++++++++++++ src/parser/PrismParser/PrismGrammar.h | 142 +++++++++++++ test/parser/ParsePrismTest.cpp | 14 +- 7 files changed, 434 insertions(+), 338 deletions(-) create mode 100644 src/parser/PrismParser/PrismGrammar.cpp create mode 100644 src/parser/PrismParser/PrismGrammar.h diff --git a/src/models/Mdp.h b/src/models/Mdp.h index dc58782a2..8c06a5deb 100644 --- a/src/models/Mdp.h +++ b/src/models/Mdp.h @@ -89,6 +89,14 @@ public: uint_fast64_t getNumberOfStates() const { return this->probabilityMatrix->getColumnCount(); } + + /*! + * Returns the number of choices for all states of the MDP. + * @return The number of choices for all states of the MDP. + */ + uint_fast64_t getNumberOfChoices() const { + return this->probabilityMatrix->getRowCount(); + } /*! * Returns the number of (non-zero) transitions of the MDP. diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 903a02d6a..ce58bd988 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -9,14 +9,7 @@ #include "src/utility/OsDetection.h" -#include "src/parser/PrismParser/Includes.h" -#include "src/parser/PrismParser/BooleanExpressionGrammar.h" -#include "src/parser/PrismParser/ConstBooleanExpressionGrammar.h" -#include "src/parser/PrismParser/ConstDoubleExpressionGrammar.h" -#include "src/parser/PrismParser/ConstIntegerExpressionGrammar.h" -#include "src/parser/PrismParser/IntegerExpressionGrammar.h" -#include "src/parser/PrismParser/IdentifierGrammars.h" -#include "src/parser/PrismParser/VariableState.h" +#include "src/parser/PrismParser/PrismGrammar.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFileFormatException.h" @@ -30,234 +23,17 @@ #include "log4cplus/loggingmacros.h" extern log4cplus::Logger logger; -// Some typedefs and namespace definitions to reduce code size. -typedef std::string::const_iterator BaseIteratorType; -typedef boost::spirit::classic::position_iterator2 PositionIteratorType; -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; namespace storm { - namespace parser { - void dump(const std::string& s) { - std::cerr << "Dump: " << s << std::endl; - } - - std::shared_ptr PrismParser::PrismGrammar::addIntegerConstant(const std::string& name, const std::shared_ptr value) { - this->state->integerConstants_.add(name, value); - this->state->allConstantNames_.add(name, name); - return value; - } - - void PrismParser::PrismGrammar::addLabel(const std::string& name, std::shared_ptr value, std::map>& mapping) { - this->state->labelNames_.add(name, name); - mapping[name] = value; - } - void PrismParser::PrismGrammar::addIntAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping) { - //std::cout << "Adding int assignment for " << variable << std::endl; - this->state->assignedLocalIntegerVariables_.add(variable, variable); - mapping[variable] = Assignment(variable, value); - } - void PrismParser::PrismGrammar::addBoolAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping) { - //std::cout << "Adding bool assignment for " << variable << std::endl; - this->state->assignedLocalBooleanVariables_.add(variable, variable); - mapping[variable] = Assignment(variable, value); - } - Module PrismParser::PrismGrammar::renameModule(const std::string& name, const std::string& oldname, std::map& mapping) { - this->state->moduleNames_.add(name, name); - Module* old = this->state->moduleMap_.find(oldname); - if (old == nullptr) { - LOG4CPLUS_ERROR(logger, "Renaming module failed: module " << oldname << " does not exist!"); - throw "Renaming module failed"; - } - Module res(*old, name, mapping, this->state); - this->state->moduleMap_.at(name) = res; - return res; - } - Module PrismParser::PrismGrammar::createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands) { - this->state->moduleNames_.add(name, name); - Module res(name, bools, ints, boolids, intids, commands); - this->state->moduleMap_.at(name) = res; - return res; - } - - void PrismParser::PrismGrammar::createIntegerVariable(const std::string name, std::shared_ptr lower, std::shared_ptr upper, std::shared_ptr init, std::vector& vars, std::map& varids) { - //std::cout << "Creating int " << name << " = " << init << std::endl; - uint_fast64_t id = this->state->addIntegerVariable(name, lower, upper, init); - vars.emplace_back(id, name, lower, upper, init); - varids[name] = id; - this->state->localIntegerVariables_.add(name, name); - } - void PrismParser::PrismGrammar::createBooleanVariable(const std::string name, std::shared_ptr init, std::vector& vars, std::map& varids) { - //std::cout << "Creating bool " << name << std::endl; - uint_fast64_t id = this->state->addBooleanVariable(name, init); - vars.emplace_back(id, name, init); - varids[name] = id; - this->state->localBooleanVariables_.add(name, name); - } - - StateReward createStateReward(std::shared_ptr guard, std::shared_ptr reward) { - return StateReward(guard, reward); - } - TransitionReward createTransitionReward(std::string label, std::shared_ptr guard, std::shared_ptr reward) { - return TransitionReward(label, guard, reward); - } - void createRewardModel(std::string name, std::vector& stateRewards, std::vector& transitionRewards, std::map& mapping) { - mapping[name] = RewardModel(name, stateRewards, transitionRewards); - } - Update createUpdate(std::shared_ptr likelihood, std::map& bools, std::map ints) { - return Update(likelihood, bools, ints); - } - Command createCommand(std::string& label, std::shared_ptr guard, std::vector& updates) { - return Command(label, guard, updates); - } - Program createProgram( - Program::ModelType modelType, - std::map> undefBoolConst, - std::map> undefIntConst, - std::map> undefDoubleConst, - std::vector modules, - std::map rewards, - std::map> labels) { - return Program(modelType, undefBoolConst, undefIntConst, undefDoubleConst, modules, rewards, labels); - } - -PrismParser::PrismGrammar::PrismGrammar() : PrismParser::PrismGrammar::base_type(start), state(new storm::parser::prism::VariableState()) { - - labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> prism::FreeIdentifierGrammar::instance(this->state) >> -qi::lit("\"") >> qi::lit("=") >> prism::BooleanExpressionGrammar::instance(this->state) >> qi::lit(";")) - [phoenix::bind(&PrismParser::PrismGrammar::addLabel, this, qi::_1, qi::_2, qi::_r1)]; - labelDefinition.name("label declaration"); - labelDefinitionList %= *labelDefinition(qi::_r1); - labelDefinitionList.name("label declaration list"); - - // This block defines all entities that are needed for parsing a reward model. - stateRewardDefinition = (prism::BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > prism::ConstDoubleExpressionGrammar::instance(this->state) >> qi::lit(";"))[qi::_val = phoenix::bind(&createStateReward, qi::_1, qi::_2)]; - stateRewardDefinition.name("state reward definition"); - transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > prism::BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[qi::_val = phoenix::bind(&createTransitionReward, qi::_a, qi::_2, qi::_3)]; - transitionRewardDefinition.name("transition reward definition"); - rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > prism::FreeIdentifierGrammar::instance(this->state) > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> qi::lit("endrewards")) - [phoenix::bind(&createRewardModel, qi::_1, qi::_a, qi::_b, qi::_r1)]; - rewardDefinition.name("reward definition"); - rewardDefinitionList = *rewardDefinition(qi::_r1); - rewardDefinitionList.name("reward definition list"); - - commandName %= this->state->commandNames_; - commandName.name("command name"); - unassignedLocalBooleanVariableName %= this->state->localBooleanVariables_ - this->state->assignedLocalBooleanVariables_; - unassignedLocalBooleanVariableName.name("unassigned local boolean variable"); - unassignedLocalIntegerVariableName %= this->state->localIntegerVariables_ - this->state->assignedLocalIntegerVariables_; - unassignedLocalIntegerVariableName.name("unassigned local integer variable"); - - // This block defines all entities that are needed for parsing a single command. - assignmentDefinition = - (qi::lit("(") >> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > prism::IntegerExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(&PrismParser::PrismGrammar::addIntAssignment, this, qi::_1, qi::_2, qi::_r2)] | - (qi::lit("(") >> unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > prism::BooleanExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(&PrismParser::PrismGrammar::addBoolAssignment, this, qi::_1, qi::_2, qi::_r1)]; - assignmentDefinition.name("assignment"); - assignmentDefinitionList = assignmentDefinition(qi::_r1, qi::_r2) % "&"; - assignmentDefinitionList.name("assignment list"); - updateDefinition = ( - prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(":")[phoenix::clear(phoenix::ref(this->state->assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(this->state->assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::bind(&createUpdate, qi::_1, qi::_a, qi::_b)]; - updateDefinition.name("update"); - updateListDefinition = +updateDefinition % "+"; - updateListDefinition.name("update list"); - commandDefinition = ( - qi::lit("[") > -( - (prism::FreeIdentifierGrammar::instance(this->state)[phoenix::bind(this->state->commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1] - ) > qi::lit("]") > prism::BooleanExpressionGrammar::instance(this->state) > qi::lit("->") > updateListDefinition > qi::lit(";") - )[qi::_val = phoenix::bind(&createCommand, qi::_a, qi::_2, qi::_3)]; - commandDefinition.name("command"); - - // This block defines all entities that are needed for parsing variable definitions. - booleanVariableDefinition = (prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > prism::ConstBooleanExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) - [ - phoenix::bind(&PrismParser::PrismGrammar::createBooleanVariable, this, qi::_1, qi::_b, qi::_r1, qi::_r2) - ]; - booleanVariableDefinition.name("boolean variable declaration"); - - integerVariableDefinition = (prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit(":") >> qi::lit("[") > prism::ConstIntegerExpressionGrammar::instance(this->state) > qi::lit("..") > prism::ConstIntegerExpressionGrammar::instance(this->state) > qi::lit("]") > -(qi::lit("init") > prism::ConstIntegerExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) - [ - phoenix::bind(&PrismParser::PrismGrammar::createIntegerVariable, this, qi::_1, qi::_2, qi::_3, qi::_b, qi::_r1, qi::_r2) - ]; - integerVariableDefinition.name("integer variable declaration"); - variableDefinition = (booleanVariableDefinition(qi::_r1, qi::_r3) | integerVariableDefinition(qi::_r2, qi::_r4)); - variableDefinition.name("variable declaration"); - - // This block defines all entities that are needed for parsing a module. - moduleDefinition = (qi::lit("module") >> prism::FreeIdentifierGrammar::instance(this->state)[phoenix::bind(&prism::VariableState::startModule, *this->state)] - >> *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) >> +commandDefinition > qi::lit("endmodule")) - [qi::_val = phoenix::bind(&PrismParser::PrismGrammar::createModule, this, qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2)]; - - moduleDefinition.name("module"); - moduleRenaming = (qi::lit("module") >> prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") - > this->state->moduleNames_ > qi::lit("[") > *( - (prism::IdentifierGrammar::instance(this->state) > qi::lit("=") > prism::IdentifierGrammar::instance(this->state) >> -qi::lit(","))[phoenix::insert(qi::_a, phoenix::construct>(qi::_1, qi::_2))] - ) > qi::lit("]") > qi::lit("endmodule")) - [qi::_val = phoenix::bind(&PrismParser::PrismGrammar::renameModule, this, qi::_1, qi::_2, qi::_a)]; - moduleRenaming.name("renamed module"); - moduleDefinitionList %= +(moduleDefinition | moduleRenaming); - moduleDefinitionList.name("module list"); - - // This block defines all entities that are needed for parsing constant definitions. - definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > prism::ConstBooleanExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; - definedBooleanConstantDefinition.name("defined boolean constant declaration"); - definedIntegerConstantDefinition = ( - qi::lit("const") >> qi::lit("int") >> prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> - prism::ConstIntegerExpressionGrammar::instance(this->state) >> qi::lit(";") - )[ qi::_val = phoenix::bind(&PrismParser::PrismGrammar::addIntegerConstant, this, qi::_1, qi::_2) ]; - definedIntegerConstantDefinition.name("defined integer constant declaration"); - definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> prism::FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > prism::ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; - definedDoubleConstantDefinition.name("defined double constant declaration"); - undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > prism::FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; - undefinedBooleanConstantDefinition.name("undefined boolean constant declaration"); - undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > prism::FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->integerConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; - undefinedIntegerConstantDefinition.name("undefined integer constant declaration"); - undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > prism::FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; - undefinedDoubleConstantDefinition.name("undefined double constant declaration"); - definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); - definedConstantDefinition.name("defined constant declaration"); - undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3)); - undefinedConstantDefinition.name("undefined constant declaration"); - constantDefinitionList = *(definedConstantDefinition | undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3)); - constantDefinitionList.name("constant declaration list"); - - // This block defines all entities that are needed for parsing a program. - modelTypeDefinition = modelType_; - modelTypeDefinition.name("model type"); - start = ( - modelTypeDefinition > - constantDefinitionList(qi::_a, qi::_b, qi::_c) > - moduleDefinitionList > - rewardDefinitionList(qi::_d) > - labelDefinitionList(qi::_e) - )[qi::_val = phoenix::bind(&createProgram, qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_d, qi::_e)]; - start.name("probabilistic program declaration"); - } - - void PrismParser::PrismGrammar::prepareForSecondRun() { - LOG4CPLUS_INFO(logger, "Preparing parser for second run."); - this->state->getIntegerVariable("d1"); - this->state->getIntegerVariable("d2"); - this->state->getIntegerVariable("s1"); - this->state->getIntegerVariable("s2"); - this->state->prepareForSecondRun(); - this->state->getIntegerVariable("d1"); - this->state->getIntegerVariable("d2"); - this->state->getIntegerVariable("s1"); - this->state->getIntegerVariable("s2"); - prism::BooleanExpressionGrammar::secondRun(); - prism::ConstBooleanExpressionGrammar::secondRun(); - prism::ConstDoubleExpressionGrammar::secondRun(); - prism::ConstIntegerExpressionGrammar::secondRun(); - prism::IntegerExpressionGrammar::secondRun(); - } - /*! * Opens the given file for parsing, invokes the helper function to parse the actual content and * closes the file properly, even if an exception is thrown in the parser. In this case, the * exception is passed on to the caller. */ storm::ir::Program PrismParser::parseFile(std::string const& filename) const { + std::cerr << "parseFile( " << filename << " )" << std::endl; // Open file and initialize result. std::ifstream inputFileStream(filename, std::ios::in); storm::ir::Program result; @@ -266,6 +42,7 @@ storm::ir::Program PrismParser::parseFile(std::string const& filename) const { try { result = parse(inputFileStream, filename); } catch(std::exception& e) { + std::cerr << "Exception: " << e.what() << std::endl; // In case of an exception properly close the file before passing exception. inputFileStream.close(); throw e; @@ -299,7 +76,7 @@ storm::ir::Program PrismParser::parse(std::istream& inputStream, std::string con // In order to instantiate the grammar, we have to pass the type of the skipping parser. // As this is more complex, we let Boost figure out the actual type for us. - PrismGrammar grammar; + prism::PrismGrammar grammar; try { // Now parse the content using phrase_parse in order to be able to supply a skipping parser. // First run. @@ -311,7 +88,12 @@ storm::ir::Program PrismParser::parse(std::istream& inputStream, std::string con // Second run. qi::phrase_parse(positionIteratorBegin2, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result); LOG4CPLUS_INFO(logger, "Finished parsing, here is the parsed program:" << std::endl << result.toString()); + // Reset grammars. + grammar.resetGrammars(); } catch(const qi::expectation_failure& e) { + // Reset grammars in any case. + grammar.resetGrammars(); + // If the parser expected content different than the one provided, display information // about the location of the error. const boost::spirit::classic::file_position_base& pos = e.first.get_position(); diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 32a797adf..48326713f 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -9,15 +9,6 @@ // All classes of the intermediate representation are used. #include "src/ir/IR.h" -#include "src/parser/PrismParser/Includes.h" -#include "src/parser/PrismParser/Tokens.h" -#include "src/parser/PrismParser/IdentifierGrammars.h" -#include "src/parser/PrismParser/VariableState.h" -#include "src/parser/PrismParser/ConstBooleanExpressionGrammar.h" -#include "src/parser/PrismParser/ConstDoubleExpressionGrammar.h" -#include "src/parser/PrismParser/ConstIntegerExpressionGrammar.h" -#include "src/parser/PrismParser/BooleanExpressionGrammar.h" -#include "src/parser/PrismParser/IntegerExpressionGrammar.h" // Used for file input. #include @@ -42,106 +33,6 @@ public: * @return a shared pointer to the intermediate representation of the PRISM file. */ storm::ir::Program parseFile(std::string const& filename) const; - - /*! - * The Boost spirit grammar for the PRISM language. Returns the intermediate representation of - * the input that complies with the PRISM syntax. - */ - class PrismGrammar : public qi::grammar< - Iterator, - Program(), - qi::locals< - std::map>, - std::map>, - std::map>, - std::map, - std::map> - >, - Skipper> { - public: - PrismGrammar(); - void prepareForSecondRun(); - - private: - - std::shared_ptr state; - - // The starting point of the grammar. - qi::rule< - Iterator, - Program(), - qi::locals< - std::map>, - std::map>, - std::map>, - std::map, - std::map> - >, - Skipper> start; - qi::rule modelTypeDefinition; - qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; - qi::rule(), Skipper> moduleDefinitionList; - - // Rules for module definition. - qi::rule, std::vector, std::map, std::map>, Skipper> moduleDefinition; - qi::rule>, Skipper> moduleRenaming; - - // Rules for variable definitions. - qi::rule&, std::vector&, std::map&, std::map&), Skipper> variableDefinition; - qi::rule&, std::map&), qi::locals>, Skipper> booleanVariableDefinition; - qi::rule&, std::map&), qi::locals>, Skipper> integerVariableDefinition; - - // Rules for command definitions. - qi::rule, Skipper> commandDefinition; - qi::rule(), Skipper> updateListDefinition; - qi::rule, std::map>, Skipper> updateDefinition; - qi::rule&, std::map&), Skipper> assignmentDefinitionList; - qi::rule&, std::map&), Skipper> assignmentDefinition; - - // Rules for variable/command names. - qi::rule commandName; - qi::rule unassignedLocalBooleanVariableName; - qi::rule unassignedLocalIntegerVariableName; - - // Rules for reward definitions. - qi::rule&), Skipper> rewardDefinitionList; - qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; - qi::rule stateRewardDefinition; - qi::rule, Skipper> transitionRewardDefinition; - - // Rules for label definitions. - qi::rule>&), Skipper> labelDefinitionList; - qi::rule>&), Skipper> labelDefinition; - - // Rules for constant definitions. - qi::rule(), Skipper> constantDefinition; - qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; - qi::rule(), Skipper> definedConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedBooleanConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedIntegerConstantDefinition; - qi::rule>&), qi::locals>, Skipper> undefinedDoubleConstantDefinition; - qi::rule(), Skipper> definedBooleanConstantDefinition; - qi::rule(), Skipper> definedIntegerConstantDefinition; - qi::rule(), Skipper> definedDoubleConstantDefinition; - - // Rules for variable recognition. - qi::rule(), Skipper> booleanVariableCreatorExpression; - qi::rule(), qi::locals>, Skipper> integerVariableCreatorExpression; - - storm::parser::prism::keywordsStruct keywords_; - storm::parser::prism::modelTypeStruct modelType_; - storm::parser::prism::relationalOperatorStruct relations_; - - std::shared_ptr addIntegerConstant(const std::string& name, const std::shared_ptr value); - void addLabel(const std::string& name, std::shared_ptr value, std::map>& mapping); - void addBoolAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); - void addIntAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); - Module renameModule(const std::string& name, const std::string& oldname, std::map& mapping); - Module createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands); - - void createIntegerVariable(const std::string name, std::shared_ptr lower, std::shared_ptr upper, std::shared_ptr init, std::vector& vars, std::map& varids); - void createBooleanVariable(const std::string name, std::shared_ptr init, std::vector& vars, std::map& varids); - }; private: /*! diff --git a/src/parser/PrismParser/BaseGrammar.h b/src/parser/PrismParser/BaseGrammar.h index 4bf4f3265..345a377e0 100644 --- a/src/parser/PrismParser/BaseGrammar.h +++ b/src/parser/PrismParser/BaseGrammar.h @@ -29,11 +29,14 @@ namespace prism { return *BaseGrammar::instanceObject; } + static void resetInstance() { + BaseGrammar::instanceObject = nullptr; + } + static void secondRun() { if (BaseGrammar::instanceObject != nullptr) { BaseGrammar::instanceObject->prepareSecondRun(); } - } std::shared_ptr createBoolLiteral(const bool value) { diff --git a/src/parser/PrismParser/PrismGrammar.cpp b/src/parser/PrismParser/PrismGrammar.cpp new file mode 100644 index 000000000..ac3f3dbf4 --- /dev/null +++ b/src/parser/PrismParser/PrismGrammar.cpp @@ -0,0 +1,258 @@ +/* + * PrismGrammar.cpp + * + * Created on: 11.01.2013 + * Author: chris + */ + +#include "PrismGrammar.h" + +#include "src/utility/OsDetection.h" + +#include "src/parser/PrismParser/Includes.h" +#include "src/parser/PrismParser/BooleanExpressionGrammar.h" +#include "src/parser/PrismParser/ConstBooleanExpressionGrammar.h" +#include "src/parser/PrismParser/ConstDoubleExpressionGrammar.h" +#include "src/parser/PrismParser/ConstIntegerExpressionGrammar.h" +#include "src/parser/PrismParser/IntegerExpressionGrammar.h" +#include "src/parser/PrismParser/IdentifierGrammars.h" +#include "src/parser/PrismParser/VariableState.h" + +// If the parser fails due to ill-formed data, this exception is thrown. +#include "src/exceptions/WrongFileFormatException.h" + +// Needed for file IO. +#include +#include +#include + +#include "log4cplus/logger.h" +#include "log4cplus/loggingmacros.h" +extern log4cplus::Logger logger; + +// Some typedefs and namespace definitions to reduce code size. +typedef std::string::const_iterator BaseIteratorType; +typedef boost::spirit::classic::position_iterator2 PositionIteratorType; +namespace qi = boost::spirit::qi; +namespace phoenix = boost::phoenix; + +namespace storm { +namespace parser { +namespace prism { + +void dump(const std::string& s) { + std::cerr << "Dump: " << s << std::endl; +} + +std::shared_ptr PrismGrammar::addIntegerConstant(const std::string& name, const std::shared_ptr value) { + this->state->integerConstants_.add(name, value); + this->state->allConstantNames_.add(name, name); + return value; +} + +void PrismGrammar::addLabel(const std::string& name, std::shared_ptr value, std::map>& mapping) { + this->state->labelNames_.add(name, name); + mapping[name] = value; +} +void PrismGrammar::addIntAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping) { + //std::cout << "Adding int assignment for " << variable << std::endl; + this->state->assignedLocalIntegerVariables_.add(variable, variable); + mapping[variable] = Assignment(variable, value); +} +void PrismGrammar::addBoolAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping) { + //std::cout << "Adding bool assignment for " << variable << std::endl; + this->state->assignedLocalBooleanVariables_.add(variable, variable); + mapping[variable] = Assignment(variable, value); +} +Module PrismGrammar::renameModule(const std::string& name, const std::string& oldname, std::map& mapping) { + this->state->moduleNames_.add(name, name); + Module* old = this->state->moduleMap_.find(oldname); + if (old == nullptr) { + LOG4CPLUS_ERROR(logger, "Renaming module failed: module " << oldname << " does not exist!"); + throw "Renaming module failed"; + } + Module res(*old, name, mapping, this->state); + this->state->moduleMap_.at(name) = res; + return res; +} +Module PrismGrammar::createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands) { + this->state->moduleNames_.add(name, name); + Module res(name, bools, ints, boolids, intids, commands); + this->state->moduleMap_.at(name) = res; + return res; +} + +void PrismGrammar::createIntegerVariable(const std::string name, std::shared_ptr lower, std::shared_ptr upper, std::shared_ptr init, std::vector& vars, std::map& varids) { + //std::cout << "Creating int " << name << " = " << init << std::endl; + uint_fast64_t id = this->state->addIntegerVariable(name, lower, upper, init); + vars.emplace_back(id, name, lower, upper, init); + varids[name] = id; + this->state->localIntegerVariables_.add(name, name); +} +void PrismGrammar::createBooleanVariable(const std::string name, std::shared_ptr init, std::vector& vars, std::map& varids) { + //std::cout << "Creating bool " << name << std::endl; + uint_fast64_t id = this->state->addBooleanVariable(name, init); + vars.emplace_back(id, name, init); + varids[name] = id; + this->state->localBooleanVariables_.add(name, name); +} + +StateReward createStateReward(std::shared_ptr guard, std::shared_ptr reward) { + return StateReward(guard, reward); +} +TransitionReward createTransitionReward(std::string label, std::shared_ptr guard, std::shared_ptr reward) { + return TransitionReward(label, guard, reward); +} +void createRewardModel(std::string name, std::vector& stateRewards, std::vector& transitionRewards, std::map& mapping) { + mapping[name] = RewardModel(name, stateRewards, transitionRewards); +} +Update createUpdate(std::shared_ptr likelihood, std::map& bools, std::map ints) { + return Update(likelihood, bools, ints); +} +Command createCommand(std::string& label, std::shared_ptr guard, std::vector& updates) { + return Command(label, guard, updates); +} +Program createProgram( + Program::ModelType modelType, + std::map> undefBoolConst, + std::map> undefIntConst, + std::map> undefDoubleConst, + std::vector modules, + std::map rewards, + std::map> labels) { + return Program(modelType, undefBoolConst, undefIntConst, undefDoubleConst, modules, rewards, labels); +} + +PrismGrammar::PrismGrammar() : PrismGrammar::base_type(start), state(new VariableState()) { + + labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> FreeIdentifierGrammar::instance(this->state) >> -qi::lit("\"") >> qi::lit("=") >> BooleanExpressionGrammar::instance(this->state) >> qi::lit(";")) + [phoenix::bind(&PrismGrammar::addLabel, this, qi::_1, qi::_2, qi::_r1)]; + labelDefinition.name("label declaration"); + labelDefinitionList %= *labelDefinition(qi::_r1); + labelDefinitionList.name("label declaration list"); + + // This block defines all entities that are needed for parsing a reward model. + stateRewardDefinition = (BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > ConstDoubleExpressionGrammar::instance(this->state) >> qi::lit(";"))[qi::_val = phoenix::bind(&createStateReward, qi::_1, qi::_2)]; + stateRewardDefinition.name("state reward definition"); + transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[qi::_val = phoenix::bind(&createTransitionReward, qi::_a, qi::_2, qi::_3)]; + transitionRewardDefinition.name("transition reward definition"); + rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > FreeIdentifierGrammar::instance(this->state) > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> qi::lit("endrewards")) + [phoenix::bind(&createRewardModel, qi::_1, qi::_a, qi::_b, qi::_r1)]; + rewardDefinition.name("reward definition"); + rewardDefinitionList = *rewardDefinition(qi::_r1); + rewardDefinitionList.name("reward definition list"); + + commandName %= this->state->commandNames_; + commandName.name("command name"); + unassignedLocalBooleanVariableName %= this->state->localBooleanVariables_ - this->state->assignedLocalBooleanVariables_; + unassignedLocalBooleanVariableName.name("unassigned local boolean variable"); + unassignedLocalIntegerVariableName %= this->state->localIntegerVariables_ - this->state->assignedLocalIntegerVariables_; + unassignedLocalIntegerVariableName.name("unassigned local integer variable"); + + // This block defines all entities that are needed for parsing a single command. + assignmentDefinition = + (qi::lit("(") >> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > IntegerExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(&PrismGrammar::addIntAssignment, this, qi::_1, qi::_2, qi::_r2)] | + (qi::lit("(") >> unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > BooleanExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(&PrismGrammar::addBoolAssignment, this, qi::_1, qi::_2, qi::_r1)]; + assignmentDefinition.name("assignment"); + assignmentDefinitionList = assignmentDefinition(qi::_r1, qi::_r2) % "&"; + assignmentDefinitionList.name("assignment list"); + updateDefinition = ( + ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(":")[phoenix::clear(phoenix::ref(this->state->assignedLocalBooleanVariables_)), phoenix::clear(phoenix::ref(this->state->assignedLocalIntegerVariables_))] > assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::bind(&createUpdate, qi::_1, qi::_a, qi::_b)]; + updateDefinition.name("update"); + updateListDefinition = +updateDefinition % "+"; + updateListDefinition.name("update list"); + commandDefinition = ( + qi::lit("[") > -( + (FreeIdentifierGrammar::instance(this->state)[phoenix::bind(this->state->commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1] + ) > qi::lit("]") > BooleanExpressionGrammar::instance(this->state) > qi::lit("->") > updateListDefinition > qi::lit(";") + )[qi::_val = phoenix::bind(&createCommand, qi::_a, qi::_2, qi::_3)]; + commandDefinition.name("command"); + + // This block defines all entities that are needed for parsing variable definitions. + booleanVariableDefinition = (FreeIdentifierGrammar::instance(this->state) >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > ConstBooleanExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) + [ + phoenix::bind(&PrismGrammar::createBooleanVariable, this, qi::_1, qi::_b, qi::_r1, qi::_r2) + ]; + booleanVariableDefinition.name("boolean variable declaration"); + + integerVariableDefinition = (FreeIdentifierGrammar::instance(this->state) >> qi::lit(":") >> qi::lit("[") > ConstIntegerExpressionGrammar::instance(this->state) > qi::lit("..") > ConstIntegerExpressionGrammar::instance(this->state) > qi::lit("]") > -(qi::lit("init") > ConstIntegerExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct>(qi::_1)]) > qi::lit(";")) + [ + phoenix::bind(&PrismGrammar::createIntegerVariable, this, qi::_1, qi::_2, qi::_3, qi::_b, qi::_r1, qi::_r2) + ]; + integerVariableDefinition.name("integer variable declaration"); + variableDefinition = (booleanVariableDefinition(qi::_r1, qi::_r3) | integerVariableDefinition(qi::_r2, qi::_r4)); + variableDefinition.name("variable declaration"); + + // This block defines all entities that are needed for parsing a module. + moduleDefinition = (qi::lit("module") >> FreeIdentifierGrammar::instance(this->state)[phoenix::bind(&VariableState::startModule, *this->state)] + >> *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) >> +commandDefinition > qi::lit("endmodule")) + [qi::_val = phoenix::bind(&PrismGrammar::createModule, this, qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2)]; + + moduleDefinition.name("module"); + moduleRenaming = (qi::lit("module") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") + > this->state->moduleNames_ > qi::lit("[") > *( + (IdentifierGrammar::instance(this->state) > qi::lit("=") > IdentifierGrammar::instance(this->state) >> -qi::lit(","))[phoenix::insert(qi::_a, phoenix::construct>(qi::_1, qi::_2))] + ) > qi::lit("]") > qi::lit("endmodule")) + [qi::_val = phoenix::bind(&PrismGrammar::renameModule, this, qi::_1, qi::_2, qi::_a)]; + moduleRenaming.name("renamed module"); + moduleDefinitionList %= +(moduleDefinition | moduleRenaming); + moduleDefinitionList.name("module list"); + + // This block defines all entities that are needed for parsing constant definitions. + definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > ConstBooleanExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; + definedBooleanConstantDefinition.name("defined boolean constant declaration"); + definedIntegerConstantDefinition = ( + qi::lit("const") >> qi::lit("int") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> + ConstIntegerExpressionGrammar::instance(this->state) >> qi::lit(";") + )[ qi::_val = phoenix::bind(&PrismGrammar::addIntegerConstant, this, qi::_1, qi::_2) ]; + definedIntegerConstantDefinition.name("defined integer constant declaration"); + definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2]; + definedDoubleConstantDefinition.name("defined double constant declaration"); + undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; + undefinedBooleanConstantDefinition.name("undefined boolean constant declaration"); + undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->integerConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; + undefinedIntegerConstantDefinition.name("undefined integer constant declaration"); + undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[qi::_a = phoenix::construct>(phoenix::new_(qi::_1)), phoenix::insert(qi::_r1, phoenix::construct>>(qi::_1, qi::_a)), phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_a), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1)]; + undefinedDoubleConstantDefinition.name("undefined double constant declaration"); + definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); + definedConstantDefinition.name("defined constant declaration"); + undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3)); + undefinedConstantDefinition.name("undefined constant declaration"); + constantDefinitionList = *(definedConstantDefinition | undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3)); + constantDefinitionList.name("constant declaration list"); + + // This block defines all entities that are needed for parsing a program. + modelTypeDefinition = modelType_; + modelTypeDefinition.name("model type"); + start = ( + modelTypeDefinition > + constantDefinitionList(qi::_a, qi::_b, qi::_c) > + moduleDefinitionList > + rewardDefinitionList(qi::_d) > + labelDefinitionList(qi::_e) + )[qi::_val = phoenix::bind(&createProgram, qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_d, qi::_e)]; + start.name("probabilistic program declaration"); +} + +void PrismGrammar::prepareForSecondRun() { + LOG4CPLUS_INFO(logger, "Preparing parser for second run."); + this->state->prepareForSecondRun(); + BooleanExpressionGrammar::secondRun(); + ConstBooleanExpressionGrammar::secondRun(); + ConstDoubleExpressionGrammar::secondRun(); + ConstIntegerExpressionGrammar::secondRun(); + IntegerExpressionGrammar::secondRun(); +} + +void PrismGrammar::resetGrammars() { + LOG4CPLUS_INFO(logger, "Resetting grammars."); + BooleanExpressionGrammar::resetInstance(); + ConstBooleanExpressionGrammar::resetInstance(); + ConstDoubleExpressionGrammar::resetInstance(); + ConstIntegerExpressionGrammar::resetInstance(); + IntegerExpressionGrammar::resetInstance(); +} + +} // namespace prism +} // namespace parser +} // namespace storm diff --git a/src/parser/PrismParser/PrismGrammar.h b/src/parser/PrismParser/PrismGrammar.h new file mode 100644 index 000000000..97033f506 --- /dev/null +++ b/src/parser/PrismParser/PrismGrammar.h @@ -0,0 +1,142 @@ +/* + * File: PrismGrammar.h + * Author: nafur + * + * Created on April 30, 2013, 5:20 PM + */ + +#ifndef PRISMGRAMMAR_H +#define PRISMGRAMMAR_H + +// All classes of the intermediate representation are used. +#include "src/ir/IR.h" +#include "src/parser/PrismParser/Includes.h" +#include "src/parser/PrismParser/Tokens.h" +#include "src/parser/PrismParser/IdentifierGrammars.h" +#include "src/parser/PrismParser/VariableState.h" +#include "src/parser/PrismParser/ConstBooleanExpressionGrammar.h" +#include "src/parser/PrismParser/ConstDoubleExpressionGrammar.h" +#include "src/parser/PrismParser/ConstIntegerExpressionGrammar.h" +#include "src/parser/PrismParser/BooleanExpressionGrammar.h" +#include "src/parser/PrismParser/IntegerExpressionGrammar.h" + +// Used for file input. +#include +#include + +namespace storm { +namespace parser { +namespace prism { + +using namespace storm::ir; +using namespace storm::ir::expressions; + +/*! + * The Boost spirit grammar for the PRISM language. Returns the intermediate representation of + * the input that complies with the PRISM syntax. + */ +class PrismGrammar : public qi::grammar< + Iterator, + Program(), + qi::locals< + std::map>, + std::map>, + std::map>, + std::map, + std::map> + >, + Skipper> { +public: + PrismGrammar(); + void prepareForSecondRun(); + void resetGrammars(); + +private: + + std::shared_ptr state; + + // The starting point of the grammar. + qi::rule< + Iterator, + Program(), + qi::locals< + std::map>, + std::map>, + std::map>, + std::map, + std::map> + >, + Skipper> start; + qi::rule modelTypeDefinition; + qi::rule>&, std::map>&, std::map>&), Skipper> constantDefinitionList; + qi::rule(), Skipper> moduleDefinitionList; + + // Rules for module definition. + qi::rule, std::vector, std::map, std::map>, Skipper> moduleDefinition; + qi::rule>, Skipper> moduleRenaming; + + // Rules for variable definitions. + qi::rule&, std::vector&, std::map&, std::map&), Skipper> variableDefinition; + qi::rule&, std::map&), qi::locals>, Skipper> booleanVariableDefinition; + qi::rule&, std::map&), qi::locals>, Skipper> integerVariableDefinition; + + // Rules for command definitions. + qi::rule, Skipper> commandDefinition; + qi::rule(), Skipper> updateListDefinition; + qi::rule, std::map>, Skipper> updateDefinition; + qi::rule&, std::map&), Skipper> assignmentDefinitionList; + qi::rule&, std::map&), Skipper> assignmentDefinition; + + // Rules for variable/command names. + qi::rule commandName; + qi::rule unassignedLocalBooleanVariableName; + qi::rule unassignedLocalIntegerVariableName; + + // Rules for reward definitions. + qi::rule&), Skipper> rewardDefinitionList; + qi::rule&), qi::locals, std::vector>, Skipper> rewardDefinition; + qi::rule stateRewardDefinition; + qi::rule, Skipper> transitionRewardDefinition; + + // Rules for label definitions. + qi::rule>&), Skipper> labelDefinitionList; + qi::rule>&), Skipper> labelDefinition; + + // Rules for constant definitions. + qi::rule(), Skipper> constantDefinition; + qi::rule>&, std::map>&, std::map>&), Skipper> undefinedConstantDefinition; + qi::rule(), Skipper> definedConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedBooleanConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedIntegerConstantDefinition; + qi::rule>&), qi::locals>, Skipper> undefinedDoubleConstantDefinition; + qi::rule(), Skipper> definedBooleanConstantDefinition; + qi::rule(), Skipper> definedIntegerConstantDefinition; + qi::rule(), Skipper> definedDoubleConstantDefinition; + + // Rules for variable recognition. + qi::rule(), Skipper> booleanVariableCreatorExpression; + qi::rule(), qi::locals>, Skipper> integerVariableCreatorExpression; + + storm::parser::prism::keywordsStruct keywords_; + storm::parser::prism::modelTypeStruct modelType_; + storm::parser::prism::relationalOperatorStruct relations_; + + std::shared_ptr addIntegerConstant(const std::string& name, const std::shared_ptr value); + void addLabel(const std::string& name, std::shared_ptr value, std::map>& mapping); + void addBoolAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); + void addIntAssignment(const std::string& variable, std::shared_ptr value, std::map& mapping); + Module renameModule(const std::string& name, const std::string& oldname, std::map& mapping); + Module createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands); + + void createIntegerVariable(const std::string name, std::shared_ptr lower, std::shared_ptr upper, std::shared_ptr init, std::vector& vars, std::map& varids); + void createBooleanVariable(const std::string name, std::shared_ptr init, std::vector& vars, std::map& varids); +}; + + +} // namespace prism +} // namespace parser +} // namespace storm + + +#endif /* PRISMGRAMMAR_H */ + diff --git a/test/parser/ParsePrismTest.cpp b/test/parser/ParsePrismTest.cpp index 4f59be220..b4155edfd 100644 --- a/test/parser/ParsePrismTest.cpp +++ b/test/parser/ParsePrismTest.cpp @@ -4,8 +4,9 @@ #include "src/utility/IoUtility.h" #include "src/ir/Program.h" #include "src/adapters/ExplicitModelAdapter.h" +#include "src/models/Mdp.h" -TEST(ParsePrismTest, parseAndOutput) { +TEST(ParsePrismTest, parseCrowds5_5) { storm::parser::PrismParser parser; storm::ir::Program program; ASSERT_NO_THROW(program = parser.parseFile("examples/dtmc/crowds/crowds5_5.pm")); @@ -17,4 +18,15 @@ TEST(ParsePrismTest, parseAndOutput) { ASSERT_EQ(model->getNumberOfTransitions(), (uint_fast64_t)15113); } +TEST(ParsePrismTest, parseTwoDice) { + storm::parser::PrismParser parser; + storm::ir::Program program; + ASSERT_NO_THROW(program = parser.parseFile("examples/mdp/two_dice/two_dice.nm")); + storm::adapters::ExplicitModelAdapter adapter(program); + std::shared_ptr> model = adapter.getModel()->as>(); + + ASSERT_EQ(model->getNumberOfStates(), (uint_fast64_t)169); + ASSERT_EQ(model->getNumberOfChoices(), (uint_fast64_t)254); + ASSERT_EQ(model->getNumberOfTransitions(), (uint_fast64_t)436); +} From ac86932785f531418ec3fbbfb20013db5aac5a94 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 30 Apr 2013 18:43:47 +0200 Subject: [PATCH 097/152] Fixed renaming: Command names were not considered. --- src/ir/Module.cpp | 11 +------- src/ir/Module.h | 5 ++-- src/parser/PrismParser.cpp | 7 +++-- src/parser/PrismParser/PrismGrammar.cpp | 4 +-- src/parser/PrismParser/VariableState.cpp | 33 +++++++++++++++++++++--- src/parser/PrismParser/VariableState.h | 6 +++-- 6 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index be2ec770f..61c245b26 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -44,16 +44,7 @@ Module::Module(const Module& module, const std::string& moduleName, const std::m LOG4CPLUS_DEBUG(logger, "Start renaming " << module.moduleName << " to " << moduleName); // First step: Create new Variables via the adder. - for (BooleanVariable it: module.booleanVariables) { - if (renaming.count(it.getName()) > 0) { - adder->addBooleanVariable(renaming.at(it.getName()), it.getInitialValue()); - } else LOG4CPLUS_ERROR(logger, moduleName << "." << it.getName() << " was not renamed!"); - } - for (IntegerVariable it: module.integerVariables) { - if (renaming.count(it.getName()) > 0) { - adder->addIntegerVariable(renaming.at(it.getName()), it.getLowerBound(), it.getUpperBound(), it.getInitialValue()); - } else LOG4CPLUS_ERROR(logger, moduleName << "." << it.getName() << " was not renamed!"); - } + adder->performRenaming(renaming); // Second step: Get all indices of variables that are produced by the renaming. for (auto it: renaming) { diff --git a/src/ir/Module.h b/src/ir/Module.h index 6e653ce47..6fbe1658e 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -24,9 +24,10 @@ namespace storm { namespace ir { struct VariableAdder { - virtual uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init) = 0; - virtual uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init) = 0; + virtual uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper) = 0; + virtual uint_fast64_t addBooleanVariable(const std::string& name) = 0; virtual std::shared_ptr getVariable(const std::string& name) = 0; + virtual void performRenaming(const std::map& renaming) = 0; }; /*! diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index ce58bd988..c7b0b9141 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -42,7 +42,6 @@ storm::ir::Program PrismParser::parseFile(std::string const& filename) const { try { result = parse(inputFileStream, filename); } catch(std::exception& e) { - std::cerr << "Exception: " << e.what() << std::endl; // In case of an exception properly close the file before passing exception. inputFileStream.close(); throw e; @@ -91,9 +90,6 @@ storm::ir::Program PrismParser::parse(std::istream& inputStream, std::string con // Reset grammars. grammar.resetGrammars(); } catch(const qi::expectation_failure& e) { - // Reset grammars in any case. - grammar.resetGrammars(); - // If the parser expected content different than the one provided, display information // about the location of the error. const boost::spirit::classic::file_position_base& pos = e.first.get_position(); @@ -117,6 +113,9 @@ storm::ir::Program PrismParser::parse(std::istream& inputStream, std::string con msg << std::endl; std::cerr << msg.str(); + + // Reset grammars in any case. + grammar.resetGrammars(); // Now propagate exception. throw storm::exceptions::WrongFileFormatException() << msg.str(); diff --git a/src/parser/PrismParser/PrismGrammar.cpp b/src/parser/PrismParser/PrismGrammar.cpp index ac3f3dbf4..1fb3ff00e 100644 --- a/src/parser/PrismParser/PrismGrammar.cpp +++ b/src/parser/PrismParser/PrismGrammar.cpp @@ -84,14 +84,14 @@ Module PrismGrammar::createModule(const std::string name, std::vector lower, std::shared_ptr upper, std::shared_ptr init, std::vector& vars, std::map& varids) { //std::cout << "Creating int " << name << " = " << init << std::endl; - uint_fast64_t id = this->state->addIntegerVariable(name, lower, upper, init); + uint_fast64_t id = this->state->addIntegerVariable(name, lower, upper); vars.emplace_back(id, name, lower, upper, init); varids[name] = id; this->state->localIntegerVariables_.add(name, name); } void PrismGrammar::createBooleanVariable(const std::string name, std::shared_ptr init, std::vector& vars, std::map& varids) { //std::cout << "Creating bool " << name << std::endl; - uint_fast64_t id = this->state->addBooleanVariable(name, init); + uint_fast64_t id = this->state->addBooleanVariable(name); vars.emplace_back(id, name, init); varids[name] = id; this->state->localBooleanVariables_.add(name, name); diff --git a/src/parser/PrismParser/VariableState.cpp b/src/parser/PrismParser/VariableState.cpp index dee14bcb3..3634b8954 100644 --- a/src/parser/PrismParser/VariableState.cpp +++ b/src/parser/PrismParser/VariableState.cpp @@ -23,13 +23,18 @@ std::ostream& operator<<(std::ostream& out, qi::symbols& symbols) { symbols.for_each(dump); return out; } +std::ostream& operator<<(std::ostream& out, VariableState::variableNamesStruct& symbols) { + SymbolDump dump(out); + symbols.for_each(dump); + return out; +} VariableState::VariableState(bool firstRun) : firstRun(firstRun), keywords(), nextBooleanVariableIndex(0), nextIntegerVariableIndex(0) { } -uint_fast64_t VariableState::addBooleanVariable(const std::string& name, const std::shared_ptr init) { +uint_fast64_t VariableState::addBooleanVariable(const std::string& name) { if (firstRun) { std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::bool_, this->nextBooleanVariableIndex, name)); LOG4CPLUS_DEBUG(logger, "Adding boolean variable " << name << " with new id " << this->nextBooleanVariableIndex); @@ -48,7 +53,7 @@ uint_fast64_t VariableState::addBooleanVariable(const std::string& name, const s } } -uint_fast64_t VariableState::addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init) { +uint_fast64_t VariableState::addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper) { if (firstRun) { std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::int_, this->nextIntegerVariableIndex, name, lower, upper)); LOG4CPLUS_DEBUG(logger, "Adding integer variable " << name << " with new id " << this->nextIntegerVariableIndex); @@ -106,12 +111,34 @@ std::shared_ptr VariableState::getVariable(const std::string if (res != nullptr) { return *res; } else { - LOG4CPLUS_ERROR(logger, "Getting variable " << name << ", but was not found. This variable does not exist."); return std::shared_ptr(nullptr); } } } +void VariableState::performRenaming(const std::map& renaming) { + for (auto it: renaming) { + std::shared_ptr* original = this->integerVariables_.find(it.first); + if (original != nullptr) { + std::shared_ptr* next = this->integerVariables_.find(it.second); + if (next == nullptr) { + this->addIntegerVariable(it.second, (*original)->getLowerBound(), (*original)->getUpperBound()); + } + } + original = this->booleanVariables_.find(it.first); + if (original != nullptr) { + if (this->booleanVariables_.find(it.second) == nullptr) { + this->addBooleanVariable(it.second); + } + } + std::string* oldCmdName = this->commandNames_.find(it.first); + if (oldCmdName != nullptr) { + LOG4CPLUS_DEBUG(logger, "Adding new command name " << it.second << " due to module renaming."); + this->commandNames_.at(it.second) = it.second; + } + } +} + void VariableState::startModule() { this->localBooleanVariables_.clear(); this->localIntegerVariables_.clear(); diff --git a/src/parser/PrismParser/VariableState.h b/src/parser/PrismParser/VariableState.h index c4046e658..620c029ff 100644 --- a/src/parser/PrismParser/VariableState.h +++ b/src/parser/PrismParser/VariableState.h @@ -46,13 +46,15 @@ public: struct variableNamesStruct : qi::symbols { } integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_, localBooleanVariables_, localIntegerVariables_, assignedLocalBooleanVariables_, assignedLocalIntegerVariables_; public: - uint_fast64_t addBooleanVariable(const std::string& name, const std::shared_ptr init); - uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper, const std::shared_ptr init); + uint_fast64_t addBooleanVariable(const std::string& name); + uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper); std::shared_ptr getBooleanVariable(const std::string& name); std::shared_ptr getIntegerVariable(const std::string& name); std::shared_ptr getVariable(const std::string& name); + void performRenaming(const std::map& renaming); + void startModule(); bool isFreeIdentifier(std::string& s) const; From 966377ae32f10c3a4bd74c98a77f7e1d8ecc0de0 Mon Sep 17 00:00:00 2001 From: gereon Date: Tue, 30 Apr 2013 18:46:38 +0200 Subject: [PATCH 098/152] Added a few more example files. --- examples/dtmc/crowds/crowds10_5.pm | 80 +++++++++++++ examples/dtmc/crowds/crowds15_5.pm | 95 +++++++++++++++ examples/dtmc/crowds/crowds20_5.pm | 110 ++++++++++++++++++ examples/dtmc/synchronous_leader/leader3_5.pm | 85 ++++++++++++++ examples/dtmc/synchronous_leader/leader4_8.pm | 89 ++++++++++++++ examples/dtmc/synchronous_leader/leader5_8.pm | 90 ++++++++++++++ examples/dtmc/synchronous_leader/leader6_8.pm | 91 +++++++++++++++ 7 files changed, 640 insertions(+) create mode 100644 examples/dtmc/crowds/crowds10_5.pm create mode 100644 examples/dtmc/crowds/crowds15_5.pm create mode 100644 examples/dtmc/crowds/crowds20_5.pm create mode 100644 examples/dtmc/synchronous_leader/leader3_5.pm create mode 100644 examples/dtmc/synchronous_leader/leader4_8.pm create mode 100644 examples/dtmc/synchronous_leader/leader5_8.pm create mode 100644 examples/dtmc/synchronous_leader/leader6_8.pm diff --git a/examples/dtmc/crowds/crowds10_5.pm b/examples/dtmc/crowds/crowds10_5.pm new file mode 100644 index 000000000..752b3f9bb --- /dev/null +++ b/examples/dtmc/crowds/crowds10_5.pm @@ -0,0 +1,80 @@ +dtmc + +// probability of forwarding +const double PF = 0.8; +const double notPF = .2; // must be 1-PF +// probability that a crowd member is bad +const double badC = .167; + // probability that a crowd member is good +const double goodC = 0.833; +// Total number of protocol runs to analyze +const int TotalRuns = 5; +// size of the crowd +const int CrowdSize = 10; + +module crowds + // protocol phase + phase: [0..4] init 0; + + // crowd member good (or bad) + good: bool init false; + + // number of protocol runs + runCount: [0..TotalRuns] init 0; + + // observe_i is the number of times the attacker observed crowd member i + observe0: [0..TotalRuns] init 0; + + observe1: [0..TotalRuns] init 0; + + observe2: [0..TotalRuns] init 0; + + observe3: [0..TotalRuns] init 0; + + observe4: [0..TotalRuns] init 0; + + observe5: [0..TotalRuns] init 0; + + observe6: [0..TotalRuns] init 0; + + observe7: [0..TotalRuns] init 0; + + observe8: [0..TotalRuns] init 0; + + observe9: [0..TotalRuns] init 0; + + // the last seen crowd member + lastSeen: [0..CrowdSize - 1] init 0; + + // get the protocol started + [] phase=0 & runCount (phase'=1) & (runCount'=runCount+1) & (lastSeen'=0); + + // decide whether crowd member is good or bad according to given probabilities + [] phase=1 -> goodC : (phase'=2) & (good'=true) + badC : (phase'=2) & (good'=false); + + // if the current member is a good member, update the last seen index (chosen uniformly) + [] phase=2 & good -> 1/10 : (lastSeen'=0) & (phase'=3) + 1/10 : (lastSeen'=1) & (phase'=3) + 1/10 : (lastSeen'=2) & (phase'=3) + 1/10 : (lastSeen'=3) & (phase'=3) + 1/10 : (lastSeen'=4) & (phase'=3) + 1/10 : (lastSeen'=5) & (phase'=3) + 1/10 : (lastSeen'=6) & (phase'=3) + 1/10 : (lastSeen'=7) & (phase'=3) + 1/10 : (lastSeen'=8) & (phase'=3) + 1/10 : (lastSeen'=9) & (phase'=3); + + // if the current member is a bad member, record the most recently seen index + [] phase=2 & !good & lastSeen=0 & observe0 < TotalRuns -> (observe0'=observe0+1) & (phase'=4); + [] phase=2 & !good & lastSeen=1 & observe1 < TotalRuns -> (observe1'=observe1+1) & (phase'=4); + [] phase=2 & !good & lastSeen=2 & observe2 < TotalRuns -> (observe2'=observe2+1) & (phase'=4); + [] phase=2 & !good & lastSeen=3 & observe3 < TotalRuns -> (observe3'=observe3+1) & (phase'=4); + [] phase=2 & !good & lastSeen=4 & observe4 < TotalRuns -> (observe4'=observe4+1) & (phase'=4); + [] phase=2 & !good & lastSeen=5 & observe5 < TotalRuns -> (observe5'=observe5+1) & (phase'=4); + [] phase=2 & !good & lastSeen=6 & observe6 < TotalRuns -> (observe6'=observe6+1) & (phase'=4); + [] phase=2 & !good & lastSeen=7 & observe7 < TotalRuns -> (observe7'=observe7+1) & (phase'=4); + [] phase=2 & !good & lastSeen=8 & observe8 < TotalRuns -> (observe8'=observe8+1) & (phase'=4); + [] phase=2 & !good & lastSeen=9 & observe9 < TotalRuns -> (observe9'=observe9+1) & (phase'=4); + + // good crowd members forward with probability PF and deliver otherwise + [] phase=3 -> PF : (phase'=1) + notPF : (phase'=4); + + // deliver the message and start over + [] phase=4 -> (phase'=0); + +endmodule + +label "observe0Greater1" = observe0 > 1; +label "observeIGreater1" = observe1 > 1 | observe2 > 1 | observe3 > 1 | observe4 > 1 | observe5 > 1 | observe6 > 1 | observe7 > 1 | observe8 > 1 | observe9 > 1; +label "observeOnlyTrueSender" = observe0 > 1 & observe1 <= 1 & observe2 <= 1 & observe3 <= 1 & observe4 <= 1 & observe5 <= 1 & observe6 <= 1 & observe7 <= 1 & observe8 <= 1 & observe9 <= 1; \ No newline at end of file diff --git a/examples/dtmc/crowds/crowds15_5.pm b/examples/dtmc/crowds/crowds15_5.pm new file mode 100644 index 000000000..511d962f0 --- /dev/null +++ b/examples/dtmc/crowds/crowds15_5.pm @@ -0,0 +1,95 @@ +dtmc + +// probability of forwarding +const double PF = 0.8; +const double notPF = .2; // must be 1-PF +// probability that a crowd member is bad +const double badC = .167; + // probability that a crowd member is good +const double goodC = 0.833; +// Total number of protocol runs to analyze +const int TotalRuns = 5; +// size of the crowd +const int CrowdSize = 15; + +module crowds + // protocol phase + phase: [0..4] init 0; + + // crowd member good (or bad) + good: bool init false; + + // number of protocol runs + runCount: [0..TotalRuns] init 0; + + // observe_i is the number of times the attacker observed crowd member i + observe0: [0..TotalRuns] init 0; + + observe1: [0..TotalRuns] init 0; + + observe2: [0..TotalRuns] init 0; + + observe3: [0..TotalRuns] init 0; + + observe4: [0..TotalRuns] init 0; + + observe5: [0..TotalRuns] init 0; + + observe6: [0..TotalRuns] init 0; + + observe7: [0..TotalRuns] init 0; + + observe8: [0..TotalRuns] init 0; + + observe9: [0..TotalRuns] init 0; + + observe10: [0..TotalRuns] init 0; + + observe11: [0..TotalRuns] init 0; + + observe12: [0..TotalRuns] init 0; + + observe13: [0..TotalRuns] init 0; + + observe14: [0..TotalRuns] init 0; + + // the last seen crowd member + lastSeen: [0..CrowdSize - 1] init 0; + + // get the protocol started + [] phase=0 & runCount 1: (phase'=1) & (runCount'=runCount+1) & (lastSeen'=0); + + // decide whether crowd member is good or bad according to given probabilities + [] phase=1 -> goodC : (phase'=2) & (good'=true) + badC : (phase'=2) & (good'=false); + + // if the current member is a good member, update the last seen index (chosen uniformly) + [] phase=2 & good -> 1/15 : (lastSeen'=0) & (phase'=3) + 1/15 : (lastSeen'=1) & (phase'=3) + 1/15 : (lastSeen'=2) & (phase'=3) + 1/15 : (lastSeen'=3) & (phase'=3) + 1/15 : (lastSeen'=4) & (phase'=3) + 1/15 : (lastSeen'=5) & (phase'=3) + 1/15 : (lastSeen'=6) & (phase'=3) + 1/15 : (lastSeen'=7) & (phase'=3) + 1/15 : (lastSeen'=8) & (phase'=3) + 1/15 : (lastSeen'=9) & (phase'=3) + 1/15 : (lastSeen'=10) & (phase'=3) + 1/15 : (lastSeen'=11) & (phase'=3) + 1/15 : (lastSeen'=12) & (phase'=3) + 1/15 : (lastSeen'=13) & (phase'=3) + 1/15 : (lastSeen'=14) & (phase'=3); + + // if the current member is a bad member, record the most recently seen index + [] phase=2 & !good & lastSeen=0 & observe0 < TotalRuns -> 1: (observe0'=observe0+1) & (phase'=4); + [] phase=2 & !good & lastSeen=1 & observe1 < TotalRuns -> 1: (observe1'=observe1+1) & (phase'=4); + [] phase=2 & !good & lastSeen=2 & observe2 < TotalRuns -> 1: (observe2'=observe2+1) & (phase'=4); + [] phase=2 & !good & lastSeen=3 & observe3 < TotalRuns -> 1: (observe3'=observe3+1) & (phase'=4); + [] phase=2 & !good & lastSeen=4 & observe4 < TotalRuns -> 1: (observe4'=observe4+1) & (phase'=4); + [] phase=2 & !good & lastSeen=5 & observe5 < TotalRuns -> 1: (observe5'=observe5+1) & (phase'=4); + [] phase=2 & !good & lastSeen=6 & observe6 < TotalRuns -> 1: (observe6'=observe6+1) & (phase'=4); + [] phase=2 & !good & lastSeen=7 & observe7 < TotalRuns -> 1: (observe7'=observe7+1) & (phase'=4); + [] phase=2 & !good & lastSeen=8 & observe8 < TotalRuns -> 1: (observe8'=observe8+1) & (phase'=4); + [] phase=2 & !good & lastSeen=9 & observe9 < TotalRuns -> 1: (observe9'=observe9+1) & (phase'=4); + [] phase=2 & !good & lastSeen=10 & observe10 < TotalRuns -> 1: (observe10'=observe10+1) & (phase'=4); + [] phase=2 & !good & lastSeen=11 & observe11 < TotalRuns -> 1: (observe11'=observe11+1) & (phase'=4); + [] phase=2 & !good & lastSeen=12 & observe12 < TotalRuns -> 1: (observe12'=observe12+1) & (phase'=4); + [] phase=2 & !good & lastSeen=13 & observe13 < TotalRuns -> 1: (observe13'=observe13+1) & (phase'=4); + [] phase=2 & !good & lastSeen=14 & observe14 < TotalRuns -> 1: (observe14'=observe14+1) & (phase'=4); + + // good crowd members forward with probability PF and deliver otherwise + [] phase=3 -> PF : (phase'=1) + notPF : (phase'=4); + + // deliver the message and start over + [] phase=4 -> 1: (phase'=0); + +endmodule + +label "observe0Greater1" = observe0 > 1; +label "observeIGreater1" = observe1 > 1 | observe2 > 1 | observe3 > 1 | observe4 > 1 | observe5 > 1 | observe6 > 1 | observe7 > 1 | observe8 > 1 | observe9 > 1 | observe10 > 1 | observe11 > 1 | observe12 > 1 | observe13 > 1 | observe14 > 1; +label "observeOnlyTrueSender" = observe0 > 1 & observe1 <= 1 & observe2 <= 1 & observe3 <= 1 & observe4 <= 1 & observe5 <= 1 & observe6 <= 1 & observe7 <= 1 & observe8 <= 1 & observe9 <= 1 & observe10 <= 1 & observe11 <= 1 & observe12 <= 1 & observe13 <= 1 & observe14 <= 1; \ No newline at end of file diff --git a/examples/dtmc/crowds/crowds20_5.pm b/examples/dtmc/crowds/crowds20_5.pm new file mode 100644 index 000000000..31c63770a --- /dev/null +++ b/examples/dtmc/crowds/crowds20_5.pm @@ -0,0 +1,110 @@ +dtmc + +// probability of forwarding +const double PF = 0.8; +const double notPF = .2; // must be 1-PF +// probability that a crowd member is bad +const double badC = .167; + // probability that a crowd member is good +const double goodC = 0.833; +// Total number of protocol runs to analyze +const int TotalRuns = 5; +// size of the crowd +const int CrowdSize = 20; + +module crowds + // protocol phase + phase: [0..4] init 0; + + // crowd member good (or bad) + good: bool init false; + + // number of protocol runs + runCount: [0..TotalRuns] init 0; + + // observe_i is the number of times the attacker observed crowd member i + observe0: [0..TotalRuns] init 0; + + observe1: [0..TotalRuns] init 0; + + observe2: [0..TotalRuns] init 0; + + observe3: [0..TotalRuns] init 0; + + observe4: [0..TotalRuns] init 0; + + observe5: [0..TotalRuns] init 0; + + observe6: [0..TotalRuns] init 0; + + observe7: [0..TotalRuns] init 0; + + observe8: [0..TotalRuns] init 0; + + observe9: [0..TotalRuns] init 0; + + observe10: [0..TotalRuns] init 0; + + observe11: [0..TotalRuns] init 0; + + observe12: [0..TotalRuns] init 0; + + observe13: [0..TotalRuns] init 0; + + observe14: [0..TotalRuns] init 0; + + observe15: [0..TotalRuns] init 0; + + observe16: [0..TotalRuns] init 0; + + observe17: [0..TotalRuns] init 0; + + observe18: [0..TotalRuns] init 0; + + observe19: [0..TotalRuns] init 0; + + // the last seen crowd member + lastSeen: [0..CrowdSize - 1] init 0; + + // get the protocol started + [] phase=0 & runCount 1:(phase'=1) & (runCount'=runCount+1) & (lastSeen'=0); + + // decide whether crowd member is good or bad according to given probabilities + [] phase=1 -> goodC : (phase'=2) & (good'=true) + badC : (phase'=2) & (good'=false); + + // if the current member is a good member, update the last seen index (chosen uniformly) + [] phase=2 & good -> 1/20 : (lastSeen'=0) & (phase'=3) + 1/20 : (lastSeen'=1) & (phase'=3) + 1/20 : (lastSeen'=2) & (phase'=3) + 1/20 : (lastSeen'=3) & (phase'=3) + 1/20 : (lastSeen'=4) & (phase'=3) + 1/20 : (lastSeen'=5) & (phase'=3) + 1/20 : (lastSeen'=6) & (phase'=3) + 1/20 : (lastSeen'=7) & (phase'=3) + 1/20 : (lastSeen'=8) & (phase'=3) + 1/20 : (lastSeen'=9) & (phase'=3) + 1/20 : (lastSeen'=10) & (phase'=3) + 1/20 : (lastSeen'=11) & (phase'=3) + 1/20 : (lastSeen'=12) & (phase'=3) + 1/20 : (lastSeen'=13) & (phase'=3) + 1/20 : (lastSeen'=14) & (phase'=3) + 1/20 : (lastSeen'=15) & (phase'=3) + 1/20 : (lastSeen'=16) & (phase'=3) + 1/20 : (lastSeen'=17) & (phase'=3) + 1/20 : (lastSeen'=18) & (phase'=3) + 1/20 : (lastSeen'=19) & (phase'=3); + + // if the current member is a bad member, record the most recently seen index + [] phase=2 & !good & lastSeen=0 & observe0 < TotalRuns -> 1:(observe0'=observe0+1) & (phase'=4); + [] phase=2 & !good & lastSeen=1 & observe1 < TotalRuns -> 1:(observe1'=observe1+1) & (phase'=4); + [] phase=2 & !good & lastSeen=2 & observe2 < TotalRuns -> 1:(observe2'=observe2+1) & (phase'=4); + [] phase=2 & !good & lastSeen=3 & observe3 < TotalRuns -> 1:(observe3'=observe3+1) & (phase'=4); + [] phase=2 & !good & lastSeen=4 & observe4 < TotalRuns -> 1:(observe4'=observe4+1) & (phase'=4); + [] phase=2 & !good & lastSeen=5 & observe5 < TotalRuns -> 1:(observe5'=observe5+1) & (phase'=4); + [] phase=2 & !good & lastSeen=6 & observe6 < TotalRuns -> 1:(observe6'=observe6+1) & (phase'=4); + [] phase=2 & !good & lastSeen=7 & observe7 < TotalRuns -> 1:(observe7'=observe7+1) & (phase'=4); + [] phase=2 & !good & lastSeen=8 & observe8 < TotalRuns -> 1:(observe8'=observe8+1) & (phase'=4); + [] phase=2 & !good & lastSeen=9 & observe9 < TotalRuns -> 1:(observe9'=observe9+1) & (phase'=4); + [] phase=2 & !good & lastSeen=10 & observe10 < TotalRuns -> 1:(observe10'=observe10+1) & (phase'=4); + [] phase=2 & !good & lastSeen=11 & observe11 < TotalRuns -> 1:(observe11'=observe11+1) & (phase'=4); + [] phase=2 & !good & lastSeen=12 & observe12 < TotalRuns -> 1:(observe12'=observe12+1) & (phase'=4); + [] phase=2 & !good & lastSeen=13 & observe13 < TotalRuns -> 1:(observe13'=observe13+1) & (phase'=4); + [] phase=2 & !good & lastSeen=14 & observe14 < TotalRuns -> 1:(observe14'=observe14+1) & (phase'=4); + [] phase=2 & !good & lastSeen=15 & observe15 < TotalRuns -> 1:(observe15'=observe15+1) & (phase'=4); + [] phase=2 & !good & lastSeen=16 & observe16 < TotalRuns -> 1:(observe16'=observe16+1) & (phase'=4); + [] phase=2 & !good & lastSeen=17 & observe17 < TotalRuns -> 1:(observe17'=observe17+1) & (phase'=4); + [] phase=2 & !good & lastSeen=18 & observe18 < TotalRuns -> 1:(observe18'=observe18+1) & (phase'=4); + [] phase=2 & !good & lastSeen=19 & observe19 < TotalRuns -> 1:(observe19'=observe19+1) & (phase'=4); + + // good crowd members forward with probability PF and deliver otherwise + [] phase=3 -> PF : (phase'=1) + notPF : (phase'=4); + + // deliver the message and start over + [] phase=4 -> 1:(phase'=0); + +endmodule + +label "observe0Greater1" = observe0 > 1; +label "observeIGreater1" = observe1 > 1 | observe2 > 1 | observe3 > 1 | observe4 > 1 | observe5 > 1 | observe6 > 1 | observe7 > 1 | observe8 > 1 | observe9 > 1 | observe10 > 1 | observe11 > 1 | observe12 > 1 | observe13 > 1 | observe14 > 1 | observe15 > 1 | observe16 > 1 | observe17 > 1 | observe18 > 1 | observe19 > 1; +label "observeOnlyTrueSender" = observe0 > 1 & observe1 <= 1 & observe2 <= 1 & observe3 <= 1 & observe4 <= 1 & observe5 <= 1 & observe6 <= 1 & observe7 <= 1 & observe8 <= 1 & observe9 <= 1 & observe10 <= 1 & observe11 <= 1 & observe12 <= 1 & observe13 <= 1 & observe14 <= 1 & observe15 <= 1 & observe16 <= 1 & observe17 <= 1 & observe18 <= 1 & observe19 <= 1; \ No newline at end of file diff --git a/examples/dtmc/synchronous_leader/leader3_5.pm b/examples/dtmc/synchronous_leader/leader3_5.pm new file mode 100644 index 000000000..2a5e200dc --- /dev/null +++ b/examples/dtmc/synchronous_leader/leader3_5.pm @@ -0,0 +1,85 @@ +// synchronous leader election protocol (itai & Rodeh) +// dxp/gxn 25/01/01 + +dtmc + +// CONSTANTS +const int N = 3; // number of processes +const int K = 5; // range of probabilistic choice + +// counter module used to count the number of processes that have been read +// and to know when a process has decided +module counter + + // counter (c=i means process j reading process (i-1)+j next) + c : [1..N-1]; + + // reading + [read] c (c'=c+1); + // finished reading + [read] c=N-1 -> (c'=c); + //decide + [done] u1|u2|u3 -> (c'=c); + // pick again reset counter + [retry] !(u1|u2|u3) -> (c'=1); + // loop (when finished to avoid deadlocks) + [loop] s1=3 -> (c'=c); + +endmodule + +// processes form a ring and suppose: +// process 1 reads process 2 +// process 2 reads process 3 +// process 3 reads process 1 +module process1 + + // local state + s1 : [0..3]; + // s1=0 make random choice + // s1=1 reading + // s1=2 deciding + // s1=3 finished + + // has a unique id so far (initially true) + u1 : bool; + + // value to be sent to next process in the ring (initially sets this to its own value) + v1 : [0..K-1]; + + // random choice + p1 : [0..K-1]; + + // pick value + [pick] s1=0 -> 1/K : (s1'=1) & (p1'=0) & (v1'=0) & (u1'=true) + + 1/K : (s1'=1) & (p1'=1) & (v1'=1) & (u1'=true) + + 1/K : (s1'=1) & (p1'=2) & (v1'=2) & (u1'=true) + + 1/K : (s1'=1) & (p1'=3) & (v1'=3) & (u1'=true) + + 1/K : (s1'=1) & (p1'=4) & (v1'=4) & (u1'=true); + // read + [read] s1=1 & u1 & c (u1'=(p1!=v2)) & (v1'=v2); + [read] s1=1 & !u1 & c (u1'=false) & (v1'=v2) & (p1'=0); + // read and move to decide + [read] s1=1 & u1 & c=N-1 -> (s1'=2) & (u1'=(p1!=v2)) & (v1'=0) & (p1'=0); + [read] s1=1 & !u1 & c=N-1 -> (s1'=2) & (u1'=false) & (v1'=0); + // deciding + // done + [done] s1=2 -> (s1'=3) & (u1'=false) & (v1'=0) & (p1'=0); + //retry + [retry] s1=2 -> (s1'=0) & (u1'=false) & (v1'=0) & (p1'=0); + // loop (when finished to avoid deadlocks) + [loop] s1=3 -> (s1'=3); + +endmodule + +// construct remaining processes through renaming +module process2 = process1 [ s1=s2,p1=p2,v1=v2,u1=u2,v2=v3 ] endmodule +module process3 = process1 [ s1=s3,p1=p3,v1=v3,u1=u3,v2=v1 ] endmodule + +// expected number of rounds +rewards "num_rounds" + [pick] true : 1; +endrewards + +// labels +label "elected" = s1=3&s2=3&s3=3; + diff --git a/examples/dtmc/synchronous_leader/leader4_8.pm b/examples/dtmc/synchronous_leader/leader4_8.pm new file mode 100644 index 000000000..fc8f167a0 --- /dev/null +++ b/examples/dtmc/synchronous_leader/leader4_8.pm @@ -0,0 +1,89 @@ +// synchronous leader election protocol (itai & Rodeh) +// dxp/gxn 25/01/01 + +dtmc + +// CONSTANTS +const N = 4; // number of processes +const K = 8; // range of probabilistic choice + +// counter module used to count the number of processes that have been read +// and to know when a process has decided +module counter + + // counter (c=i means process j reading process (i-1)+j next) + c : [1..N-1]; + + // reading + [read] c (c'=c+1); + // finished reading + [read] c=N-1 -> (c'=c); + //decide + [done] u1|u2|u3|u4 -> (c'=c); + // pick again reset counter + [retry] !(u1|u2|u3|u4) -> (c'=1); + // loop (when finished to avoid deadlocks) + [loop] s1=3 -> (c'=c); + +endmodule + +// processes form a ring and suppose: +// process 1 reads process 2 +// process 2 reads process 3 +// process 3 reads process 1 +module process1 + + // local state + s1 : [0..3]; + // s1=0 make random choice + // s1=1 reading + // s1=2 deciding + // s1=3 finished + + // has a unique id so far (initially true) + u1 : bool; + + // value to be sent to next process in the ring (initially sets this to its own value) + v1 : [0..K-1]; + + // random choice + p1 : [0..K-1]; + + // pick value + [pick] s1=0 -> 1/K : (s1'=1) & (p1'=0) & (v1'=0) & (u1'=true) + + 1/K : (s1'=1) & (p1'=1) & (v1'=1) & (u1'=true) + + 1/K : (s1'=1) & (p1'=2) & (v1'=2) & (u1'=true) + + 1/K : (s1'=1) & (p1'=3) & (v1'=3) & (u1'=true) + + 1/K : (s1'=1) & (p1'=4) & (v1'=4) & (u1'=true) + + 1/K : (s1'=1) & (p1'=5) & (v1'=5) & (u1'=true) + + 1/K : (s1'=1) & (p1'=6) & (v1'=6) & (u1'=true) + + 1/K : (s1'=1) & (p1'=7) & (v1'=7) & (u1'=true); + // read + [read] s1=1 & u1 & c (u1'=(p1!=v2)) & (v1'=v2); + [read] s1=1 & !u1 & c (u1'=false) & (v1'=v2) & (p1'=0); + // read and move to decide + [read] s1=1 & u1 & c=N-1 -> (s1'=2) & (u1'=(p1!=v2)) & (v1'=0) & (p1'=0); + [read] s1=1 & !u1 & c=N-1 -> (s1'=2) & (u1'=false) & (v1'=0); + // deciding + // done + [done] s1=2 -> (s1'=3) & (u1'=false) & (v1'=0) & (p1'=0); + //retry + [retry] s1=2 -> (s1'=0) & (u1'=false) & (v1'=0) & (p1'=0); + // loop (when finished to avoid deadlocks) + [loop] s1=3 -> (s1'=3); + +endmodule + +// construct remaining processes through renaming +module process2 = process1 [ s1=s2,p1=p2,v1=v2,u1=u2,v2=v3 ] endmodule +module process3 = process1 [ s1=s3,p1=p3,v1=v3,u1=u3,v2=v4 ] endmodule +module process4 = process1 [ s1=s4,p1=p4,v1=v4,u1=u4,v2=v1 ] endmodule + +// expected number of rounds +rewards "num_rounds" + [pick] true : 1; +endrewards + +// labels +label "elected" = s1=3&s2=3&s3=3&s4=3; + diff --git a/examples/dtmc/synchronous_leader/leader5_8.pm b/examples/dtmc/synchronous_leader/leader5_8.pm new file mode 100644 index 000000000..72139fda9 --- /dev/null +++ b/examples/dtmc/synchronous_leader/leader5_8.pm @@ -0,0 +1,90 @@ +// synchronous leader election protocol (itai & Rodeh) +// dxp/gxn 25/01/01 + +dtmc + +// CONSTANTS +const N = 5; // number of processes +const K = 8; // range of probabilistic choice + +// counter module used to count the number of processes that have been read +// and to know when a process has decided +module counter + + // counter (c=i means process j reading process (i-1)+j next) + c : [1..N-1]; + + // reading + [read] c (c'=c+1); + // finished reading + [read] c=N-1 -> (c'=c); + //decide + [done] u1|u2|u3|u4|u5 -> (c'=c); + // pick again reset counter + [retry] !(u1|u2|u3|u4|u5) -> (c'=1); + // loop (when finished to avoid deadlocks) + [loop] s1=3 -> (c'=c); + +endmodule + +// processes form a ring and suppose: +// process 1 reads process 2 +// process 2 reads process 3 +// process 3 reads process 1 +module process1 + + // local state + s1 : [0..3]; + // s1=0 make random choice + // s1=1 reading + // s1=2 deciding + // s1=3 finished + + // has a unique id so far (initially true) + u1 : bool; + + // value to be sent to next process in the ring (initially sets this to its own value) + v1 : [0..K-1]; + + // random choice + p1 : [0..K-1]; + + // pick value + [pick] s1=0 -> 1/K : (s1'=1) & (p1'=0) & (v1'=0) & (u1'=true) + + 1/K : (s1'=1) & (p1'=1) & (v1'=1) & (u1'=true) + + 1/K : (s1'=1) & (p1'=2) & (v1'=2) & (u1'=true) + + 1/K : (s1'=1) & (p1'=3) & (v1'=3) & (u1'=true) + + 1/K : (s1'=1) & (p1'=4) & (v1'=4) & (u1'=true) + + 1/K : (s1'=1) & (p1'=5) & (v1'=5) & (u1'=true) + + 1/K : (s1'=1) & (p1'=6) & (v1'=6) & (u1'=true) + + 1/K : (s1'=1) & (p1'=7) & (v1'=7) & (u1'=true); + // read + [read] s1=1 & u1 & c (u1'=(p1!=v2)) & (v1'=v2); + [read] s1=1 & !u1 & c (u1'=false) & (v1'=v2) & (p1'=0); + // read and move to decide + [read] s1=1 & u1 & c=N-1 -> (s1'=2) & (u1'=(p1!=v2)) & (v1'=0) & (p1'=0); + [read] s1=1 & !u1 & c=N-1 -> (s1'=2) & (u1'=false) & (v1'=0); + // deciding + // done + [done] s1=2 -> (s1'=3) & (u1'=false) & (v1'=0) & (p1'=0); + //retry + [retry] s1=2 -> (s1'=0) & (u1'=false) & (v1'=0) & (p1'=0); + // loop (when finished to avoid deadlocks) + [loop] s1=3 -> (s1'=3); + +endmodule + +// construct remaining processes through renaming +module process2 = process1 [ s1=s2,p1=p2,v1=v2,u1=u2,v2=v3 ] endmodule +module process3 = process1 [ s1=s3,p1=p3,v1=v3,u1=u3,v2=v4 ] endmodule +module process4 = process1 [ s1=s4,p1=p4,v1=v4,u1=u4,v2=v5 ] endmodule +module process5 = process1 [ s1=s5,p1=p5,v1=v5,u1=u5,v2=v1 ] endmodule + +// expected number of rounds +rewards "num_rounds" + [pick] true : 1; +endrewards + +// labels +label "elected" = s1=3&s2=3&s3=3&s4=3&s5=3; + diff --git a/examples/dtmc/synchronous_leader/leader6_8.pm b/examples/dtmc/synchronous_leader/leader6_8.pm new file mode 100644 index 000000000..283042ad5 --- /dev/null +++ b/examples/dtmc/synchronous_leader/leader6_8.pm @@ -0,0 +1,91 @@ +// synchronous leader election protocol (itai & Rodeh) +// dxp/gxn 25/01/01 + +dtmc + +// CONSTANTS +const N = 6; // number of processes +const K = 8; // range of probabilistic choice + +// counter module used to count the number of processes that have been read +// and to know when a process has decided +module counter + + // counter (c=i means process j reading process (i-1)+j next) + c : [1..N-1]; + + // reading + [read] c (c'=c+1); + // finished reading + [read] c=N-1 -> (c'=c); + //decide + [done] u1|u2|u3|u4|u5|u6 -> (c'=c); + // pick again reset counter + [retry] !(u1|u2|u3|u4|u5|u6) -> (c'=1); + // loop (when finished to avoid deadlocks) + [loop] s1=3 -> (c'=c); + +endmodule + +// processes form a ring and suppose: +// process 1 reads process 2 +// process 2 reads process 3 +// process 3 reads process 1 +module process1 + + // local state + s1 : [0..3]; + // s1=0 make random choice + // s1=1 reading + // s1=2 deciding + // s1=3 finished + + // has a unique id so far (initially true) + u1 : bool; + + // value to be sent to next process in the ring (initially sets this to its own value) + v1 : [0..K-1]; + + // random choice + p1 : [0..K-1]; + + // pick value + [pick] s1=0 -> 1/K : (s1'=1) & (p1'=0) & (v1'=0) & (u1'=true) + + 1/K : (s1'=1) & (p1'=1) & (v1'=1) & (u1'=true) + + 1/K : (s1'=1) & (p1'=2) & (v1'=2) & (u1'=true) + + 1/K : (s1'=1) & (p1'=3) & (v1'=3) & (u1'=true) + + 1/K : (s1'=1) & (p1'=4) & (v1'=4) & (u1'=true) + + 1/K : (s1'=1) & (p1'=5) & (v1'=5) & (u1'=true) + + 1/K : (s1'=1) & (p1'=6) & (v1'=6) & (u1'=true) + + 1/K : (s1'=1) & (p1'=7) & (v1'=7) & (u1'=true); + // read + [read] s1=1 & u1 & c (u1'=(p1!=v2)) & (v1'=v2); + [read] s1=1 & !u1 & c (u1'=false) & (v1'=v2) & (p1'=0); + // read and move to decide + [read] s1=1 & u1 & c=N-1 -> (s1'=2) & (u1'=(p1!=v2)) & (v1'=0) & (p1'=0); + [read] s1=1 & !u1 & c=N-1 -> (s1'=2) & (u1'=false) & (v1'=0); + // deciding + // done + [done] s1=2 -> (s1'=3) & (u1'=false) & (v1'=0) & (p1'=0); + //retry + [retry] s1=2 -> (s1'=0) & (u1'=false) & (v1'=0) & (p1'=0); + // loop (when finished to avoid deadlocks) + [loop] s1=3 -> (s1'=3); + +endmodule + +// construct remaining processes through renaming +module process2 = process1 [ s1=s2,p1=p2,v1=v2,u1=u2,v2=v3 ] endmodule +module process3 = process1 [ s1=s3,p1=p3,v1=v3,u1=u3,v2=v4 ] endmodule +module process4 = process1 [ s1=s4,p1=p4,v1=v4,u1=u4,v2=v5 ] endmodule +module process5 = process1 [ s1=s5,p1=p5,v1=v5,u1=u5,v2=v6 ] endmodule +module process6 = process1 [ s1=s6,p1=p6,v1=v6,u1=u6,v2=v1 ] endmodule + +// expected number of rounds +rewards "num_rounds" + [pick] true : 1; +endrewards + +// labels +label "elected" = s1=3&s2=3&s3=3&s4=3&s5=3&s6=3; + From 3ff9514f7bfbc895b9995413d483568760ba673b Mon Sep 17 00:00:00 2001 From: gereon Date: Wed, 1 May 2013 02:00:10 +0200 Subject: [PATCH 099/152] Make clone() work for variables without initial value. --- examples/dtmc/synchronous_leader/leader3_5.pm | 24 +++++++++---------- src/ir/Variable.cpp | 8 +++++-- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/examples/dtmc/synchronous_leader/leader3_5.pm b/examples/dtmc/synchronous_leader/leader3_5.pm index 2a5e200dc..0703e733d 100644 --- a/examples/dtmc/synchronous_leader/leader3_5.pm +++ b/examples/dtmc/synchronous_leader/leader3_5.pm @@ -15,15 +15,15 @@ module counter c : [1..N-1]; // reading - [read] c (c'=c+1); + [read] c 1:(c'=c+1); // finished reading - [read] c=N-1 -> (c'=c); + [read] c=N-1 -> 1:(c'=c); //decide - [done] u1|u2|u3 -> (c'=c); + [done] u1|u2|u3 -> 1:(c'=c); // pick again reset counter - [retry] !(u1|u2|u3) -> (c'=1); + [retry] !(u1|u2|u3) -> 1:(c'=1); // loop (when finished to avoid deadlocks) - [loop] s1=3 -> (c'=c); + [loop] s1=3 -> 1:(c'=c); endmodule @@ -56,18 +56,18 @@ module process1 + 1/K : (s1'=1) & (p1'=3) & (v1'=3) & (u1'=true) + 1/K : (s1'=1) & (p1'=4) & (v1'=4) & (u1'=true); // read - [read] s1=1 & u1 & c (u1'=(p1!=v2)) & (v1'=v2); - [read] s1=1 & !u1 & c (u1'=false) & (v1'=v2) & (p1'=0); + [read] s1=1 & u1 & c 1:(u1'=(p1!=v2)) & (v1'=v2); + [read] s1=1 & !u1 & c 1:(u1'=false) & (v1'=v2) & (p1'=0); // read and move to decide - [read] s1=1 & u1 & c=N-1 -> (s1'=2) & (u1'=(p1!=v2)) & (v1'=0) & (p1'=0); - [read] s1=1 & !u1 & c=N-1 -> (s1'=2) & (u1'=false) & (v1'=0); + [read] s1=1 & u1 & c=N-1 -> 1:(s1'=2) & (u1'=(p1!=v2)) & (v1'=0) & (p1'=0); + [read] s1=1 & !u1 & c=N-1 -> 1:(s1'=2) & (u1'=false) & (v1'=0); // deciding // done - [done] s1=2 -> (s1'=3) & (u1'=false) & (v1'=0) & (p1'=0); + [done] s1=2 -> 1:(s1'=3) & (u1'=false) & (v1'=0) & (p1'=0); //retry - [retry] s1=2 -> (s1'=0) & (u1'=false) & (v1'=0) & (p1'=0); + [retry] s1=2 -> 1:(s1'=0) & (u1'=false) & (v1'=0) & (p1'=0); // loop (when finished to avoid deadlocks) - [loop] s1=3 -> (s1'=3); + [loop] s1=3 -> 1:(s1'=3); endmodule diff --git a/src/ir/Variable.cpp b/src/ir/Variable.cpp index 4edc93b2f..082011655 100644 --- a/src/ir/Variable.cpp +++ b/src/ir/Variable.cpp @@ -25,8 +25,12 @@ Variable::Variable(uint_fast64_t index, std::string variableName, std::shared_pt // Nothing to do here. } -Variable::Variable(const Variable& var, const std::string& newName, const std::map& renaming, const std::map& bools, const std::map& ints) - : Variable(var.index, newName, var.initialValue->clone(renaming, bools, ints)) { +Variable::Variable(const Variable& var, const std::string& newName, const std::map& renaming, const std::map& bools, const std::map& ints) { + this->index = var.index; + this->variableName = newName; + if (var.initialValue != nullptr) { + this->initialValue = var.initialValue->clone(renaming, bools, ints); + } } // Return the name of the variable. From 6ad0c7041e1f6eaa34be8ba0822d8408cc79daed Mon Sep 17 00:00:00 2001 From: gereon Date: Wed, 1 May 2013 02:00:52 +0200 Subject: [PATCH 100/152] Allow DoubleExpressions to use integer constants --- src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp b/src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp index 82798fe3d..ddd1341f5 100644 --- a/src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp +++ b/src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp @@ -40,7 +40,7 @@ ConstDoubleExpressionGrammar::ConstDoubleExpressionGrammar(std::shared_ptr> constantDoubleExpression >> qi::lit(")") | doubleConstantExpression); constantAtomicDoubleExpression.name("constant double expression"); - doubleConstantExpression %= (this->state->doubleConstants_ | doubleLiteralExpression); + doubleConstantExpression %= (this->state->doubleConstants_ | this->state->integerConstants_ | doubleLiteralExpression); doubleConstantExpression.name("double constant or literal"); doubleLiteralExpression = qi::double_[qi::_val = phoenix::bind(&ConstDoubleExpressionGrammar::createLiteral, this, qi::_1)]; From a790a7c3eccac0be30b4758070951f6b4e638e25 Mon Sep 17 00:00:00 2001 From: gereon Date: Wed, 1 May 2013 02:01:27 +0200 Subject: [PATCH 101/152] Allow != as a token. --- src/parser/PrismParser/Tokens.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/parser/PrismParser/Tokens.h b/src/parser/PrismParser/Tokens.h index cf0392f32..bd246d358 100644 --- a/src/parser/PrismParser/Tokens.h +++ b/src/parser/PrismParser/Tokens.h @@ -54,6 +54,7 @@ namespace prism { relationalOperatorStruct() { add ("=", BinaryRelationExpression::EQUAL) + ("!=", BinaryRelationExpression::NOT_EQUAL) ("<", BinaryRelationExpression::LESS) ("<=", BinaryRelationExpression::LESS_OR_EQUAL) (">", BinaryRelationExpression::GREATER) From dfd4df2884bb55aaf3cba06b841e1cc66bcd3c46 Mon Sep 17 00:00:00 2001 From: gereon Date: Thu, 2 May 2013 16:35:48 +0200 Subject: [PATCH 102/152] Removing debug output. --- src/ir/expressions/UnaryBooleanFunctionExpression.h | 2 +- src/parser/PrismParser.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.h b/src/ir/expressions/UnaryBooleanFunctionExpression.h index 03dd1d87c..9883d6276 100644 --- a/src/ir/expressions/UnaryBooleanFunctionExpression.h +++ b/src/ir/expressions/UnaryBooleanFunctionExpression.h @@ -54,7 +54,7 @@ public: switch (functionType) { case NOT: result += "!"; break; } - result += this->getChild()->toString(); + result += "(" + this->getChild()->toString() + ")"; return result; } diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index c7b0b9141..648962689 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -33,7 +33,6 @@ namespace parser { * exception is passed on to the caller. */ storm::ir::Program PrismParser::parseFile(std::string const& filename) const { - std::cerr << "parseFile( " << filename << " )" << std::endl; // Open file and initialize result. std::ifstream inputFileStream(filename, std::ios::in); storm::ir::Program result; From b7a1e90579ac03dfe8fc165dd10c51408330f1ce Mon Sep 17 00:00:00 2001 From: gereon Date: Thu, 2 May 2013 16:36:18 +0200 Subject: [PATCH 103/152] Variables were counted in two places (VariableState and ExplicitAdapter). Now, they got mixed up... this is fixed now. --- src/adapters/ExplicitModelAdapter.cpp | 14 ++++++-------- src/ir/BooleanVariable.cpp | 2 +- src/ir/IntegerVariable.cpp | 3 ++- src/ir/Variable.cpp | 4 ++-- src/ir/Variable.h | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index be8a24e3e..03a274567 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -131,20 +131,18 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { this->booleanVariables.resize(numberOfBooleanVariables); this->integerVariables.resize(numberOfIntegerVariables); - uint_fast64_t nextBooleanVariableIndex = 0; - uint_fast64_t nextIntegerVariableIndex = 0; for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { storm::ir::Module const& module = program.getModule(i); for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { - this->booleanVariables[nextBooleanVariableIndex] = module.getBooleanVariable(j); - this->booleanVariableToIndexMap[module.getBooleanVariable(j).getName()] = nextBooleanVariableIndex; - ++nextBooleanVariableIndex; + storm::ir::BooleanVariable var = module.getBooleanVariable(j); + this->booleanVariables[var.getIndex()] = var; + this->booleanVariableToIndexMap[var.getName()] = var.getIndex(); } for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) { - this->integerVariables[nextIntegerVariableIndex] = module.getIntegerVariable(j); - this->integerVariableToIndexMap[module.getIntegerVariable(j).getName()] = nextIntegerVariableIndex; - ++nextIntegerVariableIndex; + storm::ir::IntegerVariable var = module.getIntegerVariable(j); + this->integerVariables[var.getIndex()] = var; + this->integerVariableToIndexMap[var.getName()] = var.getIndex(); } } } diff --git a/src/ir/BooleanVariable.cpp b/src/ir/BooleanVariable.cpp index f233100cd..2c03e1c44 100644 --- a/src/ir/BooleanVariable.cpp +++ b/src/ir/BooleanVariable.cpp @@ -26,7 +26,7 @@ BooleanVariable::BooleanVariable(uint_fast64_t index, std::string variableName, } BooleanVariable::BooleanVariable(const BooleanVariable& var, const std::string& newName, const std::map& renaming, const std::map& bools, const std::map& ints) - : Variable(var, newName, renaming, bools, ints) { + : Variable(var, newName, bools.at(newName), renaming, bools, ints) { } // Build a string representation of the variable. diff --git a/src/ir/IntegerVariable.cpp b/src/ir/IntegerVariable.cpp index 0e6e2a4fe..a8926b046 100644 --- a/src/ir/IntegerVariable.cpp +++ b/src/ir/IntegerVariable.cpp @@ -23,13 +23,14 @@ IntegerVariable::IntegerVariable() : lowerBound(), upperBound() { // Initializes all members according to the given values. IntegerVariable::IntegerVariable(uint_fast64_t index, std::string variableName, std::shared_ptr lowerBound, std::shared_ptr upperBound, std::shared_ptr initialValue) : Variable(index, variableName, initialValue), lowerBound(lowerBound), upperBound(upperBound) { + // TODO: This behaves like prism... if (this->getInitialValue() == nullptr) { this->setInitialValue(lowerBound); } } IntegerVariable::IntegerVariable(const IntegerVariable& var, const std::string& newName, const std::map& renaming, const std::map& bools, const std::map& ints) - : Variable(var, newName, renaming, bools, ints), lowerBound(var.lowerBound->clone(renaming, bools, ints)), upperBound(var.upperBound->clone(renaming, bools, ints)) { + : Variable(var, newName, ints.at(newName), renaming, bools, ints), lowerBound(var.lowerBound->clone(renaming, bools, ints)), upperBound(var.upperBound->clone(renaming, bools, ints)) { } // Return lower bound for variable. diff --git a/src/ir/Variable.cpp b/src/ir/Variable.cpp index 082011655..421603f4f 100644 --- a/src/ir/Variable.cpp +++ b/src/ir/Variable.cpp @@ -25,8 +25,8 @@ Variable::Variable(uint_fast64_t index, std::string variableName, std::shared_pt // Nothing to do here. } -Variable::Variable(const Variable& var, const std::string& newName, const std::map& renaming, const std::map& bools, const std::map& ints) { - this->index = var.index; +Variable::Variable(const Variable& var, const std::string& newName, const uint_fast64_t newIndex, const std::map& renaming, const std::map& bools, const std::map& ints) { + this->index = newIndex; this->variableName = newName; if (var.initialValue != nullptr) { this->initialValue = var.initialValue->clone(renaming, bools, ints); diff --git a/src/ir/Variable.h b/src/ir/Variable.h index e144d06aa..610ef903a 100644 --- a/src/ir/Variable.h +++ b/src/ir/Variable.h @@ -40,7 +40,7 @@ public: * @param var Variable to copy. * @param newName New name of this variable. */ - Variable(const Variable& var, const std::string& newName, const std::map& renaming, const std::map& bools, const std::map& ints); + Variable(const Variable& var, const std::string& newName, const uint_fast64_t newIndex, const std::map& renaming, const std::map& bools, const std::map& ints); /*! * Retrieves the name of the variable. From 860a775c1870e9b3d09f0d131ea2f94d6388b1d7 Mon Sep 17 00:00:00 2001 From: gereon Date: Thu, 2 May 2013 16:55:59 +0200 Subject: [PATCH 104/152] Actually skip modules that do not have commands with current label. --- src/adapters/ExplicitModelAdapter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index 03a274567..ad69887a0 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -168,6 +168,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { storm::ir::Module const& module = this->program.getModule(i); std::shared_ptr> ids = module.getCommandsByAction(action); + if (ids->size() == 0) continue; std::list commands; // Look up commands by their id. Add, if guard holds. From 0f545630ebffcab8df1b45417a1aec5d7519375d Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 8 May 2013 14:56:48 +0200 Subject: [PATCH 105/152] Adapted the pctl files according to our format. --- examples/dtmc/crowds/crowds.pctl | 6 ++--- examples/dtmc/die/die.pctl | 8 +++---- examples/dtmc/synchronous_leader/leader.pctl | 6 ++--- examples/mdp/asynchronous_leader/leader.pctl | 10 ++++---- examples/mdp/consensus/coin.pctl | 16 ++++++------- examples/mdp/two_dice/two_dice.pctl | 24 ++++++++++---------- 6 files changed, 35 insertions(+), 35 deletions(-) diff --git a/examples/dtmc/crowds/crowds.pctl b/examples/dtmc/crowds/crowds.pctl index a7c83e667..653da5713 100644 --- a/examples/dtmc/crowds/crowds.pctl +++ b/examples/dtmc/crowds/crowds.pctl @@ -1,3 +1,3 @@ -P=? [ F "observe0Greater1" ] -P=? [ F "observeIGreater1" ] -P=? [ F "observeOnlyTrueSender" ] +P=? [ F observe0Greater1 ] +P=? [ F observeIGreater1 ] +P=? [ F observeOnlyTrueSender ] diff --git a/examples/dtmc/die/die.pctl b/examples/dtmc/die/die.pctl index b0eb88dcd..8deea6c43 100644 --- a/examples/dtmc/die/die.pctl +++ b/examples/dtmc/die/die.pctl @@ -1,4 +1,4 @@ -P=? [ F "one" ] -P=? [ F "two" ] -P=? [ F "three" ] -R=? [ F "done" ] +P=? [ F one ] +P=? [ F two ] +P=? [ F three ] +R=? [ F done ] diff --git a/examples/dtmc/synchronous_leader/leader.pctl b/examples/dtmc/synchronous_leader/leader.pctl index e8b1899e6..b14536d80 100644 --- a/examples/dtmc/synchronous_leader/leader.pctl +++ b/examples/dtmc/synchronous_leader/leader.pctl @@ -1,3 +1,3 @@ -P=? [ F "elected" ] -P=? [ F<=(4*(N+1)) "elected" ] -R=? [ F "elected" ] +P=? [ F elected ] +P=? [ F<=(4*(N+1)) elected ] +R=? [ F elected ] diff --git a/examples/mdp/asynchronous_leader/leader.pctl b/examples/mdp/asynchronous_leader/leader.pctl index 49e4dbeaa..bb8fb1b82 100644 --- a/examples/mdp/asynchronous_leader/leader.pctl +++ b/examples/mdp/asynchronous_leader/leader.pctl @@ -1,8 +1,8 @@ -Pmin=? [ F "elected" ] +Pmin=? [ F elected ] const int K = 25; -Pmin=? [ F<=K "elected" ] -Pmax=? [ F<=K "elected" ] +Pmin=? [ F<=K elected ] +Pmax=? [ F<=K elected ] -Rmin=? [ F "elected" ] -Rmax=? [ F "elected" ] +Rmin=? [ F elected ] +Rmax=? [ F elected ] diff --git a/examples/mdp/consensus/coin.pctl b/examples/mdp/consensus/coin.pctl index 52a308559..aa371d50b 100644 --- a/examples/mdp/consensus/coin.pctl +++ b/examples/mdp/consensus/coin.pctl @@ -1,20 +1,20 @@ // C1 (with probability 1, all N processes finish the protocol) -Pmin=? [ F "finished" ] +Pmin=? [ F finished ] // C2 (minimum probability that the protocol finishes with all coins equal to v) (v=1,2) // Results are same for v=1 and v=2 by symmetry // Analytic bound is (K-1)/(2*K) -Pmin=? [ F "finished"&"all_coins_equal_0" ] -Pmin=? [ F "finished"&"all_coins_equal_1" ] +Pmin=? [ F finished & all_coins_equal_0 ] +Pmin=? [ F finished & all_coins_equal_1 ] // Max probability of finishing protocol with coins not all equal -Pmax=? [ F "finished"&!"agree" ] +Pmax=? [ F finished & !agree ] // Min/max probability of finishing within k steps -Pmin=? [ F<=k "finished" ] -Pmax=? [ F<=k "finished" ] +Pmin=? [ F<=k finished ] +Pmax=? [ F<=k finished ] // Min/max expected steps to finish -Rmin=? [ F "finished" ] -Rmax=? [ F "finished" ] +Rmin=? [ F finished ] +Rmax=? [ F finished ] diff --git a/examples/mdp/two_dice/two_dice.pctl b/examples/mdp/two_dice/two_dice.pctl index 10cdff821..4ad376feb 100644 --- a/examples/mdp/two_dice/two_dice.pctl +++ b/examples/mdp/two_dice/two_dice.pctl @@ -1,13 +1,13 @@ -Pmin=? [ F "two" ] -Pmax=? [ F "two" ] -Pmin=? [ F "three" ] -Pmax=? [ F "three" ] -Pmin=? [ F "four" ] -Pmax=? [ F "four" ] -Pmin=? [ F "five" ] -Pmax=? [ F "five" ] -Pmin=? [ F "six" ] -Pmax=? [ F "six" ] +Pmin=? [ F two ] +Pmax=? [ F two ] +Pmin=? [ F three ] +Pmax=? [ F three ] +Pmin=? [ F four ] +Pmax=? [ F four ] +Pmin=? [ F five ] +Pmax=? [ F five ] +Pmin=? [ F six ] +Pmax=? [ F six ] -Rmin=? [ F "done" ] -Rmax=? [ F "done" ] +Rmin=? [ F done ] +Rmax=? [ F done ] From 94337f5835f6fd7133239aaeffbe1b750e67ee70 Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 8 May 2013 16:19:26 +0200 Subject: [PATCH 106/152] Added move-constructor and move-assignment to bit vector class. --- src/storage/BitVector.h | 49 +++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/storage/BitVector.h b/src/storage/BitVector.h index 570283c4d..6787fe0e3 100644 --- a/src/storage/BitVector.h +++ b/src/storage/BitVector.h @@ -95,7 +95,13 @@ public: uint_fast64_t endIndex; }; - //! Constructor + /* + * Standard constructor. Constructs an empty bit vector of length 0. + */ + BitVector() : bucketCount(0), bitCount(0), bucketArray(nullptr), endIterator(*this, 0, 0, false), truncateMask(0) { + // Intentionally left empty. + } + /*! * Constructs a bit vector which can hold the given number of bits and * initializes all bits to the provided truth value. @@ -131,7 +137,6 @@ public: } } - //! Copy Constructor /*! * Copy Constructor. Performs a deep copy of the given bit vector. * @param bv A reference to the bit vector to be copied. @@ -141,8 +146,17 @@ public: bucketArray = new uint64_t[bucketCount]; std::copy(bv.bucketArray, bv.bucketArray + this->bucketCount, this->bucketArray); } + + /*! + * Move constructor. Move constructs the bit vector from the given bit vector. + * + */ + BitVector(BitVector&& bv) : bucketCount(bv.bucketCount), bitCount(bv.bitCount), endIterator(*this, bitCount, bitCount, false), truncateMask((1ll << (bitCount & mod64mask)) - 1ll) { + LOG4CPLUS_DEBUG(logger, "Invoking move constructor."); + this->bucketArray = bv.bucketArray; + bv.bucketArray = nullptr; + } - //! Destructor /*! * Destructor. Frees the underlying bucket array. */ @@ -152,7 +166,6 @@ public: } } - // Equality Operator /*! * Compares the given bit vector with the current one. */ @@ -171,7 +184,6 @@ public: return true; } - //! Assignment Operator /*! * Assigns the given bit vector to the current bit vector by a deep copy. * @param bv The bit vector to assign to the current bit vector. @@ -179,9 +191,11 @@ public: * given bit vector by means of a deep copy. */ BitVector& operator=(BitVector const& bv) { + // Check if we need to dispose of our current storage. if (this->bucketArray != nullptr) { delete[] this->bucketArray; } + // Copy the values from the other bit vector. bucketCount = bv.bucketCount; bitCount = bv.bitCount; bucketArray = new uint64_t[bucketCount]; @@ -189,6 +203,27 @@ public: updateSizeChange(); return *this; } + + BitVector& operator=(BitVector&& bv) { + // Only perform the assignment if the source and target are not identical. + if (this != &bv) { + // Check if we need to dispose of our current storage. + if (this->bucketArray != nullptr) { + delete[] this->bucketArray; + } + + // Copy the values from the other bit vector, but directly steal its storage. + bucketCount = bv.bucketCount; + bitCount = bv.bitCount; + bucketArray = bv.bucketArray; + updateSizeChange(); + + // Now alter the other bit vector such that it does not dispose of our stolen storage. + bv.bucketArray = nullptr; + } + + return *this; + } /*! * Resizes the bit vector to hold the given new number of bits. @@ -430,9 +465,9 @@ public: * Adds all indices of bits set to one to the provided list. * @param list The list to which to append the indices. */ - void addSetIndicesToList(std::vector& list) const { + void addSetIndicesToVector(std::vector& vector) const { for (auto index : *this) { - list.push_back(index); + vector.push_back(index); } } From cc7230abb1b890c698ca9a93dc18cc74b204401b Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 8 May 2013 16:20:29 +0200 Subject: [PATCH 107/152] Started to refactor graph analyzing to include less pointers and the like. Currently this breaks two tests. --- .../SparseDtmcPrctlModelChecker.h | 11 +- src/modelchecker/SparseMdpPrctlModelChecker.h | 8 +- src/utility/CommandLine.h | 2 +- src/utility/ErrorHandling.h | 37 ++- src/utility/GraphAnalyzer.h | 280 +++++++++--------- 5 files changed, 188 insertions(+), 150 deletions(-) diff --git a/src/modelchecker/SparseDtmcPrctlModelChecker.h b/src/modelchecker/SparseDtmcPrctlModelChecker.h index 6cbdd5aa3..a6d132745 100644 --- a/src/modelchecker/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/SparseDtmcPrctlModelChecker.h @@ -211,9 +211,12 @@ public: // Then, we need to identify the states which have to be taken out of the matrix, i.e. // all states that have probability 0 and 1 of satisfying the until-formula. - storm::storage::BitVector statesWithProbability0(this->getModel().getNumberOfStates()); - storm::storage::BitVector statesWithProbability1(this->getModel().getNumberOfStates()); - storm::utility::GraphAnalyzer::performProb01(this->getModel(), *leftStates, *rightStates, &statesWithProbability0, &statesWithProbability1); + std::pair statesWithProbability01 = storm::utility::GraphAnalyzer::performProb01(this->getModel(), *leftStates, *rightStates); + storm::storage::BitVector statesWithProbability0 = statesWithProbability01.first; + storm::storage::BitVector statesWithProbability1 = statesWithProbability01.second; + + std::cout << statesWithProbability0.toString() << std::endl; + std::cout << statesWithProbability1.toString() << std::endl; // Delete intermediate results that are obsolete now. delete leftStates; @@ -360,7 +363,7 @@ public: // Determine which states have a reward of infinity by definition. storm::storage::BitVector infinityStates(this->getModel().getNumberOfStates()); storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); - storm::utility::GraphAnalyzer::performProb1(this->getModel(), trueStates, *targetStates, &infinityStates); + storm::utility::GraphAnalyzer::performProb1(this->getModel(), trueStates, *targetStates, infinityStates); infinityStates.complement(); // Create resulting vector. diff --git a/src/modelchecker/SparseMdpPrctlModelChecker.h b/src/modelchecker/SparseMdpPrctlModelChecker.h index e31212e36..50b20c81d 100644 --- a/src/modelchecker/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/SparseMdpPrctlModelChecker.h @@ -216,9 +216,9 @@ public: storm::storage::BitVector statesWithProbability0(this->getModel().getNumberOfStates()); storm::storage::BitVector statesWithProbability1(this->getModel().getNumberOfStates()); if (this->minimumOperatorStack.top()) { - storm::utility::GraphAnalyzer::performProb01Min(this->getModel(), *leftStates, *rightStates, &statesWithProbability0, &statesWithProbability1); + storm::utility::GraphAnalyzer::performProb01Min(this->getModel(), *leftStates, *rightStates, statesWithProbability0, statesWithProbability1); } else { - storm::utility::GraphAnalyzer::performProb01Max(this->getModel(), *leftStates, *rightStates, &statesWithProbability0, &statesWithProbability1); + storm::utility::GraphAnalyzer::performProb01Max(this->getModel(), *leftStates, *rightStates, statesWithProbability0, statesWithProbability1); } // Delete sub-results that are obsolete now. @@ -359,9 +359,9 @@ public: storm::storage::BitVector infinityStates(this->getModel().getNumberOfStates()); storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); if (this->minimumOperatorStack.top()) { - storm::utility::GraphAnalyzer::performProb1A(this->getModel(), trueStates, *targetStates, &infinityStates); + storm::utility::GraphAnalyzer::performProb1A(this->getModel(), trueStates, *targetStates, infinityStates); } else { - storm::utility::GraphAnalyzer::performProb1E(this->getModel(), trueStates, *targetStates, &infinityStates); + storm::utility::GraphAnalyzer::performProb1E(this->getModel(), trueStates, *targetStates, infinityStates); } infinityStates.complement(); diff --git a/src/utility/CommandLine.h b/src/utility/CommandLine.h index 04599348d..134706ec2 100644 --- a/src/utility/CommandLine.h +++ b/src/utility/CommandLine.h @@ -13,7 +13,7 @@ namespace storm { namespace utility { /*! - * Prints a separation line on the command line. + * Prints a separating line to the standard output. */ void printSeparationLine(std::ostream& out); diff --git a/src/utility/ErrorHandling.h b/src/utility/ErrorHandling.h index fdc7762a5..ea65ab03a 100644 --- a/src/utility/ErrorHandling.h +++ b/src/utility/ErrorHandling.h @@ -12,12 +12,19 @@ #include #include -std::string demangle(const char* symbol) { +/* + * Demangles the given string. This is needed for the correct display of backtraces. + * + * @param symbol The name of the symbol that is to be demangled. + */ +std::string demangle(char const* symbol) { int status; - // Attention: sscanf format strings rely on size being 128 + + // Attention: sscanf format strings rely on the size being 128. char temp[128]; char* demangled; - // Check for C++ symbol + + // Check for C++ symbol. if (sscanf(symbol, "%*[^(]%*[^_]%127[^)+]", temp) == 1) { if (NULL != (demangled = abi::__cxa_demangle(temp, NULL, NULL, &status))) { std::string result(demangled); @@ -25,37 +32,49 @@ std::string demangle(const char* symbol) { return result; } } - // Check for C symbol + // Check for C symbol. if (sscanf(symbol, "%127s", temp) == 1) { return temp; } - // Return plain symbol + + // Return plain symbol if none of the above cases matched. return symbol; } +/* + * Handles the given signal. This will display the received signal and a backtrace. + * + * @param sig The code of the signal that needs to be handled. + */ void signalHandler(int sig) { #define SIZE 128 - LOG4CPLUS_FATAL(logger, "We recieved a segfault. To start with, here is a backtrace."); + LOG4CPLUS_FATAL(logger, "The program received signal " << sig << ". The following backtrace shows the status upon reception of the signal."); void *buffer[SIZE]; char **strings; int nptrs; nptrs = backtrace(buffer, SIZE); + // Try to retrieve the backtrace symbols. strings = backtrace_symbols(buffer, nptrs); if (strings == nullptr) { - std::cerr << "Obtaining the backtrace symbols failed. Well, shit." << std::endl; + std::cerr << "Obtaining the backtrace symbols failed." << std::endl; exit(2); } - // j = 2: skip the handler itself. + + // Starting this for-loop at j=2 means that we skip the handler itself. Currently this is not + // done. for (int j = 1; j < nptrs; j++) { LOG4CPLUS_FATAL(logger, nptrs-j << ": " << demangle(strings[j])); } free(strings); - LOG4CPLUS_FATAL(logger, "That's all we can do. Bye."); + LOG4CPLUS_FATAL(logger, "Exiting."); exit(2); } +/* + * Registers some signal handlers so that we can display a backtrace upon erroneuous termination. + */ void installSignalHandler() { signal(SIGSEGV, signalHandler); } diff --git a/src/utility/GraphAnalyzer.h b/src/utility/GraphAnalyzer.h index 5bbb4295c..573d2baa6 100644 --- a/src/utility/GraphAnalyzer.h +++ b/src/utility/GraphAnalyzer.h @@ -26,73 +26,63 @@ public: /*! * Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi until psi in a * deterministic model. + * * @param model The model whose graph structure to search. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. - * @param statesWithProbability0 A pointer to a bit vector that is initially empty and will contain all states with - * probability 0 after the invocation of the function. - * @param statesWithProbability1 A pointer to a bit vector that is initially empty and will contain all states with - * probability 1 after the invocation of the function. + * @return A pair of bit vectors such that the first bit vector stores the indices of all states + * with probability 0 and the second stores all indices of states with probability 1. */ template - static void performProb01(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector* statesWithProbability0, storm::storage::BitVector* statesWithProbability1) { - // Check for valid parameters. - if (statesWithProbability0 == nullptr) { - LOG4CPLUS_ERROR(logger, "Parameter 'statesWithProbability0' must not be null."); - throw storm::exceptions::InvalidArgumentException("Parameter 'statesWithProbability0' must not be null."); - } - if (statesWithProbability1 == nullptr) { - LOG4CPLUS_ERROR(logger, "Parameter 'statesWithProbability1' must not be null."); - throw storm::exceptions::InvalidArgumentException("Parameter 'statesWithProbability1' must not be null."); - } - - // Perform the actual search. - GraphAnalyzer::performProbGreater0(model, phiStates, psiStates, statesWithProbability0); - GraphAnalyzer::performProb1(model, phiStates, psiStates, *statesWithProbability0, statesWithProbability1); - statesWithProbability0->complement(); + static std::pair performProb01(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + std::pair result; + result.first = GraphAnalyzer::performProbGreater0(model, phiStates, psiStates); + result.second = GraphAnalyzer::performProb1(model, phiStates, psiStates, result.first); + result.first.complement(); + return result; } /*! - * Performs a backwards depth-first search trough the underlying graph structure + * Performs a backwards breadt-first search trough the underlying graph structure * of the given model to determine which states of the model have a positive probability * of satisfying phi until psi. The resulting states are written to the given bit vector. - * @param model The model whose graph structure to search. + * + * @param model The model whose graph structure to search. * @param phiStates A bit vector of all states satisfying phi. * @param psiStates A bit vector of all states satisfying psi. - * @param statesWithProbabilityGreater0 A pointer to the result of the search for states that possess - * a positive probability of satisfying phi until psi. + * @return A bit vector with all indices of states that have a probability greater than 0. */ template - static void performProbGreater0(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector* statesWithProbabilityGreater0) { - // Check for valid parameter. - if (statesWithProbabilityGreater0 == nullptr) { - LOG4CPLUS_ERROR(logger, "Parameter 'statesWithProbabilityGreater0' must not be null."); - throw storm::exceptions::InvalidArgumentException("Parameter 'statesWithProbabilityGreater0' must not be null."); - } - + static storm::storage::BitVector performProbGreater0(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + // Prepare the resulting bit vector. + storm::storage::BitVector statesWithProbabilityGreater0(model.getNumberOfStates()); + // Get the backwards transition relation from the model to ease the search. storm::models::GraphTransitions backwardTransitions(*model.getTransitionMatrix(), false); // Add all psi states as the already satisfy the condition. - *statesWithProbabilityGreater0 |= psiStates; + statesWithProbabilityGreater0 |= psiStates; - // Initialize the stack used for the DFS with the states + // Initialize the stack used for the BFS with the states. std::vector stack; stack.reserve(model.getNumberOfStates()); - psiStates.addSetIndicesToList(stack); + psiStates.addSetIndicesToVector(stack); - // Perform the actual DFS. + // Perform the actual BFS. while(!stack.empty()) { uint_fast64_t currentState = stack.back(); stack.pop_back(); for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) { - if (phiStates.get(*it) && !statesWithProbabilityGreater0->get(*it)) { - statesWithProbabilityGreater0->set(*it, true); + if (phiStates.get(*it) && !statesWithProbabilityGreater0.get(*it)) { + statesWithProbabilityGreater0.set(*it, true); stack.push_back(*it); } } } + + // Return result. + return statesWithProbabilityGreater0; } /*! @@ -101,24 +91,19 @@ public: * before. In order to do this, it uses the given set of states that * characterizes the states that possess at least one path to a target state. * The results are written to the given bit vector. + * * @param model The model whose graph structure to search. * @param phiStates A bit vector of all states satisfying phi. * @param psiStates A bit vector of all states satisfying psi. * @param statesWithProbabilityGreater0 A reference to a bit vector of states that possess a positive * probability mass of satisfying phi until psi. - * @param alwaysPhiUntilPsiStates A pointer to the result of the search for states that only - * have paths satisfying phi until psi. + * @return A bit vector with all indices of states that have a probability greater than 1. */ template - static void performProb1(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& statesWithProbabilityGreater0, storm::storage::BitVector* statesWithProbability1) { - // Check for valid parameter. - if (statesWithProbability1 == nullptr) { - LOG4CPLUS_ERROR(logger, "Parameter 'statesWithProbability1' must not be null."); - throw storm::exceptions::InvalidArgumentException("Parameter 'statesWithProbability1' must not be null."); - } - - GraphAnalyzer::performProbGreater0(model, ~psiStates, ~statesWithProbabilityGreater0, statesWithProbability1); - statesWithProbability1->complement(); + static storm::storage::BitVector performProb1(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& statesWithProbabilityGreater0) { + storm::storage::BitVector statesWithProbability1 = GraphAnalyzer::performProbGreater0(model, ~psiStates, ~statesWithProbabilityGreater0); + statesWithProbability1.complement(); + return statesWithProbability1; } /*! @@ -127,87 +112,97 @@ public: * before. In order to do this, it uses the given set of states that * characterizes the states that possess at least one path to a target state. * The results are written to the given bit vector. + * * @param model The model whose graph structure to search. * @param phiStates A bit vector of all states satisfying phi. * @param psiStates A bit vector of all states satisfying psi. - * @param alwaysPhiUntilPsiStates A pointer to the result of the search for states that only - * have paths satisfying phi until psi. + * @return A bit vector with all indices of states that have a probability greater than 1. */ template - static void performProb1(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector* statesWithProbability1) { - // Check for valid parameter. - if (statesWithProbability1 == nullptr) { - LOG4CPLUS_ERROR(logger, "Parameter 'statesWithProbability1' must not be null."); - throw storm::exceptions::InvalidArgumentException("Parameter 'statesWithProbability1' must not be null."); - } - - storm::storage::BitVector* statesWithProbabilityGreater0 = new storm::storage::BitVector(model.getNumberOfStates()); - GraphAnalyzer::performProbGreater0(model, phiStates, psiStates, statesWithProbabilityGreater0); - GraphAnalyzer::performProbGreater0(model, ~psiStates, ~(*statesWithProbabilityGreater0), statesWithProbability1); - delete statesWithProbabilityGreater0; - statesWithProbability1->complement(); + static storm::storage::BitVector performProb1(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + storm::storage::BitVector statesWithProbabilityGreater0(model.getNumberOfStates()); + storm::storage::BitVector statesWithProbability1(model.getNumberOfStates()); + GraphAnalyzer::performProbGreater0(model, phiStates, psiStates, statesWithProbabilityGreater0); + GraphAnalyzer::performProbGreater0(model, ~psiStates, ~(statesWithProbabilityGreater0), statesWithProbability1); + statesWithProbability1.complement(); + return statesWithProbability1; } + /*! + * Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi + * until psi in a non-deterministic model in which all non-deterministic choices are resolved + * such that the probability is maximized. + * + * @param model The model whose graph structure to search. + * @param phiStates The set of all states satisfying phi. + * @param psiStates The set of all states satisfying psi. + * @param statesWithProbability0 A pointer to a bit vector that is initially empty and will + * contain all states with probability 0 after the invocation of the function. + * @param statesWithProbability1 A pointer to a bit vector that is initially empty and will + * contain all states with probability 1 after the invocation of the function. + */ template - static void performProb01Max(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector* statesWithProbability0, storm::storage::BitVector* statesWithProbability1) { - // Check for valid parameters. - if (statesWithProbability0 == nullptr) { - LOG4CPLUS_ERROR(logger, "Parameter 'statesWithProbability0' must not be null."); - throw storm::exceptions::InvalidArgumentException("Parameter 'statesWithProbability0' must not be null."); - } - if (statesWithProbability1 == nullptr) { - LOG4CPLUS_ERROR(logger, "Parameter 'statesWithProbability1' must not be null."); - throw storm::exceptions::InvalidArgumentException("Parameter 'statesWithProbability1' must not be null."); - } - - // Perform the actual search. + static void performProb01Max(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector& statesWithProbability0, storm::storage::BitVector& statesWithProbability1) { GraphAnalyzer::performProb0A(model, phiStates, psiStates, statesWithProbability0); GraphAnalyzer::performProb1E(model, phiStates, psiStates, statesWithProbability1); } + /*! + * Computes the sets of states that have probability 0 of satisfying phi until psi under all + * possible resolutions of non-determinism in a non-deterministic model. Stated differently, + * this means that these states have probability 0 of satisfying phi until psi even if the + * scheduler tries to maximize this probability. + * + * @param model The model whose graph structure to search. + * @param phiStates The set of all states satisfying phi. + * @param psiStates The set of all states satisfying psi. + * @param statesWithProbability0 A pointer to a bit vector that is initially empty and will + * contain all states with probability 0 after the invocation of the function. + */ template - static void performProb0A(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector* statesWithProbability0) { - // Check for valid parameter. - if (statesWithProbability0 == nullptr) { - LOG4CPLUS_ERROR(logger, "Parameter 'statesWithProbability0' must not be null."); - throw storm::exceptions::InvalidArgumentException("Parameter 'statesWithProbability0' must not be null."); - } - + static void performProb0A(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector& statesWithProbability0) { // Get the backwards transition relation from the model to ease the search. storm::models::GraphTransitions backwardTransitions(*model.getTransitionMatrix(), *model.getNondeterministicChoiceIndices(), false); // Add all psi states as the already satisfy the condition. - *statesWithProbability0 |= psiStates; + statesWithProbability0 |= psiStates; - // Initialize the stack used for the DFS with the states + // Initialize the stack used for the BFS with the states std::vector stack; stack.reserve(model.getNumberOfStates()); - psiStates.addSetIndicesToList(stack); + psiStates.addSetIndicesToVector(stack); - // Perform the actual DFS. + // Perform the actual BFS. while(!stack.empty()) { uint_fast64_t currentState = stack.back(); stack.pop_back(); for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) { - if (phiStates.get(*it) && !statesWithProbability0->get(*it)) { - statesWithProbability0->set(*it, true); + if (phiStates.get(*it) && !statesWithProbability0.get(*it)) { + statesWithProbability0.set(*it, true); stack.push_back(*it); } } } - statesWithProbability0->complement(); + // Finally, invert the computed set of states. + statesWithProbability0.complement(); } + /*! + * Computes the sets of states that have probability 1 of satisfying phi until psi under at least + * one possible resolution of non-determinism in a non-deterministic model. Stated differently, + * this means that these states have probability 1 of satisfying phi until psi if the + * scheduler tries to maximize this probability. + * + * @param model The model whose graph structure to search. + * @param phiStates The set of all states satisfying phi. + * @param psiStates The set of all states satisfying psi. + * @param statesWithProbability1 A pointer to a bit vector that is initially empty and will + * contain all states with probability 1 after the invocation of the function. + */ template - static void performProb1E(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector* statesWithProbability1) { - // Check for valid parameters. - if (statesWithProbability1 == nullptr) { - LOG4CPLUS_ERROR(logger, "Parameter 'statesWithProbability1' must not be null."); - throw storm::exceptions::InvalidArgumentException("Parameter 'statesWithProbability1' must not be null."); - } - + static void performProb1E(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector& statesWithProbability1) { // Get some temporaries for convenience. std::shared_ptr> transitionMatrix = model.getTransitionMatrix(); std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); @@ -220,11 +215,12 @@ public: std::vector stack; stack.reserve(model.getNumberOfStates()); + // Perform the loop as long as the set of states gets larger. bool done = false; while (!done) { stack.clear(); storm::storage::BitVector* nextStates = new storm::storage::BitVector(psiStates); - psiStates.addSetIndicesToList(stack); + psiStates.addSetIndicesToVector(stack); while (!stack.empty()) { uint_fast64_t currentState = stack.back(); @@ -265,35 +261,42 @@ public: delete nextStates; } - *statesWithProbability1 = *currentStates; + statesWithProbability1 = *currentStates; delete currentStates; } - - template - static void performProb01Min(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector* statesWithProbability0, storm::storage::BitVector* statesWithProbability1) { - // Check for valid parameters. - if (statesWithProbability0 == nullptr) { - LOG4CPLUS_ERROR(logger, "Parameter 'statesWithProbability0' must not be null."); - throw storm::exceptions::InvalidArgumentException("Parameter 'statesWithProbability0' must not be null."); - } - if (statesWithProbability1 == nullptr) { - LOG4CPLUS_ERROR(logger, "Parameter 'statesWithProbability1' must not be null."); - throw storm::exceptions::InvalidArgumentException("Parameter 'statesWithProbability1' must not be null."); - } - - // Perform the actual search. + /*! + * Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi + * until psi in a non-deterministic model in which all non-deterministic choices are resolved + * such that the probability is minimized. + * + * @param model The model whose graph structure to search. + * @param phiStates The set of all states satisfying phi. + * @param psiStates The set of all states satisfying psi. + * @param statesWithProbability0 A pointer to a bit vector that is initially empty and will + * contain all states with probability 0 after the invocation of the function. + * @param statesWithProbability1 A pointer to a bit vector that is initially empty and will + * contain all states with probability 1 after the invocation of the function. + */ + template + static void performProb01Min(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector& statesWithProbability0, storm::storage::BitVector& statesWithProbability1) { GraphAnalyzer::performProb0E(model, phiStates, psiStates, statesWithProbability0); GraphAnalyzer::performProb1A(model, phiStates, psiStates, statesWithProbability1); } + /*! + * Computes the sets of states that have probability 0 of satisfying phi until psi under at least + * one possible resolution of non-determinism in a non-deterministic model. Stated differently, + * this means that these states have probability 0 of satisfying phi until psi if the + * scheduler tries to minimize this probability. + * + * @param model The model whose graph structure to search. + * @param phiStates The set of all states satisfying phi. + * @param psiStates The set of all states satisfying psi. + * @param statesWithProbability0 A pointer to a bit vector that is initially empty and will + * contain all states with probability 0 after the invocation of the function. + */ template - static void performProb0E(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector* statesWithProbability0) { - // Check for valid parameter. - if (statesWithProbability0 == nullptr) { - LOG4CPLUS_ERROR(logger, "Parameter 'statesWithProbability0' must not be null."); - throw storm::exceptions::InvalidArgumentException("Parameter 'statesWithProbability0' must not be null."); - } - + static void performProb0E(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector& statesWithProbability0) { // Get some temporaries for convenience. std::shared_ptr> transitionMatrix = model.getTransitionMatrix(); std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); @@ -302,12 +305,12 @@ public: storm::models::GraphTransitions backwardTransitions(*transitionMatrix, *nondeterministicChoiceIndices, false); // Add all psi states as the already satisfy the condition. - *statesWithProbability0 |= psiStates; + statesWithProbability0 |= psiStates; // Initialize the stack used for the DFS with the states std::vector stack; stack.reserve(model.getNumberOfStates()); - psiStates.addSetIndicesToList(stack); + psiStates.addSetIndicesToVector(stack); // Perform the actual DFS. while(!stack.empty()) { @@ -315,14 +318,14 @@ public: stack.pop_back(); for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) { - if (phiStates.get(*it) && !statesWithProbability0->get(*it)) { + if (phiStates.get(*it) && !statesWithProbability0.get(*it)) { // Check whether the predecessor has at least one successor in the current state // set for every nondeterministic choice. bool addToStatesWithProbability0 = true; for (auto rowIt = nondeterministicChoiceIndices->begin() + *it; rowIt != nondeterministicChoiceIndices->begin() + *it + 1; ++rowIt) { bool hasAtLeastOneSuccessorWithProbabilityGreater0 = false; for (auto colIt = transitionMatrix->constColumnIteratorBegin(*rowIt); colIt != transitionMatrix->constColumnIteratorEnd(*rowIt); ++colIt) { - if (statesWithProbability0->get(*colIt)) { + if (statesWithProbability0.get(*colIt)) { hasAtLeastOneSuccessorWithProbabilityGreater0 = true; break; } @@ -336,24 +339,30 @@ public: // If we need to add the state, then actually add it and perform further search // from the state. if (addToStatesWithProbability0) { - statesWithProbability0->set(*it, true); + statesWithProbability0.set(*it, true); stack.push_back(*it); } } } } - statesWithProbability0->complement(); + statesWithProbability0.complement(); } + /*! + * Computes the sets of states that have probability 1 of satisfying phi until psi under all + * possible resolutions of non-determinism in a non-deterministic model. Stated differently, + * this means that these states have probability 1 of satisfying phi until psi even if the + * scheduler tries to minimize this probability. + * + * @param model The model whose graph structure to search. + * @param phiStates The set of all states satisfying phi. + * @param psiStates The set of all states satisfying psi. + * @param statesWithProbability1 A pointer to a bit vector that is initially empty and will + * contain all states with probability 1 after the invocation of the function. + */ template - static void performProb1A(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector* statesWithProbability1) { - // Check for valid parameters. - if (statesWithProbability1 == nullptr) { - LOG4CPLUS_ERROR(logger, "Parameter 'statesWithProbability1' must not be null."); - throw storm::exceptions::InvalidArgumentException("Parameter 'statesWithProbability1' must not be null."); - } - + static void performProb1A(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector& statesWithProbability1) { // Get some temporaries for convenience. std::shared_ptr> transitionMatrix = model.getTransitionMatrix(); std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); @@ -366,11 +375,12 @@ public: std::vector stack; stack.reserve(model.getNumberOfStates()); + // Perform the loop as long as the set of states gets smaller. bool done = false; while (!done) { stack.clear(); storm::storage::BitVector* nextStates = new storm::storage::BitVector(psiStates); - psiStates.addSetIndicesToList(stack); + psiStates.addSetIndicesToVector(stack); while (!stack.empty()) { uint_fast64_t currentState = stack.back(); @@ -411,10 +421,16 @@ public: delete nextStates; } - *statesWithProbability1 = *currentStates; + statesWithProbability1 = *currentStates; delete currentStates; } + /* + * Performs a decomposition of the given matrix and vector indicating the nondeterministic + * choices into SCCs. + * + * @param + */ template static void performSccDecomposition(storm::storage::SparseMatrix const& matrix, std::vector const& nondeterministicChoiceIndices, std::vector>& stronglyConnectedComponents, storm::models::GraphTransitions& stronglyConnectedComponentsDependencyGraph) { LOG4CPLUS_INFO(logger, "Computing SCC decomposition."); From fc67cf4e3f66399d2db75cc9d0b1cdd5cd5d0331 Mon Sep 17 00:00:00 2001 From: dehnert Date: Thu, 9 May 2013 23:16:35 +0200 Subject: [PATCH 108/152] Further refactoring of GraphAnalyzer class. --- .../SparseDtmcPrctlModelChecker.h | 10 +- src/modelchecker/SparseMdpPrctlModelChecker.h | 15 +- src/storage/BitVector.h | 9 ++ src/utility/GraphAnalyzer.h | 131 +++++++++--------- 4 files changed, 89 insertions(+), 76 deletions(-) diff --git a/src/modelchecker/SparseDtmcPrctlModelChecker.h b/src/modelchecker/SparseDtmcPrctlModelChecker.h index a6d132745..f55f79db5 100644 --- a/src/modelchecker/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/SparseDtmcPrctlModelChecker.h @@ -212,12 +212,9 @@ public: // Then, we need to identify the states which have to be taken out of the matrix, i.e. // all states that have probability 0 and 1 of satisfying the until-formula. std::pair statesWithProbability01 = storm::utility::GraphAnalyzer::performProb01(this->getModel(), *leftStates, *rightStates); - storm::storage::BitVector statesWithProbability0 = statesWithProbability01.first; - storm::storage::BitVector statesWithProbability1 = statesWithProbability01.second; + storm::storage::BitVector statesWithProbability0 = std::move(statesWithProbability01.first); + storm::storage::BitVector statesWithProbability1 = std::move(statesWithProbability01.second); - std::cout << statesWithProbability0.toString() << std::endl; - std::cout << statesWithProbability1.toString() << std::endl; - // Delete intermediate results that are obsolete now. delete leftStates; delete rightStates; @@ -361,9 +358,8 @@ public: storm::storage::BitVector* targetStates = formula.getChild().check(*this); // Determine which states have a reward of infinity by definition. - storm::storage::BitVector infinityStates(this->getModel().getNumberOfStates()); storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); - storm::utility::GraphAnalyzer::performProb1(this->getModel(), trueStates, *targetStates, infinityStates); + storm::storage::BitVector infinityStates = storm::utility::GraphAnalyzer::performProb1(this->getModel(), trueStates, *targetStates); infinityStates.complement(); // Create resulting vector. diff --git a/src/modelchecker/SparseMdpPrctlModelChecker.h b/src/modelchecker/SparseMdpPrctlModelChecker.h index 50b20c81d..b9c80e24b 100644 --- a/src/modelchecker/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/SparseMdpPrctlModelChecker.h @@ -213,13 +213,14 @@ public: // Then, we need to identify the states which have to be taken out of the matrix, i.e. // all states that have probability 0 and 1 of satisfying the until-formula. - storm::storage::BitVector statesWithProbability0(this->getModel().getNumberOfStates()); - storm::storage::BitVector statesWithProbability1(this->getModel().getNumberOfStates()); + std::pair statesWithProbability01; if (this->minimumOperatorStack.top()) { - storm::utility::GraphAnalyzer::performProb01Min(this->getModel(), *leftStates, *rightStates, statesWithProbability0, statesWithProbability1); + statesWithProbability01 = storm::utility::GraphAnalyzer::performProb01Min(this->getModel(), *leftStates, *rightStates); } else { - storm::utility::GraphAnalyzer::performProb01Max(this->getModel(), *leftStates, *rightStates, statesWithProbability0, statesWithProbability1); + statesWithProbability01 = storm::utility::GraphAnalyzer::performProb01Max(this->getModel(), *leftStates, *rightStates); } + storm::storage::BitVector statesWithProbability0 = std::move(statesWithProbability01.first); + storm::storage::BitVector statesWithProbability1 = std::move(statesWithProbability01.second); // Delete sub-results that are obsolete now. delete leftStates; @@ -356,12 +357,12 @@ public: storm::storage::BitVector* targetStates = formula.getChild().check(*this); // Determine which states have a reward of infinity by definition. - storm::storage::BitVector infinityStates(this->getModel().getNumberOfStates()); + storm::storage::BitVector infinityStates; storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); if (this->minimumOperatorStack.top()) { - storm::utility::GraphAnalyzer::performProb1A(this->getModel(), trueStates, *targetStates, infinityStates); + infinityStates = storm::utility::GraphAnalyzer::performProb1A(this->getModel(), trueStates, *targetStates); } else { - storm::utility::GraphAnalyzer::performProb1E(this->getModel(), trueStates, *targetStates, infinityStates); + infinityStates = storm::utility::GraphAnalyzer::performProb1E(this->getModel(), trueStates, *targetStates); } infinityStates.complement(); diff --git a/src/storage/BitVector.h b/src/storage/BitVector.h index 6787fe0e3..fe5cb5a30 100644 --- a/src/storage/BitVector.h +++ b/src/storage/BitVector.h @@ -191,6 +191,7 @@ public: * given bit vector by means of a deep copy. */ BitVector& operator=(BitVector const& bv) { + LOG4CPLUS_DEBUG(logger, "Performing copy assignment."); // Check if we need to dispose of our current storage. if (this->bucketArray != nullptr) { delete[] this->bucketArray; @@ -204,7 +205,15 @@ public: return *this; } + /*! + * Move assigns the given bit vector to the current bit vector. + * + * @param bv The bit vector whose content is moved to the current bit vector. + * @return A reference to this bit vector after the contents of the given bit vector + * have been moved into it. + */ BitVector& operator=(BitVector&& bv) { + LOG4CPLUS_DEBUG(logger, "Performing move assignment."); // Only perform the assignment if the source and target are not identical. if (this != &bv) { // Check if we need to dispose of our current storage. diff --git a/src/utility/GraphAnalyzer.h b/src/utility/GraphAnalyzer.h index 573d2baa6..17971a407 100644 --- a/src/utility/GraphAnalyzer.h +++ b/src/utility/GraphAnalyzer.h @@ -120,10 +120,8 @@ public: */ template static storm::storage::BitVector performProb1(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { - storm::storage::BitVector statesWithProbabilityGreater0(model.getNumberOfStates()); - storm::storage::BitVector statesWithProbability1(model.getNumberOfStates()); - GraphAnalyzer::performProbGreater0(model, phiStates, psiStates, statesWithProbabilityGreater0); - GraphAnalyzer::performProbGreater0(model, ~psiStates, ~(statesWithProbabilityGreater0), statesWithProbability1); + storm::storage::BitVector statesWithProbabilityGreater0 = GraphAnalyzer::performProbGreater0(model, phiStates, psiStates); + storm::storage::BitVector statesWithProbability1 = GraphAnalyzer::performProbGreater0(model, ~psiStates, ~(statesWithProbabilityGreater0)); statesWithProbability1.complement(); return statesWithProbability1; } @@ -136,15 +134,14 @@ public: * @param model The model whose graph structure to search. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. - * @param statesWithProbability0 A pointer to a bit vector that is initially empty and will - * contain all states with probability 0 after the invocation of the function. - * @param statesWithProbability1 A pointer to a bit vector that is initially empty and will - * contain all states with probability 1 after the invocation of the function. + * @return A pair of bit vectors that represent all states with probability 0 and 1, respectively. */ template - static void performProb01Max(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector& statesWithProbability0, storm::storage::BitVector& statesWithProbability1) { - GraphAnalyzer::performProb0A(model, phiStates, psiStates, statesWithProbability0); - GraphAnalyzer::performProb1E(model, phiStates, psiStates, statesWithProbability1); + static std::pair performProb01Max(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + std::pair result; + result.first = GraphAnalyzer::performProb0A(model, phiStates, psiStates); + result.second = GraphAnalyzer::performProb1E(model, phiStates, psiStates); + return result; } /*! @@ -156,11 +153,13 @@ public: * @param model The model whose graph structure to search. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. - * @param statesWithProbability0 A pointer to a bit vector that is initially empty and will - * contain all states with probability 0 after the invocation of the function. + * @return A bit vector that represents all states with probability 0. */ template - static void performProb0A(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector& statesWithProbability0) { + static storm::storage::BitVector performProb0A(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + // Prepare the resulting bit vector. + storm::storage::BitVector statesWithProbability0(model.getNumberOfStates()); + // Get the backwards transition relation from the model to ease the search. storm::models::GraphTransitions backwardTransitions(*model.getTransitionMatrix(), *model.getNondeterministicChoiceIndices(), false); @@ -185,8 +184,9 @@ public: } } - // Finally, invert the computed set of states. + // Finally, invert the computed set of states and return result. statesWithProbability0.complement(); + return statesWithProbability0; } /*! @@ -198,19 +198,18 @@ public: * @param model The model whose graph structure to search. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. - * @param statesWithProbability1 A pointer to a bit vector that is initially empty and will - * contain all states with probability 1 after the invocation of the function. + * @return A bit vector that represents all states with probability 1. */ template - static void performProb1E(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector& statesWithProbability1) { - // Get some temporaries for convenience. + static storm::storage::BitVector performProb1E(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + // Get some temporaries for convenience. std::shared_ptr> transitionMatrix = model.getTransitionMatrix(); std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); // Get the backwards transition relation from the model to ease the search. storm::models::GraphTransitions backwardTransitions(*model.getTransitionMatrix(), *model.getNondeterministicChoiceIndices(), false); - storm::storage::BitVector* currentStates = new storm::storage::BitVector(model.getNumberOfStates(), true); + storm::storage::BitVector currentStates(model.getNumberOfStates(), true); std::vector stack; stack.reserve(model.getNumberOfStates()); @@ -219,7 +218,7 @@ public: bool done = false; while (!done) { stack.clear(); - storm::storage::BitVector* nextStates = new storm::storage::BitVector(psiStates); + storm::storage::BitVector nextStates(psiStates); psiStates.addSetIndicesToVector(stack); while (!stack.empty()) { @@ -227,13 +226,13 @@ public: stack.pop_back(); for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) { - if (phiStates.get(*it) && !nextStates->get(*it)) { + if (phiStates.get(*it) && !nextStates.get(*it)) { // Check whether the predecessor has only successors in the current state set for one of the // nondeterminstic choices. for (uint_fast64_t row = (*nondeterministicChoiceIndices)[*it]; row < (*nondeterministicChoiceIndices)[*it + 1]; ++row) { bool allSuccessorsInCurrentStates = true; for (auto colIt = transitionMatrix->constColumnIteratorBegin(row); colIt != transitionMatrix->constColumnIteratorEnd(row); ++colIt) { - if (!currentStates->get(*colIt)) { + if (!currentStates.get(*colIt)) { allSuccessorsInCurrentStates = false; break; } @@ -243,7 +242,7 @@ public: // add it to the set of states for the next iteration and perform a backward search from // that state. if (allSuccessorsInCurrentStates) { - nextStates->set(*it, true); + nextStates.set(*it, true); stack.push_back(*it); break; } @@ -253,16 +252,14 @@ public: } // Check whether we need to perform an additional iteration. - if (*currentStates == *nextStates) { + if (currentStates == nextStates) { done = true; } else { - *currentStates = *nextStates; + currentStates = std::move(nextStates); } - delete nextStates; } - statesWithProbability1 = *currentStates; - delete currentStates; + return currentStates; } /*! * Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi @@ -272,15 +269,14 @@ public: * @param model The model whose graph structure to search. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. - * @param statesWithProbability0 A pointer to a bit vector that is initially empty and will - * contain all states with probability 0 after the invocation of the function. - * @param statesWithProbability1 A pointer to a bit vector that is initially empty and will - * contain all states with probability 1 after the invocation of the function. + * @return A pair of bit vectors that represent all states with probability 0 and 1, respectively. */ template - static void performProb01Min(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector& statesWithProbability0, storm::storage::BitVector& statesWithProbability1) { - GraphAnalyzer::performProb0E(model, phiStates, psiStates, statesWithProbability0); - GraphAnalyzer::performProb1A(model, phiStates, psiStates, statesWithProbability1); + static std::pair performProb01Min(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + std::pair result; + result.first = GraphAnalyzer::performProb0E(model, phiStates, psiStates); + result.second = GraphAnalyzer::performProb1A(model, phiStates, psiStates); + return result; } /*! @@ -292,11 +288,13 @@ public: * @param model The model whose graph structure to search. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. - * @param statesWithProbability0 A pointer to a bit vector that is initially empty and will - * contain all states with probability 0 after the invocation of the function. + * @return A bit vector that represents all states with probability 0. */ template - static void performProb0E(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector& statesWithProbability0) { + static storm::storage::BitVector performProb0E(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + // Prepare resulting bit vector. + storm::storage::BitVector statesWithProbability0(model.getNumberOfStates()); + // Get some temporaries for convenience. std::shared_ptr> transitionMatrix = model.getTransitionMatrix(); std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); @@ -347,6 +345,7 @@ public: } statesWithProbability0.complement(); + return statesWithProbability0; } /*! @@ -358,11 +357,10 @@ public: * @param model The model whose graph structure to search. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. - * @param statesWithProbability1 A pointer to a bit vector that is initially empty and will - * contain all states with probability 1 after the invocation of the function. + * @return A bit vector that represents all states with probability 0. */ template - static void performProb1A(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector& statesWithProbability1) { + static storm::storage::BitVector performProb1A(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { // Get some temporaries for convenience. std::shared_ptr> transitionMatrix = model.getTransitionMatrix(); std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); @@ -370,7 +368,7 @@ public: // Get the backwards transition relation from the model to ease the search. storm::models::GraphTransitions backwardTransitions(*model.getTransitionMatrix(), *model.getNondeterministicChoiceIndices(), false); - storm::storage::BitVector* currentStates = new storm::storage::BitVector(model.getNumberOfStates(), true); + storm::storage::BitVector currentStates(model.getNumberOfStates(), true); std::vector stack; stack.reserve(model.getNumberOfStates()); @@ -379,7 +377,7 @@ public: bool done = false; while (!done) { stack.clear(); - storm::storage::BitVector* nextStates = new storm::storage::BitVector(psiStates); + storm::storage::BitVector nextStates(psiStates); psiStates.addSetIndicesToVector(stack); while (!stack.empty()) { @@ -387,13 +385,13 @@ public: stack.pop_back(); for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) { - if (phiStates.get(*it) && !nextStates->get(*it)) { + if (phiStates.get(*it) && !nextStates.get(*it)) { // Check whether the predecessor has only successors in the current state set for all of the // nondeterminstic choices. bool allSuccessorsInCurrentStatesForAllChoices = true; for (uint_fast64_t row = (*nondeterministicChoiceIndices)[*it]; row < (*nondeterministicChoiceIndices)[*it + 1]; ++row) { for (auto colIt = transitionMatrix->constColumnIteratorBegin(row); colIt != transitionMatrix->constColumnIteratorEnd(row); ++colIt) { - if (!currentStates->get(*colIt)) { + if (!currentStates.get(*colIt)) { allSuccessorsInCurrentStatesForAllChoices = false; goto afterCheckLoop; } @@ -405,7 +403,7 @@ public: // add it to the set of states for the next iteration and perform a backward search from // that state. if (allSuccessorsInCurrentStatesForAllChoices) { - nextStates->set(*it, true); + nextStates.set(*it, true); stack.push_back(*it); } } @@ -413,39 +411,46 @@ public: } // Check whether we need to perform an additional iteration. - if (*currentStates == *nextStates) { + if (currentStates == nextStates) { done = true; } else { - *currentStates = *nextStates; + currentStates = std::move(nextStates); } - delete nextStates; } - - statesWithProbability1 = *currentStates; - delete currentStates; + return currentStates; } - /* - * Performs a decomposition of the given matrix and vector indicating the nondeterministic - * choices into SCCs. + /*! + * Performs a decomposition of the given matrix belonging to a nondeterministic model and vector indicating the + * nondeterministic choices into SCCs. * - * @param + * @param matrix The matrix of the nondeterminstic model to decompose. + * @param nondeterministicChoiceIndices A vector indicating the non-deterministic choices of each state in the matrix. + * @return A pair whose first component represents the SCCs and whose second component represents the dependency + * transitions of the SCCs. */ template - static void performSccDecomposition(storm::storage::SparseMatrix const& matrix, std::vector const& nondeterministicChoiceIndices, std::vector>& stronglyConnectedComponents, storm::models::GraphTransitions& stronglyConnectedComponentsDependencyGraph) { + static std::pair>, storm::models::GraphTransitions> performSccDecomposition(storm::storage::SparseMatrix const& matrix, std::vector const& nondeterministicChoiceIndices) { LOG4CPLUS_INFO(logger, "Computing SCC decomposition."); - // Get the forward transition relation from the model to ease the search. storm::models::GraphTransitions forwardTransitions(matrix, nondeterministicChoiceIndices, true); // Perform the actual SCC decomposition based on the graph-transitions of the system. - performSccDecomposition(nondeterministicChoiceIndices.size() - 1, forwardTransitions, stronglyConnectedComponents, stronglyConnectedComponentsDependencyGraph); - + std::pair>, storm::models::GraphTransitions> result = performSccDecomposition(nondeterministicChoiceIndices.size() - 1, forwardTransitions); LOG4CPLUS_INFO(logger, "Done computing SCC decomposition."); + + return result; } + /*! + * Performs a topological sort of the states of the system according to the given transitions. + * + * @param transitions The transitions of the graph structure. + * @return A vector of indices that is a topological sort of the states. + */ template - static void getTopologicalSort(storm::models::GraphTransitions const& transitions, std::vector& topologicalSort) { + static std::vector getTopologicalSort(storm::models::GraphTransitions const& transitions) { + std::vector topologicalSort; topologicalSort.reserve(transitions.getNumberOfStates()); std::vector recursionStack; @@ -503,6 +508,8 @@ public: } } } + + return topologicalSort; } private: From ab11d3c2070a7a984ac4049681f9a91e914ca275 Mon Sep 17 00:00:00 2001 From: dehnert Date: Thu, 9 May 2013 23:38:38 +0200 Subject: [PATCH 109/152] Further refactoring of GraphAnalyzer class. Some comments are still missing and GraphAnalyzer should be made a namespace instead of a class with static methods only. --- ...ologicalValueIterationMdpPrctlModelChecker.h | 10 +++++----- src/utility/GraphAnalyzer.h | 17 +++++++++++------ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/modelchecker/TopologicalValueIterationMdpPrctlModelChecker.h b/src/modelchecker/TopologicalValueIterationMdpPrctlModelChecker.h index 248749624..1466c02ec 100644 --- a/src/modelchecker/TopologicalValueIterationMdpPrctlModelChecker.h +++ b/src/modelchecker/TopologicalValueIterationMdpPrctlModelChecker.h @@ -67,11 +67,11 @@ private: bool relative = s->get("relative"); // Now, we need to determine the SCCs of the MDP and a topological sort. - std::vector> stronglyConnectedComponents; - storm::models::GraphTransitions stronglyConnectedComponentsDependencyGraph; - storm::utility::GraphAnalyzer::performSccDecomposition(matrix, nondeterministicChoiceIndices, stronglyConnectedComponents, stronglyConnectedComponentsDependencyGraph); - std::vector topologicalSort; - storm::utility::GraphAnalyzer::getTopologicalSort(stronglyConnectedComponentsDependencyGraph, topologicalSort); + std::pair>, storm::models::GraphTransitions> sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(this->getModel(), stronglyConnectedComponents, stronglyConnectedComponentsDependencyGraph); + std::vector> stronglyConnectedComponents = std::move(sccDecomposition.first); + storm::models::GraphTransitions stronglyConnectedComponentsDependencyGraph = std::move(sccDecomposition.second); + + std::vector topologicalSort = storm::utility::GraphAnalyzer::getTopologicalSort(stronglyConnectedComponentsDependencyGraph); // Set up the environment for the power method. std::vector multiplyResult(matrix.getRowCount()); diff --git a/src/utility/GraphAnalyzer.h b/src/utility/GraphAnalyzer.h index 17971a407..9f33a2f7f 100644 --- a/src/utility/GraphAnalyzer.h +++ b/src/utility/GraphAnalyzer.h @@ -430,10 +430,12 @@ public: * transitions of the SCCs. */ template - static std::pair>, storm::models::GraphTransitions> performSccDecomposition(storm::storage::SparseMatrix const& matrix, std::vector const& nondeterministicChoiceIndices) { + static std::pair>, storm::models::GraphTransitions> performSccDecomposition(storm::models::AbstractNondeterministicModel const& model) { LOG4CPLUS_INFO(logger, "Computing SCC decomposition."); - // Get the forward transition relation from the model to ease the search. - storm::models::GraphTransitions forwardTransitions(matrix, nondeterministicChoiceIndices, true); + + // Get the forward transition relation from the model to ease the search. + std::vector const& nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); + storm::models::GraphTransitions forwardTransitions(model.getTransitionMatrix(), nondeterministicChoiceIndices, true); // Perform the actual SCC decomposition based on the graph-transitions of the system. std::pair>, storm::models::GraphTransitions> result = performSccDecomposition(nondeterministicChoiceIndices.size() - 1, forwardTransitions); @@ -514,7 +516,9 @@ public: private: template - static void performSccDecomposition(uint_fast64_t numberOfStates, storm::models::GraphTransitions const& forwardTransitions, std::vector>& stronglyConnectedComponents, storm::models::GraphTransitions& stronglyConnectedComponentsDependencyGraph) { + static std::pair>, storm::models::GraphTransitions> performSccDecomposition(uint_fast64_t numberOfStates, storm::models::GraphTransitions const& forwardTransitions) { + std::pair>, storm::models::GraphTransitions> sccDecomposition; + std::vector tarjanStack; tarjanStack.reserve(numberOfStates); storm::storage::BitVector tarjanStackStates(numberOfStates); @@ -528,11 +532,12 @@ private: uint_fast64_t currentIndex = 0; for (uint_fast64_t state = 0; state < numberOfStates; ++state) { if (!visitedStates.get(state)) { - performSccDecompositionHelper(state, currentIndex, stateIndices, lowlinks, tarjanStack, tarjanStackStates, visitedStates, forwardTransitions, stronglyConnectedComponents, stateToSccMap); + performSccDecompositionHelper(state, currentIndex, stateIndices, lowlinks, tarjanStack, tarjanStackStates, visitedStates, forwardTransitions, sccDecomposition.first, stateToSccMap); } } - stronglyConnectedComponentsDependencyGraph = storm::models::GraphTransitions(forwardTransitions, stronglyConnectedComponents, stateToSccMap); + sccDecomposition.second = storm::models::GraphTransitions(forwardTransitions, sccDecomposition.first, stateToSccMap); + return sccDecomposition; } template From 21e374086781c857b95577ac5d90a2e218b64447 Mon Sep 17 00:00:00 2001 From: gereon Date: Sat, 11 May 2013 13:53:52 +0200 Subject: [PATCH 110/152] Fixed bug in computation of number of choices in case of deadlocks. --- src/adapters/ExplicitModelAdapter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index ad69887a0..aabc0e963 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -520,6 +520,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { // This is a deadlock state. if (storm::settings::instance()->isSet("fix-deadlocks")) { this->numberOfTransitions++; + this->numberOfChoices++; this->transitionMap[curIndex].emplace_back(); this->transitionMap[curIndex].back().second[curIndex] = 1; } else { From 8cdb6d5394c8bc2f5ffe7c36459e9f0edea6164f Mon Sep 17 00:00:00 2001 From: gereon Date: Sat, 11 May 2013 14:43:51 +0200 Subject: [PATCH 111/152] Put initial state in stateToIndexMap --- src/adapters/ExplicitModelAdapter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index aabc0e963..dc4080ce4 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -259,6 +259,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { } } } + stateToIndexMap[this->allStates[0]] = 0; LOG4CPLUS_DEBUG(logger, "Generated " << this->allStates.size() << " initial states."); } From 54954569917c2ed45465e49746f9447689be5eb7 Mon Sep 17 00:00:00 2001 From: gereon Date: Sat, 11 May 2013 16:07:44 +0200 Subject: [PATCH 112/152] Added new log level "trace" Fixed bug in ExplicitModelAdapter --- src/adapters/ExplicitModelAdapter.cpp | 23 ++++++++++++++++++----- src/adapters/ExplicitModelAdapter.h | 10 ++++++++++ src/ir/Module.cpp | 4 ++-- src/ir/Module.h | 2 +- src/ir/Program.cpp | 22 ++++++++++++++++++++++ src/ir/Program.h | 2 ++ src/parser/PrismParser/VariableState.cpp | 10 +++++----- src/storm.cpp | 4 ++++ src/utility/Settings.cpp | 1 + 9 files changed, 65 insertions(+), 13 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index dc4080ce4..1bc602797 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -16,6 +16,8 @@ typedef std::pair, std::vector> StateType; +#include + #include "log4cplus/logger.h" #include "log4cplus/loggingmacros.h" extern log4cplus::Logger logger; @@ -95,6 +97,13 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { std::get<1>(*state)[index] = value; } + std::string ExplicitModelAdapter::toString(StateType const * const state) { + std::stringstream ss; + for (unsigned int i = 0; i < state->first.size(); i++) ss << state->first[i] << "\t"; + for (unsigned int i = 0; i < state->second.size(); i++) ss << state->second[i] << "\t"; + return ss.str(); + } + std::shared_ptr> ExplicitModelAdapter::getStateRewards(std::vector const & rewards) { std::shared_ptr> results(new std::vector(this->allStates.size())); for (uint_fast64_t index = 0; index < this->allStates.size(); index++) { @@ -193,12 +202,16 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { * @return Resulting state. */ StateType* ExplicitModelAdapter::applyUpdate(StateType const * const state, storm::ir::Update const& update) const { + return this->applyUpdate(state, state, update); + } + + StateType* ExplicitModelAdapter::applyUpdate(StateType const * const state, StateType const * const baseState, storm::ir::Update const& update) const { StateType* newState = new StateType(*state); for (auto assignedVariable : update.getBooleanAssignments()) { - setValue(newState, this->booleanVariableToIndexMap.at(assignedVariable.first), assignedVariable.second.getExpression()->getValueAsBool(state)); + setValue(newState, this->booleanVariableToIndexMap.at(assignedVariable.first), assignedVariable.second.getExpression()->getValueAsBool(baseState)); } for (auto assignedVariable : update.getIntegerAssignments()) { - setValue(newState, this->integerVariableToIndexMap.at(assignedVariable.first), assignedVariable.second.getExpression()->getValueAsInt(state)); + setValue(newState, this->integerVariableToIndexMap.at(assignedVariable.first), assignedVariable.second.getExpression()->getValueAsInt(baseState)); } return newState; } @@ -364,7 +377,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { // Iterate over all resultStates. for (auto it : resultStates) { // Apply the new update and get resulting state. - StateType* newState = this->applyUpdate(it.first, update); + StateType* newState = this->applyUpdate(it.first, this->allStates[stateID], update); probSum += update.getLikelihoodExpression()->getValueAsDouble(it.first); // Insert the new state into newStates array. // Take care of calculation of likelihood, combine identical states. @@ -425,7 +438,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { } numberOfTransitions += set.size(); } - LOG4CPLUS_DEBUG(logger, "Building deterministic transition matrix with " << numberOfTransitions << " transitions now."); + LOG4CPLUS_INFO(logger, "Building deterministic transition matrix: " << allStates.size() << " x " << allStates.size() << " with " << numberOfTransitions << " transitions."); // Now build matrix. std::shared_ptr> result(new storm::storage::SparseMatrix(allStates.size())); @@ -472,7 +485,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { * @return result matrix. */ std::shared_ptr> ExplicitModelAdapter::buildNondeterministicMatrix() { - LOG4CPLUS_DEBUG(logger, "Building nondeterministic transition matrix: " << this->numberOfChoices << " x " << allStates.size() << " with " << this->numberOfTransitions << " transitions now."); + LOG4CPLUS_INFO(logger, "Building nondeterministic transition matrix: " << this->numberOfChoices << " x " << allStates.size() << " with " << this->numberOfTransitions << " transitions."); std::shared_ptr> result(new storm::storage::SparseMatrix(this->numberOfChoices, allStates.size())); result->initialize(this->numberOfTransitions); if ((this->rewardModel != nullptr) && (this->rewardModel->hasTransitionRewards())) { diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 272d79c10..63cd91646 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -78,6 +78,7 @@ private: * @param value New value. */ static void setValue(StateType* const state, uint_fast64_t const index, int_fast64_t const value); + static std::string toString(StateType const * const state); /*! * Apply an update to the given state and return the resulting new state object. * This methods creates a copy of the given state. @@ -86,6 +87,15 @@ private: * @return Resulting state. */ StateType* applyUpdate(StateType const * const state, storm::ir::Update const& update) const; + /*! + * Apply an update to a given state and return the resulting new state object. + * Updates are done using the variable values from a given baseState. + * @params state State to be updated. + * @params baseState State used for update variables. + * @params update Update to be applied. + * @return Resulting state. + */ + StateType* applyUpdate(StateType const * const state, StateType const * const baseState, storm::ir::Update const& update) const; /*! * Reads and combines variables from all program modules and stores them. diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index 61c245b26..624f1876c 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -41,7 +41,7 @@ Module::Module(std::string moduleName, Module::Module(const Module& module, const std::string& moduleName, const std::map& renaming, std::shared_ptr adder) : moduleName(moduleName) { - LOG4CPLUS_DEBUG(logger, "Start renaming " << module.moduleName << " to " << moduleName); + LOG4CPLUS_TRACE(logger, "Start renaming " << module.moduleName << " to " << moduleName); // First step: Create new Variables via the adder. adder->performRenaming(renaming); @@ -79,7 +79,7 @@ Module::Module(const Module& module, const std::string& moduleName, const std::m } this->collectActions(); - LOG4CPLUS_DEBUG(logger, "Finished renaming..."); + LOG4CPLUS_TRACE(logger, "Finished renaming..."); } // Return the number of boolean variables. diff --git a/src/ir/Module.h b/src/ir/Module.h index 6fbe1658e..e4343e357 100644 --- a/src/ir/Module.h +++ b/src/ir/Module.h @@ -151,7 +151,7 @@ private: // A map of boolean variable names to their index. std::map booleanVariablesToIndexMap; - // A map of integer variable names to their details. + // A map of integer variable names to their index. std::map integerVariablesToIndexMap; // The commands associated with the module. diff --git a/src/ir/Program.cpp b/src/ir/Program.cpp index fd75d9b3e..96ad94b2b 100644 --- a/src/ir/Program.cpp +++ b/src/ir/Program.cpp @@ -118,6 +118,28 @@ std::map> P return this->labels; } +std::string Program::getVariableString() const { + std::map bools; + std::map ints; + unsigned maxInt = 0, maxBool = 0; + for (Module module: this->modules) { + for (unsigned int i = 0; i < module.getNumberOfBooleanVariables(); i++) { + storm::ir::BooleanVariable var = module.getBooleanVariable(i); + bools[var.getIndex()] = var.getName(); + if (var.getIndex() >= maxBool) maxBool = var.getIndex()+1; + } + for (unsigned int i = 0; i < module.getNumberOfIntegerVariables(); i++) { + storm::ir::IntegerVariable var = module.getIntegerVariable(i); + ints[var.getIndex()] = var.getName(); + if (var.getIndex() >= maxInt) maxInt = var.getIndex()+1; + } + } + std::stringstream ss; + for (unsigned int i = 0; i < maxBool; i++) ss << bools[i] << "\t"; + for (unsigned int i = 0; i < maxInt; i++) ss << ints[i] << "\t"; + return ss.str(); +} + } // namespace ir } // namepsace storm diff --git a/src/ir/Program.h b/src/ir/Program.h index a181bbcc3..c12b6dddd 100644 --- a/src/ir/Program.h +++ b/src/ir/Program.h @@ -113,6 +113,8 @@ public: */ std::map> getLabels() const; + std::string getVariableString() const; + private: // The type of the model. ModelType modelType; diff --git a/src/parser/PrismParser/VariableState.cpp b/src/parser/PrismParser/VariableState.cpp index 3634b8954..e9be69435 100644 --- a/src/parser/PrismParser/VariableState.cpp +++ b/src/parser/PrismParser/VariableState.cpp @@ -37,7 +37,7 @@ VariableState::VariableState(bool firstRun) uint_fast64_t VariableState::addBooleanVariable(const std::string& name) { if (firstRun) { std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::bool_, this->nextBooleanVariableIndex, name)); - LOG4CPLUS_DEBUG(logger, "Adding boolean variable " << name << " with new id " << this->nextBooleanVariableIndex); + LOG4CPLUS_TRACE(logger, "Adding boolean variable " << name << " with new id " << this->nextBooleanVariableIndex); this->booleanVariables_.add(name, varExpr); this->booleanVariableNames_.add(name, name); this->nextBooleanVariableIndex++; @@ -56,7 +56,7 @@ uint_fast64_t VariableState::addBooleanVariable(const std::string& name) { uint_fast64_t VariableState::addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper) { if (firstRun) { std::shared_ptr varExpr = std::shared_ptr(new VariableExpression(storm::ir::expressions::BaseExpression::int_, this->nextIntegerVariableIndex, name, lower, upper)); - LOG4CPLUS_DEBUG(logger, "Adding integer variable " << name << " with new id " << this->nextIntegerVariableIndex); + LOG4CPLUS_TRACE(logger, "Adding integer variable " << name << " with new id " << this->nextIntegerVariableIndex); this->integerVariables_.add(name, varExpr); this->integerVariableNames_.add(name, name); this->nextIntegerVariableIndex++; @@ -79,7 +79,7 @@ std::shared_ptr VariableState::getBooleanVariable(const std: return *res; } else { if (firstRun) { - LOG4CPLUS_DEBUG(logger, "Getting boolean variable " << name << ", was not yet created."); + LOG4CPLUS_TRACE(logger, "Getting boolean variable " << name << ", was not yet created."); return std::shared_ptr(new VariableExpression(BaseExpression::bool_, std::numeric_limits::max(), "bool", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); } else { LOG4CPLUS_ERROR(logger, "Getting boolean variable " << name << ", but was not found. This variable does not exist."); @@ -94,7 +94,7 @@ std::shared_ptr VariableState::getIntegerVariable(const std: return *res; } else { if (firstRun) { - LOG4CPLUS_DEBUG(logger, "Getting integer variable " << name << ", was not yet created."); + LOG4CPLUS_TRACE(logger, "Getting integer variable " << name << ", was not yet created."); return std::shared_ptr(new VariableExpression(BaseExpression::int_, std::numeric_limits::max(), "int", std::shared_ptr(nullptr), std::shared_ptr(nullptr))); } else { LOG4CPLUS_ERROR(logger, "Getting integer variable " << name << ", but was not found. This variable does not exist."); @@ -133,7 +133,7 @@ void VariableState::performRenaming(const std::map& re } std::string* oldCmdName = this->commandNames_.find(it.first); if (oldCmdName != nullptr) { - LOG4CPLUS_DEBUG(logger, "Adding new command name " << it.second << " due to module renaming."); + LOG4CPLUS_TRACE(logger, "Adding new command name " << it.second << " due to module renaming."); this->commandNames_.at(it.second) = it.second; } } diff --git a/src/storm.cpp b/src/storm.cpp index 4cc2f5e41..fe3f24dc4 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -137,6 +137,10 @@ bool parseOptions(const int argc, const char* argv[]) { logger.setLogLevel(log4cplus::DEBUG_LOG_LEVEL); LOG4CPLUS_INFO(logger, "Enable very verbose mode, log output gets printed to console."); } + if (s->isSet("trace")) { + logger.setLogLevel(log4cplus::TRACE_LOG_LEVEL); + LOG4CPLUS_INFO(logger, "Enable trace mode, log output gets printed to console."); + } if (s->isSet("logfile")) { setUpFileLogging(); } diff --git a/src/utility/Settings.cpp b/src/utility/Settings.cpp index d6e2f5bc3..6d3bb950d 100644 --- a/src/utility/Settings.cpp +++ b/src/utility/Settings.cpp @@ -132,6 +132,7 @@ void Settings::initDescriptions() { ("help,h", "produce help message") ("verbose,v", "be verbose") ("debug", "be very verbose, intended for debugging") + ("trace", "be extremely verbose, expect lots of output") ("logfile,l", bpo::value(), "name of the log file") ("configfile,c", bpo::value(), "name of config file") ("test-prctl", bpo::value(), "name of prctl file") From fad82908440c334f87bd00cedc1613ab2367cc52 Mon Sep 17 00:00:00 2001 From: gereon Date: Sat, 11 May 2013 17:12:55 +0200 Subject: [PATCH 113/152] Renamed WrongFileFormatException to WrongFormatException --- src/adapters/ExplicitModelAdapter.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index 1bc602797..57da1399d 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -2,7 +2,7 @@ #include "src/storage/SparseMatrix.h" #include "src/utility/Settings.h" -#include "src/exceptions/WrongFileFormatException.h" +#include "src/exceptions/WrongFormatException.h" #include "src/ir/Program.h" #include "src/ir/RewardModel.h" @@ -82,7 +82,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { break; default: LOG4CPLUS_ERROR(logger, "Error while creating model from probabilistic program: We can't handle this model type."); - throw storm::exceptions::WrongFileFormatException() << "Error while creating model from probabilistic program: We can't handle this model type."; + throw storm::exceptions::WrongFormatException() << "Error while creating model from probabilistic program: We can't handle this model type."; break; } @@ -341,7 +341,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { } if (std::abs(1 - probSum) > this->precision) { LOG4CPLUS_ERROR(logger, "Sum of update probabilities should be one for command:\n\t" << command.toString()); - throw storm::exceptions::WrongFileFormatException() << "Sum of update probabilities should be one for command:\n\t" << command.toString(); + throw storm::exceptions::WrongFormatException() << "Sum of update probabilities should be one for command:\n\t" << command.toString(); } } } @@ -391,7 +391,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { } if (std::abs(1 - probSum) > this->precision) { LOG4CPLUS_ERROR(logger, "Sum of update probabilities should be one for command:\n\t" << command.toString()); - throw storm::exceptions::WrongFileFormatException() << "Sum of update probabilities should be one for command:\n\t" << command.toString(); + throw storm::exceptions::WrongFormatException() << "Sum of update probabilities should be one for command:\n\t" << command.toString(); } } for (auto it: resultStates) { @@ -539,7 +539,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { this->transitionMap[curIndex].back().second[curIndex] = 1; } else { LOG4CPLUS_ERROR(logger, "Error while creating sparse matrix from probabilistic program: found deadlock state."); - throw storm::exceptions::WrongFileFormatException() << "Error while creating sparse matrix from probabilistic program: found deadlock state."; + throw storm::exceptions::WrongFormatException() << "Error while creating sparse matrix from probabilistic program: found deadlock state."; } } } From aafdbf7671f083797dc69db922945d006ee03cc4 Mon Sep 17 00:00:00 2001 From: gereon Date: Sat, 11 May 2013 17:30:20 +0200 Subject: [PATCH 114/152] Fixed errors due to merging. --- src/adapters/ExplicitModelAdapter.cpp | 13 +++++++------ src/adapters/ExplicitModelAdapter.h | 2 +- src/adapters/SymbolicModelAdapter.h | 4 ++-- src/parser/PrismParser.cpp | 4 ++-- src/parser/PrismParser/PrismGrammar.cpp | 3 --- src/storm.cpp | 2 +- 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index 57da1399d..298400acb 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -38,7 +38,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { this->clearInternalState(); } - std::shared_ptr ExplicitModelAdapter::getModel(std::string const & rewardModelName) { + std::shared_ptr> ExplicitModelAdapter::getModel(std::string const & rewardModelName) { this->buildTransitionMap(); @@ -61,24 +61,25 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { case storm::ir::Program::DTMC: { std::shared_ptr> matrix = this->buildDeterministicMatrix(); - return std::shared_ptr(new storm::models::Dtmc(matrix, stateLabeling, stateRewards, this->transitionRewards)); + return std::shared_ptr>(new storm::models::Dtmc(matrix, stateLabeling, stateRewards, this->transitionRewards)); break; } case storm::ir::Program::CTMC: { std::shared_ptr> matrix = this->buildDeterministicMatrix(); - return std::shared_ptr(new storm::models::Ctmc(matrix, stateLabeling, stateRewards, this->transitionRewards)); + return std::shared_ptr>(new storm::models::Ctmc(matrix, stateLabeling, stateRewards, this->transitionRewards)); break; } case storm::ir::Program::MDP: { std::shared_ptr> matrix = this->buildNondeterministicMatrix(); - return std::shared_ptr(new storm::models::Mdp(matrix, stateLabeling, stateRewards, this->transitionRewards)); + std::shared_ptr> choiceIndices; + return std::shared_ptr>(new storm::models::Mdp(matrix, stateLabeling, choiceIndices, stateRewards, this->transitionRewards)); break; } case storm::ir::Program::CTMDP: // Todo - //return std::shared_ptr(new storm::models::Ctmdp(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); + //return std::shared_ptr>(new storm::models::Ctmdp(matrix, stateLabeling, stateRewards, transitionRewardMatrix)); break; default: LOG4CPLUS_ERROR(logger, "Error while creating model from probabilistic program: We can't handle this model type."); @@ -86,7 +87,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { break; } - return std::shared_ptr(nullptr); + return std::shared_ptr>(nullptr); } void ExplicitModelAdapter::setValue(StateType* const state, uint_fast64_t const index, bool const value) { diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 63cd91646..1fe2e29a4 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -56,7 +56,7 @@ public: ExplicitModelAdapter(storm::ir::Program program); ~ExplicitModelAdapter(); - std::shared_ptr getModel(std::string const & rewardModelName = ""); + std::shared_ptr> getModel(std::string const & rewardModelName = ""); private: diff --git a/src/adapters/SymbolicModelAdapter.h b/src/adapters/SymbolicModelAdapter.h index f42d8f873..06b7dd37f 100644 --- a/src/adapters/SymbolicModelAdapter.h +++ b/src/adapters/SymbolicModelAdapter.h @@ -8,7 +8,7 @@ #ifndef STORM_ADAPTERS_SYMBOLICMODELADAPTER_H_ #define STORM_ADAPTERS_SYMBOLICMODELADAPTER_H_ -#include "src/exceptions/WrongFileFormatException.h" +#include "src/exceptions/WrongFormatException.h" #include "src/utility/CuddUtility.h" #include "SymbolicExpressionAdapter.h" @@ -255,7 +255,7 @@ private: storm::ir::IntegerVariable const& integerVariable = module.getIntegerVariable(j); uint_fast64_t integerRange = integerVariable.getUpperBound()->getValueAsInt(nullptr) - integerVariable.getLowerBound()->getValueAsInt(nullptr); if (integerRange <= 0) { - throw storm::exceptions::WrongFileFormatException() << "Range of variable " + throw storm::exceptions::WrongFormatException() << "Range of variable " << integerVariable.getName() << " is empty or negativ."; } uint_fast64_t numberOfDecisionDiagramVariables = static_cast(std::ceil(std::log2(integerRange))); diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 648962689..8057eda18 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -12,7 +12,7 @@ #include "src/parser/PrismParser/PrismGrammar.h" // If the parser fails due to ill-formed data, this exception is thrown. -#include "src/exceptions/WrongFileFormatException.h" +#include "src/exceptions/WrongFormatException.h" // Needed for file IO. #include @@ -117,7 +117,7 @@ storm::ir::Program PrismParser::parse(std::istream& inputStream, std::string con grammar.resetGrammars(); // Now propagate exception. - throw storm::exceptions::WrongFileFormatException() << msg.str(); + throw storm::exceptions::WrongFormatException() << msg.str(); } return result; diff --git a/src/parser/PrismParser/PrismGrammar.cpp b/src/parser/PrismParser/PrismGrammar.cpp index 1fb3ff00e..86f1319b9 100644 --- a/src/parser/PrismParser/PrismGrammar.cpp +++ b/src/parser/PrismParser/PrismGrammar.cpp @@ -18,9 +18,6 @@ #include "src/parser/PrismParser/IdentifierGrammars.h" #include "src/parser/PrismParser/VariableState.h" -// If the parser fails due to ill-formed data, this exception is thrown. -#include "src/exceptions/WrongFileFormatException.h" - // Needed for file IO. #include #include diff --git a/src/storm.cpp b/src/storm.cpp index d60700018..548399d38 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -27,7 +27,7 @@ #include "src/modelchecker/GmmxxMdpPrctlModelChecker.h" #include "src/parser/AutoParser.h" #include "src/parser/PrctlParser.h" -#include "src/solver/GraphAnalyzer.h" +//#include "src/solver/GraphAnalyzer.h" #include "src/utility/Settings.h" #include "src/utility/ErrorHandling.h" #include "src/formula/Prctl.h" From a8689804666b363cc264f26ffea1c33609a66f4c Mon Sep 17 00:00:00 2001 From: gereon Date: Sat, 11 May 2013 18:06:05 +0200 Subject: [PATCH 115/152] Fixed code so that tests compiles. --- src/models/AbstractNondeterministicModel.h | 9 +++++++++ src/models/Mdp.h | 8 -------- test/parser/ParsePrismTest.cpp | 3 ++- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/models/AbstractNondeterministicModel.h b/src/models/AbstractNondeterministicModel.h index 0ca1dea37..8b9eed511 100644 --- a/src/models/AbstractNondeterministicModel.h +++ b/src/models/AbstractNondeterministicModel.h @@ -51,6 +51,15 @@ class AbstractNondeterministicModel: public AbstractModel { // Intentionally left empty. } + + /*! + * Returns the number of choices for all states of the MDP. + * @return The number of choices for all states of the MDP. + */ + uint_fast64_t getNumberOfChoices() const { + return this->getTransitionMatrix()->getRowCount(); + } + /*! * Retrieves the size of the internal representation of the model in memory. * @return the size of the internal representation of the model in memory diff --git a/src/models/Mdp.h b/src/models/Mdp.h index 87c2322d7..586de6e5e 100644 --- a/src/models/Mdp.h +++ b/src/models/Mdp.h @@ -70,14 +70,6 @@ public: ~Mdp() { // Intentionally left empty. } - - /*! - * Returns the number of choices for all states of the MDP. - * @return The number of choices for all states of the MDP. - */ - uint_fast64_t getNumberOfChoices() const { - return this->probabilityMatrix->getRowCount(); - } storm::models::ModelType getType() const { return MDP; diff --git a/test/parser/ParsePrismTest.cpp b/test/parser/ParsePrismTest.cpp index b4155edfd..a2f23844e 100644 --- a/test/parser/ParsePrismTest.cpp +++ b/test/parser/ParsePrismTest.cpp @@ -1,9 +1,10 @@ #include "gtest/gtest.h" #include "storm-config.h" #include "src/parser/PrismParser.h" -#include "src/utility/IoUtility.h" +//#include "src/utility/IoUtility.h" #include "src/ir/Program.h" #include "src/adapters/ExplicitModelAdapter.h" +#include "src/models/Dtmc.h" #include "src/models/Mdp.h" TEST(ParsePrismTest, parseCrowds5_5) { From b28b8273623e46e264a08ed0a380ddbaf9f80436 Mon Sep 17 00:00:00 2001 From: dehnert Date: Sat, 11 May 2013 19:05:04 +0200 Subject: [PATCH 116/152] All methods of GraphAnalyzer: * commented, * return values instead of passing result variables by reference. --- src/utility/GraphAnalyzer.h | 43 ++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/src/utility/GraphAnalyzer.h b/src/utility/GraphAnalyzer.h index 9f33a2f7f..2b61b877d 100644 --- a/src/utility/GraphAnalyzer.h +++ b/src/utility/GraphAnalyzer.h @@ -421,13 +421,11 @@ public: } /*! - * Performs a decomposition of the given matrix belonging to a nondeterministic model and vector indicating the - * nondeterministic choices into SCCs. + * Performs a decomposition of the given nondetermistic model into its SCCs. * - * @param matrix The matrix of the nondeterminstic model to decompose. - * @param nondeterministicChoiceIndices A vector indicating the non-deterministic choices of each state in the matrix. + * @param model The nondeterminstic model to decompose. * @return A pair whose first component represents the SCCs and whose second component represents the dependency - * transitions of the SCCs. + * graph of the SCCs. */ template static std::pair>, storm::models::GraphTransitions> performSccDecomposition(storm::models::AbstractNondeterministicModel const& model) { @@ -455,12 +453,13 @@ public: std::vector topologicalSort; topologicalSort.reserve(transitions.getNumberOfStates()); + // Prepare the stacks needed for recursion. std::vector recursionStack; recursionStack.reserve(transitions.getNumberOfStates()); - std::vector::stateSuccessorIterator> iteratorRecursionStack; iteratorRecursionStack.reserve(transitions.getNumberOfStates()); + // Perform a depth-first search over the given transitions and record states in the reverse order they were visited. storm::storage::BitVector visitedStates(transitions.getNumberOfStates()); for (uint_fast64_t state = 0; state < transitions.getNumberOfStates(); ++state) { if (!visitedStates.get(state)) { @@ -515,20 +514,28 @@ public: } private: + /*! + * Performs an SCC decomposition of the system given by its forward transitions. + * + * @param forwardTransitions The (forward) transition relation of the model to decompose. + * @return A pair whose first component represents the SCCs and whose second component represents the dependency + * graph of the SCCs. + */ template - static std::pair>, storm::models::GraphTransitions> performSccDecomposition(uint_fast64_t numberOfStates, storm::models::GraphTransitions const& forwardTransitions) { + static std::pair>, storm::models::GraphTransitions> performSccDecomposition(storm::models::GraphTransitions const& forwardTransitions) { std::pair>, storm::models::GraphTransitions> sccDecomposition; - + uint_fast64_t numberOfStates = forwardTransitions.getNumberOfStates(); + + // Set up the environment of Tarjan's algorithm. std::vector tarjanStack; tarjanStack.reserve(numberOfStates); storm::storage::BitVector tarjanStackStates(numberOfStates); - std::vector stateIndices(numberOfStates); std::vector lowlinks(numberOfStates); storm::storage::BitVector visitedStates(numberOfStates); - std::map stateToSccMap; + // Start the search for SCCs from every vertex in the graph structure, because there is. uint_fast64_t currentIndex = 0; for (uint_fast64_t state = 0; state < numberOfStates; ++state) { if (!visitedStates.get(state)) { @@ -536,10 +543,26 @@ private: } } + // Finally, determine the dependency graph over the SCCs and return result. sccDecomposition.second = storm::models::GraphTransitions(forwardTransitions, sccDecomposition.first, stateToSccMap); return sccDecomposition; } + /*! + * Performs an SCC decomposition using Tarjan's algorithm. + * + * @param startState The state at which the search is started. + * @param currentIndex The index that is to be used as the next free index. + * @param stateIndices The vector that stores the index for each state. + * @param lowlinks A vector that stores the lowlink of each state, i.e. the lowest index of a state reachable from + * a particular state. + * @param tarjanStack A stack used for Tarjan's algorithm. + * @param tarjanStackStates A bit vector that represents all states that are currently contained in tarjanStack. + * @param visitedStates A bit vector that stores all states that have already been visited. + * @param forwardTransitions The (forward) transition relation of the graph structure. + * @param stronglyConnectedComponents A vector of strongly connected components to which newly found SCCs are added. + * @param stateToSccMap A mapping from state indices to SCC indices that maps each state to its SCC. + */ template static void performSccDecompositionHelper(uint_fast64_t startState, uint_fast64_t& currentIndex, std::vector& stateIndices, std::vector& lowlinks, std::vector& tarjanStack, storm::storage::BitVector& tarjanStackStates, storm::storage::BitVector& visitedStates, storm::models::GraphTransitions const& forwardTransitions, std::vector>& stronglyConnectedComponents, std::map& stateToSccMap) { // Create the stacks needed for turning the recursive formulation of Tarjan's algorithm From 69395face217aa8da9e76d5b3ed4152651afc45e Mon Sep 17 00:00:00 2001 From: dehnert Date: Sun, 12 May 2013 22:09:43 +0200 Subject: [PATCH 117/152] Moved creation of SCC-dependency graph into abstract model class. Added functionality to sparse matrix class to not give the number of nonzeros upfront, but to to grow on demand. --- src/models/AbstractDeterministicModel.h | 41 ++++++++ src/models/AbstractModel.h | 10 +- src/models/AbstractNondeterministicModel.h | 44 +++++++- src/models/GraphTransitions.h | 32 ------ src/storage/SparseMatrix.h | 79 +++++++++++--- src/utility/GraphAnalyzer.h | 114 ++++++++++----------- 6 files changed, 208 insertions(+), 112 deletions(-) diff --git a/src/models/AbstractDeterministicModel.h b/src/models/AbstractDeterministicModel.h index aa44ba736..f7594ba05 100644 --- a/src/models/AbstractDeterministicModel.h +++ b/src/models/AbstractDeterministicModel.h @@ -45,6 +45,47 @@ class AbstractDeterministicModel: public AbstractModel { AbstractDeterministicModel(AbstractDeterministicModel const& other) : AbstractModel(other) { // Intentionally left empty. } + + /*! + * Extracts the SCC dependency graph from the model according to the given SCC decomposition. + * + * @param stronglyConnectedComponents A vector containing the SCCs of the system. + * @param stateToSccMap A mapping from state indices to + */ + virtual storm::storage::SparseMatrix extractSccDependencyGraph(std::vector> const& stronglyConnectedComponents, std::map const& stateToSccMap) { + // The resulting sparse matrix will have as many rows/columns as there are SCCs. + uint_fast64_t numberOfStates = stronglyConnectedComponents.size(); + storm::storage::SparseMatrix sccDependencyGraph(numberOfStates); + sccDependencyGraph.initialize(); + + for (uint_fast64_t currentSccIndex = 0; currentSccIndex < stronglyConnectedComponents.size(); ++currentSccIndex) { + // Get the actual SCC. + std::vector const& scc = stronglyConnectedComponents[currentSccIndex]; + + // Now, we determine the SCCs which are reachable (in one step) from the current SCC. + std::set allTargetSccs; + for (auto state : scc) { + for (typename storm::storage::SparseMatrix::ConstIndexIterator succIt = this->getTransitionMatrix()->constColumnIteratorBegin(state), succIte = this->getTransitionMatrix()->constColumnIteratorEnd(state); succIt != succIte; ++succIt) { + uint_fast64_t targetScc = stateToSccMap.find(*succIt)->second; + + // We only need to consider transitions that are actually leaving the SCC. + if (targetScc != currentSccIndex) { + allTargetSccs.insert(targetScc); + } + } + } + + // Now we can just enumerate all the target SCCs and insert the corresponding transitions. + for (auto targetScc : allTargetSccs) { + sccDependencyGraph.insertNextValue(currentSccIndex, targetScc, true); + } + } + + // Finalize the matrix. + sccDependencyGraph.finalize(true); + + return sccDependencyGraph; + } }; } // namespace models diff --git a/src/models/AbstractModel.h b/src/models/AbstractModel.h index 58d621ee8..364e501b0 100644 --- a/src/models/AbstractModel.h +++ b/src/models/AbstractModel.h @@ -85,6 +85,14 @@ class AbstractModel: public std::enable_shared_from_this> { */ virtual ModelType getType() const = 0; + /*! + * Extracts the SCC dependency graph from the model according to the given SCC decomposition. + * + * @param stronglyConnectedComponents A vector containing the SCCs of the system. + * @param stateToSccMap A mapping from state indices to + */ + virtual storm::storage::SparseMatrix extractSccDependencyGraph(std::vector> const& stronglyConnectedComponents, std::map const& stateToSccMap) = 0; + /*! * Returns the state space size of the model. * @return The size of the state space of the model. @@ -151,7 +159,7 @@ class AbstractModel: public std::enable_shared_from_this> { * Returns the set of states with which the given state is labeled. * @return The set of states with which the given state is labeled. */ - std::set const getPropositionsForState(uint_fast64_t const &state) const { + std::set const getPropositionsForState(uint_fast64_t const& state) const { return stateLabeling->getPropositionsForState(state); } diff --git a/src/models/AbstractNondeterministicModel.h b/src/models/AbstractNondeterministicModel.h index 8b9eed511..4c51f0863 100644 --- a/src/models/AbstractNondeterministicModel.h +++ b/src/models/AbstractNondeterministicModel.h @@ -51,7 +51,6 @@ class AbstractNondeterministicModel: public AbstractModel { // Intentionally left empty. } - /*! * Returns the number of choices for all states of the MDP. * @return The number of choices for all states of the MDP. @@ -60,6 +59,49 @@ class AbstractNondeterministicModel: public AbstractModel { return this->getTransitionMatrix()->getRowCount(); } + /*! + * Extracts the SCC dependency graph from the model according to the given SCC decomposition. + * + * @param stronglyConnectedComponents A vector containing the SCCs of the system. + * @param stateToSccMap A mapping from state indices to + */ + virtual storm::storage::SparseMatrix extractSccDependencyGraph(std::vector> const& stronglyConnectedComponents, std::map const& stateToSccMap) { + // The resulting sparse matrix will have as many rows/columns as there are SCCs. + uint_fast64_t numberOfStates = stronglyConnectedComponents.size(); + storm::storage::SparseMatrix sccDependencyGraph(numberOfStates); + sccDependencyGraph.initialize(); + + for (uint_fast64_t currentSccIndex = 0; currentSccIndex < stronglyConnectedComponents.size(); ++currentSccIndex) { + // Get the actual SCC. + std::vector const& scc = stronglyConnectedComponents[currentSccIndex]; + + // Now, we determine the SCCs which are reachable (in one step) from the current SCC. + std::set allTargetSccs; + for (auto state : scc) { + for (uint_fast64_t rowIndex = (*nondeterministicChoiceIndices)[state]; rowIndex < (*nondeterministicChoiceIndices)[state + 1]; ++rowIndex) { + for (typename storm::storage::SparseMatrix::ConstIndexIterator succIt = this->getTransitionMatrix()->constColumnIteratorBegin(rowIndex), succIte = this->getTransitionMatrix()->constColumnIteratorEnd(rowIndex); succIt != succIte; ++succIt) { + uint_fast64_t targetScc = stateToSccMap.find(*succIt)->second; + + // We only need to consider transitions that are actually leaving the SCC. + if (targetScc != currentSccIndex) { + allTargetSccs.insert(targetScc); + } + } + } + } + + // Now we can just enumerate all the target SCCs and insert the corresponding transitions. + for (auto targetScc : allTargetSccs) { + sccDependencyGraph.insertNextValue(currentSccIndex, targetScc, true); + } + } + + // Finalize the matrix. + sccDependencyGraph.finalize(true); + + return sccDependencyGraph; + } + /*! * Retrieves the size of the internal representation of the model in memory. * @return the size of the internal representation of the model in memory diff --git a/src/models/GraphTransitions.h b/src/models/GraphTransitions.h index feed1b952..de435a00b 100644 --- a/src/models/GraphTransitions.h +++ b/src/models/GraphTransitions.h @@ -119,38 +119,6 @@ public: } private: - void initializeFromSccDecomposition(GraphTransitions const& transitions, std::vector> const& stronglyConnectedComponents, std::map const& stateToSccMap) { - for (uint_fast64_t currentSccIndex = 0; currentSccIndex < stronglyConnectedComponents.size(); ++currentSccIndex) { - // Mark beginning of current SCC. - stateIndications[currentSccIndex] = successorList.size(); - - // Get the actual SCC. - std::vector const& scc = stronglyConnectedComponents[currentSccIndex]; - - // Now, we determine the SCCs which are reachable (in one step) from the current SCC. - std::set allTargetSccs; - for (auto state : scc) { - for (stateSuccessorIterator succIt = transitions.beginStateSuccessorsIterator(state), succIte = transitions.endStateSuccessorsIterator(state); succIt != succIte; ++succIt) { - uint_fast64_t targetScc = stateToSccMap.find(*succIt)->second; - - // We only need to consider transitions that are actually leaving the SCC. - if (targetScc != currentSccIndex) { - allTargetSccs.insert(targetScc); - } - } - } - - // Now we can just enumerate all the target SCCs and insert the corresponding transitions. - for (auto targetScc : allTargetSccs) { - successorList.push_back(targetScc); - } - } - - // Put the sentinel element at the end and initialize the number of transitions. - stateIndications[numberOfStates] = successorList.size(); - numberOfTransitions = successorList.size(); - } - /*! * Initializes this graph transitions object using the forward transition * relation given by means of a sparse matrix. diff --git a/src/storage/SparseMatrix.h b/src/storage/SparseMatrix.h index 812545623..b0d2a1cc2 100644 --- a/src/storage/SparseMatrix.h +++ b/src/storage/SparseMatrix.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "boost/integer/integer_mask.hpp" #include "src/exceptions/InvalidStateException.h" @@ -55,8 +56,8 @@ public: * If we only want to iterate over the columns or values of the non-zero entries of * a row, we can simply iterate over the array (part) itself. */ - typedef const uint_fast64_t* const ConstIndexIterator; - typedef const T* const ConstValueIterator; + typedef uint_fast64_t const* ConstIndexIterator; + typedef T const* ConstValueIterator; /*! * Iterator class that is able to iterate over the non-zero elements of a matrix and return the position @@ -232,7 +233,7 @@ public: * * @param nonZeroEntries The number of non-zero entries this matrix is going to hold. */ - void initialize(uint_fast64_t nonZeroEntries) { + void initialize(uint_fast64_t nonZeroEntries = 0) { // Check whether initializing the matrix is safe. if (internalStatus != MatrixStatus::UnInitialized) { triggerErrorState(); @@ -260,11 +261,15 @@ public: } } } - + /*! - * Sets the matrix element at the given row and column to the given value. + * Sets the matrix element at the given row and column to the given value. After all elements have been added, + * a call to finalize() is mandatory. * NOTE: This is a linear setter. It must be called consecutively for each element, * row by row *and* column by column. + * NOTE: This method is different from insertNextValue(...) in that the number of nonzero elements must be known + * in advance (and passed to initialize()), because adding elements will not automatically increase the size of the + * underlying storage. * * @param row The row in which the matrix element is to be set. * @param col The column in which the matrix element is to be set. @@ -276,7 +281,7 @@ public: if ((row > rowCount) || (col > colCount)) { triggerErrorState(); LOG4CPLUS_ERROR(logger, "Trying to add a value at illegal position (" << row << ", " << col << ") in matrix of size (" << rowCount << ", " << colCount << ")."); - throw storm::exceptions::OutOfRangeException("Trying to add a value at illegal position."); + throw storm::exceptions::OutOfRangeException() << "Trying to add a value at illegal position (" << row << ", " << col << ") in matrix of size (" << rowCount << ", " << colCount << ")."; } // If we switched to another row, we have to adjust the missing @@ -294,14 +299,53 @@ public: ++currentSize; } + + /*! + * Inserts a value at the given row and column with the given value. After all elements have been added, + * a call to finalize() is mandatory. + * NOTE: This is a linear inserter. It must be called consecutively for each element, row by row *and* column by + * column. + * NOTE: This method is different from addNextValue(...) in that the number of nonzero elements need not be known + * in advance, because inserting elements will automatically increase the size of the underlying storage. + * + * @param row The row in which the matrix element is to be set. + * @param col The column in which the matrix element is to be set. + * @param value The value that is to be set. + */ + void insertNextValue(const uint_fast64_t row, const uint_fast64_t col, T const& value) { + // Check whether the given row and column positions are valid and throw + // error otherwise. + if ((row > rowCount) || (col > colCount)) { + triggerErrorState(); + LOG4CPLUS_ERROR(logger, "Trying to insert a value at illegal position (" << row << ", " << col << ") in matrix of size (" << rowCount << ", " << colCount << ")."); + throw storm::exceptions::OutOfRangeException() << "Trying to insert a value at illegal position (" << row << ", " << col << ") in matrix of size (" << rowCount << ", " << colCount << ")."; + } + + // If we switched to another row, we have to adjust the missing entries in the rowIndications array. + if (row != lastRow) { + for (uint_fast64_t i = lastRow + 1; i <= row; ++i) { + rowIndications[i] = currentSize; + } + lastRow = row; + } + + // Finally, set the element and increase the current size. + valueStorage.push_back(value); + columnIndications.push_back(col); + ++nonZeroEntryCount; + ++currentSize; + } + /* - * Finalizes the sparse matrix to indicate that initialization has been - * completed and the matrix may now be used. + * Finalizes the sparse matrix to indicate that initialization has been completed and the matrix may now be used. + * + * @param pushSentinelElement A boolean flag that indicates whether the sentinel element is to be pushed or inserted + * at a fixed location. If the elements have been added to the matrix via insertNextElement, this needs to be true + * and false otherwise. */ - void finalize() { - // Check whether it's safe to finalize the matrix and throw error - // otherwise. + void finalize(bool pushSentinelElement = false) { + // Check whether it's safe to finalize the matrix and throw error otherwise. if (!isInitialized()) { triggerErrorState(); LOG4CPLUS_ERROR(logger, "Trying to finalize an uninitialized matrix."); @@ -319,11 +363,14 @@ public: } } - // Set a sentinel element at the last position of the row_indications - // array. This eases iteration work, as now the indices of row i - // are always between row_indications[i] and row_indications[i + 1], - // also for the first and last row. - rowIndications[rowCount] = nonZeroEntryCount; + // Set a sentinel element at the last position of the row_indications array. This eases iteration work, as + // now the indices of row i are always between rowIndications[i] and rowIndications[i + 1], also for the + // first and last row. + if (pushSentinelElement) { + rowIndications.push_back(nonZeroEntryCount); + } else { + rowIndications[rowCount] = nonZeroEntryCount; + } setState(MatrixStatus::ReadReady); } diff --git a/src/utility/GraphAnalyzer.h b/src/utility/GraphAnalyzer.h index 2b61b877d..c8530e7ef 100644 --- a/src/utility/GraphAnalyzer.h +++ b/src/utility/GraphAnalyzer.h @@ -421,7 +421,7 @@ public: } /*! - * Performs a decomposition of the given nondetermistic model into its SCCs. + * Performs a decomposition of the given nondeterministic model into its SCCs. * * @param model The nondeterminstic model to decompose. * @return A pair whose first component represents the SCCs and whose second component represents the dependency @@ -430,51 +430,75 @@ public: template static std::pair>, storm::models::GraphTransitions> performSccDecomposition(storm::models::AbstractNondeterministicModel const& model) { LOG4CPLUS_INFO(logger, "Computing SCC decomposition."); + + std::pair>, storm::models::GraphTransitions> sccDecomposition; + uint_fast64_t numberOfStates = model.getNumberOfStates(); + + // Set up the environment of Tarjan's algorithm. + std::vector tarjanStack; + tarjanStack.reserve(numberOfStates); + storm::storage::BitVector tarjanStackStates(numberOfStates); + std::vector stateIndices(numberOfStates); + std::vector lowlinks(numberOfStates); + storm::storage::BitVector visitedStates(numberOfStates); + std::map stateToSccMap; + + // Start the search for SCCs from every vertex in the graph structure, because there is. + uint_fast64_t currentIndex = 0; + for (uint_fast64_t state = 0; state < numberOfStates; ++state) { + if (!visitedStates.get(state)) { + performSccDecompositionHelper(state, currentIndex, stateIndices, lowlinks, tarjanStack, tarjanStackStates, visitedStates, model.getTransitionMatrix(), sccDecomposition.first, stateToSccMap); + } + } + + // Finally, determine the dependency graph over the SCCs and return result. + sccDecomposition.second = model.extractSccDependencyGraph(sccDecomposition.first, stateToSccMap); - // Get the forward transition relation from the model to ease the search. - std::vector const& nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); - storm::models::GraphTransitions forwardTransitions(model.getTransitionMatrix(), nondeterministicChoiceIndices, true); - - // Perform the actual SCC decomposition based on the graph-transitions of the system. - std::pair>, storm::models::GraphTransitions> result = performSccDecomposition(nondeterministicChoiceIndices.size() - 1, forwardTransitions); LOG4CPLUS_INFO(logger, "Done computing SCC decomposition."); - - return result; + return sccDecomposition; } /*! * Performs a topological sort of the states of the system according to the given transitions. * - * @param transitions The transitions of the graph structure. + * @param matrix A square matrix representing the transition relation of the system. * @return A vector of indices that is a topological sort of the states. */ template - static std::vector getTopologicalSort(storm::models::GraphTransitions const& transitions) { + static std::vector getTopologicalSort(storm::storage::SparseMatrix const& matrix) { + if (matrix.getRowCount() != matrix.getColumnCount()) { + LOG4CPLUS_ERROR(logger, "Provided matrix is required to be square."); + throw storm::exceptions::InvalidArgumentException() << "Provided matrix is required to be square."; + } + + uint_fast64_t numberOfStates = matrix.getRowCount(); + + // Prepare the result. This relies on the matrix being square. std::vector topologicalSort; - topologicalSort.reserve(transitions.getNumberOfStates()); + topologicalSort.reserve(numberOfStates); // Prepare the stacks needed for recursion. std::vector recursionStack; - recursionStack.reserve(transitions.getNumberOfStates()); - std::vector::stateSuccessorIterator> iteratorRecursionStack; - iteratorRecursionStack.reserve(transitions.getNumberOfStates()); + recursionStack.reserve(matrix.getRowCount()); + std::vector::ConstIndexIterator> iteratorRecursionStack; + iteratorRecursionStack.reserve(numberOfStates); // Perform a depth-first search over the given transitions and record states in the reverse order they were visited. - storm::storage::BitVector visitedStates(transitions.getNumberOfStates()); - for (uint_fast64_t state = 0; state < transitions.getNumberOfStates(); ++state) { + storm::storage::BitVector visitedStates(numberOfStates); + for (uint_fast64_t state = 0; state < numberOfStates; ++state) { if (!visitedStates.get(state)) { recursionStack.push_back(state); - iteratorRecursionStack.push_back(transitions.beginStateSuccessorsIterator(state)); + iteratorRecursionStack.push_back(matrix.constColumnIteratorBegin(state)); recursionStepForward: while (!recursionStack.empty()) { uint_fast64_t currentState = recursionStack.back(); - typename storm::models::GraphTransitions::stateSuccessorIterator currentIt = iteratorRecursionStack.back(); + typename storm::storage::SparseMatrix::ConstIndexIterator currentIt = iteratorRecursionStack.back(); visitedStates.set(currentState, true); recursionStepBackward: - for (; currentIt != transitions.endStateSuccessorsIterator(currentState); ++currentIt) { + for (; currentIt != matrix.constColumnIteratorEnd(currentState); ++currentIt) { if (!visitedStates.get(*currentIt)) { // Put unvisited successor on top of our recursion stack and remember that. recursionStack.push_back(*currentIt); @@ -484,7 +508,7 @@ public: iteratorRecursionStack.push_back(currentIt + 1); // Also, put initial value for iterator on corresponding recursion stack. - iteratorRecursionStack.push_back(transitions.beginStateSuccessorsIterator(*currentIt)); + iteratorRecursionStack.push_back(matrix.constColumnIteratorBegin(*currentIt)); goto recursionStepForward; } @@ -514,40 +538,6 @@ public: } private: - /*! - * Performs an SCC decomposition of the system given by its forward transitions. - * - * @param forwardTransitions The (forward) transition relation of the model to decompose. - * @return A pair whose first component represents the SCCs and whose second component represents the dependency - * graph of the SCCs. - */ - template - static std::pair>, storm::models::GraphTransitions> performSccDecomposition(storm::models::GraphTransitions const& forwardTransitions) { - std::pair>, storm::models::GraphTransitions> sccDecomposition; - uint_fast64_t numberOfStates = forwardTransitions.getNumberOfStates(); - - // Set up the environment of Tarjan's algorithm. - std::vector tarjanStack; - tarjanStack.reserve(numberOfStates); - storm::storage::BitVector tarjanStackStates(numberOfStates); - std::vector stateIndices(numberOfStates); - std::vector lowlinks(numberOfStates); - storm::storage::BitVector visitedStates(numberOfStates); - std::map stateToSccMap; - - // Start the search for SCCs from every vertex in the graph structure, because there is. - uint_fast64_t currentIndex = 0; - for (uint_fast64_t state = 0; state < numberOfStates; ++state) { - if (!visitedStates.get(state)) { - performSccDecompositionHelper(state, currentIndex, stateIndices, lowlinks, tarjanStack, tarjanStackStates, visitedStates, forwardTransitions, sccDecomposition.first, stateToSccMap); - } - } - - // Finally, determine the dependency graph over the SCCs and return result. - sccDecomposition.second = storm::models::GraphTransitions(forwardTransitions, sccDecomposition.first, stateToSccMap); - return sccDecomposition; - } - /*! * Performs an SCC decomposition using Tarjan's algorithm. * @@ -559,30 +549,30 @@ private: * @param tarjanStack A stack used for Tarjan's algorithm. * @param tarjanStackStates A bit vector that represents all states that are currently contained in tarjanStack. * @param visitedStates A bit vector that stores all states that have already been visited. - * @param forwardTransitions The (forward) transition relation of the graph structure. + * @param matrix The transition matrix representing the graph structure. * @param stronglyConnectedComponents A vector of strongly connected components to which newly found SCCs are added. * @param stateToSccMap A mapping from state indices to SCC indices that maps each state to its SCC. */ template - static void performSccDecompositionHelper(uint_fast64_t startState, uint_fast64_t& currentIndex, std::vector& stateIndices, std::vector& lowlinks, std::vector& tarjanStack, storm::storage::BitVector& tarjanStackStates, storm::storage::BitVector& visitedStates, storm::models::GraphTransitions const& forwardTransitions, std::vector>& stronglyConnectedComponents, std::map& stateToSccMap) { + static void performSccDecompositionHelper(uint_fast64_t startState, uint_fast64_t& currentIndex, std::vector& stateIndices, std::vector& lowlinks, std::vector& tarjanStack, storm::storage::BitVector& tarjanStackStates, storm::storage::BitVector& visitedStates, storm::storage::SparseMatrix const& matrix, std::vector>& stronglyConnectedComponents, std::map& stateToSccMap) { // Create the stacks needed for turning the recursive formulation of Tarjan's algorithm // into an iterative version. In particular, we keep one stack for states and one stack // for the iterators. The last one is not strictly needed, but reduces iteration work when // all successors of a particular state are considered. std::vector recursionStateStack; recursionStateStack.reserve(lowlinks.size()); - std::vector::stateSuccessorIterator> recursionIteratorStack; + std::vector::ConstIndexIterator> recursionIteratorStack; recursionIteratorStack.reserve(lowlinks.size()); std::vector statesInStack(lowlinks.size()); // Initialize the recursion stacks with the given initial state (and its successor iterator). recursionStateStack.push_back(startState); - recursionIteratorStack.push_back(forwardTransitions.beginStateSuccessorsIterator(startState)); + recursionIteratorStack.push_back(matrix.constColumnIteratorBegin(startState)); recursionStepForward: while (!recursionStateStack.empty()) { uint_fast64_t currentState = recursionStateStack.back(); - typename storm::models::GraphTransitions::stateSuccessorIterator currentIt = recursionIteratorStack.back(); + typename storm::storage::SparseMatrix::ConstIndexIterator currentIt = recursionIteratorStack.back(); // Perform the treatment of newly discovered state as defined by Tarjan's algorithm visitedStates.set(currentState, true); @@ -593,7 +583,7 @@ private: tarjanStackStates.set(currentState, true); // Now, traverse all successors of the current state. - for(; currentIt != forwardTransitions.endStateSuccessorsIterator(currentState); ++currentIt) { + for(; currentIt != matrix.constColumnIteratorEnd(currentState); ++currentIt) { // If we have not visited the successor already, we need to perform the procedure // recursively on the newly found state. if (!visitedStates.get(*currentIt)) { @@ -606,7 +596,7 @@ private: statesInStack[*currentIt] = true; // Also, put initial value for iterator on corresponding recursion stack. - recursionIteratorStack.push_back(forwardTransitions.beginStateSuccessorsIterator(*currentIt)); + recursionIteratorStack.push_back(matrix.constColumnIteratorBegin(*currentIt)); // Perform the actual recursion step in an iterative way. goto recursionStepForward; From 6aea8de7bada7732bed1e1f71e853470993c6311 Mon Sep 17 00:00:00 2001 From: Harold Bruintjes Date: Mon, 13 May 2013 10:28:03 +0200 Subject: [PATCH 118/152] Readded cudd 2.5.0 from prismparser --- resources/3rdparty/cudd-2.5.0/LICENSE | 31 + resources/3rdparty/cudd-2.5.0/Makefile | 323 + resources/3rdparty/cudd-2.5.0/README | 177 + resources/3rdparty/cudd-2.5.0/RELEASE.NOTES | 131 + resources/3rdparty/cudd-2.5.0/cudd/Makefile | 124 + resources/3rdparty/cudd-2.5.0/cudd/cudd.h | 1082 ++ resources/3rdparty/cudd-2.5.0/cudd/cuddAPI.c | 4893 +++++ .../3rdparty/cudd-2.5.0/cudd/cuddAddAbs.c | 579 + .../3rdparty/cudd-2.5.0/cudd/cuddAddApply.c | 1121 ++ .../3rdparty/cudd-2.5.0/cudd/cuddAddFind.c | 316 + .../3rdparty/cudd-2.5.0/cudd/cuddAddInv.c | 201 + .../3rdparty/cudd-2.5.0/cudd/cuddAddIte.c | 639 + .../3rdparty/cudd-2.5.0/cudd/cuddAddNeg.c | 290 + .../3rdparty/cudd-2.5.0/cudd/cuddAddWalsh.c | 391 + .../3rdparty/cudd-2.5.0/cudd/cuddAndAbs.c | 373 + .../3rdparty/cudd-2.5.0/cudd/cuddAnneal.c | 814 + resources/3rdparty/cudd-2.5.0/cudd/cuddApa.c | 979 + .../3rdparty/cudd-2.5.0/cudd/cuddApprox.c | 2204 +++ .../3rdparty/cudd-2.5.0/cudd/cuddBddAbs.c | 760 + .../3rdparty/cudd-2.5.0/cudd/cuddBddCorr.c | 515 + .../3rdparty/cudd-2.5.0/cudd/cuddBddIte.c | 1430 ++ .../3rdparty/cudd-2.5.0/cudd/cuddBridge.c | 1016 + .../3rdparty/cudd-2.5.0/cudd/cuddCache.c | 1053 ++ .../3rdparty/cudd-2.5.0/cudd/cuddCheck.c | 885 + resources/3rdparty/cudd-2.5.0/cudd/cuddClip.c | 558 + resources/3rdparty/cudd-2.5.0/cudd/cuddCof.c | 327 + .../3rdparty/cudd-2.5.0/cudd/cuddCompose.c | 1749 ++ .../3rdparty/cudd-2.5.0/cudd/cuddDecomp.c | 2177 +++ .../3rdparty/cudd-2.5.0/cudd/cuddEssent.c | 1467 ++ .../3rdparty/cudd-2.5.0/cudd/cuddExact.c | 1020 + .../3rdparty/cudd-2.5.0/cudd/cuddExport.c | 1389 ++ .../3rdparty/cudd-2.5.0/cudd/cuddGenCof.c | 2178 +++ .../3rdparty/cudd-2.5.0/cudd/cuddGenetic.c | 960 + .../3rdparty/cudd-2.5.0/cudd/cuddGroup.c | 2188 +++ .../3rdparty/cudd-2.5.0/cudd/cuddHarwell.c | 568 + resources/3rdparty/cudd-2.5.0/cudd/cuddInit.c | 308 + resources/3rdparty/cudd-2.5.0/cudd/cuddInt.h | 1188 ++ .../3rdparty/cudd-2.5.0/cudd/cuddInteract.c | 432 + .../3rdparty/cudd-2.5.0/cudd/cuddLCache.c | 1557 ++ .../3rdparty/cudd-2.5.0/cudd/cuddLevelQ.c | 583 + .../3rdparty/cudd-2.5.0/cudd/cuddLinear.c | 1365 ++ .../3rdparty/cudd-2.5.0/cudd/cuddLiteral.c | 264 + .../3rdparty/cudd-2.5.0/cudd/cuddMatMult.c | 707 + .../3rdparty/cudd-2.5.0/cudd/cuddPriority.c | 2027 ++ resources/3rdparty/cudd-2.5.0/cudd/cuddRead.c | 517 + resources/3rdparty/cudd-2.5.0/cudd/cuddRef.c | 808 + .../3rdparty/cudd-2.5.0/cudd/cuddReorder.c | 2137 +++ resources/3rdparty/cudd-2.5.0/cudd/cuddSat.c | 1774 ++ resources/3rdparty/cudd-2.5.0/cudd/cuddSign.c | 318 + .../3rdparty/cudd-2.5.0/cudd/cuddSolve.c | 366 + .../3rdparty/cudd-2.5.0/cudd/cuddSplit.c | 686 + .../3rdparty/cudd-2.5.0/cudd/cuddSubsetHB.c | 1331 ++ .../3rdparty/cudd-2.5.0/cudd/cuddSubsetSP.c | 1660 ++ .../3rdparty/cudd-2.5.0/cudd/cuddSymmetry.c | 1707 ++ .../3rdparty/cudd-2.5.0/cudd/cuddTable.c | 3213 ++++ resources/3rdparty/cudd-2.5.0/cudd/cuddUtil.c | 4032 ++++ .../3rdparty/cudd-2.5.0/cudd/cuddWindow.c | 1023 + .../3rdparty/cudd-2.5.0/cudd/cuddZddCount.c | 357 + .../3rdparty/cudd-2.5.0/cudd/cuddZddFuncs.c | 1630 ++ .../3rdparty/cudd-2.5.0/cudd/cuddZddGroup.c | 1340 ++ .../3rdparty/cudd-2.5.0/cudd/cuddZddIsop.c | 912 + .../3rdparty/cudd-2.5.0/cudd/cuddZddLin.c | 971 + .../3rdparty/cudd-2.5.0/cudd/cuddZddMisc.c | 278 + .../3rdparty/cudd-2.5.0/cudd/cuddZddPort.c | 381 + .../3rdparty/cudd-2.5.0/cudd/cuddZddReord.c | 1664 ++ .../3rdparty/cudd-2.5.0/cudd/cuddZddSetop.c | 1166 ++ .../3rdparty/cudd-2.5.0/cudd/cuddZddSymm.c | 1711 ++ .../3rdparty/cudd-2.5.0/cudd/cuddZddUtil.c | 1205 ++ .../3rdparty/cudd-2.5.0/cudd/doc/cudd.doc | 6776 +++++++ .../3rdparty/cudd-2.5.0/cudd/doc/cudd.ps | 5036 +++++ .../cudd-2.5.0/cudd/doc/cuddAllAbs.html | 3114 +++ .../cudd-2.5.0/cudd/doc/cuddAllByFile.html | 13 + .../cudd-2.5.0/cudd/doc/cuddAllByFunc.html | 13 + .../cudd-2.5.0/cudd/doc/cuddAllDet.html | 15754 ++++++++++++++++ .../cudd-2.5.0/cudd/doc/cuddAllFile.html | 4876 +++++ .../cudd-2.5.0/cudd/doc/cuddDesc.html | 33 + .../3rdparty/cudd-2.5.0/cudd/doc/cuddExt.html | 14 + .../cudd-2.5.0/cudd/doc/cuddExtAbs.html | 1415 ++ .../cudd-2.5.0/cudd/doc/cuddExtDet.html | 4450 +++++ .../cudd-2.5.0/cudd/doc/cuddIntro.css | 30 + .../cudd-2.5.0/cudd/doc/cuddIntro.html | 219 + .../cudd-2.5.0/cudd/doc/cuddTitle.html | 18 + .../cudd-2.5.0/cudd/doc/footnode.html | 109 + .../cudd-2.5.0/cudd/doc/icons/blueball.png | Bin 0 -> 333 bytes .../cudd-2.5.0/cudd/doc/icons/ch_beg_r.png | Bin 0 -> 165 bytes .../cudd-2.5.0/cudd/doc/icons/ch_begin.png | Bin 0 -> 174 bytes .../cudd-2.5.0/cudd/doc/icons/ch_del_r.png | Bin 0 -> 288 bytes .../cudd-2.5.0/cudd/doc/icons/ch_delet.png | Bin 0 -> 288 bytes .../cudd-2.5.0/cudd/doc/icons/ch_end.png | Bin 0 -> 171 bytes .../cudd-2.5.0/cudd/doc/icons/ch_end_r.png | Bin 0 -> 155 bytes .../cudd-2.5.0/cudd/doc/icons/contents.png | Bin 0 -> 278 bytes .../cudd-2.5.0/cudd/doc/icons/crossref.png | Bin 0 -> 147 bytes .../cudd-2.5.0/cudd/doc/icons/footnote.png | Bin 0 -> 190 bytes .../cudd-2.5.0/cudd/doc/icons/greenball.png | Bin 0 -> 333 bytes .../cudd-2.5.0/cudd/doc/icons/image.png | Bin 0 -> 244 bytes .../cudd-2.5.0/cudd/doc/icons/index.png | Bin 0 -> 246 bytes .../cudd-2.5.0/cudd/doc/icons/next.png | Bin 0 -> 245 bytes .../cudd-2.5.0/cudd/doc/icons/next_g.png | Bin 0 -> 272 bytes .../cudd-2.5.0/cudd/doc/icons/nx_grp.png | Bin 0 -> 314 bytes .../cudd-2.5.0/cudd/doc/icons/nx_grp_g.png | Bin 0 -> 386 bytes .../cudd-2.5.0/cudd/doc/icons/orangeball.png | Bin 0 -> 333 bytes .../cudd-2.5.0/cudd/doc/icons/pinkball.png | Bin 0 -> 332 bytes .../cudd-2.5.0/cudd/doc/icons/prev.png | Bin 0 -> 279 bytes .../cudd-2.5.0/cudd/doc/icons/prev_g.png | Bin 0 -> 327 bytes .../cudd-2.5.0/cudd/doc/icons/purpleball.png | Bin 0 -> 332 bytes .../cudd-2.5.0/cudd/doc/icons/pv_grp.png | Bin 0 -> 352 bytes .../cudd-2.5.0/cudd/doc/icons/pv_grp_g.png | Bin 0 -> 430 bytes .../cudd-2.5.0/cudd/doc/icons/redball.png | Bin 0 -> 332 bytes .../3rdparty/cudd-2.5.0/cudd/doc/icons/up.png | Bin 0 -> 211 bytes .../cudd-2.5.0/cudd/doc/icons/up_g.png | Bin 0 -> 231 bytes .../cudd-2.5.0/cudd/doc/icons/whiteball.png | Bin 0 -> 229 bytes .../cudd-2.5.0/cudd/doc/icons/yellowball.png | Bin 0 -> 333 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img1.png | Bin 0 -> 201 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img10.png | Bin 0 -> 211 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img11.png | Bin 0 -> 476 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img12.png | Bin 0 -> 555 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img13.png | Bin 0 -> 560 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img14.png | Bin 0 -> 675 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img15.png | Bin 0 -> 200 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img16.png | Bin 0 -> 223 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img17.png | Bin 0 -> 246 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img18.png | Bin 0 -> 298 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img19.png | Bin 0 -> 409 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img2.png | Bin 0 -> 197 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img20.png | Bin 0 -> 238 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img21.png | Bin 0 -> 614 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img22.png | Bin 0 -> 12605 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img3.png | Bin 0 -> 401 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img4.png | Bin 0 -> 204 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img5.png | Bin 0 -> 315 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img6.png | Bin 0 -> 185 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img7.png | Bin 0 -> 262 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img8.png | Bin 0 -> 220 bytes .../3rdparty/cudd-2.5.0/cudd/doc/img9.png | Bin 0 -> 215 bytes .../3rdparty/cudd-2.5.0/cudd/doc/index.html | 219 + .../3rdparty/cudd-2.5.0/cudd/doc/node1.html | 174 + .../3rdparty/cudd-2.5.0/cudd/doc/node2.html | 175 + .../3rdparty/cudd-2.5.0/cudd/doc/node3.html | 1637 ++ .../3rdparty/cudd-2.5.0/cudd/doc/node4.html | 1165 ++ .../3rdparty/cudd-2.5.0/cudd/doc/node5.html | 130 + .../3rdparty/cudd-2.5.0/cudd/doc/node6.html | 132 + .../3rdparty/cudd-2.5.0/cudd/doc/node7.html | 195 + .../3rdparty/cudd-2.5.0/cudd/doc/node8.html | 848 + resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.mat | 53 + resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.out | 396 + resources/3rdparty/cudd-2.5.0/cudd/testcudd.c | 1178 ++ resources/3rdparty/cudd-2.5.0/dddmp/Makefile | 243 + .../3rdparty/cudd-2.5.0/dddmp/README.dddmp | 64 + .../cudd-2.5.0/dddmp/README.testdddmp | 79 + .../3rdparty/cudd-2.5.0/dddmp/RELEASE_NOTES | 60 + resources/3rdparty/cudd-2.5.0/dddmp/dddmp.h | 330 + .../3rdparty/cudd-2.5.0/dddmp/dddmpBinary.c | 343 + .../3rdparty/cudd-2.5.0/dddmp/dddmpConvert.c | 180 + .../3rdparty/cudd-2.5.0/dddmp/dddmpDbg.c | 166 + .../cudd-2.5.0/dddmp/dddmpDdNodeBdd.c | 455 + .../cudd-2.5.0/dddmp/dddmpDdNodeCnf.c | 944 + .../3rdparty/cudd-2.5.0/dddmp/dddmpInt.h | 216 + .../3rdparty/cudd-2.5.0/dddmp/dddmpLoad.c | 1486 ++ .../3rdparty/cudd-2.5.0/dddmp/dddmpLoadCnf.c | 1072 ++ .../3rdparty/cudd-2.5.0/dddmp/dddmpNodeAdd.c | 451 + .../3rdparty/cudd-2.5.0/dddmp/dddmpNodeBdd.c | 452 + .../3rdparty/cudd-2.5.0/dddmp/dddmpNodeCnf.c | 932 + .../3rdparty/cudd-2.5.0/dddmp/dddmpStoreAdd.c | 957 + .../3rdparty/cudd-2.5.0/dddmp/dddmpStoreBdd.c | 1114 ++ .../3rdparty/cudd-2.5.0/dddmp/dddmpStoreCnf.c | 1583 ++ .../cudd-2.5.0/dddmp/dddmpStoreMisc.c | 1641 ++ .../3rdparty/cudd-2.5.0/dddmp/dddmpUtil.c | 436 + .../cudd-2.5.0/dddmp/doc/cmdIndex.html | 9 + .../cudd-2.5.0/dddmp/doc/commands.html | 12 + .../3rdparty/cudd-2.5.0/dddmp/doc/credit.html | 15 + .../cudd-2.5.0/dddmp/doc/dddmp-2.0-A4.ps | 1261 ++ .../cudd-2.5.0/dddmp/doc/dddmp-2.0-Letter.ps | 1260 ++ .../cudd-2.5.0/dddmp/doc/dddmpAllAbs.html | 483 + .../cudd-2.5.0/dddmp/doc/dddmpAllByFile.html | 13 + .../cudd-2.5.0/dddmp/doc/dddmpAllByFunc.html | 13 + .../cudd-2.5.0/dddmp/doc/dddmpAllDet.html | 3704 ++++ .../cudd-2.5.0/dddmp/doc/dddmpAllFile.html | 679 + .../cudd-2.5.0/dddmp/doc/dddmpDesc.html | 28 + .../cudd-2.5.0/dddmp/doc/dddmpDoc.txt | Bin 0 -> 32768 bytes .../cudd-2.5.0/dddmp/doc/dddmpExt.html | 13 + .../cudd-2.5.0/dddmp/doc/dddmpExtAbs.html | 91 + .../cudd-2.5.0/dddmp/doc/dddmpExtDet.html | 693 + .../cudd-2.5.0/dddmp/doc/dddmpTitle.html | 17 + .../cudd-2.5.0/dddmp/doc/packages.html | 12 + .../cudd-2.5.0/dddmp/doc/pkgIndex.html | 13 + resources/3rdparty/cudd-2.5.0/dddmp/exp/0.add | 21 + resources/3rdparty/cudd-2.5.0/dddmp/exp/0.bdd | 19 + .../3rdparty/cudd-2.5.0/dddmp/exp/0or1.bdd | 119 + resources/3rdparty/cudd-2.5.0/dddmp/exp/1.add | 28 + resources/3rdparty/cudd-2.5.0/dddmp/exp/1.bdd | 110 + resources/3rdparty/cudd-2.5.0/dddmp/exp/2.bdd | 118 + .../3rdparty/cudd-2.5.0/dddmp/exp/2and3.bdd | 76 + resources/3rdparty/cudd-2.5.0/dddmp/exp/3.bdd | 304 + resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd | 50 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis1 | 50 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis2 | 50 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis3 | 50 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis4 | 50 + resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf | 130 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.cnf.bis | 130 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.max1 | 125 + .../3rdparty/cudd-2.5.0/dddmp/exp/4.max2 | 125 + .../3rdparty/cudd-2.5.0/dddmp/exp/4bis.bdd | 47 + .../3rdparty/cudd-2.5.0/dddmp/exp/4xor5.bdd | 120 + resources/3rdparty/cudd-2.5.0/dddmp/exp/5.bdd | 31 + .../cudd-2.5.0/dddmp/exp/composeids.txt | 20 + .../3rdparty/cudd-2.5.0/dddmp/exp/one.bdd | 13 + .../cudd-2.5.0/dddmp/exp/runAllTest.out | 269 + .../cudd-2.5.0/dddmp/exp/runAllTest.script | 11 + .../3rdparty/cudd-2.5.0/dddmp/exp/s27RP1.bdd | 18 + .../cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd | 31 + .../dddmp/exp/s27deltaDddmp1.bdd.bis | 31 + .../cudd-2.5.0/dddmp/exp/s27deltaDddmp2.bdd | 32 + .../3rdparty/cudd-2.5.0/dddmp/exp/test1.out | 44 + .../cudd-2.5.0/dddmp/exp/test1.script | 26 + .../3rdparty/cudd-2.5.0/dddmp/exp/test2.out | 23 + .../cudd-2.5.0/dddmp/exp/test2.script | 30 + .../3rdparty/cudd-2.5.0/dddmp/exp/test3.out | 18 + .../cudd-2.5.0/dddmp/exp/test3.script | 69 + .../3rdparty/cudd-2.5.0/dddmp/exp/test4.out | 24 + .../cudd-2.5.0/dddmp/exp/test4.script | 56 + .../3rdparty/cudd-2.5.0/dddmp/exp/test5.out | 28 + .../cudd-2.5.0/dddmp/exp/test5.script | 42 + .../3rdparty/cudd-2.5.0/dddmp/exp/test6.out | 31 + .../cudd-2.5.0/dddmp/exp/test6.script | 50 + .../3rdparty/cudd-2.5.0/dddmp/exp/test7.out | 102 + .../cudd-2.5.0/dddmp/exp/test7.script | 150 + .../cudd-2.5.0/dddmp/exp/varauxids.ord | 50 + .../cudd-2.5.0/dddmp/exp/varnames.ord | 50 + .../3rdparty/cudd-2.5.0/dddmp/exp/zero.bdd | 13 + .../3rdparty/cudd-2.5.0/dddmp/testdddmp.c | 2279 +++ resources/3rdparty/cudd-2.5.0/epd/Makefile | 64 + resources/3rdparty/cudd-2.5.0/epd/epd.c | 1344 ++ resources/3rdparty/cudd-2.5.0/epd/epd.h | 200 + .../3rdparty/cudd-2.5.0/mnemosyne/Makefile | 53 + .../3rdparty/cudd-2.5.0/mnemosyne/README | 39 + .../3rdparty/cudd-2.5.0/mnemosyne/mnemalyse.c | 197 + .../3rdparty/cudd-2.5.0/mnemosyne/mnemconf.h | 89 + .../3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.c | 670 + .../3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.h | 73 + .../3rdparty/cudd-2.5.0/mnemosyne/mtest.c | 38 + resources/3rdparty/cudd-2.5.0/mtr/Makefile | 96 + .../3rdparty/cudd-2.5.0/mtr/Makefile.sis | 83 + resources/3rdparty/cudd-2.5.0/mtr/doc/mtr.doc | 252 + .../cudd-2.5.0/mtr/doc/mtrAllAbs.html | 72 + .../cudd-2.5.0/mtr/doc/mtrAllDet.html | 317 + .../cudd-2.5.0/mtr/doc/mtrExtAbs.html | 72 + .../cudd-2.5.0/mtr/doc/mtrExtDet.html | 324 + resources/3rdparty/cudd-2.5.0/mtr/mtr.h | 187 + resources/3rdparty/cudd-2.5.0/mtr/mtrBasic.c | 450 + resources/3rdparty/cudd-2.5.0/mtr/mtrGroup.c | 877 + resources/3rdparty/cudd-2.5.0/mtr/mtrInt.h | 92 + resources/3rdparty/cudd-2.5.0/mtr/test.groups | 5 + resources/3rdparty/cudd-2.5.0/mtr/testmtr.c | 270 + .../3rdparty/cudd-2.5.0/nanotrav/C17.blif | 16 + .../3rdparty/cudd-2.5.0/nanotrav/C17.out | 101 + .../3rdparty/cudd-2.5.0/nanotrav/C880.blif | 770 + .../3rdparty/cudd-2.5.0/nanotrav/C880.out | 101 + .../3rdparty/cudd-2.5.0/nanotrav/Makefile | 98 + resources/3rdparty/cudd-2.5.0/nanotrav/README | 47 + resources/3rdparty/cudd-2.5.0/nanotrav/bnet.c | 2252 +++ resources/3rdparty/cudd-2.5.0/nanotrav/bnet.h | 187 + .../3rdparty/cudd-2.5.0/nanotrav/chkMterm.c | 235 + .../cudd-2.5.0/nanotrav/doc/bnetAllAbs.html | 45 + .../cudd-2.5.0/nanotrav/doc/bnetAllDet.html | 173 + .../cudd-2.5.0/nanotrav/doc/bnetExtAbs.html | 45 + .../cudd-2.5.0/nanotrav/doc/bnetExtDet.html | 173 + .../cudd-2.5.0/nanotrav/doc/ntrAllAbs.html | 114 + .../cudd-2.5.0/nanotrav/doc/ntrAllDet.html | 513 + .../cudd-2.5.0/nanotrav/doc/ntrExtAbs.html | 111 + .../cudd-2.5.0/nanotrav/doc/ntrExtDet.html | 500 + resources/3rdparty/cudd-2.5.0/nanotrav/main.c | 1394 ++ .../3rdparty/cudd-2.5.0/nanotrav/mult32a.blif | 745 + .../3rdparty/cudd-2.5.0/nanotrav/mult32a.out | 258 + .../3rdparty/cudd-2.5.0/nanotrav/nanotrav.1 | 379 + resources/3rdparty/cudd-2.5.0/nanotrav/ntr.c | 2988 +++ resources/3rdparty/cudd-2.5.0/nanotrav/ntr.h | 283 + .../3rdparty/cudd-2.5.0/nanotrav/ntrBddTest.c | 2315 +++ .../3rdparty/cudd-2.5.0/nanotrav/ntrHeap.c | 390 + .../3rdparty/cudd-2.5.0/nanotrav/ntrMflow.c | 1581 ++ .../3rdparty/cudd-2.5.0/nanotrav/ntrShort.c | 578 + .../3rdparty/cudd-2.5.0/nanotrav/ntrZddTest.c | 468 + .../3rdparty/cudd-2.5.0/nanotrav/rcn25.blif | 335 + .../3rdparty/cudd-2.5.0/nanotrav/rcn25.out | 521 + .../3rdparty/cudd-2.5.0/nanotrav/s27.blif | 30 + .../3rdparty/cudd-2.5.0/nanotrav/s27.out | 95 + resources/3rdparty/cudd-2.5.0/nanotrav/tst.sh | 9 + .../3rdparty/cudd-2.5.0/nanotrav/ucbqsort.c | 228 + resources/3rdparty/cudd-2.5.0/obj/Makefile | 114 + resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc | 5759 ++++++ resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh | 768 + resources/3rdparty/cudd-2.5.0/obj/testobj.cc | 607 + resources/3rdparty/cudd-2.5.0/setup.sh | 18 + resources/3rdparty/cudd-2.5.0/shutdown.sh | 2 + .../3rdparty/cudd-2.5.0/sis/Makefile.sis | 97 + resources/3rdparty/cudd-2.5.0/sis/cuddBdd.h | 382 + .../3rdparty/cudd-2.5.0/sis/cuddBddPort.c | 1954 ++ resources/3rdparty/cudd-2.5.0/sis/cuddPwPt.c | 147 + resources/3rdparty/cudd-2.5.0/sis/st.c | 554 + resources/3rdparty/cudd-2.5.0/sis/st.h | 97 + resources/3rdparty/cudd-2.5.0/st/Makefile | 64 + .../3rdparty/cudd-2.5.0/st/doc/stAllAbs.html | 96 + .../3rdparty/cudd-2.5.0/st/doc/stAllDet.html | 462 + .../3rdparty/cudd-2.5.0/st/doc/stExtAbs.html | 96 + .../3rdparty/cudd-2.5.0/st/doc/stExtDet.html | 463 + resources/3rdparty/cudd-2.5.0/st/st.c | 1065 ++ resources/3rdparty/cudd-2.5.0/st/st.h | 232 + resources/3rdparty/cudd-2.5.0/util/Makefile | 64 + .../3rdparty/cudd-2.5.0/util/cpu_stats.c | 89 + resources/3rdparty/cudd-2.5.0/util/cpu_time.c | 76 + .../3rdparty/cudd-2.5.0/util/datalimit.c | 50 + .../3rdparty/cudd-2.5.0/util/pathsearch.c | 94 + resources/3rdparty/cudd-2.5.0/util/pipefork.c | 93 + resources/3rdparty/cudd-2.5.0/util/prtime.c | 21 + resources/3rdparty/cudd-2.5.0/util/ptime.c | 9 + resources/3rdparty/cudd-2.5.0/util/restart.c | 137 + resources/3rdparty/cudd-2.5.0/util/safe_mem.c | 97 + .../3rdparty/cudd-2.5.0/util/saveimage.c | 229 + resources/3rdparty/cudd-2.5.0/util/state.c | 82 + resources/3rdparty/cudd-2.5.0/util/strsav.c | 14 + resources/3rdparty/cudd-2.5.0/util/stub.c | 82 + resources/3rdparty/cudd-2.5.0/util/test-res.c | 57 + resources/3rdparty/cudd-2.5.0/util/test-sav.c | 39 + resources/3rdparty/cudd-2.5.0/util/texpand.c | 57 + resources/3rdparty/cudd-2.5.0/util/util.h | 204 + 325 files changed, 187894 insertions(+) create mode 100644 resources/3rdparty/cudd-2.5.0/LICENSE create mode 100644 resources/3rdparty/cudd-2.5.0/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/README create mode 100644 resources/3rdparty/cudd-2.5.0/RELEASE.NOTES create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cudd.h create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAPI.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddAbs.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddApply.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddFind.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddInv.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddIte.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddNeg.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAddWalsh.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAndAbs.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddAnneal.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddApa.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddApprox.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddBddAbs.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddBddCorr.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddBddIte.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddBridge.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddCache.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddCheck.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddClip.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddCof.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddCompose.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddDecomp.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddEssent.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddExact.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddExport.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddGenCof.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddGenetic.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddGroup.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddHarwell.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddInit.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddInt.h create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddInteract.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddLCache.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddLevelQ.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddLinear.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddLiteral.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddMatMult.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddPriority.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddRead.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddRef.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddReorder.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSat.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSign.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSolve.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSplit.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetHB.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetSP.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddSymmetry.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddTable.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddUtil.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddWindow.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddCount.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddFuncs.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddGroup.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddIsop.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddLin.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddMisc.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddPort.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddReord.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddSetop.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddSymm.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/cuddZddUtil.c create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.doc create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.ps create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFile.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFunc.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllFile.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddDesc.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExt.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.css create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/cuddTitle.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/footnode.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/blueball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_beg_r.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_begin.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_del_r.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_delet.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_end.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_end_r.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/contents.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/crossref.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/footnote.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/greenball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/image.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/index.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/next.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/next_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/nx_grp.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/nx_grp_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/orangeball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/pinkball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/prev.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/prev_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/purpleball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/pv_grp.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/pv_grp_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/redball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/up.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/up_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/whiteball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/icons/yellowball.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img1.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img10.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img11.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img12.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img13.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img14.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img15.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img16.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img17.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img18.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img19.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img2.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img20.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img21.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img22.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img3.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img4.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img5.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img6.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img7.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img8.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/img9.png create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/index.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node1.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node2.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node3.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node4.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node5.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node6.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node7.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/doc/node8.html create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.mat create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.out create mode 100644 resources/3rdparty/cudd-2.5.0/cudd/testcudd.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/README.dddmp create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/README.testdddmp create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/RELEASE_NOTES create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmp.h create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpBinary.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpConvert.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpDbg.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeBdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeCnf.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpInt.h create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoad.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoadCnf.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeAdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeBdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeCnf.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreAdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreBdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreCnf.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreMisc.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/dddmpUtil.c create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/cmdIndex.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/commands.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/credit.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-A4.ps create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-Letter.ps create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFile.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFunc.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllFile.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDesc.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDoc.txt create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExt.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpTitle.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/packages.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/doc/pkgIndex.html create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/0.add create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/0.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/0or1.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/1.add create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/1.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/2.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/2and3.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/3.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis1 create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis2 create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis3 create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis4 create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf.bis create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max1 create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max2 create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4bis.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/4xor5.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/5.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/composeids.txt create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/one.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/s27RP1.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd.bis create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp2.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.out create mode 100755 resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.script create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/varauxids.ord create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/varnames.ord create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/exp/zero.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/dddmp/testdddmp.c create mode 100644 resources/3rdparty/cudd-2.5.0/epd/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/epd/epd.c create mode 100644 resources/3rdparty/cudd-2.5.0/epd/epd.h create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/README create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/mnemalyse.c create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/mnemconf.h create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.c create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.h create mode 100644 resources/3rdparty/cudd-2.5.0/mnemosyne/mtest.c create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/Makefile.sis create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/doc/mtr.doc create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/mtr.h create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/mtrBasic.c create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/mtrGroup.c create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/mtrInt.h create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/test.groups create mode 100644 resources/3rdparty/cudd-2.5.0/mtr/testmtr.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/C17.blif create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/C17.out create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/C880.blif create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/C880.out create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/README create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/bnet.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/bnet.h create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/chkMterm.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/main.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.blif create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.out create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/nanotrav.1 create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntr.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntr.h create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntrBddTest.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntrHeap.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntrMflow.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntrShort.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ntrZddTest.c create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.blif create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.out create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/s27.blif create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/s27.out create mode 100755 resources/3rdparty/cudd-2.5.0/nanotrav/tst.sh create mode 100644 resources/3rdparty/cudd-2.5.0/nanotrav/ucbqsort.c create mode 100644 resources/3rdparty/cudd-2.5.0/obj/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc create mode 100644 resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh create mode 100644 resources/3rdparty/cudd-2.5.0/obj/testobj.cc create mode 100755 resources/3rdparty/cudd-2.5.0/setup.sh create mode 100755 resources/3rdparty/cudd-2.5.0/shutdown.sh create mode 100644 resources/3rdparty/cudd-2.5.0/sis/Makefile.sis create mode 100644 resources/3rdparty/cudd-2.5.0/sis/cuddBdd.h create mode 100644 resources/3rdparty/cudd-2.5.0/sis/cuddBddPort.c create mode 100644 resources/3rdparty/cudd-2.5.0/sis/cuddPwPt.c create mode 100644 resources/3rdparty/cudd-2.5.0/sis/st.c create mode 100644 resources/3rdparty/cudd-2.5.0/sis/st.h create mode 100644 resources/3rdparty/cudd-2.5.0/st/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/st/doc/stAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/st/doc/stAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/st/doc/stExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/st/doc/stExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/st/st.c create mode 100644 resources/3rdparty/cudd-2.5.0/st/st.h create mode 100644 resources/3rdparty/cudd-2.5.0/util/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/util/cpu_stats.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/cpu_time.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/datalimit.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/pathsearch.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/pipefork.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/prtime.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/ptime.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/restart.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/safe_mem.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/saveimage.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/state.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/strsav.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/stub.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/test-res.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/test-sav.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/texpand.c create mode 100644 resources/3rdparty/cudd-2.5.0/util/util.h diff --git a/resources/3rdparty/cudd-2.5.0/LICENSE b/resources/3rdparty/cudd-2.5.0/LICENSE new file mode 100644 index 000000000..99c7fbae5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 1995-2004, Regents of the University of Colorado + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +Neither the name of the University of Colorado nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/resources/3rdparty/cudd-2.5.0/Makefile b/resources/3rdparty/cudd-2.5.0/Makefile new file mode 100644 index 000000000..6c7fbb4d3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/Makefile @@ -0,0 +1,323 @@ +# $Id$ +# +# Makefile for the CUDD distribution kit +#--------------------------------------------------------------------------- + +# Beginning of the configuration section. These symbol definitions can +# be overridden from the command line. + +# C++ compiler +#CXX = g++ +#CXX = icpc +#CXX = ecpc +#CXX = CC +#CXX = /usr/local/opt/SUNWspro/bin/CC +#CXX = cxx +CXX = clang++ + +# Specific options for compilation of C++ files. +CXXFLAGS = -std=c++11 -stdlib=libc++ +# Stricter standard conformance for g++. +#CXXFLAGS = -std=c++98 +# For Sun CC version 5, this invokes compatibility mode. +#CXXFLAGS = -compat +# On some versions of UP-UX, it is necessary to pass the option +a1 +# to CC for the C++ test program to compile successfully. +#CXXFLAGS = +a1 + +# C compiler used for all targets except optimize_dec, which always uses cc. +#CC = cc +#CC = /usr/local/opt/SUNWspro/bin/cc +#CC = gcc +#CC = icc +#CC = ecc +#CC = /usr/ucb/cc +#CC = c89 +#CC = $(CXX) +CC = clang + +# On some machines ranlib is either non-existent or redundant. +# Use the following definition if your machine has ranlib and you think +# it is needed. +RANLIB = ranlib +# Use the following definition if your machine either does not have +# ranlib (e.g., SUN running solaris) or can do without it (e.g., DEC Alpha). +#RANLIB = : + +# Use ICFLAGS to specify machine-independent compilation flags. +# These three are typical settings for cc. +#ICFLAGS = -g +#ICFLAGS = -O +#ICFLAGS = +# These two are typical settings for optimized code with gcc. +#ICFLAGS = -g -O3 -Wall +ICFLAGS = -O3 + +# Use XCFLAGS to specify machine-dependent compilation flags. +# For some platforms no special flags are needed. +#XCFLAGS = -DHAVE_IEEE_754 -DBSD +# +#========================== +# Linux +# +# Gcc 4.2.4 or higher on i686. +XCFLAGS = -arch x86_64 -DHAVE_IEEE_754 -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# Gcc 3.2.2 or higher on i686. +#XCFLAGS = -mtune=pentium4 -malign-double -DHAVE_IEEE_754 -DBSD +# Gcc 2.8.1 on i686. +#XCFLAGS = -mcpu=pentiumpro -malign-double -DHAVE_IEEE_754 -DBSD +# Gcc 4.2.4 or higher on x86_64 (64-bit compilation) +#XCFLAGS = -mtune=native -DHAVE_IEEE_754 -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# Gcc 4.2.4 or higher on x86_64 (32-bit compilation) +#XCFLAGS = -m32 -mtune=native -malign-double -DHAVE_IEEE_754 -DBSD +# Icc on i686 (older versions may not support -xHost). +#XCFLAGS = -ansi -xHost -align -ip -DHAVE_IEEE_754 -DBSD +# Icc on x86_64 (64-bit compilation). +#XCFLAGS = -ansi -xHost -align -ip -DHAVE_IEEE_754 -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# Gcc on ia64. +#XCFLAGS = -DHAVE_IEEE_754 -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# Icc/ecc on ia64. +#XCFLAGS = -ansi -DBSD -DHAVE_IEEE_754 -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# +#========================== +# Solaris +# +# For Solaris, BSD should not be replaced by UNIX100. +#XCFLAGS = -DHAVE_IEEE_754 -DUNIX100 -DEPD_BIG_ENDIAN +# Gcc 2.8.1 or higher on Ultrasparc. +#XCFLAGS = -mcpu=ultrasparc -DHAVE_IEEE_754 -DUNIX100 -DEPD_BIG_ENDIAN +# For Solaris 2.5 and higher, optimized code with /usr/bin/cc or CC. +#XCFLAGS = -DHAVE_IEEE_754 -DUNIX100 -xO5 -native -dalign -DEPD_BIG_ENDIAN +# On IA platforms, -dalign is not supported and causes warnings. +#XCFLAGS = -DHAVE_IEEE_754 -DUNIX100 -xO5 -native +# Recent Sun compilers won't let you use -native on old Ultras. +#XCFLAGS = -DHAVE_IEEE_754 -DUNIX100 -xO5 -dalign -xlibmil -DEPD_BIG_ENDIAN +# For Solaris 2.4, optimized code with /usr/bin/cc. +#XCFLAGS = -DHAVE_IEEE_754 -DUNIX100 -xO4 -dalign -DEPD_BIG_ENDIAN +# For Solaris 2.5 and higher, optimized code with /usr/ucb/cc. +#XCFLAGS = -DHAVE_IEEE_754 -DBSD -xO5 -native -dalign -DEPD_BIG_ENDIAN +#XCFLAGS = -DHAVE_IEEE_754 -DBSD -xO5 -dalign -xlibmil -DEPD_BIG_ENDIAN +# For Solaris 2.4, optimized code with /usr/ucb/cc. +#XCFLAGS = -DHAVE_IEEE_754 -DBSD -xO4 -dalign -DEPD_BIG_ENDIAN +# +#========================== +# DEC Alphas running Digital Unix +# +# For DEC Alphas either -ieee_with_inexact or -ieee_with_no_inexact is +# needed. If you use only BDDs, -ieee_with_no_inexact is enough. +# In the following, we consider three different compilers: +# - the old native compiler (the one of MIPS ancestry that produces u-code); +# - the new native compiler; +# - gcc +# On the Alphas, gcc (as of release 2.7.2) does not support 32-bit pointers +# and IEEE 754 floating point arithmetic. Therefore, for this architecture +# only, the native compilers provide a substatial advantage. +# With the native compilers, specify -xtaso for 32-bit pointers. +# Do not use -xtaso_short because explicit reference to stdout and stderr +# does not work with this option. (Among other things.) +# Notice that -taso must be included in LDFLAGS for -xtaso to work. +# Given the number of possible choices, only some typical configurations +# are proposed here. +# +# Old native compiler for the Alphas; 64-bit pointers. +#XCFLAGS = -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# Old native compiler for the Alphas; 32-bit pointers. +#XCFLAGS = -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -xtaso -DSIZEOF_LONG=8 +# New native compiler for the Alphas; 64-bit pointers. +#XCFLAGS = -g3 -O4 -std -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# New native compiler for the Alphas; 32-bit pointers. +#XCFLAGS = -g3 -O4 -std -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -xtaso -DSIZEOF_LONG=8 +# gcc for the Alphas: compile without HAVE_IEEE_754. +#XCFLAGS = -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# +#========================== +# +# IBM RS6000 +# +# For the IBM RS6000 -qstrict is necessary when specifying -O3 with cc. +#XCFLAGS = -DBSD -DHAVE_IEEE_754 -DEPD_BIG_ENDIAN -O3 -qstrict +# +#========================== +# +# HP-UX +# +# I haven't figured out how to enable IEEE 754 on the HPs I've tried... +# For HP-UX using gcc. +#XCFLAGS = -DUNIX100 -DEPD_BIG_ENDIAN +# For HP-UX using c89. +#XCFLAGS = +O3 -DUNIX100 -DEPD_BIG_ENDIAN +# +#========================== +# +# Windows 95/98/NT/XP/Vista/7 with Cygwin tools +# +# The value of RLIMIT_DATA_DEFAULT should reflect the amount of +# available memory (expressed in bytes). +# Recent versions of cygwin have getrlimit, but the datasize limit +# cannot be set. +#XCFLAGS = -mtune=native -malign-double -DHAVE_IEEE_754 -DHAVE_GETRLIMIT=0 -DRLIMIT_DATA_DEFAULT=268435456 + + +# Define the level of self-checking and verbosity of the CUDD package. +#DDDEBUG = -DDD_DEBUG -DDD_VERBOSE -DDD_STATS -DDD_CACHE_PROFILE -DDD_UNIQUE_PROFILE -DDD_COUNT +DDDEBUG = + +# Define the level of self-checking and verbosity of the MTR package. +#MTRDEBUG = -DMTR_DEBUG +MTRDEBUG = + +# Loader options. +LDFLAGS = +# This may produce faster code on the DECstations. +#LDFLAGS = -jmpopt -Olimit 1000 +# This may be necessary under some old versions of Linux. +#LDFLAGS = -static +# This normally makes the program faster on the DEC Alphas. +#LDFLAGS = -non_shared -om +# This is for 32-bit pointers on the DEC Alphas. +#LDFLAGS = -non_shared -om -taso +#LDFLAGS = -non_shared -taso + +# Define PURE as purify to link with purify. +# Define PURE as quantify to link with quantify. +# Remember to compile with -g if you want line-by-line info with quantify. +PURE = +#PURE = purify +#PURE = quantify + +# Define EXE as .exe for MS-DOS and derivatives. Not required by recent +# versions of cygwin. +EXE = +#EXE = .exe + +# End of the configuration section. +#--------------------------------------------------------------------------- + +MFLAG = -DMNEMOSYNE +MNEMLIB = ../mnemosyne/libmnem.a + +DDWDIR = . +IDIR = $(DDWDIR)/include +INCLUDE = -I$(IDIR) + +BDIRS = cudd dddmp mtr st util epd obj +DIRS = $(BDIRS) + +#------------------------------------------------------------------------ + +.PHONY : build +.PHONY : nanotrav +.PHONY : check_leaks +.PHONY : optimize_dec +.PHONY : testcudd +.PHONY : libobj +.PHONY : testobj +.PHONY : testdddmp +.PHONY : testmtr +.PHONY : lint +.PHONY : all +.PHONY : clean +.PHONY : distclean + + +build: + sh ./setup.sh + @for dir in $(DIRS); do \ + (cd $$dir; \ + echo Making $$dir ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" )\ + done + +nanotrav: build + +check_leaks: + sh ./setup.sh + @for dir in mnemosyne $(DIRS); do \ + (cd $$dir; \ + echo Making $$dir ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG=$(MFLAG) MNEMLIB=$(MNEMLIB) ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" EXE="$(EXE)" )\ + done + +optimize_dec: + sh ./setup.sh + @for dir in $(DIRS); do \ + (cd $$dir; \ + echo Making $$dir ...; \ + make CC=$(CC) RANLIB=$(RANLIB) XCFLAGS="$(XCFLAGS)" LDFLAGS="$(LDFLAGS)" optimize_dec )\ + done + +lint: + sh ./setup.sh + @for dir in $(DIRS) obj; do \ + (cd $$dir; \ + echo Making lint in $$dir ...; \ + make CC=$(CC) lint )\ + done + +tags: + sh ./setup.sh + @for dir in $(DIRS) obj; do \ + (cd $$dir; \ + echo Making tags in $$dir ...; \ + make CC=$(CC) tags )\ + done + +all: + sh ./setup.sh + @for dir in $(DIRS); do \ + (cd $$dir; \ + echo Making all in $$dir ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" all )\ + done + +testcudd: + sh ./setup.sh + @for dir in util st mtr epd; do \ + (cd $$dir; \ + echo Making $$dir ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" )\ + done + @(cd cudd; \ + echo Making testcudd ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" testcudd$(EXE) ) + +objlib: + sh ./setup.sh + @for dir in $(BDIRS); do \ + (cd $$dir; \ + echo Making $$dir ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" )\ + done + @(cd obj; \ + echo Making obj ...; \ + make CXX=$(CXX) CXXFLAGS=$(CXXFLAGS) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" ) + +testobj: objlib + @(cd obj; \ + echo Making testobj ...; \ + make CXX=$(CXX) CXXFLAGS=$(CXXFLAGS) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" testobj$(EXE) ) + +testdddmp: build + @(cd dddmp; \ + echo Making testdddmp ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" testdddmp$(EXE) ) + +testmtr: build + @(cd mtr; \ + echo Making testmtr ...; \ + make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" testmtr$(EXE) ) + +clean: + @for dir in mnemosyne $(DIRS) obj; do \ + (cd $$dir; \ + echo Cleaning $$dir ...; \ + make -s clean ) \ + done + +distclean: + @for dir in mnemosyne $(DIRS) obj; do \ + (cd $$dir; \ + echo Cleaning $$dir ...; \ + make -s EXE="$(EXE)" distclean ) \ + done + sh ./shutdown.sh diff --git a/resources/3rdparty/cudd-2.5.0/README b/resources/3rdparty/cudd-2.5.0/README new file mode 100644 index 000000000..864a416f9 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/README @@ -0,0 +1,177 @@ +$Id$ + +This directory contains a set of packages that allow you to build a toy +application based on the CUDD package. + +The CUDD package is a package written in C for the manipulation of +decision diagrams. It supports binary decision diagrams (BDDs), +algebraic decision diagrams (ADDs), and Zero-Suppressed BDDs (ZDDs). + +The toy application provided in this kit is called nanotrav and is a +simple-minded FSM traversal program. (See the README file and the man +page nanotrav.1 in the nanotrav directory for the details.) It is +included so that you can run a sanity check on your installation. + +INSTALLATION + +Before you build the libraries and programs, you need to check the +Makefile in the top directory. Go through the definitions contained in the +configuration section, and select the desired compiler and compilation +flags. Instructions are provided in the comments of the Makefile. + +You can always specify the options on the command line. For instance, +on some machines you can build a "fast" version of the program by typing: + + make DDDEBUG= MTRDEBUG= ICFLAGS=-O2 + +The Makefile supports several targets: + + make: + Creates a "plain" version of the program. + + make testdddmp: + Builds a test program (testdddmp) for BDD loading from and + storing to disk. See file README.test in the dddmp directory for + how to run the program. + + make testobj: + Builds a test program for the C++ interface. Requires a C++ + compiler. To run the program, run obj/testobj. + + make testcudd: + Builds a test program for CUDD. To run the program, go to the + cudd directory and type "./testcudd -p 2 r7x8.1.mat". The result + can be compared to r7x7.1.out. + + make testmtr: + Builds a test program for the mtr package. To run the program, + go to the mtr directory and type "./testmtr -p 1 test.groups". + + make clean: + Cleans directories, but leaves libraries and programs. + + make distclean: + Cleans thoroughly, returning the directories to their pristine + state. + +The following targets are more or less obsolete and may disappear or +change in the future. + + make check_leaks: + Creates a version of the program with the mnemosyne library + linked to it. It also builds the mnemalyse program, which + helps in finding memory leaks. This target does not work on the + IBM RS6000. The makefile also supports purify. To use purify, + set the PURE variable in the Makefile, and use the standard + target. + + make optimize_dec: + Builds a version of the program using the u-code compiler + available on DEC machines (DECstations and Alphas). The newer + native compiler on the Alphas does not use u-code, though. + Therefore the standard target should be used with it. + + make lint: + Runs lint on all subdirectories except mnemosyne. Creates lint + libraries for all object libraries. + + make tags: + Builds ctags-style tag files for all subdirectories except + mnemosyne. + + make all: + Makes all of the above, except check_leaks, which is + incompatible with a plain "make." + +All targets, except clean and distclean, will create the include +directory if it does not already exist. + +The Makefile does not compile the SIS interface (cuddBddPort.c and +cuddPwPt.c found in subdirectory sis). To compile the interface, you +also need array.h and var_set.h, which are not part of this +distribution, but come with SIS. Detailed instructions on how to +integrate the CUDD package in SIS can be found in the documentation +(cudd/doc). + +PLATFORMS + +This kit has been successfully built on the following configurations: + + PC (ia32 and ia64) running Ubuntu with gcc + PC (ia32 and ia64) running Ubuntu with g++ + PC (ia32 and ia64) running Linux RedHat with gcc + PC (ia32 and ia64) running Linux RedHat with g++ + PC (ia64) running Cygwin on Windows 7 and Vista with gcc + PC (ia64) running Cygwin on Windows 7 and Vista with g++ + +Platforms to which I have no longer access and therefore are no longer +supported. + + PC (ia32) running Linux RedHat with icc + PC (ia32) running Linux RedHat with icpc + PC (ia64) running Linux RedHat with ecc + PC (ia64) running Linux RedHat with ecpc + SUN running Solaris 2.8 with cc + SUN running Solaris 2.8 with CC + SUN running Solaris 2.8 with gcc + SUN running Solaris 2.8 with g++ + DECstation running Ultrix with cc + DECstation running Ultrix with gcc + IBM RS6000 running AIX 3.2.4 with cc (**) + IBM RS6000 running AIX 3.2.4 with gcc + IBM RS6000 running AIX 3.2.4 with g++ + SUN running SunOS with gcc + DEC Alpha running Digital Unix with cc + DEC Alpha running Digital Unix with cxx + DEC Alpha running Digital Unix with gcc + HP 9000/770 running HP-UX with c89 + HP 9000/770 running HP-UX with CC + HP 9000/770 running HP-UX with gcc + HP 9000/770 running HP-UX with g++ (*) + SUN running Solaris 2.8 with /usr/ucb/cc + PC running Solaris 2.8 with /usr/bin/cc + PC running Solaris 2.8 with /usr/ucb/cc + PC running Solaris 2.8 with CC + PC running Solaris 2.8 with gcc + PC running Solaris 2.8 with g++ + +NOTES + (*) C programs were compiled with g++, but linked with gcc. + + (**) Some old versions of the AIX cc compiler have buggy optimizers: + Try compiling with -O2 instead of -O3 if the program crashes. + +Running lint and compiling with gcc -Wall still produces warnings. +Running `purify' under Solaris 2.8 generates no messages. + +SANITY CHECK + +The directory `nanotrav' contains a very simple application based on the +CUDD package. The `nanotrav' directory contains a man page that +describes the options nanotrav supports. The files *.blif are sample +input files for nanotrav. + +If you have built the mnemosyne library (make check_leaks), you can do + cd mnemosyne + make runmtest +This does not work on machines running SunOS, but the version of +nanotrav that uses mnemosyne may work. + +DOCUMENTATION + +Directory cudd-2.5.0/cudd/doc contains HTML documentation for the CUDD +package. The recommended starting point is cuddIntro.html. Documentation +in both postscript(tm) format and plain text format is also provided. +Documentation for the auxiliary libraries (except for the util library) +is in the doc subdirectories. + +FEEDBACK: + +Send feedback to: + +Fabio Somenzi +University of Colorado at Boulder +ECE Dept. +Boulder, CO 80309-0425 +Fabio@Colorado.EDU +http://vlsi.colorado.edu/~fabio diff --git a/resources/3rdparty/cudd-2.5.0/RELEASE.NOTES b/resources/3rdparty/cudd-2.5.0/RELEASE.NOTES new file mode 100644 index 000000000..22867e568 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/RELEASE.NOTES @@ -0,0 +1,131 @@ +Release 2.5.0 of Cudd introduces the ability to set timeouts. The +function that is interrupted returns NULL (which the application must +be prepared to handle,) but the BDDs are uncorrupted and the invoking +program can continue to use the manager. + +In addition, reordering is now aware of timeouts, so that it gives up +when a timeout is approaching to give the invoking program a chance to +obtain some results. + +The response time to the timeout is not immediate, though most of the time +it is well below one second. Checking for timeouts has a small overhead. +In experiments, less than 1% has been observed on average. + +Creation of BDD managers with many variables (e.g., tens or hundreds +of thousands) is now much more efficient. Computing small supports of +BDDs when there are many variables is also much more efficient, but +this has been at the cost of separating the function for BDDs and ADDs +(Cudd_Support) from that for ZDDs (Cudd_zddSupport). + +The C++ interface has undergone a major upgrade. + +The handling of variable gruops in reordering has been much improved. +(Thanks to Arie Gurfinkel for a very detailed bug report!) A handful +of other bugs have been fixed as well. + + +New Functions: + +unsigned long Cudd_ReadStartTime(DdManager *unique); + +unsigned long Cudd_ReadElapsedTime(DdManager *unique); + +void Cudd_SetStartTime(DdManager *unique, unsigned long st); + +void Cudd_ResetStartTime(DdManager *unique); + +unsigned long Cudd_ReadTimeLimit(DdManager *unique); + +void Cudd_SetTimeLimit(DdManager *unique, unsigned long tl); + +void Cudd_UpdateTimeLimit(DdManager * unique); + +void Cudd_IncreaseTimeLimit(DdManager * unique, unsigned long increase); + +void Cudd_UnsetTimeLimit(DdManager *unique); + +int Cudd_TimeLimited(DdManager *unique); + +unsigned int Cudd_ReadMaxReorderings (DdManager *dd); + +void Cudd_SetMaxReorderings (DdManager *dd, unsigned int mr); + +unsigned int Cudd_ReadOrderRandomization(DdManager * dd); + +void Cudd_SetOrderRandomization(DdManager * dd, unsigned int factor); + +int Cudd_PrintGroupedOrder(DdManager * dd, const char *str, void *data); + +int Cudd_EnableOrderingMonitoring(DdManager *dd); + +int Cudd_DisableOrderingMonitoring(DdManager *dd); + +int Cudd_OrderingMonitoring(DdManager *dd); + +DdNode * Cudd_bddExistAbstractLimit(DdManager * manager, DdNode * f, DdNode * cube, unsigned int limit); + +DdNode * Cudd_bddIteLimit (DdManager *dd, DdNode *f, DdNode *g, DdNode *h, unsigned int limit); + +DdNode * Cudd_bddOrLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); + +DdNode * Cudd_bddXnorLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); + +int Cudd_CheckCube (DdManager *dd, DdNode *g); + +DdNode * Cudd_bddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f); + +DdNode * Cudd_bddLargestPrimeUnate(DdManager *dd , DdNode *f, DdNode *phaseBdd); + +int Cudd_Reserve(DdManager *manager, int amount); + +int Cudd_SupportIndices(DdManager * dd, DdNode * f, int **indices); + +int Cudd_VectorSupportIndices(DdManager * dd, DdNode ** F, int n, int **indices); + +DdNode * Cudd_zddSupport(DdManager * dd, DdNode * f); + + +Changed prototypes: + +unsigned int Cudd_ReadReorderings (DdManager *dd); + +---------------------------------------------------------------------- + +Release 2.4.2 of Cudd features several bug fixes. The most important +are those that prevented Cudd from making full use of up to 4 GB of +memory when using 32-bit pointers. A handful of bugs were discovered by +Coverity. (Thanks to Christian Stangier!) + +This release can be compiled with either 64-bit pointers or 32-bit +pointers on x86_64 platforms if sizeof(long) = sizeof(void *) = 8 and +sizeof(int) = 4. This is known as the LP64 model. For 32-bit pointers, +one usually needs supplementary libraries. On Ubuntu and Debian Linux, +one needs g++-multilib, which can be installed with +"apt-get install g++-multilib." + +Added functions + +DdNode *Cudd_Inequality (DdManager * dd, int N, int c, DdNode ** x, +DdNode ** y); + +DdNode * Cudd_Disequality (DdManager * dd, int N, int c, DdNode ** x, +DdNode ** y); + +DdNode * Cudd_bddInterval (DdManager * dd, int N, DdNode ** x, +unsigned int lowerB, unsigned int upperB); + +Changed prototypes: + +int Cudd_DumpBlif (DdManager *dd, int n, DdNode **f, char +**inames, char **onames, char *mname, FILE *fp, int mv); + +int Cudd_DumpBlifBody (DdManager *dd, int n, DdNode **f, char +**inames, char **onames, FILE *fp, int mv); + +The additional parameter allows the caller to choose between plain blif +and blif-MV. + +---------------------------------------------------------------------- + +Release 2.4.1 of Cudd features one major change with respect to previous +releases. The licensing terms are now explicitly stated. diff --git a/resources/3rdparty/cudd-2.5.0/cudd/Makefile b/resources/3rdparty/cudd-2.5.0/cudd/Makefile new file mode 100644 index 000000000..d76954746 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/Makefile @@ -0,0 +1,124 @@ +# $Id$ +# +# Cudd - DD package +#--------------------------- +.SUFFIXES: .o .c .u + +CC = gcc +RANLIB = ranlib +PURE = +# Define EXE as .exe for MS-DOS and derivatives. +EXE = +#EXE = .exe + +MFLAG = +ICFLAGS = -g +XCFLAGS = -DDD_STATS +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) +#DDDEBUG = -DDD_DEBUG -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_UNIQUE_PROFILE +DDDEBUG = + +LINTFLAGS = -u -n -DDD_STATS -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_DEBUG -DDD_UNIQUE_PROFILE + +# this is to create the lint library +LINTSWITCH = -o + +WHERE = .. + +INCLUDE = $(WHERE)/include + +LIBS = ./libcudd.a $(WHERE)/mtr/libmtr.a \ + $(WHERE)/st/libst.a $(WHERE)/util/libutil.a $(WHERE)/epd/libepd.a + +MNEMLIB = + +BLIBS = -kL. -klcudd -kL$(WHERE)/mtr -klmtr \ + -kL$(WHERE)/st -klst -kL$(WHERE)/util -klutil -kL$(WHERE)/epd -klepd + +LINTLIBS = ./llib-lcudd.ln $(WHERE)/mtr/llib-lmtr.ln \ + $(WHERE)/st/llib-lst.ln $(WHERE)/util/llib-lutil.ln \ + $(WHERE)/epd/llib-lepd.ln + +LDFLAGS = + +# files for the package +P = cudd +PSRC = cuddAPI.c cuddAddAbs.c cuddAddApply.c cuddAddFind.c cuddAddIte.c \ + cuddAddInv.c cuddAddNeg.c cuddAddWalsh.c cuddAndAbs.c \ + cuddAnneal.c cuddApa.c cuddApprox.c cuddBddAbs.c cuddBddCorr.c \ + cuddBddIte.c cuddBridge.c cuddCache.c cuddCheck.c cuddClip.c \ + cuddCof.c cuddCompose.c cuddDecomp.c cuddEssent.c \ + cuddExact.c cuddExport.c cuddGenCof.c cuddGenetic.c \ + cuddGroup.c cuddHarwell.c cuddInit.c cuddInteract.c \ + cuddLCache.c cuddLevelQ.c \ + cuddLinear.c cuddLiteral.c cuddMatMult.c cuddPriority.c \ + cuddRead.c cuddRef.c cuddReorder.c cuddSat.c cuddSign.c \ + cuddSolve.c cuddSplit.c cuddSubsetHB.c cuddSubsetSP.c cuddSymmetry.c \ + cuddTable.c cuddUtil.c cuddWindow.c cuddZddCount.c cuddZddFuncs.c \ + cuddZddGroup.c cuddZddIsop.c cuddZddLin.c cuddZddMisc.c \ + cuddZddPort.c cuddZddReord.c cuddZddSetop.c cuddZddSymm.c \ + cuddZddUtil.c +PHDR = cudd.h cuddInt.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +TARGET = test$(P)$(EXE) +TARGETu = test$(P)-u + +# files for the test program +SRC = test$(P).c +OBJ = $(SRC:.c=.o) +UBJ = $(SRC:.c=.u) + +#------------------------------------------------------ + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PSRC) $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) $(DDDEBUG) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) +$(OBJ): $(PHDR) +$(UBJ): $(PHDR) + +$(TARGET): $(SRC) $(OBJ) $(HDR) $(LIBS) $(MNEMLIB) + $(PURE) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +# optimize (DECstations and Alphas only: uses u-code) +$(TARGETu): $(SRC) $(UBJ) $(HDR) $(LIBS:.a=.b) + $(CC) -O3 -Olimit 1000 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +lintpgm: lint + lint $(LINTFLAGS) -I$(INCLUDE) $(SRC) $(LINTLIBS) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +programs: $(TARGET) $(TARGETu) lintpgm + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \ + *.bak *~ tags .gdb_history *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cudd.h b/resources/3rdparty/cudd-2.5.0/cudd/cudd.h new file mode 100644 index 000000000..d60d0c8f8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cudd.h @@ -0,0 +1,1082 @@ +/**CHeaderFile***************************************************************** + + FileName [cudd.h] + + PackageName [cudd] + + Synopsis [The University of Colorado decision diagram package.] + + Description [External functions and data strucures of the CUDD package. +
            +
          • To turn on the gathering of statistics, define DD_STATS. +
          • To link with mis, define DD_MIS. +
          + Modified by Abelardo Pardo to interface it to VIS. + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: cudd.h,v 1.180 2012/02/05 01:07:18 fabio Exp $] + +******************************************************************************/ + +#ifndef _CUDD +#define _CUDD + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include "mtr.h" +#include "epd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define CUDD_VERSION "2.5.0" + +#ifndef SIZEOF_VOID_P +#define SIZEOF_VOID_P 4 +#endif +#ifndef SIZEOF_INT +#define SIZEOF_INT 4 +#endif +#ifndef SIZEOF_LONG +#define SIZEOF_LONG 4 +#endif + +#define CUDD_TRUE 1 +#define CUDD_FALSE 0 + +#define CUDD_VALUE_TYPE double +#define CUDD_OUT_OF_MEM -1 +/* The sizes of the subtables and the cache must be powers of two. */ +#define CUDD_UNIQUE_SLOTS 256 /* initial size of subtables */ +#define CUDD_CACHE_SLOTS 262144 /* default size of the cache */ + +/* Constants for residue functions. */ +#define CUDD_RESIDUE_DEFAULT 0 +#define CUDD_RESIDUE_MSB 1 +#define CUDD_RESIDUE_TC 2 + +/* CUDD_MAXINDEX is defined in such a way that on 32-bit and 64-bit +** machines one can cast an index to (int) without generating a negative +** number. +*/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define CUDD_MAXINDEX (((DdHalfWord) ~0) >> 1) +#else +#define CUDD_MAXINDEX ((DdHalfWord) ~0) +#endif + +/* CUDD_CONST_INDEX is the index of constant nodes. Currently this +** is a synonim for CUDD_MAXINDEX. */ +#define CUDD_CONST_INDEX CUDD_MAXINDEX + +/* These constants define the digits used in the representation of +** arbitrary precision integers. The configurations tested use 8, 16, +** and 32 bits for each digit. The typedefs should be in agreement +** with these definitions. +*/ +#if SIZEOF_LONG == 8 +#define DD_APA_BITS 32 +#define DD_APA_BASE (1L << DD_APA_BITS) +#define DD_APA_HEXPRINT "%08x" +#else +#define DD_APA_BITS 16 +#define DD_APA_BASE (1 << DD_APA_BITS) +#define DD_APA_HEXPRINT "%04x" +#endif +#define DD_APA_MASK (DD_APA_BASE - 1) + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/**Enum************************************************************************ + + Synopsis [Type of reordering algorithm.] + + Description [Type of reordering algorithm.] + +******************************************************************************/ +typedef enum { + CUDD_REORDER_SAME, + CUDD_REORDER_NONE, + CUDD_REORDER_RANDOM, + CUDD_REORDER_RANDOM_PIVOT, + CUDD_REORDER_SIFT, + CUDD_REORDER_SIFT_CONVERGE, + CUDD_REORDER_SYMM_SIFT, + CUDD_REORDER_SYMM_SIFT_CONV, + CUDD_REORDER_WINDOW2, + CUDD_REORDER_WINDOW3, + CUDD_REORDER_WINDOW4, + CUDD_REORDER_WINDOW2_CONV, + CUDD_REORDER_WINDOW3_CONV, + CUDD_REORDER_WINDOW4_CONV, + CUDD_REORDER_GROUP_SIFT, + CUDD_REORDER_GROUP_SIFT_CONV, + CUDD_REORDER_ANNEALING, + CUDD_REORDER_GENETIC, + CUDD_REORDER_LINEAR, + CUDD_REORDER_LINEAR_CONVERGE, + CUDD_REORDER_LAZY_SIFT, + CUDD_REORDER_EXACT +} Cudd_ReorderingType; + + +/**Enum************************************************************************ + + Synopsis [Type of aggregation methods.] + + Description [Type of aggregation methods.] + +******************************************************************************/ +typedef enum { + CUDD_NO_CHECK, + CUDD_GROUP_CHECK, + CUDD_GROUP_CHECK2, + CUDD_GROUP_CHECK3, + CUDD_GROUP_CHECK4, + CUDD_GROUP_CHECK5, + CUDD_GROUP_CHECK6, + CUDD_GROUP_CHECK7, + CUDD_GROUP_CHECK8, + CUDD_GROUP_CHECK9 +} Cudd_AggregationType; + + +/**Enum************************************************************************ + + Synopsis [Type of hooks.] + + Description [Type of hooks.] + +******************************************************************************/ +typedef enum { + CUDD_PRE_GC_HOOK, + CUDD_POST_GC_HOOK, + CUDD_PRE_REORDERING_HOOK, + CUDD_POST_REORDERING_HOOK +} Cudd_HookType; + + +/**Enum************************************************************************ + + Synopsis [Type of error codes.] + + Description [Type of error codes.] + +******************************************************************************/ +typedef enum { + CUDD_NO_ERROR, + CUDD_MEMORY_OUT, + CUDD_TOO_MANY_NODES, + CUDD_MAX_MEM_EXCEEDED, + CUDD_TIMEOUT_EXPIRED, + CUDD_INVALID_ARG, + CUDD_INTERNAL_ERROR +} Cudd_ErrorType; + + +/**Enum************************************************************************ + + Synopsis [Group type for lazy sifting.] + + Description [Group type for lazy sifting.] + +******************************************************************************/ +typedef enum { + CUDD_LAZY_NONE, + CUDD_LAZY_SOFT_GROUP, + CUDD_LAZY_HARD_GROUP, + CUDD_LAZY_UNGROUP +} Cudd_LazyGroupType; + + +/**Enum************************************************************************ + + Synopsis [Variable type.] + + Description [Variable type. Currently used only in lazy sifting.] + +******************************************************************************/ +typedef enum { + CUDD_VAR_PRIMARY_INPUT, + CUDD_VAR_PRESENT_STATE, + CUDD_VAR_NEXT_STATE +} Cudd_VariableType; + + +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +typedef unsigned int DdHalfWord; +#else +typedef unsigned short DdHalfWord; +#endif + +typedef struct DdNode DdNode; + +typedef struct DdChildren { + struct DdNode *T; + struct DdNode *E; +} DdChildren; + +/* The DdNode structure is the only one exported out of the package */ +struct DdNode { + DdHalfWord index; + DdHalfWord ref; /* reference count */ + DdNode *next; /* next pointer for unique table */ + union { + CUDD_VALUE_TYPE value; /* for constant nodes */ + DdChildren kids; /* for internal nodes */ + } type; +}; + +typedef struct DdManager DdManager; + +typedef struct DdGen DdGen; + +/* These typedefs for arbitrary precision arithmetic should agree with +** the corresponding constant definitions above. */ +#if SIZEOF_LONG == 8 +typedef unsigned int DdApaDigit; +typedef unsigned long int DdApaDoubleDigit; +#else +typedef unsigned short int DdApaDigit; +typedef unsigned int DdApaDoubleDigit; +#endif +typedef DdApaDigit * DdApaNumber; + +/* Return type for function computing two-literal clauses. */ +typedef struct DdTlcInfo DdTlcInfo; + +/* Type of hook function. */ +typedef int (*DD_HFP)(DdManager *, const char *, void *); +/* Type of priority function */ +typedef DdNode * (*DD_PRFP)(DdManager * , int, DdNode **, DdNode **, + DdNode **); +/* Type of apply operator. */ +typedef DdNode * (*DD_AOP)(DdManager *, DdNode **, DdNode **); +/* Type of monadic apply operator. */ +typedef DdNode * (*DD_MAOP)(DdManager *, DdNode *); +/* Types of cache tag functions. */ +typedef DdNode * (*DD_CTFP)(DdManager *, DdNode *, DdNode *); +typedef DdNode * (*DD_CTFP1)(DdManager *, DdNode *); +/* Type of memory-out function. */ +typedef void (*DD_OOMFP)(long); +/* Type of comparison function for qsort. */ +typedef int (*DD_QSFP)(const void *, const void *); + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if the node is a constant node.] + + Description [Returns 1 if the node is a constant node (rather than an + internal node). All constant nodes have the same index + (CUDD_CONST_INDEX). The pointer passed to Cudd_IsConstant may be either + regular or complemented.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define Cudd_IsConstant(node) ((Cudd_Regular(node))->index == CUDD_CONST_INDEX) + + +/**Macro*********************************************************************** + + Synopsis [Complements a DD.] + + Description [Complements a DD by flipping the complement attribute of + the pointer (the least significant bit).] + + SideEffects [none] + + SeeAlso [Cudd_NotCond] + +******************************************************************************/ +#define Cudd_Not(node) ((DdNode *)((long)(node) ^ 01)) + + +/**Macro*********************************************************************** + + Synopsis [Complements a DD if a condition is true.] + + Description [Complements a DD if condition c is true; c should be + either 0 or 1, because it is used directly (for efficiency). If in + doubt on the values c may take, use "(c) ? Cudd_Not(node) : node".] + + SideEffects [none] + + SeeAlso [Cudd_Not] + +******************************************************************************/ +#define Cudd_NotCond(node,c) ((DdNode *)((long)(node) ^ (c))) + + +/**Macro*********************************************************************** + + Synopsis [Returns the regular version of a pointer.] + + Description [] + + SideEffects [none] + + SeeAlso [Cudd_Complement Cudd_IsComplement] + +******************************************************************************/ +#define Cudd_Regular(node) ((DdNode *)((unsigned long)(node) & ~01)) + + +/**Macro*********************************************************************** + + Synopsis [Returns the complemented version of a pointer.] + + Description [] + + SideEffects [none] + + SeeAlso [Cudd_Regular Cudd_IsComplement] + +******************************************************************************/ +#define Cudd_Complement(node) ((DdNode *)((unsigned long)(node) | 01)) + + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if a pointer is complemented.] + + Description [] + + SideEffects [none] + + SeeAlso [Cudd_Regular Cudd_Complement] + +******************************************************************************/ +#define Cudd_IsComplement(node) ((int) ((long) (node) & 01)) + + +/**Macro*********************************************************************** + + Synopsis [Returns the then child of an internal node.] + + Description [Returns the then child of an internal node. If + node is a constant node, the result is unpredictable.] + + SideEffects [none] + + SeeAlso [Cudd_E Cudd_V] + +******************************************************************************/ +#define Cudd_T(node) ((Cudd_Regular(node))->type.kids.T) + + +/**Macro*********************************************************************** + + Synopsis [Returns the else child of an internal node.] + + Description [Returns the else child of an internal node. If + node is a constant node, the result is unpredictable.] + + SideEffects [none] + + SeeAlso [Cudd_T Cudd_V] + +******************************************************************************/ +#define Cudd_E(node) ((Cudd_Regular(node))->type.kids.E) + + +/**Macro*********************************************************************** + + Synopsis [Returns the value of a constant node.] + + Description [Returns the value of a constant node. If + node is an internal node, the result is unpredictable.] + + SideEffects [none] + + SeeAlso [Cudd_T Cudd_E] + +******************************************************************************/ +#define Cudd_V(node) ((Cudd_Regular(node))->type.value) + + +/**Macro*********************************************************************** + + Synopsis [Returns the current position in the order of variable + index.] + + Description [Returns the current position in the order of variable + index. This macro is obsolete and is kept for compatibility. New + applications should use Cudd_ReadPerm instead.] + + SideEffects [none] + + SeeAlso [Cudd_ReadPerm] + +******************************************************************************/ +#define Cudd_ReadIndex(dd,index) (Cudd_ReadPerm(dd,index)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the cubes of a decision diagram.] + + Description [Iterates over the cubes of a decision diagram f. +
            +
          • DdManager *manager; +
          • DdNode *f; +
          • DdGen *gen; +
          • int *cube; +
          • CUDD_VALUE_TYPE value; +
          + Cudd_ForeachCube allocates and frees the generator. Therefore the + application should not try to do that. Also, the cube is freed at the + end of Cudd_ForeachCube and hence is not available outside of the loop.

          + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_GenFree + Cudd_IsGenEmpty Cudd_AutodynDisable] + +******************************************************************************/ +#define Cudd_ForeachCube(manager, f, gen, cube, value)\ + for((gen) = Cudd_FirstCube(manager, f, &cube, &value);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : CUDD_TRUE;\ + (void) Cudd_NextCube(gen, &cube, &value)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the primes of a Boolean function.] + + Description [Iterates over the primes of a Boolean function producing + a prime and irredundant cover. +

            +
          • DdManager *manager; +
          • DdNode *l; +
          • DdNode *u; +
          • DdGen *gen; +
          • int *cube; +
          + The Boolean function is described by an upper bound and a lower bound. If + the function is completely specified, the two bounds coincide. + Cudd_ForeachPrime allocates and frees the generator. Therefore the + application should not try to do that. Also, the cube is freed at the + end of Cudd_ForeachPrime and hence is not available outside of the loop.

          + CAUTION: It is a mistake to change a diagram on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_ForeachCube Cudd_FirstPrime Cudd_NextPrime Cudd_GenFree + Cudd_IsGenEmpty] + +******************************************************************************/ +#define Cudd_ForeachPrime(manager, l, u, gen, cube)\ + for((gen) = Cudd_FirstPrime(manager, l, u, &cube);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : CUDD_TRUE;\ + (void) Cudd_NextPrime(gen, &cube)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the nodes of a decision diagram.] + + Description [Iterates over the nodes of a decision diagram f. +

            +
          • DdManager *manager; +
          • DdNode *f; +
          • DdGen *gen; +
          • DdNode *node; +
          + The nodes are returned in a seemingly random order. + Cudd_ForeachNode allocates and frees the generator. Therefore the + application should not try to do that.

          + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_ForeachCube Cudd_FirstNode Cudd_NextNode Cudd_GenFree + Cudd_IsGenEmpty Cudd_AutodynDisable] + +******************************************************************************/ +#define Cudd_ForeachNode(manager, f, gen, node)\ + for((gen) = Cudd_FirstNode(manager, f, &node);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : CUDD_TRUE;\ + (void) Cudd_NextNode(gen, &node)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the paths of a ZDD.] + + Description [Iterates over the paths of a ZDD f. +

            +
          • DdManager *manager; +
          • DdNode *f; +
          • DdGen *gen; +
          • int *path; +
          + Cudd_zddForeachPath allocates and frees the generator. Therefore the + application should not try to do that. Also, the path is freed at the + end of Cudd_zddForeachPath and hence is not available outside of the loop.

          + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_zddFirstPath Cudd_zddNextPath Cudd_GenFree + Cudd_IsGenEmpty Cudd_AutodynDisable] + +******************************************************************************/ +#define Cudd_zddForeachPath(manager, f, gen, path)\ + for((gen) = Cudd_zddFirstPath(manager, f, &path);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : CUDD_TRUE;\ + (void) Cudd_zddNextPath(gen, &path)) + + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern DdNode * Cudd_addNewVar (DdManager *dd); +extern DdNode * Cudd_addNewVarAtLevel (DdManager *dd, int level); +extern DdNode * Cudd_bddNewVar (DdManager *dd); +extern DdNode * Cudd_bddNewVarAtLevel (DdManager *dd, int level); +extern DdNode * Cudd_addIthVar (DdManager *dd, int i); +extern DdNode * Cudd_bddIthVar (DdManager *dd, int i); +extern DdNode * Cudd_zddIthVar (DdManager *dd, int i); +extern int Cudd_zddVarsFromBddVars (DdManager *dd, int multiplicity); +extern DdNode * Cudd_addConst (DdManager *dd, CUDD_VALUE_TYPE c); +extern int Cudd_IsNonConstant (DdNode *f); +extern unsigned long Cudd_ReadStartTime(DdManager *unique); +extern unsigned long Cudd_ReadElapsedTime(DdManager *unique); +extern void Cudd_SetStartTime(DdManager *unique, unsigned long st); +extern void Cudd_ResetStartTime(DdManager *unique); +extern unsigned long Cudd_ReadTimeLimit(DdManager *unique); +extern void Cudd_SetTimeLimit(DdManager *unique, unsigned long tl); +extern void Cudd_UpdateTimeLimit(DdManager * unique); +extern void Cudd_IncreaseTimeLimit(DdManager * unique, unsigned long increase); +extern void Cudd_UnsetTimeLimit(DdManager *unique); +extern int Cudd_TimeLimited(DdManager *unique); +extern void Cudd_AutodynEnable (DdManager *unique, Cudd_ReorderingType method); +extern void Cudd_AutodynDisable (DdManager *unique); +extern int Cudd_ReorderingStatus (DdManager *unique, Cudd_ReorderingType *method); +extern void Cudd_AutodynEnableZdd (DdManager *unique, Cudd_ReorderingType method); +extern void Cudd_AutodynDisableZdd (DdManager *unique); +extern int Cudd_ReorderingStatusZdd (DdManager *unique, Cudd_ReorderingType *method); +extern int Cudd_zddRealignmentEnabled (DdManager *unique); +extern void Cudd_zddRealignEnable (DdManager *unique); +extern void Cudd_zddRealignDisable (DdManager *unique); +extern int Cudd_bddRealignmentEnabled (DdManager *unique); +extern void Cudd_bddRealignEnable (DdManager *unique); +extern void Cudd_bddRealignDisable (DdManager *unique); +extern DdNode * Cudd_ReadOne (DdManager *dd); +extern DdNode * Cudd_ReadZddOne (DdManager *dd, int i); +extern DdNode * Cudd_ReadZero (DdManager *dd); +extern DdNode * Cudd_ReadLogicZero (DdManager *dd); +extern DdNode * Cudd_ReadPlusInfinity (DdManager *dd); +extern DdNode * Cudd_ReadMinusInfinity (DdManager *dd); +extern DdNode * Cudd_ReadBackground (DdManager *dd); +extern void Cudd_SetBackground (DdManager *dd, DdNode *bck); +extern unsigned int Cudd_ReadCacheSlots (DdManager *dd); +extern double Cudd_ReadCacheUsedSlots (DdManager * dd); +extern double Cudd_ReadCacheLookUps (DdManager *dd); +extern double Cudd_ReadCacheHits (DdManager *dd); +extern double Cudd_ReadRecursiveCalls (DdManager * dd); +extern unsigned int Cudd_ReadMinHit (DdManager *dd); +extern void Cudd_SetMinHit (DdManager *dd, unsigned int hr); +extern unsigned int Cudd_ReadLooseUpTo (DdManager *dd); +extern void Cudd_SetLooseUpTo (DdManager *dd, unsigned int lut); +extern unsigned int Cudd_ReadMaxCache (DdManager *dd); +extern unsigned int Cudd_ReadMaxCacheHard (DdManager *dd); +extern void Cudd_SetMaxCacheHard (DdManager *dd, unsigned int mc); +extern int Cudd_ReadSize (DdManager *dd); +extern int Cudd_ReadZddSize (DdManager *dd); +extern unsigned int Cudd_ReadSlots (DdManager *dd); +extern double Cudd_ReadUsedSlots (DdManager * dd); +extern double Cudd_ExpectedUsedSlots (DdManager * dd); +extern unsigned int Cudd_ReadKeys (DdManager *dd); +extern unsigned int Cudd_ReadDead (DdManager *dd); +extern unsigned int Cudd_ReadMinDead (DdManager *dd); +extern unsigned int Cudd_ReadReorderings (DdManager *dd); +extern unsigned int Cudd_ReadMaxReorderings (DdManager *dd); +extern void Cudd_SetMaxReorderings (DdManager *dd, unsigned int mr); +extern long Cudd_ReadReorderingTime (DdManager * dd); +extern int Cudd_ReadGarbageCollections (DdManager * dd); +extern long Cudd_ReadGarbageCollectionTime (DdManager * dd); +extern double Cudd_ReadNodesFreed (DdManager * dd); +extern double Cudd_ReadNodesDropped (DdManager * dd); +extern double Cudd_ReadUniqueLookUps (DdManager * dd); +extern double Cudd_ReadUniqueLinks (DdManager * dd); +extern int Cudd_ReadSiftMaxVar (DdManager *dd); +extern void Cudd_SetSiftMaxVar (DdManager *dd, int smv); +extern int Cudd_ReadSiftMaxSwap (DdManager *dd); +extern void Cudd_SetSiftMaxSwap (DdManager *dd, int sms); +extern double Cudd_ReadMaxGrowth (DdManager *dd); +extern void Cudd_SetMaxGrowth (DdManager *dd, double mg); +extern double Cudd_ReadMaxGrowthAlternate (DdManager * dd); +extern void Cudd_SetMaxGrowthAlternate (DdManager * dd, double mg); +extern int Cudd_ReadReorderingCycle (DdManager * dd); +extern void Cudd_SetReorderingCycle (DdManager * dd, int cycle); +extern MtrNode * Cudd_ReadTree (DdManager *dd); +extern void Cudd_SetTree (DdManager *dd, MtrNode *tree); +extern void Cudd_FreeTree (DdManager *dd); +extern MtrNode * Cudd_ReadZddTree (DdManager *dd); +extern void Cudd_SetZddTree (DdManager *dd, MtrNode *tree); +extern void Cudd_FreeZddTree (DdManager *dd); +extern unsigned int Cudd_NodeReadIndex (DdNode *node); +extern int Cudd_ReadPerm (DdManager *dd, int i); +extern int Cudd_ReadPermZdd (DdManager *dd, int i); +extern int Cudd_ReadInvPerm (DdManager *dd, int i); +extern int Cudd_ReadInvPermZdd (DdManager *dd, int i); +extern DdNode * Cudd_ReadVars (DdManager *dd, int i); +extern CUDD_VALUE_TYPE Cudd_ReadEpsilon (DdManager *dd); +extern void Cudd_SetEpsilon (DdManager *dd, CUDD_VALUE_TYPE ep); +extern Cudd_AggregationType Cudd_ReadGroupcheck (DdManager *dd); +extern void Cudd_SetGroupcheck (DdManager *dd, Cudd_AggregationType gc); +extern int Cudd_GarbageCollectionEnabled (DdManager *dd); +extern void Cudd_EnableGarbageCollection (DdManager *dd); +extern void Cudd_DisableGarbageCollection (DdManager *dd); +extern int Cudd_DeadAreCounted (DdManager *dd); +extern void Cudd_TurnOnCountDead (DdManager *dd); +extern void Cudd_TurnOffCountDead (DdManager *dd); +extern int Cudd_ReadRecomb (DdManager *dd); +extern void Cudd_SetRecomb (DdManager *dd, int recomb); +extern int Cudd_ReadSymmviolation (DdManager *dd); +extern void Cudd_SetSymmviolation (DdManager *dd, int symmviolation); +extern int Cudd_ReadArcviolation (DdManager *dd); +extern void Cudd_SetArcviolation (DdManager *dd, int arcviolation); +extern int Cudd_ReadPopulationSize (DdManager *dd); +extern void Cudd_SetPopulationSize (DdManager *dd, int populationSize); +extern int Cudd_ReadNumberXovers (DdManager *dd); +extern void Cudd_SetNumberXovers (DdManager *dd, int numberXovers); +extern unsigned int Cudd_ReadOrderRandomization(DdManager * dd); +extern void Cudd_SetOrderRandomization(DdManager * dd, unsigned int factor); +extern unsigned long Cudd_ReadMemoryInUse (DdManager *dd); +extern int Cudd_PrintInfo (DdManager *dd, FILE *fp); +extern long Cudd_ReadPeakNodeCount (DdManager *dd); +extern int Cudd_ReadPeakLiveNodeCount (DdManager * dd); +extern long Cudd_ReadNodeCount (DdManager *dd); +extern long Cudd_zddReadNodeCount (DdManager *dd); +extern int Cudd_AddHook (DdManager *dd, DD_HFP f, Cudd_HookType where); +extern int Cudd_RemoveHook (DdManager *dd, DD_HFP f, Cudd_HookType where); +extern int Cudd_IsInHook (DdManager * dd, DD_HFP f, Cudd_HookType where); +extern int Cudd_StdPreReordHook (DdManager *dd, const char *str, void *data); +extern int Cudd_StdPostReordHook (DdManager *dd, const char *str, void *data); +extern int Cudd_EnableReorderingReporting (DdManager *dd); +extern int Cudd_DisableReorderingReporting (DdManager *dd); +extern int Cudd_ReorderingReporting (DdManager *dd); +extern int Cudd_PrintGroupedOrder(DdManager * dd, const char *str, void *data); +extern int Cudd_EnableOrderingMonitoring(DdManager *dd); +extern int Cudd_DisableOrderingMonitoring(DdManager *dd); +extern int Cudd_OrderingMonitoring(DdManager *dd); +extern Cudd_ErrorType Cudd_ReadErrorCode (DdManager *dd); +extern void Cudd_ClearErrorCode (DdManager *dd); +extern FILE * Cudd_ReadStdout (DdManager *dd); +extern void Cudd_SetStdout (DdManager *dd, FILE *fp); +extern FILE * Cudd_ReadStderr (DdManager *dd); +extern void Cudd_SetStderr (DdManager *dd, FILE *fp); +extern unsigned int Cudd_ReadNextReordering (DdManager *dd); +extern void Cudd_SetNextReordering (DdManager *dd, unsigned int next); +extern double Cudd_ReadSwapSteps (DdManager *dd); +extern unsigned int Cudd_ReadMaxLive (DdManager *dd); +extern void Cudd_SetMaxLive (DdManager *dd, unsigned int maxLive); +extern unsigned long Cudd_ReadMaxMemory (DdManager *dd); +extern void Cudd_SetMaxMemory (DdManager *dd, unsigned long maxMemory); +extern int Cudd_bddBindVar (DdManager *dd, int index); +extern int Cudd_bddUnbindVar (DdManager *dd, int index); +extern int Cudd_bddVarIsBound (DdManager *dd, int index); +extern DdNode * Cudd_addExistAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_addUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_addOrAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_addApply (DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g); +extern DdNode * Cudd_addPlus (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addTimes (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addThreshold (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addSetNZ (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addDivide (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addMinus (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addMinimum (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addMaximum (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addOneZeroMaximum (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addDiff (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addAgreement (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addOr (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addNand (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addNor (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addXor (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addXnor (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addNotEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addGreaterThan (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addGreaterThanEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addLessThan (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addLessThanEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addMonadicApply (DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f); +extern DdNode * Cudd_addLog (DdManager * dd, DdNode * f); +extern DdNode * Cudd_addEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addNotEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addGreaterThan (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addGreaterThanEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addLessThan (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addLessThanEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addFindMax (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addFindMin (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addIthBit (DdManager *dd, DdNode *f, int bit); +extern DdNode * Cudd_addScalarInverse (DdManager *dd, DdNode *f, DdNode *epsilon); +extern DdNode * Cudd_addIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * Cudd_addIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * Cudd_addEvalConst (DdManager *dd, DdNode *f, DdNode *g); +extern int Cudd_addLeq (DdManager * dd, DdNode * f, DdNode * g); +extern DdNode * Cudd_addCmpl (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addNegate (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addRoundOff (DdManager *dd, DdNode *f, int N); +extern DdNode * Cudd_addWalsh (DdManager *dd, DdNode **x, DdNode **y, int n); +extern DdNode * Cudd_addResidue (DdManager *dd, int n, int m, int options, int top); +extern DdNode * Cudd_bddAndAbstract (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube); +extern DdNode * Cudd_bddAndAbstractLimit (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, unsigned int limit); +extern int Cudd_ApaNumberOfDigits (int binaryDigits); +extern DdApaNumber Cudd_NewApaNumber (int digits); +extern void Cudd_ApaCopy (int digits, DdApaNumber source, DdApaNumber dest); +extern DdApaDigit Cudd_ApaAdd (int digits, DdApaNumber a, DdApaNumber b, DdApaNumber sum); +extern DdApaDigit Cudd_ApaSubtract (int digits, DdApaNumber a, DdApaNumber b, DdApaNumber diff); +extern DdApaDigit Cudd_ApaShortDivision (int digits, DdApaNumber dividend, DdApaDigit divisor, DdApaNumber quotient); +extern unsigned int Cudd_ApaIntDivision (int digits, DdApaNumber dividend, unsigned int divisor, DdApaNumber quotient); +extern void Cudd_ApaShiftRight (int digits, DdApaDigit in, DdApaNumber a, DdApaNumber b); +extern void Cudd_ApaSetToLiteral (int digits, DdApaNumber number, DdApaDigit literal); +extern void Cudd_ApaPowerOfTwo (int digits, DdApaNumber number, int power); +extern int Cudd_ApaCompare (int digitsFirst, DdApaNumber first, int digitsSecond, DdApaNumber second); +extern int Cudd_ApaCompareRatios (int digitsFirst, DdApaNumber firstNum, unsigned int firstDen, int digitsSecond, DdApaNumber secondNum, unsigned int secondDen); +extern int Cudd_ApaPrintHex (FILE *fp, int digits, DdApaNumber number); +extern int Cudd_ApaPrintDecimal (FILE *fp, int digits, DdApaNumber number); +extern int Cudd_ApaPrintExponential (FILE * fp, int digits, DdApaNumber number, int precision); +extern DdApaNumber Cudd_ApaCountMinterm (DdManager *manager, DdNode *node, int nvars, int *digits); +extern int Cudd_ApaPrintMinterm (FILE *fp, DdManager *dd, DdNode *node, int nvars); +extern int Cudd_ApaPrintMintermExp (FILE * fp, DdManager * dd, DdNode * node, int nvars, int precision); +extern int Cudd_ApaPrintDensity (FILE * fp, DdManager * dd, DdNode * node, int nvars); +extern DdNode * Cudd_UnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality); +extern DdNode * Cudd_OverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality); +extern DdNode * Cudd_RemapUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality); +extern DdNode * Cudd_RemapOverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality); +extern DdNode * Cudd_BiasedUnderApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0); +extern DdNode * Cudd_BiasedOverApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0); +extern DdNode * Cudd_bddExistAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_bddExistAbstractLimit(DdManager * manager, DdNode * f, DdNode * cube, unsigned int limit); +extern DdNode * Cudd_bddXorExistAbstract (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube); +extern DdNode * Cudd_bddUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_bddBooleanDiff (DdManager *manager, DdNode *f, int x); +extern int Cudd_bddVarIsDependent (DdManager *dd, DdNode *f, DdNode *var); +extern double Cudd_bddCorrelation (DdManager *manager, DdNode *f, DdNode *g); +extern double Cudd_bddCorrelationWeights (DdManager *manager, DdNode *f, DdNode *g, double *prob); +extern DdNode * Cudd_bddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); + extern DdNode * Cudd_bddIteLimit (DdManager *dd, DdNode *f, DdNode *g, DdNode *h, unsigned int limit); +extern DdNode * Cudd_bddIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * Cudd_bddIntersect (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddAnd (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddAndLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); +extern DdNode * Cudd_bddOr (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddOrLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); +extern DdNode * Cudd_bddNand (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddNor (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddXor (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddXnor (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddXnorLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); +extern int Cudd_bddLeq (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_addBddThreshold (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value); +extern DdNode * Cudd_addBddStrictThreshold (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value); +extern DdNode * Cudd_addBddInterval (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper); +extern DdNode * Cudd_addBddIthBit (DdManager *dd, DdNode *f, int bit); +extern DdNode * Cudd_BddToAdd (DdManager *dd, DdNode *B); +extern DdNode * Cudd_addBddPattern (DdManager *dd, DdNode *f); +extern DdNode * Cudd_bddTransfer (DdManager *ddSource, DdManager *ddDestination, DdNode *f); +extern int Cudd_DebugCheck (DdManager *table); +extern int Cudd_CheckKeys (DdManager *table); +extern DdNode * Cudd_bddClippingAnd (DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction); +extern DdNode * Cudd_bddClippingAndAbstract (DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction); +extern DdNode * Cudd_Cofactor (DdManager *dd, DdNode *f, DdNode *g); +extern int Cudd_CheckCube (DdManager *dd, DdNode *g); +extern DdNode * Cudd_bddCompose (DdManager *dd, DdNode *f, DdNode *g, int v); +extern DdNode * Cudd_addCompose (DdManager *dd, DdNode *f, DdNode *g, int v); +extern DdNode * Cudd_addPermute (DdManager *manager, DdNode *node, int *permut); +extern DdNode * Cudd_addSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n); +extern DdNode * Cudd_bddPermute (DdManager *manager, DdNode *node, int *permut); +extern DdNode * Cudd_bddVarMap (DdManager *manager, DdNode *f); +extern int Cudd_SetVarMap (DdManager *manager, DdNode **x, DdNode **y, int n); +extern DdNode * Cudd_bddSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n); +extern DdNode * Cudd_bddAdjPermuteX (DdManager *dd, DdNode *B, DdNode **x, int n); +extern DdNode * Cudd_addVectorCompose (DdManager *dd, DdNode *f, DdNode **vector); +extern DdNode * Cudd_addGeneralVectorCompose (DdManager *dd, DdNode *f, DdNode **vectorOn, DdNode **vectorOff); +extern DdNode * Cudd_addNonSimCompose (DdManager *dd, DdNode *f, DdNode **vector); +extern DdNode * Cudd_bddVectorCompose (DdManager *dd, DdNode *f, DdNode **vector); +extern int Cudd_bddApproxConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts); +extern int Cudd_bddApproxDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts); +extern int Cudd_bddIterConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts); +extern int Cudd_bddIterDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts); +extern int Cudd_bddGenConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts); +extern int Cudd_bddGenDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts); +extern int Cudd_bddVarConjDecomp (DdManager *dd, DdNode * f, DdNode ***conjuncts); +extern int Cudd_bddVarDisjDecomp (DdManager *dd, DdNode * f, DdNode ***disjuncts); +extern DdNode * Cudd_FindEssential (DdManager *dd, DdNode *f); +extern int Cudd_bddIsVarEssential (DdManager *manager, DdNode *f, int id, int phase); +extern DdTlcInfo * Cudd_FindTwoLiteralClauses (DdManager * dd, DdNode * f); +extern int Cudd_PrintTwoLiteralClauses (DdManager * dd, DdNode * f, char **names, FILE *fp); +extern int Cudd_ReadIthClause (DdTlcInfo * tlc, int i, DdHalfWord *var1, DdHalfWord *var2, int *phase1, int *phase2); +extern void Cudd_tlcInfoFree (DdTlcInfo * t); +extern int Cudd_DumpBlif (DdManager *dd, int n, DdNode **f, char **inames, char **onames, char *mname, FILE *fp, int mv); +extern int Cudd_DumpBlifBody (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp, int mv); +extern int Cudd_DumpDot (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern int Cudd_DumpDaVinci (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern int Cudd_DumpDDcal (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern int Cudd_DumpFactoredForm (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern DdNode * Cudd_bddConstrain (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_bddRestrict (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_bddNPAnd (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_addConstrain (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode ** Cudd_bddConstrainDecomp (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addRestrict (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode ** Cudd_bddCharToVect (DdManager *dd, DdNode *f); +extern DdNode * Cudd_bddLICompaction (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_bddSqueeze (DdManager *dd, DdNode *l, DdNode *u); +extern DdNode * Cudd_bddMinimize (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_SubsetCompress (DdManager *dd, DdNode *f, int nvars, int threshold); +extern DdNode * Cudd_SupersetCompress (DdManager *dd, DdNode *f, int nvars, int threshold); +extern MtrNode * Cudd_MakeTreeNode (DdManager *dd, unsigned int low, unsigned int size, unsigned int type); +extern int Cudd_addHarwell (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, DdNode ***xn, DdNode ***yn_, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy, int pr); +extern DdManager * Cudd_Init (unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory); +extern void Cudd_Quit (DdManager *unique); +extern int Cudd_PrintLinear (DdManager *table); +extern int Cudd_ReadLinear (DdManager *table, int x, int y); +extern DdNode * Cudd_bddLiteralSetIntersection (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_addMatrixMultiply (DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz); +extern DdNode * Cudd_addTimesPlus (DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz); +extern DdNode * Cudd_addTriangle (DdManager *dd, DdNode *f, DdNode *g, DdNode **z, int nz); +extern DdNode * Cudd_addOuterSum (DdManager *dd, DdNode *M, DdNode *r, DdNode *c); +extern DdNode * Cudd_PrioritySelect (DdManager *dd, DdNode *R, DdNode **x, DdNode **y, DdNode **z, DdNode *Pi, int n, DdNode * (*)(DdManager *, int, DdNode **, DdNode **, DdNode **)); +extern DdNode * Cudd_Xgty (DdManager *dd, int N, DdNode **z, DdNode **x, DdNode **y); +extern DdNode * Cudd_Xeqy (DdManager *dd, int N, DdNode **x, DdNode **y); +extern DdNode * Cudd_addXeqy (DdManager *dd, int N, DdNode **x, DdNode **y); +extern DdNode * Cudd_Dxygtdxz (DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z); +extern DdNode * Cudd_Dxygtdyz (DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z); +extern DdNode * Cudd_Inequality (DdManager * dd, int N, int c, DdNode ** x, DdNode ** y); +extern DdNode * Cudd_Disequality (DdManager * dd, int N, int c, DdNode ** x, DdNode ** y); +extern DdNode * Cudd_bddInterval (DdManager * dd, int N, DdNode ** x, unsigned int lowerB, unsigned int upperB); +extern DdNode * Cudd_CProjection (DdManager *dd, DdNode *R, DdNode *Y); +extern DdNode * Cudd_addHamming (DdManager *dd, DdNode **xVars, DdNode **yVars, int nVars); +extern int Cudd_MinHammingDist (DdManager *dd, DdNode *f, int *minterm, int upperBound); +extern DdNode * Cudd_bddClosestCube (DdManager *dd, DdNode * f, DdNode *g, int *distance); +extern int Cudd_addRead (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, DdNode ***xn, DdNode ***yn_, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy); +extern int Cudd_bddRead (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy); +extern void Cudd_Ref (DdNode *n); +extern void Cudd_RecursiveDeref (DdManager *table, DdNode *n); +extern void Cudd_IterDerefBdd (DdManager *table, DdNode *n); +extern void Cudd_DelayedDerefBdd (DdManager * table, DdNode * n); +extern void Cudd_RecursiveDerefZdd (DdManager *table, DdNode *n); +extern void Cudd_Deref (DdNode *node); +extern int Cudd_CheckZeroRef (DdManager *manager); +extern int Cudd_ReduceHeap (DdManager *table, Cudd_ReorderingType heuristic, int minsize); +extern int Cudd_ShuffleHeap (DdManager *table, int *permutation); +extern DdNode * Cudd_Eval (DdManager *dd, DdNode *f, int *inputs); +extern DdNode * Cudd_ShortestPath (DdManager *manager, DdNode *f, int *weight, int *support, int *length); +extern DdNode * Cudd_LargestCube (DdManager *manager, DdNode *f, int *length); +extern int Cudd_ShortestLength (DdManager *manager, DdNode *f, int *weight); +extern DdNode * Cudd_Decreasing (DdManager *dd, DdNode *f, int i); +extern DdNode * Cudd_Increasing (DdManager *dd, DdNode *f, int i); +extern int Cudd_EquivDC (DdManager *dd, DdNode *F, DdNode *G, DdNode *D); +extern int Cudd_bddLeqUnless (DdManager *dd, DdNode *f, DdNode *g, DdNode *D); +extern int Cudd_EqualSupNorm (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr); +extern DdNode * Cudd_bddMakePrime (DdManager *dd, DdNode *cube, DdNode *f); +extern DdNode * Cudd_bddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f); +extern DdNode * Cudd_bddLargestPrimeUnate(DdManager *dd , DdNode *f, DdNode *phaseBdd); +extern double * Cudd_CofMinterm (DdManager *dd, DdNode *node); +extern DdNode * Cudd_SolveEqn (DdManager * bdd, DdNode *F, DdNode *Y, DdNode **G, int **yIndex, int n); +extern DdNode * Cudd_VerifySol (DdManager * bdd, DdNode *F, DdNode **G, int *yIndex, int n); +extern DdNode * Cudd_SplitSet (DdManager *manager, DdNode *S, DdNode **xVars, int n, double m); +extern DdNode * Cudd_SubsetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold); +extern DdNode * Cudd_SupersetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold); +extern DdNode * Cudd_SubsetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit); +extern DdNode * Cudd_SupersetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit); +extern void Cudd_SymmProfile (DdManager *table, int lower, int upper); +extern unsigned int Cudd_Prime (unsigned int p); +extern int Cudd_Reserve(DdManager *manager, int amount); +extern int Cudd_PrintMinterm (DdManager *manager, DdNode *node); +extern int Cudd_bddPrintCover (DdManager *dd, DdNode *l, DdNode *u); +extern int Cudd_PrintDebug (DdManager *dd, DdNode *f, int n, int pr); +extern int Cudd_DagSize (DdNode *node); +extern int Cudd_EstimateCofactor (DdManager *dd, DdNode * node, int i, int phase); +extern int Cudd_EstimateCofactorSimple (DdNode * node, int i); +extern int Cudd_SharingSize (DdNode **nodeArray, int n); +extern double Cudd_CountMinterm (DdManager *manager, DdNode *node, int nvars); +extern int Cudd_EpdCountMinterm (DdManager *manager, DdNode *node, int nvars, EpDouble *epd); +extern double Cudd_CountPath (DdNode *node); +extern double Cudd_CountPathsToNonZero (DdNode *node); +extern int Cudd_SupportIndices(DdManager * dd, DdNode * f, int **indices); +extern DdNode * Cudd_Support (DdManager *dd, DdNode *f); +extern int * Cudd_SupportIndex (DdManager *dd, DdNode *f); +extern int Cudd_SupportSize (DdManager *dd, DdNode *f); +extern int Cudd_VectorSupportIndices(DdManager * dd, DdNode ** F, int n, int **indices); +extern DdNode * Cudd_VectorSupport (DdManager *dd, DdNode **F, int n); +extern int * Cudd_VectorSupportIndex (DdManager *dd, DdNode **F, int n); +extern int Cudd_VectorSupportSize (DdManager *dd, DdNode **F, int n); +extern int Cudd_ClassifySupport (DdManager *dd, DdNode *f, DdNode *g, DdNode **common, DdNode **onlyF, DdNode **onlyG); +extern int Cudd_CountLeaves (DdNode *node); +extern int Cudd_bddPickOneCube (DdManager *ddm, DdNode *node, char *string); +extern DdNode * Cudd_bddPickOneMinterm (DdManager *dd, DdNode *f, DdNode **vars, int n); +extern DdNode ** Cudd_bddPickArbitraryMinterms (DdManager *dd, DdNode *f, DdNode **vars, int n, int k); +extern DdNode * Cudd_SubsetWithMaskVars (DdManager *dd, DdNode *f, DdNode **vars, int nvars, DdNode **maskVars, int mvars); +extern DdGen * Cudd_FirstCube (DdManager *dd, DdNode *f, int **cube, CUDD_VALUE_TYPE *value); +extern int Cudd_NextCube (DdGen *gen, int **cube, CUDD_VALUE_TYPE *value); +extern DdGen * Cudd_FirstPrime(DdManager *dd, DdNode *l, DdNode *u, int **cube); +extern int Cudd_NextPrime(DdGen *gen, int **cube); +extern DdNode * Cudd_bddComputeCube (DdManager *dd, DdNode **vars, int *phase, int n); +extern DdNode * Cudd_addComputeCube (DdManager *dd, DdNode **vars, int *phase, int n); +extern DdNode * Cudd_CubeArrayToBdd (DdManager *dd, int *array); +extern int Cudd_BddToCubeArray (DdManager *dd, DdNode *cube, int *array); +extern DdGen * Cudd_FirstNode (DdManager *dd, DdNode *f, DdNode **node); +extern int Cudd_NextNode (DdGen *gen, DdNode **node); +extern int Cudd_GenFree (DdGen *gen); +extern int Cudd_IsGenEmpty (DdGen *gen); +extern DdNode * Cudd_IndicesToCube (DdManager *dd, int *array, int n); +extern void Cudd_PrintVersion (FILE *fp); +extern double Cudd_AverageDistance (DdManager *dd); +extern long Cudd_Random (void); +extern void Cudd_Srandom (long seed); +extern double Cudd_Density (DdManager *dd, DdNode *f, int nvars); +extern void Cudd_OutOfMem (long size); +extern int Cudd_zddCount (DdManager *zdd, DdNode *P); +extern double Cudd_zddCountDouble (DdManager *zdd, DdNode *P); +extern DdNode * Cudd_zddProduct (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddUnateProduct (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddWeakDiv (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddDivide (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddWeakDivF (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddDivideF (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddComplement (DdManager *dd, DdNode *node); +extern MtrNode * Cudd_MakeZddTreeNode (DdManager *dd, unsigned int low, unsigned int size, unsigned int type); +extern DdNode * Cudd_zddIsop (DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I); +extern DdNode * Cudd_bddIsop (DdManager *dd, DdNode *L, DdNode *U); +extern DdNode * Cudd_MakeBddFromZddCover (DdManager *dd, DdNode *node); +extern int Cudd_zddDagSize (DdNode *p_node); +extern double Cudd_zddCountMinterm (DdManager *zdd, DdNode *node, int path); +extern void Cudd_zddPrintSubtable (DdManager *table); +extern DdNode * Cudd_zddPortFromBdd (DdManager *dd, DdNode *B); +extern DdNode * Cudd_zddPortToBdd (DdManager *dd, DdNode *f); +extern int Cudd_zddReduceHeap (DdManager *table, Cudd_ReorderingType heuristic, int minsize); +extern int Cudd_zddShuffleHeap (DdManager *table, int *permutation); +extern DdNode * Cudd_zddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * Cudd_zddUnion (DdManager *dd, DdNode *P, DdNode *Q); +extern DdNode * Cudd_zddIntersect (DdManager *dd, DdNode *P, DdNode *Q); +extern DdNode * Cudd_zddDiff (DdManager *dd, DdNode *P, DdNode *Q); +extern DdNode * Cudd_zddDiffConst (DdManager *zdd, DdNode *P, DdNode *Q); +extern DdNode * Cudd_zddSubset1 (DdManager *dd, DdNode *P, int var); +extern DdNode * Cudd_zddSubset0 (DdManager *dd, DdNode *P, int var); +extern DdNode * Cudd_zddChange (DdManager *dd, DdNode *P, int var); +extern void Cudd_zddSymmProfile (DdManager *table, int lower, int upper); +extern int Cudd_zddPrintMinterm (DdManager *zdd, DdNode *node); +extern int Cudd_zddPrintCover (DdManager *zdd, DdNode *node); +extern int Cudd_zddPrintDebug (DdManager *zdd, DdNode *f, int n, int pr); +extern DdGen * Cudd_zddFirstPath (DdManager *zdd, DdNode *f, int **path); +extern int Cudd_zddNextPath (DdGen *gen, int **path); +extern char * Cudd_zddCoverPathToString (DdManager *zdd, int *path, char *str); +extern DdNode * Cudd_zddSupport(DdManager * dd, DdNode * f); +extern int Cudd_zddDumpDot (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern int Cudd_bddSetPiVar (DdManager *dd, int index); +extern int Cudd_bddSetPsVar (DdManager *dd, int index); +extern int Cudd_bddSetNsVar (DdManager *dd, int index); +extern int Cudd_bddIsPiVar (DdManager *dd, int index); +extern int Cudd_bddIsPsVar (DdManager *dd, int index); +extern int Cudd_bddIsNsVar (DdManager *dd, int index); +extern int Cudd_bddSetPairIndex (DdManager *dd, int index, int pairIndex); +extern int Cudd_bddReadPairIndex (DdManager *dd, int index); +extern int Cudd_bddSetVarToBeGrouped (DdManager *dd, int index); +extern int Cudd_bddSetVarHardGroup (DdManager *dd, int index); +extern int Cudd_bddResetVarToBeGrouped (DdManager *dd, int index); +extern int Cudd_bddIsVarToBeGrouped (DdManager *dd, int index); +extern int Cudd_bddSetVarToBeUngrouped (DdManager *dd, int index); +extern int Cudd_bddIsVarToBeUngrouped (DdManager *dd, int index); +extern int Cudd_bddIsVarHardGroup (DdManager *dd, int index); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _CUDD */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAPI.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAPI.c new file mode 100644 index 000000000..0985cf13d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAPI.c @@ -0,0 +1,4893 @@ +/**CFile*********************************************************************** + + FileName [cuddAPI.c] + + PackageName [cudd] + + Synopsis [Application interface functions.] + + Description [External procedures included in this module: +

            +
          • Cudd_addNewVar() +
          • Cudd_addNewVarAtLevel() +
          • Cudd_bddNewVar() +
          • Cudd_bddNewVarAtLevel() +
          • Cudd_addIthVar() +
          • Cudd_bddIthVar() +
          • Cudd_zddIthVar() +
          • Cudd_zddVarsFromBddVars() +
          • Cudd_addConst() +
          • Cudd_IsNonConstant() +
          • Cudd_ReadStartTime() +
          • Cudd_ReadElapsedTime() +
          • Cudd_SetStartTime() +
          • Cudd_ResetStartTime() +
          • Cudd_ReadTimeLimit() +
          • Cudd_SetTimeLimit() +
          • Cudd_UpdateTimeLimit() +
          • Cudd_IncreaseTimeLimit() +
          • Cudd_UnsetTimeLimit() +
          • Cudd_TimeLimited() +
          • Cudd_AutodynEnable() +
          • Cudd_AutodynDisable() +
          • Cudd_ReorderingStatus() +
          • Cudd_AutodynEnableZdd() +
          • Cudd_AutodynDisableZdd() +
          • Cudd_ReorderingStatusZdd() +
          • Cudd_zddRealignmentEnabled() +
          • Cudd_zddRealignEnable() +
          • Cudd_zddRealignDisable() +
          • Cudd_bddRealignmentEnabled() +
          • Cudd_bddRealignEnable() +
          • Cudd_bddRealignDisable() +
          • Cudd_ReadOne() +
          • Cudd_ReadZddOne() +
          • Cudd_ReadZero() +
          • Cudd_ReadLogicZero() +
          • Cudd_ReadPlusInfinity() +
          • Cudd_ReadMinusInfinity() +
          • Cudd_ReadBackground() +
          • Cudd_SetBackground() +
          • Cudd_ReadCacheSlots() +
          • Cudd_ReadCacheUsedSlots() +
          • Cudd_ReadCacheLookUps() +
          • Cudd_ReadCacheHits() +
          • Cudd_ReadMinHit() +
          • Cudd_SetMinHit() +
          • Cudd_ReadLooseUpTo() +
          • Cudd_SetLooseUpTo() +
          • Cudd_ReadMaxCache() +
          • Cudd_ReadMaxCacheHard() +
          • Cudd_SetMaxCacheHard() +
          • Cudd_ReadSize() +
          • Cudd_ReadSlots() +
          • Cudd_ReadUsedSlots() +
          • Cudd_ExpectedUsedSlots() +
          • Cudd_ReadKeys() +
          • Cudd_ReadDead() +
          • Cudd_ReadMinDead() +
          • Cudd_ReadReorderings() +
          • Cudd_ReadMaxReorderings() +
          • Cudd_SetMaxReorderings() +
          • Cudd_ReadReorderingTime() +
          • Cudd_ReadGarbageCollections() +
          • Cudd_ReadGarbageCollectionTime() +
          • Cudd_ReadNodesFreed() +
          • Cudd_ReadNodesDropped() +
          • Cudd_ReadUniqueLookUps() +
          • Cudd_ReadUniqueLinks() +
          • Cudd_ReadSiftMaxVar() +
          • Cudd_SetSiftMaxVar() +
          • Cudd_ReadMaxGrowth() +
          • Cudd_SetMaxGrowth() +
          • Cudd_ReadMaxGrowthAlternate() +
          • Cudd_SetMaxGrowthAlternate() +
          • Cudd_ReadReorderingCycle() +
          • Cudd_SetReorderingCycle() +
          • Cudd_ReadTree() +
          • Cudd_SetTree() +
          • Cudd_FreeTree() +
          • Cudd_ReadZddTree() +
          • Cudd_SetZddTree() +
          • Cudd_FreeZddTree() +
          • Cudd_NodeReadIndex() +
          • Cudd_ReadPerm() +
          • Cudd_ReadInvPerm() +
          • Cudd_ReadVars() +
          • Cudd_ReadEpsilon() +
          • Cudd_SetEpsilon() +
          • Cudd_ReadGroupCheck() +
          • Cudd_SetGroupcheck() +
          • Cudd_GarbageCollectionEnabled() +
          • Cudd_EnableGarbageCollection() +
          • Cudd_DisableGarbageCollection() +
          • Cudd_DeadAreCounted() +
          • Cudd_TurnOnCountDead() +
          • Cudd_TurnOffCountDead() +
          • Cudd_ReadRecomb() +
          • Cudd_SetRecomb() +
          • Cudd_ReadSymmviolation() +
          • Cudd_SetSymmviolation() +
          • Cudd_ReadArcviolation() +
          • Cudd_SetArcviolation() +
          • Cudd_ReadPopulationSize() +
          • Cudd_SetPopulationSize() +
          • Cudd_ReadNumberXovers() +
          • Cudd_SetNumberXovers() +
          • Cudd_ReadOrderRandomization() +
          • Cudd_SetOrderRandomization() +
          • Cudd_ReadMemoryInUse() +
          • Cudd_PrintInfo() +
          • Cudd_ReadPeakNodeCount() +
          • Cudd_ReadPeakLiveNodeCount() +
          • Cudd_ReadNodeCount() +
          • Cudd_zddReadNodeCount() +
          • Cudd_AddHook() +
          • Cudd_RemoveHook() +
          • Cudd_IsInHook() +
          • Cudd_StdPreReordHook() +
          • Cudd_StdPostReordHook() +
          • Cudd_EnableReorderingReporting() +
          • Cudd_DisableReorderingReporting() +
          • Cudd_ReorderingReporting() +
          • Cudd_PrintGroupedOrder() +
          • Cudd_EnableOrderingMonitoring() +
          • Cudd_DisableOrderingMonitoring() +
          • Cudd_OrderingMonitoring() +
          • Cudd_ReadErrorCode() +
          • Cudd_ClearErrorCode() +
          • Cudd_ReadStdout() +
          • Cudd_SetStdout() +
          • Cudd_ReadStderr() +
          • Cudd_SetStderr() +
          • Cudd_ReadNextReordering() +
          • Cudd_SetNextReordering() +
          • Cudd_ReadSwapSteps() +
          • Cudd_ReadMaxLive() +
          • Cudd_SetMaxLive() +
          • Cudd_ReadMaxMemory() +
          • Cudd_SetMaxMemory() +
          • Cudd_bddBindVar() +
          • Cudd_bddUnbindVar() +
          • Cudd_bddVarIsBound() +
          • Cudd_bddSetPiVar() +
          • Cudd_bddSetPsVar() +
          • Cudd_bddSetNsVar() +
          • Cudd_bddIsPiVar() +
          • Cudd_bddIsPsVar() +
          • Cudd_bddIsNsVar() +
          • Cudd_bddSetPairIndex() +
          • Cudd_bddReadPairIndex() +
          • Cudd_bddSetVarToBeGrouped() +
          • Cudd_bddSetVarHardGroup() +
          • Cudd_bddResetVarToBeGrouped() +
          • Cudd_bddIsVarToBeGrouped() +
          • Cudd_bddSetVarToBeUngrouped() +
          • Cudd_bddIsVarToBeUngrouped() +
          • Cudd_bddIsVarHardGroup() +
          + Static procedures included in this module: +
            +
          • fixVarTree() +
          ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAPI.c,v 1.64 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void fixVarTree (MtrNode *treenode, int *perm, int size); +static int addMultiplicityGroups (DdManager *dd, MtrNode *treenode, int multiplicity, char *vmask, char *lmask); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns a new ADD variable.] + + Description [Creates a new ADD variable. The new variable has an + index equal to the largest previous index plus 1. Returns a + pointer to the new variable if successful; NULL otherwise. + An ADD variable differs from a BDD variable because it points to the + arithmetic zero, instead of having a complement pointer to 1. ] + + SideEffects [None] + + SeeAlso [Cudd_bddNewVar Cudd_addIthVar Cudd_addConst + Cudd_addNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_addNewVar( + DdManager * dd) +{ + DdNode *res; + + if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); + do { + dd->reordered = 0; + res = cuddUniqueInter(dd,dd->size,DD_ONE(dd),DD_ZERO(dd)); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_addNewVar */ + + +/**Function******************************************************************** + + Synopsis [Returns a new ADD variable at a specified level.] + + Description [Creates a new ADD variable. The new variable has an + index equal to the largest previous index plus 1 and is positioned at + the specified level in the order. Returns a pointer to the new + variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_addNewVarAtLevel( + DdManager * dd, + int level) +{ + DdNode *res; + + if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); + if (level >= dd->size) return(Cudd_addIthVar(dd,level)); + if (!cuddInsertSubtables(dd,1,level)) return(NULL); + do { + dd->reordered = 0; + res = cuddUniqueInter(dd,dd->size - 1,DD_ONE(dd),DD_ZERO(dd)); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_addNewVarAtLevel */ + + +/**Function******************************************************************** + + Synopsis [Returns a new BDD variable.] + + Description [Creates a new BDD variable. The new variable has an + index equal to the largest previous index plus 1. Returns a + pointer to the new variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_bddNewVar( + DdManager * dd) +{ + DdNode *res; + + if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); + res = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); + + return(res); + +} /* end of Cudd_bddNewVar */ + + +/**Function******************************************************************** + + Synopsis [Returns a new BDD variable at a specified level.] + + Description [Creates a new BDD variable. The new variable has an + index equal to the largest previous index plus 1 and is positioned at + the specified level in the order. Returns a pointer to the new + variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNewVar Cudd_bddIthVar Cudd_addNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_bddNewVarAtLevel( + DdManager * dd, + int level) +{ + DdNode *res; + + if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); + if (level >= dd->size) return(Cudd_bddIthVar(dd,level)); + if (!cuddInsertSubtables(dd,1,level)) return(NULL); + res = dd->vars[dd->size - 1]; + + return(res); + +} /* end of Cudd_bddNewVarAtLevel */ + + +/**Function******************************************************************** + + Synopsis [Returns the ADD variable with index i.] + + Description [Retrieves the ADD variable with index i if it already + exists, or creates a new ADD variable. Returns a pointer to the + variable if successful; NULL otherwise. An ADD variable differs from + a BDD variable because it points to the arithmetic zero, instead of + having a complement pointer to 1. ] + + SideEffects [None] + + SeeAlso [Cudd_addNewVar Cudd_bddIthVar Cudd_addConst + Cudd_addNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_addIthVar( + DdManager * dd, + int i) +{ + DdNode *res; + + if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); + do { + dd->reordered = 0; + res = cuddUniqueInter(dd,i,DD_ONE(dd),DD_ZERO(dd)); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_addIthVar */ + + +/**Function******************************************************************** + + Synopsis [Returns the BDD variable with index i.] + + Description [Retrieves the BDD variable with index i if it already + exists, or creates a new BDD variable. Returns a pointer to the + variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel + Cudd_ReadVars] + +******************************************************************************/ +DdNode * +Cudd_bddIthVar( + DdManager * dd, + int i) +{ + DdNode *res; + + if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); + if (i < dd->size) { + res = dd->vars[i]; + } else { + res = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + } + + return(res); + +} /* end of Cudd_bddIthVar */ + + +/**Function******************************************************************** + + Synopsis [Returns the ZDD variable with index i.] + + Description [Retrieves the ZDD variable with index i if it already + exists, or creates a new ZDD variable. Returns a pointer to the + variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddIthVar Cudd_addIthVar] + +******************************************************************************/ +DdNode * +Cudd_zddIthVar( + DdManager * dd, + int i) +{ + DdNode *res; + DdNode *zvar; + DdNode *lower; + int j; + + if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); + + /* The i-th variable function has the following structure: + ** at the level corresponding to index i there is a node whose "then" + ** child points to the universe, and whose "else" child points to zero. + ** Above that level there are nodes with identical children. + */ + + /* First we build the node at the level of index i. */ + lower = (i < dd->sizeZ - 1) ? dd->univ[dd->permZ[i]+1] : DD_ONE(dd); + do { + dd->reordered = 0; + zvar = cuddUniqueInterZdd(dd, i, lower, DD_ZERO(dd)); + } while (dd->reordered == 1); + + if (zvar == NULL) + return(NULL); + cuddRef(zvar); + + /* Now we add the "filler" nodes above the level of index i. */ + for (j = dd->permZ[i] - 1; j >= 0; j--) { + do { + dd->reordered = 0; + res = cuddUniqueInterZdd(dd, dd->invpermZ[j], zvar, zvar); + } while (dd->reordered == 1); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd,zvar); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd,zvar); + zvar = res; + } + cuddDeref(zvar); + return(zvar); + +} /* end of Cudd_zddIthVar */ + + +/**Function******************************************************************** + + Synopsis [Creates one or more ZDD variables for each BDD variable.] + + Description [Creates one or more ZDD variables for each BDD + variable. If some ZDD variables already exist, only the missing + variables are created. Parameter multiplicity allows the caller to + control how many variables are created for each BDD variable in + existence. For instance, if ZDDs are used to represent covers, two + ZDD variables are required for each BDD variable. The order of the + BDD variables is transferred to the ZDD variables. If a variable + group tree exists for the BDD variables, a corresponding ZDD + variable group tree is created by expanding the BDD variable + tree. In any case, the ZDD variables derived from the same BDD + variable are merged in a ZDD variable group. If a ZDD variable group + tree exists, it is freed. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel] + +******************************************************************************/ +int +Cudd_zddVarsFromBddVars( + DdManager * dd /* DD manager */, + int multiplicity /* how many ZDD variables are created for each BDD variable */) +{ + int res; + int i, j; + int allnew; + int *permutation; + + if (multiplicity < 1) return(0); + allnew = dd->sizeZ == 0; + if (dd->size * multiplicity > dd->sizeZ) { + res = cuddResizeTableZdd(dd,dd->size * multiplicity - 1); + if (res == 0) return(0); + } + /* Impose the order of the BDD variables to the ZDD variables. */ + if (allnew) { + for (i = 0; i < dd->size; i++) { + for (j = 0; j < multiplicity; j++) { + dd->permZ[i * multiplicity + j] = + dd->perm[i] * multiplicity + j; + dd->invpermZ[dd->permZ[i * multiplicity + j]] = + i * multiplicity + j; + } + } + for (i = 0; i < dd->sizeZ; i++) { + dd->univ[i]->index = dd->invpermZ[i]; + } + } else { + permutation = ALLOC(int,dd->sizeZ); + if (permutation == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < dd->size; i++) { + for (j = 0; j < multiplicity; j++) { + permutation[i * multiplicity + j] = + dd->invperm[i] * multiplicity + j; + } + } + for (i = dd->size * multiplicity; i < dd->sizeZ; i++) { + permutation[i] = i; + } + res = Cudd_zddShuffleHeap(dd, permutation); + FREE(permutation); + if (res == 0) return(0); + } + /* Copy and expand the variable group tree if it exists. */ + if (dd->treeZ != NULL) { + Cudd_FreeZddTree(dd); + } + if (dd->tree != NULL) { + dd->treeZ = Mtr_CopyTree(dd->tree, multiplicity); + if (dd->treeZ == NULL) return(0); + } else if (multiplicity > 1) { + dd->treeZ = Mtr_InitGroupTree(0, dd->sizeZ); + if (dd->treeZ == NULL) return(0); + dd->treeZ->index = dd->invpermZ[0]; + } + /* Create groups for the ZDD variables derived from the same BDD variable. + */ + if (multiplicity > 1) { + char *vmask, *lmask; + + vmask = ALLOC(char, dd->size); + if (vmask == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + lmask = ALLOC(char, dd->size); + if (lmask == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < dd->size; i++) { + vmask[i] = lmask[i] = 0; + } + res = addMultiplicityGroups(dd,dd->treeZ,multiplicity,vmask,lmask); + FREE(vmask); + FREE(lmask); + if (res == 0) return(0); + } + return(1); + +} /* end of Cudd_zddVarsFromBddVars */ + + +/**Function******************************************************************** + + Synopsis [Returns the ADD for constant c.] + + Description [Retrieves the ADD for constant c if it already + exists, or creates a new ADD. Returns a pointer to the + ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNewVar Cudd_addIthVar] + +******************************************************************************/ +DdNode * +Cudd_addConst( + DdManager * dd, + CUDD_VALUE_TYPE c) +{ + return(cuddUniqueConst(dd,c)); + +} /* end of Cudd_addConst */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if a DD node is not constant.] + + Description [Returns 1 if a DD node is not constant. This function is + useful to test the results of Cudd_bddIteConstant, Cudd_addIteConstant, + Cudd_addEvalConst. These results may be a special value signifying + non-constant. In the other cases the macro Cudd_IsConstant can be used.] + + SideEffects [None] + + SeeAlso [Cudd_IsConstant Cudd_bddIteConstant Cudd_addIteConstant + Cudd_addEvalConst] + +******************************************************************************/ +int +Cudd_IsNonConstant( + DdNode *f) +{ + return(f == DD_NON_CONSTANT || !Cudd_IsConstant(f)); + +} /* end of Cudd_IsNonConstant */ + + +/**Function******************************************************************** + + Synopsis [Returns the start time of the manager.] + + Description [Returns the start time of the manager. This is initially set + to the number of milliseconds since the program started, but may be reset by + the application.] + + SideEffects [None] + + SeeAlso [Cudd_SetStartTime Cudd_ResetStartTime Cudd_ReadTimeLimit] + +******************************************************************************/ +unsigned long +Cudd_ReadStartTime( + DdManager * unique) +{ + return unique->startTime; + +} /* end of Cudd_ReadStartTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the time elapsed since the start time of the manager.] + + Description [Returns the time elapsed since the start time of the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadStartTime Cudd_SetStartTime] + +******************************************************************************/ +unsigned long +Cudd_ReadElapsedTime( + DdManager * unique) +{ + return util_cpu_time() - unique->startTime; + +} /* end of Cudd_ReadElapsedTime */ + + +/**Function******************************************************************** + + Synopsis [Sets the start time of the manager.] + + Description [Sets the start time of the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadStartTime Cudd_ResetStartTime Cudd_ReadElapsedTime + Cudd_SetTimeLimit] + +******************************************************************************/ +void +Cudd_SetStartTime( + DdManager * unique, + unsigned long st) +{ + unique->startTime = st; + +} /* end of Cudd_SetStartTime */ + + +/**Function******************************************************************** + + Synopsis [Resets the start time of the manager.] + + Description [Resets the start time of the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadStartTime Cudd_SetStartTime Cudd_SetTimeLimit] + +******************************************************************************/ +void +Cudd_ResetStartTime( + DdManager * unique) +{ + unique->startTime = util_cpu_time(); + +} /* end of Cudd_ResetStartTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the time limit for the manager.] + + Description [Returns the time limit for the manager. This is initially set + to a very large number, but may be reset by the application.] + + SideEffects [None] + + SeeAlso [Cudd_SetTimeLimit Cudd_UpdateTimeLimit Cudd_UnsetTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_ReadStartTime] + +******************************************************************************/ +unsigned long +Cudd_ReadTimeLimit( + DdManager * unique) +{ + return unique->timeLimit; + +} /* end of Cudd_ReadTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Sets the time limit for the manager.] + + Description [Sets the time limit for the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_UnsetTimeLimit Cudd_UpdateTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_SetTimeLimit( + DdManager * unique, + unsigned long tl) +{ + unique->timeLimit = tl; + +} /* end of Cudd_SetTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Updates the time limit for the manager.] + + Description [Updates the time limit for the manager by subtracting the + elapsed time from it.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UnsetTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_UpdateTimeLimit( + DdManager * unique) +{ + unsigned long elapsed; + if (unique->timeLimit == ~0UL) + return; + elapsed = util_cpu_time() - unique->startTime; + if (unique->timeLimit >= elapsed) { + unique->timeLimit -= elapsed; + } else { + unique->timeLimit = 0; + } + +} /* end of Cudd_UpdateTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Increases the time limit for the manager.] + + Description [Increases the time limit for the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UnsetTimeLimit + Cudd_UpdateTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_IncreaseTimeLimit( + DdManager * unique, + unsigned long increase) +{ + if (unique->timeLimit == ~0UL) + unique->timeLimit = increase; + else + unique->timeLimit += increase; + +} /* end of Cudd_IncreaseTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Unsets the time limit for the manager.] + + Description [Unsets the time limit for the manager. Actually, sets it to + a very large value.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UpdateTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_UnsetTimeLimit( + DdManager * unique) +{ + unique->timeLimit = ~0UL; + +} /* end of Cudd_UnsetTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Returns true if the time limit for the manager is set.] + + Description [Returns true if the time limit for the manager is set.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UpdateTimeLimit + Cudd_UnsetTimeLimit Cudd_IncreaseTimeLimit] + +******************************************************************************/ +int +Cudd_TimeLimited( + DdManager * unique) +{ + return unique->timeLimit != ~0UL; + +} /* end of Cudd_TimeLimited */ + + +/**Function******************************************************************** + + Synopsis [Enables automatic dynamic reordering of BDDs and ADDs.] + + Description [Enables automatic dynamic reordering of BDDs and + ADDs. Parameter method is used to determine the method used for + reordering. If CUDD_REORDER_SAME is passed, the method is + unchanged.] + + SideEffects [None] + + SeeAlso [Cudd_AutodynDisable Cudd_ReorderingStatus + Cudd_AutodynEnableZdd] + +******************************************************************************/ +void +Cudd_AutodynEnable( + DdManager * unique, + Cudd_ReorderingType method) +{ + unique->autoDyn = 1; + if (method != CUDD_REORDER_SAME) { + unique->autoMethod = method; + } +#ifndef DD_NO_DEATH_ROW + /* If reordering is enabled, using the death row causes too many + ** invocations. Hence, we shrink the death row to just one entry. + */ + cuddClearDeathRow(unique); + unique->deathRowDepth = 1; + unique->deadMask = unique->deathRowDepth - 1; + if ((unsigned) unique->nextDead > unique->deadMask) { + unique->nextDead = 0; + } + unique->deathRow = REALLOC(DdNodePtr, unique->deathRow, + unique->deathRowDepth); +#endif + return; + +} /* end of Cudd_AutodynEnable */ + + +/**Function******************************************************************** + + Synopsis [Disables automatic dynamic reordering.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_AutodynEnable Cudd_ReorderingStatus + Cudd_AutodynDisableZdd] + +******************************************************************************/ +void +Cudd_AutodynDisable( + DdManager * unique) +{ + unique->autoDyn = 0; + return; + +} /* end of Cudd_AutodynDisable */ + + +/**Function******************************************************************** + + Synopsis [Reports the status of automatic dynamic reordering of BDDs + and ADDs.] + + Description [Reports the status of automatic dynamic reordering of + BDDs and ADDs. Parameter method is set to the reordering method + currently selected. Returns 1 if automatic reordering is enabled; 0 + otherwise.] + + SideEffects [Parameter method is set to the reordering method currently + selected.] + + SeeAlso [Cudd_AutodynEnable Cudd_AutodynDisable + Cudd_ReorderingStatusZdd] + +******************************************************************************/ +int +Cudd_ReorderingStatus( + DdManager * unique, + Cudd_ReorderingType * method) +{ + *method = unique->autoMethod; + return(unique->autoDyn); + +} /* end of Cudd_ReorderingStatus */ + + +/**Function******************************************************************** + + Synopsis [Enables automatic dynamic reordering of ZDDs.] + + Description [Enables automatic dynamic reordering of ZDDs. Parameter + method is used to determine the method used for reordering ZDDs. If + CUDD_REORDER_SAME is passed, the method is unchanged.] + + SideEffects [None] + + SeeAlso [Cudd_AutodynDisableZdd Cudd_ReorderingStatusZdd + Cudd_AutodynEnable] + +******************************************************************************/ +void +Cudd_AutodynEnableZdd( + DdManager * unique, + Cudd_ReorderingType method) +{ + unique->autoDynZ = 1; + if (method != CUDD_REORDER_SAME) { + unique->autoMethodZ = method; + } + return; + +} /* end of Cudd_AutodynEnableZdd */ + + +/**Function******************************************************************** + + Synopsis [Disables automatic dynamic reordering of ZDDs.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_AutodynEnableZdd Cudd_ReorderingStatusZdd + Cudd_AutodynDisable] + +******************************************************************************/ +void +Cudd_AutodynDisableZdd( + DdManager * unique) +{ + unique->autoDynZ = 0; + return; + +} /* end of Cudd_AutodynDisableZdd */ + + +/**Function******************************************************************** + + Synopsis [Reports the status of automatic dynamic reordering of ZDDs.] + + Description [Reports the status of automatic dynamic reordering of + ZDDs. Parameter method is set to the ZDD reordering method currently + selected. Returns 1 if automatic reordering is enabled; 0 + otherwise.] + + SideEffects [Parameter method is set to the ZDD reordering method currently + selected.] + + SeeAlso [Cudd_AutodynEnableZdd Cudd_AutodynDisableZdd + Cudd_ReorderingStatus] + +******************************************************************************/ +int +Cudd_ReorderingStatusZdd( + DdManager * unique, + Cudd_ReorderingType * method) +{ + *method = unique->autoMethodZ; + return(unique->autoDynZ); + +} /* end of Cudd_ReorderingStatusZdd */ + + +/**Function******************************************************************** + + Synopsis [Tells whether the realignment of ZDD order to BDD order is + enabled.] + + Description [Returns 1 if the realignment of ZDD order to BDD order is + enabled; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddRealignEnable Cudd_zddRealignDisable + Cudd_bddRealignEnable Cudd_bddRealignDisable] + +******************************************************************************/ +int +Cudd_zddRealignmentEnabled( + DdManager * unique) +{ + return(unique->realign); + +} /* end of Cudd_zddRealignmentEnabled */ + + +/**Function******************************************************************** + + Synopsis [Enables realignment of ZDD order to BDD order.] + + Description [Enables realignment of the ZDD variable order to the + BDD variable order after the BDDs and ADDs have been reordered. The + number of ZDD variables must be a multiple of the number of BDD + variables for realignment to make sense. If this condition is not met, + Cudd_ReduceHeap will return 0. Let M be the + ratio of the two numbers. For the purpose of realignment, the ZDD + variables from M*i to (M+1)*i-1 are + reagarded as corresponding to BDD variable i. Realignment + is initially disabled.] + + SideEffects [None] + + SeeAlso [Cudd_ReduceHeap Cudd_zddRealignDisable + Cudd_zddRealignmentEnabled Cudd_bddRealignDisable + Cudd_bddRealignmentEnabled] + +******************************************************************************/ +void +Cudd_zddRealignEnable( + DdManager * unique) +{ + unique->realign = 1; + return; + +} /* end of Cudd_zddRealignEnable */ + + +/**Function******************************************************************** + + Synopsis [Disables realignment of ZDD order to BDD order.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddRealignEnable Cudd_zddRealignmentEnabled + Cudd_bddRealignEnable Cudd_bddRealignmentEnabled] + +******************************************************************************/ +void +Cudd_zddRealignDisable( + DdManager * unique) +{ + unique->realign = 0; + return; + +} /* end of Cudd_zddRealignDisable */ + + +/**Function******************************************************************** + + Synopsis [Tells whether the realignment of BDD order to ZDD order is + enabled.] + + Description [Returns 1 if the realignment of BDD order to ZDD order is + enabled; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddRealignEnable Cudd_bddRealignDisable + Cudd_zddRealignEnable Cudd_zddRealignDisable] + +******************************************************************************/ +int +Cudd_bddRealignmentEnabled( + DdManager * unique) +{ + return(unique->realignZ); + +} /* end of Cudd_bddRealignmentEnabled */ + + +/**Function******************************************************************** + + Synopsis [Enables realignment of BDD order to ZDD order.] + + Description [Enables realignment of the BDD variable order to the + ZDD variable order after the ZDDs have been reordered. The + number of ZDD variables must be a multiple of the number of BDD + variables for realignment to make sense. If this condition is not met, + Cudd_zddReduceHeap will return 0. Let M be the + ratio of the two numbers. For the purpose of realignment, the ZDD + variables from M*i to (M+1)*i-1 are + reagarded as corresponding to BDD variable i. Realignment + is initially disabled.] + + SideEffects [None] + + SeeAlso [Cudd_zddReduceHeap Cudd_bddRealignDisable + Cudd_bddRealignmentEnabled Cudd_zddRealignDisable + Cudd_zddRealignmentEnabled] + +******************************************************************************/ +void +Cudd_bddRealignEnable( + DdManager * unique) +{ + unique->realignZ = 1; + return; + +} /* end of Cudd_bddRealignEnable */ + + +/**Function******************************************************************** + + Synopsis [Disables realignment of ZDD order to BDD order.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_bddRealignEnable Cudd_bddRealignmentEnabled + Cudd_zddRealignEnable Cudd_zddRealignmentEnabled] + +******************************************************************************/ +void +Cudd_bddRealignDisable( + DdManager * unique) +{ + unique->realignZ = 0; + return; + +} /* end of Cudd_bddRealignDisable */ + + +/**Function******************************************************************** + + Synopsis [Returns the one constant of the manager.] + + Description [Returns the one constant of the manager. The one + constant is common to ADDs and BDDs.] + + SideEffects [None] + + SeeAlso [Cudd_ReadZero Cudd_ReadLogicZero Cudd_ReadZddOne] + +******************************************************************************/ +DdNode * +Cudd_ReadOne( + DdManager * dd) +{ + return(dd->one); + +} /* end of Cudd_ReadOne */ + + +/**Function******************************************************************** + + Synopsis [Returns the ZDD for the constant 1 function.] + + Description [Returns the ZDD for the constant 1 function. + The representation of the constant 1 function as a ZDD depends on + how many variables it (nominally) depends on. The index of the + topmost variable in the support is given as argument i.] + + SideEffects [None] + + SeeAlso [Cudd_ReadOne] + +******************************************************************************/ +DdNode * +Cudd_ReadZddOne( + DdManager * dd, + int i) +{ + if (i < 0) + return(NULL); + return(i < dd->sizeZ ? dd->univ[i] : DD_ONE(dd)); + +} /* end of Cudd_ReadZddOne */ + + + +/**Function******************************************************************** + + Synopsis [Returns the zero constant of the manager.] + + Description [Returns the zero constant of the manager. The zero + constant is the arithmetic zero, rather than the logic zero. The + latter is the complement of the one constant.] + + SideEffects [None] + + SeeAlso [Cudd_ReadOne Cudd_ReadLogicZero] + +******************************************************************************/ +DdNode * +Cudd_ReadZero( + DdManager * dd) +{ + return(DD_ZERO(dd)); + +} /* end of Cudd_ReadZero */ + + +/**Function******************************************************************** + + Synopsis [Returns the logic zero constant of the manager.] + + Description [Returns the zero constant of the manager. The logic zero + constant is the complement of the one constant, and is distinct from + the arithmetic zero.] + + SideEffects [None] + + SeeAlso [Cudd_ReadOne Cudd_ReadZero] + +******************************************************************************/ +DdNode * +Cudd_ReadLogicZero( + DdManager * dd) +{ + return(Cudd_Not(DD_ONE(dd))); + +} /* end of Cudd_ReadLogicZero */ + + +/**Function******************************************************************** + + Synopsis [Reads the plus-infinity constant from the manager.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_ReadPlusInfinity( + DdManager * dd) +{ + return(dd->plusinfinity); + +} /* end of Cudd_ReadPlusInfinity */ + + +/**Function******************************************************************** + + Synopsis [Reads the minus-infinity constant from the manager.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_ReadMinusInfinity( + DdManager * dd) +{ + return(dd->minusinfinity); + +} /* end of Cudd_ReadMinusInfinity */ + + +/**Function******************************************************************** + + Synopsis [Reads the background constant of the manager.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_ReadBackground( + DdManager * dd) +{ + return(dd->background); + +} /* end of Cudd_ReadBackground */ + + +/**Function******************************************************************** + + Synopsis [Sets the background constant of the manager.] + + Description [Sets the background constant of the manager. It assumes + that the DdNode pointer bck is already referenced.] + + SideEffects [None] + +******************************************************************************/ +void +Cudd_SetBackground( + DdManager * dd, + DdNode * bck) +{ + dd->background = bck; + +} /* end of Cudd_SetBackground */ + + +/**Function******************************************************************** + + Synopsis [Reads the number of slots in the cache.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadCacheUsedSlots] + +******************************************************************************/ +unsigned int +Cudd_ReadCacheSlots( + DdManager * dd) +{ + return(dd->cacheSlots); + +} /* end of Cudd_ReadCacheSlots */ + + +/**Function******************************************************************** + + Synopsis [Reads the fraction of used slots in the cache.] + + Description [Reads the fraction of used slots in the cache. The unused + slots are those in which no valid data is stored. Garbage collection, + variable reordering, and cache resizing may cause used slots to become + unused.] + + SideEffects [None] + + SeeAlso [Cudd_ReadCacheSlots] + +******************************************************************************/ +double +Cudd_ReadCacheUsedSlots( + DdManager * dd) +{ + unsigned long used = 0; + int slots = dd->cacheSlots; + DdCache *cache = dd->cache; + int i; + + for (i = 0; i < slots; i++) { + used += cache[i].h != 0; + } + + return((double)used / (double) dd->cacheSlots); + +} /* end of Cudd_ReadCacheUsedSlots */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of cache look-ups.] + + Description [Returns the number of cache look-ups.] + + SideEffects [None] + + SeeAlso [Cudd_ReadCacheHits] + +******************************************************************************/ +double +Cudd_ReadCacheLookUps( + DdManager * dd) +{ + return(dd->cacheHits + dd->cacheMisses + + dd->totCachehits + dd->totCacheMisses); + +} /* end of Cudd_ReadCacheLookUps */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of cache hits.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadCacheLookUps] + +******************************************************************************/ +double +Cudd_ReadCacheHits( + DdManager * dd) +{ + return(dd->cacheHits + dd->totCachehits); + +} /* end of Cudd_ReadCacheHits */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of recursive calls.] + + Description [Returns the number of recursive calls if the package is + compiled with DD_COUNT defined.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +double +Cudd_ReadRecursiveCalls( + DdManager * dd) +{ +#ifdef DD_COUNT + return(dd->recursiveCalls); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadRecursiveCalls */ + + + +/**Function******************************************************************** + + Synopsis [Reads the hit rate that causes resizinig of the computed + table.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetMinHit] + +******************************************************************************/ +unsigned int +Cudd_ReadMinHit( + DdManager * dd) +{ + /* Internally, the package manipulates the ratio of hits to + ** misses instead of the ratio of hits to accesses. */ + return((unsigned int) (0.5 + 100 * dd->minHit / (1 + dd->minHit))); + +} /* end of Cudd_ReadMinHit */ + + +/**Function******************************************************************** + + Synopsis [Sets the hit rate that causes resizinig of the computed + table.] + + Description [Sets the minHit parameter of the manager. This + parameter controls the resizing of the computed table. If the hit + rate is larger than the specified value, and the cache is not + already too large, then its size is doubled.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMinHit] + +******************************************************************************/ +void +Cudd_SetMinHit( + DdManager * dd, + unsigned int hr) +{ + /* Internally, the package manipulates the ratio of hits to + ** misses instead of the ratio of hits to accesses. */ + dd->minHit = (double) hr / (100.0 - (double) hr); + +} /* end of Cudd_SetMinHit */ + + +/**Function******************************************************************** + + Synopsis [Reads the looseUpTo parameter of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetLooseUpTo Cudd_ReadMinHit Cudd_ReadMinDead] + +******************************************************************************/ +unsigned int +Cudd_ReadLooseUpTo( + DdManager * dd) +{ + return(dd->looseUpTo); + +} /* end of Cudd_ReadLooseUpTo */ + + +/**Function******************************************************************** + + Synopsis [Sets the looseUpTo parameter of the manager.] + + Description [Sets the looseUpTo parameter of the manager. This + parameter of the manager controls the threshold beyond which no fast + growth of the unique table is allowed. The threshold is given as a + number of slots. If the value passed to this function is 0, the + function determines a suitable value based on the available memory.] + + SideEffects [None] + + SeeAlso [Cudd_ReadLooseUpTo Cudd_SetMinHit] + +******************************************************************************/ +void +Cudd_SetLooseUpTo( + DdManager * dd, + unsigned int lut) +{ + if (lut == 0) { + unsigned long datalimit = getSoftDataLimit(); + lut = (unsigned int) (datalimit / (sizeof(DdNode) * + DD_MAX_LOOSE_FRACTION)); + } + dd->looseUpTo = lut; + +} /* end of Cudd_SetLooseUpTo */ + + +/**Function******************************************************************** + + Synopsis [Returns the soft limit for the cache size.] + + Description [Returns the soft limit for the cache size.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxCacheHard] + +******************************************************************************/ +unsigned int +Cudd_ReadMaxCache( + DdManager * dd) +{ + return(2 * dd->cacheSlots + dd->cacheSlack); + +} /* end of Cudd_ReadMaxCache */ + + +/**Function******************************************************************** + + Synopsis [Reads the maxCacheHard parameter of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetMaxCacheHard Cudd_ReadMaxCache] + +******************************************************************************/ +unsigned int +Cudd_ReadMaxCacheHard( + DdManager * dd) +{ + return(dd->maxCacheHard); + +} /* end of Cudd_ReadMaxCache */ + + +/**Function******************************************************************** + + Synopsis [Sets the maxCacheHard parameter of the manager.] + + Description [Sets the maxCacheHard parameter of the manager. The + cache cannot grow larger than maxCacheHard entries. This parameter + allows an application to control the trade-off of memory versus + speed. If the value passed to this function is 0, the function + determines a suitable maximum cache size based on the available memory.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxCacheHard Cudd_SetMaxCache] + +******************************************************************************/ +void +Cudd_SetMaxCacheHard( + DdManager * dd, + unsigned int mc) +{ + if (mc == 0) { + unsigned long datalimit = getSoftDataLimit(); + mc = (unsigned int) (datalimit / (sizeof(DdCache) * + DD_MAX_CACHE_FRACTION)); + } + dd->maxCacheHard = mc; + +} /* end of Cudd_SetMaxCacheHard */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of BDD variables in existance.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadZddSize] + +******************************************************************************/ +int +Cudd_ReadSize( + DdManager * dd) +{ + return(dd->size); + +} /* end of Cudd_ReadSize */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of ZDD variables in existance.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadSize] + +******************************************************************************/ +int +Cudd_ReadZddSize( + DdManager * dd) +{ + return(dd->sizeZ); + +} /* end of Cudd_ReadZddSize */ + + +/**Function******************************************************************** + + Synopsis [Returns the total number of slots of the unique table.] + + Description [Returns the total number of slots of the unique table. + This number ismainly for diagnostic purposes.] + + SideEffects [None] + +******************************************************************************/ +unsigned int +Cudd_ReadSlots( + DdManager * dd) +{ + return(dd->slots); + +} /* end of Cudd_ReadSlots */ + + +/**Function******************************************************************** + + Synopsis [Reads the fraction of used slots in the unique table.] + + Description [Reads the fraction of used slots in the unique + table. The unused slots are those in which no valid data is + stored. Garbage collection, variable reordering, and subtable + resizing may cause used slots to become unused.] + + SideEffects [None] + + SeeAlso [Cudd_ReadSlots] + +******************************************************************************/ +double +Cudd_ReadUsedSlots( + DdManager * dd) +{ + unsigned long used = 0; + int i, j; + int size = dd->size; + DdNodePtr *nodelist; + DdSubtable *subtable; + DdNode *node; + DdNode *sentinel = &(dd->sentinel); + + /* Scan each BDD/ADD subtable. */ + for (i = 0; i < size; i++) { + subtable = &(dd->subtables[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != sentinel) { + used++; + } + } + } + + /* Scan the ZDD subtables. */ + size = dd->sizeZ; + + for (i = 0; i < size; i++) { + subtable = &(dd->subtableZ[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + used++; + } + } + } + + /* Constant table. */ + subtable = &(dd->constants); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + used++; + } + } + + return((double)used / (double) dd->slots); + +} /* end of Cudd_ReadUsedSlots */ + + +/**Function******************************************************************** + + Synopsis [Computes the expected fraction of used slots in the unique + table.] + + Description [Computes the fraction of slots in the unique table that + should be in use. This expected value is based on the assumption + that the hash function distributes the keys randomly; it can be + compared with the result of Cudd_ReadUsedSlots to monitor the + performance of the unique table hash function.] + + SideEffects [None] + + SeeAlso [Cudd_ReadSlots Cudd_ReadUsedSlots] + +******************************************************************************/ +double +Cudd_ExpectedUsedSlots( + DdManager * dd) +{ + int i; + int size = dd->size; + DdSubtable *subtable; + double empty = 0.0; + + /* To each subtable we apply the corollary to Theorem 8.5 (occupancy + ** distribution) from Sedgewick and Flajolet's Analysis of Algorithms. + ** The corollary says that for a table with M buckets and a load ratio + ** of r, the expected number of empty buckets is asymptotically given + ** by M * exp(-r). + */ + + /* Scan each BDD/ADD subtable. */ + for (i = 0; i < size; i++) { + subtable = &(dd->subtables[i]); + empty += (double) subtable->slots * + exp(-(double) subtable->keys / (double) subtable->slots); + } + + /* Scan the ZDD subtables. */ + size = dd->sizeZ; + + for (i = 0; i < size; i++) { + subtable = &(dd->subtableZ[i]); + empty += (double) subtable->slots * + exp(-(double) subtable->keys / (double) subtable->slots); + } + + /* Constant table. */ + subtable = &(dd->constants); + empty += (double) subtable->slots * + exp(-(double) subtable->keys / (double) subtable->slots); + + return(1.0 - empty / (double) dd->slots); + +} /* end of Cudd_ExpectedUsedSlots */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of nodes in the unique table.] + + Description [Returns the total number of nodes currently in the unique + table, including the dead nodes.] + + SideEffects [None] + + SeeAlso [Cudd_ReadDead] + +******************************************************************************/ +unsigned int +Cudd_ReadKeys( + DdManager * dd) +{ + return(dd->keys); + +} /* end of Cudd_ReadKeys */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of dead nodes in the unique table.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadKeys] + +******************************************************************************/ +unsigned int +Cudd_ReadDead( + DdManager * dd) +{ + return(dd->dead); + +} /* end of Cudd_ReadDead */ + + +/**Function******************************************************************** + + Synopsis [Reads the minDead parameter of the manager.] + + Description [Reads the minDead parameter of the manager. The minDead + parameter is used by the package to decide whether to collect garbage + or resize a subtable of the unique table when the subtable becomes + too full. The application can indirectly control the value of minDead + by setting the looseUpTo parameter.] + + SideEffects [None] + + SeeAlso [Cudd_ReadDead Cudd_ReadLooseUpTo Cudd_SetLooseUpTo] + +******************************************************************************/ +unsigned int +Cudd_ReadMinDead( + DdManager * dd) +{ + return(dd->minDead); + +} /* end of Cudd_ReadMinDead */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of times reordering has occurred.] + + Description [Returns the number of times reordering has occurred in the + manager. The number includes both the calls to Cudd_ReduceHeap from + the application program and those automatically performed by the + package. However, calls that do not even initiate reordering are not + counted. A call may not initiate reordering if there are fewer than + minsize live nodes in the manager, or if CUDD_REORDER_NONE is specified + as reordering method. The calls to Cudd_ShuffleHeap are not counted.] + + SideEffects [None] + + SeeAlso [Cudd_ReduceHeap Cudd_ReadReorderingTime] + +******************************************************************************/ +unsigned int +Cudd_ReadReorderings( + DdManager * dd) +{ + return(dd->reorderings); + +} /* end of Cudd_ReadReorderings */ + + +/**Function******************************************************************** + + Synopsis [Returns the maximum number of times reordering may be invoked.] + + Description [Returns the maximum number of times reordering may be invoked in + this manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadReorderings Cudd_SetMaxReorderings Cudd_ReduceHeap] + +******************************************************************************/ +unsigned int +Cudd_ReadMaxReorderings( + DdManager * dd) +{ + return(dd->maxReorderings); + +} /* end of Cudd_ReadMaxReorderings */ + + +/**Function******************************************************************** + + Synopsis [Sets the maximum number of times reordering may be invoked.] + + Description [Sets the maximum number of times reordering may be invoked in + this manager. The default value is (practically) infinite.] + + SideEffects [None] + + SeeAlso [Cudd_ReadReorderings Cudd_ReadMaxReorderings Cudd_ReduceHeap] + +******************************************************************************/ +void +Cudd_SetMaxReorderings( + DdManager * dd, unsigned int mr) +{ + dd->maxReorderings = mr; + +} /* end of Cudd_SetMaxReorderings */ + + +/**Function******************************************************************** + + Synopsis [Returns the time spent in reordering.] + + Description [Returns the number of milliseconds spent reordering + variables since the manager was initialized. The time spent in collecting + garbage before reordering is included.] + + SideEffects [None] + + SeeAlso [Cudd_ReadReorderings] + +******************************************************************************/ +long +Cudd_ReadReorderingTime( + DdManager * dd) +{ + return(dd->reordTime); + +} /* end of Cudd_ReadReorderingTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of times garbage collection has occurred.] + + Description [Returns the number of times garbage collection has + occurred in the manager. The number includes both the calls from + reordering procedures and those caused by requests to create new + nodes.] + + SideEffects [None] + + SeeAlso [Cudd_ReadGarbageCollectionTime] + +******************************************************************************/ +int +Cudd_ReadGarbageCollections( + DdManager * dd) +{ + return(dd->garbageCollections); + +} /* end of Cudd_ReadGarbageCollections */ + + +/**Function******************************************************************** + + Synopsis [Returns the time spent in garbage collection.] + + Description [Returns the number of milliseconds spent doing garbage + collection since the manager was initialized.] + + SideEffects [None] + + SeeAlso [Cudd_ReadGarbageCollections] + +******************************************************************************/ +long +Cudd_ReadGarbageCollectionTime( + DdManager * dd) +{ + return(dd->GCTime); + +} /* end of Cudd_ReadGarbageCollectionTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of nodes freed.] + + Description [Returns the number of nodes returned to the free list if the + keeping of this statistic is enabled; -1 otherwise. This statistic is + enabled only if the package is compiled with DD_STATS defined.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNodesDropped] + +******************************************************************************/ +double +Cudd_ReadNodesFreed( + DdManager * dd) +{ +#ifdef DD_STATS + return(dd->nodesFreed); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadNodesFreed */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of nodes dropped.] + + Description [Returns the number of nodes killed by dereferencing if the + keeping of this statistic is enabled; -1 otherwise. This statistic is + enabled only if the package is compiled with DD_STATS defined.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNodesFreed] + +******************************************************************************/ +double +Cudd_ReadNodesDropped( + DdManager * dd) +{ +#ifdef DD_STATS + return(dd->nodesDropped); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadNodesDropped */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of look-ups in the unique table.] + + Description [Returns the number of look-ups in the unique table if the + keeping of this statistic is enabled; -1 otherwise. This statistic is + enabled only if the package is compiled with DD_UNIQUE_PROFILE defined.] + + SideEffects [None] + + SeeAlso [Cudd_ReadUniqueLinks] + +******************************************************************************/ +double +Cudd_ReadUniqueLookUps( + DdManager * dd) +{ +#ifdef DD_UNIQUE_PROFILE + return(dd->uniqueLookUps); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadUniqueLookUps */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of links followed in the unique table.] + + Description [Returns the number of links followed during look-ups in the + unique table if the keeping of this statistic is enabled; -1 otherwise. + If an item is found in the first position of its collision list, the + number of links followed is taken to be 0. If it is in second position, + the number of links is 1, and so on. This statistic is enabled only if + the package is compiled with DD_UNIQUE_PROFILE defined.] + + SideEffects [None] + + SeeAlso [Cudd_ReadUniqueLookUps] + +******************************************************************************/ +double +Cudd_ReadUniqueLinks( + DdManager * dd) +{ +#ifdef DD_UNIQUE_PROFILE + return(dd->uniqueLinks); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadUniqueLinks */ + + +/**Function******************************************************************** + + Synopsis [Reads the siftMaxVar parameter of the manager.] + + Description [Reads the siftMaxVar parameter of the manager. This + parameter gives the maximum number of variables that will be sifted + for each invocation of sifting.] + + SideEffects [None] + + SeeAlso [Cudd_ReadSiftMaxSwap Cudd_SetSiftMaxVar] + +******************************************************************************/ +int +Cudd_ReadSiftMaxVar( + DdManager * dd) +{ + return(dd->siftMaxVar); + +} /* end of Cudd_ReadSiftMaxVar */ + + +/**Function******************************************************************** + + Synopsis [Sets the siftMaxVar parameter of the manager.] + + Description [Sets the siftMaxVar parameter of the manager. This + parameter gives the maximum number of variables that will be sifted + for each invocation of sifting.] + + SideEffects [None] + + SeeAlso [Cudd_SetSiftMaxSwap Cudd_ReadSiftMaxVar] + +******************************************************************************/ +void +Cudd_SetSiftMaxVar( + DdManager * dd, + int smv) +{ + dd->siftMaxVar = smv; + +} /* end of Cudd_SetSiftMaxVar */ + + +/**Function******************************************************************** + + Synopsis [Reads the siftMaxSwap parameter of the manager.] + + Description [Reads the siftMaxSwap parameter of the manager. This + parameter gives the maximum number of swaps that will be attempted + for each invocation of sifting. The real number of swaps may exceed + the set limit because the package will always complete the sifting + of the variable that causes the limit to be reached.] + + SideEffects [None] + + SeeAlso [Cudd_ReadSiftMaxVar Cudd_SetSiftMaxSwap] + +******************************************************************************/ +int +Cudd_ReadSiftMaxSwap( + DdManager * dd) +{ + return(dd->siftMaxSwap); + +} /* end of Cudd_ReadSiftMaxSwap */ + + +/**Function******************************************************************** + + Synopsis [Sets the siftMaxSwap parameter of the manager.] + + Description [Sets the siftMaxSwap parameter of the manager. This + parameter gives the maximum number of swaps that will be attempted + for each invocation of sifting. The real number of swaps may exceed + the set limit because the package will always complete the sifting + of the variable that causes the limit to be reached.] + + SideEffects [None] + + SeeAlso [Cudd_SetSiftMaxVar Cudd_ReadSiftMaxSwap] + +******************************************************************************/ +void +Cudd_SetSiftMaxSwap( + DdManager * dd, + int sms) +{ + dd->siftMaxSwap = sms; + +} /* end of Cudd_SetSiftMaxSwap */ + + +/**Function******************************************************************** + + Synopsis [Reads the maxGrowth parameter of the manager.] + + Description [Reads the maxGrowth parameter of the manager. This + parameter determines how much the number of nodes can grow during + sifting of a variable. Overall, sifting never increases the size of + the decision diagrams. This parameter only refers to intermediate + results. A lower value will speed up sifting, possibly at the + expense of quality.] + + SideEffects [None] + + SeeAlso [Cudd_SetMaxGrowth Cudd_ReadMaxGrowthAlternate] + +******************************************************************************/ +double +Cudd_ReadMaxGrowth( + DdManager * dd) +{ + return(dd->maxGrowth); + +} /* end of Cudd_ReadMaxGrowth */ + + +/**Function******************************************************************** + + Synopsis [Sets the maxGrowth parameter of the manager.] + + Description [Sets the maxGrowth parameter of the manager. This + parameter determines how much the number of nodes can grow during + sifting of a variable. Overall, sifting never increases the size of + the decision diagrams. This parameter only refers to intermediate + results. A lower value will speed up sifting, possibly at the + expense of quality.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate] + +******************************************************************************/ +void +Cudd_SetMaxGrowth( + DdManager * dd, + double mg) +{ + dd->maxGrowth = mg; + +} /* end of Cudd_SetMaxGrowth */ + + +/**Function******************************************************************** + + Synopsis [Reads the maxGrowthAlt parameter of the manager.] + + Description [Reads the maxGrowthAlt parameter of the manager. This + parameter is analogous to the maxGrowth paramter, and is used every + given number of reorderings instead of maxGrowth. The number of + reorderings is set with Cudd_SetReorderingCycle. If the number of + reorderings is 0 (default) maxGrowthAlt is never used.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate + Cudd_SetReorderingCycle Cudd_ReadReorderingCycle] + +******************************************************************************/ +double +Cudd_ReadMaxGrowthAlternate( + DdManager * dd) +{ + return(dd->maxGrowthAlt); + +} /* end of Cudd_ReadMaxGrowthAlternate */ + + +/**Function******************************************************************** + + Synopsis [Sets the maxGrowthAlt parameter of the manager.] + + Description [Sets the maxGrowthAlt parameter of the manager. This + parameter is analogous to the maxGrowth paramter, and is used every + given number of reorderings instead of maxGrowth. The number of + reorderings is set with Cudd_SetReorderingCycle. If the number of + reorderings is 0 (default) maxGrowthAlt is never used.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowth + Cudd_SetReorderingCycle Cudd_ReadReorderingCycle] + +******************************************************************************/ +void +Cudd_SetMaxGrowthAlternate( + DdManager * dd, + double mg) +{ + dd->maxGrowthAlt = mg; + +} /* end of Cudd_SetMaxGrowthAlternate */ + + +/**Function******************************************************************** + + Synopsis [Reads the reordCycle parameter of the manager.] + + Description [Reads the reordCycle parameter of the manager. This + parameter determines how often the alternate threshold on maximum + growth is used in reordering.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate + Cudd_SetReorderingCycle] + +******************************************************************************/ +int +Cudd_ReadReorderingCycle( + DdManager * dd) +{ + return(dd->reordCycle); + +} /* end of Cudd_ReadReorderingCycle */ + + +/**Function******************************************************************** + + Synopsis [Sets the reordCycle parameter of the manager.] + + Description [Sets the reordCycle parameter of the manager. This + parameter determines how often the alternate threshold on maximum + growth is used in reordering.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate + Cudd_ReadReorderingCycle] + +******************************************************************************/ +void +Cudd_SetReorderingCycle( + DdManager * dd, + int cycle) +{ + dd->reordCycle = cycle; + +} /* end of Cudd_SetReorderingCycle */ + + +/**Function******************************************************************** + + Synopsis [Returns the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetTree Cudd_FreeTree Cudd_ReadZddTree] + +******************************************************************************/ +MtrNode * +Cudd_ReadTree( + DdManager * dd) +{ + return(dd->tree); + +} /* end of Cudd_ReadTree */ + + +/**Function******************************************************************** + + Synopsis [Sets the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_FreeTree Cudd_ReadTree Cudd_SetZddTree] + +******************************************************************************/ +void +Cudd_SetTree( + DdManager * dd, + MtrNode * tree) +{ + if (dd->tree != NULL) { + Mtr_FreeTree(dd->tree); + } + dd->tree = tree; + if (tree == NULL) return; + + fixVarTree(tree, dd->perm, dd->size); + return; + +} /* end of Cudd_SetTree */ + + +/**Function******************************************************************** + + Synopsis [Frees the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetTree Cudd_ReadTree Cudd_FreeZddTree] + +******************************************************************************/ +void +Cudd_FreeTree( + DdManager * dd) +{ + if (dd->tree != NULL) { + Mtr_FreeTree(dd->tree); + dd->tree = NULL; + } + return; + +} /* end of Cudd_FreeTree */ + + +/**Function******************************************************************** + + Synopsis [Returns the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetZddTree Cudd_FreeZddTree Cudd_ReadTree] + +******************************************************************************/ +MtrNode * +Cudd_ReadZddTree( + DdManager * dd) +{ + return(dd->treeZ); + +} /* end of Cudd_ReadZddTree */ + + +/**Function******************************************************************** + + Synopsis [Sets the ZDD variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_FreeZddTree Cudd_ReadZddTree Cudd_SetTree] + +******************************************************************************/ +void +Cudd_SetZddTree( + DdManager * dd, + MtrNode * tree) +{ + if (dd->treeZ != NULL) { + Mtr_FreeTree(dd->treeZ); + } + dd->treeZ = tree; + if (tree == NULL) return; + + fixVarTree(tree, dd->permZ, dd->sizeZ); + return; + +} /* end of Cudd_SetZddTree */ + + +/**Function******************************************************************** + + Synopsis [Frees the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetZddTree Cudd_ReadZddTree Cudd_FreeTree] + +******************************************************************************/ +void +Cudd_FreeZddTree( + DdManager * dd) +{ + if (dd->treeZ != NULL) { + Mtr_FreeTree(dd->treeZ); + dd->treeZ = NULL; + } + return; + +} /* end of Cudd_FreeZddTree */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the node.] + + Description [Returns the index of the node. The node pointer can be + either regular or complemented.] + + SideEffects [None] + + SeeAlso [Cudd_ReadIndex] + +******************************************************************************/ +unsigned int +Cudd_NodeReadIndex( + DdNode * node) +{ + return((unsigned int) Cudd_Regular(node)->index); + +} /* end of Cudd_NodeReadIndex */ + + +/**Function******************************************************************** + + Synopsis [Returns the current position of the i-th variable in the + order.] + + Description [Returns the current position of the i-th variable in + the order. If the index is CUDD_CONST_INDEX, returns + CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns + -1.] + + SideEffects [None] + + SeeAlso [Cudd_ReadInvPerm Cudd_ReadPermZdd] + +******************************************************************************/ +int +Cudd_ReadPerm( + DdManager * dd, + int i) +{ + if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); + if (i < 0 || i >= dd->size) return(-1); + return(dd->perm[i]); + +} /* end of Cudd_ReadPerm */ + + +/**Function******************************************************************** + + Synopsis [Returns the current position of the i-th ZDD variable in the + order.] + + Description [Returns the current position of the i-th ZDD variable + in the order. If the index is CUDD_CONST_INDEX, returns + CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns + -1.] + + SideEffects [None] + + SeeAlso [Cudd_ReadInvPermZdd Cudd_ReadPerm] + +******************************************************************************/ +int +Cudd_ReadPermZdd( + DdManager * dd, + int i) +{ + if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); + if (i < 0 || i >= dd->sizeZ) return(-1); + return(dd->permZ[i]); + +} /* end of Cudd_ReadPermZdd */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the variable currently in the i-th + position of the order.] + + Description [Returns the index of the variable currently in the i-th + position of the order. If the index is CUDD_CONST_INDEX, returns + CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.] + + SideEffects [None] + + SeeAlso [Cudd_ReadPerm Cudd_ReadInvPermZdd] + +******************************************************************************/ +int +Cudd_ReadInvPerm( + DdManager * dd, + int i) +{ + if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); + if (i < 0 || i >= dd->size) return(-1); + return(dd->invperm[i]); + +} /* end of Cudd_ReadInvPerm */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the ZDD variable currently in the i-th + position of the order.] + + Description [Returns the index of the ZDD variable currently in the + i-th position of the order. If the index is CUDD_CONST_INDEX, returns + CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.] + + SideEffects [None] + + SeeAlso [Cudd_ReadPerm Cudd_ReadInvPermZdd] + +******************************************************************************/ +int +Cudd_ReadInvPermZdd( + DdManager * dd, + int i) +{ + if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); + if (i < 0 || i >= dd->sizeZ) return(-1); + return(dd->invpermZ[i]); + +} /* end of Cudd_ReadInvPermZdd */ + + +/**Function******************************************************************** + + Synopsis [Returns the i-th element of the vars array.] + + Description [Returns the i-th element of the vars array if it falls + within the array bounds; NULL otherwise. If i is the index of an + existing variable, this function produces the same result as + Cudd_bddIthVar. However, if the i-th var does not exist yet, + Cudd_bddIthVar will create it, whereas Cudd_ReadVars will not.] + + SideEffects [None] + + SeeAlso [Cudd_bddIthVar] + +******************************************************************************/ +DdNode * +Cudd_ReadVars( + DdManager * dd, + int i) +{ + if (i < 0 || i > dd->size) return(NULL); + return(dd->vars[i]); + +} /* end of Cudd_ReadVars */ + + +/**Function******************************************************************** + + Synopsis [Reads the epsilon parameter of the manager.] + + Description [Reads the epsilon parameter of the manager. The epsilon + parameter control the comparison between floating point numbers.] + + SideEffects [None] + + SeeAlso [Cudd_SetEpsilon] + +******************************************************************************/ +CUDD_VALUE_TYPE +Cudd_ReadEpsilon( + DdManager * dd) +{ + return(dd->epsilon); + +} /* end of Cudd_ReadEpsilon */ + + +/**Function******************************************************************** + + Synopsis [Sets the epsilon parameter of the manager to ep.] + + Description [Sets the epsilon parameter of the manager to ep. The epsilon + parameter control the comparison between floating point numbers.] + + SideEffects [None] + + SeeAlso [Cudd_ReadEpsilon] + +******************************************************************************/ +void +Cudd_SetEpsilon( + DdManager * dd, + CUDD_VALUE_TYPE ep) +{ + dd->epsilon = ep; + +} /* end of Cudd_SetEpsilon */ + + +/**Function******************************************************************** + + Synopsis [Reads the groupcheck parameter of the manager.] + + Description [Reads the groupcheck parameter of the manager. The + groupcheck parameter determines the aggregation criterion in group + sifting.] + + SideEffects [None] + + SeeAlso [Cudd_SetGroupcheck] + +******************************************************************************/ +Cudd_AggregationType +Cudd_ReadGroupcheck( + DdManager * dd) +{ + return(dd->groupcheck); + +} /* end of Cudd_ReadGroupCheck */ + + +/**Function******************************************************************** + + Synopsis [Sets the parameter groupcheck of the manager to gc.] + + Description [Sets the parameter groupcheck of the manager to gc. The + groupcheck parameter determines the aggregation criterion in group + sifting.] + + SideEffects [None] + + SeeAlso [Cudd_ReadGroupCheck] + +******************************************************************************/ +void +Cudd_SetGroupcheck( + DdManager * dd, + Cudd_AggregationType gc) +{ + dd->groupcheck = gc; + +} /* end of Cudd_SetGroupcheck */ + + +/**Function******************************************************************** + + Synopsis [Tells whether garbage collection is enabled.] + + Description [Returns 1 if garbage collection is enabled; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_EnableGarbageCollection Cudd_DisableGarbageCollection] + +******************************************************************************/ +int +Cudd_GarbageCollectionEnabled( + DdManager * dd) +{ + return(dd->gcEnabled); + +} /* end of Cudd_GarbageCollectionEnabled */ + + +/**Function******************************************************************** + + Synopsis [Enables garbage collection.] + + Description [Enables garbage collection. Garbage collection is + initially enabled. Therefore it is necessary to call this function + only if garbage collection has been explicitly disabled.] + + SideEffects [None] + + SeeAlso [Cudd_DisableGarbageCollection Cudd_GarbageCollectionEnabled] + +******************************************************************************/ +void +Cudd_EnableGarbageCollection( + DdManager * dd) +{ + dd->gcEnabled = 1; + +} /* end of Cudd_EnableGarbageCollection */ + + +/**Function******************************************************************** + + Synopsis [Disables garbage collection.] + + Description [Disables garbage collection. Garbage collection is + initially enabled. This function may be called to disable it. + However, garbage collection will still occur when a new node must be + created and no memory is left, or when garbage collection is required + for correctness. (E.g., before reordering.)] + + SideEffects [None] + + SeeAlso [Cudd_EnableGarbageCollection Cudd_GarbageCollectionEnabled] + +******************************************************************************/ +void +Cudd_DisableGarbageCollection( + DdManager * dd) +{ + dd->gcEnabled = 0; + +} /* end of Cudd_DisableGarbageCollection */ + + +/**Function******************************************************************** + + Synopsis [Tells whether dead nodes are counted towards triggering + reordering.] + + Description [Tells whether dead nodes are counted towards triggering + reordering. Returns 1 if dead nodes are counted; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_TurnOnCountDead Cudd_TurnOffCountDead] + +******************************************************************************/ +int +Cudd_DeadAreCounted( + DdManager * dd) +{ + return(dd->countDead == 0 ? 1 : 0); + +} /* end of Cudd_DeadAreCounted */ + + +/**Function******************************************************************** + + Synopsis [Causes the dead nodes to be counted towards triggering + reordering.] + + Description [Causes the dead nodes to be counted towards triggering + reordering. This causes more frequent reorderings. By default dead + nodes are not counted.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_TurnOffCountDead Cudd_DeadAreCounted] + +******************************************************************************/ +void +Cudd_TurnOnCountDead( + DdManager * dd) +{ + dd->countDead = 0; + +} /* end of Cudd_TurnOnCountDead */ + + +/**Function******************************************************************** + + Synopsis [Causes the dead nodes not to be counted towards triggering + reordering.] + + Description [Causes the dead nodes not to be counted towards + triggering reordering. This causes less frequent reorderings. By + default dead nodes are not counted. Therefore there is no need to + call this function unless Cudd_TurnOnCountDead has been previously + called.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_TurnOnCountDead Cudd_DeadAreCounted] + +******************************************************************************/ +void +Cudd_TurnOffCountDead( + DdManager * dd) +{ + dd->countDead = ~0; + +} /* end of Cudd_TurnOffCountDead */ + + +/**Function******************************************************************** + + Synopsis [Returns the current value of the recombination parameter used + in group sifting.] + + Description [Returns the current value of the recombination + parameter used in group sifting. A larger (positive) value makes the + aggregation of variables due to the second difference criterion more + likely. A smaller (negative) value makes aggregation less likely.] + + SideEffects [None] + + SeeAlso [Cudd_SetRecomb] + +******************************************************************************/ +int +Cudd_ReadRecomb( + DdManager * dd) +{ + return(dd->recomb); + +} /* end of Cudd_ReadRecomb */ + + +/**Function******************************************************************** + + Synopsis [Sets the value of the recombination parameter used in group + sifting.] + + Description [Sets the value of the recombination parameter used in + group sifting. A larger (positive) value makes the aggregation of + variables due to the second difference criterion more likely. A + smaller (negative) value makes aggregation less likely. The default + value is 0.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_ReadRecomb] + +******************************************************************************/ +void +Cudd_SetRecomb( + DdManager * dd, + int recomb) +{ + dd->recomb = recomb; + +} /* end of Cudd_SetRecomb */ + + +/**Function******************************************************************** + + Synopsis [Returns the current value of the symmviolation parameter used + in group sifting.] + + Description [Returns the current value of the symmviolation + parameter. This parameter is used in group sifting to decide how + many violations to the symmetry conditions f10 = f01 or + f11 = f00 are tolerable when checking for aggregation + due to extended symmetry. The value should be between 0 and 100. A + small value causes fewer variables to be aggregated. The default + value is 0.] + + SideEffects [None] + + SeeAlso [Cudd_SetSymmviolation] + +******************************************************************************/ +int +Cudd_ReadSymmviolation( + DdManager * dd) +{ + return(dd->symmviolation); + +} /* end of Cudd_ReadSymmviolation */ + + +/**Function******************************************************************** + + Synopsis [Sets the value of the symmviolation parameter used + in group sifting.] + + Description [Sets the value of the symmviolation + parameter. This parameter is used in group sifting to decide how + many violations to the symmetry conditions f10 = f01 or + f11 = f00 are tolerable when checking for aggregation + due to extended symmetry. The value should be between 0 and 100. A + small value causes fewer variables to be aggregated. The default + value is 0.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_ReadSymmviolation] + +******************************************************************************/ +void +Cudd_SetSymmviolation( + DdManager * dd, + int symmviolation) +{ + dd->symmviolation = symmviolation; + +} /* end of Cudd_SetSymmviolation */ + + +/**Function******************************************************************** + + Synopsis [Returns the current value of the arcviolation parameter used + in group sifting.] + + Description [Returns the current value of the arcviolation + parameter. This parameter is used in group sifting to decide how + many arcs into y not coming from x are + tolerable when checking for aggregation due to extended + symmetry. The value should be between 0 and 100. A small value + causes fewer variables to be aggregated. The default value is 0.] + + SideEffects [None] + + SeeAlso [Cudd_SetArcviolation] + +******************************************************************************/ +int +Cudd_ReadArcviolation( + DdManager * dd) +{ + return(dd->arcviolation); + +} /* end of Cudd_ReadArcviolation */ + + +/**Function******************************************************************** + + Synopsis [Sets the value of the arcviolation parameter used + in group sifting.] + + Description [Sets the value of the arcviolation + parameter. This parameter is used in group sifting to decide how + many arcs into y not coming from x are + tolerable when checking for aggregation due to extended + symmetry. The value should be between 0 and 100. A small value + causes fewer variables to be aggregated. The default value is 0.] + + SideEffects [None] + + SeeAlso [Cudd_ReadArcviolation] + +******************************************************************************/ +void +Cudd_SetArcviolation( + DdManager * dd, + int arcviolation) +{ + dd->arcviolation = arcviolation; + +} /* end of Cudd_SetArcviolation */ + + +/**Function******************************************************************** + + Synopsis [Reads the current size of the population used by the + genetic algorithm for reordering.] + + Description [Reads the current size of the population used by the + genetic algorithm for variable reordering. A larger population size will + cause the genetic algorithm to take more time, but will generally + produce better results. The default value is 0, in which case the + package uses three times the number of variables as population size, + with a maximum of 120.] + + SideEffects [None] + + SeeAlso [Cudd_SetPopulationSize] + +******************************************************************************/ +int +Cudd_ReadPopulationSize( + DdManager * dd) +{ + return(dd->populationSize); + +} /* end of Cudd_ReadPopulationSize */ + + +/**Function******************************************************************** + + Synopsis [Sets the size of the population used by the + genetic algorithm for reordering.] + + Description [Sets the size of the population used by the + genetic algorithm for variable reordering. A larger population size will + cause the genetic algorithm to take more time, but will generally + produce better results. The default value is 0, in which case the + package uses three times the number of variables as population size, + with a maximum of 120.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_ReadPopulationSize] + +******************************************************************************/ +void +Cudd_SetPopulationSize( + DdManager * dd, + int populationSize) +{ + dd->populationSize = populationSize; + +} /* end of Cudd_SetPopulationSize */ + + +/**Function******************************************************************** + + Synopsis [Reads the current number of crossovers used by the + genetic algorithm for reordering.] + + Description [Reads the current number of crossovers used by the + genetic algorithm for variable reordering. A larger number of crossovers will + cause the genetic algorithm to take more time, but will generally + produce better results. The default value is 0, in which case the + package uses three times the number of variables as number of crossovers, + with a maximum of 60.] + + SideEffects [None] + + SeeAlso [Cudd_SetNumberXovers] + +******************************************************************************/ +int +Cudd_ReadNumberXovers( + DdManager * dd) +{ + return(dd->numberXovers); + +} /* end of Cudd_ReadNumberXovers */ + + +/**Function******************************************************************** + + Synopsis [Sets the number of crossovers used by the + genetic algorithm for reordering.] + + Description [Sets the number of crossovers used by the genetic + algorithm for variable reordering. A larger number of crossovers + will cause the genetic algorithm to take more time, but will + generally produce better results. The default value is 0, in which + case the package uses three times the number of variables as number + of crossovers, with a maximum of 60.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNumberXovers] + +******************************************************************************/ +void +Cudd_SetNumberXovers( + DdManager * dd, + int numberXovers) +{ + dd->numberXovers = numberXovers; + +} /* end of Cudd_SetNumberXovers */ + + +/**Function******************************************************************** + + Synopsis [Returns the order randomization factor.] + + Description [Returns the order randomization factor. If non-zero this + factor is used to determine a perturbation of the next reordering threshold. + Larger factors cause larger perturbations.] + + SideEffects [None] + + SeeAlso [Cudd_SetOrderRandomization] + +******************************************************************************/ +unsigned int +Cudd_ReadOrderRandomization( + DdManager * dd) +{ + return(dd->randomizeOrder); + +} /* end of Cudd_ReadOrderRandomization */ + + +/**Function******************************************************************** + + Synopsis [Sets the order randomization factor.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadOrderRandomization] + +******************************************************************************/ +void +Cudd_SetOrderRandomization( + DdManager * dd, + unsigned int factor) +{ + dd->randomizeOrder = factor; + +} /* end of Cudd_SetOrderRandomization */ + + +/**Function******************************************************************** + + Synopsis [Returns the memory in use by the manager measured in bytes.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +unsigned long +Cudd_ReadMemoryInUse( + DdManager * dd) +{ + return(dd->memused); + +} /* end of Cudd_ReadMemoryInUse */ + + +/**Function******************************************************************** + + Synopsis [Prints out statistics and settings for a CUDD manager.] + + Description [Prints out statistics and settings for a CUDD manager. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_PrintInfo( + DdManager * dd, + FILE * fp) +{ + int retval; + Cudd_ReorderingType autoMethod, autoMethodZ; + + /* Modifiable parameters. */ + retval = fprintf(fp,"**** CUDD modifiable parameters ****\n"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Hard limit for cache size: %u\n", + Cudd_ReadMaxCacheHard(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache hit threshold for resizing: %u%%\n", + Cudd_ReadMinHit(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Garbage collection enabled: %s\n", + Cudd_GarbageCollectionEnabled(dd) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Limit for fast unique table growth: %u\n", + Cudd_ReadLooseUpTo(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp, + "Maximum number of variables sifted per reordering: %d\n", + Cudd_ReadSiftMaxVar(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp, + "Maximum number of variable swaps per reordering: %d\n", + Cudd_ReadSiftMaxSwap(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Maximum growth while sifting a variable: %g\n", + Cudd_ReadMaxGrowth(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Dynamic reordering of BDDs enabled: %s\n", + Cudd_ReorderingStatus(dd,&autoMethod) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Default BDD reordering method: %d\n", + (int) autoMethod); + if (retval == EOF) return(0); + retval = fprintf(fp,"Dynamic reordering of ZDDs enabled: %s\n", + Cudd_ReorderingStatusZdd(dd,&autoMethodZ) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Default ZDD reordering method: %d\n", + (int) autoMethodZ); + if (retval == EOF) return(0); + retval = fprintf(fp,"Realignment of ZDDs to BDDs enabled: %s\n", + Cudd_zddRealignmentEnabled(dd) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Realignment of BDDs to ZDDs enabled: %s\n", + Cudd_bddRealignmentEnabled(dd) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Dead nodes counted in triggering reordering: %s\n", + Cudd_DeadAreCounted(dd) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Group checking criterion: %d\n", + (int) Cudd_ReadGroupcheck(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Recombination threshold: %d\n", Cudd_ReadRecomb(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Symmetry violation threshold: %d\n", + Cudd_ReadSymmviolation(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Arc violation threshold: %d\n", + Cudd_ReadArcviolation(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"GA population size: %d\n", + Cudd_ReadPopulationSize(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of crossovers for GA: %d\n", + Cudd_ReadNumberXovers(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Next reordering threshold: %u\n", + Cudd_ReadNextReordering(dd)); + if (retval == EOF) return(0); + + /* Non-modifiable parameters. */ + retval = fprintf(fp,"**** CUDD non-modifiable parameters ****\n"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Memory in use: %lu\n", Cudd_ReadMemoryInUse(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Peak number of nodes: %ld\n", + Cudd_ReadPeakNodeCount(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Peak number of live nodes: %d\n", + Cudd_ReadPeakLiveNodeCount(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of BDD variables: %d\n", dd->size); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of ZDD variables: %d\n", dd->sizeZ); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache entries: %u\n", dd->cacheSlots); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache look-ups: %.0f\n", + Cudd_ReadCacheLookUps(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache hits: %.0f\n", + Cudd_ReadCacheHits(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache insertions: %.0f\n", + dd->cacheinserts); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache collisions: %.0f\n", + dd->cachecollisions); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache deletions: %.0f\n", + dd->cachedeletions); + if (retval == EOF) return(0); + retval = cuddCacheProfile(dd,fp); + if (retval == 0) return(0); + retval = fprintf(fp,"Soft limit for cache size: %u\n", + Cudd_ReadMaxCache(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of buckets in unique table: %u\n", dd->slots); + if (retval == EOF) return(0); + retval = fprintf(fp,"Used buckets in unique table: %.2f%% (expected %.2f%%)\n", + 100.0 * Cudd_ReadUsedSlots(dd), + 100.0 * Cudd_ExpectedUsedSlots(dd)); + if (retval == EOF) return(0); +#ifdef DD_UNIQUE_PROFILE + retval = fprintf(fp,"Unique lookups: %.0f\n", dd->uniqueLookUps); + if (retval == EOF) return(0); + retval = fprintf(fp,"Unique links: %.0f (%g per lookup)\n", + dd->uniqueLinks, dd->uniqueLinks / dd->uniqueLookUps); + if (retval == EOF) return(0); +#endif + retval = fprintf(fp,"Number of BDD and ADD nodes: %u\n", dd->keys); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of ZDD nodes: %u\n", dd->keysZ); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of dead BDD and ADD nodes: %u\n", dd->dead); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of dead ZDD nodes: %u\n", dd->deadZ); + if (retval == EOF) return(0); + retval = fprintf(fp,"Total number of nodes allocated: %.0f\n", + dd->allocated); + if (retval == EOF) return(0); + retval = fprintf(fp,"Total number of nodes reclaimed: %.0f\n", + dd->reclaimed); + if (retval == EOF) return(0); +#ifdef DD_STATS + retval = fprintf(fp,"Nodes freed: %.0f\n", dd->nodesFreed); + if (retval == EOF) return(0); + retval = fprintf(fp,"Nodes dropped: %.0f\n", dd->nodesDropped); + if (retval == EOF) return(0); +#endif +#ifdef DD_COUNT + retval = fprintf(fp,"Number of recursive calls: %.0f\n", + Cudd_ReadRecursiveCalls(dd)); + if (retval == EOF) return(0); +#endif + retval = fprintf(fp,"Garbage collections so far: %d\n", + Cudd_ReadGarbageCollections(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Time for garbage collection: %.2f sec\n", + ((double)Cudd_ReadGarbageCollectionTime(dd)/1000.0)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Reorderings so far: %d\n", dd->reorderings); + if (retval == EOF) return(0); + retval = fprintf(fp,"Time for reordering: %.2f sec\n", + ((double)Cudd_ReadReorderingTime(dd)/1000.0)); + if (retval == EOF) return(0); +#ifdef DD_COUNT + retval = fprintf(fp,"Node swaps in reordering: %.0f\n", + Cudd_ReadSwapSteps(dd)); + if (retval == EOF) return(0); +#endif + + return(1); + +} /* end of Cudd_PrintInfo */ + + +/**Function******************************************************************** + + Synopsis [Reports the peak number of nodes.] + + Description [Reports the peak number of nodes. This number includes + node on the free list. At the peak, the number of nodes on the free + list is guaranteed to be less than DD_MEM_CHUNK.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNodeCount Cudd_PrintInfo] + +******************************************************************************/ +long +Cudd_ReadPeakNodeCount( + DdManager * dd) +{ + long count = 0; + DdNodePtr *scan = dd->memoryList; + + while (scan != NULL) { + count += DD_MEM_CHUNK; + scan = (DdNodePtr *) *scan; + } + return(count); + +} /* end of Cudd_ReadPeakNodeCount */ + + +/**Function******************************************************************** + + Synopsis [Reports the peak number of live nodes.] + + Description [Reports the peak number of live nodes.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNodeCount Cudd_PrintInfo Cudd_ReadPeakNodeCount] + +******************************************************************************/ +int +Cudd_ReadPeakLiveNodeCount( + DdManager * dd) +{ + unsigned int live = dd->keys - dd->dead; + + if (live > dd->peakLiveNodes) { + dd->peakLiveNodes = live; + } + return((int)dd->peakLiveNodes); + +} /* end of Cudd_ReadPeakLiveNodeCount */ + + +/**Function******************************************************************** + + Synopsis [Reports the number of nodes in BDDs and ADDs.] + + Description [Reports the number of live nodes in BDDs and ADDs. This + number does not include the isolated projection functions and the + unused constants. These nodes that are not counted are not part of + the DDs manipulated by the application.] + + SideEffects [None] + + SeeAlso [Cudd_ReadPeakNodeCount Cudd_zddReadNodeCount] + +******************************************************************************/ +long +Cudd_ReadNodeCount( + DdManager * dd) +{ + long count; + int i; + +#ifndef DD_NO_DEATH_ROW + cuddClearDeathRow(dd); +#endif + + count = (long) (dd->keys - dd->dead); + + /* Count isolated projection functions. Their number is subtracted + ** from the node count because they are not part of the BDDs. + */ + for (i=0; i < dd->size; i++) { + if (dd->vars[i]->ref == 1) count--; + } + /* Subtract from the count the unused constants. */ + if (DD_ZERO(dd)->ref == 1) count--; + if (DD_PLUS_INFINITY(dd)->ref == 1) count--; + if (DD_MINUS_INFINITY(dd)->ref == 1) count--; + + return(count); + +} /* end of Cudd_ReadNodeCount */ + + + +/**Function******************************************************************** + + Synopsis [Reports the number of nodes in ZDDs.] + + Description [Reports the number of nodes in ZDDs. This + number always includes the two constants 1 and 0.] + + SideEffects [None] + + SeeAlso [Cudd_ReadPeakNodeCount Cudd_ReadNodeCount] + +******************************************************************************/ +long +Cudd_zddReadNodeCount( + DdManager * dd) +{ + return((long)(dd->keysZ - dd->deadZ + 2)); + +} /* end of Cudd_zddReadNodeCount */ + + +/**Function******************************************************************** + + Synopsis [Adds a function to a hook.] + + Description [Adds a function to a hook. A hook is a list of + application-provided functions called on certain occasions by the + package. Returns 1 if the function is successfully added; 2 if the + function was already in the list; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_RemoveHook] + +******************************************************************************/ +int +Cudd_AddHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where) +{ + DdHook **hook, *nextHook, *newHook; + + switch (where) { + case CUDD_PRE_GC_HOOK: + hook = &(dd->preGCHook); + break; + case CUDD_POST_GC_HOOK: + hook = &(dd->postGCHook); + break; + case CUDD_PRE_REORDERING_HOOK: + hook = &(dd->preReorderingHook); + break; + case CUDD_POST_REORDERING_HOOK: + hook = &(dd->postReorderingHook); + break; + default: + return(0); + } + /* Scan the list and find whether the function is already there. + ** If so, just return. */ + nextHook = *hook; + while (nextHook != NULL) { + if (nextHook->f == f) { + return(2); + } + hook = &(nextHook->next); + nextHook = nextHook->next; + } + /* The function was not in the list. Create a new item and append it + ** to the end of the list. */ + newHook = ALLOC(DdHook,1); + if (newHook == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newHook->next = NULL; + newHook->f = f; + *hook = newHook; + return(1); + +} /* end of Cudd_AddHook */ + + +/**Function******************************************************************** + + Synopsis [Removes a function from a hook.] + + Description [Removes a function from a hook. A hook is a list of + application-provided functions called on certain occasions by the + package. Returns 1 if successful; 0 the function was not in the list.] + + SideEffects [None] + + SeeAlso [Cudd_AddHook] + +******************************************************************************/ +int +Cudd_RemoveHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where) +{ + DdHook **hook, *nextHook; + + switch (where) { + case CUDD_PRE_GC_HOOK: + hook = &(dd->preGCHook); + break; + case CUDD_POST_GC_HOOK: + hook = &(dd->postGCHook); + break; + case CUDD_PRE_REORDERING_HOOK: + hook = &(dd->preReorderingHook); + break; + case CUDD_POST_REORDERING_HOOK: + hook = &(dd->postReorderingHook); + break; + default: + return(0); + } + nextHook = *hook; + while (nextHook != NULL) { + if (nextHook->f == f) { + *hook = nextHook->next; + FREE(nextHook); + return(1); + } + hook = &(nextHook->next); + nextHook = nextHook->next; + } + + return(0); + +} /* end of Cudd_RemoveHook */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a function is in a hook.] + + Description [Checks whether a function is in a hook. A hook is a list of + application-provided functions called on certain occasions by the + package. Returns 1 if the function is found; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_AddHook Cudd_RemoveHook] + +******************************************************************************/ +int +Cudd_IsInHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where) +{ + DdHook *hook; + + switch (where) { + case CUDD_PRE_GC_HOOK: + hook = dd->preGCHook; + break; + case CUDD_POST_GC_HOOK: + hook = dd->postGCHook; + break; + case CUDD_PRE_REORDERING_HOOK: + hook = dd->preReorderingHook; + break; + case CUDD_POST_REORDERING_HOOK: + hook = dd->postReorderingHook; + break; + default: + return(0); + } + /* Scan the list and find whether the function is already there. */ + while (hook != NULL) { + if (hook->f == f) { + return(1); + } + hook = hook->next; + } + return(0); + +} /* end of Cudd_IsInHook */ + + +/**Function******************************************************************** + + Synopsis [Sample hook function to call before reordering.] + + Description [Sample hook function to call before reordering. + Prints on the manager's stdout reordering method and initial size. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_StdPostReordHook] + +******************************************************************************/ +int +Cudd_StdPreReordHook( + DdManager *dd, + const char *str, + void *data) +{ + Cudd_ReorderingType method = (Cudd_ReorderingType) (ptruint) data; + int retval; + + retval = fprintf(dd->out,"%s reordering with ", str); + if (retval == EOF) return(0); + switch (method) { + case CUDD_REORDER_SIFT_CONVERGE: + case CUDD_REORDER_SYMM_SIFT_CONV: + case CUDD_REORDER_GROUP_SIFT_CONV: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + case CUDD_REORDER_LINEAR_CONVERGE: + retval = fprintf(dd->out,"converging "); + if (retval == EOF) return(0); + break; + default: + break; + } + switch (method) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + retval = fprintf(dd->out,"random"); + break; + case CUDD_REORDER_SIFT: + case CUDD_REORDER_SIFT_CONVERGE: + retval = fprintf(dd->out,"sifting"); + break; + case CUDD_REORDER_SYMM_SIFT: + case CUDD_REORDER_SYMM_SIFT_CONV: + retval = fprintf(dd->out,"symmetric sifting"); + break; + case CUDD_REORDER_LAZY_SIFT: + retval = fprintf(dd->out,"lazy sifting"); + break; + case CUDD_REORDER_GROUP_SIFT: + case CUDD_REORDER_GROUP_SIFT_CONV: + retval = fprintf(dd->out,"group sifting"); + break; + case CUDD_REORDER_WINDOW2: + case CUDD_REORDER_WINDOW3: + case CUDD_REORDER_WINDOW4: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + retval = fprintf(dd->out,"window"); + break; + case CUDD_REORDER_ANNEALING: + retval = fprintf(dd->out,"annealing"); + break; + case CUDD_REORDER_GENETIC: + retval = fprintf(dd->out,"genetic"); + break; + case CUDD_REORDER_LINEAR: + case CUDD_REORDER_LINEAR_CONVERGE: + retval = fprintf(dd->out,"linear sifting"); + break; + case CUDD_REORDER_EXACT: + retval = fprintf(dd->out,"exact"); + break; + default: + return(0); + } + if (retval == EOF) return(0); + + retval = fprintf(dd->out,": from %ld to ... ", strcmp(str, "BDD") == 0 ? + Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd)); + if (retval == EOF) return(0); + fflush(dd->out); + return(1); + +} /* end of Cudd_StdPreReordHook */ + + +/**Function******************************************************************** + + Synopsis [Sample hook function to call after reordering.] + + Description [Sample hook function to call after reordering. + Prints on the manager's stdout final size and reordering time. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_StdPreReordHook] + +******************************************************************************/ +int +Cudd_StdPostReordHook( + DdManager *dd, + const char *str, + void *data) +{ + unsigned long initialTime = (long) data; + int retval; + unsigned long finalTime = util_cpu_time(); + double totalTimeSec = (double)(finalTime - initialTime) / 1000.0; + + retval = fprintf(dd->out,"%ld nodes in %g sec\n", strcmp(str, "BDD") == 0 ? + Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd), + totalTimeSec); + if (retval == EOF) return(0); + retval = fflush(dd->out); + if (retval == EOF) return(0); + return(1); + +} /* end of Cudd_StdPostReordHook */ + + +/**Function******************************************************************** + + Synopsis [Enables reporting of reordering stats.] + + Description [Enables reporting of reordering stats. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Installs functions in the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_DisableReorderingReporting Cudd_ReorderingReporting] + +******************************************************************************/ +int +Cudd_EnableReorderingReporting( + DdManager *dd) +{ + if (!Cudd_AddHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_EnableReorderingReporting */ + + +/**Function******************************************************************** + + Synopsis [Disables reporting of reordering stats.] + + Description [Disables reporting of reordering stats. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Removes functions from the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_EnableReorderingReporting Cudd_ReorderingReporting] + +******************************************************************************/ +int +Cudd_DisableReorderingReporting( + DdManager *dd) +{ + if (!Cudd_RemoveHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_DisableReorderingReporting */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if reporting of reordering stats is enabled.] + + Description [Returns 1 if reporting of reordering stats is enabled; + 0 otherwise.] + + SideEffects [none] + + SeeAlso [Cudd_EnableReorderingReporting Cudd_DisableReorderingReporting] + +******************************************************************************/ +int +Cudd_ReorderingReporting( + DdManager *dd) +{ + return(Cudd_IsInHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)); + +} /* end of Cudd_ReorderingReporting */ + + +/**Function******************************************************************** + + Synopsis [Hook function to print the current variable order.] + + Description [Hook function to print the current variable order. It may be + called before or after reordering. Prints on the manager's stdout a + parenthesized list that describes the variable groups. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_StdPreReordHook] + +******************************************************************************/ +int +Cudd_PrintGroupedOrder( + DdManager * dd, + const char *str, + void *data) +{ + int isBdd = strcmp(str, "ZDD"); + MtrNode *tree = isBdd ? dd->tree : dd->treeZ; + int *invperm = isBdd ? dd->invperm : dd->invpermZ; + int size = isBdd ? dd->size : dd->sizeZ; + if (tree == NULL) { + int i, retval; + for (i=0; i < size; i++) { + retval = fprintf(dd->out, "%c%d", i==0 ? '(' : ',', invperm[i]); + if (retval == EOF) return(0); + } + retval = fprintf(dd->out,")\n"); + return (retval != EOF); + } else { + return Mtr_PrintGroupedOrder(tree,invperm,dd->out); + } + +} /* end of Cudd_PrintGroupedOrder */ + + +/**Function******************************************************************** + + Synopsis [Enables monitoring of ordering.] + + Description [Enables monitoring of ordering. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Installs functions in the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_EnableReorderingReporting] + +******************************************************************************/ +int +Cudd_EnableOrderingMonitoring( + DdManager *dd) +{ + if (!Cudd_AddHook(dd, Cudd_PrintGroupedOrder, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_PrintGroupedOrder, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_EnableOrderingMonitoring */ + + +/**Function******************************************************************** + + Synopsis [Disables monitoring of ordering.] + + Description [Disables monitoring of ordering. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Removes functions from the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_EnableOrderingMonitoring] + +******************************************************************************/ +int +Cudd_DisableOrderingMonitoring( + DdManager *dd) +{ + if (!Cudd_RemoveHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_PrintGroupedOrder, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_PrintGroupedOrder, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_DisableOrderingMonitoring */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if monitoring of ordering is enabled.] + + Description [Returns 1 if monitoring of ordering is enabled; + 0 otherwise.] + + SideEffects [none] + + SeeAlso [Cudd_EnableOrderingMonitoring Cudd_DisableOrderingMonitoring] + +******************************************************************************/ +int +Cudd_OrderingMonitoring( + DdManager *dd) +{ + return(Cudd_IsInHook(dd, Cudd_PrintGroupedOrder, CUDD_PRE_REORDERING_HOOK)); + +} /* end of Cudd_OrderingMonitoring */ + + +/**Function******************************************************************** + + Synopsis [Returns the code of the last error.] + + Description [Returns the code of the last error. The error codes are + defined in cudd.h.] + + SideEffects [None] + + SeeAlso [Cudd_ClearErrorCode] + +******************************************************************************/ +Cudd_ErrorType +Cudd_ReadErrorCode( + DdManager *dd) +{ + return(dd->errorCode); + +} /* end of Cudd_ReadErrorCode */ + + +/**Function******************************************************************** + + Synopsis [Clear the error code of a manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadErrorCode] + +******************************************************************************/ +void +Cudd_ClearErrorCode( + DdManager *dd) +{ + dd->errorCode = CUDD_NO_ERROR; + +} /* end of Cudd_ClearErrorCode */ + + +/**Function******************************************************************** + + Synopsis [Reads the stdout of a manager.] + + Description [Reads the stdout of a manager. This is the file pointer to + which messages normally going to stdout are written. It is initialized + to stdout. Cudd_SetStdout allows the application to redirect it.] + + SideEffects [None] + + SeeAlso [Cudd_SetStdout Cudd_ReadStderr] + +******************************************************************************/ +FILE * +Cudd_ReadStdout( + DdManager *dd) +{ + return(dd->out); + +} /* end of Cudd_ReadStdout */ + + +/**Function******************************************************************** + + Synopsis [Sets the stdout of a manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadStdout Cudd_SetStderr] + +******************************************************************************/ +void +Cudd_SetStdout( + DdManager *dd, + FILE *fp) +{ + dd->out = fp; + +} /* end of Cudd_SetStdout */ + + +/**Function******************************************************************** + + Synopsis [Reads the stderr of a manager.] + + Description [Reads the stderr of a manager. This is the file pointer to + which messages normally going to stderr are written. It is initialized + to stderr. Cudd_SetStderr allows the application to redirect it.] + + SideEffects [None] + + SeeAlso [Cudd_SetStderr Cudd_ReadStdout] + +******************************************************************************/ +FILE * +Cudd_ReadStderr( + DdManager *dd) +{ + return(dd->err); + +} /* end of Cudd_ReadStderr */ + + +/**Function******************************************************************** + + Synopsis [Sets the stderr of a manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadStderr Cudd_SetStdout] + +******************************************************************************/ +void +Cudd_SetStderr( + DdManager *dd, + FILE *fp) +{ + dd->err = fp; + +} /* end of Cudd_SetStderr */ + + +/**Function******************************************************************** + + Synopsis [Returns the threshold for the next dynamic reordering.] + + Description [Returns the threshold for the next dynamic reordering. + The threshold is in terms of number of nodes and is in effect only + if reordering is enabled. The count does not include the dead nodes, + unless the countDead parameter of the manager has been changed from + its default setting.] + + SideEffects [None] + + SeeAlso [Cudd_SetNextReordering] + +******************************************************************************/ +unsigned int +Cudd_ReadNextReordering( + DdManager *dd) +{ + return(dd->nextDyn); + +} /* end of Cudd_ReadNextReordering */ + + +/**Function******************************************************************** + + Synopsis [Sets the threshold for the next dynamic reordering.] + + Description [Sets the threshold for the next dynamic reordering. + The threshold is in terms of number of nodes and is in effect only + if reordering is enabled. The count does not include the dead nodes, + unless the countDead parameter of the manager has been changed from + its default setting.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNextReordering] + +******************************************************************************/ +void +Cudd_SetNextReordering( + DdManager *dd, + unsigned int next) +{ + dd->nextDyn = next; + +} /* end of Cudd_SetNextReordering */ + + +/**Function******************************************************************** + + Synopsis [Reads the number of elementary reordering steps.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +double +Cudd_ReadSwapSteps( + DdManager *dd) +{ +#ifdef DD_COUNT + return(dd->swapSteps); +#else + return(-1); +#endif + +} /* end of Cudd_ReadSwapSteps */ + + +/**Function******************************************************************** + + Synopsis [Reads the maximum allowed number of live nodes.] + + Description [Reads the maximum allowed number of live nodes. When this + number is exceeded, the package returns NULL.] + + SideEffects [none] + + SeeAlso [Cudd_SetMaxLive] + +******************************************************************************/ +unsigned int +Cudd_ReadMaxLive( + DdManager *dd) +{ + return(dd->maxLive); + +} /* end of Cudd_ReadMaxLive */ + + +/**Function******************************************************************** + + Synopsis [Sets the maximum allowed number of live nodes.] + + Description [Sets the maximum allowed number of live nodes. When this + number is exceeded, the package returns NULL.] + + SideEffects [none] + + SeeAlso [Cudd_ReadMaxLive] + +******************************************************************************/ +void +Cudd_SetMaxLive( + DdManager *dd, + unsigned int maxLive) +{ + dd->maxLive = maxLive; + +} /* end of Cudd_SetMaxLive */ + + +/**Function******************************************************************** + + Synopsis [Reads the maximum allowed memory.] + + Description [Reads the maximum allowed memory. When this + number is exceeded, the package returns NULL.] + + SideEffects [none] + + SeeAlso [Cudd_SetMaxMemory] + +******************************************************************************/ +unsigned long +Cudd_ReadMaxMemory( + DdManager *dd) +{ + return(dd->maxmemhard); + +} /* end of Cudd_ReadMaxMemory */ + + +/**Function******************************************************************** + + Synopsis [Sets the maximum allowed memory.] + + Description [Sets the maximum allowed memory. When this + number is exceeded, the package returns NULL.] + + SideEffects [none] + + SeeAlso [Cudd_ReadMaxMemory] + +******************************************************************************/ +void +Cudd_SetMaxMemory( + DdManager *dd, + unsigned long maxMemory) +{ + dd->maxmemhard = maxMemory; + +} /* end of Cudd_SetMaxMemory */ + + +/**Function******************************************************************** + + Synopsis [Prevents sifting of a variable.] + + Description [This function sets a flag to prevent sifting of a + variable. Returns 1 if successful; 0 otherwise (i.e., invalid + variable index).] + + SideEffects [Changes the "bindVar" flag in DdSubtable.] + + SeeAlso [Cudd_bddUnbindVar] + +******************************************************************************/ +int +Cudd_bddBindVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].bindVar = 1; + return(1); + +} /* end of Cudd_bddBindVar */ + + +/**Function******************************************************************** + + Synopsis [Allows the sifting of a variable.] + + Description [This function resets the flag that prevents the sifting + of a variable. In successive variable reorderings, the variable will + NOT be skipped, that is, sifted. Initially all variables can be + sifted. It is necessary to call this function only to re-enable + sifting after a call to Cudd_bddBindVar. Returns 1 if successful; 0 + otherwise (i.e., invalid variable index).] + + SideEffects [Changes the "bindVar" flag in DdSubtable.] + + SeeAlso [Cudd_bddBindVar] + +******************************************************************************/ +int +Cudd_bddUnbindVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].bindVar = 0; + return(1); + +} /* end of Cudd_bddUnbindVar */ + + +/**Function******************************************************************** + + Synopsis [Tells whether a variable can be sifted.] + + Description [This function returns 1 if a variable is enabled for + sifting. Initially all variables can be sifted. This function returns + 0 only if there has been a previous call to Cudd_bddBindVar for that + variable not followed by a call to Cudd_bddUnbindVar. The function returns + 0 also in the case in which the index of the variable is out of bounds.] + + SideEffects [none] + + SeeAlso [Cudd_bddBindVar Cudd_bddUnbindVar] + +******************************************************************************/ +int +Cudd_bddVarIsBound( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return(0); + return(dd->subtables[dd->perm[index]].bindVar); + +} /* end of Cudd_bddVarIsBound */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable type to primary input.] + + Description [Sets a variable type to primary input. The variable type is + used by lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetPsVar Cudd_bddSetNsVar Cudd_bddIsPiVar] + +******************************************************************************/ +int +Cudd_bddSetPiVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return (0); + dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRIMARY_INPUT; + return(1); + +} /* end of Cudd_bddSetPiVar */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable type to present state.] + + Description [Sets a variable type to present state. The variable type is + used by lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetPiVar Cudd_bddSetNsVar Cudd_bddIsPsVar] + +******************************************************************************/ +int +Cudd_bddSetPsVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return (0); + dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRESENT_STATE; + return(1); + +} /* end of Cudd_bddSetPsVar */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable type to next state.] + + Description [Sets a variable type to next state. The variable type is + used by lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetPiVar Cudd_bddSetPsVar Cudd_bddIsNsVar] + +******************************************************************************/ +int +Cudd_bddSetNsVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return (0); + dd->subtables[dd->perm[index]].varType = CUDD_VAR_NEXT_STATE; + return(1); + +} /* end of Cudd_bddSetNsVar */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is primary input.] + + Description [Checks whether a variable is primary input. Returns 1 if + the variable's type is primary input; 0 if the variable exists but is + not a primary input; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetPiVar Cudd_bddIsPsVar Cudd_bddIsNsVar] + +******************************************************************************/ +int +Cudd_bddIsPiVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return -1; + return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRIMARY_INPUT); + +} /* end of Cudd_bddIsPiVar */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is present state.] + + Description [Checks whether a variable is present state. Returns 1 if + the variable's type is present state; 0 if the variable exists but is + not a present state; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetPsVar Cudd_bddIsPiVar Cudd_bddIsNsVar] + +******************************************************************************/ +int +Cudd_bddIsPsVar( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return -1; + return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRESENT_STATE); + +} /* end of Cudd_bddIsPsVar */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is next state.] + + Description [Checks whether a variable is next state. Returns 1 if + the variable's type is present state; 0 if the variable exists but is + not a present state; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetNsVar Cudd_bddIsPiVar Cudd_bddIsPsVar] + +******************************************************************************/ +int +Cudd_bddIsNsVar( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return -1; + return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_NEXT_STATE); + +} /* end of Cudd_bddIsNsVar */ + + +/**Function******************************************************************** + + Synopsis [Sets a corresponding pair index for a given index.] + + Description [Sets a corresponding pair index for a given index. + These pair indices are present and next state variable. Returns 1 if + successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddReadPairIndex] + +******************************************************************************/ +int +Cudd_bddSetPairIndex( + DdManager *dd /* manager */, + int index /* variable index */, + int pairIndex /* corresponding variable index */) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].pairIndex = pairIndex; + return(1); + +} /* end of Cudd_bddSetPairIndex */ + + +/**Function******************************************************************** + + Synopsis [Reads a corresponding pair index for a given index.] + + Description [Reads a corresponding pair index for a given index. + These pair indices are present and next state variable. Returns the + corresponding variable index if the variable exists; -1 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetPairIndex] + +******************************************************************************/ +int +Cudd_bddReadPairIndex( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return -1; + return dd->subtables[dd->perm[index]].pairIndex; + +} /* end of Cudd_bddReadPairIndex */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable to be grouped.] + + Description [Sets a variable to be grouped. This function is used for + lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetVarHardGroup Cudd_bddResetVarToBeGrouped] + +******************************************************************************/ +int +Cudd_bddSetVarToBeGrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + if (dd->subtables[dd->perm[index]].varToBeGrouped <= CUDD_LAZY_SOFT_GROUP) { + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_SOFT_GROUP; + } + return(1); + +} /* end of Cudd_bddSetVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable to be a hard group.] + + Description [Sets a variable to be a hard group. This function is used + for lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetVarToBeGrouped Cudd_bddResetVarToBeGrouped + Cudd_bddIsVarHardGroup] + +******************************************************************************/ +int +Cudd_bddSetVarHardGroup( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_HARD_GROUP; + return(1); + +} /* end of Cudd_bddSetVarHardGrouped */ + + +/**Function******************************************************************** + + Synopsis [Resets a variable not to be grouped.] + + Description [Resets a variable not to be grouped. This function is + used for lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetVarToBeGrouped Cudd_bddSetVarHardGroup] + +******************************************************************************/ +int +Cudd_bddResetVarToBeGrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + if (dd->subtables[dd->perm[index]].varToBeGrouped <= + CUDD_LAZY_SOFT_GROUP) { + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_NONE; + } + return(1); + +} /* end of Cudd_bddResetVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is set to be grouped.] + + Description [Checks whether a variable is set to be grouped. This + function is used for lazy sifting.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_bddIsVarToBeGrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(-1); + if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP) + return(0); + else + return(dd->subtables[dd->perm[index]].varToBeGrouped); + +} /* end of Cudd_bddIsVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable to be ungrouped.] + + Description [Sets a variable to be ungrouped. This function is used + for lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddIsVarToBeUngrouped] + +******************************************************************************/ +int +Cudd_bddSetVarToBeUngrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_UNGROUP; + return(1); + +} /* end of Cudd_bddSetVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is set to be ungrouped.] + + Description [Checks whether a variable is set to be ungrouped. This + function is used for lazy sifting. Returns 1 if the variable is marked + to be ungrouped; 0 if the variable exists, but it is not marked to be + ungrouped; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetVarToBeUngrouped] + +******************************************************************************/ +int +Cudd_bddIsVarToBeUngrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(-1); + return dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP; + +} /* end of Cudd_bddIsVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is set to be in a hard group.] + + Description [Checks whether a variable is set to be in a hard group. This + function is used for lazy sifting. Returns 1 if the variable is marked + to be in a hard group; 0 if the variable exists, but it is not marked to be + in a hard group; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetVarHardGroup] + +******************************************************************************/ +int +Cudd_bddIsVarHardGroup( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(-1); + if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_HARD_GROUP) + return(1); + return(0); + +} /* end of Cudd_bddIsVarToBeGrouped */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Fixes a variable group tree.] + + Description [] + + SideEffects [Changes the variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static void +fixVarTree( + MtrNode * treenode, + int * perm, + int size) +{ + treenode->index = treenode->low; + treenode->low = ((int) treenode->index < size) ? + perm[treenode->index] : treenode->index; + if (treenode->child != NULL) + fixVarTree(treenode->child, perm, size); + if (treenode->younger != NULL) + fixVarTree(treenode->younger, perm, size); + return; + +} /* end of fixVarTree */ + + +/**Function******************************************************************** + + Synopsis [Adds multiplicity groups to a ZDD variable group tree.] + + Description [Adds multiplicity groups to a ZDD variable group tree. + Returns 1 if successful; 0 otherwise. This function creates the groups + for set of ZDD variables (whose cardinality is given by parameter + multiplicity) that are created for each BDD variable in + Cudd_zddVarsFromBddVars. The crux of the matter is to determine the index + each new group. (The index of the first variable in the group.) + We first build all the groups for the children of a node, and then deal + with the ZDD variables that are directly attached to the node. The problem + for these is that the tree itself does not provide information on their + position inside the group. While we deal with the children of the node, + therefore, we keep track of all the positions they occupy. The remaining + positions in the tree can be freely used. Also, we keep track of all the + variables placed in the children. All the remaining variables are directly + attached to the group. We can then place any pair of variables not yet + grouped in any pair of available positions in the node.] + + SideEffects [Changes the variable group tree.] + + SeeAlso [Cudd_zddVarsFromBddVars] + +******************************************************************************/ +static int +addMultiplicityGroups( + DdManager *dd /* manager */, + MtrNode *treenode /* current tree node */, + int multiplicity /* how many ZDD vars per BDD var */, + char *vmask /* variable pairs for which a group has been already built */, + char *lmask /* levels for which a group has already been built*/) +{ + int startV, stopV, startL; + int i, j; + MtrNode *auxnode = treenode; + + while (auxnode != NULL) { + if (auxnode->child != NULL) { + addMultiplicityGroups(dd,auxnode->child,multiplicity,vmask,lmask); + } + /* Build remaining groups. */ + startV = dd->permZ[auxnode->index] / multiplicity; + startL = auxnode->low / multiplicity; + stopV = startV + auxnode->size / multiplicity; + /* Walk down vmask starting at startV and build missing groups. */ + for (i = startV, j = startL; i < stopV; i++) { + if (vmask[i] == 0) { + MtrNode *node; + while (lmask[j] == 1) j++; + node = Mtr_MakeGroup(auxnode, j * multiplicity, multiplicity, + MTR_FIXED); + if (node == NULL) { + return(0); + } + node->index = dd->invpermZ[i * multiplicity]; + vmask[i] = 1; + lmask[j] = 1; + } + } + auxnode = auxnode->younger; + } + return(1); + +} /* end of addMultiplicityGroups */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddAbs.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddAbs.c new file mode 100644 index 000000000..5e809c134 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddAbs.c @@ -0,0 +1,579 @@ +/**CFile*********************************************************************** + + FileName [cuddAddAbs.c] + + PackageName [cudd] + + Synopsis [Quantification functions for ADDs.] + + Description [External procedures included in this module: +
            +
          • Cudd_addExistAbstract() +
          • Cudd_addUnivAbstract() +
          • Cudd_addOrAbstract() +
          + Internal procedures included in this module: +
            +
          • cuddAddExistAbstractRecur() +
          • cuddAddUnivAbstractRecur() +
          • cuddAddOrAbstractRecur() +
          + Static procedures included in this module: +
            +
          • addCheckPositiveCube() +
          ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddAbs.c,v 1.16 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static DdNode *two; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int addCheckPositiveCube (DdManager *manager, DdNode *cube); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Existentially Abstracts all the variables in cube from f.] + + Description [Abstracts all the variables in cube from f by summing + over all possible values taken by the variables. Returns the + abstracted ADD.] + + SideEffects [None] + + SeeAlso [Cudd_addUnivAbstract Cudd_bddExistAbstract + Cudd_addOrAbstract] + +******************************************************************************/ +DdNode * +Cudd_addExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + two = cuddUniqueConst(manager,(CUDD_VALUE_TYPE) 2); + if (two == NULL) return(NULL); + cuddRef(two); + + if (addCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err,"Error: Can only abstract cubes"); + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddAddExistAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(manager,two); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,two); + cuddDeref(res); + + return(res); + +} /* end of Cudd_addExistAbstract */ + + +/**Function******************************************************************** + + Synopsis [Universally Abstracts all the variables in cube from f.] + + Description [Abstracts all the variables in cube from f by taking + the product over all possible values taken by the variable. Returns + the abstracted ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addExistAbstract Cudd_bddUnivAbstract + Cudd_addOrAbstract] + +******************************************************************************/ +DdNode * +Cudd_addUnivAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (addCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err,"Error: Can only abstract cubes"); + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddAddUnivAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_addUnivAbstract */ + + +/**Function******************************************************************** + + Synopsis [Disjunctively abstracts all the variables in cube from the + 0-1 ADD f.] + + Description [Abstracts all the variables in cube from the 0-1 ADD f + by taking the disjunction over all possible values taken by the + variables. Returns the abstracted ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addUnivAbstract Cudd_addExistAbstract] + +******************************************************************************/ +DdNode * +Cudd_addOrAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (addCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err,"Error: Can only abstract cubes"); + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddAddOrAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + return(res); + +} /* end of Cudd_addOrAbstract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addExistAbstract.] + + Description [Performs the recursive step of Cudd_addExistAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddAddExistAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *T, *E, *res, *res1, *res2, *zero; + + statLine(manager); + zero = DD_ZERO(manager); + + /* Cube is guaranteed to be a cube at this point. */ + if (f == zero || cuddIsConstant(cube)) { + return(f); + } + + /* Abstract a variable that does not appear in f => multiply by 2. */ + if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { + res1 = cuddAddExistAbstractRecur(manager, f, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + /* Use the "internal" procedure to be alerted in case of + ** dynamic reordering. If dynamic reordering occurs, we + ** have to abort the entire abstraction. + */ + res = cuddAddApplyRecur(manager,Cudd_addTimes,res1,two); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + cuddDeref(res); + return(res); + } + + if ((res = cuddCacheLookup2(manager, Cudd_addExistAbstract, f, cube)) != NULL) { + return(res); + } + + T = cuddT(f); + E = cuddE(f); + + /* If the two indices are the same, so are their levels. */ + if (f->index == cube->index) { + res1 = cuddAddExistAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddExistAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddAddApplyRecur(manager, Cudd_addPlus, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); + cuddDeref(res); + return(res); + } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ + res1 = cuddAddExistAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddExistAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); + return(res); + } + +} /* end of cuddAddExistAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addUnivAbstract.] + + Description [Performs the recursive step of Cudd_addUnivAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddAddUnivAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *T, *E, *res, *res1, *res2, *one, *zero; + + statLine(manager); + one = DD_ONE(manager); + zero = DD_ZERO(manager); + + /* Cube is guaranteed to be a cube at this point. + ** zero and one are the only constatnts c such that c*c=c. + */ + if (f == zero || f == one || cube == one) { + return(f); + } + + /* Abstract a variable that does not appear in f. */ + if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { + res1 = cuddAddUnivAbstractRecur(manager, f, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + /* Use the "internal" procedure to be alerted in case of + ** dynamic reordering. If dynamic reordering occurs, we + ** have to abort the entire abstraction. + */ + res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res1); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + cuddDeref(res); + return(res); + } + + if ((res = cuddCacheLookup2(manager, Cudd_addUnivAbstract, f, cube)) != NULL) { + return(res); + } + + T = cuddT(f); + E = cuddE(f); + + /* If the two indices are the same, so are their levels. */ + if (f->index == cube->index) { + res1 = cuddAddUnivAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddUnivAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); + cuddDeref(res); + return(res); + } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ + res1 = cuddAddUnivAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddUnivAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); + return(res); + } + +} /* end of cuddAddUnivAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addOrAbstract.] + + Description [Performs the recursive step of Cudd_addOrAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddAddOrAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *T, *E, *res, *res1, *res2, *one; + + statLine(manager); + one = DD_ONE(manager); + + /* Cube is guaranteed to be a cube at this point. */ + if (cuddIsConstant(f) || cube == one) { + return(f); + } + + /* Abstract a variable that does not appear in f. */ + if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { + res = cuddAddOrAbstractRecur(manager, f, cuddT(cube)); + return(res); + } + + if ((res = cuddCacheLookup2(manager, Cudd_addOrAbstract, f, cube)) != NULL) { + return(res); + } + + T = cuddT(f); + E = cuddE(f); + + /* If the two indices are the same, so are their levels. */ + if (f->index == cube->index) { + res1 = cuddAddOrAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + if (res1 != one) { + res2 = cuddAddOrAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddAddApplyRecur(manager, Cudd_addOr, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + } else { + res = res1; + } + cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); + cuddDeref(res); + return(res); + } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ + res1 = cuddAddOrAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddOrAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); + return(res); + } + +} /* end of cuddAddOrAbstractRecur */ + + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Checks whether cube is an ADD representing the product + of positive literals.] + + Description [Checks whether cube is an ADD representing the product of + positive literals. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +addCheckPositiveCube( + DdManager * manager, + DdNode * cube) +{ + if (Cudd_IsComplement(cube)) return(0); + if (cube == DD_ONE(manager)) return(1); + if (cuddIsConstant(cube)) return(0); + if (cuddE(cube) == DD_ZERO(manager)) { + return(addCheckPositiveCube(manager, cuddT(cube))); + } + return(0); + +} /* end of addCheckPositiveCube */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddApply.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddApply.c new file mode 100644 index 000000000..9a4d2179d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddApply.c @@ -0,0 +1,1121 @@ +/**CFile*********************************************************************** + + FileName [cuddAddApply.c] + + PackageName [cudd] + + Synopsis [Apply functions for ADDs and their operators.] + + Description [External procedures included in this module: +
            +
          • Cudd_addApply() +
          • Cudd_addMonadicApply() +
          • Cudd_addPlus() +
          • Cudd_addTimes() +
          • Cudd_addThreshold() +
          • Cudd_addSetNZ() +
          • Cudd_addDivide() +
          • Cudd_addMinus() +
          • Cudd_addMinimum() +
          • Cudd_addMaximum() +
          • Cudd_addOneZeroMaximum() +
          • Cudd_addDiff() +
          • Cudd_addAgreement() +
          • Cudd_addOr() +
          • Cudd_addNand() +
          • Cudd_addNor() +
          • Cudd_addXor() +
          • Cudd_addXnor() +
          + Internal procedures included in this module: +
            +
          • cuddAddApplyRecur() +
          • cuddAddMonadicApplyRecur() +
          ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.19 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Applies op to the corresponding discriminants of f and g.] + + Description [Applies op to the corresponding discriminants of f and g. + Returns a pointer to the result if succssful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addMonadicApply Cudd_addPlus Cudd_addTimes + Cudd_addThreshold Cudd_addSetNZ Cudd_addDivide Cudd_addMinus Cudd_addMinimum + Cudd_addMaximum Cudd_addOneZeroMaximum Cudd_addDiff Cudd_addAgreement + Cudd_addOr Cudd_addNand Cudd_addNor Cudd_addXor Cudd_addXnor] + +******************************************************************************/ +DdNode * +Cudd_addApply( + DdManager * dd, + DD_AOP op, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddApplyRecur(dd,op,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addApply */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point addition.] + + Description [Integer and floating point addition. Returns NULL if not + a terminal case; f+g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addPlus( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *res; + DdNode *F, *G; + CUDD_VALUE_TYPE value; + + F = *f; G = *g; + if (F == DD_ZERO(dd)) return(G); + if (G == DD_ZERO(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + value = cuddV(F)+cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); + } + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addPlus */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point multiplication.] + + Description [Integer and floating point multiplication. Returns NULL + if not a terminal case; f * g otherwise. This function can be used also + to take the AND of two 0-1 ADDs.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addTimes( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *res; + DdNode *F, *G; + CUDD_VALUE_TYPE value; + + F = *f; G = *g; + if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ZERO(dd)); + if (F == DD_ONE(dd)) return(G); + if (G == DD_ONE(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + value = cuddV(F)*cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); + } + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addTimes */ + + +/**Function******************************************************************** + + Synopsis [f if f>=g; 0 if f<g.] + + Description [Threshold operator for Apply (f if f >=g; 0 if f<g). + Returns NULL if not a terminal case; f op g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addThreshold( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G || F == DD_PLUS_INFINITY(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F) >= cuddV(G)) { + return(F); + } else { + return(DD_ZERO(dd)); + } + } + return(NULL); + +} /* end of Cudd_addThreshold */ + + +/**Function******************************************************************** + + Synopsis [This operator sets f to the value of g wherever g != 0.] + + Description [This operator sets f to the value of g wherever g != 0. + Returns NULL if not a terminal case; f op g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addSetNZ( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(F); + if (F == DD_ZERO(dd)) return(G); + if (G == DD_ZERO(dd)) return(F); + if (cuddIsConstant(G)) return(G); + return(NULL); + +} /* end of Cudd_addSetNZ */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point division.] + + Description [Integer and floating point division. Returns NULL if not + a terminal case; f / g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addDivide( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *res; + DdNode *F, *G; + CUDD_VALUE_TYPE value; + + F = *f; G = *g; + /* We would like to use F == G -> F/G == 1, but F and G may + ** contain zeroes. */ + if (F == DD_ZERO(dd)) return(DD_ZERO(dd)); + if (G == DD_ONE(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + value = cuddV(F)/cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); + } + return(NULL); + +} /* end of Cudd_addDivide */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point subtraction.] + + Description [Integer and floating point subtraction. Returns NULL if + not a terminal case; f - g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addMinus( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *res; + DdNode *F, *G; + CUDD_VALUE_TYPE value; + + F = *f; G = *g; + if (F == G) return(DD_ZERO(dd)); + if (F == DD_ZERO(dd)) return(cuddAddNegateRecur(dd,G)); + if (G == DD_ZERO(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + value = cuddV(F)-cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); + } + return(NULL); + +} /* end of Cudd_addMinus */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point min.] + + Description [Integer and floating point min for Cudd_addApply. + Returns NULL if not a terminal case; min(f,g) otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addMinimum( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == DD_PLUS_INFINITY(dd)) return(G); + if (G == DD_PLUS_INFINITY(dd)) return(F); + if (F == G) return(F); +#if 0 + /* These special cases probably do not pay off. */ + if (F == DD_MINUS_INFINITY(dd)) return(F); + if (G == DD_MINUS_INFINITY(dd)) return(G); +#endif + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F) <= cuddV(G)) { + return(F); + } else { + return(G); + } + } + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addMinimum */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point max.] + + Description [Integer and floating point max for Cudd_addApply. + Returns NULL if not a terminal case; max(f,g) otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addMaximum( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(F); + if (F == DD_MINUS_INFINITY(dd)) return(G); + if (G == DD_MINUS_INFINITY(dd)) return(F); +#if 0 + /* These special cases probably do not pay off. */ + if (F == DD_PLUS_INFINITY(dd)) return(F); + if (G == DD_PLUS_INFINITY(dd)) return(G); +#endif + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F) >= cuddV(G)) { + return(F); + } else { + return(G); + } + } + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addMaximum */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if f > g and 0 otherwise.] + + Description [Returns 1 if f > g and 0 otherwise. Used in + conjunction with Cudd_addApply. Returns NULL if not a terminal + case.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addOneZeroMaximum( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + + if (*f == *g) return(DD_ZERO(dd)); + if (*g == DD_PLUS_INFINITY(dd)) + return DD_ZERO(dd); + if (cuddIsConstant(*f) && cuddIsConstant(*g)) { + if (cuddV(*f) > cuddV(*g)) { + return(DD_ONE(dd)); + } else { + return(DD_ZERO(dd)); + } + } + + return(NULL); + +} /* end of Cudd_addOneZeroMaximum */ + + +/**Function******************************************************************** + + Synopsis [Returns plusinfinity if f=g; returns min(f,g) if f!=g.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is plusinfinity if f=g; min(f,g) if f!=g.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addDiff( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_PLUS_INFINITY(dd)); + if (F == DD_PLUS_INFINITY(dd)) return(G); + if (G == DD_PLUS_INFINITY(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F) != cuddV(G)) { + if (cuddV(F) < cuddV(G)) { + return(F); + } else { + return(G); + } + } else { + return(DD_PLUS_INFINITY(dd)); + } + } + return(NULL); + +} /* end of Cudd_addDiff */ + + +/**Function******************************************************************** + + Synopsis [f if f==g; background if f!=g.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is f if f==g; background if f!=g.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addAgreement( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(F); + if (F == dd->background) return(F); + if (G == dd->background) return(G); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(dd->background); + return(NULL); + +} /* end of Cudd_addAgreement */ + + +/**Function******************************************************************** + + Synopsis [Disjunction of two 0-1 ADDs.] + + Description [Disjunction of two 0-1 ADDs. Returns NULL + if not a terminal case; f OR g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addOr( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ONE(dd)); + if (cuddIsConstant(F)) return(G); + if (cuddIsConstant(G)) return(F); + if (F == G) return(F); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addOr */ + + +/**Function******************************************************************** + + Synopsis [NAND of two 0-1 ADDs.] + + Description [NAND of two 0-1 ADDs. Returns NULL + if not a terminal case; f NAND g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addNand( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addNand */ + + +/**Function******************************************************************** + + Synopsis [NOR of two 0-1 ADDs.] + + Description [NOR of two 0-1 ADDs. Returns NULL + if not a terminal case; f NOR g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addNor( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ZERO(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ONE(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addNor */ + + +/**Function******************************************************************** + + Synopsis [XOR of two 0-1 ADDs.] + + Description [XOR of two 0-1 ADDs. Returns NULL + if not a terminal case; f XOR g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addXor( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ZERO(dd)); + if (F == DD_ONE(dd) && G == DD_ZERO(dd)) return(DD_ONE(dd)); + if (G == DD_ONE(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addXor */ + + +/**Function******************************************************************** + + Synopsis [XNOR of two 0-1 ADDs.] + + Description [XNOR of two 0-1 ADDs. Returns NULL + if not a terminal case; f XNOR g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addXnor( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ONE(dd)); + if (F == DD_ONE(dd) && G == DD_ONE(dd)) return(DD_ONE(dd)); + if (G == DD_ZERO(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addXnor */ + + +/**Function******************************************************************** + + Synopsis [Applies op to the discriminants of f.] + + Description [Applies op to the discriminants of f. + Returns a pointer to the result if succssful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply Cudd_addLog] + +******************************************************************************/ +DdNode * +Cudd_addMonadicApply( + DdManager * dd, + DD_MAOP op, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddMonadicApplyRecur(dd,op,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addMonadicApply */ + + +/**Function******************************************************************** + + Synopsis [Natural logarithm of an ADD.] + + Description [Natural logarithm of an ADDs. Returns NULL + if not a terminal case; log(f) otherwise. The discriminants of f must + be positive double's.] + + SideEffects [None] + + SeeAlso [Cudd_addMonadicApply] + +******************************************************************************/ +DdNode * +Cudd_addLog( + DdManager * dd, + DdNode * f) +{ + if (cuddIsConstant(f)) { + CUDD_VALUE_TYPE value = log(cuddV(f)); + DdNode *res = cuddUniqueConst(dd,value); + return(res); + } + return(NULL); + +} /* end of Cudd_addLog */ + +/**Function******************************************************************** + + Synopsis [1 if f==g; 0 otherwise.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is 1 if f==g; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addEquals( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addEquals */ + + +/**Function******************************************************************** + + Synopsis [1 if f!=g; 0 otherwise.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is 1 if f!=g; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addNotEquals( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ZERO(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ONE(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addNotEquals */ + +/**Function******************************************************************** + + Synopsis [1 if f>g; 0 otherwise.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is 1 if f>g; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addGreaterThan( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ZERO(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F)>cuddV(G)) return (DD_ONE(dd)); else return (DD_ZERO(dd)); + } + return(NULL); + +} /* end of Cudd_addGreaterThan */ + + +/**Function******************************************************************** + + Synopsis [1 if f>=g; 0 otherwise.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is 1 if f>=g; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addGreaterThanEquals( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F)>=cuddV(G)) return (DD_ONE(dd)); else return (DD_ZERO(dd)); + } + return(NULL); + +} /* end of Cudd_addGreaterThanEquals */ + + +/**Function******************************************************************** + + Synopsis [1 if findex); + gord = cuddI(dd,g->index); + if (ford <= gord) { + index = f->index; + fv = cuddT(f); + fvn = cuddE(f); + } else { + index = g->index; + fv = fvn = f; + } + if (gord <= ford) { + gv = cuddT(g); + gvn = cuddE(g); + } else { + gv = gvn = g; + } + + T = cuddAddApplyRecur(dd,op,fv,gv); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddApplyRecur(dd,op,fvn,gvn); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + + res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,cacheOp,f,g,res); + + return(res); + +} /* end of cuddAddApplyRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addMonadicApply.] + + Description [Performs the recursive step of Cudd_addMonadicApply. Returns a + pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddAddApplyRecur] + +******************************************************************************/ +DdNode * +cuddAddMonadicApplyRecur( + DdManager * dd, + DD_MAOP op, + DdNode * f) +{ + DdNode *res, *ft, *fe, *T, *E; + unsigned int index; + + /* Check terminal cases. */ + statLine(dd); + res = (*op)(dd,f); + if (res != NULL) return(res); + + /* Check cache. */ + res = cuddCacheLookup1(dd,op,f); + if (res != NULL) return(res); + + /* Recursive step. */ + index = f->index; + ft = cuddT(f); + fe = cuddE(f); + + T = cuddAddMonadicApplyRecur(dd,op,ft); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddMonadicApplyRecur(dd,op,fe); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + + res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,op,f,res); + + return(res); + +} /* end of cuddAddMonadicApplyRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddFind.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddFind.c new file mode 100644 index 000000000..1352a87ff --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddFind.c @@ -0,0 +1,316 @@ +/**CFile*********************************************************************** + + FileName [cuddAddFind.c] + + PackageName [cudd] + + Synopsis [Functions to find maximum and minimum in an ADD and to + extract the i-th bit.] + + Description [External procedures included in this module: +
            +
          • Cudd_addFindMax() +
          • Cudd_addFindMin() +
          • Cudd_addIthBit() +
          + Static functions included in this module: +
            +
          • addDoIthBit() +
          ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.9 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addDoIthBit (DdManager *dd, DdNode *f, DdNode *index); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Finds the maximum discriminant of f.] + + Description [Returns a pointer to a constant ADD.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addFindMax( + DdManager * dd, + DdNode * f) +{ + DdNode *t, *e, *res; + + statLine(dd); + if (cuddIsConstant(f)) { + return(f); + } + + res = cuddCacheLookup1(dd,Cudd_addFindMax,f); + if (res != NULL) { + return(res); + } + + t = Cudd_addFindMax(dd,cuddT(f)); + if (t == DD_PLUS_INFINITY(dd)) return(t); + + e = Cudd_addFindMax(dd,cuddE(f)); + + res = (cuddV(t) >= cuddV(e)) ? t : e; + + cuddCacheInsert1(dd,Cudd_addFindMax,f,res); + + return(res); + +} /* end of Cudd_addFindMax */ + + +/**Function******************************************************************** + + Synopsis [Finds the minimum discriminant of f.] + + Description [Returns a pointer to a constant ADD.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addFindMin( + DdManager * dd, + DdNode * f) +{ + DdNode *t, *e, *res; + + statLine(dd); + if (cuddIsConstant(f)) { + return(f); + } + + res = cuddCacheLookup1(dd,Cudd_addFindMin,f); + if (res != NULL) { + return(res); + } + + t = Cudd_addFindMin(dd,cuddT(f)); + if (t == DD_MINUS_INFINITY(dd)) return(t); + + e = Cudd_addFindMin(dd,cuddE(f)); + + res = (cuddV(t) <= cuddV(e)) ? t : e; + + cuddCacheInsert1(dd,Cudd_addFindMin,f,res); + + return(res); + +} /* end of Cudd_addFindMin */ + + +/**Function******************************************************************** + + Synopsis [Extracts the i-th bit from an ADD.] + + Description [Produces an ADD from another ADD by replacing all + discriminants whose i-th bit is equal to 1 with 1, and all other + discriminants with 0. The i-th bit refers to the integer + representation of the leaf value. If the value is has a fractional + part, it is ignored. Repeated calls to this procedure allow one to + transform an integer-valued ADD into an array of ADDs, one for each + bit of the leaf values. Returns a pointer to the resulting ADD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddIthBit] + +******************************************************************************/ +DdNode * +Cudd_addIthBit( + DdManager * dd, + DdNode * f, + int bit) +{ + DdNode *res; + DdNode *index; + + /* Use a constant node to remember the bit, so that we can use the + ** global cache. + */ + index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit); + if (index == NULL) return(NULL); + cuddRef(index); + + do { + dd->reordered = 0; + res = addDoIthBit(dd, f, index); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, index); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, index); + cuddDeref(res); + return(res); + +} /* end of Cudd_addIthBit */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addIthBit.] + + Description [Performs the recursive step for Cudd_addIthBit. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +addDoIthBit( + DdManager * dd, + DdNode * f, + DdNode * index) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int mask, value; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + mask = 1 << ((int) cuddV(index)); + value = (int) cuddV(f); + return((value & mask) == 0 ? DD_ZERO(dd) : DD_ONE(dd)); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addDoIthBit,f,index); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addDoIthBit(dd,fv,index); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addDoIthBit(dd,fvn,index); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addDoIthBit,f,index,res); + + return(res); + +} /* end of addDoIthBit */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddInv.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddInv.c new file mode 100644 index 000000000..454aa811d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddInv.c @@ -0,0 +1,201 @@ +/**CFile*********************************************************************** + + FileName [cuddAddInv.c] + + PackageName [cudd] + + Synopsis [Function to compute the scalar inverse of an ADD.] + + Description [External procedures included in this module: +
            +
          • Cudd_addScalarInverse() +
          + Internal procedures included in this module: +
            +
          • cuddAddScalarInverseRecur() +
          ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddInv.c,v 1.10 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the scalar inverse of an ADD.] + + Description [Computes an n ADD where the discriminants are the + multiplicative inverses of the corresponding discriminants of the + argument ADD. Returns a pointer to the resulting ADD in case of + success. Returns NULL if any discriminants smaller than epsilon is + encountered.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addScalarInverse( + DdManager * dd, + DdNode * f, + DdNode * epsilon) +{ + DdNode *res; + + if (!cuddIsConstant(epsilon)) { + (void) fprintf(dd->err,"Invalid epsilon\n"); + return(NULL); + } + do { + dd->reordered = 0; + res = cuddAddScalarInverseRecur(dd,f,epsilon); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addScalarInverse */ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of addScalarInverse.] + + Description [Returns a pointer to the resulting ADD in case of + success. Returns NULL if any discriminants smaller than epsilon is + encountered.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddAddScalarInverseRecur( + DdManager * dd, + DdNode * f, + DdNode * epsilon) +{ + DdNode *t, *e, *res; + CUDD_VALUE_TYPE value; + + statLine(dd); + if (cuddIsConstant(f)) { + if (ddAbs(cuddV(f)) < cuddV(epsilon)) return(NULL); + value = 1.0 / cuddV(f); + res = cuddUniqueConst(dd,value); + return(res); + } + + res = cuddCacheLookup2(dd,Cudd_addScalarInverse,f,epsilon); + if (res != NULL) return(res); + + t = cuddAddScalarInverseRecur(dd,cuddT(f),epsilon); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddAddScalarInverseRecur(dd,cuddE(f),epsilon); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + res = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd,Cudd_addScalarInverse,f,epsilon,res); + + return(res); + +} /* end of cuddAddScalarInverseRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddIte.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddIte.c new file mode 100644 index 000000000..a6e84c54c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddIte.c @@ -0,0 +1,639 @@ +/**CFile*********************************************************************** + + FileName [cuddAddIte.c] + + PackageName [cudd] + + Synopsis [ADD ITE function and satellites.] + + Description [External procedures included in this module: +
            +
          • Cudd_addIte() +
          • Cudd_addIteConstant() +
          • Cudd_addEvalConst() +
          • Cudd_addCmpl() +
          • Cudd_addLeq() +
          + Internal procedures included in this module: +
            +
          • cuddAddIteRecur() +
          • cuddAddCmplRecur() +
          + Static procedures included in this module: +
            +
          • addVarToConst() +
          ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.16 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void addVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements ITE(f,g,h).] + + Description [Implements ITE(f,g,h). This procedure assumes that f is + a 0-1 ADD. Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addIteConstant Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddIteRecur(dd,f,g,h); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addIte */ + + +/**Function******************************************************************** + + Synopsis [Implements ITEconstant for ADDs.] + + Description [Implements ITEconstant for ADDs. f must be a 0-1 ADD. + Returns a pointer to the resulting ADD (which may or may not be + constant) or DD_NON_CONSTANT. No new nodes are created. This function + can be used, for instance, to check that g has a constant value + (specified by h) whenever f is 1. If the constant value is unknown, + then one should use Cudd_addEvalConst.] + + SideEffects [None] + + SeeAlso [Cudd_addIte Cudd_addEvalConst Cudd_bddIteConstant] + +******************************************************************************/ +DdNode * +Cudd_addIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *one,*zero; + DdNode *Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*r,*t,*e; + unsigned int topf,topg,toph,v; + + statLine(dd); + /* Trivial cases. */ + if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ + return(g); + } + if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ + return(h); + } + + /* From now on, f is known not to be a constant. */ + addVarToConst(f,&g,&h,one,zero); + + /* Check remaining one variable cases. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } + if (cuddIsConstant(g) && cuddIsConstant(h)) { + return(DD_NON_CONSTANT); + } + + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + toph = cuddI(dd,h->index); + v = ddMin(topg,toph); + + /* ITE(F,G,H) = (x,G,H) (non constant) if F = (x,1,0), x < top(G,H). */ + if (topf < v && cuddIsConstant(cuddT(f)) && cuddIsConstant(cuddE(f))) { + return(DD_NON_CONSTANT); + } + + /* Check cache. */ + r = cuddConstantLookup(dd,DD_ADD_ITE_CONSTANT_TAG,f,g,h); + if (r != NULL) { + return(r); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf,v); /* v = top_var(F,G,H) */ + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg == v) { + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + if (toph == v) { + Hv = cuddT(h); Hnv = cuddE(h); + } else { + Hv = Hnv = h; + } + + /* Recursive step. */ + t = Cudd_addIteConstant(dd,Fv,Gv,Hv); + if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + e = Cudd_addIteConstant(dd,Fnv,Gnv,Hnv); + if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, t); + return(t); + +} /* end of Cudd_addIteConstant */ + + +/**Function******************************************************************** + + Synopsis [Checks whether ADD g is constant whenever ADD f is 1.] + + Description [Checks whether ADD g is constant whenever ADD f is 1. f + must be a 0-1 ADD. Returns a pointer to the resulting ADD (which may + or may not be constant) or DD_NON_CONSTANT. If f is identically 0, + the check is assumed to be successful, and the background value is + returned. No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_addIteConstant Cudd_addLeq] + +******************************************************************************/ +DdNode * +Cudd_addEvalConst( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *zero; + DdNode *Fv,*Fnv,*Gv,*Gnv,*r,*t,*e; + unsigned int topf,topg; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + statLine(dd); + /* Terminal cases. */ + if (f == DD_ONE(dd) || cuddIsConstant(g)) { + return(g); + } + if (f == (zero = DD_ZERO(dd))) { + return(dd->background); + } + +#ifdef DD_DEBUG + assert(!cuddIsConstant(f)); +#endif + /* From now on, f and g are known not to be constants. */ + + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + + /* Check cache. */ + r = cuddConstantLookup(dd,DD_ADD_EVAL_CONST_TAG,f,g,g); + if (r != NULL) { + return(r); + } + + /* Compute cofactors. */ + if (topf <= topg) { + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg <= topf) { + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + + /* Recursive step. */ + if (Fv != zero) { + t = Cudd_addEvalConst(dd,Fv,Gv); + if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + if (Fnv != zero) { + e = Cudd_addEvalConst(dd,Fnv,Gnv); + if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + } + cuddCacheInsert2(dd,Cudd_addEvalConst,f,g,t); + return(t); + } else { /* Fnv must be != zero */ + e = Cudd_addEvalConst(dd,Fnv,Gnv); + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e); + return(e); + } + +} /* end of Cudd_addEvalConst */ + + +/**Function******************************************************************** + + Synopsis [Computes the complement of an ADD a la C language.] + + Description [Computes the complement of an ADD a la C language: The + complement of 0 is 1 and the complement of everything else is 0. + Returns a pointer to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNegate] + +******************************************************************************/ +DdNode * +Cudd_addCmpl( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddCmplRecur(dd,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addCmpl */ + + +/**Function******************************************************************** + + Synopsis [Determines whether f is less than or equal to g.] + + Description [Returns 1 if f is less than or equal to g; 0 otherwise. + No new nodes are created. This procedure works for arbitrary ADDs. + For 0-1 ADDs Cudd_addEvalConst is more efficient.] + + SideEffects [None] + + SeeAlso [Cudd_addIteConstant Cudd_addEvalConst Cudd_bddLeq] + +******************************************************************************/ +int +Cudd_addLeq( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *tmp, *fv, *fvn, *gv, *gvn; + unsigned int topf, topg, res; + + /* Terminal cases. */ + if (f == g) return(1); + + statLine(dd); + if (cuddIsConstant(f)) { + if (cuddIsConstant(g)) return(cuddV(f) <= cuddV(g)); + if (f == DD_MINUS_INFINITY(dd)) return(1); + if (f == DD_PLUS_INFINITY(dd)) return(0); /* since f != g */ + } + if (g == DD_PLUS_INFINITY(dd)) return(1); + if (g == DD_MINUS_INFINITY(dd)) return(0); /* since f != g */ + + /* Check cache. */ + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq,f,g); + if (tmp != NULL) { + return(tmp == DD_ONE(dd)); + } + + /* Compute cofactors. One of f and g is not constant. */ + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + if (topf <= topg) { + fv = cuddT(f); fvn = cuddE(f); + } else { + fv = fvn = f; + } + if (topg <= topf) { + gv = cuddT(g); gvn = cuddE(g); + } else { + gv = gvn = g; + } + + res = Cudd_addLeq(dd,fvn,gvn) && Cudd_addLeq(dd,fv,gv); + + /* Store result in cache and return. */ + cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq,f,g, + Cudd_NotCond(DD_ONE(dd),res==0)); + return(res); + +} /* end of Cudd_addLeq */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addIte(f,g,h).] + + Description [Implements the recursive step of Cudd_addIte(f,g,h). + Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addIte] + +******************************************************************************/ +DdNode * +cuddAddIteRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *one,*zero; + DdNode *r,*Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*t,*e; + unsigned int topf,topg,toph,v; + int index; + + statLine(dd); + /* Trivial cases. */ + + /* One variable cases. */ + if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ + return(g); + } + if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ + return(h); + } + + /* From now on, f is known to not be a constant. */ + addVarToConst(f,&g,&h,one,zero); + + /* Check remaining one variable cases. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } + + if (g == one) { /* ITE(F,1,0) = F */ + if (h == zero) return(f); + } + + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + toph = cuddI(dd,h->index); + v = ddMin(topg,toph); + + /* A shortcut: ITE(F,G,H) = (x,G,H) if F=(x,1,0), x < top(G,H). */ + if (topf < v && cuddT(f) == one && cuddE(f) == zero) { + r = cuddUniqueInter(dd,(int)f->index,g,h); + return(r); + } + if (topf < v && cuddT(f) == zero && cuddE(f) == one) { + r = cuddUniqueInter(dd,(int)f->index,h,g); + return(r); + } + + /* Check cache. */ + r = cuddCacheLookup(dd,DD_ADD_ITE_TAG,f,g,h); + if (r != NULL) { + return(r); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf,v); /* v = top_var(F,G,H) */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg == v) { + index = g->index; + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + if (toph == v) { + index = h->index; + Hv = cuddT(h); Hnv = cuddE(h); + } else { + Hv = Hnv = h; + } + + /* Recursive step. */ + t = cuddAddIteRecur(dd,Fv,Gv,Hv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddAddIteRecur(dd,Fnv,Gnv,Hnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert(dd,DD_ADD_ITE_TAG,f,g,h,r); + + return(r); + +} /* end of cuddAddIteRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addCmpl.] + + Description [Performs the recursive step of Cudd_addCmpl. Returns a + pointer to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCmpl] + +******************************************************************************/ +DdNode * +cuddAddCmplRecur( + DdManager * dd, + DdNode * f) +{ + DdNode *one,*zero; + DdNode *r,*Fv,*Fnv,*t,*e; + + statLine(dd); + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + if (cuddIsConstant(f)) { + if (f == zero) { + return(one); + } else { + return(zero); + } + } + r = cuddCacheLookup1(dd,Cudd_addCmpl,f); + if (r != NULL) { + return(r); + } + Fv = cuddT(f); + Fnv = cuddE(f); + t = cuddAddCmplRecur(dd,Fv); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddAddCmplRecur(dd,Fnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + r = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + cuddCacheInsert1(dd,Cudd_addCmpl,f,r); + return(r); + +} /* end of cuddAddCmplRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Replaces variables with constants if possible (part of + canonical form).] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static void +addVarToConst( + DdNode * f, + DdNode ** gp, + DdNode ** hp, + DdNode * one, + DdNode * zero) +{ + DdNode *g = *gp; + DdNode *h = *hp; + + if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + *gp = one; + } + + if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + *hp = zero; + } + +} /* end of addVarToConst */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddNeg.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddNeg.c new file mode 100644 index 000000000..92c1cd71f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddNeg.c @@ -0,0 +1,290 @@ +/**CFile*********************************************************************** + + FileName [cuddAddNeg.c] + + PackageName [cudd] + + Synopsis [Function to compute the negation of an ADD.] + + Description [External procedures included in this module: +
            +
          • Cudd_addNegate() +
          • Cudd_addRoundOff() +
          + Internal procedures included in this module: +
            +
          • cuddAddNegateRecur() +
          • cuddAddRoundOffRecur() +
          ] + + Author [Fabio Somenzi, Balakrishna Kumthekar] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddNeg.c,v 1.14 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Computes the additive inverse of an ADD.] + + Description [Computes the additive inverse of an ADD. Returns a pointer + to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCmpl] + +******************************************************************************/ +DdNode * +Cudd_addNegate( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddNegateRecur(dd,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addNegate */ + + +/**Function******************************************************************** + + Synopsis [Rounds off the discriminants of an ADD.] + + Description [Rounds off the discriminants of an ADD. The discriminants are + rounded off to N digits after the decimal. Returns a pointer to the result + ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addRoundOff( + DdManager * dd, + DdNode * f, + int N) +{ + DdNode *res; + double trunc = pow(10.0,(double)N); + + do { + dd->reordered = 0; + res = cuddAddRoundOffRecur(dd,f,trunc); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addRoundOff */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addNegate.] + + Description [Implements the recursive step of Cudd_addNegate. + Returns a pointer to the result.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddAddNegateRecur( + DdManager * dd, + DdNode * f) +{ + DdNode *res, + *fv, *fvn, + *T, *E; + + statLine(dd); + /* Check terminal cases. */ + if (cuddIsConstant(f)) { + res = cuddUniqueConst(dd,-cuddV(f)); + return(res); + } + + /* Check cache */ + res = cuddCacheLookup1(dd,Cudd_addNegate,f); + if (res != NULL) return(res); + + /* Recursive Step */ + fv = cuddT(f); + fvn = cuddE(f); + T = cuddAddNegateRecur(dd,fv); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddNegateRecur(dd,fvn); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,Cudd_addNegate,f,res); + + return(res); + +} /* end of cuddAddNegateRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addRoundOff.] + + Description [Implements the recursive step of Cudd_addRoundOff. + Returns a pointer to the result.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddAddRoundOffRecur( + DdManager * dd, + DdNode * f, + double trunc) +{ + + DdNode *res, *fv, *fvn, *T, *E; + double n; + DD_CTFP1 cacheOp; + + statLine(dd); + if (cuddIsConstant(f)) { + n = ceil(cuddV(f)*trunc)/trunc; + res = cuddUniqueConst(dd,n); + return(res); + } + cacheOp = (DD_CTFP1) Cudd_addRoundOff; + res = cuddCacheLookup1(dd,cacheOp,f); + if (res != NULL) { + return(res); + } + /* Recursive Step */ + fv = cuddT(f); + fvn = cuddE(f); + T = cuddAddRoundOffRecur(dd,fv,trunc); + if (T == NULL) { + return(NULL); + } + cuddRef(T); + E = cuddAddRoundOffRecur(dd,fvn,trunc); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,cacheOp,f,res); + return(res); + +} /* end of cuddAddRoundOffRecur */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAddWalsh.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddWalsh.c new file mode 100644 index 000000000..146b1d313 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAddWalsh.c @@ -0,0 +1,391 @@ +/**CFile*********************************************************************** + + FileName [cuddAddWalsh.c] + + PackageName [cudd] + + Synopsis [Functions that generate Walsh matrices and residue + functions in ADD form.] + + Description [External procedures included in this module: +
            +
          • Cudd_addWalsh() +
          • Cudd_addResidue() +
          + Static procedures included in this module: +
            +
          • addWalshInt() +
          ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddWalsh.c,v 1.11 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addWalshInt (DdManager *dd, DdNode **x, DdNode **y, int n); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Generates a Walsh matrix in ADD form.] + + Description [Generates a Walsh matrix in ADD form. Returns a pointer + to the matrixi if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addWalsh( + DdManager * dd, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = addWalshInt(dd, x, y, n); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addWalsh */ + + +/**Function******************************************************************** + + Synopsis [Builds an ADD for the residue modulo m of an n-bit + number.] + + Description [Builds an ADD for the residue modulo m of an n-bit + number. The modulus must be at least 2, and the number of bits at + least 1. Parameter options specifies whether the MSB should be on top + or the LSB; and whther the number whose residue is computed is in + two's complement notation or not. The macro CUDD_RESIDUE_DEFAULT + specifies LSB on top and unsigned number. The macro CUDD_RESIDUE_MSB + specifies MSB on top, and the macro CUDD_RESIDUE_TC specifies two's + complement residue. To request MSB on top and two's complement residue + simultaneously, one can OR the two macros: + CUDD_RESIDUE_MSB | CUDD_RESIDUE_TC. + Cudd_addResidue returns a pointer to the resulting ADD if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addResidue( + DdManager * dd /* manager */, + int n /* number of bits */, + int m /* modulus */, + int options /* options */, + int top /* index of top variable */) +{ + int msbLsb; /* MSB on top (1) or LSB on top (0) */ + int tc; /* two's complement (1) or unsigned (0) */ + int i, j, k, t, residue, thisOne, previous, index; + DdNode **array[2], *var, *tmp, *res; + + /* Sanity check. */ + if (n < 1 && m < 2) return(NULL); + + msbLsb = options & CUDD_RESIDUE_MSB; + tc = options & CUDD_RESIDUE_TC; + + /* Allocate and initialize working arrays. */ + array[0] = ALLOC(DdNode *,m); + if (array[0] == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + array[1] = ALLOC(DdNode *,m); + if (array[1] == NULL) { + FREE(array[0]); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < m; i++) { + array[0][i] = array[1][i] = NULL; + } + + /* Initialize residues. */ + for (i = 0; i < m; i++) { + tmp = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) i); + if (tmp == NULL) { + for (j = 0; j < i; j++) { + Cudd_RecursiveDeref(dd,array[1][j]); + } + FREE(array[0]); + FREE(array[1]); + return(NULL); + } + cuddRef(tmp); + array[1][i] = tmp; + } + + /* Main iteration. */ + residue = 1; /* residue of 2**0 */ + for (k = 0; k < n; k++) { + /* Choose current and previous arrays. */ + thisOne = k & 1; + previous = thisOne ^ 1; + /* Build an ADD projection function. */ + if (msbLsb) { + index = top+n-k-1; + } else { + index = top+k; + } + var = cuddUniqueInter(dd,index,DD_ONE(dd),DD_ZERO(dd)); + if (var == NULL) { + for (j = 0; j < m; j++) { + Cudd_RecursiveDeref(dd,array[previous][j]); + } + FREE(array[0]); + FREE(array[1]); + return(NULL); + } + cuddRef(var); + for (i = 0; i < m; i ++) { + t = (i + residue) % m; + tmp = Cudd_addIte(dd,var,array[previous][t],array[previous][i]); + if (tmp == NULL) { + for (j = 0; j < i; j++) { + Cudd_RecursiveDeref(dd,array[thisOne][j]); + } + for (j = 0; j < m; j++) { + Cudd_RecursiveDeref(dd,array[previous][j]); + } + FREE(array[0]); + FREE(array[1]); + return(NULL); + } + cuddRef(tmp); + array[thisOne][i] = tmp; + } + /* One layer completed. Free the other array for the next iteration. */ + for (i = 0; i < m; i++) { + Cudd_RecursiveDeref(dd,array[previous][i]); + } + Cudd_RecursiveDeref(dd,var); + /* Update residue of 2**k. */ + residue = (2 * residue) % m; + /* Adjust residue for MSB, if this is a two's complement number. */ + if (tc && (k == n - 1)) { + residue = (m - residue) % m; + } + } + + /* We are only interested in the 0-residue node of the top layer. */ + for (i = 1; i < m; i++) { + Cudd_RecursiveDeref(dd,array[(n - 1) & 1][i]); + } + res = array[(n - 1) & 1][0]; + + FREE(array[0]); + FREE(array[1]); + + cuddDeref(res); + return(res); + +} /* end of Cudd_addResidue */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addWalsh.] + + Description [Generates a Walsh matrix in ADD form. Returns a pointer + to the matrixi if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +addWalshInt( + DdManager * dd, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *one, *minusone; + DdNode *t, *u, *t1, *u1, *v, *w; + int i; + + one = DD_ONE(dd); + if (n == 0) return(one); + + /* Build bottom part of ADD outside loop */ + minusone = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) -1); + if (minusone == NULL) return(NULL); + cuddRef(minusone); + v = Cudd_addIte(dd, y[n-1], minusone, one); + if (v == NULL) { + Cudd_RecursiveDeref(dd, minusone); + return(NULL); + } + cuddRef(v); + u = Cudd_addIte(dd, x[n-1], v, one); + if (u == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + if (n>1) { + w = Cudd_addIte(dd, y[n-1], one, minusone); + if (w == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(w); + t = Cudd_addIte(dd, x[n-1], w, minusone); + if (t == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(t); + Cudd_RecursiveDeref(dd, w); + } + cuddDeref(minusone); /* minusone is in the result; it won't die */ + + /* Loop to build the rest of the ADD */ + for (i=n-2; i>=0; i--) { + t1 = t; u1 = u; + v = Cudd_addIte(dd, y[i], t1, u1); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + return(NULL); + } + cuddRef(v); + u = Cudd_addIte(dd, x[i], v, u1); + if (u == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + if (i>0) { + w = Cudd_addIte(dd, y[i], u1, t1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(w); + t = Cudd_addIte(dd, x[i], w, t1); + if (u == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(t); + Cudd_RecursiveDeref(dd, w); + } + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + } + + cuddDeref(u); + return(u); + +} /* end of addWalshInt */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAndAbs.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAndAbs.c new file mode 100644 index 000000000..a800830bf --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAndAbs.c @@ -0,0 +1,373 @@ +/**CFile*********************************************************************** + + FileName [cuddAndAbs.c] + + PackageName [cudd] + + Synopsis [Combined AND and existential abstraction for BDDs] + + Description [External procedures included in this module: +
            +
          • Cudd_bddAndAbstract() +
          • Cudd_bddAndAbstractLimit() +
          + Internal procedures included in this module: +
            +
          • cuddBddAndAbstractRecur() +
          ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.20 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Takes the AND of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise. + Cudd_bddAndAbstract implements the semiring matrix multiplication + algorithm for the boolean semiring.] + + SideEffects [None] + + SeeAlso [Cudd_addMatrixMultiply Cudd_addTriangle Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddAndAbstract( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *res; + + do { + manager->reordered = 0; + res = cuddBddAndAbstractRecur(manager, f, g, cube); + } while (manager->reordered == 1); + return(res); + +} /* end of Cudd_bddAndAbstract */ + + +/**Function******************************************************************** + + Synopsis [Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. Returns NULL if too many nodes are required.] + + Description [Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise. + In particular, if the number of new nodes created exceeds + limit, this function returns NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddAndAbstractLimit( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = manager->maxLive; + + manager->maxLive = (manager->keys - manager->dead) + + (manager->keysZ - manager->deadZ) + limit; + do { + manager->reordered = 0; + res = cuddBddAndAbstractRecur(manager, f, g, cube); + } while (manager->reordered == 1); + manager->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddAndAbstractLimit */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Takes the AND of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +cuddBddAndAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *zero, *r, *t, *e; + unsigned int topf, topg, topcube, top, index; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == one && g == one) return(one); + + if (cube == one) { + return(cuddBddAndRecur(manager, f, g)); + } + if (f == one || f == g) { + return(cuddBddExistAbstractRecur(manager, g, cube)); + } + if (g == one) { + return(cuddBddExistAbstractRecur(manager, f, cube)); + } + /* At this point f, g, and cube are not constant. */ + + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; + g = tmp; + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + top = ddMin(topf, topg); + topcube = manager->perm[cube->index]; + + while (topcube < top) { + cube = cuddT(cube); + if (cube == one) { + return(cuddBddAndRecur(manager, f, g)); + } + topcube = manager->perm[cube->index]; + } + /* Now, topcube >= top. */ + + /* Check cache. */ + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube); + if (r != NULL) { + return(r); + } + } + + if (topf == top) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg == top) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + if (topcube == top) { /* quantify */ + DdNode *Cube = cuddT(cube); + t = cuddBddAndAbstractRecur(manager, ft, gt, Cube); + if (t == NULL) return(NULL); + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. Likewise t + t * anything == t. + ** Notice that t == fe implies that fe does not depend on the + ** variables in Cube. Likewise for t == ge. + */ + if (t == one || t == fe || t == ge) { + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, + f, g, cube, t); + return(t); + } + cuddRef(t); + /* Special case: t + !t * anything == t + anything. */ + if (t == Cudd_Not(fe)) { + e = cuddBddExistAbstractRecur(manager, ge, Cube); + } else if (t == Cudd_Not(ge)) { + e = cuddBddExistAbstractRecur(manager, fe, Cube); + } else { + e = cuddBddAndAbstractRecur(manager, fe, ge, Cube); + } + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + if (t == e) { + r = t; + cuddDeref(t); + } else { + cuddRef(e); + r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_DelayedDerefBdd(manager, t); + Cudd_DelayedDerefBdd(manager, e); + cuddDeref(r); + } + } else { + t = cuddBddAndAbstractRecur(manager, ft, gt, cube); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddAndAbstractRecur(manager, fe, ge, cube); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + if (t == e) { + r = t; + cuddDeref(t); + } else { + cuddRef(e); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager, (int) index, + Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + } + } + + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r); + return (r); + +} /* end of cuddBddAndAbstractRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddAnneal.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddAnneal.c new file mode 100644 index 000000000..622c3d14a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddAnneal.c @@ -0,0 +1,814 @@ +/**CFile*********************************************************************** + + FileName [cuddAnneal.c] + + PackageName [cudd] + + Synopsis [Reordering of DDs based on simulated annealing] + + Description [Internal procedures included in this file: +
            +
          • cuddAnnealing() +
          + Static procedures included in this file: +
            +
          • stopping_criterion() +
          • random_generator() +
          • ddExchange() +
          • ddJumpingAux() +
          • ddJumpingUp() +
          • ddJumpingDown() +
          • siftBackwardProb() +
          • copyOrder() +
          • restoreOrder() +
          + ] + + SeeAlso [] + + Author [Jae-Young Jang, Jorgen Sivesind] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Annealing parameters */ +#define BETA 0.6 +#define ALPHA 0.90 +#define EXC_PROB 0.4 +#define JUMP_UP_PROB 0.36 +#define MAXGEN_RATIO 15.0 +#define STOP_TEMP 1.0 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAnneal.c,v 1.15 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef DD_STATS +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +static int tosses; +static int acceptances; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int stopping_criterion (int c1, int c2, int c3, int c4, double temp); +static double random_generator (void); +static int ddExchange (DdManager *table, int x, int y, double temp); +static int ddJumpingAux (DdManager *table, int x, int x_low, int x_high, double temp); +static Move * ddJumpingUp (DdManager *table, int x, int x_low, int initial_size); +static Move * ddJumpingDown (DdManager *table, int x, int x_high, int initial_size); +static int siftBackwardProb (DdManager *table, Move *moves, int size, double temp); +static void copyOrder (DdManager *table, int *array, int lower, int upper); +static int restoreOrder (DdManager *table, int *array, int lower, int upper); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Get new variable-order by simulated annealing algorithm.] + + Description [Get x, y by random selection. Choose either + exchange or jump randomly. In case of jump, choose between jump_up + and jump_down randomly. Do exchange or jump and get optimal case. + Loop until there is no improvement or temperature reaches + minimum. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddAnnealing( + DdManager * table, + int lower, + int upper) +{ + int nvars; + int size; + int x,y; + int result; + int c1, c2, c3, c4; + int BestCost; + int *BestOrder; + double NewTemp, temp; + double rand1; + int innerloop, maxGen; + int ecount, ucount, dcount; + + nvars = upper - lower + 1; + + result = cuddSifting(table,lower,upper); +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + if (result == 0) return(0); + + size = table->keys - table->isolated; + + /* Keep track of the best order. */ + BestCost = size; + BestOrder = ALLOC(int,nvars); + if (BestOrder == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + copyOrder(table,BestOrder,lower,upper); + + temp = BETA * size; + maxGen = (int) (MAXGEN_RATIO * nvars); + + c1 = size + 10; + c2 = c1 + 10; + c3 = size; + c4 = c2 + 10; + ecount = ucount = dcount = 0; + + while (!stopping_criterion(c1, c2, c3, c4, temp)) { +#ifdef DD_STATS + (void) fprintf(table->out,"temp=%f\tsize=%d\tgen=%d\t", + temp,size,maxGen); + tosses = acceptances = 0; +#endif + for (innerloop = 0; innerloop < maxGen; innerloop++) { + /* Choose x, y randomly. */ + x = (int) Cudd_Random() % nvars; + do { + y = (int) Cudd_Random() % nvars; + } while (x == y); + x += lower; + y += lower; + if (x > y) { + int tmp = x; + x = y; + y = tmp; + } + + /* Choose move with roulette wheel. */ + rand1 = random_generator(); + if (rand1 < EXC_PROB) { + result = ddExchange(table,x,y,temp); /* exchange */ + ecount++; +#if 0 + (void) fprintf(table->out, + "Exchange of %d and %d: size = %d\n", + x,y,table->keys - table->isolated); +#endif + } else if (rand1 < EXC_PROB + JUMP_UP_PROB) { + result = ddJumpingAux(table,y,x,y,temp); /* jumping_up */ + ucount++; +#if 0 + (void) fprintf(table->out, + "Jump up of %d to %d: size = %d\n", + y,x,table->keys - table->isolated); +#endif + } else { + result = ddJumpingAux(table,x,x,y,temp); /* jumping_down */ + dcount++; +#if 0 + (void) fprintf(table->out, + "Jump down of %d to %d: size = %d\n", + x,y,table->keys - table->isolated); +#endif + } + + if (!result) { + FREE(BestOrder); + return(0); + } + + size = table->keys - table->isolated; /* keep current size */ + if (size < BestCost) { /* update best order */ + BestCost = size; + copyOrder(table,BestOrder,lower,upper); + } + } + c1 = c2; + c2 = c3; + c3 = c4; + c4 = size; + NewTemp = ALPHA * temp; + if (NewTemp >= 1.0) { + maxGen = (int)(log(NewTemp) / log(temp) * maxGen); + } + temp = NewTemp; /* control variable */ +#ifdef DD_STATS + (void) fprintf(table->out,"uphill = %d\taccepted = %d\n", + tosses,acceptances); + fflush(table->out); +#endif + } + + result = restoreOrder(table,BestOrder,lower,upper); + FREE(BestOrder); + if (!result) return(0); +#ifdef DD_STATS + fprintf(table->out,"#:N_EXCHANGE %8d : total exchanges\n",ecount); + fprintf(table->out,"#:N_JUMPUP %8d : total jumps up\n",ucount); + fprintf(table->out,"#:N_JUMPDOWN %8d : total jumps down",dcount); +#endif + return(1); + +} /* end of cuddAnnealing */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Checks termination condition.] + + Description [If temperature is STOP_TEMP or there is no improvement + then terminates. Returns 1 if the termination criterion is met; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +stopping_criterion( + int c1, + int c2, + int c3, + int c4, + double temp) +{ + if (STOP_TEMP < temp) { + return(0); + } else if ((c1 == c2) && (c1 == c3) && (c1 == c4)) { + return(1); + } else { + return(0); + } + +} /* end of stopping_criterion */ + + +/**Function******************************************************************** + + Synopsis [Random number generator.] + + Description [Returns a double precision value between 0.0 and 1.0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double +random_generator(void) +{ + return((double)(Cudd_Random() / 2147483561.0)); + +} /* end of random_generator */ + + +/**Function******************************************************************** + + Synopsis [This function is for exchanging two variables, x and y.] + + Description [This is the same funcion as ddSwapping except for + comparison expression. Use probability function, exp(-size_change/temp).] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddExchange( + DdManager * table, + int x, + int y, + double temp) +{ + Move *move,*moves; + int tmp; + int x_ref,y_ref; + int x_next,y_next; + int size, result; + int initial_size, limit_size; + + x_ref = x; + y_ref = y; + + x_next = cuddNextHigh(table,x); + y_next = cuddNextLow(table,y); + moves = NULL; + initial_size = limit_size = table->keys - table->isolated; + + for (;;) { + if (x_next == y_next) { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; + x = y; + y = tmp; + } else if (x == y_next) { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + tmp = x; + x = y; + y = tmp; + } else { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + x = x_next; + y = y_next; + } + + x_next = cuddNextHigh(table,x); + y_next = cuddNextLow(table,y); + if (x_next > y_ref) break; + + if ((double) size > DD_MAX_REORDER_GROWTH * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + } + + if (y_next>=x_ref) { + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + } + + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddExchangeOutOfMem; + + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(1); + +ddExchangeOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(0); + +} /* end of ddExchange */ + + +/**Function******************************************************************** + + Synopsis [Moves a variable to a specified position.] + + Description [If x==x_low, it executes jumping_down. If x==x_high, it + executes jumping_up. This funcion is similar to ddSiftingAux. Returns + 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddJumpingAux( + DdManager * table, + int x, + int x_low, + int x_high, + double temp) +{ + Move *move; + Move *moves; /* list of moves */ + int initial_size; + int result; + + initial_size = table->keys - table->isolated; + +#ifdef DD_DEBUG + assert(table->subtables[x].keys > 0); +#endif + + moves = NULL; + + if (cuddNextLow(table,x) < x_low) { + if (cuddNextHigh(table,x) > x_high) return(1); + moves = ddJumpingDown(table,x,x_high,initial_size); + /* after that point x --> x_high unless early termination */ + if (moves == NULL) goto ddJumpingAuxOutOfMem; + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddJumpingAuxOutOfMem; + } else if (cuddNextHigh(table,x) > x_high) { + moves = ddJumpingUp(table,x,x_low,initial_size); + /* after that point x --> x_low unless early termination */ + if (moves == NULL) goto ddJumpingAuxOutOfMem; + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddJumpingAuxOutOfMem; + } else { + (void) fprintf(table->err,"Unexpected condition in ddJumping\n"); + goto ddJumpingAuxOutOfMem; + } + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(1); + +ddJumpingAuxOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(0); + +} /* end of ddJumpingAux */ + + +/**Function******************************************************************** + + Synopsis [This function is for jumping up.] + + Description [This is a simplified version of ddSiftingUp. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +ddJumpingUp( + DdManager * table, + int x, + int x_low, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddNextLow(table,x); + while (y >= x_low) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) goto ddJumpingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddJumpingUpOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > table->maxGrowth * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + x = y; + y = cuddNextLow(table,x); + } + return(moves); + +ddJumpingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of ddJumpingUp */ + + +/**Function******************************************************************** + + Synopsis [This function is for jumping down.] + + Description [This is a simplified version of ddSiftingDown. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +ddJumpingDown( + DdManager * table, + int x, + int x_high, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddNextHigh(table,x); + while (y <= x_high) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddJumpingDownOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddJumpingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > table->maxGrowth * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + x = y; + y = cuddNextHigh(table,x); + } + return(moves); + +ddJumpingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of ddJumpingDown */ + + +/**Function******************************************************************** + + Synopsis [Returns the DD to the best position encountered during + sifting if there was improvement.] + + Description [Otherwise, "tosses a coin" to decide whether to keep + the current configuration or return the DD to the original + one. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +siftBackwardProb( + DdManager * table, + Move * moves, + int size, + double temp) +{ + Move *move; + int res; + int best_size = size; + double coin, threshold; + + /* Look for best size during the last sifting */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < best_size) { + best_size = move->size; + } + } + + /* If best_size equals size, the last sifting did not produce any + ** improvement. We now toss a coin to decide whether to retain + ** this change or not. + */ + if (best_size == size) { + coin = random_generator(); +#ifdef DD_STATS + tosses++; +#endif + threshold = exp(-((double)(table->keys - table->isolated - size))/temp); + if (coin < threshold) { +#ifdef DD_STATS + acceptances++; +#endif + return(1); + } + } + + /* Either there was improvement, or we have decided not to + ** accept the uphill move. Go to best position. + */ + res = table->keys - table->isolated; + for (move = moves; move != NULL; move = move->next) { + if (res == best_size) return(1); + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + + return(1); + +} /* end of sift_backward_prob */ + + +/**Function******************************************************************** + + Synopsis [Copies the current variable order to array.] + + Description [Copies the current variable order to array. + At the same time inverts the permutation.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +copyOrder( + DdManager * table, + int * array, + int lower, + int upper) +{ + int i; + int nvars; + + nvars = upper - lower + 1; + for (i = 0; i < nvars; i++) { + array[i] = table->invperm[i+lower]; + } + +} /* end of copyOrder */ + + +/**Function******************************************************************** + + Synopsis [Restores the variable order in array by a series of sifts up.] + + Description [Restores the variable order in array by a series of sifts up. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +restoreOrder( + DdManager * table, + int * array, + int lower, + int upper) +{ + int i, x, y, size; + int nvars = upper - lower + 1; + + for (i = 0; i < nvars; i++) { + x = table->perm[array[i]]; +#ifdef DD_DEBUG + assert(x >= lower && x <= upper); +#endif + y = cuddNextLow(table,x); + while (y >= i + lower) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) return(0); + x = y; + y = cuddNextLow(table,x); + } + } + + return(1); + +} /* end of restoreOrder */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddApa.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddApa.c new file mode 100644 index 000000000..7c4ff8ce6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddApa.c @@ -0,0 +1,979 @@ +/**CFile*********************************************************************** + + FileName [cuddApa.c] + + PackageName [cudd] + + Synopsis [Arbitrary precision arithmetic functions.] + + Description [External procedures included in this module: +
            +
          • Cudd_ApaNumberOfDigits() +
          • Cudd_NewApaNumber() +
          • Cudd_ApaCopy() +
          • Cudd_ApaAdd() +
          • Cudd_ApaSubtract() +
          • Cudd_ApaShortDivision() +
          • Cudd_ApaIntDivision() +
          • Cudd_ApaShiftRight() +
          • Cudd_ApaSetToLiteral() +
          • Cudd_ApaPowerOfTwo() +
          • Cudd_ApaCompare() +
          • Cudd_ApaCompareRatios() +
          • Cudd_ApaPrintHex() +
          • Cudd_ApaPrintDecimal() +
          • Cudd_ApaPrintExponential() +
          • Cudd_ApaCountMinterm() +
          • Cudd_ApaPrintMinterm() +
          • Cudd_ApaPrintMintermExp() +
          • Cudd_ApaPrintDensity() +
          + Static procedures included in this module: +
            +
          • cuddApaCountMintermAux() +
          • cuddApaStCountfree() +
          ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.20 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static DdNode *background, *zero; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdApaNumber cuddApaCountMintermAux (DdNode * node, int digits, DdApaNumber max, DdApaNumber min, st_table * table); +static enum st_retval cuddApaStCountfree (char * key, char * value, char * arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Finds the number of digits for an arbitrary precision + integer.] + + Description [Finds the number of digits for an arbitrary precision + integer given the maximum number of binary digits. The number of + binary digits should be positive. Returns the number of digits if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaNumberOfDigits( + int binaryDigits) +{ + int digits; + + digits = binaryDigits / DD_APA_BITS; + if ((digits * DD_APA_BITS) != binaryDigits) + digits++; + return(digits); + +} /* end of Cudd_ApaNumberOfDigits */ + + +/**Function******************************************************************** + + Synopsis [Allocates memory for an arbitrary precision integer.] + + Description [Allocates memory for an arbitrary precision + integer. Returns a pointer to the allocated memory if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdApaNumber +Cudd_NewApaNumber( + int digits) +{ + return(ALLOC(DdApaDigit, digits)); + +} /* end of Cudd_NewApaNumber */ + + +/**Function******************************************************************** + + Synopsis [Makes a copy of an arbitrary precision integer.] + + Description [Makes a copy of an arbitrary precision integer.] + + SideEffects [Changes parameter dest.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaCopy( + int digits, + DdApaNumber source, + DdApaNumber dest) +{ + int i; + + for (i = 0; i < digits; i++) { + dest[i] = source[i]; + } + +} /* end of Cudd_ApaCopy */ + + +/**Function******************************************************************** + + Synopsis [Adds two arbitrary precision integers.] + + Description [Adds two arbitrary precision integers. Returns the + carry out of the most significant digit.] + + SideEffects [The result of the sum is stored in parameter sum.] + + SeeAlso [] + +******************************************************************************/ +DdApaDigit +Cudd_ApaAdd( + int digits, + DdApaNumber a, + DdApaNumber b, + DdApaNumber sum) +{ + int i; + DdApaDoubleDigit partial = 0; + + for (i = digits - 1; i >= 0; i--) { + partial = a[i] + b[i] + DD_MSDIGIT(partial); + sum[i] = (DdApaDigit) DD_LSDIGIT(partial); + } + return((DdApaDigit) DD_MSDIGIT(partial)); + +} /* end of Cudd_ApaAdd */ + + +/**Function******************************************************************** + + Synopsis [Subtracts two arbitrary precision integers.] + + Description [Subtracts two arbitrary precision integers. Returns the + borrow out of the most significant digit.] + + SideEffects [The result of the subtraction is stored in parameter + diff.] + + SeeAlso [] + +******************************************************************************/ +DdApaDigit +Cudd_ApaSubtract( + int digits, + DdApaNumber a, + DdApaNumber b, + DdApaNumber diff) +{ + int i; + DdApaDoubleDigit partial = DD_APA_BASE; + + for (i = digits - 1; i >= 0; i--) { + partial = DD_MSDIGIT(partial) + DD_APA_MASK + a[i] - b[i]; + diff[i] = (DdApaDigit) DD_LSDIGIT(partial); + } + return((DdApaDigit) DD_MSDIGIT(partial) - 1); + +} /* end of Cudd_ApaSubtract */ + + +/**Function******************************************************************** + + Synopsis [Divides an arbitrary precision integer by a digit.] + + Description [Divides an arbitrary precision integer by a digit.] + + SideEffects [The quotient is returned in parameter quotient.] + + SeeAlso [] + +******************************************************************************/ +DdApaDigit +Cudd_ApaShortDivision( + int digits, + DdApaNumber dividend, + DdApaDigit divisor, + DdApaNumber quotient) +{ + int i; + DdApaDigit remainder; + DdApaDoubleDigit partial; + + remainder = 0; + for (i = 0; i < digits; i++) { + partial = remainder * DD_APA_BASE + dividend[i]; + quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor); + remainder = (DdApaDigit) (partial % divisor); + } + + return(remainder); + +} /* end of Cudd_ApaShortDivision */ + + +/**Function******************************************************************** + + Synopsis [Divides an arbitrary precision integer by an integer.] + + Description [Divides an arbitrary precision integer by a 32-bit + unsigned integer. Returns the remainder of the division. This + procedure relies on the assumption that the number of bits of a + DdApaDigit plus the number of bits of an unsigned int is less the + number of bits of the mantissa of a double. This guarantees that the + product of a DdApaDigit and an unsigned int can be represented + without loss of precision by a double. On machines where this + assumption is not satisfied, this procedure will malfunction.] + + SideEffects [The quotient is returned in parameter quotient.] + + SeeAlso [Cudd_ApaShortDivision] + +******************************************************************************/ +unsigned int +Cudd_ApaIntDivision( + int digits, + DdApaNumber dividend, + unsigned int divisor, + DdApaNumber quotient) +{ + int i; + double partial; + unsigned int remainder = 0; + double ddiv = (double) divisor; + + for (i = 0; i < digits; i++) { + partial = (double) remainder * DD_APA_BASE + dividend[i]; + quotient[i] = (DdApaDigit) (partial / ddiv); + remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv)); + } + + return(remainder); + +} /* end of Cudd_ApaIntDivision */ + + +/**Function******************************************************************** + + Synopsis [Shifts right an arbitrary precision integer by one binary + place.] + + Description [Shifts right an arbitrary precision integer by one + binary place. The most significant binary digit of the result is + taken from parameter in.] + + SideEffects [The result is returned in parameter b.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaShiftRight( + int digits, + DdApaDigit in, + DdApaNumber a, + DdApaNumber b) +{ + int i; + + for (i = digits - 1; i > 0; i--) { + b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1)); + } + b[0] = (a[0] >> 1) | (in << (DD_APA_BITS - 1)); + +} /* end of Cudd_ApaShiftRight */ + + +/**Function******************************************************************** + + Synopsis [Sets an arbitrary precision integer to a one-digit literal.] + + Description [Sets an arbitrary precision integer to a one-digit literal.] + + SideEffects [The result is returned in parameter number.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaSetToLiteral( + int digits, + DdApaNumber number, + DdApaDigit literal) +{ + int i; + + for (i = 0; i < digits - 1; i++) + number[i] = 0; + number[digits - 1] = literal; + +} /* end of Cudd_ApaSetToLiteral */ + + +/**Function******************************************************************** + + Synopsis [Sets an arbitrary precision integer to a power of two.] + + Description [Sets an arbitrary precision integer to a power of + two. If the power of two is too large to be represented, the number + is set to 0.] + + SideEffects [The result is returned in parameter number.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaPowerOfTwo( + int digits, + DdApaNumber number, + int power) +{ + int i; + int index; + + for (i = 0; i < digits; i++) + number[i] = 0; + i = digits - 1 - power / DD_APA_BITS; + if (i < 0) return; + index = power & (DD_APA_BITS - 1); + number[i] = 1 << index; + +} /* end of Cudd_ApaPowerOfTwo */ + + +/**Function******************************************************************** + + Synopsis [Compares two arbitrary precision integers.] + + Description [Compares two arbitrary precision integers. Returns 1 if + the first number is larger; 0 if they are equal; -1 if the second + number is larger.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaCompare( + int digitsFirst, + DdApaNumber first, + int digitsSecond, + DdApaNumber second) +{ + int i; + int firstNZ, secondNZ; + + /* Find first non-zero in both numbers. */ + for (firstNZ = 0; firstNZ < digitsFirst; firstNZ++) + if (first[firstNZ] != 0) break; + for (secondNZ = 0; secondNZ < digitsSecond; secondNZ++) + if (second[secondNZ] != 0) break; + if (digitsFirst - firstNZ > digitsSecond - secondNZ) return(1); + else if (digitsFirst - firstNZ < digitsSecond - secondNZ) return(-1); + for (i = 0; i < digitsFirst - firstNZ; i++) { + if (first[firstNZ + i] > second[secondNZ + i]) return(1); + else if (first[firstNZ + i] < second[secondNZ + i]) return(-1); + } + return(0); + +} /* end of Cudd_ApaCompare */ + + +/**Function******************************************************************** + + Synopsis [Compares the ratios of two arbitrary precision integers to two + unsigned ints.] + + Description [Compares the ratios of two arbitrary precision integers + to two unsigned ints. Returns 1 if the first number is larger; 0 if + they are equal; -1 if the second number is larger.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaCompareRatios( + int digitsFirst, + DdApaNumber firstNum, + unsigned int firstDen, + int digitsSecond, + DdApaNumber secondNum, + unsigned int secondDen) +{ + int result; + DdApaNumber first, second; + unsigned int firstRem, secondRem; + + first = Cudd_NewApaNumber(digitsFirst); + firstRem = Cudd_ApaIntDivision(digitsFirst,firstNum,firstDen,first); + second = Cudd_NewApaNumber(digitsSecond); + secondRem = Cudd_ApaIntDivision(digitsSecond,secondNum,secondDen,second); + result = Cudd_ApaCompare(digitsFirst,first,digitsSecond,second); + FREE(first); + FREE(second); + if (result == 0) { + if ((double)firstRem/firstDen > (double)secondRem/secondDen) + return(1); + else if ((double)firstRem/firstDen < (double)secondRem/secondDen) + return(-1); + } + return(result); + +} /* end of Cudd_ApaCompareRatios */ + + +/**Function******************************************************************** + + Synopsis [Prints an arbitrary precision integer in hexadecimal format.] + + Description [Prints an arbitrary precision integer in hexadecimal format. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintDecimal Cudd_ApaPrintExponential] + +******************************************************************************/ +int +Cudd_ApaPrintHex( + FILE * fp, + int digits, + DdApaNumber number) +{ + int i, result; + + for (i = 0; i < digits; i++) { + result = fprintf(fp,DD_APA_HEXPRINT,number[i]); + if (result == EOF) + return(0); + } + return(1); + +} /* end of Cudd_ApaPrintHex */ + + +/**Function******************************************************************** + + Synopsis [Prints an arbitrary precision integer in decimal format.] + + Description [Prints an arbitrary precision integer in decimal format. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintExponential] + +******************************************************************************/ +int +Cudd_ApaPrintDecimal( + FILE * fp, + int digits, + DdApaNumber number) +{ + int i, result; + DdApaDigit remainder; + DdApaNumber work; + unsigned char *decimal; + int leadingzero; + int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; + + work = Cudd_NewApaNumber(digits); + if (work == NULL) + return(0); + decimal = ALLOC(unsigned char, decimalDigits); + if (decimal == NULL) { + FREE(work); + return(0); + } + Cudd_ApaCopy(digits,number,work); + for (i = decimalDigits - 1; i >= 0; i--) { + remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); + decimal[i] = (unsigned char) remainder; + } + FREE(work); + + leadingzero = 1; + for (i = 0; i < decimalDigits; i++) { + leadingzero = leadingzero && (decimal[i] == 0); + if ((!leadingzero) || (i == (decimalDigits - 1))) { + result = fprintf(fp,"%1d",decimal[i]); + if (result == EOF) { + FREE(decimal); + return(0); + } + } + } + FREE(decimal); + return(1); + +} /* end of Cudd_ApaPrintDecimal */ + + +/**Function******************************************************************** + + Synopsis [Prints an arbitrary precision integer in exponential format.] + + Description [Prints an arbitrary precision integer in exponential format. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintDecimal] + +******************************************************************************/ +int +Cudd_ApaPrintExponential( + FILE * fp, + int digits, + DdApaNumber number, + int precision) +{ + int i, first, last, result; + DdApaDigit remainder; + DdApaNumber work; + unsigned char *decimal; + int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; + + work = Cudd_NewApaNumber(digits); + if (work == NULL) + return(0); + decimal = ALLOC(unsigned char, decimalDigits); + if (decimal == NULL) { + FREE(work); + return(0); + } + Cudd_ApaCopy(digits,number,work); + first = decimalDigits - 1; + for (i = decimalDigits - 1; i >= 0; i--) { + remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); + decimal[i] = (unsigned char) remainder; + if (remainder != 0) first = i; /* keep track of MS non-zero */ + } + FREE(work); + last = ddMin(first + precision, decimalDigits); + + for (i = first; i < last; i++) { + result = fprintf(fp,"%s%1d",i == first+1 ? "." : "", decimal[i]); + if (result == EOF) { + FREE(decimal); + return(0); + } + } + FREE(decimal); + result = fprintf(fp,"e+%d",decimalDigits - first - 1); + if (result == EOF) { + return(0); + } + return(1); + +} /* end of Cudd_ApaPrintExponential */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a DD.] + + Description [Counts the number of minterms of a DD. The function is + assumed to depend on nvars variables. The minterm count is + represented as an arbitrary precision unsigned integer, to allow for + any number of variables CUDD supports. Returns a pointer to the + array representing the number of minterms of the function rooted at + node if successful; NULL otherwise.] + + SideEffects [The number of digits of the result is returned in + parameter digits.] + + SeeAlso [Cudd_CountMinterm] + +******************************************************************************/ +DdApaNumber +Cudd_ApaCountMinterm( + DdManager * manager, + DdNode * node, + int nvars, + int * digits) +{ + DdApaNumber max, min; + st_table *table; + DdApaNumber i,count; + + background = manager->background; + zero = Cudd_Not(manager->one); + + *digits = Cudd_ApaNumberOfDigits(nvars+1); + max = Cudd_NewApaNumber(*digits); + if (max == NULL) { + return(NULL); + } + Cudd_ApaPowerOfTwo(*digits,max,nvars); + min = Cudd_NewApaNumber(*digits); + if (min == NULL) { + FREE(max); + return(NULL); + } + Cudd_ApaSetToLiteral(*digits,min,0); + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) { + FREE(max); + FREE(min); + return(NULL); + } + i = cuddApaCountMintermAux(Cudd_Regular(node),*digits,max,min,table); + if (i == NULL) { + FREE(max); + FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + return(NULL); + } + count = Cudd_NewApaNumber(*digits); + if (count == NULL) { + FREE(max); + FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + if (Cudd_Regular(node)->ref == 1) FREE(i); + return(NULL); + } + if (Cudd_IsComplement(node)) { + (void) Cudd_ApaSubtract(*digits,max,i,count); + } else { + Cudd_ApaCopy(*digits,i,count); + } + FREE(max); + FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + if (Cudd_Regular(node)->ref == 1) FREE(i); + return(count); + +} /* end of Cudd_ApaCountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic.] + + Description [Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintMintermExp] + +******************************************************************************/ +int +Cudd_ApaPrintMinterm( + FILE * fp, + DdManager * dd, + DdNode * node, + int nvars) +{ + int digits; + int result; + DdApaNumber count; + + count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); + if (count == NULL) + return(0); + result = Cudd_ApaPrintDecimal(fp,digits,count); + FREE(count); + if (fprintf(fp,"\n") == EOF) { + return(0); + } + return(result); + +} /* end of Cudd_ApaPrintMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints the number of minterms of a BDD or ADD in exponential + format using arbitrary precision arithmetic.] + + Description [Prints the number of minterms of a BDD or ADD in + exponential format using arbitrary precision arithmetic. Parameter + precision controls the number of signficant digits printed. Returns + 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintMinterm] + +******************************************************************************/ +int +Cudd_ApaPrintMintermExp( + FILE * fp, + DdManager * dd, + DdNode * node, + int nvars, + int precision) +{ + int digits; + int result; + DdApaNumber count; + + count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); + if (count == NULL) + return(0); + result = Cudd_ApaPrintExponential(fp,digits,count,precision); + FREE(count); + if (fprintf(fp,"\n") == EOF) { + return(0); + } + return(result); + +} /* end of Cudd_ApaPrintMintermExp */ + + +/**Function******************************************************************** + + Synopsis [Prints the density of a BDD or ADD using + arbitrary precision arithmetic.] + + Description [Prints the density of a BDD or ADD using + arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaPrintDensity( + FILE * fp, + DdManager * dd, + DdNode * node, + int nvars) +{ + int digits; + int result; + DdApaNumber count,density; + unsigned int size, remainder, fractional; + + count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); + if (count == NULL) + return(0); + size = Cudd_DagSize(node); + density = Cudd_NewApaNumber(digits); + remainder = Cudd_ApaIntDivision(digits,count,size,density); + result = Cudd_ApaPrintDecimal(fp,digits,density); + FREE(count); + FREE(density); + fractional = (unsigned int)((double)remainder / size * 1000000); + if (fprintf(fp,".%u\n", fractional) == EOF) { + return(0); + } + return(result); + +} /* end of Cudd_ApaPrintDensity */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_ApaCountMinterm.] + + Description [Performs the recursive step of Cudd_ApaCountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. + Uses the identity |f'| = max - |f|. + The procedure expects the argument "node" to be a regular pointer, and + guarantees this condition is met in the recursive calls. + For efficiency, the result of a call is cached only if the node has + a reference count greater than 1. + Returns the number of minterms of the function rooted at node.] + + SideEffects [None] + +******************************************************************************/ +static DdApaNumber +cuddApaCountMintermAux( + DdNode * node, + int digits, + DdApaNumber max, + DdApaNumber min, + st_table * table) +{ + DdNode *Nt, *Ne; + DdApaNumber mint, mint1, mint2; + DdApaDigit carryout; + + if (cuddIsConstant(node)) { + if (node == background || node == zero) { + return(min); + } else { + return(max); + } + } + if (node->ref > 1 && st_lookup(table, node, &mint)) { + return(mint); + } + + Nt = cuddT(node); Ne = cuddE(node); + + mint1 = cuddApaCountMintermAux(Nt, digits, max, min, table); + if (mint1 == NULL) return(NULL); + mint2 = cuddApaCountMintermAux(Cudd_Regular(Ne), digits, max, min, table); + if (mint2 == NULL) { + if (Nt->ref == 1) FREE(mint1); + return(NULL); + } + mint = Cudd_NewApaNumber(digits); + if (mint == NULL) { + if (Nt->ref == 1) FREE(mint1); + if (Cudd_Regular(Ne)->ref == 1) FREE(mint2); + return(NULL); + } + if (Cudd_IsComplement(Ne)) { + (void) Cudd_ApaSubtract(digits,max,mint2,mint); + carryout = Cudd_ApaAdd(digits,mint1,mint,mint); + } else { + carryout = Cudd_ApaAdd(digits,mint1,mint2,mint); + } + Cudd_ApaShiftRight(digits,carryout,mint,mint); + /* If the refernce count of a child is 1, its minterm count + ** hasn't been stored in table. Therefore, it must be explicitly + ** freed here. */ + if (Nt->ref == 1) FREE(mint1); + if (Cudd_Regular(Ne)->ref == 1) FREE(mint2); + + if (node->ref > 1) { + if (st_insert(table, (char *)node, (char *)mint) == ST_OUT_OF_MEM) { + FREE(mint); + return(NULL); + } + } + return(mint); + +} /* end of cuddApaCountMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory used to store the minterm counts recorded + in the visited table.] + + Description [Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +cuddApaStCountfree( + char * key, + char * value, + char * arg) +{ + DdApaNumber d; + + d = (DdApaNumber) value; + FREE(d); + return(ST_CONTINUE); + +} /* end of cuddApaStCountfree */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddApprox.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddApprox.c new file mode 100644 index 000000000..23f97415f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddApprox.c @@ -0,0 +1,2204 @@ +/**CFile*********************************************************************** + + FileName [cuddApprox.c] + + PackageName [cudd] + + Synopsis [Procedures to approximate a given BDD.] + + Description [External procedures provided by this module: +
            +
          • Cudd_UnderApprox() +
          • Cudd_OverApprox() +
          • Cudd_RemapUnderApprox() +
          • Cudd_RemapOverApprox() +
          • Cudd_BiasedUnderApprox() +
          • Cudd_BiasedOverApprox() +
          + Internal procedures included in this module: +
            +
          • cuddUnderApprox() +
          • cuddRemapUnderApprox() +
          • cuddBiasedUnderApprox() +
          + Static procedures included in this module: +
            +
          • updateParity() +
          • gatherInfoAux() +
          • gatherInfo() +
          • computeSavings() +
          • updateRefs() +
          • UAmarkNodes() +
          • UAbuildSubset() +
          • RAmarkNodes() +
          • BAmarkNodes() +
          • RAbuildSubset() +
          • BAapplyBias() +
          + ] + + SeeAlso [cuddSubsetHB.c cuddSubsetSP.c cuddGenCof.c] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#ifdef __STDC__ +#include +#else +#define DBL_MAX_EXP 1024 +#endif +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define NOTHING 0 +#define REPLACE_T 1 +#define REPLACE_E 2 +#define REPLACE_N 3 +#define REPLACE_TT 4 +#define REPLACE_TE 5 + +#define DONT_CARE 0 +#define CARE 1 +#define TOTAL_CARE 2 +#define CARE_ERROR 3 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/* Data structure to store the information on each node. It keeps the +** number of minterms of the function rooted at this node in terms of +** the number of variables specified by the user; the number of +** minterms of the complement; the impact of the number of minterms of +** this function on the number of minterms of the root function; the +** reference count of the node from within the root function; the +** flag that says whether the node intersects the care set; the flag +** that says whether the node should be replaced and how; the results +** of subsetting in both phases. */ +typedef struct NodeData { + double mintermsP; /* minterms for the regular node */ + double mintermsN; /* minterms for the complemented node */ + int functionRef; /* references from within this function */ + char care; /* node intersects care set */ + char replace; /* replacement decision */ + short int parity; /* 1: even; 2: odd; 3: both */ + DdNode *resultP; /* result for even parity */ + DdNode *resultN; /* result for odd parity */ +} NodeData; + +typedef struct ApproxInfo { + DdNode *one; /* one constant */ + DdNode *zero; /* BDD zero constant */ + NodeData *page; /* per-node information */ + DdHashTable *table; /* hash table to access the per-node info */ + int index; /* index of the current node */ + double max; /* max number of minterms */ + int size; /* how many nodes are left */ + double minterms; /* how many minterms are left */ +} ApproxInfo; + +/* Item of the queue used in the levelized traversal of the BDD. */ +typedef struct GlobalQueueItem { + struct GlobalQueueItem *next; + struct GlobalQueueItem *cnext; + DdNode *node; + double impactP; + double impactN; +} GlobalQueueItem; + +typedef struct LocalQueueItem { + struct LocalQueueItem *next; + struct LocalQueueItem *cnext; + DdNode *node; + int localRef; +} LocalQueueItem; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddApprox.c,v 1.31 2012/02/05 04:38:07 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void updateParity (DdNode *node, ApproxInfo *info, int newparity); +static NodeData * gatherInfoAux (DdNode *node, ApproxInfo *info, int parity); +static ApproxInfo * gatherInfo (DdManager *dd, DdNode *node, int numVars, int parity); +static int computeSavings (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue); +static int updateRefs (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue); +static int UAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, int safe, double quality); +static DdNode * UAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info); +static int RAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality); +static int BAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality1, double quality0); +static DdNode * RAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info); +static int BAapplyBias (DdManager *dd, DdNode *f, DdNode *b, ApproxInfo *info, DdHashTable *cache); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with Shiple's + underapproximation method.] + + Description [Extracts a dense subset from a BDD. This procedure uses + a variant of Tom Shiple's underapproximation method. The main + difference from the original method is that density is used as cost + function. Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value + returned by Cudd_ReadSize for numVars when the number of variables + is under 1023. If numVars is larger than 1023, it will cause + overflow. If a 0 parameter is passed then the procedure will compute + a value which will avoid overflow but will cause underflow with 2046 + variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_UnderApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddUnderApprox(dd, f, numVars, threshold, safe, quality); + } while (dd->reordered == 1); + + return(subset); + +} /* end of Cudd_UnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with Shiple's + underapproximation method.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the underapproximation procedure except for the fact that it + works on the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_OverApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddUnderApprox(dd, g, numVars, threshold, safe, quality); + } while (dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_OverApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the remapping + underapproximation method.] + + Description [Extracts a dense subset from a BDD. This procedure uses + a remapping technique and density as the cost function. + Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value + returned by Cudd_ReadSize for numVars when the number of variables + is under 1023. If numVars is larger than 1023, it will cause + overflow. If a 0 parameter is passed then the procedure will compute + a value which will avoid overflow but will cause underflow with 2046 + variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_RemapUnderApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddRemapUnderApprox(dd, f, numVars, threshold, quality); + } while (dd->reordered == 1); + + return(subset); + +} /* end of Cudd_RemapUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the remapping + underapproximation method.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the underapproximation procedure except for the fact that it + works on the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_RemapOverApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddRemapUnderApprox(dd, g, numVars, threshold, quality); + } while (dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_RemapOverApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the biased + underapproximation method.] + + Description [Extracts a dense subset from a BDD. This procedure uses + a biased remapping technique and density as the cost function. The bias + is a function. This procedure tries to approximate where the bias is 0 + and preserve the given function where the bias is 1. + Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value + returned by Cudd_ReadSize for numVars when the number of variables + is under 1023. If numVars is larger than 1023, it will cause + overflow. If a 0 parameter is passed then the procedure will compute + a value which will avoid overflow but will cause underflow with 2046 + variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox + Cudd_RemapUnderApprox Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_BiasedUnderApprox( + DdManager *dd /* manager */, + DdNode *f /* function to be subset */, + DdNode *b /* bias function */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality1 /* minimum improvement for accepted changes when b=1 */, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddBiasedUnderApprox(dd, f, b, numVars, threshold, quality1, + quality0); + } while (dd->reordered == 1); + + return(subset); + +} /* end of Cudd_BiasedUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the biased + underapproximation method.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the underapproximation procedure except for the fact that it + works on the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths + Cudd_RemapOverApprox Cudd_BiasedUnderApprox Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_BiasedOverApprox( + DdManager *dd /* manager */, + DdNode *f /* function to be superset */, + DdNode *b /* bias function */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality1 /* minimum improvement for accepted changes when b=1*/, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddBiasedUnderApprox(dd, g, b, numVars, threshold, quality1, + quality0); + } while (dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_BiasedOverApprox */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Applies Tom Shiple's underappoximation algorithm.] + + Description [Applies Tom Shiple's underappoximation algorithm. Proceeds + in three phases: +
            +
          • collect information on each node in the BDD; this is done via DFS. +
          • traverse the BDD in top-down fashion and compute for each node + whether its elimination increases density. +
          • traverse the BDD via DFS and actually perform the elimination. +
          + Returns the approximated BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_UnderApprox] + +******************************************************************************/ +DdNode * +cuddUnderApprox( + DdManager * dd /* DD manager */, + DdNode * f /* current DD */, + int numVars /* maximum number of variables */, + int threshold /* threshold under which approximation stops */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + ApproxInfo *info; + DdNode *subset; + int result; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + return(NULL); + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + /* Create table where node data are accessible via a hash table. */ + info = gatherInfo(dd, f, numVars, safe); + if (info == NULL) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Mark nodes that should be replaced by zero. */ + result = UAmarkNodes(dd, f, info, threshold, safe, quality); + if (result == 0) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Build the result. */ + subset = UAbuildSubset(dd, f, info); +#if 1 + if (subset && info->size < Cudd_DagSize(subset)) + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); +#endif + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + +#ifdef DD_DEBUG + if (subset != NULL) { + cuddRef(subset); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + } + cuddDeref(subset); + } +#endif + return(subset); + +} /* end of cuddUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Applies the remapping underappoximation algorithm.] + + Description [Applies the remapping underappoximation algorithm. + Proceeds in three phases: +
            +
          • collect information on each node in the BDD; this is done via DFS. +
          • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
          • traverse the BDD via DFS and actually perform the elimination. +
          + Returns the approximated BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_RemapUnderApprox] + +******************************************************************************/ +DdNode * +cuddRemapUnderApprox( + DdManager * dd /* DD manager */, + DdNode * f /* current DD */, + int numVars /* maximum number of variables */, + int threshold /* threshold under which approximation stops */, + double quality /* minimum improvement for accepted changes */) +{ + ApproxInfo *info; + DdNode *subset; + int result; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + /* Create table where node data are accessible via a hash table. */ + info = gatherInfo(dd, f, numVars, CUDD_TRUE); + if (info == NULL) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Mark nodes that should be replaced by zero. */ + result = RAmarkNodes(dd, f, info, threshold, quality); + if (result == 0) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Build the result. */ + subset = RAbuildSubset(dd, f, info); +#if 1 + if (subset && info->size < Cudd_DagSize(subset)) + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); +#endif + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + +#ifdef DD_DEBUG + if (subset != NULL) { + cuddRef(subset); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + } + cuddDeref(subset); + dd->errorCode = CUDD_INTERNAL_ERROR; + } +#endif + return(subset); + +} /* end of cuddRemapUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Applies the biased remapping underappoximation algorithm.] + + Description [Applies the biased remapping underappoximation algorithm. + Proceeds in three phases: +
            +
          • collect information on each node in the BDD; this is done via DFS. +
          • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
          • traverse the BDD via DFS and actually perform the elimination. +
          + Returns the approximated BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_BiasedUnderApprox] + +******************************************************************************/ +DdNode * +cuddBiasedUnderApprox( + DdManager *dd /* DD manager */, + DdNode *f /* current DD */, + DdNode *b /* bias function */, + int numVars /* maximum number of variables */, + int threshold /* threshold under which approximation stops */, + double quality1 /* minimum improvement for accepted changes when b=1 */, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + ApproxInfo *info; + DdNode *subset; + int result; + DdHashTable *cache; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + /* Create table where node data are accessible via a hash table. */ + info = gatherInfo(dd, f, numVars, CUDD_TRUE); + if (info == NULL) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + cache = cuddHashTableInit(dd,2,2); + result = BAapplyBias(dd, Cudd_Regular(f), b, info, cache); + if (result == CARE_ERROR) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + cuddHashTableQuit(cache); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + cuddHashTableQuit(cache); + + /* Mark nodes that should be replaced by zero. */ + result = BAmarkNodes(dd, f, info, threshold, quality1, quality0); + if (result == 0) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Build the result. */ + subset = RAbuildSubset(dd, f, info); +#if 1 + if (subset && info->size < Cudd_DagSize(subset)) + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); +#endif + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + +#ifdef DD_DEBUG + if (subset != NULL) { + cuddRef(subset); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + } + cuddDeref(subset); + dd->errorCode = CUDD_INTERNAL_ERROR; + } +#endif + return(subset); + +} /* end of cuddBiasedUnderApprox */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Recursively update the parity of the paths reaching a node.] + + Description [Recursively update the parity of the paths reaching a node. + Assumes that node is regular and propagates the invariant.] + + SideEffects [None] + + SeeAlso [gatherInfoAux] + +******************************************************************************/ +static void +updateParity( + DdNode * node /* function to analyze */, + ApproxInfo * info /* info on BDD */, + int newparity /* new parity for node */) +{ + NodeData *infoN; + DdNode *E; + + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node)) == NULL) + return; + if ((infoN->parity & newparity) != 0) return; + infoN->parity |= (short) newparity; + if (Cudd_IsConstant(node)) return; + updateParity(cuddT(node),info,newparity); + E = cuddE(node); + if (Cudd_IsComplement(E)) { + updateParity(Cudd_Not(E),info,3-newparity); + } else { + updateParity(E,info,newparity); + } + return; + +} /* end of updateParity */ + + +/**Function******************************************************************** + + Synopsis [Recursively counts minterms and computes reference counts + of each node in the BDD.] + + Description [Recursively counts minterms and computes reference + counts of each node in the BDD. Similar to the cuddCountMintermAux + which recursively counts the number of minterms for the dag rooted + at each node in terms of the total number of variables (max). It assumes + that the node pointer passed to it is regular and it maintains the + invariant.] + + SideEffects [None] + + SeeAlso [gatherInfo] + +******************************************************************************/ +static NodeData * +gatherInfoAux( + DdNode * node /* function to analyze */, + ApproxInfo * info /* info on BDD */, + int parity /* gather parity information */) +{ + DdNode *N, *Nt, *Ne; + NodeData *infoN, *infoT, *infoE; + + N = Cudd_Regular(node); + + /* Check whether entry for this node exists. */ + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, N)) != NULL) { + if (parity) { + /* Update parity and propagate. */ + updateParity(N, info, 1 + (int) Cudd_IsComplement(node)); + } + return(infoN); + } + + /* Compute the cofactors. */ + Nt = Cudd_NotCond(cuddT(N), N != node); + Ne = Cudd_NotCond(cuddE(N), N != node); + + infoT = gatherInfoAux(Nt, info, parity); + if (infoT == NULL) return(NULL); + infoE = gatherInfoAux(Ne, info, parity); + if (infoE == NULL) return(NULL); + + infoT->functionRef++; + infoE->functionRef++; + + /* Point to the correct location in the page. */ + infoN = &(info->page[info->index++]); + infoN->parity |= (short) (1 + Cudd_IsComplement(node)); + + infoN->mintermsP = infoT->mintermsP/2; + infoN->mintermsN = infoT->mintermsN/2; + if (Cudd_IsComplement(Ne) ^ Cudd_IsComplement(node)) { + infoN->mintermsP += infoE->mintermsN/2; + infoN->mintermsN += infoE->mintermsP/2; + } else { + infoN->mintermsP += infoE->mintermsP/2; + infoN->mintermsN += infoE->mintermsN/2; + } + + /* Insert entry for the node in the table. */ + if (cuddHashTableGenericInsert(info->table, N, infoN) == 0) { + return(NULL); + } + return(infoN); + +} /* end of gatherInfoAux */ + + +/**Function******************************************************************** + + Synopsis [Gathers information about each node.] + + Description [Counts minterms and computes reference counts of each + node in the BDD. The minterm count is separately computed for the + node and its complement. This is to avoid cancellation + errors. Returns a pointer to the data structure holding the + information gathered if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddUnderApprox gatherInfoAux] + +******************************************************************************/ +static ApproxInfo * +gatherInfo( + DdManager * dd /* manager */, + DdNode * node /* function to be analyzed */, + int numVars /* number of variables node depends on */, + int parity /* gather parity information */) +{ + ApproxInfo * info; + NodeData * infoTop; + + /* If user did not give numVars value, set it to the maximum + ** exponent that the pow function can take. The -1 is due to the + ** discrepancy in the value that pow takes and the value that + ** log gives. + */ + if (numVars == 0) { + numVars = DBL_MAX_EXP - 1; + } + + info = ALLOC(ApproxInfo,1); + if (info == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + info->max = pow(2.0,(double) numVars); + info->one = DD_ONE(dd); + info->zero = Cudd_Not(info->one); + info->size = Cudd_DagSize(node); + /* All the information gathered will be stored in a contiguous + ** piece of memory, which is allocated here. This can be done + ** efficiently because we have counted the number of nodes of the + ** BDD. info->index points to the next available entry in the array + ** that stores the per-node information. */ + info->page = ALLOC(NodeData,info->size); + if (info->page == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(info); + return(NULL); + } + memset(info->page, 0, info->size * sizeof(NodeData)); /* clear all page */ + info->table = cuddHashTableInit(dd,1,info->size); + if (info->table == NULL) { + FREE(info->page); + FREE(info); + return(NULL); + } + /* We visit the DAG in post-order DFS. Hence, the constant node is + ** in first position, and the root of the DAG is in last position. */ + + /* Info for the constant node: Initialize only fields different from 0. */ + if (cuddHashTableGenericInsert(info->table, info->one, info->page) == 0) { + FREE(info->page); + FREE(info); + cuddHashTableGenericQuit(info->table); + return(NULL); + } + info->page[0].mintermsP = info->max; + info->index = 1; + + infoTop = gatherInfoAux(node,info,parity); + if (infoTop == NULL) { + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + return(NULL); + } + if (Cudd_IsComplement(node)) { + info->minterms = infoTop->mintermsN; + } else { + info->minterms = infoTop->mintermsP; + } + + infoTop->functionRef = 1; + return(info); + +} /* end of gatherInfo */ + + +/**Function******************************************************************** + + Synopsis [Counts the nodes that would be eliminated if a given node + were replaced by zero.] + + Description [Counts the nodes that would be eliminated if a given + node were replaced by zero. This procedure uses a queue passed by + the caller for efficiency: since the queue is left empty at the + endof the search, it can be reused as is by the next search. Returns + the count (always striclty positive) if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [UAmarkNodes RAmarkNodes BAmarkNodes] + +******************************************************************************/ +static int +computeSavings( + DdManager * dd, + DdNode * f, + DdNode * skip, + ApproxInfo * info, + DdLevelQueue * queue) +{ + NodeData *infoN; + LocalQueueItem *item; + DdNode *node; + int savings = 0; + + node = Cudd_Regular(f); + skip = Cudd_Regular(skip); + /* Insert the given node in the level queue. Its local reference + ** count is set equal to the function reference count so that the + ** search will continue from it when it is retrieved. */ + item = (LocalQueueItem *) + cuddLevelQueueFirst(queue,node,cuddI(dd,node->index)); + if (item == NULL) + return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node); + item->localRef = infoN->functionRef; + + /* Process the queue. */ + while ((item = (LocalQueueItem *) queue->first) != NULL) { + node = item->node; + if (node != skip) { + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,node); + if (item->localRef == infoN->functionRef) { + /* This node is not shared. */ + DdNode *nodeT, *nodeE; + savings++; + nodeT = cuddT(node); + if (!cuddIsConstant(nodeT)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeT,cuddI(dd,nodeT->index)); + if (item == NULL) return(0); + item->localRef++; + } + nodeE = Cudd_Regular(cuddE(node)); + if (!cuddIsConstant(nodeE)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeE,cuddI(dd,nodeE->index)); + if (item == NULL) return(0); + item->localRef++; + } + } + } + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + } + +#ifdef DD_DEBUG + /* At the end of a local search the queue should be empty. */ + assert(queue->size == 0); +#endif + return(savings); + +} /* end of computeSavings */ + + +/**Function******************************************************************** + + Synopsis [Update function reference counts.] + + Description [Update function reference counts to account for replacement. + Returns the number of nodes saved if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [UAmarkNodes RAmarkNodes BAmarkNodes] + +******************************************************************************/ +static int +updateRefs( + DdManager * dd, + DdNode * f, + DdNode * skip, + ApproxInfo * info, + DdLevelQueue * queue) +{ + NodeData *infoN; + LocalQueueItem *item; + DdNode *node; + int savings = 0; + + node = Cudd_Regular(f); + /* Insert the given node in the level queue. Its function reference + ** count is set equal to 0 so that the search will continue from it + ** when it is retrieved. */ + item = (LocalQueueItem *) cuddLevelQueueFirst(queue,node,cuddI(dd,node->index)); + if (item == NULL) + return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node); + infoN->functionRef = 0; + + if (skip != NULL) { + /* Increase the function reference count of the node to be skipped + ** by 1 to account for the node pointing to it that will be created. */ + skip = Cudd_Regular(skip); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, skip); + infoN->functionRef++; + } + + /* Process the queue. */ + while ((item = (LocalQueueItem *) queue->first) != NULL) { + node = item->node; + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,node); + if (infoN->functionRef == 0) { + /* This node is not shared or to be be skipped. */ + DdNode *nodeT, *nodeE; + savings++; + nodeT = cuddT(node); + if (!cuddIsConstant(nodeT)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeT,cuddI(dd,nodeT->index)); + if (item == NULL) return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,nodeT); + infoN->functionRef--; + } + nodeE = Cudd_Regular(cuddE(node)); + if (!cuddIsConstant(nodeE)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeE,cuddI(dd,nodeE->index)); + if (item == NULL) return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,nodeE); + infoN->functionRef--; + } + } + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + } + +#ifdef DD_DEBUG + /* At the end of a local search the queue should be empty. */ + assert(queue->size == 0); +#endif + return(savings); + +} /* end of updateRefs */ + + +/**Function******************************************************************** + + Synopsis [Marks nodes for replacement by zero.] + + Description [Marks nodes for replacement by zero. Returns 1 if successful; + 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddUnderApprox] + +******************************************************************************/ +static int +UAmarkNodes( + DdManager * dd /* manager */, + DdNode * f /* function to be analyzed */, + ApproxInfo * info /* info on BDD */, + int threshold /* when to stop approximating */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdLevelQueue *queue; + DdLevelQueue *localQueue; + NodeData *infoN; + GlobalQueueItem *item; + DdNode *node; + double numOnset; + double impactP, impactN; + int savings; + +#if 0 + (void) printf("initial size = %d initial minterms = %g\n", + info->size, info->minterms); +#endif + queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); + if (queue == NULL) { + return(0); + } + localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), + dd->initSlots); + if (localQueue == NULL) { + cuddLevelQueueQuit(queue); + return(0); + } + node = Cudd_Regular(f); + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + if (item == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + if (Cudd_IsComplement(f)) { + item->impactP = 0.0; + item->impactN = 1.0; + } else { + item->impactP = 1.0; + item->impactN = 0.0; + } + while (queue->first != NULL) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; + node = Cudd_Regular(node); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node); + if (safe && infoN->parity == 3) { + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + impactP = item->impactP; + impactN = item->impactN; + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,NULL,info,localQueue); + if (savings == 0) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); +#if 0 + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); +#endif + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = CUDD_TRUE; + info->size -= savings; + info->minterms -=numOnset; +#if 0 + (void) printf("replace: new size = %d new minterms = %g\n", + info->size, info->minterms); +#endif + savings -= updateRefs(dd,node,NULL,info,localQueue); + assert(savings == 0); + continue; + } + if (!cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + if (!Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(1); + +} /* end of UAmarkNodes */ + + +/**Function******************************************************************** + + Synopsis [Builds the subset BDD.] + + Description [Builds the subset BDD. Based on the info table, + replaces selected nodes by zero. Returns a pointer to the result if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddUnderApprox] + +******************************************************************************/ +static DdNode * +UAbuildSubset( + DdManager * dd /* DD manager */, + DdNode * node /* current node */, + ApproxInfo * info /* node info */) +{ + + DdNode *Nt, *Ne, *N, *t, *e, *r; + NodeData *infoN; + + if (Cudd_IsConstant(node)) + return(node); + + N = Cudd_Regular(node); + + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, N)) != NULL) { + if (infoN->replace == CUDD_TRUE) { + return(info->zero); + } + if (N == node ) { + if (infoN->resultP != NULL) { + return(infoN->resultP); + } + } else { + if (infoN->resultN != NULL) { + return(infoN->resultN); + } + } + } else { + (void) fprintf(dd->err, + "Something is wrong, ought to be in info table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node)); + Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node)); + + t = UAbuildSubset(dd, Nt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + + e = UAbuildSubset(dd, Ne, info); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + if (N == node) { + infoN->resultP = r; + } else { + infoN->resultN = r; + } + + return(r); + +} /* end of UAbuildSubset */ + + +/**Function******************************************************************** + + Synopsis [Marks nodes for remapping.] + + Description [Marks nodes for remapping. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddRemapUnderApprox] + +******************************************************************************/ +static int +RAmarkNodes( + DdManager * dd /* manager */, + DdNode * f /* function to be analyzed */, + ApproxInfo * info /* info on BDD */, + int threshold /* when to stop approximating */, + double quality /* minimum improvement for accepted changes */) +{ + DdLevelQueue *queue; + DdLevelQueue *localQueue; + NodeData *infoN, *infoT, *infoE; + GlobalQueueItem *item; + DdNode *node, *T, *E; + DdNode *shared; /* grandchild shared by the two children of node */ + double numOnset; + double impact, impactP, impactN; + double minterms; + int savings; + int replace; + +#if 0 + (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n", + info->size, info->minterms); +#endif + queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); + if (queue == NULL) { + return(0); + } + localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), + dd->initSlots); + if (localQueue == NULL) { + cuddLevelQueueQuit(queue); + return(0); + } + /* Enqueue regular pointer to root and initialize impact. */ + node = Cudd_Regular(f); + item = (GlobalQueueItem *) + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + if (item == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + if (Cudd_IsComplement(f)) { + item->impactP = 0.0; + item->impactN = 1.0; + } else { + item->impactP = 1.0; + item->impactN = 0.0; + } + /* The nodes retrieved here are guaranteed to be non-terminal. + ** The initial node is not terminal because constant nodes are + ** dealt with in the calling procedure. Subsequent nodes are inserted + ** only if they are not terminal. */ + while ((item = (GlobalQueueItem *) queue->first) != NULL) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + node = item->node; +#ifdef DD_DEBUG + assert(item->impactP >= 0 && item->impactP <= 1.0); + assert(item->impactN >= 0 && item->impactN <= 1.0); + assert(!Cudd_IsComplement(node)); + assert(!Cudd_IsConstant(node)); +#endif + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node)) == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } +#ifdef DD_DEBUG + assert(infoN->parity >= 1 && infoN->parity <= 3); +#endif + if (infoN->parity == 3) { + /* This node can be reached through paths of different parity. + ** It is not safe to replace it, because remapping will give + ** an incorrect result, while replacement by 0 may cause node + ** splitting. */ + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + T = cuddT(node); + E = cuddE(node); + shared = NULL; + impactP = item->impactP; + impactN = item->impactN; + if (Cudd_bddLeq(dd,T,E)) { + /* Here we know that E is regular. */ +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(E)); +#endif + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, E); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; + if (infoE->functionRef == 1 && !cuddIsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; + if (infoT->functionRef == 1 && !cuddIsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } + numOnset = impact * minterms; + } else if (Cudd_bddLeq(dd,E,T)) { + /* Here E may be complemented. */ + DdNode *Ereg = Cudd_Regular(E); + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, Ereg); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoT->mintermsP/2.0 - + ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; + if (infoT->functionRef == 1 && !cuddIsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = ((E == Ereg) ? infoE->mintermsN : + infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; + if (infoE->functionRef == 1 && !cuddIsConstant(Ereg)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } + numOnset = impact * minterms; + } else { + DdNode *Ereg = Cudd_Regular(E); + DdNode *TT = cuddT(T); + DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TT == ET) { + shared = TT; + replace = REPLACE_TT; + } else { + DdNode *TE = cuddE(T); + DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TE == EE) { + shared = TE; + replace = REPLACE_TE; + } else { + replace = REPLACE_N; + } + } + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,shared,info,localQueue); + if (shared != NULL) { + NodeData *infoS; + infoS = (NodeData *) cuddHashTableGenericLookup(info->table, Cudd_Regular(shared)); + if (Cudd_IsComplement(shared)) { + numOnset -= (infoS->mintermsN * impactP + + infoS->mintermsP * impactN)/2.0; + } else { + numOnset -= (infoS->mintermsP * impactP + + infoS->mintermsN * impactN)/2.0; + } + savings--; + } + } + + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); +#if 0 + if (replace == REPLACE_T || replace == REPLACE_E) + (void) printf("node %p: impact = %g numOnset = %g savings %d\n", + node, impact, numOnset, savings); + else + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); +#endif + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = (char) replace; + info->size -= savings; + info->minterms -=numOnset; +#if 0 + (void) printf("remap(%d): new size = %d new minterms = %g\n", + replace, info->size, info->minterms); +#endif + if (replace == REPLACE_N) { + savings -= updateRefs(dd,node,NULL,info,localQueue); + } else if (replace == REPLACE_T) { + savings -= updateRefs(dd,node,E,info,localQueue); + } else if (replace == REPLACE_E) { + savings -= updateRefs(dd,node,T,info,localQueue); + } else { +#ifdef DD_DEBUG + assert(replace == REPLACE_TT || replace == REPLACE_TE); +#endif + savings -= updateRefs(dd,node,shared,info,localQueue) - 1; + } + assert(savings == 0); + } else { + replace = NOTHING; + } + if (replace == REPLACE_N) continue; + if ((replace == REPLACE_E || replace == NOTHING) && + !cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (replace == REPLACE_E) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + if ((replace == REPLACE_T || replace == NOTHING) && + !Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + if ((replace == REPLACE_TT || replace == REPLACE_TE) && + !Cudd_IsConstant(shared)) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), + cuddI(dd,Cudd_Regular(shared)->index)); + if (Cudd_IsComplement(shared)) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactP; + item->impactN += impactN; + } + } + } + + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(1); + +} /* end of RAmarkNodes */ + + +/**Function******************************************************************** + + Synopsis [Marks nodes for remapping.] + + Description [Marks nodes for remapping. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddBiasedUnderApprox] + +******************************************************************************/ +static int +BAmarkNodes( + DdManager *dd /* manager */, + DdNode *f /* function to be analyzed */, + ApproxInfo *info /* info on BDD */, + int threshold /* when to stop approximating */, + double quality1 /* minimum improvement for accepted changes when b=1 */, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + DdLevelQueue *queue; + DdLevelQueue *localQueue; + NodeData *infoN, *infoT, *infoE; + GlobalQueueItem *item; + DdNode *node, *T, *E; + DdNode *shared; /* grandchild shared by the two children of node */ + double numOnset; + double impact, impactP, impactN; + double minterms; + double quality; + int savings; + int replace; + +#if 0 + (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n", + info->size, info->minterms); +#endif + queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); + if (queue == NULL) { + return(0); + } + localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), + dd->initSlots); + if (localQueue == NULL) { + cuddLevelQueueQuit(queue); + return(0); + } + /* Enqueue regular pointer to root and initialize impact. */ + node = Cudd_Regular(f); + item = (GlobalQueueItem *) + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + if (item == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + if (Cudd_IsComplement(f)) { + item->impactP = 0.0; + item->impactN = 1.0; + } else { + item->impactP = 1.0; + item->impactN = 0.0; + } + /* The nodes retrieved here are guaranteed to be non-terminal. + ** The initial node is not terminal because constant nodes are + ** dealt with in the calling procedure. Subsequent nodes are inserted + ** only if they are not terminal. */ + while (queue->first != NULL) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; +#ifdef DD_DEBUG + assert(item->impactP >= 0 && item->impactP <= 1.0); + assert(item->impactN >= 0 && item->impactN <= 1.0); + assert(!Cudd_IsComplement(node)); + assert(!Cudd_IsConstant(node)); +#endif + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node)) == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + quality = infoN->care ? quality1 : quality0; +#ifdef DD_DEBUG + assert(infoN->parity >= 1 && infoN->parity <= 3); +#endif + if (infoN->parity == 3) { + /* This node can be reached through paths of different parity. + ** It is not safe to replace it, because remapping will give + ** an incorrect result, while replacement by 0 may cause node + ** splitting. */ + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + T = cuddT(node); + E = cuddE(node); + shared = NULL; + impactP = item->impactP; + impactN = item->impactN; + if (Cudd_bddLeq(dd,T,E)) { + /* Here we know that E is regular. */ +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(E)); +#endif + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, E); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } + numOnset = impact * minterms; + } else if (Cudd_bddLeq(dd,E,T)) { + /* Here E may be complemented. */ + DdNode *Ereg = Cudd_Regular(E); + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, Ereg); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoT->mintermsP/2.0 - + ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = ((E == Ereg) ? infoE->mintermsN : + infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } + numOnset = impact * minterms; + } else { + DdNode *Ereg = Cudd_Regular(E); + DdNode *TT = cuddT(T); + DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TT == ET) { + shared = TT; + replace = REPLACE_TT; + } else { + DdNode *TE = cuddE(T); + DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TE == EE) { + shared = TE; + replace = REPLACE_TE; + } else { + replace = REPLACE_N; + } + } + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,shared,info,localQueue); + if (shared != NULL) { + NodeData *infoS; + infoS = (NodeData *) cuddHashTableGenericLookup(info->table, Cudd_Regular(shared)); + if (Cudd_IsComplement(shared)) { + numOnset -= (infoS->mintermsN * impactP + + infoS->mintermsP * impactN)/2.0; + } else { + numOnset -= (infoS->mintermsP * impactP + + infoS->mintermsN * impactN)/2.0; + } + savings--; + } + } + + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); +#if 0 + if (replace == REPLACE_T || replace == REPLACE_E) + (void) printf("node %p: impact = %g numOnset = %g savings %d\n", + node, impact, numOnset, savings); + else + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); +#endif + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = (char) replace; + info->size -= savings; + info->minterms -=numOnset; +#if 0 + (void) printf("remap(%d): new size = %d new minterms = %g\n", + replace, info->size, info->minterms); +#endif + if (replace == REPLACE_N) { + savings -= updateRefs(dd,node,NULL,info,localQueue); + } else if (replace == REPLACE_T) { + savings -= updateRefs(dd,node,E,info,localQueue); + } else if (replace == REPLACE_E) { + savings -= updateRefs(dd,node,T,info,localQueue); + } else { +#ifdef DD_DEBUG + assert(replace == REPLACE_TT || replace == REPLACE_TE); +#endif + savings -= updateRefs(dd,node,shared,info,localQueue) - 1; + } + assert(savings == 0); + } else { + replace = NOTHING; + } + if (replace == REPLACE_N) continue; + if ((replace == REPLACE_E || replace == NOTHING) && + !cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (replace == REPLACE_E) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + if ((replace == REPLACE_T || replace == NOTHING) && + !Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + if ((replace == REPLACE_TT || replace == REPLACE_TE) && + !Cudd_IsConstant(shared)) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), + cuddI(dd,Cudd_Regular(shared)->index)); + if (Cudd_IsComplement(shared)) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + } + + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(1); + +} /* end of BAmarkNodes */ + + +/**Function******************************************************************** + + Synopsis [Builds the subset BDD for cuddRemapUnderApprox.] + + Description [Builds the subset BDDfor cuddRemapUnderApprox. Based + on the info table, performs remapping or replacement at selected + nodes. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [cuddRemapUnderApprox] + +******************************************************************************/ +static DdNode * +RAbuildSubset( + DdManager * dd /* DD manager */, + DdNode * node /* current node */, + ApproxInfo * info /* node info */) +{ + DdNode *Nt, *Ne, *N, *t, *e, *r; + NodeData *infoN; + + if (Cudd_IsConstant(node)) + return(node); + + N = Cudd_Regular(node); + + Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node)); + Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node)); + + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, N)) != NULL) { + if (N == node ) { + if (infoN->resultP != NULL) { + return(infoN->resultP); + } + } else { + if (infoN->resultN != NULL) { + return(infoN->resultN); + } + } + if (infoN->replace == REPLACE_T) { + r = RAbuildSubset(dd, Ne, info); + return(r); + } else if (infoN->replace == REPLACE_E) { + r = RAbuildSubset(dd, Nt, info); + return(r); + } else if (infoN->replace == REPLACE_N) { + return(info->zero); + } else if (infoN->replace == REPLACE_TT) { + DdNode *Ntt = Cudd_NotCond(cuddT(cuddT(N)), + Cudd_IsComplement(node)); + int index = cuddT(N)->index; + e = info->zero; + t = RAbuildSubset(dd, Ntt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + return(r); + } else if (infoN->replace == REPLACE_TE) { + DdNode *Nte = Cudd_NotCond(cuddE(cuddT(N)), + Cudd_IsComplement(node)); + int index = cuddT(N)->index; + t = info->one; + e = RAbuildSubset(dd, Nte, info); + if (e == NULL) { + return(NULL); + } + cuddRef(e); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + r =Cudd_Not(r); + cuddDeref(e); + return(r); + } + } else { + (void) fprintf(dd->err, + "Something is wrong, ought to be in info table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + t = RAbuildSubset(dd, Nt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + + e = RAbuildSubset(dd, Ne, info); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + if (N == node) { + infoN->resultP = r; + } else { + infoN->resultN = r; + } + + return(r); + +} /* end of RAbuildSubset */ + + +/**Function******************************************************************** + + Synopsis [Finds don't care nodes.] + + Description [Finds don't care nodes by traversing f and b in parallel. + Returns the care status of the visited f node if successful; CARE_ERROR + otherwise.] + + SideEffects [None] + + SeeAlso [cuddBiasedUnderApprox] + +******************************************************************************/ +static int +BAapplyBias( + DdManager *dd, + DdNode *f, + DdNode *b, + ApproxInfo *info, + DdHashTable *cache) +{ + DdNode *one, *zero, *res; + DdNode *Ft, *Fe, *B, *Bt, *Be; + unsigned int topf, topb; + NodeData *infoF; + int careT, careE; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + if ((infoF = (NodeData *) cuddHashTableGenericLookup(info->table, f)) == NULL) + return(CARE_ERROR); + if (f == one) return(TOTAL_CARE); + if (b == zero) return(infoF->care); + if (infoF->care == TOTAL_CARE) return(TOTAL_CARE); + + if ((f->ref != 1 || Cudd_Regular(b)->ref != 1) && + (res = cuddHashTableLookup2(cache,f,b)) != NULL) { + if (res->ref == 0) { + cache->manager->dead++; + cache->manager->constants.dead++; + } + return(infoF->care); + } + + topf = dd->perm[f->index]; + B = Cudd_Regular(b); + topb = cuddI(dd,B->index); + if (topf <= topb) { + Ft = cuddT(f); Fe = cuddE(f); + } else { + Ft = Fe = f; + } + if (topb <= topf) { + /* We know that b is not constant because f is not. */ + Bt = cuddT(B); Be = cuddE(B); + if (Cudd_IsComplement(b)) { + Bt = Cudd_Not(Bt); + Be = Cudd_Not(Be); + } + } else { + Bt = Be = b; + } + + careT = BAapplyBias(dd, Ft, Bt, info, cache); + if (careT == CARE_ERROR) + return(CARE_ERROR); + careE = BAapplyBias(dd, Cudd_Regular(Fe), Be, info, cache); + if (careE == CARE_ERROR) + return(CARE_ERROR); + if (careT == TOTAL_CARE && careE == TOTAL_CARE) { + infoF->care = TOTAL_CARE; + } else { + infoF->care = CARE; + } + + if (f->ref != 1 || Cudd_Regular(b)->ref != 1) { + ptrint fanout = (ptrint) f->ref * Cudd_Regular(b)->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert2(cache,f,b,one,fanout)) { + return(CARE_ERROR); + } + } + return(infoF->care); + +} /* end of BAapplyBias */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddBddAbs.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddBddAbs.c new file mode 100644 index 000000000..a806078c5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddBddAbs.c @@ -0,0 +1,760 @@ +/**CFile*********************************************************************** + + FileName [cuddBddAbs.c] + + PackageName [cudd] + + Synopsis [Quantification functions for BDDs.] + + Description [External procedures included in this module: +
            +
          • Cudd_bddExistAbstract() +
          • Cudd_bddExistAbstractLimit() +
          • Cudd_bddXorExistAbstract() +
          • Cudd_bddUnivAbstract() +
          • Cudd_bddBooleanDiff() +
          • Cudd_bddVarIsDependent() +
          + Internal procedures included in this module: +
            +
          • cuddBddExistAbstractRecur() +
          • cuddBddXorExistAbstractRecur() +
          • cuddBddBooleanDiffRecur() +
          + Static procedures included in this module: +
            +
          • bddCheckPositiveCube() +
          + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.28 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int bddCheckPositiveCube (DdManager *manager, DdNode *cube); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Existentially abstracts all the variables in cube from f.] + + Description [Existentially abstracts all the variables in cube from f. + Returns the abstracted BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddUnivAbstract Cudd_addExistAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddExistAbstract */ + + +/**Function******************************************************************** + + Synopsis [Existentially abstracts all the variables in cube from f.] + + Description [Existentially abstracts all the variables in cube from f. + Returns the abstracted BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddExistAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddExistAbstractLimit( + DdManager * manager, + DdNode * f, + DdNode * cube, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = manager->maxLive; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + manager->maxLive = (manager->keys - manager->dead) + + (manager->keysZ - manager->deadZ) + limit; + do { + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + manager->maxLive = saveLimit; + + return(res); + +} /* end of Cudd_bddExistAbstractLimit */ + + +/**Function******************************************************************** + + Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the exclusive OR of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddUnivAbstract Cudd_bddExistAbstract Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddXorExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *res; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddBddXorExistAbstractRecur(manager, f, g, cube); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddXorExistAbstract */ + + +/**Function******************************************************************** + + Synopsis [Universally abstracts all the variables in cube from f.] + + Description [Universally abstracts all the variables in cube from f. + Returns the abstracted BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddExistAbstract Cudd_addUnivAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddUnivAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube); + } while (manager->reordered == 1); + if (res != NULL) res = Cudd_Not(res); + + return(res); + +} /* end of Cudd_bddUnivAbstract */ + + +/**Function******************************************************************** + + Synopsis [Computes the boolean difference of f with respect to x.] + + Description [Computes the boolean difference of f with respect to the + variable with index x. Returns the BDD of the boolean difference if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_bddBooleanDiff( + DdManager * manager, + DdNode * f, + int x) +{ + DdNode *res, *var; + + /* If the variable is not currently in the manager, f cannot + ** depend on it. + */ + if (x >= manager->size) return(Cudd_Not(DD_ONE(manager))); + var = manager->vars[x]; + + do { + manager->reordered = 0; + res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddBooleanDiff */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is dependent on others in a + function.] + + Description [Checks whether a variable is dependent on others in a + function. Returns 1 if the variable is dependent; 0 otherwise. No + new nodes are created.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_bddVarIsDependent( + DdManager *dd, /* manager */ + DdNode *f, /* function */ + DdNode *var /* variable */) +{ + DdNode *F, *res, *zero, *ft, *fe; + unsigned topf, level; + DD_CTFP cacheOp; + int retval; + + zero = Cudd_Not(DD_ONE(dd)); + if (Cudd_IsConstant(f)) return(f == zero); + + /* From now on f is not constant. */ + F = Cudd_Regular(f); + topf = (unsigned) dd->perm[F->index]; + level = (unsigned) dd->perm[var->index]; + + /* Check terminal case. If topf > index of var, f does not depend on var. + ** Therefore, var is not dependent in f. */ + if (topf > level) { + return(0); + } + + cacheOp = (DD_CTFP) Cudd_bddVarIsDependent; + res = cuddCacheLookup2(dd,cacheOp,f,var); + if (res != NULL) { + return(res != zero); + } + + /* Compute cofactors. */ + ft = Cudd_NotCond(cuddT(F), f != F); + fe = Cudd_NotCond(cuddE(F), f != F); + + if (topf == level) { + retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe)); + } else { + retval = Cudd_bddVarIsDependent(dd,ft,var) && + Cudd_bddVarIsDependent(dd,fe,var); + } + + cuddCacheInsert2(dd,cacheOp,f,var,Cudd_NotCond(zero,retval)); + + return(retval); + +} /* Cudd_bddVarIsDependent */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive steps of Cudd_bddExistAbstract.] + + Description [Performs the recursive steps of Cudd_bddExistAbstract. + Returns the BDD obtained by abstracting the variables + of cube from f if successful; NULL otherwise. It is also used by + Cudd_bddUnivAbstract.] + + SideEffects [None] + + SeeAlso [Cudd_bddExistAbstract Cudd_bddUnivAbstract] + +******************************************************************************/ +DdNode * +cuddBddExistAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *F, *T, *E, *res, *res1, *res2, *one; + + statLine(manager); + one = DD_ONE(manager); + F = Cudd_Regular(f); + + /* Cube is guaranteed to be a cube at this point. */ + if (cube == one || F == one) { + return(f); + } + /* From now on, f and cube are non-constant. */ + + /* Abstract a variable that does not appear in f. */ + while (manager->perm[F->index] > manager->perm[cube->index]) { + cube = cuddT(cube); + if (cube == one) return(f); + } + + /* Check the cache. */ + if (F->ref != 1 && (res = cuddCacheLookup2(manager, Cudd_bddExistAbstract, f, cube)) != NULL) { + return(res); + } + + /* Compute the cofactors of f. */ + T = cuddT(F); E = cuddE(F); + if (f != F) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + + /* If the two indices are the same, so are their levels. */ + if (F->index == cube->index) { + if (T == one || E == one || T == Cudd_Not(E)) { + return(one); + } + res1 = cuddBddExistAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + if (res1 == one) { + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, one); + return(one); + } + cuddRef(res1); + res2 = cuddBddExistAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddBddAndRecur(manager, Cudd_Not(res1), Cudd_Not(res2)); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + res = Cudd_Not(res); + cuddRef(res); + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); + cuddDeref(res); + return(res); + } else { /* if (cuddI(manager,F->index) < cuddI(manager,cube->index)) */ + res1 = cuddBddExistAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddBddExistAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager, res1); + return(NULL); + } + cuddRef(res2); + /* ITE takes care of possible complementation of res1 and of the + ** case in which res1 == res2. */ + res = cuddBddIteRecur(manager, manager->vars[F->index], res1, res2); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); + return(res); + } + +} /* end of cuddBddExistAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the exclusive OR of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +cuddBddXorExistAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *F, *fv, *fnv, *G, *gv, *gnv; + DdNode *one, *zero, *r, *t, *e, *Cube; + unsigned int topf, topg, topcube, top, index; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == g) { + return(zero); + } + if (f == Cudd_Not(g)) { + return(one); + } + if (cube == one) { + return(cuddBddXorRecur(manager, f, g)); + } + if (f == one) { + return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube)); + } + if (g == one) { + return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube)); + } + if (f == zero) { + return(cuddBddExistAbstractRecur(manager, g, cube)); + } + if (g == zero) { + return(cuddBddExistAbstractRecur(manager, f, cube)); + } + + /* At this point f, g, and cube are not constant. */ + + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; + g = tmp; + } + + /* Check cache. */ + r = cuddCacheLookup(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube); + if (r != NULL) { + return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + F = Cudd_Regular(f); + topf = manager->perm[F->index]; + G = Cudd_Regular(g); + topg = manager->perm[G->index]; + top = ddMin(topf, topg); + topcube = manager->perm[cube->index]; + + if (topcube < top) { + return(cuddBddXorExistAbstractRecur(manager, f, g, cuddT(cube))); + } + /* Now, topcube >= top. */ + + if (topf == top) { + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } + } else { + index = G->index; + fv = fnv = f; + } + + if (topg == top) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + if (topcube == top) { + Cube = cuddT(cube); + } else { + Cube = cube; + } + + t = cuddBddXorExistAbstractRecur(manager, fv, gv, Cube); + if (t == NULL) return(NULL); + + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. + */ + if (t == one && topcube == top) { + cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, one); + return(one); + } + cuddRef(t); + + e = cuddBddXorExistAbstractRecur(manager, fnv, gnv, Cube); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (topcube == top) { /* abstract */ + r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + cuddDeref(r); + } else if (t == e) { + r = t; + cuddDeref(t); + cuddDeref(e); + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + } + cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, r); + return (r); + +} /* end of cuddBddXorExistAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive steps of Cudd_bddBoleanDiff.] + + Description [Performs the recursive steps of Cudd_bddBoleanDiff. + Returns the BDD obtained by XORing the cofactors of f with respect to + var if successful; NULL otherwise. Exploits the fact that dF/dx = + dF'/dx.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddBddBooleanDiffRecur( + DdManager * manager, + DdNode * f, + DdNode * var) +{ + DdNode *T, *E, *res, *res1, *res2; + + statLine(manager); + if (cuddI(manager,f->index) > manager->perm[var->index]) { + /* f does not depend on var. */ + return(Cudd_Not(DD_ONE(manager))); + } + + /* From now on, f is non-constant. */ + + /* If the two indices are the same, so are their levels. */ + if (f->index == var->index) { + res = cuddBddXorRecur(manager, cuddT(f), cuddE(f)); + return(res); + } + + /* From now on, cuddI(manager,f->index) < cuddI(manager,cube->index). */ + + /* Check the cache. */ + res = cuddCacheLookup2(manager, cuddBddBooleanDiffRecur, f, var); + if (res != NULL) { + return(res); + } + + /* Compute the cofactors of f. */ + T = cuddT(f); E = cuddE(f); + + res1 = cuddBddBooleanDiffRecur(manager, T, var); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddBddBooleanDiffRecur(manager, Cudd_Regular(E), var); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager, res1); + return(NULL); + } + cuddRef(res2); + /* ITE takes care of possible complementation of res1 and of the + ** case in which res1 == res2. */ + res = cuddBddIteRecur(manager, manager->vars[f->index], res1, res2); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, cuddBddBooleanDiffRecur, f, var, res); + return(res); + +} /* end of cuddBddBooleanDiffRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Checks whether cube is an BDD representing the product of + positive literals.] + + Description [Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +bddCheckPositiveCube( + DdManager * manager, + DdNode * cube) +{ + if (Cudd_IsComplement(cube)) return(0); + if (cube == DD_ONE(manager)) return(1); + if (cuddIsConstant(cube)) return(0); + if (cuddE(cube) == Cudd_Not(DD_ONE(manager))) { + return(bddCheckPositiveCube(manager, cuddT(cube))); + } + return(0); + +} /* end of bddCheckPositiveCube */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddBddCorr.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddBddCorr.c new file mode 100644 index 000000000..e92d24ad6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddBddCorr.c @@ -0,0 +1,515 @@ +/**CFile*********************************************************************** + + FileName [cuddBddCorr.c] + + PackageName [cudd] + + Synopsis [Correlation between BDDs.] + + Description [External procedures included in this module: +
            +
          • Cudd_bddCorrelation() +
          • Cudd_bddCorrelationWeights() +
          + Static procedures included in this module: +
            +
          • bddCorrelationAux() +
          • bddCorrelationWeightsAux() +
          • CorrelCompare() +
          • CorrelHash() +
          • CorrelCleanUp() +
          + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct hashEntry { + DdNode *f; + DdNode *g; +} HashEntry; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBddCorr.c,v 1.15 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef CORREL_STATS +static int num_calls; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static double bddCorrelationAux (DdManager *dd, DdNode *f, DdNode *g, st_table *table); +static double bddCorrelationWeightsAux (DdManager *dd, DdNode *f, DdNode *g, double *prob, st_table *table); +static int CorrelCompare (const char *key1, const char *key2); +static int CorrelHash (char *key, int modulus); +static enum st_retval CorrelCleanUp (char *key, char *value, char *arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the correlation of f and g.] + + Description [Computes the correlation of f and g. If f == g, their + correlation is 1. If f == g', their correlation is 0. Returns the + fraction of minterms in the ON-set of the EXNOR of f and g. If it + runs out of memory, returns (double)CUDD_OUT_OF_MEM.] + + SideEffects [None] + + SeeAlso [Cudd_bddCorrelationWeights] + +******************************************************************************/ +double +Cudd_bddCorrelation( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + + st_table *table; + double correlation; + +#ifdef CORREL_STATS + num_calls = 0; +#endif + + table = st_init_table(CorrelCompare,CorrelHash); + if (table == NULL) return((double)CUDD_OUT_OF_MEM); + correlation = bddCorrelationAux(manager,f,g,table); + st_foreach(table, CorrelCleanUp, NIL(char)); + st_free_table(table); + return(correlation); + +} /* end of Cudd_bddCorrelation */ + + +/**Function******************************************************************** + + Synopsis [Computes the correlation of f and g for given input + probabilities.] + + Description [Computes the correlation of f and g for given input + probabilities. On input, prob\[i\] is supposed to contain the + probability of the i-th input variable to be 1. + If f == g, their correlation is 1. If f == g', their + correlation is 0. Returns the probability that f and g have the same + value. If it runs out of memory, returns (double)CUDD_OUT_OF_MEM. The + correlation of f and the constant one gives the probability of f.] + + SideEffects [None] + + SeeAlso [Cudd_bddCorrelation] + +******************************************************************************/ +double +Cudd_bddCorrelationWeights( + DdManager * manager, + DdNode * f, + DdNode * g, + double * prob) +{ + + st_table *table; + double correlation; + +#ifdef CORREL_STATS + num_calls = 0; +#endif + + table = st_init_table(CorrelCompare,CorrelHash); + if (table == NULL) return((double)CUDD_OUT_OF_MEM); + correlation = bddCorrelationWeightsAux(manager,f,g,prob,table); + st_foreach(table, CorrelCleanUp, NIL(char)); + st_free_table(table); + return(correlation); + +} /* end of Cudd_bddCorrelationWeights */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCorrelation.] + + Description [Performs the recursive step of Cudd_bddCorrelation. + Returns the fraction of minterms in the ON-set of the EXNOR of f and + g.] + + SideEffects [None] + + SeeAlso [bddCorrelationWeightsAux] + +******************************************************************************/ +static double +bddCorrelationAux( + DdManager * dd, + DdNode * f, + DdNode * g, + st_table * table) +{ + DdNode *Fv, *Fnv, *G, *Gv, *Gnv; + double min, *pmin, min1, min2, *dummy; + HashEntry *entry; + unsigned int topF, topG; + + statLine(dd); +#ifdef CORREL_STATS + num_calls++; +#endif + + /* Terminal cases: only work for BDDs. */ + if (f == g) return(1.0); + if (f == Cudd_Not(g)) return(0.0); + + /* Standardize call using the following properties: + ** (f EXNOR g) = (g EXNOR f) + ** (f' EXNOR g') = (f EXNOR g). + */ + if (f > g) { + DdNode *tmp = f; + f = g; g = tmp; + } + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + g = Cudd_Not(g); + } + /* From now on, f is regular. */ + + entry = ALLOC(HashEntry,1); + if (entry == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + entry->f = f; entry->g = g; + + /* We do not use the fact that + ** correlation(f,g') = 1 - correlation(f,g) + ** to minimize the risk of cancellation. + */ + if (st_lookup(table, entry, &dummy)) { + min = *dummy; + FREE(entry); + return(min); + } + + G = Cudd_Regular(g); + topF = cuddI(dd,f->index); topG = cuddI(dd,G->index); + if (topF <= topG) { Fv = cuddT(f); Fnv = cuddE(f); } else { Fv = Fnv = f; } + if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; } + + if (g != G) { + Gv = Cudd_Not(Gv); + Gnv = Cudd_Not(Gnv); + } + + min1 = bddCorrelationAux(dd, Fv, Gv, table) / 2.0; + if (min1 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return(CUDD_OUT_OF_MEM); + } + min2 = bddCorrelationAux(dd, Fnv, Gnv, table) / 2.0; + if (min2 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return(CUDD_OUT_OF_MEM); + } + min = (min1+min2); + + pmin = ALLOC(double,1); + if (pmin == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + *pmin = min; + + if (st_insert(table,(char *)entry, (char *)pmin) == ST_OUT_OF_MEM) { + FREE(entry); + FREE(pmin); + return((double)CUDD_OUT_OF_MEM); + } + return(min); + +} /* end of bddCorrelationAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCorrelationWeigths.] + + Description [] + + SideEffects [None] + + SeeAlso [bddCorrelationAux] + +******************************************************************************/ +static double +bddCorrelationWeightsAux( + DdManager * dd, + DdNode * f, + DdNode * g, + double * prob, + st_table * table) +{ + DdNode *Fv, *Fnv, *G, *Gv, *Gnv; + double min, *pmin, min1, min2, *dummy; + HashEntry *entry; + int topF, topG, index; + + statLine(dd); +#ifdef CORREL_STATS + num_calls++; +#endif + + /* Terminal cases: only work for BDDs. */ + if (f == g) return(1.0); + if (f == Cudd_Not(g)) return(0.0); + + /* Standardize call using the following properties: + ** (f EXNOR g) = (g EXNOR f) + ** (f' EXNOR g') = (f EXNOR g). + */ + if (f > g) { + DdNode *tmp = f; + f = g; g = tmp; + } + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + g = Cudd_Not(g); + } + /* From now on, f is regular. */ + + entry = ALLOC(HashEntry,1); + if (entry == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + entry->f = f; entry->g = g; + + /* We do not use the fact that + ** correlation(f,g') = 1 - correlation(f,g) + ** to minimize the risk of cancellation. + */ + if (st_lookup(table, entry, &dummy)) { + min = *dummy; + FREE(entry); + return(min); + } + + G = Cudd_Regular(g); + topF = cuddI(dd,f->index); topG = cuddI(dd,G->index); + if (topF <= topG) { + Fv = cuddT(f); Fnv = cuddE(f); + index = f->index; + } else { + Fv = Fnv = f; + index = G->index; + } + if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; } + + if (g != G) { + Gv = Cudd_Not(Gv); + Gnv = Cudd_Not(Gnv); + } + + min1 = bddCorrelationWeightsAux(dd, Fv, Gv, prob, table) * prob[index]; + if (min1 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return((double)CUDD_OUT_OF_MEM); + } + min2 = bddCorrelationWeightsAux(dd, Fnv, Gnv, prob, table) * (1.0 - prob[index]); + if (min2 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return((double)CUDD_OUT_OF_MEM); + } + min = (min1+min2); + + pmin = ALLOC(double,1); + if (pmin == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + *pmin = min; + + if (st_insert(table,(char *)entry, (char *)pmin) == ST_OUT_OF_MEM) { + FREE(entry); + FREE(pmin); + return((double)CUDD_OUT_OF_MEM); + } + return(min); + +} /* end of bddCorrelationWeightsAux */ + + +/**Function******************************************************************** + + Synopsis [Compares two hash table entries.] + + Description [Compares two hash table entries. Returns 0 if they are + identical; 1 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +CorrelCompare( + const char * key1, + const char * key2) +{ + HashEntry *entry1; + HashEntry *entry2; + + entry1 = (HashEntry *) key1; + entry2 = (HashEntry *) key2; + if (entry1->f != entry2->f || entry1->g != entry2->g) return(1); + + return(0); + +} /* end of CorrelCompare */ + + +/**Function******************************************************************** + + Synopsis [Hashes a hash table entry.] + + Description [Hashes a hash table entry. It is patterned after + st_strhash. Returns a value between 0 and modulus.] + + SideEffects [None] + +******************************************************************************/ +static int +CorrelHash( + char * key, + int modulus) +{ + HashEntry *entry; + int val = 0; + + entry = (HashEntry *) key; +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + val = ((int) ((long)entry->f))*997 + ((int) ((long)entry->g)); +#else + val = ((int) entry->f)*997 + ((int) entry->g); +#endif + + return ((val < 0) ? -val : val) % modulus; + +} /* end of CorrelHash */ + + +/**Function******************************************************************** + + Synopsis [Frees memory associated with hash table.] + + Description [Frees memory associated with hash table. Returns + ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +CorrelCleanUp( + char * key, + char * value, + char * arg) +{ + double *d; + HashEntry *entry; + + entry = (HashEntry *) key; + FREE(entry); + d = (double *)value; + FREE(d); + return ST_CONTINUE; + +} /* end of CorrelCleanUp */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddBddIte.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddBddIte.c new file mode 100644 index 000000000..750a51c74 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddBddIte.c @@ -0,0 +1,1430 @@ +/**CFile*********************************************************************** + + FileName [cuddBddIte.c] + + PackageName [cudd] + + Synopsis [BDD ITE function and satellites.] + + Description [External procedures included in this module: +
            +
          • Cudd_bddIte() +
          • Cudd_bddIteLimit() +
          • Cudd_bddIteConstant() +
          • Cudd_bddIntersect() +
          • Cudd_bddAnd() +
          • Cudd_bddAndLimit() +
          • Cudd_bddOr() +
          • Cudd_bddOrLimit() +
          • Cudd_bddNand() +
          • Cudd_bddNor() +
          • Cudd_bddXor() +
          • Cudd_bddXnor() +
          • Cudd_bddXnorLimit() +
          • Cudd_bddLeq() +
          + Internal procedures included in this module: +
            +
          • cuddBddIteRecur() +
          • cuddBddIntersectRecur() +
          • cuddBddAndRecur() +
          • cuddBddXorRecur() +
          + Static procedures included in this module: +
            +
          • bddVarToConst() +
          • bddVarToCanonical() +
          • bddVarToCanonicalSimple() +
          ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBddIte.c,v 1.26 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void bddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one); +static int bddVarToCanonical (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp); +static int bddVarToCanonicalSimple (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements ITE(f,g,h).] + + Description [Implements ITE(f,g,h). Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows + up.] + + SideEffects [None] + + SeeAlso [Cudd_addIte Cudd_bddIteConstant Cudd_bddIntersect] + +******************************************************************************/ +DdNode * +Cudd_bddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddIteRecur(dd,f,g,h); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddIte */ + + +/**Function******************************************************************** + + Synopsis [Implements ITE(f,g,h). Returns + NULL if too many nodes are required.] + + Description [Implements ITE(f,g,h). Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte] + +******************************************************************************/ +DdNode * +Cudd_bddIteLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddIteRecur(dd,f,g,h); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddIteLimit */ + + +/**Function******************************************************************** + + Synopsis [Implements ITEconstant(f,g,h).] + + Description [Implements ITEconstant(f,g,h). Returns a pointer to the + resulting BDD (which may or may not be constant) or DD_NON_CONSTANT. + No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_bddIntersect Cudd_bddLeq Cudd_addIteConstant] + +******************************************************************************/ +DdNode * +Cudd_bddIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + int comple; + unsigned int topf, topg, toph, v; + + statLine(dd); + /* Trivial cases. */ + if (f == one) /* ITE(1,G,H) => G */ + return(g); + + if (f == zero) /* ITE(0,G,H) => H */ + return(h); + + /* f now not a constant. */ + bddVarToConst(f, &g, &h, one); /* possibly convert g or h */ + /* to constants */ + + if (g == h) /* ITE(F,G,G) => G */ + return(g); + + if (Cudd_IsConstant(g) && Cudd_IsConstant(h)) + return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */ + /* => DD_NON_CONSTANT */ + + if (g == Cudd_Not(h)) + return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */ + /* if F != G and F != G' */ + + comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph); + + /* Cache lookup. */ + r = cuddConstantLookup(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h); + if (r != NULL) { + return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT)); + } + + v = ddMin(topg, toph); + + /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */ + if (topf < v && cuddT(f) == one && cuddE(f) == zero) { + return(DD_NON_CONSTANT); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf, v); /* v = top_var(F,G,H) */ + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + + if (topg == v) { + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + + if (toph == v) { + H = Cudd_Regular(h); + Hv = cuddT(H); Hnv = cuddE(H); + if (Cudd_IsComplement(h)) { + Hv = Cudd_Not(Hv); + Hnv = Cudd_Not(Hnv); + } + } else { + Hv = Hnv = h; + } + + /* Recursion. */ + t = Cudd_bddIteConstant(dd, Fv, Gv, Hv); + if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) { + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv); + if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) { + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t); + return(Cudd_NotCond(t,comple)); + +} /* end of Cudd_bddIteConstant */ + + +/**Function******************************************************************** + + Synopsis [Returns a function included in the intersection of f and g.] + + Description [Computes a function included in the intersection of f and + g. (That is, a witness that the intersection is not empty.) + Cudd_bddIntersect tries to build as few new nodes as possible. If the + only result of interest is whether f and g intersect, + Cudd_bddLeq should be used instead.] + + SideEffects [None] + + SeeAlso [Cudd_bddLeq Cudd_bddIteConstant] + +******************************************************************************/ +DdNode * +Cudd_bddIntersect( + DdManager * dd /* manager */, + DdNode * f /* first operand */, + DdNode * g /* second operand */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddIntersectRecur(dd,f,g); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_bddIntersect */ + + +/**Function******************************************************************** + + Synopsis [Computes the conjunction of two BDDs f and g.] + + Description [Computes the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAndAbstract Cudd_bddIntersect + Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddAnd( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddAnd */ + + +/**Function******************************************************************** + + Synopsis [Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required.] + + Description [Computes the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddAndLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddAndLimit */ + + +/**Function******************************************************************** + + Synopsis [Computes the disjunction of two BDDs f and g.] + + Description [Computes the disjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddNand Cudd_bddNor + Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddOr( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + } while (dd->reordered == 1); + res = Cudd_NotCond(res,res != NULL); + return(res); + +} /* end of Cudd_bddOr */ + + +/**Function******************************************************************** + + Synopsis [Computes the disjunction of two BDDs f and g. Returns + NULL if too many nodes are required.] + + Description [Computes the disjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddOr] + +******************************************************************************/ +DdNode * +Cudd_bddOrLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + res = Cudd_NotCond(res,res != NULL); + return(res); + +} /* end of Cudd_bddOrLimit */ + + +/**Function******************************************************************** + + Synopsis [Computes the NAND of two BDDs f and g.] + + Description [Computes the NAND of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNor + Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddNand( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + res = Cudd_NotCond(res,res != NULL); + return(res); + +} /* end of Cudd_bddNand */ + + +/**Function******************************************************************** + + Synopsis [Computes the NOR of two BDDs f and g.] + + Description [Computes the NOR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand + Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddNor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddNor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive OR of two BDDs f and g.] + + Description [Computes the exclusive OR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr + Cudd_bddNand Cudd_bddNor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddXor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddXor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive NOR of two BDDs f and g.] + + Description [Computes the exclusive NOR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr + Cudd_bddNand Cudd_bddNor Cudd_bddXor] + +******************************************************************************/ +DdNode * +Cudd_bddXnor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,Cudd_Not(g)); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddXnor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive NOR of two BDDs f and g. Returns + NULL if too many nodes are required.] + + Description [Computes the exclusive NOR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddXnorLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,Cudd_Not(g)); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddXnorLimit */ + + +/**Function******************************************************************** + + Synopsis [Determines whether f is less than or equal to g.] + + Description [Returns 1 if f is less than or equal to g; 0 otherwise. + No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_bddIteConstant Cudd_addEvalConst] + +******************************************************************************/ +int +Cudd_bddLeq( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *one, *zero, *tmp, *F, *fv, *fvn, *gv, *gvn; + unsigned int topf, topg, res; + + statLine(dd); + /* Terminal cases and normalization. */ + if (f == g) return(1); + + if (Cudd_IsComplement(g)) { + /* Special case: if f is regular and g is complemented, + ** f(1,...,1) = 1 > 0 = g(1,...,1). + */ + if (!Cudd_IsComplement(f)) return(0); + /* Both are complemented: Swap and complement because + ** f <= g <=> g' <= f' and we want the second argument to be regular. + */ + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } else if (Cudd_IsComplement(f) && g < f) { + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } + + /* Now g is regular and, if f is not regular, f < g. */ + one = DD_ONE(dd); + if (g == one) return(1); /* no need to test against zero */ + if (f == one) return(0); /* since at this point g != one */ + if (Cudd_Not(f) == g) return(0); /* because neither is constant */ + zero = Cudd_Not(one); + if (f == zero) return(1); + + /* Here neither f nor g is constant. */ + + /* Check cache. */ + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g); + if (tmp != NULL) { + return(tmp == one); + } + + /* Compute cofactors. */ + F = Cudd_Regular(f); + topf = dd->perm[F->index]; + topg = dd->perm[g->index]; + if (topf <= topg) { + fv = cuddT(F); fvn = cuddE(F); + if (f != F) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + } else { + fv = fvn = f; + } + if (topg <= topf) { + gv = cuddT(g); gvn = cuddE(g); + } else { + gv = gvn = g; + } + + /* Recursive calls. Since we want to maximize the probability of + ** the special case f(1,...,1) > g(1,...,1), we consider the negative + ** cofactors first. Indeed, the complementation parity of the positive + ** cofactors is the same as the one of the parent functions. + */ + res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv); + + /* Store result in cache and return. */ + cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero)); + return(res); + +} /* end of Cudd_bddLeq */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddIte.] + + Description [Implements the recursive step of Cudd_bddIte. Returns a + pointer to the resulting BDD. NULL if the intermediate result blows + up or if reordering occurs.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddBddIteRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *one, *zero, *res; + DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; + unsigned int topf, topg, toph, v; + int index; + int comple; + + statLine(dd); + /* Terminal cases. */ + + /* One variable cases. */ + if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */ + return(g); + + if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */ + return(h); + + /* From now on, f is known not to be a constant. */ + if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + if (h == zero) { /* ITE(F,1,0) = F */ + return(f); + } else { + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h)); + return(Cudd_NotCond(res,res != NULL)); + } + } else if (g == zero || f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ + if (h == one) { /* ITE(F,0,1) = !F */ + return(Cudd_Not(f)); + } else { + res = cuddBddAndRecur(dd,Cudd_Not(f),h); + return(res); + } + } + if (h == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + res = cuddBddAndRecur(dd,f,g); + return(res); + } else if (h == one || f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ + res = cuddBddAndRecur(dd,f,Cudd_Not(g)); + return(Cudd_NotCond(res,res != NULL)); + } + + /* Check remaining one variable case. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = F <-> G */ + res = cuddBddXorRecur(dd,f,h); + return(res); + } + + /* From here, there are no constants. */ + comple = bddVarToCanonicalSimple(dd, &f, &g, &h, &topf, &topg, &toph); + + /* f & g are now regular pointers */ + + v = ddMin(topg, toph); + + /* A shortcut: ITE(F,G,H) = (v,G,H) if F = (v,1,0), v < top(G,H). */ + if (topf < v && cuddT(f) == one && cuddE(f) == zero) { + r = cuddUniqueInter(dd, (int) f->index, g, h); + return(Cudd_NotCond(r,comple && r != NULL)); + } + + /* Check cache. */ + r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf, v); /* v = top_var(F,G,H) */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg == v) { + index = g->index; + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + if (toph == v) { + H = Cudd_Regular(h); + index = H->index; + Hv = cuddT(H); Hnv = cuddE(H); + if (Cudd_IsComplement(h)) { + Hv = Cudd_Not(Hv); + Hnv = Cudd_Not(Hnv); + } + } else { + Hv = Hnv = h; + } + + /* Recursive step. */ + t = cuddBddIteRecur(dd,Fv,Gv,Hv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert(dd, DD_BDD_ITE_TAG, f, g, h, r); + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddIteRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddIntersect.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_bddIntersect] + +******************************************************************************/ +DdNode * +cuddBddIntersectRecur( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + DdNode *F, *G, *t, *e; + DdNode *fv, *fnv, *gv, *gnv; + DdNode *one, *zero; + unsigned int index, topf, topg; + + statLine(dd); + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == g || g == one) return(f); + if (f == one) return(g); + + /* At this point f and g are not constant. */ + if (f > g) { DdNode *tmp = f; f = g; g = tmp; } + res = cuddCacheLookup2(dd,Cudd_bddIntersect,f,g); + if (res != NULL) return(res); + + /* Find splitting variable. Here we can skip the use of cuddI, + ** because the operands are known to be non-constant. + */ + F = Cudd_Regular(f); + topf = dd->perm[F->index]; + G = Cudd_Regular(g); + topg = dd->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } + } else { + index = G->index; + fv = fnv = f; + } + + if (topg <= topf) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + /* Compute partial results. */ + t = cuddBddIntersectRecur(dd,fv,gv); + if (t == NULL) return(NULL); + cuddRef(t); + if (t != zero) { + e = zero; + } else { + e = cuddBddIntersectRecur(dd,fnv,gnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddRef(e); + + if (t == e) { /* both equal zero */ + res = t; + } else if (Cudd_IsComplement(t)) { + res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (res == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = cuddUniqueInter(dd,(int)index,t,e); + if (res == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + + cuddCacheInsert2(dd,Cudd_bddIntersect,f,g,res); + + return(res); + +} /* end of cuddBddIntersectRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddAnd.] + + Description [Implements the recursive step of Cudd_bddAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +cuddBddAndRecur( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + DdNode *F, *fv, *fnv, *G, *gv, *gnv; + DdNode *one, *r, *t, *e; + unsigned int topf, topg, index; + + statLine(manager); + one = DD_ONE(manager); + + /* Terminal cases. */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + if (F == G) { + if (f == g) return(f); + else return(Cudd_Not(one)); + } + if (F == one) { + if (f == one) return(g); + else return(f); + } + if (G == one) { + if (g == one) return(f); + else return(g); + } + + /* At this point f and g are not constant. */ + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; + g = tmp; + F = Cudd_Regular(f); + G = Cudd_Regular(g); + } + + /* Check cache. */ + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g); + if (r != NULL) return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } + } else { + index = G->index; + fv = fnv = f; + } + + if (topg <= topf) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + t = cuddBddAndRecur(manager, fv, gv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddAndRecur(manager, fnv, gnv); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r); + return(r); + +} /* end of cuddBddAndRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddXor.] + + Description [Implements the recursive step of Cudd_bddXor by taking + the exclusive OR of two BDDs. Returns a pointer to the result is + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddXor] + +******************************************************************************/ +DdNode * +cuddBddXorRecur( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + DdNode *fv, *fnv, *G, *gv, *gnv; + DdNode *one, *zero, *r, *t, *e; + unsigned int topf, topg, index; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == g) return(zero); + if (f == Cudd_Not(g)) return(one); + if (f > g) { /* Try to increase cache efficiency and simplify tests. */ + DdNode *tmp = f; + f = g; + g = tmp; + } + if (g == zero) return(f); + if (g == one) return(Cudd_Not(f)); + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + g = Cudd_Not(g); + } + /* Now the first argument is regular. */ + if (f == one) return(Cudd_Not(g)); + + /* At this point f and g are not constant. */ + + /* Check cache. */ + r = cuddCacheLookup2(manager, Cudd_bddXor, f, g); + if (r != NULL) return(r); + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[f->index]; + G = Cudd_Regular(g); + topg = manager->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = f->index; + fv = cuddT(f); + fnv = cuddE(f); + } else { + index = G->index; + fv = fnv = f; + } + + if (topg <= topf) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + t = cuddBddXorRecur(manager, fv, gv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddXorRecur(manager, fnv, gnv); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + cuddCacheInsert2(manager, Cudd_bddXor, f, g, r); + return(r); + +} /* end of cuddBddXorRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Replaces variables with constants if possible.] + + Description [This function performs part of the transformation to + standard form by replacing variables with constants if possible.] + + SideEffects [None] + + SeeAlso [bddVarToCanonical bddVarToCanonicalSimple] + +******************************************************************************/ +static void +bddVarToConst( + DdNode * f, + DdNode ** gp, + DdNode ** hp, + DdNode * one) +{ + DdNode *g = *gp; + DdNode *h = *hp; + + if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + *gp = one; + } else if (f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ + *gp = Cudd_Not(one); + } + if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + *hp = Cudd_Not(one); + } else if (f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ + *hp = one; + } + +} /* end of bddVarToConst */ + + +/**Function******************************************************************** + + Synopsis [Picks unique member from equiv expressions.] + + Description [Reduces 2 variable expressions to canonical form.] + + SideEffects [None] + + SeeAlso [bddVarToConst bddVarToCanonicalSimple] + +******************************************************************************/ +static int +bddVarToCanonical( + DdManager * dd, + DdNode ** fp, + DdNode ** gp, + DdNode ** hp, + unsigned int * topfp, + unsigned int * topgp, + unsigned int * tophp) +{ + register DdNode *F, *G, *H, *r, *f, *g, *h; + register unsigned int topf, topg, toph; + DdNode *one = dd->one; + int comple, change; + + f = *fp; + g = *gp; + h = *hp; + F = Cudd_Regular(f); + G = Cudd_Regular(g); + H = Cudd_Regular(h); + topf = cuddI(dd,F->index); + topg = cuddI(dd,G->index); + toph = cuddI(dd,H->index); + + change = 0; + + if (G == one) { /* ITE(F,c,H) */ + if ((topf > toph) || (topf == toph && f > h)) { + r = h; + h = f; + f = r; /* ITE(F,1,H) = ITE(H,1,F) */ + if (g != one) { /* g == zero */ + f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */ + h = Cudd_Not(h); + } + change = 1; + } + } else if (H == one) { /* ITE(F,G,c) */ + if ((topf > topg) || (topf == topg && f > g)) { + r = g; + g = f; + f = r; /* ITE(F,G,0) = ITE(G,F,0) */ + if (h == one) { + f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */ + g = Cudd_Not(g); + } + change = 1; + } + } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */ + if ((topf > topg) || (topf == topg && f > g)) { + r = f; + f = g; + g = r; + h = Cudd_Not(r); + change = 1; + } + } + /* adjust pointers so that the first 2 arguments to ITE are regular */ + if (Cudd_IsComplement(f) != 0) { /* ITE(!F,G,H) = ITE(F,H,G) */ + f = Cudd_Not(f); + r = g; + g = h; + h = r; + change = 1; + } + comple = 0; + if (Cudd_IsComplement(g) != 0) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ + g = Cudd_Not(g); + h = Cudd_Not(h); + change = 1; + comple = 1; + } + if (change != 0) { + *fp = f; + *gp = g; + *hp = h; + } + *topfp = cuddI(dd,f->index); + *topgp = cuddI(dd,g->index); + *tophp = cuddI(dd,Cudd_Regular(h)->index); + + return(comple); + +} /* end of bddVarToCanonical */ + + +/**Function******************************************************************** + + Synopsis [Picks unique member from equiv expressions.] + + Description [Makes sure the first two pointers are regular. This + mat require the complementation of the result, which is signaled by + returning 1 instead of 0. This function is simpler than the general + case because it assumes that no two arguments are the same or + complementary, and no argument is constant.] + + SideEffects [None] + + SeeAlso [bddVarToConst bddVarToCanonical] + +******************************************************************************/ +static int +bddVarToCanonicalSimple( + DdManager * dd, + DdNode ** fp, + DdNode ** gp, + DdNode ** hp, + unsigned int * topfp, + unsigned int * topgp, + unsigned int * tophp) +{ + register DdNode *r, *f, *g, *h; + int comple, change; + + f = *fp; + g = *gp; + h = *hp; + + change = 0; + + /* adjust pointers so that the first 2 arguments to ITE are regular */ + if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */ + f = Cudd_Not(f); + r = g; + g = h; + h = r; + change = 1; + } + comple = 0; + if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ + g = Cudd_Not(g); + h = Cudd_Not(h); + change = 1; + comple = 1; + } + if (change) { + *fp = f; + *gp = g; + *hp = h; + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + *topfp = dd->perm[f->index]; + *topgp = dd->perm[g->index]; + *tophp = dd->perm[Cudd_Regular(h)->index]; + + return(comple); + +} /* end of bddVarToCanonicalSimple */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddBridge.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddBridge.c new file mode 100644 index 000000000..a6207b7f6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddBridge.c @@ -0,0 +1,1016 @@ +/**CFile*********************************************************************** + + FileName [cuddBridge.c] + + PackageName [cudd] + + Synopsis [Translation from BDD to ADD and vice versa and transfer between + different managers.] + + Description [External procedures included in this file: +
            +
          • Cudd_addBddThreshold() +
          • Cudd_addBddStrictThreshold() +
          • Cudd_addBddInterval() +
          • Cudd_addBddIthBit() +
          • Cudd_BddToAdd() +
          • Cudd_addBddPattern() +
          • Cudd_bddTransfer() +
          + Internal procedures included in this file: +
            +
          • cuddBddTransfer() +
          • cuddAddBddDoPattern() +
          + Static procedures included in this file: +
            +
          • addBddDoThreshold() +
          • addBddDoStrictThreshold() +
          • addBddDoInterval() +
          • addBddDoIthBit() +
          • ddBddToAddRecur() +
          • cuddBddTransferRecur() +
          + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.20 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addBddDoThreshold (DdManager *dd, DdNode *f, DdNode *val); +static DdNode * addBddDoStrictThreshold (DdManager *dd, DdNode *f, DdNode *val); +static DdNode * addBddDoInterval (DdManager *dd, DdNode *f, DdNode *l, DdNode *u); +static DdNode * addBddDoIthBit (DdManager *dd, DdNode *f, DdNode *index); +static DdNode * ddBddToAddRecur (DdManager *dd, DdNode *B); +static DdNode * cuddBddTransferRecur (DdManager *ddS, DdManager *ddD, DdNode *f, st_table *table); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants greater than or equal to value with 1, and all other + discriminants with 0. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd + Cudd_addBddStrictThreshold] + +******************************************************************************/ +DdNode * +Cudd_addBddThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value) +{ + DdNode *res; + DdNode *val; + + val = cuddUniqueConst(dd,value); + if (val == NULL) return(NULL); + cuddRef(val); + + do { + dd->reordered = 0; + res = addBddDoThreshold(dd, f, val); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, val); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, val); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddThreshold */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants STRICTLY greater than value with 1, and all other + discriminants with 0. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd + Cudd_addBddThreshold] + +******************************************************************************/ +DdNode * +Cudd_addBddStrictThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value) +{ + DdNode *res; + DdNode *val; + + val = cuddUniqueConst(dd,value); + if (val == NULL) return(NULL); + cuddRef(val); + + do { + dd->reordered = 0; + res = addBddDoStrictThreshold(dd, f, val); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, val); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, val); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddStrictThreshold */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants greater than or equal to lower and less than or equal to + upper with 1, and all other discriminants with 0. Returns a pointer to + the resulting BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddThreshold Cudd_addBddStrictThreshold + Cudd_addBddPattern Cudd_BddToAdd] + +******************************************************************************/ +DdNode * +Cudd_addBddInterval( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE lower, + CUDD_VALUE_TYPE upper) +{ + DdNode *res; + DdNode *l; + DdNode *u; + + /* Create constant nodes for the interval bounds, so that we can use + ** the global cache. + */ + l = cuddUniqueConst(dd,lower); + if (l == NULL) return(NULL); + cuddRef(l); + u = cuddUniqueConst(dd,upper); + if (u == NULL) { + Cudd_RecursiveDeref(dd,l); + return(NULL); + } + cuddRef(u); + + do { + dd->reordered = 0; + res = addBddDoInterval(dd, f, l, u); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, l); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, l); + Cudd_RecursiveDeref(dd, u); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddInterval */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD by extracting the i-th bit from + the leaves.] + + Description [Converts an ADD to a BDD by replacing all + discriminants whose i-th bit is equal to 1 with 1, and all other + discriminants with 0. The i-th bit refers to the integer + representation of the leaf value. If the value is has a fractional + part, it is ignored. Repeated calls to this procedure allow one to + transform an integer-valued ADD into an array of BDDs, one for each + bit of the leaf values. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd] + +******************************************************************************/ +DdNode * +Cudd_addBddIthBit( + DdManager * dd, + DdNode * f, + int bit) +{ + DdNode *res; + DdNode *index; + + index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit); + if (index == NULL) return(NULL); + cuddRef(index); + + do { + dd->reordered = 0; + res = addBddDoIthBit(dd, f, index); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, index); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, index); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddIthBit */ + + +/**Function******************************************************************** + + Synopsis [Converts a BDD to a 0-1 ADD.] + + Description [Converts a BDD to a 0-1 ADD. Returns a pointer to the + resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddPattern Cudd_addBddThreshold Cudd_addBddInterval + Cudd_addBddStrictThreshold] + +******************************************************************************/ +DdNode * +Cudd_BddToAdd( + DdManager * dd, + DdNode * B) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = ddBddToAddRecur(dd, B); + } while (dd->reordered ==1); + return(res); + +} /* end of Cudd_BddToAdd */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants different from 0 with 1. Returns a pointer to the + resulting BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_BddToAdd Cudd_addBddThreshold Cudd_addBddInterval + Cudd_addBddStrictThreshold] + +******************************************************************************/ +DdNode * +Cudd_addBddPattern( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddBddDoPattern(dd, f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addBddPattern */ + + +/**Function******************************************************************** + + Synopsis [Convert a BDD from a manager to another one.] + + Description [Convert a BDD from a manager to another one. The orders of the + variables in the two managers may be different. Returns a + pointer to the BDD in the destination manager if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_bddTransfer( + DdManager * ddSource, + DdManager * ddDestination, + DdNode * f) +{ + DdNode *res; + do { + ddDestination->reordered = 0; + res = cuddBddTransfer(ddSource, ddDestination, f); + } while (ddDestination->reordered == 1); + return(res); + +} /* end of Cudd_bddTransfer */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Convert a BDD from a manager to another one.] + + Description [Convert a BDD from a manager to another one. Returns a + pointer to the BDD in the destination manager if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddTransfer] + +******************************************************************************/ +DdNode * +cuddBddTransfer( + DdManager * ddS, + DdManager * ddD, + DdNode * f) +{ + DdNode *res; + st_table *table = NULL; + st_generator *gen = NULL; + DdNode *key, *value; + + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) goto failure; + res = cuddBddTransferRecur(ddS, ddD, f, table); + if (res != NULL) cuddRef(res); + + /* Dereference all elements in the table and dispose of the table. + ** This must be done also if res is NULL to avoid leaks in case of + ** reordering. */ + gen = st_init_gen(table); + if (gen == NULL) goto failure; + while (st_gen(gen, &key, &value)) { + Cudd_RecursiveDeref(ddD, value); + } + st_free_gen(gen); gen = NULL; + st_free_table(table); table = NULL; + + if (res != NULL) cuddDeref(res); + return(res); + +failure: + /* No need to free gen because it is always NULL here. */ + if (table != NULL) st_free_table(table); + return(NULL); + +} /* end of cuddBddTransfer */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddPattern.] + + Description [Performs the recursive step for Cudd_addBddPattern. Returns a + pointer to the resulting BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddAddBddDoPattern( + DdManager * dd, + DdNode * f) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),f == DD_ZERO(dd))); + } + + /* Check cache. */ + res = cuddCacheLookup1(dd,Cudd_addBddPattern,f); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = cuddAddBddDoPattern(dd,fv); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddBddDoPattern(dd,fvn); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,Cudd_addBddPattern,f,res); + + return(res); + +} /* end of cuddAddBddDoPattern */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddThreshold.] + + Description [Performs the recursive step for Cudd_addBddThreshold. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [addBddDoStrictThreshold] + +******************************************************************************/ +static DdNode * +addBddDoThreshold( + DdManager * dd, + DdNode * f, + DdNode * val) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(val))); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addBddDoThreshold,f,val); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoThreshold(dd,fv,val); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoThreshold(dd,fvn,val); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addBddDoThreshold,f,val,res); + + return(res); + +} /* end of addBddDoThreshold */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddStrictThreshold.] + + Description [Performs the recursive step for Cudd_addBddStrictThreshold. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [addBddDoThreshold] + +******************************************************************************/ +static DdNode * +addBddDoStrictThreshold( + DdManager * dd, + DdNode * f, + DdNode * val) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) <= cuddV(val))); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addBddDoStrictThreshold,f,val); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoStrictThreshold(dd,fv,val); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoStrictThreshold(dd,fvn,val); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addBddDoStrictThreshold,f,val,res); + + return(res); + +} /* end of addBddDoStrictThreshold */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddInterval.] + + Description [Performs the recursive step for Cudd_addBddInterval. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [addBddDoThreshold addBddDoStrictThreshold] + +******************************************************************************/ +static DdNode * +addBddDoInterval( + DdManager * dd, + DdNode * f, + DdNode * l, + DdNode * u) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(l) || cuddV(f) > cuddV(u))); + } + + /* Check cache. */ + res = cuddCacheLookup(dd,DD_ADD_BDD_DO_INTERVAL_TAG,f,l,u); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoInterval(dd,fv,l,u); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoInterval(dd,fvn,l,u); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert(dd,DD_ADD_BDD_DO_INTERVAL_TAG,f,l,u,res); + + return(res); + +} /* end of addBddDoInterval */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddIthBit.] + + Description [Performs the recursive step for Cudd_addBddIthBit. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +addBddDoIthBit( + DdManager * dd, + DdNode * f, + DdNode * index) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int mask, value; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + mask = 1 << ((int) cuddV(index)); + value = (int) cuddV(f); + return(Cudd_NotCond(DD_ONE(dd),(value & mask) == 0)); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addBddDoIthBit,f,index); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoIthBit(dd,fv,index); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoIthBit(dd,fvn,index); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addBddDoIthBit,f,index,res); + + return(res); + +} /* end of addBddDoIthBit */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_BddToAdd.] + + Description [Performs the recursive step for Cudd_BddToAdd. Returns a + pointer to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +ddBddToAddRecur( + DdManager * dd, + DdNode * B) +{ + DdNode *one; + DdNode *res, *res1, *T, *E, *Bt, *Be; + int complement = 0; + + statLine(dd); + one = DD_ONE(dd); + + if (Cudd_IsConstant(B)) { + if (B == one) { + res = one; + } else { + res = DD_ZERO(dd); + } + return(res); + } + /* Check visited table */ + res = cuddCacheLookup1(dd,ddBddToAddRecur,B); + if (res != NULL) return(res); + + if (Cudd_IsComplement(B)) { + complement = 1; + Bt = cuddT(Cudd_Regular(B)); + Be = cuddE(Cudd_Regular(B)); + } else { + Bt = cuddT(B); + Be = cuddE(B); + } + + T = ddBddToAddRecur(dd, Bt); + if (T == NULL) return(NULL); + cuddRef(T); + + E = ddBddToAddRecur(dd, Be); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + /* No need to check for T == E, because it is guaranteed not to happen. */ + res = cuddUniqueInter(dd, (int) Cudd_Regular(B)->index, T, E); + if (res == NULL) { + Cudd_RecursiveDeref(dd ,T); + Cudd_RecursiveDeref(dd ,E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + if (complement) { + cuddRef(res); + res1 = cuddAddCmplRecur(dd, res); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(res1); + Cudd_RecursiveDeref(dd, res); + res = res1; + cuddDeref(res); + } + + /* Store result. */ + cuddCacheInsert1(dd,ddBddToAddRecur,B,res); + + return(res); + +} /* end of ddBddToAddRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddTransfer.] + + Description [Performs the recursive step of Cudd_bddTransfer. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddBddTransfer] + +******************************************************************************/ +static DdNode * +cuddBddTransferRecur( + DdManager * ddS, + DdManager * ddD, + DdNode * f, + st_table * table) +{ + DdNode *ft, *fe, *t, *e, *var, *res; + DdNode *one, *zero; + int index; + int comple = 0; + + statLine(ddD); + one = DD_ONE(ddD); + comple = Cudd_IsComplement(f); + + /* Trivial cases. */ + if (Cudd_IsConstant(f)) return(Cudd_NotCond(one, comple)); + + /* Make canonical to increase the utilization of the cache. */ + f = Cudd_NotCond(f,comple); + /* Now f is a regular pointer to a non-constant node. */ + + /* Check the cache. */ + if (st_lookup(table, f, &res)) + return(Cudd_NotCond(res,comple)); + + /* Recursive step. */ + index = f->index; + ft = cuddT(f); fe = cuddE(f); + + t = cuddBddTransferRecur(ddS, ddD, ft, table); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + + e = cuddBddTransferRecur(ddS, ddD, fe, table); + if (e == NULL) { + Cudd_RecursiveDeref(ddD, t); + return(NULL); + } + cuddRef(e); + + zero = Cudd_Not(one); + var = cuddUniqueInter(ddD,index,one,zero); + if (var == NULL) { + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + return(NULL); + } + res = cuddBddIteRecur(ddD,var,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + + if (st_add_direct(table, (char *) f, (char *) res) == ST_OUT_OF_MEM) { + Cudd_RecursiveDeref(ddD, res); + return(NULL); + } + return(Cudd_NotCond(res,comple)); + +} /* end of cuddBddTransferRecur */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddCache.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddCache.c new file mode 100644 index 000000000..bf98c69e4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddCache.c @@ -0,0 +1,1053 @@ +/**CFile*********************************************************************** + + FileName [cuddCache.c] + + PackageName [cudd] + + Synopsis [Functions for cache insertion and lookup.] + + Description [Internal procedures included in this module: +
            +
          • cuddInitCache() +
          • cuddCacheInsert() +
          • cuddCacheInsert2() +
          • cuddCacheLookup() +
          • cuddCacheLookupZdd() +
          • cuddCacheLookup2() +
          • cuddCacheLookup2Zdd() +
          • cuddConstantLookup() +
          • cuddCacheProfile() +
          • cuddCacheResize() +
          • cuddCacheFlush() +
          • cuddComputeFloorLog2() +
          + Static procedures included in this module: +
            +
          ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef DD_CACHE_PROFILE +#define DD_HYSTO_BINS 8 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddCache.c,v 1.36 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes the computed table.] + + Description [Initializes the computed table. It is called by + Cudd_Init. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Init] + +******************************************************************************/ +int +cuddInitCache( + DdManager * unique /* unique table */, + unsigned int cacheSize /* initial size of the cache */, + unsigned int maxCacheSize /* cache size beyond which no resizing occurs */) +{ + int i; + unsigned int logSize; +#ifndef DD_CACHE_PROFILE + DdNodePtr *mem; + ptruint offset; +#endif + + /* Round cacheSize to largest power of 2 not greater than the requested + ** initial cache size. */ + logSize = cuddComputeFloorLog2(ddMax(cacheSize,unique->slots/2)); + cacheSize = 1 << logSize; + unique->acache = ALLOC(DdCache,cacheSize+1); + if (unique->acache == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + /* If the size of the cache entry is a power of 2, we want to + ** enforce alignment to that power of two. This happens when + ** DD_CACHE_PROFILE is not defined. */ +#ifdef DD_CACHE_PROFILE + unique->cache = unique->acache; + unique->memused += (cacheSize) * sizeof(DdCache); +#else + mem = (DdNodePtr *) unique->acache; + offset = (ptruint) mem & (sizeof(DdCache) - 1); + mem += (sizeof(DdCache) - offset) / sizeof(DdNodePtr); + unique->cache = (DdCache *) mem; + assert(((ptruint) unique->cache & (sizeof(DdCache) - 1)) == 0); + unique->memused += (cacheSize+1) * sizeof(DdCache); +#endif + unique->cacheSlots = cacheSize; + unique->cacheShift = sizeof(int) * 8 - logSize; + unique->maxCacheHard = maxCacheSize; + /* If cacheSlack is non-negative, we can resize. */ + unique->cacheSlack = (int) ddMin(maxCacheSize, + DD_MAX_CACHE_TO_SLOTS_RATIO*unique->slots) - + 2 * (int) cacheSize; + Cudd_SetMinHit(unique,DD_MIN_HIT); + /* Initialize to avoid division by 0 and immediate resizing. */ + unique->cacheMisses = (double) (int) (cacheSize * unique->minHit + 1); + unique->cacheHits = 0; + unique->totCachehits = 0; + /* The sum of cacheMisses and totCacheMisses is always correct, + ** even though cacheMisses is larger than it should for the reasons + ** explained above. */ + unique->totCacheMisses = -unique->cacheMisses; + unique->cachecollisions = 0; + unique->cacheinserts = 0; + unique->cacheLastInserts = 0; + unique->cachedeletions = 0; + + /* Initialize the cache */ + for (i = 0; (unsigned) i < cacheSize; i++) { + unique->cache[i].h = 0; /* unused slots */ + unique->cache[i].data = NULL; /* invalid entry */ +#ifdef DD_CACHE_PROFILE + unique->cache[i].count = 0; +#endif + } + + return(1); + +} /* end of cuddInitCache */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in the cache for a function with three + operands.] + + Description [Inserts a result in the cache for a function with three + operands. The operator tag (see cuddInt.h for details) is split and stored + into unused bits of the first two pointers.] + + SideEffects [None] + + SeeAlso [cuddCacheInsert2 cuddCacheInsert1] + +******************************************************************************/ +void +cuddCacheInsert( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h, + DdNode * data) +{ + int posn; + register DdCache *entry; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + posn = ddCHash2(uh,uf,ug,table->cacheShift); + entry = &table->cache[posn]; + + table->cachecollisions += entry->data != NULL; + table->cacheinserts++; + + entry->f = (DdNode *) uf; + entry->g = (DdNode *) ug; + entry->h = uh; + entry->data = data; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddCacheInsert */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in the cache for a function with two + operands.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddCacheInsert cuddCacheInsert1] + +******************************************************************************/ +void +cuddCacheInsert2( + DdManager * table, + DD_CTFP op, + DdNode * f, + DdNode * g, + DdNode * data) +{ + int posn; + register DdCache *entry; + + posn = ddCHash2(op,f,g,table->cacheShift); + entry = &table->cache[posn]; + + if (entry->data != NULL) { + table->cachecollisions++; + } + table->cacheinserts++; + + entry->f = f; + entry->g = g; + entry->h = (ptruint) op; + entry->data = data; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddCacheInsert2 */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in the cache for a function with two + operands.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddCacheInsert cuddCacheInsert2] + +******************************************************************************/ +void +cuddCacheInsert1( + DdManager * table, + DD_CTFP1 op, + DdNode * f, + DdNode * data) +{ + int posn; + register DdCache *entry; + + posn = ddCHash2(op,f,f,table->cacheShift); + entry = &table->cache[posn]; + + if (entry->data != NULL) { + table->cachecollisions++; + } + table->cacheinserts++; + + entry->f = f; + entry->g = f; + entry->h = (ptruint) op; + entry->data = data; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddCacheInsert1 */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f, + g, and h.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup2 cuddCacheLookup1] + +******************************************************************************/ +DdNode * +cuddCacheLookup( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(uh,uf,ug,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug && + en->h==uh) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f, + g, and h.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup2Zdd cuddCacheLookup1Zdd] + +******************************************************************************/ +DdNode * +cuddCacheLookupZdd( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(uh,uf,ug,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug && + en->h==uh) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookupZdd */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f + and g.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup cuddCacheLookup1] + +******************************************************************************/ +DdNode * +cuddCacheLookup2( + DdManager * table, + DD_CTFP op, + DdNode * f, + DdNode * g) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,g,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup2 */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup cuddCacheLookup2] + +******************************************************************************/ +DdNode * +cuddCacheLookup1( + DdManager * table, + DD_CTFP1 op, + DdNode * f) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,f,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup1 */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f + and g.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookupZdd cuddCacheLookup1Zdd] + +******************************************************************************/ +DdNode * +cuddCacheLookup2Zdd( + DdManager * table, + DD_CTFP op, + DdNode * f, + DdNode * g) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,g,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup2Zdd */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookupZdd cuddCacheLookup2Zdd] + +******************************************************************************/ +DdNode * +cuddCacheLookup1Zdd( + DdManager * table, + DD_CTFP1 op, + DdNode * f) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,f,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup1Zdd */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f, + g, and h.] + + Description [Looks up in the cache for the result of op applied to f, + g, and h. Assumes that the calling procedure (e.g., + Cudd_bddIteConstant) is only interested in whether the result is + constant or not. Returns the result if found (possibly + DD_NON_CONSTANT); otherwise it returns NULL.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup] + +******************************************************************************/ +DdNode * +cuddConstantLookup( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h) +{ + int posn; + DdCache *en,*cache; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + posn = ddCHash2(uh,uf,ug,table->cacheShift); + en = &cache[posn]; + + /* We do not reclaim here because the result should not be + * referenced, but only tested for being a constant. + */ + if (en->data != NULL && + en->f == (DdNodePtr)uf && en->g == (DdNodePtr)ug && en->h == uh) { + table->cacheHits++; + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddConstantLookup */ + + +/**Function******************************************************************** + + Synopsis [Computes and prints a profile of the cache usage.] + + Description [Computes and prints a profile of the cache usage. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddCacheProfile( + DdManager * table, + FILE * fp) +{ + DdCache *cache = table->cache; + int slots = table->cacheSlots; + int nzeroes = 0; + int i, retval; + double exUsed; + +#ifdef DD_CACHE_PROFILE + double count, mean, meansq, stddev, expected; + long max, min; + int imax, imin; + double *hystogramQ, *hystogramR; /* histograms by quotient and remainder */ + int nbins = DD_HYSTO_BINS; + int bin; + long thiscount; + double totalcount, exStddev; + + meansq = mean = expected = 0.0; + max = min = (long) cache[0].count; + imax = imin = 0; + totalcount = 0.0; + + hystogramQ = ALLOC(double, nbins); + if (hystogramQ == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + hystogramR = ALLOC(double, nbins); + if (hystogramR == NULL) { + FREE(hystogramQ); + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < nbins; i++) { + hystogramQ[i] = 0; + hystogramR[i] = 0; + } + + for (i = 0; i < slots; i++) { + thiscount = (long) cache[i].count; + if (thiscount > max) { + max = thiscount; + imax = i; + } + if (thiscount < min) { + min = thiscount; + imin = i; + } + if (thiscount == 0) { + nzeroes++; + } + count = (double) thiscount; + mean += count; + meansq += count * count; + totalcount += count; + expected += count * (double) i; + bin = (i * nbins) / slots; + hystogramQ[bin] += (double) thiscount; + bin = i % nbins; + hystogramR[bin] += (double) thiscount; + } + mean /= (double) slots; + meansq /= (double) slots; + + /* Compute the standard deviation from both the data and the + ** theoretical model for a random distribution. */ + stddev = sqrt(meansq - mean*mean); + exStddev = sqrt((1 - 1/(double) slots) * totalcount / (double) slots); + + retval = fprintf(fp,"Cache average accesses = %g\n", mean); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache access standard deviation = %g ", stddev); + if (retval == EOF) return(0); + retval = fprintf(fp,"(expected = %g)\n", exStddev); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache max accesses = %ld for slot %d\n", max, imax); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache min accesses = %ld for slot %d\n", min, imin); + if (retval == EOF) return(0); + exUsed = 100.0 * (1.0 - exp(-totalcount / (double) slots)); + retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n", + 100.0 - (double) nzeroes * 100.0 / (double) slots, + exUsed); + if (retval == EOF) return(0); + + if (totalcount > 0) { + expected /= totalcount; + retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); + if (retval == EOF) return(0); + retval = fprintf(fp," (expected bin value = %g)\nBy quotient:", + expected); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp," %.0f", hystogramQ[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\nBy residue: "); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp," %.0f", hystogramR[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\n"); + if (retval == EOF) return(0); + } + + FREE(hystogramQ); + FREE(hystogramR); +#else + for (i = 0; i < slots; i++) { + nzeroes += cache[i].h == 0; + } + exUsed = 100.0 * + (1.0 - exp(-(table->cacheinserts - table->cacheLastInserts) / + (double) slots)); + retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n", + 100.0 - (double) nzeroes * 100.0 / (double) slots, + exUsed); + if (retval == EOF) return(0); +#endif + return(1); + +} /* end of cuddCacheProfile */ + + +/**Function******************************************************************** + + Synopsis [Resizes the cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddCacheResize( + DdManager * table) +{ + DdCache *cache, *oldcache, *oldacache, *entry, *old; + int i; + int posn, shift; + unsigned int slots, oldslots; + double offset; + int moved = 0; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; +#ifndef DD_CACHE_PROFILE + ptruint misalignment; + DdNodePtr *mem; +#endif + + oldcache = table->cache; + oldacache = table->acache; + oldslots = table->cacheSlots; + slots = table->cacheSlots = oldslots << 1; + +#ifdef DD_VERBOSE + (void) fprintf(table->err,"Resizing the cache from %d to %d entries\n", + oldslots, slots); + (void) fprintf(table->err, + "\thits = %g\tmisses = %g\thit ratio = %5.3f\n", + table->cacheHits, table->cacheMisses, + table->cacheHits / (table->cacheHits + table->cacheMisses)); +#endif + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + table->acache = cache = ALLOC(DdCache,slots+1); + MMoutOfMemory = saveHandler; + /* If we fail to allocate the new table we just give up. */ + if (cache == NULL) { +#ifdef DD_VERBOSE + (void) fprintf(table->err,"Resizing failed. Giving up.\n"); +#endif + table->cacheSlots = oldslots; + table->acache = oldacache; + /* Do not try to resize again. */ + table->maxCacheHard = oldslots - 1; + table->cacheSlack = - (int) (oldslots + 1); + return; + } + /* If the size of the cache entry is a power of 2, we want to + ** enforce alignment to that power of two. This happens when + ** DD_CACHE_PROFILE is not defined. */ +#ifdef DD_CACHE_PROFILE + table->cache = cache; +#else + mem = (DdNodePtr *) cache; + misalignment = (ptruint) mem & (sizeof(DdCache) - 1); + mem += (sizeof(DdCache) - misalignment) / sizeof(DdNodePtr); + table->cache = cache = (DdCache *) mem; + assert(((ptruint) table->cache & (sizeof(DdCache) - 1)) == 0); +#endif + shift = --(table->cacheShift); + table->memused += (slots - oldslots) * sizeof(DdCache); + table->cacheSlack -= slots; /* need these many slots to double again */ + + /* Clear new cache. */ + for (i = 0; (unsigned) i < slots; i++) { + cache[i].data = NULL; + cache[i].h = 0; +#ifdef DD_CACHE_PROFILE + cache[i].count = 0; +#endif + } + + /* Copy from old cache to new one. */ + for (i = 0; (unsigned) i < oldslots; i++) { + old = &oldcache[i]; + if (old->data != NULL) { + posn = ddCHash2(old->h,old->f,old->g,shift); + entry = &cache[posn]; + entry->f = old->f; + entry->g = old->g; + entry->h = old->h; + entry->data = old->data; +#ifdef DD_CACHE_PROFILE + entry->count = 1; +#endif + moved++; + } + } + + FREE(oldacache); + + /* Reinitialize measurements so as to avoid division by 0 and + ** immediate resizing. + */ + offset = (double) (int) (slots * table->minHit + 1); + table->totCacheMisses += table->cacheMisses - offset; + table->cacheMisses = offset; + table->totCachehits += table->cacheHits; + table->cacheHits = 0; + table->cacheLastInserts = table->cacheinserts - (double) moved; + +} /* end of cuddCacheResize */ + + +/**Function******************************************************************** + + Synopsis [Flushes the cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddCacheFlush( + DdManager * table) +{ + int i, slots; + DdCache *cache; + + slots = table->cacheSlots; + cache = table->cache; + for (i = 0; i < slots; i++) { + table->cachedeletions += cache[i].data != NULL; + cache[i].data = NULL; + } + table->cacheLastInserts = table->cacheinserts; + + return; + +} /* end of cuddCacheFlush */ + + +/**Function******************************************************************** + + Synopsis [Returns the floor of the logarithm to the base 2.] + + Description [Returns the floor of the logarithm to the base 2. + The input value is assumed to be greater than 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddComputeFloorLog2( + unsigned int value) +{ + int floorLog = 0; +#ifdef DD_DEBUG + assert(value > 0); +#endif + while (value > 1) { + floorLog++; + value >>= 1; + } + return(floorLog); + +} /* end of cuddComputeFloorLog2 */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddCheck.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddCheck.c new file mode 100644 index 000000000..424aaba39 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddCheck.c @@ -0,0 +1,885 @@ +/**CFile*********************************************************************** + + FileName [cuddCheck.c] + + PackageName [cudd] + + Synopsis [Functions to check consistency of data structures.] + + Description [External procedures included in this module: +
            +
          • Cudd_DebugCheck() +
          • Cudd_CheckKeys() +
          + Internal procedures included in this module: +
            +
          • cuddHeapProfile() +
          • cuddPrintNode() +
          • cuddPrintVarGroups() +
          + Static procedures included in this module: +
            +
          • debugFindParent() +
          + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddCheck.c,v 1.37 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void debugFindParent (DdManager *table, DdNode *node); +#if 0 +static void debugCheckParent (DdManager *table, DdNode *node); +#endif + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Checks for inconsistencies in the DD heap.] + + Description [Checks for inconsistencies in the DD heap: +
            +
          • node has illegal index +
          • live node has dead children +
          • node has illegal Then or Else pointers +
          • BDD/ADD node has identical children +
          • ZDD node has zero then child +
          • wrong number of total nodes +
          • wrong number of dead nodes +
          • ref count error at node +
          + Returns 0 if no inconsistencies are found; DD_OUT_OF_MEM if there is + not enough memory; 1 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_CheckKeys] + +******************************************************************************/ +int +Cudd_DebugCheck( + DdManager * table) +{ + unsigned int i; + int j,count; + int slots; + DdNodePtr *nodelist; + DdNode *f; + DdNode *sentinel = &(table->sentinel); + st_table *edgeTable; /* stores internal ref count for each node */ + st_generator *gen; + int flag = 0; + int totalNode; + int deadNode; + int index; + int shift; + + edgeTable = st_init_table(st_ptrcmp,st_ptrhash); + if (edgeTable == NULL) return(CUDD_OUT_OF_MEM); + + /* Check the BDD/ADD subtables. */ + for (i = 0; i < (unsigned) table->size; i++) { + index = table->invperm[i]; + if (i != (unsigned) table->perm[index]) { + (void) fprintf(table->err, + "Permutation corrupted: invperm[%u] = %d\t perm[%d] = %d\n", + i, index, index, table->perm[index]); + } + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + shift = table->subtables[i].shift; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { /* for each subtable slot */ + f = nodelist[j]; + while (f != sentinel) { + totalNode++; + if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { + if ((int) f->index != index) { + (void) fprintf(table->err, + "Error: node has illegal index\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if ((unsigned) cuddI(table,cuddT(f)->index) <= i || + (unsigned) cuddI(table,Cudd_Regular(cuddE(f))->index) + <= i) { + (void) fprintf(table->err, + "Error: node has illegal children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (Cudd_Regular(cuddT(f)) != cuddT(f)) { + (void) fprintf(table->err, + "Error: node has illegal form\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f) == cuddE(f)) { + (void) fprintf(table->err, + "Error: node has identical children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f)->ref == 0 || Cudd_Regular(cuddE(f))->ref == 0) { + (void) fprintf(table->err, + "Error: live node has dead children\n"); + cuddPrintNode(f,table->err); + flag =1; + } + if (ddHash(cuddT(f),cuddE(f),shift) != j) { + (void) fprintf(table->err, "Error: misplaced node\n"); + cuddPrintNode(f,table->err); + flag =1; + } + /* Increment the internal reference count for the + ** then child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddT(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + + /* Increment the internal reference count for the + ** else child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)Cudd_Regular(cuddE(f)), + &count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)Cudd_Regular(cuddE(f)), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { + deadNode++; +#if 0 + debugCheckParent(table,f); +#endif + } else { + fprintf(table->err, + "Error: node has illegal Then or Else pointers\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + + f = f->next; + } /* for each element of the collision list */ + } /* for each subtable slot */ + + if ((unsigned) totalNode != table->subtables[i].keys) { + fprintf(table->err,"Error: wrong number of total nodes\n"); + flag = 1; + } + if ((unsigned) deadNode != table->subtables[i].dead) { + fprintf(table->err,"Error: wrong number of dead nodes\n"); + flag = 1; + } + } /* for each BDD/ADD subtable */ + + /* Check the ZDD subtables. */ + for (i = 0; i < (unsigned) table->sizeZ; i++) { + index = table->invpermZ[i]; + if (i != (unsigned) table->permZ[index]) { + (void) fprintf(table->err, + "Permutation corrupted: invpermZ[%u] = %d\t permZ[%d] = %d in ZDD\n", + i, index, index, table->permZ[index]); + } + nodelist = table->subtableZ[i].nodelist; + slots = table->subtableZ[i].slots; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { /* for each subtable slot */ + f = nodelist[j]; + while (f != NULL) { + totalNode++; + if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { + if ((int) f->index != index) { + (void) fprintf(table->err, + "Error: ZDD node has illegal index\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (Cudd_IsComplement(cuddT(f)) || + Cudd_IsComplement(cuddE(f))) { + (void) fprintf(table->err, + "Error: ZDD node has complemented children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if ((unsigned) cuddIZ(table,cuddT(f)->index) <= i || + (unsigned) cuddIZ(table,cuddE(f)->index) <= i) { + (void) fprintf(table->err, + "Error: ZDD node has illegal children\n"); + cuddPrintNode(f,table->err); + cuddPrintNode(cuddT(f),table->err); + cuddPrintNode(cuddE(f),table->err); + flag = 1; + } + if (cuddT(f) == DD_ZERO(table)) { + (void) fprintf(table->err, + "Error: ZDD node has zero then child\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f)->ref == 0 || cuddE(f)->ref == 0) { + (void) fprintf(table->err, + "Error: ZDD live node has dead children\n"); + cuddPrintNode(f,table->err); + flag =1; + } + /* Increment the internal reference count for the + ** then child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddT(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + + /* Increment the internal reference count for the + ** else child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddE(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddE(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + table->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { + deadNode++; +#if 0 + debugCheckParent(table,f); +#endif + } else { + fprintf(table->err, + "Error: ZDD node has illegal Then or Else pointers\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + + f = f->next; + } /* for each element of the collision list */ + } /* for each subtable slot */ + + if ((unsigned) totalNode != table->subtableZ[i].keys) { + fprintf(table->err, + "Error: wrong number of total nodes in ZDD\n"); + flag = 1; + } + if ((unsigned) deadNode != table->subtableZ[i].dead) { + fprintf(table->err, + "Error: wrong number of dead nodes in ZDD\n"); + flag = 1; + } + } /* for each ZDD subtable */ + + /* Check the constant table. */ + nodelist = table->constants.nodelist; + slots = table->constants.slots; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != NULL) { + totalNode++; + if (f->ref != 0) { + if (f->index != CUDD_CONST_INDEX) { + fprintf(table->err,"Error: node has illegal index\n"); +#if SIZEOF_VOID_P == 8 + fprintf(table->err, + " node 0x%lx, id = %u, ref = %u, value = %g\n", + (ptruint)f,f->index,f->ref,cuddV(f)); +#else + fprintf(table->err, + " node 0x%x, id = %hu, ref = %hu, value = %g\n", + (ptruint)f,f->index,f->ref,cuddV(f)); +#endif + flag = 1; + } + } else { + deadNode++; + } + f = f->next; + } + } + if ((unsigned) totalNode != table->constants.keys) { + (void) fprintf(table->err, + "Error: wrong number of total nodes in constants\n"); + flag = 1; + } + if ((unsigned) deadNode != table->constants.dead) { + (void) fprintf(table->err, + "Error: wrong number of dead nodes in constants\n"); + flag = 1; + } + gen = st_init_gen(edgeTable); + while (st_gen(gen, &f, &count)) { + if (count > (int)(f->ref) && f->ref != DD_MAXREF) { +#if SIZEOF_VOID_P == 8 + fprintf(table->err,"ref count error at node 0x%lx, count = %d, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#else + fprintf(table->err,"ref count error at node 0x%x, count = %d, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#endif + debugFindParent(table,f); + flag = 1; + } + } + st_free_gen(gen); + st_free_table(edgeTable); + + return (flag); + +} /* end of Cudd_DebugCheck */ + + +/**Function******************************************************************** + + Synopsis [Checks for several conditions that should not occur.] + + Description [Checks for the following conditions: +
            +
          • Wrong sizes of subtables. +
          • Wrong number of keys found in unique subtable. +
          • Wrong number of dead found in unique subtable. +
          • Wrong number of keys found in the constant table +
          • Wrong number of dead found in the constant table +
          • Wrong number of total slots found +
          • Wrong number of maximum keys found +
          • Wrong number of total dead found +
          + Reports the average length of non-empty lists. Returns the number of + subtables for which the number of keys is wrong.] + + SideEffects [None] + + SeeAlso [Cudd_DebugCheck] + +******************************************************************************/ +int +Cudd_CheckKeys( + DdManager * table) +{ + int size; + int i,j; + DdNodePtr *nodelist; + DdNode *node; + DdNode *sentinel = &(table->sentinel); + DdSubtable *subtable; + int keys; + int dead; + int count = 0; + int totalKeys = 0; + int totalSlots = 0; + int totalDead = 0; + int nonEmpty = 0; + unsigned int slots; + int logSlots; + int shift; + + size = table->size; + + for (i = 0; i < size; i++) { + subtable = &(table->subtables[i]); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + slots = subtable->slots; + shift = subtable->shift; + logSlots = sizeof(int) * 8 - shift; + if (((slots >> logSlots) << logSlots) != slots) { + (void) fprintf(table->err, + "Unique table %d is not the right power of 2\n", i); + (void) fprintf(table->err, + " slots = %u shift = %d\n", slots, shift); + } + totalSlots += slots; + totalDead += dead; + for (j = 0; (unsigned) j < slots; j++) { + node = nodelist[j]; + if (node != sentinel) { + nonEmpty++; + } + while (node != sentinel) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } + } + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ +in unique table %d (difference=%d)\n", i, keys); + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ +in unique table no. %d (difference=%d)\n", i, dead); + } + } /* for each BDD/ADD subtable */ + + /* Check the ZDD subtables. */ + size = table->sizeZ; + + for (i = 0; i < size; i++) { + subtable = &(table->subtableZ[i]); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + totalSlots += subtable->slots; + totalDead += dead; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + nonEmpty++; + } + while (node != NULL) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } + } + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ +in ZDD unique table no. %d (difference=%d)\n", i, keys); + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ +in ZDD unique table no. %d (difference=%d)\n", i, dead); + } + } /* for each ZDD subtable */ + + /* Check the constant table. */ + subtable = &(table->constants); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + totalSlots += subtable->slots; + totalDead += dead; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + nonEmpty++; + } + while (node != NULL) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } + } + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ +in the constant table (difference=%d)\n", keys); + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ +in the constant table (difference=%d)\n", dead); + } + if ((unsigned) totalKeys != table->keys + table->keysZ) { + (void) fprintf(table->err, "Wrong number of total keys found \ +(difference=%d)\n", (int) (totalKeys-table->keys)); + } + if ((unsigned) totalSlots != table->slots) { + (void) fprintf(table->err, "Wrong number of total slots found \ +(difference=%d)\n", (int) (totalSlots-table->slots)); + } + if (table->minDead != (unsigned) (table->gcFrac * table->slots)) { + (void) fprintf(table->err, "Wrong number of minimum dead found \ +(%u vs. %u)\n", table->minDead, + (unsigned) (table->gcFrac * (double) table->slots)); + } + if ((unsigned) totalDead != table->dead + table->deadZ) { + (void) fprintf(table->err, "Wrong number of total dead found \ +(difference=%d)\n", (int) (totalDead-table->dead)); + } + (void) fprintf(table->out,"Average length of non-empty lists = %g\n", + (double) table->keys / (double) nonEmpty); + + return(count); + +} /* end of Cudd_CheckKeys */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints information about the heap.] + + Description [Prints to the manager's stdout the number of live nodes for each + level of the DD heap that contains at least one live node. It also + prints a summary containing: +
            +
          • total number of tables; +
          • number of tables with live nodes; +
          • table with the largest number of live nodes; +
          • number of nodes in that table. +
          + If more than one table contains the maximum number of live nodes, + only the one of lowest index is reported. Returns 1 in case of success + and 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddHeapProfile( + DdManager * dd) +{ + int ntables = dd->size; + DdSubtable *subtables = dd->subtables; + int i, /* loop index */ + nodes, /* live nodes in i-th layer */ + retval, /* return value of fprintf */ + largest = -1, /* index of the table with most live nodes */ + maxnodes = -1, /* maximum number of live nodes in a table */ + nonempty = 0; /* number of tables with live nodes */ + + /* Print header. */ +#if SIZEOF_VOID_P == 8 + retval = fprintf(dd->out,"*** DD heap profile for 0x%lx ***\n", + (ptruint) dd); +#else + retval = fprintf(dd->out,"*** DD heap profile for 0x%x ***\n", + (ptruint) dd); +#endif + if (retval == EOF) return 0; + + /* Print number of live nodes for each nonempty table. */ + for (i=0; iout,"%5d: %5d nodes\n", i, nodes); + if (retval == EOF) return 0; + if (nodes > maxnodes) { + maxnodes = nodes; + largest = i; + } + } + } + + nodes = dd->constants.keys - dd->constants.dead; + if (nodes) { + nonempty++; + retval = fprintf(dd->out,"const: %5d nodes\n", nodes); + if (retval == EOF) return 0; + if (nodes > maxnodes) { + maxnodes = nodes; + largest = CUDD_CONST_INDEX; + } + } + + /* Print summary. */ + retval = fprintf(dd->out,"Summary: %d tables, %d non-empty, largest: %d ", + ntables+1, nonempty, largest); + if (retval == EOF) return 0; + retval = fprintf(dd->out,"(with %d nodes)\n", maxnodes); + if (retval == EOF) return 0; + + return(1); + +} /* end of cuddHeapProfile */ + + +/**Function******************************************************************** + + Synopsis [Prints out information on a node.] + + Description [Prints out information on a node.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddPrintNode( + DdNode * f, + FILE *fp) +{ + f = Cudd_Regular(f); +#if SIZEOF_VOID_P == 8 + (void) fprintf(fp," node 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#else + (void) fprintf(fp," node 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#endif + +} /* end of cuddPrintNode */ + + + +/**Function******************************************************************** + + Synopsis [Prints the variable groups as a parenthesized list.] + + Description [Prints the variable groups as a parenthesized list. + For each group the level range that it represents is printed. After + each group, the group's flags are printed, preceded by a `|'. For + each flag (except MTR_TERMINAL) a character is printed. +
            +
          • F: MTR_FIXED +
          • N: MTR_NEWNODE +
          • S: MTR_SOFT +
          + The second argument, silent, if different from 0, causes + Cudd_PrintVarGroups to only check the syntax of the group tree.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddPrintVarGroups( + DdManager * dd /* manager */, + MtrNode * root /* root of the group tree */, + int zdd /* 0: BDD; 1: ZDD */, + int silent /* flag to check tree syntax only */) +{ + MtrNode *node; + int level; + + assert(root != NULL); + assert(root->younger == NULL || root->younger->elder == root); + assert(root->elder == NULL || root->elder->younger == root); + if (zdd) { + level = dd->permZ[root->index]; + } else { + level = dd->perm[root->index]; + } + if (!silent) (void) printf("(%d",level); + if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) { + if (!silent) (void) printf(","); + } else { + node = root->child; + while (node != NULL) { + assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size)); + assert(node->parent == root); + cuddPrintVarGroups(dd,node,zdd,silent); + node = node->younger; + } + } + if (!silent) { + (void) printf("%d", (int) (level + root->size - 1)); + if (root->flags != MTR_DEFAULT) { + (void) printf("|"); + if (MTR_TEST(root,MTR_FIXED)) (void) printf("F"); + if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N"); + if (MTR_TEST(root,MTR_SOFT)) (void) printf("S"); + } + (void) printf(")"); + if (root->parent == NULL) (void) printf("\n"); + } + assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0); + return; + +} /* end of cuddPrintVarGroups */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Searches the subtables above node for its parents.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +debugFindParent( + DdManager * table, + DdNode * node) +{ + int i,j; + int slots; + DdNodePtr *nodelist; + DdNode *f; + + for (i = 0; i < cuddI(table,node->index); i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + for (j=0;jout,"parent is at 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n", + (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#else + (void) fprintf(table->out,"parent is at 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n", + (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#endif + } + f = f->next; + } + } + } + +} /* end of debugFindParent */ + + +#if 0 +/**Function******************************************************************** + + Synopsis [Reports an error if a (dead) node has a non-dead parent.] + + Description [Searches all the subtables above node. Very expensive. + The same check is now implemented more efficiently in ddDebugCheck.] + + SideEffects [None] + + SeeAlso [debugFindParent] + +******************************************************************************/ +static void +debugCheckParent( + DdManager * table, + DdNode * node) +{ + int i,j; + int slots; + DdNode **nodelist,*f; + + for (i = 0; i < cuddI(table,node->index); i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + for (j=0;jref != 0) { + (void) fprintf(table->err, + "error with zero ref count\n"); + (void) fprintf(table->err,"parent is 0x%x, id = %u, ref = %u, then = 0x%x, else = 0x%x\n",f,f->index,f->ref,cuddT(f),cuddE(f)); + (void) fprintf(table->err,"child is 0x%x, id = %u, ref = %u, then = 0x%x, else = 0x%x\n",node,node->index,node->ref,cuddT(node),cuddE(node)); + } + f = f->next; + } + } + } +} +#endif diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddClip.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddClip.c new file mode 100644 index 000000000..2993254ff --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddClip.c @@ -0,0 +1,558 @@ +/**CFile*********************************************************************** + + FileName [cuddClip.c] + + PackageName [cudd] + + Synopsis [Clipping functions.] + + Description [External procedures included in this module: +
            +
          • Cudd_bddClippingAnd() +
          • Cudd_bddClippingAndAbstract() +
          + Internal procedures included in this module: +
            +
          • cuddBddClippingAnd() +
          • cuddBddClippingAndAbstract() +
          + Static procedures included in this module: +
            +
          • cuddBddClippingAndRecur() +
          • cuddBddClipAndAbsRecur() +
          + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.9 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * cuddBddClippingAndRecur (DdManager *manager, DdNode *f, DdNode *g, int distance, int direction); +static DdNode * cuddBddClipAndAbsRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, int distance, int direction); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g.] + + Description [Approximates the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddClippingAnd( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddClippingAnd(dd,f,g,maxDepth,direction); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddClippingAnd */ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube.] + + Description [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. The variables are + existentially abstracted. Returns a pointer to the resulting BDD if + successful; NULL if the intermediate result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract Cudd_bddClippingAnd] + +******************************************************************************/ +DdNode * +Cudd_bddClippingAndAbstract( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + DdNode * cube /* cube of variables to be abstracted */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddClippingAndAbstract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g.] + + Description [Approximates the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddClippingAnd] + +******************************************************************************/ +DdNode * +cuddBddClippingAnd( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + res = cuddBddClippingAndRecur(dd,f,g,maxDepth,direction); + + return(res); + +} /* end of cuddBddClippingAnd */ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube.] + + Description [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddClippingAndAbstract] + +******************************************************************************/ +DdNode * +cuddBddClippingAndAbstract( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + DdNode * cube /* cube of variables to be abstracted */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + res = cuddBddClipAndAbsRecur(dd,f,g,cube,maxDepth,direction); + + return(res); + +} /* end of cuddBddClippingAndAbstract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddClippingAnd.] + + Description [Implements the recursive step of Cudd_bddClippingAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddBddClippingAnd] + +******************************************************************************/ +static DdNode * +cuddBddClippingAndRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + int distance, + int direction) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *zero, *r, *t, *e; + unsigned int topf, topg, index; + DD_CTFP cacheOp; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == g || g == one) return(f); + if (f == one) return(g); + if (distance == 0) { + /* One last attempt at returning the right result. We sort of + ** cheat by calling Cudd_bddLeq. */ + if (Cudd_bddLeq(manager,f,g)) return(f); + if (Cudd_bddLeq(manager,g,f)) return(g); + if (direction == 1) { + if (Cudd_bddLeq(manager,f,Cudd_Not(g)) || + Cudd_bddLeq(manager,g,Cudd_Not(f))) return(zero); + } + return(Cudd_NotCond(one,(direction == 0))); + } + + /* At this point f and g are not constant. */ + distance--; + + /* Check cache. Try to increase cache efficiency by sorting the + ** pointers. */ + if (f > g) { + DdNode *tmp = f; + f = g; g = tmp; + } + F = Cudd_Regular(f); + G = Cudd_Regular(g); + cacheOp = (DD_CTFP) + (direction ? Cudd_bddClippingAnd : cuddBddClippingAnd); + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup2(manager, cacheOp, f, g); + if (r != NULL) return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg <= topf) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + t = cuddBddClippingAndRecur(manager, ft, gt, distance, direction); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddClippingAndRecur(manager, fe, ge, distance, direction); + if (e == NULL) { + Cudd_RecursiveDeref(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert2(manager, cacheOp, f, g, r); + return(r); + +} /* end of cuddBddClippingAndRecur */ + + +/**Function******************************************************************** + + Synopsis [Approximates the AND of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Approximates the AND of two BDDs and simultaneously + abstracts the variables in cube. The variables are existentially + abstracted. Returns a pointer to the result is successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddClippingAndAbstract] + +******************************************************************************/ +static DdNode * +cuddBddClipAndAbsRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube, + int distance, + int direction) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *zero, *r, *t, *e, *Cube; + unsigned int topf, topg, topcube, top, index; + ptruint cacheTag; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == one && g == one) return(one); + if (cube == one) { + return(cuddBddClippingAndRecur(manager, f, g, distance, direction)); + } + if (f == one || f == g) { + return (cuddBddExistAbstractRecur(manager, g, cube)); + } + if (g == one) { + return (cuddBddExistAbstractRecur(manager, f, cube)); + } + if (distance == 0) return(Cudd_NotCond(one,(direction == 0))); + + /* At this point f, g, and cube are not constant. */ + distance--; + + /* Check cache. */ + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; g = tmp; + } + F = Cudd_Regular(f); + G = Cudd_Regular(g); + cacheTag = direction ? DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG : + DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG; + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup(manager, cacheTag, + f, g, cube); + if (r != NULL) { + return(r); + } + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + top = ddMin(topf, topg); + topcube = manager->perm[cube->index]; + + if (topcube < top) { + return(cuddBddClipAndAbsRecur(manager, f, g, cuddT(cube), + distance, direction)); + } + /* Now, topcube >= top. */ + + if (topf == top) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg == top) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + if (topcube == top) { + Cube = cuddT(cube); + } else { + Cube = cube; + } + + t = cuddBddClipAndAbsRecur(manager, ft, gt, Cube, distance, direction); + if (t == NULL) return(NULL); + + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. + */ + if (t == one && topcube == top) { + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, cacheTag, f, g, cube, one); + return(one); + } + cuddRef(t); + + e = cuddBddClipAndAbsRecur(manager, fe, ge, Cube, distance, direction); + if (e == NULL) { + Cudd_RecursiveDeref(manager, t); + return(NULL); + } + cuddRef(e); + + if (topcube == top) { /* abstract */ + r = cuddBddClippingAndRecur(manager, Cudd_Not(t), Cudd_Not(e), + distance, (direction == 0)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + cuddDeref(r); + } else if (t == e) { + r = t; + cuddDeref(t); + cuddDeref(e); + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + } + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, cacheTag, f, g, cube, r); + return (r); + +} /* end of cuddBddClipAndAbsRecur */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddCof.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddCof.c new file mode 100644 index 000000000..cff47b20a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddCof.c @@ -0,0 +1,327 @@ +/**CFile*********************************************************************** + + FileName [cuddCof.c] + + PackageName [cudd] + + Synopsis [Cofactoring functions.] + + Description [External procedures included in this module: +
            +
          • Cudd_Cofactor() +
          • Cudd_CheckCube() +
          + Internal procedures included in this module: +
            +
          • cuddGetBranches() +
          • cuddCofactorRecur() +
          + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddCof.c,v 1.11 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the cofactor of f with respect to g.] + + Description [Computes the cofactor of f with respect to g; g must be + the BDD or the ADD of a cube. Returns a pointer to the cofactor if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_Cofactor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res,*zero; + + zero = Cudd_Not(DD_ONE(dd)); + if (g == zero || g == DD_ZERO(dd)) { + (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + do { + dd->reordered = 0; + res = cuddCofactorRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_Cofactor */ + + +/**Function******************************************************************** + + Synopsis [Checks whether g is the BDD of a cube.] + + Description [Checks whether g is the BDD of a cube. Returns 1 in case + of success; 0 otherwise. The constant 1 is a valid cube, but all other + constant functions cause cuddCheckCube to return 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_CheckCube( + DdManager * dd, + DdNode * g) +{ + DdNode *g1,*g0,*one,*zero; + + one = DD_ONE(dd); + if (g == one) return(1); + if (Cudd_IsConstant(g)) return(0); + + zero = Cudd_Not(one); + cuddGetBranches(g,&g1,&g0); + + if (g0 == zero) { + return(Cudd_CheckCube(dd, g1)); + } + if (g1 == zero) { + return(Cudd_CheckCube(dd, g0)); + } + return(0); + +} /* end of Cudd_CheckCube */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the children of g.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddGetBranches( + DdNode * g, + DdNode ** g1, + DdNode ** g0) +{ + DdNode *G = Cudd_Regular(g); + + *g1 = cuddT(G); + *g0 = cuddE(G); + if (Cudd_IsComplement(g)) { + *g1 = Cudd_Not(*g1); + *g0 = Cudd_Not(*g0); + } + +} /* end of cuddGetBranches */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_Cofactor.] + + Description [Performs the recursive step of Cudd_Cofactor. Returns a + pointer to the cofactor if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Cofactor] + +******************************************************************************/ +DdNode * +cuddCofactorRecur( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *one,*zero,*F,*G,*g1,*g0,*f1,*f0,*t,*e,*r; + unsigned int topf,topg; + int comple; + + statLine(dd); + F = Cudd_Regular(f); + if (cuddIsConstant(F)) return(f); + + one = DD_ONE(dd); + + /* The invariant g != 0 is true on entry to this procedure and is + ** recursively maintained by it. Therefore it suffices to test g + ** against one to make sure it is not constant. + */ + if (g == one) return(f); + /* From now on, f and g are known not to be constants. */ + + comple = f != F; + r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + topf = dd->perm[F->index]; + G = Cudd_Regular(g); + topg = dd->perm[G->index]; + + /* We take the cofactors of F because we are going to rely on + ** the fact that the cofactors of the complement are the complements + ** of the cofactors to better utilize the cache. Variable comple + ** remembers whether we have to complement the result or not. + */ + if (topf <= topg) { + f1 = cuddT(F); f0 = cuddE(F); + } else { + f1 = f0 = F; + } + if (topg <= topf) { + g1 = cuddT(G); g0 = cuddE(G); + if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); } + } else { + g1 = g0 = g; + } + + zero = Cudd_Not(one); + if (topf >= topg) { + if (g0 == zero || g0 == DD_ZERO(dd)) { + r = cuddCofactorRecur(dd, f1, g1); + } else if (g1 == zero || g1 == DD_ZERO(dd)) { + r = cuddCofactorRecur(dd, f0, g0); + } else { + (void) fprintf(dd->out, + "Cudd_Cofactor: Invalid restriction 2\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + if (r == NULL) return(NULL); + } else /* if (topf < topg) */ { + t = cuddCofactorRecur(dd, f1, g); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddCofactorRecur(dd, f0, g); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e)); + if (r != NULL) + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(dd,(int)F->index,t,e); + } + if (r == NULL) { + Cudd_RecursiveDeref(dd ,e); + Cudd_RecursiveDeref(dd ,t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(dd,Cudd_Cofactor,F,g,r); + + return(Cudd_NotCond(r,comple)); + +} /* end of cuddCofactorRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddCompose.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddCompose.c new file mode 100644 index 000000000..eea044f59 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddCompose.c @@ -0,0 +1,1749 @@ +/**CFile*********************************************************************** + + FileName [cuddCompose.c] + + PackageName [cudd] + + Synopsis [Functional composition and variable permutation of DDs.] + + Description [External procedures included in this module: +
            +
          • Cudd_bddCompose() +
          • Cudd_addCompose() +
          • Cudd_addPermute() +
          • Cudd_addSwapVariables() +
          • Cudd_bddPermute() +
          • Cudd_bddVarMap() +
          • Cudd_SetVarMap() +
          • Cudd_bddSwapVariables() +
          • Cudd_bddAdjPermuteX() +
          • Cudd_addVectorCompose() +
          • Cudd_addGeneralVectorCompose() +
          • Cudd_addNonSimCompose() +
          • Cudd_bddVectorCompose() +
          + Internal procedures included in this module: +
            +
          • cuddBddComposeRecur() +
          • cuddAddComposeRecur() +
          + Static procedures included in this module: +
            +
          • cuddAddPermuteRecur() +
          • cuddBddPermuteRecur() +
          • cuddBddVarMapRecur() +
          • cuddAddVectorComposeRecur() +
          • cuddAddGeneralVectorComposeRecur() +
          • cuddAddNonSimComposeRecur() +
          • cuddBddVectorComposeRecur() +
          • ddIsIthAddVar() +
          • ddIsIthAddVarPair() +
          + The permutation functions use a local cache because the results to + be remembered depend on the permutation being applied. Since the + permutation is just an array, it cannot be stored in the global + cache. There are different procedured for BDDs and ADDs. This is + because bddPermuteRecur uses cuddBddIteRecur. If this were changed, + the procedures could be merged.] + + Author [Fabio Somenzi and Kavita Ravi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddCompose.c,v 1.46 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef DD_DEBUG +static int addPermuteRecurHits; +static int bddPermuteRecurHits; +static int bddVectorComposeHits; +static int addVectorComposeHits; + +static int addGeneralVectorComposeHits; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * cuddAddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut); +static DdNode * cuddBddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut); +static DdNode * cuddBddVarMapRecur (DdManager *manager, DdNode *f); +static DdNode * cuddAddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest); +static DdNode * cuddAddNonSimComposeRecur (DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub); +static DdNode * cuddBddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest); +DD_INLINE static int ddIsIthAddVar (DdManager *dd, DdNode *f, unsigned int i); + +static DdNode * cuddAddGeneralVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest); +DD_INLINE static int ddIsIthAddVarPair (DdManager *dd, DdNode *f, DdNode *g, unsigned int i); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Substitutes g for x_v in the BDD for f.] + + Description [Substitutes g for x_v in the BDD for f. v is the index of the + variable to be substituted. Cudd_bddCompose passes the corresponding + projection function to the recursive procedure, so that the cache may + be used. Returns the composed BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCompose] + +******************************************************************************/ +DdNode * +Cudd_bddCompose( + DdManager * dd, + DdNode * f, + DdNode * g, + int v) +{ + DdNode *proj, *res; + + /* Sanity check. */ + if (v < 0 || v >= dd->size) return(NULL); + + proj = dd->vars[v]; + do { + dd->reordered = 0; + res = cuddBddComposeRecur(dd,f,g,proj); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddCompose */ + + +/**Function******************************************************************** + + Synopsis [Substitutes g for x_v in the ADD for f.] + + Description [Substitutes g for x_v in the ADD for f. v is the index of the + variable to be substituted. g must be a 0-1 ADD. Cudd_bddCompose passes + the corresponding projection function to the recursive procedure, so + that the cache may be used. Returns the composed ADD if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddCompose] + +******************************************************************************/ +DdNode * +Cudd_addCompose( + DdManager * dd, + DdNode * f, + DdNode * g, + int v) +{ + DdNode *proj, *res; + + /* Sanity check. */ + if (v < 0 || v >= dd->size) return(NULL); + + proj = dd->vars[v]; + do { + dd->reordered = 0; + res = cuddAddComposeRecur(dd,f,g,proj); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addCompose */ + + +/**Function******************************************************************** + + Synopsis [Permutes the variables of an ADD.] + + Description [Given a permutation in array permut, creates a new ADD + with permuted variables. There should be an entry in array permut + for each variable in the manager. The i-th entry of permut holds the + index of the variable that is to substitute the i-th + variable. Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_addSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_addPermute( + DdManager * manager, + DdNode * node, + int * permut) +{ + DdHashTable *table; + DdNode *res; + + do { + manager->reordered = 0; + table = cuddHashTableInit(manager,1,2); + if (table == NULL) return(NULL); + /* Recursively solve the problem. */ + res = cuddAddPermuteRecur(manager,table,node,permut); + if (res != NULL) cuddRef(res); + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (manager->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addPermute */ + + +/**Function******************************************************************** + + Synopsis [Swaps two sets of variables of the same size (x and y) in + the ADD f.] + + Description [Swaps two sets of variables of the same size (x and y) in + the ADD f. The size is given by n. The two sets of variables are + assumed to be disjoint. Returns a pointer to the resulting ADD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addPermute Cudd_bddSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_addSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *swapped; + int i, j, k; + int *permut; + + permut = ALLOC(int,dd->size); + if (permut == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) permut[i] = i; + for (i = 0; i < n; i++) { + j = x[i]->index; + k = y[i]->index; + permut[j] = k; + permut[k] = j; + } + + swapped = Cudd_addPermute(dd,f,permut); + FREE(permut); + + return(swapped); + +} /* end of Cudd_addSwapVariables */ + + +/**Function******************************************************************** + + Synopsis [Permutes the variables of a BDD.] + + Description [Given a permutation in array permut, creates a new BDD + with permuted variables. There should be an entry in array permut + for each variable in the manager. The i-th entry of permut holds the + index of the variable that is to substitute the i-th variable. + Returns a pointer to the resulting BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addPermute Cudd_bddSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_bddPermute( + DdManager * manager, + DdNode * node, + int * permut) +{ + DdHashTable *table; + DdNode *res; + + do { + manager->reordered = 0; + table = cuddHashTableInit(manager,1,2); + if (table == NULL) return(NULL); + res = cuddBddPermuteRecur(manager,table,node,permut); + if (res != NULL) cuddRef(res); + /* Dispose of local cache. */ + cuddHashTableQuit(table); + + } while (manager->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_bddPermute */ + + +/**Function******************************************************************** + + Synopsis [Remaps the variables of a BDD using the default variable map.] + + Description [Remaps the variables of a BDD using the default + variable map. A typical use of this function is to swap two sets of + variables. The variable map must be registered with Cudd_SetVarMap. + Returns a pointer to the resulting BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables Cudd_SetVarMap] + +******************************************************************************/ +DdNode * +Cudd_bddVarMap( + DdManager * manager /* DD manager */, + DdNode * f /* function in which to remap variables */) +{ + DdNode *res; + + if (manager->map == NULL) return(NULL); + do { + manager->reordered = 0; + res = cuddBddVarMapRecur(manager, f); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddVarMap */ + + +/**Function******************************************************************** + + Synopsis [Registers a variable mapping with the manager.] + + Description [Registers with the manager a variable mapping described + by two sets of variables. This variable mapping is then used by + functions like Cudd_bddVarMap. This function is convenient for + those applications that perform the same mapping several times. + However, if several different permutations are used, it may be more + efficient not to rely on the registered mapping, because changing + mapping causes the cache to be cleared. (The initial setting, + however, does not clear the cache.) The two sets of variables (x and + y) must have the same size (x and y). The size is given by n. The + two sets of variables are normally disjoint, but this restriction is + not imposeded by the function. When new variables are created, the + map is automatically extended (each new variable maps to + itself). The typical use, however, is to wait until all variables + are created, and then create the map. Returns 1 if the mapping is + successfully registered with the manager; 0 otherwise.] + + SideEffects [Modifies the manager. May clear the cache.] + + SeeAlso [Cudd_bddVarMap Cudd_bddPermute Cudd_bddSwapVariables] + +******************************************************************************/ +int +Cudd_SetVarMap ( + DdManager *manager /* DD manager */, + DdNode **x /* first array of variables */, + DdNode **y /* second array of variables */, + int n /* length of both arrays */) +{ + int i; + + if (manager->map != NULL) { + cuddCacheFlush(manager); + } else { + manager->map = ALLOC(int,manager->maxSize); + if (manager->map == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(0); + } + manager->memused += sizeof(int) * manager->maxSize; + } + /* Initialize the map to the identity. */ + for (i = 0; i < manager->size; i++) { + manager->map[i] = i; + } + /* Create the map. */ + for (i = 0; i < n; i++) { + manager->map[x[i]->index] = y[i]->index; + manager->map[y[i]->index] = x[i]->index; + } + return(1); + +} /* end of Cudd_SetVarMap */ + + +/**Function******************************************************************** + + Synopsis [Swaps two sets of variables of the same size (x and y) in + the BDD f.] + + Description [Swaps two sets of variables of the same size (x and y) + in the BDD f. The size is given by n. The two sets of variables are + assumed to be disjoint. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_addSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_bddSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *swapped; + int i, j, k; + int *permut; + + permut = ALLOC(int,dd->size); + if (permut == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) permut[i] = i; + for (i = 0; i < n; i++) { + j = x[i]->index; + k = y[i]->index; + permut[j] = k; + permut[k] = j; + } + + swapped = Cudd_bddPermute(dd,f,permut); + FREE(permut); + + return(swapped); + +} /* end of Cudd_bddSwapVariables */ + + +/**Function******************************************************************** + + Synopsis [Rearranges a set of variables in the BDD B.] + + Description [Rearranges a set of variables in the BDD B. The size of + the set is given by n. This procedure is intended for the + `randomization' of the priority functions. Returns a pointer to the + BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables + Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_PrioritySelect] + +******************************************************************************/ +DdNode * +Cudd_bddAdjPermuteX( + DdManager * dd, + DdNode * B, + DdNode ** x, + int n) +{ + DdNode *swapped; + int i, j, k; + int *permut; + + permut = ALLOC(int,dd->size); + if (permut == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) permut[i] = i; + for (i = 0; i < n-2; i += 3) { + j = x[i]->index; + k = x[i+1]->index; + permut[j] = k; + permut[k] = j; + } + + swapped = Cudd_bddPermute(dd,B,permut); + FREE(permut); + + return(swapped); + +} /* end of Cudd_bddAdjPermuteX */ + + +/**Function******************************************************************** + + Synopsis [Composes an ADD with a vector of 0-1 ADDs.] + + Description [Given a vector of 0-1 ADDs, creates a new ADD by + substituting the 0-1 ADDs for the variables of the ADD f. There + should be an entry in vector for each variable in the manager. + If no substitution is sought for a given variable, the corresponding + projection function should be specified in the vector. + This function implements simultaneous composition. + Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNonSimCompose Cudd_addPermute Cudd_addCompose + Cudd_bddVectorCompose] + +******************************************************************************/ +DdNode * +Cudd_addVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector) +{ + DdHashTable *table; + DdNode *res; + int deepest; + int i; + + do { + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (!ddIsIthAddVar(dd,vector[i],i)) { + break; + } + } + + /* Recursively solve the problem. */ + res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest); + if (res != NULL) cuddRef(res); + + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (dd->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addVectorCompose */ + + +/**Function******************************************************************** + + Synopsis [Composes an ADD with a vector of ADDs.] + + Description [Given a vector of ADDs, creates a new ADD by substituting the + ADDs for the variables of the ADD f. vectorOn contains ADDs to be substituted + for the x_v and vectorOff the ADDs to be substituted for x_v'. There should + be an entry in vector for each variable in the manager. If no substitution + is sought for a given variable, the corresponding projection function should + be specified in the vector. This function implements simultaneous + composition. Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addVectorCompose Cudd_addNonSimCompose Cudd_addPermute + Cudd_addCompose Cudd_bddVectorCompose] + +******************************************************************************/ +DdNode * +Cudd_addGeneralVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vectorOn, + DdNode ** vectorOff) +{ + DdHashTable *table; + DdNode *res; + int deepest; + int i; + + do { + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) { + break; + } + } + + /* Recursively solve the problem. */ + res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn, + vectorOff,deepest); + if (res != NULL) cuddRef(res); + + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (dd->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addGeneralVectorCompose */ + + +/**Function******************************************************************** + + Synopsis [Composes an ADD with a vector of 0-1 ADDs.] + + Description [Given a vector of 0-1 ADDs, creates a new ADD by + substituting the 0-1 ADDs for the variables of the ADD f. There + should be an entry in vector for each variable in the manager. + This function implements non-simultaneous composition. If any of the + functions being composed depends on any of the variables being + substituted, then the result depends on the order of composition, + which in turn depends on the variable order: The variables farther from + the roots in the order are substituted first. + Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addVectorCompose Cudd_addPermute Cudd_addCompose] + +******************************************************************************/ +DdNode * +Cudd_addNonSimCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector) +{ + DdNode *cube, *key, *var, *tmp, *piece; + DdNode *res; + int i, lastsub; + + /* The cache entry for this function is composed of three parts: + ** f itself, the replacement relation, and the cube of the + ** variables being substituted. + ** The replacement relation is the product of the terms (yi EXNOR gi). + ** This apporach allows us to use the global cache for this function, + ** with great savings in memory with respect to using arrays for the + ** cache entries. + ** First we build replacement relation and cube of substituted + ** variables from the vector specifying the desired composition. + */ + key = DD_ONE(dd); + cuddRef(key); + cube = DD_ONE(dd); + cuddRef(cube); + for (i = (int) dd->size - 1; i >= 0; i--) { + if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) { + continue; + } + var = Cudd_addIthVar(dd,i); + if (var == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(var); + /* Update cube. */ + tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cube); + cube = tmp; + /* Update replacement relation. */ + piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]); + if (piece == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(piece); + Cudd_RecursiveDeref(dd,var); + tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,piece); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,piece); + key = tmp; + } + + /* Now try composition, until no reordering occurs. */ + do { + /* Find real substitution with largest index. */ + for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) { + if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) { + break; + } + } + + /* Recursively solve the problem. */ + dd->reordered = 0; + res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1); + if (res != NULL) cuddRef(res); + + } while (dd->reordered == 1); + + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addNonSimCompose */ + + +/**Function******************************************************************** + + Synopsis [Composes a BDD with a vector of BDDs.] + + Description [Given a vector of BDDs, creates a new BDD by + substituting the BDDs for the variables of the BDD f. There + should be an entry in vector for each variable in the manager. + If no substitution is sought for a given variable, the corresponding + projection function should be specified in the vector. + This function implements simultaneous composition. + Returns a pointer to the resulting BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_bddCompose Cudd_addVectorCompose] + +******************************************************************************/ +DdNode * +Cudd_bddVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector) +{ + DdHashTable *table; + DdNode *res; + int deepest; + int i; + + do { + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (vector[i] != dd->vars[i]) { + break; + } + } + + /* Recursively solve the problem. */ + res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest); + if (res != NULL) cuddRef(res); + + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (dd->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_bddVectorCompose */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCompose.] + + Description [Performs the recursive step of Cudd_bddCompose. + Exploits the fact that the composition of f' with g + produces the complement of the composition of f with g to better + utilize the cache. Returns the composed BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddCompose] + +******************************************************************************/ +DdNode * +cuddBddComposeRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * proj) +{ + DdNode *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e; + unsigned int v, topf, topg, topindex; + int comple; + + statLine(dd); + v = dd->perm[proj->index]; + F = Cudd_Regular(f); + topf = cuddI(dd,F->index); + + /* Terminal case. Subsumes the test for constant f. */ + if (topf > v) return(f); + + /* We solve the problem for a regular pointer, and then complement + ** the result if the pointer was originally complemented. + */ + comple = Cudd_IsComplement(f); + + /* Check cache. */ + r = cuddCacheLookup(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + if (topf == v) { + /* Compose. */ + f1 = cuddT(F); + f0 = cuddE(F); + r = cuddBddIteRecur(dd, g, f1, f0); + if (r == NULL) return(NULL); + } else { + /* Compute cofactors of f and g. Remember the index of the top + ** variable. + */ + G = Cudd_Regular(g); + topg = cuddI(dd,G->index); + if (topf > topg) { + topindex = G->index; + f1 = f0 = F; + } else { + topindex = F->index; + f1 = cuddT(F); + f0 = cuddE(F); + } + if (topg > topf) { + g1 = g0 = g; + } else { + g1 = cuddT(G); + g0 = cuddE(G); + if (g != G) { + g1 = Cudd_Not(g1); + g0 = Cudd_Not(g0); + } + } + /* Recursive step. */ + t = cuddBddComposeRecur(dd, f1, g1, proj); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddComposeRecur(dd, f0, g0, proj); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + cuddRef(e); + + r = cuddBddIteRecur(dd, dd->vars[topindex], t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, t); /* t & e not necessarily part of r */ + Cudd_IterDerefBdd(dd, e); + cuddDeref(r); + } + + cuddCacheInsert(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj,r); + + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addCompose.] + + Description [Performs the recursive step of Cudd_addCompose. + Returns the composed BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCompose] + +******************************************************************************/ +DdNode * +cuddAddComposeRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * proj) +{ + DdNode *f1, *f0, *g1, *g0, *r, *t, *e; + unsigned int v, topf, topg, topindex; + + statLine(dd); + v = dd->perm[proj->index]; + topf = cuddI(dd,f->index); + + /* Terminal case. Subsumes the test for constant f. */ + if (topf > v) return(f); + + /* Check cache. */ + r = cuddCacheLookup(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj); + if (r != NULL) { + return(r); + } + + if (topf == v) { + /* Compose. */ + f1 = cuddT(f); + f0 = cuddE(f); + r = cuddAddIteRecur(dd, g, f1, f0); + if (r == NULL) return(NULL); + } else { + /* Compute cofactors of f and g. Remember the index of the top + ** variable. + */ + topg = cuddI(dd,g->index); + if (topf > topg) { + topindex = g->index; + f1 = f0 = f; + } else { + topindex = f->index; + f1 = cuddT(f); + f0 = cuddE(f); + } + if (topg > topf) { + g1 = g0 = g; + } else { + g1 = cuddT(g); + g0 = cuddE(g); + } + /* Recursive step. */ + t = cuddAddComposeRecur(dd, f1, g1, proj); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddAddComposeRecur(dd, f0, g0, proj); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + r = cuddUniqueInter(dd, (int) topindex, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj,r); + + return(r); + +} /* end of cuddAddComposeRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addPermute.] + + Description [ Recursively puts the ADD in the order given in the + array permut. Checks for trivial cases to terminate recursion, then + splits on the children of this node. Once the solutions for the + children are obtained, it puts into the current position the node + from the rest of the ADD that should be here. Then returns this ADD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper + position is reached in the recursion tree.

          + The DdNode * that is returned is the same ADD as passed in as node, + but in the new order.] + + SideEffects [None] + + SeeAlso [Cudd_addPermute cuddBddPermuteRecur] + +******************************************************************************/ +static DdNode * +cuddAddPermuteRecur( + DdManager * manager /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * node /* ADD to be reordered */, + int * permut /* permutation array */) +{ + DdNode *T,*E; + DdNode *res,*var; + int index; + + statLine(manager); + /* Check for terminal case of constant node. */ + if (cuddIsConstant(node)) { + return(node); + } + + /* If problem already solved, look up answer and return. */ + if (node->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) { +#ifdef DD_DEBUG + addPermuteRecurHits++; +#endif + return(res); + } + + /* Split and recur on children of this node. */ + T = cuddAddPermuteRecur(manager,table,cuddT(node),permut); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddAddPermuteRecur(manager,table,cuddE(node),permut); + if (E == NULL) { + Cudd_RecursiveDeref(manager, T); + return(NULL); + } + cuddRef(E); + + /* Move variable that should be in this position to this position + ** by creating a single var ADD for that variable, and calling + ** cuddAddIteRecur with the T and E we just created. + */ + index = permut[node->index]; + var = cuddUniqueInter(manager,index,DD_ONE(manager),DD_ZERO(manager)); + if (var == NULL) return(NULL); + cuddRef(var); + res = cuddAddIteRecur(manager,var,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(manager,var); + Cudd_RecursiveDeref(manager, T); + Cudd_RecursiveDeref(manager, E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,var); + Cudd_RecursiveDeref(manager, T); + Cudd_RecursiveDeref(manager, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (node->ref != 1) { + ptrint fanout = (ptrint) node->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,node,res,fanout)) { + Cudd_RecursiveDeref(manager, res); + return(NULL); + } + } + cuddDeref(res); + return(res); + +} /* end of cuddAddPermuteRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddPermute.] + + Description [ Recursively puts the BDD in the order given in the array permut. + Checks for trivial cases to terminate recursion, then splits on the + children of this node. Once the solutions for the children are + obtained, it puts into the current position the node from the rest of + the BDD that should be here. Then returns this BDD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper position + is reached in the recursion tree.

          + The DdNode * that is returned is the same BDD as passed in as node, + but in the new order.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute cuddAddPermuteRecur] + +******************************************************************************/ +static DdNode * +cuddBddPermuteRecur( + DdManager * manager /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * node /* BDD to be reordered */, + int * permut /* permutation array */) +{ + DdNode *N,*T,*E; + DdNode *res; + int index; + + statLine(manager); + N = Cudd_Regular(node); + + /* Check for terminal case of constant node. */ + if (cuddIsConstant(N)) { + return(node); + } + + /* If problem already solved, look up answer and return. */ + if (N->ref != 1 && (res = cuddHashTableLookup1(table,N)) != NULL) { +#ifdef DD_DEBUG + bddPermuteRecurHits++; +#endif + return(Cudd_NotCond(res,N != node)); + } + + /* Split and recur on children of this node. */ + T = cuddBddPermuteRecur(manager,table,cuddT(N),permut); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddBddPermuteRecur(manager,table,cuddE(N),permut); + if (E == NULL) { + Cudd_IterDerefBdd(manager, T); + return(NULL); + } + cuddRef(E); + + /* Move variable that should be in this position to this position + ** by retrieving the single var BDD for that variable, and calling + ** cuddBddIteRecur with the T and E we just created. + */ + index = permut[N->index]; + res = cuddBddIteRecur(manager,manager->vars[index],T,E); + if (res == NULL) { + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (N->ref != 1) { + ptrint fanout = (ptrint) N->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,N,res,fanout)) { + Cudd_IterDerefBdd(manager, res); + return(NULL); + } + } + cuddDeref(res); + return(Cudd_NotCond(res,N != node)); + +} /* end of cuddBddPermuteRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddVarMap.] + + Description [Implements the recursive step of Cudd_bddVarMap. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddVarMap] + +******************************************************************************/ +static DdNode * +cuddBddVarMapRecur( + DdManager *manager /* DD manager */, + DdNode *f /* BDD to be remapped */) +{ + DdNode *F, *T, *E; + DdNode *res; + int index; + + statLine(manager); + F = Cudd_Regular(f); + + /* Check for terminal case of constant node. */ + if (cuddIsConstant(F)) { + return(f); + } + + /* If problem already solved, look up answer and return. */ + if (F->ref != 1 && + (res = cuddCacheLookup1(manager,Cudd_bddVarMap,F)) != NULL) { + return(Cudd_NotCond(res,F != f)); + } + + /* Split and recur on children of this node. */ + T = cuddBddVarMapRecur(manager,cuddT(F)); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddBddVarMapRecur(manager,cuddE(F)); + if (E == NULL) { + Cudd_IterDerefBdd(manager, T); + return(NULL); + } + cuddRef(E); + + /* Move variable that should be in this position to this position + ** by retrieving the single var BDD for that variable, and calling + ** cuddBddIteRecur with the T and E we just created. + */ + index = manager->map[F->index]; + res = cuddBddIteRecur(manager,manager->vars[index],T,E); + if (res == NULL) { + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (F->ref != 1) { + cuddCacheInsert1(manager,Cudd_bddVarMap,F,res); + } + cuddDeref(res); + return(Cudd_NotCond(res,F != f)); + +} /* end of cuddBddVarMapRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addVectorCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddVectorComposeRecur( + DdManager * dd /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * f /* ADD in which to compose */, + DdNode ** vector /* functions to substitute */, + int deepest /* depth of deepest substitution */) +{ + DdNode *T,*E; + DdNode *res; + + statLine(dd); + /* If we are past the deepest substitution, return f. */ + if (cuddI(dd,f->index) > deepest) { + return(f); + } + + if ((res = cuddHashTableLookup1(table,f)) != NULL) { +#ifdef DD_DEBUG + addVectorComposeHits++; +#endif + return(res); + } + + /* Split and recur on children of this node. */ + T = cuddAddVectorComposeRecur(dd,table,cuddT(f),vector,deepest); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddAddVectorComposeRecur(dd,table,cuddE(f),vector,deepest); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + /* Retrieve the 0-1 ADD for the current top variable and call + ** cuddAddIteRecur with the T and E we just created. + */ + res = cuddAddIteRecur(dd,vector[f->index],T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again + */ + if (f->ref != 1) { + ptrint fanout = (ptrint) f->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + } + cuddDeref(res); + return(res); + +} /* end of cuddAddVectorComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addGeneralVectorCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddGeneralVectorComposeRecur( + DdManager * dd /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * f /* ADD in which to compose */, + DdNode ** vectorOn /* functions to substitute for x_i */, + DdNode ** vectorOff /* functions to substitute for x_i' */, + int deepest /* depth of deepest substitution */) +{ + DdNode *T,*E,*t,*e; + DdNode *res; + + /* If we are past the deepest substitution, return f. */ + if (cuddI(dd,f->index) > deepest) { + return(f); + } + + if ((res = cuddHashTableLookup1(table,f)) != NULL) { +#ifdef DD_DEBUG + addGeneralVectorComposeHits++; +#endif + return(res); + } + + /* Split and recur on children of this node. */ + T = cuddAddGeneralVectorComposeRecur(dd,table,cuddT(f), + vectorOn,vectorOff,deepest); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddAddGeneralVectorComposeRecur(dd,table,cuddE(f), + vectorOn,vectorOff,deepest); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + /* Retrieve the compose ADDs for the current top variable and call + ** cuddAddApplyRecur with the T and E we just created. + */ + t = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOn[f->index],T); + if (t == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(t); + e = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOff[f->index],E); + if (e == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again + */ + if (f->ref != 1) { + ptrint fanout = (ptrint) f->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + } + cuddDeref(res); + return(res); + +} /* end of cuddAddGeneralVectorComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addNonSimCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddNonSimComposeRecur( + DdManager * dd, + DdNode * f, + DdNode ** vector, + DdNode * key, + DdNode * cube, + int lastsub) +{ + DdNode *f1, *f0, *key1, *key0, *cube1, *var; + DdNode *T,*E; + DdNode *r; + unsigned int top, topf, topk, topc; + unsigned int index; + int i; + DdNode **vect1; + DdNode **vect0; + + statLine(dd); + /* If we are past the deepest substitution, return f. */ + if (cube == DD_ONE(dd) || cuddIsConstant(f)) { + return(f); + } + + /* If problem already solved, look up answer and return. */ + r = cuddCacheLookup(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube); + if (r != NULL) { + return(r); + } + + /* Find top variable. we just need to look at f, key, and cube, + ** because all the varibles in the gi are in key. + */ + topf = cuddI(dd,f->index); + topk = cuddI(dd,key->index); + top = ddMin(topf,topk); + topc = cuddI(dd,cube->index); + top = ddMin(top,topc); + index = dd->invperm[top]; + + /* Compute the cofactors. */ + if (topf == top) { + f1 = cuddT(f); + f0 = cuddE(f); + } else { + f1 = f0 = f; + } + if (topc == top) { + cube1 = cuddT(cube); + /* We want to eliminate vector[index] from key. Otherwise + ** cache performance is severely affected. Hence we + ** existentially quantify the variable with index "index" from key. + */ + var = Cudd_addIthVar(dd, (int) index); + if (var == NULL) { + return(NULL); + } + cuddRef(var); + key1 = cuddAddExistAbstractRecur(dd, key, var); + if (key1 == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(key1); + Cudd_RecursiveDeref(dd,var); + key0 = key1; + } else { + cube1 = cube; + if (topk == top) { + key1 = cuddT(key); + key0 = cuddE(key); + } else { + key1 = key0 = key; + } + cuddRef(key1); + } + + /* Allocate two new vectors for the cofactors of vector. */ + vect1 = ALLOC(DdNode *,lastsub); + if (vect1 == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd,key1); + return(NULL); + } + vect0 = ALLOC(DdNode *,lastsub); + if (vect0 == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd,key1); + FREE(vect1); + return(NULL); + } + + /* Cofactor the gi. Eliminate vect1[index] and vect0[index], because + ** we do not need them. + */ + for (i = 0; i < lastsub; i++) { + DdNode *gi = vector[i]; + if (gi == NULL) { + vect1[i] = vect0[i] = NULL; + } else if (gi->index == index) { + vect1[i] = cuddT(gi); + vect0[i] = cuddE(gi); + } else { + vect1[i] = vect0[i] = gi; + } + } + vect1[index] = vect0[index] = NULL; + + /* Recur on children. */ + T = cuddAddNonSimComposeRecur(dd,f1,vect1,key1,cube1,lastsub); + FREE(vect1); + if (T == NULL) { + Cudd_RecursiveDeref(dd,key1); + FREE(vect0); + return(NULL); + } + cuddRef(T); + E = cuddAddNonSimComposeRecur(dd,f0,vect0,key0,cube1,lastsub); + FREE(vect0); + if (E == NULL) { + Cudd_RecursiveDeref(dd,key1); + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + Cudd_RecursiveDeref(dd,key1); + + /* Retrieve the 0-1 ADD for the current top variable from vector, + ** and call cuddAddIteRecur with the T and E we just created. + */ + r = cuddAddIteRecur(dd,vector[index],T,E); + if (r == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + cuddDeref(r); + + /* Store answer to trim recursion. */ + cuddCacheInsert(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube,r); + + return(r); + +} /* end of cuddAddNonSimComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddVectorCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddBddVectorComposeRecur( + DdManager * dd /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * f /* BDD in which to compose */, + DdNode ** vector /* functions to be composed */, + int deepest /* depth of the deepest substitution */) +{ + DdNode *F,*T,*E; + DdNode *res; + + statLine(dd); + F = Cudd_Regular(f); + + /* If we are past the deepest substitution, return f. */ + if (cuddI(dd,F->index) > deepest) { + return(f); + } + + /* If problem already solved, look up answer and return. */ + if ((res = cuddHashTableLookup1(table,F)) != NULL) { +#ifdef DD_DEBUG + bddVectorComposeHits++; +#endif + return(Cudd_NotCond(res,F != f)); + } + + /* Split and recur on children of this node. */ + T = cuddBddVectorComposeRecur(dd,table,cuddT(F),vector, deepest); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddBddVectorComposeRecur(dd,table,cuddE(F),vector, deepest); + if (E == NULL) { + Cudd_IterDerefBdd(dd, T); + return(NULL); + } + cuddRef(E); + + /* Call cuddBddIteRecur with the BDD that replaces the current top + ** variable and the T and E we just created. + */ + res = cuddBddIteRecur(dd,vector[F->index],T,E); + if (res == NULL) { + Cudd_IterDerefBdd(dd, T); + Cudd_IterDerefBdd(dd, E); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd, T); + Cudd_IterDerefBdd(dd, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (F->ref != 1) { + ptrint fanout = (ptrint) F->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,F,res,fanout)) { + Cudd_IterDerefBdd(dd, res); + return(NULL); + } + } + cuddDeref(res); + return(Cudd_NotCond(res,F != f)); + +} /* end of cuddBddVectorComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Comparison of a function to the i-th ADD variable.] + + Description [Comparison of a function to the i-th ADD variable. Returns 1 if + the function is the i-th ADD variable; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static int +ddIsIthAddVar( + DdManager * dd, + DdNode * f, + unsigned int i) +{ + return(f->index == i && cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd)); + +} /* end of ddIsIthAddVar */ + + +/**Function******************************************************************** + + Synopsis [Comparison of a pair of functions to the i-th ADD variable.] + + Description [Comparison of a pair of functions to the i-th ADD + variable. Returns 1 if the functions are the i-th ADD variable and its + complement; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static int +ddIsIthAddVarPair( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int i) +{ + return(f->index == i && g->index == i && + cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd) && + cuddT(g) == DD_ZERO(dd) && cuddE(g) == DD_ONE(dd)); + +} /* end of ddIsIthAddVarPair */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddDecomp.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddDecomp.c new file mode 100644 index 000000000..066027d95 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddDecomp.c @@ -0,0 +1,2177 @@ +/**CFile*********************************************************************** + + FileName [cuddDecomp.c] + + PackageName [cudd] + + Synopsis [Functions for BDD decomposition.] + + Description [External procedures included in this file: +

            +
          • Cudd_bddApproxConjDecomp() +
          • Cudd_bddApproxDisjDecomp() +
          • Cudd_bddIterConjDecomp() +
          • Cudd_bddIterDisjDecomp() +
          • Cudd_bddGenConjDecomp() +
          • Cudd_bddGenDisjDecomp() +
          • Cudd_bddVarConjDecomp() +
          • Cudd_bddVarDisjDecomp() +
          + Static procedures included in this module: +
            +
          • cuddConjunctsAux() +
          • CreateBotDist() +
          • BuildConjuncts() +
          • ConjunctsFree() +
          ] + + Author [Kavita Ravi, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ +#define DEPTH 5 +#define THRESHOLD 10 +#define NONE 0 +#define PAIR_ST 1 +#define PAIR_CR 2 +#define G_ST 3 +#define G_CR 4 +#define H_ST 5 +#define H_CR 6 +#define BOTH_G 7 +#define BOTH_H 8 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ +typedef struct Conjuncts { + DdNode *g; + DdNode *h; +} Conjuncts; + +typedef struct NodeStat { + int distance; + int localRef; +} NodeStat; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddDecomp.c,v 1.45 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static DdNode *one, *zero; +long lastTimeG; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +#define FactorsNotStored(factors) ((int)((long)(factors) & 01)) + +#define FactorsComplement(factors) ((Conjuncts *)((long)(factors) | 01)) + +#define FactorsUncomplement(factors) ((Conjuncts *)((long)(factors) ^ 01)) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static NodeStat * CreateBotDist (DdNode * node, st_table * distanceTable); +static double CountMinterms (DdNode * node, double max, st_table * mintermTable, FILE *fp); +static void ConjunctsFree (DdManager * dd, Conjuncts * factors); +static int PairInTables (DdNode * g, DdNode * h, st_table * ghTable); +static Conjuncts * CheckTablesCacheAndReturn (DdNode * node, DdNode * g, DdNode * h, st_table * ghTable, st_table * cacheTable); +static Conjuncts * PickOnePair (DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable); +static Conjuncts * CheckInTables (DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable, int * outOfMem); +static Conjuncts * ZeroCase (DdManager * dd, DdNode * node, Conjuncts * factorsNv, st_table * ghTable, st_table * cacheTable, int switched); +static Conjuncts * BuildConjuncts (DdManager * dd, DdNode * node, st_table * distanceTable, st_table * cacheTable, int approxDistance, int maxLocalRef, st_table * ghTable, st_table * mintermTable); +static int cuddConjunctsAux (DdManager * dd, DdNode * f, DdNode ** c1, DdNode ** c2); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Performs two-way conjunctive decomposition of a + BDD. This procedure owes its name to the use of supersetting to + obtain an initial factor of the given function. Returns the number + of conjuncts produced, that is, 2 if successful; 1 if no meaningful + decomposition was found; 0 otherwise. The conjuncts produced by this + procedure tend to be imbalanced.] + + SideEffects [The factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddApproxDisjDecomp Cudd_bddIterConjDecomp + Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox + Cudd_bddSqueeze Cudd_bddLICompaction] + +******************************************************************************/ +int +Cudd_bddApproxConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the first factor */) +{ + DdNode *superset1, *superset2, *glocal, *hlocal; + int nvars = Cudd_SupportSize(dd,f); + + /* Find a tentative first factor by overapproximation and minimization. */ + superset1 = Cudd_RemapOverApprox(dd,f,nvars,0,1.0); + if (superset1 == NULL) return(0); + cuddRef(superset1); + superset2 = Cudd_bddSqueeze(dd,f,superset1); + if (superset2 == NULL) { + Cudd_RecursiveDeref(dd,superset1); + return(0); + } + cuddRef(superset2); + Cudd_RecursiveDeref(dd,superset1); + + /* Compute the second factor by minimization. */ + hlocal = Cudd_bddLICompaction(dd,f,superset2); + if (hlocal == NULL) { + Cudd_RecursiveDeref(dd,superset2); + return(0); + } + cuddRef(hlocal); + + /* Refine the first factor by minimization. If h turns out to be f, this + ** step guarantees that g will be 1. */ + glocal = Cudd_bddLICompaction(dd,superset2,hlocal); + if (glocal == NULL) { + Cudd_RecursiveDeref(dd,superset2); + Cudd_RecursiveDeref(dd,hlocal); + return(0); + } + cuddRef(glocal); + Cudd_RecursiveDeref(dd,superset2); + + if (glocal != DD_ONE(dd)) { + if (hlocal != DD_ONE(dd)) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,glocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = hlocal; + return(1); + } + +} /* end of Cudd_bddApproxConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD. + Returns the number of disjuncts produced, that is, 2 if successful; + 1 if no meaningful decomposition was found; 0 otherwise. The + disjuncts produced by this procedure tend to be imbalanced.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddApproxConjDecomp Cudd_bddIterDisjDecomp + Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp] + +******************************************************************************/ +int +Cudd_bddApproxDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddApproxConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddApproxDisjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Performs two-way conjunctive decomposition of a + BDD. This procedure owes its name to the iterated use of + supersetting to obtain a factor of the given function. Returns the + number of conjuncts produced, that is, 2 if successful; 1 if no + meaningful decomposition was found; 0 otherwise. The conjuncts + produced by this procedure tend to be imbalanced.] + + SideEffects [The factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddIterDisjDecomp Cudd_bddApproxConjDecomp + Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox + Cudd_bddSqueeze Cudd_bddLICompaction] + +******************************************************************************/ +int +Cudd_bddIterConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the array of conjuncts */) +{ + DdNode *superset1, *superset2, *old[2], *res[2]; + int sizeOld, sizeNew; + int nvars = Cudd_SupportSize(dd,f); + + old[0] = DD_ONE(dd); + cuddRef(old[0]); + old[1] = f; + cuddRef(old[1]); + sizeOld = Cudd_SharingSize(old,2); + + do { + /* Find a tentative first factor by overapproximation and + ** minimization. */ + superset1 = Cudd_RemapOverApprox(dd,old[1],nvars,0,1.0); + if (superset1 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(superset1); + superset2 = Cudd_bddSqueeze(dd,old[1],superset1); + if (superset2 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + Cudd_RecursiveDeref(dd,superset1); + return(0); + } + cuddRef(superset2); + Cudd_RecursiveDeref(dd,superset1); + res[0] = Cudd_bddAnd(dd,old[0],superset2); + if (res[0] == NULL) { + Cudd_RecursiveDeref(dd,superset2); + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(res[0]); + Cudd_RecursiveDeref(dd,superset2); + if (res[0] == old[0]) { + Cudd_RecursiveDeref(dd,res[0]); + break; /* avoid infinite loop */ + } + + /* Compute the second factor by minimization. */ + res[1] = Cudd_bddLICompaction(dd,old[1],res[0]); + if (res[1] == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(res[1]); + + sizeNew = Cudd_SharingSize(res,2); + if (sizeNew <= sizeOld) { + Cudd_RecursiveDeref(dd,old[0]); + old[0] = res[0]; + Cudd_RecursiveDeref(dd,old[1]); + old[1] = res[1]; + sizeOld = sizeNew; + } else { + Cudd_RecursiveDeref(dd,res[0]); + Cudd_RecursiveDeref(dd,res[1]); + break; + } + + } while (1); + + /* Refine the first factor by minimization. If h turns out to + ** be f, this step guarantees that g will be 1. */ + superset1 = Cudd_bddLICompaction(dd,old[0],old[1]); + if (superset1 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(superset1); + Cudd_RecursiveDeref(dd,old[0]); + old[0] = superset1; + + if (old[0] != DD_ONE(dd)) { + if (old[1] != DD_ONE(dd)) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[0]; + (*conjuncts)[1] = old[1]; + return(2); + } else { + Cudd_RecursiveDeref(dd,old[1]); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[0]; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,old[0]); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[1]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[1]; + return(1); + } + +} /* end of Cudd_bddIterConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD. + Returns the number of disjuncts produced, that is, 2 if successful; + 1 if no meaningful decomposition was found; 0 otherwise. The + disjuncts produced by this procedure tend to be imbalanced.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddIterConjDecomp Cudd_bddApproxDisjDecomp + Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp] + +******************************************************************************/ +int +Cudd_bddIterDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddIterConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddIterDisjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Performs two-way conjunctive decomposition of a + BDD. This procedure owes its name to the fact tht it generalizes the + decomposition based on the cofactors with respect to one + variable. Returns the number of conjuncts produced, that is, 2 if + successful; 1 if no meaningful decomposition was found; 0 + otherwise. The conjuncts produced by this procedure tend to be + balanced.] + + SideEffects [The two factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddGenDisjDecomp Cudd_bddApproxConjDecomp + Cudd_bddIterConjDecomp Cudd_bddVarConjDecomp] + +******************************************************************************/ +int +Cudd_bddGenConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the array of conjuncts */) +{ + int result; + DdNode *glocal, *hlocal; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + do { + dd->reordered = 0; + result = cuddConjunctsAux(dd, f, &glocal, &hlocal); + } while (dd->reordered == 1); + + if (result == 0) { + return(0); + } + + if (glocal != one) { + if (hlocal != one) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,glocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = hlocal; + return(1); + } + +} /* end of Cudd_bddGenConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD. + Returns the number of disjuncts produced, that is, 2 if successful; + 1 if no meaningful decomposition was found; 0 otherwise. The + disjuncts produced by this procedure tend to be balanced.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddGenConjDecomp Cudd_bddApproxDisjDecomp + Cudd_bddIterDisjDecomp Cudd_bddVarDisjDecomp] + +******************************************************************************/ +int +Cudd_bddGenDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddGenConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddGenDisjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Conjunctively decomposes one BDD according to a + variable. If f is the function of the BDD and + x is the variable, the decomposition is + (f+x)(f+x'). The variable is chosen so as to balance + the sizes of the two conjuncts and to keep them small. Returns the + number of conjuncts produced, that is, 2 if successful; 1 if no + meaningful decomposition was found; 0 otherwise.] + + SideEffects [The two factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddVarDisjDecomp Cudd_bddGenConjDecomp + Cudd_bddApproxConjDecomp Cudd_bddIterConjDecomp] + +*****************************************************************************/ +int +Cudd_bddVarConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the array of conjuncts */) +{ + int best; + int min; + DdNode *support, *scan, *var, *glocal, *hlocal; + + /* Find best cofactoring variable. */ + support = Cudd_Support(dd,f); + if (support == NULL) return(0); + if (Cudd_IsConstant(support)) { + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = f; + cuddRef((*conjuncts)[0]); + return(1); + } + cuddRef(support); + min = 1000000000; + best = -1; + scan = support; + while (!Cudd_IsConstant(scan)) { + int i = scan->index; + int est1 = Cudd_EstimateCofactor(dd,f,i,1); + int est0 = Cudd_EstimateCofactor(dd,f,i,0); + /* Minimize the size of the larger of the two cofactors. */ + int est = (est1 > est0) ? est1 : est0; + if (est < min) { + min = est; + best = i; + } + scan = cuddT(scan); + } +#ifdef DD_DEBUG + assert(best >= 0 && best < dd->size); +#endif + Cudd_RecursiveDeref(dd,support); + + var = Cudd_bddIthVar(dd,best); + glocal = Cudd_bddOr(dd,f,var); + if (glocal == NULL) { + return(0); + } + cuddRef(glocal); + hlocal = Cudd_bddOr(dd,f,Cudd_Not(var)); + if (hlocal == NULL) { + Cudd_RecursiveDeref(dd,glocal); + return(0); + } + cuddRef(hlocal); + + if (glocal != DD_ONE(dd)) { + if (hlocal != DD_ONE(dd)) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,glocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = hlocal; + return(1); + } + +} /* end of Cudd_bddVarConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD + according to a variable. If f is the function of the + BDD and x is the variable, the decomposition is + f*x + f*x'. The variable is chosen so as to balance + the sizes of the two disjuncts and to keep them small. Returns the + number of disjuncts produced, that is, 2 if successful; 1 if no + meaningful decomposition was found; 0 otherwise.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddVarConjDecomp Cudd_bddApproxDisjDecomp + Cudd_bddIterDisjDecomp Cudd_bddGenDisjDecomp] + +******************************************************************************/ +int +Cudd_bddVarDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddVarConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddVarDisjDecomp */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Get longest distance of node from constant.] + + Description [Get longest distance of node from constant. Returns the + distance of the root from the constant if successful; CUDD_OUT_OF_MEM + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static NodeStat * +CreateBotDist( + DdNode * node, + st_table * distanceTable) +{ + DdNode *N, *Nv, *Nnv; + int distance, distanceNv, distanceNnv; + NodeStat *nodeStat, *nodeStatNv, *nodeStatNnv; + +#if 0 + if (Cudd_IsConstant(node)) { + return(0); + } +#endif + + /* Return the entry in the table if found. */ + N = Cudd_Regular(node); + if (st_lookup(distanceTable, N, &nodeStat)) { + nodeStat->localRef++; + return(nodeStat); + } + + Nv = cuddT(N); + Nnv = cuddE(N); + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* Recur on the children. */ + nodeStatNv = CreateBotDist(Nv, distanceTable); + if (nodeStatNv == NULL) return(NULL); + distanceNv = nodeStatNv->distance; + + nodeStatNnv = CreateBotDist(Nnv, distanceTable); + if (nodeStatNnv == NULL) return(NULL); + distanceNnv = nodeStatNnv->distance; + /* Store max distance from constant; note sometimes this distance + ** may be to 0. + */ + distance = (distanceNv > distanceNnv) ? (distanceNv+1) : (distanceNnv + 1); + + nodeStat = ALLOC(NodeStat, 1); + if (nodeStat == NULL) { + return(0); + } + nodeStat->distance = distance; + nodeStat->localRef = 1; + + if (st_insert(distanceTable, (char *)N, (char *)nodeStat) == + ST_OUT_OF_MEM) { + return(0); + + } + return(nodeStat); + +} /* end of CreateBotDist */ + + +/**Function******************************************************************** + + Synopsis [Count the number of minterms of each node ina a BDD and + store it in a hash table.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double +CountMinterms( + DdNode * node, + double max, + st_table * mintermTable, + FILE *fp) +{ + DdNode *N, *Nv, *Nnv; + double min, minNv, minNnv; + double *dummy; + + N = Cudd_Regular(node); + + if (cuddIsConstant(N)) { + if (node == zero) { + return(0); + } else { + return(max); + } + } + + /* Return the entry in the table if found. */ + if (st_lookup(mintermTable, node, &dummy)) { + min = *dummy; + return(min); + } + + Nv = cuddT(N); + Nnv = cuddE(N); + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* Recur on the children. */ + minNv = CountMinterms(Nv, max, mintermTable, fp); + if (minNv == -1.0) return(-1.0); + minNnv = CountMinterms(Nnv, max, mintermTable, fp); + if (minNnv == -1.0) return(-1.0); + min = minNv / 2.0 + minNnv / 2.0; + /* store + */ + + dummy = ALLOC(double, 1); + if (dummy == NULL) return(-1.0); + *dummy = min; + if (st_insert(mintermTable, (char *)node, (char *)dummy) == ST_OUT_OF_MEM) { + (void) fprintf(fp, "st table insert failed\n"); + } + return(min); + +} /* end of CountMinterms */ + + +/**Function******************************************************************** + + Synopsis [Free factors structure] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ConjunctsFree( + DdManager * dd, + Conjuncts * factors) +{ + Cudd_RecursiveDeref(dd, factors->g); + Cudd_RecursiveDeref(dd, factors->h); + FREE(factors); + return; + +} /* end of ConjunctsFree */ + + +/**Function******************************************************************** + + Synopsis [Check whether the given pair is in the tables.] + + Description [.Check whether the given pair is in the tables. gTable + and hTable are combined. + absence in both is indicated by 0, + presence in gTable is indicated by 1, + presence in hTable by 2 and + presence in both by 3. + The values returned by this function are PAIR_ST, + PAIR_CR, G_ST, G_CR, H_ST, H_CR, BOTH_G, BOTH_H, NONE. + PAIR_ST implies g in gTable and h in hTable + PAIR_CR implies g in hTable and h in gTable + G_ST implies g in gTable and h not in any table + G_CR implies g in hTable and h not in any table + H_ST implies h in hTable and g not in any table + H_CR implies h in gTable and g not in any table + BOTH_G implies both in gTable + BOTH_H implies both in hTable + NONE implies none in table; ] + + SideEffects [] + + SeeAlso [CheckTablesCacheAndReturn CheckInTables] + +******************************************************************************/ +static int +PairInTables( + DdNode * g, + DdNode * h, + st_table * ghTable) +{ + int valueG, valueH, gPresent, hPresent; + + valueG = valueH = gPresent = hPresent = 0; + + gPresent = st_lookup_int(ghTable, (char *)Cudd_Regular(g), &valueG); + hPresent = st_lookup_int(ghTable, (char *)Cudd_Regular(h), &valueH); + + if (!gPresent && !hPresent) return(NONE); + + if (!hPresent) { + if (valueG & 1) return(G_ST); + if (valueG & 2) return(G_CR); + } + if (!gPresent) { + if (valueH & 1) return(H_CR); + if (valueH & 2) return(H_ST); + } + /* both in tables */ + if ((valueG & 1) && (valueH & 2)) return(PAIR_ST); + if ((valueG & 2) && (valueH & 1)) return(PAIR_CR); + + if (valueG & 1) { + return(BOTH_G); + } else { + return(BOTH_H); + } + +} /* end of PairInTables */ + + +/**Function******************************************************************** + + Synopsis [Check the tables for the existence of pair and return one + combination, cache the result.] + + Description [Check the tables for the existence of pair and return + one combination, cache the result. The assumption is that one of the + conjuncts is already in the tables.] + + SideEffects [g and h referenced for the cache] + + SeeAlso [ZeroCase] + +******************************************************************************/ +static Conjuncts * +CheckTablesCacheAndReturn( + DdNode * node, + DdNode * g, + DdNode * h, + st_table * ghTable, + st_table * cacheTable) +{ + int pairValue; + int value; + Conjuncts *factors; + + value = 0; + /* check tables */ + pairValue = PairInTables(g, h, ghTable); + assert(pairValue != NONE); + /* if both dont exist in table, we know one exists(either g or h). + * Therefore store the other and proceed + */ + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) return(NULL); + if ((pairValue == BOTH_H) || (pairValue == H_ST)) { + if (g != one) { + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(g), &value)) { + value |= 1; + } else { + value = 1; + } + if (st_insert(ghTable, (char *)Cudd_Regular(g), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = g; + factors->h = h; + } else if ((pairValue == BOTH_G) || (pairValue == G_ST)) { + if (h != one) { + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(h), &value)) { + value |= 2; + } else { + value = 2; + } + if (st_insert(ghTable, (char *)Cudd_Regular(h), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = g; + factors->h = h; + } else if (pairValue == H_CR) { + if (g != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = h; + factors->h = g; + } else if (pairValue == G_CR) { + if (h != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = h; + factors->h = g; + } else if (pairValue == PAIR_CR) { + /* pair exists in table */ + factors->g = h; + factors->h = g; + } else if (pairValue == PAIR_ST) { + factors->g = g; + factors->h = h; + } + + /* cache the result for this node */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + + return(factors); + +} /* end of CheckTablesCacheAndReturn */ + +/**Function******************************************************************** + + Synopsis [Check the tables for the existence of pair and return one + combination, store in cache.] + + Description [Check the tables for the existence of pair and return + one combination, store in cache. The pair that has more pointers to + it is picked. An approximation of the number of local pointers is + made by taking the reference count of the pairs sent. ] + + SideEffects [] + + SeeAlso [ZeroCase BuildConjuncts] + +******************************************************************************/ +static Conjuncts * +PickOnePair( + DdNode * node, + DdNode * g1, + DdNode * h1, + DdNode * g2, + DdNode * h2, + st_table * ghTable, + st_table * cacheTable) +{ + int value; + Conjuncts *factors; + int oneRef, twoRef; + + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) return(NULL); + + /* count the number of pointers to pair 2 */ + if (h2 == one) { + twoRef = (Cudd_Regular(g2))->ref; + } else if (g2 == one) { + twoRef = (Cudd_Regular(h2))->ref; + } else { + twoRef = ((Cudd_Regular(g2))->ref + (Cudd_Regular(h2))->ref)/2; + } + + /* count the number of pointers to pair 1 */ + if (h1 == one) { + oneRef = (Cudd_Regular(g1))->ref; + } else if (g1 == one) { + oneRef = (Cudd_Regular(h1))->ref; + } else { + oneRef = ((Cudd_Regular(g1))->ref + (Cudd_Regular(h1))->ref)/2; + } + + /* pick the pair with higher reference count */ + if (oneRef >= twoRef) { + factors->g = g1; + factors->h = h1; + } else { + factors->g = g2; + factors->h = h2; + } + + /* + * Store computed factors in respective tables to encourage + * recombination. + */ + if (factors->g != one) { + /* insert g in htable */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->g), &value)) { + if (value == 2) { + value |= 1; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } else { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } + + if (factors->h != one) { + /* insert h in htable */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->h), &value)) { + if (value == 1) { + value |= 2; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } else { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } + + /* Store factors in cache table for later use. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == + ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + + return(factors); + +} /* end of PickOnePair */ + + +/**Function******************************************************************** + + Synopsis [Check if the two pairs exist in the table, If any of the + conjuncts do exist, store in the cache and return the corresponding pair.] + + Description [Check if the two pairs exist in the table. If any of + the conjuncts do exist, store in the cache and return the + corresponding pair.] + + SideEffects [] + + SeeAlso [ZeroCase BuildConjuncts] + +******************************************************************************/ +static Conjuncts * +CheckInTables( + DdNode * node, + DdNode * g1, + DdNode * h1, + DdNode * g2, + DdNode * h2, + st_table * ghTable, + st_table * cacheTable, + int * outOfMem) +{ + int pairValue1, pairValue2; + Conjuncts *factors; + int value; + + *outOfMem = 0; + + /* check existence of pair in table */ + pairValue1 = PairInTables(g1, h1, ghTable); + pairValue2 = PairInTables(g2, h2, ghTable); + + /* if none of the 4 exist in the gh tables, return NULL */ + if ((pairValue1 == NONE) && (pairValue2 == NONE)) { + return NULL; + } + + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + *outOfMem = 1; + return NULL; + } + + /* pairs that already exist in the table get preference. */ + if (pairValue1 == PAIR_ST) { + factors->g = g1; + factors->h = h1; + } else if (pairValue2 == PAIR_ST) { + factors->g = g2; + factors->h = h2; + } else if (pairValue1 == PAIR_CR) { + factors->g = h1; + factors->h = g1; + } else if (pairValue2 == PAIR_CR) { + factors->g = h2; + factors->h = g2; + } else if (pairValue1 == G_ST) { + /* g exists in the table, h is not found in either table */ + factors->g = g1; + factors->h = h1; + if (h1 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == BOTH_G) { + /* g and h are found in the g table */ + factors->g = g1; + factors->h = h1; + if (h1 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == H_ST) { + /* h exists in the table, g is not found in either table */ + factors->g = g1; + factors->h = h1; + if (g1 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == BOTH_H) { + /* g and h are found in the h table */ + factors->g = g1; + factors->h = h1; + if (g1 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == G_ST) { + /* g exists in the table, h is not found in either table */ + factors->g = g2; + factors->h = h2; + if (h2 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == BOTH_G) { + /* g and h are found in the g table */ + factors->g = g2; + factors->h = h2; + if (h2 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == H_ST) { + /* h exists in the table, g is not found in either table */ + factors->g = g2; + factors->h = h2; + if (g2 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == BOTH_H) { + /* g and h are found in the h table */ + factors->g = g2; + factors->h = h2; + if (g2 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == G_CR) { + /* g found in h table and h in none */ + factors->g = h1; + factors->h = g1; + if (h1 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == H_CR) { + /* h found in g table and g in none */ + factors->g = h1; + factors->h = g1; + if (g1 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == G_CR) { + /* g found in h table and h in none */ + factors->g = h2; + factors->h = g2; + if (h2 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == H_CR) { + /* h found in g table and g in none */ + factors->g = h2; + factors->h = g2; + if (g2 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } + + /* Store factors in cache table for later use. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == + ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + return factors; +} /* end of CheckInTables */ + + + +/**Function******************************************************************** + + Synopsis [If one child is zero, do explicitly what Restrict does or better] + + Description [If one child is zero, do explicitly what Restrict does or better. + First separate a variable and its child in the base case. In case of a cube + times a function, separate the cube and function. As a last resort, look in + tables.] + + SideEffects [Frees the BDDs in factorsNv. factorsNv itself is not freed + because it is freed above.] + + SeeAlso [BuildConjuncts] + +******************************************************************************/ +static Conjuncts * +ZeroCase( + DdManager * dd, + DdNode * node, + Conjuncts * factorsNv, + st_table * ghTable, + st_table * cacheTable, + int switched) +{ + int topid; + DdNode *g, *h, *g1, *g2, *h1, *h2, *x, *N, *G, *H, *Gv, *Gnv; + DdNode *Hv, *Hnv; + int value; + int outOfMem; + Conjuncts *factors; + + /* get var at this node */ + N = Cudd_Regular(node); + topid = N->index; + x = dd->vars[topid]; + x = (switched) ? Cudd_Not(x): x; + cuddRef(x); + + /* Seprate variable and child */ + if (factorsNv->g == one) { + Cudd_RecursiveDeref(dd, factorsNv->g); + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + factors->g = x; + factors->h = factorsNv->h; + /* cache the result*/ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + FREE(factors); + return NULL; + } + + /* store x in g table, the other node is already in the table */ + if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { + value |= 1; + } else { + value = 1; + } + if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + return(factors); + } + + /* Seprate variable and child */ + if (factorsNv->h == one) { + Cudd_RecursiveDeref(dd, factorsNv->h); + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + factors->g = factorsNv->g; + factors->h = x; + /* cache the result. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + FREE(factors); + return(NULL); + } + /* store x in h table, the other node is already in the table */ + if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { + value |= 2; + } else { + value = 2; + } + if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + return(factors); + } + + G = Cudd_Regular(factorsNv->g); + Gv = cuddT(G); + Gnv = cuddE(G); + Gv = Cudd_NotCond(Gv, Cudd_IsComplement(node)); + Gnv = Cudd_NotCond(Gnv, Cudd_IsComplement(node)); + /* if the child below is a variable */ + if ((Gv == zero) || (Gnv == zero)) { + h = factorsNv->h; + g = cuddBddAndRecur(dd, x, factorsNv->g); + if (g != NULL) cuddRef(g); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + if (g == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + return NULL; + } + /* CheckTablesCacheAndReturn responsible for allocating + * factors structure., g,h referenced for cache store the + */ + factors = CheckTablesCacheAndReturn(node, + g, + h, + ghTable, + cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g); + Cudd_RecursiveDeref(dd, h); + } + return(factors); + } + + H = Cudd_Regular(factorsNv->h); + Hv = cuddT(H); + Hnv = cuddE(H); + Hv = Cudd_NotCond(Hv, Cudd_IsComplement(node)); + Hnv = Cudd_NotCond(Hnv, Cudd_IsComplement(node)); + /* if the child below is a variable */ + if ((Hv == zero) || (Hnv == zero)) { + g = factorsNv->g; + h = cuddBddAndRecur(dd, x, factorsNv->h); + if (h!= NULL) cuddRef(h); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + if (h == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + return NULL; + } + /* CheckTablesCacheAndReturn responsible for allocating + * factors structure.g,h referenced for table store + */ + factors = CheckTablesCacheAndReturn(node, + g, + h, + ghTable, + cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g); + Cudd_RecursiveDeref(dd, h); + } + return(factors); + } + + /* build g1 = x*g; h1 = h */ + /* build g2 = g; h2 = x*h */ + Cudd_RecursiveDeref(dd, x); + h1 = factorsNv->h; + g1 = cuddBddAndRecur(dd, x, factorsNv->g); + if (g1 != NULL) cuddRef(g1); + if (g1 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + return NULL; + } + + g2 = factorsNv->g; + h2 = cuddBddAndRecur(dd, x, factorsNv->h); + if (h2 != NULL) cuddRef(h2); + if (h2 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNv->g); + return NULL; + } + + /* check whether any pair is in tables */ + factors = CheckInTables(node, g1, h1, g2, h2, ghTable, cacheTable, &outOfMem); + if (outOfMem) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + return NULL; + } + if (factors != NULL) { + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + return factors; + } + + /* check for each pair in tables and choose one */ + factors = PickOnePair(node,g1, h1, g2, h2, ghTable, cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + /* now free what was created and not used */ + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + } + + return(factors); +} /* end of ZeroCase */ + + +/**Function******************************************************************** + + Synopsis [Builds the conjuncts recursively, bottom up.] + + Description [Builds the conjuncts recursively, bottom up. Constants + are returned as (f, f). The cache is checked for previously computed + result. The decomposition points are determined by the local + reference count of this node and the longest distance from the + constant. At the decomposition point, the factors returned are (f, + 1). Recur on the two children. The order is determined by the + heavier branch. Combine the factors of the two children and pick the + one that already occurs in the gh table. Occurence in g is indicated + by value 1, occurence in h by 2, occurence in both 3.] + + SideEffects [] + + SeeAlso [cuddConjunctsAux] + +******************************************************************************/ +static Conjuncts * +BuildConjuncts( + DdManager * dd, + DdNode * node, + st_table * distanceTable, + st_table * cacheTable, + int approxDistance, + int maxLocalRef, + st_table * ghTable, + st_table * mintermTable) +{ + int topid, distance; + Conjuncts *factorsNv, *factorsNnv, *factors; + Conjuncts *dummy; + DdNode *N, *Nv, *Nnv, *temp, *g1, *g2, *h1, *h2, *topv; + double minNv = 0.0, minNnv = 0.0; + double *doubleDummy; + int switched =0; + int outOfMem; + int freeNv = 0, freeNnv = 0, freeTemp; + NodeStat *nodeStat; + int value; + + /* if f is constant, return (f,f) */ + if (Cudd_IsConstant(node)) { + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + factors->g = node; + factors->h = node; + return(FactorsComplement(factors)); + } + + /* If result (a pair of conjuncts) in cache, return the factors. */ + if (st_lookup(cacheTable, node, &dummy)) { + factors = dummy; + return(factors); + } + + /* check distance and local reference count of this node */ + N = Cudd_Regular(node); + if (!st_lookup(distanceTable, N, &nodeStat)) { + (void) fprintf(dd->err, "Not in table, Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + distance = nodeStat->distance; + + /* at or below decomposition point, return (f, 1) */ + if (((nodeStat->localRef > maxLocalRef*2/3) && + (distance < approxDistance*2/3)) || + (distance <= approxDistance/4)) { + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + /* alternate assigning (f,1) */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(node), &value)) { + if (value == 3) { + if (!lastTimeG) { + factors->g = node; + factors->h = one; + lastTimeG = 1; + } else { + factors->g = one; + factors->h = node; + lastTimeG = 0; + } + } else if (value == 1) { + factors->g = node; + factors->h = one; + } else { + factors->g = one; + factors->h = node; + } + } else if (!lastTimeG) { + factors->g = node; + factors->h = one; + lastTimeG = 1; + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(factors); + return NULL; + } + } else { + factors->g = one; + factors->h = node; + lastTimeG = 0; + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(factors); + return NULL; + } + } + return(FactorsComplement(factors)); + } + + /* get the children and recur */ + Nv = cuddT(N); + Nnv = cuddE(N); + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* Choose which subproblem to solve first based on the number of + * minterms. We go first where there are more minterms. + */ + if (!Cudd_IsConstant(Nv)) { + if (!st_lookup(mintermTable, Nv, &doubleDummy)) { + (void) fprintf(dd->err, "Not in table: Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + minNv = *doubleDummy; + } + + if (!Cudd_IsConstant(Nnv)) { + if (!st_lookup(mintermTable, Nnv, &doubleDummy)) { + (void) fprintf(dd->err, "Not in table: Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + minNnv = *doubleDummy; + } + + if (minNv < minNnv) { + temp = Nv; + Nv = Nnv; + Nnv = temp; + switched = 1; + } + + /* build gt, ht recursively */ + if (Nv != zero) { + factorsNv = BuildConjuncts(dd, Nv, distanceTable, + cacheTable, approxDistance, maxLocalRef, + ghTable, mintermTable); + if (factorsNv == NULL) return(NULL); + freeNv = FactorsNotStored(factorsNv); + factorsNv = (freeNv) ? FactorsUncomplement(factorsNv) : factorsNv; + cuddRef(factorsNv->g); + cuddRef(factorsNv->h); + + /* Deal with the zero case */ + if (Nnv == zero) { + /* is responsible for freeing factorsNv */ + factors = ZeroCase(dd, node, factorsNv, ghTable, + cacheTable, switched); + if (freeNv) FREE(factorsNv); + return(factors); + } + } + + /* build ge, he recursively */ + if (Nnv != zero) { + factorsNnv = BuildConjuncts(dd, Nnv, distanceTable, + cacheTable, approxDistance, maxLocalRef, + ghTable, mintermTable); + if (factorsNnv == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + if (freeNv) FREE(factorsNv); + return(NULL); + } + freeNnv = FactorsNotStored(factorsNnv); + factorsNnv = (freeNnv) ? FactorsUncomplement(factorsNnv) : factorsNnv; + cuddRef(factorsNnv->g); + cuddRef(factorsNnv->h); + + /* Deal with the zero case */ + if (Nv == zero) { + /* is responsible for freeing factorsNv */ + factors = ZeroCase(dd, node, factorsNnv, ghTable, + cacheTable, switched); + if (freeNnv) FREE(factorsNnv); + return(factors); + } + } + + /* construct the 2 pairs */ + /* g1 = x*gt + x'*ge; h1 = x*ht + x'*he; */ + /* g2 = x*gt + x'*he; h2 = x*ht + x'*ge */ + if (switched) { + factors = factorsNnv; + factorsNnv = factorsNv; + factorsNv = factors; + freeTemp = freeNv; + freeNv = freeNnv; + freeNnv = freeTemp; + } + + /* Build the factors for this node. */ + topid = N->index; + topv = dd->vars[topid]; + + g1 = cuddBddIteRecur(dd, topv, factorsNv->g, factorsNnv->g); + if (g1 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + + cuddRef(g1); + + h1 = cuddBddIteRecur(dd, topv, factorsNv->h, factorsNnv->h); + if (h1 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + + cuddRef(h1); + + g2 = cuddBddIteRecur(dd, topv, factorsNv->g, factorsNnv->h); + if (g2 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + cuddRef(g2); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + + h2 = cuddBddIteRecur(dd, topv, factorsNv->h, factorsNnv->g); + if (h2 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + cuddRef(h2); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + + /* check for each pair in tables and choose one */ + factors = CheckInTables(node, g1, h1, g2, h2, ghTable, cacheTable, &outOfMem); + if (outOfMem) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + return(NULL); + } + if (factors != NULL) { + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + return(factors); + } + + /* if not in tables, pick one pair */ + factors = PickOnePair(node,g1, h1, g2, h2, ghTable, cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + /* now free what was created and not used */ + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + } + + return(factors); + +} /* end of BuildConjuncts */ + + +/**Function******************************************************************** + + Synopsis [Procedure to compute two conjunctive factors of f and place in *c1 and *c2.] + + Description [Procedure to compute two conjunctive factors of f and + place in *c1 and *c2. Sets up the required data - table of distances + from the constant and local reference count. Also minterm table. ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +static int +cuddConjunctsAux( + DdManager * dd, + DdNode * f, + DdNode ** c1, + DdNode ** c2) +{ + st_table *distanceTable = NULL; + st_table *cacheTable = NULL; + st_table *mintermTable = NULL; + st_table *ghTable = NULL; + st_generator *stGen; + char *key, *value; + Conjuncts *factors; + int distance, approxDistance; + double max, minterms; + int freeFactors; + NodeStat *nodeStat; + int maxLocalRef; + + /* initialize */ + *c1 = NULL; + *c2 = NULL; + + /* initialize distances table */ + distanceTable = st_init_table(st_ptrcmp,st_ptrhash); + if (distanceTable == NULL) goto outOfMem; + + /* make the entry for the constant */ + nodeStat = ALLOC(NodeStat, 1); + if (nodeStat == NULL) goto outOfMem; + nodeStat->distance = 0; + nodeStat->localRef = 1; + if (st_insert(distanceTable, (char *)one, (char *)nodeStat) == ST_OUT_OF_MEM) { + goto outOfMem; + } + + /* Count node distances from constant. */ + nodeStat = CreateBotDist(f, distanceTable); + if (nodeStat == NULL) goto outOfMem; + + /* set the distance for the decomposition points */ + approxDistance = (DEPTH < nodeStat->distance) ? nodeStat->distance : DEPTH; + distance = nodeStat->distance; + + if (distance < approxDistance) { + /* Too small to bother. */ + *c1 = f; + *c2 = DD_ONE(dd); + cuddRef(*c1); cuddRef(*c2); + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); + return(1); + } + + /* record the maximum local reference count */ + maxLocalRef = 0; + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + nodeStat = (NodeStat *)value; + maxLocalRef = (nodeStat->localRef > maxLocalRef) ? + nodeStat->localRef : maxLocalRef; + } + st_free_gen(stGen); stGen = NULL; + + + /* Count minterms for each node. */ + max = pow(2.0, (double)Cudd_SupportSize(dd,f)); /* potential overflow */ + mintermTable = st_init_table(st_ptrcmp,st_ptrhash); + if (mintermTable == NULL) goto outOfMem; + minterms = CountMinterms(f, max, mintermTable, dd->err); + if (minterms == -1.0) goto outOfMem; + + lastTimeG = Cudd_Random() & 1; + cacheTable = st_init_table(st_ptrcmp, st_ptrhash); + if (cacheTable == NULL) goto outOfMem; + ghTable = st_init_table(st_ptrcmp, st_ptrhash); + if (ghTable == NULL) goto outOfMem; + + /* Build conjuncts. */ + factors = BuildConjuncts(dd, f, distanceTable, cacheTable, + approxDistance, maxLocalRef, ghTable, mintermTable); + if (factors == NULL) goto outOfMem; + + /* free up tables */ + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); distanceTable = NULL; + st_free_table(ghTable); ghTable = NULL; + + stGen = st_init_gen(mintermTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(mintermTable); mintermTable = NULL; + + freeFactors = FactorsNotStored(factors); + factors = (freeFactors) ? FactorsUncomplement(factors) : factors; + if (factors != NULL) { + *c1 = factors->g; + *c2 = factors->h; + cuddRef(*c1); + cuddRef(*c2); + if (freeFactors) FREE(factors); + +#if 0 + if ((*c1 == f) && (!Cudd_IsConstant(f))) { + assert(*c2 == one); + } + if ((*c2 == f) && (!Cudd_IsConstant(f))) { + assert(*c1 == one); + } + + if ((*c1 != one) && (!Cudd_IsConstant(f))) { + assert(!Cudd_bddLeq(dd, *c2, *c1)); + } + if ((*c2 != one) && (!Cudd_IsConstant(f))) { + assert(!Cudd_bddLeq(dd, *c1, *c2)); + } +#endif + } + + stGen = st_init_gen(cacheTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + ConjunctsFree(dd, (Conjuncts *)value); + } + st_free_gen(stGen); stGen = NULL; + + st_free_table(cacheTable); cacheTable = NULL; + + return(1); + +outOfMem: + if (distanceTable != NULL) { + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); distanceTable = NULL; + } + if (mintermTable != NULL) { + stGen = st_init_gen(mintermTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(mintermTable); mintermTable = NULL; + } + if (ghTable != NULL) st_free_table(ghTable); + if (cacheTable != NULL) { + stGen = st_init_gen(cacheTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + ConjunctsFree(dd, (Conjuncts *)value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(cacheTable); cacheTable = NULL; + } + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + +} /* end of cuddConjunctsAux */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddEssent.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddEssent.c new file mode 100644 index 000000000..7af6df651 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddEssent.c @@ -0,0 +1,1467 @@ +/**CFile*********************************************************************** + + FileName [cuddEssent.c] + + PackageName [cudd] + + Synopsis [Functions for the detection of essential variables.] + + Description [External procedures included in this file: +
            +
          • Cudd_FindEssential() +
          • Cudd_bddIsVarEssential() +
          • Cudd_FindTwoLiteralClauses() +
          • Cudd_ReadIthClause() +
          • Cudd_PrintTwoLiteralClauses() +
          • Cudd_tlcInfoFree() +
          + Static procedures included in this module: +
            +
          • ddFindEssentialRecur() +
          • ddFindTwoLiteralClausesRecur() +
          • computeClauses() +
          • computeClausesWithUniverse() +
          • emptyClauseSet() +
          • sentinelp() +
          • equalp() +
          • beforep() +
          • oneliteralp() +
          • impliedp() +
          • bitVectorAlloc() +
          • bitVectorClear() +
          • bitVectorFree() +
          • bitVectorRead() +
          • bitVectorSet() +
          • tlcInfoAlloc() +
          ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* These definitions are for the bit vectors. */ +#if SIZEOF_LONG == 8 +#define BPL 64 +#define LOGBPL 6 +#else +#define BPL 32 +#define LOGBPL 5 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/* This structure holds the set of clauses for a node. Each clause consists +** of two literals. For one-literal clauses, the second lietral is FALSE. +** Each literal is composed of a variable and a phase. A variable is a node +** index, and requires sizeof(DdHalfWord) bytes. The constant literals use +** CUDD_MAXINDEX as variable indicator. Each phase is a bit: 0 for positive +** phase, and 1 for negative phase. +** Variables and phases are stored separately for the sake of compactness. +** The variables are stored in an array of DdHalfWord's terminated by a +** sentinel (a pair of zeroes). The phases are stored in a bit vector. +** The cnt field holds, at the end, the number of clauses. +** The clauses of the set are kept sorted. For each clause, the first literal +** is the one of least index. So, the clause with literals +2 and -4 is stored +** as (+2,-4). A one-literal clause with literal +3 is stored as +** (+3,-CUDD_MAXINDEX). Clauses are sorted in decreasing order as follows: +** (+5,-7) +** (+5,+6) +** (-5,+7) +** (-4,FALSE) +** (-4,+8) +** ... +** That is, one first looks at the variable of the first literal, then at the +** phase of the first litral, then at the variable of the second literal, +** and finally at the phase of the second literal. +*/ +struct DdTlcInfo { + DdHalfWord *vars; + long *phases; + DdHalfWord cnt; +}; + +/* This structure is for temporary representation of sets of clauses. It is +** meant to be used in link lists, when the number of clauses is not yet +** known. The encoding of a clause is the same as in DdTlcInfo, though +** the phase information is not stored in a bit array. */ +struct TlClause { + DdHalfWord v1, v2; + short p1, p2; + struct TlClause *next; +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef long BitVector; +typedef struct TlClause TlClause; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddEssent.c,v 1.25 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static BitVector *Tolv; +static BitVector *Tolp; +static BitVector *Eolv; +static BitVector *Eolp; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * ddFindEssentialRecur (DdManager *dd, DdNode *f); +static DdTlcInfo * ddFindTwoLiteralClausesRecur (DdManager * dd, DdNode * f, st_table *table); +static DdTlcInfo * computeClauses (DdTlcInfo *Tres, DdTlcInfo *Eres, DdHalfWord label, int size); +static DdTlcInfo * computeClausesWithUniverse (DdTlcInfo *Cres, DdHalfWord label, short phase); +static DdTlcInfo * emptyClauseSet (void); +static int sentinelp (DdHalfWord var1, DdHalfWord var2); +static int equalp (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b); +static int beforep (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b); +static int oneliteralp (DdHalfWord var); +static int impliedp (DdHalfWord var1, short phase1, DdHalfWord var2, short phase2, BitVector *olv, BitVector *olp); +static BitVector * bitVectorAlloc (int size); +DD_INLINE static void bitVectorClear (BitVector *vector, int size); +static void bitVectorFree (BitVector *vector); +DD_INLINE static short bitVectorRead (BitVector *vector, int i); +DD_INLINE static void bitVectorSet (BitVector * vector, int i, short val); +static DdTlcInfo * tlcInfoAlloc (void); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Finds the essential variables of a DD.] + + Description [Returns the cube of the essential variables. A positive + literal means that the variable must be set to 1 for the function to be + 1. A negative literal means that the variable must be set to 0 for the + function to be 1. Returns a pointer to the cube BDD if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddIsVarEssential] + +******************************************************************************/ +DdNode * +Cudd_FindEssential( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = ddFindEssentialRecur(dd,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_FindEssential */ + + +/**Function******************************************************************** + + Synopsis [Determines whether a given variable is essential with a + given phase in a BDD.] + + Description [Determines whether a given variable is essential with a + given phase in a BDD. Uses Cudd_bddIteConstant. Returns 1 if phase == 1 + and f-->x_id, or if phase == 0 and f-->x_id'.] + + SideEffects [None] + + SeeAlso [Cudd_FindEssential] + +******************************************************************************/ +int +Cudd_bddIsVarEssential( + DdManager * manager, + DdNode * f, + int id, + int phase) +{ + DdNode *var; + int res; + + var = Cudd_bddIthVar(manager, id); + + var = Cudd_NotCond(var,phase == 0); + + res = Cudd_bddLeq(manager, f, var); + + return(res); + +} /* end of Cudd_bddIsVarEssential */ + + +/**Function******************************************************************** + + Synopsis [Finds the two literal clauses of a DD.] + + Description [Returns the one- and two-literal clauses of a DD. + Returns a pointer to the structure holding the clauses if + successful; NULL otherwise. For a constant DD, the empty set of clauses + is returned. This is obviously correct for a non-zero constant. For the + constant zero, it is based on the assumption that only those clauses + containing variables in the support of the function are considered. Since + the support of a constant function is empty, no clauses are returned.] + + SideEffects [None] + + SeeAlso [Cudd_FindEssential] + +******************************************************************************/ +DdTlcInfo * +Cudd_FindTwoLiteralClauses( + DdManager * dd, + DdNode * f) +{ + DdTlcInfo *res; + st_table *table; + st_generator *gen; + DdTlcInfo *tlc; + DdNode *node; + int size = dd->size; + + if (Cudd_IsConstant(f)) { + res = emptyClauseSet(); + return(res); + } + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) return(NULL); + Tolv = bitVectorAlloc(size); + if (Tolv == NULL) { + st_free_table(table); + return(NULL); + } + Tolp = bitVectorAlloc(size); + if (Tolp == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + return(NULL); + } + Eolv = bitVectorAlloc(size); + if (Eolv == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + return(NULL); + } + Eolp = bitVectorAlloc(size); + if (Eolp == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + bitVectorFree(Eolv); + return(NULL); + } + + res = ddFindTwoLiteralClausesRecur(dd,f,table); + /* Dispose of table contents and free table. */ + st_foreach_item(table, gen, &node, &tlc) { + if (node != f) { + Cudd_tlcInfoFree(tlc); + } + } + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + bitVectorFree(Eolv); + bitVectorFree(Eolp); + + if (res != NULL) { + int i; + for (i = 0; !sentinelp(res->vars[i], res->vars[i+1]); i += 2); + res->cnt = i >> 1; + } + + return(res); + +} /* end of Cudd_FindTwoLiteralClauses */ + + +/**Function******************************************************************** + + Synopsis [Accesses the i-th clause of a DD.] + + Description [Accesses the i-th clause of a DD given the clause set which + must be already computed. Returns 1 if successful; 0 if i is out of range, + or in case of error.] + + SideEffects [the four components of a clause are returned as side effects.] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +int +Cudd_ReadIthClause( + DdTlcInfo * tlc, + int i, + DdHalfWord *var1, + DdHalfWord *var2, + int *phase1, + int *phase2) +{ + if (tlc == NULL) return(0); + if (tlc->vars == NULL || tlc->phases == NULL) return(0); + if (i < 0 || (unsigned) i >= tlc->cnt) return(0); + *var1 = tlc->vars[2*i]; + *var2 = tlc->vars[2*i+1]; + *phase1 = (int) bitVectorRead(tlc->phases, 2*i); + *phase2 = (int) bitVectorRead(tlc->phases, 2*i+1); + return(1); + +} /* end of Cudd_ReadIthClause */ + + +/**Function******************************************************************** + + Synopsis [Prints the two literal clauses of a DD.] + + Description [Prints the one- and two-literal clauses. Returns 1 if + successful; 0 otherwise. The argument "names" can be NULL, in which case + the variable indices are printed.] + + SideEffects [None] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +int +Cudd_PrintTwoLiteralClauses( + DdManager * dd, + DdNode * f, + char **names, + FILE *fp) +{ + DdHalfWord *vars; + BitVector *phases; + int i; + DdTlcInfo *res = Cudd_FindTwoLiteralClauses(dd, f); + FILE *ifp = fp == NULL ? dd->out : fp; + + if (res == NULL) return(0); + vars = res->vars; + phases = res->phases; + for (i = 0; !sentinelp(vars[i], vars[i+1]); i += 2) { + if (names != NULL) { + if (vars[i+1] == CUDD_MAXINDEX) { + (void) fprintf(ifp, "%s%s\n", + bitVectorRead(phases, i) ? "~" : " ", + names[vars[i]]); + } else { + (void) fprintf(ifp, "%s%s | %s%s\n", + bitVectorRead(phases, i) ? "~" : " ", + names[vars[i]], + bitVectorRead(phases, i+1) ? "~" : " ", + names[vars[i+1]]); + } + } else { + if (vars[i+1] == CUDD_MAXINDEX) { + (void) fprintf(ifp, "%s%d\n", + bitVectorRead(phases, i) ? "~" : " ", + (int) vars[i]); + } else { + (void) fprintf(ifp, "%s%d | %s%d\n", + bitVectorRead(phases, i) ? "~" : " ", + (int) vars[i], + bitVectorRead(phases, i+1) ? "~" : " ", + (int) vars[i+1]); + } + } + } + Cudd_tlcInfoFree(res); + + return(1); + +} /* end of Cudd_PrintTwoLiteralClauses */ + + +/**Function******************************************************************** + + Synopsis [Frees a DdTlcInfo Structure.] + + Description [Frees a DdTlcInfo Structure as well as the memory pointed + by it.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_tlcInfoFree( + DdTlcInfo * t) +{ + if (t->vars != NULL) FREE(t->vars); + if (t->phases != NULL) FREE(t->phases); + FREE(t); + +} /* end of Cudd_tlcInfoFree */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_FindEssential.] + + Description [Implements the recursive step of Cudd_FindEssential. + Returns a pointer to the cube BDD if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +ddFindEssentialRecur( + DdManager * dd, + DdNode * f) +{ + DdNode *T, *E, *F; + DdNode *essT, *essE, *res; + int index; + DdNode *one, *lzero, *azero; + + one = DD_ONE(dd); + F = Cudd_Regular(f); + /* If f is constant the set of essential variables is empty. */ + if (cuddIsConstant(F)) return(one); + + res = cuddCacheLookup1(dd,Cudd_FindEssential,f); + if (res != NULL) { + return(res); + } + + lzero = Cudd_Not(one); + azero = DD_ZERO(dd); + /* Find cofactors: here f is non-constant. */ + T = cuddT(F); + E = cuddE(F); + if (Cudd_IsComplement(f)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + + index = F->index; + if (Cudd_IsConstant(T) && T != lzero && T != azero) { + /* if E is zero, index is essential, otherwise there are no + ** essentials, because index is not essential and no other variable + ** can be, since setting index = 1 makes the function constant and + ** different from 0. + */ + if (E == lzero || E == azero) { + res = dd->vars[index]; + } else { + res = one; + } + } else if (T == lzero || T == azero) { + if (Cudd_IsConstant(E)) { /* E cannot be zero here */ + res = Cudd_Not(dd->vars[index]); + } else { /* E == non-constant */ + /* find essentials in the else branch */ + essE = ddFindEssentialRecur(dd,E); + if (essE == NULL) { + return(NULL); + } + cuddRef(essE); + + /* add index to the set with negative phase */ + res = cuddUniqueInter(dd,index,one,Cudd_Not(essE)); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essE); + return(NULL); + } + res = Cudd_Not(res); + cuddDeref(essE); + } + } else { /* T == non-const */ + if (E == lzero || E == azero) { + /* find essentials in the then branch */ + essT = ddFindEssentialRecur(dd,T); + if (essT == NULL) { + return(NULL); + } + cuddRef(essT); + + /* add index to the set with positive phase */ + /* use And because essT may be complemented */ + res = cuddBddAndRecur(dd,dd->vars[index],essT); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essT); + return(NULL); + } + cuddDeref(essT); + } else if (!Cudd_IsConstant(E)) { + /* if E is a non-zero constant there are no essentials + ** because T is non-constant. + */ + essT = ddFindEssentialRecur(dd,T); + if (essT == NULL) { + return(NULL); + } + if (essT == one) { + res = one; + } else { + cuddRef(essT); + essE = ddFindEssentialRecur(dd,E); + if (essE == NULL) { + Cudd_RecursiveDeref(dd,essT); + return(NULL); + } + cuddRef(essE); + + /* res = intersection(essT, essE) */ + res = cuddBddLiteralSetIntersectionRecur(dd,essT,essE); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essT); + Cudd_RecursiveDeref(dd,essE); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,essT); + Cudd_RecursiveDeref(dd,essE); + cuddDeref(res); + } + } else { /* E is a non-zero constant */ + res = one; + } + } + + cuddCacheInsert1(dd,Cudd_FindEssential, f, res); + return(res); + +} /* end of ddFindEssentialRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_FindTwoLiteralClauses.] + + Description [Implements the recursive step of + Cudd_FindTwoLiteralClauses. The DD node is assumed to be not + constant. Returns a pointer to a set of clauses if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +static DdTlcInfo * +ddFindTwoLiteralClausesRecur( + DdManager * dd, + DdNode * f, + st_table *table) +{ + DdNode *T, *E, *F; + DdNode *one, *lzero, *azero; + DdTlcInfo *res, *Tres, *Eres; + DdHalfWord index; + + F = Cudd_Regular(f); + + assert(!cuddIsConstant(F)); + + /* Check computed table. Separate entries are necessary for + ** a node and its complement. We should update the counter here. */ + if (st_lookup(table, f, &res)) { + return(res); + } + + /* Easy access to the constants for BDDs and ADDs. */ + one = DD_ONE(dd); + lzero = Cudd_Not(one); + azero = DD_ZERO(dd); + + /* Find cofactors and variable labeling the top node. */ + T = cuddT(F); E = cuddE(F); + if (Cudd_IsComplement(f)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + index = F->index; + + if (Cudd_IsConstant(T) && T != lzero && T != azero) { + /* T is a non-zero constant. If E is zero, then this node's index + ** is a one-literal clause. Otherwise, if E is a non-zero + ** constant, there are no clauses for this node. Finally, + ** if E is not constant, we recursively compute its clauses, and then + ** merge using the empty set for T. */ + if (E == lzero || E == azero) { + /* Create the clause (index + 0). */ + res = tlcInfoAlloc(); + if (res == NULL) return(NULL); + res->vars = ALLOC(DdHalfWord,4); + if (res->vars == NULL) { + FREE(res); + return(NULL); + } + res->phases = bitVectorAlloc(2); + if (res->phases == NULL) { + FREE(res->vars); + FREE(res); + return(NULL); + } + res->vars[0] = index; + res->vars[1] = CUDD_MAXINDEX; + res->vars[2] = 0; + res->vars[3] = 0; + bitVectorSet(res->phases, 0, 0); /* positive phase */ + bitVectorSet(res->phases, 1, 1); /* negative phase */ + } else if (Cudd_IsConstant(E)) { + /* If E is a non-zero constant, no clauses. */ + res = emptyClauseSet(); + } else { + /* E is non-constant */ + Tres = emptyClauseSet(); + if (Tres == NULL) return(NULL); + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) { + Cudd_tlcInfoFree(Tres); + return(NULL); + } + res = computeClauses(Tres, Eres, index, dd->size); + Cudd_tlcInfoFree(Tres); + } + } else if (T == lzero || T == azero) { + /* T is zero. If E is a non-zero constant, then the + ** complement of this node's index is a one-literal clause. + ** Otherwise, if E is not constant, we recursively compute its + ** clauses, and then merge using the universal set for T. */ + if (Cudd_IsConstant(E)) { /* E cannot be zero here */ + /* Create the clause (!index + 0). */ + res = tlcInfoAlloc(); + if (res == NULL) return(NULL); + res->vars = ALLOC(DdHalfWord,4); + if (res->vars == NULL) { + FREE(res); + return(NULL); + } + res->phases = bitVectorAlloc(2); + if (res->phases == NULL) { + FREE(res->vars); + FREE(res); + return(NULL); + } + res->vars[0] = index; + res->vars[1] = CUDD_MAXINDEX; + res->vars[2] = 0; + res->vars[3] = 0; + bitVectorSet(res->phases, 0, 1); /* negative phase */ + bitVectorSet(res->phases, 1, 1); /* negative phase */ + } else { /* E == non-constant */ + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) return(NULL); + res = computeClausesWithUniverse(Eres, index, 1); + } + } else { /* T == non-const */ + Tres = ddFindTwoLiteralClausesRecur(dd, T, table); + if (Tres == NULL) return(NULL); + if (Cudd_IsConstant(E)) { + if (E == lzero || E == azero) { + res = computeClausesWithUniverse(Tres, index, 0); + } else { + Eres = emptyClauseSet(); + if (Eres == NULL) return(NULL); + res = computeClauses(Tres, Eres, index, dd->size); + Cudd_tlcInfoFree(Eres); + } + } else { + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) return(NULL); + res = computeClauses(Tres, Eres, index, dd->size); + } + } + + /* Cache results. */ + if (st_add_direct(table, (char *)f, (char *)res) == ST_OUT_OF_MEM) { + FREE(res); + return(NULL); + } + return(res); + +} /* end of ddFindTwoLiteralClausesRecur */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-literal clauses for a node.] + + Description [Computes the two-literal clauses for a node given the + clauses for its children and the label of the node. Returns a + pointer to a TclInfo structure if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [computeClausesWithUniverse] + +******************************************************************************/ +static DdTlcInfo * +computeClauses( + DdTlcInfo *Tres /* list of clauses for T child */, + DdTlcInfo *Eres /* list of clauses for E child */, + DdHalfWord label /* variable labeling the current node */, + int size /* number of variables in the manager */) +{ + DdHalfWord *Tcv = Tres->vars; /* variables of clauses for the T child */ + BitVector *Tcp = Tres->phases; /* phases of clauses for the T child */ + DdHalfWord *Ecv = Eres->vars; /* variables of clauses for the E child */ + BitVector *Ecp = Eres->phases; /* phases of clauses for the E child */ + DdHalfWord *Vcv = NULL; /* pointer to variables of the clauses for v */ + BitVector *Vcp = NULL; /* pointer to phases of the clauses for v */ + DdTlcInfo *res = NULL; /* the set of clauses to be returned */ + int pt = 0; /* index in the list of clauses of T */ + int pe = 0; /* index in the list of clauses of E */ + int cv = 0; /* counter of the clauses for this node */ + TlClause *iclauses = NULL; /* list of inherited clauses */ + TlClause *tclauses = NULL; /* list of 1-literal clauses of T */ + TlClause *eclauses = NULL; /* list of 1-literal clauses of E */ + TlClause *nclauses = NULL; /* list of new (non-inherited) clauses */ + TlClause *lnclause = NULL; /* pointer to last new clause */ + TlClause *newclause; /* temporary pointer to new clauses */ + + /* Initialize sets of one-literal clauses. The one-literal clauses + ** are stored redundantly. These sets allow constant-time lookup, which + ** we need when we check for implication of a two-literal clause by a + ** one-literal clause. The linked lists allow fast sequential + ** processing. */ + bitVectorClear(Tolv, size); + bitVectorClear(Tolp, size); + bitVectorClear(Eolv, size); + bitVectorClear(Eolp, size); + + /* Initialize result structure. */ + res = tlcInfoAlloc(); + if (res == NULL) goto cleanup; + + /* Scan the two input list. Extract inherited two-literal clauses + ** and set aside one-literal clauses from each list. The incoming lists + ** are sorted in the order defined by beforep. The three linked list + ** produced by this loop are sorted in the reverse order because we + ** always append to the front of the lists. + ** The inherited clauses are those clauses (both one- and two-literal) + ** that are common to both children; and the two-literal clauses of + ** one child that are implied by a one-literal clause of the other + ** child. */ + while (!sentinelp(Tcv[pt], Tcv[pt+1]) || !sentinelp(Ecv[pe], Ecv[pe+1])) { + if (equalp(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1))) { + /* Add clause to inherited list. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = Tcv[pt+1]; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = bitVectorRead(Tcp, pt+1); + newclause->next = iclauses; + iclauses = newclause; + pt += 2; pe += 2; cv++; + } else if (beforep(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1))) { + if (oneliteralp(Tcv[pt+1])) { + /* Add this one-literal clause to the T set. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = 1; + newclause->next = tclauses; + tclauses = newclause; + bitVectorSet(Tolv, Tcv[pt], 1); + bitVectorSet(Tolp, Tcv[pt], bitVectorRead(Tcp, pt)); + } else { + if (impliedp(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Eolv, Eolp)) { + /* Add clause to inherited list. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = Tcv[pt+1]; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = bitVectorRead(Tcp, pt+1); + newclause->next = iclauses; + iclauses = newclause; + cv++; + } + } + pt += 2; + } else { /* !beforep() */ + if (oneliteralp(Ecv[pe+1])) { + /* Add this one-literal clause to the E set. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Ecv[pe]; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = bitVectorRead(Ecp, pe); + newclause->p2 = 1; + newclause->next = eclauses; + eclauses = newclause; + bitVectorSet(Eolv, Ecv[pe], 1); + bitVectorSet(Eolp, Ecv[pe], bitVectorRead(Ecp, pe)); + } else { + if (impliedp(Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1), + Tolv, Tolp)) { + /* Add clause to inherited list. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Ecv[pe]; + newclause->v2 = Ecv[pe+1]; + newclause->p1 = bitVectorRead(Ecp, pe); + newclause->p2 = bitVectorRead(Ecp, pe+1); + newclause->next = iclauses; + iclauses = newclause; + cv++; + } + } + pe += 2; + } + } + + /* Add one-literal clauses for the label variable to the front of + ** the two lists. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = label; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = 0; + newclause->p2 = 1; + newclause->next = tclauses; + tclauses = newclause; + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = label; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = 1; + newclause->p2 = 1; + newclause->next = eclauses; + eclauses = newclause; + + /* Produce the non-inherited clauses. We preserve the "reverse" + ** order of the two input lists by appending to the end of the + ** list. In this way, iclauses and nclauses are consistent. */ + while (tclauses != NULL && eclauses != NULL) { + if (beforep(eclauses->v1, eclauses->p1, eclauses->v2, eclauses->p2, + tclauses->v1, tclauses->p1, tclauses->v2, tclauses->p2)) { + TlClause *nextclause = tclauses->next; + TlClause *otherclauses = eclauses; + while (otherclauses != NULL) { + if (tclauses->v1 != otherclauses->v1) { + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = tclauses->v1; + newclause->v2 = otherclauses->v1; + newclause->p1 = tclauses->p1; + newclause->p2 = otherclauses->p1; + newclause->next = NULL; + if (nclauses == NULL) { + nclauses = newclause; + lnclause = newclause; + } else { + lnclause->next = newclause; + lnclause = newclause; + } + cv++; + } + otherclauses = otherclauses->next; + } + FREE(tclauses); + tclauses = nextclause; + } else { + TlClause *nextclause = eclauses->next; + TlClause *otherclauses = tclauses; + while (otherclauses != NULL) { + if (eclauses->v1 != otherclauses->v1) { + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = eclauses->v1; + newclause->v2 = otherclauses->v1; + newclause->p1 = eclauses->p1; + newclause->p2 = otherclauses->p1; + newclause->next = NULL; + if (nclauses == NULL) { + nclauses = newclause; + lnclause = newclause; + } else { + lnclause->next = newclause; + lnclause = newclause; + } + cv++; + } + otherclauses = otherclauses->next; + } + FREE(eclauses); + eclauses = nextclause; + } + } + while (tclauses != NULL) { + TlClause *nextclause = tclauses->next; + FREE(tclauses); + tclauses = nextclause; + } + while (eclauses != NULL) { + TlClause *nextclause = eclauses->next; + FREE(eclauses); + eclauses = nextclause; + } + + /* Merge inherited and non-inherited clauses. Now that we know the + ** total number, we allocate the arrays, and we fill them bottom-up + ** to restore the proper ordering. */ + Vcv = ALLOC(DdHalfWord, 2*(cv+1)); + if (Vcv == NULL) goto cleanup; + if (cv > 0) { + Vcp = bitVectorAlloc(2*cv); + if (Vcp == NULL) goto cleanup; + } else { + Vcp = NULL; + } + res->vars = Vcv; + res->phases = Vcp; + /* Add sentinel. */ + Vcv[2*cv] = 0; + Vcv[2*cv+1] = 0; + while (iclauses != NULL || nclauses != NULL) { + TlClause *nextclause; + cv--; + if (nclauses == NULL || (iclauses != NULL && + beforep(nclauses->v1, nclauses->p1, nclauses->v2, nclauses->p2, + iclauses->v1, iclauses->p1, iclauses->v2, iclauses->p2))) { + Vcv[2*cv] = iclauses->v1; + Vcv[2*cv+1] = iclauses->v2; + bitVectorSet(Vcp, 2*cv, iclauses->p1); + bitVectorSet(Vcp, 2*cv+1, iclauses->p2); + nextclause = iclauses->next; + FREE(iclauses); + iclauses = nextclause; + } else { + Vcv[2*cv] = nclauses->v1; + Vcv[2*cv+1] = nclauses->v2; + bitVectorSet(Vcp, 2*cv, nclauses->p1); + bitVectorSet(Vcp, 2*cv+1, nclauses->p2); + nextclause = nclauses->next; + FREE(nclauses); + nclauses = nextclause; + } + } + assert(cv == 0); + + return(res); + + cleanup: + if (res != NULL) Cudd_tlcInfoFree(res); + while (iclauses != NULL) { + TlClause *nextclause = iclauses->next; + FREE(iclauses); + iclauses = nextclause; + } + while (nclauses != NULL) { + TlClause *nextclause = nclauses->next; + FREE(nclauses); + nclauses = nextclause; + } + while (tclauses != NULL) { + TlClause *nextclause = tclauses->next; + FREE(tclauses); + tclauses = nextclause; + } + while (eclauses != NULL) { + TlClause *nextclause = eclauses->next; + FREE(eclauses); + eclauses = nextclause; + } + + return(NULL); + +} /* end of computeClauses */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-literal clauses for a node.] + + Description [Computes the two-literal clauses for a node with a zero + child, given the clauses for its other child and the label of the + node. Returns a pointer to a TclInfo structure if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [computeClauses] + +******************************************************************************/ +static DdTlcInfo * +computeClausesWithUniverse( + DdTlcInfo *Cres /* list of clauses for child */, + DdHalfWord label /* variable labeling the current node */, + short phase /* 0 if E child is zero; 1 if T child is zero */) +{ + DdHalfWord *Ccv = Cres->vars; /* variables of clauses for child */ + BitVector *Ccp = Cres->phases; /* phases of clauses for child */ + DdHalfWord *Vcv = NULL; /* pointer to the variables of the clauses for v */ + BitVector *Vcp = NULL; /* pointer to the phases of the clauses for v */ + DdTlcInfo *res = NULL; /* the set of clauses to be returned */ + int i; + + /* Initialize result. */ + res = tlcInfoAlloc(); + if (res == NULL) goto cleanup; + /* Count entries for new list and allocate accordingly. */ + for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2); + /* At this point, i is twice the number of clauses in the child's + ** list. We need four more entries for this node: 2 for the one-literal + ** clause for the label, and 2 for the sentinel. */ + Vcv = ALLOC(DdHalfWord,i+4); + if (Vcv == NULL) goto cleanup; + Vcp = bitVectorAlloc(i+4); + if (Vcp == NULL) goto cleanup; + res->vars = Vcv; + res->phases = Vcp; + /* Copy old list into new. */ + for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2) { + Vcv[i] = Ccv[i]; + Vcv[i+1] = Ccv[i+1]; + bitVectorSet(Vcp, i, bitVectorRead(Ccp, i)); + bitVectorSet(Vcp, i+1, bitVectorRead(Ccp, i+1)); + } + /* Add clause corresponding to label. */ + Vcv[i] = label; + bitVectorSet(Vcp, i, phase); + i++; + Vcv[i] = CUDD_MAXINDEX; + bitVectorSet(Vcp, i, 1); + i++; + /* Add sentinel. */ + Vcv[i] = 0; + Vcv[i+1] = 0; + bitVectorSet(Vcp, i, 0); + bitVectorSet(Vcp, i+1, 0); + + return(res); + + cleanup: + /* Vcp is guaranteed to be NULL here. Hence, we do not try to free it. */ + if (Vcv != NULL) FREE(Vcv); + if (res != NULL) Cudd_tlcInfoFree(res); + + return(NULL); + +} /* end of computeClausesWithUniverse */ + + +/**Function******************************************************************** + + Synopsis [Returns an enpty set of clauses.] + + Description [Returns a pointer to an empty set of clauses if + successful; NULL otherwise. No bit vector for the phases is + allocated.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdTlcInfo * +emptyClauseSet(void) +{ + DdTlcInfo *eset; + + eset = ALLOC(DdTlcInfo,1); + if (eset == NULL) return(NULL); + eset->vars = ALLOC(DdHalfWord,2); + if (eset->vars == NULL) { + FREE(eset); + return(NULL); + } + /* Sentinel */ + eset->vars[0] = 0; + eset->vars[1] = 0; + eset->phases = NULL; /* does not matter */ + eset->cnt = 0; + return(eset); + +} /* end of emptyClauseSet */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the argument is the sentinel clause.] + + Description [Returns true iff the argument is the sentinel clause. + A sentinel clause has both variables equal to 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +sentinelp( + DdHalfWord var1, + DdHalfWord var2) +{ + return(var1 == 0 && var2 == 0); + +} /* end of sentinelp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the two arguments are identical clauses.] + + Description [Returns true iff the two arguments are identical + clauses. Since literals are sorted, we only need to compare + literals in the same position.] + + SideEffects [None] + + SeeAlso [beforep] + +******************************************************************************/ +static int +equalp( + DdHalfWord var1a, + short phase1a, + DdHalfWord var1b, + short phase1b, + DdHalfWord var2a, + short phase2a, + DdHalfWord var2b, + short phase2b) +{ + return(var1a == var2a && phase1a == phase2a && + var1b == var2b && phase1b == phase2b); + +} /* end of equalp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the first argument precedes the second in + the clause order.] + + Description [Returns true iff the first argument precedes the second + in the clause order. A clause precedes another if its first lieral + precedes the first literal of the other, or if the first literals + are the same, and its second literal precedes the second literal of + the other clause. A literal precedes another if it has a higher + index, of if it has the same index, but it has lower phase. Phase 0 + is the positive phase, and it is lower than Phase 1 (negative + phase).] + + SideEffects [None] + + SeeAlso [equalp] + +******************************************************************************/ +static int +beforep( + DdHalfWord var1a, + short phase1a, + DdHalfWord var1b, + short phase1b, + DdHalfWord var2a, + short phase2a, + DdHalfWord var2b, + short phase2b) +{ + return(var1a > var2a || (var1a == var2a && + (phase1a < phase2a || (phase1a == phase2a && + (var1b > var2b || (var1b == var2b && phase1b < phase2b)))))); + +} /* end of beforep */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the argument is a one-literal clause.] + + Description [Returns true iff the argument is a one-literal clause. + A one-litaral clause has the constant FALSE as second literal. + Since the constant TRUE is never used, it is sufficient to test for + a constant.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +oneliteralp( + DdHalfWord var) +{ + return(var == CUDD_MAXINDEX); + +} /* end of oneliteralp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff either literal of a clause is in a set of + literals.] + + Description [Returns true iff either literal of a clause is in a set + of literals. The first four arguments specify the clause. The + remaining two arguments specify the literal set.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +impliedp( + DdHalfWord var1, + short phase1, + DdHalfWord var2, + short phase2, + BitVector *olv, + BitVector *olp) +{ + return((bitVectorRead(olv, var1) && + bitVectorRead(olp, var1) == phase1) || + (bitVectorRead(olv, var2) && + bitVectorRead(olp, var2) == phase2)); + +} /* end of impliedp */ + + +/**Function******************************************************************** + + Synopsis [Allocates a bit vector.] + + Description [Allocates a bit vector. The parameter size gives the + number of bits. This procedure allocates enough long's to hold the + specified number of bits. Returns a pointer to the allocated vector + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [bitVectorClear bitVectorFree] + +******************************************************************************/ +static BitVector * +bitVectorAlloc( + int size) +{ + int allocSize; + BitVector *vector; + + /* Find out how many long's we need. + ** There are sizeof(long) * 8 bits in a long. + ** The ceiling of the ratio of two integers m and n is given + ** by ((n-1)/m)+1. Putting all this together, we get... */ + allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1; + vector = ALLOC(BitVector, allocSize); + if (vector == NULL) return(NULL); + /* Clear the whole array. */ + (void) memset(vector, 0, allocSize * sizeof(BitVector)); + return(vector); + +} /* end of bitVectorAlloc */ + + +/**Function******************************************************************** + + Synopsis [Clears a bit vector.] + + Description [Clears a bit vector. The parameter size gives the + number of bits.] + + SideEffects [None] + + SeeAlso [bitVectorAlloc] + +******************************************************************************/ +DD_INLINE +static void +bitVectorClear( + BitVector *vector, + int size) +{ + int allocSize; + + /* Find out how many long's we need. + ** There are sizeof(long) * 8 bits in a long. + ** The ceiling of the ratio of two integers m and n is given + ** by ((n-1)/m)+1. Putting all this together, we get... */ + allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1; + /* Clear the whole array. */ + (void) memset(vector, 0, allocSize * sizeof(BitVector)); + return; + +} /* end of bitVectorClear */ + + +/**Function******************************************************************** + + Synopsis [Frees a bit vector.] + + Description [Frees a bit vector.] + + SideEffects [None] + + SeeAlso [bitVectorAlloc] + +******************************************************************************/ +static void +bitVectorFree( + BitVector *vector) +{ + FREE(vector); + +} /* end of bitVectorFree */ + + +/**Function******************************************************************** + + Synopsis [Returns the i-th entry of a bit vector.] + + Description [Returns the i-th entry of a bit vector.] + + SideEffects [None] + + SeeAlso [bitVectorSet] + +******************************************************************************/ +DD_INLINE +static short +bitVectorRead( + BitVector *vector, + int i) +{ + int word, bit; + short result; + + if (vector == NULL) return((short) 0); + + word = i >> LOGBPL; + bit = i & (BPL - 1); + result = (short) ((vector[word] >> bit) & 1L); + return(result); + +} /* end of bitVectorRead */ + + +/**Function******************************************************************** + + Synopsis [Sets the i-th entry of a bit vector to a value.] + + Description [Sets the i-th entry of a bit vector to a value.] + + SideEffects [None] + + SeeAlso [bitVectorRead] + +******************************************************************************/ +DD_INLINE +static void +bitVectorSet( + BitVector * vector, + int i, + short val) +{ + int word, bit; + + word = i >> LOGBPL; + bit = i & (BPL - 1); + vector[word] &= ~(1L << bit); + vector[word] |= (((long) val) << bit); + +} /* end of bitVectorSet */ + + +/**Function******************************************************************** + + Synopsis [Allocates a DdTlcInfo Structure.] + + Description [Returns a pointer to a DdTlcInfo Structure if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_tlcInfoFree] + +******************************************************************************/ +static DdTlcInfo * +tlcInfoAlloc(void) +{ + DdTlcInfo *res = ALLOC(DdTlcInfo,1); + if (res == NULL) return(NULL); + res->vars = NULL; + res->phases = NULL; + res->cnt = 0; + return(res); + +} /* end of tlcInfoAlloc */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddExact.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddExact.c new file mode 100644 index 000000000..caffbba88 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddExact.c @@ -0,0 +1,1020 @@ +/**CFile*********************************************************************** + + FileName [cuddExact.c] + + PackageName [cudd] + + Synopsis [Functions for exact variable reordering.] + + Description [External procedures included in this file: +
            +
          + Internal procedures included in this module: +
            +
          • cuddExact() +
          + Static procedures included in this module: +
            +
          • getMaxBinomial() +
          • gcd() +
          • getMatrix() +
          • freeMatrix() +
          • getLevelKeys() +
          • ddShuffle() +
          • ddSiftUp() +
          • updateUB() +
          • ddCountRoots() +
          • ddClearGlobal() +
          • computeLB() +
          • updateEntry() +
          • pushDown() +
          • initSymmInfo() +
          ] + + Author [Cheng Hua, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddExact.c,v 1.30 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef DD_STATS +static int ddTotalShuffles; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int getMaxBinomial (int n); +static DdHalfWord ** getMatrix (int rows, int cols); +static void freeMatrix (DdHalfWord **matrix); +static int getLevelKeys (DdManager *table, int l); +static int ddShuffle (DdManager *table, DdHalfWord *permutation, int lower, int upper); +static int ddSiftUp (DdManager *table, int x, int xLow); +static int updateUB (DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper); +static int ddCountRoots (DdManager *table, int lower, int upper); +static void ddClearGlobal (DdManager *table, int lower, int maxlevel); +static int computeLB (DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level); +static int updateEntry (DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper); +static void pushDown (DdHalfWord *order, int j, int level); +static DdHalfWord * initSymmInfo (DdManager *table, int lower, int upper); +static int checkSymmInfo (DdManager *table, DdHalfWord *symmInfo, int index, int level); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Exact variable ordering algorithm.] + + Description [Exact variable ordering algorithm. Finds an optimum + order for the variables between lower and upper. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddExact( + DdManager * table, + int lower, + int upper) +{ + int k, i, j; + int maxBinomial, oldSubsets, newSubsets; + int subsetCost; + int size; /* number of variables to be reordered */ + int unused, nvars, level, result; + int upperBound, lowerBound, cost; + int roots; + char *mask = NULL; + DdHalfWord *symmInfo = NULL; + DdHalfWord **newOrder = NULL; + DdHalfWord **oldOrder = NULL; + int *newCost = NULL; + int *oldCost = NULL; + DdHalfWord **tmpOrder; + int *tmpCost; + DdHalfWord *bestOrder = NULL; + DdHalfWord *order; +#ifdef DD_STATS + int ddTotalSubsets; +#endif + + /* Restrict the range to be reordered by excluding unused variables + ** at the two ends. */ + while (table->subtables[lower].keys == 1 && + table->vars[table->invperm[lower]]->ref == 1 && + lower < upper) + lower++; + while (table->subtables[upper].keys == 1 && + table->vars[table->invperm[upper]]->ref == 1 && + lower < upper) + upper--; + if (lower == upper) return(1); /* trivial problem */ + + /* Apply symmetric sifting to get a good upper bound and to extract + ** symmetry information. */ + result = cuddSymmSiftingConv(table,lower,upper); + if (result == 0) goto cuddExactOutOfMem; + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + ddTotalShuffles = 0; + ddTotalSubsets = 0; +#endif + + /* Initialization. */ + nvars = table->size; + size = upper - lower + 1; + /* Count unused variable among those to be reordered. This is only + ** used to compute maxBinomial. */ + unused = 0; + for (i = lower + 1; i < upper; i++) { + if (table->subtables[i].keys == 1 && + table->vars[table->invperm[i]]->ref == 1) + unused++; + } + + /* Find the maximum number of subsets we may have to store. */ + maxBinomial = getMaxBinomial(size - unused); + if (maxBinomial == -1) goto cuddExactOutOfMem; + + newOrder = getMatrix(maxBinomial, size); + if (newOrder == NULL) goto cuddExactOutOfMem; + + newCost = ALLOC(int, maxBinomial); + if (newCost == NULL) goto cuddExactOutOfMem; + + oldOrder = getMatrix(maxBinomial, size); + if (oldOrder == NULL) goto cuddExactOutOfMem; + + oldCost = ALLOC(int, maxBinomial); + if (oldCost == NULL) goto cuddExactOutOfMem; + + bestOrder = ALLOC(DdHalfWord, size); + if (bestOrder == NULL) goto cuddExactOutOfMem; + + mask = ALLOC(char, nvars); + if (mask == NULL) goto cuddExactOutOfMem; + + symmInfo = initSymmInfo(table, lower, upper); + if (symmInfo == NULL) goto cuddExactOutOfMem; + + roots = ddCountRoots(table, lower, upper); + + /* Initialize the old order matrix for the empty subset and the best + ** order to the current order. The cost for the empty subset includes + ** the cost of the levels between upper and the constants. These levels + ** are not going to change. Hence, we count them only once. + */ + oldSubsets = 1; + for (i = 0; i < size; i++) { + oldOrder[0][i] = bestOrder[i] = (DdHalfWord) table->invperm[i+lower]; + } + subsetCost = table->constants.keys; + for (i = upper + 1; i < nvars; i++) + subsetCost += getLevelKeys(table,i); + oldCost[0] = subsetCost; + /* The upper bound is initialized to the current size of the BDDs. */ + upperBound = table->keys - table->isolated; + + /* Now consider subsets of increasing size. */ + for (k = 1; k <= size; k++) { +#ifdef DD_STATS + (void) fprintf(table->out,"Processing subsets of size %d\n", k); + fflush(table->out); +#endif + newSubsets = 0; + level = size - k; /* offset of first bottom variable */ + + for (i = 0; i < oldSubsets; i++) { /* for each subset of size k-1 */ + order = oldOrder[i]; + cost = oldCost[i]; + lowerBound = computeLB(table, order, roots, cost, lower, upper, + level); + if (lowerBound >= upperBound) + continue; + /* Impose new order. */ + result = ddShuffle(table, order, lower, upper); + if (result == 0) goto cuddExactOutOfMem; + upperBound = updateUB(table,upperBound,bestOrder,lower,upper); + /* For each top bottom variable. */ + for (j = level; j >= 0; j--) { + /* Skip unused variables. */ + if (table->subtables[j+lower-1].keys == 1 && + table->vars[table->invperm[j+lower-1]]->ref == 1) continue; + /* Find cost under this order. */ + subsetCost = cost + getLevelKeys(table, lower + level); + newSubsets = updateEntry(table, order, level, subsetCost, + newOrder, newCost, newSubsets, mask, + lower, upper); + if (j == 0) + break; + if (checkSymmInfo(table, symmInfo, order[j-1], level) == 0) + continue; + pushDown(order,j-1,level); + /* Impose new order. */ + result = ddShuffle(table, order, lower, upper); + if (result == 0) goto cuddExactOutOfMem; + upperBound = updateUB(table,upperBound,bestOrder,lower,upper); + } /* for each bottom variable */ + } /* for each subset of size k */ + + /* New orders become old orders in preparation for next iteration. */ + tmpOrder = oldOrder; tmpCost = oldCost; + oldOrder = newOrder; oldCost = newCost; + newOrder = tmpOrder; newCost = tmpCost; +#ifdef DD_STATS + ddTotalSubsets += newSubsets; +#endif + oldSubsets = newSubsets; + } + result = ddShuffle(table, bestOrder, lower, upper); + if (result == 0) goto cuddExactOutOfMem; +#ifdef DD_STATS +#ifdef DD_VERBOSE + (void) fprintf(table->out,"\n"); +#endif + (void) fprintf(table->out,"#:S_EXACT %8d: total subsets\n", + ddTotalSubsets); + (void) fprintf(table->out,"#:H_EXACT %8d: total shuffles", + ddTotalShuffles); +#endif + + freeMatrix(newOrder); + freeMatrix(oldOrder); + FREE(bestOrder); + FREE(oldCost); + FREE(newCost); + FREE(symmInfo); + FREE(mask); + return(1); + +cuddExactOutOfMem: + + if (newOrder != NULL) freeMatrix(newOrder); + if (oldOrder != NULL) freeMatrix(oldOrder); + if (bestOrder != NULL) FREE(bestOrder); + if (oldCost != NULL) FREE(oldCost); + if (newCost != NULL) FREE(newCost); + if (symmInfo != NULL) FREE(symmInfo); + if (mask != NULL) FREE(mask); + table->errorCode = CUDD_MEMORY_OUT; + return(0); + +} /* end of cuddExact */ + + +/**Function******************************************************************** + + Synopsis [Returns the maximum value of (n choose k) for a given n.] + + Description [Computes the maximum value of (n choose k) for a given + n. The maximum value occurs for k = n/2 when n is even, or k = + (n-1)/2 when n is odd. The algorithm used in this procedure avoids + intermediate overflow problems. It is based on the identity +
          +    binomial(n,k) = n/k * binomial(n-1,k-1).
          +  
          + Returns the computed value if successful; -1 if out of range.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +getMaxBinomial( + int n) +{ + double i, j, result; + + if (n < 0 || n > 33) return(-1); /* error */ + if (n < 2) return(1); + + for (result = (double)((n+3)/2), i = result+1, j=2; i <= n; i++, j++) { + result *= i; + result /= j; + } + + return((int)result); + +} /* end of getMaxBinomial */ + + +#if 0 +/**Function******************************************************************** + + Synopsis [Returns the gcd of two integers.] + + Description [Returns the gcd of two integers. Uses the binary GCD + algorithm described in Cormen, Leiserson, and Rivest.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +gcd( + int x, + int y) +{ + int a; + int b; + int lsbMask; + + /* GCD(n,0) = n. */ + if (x == 0) return(y); + if (y == 0) return(x); + + a = x; b = y; lsbMask = 1; + + /* Here both a and b are != 0. The iteration maintains this invariant. + ** Hence, we only need to check for when they become equal. + */ + while (a != b) { + if (a & lsbMask) { + if (b & lsbMask) { /* both odd */ + if (a < b) { + b = (b - a) >> 1; + } else { + a = (a - b) >> 1; + } + } else { /* a odd, b even */ + b >>= 1; + } + } else { + if (b & lsbMask) { /* a even, b odd */ + a >>= 1; + } else { /* both even */ + lsbMask <<= 1; + } + } + } + + return(a); + +} /* end of gcd */ +#endif + + +/**Function******************************************************************** + + Synopsis [Allocates a two-dimensional matrix of ints.] + + Description [Allocates a two-dimensional matrix of ints. + Returns the pointer to the matrix if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [freeMatrix] + +******************************************************************************/ +static DdHalfWord ** +getMatrix( + int rows /* number of rows */, + int cols /* number of columns */) +{ + DdHalfWord **matrix; + int i; + + if (cols*rows == 0) return(NULL); + matrix = ALLOC(DdHalfWord *, rows); + if (matrix == NULL) return(NULL); + matrix[0] = ALLOC(DdHalfWord, cols*rows); + if (matrix[0] == NULL) { + FREE(matrix); + return(NULL); + } + for (i = 1; i < rows; i++) { + matrix[i] = matrix[i-1] + cols; + } + return(matrix); + +} /* end of getMatrix */ + + +/**Function******************************************************************** + + Synopsis [Frees a two-dimensional matrix allocated by getMatrix.] + + Description [] + + SideEffects [None] + + SeeAlso [getMatrix] + +******************************************************************************/ +static void +freeMatrix( + DdHalfWord ** matrix) +{ + FREE(matrix[0]); + FREE(matrix); + return; + +} /* end of freeMatrix */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of nodes at one level of a unique table.] + + Description [Returns the number of nodes at one level of a unique table. + The projection function, if isolated, is not counted.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +getLevelKeys( + DdManager * table, + int l) +{ + int isolated; + int x; /* x is an index */ + + x = table->invperm[l]; + isolated = table->vars[x]->ref == 1; + + return(table->subtables[l].keys - isolated); + +} /* end of getLevelKeys */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables according to a given permutation.] + + Description [Reorders variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. ddShuffle assumes that no + dead nodes are present and that the interaction matrix is properly + initialized. The reordering is achieved by a series of upward sifts. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddShuffle( + DdManager * table, + DdHalfWord * permutation, + int lower, + int upper) +{ + DdHalfWord index; + int level; + int position; +#if 0 + int numvars; +#endif + int result; +#ifdef DD_STATS + unsigned long localTime; + int initialSize; +#ifdef DD_VERBOSE + int finalSize; +#endif + int previousSize; +#endif + +#ifdef DD_STATS + localTime = util_cpu_time(); + initialSize = table->keys - table->isolated; +#endif + +#if 0 + numvars = table->size; + + (void) fprintf(table->out,"%d:", ddTotalShuffles); + for (level = 0; level < numvars; level++) { + (void) fprintf(table->out," %d", table->invperm[level]); + } + (void) fprintf(table->out,"\n"); +#endif + + for (level = 0; level <= upper - lower; level++) { + index = permutation[level]; + position = table->perm[index]; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSiftUp(table,position,level+lower); + if (!result) return(0); + } + +#ifdef DD_STATS + ddTotalShuffles++; +#ifdef DD_VERBOSE + finalSize = table->keys - table->isolated; + if (finalSize < initialSize) { + (void) fprintf(table->out,"-"); + } else if (finalSize > initialSize) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + if ((ddTotalShuffles & 63) == 0) (void) fprintf(table->out,"\n"); + fflush(table->out); +#endif +#endif + + return(1); + +} /* end of ddShuffle */ + + +/**Function******************************************************************** + + Synopsis [Moves one variable up.] + + Description [Takes a variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddSiftUp( + DdManager * table, + int x, + int xLow) +{ + int y; + int size; + + y = cuddNextLow(table,x); + while (y >= xLow) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); + } + return(1); + +} /* end of ddSiftUp */ + + +/**Function******************************************************************** + + Synopsis [Updates the upper bound and saves the best order seen so far.] + + Description [Updates the upper bound and saves the best order seen so far. + Returns the current value of the upper bound.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +updateUB( + DdManager * table, + int oldBound, + DdHalfWord * bestOrder, + int lower, + int upper) +{ + int i; + int newBound = table->keys - table->isolated; + + if (newBound < oldBound) { +#ifdef DD_STATS + (void) fprintf(table->out,"New upper bound = %d\n", newBound); + fflush(table->out); +#endif + for (i = lower; i <= upper; i++) + bestOrder[i-lower] = (DdHalfWord) table->invperm[i]; + return(newBound); + } else { + return(oldBound); + } + +} /* end of updateUB */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of roots.] + + Description [Counts the number of roots at the levels between lower and + upper. The computation is based on breadth-first search. + A node is a root if it is not reachable from any previously visited node. + (All the nodes at level lower are therefore considered roots.) + The visited flag uses the LSB of the next pointer. Returns the root + count. The roots that are constant nodes are always ignored.] + + SideEffects [None] + + SeeAlso [ddClearGlobal] + +******************************************************************************/ +static int +ddCountRoots( + DdManager * table, + int lower, + int upper) +{ + int i,j; + DdNode *f; + DdNodePtr *nodelist; + DdNode *sentinel = &(table->sentinel); + int slots; + int roots = 0; + int maxlevel = lower; + + for (i = lower; i <= upper; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + /* A node is a root of the DAG if it cannot be + ** reached by nodes above it. If a node was never + ** reached during the previous depth-first searches, + ** then it is a root, and we start a new depth-first + ** search from it. + */ + if (!Cudd_IsComplement(f->next)) { + if (f != table->vars[f->index]) { + roots++; + } + } + if (!Cudd_IsConstant(cuddT(f))) { + cuddT(f)->next = Cudd_Complement(cuddT(f)->next); + if (table->perm[cuddT(f)->index] > maxlevel) + maxlevel = table->perm[cuddT(f)->index]; + } + if (!Cudd_IsConstant(cuddE(f))) { + Cudd_Regular(cuddE(f))->next = + Cudd_Complement(Cudd_Regular(cuddE(f))->next); + if (table->perm[Cudd_Regular(cuddE(f))->index] > maxlevel) + maxlevel = table->perm[Cudd_Regular(cuddE(f))->index]; + } + f = Cudd_Regular(f->next); + } + } + } + ddClearGlobal(table, lower, maxlevel); + + return(roots); + +} /* end of ddCountRoots */ + + +/**Function******************************************************************** + + Synopsis [Scans the DD and clears the LSB of the next pointers.] + + Description [Scans the DD and clears the LSB of the next pointers. + The LSB of the next pointers are used as markers to tell whether a + node was reached. Once the roots are counted, these flags are + reset.] + + SideEffects [None] + + SeeAlso [ddCountRoots] + +******************************************************************************/ +static void +ddClearGlobal( + DdManager * table, + int lower, + int maxlevel) +{ + int i,j; + DdNode *f; + DdNodePtr *nodelist; + DdNode *sentinel = &(table->sentinel); + int slots; + + for (i = lower; i <= maxlevel; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + f->next = Cudd_Regular(f->next); + f = f->next; + } + } + } + +} /* end of ddClearGlobal */ + + +/**Function******************************************************************** + + Synopsis [Computes a lower bound on the size of a BDD.] + + Description [Computes a lower bound on the size of a BDD from the + following factors: +
            +
          • size of the lower part of it; +
          • size of the part of the upper part not subjected to reordering; +
          • number of roots in the part of the BDD subjected to reordering; +
          • variable in the support of the roots in the upper part of the + BDD subjected to reordering. +
              ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +computeLB( + DdManager * table /* manager */, + DdHalfWord * order /* optimal order for the subset */, + int roots /* roots between lower and upper */, + int cost /* minimum cost for the subset */, + int lower /* lower level to be reordered */, + int upper /* upper level to be reordered */, + int level /* offset for the current top bottom var */ + ) +{ + int i; + int lb = cost; + int lb1 = 0; + int lb2; + int support; + DdHalfWord ref; + + /* The levels not involved in reordering are not going to change. + ** Add their sizes to the lower bound. + */ + for (i = 0; i < lower; i++) { + lb += getLevelKeys(table,i); + } + /* If a variable is in the support, then there is going + ** to be at least one node labeled by that variable. + */ + for (i = lower; i <= lower+level; i++) { + support = table->subtables[i].keys > 1 || + table->vars[order[i-lower]]->ref > 1; + lb1 += support; + } + + /* Estimate the number of nodes required to connect the roots to + ** the nodes in the bottom part. */ + if (lower+level+1 < table->size) { + if (lower+level < upper) + ref = table->vars[order[level+1]]->ref; + else + ref = table->vars[table->invperm[upper+1]]->ref; + lb2 = table->subtables[lower+level+1].keys - + (ref > (DdHalfWord) 1) - roots; + } else { + lb2 = 0; + } + + lb += lb1 > lb2 ? lb1 : lb2; + + return(lb); + +} /* end of computeLB */ + + +/**Function******************************************************************** + + Synopsis [Updates entry for a subset.] + + Description [Updates entry for a subset. Finds the subset, if it exists. + If the new order for the subset has lower cost, or if the subset did not + exist, it stores the new order and cost. Returns the number of subsets + currently in the table.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +updateEntry( + DdManager * table, + DdHalfWord * order, + int level, + int cost, + DdHalfWord ** orders, + int * costs, + int subsets, + char * mask, + int lower, + int upper) +{ + int i, j; + int size = upper - lower + 1; + + /* Build a mask that says what variables are in this subset. */ + for (i = lower; i <= upper; i++) + mask[table->invperm[i]] = 0; + for (i = level; i < size; i++) + mask[order[i]] = 1; + + /* Check each subset until a match is found or all subsets are examined. */ + for (i = 0; i < subsets; i++) { + DdHalfWord *subset = orders[i]; + for (j = level; j < size; j++) { + if (mask[subset[j]] == 0) + break; + } + if (j == size) /* no mismatches: success */ + break; + } + if (i == subsets || cost < costs[i]) { /* add or replace */ + for (j = 0; j < size; j++) + orders[i][j] = order[j]; + costs[i] = cost; + subsets += (i == subsets); + } + return(subsets); + +} /* end of updateEntry */ + + +/**Function******************************************************************** + + Synopsis [Pushes a variable in the order down to position "level."] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +pushDown( + DdHalfWord * order, + int j, + int level) +{ + int i; + DdHalfWord tmp; + + tmp = order[j]; + for (i = j; i < level; i++) { + order[i] = order[i+1]; + } + order[level] = tmp; + return; + +} /* end of pushDown */ + + +/**Function******************************************************************** + + Synopsis [Gathers symmetry information.] + + Description [Translates the symmetry information stored in the next + field of each subtable from level to indices. This procedure is called + immediately after symmetric sifting, so that the next fields are correct. + By translating this informaton in terms of indices, we make it independent + of subsequent reorderings. The format used is that of the next fields: + a circular list where each variable points to the next variable in the + same symmetry group. Only the entries between lower and upper are + considered. The procedure returns a pointer to an array + holding the symmetry information if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [checkSymmInfo] + +******************************************************************************/ +static DdHalfWord * +initSymmInfo( + DdManager * table, + int lower, + int upper) +{ + int level, index, next, nextindex; + DdHalfWord *symmInfo; + + symmInfo = ALLOC(DdHalfWord, table->size); + if (symmInfo == NULL) return(NULL); + + for (level = lower; level <= upper; level++) { + index = table->invperm[level]; + next = table->subtables[level].next; + nextindex = table->invperm[next]; + symmInfo[index] = nextindex; + } + return(symmInfo); + +} /* end of initSymmInfo */ + + +/**Function******************************************************************** + + Synopsis [Check symmetry condition.] + + Description [Returns 1 if a variable is the one with the highest index + among those belonging to a symmetry group that are in the top part of + the BDD. The top part is given by level.] + + SideEffects [None] + + SeeAlso [initSymmInfo] + +******************************************************************************/ +static int +checkSymmInfo( + DdManager * table, + DdHalfWord * symmInfo, + int index, + int level) +{ + int i; + + i = symmInfo[index]; + while (i != index) { + if (index < i && table->perm[i] <= level) + return(0); + i = symmInfo[i]; + } + return(1); + +} /* end of checkSymmInfo */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddExport.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddExport.c new file mode 100644 index 000000000..3d8da77ac --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddExport.c @@ -0,0 +1,1389 @@ +/**CFile*********************************************************************** + + FileName [cuddExport.c] + + PackageName [cudd] + + Synopsis [Export functions.] + + Description [External procedures included in this module: +
                +
              • Cudd_DumpBlif() +
              • Cudd_DumpBlifBody() +
              • Cudd_DumpDot() +
              • Cudd_DumpDaVinci() +
              • Cudd_DumpDDcal() +
              • Cudd_DumpFactoredForm() +
              + Internal procedures included in this module: +
                +
              + Static procedures included in this module: +
                +
              • ddDoDumpBlif() +
              • ddDoDumpDaVinci() +
              • ddDoDumpDDcal() +
              • ddDoDumpFactoredForm() +
              ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddExport.c,v 1.23 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddDoDumpBlif (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, int mv); +static int ddDoDumpDaVinci (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, ptruint mask); +static int ddDoDumpDDcal (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, ptruint mask); +static int ddDoDumpFactoredForm (DdManager *dd, DdNode *f, FILE *fp, char **names); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Writes a blif file representing the argument BDDs.] + + Description [Writes a blif file representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). Cudd_DumpBlif does not close the file: This is the + caller responsibility. Cudd_DumpBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for onames.] + + SideEffects [None] + + SeeAlso [Cudd_DumpBlifBody Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal + Cudd_DumpDaVinci Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpBlif( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + char * mname /* model name (or NULL) */, + FILE * fp /* pointer to the dump file */, + int mv /* 0: blif, 1: blif-MV */) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; + int retval; + int i; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int,nvars); + if (sorted == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; + } + for (i = 0; i < nvars; i++) sorted[i] = 0; + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(dd,f,n); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + support = NULL; /* so that we do not try to free it in case of failure */ + + /* Write the header (.model .inputs .outputs). */ + if (mname == NULL) { + retval = fprintf(fp,".model DD\n.inputs"); + } else { + retval = fprintf(fp,".model %s\n.inputs",mname); + } + if (retval == EOF) { + FREE(sorted); + return(0); + } + + /* Write the input list by scanning the support array. */ + for (i = 0; i < nvars; i++) { + if (sorted[i]) { + if (inames == NULL) { + retval = fprintf(fp," %d", i); + } else { + retval = fprintf(fp," %s", inames[i]); + } + if (retval == EOF) goto failure; + } + } + FREE(sorted); + sorted = NULL; + + /* Write the .output line. */ + retval = fprintf(fp,"\n.outputs"); + if (retval == EOF) goto failure; + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp," f%d", i); + } else { + retval = fprintf(fp," %s", onames[i]); + } + if (retval == EOF) goto failure; + } + retval = fprintf(fp,"\n"); + if (retval == EOF) goto failure; + + retval = Cudd_DumpBlifBody(dd, n, f, inames, onames, fp, mv); + if (retval == 0) goto failure; + + /* Write trailer and return. */ + retval = fprintf(fp,".end\n"); + if (retval == EOF) goto failure; + + return(1); + +failure: + if (sorted != NULL) FREE(sorted); + if (support != NULL) Cudd_RecursiveDeref(dd,support); + return(0); + +} /* end of Cudd_DumpBlif */ + + +/**Function******************************************************************** + + Synopsis [Writes a blif body representing the argument BDDs.] + + Description [Writes a blif body representing the argument BDDs as a + network of multiplexers. No header (.model, .inputs, and .outputs) and + footer (.end) are produced by this function. One multiplexer is written + for each BDD node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). Cudd_DumpBlifBody does not close the file: This is the + caller responsibility. Cudd_DumpBlifBody uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for onames. This function prints out only + .names part.] + + SideEffects [None] + + SeeAlso [Cudd_DumpBlif Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal + Cudd_DumpDaVinci Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpBlifBody( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */, + int mv /* 0: blif, 1: blif-MV */) +{ + st_table *visited = NULL; + int retval; + int i; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + retval = ddDoDumpBlif(dd,Cudd_Regular(f[i]),fp,visited,inames,mv); + if (retval == 0) goto failure; + } + + /* To account for the possible complement on the root, + ** we put either a buffer or an inverter at the output of + ** the multiplexer representing the top node. + */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp, +#if SIZEOF_VOID_P == 8 + ".names %lx f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); +#else + ".names %x f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); +#endif + } else { + retval = fprintf(fp, +#if SIZEOF_VOID_P == 8 + ".names %lx %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]); +#else + ".names %x %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]); +#endif + } + if (retval == EOF) goto failure; + if (Cudd_IsComplement(f[i])) { + retval = fprintf(fp,"%s0 1\n", mv ? ".def 0\n" : ""); + } else { + retval = fprintf(fp,"%s1 1\n", mv ? ".def 0\n" : ""); + } + if (retval == EOF) goto failure; + } + + st_free_table(visited); + return(1); + +failure: + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_DumpBlifBody */ + + +/**Function******************************************************************** + + Synopsis [Writes a dot file representing the argument DDs.] + + Description [Writes a file representing the argument DDs in a format + suitable for the graph drawing program dot. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, + file system full). + Cudd_DumpDot does not close the file: This is the caller + responsibility. Cudd_DumpDot uses a minimal unique subset of the + hexadecimal address of a node as name for it. + If the argument inames is non-null, it is assumed to hold the pointers + to the names of the inputs. Similarly for onames. + Cudd_DumpDot uses the following convention to draw arcs: +
                +
              • solid line: THEN arcs; +
              • dotted line: complement arcs; +
              • dashed line: regular ELSE arcs. +
              + The dot options are chosen so that the drawing fits on a letter-size + sheet. + ] + + SideEffects [None] + + SeeAlso [Cudd_DumpBlif Cudd_PrintDebug Cudd_DumpDDcal + Cudd_DumpDaVinci Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpDot( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; + st_table *visited = NULL; + st_generator *gen = NULL; + int retval; + int i, j; + int slots; + DdNodePtr *nodelist; + long refAddr, diff, mask; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int,nvars); + if (sorted == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; + } + for (i = 0; i < nvars; i++) sorted[i] = 0; + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(dd,f,n); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + support = NULL; /* so that we do not try to free it in case of failure */ + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Collect all the nodes of this DD in the symbol table. */ + for (i = 0; i < n; i++) { + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; + } + + /* Find how many most significant hex digits are identical + ** in the addresses of all the nodes. Build a mask based + ** on this knowledge, so that digits that carry no information + ** will not be printed. This is done in two steps. + ** 1. We scan the symbol table to find the bits that differ + ** in at least 2 addresses. + ** 2. We choose one of the possible masks. There are 8 possible + ** masks for 32-bit integer, and 16 possible masks for 64-bit + ** integers. + */ + + /* Find the bits that are different. */ + refAddr = (long) Cudd_Regular(f[0]); + diff = 0; + gen = st_init_gen(visited); + if (gen == NULL) goto failure; + while (st_gen(gen, &scan, NULL)) { + diff |= refAddr ^ (long) scan; + } + st_free_gen(gen); gen = NULL; + + /* Choose the mask. */ + for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; + } + + /* Write the header and the global attributes. */ + retval = fprintf(fp,"digraph \"DD\" {\n"); + if (retval == EOF) return(0); + retval = fprintf(fp, + "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); + if (retval == EOF) return(0); + + /* Write the input name subgraph by scanning the support array. */ + retval = fprintf(fp,"{ node [shape = plaintext];\n"); + if (retval == EOF) goto failure; + retval = fprintf(fp," edge [style = invis];\n"); + if (retval == EOF) goto failure; + /* We use a name ("CONST NODES") with an embedded blank, because + ** it is unlikely to appear as an input name. + */ + retval = fprintf(fp," \"CONST NODES\" [style = invis];\n"); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if (sorted[dd->invperm[i]]) { + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"\" %d \" -> ", dd->invperm[i]); + } else { + retval = fprintf(fp,"\" %s \" -> ", inames[dd->invperm[i]]); + } + if (retval == EOF) goto failure; + } + } + retval = fprintf(fp,"\"CONST NODES\"; \n}\n"); + if (retval == EOF) goto failure; + + /* Write the output node subgraph. */ + retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); + if (retval == EOF) goto failure; + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + if (i == n - 1) { + retval = fprintf(fp,"; }\n"); + } else { + retval = fprintf(fp," -> "); + } + if (retval == EOF) goto failure; + } + + /* Write rank info: All nodes with the same index have the same rank. */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invperm[i]]) { + retval = fprintf(fp,"{ rank = same; "); + if (retval == EOF) goto failure; + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"\" %d \";\n", dd->invperm[i]); + } else { + retval = fprintf(fp,"\" %s \";\n", inames[dd->invperm[i]]); + } + if (retval == EOF) goto failure; + nodelist = dd->subtables[i].nodelist; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; + } + } + + /* All constants have the same rank. */ + retval = fprintf(fp, + "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); + if (retval == EOF) goto failure; + nodelist = dd->constants.nodelist; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", + (void *) ((mask & (ptrint) scan) / sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + retval = fprintf(fp,"}\n}\n"); + if (retval == EOF) goto failure; + + /* Write edge info. */ + /* Edges from the output nodes. */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + /* Account for the possible complement on the root. */ + if (Cudd_IsComplement(f[i])) { + retval = fprintf(fp," -> \"%p\" [style = dotted];\n", + (void *) ((mask & (ptrint) f[i]) / sizeof(DdNode))); + } else { + retval = fprintf(fp," -> \"%p\" [style = solid];\n", + (void *) ((mask & (ptrint) f[i]) / sizeof(DdNode))); + } + if (retval == EOF) goto failure; + } + + /* Edges from internal nodes. */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invperm[i]]) { + nodelist = dd->subtables[i].nodelist; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp, + "\"%p\" -> \"%p\";\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddT(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + if (Cudd_IsComplement(cuddE(scan))) { + retval = fprintf(fp, + "\"%p\" -> \"%p\" [style = dotted];\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddE(scan)) / + sizeof(DdNode))); + } else { + retval = fprintf(fp, + "\"%p\" -> \"%p\" [style = dashed];\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddE(scan)) / + sizeof(DdNode))); + } + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + } + } + + /* Write constant labels. */ + nodelist = dd->constants.nodelist; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n", + (void *) ((mask & (ptrint) scan) / sizeof(DdNode)), + cuddV(scan)); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + + /* Write trailer and return. */ + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; + + st_free_table(visited); + FREE(sorted); + return(1); + +failure: + if (sorted != NULL) FREE(sorted); + if (support != NULL) Cudd_RecursiveDeref(dd,support); + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_DumpDot */ + + +/**Function******************************************************************** + + Synopsis [Writes a daVinci file representing the argument BDDs.] + + Description [Writes a daVinci file representing the argument BDDs. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or + file system full). Cudd_DumpDaVinci does not close the file: This + is the caller responsibility. Cudd_DumpDaVinci uses a minimal unique + subset of the hexadecimal address of a node as name for it. If the + argument inames is non-null, it is assumed to hold the pointers to + the names of the inputs. Similarly for onames.] + + SideEffects [None] + + SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDDcal + Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpDaVinci( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + DdNode *support = NULL; + DdNode *scan; + st_table *visited = NULL; + int retval; + int i; + st_generator *gen; + ptruint refAddr, diff, mask; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Collect all the nodes of this DD in the symbol table. */ + for (i = 0; i < n; i++) { + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; + } + + /* Find how many most significant hex digits are identical + ** in the addresses of all the nodes. Build a mask based + ** on this knowledge, so that digits that carry no information + ** will not be printed. This is done in two steps. + ** 1. We scan the symbol table to find the bits that differ + ** in at least 2 addresses. + ** 2. We choose one of the possible masks. There are 8 possible + ** masks for 32-bit integer, and 16 possible masks for 64-bit + ** integers. + */ + + /* Find the bits that are different. */ + refAddr = (ptruint) Cudd_Regular(f[0]); + diff = 0; + gen = st_init_gen(visited); + while (st_gen(gen, &scan, NULL)) { + diff |= refAddr ^ (ptruint) scan; + } + st_free_gen(gen); + + /* Choose the mask. */ + for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; + } + st_free_table(visited); + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + retval = fprintf(fp, "["); + if (retval == EOF) goto failure; + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp, + "l(\"f%d\",n(\"root\",[a(\"OBJECT\",\"f%d\")],", + i,i); + } else { + retval = fprintf(fp, + "l(\"%s\",n(\"root\",[a(\"OBJECT\",\"%s\")],", + onames[i], onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp, "[e(\"edge\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],", + Cudd_IsComplement(f[i]) ? "red" : "blue"); + if (retval == EOF) goto failure; + retval = ddDoDumpDaVinci(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); + if (retval == 0) goto failure; + retval = fprintf(fp, ")]))%s", i == n-1 ? "" : ","); + if (retval == EOF) goto failure; + } + + /* Write trailer and return. */ + retval = fprintf(fp, "]\n"); + if (retval == EOF) goto failure; + + st_free_table(visited); + return(1); + +failure: + if (support != NULL) Cudd_RecursiveDeref(dd,support); + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_DumpDaVinci */ + + +/**Function******************************************************************** + + Synopsis [Writes a DDcal file representing the argument BDDs.] + + Description [Writes a DDcal file representing the argument BDDs. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or + file system full). Cudd_DumpDDcal does not close the file: This + is the caller responsibility. Cudd_DumpDDcal uses a minimal unique + subset of the hexadecimal address of a node as name for it. If the + argument inames is non-null, it is assumed to hold the pointers to + the names of the inputs. Similarly for onames.] + + SideEffects [None] + + SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci + Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpDDcal( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; + st_table *visited = NULL; + int retval; + int i; + st_generator *gen; + ptruint refAddr, diff, mask; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Collect all the nodes of this DD in the symbol table. */ + for (i = 0; i < n; i++) { + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; + } + + /* Find how many most significant hex digits are identical + ** in the addresses of all the nodes. Build a mask based + ** on this knowledge, so that digits that carry no information + ** will not be printed. This is done in two steps. + ** 1. We scan the symbol table to find the bits that differ + ** in at least 2 addresses. + ** 2. We choose one of the possible masks. There are 8 possible + ** masks for 32-bit integer, and 16 possible masks for 64-bit + ** integers. + */ + + /* Find the bits that are different. */ + refAddr = (ptruint) Cudd_Regular(f[0]); + diff = 0; + gen = st_init_gen(visited); + while (st_gen(gen, &scan, NULL)) { + diff |= refAddr ^ (ptruint) scan; + } + st_free_gen(gen); + + /* Choose the mask. */ + for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; + } + st_free_table(visited); + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int,nvars); + if (sorted == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; + } + for (i = 0; i < nvars; i++) sorted[i] = 0; + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(dd,f,n); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + support = NULL; /* so that we do not try to free it in case of failure */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invperm[i]]) { + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"v%d", dd->invperm[i]); + } else { + retval = fprintf(fp,"%s", inames[dd->invperm[i]]); + } + if (retval == EOF) goto failure; + } + retval = fprintf(fp,"%s", i == nvars - 1 ? "\n" : " * "); + if (retval == EOF) goto failure; + } + FREE(sorted); + sorted = NULL; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + retval = ddDoDumpDDcal(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); + if (retval == 0) goto failure; + if (onames == NULL) { + retval = fprintf(fp, "f%d = ", i); + } else { + retval = fprintf(fp, "%s = ", onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp, "n%p%s\n", + (void *) (((ptruint) f[i] & mask) / + (ptruint) sizeof(DdNode)), + Cudd_IsComplement(f[i]) ? "'" : ""); + if (retval == EOF) goto failure; + } + + /* Write trailer and return. */ + retval = fprintf(fp, "["); + if (retval == EOF) goto failure; + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp, "f%d", i); + } else { + retval = fprintf(fp, "%s", onames[i]); + } + retval = fprintf(fp, "%s", i == n-1 ? "" : " "); + if (retval == EOF) goto failure; + } + retval = fprintf(fp, "]\n"); + if (retval == EOF) goto failure; + + st_free_table(visited); + return(1); + +failure: + if (sorted != NULL) FREE(sorted); + if (support != NULL) Cudd_RecursiveDeref(dd,support); + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_DumpDDcal */ + + +/**Function******************************************************************** + + Synopsis [Writes factored forms representing the argument BDDs.] + + Description [Writes factored forms representing the argument BDDs. + The format of the factored form is the one used in the genlib files + for technology mapping in sis. It returns 1 in case of success; 0 + otherwise (e.g., file system full). Cudd_DumpFactoredForm does not + close the file: This is the caller responsibility. Caution must be + exercised because a factored form may be exponentially larger than + the argument BDD. If the argument inames is non-null, it is assumed + to hold the pointers to the names of the inputs. Similarly for + onames.] + + SideEffects [None] + + SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci + Cudd_DumpDDcal] + +******************************************************************************/ +int +Cudd_DumpFactoredForm( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + int retval; + int i; + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp, "f%d = ", i); + } else { + retval = fprintf(fp, "%s = ", onames[i]); + } + if (retval == EOF) return(0); + if (f[i] == DD_ONE(dd)) { + retval = fprintf(fp, "CONST1"); + if (retval == EOF) return(0); + } else if (f[i] == Cudd_Not(DD_ONE(dd)) || f[i] == DD_ZERO(dd)) { + retval = fprintf(fp, "CONST0"); + if (retval == EOF) return(0); + } else { + retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? "!(" : ""); + if (retval == EOF) return(0); + retval = ddDoDumpFactoredForm(dd,Cudd_Regular(f[i]),fp,inames); + if (retval == 0) return(0); + retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? ")" : ""); + if (retval == EOF) return(0); + } + retval = fprintf(fp, "%s", i == n-1 ? "" : "\n"); + if (retval == EOF) return(0); + } + + return(1); + +} /* end of Cudd_DumpFactoredForm */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DumpBlif.] + + Description [Performs the recursive step of Cudd_DumpBlif. Traverses + the BDD f and writes a multiplexer-network description to the file + pointed by fp in blif format. f is assumed to be a regular pointer + and ddDoDumpBlif guarantees this assumption in the recursive calls.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddDoDumpBlif( + DdManager * dd, + DdNode * f, + FILE * fp, + st_table * visited, + char ** names, + int mv) +{ + DdNode *T, *E; + int retval; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + /* If already visited, nothing to do. */ + if (st_is_member(visited, (char *) f) == 1) + return(1); + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Mark node as visited. */ + if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + + /* Check for special case: If constant node, generate constant 1. */ + if (f == DD_ONE(dd)) { +#if SIZEOF_VOID_P == 8 + retval = fprintf(fp, ".names %lx\n1\n",(ptruint) f / (ptruint) sizeof(DdNode)); +#else + retval = fprintf(fp, ".names %x\n1\n",(ptruint) f / (ptruint) sizeof(DdNode)); +#endif + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + + /* Check whether this is an ADD. We deal with 0-1 ADDs, but not + ** with the general case. + */ + if (f == DD_ZERO(dd)) { +#if SIZEOF_VOID_P == 8 + retval = fprintf(fp, ".names %lx\n%s", + (ptruint) f / (ptruint) sizeof(DdNode), + mv ? "0\n" : ""); +#else + retval = fprintf(fp, ".names %x\n%s", + (ptruint) f / (ptruint) sizeof(DdNode), + mv ? "0\n" : ""); +#endif + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + if (cuddIsConstant(f)) + return(0); + + /* Recursive calls. */ + T = cuddT(f); + retval = ddDoDumpBlif(dd,T,fp,visited,names,mv); + if (retval != 1) return(retval); + E = Cudd_Regular(cuddE(f)); + retval = ddDoDumpBlif(dd,E,fp,visited,names,mv); + if (retval != 1) return(retval); + + /* Write multiplexer taking complement arc into account. */ + if (names != NULL) { + retval = fprintf(fp,".names %s", names[f->index]); + } else { +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp,".names %u", f->index); +#else + retval = fprintf(fp,".names %hu", f->index); +#endif + } + if (retval == EOF) + return(0); + +#if SIZEOF_VOID_P == 8 + if (mv) { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %lx %lx %lx\n.def 0\n1 1 - 1\n0 - 0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %lx %lx %lx\n.def 0\n1 1 - 1\n0 - 1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } + } else { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } + } +#else + if (mv) { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %x %x %x\n.def 0\n1 1 - 1\n0 - 0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %x %x %x\n.def 0\n1 1 - 1\n0 - 1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } + } else { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %x %x %x\n11- 1\n0-0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %x %x %x\n11- 1\n0-1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } + } +#endif + if (retval == EOF) { + return(0); + } else { + return(1); + } + +} /* end of ddDoDumpBlif */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DumpDaVinci.] + + Description [Performs the recursive step of Cudd_DumpDaVinci. Traverses + the BDD f and writes a term expression to the file + pointed by fp in daVinci format. f is assumed to be a regular pointer + and ddDoDumpDaVinci guarantees this assumption in the recursive calls.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddDoDumpDaVinci( + DdManager * dd, + DdNode * f, + FILE * fp, + st_table * visited, + char ** names, + ptruint mask) +{ + DdNode *T, *E; + int retval; + ptruint id; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + id = ((ptruint) f & mask) / sizeof(DdNode); + + /* If already visited, insert a reference. */ + if (st_is_member(visited, (char *) f) == 1) { + retval = fprintf(fp,"r(\"%p\")", (void *) id); + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Mark node as visited. */ + if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + + /* Check for special case: If constant node, generate constant 1. */ + if (Cudd_IsConstant(f)) { + retval = fprintf(fp, + "l(\"%p\",n(\"constant\",[a(\"OBJECT\",\"%g\")],[]))", + (void *) id, cuddV(f)); + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + + /* Recursive calls. */ + if (names != NULL) { + retval = fprintf(fp, + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%s\"),", + (void *) id, names[f->index]); + } else { + retval = fprintf(fp, +#if SIZEOF_VOID_P == 8 + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%u\"),", +#else + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%hu\"),", +#endif + (void *) id, f->index); + } + retval = fprintf(fp, "a(\"_GO\",\"ellipse\")],[e(\"then\",[a(\"EDGECOLOR\",\"blue\"),a(\"_DIR\",\"none\")],"); + if (retval == EOF) return(0); + T = cuddT(f); + retval = ddDoDumpDaVinci(dd,T,fp,visited,names,mask); + if (retval != 1) return(retval); + retval = fprintf(fp, "),e(\"else\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],", + Cudd_IsComplement(cuddE(f)) ? "red" : "green"); + if (retval == EOF) return(0); + E = Cudd_Regular(cuddE(f)); + retval = ddDoDumpDaVinci(dd,E,fp,visited,names,mask); + if (retval != 1) return(retval); + + retval = fprintf(fp,")]))"); + if (retval == EOF) { + return(0); + } else { + return(1); + } + +} /* end of ddDoDumpDaVinci */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DumpDDcal.] + + Description [Performs the recursive step of Cudd_DumpDDcal. Traverses + the BDD f and writes a line for each node to the file + pointed by fp in DDcal format. f is assumed to be a regular pointer + and ddDoDumpDDcal guarantees this assumption in the recursive calls.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddDoDumpDDcal( + DdManager * dd, + DdNode * f, + FILE * fp, + st_table * visited, + char ** names, + ptruint mask) +{ + DdNode *T, *E; + int retval; + ptruint id, idT, idE; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + id = ((ptruint) f & mask) / sizeof(DdNode); + + /* If already visited, do nothing. */ + if (st_is_member(visited, (char *) f) == 1) { + return(1); + } + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Mark node as visited. */ + if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + + /* Check for special case: If constant node, assign constant. */ + if (Cudd_IsConstant(f)) { + if (f != DD_ONE(dd) && f != DD_ZERO(dd)) + return(0); + retval = fprintf(fp, "n%p = %g\n", (void *) id, cuddV(f)); + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + + /* Recursive calls. */ + T = cuddT(f); + retval = ddDoDumpDDcal(dd,T,fp,visited,names,mask); + if (retval != 1) return(retval); + E = Cudd_Regular(cuddE(f)); + retval = ddDoDumpDDcal(dd,E,fp,visited,names,mask); + if (retval != 1) return(retval); + idT = ((ptruint) T & mask) / sizeof(DdNode); + idE = ((ptruint) E & mask) / sizeof(DdNode); + if (names != NULL) { + retval = fprintf(fp, "n%p = %s * n%p + %s' * n%p%s\n", + (void *) id, names[f->index], + (void *) idT, names[f->index], + (void *) idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); + } else { +#if SIZEOF_VOID_P == 8 + retval = fprintf(fp, "n%p = v%u * n%p + v%u' * n%p%s\n", +#else + retval = fprintf(fp, "n%p = v%hu * n%p + v%hu' * n%p%s\n", +#endif + (void *) id, f->index, + (void *) idT, f->index, + (void *) idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); + } + if (retval == EOF) { + return(0); + } else { + return(1); + } + +} /* end of ddDoDumpDDcal */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DumpFactoredForm.] + + Description [Performs the recursive step of + Cudd_DumpFactoredForm. Traverses the BDD f and writes a factored + form for each node to the file pointed by fp in terms of the + factored forms of the children. Constants are propagated, and + absorption is applied. f is assumed to be a regular pointer and + ddDoDumpFActoredForm guarantees this assumption in the recursive + calls.] + + SideEffects [None] + + SeeAlso [Cudd_DumpFactoredForm] + +******************************************************************************/ +static int +ddDoDumpFactoredForm( + DdManager * dd, + DdNode * f, + FILE * fp, + char ** names) +{ + DdNode *T, *E; + int retval; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); + assert(!Cudd_IsConstant(f)); +#endif + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Recursive calls. */ + T = cuddT(f); + E = cuddE(f); + if (T != DD_ZERO(dd)) { + if (E != DD_ONE(dd)) { + if (names != NULL) { + retval = fprintf(fp, "%s", names[f->index]); + } else { +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp, "x%u", f->index); +#else + retval = fprintf(fp, "x%hu", f->index); +#endif + } + if (retval == EOF) return(0); + } + if (T != DD_ONE(dd)) { + retval = fprintf(fp, "%s(", E != DD_ONE(dd) ? " * " : ""); + if (retval == EOF) return(0); + retval = ddDoDumpFactoredForm(dd,T,fp,names); + if (retval != 1) return(retval); + retval = fprintf(fp, ")"); + if (retval == EOF) return(0); + } + if (E == Cudd_Not(DD_ONE(dd)) || E == DD_ZERO(dd)) return(1); + retval = fprintf(fp, " + "); + if (retval == EOF) return(0); + } + E = Cudd_Regular(E); + if (T != DD_ONE(dd)) { + if (names != NULL) { + retval = fprintf(fp, "!%s", names[f->index]); + } else { +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp, "!x%u", f->index); +#else + retval = fprintf(fp, "!x%hu", f->index); +#endif + } + if (retval == EOF) return(0); + } + if (E != DD_ONE(dd)) { + retval = fprintf(fp, "%s%s(", T != DD_ONE(dd) ? " * " : "", + E != cuddE(f) ? "!" : ""); + if (retval == EOF) return(0); + retval = ddDoDumpFactoredForm(dd,E,fp,names); + if (retval != 1) return(retval); + retval = fprintf(fp, ")"); + if (retval == EOF) return(0); + } + return(1); + +} /* end of ddDoDumpFactoredForm */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddGenCof.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddGenCof.c new file mode 100644 index 000000000..e129aca44 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddGenCof.c @@ -0,0 +1,2178 @@ +/**CFile*********************************************************************** + + FileName [cuddGenCof.c] + + PackageName [cudd] + + Synopsis [Generalized cofactors for BDDs and ADDs.] + + Description [External procedures included in this module: +
                +
              • Cudd_bddConstrain() +
              • Cudd_bddRestrict() +
              • Cudd_bddNPAnd() +
              • Cudd_addConstrain() +
              • Cudd_bddConstrainDecomp() +
              • Cudd_addRestrict() +
              • Cudd_bddCharToVect() +
              • Cudd_bddLICompaction() +
              • Cudd_bddSqueeze() +
              • Cudd_bddMinimize() +
              • Cudd_SubsetCompress() +
              • Cudd_SupersetCompress() +
              + Internal procedures included in this module: +
                +
              • cuddBddConstrainRecur() +
              • cuddBddRestrictRecur() +
              • cuddBddNPAndRecur() +
              • cuddAddConstrainRecur() +
              • cuddAddRestrictRecur() +
              • cuddBddLICompaction() +
              + Static procedures included in this module: +
                +
              • cuddBddConstrainDecomp() +
              • cuddBddCharToVect() +
              • cuddBddLICMarkEdges() +
              • cuddBddLICBuildResult() +
              • MarkCacheHash() +
              • MarkCacheCompare() +
              • MarkCacheCleanUp() +
              • cuddBddSqueeze() +
              + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Codes for edge markings in Cudd_bddLICompaction. The codes are defined +** so that they can be bitwise ORed to implement the code priority scheme. +*/ +#define DD_LIC_DC 0 +#define DD_LIC_1 1 +#define DD_LIC_0 2 +#define DD_LIC_NL 3 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/* Key for the cache used in the edge marking phase. */ +typedef struct MarkCacheKey { + DdNode *f; + DdNode *c; +} MarkCacheKey; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddGenCof.c,v 1.40 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddBddConstrainDecomp (DdManager *dd, DdNode *f, DdNode **decomp); +static DdNode * cuddBddCharToVect (DdManager *dd, DdNode *f, DdNode *x); +static int cuddBddLICMarkEdges (DdManager *dd, DdNode *f, DdNode *c, st_table *table, st_table *cache); +static DdNode * cuddBddLICBuildResult (DdManager *dd, DdNode *f, st_table *cache, st_table *table); +static int MarkCacheHash (char *ptr, int modulus); +static int MarkCacheCompare (const char *ptr1, const char *ptr2); +static enum st_retval MarkCacheCleanUp (char *key, char *value, char *arg); +static DdNode * cuddBddSqueeze (DdManager *dd, DdNode *l, DdNode *u); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes f constrain c.] + + Description [Computes f constrain c (f @ c). + Uses a canonical form: (f' @ c) = (f @ c)'. (Note: this is not true + for c.) List of special cases: +
                +
              • f @ 0 = 0 +
              • f @ 1 = f +
              • 0 @ c = 0 +
              • 1 @ c = 1 +
              • f @ f = 1 +
              • f @ f'= 0 +
              + Returns a pointer to the result if successful; NULL otherwise. Note that if + F=(f1,...,fn) and reordering takes place while computing F @ c, then the + image restriction property (Img(F,c) = Img(F @ c)) is lost.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict Cudd_addConstrain] + +******************************************************************************/ +DdNode * +Cudd_bddConstrain( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddConstrainRecur(dd,f,c); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddConstrain */ + + +/**Function******************************************************************** + + Synopsis [BDD restrict according to Coudert and Madre's algorithm + (ICCAD90).] + + Description [BDD restrict according to Coudert and Madre's algorithm + (ICCAD90). Returns the restricted BDD if successful; otherwise NULL. + If application of restrict results in a BDD larger than the input + BDD, the input BDD is returned.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_addRestrict] + +******************************************************************************/ +DdNode * +Cudd_bddRestrict( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *suppF, *suppC, *commonSupport; + DdNode *cplus, *res; + int retval; + int sizeF, sizeRes; + + /* Check terminal cases here to avoid computing supports in trivial cases. + ** This also allows us notto check later for the case c == 0, in which + ** there is no common support. */ + if (c == Cudd_Not(DD_ONE(dd))) return(Cudd_Not(DD_ONE(dd))); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(DD_ONE(dd)); + if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd))); + + /* Check if supports intersect. */ + retval = Cudd_ClassifySupport(dd,f,c,&commonSupport,&suppF,&suppC); + if (retval == 0) { + return(NULL); + } + cuddRef(commonSupport); cuddRef(suppF); cuddRef(suppC); + Cudd_IterDerefBdd(dd,suppF); + + if (commonSupport == DD_ONE(dd)) { + Cudd_IterDerefBdd(dd,commonSupport); + Cudd_IterDerefBdd(dd,suppC); + return(f); + } + Cudd_IterDerefBdd(dd,commonSupport); + + /* Abstract from c the variables that do not appear in f. */ + cplus = Cudd_bddExistAbstract(dd, c, suppC); + if (cplus == NULL) { + Cudd_IterDerefBdd(dd,suppC); + return(NULL); + } + cuddRef(cplus); + Cudd_IterDerefBdd(dd,suppC); + + do { + dd->reordered = 0; + res = cuddBddRestrictRecur(dd, f, cplus); + } while (dd->reordered == 1); + if (res == NULL) { + Cudd_IterDerefBdd(dd,cplus); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd,cplus); + /* Make restric safe by returning the smaller of the input and the + ** result. */ + sizeF = Cudd_DagSize(f); + sizeRes = Cudd_DagSize(res); + if (sizeF <= sizeRes) { + Cudd_IterDerefBdd(dd, res); + return(f); + } else { + cuddDeref(res); + return(res); + } + +} /* end of Cudd_bddRestrict */ + + +/**Function******************************************************************** + + Synopsis [Computes f non-polluting-and g.] + + Description [Computes f non-polluting-and g. The non-polluting AND + of f and g is a hybrid of AND and Restrict. From Restrict, this + operation takes the idea of existentially quantifying the top + variable of the second operand if it does not appear in the first. + Therefore, the variables that appear in the result also appear in f. + For the rest, the function behaves like AND. Since the two operands + play different roles, non-polluting AND is not commutative. + + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_bddNPAnd( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddNPAndRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddNPAnd */ + + +/**Function******************************************************************** + + Synopsis [Computes f constrain c for ADDs.] + + Description [Computes f constrain c (f @ c), for f an ADD and c a 0-1 + ADD. List of special cases: +
                +
              • F @ 0 = 0 +
              • F @ 1 = F +
              • 0 @ c = 0 +
              • 1 @ c = 1 +
              • F @ F = 1 +
              + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain] + +******************************************************************************/ +DdNode * +Cudd_addConstrain( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddConstrainRecur(dd,f,c); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addConstrain */ + + +/**Function******************************************************************** + + Synopsis [BDD conjunctive decomposition as in McMillan's CAV96 paper.] + + Description [BDD conjunctive decomposition as in McMillan's CAV96 + paper. The decomposition is canonical only for a given variable + order. If canonicity is required, variable ordering must be disabled + after the decomposition has been computed. Returns an array with one + entry for each BDD variable in the manager if successful; otherwise + NULL. The components of the solution have their reference counts + already incremented (unlike the results of most other functions in + the package).] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_bddExistAbstract] + +******************************************************************************/ +DdNode ** +Cudd_bddConstrainDecomp( + DdManager * dd, + DdNode * f) +{ + DdNode **decomp; + int res; + int i; + + /* Create an initialize decomposition array. */ + decomp = ALLOC(DdNode *,dd->size); + if (decomp == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) { + decomp[i] = NULL; + } + do { + dd->reordered = 0; + /* Clean up the decomposition array in case reordering took place. */ + for (i = 0; i < dd->size; i++) { + if (decomp[i] != NULL) { + Cudd_IterDerefBdd(dd, decomp[i]); + decomp[i] = NULL; + } + } + res = cuddBddConstrainDecomp(dd,f,decomp); + } while (dd->reordered == 1); + if (res == 0) { + FREE(decomp); + return(NULL); + } + /* Missing components are constant ones. */ + for (i = 0; i < dd->size; i++) { + if (decomp[i] == NULL) { + decomp[i] = DD_ONE(dd); + cuddRef(decomp[i]); + } + } + return(decomp); + +} /* end of Cudd_bddConstrainDecomp */ + + +/**Function******************************************************************** + + Synopsis [ADD restrict according to Coudert and Madre's algorithm + (ICCAD90).] + + Description [ADD restrict according to Coudert and Madre's algorithm + (ICCAD90). Returns the restricted ADD if successful; otherwise NULL. + If application of restrict results in an ADD larger than the input + ADD, the input ADD is returned.] + + SideEffects [None] + + SeeAlso [Cudd_addConstrain Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_addRestrict( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *supp_f, *supp_c; + DdNode *res, *commonSupport; + int intersection; + int sizeF, sizeRes; + + /* Check if supports intersect. */ + supp_f = Cudd_Support(dd, f); + if (supp_f == NULL) { + return(NULL); + } + cuddRef(supp_f); + supp_c = Cudd_Support(dd, c); + if (supp_c == NULL) { + Cudd_RecursiveDeref(dd,supp_f); + return(NULL); + } + cuddRef(supp_c); + commonSupport = Cudd_bddLiteralSetIntersection(dd, supp_f, supp_c); + if (commonSupport == NULL) { + Cudd_RecursiveDeref(dd,supp_f); + Cudd_RecursiveDeref(dd,supp_c); + return(NULL); + } + cuddRef(commonSupport); + Cudd_RecursiveDeref(dd,supp_f); + Cudd_RecursiveDeref(dd,supp_c); + intersection = commonSupport != DD_ONE(dd); + Cudd_RecursiveDeref(dd,commonSupport); + + if (intersection) { + do { + dd->reordered = 0; + res = cuddAddRestrictRecur(dd, f, c); + } while (dd->reordered == 1); + sizeF = Cudd_DagSize(f); + sizeRes = Cudd_DagSize(res); + if (sizeF <= sizeRes) { + cuddRef(res); + Cudd_RecursiveDeref(dd, res); + return(f); + } else { + return(res); + } + } else { + return(f); + } + +} /* end of Cudd_addRestrict */ + + +/**Function******************************************************************** + + Synopsis [Computes a vector whose image equals a non-zero function.] + + Description [Computes a vector of BDDs whose image equals a non-zero + function. + The result depends on the variable order. The i-th component of the vector + depends only on the first i variables in the order. Each BDD in the vector + is not larger than the BDD of the given characteristic function. This + function is based on the description of char-to-vect in "Verification of + Sequential Machines Using Boolean Functional Vectors" by O. Coudert, C. + Berthet and J. C. Madre. + Returns a pointer to an array containing the result if successful; NULL + otherwise. The size of the array equals the number of variables in the + manager. The components of the solution have their reference counts + already incremented (unlike the results of most other functions in + the package).] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain] + +******************************************************************************/ +DdNode ** +Cudd_bddCharToVect( + DdManager * dd, + DdNode * f) +{ + int i, j; + DdNode **vect; + DdNode *res = NULL; + + if (f == Cudd_Not(DD_ONE(dd))) return(NULL); + + vect = ALLOC(DdNode *, dd->size); + if (vect == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + do { + dd->reordered = 0; + for (i = 0; i < dd->size; i++) { + res = cuddBddCharToVect(dd,f,dd->vars[dd->invperm[i]]); + if (res == NULL) { + /* Clean up the vector array in case reordering took place. */ + for (j = 0; j < i; j++) { + Cudd_IterDerefBdd(dd, vect[dd->invperm[j]]); + } + break; + } + cuddRef(res); + vect[dd->invperm[i]] = res; + } + } while (dd->reordered == 1); + if (res == NULL) { + FREE(vect); + return(NULL); + } + return(vect); + +} /* end of Cudd_bddCharToVect */ + + +/**Function******************************************************************** + + Synopsis [Performs safe minimization of a BDD.] + + Description [Performs safe minimization of a BDD. Given the BDD + f of a function to be minimized and a BDD + c representing the care set, Cudd_bddLICompaction + produces the BDD of a function that agrees with f + wherever c is 1. Safe minimization means that the size + of the result is guaranteed not to exceed the size of + f. This function is based on the DAC97 paper by Hong et + al.. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_bddLICompaction( + DdManager * dd /* manager */, + DdNode * f /* function to be minimized */, + DdNode * c /* constraint (care set) */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddLICompaction(dd,f,c); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddLICompaction */ + + +/**Function******************************************************************** + + Synopsis [Finds a small BDD in a function interval.] + + Description [Finds a small BDD in a function interval. Given BDDs + l and u, representing the lower bound and + upper bound of a function interval, Cudd_bddSqueeze produces the BDD + of a function within the interval with a small BDD. Returns a + pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction] + +******************************************************************************/ +DdNode * +Cudd_bddSqueeze( + DdManager * dd /* manager */, + DdNode * l /* lower bound */, + DdNode * u /* upper bound */) +{ + DdNode *res; + int sizeRes, sizeL, sizeU; + + do { + dd->reordered = 0; + res = cuddBddSqueeze(dd,l,u); + } while (dd->reordered == 1); + if (res == NULL) return(NULL); + /* We now compare the result with the bounds and return the smallest. + ** We first compare to u, so that in case l == 0 and u == 1, we return + ** 0 as in other minimization algorithms. */ + sizeRes = Cudd_DagSize(res); + sizeU = Cudd_DagSize(u); + if (sizeU <= sizeRes) { + cuddRef(res); + Cudd_IterDerefBdd(dd,res); + res = u; + sizeRes = sizeU; + } + sizeL = Cudd_DagSize(l); + if (sizeL <= sizeRes) { + cuddRef(res); + Cudd_IterDerefBdd(dd,res); + res = l; + sizeRes = sizeL; + } + return(res); + +} /* end of Cudd_bddSqueeze */ + + +/**Function******************************************************************** + + Synopsis [Finds a small BDD that agrees with f over + c.] + + Description [Finds a small BDD that agrees with f over + c. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction Cudd_bddSqueeze] + +******************************************************************************/ +DdNode * +Cudd_bddMinimize( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *cplus, *res; + + if (c == Cudd_Not(DD_ONE(dd))) return(c); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(DD_ONE(dd)); + if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd))); + + cplus = Cudd_RemapOverApprox(dd,c,0,0,1.0); + if (cplus == NULL) return(NULL); + cuddRef(cplus); + res = Cudd_bddLICompaction(dd,f,cplus); + if (res == NULL) { + Cudd_IterDerefBdd(dd,cplus); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd,cplus); + cuddDeref(res); + return(res); + +} /* end of Cudd_bddMinimize */ + + +/**Function******************************************************************** + + Synopsis [Find a dense subset of BDD f.] + + Description [Finds a dense subset of BDD f. Density is + the ratio of number of minterms to number of nodes. Uses several + techniques in series. It is more expensive than other subsetting + procedures, but often produces better results. See + Cudd_SubsetShortPaths for a description of the threshold and nvars + parameters. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_RemapUnderApprox Cudd_SubsetShortPaths + Cudd_SubsetHeavyBranch Cudd_bddSqueeze] + +******************************************************************************/ +DdNode * +Cudd_SubsetCompress( + DdManager * dd /* manager */, + DdNode * f /* BDD whose subset is sought */, + int nvars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the subset */) +{ + DdNode *res, *tmp1, *tmp2; + + tmp1 = Cudd_SubsetShortPaths(dd, f, nvars, threshold, 0); + if (tmp1 == NULL) return(NULL); + cuddRef(tmp1); + tmp2 = Cudd_RemapUnderApprox(dd,tmp1,nvars,0,0.95); + if (tmp2 == NULL) { + Cudd_IterDerefBdd(dd,tmp1); + return(NULL); + } + cuddRef(tmp2); + Cudd_IterDerefBdd(dd,tmp1); + res = Cudd_bddSqueeze(dd,tmp2,f); + if (res == NULL) { + Cudd_IterDerefBdd(dd,tmp2); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd,tmp2); + cuddDeref(res); + return(res); + +} /* end of Cudd_SubsetCompress */ + + +/**Function******************************************************************** + + Synopsis [Find a dense superset of BDD f.] + + Description [Finds a dense superset of BDD f. Density is + the ratio of number of minterms to number of nodes. Uses several + techniques in series. It is more expensive than other supersetting + procedures, but often produces better results. See + Cudd_SupersetShortPaths for a description of the threshold and nvars + parameters. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetCompress Cudd_SupersetRemap Cudd_SupersetShortPaths + Cudd_SupersetHeavyBranch Cudd_bddSqueeze] + +******************************************************************************/ +DdNode * +Cudd_SupersetCompress( + DdManager * dd /* manager */, + DdNode * f /* BDD whose superset is sought */, + int nvars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the superset */) +{ + DdNode *subset; + + subset = Cudd_SubsetCompress(dd, Cudd_Not(f),nvars,threshold); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_SupersetCompress */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddConstrain.] + + Description [Performs the recursive step of Cudd_bddConstrain. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain] + +******************************************************************************/ +DdNode * +cuddBddConstrainRecur( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r; + DdNode *one, *zero; + unsigned int topf, topc; + int index; + int comple = 0; + + statLine(dd); + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Trivial cases. */ + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + if (f == Cudd_Not(c)) return(zero); + + /* Make canonical to increase the utilization of the cache. */ + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + comple = 1; + } + /* Now f is a regular pointer to a non-constant node; c is also + ** non-constant, but may be complemented. + */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_bddConstrain, f, c); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + /* Recursive step. */ + topf = dd->perm[f->index]; + topc = dd->perm[Cudd_Regular(c)->index]; + if (topf <= topc) { + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + index = Cudd_Regular(c)->index; + Fv = Fnv = f; + } + if (topc <= topf) { + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } + } else { + Cv = Cnv = c; + } + + if (!Cudd_IsConstant(Cv)) { + t = cuddBddConstrainRecur(dd, Fv, Cv); + if (t == NULL) + return(NULL); + } else if (Cv == one) { + t = Fv; + } else { /* Cv == zero: return Fnv @ Cnv */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddBddConstrainRecur(dd, Fnv, Cnv); + if (r == NULL) + return(NULL); + } + return(Cudd_NotCond(r,comple)); + } + cuddRef(t); + + if (!Cudd_IsConstant(Cnv)) { + e = cuddBddConstrainRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } else if (Cnv == one) { + e = Fnv; + } else { /* Cnv == zero: return Fv @ Cv previously computed */ + cuddDeref(t); + return(Cudd_NotCond(t,comple)); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd, Cudd_bddConstrain, f, c, r); + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddConstrainRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddRestrict.] + + Description [Performs the recursive step of Cudd_bddRestrict. + Returns the restricted BDD if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +cuddBddRestrictRecur( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; + unsigned int topf, topc; + int index; + int comple = 0; + + statLine(dd); + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Trivial cases */ + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + if (f == Cudd_Not(c)) return(zero); + + /* Make canonical to increase the utilization of the cache. */ + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + comple = 1; + } + /* Now f is a regular pointer to a non-constant node; c is also + ** non-constant, but may be complemented. + */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_bddRestrict, f, c); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + topf = dd->perm[f->index]; + topc = dd->perm[Cudd_Regular(c)->index]; + + if (topc < topf) { /* abstract top variable from c */ + DdNode *d, *s1, *s2; + + /* Find complements of cofactors of c. */ + if (Cudd_IsComplement(c)) { + s1 = cuddT(Cudd_Regular(c)); + s2 = cuddE(Cudd_Regular(c)); + } else { + s1 = Cudd_Not(cuddT(c)); + s2 = Cudd_Not(cuddE(c)); + } + /* Take the OR by applying DeMorgan. */ + d = cuddBddAndRecur(dd, s1, s2); + if (d == NULL) return(NULL); + d = Cudd_Not(d); + cuddRef(d); + r = cuddBddRestrictRecur(dd, f, d); + if (r == NULL) { + Cudd_IterDerefBdd(dd, d); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, d); + cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r); + cuddDeref(r); + return(Cudd_NotCond(r,comple)); + } + + /* Recursive step. Here topf <= topc. */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + if (topc == topf) { + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } + } else { + Cv = Cnv = c; + } + + if (!Cudd_IsConstant(Cv)) { + t = cuddBddRestrictRecur(dd, Fv, Cv); + if (t == NULL) return(NULL); + } else if (Cv == one) { + t = Fv; + } else { /* Cv == zero: return(Fnv @ Cnv) */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddBddRestrictRecur(dd, Fnv, Cnv); + if (r == NULL) return(NULL); + } + return(Cudd_NotCond(r,comple)); + } + cuddRef(t); + + if (!Cudd_IsConstant(Cnv)) { + e = cuddBddRestrictRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } else if (Cnv == one) { + e = Fnv; + } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ + cuddDeref(t); + return(Cudd_NotCond(t,comple)); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r); + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddRestrictRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddAnd.] + + Description [Implements the recursive step of Cudd_bddNPAnd. + Returns a pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNPAnd] + +******************************************************************************/ +DdNode * +cuddBddNPAndRecur( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *r, *t, *e; + unsigned int topf, topg, index; + + statLine(manager); + one = DD_ONE(manager); + + /* Terminal cases. */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + if (F == G) { + if (f == g) return(one); + else return(Cudd_Not(one)); + } + if (G == one) { + if (g == one) return(f); + else return(g); + } + if (F == one) { + return(f); + } + + /* At this point f and g are not constant. */ + /* Check cache. */ + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup2(manager, Cudd_bddNPAnd, f, g); + if (r != NULL) return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + + if (topg < topf) { /* abstract top variable from g */ + DdNode *d; + + /* Find complements of cofactors of g. */ + if (Cudd_IsComplement(g)) { + gt = cuddT(G); + ge = cuddE(G); + } else { + gt = Cudd_Not(cuddT(g)); + ge = Cudd_Not(cuddE(g)); + } + /* Take the OR by applying DeMorgan. */ + d = cuddBddAndRecur(manager, gt, ge); + if (d == NULL) return(NULL); + d = Cudd_Not(d); + cuddRef(d); + r = cuddBddNPAndRecur(manager, f, d); + if (r == NULL) { + Cudd_IterDerefBdd(manager, d); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(manager, d); + cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r); + cuddDeref(r); + return(r); + } + + /* Compute cofactors. */ + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + + if (topg == topf) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + t = cuddBddAndRecur(manager, ft, gt); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddAndRecur(manager, fe, ge); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r); + return(r); + +} /* end of cuddBddNPAndRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addConstrain.] + + Description [Performs the recursive step of Cudd_addConstrain. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addConstrain] + +******************************************************************************/ +DdNode * +cuddAddConstrainRecur( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r; + DdNode *one, *zero; + unsigned int topf, topc; + int index; + + statLine(dd); + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + /* Trivial cases. */ + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + + /* Now f and c are non-constant. */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_addConstrain, f, c); + if (r != NULL) { + return(r); + } + + /* Recursive step. */ + topf = dd->perm[f->index]; + topc = dd->perm[c->index]; + if (topf <= topc) { + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + index = c->index; + Fv = Fnv = f; + } + if (topc <= topf) { + Cv = cuddT(c); Cnv = cuddE(c); + } else { + Cv = Cnv = c; + } + + if (!Cudd_IsConstant(Cv)) { + t = cuddAddConstrainRecur(dd, Fv, Cv); + if (t == NULL) + return(NULL); + } else if (Cv == one) { + t = Fv; + } else { /* Cv == zero: return Fnv @ Cnv */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddAddConstrainRecur(dd, Fnv, Cnv); + if (r == NULL) + return(NULL); + } + return(r); + } + cuddRef(t); + + if (!Cudd_IsConstant(Cnv)) { + e = cuddAddConstrainRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } else if (Cnv == one) { + e = Fnv; + } else { /* Cnv == zero: return Fv @ Cv previously computed */ + cuddDeref(t); + return(t); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd, Cudd_addConstrain, f, c, r); + return(r); + +} /* end of cuddAddConstrainRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addRestrict.] + + Description [Performs the recursive step of Cudd_addRestrict. + Returns the restricted ADD if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_addRestrict] + +******************************************************************************/ +DdNode * +cuddAddRestrictRecur( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; + unsigned int topf, topc; + int index; + + statLine(dd); + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + /* Trivial cases */ + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + + /* Now f and c are non-constant. */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_addRestrict, f, c); + if (r != NULL) { + return(r); + } + + topf = dd->perm[f->index]; + topc = dd->perm[c->index]; + + if (topc < topf) { /* abstract top variable from c */ + DdNode *d, *s1, *s2; + + /* Find cofactors of c. */ + s1 = cuddT(c); + s2 = cuddE(c); + /* Take the OR by applying DeMorgan. */ + d = cuddAddApplyRecur(dd, Cudd_addOr, s1, s2); + if (d == NULL) return(NULL); + cuddRef(d); + r = cuddAddRestrictRecur(dd, f, d); + if (r == NULL) { + Cudd_RecursiveDeref(dd, d); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDeref(dd, d); + cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r); + cuddDeref(r); + return(r); + } + + /* Recursive step. Here topf <= topc. */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + if (topc == topf) { + Cv = cuddT(c); Cnv = cuddE(c); + } else { + Cv = Cnv = c; + } + + if (!Cudd_IsConstant(Cv)) { + t = cuddAddRestrictRecur(dd, Fv, Cv); + if (t == NULL) return(NULL); + } else if (Cv == one) { + t = Fv; + } else { /* Cv == zero: return(Fnv @ Cnv) */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddAddRestrictRecur(dd, Fnv, Cnv); + if (r == NULL) return(NULL); + } + return(r); + } + cuddRef(t); + + if (!Cudd_IsConstant(Cnv)) { + e = cuddAddRestrictRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } else if (Cnv == one) { + e = Fnv; + } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ + cuddDeref(t); + return(t); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r); + return(r); + +} /* end of cuddAddRestrictRecur */ + + + +/**Function******************************************************************** + + Synopsis [Performs safe minimization of a BDD.] + + Description [Performs safe minimization of a BDD. Given the BDD + f of a function to be minimized and a BDD + c representing the care set, Cudd_bddLICompaction + produces the BDD of a function that agrees with f + wherever c is 1. Safe minimization means that the size + of the result is guaranteed not to exceed the size of + f. This function is based on the DAC97 paper by Hong et + al.. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction] + +******************************************************************************/ +DdNode * +cuddBddLICompaction( + DdManager * dd /* manager */, + DdNode * f /* function to be minimized */, + DdNode * c /* constraint (care set) */) +{ + st_table *marktable, *markcache, *buildcache; + DdNode *res, *zero; + + zero = Cudd_Not(DD_ONE(dd)); + if (c == zero) return(zero); + + /* We need to use local caches for both steps of this operation. + ** The results of the edge marking step are only valid as long as the + ** edge markings themselves are available. However, the edge markings + ** are lost at the end of one invocation of Cudd_bddLICompaction. + ** Hence, the cache entries for the edge marking step must be + ** invalidated at the end of this function. + ** For the result of the building step we argue as follows. The result + ** for a node and a given constrain depends on the BDD in which the node + ** appears. Hence, the same node and constrain may give different results + ** in successive invocations. + */ + marktable = st_init_table(st_ptrcmp,st_ptrhash); + if (marktable == NULL) { + return(NULL); + } + markcache = st_init_table(MarkCacheCompare,MarkCacheHash); + if (markcache == NULL) { + st_free_table(marktable); + return(NULL); + } + if (cuddBddLICMarkEdges(dd,f,c,marktable,markcache) == CUDD_OUT_OF_MEM) { + st_foreach(markcache, MarkCacheCleanUp, NULL); + st_free_table(marktable); + st_free_table(markcache); + return(NULL); + } + st_foreach(markcache, MarkCacheCleanUp, NULL); + st_free_table(markcache); + buildcache = st_init_table(st_ptrcmp,st_ptrhash); + if (buildcache == NULL) { + st_free_table(marktable); + return(NULL); + } + res = cuddBddLICBuildResult(dd,f,buildcache,marktable); + st_free_table(buildcache); + st_free_table(marktable); + return(res); + +} /* end of cuddBddLICompaction */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddConstrainDecomp.] + + Description [Performs the recursive step of Cudd_bddConstrainDecomp. + Returns f super (i) if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrainDecomp] + +******************************************************************************/ +static int +cuddBddConstrainDecomp( + DdManager * dd, + DdNode * f, + DdNode ** decomp) +{ + DdNode *F, *fv, *fvn; + DdNode *fAbs; + DdNode *result; + int ok; + + if (Cudd_IsConstant(f)) return(1); + /* Compute complements of cofactors. */ + F = Cudd_Regular(f); + fv = cuddT(F); + fvn = cuddE(F); + if (F == f) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + /* Compute abstraction of top variable. */ + fAbs = cuddBddAndRecur(dd, fv, fvn); + if (fAbs == NULL) { + return(0); + } + cuddRef(fAbs); + fAbs = Cudd_Not(fAbs); + /* Recursively find the next abstraction and the components of the + ** decomposition. */ + ok = cuddBddConstrainDecomp(dd, fAbs, decomp); + if (ok == 0) { + Cudd_IterDerefBdd(dd,fAbs); + return(0); + } + /* Compute the component of the decomposition corresponding to the + ** top variable and store it in the decomposition array. */ + result = cuddBddConstrainRecur(dd, f, fAbs); + if (result == NULL) { + Cudd_IterDerefBdd(dd,fAbs); + return(0); + } + cuddRef(result); + decomp[F->index] = result; + Cudd_IterDerefBdd(dd, fAbs); + return(1); + +} /* end of cuddBddConstrainDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCharToVect.] + + Description [Performs the recursive step of Cudd_bddCharToVect. + This function maintains the invariant that f is non-zero. + Returns the i-th component of the vector if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddCharToVect] + +******************************************************************************/ +static DdNode * +cuddBddCharToVect( + DdManager * dd, + DdNode * f, + DdNode * x) +{ + unsigned int topf; + unsigned int level; + int comple; + + DdNode *one, *zero, *res, *F, *fT, *fE, *T, *E; + + statLine(dd); + /* Check the cache. */ + res = cuddCacheLookup2(dd, cuddBddCharToVect, f, x); + if (res != NULL) { + return(res); + } + + F = Cudd_Regular(f); + + topf = cuddI(dd,F->index); + level = dd->perm[x->index]; + + if (topf > level) return(x); + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + comple = F != f; + fT = Cudd_NotCond(cuddT(F),comple); + fE = Cudd_NotCond(cuddE(F),comple); + + if (topf == level) { + if (fT == zero) return(zero); + if (fE == zero) return(one); + return(x); + } + + /* Here topf < level. */ + if (fT == zero) return(cuddBddCharToVect(dd, fE, x)); + if (fE == zero) return(cuddBddCharToVect(dd, fT, x)); + + T = cuddBddCharToVect(dd, fT, x); + if (T == NULL) { + return(NULL); + } + cuddRef(T); + E = cuddBddCharToVect(dd, fE, x); + if (E == NULL) { + Cudd_IterDerefBdd(dd,T); + return(NULL); + } + cuddRef(E); + res = cuddBddIteRecur(dd, dd->vars[F->index], T, E); + if (res == NULL) { + Cudd_IterDerefBdd(dd,T); + Cudd_IterDerefBdd(dd,E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + cuddCacheInsert2(dd, cuddBddCharToVect, f, x, res); + return(res); + +} /* end of cuddBddCharToVect */ + + +/**Function******************************************************************** + + Synopsis [Performs the edge marking step of Cudd_bddLICompaction.] + + Description [Performs the edge marking step of Cudd_bddLICompaction. + Returns the LUB of the markings of the two outgoing edges of f + if successful; otherwise CUDD_OUT_OF_MEM.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction cuddBddLICBuildResult] + +******************************************************************************/ +static int +cuddBddLICMarkEdges( + DdManager * dd, + DdNode * f, + DdNode * c, + st_table * table, + st_table * cache) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv; + DdNode *one, *zero; + unsigned int topf, topc; + int comple; + int resT, resE, res, retval; + char **slot; + MarkCacheKey *key; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (c == zero) return(DD_LIC_DC); + if (f == one) return(DD_LIC_1); + if (f == zero) return(DD_LIC_0); + + /* Make canonical to increase the utilization of the cache. */ + comple = Cudd_IsComplement(f); + f = Cudd_Regular(f); + /* Now f is a regular pointer to a non-constant node; c may be + ** constant, or it may be complemented. + */ + + /* Check the cache. */ + key = ALLOC(MarkCacheKey, 1); + if (key == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + key->f = f; key->c = c; + if (st_lookup_int(cache, (char *)key, &res)) { + FREE(key); + if (comple) { + if (res == DD_LIC_0) res = DD_LIC_1; + else if (res == DD_LIC_1) res = DD_LIC_0; + } + return(res); + } + + /* Recursive step. */ + topf = dd->perm[f->index]; + topc = cuddI(dd,Cudd_Regular(c)->index); + if (topf <= topc) { + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topc <= topf) { + /* We know that c is not constant because f is not. */ + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } + } else { + Cv = Cnv = c; + } + + resT = cuddBddLICMarkEdges(dd, Fv, Cv, table, cache); + if (resT == CUDD_OUT_OF_MEM) { + FREE(key); + return(CUDD_OUT_OF_MEM); + } + resE = cuddBddLICMarkEdges(dd, Fnv, Cnv, table, cache); + if (resE == CUDD_OUT_OF_MEM) { + FREE(key); + return(CUDD_OUT_OF_MEM); + } + + /* Update edge markings. */ + if (topf <= topc) { + retval = st_find_or_add(table, (char *)f, (char ***)&slot); + if (retval == 0) { + *slot = (char *) (ptrint)((resT << 2) | resE); + } else if (retval == 1) { + *slot = (char *) (ptrint)((int)((ptrint) *slot) | (resT << 2) | resE); + } else { + FREE(key); + return(CUDD_OUT_OF_MEM); + } + } + + /* Cache result. */ + res = resT | resE; + if (st_insert(cache, (char *)key, (char *)(ptrint)res) == ST_OUT_OF_MEM) { + FREE(key); + return(CUDD_OUT_OF_MEM); + } + + /* Take into account possible complementation. */ + if (comple) { + if (res == DD_LIC_0) res = DD_LIC_1; + else if (res == DD_LIC_1) res = DD_LIC_0; + } + return(res); + +} /* end of cuddBddLICMarkEdges */ + + +/**Function******************************************************************** + + Synopsis [Builds the result of Cudd_bddLICompaction.] + + Description [Builds the results of Cudd_bddLICompaction. + Returns a pointer to the minimized BDD if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction cuddBddLICMarkEdges] + +******************************************************************************/ +static DdNode * +cuddBddLICBuildResult( + DdManager * dd, + DdNode * f, + st_table * cache, + st_table * table) +{ + DdNode *Fv, *Fnv, *r, *t, *e; + DdNode *one, *zero; + int index; + int comple; + int markT, markE, markings; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + if (Cudd_IsConstant(f)) return(f); + /* Make canonical to increase the utilization of the cache. */ + comple = Cudd_IsComplement(f); + f = Cudd_Regular(f); + + /* Check the cache. */ + if (st_lookup(cache, f, &r)) { + return(Cudd_NotCond(r,comple)); + } + + /* Retrieve the edge markings. */ + if (st_lookup_int(table, (char *)f, &markings) == 0) + return(NULL); + markT = markings >> 2; + markE = markings & 3; + + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + + if (markT == DD_LIC_NL) { + t = cuddBddLICBuildResult(dd,Fv,cache,table); + if (t == NULL) { + return(NULL); + } + } else if (markT == DD_LIC_1) { + t = one; + } else { + t = zero; + } + cuddRef(t); + if (markE == DD_LIC_NL) { + e = cuddBddLICBuildResult(dd,Fnv,cache,table); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } + } else if (markE == DD_LIC_1) { + e = one; + } else { + e = zero; + } + cuddRef(e); + + if (markT == DD_LIC_DC && markE != DD_LIC_DC) { + r = e; + } else if (markT != DD_LIC_DC && markE == DD_LIC_DC) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + } + cuddDeref(t); + cuddDeref(e); + + if (st_insert(cache, (char *)f, (char *)r) == ST_OUT_OF_MEM) { + cuddRef(r); + Cudd_IterDerefBdd(dd,r); + return(NULL); + } + + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddLICBuildResult */ + + +/**Function******************************************************************** + + Synopsis [Hash function for the computed table of cuddBddLICMarkEdges.] + + Description [Hash function for the computed table of + cuddBddLICMarkEdges. Returns the bucket number.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction] + +******************************************************************************/ +static int +MarkCacheHash( + char * ptr, + int modulus) +{ + int val = 0; + MarkCacheKey *entry; + + entry = (MarkCacheKey *) ptr; + + val = (int) (ptrint) entry->f; + val = val * 997 + (int) (ptrint) entry->c; + + return ((val < 0) ? -val : val) % modulus; + +} /* end of MarkCacheHash */ + + +/**Function******************************************************************** + + Synopsis [Comparison function for the computed table of + cuddBddLICMarkEdges.] + + Description [Comparison function for the computed table of + cuddBddLICMarkEdges. Returns 0 if the two nodes of the key are equal; 1 + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction] + +******************************************************************************/ +static int +MarkCacheCompare( + const char * ptr1, + const char * ptr2) +{ + MarkCacheKey *entry1, *entry2; + + entry1 = (MarkCacheKey *) ptr1; + entry2 = (MarkCacheKey *) ptr2; + + return((entry1->f != entry2->f) || (entry1->c != entry2->c)); + +} /* end of MarkCacheCompare */ + + +/**Function******************************************************************** + + Synopsis [Frees memory associated with computed table of + cuddBddLICMarkEdges.] + + Description [Frees memory associated with computed table of + cuddBddLICMarkEdges. Returns ST_CONTINUE.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction] + +******************************************************************************/ +static enum st_retval +MarkCacheCleanUp( + char * key, + char * value, + char * arg) +{ + MarkCacheKey *entry; + + entry = (MarkCacheKey *) key; + FREE(entry); + return ST_CONTINUE; + +} /* end of MarkCacheCleanUp */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddSqueeze.] + + Description [Performs the recursive step of Cudd_bddSqueeze. This + procedure exploits the fact that if we complement and swap the + bounds of the interval we obtain a valid solution by taking the + complement of the solution to the original problem. Therefore, we + can enforce the condition that the upper bound is always regular. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddSqueeze] + +******************************************************************************/ +static DdNode * +cuddBddSqueeze( + DdManager * dd, + DdNode * l, + DdNode * u) +{ + DdNode *one, *zero, *r, *lt, *le, *ut, *ue, *t, *e; +#if 0 + DdNode *ar; +#endif + int comple = 0; + unsigned int topu, topl; + int index; + + statLine(dd); + if (l == u) { + return(l); + } + one = DD_ONE(dd); + zero = Cudd_Not(one); + /* The only case when l == zero && u == one is at the top level, + ** where returning either one or zero is OK. In all other cases + ** the procedure will detect such a case and will perform + ** remapping. Therefore the order in which we test l and u at this + ** point is immaterial. */ + if (l == zero) return(l); + if (u == one) return(u); + + /* Make canonical to increase the utilization of the cache. */ + if (Cudd_IsComplement(u)) { + DdNode *temp; + temp = Cudd_Not(l); + l = Cudd_Not(u); + u = temp; + comple = 1; + } + /* At this point u is regular and non-constant; l is non-constant, but + ** may be complemented. */ + + /* Here we could check the relative sizes. */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_bddSqueeze, l, u); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + /* Recursive step. */ + topu = dd->perm[u->index]; + topl = dd->perm[Cudd_Regular(l)->index]; + if (topu <= topl) { + index = u->index; + ut = cuddT(u); ue = cuddE(u); + } else { + index = Cudd_Regular(l)->index; + ut = ue = u; + } + if (topl <= topu) { + lt = cuddT(Cudd_Regular(l)); le = cuddE(Cudd_Regular(l)); + if (Cudd_IsComplement(l)) { + lt = Cudd_Not(lt); + le = Cudd_Not(le); + } + } else { + lt = le = l; + } + + /* If one interval is contained in the other, use the smaller + ** interval. This corresponds to one-sided matching. */ + if ((lt == zero || Cudd_bddLeq(dd,lt,le)) && + (ut == one || Cudd_bddLeq(dd,ue,ut))) { /* remap */ + r = cuddBddSqueeze(dd, le, ue); + if (r == NULL) + return(NULL); + return(Cudd_NotCond(r,comple)); + } else if ((le == zero || Cudd_bddLeq(dd,le,lt)) && + (ue == one || Cudd_bddLeq(dd,ut,ue))) { /* remap */ + r = cuddBddSqueeze(dd, lt, ut); + if (r == NULL) + return(NULL); + return(Cudd_NotCond(r,comple)); + } else if ((le == zero || Cudd_bddLeq(dd,le,Cudd_Not(ut))) && + (ue == one || Cudd_bddLeq(dd,Cudd_Not(lt),ue))) { /* c-remap */ + t = cuddBddSqueeze(dd, lt, ut); + cuddRef(t); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(dd, index, Cudd_Not(t), t); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(dd, index, t, Cudd_Not(t)); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddDeref(t); + if (r == NULL) + return(NULL); + cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); + return(Cudd_NotCond(r,comple)); + } else if ((lt == zero || Cudd_bddLeq(dd,lt,Cudd_Not(ue))) && + (ut == one || Cudd_bddLeq(dd,Cudd_Not(le),ut))) { /* c-remap */ + e = cuddBddSqueeze(dd, le, ue); + cuddRef(e); + if (Cudd_IsComplement(e)) { + r = cuddUniqueInter(dd, index, Cudd_Not(e), e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + } else { + r = cuddUniqueInter(dd, index, e, Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + r = Cudd_Not(r); + } + cuddDeref(e); + if (r == NULL) + return(NULL); + cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); + return(Cudd_NotCond(r,comple)); + } + +#if 0 + /* If the two intervals intersect, take a solution from + ** the intersection of the intervals. This guarantees that the + ** splitting variable will not appear in the result. + ** This approach corresponds to two-sided matching, and is very + ** expensive. */ + if (Cudd_bddLeq(dd,lt,ue) && Cudd_bddLeq(dd,le,ut)) { + DdNode *au, *al; + au = cuddBddAndRecur(dd,ut,ue); + if (au == NULL) + return(NULL); + cuddRef(au); + al = cuddBddAndRecur(dd,Cudd_Not(lt),Cudd_Not(le)); + if (al == NULL) { + Cudd_IterDerefBdd(dd,au); + return(NULL); + } + cuddRef(al); + al = Cudd_Not(al); + ar = cuddBddSqueeze(dd, al, au); + if (ar == NULL) { + Cudd_IterDerefBdd(dd,au); + Cudd_IterDerefBdd(dd,al); + return(NULL); + } + cuddRef(ar); + Cudd_IterDerefBdd(dd,au); + Cudd_IterDerefBdd(dd,al); + } else { + ar = NULL; + } +#endif + + t = cuddBddSqueeze(dd, lt, ut); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + e = cuddBddSqueeze(dd, le, ue); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + +#if 0 + /* Check whether there is a result obtained by abstraction and whether + ** it is better than the one obtained by recursion. */ + cuddRef(r); + if (ar != NULL) { + if (Cudd_DagSize(ar) <= Cudd_DagSize(r)) { + Cudd_IterDerefBdd(dd, r); + r = ar; + } else { + Cudd_IterDerefBdd(dd, ar); + } + } + cuddDeref(r); +#endif + + cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddSqueeze */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddGenetic.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddGenetic.c new file mode 100644 index 000000000..8b259fe70 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddGenetic.c @@ -0,0 +1,960 @@ +/**CFile*********************************************************************** + + FileName [cuddGenetic.c] + + PackageName [cudd] + + Synopsis [Genetic algorithm for variable reordering.] + + Description [Internal procedures included in this file: +
                +
              • cuddGa() +
              + Static procedures included in this module: +
                +
              • make_random() +
              • sift_up() +
              • build_dd() +
              • largest() +
              • rand_int() +
              • array_hash() +
              • array_compare() +
              • find_best() +
              • find_average_fitness() +
              • PMX() +
              • roulette() +
              + + The genetic algorithm implemented here is as follows. We start with + the current DD order. We sift this order and use this as the + reference DD. We only keep 1 DD around for the entire process and + simply rearrange the order of this DD, storing the various orders + and their corresponding DD sizes. We generate more random orders to + build an initial population. This initial population is 3 times the + number of variables, with a maximum of 120. Each random order is + built (from the reference DD) and its size stored. Each random + order is also sifted to keep the DD sizes fairly small. Then a + crossover is performed between two orders (picked randomly) and the + two resulting DDs are built and sifted. For each new order, if its + size is smaller than any DD in the population, it is inserted into + the population and the DD with the largest number of nodes is thrown + out. The crossover process happens up to 50 times, and at this point + the DD in the population with the smallest size is chosen as the + result. This DD must then be built from the reference DD.] + + SeeAlso [] + + Author [Curt Musfeldt, Alan Shuler, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddGenetic.c,v 1.30 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static int popsize; /* the size of the population */ +static int numvars; /* the number of input variables in the ckt. */ +/* storedd stores the population orders and sizes. This table has two +** extra rows and one extras column. The two extra rows are used for the +** offspring produced by a crossover. Each row stores one order and its +** size. The order is stored by storing the indices of variables in the +** order in which they appear in the order. The table is in reality a +** one-dimensional array which is accessed via a macro to give the illusion +** it is a two-dimensional structure. +*/ +static int *storedd; +static st_table *computed; /* hash table to identify existing orders */ +static int *repeat; /* how many times an order is present */ +static int large; /* stores the index of the population with + ** the largest number of nodes in the DD */ +static int result; +static int cross; /* the number of crossovers to perform */ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/* macro used to access the population table as if it were a +** two-dimensional structure. +*/ +#define STOREDD(i,j) storedd[(i)*(numvars+1)+(j)] + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int make_random (DdManager *table, int lower); +static int sift_up (DdManager *table, int x, int x_low); +static int build_dd (DdManager *table, int num, int lower, int upper); +static int largest (void); +static int rand_int (int a); +static int array_hash (char *array, int modulus); +static int array_compare (const char *array1, const char *array2); +static int find_best (void); +#ifdef DD_STATS +static double find_average_fitness (void); +#endif +static int PMX (int maxvar); +static int roulette (int *p1, int *p2); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Genetic algorithm for DD reordering.] + + Description [Genetic algorithm for DD reordering. + The two children of a crossover will be stored in + storedd[popsize] and storedd[popsize+1] --- the last two slots in the + storedd array. (This will make comparisons and replacement easy.) + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddGa( + DdManager * table /* manager */, + int lower /* lowest level to be reordered */, + int upper /* highest level to be reorderded */) +{ + int i,n,m; /* dummy/loop vars */ + int index; +#ifdef DD_STATS + double average_fitness; +#endif + int small; /* index of smallest DD in population */ + + /* Do an initial sifting to produce at least one reasonable individual. */ + if (!cuddSifting(table,lower,upper)) return(0); + + /* Get the initial values. */ + numvars = upper - lower + 1; /* number of variables to be reordered */ + if (table->populationSize == 0) { + popsize = 3 * numvars; /* population size is 3 times # of vars */ + if (popsize > 120) { + popsize = 120; /* Maximum population size is 120 */ + } + } else { + popsize = table->populationSize; /* user specified value */ + } + if (popsize < 4) popsize = 4; /* enforce minimum population size */ + + /* Allocate population table. */ + storedd = ALLOC(int,(popsize+2)*(numvars+1)); + if (storedd == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + + /* Initialize the computed table. This table is made up of two data + ** structures: A hash table with the key given by the order, which says + ** if a given order is present in the population; and the repeat + ** vector, which says how many copies of a given order are stored in + ** the population table. If there are multiple copies of an order, only + ** one has a repeat count greater than 1. This copy is the one pointed + ** by the computed table. + */ + repeat = ALLOC(int,popsize); + if (repeat == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + FREE(storedd); + return(0); + } + for (i = 0; i < popsize; i++) { + repeat[i] = 0; + } + computed = st_init_table(array_compare,array_hash); + if (computed == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + FREE(storedd); + FREE(repeat); + return(0); + } + + /* Copy the current DD and its size to the population table. */ + for (i = 0; i < numvars; i++) { + STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */ + } + STOREDD(0,numvars) = table->keys - table->isolated; /* size of initial DD */ + + /* Store the initial order in the computed table. */ + if (st_insert(computed,(char *)storedd,(char *) 0) == ST_OUT_OF_MEM) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[0]++; + + /* Insert the reverse order as second element of the population. */ + for (i = 0; i < numvars; i++) { + STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */ + } + + /* Now create the random orders. make_random fills the population + ** table with random permutations. The successive loop builds and sifts + ** the DDs for the reverse order and each random permutation, and stores + ** the results in the computed table. + */ + if (!make_random(table,lower)) { + table->errorCode = CUDD_MEMORY_OUT; + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + for (i = 1; i < popsize; i++) { + result = build_dd(table,i,lower,upper); /* build and sift order */ + if (!result) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + if (st_lookup_int(computed,(char *)&STOREDD(i,0),&index)) { + repeat[index]++; + } else { + if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) == + ST_OUT_OF_MEM) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[i]++; + } + } + +#if 0 +#ifdef DD_STATS + /* Print the initial population. */ + (void) fprintf(table->out,"Initial population after sifting\n"); + for (m = 0; m < popsize; m++) { + for (i = 0; i < numvars; i++) { + (void) fprintf(table->out," %2d",STOREDD(m,i)); + } + (void) fprintf(table->out," : %3d (%d)\n", + STOREDD(m,numvars),repeat[m]); + } +#endif +#endif + + small = find_best(); +#ifdef DD_STATS + average_fitness = find_average_fitness(); + (void) fprintf(table->out,"\nInitial population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness); +#endif + + /* Decide how many crossovers should be tried. */ + if (table->numberXovers == 0) { + cross = 3*numvars; + if (cross > 60) { /* do a maximum of 50 crossovers */ + cross = 60; + } + } else { + cross = table->numberXovers; /* use user specified value */ + } + if (cross >= popsize) { + cross = popsize; + } + + /* Perform the crossovers to get the best order. */ + for (m = 0; m < cross; m++) { + if (!PMX(table->size)) { /* perform one crossover */ + table->errorCode = CUDD_MEMORY_OUT; + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + /* The offsprings are left in the last two entries of the + ** population table. These are now considered in turn. + */ + for (i = popsize; i <= popsize+1; i++) { + result = build_dd(table,i,lower,upper); /* build and sift child */ + if (!result) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + large = largest(); /* find the largest DD in population */ + + /* If the new child is smaller than the largest DD in the current + ** population, enter it into the population in place of the + ** largest DD. + */ + if (STOREDD(i,numvars) < STOREDD(large,numvars)) { + /* Look up the largest DD in the computed table. + ** Decrease its repetition count. If the repetition count + ** goes to 0, remove the largest DD from the computed table. + */ + result = st_lookup_int(computed,(char *)&STOREDD(large,0), + &index); + if (!result) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[index]--; + if (repeat[index] == 0) { + int *pointer = &STOREDD(index,0); + result = st_delete(computed, &pointer, NULL); + if (!result) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + } + /* Copy the new individual to the entry of the + ** population table just made available and update the + ** computed table. + */ + for (n = 0; n <= numvars; n++) { + STOREDD(large,n) = STOREDD(i,n); + } + if (st_lookup_int(computed,(char *)&STOREDD(large,0), + &index)) { + repeat[index]++; + } else { + if (st_insert(computed,(char *)&STOREDD(large,0), + (char *)(long)large) == ST_OUT_OF_MEM) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[large]++; + } + } + } + } + + /* Find the smallest DD in the population and build it; + ** that will be the result. + */ + small = find_best(); + + /* Print stats on the final population. */ +#ifdef DD_STATS + average_fitness = find_average_fitness(); + (void) fprintf(table->out,"\nFinal population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness); +#endif + + /* Clean up, build the result DD, and return. */ + st_free_table(computed); + computed = NULL; + result = build_dd(table,small,lower,upper); + FREE(storedd); + FREE(repeat); + return(result); + +} /* end of cuddGa */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Generates the random sequences for the initial population.] + + Description [Generates the random sequences for the initial population. + The sequences are permutations of the indices between lower and + upper in the current order.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +make_random( + DdManager * table, + int lower) +{ + int i,j; /* loop variables */ + int *used; /* is a number already in a permutation */ + int next; /* next random number without repetitions */ + + used = ALLOC(int,numvars); + if (used == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } +#if 0 +#ifdef DD_STATS + (void) fprintf(table->out,"Initial population before sifting\n"); + for (i = 0; i < 2; i++) { + for (j = 0; j < numvars; j++) { + (void) fprintf(table->out," %2d",STOREDD(i,j)); + } + (void) fprintf(table->out,"\n"); + } +#endif +#endif + for (i = 2; i < popsize; i++) { + for (j = 0; j < numvars; j++) { + used[j] = 0; + } + /* Generate a permutation of {0...numvars-1} and use it to + ** permute the variables in the layesr from lower to upper. + */ + for (j = 0; j < numvars; j++) { + do { + next = rand_int(numvars-1); + } while (used[next] != 0); + used[next] = 1; + STOREDD(i,j) = table->invperm[next+lower]; + } +#if 0 +#ifdef DD_STATS + /* Print the order just generated. */ + for (j = 0; j < numvars; j++) { + (void) fprintf(table->out," %2d",STOREDD(i,j)); + } + (void) fprintf(table->out,"\n"); +#endif +#endif + } + FREE(used); + return(1); + +} /* end of make_random */ + + +/**Function******************************************************************** + + Synopsis [Moves one variable up.] + + Description [Takes a variable from position x and sifts it up to + position x_low; x_low should be less than x. Returns 1 if successful; + 0 otherwise] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +sift_up( + DdManager * table, + int x, + int x_low) +{ + int y; + int size; + + y = cuddNextLow(table,x); + while (y >= x_low) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); + } + return(1); + +} /* end of sift_up */ + + +/**Function******************************************************************** + + Synopsis [Builds a DD from a given order.] + + Description [Builds a DD from a given order. This procedure also + sifts the final order and inserts into the array the size in nodes + of the result. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +build_dd( + DdManager * table, + int num /* the index of the individual to be built */, + int lower, + int upper) +{ + int i,j; /* loop vars */ + int position; + int index; + int limit; /* how large the DD for this order can grow */ + int size; + + /* Check the computed table. If the order already exists, it + ** suffices to copy the size from the existing entry. + */ + if (computed && st_lookup_int(computed,(char *)&STOREDD(num,0),&index)) { + STOREDD(num,numvars) = STOREDD(index,numvars); +#ifdef DD_STATS + (void) fprintf(table->out,"\nCache hit for index %d", index); +#endif + return(1); + } + + /* Stop if the DD grows 20 times larges than the reference size. */ + limit = 20 * STOREDD(0,numvars); + + /* Sift up the variables so as to build the desired permutation. + ** First the variable that has to be on top is sifted to the top. + ** Then the variable that has to occupy the secon position is sifted + ** up to the second position, and so on. + */ + for (j = 0; j < numvars; j++) { + i = STOREDD(num,j); + position = table->perm[i]; + result = sift_up(table,position,j+lower); + if (!result) return(0); + size = table->keys - table->isolated; + if (size > limit) break; + } + + /* Sift the DD just built. */ +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + result = cuddSifting(table,lower,upper); + if (!result) return(0); + + /* Copy order and size to table. */ + for (j = 0; j < numvars; j++) { + STOREDD(num,j) = table->invperm[lower+j]; + } + STOREDD(num,numvars) = table->keys - table->isolated; /* size of new DD */ + return(1); + +} /* end of build_dd */ + + +/**Function******************************************************************** + + Synopsis [Finds the largest DD in the population.] + + Description [Finds the largest DD in the population. If an order is + repeated, it avoids choosing the copy that is in the computed table + (it has repeat[i] > 1).] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +largest(void) +{ + int i; /* loop var */ + int big; /* temporary holder to return result */ + + big = 0; + while (repeat[big] > 1) big++; + for (i = big + 1; i < popsize; i++) { + if (STOREDD(i,numvars) >= STOREDD(big,numvars) && repeat[i] <= 1) { + big = i; + } + } + return(big); + +} /* end of largest */ + + +/**Function******************************************************************** + + Synopsis [Generates a random number between 0 and the integer a.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +rand_int( + int a) +{ + return(Cudd_Random() % (a+1)); + +} /* end of rand_int */ + + +/**Function******************************************************************** + + Synopsis [Hash function for the computed table.] + + Description [Hash function for the computed table. Returns the bucket + number.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +array_hash( + char * array, + int modulus) +{ + int val = 0; + int i; + int *intarray; + + intarray = (int *) array; + + for (i = 0; i < numvars; i++) { + val = val * 997 + intarray[i]; + } + + return ((val < 0) ? -val : val) % modulus; + +} /* end of array_hash */ + + +/**Function******************************************************************** + + Synopsis [Comparison function for the computed table.] + + Description [Comparison function for the computed table. Returns 0 if + the two arrays are equal; 1 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +array_compare( + const char * array1, + const char * array2) +{ + int i; + int *intarray1, *intarray2; + + intarray1 = (int *) array1; + intarray2 = (int *) array2; + + for (i = 0; i < numvars; i++) { + if (intarray1[i] != intarray2[i]) return(1); + } + return(0); + +} /* end of array_compare */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the fittest individual.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +find_best(void) +{ + int i,small; + + small = 0; + for (i = 1; i < popsize; i++) { + if (STOREDD(i,numvars) < STOREDD(small,numvars)) { + small = i; + } + } + return(small); + +} /* end of find_best */ + + +/**Function******************************************************************** + + Synopsis [Returns the average fitness of the population.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +#ifdef DD_STATS +static double +find_average_fitness(void) +{ + int i; + int total_fitness = 0; + double average_fitness; + + for (i = 0; i < popsize; i++) { + total_fitness += STOREDD(i,numvars); + } + average_fitness = (double) total_fitness / (double) popsize; + return(average_fitness); + +} /* end of find_average_fitness */ +#endif + + +/**Function******************************************************************** + + Synopsis [Performs the crossover between two parents.] + + Description [Performs the crossover between two randomly chosen + parents, and creates two children, x1 and x2. Uses the Partially + Matched Crossover operator.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +PMX( + int maxvar) +{ + int cut1,cut2; /* the two cut positions (random) */ + int mom,dad; /* the two randomly chosen parents */ + int *inv1; /* inverse permutations for repair algo */ + int *inv2; + int i; /* loop vars */ + int u,v; /* aux vars */ + + inv1 = ALLOC(int,maxvar); + if (inv1 == NULL) { + return(0); + } + inv2 = ALLOC(int,maxvar); + if (inv2 == NULL) { + FREE(inv1); + return(0); + } + + /* Choose two orders from the population using roulette wheel. */ + if (!roulette(&mom,&dad)) { + FREE(inv1); + FREE(inv2); + return(0); + } + + /* Choose two random cut positions. A cut in position i means that + ** the cut immediately precedes position i. If cut1 < cut2, we + ** exchange the middle of the two orderings; otherwise, we + ** exchange the beginnings and the ends. + */ + cut1 = rand_int(numvars-1); + do { + cut2 = rand_int(numvars-1); + } while (cut1 == cut2); + +#if 0 + /* Print out the parents. */ + (void) fprintf(table->out, + "Crossover of %d (mom) and %d (dad) between %d and %d\n", + mom,dad,cut1,cut2); + for (i = 0; i < numvars; i++) { + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(mom,i)); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < numvars; i++) { + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(dad,i)); + } + (void) fprintf(table->out,"\n"); +#endif + + /* Initialize the inverse permutations: -1 means yet undetermined. */ + for (i = 0; i < maxvar; i++) { + inv1[i] = -1; + inv2[i] = -1; + } + + /* Copy the portions whithin the cuts. */ + for (i = cut1; i != cut2; i = (i == numvars-1) ? 0 : i+1) { + STOREDD(popsize,i) = STOREDD(dad,i); + inv1[STOREDD(popsize,i)] = i; + STOREDD(popsize+1,i) = STOREDD(mom,i); + inv2[STOREDD(popsize+1,i)] = i; + } + + /* Now apply the repair algorithm outside the cuts. */ + for (i = cut2; i != cut1; i = (i == numvars-1 ) ? 0 : i+1) { + v = i; + do { + u = STOREDD(mom,v); + v = inv1[u]; + } while (v != -1); + STOREDD(popsize,i) = u; + inv1[u] = i; + v = i; + do { + u = STOREDD(dad,v); + v = inv2[u]; + } while (v != -1); + STOREDD(popsize+1,i) = u; + inv2[u] = i; + } + +#if 0 + /* Print the results of crossover. */ + for (i = 0; i < numvars; i++) { + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(popsize,i)); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < numvars; i++) { + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(popsize+1,i)); + } + (void) fprintf(table->out,"\n"); +#endif + + FREE(inv1); + FREE(inv2); + return(1); + +} /* end of PMX */ + + +/**Function******************************************************************** + + Synopsis [Selects two parents with the roulette wheel method.] + + Description [Selects two distinct parents with the roulette wheel method.] + + SideEffects [The indices of the selected parents are returned as side + effects.] + + SeeAlso [] + +******************************************************************************/ +static int +roulette( + int * p1, + int * p2) +{ + double *wheel; + double spin; + int i; + + wheel = ALLOC(double,popsize); + if (wheel == NULL) { + return(0); + } + + /* The fitness of an individual is the reciprocal of its size. */ + wheel[0] = 1.0 / (double) STOREDD(0,numvars); + + for (i = 1; i < popsize; i++) { + wheel[i] = wheel[i-1] + 1.0 / (double) STOREDD(i,numvars); + } + + /* Get a random number between 0 and wheel[popsize-1] (that is, + ** the sum of all fitness values. 2147483561 is the largest number + ** returned by Cudd_Random. + */ + spin = wheel[numvars-1] * (double) Cudd_Random() / 2147483561.0; + + /* Find the lucky element by scanning the wheel. */ + for (i = 0; i < popsize; i++) { + if (spin <= wheel[i]) break; + } + *p1 = i; + + /* Repeat the process for the second parent, making sure it is + ** distinct from the first. + */ + do { + spin = wheel[popsize-1] * (double) Cudd_Random() / 2147483561.0; + for (i = 0; i < popsize; i++) { + if (spin <= wheel[i]) break; + } + } while (i == *p1); + *p2 = i; + + FREE(wheel); + return(1); + +} /* end of roulette */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddGroup.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddGroup.c new file mode 100644 index 000000000..03a1bb7aa --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddGroup.c @@ -0,0 +1,2188 @@ +/**CFile*********************************************************************** + + FileName [cuddGroup.c] + + PackageName [cudd] + + Synopsis [Functions for group sifting.] + + Description [External procedures included in this file: +
                +
              • Cudd_MakeTreeNode() +
              + Internal procedures included in this file: +
                +
              • cuddTreeSifting() +
              + Static procedures included in this module: +
                +
              • ddTreeSiftingAux() +
              • ddCountInternalMtrNodes() +
              • ddReorderChildren() +
              • ddFindNodeHiLo() +
              • ddUniqueCompareGroup() +
              • ddGroupSifting() +
              • ddCreateGroup() +
              • ddGroupSiftingAux() +
              • ddGroupSiftingUp() +
              • ddGroupSiftingDown() +
              • ddGroupMove() +
              • ddGroupMoveBackward() +
              • ddGroupSiftingBackward() +
              • ddMergeGroups() +
              • ddDissolveGroup() +
              • ddNoCheck() +
              • ddSecDiffCheck() +
              • ddExtSymmCheck() +
              • ddVarGroupCheck() +
              • ddSetVarHandled() +
              • ddResetVarHandled() +
              • ddIsVarHandled() +
              • ddFixTree() +
              ] + + Author [Shipra Panda, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Constants for lazy sifting */ +#define DD_NORMAL_SIFT 0 +#define DD_LAZY_SIFT 1 + +/* Constants for sifting up and down */ +#define DD_SIFT_DOWN 0 +#define DD_SIFT_UP 1 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + typedef int (*DD_CHKFP)(DdManager *, int, int); +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddGroup.c,v 1.49 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static int *entry; +extern int ddTotalNumberSwapping; +#ifdef DD_STATS +extern int ddTotalNISwaps; +static int extsymmcalls; +static int extsymm; +static int secdiffcalls; +static int secdiff; +static int secdiffmisfire; +#endif +#ifdef DD_DEBUG +static int pr = 0; /* flag to enable printing while debugging */ + /* by depositing a 1 into it */ +#endif +static unsigned int originalSize; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +#ifdef DD_STATS +static int ddCountInternalMtrNodes (DdManager *table, MtrNode *treenode); +#endif +static int ddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +static void ddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper); +static int ddUniqueCompareGroup (int *ptrX, int *ptrY); +static int ddGroupSifting (DdManager *table, int lower, int upper, DD_CHKFP checkFunction, int lazyFlag); +static void ddCreateGroup (DdManager *table, int x, int y); +static int ddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh, DD_CHKFP checkFunction, int lazyFlag); +static int ddGroupSiftingUp (DdManager *table, int y, int xLow, DD_CHKFP checkFunction, Move **moves); +static int ddGroupSiftingDown (DdManager *table, int x, int xHigh, DD_CHKFP checkFunction, Move **moves); +static int ddGroupMove (DdManager *table, int x, int y, Move **moves); +static int ddGroupMoveBackward (DdManager *table, int x, int y); +static int ddGroupSiftingBackward (DdManager *table, Move *moves, int size, int upFlag, int lazyFlag); +static void ddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high); +static void ddDissolveGroup (DdManager *table, int x, int y); +static int ddNoCheck (DdManager *table, int x, int y); +static int ddSecDiffCheck (DdManager *table, int x, int y); +static int ddExtSymmCheck (DdManager *table, int x, int y); +static int ddVarGroupCheck (DdManager * table, int x, int y); +static int ddSetVarHandled (DdManager *dd, int index); +static int ddResetVarHandled (DdManager *dd, int index); +static int ddIsVarHandled (DdManager *dd, int index); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Creates a new variable group.] + + Description [Creates a new variable group. The group starts at + variable low and contains size variables. The parameter low is the index + of the first variable. If the variable already exists, its current + position in the order is known to the manager. If the variable does + not exist yet, the position is assumed to be the same as the index. + The group tree is created if it does not exist yet. + Returns a pointer to the group if successful; NULL otherwise.] + + SideEffects [The variable tree is changed.] + + SeeAlso [Cudd_MakeZddTreeNode] + +******************************************************************************/ +MtrNode * +Cudd_MakeTreeNode( + DdManager * dd /* manager */, + unsigned int low /* index of the first group variable */, + unsigned int size /* number of variables in the group */, + unsigned int type /* MTR_DEFAULT or MTR_FIXED */) +{ + MtrNode *group; + MtrNode *tree; + unsigned int level; + + /* If the variable does not exist yet, the position is assumed to be + ** the same as the index. Therefore, applications that rely on + ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new + ** variables have to create the variables before they group them. + */ + level = (low < (unsigned int) dd->size) ? dd->perm[low] : low; + + if (level + size - 1> (int) MTR_MAXHIGH) + return(NULL); + + /* If the tree does not exist yet, create it. */ + tree = dd->tree; + if (tree == NULL) { + dd->tree = tree = Mtr_InitGroupTree(0, dd->size); + if (tree == NULL) + return(NULL); + tree->index = dd->size == 0 ? 0 : dd->invperm[0]; + } + + /* Extend the upper bound of the tree if necessary. This allows the + ** application to create groups even before the variables are created. + */ + tree->size = ddMax(tree->size, ddMax(level + size, (unsigned) dd->size)); + + /* Create the group. */ + group = Mtr_MakeGroup(tree, level, size, type); + if (group == NULL) + return(NULL); + + /* Initialize the index field to the index of the variable currently + ** in position low. This field will be updated by the reordering + ** procedure to provide a handle to the group once it has been moved. + */ + group->index = (MtrHalfWord) low; + + return(group); + +} /* end of Cudd_MakeTreeNode */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Tree sifting algorithm.] + + Description [Tree sifting algorithm. Assumes that a tree representing + a group hierarchy is passed as a parameter. It then reorders each + group in postorder fashion by calling ddTreeSiftingAux. Assumes that + no dead nodes are present. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddTreeSifting( + DdManager * table /* DD table */, + Cudd_ReorderingType method /* reordering method for the groups of leaves */) +{ + int i; + int nvars; + int result; + int tempTree; + + /* If no tree is provided we create a temporary one in which all + ** variables are in a single group. After reordering this tree is + ** destroyed. + */ + tempTree = table->tree == NULL; + if (tempTree) { + table->tree = Mtr_InitGroupTree(0,table->size); + table->tree->index = table->invperm[0]; + } + nvars = table->size; + +#ifdef DD_DEBUG + if (pr > 0 && !tempTree) (void) fprintf(table->out,"cuddTreeSifting:"); + Mtr_PrintGroups(table->tree,pr <= 0); +#endif + +#ifdef DD_STATS + extsymmcalls = 0; + extsymm = 0; + secdiffcalls = 0; + secdiff = 0; + secdiffmisfire = 0; + + (void) fprintf(table->out,"\n"); + if (!tempTree) + (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", + ddCountInternalMtrNodes(table,table->tree)); +#endif + + /* Initialize the group of each subtable to itself. Initially + ** there are no groups. Groups are created according to the tree + ** structure in postorder fashion. + */ + for (i = 0; i < nvars; i++) + table->subtables[i].next = i; + + + /* Reorder. */ + result = ddTreeSiftingAux(table, table->tree, method); + +#ifdef DD_STATS /* print stats */ + if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && + (table->groupcheck == CUDD_GROUP_CHECK7 || + table->groupcheck == CUDD_GROUP_CHECK5)) { + (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); + (void) fprintf(table->out,"extsymm = %d",extsymm); + } + if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && + table->groupcheck == CUDD_GROUP_CHECK7) { + (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); + (void) fprintf(table->out,"secdiff = %d\n",secdiff); + (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); + } +#endif + + if (tempTree) + Cudd_FreeTree(table); + else + Mtr_ReorderGroups(table->tree, table->perm); + + return(result); + +} /* end of cuddTreeSifting */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Visits the group tree and reorders each group.] + + Description [Recursively visits the group tree and reorders each + group in postorder fashion. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddTreeSiftingAux( + DdManager * table, + MtrNode * treenode, + Cudd_ReorderingType method) +{ + MtrNode *auxnode; + int res; + Cudd_AggregationType saveCheck; + +#ifdef DD_DEBUG + Mtr_PrintGroups(treenode,1); +#endif + + auxnode = treenode; + while (auxnode != NULL) { + if (auxnode->child != NULL) { + if (!ddTreeSiftingAux(table, auxnode->child, method)) + return(0); + saveCheck = table->groupcheck; + table->groupcheck = CUDD_NO_CHECK; + if (method != CUDD_REORDER_LAZY_SIFT) + res = ddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT); + else + res = ddReorderChildren(table, auxnode, CUDD_REORDER_LAZY_SIFT); + table->groupcheck = saveCheck; + + if (res == 0) + return(0); + } else if (auxnode->size > 1) { + if (!ddReorderChildren(table, auxnode, method)) + return(0); + } + auxnode = auxnode->younger; + } + + return(1); + +} /* end of ddTreeSiftingAux */ + + +#ifdef DD_STATS +/**Function******************************************************************** + + Synopsis [Counts the number of internal nodes of the group tree.] + + Description [Counts the number of internal nodes of the group tree. + Returns the count.] + + SideEffects [None] + +******************************************************************************/ +static int +ddCountInternalMtrNodes( + DdManager * table, + MtrNode * treenode) +{ + MtrNode *auxnode; + int count,nodeCount; + + + nodeCount = 0; + auxnode = treenode; + while (auxnode != NULL) { + if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { + nodeCount++; + count = ddCountInternalMtrNodes(table,auxnode->child); + nodeCount += count; + } + auxnode = auxnode->younger; + } + + return(nodeCount); + +} /* end of ddCountInternalMtrNodes */ +#endif + + +/**Function******************************************************************** + + Synopsis [Reorders the children of a group tree node according to + the options.] + + Description [Reorders the children of a group tree node according to + the options. After reordering puts all the variables in the group + and/or its descendents in a single group. This allows hierarchical + reordering. If the variables in the group do not exist yet, simply + does nothing. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddReorderChildren( + DdManager * table, + MtrNode * treenode, + Cudd_ReorderingType method) +{ + int lower; + int upper; + int result; + unsigned int initialSize; + + ddFindNodeHiLo(table,treenode,&lower,&upper); + /* If upper == -1 these variables do not exist yet. */ + if (upper == -1) + return(1); + + if (treenode->flags == MTR_FIXED) { + result = 1; + } else { +#ifdef DD_STATS + (void) fprintf(table->out," "); +#endif + switch (method) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + result = cuddSwapping(table,lower,upper,method); + break; + case CUDD_REORDER_SIFT: + result = cuddSifting(table,lower,upper); + break; + case CUDD_REORDER_SIFT_CONVERGE: + do { + initialSize = table->keys - table->isolated; + result = cuddSifting(table,lower,upper); + if (initialSize <= table->keys - table->isolated) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + case CUDD_REORDER_SYMM_SIFT: + result = cuddSymmSifting(table,lower,upper); + break; + case CUDD_REORDER_SYMM_SIFT_CONV: + result = cuddSymmSiftingConv(table,lower,upper); + break; + case CUDD_REORDER_GROUP_SIFT: + if (table->groupcheck == CUDD_NO_CHECK) { + result = ddGroupSifting(table,lower,upper,ddNoCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK5) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK7) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else { + (void) fprintf(table->err, + "Unknown group ckecking method\n"); + result = 0; + } + break; + case CUDD_REORDER_GROUP_SIFT_CONV: + do { + initialSize = table->keys - table->isolated; + if (table->groupcheck == CUDD_NO_CHECK) { + result = ddGroupSifting(table,lower,upper,ddNoCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK5) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK7) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else { + (void) fprintf(table->err, + "Unknown group ckecking method\n"); + result = 0; + } +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + result = cuddWindowReorder(table,lower,upper, + CUDD_REORDER_WINDOW4); + if (initialSize <= table->keys - table->isolated) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + case CUDD_REORDER_WINDOW2: + case CUDD_REORDER_WINDOW3: + case CUDD_REORDER_WINDOW4: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + result = cuddWindowReorder(table,lower,upper,method); + break; + case CUDD_REORDER_ANNEALING: + result = cuddAnnealing(table,lower,upper); + break; + case CUDD_REORDER_GENETIC: + result = cuddGa(table,lower,upper); + break; + case CUDD_REORDER_LINEAR: + result = cuddLinearAndSifting(table,lower,upper); + break; + case CUDD_REORDER_LINEAR_CONVERGE: + do { + initialSize = table->keys - table->isolated; + result = cuddLinearAndSifting(table,lower,upper); + if (initialSize <= table->keys - table->isolated) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + case CUDD_REORDER_EXACT: + result = cuddExact(table,lower,upper); + break; + case CUDD_REORDER_LAZY_SIFT: + result = ddGroupSifting(table,lower,upper,ddVarGroupCheck, + DD_LAZY_SIFT); + break; + default: + return(0); + } + } + + /* Create a single group for all the variables that were sifted, + ** so that they will be treated as a single block by successive + ** invocations of ddGroupSifting. + */ + ddMergeGroups(table,treenode,lower,upper); + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddReorderChildren:"); +#endif + + return(result); + +} /* end of ddReorderChildren */ + + +/**Function******************************************************************** + + Synopsis [Finds the lower and upper bounds of the group represented + by treenode.] + + Description [Finds the lower and upper bounds of the group + represented by treenode. From the index and size fields we need to + derive the current positions, and find maximum and minimum.] + + SideEffects [The bounds are returned as side effects.] + + SeeAlso [] + +******************************************************************************/ +static void +ddFindNodeHiLo( + DdManager * table, + MtrNode * treenode, + int * lower, + int * upper) +{ + int low; + int high; + + /* Check whether no variables in this group already exist. + ** If so, return immediately. The calling procedure will know from + ** the values of upper that no reordering is needed. + */ + if ((int) treenode->low >= table->size) { + *lower = table->size; + *upper = -1; + return; + } + + *lower = low = (unsigned int) table->perm[treenode->index]; + high = (int) (low + treenode->size - 1); + + if (high >= table->size) { + /* This is the case of a partially existing group. The aim is to + ** reorder as many variables as safely possible. If the tree + ** node is terminal, we just reorder the subset of the group + ** that is currently in existence. If the group has + ** subgroups, then we only reorder those subgroups that are + ** fully instantiated. This way we avoid breaking up a group. + */ + MtrNode *auxnode = treenode->child; + if (auxnode == NULL) { + *upper = (unsigned int) table->size - 1; + } else { + /* Search the subgroup that strands the table->size line. + ** If the first group starts at 0 and goes past table->size + ** upper will get -1, thus correctly signaling that no reordering + ** should take place. + */ + while (auxnode != NULL) { + int thisLower = table->perm[auxnode->low]; + int thisUpper = thisLower + auxnode->size - 1; + if (thisUpper >= table->size && thisLower < table->size) + *upper = (unsigned int) thisLower - 1; + auxnode = auxnode->younger; + } + } + } else { + /* Normal case: All the variables of the group exist. */ + *upper = (unsigned int) high; + } + +#ifdef DD_DEBUG + /* Make sure that all variables in group are contiguous. */ + assert(treenode->size >= *upper - *lower + 1); +#endif + + return; + +} /* end of ddFindNodeHiLo */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the variables + according to the number of keys in the subtables. Returns the + difference in number of keys between the two variables being + compared.] + + SideEffects [None] + +******************************************************************************/ +static int +ddUniqueCompareGroup( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of ddUniqueCompareGroup */ + + +/**Function******************************************************************** + + Synopsis [Sifts from treenode->low to treenode->high.] + + Description [Sifts from treenode->low to treenode->high. If + croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the + end of the initial sifting. If a group is created, it is then sifted + again. After sifting one variable, the group that contains it is + dissolved. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSifting( + DdManager * table, + int lower, + int upper, + DD_CHKFP checkFunction, + int lazyFlag) +{ + int *var; + int i,j,x,xInit; + int nvars; + int classes; + int result; + int *sifted; + int merged; + int dissolve; +#ifdef DD_STATS + unsigned previousSize; +#endif + int xindex; + + nvars = table->size; + + /* Order variables to sift. */ + entry = NULL; + sifted = NULL; + var = ALLOC(int,nvars); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; + } + entry = ALLOC(int,nvars); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; + } + sifted = ALLOC(int,nvars); + if (sifted == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; + } + + /* Here we consider only one representative for each group. */ + for (i = 0, classes = 0; i < nvars; i++) { + sifted[i] = 0; + x = table->perm[i]; + if ((unsigned) x >= table->subtables[x].next) { + entry[i] = table->subtables[x].keys; + var[classes] = i; + classes++; + } + } + + qsort((void *)var,classes,sizeof(int), + (DD_QSFP) ddUniqueCompareGroup); + + if (lazyFlag) { + for (i = 0; i < nvars; i ++) { + ddResetVarHandled(table, i); + } + } + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime + table->reordTime + > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + xindex = var[i]; + if (sifted[xindex] == 1) /* variable already sifted as part of group */ + continue; + x = table->perm[xindex]; /* find current level of this variable */ + + if (x < lower || x > upper || table->subtables[x].bindVar == 1) + continue; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif +#ifdef DD_DEBUG + /* x is bottom of group */ + assert((unsigned) x >= table->subtables[x].next); +#endif + if ((unsigned) x == table->subtables[x].next) { + dissolve = 1; + result = ddGroupSiftingAux(table,x,lower,upper,checkFunction, + lazyFlag); + } else { + dissolve = 0; + result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); + } + if (!result) goto ddGroupSiftingOutOfMem; + + /* check for aggregation */ + merged = 0; + if (lazyFlag == 0 && table->groupcheck == CUDD_GROUP_CHECK7) { + x = table->perm[xindex]; /* find current level */ + if ((unsigned) x == table->subtables[x].next) { /* not part of a group */ + if (x != upper && sifted[table->invperm[x+1]] == 0 && + (unsigned) x+1 == table->subtables[x+1].next) { + if (ddSecDiffCheck(table,x,x+1)) { + merged =1; + ddCreateGroup(table,x,x+1); + } + } + if (x != lower && sifted[table->invperm[x-1]] == 0 && + (unsigned) x-1 == table->subtables[x-1].next) { + if (ddSecDiffCheck(table,x-1,x)) { + merged =1; + ddCreateGroup(table,x-1,x); + } + } + } + } + + if (merged) { /* a group was created */ + /* move x to bottom of group */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + /* sift */ + result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); + if (!result) goto ddGroupSiftingOutOfMem; +#ifdef DD_STATS + if (table->keys < previousSize + table->isolated) { + (void) fprintf(table->out,"_"); + } else if (table->keys > previousSize + table->isolated) { + (void) fprintf(table->out,"^"); + } else { + (void) fprintf(table->out,"*"); + } + fflush(table->out); + } else { + if (table->keys < previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > previousSize + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + /* Mark variables in the group just sifted. */ + x = table->perm[xindex]; + if ((unsigned) x != table->subtables[x].next) { + xInit = x; + do { + j = table->invperm[x]; + sifted[j] = 1; + x = table->subtables[x].next; + } while (x != xInit); + + /* Dissolve the group if it was created. */ + if (lazyFlag == 0 && dissolve) { + do { + j = table->subtables[x].next; + table->subtables[x].next = x; + x = j; + } while (x != xInit); + } + } + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddGroupSifting:"); +#endif + + if (lazyFlag) ddSetVarHandled(table, xindex); + } /* for */ + + FREE(sifted); + FREE(var); + FREE(entry); + + return(1); + +ddGroupSiftingOutOfMem: + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + if (sifted != NULL) FREE(sifted); + + return(0); + +} /* end of ddGroupSifting */ + + +/**Function******************************************************************** + + Synopsis [Creates a group encompassing variables from x to y in the + DD table.] + + Description [Creates a group encompassing variables from x to y in the + DD table. In the current implementation it must be y == x+1. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static void +ddCreateGroup( + DdManager * table, + int x, + int y) +{ + int gybot; + +#ifdef DD_DEBUG + assert(y == x+1); +#endif + + /* Find bottom of second group. */ + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + + /* Link groups. */ + table->subtables[x].next = y; + table->subtables[gybot].next = x; + + return; + +} /* ddCreateGroup */ + + +/**Function******************************************************************** + + Synopsis [Sifts one variable up and down until it has taken all + positions. Checks for aggregation.] + + Description [Sifts one variable up and down until it has taken all + positions. Checks for aggregation. There may be at most two sweeps, + even if the group grows. Assumes that x is either an isolated + variable, or it is the bottom of a group. All groups may not have + been found. The variable being moved is returned to the best position + seen during sifting. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh, + DD_CHKFP checkFunction, + int lazyFlag) +{ + Move *move; + Move *moves; /* list of moves */ + int initialSize; + int result; + int y; + int topbot; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out, + "ddGroupSiftingAux from %d to %d\n",xLow,xHigh); + assert((unsigned) x >= table->subtables[x].next); /* x is bottom of group */ +#endif + + initialSize = table->keys - table->isolated; + moves = NULL; + + originalSize = initialSize; /* for lazy sifting */ + + /* If we have a singleton, we check for aggregation in both + ** directions before we sift. + */ + if ((unsigned) x == table->subtables[x].next) { + /* Will go down first, unless x == xHigh: + ** Look for aggregation above x. + */ + for (y = x; y > xLow; y--) { + if (!checkFunction(table,y-1,y)) + break; + topbot = table->subtables[y-1].next; /* find top of y-1's group */ + table->subtables[y-1].next = y; + table->subtables[x].next = topbot; /* x is bottom of group so its */ + /* next is top of y-1's group */ + y = topbot + 1; /* add 1 for y--; new y is top of group */ + } + /* Will go up first unless x == xlow: + ** Look for aggregation below x. + */ + for (y = x; y < xHigh; y++) { + if (!checkFunction(table,y,y+1)) + break; + /* find bottom of y+1's group */ + topbot = y + 1; + while ((unsigned) topbot < table->subtables[topbot].next) { + topbot = table->subtables[topbot].next; + } + table->subtables[topbot].next = table->subtables[y].next; + table->subtables[y].next = y + 1; + y = topbot - 1; /* subtract 1 for y++; new y is bottom of group */ + } + } + + /* Now x may be in the middle of a group. + ** Find bottom of x's group. + */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + + if (x == xLow) { /* Sift down */ +#ifdef DD_DEBUG + /* x must be a singleton */ + assert((unsigned) x == table->subtables[x].next); +#endif + if (x == xHigh) return(1); /* just one variable */ + + if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_DOWN,lazyFlag); +#ifdef DD_DEBUG + assert(table->keys - table->isolated <= (unsigned) initialSize); +#endif + if (!result) goto ddGroupSiftingAuxOutOfMem; + + } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ +#ifdef DD_DEBUG + /* x is bottom of group */ + assert((unsigned) x >= table->subtables[x].next); +#endif + /* Find top of x's group */ + x = table->subtables[x].next; + + if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + /* at this point x == xLow, unless early term */ + + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_UP,lazyFlag); +#ifdef DD_DEBUG + assert(table->keys - table->isolated <= (unsigned) initialSize); +#endif + if (!result) goto ddGroupSiftingAuxOutOfMem; + + } else if (x - xLow > xHigh - x) { /* must go down first: shorter */ + if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + /* Find top of group */ + if (moves) { + x = moves->y; + } + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + x = table->subtables[x].next; +#ifdef DD_DEBUG + /* x should be the top of a group */ + assert((unsigned) x <= table->subtables[x].next); +#endif + + if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_UP,lazyFlag); +#ifdef DD_DEBUG + assert(table->keys - table->isolated <= (unsigned) initialSize); +#endif + if (!result) goto ddGroupSiftingAuxOutOfMem; + + } else { /* moving up first: shorter */ + /* Find top of x's group */ + x = table->subtables[x].next; + + if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + if (moves) { + x = moves->x; + } + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; +#ifdef DD_DEBUG + /* x is bottom of a group */ + assert((unsigned) x >= table->subtables[x].next); +#endif + + if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_DOWN,lazyFlag); +#ifdef DD_DEBUG + assert(table->keys - table->isolated <= (unsigned) initialSize); +#endif + if (!result) goto ddGroupSiftingAuxOutOfMem; + } + + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(1); + +ddGroupSiftingAuxOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(0); + +} /* end of ddGroupSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much.] + + Description [Sifts up a variable until either it reaches position + xLow or the size of the DD heap increases too much. Assumes that y is + the top of a group (or a singleton). Checks y for aggregation to the + adjacent variables. Records all the moves that are appended to the + list of moves received as input and returned as a side effect. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSiftingUp( + DdManager * table, + int y, + int xLow, + DD_CHKFP checkFunction, + Move ** moves) +{ + Move *move; + int x; + int size; + int i; + int gxtop,gybot; + int limitSize; + int xindex, yindex; + int zindex; + int z; + int isolated; + int L; /* lower bound on DD size */ +#ifdef DD_DEBUG + int checkL; +#endif + + yindex = table->invperm[y]; + + /* Initialize the lower bound. + ** The part of the DD below the bottom of y's group will not change. + ** The part of the DD above y that does not interact with any + ** variable of y's group will not change. + ** The rest may vanish in the best case, except for + ** the nodes at level xLow, which will not vanish, regardless. + ** What we use here is not really a lower bound, because we ignore + ** the interactions with all variables except y. + */ + limitSize = L = table->keys - table->isolated; + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L -= table->subtables[z].keys - isolated; + } + } + + x = cuddNextLow(table,y); + while (x >= xLow && L <= limitSize) { +#ifdef DD_DEBUG + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + if (pr > 0 && L != checkL) { + (void) fprintf(table->out, + "Inaccurate lower bound: L = %d checkL = %d\n", + L, checkL); + } +#endif + gxtop = table->subtables[x].next; + if (checkFunction(table,x,y)) { + /* Group found, attach groups */ + table->subtables[x].next = y; + i = table->subtables[y].next; + while (table->subtables[i].next != (unsigned) y) + i = table->subtables[i].next; + table->subtables[i].next = gxtop; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_NEWNODE; + move->size = table->keys - table->isolated; + move->next = *moves; + *moves = move; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y are self groups */ + xindex = table->invperm[x]; + size = cuddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); +#endif + if (size == 0) goto ddGroupSiftingUpOutOfMem; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_DEFAULT; + move->size = size; + move->next = *moves; + *moves = move; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out, + "ddGroupSiftingUp (2 single groups):\n"); +#endif + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } else { /* Group move */ + size = ddGroupMove(table,x,y,moves); + if (size == 0) goto ddGroupSiftingUpOutOfMem; + /* Update the lower bound. */ + z = (*moves)->y; + do { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L += table->subtables[z].keys - isolated; + } + z = table->subtables[z].next; + } while (z != (int) (*moves)->y); + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } + y = gxtop; + x = cuddNextLow(table,y); + } + + return(1); + +ddGroupSiftingUpOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of ddGroupSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts down a variable until it reaches position xHigh.] + + Description [Sifts down a variable until it reaches position xHigh. + Assumes that x is the bottom of a group (or a singleton). Records + all the moves. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSiftingDown( + DdManager * table, + int x, + int xHigh, + DD_CHKFP checkFunction, + Move ** moves) +{ + Move *move; + int y; + int size; + int limitSize; + int gxtop,gybot; + int R; /* upper bound on node decrease */ + int xindex, yindex; + int isolated, allVars; + int z; + int zindex; +#ifdef DD_DEBUG + int checkR; +#endif + + /* If the group consists of simple variables, there is no point in + ** sifting it down. This check is redundant if the projection functions + ** do not have external references, because the computation of the + ** lower bound takes care of the problem. It is necessary otherwise to + ** prevent the sifting down of simple variables. */ + y = x; + allVars = 1; + do { + if (table->subtables[y].keys != 1) { + allVars = 0; + break; + } + y = table->subtables[y].next; + } while (table->subtables[y].next != (unsigned) x); + if (allVars) + return(1); + + /* Initialize R. */ + xindex = table->invperm[x]; + gxtop = table->subtables[x].next; + limitSize = size = table->keys - table->isolated; + R = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } + + y = cuddNextHigh(table,x); + while (y <= xHigh && size - R < limitSize) { +#ifdef DD_DEBUG + gxtop = table->subtables[x].next; + checkR = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + assert(R >= checkR); +#endif + /* Find bottom of y group. */ + gybot = table->subtables[y].next; + while (table->subtables[gybot].next != (unsigned) y) + gybot = table->subtables[gybot].next; + + if (checkFunction(table,x,y)) { + /* Group found: attach groups and record move. */ + gxtop = table->subtables[x].next; + table->subtables[x].next = y; + table->subtables[gybot].next = gxtop; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_NEWNODE; + move->size = table->keys - table->isolated; + move->next = *moves; + *moves = move; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y are self groups */ + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); +#endif + if (size == 0) goto ddGroupSiftingDownOutOfMem; + + /* Record move. */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_DEFAULT; + move->size = size; + move->next = *moves; + *moves = move; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out, + "ddGroupSiftingDown (2 single groups):\n"); +#endif + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + + x = y; + y = cuddNextHigh(table,x); + } else { /* Group move */ + /* Update upper bound on node decrease: first phase. */ + gxtop = table->subtables[x].next; + z = gxtop + 1; + do { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R -= table->subtables[z].keys - isolated; + } + z++; + } while (z <= gybot); + size = ddGroupMove(table,x,y,moves); + if (size == 0) goto ddGroupSiftingDownOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + + /* Update upper bound on node decrease: second phase. */ + gxtop = table->subtables[gybot].next; + for (z = gxtop + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } + } + x = gybot; + y = cuddNextHigh(table,x); + } + + return(1); + +ddGroupSiftingDownOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + + return(0); + +} /* end of ddGroupSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Swaps two groups and records the move.] + + Description [Swaps two groups and records the move. Returns the + number of keys in the DD table in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupMove( + DdManager * table, + int x, + int y, + Move ** moves) +{ + Move *move; + int size; + int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + int swapx,swapy; +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + int initialSize,bestSize; +#endif + +#ifdef DD_DEBUG + /* We assume that x < y */ + assert(x < y); +#endif + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtables[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtables[ybot].next) + ybot = table->subtables[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + initialSize = bestSize = table->keys - table->isolated; +#endif + /* Sift the variables of the second group up through the first group */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddGroupMoveOutOfMem; +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (size < bestSize) + bestSize = size; +#endif + swapx = x; swapy = y; + y = x; + x = cuddNextLow(table,y); + } + y = ytop + i; + x = cuddNextLow(table,y); + } +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if ((bestSize < initialSize) && (bestSize < size)) + (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); +#endif + + /* fix groups */ + y = xtop; /* ytop is now where xtop used to be */ + for (i = 0; i < ysize - 1; i++) { + table->subtables[y].next = cuddNextHigh(table,y); + y = cuddNextHigh(table,y); + } + table->subtables[y].next = xtop; /* y is bottom of its group, join */ + /* it to top of its group */ + x = cuddNextHigh(table,y); + newxtop = x; + for (i = 0; i < xsize - 1; i++) { + table->subtables[x].next = cuddNextHigh(table,x); + x = cuddNextHigh(table,x); + } + table->subtables[x].next = newxtop; /* x is bottom of its group, join */ + /* it to top of its group */ +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddGroupMove:\n"); +#endif + + /* Store group move */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupMoveOutOfMem; + move->x = swapx; + move->y = swapy; + move->flags = MTR_DEFAULT; + move->size = table->keys - table->isolated; + move->next = *moves; + *moves = move; + + return(table->keys - table->isolated); + +ddGroupMoveOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of ddGroupMove */ + + +/**Function******************************************************************** + + Synopsis [Undoes the swap two groups.] + + Description [Undoes the swap two groups. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupMoveBackward( + DdManager * table, + int x, + int y) +{ + int size; + int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + + +#ifdef DD_DEBUG + /* We assume that x < y */ + assert(x < y); +#endif + + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtables[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtables[ybot].next) + ybot = table->subtables[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + + /* Sift the variables of the second group up through the first group */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) + return(0); + y = x; + x = cuddNextLow(table,y); + } + y = ytop + i; + x = cuddNextLow(table,y); + } + + /* fix groups */ + y = xtop; + for (i = 0; i < ysize - 1; i++) { + table->subtables[y].next = cuddNextHigh(table,y); + y = cuddNextHigh(table,y); + } + table->subtables[y].next = xtop; /* y is bottom of its group, join */ + /* to its top */ + x = cuddNextHigh(table,y); + newxtop = x; + for (i = 0; i < xsize - 1; i++) { + table->subtables[x].next = cuddNextHigh(table,x); + x = cuddNextHigh(table,x); + } + table->subtables[x].next = newxtop; /* x is bottom of its group, join */ + /* to its top */ +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddGroupMoveBackward:\n"); +#endif + + return(1); + +} /* end of ddGroupMoveBackward */ + + +/**Function******************************************************************** + + Synopsis [Determines the best position for a variables and returns + it there.] + + Description [Determines the best position for a variables and returns + it there. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSiftingBackward( + DdManager * table, + Move * moves, + int size, + int upFlag, + int lazyFlag) +{ + Move *move; + int res; + Move *end_move; + int diff, tmp_diff; + int index; + unsigned int pairlev; + + if (lazyFlag) { + end_move = NULL; + + /* Find the minimum size, and the earliest position at which it + ** was achieved. */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + end_move = move; + } else if (move->size == size) { + if (end_move == NULL) end_move = move; + } + } + + /* Find among the moves that give minimum size the one that + ** minimizes the distance from the corresponding variable. */ + if (moves != NULL) { + diff = Cudd_ReadSize(table) + 1; + index = (upFlag == 1) ? + table->invperm[moves->x] : table->invperm[moves->y]; + pairlev = + (unsigned) table->perm[Cudd_bddReadPairIndex(table, index)]; + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) { + if (upFlag == 1) { + tmp_diff = (move->x > pairlev) ? + move->x - pairlev : pairlev - move->x; + } else { + tmp_diff = (move->y > pairlev) ? + move->y - pairlev : pairlev - move->y; + } + if (tmp_diff < diff) { + diff = tmp_diff; + end_move = move; + } + } + } + } + } else { + /* Find the minimum size. */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + } + + /* In case of lazy sifting, end_move identifies the position at + ** which we want to stop. Otherwise, we stop as soon as we meet + ** the minimum size. */ + for (move = moves; move != NULL; move = move->next) { + if (lazyFlag) { + if (move == end_move) return(1); + } else { + if (move->size == size) return(1); + } + if ((table->subtables[move->x].next == move->x) && + (table->subtables[move->y].next == move->y)) { + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddGroupSiftingBackward:\n"); + assert(table->subtables[move->x].next == move->x); + assert(table->subtables[move->y].next == move->y); +#endif + } else { /* Group move necessary */ + if (move->flags == MTR_NEWNODE) { + ddDissolveGroup(table,(int)move->x,(int)move->y); + } else { + res = ddGroupMoveBackward(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + } + + } + + return(1); + +} /* end of ddGroupSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Merges groups in the DD table.] + + Description [Creates a single group from low to high and adjusts the + index field of the tree node.] + + SideEffects [None] + +******************************************************************************/ +static void +ddMergeGroups( + DdManager * table, + MtrNode * treenode, + int low, + int high) +{ + int i; + MtrNode *auxnode; + int saveindex; + int newindex; + + /* Merge all variables from low to high in one group, unless + ** this is the topmost group. In such a case we do not merge lest + ** we lose the symmetry information. */ + if (treenode != table->tree) { + for (i = low; i < high; i++) + table->subtables[i].next = i+1; + table->subtables[high].next = low; + } + + /* Adjust the index fields of the tree nodes. If a node is the + ** first child of its parent, then the parent may also need adjustment. */ + saveindex = treenode->index; + newindex = table->invperm[low]; + auxnode = treenode; + do { + auxnode->index = newindex; + if (auxnode->parent == NULL || + (int) auxnode->parent->index != saveindex) + break; + auxnode = auxnode->parent; + } while (1); + return; + +} /* end of ddMergeGroups */ + + +/**Function******************************************************************** + + Synopsis [Dissolves a group in the DD table.] + + Description [x and y are variables in a group to be cut in two. The cut + is to pass between x and y.] + + SideEffects [None] + +******************************************************************************/ +static void +ddDissolveGroup( + DdManager * table, + int x, + int y) +{ + int topx; + int boty; + + /* find top and bottom of the two groups */ + boty = y; + while ((unsigned) boty < table->subtables[boty].next) + boty = table->subtables[boty].next; + + topx = table->subtables[boty].next; + + table->subtables[boty].next = y; + table->subtables[x].next = topx; + + return; + +} /* end of ddDissolveGroup */ + + +/**Function******************************************************************** + + Synopsis [Pretends to check two variables for aggregation.] + + Description [Pretends to check two variables for aggregation. Always + returns 0.] + + SideEffects [None] + +******************************************************************************/ +static int +ddNoCheck( + DdManager * table, + int x, + int y) +{ + return(0); + +} /* end of ddNoCheck */ + + +/**Function******************************************************************** + + Synopsis [Checks two variables for aggregation.] + + Description [Checks two variables for aggregation. The check is based + on the second difference of the number of nodes as a function of the + layer. If the second difference is lower than a given threshold + (typically negative) then the two variables should be aggregated. + Returns 1 if the two variables pass the test; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSecDiffCheck( + DdManager * table, + int x, + int y) +{ + double Nx,Nx_1; + double Sx; + double threshold; + int xindex,yindex; + + if (x==0) return(0); + +#ifdef DD_STATS + secdiffcalls++; +#endif + Nx = (double) table->subtables[x].keys; + Nx_1 = (double) table->subtables[x-1].keys; + Sx = (table->subtables[y].keys/Nx) - (Nx/Nx_1); + + threshold = table->recomb / 100.0; + if (Sx < threshold) { + xindex = table->invperm[x]; + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + (void) fprintf(table->out, + "Second difference for %d = %g Pos(%d)\n", + table->invperm[x],Sx,x); +#endif +#ifdef DD_STATS + secdiff++; +#endif + return(1); + } else { +#ifdef DD_STATS + secdiffmisfire++; +#endif + return(0); + } + + } + return(0); + +} /* end of ddSecDiffCheck */ + + +/**Function******************************************************************** + + Synopsis [Checks for extended symmetry of x and y.] + + Description [Checks for extended symmetry of x and y. Returns 1 in + case of extended symmetry; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddExtSymmCheck( + DdManager * table, + int x, + int y) +{ + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10; + DdNode *one; + unsigned comple; /* f0 is complemented */ + int notproj; /* f is not a projection function */ + int arccount; /* number of arcs from layer x to layer y */ + int TotalRefCount; /* total reference count of layer y minus 1 */ + int counter; /* number of nodes of layer x that are allowed */ + /* to violate extended symmetry conditions */ + int arccounter; /* number of arcs into layer y that are allowed */ + /* to come from layers other than x */ + int i; + int xindex; + int yindex; + int res; + int slots; + DdNodePtr *list; + DdNode *sentinel = &(table->sentinel); + + xindex = table->invperm[x]; + yindex = table->invperm[y]; + + /* If the two variables do not interact, we do not want to merge them. */ + if (!cuddTestInteract(table,xindex,yindex)) + return(0); + +#ifdef DD_DEBUG + /* Checks that x and y do not contain just the projection functions. + ** With the test on interaction, these test become redundant, + ** because an isolated projection function does not interact with + ** any other variable. + */ + if (table->subtables[x].keys == 1) { + assert(table->vars[xindex]->ref != 1); + } + if (table->subtables[y].keys == 1) { + assert(table->vars[yindex]->ref != 1); + } +#endif + +#ifdef DD_STATS + extsymmcalls++; +#endif + + arccount = 0; + counter = (int) (table->subtables[x].keys * + (table->symmviolation/100.0) + 0.5); + one = DD_ONE(table); + + slots = table->subtables[x].slots; + list = table->subtables[x].nodelist; + for (i = 0; i < slots; i++) { + f = list[i]; + while (f != sentinel) { + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + f0 = Cudd_Regular(cuddE(f)); + comple = Cudd_IsComplement(cuddE(f)); + notproj = f1 != one || f0 != one || f->ref != (DdHalfWord) 1; + if (f1->index == (unsigned) yindex) { + arccount++; + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + if ((int) f0->index != yindex) { + /* If f is an isolated projection function it is + ** allowed to bypass layer y. + */ + if (notproj) { + if (counter == 0) + return(0); + counter--; /* f bypasses layer y */ + } + } + f11 = f10 = f1; + } + if ((int) f0->index == yindex) { + arccount++; + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + + /* Unless we are looking at a projection function + ** without external references except the one from the + ** table, we insist that f01 == f10 or f11 == f00 + */ + if (notproj) { + if (f01 != f10 && f11 != f00) { + if (counter == 0) + return(0); + counter--; + } + } + + f = f->next; + } /* while */ + } /* for */ + + /* Calculate the total reference counts of y */ + TotalRefCount = -1; /* -1 for projection function */ + slots = table->subtables[y].slots; + list = table->subtables[y].nodelist; + for (i = 0; i < slots; i++) { + f = list[i]; + while (f != sentinel) { + TotalRefCount += f->ref; + f = f->next; + } + } + + arccounter = (int) (table->subtables[y].keys * + (table->arcviolation/100.0) + 0.5); + res = arccount >= TotalRefCount - arccounter; + +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (res) { + (void) fprintf(table->out, + "Found extended symmetry! x = %d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); + } +#endif + +#ifdef DD_STATS + if (res) + extsymm++; +#endif + return(res); + +} /* end ddExtSymmCheck */ + + +/**Function******************************************************************** + + Synopsis [Checks for grouping of x and y.] + + Description [Checks for grouping of x and y. Returns 1 in + case of grouping; 0 otherwise. This function is used for lazy sifting.] + + SideEffects [None] + +******************************************************************************/ +static int +ddVarGroupCheck( + DdManager * table, + int x, + int y) +{ + int xindex = table->invperm[x]; + int yindex = table->invperm[y]; + + if (Cudd_bddIsVarToBeUngrouped(table, xindex)) return(0); + + if (Cudd_bddReadPairIndex(table, xindex) == yindex) { + if (ddIsVarHandled(table, xindex) || + ddIsVarHandled(table, yindex)) { + if (Cudd_bddIsVarToBeGrouped(table, xindex) || + Cudd_bddIsVarToBeGrouped(table, yindex) ) { + if (table->keys - table->isolated <= originalSize) { + return(1); + } + } + } + } + + return(0); + +} /* end of ddVarGroupCheck */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable to already handled.] + + Description [Sets a variable to already handled. This function is used + for lazy sifting.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static int +ddSetVarHandled( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].varHandled = 1; + return(1); + +} /* end of ddSetVarHandled */ + + +/**Function******************************************************************** + + Synopsis [Resets a variable to be processed.] + + Description [Resets a variable to be processed. This function is used + for lazy sifting.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static int +ddResetVarHandled( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].varHandled = 0; + return(1); + +} /* end of ddResetVarHandled */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variables is already handled.] + + Description [Checks whether a variables is already handled. This + function is used for lazy sifting.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static int +ddIsVarHandled( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(-1); + return dd->subtables[dd->perm[index]].varHandled; + +} /* end of ddIsVarHandled */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddHarwell.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddHarwell.c new file mode 100644 index 000000000..323db91d3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddHarwell.c @@ -0,0 +1,568 @@ +/**CFile*********************************************************************** + + FileName [cuddHarwell.c] + + PackageName [cudd] + + Synopsis [Function to read a matrix in Harwell format.] + + Description [External procedures included in this module: +
                +
              • Cudd_addHarwell() +
              + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddHarwell.c,v 1.10 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads in a matrix in the format of the Harwell-Boeing + benchmark suite.] + + Description [Reads in a matrix in the format of the Harwell-Boeing + benchmark suite. The variables are ordered as follows: +
              + x\[0\] y\[0\] x\[1\] y\[1\] ... +
              + 0 is the most significant bit. On input, nx and ny hold the numbers + of row and column variables already in existence. On output, they + hold the numbers of row and column variables actually used by the + matrix. m and n are set to the numbers of rows and columns of the + matrix. Their values on input are immaterial. Returns 1 on + success; 0 otherwise. The ADD for the sparse matrix is returned in + E, and its reference count is > 0.] + + SideEffects [None] + + SeeAlso [Cudd_addRead Cudd_bddRead] + +******************************************************************************/ +int +Cudd_addHarwell( + FILE * fp /* pointer to the input file */, + DdManager * dd /* DD manager */, + DdNode ** E /* characteristic function of the graph */, + DdNode *** x /* array of row variables */, + DdNode *** y /* array of column variables */, + DdNode *** xn /* array of complemented row variables */, + DdNode *** yn_ /* array of complemented column variables */, + int * nx /* number or row variables */, + int * ny /* number or column variables */, + int * m /* number of rows */, + int * n /* number of columns */, + int bx /* first index of row variables */, + int sx /* step of row variables */, + int by /* first index of column variables */, + int sy /* step of column variables */, + int pr /* verbosity level */) +{ + DdNode *one, *zero; + DdNode *w; + DdNode *cubex, *cubey, *minterm1; + int u, v, err, i, j, nv; + double val; + DdNode **lx, **ly, **lxn, **lyn; /* local copies of x, y, xn, yn_ */ + int lnx, lny; /* local copies of nx and ny */ + char title[73], key[9], mxtype[4], rhstyp[4]; + int totcrd, ptrcrd, indcrd, valcrd, rhscrd, + nrow, ncol, nnzero, neltvl, + nrhs, nrhsix; + int *colptr, *rowind; +#if 0 + int nguess, nexact; + int *rhsptr, *rhsind; +#endif + + if (*nx < 0 || *ny < 0) return(0); + + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + /* Read the header */ + err = fscanf(fp, "%72c %8c", title, key); + if (err == EOF) { + return(0); + } else if (err != 2) { + return(0); + } + title[72] = (char) 0; + key[8] = (char) 0; + + err = fscanf(fp, "%d %d %d %d %d", &totcrd, &ptrcrd, &indcrd, + &valcrd, &rhscrd); + if (err == EOF) { + return(0); + } else if (err != 5) { + return(0); + } + + err = fscanf(fp, "%3s %d %d %d %d", mxtype, &nrow, &ncol, + &nnzero, &neltvl); + if (err == EOF) { + return(0); + } else if (err != 5) { + return(0); + } + + /* Skip FORTRAN formats */ + if (rhscrd == 0) { + err = fscanf(fp, "%*s %*s %*s \n"); + } else { + err = fscanf(fp, "%*s %*s %*s %*s \n"); + } + if (err == EOF) { + return(0); + } else if (err != 0) { + return(0); + } + + /* Print out some stuff if requested to be verbose */ + if (pr>0) { + (void) fprintf(dd->out,"%s: type %s, %d rows, %d columns, %d entries\n", key, + mxtype, nrow, ncol, nnzero); + if (pr>1) (void) fprintf(dd->out,"%s\n", title); + } + + /* Check matrix type */ + if (mxtype[0] != 'R' || mxtype[1] != 'U' || mxtype[2] != 'A') { + (void) fprintf(dd->err,"%s: Illegal matrix type: %s\n", + key, mxtype); + return(0); + } + if (neltvl != 0) return(0); + + /* Read optional 5-th line */ + if (rhscrd != 0) { + err = fscanf(fp, "%3c %d %d", rhstyp, &nrhs, &nrhsix); + if (err == EOF) { + return(0); + } else if (err != 3) { + return(0); + } + rhstyp[3] = (char) 0; + if (rhstyp[0] != 'F') { + (void) fprintf(dd->err, + "%s: Sparse right-hand side not yet supported\n", key); + return(0); + } + if (pr>0) (void) fprintf(dd->out,"%d right-hand side(s)\n", nrhs); + } else { + nrhs = 0; + } + + /* Compute the number of variables */ + + /* row and column numbers start from 0 */ + u = nrow - 1; + for (i=0; u > 0; i++) { + u >>= 1; + } + lnx = i; + if (nrhs == 0) { + v = ncol - 1; + } else { + v = 2* (ddMax(ncol, nrhs) - 1); + } + for (i=0; v > 0; i++) { + v >>= 1; + } + lny = i; + + /* Allocate or reallocate arrays for variables as needed */ + if (*nx == 0) { + if (lnx > 0) { + *x = lx = ALLOC(DdNode *,lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *xn = lxn = ALLOC(DdNode *,lnx); + if (lxn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + *x = *xn = NULL; + } + } else if (lnx > *nx) { + *x = lx = REALLOC(DdNode *, *x, lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *xn = lxn = REALLOC(DdNode *, *xn, lnx); + if (lxn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + lx = *x; + lxn = *xn; + } + if (*ny == 0) { + if (lny >0) { + *y = ly = ALLOC(DdNode *,lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *yn_ = lyn = ALLOC(DdNode *,lny); + if (lyn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + *y = *yn_ = NULL; + } + } else if (lny > *ny) { + *y = ly = REALLOC(DdNode *, *y, lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *yn_ = lyn = REALLOC(DdNode *, *yn_, lny); + if (lyn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + ly = *y; + lyn = *yn_; + } + + /* Create new variables as needed */ + for (i= *nx,nv=bx+(*nx)*sx; i < lnx; i++,nv+=sx) { + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); + cuddRef(lx[i]); + do { + dd->reordered = 0; + lxn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lxn[i] == NULL) return(0); + cuddRef(lxn[i]); + } + for (i= *ny,nv=by+(*ny)*sy; i < lny; i++,nv+=sy) { + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); + do { + dd->reordered = 0; + lyn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lyn[i] == NULL) return(0); + cuddRef(lyn[i]); + } + + /* Update matrix parameters */ + *nx = lnx; + *ny = lny; + *m = nrow; + if (nrhs == 0) { + *n = ncol; + } else { + *n = (1 << (lny - 1)) + nrhs; + } + + /* Read structure data */ + colptr = ALLOC(int, ncol+1); + if (colptr == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + rowind = ALLOC(int, nnzero); + if (rowind == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + + for (i=0; ierr,"%s: Unexpected colptr[0] (%d)\n", + key,colptr[0]); + FREE(colptr); + FREE(rowind); + return(0); + } + for (i=0; i=0; nv--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + FREE(colptr); + FREE(rowind); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubey); + cubey = w; + v >>= 1; + } + for (i=colptr[j]; i=0; nv--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + FREE(colptr); + FREE(rowind); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubex); + cubex = w; + u >>= 1; + } + minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); + if (minterm1 == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + FREE(colptr); + FREE(rowind); + return(0); + } + cuddRef(minterm1); + Cudd_RecursiveDeref(dd, cubex); + w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + FREE(colptr); + FREE(rowind); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, *E); + *E = w; + } + Cudd_RecursiveDeref(dd, cubey); + } + FREE(colptr); + FREE(rowind); + + /* Read right-hand sides */ + for (j=0; j=0; nv--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubey); + cubey = w; + v >>= 1; + } + for (i=0; i=0; nv--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubex); + cubex = w; + u >>= 1; + } + minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); + if (minterm1 == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + return(0); + } + cuddRef(minterm1); + Cudd_RecursiveDeref(dd, cubex); + w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, *E); + *E = w; + } + Cudd_RecursiveDeref(dd, cubey); + } + + return(1); + +} /* end of Cudd_addHarwell */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddInit.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddInit.c new file mode 100644 index 000000000..12830bdeb --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddInit.c @@ -0,0 +1,308 @@ +/**CFile*********************************************************************** + + FileName [cuddInit.c] + + PackageName [cudd] + + Synopsis [Functions to initialize and shut down the DD manager.] + + Description [External procedures included in this module: +
                +
              • Cudd_Init() +
              • Cudd_Quit() +
              + Internal procedures included in this module: +
                +
              • cuddZddInitUniv() +
              • cuddZddFreeUniv() +
              + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddInit.c,v 1.34 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Creates a new DD manager.] + + Description [Creates a new DD manager, initializes the table, the + basic constants and the projection functions. If maxMemory is 0, + Cudd_Init decides suitable values for the maximum size of the cache + and for the limit for fast unique table growth based on the available + memory. Returns a pointer to the manager if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Quit] + +******************************************************************************/ +DdManager * +Cudd_Init( + unsigned int numVars /* initial number of BDD variables (i.e., subtables) */, + unsigned int numVarsZ /* initial number of ZDD variables (i.e., subtables) */, + unsigned int numSlots /* initial size of the unique tables */, + unsigned int cacheSize /* initial size of the cache */, + unsigned long maxMemory /* target maximum memory occupation */) +{ + DdManager *unique; + int i,result; + DdNode *one, *zero; + unsigned int maxCacheSize; + unsigned int looseUpTo; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (maxMemory == 0) { + maxMemory = getSoftDataLimit(); + } + looseUpTo = (unsigned int) ((maxMemory / sizeof(DdNode)) / + DD_MAX_LOOSE_FRACTION); + unique = cuddInitTable(numVars,numVarsZ,numSlots,looseUpTo); + if (unique == NULL) return(NULL); + unique->maxmem = (unsigned long) maxMemory / 10 * 9; + maxCacheSize = (unsigned int) ((maxMemory / sizeof(DdCache)) / + DD_MAX_CACHE_FRACTION); + result = cuddInitCache(unique,cacheSize,maxCacheSize); + if (result == 0) return(NULL); + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + unique->stash = ALLOC(char,(maxMemory / DD_STASH_FRACTION) + 4); + MMoutOfMemory = saveHandler; + if (unique->stash == NULL) { + (void) fprintf(unique->err,"Unable to set aside memory\n"); + } + + /* Initialize constants. */ + unique->one = cuddUniqueConst(unique,1.0); + if (unique->one == NULL) return(0); + cuddRef(unique->one); + unique->zero = cuddUniqueConst(unique,0.0); + if (unique->zero == NULL) return(0); + cuddRef(unique->zero); +#ifdef HAVE_IEEE_754 + if (DD_PLUS_INF_VAL != DD_PLUS_INF_VAL * 3 || + DD_PLUS_INF_VAL != DD_PLUS_INF_VAL / 3) { + (void) fprintf(unique->err,"Warning: Crippled infinite values\n"); + (void) fprintf(unique->err,"Recompile without -DHAVE_IEEE_754\n"); + } +#endif + unique->plusinfinity = cuddUniqueConst(unique,DD_PLUS_INF_VAL); + if (unique->plusinfinity == NULL) return(0); + cuddRef(unique->plusinfinity); + unique->minusinfinity = cuddUniqueConst(unique,DD_MINUS_INF_VAL); + if (unique->minusinfinity == NULL) return(0); + cuddRef(unique->minusinfinity); + unique->background = unique->zero; + + /* The logical zero is different from the CUDD_VALUE_TYPE zero! */ + one = unique->one; + zero = Cudd_Not(one); + /* Create the projection functions. */ + unique->vars = ALLOC(DdNodePtr,unique->maxSize); + if (unique->vars == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < unique->size; i++) { + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) return(0); + cuddRef(unique->vars[i]); + } + + if (unique->sizeZ) + cuddZddInitUniv(unique); + + unique->memused += sizeof(DdNode *) * unique->maxSize; + + return(unique); + +} /* end of Cudd_Init */ + + +/**Function******************************************************************** + + Synopsis [Deletes resources associated with a DD manager.] + + Description [Deletes resources associated with a DD manager and + resets the global statistical counters. (Otherwise, another manaqger + subsequently created would inherit the stats of this one.)] + + SideEffects [None] + + SeeAlso [Cudd_Init] + +******************************************************************************/ +void +Cudd_Quit( + DdManager * unique) +{ + if (unique->stash != NULL) FREE(unique->stash); + cuddFreeTable(unique); + +} /* end of Cudd_Quit */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes the ZDD universe.] + + Description [Initializes the ZDD universe. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddZddFreeUniv] + +******************************************************************************/ +int +cuddZddInitUniv( + DdManager * zdd) +{ + DdNode *p, *res; + int i; + + zdd->univ = ALLOC(DdNodePtr, zdd->sizeZ); + if (zdd->univ == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + + res = DD_ONE(zdd); + cuddRef(res); + for (i = zdd->sizeZ - 1; i >= 0; i--) { + unsigned int index = zdd->invpermZ[i]; + p = res; + res = cuddUniqueInterZdd(zdd, index, p, p); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd,p); + FREE(zdd->univ); + return(0); + } + cuddRef(res); + cuddDeref(p); + zdd->univ[i] = res; + } + +#ifdef DD_VERBOSE + cuddZddP(zdd, zdd->univ[0]); +#endif + + return(1); + +} /* end of cuddZddInitUniv */ + + +/**Function******************************************************************** + + Synopsis [Frees the ZDD universe.] + + Description [Frees the ZDD universe.] + + SideEffects [None] + + SeeAlso [cuddZddInitUniv] + +******************************************************************************/ +void +cuddZddFreeUniv( + DdManager * zdd) +{ + if (zdd->univ) { + Cudd_RecursiveDerefZdd(zdd, zdd->univ[0]); + FREE(zdd->univ); + } + +} /* end of cuddZddFreeUniv */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddInt.h b/resources/3rdparty/cudd-2.5.0/cudd/cuddInt.h new file mode 100644 index 000000000..398b057f7 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddInt.h @@ -0,0 +1,1188 @@ +/**CHeaderFile***************************************************************** + + FileName [cuddInt.h] + + PackageName [cudd] + + Synopsis [Internal data structures of the CUDD package.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: cuddInt.h,v 1.142 2012/02/05 01:07:19 fabio Exp $] + +******************************************************************************/ + +#ifndef _CUDDINT +#define _CUDDINT + + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#ifdef DD_MIS +#include "array.h" +#include "list.h" +#include "st.h" +#include "espresso.h" +#include "node.h" +#ifdef SIS +#include "graph.h" +#include "astg.h" +#endif +#include "network.h" +#endif + +#include +#include "cudd.h" +#include "st.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) +# define DD_INLINE __inline__ +# if (__GNUC__ >2 || __GNUC_MINOR__ >=7) +# define DD_UNUSED __attribute__ ((__unused__)) +# else +# define DD_UNUSED +# endif +#else +# if defined(__cplusplus) +# define DD_INLINE inline +# else +# define DD_INLINE +# endif +# define DD_UNUSED +#endif + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_MAXREF ((DdHalfWord) ~0) + +#define DD_DEFAULT_RESIZE 10 /* how many extra variables */ + /* should be added when resizing */ +#define DD_MEM_CHUNK 1022 + +/* These definitions work for CUDD_VALUE_TYPE == double */ +#define DD_ONE_VAL (1.0) +#define DD_ZERO_VAL (0.0) +#define DD_EPSILON (1.0e-12) + +/* The definitions of +/- infinity in terms of HUGE_VAL work on +** the DECstations and on many other combinations of OS/compiler. +*/ +#ifdef HAVE_IEEE_754 +# define DD_PLUS_INF_VAL (HUGE_VAL) +#else +# define DD_PLUS_INF_VAL (10e301) +# define DD_CRI_HI_MARK (10e150) +# define DD_CRI_LO_MARK (-(DD_CRI_HI_MARK)) +#endif +#define DD_MINUS_INF_VAL (-(DD_PLUS_INF_VAL)) + +#define DD_NON_CONSTANT ((DdNode *) 1) /* for Cudd_bddIteConstant */ + +/* Unique table and cache management constants. */ +#define DD_MAX_SUBTABLE_DENSITY 4 /* tells when to resize a subtable */ +/* gc when this percent are dead (measured w.r.t. slots, not keys) +** The first limit (LO) applies normally. The second limit applies when +** the package believes more space for the unique table (i.e., more dead +** nodes) would improve performance, and the unique table is not already +** too large. The third limit applies when memory is low. +*/ +#define DD_GC_FRAC_LO DD_MAX_SUBTABLE_DENSITY * 0.25 +#define DD_GC_FRAC_HI DD_MAX_SUBTABLE_DENSITY * 1.0 +#define DD_GC_FRAC_MIN 0.2 +#define DD_MIN_HIT 30 /* resize cache when hit ratio + above this percentage (default) */ +#define DD_MAX_LOOSE_FRACTION 5 /* 1 / (max fraction of memory used for + unique table in fast growth mode) */ +#define DD_MAX_CACHE_FRACTION 3 /* 1 / (max fraction of memory used for + computed table if resizing enabled) */ +#define DD_STASH_FRACTION 64 /* 1 / (fraction of memory set + aside for emergencies) */ +#define DD_MAX_CACHE_TO_SLOTS_RATIO 4 /* used to limit the cache size */ + +/* Variable ordering default parameter values. */ +#define DD_SIFT_MAX_VAR 1000 +#define DD_SIFT_MAX_SWAPS 2000000 +#define DD_DEFAULT_RECOMB 0 +#define DD_MAX_REORDER_GROWTH 1.2 +#define DD_FIRST_REORDER 4004 /* 4 for the constants */ +#define DD_DYN_RATIO 2 /* when to dynamically reorder */ + +/* Primes for cache hash functions. */ +#define DD_P1 12582917 +#define DD_P2 4256249 +#define DD_P3 741457 +#define DD_P4 1618033999 + +/* Cache tags for 3-operand operators. These tags are stored in the +** least significant bits of the cache operand pointers according to +** the following scheme. The tag consists of two hex digits. Both digits +** must be even, so that they do not interfere with complementation bits. +** The least significant one is stored in Bits 3:1 of the f operand in the +** cache entry. Bit 1 is always 1, so that we can differentiate +** three-operand operations from one- and two-operand operations. +** Therefore, the least significant digit is one of {2,6,a,e}. The most +** significant digit occupies Bits 3:1 of the g operand in the cache +** entry. It can by any even digit between 0 and e. This gives a total +** of 5 bits for the tag proper, which means a maximum of 32 three-operand +** operations. */ +#define DD_ADD_ITE_TAG 0x02 +#define DD_BDD_AND_ABSTRACT_TAG 0x06 +#define DD_BDD_XOR_EXIST_ABSTRACT_TAG 0x0a +#define DD_BDD_ITE_TAG 0x0e +#define DD_ADD_BDD_DO_INTERVAL_TAG 0x22 +#define DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG 0x26 +#define DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG 0x2a +#define DD_BDD_COMPOSE_RECUR_TAG 0x2e +#define DD_ADD_COMPOSE_RECUR_TAG 0x42 +#define DD_ADD_NON_SIM_COMPOSE_TAG 0x46 +#define DD_EQUIV_DC_TAG 0x4a +#define DD_ZDD_ITE_TAG 0x4e +#define DD_ADD_ITE_CONSTANT_TAG 0x62 +#define DD_ADD_EVAL_CONST_TAG 0x66 +#define DD_BDD_ITE_CONSTANT_TAG 0x6a +#define DD_ADD_OUT_SUM_TAG 0x6e +#define DD_BDD_LEQ_UNLESS_TAG 0x82 +#define DD_ADD_TRIANGLE_TAG 0x86 +#define DD_BDD_MAX_EXP_TAG 0x8a + +/* Generator constants. */ +#define CUDD_GEN_CUBES 0 +#define CUDD_GEN_PRIMES 1 +#define CUDD_GEN_NODES 2 +#define CUDD_GEN_ZDD_PATHS 3 +#define CUDD_GEN_EMPTY 0 +#define CUDD_GEN_NONEMPTY 1 + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +struct DdGen { + DdManager *manager; + int type; + int status; + union { + struct { + int *cube; + CUDD_VALUE_TYPE value; + } cubes; + struct { + int *cube; + DdNode *ub; + } primes; + struct { + int size; + } nodes; + } gen; + struct { + int sp; + DdNode **stack; + } stack; + DdNode *node; +}; + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/* Hooks in CUDD are functions that the application registers with the +** manager so that they are called at appropriate times. The functions +** are passed the manager as argument; they should return 1 if +** successful and 0 otherwise. +*/ +typedef struct DdHook { /* hook list element */ + DD_HFP f; /* function to be called */ + struct DdHook *next; /* next element in the list */ +} DdHook; + +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +typedef long ptrint; +typedef unsigned long ptruint; +#else +typedef int ptrint; +typedef unsigned int ptruint; +#endif + +typedef DdNode *DdNodePtr; + +/* Generic local cache item. */ +typedef struct DdLocalCacheItem { + DdNode *value; +#ifdef DD_CACHE_PROFILE + ptrint count; +#endif + DdNode *key[1]; +} DdLocalCacheItem; + +/* Local cache. */ +typedef struct DdLocalCache { + DdLocalCacheItem *item; + unsigned int itemsize; + unsigned int keysize; + unsigned int slots; + int shift; + double lookUps; + double minHit; + double hits; + unsigned int maxslots; + DdManager *manager; + struct DdLocalCache *next; +} DdLocalCache; + +/* Generic hash item. */ +typedef struct DdHashItem { + struct DdHashItem *next; + ptrint count; + DdNode *value; + DdNode *key[1]; +} DdHashItem; + +/* Local hash table */ +typedef struct DdHashTable { + unsigned int keysize; + unsigned int itemsize; + DdHashItem **bucket; + DdHashItem *nextFree; + DdHashItem **memoryList; + unsigned int numBuckets; + int shift; + unsigned int size; + unsigned int maxsize; + DdManager *manager; +} DdHashTable; + +typedef struct DdCache { + DdNode *f,*g; /* DDs */ + ptruint h; /* either operator or DD */ + DdNode *data; /* already constructed DD */ +#ifdef DD_CACHE_PROFILE + ptrint count; +#endif +} DdCache; + +typedef struct DdSubtable { /* subtable for one index */ + DdNode **nodelist; /* hash table */ + int shift; /* shift for hash function */ + unsigned int slots; /* size of the hash table */ + unsigned int keys; /* number of nodes stored in this table */ + unsigned int maxKeys; /* slots * DD_MAX_SUBTABLE_DENSITY */ + unsigned int dead; /* number of dead nodes in this table */ + unsigned int next; /* index of next variable in group */ + int bindVar; /* flag to bind this variable to its level */ + /* Fields for lazy sifting. */ + Cudd_VariableType varType; /* variable type (ps, ns, pi) */ + int pairIndex; /* corresponding variable index (ps <-> ns) */ + int varHandled; /* flag: 1 means variable is already handled */ + Cudd_LazyGroupType varToBeGrouped; /* tells what grouping to apply */ +} DdSubtable; + +struct DdManager { /* specialized DD symbol table */ + /* Constants */ + DdNode sentinel; /* for collision lists */ + DdNode *one; /* constant 1 */ + DdNode *zero; /* constant 0 */ + DdNode *plusinfinity; /* plus infinity */ + DdNode *minusinfinity; /* minus infinity */ + DdNode *background; /* background value */ + /* Computed Table */ + DdCache *acache; /* address of allocated memory for cache */ + DdCache *cache; /* the cache-based computed table */ + unsigned int cacheSlots; /* total number of cache entries */ + int cacheShift; /* shift value for cache hash function */ + double cacheMisses; /* number of cache misses (since resizing) */ + double cacheHits; /* number of cache hits (since resizing) */ + double minHit; /* hit percentage above which to resize */ + int cacheSlack; /* slots still available for resizing */ + unsigned int maxCacheHard; /* hard limit for cache size */ + /* Unique Table */ + int size; /* number of unique subtables */ + int sizeZ; /* for ZDD */ + int maxSize; /* max number of subtables before resizing */ + int maxSizeZ; /* for ZDD */ + DdSubtable *subtables; /* array of unique subtables */ + DdSubtable *subtableZ; /* for ZDD */ + DdSubtable constants; /* unique subtable for the constants */ + unsigned int slots; /* total number of hash buckets */ + unsigned int keys; /* total number of BDD and ADD nodes */ + unsigned int keysZ; /* total number of ZDD nodes */ + unsigned int dead; /* total number of dead BDD and ADD nodes */ + unsigned int deadZ; /* total number of dead ZDD nodes */ + unsigned int maxLive; /* maximum number of live nodes */ + unsigned int minDead; /* do not GC if fewer than these dead */ + double gcFrac; /* gc when this fraction is dead */ + int gcEnabled; /* gc is enabled */ + unsigned int looseUpTo; /* slow growth beyond this limit */ + /* (measured w.r.t. slots, not keys) */ + unsigned int initSlots; /* initial size of a subtable */ + DdNode **stack; /* stack for iterative procedures */ + double allocated; /* number of nodes allocated */ + /* (not during reordering) */ + double reclaimed; /* number of nodes brought back from the dead */ + int isolated; /* isolated projection functions */ + int *perm; /* current variable perm. (index to level) */ + int *permZ; /* for ZDD */ + int *invperm; /* current inv. var. perm. (level to index) */ + int *invpermZ; /* for ZDD */ + DdNode **vars; /* projection functions */ + int *map; /* variable map for fast swap */ + DdNode **univ; /* ZDD 1 for each variable */ + int linearSize; /* number of rows and columns of linear */ + long *interact; /* interacting variable matrix */ + long *linear; /* linear transform matrix */ + /* Memory Management */ + DdNode **memoryList; /* memory manager for symbol table */ + DdNode *nextFree; /* list of free nodes */ + char *stash; /* memory reserve */ +#ifndef DD_NO_DEATH_ROW + DdNode **deathRow; /* queue for dereferencing */ + int deathRowDepth; /* number of slots in the queue */ + int nextDead; /* index in the queue */ + unsigned deadMask; /* mask for circular index update */ +#endif + /* General Parameters */ + CUDD_VALUE_TYPE epsilon; /* tolerance on comparisons */ + /* Dynamic Reordering Parameters */ + int reordered; /* flag set at the end of reordering */ + unsigned int reorderings; /* number of calls to Cudd_ReduceHeap */ + unsigned int maxReorderings;/* maximum number of calls to Cudd_ReduceHeap */ + int siftMaxVar; /* maximum number of vars sifted */ + int siftMaxSwap; /* maximum number of swaps per sifting */ + double maxGrowth; /* maximum growth during reordering */ + double maxGrowthAlt; /* alternate maximum growth for reordering */ + int reordCycle; /* how often to apply alternate threshold */ + int autoDyn; /* automatic dynamic reordering flag (BDD) */ + int autoDynZ; /* automatic dynamic reordering flag (ZDD) */ + Cudd_ReorderingType autoMethod; /* default reordering method */ + Cudd_ReorderingType autoMethodZ; /* default reordering method (ZDD) */ + int realign; /* realign ZDD order after BDD reordering */ + int realignZ; /* realign BDD order after ZDD reordering */ + unsigned int nextDyn; /* reorder if this size is reached */ + unsigned int countDead; /* if 0, count deads to trigger reordering */ + MtrNode *tree; /* variable group tree (BDD) */ + MtrNode *treeZ; /* variable group tree (ZDD) */ + Cudd_AggregationType groupcheck; /* used during group sifting */ + int recomb; /* used during group sifting */ + int symmviolation; /* used during group sifting */ + int arcviolation; /* used during group sifting */ + int populationSize; /* population size for GA */ + int numberXovers; /* number of crossovers for GA */ + unsigned int randomizeOrder; /* perturb the next reordering threshold */ + DdLocalCache *localCaches; /* local caches currently in existence */ + char *hooks; /* application-specific field (used by vis) */ + DdHook *preGCHook; /* hooks to be called before GC */ + DdHook *postGCHook; /* hooks to be called after GC */ + DdHook *preReorderingHook; /* hooks to be called before reordering */ + DdHook *postReorderingHook; /* hooks to be called after reordering */ + FILE *out; /* stdout for this manager */ + FILE *err; /* stderr for this manager */ + Cudd_ErrorType errorCode; /* info on last error */ + unsigned long startTime; /* start time in milliseconds */ + unsigned long timeLimit; /* CPU time limit */ + /* Statistical counters. */ + unsigned long memused; /* total memory allocated for the manager */ + unsigned long maxmem; /* target maximum memory */ + unsigned long maxmemhard; /* hard limit for maximum memory */ + int garbageCollections; /* number of garbage collections */ + unsigned long GCTime; /* total time spent in garbage collection */ + unsigned long reordTime; /* total time spent in reordering */ + double totCachehits; /* total number of cache hits */ + double totCacheMisses; /* total number of cache misses */ + double cachecollisions; /* number of cache collisions */ + double cacheinserts; /* number of cache insertions */ + double cacheLastInserts; /* insertions at the last cache resizing */ + double cachedeletions; /* number of deletions during garbage coll. */ +#ifdef DD_STATS + double nodesFreed; /* number of nodes returned to the free list */ + double nodesDropped; /* number of nodes killed by dereferencing */ +#endif + unsigned int peakLiveNodes; /* maximum number of live nodes */ +#ifdef DD_UNIQUE_PROFILE + double uniqueLookUps; /* number of unique table lookups */ + double uniqueLinks; /* total distance traveled in coll. chains */ +#endif +#ifdef DD_COUNT + double recursiveCalls; /* number of recursive calls */ +#ifdef DD_STATS + double nextSample; /* when to write next line of stats */ +#endif + double swapSteps; /* number of elementary reordering steps */ +#endif +#ifdef DD_MIS + /* mis/verif compatibility fields */ + array_t *iton; /* maps ids in ddNode to node_t */ + array_t *order; /* copy of order_list */ + lsHandle handle; /* where it is in network BDD list */ + network_t *network; + st_table *local_order; /* for local BDDs */ + int nvars; /* variables used so far */ + int threshold; /* for pseudo var threshold value*/ +#endif +}; + +typedef struct Move { + DdHalfWord x; + DdHalfWord y; + unsigned int flags; + int size; + struct Move *next; +} Move; + +/* Generic level queue item. */ +typedef struct DdQueueItem { + struct DdQueueItem *next; + struct DdQueueItem *cnext; + void *key; +} DdQueueItem; + +/* Level queue. */ +typedef struct DdLevelQueue { + void *first; + DdQueueItem **last; + DdQueueItem *freelist; + DdQueueItem **buckets; + int levels; + int itemsize; + int size; + int maxsize; + int numBuckets; + int shift; +} DdLevelQueue; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Adds node to the head of the free list.] + + Description [Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions.] + + SideEffects [None] + + SeeAlso [cuddAllocNode cuddDynamicAllocNode cuddDeallocMove] + +******************************************************************************/ +#define cuddDeallocNode(unique,node) \ + (node)->next = (unique)->nextFree; \ + (unique)->nextFree = node; + +/**Macro*********************************************************************** + + Synopsis [Adds node to the head of the free list.] + + Description [Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions.] + + SideEffects [None] + + SeeAlso [cuddDeallocNode cuddDynamicAllocNode] + +******************************************************************************/ +#define cuddDeallocMove(unique,node) \ + ((DdNode *)(node))->ref = 0; \ + ((DdNode *)(node))->next = (unique)->nextFree; \ + (unique)->nextFree = (DdNode *)(node); + + +/**Macro*********************************************************************** + + Synopsis [Increases the reference count of a node, if it is not + saturated.] + + Description [Increases the reference count of a node, if it is not + saturated. This being a macro, it is faster than Cudd_Ref, but it + cannot be used in constructs like cuddRef(a = b()).] + + SideEffects [none] + + SeeAlso [Cudd_Ref] + +******************************************************************************/ +#define cuddRef(n) cuddSatInc(Cudd_Regular(n)->ref) + + +/**Macro*********************************************************************** + + Synopsis [Decreases the reference count of a node, if it is not + saturated.] + + Description [Decreases the reference count of node. It is primarily + used in recursive procedures to decrease the ref count of a result + node before returning it. This accomplishes the goal of removing the + protection applied by a previous cuddRef. This being a macro, it is + faster than Cudd_Deref, but it cannot be used in constructs like + cuddDeref(a = b()).] + + SideEffects [none] + + SeeAlso [Cudd_Deref] + +******************************************************************************/ +#define cuddDeref(n) cuddSatDec(Cudd_Regular(n)->ref) + + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if the node is a constant node.] + + Description [Returns 1 if the node is a constant node (rather than an + internal node). All constant nodes have the same index + (CUDD_CONST_INDEX). The pointer passed to cuddIsConstant must be regular.] + + SideEffects [none] + + SeeAlso [Cudd_IsConstant] + +******************************************************************************/ +#define cuddIsConstant(node) ((node)->index == CUDD_CONST_INDEX) + + +/**Macro*********************************************************************** + + Synopsis [Returns the then child of an internal node.] + + Description [Returns the then child of an internal node. If + node is a constant node, the result is unpredictable. + The pointer passed to cuddT must be regular.] + + SideEffects [none] + + SeeAlso [Cudd_T] + +******************************************************************************/ +#define cuddT(node) ((node)->type.kids.T) + + +/**Macro*********************************************************************** + + Synopsis [Returns the else child of an internal node.] + + Description [Returns the else child of an internal node. If + node is a constant node, the result is unpredictable. + The pointer passed to cuddE must be regular.] + + SideEffects [none] + + SeeAlso [Cudd_E] + +******************************************************************************/ +#define cuddE(node) ((node)->type.kids.E) + + +/**Macro*********************************************************************** + + Synopsis [Returns the value of a constant node.] + + Description [Returns the value of a constant node. If + node is an internal node, the result is unpredictable. + The pointer passed to cuddV must be regular.] + + SideEffects [none] + + SeeAlso [Cudd_V] + +******************************************************************************/ +#define cuddV(node) ((node)->type.value) + + +/**Macro*********************************************************************** + + Synopsis [Finds the current position of variable index in the + order.] + + Description [Finds the current position of variable index in the + order. This macro duplicates the functionality of Cudd_ReadPerm, + but it does not check for out-of-bounds indices and it is more + efficient.] + + SideEffects [none] + + SeeAlso [Cudd_ReadPerm] + +******************************************************************************/ +#define cuddI(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->perm[(index)]) + + +/**Macro*********************************************************************** + + Synopsis [Finds the current position of ZDD variable index in the + order.] + + Description [Finds the current position of ZDD variable index in the + order. This macro duplicates the functionality of Cudd_ReadPermZdd, + but it does not check for out-of-bounds indices and it is more + efficient.] + + SideEffects [none] + + SeeAlso [Cudd_ReadPermZdd] + +******************************************************************************/ +#define cuddIZ(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->permZ[(index)]) + + +/**Macro*********************************************************************** + + Synopsis [Hash function for the unique table.] + + Description [] + + SideEffects [none] + + SeeAlso [ddCHash ddCHash2] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddHash(f,g,s) \ +((((unsigned)(ptruint)(f) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (s)) +#else +#define ddHash(f,g,s) \ +((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Hash function for the cache.] + + Description [] + + SideEffects [none] + + SeeAlso [ddHash ddCHash2] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddCHash(o,f,g,h,s) \ +((((((unsigned)(ptruint)(f) + (unsigned)(ptruint)(o)) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2 + \ + (unsigned)(ptruint)(h)) * DD_P3) >> (s)) +#else +#define ddCHash(o,f,g,h,s) \ +((((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2 + \ + (unsigned)(h)) * DD_P3) >> (s)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Hash function for the cache for functions with two + operands.] + + Description [] + + SideEffects [none] + + SeeAlso [ddHash ddCHash] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddCHash2(o,f,g,s) \ +(((((unsigned)(ptruint)(f) + (unsigned)(ptruint)(o)) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (s)) +#else +#define ddCHash2(o,f,g,s) \ +(((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Clears the 4 least significant bits of a pointer.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define cuddClean(p) ((DdNode *)((ptruint)(p) & ~0xf)) + + +/**Macro*********************************************************************** + + Synopsis [Computes the minimum of two numbers.] + + Description [] + + SideEffects [none] + + SeeAlso [ddMax] + +******************************************************************************/ +#define ddMin(x,y) (((y) < (x)) ? (y) : (x)) + + +/**Macro*********************************************************************** + + Synopsis [Computes the maximum of two numbers.] + + Description [] + + SideEffects [none] + + SeeAlso [ddMin] + +******************************************************************************/ +#define ddMax(x,y) (((y) > (x)) ? (y) : (x)) + + +/**Macro*********************************************************************** + + Synopsis [Computes the absolute value of a number.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define ddAbs(x) (((x)<0) ? -(x) : (x)) + + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if the absolute value of the difference of the two + arguments x and y is less than e.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define ddEqualVal(x,y,e) (ddAbs((x)-(y))<(e)) + + +/**Macro*********************************************************************** + + Synopsis [Saturating increment operator.] + + Description [] + + SideEffects [none] + + SeeAlso [cuddSatDec] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define cuddSatInc(x) ((x)++) +#else +#define cuddSatInc(x) ((x) += (x) != (DdHalfWord)DD_MAXREF) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Saturating decrement operator.] + + Description [] + + SideEffects [none] + + SeeAlso [cuddSatInc] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define cuddSatDec(x) ((x)--) +#else +#define cuddSatDec(x) ((x) -= (x) != (DdHalfWord)DD_MAXREF) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Returns the constant 1 node.] + + Description [] + + SideEffects [none] + + SeeAlso [DD_ZERO DD_PLUS_INFINITY DD_MINUS_INFINITY] + +******************************************************************************/ +#define DD_ONE(dd) ((dd)->one) + + +/**Macro*********************************************************************** + + Synopsis [Returns the arithmetic 0 constant node.] + + Description [Returns the arithmetic 0 constant node. This is different + from the logical zero. The latter is obtained by + Cudd_Not(DD_ONE(dd)).] + + SideEffects [none] + + SeeAlso [DD_ONE Cudd_Not DD_PLUS_INFINITY DD_MINUS_INFINITY] + +******************************************************************************/ +#define DD_ZERO(dd) ((dd)->zero) + + +/**Macro*********************************************************************** + + Synopsis [Returns the plus infinity constant node.] + + Description [] + + SideEffects [none] + + SeeAlso [DD_ONE DD_ZERO DD_MINUS_INFINITY] + +******************************************************************************/ +#define DD_PLUS_INFINITY(dd) ((dd)->plusinfinity) + + +/**Macro*********************************************************************** + + Synopsis [Returns the minus infinity constant node.] + + Description [] + + SideEffects [none] + + SeeAlso [DD_ONE DD_ZERO DD_PLUS_INFINITY] + +******************************************************************************/ +#define DD_MINUS_INFINITY(dd) ((dd)->minusinfinity) + + +/**Macro*********************************************************************** + + Synopsis [Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL.] + + Description [Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL. + Furthermore, if x <= DD_MINUS_INF_VAL/2, x is set to + DD_MINUS_INF_VAL. Similarly, if DD_PLUS_INF_VAL/2 <= x, x is set to + DD_PLUS_INF_VAL. Normally this macro is a NOOP. However, if + HAVE_IEEE_754 is not defined, it makes sure that a value does not + get larger than infinity in absolute value, and once it gets to + infinity, stays there. If the value overflows before this macro is + applied, no recovery is possible.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#ifdef HAVE_IEEE_754 +#define cuddAdjust(x) +#else +#define cuddAdjust(x) ((x) = ((x) >= DD_CRI_HI_MARK) ? DD_PLUS_INF_VAL : (((x) <= DD_CRI_LO_MARK) ? DD_MINUS_INF_VAL : (x))) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Extract the least significant digit of a double digit.] + + Description [Extract the least significant digit of a double digit. Used + in the manipulation of arbitrary precision integers.] + + SideEffects [None] + + SeeAlso [DD_MSDIGIT] + +******************************************************************************/ +#define DD_LSDIGIT(x) ((x) & DD_APA_MASK) + + +/**Macro*********************************************************************** + + Synopsis [Extract the most significant digit of a double digit.] + + Description [Extract the most significant digit of a double digit. Used + in the manipulation of arbitrary precision integers.] + + SideEffects [None] + + SeeAlso [DD_LSDIGIT] + +******************************************************************************/ +#define DD_MSDIGIT(x) ((x) >> DD_APA_BITS) + + +/**Macro*********************************************************************** + + Synopsis [Outputs a line of stats.] + + Description [Outputs a line of stats if DD_COUNT and DD_STATS are + defined. Increments the number of recursive calls if DD_COUNT is + defined.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +#ifdef DD_COUNT +#ifdef DD_STATS +#define statLine(dd) dd->recursiveCalls++; \ +if (dd->recursiveCalls == dd->nextSample) {(void) fprintf(dd->err, \ +"@%.0f: %u nodes %u live %.0f dropped %.0f reclaimed\n", dd->recursiveCalls, \ +dd->keys, dd->keys - dd->dead, dd->nodesDropped, dd->reclaimed); \ +dd->nextSample += 250000;} +#else +#define statLine(dd) dd->recursiveCalls++; +#endif +#else +#define statLine(dd) +#endif + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern DdNode * cuddAddExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * cuddAddUnivAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * cuddAddOrAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * cuddAddApplyRecur (DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g); +extern DdNode * cuddAddMonadicApplyRecur (DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f); +extern DdNode * cuddAddScalarInverseRecur (DdManager *dd, DdNode *f, DdNode *epsilon); +extern DdNode * cuddAddIteRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddAddCmplRecur (DdManager *dd, DdNode *f); +extern DdNode * cuddAddNegateRecur (DdManager *dd, DdNode *f); +extern DdNode * cuddAddRoundOffRecur (DdManager *dd, DdNode *f, double trunc); +extern DdNode * cuddUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality); +extern DdNode * cuddRemapUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality); +extern DdNode * cuddBiasedUnderApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0); +extern DdNode * cuddBddAndAbstractRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube); +extern int cuddAnnealing (DdManager *table, int lower, int upper); +extern DdNode * cuddBddExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * cuddBddXorExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube); +extern DdNode * cuddBddBooleanDiffRecur (DdManager *manager, DdNode *f, DdNode *var); +extern DdNode * cuddBddIteRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddBddIntersectRecur (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddBddAndRecur (DdManager *manager, DdNode *f, DdNode *g); +extern DdNode * cuddBddXorRecur (DdManager *manager, DdNode *f, DdNode *g); +extern DdNode * cuddBddTransfer (DdManager *ddS, DdManager *ddD, DdNode *f); +extern DdNode * cuddAddBddDoPattern (DdManager *dd, DdNode *f); +extern int cuddInitCache (DdManager *unique, unsigned int cacheSize, unsigned int maxCacheSize); +extern void cuddCacheInsert (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data); +extern void cuddCacheInsert2 (DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data); +extern void cuddCacheInsert1 (DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f, DdNode *data); +extern DdNode * cuddCacheLookup (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddCacheLookupZdd (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddCacheLookup2 (DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g); +extern DdNode * cuddCacheLookup1 (DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f); +extern DdNode * cuddCacheLookup2Zdd (DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g); +extern DdNode * cuddCacheLookup1Zdd (DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f); +extern DdNode * cuddConstantLookup (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h); +extern int cuddCacheProfile (DdManager *table, FILE *fp); +extern void cuddCacheResize (DdManager *table); +extern void cuddCacheFlush (DdManager *table); +extern int cuddComputeFloorLog2 (unsigned int value); +extern int cuddHeapProfile (DdManager *dd); +extern void cuddPrintNode (DdNode *f, FILE *fp); +extern void cuddPrintVarGroups (DdManager * dd, MtrNode * root, int zdd, int silent); +extern DdNode * cuddBddClippingAnd (DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction); +extern DdNode * cuddBddClippingAndAbstract (DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction); +extern void cuddGetBranches (DdNode *g, DdNode **g1, DdNode **g0); +extern DdNode * cuddCofactorRecur (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddBddComposeRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *proj); +extern DdNode * cuddAddComposeRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *proj); +extern int cuddExact (DdManager *table, int lower, int upper); +extern DdNode * cuddBddConstrainRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddBddRestrictRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddBddNPAndRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddAddConstrainRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddAddRestrictRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddBddLICompaction (DdManager *dd, DdNode *f, DdNode *c); +extern int cuddGa (DdManager *table, int lower, int upper); +extern int cuddTreeSifting (DdManager *table, Cudd_ReorderingType method); +extern int cuddZddInitUniv (DdManager *zdd); +extern void cuddZddFreeUniv (DdManager *zdd); +extern void cuddSetInteract (DdManager *table, int x, int y); +extern int cuddTestInteract (DdManager *table, int x, int y); +extern int cuddInitInteract (DdManager *table); +extern DdLocalCache * cuddLocalCacheInit (DdManager *manager, unsigned int keySize, unsigned int cacheSize, unsigned int maxCacheSize); +extern void cuddLocalCacheQuit (DdLocalCache *cache); +extern void cuddLocalCacheInsert (DdLocalCache *cache, DdNodePtr *key, DdNode *value); +extern DdNode * cuddLocalCacheLookup (DdLocalCache *cache, DdNodePtr *key); +extern void cuddLocalCacheClearDead (DdManager *manager); +extern int cuddIsInDeathRow (DdManager *dd, DdNode *f); +extern int cuddTimesInDeathRow (DdManager *dd, DdNode *f); +extern void cuddLocalCacheClearAll (DdManager *manager); +#ifdef DD_CACHE_PROFILE +extern int cuddLocalCacheProfile (DdLocalCache *cache); +#endif +extern DdHashTable * cuddHashTableInit (DdManager *manager, unsigned int keySize, unsigned int initSize); +extern void cuddHashTableQuit (DdHashTable *hash); +extern void cuddHashTableGenericQuit (DdHashTable *hash); +extern int cuddHashTableInsert (DdHashTable *hash, DdNodePtr *key, DdNode *value, ptrint count); +extern DdNode * cuddHashTableLookup (DdHashTable *hash, DdNodePtr *key); +extern int cuddHashTableInsert1 (DdHashTable *hash, DdNode *f, DdNode *value, ptrint count); +extern DdNode * cuddHashTableLookup1 (DdHashTable *hash, DdNode *f); +extern int cuddHashTableInsert2 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *value, ptrint count); +extern DdNode * cuddHashTableLookup2 (DdHashTable *hash, DdNode *f, DdNode *g); +extern int cuddHashTableInsert3 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h, DdNode *value, ptrint count); +extern DdNode * cuddHashTableLookup3 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h); +extern int cuddHashTableGenericInsert(DdHashTable * hash, DdNode * f, void * value); +extern void * cuddHashTableGenericLookup(DdHashTable * hash, DdNode * f); +extern DdLevelQueue * cuddLevelQueueInit (int levels, int itemSize, int numBuckets); +extern void cuddLevelQueueQuit (DdLevelQueue *queue); +extern void * cuddLevelQueueFirst(DdLevelQueue * queue, void * key, int level); +extern void * cuddLevelQueueEnqueue (DdLevelQueue *queue, void *key, int level); +extern void cuddLevelQueueDequeue (DdLevelQueue *queue, int level); +extern int cuddLinearAndSifting (DdManager *table, int lower, int upper); +extern int cuddLinearInPlace (DdManager * table, int x, int y); +extern void cuddUpdateInteractionMatrix (DdManager * table, int xindex, int yindex); +extern int cuddInitLinear (DdManager *table); +extern int cuddResizeLinear (DdManager *table); +extern DdNode * cuddBddLiteralSetIntersectionRecur (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddCProjectionRecur (DdManager *dd, DdNode *R, DdNode *Y, DdNode *Ysupp); +extern DdNode * cuddBddClosestCube (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE bound); +extern void cuddReclaim (DdManager *table, DdNode *n); +extern void cuddReclaimZdd (DdManager *table, DdNode *n); +extern void cuddClearDeathRow (DdManager *table); +extern void cuddShrinkDeathRow (DdManager *table); +extern DdNode * cuddDynamicAllocNode (DdManager *table); +extern int cuddSifting (DdManager *table, int lower, int upper); +extern int cuddSwapping (DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic); +extern int cuddNextHigh (DdManager *table, int x); +extern int cuddNextLow (DdManager *table, int x); +extern int cuddSwapInPlace (DdManager *table, int x, int y); +extern int cuddBddAlignToZdd (DdManager *table); +extern DdNode * cuddBddMakePrime (DdManager *dd, DdNode *cube, DdNode *f); +extern DdNode * cuddSolveEqnRecur (DdManager *bdd, DdNode *F, DdNode *Y, DdNode **G, int n, int *yIndex, int i); +extern DdNode * cuddVerifySol (DdManager *bdd, DdNode *F, DdNode **G, int *yIndex, int n); +#ifdef ST_INCLUDED +extern DdNode* cuddSplitSetRecur (DdManager *manager, st_table *mtable, int *varSeen, DdNode *p, double n, double max, int index); +#endif +extern DdNode * cuddSubsetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold); +extern DdNode * cuddSubsetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit); +extern int cuddSymmCheck (DdManager *table, int x, int y); +extern int cuddSymmSifting (DdManager *table, int lower, int upper); +extern int cuddSymmSiftingConv (DdManager *table, int lower, int upper); +extern DdNode * cuddAllocNode (DdManager *unique); +extern DdManager * cuddInitTable (unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int looseUpTo); +extern void cuddFreeTable (DdManager *unique); +extern int cuddGarbageCollect (DdManager *unique, int clearCache); +extern DdNode * cuddZddGetNode (DdManager *zdd, int id, DdNode *T, DdNode *E); +extern DdNode * cuddZddGetNodeIVO (DdManager *dd, int index, DdNode *g, DdNode *h); +extern DdNode * cuddUniqueInter (DdManager *unique, int index, DdNode *T, DdNode *E); +extern DdNode * cuddUniqueInterIVO (DdManager *unique, int index, DdNode *T, DdNode *E); +extern DdNode * cuddUniqueInterZdd (DdManager *unique, int index, DdNode *T, DdNode *E); +extern DdNode * cuddUniqueConst (DdManager *unique, CUDD_VALUE_TYPE value); +extern void cuddRehash (DdManager *unique, int i); +extern void cuddShrinkSubtable (DdManager *unique, int i); +extern int cuddInsertSubtables (DdManager *unique, int n, int level); +extern int cuddDestroySubtables (DdManager *unique, int n); +extern int cuddResizeTableZdd (DdManager *unique, int index); +extern void cuddSlowTableGrowth (DdManager *unique); +extern int cuddP (DdManager *dd, DdNode *f); +#ifdef ST_INCLUDED +extern enum st_retval cuddStCountfree (char *key, char *value, char *arg); +extern int cuddCollectNodes (DdNode *f, st_table *visited); +#endif +extern DdNodePtr * cuddNodeArray (DdNode *f, int *n); +extern int cuddWindowReorder (DdManager *table, int low, int high, Cudd_ReorderingType submethod); +extern DdNode * cuddZddProduct (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddUnateProduct (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddWeakDiv (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddWeakDivF (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddDivide (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddDivideF (DdManager *dd, DdNode *f, DdNode *g); +extern int cuddZddGetCofactors3 (DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd); +extern int cuddZddGetCofactors2 (DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0); +extern DdNode * cuddZddComplement (DdManager *dd, DdNode *node); +extern int cuddZddGetPosVarIndex(DdManager * dd, int index); +extern int cuddZddGetNegVarIndex(DdManager * dd, int index); +extern int cuddZddGetPosVarLevel(DdManager * dd, int index); +extern int cuddZddGetNegVarLevel(DdManager * dd, int index); +extern int cuddZddTreeSifting (DdManager *table, Cudd_ReorderingType method); +extern DdNode * cuddZddIsop (DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I); +extern DdNode * cuddBddIsop (DdManager *dd, DdNode *L, DdNode *U); +extern DdNode * cuddMakeBddFromZddCover (DdManager *dd, DdNode *node); +extern int cuddZddLinearSifting (DdManager *table, int lower, int upper); +extern int cuddZddAlignToBdd (DdManager *table); +extern int cuddZddNextHigh (DdManager *table, int x); +extern int cuddZddNextLow (DdManager *table, int x); +extern int cuddZddUniqueCompare (int *ptr_x, int *ptr_y); +extern int cuddZddSwapInPlace (DdManager *table, int x, int y); +extern int cuddZddSwapping (DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic); +extern int cuddZddSifting (DdManager *table, int lower, int upper); +extern DdNode * cuddZddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddZddUnion (DdManager *zdd, DdNode *P, DdNode *Q); +extern DdNode * cuddZddIntersect (DdManager *zdd, DdNode *P, DdNode *Q); +extern DdNode * cuddZddDiff (DdManager *zdd, DdNode *P, DdNode *Q); +extern DdNode * cuddZddChangeAux (DdManager *zdd, DdNode *P, DdNode *zvar); +extern DdNode * cuddZddSubset1 (DdManager *dd, DdNode *P, int var); +extern DdNode * cuddZddSubset0 (DdManager *dd, DdNode *P, int var); +extern DdNode * cuddZddChange (DdManager *dd, DdNode *P, int var); +extern int cuddZddSymmCheck (DdManager *table, int x, int y); +extern int cuddZddSymmSifting (DdManager *table, int lower, int upper); +extern int cuddZddSymmSiftingConv (DdManager *table, int lower, int upper); +extern int cuddZddP (DdManager *zdd, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _CUDDINT */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddInteract.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddInteract.c new file mode 100644 index 000000000..42fc68046 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddInteract.c @@ -0,0 +1,432 @@ +/**CFile*********************************************************************** + + FileName [cuddInteract.c] + + PackageName [cudd] + + Synopsis [Functions to manipulate the variable interaction matrix.] + + Description [Internal procedures included in this file: +
                +
              • cuddSetInteract() +
              • cuddTestInteract() +
              • cuddInitInteract() +
              + Static procedures included in this file: +
                +
              • ddSuppInteract() +
              • ddClearLocal() +
              • ddUpdateInteract() +
              • ddClearGlobal() +
              + The interaction matrix tells whether two variables are + both in the support of some function of the DD. The main use of the + interaction matrix is in the in-place swapping. Indeed, if two + variables do not interact, there is no arc connecting the two layers; + therefore, the swap can be performed in constant time, without + scanning the subtables. Another use of the interaction matrix is in + the computation of the lower bounds for sifting. Finally, the + interaction matrix can be used to speed up aggregation checks in + symmetric and group sifting.

              + The computation of the interaction matrix is done with a series of + depth-first searches. The searches start from those nodes that have + only external references. The matrix is stored as a packed array of bits; + since it is symmetric, only the upper triangle is kept in memory. + As a final remark, we note that there may be variables that do + interact, but that for a given variable order have no arc connecting + their layers when they are adjacent. For instance, in ite(a,b,c) with + the order asize, + sets the corresponding bit of the interaction matrix to 1.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddSetInteract( + DdManager * table, + int x, + int y) +{ + int posn, word, bit; + +#ifdef DD_DEBUG + assert(x < y); + assert(y < table->size); + assert(x >= 0); +#endif + + posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1; + word = posn >> LOGBPL; + bit = posn & (BPL-1); + table->interact[word] |= 1L << bit; + +} /* end of cuddSetInteract */ + + +/**Function******************************************************************** + + Synopsis [Test interaction matrix entries.] + + Description [Given a pair of variables 0 <= x < y < table->size, + tests whether the corresponding bit of the interaction matrix is 1. + Returns the value of the bit.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddTestInteract( + DdManager * table, + int x, + int y) +{ + int posn, word, bit, result; + + if (x > y) { + int tmp = x; + x = y; + y = tmp; + } +#ifdef DD_DEBUG + assert(x < y); + assert(y < table->size); + assert(x >= 0); +#endif + + posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1; + word = posn >> LOGBPL; + bit = posn & (BPL-1); + result = (table->interact[word] >> bit) & 1L; + return(result); + +} /* end of cuddTestInteract */ + + +/**Function******************************************************************** + + Synopsis [Initializes the interaction matrix.] + + Description [Initializes the interaction matrix. The interaction + matrix is implemented as a bit vector storing the upper triangle of + the symmetric interaction matrix. The bit vector is kept in an array + of long integers. The computation is based on a series of depth-first + searches, one for each root of the DAG. Two flags are needed: The + local visited flag uses the LSB of the then pointer. The global + visited flag uses the LSB of the next pointer. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddInitInteract( + DdManager * table) +{ + int i,j; + unsigned long words; + long *interact; + char *support; + DdNode *f; + DdNode *sentinel = &(table->sentinel); + DdNodePtr *nodelist; + int slots; + unsigned long n = (unsigned long) table->size; + + words = ((n * (n-1)) >> (1 + LOGBPL)) + 1; + table->interact = interact = ALLOC(long,words); + if (interact == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < words; i++) { + interact[i] = 0; + } + + support = ALLOC(char,n); + if (support == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + FREE(interact); + return(0); + } + for (i = 0; i < n; i++) { + support[i] = 0; + } + + for (i = 0; i < n; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + /* A node is a root of the DAG if it cannot be + ** reached by nodes above it. If a node was never + ** reached during the previous depth-first searches, + ** then it is a root, and we start a new depth-first + ** search from it. + */ + if (!Cudd_IsComplement(f->next)) { + ddSuppInteract(f,support); + ddClearLocal(f); + ddUpdateInteract(table,support); + } + f = Cudd_Regular(f->next); + } + } + } + ddClearGlobal(table); + + FREE(support); + return(1); + +} /* end of cuddInitInteract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Find the support of f.] + + Description [Performs a DFS from f. Uses the LSB of the then pointer + as visited flag.] + + SideEffects [Accumulates in support the variables on which f depends.] + + SeeAlso [] + +******************************************************************************/ +static void +ddSuppInteract( + DdNode * f, + char * support) +{ + if (cuddIsConstant(f) || Cudd_IsComplement(cuddT(f))) { + return; + } + + support[f->index] = 1; + ddSuppInteract(cuddT(f),support); + ddSuppInteract(Cudd_Regular(cuddE(f)),support); + /* mark as visited */ + cuddT(f) = Cudd_Complement(cuddT(f)); + f->next = Cudd_Complement(f->next); + return; + +} /* end of ddSuppInteract */ + + +/**Function******************************************************************** + + Synopsis [Performs a DFS from f, clearing the LSB of the then pointers.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ddClearLocal( + DdNode * f) +{ + if (cuddIsConstant(f) || !Cudd_IsComplement(cuddT(f))) { + return; + } + /* clear visited flag */ + cuddT(f) = Cudd_Regular(cuddT(f)); + ddClearLocal(cuddT(f)); + ddClearLocal(Cudd_Regular(cuddE(f))); + return; + +} /* end of ddClearLocal */ + + +/**Function******************************************************************** + + Synopsis [Marks as interacting all pairs of variables that appear in + support.] + + Description [If support[i] == support[j] == 1, sets the (i,j) entry + of the interaction matrix to 1.] + + SideEffects [Clears support.] + + SeeAlso [] + +******************************************************************************/ +static void +ddUpdateInteract( + DdManager * table, + char * support) +{ + int i,j; + int n = table->size; + + for (i = 0; i < n-1; i++) { + if (support[i] == 1) { + support[i] = 0; + for (j = i+1; j < n; j++) { + if (support[j] == 1) { + cuddSetInteract(table,i,j); + } + } + } + } + support[n-1] = 0; + +} /* end of ddUpdateInteract */ + + +/**Function******************************************************************** + + Synopsis [Scans the DD and clears the LSB of the next pointers.] + + Description [The LSB of the next pointers are used as markers to tell + whether a node was reached by at least one DFS. Once the interaction + matrix is built, these flags are reset.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ddClearGlobal( + DdManager * table) +{ + int i,j; + DdNode *f; + DdNode *sentinel = &(table->sentinel); + DdNodePtr *nodelist; + int slots; + + for (i = 0; i < table->size; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + f->next = Cudd_Regular(f->next); + f = f->next; + } + } + } + +} /* end of ddClearGlobal */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddLCache.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddLCache.c new file mode 100644 index 000000000..63186e105 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddLCache.c @@ -0,0 +1,1557 @@ +/**CFile*********************************************************************** + + FileName [cuddLCache.c] + + PackageName [cudd] + + Synopsis [Functions for local caches.] + + Description [Internal procedures included in this module: +

                +
              • cuddLocalCacheInit() +
              • cuddLocalCacheQuit() +
              • cuddLocalCacheInsert() +
              • cuddLocalCacheLookup() +
              • cuddLocalCacheClearDead() +
              • cuddLocalCacheClearAll() +
              • cuddLocalCacheProfile() +
              • cuddHashTableInit() +
              • cuddHashTableQuit() +
              • cuddHashTableGenericQuit() +
              • cuddHashTableInsert() +
              • cuddHashTableLookup() +
              • cuddHashTableGenericInsert() +
              • cuddHashTableGenericLookup() +
              • cuddHashTableInsert2() +
              • cuddHashTableLookup2() +
              • cuddHashTableInsert3() +
              • cuddHashTableLookup3() +
              + Static procedures included in this module: +
                +
              • cuddLocalCacheResize() +
              • ddLCHash() +
              • cuddLocalCacheAddToList() +
              • cuddLocalCacheRemoveFromList() +
              • cuddHashTableResize() +
              • cuddHashTableAlloc() +
              ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_MAX_HASHTABLE_DENSITY 2 /* tells when to resize a table */ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.27 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Computes hash function for keys of one operand.] + + Description [] + + SideEffects [None] + + SeeAlso [ddLCHash3 ddLCHash] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddLCHash1(f,shift) \ +(((unsigned)(ptruint)(f) * DD_P1) >> (shift)) +#else +#define ddLCHash1(f,shift) \ +(((unsigned)(f) * DD_P1) >> (shift)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Computes hash function for keys of two operands.] + + Description [] + + SideEffects [None] + + SeeAlso [ddLCHash3 ddLCHash] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddLCHash2(f,g,shift) \ +((((unsigned)(ptruint)(f) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (shift)) +#else +#define ddLCHash2(f,g,shift) \ +((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Computes hash function for keys of three operands.] + + Description [] + + SideEffects [None] + + SeeAlso [ddLCHash2 ddLCHash] + +******************************************************************************/ +#define ddLCHash3(f,g,h,shift) ddCHash2(f,g,h,shift) + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void cuddLocalCacheResize (DdLocalCache *cache); +DD_INLINE static unsigned int ddLCHash (DdNodePtr *key, unsigned int keysize, int shift); +static void cuddLocalCacheAddToList (DdLocalCache *cache); +static void cuddLocalCacheRemoveFromList (DdLocalCache *cache); +static int cuddHashTableResize (DdHashTable *hash); +DD_INLINE static DdHashItem * cuddHashTableAlloc (DdHashTable *hash); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes a local computed table.] + + Description [Initializes a computed table. Returns a pointer the + the new local cache in case of success; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddInitCache] + +******************************************************************************/ +DdLocalCache * +cuddLocalCacheInit( + DdManager * manager /* manager */, + unsigned int keySize /* size of the key (number of operands) */, + unsigned int cacheSize /* Initial size of the cache */, + unsigned int maxCacheSize /* Size of the cache beyond which no resizing occurs */) +{ + DdLocalCache *cache; + int logSize; + + cache = ALLOC(DdLocalCache,1); + if (cache == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + cache->manager = manager; + cache->keysize = keySize; + cache->itemsize = (keySize + 1) * sizeof(DdNode *); +#ifdef DD_CACHE_PROFILE + cache->itemsize += sizeof(ptrint); +#endif + logSize = cuddComputeFloorLog2(ddMax(cacheSize,manager->slots/2)); + cacheSize = 1 << logSize; + cache->item = (DdLocalCacheItem *) + ALLOC(char, cacheSize * cache->itemsize); + if (cache->item == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + FREE(cache); + return(NULL); + } + cache->slots = cacheSize; + cache->shift = sizeof(int) * 8 - logSize; + cache->maxslots = ddMin(maxCacheSize,manager->slots); + cache->minHit = manager->minHit; + /* Initialize to avoid division by 0 and immediate resizing. */ + cache->lookUps = (double) (int) (cacheSize * cache->minHit + 1); + cache->hits = 0; + manager->memused += cacheSize * cache->itemsize + sizeof(DdLocalCache); + + /* Initialize the cache. */ + memset(cache->item, 0, cacheSize * cache->itemsize); + + /* Add to manager's list of local caches for GC. */ + cuddLocalCacheAddToList(cache); + + return(cache); + +} /* end of cuddLocalCacheInit */ + + +/**Function******************************************************************** + + Synopsis [Shuts down a local computed table.] + + Description [Initializes the computed table. It is called by + Cudd_Init. Returns a pointer the the new local cache in case of + success; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddLocalCacheInit] + +******************************************************************************/ +void +cuddLocalCacheQuit( + DdLocalCache * cache /* cache to be shut down */) +{ + cache->manager->memused -= + cache->slots * cache->itemsize + sizeof(DdLocalCache); + cuddLocalCacheRemoveFromList(cache); + FREE(cache->item); + FREE(cache); + + return; + +} /* end of cuddLocalCacheQuit */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in a local cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddLocalCacheInsert( + DdLocalCache * cache, + DdNodePtr * key, + DdNode * value) +{ + unsigned int posn; + DdLocalCacheItem *entry; + + posn = ddLCHash(key,cache->keysize,cache->shift); + entry = (DdLocalCacheItem *) ((char *) cache->item + + posn * cache->itemsize); + memcpy(entry->key,key,cache->keysize * sizeof(DdNode *)); + entry->value = value; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddLocalCacheInsert */ + + +/**Function******************************************************************** + + Synopsis [Looks up in a local cache.] + + Description [Looks up in a local cache. Returns the result if found; + it returns NULL if no result is found.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddLocalCacheLookup( + DdLocalCache * cache, + DdNodePtr * key) +{ + unsigned int posn; + DdLocalCacheItem *entry; + DdNode *value; + + cache->lookUps++; + posn = ddLCHash(key,cache->keysize,cache->shift); + entry = (DdLocalCacheItem *) ((char *) cache->item + + posn * cache->itemsize); + if (entry->value != NULL && + memcmp(key,entry->key,cache->keysize*sizeof(DdNode *)) == 0) { + cache->hits++; + value = Cudd_Regular(entry->value); + if (value->ref == 0) { + cuddReclaim(cache->manager,value); + } + return(entry->value); + } + + /* Cache miss: decide whether to resize */ + + if (cache->slots < cache->maxslots && + cache->hits > cache->lookUps * cache->minHit) { + cuddLocalCacheResize(cache); + } + + return(NULL); + +} /* end of cuddLocalCacheLookup */ + + +/**Function******************************************************************** + + Synopsis [Clears the dead entries of the local caches of a manager.] + + Description [Clears the dead entries of the local caches of a manager. + Used during garbage collection.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddLocalCacheClearDead( + DdManager * manager) +{ + DdLocalCache *cache = manager->localCaches; + unsigned int keysize; + unsigned int itemsize; + unsigned int slots; + DdLocalCacheItem *item; + DdNodePtr *key; + unsigned int i, j; + + while (cache != NULL) { + keysize = cache->keysize; + itemsize = cache->itemsize; + slots = cache->slots; + item = cache->item; + for (i = 0; i < slots; i++) { + if (item->value != NULL) { + if (Cudd_Regular(item->value)->ref == 0) { + item->value = NULL; + } else { + key = item->key; + for (j = 0; j < keysize; j++) { + if (Cudd_Regular(key[j])->ref == 0) { + item->value = NULL; + break; + } + } + } + } + item = (DdLocalCacheItem *) ((char *) item + itemsize); + } + cache = cache->next; + } + return; + +} /* end of cuddLocalCacheClearDead */ + + +/**Function******************************************************************** + + Synopsis [Clears the local caches of a manager.] + + Description [Clears the local caches of a manager. + Used before reordering.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddLocalCacheClearAll( + DdManager * manager) +{ + DdLocalCache *cache = manager->localCaches; + + while (cache != NULL) { + memset(cache->item, 0, cache->slots * cache->itemsize); + cache = cache->next; + } + return; + +} /* end of cuddLocalCacheClearAll */ + + +#ifdef DD_CACHE_PROFILE + +#define DD_HYSTO_BINS 8 + +/**Function******************************************************************** + + Synopsis [Computes and prints a profile of a local cache usage.] + + Description [Computes and prints a profile of a local cache usage. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddLocalCacheProfile( + DdLocalCache * cache) +{ + double count, mean, meansq, stddev, expected; + long max, min; + int imax, imin; + int i, retval, slots; + long *hystogram; + int nbins = DD_HYSTO_BINS; + int bin; + long thiscount; + double totalcount; + int nzeroes; + DdLocalCacheItem *entry; + FILE *fp = cache->manager->out; + + slots = cache->slots; + + meansq = mean = expected = 0.0; + max = min = (long) cache->item[0].count; + imax = imin = nzeroes = 0; + totalcount = 0.0; + + hystogram = ALLOC(long, nbins); + if (hystogram == NULL) { + return(0); + } + for (i = 0; i < nbins; i++) { + hystogram[i] = 0; + } + + for (i = 0; i < slots; i++) { + entry = (DdLocalCacheItem *) ((char *) cache->item + + i * cache->itemsize); + thiscount = (long) entry->count; + if (thiscount > max) { + max = thiscount; + imax = i; + } + if (thiscount < min) { + min = thiscount; + imin = i; + } + if (thiscount == 0) { + nzeroes++; + } + count = (double) thiscount; + mean += count; + meansq += count * count; + totalcount += count; + expected += count * (double) i; + bin = (i * nbins) / slots; + hystogram[bin] += thiscount; + } + mean /= (double) slots; + meansq /= (double) slots; + stddev = sqrt(meansq - mean*mean); + + retval = fprintf(fp,"Cache stats: slots = %d average = %g ", slots, mean); + if (retval == EOF) return(0); + retval = fprintf(fp,"standard deviation = %g\n", stddev); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache max accesses = %ld for slot %d\n", max, imax); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache min accesses = %ld for slot %d\n", min, imin); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache unused slots = %d\n", nzeroes); + if (retval == EOF) return(0); + + if (totalcount) { + expected /= totalcount; + retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); + if (retval == EOF) return(0); + retval = fprintf(fp," (expected bin value = %g)\n# ", expected); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp,"%ld ", hystogram[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\n"); + if (retval == EOF) return(0); + } + + FREE(hystogram); + return(1); + +} /* end of cuddLocalCacheProfile */ +#endif + + +/**Function******************************************************************** + + Synopsis [Initializes a hash table.] + + Description [Initializes a hash table. Returns a pointer to the new + table if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableQuit] + +******************************************************************************/ +DdHashTable * +cuddHashTableInit( + DdManager * manager, + unsigned int keySize, + unsigned int initSize) +{ + DdHashTable *hash; + int logSize; + + hash = ALLOC(DdHashTable, 1); + if (hash == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + hash->keysize = keySize; + hash->manager = manager; + hash->memoryList = NULL; + hash->nextFree = NULL; + hash->itemsize = (keySize + 1) * sizeof(DdNode *) + + sizeof(ptrint) + sizeof(DdHashItem *); + /* We have to guarantee that the shift be < 32. */ + if (initSize < 2) initSize = 2; + logSize = cuddComputeFloorLog2(initSize); + hash->numBuckets = 1 << logSize; + hash->shift = sizeof(int) * 8 - logSize; + hash->bucket = ALLOC(DdHashItem *, hash->numBuckets); + if (hash->bucket == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + FREE(hash); + return(NULL); + } + memset(hash->bucket, 0, hash->numBuckets * sizeof(DdHashItem *)); + hash->size = 0; + hash->maxsize = hash->numBuckets * DD_MAX_HASHTABLE_DENSITY; + return(hash); + +} /* end of cuddHashTableInit */ + + +/**Function******************************************************************** + + Synopsis [Shuts down a hash table.] + + Description [Shuts down a hash table, dereferencing all the values.] + + SideEffects [None] + + SeeAlso [cuddHashTableInit] + +******************************************************************************/ +void +cuddHashTableQuit( + DdHashTable * hash) +{ + unsigned int i; + DdManager *dd = hash->manager; + DdHashItem *bucket; + DdHashItem **memlist, **nextmem; + unsigned int numBuckets = hash->numBuckets; + + for (i = 0; i < numBuckets; i++) { + bucket = hash->bucket[i]; + while (bucket != NULL) { + Cudd_RecursiveDeref(dd, bucket->value); + bucket = bucket->next; + } + } + + memlist = hash->memoryList; + while (memlist != NULL) { + nextmem = (DdHashItem **) memlist[0]; + FREE(memlist); + memlist = nextmem; + } + + FREE(hash->bucket); + FREE(hash); + + return; + +} /* end of cuddHashTableQuit */ + + +/**Function******************************************************************** + + Synopsis [Shuts down a hash table.] + + Description [Shuts down a hash table, when the values are not DdNode + pointers.] + + SideEffects [None] + + SeeAlso [cuddHashTableInit] + +******************************************************************************/ +void +cuddHashTableGenericQuit( + DdHashTable * hash) +{ +#ifdef __osf__ +#pragma pointer_size save +#pragma pointer_size short +#endif + DdHashItem **memlist, **nextmem; + + memlist = hash->memoryList; + while (memlist != NULL) { + nextmem = (DdHashItem **) memlist[0]; + FREE(memlist); + memlist = nextmem; + } + + FREE(hash->bucket); + FREE(hash); +#ifdef __osf__ +#pragma pointer_size restore +#endif + + return; + +} /* end of cuddHashTableGenericQuit */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key has more than + three pointers. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [[cuddHashTableInsert1 cuddHashTableInsert2 cuddHashTableInsert3 + cuddHashTableLookup] + +******************************************************************************/ +int +cuddHashTableInsert( + DdHashTable * hash, + DdNodePtr * key, + DdNode * value, + ptrint count) +{ + int result; + unsigned int posn; + DdHashItem *item; + unsigned int i; + +#ifdef DD_DEBUG + assert(hash->keysize > 3); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = value; + cuddRef(value); + item->count = count; + for (i = 0; i < hash->keysize; i++) { + item->key[i] = key[i]; + } + posn = ddLCHash(key,hash->keysize,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableInsert */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key in a hash table.] + + Description [Looks up a key consisting of more than three pointers + in a hash table. Returns the value associated to the key if there + is an entry for the given key in the table; NULL otherwise. If the + entry is present, its reference counter is decremented if not + saturated. If the counter reaches 0, the value of the entry is + dereferenced, and the entry is returned to the free list.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup1 cuddHashTableLookup2 cuddHashTableLookup3 + cuddHashTableInsert] + +******************************************************************************/ +DdNode * +cuddHashTableLookup( + DdHashTable * hash, + DdNodePtr * key) +{ + unsigned int posn; + DdHashItem *item, *prev; + unsigned int i, keysize; + +#ifdef DD_DEBUG + assert(hash->keysize > 3); +#endif + + posn = ddLCHash(key,hash->keysize,hash->shift); + item = hash->bucket[posn]; + prev = NULL; + + keysize = hash->keysize; + while (item != NULL) { + DdNodePtr *key2 = item->key; + int equal = 1; + for (i = 0; i < keysize; i++) { + if (key[i] != key2[i]) { + equal = 0; + break; + } + } + if (equal) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); + } + prev = item; + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableLookup */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key is one pointer. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert cuddHashTableInsert2 cuddHashTableInsert3 + cuddHashTableLookup1] + +******************************************************************************/ +int +cuddHashTableInsert1( + DdHashTable * hash, + DdNode * f, + DdNode * value, + ptrint count) +{ + int result; + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 1); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = value; + cuddRef(value); + item->count = count; + item->key[0] = f; + posn = ddLCHash1(f,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableInsert1 */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key consisting of one pointer in a hash table.] + + Description [Looks up a key consisting of one pointer in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup cuddHashTableLookup2 cuddHashTableLookup3 + cuddHashTableInsert1] + +******************************************************************************/ +DdNode * +cuddHashTableLookup1( + DdHashTable * hash, + DdNode * f) +{ + unsigned int posn; + DdHashItem *item, *prev; + +#ifdef DD_DEBUG + assert(hash->keysize == 1); +#endif + + posn = ddLCHash1(f,hash->shift); + item = hash->bucket[posn]; + prev = NULL; + + while (item != NULL) { + DdNodePtr *key = item->key; + if (f == key[0]) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); + } + prev = item; + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableLookup1 */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key is one + pointer and the value is not a DdNode pointer. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert1 cuddHashTableGenericLookup] + +******************************************************************************/ +int +cuddHashTableGenericInsert( + DdHashTable * hash, + DdNode * f, + void * value) +{ + int result; + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 1); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = (DdNode *) value; + item->count = 0; + item->key[0] = f; + posn = ddLCHash1(f,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableGenericInsert */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key consisting of one pointer in a hash table.] + + Description [Looks up a key consisting of one pointer in a hash + table when the value is not a DdNode pointer. Returns the value + associated to the key if there is an entry for the given key in the + table; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup1 cuddHashTableGenericInsert] + +******************************************************************************/ +void * +cuddHashTableGenericLookup( + DdHashTable * hash, + DdNode * f) +{ + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 1); +#endif + + posn = ddLCHash1(f,hash->shift); + item = hash->bucket[posn]; + + while (item != NULL) { + if (f == item->key[0]) { + return ((void *) item->value); + } + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableGenericLookup */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key is + composed of two pointers. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert3 + cuddHashTableLookup2] + +******************************************************************************/ +int +cuddHashTableInsert2( + DdHashTable * hash, + DdNode * f, + DdNode * g, + DdNode * value, + ptrint count) +{ + int result; + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 2); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = value; + cuddRef(value); + item->count = count; + item->key[0] = f; + item->key[1] = g; + posn = ddLCHash2(f,g,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableInsert2 */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key consisting of two pointers in a hash table.] + + Description [Looks up a key consisting of two pointer in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup3 + cuddHashTableInsert2] + +******************************************************************************/ +DdNode * +cuddHashTableLookup2( + DdHashTable * hash, + DdNode * f, + DdNode * g) +{ + unsigned int posn; + DdHashItem *item, *prev; + +#ifdef DD_DEBUG + assert(hash->keysize == 2); +#endif + + posn = ddLCHash2(f,g,hash->shift); + item = hash->bucket[posn]; + prev = NULL; + + while (item != NULL) { + DdNodePtr *key = item->key; + if ((f == key[0]) && (g == key[1])) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); + } + prev = item; + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableLookup2 */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key is + composed of three pointers. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert2 + cuddHashTableLookup3] + +******************************************************************************/ +int +cuddHashTableInsert3( + DdHashTable * hash, + DdNode * f, + DdNode * g, + DdNode * h, + DdNode * value, + ptrint count) +{ + int result; + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 3); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = value; + cuddRef(value); + item->count = count; + item->key[0] = f; + item->key[1] = g; + item->key[2] = h; + posn = ddLCHash3(f,g,h,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableInsert3 */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key consisting of three pointers in a hash table.] + + Description [Looks up a key consisting of three pointers in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup2 + cuddHashTableInsert3] + +******************************************************************************/ +DdNode * +cuddHashTableLookup3( + DdHashTable * hash, + DdNode * f, + DdNode * g, + DdNode * h) +{ + unsigned int posn; + DdHashItem *item, *prev; + +#ifdef DD_DEBUG + assert(hash->keysize == 3); +#endif + + posn = ddLCHash3(f,g,h,hash->shift); + item = hash->bucket[posn]; + prev = NULL; + + while (item != NULL) { + DdNodePtr *key = item->key; + if ((f == key[0]) && (g == key[1]) && (h == key[2])) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); + } + prev = item; + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableLookup3 */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Resizes a local cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +cuddLocalCacheResize( + DdLocalCache * cache) +{ + DdLocalCacheItem *item, *olditem, *entry, *old; + int i, shift; + unsigned int posn; + unsigned int slots, oldslots; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + olditem = cache->item; + oldslots = cache->slots; + slots = cache->slots = oldslots << 1; + +#ifdef DD_VERBOSE + (void) fprintf(cache->manager->err, + "Resizing local cache from %d to %d entries\n", + oldslots, slots); + (void) fprintf(cache->manager->err, + "\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n", + cache->hits, cache->lookUps, cache->hits / cache->lookUps); +#endif + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + cache->item = item = + (DdLocalCacheItem *) ALLOC(char, slots * cache->itemsize); + MMoutOfMemory = saveHandler; + /* If we fail to allocate the new table we just give up. */ + if (item == NULL) { +#ifdef DD_VERBOSE + (void) fprintf(cache->manager->err,"Resizing failed. Giving up.\n"); +#endif + cache->slots = oldslots; + cache->item = olditem; + /* Do not try to resize again. */ + cache->maxslots = oldslots - 1; + return; + } + shift = --(cache->shift); + cache->manager->memused += (slots - oldslots) * cache->itemsize; + + /* Clear new cache. */ + memset(item, 0, slots * cache->itemsize); + + /* Copy from old cache to new one. */ + for (i = 0; (unsigned) i < oldslots; i++) { + old = (DdLocalCacheItem *) ((char *) olditem + i * cache->itemsize); + if (old->value != NULL) { + posn = ddLCHash(old->key,cache->keysize,shift); + entry = (DdLocalCacheItem *) ((char *) item + + posn * cache->itemsize); + memcpy(entry->key,old->key,cache->keysize*sizeof(DdNode *)); + entry->value = old->value; + } + } + + FREE(olditem); + + /* Reinitialize measurements so as to avoid division by 0 and + ** immediate resizing. + */ + cache->lookUps = (double) (int) (slots * cache->minHit + 1); + cache->hits = 0; + +} /* end of cuddLocalCacheResize */ + + +/**Function******************************************************************** + + Synopsis [Computes the hash value for a local cache.] + + Description [Computes the hash value for a local cache. Returns the + bucket index.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static unsigned int +ddLCHash( + DdNodePtr * key, + unsigned int keysize, + int shift) +{ + unsigned int val = (unsigned int) (ptrint) key[0] * DD_P2; + unsigned int i; + + for (i = 1; i < keysize; i++) { + val = val * DD_P1 + (int) (ptrint) key[i]; + } + + return(val >> shift); + +} /* end of ddLCHash */ + + +/**Function******************************************************************** + + Synopsis [Inserts a local cache in the manager list.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +cuddLocalCacheAddToList( + DdLocalCache * cache) +{ + DdManager *manager = cache->manager; + + cache->next = manager->localCaches; + manager->localCaches = cache; + return; + +} /* end of cuddLocalCacheAddToList */ + + +/**Function******************************************************************** + + Synopsis [Removes a local cache from the manager list.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +cuddLocalCacheRemoveFromList( + DdLocalCache * cache) +{ + DdManager *manager = cache->manager; + DdLocalCache **prevCache, *nextCache; + + prevCache = &(manager->localCaches); + nextCache = manager->localCaches; + + while (nextCache != NULL) { + if (nextCache == cache) { + *prevCache = nextCache->next; + return; + } + prevCache = &(nextCache->next); + nextCache = nextCache->next; + } + return; /* should never get here */ + +} /* end of cuddLocalCacheRemoveFromList */ + + +/**Function******************************************************************** + + Synopsis [Resizes a hash table.] + + Description [Resizes a hash table. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert] + +******************************************************************************/ +static int +cuddHashTableResize( + DdHashTable * hash) +{ + int j; + unsigned int posn; + DdHashItem *item; + DdHashItem *next; + DdNode **key; + int numBuckets; + DdHashItem **buckets; + DdHashItem **oldBuckets = hash->bucket; + int shift; + int oldNumBuckets = hash->numBuckets; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + /* Compute the new size of the table. */ + numBuckets = oldNumBuckets << 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + buckets = ALLOC(DdHashItem *, numBuckets); + MMoutOfMemory = saveHandler; + if (buckets == NULL) { + hash->maxsize <<= 1; + return(1); + } + + hash->bucket = buckets; + hash->numBuckets = numBuckets; + shift = --(hash->shift); + hash->maxsize <<= 1; + memset(buckets, 0, numBuckets * sizeof(DdHashItem *)); + if (hash->keysize == 1) { + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash2(key[0], key[0], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + } else if (hash->keysize == 2) { + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash2(key[0], key[1], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + } else if (hash->keysize == 3) { + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash3(key[0], key[1], key[2], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + } else { + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + posn = ddLCHash(item->key, hash->keysize, shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + } + FREE(oldBuckets); + return(1); + +} /* end of cuddHashTableResize */ + + +/**Function******************************************************************** + + Synopsis [Fast storage allocation for items in a hash table.] + + Description [Fast storage allocation for items in a hash table. The + first 4 bytes of a chunk contain a pointer to the next block; the + rest contains DD_MEM_CHUNK spaces for hash items. Returns a pointer to + a new item if successful; NULL is memory is full.] + + SideEffects [None] + + SeeAlso [cuddAllocNode cuddDynamicAllocNode] + +******************************************************************************/ +DD_INLINE +static DdHashItem * +cuddHashTableAlloc( + DdHashTable * hash) +{ + int i; + unsigned int itemsize = hash->itemsize; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + DdHashItem **mem, *thisOne, *next, *item; + + if (hash->nextFree == NULL) { + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdHashItem **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); + MMoutOfMemory = saveHandler; + if (mem == NULL) { + if (hash->manager->stash != NULL) { + FREE(hash->manager->stash); + hash->manager->stash = NULL; + /* Inhibit resizing of tables. */ + hash->manager->maxCacheHard = hash->manager->cacheSlots - 1; + hash->manager->cacheSlack = - (int) (hash->manager->cacheSlots + 1); + for (i = 0; i < hash->manager->size; i++) { + hash->manager->subtables[i].maxKeys <<= 2; + } + hash->manager->gcFrac = 0.2; + hash->manager->minDead = + (unsigned) (0.2 * (double) hash->manager->slots); + mem = (DdHashItem **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); + } + if (mem == NULL) { + (*MMoutOfMemory)((long)((DD_MEM_CHUNK + 1) * itemsize)); + hash->manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + } + + mem[0] = (DdHashItem *) hash->memoryList; + hash->memoryList = mem; + + thisOne = (DdHashItem *) ((char *) mem + itemsize); + hash->nextFree = thisOne; + for (i = 1; i < DD_MEM_CHUNK; i++) { + next = (DdHashItem *) ((char *) thisOne + itemsize); + thisOne->next = next; + thisOne = next; + } + + thisOne->next = NULL; + + } + item = hash->nextFree; + hash->nextFree = item->next; + return(item); + +} /* end of cuddHashTableAlloc */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddLevelQ.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddLevelQ.c new file mode 100644 index 000000000..34f32c5b8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddLevelQ.c @@ -0,0 +1,583 @@ +/**CFile*********************************************************************** + + FileName [cuddLevelQ.c] + + PackageName [cudd] + + Synopsis [Procedure to manage level queues.] + + Description [The functions in this file allow an application to + easily manipulate a queue where nodes are prioritized by level. The + emphasis is on efficiency. Therefore, the queue items can have + variable size. If the application does not need to attach + information to the nodes, it can declare the queue items to be of + type DdQueueItem. Otherwise, it can declare them to be of a + structure type such that the first three fields are data + pointers. The third pointer points to the node. The first two + pointers are used by the level queue functions. The remaining fields + are initialized to 0 when a new item is created, and are then left + to the exclusive use of the application. On the DEC Alphas the three + pointers must be 32-bit pointers when CUDD is compiled with 32-bit + pointers. The level queue functions make sure that each node + appears at most once in the queue. They do so by keeping a hash + table where the node is used as key. Queue items are recycled via a + free list for efficiency. + + Internal procedures provided by this module: +
                +
              • cuddLevelQueueInit() +
              • cuddLevelQueueQuit() +
              • cuddLevelQueueEnqueue() +
              • cuddLevelQueueDequeue() +
              + Static procedures included in this module: +
                +
              • hashLookup() +
              • hashInsert() +
              • hashDelete() +
              • hashResize() +
              + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.16 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**Macro*********************************************************************** + + Synopsis [Hash function for the table of a level queue.] + + Description [Hash function for the table of a level queue.] + + SideEffects [None] + + SeeAlso [hashInsert hashLookup hashDelete] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define lqHash(key,shift) \ +(((unsigned)(ptruint)(key) * DD_P1) >> (shift)) +#else +#define lqHash(key,shift) \ +(((unsigned)(key) * DD_P1) >> (shift)) +#endif + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdQueueItem * hashLookup(DdLevelQueue *queue, void *key); +static int hashInsert(DdLevelQueue *queue, DdQueueItem *item); +static void hashDelete(DdLevelQueue *queue, DdQueueItem *item); +static int hashResize(DdLevelQueue *queue); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes a level queue.] + + Description [Initializes a level queue. A level queue is a queue + where inserts are based on the levels of the nodes. Within each + level the policy is FIFO. Level queues are useful in traversing a + BDD top-down. Queue items are kept in a free list when dequeued for + efficiency. Returns a pointer to the new queue if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueQuit cuddLevelQueueEnqueue cuddLevelQueueDequeue] + +******************************************************************************/ +DdLevelQueue * +cuddLevelQueueInit( + int levels /* number of levels */, + int itemSize /* size of the item */, + int numBuckets /* initial number of hash buckets */) +{ + DdLevelQueue *queue; + int logSize; + + queue = ALLOC(DdLevelQueue,1); + if (queue == NULL) + return(NULL); + /* Keep pointers to the insertion points for all levels. */ + queue->last = ALLOC(DdQueueItem *, levels); + if (queue->last == NULL) { + FREE(queue); + return(NULL); + } + /* Use a hash table to test for uniqueness. */ + if (numBuckets < 2) numBuckets = 2; + logSize = cuddComputeFloorLog2(numBuckets); + queue->numBuckets = 1 << logSize; + queue->shift = sizeof(int) * 8 - logSize; + queue->buckets = ALLOC(DdQueueItem *, queue->numBuckets); + if (queue->buckets == NULL) { + FREE(queue->last); + FREE(queue); + return(NULL); + } + memset(queue->last, 0, levels * sizeof(DdQueueItem *)); + memset(queue->buckets, 0, queue->numBuckets * sizeof(DdQueueItem *)); + queue->first = NULL; + queue->freelist = NULL; + queue->levels = levels; + queue->itemsize = itemSize; + queue->size = 0; + queue->maxsize = queue->numBuckets * DD_MAX_SUBTABLE_DENSITY; + return(queue); + +} /* end of cuddLevelQueueInit */ + + +/**Function******************************************************************** + + Synopsis [Shuts down a level queue.] + + Description [Shuts down a level queue and releases all the + associated memory.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueInit] + +******************************************************************************/ +void +cuddLevelQueueQuit( + DdLevelQueue * queue) +{ + DdQueueItem *item; + + while (queue->freelist != NULL) { + item = queue->freelist; + queue->freelist = item->next; + FREE(item); + } + while (queue->first != NULL) { + item = (DdQueueItem *) queue->first; + queue->first = item->next; + FREE(item); + } + FREE(queue->buckets); + FREE(queue->last); + FREE(queue); + return; + +} /* end of cuddLevelQueueQuit */ + + +/**Function******************************************************************** + + Synopsis [Inserts a new key in a level queue.] + + Description [Inserts a new key in a level queue. A new entry is + created in the queue only if the node is not already + enqueued. Returns a pointer to the queue item if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueInit cuddLevelQueueDequeue] + +******************************************************************************/ +void * +cuddLevelQueueEnqueue( + DdLevelQueue * queue /* level queue */, + void * key /* key to be enqueued */, + int level /* level at which to insert */) +{ + DdQueueItem *item; + +#ifdef DD_DEBUG + assert(level < queue->levels); +#endif + /* Check whether entry for this node exists. */ + item = hashLookup(queue,key); + if (item != NULL) return(item); + + /* Get a free item from either the free list or the memory manager. */ + if (queue->freelist == NULL) { + item = (DdQueueItem *) ALLOC(char, queue->itemsize); + if (item == NULL) + return(NULL); + } else { + item = queue->freelist; + queue->freelist = item->next; + } + /* Initialize. */ + memset(item, 0, queue->itemsize); + item->key = key; + /* Update stats. */ + queue->size++; + + if (queue->last[level]) { + /* There are already items for this level in the queue. */ + item->next = queue->last[level]->next; + queue->last[level]->next = item; + } else { + /* There are no items at the current level. Look for the first + ** non-empty level preceeding this one. */ + int plevel = level; + while (plevel != 0 && queue->last[plevel] == NULL) + plevel--; + if (queue->last[plevel] == NULL) { + /* No element precedes this one in the queue. */ + item->next = (DdQueueItem *) queue->first; + queue->first = item; + } else { + item->next = queue->last[plevel]->next; + queue->last[plevel]->next = item; + } + } + queue->last[level] = item; + + /* Insert entry for the key in the hash table. */ + if (hashInsert(queue,item) == 0) { + return(NULL); + } + return(item); + +} /* end of cuddLevelQueueEnqueue */ + + +/**Function******************************************************************** + + Synopsis [Inserts the first key in a level queue.] + + Description [Inserts the first key in a level queue. Returns a + pointer to the queue item if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueEnqueue] + +******************************************************************************/ +void * +cuddLevelQueueFirst( + DdLevelQueue * queue /* level queue */, + void * key /* key to be enqueued */, + int level /* level at which to insert */) +{ + DdQueueItem *item; + +#ifdef DD_DEBUG + assert(level < queue->levels); + /* Check whether entry for this node exists. */ + item = hashLookup(queue,key); + assert(item == NULL); +#endif + + /* Get a free item from either the free list or the memory manager. */ + if (queue->freelist == NULL) { + item = (DdQueueItem *) ALLOC(char, queue->itemsize); + if (item == NULL) + return(NULL); + } else { + item = queue->freelist; + queue->freelist = item->next; + } + /* Initialize. */ + memset(item, 0, queue->itemsize); + item->key = key; + /* Update stats. */ + queue->size = 1; + + /* No element precedes this one in the queue. */ + queue->first = item; + queue->last[level] = item; + + /* Insert entry for the key in the hash table. */ + if (hashInsert(queue,item) == 0) { + return(NULL); + } + return(item); + +} /* end of cuddLevelQueueFirst */ + + +/**Function******************************************************************** + + Synopsis [Remove an item from the front of a level queue.] + + Description [Remove an item from the front of a level queue.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueEnqueue] + +******************************************************************************/ +void +cuddLevelQueueDequeue( + DdLevelQueue * queue, + int level) +{ + DdQueueItem *item = (DdQueueItem *) queue->first; + + /* Delete from the hash table. */ + hashDelete(queue,item); + + /* Since we delete from the front, if this is the last item for + ** its level, there are no other items for the same level. */ + if (queue->last[level] == item) { + queue->last[level] = NULL; + } + + queue->first = item->next; + /* Put item on the free list. */ + item->next = queue->freelist; + queue->freelist = item; + /* Update stats. */ + queue->size--; + return; + +} /* end of cuddLevelQueueDequeue */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Looks up a key in the hash table of a level queue.] + + Description [Looks up a key in the hash table of a level queue. Returns + a pointer to the item with the given key if the key is found; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueEnqueue hashInsert] + +******************************************************************************/ +static DdQueueItem * +hashLookup( + DdLevelQueue * queue, + void * key) +{ + int posn; + DdQueueItem *item; + + posn = lqHash(key,queue->shift); + item = queue->buckets[posn]; + + while (item != NULL) { + if (item->key == key) { + return(item); + } + item = item->cnext; + } + return(NULL); + +} /* end of hashLookup */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in the hash table of a level queue.] + + Description [Inserts an item in the hash table of a level queue. Returns + 1 if successful; 0 otherwise. No check is performed to see if an item with + the same key is already in the hash table.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueEnqueue] + +******************************************************************************/ +static int +hashInsert( + DdLevelQueue * queue, + DdQueueItem * item) +{ + int result; + int posn; + + if (queue->size > queue->maxsize) { + result = hashResize(queue); + if (result == 0) return(0); + } + + posn = lqHash(item->key,queue->shift); + item->cnext = queue->buckets[posn]; + queue->buckets[posn] = item; + + return(1); + +} /* end of hashInsert */ + + +/**Function******************************************************************** + + Synopsis [Removes an item from the hash table of a level queue.] + + Description [Removes an item from the hash table of a level queue. + Nothing is done if the item is not in the table.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueDequeue hashInsert] + +******************************************************************************/ +static void +hashDelete( + DdLevelQueue * queue, + DdQueueItem * item) +{ + int posn; + DdQueueItem *prevItem; + + posn = lqHash(item->key,queue->shift); + prevItem = queue->buckets[posn]; + + if (prevItem == NULL) return; + if (prevItem == item) { + queue->buckets[posn] = prevItem->cnext; + return; + } + + while (prevItem->cnext != NULL) { + if (prevItem->cnext == item) { + prevItem->cnext = item->cnext; + return; + } + prevItem = prevItem->cnext; + } + return; + +} /* end of hashDelete */ + + +/**Function******************************************************************** + + Synopsis [Resizes the hash table of a level queue.] + + Description [Resizes the hash table of a level queue. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [hashInsert] + +******************************************************************************/ +static int +hashResize( + DdLevelQueue * queue) +{ + int j; + int posn; + DdQueueItem *item; + DdQueueItem *next; + int numBuckets; + DdQueueItem **buckets; + DdQueueItem **oldBuckets = queue->buckets; + int shift; + int oldNumBuckets = queue->numBuckets; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + /* Compute the new size of the subtable. */ + numBuckets = oldNumBuckets << 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + buckets = queue->buckets = ALLOC(DdQueueItem *, numBuckets); + MMoutOfMemory = saveHandler; + if (buckets == NULL) { + queue->maxsize <<= 1; + return(1); + } + + queue->numBuckets = numBuckets; + shift = --(queue->shift); + queue->maxsize <<= 1; + memset(buckets, 0, numBuckets * sizeof(DdQueueItem *)); + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->cnext; + posn = lqHash(item->key, shift); + item->cnext = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + FREE(oldBuckets); + return(1); + +} /* end of hashResize */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddLinear.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddLinear.c new file mode 100644 index 000000000..387989004 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddLinear.c @@ -0,0 +1,1365 @@ +/**CFile*********************************************************************** + + FileName [cuddLinear.c] + + PackageName [cudd] + + Synopsis [Functions for DD reduction by linear transformations.] + + Description [ Internal procedures included in this module: +
                +
              • cuddLinearAndSifting() +
              • cuddLinearInPlace() +
              • cuddUpdateInteractionMatrix() +
              • cuddInitLinear() +
              • cuddResizeLinear() +
              + Static procedures included in this module: +
                +
              • ddLinearUniqueCompare() +
              • ddLinearAndSiftingAux() +
              • ddLinearAndSiftingUp() +
              • ddLinearAndSiftingDown() +
              • ddLinearAndSiftingBackward() +
              • ddUndoMoves() +
              • cuddXorLinear() +
              ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define CUDD_SWAP_MOVE 0 +#define CUDD_LINEAR_TRANSFORM_MOVE 1 +#define CUDD_INVERSE_TRANSFORM_MOVE 2 +#if SIZEOF_LONG == 8 +#define BPL 64 +#define LOGBPL 6 +#else +#define BPL 32 +#define LOGBPL 5 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddLinear.c,v 1.29 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int *entry; + +#ifdef DD_STATS +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +static int ddTotalNumberLinearTr; +#endif + +#ifdef DD_DEBUG +static int zero = 0; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddLinearUniqueCompare (int *ptrX, int *ptrY); +static int ddLinearAndSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddLinearAndSiftingUp (DdManager *table, int y, int xLow, Move *prevMoves); +static Move * ddLinearAndSiftingDown (DdManager *table, int x, int xHigh, Move *prevMoves); +static int ddLinearAndSiftingBackward (DdManager *table, int size, Move *moves); +static Move* ddUndoMoves (DdManager *table, Move *moves); +static void cuddXorLinear (DdManager *table, int x, int y); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints the linear transform matrix.] + + Description [Prints the linear transform matrix. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_PrintLinear( + DdManager * table) +{ + int i,j,k; + int retval; + int nvars = table->linearSize; + int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + long word; + + for (i = 0; i < nvars; i++) { + for (j = 0; j < wordsPerRow; j++) { + word = table->linear[i*wordsPerRow + j]; + for (k = 0; k < BPL; k++) { + retval = fprintf(table->out,"%ld",word & 1); + if (retval == 0) return(0); + word >>= 1; + } + } + retval = fprintf(table->out,"\n"); + if (retval == 0) return(0); + } + return(1); + +} /* end of Cudd_PrintLinear */ + + +/**Function******************************************************************** + + Synopsis [Reads an entry of the linear transform matrix.] + + Description [Reads an entry of the linear transform matrix.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ReadLinear( + DdManager * table /* CUDD manager */, + int x /* row index */, + int y /* column index */) +{ + int nvars = table->size; + int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + long word; + int bit; + int result; + + assert(table->size == table->linearSize); + + word = wordsPerRow * x + (y >> LOGBPL); + bit = y & (BPL-1); + result = (int) ((table->linear[word] >> bit) & 1); + return(result); + +} /* end of Cudd_ReadLinear */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [BDD reduction based on combination of sifting and linear + transformations.] + + Description [BDD reduction based on combination of sifting and linear + transformations. Assumes that no dead nodes are present. +
                +
              1. Order all the variables according to the number of entries + in each unique table. +
              2. Sift the variable up and down, remembering each time the + total size of the DD heap. At each position, linear transformation + of the two adjacent variables is tried and is accepted if it reduces + the size of the DD. +
              3. Select the best permutation. +
              4. Repeat 3 and 4 for all variables. +
              + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddLinearAndSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; +#ifdef DD_STATS + int previousSize; +#endif + +#ifdef DD_STATS + ddTotalNumberLinearTr = 0; +#endif + + size = table->size; + + var = NULL; + entry = NULL; + if (table->linear == NULL) { + result = cuddInitLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; +#if 0 + (void) fprintf(table->out,"\n"); + result = Cudd_PrintLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; +#endif + } else if (table->size != table->linearSize) { + result = cuddResizeLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; +#if 0 + (void) fprintf(table->out,"\n"); + result = Cudd_PrintLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; +#endif + } + + /* Find order in which to sift variables. */ + entry = ALLOC(int,size); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddLinearAndSiftingOutOfMem; + } + var = ALLOC(int,size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddLinearAndSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; + } + + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddLinearUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { + x = table->perm[var[i]]; + if (x < lower || x > upper) continue; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddLinearAndSiftingAux(table,x,lower,upper); + if (!result) goto cuddLinearAndSiftingOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif +#ifdef DD_DEBUG + (void) Cudd_DebugCheck(table); +#endif + } + + FREE(var); + FREE(entry); + +#ifdef DD_STATS + (void) fprintf(table->out,"\n#:L_LINSIFT %8d: linear trans.", + ddTotalNumberLinearTr); +#endif + + return(1); + +cuddLinearAndSiftingOutOfMem: + + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddLinearAndSifting */ + + +/**Function******************************************************************** + + Synopsis [Linearly combines two adjacent variables.] + + Description [Linearly combines two adjacent variables. Specifically, + replaces the top variable with the exclusive nor of the two variables. + It assumes that no dead nodes are present on entry to this + procedure. The procedure then guarantees that no dead nodes will be + present when it terminates. cuddLinearInPlace assumes that x < + y. Returns the number of keys in the table if successful; 0 + otherwise.] + + SideEffects [The two subtables corrresponding to variables x and y are + modified. The global counters of the unique table are also affected.] + + SeeAlso [cuddSwapInPlace] + +******************************************************************************/ +int +cuddLinearInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int comple, newcomplement; + int i; + int posn; + int isolated; + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0; + DdNode *g,*next,*last; + DdNodePtr *previousP; + DdNode *tmp; + DdNode *sentinel = &(table->sentinel); +#ifdef DD_DEBUG + int count, idcheck; +#endif + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddNextHigh(table,x) == y); + assert(table->subtables[x].keys != 0); + assert(table->subtables[y].keys != 0); + assert(table->subtables[x].dead == 0); + assert(table->subtables[y].dead == 0); +#endif + + xindex = table->invperm[x]; + yindex = table->invperm[y]; + + if (cuddTestInteract(table,xindex,yindex)) { +#ifdef DD_STATS + ddTotalNumberLinearTr++; +#endif + /* Get parameters of x subtable. */ + xlist = table->subtables[x].nodelist; + oldxkeys = table->subtables[x].keys; + xslots = table->subtables[x].slots; + xshift = table->subtables[x].shift; + + /* Get parameters of y subtable. */ + ylist = table->subtables[y].nodelist; + oldykeys = table->subtables[y].keys; + yslots = table->subtables[y].slots; + yshift = table->subtables[y].shift; + + newxkeys = 0; + newykeys = oldykeys; + + /* Check whether the two projection functions involved in this + ** swap are isolated. At the end, we'll be able to tell how many + ** isolated projection functions are there by checking only these + ** two functions again. This is done to eliminate the isolated + ** projection functions from the node count. + */ + isolated = - ((table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1)); + + /* The nodes in the x layer are put in a chain. + ** The chain is handled as a FIFO; g points to the beginning and + ** last points to the end. + */ + g = NULL; +#ifdef DD_DEBUG + last = NULL; +#endif + for (i = 0; i < xslots; i++) { + f = xlist[i]; + if (f == sentinel) continue; + xlist[i] = sentinel; + if (g == NULL) { + g = f; + } else { + last->next = f; + } + while ((next = f->next) != sentinel) { + f = next; + } /* while there are elements in the collision chain */ + last = f; + } /* for each slot of the x subtable */ +#ifdef DD_DEBUG + /* last is always assigned in the for loop because there is at + ** least one key */ + assert(last != NULL); +#endif + last->next = NULL; + +#ifdef DD_COUNT + table->swapSteps += oldxkeys; +#endif + /* Take care of the x nodes that must be re-expressed. + ** They form a linked list pointed by g. + */ + f = g; + while (f != NULL) { + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f1))); +#endif + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = f10 = f1; + } +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f11))); +#endif + f0 = cuddE(f); + comple = Cudd_IsComplement(f0); + f0 = Cudd_Regular(f0); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == f00) { + newf1 = f11; + cuddSatInc(newf1->ref); + } else { + /* Check ylist for triple (yindex,f11,f00). */ + posn = ddHash(f11, f00, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + previousP = &(ylist[posn]); + newf1 = *previousP; + while (f11 < cuddT(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + while (f11 == cuddT(newf1) && f00 < cuddE(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + if (cuddT(newf1) == f11 && cuddE(newf1) == f00) { + cuddSatInc(newf1->ref); + } else { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto cuddLinearOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f00; + /* Insert newf1 in the collision list ylist[posn]; + ** increase the ref counts of f11 and f00. + */ + newykeys++; + newf1->next = *previousP; + *previousP = newf1; + cuddSatInc(f11->ref); + tmp = Cudd_Regular(f00); + cuddSatInc(tmp->ref); + } + } + cuddT(f) = newf1; +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(newf1))); +#endif + + /* Do the same for f0, keeping complement dots into account. */ + /* decrease ref count of f0 */ + tmp = Cudd_Regular(f0); + cuddSatDec(tmp->ref); + /* create the new E child */ + if (f01 == f10) { + newf0 = f01; + tmp = Cudd_Regular(newf0); + cuddSatInc(tmp->ref); + } else { + /* make sure f01 is regular */ + newcomplement = Cudd_IsComplement(f01); + if (newcomplement) { + f01 = Cudd_Not(f01); + f10 = Cudd_Not(f10); + } + /* Check ylist for triple (yindex,f01,f10). */ + posn = ddHash(f01, f10, yshift); + /* For each element newf0 in collision list ylist[posn]. */ + previousP = &(ylist[posn]); + newf0 = *previousP; + while (f01 < cuddT(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + while (f01 == cuddT(newf0) && f10 < cuddE(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + if (cuddT(newf0) == f01 && cuddE(newf0) == f10) { + cuddSatInc(newf0->ref); + } else { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto cuddLinearOutOfMem; + newf0->index = yindex; newf0->ref = 1; + cuddT(newf0) = f01; + cuddE(newf0) = f10; + /* Insert newf0 in the collision list ylist[posn]; + ** increase the ref counts of f01 and f10. + */ + newykeys++; + newf0->next = *previousP; + *previousP = newf0; + cuddSatInc(f01->ref); + tmp = Cudd_Regular(f10); + cuddSatInc(tmp->ref); + } + if (newcomplement) { + newf0 = Cudd_Not(newf0); + } + } + cuddE(f) = newf0; + + /* Re-insert the modified f in xlist. + ** The modified f does not already exists in xlist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, xshift); + newxkeys++; + previousP = &(xlist[posn]); + tmp = *previousP; + while (newf1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; + *previousP = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previousP = &(ylist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + if (f->ref == 0) { + tmp = cuddT(f); + cuddSatDec(tmp->ref); + tmp = Cudd_Regular(cuddE(f)); + cuddSatDec(tmp->ref); + cuddDeallocNode(table,f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = sentinel; + } /* for every collision list */ + +#ifdef DD_DEBUG +#if 0 + (void) fprintf(table->out,"Linearly combining %d and %d\n",x,y); +#endif + count = 0; + idcheck = 0; + for (i = 0; i < yslots; i++) { + f = ylist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) yindex) + idcheck++; + f = f->next; + } + } + if (count != newykeys) { + fprintf(table->err,"Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",oldykeys,newykeys,count); + } + if (idcheck != 0) + fprintf(table->err,"Error in id's of ylist\twrong id's = %d\n",idcheck); + count = 0; + idcheck = 0; + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) xindex) + idcheck++; + f = f->next; + } + } + if (count != newxkeys || newxkeys != oldxkeys) { + fprintf(table->err,"Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",oldxkeys,newxkeys,count); + } + if (idcheck != 0) + fprintf(table->err,"Error in id's of xlist\twrong id's = %d\n",idcheck); +#endif + + isolated += (table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1); + table->isolated += isolated; + + /* Set the appropriate fields in table. */ + table->subtables[y].keys = newykeys; + + /* Here we should update the linear combination table + ** to record that x <- x EXNOR y. This is done by complementing + ** the (x,y) entry of the table. + */ + + table->keys += newykeys - oldykeys; + + cuddXorLinear(table,xindex,yindex); + } + +#ifdef DD_DEBUG + if (zero) { + (void) Cudd_DebugCheck(table); + } +#endif + + return(table->keys - table->isolated); + +cuddLinearOutOfMem: + (void) fprintf(table->err,"Error: cuddLinearInPlace out of memory\n"); + + return (0); + +} /* end of cuddLinearInPlace */ + + +/**Function******************************************************************** + + Synopsis [Updates the interaction matrix.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +void +cuddUpdateInteractionMatrix( + DdManager * table, + int xindex, + int yindex) +{ + int i; + for (i = 0; i < yindex; i++) { + if (i != xindex && cuddTestInteract(table,i,yindex)) { + if (i < xindex) { + cuddSetInteract(table,i,xindex); + } else { + cuddSetInteract(table,xindex,i); + } + } + } + for (i = yindex+1; i < table->size; i++) { + if (i != xindex && cuddTestInteract(table,yindex,i)) { + if (i < xindex) { + cuddSetInteract(table,i,xindex); + } else { + cuddSetInteract(table,xindex,i); + } + } + } + +} /* end of cuddUpdateInteractionMatrix */ + + +/**Function******************************************************************** + + Synopsis [Initializes the linear transform matrix.] + + Description [Initializes the linear transform matrix. Returns 1 if + successful; 0 otherwise.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +cuddInitLinear( + DdManager * table) +{ + int words; + int wordsPerRow; + int nvars; + int word; + int bit; + int i; + long *linear; + + nvars = table->size; + wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + words = wordsPerRow * nvars; + table->linear = linear = ALLOC(long,words); + if (linear == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + table->memused += words * sizeof(long); + table->linearSize = nvars; + for (i = 0; i < words; i++) linear[i] = 0; + for (i = 0; i < nvars; i++) { + word = wordsPerRow * i + (i >> LOGBPL); + bit = i & (BPL-1); + linear[word] = 1 << bit; + } + return(1); + +} /* end of cuddInitLinear */ + + +/**Function******************************************************************** + + Synopsis [Resizes the linear transform matrix.] + + Description [Resizes the linear transform matrix. Returns 1 if + successful; 0 otherwise.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +cuddResizeLinear( + DdManager * table) +{ + int words,oldWords; + int wordsPerRow,oldWordsPerRow; + int nvars,oldNvars; + int word,oldWord; + int bit; + int i,j; + long *linear,*oldLinear; + + oldNvars = table->linearSize; + oldWordsPerRow = ((oldNvars - 1) >> LOGBPL) + 1; + oldWords = oldWordsPerRow * oldNvars; + oldLinear = table->linear; + + nvars = table->size; + wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + words = wordsPerRow * nvars; + table->linear = linear = ALLOC(long,words); + if (linear == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + table->memused += (words - oldWords) * sizeof(long); + for (i = 0; i < words; i++) linear[i] = 0; + + /* Copy old matrix. */ + for (i = 0; i < oldNvars; i++) { + for (j = 0; j < oldWordsPerRow; j++) { + oldWord = oldWordsPerRow * i + j; + word = wordsPerRow * i + j; + linear[word] = oldLinear[oldWord]; + } + } + FREE(oldLinear); + + /* Add elements to the diagonal. */ + for (i = oldNvars; i < nvars; i++) { + word = wordsPerRow * i + (i >> LOGBPL); + bit = i & (BPL-1); + linear[word] = 1 << bit; + } + table->linearSize = nvars; + + return(1); + +} /* end of cuddResizeLinear */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + +******************************************************************************/ +static int +ddLinearUniqueCompare( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of ddLinearUniqueCompare */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. At each step a linear transformation is tried, and, if it + decreases the size of the DD, it is accepted. Finds the best position + and does the required changes. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddLinearAndSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; + + initialSize = table->keys - table->isolated; + + moveDown = NULL; + moveUp = NULL; + + if (x == xLow) { + moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; + + } else if (x == xHigh) { + moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + moveUp = ddUndoMoves(table,moveDown); +#ifdef DD_DEBUG + assert(moveUp == NULL || moveUp->x == x); +#endif + moveUp = ddLinearAndSiftingUp(table,x,xLow,moveUp); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; + + } else { /* must go up first: shorter */ + moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + moveDown = ddUndoMoves(table,moveUp); +#ifdef DD_DEBUG + assert(moveDown == NULL || moveDown->y == x); +#endif + moveDown = ddLinearAndSiftingDown(table,x,xHigh,moveDown); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +ddLinearAndSiftingAuxOutOfMem: + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(0); + +} /* end of ddLinearAndSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable up and applies linear transformations.] + + Description [Sifts a variable up and applies linear transformations. + Moves y up until either it reaches the bound (xLow) or the size of + the DD heap increases too much. Returns the set of moves in case of + success; NULL if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddLinearAndSiftingUp( + DdManager * table, + int y, + int xLow, + Move * prevMoves) +{ + Move *moves; + Move *move; + int x; + int size, newsize; + int limitSize; + int xindex, yindex; + int isolated; + int L; /* lower bound on DD size */ +#ifdef DD_DEBUG + int checkL; + int z; + int zindex; +#endif + + moves = prevMoves; + yindex = table->invperm[y]; + + /* Initialize the lower bound. + ** The part of the DD below y will not change. + ** The part of the DD above y that does not interact with y will not + ** change. The rest may vanish in the best case, except for + ** the nodes at level xLow, which will not vanish, regardless. + */ + limitSize = L = table->keys - table->isolated; + for (x = xLow + 1; x < y; x++) { + xindex = table->invperm[x]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L -= table->subtables[x].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + L -= table->subtables[y].keys - isolated; + + x = cuddNextLow(table,y); + while (x >= xLow && L <= limitSize) { + xindex = table->invperm[x]; +#ifdef DD_DEBUG + checkL = table->keys - table->isolated; + for (z = xLow + 1; z < y; z++) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + checkL -= table->subtables[y].keys - isolated; + if (L != checkL) { + (void) fprintf(table->out, "checkL(%d) != L(%d)\n",checkL,L); + } +#endif + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddLinearAndSiftingUpOutOfMem; + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddLinearAndSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize >= size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem; +#ifdef DD_DEBUG + if (newsize != size) { + (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } +#endif + } else if (cuddTestInteract(table,xindex,yindex)) { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + cuddUpdateInteractionMatrix(table,xindex,yindex); + } + move->size = size; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + y = x; + x = cuddNextLow(table,y); + } + return(moves); + +ddLinearAndSiftingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddLinearAndSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable down and applies linear transformations.] + + Description [Sifts a variable down and applies linear + transformations. Moves x down until either it reaches the bound + (xHigh) or the size of the DD heap increases too much. Returns the + set of moves in case of success; NULL if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddLinearAndSiftingDown( + DdManager * table, + int x, + int xHigh, + Move * prevMoves) +{ + Move *moves; + Move *move; + int y; + int size, newsize; + int R; /* upper bound on node decrease */ + int limitSize; + int xindex, yindex; + int isolated; +#ifdef DD_DEBUG + int checkR; + int z; + int zindex; +#endif + + moves = prevMoves; + /* Initialize R */ + xindex = table->invperm[x]; + limitSize = size = table->keys - table->isolated; + R = 0; + for (y = xHigh; y > x; y--) { + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R += table->subtables[y].keys - isolated; + } + } + + y = cuddNextHigh(table,x); + while (y <= xHigh && size - R < limitSize) { +#ifdef DD_DEBUG + checkR = 0; + for (z = xHigh; z > x; z--) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + if (R != checkR) { + (void) fprintf(table->out, "checkR(%d) != R(%d)\n",checkR,R); + } +#endif + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddLinearAndSiftingDownOutOfMem; + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddLinearAndSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize >= size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem; + if (newsize != size) { + (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } + } else if (cuddTestInteract(table,xindex,yindex)) { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + cuddUpdateInteractionMatrix(table,xindex,yindex); + } + move->size = size; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + x = y; + y = cuddNextHigh(table,x); + } + return(moves); + +ddLinearAndSiftingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddLinearAndSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the DD heap to the order + giving the minimum size.] + + Description [Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddLinearAndSiftingBackward( + DdManager * table, + int size, + Move * moves) +{ + Move *move; + int res; + + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + res = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { + res = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + } + + return(1); + +} /* end of ddLinearAndSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the DD heap to the order + in effect before the moves.] + + Description [Given a set of moves, returns the DD heap to the + order in effect before the moves. Returns 1 in case of success; + 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static Move* +ddUndoMoves( + DdManager * table, + Move * moves) +{ + Move *invmoves = NULL; + Move *move; + Move *invmove; + int size; + + for (move = moves; move != NULL; move = move->next) { + invmove = (Move *) cuddDynamicAllocNode(table); + if (invmove == NULL) goto ddUndoMovesOutOfMem; + invmove->x = move->x; + invmove->y = move->y; + invmove->next = invmoves; + invmoves = invmove; + if (move->flags == CUDD_SWAP_MOVE) { + invmove->flags = CUDD_SWAP_MOVE; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; + size = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ +#ifdef DD_DEBUG + (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); +#endif + invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + size = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } + invmove->size = size; + } + + return(invmoves); + +ddUndoMovesOutOfMem: + while (invmoves != NULL) { + move = invmoves->next; + cuddDeallocMove(table, invmoves); + invmoves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddUndoMoves */ + + +/**Function******************************************************************** + + Synopsis [XORs two rows of the linear transform matrix.] + + Description [XORs two rows of the linear transform matrix and replaces + the first row with the result.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static void +cuddXorLinear( + DdManager * table, + int x, + int y) +{ + int i; + int nvars = table->size; + int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + int xstart = wordsPerRow * x; + int ystart = wordsPerRow * y; + long *linear = table->linear; + + for (i = 0; i < wordsPerRow; i++) { + linear[xstart+i] ^= linear[ystart+i]; + } + +} /* end of cuddXorLinear */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddLiteral.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddLiteral.c new file mode 100644 index 000000000..b81697028 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddLiteral.c @@ -0,0 +1,264 @@ +/**CFile*********************************************************************** + + FileName [cuddLiteral.c] + + PackageName [cudd] + + Synopsis [Functions for manipulation of literal sets represented by + BDDs.] + + Description [External procedures included in this file: +
                +
              • Cudd_bddLiteralSetIntersection() +
              + Internal procedures included in this file: +
                +
              • cuddBddLiteralSetIntersectionRecur() +
              ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddLiteral.c,v 1.9 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the intesection of two sets of literals + represented as BDDs.] + + Description [Computes the intesection of two sets of literals + represented as BDDs. Each set is represented as a cube of the + literals in the set. The empty set is represented by the constant 1. + No variable can be simultaneously present in both phases in a set. + Returns a pointer to the BDD representing the intersected sets, if + successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_bddLiteralSetIntersection( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddLiteralSetIntersectionRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddLiteralSetIntersection */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of + Cudd_bddLiteralSetIntersection.] + + Description [Performs the recursive step of + Cudd_bddLiteralSetIntersection. Scans the cubes for common variables, + and checks whether they agree in phase. Returns a pointer to the + resulting cube if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddBddLiteralSetIntersectionRecur( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res, *tmp; + DdNode *F, *G; + DdNode *fc, *gc; + DdNode *one; + DdNode *zero; + unsigned int topf, topg, comple; + int phasef, phaseg; + + statLine(dd); + if (f == g) return(f); + + F = Cudd_Regular(f); + G = Cudd_Regular(g); + one = DD_ONE(dd); + + /* Here f != g. If F == G, then f and g are complementary. + ** Since they are two cubes, this case only occurs when f == v, + ** g == v', and v is a variable or its complement. + */ + if (F == G) return(one); + + zero = Cudd_Not(one); + topf = cuddI(dd,F->index); + topg = cuddI(dd,G->index); + /* Look for a variable common to both cubes. If there are none, this + ** loop will stop when the constant node is reached in both cubes. + */ + while (topf != topg) { + if (topf < topg) { /* move down on f */ + comple = f != F; + f = cuddT(F); + if (comple) f = Cudd_Not(f); + if (f == zero) { + f = cuddE(F); + if (comple) f = Cudd_Not(f); + } + F = Cudd_Regular(f); + topf = cuddI(dd,F->index); + } else if (topg < topf) { + comple = g != G; + g = cuddT(G); + if (comple) g = Cudd_Not(g); + if (g == zero) { + g = cuddE(G); + if (comple) g = Cudd_Not(g); + } + G = Cudd_Regular(g); + topg = cuddI(dd,G->index); + } + } + + /* At this point, f == one <=> g == 1. It suffices to test one of them. */ + if (f == one) return(one); + + res = cuddCacheLookup2(dd,Cudd_bddLiteralSetIntersection,f,g); + if (res != NULL) { + return(res); + } + + /* Here f and g are both non constant and have the same top variable. */ + comple = f != F; + fc = cuddT(F); + phasef = 1; + if (comple) fc = Cudd_Not(fc); + if (fc == zero) { + fc = cuddE(F); + phasef = 0; + if (comple) fc = Cudd_Not(fc); + } + comple = g != G; + gc = cuddT(G); + phaseg = 1; + if (comple) gc = Cudd_Not(gc); + if (gc == zero) { + gc = cuddE(G); + phaseg = 0; + if (comple) gc = Cudd_Not(gc); + } + + tmp = cuddBddLiteralSetIntersectionRecur(dd,fc,gc); + if (tmp == NULL) { + return(NULL); + } + + if (phasef != phaseg) { + res = tmp; + } else { + cuddRef(tmp); + if (phasef == 0) { + res = cuddBddAndRecur(dd,Cudd_Not(dd->vars[F->index]),tmp); + } else { + res = cuddBddAndRecur(dd,dd->vars[F->index],tmp); + } + if (res == NULL) { + Cudd_RecursiveDeref(dd,tmp); + return(NULL); + } + cuddDeref(tmp); /* Just cuddDeref, because it is included in result */ + } + + cuddCacheInsert2(dd,Cudd_bddLiteralSetIntersection,f,g,res); + + return(res); + +} /* end of cuddBddLiteralSetIntersectionRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddMatMult.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddMatMult.c new file mode 100644 index 000000000..adcbdc79f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddMatMult.c @@ -0,0 +1,707 @@ +/**CFile*********************************************************************** + + FileName [cuddMatMult.c] + + PackageName [cudd] + + Synopsis [Matrix multiplication functions.] + + Description [External procedures included in this module: +
                +
              • Cudd_addMatrixMultiply() +
              • Cudd_addTimesPlus() +
              • Cudd_addTriangle() +
              • Cudd_addOuterSum() +
              + Static procedures included in this module: +
                +
              • addMMRecur() +
              • addTriangleRecur() +
              • cuddAddOuterSumRecur() +
              ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.18 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addMMRecur (DdManager *dd, DdNode *A, DdNode *B, int topP, int *vars); +static DdNode * addTriangleRecur (DdManager *dd, DdNode *f, DdNode *g, int *vars, DdNode *cube); +static DdNode * cuddAddOuterSumRecur (DdManager *dd, DdNode *M, DdNode *r, DdNode *c); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Calculates the product of two matrices represented as + ADDs.] + + Description [Calculates the product of two matrices, A and B, + represented as ADDs. This procedure implements the quasiring multiplication + algorithm. A is assumed to depend on variables x (rows) and z + (columns). B is assumed to depend on variables z (rows) and y + (columns). The product of A and B then depends on x (rows) and y + (columns). Only the z variables have to be explicitly identified; + they are the "summation" variables. Returns a pointer to the + result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addTimesPlus Cudd_addTriangle Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_addMatrixMultiply( + DdManager * dd, + DdNode * A, + DdNode * B, + DdNode ** z, + int nz) +{ + int i, nvars, *vars; + DdNode *res; + + /* Array vars says what variables are "summation" variables. */ + nvars = dd->size; + vars = ALLOC(int,nvars); + if (vars == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < nvars; i++) { + vars[i] = 0; + } + for (i = 0; i < nz; i++) { + vars[z[i]->index] = 1; + } + + do { + dd->reordered = 0; + res = addMMRecur(dd,A,B,-1,vars); + } while (dd->reordered == 1); + FREE(vars); + return(res); + +} /* end of Cudd_addMatrixMultiply */ + + +/**Function******************************************************************** + + Synopsis [Calculates the product of two matrices represented as + ADDs.] + + Description [Calculates the product of two matrices, A and B, + represented as ADDs, using the CMU matrix by matrix multiplication + procedure by Clarke et al.. Matrix A has x's as row variables and z's + as column variables, while matrix B has z's as row variables and y's + as column variables. Returns the pointer to the result if successful; + NULL otherwise. The resulting matrix has x's as row variables and y's + as column variables.] + + SideEffects [None] + + SeeAlso [Cudd_addMatrixMultiply] + +******************************************************************************/ +DdNode * +Cudd_addTimesPlus( + DdManager * dd, + DdNode * A, + DdNode * B, + DdNode ** z, + int nz) +{ + DdNode *w, *cube, *tmp, *res; + int i; + tmp = Cudd_addApply(dd,Cudd_addTimes,A,B); + if (tmp == NULL) return(NULL); + Cudd_Ref(tmp); + Cudd_Ref(cube = DD_ONE(dd)); + for (i = nz-1; i >= 0; i--) { + w = Cudd_addIte(dd,z[i],cube,DD_ZERO(dd)); + if (w == NULL) { + Cudd_RecursiveDeref(dd,tmp); + return(NULL); + } + Cudd_Ref(w); + Cudd_RecursiveDeref(dd,cube); + cube = w; + } + res = Cudd_addExistAbstract(dd,tmp,cube); + if (res == NULL) { + Cudd_RecursiveDeref(dd,tmp); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + Cudd_Ref(res); + Cudd_RecursiveDeref(dd,cube); + Cudd_RecursiveDeref(dd,tmp); + Cudd_Deref(res); + return(res); + +} /* end of Cudd_addTimesPlus */ + + +/**Function******************************************************************** + + Synopsis [Performs the triangulation step for the shortest path + computation.] + + Description [Implements the semiring multiplication algorithm used in + the triangulation step for the shortest path computation. f + is assumed to depend on variables x (rows) and z (columns). g is + assumed to depend on variables z (rows) and y (columns). The product + of f and g then depends on x (rows) and y (columns). Only the z + variables have to be explicitly identified; they are the + "abstraction" variables. Returns a pointer to the result if + successful; NULL otherwise. ] + + SideEffects [None] + + SeeAlso [Cudd_addMatrixMultiply Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_addTriangle( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode ** z, + int nz) +{ + int i, nvars, *vars; + DdNode *res, *cube; + + nvars = dd->size; + vars = ALLOC(int, nvars); + if (vars == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < nvars; i++) vars[i] = -1; + for (i = 0; i < nz; i++) vars[z[i]->index] = i; + cube = Cudd_addComputeCube(dd, z, NULL, nz); + if (cube == NULL) { + FREE(vars); + return(NULL); + } + cuddRef(cube); + + do { + dd->reordered = 0; + res = addTriangleRecur(dd, f, g, vars, cube); + } while (dd->reordered == 1); + if (res != NULL) cuddRef(res); + Cudd_RecursiveDeref(dd,cube); + if (res != NULL) cuddDeref(res); + FREE(vars); + return(res); + +} /* end of Cudd_addTriangle */ + + +/**Function******************************************************************** + + Synopsis [Takes the minimum of a matrix and the outer sum of two vectors.] + + Description [Takes the pointwise minimum of a matrix and the outer + sum of two vectors. This procedure is used in the Floyd-Warshall + all-pair shortest path algorithm. Returns a pointer to the result if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addOuterSum( + DdManager *dd, + DdNode *M, + DdNode *r, + DdNode *c) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddOuterSumRecur(dd, M, r, c); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addOuterSum */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addMatrixMultiply.] + + Description [Performs the recursive step of Cudd_addMatrixMultiply. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +addMMRecur( + DdManager * dd, + DdNode * A, + DdNode * B, + int topP, + int * vars) +{ + DdNode *zero, + *At, /* positive cofactor of first operand */ + *Ae, /* negative cofactor of first operand */ + *Bt, /* positive cofactor of second operand */ + *Be, /* negative cofactor of second operand */ + *t, /* positive cofactor of result */ + *e, /* negative cofactor of result */ + *scaled, /* scaled result */ + *add_scale, /* ADD representing the scaling factor */ + *res; + int i; /* loop index */ + double scale; /* scaling factor */ + int index; /* index of the top variable */ + CUDD_VALUE_TYPE value; + unsigned int topA, topB, topV; + DD_CTFP cacheOp; + + statLine(dd); + zero = DD_ZERO(dd); + + if (A == zero || B == zero) { + return(zero); + } + + if (cuddIsConstant(A) && cuddIsConstant(B)) { + /* Compute the scaling factor. It is 2^k, where k is the + ** number of summation variables below the current variable. + ** Indeed, these constants represent blocks of 2^k identical + ** constant values in both A and B. + */ + value = cuddV(A) * cuddV(B); + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP) { + value *= (CUDD_VALUE_TYPE) 2; + } + } + } + res = cuddUniqueConst(dd, value); + return(res); + } + + /* Standardize to increase cache efficiency. Clearly, A*B != B*A + ** in matrix multiplication. However, which matrix is which is + ** determined by the variables appearing in the ADDs and not by + ** which one is passed as first argument. + */ + if (A > B) { + DdNode *tmp = A; + A = B; + B = tmp; + } + + topA = cuddI(dd,A->index); topB = cuddI(dd,B->index); + topV = ddMin(topA,topB); + + cacheOp = (DD_CTFP) addMMRecur; + res = cuddCacheLookup2(dd,cacheOp,A,B); + if (res != NULL) { + /* If the result is 0, there is no need to normalize. + ** Otherwise we count the number of z variables between + ** the current depth and the top of the ADDs. These are + ** the missing variables that determine the size of the + ** constant blocks. + */ + if (res == zero) return(res); + scale = 1.0; + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { + scale *= 2; + } + } + } + if (scale > 1.0) { + cuddRef(res); + add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); + if (add_scale == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(add_scale); + scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); + if (scaled == NULL) { + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(scaled); + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + res = scaled; + cuddDeref(res); + } + return(res); + } + + /* compute the cofactors */ + if (topV == topA) { + At = cuddT(A); + Ae = cuddE(A); + } else { + At = Ae = A; + } + if (topV == topB) { + Bt = cuddT(B); + Be = cuddE(B); + } else { + Bt = Be = B; + } + + t = addMMRecur(dd, At, Bt, (int)topV, vars); + if (t == NULL) return(NULL); + cuddRef(t); + e = addMMRecur(dd, Ae, Be, (int)topV, vars); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + index = dd->invperm[topV]; + if (vars[index] == 0) { + /* We have split on either the rows of A or the columns + ** of B. We just need to connect the two subresults, + ** which correspond to two submatrices of the result. + */ + res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); + cuddDeref(t); + cuddDeref(e); + } else { + /* we have simultaneously split on the columns of A and + ** the rows of B. The two subresults must be added. + */ + res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + } + + cuddCacheInsert2(dd,cacheOp,A,B,res); + + /* We have computed (and stored in the computed table) a minimal + ** result; that is, a result that assumes no summation variables + ** between the current depth of the recursion and its top + ** variable. We now take into account the z variables by properly + ** scaling the result. + */ + if (res != zero) { + scale = 1.0; + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { + scale *= 2; + } + } + } + if (scale > 1.0) { + add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); + if (add_scale == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(add_scale); + scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); + if (scaled == NULL) { + Cudd_RecursiveDeref(dd, res); + Cudd_RecursiveDeref(dd, add_scale); + return(NULL); + } + cuddRef(scaled); + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + res = scaled; + } + } + cuddDeref(res); + return(res); + +} /* end of addMMRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addTriangle.] + + Description [Performs the recursive step of Cudd_addTriangle. Returns + a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +addTriangleRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + int * vars, + DdNode *cube) +{ + DdNode *fv, *fvn, *gv, *gvn, *t, *e, *res; + CUDD_VALUE_TYPE value; + int top, topf, topg, index; + + statLine(dd); + if (f == DD_PLUS_INFINITY(dd) || g == DD_PLUS_INFINITY(dd)) { + return(DD_PLUS_INFINITY(dd)); + } + + if (cuddIsConstant(f) && cuddIsConstant(g)) { + value = cuddV(f) + cuddV(g); + res = cuddUniqueConst(dd, value); + return(res); + } + if (f < g) { + DdNode *tmp = f; + f = g; + g = tmp; + } + + if (f->ref != 1 || g->ref != 1) { + res = cuddCacheLookup(dd, DD_ADD_TRIANGLE_TAG, f, g, cube); + if (res != NULL) { + return(res); + } + } + + topf = cuddI(dd,f->index); topg = cuddI(dd,g->index); + top = ddMin(topf,topg); + + if (top == topf) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;} + if (top == topg) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;} + + t = addTriangleRecur(dd, fv, gv, vars, cube); + if (t == NULL) return(NULL); + cuddRef(t); + e = addTriangleRecur(dd, fvn, gvn, vars, cube); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + index = dd->invperm[top]; + if (vars[index] < 0) { + res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } else { + res = cuddAddApplyRecur(dd,Cudd_addMinimum,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + cuddDeref(res); + } + + if (f->ref != 1 || g->ref != 1) { + cuddCacheInsert(dd, DD_ADD_TRIANGLE_TAG, f, g, cube, res); + } + + return(res); + +} /* end of addTriangleRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addOuterSum.] + + Description [Performs the recursive step of Cudd_addOuterSum. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddOuterSumRecur( + DdManager *dd, + DdNode *M, + DdNode *r, + DdNode *c) +{ + DdNode *P, *R, *Mt, *Me, *rt, *re, *ct, *ce, *Rt, *Re; + int topM, topc, topr; + int v, index; + + statLine(dd); + /* Check special cases. */ + if (r == DD_PLUS_INFINITY(dd) || c == DD_PLUS_INFINITY(dd)) return(M); + + if (cuddIsConstant(c) && cuddIsConstant(r)) { + R = cuddUniqueConst(dd,Cudd_V(c)+Cudd_V(r)); + cuddRef(R); + if (cuddIsConstant(M)) { + if (cuddV(R) <= cuddV(M)) { + cuddDeref(R); + return(R); + } else { + Cudd_RecursiveDeref(dd,R); + return(M); + } + } else { + P = Cudd_addApply(dd,Cudd_addMinimum,R,M); + cuddRef(P); + Cudd_RecursiveDeref(dd,R); + cuddDeref(P); + return(P); + } + } + + /* Check the cache. */ + R = cuddCacheLookup(dd,DD_ADD_OUT_SUM_TAG,M,r,c); + if (R != NULL) return(R); + + topM = cuddI(dd,M->index); topr = cuddI(dd,r->index); + topc = cuddI(dd,c->index); + v = ddMin(topM,ddMin(topr,topc)); + + /* Compute cofactors. */ + if (topM == v) { Mt = cuddT(M); Me = cuddE(M); } else { Mt = Me = M; } + if (topr == v) { rt = cuddT(r); re = cuddE(r); } else { rt = re = r; } + if (topc == v) { ct = cuddT(c); ce = cuddE(c); } else { ct = ce = c; } + + /* Recursively solve. */ + Rt = cuddAddOuterSumRecur(dd,Mt,rt,ct); + if (Rt == NULL) return(NULL); + cuddRef(Rt); + Re = cuddAddOuterSumRecur(dd,Me,re,ce); + if (Re == NULL) { + Cudd_RecursiveDeref(dd, Rt); + return(NULL); + } + cuddRef(Re); + index = dd->invperm[v]; + R = (Rt == Re) ? Rt : cuddUniqueInter(dd,index,Rt,Re); + if (R == NULL) { + Cudd_RecursiveDeref(dd, Rt); + Cudd_RecursiveDeref(dd, Re); + return(NULL); + } + cuddDeref(Rt); + cuddDeref(Re); + + /* Store the result in the cache. */ + cuddCacheInsert(dd,DD_ADD_OUT_SUM_TAG,M,r,c,R); + + return(R); + +} /* end of cuddAddOuterSumRecur */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddPriority.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddPriority.c new file mode 100644 index 000000000..2b59adca2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddPriority.c @@ -0,0 +1,2027 @@ +/**CFile*********************************************************************** + + FileName [cuddPriority.c] + + PackageName [cudd] + + Synopsis [Priority functions.] + + Description [External procedures included in this file: +
                +
              • Cudd_PrioritySelect() +
              • Cudd_Xgty() +
              • Cudd_Xeqy() +
              • Cudd_addXeqy() +
              • Cudd_Dxygtdxz() +
              • Cudd_Dxygtdyz() +
              • Cudd_Inequality() +
              • Cudd_Disequality() +
              • Cudd_bddInterval() +
              • Cudd_CProjection() +
              • Cudd_addHamming() +
              • Cudd_MinHammingDist() +
              • Cudd_bddClosestCube() +
              + Internal procedures included in this module: +
                +
              • cuddCProjectionRecur() +
              • cuddBddClosestCube() +
              + Static procedures included in this module: +
                +
              • cuddMinHammingDistRecur() +
              • separateCube() +
              • createResult() +
              + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_DEBUG 1 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddPriority.c,v 1.36 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ +static int cuddMinHammingDistRecur (DdNode * f, int *minterm, DdHashTable * table, int upperBound); +static DdNode * separateCube (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE *distance); +static DdNode * createResult (DdManager *dd, unsigned int index, unsigned int phase, DdNode *cube, CUDD_VALUE_TYPE distance); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Selects pairs from R using a priority function.] + + Description [Selects pairs from a relation R(x,y) (given as a BDD) + in such a way that a given x appears in one pair only. Uses a + priority function to determine which y should be paired to a given x. + Cudd_PrioritySelect returns a pointer to + the selected function if successful; NULL otherwise. + Three of the arguments--x, y, and z--are vectors of BDD variables. + The first two are the variables on which R depends. The third vector + is a vector of auxiliary variables, used during the computation. This + vector is optional. If a NULL value is passed instead, + Cudd_PrioritySelect will create the working variables on the fly. + The sizes of x and y (and z if it is not NULL) should equal n. + The priority function Pi can be passed as a BDD, or can be built by + Cudd_PrioritySelect. If NULL is passed instead of a DdNode *, + parameter Pifunc is used by Cudd_PrioritySelect to build a BDD for the + priority function. (Pifunc is a pointer to a C function.) If Pi is not + NULL, then Pifunc is ignored. Pifunc should have the same interface as + the standard priority functions (e.g., Cudd_Dxygtdxz). + Cudd_PrioritySelect and Cudd_CProjection can sometimes be used + interchangeably. Specifically, calling Cudd_PrioritySelect with + Cudd_Xgty as Pifunc produces the same result as calling + Cudd_CProjection with the all-zero minterm as reference minterm. + However, depending on the application, one or the other may be + preferable: +
                +
              • When extracting representatives from an equivalence relation, + Cudd_CProjection has the advantage of nor requiring the auxiliary + variables. +
              • When computing matchings in general bipartite graphs, + Cudd_PrioritySelect normally obtains better results because it can use + more powerful matching schemes (e.g., Cudd_Dxygtdxz). +
              + ] + + SideEffects [If called with z == NULL, will create new variables in + the manager.] + + SeeAlso [Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_Xgty + Cudd_bddAdjPermuteX Cudd_CProjection] + +******************************************************************************/ +DdNode * +Cudd_PrioritySelect( + DdManager * dd /* manager */, + DdNode * R /* BDD of the relation */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */, + DdNode ** z /* array of z variables (optional: may be NULL) */, + DdNode * Pi /* BDD of the priority function (optional: may be NULL) */, + int n /* size of x, y, and z */, + DD_PRFP Pifunc /* function used to build Pi if it is NULL */) +{ + DdNode *res = NULL; + DdNode *zcube = NULL; + DdNode *Rxz, *Q; + int createdZ = 0; + int createdPi = 0; + int i; + + /* Create z variables if needed. */ + if (z == NULL) { + if (Pi != NULL) return(NULL); + z = ALLOC(DdNode *,n); + if (z == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + createdZ = 1; + for (i = 0; i < n; i++) { + if (dd->size >= (int) CUDD_MAXINDEX - 1) goto endgame; + z[i] = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); + if (z[i] == NULL) goto endgame; + } + } + + /* Create priority function BDD if needed. */ + if (Pi == NULL) { + Pi = Pifunc(dd,n,x,y,z); + if (Pi == NULL) goto endgame; + createdPi = 1; + cuddRef(Pi); + } + + /* Initialize abstraction cube. */ + zcube = DD_ONE(dd); + cuddRef(zcube); + for (i = n - 1; i >= 0; i--) { + DdNode *tmpp; + tmpp = Cudd_bddAnd(dd,z[i],zcube); + if (tmpp == NULL) goto endgame; + cuddRef(tmpp); + Cudd_RecursiveDeref(dd,zcube); + zcube = tmpp; + } + + /* Compute subset of (x,y) pairs. */ + Rxz = Cudd_bddSwapVariables(dd,R,y,z,n); + if (Rxz == NULL) goto endgame; + cuddRef(Rxz); + Q = Cudd_bddAndAbstract(dd,Rxz,Pi,zcube); + if (Q == NULL) { + Cudd_RecursiveDeref(dd,Rxz); + goto endgame; + } + cuddRef(Q); + Cudd_RecursiveDeref(dd,Rxz); + res = Cudd_bddAnd(dd,R,Cudd_Not(Q)); + if (res == NULL) { + Cudd_RecursiveDeref(dd,Q); + goto endgame; + } + cuddRef(res); + Cudd_RecursiveDeref(dd,Q); + +endgame: + if (zcube != NULL) Cudd_RecursiveDeref(dd,zcube); + if (createdZ) { + FREE(z); + } + if (createdPi) { + Cudd_RecursiveDeref(dd,Pi); + } + if (res != NULL) cuddDeref(res); + return(res); + +} /* Cudd_PrioritySelect */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function x > y.] + + Description [This function generates a BDD for the function x > y. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has 3*N-1 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. + Argument z is not used by Cudd_Xgty: it is included to make it + call-compatible to Cudd_Dxygtdxz and Cudd_Dxygtdyz.] + + SideEffects [None] + + SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Dxygtdyz] + +******************************************************************************/ +DdNode * +Cudd_Xgty( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + DdNode ** z /* array of z variables: unused */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + DdNode *u, *v, *w; + int i; + + /* Build bottom part of BDD outside loop. */ + u = Cudd_bddAnd(dd, x[N-1], Cudd_Not(y[N-1])); + if (u == NULL) return(NULL); + cuddRef(u); + + /* Loop to build the rest of the BDD. */ + for (i = N-2; i >= 0; i--) { + v = Cudd_bddAnd(dd, y[i], Cudd_Not(u)); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, u); + u = Cudd_bddIte(dd, x[i], Cudd_Not(v), w); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + + } + cuddDeref(u); + return(u); + +} /* end of Cudd_Xgty */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function x==y.] + + Description [This function generates a BDD for the function x==y. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has 3*N-1 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ] + + SideEffects [None] + + SeeAlso [Cudd_addXeqy] + +******************************************************************************/ +DdNode * +Cudd_Xeqy( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + DdNode *u, *v, *w; + int i; + + /* Build bottom part of BDD outside loop. */ + u = Cudd_bddIte(dd, x[N-1], y[N-1], Cudd_Not(y[N-1])); + if (u == NULL) return(NULL); + cuddRef(u); + + /* Loop to build the rest of the BDD. */ + for (i = N-2; i >= 0; i--) { + v = Cudd_bddAnd(dd, y[i], u); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, u); + u = Cudd_bddIte(dd, x[i], v, w); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + } + cuddDeref(u); + return(u); + +} /* end of Cudd_Xeqy */ + + +/**Function******************************************************************** + + Synopsis [Generates an ADD for the function x==y.] + + Description [This function generates an ADD for the function x==y. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The ADD is built bottom-up. + It has 3*N-1 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ] + + SideEffects [None] + + SeeAlso [Cudd_Xeqy] + +******************************************************************************/ +DdNode * +Cudd_addXeqy( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + DdNode *one, *zero; + DdNode *u, *v, *w; + int i; + + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + /* Build bottom part of ADD outside loop. */ + v = Cudd_addIte(dd, y[N-1], one, zero); + if (v == NULL) return(NULL); + cuddRef(v); + w = Cudd_addIte(dd, y[N-1], zero, one); + if (w == NULL) { + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); + u = Cudd_addIte(dd, x[N-1], v, w); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + + /* Loop to build the rest of the ADD. */ + for (i = N-2; i >= 0; i--) { + v = Cudd_addIte(dd, y[i], u, zero); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_addIte(dd, y[i], zero, u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, u); + u = Cudd_addIte(dd, x[i], v, w); + if (w == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + } + cuddDeref(u); + return(u); + +} /* end of Cudd_addXeqy */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function d(x,y) > d(x,z).] + + Description [This function generates a BDD for the function d(x,y) + > d(x,z); + x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\], + y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\], + with 0 the most significant bit. + The distance d(x,y) is defined as: + \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). + The BDD is built bottom-up. + It has 7*N-3 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ] + + SideEffects [None] + + SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdyz Cudd_Xgty Cudd_bddAdjPermuteX] + +******************************************************************************/ +DdNode * +Cudd_Dxygtdxz( + DdManager * dd /* DD manager */, + int N /* number of x, y, and z variables */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */, + DdNode ** z /* array of z variables */) +{ + DdNode *one, *zero; + DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1; + int i; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Build bottom part of BDD outside loop. */ + y1_ = Cudd_bddIte(dd, y[N-1], one, Cudd_Not(z[N-1])); + if (y1_ == NULL) return(NULL); + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[N-1], z[N-1], one); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); + x1 = Cudd_bddIte(dd, x[N-1], y1_, y2); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + + /* Loop to build the rest of the BDD. */ + for (i = N-2; i >= 0; i--) { + z1 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); + if (z1 == NULL) { + Cudd_RecursiveDeref(dd, x1); + return(NULL); + } + cuddRef(z1); + z2 = Cudd_bddIte(dd, z[i], x1, one); + if (z2 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + return(NULL); + } + cuddRef(z2); + z3 = Cudd_bddIte(dd, z[i], one, x1); + if (z3 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + return(NULL); + } + cuddRef(z3); + z4 = Cudd_bddIte(dd, z[i], x1, zero); + if (z4 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + return(NULL); + } + cuddRef(z4); + Cudd_RecursiveDeref(dd, x1); + y1_ = Cudd_bddIte(dd, y[i], z2, Cudd_Not(z1)); + if (y1_ == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + return(NULL); + } + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[i], z4, z3); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + x1 = Cudd_bddIte(dd, x[i], y1_, y2); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + } + cuddDeref(x1); + return(Cudd_Not(x1)); + +} /* end of Cudd_Dxygtdxz */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function d(x,y) > d(y,z).] + + Description [This function generates a BDD for the function d(x,y) + > d(y,z); + x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\], + y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\], + with 0 the most significant bit. + The distance d(x,y) is defined as: + \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). + The BDD is built bottom-up. + It has 7*N-3 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ] + + SideEffects [None] + + SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Xgty Cudd_bddAdjPermuteX] + +******************************************************************************/ +DdNode * +Cudd_Dxygtdyz( + DdManager * dd /* DD manager */, + int N /* number of x, y, and z variables */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */, + DdNode ** z /* array of z variables */) +{ + DdNode *one, *zero; + DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1; + int i; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Build bottom part of BDD outside loop. */ + y1_ = Cudd_bddIte(dd, y[N-1], one, z[N-1]); + if (y1_ == NULL) return(NULL); + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[N-1], z[N-1], zero); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); + x1 = Cudd_bddIte(dd, x[N-1], y1_, Cudd_Not(y2)); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + + /* Loop to build the rest of the BDD. */ + for (i = N-2; i >= 0; i--) { + z1 = Cudd_bddIte(dd, z[i], x1, zero); + if (z1 == NULL) { + Cudd_RecursiveDeref(dd, x1); + return(NULL); + } + cuddRef(z1); + z2 = Cudd_bddIte(dd, z[i], x1, one); + if (z2 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + return(NULL); + } + cuddRef(z2); + z3 = Cudd_bddIte(dd, z[i], one, x1); + if (z3 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + return(NULL); + } + cuddRef(z3); + z4 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); + if (z4 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + return(NULL); + } + cuddRef(z4); + Cudd_RecursiveDeref(dd, x1); + y1_ = Cudd_bddIte(dd, y[i], z2, z1); + if (y1_ == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + return(NULL); + } + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[i], z4, Cudd_Not(z3)); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + x1 = Cudd_bddIte(dd, x[i], y1_, Cudd_Not(y2)); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + } + cuddDeref(x1); + return(Cudd_Not(x1)); + +} /* end of Cudd_Dxygtdyz */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function x - y ≥ c.] + + Description [This function generates a BDD for the function x -y ≥ c. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has a linear number of nodes if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].] + + SideEffects [None] + + SeeAlso [Cudd_Xgty] + +******************************************************************************/ +DdNode * +Cudd_Inequality( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + int c /* right-hand side constant */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + /* The nodes at level i represent values of the difference that are + ** multiples of 2^i. We use variables with names starting with k + ** to denote the multipliers of 2^i in such multiples. */ + int kTrue = c; + int kFalse = c - 1; + /* Mask used to compute the ceiling function. Since we divide by 2^i, + ** we want to know whether the dividend is a multiple of 2^i. If it is, + ** then ceiling and floor coincide; otherwise, they differ by one. */ + int mask = 1; + int i; + + DdNode *f = NULL; /* the eventual result */ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + + /* Two x-labeled nodes are created at most at each iteration. They are + ** stored, along with their k values, in these variables. At each level, + ** the old nodes are freed and the new nodes are copied into the old map. + */ + DdNode *map[2]; + int invalidIndex = 1 << (N-1); + int index[2] = {invalidIndex, invalidIndex}; + + /* This should never happen. */ + if (N < 0) return(NULL); + + /* If there are no bits, both operands are 0. The result depends on c. */ + if (N == 0) { + if (c >= 0) return(one); + else return(zero); + } + + /* The maximum or the minimum difference comparing to c can generate the terminal case */ + if ((1 << N) - 1 < c) return(zero); + else if ((-(1 << N) + 1) >= c) return(one); + + /* Build the result bottom up. */ + for (i = 1; i <= N; i++) { + int kTrueLower, kFalseLower; + int leftChild, middleChild, rightChild; + DdNode *g0, *g1, *fplus, *fequal, *fminus; + int j; + DdNode *newMap[2]; + int newIndex[2]; + + kTrueLower = kTrue; + kFalseLower = kFalse; + /* kTrue = ceiling((c-1)/2^i) + 1 */ + kTrue = ((c-1) >> i) + ((c & mask) != 1) + 1; + mask = (mask << 1) | 1; + /* kFalse = floor(c/2^i) - 1 */ + kFalse = (c >> i) - 1; + newIndex[0] = invalidIndex; + newIndex[1] = invalidIndex; + + for (j = kFalse + 1; j < kTrue; j++) { + /* Skip if node is not reachable from top of BDD. */ + if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue; + + /* Find f- */ + leftChild = (j << 1) - 1; + if (leftChild >= kTrueLower) { + fminus = one; + } else if (leftChild <= kFalseLower) { + fminus = zero; + } else { + assert(leftChild == index[0] || leftChild == index[1]); + if (leftChild == index[0]) { + fminus = map[0]; + } else { + fminus = map[1]; + } + } + + /* Find f= */ + middleChild = j << 1; + if (middleChild >= kTrueLower) { + fequal = one; + } else if (middleChild <= kFalseLower) { + fequal = zero; + } else { + assert(middleChild == index[0] || middleChild == index[1]); + if (middleChild == index[0]) { + fequal = map[0]; + } else { + fequal = map[1]; + } + } + + /* Find f+ */ + rightChild = (j << 1) + 1; + if (rightChild >= kTrueLower) { + fplus = one; + } else if (rightChild <= kFalseLower) { + fplus = zero; + } else { + assert(rightChild == index[0] || rightChild == index[1]); + if (rightChild == index[0]) { + fplus = map[0]; + } else { + fplus = map[1]; + } + } + + /* Build new nodes. */ + g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus); + if (g1 == NULL) { + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g1); + g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal); + if (g0 == NULL) { + Cudd_IterDerefBdd(dd, g1); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g0); + f = Cudd_bddIte(dd, x[N - i], g1, g0); + if (f == NULL) { + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(f); + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + + /* Save newly computed node in map. */ + assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex); + if (newIndex[0] == invalidIndex) { + newIndex[0] = j; + newMap[0] = f; + } else { + newIndex[1] = j; + newMap[1] = f; + } + } + + /* Copy new map to map. */ + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + map[0] = newMap[0]; + map[1] = newMap[1]; + index[0] = newIndex[0]; + index[1] = newIndex[1]; + } + + cuddDeref(f); + return(f); + +} /* end of Cudd_Inequality */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function x - y != c.] + + Description [This function generates a BDD for the function x -y != c. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has a linear number of nodes if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].] + + SideEffects [None] + + SeeAlso [Cudd_Xgty] + +******************************************************************************/ +DdNode * +Cudd_Disequality( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + int c /* right-hand side constant */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + /* The nodes at level i represent values of the difference that are + ** multiples of 2^i. We use variables with names starting with k + ** to denote the multipliers of 2^i in such multiples. */ + int kTrueLb = c + 1; + int kTrueUb = c - 1; + int kFalse = c; + /* Mask used to compute the ceiling function. Since we divide by 2^i, + ** we want to know whether the dividend is a multiple of 2^i. If it is, + ** then ceiling and floor coincide; otherwise, they differ by one. */ + int mask = 1; + int i; + + DdNode *f = NULL; /* the eventual result */ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + + /* Two x-labeled nodes are created at most at each iteration. They are + ** stored, along with their k values, in these variables. At each level, + ** the old nodes are freed and the new nodes are copied into the old map. + */ + DdNode *map[2]; + int invalidIndex = 1 << (N-1); + int index[2] = {invalidIndex, invalidIndex}; + + /* This should never happen. */ + if (N < 0) return(NULL); + + /* If there are no bits, both operands are 0. The result depends on c. */ + if (N == 0) { + if (c != 0) return(one); + else return(zero); + } + + /* The maximum or the minimum difference comparing to c can generate the terminal case */ + if ((1 << N) - 1 < c || (-(1 << N) + 1) > c) return(one); + + /* Build the result bottom up. */ + for (i = 1; i <= N; i++) { + int kTrueLbLower, kTrueUbLower; + int leftChild, middleChild, rightChild; + DdNode *g0, *g1, *fplus, *fequal, *fminus; + int j; + DdNode *newMap[2]; + int newIndex[2]; + + kTrueLbLower = kTrueLb; + kTrueUbLower = kTrueUb; + /* kTrueLb = floor((c-1)/2^i) + 2 */ + kTrueLb = ((c-1) >> i) + 2; + /* kTrueUb = ceiling((c+1)/2^i) - 2 */ + kTrueUb = ((c+1) >> i) + (((c+2) & mask) != 1) - 2; + mask = (mask << 1) | 1; + newIndex[0] = invalidIndex; + newIndex[1] = invalidIndex; + + for (j = kTrueUb + 1; j < kTrueLb; j++) { + /* Skip if node is not reachable from top of BDD. */ + if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue; + + /* Find f- */ + leftChild = (j << 1) - 1; + if (leftChild >= kTrueLbLower || leftChild <= kTrueUbLower) { + fminus = one; + } else if (i == 1 && leftChild == kFalse) { + fminus = zero; + } else { + assert(leftChild == index[0] || leftChild == index[1]); + if (leftChild == index[0]) { + fminus = map[0]; + } else { + fminus = map[1]; + } + } + + /* Find f= */ + middleChild = j << 1; + if (middleChild >= kTrueLbLower || middleChild <= kTrueUbLower) { + fequal = one; + } else if (i == 1 && middleChild == kFalse) { + fequal = zero; + } else { + assert(middleChild == index[0] || middleChild == index[1]); + if (middleChild == index[0]) { + fequal = map[0]; + } else { + fequal = map[1]; + } + } + + /* Find f+ */ + rightChild = (j << 1) + 1; + if (rightChild >= kTrueLbLower || rightChild <= kTrueUbLower) { + fplus = one; + } else if (i == 1 && rightChild == kFalse) { + fplus = zero; + } else { + assert(rightChild == index[0] || rightChild == index[1]); + if (rightChild == index[0]) { + fplus = map[0]; + } else { + fplus = map[1]; + } + } + + /* Build new nodes. */ + g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus); + if (g1 == NULL) { + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g1); + g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal); + if (g0 == NULL) { + Cudd_IterDerefBdd(dd, g1); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g0); + f = Cudd_bddIte(dd, x[N - i], g1, g0); + if (f == NULL) { + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(f); + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + + /* Save newly computed node in map. */ + assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex); + if (newIndex[0] == invalidIndex) { + newIndex[0] = j; + newMap[0] = f; + } else { + newIndex[1] = j; + newMap[1] = f; + } + } + + /* Copy new map to map. */ + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + map[0] = newMap[0]; + map[1] = newMap[1]; + index[0] = newIndex[0]; + index[1] = newIndex[1]; + } + + cuddDeref(f); + return(f); + +} /* end of Cudd_Disequality */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function lowerB ≤ x ≤ upperB.] + + Description [This function generates a BDD for the function + lowerB ≤ x ≤ upperB, where x is an N-bit number, + x\[0\] x\[1\] ... x\[N-1\], with 0 the most significant bit (important!). + The number of variables N should be sufficient to represent the bounds; + otherwise, the bounds are truncated to their N least significant bits. + Two BDDs are built bottom-up for lowerB ≤ x and x ≤ upperB, and they + are finally conjoined.] + + SideEffects [None] + + SeeAlso [Cudd_Xgty] + +******************************************************************************/ +DdNode * +Cudd_bddInterval( + DdManager * dd /* DD manager */, + int N /* number of x variables */, + DdNode ** x /* array of x variables */, + unsigned int lowerB /* lower bound */, + unsigned int upperB /* upper bound */) +{ + DdNode *one, *zero; + DdNode *r, *rl, *ru; + int i; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + rl = one; + cuddRef(rl); + ru = one; + cuddRef(ru); + + /* Loop to build the rest of the BDDs. */ + for (i = N-1; i >= 0; i--) { + DdNode *vl, *vu; + vl = Cudd_bddIte(dd, x[i], + lowerB&1 ? rl : one, + lowerB&1 ? zero : rl); + if (vl == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(vl); + Cudd_IterDerefBdd(dd, rl); + rl = vl; + lowerB >>= 1; + vu = Cudd_bddIte(dd, x[i], + upperB&1 ? ru : zero, + upperB&1 ? one : ru); + if (vu == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(vu); + Cudd_IterDerefBdd(dd, ru); + ru = vu; + upperB >>= 1; + } + + /* Conjoin the two bounds. */ + r = Cudd_bddAnd(dd, rl, ru); + if (r == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + cuddDeref(r); + return(r); + +} /* end of Cudd_bddInterval */ + + +/**Function******************************************************************** + + Synopsis [Computes the compatible projection of R w.r.t. cube Y.] + + Description [Computes the compatible projection of relation R with + respect to cube Y. Returns a pointer to the c-projection if + successful; NULL otherwise. For a comparison between Cudd_CProjection + and Cudd_PrioritySelect, see the documentation of the latter.] + + SideEffects [None] + + SeeAlso [Cudd_PrioritySelect] + +******************************************************************************/ +DdNode * +Cudd_CProjection( + DdManager * dd, + DdNode * R, + DdNode * Y) +{ + DdNode *res; + DdNode *support; + + if (Cudd_CheckCube(dd,Y) == 0) { + (void) fprintf(dd->err, + "Error: The third argument of Cudd_CProjection should be a cube\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + /* Compute the support of Y, which is used by the abstraction step + ** in cuddCProjectionRecur. + */ + support = Cudd_Support(dd,Y); + if (support == NULL) return(NULL); + cuddRef(support); + + do { + dd->reordered = 0; + res = cuddCProjectionRecur(dd,R,Y,support); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd,support); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,support); + cuddDeref(res); + + return(res); + +} /* end of Cudd_CProjection */ + + +/**Function******************************************************************** + + Synopsis [Computes the Hamming distance ADD.] + + Description [Computes the Hamming distance ADD. Returns an ADD that + gives the Hamming distance between its two arguments if successful; + NULL otherwise. The two vectors xVars and yVars identify the variables + that form the two arguments.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addHamming( + DdManager * dd, + DdNode ** xVars, + DdNode ** yVars, + int nVars) +{ + DdNode *result,*tempBdd; + DdNode *tempAdd,*temp; + int i; + + result = DD_ZERO(dd); + cuddRef(result); + + for (i = 0; i < nVars; i++) { + tempBdd = Cudd_bddIte(dd,xVars[i],Cudd_Not(yVars[i]),yVars[i]); + if (tempBdd == NULL) { + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(tempBdd); + tempAdd = Cudd_BddToAdd(dd,tempBdd); + if (tempAdd == NULL) { + Cudd_RecursiveDeref(dd,tempBdd); + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(tempAdd); + Cudd_RecursiveDeref(dd,tempBdd); + temp = Cudd_addApply(dd,Cudd_addPlus,tempAdd,result); + if (temp == NULL) { + Cudd_RecursiveDeref(dd,tempAdd); + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(temp); + Cudd_RecursiveDeref(dd,tempAdd); + Cudd_RecursiveDeref(dd,result); + result = temp; + } + + cuddDeref(result); + return(result); + +} /* end of Cudd_addHamming */ + + +/**Function******************************************************************** + + Synopsis [Returns the minimum Hamming distance between f and minterm.] + + Description [Returns the minimum Hamming distance between the + minterms of a function f and a reference minterm. The function is + given as a BDD; the minterm is given as an array of integers, one + for each variable in the manager. Returns the minimum distance if + it is less than the upper bound; the upper bound if the minimum + distance is at least as large; CUDD_OUT_OF_MEM in case of failure.] + + SideEffects [None] + + SeeAlso [Cudd_addHamming Cudd_bddClosestCube] + +******************************************************************************/ +int +Cudd_MinHammingDist( + DdManager *dd /* DD manager */, + DdNode *f /* function to examine */, + int *minterm /* reference minterm */, + int upperBound /* distance above which an approximate answer is OK */) +{ + DdHashTable *table; + CUDD_VALUE_TYPE epsilon; + int res; + + table = cuddHashTableInit(dd,1,2); + if (table == NULL) { + return(CUDD_OUT_OF_MEM); + } + epsilon = Cudd_ReadEpsilon(dd); + Cudd_SetEpsilon(dd,(CUDD_VALUE_TYPE)0.0); + res = cuddMinHammingDistRecur(f,minterm,table,upperBound); + cuddHashTableQuit(table); + Cudd_SetEpsilon(dd,epsilon); + + return(res); + +} /* end of Cudd_MinHammingDist */ + + +/**Function******************************************************************** + + Synopsis [Finds a cube of f at minimum Hamming distance from g.] + + Description [Finds a cube of f at minimum Hamming distance from the + minterms of g. All the minterms of the cube are at the minimum + distance. If the distance is 0, the cube belongs to the + intersection of f and g. Returns the cube if successful; NULL + otherwise.] + + SideEffects [The distance is returned as a side effect.] + + SeeAlso [Cudd_MinHammingDist] + +******************************************************************************/ +DdNode * +Cudd_bddClosestCube( + DdManager *dd, + DdNode * f, + DdNode *g, + int *distance) +{ + DdNode *res, *acube; + CUDD_VALUE_TYPE rdist; + + /* Compute the cube and distance as a single ADD. */ + do { + dd->reordered = 0; + res = cuddBddClosestCube(dd,f,g,CUDD_CONST_INDEX + 1.0); + } while (dd->reordered == 1); + if (res == NULL) return(NULL); + cuddRef(res); + + /* Unpack distance and cube. */ + do { + dd->reordered = 0; + acube = separateCube(dd, res, &rdist); + } while (dd->reordered == 1); + if (acube == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(acube); + Cudd_RecursiveDeref(dd, res); + + /* Convert cube from ADD to BDD. */ + do { + dd->reordered = 0; + res = cuddAddBddDoPattern(dd, acube); + } while (dd->reordered == 1); + if (res == NULL) { + Cudd_RecursiveDeref(dd, acube); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, acube); + + *distance = (int) rdist; + cuddDeref(res); + return(res); + +} /* end of Cudd_bddClosestCube */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CProjection.] + + Description [Performs the recursive step of Cudd_CProjection. Returns + the projection if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_CProjection] + +******************************************************************************/ +DdNode * +cuddCProjectionRecur( + DdManager * dd, + DdNode * R, + DdNode * Y, + DdNode * Ysupp) +{ + DdNode *res, *res1, *res2, *resA; + DdNode *r, *y, *RT, *RE, *YT, *YE, *Yrest, *Ra, *Ran, *Gamma, *Alpha; + unsigned int topR, topY, top, index; + DdNode *one = DD_ONE(dd); + + statLine(dd); + if (Y == one) return(R); + +#ifdef DD_DEBUG + assert(!Cudd_IsConstant(Y)); +#endif + + if (R == Cudd_Not(one)) return(R); + + res = cuddCacheLookup2(dd, Cudd_CProjection, R, Y); + if (res != NULL) return(res); + + r = Cudd_Regular(R); + topR = cuddI(dd,r->index); + y = Cudd_Regular(Y); + topY = cuddI(dd,y->index); + + top = ddMin(topR, topY); + + /* Compute the cofactors of R */ + if (topR == top) { + index = r->index; + RT = cuddT(r); + RE = cuddE(r); + if (r != R) { + RT = Cudd_Not(RT); RE = Cudd_Not(RE); + } + } else { + RT = RE = R; + } + + if (topY > top) { + /* Y does not depend on the current top variable. + ** We just need to compute the results on the two cofactors of R + ** and make them the children of a node labeled r->index. + */ + res1 = cuddCProjectionRecur(dd,RT,Y,Ysupp); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddCProjectionRecur(dd,RE,Y,Ysupp); + if (res2 == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); + } + cuddRef(res2); + res = cuddBddIteRecur(dd, dd->vars[index], res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(NULL); + } + /* If we have reached this point, res1 and res2 are now + ** incorporated in res. cuddDeref is therefore sufficient. + */ + cuddDeref(res1); + cuddDeref(res2); + } else { + /* Compute the cofactors of Y */ + index = y->index; + YT = cuddT(y); + YE = cuddE(y); + if (y != Y) { + YT = Cudd_Not(YT); YE = Cudd_Not(YE); + } + if (YT == Cudd_Not(one)) { + Alpha = Cudd_Not(dd->vars[index]); + Yrest = YE; + Ra = RE; + Ran = RT; + } else { + Alpha = dd->vars[index]; + Yrest = YT; + Ra = RT; + Ran = RE; + } + Gamma = cuddBddExistAbstractRecur(dd,Ra,cuddT(Ysupp)); + if (Gamma == NULL) return(NULL); + if (Gamma == one) { + res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res = cuddBddAndRecur(dd, Alpha, res1); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); + } + cuddDeref(res1); + } else if (Gamma == Cudd_Not(one)) { + res1 = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res = cuddBddAndRecur(dd, Cudd_Not(Alpha), res1); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); + } + cuddDeref(res1); + } else { + cuddRef(Gamma); + resA = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); + if (resA == NULL) { + Cudd_RecursiveDeref(dd,Gamma); + return(NULL); + } + cuddRef(resA); + res2 = cuddBddAndRecur(dd, Cudd_Not(Gamma), resA); + if (res2 == NULL) { + Cudd_RecursiveDeref(dd,Gamma); + Cudd_RecursiveDeref(dd,resA); + return(NULL); + } + cuddRef(res2); + Cudd_RecursiveDeref(dd,Gamma); + Cudd_RecursiveDeref(dd,resA); + res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd,res2); + return(NULL); + } + cuddRef(res1); + res = cuddBddIteRecur(dd, Alpha, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + } + } + + cuddCacheInsert2(dd,Cudd_CProjection,R,Y,res); + + return(res); + +} /* end of cuddCProjectionRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddClosestCube.] + + Description [Performs the recursive step of Cudd_bddClosestCube. + Returns the cube if succesful; NULL otherwise. The procedure uses a + four-way recursion to examine all four combinations of cofactors of + f and g according to the following formula. +
              +    H(f,g) = min(H(ft,gt), H(fe,ge), H(ft,ge)+1, H(fe,gt)+1)
              +  
              + Bounding is based on the following observations. +
                +
              • If we already found two points at distance 0, there is no point in + continuing. Furthermore, +
              • If F == not(G) then the best we can hope for is a minimum distance + of 1. If we have already found two points at distance 1, there is + no point in continuing. (Indeed, H(F,G) == 1 in this case. We + have to continue, though, to find the cube.) +
              + The variable bound is set at the largest value of the distance + that we are still interested in. Therefore, we desist when +
              +    (bound == -1) and (F != not(G)) or (bound == 0) and (F == not(G)).
              +  
              + If we were maximally aggressive in using the bound, we would always + set the bound to the minimum distance seen thus far minus one. That + is, we would maintain the invariant +
              +    bound < minD,
              +  
              + except at the very beginning, when we have no value for + minD.

              + + However, we do not use bound < minD when examining the + two negative cofactors, because we try to find a large cube at + minimum distance. To do so, we try to find a cube in the negative + cofactors at the same or smaller distance from the cube found in the + positive cofactors.

              + + When we compute H(ft,ge) and H(fe,gt) we + know that we are going to add 1 to the result of the recursive call + to account for the difference in the splitting variable. Therefore, + we decrease the bound correspondingly.

              + + Another important observation concerns the need of examining all + four pairs of cofators only when both f and + g depend on the top variable.

              + + Suppose gt == ge == g. (That is, g does + not depend on the top variable.) Then +

              +    H(f,g) = min(H(ft,g), H(fe,g), H(ft,g)+1, H(fe,g)+1)
              +	   = min(H(ft,g), H(fe,g)) .
              +  
              + Therefore, under these circumstances, we skip the two "cross" cases.

              + + An interesting feature of this function is the scheme used for + caching the results in the global computed table. Since we have a + cube and a distance, we combine them to form an ADD. The + combination replaces the zero child of the top node of the cube with + the negative of the distance. (The use of the negative is to avoid + ambiguity with 1.) The degenerate cases (zero and one) are treated + specially because the distance is known (0 for one, and infinity for + zero).] + + SideEffects [None] + + SeeAlso [Cudd_bddClosestCube] + +******************************************************************************/ +DdNode * +cuddBddClosestCube( + DdManager *dd, + DdNode *f, + DdNode *g, + CUDD_VALUE_TYPE bound) +{ + DdNode *res, *F, *G, *ft, *fe, *gt, *ge, *tt, *ee; + DdNode *ctt, *cee, *cte, *cet; + CUDD_VALUE_TYPE minD, dtt, dee, dte, det; + DdNode *one = DD_ONE(dd); + DdNode *lzero = Cudd_Not(one); + DdNode *azero = DD_ZERO(dd); + unsigned int topf, topg, index; + + statLine(dd); + if (bound < (f == Cudd_Not(g))) return(azero); + /* Terminal cases. */ + if (g == lzero || f == lzero) return(azero); + if (f == one && g == one) return(one); + + /* Check cache. */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + if (F->ref != 1 || G->ref != 1) { + res = cuddCacheLookup2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g); + if (res != NULL) return(res); + } + + topf = cuddI(dd,F->index); + topg = cuddI(dd,G->index); + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg <= topf) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + tt = cuddBddClosestCube(dd,ft,gt,bound); + if (tt == NULL) return(NULL); + cuddRef(tt); + ctt = separateCube(dd,tt,&dtt); + if (ctt == NULL) { + Cudd_RecursiveDeref(dd, tt); + return(NULL); + } + cuddRef(ctt); + Cudd_RecursiveDeref(dd, tt); + minD = dtt; + bound = ddMin(bound,minD); + + ee = cuddBddClosestCube(dd,fe,ge,bound); + if (ee == NULL) { + Cudd_RecursiveDeref(dd, ctt); + return(NULL); + } + cuddRef(ee); + cee = separateCube(dd,ee,&dee); + if (cee == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, ee); + return(NULL); + } + cuddRef(cee); + Cudd_RecursiveDeref(dd, ee); + minD = ddMin(dtt, dee); + if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1); + + if (minD > 0 && topf == topg) { + DdNode *te = cuddBddClosestCube(dd,ft,ge,bound-1); + if (te == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + return(NULL); + } + cuddRef(te); + cte = separateCube(dd,te,&dte); + if (cte == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, te); + return(NULL); + } + cuddRef(cte); + Cudd_RecursiveDeref(dd, te); + dte += 1.0; + minD = ddMin(minD, dte); + } else { + cte = azero; + cuddRef(cte); + dte = CUDD_CONST_INDEX + 1.0; + } + if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1); + + if (minD > 0 && topf == topg) { + DdNode *et = cuddBddClosestCube(dd,fe,gt,bound-1); + if (et == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + return(NULL); + } + cuddRef(et); + cet = separateCube(dd,et,&det); + if (cet == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + Cudd_RecursiveDeref(dd, et); + return(NULL); + } + cuddRef(cet); + Cudd_RecursiveDeref(dd, et); + det += 1.0; + minD = ddMin(minD, det); + } else { + cet = azero; + cuddRef(cet); + det = CUDD_CONST_INDEX + 1.0; + } + + if (minD == dtt) { + if (dtt == dee && ctt == cee) { + res = createResult(dd,CUDD_CONST_INDEX,1,ctt,dtt); + } else { + res = createResult(dd,index,1,ctt,dtt); + } + } else if (minD == dee) { + res = createResult(dd,index,0,cee,dee); + } else if (minD == dte) { +#ifdef DD_DEBUG + assert(topf == topg); +#endif + res = createResult(dd,index,1,cte,dte); + } else { +#ifdef DD_DEBUG + assert(topf == topg); +#endif + res = createResult(dd,index,0,cet,det); + } + if (res == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + Cudd_RecursiveDeref(dd, cet); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + Cudd_RecursiveDeref(dd, cet); + + /* Only cache results that are different from azero to avoid + ** storing results that depend on the value of the bound. */ + if ((F->ref != 1 || G->ref != 1) && res != azero) + cuddCacheInsert2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g, res); + + cuddDeref(res); + return(res); + +} /* end of cuddBddClosestCube */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_MinHammingDist.] + + Description [Performs the recursive step of Cudd_MinHammingDist. + It is based on the following identity. Let H(f) be the + minimum Hamming distance of the minterms of f from the reference + minterm. Then: +

              + H(f) = min(H(f0)+h0,H(f1)+h1) + + where f0 and f1 are the two cofactors of f with respect to its top + variable; h0 is 1 if the minterm assigns 1 to the top variable of f; + h1 is 1 if the minterm assigns 0 to the top variable of f. + The upper bound on the distance is used to bound the depth of the + recursion. + Returns the minimum distance unless it exceeds the upper bound or + computation fails.] + + SideEffects [None] + + SeeAlso [Cudd_MinHammingDist] + +******************************************************************************/ +static int +cuddMinHammingDistRecur( + DdNode * f, + int *minterm, + DdHashTable * table, + int upperBound) +{ + DdNode *F, *Ft, *Fe; + double h, hT, hE; + DdNode *zero, *res; + DdManager *dd = table->manager; + + statLine(dd); + if (upperBound == 0) return(0); + + F = Cudd_Regular(f); + + if (cuddIsConstant(F)) { + zero = Cudd_Not(DD_ONE(dd)); + if (f == dd->background || f == zero) { + return(upperBound); + } else { + return(0); + } + } + if ((res = cuddHashTableLookup1(table,f)) != NULL) { + h = cuddV(res); + if (res->ref == 0) { + dd->dead++; + dd->constants.dead++; + } + return((int) h); + } + + Ft = cuddT(F); Fe = cuddE(F); + if (Cudd_IsComplement(f)) { + Ft = Cudd_Not(Ft); Fe = Cudd_Not(Fe); + } + if (minterm[F->index] == 0) { + DdNode *temp = Ft; + Ft = Fe; Fe = temp; + } + + hT = cuddMinHammingDistRecur(Ft,minterm,table,upperBound); + if (hT == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + if (hT == 0) { + hE = upperBound; + } else { + hE = cuddMinHammingDistRecur(Fe,minterm,table,upperBound - 1); + if (hE == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + } + h = ddMin(hT, hE + 1); + + if (F->ref != 1) { + ptrint fanout = (ptrint) F->ref; + cuddSatDec(fanout); + res = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) h); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + cuddRef(res); Cudd_RecursiveDeref(dd, res); + return(CUDD_OUT_OF_MEM); + } + } + + return((int) h); + +} /* end of cuddMinHammingDistRecur */ + + +/**Function******************************************************************** + + Synopsis [Separates cube from distance.] + + Description [Separates cube from distance. Returns the cube if + successful; NULL otherwise.] + + SideEffects [The distance is returned as a side effect.] + + SeeAlso [cuddBddClosestCube createResult] + +******************************************************************************/ +static DdNode * +separateCube( + DdManager *dd, + DdNode *f, + CUDD_VALUE_TYPE *distance) +{ + DdNode *cube, *t; + + /* One and zero are special cases because the distance is implied. */ + if (Cudd_IsConstant(f)) { + *distance = (f == DD_ONE(dd)) ? 0.0 : + (1.0 + (CUDD_VALUE_TYPE) CUDD_CONST_INDEX); + return(f); + } + + /* Find out which branch points to the distance and replace the top + ** node with one pointing to zero instead. */ + t = cuddT(f); + if (Cudd_IsConstant(t) && cuddV(t) <= 0) { +#ifdef DD_DEBUG + assert(!Cudd_IsConstant(cuddE(f)) || cuddE(f) == DD_ONE(dd)); +#endif + *distance = -cuddV(t); + cube = cuddUniqueInter(dd, f->index, DD_ZERO(dd), cuddE(f)); + } else { +#ifdef DD_DEBUG + assert(!Cudd_IsConstant(t) || t == DD_ONE(dd)); +#endif + *distance = -cuddV(cuddE(f)); + cube = cuddUniqueInter(dd, f->index, t, DD_ZERO(dd)); + } + + return(cube); + +} /* end of separateCube */ + + +/**Function******************************************************************** + + Synopsis [Builds a result for cache storage.] + + Description [Builds a result for cache storage. Returns a pointer + to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddBddClosestCube separateCube] + +******************************************************************************/ +static DdNode * +createResult( + DdManager *dd, + unsigned int index, + unsigned int phase, + DdNode *cube, + CUDD_VALUE_TYPE distance) +{ + DdNode *res, *constant; + + /* Special case. The cube is either one or zero, and we do not + ** add any variables. Hence, the result is also one or zero, + ** and the distance remains implied by the value of the constant. */ + if (index == CUDD_CONST_INDEX && Cudd_IsConstant(cube)) return(cube); + + constant = cuddUniqueConst(dd,-distance); + if (constant == NULL) return(NULL); + cuddRef(constant); + + if (index == CUDD_CONST_INDEX) { + /* Replace the top node. */ + if (cuddT(cube) == DD_ZERO(dd)) { + res = cuddUniqueInter(dd,cube->index,constant,cuddE(cube)); + } else { + res = cuddUniqueInter(dd,cube->index,cuddT(cube),constant); + } + } else { + /* Add a new top node. */ +#ifdef DD_DEBUG + assert(cuddI(dd,index) < cuddI(dd,cube->index)); +#endif + if (phase) { + res = cuddUniqueInter(dd,index,cube,constant); + } else { + res = cuddUniqueInter(dd,index,constant,cube); + } + } + if (res == NULL) { + Cudd_RecursiveDeref(dd, constant); + return(NULL); + } + cuddDeref(constant); /* safe because constant is part of res */ + + return(res); + +} /* end of createResult */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddRead.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddRead.c new file mode 100644 index 000000000..713668fe2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddRead.c @@ -0,0 +1,517 @@ +/**CFile*********************************************************************** + + FileName [cuddRead.c] + + PackageName [cudd] + + Synopsis [Functions to read in a matrix] + + Description [External procedures included in this module: +
                +
              • Cudd_addRead() +
              • Cudd_bddRead() +
              ] + + SeeAlso [cudd_addHarwell.c] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddRead.c,v 1.7 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Reads in a sparse matrix.] + + Description [Reads in a sparse matrix specified in a simple format. + The first line of the input contains the numbers of rows and columns. + The remaining lines contain the elements of the matrix, one per line. + Given a background value + (specified by the background field of the manager), only the values + different from it are explicitly listed. Each foreground element is + described by two integers, i.e., the row and column number, and a + real number, i.e., the value.

              + Cudd_addRead produces an ADD that depends on two sets of variables: x + and y. The x variables (x\[0\] ... x\[nx-1\]) encode the row index and + the y variables (y\[0\] ... y\[ny-1\]) encode the column index. + x\[0\] and y\[0\] are the most significant bits in the indices. + The variables may already exist or may be created by the function. + The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.

              + On input, nx and ny hold the numbers + of row and column variables already in existence. On output, they + hold the numbers of row and column variables actually used by the + matrix. When Cudd_addRead creates the variable arrays, + the index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy. + When some variables already exist Cudd_addRead expects the indices + of the existing x variables to be bx+i*sx, and the indices of the + existing y variables to be by+i*sy.

              + m and n are set to the numbers of rows and columns of the + matrix. Their values on input are immaterial. + The ADD for the + sparse matrix is returned in E, and its reference count is > 0. + Cudd_addRead returns 1 in case of success; 0 otherwise.] + + SideEffects [nx and ny are set to the numbers of row and column + variables. m and n are set to the numbers of rows and columns. x and y + are possibly extended to represent the array of row and column + variables. Similarly for xn and yn_, which hold on return from + Cudd_addRead the complements of the row and column variables.] + + SeeAlso [Cudd_addHarwell Cudd_bddRead] + +******************************************************************************/ +int +Cudd_addRead( + FILE * fp /* input file pointer */, + DdManager * dd /* DD manager */, + DdNode ** E /* characteristic function of the graph */, + DdNode *** x /* array of row variables */, + DdNode *** y /* array of column variables */, + DdNode *** xn /* array of complemented row variables */, + DdNode *** yn_ /* array of complemented column variables */, + int * nx /* number or row variables */, + int * ny /* number or column variables */, + int * m /* number of rows */, + int * n /* number of columns */, + int bx /* first index of row variables */, + int sx /* step of row variables */, + int by /* first index of column variables */, + int sy /* step of column variables */) +{ + DdNode *one, *zero; + DdNode *w, *neW; + DdNode *minterm1; + int u, v, err, i, nv; + int lnx, lny; + CUDD_VALUE_TYPE val; + DdNode **lx, **ly, **lxn, **lyn; + + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + err = fscanf(fp, "%d %d", &u, &v); + if (err == EOF) { + return(0); + } else if (err != 2) { + return(0); + } + + *m = u; + /* Compute the number of x variables. */ + lx = *x; lxn = *xn; + u--; /* row and column numbers start from 0 */ + for (lnx=0; u > 0; lnx++) { + u >>= 1; + } + /* Here we rely on the fact that REALLOC of a null pointer is + ** translates to an ALLOC. + */ + if (lnx > *nx) { + *x = lx = REALLOC(DdNode *, *x, lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *xn = lxn = REALLOC(DdNode *, *xn, lnx); + if (lxn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } + + *n = v; + /* Compute the number of y variables. */ + ly = *y; lyn = *yn_; + v--; /* row and column numbers start from 0 */ + for (lny=0; v > 0; lny++) { + v >>= 1; + } + /* Here we rely on the fact that REALLOC of a null pointer is + ** translates to an ALLOC. + */ + if (lny > *ny) { + *y = ly = REALLOC(DdNode *, *y, lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *yn_ = lyn = REALLOC(DdNode *, *yn_, lny); + if (lyn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } + + /* Create all new variables. */ + for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) { + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); + cuddRef(lx[i]); + do { + dd->reordered = 0; + lxn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lxn[i] == NULL) return(0); + cuddRef(lxn[i]); + } + for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) { + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); + do { + dd->reordered = 0; + lyn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lyn[i] == NULL) return(0); + cuddRef(lyn[i]); + } + *nx = lnx; + *ny = lny; + + *E = dd->background; /* this call will never cause reordering */ + cuddRef(*E); + + while (! feof(fp)) { + err = fscanf(fp, "%d %d %lf", &u, &v, &val); + if (err == EOF) { + break; + } else if (err != 3) { + return(0); + } else if (u >= *m || v >= *n || u < 0 || v < 0) { + return(0); + } + + minterm1 = one; cuddRef(minterm1); + + /* Build minterm1 corresponding to this arc */ + for (i = lnx - 1; i>=0; i--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lx[i]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lxn[i]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + u >>= 1; + } + for (i = lny - 1; i>=0; i--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, ly[i]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lyn[i]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + v >>= 1; + } + /* Create new constant node if necessary. + ** This call will never cause reordering. + */ + neW = cuddUniqueConst(dd, val); + if (neW == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(neW); + + w = Cudd_addIte(dd, minterm1, neW, *E); + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, neW); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, neW); + Cudd_RecursiveDeref(dd, *E); + *E = w; + } + return(1); + +} /* end of Cudd_addRead */ + + +/**Function******************************************************************** + + Synopsis [Reads in a graph (without labels) given as a list of arcs.] + + Description [Reads in a graph (without labels) given as an adjacency + matrix. The first line of the input contains the numbers of rows and + columns of the adjacency matrix. The remaining lines contain the arcs + of the graph, one per line. Each arc is described by two integers, + i.e., the row and column number, or the indices of the two endpoints. + Cudd_bddRead produces a BDD that depends on two sets of variables: x + and y. The x variables (x\[0\] ... x\[nx-1\]) encode + the row index and the y variables (y\[0\] ... y\[ny-1\]) encode the + column index. x\[0\] and y\[0\] are the most significant bits in the + indices. + The variables may already exist or may be created by the function. + The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.

              + On input, nx and ny hold the numbers of row and column variables already + in existence. On output, they hold the numbers of row and column + variables actually used by the matrix. When Cudd_bddRead creates the + variable arrays, the index of x\[i\] is bx+i*sx, and the index of + y\[i\] is by+i*sy. When some variables already exist, Cudd_bddRead + expects the indices of the existing x variables to be bx+i*sx, and the + indices of the existing y variables to be by+i*sy.

              + m and n are set to the numbers of rows and columns of the + matrix. Their values on input are immaterial. The BDD for the graph + is returned in E, and its reference count is > 0. Cudd_bddRead returns + 1 in case of success; 0 otherwise.] + + SideEffects [nx and ny are set to the numbers of row and column + variables. m and n are set to the numbers of rows and columns. x and y + are possibly extended to represent the array of row and column + variables.] + + SeeAlso [Cudd_addHarwell Cudd_addRead] + +******************************************************************************/ +int +Cudd_bddRead( + FILE * fp /* input file pointer */, + DdManager * dd /* DD manager */, + DdNode ** E /* characteristic function of the graph */, + DdNode *** x /* array of row variables */, + DdNode *** y /* array of column variables */, + int * nx /* number or row variables */, + int * ny /* number or column variables */, + int * m /* number of rows */, + int * n /* number of columns */, + int bx /* first index of row variables */, + int sx /* step of row variables */, + int by /* first index of column variables */, + int sy /* step of column variables */) +{ + DdNode *one, *zero; + DdNode *w; + DdNode *minterm1; + int u, v, err, i, nv; + int lnx, lny; + DdNode **lx, **ly; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + err = fscanf(fp, "%d %d", &u, &v); + if (err == EOF) { + return(0); + } else if (err != 2) { + return(0); + } + + *m = u; + /* Compute the number of x variables. */ + lx = *x; + u--; /* row and column numbers start from 0 */ + for (lnx=0; u > 0; lnx++) { + u >>= 1; + } + if (lnx > *nx) { + *x = lx = REALLOC(DdNode *, *x, lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } + + *n = v; + /* Compute the number of y variables. */ + ly = *y; + v--; /* row and column numbers start from 0 */ + for (lny=0; v > 0; lny++) { + v >>= 1; + } + if (lny > *ny) { + *y = ly = REALLOC(DdNode *, *y, lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } + + /* Create all new variables. */ + for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) { + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); + cuddRef(lx[i]); + } + for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) { + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); + } + *nx = lnx; + *ny = lny; + + *E = zero; /* this call will never cause reordering */ + cuddRef(*E); + + while (! feof(fp)) { + err = fscanf(fp, "%d %d", &u, &v); + if (err == EOF) { + break; + } else if (err != 2) { + return(0); + } else if (u >= *m || v >= *n || u < 0 || v < 0) { + return(0); + } + + minterm1 = one; cuddRef(minterm1); + + /* Build minterm1 corresponding to this arc. */ + for (i = lnx - 1; i>=0; i--) { + if (u & 1) { + w = Cudd_bddAnd(dd, minterm1, lx[i]); + } else { + w = Cudd_bddAnd(dd, minterm1, Cudd_Not(lx[i])); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd,minterm1); + minterm1 = w; + u >>= 1; + } + for (i = lny - 1; i>=0; i--) { + if (v & 1) { + w = Cudd_bddAnd(dd, minterm1, ly[i]); + } else { + w = Cudd_bddAnd(dd, minterm1, Cudd_Not(ly[i])); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + v >>= 1; + } + + w = Cudd_bddAnd(dd, Cudd_Not(minterm1), Cudd_Not(*E)); + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + w = Cudd_Not(w); + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, *E); + *E = w; + } + return(1); + +} /* end of Cudd_bddRead */ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddRef.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddRef.c new file mode 100644 index 000000000..457d71442 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddRef.c @@ -0,0 +1,808 @@ +/**CFile*********************************************************************** + + FileName [cuddRef.c] + + PackageName [cudd] + + Synopsis [Functions that manipulate the reference counts.] + + Description [External procedures included in this module: +

                +
              • Cudd_Ref() +
              • Cudd_RecursiveDeref() +
              • Cudd_IterDerefBdd() +
              • Cudd_DelayedDerefBdd() +
              • Cudd_RecursiveDerefZdd() +
              • Cudd_Deref() +
              • Cudd_CheckZeroRef() +
              + Internal procedures included in this module: +
                +
              • cuddReclaim() +
              • cuddReclaimZdd() +
              • cuddClearDeathRow() +
              • cuddShrinkDeathRow() +
              • cuddIsInDeathRow() +
              • cuddTimesInDeathRow() +
              + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddRef.c,v 1.29 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Increases the reference count of a node, if it is not + saturated.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_RecursiveDeref Cudd_Deref] + +******************************************************************************/ +void +Cudd_Ref( + DdNode * n) +{ + + n = Cudd_Regular(n); + + cuddSatInc(n->ref); + +} /* end of Cudd_Ref */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of node n.] + + Description [Decreases the reference count of node n. If n dies, + recursively decreases the reference counts of its children. It is + used to dispose of a DD that is no longer needed.] + + SideEffects [None] + + SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDerefZdd] + +******************************************************************************/ +void +Cudd_RecursiveDeref( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + + unsigned int live = table->keys - table->dead; + if (live > table->peakLiveNodes) { + table->peakLiveNodes = live; + } + + N = Cudd_Regular(n); + + do { +#ifdef DD_DEBUG + assert(N->ref != 0); +#endif + + if (N->ref == 1) { + N->ref = 0; + table->dead++; +#ifdef DD_STATS + table->nodesDropped++; +#endif + if (cuddIsConstant(N)) { + table->constants.dead++; + N = stack[--SP]; + } else { + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } + } else { + cuddSatDec(N->ref); + N = stack[--SP]; + } + } while (SP != 0); + +} /* end of Cudd_RecursiveDeref */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of BDD node n.] + + Description [Decreases the reference count of node n. If n dies, + recursively decreases the reference counts of its children. It is + used to dispose of a BDD that is no longer needed. It is more + efficient than Cudd_RecursiveDeref, but it cannot be used on + ADDs. The greater efficiency comes from being able to assume that no + constant node will ever die as a result of a call to this + procedure.] + + SideEffects [None] + + SeeAlso [Cudd_RecursiveDeref Cudd_DelayedDerefBdd] + +******************************************************************************/ +void +Cudd_IterDerefBdd( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + + unsigned int live = table->keys - table->dead; + if (live > table->peakLiveNodes) { + table->peakLiveNodes = live; + } + + N = Cudd_Regular(n); + + do { +#ifdef DD_DEBUG + assert(N->ref != 0); +#endif + + if (N->ref == 1) { + N->ref = 0; + table->dead++; +#ifdef DD_STATS + table->nodesDropped++; +#endif + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } else { + cuddSatDec(N->ref); + N = stack[--SP]; + } + } while (SP != 0); + +} /* end of Cudd_IterDerefBdd */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of BDD node n.] + + Description [Enqueues node n for later dereferencing. If the queue + is full decreases the reference count of the oldest node N to make + room for n. If N dies, recursively decreases the reference counts of + its children. It is used to dispose of a BDD that is currently not + needed, but may be useful again in the near future. The dereferencing + proper is done as in Cudd_IterDerefBdd.] + + SideEffects [None] + + SeeAlso [Cudd_RecursiveDeref Cudd_IterDerefBdd] + +******************************************************************************/ +void +Cudd_DelayedDerefBdd( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack; + int SP; + + unsigned int live = table->keys - table->dead; + if (live > table->peakLiveNodes) { + table->peakLiveNodes = live; + } + + n = Cudd_Regular(n); +#ifdef DD_DEBUG + assert(n->ref != 0); +#endif + +#ifdef DD_NO_DEATH_ROW + N = n; +#else + if (cuddIsConstant(n) || n->ref > 1) { +#ifdef DD_DEBUG + assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table))); +#endif + cuddSatDec(n->ref); + return; + } + + N = table->deathRow[table->nextDead]; + + if (N != NULL) { +#endif +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(N)); +#endif + stack = table->stack; + SP = 1; + do { +#ifdef DD_DEBUG + assert(N->ref != 0); +#endif + if (N->ref == 1) { + N->ref = 0; + table->dead++; +#ifdef DD_STATS + table->nodesDropped++; +#endif + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } else { + cuddSatDec(N->ref); + N = stack[--SP]; + } + } while (SP != 0); +#ifndef DD_NO_DEATH_ROW + } + table->deathRow[table->nextDead] = n; + + /* Udate insertion point. */ + table->nextDead++; + table->nextDead &= table->deadMask; +#if 0 + if (table->nextDead == table->deathRowDepth) { + if (table->deathRowDepth < table->looseUpTo / 2) { + extern void (*MMoutOfMemory)(long); + void (*saveHandler)(long) = MMoutOfMemory; + DdNodePtr *newRow; + MMoutOfMemory = Cudd_OutOfMem; + newRow = REALLOC(DdNodePtr,table->deathRow,2*table->deathRowDepth); + MMoutOfMemory = saveHandler; + if (newRow == NULL) { + table->nextDead = 0; + } else { + int i; + table->memused += table->deathRowDepth; + i = table->deathRowDepth; + table->deathRowDepth <<= 1; + for (; i < table->deathRowDepth; i++) { + newRow[i] = NULL; + } + table->deadMask = table->deathRowDepth - 1; + table->deathRow = newRow; + } + } else { + table->nextDead = 0; + } + } +#endif +#endif + +} /* end of Cudd_DelayedDerefBdd */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of ZDD node n.] + + Description [Decreases the reference count of ZDD node n. If n dies, + recursively decreases the reference counts of its children. It is + used to dispose of a ZDD that is no longer needed.] + + SideEffects [None] + + SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDeref] + +******************************************************************************/ +void +Cudd_RecursiveDerefZdd( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + + N = n; + + do { +#ifdef DD_DEBUG + assert(N->ref != 0); +#endif + + cuddSatDec(N->ref); + + if (N->ref == 0) { + table->deadZ++; +#ifdef DD_STATS + table->nodesDropped++; +#endif +#ifdef DD_DEBUG + assert(!cuddIsConstant(N)); +#endif + ord = table->permZ[N->index]; + stack[SP++] = cuddE(N); + table->subtableZ[ord].dead++; + N = cuddT(N); + } else { + N = stack[--SP]; + } + } while (SP != 0); + +} /* end of Cudd_RecursiveDerefZdd */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of node.] + + Description [Decreases the reference count of node. It is primarily + used in recursive procedures to decrease the ref count of a result + node before returning it. This accomplishes the goal of removing the + protection applied by a previous Cudd_Ref.] + + SideEffects [None] + + SeeAlso [Cudd_RecursiveDeref Cudd_RecursiveDerefZdd Cudd_Ref] + +******************************************************************************/ +void +Cudd_Deref( + DdNode * node) +{ + node = Cudd_Regular(node); + cuddSatDec(node->ref); + +} /* end of Cudd_Deref */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for nodes with non-zero reference + counts.] + + Description [Checks the unique table for nodes with non-zero + reference counts. It is normally called before Cudd_Quit to make sure + that there are no memory leaks due to missing Cudd_RecursiveDeref's. + Takes into account that reference counts may saturate and that the + basic constants and the projection functions are referenced by the + manager. Returns the number of nodes with non-zero reference count. + (Except for the cases mentioned above.)] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_CheckZeroRef( + DdManager * manager) +{ + int size; + int i, j; + int remain; /* the expected number of remaining references to one */ + DdNodePtr *nodelist; + DdNode *node; + DdNode *sentinel = &(manager->sentinel); + DdSubtable *subtable; + int count = 0; + int index; + +#ifndef DD_NO_DEATH_ROW + cuddClearDeathRow(manager); +#endif + + /* First look at the BDD/ADD subtables. */ + remain = 1; /* reference from the manager */ + size = manager->size; + remain += 2 * size; /* reference from the BDD projection functions */ + + for (i = 0; i < size; i++) { + subtable = &(manager->subtables[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + while (node != sentinel) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + index = (int) node->index; + if (node != manager->vars[index]) { + count++; + } else { + if (node->ref != 1) { + count++; + } + } + } + node = node->next; + } + } + } + + /* Then look at the ZDD subtables. */ + size = manager->sizeZ; + if (size) /* references from ZDD universe */ + remain += 2; + + for (i = 0; i < size; i++) { + subtable = &(manager->subtableZ[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + while (node != NULL) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + index = (int) node->index; + if (node == manager->univ[manager->permZ[index]]) { + if (node->ref > 2) { + count++; + } + } else { + count++; + } + } + node = node->next; + } + } + } + + /* Now examine the constant table. Plusinfinity, minusinfinity, and + ** zero are referenced by the manager. One is referenced by the + ** manager, by the ZDD universe, and by all projection functions. + ** All other nodes should have no references. + */ + nodelist = manager->constants.nodelist; + for (j = 0; (unsigned) j < manager->constants.slots; j++) { + node = nodelist[j]; + while (node != NULL) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + if (node == manager->one) { + if ((int) node->ref != remain) { + count++; + } + } else if (node == manager->zero || + node == manager->plusinfinity || + node == manager->minusinfinity) { + if (node->ref != 1) { + count++; + } + } else { + count++; + } + } + node = node->next; + } + } + return(count); + +} /* end of Cudd_CheckZeroRef */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Brings children of a dead node back.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddReclaimZdd] + +******************************************************************************/ +void +cuddReclaim( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + double initialDead = table->dead; + + N = Cudd_Regular(n); + +#ifdef DD_DEBUG + assert(N->ref == 0); +#endif + + do { + if (N->ref == 0) { + N->ref = 1; + table->dead--; + if (cuddIsConstant(N)) { + table->constants.dead--; + N = stack[--SP]; + } else { + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead--; + N = cuddT(N); + } + } else { + cuddSatInc(N->ref); + N = stack[--SP]; + } + } while (SP != 0); + + N = Cudd_Regular(n); + cuddSatDec(N->ref); + table->reclaimed += initialDead - table->dead; + +} /* end of cuddReclaim */ + + +/**Function******************************************************************** + + Synopsis [Brings children of a dead ZDD node back.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddReclaim] + +******************************************************************************/ +void +cuddReclaimZdd( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + + N = n; + +#ifdef DD_DEBUG + assert(N->ref == 0); +#endif + + do { + cuddSatInc(N->ref); + + if (N->ref == 1) { + table->deadZ--; + table->reclaimed++; +#ifdef DD_DEBUG + assert(!cuddIsConstant(N)); +#endif + ord = table->permZ[N->index]; + stack[SP++] = cuddE(N); + table->subtableZ[ord].dead--; + N = cuddT(N); + } else { + N = stack[--SP]; + } + } while (SP != 0); + + cuddSatDec(n->ref); + +} /* end of cuddReclaimZdd */ + + +/**Function******************************************************************** + + Synopsis [Shrinks the death row.] + + Description [Shrinks the death row by a factor of four.] + + SideEffects [None] + + SeeAlso [cuddClearDeathRow] + +******************************************************************************/ +void +cuddShrinkDeathRow( + DdManager *table) +{ +#ifndef DD_NO_DEATH_ROW + int i; + + if (table->deathRowDepth > 3) { + for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) { + if (table->deathRow[i] == NULL) break; + Cudd_IterDerefBdd(table,table->deathRow[i]); + table->deathRow[i] = NULL; + } + table->deathRowDepth /= 4; + table->deadMask = table->deathRowDepth - 1; + if ((unsigned) table->nextDead > table->deadMask) { + table->nextDead = 0; + } + table->deathRow = REALLOC(DdNodePtr, table->deathRow, + table->deathRowDepth); + } +#endif + +} /* end of cuddShrinkDeathRow */ + + +/**Function******************************************************************** + + Synopsis [Clears the death row.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_DelayedDerefBdd Cudd_IterDerefBdd Cudd_CheckZeroRef + cuddGarbageCollect] + +******************************************************************************/ +void +cuddClearDeathRow( + DdManager *table) +{ +#ifndef DD_NO_DEATH_ROW + int i; + + for (i = 0; i < table->deathRowDepth; i++) { + if (table->deathRow[i] == NULL) break; + Cudd_IterDerefBdd(table,table->deathRow[i]); + table->deathRow[i] = NULL; + } +#ifdef DD_DEBUG + for (; i < table->deathRowDepth; i++) { + assert(table->deathRow[i] == NULL); + } +#endif + table->nextDead = 0; +#endif + +} /* end of cuddClearDeathRow */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a node is in the death row.] + + Description [Checks whether a node is in the death row. Returns the + position of the first occurrence if the node is present; -1 + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_DelayedDerefBdd cuddClearDeathRow] + +******************************************************************************/ +int +cuddIsInDeathRow( + DdManager *dd, + DdNode *f) +{ +#ifndef DD_NO_DEATH_ROW + int i; + + for (i = 0; i < dd->deathRowDepth; i++) { + if (f == dd->deathRow[i]) { + return(i); + } + } +#endif + + return(-1); + +} /* end of cuddIsInDeathRow */ + + +/**Function******************************************************************** + + Synopsis [Counts how many times a node is in the death row.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_DelayedDerefBdd cuddClearDeathRow cuddIsInDeathRow] + +******************************************************************************/ +int +cuddTimesInDeathRow( + DdManager *dd, + DdNode *f) +{ + int count = 0; +#ifndef DD_NO_DEATH_ROW + int i; + + for (i = 0; i < dd->deathRowDepth; i++) { + count += f == dd->deathRow[i]; + } +#endif + + return(count); + +} /* end of cuddTimesInDeathRow */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddReorder.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddReorder.c new file mode 100644 index 000000000..11ce2f528 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddReorder.c @@ -0,0 +1,2137 @@ +/**CFile*********************************************************************** + + FileName [cuddReorder.c] + + PackageName [cudd] + + Synopsis [Functions for dynamic variable reordering.] + + Description [External procedures included in this file: +
                +
              • Cudd_ReduceHeap() +
              • Cudd_ShuffleHeap() +
              + Internal procedures included in this module: +
                +
              • cuddDynamicAllocNode() +
              • cuddSifting() +
              • cuddSwapping() +
              • cuddNextHigh() +
              • cuddNextLow() +
              • cuddSwapInPlace() +
              • cuddBddAlignToZdd() +
              + Static procedures included in this module: +
                +
              • ddUniqueCompare() +
              • ddSwapAny() +
              • ddSiftingAux() +
              • ddSiftingUp() +
              • ddSiftingDown() +
              • ddSiftingBackward() +
              • ddReorderPreprocess() +
              • ddReorderPostprocess() +
              • ddShuffle() +
              • ddSiftUp() +
              • bddFixTree() +
              ] + + Author [Shipra Panda, Bernard Plessier, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_MAX_SUBTABLE_SPARSITY 8 +#define DD_SHRINK_FACTOR 2 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddReorder.c,v 1.71 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int *entry; + +int ddTotalNumberSwapping; +#ifdef DD_STATS +int ddTotalNISwaps; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddUniqueCompare (int *ptrX, int *ptrY); +static Move * ddSwapAny (DdManager *table, int x, int y); +static int ddSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddSiftingUp (DdManager *table, int y, int xLow); +static Move * ddSiftingDown (DdManager *table, int x, int xHigh); +static int ddSiftingBackward (DdManager *table, int size, Move *moves); +static int ddReorderPreprocess (DdManager *table); +static int ddReorderPostprocess (DdManager *table); +static int ddShuffle (DdManager *table, int *permutation); +static int ddSiftUp (DdManager *table, int x, int xLow); +static void bddFixTree (DdManager *table, MtrNode *treenode); +static int ddUpdateMtrTree (DdManager *table, MtrNode *treenode, int *perm, int *invperm); +static int ddCheckPermuation (DdManager *table, MtrNode *treenode, int *perm, int *invperm); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Main dynamic reordering routine.] + + Description [Main dynamic reordering routine. + Calls one of the possible reordering procedures: +
                +
              • Swapping +
              • Sifting +
              • Symmetric Sifting +
              • Group Sifting +
              • Window Permutation +
              • Simulated Annealing +
              • Genetic Algorithm +
              • Dynamic Programming (exact) +
              + + For sifting, symmetric sifting, group sifting, and window + permutation it is possible to request reordering to convergence.

              + + The core of all methods is the reordering procedure + cuddSwapInPlace() which swaps two adjacent variables and is based + on Rudell's paper. + Returns 1 in case of success; 0 otherwise. In the case of symmetric + sifting (with and without convergence) returns 1 plus the number of + symmetric variables, in case of success.] + + SideEffects [Changes the variable order for all diagrams and clears + the cache.] + +******************************************************************************/ +int +Cudd_ReduceHeap( + DdManager * table /* DD manager */, + Cudd_ReorderingType heuristic /* method used for reordering */, + int minsize /* bound below which no reordering occurs */) +{ + DdHook *hook; + int result; + unsigned int nextDyn; +#ifdef DD_STATS + unsigned int initialSize; + unsigned int finalSize; +#endif + unsigned long localTime; + + /* Don't reorder if there are too many dead nodes. */ + if (table->keys - table->dead < (unsigned) minsize) + return(1); + + if (heuristic == CUDD_REORDER_SAME) { + heuristic = table->autoMethod; + } + if (heuristic == CUDD_REORDER_NONE) { + return(1); + } + + /* This call to Cudd_ReduceHeap does initiate reordering. Therefore + ** we count it. + */ + table->reorderings++; + + localTime = util_cpu_time(); + + /* Run the hook functions. */ + hook = table->preReorderingHook; + while (hook != NULL) { + int res = (hook->f)(table, "BDD", (void *)heuristic); + if (res == 0) return(0); + hook = hook->next; + } + + if (!ddReorderPreprocess(table)) return(0); + ddTotalNumberSwapping = 0; + + if (table->keys > table->peakLiveNodes) { + table->peakLiveNodes = table->keys; + } +#ifdef DD_STATS + initialSize = table->keys - table->isolated; + ddTotalNISwaps = 0; + + switch(heuristic) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + (void) fprintf(table->out,"#:I_RANDOM "); + break; + case CUDD_REORDER_SIFT: + case CUDD_REORDER_SIFT_CONVERGE: + case CUDD_REORDER_SYMM_SIFT: + case CUDD_REORDER_SYMM_SIFT_CONV: + case CUDD_REORDER_GROUP_SIFT: + case CUDD_REORDER_GROUP_SIFT_CONV: + (void) fprintf(table->out,"#:I_SIFTING "); + break; + case CUDD_REORDER_WINDOW2: + case CUDD_REORDER_WINDOW3: + case CUDD_REORDER_WINDOW4: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + (void) fprintf(table->out,"#:I_WINDOW "); + break; + case CUDD_REORDER_ANNEALING: + (void) fprintf(table->out,"#:I_ANNEAL "); + break; + case CUDD_REORDER_GENETIC: + (void) fprintf(table->out,"#:I_GENETIC "); + break; + case CUDD_REORDER_LINEAR: + case CUDD_REORDER_LINEAR_CONVERGE: + (void) fprintf(table->out,"#:I_LINSIFT "); + break; + case CUDD_REORDER_EXACT: + (void) fprintf(table->out,"#:I_EXACT "); + break; + default: + return(0); + } + (void) fprintf(table->out,"%8d: initial size",initialSize); +#endif + + /* See if we should use alternate threshold for maximum growth. */ + if (table->reordCycle && table->reorderings % table->reordCycle == 0) { + double saveGrowth = table->maxGrowth; + table->maxGrowth = table->maxGrowthAlt; + result = cuddTreeSifting(table,heuristic); + table->maxGrowth = saveGrowth; + } else { + result = cuddTreeSifting(table,heuristic); + } + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + finalSize = table->keys - table->isolated; + (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n", + ((double)(util_cpu_time() - localTime)/1000.0)); + (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n", + ddTotalNumberSwapping); + (void) fprintf(table->out,"#:M_REORDER %8d: NI swaps\n",ddTotalNISwaps); +#endif + + if (result == 0) + return(0); + + if (!ddReorderPostprocess(table)) + return(0); + + if (table->realign) { + if (!cuddZddAlignToBdd(table)) + return(0); + } + + nextDyn = (table->keys - table->constants.keys + 1) * + DD_DYN_RATIO + table->constants.keys; + if (table->reorderings < 20 || nextDyn > table->nextDyn) + table->nextDyn = nextDyn; + else + table->nextDyn += 20; + if (table->randomizeOrder != 0) { + table->nextDyn += Cudd_Random() & table->randomizeOrder; + } + table->reordered = 1; + + /* Run hook functions. */ + hook = table->postReorderingHook; + while (hook != NULL) { + int res = (hook->f)(table, "BDD", (void *)localTime); + if (res == 0) return(0); + hook = hook->next; + } + /* Update cumulative reordering time. */ + table->reordTime += util_cpu_time() - localTime; + + return(result); + +} /* end of Cudd_ReduceHeap */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables according to given permutation.] + + Description [Reorders variables according to given permutation. + The i-th entry of the permutation array contains the index of the variable + that should be brought to the i-th level. The size of the array should be + equal or greater to the number of variables currently in use. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [Changes the variable order for all diagrams and clears + the cache.] + + SeeAlso [Cudd_ReduceHeap] + +******************************************************************************/ +int +Cudd_ShuffleHeap( + DdManager * table /* DD manager */, + int * permutation /* required variable permutation */) +{ + + int result; + int i; + int identity = 1; + int *perm; + + /* Don't waste time in case of identity permutation. */ + for (i = 0; i < table->size; i++) { + if (permutation[i] != table->invperm[i]) { + identity = 0; + break; + } + } + if (identity == 1) { + return(1); + } + if (!ddReorderPreprocess(table)) return(0); + if (table->keys > table->peakLiveNodes) { + table->peakLiveNodes = table->keys; + } + + perm = ALLOC(int, table->size); + for (i = 0; i < table->size; i++) + perm[permutation[i]] = i; + if (!ddCheckPermuation(table,table->tree,perm,permutation)) { + FREE(perm); + return(0); + } + if (!ddUpdateMtrTree(table,table->tree,perm,permutation)) { + FREE(perm); + return(0); + } + FREE(perm); + + result = ddShuffle(table,permutation); + + if (!ddReorderPostprocess(table)) return(0); + + return(result); + +} /* end of Cudd_ShuffleHeap */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Dynamically allocates a Node.] + + Description [Dynamically allocates a Node. This procedure is similar + to cuddAllocNode in Cudd_Table.c, but it does not attempt garbage + collection, because during reordering there are no dead nodes. + Returns a pointer to a new node if successful; NULL is memory is + full.] + + SideEffects [None] + + SeeAlso [cuddAllocNode] + +******************************************************************************/ +DdNode * +cuddDynamicAllocNode( + DdManager * table) +{ + int i; + DdNodePtr *mem; + DdNode *list, *node; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (table->nextFree == NULL) { /* free list is empty */ + /* Try to allocate a new block. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdNodePtr *) ALLOC(DdNode, DD_MEM_CHUNK + 1); + MMoutOfMemory = saveHandler; + if (mem == NULL && table->stash != NULL) { + FREE(table->stash); + table->stash = NULL; + /* Inhibit resizing of tables. */ + table->maxCacheHard = table->cacheSlots - 1; + table->cacheSlack = - (int) (table->cacheSlots + 1); + for (i = 0; i < table->size; i++) { + table->subtables[i].maxKeys <<= 2; + } + mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1); + } + if (mem == NULL) { + /* Out of luck. Call the default handler to do + ** whatever it specifies for a failed malloc. If this + ** handler returns, then set error code, print + ** warning, and return. */ + (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); + table->errorCode = CUDD_MEMORY_OUT; +#ifdef DD_VERBOSE + (void) fprintf(table->err, + "cuddDynamicAllocNode: out of memory"); + (void) fprintf(table->err,"Memory in use = %lu\n", + table->memused); +#endif + return(NULL); + } else { /* successful allocation; slice memory */ + unsigned long offset; + table->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); + mem[0] = (DdNode *) table->memoryList; + table->memoryList = mem; + + /* Here we rely on the fact that the size of a DdNode is a + ** power of 2 and a multiple of the size of a pointer. + ** If we align one node, all the others will be aligned + ** as well. */ + offset = (unsigned long) mem & (sizeof(DdNode) - 1); + mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); +#ifdef DD_DEBUG + assert(((unsigned long) mem & (sizeof(DdNode) - 1)) == 0); +#endif + list = (DdNode *) mem; + + i = 1; + do { + list[i - 1].ref = 0; + list[i - 1].next = &list[i]; + } while (++i < DD_MEM_CHUNK); + + list[DD_MEM_CHUNK-1].ref = 0; + list[DD_MEM_CHUNK - 1].next = NULL; + + table->nextFree = &list[0]; + } + } /* if free list empty */ + + node = table->nextFree; + table->nextFree = node->next; + return (node); + +} /* end of cuddDynamicAllocNode */ + + +/**Function******************************************************************** + + Synopsis [Implementation of Rudell's sifting algorithm.] + + Description [Implementation of Rudell's sifting algorithm. + Assumes that no dead nodes are present. +

                +
              1. Order all the variables according to the number of entries + in each unique table. +
              2. Sift the variable up and down, remembering each time the + total size of the DD heap. +
              3. Select the best permutation. +
              4. Repeat 3 and 4 for all variables. +
              + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; +#ifdef DD_STATS + int previousSize; +#endif + + size = table->size; + + /* Find order in which to sift variables. */ + var = NULL; + entry = ALLOC(int,size); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddSiftingOutOfMem; + } + var = ALLOC(int,size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; + } + + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime + table->reordTime + > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + x = table->perm[var[i]]; + + if (x < lower || x > upper || table->subtables[x].bindVar == 1) + continue; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSiftingAux(table, x, lower, upper); + if (!result) goto cuddSiftingOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->err,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + FREE(var); + FREE(entry); + + return(1); + +cuddSiftingOutOfMem: + + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddSifting */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables by a sequence of (non-adjacent) swaps.] + + Description [Implementation of Plessier's algorithm that reorders + variables by a sequence of (non-adjacent) swaps. +
                +
              1. Select two variables (RANDOM or HEURISTIC). +
              2. Permute these variables. +
              3. If the nodes have decreased accept the permutation. +
              4. Otherwise reconstruct the original heap. +
              5. Loop. +
              + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddSwapping( + DdManager * table, + int lower, + int upper, + Cudd_ReorderingType heuristic) +{ + int i, j; + int max, keys; + int nvars; + int x, y; + int iterate; + int previousSize; + Move *moves, *move; + int pivot; + int modulo; + int result; + +#ifdef DD_DEBUG + /* Sanity check */ + assert(lower >= 0 && upper < table->size && lower <= upper); +#endif + + nvars = upper - lower + 1; + iterate = nvars; + + for (i = 0; i < iterate; i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { + max = -1; + for (j = lower; j <= upper; j++) { + if ((keys = table->subtables[j].keys) > max) { + max = keys; + pivot = j; + } + } + + modulo = upper - pivot; + if (modulo == 0) { + y = pivot; + } else{ + y = pivot + 1 + ((int) Cudd_Random() % modulo); + } + + modulo = pivot - lower - 1; + if (modulo < 1) { + x = lower; + } else{ + do { + x = (int) Cudd_Random() % modulo; + } while (x == y); + } + } else { + x = ((int) Cudd_Random() % nvars) + lower; + do { + y = ((int) Cudd_Random() % nvars) + lower; + } while (x == y); + } + previousSize = table->keys - table->isolated; + moves = ddSwapAny(table,x,y); + if (moves == NULL) goto cuddSwappingOutOfMem; + result = ddSiftingBackward(table,previousSize,moves); + if (!result) goto cuddSwappingOutOfMem; + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif +#if 0 + (void) fprintf(table->out,"#:t_SWAPPING %8d: tmp size\n", + table->keys - table->isolated); +#endif + } + + return(1); + +cuddSwappingOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(0); + +} /* end of cuddSwapping */ + + +/**Function******************************************************************** + + Synopsis [Finds the next subtable with a larger index.] + + Description [Finds the next subtable with a larger index. Returns the + index.] + + SideEffects [None] + + SeeAlso [cuddNextLow] + +******************************************************************************/ +int +cuddNextHigh( + DdManager * table, + int x) +{ + return(x+1); + +} /* end of cuddNextHigh */ + + +/**Function******************************************************************** + + Synopsis [Finds the next subtable with a smaller index.] + + Description [Finds the next subtable with a smaller index. Returns the + index.] + + SideEffects [None] + + SeeAlso [cuddNextHigh] + +******************************************************************************/ +int +cuddNextLow( + DdManager * table, + int x) +{ + return(x-1); + +} /* end of cuddNextLow */ + + +/**Function******************************************************************** + + Synopsis [Swaps two adjacent variables.] + + Description [Swaps two adjacent variables. It assumes that no dead + nodes are present on entry to this procedure. The procedure then + guarantees that no dead nodes will be present when it terminates. + cuddSwapInPlace assumes that x < y. Returns the number of keys in + the table if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddSwapInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int comple, newcomplement; + int i; + Cudd_VariableType varType; + Cudd_LazyGroupType groupType; + int posn; + int isolated; + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0; + DdNode *g,*next; + DdNodePtr *previousP; + DdNode *tmp; + DdNode *sentinel = &(table->sentinel); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + +#ifdef DD_DEBUG + int count,idcheck; +#endif + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddNextHigh(table,x) == y); + assert(table->subtables[x].keys != 0); + assert(table->subtables[y].keys != 0); + assert(table->subtables[x].dead == 0); + assert(table->subtables[y].dead == 0); +#endif + + ddTotalNumberSwapping++; + + /* Get parameters of x subtable. */ + xindex = table->invperm[x]; + xlist = table->subtables[x].nodelist; + oldxkeys = table->subtables[x].keys; + xslots = table->subtables[x].slots; + xshift = table->subtables[x].shift; + + /* Get parameters of y subtable. */ + yindex = table->invperm[y]; + ylist = table->subtables[y].nodelist; + oldykeys = table->subtables[y].keys; + yslots = table->subtables[y].slots; + yshift = table->subtables[y].shift; + + if (!cuddTestInteract(table,xindex,yindex)) { +#ifdef DD_STATS + ddTotalNISwaps++; +#endif + newxkeys = oldxkeys; + newykeys = oldykeys; + } else { + newxkeys = 0; + newykeys = oldykeys; + + /* Check whether the two projection functions involved in this + ** swap are isolated. At the end, we'll be able to tell how many + ** isolated projection functions are there by checking only these + ** two functions again. This is done to eliminate the isolated + ** projection functions from the node count. + */ + isolated = - ((table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1)); + + /* The nodes in the x layer that do not depend on + ** y will stay there; the others are put in a chain. + ** The chain is handled as a LIFO; g points to the beginning. + */ + g = NULL; + if ((oldxkeys >= xslots || (unsigned) xslots == table->initSlots) && + oldxkeys <= DD_MAX_SUBTABLE_DENSITY * xslots) { + for (i = 0; i < xslots; i++) { + previousP = &(xlist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if (f1->index != (DdHalfWord) yindex && + Cudd_Regular(f0)->index != (DdHalfWord) yindex) { + /* stays */ + newxkeys++; + *previousP = f; + previousP = &(f->next); + } else { + f->index = yindex; + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ + *previousP = sentinel; + } /* for each slot of the x subtable */ + } else { /* resize xlist */ + DdNode *h = NULL; + DdNodePtr *newxlist; + unsigned int newxslots; + int newxshift; + /* Empty current xlist. Nodes that stay go to list h; + ** nodes that move go to list g. */ + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if (f1->index != (DdHalfWord) yindex && + Cudd_Regular(f0)->index != (DdHalfWord) yindex) { + /* stays */ + f->next = h; + h = f; + newxkeys++; + } else { + f->index = yindex; + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ + } /* for each slot of the x subtable */ + /* Decide size of new subtable. */ + newxshift = xshift; + newxslots = xslots; + while ((unsigned) oldxkeys > DD_MAX_SUBTABLE_DENSITY * newxslots) { + newxshift--; + newxslots <<= 1; + } + while ((unsigned) oldxkeys < newxslots && + newxslots > table->initSlots) { + newxshift++; + newxslots >>= 1; + } + /* Try to allocate new table. Be ready to back off. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + newxlist = ALLOC(DdNodePtr, newxslots); + MMoutOfMemory = saveHandler; + if (newxlist == NULL) { + (void) fprintf(table->err, "Unable to resize subtable %d for lack of memory\n", i); + newxlist = xlist; + newxslots = xslots; + newxshift = xshift; + } else { + table->slots += ((int) newxslots - xslots); + table->minDead = (unsigned) + (table->gcFrac * (double) table->slots); + table->cacheSlack = (int) + ddMin(table->maxCacheHard, DD_MAX_CACHE_TO_SLOTS_RATIO + * table->slots) - 2 * (int) table->cacheSlots; + table->memused += + ((int) newxslots - xslots) * sizeof(DdNodePtr); + FREE(xlist); + xslots = newxslots; + xshift = newxshift; + xlist = newxlist; + } + /* Initialize new subtable. */ + for (i = 0; i < xslots; i++) { + xlist[i] = sentinel; + } + /* Move nodes that were parked in list h to their new home. */ + f = h; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); + f0 = cuddE(f); + /* Check xlist for pair (f11,f01). */ + posn = ddHash(f1, f0, xshift); + /* For each element tmp in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + tmp = *previousP; + while (f1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (f1 == cuddT(tmp) && f0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; + *previousP = f; + f = next; + } + } + +#ifdef DD_COUNT + table->swapSteps += oldxkeys - newxkeys; +#endif + /* Take care of the x nodes that must be re-expressed. + ** They form a linked list pointed by g. Their index has been + ** already changed to yindex. + */ + f = g; + while (f != NULL) { + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f1))); +#endif + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = f10 = f1; + } +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f11))); +#endif + f0 = cuddE(f); + comple = Cudd_IsComplement(f0); + f0 = Cudd_Regular(f0); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == f01) { + newf1 = f11; + cuddSatInc(newf1->ref); + } else { + /* Check xlist for triple (xindex,f11,f01). */ + posn = ddHash(f11, f01, xshift); + /* For each element newf1 in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + newf1 = *previousP; + while (f11 < cuddT(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + while (f11 == cuddT(newf1) && f01 < cuddE(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { + cuddSatInc(newf1->ref); + } else { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto cuddSwapOutOfMem; + newf1->index = xindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f01; + /* Insert newf1 in the collision list xlist[posn]; + ** increase the ref counts of f11 and f01. + */ + newxkeys++; + newf1->next = *previousP; + *previousP = newf1; + cuddSatInc(f11->ref); + tmp = Cudd_Regular(f01); + cuddSatInc(tmp->ref); + } + } + cuddT(f) = newf1; +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(newf1))); +#endif + + /* Do the same for f0, keeping complement dots into account. */ + /* Decrease ref count of f0. */ + tmp = Cudd_Regular(f0); + cuddSatDec(tmp->ref); + /* Create the new E child. */ + if (f10 == f00) { + newf0 = f00; + tmp = Cudd_Regular(newf0); + cuddSatInc(tmp->ref); + } else { + /* make sure f10 is regular */ + newcomplement = Cudd_IsComplement(f10); + if (newcomplement) { + f10 = Cudd_Not(f10); + f00 = Cudd_Not(f00); + } + /* Check xlist for triple (xindex,f10,f00). */ + posn = ddHash(f10, f00, xshift); + /* For each element newf0 in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + newf0 = *previousP; + while (f10 < cuddT(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + while (f10 == cuddT(newf0) && f00 < cuddE(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { + cuddSatInc(newf0->ref); + } else { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto cuddSwapOutOfMem; + newf0->index = xindex; newf0->ref = 1; + cuddT(newf0) = f10; + cuddE(newf0) = f00; + /* Insert newf0 in the collision list xlist[posn]; + ** increase the ref counts of f10 and f00. + */ + newxkeys++; + newf0->next = *previousP; + *previousP = newf0; + cuddSatInc(f10->ref); + tmp = Cudd_Regular(f00); + cuddSatInc(tmp->ref); + } + if (newcomplement) { + newf0 = Cudd_Not(newf0); + } + } + cuddE(f) = newf0; + + /* Insert the modified f in ylist. + ** The modified f does not already exists in ylist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, yshift); + newykeys++; + previousP = &(ylist[posn]); + tmp = *previousP; + while (newf1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; + *previousP = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previousP = &(ylist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + if (f->ref == 0) { + tmp = cuddT(f); + cuddSatDec(tmp->ref); + tmp = Cudd_Regular(cuddE(f)); + cuddSatDec(tmp->ref); + cuddDeallocNode(table,f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = sentinel; + } /* for i */ + +#ifdef DD_DEBUG +#if 0 + (void) fprintf(table->out,"Swapping %d and %d\n",x,y); +#endif + count = 0; + idcheck = 0; + for (i = 0; i < yslots; i++) { + f = ylist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) yindex) + idcheck++; + f = f->next; + } + } + if (count != newykeys) { + (void) fprintf(table->out, + "Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n", + oldykeys,newykeys,count); + } + if (idcheck != 0) + (void) fprintf(table->out, + "Error in id's of ylist\twrong id's = %d\n", + idcheck); + count = 0; + idcheck = 0; + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) xindex) + idcheck++; + f = f->next; + } + } + if (count != newxkeys) { + (void) fprintf(table->out, + "Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n", + oldxkeys,newxkeys,count); + } + if (idcheck != 0) + (void) fprintf(table->out, + "Error in id's of xlist\twrong id's = %d\n", + idcheck); +#endif + + isolated += (table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1); + table->isolated += isolated; + } + + /* Set the appropriate fields in table. */ + table->subtables[x].nodelist = ylist; + table->subtables[x].slots = yslots; + table->subtables[x].shift = yshift; + table->subtables[x].keys = newykeys; + table->subtables[x].maxKeys = yslots * DD_MAX_SUBTABLE_DENSITY; + i = table->subtables[x].bindVar; + table->subtables[x].bindVar = table->subtables[y].bindVar; + table->subtables[y].bindVar = i; + /* Adjust filds for lazy sifting. */ + varType = table->subtables[x].varType; + table->subtables[x].varType = table->subtables[y].varType; + table->subtables[y].varType = varType; + i = table->subtables[x].pairIndex; + table->subtables[x].pairIndex = table->subtables[y].pairIndex; + table->subtables[y].pairIndex = i; + i = table->subtables[x].varHandled; + table->subtables[x].varHandled = table->subtables[y].varHandled; + table->subtables[y].varHandled = i; + groupType = table->subtables[x].varToBeGrouped; + table->subtables[x].varToBeGrouped = table->subtables[y].varToBeGrouped; + table->subtables[y].varToBeGrouped = groupType; + + table->subtables[y].nodelist = xlist; + table->subtables[y].slots = xslots; + table->subtables[y].shift = xshift; + table->subtables[y].keys = newxkeys; + table->subtables[y].maxKeys = xslots * DD_MAX_SUBTABLE_DENSITY; + + table->perm[xindex] = y; table->perm[yindex] = x; + table->invperm[x] = yindex; table->invperm[y] = xindex; + + table->keys += newxkeys + newykeys - oldxkeys - oldykeys; + + return(table->keys - table->isolated); + +cuddSwapOutOfMem: + (void) fprintf(table->err,"Error: cuddSwapInPlace out of memory\n"); + + return (0); + +} /* end of cuddSwapInPlace */ + + +/**Function******************************************************************** + + Synopsis [Reorders BDD variables according to the order of the ZDD + variables.] + + Description [Reorders BDD variables according to the order of the + ZDD variables. This function can be called at the end of ZDD + reordering to insure that the order of the BDD variables is + consistent with the order of the ZDD variables. The number of ZDD + variables must be a multiple of the number of BDD variables. Let + M be the ratio of the two numbers. cuddBddAlignToZdd + then considers the ZDD variables from M*i to + (M+1)*i-1 as corresponding to BDD variable + i. This function should be normally called from + Cudd_zddReduceHeap, which clears the cache. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [Changes the BDD variable order for all diagrams and performs + garbage collection of the BDD unique table.] + + SeeAlso [Cudd_ShuffleHeap Cudd_zddReduceHeap] + +******************************************************************************/ +int +cuddBddAlignToZdd( + DdManager * table /* DD manager */) +{ + int *invperm; /* permutation array */ + int M; /* ratio of ZDD variables to BDD variables */ + int i; /* loop index */ + int result; /* return value */ + + /* We assume that a ratio of 0 is OK. */ + if (table->size == 0) + return(1); + + M = table->sizeZ / table->size; + /* Check whether the number of ZDD variables is a multiple of the + ** number of BDD variables. + */ + if (M * table->size != table->sizeZ) + return(0); + /* Create and initialize the inverse permutation array. */ + invperm = ALLOC(int,table->size); + if (invperm == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < table->sizeZ; i += M) { + int indexZ = table->invpermZ[i]; + int index = indexZ / M; + invperm[i / M] = index; + } + /* Eliminate dead nodes. Do not scan the cache again, because we + ** assume that Cudd_zddReduceHeap has already cleared it. + */ + cuddGarbageCollect(table,0); + + /* Initialize number of isolated projection functions. */ + table->isolated = 0; + for (i = 0; i < table->size; i++) { + if (table->vars[i]->ref == 1) table->isolated++; + } + + /* Initialize the interaction matrix. */ + result = cuddInitInteract(table); + if (result == 0) return(0); + + result = ddShuffle(table, invperm); + FREE(invperm); + /* Free interaction matrix. */ + FREE(table->interact); + /* Fix the BDD variable group tree. */ + bddFixTree(table,table->tree); + return(result); + +} /* end of cuddBddAlignToZdd */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + +******************************************************************************/ +static int +ddUniqueCompare( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of ddUniqueCompare */ + + +/**Function******************************************************************** + + Synopsis [Swaps any two variables.] + + Description [Swaps any two variables. Returns the set of moves.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSwapAny( + DdManager * table, + int x, + int y) +{ + Move *move, *moves; + int xRef,yRef; + int xNext,yNext; + int size; + int limitSize; + int tmp; + + if (x >y) { + tmp = x; x = y; y = tmp; + } + + xRef = x; yRef = y; + + xNext = cuddNextHigh(table,x); + yNext = cuddNextLow(table,y); + moves = NULL; + limitSize = table->keys - table->isolated; + + for (;;) { + if ( xNext == yNext) { + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,yNext,y); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = yNext; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + + } else if (x == yNext) { + + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + + } else { + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,yNext,y); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = yNext; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + x = xNext; + y = yNext; + } + + xNext = cuddNextHigh(table,x); + yNext = cuddNextLow(table,y); + if (xNext > yRef) break; + + if ((double) size > table->maxGrowth * (double) limitSize) break; + if (size < limitSize) limitSize = size; + } + if (yNext>=xRef) { + size = cuddSwapInPlace(table,yNext,y); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = yNext; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + } + + return(moves); + +ddSwapAnyOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of ddSwapAny */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; + + initialSize = table->keys - table->isolated; + + moveDown = NULL; + moveUp = NULL; + + if (x == xLow) { + moveDown = ddSiftingDown(table,x,xHigh); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddSiftingAuxOutOfMem; + + } else if (x == xHigh) { + moveUp = ddSiftingUp(table,x,xLow); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddSiftingAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + moveDown = ddSiftingDown(table,x,xHigh); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + if (moveDown != NULL) { + x = moveDown->y; + } + moveUp = ddSiftingUp(table,x,xLow); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position */ + result = ddSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddSiftingAuxOutOfMem; + + } else { /* must go up first: shorter */ + moveUp = ddSiftingUp(table,x,xLow); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + if (moveUp != NULL) { + x = moveUp->x; + } + moveDown = ddSiftingDown(table,x,xHigh); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddSiftingAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +ddSiftingAuxOutOfMem: + if (moveDown != (Move *) CUDD_OUT_OF_MEM) { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + } + if (moveUp != (Move *) CUDD_OUT_OF_MEM) { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + } + + return(0); + +} /* end of ddSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable up.] + + Description [Sifts a variable up. Moves y up until either it reaches + the bound (xLow) or the size of the DD heap increases too much. + Returns the set of moves in case of success; NULL if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSiftingUp( + DdManager * table, + int y, + int xLow) +{ + Move *moves; + Move *move; + int x; + int size; + int limitSize; + int xindex, yindex; + int isolated; + int L; /* lower bound on DD size */ +#ifdef DD_DEBUG + int checkL; + int z; + int zindex; +#endif + + moves = NULL; + yindex = table->invperm[y]; + + /* Initialize the lower bound. + ** The part of the DD below y will not change. + ** The part of the DD above y that does not interact with y will not + ** change. The rest may vanish in the best case, except for + ** the nodes at level xLow, which will not vanish, regardless. + */ + limitSize = L = table->keys - table->isolated; + for (x = xLow + 1; x < y; x++) { + xindex = table->invperm[x]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L -= table->subtables[x].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + L -= table->subtables[y].keys - isolated; + + x = cuddNextLow(table,y); + while (x >= xLow && L <= limitSize) { + xindex = table->invperm[x]; +#ifdef DD_DEBUG + checkL = table->keys - table->isolated; + for (z = xLow + 1; z < y; z++) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + checkL -= table->subtables[y].keys - isolated; + assert(L == checkL); +#endif + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddSiftingUpOutOfMem; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + y = x; + x = cuddNextLow(table,y); + } + return(moves); + +ddSiftingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable down.] + + Description [Sifts a variable down. Moves x down until either it + reaches the bound (xHigh) or the size of the DD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSiftingDown( + DdManager * table, + int x, + int xHigh) +{ + Move *moves; + Move *move; + int y; + int size; + int R; /* upper bound on node decrease */ + int limitSize; + int xindex, yindex; + int isolated; +#ifdef DD_DEBUG + int checkR; + int z; + int zindex; +#endif + + moves = NULL; + /* Initialize R */ + xindex = table->invperm[x]; + limitSize = size = table->keys - table->isolated; + R = 0; + for (y = xHigh; y > x; y--) { + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R += table->subtables[y].keys - isolated; + } + } + + y = cuddNextHigh(table,x); + while (y <= xHigh && size - R < limitSize) { +#ifdef DD_DEBUG + checkR = 0; + for (z = xHigh; z > x; z--) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + assert(R == checkR); +#endif + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddSiftingDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + x = y; + y = cuddNextHigh(table,x); + } + return(moves); + +ddSiftingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the DD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSiftingBackward( + DdManager * table, + int size, + Move * moves) +{ + Move *move; + int res; + + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + + return(1); + +} /* end of ddSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Prepares the DD heap for dynamic reordering.] + + Description [Prepares the DD heap for dynamic reordering. Does + garbage collection, to guarantee that there are no dead nodes; + clears the cache, which is invalidated by dynamic reordering; initializes + the number of isolated projection functions; and initializes the + interaction matrix. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddReorderPreprocess( + DdManager * table) +{ + int i; + int res; + + /* Clear the cache. */ + cuddCacheFlush(table); + cuddLocalCacheClearAll(table); + + /* Eliminate dead nodes. Do not scan the cache again. */ + cuddGarbageCollect(table,0); + + /* Initialize number of isolated projection functions. */ + table->isolated = 0; + for (i = 0; i < table->size; i++) { + if (table->vars[i]->ref == 1) table->isolated++; + } + + /* Initialize the interaction matrix. */ + res = cuddInitInteract(table); + if (res == 0) return(0); + + return(1); + +} /* end of ddReorderPreprocess */ + + +/**Function******************************************************************** + + Synopsis [Cleans up at the end of reordering.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static int +ddReorderPostprocess( + DdManager * table) +{ + +#ifdef DD_VERBOSE + (void) fflush(table->out); +#endif + + /* Free interaction matrix. */ + FREE(table->interact); + + return(1); + +} /* end of ddReorderPostprocess */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables according to a given permutation.] + + Description [Reorders variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. ddShuffle assumes that no + dead nodes are present and that the interaction matrix is properly + initialized. The reordering is achieved by a series of upward sifts. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddShuffle( + DdManager * table, + int * permutation) +{ + int index; + int level; + int position; + int numvars; + int result; +#ifdef DD_STATS + unsigned long localTime; + int initialSize; + int finalSize; + int previousSize; +#endif + + ddTotalNumberSwapping = 0; +#ifdef DD_STATS + localTime = util_cpu_time(); + initialSize = table->keys - table->isolated; + (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n", + initialSize); + ddTotalNISwaps = 0; +#endif + + numvars = table->size; + + for (level = 0; level < numvars; level++) { + index = permutation[level]; + position = table->perm[index]; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSiftUp(table,position,level); + if (!result) return(0); +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + finalSize = table->keys - table->isolated; + (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:T_SHUFFLE %8g: total time (sec)\n", + ((double)(util_cpu_time() - localTime)/1000.0)); + (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n", + ddTotalNumberSwapping); + (void) fprintf(table->out,"#:M_SHUFFLE %8d: NI swaps\n",ddTotalNISwaps); +#endif + + return(1); + +} /* end of ddShuffle */ + + +/**Function******************************************************************** + + Synopsis [Moves one variable up.] + + Description [Takes a variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddSiftUp( + DdManager * table, + int x, + int xLow) +{ + int y; + int size; + + y = cuddNextLow(table,x); + while (y >= xLow) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); + } + return(1); + +} /* end of ddSiftUp */ + + +/**Function******************************************************************** + + Synopsis [Fixes the BDD variable group tree after a shuffle.] + + Description [Fixes the BDD variable group tree after a + shuffle. Assumes that the order of the variables in a terminal node + has not been changed.] + + SideEffects [Changes the BDD variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static void +bddFixTree( + DdManager * table, + MtrNode * treenode) +{ + if (treenode == NULL) return; + treenode->low = ((int) treenode->index < table->size) ? + table->perm[treenode->index] : treenode->index; + if (treenode->child != NULL) { + bddFixTree(table, treenode->child); + } + if (treenode->younger != NULL) + bddFixTree(table, treenode->younger); + if (treenode->parent != NULL && treenode->low < treenode->parent->low) { + treenode->parent->low = treenode->low; + treenode->parent->index = treenode->index; + } + return; + +} /* end of bddFixTree */ + + +/**Function******************************************************************** + + Synopsis [Updates the BDD variable group tree before a shuffle.] + + Description [Updates the BDD variable group tree before a shuffle. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Changes the BDD variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static int +ddUpdateMtrTree( + DdManager * table, + MtrNode * treenode, + int * perm, + int * invperm) +{ + unsigned int i, size; + int index, level, minLevel, maxLevel, minIndex; + + if (treenode == NULL) return(1); + + minLevel = CUDD_MAXINDEX; + maxLevel = 0; + minIndex = -1; + /* i : level */ + for (i = treenode->low; i < treenode->low + treenode->size; i++) { + index = table->invperm[i]; + level = perm[index]; + if (level < minLevel) { + minLevel = level; + minIndex = index; + } + if (level > maxLevel) + maxLevel = level; + } + size = maxLevel - minLevel + 1; + if (minIndex == -1) return(0); + if (size == treenode->size) { + treenode->low = minLevel; + treenode->index = minIndex; + } else { + return(0); + } + + if (treenode->child != NULL) { + if (!ddUpdateMtrTree(table, treenode->child, perm, invperm)) + return(0); + } + if (treenode->younger != NULL) { + if (!ddUpdateMtrTree(table, treenode->younger, perm, invperm)) + return(0); + } + return(1); +} + + +/**Function******************************************************************** + + Synopsis [Checks the BDD variable group tree before a shuffle.] + + Description [Checks the BDD variable group tree before a shuffle. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Changes the BDD variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static int +ddCheckPermuation( + DdManager * table, + MtrNode * treenode, + int * perm, + int * invperm) +{ + unsigned int i, size; + int index, level, minLevel, maxLevel; + + if (treenode == NULL) return(1); + + minLevel = table->size; + maxLevel = 0; + /* i : level */ + for (i = treenode->low; i < treenode->low + treenode->size; i++) { + index = table->invperm[i]; + level = perm[index]; + if (level < minLevel) + minLevel = level; + if (level > maxLevel) + maxLevel = level; + } + size = maxLevel - minLevel + 1; + if (size != treenode->size) + return(0); + + if (treenode->child != NULL) { + if (!ddCheckPermuation(table, treenode->child, perm, invperm)) + return(0); + } + if (treenode->younger != NULL) { + if (!ddCheckPermuation(table, treenode->younger, perm, invperm)) + return(0); + } + return(1); +} diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSat.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSat.c new file mode 100644 index 000000000..a3ef50fc1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSat.c @@ -0,0 +1,1774 @@ +/**CFile*********************************************************************** + + FileName [cuddSat.c] + + PackageName [cudd] + + Synopsis [Functions for the solution of satisfiability related problems.] + + Description [External procedures included in this file: +
                +
              • Cudd_Eval() +
              • Cudd_ShortestPath() +
              • Cudd_LargestCube() +
              • Cudd_ShortestLength() +
              • Cudd_Decreasing() +
              • Cudd_Increasing() +
              • Cudd_EquivDC() +
              • Cudd_bddLeqUnless() +
              • Cudd_EqualSupNorm() +
              • Cudd_bddMakePrime() +
              • Cudd_bddMaximallyExpand() +
              • Cudd_bddLargestPrimeUnate() +
              + Internal procedures included in this module: +
                +
              • cuddBddMakePrime() +
              + Static procedures included in this module: +
                +
              • freePathPair() +
              • getShortest() +
              • getPath() +
              • getLargest() +
              • getCube() +
              • ddBddMaximallyExpand() +
              • ddShortestPathUnate() +
              ] + + Author [Seh-Woong Jeong, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_BIGGY 100000000 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct cuddPathPair { + int pos; + int neg; +} cuddPathPair; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSat.c,v 1.39 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static DdNode *one, *zero; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define WEIGHT(weight, col) ((weight) == NULL ? 1 : weight[col]) + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static enum st_retval freePathPair (char *key, char *value, char *arg); +static cuddPathPair getShortest (DdNode *root, int *cost, int *support, st_table *visited); +static DdNode * getPath (DdManager *manager, st_table *visited, DdNode *f, int *weight, int cost); +static cuddPathPair getLargest (DdNode *root, st_table *visited); +static DdNode * getCube (DdManager *manager, st_table *visited, DdNode *f, int cost); +static DdNode * ddBddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f); +static int ddBddShortestPathUnate(DdManager *dd, DdNode *f, int *phases, st_table *table); +static DdNode * ddGetLargestCubeUnate(DdManager *dd, DdNode *f, int *phases, st_table *table); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns the value of a DD for a given variable assignment.] + + Description [Finds the value of a DD for a given variable + assignment. The variable assignment is passed in an array of int's, + that should specify a zero or a one for each variable in the support + of the function. Returns a pointer to a constant node. No new nodes + are produced.] + + SideEffects [None] + + SeeAlso [Cudd_bddLeq Cudd_addEvalConst] + +******************************************************************************/ +DdNode * +Cudd_Eval( + DdManager * dd, + DdNode * f, + int * inputs) +{ + int comple; + DdNode *ptr; + + comple = Cudd_IsComplement(f); + ptr = Cudd_Regular(f); + + while (!cuddIsConstant(ptr)) { + if (inputs[ptr->index] == 1) { + ptr = cuddT(ptr); + } else { + comple ^= Cudd_IsComplement(cuddE(ptr)); + ptr = Cudd_Regular(cuddE(ptr)); + } + } + return(Cudd_NotCond(ptr,comple)); + +} /* end of Cudd_Eval */ + + +/**Function******************************************************************** + + Synopsis [Finds a shortest path in a DD.] + + Description [Finds a shortest path in a DD. f is the DD we want to + get the shortest path for; weight\[i\] is the weight of the THEN arc + coming from the node whose index is i. If weight is NULL, then unit + weights are assumed for all THEN arcs. All ELSE arcs have 0 weight. + If non-NULL, both weight and support should point to arrays with at + least as many entries as there are variables in the manager. + Returns the shortest path as the BDD of a cube.] + + SideEffects [support contains on return the true support of f. + If support is NULL on entry, then Cudd_ShortestPath does not compute + the true support info. length contains the length of the path.] + + SeeAlso [Cudd_ShortestLength Cudd_LargestCube] + +******************************************************************************/ +DdNode * +Cudd_ShortestPath( + DdManager * manager, + DdNode * f, + int * weight, + int * support, + int * length) +{ + DdNode *F; + st_table *visited; + DdNode *sol; + cuddPathPair *rootPair; + int complement, cost; + int i; + + one = DD_ONE(manager); + zero = DD_ZERO(manager); + + /* Initialize support. Support does not depend on variable order. + ** Hence, it does not need to be reinitialized if reordering occurs. + */ + if (support) { + for (i = 0; i < manager->size; i++) { + support[i] = 0; + } + } + + if (f == Cudd_Not(one) || f == zero) { + *length = DD_BIGGY; + return(Cudd_Not(one)); + } + /* From this point on, a path exists. */ + + do { + manager->reordered = 0; + + /* Initialize visited table. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + + /* Now get the length of the shortest path(s) from f to 1. */ + (void) getShortest(f, weight, support, visited); + + complement = Cudd_IsComplement(f); + + F = Cudd_Regular(f); + + if (!st_lookup(visited, F, &rootPair)) return(NULL); + + if (complement) { + cost = rootPair->neg; + } else { + cost = rootPair->pos; + } + + /* Recover an actual shortest path. */ + sol = getPath(manager,visited,f,weight,cost); + + st_foreach(visited, freePathPair, NULL); + st_free_table(visited); + + } while (manager->reordered == 1); + + *length = cost; + return(sol); + +} /* end of Cudd_ShortestPath */ + + +/**Function******************************************************************** + + Synopsis [Finds a largest cube in a DD.] + + Description [Finds a largest cube in a DD. f is the DD we want to + get the largest cube for. The problem is translated into the one of + finding a shortest path in f, when both THEN and ELSE arcs are assumed to + have unit length. This yields a largest cube in the disjoint cover + corresponding to the DD. Therefore, it is not necessarily the largest + implicant of f. Returns the largest cube as a BDD.] + + SideEffects [The number of literals of the cube is returned in the location + pointed by length if it is non-null.] + + SeeAlso [Cudd_ShortestPath] + +******************************************************************************/ +DdNode * +Cudd_LargestCube( + DdManager * manager, + DdNode * f, + int * length) +{ + register DdNode *F; + st_table *visited; + DdNode *sol; + cuddPathPair *rootPair; + int complement, cost; + + one = DD_ONE(manager); + zero = DD_ZERO(manager); + + if (f == Cudd_Not(one) || f == zero) { + if (length != NULL) { + *length = DD_BIGGY; + } + return(Cudd_Not(one)); + } + /* From this point on, a path exists. */ + + do { + manager->reordered = 0; + + /* Initialize visited table. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + + /* Now get the length of the shortest path(s) from f to 1. */ + (void) getLargest(f, visited); + + complement = Cudd_IsComplement(f); + + F = Cudd_Regular(f); + + if (!st_lookup(visited, F, &rootPair)) return(NULL); + + if (complement) { + cost = rootPair->neg; + } else { + cost = rootPair->pos; + } + + /* Recover an actual shortest path. */ + sol = getCube(manager,visited,f,cost); + + st_foreach(visited, freePathPair, NULL); + st_free_table(visited); + + } while (manager->reordered == 1); + + if (length != NULL) { + *length = cost; + } + return(sol); + +} /* end of Cudd_LargestCube */ + + +/**Function******************************************************************** + + Synopsis [Find the length of the shortest path(s) in a DD.] + + Description [Find the length of the shortest path(s) in a DD. f is + the DD we want to get the shortest path for; weight\[i\] is the + weight of the THEN edge coming from the node whose index is i. All + ELSE edges have 0 weight. Returns the length of the shortest + path(s) if such a path is found; a large number if the function is + identically 0, and CUDD_OUT_OF_MEM in case of failure.] + + SideEffects [None] + + SeeAlso [Cudd_ShortestPath] + +******************************************************************************/ +int +Cudd_ShortestLength( + DdManager * manager, + DdNode * f, + int * weight) +{ + register DdNode *F; + st_table *visited; + cuddPathPair *my_pair; + int complement, cost; + + one = DD_ONE(manager); + zero = DD_ZERO(manager); + + if (f == Cudd_Not(one) || f == zero) { + return(DD_BIGGY); + } + + /* From this point on, a path exists. */ + /* Initialize visited table and support. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + + /* Now get the length of the shortest path(s) from f to 1. */ + (void) getShortest(f, weight, NULL, visited); + + complement = Cudd_IsComplement(f); + + F = Cudd_Regular(f); + + if (!st_lookup(visited, F, &my_pair)) return(CUDD_OUT_OF_MEM); + + if (complement) { + cost = my_pair->neg; + } else { + cost = my_pair->pos; + } + + st_foreach(visited, freePathPair, NULL); + st_free_table(visited); + + return(cost); + +} /* end of Cudd_ShortestLength */ + + +/**Function******************************************************************** + + Synopsis [Determines whether a BDD is negative unate in a + variable.] + + Description [Determines whether the function represented by BDD f is + negative unate (monotonic decreasing) in variable i. Returns the + constant one is f is unate and the (logical) constant zero if it is not. + This function does not generate any new nodes.] + + SideEffects [None] + + SeeAlso [Cudd_Increasing] + +******************************************************************************/ +DdNode * +Cudd_Decreasing( + DdManager * dd, + DdNode * f, + int i) +{ + unsigned int topf, level; + DdNode *F, *fv, *fvn, *res; + DD_CTFP cacheOp; + + statLine(dd); +#ifdef DD_DEBUG + assert(0 <= i && i < dd->size); +#endif + + F = Cudd_Regular(f); + topf = cuddI(dd,F->index); + + /* Check terminal case. If topf > i, f does not depend on var. + ** Therefore, f is unate in i. + */ + level = (unsigned) dd->perm[i]; + if (topf > level) { + return(DD_ONE(dd)); + } + + /* From now on, f is not constant. */ + + /* Check cache. */ + cacheOp = (DD_CTFP) Cudd_Decreasing; + res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]); + if (res != NULL) { + return(res); + } + + /* Compute cofactors. */ + fv = cuddT(F); fvn = cuddE(F); + if (F != f) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + + if (topf == (unsigned) level) { + /* Special case: if fv is regular, fv(1,...,1) = 1; + ** If in addition fvn is complemented, fvn(1,...,1) = 0. + ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not + ** monotonic decreasing in i. + */ + if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) { + return(Cudd_Not(DD_ONE(dd))); + } + res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd)); + } else { + res = Cudd_Decreasing(dd,fv,i); + if (res == DD_ONE(dd)) { + res = Cudd_Decreasing(dd,fvn,i); + } + } + + cuddCacheInsert2(dd,cacheOp,f,dd->vars[i],res); + return(res); + +} /* end of Cudd_Decreasing */ + + +/**Function******************************************************************** + + Synopsis [Determines whether a BDD is positive unate in a + variable.] + + Description [Determines whether the function represented by BDD f is + positive unate (monotonic increasing) in variable i. It is based on + Cudd_Decreasing and the fact that f is monotonic increasing in i if + and only if its complement is monotonic decreasing in i.] + + SideEffects [None] + + SeeAlso [Cudd_Decreasing] + +******************************************************************************/ +DdNode * +Cudd_Increasing( + DdManager * dd, + DdNode * f, + int i) +{ + return(Cudd_Decreasing(dd,Cudd_Not(f),i)); + +} /* end of Cudd_Increasing */ + + +/**Function******************************************************************** + + Synopsis [Tells whether F and G are identical wherever D is 0.] + + Description [Tells whether F and G are identical wherever D is 0. F + and G are either two ADDs or two BDDs. D is either a 0-1 ADD or a + BDD. The function returns 1 if F and G are equivalent, and 0 + otherwise. No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_bddLeqUnless] + +******************************************************************************/ +int +Cudd_EquivDC( + DdManager * dd, + DdNode * F, + DdNode * G, + DdNode * D) +{ + DdNode *tmp, *One, *Gr, *Dr; + DdNode *Fv, *Fvn, *Gv, *Gvn, *Dv, *Dvn; + int res; + unsigned int flevel, glevel, dlevel, top; + + One = DD_ONE(dd); + + statLine(dd); + /* Check terminal cases. */ + if (D == One || F == G) return(1); + if (D == Cudd_Not(One) || D == DD_ZERO(dd) || F == Cudd_Not(G)) return(0); + + /* From now on, D is non-constant. */ + + /* Normalize call to increase cache efficiency. */ + if (F > G) { + tmp = F; + F = G; + G = tmp; + } + if (Cudd_IsComplement(F)) { + F = Cudd_Not(F); + G = Cudd_Not(G); + } + + /* From now on, F is regular. */ + + /* Check cache. */ + tmp = cuddCacheLookup(dd,DD_EQUIV_DC_TAG,F,G,D); + if (tmp != NULL) return(tmp == One); + + /* Find splitting variable. */ + flevel = cuddI(dd,F->index); + Gr = Cudd_Regular(G); + glevel = cuddI(dd,Gr->index); + top = ddMin(flevel,glevel); + Dr = Cudd_Regular(D); + dlevel = dd->perm[Dr->index]; + top = ddMin(top,dlevel); + + /* Compute cofactors. */ + if (top == flevel) { + Fv = cuddT(F); + Fvn = cuddE(F); + } else { + Fv = Fvn = F; + } + if (top == glevel) { + Gv = cuddT(Gr); + Gvn = cuddE(Gr); + if (G != Gr) { + Gv = Cudd_Not(Gv); + Gvn = Cudd_Not(Gvn); + } + } else { + Gv = Gvn = G; + } + if (top == dlevel) { + Dv = cuddT(Dr); + Dvn = cuddE(Dr); + if (D != Dr) { + Dv = Cudd_Not(Dv); + Dvn = Cudd_Not(Dvn); + } + } else { + Dv = Dvn = D; + } + + /* Solve recursively. */ + res = Cudd_EquivDC(dd,Fv,Gv,Dv); + if (res != 0) { + res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn); + } + cuddCacheInsert(dd,DD_EQUIV_DC_TAG,F,G,D,(res) ? One : Cudd_Not(One)); + + return(res); + +} /* end of Cudd_EquivDC */ + + +/**Function******************************************************************** + + Synopsis [Tells whether f is less than of equal to G unless D is 1.] + + Description [Tells whether f is less than of equal to G unless D is + 1. f, g, and D are BDDs. The function returns 1 if f is less than + of equal to G, and 0 otherwise. No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_EquivDC Cudd_bddLeq Cudd_bddIteConstant] + +******************************************************************************/ +int +Cudd_bddLeqUnless( + DdManager *dd, + DdNode *f, + DdNode *g, + DdNode *D) +{ + DdNode *tmp, *One, *F, *G; + DdNode *Ft, *Fe, *Gt, *Ge, *Dt, *De; + int res; + unsigned int flevel, glevel, dlevel, top; + + statLine(dd); + + One = DD_ONE(dd); + + /* Check terminal cases. */ + if (f == g || g == One || f == Cudd_Not(One) || D == One || + D == f || D == Cudd_Not(g)) return(1); + /* Check for two-operand cases. */ + if (D == Cudd_Not(One) || D == g || D == Cudd_Not(f)) + return(Cudd_bddLeq(dd,f,g)); + if (g == Cudd_Not(One) || g == Cudd_Not(f)) return(Cudd_bddLeq(dd,f,D)); + if (f == One) return(Cudd_bddLeq(dd,Cudd_Not(g),D)); + + /* From now on, f, g, and D are non-constant, distinct, and + ** non-complementary. */ + + /* Normalize call to increase cache efficiency. We rely on the + ** fact that f <= g unless D is equivalent to not(g) <= not(f) + ** unless D and to f <= D unless g. We make sure that D is + ** regular, and that at most one of f and g is complemented. We also + ** ensure that when two operands can be swapped, the one with the + ** lowest address comes first. */ + + if (Cudd_IsComplement(D)) { + if (Cudd_IsComplement(g)) { + /* Special case: if f is regular and g is complemented, + ** f(1,...,1) = 1 > 0 = g(1,...,1). If D(1,...,1) = 0, return 0. + */ + if (!Cudd_IsComplement(f)) return(0); + /* !g <= D unless !f or !D <= g unless !f */ + tmp = D; + D = Cudd_Not(f); + if (g < tmp) { + f = Cudd_Not(g); + g = tmp; + } else { + f = Cudd_Not(tmp); + } + } else { + if (Cudd_IsComplement(f)) { + /* !D <= !f unless g or !D <= g unless !f */ + tmp = f; + f = Cudd_Not(D); + if (tmp < g) { + D = g; + g = Cudd_Not(tmp); + } else { + D = Cudd_Not(tmp); + } + } else { + /* f <= D unless g or !D <= !f unless g */ + tmp = D; + D = g; + if (tmp < f) { + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } else { + g = tmp; + } + } + } + } else { + if (Cudd_IsComplement(g)) { + if (Cudd_IsComplement(f)) { + /* !g <= !f unless D or !g <= D unless !f */ + tmp = f; + f = Cudd_Not(g); + if (D < tmp) { + g = D; + D = Cudd_Not(tmp); + } else { + g = Cudd_Not(tmp); + } + } else { + /* f <= g unless D or !g <= !f unless D */ + if (g < f) { + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } + } + } else { + /* f <= g unless D or f <= D unless g */ + if (D < g) { + tmp = D; + D = g; + g = tmp; + } + } + } + + /* From now on, D is regular. */ + + /* Check cache. */ + tmp = cuddCacheLookup(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D); + if (tmp != NULL) return(tmp == One); + + /* Find splitting variable. */ + F = Cudd_Regular(f); + flevel = dd->perm[F->index]; + G = Cudd_Regular(g); + glevel = dd->perm[G->index]; + top = ddMin(flevel,glevel); + dlevel = dd->perm[D->index]; + top = ddMin(top,dlevel); + + /* Compute cofactors. */ + if (top == flevel) { + Ft = cuddT(F); + Fe = cuddE(F); + if (F != f) { + Ft = Cudd_Not(Ft); + Fe = Cudd_Not(Fe); + } + } else { + Ft = Fe = f; + } + if (top == glevel) { + Gt = cuddT(G); + Ge = cuddE(G); + if (G != g) { + Gt = Cudd_Not(Gt); + Ge = Cudd_Not(Ge); + } + } else { + Gt = Ge = g; + } + if (top == dlevel) { + Dt = cuddT(D); + De = cuddE(D); + } else { + Dt = De = D; + } + + /* Solve recursively. */ + res = Cudd_bddLeqUnless(dd,Ft,Gt,Dt); + if (res != 0) { + res = Cudd_bddLeqUnless(dd,Fe,Ge,De); + } + cuddCacheInsert(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D,Cudd_NotCond(One,!res)); + + return(res); + +} /* end of Cudd_bddLeqUnless */ + + +/**Function******************************************************************** + + Synopsis [Compares two ADDs for equality within tolerance.] + + Description [Compares two ADDs for equality within tolerance. Two + ADDs are reported to be equal if the maximum difference between them + (the sup norm of their difference) is less than or equal to the + tolerance parameter. Returns 1 if the two ADDs are equal (within + tolerance); 0 otherwise. If parameter pr is positive + the first failure is reported to the standard output.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_EqualSupNorm( + DdManager * dd /* manager */, + DdNode * f /* first ADD */, + DdNode * g /* second ADD */, + CUDD_VALUE_TYPE tolerance /* maximum allowed difference */, + int pr /* verbosity level */) +{ + DdNode *fv, *fvn, *gv, *gvn, *r; + unsigned int topf, topg; + + statLine(dd); + /* Check terminal cases. */ + if (f == g) return(1); + if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) { + if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) { + return(1); + } else { + if (pr>0) { + (void) fprintf(dd->out,"Offending nodes:\n"); + (void) fprintf(dd->out, + "f: address = %p\t value = %40.30f\n", + (void *) f, cuddV(f)); + (void) fprintf(dd->out, + "g: address = %p\t value = %40.30f\n", + (void *) g, cuddV(g)); + } + return(0); + } + } + + /* We only insert the result in the cache if the comparison is + ** successful. Therefore, if we hit we return 1. */ + r = cuddCacheLookup2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g); + if (r != NULL) { + return(1); + } + + /* Compute the cofactors and solve the recursive subproblems. */ + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + + if (topf <= topg) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;} + if (topg <= topf) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;} + + if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0); + if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0); + + cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g,DD_ONE(dd)); + + return(1); + +} /* end of Cudd_EqualSupNorm */ + + +/**Function******************************************************************** + + Synopsis [Expands cube to a prime implicant of f.] + + Description [Expands cube to a prime implicant of f. Returns the prime + if successful; NULL otherwise. In particular, NULL is returned if cube + is not a real cube or is not an implicant of f.] + + SideEffects [None] + + SeeAlso [Cudd_bddMaximallyExpand] + +******************************************************************************/ +DdNode * +Cudd_bddMakePrime( + DdManager *dd /* manager */, + DdNode *cube /* cube to be expanded */, + DdNode *f /* function of which the cube is to be made a prime */) +{ + DdNode *res; + + if (!Cudd_bddLeq(dd,cube,f)) return(NULL); + + do { + dd->reordered = 0; + res = cuddBddMakePrime(dd,cube,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddMakePrime */ + + +/**Function******************************************************************** + + Synopsis [Expands lb to prime implicants of (f and ub).] + + Description [Expands lb to all prime implicants of (f and ub) that contain lb. + Assumes that lb is contained in ub. Returns the disjunction of the primes if + lb is contained in f; returns the zero BDD if lb is not contained in f; + returns NULL in case of failure. In particular, NULL is returned if cube is + not a real cube or is not an implicant of f. Returning the disjunction of + all prime implicants works because the resulting function is unate.] + + SideEffects [None] + + SeeAlso [Cudd_bddMakePrime] + +******************************************************************************/ +DdNode * +Cudd_bddMaximallyExpand( + DdManager *dd /* manager */, + DdNode *lb /* cube to be expanded */, + DdNode *ub /* upper bound cube */, + DdNode *f /* function against which to expand */) +{ + DdNode *res; + + if (!Cudd_bddLeq(dd,lb,ub)) return(NULL); + + do { + dd->reordered = 0; + res = ddBddMaximallyExpand(dd,lb,ub,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddMaximallyExpand */ + + +/**Function******************************************************************** + + Synopsis [Find a largest prime of a unate function.] + + Description [Find a largest prime implicant of a unate function. + Returns the BDD for the prime if succesful; NULL otherwise. The behavior + is undefined if f is not unate. The third argument is used to determine + whether f is unate positive (increasing) or negative (decreasing) + in each of the variables in its support.] + + SideEffects [None] + + SeeAlso [Cudd_bddMaximallyExpand] + +******************************************************************************/ +DdNode * +Cudd_bddLargestPrimeUnate( + DdManager *dd /* manager */, + DdNode *f /* unate function */, + DdNode *phaseBdd /* cube of the phases */) +{ + DdNode *res; + int *phases; + int retval; + st_table *table; + + /* Extract phase vector for quick access. */ + phases = ALLOC(int, dd->size); + if (phases == NULL) return(NULL); + retval = Cudd_BddToCubeArray(dd, phaseBdd, phases); + if (retval == 0) { + FREE(phases); + return(NULL); + } + do { + dd->reordered = 0; + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) { + FREE(phases); + return(NULL); + } + (void) ddBddShortestPathUnate(dd, f, phases, table); + res = ddGetLargestCubeUnate(dd, f, phases, table); + st_free_table(table); + } while (dd->reordered == 1); + + FREE(phases); + return(res); + +} /* end of Cudd_bddLargestPrimeUnate */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddMakePrime.] + + Description [Performs the recursive step of Cudd_bddMakePrime. + Returns the prime if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddBddMakePrime( + DdManager *dd /* manager */, + DdNode *cube /* cube to be expanded */, + DdNode *f /* function of which the cube is to be made a prime */) +{ + DdNode *scan; + DdNode *t, *e; + DdNode *res = cube; + DdNode *zero = Cudd_Not(DD_ONE(dd)); + + Cudd_Ref(res); + scan = cube; + while (!Cudd_IsConstant(scan)) { + DdNode *reg = Cudd_Regular(scan); + DdNode *var = dd->vars[reg->index]; + DdNode *expanded = Cudd_bddExistAbstract(dd,res,var); + if (expanded == NULL) { + Cudd_RecursiveDeref(dd,res); + return(NULL); + } + Cudd_Ref(expanded); + if (Cudd_bddLeq(dd,expanded,f)) { + Cudd_RecursiveDeref(dd,res); + res = expanded; + } else { + Cudd_RecursiveDeref(dd,expanded); + } + cuddGetBranches(scan,&t,&e); + if (t == zero) { + scan = e; + } else if (e == zero) { + scan = t; + } else { + Cudd_RecursiveDeref(dd,res); + return(NULL); /* cube is not a cube */ + } + } + + if (scan == DD_ONE(dd)) { + Cudd_Deref(res); + return(res); + } else { + Cudd_RecursiveDeref(dd,res); + return(NULL); + } + +} /* end of cuddBddMakePrime */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Frees the entries of the visited symbol table.] + + Description [Frees the entries of the visited symbol table. Returns + ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +freePathPair( + char * key, + char * value, + char * arg) +{ + cuddPathPair *pair; + + pair = (cuddPathPair *) value; + FREE(pair); + return(ST_CONTINUE); + +} /* end of freePathPair */ + + +/**Function******************************************************************** + + Synopsis [Finds the length of the shortest path(s) in a DD.] + + Description [Finds the length of the shortest path(s) in a DD. + Uses a local symbol table to store the lengths for each + node. Only the lengths for the regular nodes are entered in the table, + because those for the complement nodes are simply obtained by swapping + the two lenghts. + Returns a pair of lengths: the length of the shortest path to 1; + and the length of the shortest path to 0. This is done so as to take + complement arcs into account.] + + SideEffects [Accumulates the support of the DD in support.] + + SeeAlso [] + +******************************************************************************/ +static cuddPathPair +getShortest( + DdNode * root, + int * cost, + int * support, + st_table * visited) +{ + cuddPathPair *my_pair, res_pair, pair_T, pair_E; + DdNode *my_root, *T, *E; + int weight; + + my_root = Cudd_Regular(root); + + if (st_lookup(visited, my_root, &my_pair)) { + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); + } + + /* In the case of a BDD the following test is equivalent to + ** testing whether the BDD is the constant 1. This formulation, + ** however, works for ADDs as well, by assuming the usual + ** dichotomy of 0 and != 0. + */ + if (cuddIsConstant(my_root)) { + if (my_root != zero) { + res_pair.pos = 0; + res_pair.neg = DD_BIGGY; + } else { + res_pair.pos = DD_BIGGY; + res_pair.neg = 0; + } + } else { + T = cuddT(my_root); + E = cuddE(my_root); + + pair_T = getShortest(T, cost, support, visited); + pair_E = getShortest(E, cost, support, visited); + weight = WEIGHT(cost, my_root->index); + res_pair.pos = ddMin(pair_T.pos+weight, pair_E.pos); + res_pair.neg = ddMin(pair_T.neg+weight, pair_E.neg); + + /* Update support. */ + if (support != NULL) { + support[my_root->index] = 1; + } + } + + my_pair = ALLOC(cuddPathPair, 1); + if (my_pair == NULL) { + if (Cudd_IsComplement(root)) { + int tmp = res_pair.pos; + res_pair.pos = res_pair.neg; + res_pair.neg = tmp; + } + return(res_pair); + } + my_pair->pos = res_pair.pos; + my_pair->neg = res_pair.neg; + + st_insert(visited, (char *)my_root, (char *)my_pair); + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); + +} /* end of getShortest */ + + +/**Function******************************************************************** + + Synopsis [Build a BDD for a shortest path of f.] + + Description [Build a BDD for a shortest path of f. + Given the minimum length from the root, and the minimum + lengths for each node (in visited), apply triangulation at each node. + Of the two children of each node on a shortest path, at least one is + on a shortest path. In case of ties the procedure chooses the THEN + children. + Returns a pointer to the cube BDD representing the path if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +getPath( + DdManager * manager, + st_table * visited, + DdNode * f, + int * weight, + int cost) +{ + DdNode *sol, *tmp; + DdNode *my_dd, *T, *E; + cuddPathPair *T_pair, *E_pair; + int Tcost, Ecost; + int complement; + + my_dd = Cudd_Regular(f); + complement = Cudd_IsComplement(f); + + sol = one; + cuddRef(sol); + + while (!cuddIsConstant(my_dd)) { + Tcost = cost - WEIGHT(weight, my_dd->index); + Ecost = cost; + + T = cuddT(my_dd); + E = cuddE(my_dd); + + if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} + + st_lookup(visited, Cudd_Regular(T), &T_pair); + if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || + (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { + tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + + complement = Cudd_IsComplement(T); + my_dd = Cudd_Regular(T); + cost = Tcost; + continue; + } + st_lookup(visited, Cudd_Regular(E), &E_pair); + if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || + (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { + tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + complement = Cudd_IsComplement(E); + my_dd = Cudd_Regular(E); + cost = Ecost; + continue; + } + (void) fprintf(manager->err,"We shouldn't be here!!\n"); + manager->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + cuddDeref(sol); + return(sol); + +} /* end of getPath */ + + +/**Function******************************************************************** + + Synopsis [Finds the size of the largest cube(s) in a DD.] + + Description [Finds the size of the largest cube(s) in a DD. + This problem is translated into finding the shortest paths from a node + when both THEN and ELSE arcs have unit lengths. + Uses a local symbol table to store the lengths for each + node. Only the lengths for the regular nodes are entered in the table, + because those for the complement nodes are simply obtained by swapping + the two lenghts. + Returns a pair of lengths: the length of the shortest path to 1; + and the length of the shortest path to 0. This is done so as to take + complement arcs into account.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static cuddPathPair +getLargest( + DdNode * root, + st_table * visited) +{ + cuddPathPair *my_pair, res_pair, pair_T, pair_E; + DdNode *my_root, *T, *E; + + my_root = Cudd_Regular(root); + + if (st_lookup(visited, my_root, &my_pair)) { + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); + } + + /* In the case of a BDD the following test is equivalent to + ** testing whether the BDD is the constant 1. This formulation, + ** however, works for ADDs as well, by assuming the usual + ** dichotomy of 0 and != 0. + */ + if (cuddIsConstant(my_root)) { + if (my_root != zero) { + res_pair.pos = 0; + res_pair.neg = DD_BIGGY; + } else { + res_pair.pos = DD_BIGGY; + res_pair.neg = 0; + } + } else { + T = cuddT(my_root); + E = cuddE(my_root); + + pair_T = getLargest(T, visited); + pair_E = getLargest(E, visited); + res_pair.pos = ddMin(pair_T.pos, pair_E.pos) + 1; + res_pair.neg = ddMin(pair_T.neg, pair_E.neg) + 1; + } + + my_pair = ALLOC(cuddPathPair, 1); + if (my_pair == NULL) { /* simply do not cache this result */ + if (Cudd_IsComplement(root)) { + int tmp = res_pair.pos; + res_pair.pos = res_pair.neg; + res_pair.neg = tmp; + } + return(res_pair); + } + my_pair->pos = res_pair.pos; + my_pair->neg = res_pair.neg; + + /* Caching may fail without affecting correctness. */ + st_insert(visited, (char *)my_root, (char *)my_pair); + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); + +} /* end of getLargest */ + + +/**Function******************************************************************** + + Synopsis [Build a BDD for a largest cube of f.] + + Description [Build a BDD for a largest cube of f. + Given the minimum length from the root, and the minimum + lengths for each node (in visited), apply triangulation at each node. + Of the two children of each node on a shortest path, at least one is + on a shortest path. In case of ties the procedure chooses the THEN + children. + Returns a pointer to the cube BDD representing the path if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +getCube( + DdManager * manager, + st_table * visited, + DdNode * f, + int cost) +{ + DdNode *sol, *tmp; + DdNode *my_dd, *T, *E; + cuddPathPair *T_pair, *E_pair; + int Tcost, Ecost; + int complement; + + my_dd = Cudd_Regular(f); + complement = Cudd_IsComplement(f); + + sol = one; + cuddRef(sol); + + while (!cuddIsConstant(my_dd)) { + Tcost = cost - 1; + Ecost = cost - 1; + + T = cuddT(my_dd); + E = cuddE(my_dd); + + if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} + + if (!st_lookup(visited, Cudd_Regular(T), &T_pair)) return(NULL); + if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || + (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { + tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + + complement = Cudd_IsComplement(T); + my_dd = Cudd_Regular(T); + cost = Tcost; + continue; + } + if (!st_lookup(visited, Cudd_Regular(E), &E_pair)) return(NULL); + if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || + (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { + tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + complement = Cudd_IsComplement(E); + my_dd = Cudd_Regular(E); + cost = Ecost; + continue; + } + (void) fprintf(manager->err,"We shouldn't be here!\n"); + manager->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + cuddDeref(sol); + return(sol); + +} /* end of getCube */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddMaximallyExpand.] + + Description [Performs the recursive step of Cudd_bddMaximallyExpand. + Returns set of primes or zero BDD if successful; NULL otherwise. On entry + to this function, ub and lb should be different from the zero BDD. The + function then maintains this invariant.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +ddBddMaximallyExpand( + DdManager *dd /* manager */, + DdNode *lb /* cube to be expanded */, + DdNode *ub /* upper bound cube */, + DdNode *f /* function against which to expand */) +{ + DdNode *one, *zero, *lbv, *lbvn, *lbnx, *ubv, *ubvn, *fv, *fvn, *res; + DdNode *F, *UB, *LB, *t, *e; + unsigned int top, toplb, topub, topf, index; + + statLine(dd); + /* Terminal cases. */ + one = DD_ONE(dd); + zero = Cudd_Not(one); + assert(ub != zero && lb != zero); + /** There are three major terminal cases in theory: + ** ub -> f : return ub + ** lb == f : return lb + ** not(lb -> f): return zero + ** Only the second case can be checked exactly in constant time. + ** For the others, we check for sufficient conditions. + */ + if (ub == f || f == one) return(ub); + if (lb == f) return(lb); + if (f == zero || ub == Cudd_Not(f) || lb == one || lb == Cudd_Not(f)) + return(zero); + if (!Cudd_IsComplement(lb) && Cudd_IsComplement(f)) return(zero); + + /* Here lb and f are not constant. */ + + /* Check cache. Since lb and ub are cubes, their local reference counts + ** are always 1. Hence, we only check the reference count of f. + */ + F = Cudd_Regular(f); + if (F->ref != 1) { + DdNode *tmp = cuddCacheLookup(dd, DD_BDD_MAX_EXP_TAG, lb, ub, f); + if (tmp != NULL) { + return(tmp); + } + } + + /* Compute cofactors. For lb we use the non-zero one in + ** both branches of the recursion. + */ + LB = Cudd_Regular(lb); + UB = Cudd_Regular(ub); + topf = dd->perm[F->index]; + toplb = dd->perm[LB->index]; + topub = (ub == one) ? CUDD_CONST_INDEX : dd->perm[UB->index]; + assert(toplb <= topub); + top = ddMin(topf,toplb); + if (toplb == top) { + index = LB->index; + lbv = cuddT(LB); + lbvn = cuddE(LB); + if (lb != LB) { + lbv = Cudd_Not(lbv); + lbvn = Cudd_Not(lbvn); + } + if (lbv == zero) { + lbnx = lbvn; + } else { + lbnx = lbv; + } + } else { + index = F->index; + lbnx = lbv = lbvn = lb; + } + if (topub == top) { + ubv = cuddT(UB); + ubvn = cuddE(UB); + if (ub != UB) { + ubv = Cudd_Not(ubv); + ubvn = Cudd_Not(ubvn); + } + } else { + ubv = ubvn = ub; + } + if (topf == top) { + fv = cuddT(F); + fvn = cuddE(F); + if (f != F) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + } else { + fv = fvn = f; + } + + /* Recursive calls. */ + if (ubv != zero) { + t = ddBddMaximallyExpand(dd, lbnx, ubv, fv); + if (t == NULL) return(NULL); + } else { + assert(topub == toplb && topub == top && lbv == zero); + t = zero; + } + cuddRef(t); + + /* If the top variable appears only in lb, the positive and negative + ** cofactors of each operand are the same. We want to avoid a + ** needless recursive call, which would force us to give up the + ** cache optimization trick based on reference counts. + */ + if (ubv == ubvn && fv == fvn) { + res = t; + } else { + if (ubvn != zero) { + e = ddBddMaximallyExpand(dd, lbnx, ubvn, fvn); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } + } else { + assert(topub == toplb && topub == top && lbvn == zero); + e = zero; + } + + if (t == e) { + res = t; + } else { + cuddRef(e); + + if (toplb == top) { + if (lbv == zero) { + /* Top variable appears in negative phase. */ + if (t != one) { + DdNode *newT; + if (Cudd_IsComplement(t)) { + newT = cuddUniqueInter(dd, index, Cudd_Not(t), zero); + if (newT == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + newT = Cudd_Not(newT); + } else { + newT = cuddUniqueInter(dd, index, t, one); + if (newT == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + } + cuddRef(newT); + cuddDeref(t); + t = newT; + } + } else if (lbvn == zero) { + /* Top variable appears in positive phase. */ + if (e != one) { + DdNode *newE; + newE = cuddUniqueInter(dd, index, one, e); + if (newE == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + cuddRef(newE); + cuddDeref(e); + e = newE; + } + } else { + /* Not a cube. */ + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + } + + /* Combine results. */ + res = cuddBddAndRecur(dd, t, e); + if (res == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + } + } + + /* Cache result and return. */ + if (F->ref != 1) { + cuddCacheInsert(dd, DD_BDD_MAX_EXP_TAG, lb, ub, f, res); + } + cuddDeref(res); + return(res); + +} /* end of ddBddMaximallyExpand */ + + +/**Function******************************************************************** + + Synopsis [Performs shortest path computation on a unate function.] + + Description [Performs shortest path computation on a unate function. + Returns the length of the shortest path to one if successful; + CUDD_OUT_OF_MEM otherwise. This function is based on the observation + that in the BDD of a unate function no node except the constant is + reachable from the root via paths of different parity.] + + SideEffects [None] + + SeeAlso [getShortest] + +******************************************************************************/ +static int +ddBddShortestPathUnate( + DdManager *dd, + DdNode *f, + int *phases, + st_table *table) +{ + int positive, l, lT, lE; + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + DdNode *F, *fv, *fvn; + + if (st_lookup_int(table, f, &l)) { + return(l); + } + if (f == one) { + l = 0; + } else if (f == zero) { + l = DD_BIGGY; + } else { + F = Cudd_Regular(f); + fv = cuddT(F); + fvn = cuddE(F); + if (f != F) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + lT = ddBddShortestPathUnate(dd, fv, phases, table); + lE = ddBddShortestPathUnate(dd, fvn, phases, table); + positive = phases[F->index]; + l = positive ? ddMin(lT+1, lE) : ddMin(lT, lE+1); + } + if (st_insert(table, f, (void *)(ptrint) l) == ST_OUT_OF_MEM) { + return(CUDD_OUT_OF_MEM); + } + return(l); + +} /* end of ddShortestPathUnate */ + + +/**Function******************************************************************** + + Synopsis [Extracts largest prime of a unate function.] + + Description [Extracts largest prime of a unate function. Returns the BDD of + the prime if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [getPath] + +******************************************************************************/ +static DdNode * +ddGetLargestCubeUnate( + DdManager *dd, + DdNode *f, + int *phases, + st_table *table) +{ + DdNode *res, *scan; + DdNode *one = DD_ONE(dd); + int cost; + + res = one; + cuddRef(res); + scan = f; + st_lookup_int(table, scan, &cost); + + while (!Cudd_IsConstant(scan)) { + int Pcost, Ncost, Tcost; + DdNode *tmp, *T, *E; + DdNode *rscan = Cudd_Regular(scan); + int index = rscan->index; + assert(phases[index] == 0 || phases[index] == 1); + int positive = phases[index] == 1; + Pcost = positive ? cost - 1 : cost; + Ncost = positive ? cost : cost - 1; + T = cuddT(rscan); + E = cuddE(rscan); + if (rscan != scan) { + T = Cudd_Not(T); + E = Cudd_Not(E); + } + tmp = res; + st_lookup_int(table, T, &Tcost); + if (Tcost == Pcost) { + cost = Pcost; + scan = T; + if (positive) { + tmp = cuddBddAndRecur(dd, dd->vars[index], res); + } + } else { + cost = Ncost; + scan = E; + if (!positive) { + tmp = cuddBddAndRecur(dd, Cudd_Not(dd->vars[index]), res); + } + } + if (tmp == NULL) { + Cudd_IterDerefBdd(dd, res); + return(NULL); + } + cuddRef(tmp); + Cudd_IterDerefBdd(dd, res); + res = tmp; + } + + cuddDeref(res); + return(res); + +} /* end of ddGetLargestCubeUnate */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSign.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSign.c new file mode 100644 index 000000000..60520697a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSign.c @@ -0,0 +1,318 @@ +/**CFile*********************************************************************** + + FileName [cuddSign.c] + + PackageName [cudd] + + Synopsis [Computation of signatures.] + + Description [External procedures included in this module: +
                +
              • Cudd_CofMinterm(); +
              + Static procedures included in this module: +
                +
              • ddCofMintermAux() +
              + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSign.c,v 1.24 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int size; + +#ifdef DD_STATS +static int num_calls; /* should equal 2n-1 (n is the # of nodes) */ +static int table_mem; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static double * ddCofMintermAux (DdManager *dd, DdNode *node, st_table *table); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Computes the fraction of minterms in the on-set of all the + positive cofactors of a BDD or ADD.] + + Description [Computes the fraction of minterms in the on-set of all + the positive cofactors of DD. Returns the pointer to an array of + doubles if successful; NULL otherwise. The array has as many + positions as there are BDD variables in the manager plus one. The + last position of the array contains the fraction of the minterms in + the ON-set of the function represented by the BDD or ADD. The other + positions of the array hold the variable signatures.] + + SideEffects [None] + +******************************************************************************/ +double * +Cudd_CofMinterm( + DdManager * dd, + DdNode * node) +{ + st_table *table; + double *values; + double *result = NULL; + int i, firstLevel; + +#ifdef DD_STATS + unsigned long startTime; + startTime = util_cpu_time(); + num_calls = 0; + table_mem = sizeof(st_table); +#endif + + table = st_init_table(st_ptrcmp, st_ptrhash); + if (table == NULL) { + (void) fprintf(dd->err, + "out-of-memory, couldn't measure DD cofactors.\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + size = dd->size; + values = ddCofMintermAux(dd, node, table); + if (values != NULL) { + result = ALLOC(double,size + 1); + if (result != NULL) { +#ifdef DD_STATS + table_mem += (size + 1) * sizeof(double); +#endif + if (Cudd_IsConstant(node)) + firstLevel = 1; + else + firstLevel = cuddI(dd,Cudd_Regular(node)->index); + for (i = 0; i < size; i++) { + if (i >= cuddI(dd,Cudd_Regular(node)->index)) { + result[dd->invperm[i]] = values[i - firstLevel]; + } else { + result[dd->invperm[i]] = values[size - firstLevel]; + } + } + result[size] = values[size - firstLevel]; + } else { + dd->errorCode = CUDD_MEMORY_OUT; + } + } + +#ifdef DD_STATS + table_mem += table->num_bins * sizeof(st_table_entry *); +#endif + if (Cudd_Regular(node)->ref == 1) FREE(values); + st_foreach(table, cuddStCountfree, NULL); + st_free_table(table); +#ifdef DD_STATS + (void) fprintf(dd->out,"Number of calls: %d\tTable memory: %d bytes\n", + num_calls, table_mem); + (void) fprintf(dd->out,"Time to compute measures: %s\n", + util_print_time(util_cpu_time() - startTime)); +#endif + if (result == NULL) { + (void) fprintf(dd->out, + "out-of-memory, couldn't measure DD cofactors.\n"); + dd->errorCode = CUDD_MEMORY_OUT; + } + return(result); + +} /* end of Cudd_CofMinterm */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Recursive Step for Cudd_CofMinterm function.] + + Description [Traverses the DD node and computes the fraction of + minterms in the on-set of all positive cofactors simultaneously. + It allocates an array with two more entries than there are + variables below the one labeling the node. One extra entry (the + first in the array) is for the variable labeling the node. The other + entry (the last one in the array) holds the fraction of minterms of + the function rooted at node. Each other entry holds the value for + one cofactor. The array is put in a symbol table, to avoid repeated + computation, and its address is returned by the procedure, for use + by the caller. Returns a pointer to the array of cofactor measures.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double * +ddCofMintermAux( + DdManager * dd, + DdNode * node, + st_table * table) +{ + DdNode *N; /* regular version of node */ + DdNode *Nv, *Nnv; + double *values; + double *valuesT, *valuesE; + int i; + int localSize, localSizeT, localSizeE; + double vT, vE; + + statLine(dd); +#ifdef DD_STATS + num_calls++; +#endif + + if (st_lookup(table, node, &values)) { + return(values); + } + + N = Cudd_Regular(node); + if (cuddIsConstant(N)) { + localSize = 1; + } else { + localSize = size - cuddI(dd,N->index) + 1; + } + values = ALLOC(double, localSize); + if (values == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + if (cuddIsConstant(N)) { + if (node == DD_ZERO(dd) || node == Cudd_Not(DD_ONE(dd))) { + values[0] = 0.0; + } else { + values[0] = 1.0; + } + } else { + Nv = Cudd_NotCond(cuddT(N),N!=node); + Nnv = Cudd_NotCond(cuddE(N),N!=node); + + valuesT = ddCofMintermAux(dd, Nv, table); + if (valuesT == NULL) return(NULL); + valuesE = ddCofMintermAux(dd, Nnv, table); + if (valuesE == NULL) return(NULL); + + if (Cudd_IsConstant(Nv)) { + localSizeT = 1; + } else { + localSizeT = size - cuddI(dd,Cudd_Regular(Nv)->index) + 1; + } + if (Cudd_IsConstant(Nnv)) { + localSizeE = 1; + } else { + localSizeE = size - cuddI(dd,Cudd_Regular(Nnv)->index) + 1; + } + values[0] = valuesT[localSizeT - 1]; + for (i = 1; i < localSize; i++) { + if (i >= cuddI(dd,Cudd_Regular(Nv)->index) - cuddI(dd,N->index)) { + vT = valuesT[i - cuddI(dd,Cudd_Regular(Nv)->index) + + cuddI(dd,N->index)]; + } else { + vT = valuesT[localSizeT - 1]; + } + if (i >= cuddI(dd,Cudd_Regular(Nnv)->index) - cuddI(dd,N->index)) { + vE = valuesE[i - cuddI(dd,Cudd_Regular(Nnv)->index) + + cuddI(dd,N->index)]; + } else { + vE = valuesE[localSizeE - 1]; + } + values[i] = (vT + vE) / 2.0; + } + if (Cudd_Regular(Nv)->ref == 1) FREE(valuesT); + if (Cudd_Regular(Nnv)->ref == 1) FREE(valuesE); + } + + if (N->ref > 1) { + if (st_add_direct(table, (char *) node, (char *) values) == ST_OUT_OF_MEM) { + FREE(values); + return(NULL); + } +#ifdef DD_STATS + table_mem += localSize * sizeof(double) + sizeof(st_table_entry); +#endif + } + return(values); + +} /* end of ddCofMintermAux */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSolve.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSolve.c new file mode 100644 index 000000000..e97779d8e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSolve.c @@ -0,0 +1,366 @@ +/**CFile*********************************************************************** + + FileName [cuddSolve.c] + + PackageName [cudd] + + Synopsis [Boolean equation solver and related functions.] + + Description [External functions included in this modoule: +
                +
              • Cudd_SolveEqn() +
              • Cudd_VerifySol() +
              + Internal functions included in this module: +
                +
              • cuddSolveEqnRecur() +
              • cuddVerifySol() +
              ] + + SeeAlso [] + + Author [Balakrishna Kumthekar] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSolve.c,v 1.13 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the solution of F(x,y) = 0.] + + Description [Implements the solution for F(x,y) = 0. The return + value is the consistency condition. The y variables are the unknowns + and the remaining variables are the parameters. Returns the + consistency condition if successful; NULL otherwise. Cudd_SolveEqn + allocates an array and fills it with the indices of the + unknowns. This array is used by Cudd_VerifySol.] + + SideEffects [The solution is returned in G; the indices of the y + variables are returned in yIndex.] + + SeeAlso [Cudd_VerifySol] + +******************************************************************************/ +DdNode * +Cudd_SolveEqn( + DdManager * bdd, + DdNode * F /* the left-hand side of the equation */, + DdNode * Y /* the cube of the y variables */, + DdNode ** G /* the array of solutions (return parameter) */, + int ** yIndex /* index of y variables */, + int n /* numbers of unknowns */) +{ + DdNode *res; + int *temp; + + *yIndex = temp = ALLOC(int, n); + if (temp == NULL) { + bdd->errorCode = CUDD_MEMORY_OUT; + (void) fprintf(bdd->out, + "Cudd_SolveEqn: Out of memory for yIndex\n"); + return(NULL); + } + + do { + bdd->reordered = 0; + res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0); + } while (bdd->reordered == 1); + + return(res); + +} /* end of Cudd_SolveEqn */ + + +/**Function******************************************************************** + + Synopsis [Checks the solution of F(x,y) = 0.] + + Description [Checks the solution of F(x,y) = 0. This procedure + substitutes the solution components for the unknowns of F and returns + the resulting BDD for F.] + + SideEffects [Frees the memory pointed by yIndex.] + + SeeAlso [Cudd_SolveEqn] + +******************************************************************************/ +DdNode * +Cudd_VerifySol( + DdManager * bdd, + DdNode * F /* the left-hand side of the equation */, + DdNode ** G /* the array of solutions */, + int * yIndex /* index of y variables */, + int n /* numbers of unknowns */) +{ + DdNode *res; + + do { + bdd->reordered = 0; + res = cuddVerifySol(bdd, F, G, yIndex, n); + } while (bdd->reordered == 1); + + FREE(yIndex); + + return(res); + +} /* end of Cudd_VerifySol */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_SolveEqn.] + + Description [Implements the recursive step of Cudd_SolveEqn. + Returns NULL if the intermediate solution blows up + or reordering occurs. The parametric solutions are + stored in the array G.] + + SideEffects [none] + + SeeAlso [Cudd_SolveEqn, Cudd_VerifySol] + +******************************************************************************/ +DdNode * +cuddSolveEqnRecur( + DdManager * bdd, + DdNode * F /* the left-hand side of the equation */, + DdNode * Y /* the cube of remaining y variables */, + DdNode ** G /* the array of solutions */, + int n /* number of unknowns */, + int * yIndex /* array holding the y variable indices */, + int i /* level of recursion */) +{ + DdNode *Fn, *Fm1, *Fv, *Fvbar, *T, *w, *nextY, *one; + DdNodePtr *variables; + + int j; + + statLine(bdd); + variables = bdd->vars; + one = DD_ONE(bdd); + + /* Base condition. */ + if (Y == one) { + return F; + } + + /* Cofactor of Y. */ + yIndex[i] = Y->index; + nextY = Cudd_T(Y); + + /* Universal abstraction of F with respect to the top variable index. */ + Fm1 = cuddBddExistAbstractRecur(bdd, Cudd_Not(F), variables[yIndex[i]]); + if (Fm1) { + Fm1 = Cudd_Not(Fm1); + cuddRef(Fm1); + } else { + return(NULL); + } + + Fn = cuddSolveEqnRecur(bdd, Fm1, nextY, G, n, yIndex, i+1); + if (Fn) { + cuddRef(Fn); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + return(NULL); + } + + Fv = cuddCofactorRecur(bdd, F, variables[yIndex[i]]); + if (Fv) { + cuddRef(Fv); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + return(NULL); + } + + Fvbar = cuddCofactorRecur(bdd, F, Cudd_Not(variables[yIndex[i]])); + if (Fvbar) { + cuddRef(Fvbar); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + return(NULL); + } + + /* Build i-th component of the solution. */ + w = cuddBddIteRecur(bdd, variables[yIndex[i]], Cudd_Not(Fv), Fvbar); + if (w) { + cuddRef(w); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + Cudd_RecursiveDeref(bdd, Fvbar); + return(NULL); + } + + T = cuddBddRestrictRecur(bdd, w, Cudd_Not(Fm1)); + if(T) { + cuddRef(T); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + Cudd_RecursiveDeref(bdd, Fvbar); + Cudd_RecursiveDeref(bdd, w); + return(NULL); + } + + Cudd_RecursiveDeref(bdd,Fm1); + Cudd_RecursiveDeref(bdd,w); + Cudd_RecursiveDeref(bdd,Fv); + Cudd_RecursiveDeref(bdd,Fvbar); + + /* Substitute components of solution already found into solution. */ + for (j = n-1; j > i; j--) { + w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]); + if(w) { + cuddRef(w); + } else { + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, T); + return(NULL); + } + Cudd_RecursiveDeref(bdd,T); + T = w; + } + G[i] = T; + + Cudd_Deref(Fn); + + return(Fn); + +} /* end of cuddSolveEqnRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_VerifySol. ] + + Description [] + + SideEffects [none] + + SeeAlso [Cudd_VerifySol] + +******************************************************************************/ +DdNode * +cuddVerifySol( + DdManager * bdd, + DdNode * F /* the left-hand side of the equation */, + DdNode ** G /* the array of solutions */, + int * yIndex /* array holding the y variable indices */, + int n /* number of unknowns */) +{ + DdNode *w, *R; + + int j; + + R = F; + cuddRef(R); + for(j = n - 1; j >= 0; j--) { + w = Cudd_bddCompose(bdd, R, G[j], yIndex[j]); + if (w) { + cuddRef(w); + } else { + return(NULL); + } + Cudd_RecursiveDeref(bdd,R); + R = w; + } + + cuddDeref(R); + + return(R); + +} /* end of cuddVerifySol */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSplit.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSplit.c new file mode 100644 index 000000000..11fe86267 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSplit.c @@ -0,0 +1,686 @@ +/**CFile*********************************************************************** + + FileName [cuddSplit.c] + + PackageName [cudd] + + Synopsis [Returns a subset of minterms from a boolean function.] + + Description [External functions included in this modoule: +
                +
              • Cudd_SplitSet() +
              + Internal functions included in this module: +
                +
              • cuddSplitSetRecur() + + Static functions included in this module: +
                  +
                • selectMintermsFromUniverse() +
                • mintermsFromUniverse() +
                • bddAnnotateMintermCount() +
                ] + + SeeAlso [] + + Author [Balakrishna Kumthekar] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * selectMintermsFromUniverse (DdManager *manager, int *varSeen, double n); +static DdNode * mintermsFromUniverse (DdManager *manager, DdNode **vars, int numVars, double n, int index); +static double bddAnnotateMintermCount (DdManager *manager, DdNode *node, double max, st_table *table); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns m minterms from a BDD.] + + Description [Returns m minterms from a BDD whose + support has n variables at most. The procedure tries + to create as few extra nodes as possible. The function represented + by S depends on at most n of the variables + in xVars. Returns a BDD with m minterms + of the on-set of S if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_SplitSet( + DdManager * manager, + DdNode * S, + DdNode ** xVars, + int n, + double m) +{ + DdNode *result; + DdNode *zero, *one; + double max, num; + st_table *mtable; + int *varSeen; + int i,index, size; + + size = manager->size; + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Trivial cases. */ + if (m == 0.0) { + return(zero); + } + if (S == zero) { + return(NULL); + } + + max = pow(2.0,(double)n); + if (m > max) + return(NULL); + + do { + manager->reordered = 0; + /* varSeen is used to mark the variables that are encountered + ** while traversing the BDD S. + */ + varSeen = ALLOC(int, size); + if (varSeen == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + varSeen[i] = -1; + } + for (i = 0; i < n; i++) { + index = (xVars[i])->index; + varSeen[manager->invperm[index]] = 0; + } + + if (S == one) { + if (m == max) { + FREE(varSeen); + return(S); + } + result = selectMintermsFromUniverse(manager,varSeen,m); + if (result) + cuddRef(result); + FREE(varSeen); + } else { + mtable = st_init_table(st_ptrcmp,st_ptrhash); + if (mtable == NULL) { + (void) fprintf(manager->out, + "Cudd_SplitSet: out-of-memory.\n"); + FREE(varSeen); + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + /* The nodes of BDD S are annotated by the number of minterms + ** in their onset. The node and the number of minterms in its + ** onset are stored in mtable. + */ + num = bddAnnotateMintermCount(manager,S,max,mtable); + if (m == num) { + st_foreach(mtable,cuddStCountfree,NIL(char)); + st_free_table(mtable); + FREE(varSeen); + return(S); + } + + result = cuddSplitSetRecur(manager,mtable,varSeen,S,m,max,0); + if (result) + cuddRef(result); + st_foreach(mtable,cuddStCountfree,NULL); + st_free_table(mtable); + FREE(varSeen); + } + } while (manager->reordered == 1); + + cuddDeref(result); + return(result); + +} /* end of Cudd_SplitSet */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_SplitSet.] + + Description [Implements the recursive step of Cudd_SplitSet. The + procedure recursively traverses the BDD and checks to see if any + node satisfies the minterm requirements as specified by 'n'. At any + node X, n is compared to the number of minterms in the onset of X's + children. If either of the child nodes have exactly n minterms, then + that node is returned; else, if n is greater than the onset of one + of the child nodes, that node is retained and the difference in the + number of minterms is extracted from the other child. In case n + minterms can be extracted from constant 1, the algorithm returns the + result with at most log(n) nodes.] + + SideEffects [The array 'varSeen' is updated at every recursive call + to set the variables traversed by the procedure.] + + SeeAlso [] + +******************************************************************************/ +DdNode* +cuddSplitSetRecur( + DdManager * manager, + st_table * mtable, + int * varSeen, + DdNode * p, + double n, + double max, + int index) +{ + DdNode *one, *zero, *N, *Nv; + DdNode *Nnv, *q, *r, *v; + DdNode *result; + double *dummy, numT, numE; + int variable, positive; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* If p is constant, extract n minterms from constant 1. The procedure by + ** construction guarantees that minterms will not be extracted from + ** constant 0. + */ + if (Cudd_IsConstant(p)) { + q = selectMintermsFromUniverse(manager,varSeen,n); + return(q); + } + + N = Cudd_Regular(p); + + /* Set variable as seen. */ + variable = N->index; + varSeen[manager->invperm[variable]] = -1; + + Nv = cuddT(N); + Nnv = cuddE(N); + if (Cudd_IsComplement(p)) { + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); + } + + /* If both the children of 'p' are constants, extract n minterms from a + ** constant node. + */ + if (Cudd_IsConstant(Nv) && Cudd_IsConstant(Nnv)) { + q = selectMintermsFromUniverse(manager,varSeen,n); + if (q == NULL) { + return(NULL); + } + cuddRef(q); + r = cuddBddAndRecur(manager,p,q); + if (r == NULL) { + Cudd_RecursiveDeref(manager,q); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDeref(manager,q); + cuddDeref(r); + return(r); + } + + /* Lookup the # of minterms in the onset of the node from the table. */ + if (!Cudd_IsConstant(Nv)) { + if (!st_lookup(mtable, Nv, &dummy)) return(NULL); + numT = *dummy/(2*(1<size; + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Count the number of variables not encountered so far in procedure + ** cuddSplitSetRecur. + */ + for (i = size-1; i >= 0; i--) { + if(varSeen[i] == 0) + numVars++; + } + vars = ALLOC(DdNode *, numVars); + if (!vars) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + j = 0; + for (i = size-1; i >= 0; i--) { + if(varSeen[i] == 0) { + vars[j] = cuddUniqueInter(manager,manager->perm[i],one,zero); + cuddRef(vars[j]); + j++; + } + } + + /* Compute a function which has n minterms and depends on at most + ** numVars variables. + */ + result = mintermsFromUniverse(manager,vars,numVars,n, 0); + if (result) + cuddRef(result); + + for (i = 0; i < numVars; i++) + Cudd_RecursiveDeref(manager,vars[i]); + FREE(vars); + + return(result); + +} /* end of selectMintermsFromUniverse */ + + +/**Function******************************************************************** + + Synopsis [Recursive procedure to extract n mintems from constant 1.] + + Description [Recursive procedure to extract n mintems from constant 1.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +mintermsFromUniverse( + DdManager * manager, + DdNode ** vars, + int numVars, + double n, + int index) +{ + DdNode *one, *zero; + DdNode *q, *result; + double max, max2; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + max = pow(2.0, (double)numVars); + max2 = max / 2.0; + + if (n == max) + return(one); + if (n == 0.0) + return(zero); + /* if n == 2^(numVars-1), return a single variable */ + if (n == max2) + return vars[index]; + else if (n > max2) { + /* When n > 2^(numVars-1), a single variable vars[index] + ** contains 2^(numVars-1) minterms. The rest are extracted + ** from a constant with 1 less variable. + */ + q = mintermsFromUniverse(manager,vars,numVars-1,(n-max2),index+1); + if (q == NULL) + return(NULL); + cuddRef(q); + result = cuddBddIteRecur(manager,vars[index],one,q); + } else { + /* When n < 2^(numVars-1), a literal of variable vars[index] + ** is selected. The required n minterms are extracted from a + ** constant with 1 less variable. + */ + q = mintermsFromUniverse(manager,vars,numVars-1,n,index+1); + if (q == NULL) + return(NULL); + cuddRef(q); + result = cuddBddAndRecur(manager,vars[index],q); + } + + if (result == NULL) { + Cudd_RecursiveDeref(manager,q); + return(NULL); + } + cuddRef(result); + Cudd_RecursiveDeref(manager,q); + cuddDeref(result); + return(result); + +} /* end of mintermsFromUniverse */ + + +/**Function******************************************************************** + + Synopsis [Annotates every node in the BDD node with its minterm count.] + + Description [Annotates every node in the BDD node with its minterm count. + In this function, every node and the minterm count represented by it are + stored in a hash table.] + + SideEffects [Fills up 'table' with the pair .] + +******************************************************************************/ +static double +bddAnnotateMintermCount( + DdManager * manager, + DdNode * node, + double max, + st_table * table) +{ + + DdNode *N,*Nv,*Nnv; + register double min_v,min_nv; + register double min_N; + double *pmin; + double *dummy; + + statLine(manager); + N = Cudd_Regular(node); + if (cuddIsConstant(N)) { + if (node == DD_ONE(manager)) { + return(max); + } else { + return(0.0); + } + } + + if (st_lookup(table, node, &dummy)) { + return(*dummy); + } + + Nv = cuddT(N); + Nnv = cuddE(N); + if (N != node) { + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); + } + + /* Recur on the two branches. */ + min_v = bddAnnotateMintermCount(manager,Nv,max,table) / 2.0; + if (min_v == (double)CUDD_OUT_OF_MEM) + return ((double)CUDD_OUT_OF_MEM); + min_nv = bddAnnotateMintermCount(manager,Nnv,max,table) / 2.0; + if (min_nv == (double)CUDD_OUT_OF_MEM) + return ((double)CUDD_OUT_OF_MEM); + min_N = min_v + min_nv; + + pmin = ALLOC(double,1); + if (pmin == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + *pmin = min_N; + + if (st_insert(table,(char *)node, (char *)pmin) == ST_OUT_OF_MEM) { + FREE(pmin); + return((double)CUDD_OUT_OF_MEM); + } + + return(min_N); + +} /* end of bddAnnotateMintermCount */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetHB.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetHB.c new file mode 100644 index 000000000..bb0f847b2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetHB.c @@ -0,0 +1,1331 @@ +/**CFile*********************************************************************** + + FileName [cuddSubsetHB.c] + + PackageName [cudd] + + Synopsis [Procedure to subset the given BDD by choosing the heavier + branches.] + + + Description [External procedures provided by this module: +
                  +
                • Cudd_SubsetHeavyBranch() +
                • Cudd_SupersetHeavyBranch() +
                + Internal procedures included in this module: +
                  +
                • cuddSubsetHeavyBranch() +
                + Static procedures included in this module: +
                  +
                • ResizeCountMintermPages(); +
                • ResizeNodeDataPages() +
                • ResizeCountNodePages() +
                • SubsetCountMintermAux() +
                • SubsetCountMinterm() +
                • SubsetCountNodesAux() +
                • SubsetCountNodes() +
                • BuildSubsetBdd() +
                + ] + + SeeAlso [cuddSubsetSP.c] + + Author [Kavita Ravi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#ifdef __STDC__ +#include +#else +#define DBL_MAX_EXP 1024 +#endif +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DEFAULT_PAGE_SIZE 2048 +#define DEFAULT_NODE_DATA_PAGE_SIZE 1024 +#define INITIAL_PAGES 128 + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/* data structure to store the information on each node. It keeps + * the number of minterms represented by the DAG rooted at this node + * in terms of the number of variables specified by the user, number + * of nodes in this DAG and the number of nodes of its child with + * lesser number of minterms that are not shared by the child with + * more minterms + */ +struct NodeData { + double *mintermPointer; + int *nodesPointer; + int *lightChildNodesPointer; +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct NodeData NodeData_t; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSubsetHB.c,v 1.39 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int memOut; +#ifdef DEBUG +static int num_calls; +#endif + +static DdNode *zero, *one; /* constant functions */ +static double **mintermPages; /* pointers to the pages */ +static int **nodePages; /* pointers to the pages */ +static int **lightNodePages; /* pointers to the pages */ +static double *currentMintermPage; /* pointer to the current + page */ +static double max; /* to store the 2^n value of the number + * of variables */ + +static int *currentNodePage; /* pointer to the current + page */ +static int *currentLightNodePage; /* pointer to the + * current page */ +static int pageIndex; /* index to next element */ +static int page; /* index to current page */ +static int pageSize = DEFAULT_PAGE_SIZE; /* page size */ +static int maxPages; /* number of page pointers */ + +static NodeData_t *currentNodeDataPage; /* pointer to the current + page */ +static int nodeDataPage; /* index to next element */ +static int nodeDataPageIndex; /* index to next element */ +static NodeData_t **nodeDataPages; /* index to current page */ +static int nodeDataPageSize = DEFAULT_NODE_DATA_PAGE_SIZE; + /* page size */ +static int maxNodeDataPages; /* number of page pointers */ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void ResizeNodeDataPages (void); +static void ResizeCountMintermPages (void); +static void ResizeCountNodePages (void); +static double SubsetCountMintermAux (DdNode *node, double max, st_table *table); +static st_table * SubsetCountMinterm (DdNode *node, int nvars); +static int SubsetCountNodesAux (DdNode *node, st_table *table, double max); +static int SubsetCountNodes (DdNode *node, st_table *table, int nvars); +static void StoreNodes (st_table *storeTable, DdManager *dd, DdNode *node); +static DdNode * BuildSubsetBdd (DdManager *dd, DdNode *node, int *size, st_table *visitedTable, int threshold, st_table *storeTable, st_table *approxTable); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the heavy branch + heuristic.] + + Description [Extracts a dense subset from a BDD. This procedure + builds a subset by throwing away one of the children of each node, + starting from the root, until the result is small enough. The child + that is eliminated from the result is the one that contributes the + fewer minterms. Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation and node count calculation. The optimal number should + be as close as possible to the size of the support of f. However, + it is safe to pass the value returned by Cudd_ReadSize for numVars + when the number of variables is under 1023. If numVars is larger + than 1023, it will overflow. If a 0 parameter is passed then the + procedure will compute a value which will avoid overflow but will + cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SupersetHeavyBranch Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_SubsetHeavyBranch( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the subset */) +{ + DdNode *subset; + + memOut = 0; + do { + dd->reordered = 0; + subset = cuddSubsetHeavyBranch(dd, f, numVars, threshold); + } while ((dd->reordered == 1) && (!memOut)); + + return(subset); + +} /* end of Cudd_SubsetHeavyBranch */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the heavy branch + heuristic.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the subset procedure except for the fact that it + receives the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. This procedure builds a superset by throwing away + one of the children of each node starting from the root of the + complement function, until the result is small enough. The child + that is eliminated from the result is the one that contributes the + fewer minterms. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation and node count calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_SupersetHeavyBranch( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the superset */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + memOut = 0; + do { + dd->reordered = 0; + subset = cuddSubsetHeavyBranch(dd, g, numVars, threshold); + } while ((dd->reordered == 1) && (!memOut)); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_SupersetHeavyBranch */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [The main procedure that returns a subset by choosing the heavier + branch in the BDD.] + + Description [Here a subset BDD is built by throwing away one of the + children. Starting at root, annotate each node with the number of + minterms (in terms of the total number of variables specified - + numVars), number of nodes taken by the DAG rooted at this node and + number of additional nodes taken by the child that has the lesser + minterms. The child with the lower number of minterms is thrown away + and a dyanmic count of the nodes of the subset is kept. Once the + threshold is reached the subset is returned to the calling + procedure.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetHeavyBranch] + +******************************************************************************/ +DdNode * +cuddSubsetHeavyBranch( + DdManager * dd /* DD manager */, + DdNode * f /* current DD */, + int numVars /* maximum number of variables */, + int threshold /* threshold size for the subset */) +{ + + int i, *size; + st_table *visitedTable; + int numNodes; + NodeData_t *currNodeQual; + DdNode *subset; + st_table *storeTable, *approxTable; + DdNode *key, *value; + st_generator *stGen; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + one = Cudd_ReadOne(dd); + zero = Cudd_Not(one); + + /* If user does not know numVars value, set it to the maximum + * exponent that the pow function can take. The -1 is due to the + * discrepancy in the value that pow takes and the value that + * log gives. + */ + if (numVars == 0) { + /* set default value */ + numVars = DBL_MAX_EXP - 1; + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + max = pow(2.0, (double)numVars); + + /* Create visited table where structures for node data are allocated and + stored in a st_table */ + visitedTable = SubsetCountMinterm(f, numVars); + if ((visitedTable == NULL) || memOut) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + numNodes = SubsetCountNodes(f, visitedTable, numVars); + if (memOut) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + + if (st_lookup(visitedTable, f, &currNodeQual) == 0) { + fprintf(dd->err, + "Something is wrong, ought to be node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + } + + size = ALLOC(int, 1); + if (size == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + *size = numNodes; + +#ifdef DEBUG + num_calls = 0; +#endif + /* table to store nodes being created. */ + storeTable = st_init_table(st_ptrcmp, st_ptrhash); + /* insert the constant */ + cuddRef(one); + if (st_insert(storeTable, Cudd_ReadOne(dd), NULL) == + ST_OUT_OF_MEM) { + fprintf(dd->out, "Something wrong, st_table insert failed\n"); + } + /* table to store approximations of nodes */ + approxTable = st_init_table(st_ptrcmp, st_ptrhash); + subset = (DdNode *)BuildSubsetBdd(dd, f, size, visitedTable, threshold, + storeTable, approxTable); + if (subset != NULL) { + cuddRef(subset); + } + + stGen = st_init_gen(approxTable); + if (stGen == NULL) { + st_free_table(approxTable); + return(NULL); + } + while(st_gen(stGen, &key, &value)) { + Cudd_RecursiveDeref(dd, value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(approxTable); + + stGen = st_init_gen(storeTable); + if (stGen == NULL) { + st_free_table(storeTable); + return(NULL); + } + while(st_gen(stGen, &key, &value)) { + Cudd_RecursiveDeref(dd, key); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(storeTable); + + for (i = 0; i <= page; i++) { + FREE(mintermPages[i]); + } + FREE(mintermPages); + for (i = 0; i <= page; i++) { + FREE(nodePages[i]); + } + FREE(nodePages); + for (i = 0; i <= page; i++) { + FREE(lightNodePages[i]); + } + FREE(lightNodePages); + for (i = 0; i <= nodeDataPage; i++) { + FREE(nodeDataPages[i]); + } + FREE(nodeDataPages); + st_free_table(visitedTable); + FREE(size); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + + if (subset != NULL) { +#ifdef DD_DEBUG + if (!Cudd_bddLeq(dd, subset, f)) { + fprintf(dd->err, "Wrong subset\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } +#endif + cuddDeref(subset); + return(subset); + } else { + return(NULL); + } +} /* end of cuddSubsetHeavyBranch */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store the node data.] + + Description [Resize the number of pages allocated to store the node data + The procedure moves the counter to the next page when the end of + the page is reached and allocates new pages when necessary.] + + SideEffects [Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. ] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeNodeDataPages(void) +{ + int i; + NodeData_t **newNodeDataPages; + + nodeDataPage++; + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. Page numbers are incremented by + * INITIAL_PAGES + */ + if (nodeDataPage == maxNodeDataPages) { + newNodeDataPages = ALLOC(NodeData_t *,maxNodeDataPages + INITIAL_PAGES); + if (newNodeDataPages == NULL) { + for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + memOut = 1; + return; + } else { + for (i = 0; i < maxNodeDataPages; i++) { + newNodeDataPages[i] = nodeDataPages[i]; + } + /* Increase total page count */ + maxNodeDataPages += INITIAL_PAGES; + FREE(nodeDataPages); + nodeDataPages = newNodeDataPages; + } + } + /* Allocate a new page */ + currentNodeDataPage = nodeDataPages[nodeDataPage] = + ALLOC(NodeData_t ,nodeDataPageSize); + if (currentNodeDataPage == NULL) { + for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + memOut = 1; + return; + } + /* reset page index */ + nodeDataPageIndex = 0; + return; + +} /* end of ResizeNodeDataPages */ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store the minterm + counts. ] + + Description [Resize the number of pages allocated to store the minterm + counts. The procedure moves the counter to the next page when the + end of the page is reached and allocates new pages when necessary.] + + SideEffects [Changes the size of minterm pages, page, page index, maximum + number of pages freeing stuff in case of memory out. ] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeCountMintermPages(void) +{ + int i; + double **newMintermPages; + + page++; + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. Page numbers are incremented by + * INITIAL_PAGES + */ + if (page == maxPages) { + newMintermPages = ALLOC(double *,maxPages + INITIAL_PAGES); + if (newMintermPages == NULL) { + for (i = 0; i < page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newMintermPages[i] = mintermPages[i]; + } + /* Increase total page count */ + maxPages += INITIAL_PAGES; + FREE(mintermPages); + mintermPages = newMintermPages; + } + } + /* Allocate a new page */ + currentMintermPage = mintermPages[page] = ALLOC(double,pageSize); + if (currentMintermPage == NULL) { + for (i = 0; i < page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + memOut = 1; + return; + } + /* reset page index */ + pageIndex = 0; + return; + +} /* end of ResizeCountMintermPages */ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store the node counts.] + + Description [Resize the number of pages allocated to store the node counts. + The procedure moves the counter to the next page when the end of + the page is reached and allocates new pages when necessary.] + + SideEffects [Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out.] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeCountNodePages(void) +{ + int i; + int **newNodePages; + + page++; + + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. The number of pages is incremented + * by INITIAL_PAGES. + */ + if (page == maxPages) { + newNodePages = ALLOC(int *,maxPages + INITIAL_PAGES); + if (newNodePages == NULL) { + for (i = 0; i < page; i++) FREE(nodePages[i]); + FREE(nodePages); + for (i = 0; i < page; i++) FREE(lightNodePages[i]); + FREE(lightNodePages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newNodePages[i] = nodePages[i]; + } + FREE(nodePages); + nodePages = newNodePages; + } + + newNodePages = ALLOC(int *,maxPages + INITIAL_PAGES); + if (newNodePages == NULL) { + for (i = 0; i < page; i++) FREE(nodePages[i]); + FREE(nodePages); + for (i = 0; i < page; i++) FREE(lightNodePages[i]); + FREE(lightNodePages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newNodePages[i] = lightNodePages[i]; + } + FREE(lightNodePages); + lightNodePages = newNodePages; + } + /* Increase total page count */ + maxPages += INITIAL_PAGES; + } + /* Allocate a new page */ + currentNodePage = nodePages[page] = ALLOC(int,pageSize); + if (currentNodePage == NULL) { + for (i = 0; i < page; i++) FREE(nodePages[i]); + FREE(nodePages); + for (i = 0; i < page; i++) FREE(lightNodePages[i]); + FREE(lightNodePages); + memOut = 1; + return; + } + /* Allocate a new page */ + currentLightNodePage = lightNodePages[page] = ALLOC(int,pageSize); + if (currentLightNodePage == NULL) { + for (i = 0; i <= page; i++) FREE(nodePages[i]); + FREE(nodePages); + for (i = 0; i < page; i++) FREE(lightNodePages[i]); + FREE(lightNodePages); + memOut = 1; + return; + } + /* reset page index */ + pageIndex = 0; + return; + +} /* end of ResizeCountNodePages */ + + +/**Function******************************************************************** + + Synopsis [Recursively counts minterms of each node in the DAG.] + + Description [Recursively counts minterms of each node in the DAG. + Similar to the cuddCountMintermAux which recursively counts the + number of minterms for the dag rooted at each node in terms of the + total number of variables (max). This procedure creates the node + data structure and stores the minterm count as part of the node + data structure. ] + + SideEffects [Creates structures of type node quality and fills the st_table] + + SeeAlso [SubsetCountMinterm] + +******************************************************************************/ +static double +SubsetCountMintermAux( + DdNode * node /* function to analyze */, + double max /* number of minterms of constant 1 */, + st_table * table /* visitedTable table */) +{ + + DdNode *N,*Nv,*Nnv; /* nodes to store cofactors */ + double min,*pmin; /* minterm count */ + double min1, min2; /* minterm count */ + NodeData_t *dummy; + NodeData_t *newEntry; + int i; + +#ifdef DEBUG + num_calls++; +#endif + + /* Constant case */ + if (Cudd_IsConstant(node)) { + if (node == zero) { + return(0.0); + } else { + return(max); + } + } else { + + /* check if entry for this node exists */ + if (st_lookup(table, node, &dummy)) { + min = *(dummy->mintermPointer); + return(min); + } + + /* Make the node regular to extract cofactors */ + N = Cudd_Regular(node); + + /* store the cofactors */ + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + min1 = SubsetCountMintermAux(Nv, max,table)/2.0; + if (memOut) return(0.0); + min2 = SubsetCountMintermAux(Nnv,max,table)/2.0; + if (memOut) return(0.0); + min = (min1+min2); + + /* if page index is at the bottom, then create a new page */ + if (pageIndex == pageSize) ResizeCountMintermPages(); + if (memOut) { + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0.0); + } + + /* point to the correct location in the page */ + pmin = currentMintermPage+pageIndex; + pageIndex++; + + /* store the minterm count of this node in the page */ + *pmin = min; + + /* Note I allocate the struct here. Freeing taken care of later */ + if (nodeDataPageIndex == nodeDataPageSize) ResizeNodeDataPages(); + if (memOut) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + st_free_table(table); + return(0.0); + } + + newEntry = currentNodeDataPage + nodeDataPageIndex; + nodeDataPageIndex++; + + /* points to the correct location in the page */ + newEntry->mintermPointer = pmin; + /* initialize this field of the Node Quality structure */ + newEntry->nodesPointer = NULL; + + /* insert entry for the node in the table */ + if (st_insert(table,node, newEntry) == ST_OUT_OF_MEM) { + memOut = 1; + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0.0); + } + return(min); + } + +} /* end of SubsetCountMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Counts minterms of each node in the DAG] + + Description [Counts minterms of each node in the DAG. Similar to the + Cudd_CountMinterm procedure except this returns the minterm count for + all the nodes in the bdd in an st_table.] + + SideEffects [none] + + SeeAlso [SubsetCountMintermAux] + +******************************************************************************/ +static st_table * +SubsetCountMinterm( + DdNode * node /* function to be analyzed */, + int nvars /* number of variables node depends on */) +{ + st_table *table; + int i; + + +#ifdef DEBUG + num_calls = 0; +#endif + + max = pow(2.0,(double) nvars); + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) goto OUT_OF_MEM; + maxPages = INITIAL_PAGES; + mintermPages = ALLOC(double *,maxPages); + if (mintermPages == NULL) { + st_free_table(table); + goto OUT_OF_MEM; + } + page = 0; + currentMintermPage = ALLOC(double,pageSize); + mintermPages[page] = currentMintermPage; + if (currentMintermPage == NULL) { + FREE(mintermPages); + st_free_table(table); + goto OUT_OF_MEM; + } + pageIndex = 0; + maxNodeDataPages = INITIAL_PAGES; + nodeDataPages = ALLOC(NodeData_t *, maxNodeDataPages); + if (nodeDataPages == NULL) { + for (i = 0; i <= page ; i++) FREE(mintermPages[i]); + FREE(mintermPages); + st_free_table(table); + goto OUT_OF_MEM; + } + nodeDataPage = 0; + currentNodeDataPage = ALLOC(NodeData_t ,nodeDataPageSize); + nodeDataPages[nodeDataPage] = currentNodeDataPage; + if (currentNodeDataPage == NULL) { + for (i = 0; i <= page ; i++) FREE(mintermPages[i]); + FREE(mintermPages); + FREE(nodeDataPages); + st_free_table(table); + goto OUT_OF_MEM; + } + nodeDataPageIndex = 0; + + (void) SubsetCountMintermAux(node,max,table); + if (memOut) goto OUT_OF_MEM; + return(table); + +OUT_OF_MEM: + memOut = 1; + return(NULL); + +} /* end of SubsetCountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node.] + + Description [Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node. . Note that the same dag may be the lighter child of two + different nodes and have different counts. As with the minterm counts, + the node counts are stored in pages to be space efficient and the + address for these node counts are stored in an st_table associated + to each node. ] + + SideEffects [Updates the node data table with node counts] + + SeeAlso [SubsetCountNodes] + +******************************************************************************/ +static int +SubsetCountNodesAux( + DdNode * node /* current node */, + st_table * table /* table to update node count, also serves as visited table. */, + double max /* maximum number of variables */) +{ + int tval, eval, i; + DdNode *N, *Nv, *Nnv; + double minNv, minNnv; + NodeData_t *dummyN, *dummyNv, *dummyNnv, *dummyNBar; + int *pmin, *pminBar, *val; + + if ((node == NULL) || Cudd_IsConstant(node)) + return(0); + + /* if this node has been processed do nothing */ + if (st_lookup(table, node, &dummyN) == 1) { + val = dummyN->nodesPointer; + if (val != NULL) + return(0); + } else { + return(0); + } + + N = Cudd_Regular(node); + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* find the minterm counts for the THEN and ELSE branches */ + if (Cudd_IsConstant(Nv)) { + if (Nv == zero) { + minNv = 0.0; + } else { + minNv = max; + } + } else { + if (st_lookup(table, Nv, &dummyNv) == 1) + minNv = *(dummyNv->mintermPointer); + else { + return(0); + } + } + if (Cudd_IsConstant(Nnv)) { + if (Nnv == zero) { + minNnv = 0.0; + } else { + minNnv = max; + } + } else { + if (st_lookup(table, Nnv, &dummyNnv) == 1) { + minNnv = *(dummyNnv->mintermPointer); + } + else { + return(0); + } + } + + + /* recur based on which has larger minterm, */ + if (minNv >= minNnv) { + tval = SubsetCountNodesAux(Nv, table, max); + if (memOut) return(0); + eval = SubsetCountNodesAux(Nnv, table, max); + if (memOut) return(0); + + /* store the node count of the lighter child. */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pmin = currentLightNodePage + pageIndex; + *pmin = eval; /* Here the ELSE child is lighter */ + dummyN->lightChildNodesPointer = pmin; + + } else { + eval = SubsetCountNodesAux(Nnv, table, max); + if (memOut) return(0); + tval = SubsetCountNodesAux(Nv, table, max); + if (memOut) return(0); + + /* store the node count of the lighter child. */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pmin = currentLightNodePage + pageIndex; + *pmin = tval; /* Here the THEN child is lighter */ + dummyN->lightChildNodesPointer = pmin; + + } + /* updating the page index for node count storage. */ + pmin = currentNodePage + pageIndex; + *pmin = tval + eval + 1; + dummyN->nodesPointer = pmin; + + /* pageIndex is parallel page index for count_nodes and count_lightNodes */ + pageIndex++; + + /* if this node has been reached first, it belongs to a heavier + branch. Its complement will be reached later on a lighter branch. + Hence the complement has zero node count. */ + + if (st_lookup(table, Cudd_Not(node), &dummyNBar) == 1) { + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i < page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pminBar = currentLightNodePage + pageIndex; + *pminBar = 0; + dummyNBar->lightChildNodesPointer = pminBar; + /* The lighter child has less nodes than the parent. + * So if parent 0 then lighter child zero + */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i < page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pminBar = currentNodePage + pageIndex; + *pminBar = 0; + dummyNBar->nodesPointer = pminBar ; /* maybe should point to zero */ + + pageIndex++; + } + return(*pmin); +} /*end of SubsetCountNodesAux */ + + +/**Function******************************************************************** + + Synopsis [Counts the nodes under the current node and its lighter child] + + Description [Counts the nodes under the current node and its lighter + child. Calls a recursive procedure to count the number of nodes of + a DAG rooted at a particular node and the number of nodes taken by its + lighter child.] + + SideEffects [None] + + SeeAlso [SubsetCountNodesAux] + +******************************************************************************/ +static int +SubsetCountNodes( + DdNode * node /* function to be analyzed */, + st_table * table /* node quality table */, + int nvars /* number of variables node depends on */) +{ + int num; + int i; + +#ifdef DEBUG + num_calls = 0; +#endif + + max = pow(2.0,(double) nvars); + maxPages = INITIAL_PAGES; + nodePages = ALLOC(int *,maxPages); + if (nodePages == NULL) { + goto OUT_OF_MEM; + } + + lightNodePages = ALLOC(int *,maxPages); + if (lightNodePages == NULL) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + FREE(nodePages); + goto OUT_OF_MEM; + } + + page = 0; + currentNodePage = nodePages[page] = ALLOC(int,pageSize); + if (currentNodePage == NULL) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + FREE(lightNodePages); + FREE(nodePages); + goto OUT_OF_MEM; + } + + currentLightNodePage = lightNodePages[page] = ALLOC(int,pageSize); + if (currentLightNodePage == NULL) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + FREE(currentNodePage); + FREE(lightNodePages); + FREE(nodePages); + goto OUT_OF_MEM; + } + + pageIndex = 0; + num = SubsetCountNodesAux(node,table,max); + if (memOut) goto OUT_OF_MEM; + return(num); + +OUT_OF_MEM: + memOut = 1; + return(0); + +} /* end of SubsetCountNodes */ + + +/**Function******************************************************************** + + Synopsis [Procedure to recursively store nodes that are retained in the subset.] + + Description [rocedure to recursively store nodes that are retained in the subset.] + + SideEffects [None] + + SeeAlso [StoreNodes] + +******************************************************************************/ +static void +StoreNodes( + st_table * storeTable, + DdManager * dd, + DdNode * node) +{ + DdNode *N, *Nt, *Ne; + if (Cudd_IsConstant(dd)) { + return; + } + N = Cudd_Regular(node); + if (st_lookup(storeTable, N, NULL)) { + return; + } + cuddRef(N); + if (st_insert(storeTable, N, NULL) == ST_OUT_OF_MEM) { + fprintf(dd->err,"Something wrong, st_table insert failed\n"); + } + + Nt = Cudd_T(N); + Ne = Cudd_E(N); + + StoreNodes(storeTable, dd, Nt); + StoreNodes(storeTable, dd, Ne); + return; + +} + + +/**Function******************************************************************** + + Synopsis [Builds the subset BDD using the heavy branch method.] + + Description [The procedure carries out the building of the subset BDD + starting at the root. Using the three different counts labelling each node, + the procedure chooses the heavier branch starting from the root and keeps + track of the number of nodes it discards at each step, thus keeping count + of the size of the subset BDD dynamically. Once the threshold is satisfied, + the procedure then calls ITE to build the BDD.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +BuildSubsetBdd( + DdManager * dd /* DD manager */, + DdNode * node /* current node */, + int * size /* current size of the subset */, + st_table * visitedTable /* visited table storing all node data */, + int threshold, + st_table * storeTable, + st_table * approxTable) +{ + + DdNode *Nv, *Nnv, *N, *topv, *neW; + double minNv, minNnv; + NodeData_t *currNodeQual; + NodeData_t *currNodeQualT; + NodeData_t *currNodeQualE; + DdNode *ThenBranch, *ElseBranch; + unsigned int topid; + char *dummy; + +#ifdef DEBUG + num_calls++; +#endif + /*If the size of the subset is below the threshold, dont do + anything. */ + if ((*size) <= threshold) { + /* store nodes below this, so we can recombine if possible */ + StoreNodes(storeTable, dd, node); + return(node); + } + + if (Cudd_IsConstant(node)) + return(node); + + /* Look up minterm count for this node. */ + if (!st_lookup(visitedTable, node, &currNodeQual)) { + fprintf(dd->err, + "Something is wrong, ought to be in node quality table\n"); + } + + /* Get children. */ + N = Cudd_Regular(node); + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + /* complement if necessary */ + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + if (!Cudd_IsConstant(Nv)) { + /* find out minterms and nodes contributed by then child */ + if (!st_lookup(visitedTable, Nv, &currNodeQualT)) { + fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + else { + minNv = *(((NodeData_t *)currNodeQualT)->mintermPointer); + } + } else { + if (Nv == zero) { + minNv = 0; + } else { + minNv = max; + } + } + if (!Cudd_IsConstant(Nnv)) { + /* find out minterms and nodes contributed by else child */ + if (!st_lookup(visitedTable, Nnv, &currNodeQualE)) { + fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } else { + minNnv = *(((NodeData_t *)currNodeQualE)->mintermPointer); + } + } else { + if (Nnv == zero) { + minNnv = 0; + } else { + minNnv = max; + } + } + + /* keep track of size of subset by subtracting the number of + * differential nodes contributed by lighter child + */ + *size = (*(size)) - (int)*(currNodeQual->lightChildNodesPointer); + if (minNv >= minNnv) { /*SubsetCountNodesAux procedure takes + the Then branch in case of a tie */ + + /* recur with the Then branch */ + ThenBranch = (DdNode *)BuildSubsetBdd(dd, Nv, size, + visitedTable, threshold, storeTable, approxTable); + if (ThenBranch == NULL) { + return(NULL); + } + cuddRef(ThenBranch); + /* The Else branch is either a node that already exists in the + * subset, or one whose approximation has been computed, or + * Zero. + */ + if (st_lookup(storeTable, Cudd_Regular(Nnv), &dummy)) { + ElseBranch = Nnv; + cuddRef(ElseBranch); + } else { + if (st_lookup(approxTable, Nnv, &dummy)) { + ElseBranch = (DdNode *)dummy; + cuddRef(ElseBranch); + } else { + ElseBranch = zero; + cuddRef(ElseBranch); + } + } + + } + else { + /* recur with the Else branch */ + ElseBranch = (DdNode *)BuildSubsetBdd(dd, Nnv, size, + visitedTable, threshold, storeTable, approxTable); + if (ElseBranch == NULL) { + return(NULL); + } + cuddRef(ElseBranch); + /* The Then branch is either a node that already exists in the + * subset, or one whose approximation has been computed, or + * Zero. + */ + if (st_lookup(storeTable, Cudd_Regular(Nv), &dummy)) { + ThenBranch = Nv; + cuddRef(ThenBranch); + } else { + if (st_lookup(approxTable, Nv, &dummy)) { + ThenBranch = (DdNode *)dummy; + cuddRef(ThenBranch); + } else { + ThenBranch = zero; + cuddRef(ThenBranch); + } + } + } + + /* construct the Bdd with the top variable and the two children */ + topid = Cudd_NodeReadIndex(N); + topv = Cudd_ReadVars(dd, topid); + cuddRef(topv); + neW = cuddBddIteRecur(dd, topv, ThenBranch, ElseBranch); + if (neW != NULL) { + cuddRef(neW); + } + Cudd_RecursiveDeref(dd, topv); + Cudd_RecursiveDeref(dd, ThenBranch); + Cudd_RecursiveDeref(dd, ElseBranch); + + + if (neW == NULL) + return(NULL); + else { + /* store this node in the store table */ + if (!st_lookup(storeTable, Cudd_Regular(neW), &dummy)) { + cuddRef(neW); + if (st_insert(storeTable, Cudd_Regular(neW), NULL) == + ST_OUT_OF_MEM) + return (NULL); + } + /* store the approximation for this node */ + if (N != Cudd_Regular(neW)) { + if (st_lookup(approxTable, node, &dummy)) { + fprintf(dd->err, "This node should not be in the approximated table\n"); + } else { + cuddRef(neW); + if (st_insert(approxTable, node, neW) == + ST_OUT_OF_MEM) + return(NULL); + } + } + cuddDeref(neW); + return(neW); + } +} /* end of BuildSubsetBdd */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetSP.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetSP.c new file mode 100644 index 000000000..fa89f167f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSubsetSP.c @@ -0,0 +1,1660 @@ +/**CFile*********************************************************************** + + FileName [cuddSubsetSP.c] + + PackageName [cudd] + + Synopsis [Procedure to subset the given BDD choosing the shortest paths + (largest cubes) in the BDD.] + + + Description [External procedures included in this module: +
                  +
                • Cudd_SubsetShortPaths() +
                • Cudd_SupersetShortPaths() +
                + Internal procedures included in this module: +
                  +
                • cuddSubsetShortPaths() +
                + Static procedures included in this module: +
                  +
                • BuildSubsetBdd() +
                • CreatePathTable() +
                • AssessPathLength() +
                • CreateTopDist() +
                • CreateBotDist() +
                • ResizeNodeDistPages() +
                • ResizeQueuePages() +
                • stPathTableDdFree() +
                + ] + + SeeAlso [cuddSubsetHB.c] + + Author [Kavita Ravi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DEFAULT_PAGE_SIZE 2048 /* page size to store the BFS queue element type */ +#define DEFAULT_NODE_DIST_PAGE_SIZE 2048 /* page size to store NodeDist_t type */ +#define MAXSHORTINT ((DdHalfWord) ~0) /* constant defined to store + * maximum distance of a node + * from the root or the constant + */ +#define INITIAL_PAGES 128 /* number of initial pages for the + * queue/NodeDist_t type */ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/* structure created to store subset results for each node and distances with + * odd and even parity of the node from the root and sink. Main data structure + * in this procedure. + */ +struct NodeDist { + DdHalfWord oddTopDist; + DdHalfWord evenTopDist; + DdHalfWord oddBotDist; + DdHalfWord evenBotDist; + DdNode *regResult; + DdNode *compResult; +}; + +/* assorted information needed by the BuildSubsetBdd procedure. */ +struct AssortedInfo { + unsigned int maxpath; + int findShortestPath; + int thresholdReached; + st_table *maxpathTable; + int threshold; +}; + +struct GlobalInfo { + struct NodeDist **nodeDistPages; /* pointers to the pages */ + int nodeDistPageIndex; /* index to next element */ + int nodeDistPage; /* index to current page */ + int nodeDistPageSize; /* page size */ + int maxNodeDistPages; /* number of page pointers */ + struct NodeDist *currentNodeDistPage; /* current page */ + DdNode ***queuePages; /* pointers to the pages */ + int queuePageIndex; /* index to next element */ + int queuePage; /* index to current page */ + int queuePageSize; /* page size */ + int maxQueuePages; /* number of page pointers */ + DdNode **currentQueuePage; /* current page */ +#ifdef DD_DEBUG + int numCalls; + int hits; + int thishit; +#endif +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct NodeDist NodeDist_t; +typedef struct GlobalInfo GlobalInfo_t; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSubsetSP.c,v 1.36 2012/02/05 01:07:19 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void ResizeNodeDistPages (DdManager *dd, GlobalInfo_t *gInfo); +static void ResizeQueuePages (DdManager *dd, GlobalInfo_t *gInfo); +static void CreateTopDist (DdManager *dd, GlobalInfo_t *gInfo, st_table *pathTable, int parentPage, int parentQueueIndex, int topLen, DdNode **childPage, int childQueueIndex, int numParents, FILE *fp); +static int CreateBotDist (DdNode *node, st_table *pathTable, unsigned int *pathLengthArray, FILE *fp); +static st_table * CreatePathTable (DdManager *dd, GlobalInfo_t *gInfo, DdNode *node, unsigned int *pathLengthArray, FILE *fp); +static unsigned int AssessPathLength (unsigned int *pathLengthArray, int threshold, int numVars, unsigned int *excess, FILE *fp); +static DdNode * BuildSubsetBdd (DdManager *dd, GlobalInfo_t *gInfo, st_table *pathTable, DdNode *node, struct AssortedInfo *info, st_table *subsetNodeTable); +static enum st_retval stPathTableDdFree (char *key, char *value, char *arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of Exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the shortest paths + heuristic.] + + Description [Extracts a dense subset from a BDD. This procedure + tries to preserve the shortest paths of the input BDD, because they + give many minterms and contribute few nodes. This procedure may + increase the number of nodes in trying to create the subset or + reduce the number of nodes due to recombination as compared to the + original BDD. Hence the threshold may not be strictly adhered to. In + practice, recombination overshadows the increase in the number of + nodes and results in small BDDs as compared to the threshold. The + hardlimit specifies whether threshold needs to be strictly adhered + to. If it is set to 1, the procedure ensures that result is never + larger than the specified limit but may be considerably less than + the threshold. Returns a pointer to the BDD for the subset if + successful; NULL otherwise. The value for numVars should be as + close as possible to the size of the support of f for better + efficiency. However, it is safe to pass the value returned by + Cudd_ReadSize for numVars. If 0 is passed, then the value returned + by Cudd_ReadSize is used.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_SubsetShortPaths( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the subset */, + int hardlimit /* flag: 1 if threshold is a hard limit */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddSubsetShortPaths(dd, f, numVars, threshold, hardlimit); + } while(dd->reordered == 1); + + return(subset); + +} /* end of Cudd_SubsetShortPaths */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the shortest paths + heuristic.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the subset procedure except for the fact that it + receives the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. This procedure tries to preserve the shortest + paths of the complement BDD, because they give many minterms and + contribute few nodes. This procedure may increase the number of + nodes in trying to create the superset or reduce the number of nodes + due to recombination as compared to the original BDD. Hence the + threshold may not be strictly adhered to. In practice, recombination + overshadows the increase in the number of nodes and results in small + BDDs as compared to the threshold. The hardlimit specifies whether + threshold needs to be strictly adhered to. If it is set to 1, the + procedure ensures that result is never larger than the specified + limit but may be considerably less than the threshold. Returns a + pointer to the BDD for the superset if successful; NULL + otherwise. The value for numVars should be as close as possible to + the size of the support of f for better efficiency. However, it is + safe to pass the value returned by Cudd_ReadSize for numVar. If 0 + is passed, then the value returned by Cudd_ReadSize is used.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SupersetHeavyBranch Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_SupersetShortPaths( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the subset */, + int hardlimit /* flag: 1 if threshold is a hard limit */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddSubsetShortPaths(dd, g, numVars, threshold, hardlimit); + } while(dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_SupersetShortPaths */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [The outermost procedure to return a subset of the given BDD + with the shortest path lengths.] + + Description [The outermost procedure to return a subset of the given + BDD with the largest cubes. The path lengths are calculated, the maximum + allowable path length is determined and the number of nodes of this + path length that can be used to build a subset. If the threshold is + larger than the size of the original BDD, the original BDD is + returned. ] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths] + +******************************************************************************/ +DdNode * +cuddSubsetShortPaths( + DdManager * dd /* DD manager */, + DdNode * f /* function to be subset */, + int numVars /* total number of variables in consideration */, + int threshold /* maximum number of nodes allowed in the subset */, + int hardlimit /* flag determining whether threshold should be respected strictly */) +{ + GlobalInfo_t gInfo; + st_table *pathTable; + DdNode *N, *subset; + + unsigned int *pathLengthArray; + unsigned int maxpath, oddLen, evenLen, pathLength, *excess; + int i; + NodeDist_t *nodeStat; + struct AssortedInfo *info; + st_table *subsetNodeTable; + + gInfo.nodeDistPageSize = DEFAULT_NODE_DIST_PAGE_SIZE; + gInfo.queuePageSize = DEFAULT_PAGE_SIZE; + + if (numVars == 0) { + /* set default value */ + numVars = Cudd_ReadSize(dd); + } + + if (threshold > numVars) { + threshold = threshold - numVars; + } + if (f == NULL) { + fprintf(dd->err, "Cannot partition, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + if (Cudd_IsConstant(f)) + return (f); + + pathLengthArray = ALLOC(unsigned int, numVars+1); + for (i = 0; i < numVars+1; i++) pathLengthArray[i] = 0; + + +#ifdef DD_DEBUG + gInfo.numCalls = 0; +#endif + + pathTable = CreatePathTable(dd, &gInfo, f, pathLengthArray, dd->err); + + if ((pathTable == NULL) || (dd->errorCode == CUDD_MEMORY_OUT)) { + if (pathTable != NULL) + st_free_table(pathTable); + FREE(pathLengthArray); + return (NIL(DdNode)); + } + + excess = ALLOC(unsigned int, 1); + *excess = 0; + maxpath = AssessPathLength(pathLengthArray, threshold, numVars, excess, + dd->err); + + if (maxpath != (unsigned) (numVars + 1)) { + + info = ALLOC(struct AssortedInfo, 1); + info->maxpath = maxpath; + info->findShortestPath = 0; + info->thresholdReached = *excess; + info->maxpathTable = st_init_table(st_ptrcmp, st_ptrhash); + info->threshold = threshold; + +#ifdef DD_DEBUG + (void) fprintf(dd->out, "Path length array\n"); + for (i = 0; i < (numVars+1); i++) { + if (pathLengthArray[i]) + (void) fprintf(dd->out, "%d ",i); + } + (void) fprintf(dd->out, "\n"); + for (i = 0; i < (numVars+1); i++) { + if (pathLengthArray[i]) + (void) fprintf(dd->out, "%d ",pathLengthArray[i]); + } + (void) fprintf(dd->out, "\n"); + (void) fprintf(dd->out, "Maxpath = %d, Thresholdreached = %d\n", + maxpath, info->thresholdReached); +#endif + + N = Cudd_Regular(f); + if (!st_lookup(pathTable, N, &nodeStat)) { + fprintf(dd->err, "Something wrong, root node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + FREE(excess); + FREE(info); + return(NULL); + } else { + if ((nodeStat->oddTopDist != MAXSHORTINT) && + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + else + oddLen = MAXSHORTINT; + + if ((nodeStat->evenTopDist != MAXSHORTINT) && + (nodeStat->evenBotDist != MAXSHORTINT)) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + else + evenLen = MAXSHORTINT; + + pathLength = (oddLen <= evenLen) ? oddLen : evenLen; + if (pathLength > maxpath) { + (void) fprintf(dd->err, "All computations are bogus, since root has path length greater than max path length within threshold %u, %u\n", maxpath, pathLength); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + } + +#ifdef DD_DEBUG + gInfo.numCalls = 0; + gInfo.hits = 0; + gInfo.thishit = 0; +#endif + /* initialize a table to store computed nodes */ + if (hardlimit) { + subsetNodeTable = st_init_table(st_ptrcmp, st_ptrhash); + } else { + subsetNodeTable = NIL(st_table); + } + subset = BuildSubsetBdd(dd, &gInfo, pathTable, f, info, subsetNodeTable); + if (subset != NULL) { + cuddRef(subset); + } + /* record the number of times a computed result for a node is hit */ + +#ifdef DD_DEBUG + (void) fprintf(dd->out, "Hits = %d, New==Node = %d, NumCalls = %d\n", + gInfo.hits, gInfo.thishit, gInfo.numCalls); +#endif + + if (subsetNodeTable != NIL(st_table)) { + st_free_table(subsetNodeTable); + } + st_free_table(info->maxpathTable); + st_foreach(pathTable, stPathTableDdFree, (char *)dd); + + FREE(info); + + } else {/* if threshold larger than size of dd */ + subset = f; + cuddRef(subset); + } + FREE(excess); + st_free_table(pathTable); + FREE(pathLengthArray); + for (i = 0; i <= gInfo.nodeDistPage; i++) FREE(gInfo.nodeDistPages[i]); + FREE(gInfo.nodeDistPages); + +#ifdef DD_DEBUG + /* check containment of subset in f */ + if (subset != NULL) { + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong partition\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + } +#endif + + if (subset != NULL) { + cuddDeref(subset); + return(subset); + } else { + return(NULL); + } + +} /* end of cuddSubsetShortPaths */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store the distances + related to each node.] + + Description [Resize the number of pages allocated to store the distances + related to each node. The procedure moves the counter to the + next page when the end of the page is reached and allocates new + pages when necessary. ] + + SideEffects [Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. ] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeNodeDistPages( + DdManager *dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */) +{ + int i; + NodeDist_t **newNodeDistPages; + + /* move to next page */ + gInfo->nodeDistPage++; + + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. Page numbers are incremented by + * INITIAL_PAGES + */ + if (gInfo->nodeDistPage == gInfo->maxNodeDistPages) { + newNodeDistPages = ALLOC(NodeDist_t *,gInfo->maxNodeDistPages + INITIAL_PAGES); + if (newNodeDistPages == NULL) { + for (i = 0; i < gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + dd->errorCode = CUDD_MEMORY_OUT; + return; + } else { + for (i = 0; i < gInfo->maxNodeDistPages; i++) { + newNodeDistPages[i] = gInfo->nodeDistPages[i]; + } + /* Increase total page count */ + gInfo->maxNodeDistPages += INITIAL_PAGES; + FREE(gInfo->nodeDistPages); + gInfo->nodeDistPages = newNodeDistPages; + } + } + /* Allocate a new page */ + gInfo->currentNodeDistPage = gInfo->nodeDistPages[gInfo->nodeDistPage] = + ALLOC(NodeDist_t, gInfo->nodeDistPageSize); + if (gInfo->currentNodeDistPage == NULL) { + for (i = 0; i < gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + dd->errorCode = CUDD_MEMORY_OUT; + return; + } + /* reset page index */ + gInfo->nodeDistPageIndex = 0; + return; + +} /* end of ResizeNodeDistPages */ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd .] + + Description [Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd. The procedure moves the counter to the + next page when the end of the page is reached and allocates new + pages when necessary.] + + SideEffects [Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. ] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeQueuePages( + DdManager *dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */) +{ + int i; + DdNode ***newQueuePages; + + gInfo->queuePage++; + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. Page numbers are incremented by + * INITIAL_PAGES + */ + if (gInfo->queuePage == gInfo->maxQueuePages) { + newQueuePages = ALLOC(DdNode **,gInfo->maxQueuePages + INITIAL_PAGES); + if (newQueuePages == NULL) { + for (i = 0; i < gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + dd->errorCode = CUDD_MEMORY_OUT; + return; + } else { + for (i = 0; i < gInfo->maxQueuePages; i++) { + newQueuePages[i] = gInfo->queuePages[i]; + } + /* Increase total page count */ + gInfo->maxQueuePages += INITIAL_PAGES; + FREE(gInfo->queuePages); + gInfo->queuePages = newQueuePages; + } + } + /* Allocate a new page */ + gInfo->currentQueuePage = gInfo->queuePages[gInfo->queuePage] = + ALLOC(DdNode *,gInfo->queuePageSize); + if (gInfo->currentQueuePage == NULL) { + for (i = 0; i < gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + dd->errorCode = CUDD_MEMORY_OUT; + return; + } + /* reset page index */ + gInfo->queuePageIndex = 0; + return; + +} /* end of ResizeQueuePages */ + + +/**Function******************************************************************** + + Synopsis [ Labels each node with its shortest distance from the root] + + Description [ Labels each node with its shortest distance from the root. + This is done in a BFS search of the BDD. The nodes are processed + in a queue implemented as pages(array) to reduce memory fragmentation. + An entry is created for each node visited. The distance from the root + to the node with the corresponding parity is updated. The procedure + is called recursively each recusion level handling nodes at a given + level from the root.] + + + SideEffects [Creates entries in the pathTable] + + SeeAlso [CreatePathTable CreateBotDist] + +******************************************************************************/ +static void +CreateTopDist( + DdManager *dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */, + st_table * pathTable /* hast table to store path lengths */, + int parentPage /* the pointer to the page on which the first parent in the queue is to be found. */, + int parentQueueIndex /* pointer to the first parent on the page */, + int topLen /* current distance from the root */, + DdNode ** childPage /* pointer to the page on which the first child is to be added. */, + int childQueueIndex /* pointer to the first child */, + int numParents /* number of parents to process in this recursive call */, + FILE *fp /* where to write messages */) +{ + NodeDist_t *nodeStat; + DdNode *N, *Nv, *Nnv, *node, *child, *regChild; + int i; + int processingDone, childrenCount; + +#ifdef DD_DEBUG + gInfo->numCalls++; + + /* assume this procedure comes in with only the root node*/ + /* set queue index to the next available entry for addition */ + /* set queue page to page of addition */ + if ((gInfo->queuePages[parentPage] == childPage) && (parentQueueIndex == + childQueueIndex)) { + fprintf(fp, "Should not happen that they are equal\n"); + } + assert(gInfo->queuePageIndex == childQueueIndex); + assert(gInfo->currentQueuePage == childPage); +#endif + /* number children added to queue is initialized , needed for + * numParents in the next call + */ + childrenCount = 0; + /* process all the nodes in this level */ + while (numParents) { + numParents--; + if (parentQueueIndex == gInfo->queuePageSize) { + parentPage++; + parentQueueIndex = 0; + } + /* a parent to process */ + node = *(gInfo->queuePages[parentPage] + parentQueueIndex); + parentQueueIndex++; + /* get its children */ + N = Cudd_Regular(node); + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + processingDone = 2; + while (processingDone) { + /* processing the THEN and the ELSE children, the THEN + * child first + */ + if (processingDone == 2) { + child = Nv; + } else { + child = Nnv; + } + + regChild = Cudd_Regular(child); + /* dont process if the child is a constant */ + if (!Cudd_IsConstant(child)) { + /* check is already visited, if not add a new entry in + * the path Table + */ + if (!st_lookup(pathTable, regChild, &nodeStat)) { + /* if not in table, has never been visited */ + /* create entry for table */ + if (gInfo->nodeDistPageIndex == gInfo->nodeDistPageSize) + ResizeNodeDistPages(dd, gInfo); + if (dd->errorCode == CUDD_MEMORY_OUT) { + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + st_free_table(pathTable); + return; + } + /* New entry for child in path Table is created here */ + nodeStat = gInfo->currentNodeDistPage + gInfo->nodeDistPageIndex; + gInfo->nodeDistPageIndex++; + + /* Initialize fields of the node data */ + nodeStat->oddTopDist = MAXSHORTINT; + nodeStat->evenTopDist = MAXSHORTINT; + nodeStat->evenBotDist = MAXSHORTINT; + nodeStat->oddBotDist = MAXSHORTINT; + nodeStat->regResult = NULL; + nodeStat->compResult = NULL; + /* update the table entry element, the distance keeps + * track of the parity of the path from the root + */ + if (Cudd_IsComplement(child)) { + nodeStat->oddTopDist = (DdHalfWord) topLen + 1; + } else { + nodeStat->evenTopDist = (DdHalfWord) topLen + 1; + } + + /* insert entry element for child in the table */ + if (st_insert(pathTable, regChild, + nodeStat) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i <= gInfo->nodeDistPage; i++) + FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + st_free_table(pathTable); + return; + } + + /* Create list element for this child to process its children. + * If this node has been processed already, then it appears + * in the path table and hence is never added to the list + * again. + */ + + if (gInfo->queuePageIndex == gInfo->queuePageSize) ResizeQueuePages(dd, gInfo); + if (dd->errorCode == CUDD_MEMORY_OUT) { + for (i = 0; i <= gInfo->nodeDistPage; i++) + FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + st_free_table(pathTable); + return; + } + *(gInfo->currentQueuePage + gInfo->queuePageIndex) = child; + gInfo->queuePageIndex++; + + childrenCount++; + } else { + /* if not been met in a path with this parity before */ + /* put in list */ + if (((Cudd_IsComplement(child)) && (nodeStat->oddTopDist == + MAXSHORTINT)) || ((!Cudd_IsComplement(child)) && + (nodeStat->evenTopDist == MAXSHORTINT))) { + + if (gInfo->queuePageIndex == gInfo->queuePageSize) ResizeQueuePages(dd, gInfo); + if (dd->errorCode == CUDD_MEMORY_OUT) { + for (i = 0; i <= gInfo->nodeDistPage; i++) + FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + st_free_table(pathTable); + return; + + } + *(gInfo->currentQueuePage + gInfo->queuePageIndex) = child; + gInfo->queuePageIndex++; + + /* update the distance with the appropriate parity */ + if (Cudd_IsComplement(child)) { + nodeStat->oddTopDist = (DdHalfWord) topLen + 1; + } else { + nodeStat->evenTopDist = (DdHalfWord) topLen + 1; + } + childrenCount++; + } + + } /* end of else (not found in st_table) */ + } /*end of if Not constant child */ + processingDone--; + } /*end of while processing Nv, Nnv */ + } /*end of while numParents */ + +#ifdef DD_DEBUG + assert(gInfo->queuePages[parentPage] == childPage); + assert(parentQueueIndex == childQueueIndex); +#endif + + if (childrenCount != 0) { + topLen++; + childPage = gInfo->currentQueuePage; + childQueueIndex = gInfo->queuePageIndex; + CreateTopDist(dd, gInfo, pathTable, parentPage, parentQueueIndex, topLen, + childPage, childQueueIndex, childrenCount, fp); + } + + return; + +} /* end of CreateTopDist */ + + +/**Function******************************************************************** + + Synopsis [ Labels each node with the shortest distance from the constant.] + + Description [Labels each node with the shortest distance from the constant. + This is done in a DFS search of the BDD. Each node has an odd + and even parity distance from the sink (since there exists paths to both + zero and one) which is less than MAXSHORTINT. At each node these distances + are updated using the minimum distance of its children from the constant. + SInce now both the length from the root and child is known, the minimum path + length(length of the shortest path between the root and the constant that + this node lies on) of this node can be calculated and used to update the + pathLengthArray] + + SideEffects [Updates Path Table and path length array] + + SeeAlso [CreatePathTable CreateTopDist AssessPathLength] + +******************************************************************************/ +static int +CreateBotDist( + DdNode * node /* current node */, + st_table * pathTable /* path table with path lengths */, + unsigned int * pathLengthArray /* array that stores number of nodes belonging to a particular path length. */, + FILE *fp /* where to write messages */) +{ + DdNode *N, *Nv, *Nnv; + DdNode *realChild; + DdNode *child, *regChild; + NodeDist_t *nodeStat, *nodeStatChild; + unsigned int oddLen, evenLen, pathLength; + DdHalfWord botDist; + int processingDone; + + if (Cudd_IsConstant(node)) + return(1); + N = Cudd_Regular(node); + /* each node has one table entry */ + /* update as you go down the min dist of each node from + the root in each (odd and even) parity */ + if (!st_lookup(pathTable, N, &nodeStat)) { + fprintf(fp, "Something wrong, the entry doesn't exist\n"); + return(0); + } + + /* compute length of odd parity distances */ + if ((nodeStat->oddTopDist != MAXSHORTINT) && + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + else + oddLen = MAXSHORTINT; + + /* compute length of even parity distances */ + if (!((nodeStat->evenTopDist == MAXSHORTINT) || + (nodeStat->evenBotDist == MAXSHORTINT))) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + else + evenLen = MAXSHORTINT; + + /* assign pathlength to minimum of the two */ + pathLength = (oddLen <= evenLen) ? oddLen : evenLen; + + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + /* process each child */ + processingDone = 0; + while (processingDone != 2) { + if (!processingDone) { + child = Nv; + } else { + child = Nnv; + } + + realChild = Cudd_NotCond(child, Cudd_IsComplement(node)); + regChild = Cudd_Regular(child); + if (Cudd_IsConstant(realChild)) { + /* Found a minterm; count parity and shortest distance + ** from the constant. + */ + if (Cudd_IsComplement(child)) + nodeStat->oddBotDist = 1; + else + nodeStat->evenBotDist = 1; + } else { + /* If node not in table, recur. */ + if (!st_lookup(pathTable, regChild, &nodeStatChild)) { + fprintf(fp, "Something wrong, node in table should have been created in top dist proc.\n"); + return(0); + } + + if (nodeStatChild->oddBotDist == MAXSHORTINT) { + if (nodeStatChild->evenBotDist == MAXSHORTINT) { + if (!CreateBotDist(realChild, pathTable, pathLengthArray, fp)) + return(0); + } else { + fprintf(fp, "Something wrong, both bot nodeStats should be there\n"); + return(0); + } + } + + /* Update shortest distance from the constant depending on + ** parity. */ + + if (Cudd_IsComplement(child)) { + /* If parity on the edge then add 1 to even distance + ** of child to get odd parity distance and add 1 to + ** odd distance of child to get even parity + ** distance. Change distance of current node only if + ** the calculated distance is less than existing + ** distance. */ + if (nodeStatChild->oddBotDist != MAXSHORTINT) + botDist = nodeStatChild->oddBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->evenBotDist > botDist ) + nodeStat->evenBotDist = botDist; + + if (nodeStatChild->evenBotDist != MAXSHORTINT) + botDist = nodeStatChild->evenBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->oddBotDist > botDist) + nodeStat->oddBotDist = botDist; + + } else { + /* If parity on the edge then add 1 to even distance + ** of child to get even parity distance and add 1 to + ** odd distance of child to get odd parity distance. + ** Change distance of current node only if the + ** calculated distance is lesser than existing + ** distance. */ + if (nodeStatChild->evenBotDist != MAXSHORTINT) + botDist = nodeStatChild->evenBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->evenBotDist > botDist) + nodeStat->evenBotDist = botDist; + + if (nodeStatChild->oddBotDist != MAXSHORTINT) + botDist = nodeStatChild->oddBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->oddBotDist > botDist) + nodeStat->oddBotDist = botDist; + } + } /* end of else (if not constant child ) */ + processingDone++; + } /* end of while processing Nv, Nnv */ + + /* Compute shortest path length on the fly. */ + if ((nodeStat->oddTopDist != MAXSHORTINT) && + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + else + oddLen = MAXSHORTINT; + + if ((nodeStat->evenTopDist != MAXSHORTINT) && + (nodeStat->evenBotDist != MAXSHORTINT)) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + else + evenLen = MAXSHORTINT; + + /* Update path length array that has number of nodes of a particular + ** path length. */ + if (oddLen < pathLength ) { + if (pathLength != MAXSHORTINT) + pathLengthArray[pathLength]--; + if (oddLen != MAXSHORTINT) + pathLengthArray[oddLen]++; + pathLength = oddLen; + } + if (evenLen < pathLength ) { + if (pathLength != MAXSHORTINT) + pathLengthArray[pathLength]--; + if (evenLen != MAXSHORTINT) + pathLengthArray[evenLen]++; + } + + return(1); + +} /*end of CreateBotDist */ + + +/**Function******************************************************************** + + Synopsis [ The outer procedure to label each node with its shortest + distance from the root and constant] + + Description [ The outer procedure to label each node with its shortest + distance from the root and constant. Calls CreateTopDist and CreateBotDist. + The basis for computing the distance between root and constant is that + the distance may be the sum of even distances from the node to the root + and constant or the sum of odd distances from the node to the root and + constant. Both CreateTopDist and CreateBotDist create the odd and + even parity distances from the root and constant respectively.] + + SideEffects [None] + + SeeAlso [CreateTopDist CreateBotDist] + +******************************************************************************/ +static st_table * +CreatePathTable( + DdManager *dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */, + DdNode * node /* root of function */, + unsigned int * pathLengthArray /* array of path lengths to store nodes labeled with the various path lengths */, + FILE *fp /* where to write messages */) +{ + + st_table *pathTable; + NodeDist_t *nodeStat; + DdHalfWord topLen; + DdNode *N; + int i, numParents; + int insertValue; + DdNode **childPage; + int parentPage; + int childQueueIndex, parentQueueIndex; + + /* Creating path Table for storing data about nodes */ + pathTable = st_init_table(st_ptrcmp,st_ptrhash); + + /* initializing pages for info about each node */ + gInfo->maxNodeDistPages = INITIAL_PAGES; + gInfo->nodeDistPages = ALLOC(NodeDist_t *, gInfo->maxNodeDistPages); + if (gInfo->nodeDistPages == NULL) { + goto OUT_OF_MEM; + } + gInfo->nodeDistPage = 0; + gInfo->currentNodeDistPage = gInfo->nodeDistPages[gInfo->nodeDistPage] = + ALLOC(NodeDist_t, gInfo->nodeDistPageSize); + if (gInfo->currentNodeDistPage == NULL) { + for (i = 0; i <= gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + goto OUT_OF_MEM; + } + gInfo->nodeDistPageIndex = 0; + + /* Initializing pages for the BFS search queue, implemented as an array. */ + gInfo->maxQueuePages = INITIAL_PAGES; + gInfo->queuePages = ALLOC(DdNode **, gInfo->maxQueuePages); + if (gInfo->queuePages == NULL) { + goto OUT_OF_MEM; + } + gInfo->queuePage = 0; + gInfo->currentQueuePage = gInfo->queuePages[gInfo->queuePage] = + ALLOC(DdNode *, gInfo->queuePageSize); + if (gInfo->currentQueuePage == NULL) { + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + goto OUT_OF_MEM; + } + gInfo->queuePageIndex = 0; + + /* Enter the root node into the queue to start with. */ + parentPage = gInfo->queuePage; + parentQueueIndex = gInfo->queuePageIndex; + topLen = 0; + *(gInfo->currentQueuePage + gInfo->queuePageIndex) = node; + gInfo->queuePageIndex++; + childPage = gInfo->currentQueuePage; + childQueueIndex = gInfo->queuePageIndex; + + N = Cudd_Regular(node); + + if (gInfo->nodeDistPageIndex == gInfo->nodeDistPageSize) ResizeNodeDistPages(dd, gInfo); + if (dd->errorCode == CUDD_MEMORY_OUT) { + for (i = 0; i <= gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + st_free_table(pathTable); + goto OUT_OF_MEM; + } + + nodeStat = gInfo->currentNodeDistPage + gInfo->nodeDistPageIndex; + gInfo->nodeDistPageIndex++; + + nodeStat->oddTopDist = MAXSHORTINT; + nodeStat->evenTopDist = MAXSHORTINT; + nodeStat->evenBotDist = MAXSHORTINT; + nodeStat->oddBotDist = MAXSHORTINT; + nodeStat->regResult = NULL; + nodeStat->compResult = NULL; + + insertValue = st_insert(pathTable, N, nodeStat); + if (insertValue == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i <= gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + st_free_table(pathTable); + goto OUT_OF_MEM; + } else if (insertValue == 1) { + fprintf(fp, "Something wrong, the entry exists but didnt show up in st_lookup\n"); + return(NULL); + } + + if (Cudd_IsComplement(node)) { + nodeStat->oddTopDist = 0; + } else { + nodeStat->evenTopDist = 0; + } + numParents = 1; + /* call the function that counts the distance of each node from the + * root + */ +#ifdef DD_DEBUG + gInfo->numCalls = 0; +#endif + CreateTopDist(dd, gInfo, pathTable, parentPage, parentQueueIndex, (int) topLen, + childPage, childQueueIndex, numParents, fp); + if (dd->errorCode == CUDD_MEMORY_OUT) { + fprintf(fp, "Out of Memory and cant count path lengths\n"); + goto OUT_OF_MEM; + } + +#ifdef DD_DEBUG + gInfo->numCalls = 0; +#endif + /* call the function that counts the distance of each node from the + * constant + */ + if (!CreateBotDist(node, pathTable, pathLengthArray, fp)) return(NULL); + + /* free BFS queue pages as no longer required */ + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + return(pathTable); + +OUT_OF_MEM: + (void) fprintf(fp, "Out of Memory, cannot allocate pages\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + +} /*end of CreatePathTable */ + + +/**Function******************************************************************** + + Synopsis [Chooses the maximum allowable path length of nodes under the + threshold.] + + Description [Chooses the maximum allowable path length under each node. + The corner cases are when the threshold is larger than the number + of nodes in the BDD iself, in which case 'numVars + 1' is returned. + If all nodes of a particular path length are needed, then the + maxpath returned is the next one with excess nodes = 0;] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static unsigned int +AssessPathLength( + unsigned int * pathLengthArray /* array determining number of nodes belonging to the different path lengths */, + int threshold /* threshold to determine maximum allowable nodes in the subset */, + int numVars /* maximum number of variables */, + unsigned int * excess /* number of nodes labeled maxpath required in the subset */, + FILE *fp /* where to write messages */) +{ + unsigned int i, maxpath; + int temp; + + temp = threshold; + i = 0; + maxpath = 0; + /* quit loop if i reaches max number of variables or if temp reaches + * below zero + */ + while ((i < (unsigned) numVars+1) && (temp > 0)) { + if (pathLengthArray[i] > 0) { + maxpath = i; + temp = temp - pathLengthArray[i]; + } + i++; + } + /* if all nodes of max path are needed */ + if (temp >= 0) { + maxpath++; /* now maxpath becomes the next maxppath or max number + of variables */ + *excess = 0; + } else { /* normal case when subset required is less than size of + original BDD */ + *excess = temp + pathLengthArray[maxpath]; + } + + if (maxpath == 0) { + fprintf(fp, "Path Length array seems to be all zeroes, check\n"); + } + return(maxpath); + +} /* end of AssessPathLength */ + + +/**Function******************************************************************** + + Synopsis [Builds the BDD with nodes labeled with path length less than or equal to maxpath] + + Description [Builds the BDD with nodes labeled with path length + under maxpath and as many nodes labeled maxpath as determined by the + threshold. The procedure uses the path table to determine which nodes + in the original bdd need to be retained. This procedure picks a + shortest path (tie break decided by taking the child with the shortest + distance to the constant) and recurs down the path till it reaches the + constant. the procedure then starts building the subset upward from + the constant. All nodes labeled by path lengths less than the given + maxpath are used to build the subset. However, in the case of nodes + that have label equal to maxpath, as many are chosen as required by + the threshold. This number is stored in the info structure in the + field thresholdReached. This field is decremented whenever a node + labeled maxpath is encountered and the nodes labeled maxpath are + aggregated in a maxpath table. As soon as the thresholdReached count + goes to 0, the shortest path from this node to the constant is found. + The extraction of nodes with the above labeling is based on the fact + that each node, labeled with a path length, P, has at least one child + labeled P or less. So extracting all nodes labeled a given path length + P ensures complete paths between the root and the constant. Extraction + of a partial number of nodes with a given path length may result in + incomplete paths and hence the additional number of nodes are grabbed + to complete the path. Since the Bdd is built bottom-up, other nodes + labeled maxpath do lie on complete paths. The procedure may cause the + subset to have a larger or smaller number of nodes than the specified + threshold. The increase in the number of nodes is caused by the + building of a subset and the reduction by recombination. However in + most cases, the recombination overshadows the increase and the + procedure returns a result with lower number of nodes than specified. + The subsetNodeTable is NIL when there is no hard limit on the number + of nodes. Further efforts towards keeping the subset closer to the + threshold number were abandoned in favour of keeping the procedure + simple and fast.] + + SideEffects [SubsetNodeTable is changed if it is not NIL.] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +BuildSubsetBdd( + DdManager * dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */, + st_table * pathTable /* path table with path lengths and computed results */, + DdNode * node /* current node */, + struct AssortedInfo * info /* assorted information structure */, + st_table * subsetNodeTable /* table storing computed results */) +{ + DdNode *N, *Nv, *Nnv; + DdNode *ThenBranch, *ElseBranch, *childBranch; + DdNode *child, *regChild, *regNnv, *regNv; + NodeDist_t *nodeStatNv, *nodeStat, *nodeStatNnv; + DdNode *neW, *topv, *regNew; + char *entry; + unsigned int topid; + unsigned int childPathLength, oddLen, evenLen, NnvPathLength, NvPathLength; + unsigned int NvBotDist, NnvBotDist; + int tiebreakChild; + int processingDone, thenDone, elseDone; + + DdNode *zero = Cudd_Not(DD_ONE(dd)); +#ifdef DD_DEBUG + gInfo->numCalls++; +#endif + if (Cudd_IsConstant(node)) + return(node); + + N = Cudd_Regular(node); + /* Find node in table. */ + if (!st_lookup(pathTable, N, &nodeStat)) { + (void) fprintf(dd->err, "Something wrong, node must be in table \n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + /* If the node in the table has been visited, then return the corresponding + ** Dd. Since a node can become a subset of itself, its + ** complement (that is te same node reached by a different parity) will + ** become a superset of the original node and result in some minterms + ** that were not in the original set. Hence two different results are + ** maintained, corresponding to the odd and even parities. + */ + + /* If this node is reached with an odd parity, get odd parity results. */ + if (Cudd_IsComplement(node)) { + if (nodeStat->compResult != NULL) { +#ifdef DD_DEBUG + gInfo->hits++; +#endif + return(nodeStat->compResult); + } + } else { + /* if this node is reached with an even parity, get even parity + * results + */ + if (nodeStat->regResult != NULL) { +#ifdef DD_DEBUG + gInfo->hits++; +#endif + return(nodeStat->regResult); + } + } + + + /* get children */ + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* no child processed */ + processingDone = 0; + /* then child not processed */ + thenDone = 0; + ThenBranch = NULL; + /* else child not processed */ + elseDone = 0; + ElseBranch = NULL; + /* if then child constant, branch is the child */ + if (Cudd_IsConstant(Nv)) { + /*shortest path found */ + if ((Nv == DD_ONE(dd)) && (info->findShortestPath)) { + info->findShortestPath = 0; + } + + ThenBranch = Nv; + cuddRef(ThenBranch); + if (ThenBranch == NULL) { + return(NULL); + } + + thenDone++; + processingDone++; + NvBotDist = MAXSHORTINT; + } else { + /* Derive regular child for table lookup. */ + regNv = Cudd_Regular(Nv); + /* Get node data for shortest path length. */ + if (!st_lookup(pathTable, regNv, &nodeStatNv) ) { + (void) fprintf(dd->err, "Something wrong, node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + /* Derive shortest path length for child. */ + if ((nodeStatNv->oddTopDist != MAXSHORTINT) && + (nodeStatNv->oddBotDist != MAXSHORTINT)) { + oddLen = (nodeStatNv->oddTopDist + nodeStatNv->oddBotDist); + } else { + oddLen = MAXSHORTINT; + } + + if ((nodeStatNv->evenTopDist != MAXSHORTINT) && + (nodeStatNv->evenBotDist != MAXSHORTINT)) { + evenLen = (nodeStatNv->evenTopDist +nodeStatNv->evenBotDist); + } else { + evenLen = MAXSHORTINT; + } + + NvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; + NvBotDist = (oddLen <= evenLen) ? nodeStatNv->oddBotDist: + nodeStatNv->evenBotDist; + } + /* if else child constant, branch is the child */ + if (Cudd_IsConstant(Nnv)) { + /*shortest path found */ + if ((Nnv == DD_ONE(dd)) && (info->findShortestPath)) { + info->findShortestPath = 0; + } + + ElseBranch = Nnv; + cuddRef(ElseBranch); + if (ElseBranch == NULL) { + return(NULL); + } + + elseDone++; + processingDone++; + NnvBotDist = MAXSHORTINT; + } else { + /* Derive regular child for table lookup. */ + regNnv = Cudd_Regular(Nnv); + /* Get node data for shortest path length. */ + if (!st_lookup(pathTable, regNnv, &nodeStatNnv) ) { + (void) fprintf(dd->err, "Something wrong, node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + /* Derive shortest path length for child. */ + if ((nodeStatNnv->oddTopDist != MAXSHORTINT) && + (nodeStatNnv->oddBotDist != MAXSHORTINT)) { + oddLen = (nodeStatNnv->oddTopDist + nodeStatNnv->oddBotDist); + } else { + oddLen = MAXSHORTINT; + } + + if ((nodeStatNnv->evenTopDist != MAXSHORTINT) && + (nodeStatNnv->evenBotDist != MAXSHORTINT)) { + evenLen = (nodeStatNnv->evenTopDist +nodeStatNnv->evenBotDist); + } else { + evenLen = MAXSHORTINT; + } + + NnvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; + NnvBotDist = (oddLen <= evenLen) ? nodeStatNnv->oddBotDist : + nodeStatNnv->evenBotDist; + } + + tiebreakChild = (NvBotDist <= NnvBotDist) ? 1 : 0; + /* while both children not processed */ + while (processingDone != 2) { + if (!processingDone) { + /* if no child processed */ + /* pick the child with shortest path length and record which one + * picked + */ + if ((NvPathLength < NnvPathLength) || + ((NvPathLength == NnvPathLength) && (tiebreakChild == 1))) { + child = Nv; + regChild = regNv; + thenDone = 1; + childPathLength = NvPathLength; + } else { + child = Nnv; + regChild = regNnv; + elseDone = 1; + childPathLength = NnvPathLength; + } /* then path length less than else path length */ + } else { + /* if one child processed, process the other */ + if (thenDone) { + child = Nnv; + regChild = regNnv; + elseDone = 1; + childPathLength = NnvPathLength; + } else { + child = Nv; + regChild = regNv; + thenDone = 1; + childPathLength = NvPathLength; + } /* end of else pick the Then child if ELSE child processed */ + } /* end of else one child has been processed */ + + /* ignore (replace with constant 0) all nodes which lie on paths larger + * than the maximum length of the path required + */ + if (childPathLength > info->maxpath) { + /* record nodes visited */ + childBranch = zero; + } else { + if (childPathLength < info->maxpath) { + if (info->findShortestPath) { + info->findShortestPath = 0; + } + childBranch = BuildSubsetBdd(dd, gInfo, pathTable, child, info, + subsetNodeTable); + + } else { /* Case: path length of node = maxpath */ + /* If the node labeled with maxpath is found in the + ** maxpathTable, use it to build the subset BDD. */ + if (st_lookup(info->maxpathTable, regChild, &entry)) { + /* When a node that is already been chosen is hit, + ** the quest for a complete path is over. */ + if (info->findShortestPath) { + info->findShortestPath = 0; + } + childBranch = BuildSubsetBdd(dd, gInfo, pathTable, child, info, + subsetNodeTable); + } else { + /* If node is not found in the maxpathTable and + ** the threshold has been reached, then if the + ** path needs to be completed, continue. Else + ** replace the node with a zero. */ + if (info->thresholdReached <= 0) { + if (info->findShortestPath) { + if (st_insert(info->maxpathTable, regChild, + NULL) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + (void) fprintf(dd->err, "OUT of memory\n"); + info->thresholdReached = 0; + childBranch = zero; + } else { + info->thresholdReached--; + childBranch = BuildSubsetBdd(dd, gInfo, pathTable, + child, info,subsetNodeTable); + } + } else { /* not find shortest path, we dont need this + node */ + childBranch = zero; + } + } else { /* Threshold hasn't been reached, + ** need the node. */ + if (st_insert(info->maxpathTable, regChild, + NULL) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + (void) fprintf(dd->err, "OUT of memory\n"); + info->thresholdReached = 0; + childBranch = zero; + } else { + info->thresholdReached--; + if (info->thresholdReached <= 0) { + info->findShortestPath = 1; + } + childBranch = BuildSubsetBdd(dd, gInfo, pathTable, + child, info, subsetNodeTable); + + } /* end of st_insert successful */ + } /* end of threshold hasnt been reached yet */ + } /* end of else node not found in maxpath table */ + } /* end of if (path length of node = maxpath) */ + } /* end if !(childPathLength > maxpath) */ + if (childBranch == NULL) { + /* deref other stuff incase reordering has taken place */ + if (ThenBranch != NULL) { + Cudd_RecursiveDeref(dd, ThenBranch); + ThenBranch = NULL; + } + if (ElseBranch != NULL) { + Cudd_RecursiveDeref(dd, ElseBranch); + ElseBranch = NULL; + } + return(NULL); + } + + cuddRef(childBranch); + + if (child == Nv) { + ThenBranch = childBranch; + } else { + ElseBranch = childBranch; + } + processingDone++; + + } /*end of while processing Nv, Nnv */ + + info->findShortestPath = 0; + topid = Cudd_NodeReadIndex(N); + topv = Cudd_ReadVars(dd, topid); + cuddRef(topv); + neW = cuddBddIteRecur(dd, topv, ThenBranch, ElseBranch); + if (neW != NULL) { + cuddRef(neW); + } + Cudd_RecursiveDeref(dd, topv); + Cudd_RecursiveDeref(dd, ThenBranch); + Cudd_RecursiveDeref(dd, ElseBranch); + + + /* Hard Limit of threshold has been imposed */ + if (subsetNodeTable != NIL(st_table)) { + /* check if a new node is created */ + regNew = Cudd_Regular(neW); + /* subset node table keeps all new nodes that have been created to keep + * a running count of how many nodes have been built in the subset. + */ + if (!st_lookup(subsetNodeTable, regNew, &entry)) { + if (!Cudd_IsConstant(regNew)) { + if (st_insert(subsetNodeTable, regNew, + NULL) == ST_OUT_OF_MEM) { + (void) fprintf(dd->err, "Out of memory\n"); + return (NULL); + } + if (st_count(subsetNodeTable) > info->threshold) { + info->thresholdReached = 0; + } + } + } + } + + + if (neW == NULL) { + return(NULL); + } else { + /*store computed result in regular form*/ + if (Cudd_IsComplement(node)) { + nodeStat->compResult = neW; + cuddRef(nodeStat->compResult); + /* if the new node is the same as the corresponding node in the + * original bdd then its complement need not be computed as it + * cannot be larger than the node itself + */ + if (neW == node) { +#ifdef DD_DEBUG + gInfo->thishit++; +#endif + /* if a result for the node has already been computed, then + * it can only be smaller than teh node itself. hence store + * the node result in order not to break recombination + */ + if (nodeStat->regResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->regResult); + } + nodeStat->regResult = Cudd_Not(neW); + cuddRef(nodeStat->regResult); + } + + } else { + nodeStat->regResult = neW; + cuddRef(nodeStat->regResult); + if (neW == node) { +#ifdef DD_DEBUG + gInfo->thishit++; +#endif + if (nodeStat->compResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->compResult); + } + nodeStat->compResult = Cudd_Not(neW); + cuddRef(nodeStat->compResult); + } + } + + cuddDeref(neW); + return(neW); + } /* end of else i.e. Subset != NULL */ +} /* end of BuildSubsetBdd */ + + +/**Function******************************************************************** + + Synopsis [Procedure to free te result dds stored in the NodeDist pages.] + + Description [None] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static enum st_retval +stPathTableDdFree( + char * key, + char * value, + char * arg) +{ + NodeDist_t *nodeStat; + DdManager *dd; + + nodeStat = (NodeDist_t *)value; + dd = (DdManager *)arg; + if (nodeStat->regResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->regResult); + } + if (nodeStat->compResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->compResult); + } + return(ST_CONTINUE); + +} /* end of stPathTableFree */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddSymmetry.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddSymmetry.c new file mode 100644 index 000000000..7761949ee --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddSymmetry.c @@ -0,0 +1,1707 @@ +/**CFile*********************************************************************** + + FileName [cuddSymmetry.c] + + PackageName [cudd] + + Synopsis [Functions for symmetry-based variable reordering.] + + Description [External procedures included in this file: +
                  +
                • Cudd_SymmProfile() +
                + Internal procedures included in this module: +
                  +
                • cuddSymmCheck() +
                • cuddSymmSifting() +
                • cuddSymmSiftingConv() +
                + Static procedures included in this module: +
                  +
                • ddSymmUniqueCompare() +
                • ddSymmSiftingAux() +
                • ddSymmSiftingConvAux() +
                • ddSymmSiftingUp() +
                • ddSymmSiftingDown() +
                • ddSymmGroupMove() +
                • ddSymmGroupMoveBackward() +
                • ddSymmSiftingBackward() +
                • ddSymmSummary() +
                ] + + Author [Shipra Panda, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define MV_OOM (Move *)1 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSymmetry.c,v 1.28 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int *entry; + +extern int ddTotalNumberSwapping; +#ifdef DD_STATS +extern int ddTotalNISwaps; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddSymmUniqueCompare (int *ptrX, int *ptrY); +static int ddSymmSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static int ddSymmSiftingConvAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddSymmSiftingUp (DdManager *table, int y, int xLow); +static Move * ddSymmSiftingDown (DdManager *table, int x, int xHigh); +static int ddSymmGroupMove (DdManager *table, int x, int y, Move **moves); +static int ddSymmGroupMoveBackward (DdManager *table, int x, int y); +static int ddSymmSiftingBackward (DdManager *table, Move *moves, int size); +static void ddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints statistics on symmetric variables.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +void +Cudd_SymmProfile( + DdManager * table, + int lower, + int upper) +{ + int i,x,gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; + + for (i = lower; i <= upper; i++) { + if (table->subtables[i].next != (unsigned) i) { + x = i; + (void) fprintf(table->out,"Group:"); + do { + (void) fprintf(table->out," %d",table->invperm[x]); + TotalSymm++; + gbot = x; + x = table->subtables[x].next; + } while (x != i); + TotalSymmGroups++; +#ifdef DD_DEBUG + assert(table->subtables[gbot].next == (unsigned) i); +#endif + i = gbot; + (void) fprintf(table->out,"\n"); + } + } + (void) fprintf(table->out,"Total Symmetric = %d\n",TotalSymm); + (void) fprintf(table->out,"Total Groups = %d\n",TotalSymmGroups); + +} /* end of Cudd_SymmProfile */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Checks for symmetry of x and y.] + + Description [Checks for symmetry of x and y. Ignores projection + functions, unless they are isolated. Returns 1 in case of symmetry; 0 + otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddSymmCheck( + DdManager * table, + int x, + int y) +{ + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10; + int comple; /* f0 is complemented */ + int xsymmy; /* x and y may be positively symmetric */ + int xsymmyp; /* x and y may be negatively symmetric */ + int arccount; /* number of arcs from layer x to layer y */ + int TotalRefCount; /* total reference count of layer y minus 1 */ + int yindex; + int i; + DdNodePtr *list; + int slots; + DdNode *sentinel = &(table->sentinel); +#ifdef DD_DEBUG + int xindex; +#endif + + /* Checks that x and y are not the projection functions. + ** For x it is sufficient to check whether there is only one + ** node; indeed, if there is one node, it is the projection function + ** and it cannot point to y. Hence, if y isn't just the projection + ** function, it has one arc coming from a layer different from x. + */ + if (table->subtables[x].keys == 1) { + return(0); + } + yindex = table->invperm[y]; + if (table->subtables[y].keys == 1) { + if (table->vars[yindex]->ref == 1) + return(0); + } + + xsymmy = xsymmyp = 1; + arccount = 0; + slots = table->subtables[x].slots; + list = table->subtables[x].nodelist; + for (i = 0; i < slots; i++) { + f = list[i]; + while (f != sentinel) { + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + f0 = Cudd_Regular(cuddE(f)); + comple = Cudd_IsComplement(cuddE(f)); + if ((int) f1->index == yindex) { + arccount++; + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + if ((int) f0->index != yindex) { + /* If f is an isolated projection function it is + ** allowed to bypass layer y. + */ + if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) + return(0); /* f bypasses layer y */ + } + f11 = f10 = f1; + } + if ((int) f0->index == yindex) { + arccount++; + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + + if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) { + xsymmy &= f01 == f10; + xsymmyp &= f11 == f00; + if ((xsymmy == 0) && (xsymmyp == 0)) + return(0); + } + + f = f->next; + } /* while */ + } /* for */ + + /* Calculate the total reference counts of y */ + TotalRefCount = -1; /* -1 for projection function */ + slots = table->subtables[y].slots; + list = table->subtables[y].nodelist; + for (i = 0; i < slots; i++) { + f = list[i]; + while (f != sentinel) { + TotalRefCount += f->ref; + f = f->next; + } + } + +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (arccount == TotalRefCount) { + xindex = table->invperm[x]; + (void) fprintf(table->out, + "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); + } +#endif + + return(arccount == TotalRefCount); + +} /* end of cuddSymmCheck */ + + +/**Function******************************************************************** + + Synopsis [Symmetric sifting algorithm.] + + Description [Symmetric sifting algorithm. + Assumes that no dead nodes are present. +
                  +
                1. Order all the variables according to the number of entries in + each unique subtable. +
                2. Sift the variable up and down, remembering each time the total + size of the DD heap and grouping variables that are symmetric. +
                3. Select the best permutation. +
                4. Repeat 3 and 4 for all variables. +
                + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddSymmSiftingConv] + +******************************************************************************/ +int +cuddSymmSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; + int symvars; + int symgroups; +#ifdef DD_STATS + int previousSize; +#endif + + size = table->size; + + /* Find order in which to sift variables. */ + var = NULL; + entry = ALLOC(int,size); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingOutOfMem; + } + var = ALLOC(int,size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; + } + + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); + + /* Initialize the symmetry of each subtable to itself. */ + for (i = lower; i <= upper; i++) { + table->subtables[i].next = i; + } + + for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + x = table->perm[var[i]]; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + if (x < lower || x > upper) continue; + if (table->subtables[x].next == (unsigned) x) { + result = ddSymmSiftingAux(table,x,lower,upper); + if (!result) goto ddSymmSiftingOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } + + FREE(var); + FREE(entry); + + ddSymmSummary(table, lower, upper, &symvars, &symgroups); + +#ifdef DD_STATS + (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n", + symvars); + (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups", + symgroups); +#endif + + return(1+symvars); + +ddSymmSiftingOutOfMem: + + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddSymmSifting */ + + +/**Function******************************************************************** + + Synopsis [Symmetric sifting to convergence algorithm.] + + Description [Symmetric sifting to convergence algorithm. + Assumes that no dead nodes are present. +
                  +
                1. Order all the variables according to the number of entries in + each unique subtable. +
                2. Sift the variable up and down, remembering each time the total + size of the DD heap and grouping variables that are symmetric. +
                3. Select the best permutation. +
                4. Repeat 3 and 4 for all variables. +
                5. Repeat 1-4 until no further improvement. +
                + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddSymmSifting] + +******************************************************************************/ +int +cuddSymmSiftingConv( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; + int symvars; + int symgroups; + int classes; + int initialSize; +#ifdef DD_STATS + int previousSize; +#endif + + initialSize = table->keys - table->isolated; + + size = table->size; + + /* Find order in which to sift variables. */ + var = NULL; + entry = ALLOC(int,size); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingConvOutOfMem; + } + var = ALLOC(int,size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingConvOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; + } + + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); + + /* Initialize the symmetry of each subtable to itself + ** for first pass of converging symmetric sifting. + */ + for (i = lower; i <= upper; i++) { + table->subtables[i].next = i; + } + + for (i = 0; i < ddMin(table->siftMaxVar, table->size); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + x = table->perm[var[i]]; + if (x < lower || x > upper) continue; + /* Only sift if not in symmetry group already. */ + if (table->subtables[x].next == (unsigned) x) { +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSymmSiftingAux(table,x,lower,upper); + if (!result) goto ddSymmSiftingConvOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } + + /* Sifting now until convergence. */ + while ((unsigned) initialSize > table->keys - table->isolated) { + initialSize = table->keys - table->isolated; +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + /* Here we consider only one representative for each symmetry class. */ + for (x = lower, classes = 0; x <= upper; x++, classes++) { + while ((unsigned) x < table->subtables[x].next) { + x = table->subtables[x].next; + } + /* Here x is the largest index in a group. + ** Groups consist of adjacent variables. + ** Hence, the next increment of x will move it to a new group. + */ + i = table->invperm[x]; + entry[i] = table->subtables[x].keys; + var[classes] = i; + } + + qsort((void *)var,classes,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + x = table->perm[var[i]]; + if ((unsigned) x >= table->subtables[x].next) { +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSymmSiftingConvAux(table,x,lower,upper); + if (!result ) goto ddSymmSiftingConvOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } /* for */ + } + + ddSymmSummary(table, lower, upper, &symvars, &symgroups); + +#ifdef DD_STATS + (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n", + symvars); + (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups", + symgroups); +#endif + + FREE(var); + FREE(entry); + + return(1+symvars); + +ddSymmSiftingConvOutOfMem: + + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddSymmSiftingConv */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the variables + according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmUniqueCompare( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of ddSymmUniqueCompare */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is not part of a symmetry group. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; + int i; + int topbot; /* index to either top or bottom of symmetry group */ + int initGroupSize, finalGroupSize; + + +#ifdef DD_DEBUG + /* check for previously detected symmetry */ + assert(table->subtables[x].next == (unsigned) x); +#endif + + initialSize = table->keys - table->isolated; + + moveDown = NULL; + moveUp = NULL; + + if ((x - xLow) > (xHigh - x)) { + /* Will go down first, unless x == xHigh: + ** Look for consecutive symmetries above x. + */ + for (i = x; i > xLow; i--) { + if (!cuddSymmCheck(table,i-1,i)) + break; + topbot = table->subtables[i-1].next; /* find top of i-1's group */ + table->subtables[i-1].next = i; + table->subtables[x].next = topbot; /* x is bottom of group so its */ + /* next is top of i-1's group */ + i = topbot + 1; /* add 1 for i--; new i is top of symm group */ + } + } else { + /* Will go up first unless x == xlow: + ** Look for consecutive symmetries below x. + */ + for (i = x; i < xHigh; i++) { + if (!cuddSymmCheck(table,i,i+1)) + break; + /* find bottom of i+1's symm group */ + topbot = i + 1; + while ((unsigned) topbot < table->subtables[topbot].next) { + topbot = table->subtables[topbot].next; + } + table->subtables[topbot].next = table->subtables[i].next; + table->subtables[i].next = i + 1; + i = topbot - 1; /* subtract 1 for i++; new i is bottom of group */ + } + } + + /* Now x may be in the middle of a symmetry group. + ** Find bottom of x's symm group. + */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + + if (x == xLow) { /* Sift down */ + +#ifdef DD_DEBUG + /* x must be a singleton */ + assert((unsigned) x == table->subtables[x].next); +#endif + if (x == xHigh) return(1); /* just one variable */ + + initGroupSize = 1; + + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* after this point x --> xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + if (moveDown == NULL) return(1); + + x = moveDown->y; + /* Find bottom of x's group */ + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + finalGroupSize = i - x + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; + + } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ + /* Find top of x's symm group */ + i = x; /* bottom */ + x = table->subtables[x].next; /* top */ + + if (x == xLow) return(1); /* just one big group */ + + initGroupSize = i - x + 1; + + moveUp = ddSymmSiftingUp(table,x,xLow); + /* after this point x --> xLow, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + if (moveUp == NULL) return(1); + + x = moveUp->x; + /* Find top of x's group */ + i = table->subtables[x].next; +#ifdef DD_DEBUG + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + finalGroupSize = x - i + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; /* x is top here */ + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + x = table->subtables[i].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + initGroupSize = i - x + 1; + + moveUp = ddSymmSiftingUp(table,x,xLow); + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + finalGroupSize = x - i + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; + + } else { /* moving up first: shorter */ + /* Find top of x's symmetry group */ + x = table->subtables[x].next; + + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xHigh, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x is bottom of the symmetry group and i is top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + initGroupSize = x - i + 1; + + moveDown = ddSymmSiftingDown(table,x,xHigh); + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + finalGroupSize = i - x + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +ddSymmSiftingAuxOutOfMem: + if (moveDown != MV_OOM) { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + } + if (moveUp != MV_OOM) { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + } + + return(0); + +} /* end of ddSymmSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is either an isolated variable, or it is the bottom of + a symmetry group. All symmetries may not have been found, because of + exceeded growth limit. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmSiftingConvAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; + int i; + int initGroupSize, finalGroupSize; + + + initialSize = table->keys - table->isolated; + + moveDown = NULL; + moveUp = NULL; + + if (x == xLow) { /* Sift down */ +#ifdef DD_DEBUG + /* x is bottom of symmetry group */ + assert((unsigned) x >= table->subtables[x].next); +#endif + i = table->subtables[x].next; + initGroupSize = x - i + 1; + + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + if (moveDown == NULL) return(1); + + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetric group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + finalGroupSize = i - x + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingConvAuxOutOfMem; + + } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ + /* Find top of x's symm group */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = x; /* bottom */ + x = table->subtables[x].next; /* top */ + + if (x == xLow) return(1); + + initGroupSize = i - x + 1; + + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xLow, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + if (moveUp == NULL) return(1); + + x = moveUp->x; + i = table->subtables[x].next; +#ifdef DD_DEBUG + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + finalGroupSize = x - i + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) + goto ddSymmSiftingConvAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = x; + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + initGroupSize = i - x + 1; + + moveUp = ddSymmSiftingUp(table,x,xLow); + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + finalGroupSize = x - i + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) goto ddSymmSiftingConvAuxOutOfMem; + + } else { /* moving up first: shorter */ + /* Find top of x's symmetry group */ + x = table->subtables[x].next; + + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xHigh, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x is bottom of the symmetry group and i is top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + initGroupSize = x - i + 1; + + moveDown = ddSymmSiftingDown(table,x,xHigh); + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + finalGroupSize = i - x + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingConvAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +ddSymmSiftingConvAuxOutOfMem: + if (moveDown != MV_OOM) { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + } + if (moveUp != MV_OOM) { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + } + + return(0); + +} /* end of ddSymmSiftingConvAux */ + + +/**Function******************************************************************** + + Synopsis [Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much.] + + Description [Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much. Assumes that x is the top + of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; MV_OOM if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSymmSiftingUp( + DdManager * table, + int y, + int xLow) +{ + Move *moves; + Move *move; + int x; + int size; + int i; + int gxtop,gybot; + int limitSize; + int xindex, yindex; + int zindex; + int z; + int isolated; + int L; /* lower bound on DD size */ +#ifdef DD_DEBUG + int checkL; +#endif + + + moves = NULL; + yindex = table->invperm[y]; + + /* Initialize the lower bound. + ** The part of the DD below the bottom of y' group will not change. + ** The part of the DD above y that does not interact with y will not + ** change. The rest may vanish in the best case, except for + ** the nodes at level xLow, which will not vanish, regardless. + */ + limitSize = L = table->keys - table->isolated; + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L -= table->subtables[z].keys - isolated; + } + } + + x = cuddNextLow(table,y); + while (x >= xLow && L <= limitSize) { +#ifdef DD_DEBUG + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + assert(L == checkL); +#endif + gxtop = table->subtables[x].next; + if (cuddSymmCheck(table,x,y)) { + /* Symmetry found, attach symm groups */ + table->subtables[x].next = y; + i = table->subtables[y].next; + while (table->subtables[i].next != (unsigned) y) + i = table->subtables[i].next; + table->subtables[i].next = gxtop; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y have self symmetry */ + xindex = table->invperm[x]; + size = cuddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); +#endif + if (size == 0) goto ddSymmSiftingUpOutOfMem; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSymmSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + } else { /* Group move */ + size = ddSymmGroupMove(table,x,y,&moves); + if (size == 0) goto ddSymmSiftingUpOutOfMem; + /* Update the lower bound. */ + z = moves->y; + do { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L += table->subtables[z].keys - isolated; + } + z = table->subtables[z].next; + } while (z != (int) moves->y); + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + } + y = gxtop; + x = cuddNextLow(table,y); + } + + return(moves); + +ddSymmSiftingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(MV_OOM); + +} /* end of ddSymmSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Moves x down until either it reaches the bound (xHigh) or + the size of the DD heap increases too much.] + + Description [Moves x down until either it reaches the bound (xHigh) + or the size of the DD heap increases too much. Assumes that x is the + bottom of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; MV_OOM if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSymmSiftingDown( + DdManager * table, + int x, + int xHigh) +{ + Move *moves; + Move *move; + int y; + int size; + int limitSize; + int gxtop,gybot; + int R; /* upper bound on node decrease */ + int xindex, yindex; + int isolated; + int z; + int zindex; +#ifdef DD_DEBUG + int checkR; +#endif + + moves = NULL; + /* Initialize R */ + xindex = table->invperm[x]; + gxtop = table->subtables[x].next; + limitSize = size = table->keys - table->isolated; + R = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } + + y = cuddNextHigh(table,x); + while (y <= xHigh && size - R < limitSize) { +#ifdef DD_DEBUG + gxtop = table->subtables[x].next; + checkR = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + assert(R == checkR); +#endif + gybot = table->subtables[y].next; + while (table->subtables[gybot].next != (unsigned) y) + gybot = table->subtables[gybot].next; + if (cuddSymmCheck(table,x,y)) { + /* Symmetry found, attach symm groups */ + gxtop = table->subtables[x].next; + table->subtables[x].next = y; + table->subtables[gybot].next = gxtop; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y have self symmetry */ + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); +#endif + if (size == 0) goto ddSymmSiftingDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSymmSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + } else { /* Group move */ + /* Update upper bound on node decrease: first phase. */ + gxtop = table->subtables[x].next; + z = gxtop + 1; + do { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R -= table->subtables[z].keys - isolated; + } + z++; + } while (z <= gybot); + size = ddSymmGroupMove(table,x,y,&moves); + if (size == 0) goto ddSymmSiftingDownOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + /* Update upper bound on node decrease: second phase. */ + gxtop = table->subtables[gybot].next; + for (z = gxtop + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } + } + x = gybot; + y = cuddNextHigh(table,x); + } + + return(moves); + +ddSymmSiftingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(MV_OOM); + +} /* end of ddSymmSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Swaps two groups.] + + Description [Swaps two groups. x is assumed to be the bottom variable + of the first group. y is assumed to be the top variable of the second + group. Updates the list of moves. Returns the number of keys in the + table if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmGroupMove( + DdManager * table, + int x, + int y, + Move ** moves) +{ + Move *move; + int size; + int i,j; + int xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + int swapx,swapy; + +#ifdef DD_DEBUG + assert(x < y); /* we assume that x < y */ +#endif + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtables[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtables[ybot].next) + ybot = table->subtables[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + + /* Sift the variables of the second group up through the first group. */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) return(0); + swapx = x; swapy = y; + y = x; + x = y - 1; + } + y = ytop + i; + x = y - 1; + } + + /* fix symmetries */ + y = xtop; /* ytop is now where xtop used to be */ + for (i = 0; i < ysize-1 ; i++) { + table->subtables[y].next = y + 1; + y = y + 1; + } + table->subtables[y].next = xtop; /* y is bottom of its group, join */ + /* its symmetry to top of its group */ + x = y + 1; + newxtop = x; + for (i = 0; i < xsize - 1 ; i++) { + table->subtables[x].next = x + 1; + x = x + 1; + } + table->subtables[x].next = newxtop; /* x is bottom of its group, join */ + /* its symmetry to top of its group */ + /* Store group move */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) return(0); + move->x = swapx; + move->y = swapy; + move->size = size; + move->next = *moves; + *moves = move; + + return(size); + +} /* end of ddSymmGroupMove */ + + +/**Function******************************************************************** + + Synopsis [Undoes the swap of two groups.] + + Description [Undoes the swap of two groups. x is assumed to be the + bottom variable of the first group. y is assumed to be the top + variable of the second group. Returns the number of keys in the table + if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmGroupMoveBackward( + DdManager * table, + int x, + int y) +{ + int size; + int i,j; + int xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + +#ifdef DD_DEBUG + assert(x < y); /* We assume that x < y */ +#endif + + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtables[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtables[ybot].next) + ybot = table->subtables[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + + /* Sift the variables of the second group up through the first group. */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) return(0); + y = x; + x = cuddNextLow(table,y); + } + y = ytop + i; + x = y - 1; + } + + /* Fix symmetries. */ + y = xtop; + for (i = 0; i < ysize-1 ; i++) { + table->subtables[y].next = y + 1; + y = y + 1; + } + table->subtables[y].next = xtop; /* y is bottom of its group, join */ + /* its symmetry to top of its group */ + x = y + 1; + newxtop = x; + for (i = 0; i < xsize-1 ; i++) { + table->subtables[x].next = x + 1; + x = x + 1; + } + table->subtables[x].next = newxtop; /* x is bottom of its group, join */ + /* its symmetry to top of its group */ + + return(size); + +} /* end of ddSymmGroupMoveBackward */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the DD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmSiftingBackward( + DdManager * table, + Move * moves, + int size) +{ + Move *move; + int res; + + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + if (table->subtables[move->x].next == move->x && table->subtables[move->y].next == move->y) { + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); +#ifdef DD_DEBUG + assert(table->subtables[move->x].next == move->x); + assert(table->subtables[move->y].next == move->y); +#endif + } else { /* Group move necessary */ + res = ddSymmGroupMoveBackward(table,(int)move->x,(int)move->y); + } + if (!res) return(0); + } + + return(1); + +} /* end of ddSymmSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Counts numbers of symmetric variables and symmetry + groups.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static void +ddSymmSummary( + DdManager * table, + int lower, + int upper, + int * symvars, + int * symgroups) +{ + int i,x,gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; + + for (i = lower; i <= upper; i++) { + if (table->subtables[i].next != (unsigned) i) { + TotalSymmGroups++; + x = i; + do { + TotalSymm++; + gbot = x; + x = table->subtables[x].next; + } while (x != i); +#ifdef DD_DEBUG + assert(table->subtables[gbot].next == (unsigned) i); +#endif + i = gbot; + } + } + *symvars = TotalSymm; + *symgroups = TotalSymmGroups; + + return; + +} /* end of ddSymmSummary */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddTable.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddTable.c new file mode 100644 index 000000000..b8e989375 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddTable.c @@ -0,0 +1,3213 @@ +/**CFile*********************************************************************** + + FileName [cuddTable.c] + + PackageName [cudd] + + Synopsis [Unique table management functions.] + + Description [External procedures included in this module: +
                  +
                • Cudd_Prime() +
                • Cudd_Reserve() +
                + Internal procedures included in this module: +
                  +
                • cuddAllocNode() +
                • cuddInitTable() +
                • cuddFreeTable() +
                • cuddGarbageCollect() +
                • cuddZddGetNode() +
                • cuddZddGetNodeIVO() +
                • cuddUniqueInter() +
                • cuddUniqueInterIVO() +
                • cuddUniqueInterZdd() +
                • cuddUniqueConst() +
                • cuddRehash() +
                • cuddShrinkSubtable() +
                • cuddInsertSubtables() +
                • cuddDestroySubtables() +
                • cuddResizeTableZdd() +
                • cuddSlowTableGrowth() +
                + Static procedures included in this module: +
                  +
                • ddRehashZdd() +
                • ddResizeTable() +
                • cuddFindParent() +
                • cuddOrderedInsert() +
                • cuddOrderedThread() +
                • cuddRotateLeft() +
                • cuddRotateRight() +
                • cuddDoRebalance() +
                • cuddCheckCollisionOrdering() +
                ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST +/* Constants for red/black trees. */ +#define DD_STACK_SIZE 128 +#define DD_RED 0 +#define DD_BLACK 1 +#define DD_PAGE_SIZE 8192 +#define DD_PAGE_MASK ~(DD_PAGE_SIZE - 1) +#endif +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/* This is a hack for when CUDD_VALUE_TYPE is double */ +typedef union hack { + CUDD_VALUE_TYPE value; + unsigned int bits[2]; +} hack; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.126 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST +/* Macros for red/black trees. */ +#define DD_INSERT_COMPARE(x,y) \ + (((ptruint) (x) & DD_PAGE_MASK) - ((ptruint) (y) & DD_PAGE_MASK)) +#define DD_COLOR(p) ((p)->index) +#define DD_IS_BLACK(p) ((p)->index == DD_BLACK) +#define DD_IS_RED(p) ((p)->index == DD_RED) +#define DD_LEFT(p) cuddT(p) +#define DD_RIGHT(p) cuddE(p) +#define DD_NEXT(p) ((p)->next) +#endif +#endif + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void ddRehashZdd (DdManager *unique, int i); +static int ddResizeTable (DdManager *unique, int index, int amount); +static int cuddFindParent (DdManager *table, DdNode *node); +DD_INLINE static void ddFixLimits (DdManager *unique); +#ifdef DD_RED_BLACK_FREE_LIST +static void cuddOrderedInsert (DdNodePtr *root, DdNodePtr node); +static DdNode * cuddOrderedThread (DdNode *root, DdNode *list); +static void cuddRotateLeft (DdNodePtr *nodeP); +static void cuddRotateRight (DdNodePtr *nodeP); +static void cuddDoRebalance (DdNodePtr **stack, int stackN); +#endif +static void ddPatchTree (DdManager *dd, MtrNode *treenode); +#ifdef DD_DEBUG +static int cuddCheckCollisionOrdering (DdManager *unique, int i, int j); +#endif +static void ddReportRefMess (DdManager *unique, int i, const char *caller); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns the next prime >= p.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +unsigned int +Cudd_Prime( + unsigned int p) +{ + int i,pn; + + p--; + do { + p++; + if (p&1) { + pn = 1; + i = 3; + while ((unsigned) (i * i) <= p) { + if (p % i == 0) { + pn = 0; + break; + } + i += 2; + } + } else { + pn = 0; + } + } while (!pn); + return(p); + +} /* end of Cudd_Prime */ + + +/**Function******************************************************************** + + Synopsis [Expand manager without creating variables.] + + Description [Expand a manager by a specified number of subtables without + actually creating new variables. This function can be used to reduce the + frequency of resizing when an estimate of the number of variables is + available. One would call this function instead of passing the number + of variables to Cudd_Init if variables should not be created right away + of if the estimate on their number became available only after the manager + has been created. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Init] + +******************************************************************************/ +int +Cudd_Reserve( + DdManager *manager, + int amount) +{ + int currentSize = manager->size; + if (amount < 0) + return(0); + if (currentSize + amount < currentSize) /* overflow */ + return(0); + if (amount <= manager->maxSize - manager->size) + return(1); + return ddResizeTable(manager, -1, amount); + +} /* end of Cudd_Reserve */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Fast storage allocation for DdNodes in the table.] + + Description [Fast storage allocation for DdNodes in the table. The + first 4 bytes of a chunk contain a pointer to the next block; the + rest contains DD_MEM_CHUNK spaces for DdNodes. Returns a pointer to + a new node if successful; NULL is memory is full.] + + SideEffects [None] + + SeeAlso [cuddDynamicAllocNode] + +******************************************************************************/ +DdNode * +cuddAllocNode( + DdManager * unique) +{ + int i; + DdNodePtr *mem; + DdNode *list, *node; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (unique->nextFree == NULL) { /* free list is empty */ + /* Check for exceeded limits. */ + if ((unique->keys - unique->dead) + (unique->keysZ - unique->deadZ) > + unique->maxLive) { + unique->errorCode = CUDD_TOO_MANY_NODES; + return(NULL); + } + if (util_cpu_time() - unique->startTime > unique->timeLimit) { + unique->errorCode = CUDD_TIMEOUT_EXPIRED; + return(NULL); + } + if (unique->stash == NULL || unique->memused > unique->maxmemhard) { + (void) cuddGarbageCollect(unique,1); + mem = NULL; + } + if (unique->nextFree == NULL) { + if (unique->memused > unique->maxmemhard) { + unique->errorCode = CUDD_MAX_MEM_EXCEEDED; + return(NULL); + } + /* Try to allocate a new block. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1); + MMoutOfMemory = saveHandler; + if (mem == NULL) { + /* No more memory: Try collecting garbage. If this succeeds, + ** we end up with mem still NULL, but unique->nextFree != + ** NULL. */ + if (cuddGarbageCollect(unique,1) == 0) { + /* Last resort: Free the memory stashed away, if there + ** any. If this succeeeds, mem != NULL and + ** unique->nextFree still NULL. */ + if (unique->stash != NULL) { + FREE(unique->stash); + unique->stash = NULL; + /* Inhibit resizing of tables. */ + cuddSlowTableGrowth(unique); + /* Now try again. */ + mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1); + } + if (mem == NULL) { + /* Out of luck. Call the default handler to do + ** whatever it specifies for a failed malloc. + ** If this handler returns, then set error code, + ** print warning, and return. */ + (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); + unique->errorCode = CUDD_MEMORY_OUT; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "cuddAllocNode: out of memory"); + (void) fprintf(unique->err, "Memory in use = %lu\n", + unique->memused); +#endif + return(NULL); + } + } + } + if (mem != NULL) { /* successful allocation; slice memory */ + ptruint offset; + unique->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); + mem[0] = (DdNodePtr) unique->memoryList; + unique->memoryList = mem; + + /* Here we rely on the fact that a DdNode is as large + ** as 4 pointers. */ + offset = (ptruint) mem & (sizeof(DdNode) - 1); + mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); + assert(((ptruint) mem & (sizeof(DdNode) - 1)) == 0); + list = (DdNode *) mem; + + i = 1; + do { + list[i - 1].ref = 0; + list[i - 1].next = &list[i]; + } while (++i < DD_MEM_CHUNK); + + list[DD_MEM_CHUNK-1].ref = 0; + list[DD_MEM_CHUNK-1].next = NULL; + + unique->nextFree = &list[0]; + } + } + } + unique->allocated++; + node = unique->nextFree; + unique->nextFree = node->next; + return(node); + +} /* end of cuddAllocNode */ + + +/**Function******************************************************************** + + Synopsis [Creates and initializes the unique table.] + + Description [Creates and initializes the unique table. Returns a pointer + to the table if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Init cuddFreeTable] + +******************************************************************************/ +DdManager * +cuddInitTable( + unsigned int numVars /* Initial number of BDD variables (and subtables) */, + unsigned int numVarsZ /* Initial number of ZDD variables (and subtables) */, + unsigned int numSlots /* Initial size of the BDD subtables */, + unsigned int looseUpTo /* Limit for fast table growth */) +{ + DdManager *unique = ALLOC(DdManager,1); + int i, j; + DdNodePtr *nodelist; + DdNode *sentinel; + unsigned int slots; + int shift; + + if (unique == NULL) { + return(NULL); + } + sentinel = &(unique->sentinel); + sentinel->ref = 0; + sentinel->index = 0; + cuddT(sentinel) = NULL; + cuddE(sentinel) = NULL; + sentinel->next = NULL; + unique->epsilon = DD_EPSILON; + unique->size = numVars; + unique->sizeZ = numVarsZ; + unique->maxSize = ddMax(DD_DEFAULT_RESIZE, numVars); + unique->maxSizeZ = ddMax(DD_DEFAULT_RESIZE, numVarsZ); + + /* Adjust the requested number of slots to a power of 2. */ + slots = 8; + while (slots < numSlots) { + slots <<= 1; + } + unique->initSlots = slots; + shift = sizeof(int) * 8 - cuddComputeFloorLog2(slots); + + unique->slots = (numVars + numVarsZ + 1) * slots; + unique->keys = 0; + unique->maxLive = ~0; /* very large number */ + unique->keysZ = 0; + unique->dead = 0; + unique->deadZ = 0; + unique->gcFrac = DD_GC_FRAC_HI; + unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots); + unique->looseUpTo = looseUpTo; + unique->gcEnabled = 1; + unique->allocated = 0; + unique->reclaimed = 0; + unique->subtables = ALLOC(DdSubtable,unique->maxSize); + if (unique->subtables == NULL) { + FREE(unique); + return(NULL); + } + unique->subtableZ = ALLOC(DdSubtable,unique->maxSizeZ); + if (unique->subtableZ == NULL) { + FREE(unique->subtables); + FREE(unique); + return(NULL); + } + unique->perm = ALLOC(int,unique->maxSize); + if (unique->perm == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique); + return(NULL); + } + unique->invperm = ALLOC(int,unique->maxSize); + if (unique->invperm == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique); + return(NULL); + } + unique->permZ = ALLOC(int,unique->maxSizeZ); + if (unique->permZ == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique); + return(NULL); + } + unique->invpermZ = ALLOC(int,unique->maxSizeZ); + if (unique->invpermZ == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique); + return(NULL); + } + unique->map = NULL; + unique->stack = ALLOC(DdNodePtr,ddMax(unique->maxSize,unique->maxSizeZ)+1); + if (unique->stack == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique); + return(NULL); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + +#ifndef DD_NO_DEATH_ROW + unique->deathRowDepth = 1 << cuddComputeFloorLog2(unique->looseUpTo >> 2); + unique->deathRow = ALLOC(DdNodePtr,unique->deathRowDepth); + if (unique->deathRow == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique->stack); + FREE(unique); + return(NULL); + } + for (i = 0; i < unique->deathRowDepth; i++) { + unique->deathRow[i] = NULL; + } + unique->nextDead = 0; + unique->deadMask = unique->deathRowDepth - 1; +#endif + + for (i = 0; (unsigned) i < numVars; i++) { + unique->subtables[i].slots = slots; + unique->subtables[i].shift = shift; + unique->subtables[i].keys = 0; + unique->subtables[i].dead = 0; + unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[i].bindVar = 0; + unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[i].pairIndex = 0; + unique->subtables[i].varHandled = 0; + unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + nodelist = unique->subtables[i].nodelist = ALLOC(DdNodePtr,slots); + if (nodelist == NULL) { + for (j = 0; j < i; j++) { + FREE(unique->subtables[j].nodelist); + } + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique->stack); + FREE(unique); + return(NULL); + } + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = sentinel; + } + unique->perm[i] = i; + unique->invperm[i] = i; + } + for (i = 0; (unsigned) i < numVarsZ; i++) { + unique->subtableZ[i].slots = slots; + unique->subtableZ[i].shift = shift; + unique->subtableZ[i].keys = 0; + unique->subtableZ[i].dead = 0; + unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + nodelist = unique->subtableZ[i].nodelist = ALLOC(DdNodePtr,slots); + if (nodelist == NULL) { + for (j = 0; (unsigned) j < numVars; j++) { + FREE(unique->subtables[j].nodelist); + } + FREE(unique->subtables); + for (j = 0; j < i; j++) { + FREE(unique->subtableZ[j].nodelist); + } + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique->stack); + FREE(unique); + return(NULL); + } + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + unique->permZ[i] = i; + unique->invpermZ[i] = i; + } + unique->constants.slots = slots; + unique->constants.shift = shift; + unique->constants.keys = 0; + unique->constants.dead = 0; + unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + nodelist = unique->constants.nodelist = ALLOC(DdNodePtr,slots); + if (nodelist == NULL) { + for (j = 0; (unsigned) j < numVars; j++) { + FREE(unique->subtables[j].nodelist); + } + FREE(unique->subtables); + for (j = 0; (unsigned) j < numVarsZ; j++) { + FREE(unique->subtableZ[j].nodelist); + } + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique->stack); + FREE(unique); + return(NULL); + } + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + + unique->memoryList = NULL; + unique->nextFree = NULL; + + unique->memused = sizeof(DdManager) + (unique->maxSize + unique->maxSizeZ) + * (sizeof(DdSubtable) + 2 * sizeof(int)) + (numVars + 1) * + slots * sizeof(DdNodePtr) + + (ddMax(unique->maxSize,unique->maxSizeZ) + 1) * sizeof(DdNodePtr); +#ifndef DD_NO_DEATH_ROW + unique->memused += unique->deathRowDepth * sizeof(DdNodePtr); +#endif + + /* Initialize fields concerned with automatic dynamic reordering. */ + unique->reordered = 0; + unique->reorderings = 0; + unique->maxReorderings = ~0; + unique->siftMaxVar = DD_SIFT_MAX_VAR; + unique->siftMaxSwap = DD_SIFT_MAX_SWAPS; + unique->maxGrowth = DD_MAX_REORDER_GROWTH; + unique->maxGrowthAlt = 2.0 * DD_MAX_REORDER_GROWTH; + unique->reordCycle = 0; /* do not use alternate threshold */ + unique->autoDyn = 0; /* initially disabled */ + unique->autoDynZ = 0; /* initially disabled */ + unique->autoMethod = CUDD_REORDER_SIFT; + unique->autoMethodZ = CUDD_REORDER_SIFT; + unique->realign = 0; /* initially disabled */ + unique->realignZ = 0; /* initially disabled */ + unique->nextDyn = DD_FIRST_REORDER; + unique->countDead = ~0; + unique->tree = NULL; + unique->treeZ = NULL; + unique->groupcheck = CUDD_GROUP_CHECK7; + unique->recomb = DD_DEFAULT_RECOMB; + unique->symmviolation = 0; + unique->arcviolation = 0; + unique->populationSize = 0; + unique->numberXovers = 0; + unique->randomizeOrder = 0; + unique->linear = NULL; + unique->linearSize = 0; + + /* Initialize ZDD universe. */ + unique->univ = (DdNodePtr *)NULL; + + /* Initialize auxiliary fields. */ + unique->localCaches = NULL; + unique->preGCHook = NULL; + unique->postGCHook = NULL; + unique->preReorderingHook = NULL; + unique->postReorderingHook = NULL; + unique->out = stdout; + unique->err = stderr; + unique->errorCode = CUDD_NO_ERROR; + unique->startTime = util_cpu_time(); + unique->timeLimit = ~0UL; + + /* Initialize statistical counters. */ + unique->maxmemhard = ~ 0UL; + unique->garbageCollections = 0; + unique->GCTime = 0; + unique->reordTime = 0; +#ifdef DD_STATS + unique->nodesDropped = 0; + unique->nodesFreed = 0; +#endif + unique->peakLiveNodes = 0; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLookUps = 0; + unique->uniqueLinks = 0; +#endif +#ifdef DD_COUNT + unique->recursiveCalls = 0; + unique->swapSteps = 0; +#ifdef DD_STATS + unique->nextSample = 250000; +#endif +#endif + + return(unique); + +} /* end of cuddInitTable */ + + +/**Function******************************************************************** + + Synopsis [Frees the resources associated to a unique table.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddInitTable] + +******************************************************************************/ +void +cuddFreeTable( + DdManager * unique) +{ + DdNodePtr *next; + DdNodePtr *memlist = unique->memoryList; + int i; + + if (unique->univ != NULL) cuddZddFreeUniv(unique); + while (memlist != NULL) { + next = (DdNodePtr *) memlist[0]; /* link to next block */ + FREE(memlist); + memlist = next; + } + unique->nextFree = NULL; + unique->memoryList = NULL; + + for (i = 0; i < unique->size; i++) { + FREE(unique->subtables[i].nodelist); + } + for (i = 0; i < unique->sizeZ; i++) { + FREE(unique->subtableZ[i].nodelist); + } + FREE(unique->constants.nodelist); + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->acache); + FREE(unique->perm); + FREE(unique->permZ); + FREE(unique->invperm); + FREE(unique->invpermZ); + FREE(unique->vars); + if (unique->map != NULL) FREE(unique->map); + FREE(unique->stack); +#ifndef DD_NO_DEATH_ROW + FREE(unique->deathRow); +#endif + if (unique->tree != NULL) Mtr_FreeTree(unique->tree); + if (unique->treeZ != NULL) Mtr_FreeTree(unique->treeZ); + if (unique->linear != NULL) FREE(unique->linear); + while (unique->preGCHook != NULL) + Cudd_RemoveHook(unique,unique->preGCHook->f,CUDD_PRE_GC_HOOK); + while (unique->postGCHook != NULL) + Cudd_RemoveHook(unique,unique->postGCHook->f,CUDD_POST_GC_HOOK); + while (unique->preReorderingHook != NULL) + Cudd_RemoveHook(unique,unique->preReorderingHook->f, + CUDD_PRE_REORDERING_HOOK); + while (unique->postReorderingHook != NULL) + Cudd_RemoveHook(unique,unique->postReorderingHook->f, + CUDD_POST_REORDERING_HOOK); + FREE(unique); + +} /* end of cuddFreeTable */ + + +/**Function******************************************************************** + + Synopsis [Performs garbage collection on the unique tables.] + + Description [Performs garbage collection on the BDD and ZDD unique tables. + If clearCache is 0, the cache is not cleared. This should only be + specified if the cache has been cleared right before calling + cuddGarbageCollect. (As in the case of dynamic reordering.) + Returns the total number of deleted nodes.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddGarbageCollect( + DdManager * unique, + int clearCache) +{ + DdHook *hook; + DdCache *cache = unique->cache; + DdNode *sentinel = &(unique->sentinel); + DdNodePtr *nodelist; + int i, j, deleted, totalDeleted, totalDeletedZ; + DdCache *c; + DdNode *node,*next; + DdNodePtr *lastP; + int slots; + unsigned long localTime; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + DdNodePtr tree; +#else + DdNodePtr *memListTrav, *nxtNode; + DdNode *downTrav, *sentry; + int k; +#endif +#endif + +#ifndef DD_NO_DEATH_ROW + cuddClearDeathRow(unique); +#endif + + hook = unique->preGCHook; + while (hook != NULL) { + int res = (hook->f)(unique,"DD",NULL); + if (res == 0) return(0); + hook = hook->next; + } + + if (unique->dead + unique->deadZ == 0) { + hook = unique->postGCHook; + while (hook != NULL) { + int res = (hook->f)(unique,"DD",NULL); + if (res == 0) return(0); + hook = hook->next; + } + return(0); + } + + /* If many nodes are being reclaimed, we want to resize the tables + ** more aggressively, to reduce the frequency of garbage collection. + */ + if (clearCache && unique->gcFrac == DD_GC_FRAC_LO && + unique->slots <= unique->looseUpTo && unique->stash != NULL) { + unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots); +#ifdef DD_VERBOSE + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_HI); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); +#endif + unique->gcFrac = DD_GC_FRAC_HI; + return(0); + } + + localTime = util_cpu_time(); + + unique->garbageCollections++; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "garbage collecting (%d dead BDD nodes out of %d, min %d)...", + unique->dead, unique->keys, unique->minDead); + (void) fprintf(unique->err, + " (%d dead ZDD nodes out of %d)...", + unique->deadZ, unique->keysZ); +#endif + + /* Remove references to garbage collected nodes from the cache. */ + if (clearCache) { + slots = unique->cacheSlots; + for (i = 0; i < slots; i++) { + c = &cache[i]; + if (c->data != NULL) { + if (cuddClean(c->f)->ref == 0 || + cuddClean(c->g)->ref == 0 || + (((ptruint)c->f & 0x2) && Cudd_Regular(c->h)->ref == 0) || + (c->data != DD_NON_CONSTANT && + Cudd_Regular(c->data)->ref == 0)) { + c->data = NULL; + unique->cachedeletions++; + } + } + } + cuddLocalCacheClearDead(unique); + } + + /* Now return dead nodes to free list. Count them for sanity check. */ + totalDeleted = 0; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + tree = NULL; +#endif +#endif + + for (i = 0; i < unique->size; i++) { + if (unique->subtables[i].dead == 0) continue; + nodelist = unique->subtables[i].nodelist; + + deleted = 0; + slots = unique->subtables[i].slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != sentinel) { + next = node->next; + if (node->ref == 0) { + deleted++; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + cuddOrderedInsert(&tree,node); +#endif +#else + cuddDeallocNode(unique,node); +#endif + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = sentinel; + } + if ((unsigned) deleted != unique->subtables[i].dead) { + ddReportRefMess(unique, i, "cuddGarbageCollect"); + } + totalDeleted += deleted; + unique->subtables[i].keys -= deleted; + unique->subtables[i].dead = 0; + } + if (unique->constants.dead != 0) { + nodelist = unique->constants.nodelist; + deleted = 0; + slots = unique->constants.slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != NULL) { + next = node->next; + if (node->ref == 0) { + deleted++; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + cuddOrderedInsert(&tree,node); +#endif +#else + cuddDeallocNode(unique,node); +#endif + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = NULL; + } + if ((unsigned) deleted != unique->constants.dead) { + ddReportRefMess(unique, CUDD_CONST_INDEX, "cuddGarbageCollect"); + } + totalDeleted += deleted; + unique->constants.keys -= deleted; + unique->constants.dead = 0; + } + if ((unsigned) totalDeleted != unique->dead) { + ddReportRefMess(unique, -1, "cuddGarbageCollect"); + } + unique->keys -= totalDeleted; + unique->dead = 0; +#ifdef DD_STATS + unique->nodesFreed += (double) totalDeleted; +#endif + + totalDeletedZ = 0; + + for (i = 0; i < unique->sizeZ; i++) { + if (unique->subtableZ[i].dead == 0) continue; + nodelist = unique->subtableZ[i].nodelist; + + deleted = 0; + slots = unique->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != NULL) { + next = node->next; + if (node->ref == 0) { + deleted++; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + cuddOrderedInsert(&tree,node); +#endif +#else + cuddDeallocNode(unique,node); +#endif + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = NULL; + } + if ((unsigned) deleted != unique->subtableZ[i].dead) { + ddReportRefMess(unique, i, "cuddGarbageCollect"); + } + totalDeletedZ += deleted; + unique->subtableZ[i].keys -= deleted; + unique->subtableZ[i].dead = 0; + } + + /* No need to examine the constant table for ZDDs. + ** If we did we should be careful not to count whatever dead + ** nodes we found there among the dead ZDD nodes. */ + if ((unsigned) totalDeletedZ != unique->deadZ) { + ddReportRefMess(unique, -1, "cuddGarbageCollect"); + } + unique->keysZ -= totalDeletedZ; + unique->deadZ = 0; +#ifdef DD_STATS + unique->nodesFreed += (double) totalDeletedZ; +#endif + + +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + unique->nextFree = cuddOrderedThread(tree,unique->nextFree); +#else + memListTrav = unique->memoryList; + sentry = NULL; + while (memListTrav != NULL) { + ptruint offset; + nxtNode = (DdNodePtr *)memListTrav[0]; + offset = (ptruint) memListTrav & (sizeof(DdNode) - 1); + memListTrav += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); + downTrav = (DdNode *)memListTrav; + k = 0; + do { + if (downTrav[k].ref == 0) { + if (sentry == NULL) { + unique->nextFree = sentry = &downTrav[k]; + } else { + /* First hook sentry->next to the dead node and then + ** reassign sentry to the dead node. */ + sentry = (sentry->next = &downTrav[k]); + } + } + } while (++k < DD_MEM_CHUNK); + memListTrav = nxtNode; + } + sentry->next = NULL; +#endif +#endif + + unique->GCTime += util_cpu_time() - localTime; + + hook = unique->postGCHook; + while (hook != NULL) { + int res = (hook->f)(unique,"DD",NULL); + if (res == 0) return(0); + hook = hook->next; + } + +#ifdef DD_VERBOSE + (void) fprintf(unique->err," done\n"); +#endif + + return(totalDeleted+totalDeletedZ); + +} /* end of cuddGarbageCollect */ + + +/**Function******************************************************************** + + Synopsis [Wrapper for cuddUniqueInterZdd.] + + Description [Wrapper for cuddUniqueInterZdd, which applies the ZDD + reduction rule. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted.] + + SideEffects [None] + + SeeAlso [cuddUniqueInterZdd] + +******************************************************************************/ +DdNode * +cuddZddGetNode( + DdManager * zdd, + int id, + DdNode * T, + DdNode * E) +{ + DdNode *node; + + if (T == DD_ZERO(zdd)) + return(E); + node = cuddUniqueInterZdd(zdd, id, T, E); + return(node); + +} /* end of cuddZddGetNode */ + + +/**Function******************************************************************** + + Synopsis [Wrapper for cuddUniqueInterZdd that is independent of variable + ordering.] + + Description [Wrapper for cuddUniqueInterZdd that is independent of + variable ordering (IVO). This function does not require parameter + index to precede the indices of the top nodes of g and h in the + variable order. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted.] + + SideEffects [None] + + SeeAlso [cuddZddGetNode cuddZddIsop] + +******************************************************************************/ +DdNode * +cuddZddGetNodeIVO( + DdManager * dd, + int index, + DdNode * g, + DdNode * h) +{ + DdNode *f, *r, *t; + DdNode *zdd_one = DD_ONE(dd); + DdNode *zdd_zero = DD_ZERO(dd); + + f = cuddUniqueInterZdd(dd, index, zdd_one, zdd_zero); + if (f == NULL) { + return(NULL); + } + cuddRef(f); + t = cuddZddProduct(dd, f, g); + if (t == NULL) { + Cudd_RecursiveDerefZdd(dd, f); + return(NULL); + } + cuddRef(t); + Cudd_RecursiveDerefZdd(dd, f); + r = cuddZddUnion(dd, t, h); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, t); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDerefZdd(dd, t); + + cuddDeref(r); + return(r); + +} /* end of cuddZddGetNodeIVO */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for the existence of an internal node.] + + Description [Checks the unique table for the existence of an internal + node. If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. For a newly + created node, increments the reference counts of what T and E point + to. Returns a pointer to the new node if successful; NULL if memory + is exhausted or if reordering took place.] + + SideEffects [None] + + SeeAlso [cuddUniqueInterZdd] + +******************************************************************************/ +DdNode * +cuddUniqueInter( + DdManager * unique, + int index, + DdNode * T, + DdNode * E) +{ + int pos; + unsigned int level; + int retval; + DdNodePtr *nodelist; + DdNode *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int gcNumber; + +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLookUps++; +#endif + + if ((0x1ffffUL & (unsigned long) unique->cacheMisses) == 0) { + if (util_cpu_time() - unique->startTime > unique->timeLimit) { + unique->errorCode = CUDD_TIMEOUT_EXPIRED; + return(NULL); + } + } + if (index >= unique->size) { + int amount = ddMax(DD_DEFAULT_RESIZE,unique->size/20); + if (!ddResizeTable(unique,index,amount)) return(NULL); + } + + level = unique->perm[index]; + subtable = &(unique->subtables[level]); + +#ifdef DD_DEBUG + assert(level < (unsigned) cuddI(unique,T->index)); + assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index)); +#endif + + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + while (T == cuddT(looking) && E < cuddE(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + if (T == cuddT(looking) && E == cuddE(looking)) { + if (looking->ref == 0) { + cuddReclaim(unique,looking); + } + return(looking); + } + + /* countDead is 0 if deads should be counted and ~0 if they should not. */ + if (unique->autoDyn && + unique->keys - (unique->dead & unique->countDead) >= unique->nextDyn && + unique->maxReorderings > 0) { + unsigned long cpuTime; +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(unique); + if (retval != 0) return(NULL); + retval = Cudd_CheckKeys(unique); + if (retval != 0) return(NULL); +#endif + retval = Cudd_ReduceHeap(unique,unique->autoMethod,10); /* 10 = whatever */ + unique->maxReorderings--; + if (retval == 0) { + unique->reordered = 2; + } else if ((cpuTime = util_cpu_time()) - unique->startTime > unique->timeLimit) { + unique->errorCode = CUDD_TIMEOUT_EXPIRED; + unique->reordered = 0; + } else if (unique->timeLimit - (cpuTime - unique->startTime) + < unique->reordTime) { + unique->autoDyn = 0; + } +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(unique); + if (retval != 0) unique->reordered = 2; + retval = Cudd_CheckKeys(unique); + if (retval != 0) unique->reordered = 2; +#endif + return(NULL); + } + + if (subtable->keys > subtable->maxKeys) { + if (unique->gcEnabled && + ((unique->dead > unique->minDead) || + ((unique->dead > unique->minDead / 2) && + (subtable->dead > subtable->keys * 0.95)))) { /* too many dead */ + if (util_cpu_time() - unique->startTime > unique->timeLimit) { + unique->errorCode = CUDD_TIMEOUT_EXPIRED; + return(NULL); + } + (void) cuddGarbageCollect(unique,1); + } else { + cuddRehash(unique,(int)level); + } + /* Update pointer to insertion point. In the case of rehashing, + ** the slot may have changed. In the case of garbage collection, + ** the predecessor may have been dead. */ + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + while (T == cuddT(looking) && E < cuddE(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + } + + gcNumber = unique->garbageCollections; + looking = cuddAllocNode(unique); + if (looking == NULL) { + return(NULL); + } + unique->keys++; + subtable->keys++; + + if (gcNumber != unique->garbageCollections) { + DdNode *looking2; + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + previousP = &(nodelist[pos]); + looking2 = *previousP; + + while (T < cuddT(looking2)) { + previousP = &(looking2->next); + looking2 = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + while (T == cuddT(looking2) && E < cuddE(looking2)) { + previousP = &(looking2->next); + looking2 = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + } + looking->index = index; + cuddT(looking) = T; + cuddE(looking) = E; + looking->next = *previousP; + *previousP = looking; + cuddSatInc(T->ref); /* we know T is a regular pointer */ + cuddRef(E); + +#ifdef DD_DEBUG + cuddCheckCollisionOrdering(unique,level,pos); +#endif + + return(looking); + +} /* end of cuddUniqueInter */ + + +/**Function******************************************************************** + + Synopsis [Wrapper for cuddUniqueInter that is independent of variable + ordering.] + + Description [Wrapper for cuddUniqueInter that is independent of + variable ordering (IVO). This function does not require parameter + index to precede the indices of the top nodes of T and E in the + variable order. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted.] + + SideEffects [None] + + SeeAlso [cuddUniqueInter Cudd_MakeBddFromZddCover] + +******************************************************************************/ +DdNode * +cuddUniqueInterIVO( + DdManager * unique, + int index, + DdNode * T, + DdNode * E) +{ + DdNode *result; + DdNode *v; + + v = cuddUniqueInter(unique, index, DD_ONE(unique), + Cudd_Not(DD_ONE(unique))); + if (v == NULL) + return(NULL); + /* Since v is a projection function, we can skip the call to cuddRef. */ + result = cuddBddIteRecur(unique, v, T, E); + return(result); + +} /* end of cuddUniqueInterIVO */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for the existence of an internal + ZDD node.] + + Description [Checks the unique table for the existence of an internal + ZDD node. If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. For a newly + created node, increments the reference counts of what T and E point + to. Returns a pointer to the new node if successful; NULL if memory + is exhausted or if reordering took place.] + + SideEffects [None] + + SeeAlso [cuddUniqueInter] + +******************************************************************************/ +DdNode * +cuddUniqueInterZdd( + DdManager * unique, + int index, + DdNode * T, + DdNode * E) +{ + int pos; + unsigned int level; + int retval; + DdNodePtr *nodelist; + DdNode *looking; + DdSubtable *subtable; + +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLookUps++; +#endif + + if (index >= unique->sizeZ) { + if (!cuddResizeTableZdd(unique,index)) return(NULL); + } + + level = unique->permZ[index]; + subtable = &(unique->subtableZ[level]); + +#ifdef DD_DEBUG + assert(level < (unsigned) cuddIZ(unique,T->index)); + assert(level < (unsigned) cuddIZ(unique,Cudd_Regular(E)->index)); +#endif + + if (subtable->keys > subtable->maxKeys) { + if (unique->gcEnabled && ((unique->deadZ > unique->minDead) || + (10 * subtable->dead > 9 * subtable->keys))) { /* too many dead */ + (void) cuddGarbageCollect(unique,1); + } else { + ddRehashZdd(unique,(int)level); + } + } + + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + looking = nodelist[pos]; + + while (looking != NULL) { + if (cuddT(looking) == T && cuddE(looking) == E) { + if (looking->ref == 0) { + cuddReclaimZdd(unique,looking); + } + return(looking); + } + looking = looking->next; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + + /* countDead is 0 if deads should be counted and ~0 if they should not. */ + if (unique->autoDynZ && + unique->keysZ - (unique->deadZ & unique->countDead) >= unique->nextDyn) { +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(unique); + if (retval != 0) return(NULL); + retval = Cudd_CheckKeys(unique); + if (retval != 0) return(NULL); +#endif + retval = Cudd_zddReduceHeap(unique,unique->autoMethodZ,10); /* 10 = whatever */ + if (retval == 0) unique->reordered = 2; +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(unique); + if (retval != 0) unique->reordered = 2; + retval = Cudd_CheckKeys(unique); + if (retval != 0) unique->reordered = 2; +#endif + return(NULL); + } + + unique->keysZ++; + subtable->keys++; + + looking = cuddAllocNode(unique); + if (looking == NULL) return(NULL); + looking->index = index; + cuddT(looking) = T; + cuddE(looking) = E; + looking->next = nodelist[pos]; + nodelist[pos] = looking; + cuddRef(T); + cuddRef(E); + + return(looking); + +} /* end of cuddUniqueInterZdd */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for the existence of a constant node.] + + Description [Checks the unique table for the existence of a constant node. + If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. Returns a + pointer to the new node.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddUniqueConst( + DdManager * unique, + CUDD_VALUE_TYPE value) +{ + int pos; + DdNodePtr *nodelist; + DdNode *looking; + hack split; + +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLookUps++; +#endif + + if (unique->constants.keys > unique->constants.maxKeys) { + if (unique->gcEnabled && ((unique->dead > unique->minDead) || + (10 * unique->constants.dead > 9 * unique->constants.keys))) { /* too many dead */ + (void) cuddGarbageCollect(unique,1); + } else { + cuddRehash(unique,CUDD_CONST_INDEX); + } + } + + cuddAdjust(value); /* for the case of crippled infinities */ + + if (ddAbs(value) < unique->epsilon) { + value = 0.0; + } + split.value = value; + + pos = ddHash(split.bits[0], split.bits[1], unique->constants.shift); + nodelist = unique->constants.nodelist; + looking = nodelist[pos]; + + /* Here we compare values both for equality and for difference less + * than epsilon. The first comparison is required when values are + * infinite, since Infinity - Infinity is NaN and NaN < X is 0 for + * every X. + */ + while (looking != NULL) { + if (looking->type.value == value || + ddEqualVal(looking->type.value,value,unique->epsilon)) { + if (looking->ref == 0) { + cuddReclaim(unique,looking); + } + return(looking); + } + looking = looking->next; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + + unique->keys++; + unique->constants.keys++; + + looking = cuddAllocNode(unique); + if (looking == NULL) return(NULL); + looking->index = CUDD_CONST_INDEX; + looking->type.value = value; + looking->next = nodelist[pos]; + nodelist[pos] = looking; + + return(looking); + +} /* end of cuddUniqueConst */ + + +/**Function******************************************************************** + + Synopsis [Rehashes a unique subtable.] + + Description [Doubles the size of a unique subtable and rehashes its + contents.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddRehash( + DdManager * unique, + int i) +{ + unsigned int slots, oldslots; + int shift, oldshift; + int j, pos; + DdNodePtr *nodelist, *oldnodelist; + DdNode *node, *next; + DdNode *sentinel = &(unique->sentinel); + hack split; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (unique->gcFrac == DD_GC_FRAC_HI && unique->slots > unique->looseUpTo) { + unique->gcFrac = DD_GC_FRAC_LO; + unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); +#ifdef DD_VERBOSE + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_LO); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); +#endif + } + + if (unique->gcFrac != DD_GC_FRAC_MIN && unique->memused > unique->maxmem) { + unique->gcFrac = DD_GC_FRAC_MIN; + unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots); +#ifdef DD_VERBOSE + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_MIN); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); +#endif + cuddShrinkDeathRow(unique); + if (cuddGarbageCollect(unique,1) > 0) return; + } + + if (i != CUDD_CONST_INDEX) { + oldslots = unique->subtables[i].slots; + oldshift = unique->subtables[i].shift; + oldnodelist = unique->subtables[i].nodelist; + + /* Compute the new size of the subtable. */ + slots = oldslots << 1; + shift = oldshift - 1; + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + (void) fprintf(unique->err, + "Unable to resize subtable %d for lack of memory\n", + i); + /* Prevent frequent resizing attempts. */ + (void) cuddGarbageCollect(unique,1); + if (unique->stash != NULL) { + FREE(unique->stash); + unique->stash = NULL; + /* Inhibit resizing of tables. */ + cuddSlowTableGrowth(unique); + } + return; + } + unique->subtables[i].nodelist = nodelist; + unique->subtables[i].slots = slots; + unique->subtables[i].shift = shift; + unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + + /* Move the nodes from the old table to the new table. + ** This code depends on the type of hash function. + ** It assumes that the effect of doubling the size of the table + ** is to retain one more bit of the 32-bit hash value. + ** The additional bit is the LSB. */ + for (j = 0; (unsigned) j < oldslots; j++) { + DdNodePtr *evenP, *oddP; + node = oldnodelist[j]; + evenP = &(nodelist[j<<1]); + oddP = &(nodelist[(j<<1)+1]); + while (node != sentinel) { + next = node->next; + pos = ddHash(cuddT(node), cuddE(node), shift); + if (pos & 1) { + *oddP = node; + oddP = &(node->next); + } else { + *evenP = node; + evenP = &(node->next); + } + node = next; + } + *evenP = *oddP = sentinel; + } + FREE(oldnodelist); + +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "rehashing layer %d: keys %d dead %d new size %d\n", + i, unique->subtables[i].keys, + unique->subtables[i].dead, slots); +#endif + } else { + oldslots = unique->constants.slots; + oldshift = unique->constants.shift; + oldnodelist = unique->constants.nodelist; + + /* The constant subtable is never subjected to reordering. + ** Therefore, when it is resized, it is because it has just + ** reached the maximum load. We can safely just double the size, + ** with no need for the loop we use for the other tables. + */ + slots = oldslots << 1; + shift = oldshift - 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + (void) fprintf(unique->err, + "Unable to resize constant subtable for lack of memory\n"); + (void) cuddGarbageCollect(unique,1); + for (j = 0; j < unique->size; j++) { + unique->subtables[j].maxKeys <<= 1; + } + unique->constants.maxKeys <<= 1; + return; + } + unique->constants.slots = slots; + unique->constants.shift = shift; + unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + unique->constants.nodelist = nodelist; + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + split.value = cuddV(node); + pos = ddHash(split.bits[0], split.bits[1], shift); + node->next = nodelist[pos]; + nodelist[pos] = node; + node = next; + } + } + FREE(oldnodelist); + +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "rehashing constants: keys %d dead %d new size %d\n", + unique->constants.keys,unique->constants.dead,slots); +#endif + } + + /* Update global data */ + + unique->memused += (slots - oldslots) * sizeof(DdNodePtr); + unique->slots += (slots - oldslots); + ddFixLimits(unique); + +} /* end of cuddRehash */ + + +/**Function******************************************************************** + + Synopsis [Shrinks a subtable.] + + Description [Shrinks a subtable.] + + SideEffects [None] + + SeeAlso [cuddRehash] + +******************************************************************************/ +void +cuddShrinkSubtable( + DdManager *unique, + int i) +{ + int j; + int shift, posn; + DdNodePtr *nodelist, *oldnodelist; + DdNode *node, *next; + DdNode *sentinel = &(unique->sentinel); + unsigned int slots, oldslots; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + oldnodelist = unique->subtables[i].nodelist; + oldslots = unique->subtables[i].slots; + slots = oldslots >> 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + return; + } + unique->subtables[i].nodelist = nodelist; + unique->subtables[i].slots = slots; + unique->subtables[i].shift++; + unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "shrunk layer %d (%d keys) from %d to %d slots\n", + i, unique->subtables[i].keys, oldslots, slots); +#endif + + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = sentinel; + } + shift = unique->subtables[i].shift; + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != sentinel) { + DdNode *looking, *T, *E; + DdNodePtr *previousP; + next = node->next; + posn = ddHash(cuddT(node), cuddE(node), shift); + previousP = &(nodelist[posn]); + looking = *previousP; + T = cuddT(node); + E = cuddE(node); + while (T < cuddT(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + while (T == cuddT(looking) && E < cuddE(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + node->next = *previousP; + *previousP = node; + node = next; + } + } + FREE(oldnodelist); + + unique->memused += ((long) slots - (long) oldslots) * sizeof(DdNode *); + unique->slots += slots - oldslots; + unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); + unique->cacheSlack = (int) + ddMin(unique->maxCacheHard,DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) + - 2 * (int) unique->cacheSlots; + +} /* end of cuddShrinkSubtable */ + + +/**Function******************************************************************** + + Synopsis [Inserts n new subtables in a unique table at level.] + + Description [Inserts n new subtables in a unique table at level. + The number n should be positive, and level should be an existing level. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddDestroySubtables] + +******************************************************************************/ +int +cuddInsertSubtables( + DdManager * unique, + int n, + int level) +{ + DdSubtable *newsubtables; + DdNodePtr *newnodelist; + DdNodePtr *newvars; + DdNode *sentinel = &(unique->sentinel); + int oldsize,newsize; + int i,j,index,reorderSave; + unsigned int numSlots = unique->initSlots; + int *newperm, *newinvperm, *newmap; + DdNode *one, *zero; + +#ifdef DD_DEBUG + assert(n > 0 && level < unique->size); +#endif + + oldsize = unique->size; + /* Easy case: there is still room in the current table. */ + if (oldsize + n <= unique->maxSize) { + /* Shift the tables at and below level. */ + for (i = oldsize - 1; i >= level; i--) { + unique->subtables[i+n].slots = unique->subtables[i].slots; + unique->subtables[i+n].shift = unique->subtables[i].shift; + unique->subtables[i+n].keys = unique->subtables[i].keys; + unique->subtables[i+n].maxKeys = unique->subtables[i].maxKeys; + unique->subtables[i+n].dead = unique->subtables[i].dead; + unique->subtables[i+n].nodelist = unique->subtables[i].nodelist; + unique->subtables[i+n].bindVar = unique->subtables[i].bindVar; + unique->subtables[i+n].varType = unique->subtables[i].varType; + unique->subtables[i+n].pairIndex = unique->subtables[i].pairIndex; + unique->subtables[i+n].varHandled = unique->subtables[i].varHandled; + unique->subtables[i+n].varToBeGrouped = + unique->subtables[i].varToBeGrouped; + + index = unique->invperm[i]; + unique->invperm[i+n] = index; + unique->perm[index] += n; + } + /* Create new subtables. */ + for (i = 0; i < n; i++) { + unique->subtables[level+i].slots = numSlots; + unique->subtables[level+i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtables[level+i].keys = 0; + unique->subtables[level+i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[level+i].dead = 0; + unique->subtables[level+i].bindVar = 0; + unique->subtables[level+i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[level+i].pairIndex = 0; + unique->subtables[level+i].varHandled = 0; + unique->subtables[level+i].varToBeGrouped = CUDD_LAZY_NONE; + + unique->perm[oldsize+i] = level + i; + unique->invperm[level+i] = oldsize + i; + newnodelist = unique->subtables[level+i].nodelist = + ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + if (unique->map != NULL) { + for (i = 0; i < n; i++) { + unique->map[oldsize+i] = oldsize + i; + } + } + } else { + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables. + */ + newsize = oldsize + n + DD_DEFAULT_RESIZE; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "Increasing the table size from %d to %d\n", + unique->maxSize, newsize); +#endif + /* Allocate memory for new arrays (except nodelists). */ + newsubtables = ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newvars = ALLOC(DdNodePtr,newsize); + if (newvars == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + FREE(newsubtables); + return(0); + } + newperm = ALLOC(int,newsize); + if (newperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + FREE(newsubtables); + FREE(newvars); + return(0); + } + newinvperm = ALLOC(int,newsize); + if (newinvperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + return(0); + } + if (unique->map != NULL) { + newmap = ALLOC(int,newsize); + if (newmap == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + FREE(newinvperm); + return(0); + } + unique->memused += (newsize - unique->maxSize) * sizeof(int); + } + unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + /* Copy levels before insertion points from old tables. */ + for (i = 0; i < level; i++) { + newsubtables[i].slots = unique->subtables[i].slots; + newsubtables[i].shift = unique->subtables[i].shift; + newsubtables[i].keys = unique->subtables[i].keys; + newsubtables[i].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i].dead = unique->subtables[i].dead; + newsubtables[i].nodelist = unique->subtables[i].nodelist; + newsubtables[i].bindVar = unique->subtables[i].bindVar; + newsubtables[i].varType = unique->subtables[i].varType; + newsubtables[i].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i].varHandled = unique->subtables[i].varHandled; + newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + newperm[i] = unique->perm[i]; + newinvperm[i] = unique->invperm[i]; + } + /* Finish initializing permutation for new table to old one. */ + for (i = level; i < oldsize; i++) { + newperm[i] = unique->perm[i]; + } + /* Initialize new levels. */ + for (i = level; i < level + n; i++) { + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newsubtables[i].bindVar = 0; + newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + newsubtables[i].pairIndex = 0; + newsubtables[i].varHandled = 0; + newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + newperm[oldsize + i - level] = i; + newinvperm[i] = oldsize + i - level; + newnodelist = newsubtables[i].nodelist = ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + /* We are going to leak some memory. We should clean up. */ + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + /* Copy the old tables for levels past the insertion point. */ + for (i = level; i < oldsize; i++) { + newsubtables[i+n].slots = unique->subtables[i].slots; + newsubtables[i+n].shift = unique->subtables[i].shift; + newsubtables[i+n].keys = unique->subtables[i].keys; + newsubtables[i+n].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i+n].dead = unique->subtables[i].dead; + newsubtables[i+n].nodelist = unique->subtables[i].nodelist; + newsubtables[i+n].bindVar = unique->subtables[i].bindVar; + newsubtables[i+n].varType = unique->subtables[i].varType; + newsubtables[i+n].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i+n].varHandled = unique->subtables[i].varHandled; + newsubtables[i+n].varToBeGrouped = + unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + index = unique->invperm[i]; + newinvperm[i+n] = index; + newperm[index] += n; + } + /* Update the map. */ + if (unique->map != NULL) { + for (i = 0; i < oldsize; i++) { + newmap[i] = unique->map[i]; + } + for (i = oldsize; i < oldsize + n; i++) { + newmap[i] = i; + } + FREE(unique->map); + unique->map = newmap; + } + /* Install the new tables and free the old ones. */ + FREE(unique->subtables); + unique->subtables = newsubtables; + unique->maxSize = newsize; + FREE(unique->vars); + unique->vars = newvars; + FREE(unique->perm); + unique->perm = newperm; + FREE(unique->invperm); + unique->invperm = newinvperm; + /* Update the stack for iterative procedures. */ + if (newsize > unique->maxSizeZ) { + FREE(unique->stack); + unique->stack = ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); + } + } + /* Update manager parameters to account for the new subtables. */ + unique->slots += n * numSlots; + ddFixLimits(unique); + unique->size += n; + + /* Now that the table is in a coherent state, create the new + ** projection functions. We need to temporarily disable reordering, + ** because we cannot reorder without projection functions in place. + **/ + one = unique->one; + zero = Cudd_Not(one); + + reorderSave = unique->autoDyn; + unique->autoDyn = 0; + for (i = oldsize; i < oldsize + n; i++) { + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) { + unique->autoDyn = reorderSave; + /* Shift everything back so table remains coherent. */ + for (j = oldsize; j < i; j++) { + Cudd_IterDerefBdd(unique,unique->vars[j]); + cuddDeallocNode(unique,unique->vars[j]); + unique->vars[j] = NULL; + } + for (j = level; j < oldsize; j++) { + unique->subtables[j].slots = unique->subtables[j+n].slots; + unique->subtables[j].slots = unique->subtables[j+n].slots; + unique->subtables[j].shift = unique->subtables[j+n].shift; + unique->subtables[j].keys = unique->subtables[j+n].keys; + unique->subtables[j].maxKeys = + unique->subtables[j+n].maxKeys; + unique->subtables[j].dead = unique->subtables[j+n].dead; + FREE(unique->subtables[j].nodelist); + unique->subtables[j].nodelist = + unique->subtables[j+n].nodelist; + unique->subtables[j+n].nodelist = NULL; + unique->subtables[j].bindVar = + unique->subtables[j+n].bindVar; + unique->subtables[j].varType = + unique->subtables[j+n].varType; + unique->subtables[j].pairIndex = + unique->subtables[j+n].pairIndex; + unique->subtables[j].varHandled = + unique->subtables[j+n].varHandled; + unique->subtables[j].varToBeGrouped = + unique->subtables[j+n].varToBeGrouped; + index = unique->invperm[j+n]; + unique->invperm[j] = index; + unique->perm[index] -= n; + } + unique->size = oldsize; + unique->slots -= n * numSlots; + ddFixLimits(unique); + (void) Cudd_DebugCheck(unique); + return(0); + } + cuddRef(unique->vars[i]); + } + if (unique->tree != NULL) { + unique->tree->size += n; + unique->tree->index = unique->invperm[0]; + ddPatchTree(unique,unique->tree); + } + unique->autoDyn = reorderSave; + + return(1); + +} /* end of cuddInsertSubtables */ + + +/**Function******************************************************************** + + Synopsis [Destroys the n most recently created subtables in a unique table.] + + Description [Destroys the n most recently created subtables in a unique + table. n should be positive. The subtables should not contain any live + nodes, except the (isolated) projection function. The projection + functions are freed. Returns 1 if successful; 0 otherwise.] + + SideEffects [The variable map used for fast variable substitution is + destroyed if it exists. In this case the cache is also cleared.] + + SeeAlso [cuddInsertSubtables Cudd_SetVarMap] + +******************************************************************************/ +int +cuddDestroySubtables( + DdManager * unique, + int n) +{ + DdSubtable *subtables; + DdNodePtr *nodelist; + DdNodePtr *vars; + int firstIndex, lastIndex; + int index, level, newlevel; + int lowestLevel; + int shift; + int found; + + /* Sanity check and set up. */ + if (n <= 0) return(0); + if (n > unique->size) n = unique->size; + + subtables = unique->subtables; + vars = unique->vars; + firstIndex = unique->size - n; + lastIndex = unique->size; + + /* Check for nodes labeled by the variables being destroyed + ** that may still be in use. It is allowed to destroy a variable + ** only if there are no such nodes. Also, find the lowest level + ** among the variables being destroyed. This will make further + ** processing more efficient. + */ + lowestLevel = unique->size; + for (index = firstIndex; index < lastIndex; index++) { + level = unique->perm[index]; + if (level < lowestLevel) lowestLevel = level; + nodelist = subtables[level].nodelist; + if (subtables[level].keys - subtables[level].dead != 1) return(0); + /* The projection function should be isolated. If the ref count + ** is 1, everything is OK. If the ref count is saturated, then + ** we need to make sure that there are no nodes pointing to it. + ** As for the external references, we assume the application is + ** responsible for them. + */ + if (vars[index]->ref != 1) { + if (vars[index]->ref != DD_MAXREF) return(0); + found = cuddFindParent(unique,vars[index]); + if (found) { + return(0); + } else { + vars[index]->ref = 1; + } + } + Cudd_RecursiveDeref(unique,vars[index]); + } + + /* Collect garbage, because we cannot afford having dead nodes pointing + ** to the dead nodes in the subtables being destroyed. + */ + (void) cuddGarbageCollect(unique,1); + + /* Here we know we can destroy our subtables. */ + for (index = firstIndex; index < lastIndex; index++) { + level = unique->perm[index]; + nodelist = subtables[level].nodelist; +#ifdef DD_DEBUG + assert(subtables[level].keys == 0); +#endif + FREE(nodelist); + unique->memused -= sizeof(DdNodePtr) * subtables[level].slots; + unique->slots -= subtables[level].slots; + unique->dead -= subtables[level].dead; + } + + /* Here all subtables to be destroyed have their keys field == 0 and + ** their hash tables have been freed. + ** We now scan the subtables from level lowestLevel + 1 to level size - 1, + ** shifting the subtables as required. We keep a running count of + ** how many subtables have been moved, so that we know by how many + ** positions each subtable should be shifted. + */ + shift = 1; + for (level = lowestLevel + 1; level < unique->size; level++) { + if (subtables[level].keys == 0) { + shift++; + continue; + } + newlevel = level - shift; + subtables[newlevel].slots = subtables[level].slots; + subtables[newlevel].shift = subtables[level].shift; + subtables[newlevel].keys = subtables[level].keys; + subtables[newlevel].maxKeys = subtables[level].maxKeys; + subtables[newlevel].dead = subtables[level].dead; + subtables[newlevel].nodelist = subtables[level].nodelist; + index = unique->invperm[level]; + unique->perm[index] = newlevel; + unique->invperm[newlevel] = index; + subtables[newlevel].bindVar = subtables[level].bindVar; + subtables[newlevel].varType = subtables[level].varType; + subtables[newlevel].pairIndex = subtables[level].pairIndex; + subtables[newlevel].varHandled = subtables[level].varHandled; + subtables[newlevel].varToBeGrouped = subtables[level].varToBeGrouped; + } + /* Destroy the map. If a surviving variable is + ** mapped to a dying variable, and the map were used again, + ** an out-of-bounds access to unique->vars would result. */ + if (unique->map != NULL) { + cuddCacheFlush(unique); + FREE(unique->map); + unique->map = NULL; + } + + unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); + unique->size -= n; + + return(1); + +} /* end of cuddDestroySubtables */ + + +/**Function******************************************************************** + + Synopsis [Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index.] + + Description [Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index. When new ZDD variables are created, it + is possible to preserve the functions unchanged, or it is possible to + preserve the covers unchanged, but not both. cuddResizeTableZdd preserves + the covers. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [ddResizeTable] + +******************************************************************************/ +int +cuddResizeTableZdd( + DdManager * unique, + int index) +{ + DdSubtable *newsubtables; + DdNodePtr *newnodelist; + int oldsize,newsize; + int i,j,reorderSave; + unsigned int numSlots = unique->initSlots; + int *newperm, *newinvperm; + + oldsize = unique->sizeZ; + /* Easy case: there is still room in the current table. */ + if (index < unique->maxSizeZ) { + for (i = oldsize; i <= index; i++) { + unique->subtableZ[i].slots = numSlots; + unique->subtableZ[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtableZ[i].keys = 0; + unique->subtableZ[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtableZ[i].dead = 0; + unique->permZ[i] = i; + unique->invpermZ[i] = i; + newnodelist = unique->subtableZ[i].nodelist = + ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = NULL; + } + } + } else { + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables up to index included. + */ + newsize = index + DD_DEFAULT_RESIZE; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "Increasing the ZDD table size from %d to %d\n", + unique->maxSizeZ, newsize); +#endif + newsubtables = ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newperm = ALLOC(int,newsize); + if (newperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newinvperm = ALLOC(int,newsize); + if (newinvperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->memused += (newsize - unique->maxSizeZ) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + if (newsize > unique->maxSize) { + FREE(unique->stack); + unique->stack = ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); + } + for (i = 0; i < oldsize; i++) { + newsubtables[i].slots = unique->subtableZ[i].slots; + newsubtables[i].shift = unique->subtableZ[i].shift; + newsubtables[i].keys = unique->subtableZ[i].keys; + newsubtables[i].maxKeys = unique->subtableZ[i].maxKeys; + newsubtables[i].dead = unique->subtableZ[i].dead; + newsubtables[i].nodelist = unique->subtableZ[i].nodelist; + newperm[i] = unique->permZ[i]; + newinvperm[i] = unique->invpermZ[i]; + } + for (i = oldsize; i <= index; i++) { + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newperm[i] = i; + newinvperm[i] = i; + newnodelist = newsubtables[i].nodelist = ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = NULL; + } + } + FREE(unique->subtableZ); + unique->subtableZ = newsubtables; + unique->maxSizeZ = newsize; + FREE(unique->permZ); + unique->permZ = newperm; + FREE(unique->invpermZ); + unique->invpermZ = newinvperm; + } + unique->slots += (index + 1 - unique->sizeZ) * numSlots; + ddFixLimits(unique); + unique->sizeZ = index + 1; + + /* Now that the table is in a coherent state, update the ZDD + ** universe. We need to temporarily disable reordering, + ** because we cannot reorder without universe in place. + */ + + reorderSave = unique->autoDynZ; + unique->autoDynZ = 0; + cuddZddFreeUniv(unique); + if (!cuddZddInitUniv(unique)) { + unique->autoDynZ = reorderSave; + return(0); + } + unique->autoDynZ = reorderSave; + + return(1); + +} /* end of cuddResizeTableZdd */ + + +/**Function******************************************************************** + + Synopsis [Adjusts parameters of a table to slow down its growth.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddSlowTableGrowth( + DdManager *unique) +{ + int i; + + unique->maxCacheHard = unique->cacheSlots - 1; + unique->cacheSlack = - (int) (unique->cacheSlots + 1); + for (i = 0; i < unique->size; i++) { + unique->subtables[i].maxKeys <<= 2; + } + unique->gcFrac = DD_GC_FRAC_MIN; + unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots); + cuddShrinkDeathRow(unique); + (void) fprintf(unique->err,"Slowing down table growth: "); + (void) fprintf(unique->err,"GC fraction = %.2f\t", unique->gcFrac); + (void) fprintf(unique->err,"minDead = %u\n", unique->minDead); + +} /* end of cuddSlowTableGrowth */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Rehashes a ZDD unique subtable.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddRehash] + +******************************************************************************/ +static void +ddRehashZdd( + DdManager * unique, + int i) +{ + unsigned int slots, oldslots; + int shift, oldshift; + int j, pos; + DdNodePtr *nodelist, *oldnodelist; + DdNode *node, *next; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (unique->slots > unique->looseUpTo) { + unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); +#ifdef DD_VERBOSE + if (unique->gcFrac == DD_GC_FRAC_HI) { + (void) fprintf(unique->err,"GC fraction = %.2f\t", + DD_GC_FRAC_LO); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); + } +#endif + unique->gcFrac = DD_GC_FRAC_LO; + } + + assert(i != CUDD_MAXINDEX); + oldslots = unique->subtableZ[i].slots; + oldshift = unique->subtableZ[i].shift; + oldnodelist = unique->subtableZ[i].nodelist; + + /* Compute the new size of the subtable. Normally, we just + ** double. However, after reordering, a table may be severely + ** overloaded. Therefore, we iterate. */ + slots = oldslots; + shift = oldshift; + do { + slots <<= 1; + shift--; + } while (slots * DD_MAX_SUBTABLE_DENSITY < unique->subtableZ[i].keys); + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + (void) fprintf(unique->err, + "Unable to resize ZDD subtable %d for lack of memory.\n", + i); + (void) cuddGarbageCollect(unique,1); + for (j = 0; j < unique->sizeZ; j++) { + unique->subtableZ[j].maxKeys <<= 1; + } + return; + } + unique->subtableZ[i].nodelist = nodelist; + unique->subtableZ[i].slots = slots; + unique->subtableZ[i].shift = shift; + unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + pos = ddHash(cuddT(node), cuddE(node), shift); + node->next = nodelist[pos]; + nodelist[pos] = node; + node = next; + } + } + FREE(oldnodelist); + +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "rehashing layer %d: keys %d dead %d new size %d\n", + i, unique->subtableZ[i].keys, + unique->subtableZ[i].dead, slots); +#endif + + /* Update global data. */ + unique->memused += (slots - oldslots) * sizeof(DdNode *); + unique->slots += (slots - oldslots); + ddFixLimits(unique); + +} /* end of ddRehashZdd */ + + +/**Function******************************************************************** + + Synopsis [Increases the number of subtables in a unique table so + that it meets or exceeds index.] + + Description [Increases the number of subtables in a unique table so + that it meets or exceeds index. The parameter amount determines how + much spare space is allocated to prevent too frequent resizing. If + index is negative, the table is resized, but no new variables are + created. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Reserve cuddResizeTableZdd] + +******************************************************************************/ +static int +ddResizeTable( + DdManager * unique, + int index, + int amount) +{ + DdSubtable *newsubtables; + DdNodePtr *newnodelist; + DdNodePtr *newvars; + DdNode *sentinel = &(unique->sentinel); + int oldsize,newsize; + int i,j,reorderSave; + int numSlots = unique->initSlots; + int *newperm, *newinvperm, *newmap; + DdNode *one, *zero; + + oldsize = unique->size; + /* Easy case: there is still room in the current table. */ + if (index >= 0 && index < unique->maxSize) { + for (i = oldsize; i <= index; i++) { + unique->subtables[i].slots = numSlots; + unique->subtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtables[i].keys = 0; + unique->subtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[i].dead = 0; + unique->subtables[i].bindVar = 0; + unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[i].pairIndex = 0; + unique->subtables[i].varHandled = 0; + unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + unique->perm[i] = i; + unique->invperm[i] = i; + newnodelist = unique->subtables[i].nodelist = + ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + for (j = oldsize; j < i; j++) { + FREE(unique->subtables[j].nodelist); + } + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + if (unique->map != NULL) { + for (i = oldsize; i <= index; i++) { + unique->map[i] = i; + } + } + } else { + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables up to index included. + */ + newsize = (index < 0) ? amount : index + amount; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "Increasing the table size from %d to %d\n", + unique->maxSize, newsize); +#endif + newsubtables = ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newvars = ALLOC(DdNodePtr,newsize); + if (newvars == NULL) { + FREE(newsubtables); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newperm = ALLOC(int,newsize); + if (newperm == NULL) { + FREE(newsubtables); + FREE(newvars); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newinvperm = ALLOC(int,newsize); + if (newinvperm == NULL) { + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + if (unique->map != NULL) { + newmap = ALLOC(int,newsize); + if (newmap == NULL) { + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + FREE(newinvperm); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->memused += (newsize - unique->maxSize) * sizeof(int); + } + unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + if (newsize > unique->maxSizeZ) { + FREE(unique->stack); + unique->stack = ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + FREE(newinvperm); + if (unique->map != NULL) { + FREE(newmap); + } + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); + } + for (i = 0; i < oldsize; i++) { + newsubtables[i].slots = unique->subtables[i].slots; + newsubtables[i].shift = unique->subtables[i].shift; + newsubtables[i].keys = unique->subtables[i].keys; + newsubtables[i].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i].dead = unique->subtables[i].dead; + newsubtables[i].nodelist = unique->subtables[i].nodelist; + newsubtables[i].bindVar = unique->subtables[i].bindVar; + newsubtables[i].varType = unique->subtables[i].varType; + newsubtables[i].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i].varHandled = unique->subtables[i].varHandled; + newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + newperm[i] = unique->perm[i]; + newinvperm[i] = unique->invperm[i]; + } + for (i = oldsize; i <= index; i++) { + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newsubtables[i].bindVar = 0; + newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + newsubtables[i].pairIndex = 0; + newsubtables[i].varHandled = 0; + newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + newperm[i] = i; + newinvperm[i] = i; + newnodelist = newsubtables[i].nodelist = ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + if (unique->map != NULL) { + for (i = 0; i < oldsize; i++) { + newmap[i] = unique->map[i]; + } + for (i = oldsize; i <= index; i++) { + newmap[i] = i; + } + FREE(unique->map); + unique->map = newmap; + } + FREE(unique->subtables); + unique->subtables = newsubtables; + unique->maxSize = newsize; + FREE(unique->vars); + unique->vars = newvars; + FREE(unique->perm); + unique->perm = newperm; + FREE(unique->invperm); + unique->invperm = newinvperm; + } + + /* Now that the table is in a coherent state, create the new + ** projection functions. We need to temporarily disable reordering, + ** because we cannot reorder without projection functions in place. + **/ + if (index >= 0) { + one = unique->one; + zero = Cudd_Not(one); + + unique->size = index + 1; + if (unique->tree != NULL) { + unique->tree->size = ddMax(unique->tree->size, unique->size); + } + unique->slots += (index + 1 - oldsize) * numSlots; + ddFixLimits(unique); + + reorderSave = unique->autoDyn; + unique->autoDyn = 0; + for (i = oldsize; i <= index; i++) { + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) { + unique->autoDyn = reorderSave; + for (j = oldsize; j < i; j++) { + Cudd_IterDerefBdd(unique,unique->vars[j]); + cuddDeallocNode(unique,unique->vars[j]); + unique->vars[j] = NULL; + } + for (j = oldsize; j <= index; j++) { + FREE(unique->subtables[j].nodelist); + unique->subtables[j].nodelist = NULL; + } + unique->size = oldsize; + unique->slots -= (index + 1 - oldsize) * numSlots; + ddFixLimits(unique); + return(0); + } + cuddRef(unique->vars[i]); + } + unique->autoDyn = reorderSave; + } + + return(1); + +} /* end of ddResizeTable */ + + +/**Function******************************************************************** + + Synopsis [Searches the subtables above node for a parent.] + + Description [Searches the subtables above node for a parent. Returns 1 + as soon as one parent is found. Returns 0 is the search is fruitless.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddFindParent( + DdManager * table, + DdNode * node) +{ + int i,j; + int slots; + DdNodePtr *nodelist; + DdNode *f; + + for (i = cuddI(table,node->index) - 1; i >= 0; i--) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (cuddT(f) > node) { + f = f->next; + } + while (cuddT(f) == node && Cudd_Regular(cuddE(f)) > node) { + f = f->next; + } + if (cuddT(f) == node && Cudd_Regular(cuddE(f)) == node) { + return(1); + } + } + } + + return(0); + +} /* end of cuddFindParent */ + + +/**Function******************************************************************** + + Synopsis [Adjusts the values of table limits.] + + Description [Adjusts the values of table fields controlling the. + sizes of subtables and computed table. If the computed table is too small + according to the new values, it is resized.] + + SideEffects [Modifies manager fields. May resize computed table.] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static void +ddFixLimits( + DdManager *unique) +{ + unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); + unique->cacheSlack = (int) ddMin(unique->maxCacheHard, + DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) - + 2 * (int) unique->cacheSlots; + if (unique->cacheSlots < unique->slots/2 && unique->cacheSlack >= 0) + cuddCacheResize(unique); + return; + +} /* end of ddFixLimits */ + + +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST +/**Function******************************************************************** + + Synopsis [Inserts a DdNode in a red/black search tree.] + + Description [Inserts a DdNode in a red/black search tree. Nodes from + the same "page" (defined by DD_PAGE_MASK) are linked in a LIFO list.] + + SideEffects [None] + + SeeAlso [cuddOrderedThread] + +******************************************************************************/ +static void +cuddOrderedInsert( + DdNodePtr * root, + DdNodePtr node) +{ + DdNode *scan; + DdNodePtr *scanP; + DdNodePtr *stack[DD_STACK_SIZE]; + int stackN = 0; + + scanP = root; + while ((scan = *scanP) != NULL) { + stack[stackN++] = scanP; + if (DD_INSERT_COMPARE(node, scan) == 0) { /* add to page list */ + DD_NEXT(node) = DD_NEXT(scan); + DD_NEXT(scan) = node; + return; + } + scanP = (node < scan) ? &DD_LEFT(scan) : &DD_RIGHT(scan); + } + DD_RIGHT(node) = DD_LEFT(node) = DD_NEXT(node) = NULL; + DD_COLOR(node) = DD_RED; + *scanP = node; + stack[stackN] = &node; + cuddDoRebalance(stack,stackN); + +} /* end of cuddOrderedInsert */ + + +/**Function******************************************************************** + + Synopsis [Threads all the nodes of a search tree into a linear list.] + + Description [Threads all the nodes of a search tree into a linear + list. For each node of the search tree, the "left" child, if non-null, has + a lower address than its parent, and the "right" child, if non-null, has a + higher address than its parent. + The list is sorted in order of increasing addresses. The search + tree is destroyed as a result of this operation. The last element of + the linear list is made to point to the address passed in list. Each + node if the search tree is a linearly-linked list of nodes from the + same memory page (as defined in DD_PAGE_MASK). When a node is added to + the linear list, all the elements of the linked list are added.] + + SideEffects [The search tree is destroyed as a result of this operation.] + + SeeAlso [cuddOrderedInsert] + +******************************************************************************/ +static DdNode * +cuddOrderedThread( + DdNode * root, + DdNode * list) +{ + DdNode *current, *next, *prev, *end; + + current = root; + /* The first word in the node is used to implement a stack that holds + ** the nodes from the root of the tree to the current node. Here we + ** put the root of the tree at the bottom of the stack. + */ + *((DdNodePtr *) current) = NULL; + + while (current != NULL) { + if (DD_RIGHT(current) != NULL) { + /* If possible, we follow the "right" link. Eventually we'll + ** find the node with the largest address in the current tree. + ** In this phase we use the first word of a node to implemen + ** a stack of the nodes on the path from the root to "current". + ** Also, we disconnect the "right" pointers to indicate that + ** we have already followed them. + */ + next = DD_RIGHT(current); + DD_RIGHT(current) = NULL; + *((DdNodePtr *)next) = current; + current = next; + } else { + /* We can't proceed along the "right" links any further. + ** Hence "current" is the largest element in the current tree. + ** We make this node the new head of "list". (Repeating this + ** operation until the tree is empty yields the desired linear + ** threading of all nodes.) + */ + prev = *((DdNodePtr *) current); /* save prev node on stack in prev */ + /* Traverse the linked list of current until the end. */ + for (end = current; DD_NEXT(end) != NULL; end = DD_NEXT(end)); + DD_NEXT(end) = list; /* attach "list" at end and make */ + list = current; /* "current" the new head of "list" */ + /* Now, if current has a "left" child, we push it on the stack. + ** Otherwise, we just continue with the parent of "current". + */ + if (DD_LEFT(current) != NULL) { + next = DD_LEFT(current); + *((DdNodePtr *) next) = prev; + current = next; + } else { + current = prev; + } + } + } + + return(list); + +} /* end of cuddOrderedThread */ + + +/**Function******************************************************************** + + Synopsis [Performs the left rotation for red/black trees.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddRotateRight] + +******************************************************************************/ +DD_INLINE +static void +cuddRotateLeft( + DdNodePtr * nodeP) +{ + DdNode *newRoot; + DdNode *oldRoot = *nodeP; + + *nodeP = newRoot = DD_RIGHT(oldRoot); + DD_RIGHT(oldRoot) = DD_LEFT(newRoot); + DD_LEFT(newRoot) = oldRoot; + +} /* end of cuddRotateLeft */ + + +/**Function******************************************************************** + + Synopsis [Performs the right rotation for red/black trees.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddRotateLeft] + +******************************************************************************/ +DD_INLINE +static void +cuddRotateRight( + DdNodePtr * nodeP) +{ + DdNode *newRoot; + DdNode *oldRoot = *nodeP; + + *nodeP = newRoot = DD_LEFT(oldRoot); + DD_LEFT(oldRoot) = DD_RIGHT(newRoot); + DD_RIGHT(newRoot) = oldRoot; + +} /* end of cuddRotateRight */ + + +/**Function******************************************************************** + + Synopsis [Rebalances a red/black tree.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +cuddDoRebalance( + DdNodePtr ** stack, + int stackN) +{ + DdNodePtr *xP, *parentP, *grandpaP; + DdNode *x, *y, *parent, *grandpa; + + xP = stack[stackN]; + x = *xP; + /* Work our way back up, re-balancing the tree. */ + while (--stackN >= 0) { + parentP = stack[stackN]; + parent = *parentP; + if (DD_IS_BLACK(parent)) break; + /* Since the root is black, here a non-null grandparent exists. */ + grandpaP = stack[stackN-1]; + grandpa = *grandpaP; + if (parent == DD_LEFT(grandpa)) { + y = DD_RIGHT(grandpa); + if (y != NULL && DD_IS_RED(y)) { + DD_COLOR(parent) = DD_BLACK; + DD_COLOR(y) = DD_BLACK; + DD_COLOR(grandpa) = DD_RED; + x = grandpa; + stackN--; + } else { + if (x == DD_RIGHT(parent)) { + cuddRotateLeft(parentP); + DD_COLOR(x) = DD_BLACK; + } else { + DD_COLOR(parent) = DD_BLACK; + } + DD_COLOR(grandpa) = DD_RED; + cuddRotateRight(grandpaP); + break; + } + } else { + y = DD_LEFT(grandpa); + if (y != NULL && DD_IS_RED(y)) { + DD_COLOR(parent) = DD_BLACK; + DD_COLOR(y) = DD_BLACK; + DD_COLOR(grandpa) = DD_RED; + x = grandpa; + stackN--; + } else { + if (x == DD_LEFT(parent)) { + cuddRotateRight(parentP); + DD_COLOR(x) = DD_BLACK; + } else { + DD_COLOR(parent) = DD_BLACK; + } + DD_COLOR(grandpa) = DD_RED; + cuddRotateLeft(grandpaP); + } + } + } + DD_COLOR(*(stack[0])) = DD_BLACK; + +} /* end of cuddDoRebalance */ +#endif +#endif + + +/**Function******************************************************************** + + Synopsis [Fixes a variable tree after the insertion of new subtables.] + + Description [Fixes a variable tree after the insertion of new subtables. + After such an insertion, the low fields of the tree below the insertion + point are inconsistent.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ddPatchTree( + DdManager *dd, + MtrNode *treenode) +{ + MtrNode *auxnode = treenode; + + while (auxnode != NULL) { + auxnode->low = dd->perm[auxnode->index]; + if (auxnode->child != NULL) { + ddPatchTree(dd, auxnode->child); + } + auxnode = auxnode->younger; + } + + return; + +} /* end of ddPatchTree */ + + +#ifdef DD_DEBUG +/**Function******************************************************************** + + Synopsis [Checks whether a collision list is ordered.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddCheckCollisionOrdering( + DdManager *unique, + int i, + int j) +{ + int slots; + DdNode *node, *next; + DdNodePtr *nodelist; + DdNode *sentinel = &(unique->sentinel); + + nodelist = unique->subtables[i].nodelist; + slots = unique->subtables[i].slots; + node = nodelist[j]; + if (node == sentinel) return(1); + next = node->next; + while (next != sentinel) { + if (cuddT(node) < cuddT(next) || + (cuddT(node) == cuddT(next) && cuddE(node) < cuddE(next))) { + (void) fprintf(unique->err, + "Unordered list: index %u, position %d\n", i, j); + return(0); + } + node = next; + next = node->next; + } + return(1); + +} /* end of cuddCheckCollisionOrdering */ +#endif + + + + +/**Function******************************************************************** + + Synopsis [Reports problem in garbage collection.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddGarbageCollect cuddGarbageCollectZdd] + +******************************************************************************/ +static void +ddReportRefMess( + DdManager *unique /* manager */, + int i /* table in which the problem occurred */, + const char *caller /* procedure that detected the problem */) +{ + if (i == CUDD_CONST_INDEX) { + (void) fprintf(unique->err, + "%s: problem in constants\n", caller); + } else if (i != -1) { + (void) fprintf(unique->err, + "%s: problem in table %d\n", caller, i); + } + (void) fprintf(unique->err, " dead count != deleted\n"); + (void) fprintf(unique->err, " This problem is often due to a missing \ +call to Cudd_Ref\n or to an extra call to Cudd_RecursiveDeref.\n \ +See the CUDD Programmer's Guide for additional details."); + abort(); + +} /* end of ddReportRefMess */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddUtil.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddUtil.c new file mode 100644 index 000000000..1a1a47a03 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddUtil.c @@ -0,0 +1,4032 @@ +/**CFile*********************************************************************** + + FileName [cuddUtil.c] + + PackageName [cudd] + + Synopsis [Utility functions.] + + Description [External procedures included in this module: +
                  +
                • Cudd_PrintMinterm() +
                • Cudd_bddPrintCover() +
                • Cudd_PrintDebug() +
                • Cudd_DagSize() +
                • Cudd_EstimateCofactor() +
                • Cudd_EstimateCofactorSimple() +
                • Cudd_SharingSize() +
                • Cudd_CountMinterm() +
                • Cudd_EpdCountMinterm() +
                • Cudd_CountPath() +
                • Cudd_CountPathsToNonZero() +
                • Cudd_SupportIndices() +
                • Cudd_Support() +
                • Cudd_SupportIndex() +
                • Cudd_SupportSize() +
                • Cudd_VectorSupportIndices() +
                • Cudd_VectorSupport() +
                • Cudd_VectorSupportIndex() +
                • Cudd_VectorSupportSize() +
                • Cudd_ClassifySupport() +
                • Cudd_CountLeaves() +
                • Cudd_bddPickOneCube() +
                • Cudd_bddPickOneMinterm() +
                • Cudd_bddPickArbitraryMinterms() +
                • Cudd_SubsetWithMaskVars() +
                • Cudd_FirstCube() +
                • Cudd_NextCube() +
                • Cudd_bddComputeCube() +
                • Cudd_addComputeCube() +
                • Cudd_FirstNode() +
                • Cudd_NextNode() +
                • Cudd_GenFree() +
                • Cudd_IsGenEmpty() +
                • Cudd_IndicesToCube() +
                • Cudd_PrintVersion() +
                • Cudd_AverageDistance() +
                • Cudd_Random() +
                • Cudd_Srandom() +
                • Cudd_Density() +
                + Internal procedures included in this module: +
                  +
                • cuddP() +
                • cuddStCountfree() +
                • cuddCollectNodes() +
                • cuddNodeArray() +
                + Static procedures included in this module: +
                  +
                • dp2() +
                • ddPrintMintermAux() +
                • ddDagInt() +
                • ddCountMintermAux() +
                • ddEpdCountMintermAux() +
                • ddCountPathAux() +
                • ddSupportStep() +
                • ddClearFlag() +
                • ddLeavesInt() +
                • ddPickArbitraryMinterms() +
                • ddPickRepresentativeCube() +
                • ddEpdFree() +
                • ddFindSupport() +
                • ddClearVars() +
                • indexCompare() +
                ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Random generator constants. */ +#define MODULUS1 2147483563 +#define LEQA1 40014 +#define LEQQ1 53668 +#define LEQR1 12211 +#define MODULUS2 2147483399 +#define LEQA2 40692 +#define LEQQ2 52774 +#define LEQR2 3791 +#define STAB_SIZE 64 +#define STAB_DIV (1 + (MODULUS1 - 1) / STAB_SIZE) + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddUtil.c,v 1.83 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static DdNode *background, *zero; + +static long cuddRand = 0; +static long cuddRand2; +static long shuffleSelect; +static long shuffleTable[STAB_SIZE]; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define bang(f) ((Cudd_IsComplement(f)) ? '!' : ' ') + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int dp2 (DdManager *dd, DdNode *f, st_table *t); +static void ddPrintMintermAux (DdManager *dd, DdNode *node, int *list); +static int ddDagInt (DdNode *n); +static int cuddNodeArrayRecur (DdNode *f, DdNodePtr *table, int index); +static int cuddEstimateCofactor (DdManager *dd, st_table *table, DdNode * node, int i, int phase, DdNode ** ptr); +static DdNode * cuddUniqueLookup (DdManager * unique, int index, DdNode * T, DdNode * E); +static int cuddEstimateCofactorSimple (DdNode * node, int i); +static double ddCountMintermAux (DdNode *node, double max, DdHashTable *table); +static int ddEpdCountMintermAux (DdNode *node, EpDouble *max, EpDouble *epd, st_table *table); +static double ddCountPathAux (DdNode *node, st_table *table); +static double ddCountPathsToNonZero (DdNode * N, st_table * table); +static void ddSupportStep (DdNode *f, int *support); +static void ddClearFlag (DdNode *f); +static int ddLeavesInt (DdNode *n); +static int ddPickArbitraryMinterms (DdManager *dd, DdNode *node, int nvars, int nminterms, char **string); +static int ddPickRepresentativeCube (DdManager *dd, DdNode *node, double *weight, char *string); +static enum st_retval ddEpdFree (char * key, char * value, char * arg); +static void ddFindSupport(DdManager *dd, DdNode *f, int *SP); +static void ddClearVars(DdManager *dd, int SP); +static int indexCompare(const void *a, const void *b); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints a disjoint sum of products.] + + Description [Prints a disjoint sum of product cover for the function + rooted at node. Each product corresponds to a path from node to a + leaf node different from the logical zero, and different from the + background value. Uses the package default output file. Returns 1 + if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug Cudd_bddPrintCover] + +******************************************************************************/ +int +Cudd_PrintMinterm( + DdManager * manager, + DdNode * node) +{ + int i, *list; + + background = manager->background; + zero = Cudd_Not(manager->one); + list = ALLOC(int,manager->size); + if (list == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < manager->size; i++) list[i] = 2; + ddPrintMintermAux(manager,node,list); + FREE(list); + return(1); + +} /* end of Cudd_PrintMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints a sum of prime implicants of a BDD.] + + Description [Prints a sum of product cover for an incompletely + specified function given by a lower bound and an upper bound. Each + product is a prime implicant obtained by expanding the product + corresponding to a path from node to the constant one. Uses the + package default output file. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintMinterm] + +******************************************************************************/ +int +Cudd_bddPrintCover( + DdManager *dd, + DdNode *l, + DdNode *u) +{ + int *array; + int q, result; + DdNode *lb; +#ifdef DD_DEBUG + DdNode *cover; +#endif + + array = ALLOC(int, Cudd_ReadSize(dd)); + if (array == NULL) return(0); + lb = l; + cuddRef(lb); +#ifdef DD_DEBUG + cover = Cudd_ReadLogicZero(dd); + cuddRef(cover); +#endif + while (lb != Cudd_ReadLogicZero(dd)) { + DdNode *implicant, *prime, *tmp; + int length; + implicant = Cudd_LargestCube(dd,lb,&length); + if (implicant == NULL) { + Cudd_RecursiveDeref(dd,lb); + FREE(array); + return(0); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,u); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,implicant); + FREE(array); + return(0); + } + cuddRef(prime); + Cudd_RecursiveDeref(dd,implicant); + tmp = Cudd_bddAnd(dd,lb,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + FREE(array); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,lb); + lb = tmp; + result = Cudd_BddToCubeArray(dd,prime,array); + if (result == 0) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + FREE(array); + return(0); + } + for (q = 0; q < dd->size; q++) { + switch (array[q]) { + case 0: + (void) fprintf(dd->out, "0"); + break; + case 1: + (void) fprintf(dd->out, "1"); + break; + case 2: + (void) fprintf(dd->out, "-"); + break; + default: + (void) fprintf(dd->out, "?"); + } + } + (void) fprintf(dd->out, " 1\n"); +#ifdef DD_DEBUG + tmp = Cudd_bddOr(dd,prime,cover); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cover); + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + FREE(array); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cover); + cover = tmp; +#endif + Cudd_RecursiveDeref(dd,prime); + } + (void) fprintf(dd->out, "\n"); + Cudd_RecursiveDeref(dd,lb); + FREE(array); +#ifdef DD_DEBUG + if (!Cudd_bddLeq(dd,cover,u) || !Cudd_bddLeq(dd,l,cover)) { + Cudd_RecursiveDeref(dd,cover); + return(0); + } + Cudd_RecursiveDeref(dd,cover); +#endif + return(1); + +} /* end of Cudd_bddPrintCover */ + + +/**Function******************************************************************** + + Synopsis [Prints to the standard output a DD and its statistics.] + + Description [Prints to the standard output a DD and its statistics. + The statistics include the number of nodes, the number of leaves, and + the number of minterms. (The number of minterms is the number of + assignments to the variables that cause the function to be different + from the logical zero (for BDDs) and from the background value (for + ADDs.) The statistics are printed if pr > 0. Specifically: +
                  +
                • pr = 0 : prints nothing +
                • pr = 1 : prints counts of nodes and minterms +
                • pr = 2 : prints counts + disjoint sum of product +
                • pr = 3 : prints counts + list of nodes +
                • pr > 3 : prints counts + disjoint sum of product + list of nodes +
                + For the purpose of counting the number of minterms, the function is + supposed to depend on n variables. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize Cudd_CountLeaves Cudd_CountMinterm + Cudd_PrintMinterm] + +******************************************************************************/ +int +Cudd_PrintDebug( + DdManager * dd, + DdNode * f, + int n, + int pr) +{ + DdNode *azero, *bzero; + int nodes; + int leaves; + double minterms; + int retval = 1; + + if (f == NULL) { + (void) fprintf(dd->out,": is the NULL DD\n"); + (void) fflush(dd->out); + return(0); + } + azero = DD_ZERO(dd); + bzero = Cudd_Not(DD_ONE(dd)); + if ((f == azero || f == bzero) && pr > 0){ + (void) fprintf(dd->out,": is the zero DD\n"); + (void) fflush(dd->out); + return(1); + } + if (pr > 0) { + nodes = Cudd_DagSize(f); + if (nodes == CUDD_OUT_OF_MEM) retval = 0; + leaves = Cudd_CountLeaves(f); + if (leaves == CUDD_OUT_OF_MEM) retval = 0; + minterms = Cudd_CountMinterm(dd, f, n); + if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; + (void) fprintf(dd->out,": %d nodes %d leaves %g minterms\n", + nodes, leaves, minterms); + if (pr > 2) { + if (!cuddP(dd, f)) retval = 0; + } + if (pr == 2 || pr > 3) { + if (!Cudd_PrintMinterm(dd,f)) retval = 0; + (void) fprintf(dd->out,"\n"); + } + (void) fflush(dd->out); + } + return(retval); + +} /* end of Cudd_PrintDebug */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of nodes in a DD.] + + Description [Counts the number of nodes in a DD. Returns the number + of nodes in the graph rooted at node.] + + SideEffects [None] + + SeeAlso [Cudd_SharingSize Cudd_PrintDebug] + +******************************************************************************/ +int +Cudd_DagSize( + DdNode * node) +{ + int i; + + i = ddDagInt(Cudd_Regular(node)); + ddClearFlag(Cudd_Regular(node)); + + return(i); + +} /* end of Cudd_DagSize */ + + +/**Function******************************************************************** + + Synopsis [Estimates the number of nodes in a cofactor of a DD.] + + Description [Estimates the number of nodes in a cofactor of a DD. + Returns an estimate of the number of nodes in a cofactor of + the graph rooted at node with respect to the variable whose index is i. + In case of failure, returns CUDD_OUT_OF_MEM. + This function uses a refinement of the algorithm of Cabodi et al. + (ICCAD96). The refinement allows the procedure to account for part + of the recombination that may occur in the part of the cofactor above + the cofactoring variable. This procedure does not create any new node. + It does keep a small table of results; therefore it may run out of memory. + If this is a concern, one should use Cudd_EstimateCofactorSimple, which + is faster, does not allocate any memory, but is less accurate.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize Cudd_EstimateCofactorSimple] + +******************************************************************************/ +int +Cudd_EstimateCofactor( + DdManager *dd /* manager */, + DdNode * f /* function */, + int i /* index of variable */, + int phase /* 1: positive; 0: negative */ + ) +{ + int val; + DdNode *ptr; + st_table *table; + + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) return(CUDD_OUT_OF_MEM); + val = cuddEstimateCofactor(dd,table,Cudd_Regular(f),i,phase,&ptr); + ddClearFlag(Cudd_Regular(f)); + st_free_table(table); + + return(val); + +} /* end of Cudd_EstimateCofactor */ + + +/**Function******************************************************************** + + Synopsis [Estimates the number of nodes in a cofactor of a DD.] + + Description [Estimates the number of nodes in a cofactor of a DD. + Returns an estimate of the number of nodes in the positive cofactor of + the graph rooted at node with respect to the variable whose index is i. + This procedure implements with minor changes the algorithm of Cabodi et al. + (ICCAD96). It does not allocate any memory, it does not change the + state of the manager, and it is fast. However, it has been observed to + overestimate the size of the cofactor by as much as a factor of 2.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize] + +******************************************************************************/ +int +Cudd_EstimateCofactorSimple( + DdNode * node, + int i) +{ + int val; + + val = cuddEstimateCofactorSimple(Cudd_Regular(node),i); + ddClearFlag(Cudd_Regular(node)); + + return(val); + +} /* end of Cudd_EstimateCofactorSimple */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of nodes in an array of DDs.] + + Description [Counts the number of nodes in an array of DDs. Shared + nodes are counted only once. Returns the total number of nodes.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize] + +******************************************************************************/ +int +Cudd_SharingSize( + DdNode ** nodeArray, + int n) +{ + int i,j; + + i = 0; + for (j = 0; j < n; j++) { + i += ddDagInt(Cudd_Regular(nodeArray[j])); + } + for (j = 0; j < n; j++) { + ddClearFlag(Cudd_Regular(nodeArray[j])); + } + return(i); + +} /* end of Cudd_SharingSize */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a DD.] + + Description [Counts the number of minterms of a DD. The function is + assumed to depend on nvars variables. The minterm count is + represented as a double, to allow for a larger number of variables. + Returns the number of minterms of the function rooted at node if + successful; (double) CUDD_OUT_OF_MEM otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug Cudd_CountPath] + +******************************************************************************/ +double +Cudd_CountMinterm( + DdManager * manager, + DdNode * node, + int nvars) +{ + double max; + DdHashTable *table; + double res; + CUDD_VALUE_TYPE epsilon; + + background = manager->background; + zero = Cudd_Not(manager->one); + + max = pow(2.0,(double)nvars); + table = cuddHashTableInit(manager,1,2); + if (table == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + epsilon = Cudd_ReadEpsilon(manager); + Cudd_SetEpsilon(manager,(CUDD_VALUE_TYPE)0.0); + res = ddCountMintermAux(node,max,table); + cuddHashTableQuit(table); + Cudd_SetEpsilon(manager,epsilon); + + return(res); + +} /* end of Cudd_CountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of paths of a DD.] + + Description [Counts the number of paths of a DD. Paths to all + terminal nodes are counted. The path count is represented as a + double, to allow for a larger number of variables. Returns the + number of paths of the function rooted at node if successful; + (double) CUDD_OUT_OF_MEM otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_CountMinterm] + +******************************************************************************/ +double +Cudd_CountPath( + DdNode * node) +{ + + st_table *table; + double i; + + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + i = ddCountPathAux(Cudd_Regular(node),table); + st_foreach(table, cuddStCountfree, NULL); + st_free_table(table); + return(i); + +} /* end of Cudd_CountPath */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a DD with extended precision.] + + Description [Counts the number of minterms of a DD with extended precision. + The function is assumed to depend on nvars variables. The minterm count is + represented as an EpDouble, to allow any number of variables. + Returns 0 if successful; CUDD_OUT_OF_MEM otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug Cudd_CountPath] + +******************************************************************************/ +int +Cudd_EpdCountMinterm( + DdManager * manager, + DdNode * node, + int nvars, + EpDouble * epd) +{ + EpDouble max, tmp; + st_table *table; + int status; + + background = manager->background; + zero = Cudd_Not(manager->one); + + EpdPow2(nvars, &max); + table = st_init_table(EpdCmp, st_ptrhash); + if (table == NULL) { + EpdMakeZero(epd, 0); + return(CUDD_OUT_OF_MEM); + } + status = ddEpdCountMintermAux(Cudd_Regular(node),&max,epd,table); + st_foreach(table, ddEpdFree, NULL); + st_free_table(table); + if (status == CUDD_OUT_OF_MEM) { + EpdMakeZero(epd, 0); + return(CUDD_OUT_OF_MEM); + } + if (Cudd_IsComplement(node)) { + EpdSubtract3(&max, epd, &tmp); + EpdCopy(&tmp, epd); + } + return(0); + +} /* end of Cudd_EpdCountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of paths to a non-zero terminal of a DD.] + + Description [Counts the number of paths to a non-zero terminal of a + DD. The path count is + represented as a double, to allow for a larger number of variables. + Returns the number of paths of the function rooted at node.] + + SideEffects [None] + + SeeAlso [Cudd_CountMinterm Cudd_CountPath] + +******************************************************************************/ +double +Cudd_CountPathsToNonZero( + DdNode * node) +{ + + st_table *table; + double i; + + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + i = ddCountPathsToNonZero(node,table); + st_foreach(table, cuddStCountfree, NULL); + st_free_table(table); + return(i); + +} /* end of Cudd_CountPathsToNonZero */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a DD depends.] + + Description [Finds the variables on which a DD depends. Returns the + number of variables if successful; CUDD_OUT_OF_MEM otherwise.] + + SideEffects [The indices of the support variables are returned as + side effects. If the function is constant, no array is allocated.] + + SeeAlso [Cudd_Support Cudd_SupportIndex Cudd_VectorSupportIndices] + +******************************************************************************/ +int +Cudd_SupportIndices( + DdManager * dd /* manager */, + DdNode * f /* DD whose support is sought */, + int **indices /* array containing (on return) the indices */) +{ + int SP = 0; + + ddFindSupport(dd, Cudd_Regular(f), &SP); + ddClearFlag(Cudd_Regular(f)); + ddClearVars(dd, SP); + if (SP > 0) { + int i; + *indices = ALLOC(int, SP); + if (*indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + + for (i = 0; i < SP; i++) + (*indices)[i] = (int) (ptrint) dd->stack[i]; + + qsort(*indices, SP, sizeof(int), indexCompare); + } else { + *indices = NULL; + } + + return(SP); + +} /* end of Cudd_SupportIndices */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a DD depends.] + + Description [Finds the variables on which a DD depends. + Returns a BDD consisting of the product of the variables if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_VectorSupport Cudd_ClassifySupport] + +******************************************************************************/ +DdNode * +Cudd_Support( + DdManager * dd /* manager */, + DdNode * f /* DD whose support is sought */) +{ + int *support; + DdNode *res; + int j; + + int size = Cudd_SupportIndices(dd, f, &support); + if (size == CUDD_OUT_OF_MEM) + return(NULL); + + /* Transform support from array of indices to cube. */ + res = DD_ONE(dd); + cuddRef(res); + + for (j = size - 1; j >= 0; j--) { /* for each index bottom-up (almost) */ + int index = support[j]; + DdNode *var = dd->vars[index]; + DdNode *tmp = Cudd_bddAnd(dd,res,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,res); + FREE(support); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,res); + res = tmp; + } + + FREE(support); + cuddDeref(res); + return(res); + +} /* end of Cudd_Support */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a DD depends.] + + Description [Finds the variables on which a DD depends. Returns an + index array of the variables if successful; NULL otherwise. The + size of the array equals the number of variables in the manager. + Each entry of the array is 1 if the corresponding variable is in the + support of the DD and 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Support Cudd_SupportIndices Cudd_ClassifySupport] + +******************************************************************************/ +int * +Cudd_SupportIndex( + DdManager * dd /* manager */, + DdNode * f /* DD whose support is sought */) +{ + int *support; + int i; + int size; + + /* Allocate and initialize support array for ddSupportStep. */ + size = ddMax(dd->size, dd->sizeZ); + support = ALLOC(int,size); + if (support == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + support[i] = 0; + } + + /* Compute support and clean up markers. */ + ddSupportStep(Cudd_Regular(f),support); + ddClearFlag(Cudd_Regular(f)); + + return(support); + +} /* end of Cudd_SupportIndex */ + + +/**Function******************************************************************** + + Synopsis [Counts the variables on which a DD depends.] + + Description [Returns the variables on which a DD depends.] + + SideEffects [None] + + SeeAlso [Cudd_Support Cudd_SupportIndices] + +******************************************************************************/ +int +Cudd_SupportSize( + DdManager * dd /* manager */, + DdNode * f /* DD whose support size is sought */) +{ + int SP = 0; + + ddFindSupport(dd, Cudd_Regular(f), &SP); + ddClearFlag(Cudd_Regular(f)); + ddClearVars(dd, SP); + + return(SP); + +} /* end of Cudd_SupportSize */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a set of DDs depends.] + + Description [Finds the variables on which a set of DDs depends. The + set must contain either BDDs and ADDs, or ZDDs. Returns the number + of variables if successful; CUDD_OUT_OF_MEM otherwise.] + + SideEffects [The indices of the support variables are returned as + side effects. If the function is constant, no array is allocated.] + + SeeAlso [Cudd_Support Cudd_SupportIndex Cudd_VectorSupportIndices] + +******************************************************************************/ +int +Cudd_VectorSupportIndices( + DdManager * dd /* manager */, + DdNode ** F /* DD whose support is sought */, + int n /* size of the array */, + int **indices /* array containing (on return) the indices */) +{ + int i; + int SP = 0; + + /* Compute support and clean up markers. */ + for (i = 0; i < n; i++) { + ddFindSupport(dd, Cudd_Regular(F[i]), &SP); + } + for (i = 0; i < n; i++) { + ddClearFlag(Cudd_Regular(F[i])); + } + ddClearVars(dd, SP); + + if (SP > 0) { + int i; + *indices = ALLOC(int, SP); + if (*indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + + for (i = 0; i < SP; i++) + (*indices)[i] = (int) (ptrint) dd->stack[i]; + + qsort(*indices, SP, sizeof(int), indexCompare); + } else { + *indices = NULL; + } + + return(SP); + +} /* end of Cudd_VectorSupportIndices */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a set of DDs depends.] + + Description [Finds the variables on which a set of DDs depends. + The set must contain either BDDs and ADDs, or ZDDs. + Returns a BDD consisting of the product of the variables if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Support Cudd_ClassifySupport] + +******************************************************************************/ +DdNode * +Cudd_VectorSupport( + DdManager * dd /* manager */, + DdNode ** F /* array of DDs whose support is sought */, + int n /* size of the array */) +{ + int *support; + DdNode *res; + int j; + int size = Cudd_VectorSupportIndices(dd, F, n, &support); + if (size == CUDD_OUT_OF_MEM) + return(NULL); + + /* Transform support from array of indices to cube. */ + res = DD_ONE(dd); + cuddRef(res); + + for (j = size - 1; j >= 0; j--) { /* for each index bottom-up (almost) */ + int index = support[j]; + DdNode *var = dd->vars[index]; + DdNode *tmp = Cudd_bddAnd(dd,res,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,res); + FREE(support); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,res); + res = tmp; + } + + FREE(support); + cuddDeref(res); + return(res); + +} /* end of Cudd_VectorSupport */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a set of DDs depends.] + + Description [Finds the variables on which a set of DDs depends. + The set must contain either BDDs and ADDs, or ZDDs. + Returns an index array of the variables if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_SupportIndex Cudd_VectorSupport Cudd_VectorSupportIndices] + +******************************************************************************/ +int * +Cudd_VectorSupportIndex( + DdManager * dd /* manager */, + DdNode ** F /* array of DDs whose support is sought */, + int n /* size of the array */) +{ + int *support; + int i; + int size; + + /* Allocate and initialize support array for ddSupportStep. */ + size = ddMax(dd->size, dd->sizeZ); + support = ALLOC(int,size); + if (support == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + support[i] = 0; + } + + /* Compute support and clean up markers. */ + for (i = 0; i < n; i++) { + ddSupportStep(Cudd_Regular(F[i]),support); + } + for (i = 0; i < n; i++) { + ddClearFlag(Cudd_Regular(F[i])); + } + + return(support); + +} /* end of Cudd_VectorSupportIndex */ + + +/**Function******************************************************************** + + Synopsis [Counts the variables on which a set of DDs depends.] + + Description [Returns the variables on which a set of DDs depends. + The set must contain either BDDs and ADDs, or ZDDs.] + + SideEffects [None] + + SeeAlso [Cudd_VectorSupport Cudd_SupportSize] + +******************************************************************************/ +int +Cudd_VectorSupportSize( + DdManager * dd /* manager */, + DdNode ** F /* array of DDs whose support is sought */, + int n /* size of the array */) +{ + int i; + int SP = 0; + + /* Compute support and clean up markers. */ + for (i = 0; i < n; i++) { + ddFindSupport(dd, Cudd_Regular(F[i]), &SP); + } + for (i = 0; i < n; i++) { + ddClearFlag(Cudd_Regular(F[i])); + } + ddClearVars(dd, SP); + + return(SP); + +} /* end of Cudd_VectorSupportSize */ + + +/**Function******************************************************************** + + Synopsis [Classifies the variables in the support of two DDs.] + + Description [Classifies the variables in the support of two DDs + f and g, depending on whther they appear + in both DDs, only in f, or only in g. + Returns 1 if successful; 0 otherwise.] + + SideEffects [The cubes of the three classes of variables are + returned as side effects.] + + SeeAlso [Cudd_Support Cudd_VectorSupport] + +******************************************************************************/ +int +Cudd_ClassifySupport( + DdManager * dd /* manager */, + DdNode * f /* first DD */, + DdNode * g /* second DD */, + DdNode ** common /* cube of shared variables */, + DdNode ** onlyF /* cube of variables only in f */, + DdNode ** onlyG /* cube of variables only in g */) +{ + int *supportF, *supportG; + int fi, gi; + int sizeF, sizeG; + + sizeF = Cudd_SupportIndices(dd, f, &supportF); + if (sizeF == CUDD_OUT_OF_MEM) + return(0); + + sizeG = Cudd_SupportIndices(dd, g, &supportG); + if (sizeG == CUDD_OUT_OF_MEM) { + FREE(supportF); + return(0); + } + + /* Classify variables and create cubes. This part of the procedure + ** relies on the sorting of the indices in the two support arrays. + */ + *common = *onlyF = *onlyG = DD_ONE(dd); + cuddRef(*common); cuddRef(*onlyF); cuddRef(*onlyG); + fi = sizeF - 1; + gi = sizeG - 1; + while (fi >= 0 || gi >= 0) { + int indexF = fi >= 0 ? supportF[fi] : -1; + int indexG = gi >= 0 ? supportG[gi] : -1; + int index = ddMax(indexF, indexG); + DdNode *var = dd->vars[index]; +#ifdef DD_DEBUG + assert(index >= 0); +#endif + if (indexF == indexG) { + DdNode *tmp = Cudd_bddAnd(dd,*common,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + FREE(supportF); FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*common); + *common = tmp; + fi--; + gi--; + } else if (index == indexF) { + DdNode *tmp = Cudd_bddAnd(dd,*onlyF,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + FREE(supportF); FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*onlyF); + *onlyF = tmp; + fi--; + } else { /* index == indexG */ + DdNode *tmp = Cudd_bddAnd(dd,*onlyG,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + FREE(supportF); FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*onlyG); + *onlyG = tmp; + gi--; + } + } + + FREE(supportF); FREE(supportG); + cuddDeref(*common); cuddDeref(*onlyF); cuddDeref(*onlyG); + return(1); + +} /* end of Cudd_ClassifySupport */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of leaves in a DD.] + + Description [Counts the number of leaves in a DD. Returns the number + of leaves in the DD rooted at node if successful; CUDD_OUT_OF_MEM + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug] + +******************************************************************************/ +int +Cudd_CountLeaves( + DdNode * node) +{ + int i; + + i = ddLeavesInt(Cudd_Regular(node)); + ddClearFlag(Cudd_Regular(node)); + return(i); + +} /* end of Cudd_CountLeaves */ + + +/**Function******************************************************************** + + Synopsis [Picks one on-set cube randomly from the given DD.] + + Description [Picks one on-set cube randomly from the given DD. The + cube is written into an array of characters. The array must have at + least as many entries as there are variables. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPickOneMinterm] + +******************************************************************************/ +int +Cudd_bddPickOneCube( + DdManager * ddm, + DdNode * node, + char * string) +{ + DdNode *N, *T, *E; + DdNode *one, *bzero; + char dir; + int i; + + if (string == NULL || node == NULL) return(0); + + /* The constant 0 function has no on-set cubes. */ + one = DD_ONE(ddm); + bzero = Cudd_Not(one); + if (node == bzero) return(0); + + for (i = 0; i < ddm->size; i++) string[i] = 2; + + for (;;) { + + if (node == one) break; + + N = Cudd_Regular(node); + + T = cuddT(N); E = cuddE(N); + if (Cudd_IsComplement(node)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + if (T == bzero) { + string[N->index] = 0; + node = E; + } else if (E == bzero) { + string[N->index] = 1; + node = T; + } else { + dir = (char) ((Cudd_Random() & 0x2000) >> 13); + string[N->index] = dir; + node = dir ? T : E; + } + } + return(1); + +} /* end of Cudd_bddPickOneCube */ + + +/**Function******************************************************************** + + Synopsis [Picks one on-set minterm randomly from the given DD.] + + Description [Picks one on-set minterm randomly from the given + DD. The minterm is in terms of vars. The array + vars should contain at least all variables in the + support of f; if this condition is not met the minterm + built by this procedure may not be contained in + f. Builds a BDD for the minterm and returns a pointer + to it if successful; NULL otherwise. There are three reasons why the + procedure may fail: +
                  +
                • It may run out of memory; +
                • the function f may be the constant 0; +
                • the minterm may not be contained in f. +
                ] + + SideEffects [None] + + SeeAlso [Cudd_bddPickOneCube] + +******************************************************************************/ +DdNode * +Cudd_bddPickOneMinterm( + DdManager * dd /* manager */, + DdNode * f /* function from which to pick one minterm */, + DdNode ** vars /* array of variables */, + int n /* size of vars */) +{ + char *string; + int i, size; + int *indices; + int result; + DdNode *old, *neW; + + size = dd->size; + string = ALLOC(char, size); + if (string == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + indices = ALLOC(int,n); + if (indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(string); + return(NULL); + } + + for (i = 0; i < n; i++) { + indices[i] = vars[i]->index; + } + + result = Cudd_bddPickOneCube(dd,f,string); + if (result == 0) { + FREE(string); + FREE(indices); + return(NULL); + } + + /* Randomize choice for don't cares. */ + for (i = 0; i < n; i++) { + if (string[indices[i]] == 2) + string[indices[i]] = (char) ((Cudd_Random() & 0x20) >> 5); + } + + /* Build result BDD. */ + old = Cudd_ReadOne(dd); + cuddRef(old); + + for (i = n-1; i >= 0; i--) { + neW = Cudd_bddAnd(dd,old,Cudd_NotCond(vars[i],string[indices[i]]==0)); + if (neW == NULL) { + FREE(string); + FREE(indices); + Cudd_RecursiveDeref(dd,old); + return(NULL); + } + cuddRef(neW); + Cudd_RecursiveDeref(dd,old); + old = neW; + } + +#ifdef DD_DEBUG + /* Test. */ + if (Cudd_bddLeq(dd,old,f)) { + cuddDeref(old); + } else { + Cudd_RecursiveDeref(dd,old); + old = NULL; + } +#else + cuddDeref(old); +#endif + + FREE(string); + FREE(indices); + return(old); + +} /* end of Cudd_bddPickOneMinterm */ + + +/**Function******************************************************************** + + Synopsis [Picks k on-set minterms evenly distributed from given DD.] + + Description [Picks k on-set minterms evenly distributed from given DD. + The minterms are in terms of vars. The array + vars should contain at least all variables in the + support of f; if this condition is not met the minterms + built by this procedure may not be contained in + f. Builds an array of BDDs for the minterms and returns a + pointer to it if successful; NULL otherwise. There are three reasons + why the procedure may fail: +
                  +
                • It may run out of memory; +
                • the function f may be the constant 0; +
                • the minterms may not be contained in f. +
                ] + + SideEffects [None] + + SeeAlso [Cudd_bddPickOneMinterm Cudd_bddPickOneCube] + +******************************************************************************/ +DdNode ** +Cudd_bddPickArbitraryMinterms( + DdManager * dd /* manager */, + DdNode * f /* function from which to pick k minterms */, + DdNode ** vars /* array of variables */, + int n /* size of vars */, + int k /* number of minterms to find */) +{ + char **string; + int i, j, l, size; + int *indices; + int result; + DdNode **old, *neW; + double minterms; + char *saveString; + int saveFlag, savePoint, isSame; + + minterms = Cudd_CountMinterm(dd,f,n); + if ((double)k > minterms) { + return(NULL); + } + + size = dd->size; + string = ALLOC(char *, k); + if (string == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < k; i++) { + string[i] = ALLOC(char, size + 1); + if (string[i] == NULL) { + for (j = 0; j < i; j++) + FREE(string[i]); + FREE(string); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (j = 0; j < size; j++) string[i][j] = '2'; + string[i][size] = '\0'; + } + indices = ALLOC(int,n); + if (indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + FREE(string[i]); + FREE(string); + return(NULL); + } + + for (i = 0; i < n; i++) { + indices[i] = vars[i]->index; + } + + result = ddPickArbitraryMinterms(dd,f,n,k,string); + if (result == 0) { + for (i = 0; i < k; i++) + FREE(string[i]); + FREE(string); + FREE(indices); + return(NULL); + } + + old = ALLOC(DdNode *, k); + if (old == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + FREE(string[i]); + FREE(string); + FREE(indices); + return(NULL); + } + saveString = ALLOC(char, size + 1); + if (saveString == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + FREE(string[i]); + FREE(string); + FREE(indices); + FREE(old); + return(NULL); + } + saveFlag = 0; + + /* Build result BDD array. */ + for (i = 0; i < k; i++) { + isSame = 0; + if (!saveFlag) { + for (j = i + 1; j < k; j++) { + if (strcmp(string[i], string[j]) == 0) { + savePoint = i; + strcpy(saveString, string[i]); + saveFlag = 1; + break; + } + } + } else { + if (strcmp(string[i], saveString) == 0) { + isSame = 1; + } else { + saveFlag = 0; + for (j = i + 1; j < k; j++) { + if (strcmp(string[i], string[j]) == 0) { + savePoint = i; + strcpy(saveString, string[i]); + saveFlag = 1; + break; + } + } + } + } + /* Randomize choice for don't cares. */ + for (j = 0; j < n; j++) { + if (string[i][indices[j]] == '2') + string[i][indices[j]] = + (char) ((Cudd_Random() & 0x20) ? '1' : '0'); + } + + while (isSame) { + isSame = 0; + for (j = savePoint; j < i; j++) { + if (strcmp(string[i], string[j]) == 0) { + isSame = 1; + break; + } + } + if (isSame) { + strcpy(string[i], saveString); + /* Randomize choice for don't cares. */ + for (j = 0; j < n; j++) { + if (string[i][indices[j]] == '2') + string[i][indices[j]] = + (char) ((Cudd_Random() & 0x20) ? '1' : '0'); + } + } + } + + old[i] = Cudd_ReadOne(dd); + cuddRef(old[i]); + + for (j = 0; j < n; j++) { + if (string[i][indices[j]] == '0') { + neW = Cudd_bddAnd(dd,old[i],Cudd_Not(vars[j])); + } else { + neW = Cudd_bddAnd(dd,old[i],vars[j]); + } + if (neW == NULL) { + FREE(saveString); + for (l = 0; l < k; l++) + FREE(string[l]); + FREE(string); + FREE(indices); + for (l = 0; l <= i; l++) + Cudd_RecursiveDeref(dd,old[l]); + FREE(old); + return(NULL); + } + cuddRef(neW); + Cudd_RecursiveDeref(dd,old[i]); + old[i] = neW; + } + + /* Test. */ + if (!Cudd_bddLeq(dd,old[i],f)) { + FREE(saveString); + for (l = 0; l < k; l++) + FREE(string[l]); + FREE(string); + FREE(indices); + for (l = 0; l <= i; l++) + Cudd_RecursiveDeref(dd,old[l]); + FREE(old); + return(NULL); + } + } + + FREE(saveString); + for (i = 0; i < k; i++) { + cuddDeref(old[i]); + FREE(string[i]); + } + FREE(string); + FREE(indices); + return(old); + +} /* end of Cudd_bddPickArbitraryMinterms */ + + +/**Function******************************************************************** + + Synopsis [Extracts a subset from a BDD.] + + Description [Extracts a subset from a BDD in the following procedure. + 1. Compute the weight for each mask variable by counting the number of + minterms for both positive and negative cofactors of the BDD with + respect to each mask variable. (weight = #positive - #negative) + 2. Find a representative cube of the BDD by using the weight. From the + top variable of the BDD, for each variable, if the weight is greater + than 0.0, choose THEN branch, othereise ELSE branch, until meeting + the constant 1. + 3. Quantify out the variables not in maskVars from the representative + cube and if a variable in maskVars is don't care, replace the + variable with a constant(1 or 0) depending on the weight. + 4. Make a subset of the BDD by multiplying with the modified cube.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_SubsetWithMaskVars( + DdManager * dd /* manager */, + DdNode * f /* function from which to pick a cube */, + DdNode ** vars /* array of variables */, + int nvars /* size of vars */, + DdNode ** maskVars /* array of variables */, + int mvars /* size of maskVars */) +{ + double *weight; + char *string; + int i, size; + int *indices, *mask; + int result; + DdNode *zero, *cube, *newCube, *subset; + DdNode *cof; + + DdNode *support; + support = Cudd_Support(dd,f); + cuddRef(support); + Cudd_RecursiveDeref(dd,support); + + zero = Cudd_Not(dd->one); + size = dd->size; + + weight = ALLOC(double,size); + if (weight == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + weight[i] = 0.0; + } + for (i = 0; i < mvars; i++) { + cof = Cudd_Cofactor(dd, f, maskVars[i]); + cuddRef(cof); + weight[i] = Cudd_CountMinterm(dd, cof, nvars); + Cudd_RecursiveDeref(dd,cof); + + cof = Cudd_Cofactor(dd, f, Cudd_Not(maskVars[i])); + cuddRef(cof); + weight[i] -= Cudd_CountMinterm(dd, cof, nvars); + Cudd_RecursiveDeref(dd,cof); + } + + string = ALLOC(char, size + 1); + if (string == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(weight); + return(NULL); + } + mask = ALLOC(int, size); + if (mask == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(weight); + FREE(string); + return(NULL); + } + for (i = 0; i < size; i++) { + string[i] = '2'; + mask[i] = 0; + } + string[size] = '\0'; + indices = ALLOC(int,nvars); + if (indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(weight); + FREE(string); + FREE(mask); + return(NULL); + } + for (i = 0; i < nvars; i++) { + indices[i] = vars[i]->index; + } + + result = ddPickRepresentativeCube(dd,f,weight,string); + if (result == 0) { + FREE(weight); + FREE(string); + FREE(mask); + FREE(indices); + return(NULL); + } + + cube = Cudd_ReadOne(dd); + cuddRef(cube); + zero = Cudd_Not(Cudd_ReadOne(dd)); + for (i = 0; i < nvars; i++) { + if (string[indices[i]] == '0') { + newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); + } else if (string[indices[i]] == '1') { + newCube = Cudd_bddIte(dd,cube,vars[i],zero); + } else + continue; + if (newCube == NULL) { + FREE(weight); + FREE(string); + FREE(mask); + FREE(indices); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(newCube); + Cudd_RecursiveDeref(dd,cube); + cube = newCube; + } + Cudd_RecursiveDeref(dd,cube); + + for (i = 0; i < mvars; i++) { + mask[maskVars[i]->index] = 1; + } + for (i = 0; i < nvars; i++) { + if (mask[indices[i]]) { + if (string[indices[i]] == '2') { + if (weight[indices[i]] >= 0.0) + string[indices[i]] = '1'; + else + string[indices[i]] = '0'; + } + } else { + string[indices[i]] = '2'; + } + } + + cube = Cudd_ReadOne(dd); + cuddRef(cube); + zero = Cudd_Not(Cudd_ReadOne(dd)); + + /* Build result BDD. */ + for (i = 0; i < nvars; i++) { + if (string[indices[i]] == '0') { + newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); + } else if (string[indices[i]] == '1') { + newCube = Cudd_bddIte(dd,cube,vars[i],zero); + } else + continue; + if (newCube == NULL) { + FREE(weight); + FREE(string); + FREE(mask); + FREE(indices); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(newCube); + Cudd_RecursiveDeref(dd,cube); + cube = newCube; + } + + subset = Cudd_bddAnd(dd,f,cube); + cuddRef(subset); + Cudd_RecursiveDeref(dd,cube); + + /* Test. */ + if (Cudd_bddLeq(dd,subset,f)) { + cuddDeref(subset); + } else { + Cudd_RecursiveDeref(dd,subset); + subset = NULL; + } + + FREE(weight); + FREE(string); + FREE(mask); + FREE(indices); + return(subset); + +} /* end of Cudd_SubsetWithMaskVars */ + + +/**Function******************************************************************** + + Synopsis [Finds the first cube of a decision diagram.] + + Description [Defines an iterator on the onset of a decision diagram + and finds its first cube. Returns a generator that contains the + information necessary to continue the enumeration if successful; NULL + otherwise.

                + A cube is represented as an array of literals, which are integers in + {0, 1, 2}; 0 represents a complemented literal, 1 represents an + uncomplemented literal, and 2 stands for don't care. The enumeration + produces a disjoint cover of the function associated with the diagram. + The size of the array equals the number of variables in the manager at + the time Cudd_FirstCube is called.

                + For each cube, a value is also returned. This value is always 1 for a + BDD, while it may be different from 1 for an ADD. + For BDDs, the offset is the set of cubes whose value is the logical zero. + For ADDs, the offset is the set of cubes whose value is the + background value. The cubes of the offset are not enumerated.] + + SideEffects [The first cube and its value are returned as side effects.] + + SeeAlso [Cudd_ForeachCube Cudd_NextCube Cudd_GenFree Cudd_IsGenEmpty + Cudd_FirstNode] + +******************************************************************************/ +DdGen * +Cudd_FirstCube( + DdManager * dd, + DdNode * f, + int ** cube, + CUDD_VALUE_TYPE * value) +{ + DdGen *gen; + DdNode *top, *treg, *next, *nreg, *prev, *preg; + int i; + int nvars; + + /* Sanity Check. */ + if (dd == NULL || f == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ALLOC(DdGen,1); + if (gen == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = dd; + gen->type = CUDD_GEN_CUBES; + gen->status = CUDD_GEN_EMPTY; + gen->gen.cubes.cube = NULL; + gen->gen.cubes.value = DD_ZERO_VAL; + gen->stack.sp = 0; + gen->stack.stack = NULL; + gen->node = NULL; + + nvars = dd->size; + gen->gen.cubes.cube = ALLOC(int,nvars); + if (gen->gen.cubes.cube == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(gen); + return(NULL); + } + for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; + + /* The maximum stack depth is one plus the number of variables. + ** because a path may have nodes at all levels, including the + ** constant level. + */ + gen->stack.stack = ALLOC(DdNodePtr, nvars+1); + if (gen->stack.stack == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(gen->gen.cubes.cube); + FREE(gen); + return(NULL); + } + for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; + + /* Find the first cube of the onset. */ + gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; + + while (1) { + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + if (!cuddIsConstant(treg)) { + /* Take the else branch first. */ + gen->gen.cubes.cube[treg->index] = 0; + next = cuddE(treg); + if (top != treg) next = Cudd_Not(next); + gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; + } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { + /* Backtrack */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = gen->stack.stack[gen->stack.sp-2]; + preg = Cudd_Regular(prev); + nreg = cuddT(preg); + if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[preg->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[preg->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(top); + goto done; + } + } + +done: + *cube = gen->gen.cubes.cube; + *value = gen->gen.cubes.value; + return(gen); + +} /* end of Cudd_FirstCube */ + + +/**Function******************************************************************** + + Synopsis [Generates the next cube of a decision diagram onset.] + + Description [Generates the next cube of a decision diagram onset, + using generator gen. Returns 0 if the enumeration is completed; 1 + otherwise.] + + SideEffects [The cube and its value are returned as side effects. The + generator is modified.] + + SeeAlso [Cudd_ForeachCube Cudd_FirstCube Cudd_GenFree Cudd_IsGenEmpty + Cudd_NextNode] + +******************************************************************************/ +int +Cudd_NextCube( + DdGen * gen, + int ** cube, + CUDD_VALUE_TYPE * value) +{ + DdNode *top, *treg, *next, *nreg, *prev, *preg; + DdManager *dd = gen->manager; + + /* Backtrack from previously reached terminal node. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + prev = gen->stack.stack[gen->stack.sp-2]; + preg = Cudd_Regular(prev); + nreg = cuddT(preg); + if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[preg->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[preg->index] = 2; + gen->stack.sp--; + } + + while (1) { + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + if (!cuddIsConstant(treg)) { + /* Take the else branch first. */ + gen->gen.cubes.cube[treg->index] = 0; + next = cuddE(treg); + if (top != treg) next = Cudd_Not(next); + gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; + } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { + /* Backtrack */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = gen->stack.stack[gen->stack.sp-2]; + preg = Cudd_Regular(prev); + nreg = cuddT(preg); + if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[preg->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[preg->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(top); + goto done; + } + } + +done: + if (gen->status == CUDD_GEN_EMPTY) return(0); + *cube = gen->gen.cubes.cube; + *value = gen->gen.cubes.value; + return(1); + +} /* end of Cudd_NextCube */ + + +/**Function******************************************************************** + + Synopsis [Finds the first prime of a Boolean function.] + + Description [Defines an iterator on a pair of BDDs describing a + (possibly incompletely specified) Boolean functions and finds the + first cube of a cover of the function. Returns a generator + that contains the information necessary to continue the enumeration + if successful; NULL otherwise.

                + + The two argument BDDs are the lower and upper bounds of an interval. + It is a mistake to call this function with a lower bound that is not + less than or equal to the upper bound.

                + + A cube is represented as an array of literals, which are integers in + {0, 1, 2}; 0 represents a complemented literal, 1 represents an + uncomplemented literal, and 2 stands for don't care. The enumeration + produces a prime and irredundant cover of the function associated + with the two BDDs. The size of the array equals the number of + variables in the manager at the time Cudd_FirstCube is called.

                + + This iterator can only be used on BDDs.] + + SideEffects [The first cube is returned as side effect.] + + SeeAlso [Cudd_ForeachPrime Cudd_NextPrime Cudd_GenFree Cudd_IsGenEmpty + Cudd_FirstCube Cudd_FirstNode] + +******************************************************************************/ +DdGen * +Cudd_FirstPrime( + DdManager *dd, + DdNode *l, + DdNode *u, + int **cube) +{ + DdGen *gen; + DdNode *implicant, *prime, *tmp; + int length, result; + + /* Sanity Check. */ + if (dd == NULL || l == NULL || u == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ALLOC(DdGen,1); + if (gen == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = dd; + gen->type = CUDD_GEN_PRIMES; + gen->status = CUDD_GEN_EMPTY; + gen->gen.primes.cube = NULL; + gen->gen.primes.ub = u; + gen->stack.sp = 0; + gen->stack.stack = NULL; + gen->node = l; + cuddRef(l); + + gen->gen.primes.cube = ALLOC(int,dd->size); + if (gen->gen.primes.cube == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(gen); + return(NULL); + } + + if (gen->node == Cudd_ReadLogicZero(dd)) { + gen->status = CUDD_GEN_EMPTY; + } else { + implicant = Cudd_LargestCube(dd,gen->node,&length); + if (implicant == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + FREE(gen->gen.primes.cube); + FREE(gen); + return(NULL); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,implicant); + FREE(gen->gen.primes.cube); + FREE(gen); + return(NULL); + } + cuddRef(prime); + Cudd_RecursiveDeref(dd,implicant); + tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,prime); + FREE(gen->gen.primes.cube); + FREE(gen); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,gen->node); + gen->node = tmp; + result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); + if (result == 0) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,prime); + FREE(gen->gen.primes.cube); + FREE(gen); + return(NULL); + } + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_NONEMPTY; + } + *cube = gen->gen.primes.cube; + return(gen); + +} /* end of Cudd_FirstPrime */ + + +/**Function******************************************************************** + + Synopsis [Generates the next prime of a Boolean function.] + + Description [Generates the next cube of a Boolean function, + using generator gen. Returns 0 if the enumeration is completed; 1 + otherwise.] + + SideEffects [The cube and is returned as side effects. The + generator is modified.] + + SeeAlso [Cudd_ForeachPrime Cudd_FirstPrime Cudd_GenFree Cudd_IsGenEmpty + Cudd_NextCube Cudd_NextNode] + +******************************************************************************/ +int +Cudd_NextPrime( + DdGen *gen, + int **cube) +{ + DdNode *implicant, *prime, *tmp; + DdManager *dd = gen->manager; + int length, result; + + if (gen->node == Cudd_ReadLogicZero(dd)) { + gen->status = CUDD_GEN_EMPTY; + } else { + implicant = Cudd_LargestCube(dd,gen->node,&length); + if (implicant == NULL) { + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,implicant); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(prime); + Cudd_RecursiveDeref(dd,implicant); + tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,gen->node); + gen->node = tmp; + result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); + if (result == 0) { + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_NONEMPTY; + } + if (gen->status == CUDD_GEN_EMPTY) return(0); + *cube = gen->gen.primes.cube; + return(1); + +} /* end of Cudd_NextPrime */ + + +/**Function******************************************************************** + + Synopsis [Computes the cube of an array of BDD variables.] + + Description [Computes the cube of an array of BDD variables. If + non-null, the phase argument indicates which literal of each + variable should appear in the cube. If phase\[i\] is nonzero, then the + positive literal is used. If phase is NULL, the cube is positive unate. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addComputeCube Cudd_IndicesToCube Cudd_CubeArrayToBdd] + +******************************************************************************/ +DdNode * +Cudd_bddComputeCube( + DdManager * dd, + DdNode ** vars, + int * phase, + int n) +{ + DdNode *cube; + DdNode *fn; + int i; + + cube = DD_ONE(dd); + cuddRef(cube); + + for (i = n - 1; i >= 0; i--) { + if (phase == NULL || phase[i] != 0) { + fn = Cudd_bddAnd(dd,vars[i],cube); + } else { + fn = Cudd_bddAnd(dd,Cudd_Not(vars[i]),cube); + } + if (fn == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(fn); + Cudd_RecursiveDeref(dd,cube); + cube = fn; + } + cuddDeref(cube); + + return(cube); + +} /* end of Cudd_bddComputeCube */ + + +/**Function******************************************************************** + + Synopsis [Computes the cube of an array of ADD variables.] + + Description [Computes the cube of an array of ADD variables. If + non-null, the phase argument indicates which literal of each + variable should appear in the cube. If phase\[i\] is nonzero, then the + positive literal is used. If phase is NULL, the cube is positive unate. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [none] + + SeeAlso [Cudd_bddComputeCube] + +******************************************************************************/ +DdNode * +Cudd_addComputeCube( + DdManager * dd, + DdNode ** vars, + int * phase, + int n) +{ + DdNode *cube, *zero; + DdNode *fn; + int i; + + cube = DD_ONE(dd); + cuddRef(cube); + zero = DD_ZERO(dd); + + for (i = n - 1; i >= 0; i--) { + if (phase == NULL || phase[i] != 0) { + fn = Cudd_addIte(dd,vars[i],cube,zero); + } else { + fn = Cudd_addIte(dd,vars[i],zero,cube); + } + if (fn == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(fn); + Cudd_RecursiveDeref(dd,cube); + cube = fn; + } + cuddDeref(cube); + + return(cube); + +} /* end of Cudd_addComputeCube */ + + +/**Function******************************************************************** + + Synopsis [Builds the BDD of a cube from a positional array.] + + Description [Builds a cube from a positional array. The array must + have one integer entry for each BDD variable. If the i-th entry is + 1, the variable of index i appears in true form in the cube; If the + i-th entry is 0, the variable of index i appears complemented in the + cube; otherwise the variable does not appear in the cube. Returns a + pointer to the BDD for the cube if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddComputeCube Cudd_IndicesToCube Cudd_BddToCubeArray] + +******************************************************************************/ +DdNode * +Cudd_CubeArrayToBdd( + DdManager *dd, + int *array) +{ + DdNode *cube, *var, *tmp; + int i; + int size = Cudd_ReadSize(dd); + + cube = DD_ONE(dd); + cuddRef(cube); + for (i = size - 1; i >= 0; i--) { + if ((array[i] & ~1) == 0) { + var = Cudd_bddIthVar(dd,i); + tmp = Cudd_bddAnd(dd,cube,Cudd_NotCond(var,array[i]==0)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cube); + cube = tmp; + } + } + cuddDeref(cube); + return(cube); + +} /* end of Cudd_CubeArrayToBdd */ + + +/**Function******************************************************************** + + Synopsis [Builds a positional array from the BDD of a cube.] + + Description [Builds a positional array from the BDD of a cube. + Array must have one entry for each BDD variable. The positional + array has 1 in i-th position if the variable of index i appears in + true form in the cube; it has 0 in i-th position if the variable of + index i appears in complemented form in the cube; finally, it has 2 + in i-th position if the variable of index i does not appear in the + cube. Returns 1 if successful (the BDD is indeed a cube); 0 + otherwise.] + + SideEffects [The result is in the array passed by reference.] + + SeeAlso [Cudd_CubeArrayToBdd] + +******************************************************************************/ +int +Cudd_BddToCubeArray( + DdManager *dd, + DdNode *cube, + int *array) +{ + DdNode *scan, *t, *e; + int i; + int size = Cudd_ReadSize(dd); + DdNode *zero = Cudd_Not(DD_ONE(dd)); + + for (i = size-1; i >= 0; i--) { + array[i] = 2; + } + scan = cube; + while (!Cudd_IsConstant(scan)) { + int index = Cudd_Regular(scan)->index; + cuddGetBranches(scan,&t,&e); + if (t == zero) { + array[index] = 0; + scan = e; + } else if (e == zero) { + array[index] = 1; + scan = t; + } else { + return(0); /* cube is not a cube */ + } + } + if (scan == zero) { + return(0); + } else { + return(1); + } + +} /* end of Cudd_BddToCubeArray */ + + +/**Function******************************************************************** + + Synopsis [Finds the first node of a decision diagram.] + + Description [Defines an iterator on the nodes of a decision diagram + and finds its first node. Returns a generator that contains the + information necessary to continue the enumeration if successful; + NULL otherwise. The nodes are enumerated in a reverse topological + order, so that a node is always preceded in the enumeration by its + descendants.] + + SideEffects [The first node is returned as a side effect.] + + SeeAlso [Cudd_ForeachNode Cudd_NextNode Cudd_GenFree Cudd_IsGenEmpty + Cudd_FirstCube] + +******************************************************************************/ +DdGen * +Cudd_FirstNode( + DdManager * dd, + DdNode * f, + DdNode ** node) +{ + DdGen *gen; + int size; + + /* Sanity Check. */ + if (dd == NULL || f == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ALLOC(DdGen,1); + if (gen == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = dd; + gen->type = CUDD_GEN_NODES; + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp = 0; + gen->node = NULL; + + /* Collect all the nodes on the generator stack for later perusal. */ + gen->stack.stack = cuddNodeArray(Cudd_Regular(f), &size); + if (gen->stack.stack == NULL) { + FREE(gen); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + gen->gen.nodes.size = size; + + /* Find the first node. */ + if (gen->stack.sp < gen->gen.nodes.size) { + gen->status = CUDD_GEN_NONEMPTY; + gen->node = gen->stack.stack[gen->stack.sp]; + *node = gen->node; + } + + return(gen); + +} /* end of Cudd_FirstNode */ + + +/**Function******************************************************************** + + Synopsis [Finds the next node of a decision diagram.] + + Description [Finds the node of a decision diagram, using generator + gen. Returns 0 if the enumeration is completed; 1 otherwise.] + + SideEffects [The next node is returned as a side effect.] + + SeeAlso [Cudd_ForeachNode Cudd_FirstNode Cudd_GenFree Cudd_IsGenEmpty + Cudd_NextCube] + +******************************************************************************/ +int +Cudd_NextNode( + DdGen * gen, + DdNode ** node) +{ + /* Find the next node. */ + gen->stack.sp++; + if (gen->stack.sp < gen->gen.nodes.size) { + gen->node = gen->stack.stack[gen->stack.sp]; + *node = gen->node; + return(1); + } else { + gen->status = CUDD_GEN_EMPTY; + return(0); + } + +} /* end of Cudd_NextNode */ + + +/**Function******************************************************************** + + Synopsis [Frees a CUDD generator.] + + Description [Frees a CUDD generator. Always returns 0, so that it can + be used in mis-like foreach constructs.] + + SideEffects [None] + + SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube + Cudd_FirstNode Cudd_NextNode Cudd_IsGenEmpty] + +******************************************************************************/ +int +Cudd_GenFree( + DdGen * gen) +{ + if (gen == NULL) return(0); + switch (gen->type) { + case CUDD_GEN_CUBES: + case CUDD_GEN_ZDD_PATHS: + FREE(gen->gen.cubes.cube); + FREE(gen->stack.stack); + break; + case CUDD_GEN_PRIMES: + FREE(gen->gen.primes.cube); + Cudd_RecursiveDeref(gen->manager,gen->node); + break; + case CUDD_GEN_NODES: + FREE(gen->stack.stack); + break; + default: + return(0); + } + FREE(gen); + return(0); + +} /* end of Cudd_GenFree */ + + +/**Function******************************************************************** + + Synopsis [Queries the status of a generator.] + + Description [Queries the status of a generator. Returns 1 if the + generator is empty or NULL; 0 otherswise.] + + SideEffects [None] + + SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube + Cudd_FirstNode Cudd_NextNode Cudd_GenFree] + +******************************************************************************/ +int +Cudd_IsGenEmpty( + DdGen * gen) +{ + if (gen == NULL) return(1); + return(gen->status == CUDD_GEN_EMPTY); + +} /* end of Cudd_IsGenEmpty */ + + +/**Function******************************************************************** + + Synopsis [Builds a cube of BDD variables from an array of indices.] + + Description [Builds a cube of BDD variables from an array of indices. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddComputeCube Cudd_CubeArrayToBdd] + +******************************************************************************/ +DdNode * +Cudd_IndicesToCube( + DdManager * dd, + int * array, + int n) +{ + DdNode *cube, *tmp; + int i; + + cube = DD_ONE(dd); + cuddRef(cube); + for (i = n - 1; i >= 0; i--) { + tmp = Cudd_bddAnd(dd,Cudd_bddIthVar(dd,array[i]),cube); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cube); + cube = tmp; + } + + cuddDeref(cube); + return(cube); + +} /* end of Cudd_IndicesToCube */ + + +/**Function******************************************************************** + + Synopsis [Prints the package version number.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_PrintVersion( + FILE * fp) +{ + (void) fprintf(fp, "%s\n", CUDD_VERSION); + +} /* end of Cudd_PrintVersion */ + + +/**Function******************************************************************** + + Synopsis [Computes the average distance between adjacent nodes.] + + Description [Computes the average distance between adjacent nodes in + the manager. Adjacent nodes are node pairs such that the second node + is the then child, else child, or next node in the collision list.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +double +Cudd_AverageDistance( + DdManager * dd) +{ + double tetotal, nexttotal; + double tesubtotal, nextsubtotal; + double temeasured, nextmeasured; + int i, j; + int slots, nvars; + long diff; + DdNode *scan; + DdNodePtr *nodelist; + DdNode *sentinel = &(dd->sentinel); + + nvars = dd->size; + if (nvars == 0) return(0.0); + + /* Initialize totals. */ + tetotal = 0.0; + nexttotal = 0.0; + temeasured = 0.0; + nextmeasured = 0.0; + + /* Scan the variable subtables. */ + for (i = 0; i < nvars; i++) { + nodelist = dd->subtables[i].nodelist; + tesubtotal = 0.0; + nextsubtotal = 0.0; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != sentinel) { + diff = (long) scan - (long) cuddT(scan); + tesubtotal += (double) ddAbs(diff); + diff = (long) scan - (long) Cudd_Regular(cuddE(scan)); + tesubtotal += (double) ddAbs(diff); + temeasured += 2.0; + if (scan->next != sentinel) { + diff = (long) scan - (long) scan->next; + nextsubtotal += (double) ddAbs(diff); + nextmeasured += 1.0; + } + scan = scan->next; + } + } + tetotal += tesubtotal; + nexttotal += nextsubtotal; + } + + /* Scan the constant table. */ + nodelist = dd->constants.nodelist; + nextsubtotal = 0.0; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (scan->next != NULL) { + diff = (long) scan - (long) scan->next; + nextsubtotal += (double) ddAbs(diff); + nextmeasured += 1.0; + } + scan = scan->next; + } + } + nexttotal += nextsubtotal; + + return((tetotal + nexttotal) / (temeasured + nextmeasured)); + +} /* end of Cudd_AverageDistance */ + + +/**Function******************************************************************** + + Synopsis [Portable random number generator.] + + Description [Portable number generator based on ran2 from "Numerical + Recipes in C." It is a long period (> 2 * 10^18) random number generator + of L'Ecuyer with Bays-Durham shuffle. Returns a long integer uniformly + distributed between 0 and 2147483561 (inclusive of the endpoint values). + The random generator can be explicitly initialized by calling + Cudd_Srandom. If no explicit initialization is performed, then the + seed 1 is assumed.] + + SideEffects [None] + + SeeAlso [Cudd_Srandom] + +******************************************************************************/ +long +Cudd_Random(void) +{ + int i; /* index in the shuffle table */ + long int w; /* work variable */ + + /* cuddRand == 0 if the geneartor has not been initialized yet. */ + if (cuddRand == 0) Cudd_Srandom(1); + + /* Compute cuddRand = (cuddRand * LEQA1) % MODULUS1 avoiding + ** overflows by Schrage's method. + */ + w = cuddRand / LEQQ1; + cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; + cuddRand += (cuddRand < 0) * MODULUS1; + + /* Compute cuddRand2 = (cuddRand2 * LEQA2) % MODULUS2 avoiding + ** overflows by Schrage's method. + */ + w = cuddRand2 / LEQQ2; + cuddRand2 = LEQA2 * (cuddRand2 - w * LEQQ2) - w * LEQR2; + cuddRand2 += (cuddRand2 < 0) * MODULUS2; + + /* cuddRand is shuffled with the Bays-Durham algorithm. + ** shuffleSelect and cuddRand2 are combined to generate the output. + */ + + /* Pick one element from the shuffle table; "i" will be in the range + ** from 0 to STAB_SIZE-1. + */ + i = (int) (shuffleSelect / STAB_DIV); + /* Mix the element of the shuffle table with the current iterate of + ** the second sub-generator, and replace the chosen element of the + ** shuffle table with the current iterate of the first sub-generator. + */ + shuffleSelect = shuffleTable[i] - cuddRand2; + shuffleTable[i] = cuddRand; + shuffleSelect += (shuffleSelect < 1) * (MODULUS1 - 1); + /* Since shuffleSelect != 0, and we want to be able to return 0, + ** here we subtract 1 before returning. + */ + return(shuffleSelect - 1); + +} /* end of Cudd_Random */ + + +/**Function******************************************************************** + + Synopsis [Initializer for the portable random number generator.] + + Description [Initializer for the portable number generator based on + ran2 in "Numerical Recipes in C." The input is the seed for the + generator. If it is negative, its absolute value is taken as seed. + If it is 0, then 1 is taken as seed. The initialized sets up the two + recurrences used to generate a long-period stream, and sets up the + shuffle table.] + + SideEffects [None] + + SeeAlso [Cudd_Random] + +******************************************************************************/ +void +Cudd_Srandom( + long seed) +{ + int i; + + if (seed < 0) cuddRand = -seed; + else if (seed == 0) cuddRand = 1; + else cuddRand = seed; + cuddRand2 = cuddRand; + /* Load the shuffle table (after 11 warm-ups). */ + for (i = 0; i < STAB_SIZE + 11; i++) { + long int w; + w = cuddRand / LEQQ1; + cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; + cuddRand += (cuddRand < 0) * MODULUS1; + shuffleTable[i % STAB_SIZE] = cuddRand; + } + shuffleSelect = shuffleTable[1 % STAB_SIZE]; + +} /* end of Cudd_Srandom */ + + +/**Function******************************************************************** + + Synopsis [Computes the density of a BDD or ADD.] + + Description [Computes the density of a BDD or ADD. The density is + the ratio of the number of minterms to the number of nodes. If 0 is + passed as number of variables, the number of variables existing in + the manager is used. Returns the density if successful; (double) + CUDD_OUT_OF_MEM otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_CountMinterm Cudd_DagSize] + +******************************************************************************/ +double +Cudd_Density( + DdManager * dd /* manager */, + DdNode * f /* function whose density is sought */, + int nvars /* size of the support of f */) +{ + double minterms; + int nodes; + double density; + + if (nvars == 0) nvars = dd->size; + minterms = Cudd_CountMinterm(dd,f,nvars); + if (minterms == (double) CUDD_OUT_OF_MEM) return(minterms); + nodes = Cudd_DagSize(f); + density = minterms / (double) nodes; + return(density); + +} /* end of Cudd_Density */ + + +/**Function******************************************************************** + + Synopsis [Warns that a memory allocation failed.] + + Description [Warns that a memory allocation failed. + This function can be used as replacement of MMout_of_memory to prevent + the safe_mem functions of the util package from exiting when malloc + returns NULL. One possible use is in case of discretionary allocations; + for instance, the allocation of memory to enlarge the computed table.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_OutOfMem( + long size /* size of the allocation that failed */) +{ + (void) fflush(stdout); + (void) fprintf(stderr, "\nunable to allocate %ld bytes\n", size); + return; + +} /* end of Cudd_OutOfMem */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints a DD to the standard output. One line per node is + printed.] + + Description [Prints a DD to the standard output. One line per node is + printed. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug] + +******************************************************************************/ +int +cuddP( + DdManager * dd, + DdNode * f) +{ + int retval; + st_table *table = st_init_table(st_ptrcmp,st_ptrhash); + + if (table == NULL) return(0); + + retval = dp2(dd,f,table); + st_free_table(table); + (void) fputc('\n',dd->out); + return(retval); + +} /* end of cuddP */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory used to store the minterm counts recorded + in the visited table.] + + Description [Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +enum st_retval +cuddStCountfree( + char * key, + char * value, + char * arg) +{ + double *d; + + d = (double *)value; + FREE(d); + return(ST_CONTINUE); + +} /* end of cuddStCountfree */ + + +/**Function******************************************************************** + + Synopsis [Recursively collects all the nodes of a DD in a symbol + table.] + + Description [Traverses the DD f and collects all its nodes in a + symbol table. f is assumed to be a regular pointer and + cuddCollectNodes guarantees this assumption in the recursive calls. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddCollectNodes( + DdNode * f, + st_table * visited) +{ + DdNode *T, *E; + int retval; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + /* If already visited, nothing to do. */ + if (st_is_member(visited, (char *) f) == 1) + return(1); + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Mark node as visited. */ + if (st_add_direct(visited, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + + /* Check terminal case. */ + if (cuddIsConstant(f)) + return(1); + + /* Recursive calls. */ + T = cuddT(f); + retval = cuddCollectNodes(T,visited); + if (retval != 1) return(retval); + E = Cudd_Regular(cuddE(f)); + retval = cuddCollectNodes(E,visited); + return(retval); + +} /* end of cuddCollectNodes */ + + +/**Function******************************************************************** + + Synopsis [Recursively collects all the nodes of a DD in an array.] + + Description [Traverses the DD f and collects all its nodes in an array. + The caller should free the array returned by cuddNodeArray. + Returns a pointer to the array of nodes in case of success; NULL + otherwise. The nodes are collected in reverse topological order, so + that a node is always preceded in the array by all its descendants.] + + SideEffects [The number of nodes is returned as a side effect.] + + SeeAlso [Cudd_FirstNode] + +******************************************************************************/ +DdNodePtr * +cuddNodeArray( + DdNode *f, + int *n) +{ + DdNodePtr *table; + int size, retval; + + size = ddDagInt(Cudd_Regular(f)); + table = ALLOC(DdNodePtr, size); + if (table == NULL) { + ddClearFlag(Cudd_Regular(f)); + return(NULL); + } + + retval = cuddNodeArrayRecur(f, table, 0); + assert(retval == size); + + *n = size; + return(table); + +} /* cuddNodeArray */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of cuddP.] + + Description [Performs the recursive step of cuddP. Returns 1 in case + of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +dp2( + DdManager *dd, + DdNode * f, + st_table * t) +{ + DdNode *g, *n, *N; + int T,E; + + if (f == NULL) { + return(0); + } + g = Cudd_Regular(f); + if (cuddIsConstant(g)) { +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"ID = %c0x%lx\tvalue = %-9g\n", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g)); +#else + (void) fprintf(dd->out,"ID = %c0x%x\tvalue = %-9g\n", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g)); +#endif + return(1); + } + if (st_is_member(t,(char *) g) == 1) { + return(1); + } + if (st_add_direct(t,(char *) g,NULL) == ST_OUT_OF_MEM) + return(0); +#ifdef DD_STATS +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %d\tr = %d\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode), g->index, g->ref); +#else + (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\tr = %d\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),g->index,g->ref); +#endif +#else +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %u\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),g->index); +#else + (void) fprintf(dd->out,"ID = %c0x%x\tindex = %hu\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),g->index); +#endif +#endif + n = cuddT(g); + if (cuddIsConstant(n)) { + (void) fprintf(dd->out,"T = %-9g\t",cuddV(n)); + T = 1; + } else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"T = 0x%lx\t",(ptruint) n / (ptruint) sizeof(DdNode)); +#else + (void) fprintf(dd->out,"T = 0x%x\t",(ptruint) n / (ptruint) sizeof(DdNode)); +#endif + T = 0; + } + + n = cuddE(g); + N = Cudd_Regular(n); + if (cuddIsConstant(N)) { + (void) fprintf(dd->out,"E = %c%-9g\n",bang(n),cuddV(N)); + E = 1; + } else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"E = %c0x%lx\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode)); +#else + (void) fprintf(dd->out,"E = %c0x%x\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode)); +#endif + E = 0; + } + if (E == 0) { + if (dp2(dd,N,t) == 0) + return(0); + } + if (T == 0) { + if (dp2(dd,cuddT(g),t) == 0) + return(0); + } + return(1); + +} /* end of dp2 */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_PrintMinterm.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static void +ddPrintMintermAux( + DdManager * dd /* manager */, + DdNode * node /* current node */, + int * list /* current recursion path */) +{ + DdNode *N,*Nv,*Nnv; + int i,v,index; + + N = Cudd_Regular(node); + + if (cuddIsConstant(N)) { + /* Terminal case: Print one cube based on the current recursion + ** path, unless we have reached the background value (ADDs) or + ** the logical zero (BDDs). + */ + if (node != background && node != zero) { + for (i = 0; i < dd->size; i++) { + v = list[i]; + if (v == 0) (void) fprintf(dd->out,"0"); + else if (v == 1) (void) fprintf(dd->out,"1"); + else (void) fprintf(dd->out,"-"); + } + (void) fprintf(dd->out," % g\n", cuddV(node)); + } + } else { + Nv = cuddT(N); + Nnv = cuddE(N); + if (Cudd_IsComplement(node)) { + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); + } + index = N->index; + list[index] = 0; + ddPrintMintermAux(dd,Nnv,list); + list[index] = 1; + ddPrintMintermAux(dd,Nv,list); + list[index] = 2; + } + return; + +} /* end of ddPrintMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DagSize.] + + Description [Performs the recursive step of Cudd_DagSize. Returns the + number of nodes in the graph rooted at n.] + + SideEffects [None] + +******************************************************************************/ +static int +ddDagInt( + DdNode * n) +{ + int tval, eval; + + if (Cudd_IsComplement(n->next)) { + return(0); + } + n->next = Cudd_Not(n->next); + if (cuddIsConstant(n)) { + return(1); + } + tval = ddDagInt(cuddT(n)); + eval = ddDagInt(Cudd_Regular(cuddE(n))); + return(1 + tval + eval); + +} /* end of ddDagInt */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of cuddNodeArray.] + + Description [Performs the recursive step of cuddNodeArray. Returns + an the number of nodes in the DD. Clear the least significant bit + of the next field that was used as visited flag by + cuddNodeArrayRecur when counting the nodes. node is supposed to be + regular; the invariant is maintained by this procedure.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddNodeArrayRecur( + DdNode *f, + DdNodePtr *table, + int index) +{ + int tindex, eindex; + + if (!Cudd_IsComplement(f->next)) { + return(index); + } + /* Clear visited flag. */ + f->next = Cudd_Regular(f->next); + if (cuddIsConstant(f)) { + table[index] = f; + return(index + 1); + } + tindex = cuddNodeArrayRecur(cuddT(f), table, index); + eindex = cuddNodeArrayRecur(Cudd_Regular(cuddE(f)), table, tindex); + table[eindex] = f; + return(eindex + 1); + +} /* end of cuddNodeArrayRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CofactorEstimate.] + + Description [Performs the recursive step of Cudd_CofactorEstimate. + Returns an estimate of the number of nodes in the DD of a + cofactor of node. Uses the least significant bit of the next field as + visited flag. node is supposed to be regular; the invariant is maintained + by this procedure.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddEstimateCofactor( + DdManager *dd, + st_table *table, + DdNode * node, + int i, + int phase, + DdNode ** ptr) +{ + int tval, eval, val; + DdNode *ptrT, *ptrE; + + if (Cudd_IsComplement(node->next)) { + if (!st_lookup(table,(char *)node,(char **)ptr)) { + if (st_add_direct(table,(char *)node,(char *)node) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + *ptr = node; + } + return(0); + } + node->next = Cudd_Not(node->next); + if (cuddIsConstant(node)) { + *ptr = node; + if (st_add_direct(table,(char *)node,(char *)node) == ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + return(1); + } + if ((int) node->index == i) { + if (phase == 1) { + *ptr = cuddT(node); + val = ddDagInt(cuddT(node)); + } else { + *ptr = cuddE(node); + val = ddDagInt(Cudd_Regular(cuddE(node))); + } + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + return(val); + } + if (dd->perm[node->index] > dd->perm[i]) { + *ptr = node; + tval = ddDagInt(cuddT(node)); + eval = ddDagInt(Cudd_Regular(cuddE(node))); + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)node) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + val = 1 + tval + eval; + return(val); + } + tval = cuddEstimateCofactor(dd,table,cuddT(node),i,phase,&ptrT); + eval = cuddEstimateCofactor(dd,table,Cudd_Regular(cuddE(node)),i, + phase,&ptrE); + ptrE = Cudd_NotCond(ptrE,Cudd_IsComplement(cuddE(node))); + if (ptrT == ptrE) { /* recombination */ + *ptr = ptrT; + val = tval; + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + } else if ((ptrT != cuddT(node) || ptrE != cuddE(node)) && + (*ptr = cuddUniqueLookup(dd,node->index,ptrT,ptrE)) != NULL) { + if (Cudd_IsComplement((*ptr)->next)) { + val = 0; + } else { + val = 1 + tval + eval; + } + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + } else { + *ptr = node; + val = 1 + tval + eval; + } + return(val); + +} /* end of cuddEstimateCofactor */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for the existence of an internal node.] + + Description [Checks the unique table for the existence of an internal + node. Returns a pointer to the node if it is in the table; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddUniqueInter] + +******************************************************************************/ +static DdNode * +cuddUniqueLookup( + DdManager * unique, + int index, + DdNode * T, + DdNode * E) +{ + int posn; + unsigned int level; + DdNodePtr *nodelist; + DdNode *looking; + DdSubtable *subtable; + + if (index >= unique->size) { + return(NULL); + } + + level = unique->perm[index]; + subtable = &(unique->subtables[level]); + +#ifdef DD_DEBUG + assert(level < (unsigned) cuddI(unique,T->index)); + assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index)); +#endif + + posn = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + looking = nodelist[posn]; + + while (T < cuddT(looking)) { + looking = Cudd_Regular(looking->next); + } + while (T == cuddT(looking) && E < cuddE(looking)) { + looking = Cudd_Regular(looking->next); + } + if (cuddT(looking) == T && cuddE(looking) == E) { + return(looking); + } + + return(NULL); + +} /* end of cuddUniqueLookup */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CofactorEstimateSimple.] + + Description [Performs the recursive step of Cudd_CofactorEstimateSimple. + Returns an estimate of the number of nodes in the DD of the positive + cofactor of node. Uses the least significant bit of the next field as + visited flag. node is supposed to be regular; the invariant is maintained + by this procedure.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddEstimateCofactorSimple( + DdNode * node, + int i) +{ + int tval, eval; + + if (Cudd_IsComplement(node->next)) { + return(0); + } + node->next = Cudd_Not(node->next); + if (cuddIsConstant(node)) { + return(1); + } + tval = cuddEstimateCofactorSimple(cuddT(node),i); + if ((int) node->index == i) return(tval); + eval = cuddEstimateCofactorSimple(Cudd_Regular(cuddE(node)),i); + return(1 + tval + eval); + +} /* end of cuddEstimateCofactorSimple */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CountMinterm.] + + Description [Performs the recursive step of Cudd_CountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: +

                + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. Does not use the + identity |f'| = max - |f|, to minimize loss of accuracy due to + roundoff. Returns the number of minterms of the function rooted at + node.] + + SideEffects [None] + +******************************************************************************/ +static double +ddCountMintermAux( + DdNode * node, + double max, + DdHashTable * table) +{ + DdNode *N, *Nt, *Ne; + double min, minT, minE; + DdNode *res; + + N = Cudd_Regular(node); + + if (cuddIsConstant(N)) { + if (node == background || node == zero) { + return(0.0); + } else { + return(max); + } + } + if (N->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) { + min = cuddV(res); + if (res->ref == 0) { + table->manager->dead++; + table->manager->constants.dead++; + } + return(min); + } + + Nt = cuddT(N); Ne = cuddE(N); + if (Cudd_IsComplement(node)) { + Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); + } + + minT = ddCountMintermAux(Nt,max,table); + if (minT == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + minT *= 0.5; + minE = ddCountMintermAux(Ne,max,table); + if (minE == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + minE *= 0.5; + min = minT + minE; + + if (N->ref != 1) { + ptrint fanout = (ptrint) N->ref; + cuddSatDec(fanout); + res = cuddUniqueConst(table->manager,min); + if (!cuddHashTableInsert1(table,node,res,fanout)) { + cuddRef(res); Cudd_RecursiveDeref(table->manager, res); + return((double)CUDD_OUT_OF_MEM); + } + } + + return(min); + +} /* end of ddCountMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CountPath.] + + Description [Performs the recursive step of Cudd_CountPath. + It is based on the following identity. Let |f| be the + number of paths of f. Then: + + |f| = |f0|+|f1| + + where f0 and f1 are the two cofactors of f. Uses the + identity |f'| = |f|, to improve the utilization of the (local) cache. + Returns the number of paths of the function rooted at node.] + + SideEffects [None] + +******************************************************************************/ +static double +ddCountPathAux( + DdNode * node, + st_table * table) +{ + + DdNode *Nv, *Nnv; + double paths, *ppaths, paths1, paths2; + double *dummy; + + + if (cuddIsConstant(node)) { + return(1.0); + } + if (st_lookup(table, node, &dummy)) { + paths = *dummy; + return(paths); + } + + Nv = cuddT(node); Nnv = cuddE(node); + + paths1 = ddCountPathAux(Nv,table); + if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + paths2 = ddCountPathAux(Cudd_Regular(Nnv),table); + if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + paths = paths1 + paths2; + + ppaths = ALLOC(double,1); + if (ppaths == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + + *ppaths = paths; + + if (st_add_direct(table,(char *)node, (char *)ppaths) == ST_OUT_OF_MEM) { + FREE(ppaths); + return((double)CUDD_OUT_OF_MEM); + } + return(paths); + +} /* end of ddCountPathAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_EpdCountMinterm.] + + Description [Performs the recursive step of Cudd_EpdCountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. Does not use the + identity |f'| = max - |f|, to minimize loss of accuracy due to + roundoff. Returns the number of minterms of the function rooted at + node.] + + SideEffects [None] + +******************************************************************************/ +static int +ddEpdCountMintermAux( + DdNode * node, + EpDouble * max, + EpDouble * epd, + st_table * table) +{ + DdNode *Nt, *Ne; + EpDouble *min, minT, minE; + EpDouble *res; + int status; + + /* node is assumed to be regular */ + if (cuddIsConstant(node)) { + if (node == background || node == zero) { + EpdMakeZero(epd, 0); + } else { + EpdCopy(max, epd); + } + return(0); + } + if (node->ref != 1 && st_lookup(table, node, &res)) { + EpdCopy(res, epd); + return(0); + } + + Nt = cuddT(node); Ne = cuddE(node); + + status = ddEpdCountMintermAux(Nt,max,&minT,table); + if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + EpdMultiply(&minT, (double)0.5); + status = ddEpdCountMintermAux(Cudd_Regular(Ne),max,&minE,table); + if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + if (Cudd_IsComplement(Ne)) { + EpdSubtract3(max, &minE, epd); + EpdCopy(epd, &minE); + } + EpdMultiply(&minE, (double)0.5); + EpdAdd3(&minT, &minE, epd); + + if (node->ref > 1) { + min = EpdAlloc(); + if (!min) + return(CUDD_OUT_OF_MEM); + EpdCopy(epd, min); + if (st_insert(table, (char *)node, (char *)min) == ST_OUT_OF_MEM) { + EpdFree(min); + return(CUDD_OUT_OF_MEM); + } + } + + return(0); + +} /* end of ddEpdCountMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CountPathsToNonZero.] + + Description [Performs the recursive step of Cudd_CountPathsToNonZero. + It is based on the following identity. Let |f| be the + number of paths of f. Then: + + |f| = |f0|+|f1| + + where f0 and f1 are the two cofactors of f. Returns the number of + paths of the function rooted at node.] + + SideEffects [None] + +******************************************************************************/ +static double +ddCountPathsToNonZero( + DdNode * N, + st_table * table) +{ + + DdNode *node, *Nt, *Ne; + double paths, *ppaths, paths1, paths2; + double *dummy; + + node = Cudd_Regular(N); + if (cuddIsConstant(node)) { + return((double) !(Cudd_IsComplement(N) || cuddV(node)==DD_ZERO_VAL)); + } + if (st_lookup(table, N, &dummy)) { + paths = *dummy; + return(paths); + } + + Nt = cuddT(node); Ne = cuddE(node); + if (node != N) { + Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); + } + + paths1 = ddCountPathsToNonZero(Nt,table); + if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + paths2 = ddCountPathsToNonZero(Ne,table); + if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + paths = paths1 + paths2; + + ppaths = ALLOC(double,1); + if (ppaths == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + + *ppaths = paths; + + if (st_add_direct(table,(char *)N, (char *)ppaths) == ST_OUT_OF_MEM) { + FREE(ppaths); + return((double)CUDD_OUT_OF_MEM); + } + return(paths); + +} /* end of ddCountPathsToNonZero */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_Support.] + + Description [Performs the recursive step of Cudd_Support. Performs a + DFS from f. The support is accumulated in supp as a side effect. Uses + the LSB of the then pointer as visited flag.] + + SideEffects [None] + + SeeAlso [ddClearFlag] + +******************************************************************************/ +static void +ddSupportStep( + DdNode * f, + int * support) +{ + if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) + return; + + support[f->index] = 1; + ddSupportStep(cuddT(f),support); + ddSupportStep(Cudd_Regular(cuddE(f)),support); + /* Mark as visited. */ + f->next = Cudd_Complement(f->next); + +} /* end of ddSupportStep */ + + +/**Function******************************************************************** + + Synopsis [Performs a DFS from f, clearing the LSB of the next + pointers.] + + Description [] + + SideEffects [None] + + SeeAlso [ddSupportStep ddFindSupport ddLeavesInt ddDagInt] + +******************************************************************************/ +static void +ddClearFlag( + DdNode * f) +{ + if (!Cudd_IsComplement(f->next)) { + return; + } + /* Clear visited flag. */ + f->next = Cudd_Regular(f->next); + if (cuddIsConstant(f)) { + return; + } + ddClearFlag(cuddT(f)); + ddClearFlag(Cudd_Regular(cuddE(f))); + return; + +} /* end of ddClearFlag */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CountLeaves.] + + Description [Performs the recursive step of Cudd_CountLeaves. Returns + the number of leaves in the DD rooted at n.] + + SideEffects [None] + + SeeAlso [Cudd_CountLeaves] + +******************************************************************************/ +static int +ddLeavesInt( + DdNode * n) +{ + int tval, eval; + + if (Cudd_IsComplement(n->next)) { + return(0); + } + n->next = Cudd_Not(n->next); + if (cuddIsConstant(n)) { + return(1); + } + tval = ddLeavesInt(cuddT(n)); + eval = ddLeavesInt(Cudd_Regular(cuddE(n))); + return(tval + eval); + +} /* end of ddLeavesInt */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddPickArbitraryMinterms.] + + Description [Performs the recursive step of Cudd_bddPickArbitraryMinterms. + Returns 1 if successful; 0 otherwise.] + + SideEffects [none] + + SeeAlso [Cudd_bddPickArbitraryMinterms] + +******************************************************************************/ +static int +ddPickArbitraryMinterms( + DdManager *dd, + DdNode *node, + int nvars, + int nminterms, + char **string) +{ + DdNode *N, *T, *E; + DdNode *one, *bzero; + int i, t, result; + double min1, min2; + + if (string == NULL || node == NULL) return(0); + + /* The constant 0 function has no on-set cubes. */ + one = DD_ONE(dd); + bzero = Cudd_Not(one); + if (nminterms == 0 || node == bzero) return(1); + if (node == one) { + return(1); + } + + N = Cudd_Regular(node); + T = cuddT(N); E = cuddE(N); + if (Cudd_IsComplement(node)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + + min1 = Cudd_CountMinterm(dd, T, nvars) / 2.0; + if (min1 == (double)CUDD_OUT_OF_MEM) return(0); + min2 = Cudd_CountMinterm(dd, E, nvars) / 2.0; + if (min2 == (double)CUDD_OUT_OF_MEM) return(0); + + t = (int)((double)nminterms * min1 / (min1 + min2) + 0.5); + for (i = 0; i < t; i++) + string[i][N->index] = '1'; + for (i = t; i < nminterms; i++) + string[i][N->index] = '0'; + + result = ddPickArbitraryMinterms(dd,T,nvars,t,&string[0]); + if (result == 0) + return(0); + result = ddPickArbitraryMinterms(dd,E,nvars,nminterms-t,&string[t]); + return(result); + +} /* end of ddPickArbitraryMinterms */ + + +/**Function******************************************************************** + + Synopsis [Finds a representative cube of a BDD.] + + Description [Finds a representative cube of a BDD with the weight of + each variable. From the top variable, if the weight is greater than or + equal to 0.0, choose THEN branch unless the child is the constant 0. + Otherwise, choose ELSE branch unless the child is the constant 0.] + + SideEffects [Cudd_SubsetWithMaskVars Cudd_bddPickOneCube] + +******************************************************************************/ +static int +ddPickRepresentativeCube( + DdManager *dd, + DdNode *node, + double *weight, + char *string) +{ + DdNode *N, *T, *E; + DdNode *one, *bzero; + + if (string == NULL || node == NULL) return(0); + + /* The constant 0 function has no on-set cubes. */ + one = DD_ONE(dd); + bzero = Cudd_Not(one); + if (node == bzero) return(0); + + if (node == DD_ONE(dd)) return(1); + + for (;;) { + N = Cudd_Regular(node); + if (N == one) + break; + T = cuddT(N); + E = cuddE(N); + if (Cudd_IsComplement(node)) { + T = Cudd_Not(T); + E = Cudd_Not(E); + } + if (weight[N->index] >= 0.0) { + if (T == bzero) { + node = E; + string[N->index] = '0'; + } else { + node = T; + string[N->index] = '1'; + } + } else { + if (E == bzero) { + node = T; + string[N->index] = '1'; + } else { + node = E; + string[N->index] = '0'; + } + } + } + return(1); + +} /* end of ddPickRepresentativeCube */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory used to store the minterm counts recorded + in the visited table.] + + Description [Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +ddEpdFree( + char * key, + char * value, + char * arg) +{ + EpDouble *epd; + + epd = (EpDouble *) value; + EpdFree(epd); + return(ST_CONTINUE); + +} /* end of ddEpdFree */ + + +/**Function******************************************************************** + + Synopsis [Recursively find the support of f.] + + Description [Recursively find the support of f. This function uses the + LSB of the next field of the nodes of f as visited flag. It also uses the + LSB of the next field of the variables as flag to remember whether a + certain index has already been seen. Finally, it uses the manager stack + to record all seen indices.] + + SideEffects [The stack pointer SP is modified by side-effect. The next + fields are changed and need to be reset.] + +******************************************************************************/ +static void +ddFindSupport( + DdManager *dd, + DdNode *f, + int *SP) +{ + int index; + DdNode *var; + + if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) { + return; + } + + index = f->index; + var = dd->vars[index]; + /* It is possible that var is embedded in f. That causes no problem, + ** though, because if we see it after encountering another node with + ** the same index, nothing is supposed to happen. + */ + if (!Cudd_IsComplement(var->next)) { + var->next = Cudd_Complement(var->next); + dd->stack[*SP] = (DdNode *)(ptrint) index; + (*SP)++; + } + ddFindSupport(dd, cuddT(f), SP); + ddFindSupport(dd, Cudd_Regular(cuddE(f)), SP); + /* Mark as visited. */ + f->next = Cudd_Complement(f->next); + +} /* end of ddFindSupport */ + + +/**Function******************************************************************** + + Synopsis [Clears visited flags for variables.] + + Description [Clears visited flags for variables.] + + SideEffects [None] + +******************************************************************************/ +static void +ddClearVars( + DdManager *dd, + int SP) +{ + int i; + + for (i = 0; i < SP; i++) { + int index = (int) (ptrint) dd->stack[i]; + DdNode *var = dd->vars[index]; + var->next = Cudd_Regular(var->next); + } + +} /* end of ddClearVars */ + + +/**Function******************************************************************** + + Synopsis [Compares indices for qsort.] + + Description [Compares indices for qsort. Subtracting these integers + cannot produce overflow, because they are non-negative.] + + SideEffects [None] + +******************************************************************************/ +static int +indexCompare( + const void *a, + const void *b) +{ + int ia = *((int *) a); + int ib = *((int *) b); + return(ia - ib); + +} /* end of indexCompare */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddWindow.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddWindow.c new file mode 100644 index 000000000..2f80beb16 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddWindow.c @@ -0,0 +1,1023 @@ +/**CFile*********************************************************************** + + FileName [cuddWindow.c] + + PackageName [cudd] + + Synopsis [Functions for variable reordering by window permutation.] + + Description [Internal procedures included in this module: +
                  +
                • cuddWindowReorder() +
                + Static procedures included in this module: +
                  +
                • ddWindow2() +
                • ddWindowConv2() +
                • ddPermuteWindow3() +
                • ddWindow3() +
                • ddWindowConv3() +
                • ddPermuteWindow4() +
                • ddWindow4() +
                • ddWindowConv4() +
                ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddWindow.c,v 1.15 2012/02/05 01:07:19 fabio Exp $"; +#endif + +#ifdef DD_STATS +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddWindow2 (DdManager *table, int low, int high); +static int ddWindowConv2 (DdManager *table, int low, int high); +static int ddPermuteWindow3 (DdManager *table, int x); +static int ddWindow3 (DdManager *table, int low, int high); +static int ddWindowConv3 (DdManager *table, int low, int high); +static int ddPermuteWindow4 (DdManager *table, int w); +static int ddWindow4 (DdManager *table, int low, int high); +static int ddWindowConv4 (DdManager *table, int low, int high); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Reorders by applying the method of the sliding window.] + + Description [Reorders by applying the method of the sliding window. + Tries all possible permutations to the variables in a window that + slides from low to high. The size of the window is determined by + submethod. Assumes that no dead nodes are present. Returns 1 in + case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddWindowReorder( + DdManager * table /* DD table */, + int low /* lowest index to reorder */, + int high /* highest index to reorder */, + Cudd_ReorderingType submethod /* window reordering option */) +{ + + int res; +#ifdef DD_DEBUG + int supposedOpt; +#endif + + switch (submethod) { + case CUDD_REORDER_WINDOW2: + res = ddWindow2(table,low,high); + break; + case CUDD_REORDER_WINDOW3: + res = ddWindow3(table,low,high); + break; + case CUDD_REORDER_WINDOW4: + res = ddWindow4(table,low,high); + break; + case CUDD_REORDER_WINDOW2_CONV: + res = ddWindowConv2(table,low,high); + break; + case CUDD_REORDER_WINDOW3_CONV: + res = ddWindowConv3(table,low,high); +#ifdef DD_DEBUG + supposedOpt = table->keys - table->isolated; + res = ddWindow3(table,low,high); + if (table->keys - table->isolated != (unsigned) supposedOpt) { + (void) fprintf(table->err, "Convergence failed! (%d != %d)\n", + table->keys - table->isolated, supposedOpt); + } +#endif + break; + case CUDD_REORDER_WINDOW4_CONV: + res = ddWindowConv4(table,low,high); +#ifdef DD_DEBUG + supposedOpt = table->keys - table->isolated; + res = ddWindow4(table,low,high); + if (table->keys - table->isolated != (unsigned) supposedOpt) { + (void) fprintf(table->err,"Convergence failed! (%d != %d)\n", + table->keys - table->isolated, supposedOpt); + } +#endif + break; + default: return(0); + } + + return(res); + +} /* end of cuddWindowReorder */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reorders by applying a sliding window of width 2.] + + Description [Reorders by applying a sliding window of width 2. + Tries both permutations of the variables in a window + that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindow2( + DdManager * table, + int low, + int high) +{ + + int x; + int res; + int size; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 1) return(0); + + res = table->keys - table->isolated; + for (x = low; x < high; x++) { + size = res; + res = cuddSwapInPlace(table,x,x+1); + if (res == 0) return(0); + if (res >= size) { /* no improvement: undo permutation */ + res = cuddSwapInPlace(table,x,x+1); + if (res == 0) return(0); + } +#ifdef DD_STATS + if (res < size) { + (void) fprintf(table->out,"-"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + return(1); + +} /* end of ddWindow2 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by repeatedly applying a sliding window of width 2.] + + Description [Reorders by repeatedly applying a sliding window of width + 2. Tries both permutations of the variables in a window + that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindowConv2( + DdManager * table, + int low, + int high) +{ + int x; + int res; + int nwin; + int newevent; + int *events; + int size; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 1) return(ddWindowConv2(table,low,high)); + + nwin = high-low; + events = ALLOC(int,nwin); + if (events == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (x=0; xkeys - table->isolated; + do { + newevent = 0; + for (x=0; x= size) { /* no improvement: undo permutation */ + res = cuddSwapInPlace(table,x+low,x+low+1); + if (res == 0) { + FREE(events); + return(0); + } + } + if (res < size) { + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + } + events[x] = 0; +#ifdef DD_STATS + if (res < size) { + (void) fprintf(table->out,"-"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } +#ifdef DD_STATS + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } +#endif + } while (newevent); + + FREE(events); + + return(1); + +} /* end of ddWindowConv3 */ + + +/**Function******************************************************************** + + Synopsis [Tries all the permutations of the three variables between + x and x+2 and retains the best.] + + Description [Tries all the permutations of the three variables between + x and x+2 and retains the best. Assumes that no dead nodes are + present. Returns the index of the best permutation (1-6) in case of + success; 0 otherwise.Assumes that no dead nodes are present. Returns + the index of the best permutation (1-6) in case of success; 0 + otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddPermuteWindow3( + DdManager * table, + int x) +{ + int y,z; + int size,sizeNew; + int best; + +#ifdef DD_DEBUG + assert(table->dead == 0); + assert(x+2 < table->size); +#endif + + size = table->keys - table->isolated; + y = x+1; z = y+1; + + /* The permutation pattern is: + ** (x,y)(y,z) + ** repeated three times to get all 3! = 6 permutations. + */ +#define ABC 1 + best = ABC; + +#define BAC 2 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = BAC; + size = sizeNew; + } +#define BCA 3 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = BCA; + size = sizeNew; + } +#define CBA 4 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = CBA; + size = sizeNew; + } +#define CAB 5 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = CAB; + size = sizeNew; + } +#define ACB 6 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = ACB; + size = sizeNew; + } + + /* Now take the shortest route to the best permuytation. + ** The initial permutation is ACB. + */ + switch(best) { + case BCA: if (!cuddSwapInPlace(table,y,z)) return(0); + case CBA: if (!cuddSwapInPlace(table,x,y)) return(0); + case ABC: if (!cuddSwapInPlace(table,y,z)) return(0); + case ACB: break; + case BAC: if (!cuddSwapInPlace(table,y,z)) return(0); + case CAB: if (!cuddSwapInPlace(table,x,y)) return(0); + break; + default: return(0); + } + +#ifdef DD_DEBUG + assert(table->keys - table->isolated == (unsigned) size); +#endif + + return(best); + +} /* end of ddPermuteWindow3 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by applying a sliding window of width 3.] + + Description [Reorders by applying a sliding window of width 3. + Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindow3( + DdManager * table, + int low, + int high) +{ + + int x; + int res; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 2) return(ddWindow2(table,low,high)); + + for (x = low; x+1 < high; x++) { + res = ddPermuteWindow3(table,x); + if (res == 0) return(0); +#ifdef DD_STATS + if (res == ABC) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); +#endif + } + + return(1); + +} /* end of ddWindow3 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by repeatedly applying a sliding window of width 3.] + + Description [Reorders by repeatedly applying a sliding window of width + 3. Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindowConv3( + DdManager * table, + int low, + int high) +{ + int x; + int res; + int nwin; + int newevent; + int *events; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 2) return(ddWindowConv2(table,low,high)); + + nwin = high-low-1; + events = ALLOC(int,nwin); + if (events == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (x=0; x 1) events[x-2] = 1; + newevent = 1; + break; + case BCA: + case CBA: + case CAB: + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + case ACB: + if (x < nwin-2) events[x+2] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + break; + default: + FREE(events); + return(0); + } + events[x] = 0; +#ifdef DD_STATS + if (res == ABC) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); +#endif + } + } +#ifdef DD_STATS + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } +#endif + } while (newevent); + + FREE(events); + + return(1); + +} /* end of ddWindowConv3 */ + + +/**Function******************************************************************** + + Synopsis [Tries all the permutations of the four variables between w + and w+3 and retains the best.] + + Description [Tries all the permutations of the four variables between + w and w+3 and retains the best. Assumes that no dead nodes are + present. Returns the index of the best permutation (1-24) in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddPermuteWindow4( + DdManager * table, + int w) +{ + int x,y,z; + int size,sizeNew; + int best; + +#ifdef DD_DEBUG + assert(table->dead == 0); + assert(w+3 < table->size); +#endif + + size = table->keys - table->isolated; + x = w+1; y = x+1; z = y+1; + + /* The permutation pattern is: + * (w,x)(y,z)(w,x)(x,y) + * (y,z)(w,x)(y,z)(x,y) + * repeated three times to get all 4! = 24 permutations. + * This gives a hamiltonian circuit of Cayley's graph. + * The codes to the permutation are assigned in topological order. + * The permutations at lower distance from the final permutation are + * assigned lower codes. This way we can choose, between + * permutations that give the same size, one that requires the minimum + * number of swaps from the final permutation of the hamiltonian circuit. + * There is an exception to this rule: ABCD is given Code 1, to + * avoid oscillation when convergence is sought. + */ +#define ABCD 1 + best = ABCD; + +#define BACD 7 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = BACD; + size = sizeNew; + } +#define BADC 13 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = BADC; + size = sizeNew; + } +#define ABDC 8 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && ABDC < best)) { + if (sizeNew == 0) return(0); + best = ABDC; + size = sizeNew; + } +#define ADBC 14 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = ADBC; + size = sizeNew; + } +#define ADCB 9 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && ADCB < best)) { + if (sizeNew == 0) return(0); + best = ADCB; + size = sizeNew; + } +#define DACB 15 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = DACB; + size = sizeNew; + } +#define DABC 20 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = DABC; + size = sizeNew; + } +#define DBAC 23 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = DBAC; + size = sizeNew; + } +#define BDAC 19 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && BDAC < best)) { + if (sizeNew == 0) return(0); + best = BDAC; + size = sizeNew; + } +#define BDCA 21 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && BDCA < best)) { + if (sizeNew == 0) return(0); + best = BDCA; + size = sizeNew; + } +#define DBCA 24 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = DBCA; + size = sizeNew; + } +#define DCBA 22 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size || (sizeNew == size && DCBA < best)) { + if (sizeNew == 0) return(0); + best = DCBA; + size = sizeNew; + } +#define DCAB 18 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && DCAB < best)) { + if (sizeNew == 0) return(0); + best = DCAB; + size = sizeNew; + } +#define CDAB 12 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && CDAB < best)) { + if (sizeNew == 0) return(0); + best = CDAB; + size = sizeNew; + } +#define CDBA 17 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && CDBA < best)) { + if (sizeNew == 0) return(0); + best = CDBA; + size = sizeNew; + } +#define CBDA 11 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size || (sizeNew == size && CBDA < best)) { + if (sizeNew == 0) return(0); + best = CBDA; + size = sizeNew; + } +#define BCDA 16 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && BCDA < best)) { + if (sizeNew == 0) return(0); + best = BCDA; + size = sizeNew; + } +#define BCAD 10 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && BCAD < best)) { + if (sizeNew == 0) return(0); + best = BCAD; + size = sizeNew; + } +#define CBAD 5 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && CBAD < best)) { + if (sizeNew == 0) return(0); + best = CBAD; + size = sizeNew; + } +#define CABD 3 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size || (sizeNew == size && CABD < best)) { + if (sizeNew == 0) return(0); + best = CABD; + size = sizeNew; + } +#define CADB 6 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && CADB < best)) { + if (sizeNew == 0) return(0); + best = CADB; + size = sizeNew; + } +#define ACDB 4 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && ACDB < best)) { + if (sizeNew == 0) return(0); + best = ACDB; + size = sizeNew; + } +#define ACBD 2 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && ACBD < best)) { + if (sizeNew == 0) return(0); + best = ACBD; + size = sizeNew; + } + + /* Now take the shortest route to the best permutation. + ** The initial permutation is ACBD. + */ + switch(best) { + case DBCA: if (!cuddSwapInPlace(table,y,z)) return(0); + case BDCA: if (!cuddSwapInPlace(table,x,y)) return(0); + case CDBA: if (!cuddSwapInPlace(table,w,x)) return(0); + case ADBC: if (!cuddSwapInPlace(table,y,z)) return(0); + case ABDC: if (!cuddSwapInPlace(table,x,y)) return(0); + case ACDB: if (!cuddSwapInPlace(table,y,z)) return(0); + case ACBD: break; + case DCBA: if (!cuddSwapInPlace(table,y,z)) return(0); + case BCDA: if (!cuddSwapInPlace(table,x,y)) return(0); + case CBDA: if (!cuddSwapInPlace(table,w,x)) return(0); + if (!cuddSwapInPlace(table,x,y)) return(0); + if (!cuddSwapInPlace(table,y,z)) return(0); + break; + case DBAC: if (!cuddSwapInPlace(table,x,y)) return(0); + case DCAB: if (!cuddSwapInPlace(table,w,x)) return(0); + case DACB: if (!cuddSwapInPlace(table,y,z)) return(0); + case BACD: if (!cuddSwapInPlace(table,x,y)) return(0); + case CABD: if (!cuddSwapInPlace(table,w,x)) return(0); + break; + case DABC: if (!cuddSwapInPlace(table,y,z)) return(0); + case BADC: if (!cuddSwapInPlace(table,x,y)) return(0); + case CADB: if (!cuddSwapInPlace(table,w,x)) return(0); + if (!cuddSwapInPlace(table,y,z)) return(0); + break; + case BDAC: if (!cuddSwapInPlace(table,x,y)) return(0); + case CDAB: if (!cuddSwapInPlace(table,w,x)) return(0); + case ADCB: if (!cuddSwapInPlace(table,y,z)) return(0); + case ABCD: if (!cuddSwapInPlace(table,x,y)) return(0); + break; + case BCAD: if (!cuddSwapInPlace(table,x,y)) return(0); + case CBAD: if (!cuddSwapInPlace(table,w,x)) return(0); + if (!cuddSwapInPlace(table,x,y)) return(0); + break; + default: return(0); + } + +#ifdef DD_DEBUG + assert(table->keys - table->isolated == (unsigned) size); +#endif + + return(best); + +} /* end of ddPermuteWindow4 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by applying a sliding window of width 4.] + + Description [Reorders by applying a sliding window of width 4. + Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindow4( + DdManager * table, + int low, + int high) +{ + + int w; + int res; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 3) return(ddWindow3(table,low,high)); + + for (w = low; w+2 < high; w++) { + res = ddPermuteWindow4(table,w); + if (res == 0) return(0); +#ifdef DD_STATS + if (res == ABCD) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); +#endif + } + + return(1); + +} /* end of ddWindow4 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by repeatedly applying a sliding window of width 4.] + + Description [Reorders by repeatedly applying a sliding window of width + 4. Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindowConv4( + DdManager * table, + int low, + int high) +{ + int x; + int res; + int nwin; + int newevent; + int *events; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 3) return(ddWindowConv3(table,low,high)); + + nwin = high-low-2; + events = ALLOC(int,nwin); + if (events == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (x=0; x 2) events[x-3] = 1; + newevent = 1; + break; + case BADC: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case ABDC: + if (x < nwin-3) events[x+3] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + break; + case ADBC: + case ADCB: + case ACDB: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-2) events[x+2] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + case DACB: + case DABC: + case DBAC: + case BDAC: + case BDCA: + case DBCA: + case DCBA: + case DCAB: + case CDAB: + case CDBA: + case CBDA: + case BCDA: + case CADB: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case BCAD: + case CBAD: + case CABD: + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 1) events[x-2] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case ACBD: + if (x < nwin-2) events[x+2] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + default: + FREE(events); + return(0); + } + events[x] = 0; +#ifdef DD_STATS + if (res == ABCD) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); +#endif + } + } +#ifdef DD_STATS + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } +#endif + } while (newevent); + + FREE(events); + + return(1); + +} /* end of ddWindowConv4 */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddCount.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddCount.c new file mode 100644 index 000000000..b65d1022f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddCount.c @@ -0,0 +1,357 @@ +/**CFile*********************************************************************** + + FileName [cuddZddCount.c] + + PackageName [cudd] + + Synopsis [Procedures to count the number of minterms of a ZDD.] + + Description [External procedures included in this module: +
                  +
                • Cudd_zddCount(); +
                • Cudd_zddCountDouble(); +
                + Internal procedures included in this module: +
                  +
                + Static procedures included in this module: +
                  +
                • cuddZddCountStep(); +
                • cuddZddCountDoubleStep(); +
                • st_zdd_count_dbl_free() +
                • st_zdd_countfree() +
                + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.15 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddZddCountStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty); +static double cuddZddCountDoubleStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty); +static enum st_retval st_zdd_countfree (char *key, char *value, char *arg); +static enum st_retval st_zdd_count_dbl_free (char *key, char *value, char *arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms in a ZDD.] + + Description [Returns an integer representing the number of minterms + in a ZDD.] + + SideEffects [None] + + SeeAlso [Cudd_zddCountDouble] + +******************************************************************************/ +int +Cudd_zddCount( + DdManager * zdd, + DdNode * P) +{ + st_table *table; + int res; + DdNode *base, *empty; + + base = DD_ONE(zdd); + empty = DD_ZERO(zdd); + table = st_init_table(st_ptrcmp, st_ptrhash); + if (table == NULL) return(CUDD_OUT_OF_MEM); + res = cuddZddCountStep(P, table, base, empty); + if (res == CUDD_OUT_OF_MEM) { + zdd->errorCode = CUDD_MEMORY_OUT; + } + st_foreach(table, st_zdd_countfree, NIL(char)); + st_free_table(table); + + return(res); + +} /* end of Cudd_zddCount */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a ZDD.] + + Description [Counts the number of minterms of a ZDD. The result is + returned as a double. If the procedure runs out of memory, it + returns (double) CUDD_OUT_OF_MEM. This procedure is used in + Cudd_zddCountMinterm.] + + SideEffects [None] + + SeeAlso [Cudd_zddCountMinterm Cudd_zddCount] + +******************************************************************************/ +double +Cudd_zddCountDouble( + DdManager * zdd, + DdNode * P) +{ + st_table *table; + double res; + DdNode *base, *empty; + + base = DD_ONE(zdd); + empty = DD_ZERO(zdd); + table = st_init_table(st_ptrcmp, st_ptrhash); + if (table == NULL) return((double)CUDD_OUT_OF_MEM); + res = cuddZddCountDoubleStep(P, table, base, empty); + if (res == (double)CUDD_OUT_OF_MEM) { + zdd->errorCode = CUDD_MEMORY_OUT; + } + st_foreach(table, st_zdd_count_dbl_free, NIL(char)); + st_free_table(table); + + return(res); + +} /* end of Cudd_zddCountDouble */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddCount.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddCountStep( + DdNode * P, + st_table * table, + DdNode * base, + DdNode * empty) +{ + int res; + int *dummy; + + if (P == empty) + return(0); + if (P == base) + return(1); + + /* Check cache. */ + if (st_lookup(table, P, &dummy)) { + res = *dummy; + return(res); + } + + res = cuddZddCountStep(cuddE(P), table, base, empty) + + cuddZddCountStep(cuddT(P), table, base, empty); + + dummy = ALLOC(int, 1); + if (dummy == NULL) { + return(CUDD_OUT_OF_MEM); + } + *dummy = res; + if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) { + FREE(dummy); + return(CUDD_OUT_OF_MEM); + } + + return(res); + +} /* end of cuddZddCountStep */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddCountDouble.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double +cuddZddCountDoubleStep( + DdNode * P, + st_table * table, + DdNode * base, + DdNode * empty) +{ + double res; + double *dummy; + + if (P == empty) + return((double)0.0); + if (P == base) + return((double)1.0); + + /* Check cache */ + if (st_lookup(table, P, &dummy)) { + res = *dummy; + return(res); + } + + res = cuddZddCountDoubleStep(cuddE(P), table, base, empty) + + cuddZddCountDoubleStep(cuddT(P), table, base, empty); + + dummy = ALLOC(double, 1); + if (dummy == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + *dummy = res; + if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) { + FREE(dummy); + return((double)CUDD_OUT_OF_MEM); + } + + return(res); + +} /* end of cuddZddCountDoubleStep */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory associated with the computed table of + Cudd_zddCount.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static enum st_retval +st_zdd_countfree( + char * key, + char * value, + char * arg) +{ + int *d; + + d = (int *)value; + FREE(d); + return(ST_CONTINUE); + +} /* end of st_zdd_countfree */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory associated with the computed table of + Cudd_zddCountDouble.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static enum st_retval +st_zdd_count_dbl_free( + char * key, + char * value, + char * arg) +{ + double *d; + + d = (double *)value; + FREE(d); + return(ST_CONTINUE); + +} /* end of st_zdd_count_dbl_free */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddFuncs.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddFuncs.c new file mode 100644 index 000000000..9d818212b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddFuncs.c @@ -0,0 +1,1630 @@ +/**CFile*********************************************************************** + + FileName [cuddZddFuncs.c] + + PackageName [cudd] + + Synopsis [Functions to manipulate covers represented as ZDDs.] + + Description [External procedures included in this module: +
                  +
                • Cudd_zddProduct(); +
                • Cudd_zddUnateProduct(); +
                • Cudd_zddWeakDiv(); +
                • Cudd_zddWeakDivF(); +
                • Cudd_zddDivide(); +
                • Cudd_zddDivideF(); +
                • Cudd_zddComplement(); +
                + Internal procedures included in this module: +
                  +
                • cuddZddProduct(); +
                • cuddZddUnateProduct(); +
                • cuddZddWeakDiv(); +
                • cuddZddWeakDivF(); +
                • cuddZddDivide(); +
                • cuddZddDivideF(); +
                • cuddZddGetCofactors3() +
                • cuddZddGetCofactors2() +
                • cuddZddComplement(); +
                • cuddZddGetPosVarIndex(); +
                • cuddZddGetNegVarIndex(); +
                • cuddZddGetPosVarLevel(); +
                • cuddZddGetNegVarLevel(); +
                + Static procedures included in this module: +
                  +
                + ] + + SeeAlso [] + + Author [In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddFuncs.c,v 1.17 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the product of two covers represented by ZDDs.] + + Description [Computes the product of two covers represented by + ZDDs. The result is also a ZDD. Returns a pointer to the result if + successful; NULL otherwise. The covers on which Cudd_zddProduct + operates use two ZDD variables for each function variable (one ZDD + variable for each literal of the variable). Those two ZDD variables + should be adjacent in the order.] + + SideEffects [None] + + SeeAlso [Cudd_zddUnateProduct] + +******************************************************************************/ +DdNode * +Cudd_zddProduct( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddProduct(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddProduct */ + + +/**Function******************************************************************** + + Synopsis [Computes the product of two unate covers.] + + Description [Computes the product of two unate covers represented as + ZDDs. Unate covers use one ZDD variable for each BDD + variable. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddProduct] + +******************************************************************************/ +DdNode * +Cudd_zddUnateProduct( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddUnateProduct(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddUnateProduct */ + + +/**Function******************************************************************** + + Synopsis [Applies weak division to two covers.] + + Description [Applies weak division to two ZDDs representing two + covers. Returns a pointer to the ZDD representing the result if + successful; NULL otherwise. The result of weak division depends on + the variable order. The covers on which Cudd_zddWeakDiv operates use + two ZDD variables for each function variable (one ZDD variable for + each literal of the variable). Those two ZDD variables should be + adjacent in the order.] + + SideEffects [None] + + SeeAlso [Cudd_zddDivide] + +******************************************************************************/ +DdNode * +Cudd_zddWeakDiv( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddWeakDiv(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddWeakDiv */ + + +/**Function******************************************************************** + + Synopsis [Computes the quotient of two unate covers.] + + Description [Computes the quotient of two unate covers represented + by ZDDs. Unate covers use one ZDD variable for each BDD + variable. Returns a pointer to the resulting ZDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddWeakDiv] + +******************************************************************************/ +DdNode * +Cudd_zddDivide( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddDivide(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddDivide */ + + +/**Function******************************************************************** + + Synopsis [Modified version of Cudd_zddWeakDiv.] + + Description [Modified version of Cudd_zddWeakDiv. This function may + disappear in future releases.] + + SideEffects [None] + + SeeAlso [Cudd_zddWeakDiv] + +******************************************************************************/ +DdNode * +Cudd_zddWeakDivF( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddWeakDivF(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddWeakDivF */ + + +/**Function******************************************************************** + + Synopsis [Modified version of Cudd_zddDivide.] + + Description [Modified version of Cudd_zddDivide. This function may + disappear in future releases.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddDivideF( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddDivideF(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddDivideF */ + + +/**Function******************************************************************** + + Synopsis [Computes a complement cover for a ZDD node.] + + Description [Computes a complement cover for a ZDD node. For lack of a + better method, we first extract the function BDD from the ZDD cover, + then make the complement of the ZDD cover from the complement of the + BDD node by using ISOP. Returns a pointer to the resulting cover if + successful; NULL otherwise. The result depends on current variable + order.] + + SideEffects [The result depends on current variable order.] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddComplement( + DdManager *dd, + DdNode *node) +{ + DdNode *b, *isop, *zdd_I; + + /* Check cache */ + zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node); + if (zdd_I) + return(zdd_I); + + b = Cudd_MakeBddFromZddCover(dd, node); + if (!b) + return(NULL); + Cudd_Ref(b); + isop = Cudd_zddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I); + if (!isop) { + Cudd_RecursiveDeref(dd, b); + return(NULL); + } + Cudd_Ref(isop); + Cudd_Ref(zdd_I); + Cudd_RecursiveDeref(dd, b); + Cudd_RecursiveDeref(dd, isop); + + cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I); + Cudd_Deref(zdd_I); + return(zdd_I); +} /* end of Cudd_zddComplement */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddProduct.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddProduct] + +******************************************************************************/ +DdNode * +cuddZddProduct( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v, top_f, top_g; + DdNode *tmp, *term1, *term2, *term3; + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *R0, *R1, *Rd, *N0, *N1; + DdNode *r; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + int flag; + int pv, nv; + + statLine(dd); + if (f == zero || g == zero) + return(zero); + if (f == one) + return(g); + if (g == one) + return(f); + + top_f = dd->permZ[f->index]; + top_g = dd->permZ[g->index]; + + if (top_f > top_g) + return(cuddZddProduct(dd, g, f)); + + /* Check cache */ + r = cuddCacheLookup2Zdd(dd, cuddZddProduct, f, g); + if (r) + return(r); + + v = f->index; /* either yi or zi */ + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + Cudd_Ref(gd); + pv = cuddZddGetPosVarIndex(dd, v); + nv = cuddZddGetNegVarIndex(dd, v); + + Rd = cuddZddProduct(dd, fd, gd); + if (Rd == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(Rd); + + term1 = cuddZddProduct(dd, f0, g0); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + return(NULL); + } + Cudd_Ref(term1); + term2 = cuddZddProduct(dd, f0, gd); + if (term2 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term2); + term3 = cuddZddProduct(dd, fd, g0); + if (term3 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); + } + Cudd_Ref(term3); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g0); + tmp = cuddZddUnion(dd, term1, term2); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + R0 = cuddZddUnion(dd, tmp, term3); + if (R0 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(R0); + Cudd_RecursiveDerefZdd(dd, tmp); + Cudd_RecursiveDerefZdd(dd, term3); + N0 = cuddZddGetNode(dd, nv, R0, Rd); /* nv = zi */ + if (N0 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, R0); + return(NULL); + } + Cudd_Ref(N0); + Cudd_RecursiveDerefZdd(dd, R0); + Cudd_RecursiveDerefZdd(dd, Rd); + + term1 = cuddZddProduct(dd, f1, g1); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + return(NULL); + } + Cudd_Ref(term1); + term2 = cuddZddProduct(dd, f1, gd); + if (term2 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term2); + term3 = cuddZddProduct(dd, fd, g1); + if (term3 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); + } + Cudd_Ref(term3); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + tmp = cuddZddUnion(dd, term1, term2); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + R1 = cuddZddUnion(dd, tmp, term3); + if (R1 == NULL) { + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(R1); + Cudd_RecursiveDerefZdd(dd, tmp); + Cudd_RecursiveDerefZdd(dd, term3); + N1 = cuddZddGetNode(dd, pv, R1, N0); /* pv = yi */ + if (N1 == NULL) { + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, R1); + return(NULL); + } + Cudd_Ref(N1); + Cudd_RecursiveDerefZdd(dd, R1); + Cudd_RecursiveDerefZdd(dd, N0); + + cuddCacheInsert2(dd, cuddZddProduct, f, g, N1); + Cudd_Deref(N1); + return(N1); + +} /* end of cuddZddProduct */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddUnateProduct.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddUnateProduct] + +******************************************************************************/ +DdNode * +cuddZddUnateProduct( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v, top_f, top_g; + DdNode *term1, *term2, *term3, *term4; + DdNode *sum1, *sum2; + DdNode *f0, *f1, *g0, *g1; + DdNode *r; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + int flag; + + statLine(dd); + if (f == zero || g == zero) + return(zero); + if (f == one) + return(g); + if (g == one) + return(f); + + top_f = dd->permZ[f->index]; + top_g = dd->permZ[g->index]; + + if (top_f > top_g) + return(cuddZddUnateProduct(dd, g, f)); + + /* Check cache */ + r = cuddCacheLookup2Zdd(dd, cuddZddUnateProduct, f, g); + if (r) + return(r); + + v = f->index; /* either yi or zi */ + flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + + term1 = cuddZddUnateProduct(dd, f1, g1); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(term1); + term2 = cuddZddUnateProduct(dd, f1, g0); + if (term2 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term2); + term3 = cuddZddUnateProduct(dd, f0, g1); + if (term3 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); + } + Cudd_Ref(term3); + term4 = cuddZddUnateProduct(dd, f0, g0); + if (term4 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); + } + Cudd_Ref(term4); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + sum1 = cuddZddUnion(dd, term1, term2); + if (sum1 == NULL) { + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, term4); + return(NULL); + } + Cudd_Ref(sum1); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + sum2 = cuddZddUnion(dd, sum1, term3); + if (sum2 == NULL) { + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, term4); + Cudd_RecursiveDerefZdd(dd, sum1); + return(NULL); + } + Cudd_Ref(sum2); + Cudd_RecursiveDerefZdd(dd, sum1); + Cudd_RecursiveDerefZdd(dd, term3); + r = cuddZddGetNode(dd, v, sum2, term4); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, term4); + Cudd_RecursiveDerefZdd(dd, sum2); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDerefZdd(dd, sum2); + Cudd_RecursiveDerefZdd(dd, term4); + + cuddCacheInsert2(dd, cuddZddUnateProduct, f, g, r); + Cudd_Deref(r); + return(r); + +} /* end of cuddZddUnateProduct */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddWeakDiv.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddWeakDiv] + +******************************************************************************/ +DdNode * +cuddZddWeakDiv( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *q, *tmp; + DdNode *r; + int flag; + + statLine(dd); + if (g == one) + return(f); + if (f == zero || f == one) + return(zero); + if (f == g) + return(one); + + /* Check cache. */ + r = cuddCacheLookup2Zdd(dd, cuddZddWeakDiv, f, g); + if (r) + return(r); + + v = g->index; + + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + Cudd_Ref(gd); + + q = g; + + if (g0 != zero) { + q = cuddZddWeakDiv(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + } + else + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g0); + + if (q == zero) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); + Cudd_Deref(q); + return(zero); + } + + if (g1 != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDiv(dd, f1, g1); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + } + else { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + } + + if (q == zero) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); + Cudd_Deref(q); + return(zero); + } + + if (gd != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDiv(dd, fd, gd); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + } + else { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + } + + cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, q); + Cudd_Deref(q); + return(q); + +} /* end of cuddZddWeakDiv */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddWeakDivF.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddWeakDivF] + +******************************************************************************/ +DdNode * +cuddZddWeakDivF( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v, top_f, top_g, vf, vg; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *q, *tmp; + DdNode *r; + DdNode *term1, *term0, *termd; + int flag; + int pv, nv; + + statLine(dd); + if (g == one) + return(f); + if (f == zero || f == one) + return(zero); + if (f == g) + return(one); + + /* Check cache. */ + r = cuddCacheLookup2Zdd(dd, cuddZddWeakDivF, f, g); + if (r) + return(r); + + top_f = dd->permZ[f->index]; + top_g = dd->permZ[g->index]; + vf = top_f >> 1; + vg = top_g >> 1; + v = ddMin(top_f, top_g); + + if (v == top_f && vf < vg) { + v = f->index; + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + + pv = cuddZddGetPosVarIndex(dd, v); + nv = cuddZddGetNegVarIndex(dd, v); + + term1 = cuddZddWeakDivF(dd, f1, g); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(term1); + Cudd_RecursiveDerefZdd(dd, f1); + term0 = cuddZddWeakDivF(dd, f0, g); + if (term0 == NULL) { + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term0); + Cudd_RecursiveDerefZdd(dd, f0); + termd = cuddZddWeakDivF(dd, fd, g); + if (termd == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term0); + return(NULL); + } + Cudd_Ref(termd); + Cudd_RecursiveDerefZdd(dd, fd); + + tmp = cuddZddGetNode(dd, nv, term0, termd); /* nv = zi */ + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term0); + Cudd_RecursiveDerefZdd(dd, termd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, term0); + Cudd_RecursiveDerefZdd(dd, termd); + q = cuddZddGetNode(dd, pv, term1, tmp); /* pv = yi */ + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, tmp); + + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q); + Cudd_Deref(q); + return(q); + } + + if (v == top_f) + v = f->index; + else + v = g->index; + + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + Cudd_Ref(gd); + + q = g; + + if (g0 != zero) { + q = cuddZddWeakDivF(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + } + else + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g0); + + if (q == zero) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); + Cudd_Deref(q); + return(zero); + } + + if (g1 != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDivF(dd, f1, g1); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + } + else { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + } + + if (q == zero) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); + Cudd_Deref(q); + return(zero); + } + + if (gd != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDivF(dd, fd, gd); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + } + else { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + } + + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q); + Cudd_Deref(q); + return(q); + +} /* end of cuddZddWeakDivF */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddDivide.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddDivide] + +******************************************************************************/ +DdNode * +cuddZddDivide( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *g0, *g1; + DdNode *q, *r, *tmp; + int flag; + + statLine(dd); + if (g == one) + return(f); + if (f == zero || f == one) + return(zero); + if (f == g) + return(one); + + /* Check cache. */ + r = cuddCacheLookup2Zdd(dd, cuddZddDivide, f, g); + if (r) + return(r); + + v = g->index; + + flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */ + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + + r = cuddZddDivide(dd, f1, g1); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(r); + + if (r != zero && g0 != zero) { + tmp = r; + q = cuddZddDivide(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(q); + r = cuddZddIntersect(dd, r, q); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, q); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDerefZdd(dd, q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + + cuddCacheInsert2(dd, cuddZddDivide, f, g, r); + Cudd_Deref(r); + return(r); + +} /* end of cuddZddDivide */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddDivideF.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddDivideF] + +******************************************************************************/ +DdNode * +cuddZddDivideF( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *g0, *g1; + DdNode *q, *r, *tmp; + int flag; + + statLine(dd); + if (g == one) + return(f); + if (f == zero || f == one) + return(zero); + if (f == g) + return(one); + + /* Check cache. */ + r = cuddCacheLookup2Zdd(dd, cuddZddDivideF, f, g); + if (r) + return(r); + + v = g->index; + + flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */ + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + + r = cuddZddDivideF(dd, f1, g1); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(r); + + if (r != zero && g0 != zero) { + tmp = r; + q = cuddZddDivideF(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(q); + r = cuddZddIntersect(dd, r, q); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, q); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDerefZdd(dd, q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + + cuddCacheInsert2(dd, cuddZddDivideF, f, g, r); + Cudd_Deref(r); + return(r); + +} /* end of cuddZddDivideF */ + + +/**Function******************************************************************** + + Synopsis [Computes the three-way decomposition of f w.r.t. v.] + + Description [Computes the three-way decomposition of function f (represented + by a ZDD) wit respect to variable v. Returns 0 if successful; 1 otherwise.] + + SideEffects [The results are returned in f1, f0, and fd.] + + SeeAlso [cuddZddGetCofactors2] + +******************************************************************************/ +int +cuddZddGetCofactors3( + DdManager * dd, + DdNode * f, + int v, + DdNode ** f1, + DdNode ** f0, + DdNode ** fd) +{ + DdNode *pc, *nc; + DdNode *zero = DD_ZERO(dd); + int top, hv, ht, pv, nv; + int level; + + top = dd->permZ[f->index]; + level = dd->permZ[v]; + hv = level >> 1; + ht = top >> 1; + + if (hv < ht) { + *f1 = zero; + *f0 = zero; + *fd = f; + } + else { + pv = cuddZddGetPosVarIndex(dd, v); + nv = cuddZddGetNegVarIndex(dd, v); + + /* not to create intermediate ZDD node */ + if (cuddZddGetPosVarLevel(dd, v) < cuddZddGetNegVarLevel(dd, v)) { + pc = cuddZddSubset1(dd, f, pv); + if (pc == NULL) + return(1); + Cudd_Ref(pc); + nc = cuddZddSubset0(dd, f, pv); + if (nc == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + return(1); + } + Cudd_Ref(nc); + + *f1 = cuddZddSubset0(dd, pc, nv); + if (*f1 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + return(1); + } + Cudd_Ref(*f1); + *f0 = cuddZddSubset1(dd, nc, nv); + if (*f0 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + return(1); + } + Cudd_Ref(*f0); + + *fd = cuddZddSubset0(dd, nc, nv); + if (*fd == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*fd); + } else { + pc = cuddZddSubset1(dd, f, nv); + if (pc == NULL) + return(1); + Cudd_Ref(pc); + nc = cuddZddSubset0(dd, f, nv); + if (nc == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + return(1); + } + Cudd_Ref(nc); + + *f0 = cuddZddSubset0(dd, pc, pv); + if (*f0 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + return(1); + } + Cudd_Ref(*f0); + *f1 = cuddZddSubset1(dd, nc, pv); + if (*f1 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*f1); + + *fd = cuddZddSubset0(dd, nc, pv); + if (*fd == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*fd); + } + + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_Deref(*f1); + Cudd_Deref(*f0); + Cudd_Deref(*fd); + } + return(0); + +} /* end of cuddZddGetCofactors3 */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-way decomposition of f w.r.t. v.] + + Description [] + + SideEffects [The results are returned in f1 and f0.] + + SeeAlso [cuddZddGetCofactors3] + +******************************************************************************/ +int +cuddZddGetCofactors2( + DdManager * dd, + DdNode * f, + int v, + DdNode ** f1, + DdNode ** f0) +{ + *f1 = cuddZddSubset1(dd, f, v); + if (*f1 == NULL) + return(1); + *f0 = cuddZddSubset0(dd, f, v); + if (*f0 == NULL) { + Cudd_RecursiveDerefZdd(dd, *f1); + return(1); + } + return(0); + +} /* end of cuddZddGetCofactors2 */ + + +/**Function******************************************************************** + + Synopsis [Computes a complement of a ZDD node.] + + Description [Computes the complement of a ZDD node. So far, since we + couldn't find a direct way to get the complement of a ZDD cover, we first + convert a ZDD cover to a BDD, then make the complement of the ZDD cover + from the complement of the BDD node by using ISOP.] + + SideEffects [The result depends on current variable order.] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddComplement( + DdManager * dd, + DdNode *node) +{ + DdNode *b, *isop, *zdd_I; + + /* Check cache */ + zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node); + if (zdd_I) + return(zdd_I); + + b = cuddMakeBddFromZddCover(dd, node); + if (!b) + return(NULL); + cuddRef(b); + isop = cuddZddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I); + if (!isop) { + Cudd_RecursiveDeref(dd, b); + return(NULL); + } + cuddRef(isop); + cuddRef(zdd_I); + Cudd_RecursiveDeref(dd, b); + Cudd_RecursiveDeref(dd, isop); + + cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I); + cuddDeref(zdd_I); + return(zdd_I); +} /* end of cuddZddComplement */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of positive ZDD variable.] + + Description [Returns the index of positive ZDD variable.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddGetPosVarIndex( + DdManager * dd, + int index) +{ + int pv = (index >> 1) << 1; + return(pv); +} /* end of cuddZddGetPosVarIndex */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of negative ZDD variable.] + + Description [Returns the index of negative ZDD variable.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddGetNegVarIndex( + DdManager * dd, + int index) +{ + int nv = index | 0x1; + return(nv); +} /* end of cuddZddGetPosVarIndex */ + + +/**Function******************************************************************** + + Synopsis [Returns the level of positive ZDD variable.] + + Description [Returns the level of positive ZDD variable.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddGetPosVarLevel( + DdManager * dd, + int index) +{ + int pv = cuddZddGetPosVarIndex(dd, index); + return(dd->permZ[pv]); +} /* end of cuddZddGetPosVarLevel */ + + +/**Function******************************************************************** + + Synopsis [Returns the level of negative ZDD variable.] + + Description [Returns the level of negative ZDD variable.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddGetNegVarLevel( + DdManager * dd, + int index) +{ + int nv = cuddZddGetNegVarIndex(dd, index); + return(dd->permZ[nv]); +} /* end of cuddZddGetNegVarLevel */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddGroup.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddGroup.c new file mode 100644 index 000000000..11b31734d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddGroup.c @@ -0,0 +1,1340 @@ +/**CFile*********************************************************************** + + FileName [cuddZddGroup.c] + + PackageName [cudd] + + Synopsis [Functions for ZDD group sifting.] + + Description [External procedures included in this file: +
                  +
                • Cudd_MakeZddTreeNode() +
                + Internal procedures included in this file: +
                  +
                • cuddZddTreeSifting() +
                + Static procedures included in this module: +
                  +
                • zddTreeSiftingAux() +
                • zddCountInternalMtrNodes() +
                • zddReorderChildren() +
                • zddFindNodeHiLo() +
                • zddUniqueCompareGroup() +
                • zddGroupSifting() +
                • zddGroupSiftingAux() +
                • zddGroupSiftingUp() +
                • zddGroupSiftingDown() +
                • zddGroupMove() +
                • zddGroupMoveBackward() +
                • zddGroupSiftingBackward() +
                • zddMergeGroups() +
                ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddGroup.c,v 1.22 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int *entry; +extern int zddTotalNumberSwapping; +#ifdef DD_STATS +static int extsymmcalls; +static int extsymm; +static int secdiffcalls; +static int secdiff; +static int secdiffmisfire; +#endif +#ifdef DD_DEBUG +static int pr = 0; /* flag to enable printing while debugging */ + /* by depositing a 1 into it */ +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int zddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +#ifdef DD_STATS +static int zddCountInternalMtrNodes (DdManager *table, MtrNode *treenode); +#endif +static int zddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +static void zddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper); +static int zddUniqueCompareGroup (int *ptrX, int *ptrY); +static int zddGroupSifting (DdManager *table, int lower, int upper); +static int zddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static int zddGroupSiftingUp (DdManager *table, int y, int xLow, Move **moves); +static int zddGroupSiftingDown (DdManager *table, int x, int xHigh, Move **moves); +static int zddGroupMove (DdManager *table, int x, int y, Move **moves); +static int zddGroupMoveBackward (DdManager *table, int x, int y); +static int zddGroupSiftingBackward (DdManager *table, Move *moves, int size); +static void zddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Creates a new ZDD variable group.] + + Description [Creates a new ZDD variable group. The group starts at + variable and contains size variables. The parameter low is the index + of the first variable. If the variable already exists, its current + position in the order is known to the manager. If the variable does + not exist yet, the position is assumed to be the same as the index. + The group tree is created if it does not exist yet. + Returns a pointer to the group if successful; NULL otherwise.] + + SideEffects [The ZDD variable tree is changed.] + + SeeAlso [Cudd_MakeTreeNode] + +******************************************************************************/ +MtrNode * +Cudd_MakeZddTreeNode( + DdManager * dd /* manager */, + unsigned int low /* index of the first group variable */, + unsigned int size /* number of variables in the group */, + unsigned int type /* MTR_DEFAULT or MTR_FIXED */) +{ + MtrNode *group; + MtrNode *tree; + unsigned int level; + + /* If the variable does not exist yet, the position is assumed to be + ** the same as the index. Therefore, applications that rely on + ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new + ** variables have to create the variables before they group them. + */ + level = (low < (unsigned int) dd->sizeZ) ? dd->permZ[low] : low; + + if (level + size - 1> (int) MTR_MAXHIGH) + return(NULL); + + /* If the tree does not exist yet, create it. */ + tree = dd->treeZ; + if (tree == NULL) { + dd->treeZ = tree = Mtr_InitGroupTree(0, dd->sizeZ); + if (tree == NULL) + return(NULL); + tree->index = dd->invpermZ[0]; + } + + /* Extend the upper bound of the tree if necessary. This allows the + ** application to create groups even before the variables are created. + */ + tree->size = ddMax(tree->size, level + size); + + /* Create the group. */ + group = Mtr_MakeGroup(tree, level, size, type); + if (group == NULL) + return(NULL); + + /* Initialize the index field to the index of the variable currently + ** in position low. This field will be updated by the reordering + ** procedure to provide a handle to the group once it has been moved. + */ + group->index = (MtrHalfWord) low; + + return(group); + +} /* end of Cudd_MakeZddTreeNode */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Tree sifting algorithm for ZDDs.] + + Description [Tree sifting algorithm for ZDDs. Assumes that a tree + representing a group hierarchy is passed as a parameter. It then + reorders each group in postorder fashion by calling + zddTreeSiftingAux. Assumes that no dead nodes are present. Returns + 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddZddTreeSifting( + DdManager * table /* DD table */, + Cudd_ReorderingType method /* reordering method for the groups of leaves */) +{ + int i; + int nvars; + int result; + int tempTree; + + /* If no tree is provided we create a temporary one in which all + ** variables are in a single group. After reordering this tree is + ** destroyed. + */ + tempTree = table->treeZ == NULL; + if (tempTree) { + table->treeZ = Mtr_InitGroupTree(0,table->sizeZ); + table->treeZ->index = table->invpermZ[0]; + } + nvars = table->sizeZ; + +#ifdef DD_DEBUG + if (pr > 0 && !tempTree) + (void) fprintf(table->out,"cuddZddTreeSifting:"); + Mtr_PrintGroups(table->treeZ,pr <= 0); +#endif +#if 0 + /* Debugging code. */ + if (table->tree && table->treeZ) { + (void) fprintf(table->out,"\n"); + Mtr_PrintGroups(table->tree, 0); + cuddPrintVarGroups(table,table->tree,0,0); + for (i = 0; i < table->size; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->invperm[i]); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < table->size; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->perm[i]); + } + (void) fprintf(table->out,"\n\n"); + Mtr_PrintGroups(table->treeZ,0); + cuddPrintVarGroups(table,table->treeZ,1,0); + for (i = 0; i < table->sizeZ; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->invpermZ[i]); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < table->sizeZ; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->permZ[i]); + } + (void) fprintf(table->out,"\n"); + } + /* End of debugging code. */ +#endif +#ifdef DD_STATS + extsymmcalls = 0; + extsymm = 0; + secdiffcalls = 0; + secdiff = 0; + secdiffmisfire = 0; + + (void) fprintf(table->out,"\n"); + if (!tempTree) + (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", + zddCountInternalMtrNodes(table,table->treeZ)); +#endif + + /* Initialize the group of each subtable to itself. Initially + ** there are no groups. Groups are created according to the tree + ** structure in postorder fashion. + */ + for (i = 0; i < nvars; i++) + table->subtableZ[i].next = i; + + /* Reorder. */ + result = zddTreeSiftingAux(table, table->treeZ, method); + +#ifdef DD_STATS /* print stats */ + if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && + (table->groupcheck == CUDD_GROUP_CHECK7 || + table->groupcheck == CUDD_GROUP_CHECK5)) { + (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); + (void) fprintf(table->out,"extsymm = %d",extsymm); + } + if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && + table->groupcheck == CUDD_GROUP_CHECK7) { + (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); + (void) fprintf(table->out,"secdiff = %d\n",secdiff); + (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); + } +#endif + + if (tempTree) + Cudd_FreeZddTree(table); + return(result); + +} /* end of cuddZddTreeSifting */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Visits the group tree and reorders each group.] + + Description [Recursively visits the group tree and reorders each + group in postorder fashion. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddTreeSiftingAux( + DdManager * table, + MtrNode * treenode, + Cudd_ReorderingType method) +{ + MtrNode *auxnode; + int res; + +#ifdef DD_DEBUG + Mtr_PrintGroups(treenode,1); +#endif + + auxnode = treenode; + while (auxnode != NULL) { + if (auxnode->child != NULL) { + if (!zddTreeSiftingAux(table, auxnode->child, method)) + return(0); + res = zddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT); + if (res == 0) + return(0); + } else if (auxnode->size > 1) { + if (!zddReorderChildren(table, auxnode, method)) + return(0); + } + auxnode = auxnode->younger; + } + + return(1); + +} /* end of zddTreeSiftingAux */ + + +#ifdef DD_STATS +/**Function******************************************************************** + + Synopsis [Counts the number of internal nodes of the group tree.] + + Description [Counts the number of internal nodes of the group tree. + Returns the count.] + + SideEffects [None] + +******************************************************************************/ +static int +zddCountInternalMtrNodes( + DdManager * table, + MtrNode * treenode) +{ + MtrNode *auxnode; + int count,nodeCount; + + + nodeCount = 0; + auxnode = treenode; + while (auxnode != NULL) { + if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { + nodeCount++; + count = zddCountInternalMtrNodes(table,auxnode->child); + nodeCount += count; + } + auxnode = auxnode->younger; + } + + return(nodeCount); + +} /* end of zddCountInternalMtrNodes */ +#endif + + +/**Function******************************************************************** + + Synopsis [Reorders the children of a group tree node according to + the options.] + + Description [Reorders the children of a group tree node according to + the options. After reordering puts all the variables in the group + and/or its descendents in a single group. This allows hierarchical + reordering. If the variables in the group do not exist yet, simply + does nothing. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddReorderChildren( + DdManager * table, + MtrNode * treenode, + Cudd_ReorderingType method) +{ + int lower; + int upper; + int result; + unsigned int initialSize; + + zddFindNodeHiLo(table,treenode,&lower,&upper); + /* If upper == -1 these variables do not exist yet. */ + if (upper == -1) + return(1); + + if (treenode->flags == MTR_FIXED) { + result = 1; + } else { +#ifdef DD_STATS + (void) fprintf(table->out," "); +#endif + switch (method) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + result = cuddZddSwapping(table,lower,upper,method); + break; + case CUDD_REORDER_SIFT: + result = cuddZddSifting(table,lower,upper); + break; + case CUDD_REORDER_SIFT_CONVERGE: + do { + initialSize = table->keysZ; + result = cuddZddSifting(table,lower,upper); + if (initialSize <= table->keysZ) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + case CUDD_REORDER_SYMM_SIFT: + result = cuddZddSymmSifting(table,lower,upper); + break; + case CUDD_REORDER_SYMM_SIFT_CONV: + result = cuddZddSymmSiftingConv(table,lower,upper); + break; + case CUDD_REORDER_GROUP_SIFT: + result = zddGroupSifting(table,lower,upper); + break; + case CUDD_REORDER_LINEAR: + result = cuddZddLinearSifting(table,lower,upper); + break; + case CUDD_REORDER_LINEAR_CONVERGE: + do { + initialSize = table->keysZ; + result = cuddZddLinearSifting(table,lower,upper); + if (initialSize <= table->keysZ) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + default: + return(0); + } + } + + /* Create a single group for all the variables that were sifted, + ** so that they will be treated as a single block by successive + ** invocations of zddGroupSifting. + */ + zddMergeGroups(table,treenode,lower,upper); + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddReorderChildren:"); +#endif + + return(result); + +} /* end of zddReorderChildren */ + + +/**Function******************************************************************** + + Synopsis [Finds the lower and upper bounds of the group represented + by treenode.] + + Description [Finds the lower and upper bounds of the group represented + by treenode. The high and low fields of treenode are indices. From + those we need to derive the current positions, and find maximum and + minimum.] + + SideEffects [The bounds are returned as side effects.] + + SeeAlso [] + +******************************************************************************/ +static void +zddFindNodeHiLo( + DdManager * table, + MtrNode * treenode, + int * lower, + int * upper) +{ + int low; + int high; + + /* Check whether no variables in this group already exist. + ** If so, return immediately. The calling procedure will know from + ** the values of upper that no reordering is needed. + */ + if ((int) treenode->low >= table->sizeZ) { + *lower = table->sizeZ; + *upper = -1; + return; + } + + *lower = low = (unsigned int) table->permZ[treenode->index]; + high = (int) (low + treenode->size - 1); + + if (high >= table->sizeZ) { + /* This is the case of a partially existing group. The aim is to + ** reorder as many variables as safely possible. If the tree + ** node is terminal, we just reorder the subset of the group + ** that is currently in existence. If the group has + ** subgroups, then we only reorder those subgroups that are + ** fully instantiated. This way we avoid breaking up a group. + */ + MtrNode *auxnode = treenode->child; + if (auxnode == NULL) { + *upper = (unsigned int) table->sizeZ - 1; + } else { + /* Search the subgroup that strands the table->sizeZ line. + ** If the first group starts at 0 and goes past table->sizeZ + ** upper will get -1, thus correctly signaling that no reordering + ** should take place. + */ + while (auxnode != NULL) { + int thisLower = table->permZ[auxnode->low]; + int thisUpper = thisLower + auxnode->size - 1; + if (thisUpper >= table->sizeZ && thisLower < table->sizeZ) + *upper = (unsigned int) thisLower - 1; + auxnode = auxnode->younger; + } + } + } else { + /* Normal case: All the variables of the group exist. */ + *upper = (unsigned int) high; + } + +#ifdef DD_DEBUG + /* Make sure that all variables in group are contiguous. */ + assert(treenode->size >= *upper - *lower + 1); +#endif + + return; + +} /* end of zddFindNodeHiLo */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the variables + according to the number of keys in the subtables. Returns the + difference in number of keys between the two variables being + compared.] + + SideEffects [None] + +******************************************************************************/ +static int +zddUniqueCompareGroup( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of zddUniqueCompareGroup */ + + +/**Function******************************************************************** + + Synopsis [Sifts from treenode->low to treenode->high.] + + Description [Sifts from treenode->low to treenode->high. If + croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the + end of the initial sifting. If a group is created, it is then sifted + again. After sifting one variable, the group that contains it is + dissolved. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSifting( + DdManager * table, + int lower, + int upper) +{ + int *var; + int i,j,x,xInit; + int nvars; + int classes; + int result; + int *sifted; +#ifdef DD_STATS + unsigned previousSize; +#endif + int xindex; + + nvars = table->sizeZ; + + /* Order variables to sift. */ + entry = NULL; + sifted = NULL; + var = ALLOC(int,nvars); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; + } + entry = ALLOC(int,nvars); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; + } + sifted = ALLOC(int,nvars); + if (sifted == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; + } + + /* Here we consider only one representative for each group. */ + for (i = 0, classes = 0; i < nvars; i++) { + sifted[i] = 0; + x = table->permZ[i]; + if ((unsigned) x >= table->subtableZ[x].next) { + entry[i] = table->subtableZ[x].keys; + var[classes] = i; + classes++; + } + } + + qsort((void *)var,classes,sizeof(int),(DD_QSFP)zddUniqueCompareGroup); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + xindex = var[i]; + if (sifted[xindex] == 1) /* variable already sifted as part of group */ + continue; + x = table->permZ[xindex]; /* find current level of this variable */ + if (x < lower || x > upper) + continue; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif +#ifdef DD_DEBUG + /* x is bottom of group */ + assert((unsigned) x >= table->subtableZ[x].next); +#endif + result = zddGroupSiftingAux(table,x,lower,upper); + if (!result) goto zddGroupSiftingOutOfMem; + +#ifdef DD_STATS + if (table->keysZ < previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > previousSize) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + + /* Mark variables in the group just sifted. */ + x = table->permZ[xindex]; + if ((unsigned) x != table->subtableZ[x].next) { + xInit = x; + do { + j = table->invpermZ[x]; + sifted[j] = 1; + x = table->subtableZ[x].next; + } while (x != xInit); + } + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSifting:"); +#endif + } /* for */ + + FREE(sifted); + FREE(var); + FREE(entry); + + return(1); + +zddGroupSiftingOutOfMem: + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + if (sifted != NULL) FREE(sifted); + + return(0); + +} /* end of zddGroupSifting */ + + +/**Function******************************************************************** + + Synopsis [Sifts one variable up and down until it has taken all + positions. Checks for aggregation.] + + Description [Sifts one variable up and down until it has taken all + positions. Checks for aggregation. There may be at most two sweeps, + even if the group grows. Assumes that x is either an isolated + variable, or it is the bottom of a group. All groups may not have + been found. The variable being moved is returned to the best position + seen during sifting. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + Move *move; + Move *moves; /* list of moves */ + int initialSize; + int result; + + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingAux from %d to %d\n",xLow,xHigh); + assert((unsigned) x >= table->subtableZ[x].next); /* x is bottom of group */ +#endif + + initialSize = table->keysZ; + moves = NULL; + + if (x == xLow) { /* Sift down */ +#ifdef DD_DEBUG + /* x must be a singleton */ + assert((unsigned) x == table->subtableZ[x].next); +#endif + if (x == xHigh) return(1); /* just one variable */ + + if (!zddGroupSiftingDown(table,x,xHigh,&moves)) + goto zddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); +#ifdef DD_DEBUG + assert(table->keysZ <= (unsigned) initialSize); +#endif + if (!result) goto zddGroupSiftingAuxOutOfMem; + + } else if (cuddZddNextHigh(table,x) > xHigh) { /* Sift up */ +#ifdef DD_DEBUG + /* x is bottom of group */ + assert((unsigned) x >= table->subtableZ[x].next); +#endif + /* Find top of x's group */ + x = table->subtableZ[x].next; + + if (!zddGroupSiftingUp(table,x,xLow,&moves)) + goto zddGroupSiftingAuxOutOfMem; + /* at this point x == xLow, unless early term */ + + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); +#ifdef DD_DEBUG + assert(table->keysZ <= (unsigned) initialSize); +#endif + if (!result) goto zddGroupSiftingAuxOutOfMem; + + } else if (x - xLow > xHigh - x) { /* must go down first: shorter */ + if (!zddGroupSiftingDown(table,x,xHigh,&moves)) + goto zddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + /* Find top of group */ + if (moves) { + x = moves->y; + } + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; +#ifdef DD_DEBUG + /* x should be the top of a group */ + assert((unsigned) x <= table->subtableZ[x].next); +#endif + + if (!zddGroupSiftingUp(table,x,xLow,&moves)) + goto zddGroupSiftingAuxOutOfMem; + + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); +#ifdef DD_DEBUG + assert(table->keysZ <= (unsigned) initialSize); +#endif + if (!result) goto zddGroupSiftingAuxOutOfMem; + + } else { /* moving up first: shorter */ + /* Find top of x's group */ + x = table->subtableZ[x].next; + + if (!zddGroupSiftingUp(table,x,xLow,&moves)) + goto zddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + if (moves) { + x = moves->x; + } + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; +#ifdef DD_DEBUG + /* x is bottom of a group */ + assert((unsigned) x >= table->subtableZ[x].next); +#endif + + if (!zddGroupSiftingDown(table,x,xHigh,&moves)) + goto zddGroupSiftingAuxOutOfMem; + + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); +#ifdef DD_DEBUG + assert(table->keysZ <= (unsigned) initialSize); +#endif + if (!result) goto zddGroupSiftingAuxOutOfMem; + } + + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(1); + +zddGroupSiftingAuxOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(0); + +} /* end of zddGroupSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much.] + + Description [Sifts up a variable until either it reaches position + xLow or the size of the DD heap increases too much. Assumes that y is + the top of a group (or a singleton). Checks y for aggregation to the + adjacent variables. Records all the moves that are appended to the + list of moves received as input and returned as a side effect. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSiftingUp( + DdManager * table, + int y, + int xLow, + Move ** moves) +{ + Move *move; + int x; + int size; + int gxtop; + int limitSize; + + limitSize = table->keysZ; + + x = cuddZddNextLow(table,y); + while (x >= xLow) { + gxtop = table->subtableZ[x].next; + if (table->subtableZ[x].next == (unsigned) x && + table->subtableZ[y].next == (unsigned) y) { + /* x and y are self groups */ + size = cuddZddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtableZ[x].next == (unsigned) x); + assert(table->subtableZ[y].next == (unsigned) y); +#endif + if (size == 0) goto zddGroupSiftingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto zddGroupSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_DEFAULT; + move->size = size; + move->next = *moves; + *moves = move; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingUp (2 single groups):\n"); +#endif + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } else { /* group move */ + size = zddGroupMove(table,x,y,moves); + if (size == 0) goto zddGroupSiftingUpOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } + y = gxtop; + x = cuddZddNextLow(table,y); + } + + return(1); + +zddGroupSiftingUpOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of zddGroupSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts down a variable until it reaches position xHigh.] + + Description [Sifts down a variable until it reaches position xHigh. + Assumes that x is the bottom of a group (or a singleton). Records + all the moves. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSiftingDown( + DdManager * table, + int x, + int xHigh, + Move ** moves) +{ + Move *move; + int y; + int size; + int limitSize; + int gybot; + + + /* Initialize R */ + limitSize = size = table->keysZ; + y = cuddZddNextHigh(table,x); + while (y <= xHigh) { + /* Find bottom of y group. */ + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + + if (table->subtableZ[x].next == (unsigned) x && + table->subtableZ[y].next == (unsigned) y) { + /* x and y are self groups */ + size = cuddZddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtableZ[x].next == (unsigned) x); + assert(table->subtableZ[y].next == (unsigned) y); +#endif + if (size == 0) goto zddGroupSiftingDownOutOfMem; + + /* Record move. */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto zddGroupSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_DEFAULT; + move->size = size; + move->next = *moves; + *moves = move; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingDown (2 single groups):\n"); +#endif + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + x = y; + y = cuddZddNextHigh(table,x); + } else { /* Group move */ + size = zddGroupMove(table,x,y,moves); + if (size == 0) goto zddGroupSiftingDownOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } + x = gybot; + y = cuddZddNextHigh(table,x); + } + + return(1); + +zddGroupSiftingDownOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + + return(0); + +} /* end of zddGroupSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Swaps two groups and records the move.] + + Description [Swaps two groups and records the move. Returns the + number of keys in the DD table in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupMove( + DdManager * table, + int x, + int y, + Move ** moves) +{ + Move *move; + int size; + int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + int swapx,swapy; +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + int initialSize,bestSize; +#endif + +#ifdef DD_DEBUG + /* We assume that x < y */ + assert(x < y); +#endif + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtableZ[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtableZ[ybot].next) + ybot = table->subtableZ[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + initialSize = bestSize = table->keysZ; +#endif + /* Sift the variables of the second group up through the first group */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddZddSwapInPlace(table,x,y); + if (size == 0) goto zddGroupMoveOutOfMem; +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (size < bestSize) + bestSize = size; +#endif + swapx = x; swapy = y; + y = x; + x = cuddZddNextLow(table,y); + } + y = ytop + i; + x = cuddZddNextLow(table,y); + } +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if ((bestSize < initialSize) && (bestSize < size)) + (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); +#endif + + /* fix groups */ + y = xtop; /* ytop is now where xtop used to be */ + for (i = 0; i < ysize - 1; i++) { + table->subtableZ[y].next = cuddZddNextHigh(table,y); + y = cuddZddNextHigh(table,y); + } + table->subtableZ[y].next = xtop; /* y is bottom of its group, join */ + /* it to top of its group */ + x = cuddZddNextHigh(table,y); + newxtop = x; + for (i = 0; i < xsize - 1; i++) { + table->subtableZ[x].next = cuddZddNextHigh(table,x); + x = cuddZddNextHigh(table,x); + } + table->subtableZ[x].next = newxtop; /* x is bottom of its group, join */ + /* it to top of its group */ +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupMove:\n"); +#endif + + /* Store group move */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto zddGroupMoveOutOfMem; + move->x = swapx; + move->y = swapy; + move->flags = MTR_DEFAULT; + move->size = table->keysZ; + move->next = *moves; + *moves = move; + + return(table->keysZ); + +zddGroupMoveOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of zddGroupMove */ + + +/**Function******************************************************************** + + Synopsis [Undoes the swap two groups.] + + Description [Undoes the swap two groups. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupMoveBackward( + DdManager * table, + int x, + int y) +{ + int size; + int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + + +#ifdef DD_DEBUG + /* We assume that x < y */ + assert(x < y); +#endif + + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtableZ[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtableZ[ybot].next) + ybot = table->subtableZ[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + + /* Sift the variables of the second group up through the first group */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddZddSwapInPlace(table,x,y); + if (size == 0) + return(0); + y = x; + x = cuddZddNextLow(table,y); + } + y = ytop + i; + x = cuddZddNextLow(table,y); + } + + /* fix groups */ + y = xtop; + for (i = 0; i < ysize - 1; i++) { + table->subtableZ[y].next = cuddZddNextHigh(table,y); + y = cuddZddNextHigh(table,y); + } + table->subtableZ[y].next = xtop; /* y is bottom of its group, join */ + /* to its top */ + x = cuddZddNextHigh(table,y); + newxtop = x; + for (i = 0; i < xsize - 1; i++) { + table->subtableZ[x].next = cuddZddNextHigh(table,x); + x = cuddZddNextHigh(table,x); + } + table->subtableZ[x].next = newxtop; /* x is bottom of its group, join */ + /* to its top */ +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupMoveBackward:\n"); +#endif + + return(1); + +} /* end of zddGroupMoveBackward */ + + +/**Function******************************************************************** + + Synopsis [Determines the best position for a variables and returns + it there.] + + Description [Determines the best position for a variables and returns + it there. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSiftingBackward( + DdManager * table, + Move * moves, + int size) +{ + Move *move; + int res; + + + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + if ((table->subtableZ[move->x].next == move->x) && + (table->subtableZ[move->y].next == move->y)) { + res = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingBackward:\n"); + assert(table->subtableZ[move->x].next == move->x); + assert(table->subtableZ[move->y].next == move->y); +#endif + } else { /* Group move necessary */ + res = zddGroupMoveBackward(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + } + + return(1); + +} /* end of zddGroupSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Merges groups in the DD table.] + + Description [Creates a single group from low to high and adjusts the + idex field of the tree node.] + + SideEffects [None] + +******************************************************************************/ +static void +zddMergeGroups( + DdManager * table, + MtrNode * treenode, + int low, + int high) +{ + int i; + MtrNode *auxnode; + int saveindex; + int newindex; + + /* Merge all variables from low to high in one group, unless + ** this is the topmost group. In such a case we do not merge lest + ** we lose the symmetry information. */ + if (treenode != table->treeZ) { + for (i = low; i < high; i++) + table->subtableZ[i].next = i+1; + table->subtableZ[high].next = low; + } + + /* Adjust the index fields of the tree nodes. If a node is the + ** first child of its parent, then the parent may also need adjustment. */ + saveindex = treenode->index; + newindex = table->invpermZ[low]; + auxnode = treenode; + do { + auxnode->index = newindex; + if (auxnode->parent == NULL || + (int) auxnode->parent->index != saveindex) + break; + auxnode = auxnode->parent; + } while (1); + return; + +} /* end of zddMergeGroups */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddIsop.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddIsop.c new file mode 100644 index 000000000..c1eaea3d6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddIsop.c @@ -0,0 +1,912 @@ +/**CFile*********************************************************************** + + FileName [cuddZddIsop.c] + + PackageName [cudd] + + Synopsis [Functions to find irredundant SOP covers as ZDDs from BDDs.] + + Description [External procedures included in this module: +
                  +
                • Cudd_bddIsop() +
                • Cudd_zddIsop() +
                • Cudd_MakeBddFromZddCover() +
                + Internal procedures included in this module: +
                  +
                • cuddBddIsop() +
                • cuddZddIsop() +
                • cuddMakeBddFromZddCover() +
                + Static procedures included in this module: +
                  +
                + ] + + SeeAlso [] + + Author [In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddIsop.c,v 1.22 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Computes an ISOP in ZDD form from BDDs.] + + Description [Computes an irredundant sum of products (ISOP) in ZDD + form from BDDs. The two BDDs L and U represent the lower bound and + the upper bound, respectively, of the function. The ISOP uses two + ZDD variables for each BDD variable: One for the positive literal, + and one for the negative literal. These two variables should be + adjacent in the ZDD order. The two ZDD variables corresponding to + BDD variable i should have indices 2i and + 2i+1. The result of this procedure depends on the + variable order. If successful, Cudd_zddIsop returns the BDD for + the function chosen from the interval. The ZDD representing the + irredundant cover is returned as a side effect in zdd_I. In case of + failure, NULL is returned.] + + SideEffects [zdd_I holds the pointer to the ZDD for the ISOP on + successful return.] + + SeeAlso [Cudd_bddIsop Cudd_zddVarsFromBddVars] + +******************************************************************************/ +DdNode * +Cudd_zddIsop( + DdManager * dd, + DdNode * L, + DdNode * U, + DdNode ** zdd_I) +{ + DdNode *res; + int autoDynZ; + + autoDynZ = dd->autoDynZ; + dd->autoDynZ = 0; + + do { + dd->reordered = 0; + res = cuddZddIsop(dd, L, U, zdd_I); + } while (dd->reordered == 1); + dd->autoDynZ = autoDynZ; + return(res); + +} /* end of Cudd_zddIsop */ + + +/**Function******************************************************************** + + Synopsis [Computes a BDD in the interval between L and U with a + simple sum-of-product cover.] + + Description [Computes a BDD in the interval between L and U with a + simple sum-of-product cover. This procedure is similar to + Cudd_zddIsop, but it does not return the ZDD for the cover. Returns + a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddIsop] + +******************************************************************************/ +DdNode * +Cudd_bddIsop( + DdManager * dd, + DdNode * L, + DdNode * U) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddIsop(dd, L, U); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddIsop */ + + +/**Function******************************************************************** + + Synopsis [Converts a ZDD cover to a BDD.] + + Description [Converts a ZDD cover to a BDD for the function represented + by the cover. If successful, it returns a BDD node, otherwise it returns + NULL.] + + SideEffects [] + + SeeAlso [Cudd_zddIsop] + +******************************************************************************/ +DdNode * +Cudd_MakeBddFromZddCover( + DdManager * dd, + DdNode * node) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddMakeBddFromZddCover(dd, node); + } while (dd->reordered == 1); + return(res); +} /* end of Cudd_MakeBddFromZddCover */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddIsop.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddIsop] + +******************************************************************************/ +DdNode * +cuddZddIsop( + DdManager * dd, + DdNode * L, + DdNode * U, + DdNode ** zdd_I) +{ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + DdNode *zdd_one = DD_ONE(dd); + DdNode *zdd_zero = DD_ZERO(dd); + int v, top_l, top_u; + DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; + DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; + DdNode *Isub0, *Isub1, *Id; + DdNode *zdd_Isub0, *zdd_Isub1, *zdd_Id; + DdNode *x; + DdNode *term0, *term1, *sum; + DdNode *Lv, *Uv, *Lnv, *Unv; + DdNode *r, *y, *z; + int index; + DD_CTFP cacheOp; + + statLine(dd); + if (L == zero) { + *zdd_I = zdd_zero; + return(zero); + } + if (U == one) { + *zdd_I = zdd_one; + return(one); + } + + if (U == zero || L == one) { + printf("*** ERROR : illegal condition for ISOP (U < L).\n"); + exit(1); + } + + /* Check the cache. We store two results for each recursive call. + ** One is the BDD, and the other is the ZDD. Both are needed. + ** Hence we need a double hit in the cache to terminate the + ** recursion. Clearly, collisions may evict only one of the two + ** results. */ + cacheOp = (DD_CTFP) cuddZddIsop; + r = cuddCacheLookup2(dd, cuddBddIsop, L, U); + if (r) { + *zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U); + if (*zdd_I) + return(r); + else { + /* The BDD result may have been dead. In that case + ** cuddCacheLookup2 would have called cuddReclaim, + ** whose effects we now have to undo. */ + cuddRef(r); + Cudd_RecursiveDeref(dd, r); + } + } + + top_l = dd->perm[Cudd_Regular(L)->index]; + top_u = dd->perm[Cudd_Regular(U)->index]; + v = ddMin(top_l, top_u); + + /* Compute cofactors. */ + if (top_l == v) { + index = Cudd_Regular(L)->index; + Lv = Cudd_T(L); + Lnv = Cudd_E(L); + if (Cudd_IsComplement(L)) { + Lv = Cudd_Not(Lv); + Lnv = Cudd_Not(Lnv); + } + } + else { + index = Cudd_Regular(U)->index; + Lv = Lnv = L; + } + + if (top_u == v) { + Uv = Cudd_T(U); + Unv = Cudd_E(U); + if (Cudd_IsComplement(U)) { + Uv = Cudd_Not(Uv); + Unv = Cudd_Not(Unv); + } + } + else { + Uv = Unv = U; + } + + Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv)); + if (Lsub0 == NULL) + return(NULL); + Cudd_Ref(Lsub0); + Usub0 = Unv; + Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv)); + if (Lsub1 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + return(NULL); + } + Cudd_Ref(Lsub1); + Usub1 = Uv; + + Isub0 = cuddZddIsop(dd, Lsub0, Usub0, &zdd_Isub0); + if (Isub0 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + return(NULL); + } + /* + if ((!cuddIsConstant(Cudd_Regular(Isub0))) && + (Cudd_Regular(Isub0)->index != zdd_Isub0->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Isub0->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); + } + */ + Cudd_Ref(Isub0); + Cudd_Ref(zdd_Isub0); + Isub1 = cuddZddIsop(dd, Lsub1, Usub1, &zdd_Isub1); + if (Isub1 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + return(NULL); + } + /* + if ((!cuddIsConstant(Cudd_Regular(Isub1))) && + (Cudd_Regular(Isub1)->index != zdd_Isub1->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Isub1->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); + } + */ + Cudd_Ref(Isub1); + Cudd_Ref(zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + + Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0)); + if (Lsuper0 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + return(NULL); + } + Cudd_Ref(Lsuper0); + Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1)); + if (Lsuper1 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + return(NULL); + } + Cudd_Ref(Lsuper1); + Usuper0 = Unv; + Usuper1 = Uv; + + /* Ld = Lsuper0 + Lsuper1 */ + Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1)); + if (Ld == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + return(NULL); + } + Ld = Cudd_Not(Ld); + Cudd_Ref(Ld); + /* Ud = Usuper0 * Usuper1 */ + Ud = cuddBddAndRecur(dd, Usuper0, Usuper1); + if (Ud == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + Cudd_RecursiveDeref(dd, Ld); + return(NULL); + } + Cudd_Ref(Ud); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + + Id = cuddZddIsop(dd, Ld, Ud, &zdd_Id); + if (Id == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + return(NULL); + } + /* + if ((!cuddIsConstant(Cudd_Regular(Id))) && + (Cudd_Regular(Id)->index != zdd_Id->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Id->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); + } + */ + Cudd_Ref(Id); + Cudd_Ref(zdd_Id); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + + x = cuddUniqueInter(dd, index, one, zero); + if (x == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + return(NULL); + } + Cudd_Ref(x); + /* term0 = x * Isub0 */ + term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0); + if (term0 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + Cudd_Ref(term0); + Cudd_RecursiveDeref(dd, Isub0); + /* term1 = x * Isub1 */ + term1 = cuddBddAndRecur(dd, x, Isub1); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, term0); + return(NULL); + } + Cudd_Ref(term1); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, Isub1); + /* sum = term0 + term1 */ + sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1)); + if (sum == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + return(NULL); + } + sum = Cudd_Not(sum); + Cudd_Ref(sum); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + /* r = sum + Id */ + r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id)); + r = Cudd_NotCond(r, r != NULL); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, sum); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDeref(dd, sum); + Cudd_RecursiveDeref(dd, Id); + + if (zdd_Isub0 != zdd_zero) { + z = cuddZddGetNodeIVO(dd, index * 2 + 1, zdd_Isub0, zdd_Id); + if (z == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, r); + return(NULL); + } + } + else { + z = zdd_Id; + } + Cudd_Ref(z); + if (zdd_Isub1 != zdd_zero) { + y = cuddZddGetNodeIVO(dd, index * 2, zdd_Isub1, z); + if (y == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, r); + Cudd_RecursiveDerefZdd(dd, z); + return(NULL); + } + } + else + y = z; + Cudd_Ref(y); + + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDerefZdd(dd, z); + + cuddCacheInsert2(dd, cuddBddIsop, L, U, r); + cuddCacheInsert2(dd, cacheOp, L, U, y); + + Cudd_Deref(r); + Cudd_Deref(y); + *zdd_I = y; + /* + if (Cudd_Regular(r)->index != y->index / 2) { + printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n"); + } + */ + return(r); + +} /* end of cuddZddIsop */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddIsop.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_bddIsop] + +******************************************************************************/ +DdNode * +cuddBddIsop( + DdManager * dd, + DdNode * L, + DdNode * U) +{ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + int v, top_l, top_u; + DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; + DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; + DdNode *Isub0, *Isub1, *Id; + DdNode *x; + DdNode *term0, *term1, *sum; + DdNode *Lv, *Uv, *Lnv, *Unv; + DdNode *r; + int index; + + statLine(dd); + if (L == zero) + return(zero); + if (U == one) + return(one); + + /* Check cache */ + r = cuddCacheLookup2(dd, cuddBddIsop, L, U); + if (r) + return(r); + + top_l = dd->perm[Cudd_Regular(L)->index]; + top_u = dd->perm[Cudd_Regular(U)->index]; + v = ddMin(top_l, top_u); + + /* Compute cofactors */ + if (top_l == v) { + index = Cudd_Regular(L)->index; + Lv = Cudd_T(L); + Lnv = Cudd_E(L); + if (Cudd_IsComplement(L)) { + Lv = Cudd_Not(Lv); + Lnv = Cudd_Not(Lnv); + } + } + else { + index = Cudd_Regular(U)->index; + Lv = Lnv = L; + } + + if (top_u == v) { + Uv = Cudd_T(U); + Unv = Cudd_E(U); + if (Cudd_IsComplement(U)) { + Uv = Cudd_Not(Uv); + Unv = Cudd_Not(Unv); + } + } + else { + Uv = Unv = U; + } + + Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv)); + if (Lsub0 == NULL) + return(NULL); + Cudd_Ref(Lsub0); + Usub0 = Unv; + Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv)); + if (Lsub1 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + return(NULL); + } + Cudd_Ref(Lsub1); + Usub1 = Uv; + + Isub0 = cuddBddIsop(dd, Lsub0, Usub0); + if (Isub0 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + return(NULL); + } + Cudd_Ref(Isub0); + Isub1 = cuddBddIsop(dd, Lsub1, Usub1); + if (Isub1 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + Cudd_RecursiveDeref(dd, Isub0); + return(NULL); + } + Cudd_Ref(Isub1); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + + Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0)); + if (Lsuper0 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + return(NULL); + } + Cudd_Ref(Lsuper0); + Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1)); + if (Lsuper1 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + return(NULL); + } + Cudd_Ref(Lsuper1); + Usuper0 = Unv; + Usuper1 = Uv; + + /* Ld = Lsuper0 + Lsuper1 */ + Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1)); + Ld = Cudd_NotCond(Ld, Ld != NULL); + if (Ld == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + return(NULL); + } + Cudd_Ref(Ld); + Ud = cuddBddAndRecur(dd, Usuper0, Usuper1); + if (Ud == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + Cudd_RecursiveDeref(dd, Ld); + return(NULL); + } + Cudd_Ref(Ud); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + + Id = cuddBddIsop(dd, Ld, Ud); + if (Id == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + return(NULL); + } + Cudd_Ref(Id); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + + x = cuddUniqueInter(dd, index, one, zero); + if (x == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + return(NULL); + } + Cudd_Ref(x); + term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0); + if (term0 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + Cudd_Ref(term0); + Cudd_RecursiveDeref(dd, Isub0); + term1 = cuddBddAndRecur(dd, x, Isub1); + if (term1 == NULL) { + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, term0); + return(NULL); + } + Cudd_Ref(term1); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, Isub1); + /* sum = term0 + term1 */ + sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1)); + sum = Cudd_NotCond(sum, sum != NULL); + if (sum == NULL) { + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + return(NULL); + } + Cudd_Ref(sum); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + /* r = sum + Id */ + r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id)); + r = Cudd_NotCond(r, r != NULL); + if (r == NULL) { + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, sum); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDeref(dd, sum); + Cudd_RecursiveDeref(dd, Id); + + cuddCacheInsert2(dd, cuddBddIsop, L, U, r); + + Cudd_Deref(r); + return(r); + +} /* end of cuddBddIsop */ + + +/**Function******************************************************************** + + Synopsis [Converts a ZDD cover to a BDD.] + + Description [Converts a ZDD cover to a BDD. If successful, it returns + a BDD node, otherwise it returns NULL. It is a recursive algorithm + that works as follows. First it computes 3 cofactors of a ZDD cover: + f1, f0 and fd. Second, it compute BDDs (b1, b0 and bd) of f1, f0 and fd. + Third, it computes T=b1+bd and E=b0+bd. Fourth, it computes ITE(v,T,E) where + v is the variable which has the index of the top node of the ZDD cover. + In this case, since the index of v can be larger than either the one of T + or the one of E, cuddUniqueInterIVO is called, where IVO stands for + independent from variable ordering.] + + SideEffects [] + + SeeAlso [Cudd_MakeBddFromZddCover] + +******************************************************************************/ +DdNode * +cuddMakeBddFromZddCover( + DdManager * dd, + DdNode * node) +{ + DdNode *neW; + int v; + DdNode *f1, *f0, *fd; + DdNode *b1, *b0, *bd; + DdNode *T, *E; + + statLine(dd); + if (node == dd->one) + return(dd->one); + if (node == dd->zero) + return(Cudd_Not(dd->one)); + + /* Check cache */ + neW = cuddCacheLookup1(dd, cuddMakeBddFromZddCover, node); + if (neW) + return(neW); + + v = Cudd_Regular(node)->index; /* either yi or zi */ + if (cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd)) return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + + b1 = cuddMakeBddFromZddCover(dd, f1); + if (!b1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(b1); + b0 = cuddMakeBddFromZddCover(dd, f0); + if (!b0) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDeref(dd, b1); + return(NULL); + } + Cudd_Ref(b0); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + if (fd != dd->zero) { + bd = cuddMakeBddFromZddCover(dd, fd); + if (!bd) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDeref(dd, b1); + Cudd_RecursiveDeref(dd, b0); + return(NULL); + } + Cudd_Ref(bd); + Cudd_RecursiveDerefZdd(dd, fd); + + T = cuddBddAndRecur(dd, Cudd_Not(b1), Cudd_Not(bd)); + if (!T) { + Cudd_RecursiveDeref(dd, b1); + Cudd_RecursiveDeref(dd, b0); + Cudd_RecursiveDeref(dd, bd); + return(NULL); + } + T = Cudd_NotCond(T, T != NULL); + Cudd_Ref(T); + Cudd_RecursiveDeref(dd, b1); + E = cuddBddAndRecur(dd, Cudd_Not(b0), Cudd_Not(bd)); + if (!E) { + Cudd_RecursiveDeref(dd, b0); + Cudd_RecursiveDeref(dd, bd); + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + E = Cudd_NotCond(E, E != NULL); + Cudd_Ref(E); + Cudd_RecursiveDeref(dd, b0); + Cudd_RecursiveDeref(dd, bd); + } + else { + Cudd_RecursiveDerefZdd(dd, fd); + T = b1; + E = b0; + } + + if (Cudd_IsComplement(T)) { + neW = cuddUniqueInterIVO(dd, v / 2, Cudd_Not(T), Cudd_Not(E)); + if (!neW) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + neW = Cudd_Not(neW); + } + else { + neW = cuddUniqueInterIVO(dd, v / 2, T, E); + if (!neW) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + Cudd_Ref(neW); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + + cuddCacheInsert1(dd, cuddMakeBddFromZddCover, node, neW); + Cudd_Deref(neW); + return(neW); + +} /* end of cuddMakeBddFromZddCover */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddLin.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddLin.c new file mode 100644 index 000000000..3fc989d5b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddLin.c @@ -0,0 +1,971 @@ +/**CFile*********************************************************************** + + FileName [cuddZddLin.c] + + PackageName [cudd] + + Synopsis [Procedures for dynamic variable ordering of ZDDs.] + + Description [Internal procedures included in this module: +
                  +
                • cuddZddLinearSifting() +
                + Static procedures included in this module: +
                  +
                • cuddZddLinearInPlace() +
                • cuddZddLinerAux() +
                • cuddZddLinearUp() +
                • cuddZddLinearDown() +
                • cuddZddLinearBackward() +
                • cuddZddUndoMoves() +
                + ] + + SeeAlso [cuddLinear.c cuddZddReord.c] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define CUDD_SWAP_MOVE 0 +#define CUDD_LINEAR_TRANSFORM_MOVE 1 +#define CUDD_INVERSE_TRANSFORM_MOVE 2 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddLin.c,v 1.16 2012/02/05 01:07:19 fabio Exp $"; +#endif + +extern int *zdd_entry; +extern int zddTotalNumberSwapping; +static int zddTotalNumberLinearTr; +static DdNode *empty; + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddZddLinearInPlace (DdManager * table, int x, int y); +static int cuddZddLinearAux (DdManager *table, int x, int xLow, int xHigh); +static Move * cuddZddLinearUp (DdManager *table, int y, int xLow, Move *prevMoves); +static Move * cuddZddLinearDown (DdManager *table, int x, int xHigh, Move *prevMoves); +static int cuddZddLinearBackward (DdManager *table, int size, Move *moves); +static Move* cuddZddUndoMoves (DdManager *table, Move *moves); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + + + +/**Function******************************************************************** + + Synopsis [Implementation of the linear sifting algorithm for ZDDs.] + + Description [Implementation of the linear sifting algorithm for ZDDs. + Assumes that no dead nodes are present. +
                  +
                1. Order all the variables according to the number of entries + in each unique table. +
                2. Sift the variable up and down and applies the XOR transformation, + remembering each time the total size of the DD heap. +
                3. Select the best permutation. +
                4. Repeat 3 and 4 for all variables. +
                + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddLinearSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; +#ifdef DD_STATS + int previousSize; +#endif + + size = table->sizeZ; + empty = table->zero; + + /* Find order in which to sift variables. */ + var = NULL; + zdd_entry = ALLOC(int, size); + if (zdd_entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; + } + var = ALLOC(int, size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; + } + + qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar, size); i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = cuddZddLinearAux(table, x, lower, upper); + if (!result) + goto cuddZddSiftingOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + FREE(var); + FREE(zdd_entry); + + return(1); + +cuddZddSiftingOutOfMem: + + if (zdd_entry != NULL) FREE(zdd_entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddZddLinearSifting */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Linearly combines two adjacent variables.] + + Description [Linearly combines two adjacent variables. It assumes + that no dead nodes are present on entry to this procedure. The + procedure then guarantees that no dead nodes will be present when it + terminates. cuddZddLinearInPlace assumes that x < y. Returns the + number of keys in the table if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddZddSwapInPlace cuddLinearInPlace] + +******************************************************************************/ +static int +cuddZddLinearInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int i; + int posn; + DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; + DdNode *newf1, *newf0, *g, *next, *previous; + DdNode *special; + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddZddNextHigh(table,x) == y); + assert(table->subtableZ[x].keys != 0); + assert(table->subtableZ[y].keys != 0); + assert(table->subtableZ[x].dead == 0); + assert(table->subtableZ[y].dead == 0); +#endif + + zddTotalNumberLinearTr++; + + /* Get parameters of x subtable. */ + xindex = table->invpermZ[x]; + xlist = table->subtableZ[x].nodelist; + oldxkeys = table->subtableZ[x].keys; + xslots = table->subtableZ[x].slots; + xshift = table->subtableZ[x].shift; + newxkeys = 0; + + /* Get parameters of y subtable. */ + yindex = table->invpermZ[y]; + ylist = table->subtableZ[y].nodelist; + oldykeys = table->subtableZ[y].keys; + yslots = table->subtableZ[y].slots; + yshift = table->subtableZ[y].shift; + newykeys = oldykeys; + + /* The nodes in the x layer are put in two chains. The chain + ** pointed by g holds the normal nodes. When re-expressed they stay + ** in the x list. The chain pointed by special holds the elements + ** that will move to the y list. + */ + g = special = NULL; + for (i = 0; i < xslots; i++) { + f = xlist[i]; + if (f == NULL) continue; + xlist[i] = NULL; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); + /* if (f1->index == yindex) */ cuddSatDec(f1->ref); + f0 = cuddE(f); + /* if (f0->index == yindex) */ cuddSatDec(f0->ref); + if ((int) f1->index == yindex && cuddE(f1) == empty && + (int) f0->index != yindex) { + f->next = special; + special = f; + } else { + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ + } /* for each slot of the x subtable */ + + /* Mark y nodes with pointers from above x. We mark them by + ** changing their index to x. + */ + for (i = 0; i < yslots; i++) { + f = ylist[i]; + while (f != NULL) { + if (f->ref != 0) { + f->index = xindex; + } + f = f->next; + } /* while there are elements in the collision chain */ + } /* for each slot of the y subtable */ + + /* Move special nodes to the y list. */ + f = special; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); + f11 = cuddT(f1); + cuddT(f) = f11; + cuddSatInc(f11->ref); + f0 = cuddE(f); + cuddSatInc(f0->ref); + f->index = yindex; + /* Insert at the beginning of the list so that it will be + ** found first if there is a duplicate. The duplicate will + ** eventually be moved or garbage collected. No node + ** re-expression will add a pointer to it. + */ + posn = ddHash(f11, f0, yshift); + f->next = ylist[posn]; + ylist[posn] = f; + newykeys++; + f = next; + } + + /* Take care of the remaining x nodes that must be re-expressed. + ** They form a linked list pointed by g. + */ + f = g; + while (f != NULL) { +#ifdef DD_COUNT + table->swapSteps++; +#endif + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + if ((int) f1->index == yindex || (int) f1->index == xindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = empty; f10 = f1; + } + f0 = cuddE(f); + if ((int) f0->index == yindex || (int) f0->index == xindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = empty; f00 = f0; + } + /* Create the new T child. */ + if (f01 == empty) { + newf1 = f10; + cuddSatInc(newf1->ref); + } else { + /* Check ylist for triple (yindex, f01, f10). */ + posn = ddHash(f01, f10, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + newf1 = ylist[posn]; + /* Search the collision chain skipping the marked nodes. */ + while (newf1 != NULL) { + if (cuddT(newf1) == f01 && cuddE(newf1) == f10 && + (int) newf1->index == yindex) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f01; + cuddE(newf1) = f10; + /* Insert newf1 in the collision list ylist[pos]; + ** increase the ref counts of f01 and f10 + */ + newykeys++; + newf1->next = ylist[posn]; + ylist[posn] = newf1; + cuddSatInc(f01->ref); + cuddSatInc(f10->ref); + } + } + cuddT(f) = newf1; + + /* Do the same for f0. */ + /* Create the new E child. */ + if (f11 == empty) { + newf0 = f00; + cuddSatInc(newf0->ref); + } else { + /* Check ylist for triple (yindex, f11, f00). */ + posn = ddHash(f11, f00, yshift); + /* For each element newf0 in collision list ylist[posn]. */ + newf0 = ylist[posn]; + while (newf0 != NULL) { + if (cuddT(newf0) == f11 && cuddE(newf0) == f00 && + (int) newf0->index == yindex) { + cuddSatInc(newf0->ref); + break; /* match */ + } + newf0 = newf0->next; + } /* while newf0 */ + if (newf0 == NULL) { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto zddSwapOutOfMem; + newf0->index = yindex; newf0->ref = 1; + cuddT(newf0) = f11; cuddE(newf0) = f00; + /* Insert newf0 in the collision list ylist[posn]; + ** increase the ref counts of f11 and f00. + */ + newykeys++; + newf0->next = ylist[posn]; + ylist[posn] = newf0; + cuddSatInc(f11->ref); + cuddSatInc(f00->ref); + } + } + cuddE(f) = newf0; + + /* Re-insert the modified f in xlist. + ** The modified f does not already exists in xlist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, xshift); + newxkeys++; + f->next = xlist[posn]; + xlist[posn] = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer and move the marked nodes to the x list. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previous = NULL; + f = ylist[i]; + while (f != NULL) { + next = f->next; + if (f->ref == 0) { + cuddSatDec(cuddT(f)->ref); + cuddSatDec(cuddE(f)->ref); + cuddDeallocNode(table, f); + newykeys--; + if (previous == NULL) + ylist[i] = next; + else + previous->next = next; + } else if ((int) f->index == xindex) { /* move marked node */ + if (previous == NULL) + ylist[i] = next; + else + previous->next = next; + f1 = cuddT(f); + cuddSatDec(f1->ref); + /* Check ylist for triple (yindex, f1, empty). */ + posn = ddHash(f1, empty, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + newf1 = ylist[posn]; + while (newf1 != NULL) { + if (cuddT(newf1) == f1 && cuddE(newf1) == empty && + (int) newf1->index == yindex) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f1; cuddE(newf1) = empty; + /* Insert newf1 in the collision list ylist[posn]; + ** increase the ref counts of f1 and empty. + */ + newykeys++; + newf1->next = ylist[posn]; + ylist[posn] = newf1; + if (posn == i && previous == NULL) + previous = newf1; + cuddSatInc(f1->ref); + cuddSatInc(empty->ref); + } + cuddT(f) = newf1; + f0 = cuddE(f); + /* Insert f in x list. */ + posn = ddHash(newf1, f0, xshift); + newxkeys++; + newykeys--; + f->next = xlist[posn]; + xlist[posn] = f; + } else { + previous = f; + } + f = next; + } /* while f */ + } /* for i */ + + /* Set the appropriate fields in table. */ + table->subtableZ[x].keys = newxkeys; + table->subtableZ[y].keys = newykeys; + + table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys; + + /* Update univ section; univ[x] remains the same. */ + table->univ[y] = cuddT(table->univ[x]); + +#if 0 + (void) fprintf(table->out,"x = %d y = %d\n", x, y); + (void) Cudd_DebugCheck(table); + (void) Cudd_CheckKeys(table); +#endif + + return (table->keysZ); + +zddSwapOutOfMem: + (void) fprintf(table->err, "Error: cuddZddSwapInPlace out of memory\n"); + + return (0); + +} /* end of cuddZddLinearInPlace */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddLinearAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + Move *move; + Move *moveUp; /* list of up move */ + Move *moveDown; /* list of down move */ + + int initial_size; + int result; + + initial_size = table->keysZ; + +#ifdef DD_DEBUG + assert(table->subtableZ[x].keys > 0); +#endif + + moveDown = NULL; + moveUp = NULL; + + if (x == xLow) { + moveDown = cuddZddLinearDown(table, x, xHigh, NULL); + /* At this point x --> xHigh. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveDown); + if (!result) + goto cuddZddLinearAuxOutOfMem; + + } else if (x == xHigh) { + moveUp = cuddZddLinearUp(table, x, xLow, NULL); + /* At this point x --> xLow. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveUp); + if (!result) + goto cuddZddLinearAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + moveDown = cuddZddLinearDown(table, x, xHigh, NULL); + /* At this point x --> xHigh. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + moveUp = cuddZddUndoMoves(table,moveDown); +#ifdef DD_DEBUG + assert(moveUp == NULL || moveUp->x == x); +#endif + moveUp = cuddZddLinearUp(table, x, xLow, moveUp); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveUp); + if (!result) + goto cuddZddLinearAuxOutOfMem; + + } else { + moveUp = cuddZddLinearUp(table, x, xLow, NULL); + /* At this point x --> xHigh. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Then move up. */ + moveDown = cuddZddUndoMoves(table,moveUp); +#ifdef DD_DEBUG + assert(moveDown == NULL || moveDown->y == x); +#endif + moveDown = cuddZddLinearDown(table, x, xHigh, moveDown); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveDown); + if (!result) + goto cuddZddLinearAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +cuddZddLinearAuxOutOfMem: + if (moveDown != (Move *) CUDD_OUT_OF_MEM) { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + } + if (moveUp != (Move *) CUDD_OUT_OF_MEM) { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + } + + return(0); + +} /* end of cuddZddLinearAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable up applying the XOR transformation.] + + Description [Sifts a variable up applying the XOR + transformation. Moves y up until either it reaches the bound (xLow) + or the size of the ZDD heap increases too much. Returns the set of + moves in case of success; NULL if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddLinearUp( + DdManager * table, + int y, + int xLow, + Move * prevMoves) +{ + Move *moves; + Move *move; + int x; + int size, newsize; + int limitSize; + + moves = prevMoves; + limitSize = table->keysZ; + + x = cuddZddNextLow(table, y); + while (x >= xLow) { + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddLinearUpOutOfMem; + newsize = cuddZddLinearInPlace(table, x, y); + if (newsize == 0) + goto cuddZddLinearUpOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddLinearUpOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize > size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddZddLinearInPlace(table,x,y); + if (newsize == 0) goto cuddZddLinearUpOutOfMem; +#ifdef DD_DEBUG + if (newsize != size) { + (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } +#endif + } else { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + } + move->size = size; + + if ((double)size > (double)limitSize * table->maxGrowth) + break; + if (size < limitSize) + limitSize = size; + + y = x; + x = cuddZddNextLow(table, y); + } + return(moves); + +cuddZddLinearUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of cuddZddLinearUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable down and applies the XOR transformation.] + + Description [Sifts a variable down. Moves x down until either it + reaches the bound (xHigh) or the size of the ZDD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddLinearDown( + DdManager * table, + int x, + int xHigh, + Move * prevMoves) +{ + Move *moves; + Move *move; + int y; + int size, newsize; + int limitSize; + + moves = prevMoves; + limitSize = table->keysZ; + + y = cuddZddNextHigh(table, x); + while (y <= xHigh) { + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddLinearDownOutOfMem; + newsize = cuddZddLinearInPlace(table, x, y); + if (newsize == 0) + goto cuddZddLinearDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddLinearDownOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize > size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddZddLinearInPlace(table,x,y); + if (newsize == 0) goto cuddZddLinearDownOutOfMem; + if (newsize != size) { + (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } + } else { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + } + move->size = size; + + if ((double)size > (double)limitSize * table->maxGrowth) + break; + if (size < limitSize) + limitSize = size; + + x = y; + y = cuddZddNextHigh(table, x); + } + return(moves); + +cuddZddLinearDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of cuddZddLinearDown */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the ZDD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddLinearBackward( + DdManager * table, + int size, + Move * moves) +{ + Move *move; + int res; + + /* Find the minimum size among moves. */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) + return(0); + if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { + res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + } + + return(1); + +} /* end of cuddZddLinearBackward */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the ZDD heap to the order + in effect before the moves.] + + Description [Given a set of moves, returns the ZDD heap to the + order in effect before the moves. Returns 1 in case of success; + 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static Move* +cuddZddUndoMoves( + DdManager * table, + Move * moves) +{ + Move *invmoves = NULL; + Move *move; + Move *invmove; + int size; + + for (move = moves; move != NULL; move = move->next) { + invmove = (Move *) cuddDynamicAllocNode(table); + if (invmove == NULL) goto cuddZddUndoMovesOutOfMem; + invmove->x = move->x; + invmove->y = move->y; + invmove->next = invmoves; + invmoves = invmove; + if (move->flags == CUDD_SWAP_MOVE) { + invmove->flags = CUDD_SWAP_MOVE; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; + size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ +#ifdef DD_DEBUG + (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); +#endif + invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } + invmove->size = size; + } + + return(invmoves); + +cuddZddUndoMovesOutOfMem: + while (invmoves != NULL) { + move = invmoves->next; + cuddDeallocMove(table, invmoves); + invmoves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of cuddZddUndoMoves */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddMisc.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddMisc.c new file mode 100644 index 000000000..ec7686276 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddMisc.c @@ -0,0 +1,278 @@ +/**CFile*********************************************************************** + + FileName [cuddZddMisc.c] + + PackageName [cudd] + + Synopsis [Miscellaneous utility functions for ZDDs.] + + Description [External procedures included in this module: +
                  +
                • Cudd_zddDagSize() +
                • Cudd_zddCountMinterm() +
                • Cudd_zddPrintSubtable() +
                + Internal procedures included in this module: +
                  +
                + Static procedures included in this module: +
                  +
                • cuddZddDagInt() +
                + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddMisc.c,v 1.18 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddZddDagInt (DdNode *n, st_table *tab); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Counts the number of nodes in a ZDD.] + + Description [Counts the number of nodes in a ZDD. This function + duplicates Cudd_DagSize and is only retained for compatibility.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize] + +******************************************************************************/ +int +Cudd_zddDagSize( + DdNode * p_node) +{ + + int i; + st_table *table; + + table = st_init_table(st_ptrcmp, st_ptrhash); + i = cuddZddDagInt(p_node, table); + st_free_table(table); + return(i); + +} /* end of Cudd_zddDagSize */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a ZDD.] + + Description [Counts the number of minterms of the ZDD rooted at + node. This procedure takes a parameter + path that specifies how many variables are in the + support of the function. If the procedure runs out of memory, it + returns (double) CUDD_OUT_OF_MEM.] + + SideEffects [None] + + SeeAlso [Cudd_zddCountDouble] + +******************************************************************************/ +double +Cudd_zddCountMinterm( + DdManager * zdd, + DdNode * node, + int path) +{ + double dc_var, minterms; + + dc_var = (double)((double)(zdd->sizeZ) - (double)path); + minterms = Cudd_zddCountDouble(zdd, node) / pow(2.0, dc_var); + return(minterms); + +} /* end of Cudd_zddCountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints the ZDD table.] + + Description [Prints the ZDD table for debugging purposes.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_zddPrintSubtable( + DdManager * table) +{ + int i, j; + DdNode *z1, *z1_next, *base; + DdSubtable *ZSubTable; + + base = table->one; + for (i = table->sizeZ - 1; i >= 0; i--) { + ZSubTable = &(table->subtableZ[i]); + printf("subtable[%d]:\n", i); + for (j = ZSubTable->slots - 1; j >= 0; j--) { + z1 = ZSubTable->nodelist[j]; + while (z1 != NIL(DdNode)) { + (void) fprintf(table->out, +#if SIZEOF_VOID_P == 8 + "ID = 0x%lx\tindex = %u\tr = %u\t", + (ptruint) z1 / (ptruint) sizeof(DdNode), + z1->index, z1->ref); +#else + "ID = 0x%x\tindex = %hu\tr = %hu\t", + (ptruint) z1 / (ptruint) sizeof(DdNode), + z1->index, z1->ref); +#endif + z1_next = cuddT(z1); + if (Cudd_IsConstant(z1_next)) { + (void) fprintf(table->out, "T = %d\t\t", + (z1_next == base)); + } + else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(table->out, "T = 0x%lx\t", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); +#else + (void) fprintf(table->out, "T = 0x%x\t", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); +#endif + } + z1_next = cuddE(z1); + if (Cudd_IsConstant(z1_next)) { + (void) fprintf(table->out, "E = %d\n", + (z1_next == base)); + } + else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(table->out, "E = 0x%lx\n", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); +#else + (void) fprintf(table->out, "E = 0x%x\n", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); +#endif + } + + z1_next = z1->next; + z1 = z1_next; + } + } + } + putchar('\n'); + +} /* Cudd_zddPrintSubtable */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddDagSize.] + + Description [Performs the recursive step of Cudd_zddDagSize. Does + not check for out-of-memory conditions.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddDagInt( + DdNode * n, + st_table * tab) +{ + if (n == NIL(DdNode)) + return(0); + + if (st_is_member(tab, (char *)n) == 1) + return(0); + + if (Cudd_IsConstant(n)) + return(0); + + (void)st_insert(tab, (char *)n, NIL(char)); + return(1 + cuddZddDagInt(cuddT(n), tab) + + cuddZddDagInt(cuddE(n), tab)); + +} /* cuddZddDagInt */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddPort.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddPort.c new file mode 100644 index 000000000..c661c6a88 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddPort.c @@ -0,0 +1,381 @@ +/**CFile*********************************************************************** + + FileName [cuddZddPort.c] + + PackageName [cudd] + + Synopsis [Functions that translate BDDs to ZDDs.] + + Description [External procedures included in this module: +
                  +
                • Cudd_zddPortFromBdd() +
                • Cudd_zddPortToBdd() +
                + Internal procedures included in this module: +
                  +
                + Static procedures included in this module: +
                  +
                • zddPortFromBddStep() +
                • zddPortToBddStep() +
                + ] + + SeeAlso [] + + Author [Hyong-kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddPort.c,v 1.14 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * zddPortFromBddStep (DdManager *dd, DdNode *B, int expected); +static DdNode * zddPortToBddStep (DdManager *dd, DdNode *f, int depth); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Converts a BDD into a ZDD.] + + Description [Converts a BDD into a ZDD. This function assumes that + there is a one-to-one correspondence between the BDD variables and the + ZDD variables, and that the variable order is the same for both types + of variables. These conditions are established if the ZDD variables + are created by one call to Cudd_zddVarsFromBddVars with multiplicity = + 1. Returns a pointer to the resulting ZDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddVarsFromBddVars] + +******************************************************************************/ +DdNode * +Cudd_zddPortFromBdd( + DdManager * dd, + DdNode * B) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = zddPortFromBddStep(dd,B,0); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_zddPortFromBdd */ + + +/**Function******************************************************************** + + Synopsis [Converts a ZDD into a BDD.] + + Description [Converts a ZDD into a BDD. Returns a pointer to the resulting + ZDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddPortFromBdd] + +******************************************************************************/ +DdNode * +Cudd_zddPortToBdd( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = zddPortToBddStep(dd,f,0); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_zddPortToBdd */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddPortFromBdd.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +zddPortFromBddStep( + DdManager * dd, + DdNode * B, + int expected) +{ + DdNode *res, *prevZdd, *t, *e; + DdNode *Breg, *Bt, *Be; + int id, level; + + statLine(dd); + /* Terminal cases. */ + if (B == Cudd_Not(DD_ONE(dd))) + return(DD_ZERO(dd)); + if (B == DD_ONE(dd)) { + if (expected >= dd->sizeZ) { + return(DD_ONE(dd)); + } else { + return(dd->univ[expected]); + } + } + + Breg = Cudd_Regular(B); + + /* Computed table look-up. */ + res = cuddCacheLookup1Zdd(dd,Cudd_zddPortFromBdd,B); + if (res != NULL) { + level = cuddI(dd,Breg->index); + /* Adding DC vars. */ + if (expected < level) { + /* Add suppressed variables. */ + cuddRef(res); + for (level--; level >= expected; level--) { + prevZdd = res; + id = dd->invperm[level]; + res = cuddZddGetNode(dd, id, prevZdd, prevZdd); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd, prevZdd); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd, prevZdd); + } + cuddDeref(res); + } + return(res); + } /* end of cache look-up */ + + if (Cudd_IsComplement(B)) { + Bt = Cudd_Not(cuddT(Breg)); + Be = Cudd_Not(cuddE(Breg)); + } else { + Bt = cuddT(Breg); + Be = cuddE(Breg); + } + + id = Breg->index; + level = cuddI(dd,id); + t = zddPortFromBddStep(dd, Bt, level+1); + if (t == NULL) return(NULL); + cuddRef(t); + e = zddPortFromBddStep(dd, Be, level+1); + if (e == NULL) { + Cudd_RecursiveDerefZdd(dd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(dd, id, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd, t); + Cudd_RecursiveDerefZdd(dd, e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd, t); + Cudd_RecursiveDerefZdd(dd, e); + + cuddCacheInsert1(dd,Cudd_zddPortFromBdd,B,res); + + for (level--; level >= expected; level--) { + prevZdd = res; + id = dd->invperm[level]; + res = cuddZddGetNode(dd, id, prevZdd, prevZdd); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd, prevZdd); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd, prevZdd); + } + + cuddDeref(res); + return(res); + +} /* end of zddPortFromBddStep */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddPortToBdd.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +zddPortToBddStep( + DdManager * dd /* manager */, + DdNode * f /* ZDD to be converted */, + int depth /* recursion depth */) +{ + DdNode *one, *zero, *T, *E, *res, *var; + unsigned int index; + unsigned int level; + + statLine(dd); + one = DD_ONE(dd); + zero = DD_ZERO(dd); + if (f == zero) return(Cudd_Not(one)); + + if (depth == dd->sizeZ) return(one); + + index = dd->invpermZ[depth]; + level = cuddIZ(dd,f->index); + var = cuddUniqueInter(dd,index,one,Cudd_Not(one)); + if (var == NULL) return(NULL); + cuddRef(var); + + if (level > (unsigned) depth) { + E = zddPortToBddStep(dd,f,depth+1); + if (E == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(E); + res = cuddBddIteRecur(dd,var,Cudd_Not(one),E); + if (res == NULL) { + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,E); + cuddDeref(res); + return(res); + } + + res = cuddCacheLookup1(dd,Cudd_zddPortToBdd,f); + if (res != NULL) { + Cudd_RecursiveDeref(dd,var); + return(res); + } + + T = zddPortToBddStep(dd,cuddT(f),depth+1); + if (T == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(T); + E = zddPortToBddStep(dd,cuddE(f),depth+1); + if (E == NULL) { + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + + res = cuddBddIteRecur(dd,var,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + cuddDeref(res); + + cuddCacheInsert1(dd,Cudd_zddPortToBdd,f,res); + + return(res); + +} /* end of zddPortToBddStep */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddReord.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddReord.c new file mode 100644 index 000000000..c4b67bf84 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddReord.c @@ -0,0 +1,1664 @@ +/**CFile*********************************************************************** + + FileName [cuddZddReord.c] + + PackageName [cudd] + + Synopsis [Procedures for dynamic variable ordering of ZDDs.] + + Description [External procedures included in this module: +
                  +
                • Cudd_zddReduceHeap() +
                • Cudd_zddShuffleHeap() +
                + Internal procedures included in this module: +
                  +
                • cuddZddAlignToBdd() +
                • cuddZddNextHigh() +
                • cuddZddNextLow() +
                • cuddZddUniqueCompare() +
                • cuddZddSwapInPlace() +
                • cuddZddSwapping() +
                • cuddZddSifting() +
                + Static procedures included in this module: +
                  +
                • zddSwapAny() +
                • cuddZddSiftingAux() +
                • cuddZddSiftingUp() +
                • cuddZddSiftingDown() +
                • cuddZddSiftingBackward() +
                • zddReorderPreprocess() +
                • zddReorderPostprocess() +
                • zddShuffle() +
                • zddSiftUp() +
                + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_MAX_SUBTABLE_SPARSITY 8 +#define DD_SHRINK_FACTOR 2 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddReord.c,v 1.49 2012/02/05 01:07:19 fabio Exp $"; +#endif + +int *zdd_entry; + +int zddTotalNumberSwapping; + +static DdNode *empty; + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static Move * zddSwapAny (DdManager *table, int x, int y); +static int cuddZddSiftingAux (DdManager *table, int x, int x_low, int x_high); +static Move * cuddZddSiftingUp (DdManager *table, int x, int x_low, int initial_size); +static Move * cuddZddSiftingDown (DdManager *table, int x, int x_high, int initial_size); +static int cuddZddSiftingBackward (DdManager *table, Move *moves, int size); +static void zddReorderPreprocess (DdManager *table); +static int zddReorderPostprocess (DdManager *table); +static int zddShuffle (DdManager *table, int *permutation); +static int zddSiftUp (DdManager *table, int x, int xLow); +static void zddFixTree (DdManager *table, MtrNode *treenode); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Main dynamic reordering routine for ZDDs.] + + Description [Main dynamic reordering routine for ZDDs. + Calls one of the possible reordering procedures: +
                  +
                • Swapping +
                • Sifting +
                • Symmetric Sifting +
                + + For sifting and symmetric sifting it is possible to request reordering + to convergence.

                + + The core of all methods is the reordering procedure + cuddZddSwapInPlace() which swaps two adjacent variables. + Returns 1 in case of success; 0 otherwise. In the case of symmetric + sifting (with and without convergence) returns 1 plus the number of + symmetric variables, in case of success.] + + SideEffects [Changes the variable order for all ZDDs and clears + the cache.] + +******************************************************************************/ +int +Cudd_zddReduceHeap( + DdManager * table /* DD manager */, + Cudd_ReorderingType heuristic /* method used for reordering */, + int minsize /* bound below which no reordering occurs */) +{ + DdHook *hook; + int result; + unsigned int nextDyn; +#ifdef DD_STATS + unsigned int initialSize; + unsigned int finalSize; +#endif + unsigned long localTime; + + /* Don't reorder if there are too many dead nodes. */ + if (table->keysZ - table->deadZ < (unsigned) minsize) + return(1); + + if (heuristic == CUDD_REORDER_SAME) { + heuristic = table->autoMethodZ; + } + if (heuristic == CUDD_REORDER_NONE) { + return(1); + } + + /* This call to Cudd_zddReduceHeap does initiate reordering. Therefore + ** we count it. + */ + table->reorderings++; + empty = table->zero; + + localTime = util_cpu_time(); + + /* Run the hook functions. */ + hook = table->preReorderingHook; + while (hook != NULL) { + int res = (hook->f)(table, "ZDD", (void *)heuristic); + if (res == 0) return(0); + hook = hook->next; + } + + /* Clear the cache and collect garbage. */ + zddReorderPreprocess(table); + zddTotalNumberSwapping = 0; + +#ifdef DD_STATS + initialSize = table->keysZ; + + switch(heuristic) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + (void) fprintf(table->out,"#:I_RANDOM "); + break; + case CUDD_REORDER_SIFT: + case CUDD_REORDER_SIFT_CONVERGE: + case CUDD_REORDER_SYMM_SIFT: + case CUDD_REORDER_SYMM_SIFT_CONV: + (void) fprintf(table->out,"#:I_SIFTING "); + break; + case CUDD_REORDER_LINEAR: + case CUDD_REORDER_LINEAR_CONVERGE: + (void) fprintf(table->out,"#:I_LINSIFT "); + break; + default: + (void) fprintf(table->err,"Unsupported ZDD reordering method\n"); + return(0); + } + (void) fprintf(table->out,"%8d: initial size",initialSize); +#endif + + result = cuddZddTreeSifting(table,heuristic); + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + finalSize = table->keysZ; + (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n", + ((double)(util_cpu_time() - localTime)/1000.0)); + (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n", + zddTotalNumberSwapping); +#endif + + if (result == 0) + return(0); + + if (!zddReorderPostprocess(table)) + return(0); + + if (table->realignZ) { + if (!cuddBddAlignToZdd(table)) + return(0); + } + + nextDyn = table->keysZ * DD_DYN_RATIO; + if (table->reorderings < 20 || nextDyn > table->nextDyn) + table->nextDyn = nextDyn; + else + table->nextDyn += 20; + + table->reordered = 1; + + /* Run hook functions. */ + hook = table->postReorderingHook; + while (hook != NULL) { + int res = (hook->f)(table, "ZDD", (void *)localTime); + if (res == 0) return(0); + hook = hook->next; + } + /* Update cumulative reordering time. */ + table->reordTime += util_cpu_time() - localTime; + + return(result); + +} /* end of Cudd_zddReduceHeap */ + + +/**Function******************************************************************** + + Synopsis [Reorders ZDD variables according to given permutation.] + + Description [Reorders ZDD variables according to given permutation. + The i-th entry of the permutation array contains the index of the variable + that should be brought to the i-th level. The size of the array should be + equal or greater to the number of variables currently in use. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [Changes the ZDD variable order for all diagrams and clears + the cache.] + + SeeAlso [Cudd_zddReduceHeap] + +******************************************************************************/ +int +Cudd_zddShuffleHeap( + DdManager * table /* DD manager */, + int * permutation /* required variable permutation */) +{ + + int result; + + empty = table->zero; + zddReorderPreprocess(table); + + result = zddShuffle(table,permutation); + + if (!zddReorderPostprocess(table)) return(0); + + return(result); + +} /* end of Cudd_zddShuffleHeap */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Reorders ZDD variables according to the order of the BDD + variables.] + + Description [Reorders ZDD variables according to the order of the + BDD variables. This function can be called at the end of BDD + reordering to insure that the order of the ZDD variables is + consistent with the order of the BDD variables. The number of ZDD + variables must be a multiple of the number of BDD variables. Let + M be the ratio of the two numbers. cuddZddAlignToBdd + then considers the ZDD variables from M*i to + (M+1)*i-1 as corresponding to BDD variable + i. This function should be normally called from + Cudd_ReduceHeap, which clears the cache. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [Changes the ZDD variable order for all diagrams and performs + garbage collection of the ZDD unique table.] + + SeeAlso [Cudd_zddShuffleHeap Cudd_ReduceHeap] + +******************************************************************************/ +int +cuddZddAlignToBdd( + DdManager * table /* DD manager */) +{ + int *invpermZ; /* permutation array */ + int M; /* ratio of ZDD variables to BDD variables */ + int i,j; /* loop indices */ + int result; /* return value */ + + /* We assume that a ratio of 0 is OK. */ + if (table->sizeZ == 0) + return(1); + + empty = table->zero; + M = table->sizeZ / table->size; + /* Check whether the number of ZDD variables is a multiple of the + ** number of BDD variables. + */ + if (M * table->size != table->sizeZ) + return(0); + /* Create and initialize the inverse permutation array. */ + invpermZ = ALLOC(int,table->sizeZ); + if (invpermZ == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < table->size; i++) { + int index = table->invperm[i]; + int indexZ = index * M; + int levelZ = table->permZ[indexZ]; + levelZ = (levelZ / M) * M; + for (j = 0; j < M; j++) { + invpermZ[M * i + j] = table->invpermZ[levelZ + j]; + } + } + /* Eliminate dead nodes. Do not scan the cache again, because we + ** assume that Cudd_ReduceHeap has already cleared it. + */ + cuddGarbageCollect(table,0); + + result = zddShuffle(table, invpermZ); + FREE(invpermZ); + /* Fix the ZDD variable group tree. */ + zddFixTree(table,table->treeZ); + return(result); + +} /* end of cuddZddAlignToBdd */ + + +/**Function******************************************************************** + + Synopsis [Finds the next subtable with a larger index.] + + Description [Finds the next subtable with a larger index. Returns the + index.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddNextHigh( + DdManager * table, + int x) +{ + return(x + 1); + +} /* end of cuddZddNextHigh */ + + +/**Function******************************************************************** + + Synopsis [Finds the next subtable with a smaller index.] + + Description [Finds the next subtable with a smaller index. Returns the + index.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddNextLow( + DdManager * table, + int x) +{ + return(x - 1); + +} /* end of cuddZddNextLow */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddUniqueCompare( + int * ptr_x, + int * ptr_y) +{ + return(zdd_entry[*ptr_y] - zdd_entry[*ptr_x]); + +} /* end of cuddZddUniqueCompare */ + + +/**Function******************************************************************** + + Synopsis [Swaps two adjacent variables.] + + Description [Swaps two adjacent variables. It assumes that no dead + nodes are present on entry to this procedure. The procedure then + guarantees that no dead nodes will be present when it terminates. + cuddZddSwapInPlace assumes that x < y. Returns the number of keys in + the table if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddSwapInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int i; + int posn; + DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; + DdNode *newf1, *newf0, *next; + DdNodePtr g, *lastP, *previousP; + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddZddNextHigh(table,x) == y); + assert(table->subtableZ[x].keys != 0); + assert(table->subtableZ[y].keys != 0); + assert(table->subtableZ[x].dead == 0); + assert(table->subtableZ[y].dead == 0); +#endif + + zddTotalNumberSwapping++; + + /* Get parameters of x subtable. */ + xindex = table->invpermZ[x]; + xlist = table->subtableZ[x].nodelist; + oldxkeys = table->subtableZ[x].keys; + xslots = table->subtableZ[x].slots; + xshift = table->subtableZ[x].shift; + newxkeys = 0; + + yindex = table->invpermZ[y]; + ylist = table->subtableZ[y].nodelist; + oldykeys = table->subtableZ[y].keys; + yslots = table->subtableZ[y].slots; + yshift = table->subtableZ[y].shift; + newykeys = oldykeys; + + /* The nodes in the x layer that don't depend on y directly + ** will stay there; the others are put in a chain. + ** The chain is handled as a FIFO; g points to the beginning and + ** last points to the end. + */ + + g = NULL; + lastP = &g; + for (i = 0; i < xslots; i++) { + previousP = &(xlist[i]); + f = *previousP; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if ((f1->index != (DdHalfWord) yindex) && + (f0->index != (DdHalfWord) yindex)) { /* stays */ + newxkeys++; + *previousP = f; + previousP = &(f->next); + } else { + f->index = yindex; + *lastP = f; + lastP = &(f->next); + } + f = next; + } /* while there are elements in the collision chain */ + *previousP = NULL; + } /* for each slot of the x subtable */ + *lastP = NULL; + + +#ifdef DD_COUNT + table->swapSteps += oldxkeys - newxkeys; +#endif + /* Take care of the x nodes that must be re-expressed. + ** They form a linked list pointed by g. Their index has been + ** changed to yindex already. + */ + f = g; + while (f != NULL) { + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = empty; f10 = f1; + } + f0 = cuddE(f); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = empty; f00 = f0; + } + + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == empty) { + if (f01 != empty) { + newf1 = f01; + cuddSatInc(newf1->ref); + } + /* else case was already handled when finding nodes + ** with both children below level y + */ + } else { + /* Check xlist for triple (xindex, f11, f01). */ + posn = ddHash(f11, f01, xshift); + /* For each element newf1 in collision list xlist[posn]. */ + newf1 = xlist[posn]; + while (newf1 != NULL) { + if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = xindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f01; + /* Insert newf1 in the collision list xlist[pos]; + ** increase the ref counts of f11 and f01 + */ + newxkeys++; + newf1->next = xlist[posn]; + xlist[posn] = newf1; + cuddSatInc(f11->ref); + cuddSatInc(f01->ref); + } + } + cuddT(f) = newf1; + + /* Do the same for f0. */ + /* Decrease ref count of f0. */ + cuddSatDec(f0->ref); + /* Create the new E child. */ + if (f10 == empty) { + newf0 = f00; + cuddSatInc(newf0->ref); + } else { + /* Check xlist for triple (xindex, f10, f00). */ + posn = ddHash(f10, f00, xshift); + /* For each element newf0 in collision list xlist[posn]. */ + newf0 = xlist[posn]; + while (newf0 != NULL) { + if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { + cuddSatInc(newf0->ref); + break; /* match */ + } + newf0 = newf0->next; + } /* while newf0 */ + if (newf0 == NULL) { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto zddSwapOutOfMem; + newf0->index = xindex; newf0->ref = 1; + cuddT(newf0) = f10; cuddE(newf0) = f00; + /* Insert newf0 in the collision list xlist[posn]; + ** increase the ref counts of f10 and f00. + */ + newxkeys++; + newf0->next = xlist[posn]; + xlist[posn] = newf0; + cuddSatInc(f10->ref); + cuddSatInc(f00->ref); + } + } + cuddE(f) = newf0; + + /* Insert the modified f in ylist. + ** The modified f does not already exists in ylist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, yshift); + newykeys++; + f->next = ylist[posn]; + ylist[posn] = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previousP = &(ylist[i]); + f = *previousP; + while (f != NULL) { + next = f->next; + if (f->ref == 0) { + cuddSatDec(cuddT(f)->ref); + cuddSatDec(cuddE(f)->ref); + cuddDeallocNode(table, f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = NULL; + } /* for i */ + + /* Set the appropriate fields in table. */ + table->subtableZ[x].nodelist = ylist; + table->subtableZ[x].slots = yslots; + table->subtableZ[x].shift = yshift; + table->subtableZ[x].keys = newykeys; + table->subtableZ[x].maxKeys = yslots * DD_MAX_SUBTABLE_DENSITY; + + table->subtableZ[y].nodelist = xlist; + table->subtableZ[y].slots = xslots; + table->subtableZ[y].shift = xshift; + table->subtableZ[y].keys = newxkeys; + table->subtableZ[y].maxKeys = xslots * DD_MAX_SUBTABLE_DENSITY; + + table->permZ[xindex] = y; table->permZ[yindex] = x; + table->invpermZ[x] = yindex; table->invpermZ[y] = xindex; + + table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys; + + /* Update univ section; univ[x] remains the same. */ + table->univ[y] = cuddT(table->univ[x]); + + return (table->keysZ); + +zddSwapOutOfMem: + (void) fprintf(table->err, "Error: cuddZddSwapInPlace out of memory\n"); + + return (0); + +} /* end of cuddZddSwapInPlace */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables by a sequence of (non-adjacent) swaps.] + + Description [Implementation of Plessier's algorithm that reorders + variables by a sequence of (non-adjacent) swaps. +

                  +
                1. Select two variables (RANDOM or HEURISTIC). +
                2. Permute these variables. +
                3. If the nodes have decreased accept the permutation. +
                4. Otherwise reconstruct the original heap. +
                5. Loop. +
                + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddSwapping( + DdManager * table, + int lower, + int upper, + Cudd_ReorderingType heuristic) +{ + int i, j; + int max, keys; + int nvars; + int x, y; + int iterate; + int previousSize; + Move *moves, *move; + int pivot; + int modulo; + int result; + +#ifdef DD_DEBUG + /* Sanity check */ + assert(lower >= 0 && upper < table->sizeZ && lower <= upper); +#endif + + nvars = upper - lower + 1; + iterate = nvars; + + for (i = 0; i < iterate; i++) { + if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { + /* Find pivot <= id with maximum keys. */ + for (max = -1, j = lower; j <= upper; j++) { + if ((keys = table->subtableZ[j].keys) > max) { + max = keys; + pivot = j; + } + } + + modulo = upper - pivot; + if (modulo == 0) { + y = pivot; /* y = nvars-1 */ + } else { + /* y = random # from {pivot+1 .. nvars-1} */ + y = pivot + 1 + (int) (Cudd_Random() % modulo); + } + + modulo = pivot - lower - 1; + if (modulo < 1) { /* if pivot = 1 or 0 */ + x = lower; + } else { + do { /* x = random # from {0 .. pivot-2} */ + x = (int) Cudd_Random() % modulo; + } while (x == y); + /* Is this condition really needed, since x and y + are in regions separated by pivot? */ + } + } else { + x = (int) (Cudd_Random() % nvars) + lower; + do { + y = (int) (Cudd_Random() % nvars) + lower; + } while (x == y); + } + + previousSize = table->keysZ; + moves = zddSwapAny(table, x, y); + if (moves == NULL) + goto cuddZddSwappingOutOfMem; + + result = cuddZddSiftingBackward(table, moves, previousSize); + if (!result) + goto cuddZddSwappingOutOfMem; + + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + return(1); + +cuddZddSwappingOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(0); + +} /* end of cuddZddSwapping */ + + +/**Function******************************************************************** + + Synopsis [Implementation of Rudell's sifting algorithm.] + + Description [Implementation of Rudell's sifting algorithm. + Assumes that no dead nodes are present. +
                  +
                1. Order all the variables according to the number of entries + in each unique table. +
                2. Sift the variable up and down, remembering each time the + total size of the DD heap. +
                3. Select the best permutation. +
                4. Repeat 3 and 4 for all variables. +
                + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; +#ifdef DD_STATS + int previousSize; +#endif + + size = table->sizeZ; + + /* Find order in which to sift variables. */ + var = NULL; + zdd_entry = ALLOC(int, size); + if (zdd_entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; + } + var = ALLOC(int, size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; + } + + qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar, size); i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = cuddZddSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSiftingOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + FREE(var); + FREE(zdd_entry); + + return(1); + +cuddZddSiftingOutOfMem: + + if (zdd_entry != NULL) FREE(zdd_entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddZddSifting */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Swaps any two variables.] + + Description [Swaps any two variables. Returns the set of moves.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +zddSwapAny( + DdManager * table, + int x, + int y) +{ + Move *move, *moves; + int tmp, size; + int x_ref, y_ref; + int x_next, y_next; + int limit_size; + + if (x > y) { /* make x precede y */ + tmp = x; x = y; y = tmp; + } + + x_ref = x; y_ref = y; + + x_next = cuddZddNextHigh(table, x); + y_next = cuddZddNextLow(table, y); + moves = NULL; + limit_size = table->keysZ; + + for (;;) { + if (x_next == y_next) { /* x < x_next = y_next < y */ + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, y_next, y); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + + } else if (x == y_next) { /* x = y_next < y = x_next */ + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + } else { + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, y_next, y); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + x = x_next; y = y_next; + } + + x_next = cuddZddNextHigh(table, x); + y_next = cuddZddNextLow(table, y); + if (x_next > y_ref) + break; /* if x == y_ref */ + + if ((double) size > table->maxGrowth * (double) limit_size) + break; + if (size < limit_size) + limit_size = size; + } + if (y_next >= x_ref) { + size = cuddZddSwapInPlace(table, y_next, y); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + } + + return(moves); + +zddSwapAnyOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of zddSwapAny */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSiftingAux( + DdManager * table, + int x, + int x_low, + int x_high) +{ + Move *move; + Move *moveUp; /* list of up move */ + Move *moveDown; /* list of down move */ + + int initial_size; + int result; + + initial_size = table->keysZ; + +#ifdef DD_DEBUG + assert(table->subtableZ[x].keys > 0); +#endif + + moveDown = NULL; + moveUp = NULL; + + if (x == x_low) { + moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); + /* after that point x --> x_high */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveDown, + initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; + + } + else if (x == x_high) { + moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); + /* after that point x --> x_low */ + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveUp, initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; + } + else if ((x - x_low) > (x_high - x)) { + /* must go down first:shorter */ + moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); + /* after that point x --> x_high */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + moveUp = cuddZddSiftingUp(table, moveDown->y, x_low, + initial_size); + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveUp, initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; + } + else { + moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); + /* after that point x --> x_high */ + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + moveDown = cuddZddSiftingDown(table, moveUp->x, x_high, + initial_size); + /* then move up */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveDown, + initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +cuddZddSiftingAuxOutOfMem: + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(0); + +} /* end of cuddZddSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable up.] + + Description [Sifts a variable up. Moves y up until either it reaches + the bound (x_low) or the size of the ZDD heap increases too much. + Returns the set of moves in case of success; NULL if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddSiftingUp( + DdManager * table, + int x, + int x_low, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddZddNextLow(table, x); + while (y >= x_low) { + size = cuddZddSwapInPlace(table, y, x); + if (size == 0) + goto cuddZddSiftingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSiftingUpOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + + if ((double)size > (double)limit_size * table->maxGrowth) + break; + if (size < limit_size) + limit_size = size; + + x = y; + y = cuddZddNextLow(table, x); + } + return(moves); + +cuddZddSiftingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of cuddZddSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable down.] + + Description [Sifts a variable down. Moves x down until either it + reaches the bound (x_high) or the size of the ZDD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddSiftingDown( + DdManager * table, + int x, + int x_high, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddZddNextHigh(table, x); + while (y <= x_high) { + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddSiftingDownOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + if ((double)size > (double)limit_size * table->maxGrowth) + break; + if (size < limit_size) + limit_size = size; + + x = y; + y = cuddZddNextHigh(table, x); + } + return(moves); + +cuddZddSiftingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of cuddZddSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the ZDD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSiftingBackward( + DdManager * table, + Move * moves, + int size) +{ + int i; + int i_best; + Move *move; + int res; + + /* Find the minimum size among moves. */ + i_best = -1; + for (move = moves, i = 0; move != NULL; move = move->next, i++) { + if (move->size < size) { + i_best = i; + size = move->size; + } + } + + for (move = moves, i = 0; move != NULL; move = move->next, i++) { + if (i == i_best) + break; + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) + return(0); + if (i_best == -1 && res == size) + break; + } + + return(1); + +} /* end of cuddZddSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Prepares the ZDD heap for dynamic reordering.] + + Description [Prepares the ZDD heap for dynamic reordering. Does + garbage collection, to guarantee that there are no dead nodes; + and clears the cache, which is invalidated by dynamic reordering.] + + SideEffects [None] + +******************************************************************************/ +static void +zddReorderPreprocess( + DdManager * table) +{ + + /* Clear the cache. */ + cuddCacheFlush(table); + + /* Eliminate dead nodes. Do not scan the cache again. */ + cuddGarbageCollect(table,0); + + return; + +} /* end of ddReorderPreprocess */ + + +/**Function******************************************************************** + + Synopsis [Shrinks almost empty ZDD subtables at the end of reordering + to guarantee that they have a reasonable load factor.] + + Description [Shrinks almost empty subtables at the end of reordering to + guarantee that they have a reasonable load factor. However, if there many + nodes are being reclaimed, then no resizing occurs. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddReorderPostprocess( + DdManager * table) +{ + int i, j, posn; + DdNodePtr *nodelist, *oldnodelist; + DdNode *node, *next; + unsigned int slots, oldslots; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + +#ifdef DD_VERBOSE + (void) fflush(table->out); +#endif + + /* If we have very many reclaimed nodes, we do not want to shrink + ** the subtables, because this will lead to more garbage + ** collections. More garbage collections mean shorter mean life for + ** nodes with zero reference count; hence lower probability of finding + ** a result in the cache. + */ + if (table->reclaimed > table->allocated * 0.5) return(1); + + /* Resize subtables. */ + for (i = 0; i < table->sizeZ; i++) { + int shift; + oldslots = table->subtableZ[i].slots; + if (oldslots < table->subtableZ[i].keys * DD_MAX_SUBTABLE_SPARSITY || + oldslots <= table->initSlots) continue; + oldnodelist = table->subtableZ[i].nodelist; + slots = oldslots >> 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + return(1); + } + table->subtableZ[i].nodelist = nodelist; + table->subtableZ[i].slots = slots; + table->subtableZ[i].shift++; + table->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; +#ifdef DD_VERBOSE + (void) fprintf(table->err, + "shrunk layer %d (%d keys) from %d to %d slots\n", + i, table->subtableZ[i].keys, oldslots, slots); +#endif + + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + shift = table->subtableZ[i].shift; + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + posn = ddHash(cuddT(node), cuddE(node), shift); + node->next = nodelist[posn]; + nodelist[posn] = node; + node = next; + } + } + FREE(oldnodelist); + + table->memused += (slots - oldslots) * sizeof(DdNode *); + table->slots += slots - oldslots; + table->minDead = (unsigned) (table->gcFrac * (double) table->slots); + table->cacheSlack = (int) ddMin(table->maxCacheHard, + DD_MAX_CACHE_TO_SLOTS_RATIO*table->slots) - + 2 * (int) table->cacheSlots; + } + /* We don't look at the constant subtable, because it is not + ** affected by reordering. + */ + + return(1); + +} /* end of zddReorderPostprocess */ + + +/**Function******************************************************************** + + Synopsis [Reorders ZDD variables according to a given permutation.] + + Description [Reorders ZDD variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. zddShuffle assumes that no + dead nodes are present. The reordering is achieved by a series of + upward sifts. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zddShuffle( + DdManager * table, + int * permutation) +{ + int index; + int level; + int position; + int numvars; + int result; +#ifdef DD_STATS + unsigned long localTime; + int initialSize; + int finalSize; + int previousSize; +#endif + + zddTotalNumberSwapping = 0; +#ifdef DD_STATS + localTime = util_cpu_time(); + initialSize = table->keysZ; + (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n", + initialSize); +#endif + + numvars = table->sizeZ; + + for (level = 0; level < numvars; level++) { + index = permutation[level]; + position = table->permZ[index]; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = zddSiftUp(table,position,level); + if (!result) return(0); +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + finalSize = table->keysZ; + (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:T_SHUFFLE %8g: total time (sec)\n", + ((double)(util_cpu_time() - localTime)/1000.0)); + (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n", + zddTotalNumberSwapping); +#endif + + return(1); + +} /* end of zddShuffle */ + + +/**Function******************************************************************** + + Synopsis [Moves one ZDD variable up.] + + Description [Takes a ZDD variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zddSiftUp( + DdManager * table, + int x, + int xLow) +{ + int y; + int size; + + y = cuddZddNextLow(table,x); + while (y >= xLow) { + size = cuddZddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddZddNextLow(table,x); + } + return(1); + +} /* end of zddSiftUp */ + + +/**Function******************************************************************** + + Synopsis [Fixes the ZDD variable group tree after a shuffle.] + + Description [Fixes the ZDD variable group tree after a + shuffle. Assumes that the order of the variables in a terminal node + has not been changed.] + + SideEffects [Changes the ZDD variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static void +zddFixTree( + DdManager * table, + MtrNode * treenode) +{ + if (treenode == NULL) return; + treenode->low = ((int) treenode->index < table->sizeZ) ? + table->permZ[treenode->index] : treenode->index; + if (treenode->child != NULL) { + zddFixTree(table, treenode->child); + } + if (treenode->younger != NULL) + zddFixTree(table, treenode->younger); + if (treenode->parent != NULL && treenode->low < treenode->parent->low) { + treenode->parent->low = treenode->low; + treenode->parent->index = treenode->index; + } + return; + +} /* end of zddFixTree */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddSetop.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddSetop.c new file mode 100644 index 000000000..18cce2c92 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddSetop.c @@ -0,0 +1,1166 @@ +/**CFile*********************************************************************** + + FileName [cuddZddSetop.c] + + PackageName [cudd] + + Synopsis [Set operations on ZDDs.] + + Description [External procedures included in this module: +
                  +
                • Cudd_zddIte() +
                • Cudd_zddUnion() +
                • Cudd_zddIntersect() +
                • Cudd_zddDiff() +
                • Cudd_zddDiffConst() +
                • Cudd_zddSubset1() +
                • Cudd_zddSubset0() +
                • Cudd_zddChange() +
                + Internal procedures included in this module: +
                  +
                • cuddZddIte() +
                • cuddZddUnion() +
                • cuddZddIntersect() +
                • cuddZddDiff() +
                • cuddZddChangeAux() +
                • cuddZddSubset1() +
                • cuddZddSubset0() +
                + Static procedures included in this module: +
                  +
                • zdd_subset1_aux() +
                • zdd_subset0_aux() +
                • zddVarToConst() +
                + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddSetop.c,v 1.26 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * zdd_subset1_aux (DdManager *zdd, DdNode *P, DdNode *zvar); +static DdNode * zdd_subset0_aux (DdManager *zdd, DdNode *P, DdNode *zvar); +static void zddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *base, DdNode *empty); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the ITE of three ZDDs.] + + Description [Computes the ITE of three ZDDs. Returns a pointer to the + result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddIte(dd, f, g, h); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddIte */ + + +/**Function******************************************************************** + + Synopsis [Computes the union of two ZDDs.] + + Description [Computes the union of two ZDDs. Returns a pointer to the + result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddUnion( + DdManager * dd, + DdNode * P, + DdNode * Q) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddUnion(dd, P, Q); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddUnion */ + + +/**Function******************************************************************** + + Synopsis [Computes the intersection of two ZDDs.] + + Description [Computes the intersection of two ZDDs. Returns a pointer to + the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddIntersect( + DdManager * dd, + DdNode * P, + DdNode * Q) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddIntersect(dd, P, Q); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddIntersect */ + + +/**Function******************************************************************** + + Synopsis [Computes the difference of two ZDDs.] + + Description [Computes the difference of two ZDDs. Returns a pointer to the + result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddDiffConst] + +******************************************************************************/ +DdNode * +Cudd_zddDiff( + DdManager * dd, + DdNode * P, + DdNode * Q) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddDiff(dd, P, Q); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddDiff */ + + +/**Function******************************************************************** + + Synopsis [Performs the inclusion test for ZDDs (P implies Q).] + + Description [Inclusion test for ZDDs (P implies Q). No new nodes are + generated by this procedure. Returns empty if true; + a valid pointer different from empty or DD_NON_CONSTANT otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddDiff] + +******************************************************************************/ +DdNode * +Cudd_zddDiffConst( + DdManager * zdd, + DdNode * P, + DdNode * Q) +{ + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *res; + DdManager *table = zdd; + + statLine(zdd); + if (P == empty) + return(empty); + if (Q == empty) + return(P); + if (P == Q) + return(empty); + + /* Check cache. The cache is shared by cuddZddDiff(). */ + res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) + p_top = P->index; + else + p_top = zdd->permZ[P->index]; + if (cuddIsConstant(Q)) + q_top = Q->index; + else + q_top = zdd->permZ[Q->index]; + if (p_top < q_top) { + res = DD_NON_CONSTANT; + } else if (p_top > q_top) { + res = Cudd_zddDiffConst(zdd, P, cuddE(Q)); + } else { + t = Cudd_zddDiffConst(zdd, cuddT(P), cuddT(Q)); + if (t != empty) + res = DD_NON_CONSTANT; + else + res = Cudd_zddDiffConst(zdd, cuddE(P), cuddE(Q)); + } + + cuddCacheInsert2(table, cuddZddDiff, P, Q, res); + + return(res); + +} /* end of Cudd_zddDiffConst */ + + +/**Function******************************************************************** + + Synopsis [Computes the positive cofactor of a ZDD w.r.t. a variable.] + + Description [Computes the positive cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is asserted. Returns a pointer to + the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddSubset0] + +******************************************************************************/ +DdNode * +Cudd_zddSubset1( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *r; + + do { + dd->reordered = 0; + r = cuddZddSubset1(dd, P, var); + } while (dd->reordered == 1); + + return(r); + +} /* end of Cudd_zddSubset1 */ + + +/**Function******************************************************************** + + Synopsis [Computes the negative cofactor of a ZDD w.r.t. a variable.] + + Description [Computes the negative cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is negated. Returns a pointer to + the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddSubset1] + +******************************************************************************/ +DdNode * +Cudd_zddSubset0( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *r; + + do { + dd->reordered = 0; + r = cuddZddSubset0(dd, P, var); + } while (dd->reordered == 1); + + return(r); + +} /* end of Cudd_zddSubset0 */ + + +/**Function******************************************************************** + + Synopsis [Substitutes a variable with its complement in a ZDD.] + + Description [Substitutes a variable with its complement in a ZDD. + returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddChange( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *res; + + if ((unsigned int) var >= CUDD_MAXINDEX - 1) return(NULL); + + do { + dd->reordered = 0; + res = cuddZddChange(dd, P, var); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddChange */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddIte.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *tautology, *empty; + DdNode *r,*Gv,*Gvn,*Hv,*Hvn,*t,*e; + unsigned int topf,topg,toph,v,top; + int index; + + statLine(dd); + /* Trivial cases. */ + /* One variable cases. */ + if (f == (empty = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ + return(h); + } + topf = cuddIZ(dd,f->index); + topg = cuddIZ(dd,g->index); + toph = cuddIZ(dd,h->index); + v = ddMin(topg,toph); + top = ddMin(topf,v); + + tautology = (top == CUDD_MAXINDEX) ? DD_ONE(dd) : dd->univ[top]; + if (f == tautology) { /* ITE(1,G,H) = G */ + return(g); + } + + /* From now on, f is known to not be a constant. */ + zddVarToConst(f,&g,&h,tautology,empty); + + /* Check remaining one variable cases. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } + + if (g == tautology) { /* ITE(F,1,0) = F */ + if (h == empty) return(f); + } + + /* Check cache. */ + r = cuddCacheLookupZdd(dd,DD_ZDD_ITE_TAG,f,g,h); + if (r != NULL) { + return(r); + } + + /* Recompute these because they may have changed in zddVarToConst. */ + topg = cuddIZ(dd,g->index); + toph = cuddIZ(dd,h->index); + v = ddMin(topg,toph); + + if (topf < v) { + r = cuddZddIte(dd,cuddE(f),g,h); + if (r == NULL) return(NULL); + } else if (topf > v) { + if (topg > v) { + Gvn = g; + index = h->index; + } else { + Gvn = cuddE(g); + index = g->index; + } + if (toph > v) { + Hv = empty; Hvn = h; + } else { + Hv = cuddT(h); Hvn = cuddE(h); + } + e = cuddZddIte(dd,f,Gvn,Hvn); + if (e == NULL) return(NULL); + cuddRef(e); + r = cuddZddGetNode(dd,index,Hv,e); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + return(NULL); + } + cuddDeref(e); + } else { + index = f->index; + if (topg > v) { + Gv = empty; Gvn = g; + } else { + Gv = cuddT(g); Gvn = cuddE(g); + } + if (toph > v) { + Hv = empty; Hvn = h; + } else { + Hv = cuddT(h); Hvn = cuddE(h); + } + e = cuddZddIte(dd,cuddE(f),Gvn,Hvn); + if (e == NULL) return(NULL); + cuddRef(e); + t = cuddZddIte(dd,cuddT(f),Gv,Hv); + if (t == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + return(NULL); + } + cuddRef(t); + r = cuddZddGetNode(dd,index,t,e); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + Cudd_RecursiveDerefZdd(dd,t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert(dd,DD_ZDD_ITE_TAG,f,g,h,r); + + return(r); + +} /* end of cuddZddIte */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddUnion.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddUnion( + DdManager * zdd, + DdNode * P, + DdNode * Q) +{ + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; + + statLine(zdd); + if (P == empty) + return(Q); + if (Q == empty) + return(P); + if (P == Q) + return(P); + + /* Check cache */ + res = cuddCacheLookup2Zdd(table, cuddZddUnion, P, Q); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) + p_top = P->index; + else + p_top = zdd->permZ[P->index]; + if (cuddIsConstant(Q)) + q_top = Q->index; + else + q_top = zdd->permZ[Q->index]; + if (p_top < q_top) { + e = cuddZddUnion(zdd, cuddE(P), Q); + if (e == NULL) return (NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, cuddT(P), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); + } else if (p_top > q_top) { + e = cuddZddUnion(zdd, P, cuddE(Q)); + if (e == NULL) return(NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, Q->index, cuddT(Q), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); + } else { + t = cuddZddUnion(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddUnion(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(table, cuddZddUnion, P, Q, res); + + return(res); + +} /* end of cuddZddUnion */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddIntersect.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddIntersect( + DdManager * zdd, + DdNode * P, + DdNode * Q) +{ + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; + + statLine(zdd); + if (P == empty) + return(empty); + if (Q == empty) + return(empty); + if (P == Q) + return(P); + + /* Check cache. */ + res = cuddCacheLookup2Zdd(table, cuddZddIntersect, P, Q); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) + p_top = P->index; + else + p_top = zdd->permZ[P->index]; + if (cuddIsConstant(Q)) + q_top = Q->index; + else + q_top = zdd->permZ[Q->index]; + if (p_top < q_top) { + res = cuddZddIntersect(zdd, cuddE(P), Q); + if (res == NULL) return(NULL); + } else if (p_top > q_top) { + res = cuddZddIntersect(zdd, P, cuddE(Q)); + if (res == NULL) return(NULL); + } else { + t = cuddZddIntersect(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddIntersect(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(table, cuddZddIntersect, P, Q, res); + + return(res); + +} /* end of cuddZddIntersect */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddDiff.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddDiff( + DdManager * zdd, + DdNode * P, + DdNode * Q) +{ + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; + + statLine(zdd); + if (P == empty) + return(empty); + if (Q == empty) + return(P); + if (P == Q) + return(empty); + + /* Check cache. The cache is shared by Cudd_zddDiffConst(). */ + res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q); + if (res != NULL && res != DD_NON_CONSTANT) + return(res); + + if (cuddIsConstant(P)) + p_top = P->index; + else + p_top = zdd->permZ[P->index]; + if (cuddIsConstant(Q)) + q_top = Q->index; + else + q_top = zdd->permZ[Q->index]; + if (p_top < q_top) { + e = cuddZddDiff(zdd, cuddE(P), Q); + if (e == NULL) return(NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, cuddT(P), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); + } else if (p_top > q_top) { + res = cuddZddDiff(zdd, P, cuddE(Q)); + if (res == NULL) return(NULL); + } else { + t = cuddZddDiff(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddDiff(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(table, cuddZddDiff, P, Q, res); + + return(res); + +} /* end of cuddZddDiff */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddChange.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddChangeAux( + DdManager * zdd, + DdNode * P, + DdNode * zvar) +{ + int top_var, level; + DdNode *res, *t, *e; + DdNode *base = DD_ONE(zdd); + DdNode *empty = DD_ZERO(zdd); + + statLine(zdd); + if (P == empty) + return(empty); + if (P == base) + return(zvar); + + /* Check cache. */ + res = cuddCacheLookup2Zdd(zdd, cuddZddChangeAux, P, zvar); + if (res != NULL) + return(res); + + top_var = zdd->permZ[P->index]; + level = zdd->permZ[zvar->index]; + + if (top_var > level) { + res = cuddZddGetNode(zdd, zvar->index, P, DD_ZERO(zdd)); + if (res == NULL) return(NULL); + } else if (top_var == level) { + res = cuddZddGetNode(zdd, zvar->index, cuddE(P), cuddT(P)); + if (res == NULL) return(NULL); + } else { + t = cuddZddChangeAux(zdd, cuddT(P), zvar); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddChangeAux(zdd, cuddE(P), zvar); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(zdd, cuddZddChangeAux, P, zvar, res); + + return(res); + +} /* end of cuddZddChangeAux */ + + +/**Function******************************************************************** + + Synopsis [Computes the positive cofactor of a ZDD w.r.t. a variable.] + + Description [Computes the positive cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is asserted. Returns a pointer to + the result if successful; NULL otherwise. cuddZddSubset1 performs + the same function as Cudd_zddSubset1, but does not restart if + reordering has taken place. Therefore it can be called from within a + recursive procedure.] + + SideEffects [None] + + SeeAlso [cuddZddSubset0 Cudd_zddSubset1] + +******************************************************************************/ +DdNode * +cuddZddSubset1( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *zvar, *r; + DdNode *base, *empty; + + base = DD_ONE(dd); + empty = DD_ZERO(dd); + + zvar = cuddUniqueInterZdd(dd, var, base, empty); + if (zvar == NULL) { + return(NULL); + } else { + cuddRef(zvar); + r = zdd_subset1_aux(dd, P, zvar); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, zvar); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDerefZdd(dd, zvar); + } + + cuddDeref(r); + return(r); + +} /* end of cuddZddSubset1 */ + + +/**Function******************************************************************** + + Synopsis [Computes the negative cofactor of a ZDD w.r.t. a variable.] + + Description [Computes the negative cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is negated. Returns a pointer to + the result if successful; NULL otherwise. cuddZddSubset0 performs + the same function as Cudd_zddSubset0, but does not restart if + reordering has taken place. Therefore it can be called from within a + recursive procedure.] + + SideEffects [None] + + SeeAlso [cuddZddSubset1 Cudd_zddSubset0] + +******************************************************************************/ +DdNode * +cuddZddSubset0( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *zvar, *r; + DdNode *base, *empty; + + base = DD_ONE(dd); + empty = DD_ZERO(dd); + + zvar = cuddUniqueInterZdd(dd, var, base, empty); + if (zvar == NULL) { + return(NULL); + } else { + cuddRef(zvar); + r = zdd_subset0_aux(dd, P, zvar); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, zvar); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDerefZdd(dd, zvar); + } + + cuddDeref(r); + return(r); + +} /* end of cuddZddSubset0 */ + + +/**Function******************************************************************** + + Synopsis [Substitutes a variable with its complement in a ZDD.] + + Description [Substitutes a variable with its complement in a ZDD. + returns a pointer to the result if successful; NULL + otherwise. cuddZddChange performs the same function as + Cudd_zddChange, but does not restart if reordering has taken + place. Therefore it can be called from within a recursive + procedure.] + + SideEffects [None] + + SeeAlso [Cudd_zddChange] + +******************************************************************************/ +DdNode * +cuddZddChange( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *zvar, *res; + + zvar = cuddUniqueInterZdd(dd, var, DD_ONE(dd), DD_ZERO(dd)); + if (zvar == NULL) return(NULL); + cuddRef(zvar); + + res = cuddZddChangeAux(dd, P, zvar); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd,zvar); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd,zvar); + cuddDeref(res); + return(res); + +} /* end of cuddZddChange */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddSubset1.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +zdd_subset1_aux( + DdManager * zdd, + DdNode * P, + DdNode * zvar) +{ + int top_var, level; + DdNode *res, *t, *e; + DdNode *empty; + + statLine(zdd); + empty = DD_ZERO(zdd); + + /* Check cache. */ + res = cuddCacheLookup2Zdd(zdd, zdd_subset1_aux, P, zvar); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) { + res = empty; + cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res); + return(res); + } + + top_var = zdd->permZ[P->index]; + level = zdd->permZ[zvar->index]; + + if (top_var > level) { + res = empty; + } else if (top_var == level) { + res = cuddT(P); + } else { + t = zdd_subset1_aux(zdd, cuddT(P), zvar); + if (t == NULL) return(NULL); + cuddRef(t); + e = zdd_subset1_aux(zdd, cuddE(P), zvar); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res); + + return(res); + +} /* end of zdd_subset1_aux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddSubset0.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +zdd_subset0_aux( + DdManager * zdd, + DdNode * P, + DdNode * zvar) +{ + int top_var, level; + DdNode *res, *t, *e; + + statLine(zdd); + + /* Check cache. */ + res = cuddCacheLookup2Zdd(zdd, zdd_subset0_aux, P, zvar); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) { + res = P; + cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res); + return(res); + } + + top_var = zdd->permZ[P->index]; + level = zdd->permZ[zvar->index]; + + if (top_var > level) { + res = P; + } + else if (top_var == level) { + res = cuddE(P); + } + else { + t = zdd_subset0_aux(zdd, cuddT(P), zvar); + if (t == NULL) return(NULL); + cuddRef(t); + e = zdd_subset0_aux(zdd, cuddE(P), zvar); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res); + + return(res); + +} /* end of zdd_subset0_aux */ + + +/**Function******************************************************************** + + Synopsis [Replaces variables with constants if possible (part of + canonical form).] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +zddVarToConst( + DdNode * f, + DdNode ** gp, + DdNode ** hp, + DdNode * base, + DdNode * empty) +{ + DdNode *g = *gp; + DdNode *h = *hp; + + if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + *gp = base; + } + + if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + *hp = empty; + } + +} /* end of zddVarToConst */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddSymm.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddSymm.c new file mode 100644 index 000000000..559d1a2a5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddSymm.c @@ -0,0 +1,1711 @@ +/**CFile*********************************************************************** + + FileName [cuddZddSymm.c] + + PackageName [cudd] + + Synopsis [Functions for symmetry-based ZDD variable reordering.] + + Description [External procedures included in this module: +
                  +
                • Cudd_zddSymmProfile() +
                + Internal procedures included in this module: +
                  +
                • cuddZddSymmCheck() +
                • cuddZddSymmSifting() +
                • cuddZddSymmSiftingConv() +
                + Static procedures included in this module: +
                  +
                • cuddZddUniqueCompare() +
                • cuddZddSymmSiftingAux() +
                • cuddZddSymmSiftingConvAux() +
                • cuddZddSymmSifting_up() +
                • cuddZddSymmSifting_down() +
                • zdd_group_move() +
                • cuddZddSymmSiftingBackward() +
                • zdd_group_move_backward() +
                + ] + + SeeAlso [cuddSymmetry.c] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define ZDD_MV_OOM (Move *)1 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddSymm.c,v 1.31 2012/02/05 01:07:19 fabio Exp $"; +#endif + +extern int *zdd_entry; + +extern int zddTotalNumberSwapping; + +static DdNode *empty; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddZddSymmSiftingAux (DdManager *table, int x, int x_low, int x_high); +static int cuddZddSymmSiftingConvAux (DdManager *table, int x, int x_low, int x_high); +static Move * cuddZddSymmSifting_up (DdManager *table, int x, int x_low, int initial_size); +static Move * cuddZddSymmSifting_down (DdManager *table, int x, int x_high, int initial_size); +static int cuddZddSymmSiftingBackward (DdManager *table, Move *moves, int size); +static int zdd_group_move (DdManager *table, int x, int y, Move **moves); +static int zdd_group_move_backward (DdManager *table, int x, int y); +static void cuddZddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints statistics on symmetric ZDD variables.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_zddSymmProfile( + DdManager * table, + int lower, + int upper) +{ + int i, x, gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; + + for (i = lower; i < upper; i++) { + if (table->subtableZ[i].next != (unsigned) i) { + x = i; + (void) fprintf(table->out,"Group:"); + do { + (void) fprintf(table->out," %d", table->invpermZ[x]); + TotalSymm++; + gbot = x; + x = table->subtableZ[x].next; + } while (x != i); + TotalSymmGroups++; +#ifdef DD_DEBUG + assert(table->subtableZ[gbot].next == (unsigned) i); +#endif + i = gbot; + (void) fprintf(table->out,"\n"); + } + } + (void) fprintf(table->out,"Total Symmetric = %d\n", TotalSymm); + (void) fprintf(table->out,"Total Groups = %d\n", TotalSymmGroups); + +} /* end of Cudd_zddSymmProfile */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Checks for symmetry of x and y.] + + Description [Checks for symmetry of x and y. Ignores projection + functions, unless they are isolated. Returns 1 in case of + symmetry; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddSymmCheck( + DdManager * table, + int x, + int y) +{ + int i; + DdNode *f, *f0, *f1, *f01, *f00, *f11, *f10; + int yindex; + int xsymmy = 1; + int xsymmyp = 1; + int arccount = 0; + int TotalRefCount = 0; + int symm_found; + + empty = table->zero; + + yindex = table->invpermZ[y]; + for (i = table->subtableZ[x].slots - 1; i >= 0; i--) { + f = table->subtableZ[x].nodelist[i]; + while (f != NULL) { + /* Find f1, f0, f11, f10, f01, f00 */ + f1 = cuddT(f); + f0 = cuddE(f); + if ((int) f1->index == yindex) { + f11 = cuddT(f1); + f10 = cuddE(f1); + if (f10 != empty) + arccount++; + } else { + if ((int) f0->index != yindex) { + return(0); /* f bypasses layer y */ + } + f11 = empty; + f10 = f1; + } + if ((int) f0->index == yindex) { + f01 = cuddT(f0); + f00 = cuddE(f0); + if (f00 != empty) + arccount++; + } else { + f01 = empty; + f00 = f0; + } + if (f01 != f10) + xsymmy = 0; + if (f11 != f00) + xsymmyp = 0; + if ((xsymmy == 0) && (xsymmyp == 0)) + return(0); + + f = f->next; + } /* for each element of the collision list */ + } /* for each slot of the subtable */ + + /* Calculate the total reference counts of y + ** whose else arc is not empty. + */ + for (i = table->subtableZ[y].slots - 1; i >= 0; i--) { + f = table->subtableZ[y].nodelist[i]; + while (f != NIL(DdNode)) { + if (cuddE(f) != empty) + TotalRefCount += f->ref; + f = f->next; + } + } + + symm_found = (arccount == TotalRefCount); +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (symm_found) { + int xindex = table->invpermZ[x]; + (void) fprintf(table->out, + "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); + } +#endif + + return(symm_found); + +} /* end cuddZddSymmCheck */ + + +/**Function******************************************************************** + + Synopsis [Symmetric sifting algorithm for ZDDs.] + + Description [Symmetric sifting algorithm. + Assumes that no dead nodes are present. +
                  +
                1. Order all the variables according to the number of entries in + each unique subtable. +
                2. Sift the variable up and down, remembering each time the total + size of the ZDD heap and grouping variables that are symmetric. +
                3. Select the best permutation. +
                4. Repeat 3 and 4 for all variables. +
                + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddZddSymmSiftingConv] + +******************************************************************************/ +int +cuddZddSymmSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int nvars; + int x; + int result; + int symvars; + int symgroups; + int iteration; +#ifdef DD_STATS + int previousSize; +#endif + + nvars = table->sizeZ; + + /* Find order in which to sift variables. */ + var = NULL; + zdd_entry = ALLOC(int, nvars); + if (zdd_entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingOutOfMem; + } + var = ALLOC(int, nvars); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingOutOfMem; + } + + for (i = 0; i < nvars; i++) { + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; + } + + qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); + + /* Initialize the symmetry of each subtable to itself. */ + for (i = lower; i <= upper; i++) + table->subtableZ[i].next = i; + + iteration = ddMin(table->siftMaxVar, nvars); + for (i = 0; i < iteration; i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + if (x < lower || x > upper) continue; + if (table->subtableZ[x].next == (unsigned) x) { + result = cuddZddSymmSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); +#ifdef DD_VERBOSE + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); +#endif + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } + + FREE(var); + FREE(zdd_entry); + + cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups); + +#ifdef DD_STATS + (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n",symvars); + (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n",symgroups); +#endif + + return(1+symvars); + +cuddZddSymmSiftingOutOfMem: + + if (zdd_entry != NULL) + FREE(zdd_entry); + if (var != NULL) + FREE(var); + + return(0); + +} /* end of cuddZddSymmSifting */ + + +/**Function******************************************************************** + + Synopsis [Symmetric sifting to convergence algorithm for ZDDs.] + + Description [Symmetric sifting to convergence algorithm for ZDDs. + Assumes that no dead nodes are present. +
                  +
                1. Order all the variables according to the number of entries in + each unique subtable. +
                2. Sift the variable up and down, remembering each time the total + size of the ZDD heap and grouping variables that are symmetric. +
                3. Select the best permutation. +
                4. Repeat 3 and 4 for all variables. +
                5. Repeat 1-4 until no further improvement. +
                + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddZddSymmSifting] + +******************************************************************************/ +int +cuddZddSymmSiftingConv( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int nvars; + int initialSize; + int x; + int result; + int symvars; + int symgroups; + int classes; + int iteration; +#ifdef DD_STATS + int previousSize; +#endif + + initialSize = table->keysZ; + + nvars = table->sizeZ; + + /* Find order in which to sift variables. */ + var = NULL; + zdd_entry = ALLOC(int, nvars); + if (zdd_entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingConvOutOfMem; + } + var = ALLOC(int, nvars); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingConvOutOfMem; + } + + for (i = 0; i < nvars; i++) { + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; + } + + qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); + + /* Initialize the symmetry of each subtable to itself + ** for first pass of converging symmetric sifting. + */ + for (i = lower; i <= upper; i++) + table->subtableZ[i].next = i; + + iteration = ddMin(table->siftMaxVar, table->sizeZ); + for (i = 0; i < iteration; i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; + /* Only sift if not in symmetry group already. */ + if (table->subtableZ[x].next == (unsigned) x) { +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = cuddZddSymmSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingConvOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); +#ifdef DD_VERBOSE + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); +#endif + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } + + /* Sifting now until convergence. */ + while ((unsigned) initialSize > table->keysZ) { + initialSize = table->keysZ; +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + /* Here we consider only one representative for each symmetry class. */ + for (x = lower, classes = 0; x <= upper; x++, classes++) { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + /* Here x is the largest index in a group. + ** Groups consists of adjacent variables. + ** Hence, the next increment of x will move it to a new group. + */ + i = table->invpermZ[x]; + zdd_entry[i] = table->subtableZ[x].keys; + var[classes] = i; + } + + qsort((void *)var,classes,sizeof(int),(DD_QSFP)cuddZddUniqueCompare); + + /* Now sift. */ + iteration = ddMin(table->siftMaxVar, nvars); + for (i = 0; i < iteration; i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; + if ((unsigned) x >= table->subtableZ[x].next) { +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = cuddZddSymmSiftingConvAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingConvOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); +#ifdef DD_VERBOSE + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); +#endif + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } /* for */ + } + + cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups); + +#ifdef DD_STATS + (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n", + symvars); + (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n", + symgroups); +#endif + + FREE(var); + FREE(zdd_entry); + + return(1+symvars); + +cuddZddSymmSiftingConvOutOfMem: + + if (zdd_entry != NULL) + FREE(zdd_entry); + if (var != NULL) + FREE(var); + + return(0); + +} /* end of cuddZddSymmSiftingConv */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Given x_low <= x <= x_high moves x up and down between the + boundaries.] + + Description [Given x_low <= x <= x_high moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is not part of a symmetry group. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSymmSiftingAux( + DdManager * table, + int x, + int x_low, + int x_high) +{ + Move *move; + Move *move_up; /* list of up move */ + Move *move_down; /* list of down move */ + int initial_size; + int result; + int i; + int topbot; /* index to either top or bottom of symmetry group */ + int init_group_size, final_group_size; + + initial_size = table->keysZ; + + move_down = NULL; + move_up = NULL; + + /* Look for consecutive symmetries above x. */ + for (i = x; i > x_low; i--) { + if (!cuddZddSymmCheck(table, i - 1, i)) + break; + /* find top of i-1's symmetry */ + topbot = table->subtableZ[i - 1].next; + table->subtableZ[i - 1].next = i; + table->subtableZ[x].next = topbot; + /* x is bottom of group so its symmetry is top of i-1's + group */ + i = topbot + 1; /* add 1 for i--, new i is top of symm group */ + } + /* Look for consecutive symmetries below x. */ + for (i = x; i < x_high; i++) { + if (!cuddZddSymmCheck(table, i, i + 1)) + break; + /* find bottom of i+1's symm group */ + topbot = i + 1; + while ((unsigned) topbot < table->subtableZ[topbot].next) + topbot = table->subtableZ[topbot].next; + + table->subtableZ[topbot].next = table->subtableZ[i].next; + table->subtableZ[i].next = i + 1; + i = topbot - 1; /* add 1 for i++, + new i is bottom of symm group */ + } + + /* Now x maybe in the middle of a symmetry group. */ + if (x == x_low) { /* Sift down */ + /* Find bottom of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + + i = table->subtableZ[x].next; + init_group_size = x - i + 1; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) + x = move_down->y; + else + x = table->subtableZ[x].next; + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, + move_down, initial_size); + } + else { + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; + } + else if (x == x_high) { /* Sift up */ + /* Find top of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_low, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) + x = move_up->x; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; + } + else if ((x - x_low) > (x_high - x)) { /* must go down first: + shorter */ + /* Find bottom of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_down != NULL) { + x = move_down->y; + } + else { + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; + } + else { /* moving up first:shorter */ + /* Find top of x's symmetry group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_high, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + init_group_size = x - i + 1; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) { + x = move_down->y; + } + else { + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetries detected, + go back to best position */ + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + else { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; + } + + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + + return(1); + +cuddZddSymmSiftingAuxOutOfMem: + if (move_down != ZDD_MV_OOM) { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + } + if (move_up != ZDD_MV_OOM) { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + } + + return(0); + +} /* end of cuddZddSymmSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Given x_low <= x <= x_high moves x up and down between the + boundaries.] + + Description [Given x_low <= x <= x_high moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is either an isolated variable, or it is the bottom of + a symmetry group. All symmetries may not have been found, because of + exceeded growth limit. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSymmSiftingConvAux( + DdManager * table, + int x, + int x_low, + int x_high) +{ + Move *move; + Move *move_up; /* list of up move */ + Move *move_down; /* list of down move */ + int initial_size; + int result; + int i; + int init_group_size, final_group_size; + + initial_size = table->keysZ; + + move_down = NULL; + move_up = NULL; + + if (x == x_low) { /* Sift down */ + i = table->subtableZ[x].next; + init_group_size = x - i + 1; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) + x = move_down->y; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetries detected, + go back to best position */ + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + else { + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; + } + else if (x == x_high) { /* Sift up */ + /* Find top of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_low, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) + x = move_up->x; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; + } + else if ((x - x_low) > (x_high - x)) { /* must go down first: + shorter */ + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_down != NULL) { + x = move_down->y; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; + } + else { /* moving up first:shorter */ + /* Find top of x's symmetry group */ + x = table->subtableZ[x].next; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_high, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + init_group_size = x - i + 1; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) { + x = move_down->y; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetries detected, + go back to best position */ + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + else { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; + } + + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + + return(1); + +cuddZddSymmSiftingConvAuxOutOfMem: + if (move_down != ZDD_MV_OOM) { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + } + if (move_up != ZDD_MV_OOM) { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + } + + return(0); + +} /* end of cuddZddSymmSiftingConvAux */ + + +/**Function******************************************************************** + + Synopsis [Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much.] + + Description [Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much. Assumes that x is the top + of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; ZDD_MV_OOM if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddSymmSifting_up( + DdManager * table, + int x, + int x_low, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + int i, gytop; + + moves = NULL; + y = cuddZddNextLow(table, x); + while (y >= x_low) { + gytop = table->subtableZ[y].next; + if (cuddZddSymmCheck(table, y, x)) { + /* Symmetry found, attach symm groups */ + table->subtableZ[y].next = x; + i = table->subtableZ[x].next; + while (table->subtableZ[i].next != (unsigned) x) + i = table->subtableZ[i].next; + table->subtableZ[i].next = gytop; + } + else if ((table->subtableZ[x].next == (unsigned) x) && + (table->subtableZ[y].next == (unsigned) y)) { + /* x and y have self symmetry */ + size = cuddZddSwapInPlace(table, y, x); + if (size == 0) + goto cuddZddSymmSifting_upOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSymmSifting_upOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + else { /* Group move */ + size = zdd_group_move(table, y, x, &moves); + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + x = gytop; + y = cuddZddNextLow(table, x); + } + + return(moves); + +cuddZddSymmSifting_upOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(ZDD_MV_OOM); + +} /* end of cuddZddSymmSifting_up */ + + +/**Function******************************************************************** + + Synopsis [Moves x down until either it reaches the bound (x_high) or + the size of the ZDD heap increases too much.] + + Description [Moves x down until either it reaches the bound (x_high) + or the size of the ZDD heap increases too much. Assumes that x is the + bottom of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; ZDD_MV_OOM if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddSymmSifting_down( + DdManager * table, + int x, + int x_high, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + int i, gxtop, gybot; + + moves = NULL; + y = cuddZddNextHigh(table, x); + while (y <= x_high) { + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + if (cuddZddSymmCheck(table, x, y)) { + /* Symmetry found, attach symm groups */ + gxtop = table->subtableZ[x].next; + table->subtableZ[x].next = y; + i = table->subtableZ[y].next; + while (table->subtableZ[i].next != (unsigned) y) + i = table->subtableZ[i].next; + table->subtableZ[i].next = gxtop; + } + else if ((table->subtableZ[x].next == (unsigned) x) && + (table->subtableZ[y].next == (unsigned) y)) { + /* x and y have self symmetry */ + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddSymmSifting_downOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSymmSifting_downOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + x = y; + y = cuddZddNextHigh(table, x); + } + else { /* Group move */ + size = zdd_group_move(table, x, y, &moves); + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + x = gybot; + y = cuddZddNextHigh(table, x); + } + + return(moves); + +cuddZddSymmSifting_downOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(ZDD_MV_OOM); + +} /* end of cuddZddSymmSifting_down */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the ZDD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSymmSiftingBackward( + DdManager * table, + Move * moves, + int size) +{ + int i; + int i_best; + Move *move; + int res; + + i_best = -1; + for (move = moves, i = 0; move != NULL; move = move->next, i++) { + if (move->size < size) { + i_best = i; + size = move->size; + } + } + + for (move = moves, i = 0; move != NULL; move = move->next, i++) { + if (i == i_best) break; + if ((table->subtableZ[move->x].next == move->x) && + (table->subtableZ[move->y].next == move->y)) { + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) return(0); + } + else { /* Group move necessary */ + res = zdd_group_move_backward(table, move->x, move->y); + } + if (i_best == -1 && res == size) + break; + } + + return(1); + +} /* end of cuddZddSymmSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Swaps two groups.] + + Description [Swaps two groups. x is assumed to be the bottom variable + of the first group. y is assumed to be the top variable of the second + group. Updates the list of moves. Returns the number of keys in the + table if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zdd_group_move( + DdManager * table, + int x, + int y, + Move ** moves) +{ + Move *move; + int size; + int i, temp, gxtop, gxbot, gybot, yprev; + int swapx, swapy; + +#ifdef DD_DEBUG + assert(x < y); /* we assume that x < y */ +#endif + /* Find top and bottom for the two groups. */ + gxtop = table->subtableZ[x].next; + gxbot = x; + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + yprev = gybot; + + while (x <= y) { + while (y > gxtop) { + /* Set correct symmetries. */ + temp = table->subtableZ[x].next; + if (temp == x) + temp = y; + i = gxtop; + for (;;) { + if (table->subtableZ[i].next == (unsigned) x) { + table->subtableZ[i].next = y; + break; + } else { + i = table->subtableZ[i].next; + } + } + if (table->subtableZ[y].next != (unsigned) y) { + table->subtableZ[x].next = table->subtableZ[y].next; + } else { + table->subtableZ[x].next = x; + } + + if (yprev != y) { + table->subtableZ[yprev].next = x; + } else { + yprev = x; + } + table->subtableZ[y].next = temp; + + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto zdd_group_moveOutOfMem; + swapx = x; + swapy = y; + y = x; + x--; + } /* while y > gxtop */ + + /* Trying to find the next y. */ + if (table->subtableZ[y].next <= (unsigned) y) { + gybot = y; + } else { + y = table->subtableZ[y].next; + } + + yprev = gxtop; + gxtop++; + gxbot++; + x = gxbot; + } /* while x <= y, end of group movement */ + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zdd_group_moveOutOfMem; + move->x = swapx; + move->y = swapy; + move->size = table->keysZ; + move->next = *moves; + *moves = move; + + return(table->keysZ); + +zdd_group_moveOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of zdd_group_move */ + + +/**Function******************************************************************** + + Synopsis [Undoes the swap of two groups.] + + Description [Undoes the swap of two groups. x is assumed to be the + bottom variable of the first group. y is assumed to be the top + variable of the second group. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zdd_group_move_backward( + DdManager * table, + int x, + int y) +{ + int size; + int i, temp, gxtop, gxbot, gybot, yprev; + +#ifdef DD_DEBUG + assert(x < y); /* we assume that x < y */ +#endif + /* Find top and bottom of the two groups. */ + gxtop = table->subtableZ[x].next; + gxbot = x; + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + yprev = gybot; + + while (x <= y) { + while (y > gxtop) { + /* Set correct symmetries. */ + temp = table->subtableZ[x].next; + if (temp == x) + temp = y; + i = gxtop; + for (;;) { + if (table->subtableZ[i].next == (unsigned) x) { + table->subtableZ[i].next = y; + break; + } else { + i = table->subtableZ[i].next; + } + } + if (table->subtableZ[y].next != (unsigned) y) { + table->subtableZ[x].next = table->subtableZ[y].next; + } else { + table->subtableZ[x].next = x; + } + + if (yprev != y) { + table->subtableZ[yprev].next = x; + } else { + yprev = x; + } + table->subtableZ[y].next = temp; + + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + return(0); + y = x; + x--; + } /* while y > gxtop */ + + /* Trying to find the next y. */ + if (table->subtableZ[y].next <= (unsigned) y) { + gybot = y; + } else { + y = table->subtableZ[y].next; + } + + yprev = gxtop; + gxtop++; + gxbot++; + x = gxbot; + } /* while x <= y, end of group movement backward */ + + return(size); + +} /* end of zdd_group_move_backward */ + + +/**Function******************************************************************** + + Synopsis [Counts numbers of symmetric variables and symmetry + groups.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static void +cuddZddSymmSummary( + DdManager * table, + int lower, + int upper, + int * symvars, + int * symgroups) +{ + int i,x,gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; + + for (i = lower; i <= upper; i++) { + if (table->subtableZ[i].next != (unsigned) i) { + TotalSymmGroups++; + x = i; + do { + TotalSymm++; + gbot = x; + x = table->subtableZ[x].next; + } while (x != i); +#ifdef DD_DEBUG + assert(table->subtableZ[gbot].next == (unsigned) i); +#endif + i = gbot; + } + } + *symvars = TotalSymm; + *symgroups = TotalSymmGroups; + + return; + +} /* end of cuddZddSymmSummary */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/cuddZddUtil.c b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddUtil.c new file mode 100644 index 000000000..aecb93ee4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/cuddZddUtil.c @@ -0,0 +1,1205 @@ +/**CFile*********************************************************************** + + FileName [cuddZddUtil.c] + + PackageName [cudd] + + Synopsis [Utility functions for ZDDs.] + + Description [External procedures included in this module: +
                  +
                • Cudd_zddPrintMinterm() +
                • Cudd_zddPrintCover() +
                • Cudd_zddPrintDebug() +
                • Cudd_zddFirstPath() +
                • Cudd_zddNextPath() +
                • Cudd_zddCoverPathToString() +
                • Cudd_zddSupport() +
                • Cudd_zddDumpDot() +
                + Internal procedures included in this module: +
                  +
                • cuddZddP() +
                + Static procedures included in this module: +
                  +
                • zp2() +
                • zdd_print_minterm_aux() +
                • zddPrintCoverAux() +
                • zddSupportStep() +
                • zddClearFlag() +
                + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.29 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int zp2 (DdManager *zdd, DdNode *f, st_table *t); +static void zdd_print_minterm_aux (DdManager *zdd, DdNode *node, int level, int *list); +static void zddPrintCoverAux (DdManager *zdd, DdNode *node, int level, int *list); +static void zddSupportStep(DdNode * f, int * support); +static void zddClearFlag(DdNode * f); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints a disjoint sum of product form for a ZDD.] + + Description [Prints a disjoint sum of product form for a ZDD. Returns 1 + if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddPrintDebug Cudd_zddPrintCover] + +******************************************************************************/ +int +Cudd_zddPrintMinterm( + DdManager * zdd, + DdNode * node) +{ + int i, size; + int *list; + + size = (int)zdd->sizeZ; + list = ALLOC(int, size); + if (list == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ + zdd_print_minterm_aux(zdd, node, 0, list); + FREE(list); + return(1); + +} /* end of Cudd_zddPrintMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints a sum of products from a ZDD representing a cover.] + + Description [Prints a sum of products from a ZDD representing a cover. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddPrintMinterm] + +******************************************************************************/ +int +Cudd_zddPrintCover( + DdManager * zdd, + DdNode * node) +{ + int i, size; + int *list; + + size = (int)zdd->sizeZ; + if (size % 2 != 0) return(0); /* number of variables should be even */ + list = ALLOC(int, size); + if (list == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ + zddPrintCoverAux(zdd, node, 0, list); + FREE(list); + return(1); + +} /* end of Cudd_zddPrintCover */ + + +/**Function******************************************************************** + + Synopsis [Prints to the standard output a ZDD and its statistics.] + + Description [Prints to the standard output a DD and its statistics. + The statistics include the number of nodes and the number of minterms. + (The number of minterms is also the number of combinations in the set.) + The statistics are printed if pr > 0. Specifically: +
                  +
                • pr = 0 : prints nothing +
                • pr = 1 : prints counts of nodes and minterms +
                • pr = 2 : prints counts + disjoint sum of products +
                • pr = 3 : prints counts + list of nodes +
                • pr > 3 : prints counts + disjoint sum of products + list of nodes +
                + Returns 1 if successful; 0 otherwise. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_zddPrintDebug( + DdManager * zdd, + DdNode * f, + int n, + int pr) +{ + DdNode *empty = DD_ZERO(zdd); + int nodes; + double minterms; + int retval = 1; + + if (f == empty && pr > 0) { + (void) fprintf(zdd->out,": is the empty ZDD\n"); + (void) fflush(zdd->out); + return(1); + } + + if (pr > 0) { + nodes = Cudd_zddDagSize(f); + if (nodes == CUDD_OUT_OF_MEM) retval = 0; + minterms = Cudd_zddCountMinterm(zdd, f, n); + if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; + (void) fprintf(zdd->out,": %d nodes %g minterms\n", + nodes, minterms); + if (pr > 2) + if (!cuddZddP(zdd, f)) retval = 0; + if (pr == 2 || pr > 3) { + if (!Cudd_zddPrintMinterm(zdd, f)) retval = 0; + (void) fprintf(zdd->out,"\n"); + } + (void) fflush(zdd->out); + } + return(retval); + +} /* end of Cudd_zddPrintDebug */ + + + +/**Function******************************************************************** + + Synopsis [Finds the first path of a ZDD.] + + Description [Defines an iterator on the paths of a ZDD + and finds its first path. Returns a generator that contains the + information necessary to continue the enumeration if successful; NULL + otherwise.

                + A path is represented as an array of literals, which are integers in + {0, 1, 2}; 0 represents an else arc out of a node, 1 represents a then arc + out of a node, and 2 stands for the absence of a node. + The size of the array equals the number of variables in the manager at + the time Cudd_zddFirstCube is called.

                + The paths that end in the empty terminal are not enumerated.] + + SideEffects [The first path is returned as a side effect.] + + SeeAlso [Cudd_zddForeachPath Cudd_zddNextPath Cudd_GenFree + Cudd_IsGenEmpty] + +******************************************************************************/ +DdGen * +Cudd_zddFirstPath( + DdManager * zdd, + DdNode * f, + int ** path) +{ + DdGen *gen; + DdNode *top, *next, *prev; + int i; + int nvars; + + /* Sanity Check. */ + if (zdd == NULL || f == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ALLOC(DdGen,1); + if (gen == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = zdd; + gen->type = CUDD_GEN_ZDD_PATHS; + gen->status = CUDD_GEN_EMPTY; + gen->gen.cubes.cube = NULL; + gen->gen.cubes.value = DD_ZERO_VAL; + gen->stack.sp = 0; + gen->stack.stack = NULL; + gen->node = NULL; + + nvars = zdd->sizeZ; + gen->gen.cubes.cube = ALLOC(int,nvars); + if (gen->gen.cubes.cube == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + FREE(gen); + return(NULL); + } + for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; + + /* The maximum stack depth is one plus the number of variables. + ** because a path may have nodes at all levels, including the + ** constant level. + */ + gen->stack.stack = ALLOC(DdNodePtr, nvars+1); + if (gen->stack.stack == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + FREE(gen->gen.cubes.cube); + FREE(gen); + return(NULL); + } + for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; + + /* Find the first path of the ZDD. */ + gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; + + while (1) { + top = gen->stack.stack[gen->stack.sp-1]; + if (!cuddIsConstant(Cudd_Regular(top))) { + /* Take the else branch first. */ + gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; + next = cuddE(Cudd_Regular(top)); + gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; + } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { + /* Backtrack. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); + next = cuddT(prev); + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[prev->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[prev->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(Cudd_Regular(top)); + goto done; + } + } + +done: + *path = gen->gen.cubes.cube; + return(gen); + +} /* end of Cudd_zddFirstPath */ + + +/**Function******************************************************************** + + Synopsis [Generates the next path of a ZDD.] + + Description [Generates the next path of a ZDD onset, + using generator gen. Returns 0 if the enumeration is completed; 1 + otherwise.] + + SideEffects [The path is returned as a side effect. The + generator is modified.] + + SeeAlso [Cudd_zddForeachPath Cudd_zddFirstPath Cudd_GenFree + Cudd_IsGenEmpty] + +******************************************************************************/ +int +Cudd_zddNextPath( + DdGen * gen, + int ** path) +{ + DdNode *top, *next, *prev; + DdManager *zdd = gen->manager; + + /* Backtrack from previously reached terminal node. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + top = gen->stack.stack[gen->stack.sp-1]; + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); + next = cuddT(prev); + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[prev->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[prev->index] = 2; + gen->stack.sp--; + } + + while (1) { + top = gen->stack.stack[gen->stack.sp-1]; + if (!cuddIsConstant(Cudd_Regular(top))) { + /* Take the else branch first. */ + gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; + next = cuddE(Cudd_Regular(top)); + gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; + } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { + /* Backtrack. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); + next = cuddT(prev); + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[prev->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[prev->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(Cudd_Regular(top)); + goto done; + } + } + +done: + if (gen->status == CUDD_GEN_EMPTY) return(0); + *path = gen->gen.cubes.cube; + return(1); + +} /* end of Cudd_zddNextPath */ + + +/**Function******************************************************************** + + Synopsis [Converts a path of a ZDD representing a cover to a string.] + + Description [Converts a path of a ZDD representing a cover to a + string. The string represents an implicant of the cover. The path + is typically produced by Cudd_zddForeachPath. Returns a pointer to + the string if successful; NULL otherwise. If the str input is NULL, + it allocates a new string. The string passed to this function must + have enough room for all variables and for the terminator.] + + SideEffects [None] + + SeeAlso [Cudd_zddForeachPath] + +******************************************************************************/ +char * +Cudd_zddCoverPathToString( + DdManager *zdd /* DD manager */, + int *path /* path of ZDD representing a cover */, + char *str /* pointer to string to use if != NULL */ + ) +{ + int nvars = zdd->sizeZ; + int i; + char *res; + + if (nvars & 1) return(NULL); + nvars >>= 1; + if (str == NULL) { + res = ALLOC(char, nvars+1); + if (res == NULL) return(NULL); + } else { + res = str; + } + for (i = 0; i < nvars; i++) { + int v = (path[2*i] << 2) | path[2*i+1]; + switch (v) { + case 0: + case 2: + case 8: + case 10: + res[i] = '-'; + break; + case 1: + case 9: + res[i] = '0'; + break; + case 4: + case 6: + res[i] = '1'; + break; + default: + res[i] = '?'; + } + } + res[nvars] = 0; + + return(res); + +} /* end of Cudd_zddCoverPathToString */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a ZDD depends.] + + Description [Finds the variables on which a ZDD depends. + Returns a BDD consisting of the product of the variables if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Support] + +******************************************************************************/ +DdNode * +Cudd_zddSupport( + DdManager * dd /* manager */, + DdNode * f /* ZDD whose support is sought */) +{ + int *support; + DdNode *res, *tmp, *var; + int i,j; + int size; + + /* Allocate and initialize support array for ddSupportStep. */ + size = ddMax(dd->size, dd->sizeZ); + support = ALLOC(int,size); + if (support == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + support[i] = 0; + } + + /* Compute support and clean up markers. */ + zddSupportStep(Cudd_Regular(f),support); + zddClearFlag(Cudd_Regular(f)); + + /* Transform support from array to cube. */ + do { + dd->reordered = 0; + res = DD_ONE(dd); + cuddRef(res); + for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ + i = (j >= dd->size) ? j : dd->invperm[j]; + if (support[i] == 1) { + /* The following call to cuddUniqueInter is guaranteed + ** not to trigger reordering because the node we look up + ** already exists. */ + var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + cuddRef(var); + tmp = cuddBddAndRecur(dd,res,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + res = NULL; + break; + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + res = tmp; + } + } + } while (dd->reordered == 1); + + FREE(support); + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_zddSupport */ + + +/**Function******************************************************************** + + Synopsis [Writes a dot file representing the argument ZDDs.] + + Description [Writes a file representing the argument ZDDs in a format + suitable for the graph drawing program dot. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, + file system full). + Cudd_zddDumpDot does not close the file: This is the caller + responsibility. Cudd_zddDumpDot uses a minimal unique subset of the + hexadecimal address of a node as name for it. + If the argument inames is non-null, it is assumed to hold the pointers + to the names of the inputs. Similarly for onames. + Cudd_zddDumpDot uses the following convention to draw arcs: +

                  +
                • solid line: THEN arcs; +
                • dashed line: ELSE arcs. +
                + The dot options are chosen so that the drawing fits on a letter-size + sheet. + ] + + SideEffects [None] + + SeeAlso [Cudd_DumpDot Cudd_zddPrintDebug] + +******************************************************************************/ +int +Cudd_zddDumpDot( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->sizeZ; + st_table *visited = NULL; + st_generator *gen; + int retval; + int i, j; + int slots; + DdNodePtr *nodelist; + long refAddr, diff, mask; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int,nvars); + if (sorted == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; + } + for (i = 0; i < nvars; i++) sorted[i] = 0; + + /* Take the union of the supports of each output function. */ + for (i = 0; i < n; i++) { + support = Cudd_zddSupport(dd,f[i]); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + } + support = NULL; /* so that we do not try to free it in case of failure */ + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Collect all the nodes of this DD in the symbol table. */ + for (i = 0; i < n; i++) { + retval = cuddCollectNodes(f[i],visited); + if (retval == 0) goto failure; + } + + /* Find how many most significant hex digits are identical + ** in the addresses of all the nodes. Build a mask based + ** on this knowledge, so that digits that carry no information + ** will not be printed. This is done in two steps. + ** 1. We scan the symbol table to find the bits that differ + ** in at least 2 addresses. + ** 2. We choose one of the possible masks. There are 8 possible + ** masks for 32-bit integer, and 16 possible masks for 64-bit + ** integers. + */ + + /* Find the bits that are different. */ + refAddr = (long) f[0]; + diff = 0; + gen = st_init_gen(visited); + while (st_gen(gen, &scan, NULL)) { + diff |= refAddr ^ (long) scan; + } + st_free_gen(gen); + + /* Choose the mask. */ + for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; + } + + /* Write the header and the global attributes. */ + retval = fprintf(fp,"digraph \"ZDD\" {\n"); + if (retval == EOF) return(0); + retval = fprintf(fp, + "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); + if (retval == EOF) return(0); + + /* Write the input name subgraph by scanning the support array. */ + retval = fprintf(fp,"{ node [shape = plaintext];\n"); + if (retval == EOF) goto failure; + retval = fprintf(fp," edge [style = invis];\n"); + if (retval == EOF) goto failure; + /* We use a name ("CONST NODES") with an embedded blank, because + ** it is unlikely to appear as an input name. + */ + retval = fprintf(fp," \"CONST NODES\" [style = invis];\n"); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if (sorted[dd->invpermZ[i]]) { + if (inames == NULL) { + retval = fprintf(fp,"\" %d \" -> ", dd->invpermZ[i]); + } else { + retval = fprintf(fp,"\" %s \" -> ", inames[dd->invpermZ[i]]); + } + if (retval == EOF) goto failure; + } + } + retval = fprintf(fp,"\"CONST NODES\"; \n}\n"); + if (retval == EOF) goto failure; + + /* Write the output node subgraph. */ + retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); + if (retval == EOF) goto failure; + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + if (i == n - 1) { + retval = fprintf(fp,"; }\n"); + } else { + retval = fprintf(fp," -> "); + } + if (retval == EOF) goto failure; + } + + /* Write rank info: All nodes with the same index have the same rank. */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invpermZ[i]]) { + retval = fprintf(fp,"{ rank = same; "); + if (retval == EOF) goto failure; + if (inames == NULL) { + retval = fprintf(fp,"\" %d \";\n", dd->invpermZ[i]); + } else { + retval = fprintf(fp,"\" %s \";\n", inames[dd->invpermZ[i]]); + } + if (retval == EOF) goto failure; + nodelist = dd->subtableZ[i].nodelist; + slots = dd->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", (void *) + ((mask & (ptrint) scan) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; + } + } + + /* All constants have the same rank. */ + retval = fprintf(fp, + "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); + if (retval == EOF) goto failure; + nodelist = dd->constants.nodelist; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", (void *) + ((mask & (ptrint) scan) / sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + retval = fprintf(fp,"}\n}\n"); + if (retval == EOF) goto failure; + + /* Write edge info. */ + /* Edges from the output nodes. */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp," -> \"%p\" [style = solid];\n", + (void *) ((mask & (ptrint) f[i]) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + + /* Edges from internal nodes. */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invpermZ[i]]) { + nodelist = dd->subtableZ[i].nodelist; + slots = dd->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp, + "\"%p\" -> \"%p\";\n", + (void *) ((mask & (ptrint) scan) / sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddT(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + retval = fprintf(fp, + "\"%p\" -> \"%p\" [style = dashed];\n", + (void *) ((mask & (ptrint) scan) + / sizeof(DdNode)), + (void *) ((mask & (ptrint) + cuddE(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + } + } + + /* Write constant labels. */ + nodelist = dd->constants.nodelist; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + cuddV(scan)); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + + /* Write trailer and return. */ + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; + + st_free_table(visited); + FREE(sorted); + return(1); + +failure: + if (sorted != NULL) FREE(sorted); + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_zddDumpBlif */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints a ZDD to the standard output. One line per node is + printed.] + + Description [Prints a ZDD to the standard output. One line per node is + printed. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddPrintDebug] + +******************************************************************************/ +int +cuddZddP( + DdManager * zdd, + DdNode * f) +{ + int retval; + st_table *table = st_init_table(st_ptrcmp, st_ptrhash); + + if (table == NULL) return(0); + + retval = zp2(zdd, f, table); + st_free_table(table); + (void) fputc('\n', zdd->out); + return(retval); + +} /* end of cuddZddP */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of cuddZddP.] + + Description [Performs the recursive step of cuddZddP. Returns 1 in + case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zp2( + DdManager * zdd, + DdNode * f, + st_table * t) +{ + DdNode *n; + int T, E; + DdNode *base = DD_ONE(zdd); + + if (f == NULL) + return(0); + + if (Cudd_IsConstant(f)) { + (void)fprintf(zdd->out, "ID = %d\n", (f == base)); + return(1); + } + if (st_is_member(t, (char *)f) == 1) + return(1); + + if (st_insert(t, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + +#if SIZEOF_VOID_P == 8 + (void) fprintf(zdd->out, "ID = 0x%lx\tindex = %u\tr = %u\t", + (ptruint)f / (ptruint) sizeof(DdNode), f->index, f->ref); +#else + (void) fprintf(zdd->out, "ID = 0x%x\tindex = %hu\tr = %hu\t", + (ptruint)f / (ptruint) sizeof(DdNode), f->index, f->ref); +#endif + + n = cuddT(f); + if (Cudd_IsConstant(n)) { + (void) fprintf(zdd->out, "T = %d\t\t", (n == base)); + T = 1; + } else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(zdd->out, "T = 0x%lx\t", (ptruint) n / + (ptruint) sizeof(DdNode)); +#else + (void) fprintf(zdd->out, "T = 0x%x\t", (ptruint) n / + (ptruint) sizeof(DdNode)); +#endif + T = 0; + } + + n = cuddE(f); + if (Cudd_IsConstant(n)) { + (void) fprintf(zdd->out, "E = %d\n", (n == base)); + E = 1; + } else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(zdd->out, "E = 0x%lx\n", (ptruint) n / + (ptruint) sizeof(DdNode)); +#else + (void) fprintf(zdd->out, "E = 0x%x\n", (ptruint) n / + (ptruint) sizeof(DdNode)); +#endif + E = 0; + } + + if (E == 0) + if (zp2(zdd, cuddE(f), t) == 0) return(0); + if (T == 0) + if (zp2(zdd, cuddT(f), t) == 0) return(0); + return(1); + +} /* end of zp2 */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddPrintMinterm.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +zdd_print_minterm_aux( + DdManager * zdd /* manager */, + DdNode * node /* current node */, + int level /* depth in the recursion */, + int * list /* current recursion path */) +{ + DdNode *Nv, *Nnv; + int i, v; + DdNode *base = DD_ONE(zdd); + + if (Cudd_IsConstant(node)) { + if (node == base) { + /* Check for missing variable. */ + if (level != zdd->sizeZ) { + list[zdd->invpermZ[level]] = 0; + zdd_print_minterm_aux(zdd, node, level + 1, list); + return; + } + /* Terminal case: Print one cube based on the current recursion + ** path. + */ + for (i = 0; i < zdd->sizeZ; i++) { + v = list[i]; + if (v == 0) + (void) fprintf(zdd->out,"0"); + else if (v == 1) + (void) fprintf(zdd->out,"1"); + else if (v == 3) + (void) fprintf(zdd->out,"@"); /* should never happen */ + else + (void) fprintf(zdd->out,"-"); + } + (void) fprintf(zdd->out," 1\n"); + } + } else { + /* Check for missing variable. */ + if (level != cuddIZ(zdd,node->index)) { + list[zdd->invpermZ[level]] = 0; + zdd_print_minterm_aux(zdd, node, level + 1, list); + return; + } + + Nnv = cuddE(node); + Nv = cuddT(node); + if (Nv == Nnv) { + list[node->index] = 2; + zdd_print_minterm_aux(zdd, Nnv, level + 1, list); + return; + } + + list[node->index] = 1; + zdd_print_minterm_aux(zdd, Nv, level + 1, list); + list[node->index] = 0; + zdd_print_minterm_aux(zdd, Nnv, level + 1, list); + } + return; + +} /* end of zdd_print_minterm_aux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddPrintCover.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +zddPrintCoverAux( + DdManager * zdd /* manager */, + DdNode * node /* current node */, + int level /* depth in the recursion */, + int * list /* current recursion path */) +{ + DdNode *Nv, *Nnv; + int i, v; + DdNode *base = DD_ONE(zdd); + + if (Cudd_IsConstant(node)) { + if (node == base) { + /* Check for missing variable. */ + if (level != zdd->sizeZ) { + list[zdd->invpermZ[level]] = 0; + zddPrintCoverAux(zdd, node, level + 1, list); + return; + } + /* Terminal case: Print one cube based on the current recursion + ** path. + */ + for (i = 0; i < zdd->sizeZ; i += 2) { + v = list[i] * 4 + list[i+1]; + if (v == 0) + (void) putc('-',zdd->out); + else if (v == 4) + (void) putc('1',zdd->out); + else if (v == 1) + (void) putc('0',zdd->out); + else + (void) putc('@',zdd->out); /* should never happen */ + } + (void) fprintf(zdd->out," 1\n"); + } + } else { + /* Check for missing variable. */ + if (level != cuddIZ(zdd,node->index)) { + list[zdd->invpermZ[level]] = 0; + zddPrintCoverAux(zdd, node, level + 1, list); + return; + } + + Nnv = cuddE(node); + Nv = cuddT(node); + if (Nv == Nnv) { + list[node->index] = 2; + zddPrintCoverAux(zdd, Nnv, level + 1, list); + return; + } + + list[node->index] = 1; + zddPrintCoverAux(zdd, Nv, level + 1, list); + list[node->index] = 0; + zddPrintCoverAux(zdd, Nnv, level + 1, list); + } + return; + +} /* end of zddPrintCoverAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddSupport.] + + Description [Performs the recursive step of Cudd_zddSupport. Performs a + DFS from f. The support is accumulated in supp as a side effect. Uses + the LSB of the then pointer as visited flag.] + + SideEffects [None] + + SeeAlso [zddClearFlag] + +******************************************************************************/ +static void +zddSupportStep( + DdNode * f, + int * support) +{ + if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) { + return; + } + + support[f->index] = 1; + zddSupportStep(cuddT(f),support); + zddSupportStep(Cudd_Regular(cuddE(f)),support); + /* Mark as visited. */ + f->next = Cudd_Not(f->next); + return; + +} /* end of zddSupportStep */ + + +/**Function******************************************************************** + + Synopsis [Performs a DFS from f, clearing the LSB of the next + pointers.] + + Description [] + + SideEffects [None] + + SeeAlso [zddSupportStep] + +******************************************************************************/ +static void +zddClearFlag( + DdNode * f) +{ + if (!Cudd_IsComplement(f->next)) { + return; + } + /* Clear visited flag. */ + f->next = Cudd_Regular(f->next); + if (cuddIsConstant(f)) { + return; + } + zddClearFlag(cuddT(f)); + zddClearFlag(Cudd_Regular(cuddE(f))); + return; + +} /* end of zddClearFlag */ + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.doc b/resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.doc new file mode 100644 index 000000000..7a9169b19 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.doc @@ -0,0 +1,6776 @@ +The cudd package + +The University of Colorado decision diagram package. + +Fabio Somenzi + +********************************************************************** + +Cudd_AddHook() Adds a function to a hook. + +Cudd_ApaAdd() Adds two arbitrary precision integers. + +Cudd_ApaCompareRatios() Compares the ratios of two arbitrary precision + integers to two unsigned ints. + +Cudd_ApaCompare() Compares two arbitrary precision integers. + +Cudd_ApaCopy() Makes a copy of an arbitrary precision integer. + +Cudd_ApaCountMinterm() Counts the number of minterms of a DD. + +Cudd_ApaIntDivision() Divides an arbitrary precision integer by an + integer. + +Cudd_ApaNumberOfDigits() Finds the number of digits for an arbitrary + precision integer. + +Cudd_ApaPowerOfTwo() Sets an arbitrary precision integer to a power + of two. + +Cudd_ApaPrintDecimal() Prints an arbitrary precision integer in + decimal format. + +Cudd_ApaPrintDensity() Prints the density of a BDD or ADD using + arbitrary precision arithmetic. + +Cudd_ApaPrintExponential() Prints an arbitrary precision integer in + exponential format. + +Cudd_ApaPrintHex() Prints an arbitrary precision integer in + hexadecimal format. + +Cudd_ApaPrintMintermExp() Prints the number of minterms of a BDD or ADD + in exponential format using arbitrary + precision arithmetic. + +Cudd_ApaPrintMinterm() Prints the number of minterms of a BDD or ADD + using arbitrary precision arithmetic. + +Cudd_ApaSetToLiteral() Sets an arbitrary precision integer to a one- + digit literal. + +Cudd_ApaShiftRight() Shifts right an arbitrary precision integer by + one binary place. + +Cudd_ApaShortDivision() Divides an arbitrary precision integer by a + digit. + +Cudd_ApaSubtract() Subtracts two arbitrary precision integers. + +Cudd_AutodynDisableZdd() Disables automatic dynamic reordering of ZDDs. + +Cudd_AutodynDisable() Disables automatic dynamic reordering. + +Cudd_AutodynEnableZdd() Enables automatic dynamic reordering of ZDDs. + +Cudd_AutodynEnable() Enables automatic dynamic reordering of BDDs + and ADDs. + +Cudd_AverageDistance() Computes the average distance between adjacent + nodes. + +Cudd_BddToAdd() Converts a BDD to a 0-1 ADD. + +Cudd_BddToCubeArray() Builds a positional array from the BDD of a + cube. + +Cudd_BiasedOverApprox() Extracts a dense superset from a BDD with the + biased underapproximation method. + +Cudd_BiasedUnderApprox() Extracts a dense subset from a BDD with the + biased underapproximation method. + +Cudd_CProjection() Computes the compatible projection of R w.r.t. + cube Y. + +Cudd_CheckCube() Checks whether g is the BDD of a cube. + +Cudd_CheckKeys() Checks for several conditions that should not + occur. + +Cudd_CheckZeroRef() Checks the unique table for nodes with non-zero + reference counts. + +Cudd_ClassifySupport() Classifies the variables in the support of two + DDs. + +Cudd_ClearErrorCode() Clear the error code of a manager. + +Cudd_CofMinterm() Computes the fraction of minterms in the on-set + of all the positive cofactors of a BDD or + ADD. + +Cudd_Cofactor() Computes the cofactor of f with respect to g. + +Cudd_CountLeaves() Counts the number of leaves in a DD. + +Cudd_CountMinterm() Counts the number of minterms of a DD. + +Cudd_CountPathsToNonZero() Counts the number of paths to a non-zero + terminal of a DD. + +Cudd_CountPath() Counts the number of paths of a DD. + +Cudd_CubeArrayToBdd() Builds the BDD of a cube from a positional + array. + +Cudd_DagSize() Counts the number of nodes in a DD. + +Cudd_DeadAreCounted() Tells whether dead nodes are counted towards + triggering reordering. + +Cudd_DebugCheck() Checks for inconsistencies in the DD heap. + +Cudd_Decreasing() Determines whether a BDD is negative unate in a + variable. + +Cudd_DelayedDerefBdd() Decreases the reference count of BDD node n. + +Cudd_Density() Computes the density of a BDD or ADD. + +Cudd_Deref() Decreases the reference count of node. + +Cudd_DisableGarbageCollection() + Disables garbage collection. + +Cudd_DisableOrderingMonitoring() + Disables monitoring of ordering. + +Cudd_DisableReorderingReporting() + Disables reporting of reordering stats. + +Cudd_Disequality() Generates a BDD for the function x - y != c. + +Cudd_DumpBlifBody() Writes a blif body representing the argument + BDDs. + +Cudd_DumpBlif() Writes a blif file representing the argument + BDDs. + +Cudd_DumpDDcal() Writes a DDcal file representing the argument + BDDs. + +Cudd_DumpDaVinci() Writes a daVinci file representing the argument + BDDs. + +Cudd_DumpDot() Writes a dot file representing the argument + DDs. + +Cudd_DumpFactoredForm() Writes factored forms representing the argument + BDDs. + +Cudd_Dxygtdxz() Generates a BDD for the function d(x,y) > + d(x,z). + +Cudd_Dxygtdyz() Generates a BDD for the function d(x,y) > + d(y,z). + +Cudd_EnableGarbageCollection() Enables garbage collection. + +Cudd_EnableOrderingMonitoring() + Enables monitoring of ordering. + +Cudd_EnableReorderingReporting() + Enables reporting of reordering stats. + +Cudd_EpdCountMinterm() Counts the number of minterms of a DD with + extended precision. + +Cudd_EqualSupNorm() Compares two ADDs for equality within + tolerance. + +Cudd_EquivDC() Tells whether F and G are identical wherever D + is 0. + +Cudd_EstimateCofactorSimple() Estimates the number of nodes in a cofactor of + a DD. + +Cudd_EstimateCofactor() Estimates the number of nodes in a cofactor of + a DD. + +Cudd_Eval() Returns the value of a DD for a given variable + assignment. + +Cudd_ExpectedUsedSlots() Computes the expected fraction of used slots in + the unique table. + +Cudd_FindEssential() Finds the essential variables of a DD. + +Cudd_FindTwoLiteralClauses() Finds the two literal clauses of a DD. + +Cudd_FirstCube() Finds the first cube of a decision diagram. + +Cudd_FirstNode() Finds the first node of a decision diagram. + +Cudd_FirstPrime() Finds the first prime of a Boolean function. + +Cudd_FreeTree() Frees the variable group tree of the manager. + +Cudd_FreeZddTree() Frees the variable group tree of the manager. + +Cudd_GarbageCollectionEnabled() + Tells whether garbage collection is enabled. + +Cudd_GenFree() Frees a CUDD generator. + +Cudd_IncreaseTimeLimit() Increases the time limit for the manager. + +Cudd_Increasing() Determines whether a BDD is positive unate in a + variable. + +Cudd_IndicesToCube() Builds a cube of BDD variables from an array of + indices. + +Cudd_Inequality() Generates a BDD for the function x - y ≥ c. + +Cudd_Init() Creates a new DD manager. + +Cudd_IsGenEmpty() Queries the status of a generator. + +Cudd_IsInHook() Checks whether a function is in a hook. + +Cudd_IsNonConstant() Returns 1 if a DD node is not constant. + +Cudd_IterDerefBdd() Decreases the reference count of BDD node n. + +Cudd_LargestCube() Finds a largest cube in a DD. + +Cudd_MakeBddFromZddCover() Converts a ZDD cover to a BDD. + +Cudd_MakeTreeNode() Creates a new variable group. + +Cudd_MakeZddTreeNode() Creates a new ZDD variable group. + +Cudd_MinHammingDist() Returns the minimum Hamming distance between f + and minterm. + +Cudd_NewApaNumber() Allocates memory for an arbitrary precision + integer. + +Cudd_NextCube() Generates the next cube of a decision diagram + onset. + +Cudd_NextNode() Finds the next node of a decision diagram. + +Cudd_NextPrime() Generates the next prime of a Boolean function. + +Cudd_NodeReadIndex() Returns the index of the node. + +Cudd_OrderingMonitoring() Returns 1 if monitoring of ordering is enabled. + +Cudd_OutOfMem() Warns that a memory allocation failed. + +Cudd_OverApprox() Extracts a dense superset from a BDD with + Shiple's underapproximation method. + +Cudd_Prime() Returns the next prime >= p. + +Cudd_PrintDebug() Prints to the standard output a DD and its + statistics. + +Cudd_PrintGroupedOrder() Hook function to print the current variable + order. + +Cudd_PrintInfo() Prints out statistics and settings for a CUDD + manager. + +Cudd_PrintLinear() Prints the linear transform matrix. + +Cudd_PrintMinterm() Prints a disjoint sum of products. + +Cudd_PrintTwoLiteralClauses() Prints the two literal clauses of a DD. + +Cudd_PrintVersion() Prints the package version number. + +Cudd_PrioritySelect() Selects pairs from R using a priority function. + +Cudd_Quit() Deletes resources associated with a DD manager. + +Cudd_Random() Portable random number generator. + +Cudd_ReadArcviolation() Returns the current value of the arcviolation + parameter used in group sifting. + +Cudd_ReadBackground() Reads the background constant of the manager. + +Cudd_ReadCacheHits() Returns the number of cache hits. + +Cudd_ReadCacheLookUps() Returns the number of cache look-ups. + +Cudd_ReadCacheSlots() Reads the number of slots in the cache. + +Cudd_ReadCacheUsedSlots() Reads the fraction of used slots in the cache. + +Cudd_ReadDead() Returns the number of dead nodes in the unique + table. + +Cudd_ReadElapsedTime() Returns the time elapsed since the start time + of the manager. + +Cudd_ReadEpsilon() Reads the epsilon parameter of the manager. + +Cudd_ReadErrorCode() Returns the code of the last error. + +Cudd_ReadGarbageCollectionTime() + Returns the time spent in garbage collection. + +Cudd_ReadGarbageCollections() Returns the number of times garbage collection + has occurred. + +Cudd_ReadGroupcheck() Reads the groupcheck parameter of the manager. + +Cudd_ReadInvPermZdd() Returns the index of the ZDD variable currently + in the i-th position of the order. + +Cudd_ReadInvPerm() Returns the index of the variable currently in + the i-th position of the order. + +Cudd_ReadIthClause() Accesses the i-th clause of a DD. + +Cudd_ReadKeys() Returns the number of nodes in the unique + table. + +Cudd_ReadLinear() Reads an entry of the linear transform matrix. + +Cudd_ReadLogicZero() Returns the logic zero constant of the manager. + +Cudd_ReadLooseUpTo() Reads the looseUpTo parameter of the manager. + +Cudd_ReadMaxCacheHard() Reads the maxCacheHard parameter of the + manager. + +Cudd_ReadMaxCache() Returns the soft limit for the cache size. + +Cudd_ReadMaxGrowthAlternate() Reads the maxGrowthAlt parameter of the + manager. + +Cudd_ReadMaxGrowth() Reads the maxGrowth parameter of the manager. + +Cudd_ReadMaxLive() Reads the maximum allowed number of live nodes. + +Cudd_ReadMaxMemory() Reads the maximum allowed memory. + +Cudd_ReadMaxReorderings() Returns the maximum number of times reordering + may be invoked. + +Cudd_ReadMemoryInUse() Returns the memory in use by the manager + measured in bytes. + +Cudd_ReadMinDead() Reads the minDead parameter of the manager. + +Cudd_ReadMinHit() Reads the hit rate that causes resizinig of the + computed table. + +Cudd_ReadMinusInfinity() Reads the minus-infinity constant from the + manager. + +Cudd_ReadNextReordering() Returns the threshold for the next dynamic + reordering. + +Cudd_ReadNodeCount() Reports the number of nodes in BDDs and ADDs. + +Cudd_ReadNodesDropped() Returns the number of nodes dropped. + +Cudd_ReadNodesFreed() Returns the number of nodes freed. + +Cudd_ReadNumberXovers() Reads the current number of crossovers used by + the genetic algorithm for reordering. + +Cudd_ReadOne() Returns the one constant of the manager. + +Cudd_ReadOrderRandomization() Returns the order randomization factor. + +Cudd_ReadPeakLiveNodeCount() Reports the peak number of live nodes. + +Cudd_ReadPeakNodeCount() Reports the peak number of nodes. + +Cudd_ReadPermZdd() Returns the current position of the i-th ZDD + variable in the order. + +Cudd_ReadPerm() Returns the current position of the i-th + variable in the order. + +Cudd_ReadPlusInfinity() Reads the plus-infinity constant from the + manager. + +Cudd_ReadPopulationSize() Reads the current size of the population used + by the genetic algorithm for reordering. + +Cudd_ReadRecomb() Returns the current value of the recombination + parameter used in group sifting. + +Cudd_ReadRecursiveCalls() Returns the number of recursive calls. + +Cudd_ReadReorderingCycle() Reads the reordCycle parameter of the manager. + +Cudd_ReadReorderingTime() Returns the time spent in reordering. + +Cudd_ReadReorderings() Returns the number of times reordering has + occurred. + +Cudd_ReadSiftMaxSwap() Reads the siftMaxSwap parameter of the manager. + +Cudd_ReadSiftMaxVar() Reads the siftMaxVar parameter of the manager. + +Cudd_ReadSize() Returns the number of BDD variables in + existance. + +Cudd_ReadSlots() Returns the total number of slots of the unique + table. + +Cudd_ReadStartTime() Returns the start time of the manager. + +Cudd_ReadStderr() Reads the stderr of a manager. + +Cudd_ReadStdout() Reads the stdout of a manager. + +Cudd_ReadSwapSteps() Reads the number of elementary reordering + steps. + +Cudd_ReadSymmviolation() Returns the current value of the symmviolation + parameter used in group sifting. + +Cudd_ReadTimeLimit() Returns the time limit for the manager. + +Cudd_ReadTree() Returns the variable group tree of the manager. + +Cudd_ReadUniqueLinks() Returns the number of links followed in the + unique table. + +Cudd_ReadUniqueLookUps() Returns the number of look-ups in the unique + table. + +Cudd_ReadUsedSlots() Reads the fraction of used slots in the unique + table. + +Cudd_ReadVars() Returns the i-th element of the vars array. + +Cudd_ReadZddOne() Returns the ZDD for the constant 1 function. + +Cudd_ReadZddSize() Returns the number of ZDD variables in + existance. + +Cudd_ReadZddTree() Returns the variable group tree of the manager. + +Cudd_ReadZero() Returns the zero constant of the manager. + +Cudd_RecursiveDerefZdd() Decreases the reference count of ZDD node n. + +Cudd_RecursiveDeref() Decreases the reference count of node n. + +Cudd_ReduceHeap() Main dynamic reordering routine. + +Cudd_Ref() Increases the reference count of a node, if it + is not saturated. + +Cudd_RemapOverApprox() Extracts a dense superset from a BDD with the + remapping underapproximation method. + +Cudd_RemapUnderApprox() Extracts a dense subset from a BDD with the + remapping underapproximation method. + +Cudd_RemoveHook() Removes a function from a hook. + +Cudd_ReorderingReporting() Returns 1 if reporting of reordering stats is + enabled. + +Cudd_ReorderingStatusZdd() Reports the status of automatic dynamic + reordering of ZDDs. + +Cudd_ReorderingStatus() Reports the status of automatic dynamic + reordering of BDDs and ADDs. + +Cudd_Reserve() Expand manager without creating variables. + +Cudd_ResetStartTime() Resets the start time of the manager. + +Cudd_SetArcviolation() Sets the value of the arcviolation parameter + used in group sifting. + +Cudd_SetBackground() Sets the background constant of the manager. + +Cudd_SetEpsilon() Sets the epsilon parameter of the manager to + ep. + +Cudd_SetGroupcheck() Sets the parameter groupcheck of the manager to + gc. + +Cudd_SetLooseUpTo() Sets the looseUpTo parameter of the manager. + +Cudd_SetMaxCacheHard() Sets the maxCacheHard parameter of the manager. + +Cudd_SetMaxGrowthAlternate() Sets the maxGrowthAlt parameter of the manager. + +Cudd_SetMaxGrowth() Sets the maxGrowth parameter of the manager. + +Cudd_SetMaxLive() Sets the maximum allowed number of live nodes. + +Cudd_SetMaxMemory() Sets the maximum allowed memory. + +Cudd_SetMaxReorderings() Sets the maximum number of times reordering may + be invoked. + +Cudd_SetMinHit() Sets the hit rate that causes resizinig of the + computed table. + +Cudd_SetNextReordering() Sets the threshold for the next dynamic + reordering. + +Cudd_SetNumberXovers() Sets the number of crossovers used by the + genetic algorithm for reordering. + +Cudd_SetOrderRandomization() Sets the order randomization factor. + +Cudd_SetPopulationSize() Sets the size of the population used by the + genetic algorithm for reordering. + +Cudd_SetRecomb() Sets the value of the recombination parameter + used in group sifting. + +Cudd_SetReorderingCycle() Sets the reordCycle parameter of the manager. + +Cudd_SetSiftMaxSwap() Sets the siftMaxSwap parameter of the manager. + +Cudd_SetSiftMaxVar() Sets the siftMaxVar parameter of the manager. + +Cudd_SetStartTime() Sets the start time of the manager. + +Cudd_SetStderr() Sets the stderr of a manager. + +Cudd_SetStdout() Sets the stdout of a manager. + +Cudd_SetSymmviolation() Sets the value of the symmviolation parameter + used in group sifting. + +Cudd_SetTimeLimit() Sets the time limit for the manager. + +Cudd_SetTree() Sets the variable group tree of the manager. + +Cudd_SetVarMap() Registers a variable mapping with the manager. + +Cudd_SetZddTree() Sets the ZDD variable group tree of the + manager. + +Cudd_SharingSize() Counts the number of nodes in an array of DDs. + +Cudd_ShortestLength() Find the length of the shortest path(s) in a + DD. + +Cudd_ShortestPath() Finds a shortest path in a DD. + +Cudd_ShuffleHeap() Reorders variables according to given + permutation. + +Cudd_SolveEqn() Implements the solution of F(x,y) = 0. + +Cudd_SplitSet() Returns m minterms from a BDD. + +Cudd_Srandom() Initializer for the portable random number + generator. + +Cudd_StdPostReordHook() Sample hook function to call after reordering. + +Cudd_StdPreReordHook() Sample hook function to call before reordering. + +Cudd_SubsetCompress() Find a dense subset of BDD f. + +Cudd_SubsetHeavyBranch() Extracts a dense subset from a BDD with the + heavy branch heuristic. + +Cudd_SubsetShortPaths() Extracts a dense subset from a BDD with the + shortest paths heuristic. + +Cudd_SubsetWithMaskVars() Extracts a subset from a BDD. + +Cudd_SupersetCompress() Find a dense superset of BDD f. + +Cudd_SupersetHeavyBranch() Extracts a dense superset from a BDD with the + heavy branch heuristic. + +Cudd_SupersetShortPaths() Extracts a dense superset from a BDD with the + shortest paths heuristic. + +Cudd_SupportIndex() Finds the variables on which a DD depends. + +Cudd_SupportIndices() Finds the variables on which a DD depends. + +Cudd_SupportSize() Counts the variables on which a DD depends. + +Cudd_Support() Finds the variables on which a DD depends. + +Cudd_SymmProfile() Prints statistics on symmetric variables. + +Cudd_TimeLimited() Returns true if the time limit for the manager + is set. + +Cudd_TurnOffCountDead() Causes the dead nodes not to be counted towards + triggering reordering. + +Cudd_TurnOnCountDead() Causes the dead nodes to be counted towards + triggering reordering. + +Cudd_UnderApprox() Extracts a dense subset from a BDD with + Shiple's underapproximation method. + +Cudd_UnsetTimeLimit() Unsets the time limit for the manager. + +Cudd_UpdateTimeLimit() Updates the time limit for the manager. + +Cudd_VectorSupportIndex() Finds the variables on which a set of DDs + depends. + +Cudd_VectorSupportIndices() Finds the variables on which a set of DDs + depends. + +Cudd_VectorSupportSize() Counts the variables on which a set of DDs + depends. + +Cudd_VectorSupport() Finds the variables on which a set of DDs + depends. + +Cudd_VerifySol() Checks the solution of F(x,y) = 0. + +Cudd_Xeqy() Generates a BDD for the function x==y. + +Cudd_Xgty() Generates a BDD for the function x > y. + +Cudd_addAgreement() f if f==g; background if f!=g. + +Cudd_addApply() Applies op to the corresponding discriminants + of f and g. + +Cudd_addBddInterval() Converts an ADD to a BDD. + +Cudd_addBddIthBit() Converts an ADD to a BDD by extracting the i-th + bit from the leaves. + +Cudd_addBddPattern() Converts an ADD to a BDD. + +Cudd_addBddStrictThreshold() Converts an ADD to a BDD. + +Cudd_addBddThreshold() Converts an ADD to a BDD. + +Cudd_addCmpl() Computes the complement of an ADD a la C + language. + +Cudd_addCompose() Substitutes g for x_v in the ADD for f. + +Cudd_addComputeCube() Computes the cube of an array of ADD variables. + +Cudd_addConstrain() Computes f constrain c for ADDs. + +Cudd_addConst() Returns the ADD for constant c. + +Cudd_addDiff() Returns plusinfinity if f=g; returns min(f,g) + if f!=g. + +Cudd_addDivide() Integer and floating point division. + +Cudd_addEvalConst() Checks whether ADD g is constant whenever ADD f + is 1. + +Cudd_addExistAbstract() Existentially Abstracts all the variables in + cube from f. + +Cudd_addFindMax() Finds the maximum discriminant of f. + +Cudd_addFindMin() Finds the minimum discriminant of f. + +Cudd_addGeneralVectorCompose() Composes an ADD with a vector of ADDs. + +Cudd_addHamming() Computes the Hamming distance ADD. + +Cudd_addHarwell() Reads in a matrix in the format of the Harwell- + Boeing benchmark suite. + +Cudd_addIteConstant() Implements ITEconstant for ADDs. + +Cudd_addIte() Implements ITE(f,g,h). + +Cudd_addIthBit() Extracts the i-th bit from an ADD. + +Cudd_addIthVar() Returns the ADD variable with index i. + +Cudd_addLeq() Determines whether f is less than or equal to + g. + +Cudd_addLog() Natural logarithm of an ADD. + +Cudd_addMatrixMultiply() Calculates the product of two matrices + represented as ADDs. + +Cudd_addMaximum() Integer and floating point max. + +Cudd_addMinimum() Integer and floating point min. + +Cudd_addMinus() Integer and floating point subtraction. + +Cudd_addMonadicApply() Applies op to the discriminants of f. + +Cudd_addNand() NAND of two 0-1 ADDs. + +Cudd_addNegate() Computes the additive inverse of an ADD. + +Cudd_addNewVarAtLevel() Returns a new ADD variable at a specified + level. + +Cudd_addNewVar() Returns a new ADD variable. + +Cudd_addNonSimCompose() Composes an ADD with a vector of 0-1 ADDs. + +Cudd_addNor() NOR of two 0-1 ADDs. + +Cudd_addOneZeroMaximum() Returns 1 if f > g and 0 otherwise. + +Cudd_addOrAbstract() Disjunctively abstracts all the variables in + cube from the 0-1 ADD f. + +Cudd_addOr() Disjunction of two 0-1 ADDs. + +Cudd_addOuterSum() Takes the minimum of a matrix and the outer sum + of two vectors. + +Cudd_addPermute() Permutes the variables of an ADD. + +Cudd_addPlus() Integer and floating point addition. + +Cudd_addRead() Reads in a sparse matrix. + +Cudd_addResidue() Builds an ADD for the residue modulo m of an n- + bit number. + +Cudd_addRestrict() ADD restrict according to Coudert and Madre's + algorithm (ICCAD90). + +Cudd_addRoundOff() Rounds off the discriminants of an ADD. + +Cudd_addScalarInverse() Computes the scalar inverse of an ADD. + +Cudd_addSetNZ() This operator sets f to the value of g wherever + g != 0. + +Cudd_addSwapVariables() Swaps two sets of variables of the same size (x + and y) in the ADD f. + +Cudd_addThreshold() f if f>=g; 0 if f d(x,z); x, y, and + z are N-bit numbers, x[0] x[1] ... x[N-1], y[0] y[1] ... y[N-1], and z[0] + z[1] ... z[N-1], with 0 the most significant bit. The distance d(x,y) is + defined as: sum_{i=0}^{N-1}(|x_i - y_i| cdot 2^{N-i-1}). The BDD is built + bottom-up. It has 7*N-3 internal nodes, if the variables are ordered as + follows: x[0] y[0] z[0] x[1] y[1] z[1] ... x[N-1] y[N-1] z[N-1]. + + Side Effects: None + +DdNode * +Cudd_Dxygtdyz( + DdManager * dd, DD manager + int N, number of x, y, and z variables + DdNode ** x, array of x variables + DdNode ** y, array of y variables + DdNode ** z array of z variables +) + This function generates a BDD for the function d(x,y) > d(y,z); x, y, and + z are N-bit numbers, x[0] x[1] ... x[N-1], y[0] y[1] ... y[N-1], and z[0] + z[1] ... z[N-1], with 0 the most significant bit. The distance d(x,y) is + defined as: sum_{i=0}^{N-1}(|x_i - y_i| cdot 2^{N-i-1}). The BDD is built + bottom-up. It has 7*N-3 internal nodes, if the variables are ordered as + follows: x[0] y[0] z[0] x[1] y[1] z[1] ... x[N-1] y[N-1] z[N-1]. + + Side Effects: None + +void +Cudd_EnableGarbageCollection( + DdManager * dd +) + Enables garbage collection. Garbage collection is initially enabled. + Therefore it is necessary to call this function only if garbage collection + has been explicitly disabled. + + Side Effects: None + +int +Cudd_EnableOrderingMonitoring( + DdManager * dd +) + Enables monitoring of ordering. Returns 1 if successful; 0 otherwise. + + Side Effects: Installs functions in the pre-reordering and post-reordering + hooks. + +int +Cudd_EnableReorderingReporting( + DdManager * dd +) + Enables reporting of reordering stats. Returns 1 if successful; 0 otherwise. + + Side Effects: Installs functions in the pre-reordering and post-reordering + hooks. + +int +Cudd_EpdCountMinterm( + DdManager * manager, + DdNode * node, + int nvars, + EpDouble * epd +) + Counts the number of minterms of a DD with extended precision. The function + is assumed to depend on nvars variables. The minterm count is represented as + an EpDouble, to allow any number of variables. Returns 0 if successful; + CUDD_OUT_OF_MEM otherwise. + + Side Effects: None + +int +Cudd_EqualSupNorm( + DdManager * dd, manager + DdNode * f, first ADD + DdNode * g, second ADD + CUDD_VALUE_TYPE tolerance, maximum allowed difference + int pr verbosity level +) + Compares two ADDs for equality within tolerance. Two ADDs are reported to be + equal if the maximum difference between them (the sup norm of their + difference) is less than or equal to the tolerance parameter. Returns 1 if + the two ADDs are equal (within tolerance); 0 otherwise. If parameter + pr is positive the first failure is reported to the standard + output. + + Side Effects: None + +int +Cudd_EquivDC( + DdManager * dd, + DdNode * F, + DdNode * G, + DdNode * D +) + Tells whether F and G are identical wherever D is 0. F and G are either two + ADDs or two BDDs. D is either a 0-1 ADD or a BDD. The function returns 1 if + F and G are equivalent, and 0 otherwise. No new nodes are created. + + Side Effects: None + +int +Cudd_EstimateCofactorSimple( + DdNode * node, + int i +) + Estimates the number of nodes in a cofactor of a DD. Returns an estimate of + the number of nodes in the positive cofactor of the graph rooted at node + with respect to the variable whose index is i. This procedure implements + with minor changes the algorithm of Cabodi et al. (ICCAD96). It does not + allocate any memory, it does not change the state of the manager, and it is + fast. However, it has been observed to overestimate the size of the cofactor + by as much as a factor of 2. + + Side Effects: None + +int +Cudd_EstimateCofactor( + DdManager * dd, manager + DdNode * f, function + int i, index of variable + int phase 1: positive; 0: negative +) + Estimates the number of nodes in a cofactor of a DD. Returns an estimate of + the number of nodes in a cofactor of the graph rooted at node with respect + to the variable whose index is i. In case of failure, returns + CUDD_OUT_OF_MEM. This function uses a refinement of the algorithm of Cabodi + et al. (ICCAD96). The refinement allows the procedure to account for part of + the recombination that may occur in the part of the cofactor above the + cofactoring variable. This procedure does not create any new node. It does + keep a small table of results; therefore it may run out of memory. If this + is a concern, one should use Cudd_EstimateCofactorSimple, which is faster, + does not allocate any memory, but is less accurate. + + Side Effects: None + +DdNode * +Cudd_Eval( + DdManager * dd, + DdNode * f, + int * inputs +) + Finds the value of a DD for a given variable assignment. The variable + assignment is passed in an array of int's, that should specify a zero or a + one for each variable in the support of the function. Returns a pointer to a + constant node. No new nodes are produced. + + Side Effects: None + +double +Cudd_ExpectedUsedSlots( + DdManager * dd +) + Computes the fraction of slots in the unique table that should be in use. + This expected value is based on the assumption that the hash function + distributes the keys randomly; it can be compared with the result of + Cudd_ReadUsedSlots to monitor the performance of the unique table hash + function. + + Side Effects: None + +DdNode * +Cudd_FindEssential( + DdManager * dd, + DdNode * f +) + Returns the cube of the essential variables. A positive literal means that + the variable must be set to 1 for the function to be 1. A negative literal + means that the variable must be set to 0 for the function to be 1. Returns a + pointer to the cube BDD if successful; NULL otherwise. + + Side Effects: None + +DdTlcInfo * +Cudd_FindTwoLiteralClauses( + DdManager * dd, + DdNode * f +) + Returns the one- and two-literal clauses of a DD. Returns a pointer to the + structure holding the clauses if successful; NULL otherwise. For a constant + DD, the empty set of clauses is returned. This is obviously correct for a + non-zero constant. For the constant zero, it is based on the assumption that + only those clauses containing variables in the support of the function are + considered. Since the support of a constant function is empty, no clauses + are returned. + + Side Effects: None + +DdGen * +Cudd_FirstCube( + DdManager * dd, + DdNode * f, + int ** cube, + CUDD_VALUE_TYPE * value +) + Defines an iterator on the onset of a decision diagram and finds its first + cube. Returns a generator that contains the information necessary to + continue the enumeration if successful; NULL otherwise. A cube is + represented as an array of literals, which are integers in {0, 1, 2}; 0 + represents a complemented literal, 1 represents an uncomplemented literal, + and 2 stands for don't care. The enumeration produces a disjoint cover of + the function associated with the diagram. The size of the array equals the + number of variables in the manager at the time Cudd_FirstCube is called. + For each cube, a value is also returned. This value is always 1 for a BDD, + while it may be different from 1 for an ADD. For BDDs, the offset is the set + of cubes whose value is the logical zero. For ADDs, the offset is the set of + cubes whose value is the background value. The cubes of the offset are not + enumerated. + + Side Effects: The first cube and its value are returned as side effects. + +DdGen * +Cudd_FirstNode( + DdManager * dd, + DdNode * f, + DdNode ** node +) + Defines an iterator on the nodes of a decision diagram and finds its first + node. Returns a generator that contains the information necessary to + continue the enumeration if successful; NULL otherwise. The nodes are + enumerated in a reverse topological order, so that a node is always preceded + in the enumeration by its descendants. + + Side Effects: The first node is returned as a side effect. + +DdGen * +Cudd_FirstPrime( + DdManager * dd, + DdNode * l, + DdNode * u, + int ** cube +) + Defines an iterator on a pair of BDDs describing a (possibly incompletely + specified) Boolean functions and finds the first cube of a cover of the + function. Returns a generator that contains the information necessary to + continue the enumeration if successful; NULL otherwise. The two argument + BDDs are the lower and upper bounds of an interval. It is a mistake to call + this function with a lower bound that is not less than or equal to the upper + bound. A cube is represented as an array of literals, which are integers + in {0, 1, 2}; 0 represents a complemented literal, 1 represents an + uncomplemented literal, and 2 stands for don't care. The enumeration + produces a prime and irredundant cover of the function associated with the + two BDDs. The size of the array equals the number of variables in the + manager at the time Cudd_FirstCube is called. This iterator can only be + used on BDDs. + + Side Effects: The first cube is returned as side effect. + +void +Cudd_FreeTree( + DdManager * dd +) + Frees the variable group tree of the manager. + + Side Effects: None + +void +Cudd_FreeZddTree( + DdManager * dd +) + Frees the variable group tree of the manager. + + Side Effects: None + +int +Cudd_GarbageCollectionEnabled( + DdManager * dd +) + Returns 1 if garbage collection is enabled; 0 otherwise. + + Side Effects: None + +int +Cudd_GenFree( + DdGen * gen +) + Frees a CUDD generator. Always returns 0, so that it can be used in mis-like + foreach constructs. + + Side Effects: None + +void +Cudd_IncreaseTimeLimit( + DdManager * unique, + unsigned long increase +) + Increases the time limit for the manager. + + Side Effects: None + +DdNode * +Cudd_Increasing( + DdManager * dd, + DdNode * f, + int i +) + Determines whether the function represented by BDD f is positive unate + (monotonic increasing) in variable i. It is based on Cudd_Decreasing and the + fact that f is monotonic increasing in i if and only if its complement is + monotonic decreasing in i. + + Side Effects: None + +DdNode * +Cudd_IndicesToCube( + DdManager * dd, + int * array, + int n +) + Builds a cube of BDD variables from an array of indices. Returns a pointer + to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_Inequality( + DdManager * dd, DD manager + int N, number of x and y variables + int c, right-hand side constant + DdNode ** x, array of x variables + DdNode ** y array of y variables +) + This function generates a BDD for the function x -y ≥ c. Both x and y are + N-bit numbers, x[0] x[1] ... x[N-1] and y[0] y[1] ... y[N-1], with 0 the + most significant bit. The BDD is built bottom-up. It has a linear number of + nodes if the variables are ordered as follows: x[0] y[0] x[1] y[1] ... x[N- + 1] y[N-1]. + + Side Effects: None + +DdManager * +Cudd_Init( + unsigned int numVars, initial number of BDD variables (i.e., + subtables) + unsigned int numVarsZ, initial number of ZDD variables (i.e., + subtables) + unsigned int numSlots, initial size of the unique tables + unsigned int cacheSize, initial size of the cache + unsigned long maxMemory target maximum memory occupation +) + Creates a new DD manager, initializes the table, the basic constants and the + projection functions. If maxMemory is 0, Cudd_Init decides suitable values + for the maximum size of the cache and for the limit for fast unique table + growth based on the available memory. Returns a pointer to the manager if + successful; NULL otherwise. + + Side Effects: None + +int +Cudd_IsGenEmpty( + DdGen * gen +) + Queries the status of a generator. Returns 1 if the generator is empty or + NULL; 0 otherswise. + + Side Effects: None + +int +Cudd_IsInHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where +) + Checks whether a function is in a hook. A hook is a list of application- + provided functions called on certain occasions by the package. Returns 1 if + the function is found; 0 otherwise. + + Side Effects: None + +int +Cudd_IsNonConstant( + DdNode * f +) + Returns 1 if a DD node is not constant. This function is useful to test the + results of Cudd_bddIteConstant, Cudd_addIteConstant, Cudd_addEvalConst. + These results may be a special value signifying non-constant. In the other + cases the macro Cudd_IsConstant can be used. + + Side Effects: None + +void +Cudd_IterDerefBdd( + DdManager * table, + DdNode * n +) + Decreases the reference count of node n. If n dies, recursively decreases + the reference counts of its children. It is used to dispose of a BDD that is + no longer needed. It is more efficient than Cudd_RecursiveDeref, but it + cannot be used on ADDs. The greater efficiency comes from being able to + assume that no constant node will ever die as a result of a call to this + procedure. + + Side Effects: None + +DdNode * +Cudd_LargestCube( + DdManager * manager, + DdNode * f, + int * length +) + Finds a largest cube in a DD. f is the DD we want to get the largest cube + for. The problem is translated into the one of finding a shortest path in f, + when both THEN and ELSE arcs are assumed to have unit length. This yields a + largest cube in the disjoint cover corresponding to the DD. Therefore, it is + not necessarily the largest implicant of f. Returns the largest cube as a + BDD. + + Side Effects: The number of literals of the cube is returned in the location + pointed by length if it is non-null. + +DdNode * +Cudd_MakeBddFromZddCover( + DdManager * dd, + DdNode * node +) + Converts a ZDD cover to a BDD for the function represented by the cover. If + successful, it returns a BDD node, otherwise it returns NULL. + + +MtrNode * +Cudd_MakeTreeNode( + DdManager * dd, manager + unsigned int low, index of the first group variable + unsigned int size, number of variables in the group + unsigned int type MTR_DEFAULT or MTR_FIXED +) + Creates a new variable group. The group starts at variable low and contains + size variables. The parameter low is the index of the first variable. If the + variable already exists, its current position in the order is known to the + manager. If the variable does not exist yet, the position is assumed to be + the same as the index. The group tree is created if it does not exist yet. + Returns a pointer to the group if successful; NULL otherwise. + + Side Effects: The variable tree is changed. + +MtrNode * +Cudd_MakeZddTreeNode( + DdManager * dd, manager + unsigned int low, index of the first group variable + unsigned int size, number of variables in the group + unsigned int type MTR_DEFAULT or MTR_FIXED +) + Creates a new ZDD variable group. The group starts at variable and contains + size variables. The parameter low is the index of the first variable. If the + variable already exists, its current position in the order is known to the + manager. If the variable does not exist yet, the position is assumed to be + the same as the index. The group tree is created if it does not exist yet. + Returns a pointer to the group if successful; NULL otherwise. + + Side Effects: The ZDD variable tree is changed. + +int +Cudd_MinHammingDist( + DdManager * dd, DD manager + DdNode * f, function to examine + int * minterm, reference minterm + int upperBound distance above which an approximate + answer is OK +) + Returns the minimum Hamming distance between the minterms of a function f + and a reference minterm. The function is given as a BDD; the minterm is + given as an array of integers, one for each variable in the manager. Returns + the minimum distance if it is less than the upper bound; the upper bound if + the minimum distance is at least as large; CUDD_OUT_OF_MEM in case of + failure. + + Side Effects: None + +DdApaNumber +Cudd_NewApaNumber( + int digits +) + Allocates memory for an arbitrary precision integer. Returns a pointer to + the allocated memory if successful; NULL otherwise. + + Side Effects: None + +int +Cudd_NextCube( + DdGen * gen, + int ** cube, + CUDD_VALUE_TYPE * value +) + Generates the next cube of a decision diagram onset, using generator gen. + Returns 0 if the enumeration is completed; 1 otherwise. + + Side Effects: The cube and its value are returned as side effects. The + generator is modified. + +int +Cudd_NextNode( + DdGen * gen, + DdNode ** node +) + Finds the node of a decision diagram, using generator gen. Returns 0 if the + enumeration is completed; 1 otherwise. + + Side Effects: The next node is returned as a side effect. + +int +Cudd_NextPrime( + DdGen * gen, + int ** cube +) + Generates the next cube of a Boolean function, using generator gen. Returns + 0 if the enumeration is completed; 1 otherwise. + + Side Effects: The cube and is returned as side effects. The generator is + modified. + +unsigned int +Cudd_NodeReadIndex( + DdNode * node +) + Returns the index of the node. The node pointer can be either regular or + complemented. + + Side Effects: None + +int +Cudd_OrderingMonitoring( + DdManager * dd +) + Returns 1 if monitoring of ordering is enabled; 0 otherwise. + + Side Effects: none + +void +Cudd_OutOfMem( + long size size of the allocation that failed +) + Warns that a memory allocation failed. This function can be used as + replacement of MMout_of_memory to prevent the safe_mem functions of the util + package from exiting when malloc returns NULL. One possible use is in case + of discretionary allocations; for instance, the allocation of memory to + enlarge the computed table. + + Side Effects: None + +DdNode * +Cudd_OverApprox( + DdManager * dd, manager + DdNode * f, function to be superset + int numVars, number of variables in the support of f + int threshold, when to stop approximation + int safe, enforce safe approximation + double quality minimum improvement for accepted changes +) + Extracts a dense superset from a BDD. The procedure is identical to the + underapproximation procedure except for the fact that it works on the + complement of the given function. Extracting the subset of the complement + function is equivalent to extracting the superset of the function. Returns a + pointer to the BDD of the superset if successful. NULL if intermediate + result causes the procedure to run out of memory. The parameter numVars is + the maximum number of variables to be used in minterm calculation. The + optimal number should be as close as possible to the size of the support of + f. However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is larger + than 1023, it will overflow. If a 0 parameter is passed then the procedure + will compute a value which will avoid overflow but will cause underflow with + 2046 variables or more. + + Side Effects: None + +unsigned int +Cudd_Prime( + unsigned int p +) + Returns the next prime >= p. + + Side Effects: None + +int +Cudd_PrintDebug( + DdManager * dd, + DdNode * f, + int n, + int pr +) + Prints to the standard output a DD and its statistics. The statistics + include the number of nodes, the number of leaves, and the number of + minterms. (The number of minterms is the number of assignments to the + variables that cause the function to be different from the logical zero (for + BDDs) and from the background value (for ADDs.) The statistics are printed + if pr > 0. Specifically: pr = 0 : prints nothing pr = 1 : + prints counts of nodes and minterms pr = 2 : prints counts + disjoint + sum of product pr = 3 : prints counts + list of nodes pr > 3 : + prints counts + disjoint sum of product + list of nodes For the + purpose of counting the number of minterms, the function is supposed to + depend on n variables. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_PrintGroupedOrder( + DdManager * dd, + const char * str, + void * data +) + Hook function to print the current variable order. It may be called before + or after reordering. Prints on the manager's stdout a parenthesized list + that describes the variable groups. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_PrintInfo( + DdManager * dd, + FILE * fp +) + Prints out statistics and settings for a CUDD manager. Returns 1 if + successful; 0 otherwise. + + Side Effects: None + +int +Cudd_PrintLinear( + DdManager * table +) + Prints the linear transform matrix. Returns 1 in case of success; 0 + otherwise. + + Side Effects: none + +int +Cudd_PrintMinterm( + DdManager * manager, + DdNode * node +) + Prints a disjoint sum of product cover for the function rooted at node. Each + product corresponds to a path from node to a leaf node different from the + logical zero, and different from the background value. Uses the package + default output file. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_PrintTwoLiteralClauses( + DdManager * dd, + DdNode * f, + char ** names, + FILE * fp +) + Prints the one- and two-literal clauses. Returns 1 if successful; 0 + otherwise. The argument "names" can be NULL, in which case the variable + indices are printed. + + Side Effects: None + +void +Cudd_PrintVersion( + FILE * fp +) + Prints the package version number. + + Side Effects: None + +DdNode * +Cudd_PrioritySelect( + DdManager * dd, manager + DdNode * R, BDD of the relation + DdNode ** x, array of x variables + DdNode ** y, array of y variables + DdNode ** z, array of z variables (optional: may be + NULL) + DdNode * Pi, BDD of the priority function (optional: + may be NULL) + int n, size of x, y, and z + DD_PRFP Pifunc function used to build Pi if it is NULL +) + Selects pairs from a relation R(x,y) (given as a BDD) in such a way that a + given x appears in one pair only. Uses a priority function to determine + which y should be paired to a given x. Cudd_PrioritySelect returns a pointer + to the selected function if successful; NULL otherwise. Three of the + arguments--x, y, and z--are vectors of BDD variables. The first two are the + variables on which R depends. The third vector is a vector of auxiliary + variables, used during the computation. This vector is optional. If a NULL + value is passed instead, Cudd_PrioritySelect will create the working + variables on the fly. The sizes of x and y (and z if it is not NULL) should + equal n. The priority function Pi can be passed as a BDD, or can be built by + Cudd_PrioritySelect. If NULL is passed instead of a DdNode *, parameter + Pifunc is used by Cudd_PrioritySelect to build a BDD for the priority + function. (Pifunc is a pointer to a C function.) If Pi is not NULL, then + Pifunc is ignored. Pifunc should have the same interface as the standard + priority functions (e.g., Cudd_Dxygtdxz). Cudd_PrioritySelect and + Cudd_CProjection can sometimes be used interchangeably. Specifically, + calling Cudd_PrioritySelect with Cudd_Xgty as Pifunc produces the same + result as calling Cudd_CProjection with the all-zero minterm as reference + minterm. However, depending on the application, one or the other may be + preferable: When extracting representatives from an equivalence + relation, Cudd_CProjection has the advantage of nor requiring the auxiliary + variables. When computing matchings in general bipartite graphs, + Cudd_PrioritySelect normally obtains better results because it can use more + powerful matching schemes (e.g., Cudd_Dxygtdxz). + + Side Effects: If called with z == NULL, will create new variables in the + manager. + +void +Cudd_Quit( + DdManager * unique +) + Deletes resources associated with a DD manager and resets the global + statistical counters. (Otherwise, another manaqger subsequently created + would inherit the stats of this one.) + + Side Effects: None + +long +Cudd_Random( + +) + Portable number generator based on ran2 from "Numerical Recipes in C." It is + a long period (> 2 * 10^18) random number generator of L'Ecuyer with Bays- + Durham shuffle. Returns a long integer uniformly distributed between 0 and + 2147483561 (inclusive of the endpoint values). The random generator can be + explicitly initialized by calling Cudd_Srandom. If no explicit + initialization is performed, then the seed 1 is assumed. + + Side Effects: None + +int +Cudd_ReadArcviolation( + DdManager * dd +) + Returns the current value of the arcviolation parameter. This parameter is + used in group sifting to decide how many arcs into y not coming + from x are tolerable when checking for aggregation due to + extended symmetry. The value should be between 0 and 100. A small value + causes fewer variables to be aggregated. The default value is 0. + + Side Effects: None + +DdNode * +Cudd_ReadBackground( + DdManager * dd +) + Reads the background constant of the manager. + + Side Effects: None + +double +Cudd_ReadCacheHits( + DdManager * dd +) + Returns the number of cache hits. + + Side Effects: None + +double +Cudd_ReadCacheLookUps( + DdManager * dd +) + Returns the number of cache look-ups. + + Side Effects: None + +unsigned int +Cudd_ReadCacheSlots( + DdManager * dd +) + Reads the number of slots in the cache. + + Side Effects: None + +double +Cudd_ReadCacheUsedSlots( + DdManager * dd +) + Reads the fraction of used slots in the cache. The unused slots are those in + which no valid data is stored. Garbage collection, variable reordering, and + cache resizing may cause used slots to become unused. + + Side Effects: None + +unsigned int +Cudd_ReadDead( + DdManager * dd +) + Returns the number of dead nodes in the unique table. + + Side Effects: None + +unsigned long +Cudd_ReadElapsedTime( + DdManager * unique +) + Returns the time elapsed since the start time of the manager. + + Side Effects: None + +CUDD_VALUE_TYPE +Cudd_ReadEpsilon( + DdManager * dd +) + Reads the epsilon parameter of the manager. The epsilon parameter control + the comparison between floating point numbers. + + Side Effects: None + +Cudd_ErrorType +Cudd_ReadErrorCode( + DdManager * dd +) + Returns the code of the last error. The error codes are defined in cudd.h. + + Side Effects: None + +long +Cudd_ReadGarbageCollectionTime( + DdManager * dd +) + Returns the number of milliseconds spent doing garbage collection since the + manager was initialized. + + Side Effects: None + +int +Cudd_ReadGarbageCollections( + DdManager * dd +) + Returns the number of times garbage collection has occurred in the manager. + The number includes both the calls from reordering procedures and those + caused by requests to create new nodes. + + Side Effects: None + +Cudd_AggregationType +Cudd_ReadGroupcheck( + DdManager * dd +) + Reads the groupcheck parameter of the manager. The groupcheck parameter + determines the aggregation criterion in group sifting. + + Side Effects: None + +int +Cudd_ReadInvPermZdd( + DdManager * dd, + int i +) + Returns the index of the ZDD variable currently in the i-th position of the + order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; + otherwise, if the index is out of bounds returns -1. + + Side Effects: None + +int +Cudd_ReadInvPerm( + DdManager * dd, + int i +) + Returns the index of the variable currently in the i-th position of the + order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; + otherwise, if the index is out of bounds returns -1. + + Side Effects: None + +int +Cudd_ReadIthClause( + DdTlcInfo * tlc, + int i, + DdHalfWord * var1, + DdHalfWord * var2, + int * phase1, + int * phase2 +) + Accesses the i-th clause of a DD given the clause set which must be already + computed. Returns 1 if successful; 0 if i is out of range, or in case of + error. + + Side Effects: the four components of a clause are returned as side effects. + +unsigned int +Cudd_ReadKeys( + DdManager * dd +) + Returns the total number of nodes currently in the unique table, including + the dead nodes. + + Side Effects: None + +int +Cudd_ReadLinear( + DdManager * table, CUDD manager + int x, row index + int y column index +) + Reads an entry of the linear transform matrix. + + Side Effects: none + +DdNode * +Cudd_ReadLogicZero( + DdManager * dd +) + Returns the zero constant of the manager. The logic zero constant is the + complement of the one constant, and is distinct from the arithmetic zero. + + Side Effects: None + +unsigned int +Cudd_ReadLooseUpTo( + DdManager * dd +) + Reads the looseUpTo parameter of the manager. + + Side Effects: None + +unsigned int +Cudd_ReadMaxCacheHard( + DdManager * dd +) + Reads the maxCacheHard parameter of the manager. + + Side Effects: None + +unsigned int +Cudd_ReadMaxCache( + DdManager * dd +) + Returns the soft limit for the cache size. + + Side Effects: None + +double +Cudd_ReadMaxGrowthAlternate( + DdManager * dd +) + Reads the maxGrowthAlt parameter of the manager. This parameter is analogous + to the maxGrowth paramter, and is used every given number of reorderings + instead of maxGrowth. The number of reorderings is set with + Cudd_SetReorderingCycle. If the number of reorderings is 0 (default) + maxGrowthAlt is never used. + + Side Effects: None + +double +Cudd_ReadMaxGrowth( + DdManager * dd +) + Reads the maxGrowth parameter of the manager. This parameter determines how + much the number of nodes can grow during sifting of a variable. Overall, + sifting never increases the size of the decision diagrams. This parameter + only refers to intermediate results. A lower value will speed up sifting, + possibly at the expense of quality. + + Side Effects: None + +unsigned int +Cudd_ReadMaxLive( + DdManager * dd +) + Reads the maximum allowed number of live nodes. When this number is + exceeded, the package returns NULL. + + Side Effects: none + +unsigned long +Cudd_ReadMaxMemory( + DdManager * dd +) + Reads the maximum allowed memory. When this number is exceeded, the package + returns NULL. + + Side Effects: none + +unsigned int +Cudd_ReadMaxReorderings( + DdManager * dd +) + Returns the maximum number of times reordering may be invoked in this + manager. + + Side Effects: None + +unsigned long +Cudd_ReadMemoryInUse( + DdManager * dd +) + Returns the memory in use by the manager measured in bytes. + + Side Effects: None + +unsigned int +Cudd_ReadMinDead( + DdManager * dd +) + Reads the minDead parameter of the manager. The minDead parameter is used by + the package to decide whether to collect garbage or resize a subtable of the + unique table when the subtable becomes too full. The application can + indirectly control the value of minDead by setting the looseUpTo parameter. + + Side Effects: None + +unsigned int +Cudd_ReadMinHit( + DdManager * dd +) + Reads the hit rate that causes resizinig of the computed table. + + Side Effects: None + +DdNode * +Cudd_ReadMinusInfinity( + DdManager * dd +) + Reads the minus-infinity constant from the manager. + + Side Effects: None + +unsigned int +Cudd_ReadNextReordering( + DdManager * dd +) + Returns the threshold for the next dynamic reordering. The threshold is in + terms of number of nodes and is in effect only if reordering is enabled. The + count does not include the dead nodes, unless the countDead parameter of the + manager has been changed from its default setting. + + Side Effects: None + +long +Cudd_ReadNodeCount( + DdManager * dd +) + Reports the number of live nodes in BDDs and ADDs. This number does not + include the isolated projection functions and the unused constants. These + nodes that are not counted are not part of the DDs manipulated by the + application. + + Side Effects: None + +double +Cudd_ReadNodesDropped( + DdManager * dd +) + Returns the number of nodes killed by dereferencing if the keeping of this + statistic is enabled; -1 otherwise. This statistic is enabled only if the + package is compiled with DD_STATS defined. + + Side Effects: None + +double +Cudd_ReadNodesFreed( + DdManager * dd +) + Returns the number of nodes returned to the free list if the keeping of this + statistic is enabled; -1 otherwise. This statistic is enabled only if the + package is compiled with DD_STATS defined. + + Side Effects: None + +int +Cudd_ReadNumberXovers( + DdManager * dd +) + Reads the current number of crossovers used by the genetic algorithm for + variable reordering. A larger number of crossovers will cause the genetic + algorithm to take more time, but will generally produce better results. The + default value is 0, in which case the package uses three times the number of + variables as number of crossovers, with a maximum of 60. + + Side Effects: None + +DdNode * +Cudd_ReadOne( + DdManager * dd +) + Returns the one constant of the manager. The one constant is common to ADDs + and BDDs. + + Side Effects: None + +unsigned int +Cudd_ReadOrderRandomization( + DdManager * dd +) + Returns the order randomization factor. If non-zero this factor is used to + determine a perturbation of the next reordering threshold. Larger factors + cause larger perturbations. + + Side Effects: None + +int +Cudd_ReadPeakLiveNodeCount( + DdManager * dd +) + Reports the peak number of live nodes. + + Side Effects: None + +long +Cudd_ReadPeakNodeCount( + DdManager * dd +) + Reports the peak number of nodes. This number includes node on the free + list. At the peak, the number of nodes on the free list is guaranteed to be + less than DD_MEM_CHUNK. + + Side Effects: None + +int +Cudd_ReadPermZdd( + DdManager * dd, + int i +) + Returns the current position of the i-th ZDD variable in the order. If the + index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index + is out of bounds returns -1. + + Side Effects: None + +int +Cudd_ReadPerm( + DdManager * dd, + int i +) + Returns the current position of the i-th variable in the order. If the index + is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index is + out of bounds returns -1. + + Side Effects: None + +DdNode * +Cudd_ReadPlusInfinity( + DdManager * dd +) + Reads the plus-infinity constant from the manager. + + Side Effects: None + +int +Cudd_ReadPopulationSize( + DdManager * dd +) + Reads the current size of the population used by the genetic algorithm for + variable reordering. A larger population size will cause the genetic + algorithm to take more time, but will generally produce better results. The + default value is 0, in which case the package uses three times the number of + variables as population size, with a maximum of 120. + + Side Effects: None + +int +Cudd_ReadRecomb( + DdManager * dd +) + Returns the current value of the recombination parameter used in group + sifting. A larger (positive) value makes the aggregation of variables due to + the second difference criterion more likely. A smaller (negative) value + makes aggregation less likely. + + Side Effects: None + +double +Cudd_ReadRecursiveCalls( + DdManager * dd +) + Returns the number of recursive calls if the package is compiled with + DD_COUNT defined. + + Side Effects: None + +int +Cudd_ReadReorderingCycle( + DdManager * dd +) + Reads the reordCycle parameter of the manager. This parameter determines how + often the alternate threshold on maximum growth is used in reordering. + + Side Effects: None + +long +Cudd_ReadReorderingTime( + DdManager * dd +) + Returns the number of milliseconds spent reordering variables since the + manager was initialized. The time spent in collecting garbage before + reordering is included. + + Side Effects: None + +unsigned int +Cudd_ReadReorderings( + DdManager * dd +) + Returns the number of times reordering has occurred in the manager. The + number includes both the calls to Cudd_ReduceHeap from the application + program and those automatically performed by the package. However, calls + that do not even initiate reordering are not counted. A call may not + initiate reordering if there are fewer than minsize live nodes in the + manager, or if CUDD_REORDER_NONE is specified as reordering method. The + calls to Cudd_ShuffleHeap are not counted. + + Side Effects: None + +int +Cudd_ReadSiftMaxSwap( + DdManager * dd +) + Reads the siftMaxSwap parameter of the manager. This parameter gives the + maximum number of swaps that will be attempted for each invocation of + sifting. The real number of swaps may exceed the set limit because the + package will always complete the sifting of the variable that causes the + limit to be reached. + + Side Effects: None + +int +Cudd_ReadSiftMaxVar( + DdManager * dd +) + Reads the siftMaxVar parameter of the manager. This parameter gives the + maximum number of variables that will be sifted for each invocation of + sifting. + + Side Effects: None + +int +Cudd_ReadSize( + DdManager * dd +) + Returns the number of BDD variables in existance. + + Side Effects: None + +unsigned int +Cudd_ReadSlots( + DdManager * dd +) + Returns the total number of slots of the unique table. This number ismainly + for diagnostic purposes. + + Side Effects: None + +unsigned long +Cudd_ReadStartTime( + DdManager * unique +) + Returns the start time of the manager. This is initially set to the number + of milliseconds since the program started, but may be reset by the + application. + + Side Effects: None + +FILE * +Cudd_ReadStderr( + DdManager * dd +) + Reads the stderr of a manager. This is the file pointer to which messages + normally going to stderr are written. It is initialized to stderr. + Cudd_SetStderr allows the application to redirect it. + + Side Effects: None + +FILE * +Cudd_ReadStdout( + DdManager * dd +) + Reads the stdout of a manager. This is the file pointer to which messages + normally going to stdout are written. It is initialized to stdout. + Cudd_SetStdout allows the application to redirect it. + + Side Effects: None + +double +Cudd_ReadSwapSteps( + DdManager * dd +) + Reads the number of elementary reordering steps. + + Side Effects: none + +int +Cudd_ReadSymmviolation( + DdManager * dd +) + Returns the current value of the symmviolation parameter. This parameter is + used in group sifting to decide how many violations to the symmetry + conditions f10 = f01 or f11 = f00 are tolerable + when checking for aggregation due to extended symmetry. The value should be + between 0 and 100. A small value causes fewer variables to be aggregated. + The default value is 0. + + Side Effects: None + +unsigned long +Cudd_ReadTimeLimit( + DdManager * unique +) + Returns the time limit for the manager. This is initially set to a very + large number, but may be reset by the application. + + Side Effects: None + +MtrNode * +Cudd_ReadTree( + DdManager * dd +) + Returns the variable group tree of the manager. + + Side Effects: None + +double +Cudd_ReadUniqueLinks( + DdManager * dd +) + Returns the number of links followed during look-ups in the unique table if + the keeping of this statistic is enabled; -1 otherwise. If an item is found + in the first position of its collision list, the number of links followed is + taken to be 0. If it is in second position, the number of links is 1, and so + on. This statistic is enabled only if the package is compiled with + DD_UNIQUE_PROFILE defined. + + Side Effects: None + +double +Cudd_ReadUniqueLookUps( + DdManager * dd +) + Returns the number of look-ups in the unique table if the keeping of this + statistic is enabled; -1 otherwise. This statistic is enabled only if the + package is compiled with DD_UNIQUE_PROFILE defined. + + Side Effects: None + +double +Cudd_ReadUsedSlots( + DdManager * dd +) + Reads the fraction of used slots in the unique table. The unused slots are + those in which no valid data is stored. Garbage collection, variable + reordering, and subtable resizing may cause used slots to become unused. + + Side Effects: None + +DdNode * +Cudd_ReadVars( + DdManager * dd, + int i +) + Returns the i-th element of the vars array if it falls within the array + bounds; NULL otherwise. If i is the index of an existing variable, this + function produces the same result as Cudd_bddIthVar. However, if the i-th + var does not exist yet, Cudd_bddIthVar will create it, whereas Cudd_ReadVars + will not. + + Side Effects: None + +DdNode * +Cudd_ReadZddOne( + DdManager * dd, + int i +) + Returns the ZDD for the constant 1 function. The representation of the + constant 1 function as a ZDD depends on how many variables it (nominally) + depends on. The index of the topmost variable in the support is given as + argument i. + + Side Effects: None + +int +Cudd_ReadZddSize( + DdManager * dd +) + Returns the number of ZDD variables in existance. + + Side Effects: None + +MtrNode * +Cudd_ReadZddTree( + DdManager * dd +) + Returns the variable group tree of the manager. + + Side Effects: None + +DdNode * +Cudd_ReadZero( + DdManager * dd +) + Returns the zero constant of the manager. The zero constant is the + arithmetic zero, rather than the logic zero. The latter is the complement of + the one constant. + + Side Effects: None + +void +Cudd_RecursiveDerefZdd( + DdManager * table, + DdNode * n +) + Decreases the reference count of ZDD node n. If n dies, recursively + decreases the reference counts of its children. It is used to dispose of a + ZDD that is no longer needed. + + Side Effects: None + +void +Cudd_RecursiveDeref( + DdManager * table, + DdNode * n +) + Decreases the reference count of node n. If n dies, recursively decreases + the reference counts of its children. It is used to dispose of a DD that is + no longer needed. + + Side Effects: None + +int +Cudd_ReduceHeap( + DdManager * table, DD manager + Cudd_ReorderingTy heuristic, method used for reordering + int minsize bound below which no reordering occurs +) + Main dynamic reordering routine. Calls one of the possible reordering + procedures: Swapping Sifting Symmetric Sifting Group + Sifting Window Permutation Simulated Annealing Genetic Algorithm + Dynamic Programming (exact) For sifting, symmetric sifting, group + sifting, and window permutation it is possible to request reordering to + convergence. The core of all methods is the reordering procedure + cuddSwapInPlace() which swaps two adjacent variables and is based on + Rudell's paper. Returns 1 in case of success; 0 otherwise. In the case of + symmetric sifting (with and without convergence) returns 1 plus the number + of symmetric variables, in case of success. + + Side Effects: Changes the variable order for all diagrams and clears the + cache. + +void +Cudd_Ref( + DdNode * n +) + Increases the reference count of a node, if it is not saturated. + + Side Effects: None + +DdNode * +Cudd_RemapOverApprox( + DdManager * dd, manager + DdNode * f, function to be superset + int numVars, number of variables in the support of f + int threshold, when to stop approximation + double quality minimum improvement for accepted changes +) + Extracts a dense superset from a BDD. The procedure is identical to the + underapproximation procedure except for the fact that it works on the + complement of the given function. Extracting the subset of the complement + function is equivalent to extracting the superset of the function. Returns a + pointer to the BDD of the superset if successful. NULL if intermediate + result causes the procedure to run out of memory. The parameter numVars is + the maximum number of variables to be used in minterm calculation. The + optimal number should be as close as possible to the size of the support of + f. However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is larger + than 1023, it will overflow. If a 0 parameter is passed then the procedure + will compute a value which will avoid overflow but will cause underflow with + 2046 variables or more. + + Side Effects: None + +DdNode * +Cudd_RemapUnderApprox( + DdManager * dd, manager + DdNode * f, function to be subset + int numVars, number of variables in the support of f + int threshold, when to stop approximation + double quality minimum improvement for accepted changes +) + Extracts a dense subset from a BDD. This procedure uses a remapping + technique and density as the cost function. Returns a pointer to the BDD of + the subset if successful. NULL if the procedure runs out of memory. The + parameter numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to the size + of the support of f. However, it is safe to pass the value returned by + Cudd_ReadSize for numVars when the number of variables is under 1023. If + numVars is larger than 1023, it will cause overflow. If a 0 parameter is + passed then the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more. + + Side Effects: None + +int +Cudd_RemoveHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where +) + Removes a function from a hook. A hook is a list of application-provided + functions called on certain occasions by the package. Returns 1 if + successful; 0 the function was not in the list. + + Side Effects: None + +int +Cudd_ReorderingReporting( + DdManager * dd +) + Returns 1 if reporting of reordering stats is enabled; 0 otherwise. + + Side Effects: none + +int +Cudd_ReorderingStatusZdd( + DdManager * unique, + Cudd_ReorderingTy method +) + Reports the status of automatic dynamic reordering of ZDDs. Parameter method + is set to the ZDD reordering method currently selected. Returns 1 if + automatic reordering is enabled; 0 otherwise. + + Side Effects: Parameter method is set to the ZDD reordering method currently + selected. + +int +Cudd_ReorderingStatus( + DdManager * unique, + Cudd_ReorderingTy method +) + Reports the status of automatic dynamic reordering of BDDs and ADDs. + Parameter method is set to the reordering method currently selected. Returns + 1 if automatic reordering is enabled; 0 otherwise. + + Side Effects: Parameter method is set to the reordering method currently + selected. + +int +Cudd_Reserve( + DdManager * manager, + int amount +) + Expand a manager by a specified number of subtables without actually + creating new variables. This function can be used to reduce the frequency of + resizing when an estimate of the number of variables is available. One would + call this function instead of passing the number of variables to Cudd_Init + if variables should not be created right away of if the estimate on their + number became available only after the manager has been created. Returns 1 + if successful; 0 otherwise. + + Side Effects: None + +void +Cudd_ResetStartTime( + DdManager * unique +) + Resets the start time of the manager. + + Side Effects: None + +void +Cudd_SetArcviolation( + DdManager * dd, + int arcviolation +) + Sets the value of the arcviolation parameter. This parameter is used in + group sifting to decide how many arcs into y not coming from + x are tolerable when checking for aggregation due to extended + symmetry. The value should be between 0 and 100. A small value causes fewer + variables to be aggregated. The default value is 0. + + Side Effects: None + +void +Cudd_SetBackground( + DdManager * dd, + DdNode * bck +) + Sets the background constant of the manager. It assumes that the DdNode + pointer bck is already referenced. + + Side Effects: None + +void +Cudd_SetEpsilon( + DdManager * dd, + CUDD_VALUE_TYPE ep +) + Sets the epsilon parameter of the manager to ep. The epsilon parameter + control the comparison between floating point numbers. + + Side Effects: None + +void +Cudd_SetGroupcheck( + DdManager * dd, + Cudd_AggregationT gc +) + Sets the parameter groupcheck of the manager to gc. The groupcheck parameter + determines the aggregation criterion in group sifting. + + Side Effects: None + +void +Cudd_SetLooseUpTo( + DdManager * dd, + unsigned int lut +) + Sets the looseUpTo parameter of the manager. This parameter of the manager + controls the threshold beyond which no fast growth of the unique table is + allowed. The threshold is given as a number of slots. If the value passed to + this function is 0, the function determines a suitable value based on the + available memory. + + Side Effects: None + +void +Cudd_SetMaxCacheHard( + DdManager * dd, + unsigned int mc +) + Sets the maxCacheHard parameter of the manager. The cache cannot grow larger + than maxCacheHard entries. This parameter allows an application to control + the trade-off of memory versus speed. If the value passed to this function + is 0, the function determines a suitable maximum cache size based on the + available memory. + + Side Effects: None + +void +Cudd_SetMaxGrowthAlternate( + DdManager * dd, + double mg +) + Sets the maxGrowthAlt parameter of the manager. This parameter is analogous + to the maxGrowth paramter, and is used every given number of reorderings + instead of maxGrowth. The number of reorderings is set with + Cudd_SetReorderingCycle. If the number of reorderings is 0 (default) + maxGrowthAlt is never used. + + Side Effects: None + +void +Cudd_SetMaxGrowth( + DdManager * dd, + double mg +) + Sets the maxGrowth parameter of the manager. This parameter determines how + much the number of nodes can grow during sifting of a variable. Overall, + sifting never increases the size of the decision diagrams. This parameter + only refers to intermediate results. A lower value will speed up sifting, + possibly at the expense of quality. + + Side Effects: None + +void +Cudd_SetMaxLive( + DdManager * dd, + unsigned int maxLive +) + Sets the maximum allowed number of live nodes. When this number is exceeded, + the package returns NULL. + + Side Effects: none + +void +Cudd_SetMaxMemory( + DdManager * dd, + unsigned long maxMemory +) + Sets the maximum allowed memory. When this number is exceeded, the package + returns NULL. + + Side Effects: none + +void +Cudd_SetMaxReorderings( + DdManager * dd, + unsigned int mr +) + Sets the maximum number of times reordering may be invoked in this manager. + The default value is (practically) infinite. + + Side Effects: None + +void +Cudd_SetMinHit( + DdManager * dd, + unsigned int hr +) + Sets the minHit parameter of the manager. This parameter controls the + resizing of the computed table. If the hit rate is larger than the specified + value, and the cache is not already too large, then its size is doubled. + + Side Effects: None + +void +Cudd_SetNextReordering( + DdManager * dd, + unsigned int next +) + Sets the threshold for the next dynamic reordering. The threshold is in + terms of number of nodes and is in effect only if reordering is enabled. The + count does not include the dead nodes, unless the countDead parameter of the + manager has been changed from its default setting. + + Side Effects: None + +void +Cudd_SetNumberXovers( + DdManager * dd, + int numberXovers +) + Sets the number of crossovers used by the genetic algorithm for variable + reordering. A larger number of crossovers will cause the genetic algorithm + to take more time, but will generally produce better results. The default + value is 0, in which case the package uses three times the number of + variables as number of crossovers, with a maximum of 60. + + Side Effects: None + +void +Cudd_SetOrderRandomization( + DdManager * dd, + unsigned int factor +) + Sets the order randomization factor. + + Side Effects: None + +void +Cudd_SetPopulationSize( + DdManager * dd, + int populationSize +) + Sets the size of the population used by the genetic algorithm for variable + reordering. A larger population size will cause the genetic algorithm to + take more time, but will generally produce better results. The default value + is 0, in which case the package uses three times the number of variables as + population size, with a maximum of 120. + + Side Effects: Changes the manager. + +void +Cudd_SetRecomb( + DdManager * dd, + int recomb +) + Sets the value of the recombination parameter used in group sifting. A + larger (positive) value makes the aggregation of variables due to the second + difference criterion more likely. A smaller (negative) value makes + aggregation less likely. The default value is 0. + + Side Effects: Changes the manager. + +void +Cudd_SetReorderingCycle( + DdManager * dd, + int cycle +) + Sets the reordCycle parameter of the manager. This parameter determines how + often the alternate threshold on maximum growth is used in reordering. + + Side Effects: None + +void +Cudd_SetSiftMaxSwap( + DdManager * dd, + int sms +) + Sets the siftMaxSwap parameter of the manager. This parameter gives the + maximum number of swaps that will be attempted for each invocation of + sifting. The real number of swaps may exceed the set limit because the + package will always complete the sifting of the variable that causes the + limit to be reached. + + Side Effects: None + +void +Cudd_SetSiftMaxVar( + DdManager * dd, + int smv +) + Sets the siftMaxVar parameter of the manager. This parameter gives the + maximum number of variables that will be sifted for each invocation of + sifting. + + Side Effects: None + +void +Cudd_SetStartTime( + DdManager * unique, + unsigned long st +) + Sets the start time of the manager. + + Side Effects: None + +void +Cudd_SetStderr( + DdManager * dd, + FILE * fp +) + Sets the stderr of a manager. + + Side Effects: None + +void +Cudd_SetStdout( + DdManager * dd, + FILE * fp +) + Sets the stdout of a manager. + + Side Effects: None + +void +Cudd_SetSymmviolation( + DdManager * dd, + int symmviolation +) + Sets the value of the symmviolation parameter. This parameter is used in + group sifting to decide how many violations to the symmetry conditions + f10 = f01 or f11 = f00 are tolerable when checking + for aggregation due to extended symmetry. The value should be between 0 and + 100. A small value causes fewer variables to be aggregated. The default + value is 0. + + Side Effects: Changes the manager. + +void +Cudd_SetTimeLimit( + DdManager * unique, + unsigned long tl +) + Sets the time limit for the manager. + + Side Effects: None + +void +Cudd_SetTree( + DdManager * dd, + MtrNode * tree +) + Sets the variable group tree of the manager. + + Side Effects: None + +int +Cudd_SetVarMap( + DdManager * manager, DD manager + DdNode ** x, first array of variables + DdNode ** y, second array of variables + int n length of both arrays +) + Registers with the manager a variable mapping described by two sets of + variables. This variable mapping is then used by functions like + Cudd_bddVarMap. This function is convenient for those applications that + perform the same mapping several times. However, if several different + permutations are used, it may be more efficient not to rely on the + registered mapping, because changing mapping causes the cache to be cleared. + (The initial setting, however, does not clear the cache.) The two sets of + variables (x and y) must have the same size (x and y). The size is given by + n. The two sets of variables are normally disjoint, but this restriction is + not imposeded by the function. When new variables are created, the map is + automatically extended (each new variable maps to itself). The typical use, + however, is to wait until all variables are created, and then create the + map. Returns 1 if the mapping is successfully registered with the manager; 0 + otherwise. + + Side Effects: Modifies the manager. May clear the cache. + +void +Cudd_SetZddTree( + DdManager * dd, + MtrNode * tree +) + Sets the ZDD variable group tree of the manager. + + Side Effects: None + +int +Cudd_SharingSize( + DdNode ** nodeArray, + int n +) + Counts the number of nodes in an array of DDs. Shared nodes are counted only + once. Returns the total number of nodes. + + Side Effects: None + +int +Cudd_ShortestLength( + DdManager * manager, + DdNode * f, + int * weight +) + Find the length of the shortest path(s) in a DD. f is the DD we want to get + the shortest path for; weight[i] is the weight of the THEN edge coming from + the node whose index is i. All ELSE edges have 0 weight. Returns the length + of the shortest path(s) if such a path is found; a large number if the + function is identically 0, and CUDD_OUT_OF_MEM in case of failure. + + Side Effects: None + +DdNode * +Cudd_ShortestPath( + DdManager * manager, + DdNode * f, + int * weight, + int * support, + int * length +) + Finds a shortest path in a DD. f is the DD we want to get the shortest path + for; weight[i] is the weight of the THEN arc coming from the node whose + index is i. If weight is NULL, then unit weights are assumed for all THEN + arcs. All ELSE arcs have 0 weight. If non-NULL, both weight and support + should point to arrays with at least as many entries as there are variables + in the manager. Returns the shortest path as the BDD of a cube. + + Side Effects: support contains on return the true support of f. If support + is NULL on entry, then Cudd_ShortestPath does not compute the true support + info. length contains the length of the path. + +int +Cudd_ShuffleHeap( + DdManager * table, DD manager + int * permutation required variable permutation +) + Reorders variables according to given permutation. The i-th entry of the + permutation array contains the index of the variable that should be brought + to the i-th level. The size of the array should be equal or greater to the + number of variables currently in use. Returns 1 in case of success; 0 + otherwise. + + Side Effects: Changes the variable order for all diagrams and clears the + cache. + +DdNode * +Cudd_SolveEqn( + DdManager * bdd, + DdNode * F, the left-hand side of the equation + DdNode * Y, the cube of the y variables + DdNode ** G, the array of solutions (return parameter) + int ** yIndex, index of y variables + int n numbers of unknowns +) + Implements the solution for F(x,y) = 0. The return value is the consistency + condition. The y variables are the unknowns and the remaining variables are + the parameters. Returns the consistency condition if successful; NULL + otherwise. Cudd_SolveEqn allocates an array and fills it with the indices of + the unknowns. This array is used by Cudd_VerifySol. + + Side Effects: The solution is returned in G; the indices of the y variables + are returned in yIndex. + +DdNode * +Cudd_SplitSet( + DdManager * manager, + DdNode * S, + DdNode ** xVars, + int n, + double m +) + Returns m minterms from a BDD whose support has n + variables at most. The procedure tries to create as few extra nodes as + possible. The function represented by S depends on at most + n of the variables in xVars. Returns a BDD with + m minterms of the on-set of S if successful; NULL otherwise. + + Side Effects: None + +void +Cudd_Srandom( + long seed +) + Initializer for the portable number generator based on ran2 in "Numerical + Recipes in C." The input is the seed for the generator. If it is negative, + its absolute value is taken as seed. If it is 0, then 1 is taken as seed. + The initialized sets up the two recurrences used to generate a long-period + stream, and sets up the shuffle table. + + Side Effects: None + +int +Cudd_StdPostReordHook( + DdManager * dd, + const char * str, + void * data +) + Sample hook function to call after reordering. Prints on the manager's + stdout final size and reordering time. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_StdPreReordHook( + DdManager * dd, + const char * str, + void * data +) + Sample hook function to call before reordering. Prints on the manager's + stdout reordering method and initial size. Returns 1 if successful; 0 + otherwise. + + Side Effects: None + +DdNode * +Cudd_SubsetCompress( + DdManager * dd, manager + DdNode * f, BDD whose subset is sought + int nvars, number of variables in the support of f + int threshold maximum number of nodes in the subset +) + Finds a dense subset of BDD f. Density is the ratio of number + of minterms to number of nodes. Uses several techniques in series. It is + more expensive than other subsetting procedures, but often produces better + results. See Cudd_SubsetShortPaths for a description of the threshold and + nvars parameters. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_SubsetHeavyBranch( + DdManager * dd, manager + DdNode * f, function to be subset + int numVars, number of variables in the support of f + int threshold maximum number of nodes in the subset +) + Extracts a dense subset from a BDD. This procedure builds a subset by + throwing away one of the children of each node, starting from the root, + until the result is small enough. The child that is eliminated from the + result is the one that contributes the fewer minterms. Returns a pointer to + the BDD of the subset if successful. NULL if the procedure runs out of + memory. The parameter numVars is the maximum number of variables to be used + in minterm calculation and node count calculation. The optimal number should + be as close as possible to the size of the support of f. However, it is safe + to pass the value returned by Cudd_ReadSize for numVars when the number of + variables is under 1023. If numVars is larger than 1023, it will overflow. + If a 0 parameter is passed then the procedure will compute a value which + will avoid overflow but will cause underflow with 2046 variables or more. + + Side Effects: None + +DdNode * +Cudd_SubsetShortPaths( + DdManager * dd, manager + DdNode * f, function to be subset + int numVars, number of variables in the support of f + int threshold, maximum number of nodes in the subset + int hardlimit flag: 1 if threshold is a hard limit +) + Extracts a dense subset from a BDD. This procedure tries to preserve the + shortest paths of the input BDD, because they give many minterms and + contribute few nodes. This procedure may increase the number of nodes in + trying to create the subset or reduce the number of nodes due to + recombination as compared to the original BDD. Hence the threshold may not + be strictly adhered to. In practice, recombination overshadows the increase + in the number of nodes and results in small BDDs as compared to the + threshold. The hardlimit specifies whether threshold needs to be strictly + adhered to. If it is set to 1, the procedure ensures that result is never + larger than the specified limit but may be considerably less than the + threshold. Returns a pointer to the BDD for the subset if successful; NULL + otherwise. The value for numVars should be as close as possible to the size + of the support of f for better efficiency. However, it is safe to pass the + value returned by Cudd_ReadSize for numVars. If 0 is passed, then the value + returned by Cudd_ReadSize is used. + + Side Effects: None + +DdNode * +Cudd_SubsetWithMaskVars( + DdManager * dd, manager + DdNode * f, function from which to pick a cube + DdNode ** vars, array of variables + int nvars, size of vars + DdNode ** maskVars, array of variables + int mvars size of maskVars +) + Extracts a subset from a BDD in the following procedure. 1. Compute the + weight for each mask variable by counting the number of minterms for both + positive and negative cofactors of the BDD with respect to each mask + variable. (weight = #positive - #negative) 2. Find a representative cube of + the BDD by using the weight. From the top variable of the BDD, for each + variable, if the weight is greater than 0.0, choose THEN branch, othereise + ELSE branch, until meeting the constant 1. 3. Quantify out the variables not + in maskVars from the representative cube and if a variable in maskVars is + don't care, replace the variable with a constant(1 or 0) depending on the + weight. 4. Make a subset of the BDD by multiplying with the modified cube. + + Side Effects: None + +DdNode * +Cudd_SupersetCompress( + DdManager * dd, manager + DdNode * f, BDD whose superset is sought + int nvars, number of variables in the support of f + int threshold maximum number of nodes in the superset +) + Finds a dense superset of BDD f. Density is the ratio of number + of minterms to number of nodes. Uses several techniques in series. It is + more expensive than other supersetting procedures, but often produces better + results. See Cudd_SupersetShortPaths for a description of the threshold and + nvars parameters. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_SupersetHeavyBranch( + DdManager * dd, manager + DdNode * f, function to be superset + int numVars, number of variables in the support of f + int threshold maximum number of nodes in the superset +) + Extracts a dense superset from a BDD. The procedure is identical to the + subset procedure except for the fact that it receives the complement of the + given function. Extracting the subset of the complement function is + equivalent to extracting the superset of the function. This procedure builds + a superset by throwing away one of the children of each node starting from + the root of the complement function, until the result is small enough. The + child that is eliminated from the result is the one that contributes the + fewer minterms. Returns a pointer to the BDD of the superset if successful. + NULL if intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in minterm + calculation and node count calculation. The optimal number should be as + close as possible to the size of the support of f. However, it is safe to + pass the value returned by Cudd_ReadSize for numVars when the number of + variables is under 1023. If numVars is larger than 1023, it will overflow. + If a 0 parameter is passed then the procedure will compute a value which + will avoid overflow but will cause underflow with 2046 variables or more. + + Side Effects: None + +DdNode * +Cudd_SupersetShortPaths( + DdManager * dd, manager + DdNode * f, function to be superset + int numVars, number of variables in the support of f + int threshold, maximum number of nodes in the subset + int hardlimit flag: 1 if threshold is a hard limit +) + Extracts a dense superset from a BDD. The procedure is identical to the + subset procedure except for the fact that it receives the complement of the + given function. Extracting the subset of the complement function is + equivalent to extracting the superset of the function. This procedure tries + to preserve the shortest paths of the complement BDD, because they give many + minterms and contribute few nodes. This procedure may increase the number of + nodes in trying to create the superset or reduce the number of nodes due to + recombination as compared to the original BDD. Hence the threshold may not + be strictly adhered to. In practice, recombination overshadows the increase + in the number of nodes and results in small BDDs as compared to the + threshold. The hardlimit specifies whether threshold needs to be strictly + adhered to. If it is set to 1, the procedure ensures that result is never + larger than the specified limit but may be considerably less than the + threshold. Returns a pointer to the BDD for the superset if successful; NULL + otherwise. The value for numVars should be as close as possible to the size + of the support of f for better efficiency. However, it is safe to pass the + value returned by Cudd_ReadSize for numVar. If 0 is passed, then the value + returned by Cudd_ReadSize is used. + + Side Effects: None + +int * +Cudd_SupportIndex( + DdManager * dd, manager + DdNode * f DD whose support is sought +) + Finds the variables on which a DD depends. Returns an index array of the + variables if successful; NULL otherwise. The size of the array equals the + number of variables in the manager. Each entry of the array is 1 if the + corresponding variable is in the support of the DD and 0 otherwise. + + Side Effects: None + +int +Cudd_SupportIndices( + DdManager * dd, manager + DdNode * f, DD whose support is sought + int ** indices array containing (on return) the indices +) + Finds the variables on which a DD depends. Returns the number of variables + if successful; CUDD_OUT_OF_MEM otherwise. + + Side Effects: The indices of the support variables are returned as side + effects. If the function is constant, no array is allocated. + +int +Cudd_SupportSize( + DdManager * dd, manager + DdNode * f DD whose support size is sought +) + Returns the variables on which a DD depends. + + Side Effects: None + +DdNode * +Cudd_Support( + DdManager * dd, manager + DdNode * f DD whose support is sought +) + Finds the variables on which a DD depends. Returns a BDD consisting of the + product of the variables if successful; NULL otherwise. + + Side Effects: None + +void +Cudd_SymmProfile( + DdManager * table, + int lower, + int upper +) + Prints statistics on symmetric variables. + + Side Effects: None + +int +Cudd_TimeLimited( + DdManager * unique +) + Returns true if the time limit for the manager is set. + + Side Effects: None + +void +Cudd_TurnOffCountDead( + DdManager * dd +) + Causes the dead nodes not to be counted towards triggering reordering. This + causes less frequent reorderings. By default dead nodes are not counted. + Therefore there is no need to call this function unless Cudd_TurnOnCountDead + has been previously called. + + Side Effects: Changes the manager. + +void +Cudd_TurnOnCountDead( + DdManager * dd +) + Causes the dead nodes to be counted towards triggering reordering. This + causes more frequent reorderings. By default dead nodes are not counted. + + Side Effects: Changes the manager. + +DdNode * +Cudd_UnderApprox( + DdManager * dd, manager + DdNode * f, function to be subset + int numVars, number of variables in the support of f + int threshold, when to stop approximation + int safe, enforce safe approximation + double quality minimum improvement for accepted changes +) + Extracts a dense subset from a BDD. This procedure uses a variant of Tom + Shiple's underapproximation method. The main difference from the original + method is that density is used as cost function. Returns a pointer to the + BDD of the subset if successful. NULL if the procedure runs out of memory. + The parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value returned + by Cudd_ReadSize for numVars when the number of variables is under 1023. If + numVars is larger than 1023, it will cause overflow. If a 0 parameter is + passed then the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more. + + Side Effects: None + +void +Cudd_UnsetTimeLimit( + DdManager * unique +) + Unsets the time limit for the manager. Actually, sets it to a very large + value. + + Side Effects: None + +void +Cudd_UpdateTimeLimit( + DdManager * unique +) + Updates the time limit for the manager by subtracting the elapsed time from + it. + + Side Effects: None + +int * +Cudd_VectorSupportIndex( + DdManager * dd, manager + DdNode ** F, array of DDs whose support is sought + int n size of the array +) + Finds the variables on which a set of DDs depends. The set must contain + either BDDs and ADDs, or ZDDs. Returns an index array of the variables if + successful; NULL otherwise. + + Side Effects: None + +int +Cudd_VectorSupportIndices( + DdManager * dd, manager + DdNode ** F, DD whose support is sought + int n, size of the array + int ** indices array containing (on return) the indices +) + Finds the variables on which a set of DDs depends. The set must contain + either BDDs and ADDs, or ZDDs. Returns the number of variables if + successful; CUDD_OUT_OF_MEM otherwise. + + Side Effects: The indices of the support variables are returned as side + effects. If the function is constant, no array is allocated. + +int +Cudd_VectorSupportSize( + DdManager * dd, manager + DdNode ** F, array of DDs whose support is sought + int n size of the array +) + Returns the variables on which a set of DDs depends. The set must contain + either BDDs and ADDs, or ZDDs. + + Side Effects: None + +DdNode * +Cudd_VectorSupport( + DdManager * dd, manager + DdNode ** F, array of DDs whose support is sought + int n size of the array +) + Finds the variables on which a set of DDs depends. The set must contain + either BDDs and ADDs, or ZDDs. Returns a BDD consisting of the product of + the variables if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_VerifySol( + DdManager * bdd, + DdNode * F, the left-hand side of the equation + DdNode ** G, the array of solutions + int * yIndex, index of y variables + int n numbers of unknowns +) + Checks the solution of F(x,y) = 0. This procedure substitutes the solution + components for the unknowns of F and returns the resulting BDD for F. + + Side Effects: Frees the memory pointed by yIndex. + +DdNode * +Cudd_Xeqy( + DdManager * dd, DD manager + int N, number of x and y variables + DdNode ** x, array of x variables + DdNode ** y array of y variables +) + This function generates a BDD for the function x==y. Both x and y are N-bit + numbers, x[0] x[1] ... x[N-1] and y[0] y[1] ... y[N-1], with 0 the most + significant bit. The BDD is built bottom-up. It has 3*N-1 internal nodes, if + the variables are ordered as follows: x[0] y[0] x[1] y[1] ... x[N-1] y[N-1]. + + Side Effects: None + +DdNode * +Cudd_Xgty( + DdManager * dd, DD manager + int N, number of x and y variables + DdNode ** z, array of z variables: unused + DdNode ** x, array of x variables + DdNode ** y array of y variables +) + This function generates a BDD for the function x > y. Both x and y are N- + bit numbers, x[0] x[1] ... x[N-1] and y[0] y[1] ... y[N-1], with 0 the most + significant bit. The BDD is built bottom-up. It has 3*N-1 internal nodes, if + the variables are ordered as follows: x[0] y[0] x[1] y[1] ... x[N-1] y[N-1]. + Argument z is not used by Cudd_Xgty: it is included to make it call- + compatible to Cudd_Dxygtdxz and Cudd_Dxygtdyz. + + Side Effects: None + +DdNode * +Cudd_addAgreement( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Returns NULL if not a terminal case; f op g otherwise, where f op g is f if + f==g; background if f!=g. + + Side Effects: None + +DdNode * +Cudd_addApply( + DdManager * dd, + DD_AOP op, + DdNode * f, + DdNode * g +) + Applies op to the corresponding discriminants of f and g. Returns a pointer + to the result if succssful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddInterval( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE lower, + CUDD_VALUE_TYPE upper +) + Converts an ADD to a BDD by replacing all discriminants greater than or + equal to lower and less than or equal to upper with 1, and all other + discriminants with 0. Returns a pointer to the resulting BDD if successful; + NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddIthBit( + DdManager * dd, + DdNode * f, + int bit +) + Converts an ADD to a BDD by replacing all discriminants whose i-th bit is + equal to 1 with 1, and all other discriminants with 0. The i-th bit refers + to the integer representation of the leaf value. If the value is has a + fractional part, it is ignored. Repeated calls to this procedure allow one + to transform an integer-valued ADD into an array of BDDs, one for each bit + of the leaf values. Returns a pointer to the resulting BDD if successful; + NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddPattern( + DdManager * dd, + DdNode * f +) + Converts an ADD to a BDD by replacing all discriminants different from 0 + with 1. Returns a pointer to the resulting BDD if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddStrictThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value +) + Converts an ADD to a BDD by replacing all discriminants STRICTLY greater + than value with 1, and all other discriminants with 0. Returns a pointer to + the resulting BDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value +) + Converts an ADD to a BDD by replacing all discriminants greater than or + equal to value with 1, and all other discriminants with 0. Returns a pointer + to the resulting BDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addCmpl( + DdManager * dd, + DdNode * f +) + Computes the complement of an ADD a la C language: The complement of 0 is 1 + and the complement of everything else is 0. Returns a pointer to the + resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addCompose( + DdManager * dd, + DdNode * f, + DdNode * g, + int v +) + Substitutes g for x_v in the ADD for f. v is the index of the variable to be + substituted. g must be a 0-1 ADD. Cudd_bddCompose passes the corresponding + projection function to the recursive procedure, so that the cache may be + used. Returns the composed ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addComputeCube( + DdManager * dd, + DdNode ** vars, + int * phase, + int n +) + Computes the cube of an array of ADD variables. If non-null, the phase + argument indicates which literal of each variable should appear in the cube. + If phase[i] is nonzero, then the positive literal is used. If phase is NULL, + the cube is positive unate. Returns a pointer to the result if successful; + NULL otherwise. + + Side Effects: none + +DdNode * +Cudd_addConstrain( + DdManager * dd, + DdNode * f, + DdNode * c +) + Computes f constrain c (f @ c), for f an ADD and c a 0-1 ADD. List of + special cases: F @ 0 = 0 F @ 1 = F 0 @ c = 0 1 @ c + = 1 F @ F = 1 Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_addConst( + DdManager * dd, + CUDD_VALUE_TYPE c +) + Retrieves the ADD for constant c if it already exists, or creates a new ADD. + Returns a pointer to the ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addDiff( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Returns NULL if not a terminal case; f op g otherwise, where f op g is + plusinfinity if f=g; min(f,g) if f!=g. + + Side Effects: None + +DdNode * +Cudd_addDivide( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point division. Returns NULL if not a terminal case; f + / g otherwise. + + Side Effects: None + +DdNode * +Cudd_addEvalConst( + DdManager * dd, + DdNode * f, + DdNode * g +) + Checks whether ADD g is constant whenever ADD f is 1. f must be a 0-1 ADD. + Returns a pointer to the resulting ADD (which may or may not be constant) or + DD_NON_CONSTANT. If f is identically 0, the check is assumed to be + successful, and the background value is returned. No new nodes are created. + + Side Effects: None + +DdNode * +Cudd_addExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube +) + Abstracts all the variables in cube from f by summing over all possible + values taken by the variables. Returns the abstracted ADD. + + Side Effects: None + +DdNode * +Cudd_addFindMax( + DdManager * dd, + DdNode * f +) + Returns a pointer to a constant ADD. + + Side Effects: None + +DdNode * +Cudd_addFindMin( + DdManager * dd, + DdNode * f +) + Returns a pointer to a constant ADD. + + Side Effects: None + +DdNode * +Cudd_addGeneralVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vectorOn, + DdNode ** vectorOff +) + Given a vector of ADDs, creates a new ADD by substituting the ADDs for the + variables of the ADD f. vectorOn contains ADDs to be substituted for the x_v + and vectorOff the ADDs to be substituted for x_v'. There should be an entry + in vector for each variable in the manager. If no substitution is sought for + a given variable, the corresponding projection function should be specified + in the vector. This function implements simultaneous composition. Returns a + pointer to the resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addHamming( + DdManager * dd, + DdNode ** xVars, + DdNode ** yVars, + int nVars +) + Computes the Hamming distance ADD. Returns an ADD that gives the Hamming + distance between its two arguments if successful; NULL otherwise. The two + vectors xVars and yVars identify the variables that form the two arguments. + + Side Effects: None + +int +Cudd_addHarwell( + FILE * fp, pointer to the input file + DdManager * dd, DD manager + DdNode ** E, characteristic function of the graph + DdNode *** x, array of row variables + DdNode *** y, array of column variables + DdNode *** xn, array of complemented row variables + DdNode *** yn_, array of complemented column variables + int * nx, number or row variables + int * ny, number or column variables + int * m, number of rows + int * n, number of columns + int bx, first index of row variables + int sx, step of row variables + int by, first index of column variables + int sy, step of column variables + int pr verbosity level +) + Reads in a matrix in the format of the Harwell-Boeing benchmark suite. The + variables are ordered as follows: x[0] y[0] x[1] y[1] ... + 0 is the most significant bit. On input, nx and ny hold the + numbers of row and column variables already in existence. On output, they + hold the numbers of row and column variables actually used by the matrix. m + and n are set to the numbers of rows and columns of the matrix. Their values + on input are immaterial. Returns 1 on success; 0 otherwise. The ADD for the + sparse matrix is returned in E, and its reference count is > 0. + + Side Effects: None + +DdNode * +Cudd_addIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Implements ITEconstant for ADDs. f must be a 0-1 ADD. Returns a pointer to + the resulting ADD (which may or may not be constant) or DD_NON_CONSTANT. No + new nodes are created. This function can be used, for instance, to check + that g has a constant value (specified by h) whenever f is 1. If the + constant value is unknown, then one should use Cudd_addEvalConst. + + Side Effects: None + +DdNode * +Cudd_addIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Implements ITE(f,g,h). This procedure assumes that f is a 0-1 ADD. Returns a + pointer to the resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addIthBit( + DdManager * dd, + DdNode * f, + int bit +) + Produces an ADD from another ADD by replacing all discriminants whose i-th + bit is equal to 1 with 1, and all other discriminants with 0. The i-th bit + refers to the integer representation of the leaf value. If the value is has + a fractional part, it is ignored. Repeated calls to this procedure allow one + to transform an integer-valued ADD into an array of ADDs, one for each bit + of the leaf values. Returns a pointer to the resulting ADD if successful; + NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addIthVar( + DdManager * dd, + int i +) + Retrieves the ADD variable with index i if it already exists, or creates a + new ADD variable. Returns a pointer to the variable if successful; NULL + otherwise. An ADD variable differs from a BDD variable because it points to + the arithmetic zero, instead of having a complement pointer to 1. + + Side Effects: None + +int +Cudd_addLeq( + DdManager * dd, + DdNode * f, + DdNode * g +) + Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are + created. This procedure works for arbitrary ADDs. For 0-1 ADDs + Cudd_addEvalConst is more efficient. + + Side Effects: None + +DdNode * +Cudd_addLog( + DdManager * dd, + DdNode * f +) + Natural logarithm of an ADDs. Returns NULL if not a terminal case; log(f) + otherwise. The discriminants of f must be positive double's. + + Side Effects: None + +DdNode * +Cudd_addMatrixMultiply( + DdManager * dd, + DdNode * A, + DdNode * B, + DdNode ** z, + int nz +) + Calculates the product of two matrices, A and B, represented as ADDs. This + procedure implements the quasiring multiplication algorithm. A is assumed to + depend on variables x (rows) and z (columns). B is assumed to depend on + variables z (rows) and y (columns). The product of A and B then depends on x + (rows) and y (columns). Only the z variables have to be explicitly + identified; they are the "summation" variables. Returns a pointer to the + result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addMaximum( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point max for Cudd_addApply. Returns NULL if not a + terminal case; max(f,g) otherwise. + + Side Effects: None + +DdNode * +Cudd_addMinimum( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point min for Cudd_addApply. Returns NULL if not a + terminal case; min(f,g) otherwise. + + Side Effects: None + +DdNode * +Cudd_addMinus( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point subtraction. Returns NULL if not a terminal case; + f - g otherwise. + + Side Effects: None + +DdNode * +Cudd_addMonadicApply( + DdManager * dd, + DD_MAOP op, + DdNode * f +) + Applies op to the discriminants of f. Returns a pointer to the result if + succssful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addNand( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + NAND of two 0-1 ADDs. Returns NULL if not a terminal case; f NAND g + otherwise. + + Side Effects: None + +DdNode * +Cudd_addNegate( + DdManager * dd, + DdNode * f +) + Computes the additive inverse of an ADD. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addNewVarAtLevel( + DdManager * dd, + int level +) + Creates a new ADD variable. The new variable has an index equal to the + largest previous index plus 1 and is positioned at the specified level in + the order. Returns a pointer to the new variable if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_addNewVar( + DdManager * dd +) + Creates a new ADD variable. The new variable has an index equal to the + largest previous index plus 1. Returns a pointer to the new variable if + successful; NULL otherwise. An ADD variable differs from a BDD variable + because it points to the arithmetic zero, instead of having a complement + pointer to 1. + + Side Effects: None + +DdNode * +Cudd_addNonSimCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector +) + Given a vector of 0-1 ADDs, creates a new ADD by substituting the 0-1 ADDs + for the variables of the ADD f. There should be an entry in vector for each + variable in the manager. This function implements non-simultaneous + composition. If any of the functions being composed depends on any of the + variables being substituted, then the result depends on the order of + composition, which in turn depends on the variable order: The variables + farther from the roots in the order are substituted first. Returns a pointer + to the resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addNor( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + NOR of two 0-1 ADDs. Returns NULL if not a terminal case; f NOR g otherwise. + + Side Effects: None + +DdNode * +Cudd_addOneZeroMaximum( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Returns 1 if f > g and 0 otherwise. Used in conjunction with + Cudd_addApply. Returns NULL if not a terminal case. + + Side Effects: None + +DdNode * +Cudd_addOrAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube +) + Abstracts all the variables in cube from the 0-1 ADD f by taking the + disjunction over all possible values taken by the variables. Returns the + abstracted ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addOr( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Disjunction of two 0-1 ADDs. Returns NULL if not a terminal case; f OR g + otherwise. + + Side Effects: None + +DdNode * +Cudd_addOuterSum( + DdManager * dd, + DdNode * M, + DdNode * r, + DdNode * c +) + Takes the pointwise minimum of a matrix and the outer sum of two vectors. + This procedure is used in the Floyd-Warshall all-pair shortest path + algorithm. Returns a pointer to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addPermute( + DdManager * manager, + DdNode * node, + int * permut +) + Given a permutation in array permut, creates a new ADD with permuted + variables. There should be an entry in array permut for each variable in the + manager. The i-th entry of permut holds the index of the variable that is to + substitute the i-th variable. Returns a pointer to the resulting ADD if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addPlus( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point addition. Returns NULL if not a terminal case; + f+g otherwise. + + Side Effects: None + +int +Cudd_addRead( + FILE * fp, input file pointer + DdManager * dd, DD manager + DdNode ** E, characteristic function of the graph + DdNode *** x, array of row variables + DdNode *** y, array of column variables + DdNode *** xn, array of complemented row variables + DdNode *** yn_, array of complemented column variables + int * nx, number or row variables + int * ny, number or column variables + int * m, number of rows + int * n, number of columns + int bx, first index of row variables + int sx, step of row variables + int by, first index of column variables + int sy step of column variables +) + Reads in a sparse matrix specified in a simple format. The first line of the + input contains the numbers of rows and columns. The remaining lines contain + the elements of the matrix, one per line. Given a background value + (specified by the background field of the manager), only the values + different from it are explicitly listed. Each foreground element is + described by two integers, i.e., the row and column number, and a real + number, i.e., the value. Cudd_addRead produces an ADD that depends on two + sets of variables: x and y. The x variables (x[0] ... x[nx-1]) encode the + row index and the y variables (y[0] ... y[ny-1]) encode the column index. + x[0] and y[0] are the most significant bits in the indices. The variables + may already exist or may be created by the function. The index of x[i] is + bx+i*sx, and the index of y[i] is by+i*sy. On input, nx and ny hold the + numbers of row and column variables already in existence. On output, they + hold the numbers of row and column variables actually used by the matrix. + When Cudd_addRead creates the variable arrays, the index of x[i] is bx+i*sx, + and the index of y[i] is by+i*sy. When some variables already exist + Cudd_addRead expects the indices of the existing x variables to be bx+i*sx, + and the indices of the existing y variables to be by+i*sy. m and n are + set to the numbers of rows and columns of the matrix. Their values on input + are immaterial. The ADD for the sparse matrix is returned in E, and its + reference count is > 0. Cudd_addRead returns 1 in case of success; 0 + otherwise. + + Side Effects: nx and ny are set to the numbers of row and column variables. + m and n are set to the numbers of rows and columns. x and y are possibly + extended to represent the array of row and column variables. Similarly for + xn and yn_, which hold on return from Cudd_addRead the complements of the + row and column variables. + +DdNode * +Cudd_addResidue( + DdManager * dd, manager + int n, number of bits + int m, modulus + int options, options + int top index of top variable +) + Builds an ADD for the residue modulo m of an n-bit number. The modulus must + be at least 2, and the number of bits at least 1. Parameter options + specifies whether the MSB should be on top or the LSB; and whther the number + whose residue is computed is in two's complement notation or not. The macro + CUDD_RESIDUE_DEFAULT specifies LSB on top and unsigned number. The macro + CUDD_RESIDUE_MSB specifies MSB on top, and the macro CUDD_RESIDUE_TC + specifies two's complement residue. To request MSB on top and two's + complement residue simultaneously, one can OR the two macros: + CUDD_RESIDUE_MSB | CUDD_RESIDUE_TC. Cudd_addResidue returns a pointer to the + resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addRestrict( + DdManager * dd, + DdNode * f, + DdNode * c +) + ADD restrict according to Coudert and Madre's algorithm (ICCAD90). Returns + the restricted ADD if successful; otherwise NULL. If application of restrict + results in an ADD larger than the input ADD, the input ADD is returned. + + Side Effects: None + +DdNode * +Cudd_addRoundOff( + DdManager * dd, + DdNode * f, + int N +) + Rounds off the discriminants of an ADD. The discriminants are rounded off to + N digits after the decimal. Returns a pointer to the result ADD if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addScalarInverse( + DdManager * dd, + DdNode * f, + DdNode * epsilon +) + Computes an n ADD where the discriminants are the multiplicative inverses of + the corresponding discriminants of the argument ADD. Returns a pointer to + the resulting ADD in case of success. Returns NULL if any discriminants + smaller than epsilon is encountered. + + Side Effects: None + +DdNode * +Cudd_addSetNZ( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + This operator sets f to the value of g wherever g != 0. Returns NULL if not + a terminal case; f op g otherwise. + + Side Effects: None + +DdNode * +Cudd_addSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n +) + Swaps two sets of variables of the same size (x and y) in the ADD f. The + size is given by n. The two sets of variables are assumed to be disjoint. + Returns a pointer to the resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addThreshold( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Threshold operator for Apply (f if f >=g; 0 if fx_id, or if + phase == 0 and f-->x_id'. + + Side Effects: None + +int +Cudd_bddIsVarHardGroup( + DdManager * dd, + int index +) + Checks whether a variable is set to be in a hard group. This function is + used for lazy sifting. Returns 1 if the variable is marked to be in a hard + group; 0 if the variable exists, but it is not marked to be in a hard group; + -1 if the variable does not exist. + + Side Effects: none + +int +Cudd_bddIsVarToBeGrouped( + DdManager * dd, + int index +) + Checks whether a variable is set to be grouped. This function is used for + lazy sifting. + + Side Effects: none + +int +Cudd_bddIsVarToBeUngrouped( + DdManager * dd, + int index +) + Checks whether a variable is set to be ungrouped. This function is used for + lazy sifting. Returns 1 if the variable is marked to be ungrouped; 0 if the + variable exists, but it is not marked to be ungrouped; -1 if the variable + does not exist. + + Side Effects: none + +DdNode * +Cudd_bddIsop( + DdManager * dd, + DdNode * L, + DdNode * U +) + Computes a BDD in the interval between L and U with a simple sum-of-product + cover. This procedure is similar to Cudd_zddIsop, but it does not return the + ZDD for the cover. Returns a pointer to the BDD if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_bddIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Implements ITEconstant(f,g,h). Returns a pointer to the resulting BDD (which + may or may not be constant) or DD_NON_CONSTANT. No new nodes are created. + + Side Effects: None + +DdNode * +Cudd_bddIteLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h, + unsigned int limit +) + Implements ITE(f,g,h). Returns a pointer to the resulting BDD if successful; + NULL if the intermediate result blows up or more new nodes than + limit are required. + + Side Effects: None + +int +Cudd_bddIterConjDecomp( + DdManager * dd, manager + DdNode * f, function to be decomposed + DdNode *** conjuncts address of the array of conjuncts +) + Performs two-way conjunctive decomposition of a BDD. This procedure owes its + name to the iterated use of supersetting to obtain a factor of the given + function. Returns the number of conjuncts produced, that is, 2 if + successful; 1 if no meaningful decomposition was found; 0 otherwise. The + conjuncts produced by this procedure tend to be imbalanced. + + Side Effects: The factors are returned in an array as side effects. The + array is allocated by this function. It is the caller's responsibility to + free it. On successful completion, the conjuncts are already referenced. If + the function returns 0, the array for the conjuncts is not allocated. If the + function returns 1, the only factor equals the function to be decomposed. + +int +Cudd_bddIterDisjDecomp( + DdManager * dd, manager + DdNode * f, function to be decomposed + DdNode *** disjuncts address of the array of the disjuncts +) + Performs two-way disjunctive decomposition of a BDD. Returns the number of + disjuncts produced, that is, 2 if successful; 1 if no meaningful + decomposition was found; 0 otherwise. The disjuncts produced by this + procedure tend to be imbalanced. + + Side Effects: The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already referenced. + If the function returns 0, the array for the disjuncts is not allocated. If + the function returns 1, the only factor equals the function to be + decomposed. + +DdNode * +Cudd_bddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Implements ITE(f,g,h). Returns a pointer to the resulting BDD if successful; + NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddIthVar( + DdManager * dd, + int i +) + Retrieves the BDD variable with index i if it already exists, or creates a + new BDD variable. Returns a pointer to the variable if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_bddLICompaction( + DdManager * dd, manager + DdNode * f, function to be minimized + DdNode * c constraint (care set) +) + Performs safe minimization of a BDD. Given the BDD f of a + function to be minimized and a BDD c representing the care set, + Cudd_bddLICompaction produces the BDD of a function that agrees with + f wherever c is 1. Safe minimization means that + the size of the result is guaranteed not to exceed the size of + f. This function is based on the DAC97 paper by Hong et al.. + Returns a pointer to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddLargestPrimeUnate( + DdManager * dd, manager + DdNode * f, unate function + DdNode * phaseBdd cube of the phases +) + Find a largest prime implicant of a unate function. Returns the BDD for the + prime if succesful; NULL otherwise. The behavior is undefined if f is not + unate. The third argument is used to determine whether f is unate positive + (increasing) or negative (decreasing) in each of the variables in its + support. + + Side Effects: None + +int +Cudd_bddLeqUnless( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * D +) + Tells whether f is less than of equal to G unless D is 1. f, g, and D are + BDDs. The function returns 1 if f is less than of equal to G, and 0 + otherwise. No new nodes are created. + + Side Effects: None + +int +Cudd_bddLeq( + DdManager * dd, + DdNode * f, + DdNode * g +) + Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are + created. + + Side Effects: None + +DdNode * +Cudd_bddLiteralSetIntersection( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the intesection of two sets of literals represented as BDDs. Each + set is represented as a cube of the literals in the set. The empty set is + represented by the constant 1. No variable can be simultaneously present in + both phases in a set. Returns a pointer to the BDD representing the + intersected sets, if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddMakePrime( + DdManager * dd, manager + DdNode * cube, cube to be expanded + DdNode * f function of which the cube is to be made + a prime +) + Expands cube to a prime implicant of f. Returns the prime if successful; + NULL otherwise. In particular, NULL is returned if cube is not a real cube + or is not an implicant of f. + + Side Effects: None + +DdNode * +Cudd_bddMaximallyExpand( + DdManager * dd, manager + DdNode * lb, cube to be expanded + DdNode * ub, upper bound cube + DdNode * f function against which to expand +) + Expands lb to all prime implicants of (f and ub) that contain lb. Assumes + that lb is contained in ub. Returns the disjunction of the primes if lb is + contained in f; returns the zero BDD if lb is not contained in f; returns + NULL in case of failure. In particular, NULL is returned if cube is not a + real cube or is not an implicant of f. Returning the disjunction of all + prime implicants works because the resulting function is unate. + + Side Effects: None + +DdNode * +Cudd_bddMinimize( + DdManager * dd, + DdNode * f, + DdNode * c +) + Finds a small BDD that agrees with f over c. + Returns a pointer to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddNPAnd( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes f non-polluting-and g. The non-polluting AND of f and g is a hybrid + of AND and Restrict. From Restrict, this operation takes the idea of + existentially quantifying the top variable of the second operand if it does + not appear in the first. Therefore, the variables that appear in the result + also appear in f. For the rest, the function behaves like AND. Since the two + operands play different roles, non-polluting AND is not commutative. Returns + a pointer to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddNand( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the NAND of two BDDs f and g. Returns a pointer to the resulting + BDD if successful; NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddNewVarAtLevel( + DdManager * dd, + int level +) + Creates a new BDD variable. The new variable has an index equal to the + largest previous index plus 1 and is positioned at the specified level in + the order. Returns a pointer to the new variable if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_bddNewVar( + DdManager * dd +) + Creates a new BDD variable. The new variable has an index equal to the + largest previous index plus 1. Returns a pointer to the new variable if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddNor( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the NOR of two BDDs f and g. Returns a pointer to the resulting BDD + if successful; NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddOrLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit +) + Computes the disjunction of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up or + more new nodes than limit are required. + + Side Effects: None + +DdNode * +Cudd_bddOr( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the disjunction of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddPermute( + DdManager * manager, + DdNode * node, + int * permut +) + Given a permutation in array permut, creates a new BDD with permuted + variables. There should be an entry in array permut for each variable in the + manager. The i-th entry of permut holds the index of the variable that is to + substitute the i-th variable. Returns a pointer to the resulting BDD if + successful; NULL otherwise. + + Side Effects: None + +DdNode ** +Cudd_bddPickArbitraryMinterms( + DdManager * dd, manager + DdNode * f, function from which to pick k minterms + DdNode ** vars, array of variables + int n, size of vars + int k number of minterms to find +) + Picks k on-set minterms evenly distributed from given DD. The minterms are + in terms of vars. The array vars should contain at + least all variables in the support of f; if this condition is + not met the minterms built by this procedure may not be contained in + f. Builds an array of BDDs for the minterms and returns a + pointer to it if successful; NULL otherwise. There are three reasons why the + procedure may fail: It may run out of memory; the function + f may be the constant 0; the minterms may not be contained + in f. + + Side Effects: None + +int +Cudd_bddPickOneCube( + DdManager * ddm, + DdNode * node, + char * string +) + Picks one on-set cube randomly from the given DD. The cube is written into + an array of characters. The array must have at least as many entries as + there are variables. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +DdNode * +Cudd_bddPickOneMinterm( + DdManager * dd, manager + DdNode * f, function from which to pick one minterm + DdNode ** vars, array of variables + int n size of vars +) + Picks one on-set minterm randomly from the given DD. The minterm is in terms + of vars. The array vars should contain at least + all variables in the support of f; if this condition is not met + the minterm built by this procedure may not be contained in f. + Builds a BDD for the minterm and returns a pointer to it if successful; NULL + otherwise. There are three reasons why the procedure may fail: It + may run out of memory; the function f may be the constant + 0; the minterm may not be contained in f. + + Side Effects: None + +int +Cudd_bddPrintCover( + DdManager * dd, + DdNode * l, + DdNode * u +) + Prints a sum of product cover for an incompletely specified function given + by a lower bound and an upper bound. Each product is a prime implicant + obtained by expanding the product corresponding to a path from node to the + constant one. Uses the package default output file. Returns 1 if successful; + 0 otherwise. + + Side Effects: None + +int +Cudd_bddReadPairIndex( + DdManager * dd, + int index +) + Reads a corresponding pair index for a given index. These pair indices are + present and next state variable. Returns the corresponding variable index if + the variable exists; -1 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddRead( + FILE * fp, input file pointer + DdManager * dd, DD manager + DdNode ** E, characteristic function of the graph + DdNode *** x, array of row variables + DdNode *** y, array of column variables + int * nx, number or row variables + int * ny, number or column variables + int * m, number of rows + int * n, number of columns + int bx, first index of row variables + int sx, step of row variables + int by, first index of column variables + int sy step of column variables +) + Reads in a graph (without labels) given as an adjacency matrix. The first + line of the input contains the numbers of rows and columns of the adjacency + matrix. The remaining lines contain the arcs of the graph, one per line. + Each arc is described by two integers, i.e., the row and column number, or + the indices of the two endpoints. Cudd_bddRead produces a BDD that depends + on two sets of variables: x and y. The x variables (x[0] ... x[nx-1]) encode + the row index and the y variables (y[0] ... y[ny-1]) encode the column + index. x[0] and y[0] are the most significant bits in the indices. The + variables may already exist or may be created by the function. The index of + x[i] is bx+i*sx, and the index of y[i] is by+i*sy. On input, nx and ny + hold the numbers of row and column variables already in existence. On + output, they hold the numbers of row and column variables actually used by + the matrix. When Cudd_bddRead creates the variable arrays, the index of x[i] + is bx+i*sx, and the index of y[i] is by+i*sy. When some variables already + exist, Cudd_bddRead expects the indices of the existing x variables to be + bx+i*sx, and the indices of the existing y variables to be by+i*sy. m and + n are set to the numbers of rows and columns of the matrix. Their values on + input are immaterial. The BDD for the graph is returned in E, and its + reference count is > 0. Cudd_bddRead returns 1 in case of success; 0 + otherwise. + + Side Effects: nx and ny are set to the numbers of row and column variables. + m and n are set to the numbers of rows and columns. x and y are possibly + extended to represent the array of row and column variables. + +void +Cudd_bddRealignDisable( + DdManager * unique +) + Disables realignment of ZDD order to BDD order. + + Side Effects: None + +void +Cudd_bddRealignEnable( + DdManager * unique +) + Enables realignment of the BDD variable order to the ZDD variable order + after the ZDDs have been reordered. The number of ZDD variables must be a + multiple of the number of BDD variables for realignment to make sense. If + this condition is not met, Cudd_zddReduceHeap will return 0. Let + M be the ratio of the two numbers. For the purpose of + realignment, the ZDD variables from M*i to (M+1)*i- + 1 are reagarded as corresponding to BDD variable i. + Realignment is initially disabled. + + Side Effects: None + +int +Cudd_bddRealignmentEnabled( + DdManager * unique +) + Returns 1 if the realignment of BDD order to ZDD order is enabled; 0 + otherwise. + + Side Effects: None + +int +Cudd_bddResetVarToBeGrouped( + DdManager * dd, + int index +) + Resets a variable not to be grouped. This function is used for lazy sifting. + Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +DdNode * +Cudd_bddRestrict( + DdManager * dd, + DdNode * f, + DdNode * c +) + BDD restrict according to Coudert and Madre's algorithm (ICCAD90). Returns + the restricted BDD if successful; otherwise NULL. If application of restrict + results in a BDD larger than the input BDD, the input BDD is returned. + + Side Effects: None + +int +Cudd_bddSetNsVar( + DdManager * dd, manager + int index variable index +) + Sets a variable type to next state. The variable type is used by lazy + sifting. Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetPairIndex( + DdManager * dd, manager + int index, variable index + int pairIndex corresponding variable index +) + Sets a corresponding pair index for a given index. These pair indices are + present and next state variable. Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetPiVar( + DdManager * dd, manager + int index variable index +) + Sets a variable type to primary input. The variable type is used by lazy + sifting. Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetPsVar( + DdManager * dd, manager + int index variable index +) + Sets a variable type to present state. The variable type is used by lazy + sifting. Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetVarHardGroup( + DdManager * dd, + int index +) + Sets a variable to be a hard group. This function is used for lazy sifting. + Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetVarToBeGrouped( + DdManager * dd, + int index +) + Sets a variable to be grouped. This function is used for lazy sifting. + Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetVarToBeUngrouped( + DdManager * dd, + int index +) + Sets a variable to be ungrouped. This function is used for lazy sifting. + Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +DdNode * +Cudd_bddSqueeze( + DdManager * dd, manager + DdNode * l, lower bound + DdNode * u upper bound +) + Finds a small BDD in a function interval. Given BDDs l and + u, representing the lower bound and upper bound of a function + interval, Cudd_bddSqueeze produces the BDD of a function within the interval + with a small BDD. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_bddSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n +) + Swaps two sets of variables of the same size (x and y) in the BDD f. The + size is given by n. The two sets of variables are assumed to be disjoint. + Returns a pointer to the resulting BDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddTransfer( + DdManager * ddSource, + DdManager * ddDestination, + DdNode * f +) + Convert a BDD from a manager to another one. The orders of the variables in + the two managers may be different. Returns a pointer to the BDD in the + destination manager if successful; NULL otherwise. + + Side Effects: None + +int +Cudd_bddUnbindVar( + DdManager * dd, manager + int index variable index +) + This function resets the flag that prevents the sifting of a variable. In + successive variable reorderings, the variable will NOT be skipped, that is, + sifted. Initially all variables can be sifted. It is necessary to call this + function only to re-enable sifting after a call to Cudd_bddBindVar. Returns + 1 if successful; 0 otherwise (i.e., invalid variable index). + + Side Effects: Changes the "bindVar" flag in DdSubtable. + +DdNode * +Cudd_bddUnivAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube +) + Universally abstracts all the variables in cube from f. Returns the + abstracted BDD if successful; NULL otherwise. + + Side Effects: None + +int +Cudd_bddVarConjDecomp( + DdManager * dd, manager + DdNode * f, function to be decomposed + DdNode *** conjuncts address of the array of conjuncts +) + Conjunctively decomposes one BDD according to a variable. If f + is the function of the BDD and x is the variable, the + decomposition is (f+x)(f+x'). The variable is chosen so as to + balance the sizes of the two conjuncts and to keep them small. Returns the + number of conjuncts produced, that is, 2 if successful; 1 if no meaningful + decomposition was found; 0 otherwise. + + Side Effects: The two factors are returned in an array as side effects. The + array is allocated by this function. It is the caller's responsibility to + free it. On successful completion, the conjuncts are already referenced. If + the function returns 0, the array for the conjuncts is not allocated. If the + function returns 1, the only factor equals the function to be decomposed. + +int +Cudd_bddVarDisjDecomp( + DdManager * dd, manager + DdNode * f, function to be decomposed + DdNode *** disjuncts address of the array of the disjuncts +) + Performs two-way disjunctive decomposition of a BDD according to a variable. + If f is the function of the BDD and x is the + variable, the decomposition is f*x + f*x'. The variable is + chosen so as to balance the sizes of the two disjuncts and to keep them + small. Returns the number of disjuncts produced, that is, 2 if successful; 1 + if no meaningful decomposition was found; 0 otherwise. + + Side Effects: The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already referenced. + If the function returns 0, the array for the disjuncts is not allocated. If + the function returns 1, the only factor equals the function to be + decomposed. + +int +Cudd_bddVarIsBound( + DdManager * dd, manager + int index variable index +) + This function returns 1 if a variable is enabled for sifting. Initially all + variables can be sifted. This function returns 0 only if there has been a + previous call to Cudd_bddBindVar for that variable not followed by a call to + Cudd_bddUnbindVar. The function returns 0 also in the case in which the + index of the variable is out of bounds. + + Side Effects: none + +int +Cudd_bddVarIsDependent( + DdManager * dd, + DdNode * f, + DdNode * var variable +) + Checks whether a variable is dependent on others in a function. Returns 1 if + the variable is dependent; 0 otherwise. No new nodes are created. + + Side Effects: None + +DdNode * +Cudd_bddVarMap( + DdManager * manager, DD manager + DdNode * f function in which to remap variables +) + Remaps the variables of a BDD using the default variable map. A typical use + of this function is to swap two sets of variables. The variable map must be + registered with Cudd_SetVarMap. Returns a pointer to the resulting BDD if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector +) + Given a vector of BDDs, creates a new BDD by substituting the BDDs for the + variables of the BDD f. There should be an entry in vector for each variable + in the manager. If no substitution is sought for a given variable, the + corresponding projection function should be specified in the vector. This + function implements simultaneous composition. Returns a pointer to the + resulting BDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddXnorLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit +) + Computes the exclusive NOR of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up or + more new nodes than limit are required. + + Side Effects: None + +DdNode * +Cudd_bddXnor( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the exclusive NOR of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddXorExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube +) + Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddXor( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the exclusive OR of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up. + + Side Effects: None + +void +Cudd_tlcInfoFree( + DdTlcInfo * t +) + Frees a DdTlcInfo Structure as well as the memory pointed by it. + + Side Effects: None + +DdNode * +Cudd_zddChange( + DdManager * dd, + DdNode * P, + int var +) + Substitutes a variable with its complement in a ZDD. returns a pointer to + the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddComplement( + DdManager * dd, + DdNode * node +) + Computes a complement cover for a ZDD node. For lack of a better method, we + first extract the function BDD from the ZDD cover, then make the complement + of the ZDD cover from the complement of the BDD node by using ISOP. Returns + a pointer to the resulting cover if successful; NULL otherwise. The result + depends on current variable order. + + Side Effects: The result depends on current variable order. + +double +Cudd_zddCountDouble( + DdManager * zdd, + DdNode * P +) + Counts the number of minterms of a ZDD. The result is returned as a double. + If the procedure runs out of memory, it returns (double) CUDD_OUT_OF_MEM. + This procedure is used in Cudd_zddCountMinterm. + + Side Effects: None + +double +Cudd_zddCountMinterm( + DdManager * zdd, + DdNode * node, + int path +) + Counts the number of minterms of the ZDD rooted at node. This + procedure takes a parameter path that specifies how many + variables are in the support of the function. If the procedure runs out of + memory, it returns (double) CUDD_OUT_OF_MEM. + + Side Effects: None + +int +Cudd_zddCount( + DdManager * zdd, + DdNode * P +) + Returns an integer representing the number of minterms in a ZDD. + + Side Effects: None + +char * +Cudd_zddCoverPathToString( + DdManager * zdd, DD manager + int * path, path of ZDD representing a cover + char * str pointer to string to use if != NULL +) + Converts a path of a ZDD representing a cover to a string. The string + represents an implicant of the cover. The path is typically produced by + Cudd_zddForeachPath. Returns a pointer to the string if successful; NULL + otherwise. If the str input is NULL, it allocates a new string. The string + passed to this function must have enough room for all variables and for the + terminator. + + Side Effects: None + +int +Cudd_zddDagSize( + DdNode * p_node +) + Counts the number of nodes in a ZDD. This function duplicates Cudd_DagSize + and is only retained for compatibility. + + Side Effects: None + +DdNode * +Cudd_zddDiffConst( + DdManager * zdd, + DdNode * P, + DdNode * Q +) + Inclusion test for ZDDs (P implies Q). No new nodes are generated by this + procedure. Returns empty if true; a valid pointer different from empty or + DD_NON_CONSTANT otherwise. + + Side Effects: None + +DdNode * +Cudd_zddDiff( + DdManager * dd, + DdNode * P, + DdNode * Q +) + Computes the difference of two ZDDs. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddDivideF( + DdManager * dd, + DdNode * f, + DdNode * g +) + Modified version of Cudd_zddDivide. This function may disappear in future + releases. + + Side Effects: None + +DdNode * +Cudd_zddDivide( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the quotient of two unate covers represented by ZDDs. Unate covers + use one ZDD variable for each BDD variable. Returns a pointer to the + resulting ZDD if successful; NULL otherwise. + + Side Effects: None + +int +Cudd_zddDumpDot( + DdManager * dd, manager + int n, number of output nodes to be dumped + DdNode ** f, array of output nodes to be dumped + char ** inames, array of input names (or NULL) + char ** onames, array of output names (or NULL) + FILE * fp pointer to the dump file +) + Writes a file representing the argument ZDDs in a format suitable for the + graph drawing program dot. It returns 1 in case of success; 0 otherwise + (e.g., out-of-memory, file system full). Cudd_zddDumpDot does not close the + file: This is the caller responsibility. Cudd_zddDumpDot uses a minimal + unique subset of the hexadecimal address of a node as name for it. If the + argument inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for onames. Cudd_zddDumpDot uses the following + convention to draw arcs: solid line: THEN arcs; dashed line: + ELSE arcs. The dot options are chosen so that the drawing fits on a + letter-size sheet. + + Side Effects: None + +DdGen * +Cudd_zddFirstPath( + DdManager * zdd, + DdNode * f, + int ** path +) + Defines an iterator on the paths of a ZDD and finds its first path. Returns + a generator that contains the information necessary to continue the + enumeration if successful; NULL otherwise. A path is represented as an + array of literals, which are integers in {0, 1, 2}; 0 represents an else arc + out of a node, 1 represents a then arc out of a node, and 2 stands for the + absence of a node. The size of the array equals the number of variables in + the manager at the time Cudd_zddFirstCube is called. The paths that end + in the empty terminal are not enumerated. + + Side Effects: The first path is returned as a side effect. + +DdNode * +Cudd_zddIntersect( + DdManager * dd, + DdNode * P, + DdNode * Q +) + Computes the intersection of two ZDDs. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddIsop( + DdManager * dd, + DdNode * L, + DdNode * U, + DdNode ** zdd_I +) + Computes an irredundant sum of products (ISOP) in ZDD form from BDDs. The + two BDDs L and U represent the lower bound and the upper bound, + respectively, of the function. The ISOP uses two ZDD variables for each BDD + variable: One for the positive literal, and one for the negative literal. + These two variables should be adjacent in the ZDD order. The two ZDD + variables corresponding to BDD variable i should have indices + 2i and 2i+1. The result of this procedure depends + on the variable order. If successful, Cudd_zddIsop returns the BDD for the + function chosen from the interval. The ZDD representing the irredundant + cover is returned as a side effect in zdd_I. In case of failure, NULL is + returned. + + Side Effects: zdd_I holds the pointer to the ZDD for the ISOP on successful + return. + +DdNode * +Cudd_zddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Computes the ITE of three ZDDs. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddIthVar( + DdManager * dd, + int i +) + Retrieves the ZDD variable with index i if it already exists, or creates a + new ZDD variable. Returns a pointer to the variable if successful; NULL + otherwise. + + Side Effects: None + +int +Cudd_zddNextPath( + DdGen * gen, + int ** path +) + Generates the next path of a ZDD onset, using generator gen. Returns 0 if + the enumeration is completed; 1 otherwise. + + Side Effects: The path is returned as a side effect. The generator is + modified. + +DdNode * +Cudd_zddPortFromBdd( + DdManager * dd, + DdNode * B +) + Converts a BDD into a ZDD. This function assumes that there is a one-to-one + correspondence between the BDD variables and the ZDD variables, and that the + variable order is the same for both types of variables. These conditions are + established if the ZDD variables are created by one call to + Cudd_zddVarsFromBddVars with multiplicity = 1. Returns a pointer to the + resulting ZDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddPortToBdd( + DdManager * dd, + DdNode * f +) + Converts a ZDD into a BDD. Returns a pointer to the resulting ZDD if + successful; NULL otherwise. + + Side Effects: None + +int +Cudd_zddPrintCover( + DdManager * zdd, + DdNode * node +) + Prints a sum of products from a ZDD representing a cover. Returns 1 if + successful; 0 otherwise. + + Side Effects: None + +int +Cudd_zddPrintDebug( + DdManager * zdd, + DdNode * f, + int n, + int pr +) + Prints to the standard output a DD and its statistics. The statistics + include the number of nodes and the number of minterms. (The number of + minterms is also the number of combinations in the set.) The statistics are + printed if pr > 0. Specifically: pr = 0 : prints nothing + pr = 1 : prints counts of nodes and minterms pr = 2 : prints counts + + disjoint sum of products pr = 3 : prints counts + list of nodes pr + > 3 : prints counts + disjoint sum of products + list of nodes + Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_zddPrintMinterm( + DdManager * zdd, + DdNode * node +) + Prints a disjoint sum of product form for a ZDD. Returns 1 if successful; 0 + otherwise. + + Side Effects: None + +void +Cudd_zddPrintSubtable( + DdManager * table +) + Prints the ZDD table for debugging purposes. + + Side Effects: None + +DdNode * +Cudd_zddProduct( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the product of two covers represented by ZDDs. The result is also a + ZDD. Returns a pointer to the result if successful; NULL otherwise. The + covers on which Cudd_zddProduct operates use two ZDD variables for each + function variable (one ZDD variable for each literal of the variable). Those + two ZDD variables should be adjacent in the order. + + Side Effects: None + +long +Cudd_zddReadNodeCount( + DdManager * dd +) + Reports the number of nodes in ZDDs. This number always includes the two + constants 1 and 0. + + Side Effects: None + +void +Cudd_zddRealignDisable( + DdManager * unique +) + Disables realignment of ZDD order to BDD order. + + Side Effects: None + +void +Cudd_zddRealignEnable( + DdManager * unique +) + Enables realignment of the ZDD variable order to the BDD variable order + after the BDDs and ADDs have been reordered. The number of ZDD variables + must be a multiple of the number of BDD variables for realignment to make + sense. If this condition is not met, Cudd_ReduceHeap will return 0. Let + M be the ratio of the two numbers. For the purpose of + realignment, the ZDD variables from M*i to (M+1)*i- + 1 are reagarded as corresponding to BDD variable i. + Realignment is initially disabled. + + Side Effects: None + +int +Cudd_zddRealignmentEnabled( + DdManager * unique +) + Returns 1 if the realignment of ZDD order to BDD order is enabled; 0 + otherwise. + + Side Effects: None + +int +Cudd_zddReduceHeap( + DdManager * table, DD manager + Cudd_ReorderingTy heuristic, method used for reordering + int minsize bound below which no reordering occurs +) + Main dynamic reordering routine for ZDDs. Calls one of the possible + reordering procedures: Swapping Sifting Symmetric Sifting + For sifting and symmetric sifting it is possible to request reordering + to convergence. The core of all methods is the reordering procedure + cuddZddSwapInPlace() which swaps two adjacent variables. Returns 1 in case + of success; 0 otherwise. In the case of symmetric sifting (with and without + convergence) returns 1 plus the number of symmetric variables, in case of + success. + + Side Effects: Changes the variable order for all ZDDs and clears the cache. + +int +Cudd_zddShuffleHeap( + DdManager * table, DD manager + int * permutation required variable permutation +) + Reorders ZDD variables according to given permutation. The i-th entry of the + permutation array contains the index of the variable that should be brought + to the i-th level. The size of the array should be equal or greater to the + number of variables currently in use. Returns 1 in case of success; 0 + otherwise. + + Side Effects: Changes the ZDD variable order for all diagrams and clears the + cache. + +DdNode * +Cudd_zddSubset0( + DdManager * dd, + DdNode * P, + int var +) + Computes the negative cofactor of a ZDD w.r.t. a variable. In terms of + combinations, the result is the set of all combinations in which the + variable is negated. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_zddSubset1( + DdManager * dd, + DdNode * P, + int var +) + Computes the positive cofactor of a ZDD w.r.t. a variable. In terms of + combinations, the result is the set of all combinations in which the + variable is asserted. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_zddSupport( + DdManager * dd, manager + DdNode * f ZDD whose support is sought +) + Finds the variables on which a ZDD depends. Returns a BDD consisting of the + product of the variables if successful; NULL otherwise. + + Side Effects: None + +void +Cudd_zddSymmProfile( + DdManager * table, + int lower, + int upper +) + Prints statistics on symmetric ZDD variables. + + Side Effects: None + +DdNode * +Cudd_zddUnateProduct( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the product of two unate covers represented as ZDDs. Unate covers + use one ZDD variable for each BDD variable. Returns a pointer to the result + if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddUnion( + DdManager * dd, + DdNode * P, + DdNode * Q +) + Computes the union of two ZDDs. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +int +Cudd_zddVarsFromBddVars( + DdManager * dd, DD manager + int multiplicity how many ZDD variables are created for + each BDD variable +) + Creates one or more ZDD variables for each BDD variable. If some ZDD + variables already exist, only the missing variables are created. Parameter + multiplicity allows the caller to control how many variables are created for + each BDD variable in existence. For instance, if ZDDs are used to represent + covers, two ZDD variables are required for each BDD variable. The order of + the BDD variables is transferred to the ZDD variables. If a variable group + tree exists for the BDD variables, a corresponding ZDD variable group tree + is created by expanding the BDD variable tree. In any case, the ZDD + variables derived from the same BDD variable are merged in a ZDD variable + group. If a ZDD variable group tree exists, it is freed. Returns 1 if + successful; 0 otherwise. + + Side Effects: None + +DdNode * +Cudd_zddWeakDivF( + DdManager * dd, + DdNode * f, + DdNode * g +) + Modified version of Cudd_zddWeakDiv. This function may disappear in future + releases. + + Side Effects: None + +DdNode * +Cudd_zddWeakDiv( + DdManager * dd, + DdNode * f, + DdNode * g +) + Applies weak division to two ZDDs representing two covers. Returns a pointer + to the ZDD representing the result if successful; NULL otherwise. The result + of weak division depends on the variable order. The covers on which + Cudd_zddWeakDiv operates use two ZDD variables for each function variable + (one ZDD variable for each literal of the variable). Those two ZDD variables + should be adjacent in the order. + + Side Effects: None + +writing ./cuddTitle.html diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.ps b/resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.ps new file mode 100644 index 000000000..0a12057cc --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cudd.ps @@ -0,0 +1,5036 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.92b Copyright 2002 Radical Eye Software +%%Title: cudd.dvi +%%Pages: 48 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%DocumentFonts: Times-Roman CMMI12 Times-Bold Times-Italic CMSY10 CMR10 +%%+ CMMI10 CMMI8 Courier CMSY8 CMR8 Times-BoldItalic +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -o cudd.ps cudd +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2012.02.04:1929 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% File 8r.enc as of 2002-03-12 for PSNFSS 9 +% +% This is the encoding vector for Type1 and TrueType fonts to be used +% with TeX. This file is part of the PSNFSS bundle, version 9 +% +% Authors: S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry, W. Schmidt +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida + Euro. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both ASCII and Windows. +% +% (6) /Euro is assigned to 128, as in Windows ANSI +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there down to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /Euro /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0 +ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{ +pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get +div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type +/nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end +definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup +sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll +mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[ +exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if} +forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def +end + +%%EndProcSet +%%BeginProcSet: special.pro +%! +TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N +/vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N +/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N +/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ +/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho +X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B +/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ +/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known +{userdict/md get type/dicttype eq{userdict begin md length 10 add md +maxlength ge{/md md dup length 20 add dict copy def}if end md begin +/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S +atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ +itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll +transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll +curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf +pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} +if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 +-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 +get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip +yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub +neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ +noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop +90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get +neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr +1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr +2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 +-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S +TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ +Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale +}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState +save N userdict maxlength dict begin/magscale true def normalscale +currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts +/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x +psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx +psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub +TR/showpage{}N/erasepage{}N/setpagedevice{pop}N/copypage{}N/p 3 def +@MacSetUp}N/doclip{psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll +newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto +closepath clip newpath moveto}N/endTexFig{end psf$SavedState restore}N +/@beginspecial{SDict begin/SpecialSave save N gsave normalscale +currentpoint TR @SpecialDefaults count/ocount X/dcount countdictstack N} +N/@setspecial{CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs +neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate +rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse +scale llx neg lly neg TR}{rhiSeen{rhi ury lly sub div dup scale llx neg +lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx +ury lineto llx ury lineto closepath clip}if/showpage{}N/erasepage{}N +/setpagedevice{pop}N/copypage{}N newpath}N/@endspecial{count ocount sub{ +pop}repeat countdictstack dcount sub{end}repeat grestore SpecialSave +restore end}N/@defspecial{SDict begin}N/@fedspecial{end}B/li{lineto}B +/rl{rlineto}B/rc{rcurveto}B/np{/SaveX currentpoint/SaveY X N 1 +setlinecap newpath}N/st{stroke SaveX SaveY moveto}N/fil{fill SaveX SaveY +moveto}N/ellipse{/endangle X/startangle X/yrad X/xrad X/savematrix +matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc +savematrix setmatrix}N end + +%%EndProcSet +%%BeginProcSet: color.pro +%! +TeXDict begin/setcmykcolor where{pop}{/setcmykcolor{dup 10 eq{pop +setrgbcolor}{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll +}repeat setrgbcolor pop}ifelse}B}ifelse/TeXcolorcmyk{setcmykcolor}def +/TeXcolorrgb{setrgbcolor}def/TeXcolorgrey{setgray}def/TeXcolorgray{ +setgray}def/TeXcolorhsb{sethsbcolor}def/currentcmykcolor where{pop}{ +/currentcmykcolor{currentrgbcolor 10}B}ifelse/DC{exch dup userdict exch +known{pop pop}{X}ifelse}B/GreenYellow{0.15 0 0.69 0 setcmykcolor}DC +/Yellow{0 0 1 0 setcmykcolor}DC/Goldenrod{0 0.10 0.84 0 setcmykcolor}DC +/Dandelion{0 0.29 0.84 0 setcmykcolor}DC/Apricot{0 0.32 0.52 0 +setcmykcolor}DC/Peach{0 0.50 0.70 0 setcmykcolor}DC/Melon{0 0.46 0.50 0 +setcmykcolor}DC/YellowOrange{0 0.42 1 0 setcmykcolor}DC/Orange{0 0.61 +0.87 0 setcmykcolor}DC/BurntOrange{0 0.51 1 0 setcmykcolor}DC +/Bittersweet{0 0.75 1 0.24 setcmykcolor}DC/RedOrange{0 0.77 0.87 0 +setcmykcolor}DC/Mahogany{0 0.85 0.87 0.35 setcmykcolor}DC/Maroon{0 0.87 +0.68 0.32 setcmykcolor}DC/BrickRed{0 0.89 0.94 0.28 setcmykcolor}DC/Red{ +0 1 1 0 setcmykcolor}DC/OrangeRed{0 1 0.50 0 setcmykcolor}DC/RubineRed{ +0 1 0.13 0 setcmykcolor}DC/WildStrawberry{0 0.96 0.39 0 setcmykcolor}DC +/Salmon{0 0.53 0.38 0 setcmykcolor}DC/CarnationPink{0 0.63 0 0 +setcmykcolor}DC/Magenta{0 1 0 0 setcmykcolor}DC/VioletRed{0 0.81 0 0 +setcmykcolor}DC/Rhodamine{0 0.82 0 0 setcmykcolor}DC/Mulberry{0.34 0.90 +0 0.02 setcmykcolor}DC/RedViolet{0.07 0.90 0 0.34 setcmykcolor}DC +/Fuchsia{0.47 0.91 0 0.08 setcmykcolor}DC/Lavender{0 0.48 0 0 +setcmykcolor}DC/Thistle{0.12 0.59 0 0 setcmykcolor}DC/Orchid{0.32 0.64 0 +0 setcmykcolor}DC/DarkOrchid{0.40 0.80 0.20 0 setcmykcolor}DC/Purple{ +0.45 0.86 0 0 setcmykcolor}DC/Plum{0.50 1 0 0 setcmykcolor}DC/Violet{ +0.79 0.88 0 0 setcmykcolor}DC/RoyalPurple{0.75 0.90 0 0 setcmykcolor}DC +/BlueViolet{0.86 0.91 0 0.04 setcmykcolor}DC/Periwinkle{0.57 0.55 0 0 +setcmykcolor}DC/CadetBlue{0.62 0.57 0.23 0 setcmykcolor}DC +/CornflowerBlue{0.65 0.13 0 0 setcmykcolor}DC/MidnightBlue{0.98 0.13 0 +0.43 setcmykcolor}DC/NavyBlue{0.94 0.54 0 0 setcmykcolor}DC/RoyalBlue{1 +0.50 0 0 setcmykcolor}DC/Blue{1 1 0 0 setcmykcolor}DC/Cerulean{0.94 0.11 +0 0 setcmykcolor}DC/Cyan{1 0 0 0 setcmykcolor}DC/ProcessBlue{0.96 0 0 0 +setcmykcolor}DC/SkyBlue{0.62 0 0.12 0 setcmykcolor}DC/Turquoise{0.85 0 +0.20 0 setcmykcolor}DC/TealBlue{0.86 0 0.34 0.02 setcmykcolor}DC +/Aquamarine{0.82 0 0.30 0 setcmykcolor}DC/BlueGreen{0.85 0 0.33 0 +setcmykcolor}DC/Emerald{1 0 0.50 0 setcmykcolor}DC/JungleGreen{0.99 0 +0.52 0 setcmykcolor}DC/SeaGreen{0.69 0 0.50 0 setcmykcolor}DC/Green{1 0 +1 0 setcmykcolor}DC/ForestGreen{0.91 0 0.88 0.12 setcmykcolor}DC +/PineGreen{0.92 0 0.59 0.25 setcmykcolor}DC/LimeGreen{0.50 0 1 0 +setcmykcolor}DC/YellowGreen{0.44 0 0.74 0 setcmykcolor}DC/SpringGreen{ +0.26 0 0.76 0 setcmykcolor}DC/OliveGreen{0.64 0 0.95 0.40 setcmykcolor} +DC/RawSienna{0 0.72 1 0.45 setcmykcolor}DC/Sepia{0 0.83 1 0.70 +setcmykcolor}DC/Brown{0 0.81 1 0.60 setcmykcolor}DC/Tan{0.14 0.42 0.56 0 +setcmykcolor}DC/Gray{0 0 0 0.50 setcmykcolor}DC/Black{0 0 0 1 +setcmykcolor}DC/White{0 0 0 0 setcmykcolor}DC end + +%%EndProcSet +%%BeginFont: CMR8 +%!PS-AdobeFont-1.1: CMR8 1.0 +%%CreationDate: 1991 Aug 20 16:39:40 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.0) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMR8) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle 0 def +/isFixedPitch false def +end readonly def +/FontName /CMR8 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 48 /zero put +dup 49 /one put +dup 50 /two put +dup 51 /three put +readonly def +/FontBBox{-36 -250 1070 750}readonly def +/UniqueID 5000791 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 +016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 +9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F +D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 +469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 +2BDBF16FBC7512FAA308A093FE5CF4E9D2405B169CD5365D6ECED5D768D66D6C +68618B8C482B341F8CA38E9BB9BAFCFAAD9C2F3FD033B62690986ED43D9C9361 +3645B82392D5CAE11A7CB49D7E2E82DCD485CBA1772CE422BB1D7283AD675B65 +48A7EA0069A883EC1DAA3E1F9ECE7586D6CF0A128CD557C7E5D7AA3EA97EBAD3 +9619D1BFCF4A6D64768741EDEA0A5B0EFBBF347CDCBE2E03D756967A16B613DB +0FC45FA2A3312E0C46A5FD0466AB097C58FFEEC40601B8395E52775D0AFCD7DB +8AB317333110531E5C44A4CB4B5ACD571A1A60960B15E450948A5EEA14DD330F +EA209265DB8E1A1FC80DCD3860323FD26C113B041A88C88A21655878680A4466 +FA10403D24BB97152A49B842C180E4D258C9D48F21D057782D90623116830BA3 +9902B3C5F2F2DD01433B0D7099C07DBDE268D0FFED5169BCD03D48B2F058AD62 +D8678C626DC7A3F352152C99BA963EF95F8AD11DB8B0D351210A17E4C2C55AD8 +9EB64172935D3C20A398F3EEEEC31551966A7438EF3FEE422C6D4E05337620D5 +ACC7B52BED984BFAAD36EF9D20748B05D07BE4414A63975125D272FAD83F76E6 +10FFF8363014BE526D580873C5A42B70FA911EC7B86905F13AFE55EB0273F582 +83158793B8CC296B8DE1DCCF1250FD57CB0E035C7EDA3B0092ED940D37A05493 +2EC54E09B984FCA4AB7D2EA182BCF1263AA244B07EC0EA901C077A059F709F30 +4384CB5FA748F2054FAD9A7A43D4EA427918BD414F766531136B60C3477C6632 +BEFE3897B58C19276A301926C2AEF2756B367319772C9B201C49B4D935A8267B +041D6F1783B6AEA4DAC4F5B3507D7032AA640AAB12E343A4E9BDCF419C04A721 +3888B25AF4E293AACED9A6BDC78E61DA1C424C6503CC1885F762BE0618B16C14 +7386EB4C4B9B3142B9662F48CF5B55DC44261F9F0F975611120F7B9846423136 +B3A568B97F5822B76CF10ECD4CD0C64DC55413CC2E843FB37053EAFE985A98CF +9E408707AB2BBD2F036B622F74397BE4BEFA06A0CC51A30C326C3654B5E548B5 +FD5BE6BFFD05A02E81F12A94892139862012A6776D80F0B7C3E90F8E34918601 +8A6B25676CDD71F0DBD7CF514F0363B15B6C7E62EF9BE227EB164481CC0EF812 +8B8B5FDD0FA1815E629760FDEAA026094F96B05BE963194E99D2E5444F62C26B +1BBAD76672EEC98948B7D9C81CAEBBB7C9CBA16CBDFC595D7AD3F92651B63D50 +CC7E92F4E96C4DE2721AFEE94FBFE5843979D30068BC1F11E5374F6F6EF4586C +AB699727770D97A8681D2E75E907027302832D0834FD7BB48EE89D7F0A39E263 +C34F09602BDEF782A7BCF182CB6D8603E31EF82E669B294BBE9B5AD29CD12FA9 +DD1CAAC8AB4DBB663F8C50472C9D7CF3CFB9AE712D83B306991B89F75A87A6C8 +CF7901236E9EE16204F26C79404A6EB87AC532A29C47C9455D0F3DCCA48E2B26 +1240EB3CD115047EC6C4E3F5B3680127DF7509CD26BEF7C542D0332B2A2F680F +ECAC3A2C958DC3F17576DEBDB9478343EE622DF8C8F7C488ED049690697A6B1D +BAFF45A781099100DD7B0A0598A4A93E088E8B44198EB0DE3761F141AEF45C92 +1A71F32189FEFCC7978570BEBD53305BFB9B68829998196345770721ABAE7410 +50A99976446ABBBF31130CE1A85B4F37B85BBCCD2E31C072B96F005E7506BA7B +6AF46E32CEAB608411DACC4D93ECE77BC4C4282DE8FC4189C8661A93F0A3C0CC +B09077804522B3675B87F45E9E0AB99AFC3F6A979FB2030642DB80CBB4A92BA9 +8FEADF534577FE567839008FEB0F6CD811ACB7CEDCEFC98807636A24B6EDAD43 +83CE013C9E660F3F3DB842554D04B5D8277640A931ED4CC700F8BCFF901775C6 +DBE1A76EE8ADC5601FF1DC4EC663E3E960064875BBCA81F5B82118A055D48C9D +C2DC4C00BB1B42B6C3D00354040080ACAD10EE6A464E5F62E5AC4236FF2D2A6A +BBFE55CD6E55990D15C6A13229F0AB706D61C746EF99E2AF9365 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMSY8 +%!PS-AdobeFont-1.1: CMSY8 1.0 +%%CreationDate: 1991 Aug 15 07:22:10 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.0) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMSY8) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.035 def +/isFixedPitch false def +end readonly def +/FontName /CMSY8 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 0 /minus put +dup 48 /prime put +readonly def +/FontBBox{-30 -955 1185 779}readonly def +/UniqueID 5000818 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964 +7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4 +A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85 +E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A +221A37D9A807DD01161779DDE7D5FC1B2109839E5B52DFBB2A7C1B5D8E7E8AA0 +5B10EA43D6A8ED61AF5B23D49920D8F79DAB6A59062134D84AC0100187A6CD1F +80F5DDD9D222ACB1C23326A7656A635C4A241CCD32CBFDF8363206B8AA36E107 +1477F5496111E055C7491002AFF272E46ECC46422F0380D093284870022523FB +DA1716CC4F2E2CCAD5F173FCBE6EDDB874AD255CD5E5C0F86214393FCB5F5C20 +9C3C2BB5886E36FC3CCC21483C3AC193485A46E9D22BD7201894E4D45ADD9BF1 +CC5CF6A5010B5654AC0BE0DA903DB563B13840BA3015F72E51E3BC80156388BA +F83C7D393392BCBC227771CDCB976E93302530FA3F4BEF341997D4302A48384A +CEFFC1559462EA5F60DC05245E8499D8E61397B2C094CEED1AF26EE15A837209 +ECE64FEF41ABE8DDA7BE1F351CF14E07BA8FD40CEFBFC3CE7B9D4912D6FE752D +9CF163084E688DDCC4B5AAEDEB6E94DDDE34330BA35394A8B485E767F0F94A71 +4532F3B89C51AC3FD1C082EF41EA489B9595B4120FDCA2F599C88F5058126CD1 +4C7F96B4FE22BAB1A5E16F215DECBCE4186C68B6263BD5331CDC1FF9F30332A7 +7B831255A41A642C5719272C6B5993171CA395A0D11B6376457EC30E1CDE47A4 +9B9EE95D112C64084901B6357E881C0DEB6836B80F21E57B660388BA4F7B89EB +9AF7DE8AEA702FC5B765552F78058A20E424277F667A4E9955A797593CE44E19 +A98F149CA17D6379040A1C836CA18234278DFDA205EFD55D527C7F38766D4C97 + +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMMI8 +%!PS-AdobeFont-1.1: CMMI8 1.100 +%%CreationDate: 1996 Jul 23 07:53:54 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.100) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMMI8) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.04 def +/isFixedPitch false def +end readonly def +/FontName /CMMI8 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 110 /n put +readonly def +/FontBBox{-24 -250 1110 750}readonly def +/UniqueID 5087383 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE +3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B +532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 +B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B +986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE +D919C2DDD26BDC0D99398B9F4D03D6A8F05B47AF95EF28A9C561DBDC98C47CF5 +5250011D19E9366EB6FD153D3A100CAA6212E3D5D93990737F8D326D347B7EDC +4391C9DF440285B8FC159D0E98D4258FC57892DDF753642CD526A96ACEDA4120 +788F22B1D09F149794E66DD1AC2C2B3BC6FEC59D626F427CD5AE9C54C7F78F62 +C36F49B3C2E5E62AFB56DCEE87445A12A942C14AE618D1FE1B11A9CF9FAA1F32 +617B598CE5058715EF3051E228F72F651040AD99A741F247C68007E68C84E9D1 +D0BF99AA5D777D88A7D3CED2EA67F4AE61E8BC0495E7DA382E82DDB2B009DD63 +532C74E3BE5EC555A014BCBB6AB31B8286D7712E0E926F8696830672B8214E9B +5D0740C16ADF0AFD47C4938F373575C6CA91E46D88DE24E682DEC44B57EA8AF8 +4E57D45646073250D82C4B50CBBB0B369932618301F3D4186277103B53B3C9E6 +DB42D6B30115F67B9D078220D5752644930643BDF9FACF684EBE13E39B65055E +B1BD054C324962025EC79E1D155936FE32D9F2224353F2A46C3558EF216F6BB2 +A304BAF752BEEC36C4440B556AEFECF454BA7CBBA7537BCB10EBC21047333A89 +8936419D857CD9F59EBA20B0A3D9BA4A0D3395336B4CDA4BA6451B6E4D1370FA +D9BDABB7F271BC1C6C48D9DF1E5A6FAE788F5609DE3C48D47A67097C547D9817 +AD3A7CCE2B771843D69F860DA4059A71494281C0AD8D4BAB3F67BB6739723C04 +AE05F9E35B2B2CB9C7874C114F57A185C8563C0DCCA93F8096384D71A2994748 +A3C7C8B8AF54961A8838AD279441D9A5EB6C1FE26C98BD025F353124DA68A827 +AE2AF8D25CA48031C242AA433EEEBB8ABA4B96821786C38BACB5F58C3D5DA011 +85B385124C2B6534F3CD1866AF92009D93B97F763AA3CF46C60636D7FC1564CF +1DDFBC12CA37D27A79B11F2AFF2D70DBEE03CF1DFA5B864A2DC22266E4FA43DC +3F2CC229231F1F72874E6A74A90E8003B9AF1BFAA55C071FDDE5C94E4AE3C5BF +936EDFD4164624881410AB9EF0593F823D40BA7D059992104D08E41EBAD8F276 +A84EE2C9AEBC7CCB72AA6B6E6FE52293DC7BC34C2D1B69418392608FC5920291 +733654FA401E05F3E647B1C6AF4BECC3E802F9963344B05EC3DE8C774293CDB4 +3F057D6F258BD341848FA7FDCFD4D1923FCAB51FA8ADAE6D9F19C1FFA6EB5E9F +ECF844CEC6C1320D3F00C7259EF5812526F58248C61F89A42D9C9288CA8076FA +77E1C950940D8D6A7D852A0D0ABEBF2EDEDCDF6DDE0C8CCAC8DA9B28207D9CF8 +46446E1153D8D8795EE914B12349137D4BE461BCF5A6A3CF15FA5B9E91EB9B90 +0483916D0CD40EDC29EB0B996B16462A64F3B19B57802D9AFE3F1D91D9A8553C +531EB8B4E975037ED620EED3020388BFE705958B1E3AD4638B9CC8644C2F4024 +5DACD97151C3DF7A448CC3 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMMI10 +%!PS-AdobeFont-1.1: CMMI10 1.100 +%%CreationDate: 1996 Jul 23 07:53:57 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.100) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMMI10) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.04 def +/isFixedPitch false def +end readonly def +/FontName /CMMI10 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 59 /comma put +dup 76 /L put +dup 85 /U put +dup 102 /f put +dup 103 /g put +dup 104 /h put +dup 105 /i put +dup 110 /n put +dup 120 /x put +readonly def +/FontBBox{-32 -250 1048 750}readonly def +/UniqueID 5087385 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE +3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B +532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 +B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B +986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE +D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958 +9E394A533A081C36D456A09920001A3D2199583EB9B84B4DEE08E3D12939E321 +990CD249827D9648574955F61BAAA11263A91B6C3D47A5190165B0C25ABF6D3E +6EC187E4B05182126BB0D0323D943170B795255260F9FD25F2248D04F45DFBFB +DEF7FF8B19BFEF637B210018AE02572B389B3F76282BEB29CC301905D388C721 +59616893E774413F48DE0B408BC66DCE3FE17CB9F84D205839D58014D6A88823 +D9320AE93AF96D97A02C4D5A2BB2B8C7925C4578003959C46E3CE1A2F0EAC4BF +8B9B325E46435BDE60BC54D72BC8ACB5C0A34413AC87045DC7B84646A324B808 +6FD8E34217213E131C3B1510415CE45420688ED9C1D27890EC68BD7C1235FAF9 +1DAB3A369DD2FC3BE5CF9655C7B7EDA7361D7E05E5831B6B8E2EEC542A7B38EE +03BE4BAC6079D038ACB3C7C916279764547C2D51976BABA94BA9866D79F13909 +95AA39B0F03103A07CBDF441B8C5669F729020AF284B7FF52A29C6255FCAACF1 +74109050FBA2602E72593FBCBFC26E726EE4AEF97B7632BC4F5F353B5C67FED2 +3EA752A4A57B8F7FEFF1D7341D895F0A3A0BE1D8E3391970457A967EFF84F6D8 +47750B1145B8CC5BD96EE7AA99DDC9E06939E383BDA41175233D58AD263EBF19 +AFC0E2F840512D321166547B306C592B8A01E1FA2564B9A26DAC14256414E4C8 +42616728D918C74D13C349F4186EC7B9708B86467425A6FDB3A396562F7EE4D8 +40B43621744CF8A23A6E532649B66C2A0002DD04F8F39618E4F572819DD34837 +B5A08E643FDCA1505AF6A1FA3DDFD1FA758013CAED8ACDDBBB334D664DFF5B53 +95601766758C197F327101A9C9BF396ED625E27A7791ADF7474135C50F2F927A +5B5E332A003F858399565E4C02931D19AC2866CEFAB2288ACA215F2B7BE37156 +89009B14D623E0A872AC17AA52D29EA6E8D725A05A300AAD937745F61803544E +978846734C4C8FEA576A5D77903920CF4531C051776BBDF99ABD8C09849E586C +ED0E1D51A0047D2FF9097EA10DE0E397D69BC302D7A949CC435EE46C508FB6D6 +DAA66F2EDD3A6881D50A440A702018A99102DE5039F7CA1EF9F4C36D5C66AA4C +97C81079C961F48C6EC9E1C26E3740945443C9A262373410B96043CF52CA074A +D18DAFCE0ADE27C2C4A109C21C1B2A8E2F9DF1F14ED57195984F76A5B4213F69 +53C017777402DB63066D528BD2C690959CFE72FAE34C98CA3E797C3CE2B8544E +143B2BB6D7ED137528BC8BB4AB4BB49A295C43C96E92D2D4AA0157DD37CFE2DA +921259A6876045871A994E1316BD39142279BEED0AFCAE7F8D847650D409C934 +D8D16486AC153C8C6F5849270F71DBB5A744A258D5EF64F8819025F49B5A3D29 +889F9CE6CAFB1A44F503559B63B9BEB727C9FD6F99F1E618DEC55C349E1D24BA +3E4599AC645E89E2852D0E152DC94465071B3835EDC93C2924778DFAC1664734 +98F5583DDF83315203AAF78897CE1768F22083276F6D29D07C72CE4B3FF6F293 +28DC673F80626F8654E4FCF6A0263C1DB7AC8F63790729256F9B969908F3A176 +05D7AD6ED5F8E8AF79890282AE7B4C55AEE6526920983A72C5876DE620CF4E3A +7D1376FEF0B296F62C5C29D8D9BEE6B622AAFB66335001F92DAA1E119CFD5101 +08FCB0F238A64FCF56A62C7C08C0871C8D15DB0374C53D39CCD8B1058BAA3FAF +F9785E2D17FCE278B5179EB8AE77B6F1ADBDA6284B0658A07D91B044ABD82EE8 +C9F1763A966496728615DD1EBAB159D7CF6168DBB2582815DA6733785828DF75 +D6848392D3E479E5527DFC967F36D3D66CA6FE01FC6FA9BF6AD401051013DE6A +C69971B1271DFE6ED6A8B53B394CE11FEE75CB1F9AB278A74FD2765FFA3773F9 +F61B5B11C462CE38287536B946E7BD1F8AE0C8F5804B04AFDBB624A2489DAE07 +903F90656C96D1E1C2101FBB9B48C66BFED1B572CEEA04A16AAFE734E754251F +EC12CAF4D56AA5A936D40CBB44E76FF4780B8594967138A1E3092254DB2D4C2C +CDECE9AF76FAF9B3DED9847C79C1723CDD328E4B0B15566C6CD8490ADFEB9169 +418B34C36EF4FB43EF7FB5F1BFE7F795E85FEBA443DCABD076418BA94DAE6505 +D4E6075D792C0C1A6BDFF56326FBA965DFB9519F072BBB8CA486D4C9AA6FCF62 +3CDACB91B41C69837DB4E6DACD0AC582A044D526E340343720AED1742DC4E52F +67579B3A625C4B5E508BCFF3DA667DAE69B25F9D50996033797C42D7CBD85F99 +AB2CDCF739E3B2C6AEA3C315AC2D0F0D48B293B1397A9C1E304260CD8D0C3497 +27385284419D6B3BFCD701C367149332FA1A58EAA22A193C24375D40482129C0 +55BD4147CF597B64FD1F3F3545A03235B6918790D39B7473FE8AE5ED218500D2 +1F6B8EE7632762D06578544C16D9D3866B4A8295904C95CE224E15044770C7B8 +F7408C215A0FA286CAE554D3C51D6BF20B33F4890784816A1AD1B202C381DA82 +01CBEFC0B043181DCD849BCCF035C87708B6E3A9CE4D68B61E35B9CF54123A30 +0939400BA136E6CD4D30F42259ADDAAC17D613E6998BBE4F37C414F397D802AF +83EB5B4247C648B834C3F59C566F252EACE08706E410299F72BEAB9A49274E5E +74F834B4A5983F4C00932124B5D9DFA54E5EF7C1CB9A97C29B49BBCE6F00AE13 +E9CB172D2033E719841728DAB47C858BA8C0687B844B7FC5C2513F5A88A9E5DF +436A28193F1C9A42F840634CCB6681EFC5249080769728E330520A5D6D50164C +0C9A8456535BC89E45BDA70C62CC42C5E750470EFAE512202D95E5BAF604352E +8001E29161B7D6FB6CAD331E42E636021B2854923894715B496038F4AEDBD1E9 +12CC6F15B440C87B8633C43B5D696AFE0C8ACDDC98503A6B3F8685987D178FD6 +E3E8DC9763CCB10ED3D8E065CF3354496D648053B2F0B7B5596528AA91EB6F7D +F7E856ECB8DDB8523CAB5CB6349827450C58A3B007CB9928AF1E98DF77D84B4A +A97B85CEC023289C82A2189AB947C56BAA64911653C2FFFB4D546F3A08821136 +14E904163C9F1CBC64BCC368CBE5764423BB308364B8CA907F38687A153BB01F +6BAE773B21DB3FFE55F9523A52C6286FA2C090F4B8EA11A7C793AC55AAEDDF0C +5E9219B11A940F1ACDE2E124F42F040C9B29D8A56099B0592E1FC33C42B5BAF5 +5CD5E0997B66D81132C4DEE5A9B34AB0761164E23B1418D9AF2EF466EE648BF7 +B550A0559B37AA4EEFE096D5B7B65A891FBB0364CDB8FAC49A7011152CA04B0C +4A91E982CF0E718DBDCAE97F90BC2D22EEA14CDE4003702563D5E02D758A3839 +4A4DDC3DF05069E1F23CB5B5ED68DBFDD1E26FF41967D5158056D86DE8BFAE94 +407645A693988C796417224C91661505FA3983863E2563E4228A5E76BA5E72B9 +10C08AF95D0C4C29E812EF8B3E2CD401562C1C7A35E49054D492DE9712D89C49 +FCB524E3D479A05DABA3D774E30F247A9287407468809AB93E53C3F9B5F5A6D7 +74F447C46BDA6AC95BBFF5A39268259C1E4A4C16FBE30C2DAD58C1D3F9DF5887 +CFE667D2E29DDBA05CE796355F0E1EC3A10FA0421074651E0B584FBD4A04D4C1 +3B4E8E729EB0F7676958F4A3677504132AEAF0DF00F781E4CC4E055917D0F363 +327C3C8E48E75675D425B02D4387269FC8487A325155B0335D +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMR10 +%!PS-AdobeFont-1.1: CMR10 1.00B +%%CreationDate: 1992 Feb 19 19:54:52 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.00B) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMR10) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle 0 def +/isFixedPitch false def +end readonly def +/FontName /CMR10 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 40 /parenleft put +dup 41 /parenright put +dup 43 /plus put +dup 48 /zero put +dup 49 /one put +dup 50 /two put +dup 53 /five put +dup 61 /equal put +readonly def +/FontBBox{-251 -250 1009 969}readonly def +/UniqueID 5000793 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 +016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 +9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F +D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 +469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 +2BDBF16FBC7512FAA308A093FE5CF7158F1163BC1F3352E22A1452E73FECA8A4 +87100FB1FFC4C8AF409B2067537220E605DA0852CA49839E1386AF9D7A1A455F +D1F017CE45884D76EF2CB9BC5821FD25365DDEA6E45F332B5F68A44AD8A530F0 +92A36FAC8D27F9087AFEEA2096F839A2BC4B937F24E080EF7C0F9374A18D565C +295A05210DB96A23175AC59A9BD0147A310EF49C551A417E0A22703F94FF7B75 +409A5D417DA6730A69E310FA6A4229FC7E4F620B0FC4C63C50E99E179EB51E4C +4BC45217722F1E8E40F1E1428E792EAFE05C5A50D38C52114DFCD24D54027CBF +2512DD116F0463DE4052A7AD53B641A27E81E481947884CE35661B49153FA19E +0A2A860C7B61558671303DE6AE06A80E4E450E17067676E6BBB42A9A24ACBC3E +B0CA7B7A3BFEA84FED39CCFB6D545BB2BCC49E5E16976407AB9D94556CD4F008 +24EF579B6800B6DC3AAF840B3FC6822872368E3B4274DD06CA36AF8F6346C11B +43C772CC242F3B212C4BD7018D71A1A74C9A94ED0093A5FB6557F4E0751047AF +D72098ECA301B8AE68110F983796E581F106144951DF5B750432A230FDA3B575 +5A38B5E7972AABC12306A01A99FCF8189D71B8DBF49550BAEA9CF1B97CBFC7CC +96498ECC938B1A1710B670657DE923A659DB8757147B140A48067328E7E3F9C3 +7D1888B284904301450CE0BC15EEEA00E48CCD6388F3FC390E75D51F36C3E61E +E84B5AD036ADADEBD4F8D399AA559B34270D370DEDF077D1D49253F313C333CB +F22FD740EDE076FE3383503F159888E77132A06528CEBA5BB0E57C07D36B73D7 +C81B71200D95D73A1AD33BBA5CA3E34B94447EAB8D27625CBFF13B56F87A9B74 +4B52A09BAB0AABD5E398B1E5E9868BC080EFC7ECBDA4D6817C3255A51A814A04 +0839172E2CCECB4F6E7B5B6B3B61D5858256AD27D93969EBB34C7EE68BF805D0 +39CA6AC7DECCD1A395E7BA297AB0E97B3290EDAED775EAB0D7D553F222A3B014 +FFA358EE448BBB24E1B44CE0BB474DFA01B0F4C4964248444FCA4DDEA8FDA9B8 +82F96DCBEF94CAC9C8F48922899CB1E7D70F650E6471E5408C44554E72599D97 +BC1D32360ECFB378192605E726A3DDA7E5B02736CEB7BE8A5C27AE952F4946D0 +1DD1D65C1D50D0317984B781D64B6075D35EC1E3507FD4FE2E7097A0EE116EEC +3497D2D84B19F68EBF7125FB02920466AE4FE25A3C3068A83A513556D05359A3 +93B6C6929BA47044787EEBA3A38E8266CF1D13DB69779644DF8AFE2C2C5C81F9 +75CBC9CA07E6CB70211CA62FD7CF596132333970E5233AAFBF984EC110664810 +AEFBADCE663CADF91D36D1587C5D7E7F63E3A674856AD7CDB99CD276D3659ED0 +CA0FDC17251E69BA7F2F3AC57257831C31AFBB0DADF44F7E6EF84D63C03E75FF +886FFDAF8153EA8E0779E46935AB0AEFC84AC2061291D39E5F67FB75BEA48EDA +030512CDB14B16D466CFBC58D3764B83AF5C00D05A3F052F53BBE4E1417773CA +BDBEAC50BB7BFF981255BDA6650870E4D67BCB80A63BA050F2650934CB6E742B +B2B2A115C1F9827C979E8F2E92C0A1F428288643C8A27B7105587366E1BFF1FB +056DE92CAD4A7F391A483DE4E9930E8C5BA9B215F1E3FA4798A1740A9B72810A +44CD1D1ECAC8ED7BA3655C4EEF6BF28A2B0B23B0BF783A4FBDDB1246B5EEA601 +6440F98C0A3B6ED360561479EA83990A78A0F4608698B30FE6476AED9349D11F +FB467D3C19D7A3539B8A2DA0C54454A231B87FB441A1BE6893E0F67081E8FF09 +FC20412C452D8227D4BA7665EA8F14A1987845CF8570EDD926F4EF5F2D85DB99 +736D7A939D4313F589033FA135D6366EB8B63C026357360A9E8717656ADABA76 +11B9D672B7D57F1422CAEA295A774CB1F6BEAE51A7A9F7EACF6F22CC6412F1D6 +9DDF884EB94F91B5F301039EE962C51F7FCEF8319CE80F46A7E3187EE60342DB +4057C2374CF68AAD30B5979B24D41ED8A803A1E6EA845D7E7675031A2D4257D8 +4BE91A75006673CE3C24AA4C4138EED6DE5147FD16049BC523D54F26BF951AAC +85157DB39E8B38798267AE2E5266331CFAA0E4D18D2F5C50277BE056498E569E +90AB0A7127F94F0EEC3FC2DC7BF421A2A855318646BACC78EC03D14CC41AB9CA +61649659F81614F8FA9E052F37445DBAF2B0873A06015E16A268544FB047AD0A +E9EF324844E8CA272D00944D54B691CA137E1CF59B69F59D5F9A40EEA081C9EC +6AD88DB832E588F5AACA900198105A8D59C215DCD387B32FE34E9B8476AB5C7A +B739EEE6840ACBFDC79501A04FFB2A57D3A4D3D181D68F074DFB0E828C41FBE3 +E7D0F2A7CE0AC1C7ED09FD9C6E085C89E8BC46BA83A8CED54EDB6EDE1B55B349 +84C37F33BB71994A8EF29050A902448E21CA0B2B5E9DDCF43ACBB79CC841E7EA +5D8BA0D8C18DDFB3B72559BF6251A5F026FAEB035509D20058FEC5FDB1B7E329 +3E299B4FBDF2BD3A5D27035BB8732C3688C3C203D1664522CEBC8BCAC7D4E643 +6490E8CAE79FB51F9285A64099719EA841CD4710392D94660920608397214CEA +588A9CFC233DA75C7C8F381ECEA4065F431122D472D333B2E260DB32F5CCCB15 +56BB953DEC3B6E451B212ABBE079888B73C48744CF5A9C1DCB47C423C647A94F +2B4358B020B2C5FDF1D4B7BE081BC0F4EA86359DFE9BDCC1CBDA475618A71ED4 +F61834FCC9DAA616C7C8D2407333ECE57AD5F5F43FD077EB12C2310BF7EB1EFC +1EAEE06F0891DEFD32AF69082D203207524CA6DC8005C22C1C1CE2C6CBED42B3 +122148A0A6BAFC0DEEEC37594B68494BB5EF16E510C1CD4BF3F6597F98E5362C +544F51DC368425AD6A867D1E6E9AB208C77982536D56581A539597DC172F1D09 +BF027427518C4CCD96BD4321DD8FF54C8D034F66F32F3A2DDFA05E33E5C5408B +8C8511FE0E8F52F38475B84E2A2F5F7B09F8F92D8E1DE2754E683A39EE71BD78 +EFFA9E0804386F6B98CB37112C4A8844C8E2F26C8920CD18089BE16D20922DD4 +AF2EFCE40BCFFB79A001E1DFF89AC67B02FFB09FD38354B57A5FAD9BA3640064 +E4CB7CFC355B5384699A57E86513CA2F89B938688A3F42A6FDBC6E92D50C050E +B96AFCE7691A96AEC83213FC00BD81EA3895 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMSY10 +%!PS-AdobeFont-1.1: CMSY10 1.0 +%%CreationDate: 1991 Aug 15 07:20:57 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.0) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMSY10) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.035 def +/isFixedPitch false def +end readonly def +/FontName /CMSY10 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /periodcentered put +dup 15 /bullet put +dup 102 /braceleft put +dup 103 /braceright put +readonly def +/FontBBox{-29 -960 1116 775}readonly def +/UniqueID 5000820 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964 +7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4 +A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85 +E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A +221A37D9A807DD01161779DDE7D31FF2B87F97C73D63EECDDA4C49501773468A +27D1663E0B62F461F6E40A5D6676D1D12B51E641C1D4E8E2771864FC104F8CBF +5B78EC1D88228725F1C453A678F58A7E1B7BD7CA700717D288EB8DA1F57C4F09 +0ABF1D42C5DDD0C384C7E22F8F8047BE1D4C1CC8E33368FB1AC82B4E96146730 +DE3302B2E6B819CB6AE455B1AF3187FFE8071AA57EF8A6616B9CB7941D44EC7A +71A7BB3DF755178D7D2E4BB69859EFA4BBC30BD6BB1531133FD4D9438FF99F09 +4ECC068A324D75B5F696B8688EEB2F17E5ED34CCD6D047A4E3806D000C199D7C +515DB70A8D4F6146FE068DC1E5DE8BC57030ACE57A0A31C99BEDB251A0ECAD78 +253AB3339E847FBB1AF693606A973F6ECD887C325CA59C6A4A9AC48AF5551D10 +EE26B8C4DA13F670D3F0C09187B9AB37F2BA6A32F8D363393D22215650EEE7F8 +DFB1378390C44F36098EA2DA6CB943DACFB8AECD62E46F120BE7A15C19200094 +7975CA278BAF5E155531F90FCBFE67D2AC15BA6E3B15FEF09F697956F198D111 +16292151DECACDAF2B2CF42B82DE6D4515735744887745770F8D8656BAEEFC04 +2F6A832F466D4244F1F9998BF49A413F094108FC90F586AEB324888BD885F2A1 +C749504E6DCB10F6A2B797826939AFA46BD208A268FB4C6635264B2B39F6E11E +34ED5B3D02E6C9178BFE61AE0A0B6B789E394F8A33730EC5E4484F2D962268F5 +8FD36EAD6CF68C7120E82FD8B2EA91095227CFF985054557361FD9B1E8FACB8C +A17AD35513D4D69B5D52470A6B4796299442430E66AAB39A574CF4C4D0838C52 +B675FB04C646FE52C599EA039302B200CEA102986E6549225D22F30455B7947B +5DCF0190B5296E12FA026272B1D2076B630CABB8F71589ECB69B95486A650A09 +05D11C00F0909A7228A107C7D27074FC6B5380FB3534816E122D65369D70C68E +98E1951DA9756B3CD665F378B661506661175A89D37889CDB07D1692988875EE +878DC0771EF29DDB382287584FE12E47FD7CEE6C130E2D2B3028C8C54B83C977 +26845C0960D62A50B290605368BE2568340524244ABCEE470B683E92456DEE76 +228DCCBDBC688458DF63F2C1E4D8BA46657CB79B9E28179AD2459603874FC200 +CAB2ABDBD725DB89EB7E7C5DFE03826FC7EA65F57CF87E382A976D70F44596B5 +53C6DC34FE7F2B295D67AA8A550F1DF1D040237352D42F14D1D0E7A23318E53B +BA0958CC11E47508EE8D9DCAB8116452978F0963222D14739F8E890A39AB41BC +B66B92570A18 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMMI12 +%!PS-AdobeFont-1.1: CMMI12 1.100 +%%CreationDate: 1996 Jul 27 08:57:55 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.100) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMMI12) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.04 def +/isFixedPitch false def +end readonly def +/FontName /CMMI12 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 60 /less put +dup 62 /greater put +readonly def +/FontBBox{-30 -250 1026 750}readonly def +/UniqueID 5087386 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE +3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B +532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 +B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B +986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE +D919C2DDD26BDC0D99398B9F4D03D6A8F05B47AF95EF28A9C561DBDC98C47CF5 +5250011D19E9366EB6FD153D3A100CAA6212E3D5D93990737F8D326D347B7EDC +4391C9DF440285B8FC159D0E98D4258FC57892DCC57F7903449E07914FBE9E67 +3C15C2153C061EB541F66C11E7EE77D5D77C0B11E1AC55101DA976CCACAB6993 +EED1406FBB7FF30EAC9E90B90B2AF4EC7C273CA32F11A5C1426FF641B4A2FB2F +4E68635C93DB835737567FAF8471CBC05078DCD4E40E25A2F4E5AF46C234CF59 +2A1CE8F39E1BA1B2A594355637E474167EAD4D97D51AF0A899B44387E1FD933A +323AFDA6BA740534A510B4705C0A15647AFBF3E53A82BF320DD96753639BE49C +2F79A1988863EF977B800C9DB5B42039C23EB86953713F730E03EA22FF7BB2C1 +D97D33FD77B1BDCC2A60B12CF7805CFC90C5B914C0F30A673DF9587F93E47CEA +5932DD1930560C4F0D97547BCD805D6D854455B13A4D7382A22F562D7C55041F +0FD294BDAA1834820F894265A667E5C97D95FF152531EF97258F56374502865D +A1E7C0C5FB7C6FB7D3C43FEB3431095A59FBF6F61CEC6D6DEE09F4EB0FD70D77 +2A8B0A4984C6120293F6B947944BE23259F6EB64303D627353163B6505FC8A60 +00681F7A3968B6CBB49E0420A691258F5E7B07B417157803FCBE9B9FB1F80FD8 +CA0DA1186446DD565542BCCC7D339A1EB34C7F49246E8D72E987EB477C6DB757 +99AF86CEBCD7605C487A00CD2CD093098182DC57B20D78ECE0BECF3A0BF88EBA +C866DB19F34BBBED6634AFC0F08D2AFB2A92578A6F8B4ADCD6594737FF6EED7D +5B536DA9E3E2CADB40DB7C600EA4D100D33C3B92B1CF857E012C4EB370BA8295 +55B50047CD58E912E67E22C1B92F41D0BEE742201DF198F3766AE35EA71D8195 +A8C94D661C40D718CB09497485FAA34204229AECFE644C93FFDA54C789E4F751 +3D2519F7CB9E79B2ABE3101DF2EBFAD375469CDC687FB3DC2833EDC0F946B41F +F28D72FFF2A9B8B0D76DC542537612E2BE0F3FB9601C897386359C55E867A547 +F872005F5C56C6EC5E9685E03D7A82653BE8B69741C4DF332AEEB2AA450B23F3 +EABD5ED060606CC7DB1762632EC3C6C4A66ADAF61A97D949DEA5156B4CF34765 +67AC3F10AE17199A710A882D47979F9D41AA2CB794648BE47479F0B00E18BF04 +923F54CEC1214BAFA39BB65ECB013875899E9901B7882D16D2E2C97AD3353668 +A6070081E4DC627AF9192599F5876369908FBDFA11E8D6CB2E83896E9C897CEC +FD1D25651D66A333AF531FF74E1B0DEB1E3D1B5B7D3FB9D1C8BF60517B31C8D2 +1C264F44BC9AF3D9BA5280D1618EED96C11ED24F789FAA263394C658DFCA8DE9 +D47D9E188E212F9EC1DCF449DFDAB8437FAB9EA9AF01AE1714E8F932855182 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +TeXDict begin 40258431 52099146 1000 600 600 (cudd.dvi) +@start /Fa 137[40 51 1[35 35 8[25 2[30 40 45 40 16[61 +13[66 61 67[{ TeXBase1Encoding ReEncodeFont }12 90.9091 +/Times-BoldItalic rf /Fb 136[50 7[37 2[21 108[{ + TeXBase1Encoding ReEncodeFont }3 74.7198 /Times-Italic +rf /Fc 204[35 35 35 35 48[{}4 66.4176 /CMR8 rf /Fd 207[19 +47[55{}2 66.4176 /CMSY8 rf /Fe 133[33 37 37 54 37 37 +21 29 25 1[37 37 37 58 21 37 1[21 37 37 25 33 37 33 37 +33 9[71 54 54 46 11[54 2[46 54 50 7[21 21 10[21 19 25 +19 41[42 2[{ TeXBase1Encoding ReEncodeFont }39 74.7198 +/Times-Roman rf /Ff 201[25 25 25 25 25 25 49[{ + TeXBase1Encoding ReEncodeFont }6 49.8132 /Times-Roman +rf /Fg 201[33 33 33 33 33 33 49[{ TeXBase1Encoding ReEncodeFont }6 +66.4176 /Times-Roman rf /Fh 130[55 55 55 55 55 55 55 +55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 +55 55 55 55 1[55 1[55 55 55 55 1[55 1[55 55 55 55 55 +55 55 55 55 55 55 2[55 55 55 55 55 55 55 55 55 55 55 +55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 +55 55 55 55 55 2[55 1[55 55 55 33[{ TeXBase1Encoding ReEncodeFont }84 +90.9091 /Courier rf /Fi 133[44 50 1[72 50 55 33 39 44 +55 55 50 55 83 28 55 1[28 55 50 33 44 55 44 55 50 6[66 +2[100 72 72 66 55 72 1[61 78 1[94 66 78 1[39 78 78 61 +1[72 72 66 72 7[50 50 50 50 50 50 50 50 50 50 28 25 46[{ + TeXBase1Encoding ReEncodeFont }56 99.6264 /Times-Bold +rf /Fj 145[43 110[{}1 66.4176 /CMMI8 rf /Fk 135[52 9[55 +4[31 52 43 45 16[62 8[62 16[25 59[{}9 90.9091 /CMMI10 +rf /Fl 194[71 7[45 2[45 45 45 4[71 1[35 35 40[{}8 90.9091 +/CMR10 rf /Fm 152[45 45 86[45 13[25 1[{}4 90.9091 /CMSY10 +rf /Fn 133[35 40 40 61 40 45 25 35 35 45 45 45 45 66 +25 40 25 25 45 45 25 40 45 40 45 45 6[51 1[56 76 56 66 +51 45 56 66 56 66 61 76 51 61 40 30 66 66 56 56 66 61 +56 56 7[45 1[45 3[45 45 45 2[23 30 3[30 30 30 35[45 45 +2[{ TeXBase1Encoding ReEncodeFont }63 90.9091 /Times-Italic +rf /Fo 87[30 16[91 45 1[40 40 24[40 45 45 66 45 45 25 +35 30 45 45 45 45 71 25 45 25 25 45 45 30 40 45 40 45 +40 3[30 1[30 56 66 66 86 66 66 56 51 61 66 51 66 66 81 +56 66 35 30 66 66 51 56 66 61 61 66 5[25 25 45 45 45 +45 45 45 45 45 45 45 25 23 30 23 51 1[30 30 30 1[76 33[51 +51 2[{ TeXBase1Encoding ReEncodeFont }82 90.9091 /Times-Roman +rf /Fp 105[45 27[40 45 45 66 45 51 30 35 40 1[51 45 51 +76 25 51 1[25 51 45 30 40 51 40 51 45 6[61 66 66 91 66 +66 61 51 66 1[56 71 66 86 61 2[35 71 71 56 61 66 66 61 +66 5[30 30 1[45 1[45 45 45 45 45 45 45 1[23 1[23 52 3[30 +36[51 2[{ TeXBase1Encoding ReEncodeFont }63 90.9091 /Times-Bold +rf /Fq 135[60 86 1[66 40 47 53 2[60 66 100 33 66 1[33 +66 60 40 53 66 53 1[60 11[86 80 1[86 1[73 2[113 3[47 +93 93 2[86 86 1[86 10[60 60 60 60 60 60 5[68 3[40 39[{ + TeXBase1Encoding ReEncodeFont }38 119.552 /Times-Bold +rf /Fr 193[76 1[76 60[{}2 99.6264 /CMMI12 rf /Fs 133[44 +50 2[50 50 28 39 33 1[50 50 50 78 28 2[28 1[50 33 44 +50 44 50 44 11[72 1[55 12[55 61 72 66 66 1[92 11[50 1[50 +50 50 1[25 1[25 44[{ TeXBase1Encoding ReEncodeFont }34 +99.6264 /Times-Roman rf /Ft 140[56 48 2[72 72 112 40 +72 1[40 1[72 1[64 1[64 1[64 11[104 2[96 1[80 11[104 96 +8[40 4[72 2[72 1[72 1[36 46[{ TeXBase1Encoding ReEncodeFont }22 +143.462 /Times-Roman rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin + end +%%EndSetup +%%Page: 1 1 +TeXDict begin 1 0 bop Black Black Black Black 804 937 +a Ft(CUDD:)34 b(CU)i(Decision)d(Diagram)h(P)n(ackage)1558 +1120 y(Release)g(2.5.0)1643 1373 y Fs(F)o(abio)25 b(Somenzi)720 +1489 y(Department)f(of)h(Electrical,)g(Computer)l(,)f(and)h(Ener)n(gy)g +(Engineering)1261 1605 y(Uni)n(v)o(ersity)e(of)i(Colorado)f(at)h +(Boulder)1408 1721 y Fr(<)p Fs(F)o(abio@Colorado.EDU)p +Fr(>)1601 1923 y Fs(February)h(4,)e(2012)448 2316 y Fq(Contents)448 +2523 y Fp(1)92 b(Intr)n(oduction)2315 b(4)448 2726 y(2)92 +b(Ho)o(w)22 b(to)i(Get)f(CUDD)2077 b(5)585 2839 y Fo(2.1)96 +b(The)23 b(CUDD)e(P)o(ackage)92 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 171 w(5)p Black 585 2952 a(2.2)96 b(CUDD)21 b(Friends)81 +b(.)45 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(5)p +Black 448 3156 a Fp(3)92 b(User')m(s)23 b(Manual)2238 +b(5)585 3269 y Fo(3.1)96 b(Compiling)24 b(and)g(Linking)53 +b(.)45 b(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(6)p Black 585 3382 +a(3.2)96 b(Basic)23 b(Data)h(Structures)51 b(.)45 b(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +p Black 171 w(6)p Black 794 3495 a(3.2.1)110 b(Nodes)41 +b(.)46 b(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 +w(6)p Black 794 3608 a(3.2.2)110 b(The)23 b(Manager)60 +b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(7)p Black 794 +3721 a(3.2.3)110 b(Cache)46 b(.)g(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +p Black 171 w(8)p Black 585 3833 a(3.3)96 b(Initializing)26 +b(and)e(Shutting)h(Do)n(wn)e(a)g(DdManager)78 b(.)46 +b(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(8)p +Black 585 3946 a(3.4)96 b(Setting)24 b(P)o(arameters)87 +b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(9)p Black +585 4059 a(3.5)96 b(Constant)25 b(Functions)66 b(.)45 +b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(9)p Black 794 +4172 a(3.5.1)110 b(One,)23 b(Logic)g(Zero,)g(and)h(Arithmetic)h(Zero)41 +b(.)46 b(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +171 w(9)p Black 794 4285 a(3.5.2)110 b(Prede\002ned)24 +b(Constants)51 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(10)p Black 794 +4398 a(3.5.3)110 b(Background)36 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(10)p Black 794 4511 a(3.5.4)110 b(Ne)n(w)22 +b(Constants)65 b(.)45 b(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(11)p +Black 585 4624 a(3.6)96 b(Creating)25 b(V)-10 b(ariables)28 +b(.)45 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(11)p +Black 794 4737 a(3.6.1)110 b(Ne)n(w)22 b(BDD)f(and)j(ADD)e(V)-10 +b(ariables)43 b(.)i(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)p Black 125 w(11)p Black 794 4850 a(3.6.2)110 b(Ne)n(w)22 +b(ZDD)f(V)-10 b(ariables)81 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(12)p +Black 585 4963 a(3.7)96 b(Basic)23 b(BDD)f(Manipulation)47 +b(.)f(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)p Black 125 w(12)p Black Black 1920 +5225 a(1)p Black eop end +%%Page: 2 2 +TeXDict begin 2 1 bop Black Black 585 573 a Fo(3.8)96 +b(Basic)23 b(ADD)f(Manipulation)42 b(.)k(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(13)p Black 585 686 a(3.9)96 b(Basic)23 b(ZDD)f +(Manipulation)52 b(.)46 b(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(14)p +Black 585 799 a(3.10)51 b(Con)l(v)o(erting)26 b(ADDs)c(to)h(BDDs)f(and) +i(V)-5 b(ice)23 b(V)-10 b(ersa)85 b(.)45 b(.)h(.)f(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)p Black 125 w(15)p Black 585 912 a(3.11)51 +b(Con)l(v)o(erting)26 b(BDDs)c(to)h(ZDDs)f(and)i(V)-5 +b(ice)23 b(V)-10 b(ersa)27 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)p Black 125 w(15)p Black 585 1024 a(3.12)51 +b(V)-10 b(ariable)24 b(Reordering)i(for)e(BDDs)e(and)i(ADDs)63 +b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(16)p Black 585 1137 a(3.13)51 b(Grouping)25 +b(V)-10 b(ariables)61 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(19)p Black 585 1250 a(3.14)51 b(V)-10 b(ariable)24 +b(Reordering)i(for)e(ZDDs)68 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(20)p +Black 585 1363 a(3.15)51 b(K)n(eeping)24 b(Consistent)i(V)-10 +b(ariable)24 b(Orders)h(for)e(BDDs)f(and)i(ZDDs)46 b(.)f(.)g(.)g(.)g(.) +p Black 125 w(21)p Black 585 1476 a(3.16)51 b(Hooks)k(.)45 +b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(21)p Black 585 1589 a(3.17)51 b(T)m(imeouts)24 +b(and)g(Limits)82 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(22)p Black 585 1702 a(3.18)51 b(The)23 b(SIS/VIS)f(Interf)o(ace) +27 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(22)p Black +794 1815 a(3.18.1)65 b(Using)24 b(the)f(CUDD)f(P)o(ackage)i(in)f(SIS)h +(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(22)p Black 585 1928 a(3.19)51 b(Writing)24 +b(Decision)h(Diagrams)f(to)g(a)f(File)57 b(.)45 b(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(24)p +Black 585 2041 a(3.20)51 b(Sa)n(ving)24 b(and)g(Restoring)h(BDDs)78 +b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)p Black 125 w(24)p Black 448 2245 a Fp(4)92 +b(Pr)n(ogrammer')m(s)25 b(Manual)1870 b(24)585 2357 y +Fo(4.1)96 b(Compiling)24 b(and)g(Linking)53 b(.)45 b(.)h(.)f(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(24)p Black 585 2470 a(4.2)96 b(Reference)25 +b(Counts)53 b(.)45 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(26)p Black 794 2583 a(4.2.1)110 b(NULL)21 b(Return)j(V)-10 +b(alues)42 b(.)j(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)p Black 125 w(27)p Black 794 2696 +a(4.2.2)110 b Fn(Cudd)p 1286 2696 28 4 v 33 w(Recur)o(siveDer)m(ef)40 +b Fo(vs.)23 b Fn(Cudd)p 2239 2696 V 34 w(Der)m(ef)45 +b Fo(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(27)p Black 794 2809 a(4.2.3)110 b(When)23 b(Increasing)k(the)d +(Reference)h(Count)f(is)f(Unnecessary)90 b(.)45 b(.)p +Black 125 w(27)p Black 794 2922 a(4.2.4)110 b(Saturating)25 +b(Increments)h(and)e(Decrements)91 b(.)45 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)p Black 125 w(28)p Black 585 3035 a(4.3)96 b(Complement)24 +b(Arcs)37 b(.)45 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(28)p Black 585 3148 a(4.4)96 b(The)23 b(Cache)37 +b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(29)p Black 794 3261 a(4.4.1)110 b(Cache)24 +b(Sizing)64 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(29)p +Black 794 3374 a(4.4.2)110 b(Local)23 b(Caches)55 b(.)45 +b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(30)p Black 585 3487 +a(4.5)96 b(The)23 b(Unique)h(T)-7 b(able)47 b(.)e(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)p Black 125 w(31)p Black 585 3599 a(4.6)96 b(Allo)n(wing)24 +b(Asynchronous)j(Reordering)64 b(.)45 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(32)p Black 585 +3712 a(4.7)96 b(Deb)n(ugging)28 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)p Black 125 w(33)p Black 585 3825 a(4.8)96 +b(Gathering)25 b(and)f(Interpreting)j(Statistics)64 b(.)45 +b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(34)p Black 794 3938 a(4.8.1)110 b(Non)23 +b(Modi\002able)i(P)o(arameters)89 b(.)45 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(34)p Black +794 4051 a(4.8.2)110 b(Modi\002able)24 b(P)o(arameters)64 +b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)p Black 125 w(37)p Black 794 4164 a(4.8.3)110 +b(Extended)25 b(Statistics)g(and)f(Reporting)63 b(.)45 +b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(39)p Black 585 4277 a(4.9)96 b(Guidelines)25 b(for)f +(Documentation)75 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(39)p Black 448 +4481 a Fp(5)92 b(The)22 b(C++)g(Interface)2044 b(40)585 +4594 y Fo(5.1)96 b(Compiling)24 b(and)g(Linking)53 b(.)45 +b(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)p Black 125 w(40)p Black 585 4707 +a(5.2)96 b(Basic)23 b(Manipulation)58 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +p Black 125 w(40)p Black 448 4910 a Fp(6)92 b(Ackno)o(wledgments)2050 +b(41)p Black 1920 5225 a Fo(2)p Black eop end +%%Page: 3 3 +TeXDict begin 3 2 bop Black Black 585 573 a Fp(Refer)n(ences)2341 +b(41)585 777 y(Index)2539 b(43)p Black 1920 5225 a Fo(3)p +Black eop end +%%Page: 4 4 +TeXDict begin 4 3 bop Black Black 448 573 a Fq(1)120 +b(Intr)n(oduction)448 780 y Fo(The)28 b(CUDD)d(package)30 +b(pro)o(vides)g(functions)g(to)e(manipulate)i(Binary)e(Decision)i +(Diagrams)448 893 y(\(BDDs\))35 b([5,)f(3)q(],)j(Algebraic)g(Decision)g +(Diagrams)e(\(ADDs\))g([1],)j(and)d(Zero-suppressed)448 +1006 y(Binary)f(Decision)g(Diagrams)g(\(ZDDs\))e([12)q(].)56 +b(BDDs)32 b(are)h(used)g(to)g(represent)j(switching)448 +1119 y(functions;)i(ADDs)30 b(are)h(used)h(to)g(represent)h(function)h +(from)d Fm(f)p Fl(0)p Fk(;)15 b Fl(1)p Fm(g)2673 1086 +y Fj(n)2753 1119 y Fo(to)31 b(an)g(arbitrary)i(set.)448 +1231 y(ZDDs)20 b(represent)j(switching)g(functions)g(lik)o(e)f(BDDs;)e +(ho)n(we)n(v)o(er)l(,)i(the)o(y)g(are)f(much)g(more)g(ef)n(\002-)448 +1344 y(cient)27 b(than)f(BDDs)e(when)i(the)g(functions)i(to)d(be)h +(represented)j(are)c(characteristic)30 b(functions)448 +1457 y(of)h(cube)g(sets,)i(or)d(in)h(general,)i(when)e(the)g(ON-set)f +(of)g(the)h(function)i(to)d(be)h(represented)i(is)448 +1570 y(v)o(ery)24 b(sparse.)30 b(The)o(y)23 b(are)h(inferior)i(to)d +(BDDs)f(in)h(other)i(cases.)589 1683 y(The)30 b(package)h(pro)o(vides)h +(a)d(lar)n(ge)i(set)f(of)f(operations)k(on)c(BDDs,)h(ADDs,)f(and)h +(ZDDs,)448 1796 y(functions)d(to)d(con)l(v)o(ert)h(BDDs)e(into)h(ADDs)f +(or)g(ZDDs)g(and)h(vice)g(v)o(ersa,)h(and)f(a)g(lar)n(ge)h(assort-)448 +1909 y(ment)f(of)f(v)n(ariable)j(reordering)g(methods.)589 +2022 y(The)e(CUDD)d(package)k(can)f(be)g(used)g(in)g(three)g(w)o(ays:)p +Black 585 2190 a Fm(\017)p Black 46 w Fo(As)17 b(a)h(black)h(box.)28 +b(In)18 b(this)h(case,)g(the)g(application)i(program)f(that)f(needs)g +(to)f(manipulate)676 2303 y(decision)25 b(diagrams)f(only)g(uses)g(the) +g(e)o(xported)h(functions)g(of)e(the)h(package.)30 b(The)23 +b(rich)676 2416 y(set)g(of)h(functions)i(included)g(in)d(the)h(CUDD)d +(package)26 b(allo)n(ws)e(man)o(y)f(applications)k(to)676 +2529 y(be)21 b(written)i(in)f(this)g(w)o(ay)-6 b(.)28 +b(Section)23 b(3)e(describes)k(ho)n(w)c(to)h(use)g(the)g(e)o(xported)i +(functions)676 2642 y(of)g(the)h(package.)33 b(An)24 +b(application)k(written)d(in)f(terms)h(of)f(the)h(e)o(xported)h +(functions)h(of)676 2755 y(the)f(package)j(needs)e(not)g(concern)i +(itself)e(with)f(the)h(details)h(of)f(v)n(ariable)h(reordering,)676 +2868 y(which)23 b(may)h(tak)o(e)g(place)h(behind)g(the)f(scenes.)p +Black 585 3047 a Fm(\017)p Black 46 w Fo(As)h(a)g(clear)i(box.)36 +b(When)26 b(writing)g(a)g(sophisticated)j(application)g(based)e(on)f +(decision)676 3160 y(diagrams,)35 b(ef)n(\002cienc)o(y)e(often)g +(dictates)h(that)f(some)f(functions)i(be)e(implemented)i(as)676 +3273 y(direct)h(recursi)n(v)o(e)h(manipulation)i(of)c(the)h(diagrams,)j +(instead)e(of)f(being)g(written)g(in)676 3386 y(terms)e(of)g(e)o +(xisting)i(primiti)n(v)o(e)f(functions.)60 b(Section)35 +b(4)d(e)o(xplains)j(ho)n(w)e(to)g(add)h(ne)n(w)676 3499 +y(functions)j(to)f(the)f(CUDD)e(package.)66 b(It)35 b(also)h(details)h +(ho)n(w)d(to)i(write)f(a)g(recursi)n(v)o(e)676 3612 y(function)25 +b(that)f(can)g(be)g(interrupted)i(by)e(dynamic)h(v)n(ariable)g +(reordering.)p Black 585 3792 a Fm(\017)p Black 46 w +Fo(Through)c(an)f(interf)o(ace.)30 b(Object-oriented)23 +b(languages)g(lik)o(e)e(C++)e(and)h(Perl5)g(can)h(free)676 +3905 y(the)k(programmer)h(from)f(the)h(b)n(urden)h(of)e(memory)g +(management.)35 b(A)24 b(C++)g(interf)o(ace)676 4018 +y(is)k(included)i(in)e(the)h(distrib)n(ution)j(of)c(CUDD.)d(It)j +(automatically)k(frees)d(decision)h(di-)676 4131 y(agrams)g(that)f(are) +h(no)f(longer)i(used)f(by)f(the)h(application)i(and)e(o)o(v)o(erloads)h +(operators.)676 4244 y(Almost)i(all)h(the)g(functionality)k(pro)o +(vided)e(by)e(the)g(CUDD)d(e)o(xported)36 b(functions)g(is)676 +4356 y(a)n(v)n(ailable)d(through)g(the)e(C++)f(interf)o(ace,)35 +b(which)c(is)g(especially)j(recommended)f(for)676 4469 +y(f)o(ast)e(prototyping.)56 b(Section)32 b(5)f(e)o(xplains)j(ho)n(w)c +(to)i(use)f(the)h(interf)o(ace.)54 b(A)31 b(Perl5)g(in-)676 +4582 y(terf)o(ace)38 b(also)g(e)o(xists)g(and)f(is)g(ditrib)n(uted)j +(separately)-6 b(.)71 b(\(See)37 b(Section)h(2.2.\))69 +b(Some)676 4695 y(applications)27 b(de\002ne)d(their)g(o)n(wn)f(interf) +o(aces.)31 b(See)23 b(for)h(e)o(xample)g(Section)h(3.18.)448 +4863 y(In)k(the)h(follo)n(wing,)i(the)d(reader)i(is)e(supposed)j(to)d +(be)g(f)o(amiliar)h(with)f(the)h(basic)g(ideas)g(about)448 +4976 y(decision)c(diagrams,)f(as)e(found,)i(for)e(instance,)j(in)d([3)q +(].)p Black 1920 5225 a(4)p Black eop end +%%Page: 5 5 +TeXDict begin 5 4 bop Black Black 448 573 a Fq(2)120 +b(Ho)o(w)29 b(to)h(Get)g(CUDD)448 783 y Fi(2.1)99 b(The)26 +b(CUDD)f(P)o(ackage)448 957 y Fo(The)36 b(CUDD)e(package)39 +b(is)d(a)n(v)n(ailable)j(via)d(anon)o(ymous)j(FTP)34 +b(from)i(vlsi.Colorado.EDU.)448 1070 y(A)29 b(compressed)j(tar)e +(\002le)f(named)h Fh(cudd-2.5.0.tar.)o(gz)22 b Fo(can)31 +b(be)e(found)i(in)f(directory)448 1183 y Fh(pub)p Fo(.)d(Once)c(you)h +(ha)n(v)o(e)h(this)f(\002le,)p Black Black 676 1371 a +Fh(gzip)52 b(-dc)i(cudd-2.5.0.tar)o(.g)o(z)48 b(|)54 +b(tar)g(xvf)f(-)448 1559 y Fo(will)27 b(create)g(directory)j +Fh(cudd-2.5.0)21 b Fo(and)27 b(its)g(subdirectories.)42 +b(These)27 b(directories)j(con-)448 1671 y(tain)h(the)g(decision)i +(diagram)f(package,)i(a)c(fe)n(w)g(support)j(libraries,)h(and)d(a)f(to) +o(y)h(application)448 1784 y(based)23 b(on)f(the)h(decision)h(diagram)f +(package.)30 b(There)22 b(is)g(a)f(README)e(\002le)i(with)h +(instructions)448 1897 y(on)33 b(con\002guration)j(and)d(installation)j +(in)d Fh(cudd-2.5.0)p Fo(.)51 b(Y)-10 b(ou)32 b(can)i(use)f(a)f +(compiler)i(for)448 2010 y(either)25 b(ANSI)d(C)g(or)i(C++.)589 +2123 y(Once)g(you)g(ha)n(v)o(e)g(made)g(the)g(libraries)h(and)f +(program,)h(you)f(can)g(type:)p Black Black 676 2311 +a Fh(cd)53 b(nanotrav)676 2424 y(nanotrav)e(-p)i(1)h(-autodyn)d +(-reordering)f(sifting)h(-trav)676 2537 y(mult32a.blif)448 +2724 y Fo(This)26 b(will)g(run)h(a)e(simple-minded)k(FSM)c(tra)n(v)o +(ersal)j(program.)38 b(\(On)25 b(a)h(2.4)g(GHz)f(Pentium)i(4)448 +2837 y(\(TM\),)g(it)h(tak)o(es)h(about)h(0.5)e(s.\))42 +b(The)28 b(output)i(produced)g(by)f(the)f(program)h(can)g(be)f(check)o +(ed)448 2950 y(against)35 b Fh(cudd-2.5.0/nano)o(tra)o(v/)o(mu)o(lt)o +(32)o(a.o)o(ut)o Fo(.)52 b(More)34 b(information)i(on)e(the)448 +3063 y Fh(nanotrav)19 b Fo(program)25 b(can)f(be)g(found)g(in)g +Fh(cudd-2.5.0/nan)o(otr)o(av)o(/R)o(EA)o(DM)o(E)p Fo(.)589 +3176 y(If)i(you)h(w)o(ant)f(to)g(be)g(noti\002ed)h(of)f(ne)n(w)f +(releases)j(of)e(the)h(CUDD)c(package,)29 b(send)e(a)e(mes-)448 +3289 y(sage)g(to)e Fh(Fabio@Colorado.)o(ED)o(U)p Fo(.)448 +3538 y Fi(2.2)99 b(CUDD)25 b(Friends)448 3712 y Fo(T)-7 +b(w)o(o)18 b(CUDD)g(e)o(xtensions)k(are)e(a)n(v)n(ailable)h(via)f(anon) +o(ymous)i(FTP)17 b(from)i(vlsi.Colorado.EDU.)p Black +585 3900 a Fm(\017)p Black 46 w Fn(P)-7 b(erlDD)27 b +Fo(is)i(an)f(object-oriented)34 b(Perl5)29 b(interf)o(ace)i(to)d(CUDD.) +f(It)h(is)h(or)n(ganized)i(as)e(a)676 4013 y(standard)f(Perl)e(e)o +(xtension)j(module.)39 b(The)26 b(Perl)g(interf)o(ace)j(is)d(at)h(a)f +(some)n(what)h(higher)676 4126 y(le)n(v)o(el)c(than)i(the)e(C++)g +(interf)o(ace,)j(b)n(ut)e(it)f(is)h(not)g(as)f(complete.)p +Black 585 4313 a Fm(\017)p Black 46 w Fn(DDcal)g Fo(is)h(a)g(graphic)h +(BDD)e(calculator)j(based)f(on)f(CUDD,)e(Perl-Tk,)i(and)g(dot.)31 +b(\(See)676 4426 y(Section)24 b(3.19)g(for)g(information)i(on)d +Fn(dot)p Fo(.\))448 4719 y Fq(3)120 b(User')l(s)28 b(Manual)448 +4926 y Fo(This)c(section)h(describes)h(the)e(use)g(of)f(the)h(CUDD)d +(package)26 b(as)d(a)g(black)i(box.)p Black 1920 5225 +a(5)p Black eop end +%%Page: 6 6 +TeXDict begin 6 5 bop Black Black 448 573 a Fi(3.1)99 +b(Compiling)25 b(and)g(Linking)448 747 y Fo(T)-7 b(o)23 +b(b)n(uild)i(an)e(application)k(that)d(uses)g(the)g(CUDD)d(package,)26 +b(you)e(should)h(add)p Black Black 448 935 a Fh(#include)51 +b("util.h")448 1048 y(#include)g("cudd.h")448 1235 y +Fo(to)32 b(your)g(source)h(\002les,)g(and)g(should)g(link)f +Fh(libcudd.a)p Fo(,)d Fh(libmtr.a)p Fo(,)f Fh(libst.a)p +Fo(,)i(and)448 1348 y Fh(libutil.a)23 b Fo(to)28 b(your)h(e)o(x)o +(ecutable.)43 b(\(All)28 b(these)h(libraries)g(are)f(part)h(of)f(the)g +(distrib)n(ution.\))448 1461 y(Some)20 b(platforms)h(require)h +(speci\002c)e(compiler)i(and)e(link)o(er)h(\003ags.)28 +b(Refer)20 b(to)g(the)g Fh(Makefile)448 1574 y Fo(in)k(the)g(top)f(le)n +(v)o(el)h(directory)i(of)e(the)f(distrib)n(ution.)589 +1687 y(K)n(eep)d(in)g(mind)g(that)h(whate)n(v)o(er)g(\003ags)e(af)n +(fect)i(the)g(size)f(of)g(data)h(structures\227for)i(instance)448 +1800 y(the)e(\003ags)f(used)g(to)g(use)h(64-bit)g(pointers)h(where)f(a) +n(v)n(ailable\227must)i(be)d(speci\002ed)h(when)f(com-)448 +1913 y(piling)25 b(both)g(CUDD)c(and)j(the)g(\002les)f(that)h(include)h +(its)f(header)h(\002les.)448 2162 y Fi(3.2)99 b(Basic)25 +b(Data)g(Structur)n(es)448 2336 y Fp(3.2.1)92 b(Nodes)448 +2510 y Fo(BDDs,)24 b(ADDs,)h(and)h(ZDDs)d(are)j(made)g(of)f(DdNode')-5 +b(s.)35 b(A)25 b(DdNode)g(\(node)i(for)f(short\))g(is)g(a)448 +2623 y(structure)j(with)d(se)n(v)o(eral)i(\002elds.)37 +b(Those)27 b(that)g(are)f(of)h(interest)h(to)e(the)h(application)j +(that)d(uses)448 2736 y(the)e(CUDD)d(package)27 b(as)d(a)g(black)i(box) +f(are)f(the)h(v)n(ariable)h(inde)o(x,)g(the)e(reference)j(count,)f(and) +448 2849 y(the)f(v)n(alue.)33 b(The)24 b(remaining)i(\002elds)f(are)f +(pointers)j(that)e(connect)i(nodes)e(among)g(themselv)o(es)448 +2962 y(and)f(that)g(are)g(used)g(to)g(implement)h(the)e(unique)j +(table.)j(\(See)23 b(Section)i(3.2.2.\))589 3075 y(The)h +Fn(inde)n(x)i Fo(\002eld)e(holds)h(the)g(name)f(of)g(the)h(v)n(ariable) +h(that)e(labels)i(the)e(node.)38 b(The)25 b(inde)o(x)448 +3188 y(of)37 b(a)f(v)n(ariable)i(is)f(a)f(permanent)j(attrib)n(ute)g +(that)e(re\003ects)g(the)g(order)h(of)e(creation.)70 +b(Inde)o(x)448 3301 y(0)26 b(corresponds)k(to)c(the)g(v)n(ariable)i +(created)g(\002rst.)36 b(On)25 b(a)h(machine)h(with)f(32-bit)h +(pointers,)i(the)448 3414 y(maximum)21 b(number)h(of)e(v)n(ariables)j +(is)d(the)h(lar)n(gest)i(v)n(alue)e(that)h(can)f(be)f(stored)j(in)d(an) +h(unsigned)448 3527 y(short)27 b(inte)o(ger)g(minus)f(1.)35 +b(The)25 b(lar)n(gest)j(inde)o(x)f(is)e(reserv)o(ed)j(for)e(the)g +(constant)h(nodes.)37 b(When)448 3640 y(64-bit)24 b(pointers)g(are)e +(used,)h(the)f(maximum)g(number)h(of)f(v)n(ariables)i(is)e(the)g(lar)n +(gest)i(v)n(alue)f(that)448 3752 y(can)h(be)g(stored)h(in)e(an)h +(unsigned)i(inte)o(ger)e(minus)g(1.)589 3865 y(When)k(v)n(ariables)i +(are)e(reordered)i(to)e(reduce)h(the)f(size)g(of)f(the)h(decision)i +(diagrams,)g(the)448 3978 y(v)n(ariables)h(may)e(shift)h(in)f(the)g +(order)l(,)i(b)n(ut)f(the)o(y)f(retain)h(their)g(indices.)47 +b(The)28 b(package)j(k)o(eeps)448 4091 y(track)d(of)e(the)h(v)n +(ariable)h(permutation)h(\(and)e(its)g(in)l(v)o(erse\).)40 +b(The)26 b(application)j(is)e(not)g(af)n(fected)448 4204 +y(by)d(v)n(ariable)h(reordering,)h(e)o(xcept)f(in)e(the)h(follo)n(wing) +h(cases.)p Black 585 4392 a Fm(\017)p Black 46 w Fo(If)17 +b(the)i(application)i(uses)e(generators)i(\()p Fn(Cudd)p +2104 4392 28 4 v 34 w(F)-10 b(or)m(eac)o(hCube)20 b Fo(and)e +Fn(Cudd)p 2985 4392 V 34 w(F)-10 b(or)m(eac)o(hNode)p +Fo(\))676 4505 y(and)20 b(reordering)j(is)d(enabled,)j(then)e(it)f +(must)g(tak)o(e)h(care)f(not)h(to)f(call)h(an)o(y)f(operation)j(that) +676 4618 y(may)29 b(create)i(ne)n(w)e(nodes)j(\(and)e(hence)h(possibly) +h(trigger)g(reordering\).)51 b(This)29 b(is)h(be-)676 +4730 y(cause)j(the)g(cubes)h(\(i.e.,)g(paths\))g(and)f(nodes)h(of)e(a)g +(diagram)i(change)g(as)f(a)f(result)h(of)676 4843 y(reordering.)p +Black 1920 5225 a(6)p Black eop end +%%Page: 7 7 +TeXDict begin 7 6 bop Black Black Black 585 573 a Fm(\017)p +Black 46 w Fo(If)26 b(the)h(application)j(uses)d Fn(Cudd)p +1712 573 28 4 v 34 w(bddConstr)o(ain)j Fo(and)d(reordering)i(tak)o(es)f +(place,)h(then)676 686 y(the)23 b(property)j(of)e Fn(Cudd)p +1440 686 V 33 w(bddConstr)o(ain)j Fo(of)c(being)i(an)e(image)h +(restrictor)i(is)e(lost.)589 873 y(The)j(CUDD)f(package)j(relies)g(on)e +(garbage)i(collection)h(to)e(reclaim)g(the)g(memory)f(used)448 +986 y(by)35 b(diagrams)i(that)e(are)h(no)f(longer)h(in)f(use.)64 +b(The)34 b(scheme)i(emplo)o(yed)h(for)e(garbage)i(col-)448 +1099 y(lection)32 b(is)d(based)i(on)f(k)o(eeping)h(a)e(reference)j +(count)f(for)f(each)g(node.)48 b(The)29 b(references)k(that)448 +1212 y(are)26 b(counted)i(are)e(both)h(the)f(internal)h(references)i +(\(references)f(from)e(other)h(nodes\))g(and)f(e)o(x-)448 +1325 y(ternal)37 b(references)h(\(typically)g(references)g(from)d(the)g +(calling)i(en)l(vironment\).)68 b(When)35 b(an)448 1438 +y(application)25 b(creates)f(a)d(ne)n(w)g(BDD,)f(ADD,)f(or)j(ZDD,)d(it) +j(must)f(increase)j(its)e(reference)i(count)448 1551 +y(e)o(xplicitly)-6 b(,)40 b(through)d(a)e(call)g(to)g +Fn(Cudd)p 1707 1551 V 34 w(Ref)13 b Fo(.)62 b(Similarly)-6 +b(,)38 b(when)e(a)e(diagram)i(is)f(no)g(longer)448 1664 +y(needed,)28 b(the)e(application)i(must)e(call)g Fn(Cudd)p +1877 1664 V 34 w(Recur)o(siveDer)m(ef)41 b Fo(\(for)26 +b(BDDs)e(and)i(ADDs\))e(or)448 1777 y Fn(Cudd)p 649 1777 +V 34 w(Recur)o(siveDer)m(efZdd)29 b Fo(\(for)24 b(ZDDs\))e(to)h +(\223rec)o(ycle\224)j(the)e(nodes)h(of)e(the)h(diagram.)589 +1890 y(T)-6 b(erminal)37 b(nodes)h(carry)g(a)e(v)n(alue.)69 +b(This)36 b(is)h(especially)i(important)g(for)d(ADDs.)67 +b(By)448 2002 y(def)o(ault,)29 b(the)f(v)n(alue)f(is)g(a)f(double.)41 +b(T)-7 b(o)25 b(change)k(to)d(something)j(dif)n(ferent)g(\(e.g.,)e(an)g +(inte)o(ger\),)448 2115 y(the)21 b(package)i(must)d(be)h(modi\002ed)g +(and)g(recompiled.)30 b(Support)21 b(for)g(this)g(process)i(is)d +(currently)448 2228 y(v)o(ery)k(rudimentary)-6 b(.)448 +2474 y Fp(3.2.2)92 b(The)22 b(Manager)448 2648 y Fo(All)27 +b(nodes)i(used)g(in)f(BDDs,)f(ADDs,)g(and)h(ZDDs)e(are)i(k)o(ept)g(in)g +(special)h(hash)g(tables)g(called)448 2761 y(the)36 b +Fn(unique)i(tables)p Fo(.)66 b(Speci\002cally)-6 b(,)40 +b(BDDs)35 b(and)h(ADDs)e(share)j(the)f(same)f(unique)j(table,)448 +2874 y(whereas)24 b(ZDDs)d(ha)n(v)o(e)j(their)f(o)n(wn)f(table.)30 +b(As)22 b(the)h(name)f(implies,)i(the)f(main)g(purpose)h(of)f(the)448 +2987 y(unique)i(table)e(is)g(to)f(guarantee)k(that)d(each)g(node)h(is)e +(unique;)j(that)e(is,)g(there)g(is)g(no)g(other)g(node)448 +3100 y(labeled)h(by)e(the)h(same)f(v)n(ariable)i(and)e(with)g(the)g +(same)h(children.)30 b(This)22 b(uniqueness)j(property)448 +3213 y(mak)o(es)34 b(decision)i(diagrams)f(canonical.)61 +b(The)33 b(unique)i(tables)f(and)g(some)g(auxiliary)i(data)448 +3326 y(structures)e(mak)o(e)d(up)g(the)g(DdManager)h(\(manager)h(for)e +(short\).)52 b(Though)32 b(the)f(application)448 3439 +y(that)c(uses)h(only)f(the)g(e)o(xported)h(functions)h(needs)f(not)f +(be)f(concerned)j(with)e(most)f(details)i(of)448 3552 +y(the)20 b(manager)l(,)h(it)e(has)h(to)f(deal)h(with)f(the)h(manager)g +(in)g(the)f(follo)n(wing)i(sense.)28 b(The)19 b(application)448 +3665 y(must)28 b(initialize)h(the)f(manager)h(by)e(calling)i(an)e +(appropriate)k(function.)42 b(\(See)27 b(Section)h(3.3.\))448 +3778 y(Subsequently)-6 b(,)25 b(it)c(must)h(pass)g(a)f(pointer)j(to)d +(the)h(manager)h(to)e(all)h(the)f(functions)j(that)f(operate)448 +3890 y(on)h(decision)i(diagrams.)589 4003 y(W)l(ith)k(the)g(e)o +(xception)i(of)d(a)g(fe)n(w)g(statistical)j(counters,)h(there)d(are)g +(no)f(global)i(v)n(ariables)448 4116 y(in)f(the)g(CUDD)d(package.)50 +b(Therefore,)32 b(it)e(is)f(quite)i(possible)h(to)d(ha)n(v)o(e)i +(multiple)g(managers)448 4229 y(simultaneously)h(acti)n(v)o(e)d(in)f +(the)g(same)g(application.)2140 4196 y Fg(1)2223 4229 +y Fo(It)g(is)g(the)g(pointers)i(to)e(the)h(managers)448 +4342 y(that)24 b(tell)g(the)g(functions)i(on)e(what)f(data)h(the)o(y)g +(should)i(operate.)p Black 448 4423 1196 4 v 554 4479 +a Ff(1)583 4511 y Fe(The)18 b(global)h(statistical)e(counters)i(are)f +(used)h(locally;)g(hence)g(the)o(y)f(are)h(compatible)g(with)e(the)i +(use)f(of)g(multi-)448 4602 y(ple)h(managers.)p Black +Black 1920 5225 a Fo(7)p Black eop end +%%Page: 8 8 +TeXDict begin 8 7 bop Black Black 448 573 a Fp(3.2.3)92 +b(Cache)448 747 y Fo(Ef)n(\002cient)23 b(recursi)n(v)o(e)i +(manipulation)h(of)e(decision)h(diagrams)f(requires)i(the)d(use)h(of)f +(a)f(table)i(to)448 860 y(store)i(computed)g(results.)34 +b(This)24 b(table)i(is)e(called)i(here)g(the)e Fn(cac)o(he)i +Fo(because)g(it)f(is)f(ef)n(fecti)n(v)o(ely)448 973 y(handled)g(lik)o +(e)f(a)e(cache)i(of)f(v)n(ariable)i(b)n(ut)e(limited)h(capacity)-6 +b(.)30 b(The)22 b(CUDD)d(package)24 b(starts)f(by)448 +1086 y(def)o(ault)31 b(with)e(a)g(small)g(cache,)i(and)f(increases)h +(its)e(size)h(until)g(either)g(no)f(further)i(bene\002t)e(is)448 +1199 y(achie)n(v)o(ed,)c(or)f(a)f(limit)g(size)h(is)f(reached.)31 +b(The)23 b(user)h(can)g(in\003uence)h(this)f(polic)o(y)g(by)g(choosing) +448 1312 y(initial)h(and)f(limit)g(v)n(alues)g(for)g(the)g(cache)h +(size.)589 1425 y(T)-7 b(oo)22 b(small)g(a)f(cache)i(will)e(cause)i +(frequent)h(o)o(v)o(erwriting)f(of)f(useful)h(results.)30 +b(T)-7 b(oo)21 b(lar)n(ge)i(a)448 1537 y(cache)h(will)d(cause)j(o)o(v)o +(erhead,)g(because)g(the)e(whole)h(cache)g(is)f(scanned)i(e)n(v)o(ery)f +(time)f(garbage)448 1650 y(collection)27 b(tak)o(es)f(place.)32 +b(The)24 b(optimal)h(parameters)i(depend)f(on)e(the)h(speci\002c)g +(application.)448 1763 y(The)e(def)o(ault)j(parameters)f(w)o(ork)f +(reasonably)i(well)e(for)f(a)g(lar)n(ge)i(spectrum)g(of)f +(applications.)589 1876 y(The)32 b(cache)h(of)f(the)h(CUDD)d(package)k +(is)e(used)h(by)f(most)g(recursi)n(v)o(e)i(functions)h(of)d(the)448 +1989 y(package,)26 b(and)e(can)f(be)h(used)g(by)g(user)n(-supplied)k +(functions)e(as)d(well.)29 b(\(See)23 b(Section)h(4.4.\))448 +2236 y Fi(3.3)99 b(Initializing)24 b(and)i(Shutting)g(Do)o(wn)f(a)g +(DdManager)448 2411 y Fo(T)-7 b(o)27 b(use)g(the)h(functions)i(in)d +(the)h(CUDD)d(package,)30 b(one)e(has)g(\002rst)f(to)g(initialize)j +(the)d(package)448 2524 y(itself)e(by)e(calling)j Fn(Cudd)p +1238 2524 28 4 v 33 w(Init)r Fo(.)j(This)24 b(function)h(tak)o(es)g +(four)f(parameters:)p Black 585 2702 a Fm(\017)p Black +46 w Fo(numV)-10 b(ars:)28 b(It)21 b(is)h(the)f(initial)i(number)f(of)g +(v)n(ariables)h(for)f(BDDs)e(and)i(ADDs.)k(If)21 b(the)h(to-)676 +2815 y(tal)e(number)i(of)f(v)n(ariables)h(needed)h(by)d(the)h +(application)j(is)d(kno)n(wn,)g(then)g(it)g(is)f(slightly)676 +2928 y(more)h(ef)n(\002cient)h(to)f(create)i(a)e(manager)i(with)e(that) +h(number)g(of)f(v)n(ariables.)30 b(If)22 b(the)f(num-)676 +3041 y(ber)g(is)g(unkno)n(wn,)i(it)e(can)h(be)f(set)g(to)g(0,)h(or)f +(to)g(an)o(y)g(other)i(lo)n(wer)e(bound)h(on)g(the)f(number)676 +3154 y(of)28 b(v)n(ariables.)47 b(Requesting)31 b(more)e(v)n(ariables)i +(than)f(are)f(actually)i(needed)f(is)f(not)g(in-)676 +3267 y(correct,)24 b(b)n(ut)g(is)g(not)g(ef)n(\002cient.)p +Black 585 3450 a Fm(\017)p Black 46 w Fo(numV)-10 b(arsZ:)27 +b(It)h(is)f(the)h(initial)h(number)f(of)g(v)n(ariables)i(for)d(ZDDs.)40 +b(See)27 b(Sections)h(3.9)676 3563 y(and)c(3.11)f(for)h(a)f(discussion) +k(of)c(the)h(v)n(alue)g(of)g(this)g(ar)n(gument.)p Black +585 3747 a Fm(\017)p Black 46 w Fo(numSlots:)42 b(Determines)31 +b(the)f(initial)h(size)f(of)g(each)h(subtable)h(of)d(the)h(unique)i +(table.)676 3860 y(There)c(is)g(a)f(subtable)j(for)f(each)f(v)n +(ariable.)44 b(The)28 b(size)g(of)g(each)h(subtable)h(is)e(dynami-)676 +3973 y(cally)e(adjusted)i(to)e(re\003ect)g(the)g(number)h(of)f(nodes.) +37 b(It)25 b(is)h(normally)h(O.K.)d(to)i(use)g(the)676 +4086 y(def)o(ault)f(v)n(alue)f(for)g(this)g(parameter)l(,)h(which)f(is) +g(CUDD)p 2448 4086 V 31 w(UNIQ)o(UE)p 2828 4086 V 31 +w(SLO)l(TS.)p Black 585 4270 a Fm(\017)p Black 46 w Fo(cacheSize:)39 +b(It)28 b(is)g(the)g(initial)h(size)g(\(number)g(of)f(entries\))h(of)f +(the)h(cache.)43 b(Its)28 b(def)o(ault)676 4383 y(v)n(alue)c(is)f(CUDD) +p 1240 4383 V 32 w(CA)l(CHE)p 1578 4383 V 31 w(SLO)l(TS.)p +Black 585 4567 a Fm(\017)p Black 46 w Fo(maxMemory:)29 +b(It)23 b(is)g(the)h(tar)n(get)g(v)n(alue)g(for)f(the)h(maximum)f +(memory)g(occupation)j(\(in)676 4680 y(bytes\).)k(The)23 +b(package)i(uses)g(this)f(v)n(alue)g(to)f(decide)i(tw)o(o)f +(parameters.)p Black 785 4863 a Fp(\226)p Black 46 w +Fo(the)29 b(maximum)f(size)i(to)e(which)i(the)f(cache)h(will)e(gro)n(w) +-6 b(,)30 b(re)o(gardless)g(of)f(the)g(hit)876 4976 y(rate)24 +b(or)f(the)h(size)g(of)f(the)h(unique)h(table.)p Black +1920 5225 a(8)p Black eop end +%%Page: 9 9 +TeXDict begin 9 8 bop Black Black Black 785 573 a Fp(\226)p +Black 46 w Fo(the)19 b(maximum)g(size)h(to)f(which)h(gro)n(wth)f(of)g +(the)h(unique)h(table)f(will)f(be)g(preferred)876 686 +y(to)k(garbage)i(collection.)676 873 y(If)j(maxMemory)h(is)g(set)g(to)f +(0,)h(CUDD)e(tries)i(to)g(guess)g(a)f(good)i(v)n(alue)g(based)f(on)g +(the)676 986 y(a)n(v)n(ailable)c(memory)-6 b(.)448 1174 +y(A)23 b(typical)i(call)f(to)f Fn(Cudd)p 1255 1174 28 +4 v 34 w(Init)j Fo(may)d(look)h(lik)o(e)g(this:)p Black +Black 557 1362 a Fh(manager)52 b(=)i(Cudd_Init\(0,0,)o(CUD)o(D_)o(UN)o +(IQ)o(UE)o(_SL)o(OT)o(S,)o(CU)o(DD)o(_CA)o(CH)o(E_)o(SL)o(OT)o(S,0)o +(\);)448 1549 y Fo(T)-7 b(o)34 b(reclaim)i(all)f(the)g(memory)g +(associated)j(with)d(a)f(manager)l(,)39 b(an)c(application)j(must)d +(call)448 1662 y Fn(Cudd)p 649 1662 V 34 w(Quit)r Fo(.)28 +b(This)c(is)f(normally)i(done)f(before)h(e)o(xiting.)448 +1911 y Fi(3.4)99 b(Setting)26 b(P)o(arameters)448 2086 +y Fo(The)i(package)j(pro)o(vides)f(se)n(v)o(eral)g(functions)h(to)d +(set)h(the)g(parameters)h(that)f(control)i(v)n(arious)448 +2198 y(functions.)g(F)o(or)22 b(instance,)j(the)e(package)i(has)f(an)f +(automatic)h(w)o(ay)f(of)g(determining)i(whether)448 +2311 y(a)f(lar)n(ger)i(unique)f(table)g(w)o(ould)g(mak)o(e)f(the)g +(application)k(run)c(f)o(aster)-5 b(.)32 b(In)24 b(that)g(case,)h(the)f +(pack-)448 2424 y(age)19 b(enters)h(a)e(\223f)o(ast)i(gro)n(wth\224)f +(mode)g(in)g(which)g(resizing)i(of)d(the)h(unique)h(subtables)i(is)c(f) +o(a)n(v)n(ored)448 2537 y(o)o(v)o(er)25 b(garbage)h(collection.)36 +b(When)25 b(the)g(unique)h(table)g(reaches)g(a)f(gi)n(v)o(en)g(size,)h +(ho)n(we)n(v)o(er)l(,)f(the)448 2650 y(package)d(returns)e(to)g(the)f +(normal)h(\223slo)n(w)f(gro)n(wth\224)i(mode,)f(e)n(v)o(en)f(though)i +(the)e(conditions)k(that)448 2763 y(caused)k(the)f(transition)i(to)d(f) +o(ast)h(gro)n(wth)f(still)h(pre)n(v)n(ail.)35 b(The)25 +b(limit)g(size)h(for)f(f)o(ast)h(gro)n(wth)g(can)448 +2876 y(be)k(read)h(by)f Fn(Cudd)p 1070 2876 V 33 w(ReadLooseUpT)-8 +b(o)31 b Fo(and)g(changed)h(by)e Fn(Cudd)p 2544 2876 +V 33 w(SetLooseUpT)-8 b(o)p Fo(.)49 b(Similar)448 2989 +y(pairs)25 b(of)e(functions)j(e)o(xist)e(for)g(se)n(v)o(eral)h(other)f +(parameters.)31 b(See)23 b(also)h(Section)h(4.8.)448 +3238 y Fi(3.5)99 b(Constant)26 b(Functions)448 3412 y +Fo(The)18 b(CUDD)e(P)o(ackage)j(de\002nes)g(se)n(v)o(eral)h(constant)g +(functions.)30 b(These)18 b(functions)j(are)e(created)448 +3525 y(when)24 b(the)g(manager)g(is)g(initialized,)i(and)e(are)g +(accessible)i(through)f(the)f(manager)h(itself.)448 3771 +y Fp(3.5.1)92 b(One,)22 b(Logic)i(Zer)n(o,)g(and)e(Arithmetic)i(Zer)n +(o)448 3945 y Fo(The)36 b(constant)i(1)d(\(returned)j(by)e +Fn(Cudd)p 1738 3945 V 34 w(ReadOne)p Fo(\))g(is)g(common)g(to)g(BDDs,)h +(ADDs,)g(and)448 4058 y(ZDDs.)42 b(Ho)n(we)n(v)o(er)l(,)29 +b(its)f(meaning)i(is)e(dif)n(ferent)i(for)f(ADDs)d(and)j(BDDs,)f(on)g +(the)h(one)g(hand,)448 4171 y(and)c(ZDDs,)f(on)g(the)h(other)h(hand.)33 +b(The)25 b(diagram)g(consisting)j(of)d(the)g(constant)h(1)f(node)g +(only)448 4284 y(represents)33 b(the)d(constant)i(1)e(function)i(for)e +(ADDs)f(and)h(BDDs.)46 b(F)o(or)29 b(ZDDs,)h(its)g(meaning)448 +4397 y(depends)i(on)d(the)g(number)i(of)e(v)n(ariables:)42 +b(It)29 b(is)g(the)h(conjunction)j(of)c(the)g(complements)i(of)448 +4510 y(all)j(v)n(ariables.)63 b(Con)l(v)o(ersely)-6 b(,)38 +b(the)d(representation)j(of)c(the)g(constant)i(1)e(function)i(depends) +448 4623 y(on)28 b(the)f(number)h(of)f(v)n(ariables.)42 +b(The)26 b(constant)k(1)c(function)k(of)d Fk(n)f Fo(v)n(ariables)j(is)e +(returned)i(by)448 4736 y Fn(Cudd)p 649 4736 V 34 w(ReadZddOne)p +Fo(.)p Black 1920 5225 a(9)p Black eop end +%%Page: 10 10 +TeXDict begin 10 9 bop Black Black 589 573 a Fo(The)29 +b(constant)j(0)c(is)h(common)h(to)f(ADDs)f(and)h(ZDDs,)g(b)n(ut)h(not)f +(to)g(BDDs.)44 b(The)29 b(BDD)448 686 y(logic)21 b(0)f(is)g +Fp(not)g Fo(associated)i(with)e(the)h(constant)h(0)e(function:)29 +b(It)20 b(is)g(obtained)i(by)f(complemen-)448 799 y(tation)26 +b(\()p Fn(Cudd)p 910 799 28 4 v 34 w(Not)r Fo(\))e(of)h(the)g(constant) +i(1.)32 b(\(It)24 b(is)h(also)g(returned)i(by)e Fn(Cudd)p +2795 799 V 33 w(ReadLo)o(gicZer)l(o)p Fo(.\))448 912 +y(All)e(other)i(constants)h(are)e(speci\002c)g(to)f(ADDs.)448 +1157 y Fp(3.5.2)92 b(Pr)n(ede\002ned)22 b(Constants)448 +1332 y Fo(Besides)34 b(0)e(\(returned)j(by)d Fn(Cudd)p +1528 1332 V 34 w(ReadZer)l(o)p Fo(\))h(and)g(1,)h(the)f(follo)n(wing)h +(constant)h(functions)448 1445 y(are)24 b(created)h(at)f +(initialization)j(time.)p Black 562 1632 a(1.)p Black +46 w(PlusIn\002nity)f(and)g(MinusIn\002nity:)34 b(On)25 +b(computers)i(implementing)g(the)e(IEEE)e(stan-)676 1745 +y(dard)39 b(754)g(for)f(\003oating-point)k(arithmetic,)h(these)d(tw)o +(o)e(constants)j(are)d(set)h(to)f(the)676 1858 y(signed)19 +b(in\002nities.)29 b(On)17 b(the)h(DEC)e(Alphas,)k(the)e(option)i +Fh(-ieee_with_no_i)o(ne)o(xa)o(ct)676 1971 y Fo(or)33 +b Fh(-ieee_with_inexa)o(ct)26 b Fo(must)34 b(be)g(passed)h(to)f(the)g +(DEC)e(compiler)j(to)f(get)676 2084 y(support)26 b(of)e(the)h(IEEE)d +(standard.)34 b(\(The)24 b(compiler)i(still)f(produces)h(a)e(w)o +(arning,)i(b)n(ut)f(it)676 2197 y(can)30 b(be)h(ignored.\))52 +b(Compiling)32 b(with)e(those)i(options)g(may)e(cause)i(substantial)i +(per)n(-)676 2310 y(formance)39 b(de)o(gradation)j(on)c(the)g(Ev)n +(olution)j(IV)c(CPUs.)71 b(\(Especially)41 b(if)d(the)g(ap-)676 +2423 y(plication)d(does)f(use)f(the)g(in\002nities.\))58 +b(The)33 b(problem)h(is)e(reportedly)k(solv)o(ed)e(in)f(the)676 +2536 y(Ev)n(olution)h(V)d(CPUs.)55 b(If)32 b Fh(gcc)e +Fo(is)j(used)g(to)f(compile)i(CUDD)c(on)j(the)g(Alphas,)i(the)676 +2648 y(symbol)26 b Fh(HAVE)p 1193 2648 V 31 w(IEEE)p +1444 2648 V 31 w(754)d Fo(must)j(be)f(unde\002ned.)37 +b(\(See)25 b(the)h(Mak)o(e\002le)g(for)f(the)h(de-)676 +2761 y(tails.\))39 b(The)26 b(v)n(alues)i(of)e(these)i(constants)h(are) +e(returned)i(by)d Fn(Cudd)p 2802 2761 V 34 w(ReadPlusIn\002nity)676 +2874 y Fo(and)e Fn(Cudd)p 1031 2874 V 33 w(ReadMinusIn\002nity)p +Fo(.)p Black 562 3062 a(2.)p Black 46 w(Epsilon:)38 b(This)28 +b(constant,)j(initially)f(set)e(to)f Fl(10)2183 3029 +y Fd(\000)p Fc(12)2314 3062 y Fo(,)h(is)f(used)i(in)f(comparing)h +(\003oating)676 3175 y(point)e(v)n(alues)g(for)f(equality)-6 +b(.)39 b(Its)26 b(v)n(alue)h(is)f(returned)j(by)d Fn(Cudd)p +2688 3175 V 34 w(ReadEpsilon)p Fo(,)i(and)f(it)676 3288 +y(can)h(be)g(modi\002ed)h(by)g(calling)g Fn(Cudd)p 1887 +3288 V 34 w(SetEpsilon)p Fo(.)45 b(Unlik)o(e)29 b(the)g(other)g +(constants,)j(it)676 3401 y(does)24 b(not)g(correspond)i(to)e(a)f +(node.)448 3646 y Fp(3.5.3)92 b(Backgr)n(ound)448 3821 +y Fo(The)22 b(background)k(v)n(alue)e(is)e(a)g(constant)j(typically)g +(used)e(to)g(represent)h(non-e)o(xisting)i(arcs)d(in)448 +3934 y(graphs.)31 b(Consider)26 b(a)d(shortest)j(path)e(problem.)31 +b(T)-7 b(w)o(o)22 b(nodes)j(that)g(are)f(not)g(connected)i(by)e(an)448 +4047 y(arc)31 b(can)f(be)g(re)o(garded)i(as)e(being)h(joined)h(by)e(an) +g(arc)g(of)g(in\002nite)h(length.)50 b(In)30 b(shortest)j(path)448 +4159 y(problems,)27 b(it)d(is)g(therefore)j(con)l(v)o(enient)h(to)d +(set)g(the)g(background)j(v)n(alue)d(to)g(PlusIn\002nity.)33 +b(In)448 4272 y(netw)o(ork)26 b(\003o)n(w)e(problems,)i(on)f(the)g +(other)h(hand,)g(tw)o(o)e(nodes)i(not)g(connected)h(by)e(an)g(arc)g +(can)448 4385 y(be)j(re)o(garded)h(as)f(joined)h(by)f(an)g(arc)g(of)f +(0)h(capacity)-6 b(.)43 b(F)o(or)27 b(these)i(problems,)h(therefore,)h +(it)c(is)448 4498 y(more)i(con)l(v)o(enient)j(to)c(set)h(the)g +(background)j(v)n(alue)d(to)g(0.)43 b(In)29 b(general,)i(when)e +(representing)448 4611 y(sparse)c(matrices,)g(the)e(background)k(v)n +(alue)e(is)e(the)h(v)n(alue)g(that)g(is)g(assumed)h(implicitly)-6 +b(.)589 4724 y(At)18 b(initialization,)k(the)d(background)i(v)n(alue)e +(is)f(set)g(to)g(0.)27 b(It)18 b(can)g(be)g(read)h(with)f +Fn(Cudd)p 3237 4724 V 34 w(ReadBac)n(kgr)l(ound)r Fo(,)448 +4837 y(and)k(modi\002ed)f(with)f Fn(Cudd)p 1325 4837 +V 34 w(SetBac)n(kgr)l(ound)p Fo(.)31 b(The)21 b(background)j(v)n(alue)d +(af)n(fects)h(procedures)p Black 1897 5225 a(10)p Black +eop end +%%Page: 11 11 +TeXDict begin 11 10 bop Black Black 448 573 a Fo(that)34 +b(read)f(sparse)i(matrices/graphs)h(\()p Fn(Cudd)p 1903 +573 28 4 v 34 w(addRead)h Fo(and)c Fn(Cudd)p 2654 573 +V 34 w(addHarwell)p Fo(\),)k(proce-)448 686 y(dures)31 +b(that)f(print)g(out)f(sum-of-product)34 b(e)o(xpressions)e(for)d(ADDs) +f(\()p Fn(Cudd)p 2855 686 V 34 w(PrintMinterm)p Fo(\),)448 +799 y(generators)43 b(of)d(cubes)h(\()p Fn(Cudd)p 1458 +799 V 34 w(F)-10 b(or)m(eac)o(hCube)p Fo(\),)46 b(and)40 +b(procedures)j(that)e(count)g(minterms)448 912 y(\()p +Fn(Cudd)p 679 912 V 34 w(CountMinterm)p Fo(\).)448 1157 +y Fp(3.5.4)92 b(New)22 b(Constants)448 1332 y Fo(Ne)n(w)d(constant)j +(can)f(be)f(created)i(by)e(calling)i Fn(Cudd)p 2070 1332 +V 34 w(addConst)r Fo(.)29 b(This)20 b(function)i(will)e(retrie)n(v)o(e) +448 1445 y(the)31 b(ADD)e(for)i(the)g(desired)h(constant,)i(if)d(it)f +(already)i(e)o(xist,)h(or)e(it)f(will)g(create)i(a)e(ne)n(w)g(one.)448 +1558 y(Ob)o(viously)-6 b(,)25 b(ne)n(w)e(constants)j(should)f(only)g +(be)e(used)i(when)e(manipulating)k(ADDs.)448 1807 y Fi(3.6)99 +b(Cr)n(eating)26 b(V)-9 b(ariables)448 1981 y Fo(Decision)28 +b(diagrams)g(are)e(typically)j(created)f(by)e(combining)i(simpler)g +(decision)g(diagrams.)448 2094 y(The)22 b(simplest)h(decision)h +(diagrams,)g(of)e(course,)h(cannot)h(be)e(created)h(in)f(that)h(w)o(ay) +-6 b(.)28 b(Constant)448 2207 y(functions)e(ha)n(v)o(e)e(been)g +(discussed)h(in)e(Section)h(3.5.)29 b(In)23 b(this)g(section)i(we)d +(discuss)j(the)f(simple)448 2320 y(v)n(ariable)i(functions,)f(also)g +(kno)n(wn)e(as)h Fn(pr)l(ojection)i(functions)p Fo(.)448 +2566 y Fp(3.6.1)92 b(New)22 b(BDD)g(and)g(ADD)g(V)-8 +b(ariables)448 2740 y Fo(The)27 b(projection)j(functions)g(are)e +(distinct)h(for)f(BDDs)d(and)j(ADDs.)39 b(A)26 b(projection)k(function) +448 2853 y(for)24 b(BDDs)d(consists)k(of)e(an)h(internal)h(node)f(with) +f(both)h(outgoing)h(arcs)f(pointing)h(to)e(the)h(con-)448 +2966 y(stant)h(1.)j(The)23 b Fn(else)h Fo(arc)g(is)f(complemented.)589 +3079 y(An)e(ADD)e(projection)k(function,)h(on)d(the)g(other)h(hand,)g +(has)f(the)g Fn(else)h Fo(pointer)g(directed)h(to)448 +3192 y(the)35 b(arithmetic)h(zero)f(function.)64 b(One)34 +b(should)i(ne)n(v)o(er)f(mix)f(the)h(tw)o(o)f(types)h(of)f(v)n +(ariables.)448 3304 y(BDD)k(v)n(ariables)k(should)g(be)e(used)h(when)f +(manipulating)j(BDDs,)f(and)e(ADD)e(v)n(ariables)448 +3417 y(should)c(be)e(used)h(when)f(manipulating)j(ADDs.)53 +b(Three)33 b(functions)h(are)f(pro)o(vided)h(to)e(cre-)448 +3530 y(ate)24 b(BDD)e(v)n(ariables:)p Black 585 3718 +a Fm(\017)p Black 46 w Fn(Cudd)p 877 3718 V 33 w(bddIthV)-10 +b(ar)r Fo(:)40 b(Returns)29 b(the)f(projection)j(function)f(with)e +(inde)o(x)h Fk(i)p Fo(.)41 b(If)28 b(the)g(func-)676 +3831 y(tion)c(does)g(not)g(e)o(xist,)g(it)f(is)g(created.)p +Black 585 4018 a Fm(\017)p Black 46 w Fn(Cudd)p 877 4018 +V 33 w(bddNe)o(wV)-10 b(ar)r Fo(:)49 b(Returns)35 b(a)d(ne)n(w)h +(projection)j(function,)i(whose)c(inde)o(x)g(is)f(the)676 +4131 y(lar)n(gest)25 b(inde)o(x)f(in)g(use)g(at)f(the)h(time)f(of)h +(the)g(call,)f(plus)i(1.)p Black 585 4319 a Fm(\017)p +Black 46 w Fn(Cudd)p 877 4319 V 33 w(bddNe)o(wV)-10 b(arAtLe)o(vel)p +Fo(:)50 b(Similar)34 b(to)f Fn(Cudd)p 2283 4319 V 34 +w(bddNe)o(wV)-10 b(ar)r Fo(.)59 b(In)34 b(addition)i(it)d(al-)676 +4432 y(lo)n(ws)27 b(to)h(specify)i(the)e(position)i(in)e(the)g(v)n +(ariable)h(order)g(at)f(which)g(the)g(ne)n(w)g(v)n(ariable)676 +4545 y(should)i(be)f(inserted.)47 b(In)29 b(contrast,)j +Fn(Cudd)p 2060 4545 V 33 w(bddNe)o(wV)-10 b(ar)32 b Fo(adds)d(the)h(ne) +n(w)e(v)n(ariable)i(at)676 4658 y(the)23 b(end)h(of)g(the)g(order)-5 +b(.)448 4845 y(The)33 b(analogous)j(functions)g(for)d(ADDs)f(are)i +Fn(Cudd)p 2142 4845 V 33 w(addIthV)-10 b(ar)r Fo(,)38 +b Fn(Cudd)p 2795 4845 V 33 w(addNe)o(wV)-10 b(ar)r Fo(,)36 +b(and)448 4958 y Fn(Cudd)p 649 4958 V 34 w(addNe)o(wV)-10 +b(arAtLe)o(vel)p Fo(.)p Black 1897 5225 a(11)p Black +eop end +%%Page: 12 12 +TeXDict begin 12 11 bop Black Black 448 573 a Fp(3.6.2)92 +b(New)22 b(ZDD)g(V)-8 b(ariables)448 747 y Fo(Unlik)o(e)33 +b(the)f(projection)i(functions)g(of)e(BDDs)e(and)i(ADDs,)g(the)g +(projection)i(functions)g(of)448 860 y(ZDDs)20 b(ha)n(v)o(e)j(diagrams) +g(with)e Fk(n)13 b Fl(+)g(1)22 b Fo(nodes,)h(where)f +Fk(n)e Fo(is)i(the)f(number)i(of)f(v)n(ariables.)30 b(There-)448 +973 y(fore)g(the)f(ZDDs)e(of)h(the)h(projection)j(functions)f(change)g +(when)d(ne)n(w)h(v)n(ariables)h(are)f(added.)448 1086 +y(This)21 b(will)g(be)h(discussed)i(in)d(Section)h(3.9.)28 +b(Here)21 b(we)g(assume)h(that)g(the)g(number)g(of)f(v)n(ariables)448 +1199 y(is)j(\002x)o(ed.)k(The)23 b(ZDD)f(of)h(the)h Fk(i)p +Fo(-th)g(projection)i(function)g(is)d(returned)j(by)e +Fn(Cudd)p 2965 1199 28 4 v 33 w(zddIthV)-10 b(ar)r Fo(.)448 +1448 y Fi(3.7)99 b(Basic)25 b(BDD)h(Manipulation)448 +1622 y Fo(Common)34 b(manipulations)j(of)d(BDDs)e(can)i(be)g +(accomplished)j(by)d(calling)h Fn(Cudd)p 3153 1622 V +34 w(bddIte)p Fo(.)448 1735 y(This)19 b(function)i(tak)o(es)e(three)h +(BDDs,)d Fk(f)10 b Fo(,)18 b Fk(g)s Fo(,)h(and)g Fk(h)p +Fo(,)g(as)g(ar)n(guments)i(and)e(computes)h Fk(f)12 b +Fm(\001)r Fk(g)5 b Fl(+)r Fk(f)3311 1702 y Fd(0)3335 +1735 y Fm(\001)r Fk(h)p Fo(.)448 1848 y(Lik)o(e)29 b(all)g(the)g +(functions)j(that)d(create)h(ne)n(w)f(BDDs)e(or)i(ADDs,)f +Fn(Cudd)p 2698 1848 V 34 w(bddIte)i Fo(returns)h(a)d(re-)448 +1961 y(sult)j(that)g(must)f(be)g(e)o(xplicitly)i(referenced)h(by)d(the) +h(caller)-5 b(.)49 b Fn(Cudd)p 2609 1961 V 34 w(bddIte)32 +b Fo(can)e(be)g(used)h(to)448 2074 y(implement)i(all)e(tw)o(o-ar)n +(gument)k(boolean)e(functions.)55 b(Ho)n(we)n(v)o(er)l(,)33 +b(the)f(package)i(also)e(pro-)448 2187 y(vides)24 b Fn(Cudd)p +863 2187 V 33 w(bddAnd)i Fo(as)c(well)g(as)g(the)h(other)g(tw)o +(o-operand)i(boolean)f(functions,)h(which)d(are)448 2300 +y(slightly)32 b(more)f(ef)n(\002cient)f(when)h(a)e(tw)o(o-operand)k +(function)f(is)e(called)i(for)-5 b(.)48 b(The)30 b(follo)n(wing)448 +2413 y(fragment)24 b(of)f(code)h(illustrates)h(ho)n(w)d(to)h(b)n(uild)h +(the)f(BDD)e(for)h(the)h(function)i Fk(f)35 b Fl(=)25 +b Fk(x)3101 2380 y Fd(0)3101 2436 y Fc(0)3140 2413 y +Fk(x)3192 2380 y Fd(0)3192 2436 y Fc(1)3232 2413 y Fk(x)3284 +2380 y Fd(0)3284 2436 y Fc(2)3323 2413 y Fk(x)3375 2380 +y Fd(0)3375 2436 y Fc(3)3414 2413 y Fo(.)p Black Black +448 2600 a Fh(DdManager)51 b(*manager;)448 2713 y(DdNode)h(*f,)h(*var,) +g(*tmp;)448 2826 y(int)h(i;)448 3052 y(...)448 3278 y(f)g(=)h +(Cudd_ReadOne\(m)o(an)o(ag)o(er)o(\);)448 3391 y(Cudd_Ref\(f\);)448 +3504 y(for)f(\(i)f(=)h(3;)g(i)g(>=)g(0;)f(i--\))g({)667 +3616 y(var)g(=)h(Cudd_bddIthVar)o(\(m)o(ana)o(ge)o(r,)o(i\))o(;)667 +3729 y(tmp)f(=)h(Cudd_bddAnd\(ma)o(na)o(ger)o(,C)o(ud)o(d_)o(No)o(t\(v) +o(ar)o(\),)o(f\))o(;)667 3842 y(Cudd_Ref\(tmp\);)667 +3955 y(Cudd_Recursive)o(De)o(re)o(f\()o(ma)o(nag)o(er)o(,f)o(\);)667 +4068 y(f)g(=)g(tmp;)448 4181 y(})448 4369 y Fo(This)24 +b(e)o(xample)g(illustrates)i(the)e(follo)n(wing)h(points:)p +Black 585 4556 a Fm(\017)p Black 46 w Fo(Intermediate)40 +b(results)g(must)d(be)h(\223referenced\224)k(and)c(\223dereferenced.)-6 +b(\224)76 b(Ho)n(we)n(v)o(er)l(,)676 4669 y Fh(var)25 +b Fo(is)j(a)f(projection)k(function,)g(and)d(its)g(reference)i(count)f +(is)f(al)o(w)o(ays)g(greater)i(than)676 4782 y(0.)e(Therefore,)d(there) +f(is)g(no)f(call)h(to)g Fn(Cudd)p 2026 4782 V 33 w(Ref)13 +b Fo(.)p Black 1897 5225 a(12)p Black eop end +%%Page: 13 13 +TeXDict begin 13 12 bop Black Black Black 585 573 a Fm(\017)p +Black 46 w Fo(The)24 b(ne)n(w)g Fh(f)f Fo(must)i(be)f(assigned)j(to)e +(a)f(temporary)j(v)n(ariable)f(\()p Fh(tmp)d Fo(in)h(this)h(e)o +(xample\).)676 686 y(If)c(the)g(result)i(of)e Fn(Cudd)p +1408 686 28 4 v 34 w(bddAnd)k Fo(were)c(assigned)i(directly)h(to)d +Fh(f)p Fo(,)f(the)i(old)f Fh(f)f Fo(w)o(ould)i(be)676 +799 y(lost,)h(and)h(there)h(w)o(ould)f(be)f(no)h(w)o(ay)f(to)h(free)g +(its)f(nodes.)p Black 585 983 a Fm(\017)p Black 46 w +Fo(The)g(statement)i Fh(f)54 b(=)g(tmp)21 b Fo(has)j(the)g(same)g(ef)n +(fect)g(as:)p Black Black 894 1197 a Fh(f)54 b(=)g(tmp;)894 +1310 y(Cudd_Ref\(f\);)894 1423 y(Cudd_Recursive)o(De)o(ref)o(\(m)o(an)o +(ag)o(er)o(,tm)o(p\))o(;)676 1637 y Fo(b)n(ut)27 b(is)f(more)h(ef)n +(\002cient.)39 b(The)26 b(reference)j(is)d(\223passed\224)j(from)e +Fh(tmp)d Fo(to)j Fh(f)p Fo(,)f(and)h Fh(tmp)d Fo(is)676 +1750 y(no)n(w)f(ready)h(to)g(be)f(reutilized.)p Black +585 1934 a Fm(\017)p Black 46 w Fo(It)31 b(is)g(normally)h(more)g(ef)n +(\002cient)g(to)f(b)n(uild)h(BDDs)e(\223bottom-up.)-6 +b(\224)54 b(This)31 b(is)g(why)g(the)676 2047 y(loop)22 +b(goes)g(from)f(3)g(to)g(0.)28 b(Notice,)22 b(ho)n(we)n(v)o(er)l(,)g +(that)g(after)g(v)n(ariable)h(reordering,)h(higher)676 +2160 y(inde)o(x)30 b(does)h(not)f(necessarily)i(mean)e(\223closer)h(to) +f(the)g(bottom.)-6 b(\224)48 b(Of)29 b(course,)j(in)e(this)676 +2273 y(simple)24 b(e)o(xample,)g(ef)n(\002cienc)o(y)g(is)g(not)g(a)f +(concern.)p Black 585 2457 a Fm(\017)p Black 46 w Fo(Had)31 +b(we)g(w)o(anted)h(to)g(conjoin)i(the)e(v)n(ariables)h(in)f(a)f +(bottom-up)j(f)o(ashion)g(e)n(v)o(en)e(after)676 2569 +y(reordering,)26 b(we)c(should)j(ha)n(v)o(e)f(used)g +Fn(Cudd)p 2074 2569 V 34 w(ReadIn)l(vP)-7 b(erm)p Fo(.)30 +b(One)23 b(has)g(to)h(be)f(careful,)676 2682 y(though,)28 +b(to)e(\002x)f(the)i(order)g(of)f(conjunction)j(before)f(entering)g +(the)e(loop.)38 b(Otherwise,)676 2795 y(if)33 b(reordering)j(tak)o(es)e +(place,)i(it)d(is)h(possible)h(to)e(use)h(one)f(v)n(ariable)i(twice)f +(and)g(skip)676 2908 y(another)25 b(v)n(ariable.)448 +3156 y Fi(3.8)99 b(Basic)25 b(ADD)g(Manipulation)448 +3330 y Fo(The)f(most)f(common)h(w)o(ay)g(to)f(manipulate)j(ADDs)c(is)i +(via)g Fn(Cudd)p 2521 3330 V 34 w(addApply)p Fo(.)31 +b(This)23 b(function)448 3443 y(can)35 b(apply)g(a)e(wide)h(v)n(ariety) +h(of)f(operators)i(to)e(a)f(pair)h(of)g(ADDs.)58 b(Among)34 +b(the)g(a)n(v)n(ailable)448 3556 y(operators)27 b(are)d(addition,)i +(multiplication,)h(di)n(vision,)f(minimum,)d(maximum,)h(and)g(boolean) +448 3669 y(operators)i(that)e(w)o(ork)g(on)g(ADDs)e(whose)i(lea)n(v)o +(es)g(are)g(restricted)i(to)e(0)f(and)h(1)f(\(0-1)h(ADDs\).)589 +3782 y(The)g(follo)n(wing)h(fragment)g(of)f(code)h(illustrates)h(ho)n +(w)d(to)h(b)n(uild)h(the)f(ADD)e(for)i(the)g(func-)448 +3894 y(tion)g Fk(f)35 b Fl(=)25 b(5)p Fk(x)885 3908 y +Fc(0)925 3894 y Fk(x)977 3908 y Fc(1)1016 3894 y Fk(x)1068 +3908 y Fc(2)1108 3894 y Fk(x)1160 3908 y Fc(3)1199 3894 +y Fo(.)p Black Black 448 4073 a Fh(DdManager)51 b(*manager;)448 +4186 y(DdNode)h(*f,)h(*var,)g(*tmp;)448 4299 y(int)h(i;)448 +4525 y(...)448 4751 y(f)g(=)h(Cudd_addConst\()o(ma)o(na)o(ge)o(r,)o +(5\);)448 4863 y(Cudd_Ref\(f\);)448 4976 y(for)f(\(i)f(=)h(3;)g(i)g(>=) +g(0;)f(i--\))g({)p Black 1897 5225 a Fo(13)p Black eop +end +%%Page: 14 14 +TeXDict begin 14 13 bop Black Black 667 573 a Fh(var)53 +b(=)h(Cudd_addIthVar)o(\(m)o(ana)o(ge)o(r,)o(i\))o(;)667 +686 y(Cudd_Ref\(var\);)667 799 y(tmp)f(=)h(Cudd_addApply\()o(ma)o(nag)o +(er)o(,C)o(ud)o(d_)o(add)o(Ti)o(me)o(s,)o(va)o(r,f)o(\);)667 +912 y(Cudd_Ref\(tmp\);)667 1024 y(Cudd_Recursive)o(De)o(re)o(f\()o(ma)o +(nag)o(er)o(,f)o(\);)667 1137 y(Cudd_Recursive)o(De)o(re)o(f\()o(ma)o +(nag)o(er)o(,v)o(ar)o(\);)667 1250 y(f)g(=)g(tmp;)448 +1363 y(})448 1538 y Fo(This)25 b(e)o(xample,)i(contrasted)h(to)d(the)g +(e)o(xample)h(of)g(BDD)d(manipulation,)28 b(illustrates)g(the)e(fol-) +448 1651 y(lo)n(wing)e(points:)p Black 585 1826 a Fm(\017)p +Black 46 w Fo(The)d(ADD)f(projection)25 b(function)f(are)e(not)g +(maintained)i(by)e(the)g(manager)-5 b(.)30 b(It)21 b(is)h(there-)676 +1939 y(fore)i(necessary)i(to)d(reference)j(and)e(dereference)j(them.)p +Black 585 2122 a Fm(\017)p Black 46 w Fo(The)17 b(product)j(of)e(tw)o +(o)g(ADDs)e(is)i(computed)i(by)e(calling)i Fn(Cudd)p +2652 2122 28 4 v 34 w(addApply)g Fo(with)d Fn(Cudd)p +3426 2122 V 34 w(addT)-5 b(imes)676 2235 y Fo(as)19 b(parameter)-5 +b(.)29 b(There)20 b(is)f(no)h(\223apply\224)i(function)f(for)f(BDDs,)f +(because)i Fn(Cudd)p 3123 2235 V 34 w(bddAnd)676 2348 +y Fo(and)g Fn(Cudd)p 1028 2348 V 34 w(bddXor)i Fo(plus)f +(complementation)i(are)d(suf)n(\002cient)h(to)f(implement)h(all)e(tw)o +(o-)676 2461 y(ar)n(gument)25 b(boolean)h(functions.)448 +2707 y Fi(3.9)99 b(Basic)25 b(ZDD)h(Manipulation)448 +2882 y Fo(ZDDs)21 b(are)i(often)h(generated)h(by)e(con)l(v)o(erting)j +(e)o(xisting)e(BDDs.)j(\(See)c(Section)g(3.11.\))29 b(Ho)n(w-)448 +2995 y(e)n(v)o(er)l(,)20 b(it)e(is)g(also)h(possible)h(to)e(b)n(uild)i +(ZDDs)d(by)h(applying)j(boolean)f(operators)h(to)d(other)h(ZDDs,)448 +3108 y(starting)29 b(from)e(constants)i(and)e(projection)j(functions.) +41 b(The)26 b(follo)n(wing)j(fragment)f(of)e(code)448 +3220 y(illustrates)34 b(ho)n(w)d(to)h(b)n(uild)g(the)g(ZDD)d(for)j(the) +g(function)h Fk(f)49 b Fl(=)40 b Fk(x)2562 3187 y Fd(0)2562 +3244 y Fc(0)2627 3220 y Fl(+)26 b Fk(x)2776 3187 y Fd(0)2776 +3244 y Fc(1)2841 3220 y Fl(+)g Fk(x)2990 3187 y Fd(0)2990 +3244 y Fc(2)3056 3220 y Fl(+)f Fk(x)3204 3187 y Fd(0)3204 +3244 y Fc(3)3244 3220 y Fo(.)51 b(W)-7 b(e)448 3333 y(assume)25 +b(that)g(the)f(four)h(v)n(ariables)h(already)f(e)o(xist)g(in)f(the)g +(manager)h(when)g(the)f(ZDD)e(for)i Fk(f)32 b Fo(is)448 +3446 y(b)n(uilt.)e(Note)24 b(the)f(use)h(of)g(De)e(Mor)n(gan')-5 +b(s)26 b(la)o(w)-6 b(.)p Black Black 448 3621 a Fh(DdManager)51 +b(*manager;)448 3734 y(DdNode)h(*f,)h(*var,)g(*tmp;)448 +3847 y(int)h(i;)448 4073 y(manager)e(=)i(Cudd_Init\(0,4,)o(CU)o(DD_)o +(UN)o(IQ)o(UE)o(_S)o(LOT)o(S,)667 4186 y(CUDD_CACHE_SLO)o(TS)o(,0)o +(\);)448 4299 y(...)448 4525 y(tmp)g(=)g(Cudd_ReadZddOn)o(e\()o(ma)o +(na)o(ger)o(,0)o(\);)448 4638 y(Cudd_Ref\(tmp\);)448 +4751 y(for)g(\(i)f(=)h(3;)g(i)g(>=)g(0;)f(i--\))g({)667 +4863 y(var)g(=)h(Cudd_zddIthVar)o(\(m)o(ana)o(ge)o(r,)o(i\))o(;)667 +4976 y(Cudd_Ref\(var\);)p Black 1897 5225 a Fo(14)p Black +eop end +%%Page: 15 15 +TeXDict begin 15 14 bop Black Black 667 573 a Fh(f)54 +b(=)g(Cudd_zddInters)o(ec)o(t\()o(man)o(ag)o(er)o(,v)o(ar)o(,tm)o(p\))o +(;)667 686 y(Cudd_Ref\(f\);)667 799 y(Cudd_Recursive)o(De)o(re)o(fZ)o +(dd)o(\(ma)o(na)o(ge)o(r,)o(tm)o(p\);)667 912 y(Cudd_Recursive)o(De)o +(re)o(fZ)o(dd)o(\(ma)o(na)o(ge)o(r,)o(va)o(r\);)667 1024 +y(tmp)f(=)h(f;)448 1137 y(})448 1250 y(f)g(=)h(Cudd_zddDiff\(m)o(an)o +(ag)o(er)o(,C)o(udd)o(_R)o(ea)o(dZ)o(dd)o(One)o(\(m)o(an)o(ag)o(er)o +(,0\))o(,t)o(mp)o(\);)448 1363 y(Cudd_Ref\(f\);)448 1476 +y(Cudd_RecursiveD)o(ere)o(fZ)o(dd)o(\(m)o(an)o(age)o(r,)o(tm)o(p\))o(;) +448 1664 y Fo(This)24 b(e)o(xample)g(illustrates)i(the)e(follo)n(wing)h +(points:)p Black 585 1851 a Fm(\017)p Black 46 w Fo(The)e(projection)k +(functions)f(are)e(referenced,)j(because)f(the)o(y)e(are)g(not)g +(maintained)i(by)676 1964 y(the)d(manager)-5 b(.)p Black +585 2152 a Fm(\017)p Black 46 w Fo(Complementation)26 +b(is)d(obtained)j(by)e(subtracting)i(from)e(the)g(constant)h(1)f +(function.)p Black 585 2340 a Fm(\017)p Black 46 w Fo(The)f(result)h +(of)g Fn(Cudd)p 1364 2340 28 4 v 34 w(ReadZddOne)g Fo(does)g(not)g +(require)h(referencing.)448 2527 y(CUDD)31 b(pro)o(vides)j(functions)i +(for)d(the)g(manipulation)i(of)e(co)o(v)o(ers)g(represented)j(by)d +(ZDDs.)448 2640 y(F)o(or)40 b(instance,)47 b Fn(Cudd)p +1179 2640 V 33 w(zddIsop)c Fo(b)n(uilds)f(a)e(ZDD)f(representing)44 +b(an)c(irredundant)k(sum)c(of)448 2753 y(products)31 +b(for)e(the)g(incompletely)i(speci\002ed)f(function)h(de\002ned)e(by)f +(the)h(tw)o(o)f(BDDs)f Fk(L)h Fo(and)448 2866 y Fk(U)10 +b Fo(.)45 b Fn(Cudd)p 789 2866 V 33 w(zddW)-8 b(eakDiv)31 +b Fo(performs)f(the)f(weak)g(di)n(vision)i(of)e(tw)o(o)g(co)o(v)o(ers)h +(gi)n(v)o(en)f(as)g(ZDDs.)448 2979 y(These)c(functions)h(e)o(xpect)f +(the)f(tw)o(o)g(ZDD)e(v)n(ariables)k(corresponding)i(to)c(the)g(tw)o(o) +g(literals)h(of)448 3092 y(the)30 b(function)j(v)n(ariable)e(to)f(be)g +(adjacent.)50 b(One)29 b(has)h(to)g(create)h(v)n(ariable)h(groups)f +(\(see)g(Sec-)448 3205 y(tion)23 b(3.14\))g(for)g(reordering)i(of)d +(the)h(ZDD)e(v)n(ariables)j(to)e(w)o(ork.)29 b(BDD)20 +b(automatic)k(reordering)448 3318 y(is)31 b(safe)h(e)n(v)o(en)f +(without)h(groups:)45 b(If)31 b(realignment)i(of)e(ZDD)e(and)i(ADD/BDD) +d(v)n(ariables)33 b(is)448 3430 y(requested)26 b(\(see)e(Section)h +(3.15\))f(groups)h(will)e(be)h(k)o(ept)g(adjacent.)448 +3680 y Fi(3.10)99 b(Con)l(v)o(erting)26 b(ADDs)e(to)h(BDDs)g(and)h(V)l +(ice)f(V)-10 b(ersa)448 3854 y Fo(Se)n(v)o(eral)25 b(procedures)i(are)d +(pro)o(vided)i(to)e(con)l(v)o(ert)i(ADDs)d(to)h(BDDs,)f(according)j(to) +e(dif)n(ferent)448 3967 y(criteria.)29 b(\()p Fn(Cudd)p +986 3967 V 34 w(addBddP)-7 b(attern)p Fo(,)21 b Fn(Cudd)p +1805 3967 V 34 w(addBddInterval)p Fo(,)i(and)18 b Fn(Cudd)p +2795 3967 V 34 w(addBddThr)m(eshold)r Fo(.\))448 4080 +y(The)34 b(con)l(v)o(ersion)i(from)e(BDDs)e(to)h(ADDs)g(\()p +Fn(Cudd)p 2119 4080 V 34 w(BddT)-8 b(oAdd)r Fo(\))34 +b(is)f(based)i(on)f(the)g(simple)448 4193 y(principle)26 +b(of)e(mapping)h(the)f(logical)i(0)d(and)h(1)g(on)f(the)h(arithmetic)i +(0)d(and)i(1.)k(It)23 b(is)h(also)g(possi-)448 4306 y(ble)g(to)g(con)l +(v)o(ert)h(an)f(ADD)e(with)h(inte)o(ger)i(v)n(alues)g(\(more)f +(precisely)-6 b(,)26 b(\003oating)e(point)h(numbers)448 +4418 y(with)f(0)f(fractional)j(part\))e(to)g(an)f(array)i(of)e(BDDs)f +(by)i(repeatedly)i(calling)f Fn(Cudd)p 3012 4418 V 34 +w(addIthBit)r Fo(.)448 4668 y Fi(3.11)99 b(Con)l(v)o(erting)26 +b(BDDs)f(to)g(ZDDs)g(and)g(V)l(ice)g(V)-10 b(ersa)448 +4842 y Fo(Man)o(y)22 b(applications)k(\002rst)21 b(b)n(uild)j(a)d(set)h +(of)g(BDDs)f(and)h(then)h(deri)n(v)o(e)g(ZDDs)d(from)i(the)g(BDDs.)448 +4955 y(These)i(applications)j(should)e(create)f(the)g(manager)g(with)f +(0)g(ZDD)e(v)n(ariables)26 b(and)e(create)g(the)p Black +1897 5225 a(15)p Black eop end +%%Page: 16 16 +TeXDict begin 16 15 bop Black Black 448 573 a Fo(BDDs.)40 +b(Then)27 b(the)o(y)h(should)h(call)f Fn(Cudd)p 1762 +573 28 4 v 34 w(zddV)-10 b(ar)o(sF)-5 b(r)l(omBddV)-10 +b(ar)o(s)30 b Fo(to)d(create)i(the)f(necessary)448 686 +y(ZDD)j(v)n(ariables\227whose)36 b(number)e(is)e(lik)o(ely)i(to)f(be)g +(kno)n(wn)g(once)g(the)g(BDDs)e(are)i(a)n(v)n(ail-)448 +799 y(able.)g(This)24 b(approach)j(eliminates)f(the)f(dif)n +(\002culties)i(that)e(arise)g(when)g(the)f(number)i(of)e(ZDD)448 +912 y(v)n(ariables)i(changes)f(while)f(ZDDs)e(are)i(being)h(b)n(uilt.) +589 1024 y(The)h(simplest)h(con)l(v)o(ersion)h(from)e(BDDs)e(to)h(ZDDs) +f(is)i(a)f(simple)h(change)h(of)f(represen-)448 1137 +y(tation,)39 b(which)c(preserv)o(es)i(the)f(functions.)65 +b(Simply)35 b(put,)j(gi)n(v)o(en)d(a)g(BDD)e(for)i Fk(f)10 +b Fo(,)36 b(a)e(ZDD)448 1250 y(for)g Fk(f)42 b Fo(is)34 +b(requested.)61 b(In)34 b(this)g(case)h(the)e(correspondence)39 +b(between)c(the)e(BDD)f(v)n(ariables)448 1363 y(and)g(ZDD)e(v)n +(ariables)j(is)e(one-to-one.)55 b(Hence,)34 b Fn(Cudd)p +2232 1363 V 34 w(zddV)-10 b(ar)o(sF)-5 b(r)l(omBddV)-10 +b(ar)o(s)33 b Fo(should)g(be)448 1476 y(called)c(with)e(the)g +Fn(multiplicity)j Fo(parameter)f(equal)f(to)g(1.)39 b(The)27 +b(con)l(v)o(ersion)j(proper)f(can)f(then)448 1589 y(be)37 +b(performed)h(by)f(calling)h Fn(Cudd)p 1595 1589 V 33 +w(zddP)-7 b(ortF)i(r)l(omBdd)r Fo(.)69 b(The)36 b(in)l(v)o(erse)j +(transformation)g(is)448 1702 y(performed)26 b(by)d Fn(Cudd)p +1164 1702 V 34 w(zddP)-7 b(ortT)f(oBdd)r Fo(.)589 1815 +y(ZDDs)28 b(are)i(quite)h(often)f(used)h(for)e(the)h(representation)k +(of)c Fn(co)o(ver)o(s)p Fo(.)48 b(This)29 b(is)h(normally)448 +1928 y(done)36 b(by)g(associating)i(tw)o(o)d(ZDD)e(v)n(ariables)38 +b(to)d(each)h(v)n(ariable)h(of)e(the)g(function.)66 b(\(And)448 +2041 y(hence,)28 b(typically)-6 b(,)28 b(to)e(each)g(BDD)e(v)n +(ariable.\))38 b(One)25 b(ZDD)f(v)n(ariable)j(is)f(associated)i(with)e +(the)448 2154 y(positi)n(v)o(e)35 b(literal)f(of)f(the)g(BDD)e(v)n +(ariable,)37 b(while)d(the)f(other)h(ZDD)d(v)n(ariable)k(is)d +(associated)448 2267 y(with)i(the)f(ne)o(gati)n(v)o(e)h(literal.)60 +b(A)32 b(call)i(to)f Fn(Cudd)p 1980 2267 V 34 w(zddV)-10 +b(ar)o(sF)-5 b(r)l(omBddV)-10 b(ar)o(s)36 b Fo(with)d +Fn(multiplicity)448 2379 y Fo(equal)25 b(to)e(2)h(will)f(associate)j +(to)d(BDD)f(v)n(ariable)j Fk(i)e Fo(the)h(tw)o(o)f(ZDD)f(v)n(ariables)j +Fl(2)p Fk(i)f Fo(and)g Fl(2)p Fk(i)d Fl(+)f(1)p Fo(.)589 +2492 y(If)j(a)f(BDD)f(v)n(ariable)j(group)g(tree)f(e)o(xists)h(when)f +Fn(Cudd)p 2300 2492 V 34 w(zddV)-10 b(ar)o(sF)-5 b(r)l(omBddV)-10 +b(ar)o(s)25 b Fo(is)d(called)448 2605 y(\(see)29 b(Section)f(3.13\))g +(the)g(function)i(generates)g(a)e(ZDD)d(v)n(ariable)30 +b(group)f(tree)f(consistent)i(to)448 2718 y(it.)57 b(In)33 +b(an)o(y)h(case,)h(all)f(the)f(ZDD)e(v)n(ariables)k(deri)n(v)o(ed)g +(from)e(the)g(same)g(BDD)e(v)n(ariable)k(are)448 2831 +y(clustered)26 b(into)e(a)f(group.)589 2944 y(If)i(the)f(ZDD)e(for)j +Fk(f)33 b Fo(is)24 b(created)i(and)f(later)g(a)f(ne)n(w)f(ZDD)g(v)n +(ariable)j(is)e(added)h(to)g(the)f(man-)448 3057 y(ager)l(,)f(the)e +(function)i(represented)i(by)c(the)h(e)o(xisting)g(ZDD)e(changes.)29 +b(Suppose,)23 b(for)e(instance,)448 3170 y(that)26 b(tw)o(o)f(v)n +(ariables)i(are)e(initially)i(created,)g(and)e(that)h(the)f(ZDD)e(for)i +Fk(f)38 b Fl(=)27 b Fk(x)2896 3184 y Fc(0)2957 3170 y +Fl(+)21 b Fk(x)3101 3184 y Fc(1)3165 3170 y Fo(is)j(b)n(uilt.)448 +3283 y(If)33 b(a)g(third)h(v)n(ariable)h(is)e(added,)k(say)c +Fk(x)1714 3297 y Fc(2)1753 3283 y Fo(,)i(then)f(the)f(ZDD)e(represents) +36 b Fk(g)47 b Fl(=)c(\()p Fk(x)3054 3297 y Fc(0)3121 +3283 y Fl(+)27 b Fk(x)3271 3297 y Fc(1)3310 3283 y Fl(\))p +Fk(x)3397 3250 y Fd(0)3397 3306 y Fc(2)448 3396 y Fo(instead.)36 +b(This)25 b(change)i(in)e(function)j(ob)o(viously)g(applies)f(re)o +(gardless)g(of)e(what)g(use)h(is)f(made)448 3509 y(of)j(the)g(ZDD.)39 +b(Ho)n(we)n(v)o(er)l(,)29 b(if)e(the)h(ZDD)e(is)h(used)i(to)e +(represent)k(a)c(co)o(v)o(er,)i(the)f(co)o(v)o(er)g(itself)g(is)448 +3621 y(not)i(changed)h(by)e(the)g(addition)j(of)c(ne)n(w)h(v)n +(ariable.)47 b(\(What)29 b(changes)i(is)e(the)g(characteristic)448 +3734 y(function)d(of)d(the)h(co)o(v)o(er)-5 b(.\))448 +3984 y Fi(3.12)99 b(V)-9 b(ariable)25 b(Reordering)h(f)n(or)e(BDDs)h +(and)h(ADDs)448 4158 y Fo(The)20 b(CUDD)d(package)22 +b(pro)o(vides)g(a)d(rich)h(set)g(of)g(dynamic)h(reordering)i +(algorithms.)29 b(Some)19 b(of)448 4271 y(them)24 b(are)g(slight)g(v)n +(ariations)i(of)e(e)o(xisting)h(techniques)i([16)q(,)22 +b(6)q(,)g(2)q(,)g(10)q(,)h(15)q(,)f(11)q(];)h(some)h(others)448 +4384 y(ha)n(v)o(e)h(been)f(de)n(v)o(eloped)i(speci\002cally)f(for)f +(this)g(package)i([14)q(,)c(13)q(].)589 4497 y(Reordering)33 +b(af)n(fects)e(a)f(unique)i(table.)50 b(This)30 b(means)h(that)g(BDDs)e +(and)i(ADDs,)f(which)448 4609 y(share)36 b(the)g(same)f(unique)i(table) +f(are)f(simultaneously)k(reordered.)66 b(ZDDs,)36 b(on)f(the)g(other) +448 4722 y(hand,)22 b(are)f(reordered)i(separately)-6 +b(.)31 b(In)20 b(the)h(follo)n(wing)h(we)e(discuss)i(the)f(reordering)i +(of)e(BDDs)448 4835 y(and)j(ADDs.)j(Reordering)f(for)e(ZDDs)e(is)h(the) +h(subject)h(of)f(Section)g(3.14.)p Black 1897 5225 a(16)p +Black eop end +%%Page: 17 17 +TeXDict begin 17 16 bop Black Black 589 573 a Fo(Reordering)28 +b(of)d(the)g(v)n(ariables)i(can)f(be)f(in)l(v)n(ok)o(ed)j(directly)f +(by)e(the)g(application)j(by)e(call-)448 686 y(ing)g +Fn(Cudd)p 790 686 28 4 v 34 w(ReduceHeap)p Fo(.)35 b(Or)24 +b(it)h(can)h(be)f(automatically)k(triggered)e(by)e(the)h(package)h +(when)448 799 y(the)k(number)g(of)g(nodes)g(has)g(reached)h(a)e(gi)n(v) +o(en)h(threshold.)52 b(\(The)30 b(threshold)j(is)d(initialized)448 +912 y(and)h(automatically)j(adjusted)f(after)e(each)h(reordering)h(by)e +(the)g(package.\))52 b(T)-7 b(o)30 b(enable)i(au-)448 +1024 y(tomatic)c(dynamic)h(reordering)h(\(also)e(called)g +Fn(async)o(hr)l(onous)j Fo(dynamic)e(reordering)h(in)d(this)448 +1137 y(document\))37 b(the)f(application)i(must)d(call)h +Fn(Cudd)p 2033 1137 V 34 w(A)n(utodynEnable)p Fo(.)66 +b(Automatic)36 b(dynamic)448 1250 y(reordering)27 b(can)d(subsequently) +j(be)d(disabled)h(by)f(calling)h Fn(Cudd)p 2515 1250 +V 34 w(A)n(utodynDisable)p Fo(.)589 1363 y(All)18 b(reordering)j +(methods)e(are)f(a)n(v)n(ailable)j(in)d(both)h(the)f(case)h(of)f +(direct)h(call)g(to)f Fn(Cudd)p 3238 1363 V 33 w(ReduceHeap)448 +1476 y Fo(and)23 b(the)g(case)g(of)g(automatic)h(in)l(v)n(ocation.)32 +b(F)o(or)21 b(man)o(y)i(methods,)h(the)e(reordering)k(procedure)448 +1589 y(is)34 b(iterated)h(until)f(no)f(further)i(impro)o(v)o(ement)g +(is)e(obtained.)61 b(W)-7 b(e)32 b(call)i(these)g(methods)h(the)448 +1702 y Fn(con)l(ver)m(ging)40 b Fo(methods.)68 b(When)37 +b(constraints)i(are)e(imposed)g(on)g(the)f(relati)n(v)o(e)i(position)g +(of)448 1815 y(v)n(ariables)31 b(\(see)d(Section)h(3.13\))g(the)f +(reordering)j(methods)f(apply)f(inside)g(the)g(groups.)44 +b(The)448 1928 y(groups)33 b(themselv)o(es)g(are)e(reordered)i(by)e +(sifting.)53 b(Each)31 b(method)h(is)e(identi\002ed)j(by)e(a)g(con-)448 +2041 y(stant)24 b(of)f(the)h(enumerated)h(type)f Fn(Cudd)p +1700 2041 V 34 w(Reor)m(deringT)-7 b(ype)26 b Fo(de\002ned)e(in)f +Fn(cudd.h)h Fo(\(the)g(e)o(xternal)448 2154 y(header)h(\002le)e(of)h +(the)f(CUDD)f(package\):)p Black 448 2366 a Fp(CUDD)p +717 2366 V 32 w(REORDER)p 1206 2366 V 30 w(NONE:)p Black +44 w Fo(This)i(method)g(causes)h(no)f(reordering.)p Black +448 2554 a Fp(CUDD)p 717 2554 V 32 w(REORDER)p 1206 2554 +V 30 w(SAME:)p Black 44 w Fo(If)18 b(passed)i(to)e Fn(Cudd)p +2196 2554 V 33 w(A)n(utodynEnable)p Fo(,)k(this)d(method)g(lea)n(v)o +(es)676 2667 y(the)f(current)i(method)f(for)f(automatic)i(reordering)h +(unchanged.)30 b(If)17 b(passed)j(to)e Fn(Cudd)p 3333 +2667 V 34 w(ReduceHeap)p Fo(,)676 2780 y(this)24 b(method)g(causes)h +(the)f(current)h(method)g(for)e(automatic)j(reordering)g(to)d(be)h +(used.)p Black 448 2967 a Fp(CUDD)p 717 2967 V 32 w(REORDER)p +1206 2967 V 30 w(RANDOM:)p Black 44 w Fo(P)o(airs)17 +b(of)h(v)n(ariables)j(are)d(randomly)i(chosen,)g(and)f(sw)o(apped)676 +3080 y(in)29 b(the)h(order)-5 b(.)48 b(The)29 b(sw)o(ap)h(is)f +(performed)i(by)f(a)f(series)i(of)f(sw)o(aps)g(of)f(adjacent)j(v)n +(ari-)676 3193 y(ables.)c(The)18 b(best)h(order)g(among)g(those)h +(obtained)g(by)f(the)g(series)g(of)f(sw)o(aps)h(is)g(retained.)676 +3306 y(The)24 b(number)i(of)f(pairs)h(chosen)h(for)e(sw)o(apping)i +(equals)f(the)f(number)h(of)f(v)n(ariables)i(in)676 3419 +y(the)c(diagram.)p Black 448 3606 a Fp(CUDD)p 717 3606 +V 32 w(REORDER)p 1206 3606 V 30 w(RANDOM)p 1657 3606 +V 31 w(PIV)l(O)l(T:)p Black 45 w Fo(Same)17 b(as)h(CUDD)p +2615 3606 V 31 w(REORDER)p 3073 3606 V 30 w(RANDOM,)676 +3719 y(b)n(ut)30 b(the)g(tw)o(o)f(v)n(ariables)j(are)d(chosen)j(so)d +(that)h(the)g(\002rst)g(is)f(abo)o(v)o(e)h(the)g(v)n(ariable)h(with)676 +3832 y(the)d(lar)n(gest)h(number)g(of)e(nodes,)j(and)e(the)g(second)i +(is)d(belo)n(w)h(that)g(v)n(ariable.)43 b(In)28 b(case)676 +3945 y(there)h(are)g(se)n(v)o(eral)h(v)n(ariables)h(tied)e(for)g(the)g +(maximum)g(number)g(of)g(nodes,)i(the)e(one)676 4058 +y(closest)c(to)e(the)h(root)g(is)g(used.)p Black 448 +4246 a Fp(CUDD)p 717 4246 V 32 w(REORDER)p 1206 4246 +V 30 w(SIFT:)p Black 45 w Fo(This)g(method)h(is)g(an)f(implementation)k +(of)c(Rudell')-5 b(s)26 b(sifting)676 4359 y(algorithm)i([16)q(].)39 +b(A)26 b(simpli\002ed)i(description)i(of)d(sifting)h(is)f(as)g(follo)n +(ws:)37 b(Each)27 b(v)n(ari-)676 4472 y(able)32 b(is)g(considered)j(in) +d(turn.)55 b(A)30 b(v)n(ariable)k(is)e(mo)o(v)o(ed)g(up)g(and)g(do)n +(wn)g(in)g(the)g(order)676 4584 y(so)26 b(that)h(it)e(tak)o(es)j(all)e +(possible)i(positions.)40 b(The)25 b(best)i(position)i(is)d +(identi\002ed)h(and)g(the)676 4697 y(v)n(ariable)e(is)e(returned)j(to)d +(that)h(position.)676 4848 y(In)30 b(reality)-6 b(,)34 +b(things)e(are)f(a)g(bit)g(more)f(complicated.)53 b(F)o(or)30 +b(instance,)35 b(there)c(is)g(a)f(limit)676 4961 y(on)g(the)g(number)h +(of)f(v)n(ariables)i(that)f(will)f(be)g(sifted.)49 b(This)30 +b(limit)g(can)h(be)f(read)g(with)p Black 1897 5225 a(17)p +Black eop end +%%Page: 18 18 +TeXDict begin 18 17 bop Black Black 676 573 a Fn(Cudd)p +877 573 28 4 v 33 w(ReadSiftMaxV)-10 b(ar)29 b Fo(and)d(set)f(with)g +Fn(Cudd)p 2195 573 V 34 w(SetSiftMaxV)-10 b(ar)r Fo(.)35 +b(In)25 b(addition,)i(if)e(the)676 686 y(diagram)31 b(gro)n(ws)g(too)g +(much)g(while)g(mo)o(ving)h(a)e(v)n(ariable)j(up)d(or)h(do)n(wn,)h +(that)g(mo)o(v)o(e-)676 799 y(ment)37 b(is)f(terminated)j(before)g(the) +e(v)n(ariable)i(has)e(reached)i(one)e(end)g(of)g(the)h(order)-5 +b(.)676 912 y(The)27 b(maximum)g(ratio)i(by)f(which)g(the)g(diagram)h +(is)e(allo)n(wed)i(to)e(gro)n(w)h(while)f(a)h(v)n(ari-)676 +1024 y(able)35 b(is)f(being)h(sifted)h(can)f(be)f(read)h(with)g +Fn(Cudd)p 2292 1024 V 33 w(ReadMaxGr)l(owth)h Fo(and)f(set)f(with)676 +1137 y Fn(Cudd)p 877 1137 V 33 w(SetMaxGr)l(owth)p Fo(.)p +Black 448 1318 a Fp(CUDD)p 717 1318 V 32 w(REORDER)p +1206 1318 V 30 w(SIFT)p 1439 1318 V 32 w(CONVERGE:)p +Black 43 w Fo(This)18 b(is)f(the)i(con)l(v)o(er)n(ging)i(v)n(ariant)f +(of)e(CUDD-)p 676 1431 V 703 1431 a(REORDER)p 1135 1431 +V 30 w(SIFT)-7 b(.)p Black 448 1612 a Fp(CUDD)p 717 1612 +V 32 w(REORDER)p 1206 1612 V 30 w(SYMM)p 1525 1612 V +31 w(SIFT:)p Black 45 w Fo(This)34 b(method)h(is)f(an)g(implementation) +i(of)e(sym-)676 1725 y(metric)27 b(sifting)i([14)q(].)39 +b(It)26 b(is)h(similar)h(to)f(sifting,)i(with)e(one)h(addition:)38 +b(V)-10 b(ariables)29 b(that)676 1837 y(become)23 b(adjacent)i(during)f +(sifting)g(are)f(tested)h(for)f(symmetry.)29 b(If)22 +b(the)o(y)h(are)g(symmet-)676 1950 y(ric,)34 b(the)o(y)f(are)f(link)o +(ed)i(in)f(a)f(group.)56 b(Sifting)33 b(then)g(continues)i(with)e(a)e +(group)j(being)676 2063 y(mo)o(v)o(ed,)d(instead)h(of)f(a)e(single)j(v) +n(ariable.)51 b(After)30 b(symmetric)i(sifting)f(has)g(been)g(run,)676 +2176 y Fn(Cudd)p 877 2176 V 33 w(SymmPr)l(o\002le)h Fo(can)g(be)g +(called)g(to)g(report)h(on)e(the)h(symmetry)g(groups)h(found.)676 +2289 y(\(Both)23 b(positi)n(v)o(e)i(and)f(ne)o(gati)n(v)o(e)h +(symmetries)g(are)e(reported.\))p Black 448 2470 a Fp(CUDD)p +717 2470 V 32 w(REORDER)p 1206 2470 V 30 w(SYMM)p 1525 +2470 V 31 w(SIFT)p 1759 2470 V 32 w(CONV:)p Black 45 +w Fo(This)17 b(is)h(the)h(con)l(v)o(er)n(ging)i(v)n(ariant)f(of)e +(CUDD-)p 676 2583 V 703 2583 a(REORDER)p 1135 2583 V +30 w(SYMM)p 1444 2583 V 31 w(SIFT)-7 b(.)p Black 448 +2763 a Fp(CUDD)p 717 2763 V 32 w(REORDER)p 1206 2763 +V 30 w(GR)m(OUP)p 1563 2763 V 31 w(SIFT:)p Black 45 w +Fo(This)22 b(method)i(is)e(an)h(implementation)i(of)e(group)676 +2876 y(sifting)c([13)r(].)26 b(It)18 b(is)g(similar)h(to)f(symmetric)i +(sifting,)g(b)n(ut)f(aggre)o(gation)i(is)d(not)h(restricted)676 +2989 y(to)k(symmetric)i(v)n(ariables.)p Black 448 3170 +a Fp(CUDD)p 717 3170 V 32 w(REORDER)p 1206 3170 V 30 +w(GR)m(OUP)p 1563 3170 V 31 w(SIFT)p 1797 3170 V 32 w(CONV:)p +Black 44 w Fo(This)36 b(method)h(repeats)g(until)g(con)l(v)o(er)n(-)676 +3283 y(gence)h(the)f(combination)j(of)d(CUDD)p 1938 3283 +V 31 w(REORDER)p 2396 3283 V 30 w(GR)l(OUP)p 2732 3283 +V 32 w(SIFT)e(and)i(CUDD-)p 676 3396 V 703 3396 a(REORDER)p +1135 3396 V 30 w(WINDO)m(W4.)p Black 448 3576 a Fp(CUDD)p +717 3576 V 32 w(REORDER)p 1206 3576 V 30 w(WINDO)-5 b(W2:)p +Black 46 w Fo(This)30 b(method)h(implements)h(the)e(windo)n(w)h(permu-) +676 3689 y(tation)j(approach)i(of)d(Fujita)h([8)q(])f(and)g(Ishiura)j +([10)q(].)57 b(The)33 b(size)h(of)g(the)f(windo)n(w)g(is)676 +3802 y(2.)p Black 448 3983 a Fp(CUDD)p 717 3983 V 32 +w(REORDER)p 1206 3983 V 30 w(WINDO)-5 b(W3:)p Black 46 +w Fo(Similar)18 b(to)g(CUDD)p 2404 3983 V 31 w(REORDER)p +2862 3983 V 30 w(WINDO)m(W2,)f(b)n(ut)676 4096 y(with)23 +b(a)g(windo)n(w)g(of)h(size)g(3.)p Black 448 4276 a Fp(CUDD)p +717 4276 V 32 w(REORDER)p 1206 4276 V 30 w(WINDO)-5 b(W4:)p +Black 46 w Fo(Similar)18 b(to)g(CUDD)p 2404 4276 V 31 +w(REORDER)p 2862 4276 V 30 w(WINDO)m(W2,)f(b)n(ut)676 +4389 y(with)23 b(a)g(windo)n(w)g(of)h(size)g(4.)p Black +448 4570 a Fp(CUDD)p 717 4570 V 32 w(REORDER)p 1206 4570 +V 30 w(WINDO)-5 b(W2)p 1696 4570 V 33 w(CONV:)p Black +44 w Fo(This)18 b(is)g(the)g(con)l(v)o(er)n(ging)k(v)n(ariant)d(of)f +(CUDD-)p 676 4683 V 703 4683 a(REORDER)p 1135 4683 V +30 w(WINDO)m(W2.)p Black 448 4863 a Fp(CUDD)p 717 4863 +V 32 w(REORDER)p 1206 4863 V 30 w(WINDO)-5 b(W3)p 1696 +4863 V 33 w(CONV:)p Black 44 w Fo(This)18 b(is)g(the)g(con)l(v)o(er)n +(ging)k(v)n(ariant)d(of)f(CUDD-)p 676 4976 V 703 4976 +a(REORDER)p 1135 4976 V 30 w(WINDO)m(W3.)p Black 1897 +5225 a(18)p Black eop end +%%Page: 19 19 +TeXDict begin 19 18 bop Black Black Black 448 573 a Fp(CUDD)p +717 573 28 4 v 32 w(REORDER)p 1206 573 V 30 w(WINDO)-5 +b(W4)p 1696 573 V 33 w(CONV:)p Black 44 w Fo(This)18 +b(is)g(the)g(con)l(v)o(er)n(ging)k(v)n(ariant)d(of)f(CUDD-)p +676 686 V 703 686 a(REORDER)p 1135 686 V 30 w(WINDO)m(W4.)p +Black 448 867 a Fp(CUDD)p 717 867 V 32 w(REORDER)p 1206 +867 V 30 w(ANNEALING:)p Black 43 w Fo(This)24 b(method)h(is)f(an)h +(implementation)i(of)d(simu-)676 980 y(lated)e(annealing)h(for)f(v)n +(ariable)h(ordering,)g(v)n(aguely)g(resemblant)g(of)e(the)h(algorithm)g +(of)676 1093 y([2].)28 b(This)c(method)g(is)g(potentially)i(v)o(ery)e +(slo)n(w)-6 b(.)p Black 448 1275 a Fp(CUDD)p 717 1275 +V 32 w(REORDER)p 1206 1275 V 30 w(GENETIC:)p Black 44 +w Fo(This)26 b(method)i(is)e(an)h(implementation)j(of)c(a)h(genetic)676 +1388 y(algorithm)g(for)e(v)n(ariable)j(ordering,)f(inspired)h(by)d(the) +h(w)o(ork)g(of)f(Drechsler)i([6)q(].)33 b(This)676 1501 +y(method)24 b(is)f(potentially)k(v)o(ery)d(slo)n(w)-6 +b(.)p Black 448 1682 a Fp(CUDD)p 717 1682 V 32 w(REORDER)p +1206 1682 V 30 w(EXA)h(CT:)p Black 44 w Fo(This)22 b(method)i +(implements)h(a)d(dynamic)i(programming)676 1795 y(approach)d(to)f(e)o +(xact)g(reordering)i([9)q(,)c(7)q(,)g(10)q(],)h(with)h(impro)o(v)o +(ements)h(described)h(in)d([11)q(].)676 1908 y(It)33 +b(only)h(stores)g(one)g(BDD)d(at)j(the)f(time.)58 b(Therefore,)37 +b(it)c(is)g(relati)n(v)o(ely)i(ef)n(\002cient)f(in)676 +2021 y(terms)29 b(of)g(memory)-6 b(.)45 b(Compared)29 +b(to)g(other)h(reordering)i(strate)o(gies,)g(it)d(is)g(v)o(ery)g(slo)n +(w)-6 b(,)676 2134 y(and)24 b(is)f(not)h(recommended)i(for)d(more)h +(than)g(16)g(v)n(ariables.)448 2329 y(So)f(f)o(ar)h(we)e(ha)n(v)o(e)i +(described)i(methods)f(whereby)g(the)e(package)j(selects)f(an)e(order)i +(automati-)448 2442 y(cally)-6 b(.)28 b(A)17 b(gi)n(v)o(en)i(order)g +(of)f(the)g(v)n(ariables)i(can)f(also)g(be)f(imposed)h(by)f(calling)i +Fn(Cudd)p 3050 2442 V 34 w(Shuf)n(\003eHeap)p Fo(.)448 +2688 y Fi(3.13)99 b(Gr)n(ouping)26 b(V)-9 b(ariables)448 +2862 y Fo(CUDD)29 b(allo)n(ws)i(the)g(application)j(to)d(specify)h +(constraints)i(on)d(the)g(positions)j(of)c(group)i(of)448 +2975 y(v)n(ariables.)63 b(It)34 b(is)g(possible)j(to)d(request)i(that)f +(a)f(group)h(of)f(contiguous)k(v)n(ariables)e(be)e(k)o(ept)448 +3088 y(contiguous)39 b(by)d(the)g(reordering)i(procedures.)68 +b(It)35 b(is)g(also)h(possible)i(to)e(request)h(that)f(the)448 +3201 y(relati)n(v)o(e)31 b(order)f(of)g(some)f(groups)j(of)d(v)n +(ariables)j(be)d(left)h(unchanged.)50 b(The)29 b(constraints)j(on)448 +3314 y(the)24 b(order)h(are)e(speci\002ed)i(by)f(means)g(of)f(a)g +(tree,)h(which)g(is)f(created)j(in)d(one)h(of)g(tw)o(o)f(w)o(ays:)p +Black 585 3486 a Fm(\017)p Black 46 w Fo(By)f(calling)k +Fn(Cudd)p 1276 3486 V 33 w(Mak)o(eT)-5 b(r)m(eeNode)p +Fo(.)p Black 585 3668 a Fm(\017)p Black 46 w Fo(By)21 +b(calling)j(the)f(functions)i(of)d(the)h(MTR)e(library)j(\(part)f(of)f +(the)h(distrib)n(ution\),)j(and)d(by)676 3781 y(re)o(gistering)i(the)d +(result)i(with)e(the)g(manager)i(using)f Fn(Cudd)p 2510 +3781 V 34 w(SetT)-5 b(r)m(ee)p Fo(.)29 b(The)22 b(current)i(tree)676 +3894 y(re)o(gistered)h(with)f(the)g(manager)g(can)g(be)g(read)g(with)f +Fn(Cudd)p 2531 3894 V 34 w(ReadT)-5 b(r)m(ee)p Fo(.)589 +4067 y(Each)36 b(node)h(in)f(the)g(tree)h(represents)h(a)e(range)h(of)f +(v)n(ariables.)68 b(The)35 b(lo)n(wer)h(bound)h(of)448 +4180 y(the)29 b(range)g(is)f(gi)n(v)o(en)h(by)f(the)h +Fn(low)e Fo(\002eld)h(of)g(the)h(node,)h(and)f(the)f(size)h(of)f(the)g +(group)i(is)e(gi)n(v)o(en)448 4293 y(by)33 b(the)g Fn(size)g +Fo(\002eld)g(of)g(the)g(node.)1525 4260 y Fg(2)1619 4293 +y Fo(The)f(v)n(ariables)j(in)e(each)g(range)h(are)f(k)o(ept)g +(contiguous.)448 4405 y(Furthermore,)22 b(if)e(a)f(node)i(is)f(mark)o +(ed)g(with)g(the)g(MTR)p 2159 4405 V 32 w(FIXED)e(\003ag,)i(then)g(the) +g(relati)n(v)o(e)h(order)448 4518 y(of)32 b(the)g(v)n(ariable)i(ranges) +g(associated)g(to)e(its)g(children)i(is)e(not)h(changed.)56 +b(As)31 b(an)h(e)o(xample,)448 4631 y(suppose)26 b(the)e(initial)h(v)n +(ariable)g(order)f(is:)p Black 448 4706 1196 4 v 554 +4762 a Ff(2)583 4794 y Fe(When)18 b(the)g(v)n(ariables)h(in)f(a)g +(group)h(are)f(reordered,)h(the)g(association)g(between)f(the)h +Fb(low)e Fe(\002eld)h(and)h(the)f(inde)o(x)448 4885 y(of)k(the)h +(\002rst)e(v)n(ariable)h(in)g(the)h(group)g(is)f(lost.)32 +b(The)22 b(package)i(updates)f(the)f(tree)g(to)g(k)o(eep)h(track)f(of)h +(the)f(changes.)448 4976 y(Ho)n(we)n(v)o(er)m(,)e(the)f(application)g +(cannot)h(rely)f(on)h Fb(low)e Fe(to)h(determine)g(the)g(position)h(of) +f(v)n(ariables.)p Black Black 1897 5225 a Fo(19)p Black +eop end +%%Page: 20 20 +TeXDict begin 20 19 bop Black Black Black Black 448 573 +a Fh(x0,)54 b(y0,)f(z0,)g(x1,)g(y1,)g(z1,)g(...)h(,)g(x9,)f(y9,)g(z9.) +448 748 y Fo(Suppose)27 b(we)f(w)o(ant)f(to)h(k)o(eep)h(each)g(group)g +(of)f(three)g(v)n(ariables)i(with)e(the)g(same)g(inde)o(x)h(\(e.g.,)448 +861 y Fh(x3,)54 b(y3,)f(z3)p Fo(\))21 b(contiguous,)27 +b(while)c(allo)n(wing)h(the)g(package)h(to)e(change)i(the)f(order)g(of) +f(the)448 974 y(groups.)31 b(W)-7 b(e)22 b(can)i(accomplish)i(this)e +(with)f(the)h(follo)n(wing)h(code:)p Black Black 448 +1150 a Fh(for)54 b(\(i)f(=)h(0;)g(i)g(<)g(10;)f(i++\))g({)667 +1262 y(\(void\))e(Cudd_MakeTreeNo)o(de\()o(ma)o(na)o(ge)o(r,)o(i*3)o +(,3)o(,M)o(TR)o(_D)o(EFA)o(UL)o(T\))o(;)448 1375 y(})448 +1551 y Fo(If)26 b(we)f(w)o(ant)h(to)g(k)o(eep)h(the)f(order)h(within)g +(each)g(group)g(of)f(v)n(ariables)i(\002x)o(ed)e(\(i.e.,)f +Fh(x)g Fo(before)j Fh(y)448 1664 y Fo(before)d Fh(z)p +Fo(\))e(we)f(need)j(to)e(change)i(MTR)p 1710 1664 28 +4 v 32 w(DEF)-7 b(A)i(UL)d(T)20 b(into)k(MTR)p 2521 1664 +V 32 w(FIXED.)589 1777 y(The)32 b Fn(low)f Fo(parameter)i(passed)g(to)f +Fn(Cudd)p 1894 1777 V 33 w(Mak)o(eT)-5 b(r)m(eeNode)33 +b Fo(is)f(the)g(inde)o(x)g(of)f(a)h(v)n(ariable)448 1890 +y(\(as)27 b(opposed)i(to)e(its)f(le)n(v)o(el)h(or)g(position)i(in)d +(the)h(order\).)39 b(The)27 b(group)g(tree)h(can)f(be)f(created)i(at) +448 2003 y(an)o(y)g(time.)40 b(The)27 b(result)h(ob)o(viously)i +(depends)f(on)f(the)f(v)n(ariable)i(order)g(in)e(ef)n(fect)h(at)f +(creation)448 2115 y(time.)589 2228 y(It)20 b(is)g(possible)i(to)e +(create)h(a)e(v)n(ariable)j(group)f(tree)f(also)h(before)g(the)f(v)n +(ariables)i(themselv)o(es)448 2341 y(are)f(created.)29 +b(The)21 b(package)h(assumes)g(in)e(this)i(case)f(that)g(the)g(inde)o +(x)g(of)g(the)f(v)n(ariables)j(not)e(yet)448 2454 y(in)h(e)o(xistence)i +(will)e(equal)g(their)h(position)h(in)e(the)g(order)h(when)f(the)o(y)g +(are)g(created.)30 b(Therefore,)448 2567 y(applications)g(that)c(rely)h +(on)f Fn(Cudd)p 1558 2567 V 34 w(bddNe)o(wV)-10 b(arAtLe)o(vel)26 +b Fo(or)g Fn(Cudd)p 2613 2567 V 34 w(addNe)o(wV)-10 b(arAtLe)o(vel)26 +b Fo(to)448 2680 y(create)f(ne)n(w)e(v)n(ariables)j(ha)n(v)o(e)e(to)f +(create)i(the)f(v)n(ariables)h(before)g(the)o(y)f(group)h(them.)589 +2793 y(The)31 b(reordering)j(procedure)g(will)d(skip)h(all)g(groups)h +(whose)e(v)n(ariables)j(are)d(not)h(yet)f(in)448 2906 +y(e)o(xistence.)h(F)o(or)24 b(groups)h(that)g(are)f(only)h(partially)h +(in)e(e)o(xistence,)i(the)e(reordering)j(procedure)448 +3019 y(will)18 b(try)h(to)f(reorder)i(the)e(v)n(ariables)i(already)g +(instantiated,)j(without)c(violating)i(the)d(adjacenc)o(y)448 +3132 y(constraints.)448 3378 y Fi(3.14)99 b(V)-9 b(ariable)25 +b(Reordering)h(f)n(or)e(ZDDs)448 3553 y Fo(Reordering)h(of)d(ZDDs)f(is) +h(done)h(in)g(much)f(the)h(same)f(w)o(ay)h(as)f(the)g(reordering)k(of)c +(BDDs)f(and)448 3666 y(ADDs.)28 b(The)23 b(functions)j(corresponding)i +(to)c Fn(Cudd)p 2095 3666 V 33 w(ReduceHeap)i Fo(and)e +Fn(Cudd)p 2966 3666 V 33 w(Shuf)n(\003eHeap)448 3778 +y Fo(are)h Fn(Cudd)p 784 3778 V 33 w(zddReduceHeap)i +Fo(and)e Fn(Cudd)p 1782 3778 V 34 w(zddShuf)n(\003eHeap)p +Fo(.)34 b(T)-7 b(o)23 b(enable)j(dynamic)f(reorder)n(-)448 +3891 y(ing,)36 b(the)e(application)j(must)c(call)h Fn(Cudd)p +1777 3891 V 34 w(A)n(utodynEnableZdd)r Fo(,)39 b(and)34 +b(to)g(disable)h(dynamic)448 4004 y(reordering,)29 b(it)d(must)g(call)g +Fn(Cudd)p 1510 4004 V 34 w(A)n(utodynDisableZdd)r Fo(.)39 +b(In)26 b(the)g(current)i(implementation,)448 4117 y(ho)n(we)n(v)o(er)l +(,)c(the)f(choice)h(of)f(reordering)j(methods)e(for)g(ZDDs)d(is)i(more) +g(limited.)29 b(Speci\002cally)-6 b(,)448 4230 y(these)25 +b(methods)g(are)e(a)n(v)n(ailable:)p Black 448 4428 a +Fp(CUDD)p 717 4428 V 32 w(REORDER)p 1206 4428 V 30 w(NONE;)p +Black Black 448 4611 a(CUDD)p 717 4611 V 32 w(REORDER)p +1206 4611 V 30 w(SAME;)p Black Black 448 4794 a(CUDD)p +717 4794 V 32 w(REORDER)p 1206 4794 V 30 w(RANDOM;)p +Black Black 448 4976 a(CUDD)p 717 4976 V 32 w(REORDER)p +1206 4976 V 30 w(RANDOM)p 1657 4976 V 31 w(PIV)l(O)l(T;)p +Black Black 1897 5225 a Fo(20)p Black eop end +%%Page: 21 21 +TeXDict begin 21 20 bop Black Black Black 448 573 a Fp(CUDD)p +717 573 28 4 v 32 w(REORDER)p 1206 573 V 30 w(SIFT;)p +Black Black 448 760 a(CUDD)p 717 760 V 32 w(REORDER)p +1206 760 V 30 w(SIFT)p 1439 760 V 32 w(CONVERGE;)p Black +Black 448 948 a(CUDD)p 717 948 V 32 w(REORDER)p 1206 +948 V 30 w(SYMM)p 1525 948 V 31 w(SIFT;)p Black Black +448 1136 a(CUDD)p 717 1136 V 32 w(REORDER)p 1206 1136 +V 30 w(SYMM)p 1525 1136 V 31 w(SIFT)p 1759 1136 V 32 +w(CONV.)p Black 589 1348 a Fo(T)-7 b(o)20 b(create)j(ZDD)c(v)n(ariable) +k(groups,)g(the)e(application)j(calls)e Fn(Cudd)p 2693 +1348 V 34 w(Mak)o(eZddT)-5 b(r)m(eeNode)p Fo(.)448 1597 +y Fi(3.15)99 b(K)n(eeping)25 b(Consistent)g(V)-9 b(ariable)25 +b(Orders)g(f)n(or)g(BDDs)g(and)g(ZDDs)448 1772 y Fo(Se)n(v)o(eral)f +(applications)i(that)e(manipulate)i(both)e(BDDs)d(and)j(ZDDs)d +(bene\002t)j(from)f(k)o(eeping)j(a)448 1885 y(\002x)o(ed)e +(correspondence)29 b(between)d(the)f(order)g(of)f(the)h(BDD)d(v)n +(ariables)27 b(and)e(the)f(order)i(of)e(the)448 1998 +y(ZDD)k(v)n(ariables.)51 b(If)30 b(each)h(BDD)d(v)n(ariable)k +(corresponds)h(to)d(a)g(group)h(of)f(ZDD)e(v)n(ariables,)448 +2110 y(then)34 b(it)e(is)g(often)i(desirable)h(that)e(the)g(groups)h +(of)f(ZDD)d(v)n(ariables)35 b(be)d(in)h(the)g(same)f(order)448 +2223 y(as)g(the)g(corresponding)37 b(BDD)30 b(v)n(ariables.)55 +b(CUDD)30 b(allo)n(ws)i(the)h(ZDD)c(order)k(to)f(track)h(the)448 +2336 y(BDD)27 b(order)j(and)f(vice)g(v)o(ersa.)45 b(T)-7 +b(o)27 b(ha)n(v)o(e)j(the)f(ZDD)d(order)k(track)f(the)g(BDD)e(order)l +(,)k(the)e(ap-)448 2449 y(plication)g(calls)e Fn(Cudd)p +1185 2449 V 34 w(zddRealignEnable)p Fo(.)41 b(The)26 +b(ef)n(fect)i(of)e(this)h(call)g(can)g(be)f(re)n(v)o(ersed)i(by)448 +2562 y(calling)j Fn(Cudd)p 925 2562 V 34 w(zddRealignDisable)p +Fo(.)48 b(When)29 b(ZDD)e(realignment)k(is)e(in)g(ef)n(fect,)i +(automatic)448 2675 y(reordering)c(of)c(ZDDs)f(should)j(be)f(disabled.) +448 2924 y Fi(3.16)99 b(Hooks)448 3098 y Fo(Hooks)22 +b(in)f(CUDD)d(are)k(lists)f(of)g(application-speci\002ed)27 +b(functions)c(to)e(be)g(run)g(on)h(certain)g(oc-)448 +3211 y(casions.)29 b(Each)18 b(hook)h(is)f(identi\002ed)i(by)e(a)g +(constant)i(of)e(the)g(enumerated)j(type)d Fn(Cudd)p +3125 3211 V 34 w(HookT)-7 b(ype)p Fo(.)448 3324 y(In)24 +b(V)-10 b(ersion)24 b(2.5.0)g(hooks)h(are)e(de\002ned)i(for)e(these)i +(occasions:)p Black 585 3512 a Fm(\017)p Black 46 w Fo(before)f +(garbage)h(collection)i(\(CUDD)p 1916 3512 V 31 w(PRE)p +2115 3512 V 32 w(GC)p 2274 3512 V 32 w(HOOK\);)p Black +585 3700 a Fm(\017)p Black 46 w Fo(after)d(garbage)h(collection)h +(\(CUDD)p 1850 3700 V 32 w(POST)p 2106 3700 V 31 w(GC)p +2264 3700 V 32 w(HOOK\);)p Black 585 3887 a Fm(\017)p +Black 46 w Fo(before)e(v)n(ariable)i(reordering)g(\(CUDD)p +1939 3887 V 32 w(PRE)p 2139 3887 V 31 w(REORDERING)p +2759 3887 V 30 w(HOOK\);)p Black 585 4075 a Fm(\017)p +Black 46 w Fo(after)e(v)n(ariable)h(reordering)h(\(CUDD)p +1873 4075 V 32 w(POST)p 2129 4075 V 31 w(REORDERING)p +2749 4075 V 30 w(HOOK\).)448 4262 y(The)e(current)i(implementation)i +(of)c(hooks)i(is)e(e)o(xperimental.)34 b(A)24 b(function)i(added)g(to)e +(a)g(hook)448 4375 y(recei)n(v)o(es)c(a)e(pointer)i(to)e(the)g(manager) +l(,)j(a)d(pointer)i(to)e(a)g(constant)i(string,)h(and)d(a)g(pointer)i +(to)e(v)n(oid)448 4488 y(as)27 b(ar)n(guments;)j(it)d(must)f(return)i +(1)e(if)g(successful;)31 b(0)c(otherwise.)39 b(The)26 +b(second)i(ar)n(gument)g(is)448 4601 y(one)21 b(of)f(\223DD,)-6 +b(\224)19 b(\223BDD,)-6 b(\224)18 b(and)j(\223ZDD.)-6 +b(\224)18 b(This)i(allo)n(ws)h(the)f(hook)h(functions)i(to)d(tell)h +(the)f(type)h(of)448 4714 y(diagram)f(for)f(which)h(reordering)h(or)e +(garbage)h(collection)i(tak)o(es)e(place.)28 b(The)19 +b(third)g(ar)n(gument)448 4827 y(v)n(aries)30 b(depending)h(on)e(the)g +(hook.)45 b(The)28 b(hook)h(functions)i(called)f(before)g(or)f(after)g +(garbage)448 4940 y(collection)d(do)d(not)g(use)g(it.)28 +b(The)23 b(hook)h(functions)h(called)f(before)g(reordering)i(are)d +(passed,)h(in)p Black 1897 5225 a(21)p Black eop end +%%Page: 22 22 +TeXDict begin 22 21 bop Black Black 448 573 a Fo(addition)32 +b(to)d(the)h(pointer)h(to)f(the)g(manager)l(,)i(also)e(the)g(method)g +(used)h(for)e(reordering.)50 b(The)448 686 y(hook)27 +b(functions)h(called)f(after)f(reordering)j(are)d(passed)h(the)f(start) +g(time.)35 b(T)-7 b(o)25 b(add)h(a)f(function)448 799 +y(to)e(a)g(hook,)g(one)h(uses)f Fn(Cudd)p 1363 799 28 +4 v 34 w(AddHook)r Fo(.)29 b(The)22 b(function)j(of)e(a)g(gi)n(v)o(en)g +(hook)h(are)f(called)h(in)f(the)448 912 y(order)k(in)e(which)h(the)o(y) +g(were)f(added)i(to)f(the)f(hook.)36 b(F)o(or)25 b(sample)h(hook)g +(functions,)j(one)d(may)448 1024 y(look)f(at)e Fn(Cudd)p +922 1024 V 34 w(StdPr)m(eReor)m(dHook)k Fo(and)d Fn(Cudd)p +1990 1024 V 34 w(StdP)-7 b(ostReor)m(dHook)r Fo(.)448 +1274 y Fi(3.17)99 b(T)n(imeouts)26 b(and)f(Limits)448 +1448 y Fo(It)19 b(is)h(possible)h(to)f(set)f(a)g(time)g(limit)h(for)f +(a)g(manger)h(with)g Fn(Cudd)p 2413 1448 V 33 w(SetT)-5 +b(imeLimit)r Fo(.)27 b(Once)20 b(set,)g(the)448 1561 +y(time)g(a)n(v)n(ailable)i(to)e(the)h(manager)g(can)f(be)g(modi\002ed)h +(through)h(other)f(API)d(functions.)31 b(CUDD)448 1674 +y(checks)e(for)e(e)o(xpiration)i(periodically)-6 b(.)43 +b(When)27 b(time)g(has)g(e)o(xpired,)j(it)c(returns)j(NULL)24 +b(from)448 1787 y(the)29 b(call)h(in)e(progress,)k(b)n(ut)e(it)e(lea)n +(v)o(es)i(the)f(manager)h(in)f(a)f(consistent)k(state.)45 +b(The)28 b(in)l(v)n(oking)448 1900 y(application)f(must)d(be)f +(designed)j(to)d(handle)j(the)d(NULL)e(v)n(alues)k(returned.)589 +2013 y(When)35 b(reordering,)k(if)34 b(a)g(timout)h(is)f(approaching,) +41 b(CUDD)31 b(will)j(quit)h(reordering)i(to)448 2125 +y(gi)n(v)o(e)24 b(the)g(application)i(a)e(chance)h(to)e(\002nish)h +(some)g(computation.)589 2238 y(It)31 b(is)h(also)f(possible)j(to)d(in) +l(v)n(ok)o(e)j(some)d(functions)j(that)e(return)g(NULL)d(if)i(the)o(y)h +(cannot)448 2351 y(complete)k(without)f(creating)i(more)d(than)h(a)f +(set)g(number)h(of)g(nodes.)62 b(See,)36 b(for)e(instance,)448 +2464 y Fn(Cudd)p 649 2464 V 34 w(bddAndLimit)r Fo(.)448 +2713 y Fi(3.18)99 b(The)26 b(SIS/VIS)f(Interface)448 +2888 y Fo(The)j(CUDD)d(package)30 b(contains)f(interf)o(ace)h +(functions)h(that)d(emulate)g(the)g(beha)n(vior)i(of)e(the)448 +3001 y(original)i(BDD)c(package)k(used)f(in)f(SIS)e([17)q(])i(and)g(in) +g(the)g(ne)n(wer)g(VIS)2719 2968 y Fg(3)2783 3001 y Fo([4].)42 +b(Ho)n(w)26 b(to)i(b)n(uild)448 3113 y(VIS)i(with)i(CUDD)d(is)i +(described)j(in)e(the)f(installation)k(documents)f(of)d(VIS.)f(\(V)-10 +b(ersion)32 b(1.1)448 3226 y(and)24 b(later)-5 b(.\))448 +3472 y Fp(3.18.1)93 b(Using)22 b(the)h(CUDD)f(P)o(ackage)i(in)e(SIS)448 +3646 y Fo(This)32 b(section)h(describes)h(ho)n(w)d(to)h(b)n(uild)g(SIS) +f(with)g(the)h(CUDD)d(package.)55 b(Let)31 b Fh(SISDIR)448 +3759 y Fo(designate)41 b(the)d(root)h(of)f(the)g(directory)j(hierarchy) +f(where)e(the)h(sources)g(for)g(SIS)d(reside.)448 3872 +y(Let)27 b Fh(CUDDDIR)d Fo(be)j(the)h(root)g(of)g(the)f(directory)j +(hierarchy)g(where)e(the)f(distrib)n(ution)32 b(of)27 +b(the)448 3985 y(CUDD)21 b(package)k(resides.)30 b(T)-7 +b(o)22 b(b)n(uild)i(SIS)d(with)i(the)g(CUDD)e(package,)k(follo)n(w)e +(these)h(steps.)p Black 562 4173 a(1.)p Black 46 w(Create)g +(directories)i Fh(SISDIR/sis/cudd)16 b Fo(and)24 b Fh(SISDIR/sis/mtr)p +Fo(.)p Black 562 4360 a(2.)p Black 46 w(Cop)o(y)18 b(all)g(\002les)g +(from)g Fh(CUDDDIR/cudd)12 b Fo(and)18 b Fh(CUDDDIR/sis)13 +b Fo(to)18 b Fh(SISDIR/sis/cud)o(d)676 4473 y Fo(and)24 +b(all)f(\002les)g(from)h Fh(CUDDDIR/mtr)18 b Fo(to)23 +b Fh(SISDIR/sis/mtr)p Fo(.)p Black 562 4661 a(3.)p Black +46 w(Cop)o(y)35 b Fh(CUDDDIR/cudd/d)o(oc)o(/c)o(ud)o(d.d)o(oc)27 +b Fo(to)35 b Fh(SISDIR/sis/cud)o(d)p Fo(;)f(also)676 +4774 y(cop)o(y)24 b Fh(CUDDDIR/mtr/doc)o(/m)o(tr)o(.do)o(c)16 +b Fo(to)24 b Fh(SISDIR/sis/mtr)o Fo(.)p Black 448 4855 +1196 4 v 554 4911 a Ff(3)583 4942 y Fe(http://vlsi.Colorado.EDU/)18 +b(vis/)p Black Black 1897 5225 a Fo(22)p Black eop end +%%Page: 23 23 +TeXDict begin 23 22 bop Black Black Black 562 573 a Fo(4.)p +Black 46 w(In)38 b Fh(SISDIR/sis/cud)o(d)31 b Fo(mak)o(e)39 +b Fh(bdd.h)c Fo(a)j(symbolic)h(link)g(to)f Fh(cuddBdd.h)p +Fo(.)676 686 y(\(That)23 b(is:)29 b Fh(ln)54 b(-s)g(cuddBdd.h)c(bdd.h)p +Fo(.\))p Black 562 873 a(5.)p Black 46 w(In)27 b Fh(SISDIR/sis/cudd)20 +b Fo(delete)29 b Fh(Makefile)23 b Fo(and)28 b(rename)h +Fh(Makefile.sis)676 986 y Fo(as)23 b Fh(Makefile)p Fo(.)h(Do)f(the)h +(same)f(in)h Fh(SISDIR/sis/mtr)p Fo(.)p Black 562 1174 +a(6.)p Black 46 w(Cop)o(y)18 b Fh(CUDDDIR/sis/st.)o([c)o(h])11 +b Fo(and)18 b Fh(CUDDDIR/st/doc/)o(st)o(.d)o(oc)11 b +Fo(to)18 b Fh(SISDIR/sis/st)p Fo(.)676 1287 y(\(This)29 +b(will)h(o)o(v)o(erwrite)h(the)f(original)h(\002les:)42 +b(Y)-10 b(ou)29 b(may)h(w)o(ant)g(to)g(sa)n(v)o(e)g(them)g(before-)676 +1400 y(hand.\))p Black 562 1587 a(7.)p Black 46 w(From)17 +b Fh(CUDDDIR/util)12 b Fo(cop)o(y)19 b Fh(datalimit.c)12 +b Fo(to)18 b Fh(SISDIR/sis/util)o Fo(.)i(Up-)676 1700 +y(date)30 b Fh(util.h)d Fo(and)k Fh(Makefile)26 b Fo(in)k +Fh(SISDIR/sis/uti)o(l)p Fo(.)42 b(Speci\002cally)-6 b(,)33 +b(add)676 1813 y(the)38 b(declaration)k Fh(EXTERN)52 +b(long)g(getSoftDataLimi)o(t\(\))o(;)39 b Fo(to)f Fh(util.h)676 +1926 y Fo(and)24 b(add)g Fh(datalimit.c)17 b Fo(to)24 +b(the)g(list)f(of)h(source)h(\002les)e(\(PSRC\))f(in)h +Fh(Makefile)p Fo(.)p Black 562 2114 a(8.)p Black 46 w(In)g +Fh(SISDIR/sis)17 b Fo(remo)o(v)o(e)23 b(the)h(link)f(from)g +Fh(bdd)e Fo(to)i Fh(bdd)p 2578 2114 28 4 v 31 w(cmu)e +Fo(or)i Fh(bdd)p 3058 2114 V 32 w(ucb)d Fo(\(that)676 +2227 y(is,)36 b Fh(rm)54 b(bdd)p Fo(\))32 b(and)j(mak)o(e)f +Fh(bdd)e Fo(a)i(symbolic)i(link)f(to)f Fh(cudd)p Fo(.)58 +b(\(That)35 b(is:)50 b Fh(ln)k(-s)676 2340 y(cudd)e(bdd)p +Fo(.\))p Black 562 2527 a(9.)p Black 46 w(Still)17 b(in)h +Fh(SISDIR/sis)p Fo(,)c(edit)19 b Fh(Makefile)p Fo(,)14 +b Fh(Makefile.oct)p Fo(,)f(and)18 b Fh(Makefile.nooct)p +Fo(.)676 2640 y(In)23 b(all)h(three)g(\002les)f(add)h(mtr)f(to)h(the)g +(list)g(of)f(directories)j(to)e(be)f(made)h(\(DIRS\).)p +Black 517 2828 a(10.)p Black 46 w(In)18 b Fh(SISDIR/sis/inc)o(lu)o(de) +11 b Fo(mak)o(e)18 b Fh(mtr.h)d Fo(a)j(symbolic)h(link)g(to)f +Fh(../mtr/mtr.h)p Fo(.)p Black 517 3015 a(11.)p Black +46 w(In)g Fh(SISDIR/sis/doc)10 b Fo(mak)o(e)19 b Fh(cudd.doc)13 +b Fo(a)18 b(symbolic)i(link)e(to)g Fh(../cudd/cudd.doc)676 +3128 y Fo(and)32 b Fh(mtr.doc)d Fo(a)j(symbolic)h(link)g(to)g +Fh(../mtr/mtr.doc)o Fo(.)48 b(\(That)33 b(is:)46 b Fh(ln)54 +b(-s)676 3241 y(../cudd/cudd.d)o(oc)48 b(.;)53 b(ln)h(-s)g +(../mtr/mtr.doc)48 b(.)p Fo(.\))p Black 517 3429 a(12.)p +Black 46 w(From)25 b Fh(SISDIR)e Fo(do)j Fh(make)53 b(clean)23 +b Fo(follo)n(wed)k(by)f Fh(make)53 b(-i)p Fo(.)35 b(This)26 +b(should)i(cre-)676 3542 y(ate)23 b(a)g(w)o(orking)i(cop)o(y)g(of)e +(SIS)f(that)i(uses)h(the)e(CUDD)f(package.)589 3729 y(The)35 +b(replacement)j(for)d(the)h Fh(st)d Fo(library)k(is)e(because)i(the)e +(v)o(ersion)i(shipped)g(with)e(the)448 3842 y(CUDD)22 +b(package)27 b(tests)e(for)f(out-of-memory)j(conditions.)35 +b(Notice)24 b(that)h(the)g(v)o(ersion)h(of)e(the)448 +3955 y Fh(st)32 b Fo(library)k(to)e(be)f(used)i(for)f(replacement)j(is) +c(not)h(the)h(one)f(used)h(for)f(the)g(normal)g(b)n(uild,)448 +4068 y(because)26 b(the)e(latter)g(has)g(been)h(modi\002ed)f(for)g(C++) +f(compatibility)-6 b(.)32 b(The)23 b(abo)o(v)o(e)h(installation)448 +4181 y(procedure)34 b(has)e(been)h(tested)f(on)g(SIS)e(1.3.)52 +b(SIS)30 b(can)i(be)g(obtained)h(via)f(anon)o(ymous)h(FTP)448 +4294 y(from)18 b Fh(ic.eecs.berkele)o(y.e)o(du)o Fo(.)i(T)-7 +b(o)17 b(b)n(uild)j(SIS)c(1.3,)j(you)g(need)g Fh(sis-1.2.tar.Z)448 +4407 y Fo(and)g Fh(sis-1.2.patch1.Z)o Fo(.)12 b(When)19 +b(compiling)h(on)f(a)f(DEC)f(Alpha,)i(you)h(should)g(add)f(the)448 +4520 y Fh(-ieee)p 728 4520 V 31 w(with)p 979 4520 V 31 +w(no)p 1120 4520 V 31 w(inexact)e Fo(\003ag.)27 b(\(See)20 +b(Section)h(3.5.2.\))28 b(Refer)20 b(to)g(the)h Fh(Makefile)15 +b Fo(in)448 4633 y(the)24 b(top)g(le)n(v)o(el)g(directory)i(of)d(the)h +(distrib)n(ution)j(for)d(ho)n(w)f(to)g(compile)i(with)e(32-bit)i +(pointers.)p Black 1897 5225 a(23)p Black eop end +%%Page: 24 24 +TeXDict begin 24 23 bop Black Black 448 573 a Fi(3.19)99 +b(Writing)25 b(Decision)f(Diagrams)g(to)h(a)g(File)448 +747 y Fo(The)c(CUDD)e(package)k(pro)o(vides)g(se)n(v)o(eral)f +(functions)i(to)d(write)g(decision)j(diagrams)e(to)f(a)g(\002le.)448 +860 y Fn(Cudd)p 649 860 28 4 v 34 w(DumpBlif)35 b Fo(writes)23 +b(a)f(\002le)g(in)g Fn(blif)37 b Fo(format.)28 b(It)23 +b(is)f(restricted)j(to)d(BDDs.)27 b(The)22 b(diagrams)448 +973 y(are)j(written)g(as)f(a)g(netw)o(ork)i(of)e(multiple)o(x)o(ers,)i +(one)f(multiple)o(x)o(er)h(for)f(each)g(internal)h(node)f(of)448 +1086 y(the)f(BDD.)589 1199 y Fn(Cudd)p 790 1199 V 34 +w(DumpDot)37 b Fo(produces)i(input)e(suitable)h(to)e(the)g(graph-dra)o +(wing)j(program)e Fn(dot)3399 1166 y Fg(4)448 1312 y +Fo(written)29 b(by)g(Eleftherios)h(K)m(outso\002os)g(and)f(Stephen)g +(C.)e(North.)43 b(An)28 b(e)o(xample)h(of)g(dra)o(wing)448 +1425 y(produced)f(by)d(dot)g(from)g(the)g(output)h(of)f +Fn(Cudd)p 1959 1425 V 34 w(DumpDot)h Fo(is)e(sho)n(wn)i(in)e(Figure)i +(1.)32 b(It)25 b(is)f(re-)448 1537 y(stricted)j(to)d(BDDs)f(and)h +(ADDs.)30 b Fn(Cudd)p 1726 1537 V 34 w(zddDumpDot)d Fo(is)d(the)h +(analog)h(of)e Fn(Cudd)p 3050 1537 V 34 w(DumpDot)448 +1650 y Fo(for)g(ZDDs.)589 1763 y Fn(Cudd)p 790 1763 V +34 w(DumpDaV)-7 b(inci)41 b Fo(produces)i(input)f(suitable)g(to)f(the)g +(graph-dra)o(wing)i(program)448 1876 y Fn(daV)-7 b(inci)722 +1843 y Fg(5)799 1876 y Fo(de)n(v)o(eloped)40 b(at)d(the)i(Uni)n(v)o +(ersity)g(of)f(Bremen.)71 b(It)38 b(is)f(restricted)k(to)d(BDDs)e(and) +448 1989 y(ADDs.)589 2102 y(Functions)f(are)d(also)h(a)n(v)n(ailable)h +(to)f(produce)h(the)e(input)i(format)f(of)f Fn(DDcal)g +Fo(\(see)h(Sec-)448 2215 y(tion)24 b(2.2\))g(and)g(f)o(actored)i +(forms.)448 2464 y Fi(3.20)99 b(Sa)n(ving)25 b(and)g(Restoring)g(BDDs) +448 2638 y Fo(The)e Fn(dddmp)858 2605 y Fg(6)919 2638 +y Fo(library)i(by)e(Gianpiero)i(Cabodi)f(and)g(Stef)o(ano)g(Quer)f +(allo)n(ws)g(a)g(CUDD)e(appli-)448 2751 y(cation)30 b(to)e(sa)n(v)o(e)h +(BDDs)d(to)j(disk)g(in)f(compact)h(form)f(for)h(later)g(retrie)n(v)n +(al.)44 b(See)28 b(the)g(library')-5 b(s)448 2864 y(o)n(wn)23 +b(documentation)k(for)d(the)g(details.)448 3157 y Fq(4)120 +b(Pr)n(ogrammer')l(s)27 b(Manual)448 3364 y Fo(This)g(section)i(pro)o +(vides)g(additional)h(detail)e(on)f(the)g(w)o(orking)i(of)e(the)g(CUDD) +e(package)k(and)448 3477 y(on)37 b(the)g(programming)h(con)l(v)o +(entions)i(follo)n(wed)e(in)e(its)h(writing.)68 b(The)36 +b(additional)j(detail)448 3590 y(should)21 b(help)f(those)h(who)e(w)o +(ant)g(to)h(write)f(procedures)j(that)e(directly)h(manipulate)h(the)e +(CUDD)448 3703 y(data)k(structures.)448 3952 y Fi(4.1)99 +b(Compiling)25 b(and)g(Linking)448 4126 y Fo(If)32 b(you)h(plan)h(to)e +(use)h(the)f(CUDD)f(package)j(as)e(a)g(clear)i(box)f(\(for)f(instance,) +37 b(you)c(w)o(ant)f(to)448 4239 y(write)24 b(a)f(procedure)j(that)e +(tra)n(v)o(erses)i(a)d(decision)j(diagram\))f(you)f(need)g(to)f(add)p +Black Black 448 4427 a Fh(#include)51 b("cuddInt.h")p +Black 448 4491 1196 4 v 554 4546 a Ff(4)583 4578 y Fe(http://www)-5 +b(.research.att.com/sw/tools/graphviz)554 4640 y Ff(5)583 +4671 y Fe(ftp://ftp.uni-bremen.de/pub/graphics/daV)l(inci)554 +4733 y Ff(6)583 4764 y Fe(ftp://ftp.polito.it/pub/research/dddmp/)p +Black Black 1897 5225 a Fo(24)p Black eop end +%%Page: 25 25 +TeXDict begin 25 24 bop Black Black Black 721 4226 a +@beginspecial 66 @llx 36 @lly 547 @urx 757 @ury 4393 +@rhi @setspecial +%%BeginDocument: phase.ps +%!PS-Adobe-2.0 +%%Creator: dot version 95 (4-10-95) +%%For: (fabio) Fabio Somenzi,OT4-11,2-3466,ECE faculty +%%Title: DD +%%Pages: (atend) +%%BoundingBox: 66 36 547 757 +%%EndComments +%%BeginProlog +save +/DotDict 200 dict def +DotDict begin + +%%BeginResource: procset +/coord-font-family /Times-Roman def +/default-font-family /Times-Roman def +/coordfont coord-font-family findfont 8 scalefont def + +/InvScaleFactor 1.0 def +/set_scale { + dup 1 exch div /InvScaleFactor exch def + dup scale +} bind def + +% styles +/solid { } bind def +/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def +/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def +/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def +/bold { 2 setlinewidth } bind def +/filled { } bind def +/unfilled { } bind def +/rounded { } bind def +/diagonals { } bind def + +% hooks for setting color +/nodecolor { sethsbcolor } bind def +/edgecolor { sethsbcolor } bind def +/graphcolor { sethsbcolor } bind def +/nopcolor {pop pop pop} bind def + +/beginpage { % i j npages + /npages exch def + /j exch def + /i exch def + /str 10 string def + npages 1 gt { + gsave + coordfont setfont + 0 0 moveto + (() show i str cvs show (,) show j str cvs show ()) show + grestore + } if +} bind def + +/set_font { + findfont exch + scalefont setfont +} def + +/arrowhead { + /arrowwidth exch def + /arrowlength exch def + gsave + 3 1 roll + translate + rotate + newpath + arrowlength arrowwidth 2 div moveto + 0 0 lineto + arrowlength arrowwidth -2 div lineto + closepath fill + stroke + grestore +} def + +% draw aligned label in bounding box aligned to current point +% alignfactor tells what fraction to place on the left. +% -.5 is centered. +/alignedtext { % text labelwidth fontsz alignfactor + /alignfactor exch def + /fontsz exch def + /width exch def + /text exch def + gsave + % even if node or edge is dashed, don't paint text with dashes + [] 0 setdash + currentpoint newpath moveto + text stringwidth pop + alignfactor mul fontsz -.3 mul rmoveto + text show + grestore +} def + +/boxprim { % xcorner ycorner xsize ysize + 4 2 roll + moveto + 2 copy + exch 0 rlineto + 0 exch rlineto + pop neg 0 rlineto + closepath +} bind def + +/ellipse_path { + /ry exch def + /rx exch def + /y exch def + /x exch def + matrix currentmatrix + newpath + x y translate + rx ry scale + 0 0 1 0 360 arc + setmatrix +} bind def + +/endpage { showpage } bind def + +/layercolorseq + [ % layer color sequence - darkest to lightest + [0 0 0] + [.2 .8 .8] + [.4 .8 .8] + [.6 .8 .8] + [.8 .8 .8] + ] +def + +/setlayer {/maxlayer exch def /curlayer exch def + layercolorseq curlayer get + aload pop sethsbcolor + /nodecolor {nopcolor} def + /edgecolor {nopcolor} def + /graphcolor {nopcolor} def +} bind def + +/onlayer { curlayer ne {invis} if } def + +/onlayers { + /myupper exch def + /mylower exch def + curlayer mylower lt + curlayer myupper gt + or + {invis} if +} def + +/curlayer 0 def + +%%EndResource +%%EndProlog +%%BeginSetup +14 default-font-family set_font +% /arrowlength 10 def +% /arrowwidth 5 def +%%EndSetup +%%Page: 1 (atend) +%%PageBoundingBox: 66 36 547 757 +gsave +65 35 482 722 boxprim clip newpath +66 36 translate +0 0 1 beginpage +0.7407 set_scale +0 0 translate 0 rotate +0.000 0.000 0.000 graphcolor +14.00 /Times-Roman set_font + +% CONST NODES +gsave 10 dict begin +invis +gsave 10 dict begin +55 19 moveto (CONST NODES) 96 14.00 -0.50 alignedtext +end grestore +end grestore + +% a110 +gsave 10 dict begin +gsave 10 dict begin +55 883 moveto (a110) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a111 +gsave 10 dict begin +gsave 10 dict begin +55 811 moveto (a111) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a110 -> a111 +gsave 10 dict begin +invis +newpath 55 864 moveto +55 853 55 839 55 828 curveto +stroke +end grestore + +% a210 +gsave 10 dict begin +gsave 10 dict begin +55 739 moveto (a210) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a111 -> a210 +gsave 10 dict begin +invis +newpath 55 792 moveto +55 781 55 767 55 756 curveto +stroke +end grestore + +% a211 +gsave 10 dict begin +gsave 10 dict begin +55 667 moveto (a211) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a210 -> a211 +gsave 10 dict begin +invis +newpath 55 720 moveto +55 709 55 695 55 684 curveto +stroke +end grestore + +% a310 +gsave 10 dict begin +gsave 10 dict begin +55 595 moveto (a310) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a211 -> a310 +gsave 10 dict begin +invis +newpath 55 648 moveto +55 637 55 623 55 612 curveto +stroke +end grestore + +% a311 +gsave 10 dict begin +gsave 10 dict begin +55 523 moveto (a311) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a310 -> a311 +gsave 10 dict begin +invis +newpath 55 576 moveto +55 565 55 551 55 540 curveto +stroke +end grestore + +% a410 +gsave 10 dict begin +gsave 10 dict begin +55 451 moveto (a410) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a311 -> a410 +gsave 10 dict begin +invis +newpath 55 504 moveto +55 493 55 479 55 468 curveto +stroke +end grestore + +% a411 +gsave 10 dict begin +gsave 10 dict begin +55 379 moveto (a411) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a410 -> a411 +gsave 10 dict begin +invis +newpath 55 432 moveto +55 421 55 407 55 396 curveto +stroke +end grestore + +% a510 +gsave 10 dict begin +gsave 10 dict begin +55 307 moveto (a510) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a411 -> a510 +gsave 10 dict begin +invis +newpath 55 360 moveto +55 349 55 335 55 324 curveto +stroke +end grestore + +% a511 +gsave 10 dict begin +gsave 10 dict begin +55 235 moveto (a511) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a510 -> a511 +gsave 10 dict begin +invis +newpath 55 288 moveto +55 277 55 263 55 252 curveto +stroke +end grestore + +% a610 +gsave 10 dict begin +gsave 10 dict begin +55 163 moveto (a610) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a511 -> a610 +gsave 10 dict begin +invis +newpath 55 216 moveto +55 205 55 191 55 180 curveto +stroke +end grestore + +% a611 +gsave 10 dict begin +gsave 10 dict begin +55 91 moveto (a611) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a610 -> a611 +gsave 10 dict begin +invis +newpath 55 144 moveto +55 133 55 119 55 108 curveto +stroke +end grestore + +% a611 -> CONST NODES +gsave 10 dict begin +invis +newpath 55 72 moveto +55 61 55 47 55 36 curveto +stroke +end grestore + +% o +gsave 10 dict begin +newpath 511 972 moveto +457 972 lineto +457 936 lineto +511 936 lineto +closepath +stroke +gsave 10 dict begin +484 955 moveto (o) 7 14.00 -0.50 alignedtext +end grestore +end grestore + +% a00 +gsave 10 dict begin +484 882 27 18 ellipse_path +stroke +gsave 10 dict begin +484 883 moveto (a00) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% o -> a00 +gsave 10 dict begin +solid +newpath 484 936 moveto +484 925 484 911 484 900 curveto +stroke +end grestore + +% 9fc +gsave 10 dict begin +448 810 27 18 ellipse_path +stroke +gsave 10 dict begin +448 811 moveto (9fc) 17 14.00 -0.50 alignedtext +end grestore +end grestore + +% a00 -> 9fc +newpath 475 865 moveto +470 853 462 839 457 827 curveto +stroke + +% 9ff +gsave 10 dict begin +520 810 27 18 ellipse_path +stroke +gsave 10 dict begin +520 811 moveto (9ff) 16 14.00 -0.50 alignedtext +end grestore +end grestore + +% a00 -> 9ff +gsave 10 dict begin +dashed +newpath 493 865 moveto +498 853 506 839 511 827 curveto +stroke +end grestore + +% 995 +gsave 10 dict begin +453 738 27 18 ellipse_path +stroke +gsave 10 dict begin +453 739 moveto (995) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fc -> 995 +gsave 10 dict begin +dashed +newpath 449 792 moveto +450 781 451 767 452 756 curveto +stroke +end grestore + +% 9fb +gsave 10 dict begin +381 738 27 18 ellipse_path +stroke +gsave 10 dict begin +381 739 moveto (9fb) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fc -> 9fb +newpath 433 794 moveto +422 782 407 765 396 753 curveto +stroke + +% 9fe +gsave 10 dict begin +584 738 27 18 ellipse_path +stroke +gsave 10 dict begin +584 739 moveto (9fe) 17 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ff -> 9fe +gsave 10 dict begin +dashed +newpath 534 794 moveto +545 782 560 765 570 753 curveto +stroke +end grestore + +% 95f +gsave 10 dict begin +512 666 27 18 ellipse_path +stroke +gsave 10 dict begin +512 667 moveto (95f) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ff -> 95f +newpath 519 792 moveto +518 764 515 712 513 684 curveto +stroke + +% 994 +gsave 10 dict begin +347 594 27 18 ellipse_path +stroke +gsave 10 dict begin +347 595 moveto (994) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 995 -> 994 +newpath 432 727 moveto +407 714 370 693 363 684 curveto +356 675 351 636 349 612 curveto +stroke + +% 946 +gsave 10 dict begin +newpath 401 36 moveto +347 36 lineto +347 0 lineto +401 0 lineto +closepath +stroke +gsave 10 dict begin +374 19 moveto (1) 7 14.00 -0.50 alignedtext +end grestore +end grestore + +% 995 -> 946 +gsave 10 dict begin +dotted +newpath 584 594 moveto +589 570 587 545 584 522 curveto +stroke +newpath 453 720 moveto +454 698 458 662 473 648 curveto +498 621 544 628 577 612 curveto +582 609 582 600 584 594 curveto +stroke +end grestore + +% 9f7 +gsave 10 dict begin +292 666 27 18 ellipse_path +stroke +gsave 10 dict begin +292 667 moveto (9f7) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fb -> 9f7 +newpath 363 724 moveto +347 711 325 693 309 680 curveto +stroke + +% 9fa +gsave 10 dict begin +402 666 27 18 ellipse_path +stroke +gsave 10 dict begin +402 667 moveto (9fa) 17 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fb -> 9fa +gsave 10 dict begin +dashed +newpath 386 720 moveto +389 709 393 695 397 684 curveto +stroke +end grestore + +% 9fd +gsave 10 dict begin +584 666 27 18 ellipse_path +stroke +gsave 10 dict begin +584 667 moveto (9fd) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fe -> 9fd +newpath 584 720 moveto +584 709 584 695 584 684 curveto +stroke + +% 9fe -> 946 +gsave 10 dict begin +dotted +newpath 600 723 moveto +611 711 625 696 632 684 curveto +637 673 637 658 632 648 curveto +632 648 584 594 584 594 curveto +stroke +end grestore + +% 9f7 -> 994 +gsave 10 dict begin +dashed +newpath 304 650 moveto +313 638 326 622 335 610 curveto +stroke +end grestore + +% 9f6 +gsave 10 dict begin +275 594 27 18 ellipse_path +stroke +gsave 10 dict begin +275 595 moveto (9f6) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f7 -> 9f6 +newpath 288 648 moveto +285 637 282 623 279 612 curveto +stroke + +% 9f9 +gsave 10 dict begin +529 594 27 18 ellipse_path +stroke +gsave 10 dict begin +529 595 moveto (9f9) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fa -> 9f9 +gsave 10 dict begin +dashed +newpath 423 654 moveto +447 641 485 619 508 606 curveto +stroke +end grestore + +% 95e +gsave 10 dict begin +457 522 27 18 ellipse_path +stroke +gsave 10 dict begin +457 523 moveto (95e) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fa -> 95e +newpath 465 594 moveto +464 579 462 556 460 540 curveto +stroke +newpath 420 652 moveto +439 638 464 614 465 594 curveto +stroke + +% 95f -> 95e +newpath 497 651 moveto +483 636 464 612 465 594 curveto +stroke + +% 95f -> 946 +gsave 10 dict begin +dotted +newpath 531 653 moveto +551 639 579 615 584 594 curveto +stroke +end grestore + +% 9fd -> 9f9 +newpath 572 650 moveto +563 638 550 622 541 610 curveto +stroke + +% 9fd -> 946 +gsave 10 dict begin +dotted +newpath 582 648 moveto +581 631 580 608 584 594 curveto +stroke +end grestore + +% 993 +gsave 10 dict begin +292 450 27 18 ellipse_path +stroke +gsave 10 dict begin +292 451 moveto (993) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 994 -> 993 +newpath 333 578 moveto +323 566 312 551 308 540 curveto +301 521 296 489 294 468 curveto +stroke + +% 994 -> 946 +gsave 10 dict begin +dotted +newpath 357 577 moveto +371 556 396 519 418 504 curveto +447 482 489 484 522 468 curveto +527 465 527 456 529 450 curveto +stroke +newpath 529 450 moveto +534 426 532 401 529 378 curveto +stroke +end grestore + +% 9f5 +gsave 10 dict begin +347 522 27 18 ellipse_path +stroke +gsave 10 dict begin +347 523 moveto (9f5) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f6 -> 9f5 +gsave 10 dict begin +dashed +newpath 290 579 moveto +302 567 319 550 332 537 curveto +stroke +end grestore + +% 9f2 +gsave 10 dict begin +237 522 27 18 ellipse_path +stroke +gsave 10 dict begin +237 523 moveto (9f2) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f6 -> 9f2 +newpath 266 577 moveto +260 566 252 551 246 539 curveto +stroke + +% 9f8 +gsave 10 dict begin +529 522 27 18 ellipse_path +stroke +gsave 10 dict begin +529 523 moveto (9f8) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f9 -> 9f8 +newpath 529 576 moveto +529 565 529 551 529 540 curveto +stroke + +% 9f9 -> 946 +gsave 10 dict begin +dotted +newpath 546 580 moveto +563 565 587 541 584 522 curveto +stroke +newpath 584 522 moveto +579 492 522 479 529 450 curveto +stroke +end grestore + +% 9f4 +gsave 10 dict begin +474 450 27 18 ellipse_path +stroke +gsave 10 dict begin +474 451 moveto (9f4) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f5 -> 9f4 +gsave 10 dict begin +dashed +newpath 368 510 moveto +392 497 430 475 453 462 curveto +stroke +end grestore + +% 95d +gsave 10 dict begin +402 378 27 18 ellipse_path +stroke +gsave 10 dict begin +402 379 moveto (95d) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f5 -> 95d +newpath 365 508 moveto +384 494 409 470 410 450 curveto +stroke +newpath 410 450 moveto +409 435 407 412 405 396 curveto +stroke + +% 9f2 -> 993 +gsave 10 dict begin +dashed +newpath 249 506 moveto +258 494 271 478 280 466 curveto +stroke +end grestore + +% 9f1 +gsave 10 dict begin +220 450 27 18 ellipse_path +stroke +gsave 10 dict begin +220 451 moveto (9f1) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f2 -> 9f1 +newpath 233 504 moveto +230 493 227 479 224 468 curveto +stroke + +% 95e -> 95d +newpath 442 507 moveto +428 492 409 468 410 450 curveto +stroke + +% 95e -> 946 +gsave 10 dict begin +dotted +newpath 476 509 moveto +496 495 524 471 529 450 curveto +stroke +end grestore + +% 9f8 -> 9f4 +newpath 517 506 moveto +508 494 495 478 486 466 curveto +stroke + +% 9f8 -> 946 +gsave 10 dict begin +dotted +newpath 527 504 moveto +526 487 525 464 529 450 curveto +stroke +end grestore + +% 992 +gsave 10 dict begin +237 306 27 18 ellipse_path +stroke +gsave 10 dict begin +237 307 moveto (992) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 993 -> 992 +newpath 278 434 moveto +268 422 257 407 253 396 curveto +246 377 241 345 239 324 curveto +stroke + +% 993 -> 946 +gsave 10 dict begin +dotted +newpath 474 306 moveto +474 306 474 234 474 234 curveto +stroke +newpath 302 433 moveto +316 412 341 375 363 360 curveto +392 338 434 340 467 324 curveto +472 321 472 312 474 306 curveto +stroke +end grestore + +% 9ed +gsave 10 dict begin +182 378 27 18 ellipse_path +stroke +gsave 10 dict begin +182 379 moveto (9ed) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f1 -> 9ed +newpath 211 433 moveto +205 422 197 407 191 395 curveto +stroke + +% 9f0 +gsave 10 dict begin +292 378 27 18 ellipse_path +stroke +gsave 10 dict begin +292 379 moveto (9f0) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f1 -> 9f0 +gsave 10 dict begin +dashed +newpath 235 435 moveto +247 423 264 406 277 393 curveto +stroke +end grestore + +% 9f3 +gsave 10 dict begin +474 378 27 18 ellipse_path +stroke +gsave 10 dict begin +474 379 moveto (9f3) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f4 -> 9f3 +newpath 474 432 moveto +474 421 474 407 474 396 curveto +stroke + +% 9f4 -> 946 +gsave 10 dict begin +dotted +newpath 491 436 moveto +508 421 532 397 529 378 curveto +stroke +newpath 529 378 moveto +528 371 525 365 522 360 curveto +522 360 474 306 474 306 curveto +stroke +end grestore + +% 9ed -> 992 +gsave 10 dict begin +dashed +newpath 194 362 moveto +203 350 216 334 225 322 curveto +stroke +end grestore + +% 9ec +gsave 10 dict begin +165 306 27 18 ellipse_path +stroke +gsave 10 dict begin +165 307 moveto (9ec) 19 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ed -> 9ec +newpath 178 360 moveto +175 349 172 335 169 324 curveto +stroke + +% 9ef +gsave 10 dict begin +419 306 27 18 ellipse_path +stroke +gsave 10 dict begin +419 307 moveto (9ef) 17 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f0 -> 9ef +gsave 10 dict begin +dashed +newpath 313 366 moveto +337 353 375 331 398 318 curveto +stroke +end grestore + +% 95c +gsave 10 dict begin +347 234 27 18 ellipse_path +stroke +gsave 10 dict begin +347 235 moveto (95c) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f0 -> 95c +newpath 310 364 moveto +329 350 354 326 355 306 curveto +stroke +newpath 355 306 moveto +354 291 352 268 350 252 curveto +stroke + +% 95d -> 95c +newpath 387 363 moveto +373 348 354 324 355 306 curveto +stroke + +% 95d -> 946 +gsave 10 dict begin +dotted +newpath 421 365 moveto +441 351 469 327 474 306 curveto +stroke +end grestore + +% 9f3 -> 9ef +newpath 462 362 moveto +453 350 440 334 431 322 curveto +stroke + +% 9f3 -> 946 +gsave 10 dict begin +dotted +newpath 472 360 moveto +471 343 470 320 474 306 curveto +stroke +end grestore + +% 954 +gsave 10 dict begin +165 162 27 18 ellipse_path +stroke +gsave 10 dict begin +165 163 moveto (954) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 992 -> 954 +newpath 220 234 moveto +214 216 194 192 180 177 curveto +stroke +newpath 233 288 moveto +230 272 224 248 220 234 curveto +stroke + +% 992 -> 946 +gsave 10 dict begin +dotted +newpath 220 234 moveto +220 234 213 144 213 144 curveto +213 144 193 90 193 90 curveto +stroke +end grestore + +% 987 +gsave 10 dict begin +165 234 27 18 ellipse_path +stroke +gsave 10 dict begin +165 235 moveto (987) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ec -> 987 +newpath 165 288 moveto +165 277 165 263 165 252 curveto +stroke + +% 9eb +gsave 10 dict begin +275 234 27 18 ellipse_path +stroke +gsave 10 dict begin +275 235 moveto (9eb) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ec -> 9eb +gsave 10 dict begin +dashed +newpath 184 293 moveto +204 280 236 260 256 247 curveto +stroke +end grestore + +% 9ee +gsave 10 dict begin +419 234 27 18 ellipse_path +stroke +gsave 10 dict begin +419 235 moveto (9ee) 19 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ef -> 9ee +newpath 419 288 moveto +419 277 419 263 419 252 curveto +stroke + +% 9ef -> 946 +gsave 10 dict begin +dotted +newpath 474 234 moveto +477 210 461 184 469 162 curveto +stroke +newpath 435 291 moveto +450 276 471 252 474 234 curveto +stroke +end grestore + +% 987 -> 954 +gsave 10 dict begin +dashed +newpath 165 216 moveto +165 205 165 191 165 180 curveto +stroke +end grestore + +% 987 -> 946 +newpath 193 90 moveto +225 56 305 34 347 24 curveto +stroke +newpath 152 218 moveto +136 197 113 162 126 144 curveto +144 120 173 110 193 90 curveto +stroke + +% 9ea +gsave 10 dict begin +410 162 27 18 ellipse_path +stroke +gsave 10 dict begin +410 163 moveto (9ea) 19 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9eb -> 9ea +gsave 10 dict begin +dashed +newpath 296 223 moveto +321 210 363 187 389 174 curveto +stroke +end grestore + +% 955 +gsave 10 dict begin +374 90 27 18 ellipse_path +stroke +gsave 10 dict begin +374 91 moveto (955) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9eb -> 955 +newpath 293 220 moveto +311 206 338 182 347 162 curveto +stroke +newpath 347 162 moveto +353 147 362 124 368 108 curveto +stroke + +% 95c -> 955 +newpath 344 216 moveto +342 199 341 175 347 162 curveto +stroke + +% 95c -> 946 +gsave 10 dict begin +dotted +newpath 368 222 moveto +372 220 376 217 380 216 curveto +407 203 436 195 462 180 curveto +467 176 466 168 469 162 curveto +stroke +newpath 469 162 moveto +476 139 475 113 469 90 curveto +stroke +end grestore + +% 9ee -> 9ea +newpath 417 216 moveto +415 205 414 191 412 180 curveto +stroke + +% 9ee -> 946 +gsave 10 dict begin +dotted +newpath 432 218 moveto +442 206 454 190 462 180 curveto +465 174 466 168 469 162 curveto +stroke +end grestore + +% 954 -> 946 +newpath 169 144 moveto +174 127 182 101 193 90 curveto +stroke + +% 954 -> 946 +gsave 10 dict begin +dotted +end grestore + +% 9ea -> 955 +newpath 401 145 moveto +396 133 388 119 383 107 curveto +stroke + +% 9ea -> 946 +gsave 10 dict begin +dotted +newpath 429 149 moveto +448 133 474 109 469 90 curveto +stroke +newpath 469 90 moveto +462 66 427 44 401 30 curveto +stroke +end grestore + +% 955 -> 946 +newpath 374 72 moveto +374 61 374 47 374 36 curveto +stroke + +% 955 -> 946 +gsave 10 dict begin +dotted +end grestore +endpage +grestore +%%PageTrailer +%%Trailer +%%Pages: 1 +end +restore +%%EOF + +%%EndDocument + @endspecial 448 4422 a Fo(Figure)34 b(1:)49 b(A)32 b(BDD)f +(representing)37 b(a)c(phase)h(constraint)i(for)e(the)f(optimization)j +(of)d(\002x)o(ed-)448 4535 y(polarity)27 b(Reed-Muller)g(forms.)33 +b(The)24 b(label)i(of)f(each)h(node)f(is)g(the)g(unique)i(part)e(of)g +(the)g(node)448 4648 y(address.)31 b(All)21 b(nodes)j(on)f(the)g(same)f +(le)n(v)o(el)h(correspond)i(to)e(the)g(same)f(v)n(ariable,)i(whose)f +(name)448 4761 y(is)f(sho)n(wn)h(at)f(the)g(left)g(of)g(the)h(diagram.) +29 b(Dotted)23 b(lines)g(indicate)h(complement)g(arcs.)k(Dashed)448 +4874 y(lines)d(indicate)g(re)o(gular)g(\223else\224)g(arcs.)p +Black Black 1897 5225 a(25)p Black eop end +%%Page: 26 26 +TeXDict begin 26 25 bop Black Black 448 573 a Fo(to)24 +b(your)h(source)h(\002les.)k(In)24 b(addition,)i(you)f(should)h(link)e +Fh(libcudd.a)19 b Fo(to)24 b(your)h(e)o(x)o(ecutable.)448 +686 y(Some)20 b(platforms)h(require)h(speci\002c)e(compiler)i(and)e +(link)o(er)h(\003ags.)28 b(Refer)20 b(to)g(the)g Fh(Makefile)448 +799 y Fo(in)k(the)g(top)f(le)n(v)o(el)h(directory)i(of)e(the)f(distrib) +n(ution.)448 1040 y Fi(4.2)99 b(Refer)n(ence)27 b(Counts)448 +1214 y Fo(Garbage)d(collection)i(in)d(the)g(CUDD)d(package)25 +b(is)e(based)h(on)f(reference)i(counts.)30 b(Each)22 +b(node)448 1327 y(stores)j(the)f(sum)f(of)g(the)h(e)o(xternal)h +(references)h(and)e(internal)h(references.)31 b(An)23 +b(internal)i(BDD)448 1440 y(or)33 b(ADD)e(node)i(is)g(created)h(by)f(a) +g(call)g(to)f Fn(cuddUniqueInter)r Fo(,)40 b(an)32 b(internal)j(ZDD)c +(node)i(is)448 1553 y(created)c(by)e(a)g(call)g(to)g +Fn(cuddUniqueInterZdd)r Fo(,)33 b(and)28 b(a)e(terminal)j(node)e(is)g +(created)i(by)e(a)g(call)448 1666 y(to)g Fn(cuddUniqueConst)r +Fo(.)40 b(If)27 b(the)f(node)i(returned)g(by)f(these)g(functions)i(is)d +(ne)n(w)-6 b(,)27 b(its)f(reference)448 1779 y(count)32 +b(is)e(zero.)51 b(The)30 b(function)i(that)g(calls)f +Fn(cuddUniqueInter)r Fo(,)36 b Fn(cuddUniqueInterZdd)r +Fo(,)h(or)448 1892 y Fn(cuddUniqueConst)j Fo(is)35 b(responsible)j(for) +d(increasing)i(the)e(reference)i(count)f(of)f(the)g(node.)448 +2005 y(This)24 b(is)f(accomplished)k(by)c(calling)i Fn(Cudd)p +1823 2005 28 4 v 34 w(Ref)13 b Fo(.)589 2118 y(When)22 +b(a)f(function)i(is)e(no)g(longer)i(needed)f(by)g(an)f(application,)j +(the)e(memory)f(used)h(by)f(its)448 2231 y(diagram)32 +b(can)g(be)f(rec)o(ycled)i(by)e(calling)i Fn(Cudd)p 1986 +2231 V 33 w(Recur)o(siveDer)m(ef)47 b Fo(\(BDDs)30 b(and)i(ADDs\))d(or) +448 2344 y Fn(Cudd)p 649 2344 V 34 w(Recur)o(siveDer)m(efZdd)36 +b Fo(\(ZDDs\).)49 b(These)31 b(functions)i(decrease)g(the)e(reference)i +(count)448 2456 y(of)h(the)h(node)g(passed)g(to)f(them.)61 +b(If)34 b(the)g(reference)i(count)g(becomes)f(0,)h(then)f(tw)o(o)f +(things)448 2569 y(happen:)p Black 562 2718 a(1.)p Black +46 w(The)23 b(node)i(is)f(declared)i(\223dead;\224)g(this)e(entails)h +(increasing)i(the)d(counters)i(of)e(the)g(dead)676 2831 +y(nodes.)56 b(\(One)32 b(counter)i(for)f(the)f(subtable)j(to)d(which)h +(the)g(node)g(belongs,)j(and)d(one)676 2944 y(global)f(counter)h(for)f +(the)f(unique)i(table)f(to)f(which)h(the)f(node)i(belongs.\))54 +b(The)30 b(node)676 3057 y(itself)24 b(is)f(not)h(af)n(fected.)p +Black 562 3229 a(2.)p Black 46 w(The)f(function)i(is)f(recursi)n(v)o +(ely)i(called)f(on)e(the)h(tw)o(o)f(children)j(of)d(the)h(node.)448 +3378 y(F)o(or)35 b(instance,)41 b(if)36 b(the)g(diagram)h(of)f(a)f +(function)j(does)f(not)f(share)h(an)o(y)f(nodes)i(with)d(other)448 +3491 y(diagrams,)k(then)c(calling)h Fn(Cudd)p 1513 3491 +V 33 w(Recur)o(siveDer)m(ef)50 b Fo(or)34 b Fn(Cudd)p +2459 3491 V 34 w(Recur)o(siveDer)m(efZdd)40 b Fo(on)34 +b(its)448 3603 y(root)24 b(will)g(cause)g(all)g(the)g(nodes)h(of)e(the) +h(diagram)g(to)g(become)g(dead.)589 3716 y(When)d(the)f(number)g(of)g +(dead)h(nodes)g(reaches)g(a)f(gi)n(v)o(en)g(le)n(v)o(el)g +(\(dynamically)j(determined)448 3829 y(by)33 b(the)f(package\))j +(garbage)e(collection)i(tak)o(es)f(place.)56 b(During)33 +b(garbage)g(collection)i(dead)448 3942 y(nodes)25 b(are)f(returned)h +(to)f(the)g(node)g(free)g(list.)589 4055 y(When)37 b(a)e(ne)n(w)g(node) +i(is)f(created,)k(it)c(is)g(important)h(to)f(increase)i(its)e +(reference)i(count)448 4168 y(before)25 b(one)f(of)g(the)f(tw)o(o)h +(follo)n(wing)h(e)n(v)o(ents)f(occurs:)p Black 562 4317 +a(1.)p Black 46 w(A)19 b(call)j(to)e Fn(cuddUniqueInter)r +Fo(,)26 b(to)21 b Fn(cuddUniqueInterZdd)r Fo(,)26 b(to)21 +b Fn(cuddUniqueConst)r Fo(,)j(or)676 4430 y(to)f(a)g(function)j(that)e +(may)f(e)n(v)o(entually)j(cause)f(a)e(call)h(to)f(them.)p +Black 562 4602 a(2.)p Black 46 w(A)28 b(call)i(to)f Fn(Cudd)p +1230 4602 V 34 w(Recur)o(siveDer)m(ef)13 b Fo(,)33 b(to)c +Fn(Cudd)p 2186 4602 V 34 w(Recur)o(siveDer)m(efZdd)r +Fo(,)34 b(or)29 b(to)g(a)g(func-)676 4715 y(tion)24 b(that)g(may)f(e)n +(v)o(entually)j(cause)f(a)e(call)h(to)f(them.)448 4863 +y(In)31 b(practice,)j(it)d(is)f(recommended)j(to)e(increase)i(the)e +(reference)i(count)f(as)f(soon)g(as)g(the)g(re-)448 4976 +y(turned)25 b(pointer)h(has)d(been)i(tested)g(for)e(not)h(being)h +(NULL.)p Black 1897 5225 a(26)p Black eop end +%%Page: 27 27 +TeXDict begin 27 26 bop Black Black 448 573 a Fp(4.2.1)92 +b(NULL)21 b(Retur)o(n)h(V)-8 b(alues)448 747 y Fo(The)25 +b(interf)o(ace)i(to)e(the)g(memory)g(management)i(functions)g(\(e.g.,)e +(malloc\))h(used)g(by)f(CUDD)448 860 y(intercepts)k(NULL)c(return)i(v)n +(alues)h(and)f(calls)g(a)f(handler)-5 b(.)40 b(The)26 +b(def)o(ault)i(handler)g(e)o(xits)f(with)448 973 y(an)i(error)h +(message.)47 b(If)29 b(the)g(application)k(does)d(not)f(install)i +(another)g(handler)l(,)h(therefore,)h(a)448 1086 y(NULL)21 +b(return)k(v)n(alue)g(from)e(an)h(e)o(xported)h(function)h(of)d(CUDD)e +(signals)26 b(an)d(internal)j(error)-5 b(.)589 1199 y(If)23 +b(the)f(aplication,)j(ho)n(we)n(v)o(er)l(,)e(installs)i(another)f +(handler)g(that)f(lets)g(e)o(x)o(ecution)h(continue,)448 +1312 y(a)i(NULL)f(pointer)j(returned)g(by)f(an)g(e)o(xported)h +(function)h(typically)g(indicates)g(that)e(the)g(pro-)448 +1425 y(cess)32 b(has)g(run)g(out)g(of)f(memory)-6 b(.)53 +b Fn(Cudd)p 1760 1425 28 4 v 33 w(ReadErr)l(orCode)34 +b Fo(can)d(be)h(used)g(to)f(ascertain)j(the)448 1537 +y(nature)25 b(of)f(the)f(problem.)589 1650 y(An)37 b(application)j +(that)d(tests)h(for)f(the)h(result)g(being)g(NULL)c(can)k(try)f(some)g +(remedial)448 1763 y(action,)25 b(if)e(it)g(runs)h(out)g(of)g(memory)-6 +b(.)28 b(F)o(or)23 b(instance,)i(it)e(may)h(free)g(some)f(memory)h +(that)g(is)f(not)448 1876 y(strictly)29 b(necessary)-6 +b(,)31 b(or)c(try)g(a)g(slo)n(wer)g(algorithm)i(that)f(tak)o(es)g(less) +g(space.)40 b(As)27 b(an)g(e)o(xample,)448 1989 y(CUDD)e(o)o(v)o +(errides)k(the)f(def)o(ault)h(handler)g(when)f(trying)g(to)g(enlar)n +(ge)h(the)f(cache)g(or)f(increase)448 2102 y(the)i(number)g(of)f(slots) +h(of)f(the)h(unique)h(table.)43 b(If)28 b(the)h(allocation)h(f)o(ails,) +g(the)f(package)h(prints)448 2215 y(out)24 b(a)f(message)i(and)f +(continues)i(without)f(resizing)g(the)f(cache.)448 2461 +y Fp(4.2.2)92 b Fa(Cudd)p 928 2461 V 33 w(Recursiv)o(eDeref)35 +b Fp(vs.)23 b Fa(Cudd)p 1901 2461 V 33 w(Deref)448 2635 +y Fo(It)36 b(is)f(often)i(the)f(case)g(that)h(a)e(recursi)n(v)o(e)i +(procedure)i(has)d(to)g(protect)h(the)f(result)h(it)e(is)h(go-)448 +2748 y(ing)j(to)g(return,)k(while)c(it)f(disposes)j(of)d(intermediate)j +(results.)75 b(\(See)38 b(the)h(pre)n(vious)i(dis-)448 +2861 y(cussion)i(on)d(when)h(to)f(increase)j(reference)g(counts.\))81 +b(Once)41 b(the)g(intermediate)i(results)448 2974 y(ha)n(v)o(e)37 +b(been)f(properly)i(disposed)f(of,)i(the)c(\002nal)h(result)h(must)e +(be)h(returned)h(to)f(its)f(pristine)448 3087 y(state,)h(in)d(which)g +(the)g(root)h(node)g(may)e(ha)n(v)o(e)i(a)e(reference)k(count)e(of)e +(0.)57 b(One)32 b(cannot)j(use)448 3200 y Fn(Cudd)p 649 +3200 V 34 w(Recur)o(siveDer)m(ef)49 b Fo(\(or)33 b Fn(Cudd)p +1624 3200 V 34 w(Recur)o(siveDer)m(efZdd)r Fo(\))j(for)d(this)h +(purpose,)j(because)e(it)448 3313 y(may)22 b(erroneously)j(mak)o(e)d +(some)g(nodes)h(dead.)29 b(Therefore,)24 b(the)e(package)i(pro)o(vides) +g(a)d(dif)n(fer)n(-)448 3425 y(ent)k(function:)35 b Fn(Cudd)p +1144 3425 V 33 w(Der)m(ef)13 b Fo(.)33 b(This)25 b(function)i(is)d(not) +i(recursi)n(v)o(e,)g(and)g(does)f(not)h(change)g(the)448 +3538 y(dead)g(node)f(counts.)34 b(Its)25 b(use)g(is)f(almost)h(e)o +(xclusi)n(v)o(ely)i(the)e(one)g(just)g(described:)34 +b(Decreasing)448 3651 y(the)26 b(reference)h(count)g(of)e(the)g(root)h +(of)f(the)h(\002nal)f(result)h(before)h(returning)h(from)d(a)g(recursi) +n(v)o(e)448 3764 y(procedure.)448 4010 y Fp(4.2.3)92 +b(When)22 b(Incr)n(easing)j(the)e(Refer)n(ence)i(Count)d(is)h +(Unnecessary)448 4184 y Fo(When)29 b(a)f(cop)o(y)h(of)f(a)g +(prede\002ned)i(constant)h(or)d(of)g(a)g(simple)h(BDD)d(v)n(ariable)k +(is)e(needed)i(for)448 4297 y(comparison)g(purposes,)g(then)f(calling)g +Fn(Cudd)p 1931 4297 V 33 w(Ref)40 b Fo(is)27 b(not)h(necessary)-6 +b(,)31 b(because)e(these)f(sim-)448 4410 y(ple)j(functions)i(are)d +(guaranteed)k(to)c(ha)n(v)o(e)h(reference)i(counts)f(greater)g(than)f +(0)f(at)g(all)g(times.)448 4523 y(If)35 b(no)g(call)g(to)f +Fn(Cudd)p 1138 4523 V 34 w(Ref)47 b Fo(is)35 b(made,)i(then)f(no)f +(attempt)g(to)g(free)g(the)g(diagram)h(by)f(calling)448 +4636 y Fn(Cudd)p 649 4636 V 34 w(Recur)o(siveDer)m(ef)k +Fo(or)24 b Fn(Cudd)p 1575 4636 V 33 w(Recur)o(siveDer)m(efZdd)29 +b Fo(should)c(be)f(made.)p Black 1897 5225 a(27)p Black +eop end +%%Page: 28 28 +TeXDict begin 28 27 bop Black Black 448 573 a Fp(4.2.4)92 +b(Saturating)24 b(Incr)n(ements)g(and)f(Decr)n(ements)448 +747 y Fo(On)30 b(32-bit)i(machines,)i(the)d(CUDD)d(package)33 +b(stores)f(the)f(reference)i(counts)f(in)f(unsigned)448 +860 y(short)38 b(int')-5 b(s.)68 b(F)o(or)36 b(lar)n(ge)i(diagrams,)j +(it)36 b(is)g(possible)j(for)e(some)f(reference)j(counts)f(to)e(e)o(x-) +448 973 y(ceed)27 b(the)g(capacity)h(of)f(an)f(unsigned)j(short)e(int.) +38 b(Therefore,)28 b(increments)g(and)f(decrements)448 +1086 y(of)34 b(reference)j(counts)f(are)e Fn(satur)o(ating)p +Fo(.)64 b(This)34 b(means)g(that)h(once)g(a)f(reference)j(count)e(has) +448 1199 y(reached)24 b(the)e(maximum)f(possible)j(v)n(alue,)f(it)e(is) +h(no)g(longer)h(changed)h(by)d(calls)i(to)e Fn(Cudd)p +3264 1199 28 4 v 34 w(Ref)p Fo(,)448 1312 y Fn(Cudd)p +649 1312 V 34 w(Recur)o(siveDer)m(ef)13 b Fo(,)46 b Fn(Cudd)p +1519 1312 V 34 w(Recur)o(siveDer)m(efZdd)r Fo(,)h(or)40 +b Fn(Cudd)p 2635 1312 V 34 w(Der)m(ef)13 b Fo(.)77 b(As)39 +b(a)h(conse-)448 1425 y(quence,)30 b(some)d(nodes)i(that)e(ha)n(v)o(e)h +(no)f(references)j(may)d(not)h(be)f(declared)i(dead.)41 +b(This)27 b(may)448 1537 y(result)j(in)e(a)g(small)h(w)o(aste)f(of)h +(memory)-6 b(,)29 b(which)g(is)f(normally)i(more)f(than)g(of)n(fset)g +(by)g(the)f(re-)448 1650 y(duction)e(in)d(size)h(of)g(the)g(node)g +(structure.)589 1763 y(When)j(using)h(64-bit)f(pointers,)i(there)f(is)e +(normally)i(no)e(memory)h(adv)n(antage)i(from)d(us-)448 +1876 y(ing)e(short)h(int')-5 b(s)24 b(instead)h(of)e(int')-5 +b(s)25 b(in)e(a)g(DdNode.)29 b(Therefore,)c(increments)g(and)f +(decrements)448 1989 y(are)31 b(not)h(saturating)h(in)e(that)h(case.)51 +b(What)31 b(option)i(is)e(in)f(ef)n(fect)i(depends)h(on)e(tw)o(o)g +(macros,)448 2102 y(SIZEOF)p 763 2102 V 31 w(V)l(OID)p +1018 2102 V 32 w(P)f(and)h(SIZEOF)p 1602 2102 V 30 w(INT,)e(de\002ned)j +(in)e(the)h(e)o(xternal)h(header)g(\002le)e(\()p Fn(cudd.h)p +Fo(\).)448 2215 y(The)g(increments)i(and)e(decrements)i(of)e(the)g +(reference)i(counts)f(are)f(performed)i(using)f(tw)o(o)448 +2328 y(macros:)d Fn(cuddSatInc)21 b Fo(and)d Fn(cuddSatDec)p +Fo(,)k(whose)c(de\002nitions)i(depend)g(on)e(SIZEOF)p +3170 2328 V 31 w(V)l(OID)p 3425 2328 V 33 w(P)448 2441 +y(and)24 b(SIZEOF)p 917 2441 V 31 w(INT.)448 2690 y Fi(4.3)99 +b(Complement)26 b(Ar)n(cs)448 2864 y Fo(If)j(ADDs)f(are)h(restricted)j +(to)d(use)g(only)h(the)g(constants)i(0)c(and)i(1,)g(the)o(y)f(beha)n(v) +o(e)i(lik)o(e)f(BDDs)448 2977 y(without)d(complement)h(arcs.)36 +b(It)25 b(is)h(normally)h(easier)g(to)f(write)g(code)g(that)h +(manipulates)h(0-1)448 3090 y(ADDs,)33 b(than)h(to)e(write)h(code)g +(for)g(BDDs.)54 b(Ho)n(we)n(v)o(er)l(,)34 b(complementation)i(is)d(tri) +n(vial)g(with)448 3203 y(complement)c(arcs,)g(and)f(is)f(not)h(tri)n +(vial)g(without.)41 b(As)27 b(a)g(consequence,)k(with)d(complement)448 +3316 y(arcs)h(it)g(is)f(possible)j(to)d(check)i(for)f(more)f(terminal)i +(cases)g(and)f(it)f(is)g(possible)j(to)d(apply)i(De)448 +3429 y(Mor)n(gan')-5 b(s)25 b(la)o(ws)d(to)g(reduce)j(problems)f(that)f +(are)g(essentially)j(identical)f(to)d(a)h(standard)i(form.)448 +3542 y(This)f(in)f(turn)h(increases)i(the)e(utilization)i(of)e(the)g +(cache.)589 3655 y(The)38 b(complement)h(attrib)n(ute)h(is)d(stored)i +(in)e(the)h(least)h(signi\002cant)g(bit)f(of)f(the)h(\223else\224)448 +3768 y(pointer)25 b(of)f(each)g(node.)29 b(An)23 b(e)o(xternal)i +(pointer)g(to)e(a)g(function)j(can)e(also)g(be)f(complemented.)448 +3880 y(The)d(\223then\224)j(pointer)f(to)e(a)h(node,)g(on)g(the)g +(other)g(hand,)h(is)f(al)o(w)o(ays)g Fn(r)m(e)l(gular)p +Fo(.)30 b(It)20 b(is)h(a)f(mistak)o(e)h(to)448 3993 y(use)f(a)f +(complement)i(pointer)g(as)f(it)f(is)g(to)g(address)j(memory)-6 +b(.)27 b(Instead,)22 b(it)d(is)g(al)o(w)o(ays)i(necessary)448 +4106 y(to)28 b(obtain)i(a)e(re)o(gular)h(v)o(ersion)h(of)e(it.)42 +b(This)28 b(is)g(normally)h(done)g(by)g(calling)g Fn(Cudd)p +3094 4106 V 34 w(Re)l(gular)r Fo(.)448 4219 y(It)f(is)f(also)h(a)f +(mistak)o(e)i(to)e(call)h Fn(cuddUniqueInter)34 b Fo(with)27 +b(a)g(complemented)j(\223then\224)f(child)f(as)448 4332 +y(ar)n(gument.)i(The)22 b(calling)i(procedure)h(must)d(apply)h(De)e +(Mor)n(gan')-5 b(s)24 b(la)o(ws)d(by)h(complementing)448 +4445 y(both)32 b(pointers)i(passed)f(to)e Fn(cuddUniqueInter)38 +b Fo(and)31 b(then)h(taking)h(the)f(complement)h(of)e(the)448 +4558 y(result.)p Black 1897 5225 a(28)p Black eop end +%%Page: 29 29 +TeXDict begin 29 28 bop Black Black 448 573 a Fi(4.4)99 +b(The)26 b(Cache)448 747 y Fo(Each)38 b(entry)g(of)g(the)f(cache)i +(consists)g(of)f(\002)n(v)o(e)e(\002elds:)57 b(The)37 +b(operator)l(,)43 b(three)c(pointers)g(to)448 860 y(operands)d(and)e(a) +f(pointer)i(to)e(the)h(result.)60 b(The)33 b(operator)i(and)f(the)g +(three)g(pointers)i(to)d(the)448 973 y(operands)26 b(are)e(combined)h +(to)f(form)f(three)i(w)o(ords.)k(The)23 b(combination)j(relies)f(on)e +(tw)o(o)h(f)o(acts:)p Black 585 1155 a Fm(\017)p Black +46 w Fo(Most)i(operations)k(ha)n(v)o(e)d(one)h(or)e(tw)o(o)h(operands.) +40 b(A)26 b(fe)n(w)g(bits)h(are)g(suf)n(\002cient)h(to)f(dis-)676 +1268 y(criminate)e(all)e(three-operands)28 b(operations.)p +Black 585 1454 a Fm(\017)p Black 46 w Fo(All)h(nodes)h(are)g(aligned)h +(to)f(16-byte)h(boundaries.)50 b(\(32-byte)32 b(boundaries)h(if)c +(64-bit)676 1567 y(pointers)j(are)f(used.\))51 b(Hence,)33 +b(there)e(are)g(a)g(fe)n(w)e(bits)j(a)n(v)n(ailable)h(to)d(distinguish) +k(the)676 1679 y(three-operand)27 b(operations)g(from)c(te)g(others)i +(and)f(to)g(assign)h(unique)g(codes)g(to)e(them.)589 +1862 y(The)30 b(cache)h(does)f(not)g(contrib)n(ute)j(to)d(the)g +(reference)i(counts)f(of)f(the)g(nodes.)48 b(The)30 b(f)o(act)448 +1975 y(that)h(the)g(cache)g(contains)h(a)e(pointer)i(to)e(a)g(node)h +(does)g(not)f(imply)h(that)g(the)f(node)h(is)f(ali)n(v)o(e.)448 +2088 y(Instead,)k(when)d(garbage)h(collection)h(tak)o(es)e(place,)i +(all)e(entries)h(of)e(the)h(cache)h(pointing)g(to)448 +2201 y(dead)25 b(nodes)f(are)g(cleared.)589 2313 y(The)f(cache)i(is)e +(also)h(cleared)h(\(of)f(all)f(entries\))j(when)d(dynamic)i(reordering) +h(tak)o(es)f(place.)448 2426 y(In)f(both)g(cases,)g(the)g(entries)h +(remo)o(v)o(ed)f(from)g(the)g(cache)g(are)g(about)h(to)e(become)i(in)l +(v)n(alid.)589 2539 y(All)30 b(operands)j(and)e(results)i(in)d(a)g +(cache)i(entry)g(must)e(be)h(pointers)h(to)f(DdNodes.)50 +b(If)31 b(a)448 2652 y(function)f(produces)f(more)f(than)g(one)f +(result,)j(or)d(uses)h(more)f(than)h(three)g(ar)n(guments,)i(there)448 +2765 y(are)24 b(currently)i(tw)o(o)d(solutions:)p Black +585 2947 a Fm(\017)p Black 46 w Fo(Build)g(a)g(separate,)j(local,)e +(cache.)30 b(\(Using,)24 b(for)f(instance,)j(the)e Fn(st)h +Fo(library.\))p Black 585 3133 a Fm(\017)p Black 46 w +Fo(Combine)33 b(multiple)h(results,)i(or)c(multiple)i(operands,)j(into) +c(a)g(single)h(diagram,)h(by)676 3246 y(b)n(uilding)26 +b(a)d(\223multiple)o(xing)j(structure\224)g(with)e(reserv)o(ed)h(v)n +(ariables.)448 3428 y(Support)35 b(of)f(the)h(former)f(solution)j(is)c +(under)j(de)n(v)o(elopment.)62 b(\(See)34 b Fh(cuddLCache.c)p +Fo(..\))448 3541 y(Support)25 b(for)f(the)f(latter)i(solution)h(may)d +(be)h(pro)o(vided)h(in)f(future)g(v)o(ersions)i(of)d(the)h(package.)589 +3654 y(There)e(are)g(three)h(sets)g(of)e(interf)o(ace)j(functions)h(to) +c(the)i(cache.)29 b(The)21 b(\002rst)h(set)g(is)f(for)h(func-)448 +3767 y(tions)31 b(with)f(three)i(operands:)44 b Fn(cuddCac)o(heInsert) +36 b Fo(and)31 b Fn(cuddCac)o(heLookup)p Fo(.)52 b(The)30 +b(second)448 3880 y(set)21 b(is)g(for)g(functions)j(with)c(tw)o(o)h +(operands:)30 b Fn(cuddCac)o(heInsert2)25 b Fo(and)d +Fn(cuddCac)o(heLookup2)p Fo(.)448 3993 y(The)33 b(second)i(set)f(is)f +(for)h(functions)i(with)d(one)h(operand:)51 b Fn(cuddCac)o(heInsert1)38 +b Fo(and)c Fn(cudd-)448 4106 y(Cac)o(heLookup1)p Fo(.)42 +b(The)26 b(second)j(set)e(is)g(slightly)i(f)o(aster)f(than)g(the)f +(\002rst,)h(and)f(the)g(third)h(set)f(is)448 4219 y(slightly)f(f)o +(aster)f(than)f(the)g(second.)448 4463 y Fp(4.4.1)92 +b(Cache)23 b(Sizing)448 4638 y Fo(The)e(size)i(of)e(the)h(cache)h(can)f +(increase)h(during)h(the)d(e)o(x)o(ecution)j(of)e(an)f(application.)31 +b(\(There)22 b(is)448 4751 y(currently)27 b(no)d(w)o(ay)g(to)g +(decrease)i(the)e(size)h(of)f(the)g(cache,)i(though)f(it)f(w)o(ould)h +(not)f(be)g(dif)n(\002cult)448 4863 y(to)33 b(do)g(it.\))57 +b(When)33 b(a)g(cache)h(miss)f(occurs,)j(the)e(package)g(uses)g(the)f +(follo)n(wing)i(criteria)f(to)448 4976 y(decide)25 b(whether)g(to)e +(resize)i(the)f(cache:)p Black 1897 5225 a(29)p Black +eop end +%%Page: 30 30 +TeXDict begin 30 29 bop Black Black Black 562 573 a Fo(1.)p +Black 46 w(If)28 b(the)h(cache)g(already)i(e)o(xceeds)f(the)f(limit)f +(gi)n(v)o(en)h(by)g(the)g Fh(maxCache)24 b Fo(\002eld)29 +b(of)f(the)676 686 y(manager)l(,)i(no)f(resizing)h(tak)o(es)f(place.)44 +b(The)28 b(limit)g(is)g(the)h(minimum)f(of)g(tw)o(o)g(v)n(alues:)676 +799 y(a)k(v)n(alue)i(set)f(at)f(initialization)37 b(time)c(and)g +(possibly)i(modi\002ed)e(by)g(the)g(application,)676 +912 y(which)g(constitutes)i(the)e(hard)h(limit)e(be)o(yond)i(which)f +(the)g(cache)h(will)e(ne)n(v)o(er)h(gro)n(w;)676 1024 +y(and)23 b(a)f(number)i(that)f(depends)i(on)e(the)g(current)h(total)g +(number)g(of)e(slots)i(in)f(the)g(unique)676 1137 y(table.)p +Black 562 1325 a(2.)p Black 46 w(If)f(the)h(cache)h(is)f(not)g(too)g +(lar)n(ge)h(already)-6 b(,)25 b(resizing)g(is)d(decided)j(based)f(on)f +(the)g(hit)g(rate.)676 1438 y(The)28 b(polic)o(y)i(adopted)h(by)e(the)h +(CUDD)c(package)31 b(is)e(\223re)n(w)o(ard-based.)-6 +b(\224)48 b(If)29 b(the)g(cache)676 1551 y(hit)23 b(rate)h(is)g(high,)g +(then)g(it)f(is)h(w)o(orthwhile)h(to)e(increase)j(the)d(size)h(of)g +(the)g(cache.)448 1738 y(When)i(resizing)h(tak)o(es)f(place,)g(the)g +(statistical)h(counters)h(used)e(to)f(compute)h(the)f(hit)h(rate)f(are) +448 1851 y(reinitialized)g(so)c(as)g(to)g(pre)n(v)o(ent)h(immediate)g +(resizing.)30 b(The)21 b(number)h(of)f(entries)i(is)d(doubled.)589 +1964 y(The)k(rationale)i(for)e(the)g(\223re)n(w)o(ard-based\224)j +(polic)o(y)e(is)e(as)h(follo)n(ws.)30 b(In)23 b(man)o(y)h(BDD/ADD)448 +2077 y(applications)j(the)c(hit)g(rate)g(is)g(not)g(v)o(ery)g(sensiti)n +(v)o(e)i(to)d(the)h(size)h(of)e(the)i(cache:)30 b(It)22 +b(is)h(primarily)448 2190 y(a)i(function)j(of)e(the)g(problem)g +(instance)i(at)d(hand.)36 b(If)25 b(a)h(lar)n(ge)g(hit)g(rate)g(is)g +(observ)o(ed,)h(chances)448 2303 y(are)c(that)g(by)g(using)g(a)f(lar)n +(ge)i(cache,)g(the)e(results)i(of)f(lar)n(ge)h(problems)g(\(those)f +(that)h(w)o(ould)f(tak)o(e)448 2416 y(longer)31 b(to)f(solv)o(e\))g +(will)g(survi)n(v)o(e)g(in)g(the)g(cache)h(without)f(being)h(o)o(v)o +(erwritten)g(long)f(enough)448 2529 y(to)i(cause)i(a)d(v)n(aluable)k +(cache)e(hit.)55 b(Notice)32 b(that)h(when)f(a)g(lar)n(ge)i(problem)f +(is)f(solv)o(ed)h(more)448 2642 y(than)c(once,)g(so)f(are)g(its)g +(recursi)n(v)o(ely)i(generated)g(subproblems.)44 b(If)28 +b(the)g(hit)f(rate)i(is)e(lo)n(w)-6 b(,)28 b(the)448 +2755 y(probability)f(of)c(lar)n(ge)i(problems)g(being)g(solv)o(ed)g +(more)e(than)i(once)f(is)f(lo)n(w)-6 b(.)589 2868 y(The)20 +b(other)h(observ)n(ation)j(about)d(the)f(cache)i(sizing)f(polic)o(y)g +(is)f(that)h(there)g(is)f(little)h(point)g(in)448 2980 +y(k)o(eeping)k(a)d(cache)h(which)g(is)f(much)h(lar)n(ger)h(than)f(the)g +(unique)h(table.)29 b(Ev)o(ery)23 b(time)f(the)h(unique)448 +3093 y(table)29 b(\223\002lls)g(up,)-6 b(\224)29 b(garbage)g +(collection)i(is)d(in)l(v)n(ok)o(ed)j(and)e(the)f(cache)h(is)f(cleared) +i(of)e(all)g(dead)448 3206 y(entries.)h(A)19 b(cache)i(that)g(is)f +(much)g(lar)n(ger)i(than)f(the)f(unique)i(table)f(is)f(therefore)i +(less)f(than)f(fully)448 3319 y(utilized.)448 3565 y +Fp(4.4.2)92 b(Local)24 b(Caches)448 3739 y Fo(Sometimes)k(it)f(may)f +(be)i(necessary)h(or)e(con)l(v)o(enient)j(to)d(use)h(a)f(local)h +(cache.)40 b(A)26 b(local)i(cache)448 3852 y(can)f(be)g(lossless)i +(\(no)e(results)h(are)e(e)n(v)o(er)h(o)o(v)o(erwritten\),)i(or)e(it)f +(may)g(store)i(objects)g(for)f(which)448 3965 y(canonical)36 +b(representations)h(are)c(not)g(a)n(v)n(ailable.)59 b(One)33 +b(important)h(f)o(act)g(to)f(k)o(eep)g(in)g(mind)448 +4078 y(when)d(using)g(a)f(local)h(cache)h(is)e(that)h(local)g(caches)h +(are)e(not)h(cleared)h(during)g(garbage)g(col-)448 4191 +y(lection)e(or)e(before)i(reordering.)42 b(Therefore,)29 +b(it)e(is)g(necessary)j(to)d(increment)i(the)e(reference)448 +4304 y(count)22 b(of)d(all)i(nodes)g(pointed)h(by)e(a)g(local)h(cache.) +28 b(\(Unless)21 b(their)g(reference)h(counts)g(are)e(guar)n(-)448 +4417 y(anteed)25 b(positi)n(v)o(e)h(in)d(some)h(other)h(w)o(ay)-6 +b(.)29 b(One)23 b(such)i(w)o(ay)e(is)h(by)f(including)k(all)d(partial)h +(results)448 4530 y(in)i(the)g(global)i(result.\))40 +b(Before)27 b(disposing)j(of)d(the)g(local)h(cache,)g(all)f(elements)i +(stored)f(in)f(it)448 4643 y(must)20 b(be)g(passed)h(to)e +Fn(Cudd)p 1300 4643 28 4 v 34 w(Recur)o(siveDer)m(ef)13 +b Fo(.)30 b(As)19 b(consequence)k(of)d(the)g(f)o(act)g(that)g(all)g +(results)448 4756 y(in)i(a)g(local)h(cache)g(are)g(referenced,)i(it)d +(is)g(generally)i(con)l(v)o(enient)h(to)e(store)g(in)f(the)g(local)h +(cache)448 4868 y(also)h(the)e(result)i(of)f(tri)n(vial)g(problems,)h +(which)f(are)g(not)g(usually)h(stored)g(in)f(the)f(global)i(cache.)p +Black 1897 5225 a(30)p Black eop end +%%Page: 31 31 +TeXDict begin 31 30 bop Black Black 448 573 a Fo(Otherwise,)35 +b(after)d(a)g(recursi)n(v)o(e)h(call,)i(it)c(is)h(dif)n(\002cult)g(to)g +(tell)h(whether)f(the)h(result)g(is)e(in)h(the)448 686 +y(cache,)25 b(and)f(therefore)h(referenced,)h(or)e(not)g(in)f(the)h +(cache,)g(and)g(therefore)i(not)e(referenced.)589 799 +y(An)19 b(alternati)n(v)o(e)i(approach)g(to)e(referencing)j(the)d +(results)i(in)e(the)g(local)h(caches)g(is)f(to)g(install)448 +912 y(hook)25 b(functions)h(\(see)e(Section)g(3.16\))h(to)e(be)h(e)o(x) +o(ecuted)h(before)g(garbage)g(collection.)448 1158 y +Fi(4.5)99 b(The)26 b(Unique)g(T)-9 b(able)448 1333 y +Fo(A)29 b(recursi)n(v)o(e)j(procedure)h(typically)f(splits)g(the)e +(operands)j(by)d(e)o(xpanding)j(with)d(respect)h(to)448 +1445 y(the)d(topmost)h(v)n(ariable.)43 b(T)-7 b(opmost)28 +b(in)g(this)g(conte)o(xt)h(refers)g(to)e(the)h(v)n(ariable)i(that)e(is) +g(closest)448 1558 y(to)i(the)f(roots)i(in)e(the)h(current)h(v)n +(ariable)g(order)-5 b(.)47 b(The)29 b(nodes,)j(on)d(the)h(other)g +(hand,)i(hold)e(the)448 1671 y(inde)o(x,)c(which)f(is)g(in)l(v)n +(ariant)i(with)e(reordering.)36 b(Therefore,)26 b(when)f(splitting,)j +(one)d(must)g(use)448 1784 y(the)j(permutation)i(array)e(maintained)i +(by)d(the)h(package)i(to)d(get)h(the)f(right)i(le)n(v)o(el.)40 +b(Access)28 b(to)448 1897 y(the)22 b(permutation)i(array)e(is)f(pro)o +(vided)i(by)f(the)f(macro)h Fn(cuddI)27 b Fo(for)21 b(BDDs)f(and)i +(ADDs,)d(and)j(by)448 2010 y(the)i(macro)g Fn(cuddIZ)29 +b Fo(for)24 b(ZDDs.)589 2123 y(The)i(unique)i(table)f(consists)h(of)e +(as)g(man)o(y)g(hash)h(tables)h(as)e(there)h(are)f(v)n(ariables)i(in)e +(use.)448 2236 y(These)e(has)f(tables)h(are)g(called)g +Fn(unique)h(subtables)p Fo(.)31 b(The)23 b(sizes)g(of)g(the)h(unique)h +(subtables)g(are)448 2349 y(determined)h(by)e(tw)o(o)f(criteria:)p +Black 562 2524 a(1.)p Black 46 w(The)g(collision)j(lists)e(should)h(be) +f(short)g(to)g(k)o(eep)g(access)h(time)e(do)n(wn.)p Black +562 2707 a(2.)p Black 46 w(There)18 b(should)i(be)e(enough)i(room)e +(for)g(dead)h(nodes,)h(to)e(pre)n(v)o(ent)h(too)g(frequent)h(garbage) +676 2819 y(collections.)448 2995 y(While)30 b(the)g(\002rst)g +(criterion)i(is)d(f)o(airly)i(straightforw)o(ard)j(to)c(implement,)i +(the)e(second)h(lea)n(v)o(es)448 3108 y(more)22 b(room)g(to)f(creati)n +(vity)-6 b(.)31 b(The)21 b(CUDD)e(package)24 b(tries)f(to)e(\002gure)h +(out)g(whether)h(more)e(dead)448 3220 y(node)j(should)h(be)e(allo)n +(wed)g(to)g(increase)i(performance.)31 b(\(See)23 b(also)h(Section)f +(3.4.\))29 b(There)23 b(are)448 3333 y(tw)o(o)k(reasons)h(for)f(not)g +(doing)h(garbage)g(collection)h(too)e(often.)39 b(The)26 +b(ob)o(vious)j(one)e(is)f(that)i(it)448 3446 y(is)21 +b(e)o(xpensi)n(v)o(e.)30 b(The)21 b(second)i(is)e(that)h(dead)g(nodes)g +(may)f(be)g(reclaimed,)j(if)d(the)o(y)g(are)h(the)f(result)448 +3559 y(of)k(a)g(successful)j(cache)f(lookup.)35 b(Hence)26 +b(dead)g(nodes)g(may)f(pro)o(vide)i(a)e(substantial)j(speed-)448 +3672 y(up)35 b(if)f(the)o(y)g(are)h(k)o(ept)g(around)g(long)h(enough.) +62 b(The)34 b(usefulness)j(of)d(k)o(eeping)i(man)o(y)e(dead)448 +3785 y(nodes)g(around)h(v)n(aries)f(from)e(application)k(to)d +(application,)38 b(and)33 b(from)g(problem)h(instance)448 +3898 y(to)d(problem)g(instance.)51 b(As)30 b(in)g(the)h(sizing)g(of)f +(the)h(cache,)i(the)e(CUDD)d(package)k(adopts)g(a)448 +4011 y(\223re)n(w)o(ard-based\224)k(polic)o(y)e(to)e(decide)i(ho)n(w)e +(much)h(room)f(should)i(be)f(used)g(for)g(the)g(unique)448 +4124 y(table.)62 b(If)35 b(the)f(number)h(of)g(dead)g(nodes)h +(reclaimed)g(is)e(lar)n(ge)h(compared)h(to)f(the)f(number)448 +4237 y(of)d(nodes)h(directly)g(requested)h(from)e(the)g(memory)f +(manager)l(,)k(then)d(the)g(CUDD)d(package)448 4350 y(assumes)34 +b(that)g(it)e(will)h(be)f(bene\002cial)j(to)e(allo)n(w)f(more)h(room)g +(for)g(the)g(subtables,)k(thereby)448 4462 y(reducing)31 +b(the)e(frequenc)o(y)i(of)e(garbage)h(collection.)47 +b(The)28 b(package)j(does)e(so)g(by)g(switching)448 4575 +y(between)c(tw)o(o)e(modes)h(of)g(operation:)p Black +562 4751 a(1.)p Black 46 w(F)o(ast)d(gro)n(wth:)30 b(In)22 +b(this)h(mode,)f(the)h(ratio)g(of)g(dead)g(nodes)g(to)g(total)g(nodes)h +(required)g(for)676 4863 y(garbage)k(collection)h(is)e(higher)h(than)g +(in)f(the)g(slo)n(w)f(gro)n(wth)h(mode)g(to)g(f)o(a)n(v)n(or)h +(resizing)676 4976 y(of)23 b(the)h(subtables.)p Black +1897 5225 a(31)p Black eop end +%%Page: 32 32 +TeXDict begin 32 31 bop Black Black Black 562 573 a Fo(2.)p +Black 46 w(Slo)n(w)28 b(gro)n(wth:)42 b(In)29 b(this)h(mode)g(k)o +(eeping)h(man)o(y)f(dead)g(nodes)h(around)g(is)f(not)f(as)h(im-)676 +686 y(portant)25 b(as)e(k)o(eeping)j(memory)e(requirements)i(lo)n(w)-6 +b(.)448 873 y(Switching)25 b(from)e(one)h(mode)g(to)f(the)h(other)h(is) +e(based)i(on)e(the)h(follo)n(wing)h(criteria:)p Black +562 1061 a(1.)p Black 46 w(If)e(the)h(unique)h(table)f(is)g(already)h +(lar)n(ge,)f(only)h(slo)n(w)e(gro)n(wth)h(is)f(possible.)p +Black 562 1249 a(2.)p Black 46 w(If)35 b(the)h(table)h(is)f(small)g +(and)g(man)o(y)g(dead)h(nodes)g(are)f(being)h(reclaimed,)j(then)d(f)o +(ast)676 1362 y(gro)n(wth)24 b(is)f(selected.)448 1549 +y(This)j(polic)o(y)g(is)g(especially)i(ef)n(fecti)n(v)o(e)f(when)f(the) +g(diagrams)h(being)f(manipulated)j(ha)n(v)o(e)d(lots)448 +1662 y(of)f(recombination.)37 b(Notice)25 b(the)h(interplay)h(of)e(the) +h(cache)g(sizing)g(and)g(unique)g(sizing:)34 b(F)o(ast)448 +1775 y(gro)n(wth)24 b(normally)h(occurs)f(when)g(the)f(cache)h(hit)g +(rate)g(is)f(lar)n(ge.)29 b(The)23 b(cache)h(and)g(the)g(unique)448 +1888 y(table)h(then)f(gro)n(w)f(in)h(concert,)h(preserving)h(a)d +(healthy)i(balance)h(between)e(their)h(sizes.)448 2137 +y Fi(4.6)99 b(Allo)o(wing)24 b(Asynchr)n(onous)i(Reordering)448 +2311 y Fo(Asynchronous)36 b(reordering)f(is)d(the)g(reordering)j(that)d +(is)g(triggered)j(automatically)g(by)d(the)448 2424 y(increase)37 +b(of)d(the)h(number)g(of)g(nodes.)62 b(Asynchronous)38 +b(reordering)f(tak)o(es)f(place)f(when)g(a)448 2537 y(ne)n(w)28 +b(internal)i(node)g(must)e(be)g(created,)j(and)e(the)g(number)g(of)f +(nodes)i(has)f(reached)h(a)e(gi)n(v)o(en)448 2650 y(threshold.)49 +b(\(The)29 b(threshold)j(is)d(adjusted)i(by)f(the)f(package)i(e)n(v)o +(ery)f(time)f(reordering)j(tak)o(es)448 2763 y(place.\))589 +2876 y(Those)24 b(procedures)j(that)d(do)g(not)f(create)i(ne)n(w)e +(nodes)i(\(e.g.,)e(procedures)j(that)e(count)h(the)448 +2989 y(number)g(of)e(nodes)h(or)g(minterms\))g(need)g(not)g(w)o(orry)f +(about)i(asynchronous)i(reordering:)32 b(No)448 3102 +y(special)25 b(precaution)i(is)c(necessary)j(in)e(writing)g(them.)589 +3215 y(Procedures)i(that)e(only)g(manipulate)i(decision)f(diagrams)g +(through)g(the)f(e)o(xported)h(func-)448 3328 y(tions)j(of)e(the)h +(CUDD)e(package)j(also)f(need)h(not)f(concern)h(themselv)o(es)h(with)d +(asynchronous)448 3440 y(reordering.)32 b(\(See)23 b(Section)i(3.2.1)e +(for)h(the)g(e)o(xceptions.\))589 3553 y(The)i(remaining)h(class)g(of)e +(procedures)k(is)c(composed)j(of)d(functions)j(that)e(visit)h(the)f +(dia-)448 3666 y(grams)h(and)h(may)e(create)i(ne)n(w)e(nodes.)39 +b(All)26 b(such)i(procedures)h(in)e(the)g(CUDD)d(package)29 +b(are)448 3779 y(written)35 b(so)e(that)h(the)o(y)g(can)g(be)f +(interrupted)k(by)d(dynamic)g(reordering.)62 b(The)33 +b(general)i(ap-)448 3892 y(proach)26 b(follo)n(wed)g(goes)f(under)g +(the)g(name)f(of)h(\223abort)g(and)g(retry.)-6 b(\224)32 +b(As)24 b(the)g(name)h(implies,)g(a)448 4005 y(computation)i(that)d(is) +f(interrupted)k(by)c(dynamic)i(reordering)h(is)e(aborted)h(and)f(tried) +h(again.)589 4118 y(A)e(recursi)n(v)o(e)i(procedure)h(that)e(can)f(be)h +(interrupted)i(by)e(dynamic)g(reordering)i(\(an)e(inter)n(-)448 +4231 y(ruptible)g(procedure)h(from)d(no)n(w)g(on\))h(is)f(composed)i +(of)e(tw)o(o)f(functions.)31 b(One)22 b(is)g(responsible)448 +4344 y(for)30 b(the)f(real)h(computation.)49 b(The)29 +b(other)h(is)f(a)g(simple)h(wrapper,)h(which)f(tests)g(whether)g(re-) +448 4457 y(ordering)c(occurred)g(and)e(restarts)h(the)f(computation)i +(if)d(it)h(did.)589 4570 y(Asynchronous)f(reordering)e(of)e(BDDs)e(and) +i(ADDs)e(can)i(only)h(be)e(triggered)k(inside)e Fn(cud-)448 +4682 y(dUniqueInter)r Fo(,)36 b(when)31 b(a)f(ne)n(w)g(node)i(is)f +(about)h(to)e(be)h(created.)53 b(Lik)o(e)n(wise,)32 b(asynchronous)448 +4795 y(reordering)f(of)d(ZDDs)f(can)h(only)h(be)f(triggered)j(inside)e +Fn(cuddUniqueInterZdd)r Fo(.)48 b(When)28 b(re-)448 4908 +y(ordering)e(is)d(triggered,)j(three)e(things)h(happen:)p +Black 1897 5225 a(32)p Black eop end +%%Page: 33 33 +TeXDict begin 33 32 bop Black Black Black 562 573 a Fo(1.)p +Black 46 w Fn(cuddUniqueInter)29 b Fo(returns)d(a)d(NULL)e(v)n(alue;)p +Black 562 760 a(2.)p Black 46 w(The)i(\003ag)g Fn(r)m(eor)m(der)m(ed)28 +b Fo(of)23 b(the)h(manager)h(is)e(set)h(to)g(1.)29 b(\(0)23 +b(means)h(no)g(reordering,)i(while)676 873 y(2)d(indicates)j(an)d +(error)i(occurred)g(during)g(reordering.\))p Black 562 +1061 a(3.)p Black 46 w(The)g(counter)k Fn(r)m(eor)m(derings)g +Fo(of)d(the)g(manager)i(is)e(incremented.)40 b(The)26 +b(counter)i(is)e(ini-)676 1174 y(tialized)37 b(to)f(0)f(when)h(the)g +(manager)h(is)f(started)h(and)f(can)g(be)g(accessed)i(by)e(calling)676 +1287 y Fn(Cudd)p 877 1287 28 4 v 33 w(ReadReor)m(derings)p +Fo(.)41 b(By)25 b(taking)j(tw)o(o)e(readings)j(of)d(the)h(counter)l(,)i +(an)d(applica-)676 1400 y(tion)32 b(can)g(determine)i(if)d(v)n(ariable) +j(reordering)h(has)d(tak)o(en)h(place)g(between)g(the)f(\002rst)676 +1513 y(and)27 b(the)g(second)h(reading.)41 b(The)26 b(package)j +(itself,)f(ho)n(we)n(v)o(er)l(,)g(does)g(not)f(mak)o(e)g(use)g(of)676 +1626 y(the)c(counter:)31 b(It)24 b(is)f(mentioned)j(here)e(for)g +(completeness.)589 1813 y(The)35 b(recursi)n(v)o(e)h(procedure)i(that)d +(recei)n(v)o(es)h(a)e(NULL)f(v)n(alue)i(from)g Fn(cuddUniqueInter)448 +1926 y Fo(must)g(free)h(all)f(intermediate)j(results)f(that)e(it)g(may) +g(ha)n(v)o(e)h(computed)g(before,)j(and)d(return)448 +2039 y(NULL)21 b(in)j(its)f(turn.)589 2152 y(The)31 b(wrapper)g +(function)i(does)e(not)g(decide)i(whether)e(reordering)j(occurred)e +(based)g(on)448 2265 y(the)37 b(NULL)e(return)j(v)n(alue,)i(because)f +(the)e(NULL)d(v)n(alue)k(may)e(be)h(the)g(result)h(of)f(lack)g(of)448 +2378 y(memory)-6 b(.)29 b(Instead,)c(it)f(checks)h(the)e +Fn(r)m(eor)m(der)m(ed)28 b Fo(\003ag.)589 2491 y(When)h(a)e(recursi)n +(v)o(e)i(procedure)i(calls)e(another)g(recursi)n(v)o(e)h(procedure)g +(that)f(may)e(cause)448 2604 y(reordering,)i(it)d(should)i(bypass)f +(the)f(wrapper)h(and)g(call)f(the)g(recursi)n(v)o(e)i(procedure)h +(directly)-6 b(.)448 2716 y(Otherwise,)29 b(the)f(calling)i(procedure)g +(will)d(not)h(kno)n(w)f(whether)i(reordering)h(occurred,)h(and)448 +2829 y(will)26 b(not)g(be)g(able)g(to)g(restart.)37 b(This)25 +b(is)h(the)g(main)g(reason)h(why)e(most)h(recursi)n(v)o(e)h(procedures) +448 2942 y(are)k(internal,)i(rather)e(than)g(static.)50 +b(\(The)30 b(wrappers,)j(on)d(the)h(other)g(hand,)h(are)e(mostly)h(e)o +(x-)448 3055 y(ported.\))448 3304 y Fi(4.7)99 b(Deb)n(ugging)448 +3479 y Fo(By)35 b(de\002ning)i(the)g(symbol)f(DD)p 1508 +3479 V 32 w(DEB)o(UG)e(during)j(compilation,)k(numerous)d(checks)f(are) +448 3592 y(added)20 b(to)e(the)g(code.)28 b(In)18 b(addition,)j(the)d +(procedures)j Fn(Cudd)p 2297 3592 V 34 w(Deb)n(ugChec)n(k)r +Fo(,)g Fn(Cudd)p 3036 3592 V 33 w(Chec)n(kK)m(e)m(ys)p +Fo(,)448 3704 y(and)g Fn(cuddHeapPr)l(o\002le)i Fo(can)e(be)f(called)h +(at)f(an)o(y)g(point)i(to)e(v)o(erify)h(the)f(consistenc)o(y)j(of)d +(the)h(data)448 3817 y(structure.)44 b(\()p Fn(cuddHeapPr)l(o\002le)31 +b Fo(is)d(an)f(internal)j(procedure.)44 b(It)27 b(is)h(declared)i(in)d +Fn(cuddInt.h)p Fo(.\))448 3930 y(Procedures)37 b Fn(Cudd)p +1087 3930 V 34 w(Deb)n(ugChec)n(k)h Fo(and)d Fn(Cudd)p +1983 3930 V 34 w(Chec)n(kK)m(e)m(ys)h Fo(are)f(especially)i(useful)f +(when)448 4043 y(CUDD)20 b(reports)k(that)e(during)i(garbage)f +(collection)i(the)d(number)h(of)e(nodes)j(actually)g(deleted)448 +4156 y(from)k(the)h(unique)h(table)f(is)f(dif)n(ferent)i(from)f(the)f +(count)i(of)e(dead)h(nodes)g(k)o(ept)g(by)g(the)f(man-)448 +4269 y(ager)-5 b(.)36 b(The)25 b(error)h(causing)h(the)f(discrepanc)o +(y)j(may)c(ha)n(v)o(e)h(occurred)i(much)d(earlier)i(than)f(it)f(is)448 +4382 y(disco)o(v)o(ered.)42 b(A)26 b(fe)n(w)h(strate)o(gicaly)j(placed) +f(calls)f(to)f(the)g(deb)n(ugging)k(procedures)f(can)e(con-)448 +4495 y(siderably)j(narro)n(w)e(do)n(wn)f(the)h(search)g(for)g(the)g +(source)g(of)g(the)f(problem.)45 b(\(F)o(or)27 b(instance,)32 +b(a)448 4608 y(call)23 b(to)g Fn(Cudd)p 895 4608 V 34 +w(Recur)o(siveDer)m(ef)38 b Fo(where)23 b(one)g(to)f +Fn(Cudd)p 2210 4608 V 34 w(Der)m(ef)36 b Fo(w)o(as)22 +b(required)i(may)f(be)f(iden-)448 4721 y(ti\002ed)i(in)f(this)h(w)o(ay) +-6 b(.\))589 4834 y(One)29 b(of)g(the)g(most)g(common)g(problems)i +(encountered)h(in)d(deb)n(ugging)j(code)e(based)g(on)448 +4946 y(the)j(CUDD)e(package)k(is)e(a)f(missing)i(call)f(to)g +Fn(Cudd)p 2158 4946 V 34 w(Recur)o(siveDer)m(ef)13 b +Fo(.)59 b(T)-7 b(o)32 b(help)h(identify)p Black 1897 +5225 a(33)p Black eop end +%%Page: 34 34 +TeXDict begin 34 33 bop Black Black 448 573 a Fo(this)22 +b(type)g(of)f(problems,)i(the)e(package)i(pro)o(vides)g(a)e(function)i +(called)f Fn(Cudd)p 2858 573 28 4 v 34 w(Chec)n(kZer)l(oRef)13 +b Fo(.)448 686 y(This)37 b(function)h(should)h(be)d(called)i +(immediately)g(before)g(shutting)h(do)n(wn)e(the)f(manager)-5 +b(.)448 799 y Fn(Cudd)p 649 799 V 34 w(Chec)n(kZer)l(oRef)34 +b Fo(checks)20 b(that)g(the)f(only)h(nodes)g(left)f(with)g(non-zero)i +(reference)h(counts)448 912 y(are)27 b(the)f(prede\002ned)j(constants,) +g(the)e(BDD)d(projection)29 b(functions,)h(and)c(nodes)i(whose)f(ref-) +448 1024 y(erence)e(counts)g(are)f(saturated.)589 1137 +y(F)o(or)29 b(this)h(function)i(to)e(be)g(ef)n(fecti)n(v)o(e)h(the)f +(application)i(must)e(e)o(xplicitly)i(dispose)g(of)d(all)448 +1250 y(diagrams)c(to)f(which)g(it)f(has)h(pointers)h(before)g(calling)h +(it.)448 1498 y Fi(4.8)99 b(Gathering)26 b(and)f(Inter)o(pr)n(eting)i +(Statistics)448 1673 y Fo(Function)33 b Fn(Cudd)p 1003 +1673 V 34 w(PrintInfo)g Fo(can)f(be)f(called)i(to)e(print)i(out)f(the)f +(v)n(alues)i(of)e(parameters)j(and)448 1786 y(statistics)c(for)e(a)f +(manager)-5 b(.)41 b(The)27 b(output)j(of)d Fn(Cudd)p +2089 1786 V 34 w(PrintInfo)i Fo(is)e(di)n(vided)i(in)e(tw)o(o)g +(sections.)448 1899 y(The)19 b(\002rst)g(reports)i(the)e(v)n(alues)h +(of)f(parameters)j(that)d(are)h(under)g(the)f(application)k(control.)29 +b(The)448 2011 y(second)e(reports)g(the)f(v)n(alues)g(of)f(statistical) +j(counters)f(and)f(other)g(non-modi\002able)i(parame-)448 +2124 y(ters.)j(A)22 b(quick)k(guide)f(to)f(the)g(interpretation)k(of)c +(all)g(these)h(quantities)h(follo)n(ws.)31 b(F)o(or)23 +b(ease)h(of)448 2237 y(e)o(xposition,)30 b(we)25 b(re)n(v)o(erse)j(the) +f(order)g(and)g(describe)i(the)d(non-modi\002able)j(parameters)g +(\002rst.)448 2350 y(W)-7 b(e')o(ll)24 b(use)g(a)f(sample)h(run)g(as)f +(e)o(xample.)30 b(There)24 b(is)f(nothing)j(special)f(about)g(this)f +(run.)448 2595 y Fp(4.8.1)92 b(Non)22 b(Modi\002able)h(P)o(arameters) +448 2769 y Fo(The)g(list)h(of)g(non-modi\002able)i(parameters)g(starts) +e(with:)p Black Black 667 2952 a Fh(****)52 b(CUDD)h(non-modifiable)48 +b(parameters)i(****)667 3065 y(Memory)h(in)j(use:)f(32544220)448 +3247 y Fo(This)25 b(is)f(the)h(memory)g(used)h(by)f(CUDD)d(for)j(three) +h(things)g(mainly:)32 b(Unique)26 b(table)f(\(includ-)448 +3360 y(ing)i(all)g(DD)d(nodes)k(in)e(use\),)i(node)f(free)g(list,)g +(and)g(computed)h(table.)38 b(This)26 b(number)i(almost)448 +3473 y(ne)n(v)o(er)g(decreases)h(in)f(the)f(lifetime)h(of)f(a)g(CUDD)e +(manager)l(,)k(because)g(CUDD)c(does)j(not)f(re-)448 +3586 y(lease)k(memory)f(when)g(it)f(frees)h(nodes.)49 +b(Rather)l(,)32 b(it)d(puts)h(the)g(nodes)h(on)f(its)g(o)n(wn)f(free)h +(list.)448 3699 y(This)h(number)g(is)g(in)f(bytes.)51 +b(It)30 b(does)i(not)f(represent)i(the)e(peak)g(memory)g(occupation,)k +(be-)448 3812 y(cause)d(it)e(does)h(not)g(include)h(the)e(size)h(of)f +(data)h(structures)i(created)f(temporarily)h(by)d(some)448 +3925 y(functions)c(\(e.g.,)d(local)i(look-up)g(tables\).)p +Black Black 667 4131 a Fh(Peak)52 b(number)g(of)i(nodes:)d(837018)448 +4338 y Fo(This)31 b(number)h(is)f(the)g(number)g(of)g(nodes)h(that)g +(the)f(manager)h(has)f(allocated.)54 b(This)30 b(is)h(not)448 +4451 y(the)d(lar)n(gest)h(size)f(of)f(the)h(BDDs,)e(because)j(the)f +(manager)g(will)f(normally)i(ha)n(v)o(e)f(some)f(dead)448 +4563 y(nodes)e(and)f(some)g(nodes)h(on)e(the)h(free)g(list.)p +Black Black 667 4770 a Fh(Peak)52 b(number)g(of)i(live)e(nodes:)g +(836894)448 4976 y Fo(This)20 b(is)g(the)h(lar)n(gest)h(number)f(of)f +(li)n(v)o(e)g(nodes)h(that)g(the)f(manager)i(has)e(held)h(since)g(its)g +(creation.)p Black 1897 5225 a(34)p Black eop end +%%Page: 35 35 +TeXDict begin 35 34 bop Black Black Black Black 667 573 +a Fh(Number)51 b(of)j(BDD)f(variables:)d(198)667 686 +y(Number)h(of)j(ZDD)f(variables:)d(0)448 892 y Fo(These)24 +b(numbers)h(tell)f(us)f(this)h(run)g(w)o(as)g(not)f(using)i(ZDDs.)p +Black Black 667 1099 a Fh(Number)51 b(of)j(cache)e(entries:)f(1048576) +448 1306 y Fo(Current)25 b(number)g(of)f(slots)h(of)f(the)g(computed)i +(table.)31 b(If)24 b(one)g(has)g(a)g(performance)i(problem,)448 +1419 y(this)e(is)g(one)g(of)f(the)h(numbers)h(to)e(look)i(at.)j(The)23 +b(cache)i(size)f(is)f(al)o(w)o(ays)i(a)e(po)n(wer)g(of)h(2.)p +Black Black 667 1625 a Fh(Number)51 b(of)j(cache)e(look-ups:)f(2996536) +667 1738 y(Number)g(of)j(cache)e(hits:)g(1187087)448 +1945 y Fo(These)22 b(numbers)i(gi)n(v)o(e)e(an)g(indication)i(of)e(the) +g(hit)g(rate)h(in)e(the)i(computed)g(table.)29 b(It)22 +b(is)g(not)g(un-)448 2058 y(lik)o(ely)j(for)f(model)g(checking)i(runs)e +(to)g(get)f(hit)h(rates)g(e)n(v)o(en)g(higher)h(than)f(this)h(one)f +(\(39.62\045\).)p Black Black 667 2265 a Fh(Number)51 +b(of)j(cache)e(insertions:)e(1809473)667 2377 y(Number)h(of)j(cache)e +(collisions:)e(961208)667 2490 y(Number)h(of)j(cache)e(deletions:)e(0) +448 2697 y Fo(A)30 b(collision)j(occurs)f(when)f(a)f(cache)i(entry)g +(is)e(o)o(v)o(erwritten.)52 b(A)30 b(deletion)j(occurs)f(when)f(a)448 +2810 y(cache)c(entry)g(is)e(in)l(v)n(alidated)k(\(e.g.,)d(during)h +(garbage)g(collection\).)39 b(If)25 b(the)h(number)h(of)e(dele-)448 +2923 y(tions)d(is)f(high)g(compared)i(to)d(the)h(number)h(of)f +(collisions,)i(it)e(means)g(that)g(garbage)i(collection)448 +3036 y(occurs)32 b(too)e(often.)48 b(In)30 b(this)g(case)h(there)f +(were)g(no)g(garbage)h(collections;)36 b(hence,)d(no)c(dele-)448 +3149 y(tions.)p Black Black 667 3355 a Fh(Cache)52 b(used)g(slots)h(=)h +(80.90\045)e(\(expected)e(82.19\045\))448 3562 y Fo(Percentage)26 +b(of)e(cache)i(slots)f(that)f(contain)i(a)e(v)n(alid)h(entry)-6 +b(.)31 b(If)24 b(this)h(number)g(is)f(small,)g(it)g(may)448 +3675 y(signal)h(one)f(of)g(three)g(conditions:)p Black +562 3858 a(1.)p Black 46 w(The)f(cache)h(may)g(ha)n(v)o(e)g(been)g +(recently)i(resized)f(and)f(it)f(is)g(still)i(\002lling)f(up.)p +Black 562 4043 a(2.)p Black 46 w(The)j(cache)i(is)f(too)h(lar)n(ge)g +(for)f(the)g(BDDs.)41 b(This)28 b(should)i(not)e(happen)i(if)d(the)i +(size)f(of)676 4156 y(the)23 b(cache)i(is)e(determined)j(by)e(CUDD.)p +Black 562 4342 a(3.)p Black 46 w(The)f(hash)i(function)h(is)d(not)i(w)o +(orking)g(properly)-6 b(.)32 b(This)24 b(is)f(accompanied)k(by)d(a)f +(de)o(gra-)676 4455 y(dation)34 b(in)f(performance.)59 +b(Con)l(v)o(ersely)-6 b(,)37 b(a)c(de)o(gradation)j(in)c(performance)k +(may)c(be)676 4568 y(due)24 b(to)f(bad)h(hash)g(function)i(beha)n(vior) +-5 b(.)448 4751 y(The)26 b(e)o(xpected)j(v)n(alue)e(is)f(computed)j +(assuming)f(a)e(uniformly)i(random)f(distrib)n(ution)k(of)26 +b(the)448 4863 y(accesses.)45 b(If)28 b(the)h(dif)n(ference)h(between)g +(the)e(measured)i(v)n(alue)f(and)g(the)f(e)o(xpected)i(v)n(alue)f(is) +448 4976 y(lar)n(ge)c(\(unlik)o(e)g(this)g(case\),)f(the)g(cache)g(is)g +(not)f(w)o(orking)i(properly)-6 b(.)p Black 1897 5225 +a(35)p Black eop end +%%Page: 36 36 +TeXDict begin 36 35 bop Black Black Black Black 667 573 +a Fh(Soft)52 b(limit)g(for)i(cache)e(size:)g(1318912)448 +781 y Fo(This)25 b(number)h(says)f(ho)n(w)g(lar)n(ge)h(the)f(cache)h +(can)f(gro)n(w)-6 b(.)33 b(This)24 b(limit)h(is)g(based)h(on)f(the)g +(size)g(of)448 894 y(the)k(unique)g(table.)43 b(CUDD)26 +b(uses)j(a)e(re)n(w)o(ard-based)k(polic)o(y)e(for)f(gro)n(wing)h(the)f +(cache.)44 b(\(See)448 1007 y(Section)32 b(4.4.1.\))49 +b(The)30 b(def)o(ault)i(hit)e(rate)h(for)g(resizing)h(is)e(30\045)g +(and)h(the)g(v)n(alue)g(in)f(ef)n(fect)h(is)448 1120 +y(reported)26 b(among)e(the)g(modi\002able)h(parameters.)p +Black Black 667 1328 a Fh(Number)51 b(of)j(buckets)d(in)j(unique)e +(table:)g(329728)448 1537 y Fo(This)28 b(number)g(is)g(e)o(xactly)h +(one)f(quarter)i(of)d(the)h(one)g(abo)o(v)o(e.)42 b(This)28 +b(is)f(indeed)j(ho)n(w)d(the)h(soft)448 1650 y(limit)37 +b(is)g(determined)i(currently)-6 b(,)43 b(unless)38 b(the)g(computed)g +(table)g(hits)g(the)f(speci\002ed)i(hard)448 1763 y(limit.)29 +b(\(See)23 b(belo)n(w)-6 b(.\))p Black Black 667 1971 +a Fh(Used)52 b(buckets)g(in)h(unique)f(table:)g(87.96\045)g(\(expected) +e(87.93\045\))448 2180 y Fo(Percentage)27 b(of)e(unique)i(table)f(b)n +(uck)o(ets)h(that)e(contain)i(at)e(least)g(one)h(node.)34 +b(Remarks)25 b(analo-)448 2293 y(gous)g(to)e(those)i(made)e(about)i +(the)f(used)g(cache)h(slots)f(apply)-6 b(.)p Black Black +667 2501 a Fh(Number)51 b(of)j(BDD)f(and)g(ADD)g(nodes:)f(836894)667 +2614 y(Number)f(of)j(ZDD)f(nodes:)f(0)448 2822 y Fo(Ho)n(w)22 +b(man)o(y)i(nodes)h(are)e(currently)j(in)e(the)g(unique)h(table,)f +(either)h(ali)n(v)o(e)e(or)h(dead.)p Black Black 667 +3031 a Fh(Number)51 b(of)j(dead)f(BDD)g(and)g(ADD)g(nodes:)f(0)667 +3144 y(Number)f(of)j(dead)f(ZDD)g(nodes:)f(0)448 3352 +y Fo(Subtract)29 b(these)f(numbers)g(from)f(those)i(abo)o(v)o(e)e(to)h +(get)f(the)g(number)i(of)e(li)n(v)o(e)g(nodes.)41 b(In)27 +b(this)448 3465 y(case)k(there)g(are)g(no)f(dead)h(nodes)g(because)i +(the)d(application)j(uses)e(delayed)h(dereferencing)448 +3578 y Fn(Cudd)p 649 3578 28 4 v 34 w(DelayedDer)m(efBdd)r +Fo(.)p Black Black 667 3786 a Fh(Total)52 b(number)g(of)h(nodes)f +(allocated:)e(836894)448 3995 y Fo(This)29 b(is)g(the)g(total)h(number) +g(of)e(nodes)j(that)e(were)g(requested)i(and)f(obtained)h(from)e(the)g +(free)448 4108 y(list.)52 b(It)31 b(ne)n(v)o(er)h(decreases,)j(and)d +(is)f(not)g(an)g(indication)j(of)e(memory)f(occupation)j(after)e(the) +448 4221 y(\002rst)23 b(garbage)i(collection.)32 b(Rather)l(,)24 +b(it)f(is)h(a)f(measure)h(of)g(the)g(package)h(acti)n(vity)-6 +b(.)p Black Black 667 4429 a Fh(Total)52 b(number)g(of)h(nodes)f +(reclaimed:)e(0)448 4638 y Fo(These)29 b(are)f(the)h(nodes)g(that)g +(were)f(resuscitated)k(from)c(the)h(dead.)43 b(If)28 +b(the)o(y)h(are)f(man)o(y)g(more)448 4751 y(than)23 b(the)e(allocated)j +(nodes,)f(and)f(the)g(total)g(number)h(of)e(slots)h(is)g(lo)n(w)f +(relati)n(v)o(e)h(to)g(the)f(number)448 4863 y(of)26 +b(nodes,)i(then)f(one)g(may)f(w)o(ant)g(to)g(increase)i(the)f(limit)f +(for)g(f)o(ast)h(unique)h(table)f(gro)n(wth.)37 b(In)448 +4976 y(this)24 b(case,)g(the)g(number)h(is)e(0)g(because)j(of)d +(delayed)i(dereferencing.)p Black 1897 5225 a(36)p Black +eop end +%%Page: 37 37 +TeXDict begin 37 36 bop Black Black Black Black 667 573 +a Fh(Garbage)51 b(collections)e(so)54 b(far:)f(0)667 +686 y(Time)f(for)h(garbage)f(collections:)d(0.00)k(sec)667 +799 y(Reorderings)c(so)54 b(far:)e(0)667 912 y(Time)g(for)h +(reordering:)d(0.00)j(sec)448 1124 y Fo(There)26 b(is)f(a)g(GC)f(for)i +(each)g(reordering.)37 b(Hence)26 b(the)f(\002rst)h(count)g(will)f(al)o +(w)o(ays)h(be)g(at)f(least)h(as)448 1237 y(lar)n(ge)f(as)f(the)f +(second.)p Black Black 667 1450 a Fh(Node)52 b(swaps)g(in)i +(reordering:)c(0)448 1662 y Fo(This)31 b(is)g(the)g(number)h(of)e +(elementary)j(reordering)h(steps.)52 b(Each)31 b(step)g(consists)i(of)e +(the)g(re-)448 1775 y(e)o(xpression)g(of)d(one)g(node)h(while)f(sw)o +(apping)i(tw)o(o)e(adjacent)i(v)n(ariables.)44 b(This)28 +b(number)h(is)f(a)448 1888 y(good)d(measure)f(of)g(the)g(amount)g(of)g +(w)o(ork)f(done)i(in)e(reordering.)448 2134 y Fp(4.8.2)92 +b(Modi\002able)23 b(P)o(arameters)448 2308 y Fo(Let)g(us)g(no)n(w)f +(consider)k(the)d(modi\002able)h(parameters,)h(that)f(is,)e(those)i +(settings)h(on)f(which)f(the)448 2421 y(application)k(or)c(the)h(user)g +(has)g(control.)p Black Black 667 2634 a Fh(****)52 b(CUDD)h +(modifiable)d(parameters)g(****)667 2746 y(Hard)i(limit)g(for)i(cache)e +(size:)g(8388608)448 2959 y Fo(This)30 b(number)i(counts)f(entries.)51 +b(Each)30 b(entry)h(is)f(16)h(bytes)g(if)f(CUDD)e(is)i(compiled)i(to)e +(use)448 3072 y(32-bit)25 b(pointers.)31 b(T)-7 b(w)o(o)22 +b(important)j(observ)n(ations)i(are)d(in)g(order:)p Black +562 3259 a(1.)p Black 46 w(If)29 b(the)i(datasize)h(limit)e(is)g(set,)h +(CUDD)d(will)i(use)g(it)g(to)g(determine)h(this)g(number)g(au-)676 +3372 y(tomatically)-6 b(.)39 b(On)26 b(a)g(Unix)g(system,)i(one)f(can)g +(type)g(\223limit\224)g(or)f(\223ulimit\224)i(to)e(v)o(erify)i(if)676 +3485 y(this)e(v)n(alue)h(is)e(set.)36 b(If)26 b(the)g(datasize)i(limit) +e(is)f(not)h(set,)h(CUDD)c(uses)k(a)e(def)o(ault)j(which)676 +3598 y(is)21 b(rather)i(small.)28 b(If)22 b(you)g(ha)n(v)o(e)g(enough)i +(memory)d(\(say)i(64MB)e(or)h(more\))f(you)i(should)676 +3711 y(seriously)29 b(consider)g Fn(not)f Fo(using)g(the)f(def)o(ault.) +40 b(So,)27 b(either)h(set)e(the)h(datasize)i(limit,)e(or)676 +3824 y(o)o(v)o(erride)d(the)g(def)o(ault)i(with)d Fn(Cudd)p +1792 3824 28 4 v 34 w(SetMaxCac)o(heHar)m(d)r Fo(.)p +Black 562 4012 a(2.)p Black 46 w(If)d(a)g(process)j(seems)e(to)g(be)f +(going)i(no)n(where,)g(a)f(small)f(v)n(alue)i(for)f(this)g(parameter)i +(may)676 4125 y(be)29 b(the)h(culprit.)47 b(One)29 b(cannot)i(o)o(v)o +(eremphasize)h(the)e(importance)i(of)d(the)h(computed)676 +4237 y(table)24 b(in)f(BDD)f(algorithms.)448 4425 y(In)i(this)g(case)g +(the)g(limit)f(w)o(as)g(automatically)k(set)d(for)f(a)g(tar)n(get)i +(maximum)f(memory)f(occupa-)448 4538 y(tion)h(of)g(104)g(MB.)p +Black Black 667 4751 a Fh(Cache)52 b(hit)h(threshold)d(for)k(resizing:) +c(15\045)p Black 1897 5225 a Fo(37)p Black eop end +%%Page: 38 38 +TeXDict begin 38 37 bop Black Black 448 573 a Fo(This)25 +b(number)g(can)g(be)f(changed)j(if)d(one)h(suspects)i(performance)g(is) +d(hindered)j(by)d(the)h(small)448 686 y(size)30 b(of)e(the)i(cache,)g +(and)g(the)f(cache)h(is)e(not)i(gro)n(wing)f(to)n(w)o(ards)h(the)f +(soft)g(limit)g(suf)n(\002ciently)448 799 y(f)o(ast.)g(In)21 +b(such)h(a)f(case)h(one)g(can)g(change)h(the)e(def)o(ault)i(30\045)f +(to)f(15\045)g(\(as)g(in)h(this)g(case\))g(or)f(e)n(v)o(en)448 +912 y(1\045.)p Black Black 667 1124 a Fh(Garbage)51 b(collection)f +(enabled:)h(yes)448 1337 y Fo(One)34 b(can)g(disable)i(it,)f(b)n(ut)g +(there)f(are)g(fe)n(w)f(good)i(reasons)h(for)e(doing)h(so.)60 +b(It)33 b(is)h(normally)448 1450 y(preferable)26 b(to)e(raise)g(the)g +(limit)g(for)f(f)o(ast)h(unique)i(table)e(gro)n(wth.)29 +b(\(See)24 b(belo)n(w)-6 b(.\))p Black Black 667 1662 +a Fh(Limit)52 b(for)h(fast)g(unique)e(table)i(growth:)e(1363148)448 +1875 y Fo(See)23 b(Section)i(4.5)f(and)g(the)g(comments)g(abo)o(v)o(e)h +(about)g(reclaimed)g(nodes)g(and)f(hard)g(limit)g(for)448 +1988 y(the)g(cache)h(size.)30 b(This)23 b(v)n(alue)i(w)o(as)e(chosen)i +(automatically)i(by)d(CUDD)d(for)j(a)g(datasize)h(limit)448 +2100 y(of)f(1)f(GB.)p Black Black 667 2313 a Fh(Maximum)51 +b(number)h(of)h(variables)e(sifted)h(per)h(reordering:)c(1000)667 +2426 y(Maximum)i(number)h(of)h(variable)e(swaps)h(per)i(reordering:)49 +b(2000000)667 2539 y(Maximum)i(growth)h(while)g(sifting)f(a)j +(variable:)d(1.2)448 2751 y Fo(Lo)n(wering)29 b(these)f(numbers)i(will) +d(cause)i(reordering)i(to)c(be)h(less)h(accurate)h(and)e(f)o(aster)-5 +b(.)43 b(Re-)448 2864 y(sults)22 b(are)f(some)n(what)g(unpredictable,)k +(because)d(lar)n(ger)g(BDDs)d(after)j(one)f(reordering)i(do)e(not)448 +2977 y(necessarily)27 b(mean)d(the)f(process)j(will)d(go)h(f)o(aster)g +(or)g(slo)n(wer)-5 b(.)p Black Black 667 3190 a Fh(Dynamic)51 +b(reordering)f(of)j(BDDs)g(enabled:)e(yes)667 3303 y(Default)g(BDD)i +(reordering)d(method:)h(4)667 3416 y(Dynamic)g(reordering)f(of)j(ZDDs)g +(enabled:)e(no)667 3528 y(Default)g(ZDD)i(reordering)d(method:)h(4)448 +3741 y Fo(These)38 b(lines)h(tell)f(whether)g(automatic)i(reordering)g +(can)e(tak)o(e)g(place)h(and)f(what)f(method)448 3854 +y(w)o(ould)28 b(be)f(used.)41 b(The)27 b(mapping)i(from)e(numbers)h(to) +f(methods)i(is)e(in)g Fh(cudd.h)p Fo(.)37 b(One)27 b(may)448 +3967 y(w)o(ant)i(to)f(try)g(dif)n(ferent)i(BDD)d(reordering)k(methods.) +44 b(If)28 b(v)n(ariable)i(groups)g(are)f(used,)h(ho)n(w-)448 +4080 y(e)n(v)o(er)l(,)21 b(one)f(should)i(not)e(e)o(xpect)h(to)e(see)h +(big)g(dif)n(ferences,)j(because)f(CUDD)c(uses)i(the)g(reported)448 +4193 y(method)31 b(only)f(to)f(reorder)i(each)f(leaf)g(v)n(ariable)h +(group)f(\(typically)i(corresponding)i(present)448 4306 +y(and)d(ne)o(xt)g(state)g(v)n(ariables\).)51 b(F)o(or)30 +b(the)h(relati)n(v)o(e)g(order)g(of)g(the)f(groups,)k(it)c(al)o(w)o +(ays)h(uses)g(the)448 4418 y(same)24 b(algorithm,)h(which)f(is)f(ef)n +(fecti)n(v)o(ely)j(sifting.)589 4531 y(As)i(for)h(enabling)h(dynamic)g +(reordering)h(or)e(not,)h(a)e(sensible)i(recommendation)i(is)c(the)448 +4644 y(follo)n(wing:)36 b(Unless)27 b(the)f(circuit)h(is)f(rather)h +(small)f(or)g(one)h(has)f(a)g(pretty)h(good)g(idea)f(of)g(what)448 +4757 y(the)e(order)h(should)g(be,)e(reordering)j(should)g(be)d +(enabled.)p Black 1897 5225 a(38)p Black eop end +%%Page: 39 39 +TeXDict begin 39 38 bop Black Black Black Black 667 573 +a Fh(Realignment)49 b(of)54 b(ZDDs)e(to)i(BDDs)f(enabled:)e(no)667 +686 y(Realignment)e(of)54 b(BDDs)e(to)i(ZDDs)f(enabled:)e(no)667 +799 y(Dead)h(nodes)g(counted)g(in)h(triggering)d(reordering:)g(no)667 +912 y(Group)i(checking)f(criterion:)f(7)667 1024 y(Recombination)e +(threshold:)i(0)667 1137 y(Symmetry)g(violation)h(threshold:)f(0)667 +1250 y(Arc)j(violation)d(threshold:)g(0)667 1363 y(GA)j(population)d +(size:)i(0)667 1476 y(Number)f(of)j(crossovers)c(for)j(GA:)g(0)448 +1681 y Fo(P)o(arameters)26 b(for)f(reordering.)37 b(See)24 +b(the)i(documentation)i(of)d(the)h(functions)i(used)e(to)f(control)448 +1794 y(these)g(parameters)g(for)f(the)g(details.)p Black +Black 667 1998 a Fh(Next)52 b(reordering)e(threshold:)g(100000)448 +2203 y Fo(When)25 b(the)g(number)g(of)g(nodes)h(crosses)g(this)f +(threshold,)i(reordering)g(will)e(be)f(triggered.)34 +b(\(If)448 2315 y(enabled;)26 b(in)d(this)h(case)f(it)g(is)g(not.\))30 +b(This)23 b(parameter)h(is)f(updated)j(by)d(the)g(package)i(whene)n(v)o +(er)448 2428 y(reordering)i(tak)o(es)f(place.)32 b(The)24 +b(application)j(can)e(change)h(it,)e(for)g(instance)j(at)d(start-up.)33 +b(An-)448 2541 y(other)24 b(possibility)h(is)e(to)f(use)h(a)f(hook)h +(function)i(\(see)e(Section)h(3.16\))f(to)f(o)o(v)o(erride)i(the)f(def) +o(ault)448 2654 y(updating)j(polic)o(y)-6 b(.)448 2899 +y Fp(4.8.3)92 b(Extended)22 b(Statistics)k(and)c(Reporting)448 +3073 y Fo(The)27 b(follo)n(wing)i(symbols)f(can)f(be)h(de\002ned)g +(during)g(compilation)i(to)d(increase)i(the)e(amount)448 +3186 y(of)d(statistics)i(gathered)f(and)f(the)g(number)g(of)g(messages) +h(produced)h(by)d(the)h(package:)p Black 585 3367 a Fm(\017)p +Black 46 w Fo(DD)p 813 3367 28 4 v 32 w(ST)-8 b(A)e(TS;)p +Black 585 3552 a Fm(\017)p Black 46 w Fo(DD)p 813 3552 +V 32 w(CA)l(CHE)p 1151 3552 V 31 w(PR)l(OFILE;)p Black +585 3737 a Fm(\017)p Black 46 w Fo(DD)p 813 3737 V 32 +w(UNIQ)o(UE)p 1194 3737 V 31 w(PR)l(OFILE.)p Black 585 +3922 a Fm(\017)p Black 46 w Fo(DD)p 813 3922 V 32 w(VERBOSE;)448 +4103 y(De\002ning)27 b(DD)p 929 4103 V 32 w(CA)l(CHE)p +1267 4103 V 32 w(PR)l(OFILE)d(causes)k(each)f(entry)h(of)e(the)h(cache) +h(to)f(include)h(an)f(ac-)448 4215 y(cess)i(counter)l(,)h(which)e(is)g +(used)g(to)g(compute)h(simple)f(statistics)i(on)e(the)g(distrib)n +(ution)j(of)d(the)448 4328 y(k)o(e)o(ys.)448 4576 y Fi(4.9)99 +b(Guidelines)25 b(f)n(or)g(Documentation)448 4751 y Fo(The)36 +b(documentation)j(of)d(the)g(CUDD)d(functions)38 b(is)e(e)o(xtracted)i +(automatically)g(from)e(the)448 4863 y(sources)23 b(by)e(Stephen)h(Edw) +o(ards')-5 b(s)21 b(e)o(xtdoc.)29 b(\(The)21 b(Ext)f(system)i(is)e(a)n +(v)n(ailable)j(via)e(anon)o(ymous)448 4976 y(FTP)27 b(from)i +Fh(ic.eecs.berkele)o(y.)o(ed)o(u)p Fo(.\))38 b(The)29 +b(follo)n(wing)h(guidelines)i(are)d(follo)n(wed)p Black +1897 5225 a(39)p Black eop end +%%Page: 40 40 +TeXDict begin 40 39 bop Black Black 448 573 a Fo(in)28 +b(CUDD)d(to)j(insure)h(consistent)h(and)f(ef)n(fecti)n(v)o(e)f(use)h +(of)e(automatic)i(e)o(xtraction.)44 b(It)27 b(is)h(rec-)448 +686 y(ommended)d(that)f(e)o(xtensions)i(to)e(CUDD)d(follo)n(w)j(the)g +(same)f(documentation)k(guidelines.)p Black 585 873 a +Fm(\017)p Black 46 w Fo(The)j(documentation)35 b(of)c(an)g(e)o(xported) +i(procedure)h(should)f(be)e(suf)n(\002cient)h(to)f(allo)n(w)676 +986 y(one)23 b(to)h(use)f(it)h(without)g(reading)h(the)f(code.)29 +b(It)23 b(is)g(not)h(necessary)i(to)d(e)o(xplain)i(ho)n(w)e(the)676 +1099 y(procedure)j(w)o(orks;)e(only)g(what)g(it)f(does.)p +Black 585 1287 a Fm(\017)p Black 46 w Fo(The)29 b Fn(SeeAlso)i +Fo(\002elds)f(should)i(be)e(space-separated)k(lists)d(of)f(function)i +(names.)49 b(The)676 1400 y Fn(SeeAlso)24 b Fo(\002eld)f(of)g(an)g(e)o +(xported)j(procedure)g(should)e(only)h(reference)g(other)f(e)o(xported) +676 1513 y(procedures.)39 b(The)26 b Fn(SeeAlso)h Fo(\002eld)f(of)h(an) +f(internal)i(procedure)h(may)d(reference)i(other)676 +1626 y(internal)c(procedures)i(as)d(well)f(as)h(e)o(xported)i +(procedures,)g(b)n(ut)f(no)f(static)h(procedures.)p Black +585 1813 a Fm(\017)p Black 46 w Fo(The)30 b(return)i(v)n(alues)g(are)f +(detailed)i(in)e(the)g Fn(Description)i Fo(\002eld,)g(not)e(in)g(the)g +Fn(Synopsis)676 1926 y Fo(\002eld.)p Black 585 2114 a +Fm(\017)p Black 46 w Fo(The)c(parameters)k(are)d(documented)j +(alongside)g(their)e(declarations.)46 b(Further)29 b(com-)676 +2227 y(ments)23 b(may)h(appear)h(in)e(the)h Fn(Description)i +Fo(\002eld.)p Black 585 2414 a Fm(\017)p Black 46 w Fo(If)i(the)i +Fn(Description)h Fo(\002eld)e(is)g(non-empty\227which)j(is)d(the)h +(normal)f(case)h(for)f(an)g(e)o(x-)676 2527 y(ported)19 +b(procedure\227then)j(the)d(synopsis)h(is)e(repeated\227possibly)23 +b(slightly)d(changed\227)676 2640 y(at)25 b(the)h(be)o(ginning)i(of)e +(the)g Fn(Description)i Fo(\002eld.)35 b(This)25 b(is)h(so)f(because)j +(e)o(xtdoc)f(will)e(not)676 2753 y(put)e(the)h(synopsis)i(in)e(the)f +(same)h(HTML)d(\002le)i(as)h(the)f(description.)p Black +585 2941 a Fm(\017)p Black 46 w Fo(The)g Fn(Synopsis)j +Fo(\002eld)d(should)i(be)f(about)g(one)g(line)g(long.)448 +3233 y Fq(5)120 b(The)30 b(C++)g(Interface)448 3444 y +Fi(5.1)99 b(Compiling)25 b(and)g(Linking)448 3618 y Fo(T)-7 +b(o)23 b(b)n(uild)i(an)e(application)k(that)d(uses)g(the)g(CUDD)d(C++)i +(interf)o(ace,)j(you)e(should)h(add)p Black Black 448 +3805 a Fh(#include)51 b("cuddObj.hh")448 3993 y Fo(to)31 +b(your)g(source)i(\002les.)50 b(In)30 b(addition)j(to)e(the)g(normal)g +(CUDD)e(libraries)j(\(see)g(Section)f(3.1\))448 4106 +y(you)22 b(should)g(link)g Fh(libobj.a)16 b Fo(to)21 +b(your)h(e)o(x)o(ecutable.)30 b(Refer)21 b(to)f(the)i +Fh(Makefile)16 b Fo(in)21 b(the)g(top)448 4219 y(le)n(v)o(el)j +(directory)i(of)d(the)h(distrib)n(ution)j(for)d(further)h(details.)448 +4468 y Fi(5.2)99 b(Basic)25 b(Manipulation)448 4642 y +Fo(The)d(follo)n(wing)i(fragment)g(of)f(code)g(illustrates)i(some)e +(simple)g(operations)j(on)c(BDDs)f(using)448 4755 y(the)j(C++)f(interf) +o(ace.)p Black 1897 5225 a(40)p Black eop end +%%Page: 41 41 +TeXDict begin 41 40 bop Black Black Black Black 448 573 +a Fh(Cudd)53 b(mgr\(0,0\);)448 686 y(BDD)h(x)g(=)g(mgr.bddVar\(\);)448 +799 y(BDD)g(y)g(=)g(mgr.bddVar\(\);)448 912 y(BDD)g(f)g(=)g(x)g(*)g(y;) +448 1024 y(BDD)g(g)g(=)g(y)g(+)g(!x;)448 1137 y(cout)f(<<)h("f)f(is")g +(<<)h(\(f)g(<=)f(g)h(?)h("")e(:)h(")g(not"\))721 1250 +y(<<)g(")g(less)e(than)h(or)h(equal)e(to)i(g\\n";)448 +1438 y Fo(This)22 b(code)h(creates)h(a)e(manager)h(called)h +Fh(mgr)c Fo(and)j(tw)o(o)e(v)n(ariables)k(in)d(it.)28 +b(It)22 b(then)h(de\002nes)g(tw)o(o)448 1551 y(functions)31 +b Fh(f)c Fo(and)h Fh(g)f Fo(in)h(terms)g(of)g(the)g(v)n(ariables.)44 +b(Finally)-6 b(,)30 b(it)e(prints)h(a)f(message)h(based)g(on)448 +1664 y(the)h(comparison)j(of)c(the)i(tw)o(o)e(functions.)50 +b(No)30 b(e)o(xplicit)h(referencing)i(or)d(dereferencing)j(is)448 +1777 y(required.)h(The)25 b(operators)i(are)d(o)o(v)o(erloaded)j(in)e +(the)g(intuiti)n(v)o(e)h(w)o(ay)-6 b(.)32 b(BDDs)23 b(are)i(freed)g +(when)448 1890 y(e)o(x)o(ecution)d(lea)n(v)o(es)e(the)g(scope)g(in)g +(which)g(the)o(y)f(are)h(de\002ned)g(or)f(when)h(the)g(v)n(ariables)h +(referring)448 2002 y(to)j(them)f(are)h(o)o(v)o(erwritten.)448 +2295 y Fq(6)120 b(Ackno)o(wledgments)448 2502 y Fo(The)27 +b(contrib)n(utors:)40 b(Iris)27 b(Bahar)l(,)h(Hyunw)o(oo)g(Cho,)f +(Erica)g(Frohm,)g(Charlie)h(Gaona,)g(Cheng)448 2615 y(Hua,)k(Jae-Y)-10 +b(oung)32 b(Jang,)g(Seh-W)-7 b(oong)31 b(Jeong,)i(Balakrishna)g(K)o +(umthekar)l(,)g(Enrico)d(Macii,)448 2728 y(Bobbie)19 +b(Manne,)h(In-Ho)e(Moon,)h(Curt)f(Musfeldt,)j(Shipra)d(P)o(anda,)h +(Abelardo)h(P)o(ardo,)f(Bernard)448 2841 y(Plessier)l(,)28 +b(Ka)n(vita)f(Ra)n(vi,)g(Hyongk)o(yoon)i(Shin,)d(Alan)h(Shuler)l(,)g +(Arun)f(Si)n(v)n(akumaran,)i(Jor)n(gen)448 2954 y(Si)n(v)o(esind.)448 +3067 y(The)k(early)h(adopters:)49 b(Gianpiero)34 b(Cabodi,)h(Jordi)e +(Cortadella,)j(Mario)d(Escobar)l(,)j(Gayani)448 3180 +y(Gamage,)28 b(Gary)f(Hachtel,)i(Mariano)g(Hermida,)f(W)-7 +b(oohyuk)28 b(Lee,)f(Enric)g(P)o(astor)l(,)i(Massimo)448 +3292 y(Poncino,)c(Ellen)e(Sento)o(vich,)i(the)f(students)i(of)d +(ECEN5139.)589 3405 y(I)36 b(am)f(also)h(particularly)k(indebted)e(to)e +(the)g(follo)n(wing)h(people)g(for)g(in-depth)h(discus-)448 +3518 y(sions)23 b(on)f(BDDs:)27 b(Armin)22 b(Biere,)g(Oli)n(vier)g +(Coudert,)h(Arie)f(Gur\002nk)o(el,)h(Geert)f(Janssen,)i(Don)448 +3631 y(Knuth,)39 b(Da)n(vid)d(Long,)i(Jean)f(Christophe)g(Madre,)i(K)n +(en)c(McMillan,)k(Shin-Ichi)e(Minato,)448 3744 y(Jaehong)24 +b(P)o(ark,)c(Rajee)n(v)i(Ranjan,)g(Rick)f(Rudell,)h(Ellen)f(Sento)o +(vich,)i(T)-7 b(om)20 b(Shiple,)i(Christian)448 3857 +y(Stangier)l(,)j(and)f(Bw)o(olen)g(Y)-9 b(ang.)589 3970 +y(Special)28 b(thanks)h(to)e(Norris)h(Ip)f(for)g(guiding)j(my)c(f)o +(altering)k(steps)e(in)f(the)g(design)i(of)e(the)448 +4083 y(C++)h(interf)o(ace.)46 b(Gianpiero)30 b(Cabodi)f(and)g(Stef)o +(ano)g(Quer)g(ha)n(v)o(e)g(graciously)i(agreed)f(to)e(let)448 +4196 y(me)23 b(distrib)n(ute)j(their)f(dddmp)f(library)h(with)f(CUDD.) +589 4309 y(Masahiro)j(Fujita,)e(Gary)g(Hachtel,)h(and)f(Carl)g(Pixle)o +(y)g(ha)n(v)o(e)h(pro)o(vided)h(encouragement)448 4422 +y(and)d(advice.)589 4534 y(The)31 b(National)i(Science)f(F)o(oundation) +h(and)f(the)f(Semiconductor)j(Research)f(Corpora-)448 +4647 y(tion)24 b(ha)n(v)o(e)h(supported)h(in)d(part)h(the)g(de)n(v)o +(elopment)i(of)d(this)i(package.)p Black 1897 5225 a(41)p +Black eop end +%%Page: 42 42 +TeXDict begin 42 41 bop Black Black 448 573 a Fq(Refer)n(ences)p +Black 494 780 a Fo([1])p Black 46 w(R.)27 b(I.)h(Bahar)l(,)i(E.)e(A.)f +(Frohm,)i(C.)e(M.)h(Gaona,)i(G.)d(D.)g(Hachtel,)j(E.)e(Macii,)h(A.)f(P) +o(ardo,)645 893 y(and)d(F)-7 b(.)23 b(Somenzi.)36 b(Algebraic)27 +b(decision)f(diagrams)g(and)f(their)g(applications.)40 +b(In)25 b Fn(Pr)l(o-)645 1006 y(ceedings)30 b(of)d(the)h(International) +k(Confer)m(ence)d(on)e(Computer)n(-Aided)j(Design)p Fo(,)f(pages)645 +1119 y(188\226191,)d(Santa)e(Clara,)f(CA,)f(No)o(v)o(ember)h(1993.)p +Black 494 1306 a([2])p Black 46 w(B.)36 b(Bollig,)41 +b(M.)35 b(L)8 b(\250)-38 b(obbing,)42 b(and)c(I.)e(W)-7 +b(e)o(gener)i(.)77 b(Simulated)38 b(annealing)i(to)d(impro)o(v)o(e)645 +1419 y(v)n(ariable)31 b(orderings)h(for)e(OBDDs.)50 b(Presented)30 +b(at)g(the)f(International)k(W)-7 b(orkshop)31 b(on)645 +1532 y(Logic)24 b(Synthesis,)h(Granlibakk)o(en,)h(CA,)c(May)h(1995.)p +Black 494 1720 a([3])p Black 46 w(K.)29 b(S.)f(Brace,)k(R.)d(L.)f +(Rudell,)k(and)f(R.)d(E.)h(Bryant.)55 b(Ef)n(\002cient)30 +b(implementation)j(of)d(a)645 1833 y(BDD)f(package.)57 +b(In)30 b Fn(Pr)l(oceedings)j(of)e(the)f(27th)h(Design)h(A)n(utomation) +g(Confer)m(ence)p Fo(,)645 1945 y(pages)25 b(40\22645,)g(Orlando,)f +(FL,)e(June)i(1990.)p Black 494 2133 a([4])p Black 46 +w(R.)g(K.)g(Brayton)j(et)e(al.)40 b(VIS:)24 b(A)h(system)h(for)f(v)o +(eri\002cation)j(and)e(synthesis.)42 b(T)-6 b(echnical)645 +2246 y(Report)31 b(UCB/ERL)26 b(M95/104,)33 b(Electronics)f(Research)f +(Lab,)g(Uni)n(v)-6 b(.)29 b(of)h(California,)645 2359 +y(December)24 b(1995.)p Black 494 2547 a([5])p Black +46 w(R.)32 b(E.)g(Bryant.)65 b(Graph-based)36 b(algorithms)g(for)d +(Boolean)i(function)h(manipulation.)645 2659 y Fn(IEEE)22 +b(T)-5 b(r)o(ansactions)26 b(on)e(Computer)o(s)p Fo(,)g +(C-35\(8\):677\226691,)k(August)c(1986.)p Black 494 2847 +a([6])p Black 46 w(R.)32 b(Drechsler)l(,)38 b(B.)32 b(Beck)o(er)l(,)k +(and)e(N.)e(G)8 b(\250)-38 b(ock)o(el.)66 b(A)32 b(genetic)j(algorithm) +g(for)f(v)n(ariable)645 2960 y(ordering)27 b(of)e(OBDDs.)35 +b(Presented)26 b(at)f(the)g(International)j(W)-7 b(orkshop)27 +b(on)d(Logic)h(Syn-)645 3073 y(thesis,)g(Granlibakk)o(en,)h(CA,)c(May)h +(1995.)p Black 494 3261 a([7])p Black 46 w(S.)j(J.)g(Friedman)i(and)g +(K.)e(J.)g(Supo)n(wit.)45 b(Finding)28 b(the)g(optimal)g(v)n(ariable)h +(ordering)g(for)645 3373 y(binary)24 b(decision)h(diagrams.)32 +b Fn(IEEE)21 b(T)-5 b(r)o(ansactions)25 b(on)d(Computer)o(s)p +Fo(,)i(39\(5\):710\226713,)645 3486 y(May)g(1990.)p Black +494 3674 a([8])p Black 46 w(M.)35 b(Fujita,)k(Y)-12 b(.)35 +b(Matsunaga,)40 b(and)d(T)-7 b(.)34 b(Kakuda.)74 b(On)35 +b(v)n(ariable)j(ordering)g(of)e(binary)645 3787 y(decision)30 +b(diagrams)f(for)f(the)g(application)j(of)c(multi-le)n(v)o(el)i(logic)g +(synthesis.)49 b(In)28 b Fn(Pr)l(o-)645 3900 y(ceedings)33 +b(of)e(the)g(Eur)l(opean)h(Confer)m(ence)h(on)e(Design)g(A)n(utomation) +p Fo(,)j(pages)e(50\22654,)645 4013 y(Amsterdam,)24 b(February)h(1991.) +p Black 494 4200 a([9])p Black 46 w(M.)h(Held)g(and)i(R.)d(M.)g(Karp.) +44 b(A)25 b(dynamic)j(programming)h(approach)g(to)e(sequencing)645 +4313 y(problems.)35 b Fn(J)n(.)23 b(SIAM)p Fo(,)f(10\(1\):196\226210,) +28 b(1962.)p Black 448 4501 a([10])p Black 47 w(N.)e(Ishiura,)i(H.)e +(Sa)o(w)o(ada,)h(and)g(S.)e(Y)-9 b(ajima.)43 b(Minimization)29 +b(of)e(binary)h(decision)h(dia-)645 4614 y(grams)f(based)g(on)g(e)o +(xchanges)h(of)e(v)n(ariables.)48 b(In)27 b Fn(Pr)l(oceedings)j(of)d +(the)g(International)645 4727 y(Confer)m(ence)37 b(on)e(Computer)n +(-Aided)j(Design)p Fo(,)g(pages)e(472\226475,)k(Santa)35 +b(Clara,)j(CA,)645 4840 y(No)o(v)o(ember)24 b(1991.)p +Black 1897 5225 a(42)p Black eop end +%%Page: 43 43 +TeXDict begin 43 42 bop Black Black Black 448 573 a Fo([11])p +Black 47 w(S.-W)-8 b(.)31 b(Jeong,)37 b(T)-7 b(.-S.)31 +b(Kim,)k(and)e(F)-7 b(.)32 b(Somenzi.)64 b(An)33 b(ef)n(\002cient)h +(method)g(for)f(optimal)645 686 y(BDD)25 b(ordering)k(computation.)47 +b(In)27 b Fn(International)k(Confer)m(ence)e(on)e(VLSI)f(and)h(CAD)645 +799 y(\(ICVC'93\))p Fo(,)c(T)-7 b(aejon,)24 b(K)m(orea,)f(No)o(v)o +(ember)h(1993.)p Black 448 986 a([12])p Black 47 w(S.-I.)29 +b(Minato.)55 b(Zero-suppressed)35 b(BDDs)28 b(for)j(set)f(manipulation) +j(in)d(combinatorial)645 1099 y(problems.)35 b(In)24 +b Fn(Pr)l(oceedings)i(of)e(the)g(Design)g(A)n(utomation)h(Confer)m +(ence)p Fo(,)g(pages)g(272\226)645 1212 y(277,)f(Dallas,)g(TX,)d(June)k +(1993.)p Black 448 1400 a([13])p Black 47 w(S.)38 b(P)o(anda)i(and)f(F) +-7 b(.)38 b(Somenzi.)85 b(Who)39 b(are)h(the)f(v)n(ariables)j(in)d +(your)h(neighborhood.)645 1513 y(In)28 b Fn(Pr)l(oceedings)i(of)d(the)h +(International)j(Confer)m(ence)e(on)f(Computer)n(-Aided)i(Design)p +Fo(,)645 1626 y(pages)25 b(74\22677,)g(San)e(Jose,)h(CA,)d(No)o(v)o +(ember)j(1995.)p Black 448 1813 a([14])p Black 47 w(S.)41 +b(P)o(anda,)48 b(F)-7 b(.)40 b(Somenzi,)48 b(and)43 b(B.)e(F)-7 +b(.)41 b(Plessier)-5 b(.)96 b(Symmetry)43 b(detection)i(and)e(dy-)645 +1926 y(namic)31 b(v)n(ariable)i(ordering)f(of)f(decision)i(diagrams.)57 +b(In)30 b Fn(Pr)l(oceedings)k(of)c(the)h(Inter)n(-)645 +2039 y(national)h(Confer)m(ence)g(on)e(Computer)n(-Aided)i(Design)p +Fo(,)f(pages)g(628\226631,)j(San)29 b(Jose,)645 2152 +y(CA,)22 b(No)o(v)o(ember)i(1994.)p Black 448 2340 a([15])p +Black 47 w(B.)i(F)-7 b(.)25 b(Plessier)-5 b(.)46 b Fn(A)26 +b(Gener)o(al)i(F)-5 b(r)o(ame)o(work)27 b(for)g(V)-10 +b(eri\002cation)30 b(of)d(Sequential)j(Cir)m(cuits)p +Fo(.)645 2452 y(PhD)24 b(thesis,)i(Uni)n(v)o(ersity)h(of)e(Colorado)h +(at)f(Boulder)l(,)i(Dept.)d(of)h(Electrical)i(and)e(Com-)645 +2565 y(puter)g(Engineering,)h(1993.)p Black 448 2753 +a([16])p Black 47 w(R.)e(Rudell.)41 b(Dynamic)25 b(v)n(ariable)j +(ordering)f(for)f(ordered)h(binary)g(decision)h(diagrams.)645 +2866 y(In)g Fn(Pr)l(oceedings)i(of)d(the)h(International)j(Confer)m +(ence)e(on)f(Computer)n(-Aided)i(Design)p Fo(,)645 2979 +y(pages)25 b(42\22647,)g(Santa)e(Clara,)h(CA,)d(No)o(v)o(ember)j(1993.) +p Black 448 3166 a([17])p Black 47 w(E.)43 b(M.)f(Sento)o(vich,)51 +b(K.)42 b(J.)i(Singh,)49 b(C.)42 b(Moon,)50 b(H.)42 b(Sa)n(v)n(oj,)50 +b(R.)42 b(K.)h(Brayton,)50 b(and)645 3279 y(A.)35 b(Sangio)o(v)n +(anni-V)-5 b(incentelli.)79 b(Sequential)38 b(circuit)g(design)g(using) +f(synthesis)i(and)645 3392 y(optimization.)55 b(In)29 +b Fn(Pr)l(oceedings)j(of)e(the)f(International)34 b(Confer)m(ence)d(on) +e(Computer)645 3505 y(Design)p Fo(,)24 b(pages)h(328\226333,)h +(Cambridge,)e(MA,)e(October)i(1992.)p Black 1897 5225 +a(43)p Black eop end +%%Page: 44 44 +TeXDict begin 44 43 bop Black Black Black 448 705 a Fq(Index)p +Black 448 892 a Fo(ADD,)22 b(4,)h(7,)f(11,)i(13)448 1005 +y(aggre)o(gation,)i(18)448 1118 y(Algebraic)f(Decision)g(Diagram,)f +Fn(see)g Fo(ADD)448 1231 y(arc)614 1344 y(complement,)h(11,)f(25,)f(28) +614 1457 y(re)o(gular)l(,)i(25,)f(28)448 1653 y(background)j(v)n(alue,) +d(10)448 1766 y(BDD,)e(4,)h(7,)f(10,)i(12)448 1878 y(Binary)g(Decision) +h(Diagram,)f Fn(see)g Fo(BDD)448 1991 y(box)614 2104 +y(black,)h(4)614 2217 y(clear)l(,)g(4,)e(24)448 2413 +y(cache,)i(8,)e(28,)g(29)614 2526 y(collision,)j(35)614 +2639 y(collision)g(list,)e(31)614 2752 y(deletion,)i(35)614 +2865 y(local,)f(29,)e(30)614 2978 y(lossless,)j(30)614 +3091 y(re)n(w)o(ard-based)h(resizing,)e(30)614 3204 y(sizing,)g(29)448 +3316 y(cacheSize,)g(8)448 3429 y(canonical,)h(7,)d(30)448 +3542 y(compiling,)i(6,)e(10,)h(24)448 3655 y(con\002guration,)j(5)448 +3768 y(con)l(v)o(ersion)614 3881 y(of)d(ADDs)e(to)h(BDDs,)f(15)614 +3994 y(of)i(BDDs)e(to)h(ADDs,)f(15)614 4107 y(of)i(BDDs)e(to)h(ZDDs,)f +(14,)h(15)614 4220 y(of)h(ZDDs)e(to)h(BDDs,)f(15)448 +4333 y(cube)j(sets,)e(4)448 4446 y(cudd.h,)i(6,)e(17,)g(28)448 +4558 y Fn(Cudd)p 649 4558 28 4 v 34 w(addApply)p Fo(,)i(13,)e(14)448 +4671 y Fn(Cudd)p 649 4671 V 34 w(addBddInterval)p Fo(,)k(15)448 +4784 y Fn(Cudd)p 649 4784 V 34 w(addBddP)-7 b(attern)p +Fo(,)26 b(15)448 4897 y Fn(Cudd)p 649 4897 V 34 w(addBddThr)m(eshold)p +Fo(,)h(15)p Black Black 1984 892 a Fn(Cudd)p 2185 892 +V 34 w(addConst)p Fo(,)e(11)1984 1005 y Fn(Cudd)p 2185 +1005 V 34 w(addHarwell)p Fo(,)g(11)1984 1118 y Fn(Cudd)p +2185 1118 V 34 w(AddHook)p Fo(,)f(22)1984 1231 y Fn(Cudd)p +2185 1231 V 34 w(addIthBit)p Fo(,)h(15)1984 1344 y Fn(Cudd)p +2185 1344 V 34 w(addIthV)-10 b(ar)p Fo(,)25 b(11)1984 +1457 y Fn(Cudd)p 2185 1457 V 34 w(addNe)o(wV)-10 b(ar)p +Fo(,)23 b(11)1984 1570 y Fn(Cudd)p 2185 1570 V 34 w(addNe)o(wV)-10 +b(arAtLe)o(vel)p Fo(,)24 b(11,)f(20)1984 1683 y Fn(Cudd)p +2185 1683 V 34 w(addRead)p Fo(,)i(11)1984 1795 y Fn(Cudd)p +2185 1795 V 34 w(addT)-5 b(imes)p Fo(,)24 b(14)1984 1908 +y Fn(Cudd)p 2185 1908 V 34 w(A)n(utodynDisable)p Fo(,)i(17)1984 +2021 y Fn(Cudd)p 2185 2021 V 34 w(A)n(utodynDisableZdd)p +Fo(,)h(20)1984 2134 y Fn(Cudd)p 2185 2134 V 34 w(A)n(utodynEnable)p +Fo(,)f(17)1984 2247 y Fn(Cudd)p 2185 2247 V 34 w(A)n(utodynEnableZdd)p +Fo(,)h(20)1984 2360 y Fn(Cudd)p 2185 2360 V 34 w(bddAnd)p +Fo(,)d(12\22614)1984 2473 y Fn(Cudd)p 2185 2473 V 34 +w(bddAndLimit)p Fo(,)g(22)1984 2586 y Fn(Cudd)p 2185 +2586 V 34 w(bddConstr)o(ain)p Fo(,)i(7)1984 2699 y Fn(Cudd)p +2185 2699 V 34 w(bddIte)p Fo(,)f(12)1984 2812 y Fn(Cudd)p +2185 2812 V 34 w(bddIthV)-10 b(ar)p Fo(,)25 b(11)1984 +2925 y Fn(Cudd)p 2185 2925 V 34 w(bddNe)o(wV)-10 b(ar)p +Fo(,)23 b(11)1984 3037 y Fn(Cudd)p 2185 3037 V 34 w(bddNe)o(wV)-10 +b(arAtLe)o(vel)p Fo(,)24 b(11,)f(20)1984 3150 y Fn(Cudd)p +2185 3150 V 34 w(BddT)-8 b(oAdd)p Fo(,)23 b(15)1984 3263 +y Fn(Cudd)p 2185 3263 V 34 w(bddXor)p Fo(,)h(14)1984 +3376 y(CUDD)p 2248 3376 V 31 w(CA)l(CHE)p 2585 3376 V +32 w(SLO)l(TS,)c(8)1984 3489 y Fn(Cudd)p 2185 3489 V +34 w(Chec)n(kK)m(e)m(ys)p Fo(,)25 b(33)1984 3602 y Fn(Cudd)p +2185 3602 V 34 w(Chec)n(kZer)l(oRef)p Fo(,)g(34)1984 +3715 y Fn(Cudd)p 2185 3715 V 34 w(CountMinterm)p Fo(,)g(11)1984 +3828 y Fn(Cudd)p 2185 3828 V 34 w(Deb)n(ugChec)n(k)p +Fo(,)g(33)1984 3941 y Fn(Cudd)p 2185 3941 V 34 w(DelayedDer)m(efBdd)p +Fo(,)g(36)1984 4054 y Fn(Cudd)p 2185 4054 V 34 w(Der)m(ef)p +Fo(,)e(27,)g(28)1984 4167 y Fn(Cudd)p 2185 4167 V 34 +w(DumpBlif)p Fo(,)g(24)1984 4279 y Fn(Cudd)p 2185 4279 +V 34 w(DumpDaV)-7 b(inci)p Fo(,)24 b(24)1984 4392 y Fn(Cudd)p +2185 4392 V 34 w(DumpDot)p Fo(,)f(24)1984 4505 y Fn(Cudd)p +2185 4505 V 34 w(F)-10 b(or)m(eac)o(hCube)p Fo(,)25 b(6,)e(11)1984 +4618 y Fn(Cudd)p 2185 4618 V 34 w(F)-10 b(or)m(eac)o(hNode)p +Fo(,)25 b(6)1984 4731 y Fn(Cudd)p 2185 4731 V 34 w(HookT)-7 +b(ype)p Fo(,)24 b(21)1984 4844 y Fn(Cudd)p 2185 4844 +V 34 w(Init)p Fo(,)g(8,)f(9)1984 4957 y Fn(Cudd)p 2185 +4957 V 34 w(Mak)o(eT)-5 b(r)m(eeNode)p Fo(,)25 b(19,)e(20)p +Black 1897 5225 a(44)p Black eop end +%%Page: 45 45 +TeXDict begin 45 44 bop Black Black 448 573 a Fn(Cudd)p +649 573 28 4 v 34 w(Mak)o(eZddT)-5 b(r)m(eeNode)p Fo(,)25 +b(21)448 686 y Fn(Cudd)p 649 686 V 34 w(Not)p Fo(,)e(10)448 +799 y Fn(Cudd)p 649 799 V 34 w(PrintInfo)p Fo(,)i(34)448 +912 y Fn(Cudd)p 649 912 V 34 w(PrintMinterm)p Fo(,)f(11)448 +1024 y Fn(Cudd)p 649 1024 V 34 w(Quit)p Fo(,)f(9)448 +1137 y Fn(Cudd)p 649 1137 V 34 w(ReadBac)n(kgr)l(ound)p +Fo(,)k(10)448 1250 y Fn(Cudd)p 649 1250 V 34 w(ReadEpsilon)p +Fo(,)e(10)448 1363 y Fn(Cudd)p 649 1363 V 34 w(ReadErr)l(orCode)p +Fo(,)g(27)448 1476 y Fn(Cudd)p 649 1476 V 34 w(ReadIn)l(vP)-7 +b(erm)p Fo(,)24 b(13)448 1589 y Fn(Cudd)p 649 1589 V +34 w(ReadLo)o(gicZer)l(o)p Fo(,)h(10)448 1702 y Fn(Cudd)p +649 1702 V 34 w(ReadLooseUpto)p Fo(,)g(9)448 1815 y Fn(Cudd)p +649 1815 V 34 w(ReadMaxGr)l(owth)p Fo(,)g(18)448 1928 +y Fn(Cudd)p 649 1928 V 34 w(ReadMinusIn\002nity)p Fo(,)i(10)448 +2041 y Fn(Cudd)p 649 2041 V 34 w(ReadOne)p Fo(,)d(9)448 +2154 y Fn(Cudd)p 649 2154 V 34 w(ReadPlusIn\002nity)p +Fo(,)i(10)448 2267 y Fn(Cudd)p 649 2267 V 34 w(ReadReor)m(derings)p +Fo(,)g(33)448 2379 y Fn(Cudd)p 649 2379 V 34 w(ReadSiftMaxV)-10 +b(ar)p Fo(,)25 b(18)448 2492 y Fn(Cudd)p 649 2492 V 34 +w(ReadT)-5 b(r)m(ee)p Fo(,)24 b(19)448 2605 y Fn(Cudd)p +649 2605 V 34 w(ReadZddOne)p Fo(,)g(9,)f(15)448 2718 +y Fn(Cudd)p 649 2718 V 34 w(ReadZer)l(o)p Fo(,)h(10)448 +2831 y Fn(Cudd)p 649 2831 V 34 w(Recur)o(siveDer)m(ef)p +Fo(,)i(7,)d(26\22628,)h(30,)g(33)448 2944 y Fn(Cudd)p +649 2944 V 34 w(Recur)o(siveDer)m(efZdd)p Fo(,)i(7,)d(26\22628)448 +3057 y Fn(Cudd)p 649 3057 V 34 w(ReduceHeap)p Fo(,)i(17)448 +3170 y Fn(Cudd)p 649 3170 V 34 w(Ref)p Fo(,)e(7,)g(12,)g(26,)g(27)448 +3283 y Fn(Cudd)p 649 3283 V 34 w(Re)l(gular)p Fo(,)i(28)448 +3396 y(CUDD)p 712 3396 V 32 w(REORDER)p 1171 3396 V 30 +w(ANNEALING,)19 b(19)448 3509 y(CUDD)p 712 3509 V 32 +w(REORDER)p 1171 3509 V 30 w(EXA)l(CT)-7 b(,)21 b(19)448 +3621 y(CUDD)p 712 3621 V 32 w(REORDER)p 1171 3621 V 30 +w(GENETIC,)f(19)448 3734 y(CUDD)p 712 3734 V 32 w(REORDER)p +1171 3734 V 30 w(GR)l(OUP)p 1507 3734 V 31 w(SIFT)-7 +b(,)21 b(18)448 3847 y(CUDD)p 712 3847 V 32 w(REORDER)p +1171 3847 V 30 w(GR)l(OUP)p 1507 3847 V 31 w(SIFT)p 1726 +3847 V 31 w(CONV)-12 b(,)780 3960 y(18)448 4073 y(CUDD)p +712 4073 V 32 w(REORDER)p 1171 4073 V 30 w(NONE,)20 b(17,)k(20)448 +4186 y(CUDD)p 712 4186 V 32 w(REORDER)p 1171 4186 V 30 +w(RANDOM,)c(17,)j(20)448 4299 y(CUDD)p 712 4299 V 32 +w(REORDER)p 1171 4299 V 30 w(RANDOM)p 1607 4299 V 30 +w(PIV)l(O)l(T)-7 b(,)780 4412 y(17,)24 b(20)448 4525 +y(CUDD)p 712 4525 V 32 w(REORDER)p 1171 4525 V 30 w(SAME,)d(17,)i(20) +448 4638 y(CUDD)p 712 4638 V 32 w(REORDER)p 1171 4638 +V 30 w(SIFT)-7 b(,)21 b(17,)j(21)448 4751 y(CUDD)p 712 +4751 V 32 w(REORDER)p 1171 4751 V 30 w(SIFT)p 1389 4751 +V 31 w(CONVERGE,)780 4863 y(18,)g(21)448 4976 y(CUDD)p +712 4976 V 32 w(REORDER)p 1171 4976 V 30 w(SYMM)p 1480 +4976 V 31 w(SIFT)-7 b(,)16 b(18,)j(21)p Black Black 1984 +573 a(CUDD)p 2248 573 V 31 w(REORDER)p 2706 573 V 30 +w(SYMM)p 3015 573 V 32 w(SIFT)p 3235 573 V 32 w(CONV)-12 +b(,)2316 686 y(18,)24 b(21)1984 799 y(CUDD)p 2248 799 +V 31 w(REORDER)p 2706 799 V 30 w(WINDO)m(W2,)e(18)1984 +912 y(CUDD)p 2248 912 V 31 w(REORDER)p 2706 912 V 30 +w(WINDO)m(W2)p 3178 912 V 32 w(CONV)-12 b(,)2316 1024 +y(18)1984 1137 y(CUDD)p 2248 1137 V 31 w(REORDER)p 2706 +1137 V 30 w(WINDO)m(W3,)22 b(18)1984 1250 y(CUDD)p 2248 +1250 V 31 w(REORDER)p 2706 1250 V 30 w(WINDO)m(W3)p 3178 +1250 V 32 w(CONV)-12 b(,)2316 1363 y(18)1984 1476 y(CUDD)p +2248 1476 V 31 w(REORDER)p 2706 1476 V 30 w(WINDO)m(W4,)22 +b(18)1984 1589 y(CUDD)p 2248 1589 V 31 w(REORDER)p 2706 +1589 V 30 w(WINDO)m(W4)p 3178 1589 V 32 w(CONV)-12 b(,)2316 +1702 y(19)1984 1815 y Fn(Cudd)p 2185 1815 V 34 w(SetEpsilon)p +Fo(,)25 b(10)1984 1928 y Fn(Cudd)p 2185 1928 V 34 w(SetLooseUpT)-8 +b(o)p Fo(,)24 b(9)1984 2041 y Fn(Cudd)p 2185 2041 V 34 +w(SetMaxCac)o(heHar)m(d)p Fo(,)h(37)1984 2154 y Fn(Cudd)p +2185 2154 V 34 w(SetMaxGr)l(owth)p Fo(,)g(18)1984 2267 +y Fn(Cudd)p 2185 2267 V 34 w(SetSiftMaxV)-10 b(ar)p Fo(,)26 +b(18)1984 2379 y Fn(Cudd)p 2185 2379 V 34 w(SetT)-5 b(imeLimit)p +Fo(,)23 b(22)1984 2492 y Fn(Cudd)p 2185 2492 V 34 w(SetT)-5 +b(r)m(ee)p Fo(,)24 b(19)1984 2605 y Fn(Cudd)p 2185 2605 +V 34 w(Shuf)n(\003eHeap)p Fo(,)i(19)1984 2718 y Fn(Cudd)p +2185 2718 V 34 w(StdP)-7 b(ostReor)m(dHook)p Fo(,)26 +b(22)1984 2831 y Fn(Cudd)p 2185 2831 V 34 w(StdPr)m(eReor)m(dHook)p +Fo(,)f(22)1984 2944 y Fn(Cudd)p 2185 2944 V 34 w(SymmPr)l(o\002le)p +Fo(,)f(18)1984 3057 y(CUDD)p 2248 3057 V 31 w(UNIQ)o(UE)p +2628 3057 V 32 w(SLO)l(TS,)c(8)1984 3170 y Fn(Cudd)p +2185 3170 V 34 w(zddDumpDot)p Fo(,)k(24)1984 3283 y Fn(Cudd)p +2185 3283 V 34 w(zddIsop)p Fo(,)h(15)1984 3396 y Fn(Cudd)p +2185 3396 V 34 w(zddIthV)-10 b(ar)p Fo(,)25 b(12)1984 +3509 y Fn(Cudd)p 2185 3509 V 34 w(zddP)-7 b(ortF)i(r)l(omBdd)p +Fo(,)24 b(16)1984 3621 y Fn(Cudd)p 2185 3621 V 34 w(zddP)-7 +b(ortT)f(oBdd)p Fo(,)24 b(16)1984 3734 y Fn(Cudd)p 2185 +3734 V 34 w(zddRealignDisable)p Fo(,)j(21)1984 3847 y +Fn(Cudd)p 2185 3847 V 34 w(zddRealignEnable)p Fo(,)g(21)1984 +3960 y Fn(Cudd)p 2185 3960 V 34 w(zddReduceHeap)p Fo(,)f(20)1984 +4073 y Fn(Cudd)p 2185 4073 V 34 w(zddShuf)n(\003eHeap)p +Fo(,)h(20)1984 4186 y Fn(Cudd)p 2185 4186 V 34 w(zddV)-10 +b(ar)o(sF)-5 b(r)l(omBddV)-10 b(ar)o(s)p Fo(,)25 b(16)1984 +4299 y Fn(Cudd)p 2185 4299 V 34 w(zddW)-8 b(eakDiv)p +Fo(,)24 b(15)1984 4412 y Fn(cuddCac)o(heInsert)p Fo(,)j(29)1984 +4525 y Fn(cuddCac)o(heInsert1)p Fo(,)h(29)1984 4638 y +Fn(cuddCac)o(heInsert2)p Fo(,)g(29)1984 4751 y Fn(cuddCac)o(heLookup)p +Fo(,)f(29)1984 4863 y Fn(cuddCac)o(heLookup1)p Fo(,)g(29)1984 +4976 y Fn(cuddCac)o(heLookup2)p Fo(,)g(29)p Black 1897 +5225 a(45)p Black eop end +%%Page: 46 46 +TeXDict begin 46 45 bop Black Black 448 573 a Fo(CUDDDIR,)21 +b(22)448 686 y Fn(cuddHeapPr)l(o\002le)p Fo(,)27 b(33)448 +799 y Fn(cuddI)p Fo(,)e(31)448 912 y(cuddInt.h,)h(33)448 +1024 y Fn(cuddIZ)p Fo(,)e(31)448 1137 y Fn(cuddSatDec)p +Fo(,)i(28)448 1250 y Fn(cuddSatInc)p Fo(,)h(28)448 1363 +y Fn(cuddUniqueConst)p Fo(,)g(26)448 1476 y Fn(cuddUniqueInter)p +Fo(,)h(26,)23 b(28,)h(32,)f(33)448 1589 y Fn(cuddUniqueInterZdd)p +Fo(,)28 b(26,)c(32)448 1777 y(DD)p 585 1777 28 4 v 32 +w(CA)l(CHE)p 923 1777 V 31 w(PR)l(OFILE,)d(39)448 1890 +y(DD)p 585 1890 V 32 w(DEB)o(UG,)g(33)448 2003 y(DD)p +585 2003 V 32 w(ST)-8 b(A)e(TS,)20 b(39)448 2116 y(DD)p +585 2116 V 32 w(UNIQ)o(UE)p 966 2116 V 31 w(PR)l(OFILE,)h(39)448 +2229 y(DD)p 585 2229 V 32 w(VERBOSE,)f(39)448 2342 y(DdManager)l(,)25 +b(7,)e(8)448 2455 y(DdNode,)h(6,)f(29)448 2568 y(deb)n(ugging,)k(33)448 +2681 y(DEC)22 b(Alpha,)h(23)448 2793 y(DEC)f(Alpha,)h(10)448 +2906 y(documentation,)k(39)614 3019 y Fn(Description)p +Fo(,)f(40)614 3132 y(HTML)c(\002les,)h(40)614 3245 y +Fn(SeeAlso)p Fo(,)i(40)614 3358 y Fn(Synopsis)p Fo(,)h(40)448 +3471 y(dot,)e Fn(see)g Fo(graph,)g(dra)o(wing)448 3659 +y(Epsilon,)h(10)448 3772 y(e)o(xtdoc,)g Fn(see)f Fo(documentation)448 +3960 y(\003oating)h(point,)f(10)614 4073 y(double)i(\(C)c(type\),)i(7) +614 4186 y(IEEE)e(Standard)j(754,)f(10)448 4299 y(free)g(list,)g(26)448 +4412 y(FTP)-10 b(,)21 b(5,)i(23,)h(39)448 4525 y(function)614 +4638 y(characteristic,)j(4,)c(16)614 4751 y(co)o(v)o(er)l(,)h(15,)g(16) +697 4863 y(irredundant,)j(15)614 4976 y(minterms,)d(11,)g(32)p +Black Black 2150 573 a(ON-set,)f(4)2150 686 y(sum)h(of)f(products,)j +(11)2150 799 y(switching,)f(4)1984 995 y(garbage)g(collection,)h +(7\2269,)e(26,)f(29\22631)2150 1108 y(hooks,)i(21)1984 +1220 y(gcc,)f(10)1984 1333 y(generator)l(,)i(6)1984 1446 +y(global)f(v)n(ariables,)h(7)1984 1559 y(graph)2150 1672 +y(arc)e(capacity)-6 b(,)25 b(10)2150 1785 y(arc)f(length,)h(10)2150 +1898 y(dra)o(wing,)f(24)1984 2011 y(gro)n(wth,)g(9)1984 +2124 y(gzip,)g(5)1984 2320 y(HA)-12 b(VE)p 2231 2320 +V 31 w(IEEE)p 2460 2320 V 32 w(754,)24 b(10)1984 2433 +y(header)h(\002les,)e(17,)h(28)1984 2545 y(hook,)g(21)1984 +2741 y(in\002nities,)h(10)1984 2854 y(installation,)i(5)1984 +2967 y(Intel)e(Pentium)e(4,)g(5)1984 3080 y(interf)o(ace)2150 +3193 y(cache,)i(29)2150 3306 y(SIS,)d(22)2150 3419 y(VIS,)g(22)1984 +3615 y(libraries,)k(5)2150 3728 y(cudd,)e(6)2150 3841 +y(dddmp,)g(24)2150 3954 y(mtr)l(,)f(6,)g(19)2150 4066 +y(obj,)h(40)2150 4179 y(st,)f(6,)g(29)2150 4292 y(util,)h(6)1984 +4488 y(Mak)o(e\002le,)g(6,)f(10,)g(40)1984 4601 y(manager)l(,)i(7,)e(9) +1984 4714 y(matrix)2150 4827 y(sparse,)i(10)1984 4940 +y(maxCache,)f(30)p Black 1897 5225 a(46)p Black eop end +%%Page: 47 47 +TeXDict begin 47 46 bop Black Black 448 573 a Fo(maxMemory)-6 +b(,)24 b(8)448 686 y(MinusIn\002nity)-6 b(,)26 b(10)448 +799 y(MTR)p 651 799 28 4 v 32 w(DEF)-7 b(A)i(UL)d(T)h(,)20 +b(20)448 912 y(MTR)p 651 912 V 32 w(FIXED,)h(19)448 1100 +y(nanotra)n(v)-6 b(,)26 b(5)448 1213 y(node,)e(6)614 +1326 y(constant,)i(6,)d(9\22611,)h(26,)f(27)697 1438 +y(v)n(alue,)h(7)614 1551 y(dead,)g(26,)g(29,)f(31)614 +1664 y(dereference,)k(14)614 1777 y(reclaimed,)e(31)614 +1890 y(rec)o(ycling,)h(7)614 2003 y(reference,)g(14)614 +2116 y(reference)g(count,)f(26)614 2229 y(reference)c(count,)f(6,)f(7,) +g(12,)g(13,)g(26\22630,)780 2342 y(34)697 2455 y(saturated,)26 +b(34)614 2568 y(terminal,)f Fn(see)f Fo(node,)g(constant)614 +2681 y(v)n(ariable)i(inde)o(x,)e(6)448 2793 y(numSlots,)g(8)448 +2906 y(numV)-10 b(ars,)24 b(8)448 3019 y(numV)-10 b(arsZ,)23 +b(8)448 3207 y(PlusIn\002nity)-6 b(,)25 b(10)448 3320 +y(projection)i(functions,)e(11,)f(12,)f(14,)h(15,)f(34)448 +3509 y(README)e(\002le,)h(5)448 3621 y(reordering,)k(4,)d(6,)g(29)614 +3734 y(abort)i(and)f(retry)-6 b(,)24 b(32)614 3847 y(asynchronous,)k +(17,)23 b(32)614 3960 y(con)l(v)o(er)n(ging,)k(17,)d(18)614 +4073 y(Cudd)p 815 4073 V 34 w(ReorderingT)-7 b(ype,)26 +b(17)614 4186 y(dynamic,)f(4,)e(16,)g(20)614 4299 y(e)o(xact,)h(19)614 +4412 y(function)i(wrapper)l(,)f(32,)e(33)614 4525 y(genetic,)i(19)614 +4638 y(group,)g(17,)e(18)614 4751 y(hooks,)i(21)614 4863 +y(interruptible)j(procedure,)d(32)614 4976 y(of)f(BDDs)e(and)i(ADDs,)e +(16)p Black Black 2150 573 a(of)i(ZDDs,)d(15,)j(20)2150 +686 y(random,)g(17)2150 799 y(sifting,)h(17)2150 912 +y(simulated)h(annealing,)f(19)2150 1024 y(symmetric,)g(18)2150 +1137 y(threshold,)h(17,)d(32)2150 1250 y(windo)n(w)-6 +b(,)23 b(18)1984 1446 y(saturating)2150 1559 y(decrements,)j(28)2150 +1672 y(increments,)g(28)1984 1785 y(SISDIR,)c(22)1984 +1898 y(SIZEOF)p 2299 1898 V 31 w(INT)-7 b(,)22 b(28)1984 +2011 y(SIZEOF)p 2299 2011 V 31 w(V)l(OID)p 2554 2011 +V 32 w(P)-10 b(,)22 b(28)1984 2124 y(statistical)k(counters,)g(7,)d(30) +1984 2237 y(statistical)j(counters,)g(26)1984 2350 y(statistics,)g(34) +1984 2462 y(subtable,)g(8,)d(26)1984 2575 y(symmetry)-6 +b(,)24 b(18)1984 2771 y(table)2150 2884 y(computed,)h(8)2150 +2997 y(gro)n(wth,)f(9)2150 3110 y(hash,)g(7,)f(31)2150 +3223 y(unique,)i(6\2269,)f(16,)f(26,)h(30,)f(31)2233 +3336 y(f)o(ast)h(gro)n(wth,)g(31)2233 3449 y(re)n(w)o(ard-based)i +(resizing,)g(31)2233 3562 y(slo)n(w)d(gro)n(wth,)h(32)1984 +3675 y(timeout,)g(22)1984 3870 y(v)n(ariable)2150 3983 +y(groups,)h(19)2150 4096 y(order)l(,)g(6,)e(11)2150 4209 +y(permutation,)j(6,)d(31)2150 4322 y(tree,)h(19,)f(20)1984 +4518 y(ZDD,)e(4,)i(7,)g(12,)h(14,)f(15)1984 4631 y(zero)2150 +4744 y(arithmetic,)i(9,)e(11,)h(15)2150 4857 y(logical,)h(9,)e(15)p +Black 1897 5225 a(47)p Black eop end +%%Page: 48 48 +TeXDict begin 48 47 bop Black Black 448 573 a Fo(Zero-suppressed)22 +b(Binary)d(Decision)h(Diagram,)780 686 y Fn(see)k Fo(ZDD)p +Black Black Black 1897 5225 a(48)p Black eop end +%%Trailer + +userdict /end-hook known{end-hook}if +%%EOF diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllAbs.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllAbs.html new file mode 100644 index 000000000..969b6e6cc --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllAbs.html @@ -0,0 +1,3114 @@ + +cudd package abstract + + + + + +
                +
                AssessPathLength() +
                Chooses the maximum allowable path length of nodes under the + threshold. + +
                BAapplyBias() +
                Finds don't care nodes. + +
                BAmarkNodes() +
                Marks nodes for remapping. + +
                BuildConjuncts() +
                Builds the conjuncts recursively, bottom up. + +
                BuildSubsetBdd() +
                Builds the BDD with nodes labeled with path length less than or equal to maxpath + +
                BuildSubsetBdd() +
                Builds the subset BDD using the heavy branch method. + +
                CheckInTables() +
                Check if the two pairs exist in the table, If any of the + conjuncts do exist, store in the cache and return the corresponding pair. + +
                CheckTablesCacheAndReturn() +
                Check the tables for the existence of pair and return one + combination, cache the result. + +
                ConjunctsFree() +
                Free factors structure + +
                CorrelCleanUp() +
                Frees memory associated with hash table. + +
                CorrelCompare() +
                Compares two hash table entries. + +
                CorrelHash() +
                Hashes a hash table entry. + +
                CountMinterms() +
                Count the number of minterms of each node ina a BDD and + store it in a hash table. + +
                CreateBotDist() +
                Get longest distance of node from constant. + +
                CreateBotDist() +
                Labels each node with the shortest distance from the constant. + +
                CreatePathTable() +
                The outer procedure to label each node with its shortest + distance from the root and constant + +
                CreateTopDist() +
                Labels each node with its shortest distance from the root + +
                Cudd_AddHook() +
                Adds a function to a hook. + +
                Cudd_ApaAdd() +
                Adds two arbitrary precision integers. + +
                Cudd_ApaCompareRatios() +
                Compares the ratios of two arbitrary precision integers to two + unsigned ints. + +
                Cudd_ApaCompare() +
                Compares two arbitrary precision integers. + +
                Cudd_ApaCopy() +
                Makes a copy of an arbitrary precision integer. + +
                Cudd_ApaCountMinterm() +
                Counts the number of minterms of a DD. + +
                Cudd_ApaIntDivision() +
                Divides an arbitrary precision integer by an integer. + +
                Cudd_ApaNumberOfDigits() +
                Finds the number of digits for an arbitrary precision + integer. + +
                Cudd_ApaPowerOfTwo() +
                Sets an arbitrary precision integer to a power of two. + +
                Cudd_ApaPrintDecimal() +
                Prints an arbitrary precision integer in decimal format. + +
                Cudd_ApaPrintDensity() +
                Prints the density of a BDD or ADD using + arbitrary precision arithmetic. + +
                Cudd_ApaPrintExponential() +
                Prints an arbitrary precision integer in exponential format. + +
                Cudd_ApaPrintHex() +
                Prints an arbitrary precision integer in hexadecimal format. + +
                Cudd_ApaPrintMintermExp() +
                Prints the number of minterms of a BDD or ADD in exponential + format using arbitrary precision arithmetic. + +
                Cudd_ApaPrintMinterm() +
                Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic. + +
                Cudd_ApaSetToLiteral() +
                Sets an arbitrary precision integer to a one-digit literal. + +
                Cudd_ApaShiftRight() +
                Shifts right an arbitrary precision integer by one binary + place. + +
                Cudd_ApaShortDivision() +
                Divides an arbitrary precision integer by a digit. + +
                Cudd_ApaSubtract() +
                Subtracts two arbitrary precision integers. + +
                Cudd_AutodynDisableZdd() +
                Disables automatic dynamic reordering of ZDDs. + +
                Cudd_AutodynDisable() +
                Disables automatic dynamic reordering. + +
                Cudd_AutodynEnableZdd() +
                Enables automatic dynamic reordering of ZDDs. + +
                Cudd_AutodynEnable() +
                Enables automatic dynamic reordering of BDDs and ADDs. + +
                Cudd_AverageDistance() +
                Computes the average distance between adjacent nodes. + +
                Cudd_BddToAdd() +
                Converts a BDD to a 0-1 ADD. + +
                Cudd_BddToCubeArray() +
                Builds a positional array from the BDD of a cube. + +
                Cudd_BiasedOverApprox() +
                Extracts a dense superset from a BDD with the biased + underapproximation method. + +
                Cudd_BiasedUnderApprox() +
                Extracts a dense subset from a BDD with the biased + underapproximation method. + +
                Cudd_CProjection() +
                Computes the compatible projection of R w.r.t. cube Y. + +
                Cudd_CheckCube() +
                Checks whether g is the BDD of a cube. + +
                Cudd_CheckKeys() +
                Checks for several conditions that should not occur. + +
                Cudd_CheckZeroRef() +
                Checks the unique table for nodes with non-zero reference + counts. + +
                Cudd_ClassifySupport() +
                Classifies the variables in the support of two DDs. + +
                Cudd_ClearErrorCode() +
                Clear the error code of a manager. + +
                Cudd_CofMinterm() +
                Computes the fraction of minterms in the on-set of all the + positive cofactors of a BDD or ADD. + +
                Cudd_Cofactor() +
                Computes the cofactor of f with respect to g. + +
                Cudd_CountLeaves() +
                Counts the number of leaves in a DD. + +
                Cudd_CountMinterm() +
                Counts the number of minterms of a DD. + +
                Cudd_CountPathsToNonZero() +
                Counts the number of paths to a non-zero terminal of a DD. + +
                Cudd_CountPath() +
                Counts the number of paths of a DD. + +
                Cudd_CubeArrayToBdd() +
                Builds the BDD of a cube from a positional array. + +
                Cudd_DagSize() +
                Counts the number of nodes in a DD. + +
                Cudd_DeadAreCounted() +
                Tells whether dead nodes are counted towards triggering + reordering. + +
                Cudd_DebugCheck() +
                Checks for inconsistencies in the DD heap. + +
                Cudd_Decreasing() +
                Determines whether a BDD is negative unate in a + variable. + +
                Cudd_DelayedDerefBdd() +
                Decreases the reference count of BDD node n. + +
                Cudd_Density() +
                Computes the density of a BDD or ADD. + +
                Cudd_Deref() +
                Decreases the reference count of node. + +
                Cudd_DisableGarbageCollection() +
                Disables garbage collection. + +
                Cudd_DisableOrderingMonitoring() +
                Disables monitoring of ordering. + +
                Cudd_DisableReorderingReporting() +
                Disables reporting of reordering stats. + +
                Cudd_Disequality() +
                Generates a BDD for the function x - y != c. + +
                Cudd_DumpBlifBody() +
                Writes a blif body representing the argument BDDs. + +
                Cudd_DumpBlif() +
                Writes a blif file representing the argument BDDs. + +
                Cudd_DumpDDcal() +
                Writes a DDcal file representing the argument BDDs. + +
                Cudd_DumpDaVinci() +
                Writes a daVinci file representing the argument BDDs. + +
                Cudd_DumpDot() +
                Writes a dot file representing the argument DDs. + +
                Cudd_DumpFactoredForm() +
                Writes factored forms representing the argument BDDs. + +
                Cudd_Dxygtdxz() +
                Generates a BDD for the function d(x,y) > d(x,z). + +
                Cudd_Dxygtdyz() +
                Generates a BDD for the function d(x,y) > d(y,z). + +
                Cudd_EnableGarbageCollection() +
                Enables garbage collection. + +
                Cudd_EnableOrderingMonitoring() +
                Enables monitoring of ordering. + +
                Cudd_EnableReorderingReporting() +
                Enables reporting of reordering stats. + +
                Cudd_EpdCountMinterm() +
                Counts the number of minterms of a DD with extended precision. + +
                Cudd_EqualSupNorm() +
                Compares two ADDs for equality within tolerance. + +
                Cudd_EquivDC() +
                Tells whether F and G are identical wherever D is 0. + +
                Cudd_EstimateCofactorSimple() +
                Estimates the number of nodes in a cofactor of a DD. + +
                Cudd_EstimateCofactor() +
                Estimates the number of nodes in a cofactor of a DD. + +
                Cudd_Eval() +
                Returns the value of a DD for a given variable assignment. + +
                Cudd_ExpectedUsedSlots() +
                Computes the expected fraction of used slots in the unique + table. + +
                Cudd_FindEssential() +
                Finds the essential variables of a DD. + +
                Cudd_FindTwoLiteralClauses() +
                Finds the two literal clauses of a DD. + +
                Cudd_FirstCube() +
                Finds the first cube of a decision diagram. + +
                Cudd_FirstNode() +
                Finds the first node of a decision diagram. + +
                Cudd_FirstPrime() +
                Finds the first prime of a Boolean function. + +
                Cudd_FreeTree() +
                Frees the variable group tree of the manager. + +
                Cudd_FreeZddTree() +
                Frees the variable group tree of the manager. + +
                Cudd_GarbageCollectionEnabled() +
                Tells whether garbage collection is enabled. + +
                Cudd_GenFree() +
                Frees a CUDD generator. + +
                Cudd_IncreaseTimeLimit() +
                Increases the time limit for the manager. + +
                Cudd_Increasing() +
                Determines whether a BDD is positive unate in a + variable. + +
                Cudd_IndicesToCube() +
                Builds a cube of BDD variables from an array of indices. + +
                Cudd_Inequality() +
                Generates a BDD for the function x - y ≥ c. + +
                Cudd_Init() +
                Creates a new DD manager. + +
                Cudd_IsGenEmpty() +
                Queries the status of a generator. + +
                Cudd_IsInHook() +
                Checks whether a function is in a hook. + +
                Cudd_IsNonConstant() +
                Returns 1 if a DD node is not constant. + +
                Cudd_IterDerefBdd() +
                Decreases the reference count of BDD node n. + +
                Cudd_LargestCube() +
                Finds a largest cube in a DD. + +
                Cudd_MakeBddFromZddCover() +
                Converts a ZDD cover to a BDD. + +
                Cudd_MakeTreeNode() +
                Creates a new variable group. + +
                Cudd_MakeZddTreeNode() +
                Creates a new ZDD variable group. + +
                Cudd_MinHammingDist() +
                Returns the minimum Hamming distance between f and minterm. + +
                Cudd_NewApaNumber() +
                Allocates memory for an arbitrary precision integer. + +
                Cudd_NextCube() +
                Generates the next cube of a decision diagram onset. + +
                Cudd_NextNode() +
                Finds the next node of a decision diagram. + +
                Cudd_NextPrime() +
                Generates the next prime of a Boolean function. + +
                Cudd_NodeReadIndex() +
                Returns the index of the node. + +
                Cudd_OrderingMonitoring() +
                Returns 1 if monitoring of ordering is enabled. + +
                Cudd_OutOfMem() +
                Warns that a memory allocation failed. + +
                Cudd_OverApprox() +
                Extracts a dense superset from a BDD with Shiple's + underapproximation method. + +
                Cudd_Prime() +
                Returns the next prime >= p. + +
                Cudd_PrintDebug() +
                Prints to the standard output a DD and its statistics. + +
                Cudd_PrintGroupedOrder() +
                Hook function to print the current variable order. + +
                Cudd_PrintInfo() +
                Prints out statistics and settings for a CUDD manager. + +
                Cudd_PrintLinear() +
                Prints the linear transform matrix. + +
                Cudd_PrintMinterm() +
                Prints a disjoint sum of products. + +
                Cudd_PrintTwoLiteralClauses() +
                Prints the two literal clauses of a DD. + +
                Cudd_PrintVersion() +
                Prints the package version number. + +
                Cudd_PrioritySelect() +
                Selects pairs from R using a priority function. + +
                Cudd_Quit() +
                Deletes resources associated with a DD manager. + +
                Cudd_Random() +
                Portable random number generator. + +
                Cudd_ReadArcviolation() +
                Returns the current value of the arcviolation parameter used + in group sifting. + +
                Cudd_ReadBackground() +
                Reads the background constant of the manager. + +
                Cudd_ReadCacheHits() +
                Returns the number of cache hits. + +
                Cudd_ReadCacheLookUps() +
                Returns the number of cache look-ups. + +
                Cudd_ReadCacheSlots() +
                Reads the number of slots in the cache. + +
                Cudd_ReadCacheUsedSlots() +
                Reads the fraction of used slots in the cache. + +
                Cudd_ReadDead() +
                Returns the number of dead nodes in the unique table. + +
                Cudd_ReadElapsedTime() +
                Returns the time elapsed since the start time of the manager. + +
                Cudd_ReadEpsilon() +
                Reads the epsilon parameter of the manager. + +
                Cudd_ReadErrorCode() +
                Returns the code of the last error. + +
                Cudd_ReadGarbageCollectionTime() +
                Returns the time spent in garbage collection. + +
                Cudd_ReadGarbageCollections() +
                Returns the number of times garbage collection has occurred. + +
                Cudd_ReadGroupcheck() +
                Reads the groupcheck parameter of the manager. + +
                Cudd_ReadInvPermZdd() +
                Returns the index of the ZDD variable currently in the i-th + position of the order. + +
                Cudd_ReadInvPerm() +
                Returns the index of the variable currently in the i-th + position of the order. + +
                Cudd_ReadIthClause() +
                Accesses the i-th clause of a DD. + +
                Cudd_ReadKeys() +
                Returns the number of nodes in the unique table. + +
                Cudd_ReadLinear() +
                Reads an entry of the linear transform matrix. + +
                Cudd_ReadLogicZero() +
                Returns the logic zero constant of the manager. + +
                Cudd_ReadLooseUpTo() +
                Reads the looseUpTo parameter of the manager. + +
                Cudd_ReadMaxCacheHard() +
                Reads the maxCacheHard parameter of the manager. + +
                Cudd_ReadMaxCache() +
                Returns the soft limit for the cache size. + +
                Cudd_ReadMaxGrowthAlternate() +
                Reads the maxGrowthAlt parameter of the manager. + +
                Cudd_ReadMaxGrowth() +
                Reads the maxGrowth parameter of the manager. + +
                Cudd_ReadMaxLive() +
                Reads the maximum allowed number of live nodes. + +
                Cudd_ReadMaxMemory() +
                Reads the maximum allowed memory. + +
                Cudd_ReadMaxReorderings() +
                Returns the maximum number of times reordering may be invoked. + +
                Cudd_ReadMemoryInUse() +
                Returns the memory in use by the manager measured in bytes. + +
                Cudd_ReadMinDead() +
                Reads the minDead parameter of the manager. + +
                Cudd_ReadMinHit() +
                Reads the hit rate that causes resizinig of the computed + table. + +
                Cudd_ReadMinusInfinity() +
                Reads the minus-infinity constant from the manager. + +
                Cudd_ReadNextReordering() +
                Returns the threshold for the next dynamic reordering. + +
                Cudd_ReadNodeCount() +
                Reports the number of nodes in BDDs and ADDs. + +
                Cudd_ReadNodesDropped() +
                Returns the number of nodes dropped. + +
                Cudd_ReadNodesFreed() +
                Returns the number of nodes freed. + +
                Cudd_ReadNumberXovers() +
                Reads the current number of crossovers used by the + genetic algorithm for reordering. + +
                Cudd_ReadOne() +
                Returns the one constant of the manager. + +
                Cudd_ReadOrderRandomization() +
                Returns the order randomization factor. + +
                Cudd_ReadPeakLiveNodeCount() +
                Reports the peak number of live nodes. + +
                Cudd_ReadPeakNodeCount() +
                Reports the peak number of nodes. + +
                Cudd_ReadPermZdd() +
                Returns the current position of the i-th ZDD variable in the + order. + +
                Cudd_ReadPerm() +
                Returns the current position of the i-th variable in the + order. + +
                Cudd_ReadPlusInfinity() +
                Reads the plus-infinity constant from the manager. + +
                Cudd_ReadPopulationSize() +
                Reads the current size of the population used by the + genetic algorithm for reordering. + +
                Cudd_ReadRecomb() +
                Returns the current value of the recombination parameter used + in group sifting. + +
                Cudd_ReadRecursiveCalls() +
                Returns the number of recursive calls. + +
                Cudd_ReadReorderingCycle() +
                Reads the reordCycle parameter of the manager. + +
                Cudd_ReadReorderingTime() +
                Returns the time spent in reordering. + +
                Cudd_ReadReorderings() +
                Returns the number of times reordering has occurred. + +
                Cudd_ReadSiftMaxSwap() +
                Reads the siftMaxSwap parameter of the manager. + +
                Cudd_ReadSiftMaxVar() +
                Reads the siftMaxVar parameter of the manager. + +
                Cudd_ReadSize() +
                Returns the number of BDD variables in existance. + +
                Cudd_ReadSlots() +
                Returns the total number of slots of the unique table. + +
                Cudd_ReadStartTime() +
                Returns the start time of the manager. + +
                Cudd_ReadStderr() +
                Reads the stderr of a manager. + +
                Cudd_ReadStdout() +
                Reads the stdout of a manager. + +
                Cudd_ReadSwapSteps() +
                Reads the number of elementary reordering steps. + +
                Cudd_ReadSymmviolation() +
                Returns the current value of the symmviolation parameter used + in group sifting. + +
                Cudd_ReadTimeLimit() +
                Returns the time limit for the manager. + +
                Cudd_ReadTree() +
                Returns the variable group tree of the manager. + +
                Cudd_ReadUniqueLinks() +
                Returns the number of links followed in the unique table. + +
                Cudd_ReadUniqueLookUps() +
                Returns the number of look-ups in the unique table. + +
                Cudd_ReadUsedSlots() +
                Reads the fraction of used slots in the unique table. + +
                Cudd_ReadVars() +
                Returns the i-th element of the vars array. + +
                Cudd_ReadZddOne() +
                Returns the ZDD for the constant 1 function. + +
                Cudd_ReadZddSize() +
                Returns the number of ZDD variables in existance. + +
                Cudd_ReadZddTree() +
                Returns the variable group tree of the manager. + +
                Cudd_ReadZero() +
                Returns the zero constant of the manager. + +
                Cudd_RecursiveDerefZdd() +
                Decreases the reference count of ZDD node n. + +
                Cudd_RecursiveDeref() +
                Decreases the reference count of node n. + +
                Cudd_ReduceHeap() +
                Main dynamic reordering routine. + +
                Cudd_Ref() +
                Increases the reference count of a node, if it is not + saturated. + +
                Cudd_RemapOverApprox() +
                Extracts a dense superset from a BDD with the remapping + underapproximation method. + +
                Cudd_RemapUnderApprox() +
                Extracts a dense subset from a BDD with the remapping + underapproximation method. + +
                Cudd_RemoveHook() +
                Removes a function from a hook. + +
                Cudd_ReorderingReporting() +
                Returns 1 if reporting of reordering stats is enabled. + +
                Cudd_ReorderingStatusZdd() +
                Reports the status of automatic dynamic reordering of ZDDs. + +
                Cudd_ReorderingStatus() +
                Reports the status of automatic dynamic reordering of BDDs + and ADDs. + +
                Cudd_Reserve() +
                Expand manager without creating variables. + +
                Cudd_ResetStartTime() +
                Resets the start time of the manager. + +
                Cudd_SetArcviolation() +
                Sets the value of the arcviolation parameter used + in group sifting. + +
                Cudd_SetBackground() +
                Sets the background constant of the manager. + +
                Cudd_SetEpsilon() +
                Sets the epsilon parameter of the manager to ep. + +
                Cudd_SetGroupcheck() +
                Sets the parameter groupcheck of the manager to gc. + +
                Cudd_SetLooseUpTo() +
                Sets the looseUpTo parameter of the manager. + +
                Cudd_SetMaxCacheHard() +
                Sets the maxCacheHard parameter of the manager. + +
                Cudd_SetMaxGrowthAlternate() +
                Sets the maxGrowthAlt parameter of the manager. + +
                Cudd_SetMaxGrowth() +
                Sets the maxGrowth parameter of the manager. + +
                Cudd_SetMaxLive() +
                Sets the maximum allowed number of live nodes. + +
                Cudd_SetMaxMemory() +
                Sets the maximum allowed memory. + +
                Cudd_SetMaxReorderings() +
                Sets the maximum number of times reordering may be invoked. + +
                Cudd_SetMinHit() +
                Sets the hit rate that causes resizinig of the computed + table. + +
                Cudd_SetNextReordering() +
                Sets the threshold for the next dynamic reordering. + +
                Cudd_SetNumberXovers() +
                Sets the number of crossovers used by the + genetic algorithm for reordering. + +
                Cudd_SetOrderRandomization() +
                Sets the order randomization factor. + +
                Cudd_SetPopulationSize() +
                Sets the size of the population used by the + genetic algorithm for reordering. + +
                Cudd_SetRecomb() +
                Sets the value of the recombination parameter used in group + sifting. + +
                Cudd_SetReorderingCycle() +
                Sets the reordCycle parameter of the manager. + +
                Cudd_SetSiftMaxSwap() +
                Sets the siftMaxSwap parameter of the manager. + +
                Cudd_SetSiftMaxVar() +
                Sets the siftMaxVar parameter of the manager. + +
                Cudd_SetStartTime() +
                Sets the start time of the manager. + +
                Cudd_SetStderr() +
                Sets the stderr of a manager. + +
                Cudd_SetStdout() +
                Sets the stdout of a manager. + +
                Cudd_SetSymmviolation() +
                Sets the value of the symmviolation parameter used + in group sifting. + +
                Cudd_SetTimeLimit() +
                Sets the time limit for the manager. + +
                Cudd_SetTree() +
                Sets the variable group tree of the manager. + +
                Cudd_SetVarMap() +
                Registers a variable mapping with the manager. + +
                Cudd_SetZddTree() +
                Sets the ZDD variable group tree of the manager. + +
                Cudd_SharingSize() +
                Counts the number of nodes in an array of DDs. + +
                Cudd_ShortestLength() +
                Find the length of the shortest path(s) in a DD. + +
                Cudd_ShortestPath() +
                Finds a shortest path in a DD. + +
                Cudd_ShuffleHeap() +
                Reorders variables according to given permutation. + +
                Cudd_SolveEqn() +
                Implements the solution of F(x,y) = 0. + +
                Cudd_SplitSet() +
                Returns m minterms from a BDD. + +
                Cudd_Srandom() +
                Initializer for the portable random number generator. + +
                Cudd_StdPostReordHook() +
                Sample hook function to call after reordering. + +
                Cudd_StdPreReordHook() +
                Sample hook function to call before reordering. + +
                Cudd_SubsetCompress() +
                Find a dense subset of BDD f. + +
                Cudd_SubsetHeavyBranch() +
                Extracts a dense subset from a BDD with the heavy branch + heuristic. + +
                Cudd_SubsetShortPaths() +
                Extracts a dense subset from a BDD with the shortest paths + heuristic. + +
                Cudd_SubsetWithMaskVars() +
                Extracts a subset from a BDD. + +
                Cudd_SupersetCompress() +
                Find a dense superset of BDD f. + +
                Cudd_SupersetHeavyBranch() +
                Extracts a dense superset from a BDD with the heavy branch + heuristic. + +
                Cudd_SupersetShortPaths() +
                Extracts a dense superset from a BDD with the shortest paths + heuristic. + +
                Cudd_SupportIndex() +
                Finds the variables on which a DD depends. + +
                Cudd_SupportIndices() +
                Finds the variables on which a DD depends. + +
                Cudd_SupportSize() +
                Counts the variables on which a DD depends. + +
                Cudd_Support() +
                Finds the variables on which a DD depends. + +
                Cudd_SymmProfile() +
                Prints statistics on symmetric variables. + +
                Cudd_TimeLimited() +
                Returns true if the time limit for the manager is set. + +
                Cudd_TurnOffCountDead() +
                Causes the dead nodes not to be counted towards triggering + reordering. + +
                Cudd_TurnOnCountDead() +
                Causes the dead nodes to be counted towards triggering + reordering. + +
                Cudd_UnderApprox() +
                Extracts a dense subset from a BDD with Shiple's + underapproximation method. + +
                Cudd_UnsetTimeLimit() +
                Unsets the time limit for the manager. + +
                Cudd_UpdateTimeLimit() +
                Updates the time limit for the manager. + +
                Cudd_VectorSupportIndex() +
                Finds the variables on which a set of DDs depends. + +
                Cudd_VectorSupportIndices() +
                Finds the variables on which a set of DDs depends. + +
                Cudd_VectorSupportSize() +
                Counts the variables on which a set of DDs depends. + +
                Cudd_VectorSupport() +
                Finds the variables on which a set of DDs depends. + +
                Cudd_VerifySol() +
                Checks the solution of F(x,y) = 0. + +
                Cudd_Xeqy() +
                Generates a BDD for the function x==y. + +
                Cudd_Xgty() +
                Generates a BDD for the function x > y. + +
                Cudd_addAgreement() +
                f if f==g; background if f!=g. + +
                Cudd_addApply() +
                Applies op to the corresponding discriminants of f and g. + +
                Cudd_addBddInterval() +
                Converts an ADD to a BDD. + +
                Cudd_addBddIthBit() +
                Converts an ADD to a BDD by extracting the i-th bit from + the leaves. + +
                Cudd_addBddPattern() +
                Converts an ADD to a BDD. + +
                Cudd_addBddStrictThreshold() +
                Converts an ADD to a BDD. + +
                Cudd_addBddThreshold() +
                Converts an ADD to a BDD. + +
                Cudd_addCmpl() +
                Computes the complement of an ADD a la C language. + +
                Cudd_addCompose() +
                Substitutes g for x_v in the ADD for f. + +
                Cudd_addComputeCube() +
                Computes the cube of an array of ADD variables. + +
                Cudd_addConstrain() +
                Computes f constrain c for ADDs. + +
                Cudd_addConst() +
                Returns the ADD for constant c. + +
                Cudd_addDiff() +
                Returns plusinfinity if f=g; returns min(f,g) if f!=g. + +
                Cudd_addDivide() +
                Integer and floating point division. + +
                Cudd_addEvalConst() +
                Checks whether ADD g is constant whenever ADD f is 1. + +
                Cudd_addExistAbstract() +
                Existentially Abstracts all the variables in cube from f. + +
                Cudd_addFindMax() +
                Finds the maximum discriminant of f. + +
                Cudd_addFindMin() +
                Finds the minimum discriminant of f. + +
                Cudd_addGeneralVectorCompose() +
                Composes an ADD with a vector of ADDs. + +
                Cudd_addHamming() +
                Computes the Hamming distance ADD. + +
                Cudd_addHarwell() +
                Reads in a matrix in the format of the Harwell-Boeing + benchmark suite. + +
                Cudd_addIteConstant() +
                Implements ITEconstant for ADDs. + +
                Cudd_addIte() +
                Implements ITE(f,g,h). + +
                Cudd_addIthBit() +
                Extracts the i-th bit from an ADD. + +
                Cudd_addIthVar() +
                Returns the ADD variable with index i. + +
                Cudd_addLeq() +
                Determines whether f is less than or equal to g. + +
                Cudd_addLog() +
                Natural logarithm of an ADD. + +
                Cudd_addMatrixMultiply() +
                Calculates the product of two matrices represented as + ADDs. + +
                Cudd_addMaximum() +
                Integer and floating point max. + +
                Cudd_addMinimum() +
                Integer and floating point min. + +
                Cudd_addMinus() +
                Integer and floating point subtraction. + +
                Cudd_addMonadicApply() +
                Applies op to the discriminants of f. + +
                Cudd_addNand() +
                NAND of two 0-1 ADDs. + +
                Cudd_addNegate() +
                Computes the additive inverse of an ADD. + +
                Cudd_addNewVarAtLevel() +
                Returns a new ADD variable at a specified level. + +
                Cudd_addNewVar() +
                Returns a new ADD variable. + +
                Cudd_addNonSimCompose() +
                Composes an ADD with a vector of 0-1 ADDs. + +
                Cudd_addNor() +
                NOR of two 0-1 ADDs. + +
                Cudd_addOneZeroMaximum() +
                Returns 1 if f > g and 0 otherwise. + +
                Cudd_addOrAbstract() +
                Disjunctively abstracts all the variables in cube from the + 0-1 ADD f. + +
                Cudd_addOr() +
                Disjunction of two 0-1 ADDs. + +
                Cudd_addOuterSum() +
                Takes the minimum of a matrix and the outer sum of two vectors. + +
                Cudd_addPermute() +
                Permutes the variables of an ADD. + +
                Cudd_addPlus() +
                Integer and floating point addition. + +
                Cudd_addRead() +
                Reads in a sparse matrix. + +
                Cudd_addResidue() +
                Builds an ADD for the residue modulo m of an n-bit + number. + +
                Cudd_addRestrict() +
                ADD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
                Cudd_addRoundOff() +
                Rounds off the discriminants of an ADD. + +
                Cudd_addScalarInverse() +
                Computes the scalar inverse of an ADD. + +
                Cudd_addSetNZ() +
                This operator sets f to the value of g wherever g != 0. + +
                Cudd_addSwapVariables() +
                Swaps two sets of variables of the same size (x and y) in + the ADD f. + +
                Cudd_addThreshold() +
                f if f>=g; 0 if f<g. + +
                Cudd_addTimesPlus() +
                Calculates the product of two matrices represented as + ADDs. + +
                Cudd_addTimes() +
                Integer and floating point multiplication. + +
                Cudd_addTriangle() +
                Performs the triangulation step for the shortest path + computation. + +
                Cudd_addUnivAbstract() +
                Universally Abstracts all the variables in cube from f. + +
                Cudd_addVectorCompose() +
                Composes an ADD with a vector of 0-1 ADDs. + +
                Cudd_addWalsh() +
                Generates a Walsh matrix in ADD form. + +
                Cudd_addXeqy() +
                Generates an ADD for the function x==y. + +
                Cudd_addXnor() +
                XNOR of two 0-1 ADDs. + +
                Cudd_addXor() +
                XOR of two 0-1 ADDs. + +
                Cudd_bddAdjPermuteX() +
                Rearranges a set of variables in the BDD B. + +
                Cudd_bddAndAbstractLimit() +
                Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. Returns NULL if too many nodes are required. + +
                Cudd_bddAndAbstract() +
                Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                Cudd_bddAndLimit() +
                Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                Cudd_bddAnd() +
                Computes the conjunction of two BDDs f and g. + +
                Cudd_bddApproxConjDecomp() +
                Performs two-way conjunctive decomposition of a BDD. + +
                Cudd_bddApproxDisjDecomp() +
                Performs two-way disjunctive decomposition of a BDD. + +
                Cudd_bddBindVar() +
                Prevents sifting of a variable. + +
                Cudd_bddBooleanDiff() +
                Computes the boolean difference of f with respect to x. + +
                Cudd_bddCharToVect() +
                Computes a vector whose image equals a non-zero function. + +
                Cudd_bddClippingAndAbstract() +
                Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
                Cudd_bddClippingAnd() +
                Approximates the conjunction of two BDDs f and g. + +
                Cudd_bddClosestCube() +
                Finds a cube of f at minimum Hamming distance from g. + +
                Cudd_bddCompose() +
                Substitutes g for x_v in the BDD for f. + +
                Cudd_bddComputeCube() +
                Computes the cube of an array of BDD variables. + +
                Cudd_bddConstrainDecomp() +
                BDD conjunctive decomposition as in McMillan's CAV96 paper. + +
                Cudd_bddConstrain() +
                Computes f constrain c. + +
                Cudd_bddCorrelationWeights() +
                Computes the correlation of f and g for given input + probabilities. + +
                Cudd_bddCorrelation() +
                Computes the correlation of f and g. + +
                Cudd_bddExistAbstractLimit() +
                Existentially abstracts all the variables in cube from f. + +
                Cudd_bddExistAbstract() +
                Existentially abstracts all the variables in cube from f. + +
                Cudd_bddGenConjDecomp() +
                Performs two-way conjunctive decomposition of a BDD. + +
                Cudd_bddGenDisjDecomp() +
                Performs two-way disjunctive decomposition of a BDD. + +
                Cudd_bddIntersect() +
                Returns a function included in the intersection of f and g. + +
                Cudd_bddInterval() +
                Generates a BDD for the function lowerB ≤ x ≤ upperB. + +
                Cudd_bddIsNsVar() +
                Checks whether a variable is next state. + +
                Cudd_bddIsPiVar() +
                Checks whether a variable is primary input. + +
                Cudd_bddIsPsVar() +
                Checks whether a variable is present state. + +
                Cudd_bddIsVarEssential() +
                Determines whether a given variable is essential with a + given phase in a BDD. + +
                Cudd_bddIsVarHardGroup() +
                Checks whether a variable is set to be in a hard group. + +
                Cudd_bddIsVarToBeGrouped() +
                Checks whether a variable is set to be grouped. + +
                Cudd_bddIsVarToBeUngrouped() +
                Checks whether a variable is set to be ungrouped. + +
                Cudd_bddIsop() +
                Computes a BDD in the interval between L and U with a + simple sum-of-product cover. + +
                Cudd_bddIteConstant() +
                Implements ITEconstant(f,g,h). + +
                Cudd_bddIteLimit() +
                Implements ITE(f,g,h). Returns + NULL if too many nodes are required. + +
                Cudd_bddIterConjDecomp() +
                Performs two-way conjunctive decomposition of a BDD. + +
                Cudd_bddIterDisjDecomp() +
                Performs two-way disjunctive decomposition of a BDD. + +
                Cudd_bddIte() +
                Implements ITE(f,g,h). + +
                Cudd_bddIthVar() +
                Returns the BDD variable with index i. + +
                Cudd_bddLICompaction() +
                Performs safe minimization of a BDD. + +
                Cudd_bddLargestPrimeUnate() +
                Find a largest prime of a unate function. + +
                Cudd_bddLeqUnless() +
                Tells whether f is less than of equal to G unless D is 1. + +
                Cudd_bddLeq() +
                Determines whether f is less than or equal to g. + +
                Cudd_bddLiteralSetIntersection() +
                Computes the intesection of two sets of literals + represented as BDDs. + +
                Cudd_bddMakePrime() +
                Expands cube to a prime implicant of f. + +
                Cudd_bddMaximallyExpand() +
                Expands lb to prime implicants of (f and ub). + +
                Cudd_bddMinimize() +
                Finds a small BDD that agrees with f over + c. + +
                Cudd_bddNPAnd() +
                Computes f non-polluting-and g. + +
                Cudd_bddNand() +
                Computes the NAND of two BDDs f and g. + +
                Cudd_bddNewVarAtLevel() +
                Returns a new BDD variable at a specified level. + +
                Cudd_bddNewVar() +
                Returns a new BDD variable. + +
                Cudd_bddNor() +
                Computes the NOR of two BDDs f and g. + +
                Cudd_bddOrLimit() +
                Computes the disjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                Cudd_bddOr() +
                Computes the disjunction of two BDDs f and g. + +
                Cudd_bddPermute() +
                Permutes the variables of a BDD. + +
                Cudd_bddPickArbitraryMinterms() +
                Picks k on-set minterms evenly distributed from given DD. + +
                Cudd_bddPickOneCube() +
                Picks one on-set cube randomly from the given DD. + +
                Cudd_bddPickOneMinterm() +
                Picks one on-set minterm randomly from the given DD. + +
                Cudd_bddPrintCover() +
                Prints a sum of prime implicants of a BDD. + +
                Cudd_bddReadPairIndex() +
                Reads a corresponding pair index for a given index. + +
                Cudd_bddRead() +
                Reads in a graph (without labels) given as a list of arcs. + +
                Cudd_bddRealignDisable() +
                Disables realignment of ZDD order to BDD order. + +
                Cudd_bddRealignEnable() +
                Enables realignment of BDD order to ZDD order. + +
                Cudd_bddRealignmentEnabled() +
                Tells whether the realignment of BDD order to ZDD order is + enabled. + +
                Cudd_bddResetVarToBeGrouped() +
                Resets a variable not to be grouped. + +
                Cudd_bddRestrict() +
                BDD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
                Cudd_bddSetNsVar() +
                Sets a variable type to next state. + +
                Cudd_bddSetPairIndex() +
                Sets a corresponding pair index for a given index. + +
                Cudd_bddSetPiVar() +
                Sets a variable type to primary input. + +
                Cudd_bddSetPsVar() +
                Sets a variable type to present state. + +
                Cudd_bddSetVarHardGroup() +
                Sets a variable to be a hard group. + +
                Cudd_bddSetVarToBeGrouped() +
                Sets a variable to be grouped. + +
                Cudd_bddSetVarToBeUngrouped() +
                Sets a variable to be ungrouped. + +
                Cudd_bddSqueeze() +
                Finds a small BDD in a function interval. + +
                Cudd_bddSwapVariables() +
                Swaps two sets of variables of the same size (x and y) in + the BDD f. + +
                Cudd_bddTransfer() +
                Convert a BDD from a manager to another one. + +
                Cudd_bddUnbindVar() +
                Allows the sifting of a variable. + +
                Cudd_bddUnivAbstract() +
                Universally abstracts all the variables in cube from f. + +
                Cudd_bddVarConjDecomp() +
                Performs two-way conjunctive decomposition of a BDD. + +
                Cudd_bddVarDisjDecomp() +
                Performs two-way disjunctive decomposition of a BDD. + +
                Cudd_bddVarIsBound() +
                Tells whether a variable can be sifted. + +
                Cudd_bddVarIsDependent() +
                Checks whether a variable is dependent on others in a + function. + +
                Cudd_bddVarMap() +
                Remaps the variables of a BDD using the default variable map. + +
                Cudd_bddVectorCompose() +
                Composes a BDD with a vector of BDDs. + +
                Cudd_bddXnorLimit() +
                Computes the exclusive NOR of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                Cudd_bddXnor() +
                Computes the exclusive NOR of two BDDs f and g. + +
                Cudd_bddXorExistAbstract() +
                Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
                Cudd_bddXor() +
                Computes the exclusive OR of two BDDs f and g. + +
                Cudd_tlcInfoFree() +
                Frees a DdTlcInfo Structure. + +
                Cudd_zddChange() +
                Substitutes a variable with its complement in a ZDD. + +
                Cudd_zddComplement() +
                Computes a complement cover for a ZDD node. + +
                Cudd_zddCountDouble() +
                Counts the number of minterms of a ZDD. + +
                Cudd_zddCountMinterm() +
                Counts the number of minterms of a ZDD. + +
                Cudd_zddCount() +
                Counts the number of minterms in a ZDD. + +
                Cudd_zddCoverPathToString() +
                Converts a path of a ZDD representing a cover to a string. + +
                Cudd_zddDagSize() +
                Counts the number of nodes in a ZDD. + +
                Cudd_zddDiffConst() +
                Performs the inclusion test for ZDDs (P implies Q). + +
                Cudd_zddDiff() +
                Computes the difference of two ZDDs. + +
                Cudd_zddDivideF() +
                Modified version of Cudd_zddDivide. + +
                Cudd_zddDivide() +
                Computes the quotient of two unate covers. + +
                Cudd_zddDumpDot() +
                Writes a dot file representing the argument ZDDs. + +
                Cudd_zddFirstPath() +
                Finds the first path of a ZDD. + +
                Cudd_zddIntersect() +
                Computes the intersection of two ZDDs. + +
                Cudd_zddIsop() +
                Computes an ISOP in ZDD form from BDDs. + +
                Cudd_zddIte() +
                Computes the ITE of three ZDDs. + +
                Cudd_zddIthVar() +
                Returns the ZDD variable with index i. + +
                Cudd_zddNextPath() +
                Generates the next path of a ZDD. + +
                Cudd_zddPortFromBdd() +
                Converts a BDD into a ZDD. + +
                Cudd_zddPortToBdd() +
                Converts a ZDD into a BDD. + +
                Cudd_zddPrintCover() +
                Prints a sum of products from a ZDD representing a cover. + +
                Cudd_zddPrintDebug() +
                Prints to the standard output a ZDD and its statistics. + +
                Cudd_zddPrintMinterm() +
                Prints a disjoint sum of product form for a ZDD. + +
                Cudd_zddPrintSubtable() +
                Prints the ZDD table. + +
                Cudd_zddProduct() +
                Computes the product of two covers represented by ZDDs. + +
                Cudd_zddReadNodeCount() +
                Reports the number of nodes in ZDDs. + +
                Cudd_zddRealignDisable() +
                Disables realignment of ZDD order to BDD order. + +
                Cudd_zddRealignEnable() +
                Enables realignment of ZDD order to BDD order. + +
                Cudd_zddRealignmentEnabled() +
                Tells whether the realignment of ZDD order to BDD order is + enabled. + +
                Cudd_zddReduceHeap() +
                Main dynamic reordering routine for ZDDs. + +
                Cudd_zddShuffleHeap() +
                Reorders ZDD variables according to given permutation. + +
                Cudd_zddSubset0() +
                Computes the negative cofactor of a ZDD w.r.t. a variable. + +
                Cudd_zddSubset1() +
                Computes the positive cofactor of a ZDD w.r.t. a variable. + +
                Cudd_zddSupport() +
                Finds the variables on which a ZDD depends. + +
                Cudd_zddSymmProfile() +
                Prints statistics on symmetric ZDD variables. + +
                Cudd_zddUnateProduct() +
                Computes the product of two unate covers. + +
                Cudd_zddUnion() +
                Computes the union of two ZDDs. + +
                Cudd_zddVarsFromBddVars() +
                Creates one or more ZDD variables for each BDD variable. + +
                Cudd_zddWeakDivF() +
                Modified version of Cudd_zddWeakDiv. + +
                Cudd_zddWeakDiv() +
                Applies weak division to two covers. + +
                MarkCacheCleanUp() +
                Frees memory associated with computed table of + cuddBddLICMarkEdges. + +
                MarkCacheCompare() +
                Comparison function for the computed table of + cuddBddLICMarkEdges. + +
                MarkCacheHash() +
                Hash function for the computed table of cuddBddLICMarkEdges. + +
                PMX() +
                Performs the crossover between two parents. + +
                PairInTables() +
                Check whether the given pair is in the tables. + +
                PickOnePair() +
                Check the tables for the existence of pair and return one + combination, store in cache. + +
                RAbuildSubset() +
                Builds the subset BDD for cuddRemapUnderApprox. + +
                RAmarkNodes() +
                Marks nodes for remapping. + +
                ResizeCountMintermPages() +
                Resize the number of pages allocated to store the minterm + counts. + +
                ResizeCountNodePages() +
                Resize the number of pages allocated to store the node counts. + +
                ResizeNodeDataPages() +
                Resize the number of pages allocated to store the node data. + +
                ResizeNodeDistPages() +
                Resize the number of pages allocated to store the distances + related to each node. + +
                ResizeQueuePages() +
                Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd . + +
                StoreNodes() +
                Procedure to recursively store nodes that are retained in the subset. + +
                SubsetCountMintermAux() +
                Recursively counts minterms of each node in the DAG. + +
                SubsetCountMinterm() +
                Counts minterms of each node in the DAG + +
                SubsetCountNodesAux() +
                Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node. + +
                SubsetCountNodes() +
                Counts the nodes under the current node and its lighter child + +
                UAbuildSubset() +
                Builds the subset BDD. + +
                UAmarkNodes() +
                Marks nodes for replacement by zero. + +
                ZeroCase() +
                If one child is zero, do explicitly what Restrict does or better + +
                addBddDoInterval() +
                Performs the recursive step for Cudd_addBddInterval. + +
                addBddDoIthBit() +
                Performs the recursive step for Cudd_addBddIthBit. + +
                addBddDoStrictThreshold() +
                Performs the recursive step for Cudd_addBddStrictThreshold. + +
                addBddDoThreshold() +
                Performs the recursive step for Cudd_addBddThreshold. + +
                addCheckPositiveCube() +
                Checks whether cube is an ADD representing the product + of positive literals. + +
                addDoIthBit() +
                Performs the recursive step for Cudd_addIthBit. + +
                addMMRecur() +
                Performs the recursive step of Cudd_addMatrixMultiply. + +
                addMultiplicityGroups() +
                Adds multiplicity groups to a ZDD variable group tree. + +
                addTriangleRecur() +
                Performs the recursive step of Cudd_addTriangle. + +
                addVarToConst() +
                Replaces variables with constants if possible (part of + canonical form). + +
                addWalshInt() +
                Implements the recursive step of Cudd_addWalsh. + +
                array_compare() +
                Comparison function for the computed table. + +
                array_hash() +
                Hash function for the computed table. + +
                bddAnnotateMintermCount() +
                Annotates every node in the BDD node with its minterm count. + +
                bddCheckPositiveCube() +
                Checks whether cube is an BDD representing the product of + positive literals. + +
                bddCorrelationAux() +
                Performs the recursive step of Cudd_bddCorrelation. + +
                bddCorrelationWeightsAux() +
                Performs the recursive step of Cudd_bddCorrelationWeigths. + +
                bddFixTree() +
                Fixes the BDD variable group tree after a shuffle. + +
                bddVarToCanonicalSimple() +
                Picks unique member from equiv expressions. + +
                bddVarToCanonical() +
                Picks unique member from equiv expressions. + +
                bddVarToConst() +
                Replaces variables with constants if possible. + +
                beforep() +
                Returns true iff the first argument precedes the second in + the clause order. + +
                bitVectorAlloc() +
                Allocates a bit vector. + +
                bitVectorFree() +
                Frees a bit vector. + +
                build_dd() +
                Builds a DD from a given order. + +
                checkSymmInfo() +
                Check symmetry condition. + +
                computeClausesWithUniverse() +
                Computes the two-literal clauses for a node. + +
                computeClauses() +
                Computes the two-literal clauses for a node. + +
                computeLB() +
                Computes a lower bound on the size of a BDD. + +
                computeSavings() +
                Counts the nodes that would be eliminated if a given node + were replaced by zero. + +
                copyOrder() +
                Copies the current variable order to array. + +
                createResult() +
                Builds a result for cache storage. + +
                cuddAddApplyRecur() +
                Performs the recursive step of Cudd_addApply. + +
                cuddAddBddDoPattern() +
                Performs the recursive step for Cudd_addBddPattern. + +
                cuddAddCmplRecur() +
                Performs the recursive step of Cudd_addCmpl. + +
                cuddAddComposeRecur() +
                Performs the recursive step of Cudd_addCompose. + +
                cuddAddConstrainRecur() +
                Performs the recursive step of Cudd_addConstrain. + +
                cuddAddExistAbstractRecur() +
                Performs the recursive step of Cudd_addExistAbstract. + +
                cuddAddGeneralVectorComposeRecur() +
                Performs the recursive step of Cudd_addGeneralVectorCompose. + +
                cuddAddIteRecur() +
                Implements the recursive step of Cudd_addIte(f,g,h). + +
                cuddAddMonadicApplyRecur() +
                Performs the recursive step of Cudd_addMonadicApply. + +
                cuddAddNegateRecur() +
                Implements the recursive step of Cudd_addNegate. + +
                cuddAddNonSimComposeRecur() +
                Performs the recursive step of Cudd_addNonSimCompose. + +
                cuddAddOrAbstractRecur() +
                Performs the recursive step of Cudd_addOrAbstract. + +
                cuddAddOuterSumRecur() +
                Performs the recursive step of Cudd_addOuterSum. + +
                cuddAddPermuteRecur() +
                Implements the recursive step of Cudd_addPermute. + +
                cuddAddRestrictRecur() +
                Performs the recursive step of Cudd_addRestrict. + +
                cuddAddRoundOffRecur() +
                Implements the recursive step of Cudd_addRoundOff. + +
                cuddAddScalarInverseRecur() +
                Performs the recursive step of addScalarInverse. + +
                cuddAddUnivAbstractRecur() +
                Performs the recursive step of Cudd_addUnivAbstract. + +
                cuddAddVectorComposeRecur() +
                Performs the recursive step of Cudd_addVectorCompose. + +
                cuddAllocNode() +
                Fast storage allocation for DdNodes in the table. + +
                cuddAnnealing() +
                Get new variable-order by simulated annealing algorithm. + +
                cuddApaCountMintermAux() +
                Performs the recursive step of Cudd_ApaCountMinterm. + +
                cuddApaStCountfree() +
                Frees the memory used to store the minterm counts recorded + in the visited table. + +
                cuddBddAlignToZdd() +
                Reorders BDD variables according to the order of the ZDD + variables. + +
                cuddBddAndAbstractRecur() +
                Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                cuddBddAndRecur() +
                Implements the recursive step of Cudd_bddAnd. + +
                cuddBddBooleanDiffRecur() +
                Performs the recursive steps of Cudd_bddBoleanDiff. + +
                cuddBddCharToVect() +
                Performs the recursive step of Cudd_bddCharToVect. + +
                cuddBddClipAndAbsRecur() +
                Approximates the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                cuddBddClippingAndAbstract() +
                Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
                cuddBddClippingAndRecur() +
                Implements the recursive step of Cudd_bddClippingAnd. + +
                cuddBddClippingAnd() +
                Approximates the conjunction of two BDDs f and g. + +
                cuddBddClosestCube() +
                Performs the recursive step of Cudd_bddClosestCube. + +
                cuddBddComposeRecur() +
                Performs the recursive step of Cudd_bddCompose. + +
                cuddBddConstrainDecomp() +
                Performs the recursive step of Cudd_bddConstrainDecomp. + +
                cuddBddConstrainRecur() +
                Performs the recursive step of Cudd_bddConstrain. + +
                cuddBddExistAbstractRecur() +
                Performs the recursive steps of Cudd_bddExistAbstract. + +
                cuddBddIntersectRecur() +
                Implements the recursive step of Cudd_bddIntersect. + +
                cuddBddIsop() +
                Performs the recursive step of Cudd_bddIsop. + +
                cuddBddIteRecur() +
                Implements the recursive step of Cudd_bddIte. + +
                cuddBddLICBuildResult() +
                Builds the result of Cudd_bddLICompaction. + +
                cuddBddLICMarkEdges() +
                Performs the edge marking step of Cudd_bddLICompaction. + +
                cuddBddLICompaction() +
                Performs safe minimization of a BDD. + +
                cuddBddLiteralSetIntersectionRecur() +
                Performs the recursive step of + Cudd_bddLiteralSetIntersection. + +
                cuddBddMakePrime() +
                Performs the recursive step of Cudd_bddMakePrime. + +
                cuddBddNPAndRecur() +
                Implements the recursive step of Cudd_bddAnd. + +
                cuddBddPermuteRecur() +
                Implements the recursive step of Cudd_bddPermute. + +
                cuddBddRestrictRecur() +
                Performs the recursive step of Cudd_bddRestrict. + +
                cuddBddSqueeze() +
                Performs the recursive step of Cudd_bddSqueeze. + +
                cuddBddTransferRecur() +
                Performs the recursive step of Cudd_bddTransfer. + +
                cuddBddTransfer() +
                Convert a BDD from a manager to another one. + +
                cuddBddVarMapRecur() +
                Implements the recursive step of Cudd_bddVarMap. + +
                cuddBddVectorComposeRecur() +
                Performs the recursive step of Cudd_bddVectorCompose. + +
                cuddBddXorExistAbstractRecur() +
                Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
                cuddBddXorRecur() +
                Implements the recursive step of Cudd_bddXor. + +
                cuddBiasedUnderApprox() +
                Applies the biased remapping underappoximation algorithm. + +
                cuddCProjectionRecur() +
                Performs the recursive step of Cudd_CProjection. + +
                cuddCacheFlush() +
                Flushes the cache. + +
                cuddCacheInsert1() +
                Inserts a result in the cache for a function with two + operands. + +
                cuddCacheInsert2() +
                Inserts a result in the cache for a function with two + operands. + +
                cuddCacheInsert() +
                Inserts a result in the cache for a function with three + operands. + +
                cuddCacheLookup1Zdd() +
                Looks up in the cache for the result of op applied to f. + +
                cuddCacheLookup1() +
                Looks up in the cache for the result of op applied to f. + +
                cuddCacheLookup2Zdd() +
                Looks up in the cache for the result of op applied to f + and g. + +
                cuddCacheLookup2() +
                Looks up in the cache for the result of op applied to f + and g. + +
                cuddCacheLookupZdd() +
                Looks up in the cache for the result of op applied to f, + g, and h. + +
                cuddCacheLookup() +
                Looks up in the cache for the result of op applied to f, + g, and h. + +
                cuddCacheProfile() +
                Computes and prints a profile of the cache usage. + +
                cuddCacheResize() +
                Resizes the cache. + +
                cuddCheckCollisionOrdering() +
                Checks whether a collision list is ordered. + +
                cuddClearDeathRow() +
                Clears the death row. + +
                cuddCofactorRecur() +
                Performs the recursive step of Cudd_Cofactor. + +
                cuddCollectNodes() +
                Recursively collects all the nodes of a DD in a symbol + table. + +
                cuddComputeFloorLog2() +
                Returns the floor of the logarithm to the base 2. + +
                cuddConjunctsAux() +
                Procedure to compute two conjunctive factors of f and place in *c1 and *c2. + +
                cuddConstantLookup() +
                Looks up in the cache for the result of op applied to f, + g, and h. + +
                cuddDestroySubtables() +
                Destroys the n most recently created subtables in a unique table. + +
                cuddDoRebalance() +
                Rebalances a red/black tree. + +
                cuddDynamicAllocNode() +
                Dynamically allocates a Node. + +
                cuddEstimateCofactorSimple() +
                Performs the recursive step of Cudd_CofactorEstimateSimple. + +
                cuddEstimateCofactor() +
                Performs the recursive step of Cudd_CofactorEstimate. + +
                cuddExact() +
                Exact variable ordering algorithm. + +
                cuddFindParent() +
                Searches the subtables above node for a parent. + +
                cuddFreeTable() +
                Frees the resources associated to a unique table. + +
                cuddGarbageCollect() +
                Performs garbage collection on the unique tables. + +
                cuddGa() +
                Genetic algorithm for DD reordering. + +
                cuddGetBranches() +
                Computes the children of g. + +
                cuddHashTableGenericInsert() +
                Inserts an item in a hash table. + +
                cuddHashTableGenericLookup() +
                Looks up a key consisting of one pointer in a hash table. + +
                cuddHashTableGenericQuit() +
                Shuts down a hash table. + +
                cuddHashTableInit() +
                Initializes a hash table. + +
                cuddHashTableInsert1() +
                Inserts an item in a hash table. + +
                cuddHashTableInsert2() +
                Inserts an item in a hash table. + +
                cuddHashTableInsert3() +
                Inserts an item in a hash table. + +
                cuddHashTableInsert() +
                Inserts an item in a hash table. + +
                cuddHashTableLookup1() +
                Looks up a key consisting of one pointer in a hash table. + +
                cuddHashTableLookup2() +
                Looks up a key consisting of two pointers in a hash table. + +
                cuddHashTableLookup3() +
                Looks up a key consisting of three pointers in a hash table. + +
                cuddHashTableLookup() +
                Looks up a key in a hash table. + +
                cuddHashTableQuit() +
                Shuts down a hash table. + +
                cuddHashTableResize() +
                Resizes a hash table. + +
                cuddHeapProfile() +
                Prints information about the heap. + +
                cuddInitCache() +
                Initializes the computed table. + +
                cuddInitInteract() +
                Initializes the interaction matrix. + +
                cuddInitLinear() +
                Initializes the linear transform matrix. + +
                cuddInitTable() +
                Creates and initializes the unique table. + +
                cuddInsertSubtables() +
                Inserts n new subtables in a unique table at level. + +
                cuddIsInDeathRow() +
                Checks whether a node is in the death row. + +
                cuddLevelQueueDequeue() +
                Remove an item from the front of a level queue. + +
                cuddLevelQueueEnqueue() +
                Inserts a new key in a level queue. + +
                cuddLevelQueueFirst() +
                Inserts the first key in a level queue. + +
                cuddLevelQueueInit() +
                Initializes a level queue. + +
                cuddLevelQueueQuit() +
                Shuts down a level queue. + +
                cuddLinearAndSifting() +
                BDD reduction based on combination of sifting and linear + transformations. + +
                cuddLinearInPlace() +
                Linearly combines two adjacent variables. + +
                cuddLocalCacheAddToList() +
                Inserts a local cache in the manager list. + +
                cuddLocalCacheClearAll() +
                Clears the local caches of a manager. + +
                cuddLocalCacheClearDead() +
                Clears the dead entries of the local caches of a manager. + +
                cuddLocalCacheInit() +
                Initializes a local computed table. + +
                cuddLocalCacheInsert() +
                Inserts a result in a local cache. + +
                cuddLocalCacheLookup() +
                Looks up in a local cache. + +
                cuddLocalCacheProfile() +
                Computes and prints a profile of a local cache usage. + +
                cuddLocalCacheQuit() +
                Shuts down a local computed table. + +
                cuddLocalCacheRemoveFromList() +
                Removes a local cache from the manager list. + +
                cuddLocalCacheResize() +
                Resizes a local cache. + +
                cuddMakeBddFromZddCover() +
                Converts a ZDD cover to a BDD. + +
                cuddMinHammingDistRecur() +
                Performs the recursive step of Cudd_MinHammingDist. + +
                cuddNextHigh() +
                Finds the next subtable with a larger index. + +
                cuddNextLow() +
                Finds the next subtable with a smaller index. + +
                cuddNodeArrayRecur() +
                Performs the recursive step of cuddNodeArray. + +
                cuddNodeArray() +
                Recursively collects all the nodes of a DD in an array. + +
                cuddOrderedInsert() +
                Inserts a DdNode in a red/black search tree. + +
                cuddOrderedThread() +
                Threads all the nodes of a search tree into a linear list. + +
                cuddPrintNode() +
                Prints out information on a node. + +
                cuddPrintVarGroups() +
                Prints the variable groups as a parenthesized list. + +
                cuddP() +
                Prints a DD to the standard output. One line per node is + printed. + +
                cuddReclaimZdd() +
                Brings children of a dead ZDD node back. + +
                cuddReclaim() +
                Brings children of a dead node back. + +
                cuddRehash() +
                Rehashes a unique subtable. + +
                cuddRemapUnderApprox() +
                Applies the remapping underappoximation algorithm. + +
                cuddResizeLinear() +
                Resizes the linear transform matrix. + +
                cuddResizeTableZdd() +
                Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index. + +
                cuddSetInteract() +
                Set interaction matrix entries. + +
                cuddShrinkDeathRow() +
                Shrinks the death row. + +
                cuddShrinkSubtable() +
                Shrinks a subtable. + +
                cuddSifting() +
                Implementation of Rudell's sifting algorithm. + +
                cuddSlowTableGrowth() +
                Adjusts parameters of a table to slow down its growth. + +
                cuddSolveEqnRecur() +
                Implements the recursive step of Cudd_SolveEqn. + +
                cuddSplitSetRecur() +
                Implements the recursive step of Cudd_SplitSet. + +
                cuddStCountfree() +
                Frees the memory used to store the minterm counts recorded + in the visited table. + +
                cuddSubsetHeavyBranch() +
                The main procedure that returns a subset by choosing the heavier + branch in the BDD. + +
                cuddSubsetShortPaths() +
                The outermost procedure to return a subset of the given BDD + with the shortest path lengths. + +
                cuddSwapInPlace() +
                Swaps two adjacent variables. + +
                cuddSwapping() +
                Reorders variables by a sequence of (non-adjacent) swaps. + +
                cuddSymmCheck() +
                Checks for symmetry of x and y. + +
                cuddSymmSiftingConv() +
                Symmetric sifting to convergence algorithm. + +
                cuddSymmSifting() +
                Symmetric sifting algorithm. + +
                cuddTestInteract() +
                Test interaction matrix entries. + +
                cuddTimesInDeathRow() +
                Counts how many times a node is in the death row. + +
                cuddTreeSifting() +
                Tree sifting algorithm. + +
                cuddUnderApprox() +
                Applies Tom Shiple's underappoximation algorithm. + +
                cuddUniqueConst() +
                Checks the unique table for the existence of a constant node. + +
                cuddUniqueInterIVO() +
                Wrapper for cuddUniqueInter that is independent of variable + ordering. + +
                cuddUniqueInterZdd() +
                Checks the unique table for the existence of an internal + ZDD node. + +
                cuddUniqueInter() +
                Checks the unique table for the existence of an internal node. + +
                cuddUniqueLookup() +
                Checks the unique table for the existence of an internal node. + +
                cuddUpdateInteractionMatrix() +
                Updates the interaction matrix. + +
                cuddVerifySol() +
                Implements the recursive step of Cudd_VerifySol. + +
                cuddWindowReorder() +
                Reorders by applying the method of the sliding window. + +
                cuddXorLinear() +
                XORs two rows of the linear transform matrix. + +
                cuddZddAlignToBdd() +
                Reorders ZDD variables according to the order of the BDD + variables. + +
                cuddZddChangeAux() +
                Performs the recursive step of Cudd_zddChange. + +
                cuddZddChange() +
                Substitutes a variable with its complement in a ZDD. + +
                cuddZddComplement() +
                Computes a complement of a ZDD node. + +
                cuddZddCountDoubleStep() +
                Performs the recursive step of Cudd_zddCountDouble. + +
                cuddZddCountStep() +
                Performs the recursive step of Cudd_zddCount. + +
                cuddZddDagInt() +
                Performs the recursive step of Cudd_zddDagSize. + +
                cuddZddDiff() +
                Performs the recursive step of Cudd_zddDiff. + +
                cuddZddDivideF() +
                Performs the recursive step of Cudd_zddDivideF. + +
                cuddZddDivide() +
                Performs the recursive step of Cudd_zddDivide. + +
                cuddZddFreeUniv() +
                Frees the ZDD universe. + +
                cuddZddGetCofactors2() +
                Computes the two-way decomposition of f w.r.t. v. + +
                cuddZddGetCofactors3() +
                Computes the three-way decomposition of f w.r.t. v. + +
                cuddZddGetNegVarIndex() +
                Returns the index of negative ZDD variable. + +
                cuddZddGetNegVarLevel() +
                Returns the level of negative ZDD variable. + +
                cuddZddGetNodeIVO() +
                Wrapper for cuddUniqueInterZdd that is independent of variable + ordering. + +
                cuddZddGetNode() +
                Wrapper for cuddUniqueInterZdd. + +
                cuddZddGetPosVarIndex() +
                Returns the index of positive ZDD variable. + +
                cuddZddGetPosVarLevel() +
                Returns the level of positive ZDD variable. + +
                cuddZddInitUniv() +
                Initializes the ZDD universe. + +
                cuddZddIntersect() +
                Performs the recursive step of Cudd_zddIntersect. + +
                cuddZddIsop() +
                Performs the recursive step of Cudd_zddIsop. + +
                cuddZddIte() +
                Performs the recursive step of Cudd_zddIte. + +
                cuddZddLinearAux() +
                Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                cuddZddLinearBackward() +
                Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
                cuddZddLinearDown() +
                Sifts a variable down and applies the XOR transformation. + +
                cuddZddLinearInPlace() +
                Linearly combines two adjacent variables. + +
                cuddZddLinearSifting() +
                Implementation of the linear sifting algorithm for ZDDs. + +
                cuddZddLinearUp() +
                Sifts a variable up applying the XOR transformation. + +
                cuddZddNextHigh() +
                Finds the next subtable with a larger index. + +
                cuddZddNextLow() +
                Finds the next subtable with a smaller index. + +
                cuddZddProduct() +
                Performs the recursive step of Cudd_zddProduct. + +
                cuddZddP() +
                Prints a ZDD to the standard output. One line per node is + printed. + +
                cuddZddSiftingAux() +
                Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                cuddZddSiftingBackward() +
                Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
                cuddZddSiftingDown() +
                Sifts a variable down. + +
                cuddZddSiftingUp() +
                Sifts a variable up. + +
                cuddZddSifting() +
                Implementation of Rudell's sifting algorithm. + +
                cuddZddSubset0() +
                Computes the negative cofactor of a ZDD w.r.t. a variable. + +
                cuddZddSubset1() +
                Computes the positive cofactor of a ZDD w.r.t. a variable. + +
                cuddZddSwapInPlace() +
                Swaps two adjacent variables. + +
                cuddZddSwapping() +
                Reorders variables by a sequence of (non-adjacent) swaps. + +
                cuddZddSymmCheck() +
                Checks for symmetry of x and y. + +
                cuddZddSymmSiftingAux() +
                Given x_low <= x <= x_high moves x up and down between the + boundaries. + +
                cuddZddSymmSiftingBackward() +
                Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
                cuddZddSymmSiftingConvAux() +
                Given x_low <= x <= x_high moves x up and down between the + boundaries. + +
                cuddZddSymmSiftingConv() +
                Symmetric sifting to convergence algorithm for ZDDs. + +
                cuddZddSymmSifting_down() +
                Moves x down until either it reaches the bound (x_high) or + the size of the ZDD heap increases too much. + +
                cuddZddSymmSifting_up() +
                Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much. + +
                cuddZddSymmSifting() +
                Symmetric sifting algorithm for ZDDs. + +
                cuddZddSymmSummary() +
                Counts numbers of symmetric variables and symmetry + groups. + +
                cuddZddTreeSifting() +
                Tree sifting algorithm for ZDDs. + +
                cuddZddUnateProduct() +
                Performs the recursive step of Cudd_zddUnateProduct. + +
                cuddZddUndoMoves() +
                Given a set of moves, returns the ZDD heap to the order + in effect before the moves. + +
                cuddZddUnion() +
                Performs the recursive step of Cudd_zddUnion. + +
                cuddZddUniqueCompare() +
                Comparison function used by qsort. + +
                cuddZddWeakDivF() +
                Performs the recursive step of Cudd_zddWeakDivF. + +
                cuddZddWeakDiv() +
                Performs the recursive step of Cudd_zddWeakDiv. + +
                ddBddMaximallyExpand() +
                Performs the recursive step of Cudd_bddMaximallyExpand. + +
                ddBddShortestPathUnate() +
                Performs shortest path computation on a unate function. + +
                ddBddToAddRecur() +
                Performs the recursive step for Cudd_BddToAdd. + +
                ddCheckPermuation() +
                Checks the BDD variable group tree before a shuffle. + +
                ddClearFlag() +
                Performs a DFS from f, clearing the LSB of the next + pointers. + +
                ddClearGlobal() +
                Scans the DD and clears the LSB of the next pointers. + +
                ddClearGlobal() +
                Scans the DD and clears the LSB of the next pointers. + +
                ddClearLocal() +
                Performs a DFS from f, clearing the LSB of the then pointers. + +
                ddClearVars() +
                Clears visited flags for variables. + +
                ddCofMintermAux() +
                Recursive Step for Cudd_CofMinterm function. + +
                ddCountInternalMtrNodes() +
                Counts the number of internal nodes of the group tree. + +
                ddCountMintermAux() +
                Performs the recursive step of Cudd_CountMinterm. + +
                ddCountPathAux() +
                Performs the recursive step of Cudd_CountPath. + +
                ddCountPathsToNonZero() +
                Performs the recursive step of Cudd_CountPathsToNonZero. + +
                ddCountRoots() +
                Counts the number of roots. + +
                ddCreateGroup() +
                Creates a group encompassing variables from x to y in the + DD table. + +
                ddDagInt() +
                Performs the recursive step of Cudd_DagSize. + +
                ddDissolveGroup() +
                Dissolves a group in the DD table. + +
                ddDoDumpBlif() +
                Performs the recursive step of Cudd_DumpBlif. + +
                ddDoDumpDDcal() +
                Performs the recursive step of Cudd_DumpDDcal. + +
                ddDoDumpDaVinci() +
                Performs the recursive step of Cudd_DumpDaVinci. + +
                ddDoDumpFactoredForm() +
                Performs the recursive step of Cudd_DumpFactoredForm. + +
                ddEpdCountMintermAux() +
                Performs the recursive step of Cudd_EpdCountMinterm. + +
                ddEpdFree() +
                Frees the memory used to store the minterm counts recorded + in the visited table. + +
                ddExchange() +
                This function is for exchanging two variables, x and y. + +
                ddExtSymmCheck() +
                Checks for extended symmetry of x and y. + +
                ddFindEssentialRecur() +
                Implements the recursive step of Cudd_FindEssential. + +
                ddFindNodeHiLo() +
                Finds the lower and upper bounds of the group represented + by treenode. + +
                ddFindSupport() +
                Recursively find the support of f. + +
                ddFindTwoLiteralClausesRecur() +
                Implements the recursive step of Cudd_FindTwoLiteralClauses. + +
                ddGetLargestCubeUnate() +
                Extracts largest prime of a unate function. + +
                ddGroupMoveBackward() +
                Undoes the swap two groups. + +
                ddGroupMove() +
                Swaps two groups and records the move. + +
                ddGroupSiftingAux() +
                Sifts one variable up and down until it has taken all + positions. Checks for aggregation. + +
                ddGroupSiftingBackward() +
                Determines the best position for a variables and returns + it there. + +
                ddGroupSiftingDown() +
                Sifts down a variable until it reaches position xHigh. + +
                ddGroupSiftingUp() +
                Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much. + +
                ddGroupSifting() +
                Sifts from treenode->low to treenode->high. + +
                ddIsVarHandled() +
                Checks whether a variables is already handled. + +
                ddJumpingAux() +
                Moves a variable to a specified position. + +
                ddJumpingDown() +
                This function is for jumping down. + +
                ddJumpingUp() +
                This function is for jumping up. + +
                ddLeavesInt() +
                Performs the recursive step of Cudd_CountLeaves. + +
                ddLinearAndSiftingAux() +
                Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                ddLinearAndSiftingBackward() +
                Given a set of moves, returns the DD heap to the order + giving the minimum size. + +
                ddLinearAndSiftingDown() +
                Sifts a variable down and applies linear transformations. + +
                ddLinearAndSiftingUp() +
                Sifts a variable up and applies linear transformations. + +
                ddLinearUniqueCompare() +
                Comparison function used by qsort. + +
                ddMergeGroups() +
                Merges groups in the DD table. + +
                ddNoCheck() +
                Pretends to check two variables for aggregation. + +
                ddPatchTree() +
                Fixes a variable tree after the insertion of new subtables. + +
                ddPermuteWindow3() +
                Tries all the permutations of the three variables between + x and x+2 and retains the best. + +
                ddPermuteWindow4() +
                Tries all the permutations of the four variables between w + and w+3 and retains the best. + +
                ddPickArbitraryMinterms() +
                Performs the recursive step of Cudd_bddPickArbitraryMinterms. + +
                ddPickRepresentativeCube() +
                Finds a representative cube of a BDD. + +
                ddPrintMintermAux() +
                Performs the recursive step of Cudd_PrintMinterm. + +
                ddRehashZdd() +
                Rehashes a ZDD unique subtable. + +
                ddReorderChildren() +
                Reorders the children of a group tree node according to + the options. + +
                ddReorderPostprocess() +
                Cleans up at the end of reordering. + +
                ddReorderPreprocess() +
                Prepares the DD heap for dynamic reordering. + +
                ddReportRefMess() +
                Reports problem in garbage collection. + +
                ddResetVarHandled() +
                Resets a variable to be processed. + +
                ddResizeTable() +
                Increases the number of subtables in a unique table so + that it meets or exceeds index. + +
                ddSecDiffCheck() +
                Checks two variables for aggregation. + +
                ddSetVarHandled() +
                Sets a variable to already handled. + +
                ddShuffle() +
                Reorders variables according to a given permutation. + +
                ddShuffle() +
                Reorders variables according to a given permutation. + +
                ddSiftUp() +
                Moves one variable up. + +
                ddSiftUp() +
                Moves one variable up. + +
                ddSiftingAux() +
                Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                ddSiftingBackward() +
                Given a set of moves, returns the DD heap to the position + giving the minimum size. + +
                ddSiftingDown() +
                Sifts a variable down. + +
                ddSiftingUp() +
                Sifts a variable up. + +
                ddSuppInteract() +
                Find the support of f. + +
                ddSupportStep() +
                Performs the recursive step of Cudd_Support. + +
                ddSwapAny() +
                Swaps any two variables. + +
                ddSymmGroupMoveBackward() +
                Undoes the swap of two groups. + +
                ddSymmGroupMove() +
                Swaps two groups. + +
                ddSymmSiftingAux() +
                Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                ddSymmSiftingBackward() +
                Given a set of moves, returns the DD heap to the position + giving the minimum size. + +
                ddSymmSiftingConvAux() +
                Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                ddSymmSiftingDown() +
                Moves x down until either it reaches the bound (xHigh) or + the size of the DD heap increases too much. + +
                ddSymmSiftingUp() +
                Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much. + +
                ddSymmSummary() +
                Counts numbers of symmetric variables and symmetry + groups. + +
                ddSymmUniqueCompare() +
                Comparison function used by qsort. + +
                ddTreeSiftingAux() +
                Visits the group tree and reorders each group. + +
                ddUndoMoves() +
                Given a set of moves, returns the DD heap to the order + in effect before the moves. + +
                ddUniqueCompareGroup() +
                Comparison function used by qsort. + +
                ddUniqueCompare() +
                Comparison function used by qsort. + +
                ddUpdateInteract() +
                Marks as interacting all pairs of variables that appear in + support. + +
                ddUpdateMtrTree() +
                Updates the BDD variable group tree before a shuffle. + +
                ddVarGroupCheck() +
                Checks for grouping of x and y. + +
                ddWindow2() +
                Reorders by applying a sliding window of width 2. + +
                ddWindow3() +
                Reorders by applying a sliding window of width 3. + +
                ddWindow4() +
                Reorders by applying a sliding window of width 4. + +
                ddWindowConv2() +
                Reorders by repeatedly applying a sliding window of width 2. + +
                ddWindowConv3() +
                Reorders by repeatedly applying a sliding window of width 3. + +
                ddWindowConv4() +
                Reorders by repeatedly applying a sliding window of width 4. + +
                debugCheckParent() +
                Reports an error if a (dead) node has a non-dead parent. + +
                debugFindParent() +
                Searches the subtables above node for its parents. + +
                dp2() +
                Performs the recursive step of cuddP. + +
                emptyClauseSet() +
                Returns an enpty set of clauses. + +
                equalp() +
                Returns true iff the two arguments are identical clauses. + +
                find_best() +
                Returns the index of the fittest individual. + +
                fixVarTree() +
                Fixes a variable group tree. + +
                freeMatrix() +
                Frees a two-dimensional matrix allocated by getMatrix. + +
                freePathPair() +
                Frees the entries of the visited symbol table. + +
                gatherInfoAux() +
                Recursively counts minterms and computes reference counts + of each node in the BDD. + +
                gatherInfo() +
                Gathers information about each node. + +
                gcd() +
                Returns the gcd of two integers. + +
                getCube() +
                Build a BDD for a largest cube of f. + +
                getLargest() +
                Finds the size of the largest cube(s) in a DD. + +
                getLevelKeys() +
                Returns the number of nodes at one level of a unique table. + +
                getMatrix() +
                Allocates a two-dimensional matrix of ints. + +
                getMaxBinomial() +
                Returns the maximum value of (n choose k) for a given n. + +
                getPath() +
                Build a BDD for a shortest path of f. + +
                getShortest() +
                Finds the length of the shortest path(s) in a DD. + +
                hashDelete() +
                Removes an item from the hash table of a level queue. + +
                hashInsert() +
                Inserts an item in the hash table of a level queue. + +
                hashLookup() +
                Looks up a key in the hash table of a level queue. + +
                hashResize() +
                Resizes the hash table of a level queue. + +
                impliedp() +
                Returns true iff either literal of a clause is in a set of + literals. + +
                indexCompare() +
                Compares indices for qsort. + +
                initSymmInfo() +
                Gathers symmetry information. + +
                largest() +
                Finds the largest DD in the population. + +
                make_random() +
                Generates the random sequences for the initial population. + +
                mintermsFromUniverse() +
                Recursive procedure to extract n mintems from constant 1. + +
                oneliteralp() +
                Returns true iff the argument is a one-literal clause. + +
                pushDown() +
                Pushes a variable in the order down to position "level." + +
                rand_int() +
                Generates a random number between 0 and the integer a. + +
                random_generator() +
                Random number generator. + +
                restoreOrder() +
                Restores the variable order in array by a series of sifts up. + +
                roulette() +
                Selects two parents with the roulette wheel method. + +
                selectMintermsFromUniverse() +
                This function prepares an array of variables which have not been + encountered so far when traversing the procedure cuddSplitSetRecur. + +
                sentinelp() +
                Returns true iff the argument is the sentinel clause. + +
                separateCube() +
                Separates cube from distance. + +
                siftBackwardProb() +
                Returns the DD to the best position encountered during + sifting if there was improvement. + +
                sift_up() +
                Moves one variable up. + +
                stPathTableDdFree() +
                Procedure to free te result dds stored in the NodeDist pages. + +
                st_zdd_count_dbl_free() +
                Frees the memory associated with the computed table of + Cudd_zddCountDouble. + +
                st_zdd_countfree() +
                Frees the memory associated with the computed table of + Cudd_zddCount. + +
                stopping_criterion() +
                Checks termination condition. + +
                tlcInfoAlloc() +
                Allocates a DdTlcInfo Structure. + +
                updateEntry() +
                Updates entry for a subset. + +
                updateParity() +
                Recursively update the parity of the paths reaching a node. + +
                updateRefs() +
                Update function reference counts. + +
                updateUB() +
                Updates the upper bound and saves the best order seen so far. + +
                zddClearFlag() +
                Performs a DFS from f, clearing the LSB of the next + pointers. + +
                zddCountInternalMtrNodes() +
                Counts the number of internal nodes of the group tree. + +
                zddFindNodeHiLo() +
                Finds the lower and upper bounds of the group represented + by treenode. + +
                zddFixTree() +
                Fixes the ZDD variable group tree after a shuffle. + +
                zddGroupMoveBackward() +
                Undoes the swap two groups. + +
                zddGroupMove() +
                Swaps two groups and records the move. + +
                zddGroupSiftingAux() +
                Sifts one variable up and down until it has taken all + positions. Checks for aggregation. + +
                zddGroupSiftingBackward() +
                Determines the best position for a variables and returns + it there. + +
                zddGroupSiftingDown() +
                Sifts down a variable until it reaches position xHigh. + +
                zddGroupSiftingUp() +
                Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much. + +
                zddGroupSifting() +
                Sifts from treenode->low to treenode->high. + +
                zddMergeGroups() +
                Merges groups in the DD table. + +
                zddPortFromBddStep() +
                Performs the recursive step of Cudd_zddPortFromBdd. + +
                zddPortToBddStep() +
                Performs the recursive step of Cudd_zddPortToBdd. + +
                zddPrintCoverAux() +
                Performs the recursive step of Cudd_zddPrintCover. + +
                zddReorderChildren() +
                Reorders the children of a group tree node according to + the options. + +
                zddReorderPostprocess() +
                Shrinks almost empty ZDD subtables at the end of reordering + to guarantee that they have a reasonable load factor. + +
                zddReorderPreprocess() +
                Prepares the ZDD heap for dynamic reordering. + +
                zddShuffle() +
                Reorders ZDD variables according to a given permutation. + +
                zddSiftUp() +
                Moves one ZDD variable up. + +
                zddSupportStep() +
                Performs the recursive step of Cudd_zddSupport. + +
                zddSwapAny() +
                Swaps any two variables. + +
                zddTreeSiftingAux() +
                Visits the group tree and reorders each group. + +
                zddUniqueCompareGroup() +
                Comparison function used by qsort. + +
                zddVarToConst() +
                Replaces variables with constants if possible (part of + canonical form). + +
                zdd_group_move_backward() +
                Undoes the swap of two groups. + +
                zdd_group_move() +
                Swaps two groups. + +
                zdd_print_minterm_aux() +
                Performs the recursive step of Cudd_zddPrintMinterm. + +
                zdd_subset0_aux() +
                Performs the recursive step of Cudd_zddSubset0. + +
                zdd_subset1_aux() +
                Performs the recursive step of Cudd_zddSubset1. + +
                zp2() +
                Performs the recursive step of cuddZddP. + +
                () +
                Adds node to the head of the free list. + +
                () +
                Adds node to the head of the free list. + +
                () +
                Adjusts the values of table limits. + +
                () +
                Clears a bit vector. + +
                () +
                Clears the 4 least significant bits of a pointer. + +
                () +
                Comparison of a function to the i-th ADD variable. + +
                () +
                Comparison of a pair of functions to the i-th ADD variable. + +
                () +
                Complements a DD if a condition is true. + +
                () +
                Complements a DD. + +
                () +
                Computes hash function for keys of one operand. + +
                () +
                Computes hash function for keys of three operands. + +
                () +
                Computes hash function for keys of two operands. + +
                () +
                Computes the absolute value of a number. + +
                () +
                Computes the hash value for a local cache. + +
                () +
                Computes the maximum of two numbers. + +
                () +
                Computes the minimum of two numbers. + +
                () +
                Decreases the reference count of a node, if it is not + saturated. + +
                () +
                Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL. + +
                () +
                Extract the least significant digit of a double digit. + +
                () +
                Extract the most significant digit of a double digit. + +
                () +
                Fast storage allocation for items in a hash table. + +
                () +
                Finds the current position of ZDD variable index in the + order. + +
                () +
                Finds the current position of variable index in the + order. + +
                () +
                Hash function for the cache for functions with two + operands. + +
                () +
                Hash function for the cache. + +
                () +
                Hash function for the table of a level queue. + +
                () +
                Hash function for the unique table. + +
                () +
                Increases the reference count of a node, if it is not + saturated. + +
                () +
                Iterates over the cubes of a decision diagram. + +
                () +
                Iterates over the nodes of a decision diagram. + +
                () +
                Iterates over the paths of a ZDD. + +
                () +
                Iterates over the primes of a Boolean function. + +
                () +
                Outputs a line of stats. + +
                () +
                Performs the left rotation for red/black trees. + +
                () +
                Performs the right rotation for red/black trees. + +
                () +
                Returns 1 if a pointer is complemented. + +
                () +
                Returns 1 if the absolute value of the difference of the two + arguments x and y is less than e. + +
                () +
                Returns 1 if the node is a constant node. + +
                () +
                Returns 1 if the node is a constant node. + +
                () +
                Returns the arithmetic 0 constant node. + +
                () +
                Returns the average fitness of the population. + +
                () +
                Returns the complemented version of a pointer. + +
                () +
                Returns the constant 1 node. + +
                () +
                Returns the current position in the order of variable + index. + +
                () +
                Returns the else child of an internal node. + +
                () +
                Returns the else child of an internal node. + +
                () +
                Returns the i-th entry of a bit vector. + +
                () +
                Returns the minus infinity constant node. + +
                () +
                Returns the plus infinity constant node. + +
                () +
                Returns the regular version of a pointer. + +
                () +
                Returns the then child of an internal node. + +
                () +
                Returns the then child of an internal node. + +
                () +
                Returns the value of a constant node. + +
                () +
                Returns the value of a constant node. + +
                () +
                Saturating decrement operator. + +
                () +
                Saturating increment operator. + +
                () +
                Sets the i-th entry of a bit vector to a value. + +
                + +
                + +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFile.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFile.html new file mode 100644 index 000000000..4076ddeae --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFile.html @@ -0,0 +1,13 @@ + +The cudd package for maintainers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFunc.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFunc.html new file mode 100644 index 000000000..76ec3ae05 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllByFunc.html @@ -0,0 +1,13 @@ + +The cudd package for maintainers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllDet.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllDet.html new file mode 100644 index 000000000..b700560e8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllDet.html @@ -0,0 +1,15754 @@ + +The cudd package: all functions + + + +
                +
                +
                +
                +static unsigned int 
                +AssessPathLength(
                +  unsigned int * pathLengthArray, array determining number of nodes belonging to the different path lengths
                +  int  threshold, threshold to determine maximum allowable nodes in the subset
                +  int  numVars, maximum number of variables
                +  unsigned int * excess, number of nodes labeled maxpath required in the subset
                +  FILE * fp where to write messages
                +)
                +
                +
                Chooses the maximum allowable path length under each node. + The corner cases are when the threshold is larger than the number + of nodes in the BDD iself, in which case 'numVars + 1' is returned. + If all nodes of a particular path length are needed, then the + maxpath returned is the next one with excess nodes = 0; +

                + +

                Side Effects None +

                + +

                Defined in cuddSubsetSP.c + +
                +
                +static int 
                +BAapplyBias(
                +  DdManager * dd, 
                +  DdNode * f, 
                +  DdNode * b, 
                +  ApproxInfo * info, 
                +  DdHashTable * cache 
                +)
                +
                +
                Finds don't care nodes by traversing f and b in parallel. + Returns the care status of the visited f node if successful; CARE_ERROR + otherwise. +

                + +

                Side Effects None +

                + +

                See Also cuddBiasedUnderApprox + + +
                Defined in cuddApprox.c + +
                +
                +static int 
                +BAmarkNodes(
                +  DdManager * dd, manager
                +  DdNode * f, function to be analyzed
                +  ApproxInfo * info, info on BDD
                +  int  threshold, when to stop approximating
                +  double  quality1, minimum improvement for accepted changes when b=1
                +  double  quality0 minimum improvement for accepted changes when b=0
                +)
                +
                +
                Marks nodes for remapping. Returns 1 if successful; 0 + otherwise. +

                + +

                Side Effects None +

                + +

                See Also cuddBiasedUnderApprox + + +
                Defined in cuddApprox.c + +
                +
                +static Conjuncts * 
                +BuildConjuncts(
                +  DdManager * dd, 
                +  DdNode * node, 
                +  st_table * distanceTable, 
                +  st_table * cacheTable, 
                +  int  approxDistance, 
                +  int  maxLocalRef, 
                +  st_table * ghTable, 
                +  st_table * mintermTable 
                +)
                +
                +
                Builds the conjuncts recursively, bottom up. Constants + are returned as (f, f). The cache is checked for previously computed + result. The decomposition points are determined by the local + reference count of this node and the longest distance from the + constant. At the decomposition point, the factors returned are (f, + 1). Recur on the two children. The order is determined by the + heavier branch. Combine the factors of the two children and pick the + one that already occurs in the gh table. Occurence in g is indicated + by value 1, occurence in h by 2, occurence in both 3. +

                + +

                See Also cuddConjunctsAux + + +
                Defined in cuddDecomp.c + +
                +
                +static DdNode * 
                +BuildSubsetBdd(
                +  DdManager * dd, DD manager
                +  GlobalInfo_t * gInfo, global information
                +  st_table * pathTable, path table with path lengths and computed results
                +  DdNode * node, current node
                +  struct AssortedInfo * info, assorted information structure
                +  st_table * subsetNodeTable table storing computed results
                +)
                +
                +
                Builds the BDD with nodes labeled with path length + under maxpath and as many nodes labeled maxpath as determined by the + threshold. The procedure uses the path table to determine which nodes + in the original bdd need to be retained. This procedure picks a + shortest path (tie break decided by taking the child with the shortest + distance to the constant) and recurs down the path till it reaches the + constant. the procedure then starts building the subset upward from + the constant. All nodes labeled by path lengths less than the given + maxpath are used to build the subset. However, in the case of nodes + that have label equal to maxpath, as many are chosen as required by + the threshold. This number is stored in the info structure in the + field thresholdReached. This field is decremented whenever a node + labeled maxpath is encountered and the nodes labeled maxpath are + aggregated in a maxpath table. As soon as the thresholdReached count + goes to 0, the shortest path from this node to the constant is found. + The extraction of nodes with the above labeling is based on the fact + that each node, labeled with a path length, P, has at least one child + labeled P or less. So extracting all nodes labeled a given path length + P ensures complete paths between the root and the constant. Extraction + of a partial number of nodes with a given path length may result in + incomplete paths and hence the additional number of nodes are grabbed + to complete the path. Since the Bdd is built bottom-up, other nodes + labeled maxpath do lie on complete paths. The procedure may cause the + subset to have a larger or smaller number of nodes than the specified + threshold. The increase in the number of nodes is caused by the + building of a subset and the reduction by recombination. However in + most cases, the recombination overshadows the increase and the + procedure returns a result with lower number of nodes than specified. + The subsetNodeTable is NIL when there is no hard limit on the number + of nodes. Further efforts towards keeping the subset closer to the + threshold number were abandoned in favour of keeping the procedure + simple and fast. +

                + +

                Side Effects SubsetNodeTable is changed if it is not NIL. +

                + +

                Defined in cuddSubsetSP.c + +
                +
                +static DdNode * 
                +BuildSubsetBdd(
                +  DdManager * dd, DD manager
                +  DdNode * node, current node
                +  int * size, current size of the subset
                +  st_table * visitedTable, visited table storing all node data
                +  int  threshold, 
                +  st_table * storeTable, 
                +  st_table * approxTable 
                +)
                +
                +
                The procedure carries out the building of the subset BDD + starting at the root. Using the three different counts labelling each node, + the procedure chooses the heavier branch starting from the root and keeps + track of the number of nodes it discards at each step, thus keeping count + of the size of the subset BDD dynamically. Once the threshold is satisfied, + the procedure then calls ITE to build the BDD. +

                + +

                Side Effects None +

                + +

                Defined in cuddSubsetHB.c + +
                +
                + 
                +CUDD_VALUE_TYPE *þvalueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +CUDD_VALUE_TYPE *þvalueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +CUDD_VALUE_TYPE þcþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +CUDD_VALUE_TYPE þepþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +CUDD_VALUE_TYPE þupperþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +CUDD_VALUE_TYPE þvalueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +CUDD_VALUE_TYPE þvalueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                +static Conjuncts * 
                +CheckInTables(
                +  DdNode * node, 
                +  DdNode * g1, 
                +  DdNode * h1, 
                +  DdNode * g2, 
                +  DdNode * h2, 
                +  st_table * ghTable, 
                +  st_table * cacheTable, 
                +  int * outOfMem 
                +)
                +
                +
                Check if the two pairs exist in the table. If any of + the conjuncts do exist, store in the cache and return the + corresponding pair. +

                + +

                See Also ZeroCase +BuildConjuncts + + +
                Defined in cuddDecomp.c + +
                +
                +static Conjuncts * 
                +CheckTablesCacheAndReturn(
                +  DdNode * node, 
                +  DdNode * g, 
                +  DdNode * h, 
                +  st_table * ghTable, 
                +  st_table * cacheTable 
                +)
                +
                +
                Check the tables for the existence of pair and return + one combination, cache the result. The assumption is that one of the + conjuncts is already in the tables. +

                + +

                Side Effects g and h referenced for the cache +

                + +

                See Also ZeroCase + + +
                Defined in cuddDecomp.c + +
                +
                +static void 
                +ConjunctsFree(
                +  DdManager * dd, 
                +  Conjuncts * factors 
                +)
                +
                +
                Free factors structure +

                + +

                Side Effects None +

                + +

                Defined in cuddDecomp.c + +
                +
                +static enum st_retval 
                +CorrelCleanUp(
                +  char * key, 
                +  char * value, 
                +  char * arg 
                +)
                +
                +
                Frees memory associated with hash table. Returns + ST_CONTINUE. +

                + +

                Side Effects None +

                + +

                Defined in cuddBddCorr.c + +
                +
                +static int 
                +CorrelCompare(
                +  const char * key1, 
                +  const char * key2 
                +)
                +
                +
                Compares two hash table entries. Returns 0 if they are + identical; 1 otherwise. +

                + +

                Side Effects None +

                + +

                Defined in cuddBddCorr.c + +
                +
                +static int 
                +CorrelHash(
                +  char * key, 
                +  int  modulus 
                +)
                +
                +
                Hashes a hash table entry. It is patterned after + st_strhash. Returns a value between 0 and modulus. +

                + +

                Side Effects None +

                + +

                Defined in cuddBddCorr.c + +
                +
                +static double 
                +CountMinterms(
                +  DdNode * node, 
                +  double  max, 
                +  st_table * mintermTable, 
                +  FILE * fp 
                +)
                +
                +
                Count the number of minterms of each node ina a BDD and + store it in a hash table. +

                + +

                Side Effects None +

                + +

                Defined in cuddDecomp.c + +
                +
                +static NodeStat * 
                +CreateBotDist(
                +  DdNode * node, 
                +  st_table * distanceTable 
                +)
                +
                +
                Get longest distance of node from constant. Returns the + distance of the root from the constant if successful; CUDD_OUT_OF_MEM + otherwise. +

                + +

                Side Effects None +

                + +

                Defined in cuddDecomp.c + +
                +
                +static int 
                +CreateBotDist(
                +  DdNode * node, current node
                +  st_table * pathTable, path table with path lengths
                +  unsigned int * pathLengthArray, array that stores number of nodes belonging to a particular path length.
                +  FILE * fp where to write messages
                +)
                +
                +
                Labels each node with the shortest distance from the constant. + This is done in a DFS search of the BDD. Each node has an odd + and even parity distance from the sink (since there exists paths to both + zero and one) which is less than MAXSHORTINT. At each node these distances + are updated using the minimum distance of its children from the constant. + SInce now both the length from the root and child is known, the minimum path + length(length of the shortest path between the root and the constant that + this node lies on) of this node can be calculated and used to update the + pathLengthArray +

                + +

                Side Effects Updates Path Table and path length array +

                + +

                See Also CreatePathTable +CreateTopDist +AssessPathLength + + +
                Defined in cuddSubsetSP.c + +
                +
                +static st_table * 
                +CreatePathTable(
                +  DdManager * dd, DD manager
                +  GlobalInfo_t * gInfo, global information
                +  DdNode * node, root of function
                +  unsigned int * pathLengthArray, array of path lengths to store nodes labeled with the various path lengths
                +  FILE * fp where to write messages
                +)
                +
                +
                The outer procedure to label each node with its shortest + distance from the root and constant. Calls CreateTopDist and CreateBotDist. + The basis for computing the distance between root and constant is that + the distance may be the sum of even distances from the node to the root + and constant or the sum of odd distances from the node to the root and + constant. Both CreateTopDist and CreateBotDist create the odd and + even parity distances from the root and constant respectively. +

                + +

                Side Effects None +

                + +

                See Also CreateTopDist +CreateBotDist + + +
                Defined in cuddSubsetSP.c + +
                +
                +static void 
                +CreateTopDist(
                +  DdManager * dd, DD manager
                +  GlobalInfo_t * gInfo, global information
                +  st_table * pathTable, hast table to store path lengths
                +  int  parentPage, the pointer to the page on which the first parent in the queue is to be found.
                +  int  parentQueueIndex, pointer to the first parent on the page
                +  int  topLen, current distance from the root
                +  DdNode ** childPage, pointer to the page on which the first child is to be added.
                +  int  childQueueIndex, pointer to the first child
                +  int  numParents, number of parents to process in this recursive call
                +  FILE * fp where to write messages
                +)
                +
                +
                Labels each node with its shortest distance from the root. + This is done in a BFS search of the BDD. The nodes are processed + in a queue implemented as pages(array) to reduce memory fragmentation. + An entry is created for each node visited. The distance from the root + to the node with the corresponding parity is updated. The procedure + is called recursively each recusion level handling nodes at a given + level from the root. +

                + +

                Side Effects Creates entries in the pathTable +

                + +

                See Also CreatePathTable +CreateBotDist + + +
                Defined in cuddSubsetSP.c + +
                +
                + 
                +Cudd_AggregationType þgcþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +Cudd_HookType þwhereþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +Cudd_HookType þwhereþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +Cudd_HookType þwhereþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +Cudd_ReorderingType *þmethodþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +Cudd_ReorderingType *þmethodþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +Cudd_ReorderingType þmethodþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +Cudd_ReorderingType þmethodþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DD_PRFP þPifuncþfunction used to build Pi if it is NULL(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdApaDigit þliteralþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdApaNumber þbþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdApaNumber þdestþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdApaNumber þdiffþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdApaNumber þnumberþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdApaNumber þnumberþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdApaNumber þquotientþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdApaNumber þquotientþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdApaNumber þsecondþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdApaNumber þsumþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdGen *þgenþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdGen *þgenþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þddþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þmanagerþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þtableþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þtableþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þtableþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þtableþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdManager *þuniqueþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode ***þconjunctsþaddress of the array of conjuncts(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode ***þconjunctsþaddress of the array of conjuncts(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode ***þconjunctsþaddress of the array of conjuncts(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode ***þconjunctsþaddress of the first factor(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þonlyGþcube of variables only in g(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þvectorOffþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þvectorþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þvectorþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þvectorþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þyþarray of y variables(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þyþarray of y variables(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þyþarray of y variables(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þyþarray of y variables(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þyþarray of y variables(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þzdd_Iþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þzþarray of z variables(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode **þzþarray of z variables(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þBþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þBþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þDþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þDþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þPþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þPþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þQþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þQþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þQþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þQþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þUþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þYþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þbckþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcubeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcubeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcubeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcubeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcubeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcubeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcubeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þcþconstraint (care set)(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þepsilonþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþDD whose support is sought(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþDD whose support is sought(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþDD whose support size is sought(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþZDD whose support is sought(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþfunction against which to expand(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþfunction in which to remap variables(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þfþfunction of which the cube is to be made a prime(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þgþsecond operand(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þhþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þhþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þhþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þhþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þhþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þnþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þp_nodeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þphaseBddþcube of the phases(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þuþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þuþupper bound(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdNode *þvarþvariable(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +DdTlcInfo *þtþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +EpDouble *þepdþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +FILE *þfpþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +FILE *þfpþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +FILE *þfpþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +FILE *þfpþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +FILE *þfpþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +FILE *þfpþpointer to the dump file(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +FILE *þfpþpointer to the dump file(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +FILE *þfpþpointer to the dump file(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +FILE *þfpþpointer to the dump file(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +FILE *þfpþpointer to the dump file(
                +    
                +)
                +
                +
                +

                + +

                +
                +static enum st_retval 
                +MarkCacheCleanUp(
                +  char * key, 
                +  char * value, 
                +  char * arg 
                +)
                +
                +
                Frees memory associated with computed table of + cuddBddLICMarkEdges. Returns ST_CONTINUE. +

                + +

                Side Effects None +

                + +

                See Also Cudd_bddLICompaction + + +
                Defined in cuddGenCof.c + +
                +
                +static int 
                +MarkCacheCompare(
                +  const char * ptr1, 
                +  const char * ptr2 
                +)
                +
                +
                Comparison function for the computed table of + cuddBddLICMarkEdges. Returns 0 if the two nodes of the key are equal; 1 + otherwise. +

                + +

                Side Effects None +

                + +

                See Also Cudd_bddLICompaction + + +
                Defined in cuddGenCof.c + +
                +
                +static int 
                +MarkCacheHash(
                +  char * ptr, 
                +  int  modulus 
                +)
                +
                +
                Hash function for the computed table of + cuddBddLICMarkEdges. Returns the bucket number. +

                + +

                Side Effects None +

                + +

                See Also Cudd_bddLICompaction + + +
                Defined in cuddGenCof.c + +
                +
                + 
                +MtrNode *þtreeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +MtrNode *þtreeþ(
                +    
                +)
                +
                +
                +

                + +

                +
                +static int 
                +PMX(
                +  int  maxvar 
                +)
                +
                +
                Performs the crossover between two randomly chosen + parents, and creates two children, x1 and x2. Uses the Partially + Matched Crossover operator. +

                + +

                Side Effects None +

                + +

                Defined in cuddGenetic.c + +
                +
                +static int 
                +PairInTables(
                +  DdNode * g, 
                +  DdNode * h, 
                +  st_table * ghTable 
                +)
                +
                +
                .Check whether the given pair is in the tables. gTable + and hTable are combined. + absence in both is indicated by 0, + presence in gTable is indicated by 1, + presence in hTable by 2 and + presence in both by 3. + The values returned by this function are PAIR_ST, + PAIR_CR, G_ST, G_CR, H_ST, H_CR, BOTH_G, BOTH_H, NONE. + PAIR_ST implies g in gTable and h in hTable + PAIR_CR implies g in hTable and h in gTable + G_ST implies g in gTable and h not in any table + G_CR implies g in hTable and h not in any table + H_ST implies h in hTable and g not in any table + H_CR implies h in gTable and g not in any table + BOTH_G implies both in gTable + BOTH_H implies both in hTable + NONE implies none in table; +

                + +

                See Also CheckTablesCacheAndReturn +CheckInTables + + +
                Defined in cuddDecomp.c + +
                +
                +static Conjuncts * 
                +PickOnePair(
                +  DdNode * node, 
                +  DdNode * g1, 
                +  DdNode * h1, 
                +  DdNode * g2, 
                +  DdNode * h2, 
                +  st_table * ghTable, 
                +  st_table * cacheTable 
                +)
                +
                +
                Check the tables for the existence of pair and return + one combination, store in cache. The pair that has more pointers to + it is picked. An approximation of the number of local pointers is + made by taking the reference count of the pairs sent. +

                + +

                See Also ZeroCase +BuildConjuncts + + +
                Defined in cuddDecomp.c + +
                +
                +static DdNode * 
                +RAbuildSubset(
                +  DdManager * dd, DD manager
                +  DdNode * node, current node
                +  ApproxInfo * info node info
                +)
                +
                +
                Builds the subset BDDfor cuddRemapUnderApprox. Based + on the info table, performs remapping or replacement at selected + nodes. Returns a pointer to the result if successful; NULL + otherwise. +

                + +

                Side Effects None +

                + +

                See Also cuddRemapUnderApprox + + +
                Defined in cuddApprox.c + +
                +
                +static int 
                +RAmarkNodes(
                +  DdManager * dd, manager
                +  DdNode * f, function to be analyzed
                +  ApproxInfo * info, info on BDD
                +  int  threshold, when to stop approximating
                +  double  quality minimum improvement for accepted changes
                +)
                +
                +
                Marks nodes for remapping. Returns 1 if successful; 0 + otherwise. +

                + +

                Side Effects None +

                + +

                See Also cuddRemapUnderApprox + + +
                Defined in cuddApprox.c + +
                +
                +static void 
                +ResizeCountMintermPages(
                +    
                +)
                +
                +
                Resize the number of pages allocated to store the minterm + counts. The procedure moves the counter to the next page when the + end of the page is reached and allocates new pages when necessary. +

                + +

                Side Effects Changes the size of minterm pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

                + +

                Defined in cuddSubsetHB.c + +
                +
                +static void 
                +ResizeCountNodePages(
                +    
                +)
                +
                +
                Resize the number of pages allocated to store the node counts. + The procedure moves the counter to the next page when the end of + the page is reached and allocates new pages when necessary. +

                + +

                Side Effects Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

                + +

                Defined in cuddSubsetHB.c + +
                +
                +static void 
                +ResizeNodeDataPages(
                +    
                +)
                +
                +
                Resize the number of pages allocated to store the node data + The procedure moves the counter to the next page when the end of + the page is reached and allocates new pages when necessary. +

                + +

                Side Effects Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

                + +

                Defined in cuddSubsetHB.c + +
                +
                +static void 
                +ResizeNodeDistPages(
                +  DdManager * dd, DD manager
                +  GlobalInfo_t * gInfo global information
                +)
                +
                +
                Resize the number of pages allocated to store the distances + related to each node. The procedure moves the counter to the + next page when the end of the page is reached and allocates new + pages when necessary. +

                + +

                Side Effects Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

                + +

                Defined in cuddSubsetSP.c + +
                +
                +static void 
                +ResizeQueuePages(
                +  DdManager * dd, DD manager
                +  GlobalInfo_t * gInfo global information
                +)
                +
                +
                Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd. The procedure moves the counter to the + next page when the end of the page is reached and allocates new + pages when necessary. +

                + +

                Side Effects Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

                + +

                Defined in cuddSubsetSP.c + +
                +
                +static void 
                +StoreNodes(
                +  st_table * storeTable, 
                +  DdManager * dd, 
                +  DdNode * node 
                +)
                +
                +
                rocedure to recursively store nodes that are retained in the subset. +

                + +

                Side Effects None +

                + +

                See Also StoreNodes + + +
                Defined in cuddSubsetHB.c + +
                +
                +static double 
                +SubsetCountMintermAux(
                +  DdNode * node, function to analyze
                +  double  max, number of minterms of constant 1
                +  st_table * table visitedTable table
                +)
                +
                +
                Recursively counts minterms of each node in the DAG. + Similar to the cuddCountMintermAux which recursively counts the + number of minterms for the dag rooted at each node in terms of the + total number of variables (max). This procedure creates the node + data structure and stores the minterm count as part of the node + data structure. +

                + +

                Side Effects Creates structures of type node quality and fills the st_table +

                + +

                See Also SubsetCountMinterm + + +
                Defined in cuddSubsetHB.c + +
                +
                +static st_table * 
                +SubsetCountMinterm(
                +  DdNode * node, function to be analyzed
                +  int  nvars number of variables node depends on
                +)
                +
                +
                Counts minterms of each node in the DAG. Similar to the + Cudd_CountMinterm procedure except this returns the minterm count for + all the nodes in the bdd in an st_table. +

                + +

                Side Effects none +

                + +

                See Also SubsetCountMintermAux + + +
                Defined in cuddSubsetHB.c + +
                +
                +static int 
                +SubsetCountNodesAux(
                +  DdNode * node, current node
                +  st_table * table, table to update node count, also serves as visited table.
                +  double  max maximum number of variables
                +)
                +
                +
                Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node. . Note that the same dag may be the lighter child of two + different nodes and have different counts. As with the minterm counts, + the node counts are stored in pages to be space efficient and the + address for these node counts are stored in an st_table associated + to each node. +

                + +

                Side Effects Updates the node data table with node counts +

                + +

                See Also SubsetCountNodes + + +
                Defined in cuddSubsetHB.c + +
                +
                +static int 
                +SubsetCountNodes(
                +  DdNode * node, function to be analyzed
                +  st_table * table, node quality table
                +  int  nvars number of variables node depends on
                +)
                +
                +
                Counts the nodes under the current node and its lighter + child. Calls a recursive procedure to count the number of nodes of + a DAG rooted at a particular node and the number of nodes taken by its + lighter child. +

                + +

                Side Effects None +

                + +

                See Also SubsetCountNodesAux + + +
                Defined in cuddSubsetHB.c + +
                +
                +static DdNode * 
                +UAbuildSubset(
                +  DdManager * dd, DD manager
                +  DdNode * node, current node
                +  ApproxInfo * info node info
                +)
                +
                +
                Builds the subset BDD. Based on the info table, + replaces selected nodes by zero. Returns a pointer to the result if + successful; NULL otherwise. +

                + +

                Side Effects None +

                + +

                See Also cuddUnderApprox + + +
                Defined in cuddApprox.c + +
                +
                +static int 
                +UAmarkNodes(
                +  DdManager * dd, manager
                +  DdNode * f, function to be analyzed
                +  ApproxInfo * info, info on BDD
                +  int  threshold, when to stop approximating
                +  int  safe, enforce safe approximation
                +  double  quality minimum improvement for accepted changes
                +)
                +
                +
                Marks nodes for replacement by zero. Returns 1 if successful; + 0 otherwise. +

                + +

                Side Effects None +

                + +

                See Also cuddUnderApprox + + +
                Defined in cuddApprox.c + +
                +
                +static Conjuncts * 
                +ZeroCase(
                +  DdManager * dd, 
                +  DdNode * node, 
                +  Conjuncts * factorsNv, 
                +  st_table * ghTable, 
                +  st_table * cacheTable, 
                +  int  switched 
                +)
                +
                +
                If one child is zero, do explicitly what Restrict does or better. + First separate a variable and its child in the base case. In case of a cube + times a function, separate the cube and function. As a last resort, look in + tables. +

                + +

                Side Effects Frees the BDDs in factorsNv. factorsNv itself is not freed + because it is freed above. +

                + +

                See Also BuildConjuncts + + +
                Defined in cuddDecomp.c + +
                +
                +static DdNode * 
                +addBddDoInterval(
                +  DdManager * dd, 
                +  DdNode * f, 
                +  DdNode * l, 
                +  DdNode * u 
                +)
                +
                +
                Performs the recursive step for Cudd_addBddInterval. + Returns a pointer to the BDD if successful; NULL otherwise. +

                + +

                Side Effects None +

                + +

                See Also addBddDoThreshold +addBddDoStrictThreshold + + +
                Defined in cuddBridge.c + +
                +
                +static DdNode * 
                +addBddDoIthBit(
                +  DdManager * dd, 
                +  DdNode * f, 
                +  DdNode * index 
                +)
                +
                +
                Performs the recursive step for Cudd_addBddIthBit. + Returns a pointer to the BDD if successful; NULL otherwise. +

                + +

                Side Effects None +

                + +

                Defined in cuddBridge.c + +
                +
                +static DdNode * 
                +addBddDoStrictThreshold(
                +  DdManager * dd, 
                +  DdNode * f, 
                +  DdNode * val 
                +)
                +
                +
                Performs the recursive step for Cudd_addBddStrictThreshold. + Returns a pointer to the BDD if successful; NULL otherwise. +

                + +

                Side Effects None +

                + +

                See Also addBddDoThreshold + + +
                Defined in cuddBridge.c + +
                +
                +static DdNode * 
                +addBddDoThreshold(
                +  DdManager * dd, 
                +  DdNode * f, 
                +  DdNode * val 
                +)
                +
                +
                Performs the recursive step for Cudd_addBddThreshold. + Returns a pointer to the BDD if successful; NULL otherwise. +

                + +

                Side Effects None +

                + +

                See Also addBddDoStrictThreshold + + +
                Defined in cuddBridge.c + +
                +
                +static int 
                +addCheckPositiveCube(
                +  DdManager * manager, 
                +  DdNode * cube 
                +)
                +
                +
                Checks whether cube is an ADD representing the product of + positive literals. Returns 1 in case of success; 0 otherwise. +

                + +

                Side Effects None +

                + +

                Defined in cuddAddAbs.c + +
                +
                +static DdNode * 
                +addDoIthBit(
                +  DdManager * dd, 
                +  DdNode * f, 
                +  DdNode * index 
                +)
                +
                +
                Performs the recursive step for Cudd_addIthBit. + Returns a pointer to the BDD if successful; NULL otherwise. +

                + +

                Side Effects None +

                + +

                Defined in cuddAddFind.c + +
                +
                +static DdNode * 
                +addMMRecur(
                +  DdManager * dd, 
                +  DdNode * A, 
                +  DdNode * B, 
                +  int  topP, 
                +  int * vars 
                +)
                +
                +
                Performs the recursive step of Cudd_addMatrixMultiply. + Returns a pointer to the result if successful; NULL otherwise. +

                + +

                Side Effects None +

                + +

                Defined in cuddMatMult.c + +
                +
                +static int 
                +addMultiplicityGroups(
                +  DdManager * dd, manager
                +  MtrNode * treenode, current tree node
                +  int  multiplicity, how many ZDD vars per BDD var
                +  char * vmask, variable pairs for which a group has been already built
                +  char * lmask levels for which a group has already been built
                +)
                +
                +
                Adds multiplicity groups to a ZDD variable group tree. + Returns 1 if successful; 0 otherwise. This function creates the groups + for set of ZDD variables (whose cardinality is given by parameter + multiplicity) that are created for each BDD variable in + Cudd_zddVarsFromBddVars. The crux of the matter is to determine the index + each new group. (The index of the first variable in the group.) + We first build all the groups for the children of a node, and then deal + with the ZDD variables that are directly attached to the node. The problem + for these is that the tree itself does not provide information on their + position inside the group. While we deal with the children of the node, + therefore, we keep track of all the positions they occupy. The remaining + positions in the tree can be freely used. Also, we keep track of all the + variables placed in the children. All the remaining variables are directly + attached to the group. We can then place any pair of variables not yet + grouped in any pair of available positions in the node. +

                + +

                Side Effects Changes the variable group tree. +

                + +

                See Also Cudd_zddVarsFromBddVars + + +
                Defined in cuddAPI.c + +
                +
                +static DdNode * 
                +addTriangleRecur(
                +  DdManager * dd, 
                +  DdNode * f, 
                +  DdNode * g, 
                +  int * vars, 
                +  DdNode * cube 
                +)
                +
                +
                Performs the recursive step of Cudd_addTriangle. Returns + a pointer to the result if successful; NULL otherwise. +

                + +

                Side Effects None +

                + +

                Defined in cuddMatMult.c + +
                +
                +static void 
                +addVarToConst(
                +  DdNode * f, 
                +  DdNode ** gp, 
                +  DdNode ** hp, 
                +  DdNode * one, 
                +  DdNode * zero 
                +)
                +
                +
                Replaces variables with constants if possible (part of + canonical form). +

                + +

                Side Effects None +

                + +

                Defined in cuddAddIte.c + +
                +
                +static DdNode * 
                +addWalshInt(
                +  DdManager * dd, 
                +  DdNode ** x, 
                +  DdNode ** y, 
                +  int  n 
                +)
                +
                +
                Generates a Walsh matrix in ADD form. Returns a pointer + to the matrixi if successful; NULL otherwise. +

                + +

                Side Effects None +

                + +

                Defined in cuddAddWalsh.c + +
                +
                +static int 
                +array_compare(
                +  const char * array1, 
                +  const char * array2 
                +)
                +
                +
                Comparison function for the computed table. Returns 0 if + the two arrays are equal; 1 otherwise. +

                + +

                Side Effects None +

                + +

                Defined in cuddGenetic.c + +
                +
                +static int 
                +array_hash(
                +  char * array, 
                +  int  modulus 
                +)
                +
                +
                Hash function for the computed table. Returns the bucket + number. +

                + +

                Side Effects None +

                + +

                Defined in cuddGenetic.c + +
                +
                +static double 
                +bddAnnotateMintermCount(
                +  DdManager * manager, 
                +  DdNode * node, 
                +  double  max, 
                +  st_table * table 
                +)
                +
                +
                Annotates every node in the BDD node with its minterm count. + In this function, every node and the minterm count represented by it are + stored in a hash table. +

                + +

                Side Effects Fills up 'table' with the pair . +

                + +

                Defined in cuddSplit.c + +
                +
                +static int 
                +bddCheckPositiveCube(
                +  DdManager * manager, 
                +  DdNode * cube 
                +)
                +
                +
                Returns 1 in case of success; 0 otherwise. +

                + +

                Side Effects None +

                + +

                Defined in cuddBddAbs.c + +
                +
                +static double 
                +bddCorrelationAux(
                +  DdManager * dd, 
                +  DdNode * f, 
                +  DdNode * g, 
                +  st_table * table 
                +)
                +
                +
                Performs the recursive step of Cudd_bddCorrelation. + Returns the fraction of minterms in the ON-set of the EXNOR of f and + g. +

                + +

                Side Effects None +

                + +

                See Also bddCorrelationWeightsAux + + +
                Defined in cuddBddCorr.c + +
                +
                +static double 
                +bddCorrelationWeightsAux(
                +  DdManager * dd, 
                +  DdNode * f, 
                +  DdNode * g, 
                +  double * prob, 
                +  st_table * table 
                +)
                +
                +
                Performs the recursive step of Cudd_bddCorrelationWeigths. +

                + +

                Side Effects None +

                + +

                See Also bddCorrelationAux + + +
                Defined in cuddBddCorr.c + +
                +
                +static void 
                +bddFixTree(
                +  DdManager * table, 
                +  MtrNode * treenode 
                +)
                +
                +
                Fixes the BDD variable group tree after a + shuffle. Assumes that the order of the variables in a terminal node + has not been changed. +

                + +

                Side Effects Changes the BDD variable group tree. +

                + +

                Defined in cuddReorder.c + +
                +
                +static int 
                +bddVarToCanonicalSimple(
                +  DdManager * dd, 
                +  DdNode ** fp, 
                +  DdNode ** gp, 
                +  DdNode ** hp, 
                +  unsigned int * topfp, 
                +  unsigned int * topgp, 
                +  unsigned int * tophp 
                +)
                +
                +
                Makes sure the first two pointers are regular. This + mat require the complementation of the result, which is signaled by + returning 1 instead of 0. This function is simpler than the general + case because it assumes that no two arguments are the same or + complementary, and no argument is constant. +

                + +

                Side Effects None +

                + +

                See Also bddVarToConst +bddVarToCanonical + + +
                Defined in cuddBddIte.c + +
                +
                +static int 
                +bddVarToCanonical(
                +  DdManager * dd, 
                +  DdNode ** fp, 
                +  DdNode ** gp, 
                +  DdNode ** hp, 
                +  unsigned int * topfp, 
                +  unsigned int * topgp, 
                +  unsigned int * tophp 
                +)
                +
                +
                Reduces 2 variable expressions to canonical form. +

                + +

                Side Effects None +

                + +

                See Also bddVarToConst +bddVarToCanonicalSimple + + +
                Defined in cuddBddIte.c + +
                +
                +static void 
                +bddVarToConst(
                +  DdNode * f, 
                +  DdNode ** gp, 
                +  DdNode ** hp, 
                +  DdNode * one 
                +)
                +
                +
                This function performs part of the transformation to + standard form by replacing variables with constants if possible. +

                + +

                Side Effects None +

                + +

                See Also bddVarToCanonical +bddVarToCanonicalSimple + + +
                Defined in cuddBddIte.c + +
                +
                +static int 
                +beforep(
                +  DdHalfWord  var1a, 
                +  short  phase1a, 
                +  DdHalfWord  var1b, 
                +  short  phase1b, 
                +  DdHalfWord  var2a, 
                +  short  phase2a, 
                +  DdHalfWord  var2b, 
                +  short  phase2b 
                +)
                +
                +
                Returns true iff the first argument precedes the second + in the clause order. A clause precedes another if its first lieral + precedes the first literal of the other, or if the first literals + are the same, and its second literal precedes the second literal of + the other clause. A literal precedes another if it has a higher + index, of if it has the same index, but it has lower phase. Phase 0 + is the positive phase, and it is lower than Phase 1 (negative + phase). +

                + +

                Side Effects None +

                + +

                See Also equalp + + +
                Defined in cuddEssent.c + +
                +
                +static BitVector * 
                +bitVectorAlloc(
                +  int  size 
                +)
                +
                +
                Allocates a bit vector. The parameter size gives the + number of bits. This procedure allocates enough long's to hold the + specified number of bits. Returns a pointer to the allocated vector + if successful; NULL otherwise. +

                + +

                Side Effects None +

                + +

                See Also bitVectorClear +bitVectorFree + + +
                Defined in cuddEssent.c + +
                +
                +static void 
                +bitVectorFree(
                +  BitVector * vector 
                +)
                +
                +
                Frees a bit vector. +

                + +

                Side Effects None +

                + +

                See Also bitVectorAlloc + + +
                Defined in cuddEssent.c + +
                +
                +static int 
                +build_dd(
                +  DdManager * table, 
                +  int  num, the index of the individual to be built
                +  int  lower, 
                +  int  upper 
                +)
                +
                +
                Builds a DD from a given order. This procedure also + sifts the final order and inserts into the array the size in nodes + of the result. Returns 1 if successful; 0 otherwise. +

                + +

                Side Effects None +

                + +

                Defined in cuddGenetic.c + +
                +
                + 
                +char *þstringþ(
                +    
                +)
                +
                +
                +

                + +

                +
                + 
                +char *þstrþpointer to string to use if != NULL(
                +    
                +)
                +
                +
                +

                + +

                +
                +static int 
                +checkSymmInfo(
                +  DdManager * table, 
                +  DdHalfWord * symmInfo, 
                +  int  index, 
                +  int  level 
                +)
                +
                +
                Returns 1 if a variable is the one with the highest index + among those belonging to a symmetry group that are in the top part of + the BDD. The top part is given by level. +

                + +

                Side Effects None +

                + +

                See Also initSymmInfo + + +
                Defined in cuddExact.c + +
                +
                +static DdTlcInfo * 
                +computeClausesWithUniverse(
                +  DdTlcInfo * Cres, list of clauses for child
                +  DdHalfWord  label, variable labeling the current node
                +  short  phase 0 if E child is zero; 1 if T child is zero
                +)
                +
                +
                Computes the two-literal clauses for a node with a zero + child, given the clauses for its other child and the label of the + node. Returns a pointer to a TclInfo structure if successful; NULL + otherwise. +

                + +

                Side Effects None +

                + +

                See Also computeClauses + + +
                Defined in cuddEssent.c + +
                +
                +static DdTlcInfo * 
                +computeClauses(
                +  DdTlcInfo * Tres, list of clauses for T child
                +  DdTlcInfo * Eres, list of clauses for E child
                +  DdHalfWord  label, variable labeling the current node
                +  int  size number of variables in the manager
                +)
                +
                +
                Computes the two-literal clauses for a node given the + clauses for its children and the label of the node. Returns a + pointer to a TclInfo structure if successful; NULL otherwise. +

                + +

                Side Effects None +

                + +

                See Also computeClausesWithUniverse + + +
                Defined in cuddEssent.c + +
                +
                +static int 
                +computeLB(
                +  DdManager * table, manager
                +  DdHalfWord * order, optimal order for the subset
                +  int  roots, roots between lower and upper
                +  int  cost, minimum cost for the subset
                +  int  lower, lower level to be reordered
                +  int  upper, upper level to be reordered
                +  int  level offset for the current top bottom var
                +)
                +
                +
                Computes a lower bound on the size of a BDD from the + following factors: +
                  +
                • size of the lower part of it; +
                • size of the part of the upper part not subjected to reordering; +
                • number of roots in the part of the BDD subjected to reordering; +
                • variable in the support of the roots in the upper part of the + BDD subjected to reordering. +
                    +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddExact.c + +
                    +
                    +static int 
                    +computeSavings(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * skip, 
                    +  ApproxInfo * info, 
                    +  DdLevelQueue * queue 
                    +)
                    +
                    +
                    Counts the nodes that would be eliminated if a given + node were replaced by zero. This procedure uses a queue passed by + the caller for efficiency: since the queue is left empty at the + endof the search, it can be reused as is by the next search. Returns + the count (always striclty positive) if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also UAmarkNodes +RAmarkNodes +BAmarkNodes + + +
                    Defined in cuddApprox.c + +
                    +
                    +static void 
                    +copyOrder(
                    +  DdManager * table, 
                    +  int * array, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Copies the current variable order to array. + At the same time inverts the permutation. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAnneal.c + +
                    +
                    +static DdNode * 
                    +createResult(
                    +  DdManager * dd, 
                    +  unsigned int  index, 
                    +  unsigned int  phase, 
                    +  DdNode * cube, 
                    +  CUDD_VALUE_TYPE  distance 
                    +)
                    +
                    +
                    Builds a result for cache storage. Returns a pointer + to the resulting ADD if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddBddClosestCube +separateCube + + +
                    Defined in cuddPriority.c + +
                    +
                    +DdNode * 
                    +cuddAddApplyRecur(
                    +  DdManager * dd, 
                    +  DD_AOP  op, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_addApply. Returns a + pointer to the result if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddAddMonadicApplyRecur + + +
                    Defined in cuddAddApply.c + +
                    +
                    +DdNode * 
                    +cuddAddBddDoPattern(
                    +  DdManager * dd, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Performs the recursive step for Cudd_addBddPattern. Returns a + pointer to the resulting BDD if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddBridge.c + +
                    +
                    +DdNode * 
                    +cuddAddCmplRecur(
                    +  DdManager * dd, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_addCmpl. Returns a + pointer to the resulting ADD if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_addCmpl + + +
                    Defined in cuddAddIte.c + +
                    +
                    +DdNode * 
                    +cuddAddComposeRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * proj 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_addCompose. + Returns the composed BDD if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_addCompose + + +
                    Defined in cuddCompose.c + +
                    +
                    +DdNode * 
                    +cuddAddConstrainRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * c 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_addConstrain. + Returns a pointer to the result if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_addConstrain + + +
                    Defined in cuddGenCof.c + +
                    +
                    +DdNode * 
                    +cuddAddExistAbstractRecur(
                    +  DdManager * manager, 
                    +  DdNode * f, 
                    +  DdNode * cube 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_addExistAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAddAbs.c + +
                    +
                    +static DdNode * 
                    +cuddAddGeneralVectorComposeRecur(
                    +  DdManager * dd, DD manager
                    +  DdHashTable * table, computed table
                    +  DdNode * f, ADD in which to compose
                    +  DdNode ** vectorOn, functions to substitute for x_i
                    +  DdNode ** vectorOff, functions to substitute for x_i'
                    +  int  deepest depth of deepest substitution
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_addGeneralVectorCompose. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCompose.c + +
                    +
                    +DdNode * 
                    +cuddAddIteRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * h 
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_addIte(f,g,h). + Returns a pointer to the resulting ADD if successful; NULL + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_addIte + + +
                    Defined in cuddAddIte.c + +
                    +
                    +DdNode * 
                    +cuddAddMonadicApplyRecur(
                    +  DdManager * dd, 
                    +  DD_MAOP  op, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_addMonadicApply. Returns a + pointer to the result if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddAddApplyRecur + + +
                    Defined in cuddAddApply.c + +
                    +
                    +DdNode * 
                    +cuddAddNegateRecur(
                    +  DdManager * dd, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_addNegate. + Returns a pointer to the result. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAddNeg.c + +
                    +
                    +static DdNode * 
                    +cuddAddNonSimComposeRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode ** vector, 
                    +  DdNode * key, 
                    +  DdNode * cube, 
                    +  int  lastsub 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_addNonSimCompose. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCompose.c + +
                    +
                    +DdNode * 
                    +cuddAddOrAbstractRecur(
                    +  DdManager * manager, 
                    +  DdNode * f, 
                    +  DdNode * cube 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_addOrAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAddAbs.c + +
                    +
                    +static DdNode * 
                    +cuddAddOuterSumRecur(
                    +  DdManager * dd, 
                    +  DdNode * M, 
                    +  DdNode * r, 
                    +  DdNode * c 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_addOuterSum. + Returns a pointer to the result if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddMatMult.c + +
                    +
                    +static DdNode * 
                    +cuddAddPermuteRecur(
                    +  DdManager * manager, DD manager
                    +  DdHashTable * table, computed table
                    +  DdNode * node, ADD to be reordered
                    +  int * permut permutation array
                    +)
                    +
                    +
                    Recursively puts the ADD in the order given in the + array permut. Checks for trivial cases to terminate recursion, then + splits on the children of this node. Once the solutions for the + children are obtained, it puts into the current position the node + from the rest of the ADD that should be here. Then returns this ADD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper + position is reached in the recursion tree.

                    + The DdNode * that is returned is the same ADD as passed in as node, + but in the new order. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_addPermute +cuddBddPermuteRecur + + +
                    Defined in cuddCompose.c + +
                    +
                    +DdNode * 
                    +cuddAddRestrictRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * c 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_addRestrict. + Returns the restricted ADD if successful; otherwise NULL. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_addRestrict + + +
                    Defined in cuddGenCof.c + +
                    +
                    +DdNode * 
                    +cuddAddRoundOffRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  double  trunc 
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_addRoundOff. + Returns a pointer to the result. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAddNeg.c + +
                    +
                    +DdNode * 
                    +cuddAddScalarInverseRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * epsilon 
                    +)
                    +
                    +
                    Returns a pointer to the resulting ADD in case of + success. Returns NULL if any discriminants smaller than epsilon is + encountered. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAddInv.c + +
                    +
                    +DdNode * 
                    +cuddAddUnivAbstractRecur(
                    +  DdManager * manager, 
                    +  DdNode * f, 
                    +  DdNode * cube 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_addUnivAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAddAbs.c + +
                    +
                    +static DdNode * 
                    +cuddAddVectorComposeRecur(
                    +  DdManager * dd, DD manager
                    +  DdHashTable * table, computed table
                    +  DdNode * f, ADD in which to compose
                    +  DdNode ** vector, functions to substitute
                    +  int  deepest depth of deepest substitution
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_addVectorCompose. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCompose.c + +
                    +
                    +DdNode * 
                    +cuddAllocNode(
                    +  DdManager * unique 
                    +)
                    +
                    +
                    Fast storage allocation for DdNodes in the table. The + first 4 bytes of a chunk contain a pointer to the next block; the + rest contains DD_MEM_CHUNK spaces for DdNodes. Returns a pointer to + a new node if successful; NULL is memory is full. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddDynamicAllocNode + + +
                    Defined in cuddTable.c + +
                    +
                    +int 
                    +cuddAnnealing(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Get x, y by random selection. Choose either + exchange or jump randomly. In case of jump, choose between jump_up + and jump_down randomly. Do exchange or jump and get optimal case. + Loop until there is no improvement or temperature reaches + minimum. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAnneal.c + +
                    +
                    +static DdApaNumber 
                    +cuddApaCountMintermAux(
                    +  DdNode * node, 
                    +  int  digits, 
                    +  DdApaNumber  max, 
                    +  DdApaNumber  min, 
                    +  st_table * table 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_ApaCountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. + Uses the identity |f'| = max - |f|. + The procedure expects the argument "node" to be a regular pointer, and + guarantees this condition is met in the recursive calls. + For efficiency, the result of a call is cached only if the node has + a reference count greater than 1. + Returns the number of minterms of the function rooted at node. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddApa.c + +
                    +
                    +static enum st_retval 
                    +cuddApaStCountfree(
                    +  char * key, 
                    +  char * value, 
                    +  char * arg 
                    +)
                    +
                    +
                    Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddApa.c + +
                    +
                    +int 
                    +cuddBddAlignToZdd(
                    +  DdManager * table DD manager
                    +)
                    +
                    +
                    Reorders BDD variables according to the order of the + ZDD variables. This function can be called at the end of ZDD + reordering to insure that the order of the BDD variables is + consistent with the order of the ZDD variables. The number of ZDD + variables must be a multiple of the number of BDD variables. Let + M be the ratio of the two numbers. cuddBddAlignToZdd + then considers the ZDD variables from M*i to + (M+1)*i-1 as corresponding to BDD variable + i. This function should be normally called from + Cudd_zddReduceHeap, which clears the cache. Returns 1 in case of + success; 0 otherwise. +

                    + +

                    Side Effects Changes the BDD variable order for all diagrams and performs + garbage collection of the BDD unique table. +

                    + +

                    See Also Cudd_ShuffleHeap +Cudd_zddReduceHeap + + +
                    Defined in cuddReorder.c + +
                    +
                    +DdNode * 
                    +cuddBddAndAbstractRecur(
                    +  DdManager * manager, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * cube 
                    +)
                    +
                    +
                    Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddAndAbstract + + +
                    Defined in cuddAndAbs.c + +
                    +
                    +DdNode * 
                    +cuddBddAndRecur(
                    +  DdManager * manager, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_bddAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddAnd + + +
                    Defined in cuddBddIte.c + +
                    +
                    +DdNode * 
                    +cuddBddBooleanDiffRecur(
                    +  DdManager * manager, 
                    +  DdNode * f, 
                    +  DdNode * var 
                    +)
                    +
                    +
                    Performs the recursive steps of Cudd_bddBoleanDiff. + Returns the BDD obtained by XORing the cofactors of f with respect to + var if successful; NULL otherwise. Exploits the fact that dF/dx = + dF'/dx. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddBddAbs.c + +
                    +
                    +static DdNode * 
                    +cuddBddCharToVect(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * x 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_bddCharToVect. + This function maintains the invariant that f is non-zero. + Returns the i-th component of the vector if successful; otherwise NULL. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddCharToVect + + +
                    Defined in cuddGenCof.c + +
                    +
                    +static DdNode * 
                    +cuddBddClipAndAbsRecur(
                    +  DdManager * manager, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * cube, 
                    +  int  distance, 
                    +  int  direction 
                    +)
                    +
                    +
                    Approximates the AND of two BDDs and simultaneously + abstracts the variables in cube. The variables are existentially + abstracted. Returns a pointer to the result is successful; NULL + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddClippingAndAbstract + + +
                    Defined in cuddClip.c + +
                    +
                    +DdNode * 
                    +cuddBddClippingAndAbstract(
                    +  DdManager * dd, manager
                    +  DdNode * f, first conjunct
                    +  DdNode * g, second conjunct
                    +  DdNode * cube, cube of variables to be abstracted
                    +  int  maxDepth, maximum recursion depth
                    +  int  direction under (0) or over (1) approximation
                    +)
                    +
                    +
                    Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddClippingAndAbstract + + +
                    Defined in cuddClip.c + +
                    +
                    +static DdNode * 
                    +cuddBddClippingAndRecur(
                    +  DdManager * manager, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  int  distance, 
                    +  int  direction 
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_bddClippingAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddBddClippingAnd + + +
                    Defined in cuddClip.c + +
                    +
                    +DdNode * 
                    +cuddBddClippingAnd(
                    +  DdManager * dd, manager
                    +  DdNode * f, first conjunct
                    +  DdNode * g, second conjunct
                    +  int  maxDepth, maximum recursion depth
                    +  int  direction under (0) or over (1) approximation
                    +)
                    +
                    +
                    Approximates the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddClippingAnd + + +
                    Defined in cuddClip.c + +
                    +
                    +DdNode * 
                    +cuddBddClosestCube(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  CUDD_VALUE_TYPE  bound 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_bddClosestCube. + Returns the cube if succesful; NULL otherwise. The procedure uses a + four-way recursion to examine all four combinations of cofactors of + f and g according to the following formula. +
                    +    H(f,g) = min(H(ft,gt), H(fe,ge), H(ft,ge)+1, H(fe,gt)+1)
                    +  
                    + Bounding is based on the following observations. +
                      +
                    • If we already found two points at distance 0, there is no point in + continuing. Furthermore, +
                    • If F == not(G) then the best we can hope for is a minimum distance + of 1. If we have already found two points at distance 1, there is + no point in continuing. (Indeed, H(F,G) == 1 in this case. We + have to continue, though, to find the cube.) +
                    + The variable bound is set at the largest value of the distance + that we are still interested in. Therefore, we desist when +
                    +    (bound == -1) and (F != not(G)) or (bound == 0) and (F == not(G)).
                    +  
                    + If we were maximally aggressive in using the bound, we would always + set the bound to the minimum distance seen thus far minus one. That + is, we would maintain the invariant +
                    +    bound < minD,
                    +  
                    + except at the very beginning, when we have no value for + minD.

                    + + However, we do not use bound < minD when examining the + two negative cofactors, because we try to find a large cube at + minimum distance. To do so, we try to find a cube in the negative + cofactors at the same or smaller distance from the cube found in the + positive cofactors.

                    + + When we compute H(ft,ge) and H(fe,gt) we + know that we are going to add 1 to the result of the recursive call + to account for the difference in the splitting variable. Therefore, + we decrease the bound correspondingly.

                    + + Another important observation concerns the need of examining all + four pairs of cofators only when both f and + g depend on the top variable.

                    + + Suppose gt == ge == g. (That is, g does + not depend on the top variable.) Then +

                    +    H(f,g) = min(H(ft,g), H(fe,g), H(ft,g)+1, H(fe,g)+1)
                    +	   = min(H(ft,g), H(fe,g)) .
                    +  
                    + Therefore, under these circumstances, we skip the two "cross" cases.

                    + + An interesting feature of this function is the scheme used for + caching the results in the global computed table. Since we have a + cube and a distance, we combine them to form an ADD. The + combination replaces the zero child of the top node of the cube with + the negative of the distance. (The use of the negative is to avoid + ambiguity with 1.) The degenerate cases (zero and one) are treated + specially because the distance is known (0 for one, and infinity for + zero). +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddClosestCube + + +
                    Defined in cuddPriority.c + +
                    +
                    +DdNode * 
                    +cuddBddComposeRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * proj 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_bddCompose. + Exploits the fact that the composition of f' with g + produces the complement of the composition of f with g to better + utilize the cache. Returns the composed BDD if successful; NULL + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddCompose + + +
                    Defined in cuddCompose.c + +
                    +
                    +static int 
                    +cuddBddConstrainDecomp(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode ** decomp 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_bddConstrainDecomp. + Returns f super (i) if successful; otherwise NULL. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddConstrainDecomp + + +
                    Defined in cuddGenCof.c + +
                    +
                    +DdNode * 
                    +cuddBddConstrainRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * c 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_bddConstrain. + Returns a pointer to the result if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddConstrain + + +
                    Defined in cuddGenCof.c + +
                    +
                    +DdNode * 
                    +cuddBddExistAbstractRecur(
                    +  DdManager * manager, 
                    +  DdNode * f, 
                    +  DdNode * cube 
                    +)
                    +
                    +
                    Performs the recursive steps of Cudd_bddExistAbstract. + Returns the BDD obtained by abstracting the variables + of cube from f if successful; NULL otherwise. It is also used by + Cudd_bddUnivAbstract. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddExistAbstract +Cudd_bddUnivAbstract + + +
                    Defined in cuddBddAbs.c + +
                    +
                    +DdNode * 
                    +cuddBddIntersectRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_bddIntersect. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddIntersect + + +
                    Defined in cuddBddIte.c + +
                    +
                    +DdNode	* 
                    +cuddBddIsop(
                    +  DdManager * dd, 
                    +  DdNode * L, 
                    +  DdNode * U 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_bddIsop. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddIsop + + +
                    Defined in cuddZddIsop.c + +
                    +
                    +DdNode * 
                    +cuddBddIteRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * h 
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_bddIte. Returns a + pointer to the resulting BDD. NULL if the intermediate result blows + up or if reordering occurs. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddBddIte.c + +
                    +
                    +static DdNode * 
                    +cuddBddLICBuildResult(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  st_table * cache, 
                    +  st_table * table 
                    +)
                    +
                    +
                    Builds the results of Cudd_bddLICompaction. + Returns a pointer to the minimized BDD if successful; otherwise NULL. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddLICompaction +cuddBddLICMarkEdges + + +
                    Defined in cuddGenCof.c + +
                    +
                    +static int 
                    +cuddBddLICMarkEdges(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * c, 
                    +  st_table * table, 
                    +  st_table * cache 
                    +)
                    +
                    +
                    Performs the edge marking step of Cudd_bddLICompaction. + Returns the LUB of the markings of the two outgoing edges of f + if successful; otherwise CUDD_OUT_OF_MEM. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddLICompaction +cuddBddLICBuildResult + + +
                    Defined in cuddGenCof.c + +
                    +
                    +DdNode * 
                    +cuddBddLICompaction(
                    +  DdManager * dd, manager
                    +  DdNode * f, function to be minimized
                    +  DdNode * c constraint (care set)
                    +)
                    +
                    +
                    Performs safe minimization of a BDD. Given the BDD + f of a function to be minimized and a BDD + c representing the care set, Cudd_bddLICompaction + produces the BDD of a function that agrees with f + wherever c is 1. Safe minimization means that the size + of the result is guaranteed not to exceed the size of + f. This function is based on the DAC97 paper by Hong et + al.. Returns a pointer to the result if successful; NULL + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddLICompaction + + +
                    Defined in cuddGenCof.c + +
                    +
                    +DdNode * 
                    +cuddBddLiteralSetIntersectionRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Performs the recursive step of + Cudd_bddLiteralSetIntersection. Scans the cubes for common variables, + and checks whether they agree in phase. Returns a pointer to the + resulting cube if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLiteral.c + +
                    +
                    +DdNode * 
                    +cuddBddMakePrime(
                    +  DdManager * dd, manager
                    +  DdNode * cube, cube to be expanded
                    +  DdNode * f function of which the cube is to be made a prime
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_bddMakePrime. + Returns the prime if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSat.c + +
                    +
                    +DdNode * 
                    +cuddBddNPAndRecur(
                    +  DdManager * manager, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_bddNPAnd. + Returns a pointer to the result is successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddNPAnd + + +
                    Defined in cuddGenCof.c + +
                    +
                    +static DdNode * 
                    +cuddBddPermuteRecur(
                    +  DdManager * manager, DD manager
                    +  DdHashTable * table, computed table
                    +  DdNode * node, BDD to be reordered
                    +  int * permut permutation array
                    +)
                    +
                    +
                    Recursively puts the BDD in the order given in the array permut. + Checks for trivial cases to terminate recursion, then splits on the + children of this node. Once the solutions for the children are + obtained, it puts into the current position the node from the rest of + the BDD that should be here. Then returns this BDD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper position + is reached in the recursion tree.

                    + The DdNode * that is returned is the same BDD as passed in as node, + but in the new order. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddPermute +cuddAddPermuteRecur + + +
                    Defined in cuddCompose.c + +
                    +
                    +DdNode * 
                    +cuddBddRestrictRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * c 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_bddRestrict. + Returns the restricted BDD if successful; otherwise NULL. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddRestrict + + +
                    Defined in cuddGenCof.c + +
                    +
                    +static DdNode * 
                    +cuddBddSqueeze(
                    +  DdManager * dd, 
                    +  DdNode * l, 
                    +  DdNode * u 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_bddSqueeze. This + procedure exploits the fact that if we complement and swap the + bounds of the interval we obtain a valid solution by taking the + complement of the solution to the original problem. Therefore, we + can enforce the condition that the upper bound is always regular. + Returns a pointer to the result if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddSqueeze + + +
                    Defined in cuddGenCof.c + +
                    +
                    +static DdNode * 
                    +cuddBddTransferRecur(
                    +  DdManager * ddS, 
                    +  DdManager * ddD, 
                    +  DdNode * f, 
                    +  st_table * table 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_bddTransfer. + Returns a pointer to the result if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddBddTransfer + + +
                    Defined in cuddBridge.c + +
                    +
                    +DdNode * 
                    +cuddBddTransfer(
                    +  DdManager * ddS, 
                    +  DdManager * ddD, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Convert a BDD from a manager to another one. Returns a + pointer to the BDD in the destination manager if successful; NULL + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddTransfer + + +
                    Defined in cuddBridge.c + +
                    +
                    +static DdNode * 
                    +cuddBddVarMapRecur(
                    +  DdManager * manager, DD manager
                    +  DdNode * f BDD to be remapped
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_bddVarMap. + Returns a pointer to the result if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddVarMap + + +
                    Defined in cuddCompose.c + +
                    +
                    +static DdNode * 
                    +cuddBddVectorComposeRecur(
                    +  DdManager * dd, DD manager
                    +  DdHashTable * table, computed table
                    +  DdNode * f, BDD in which to compose
                    +  DdNode ** vector, functions to be composed
                    +  int  deepest depth of the deepest substitution
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_bddVectorCompose. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCompose.c + +
                    +
                    +DdNode * 
                    +cuddBddXorExistAbstractRecur(
                    +  DdManager * manager, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * cube 
                    +)
                    +
                    +
                    Takes the exclusive OR of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddAndAbstract + + +
                    Defined in cuddBddAbs.c + +
                    +
                    +DdNode * 
                    +cuddBddXorRecur(
                    +  DdManager * manager, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_bddXor by taking + the exclusive OR of two BDDs. Returns a pointer to the result is + successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_bddXor + + +
                    Defined in cuddBddIte.c + +
                    +
                    +DdNode * 
                    +cuddBiasedUnderApprox(
                    +  DdManager * dd, DD manager
                    +  DdNode * f, current DD
                    +  DdNode * b, bias function
                    +  int  numVars, maximum number of variables
                    +  int  threshold, threshold under which approximation stops
                    +  double  quality1, minimum improvement for accepted changes when b=1
                    +  double  quality0 minimum improvement for accepted changes when b=0
                    +)
                    +
                    +
                    Applies the biased remapping underappoximation algorithm. + Proceeds in three phases: +
                      +
                    • collect information on each node in the BDD; this is done via DFS. +
                    • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
                    • traverse the BDD via DFS and actually perform the elimination. +
                    + Returns the approximated BDD if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_BiasedUnderApprox + + +
                    Defined in cuddApprox.c + +
                    +
                    +DdNode * 
                    +cuddCProjectionRecur(
                    +  DdManager * dd, 
                    +  DdNode * R, 
                    +  DdNode * Y, 
                    +  DdNode * Ysupp 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_CProjection. Returns + the projection if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_CProjection + + +
                    Defined in cuddPriority.c + +
                    +
                    +void 
                    +cuddCacheFlush(
                    +  DdManager * table 
                    +)
                    +
                    +
                    Flushes the cache. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCache.c + +
                    +
                    +void 
                    +cuddCacheInsert1(
                    +  DdManager * table, 
                    +  DD_CTFP1  op, 
                    +  DdNode * f, 
                    +  DdNode * data 
                    +)
                    +
                    +
                    Inserts a result in the cache for a function with two + operands. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddCacheInsert +cuddCacheInsert2 + + +
                    Defined in cuddCache.c + +
                    +
                    +void 
                    +cuddCacheInsert2(
                    +  DdManager * table, 
                    +  DD_CTFP  op, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * data 
                    +)
                    +
                    +
                    Inserts a result in the cache for a function with two + operands. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddCacheInsert +cuddCacheInsert1 + + +
                    Defined in cuddCache.c + +
                    +
                    +void 
                    +cuddCacheInsert(
                    +  DdManager * table, 
                    +  ptruint  op, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * h, 
                    +  DdNode * data 
                    +)
                    +
                    +
                    Inserts a result in the cache for a function with three + operands. The operator tag (see cuddInt.h for details) is split and stored + into unused bits of the first two pointers. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddCacheInsert2 +cuddCacheInsert1 + + +
                    Defined in cuddCache.c + +
                    +
                    +DdNode * 
                    +cuddCacheLookup1Zdd(
                    +  DdManager * table, 
                    +  DD_CTFP1  op, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Returns the result if found; it returns NULL if no + result is found. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddCacheLookupZdd +cuddCacheLookup2Zdd + + +
                    Defined in cuddCache.c + +
                    +
                    +DdNode * 
                    +cuddCacheLookup1(
                    +  DdManager * table, 
                    +  DD_CTFP1  op, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Returns the result if found; it returns NULL if no + result is found. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddCacheLookup +cuddCacheLookup2 + + +
                    Defined in cuddCache.c + +
                    +
                    +DdNode * 
                    +cuddCacheLookup2Zdd(
                    +  DdManager * table, 
                    +  DD_CTFP  op, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Returns the result if found; it returns NULL if no + result is found. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddCacheLookupZdd +cuddCacheLookup1Zdd + + +
                    Defined in cuddCache.c + +
                    +
                    +DdNode * 
                    +cuddCacheLookup2(
                    +  DdManager * table, 
                    +  DD_CTFP  op, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Returns the result if found; it returns NULL if no + result is found. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddCacheLookup +cuddCacheLookup1 + + +
                    Defined in cuddCache.c + +
                    +
                    +DdNode * 
                    +cuddCacheLookupZdd(
                    +  DdManager * table, 
                    +  ptruint  op, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * h 
                    +)
                    +
                    +
                    Returns the result if found; it returns NULL if no + result is found. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddCacheLookup2Zdd +cuddCacheLookup1Zdd + + +
                    Defined in cuddCache.c + +
                    +
                    +DdNode * 
                    +cuddCacheLookup(
                    +  DdManager * table, 
                    +  ptruint  op, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * h 
                    +)
                    +
                    +
                    Returns the result if found; it returns NULL if no + result is found. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddCacheLookup2 +cuddCacheLookup1 + + +
                    Defined in cuddCache.c + +
                    +
                    +int 
                    +cuddCacheProfile(
                    +  DdManager * table, 
                    +  FILE * fp 
                    +)
                    +
                    +
                    Computes and prints a profile of the cache usage. + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCache.c + +
                    +
                    +void 
                    +cuddCacheResize(
                    +  DdManager * table 
                    +)
                    +
                    +
                    Resizes the cache. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCache.c + +
                    +
                    +static int 
                    +cuddCheckCollisionOrdering(
                    +  DdManager * unique, 
                    +  int  i, 
                    +  int  j 
                    +)
                    +
                    +
                    Checks whether a collision list is ordered. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddTable.c + +
                    +
                    +void 
                    +cuddClearDeathRow(
                    +  DdManager * table 
                    +)
                    +
                    +
                    Clears the death row. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_DelayedDerefBdd +Cudd_IterDerefBdd +Cudd_CheckZeroRef +cuddGarbageCollect + + +
                    Defined in cuddRef.c + +
                    +
                    +DdNode * 
                    +cuddCofactorRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_Cofactor. Returns a + pointer to the cofactor if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_Cofactor + + +
                    Defined in cuddCof.c + +
                    +
                    +int 
                    +cuddCollectNodes(
                    +  DdNode * f, 
                    +  st_table * visited 
                    +)
                    +
                    +
                    Traverses the DD f and collects all its nodes in a + symbol table. f is assumed to be a regular pointer and + cuddCollectNodes guarantees this assumption in the recursive calls. + Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +int 
                    +cuddComputeFloorLog2(
                    +  unsigned int  value 
                    +)
                    +
                    +
                    Returns the floor of the logarithm to the base 2. + The input value is assumed to be greater than 0. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCache.c + +
                    +
                    +static int 
                    +cuddConjunctsAux(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode ** c1, 
                    +  DdNode ** c2 
                    +)
                    +
                    +
                    Procedure to compute two conjunctive factors of f and + place in *c1 and *c2. Sets up the required data - table of distances + from the constant and local reference count. Also minterm table. +

                    + +

                    Defined in cuddDecomp.c + +
                    +
                    +DdNode * 
                    +cuddConstantLookup(
                    +  DdManager * table, 
                    +  ptruint  op, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * h 
                    +)
                    +
                    +
                    Looks up in the cache for the result of op applied to f, + g, and h. Assumes that the calling procedure (e.g., + Cudd_bddIteConstant) is only interested in whether the result is + constant or not. Returns the result if found (possibly + DD_NON_CONSTANT); otherwise it returns NULL. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddCacheLookup + + +
                    Defined in cuddCache.c + +
                    +
                    +int 
                    +cuddDestroySubtables(
                    +  DdManager * unique, 
                    +  int  n 
                    +)
                    +
                    +
                    Destroys the n most recently created subtables in a unique + table. n should be positive. The subtables should not contain any live + nodes, except the (isolated) projection function. The projection + functions are freed. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects The variable map used for fast variable substitution is + destroyed if it exists. In this case the cache is also cleared. +

                    + +

                    See Also cuddInsertSubtables +Cudd_SetVarMap + + +
                    Defined in cuddTable.c + +
                    +
                    +static void 
                    +cuddDoRebalance(
                    +  DdNodePtr ** stack, 
                    +  int  stackN 
                    +)
                    +
                    +
                    Rebalances a red/black tree. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddTable.c + +
                    +
                    +DdNode * 
                    +cuddDynamicAllocNode(
                    +  DdManager * table 
                    +)
                    +
                    +
                    Dynamically allocates a Node. This procedure is similar + to cuddAllocNode in Cudd_Table.c, but it does not attempt garbage + collection, because during reordering there are no dead nodes. + Returns a pointer to a new node if successful; NULL is memory is + full. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddAllocNode + + +
                    Defined in cuddReorder.c + +
                    +
                    +static int 
                    +cuddEstimateCofactorSimple(
                    +  DdNode * node, 
                    +  int  i 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_CofactorEstimateSimple. + Returns an estimate of the number of nodes in the DD of the positive + cofactor of node. Uses the least significant bit of the next field as + visited flag. node is supposed to be regular; the invariant is maintained + by this procedure. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +static int 
                    +cuddEstimateCofactor(
                    +  DdManager * dd, 
                    +  st_table * table, 
                    +  DdNode * node, 
                    +  int  i, 
                    +  int  phase, 
                    +  DdNode ** ptr 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_CofactorEstimate. + Returns an estimate of the number of nodes in the DD of a + cofactor of node. Uses the least significant bit of the next field as + visited flag. node is supposed to be regular; the invariant is maintained + by this procedure. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +int 
                    +cuddExact(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Exact variable ordering algorithm. Finds an optimum + order for the variables between lower and upper. Returns 1 if + successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddExact.c + +
                    +
                    +static int 
                    +cuddFindParent(
                    +  DdManager * table, 
                    +  DdNode * node 
                    +)
                    +
                    +
                    Searches the subtables above node for a parent. Returns 1 + as soon as one parent is found. Returns 0 is the search is fruitless. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddTable.c + +
                    +
                    +void 
                    +cuddFreeTable(
                    +  DdManager * unique 
                    +)
                    +
                    +
                    Frees the resources associated to a unique table. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddInitTable + + +
                    Defined in cuddTable.c + +
                    +
                    +int 
                    +cuddGarbageCollect(
                    +  DdManager * unique, 
                    +  int  clearCache 
                    +)
                    +
                    +
                    Performs garbage collection on the BDD and ZDD unique tables. + If clearCache is 0, the cache is not cleared. This should only be + specified if the cache has been cleared right before calling + cuddGarbageCollect. (As in the case of dynamic reordering.) + Returns the total number of deleted nodes. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddTable.c + +
                    +
                    +int 
                    +cuddGa(
                    +  DdManager * table, manager
                    +  int  lower, lowest level to be reordered
                    +  int  upper highest level to be reorderded
                    +)
                    +
                    +
                    Genetic algorithm for DD reordering. + The two children of a crossover will be stored in + storedd[popsize +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGenetic.c + +
                    +
                    +void 
                    +cuddGetBranches(
                    +  DdNode * g, 
                    +  DdNode ** g1, 
                    +  DdNode ** g0 
                    +)
                    +
                    +
                    Computes the children of g. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCof.c + +
                    +
                    +int 
                    +cuddHashTableGenericInsert(
                    +  DdHashTable * hash, 
                    +  DdNode * f, 
                    +  void * value 
                    +)
                    +
                    +
                    Inserts an item in a hash table when the key is one + pointer and the value is not a DdNode pointer. Returns 1 if + successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddHashTableInsert1 +cuddHashTableGenericLookup + + +
                    Defined in cuddLCache.c + +
                    +
                    +void * 
                    +cuddHashTableGenericLookup(
                    +  DdHashTable * hash, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Looks up a key consisting of one pointer in a hash + table when the value is not a DdNode pointer. Returns the value + associated to the key if there is an entry for the given key in the + table; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddHashTableLookup1 +cuddHashTableGenericInsert + + +
                    Defined in cuddLCache.c + +
                    +
                    +void 
                    +cuddHashTableGenericQuit(
                    +  DdHashTable * hash 
                    +)
                    +
                    +
                    Shuts down a hash table, when the values are not DdNode + pointers. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddHashTableInit + + +
                    Defined in cuddLCache.c + +
                    +
                    +DdHashTable * 
                    +cuddHashTableInit(
                    +  DdManager * manager, 
                    +  unsigned int  keySize, 
                    +  unsigned int  initSize 
                    +)
                    +
                    +
                    Initializes a hash table. Returns a pointer to the new + table if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddHashTableQuit + + +
                    Defined in cuddLCache.c + +
                    +
                    +int 
                    +cuddHashTableInsert1(
                    +  DdHashTable * hash, 
                    +  DdNode * f, 
                    +  DdNode * value, 
                    +  ptrint  count 
                    +)
                    +
                    +
                    Inserts an item in a hash table when the key is one pointer. + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddHashTableInsert +cuddHashTableInsert2 +cuddHashTableInsert3 +cuddHashTableLookup1 + + +
                    Defined in cuddLCache.c + +
                    +
                    +int 
                    +cuddHashTableInsert2(
                    +  DdHashTable * hash, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * value, 
                    +  ptrint  count 
                    +)
                    +
                    +
                    Inserts an item in a hash table when the key is + composed of two pointers. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddHashTableInsert +cuddHashTableInsert1 +cuddHashTableInsert3 +cuddHashTableLookup2 + + +
                    Defined in cuddLCache.c + +
                    +
                    +int 
                    +cuddHashTableInsert3(
                    +  DdHashTable * hash, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * h, 
                    +  DdNode * value, 
                    +  ptrint  count 
                    +)
                    +
                    +
                    Inserts an item in a hash table when the key is + composed of three pointers. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddHashTableInsert +cuddHashTableInsert1 +cuddHashTableInsert2 +cuddHashTableLookup3 + + +
                    Defined in cuddLCache.c + +
                    +
                    +int 
                    +cuddHashTableInsert(
                    +  DdHashTable * hash, 
                    +  DdNodePtr * key, 
                    +  DdNode * value, 
                    +  ptrint  count 
                    +)
                    +
                    +
                    Inserts an item in a hash table when the key has more than + three pointers. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also [cuddHashTableInsert1 +cuddHashTableInsert2 +cuddHashTableInsert3 +cuddHashTableLookup + + +
                    Defined in cuddLCache.c + +
                    +
                    +DdNode * 
                    +cuddHashTableLookup1(
                    +  DdHashTable * hash, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Looks up a key consisting of one pointer in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddHashTableLookup +cuddHashTableLookup2 +cuddHashTableLookup3 +cuddHashTableInsert1 + + +
                    Defined in cuddLCache.c + +
                    +
                    +DdNode * 
                    +cuddHashTableLookup2(
                    +  DdHashTable * hash, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Looks up a key consisting of two pointer in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddHashTableLookup +cuddHashTableLookup1 +cuddHashTableLookup3 +cuddHashTableInsert2 + + +
                    Defined in cuddLCache.c + +
                    +
                    +DdNode * 
                    +cuddHashTableLookup3(
                    +  DdHashTable * hash, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * h 
                    +)
                    +
                    +
                    Looks up a key consisting of three pointers in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddHashTableLookup +cuddHashTableLookup1 +cuddHashTableLookup2 +cuddHashTableInsert3 + + +
                    Defined in cuddLCache.c + +
                    +
                    +DdNode * 
                    +cuddHashTableLookup(
                    +  DdHashTable * hash, 
                    +  DdNodePtr * key 
                    +)
                    +
                    +
                    Looks up a key consisting of more than three pointers + in a hash table. Returns the value associated to the key if there + is an entry for the given key in the table; NULL otherwise. If the + entry is present, its reference counter is decremented if not + saturated. If the counter reaches 0, the value of the entry is + dereferenced, and the entry is returned to the free list. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddHashTableLookup1 +cuddHashTableLookup2 +cuddHashTableLookup3 +cuddHashTableInsert + + +
                    Defined in cuddLCache.c + +
                    +
                    +void 
                    +cuddHashTableQuit(
                    +  DdHashTable * hash 
                    +)
                    +
                    +
                    Shuts down a hash table, dereferencing all the values. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddHashTableInit + + +
                    Defined in cuddLCache.c + +
                    +
                    +static int 
                    +cuddHashTableResize(
                    +  DdHashTable * hash 
                    +)
                    +
                    +
                    Resizes a hash table. Returns 1 if successful; 0 + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddHashTableInsert + + +
                    Defined in cuddLCache.c + +
                    +
                    +int 
                    +cuddHeapProfile(
                    +  DdManager * dd 
                    +)
                    +
                    +
                    Prints to the manager's stdout the number of live nodes for each + level of the DD heap that contains at least one live node. It also + prints a summary containing: +
                      +
                    • total number of tables; +
                    • number of tables with live nodes; +
                    • table with the largest number of live nodes; +
                    • number of nodes in that table. +
                    + If more than one table contains the maximum number of live nodes, + only the one of lowest index is reported. Returns 1 in case of success + and 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCheck.c + +
                    +
                    +int 
                    +cuddInitCache(
                    +  DdManager * unique, unique table
                    +  unsigned int  cacheSize, initial size of the cache
                    +  unsigned int  maxCacheSize cache size beyond which no resizing occurs
                    +)
                    +
                    +
                    Initializes the computed table. It is called by + Cudd_Init. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_Init + + +
                    Defined in cuddCache.c + +
                    +
                    +int 
                    +cuddInitInteract(
                    +  DdManager * table 
                    +)
                    +
                    +
                    Initializes the interaction matrix. The interaction + matrix is implemented as a bit vector storing the upper triangle of + the symmetric interaction matrix. The bit vector is kept in an array + of long integers. The computation is based on a series of depth-first + searches, one for each root of the DAG. Two flags are needed: The + local visited flag uses the LSB of the then pointer. The global + visited flag uses the LSB of the next pointer. + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddInteract.c + +
                    +
                    +int 
                    +cuddInitLinear(
                    +  DdManager * table 
                    +)
                    +
                    +
                    Initializes the linear transform matrix. Returns 1 if + successful; 0 otherwise. +

                    + +

                    Side Effects none +

                    + +

                    Defined in cuddLinear.c + +
                    +
                    +DdManager * 
                    +cuddInitTable(
                    +  unsigned int  numVars, Initial number of BDD variables (and subtables)
                    +  unsigned int  numVarsZ, Initial number of ZDD variables (and subtables)
                    +  unsigned int  numSlots, Initial size of the BDD subtables
                    +  unsigned int  looseUpTo Limit for fast table growth
                    +)
                    +
                    +
                    Creates and initializes the unique table. Returns a pointer + to the table if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_Init +cuddFreeTable + + +
                    Defined in cuddTable.c + +
                    +
                    +int 
                    +cuddInsertSubtables(
                    +  DdManager * unique, 
                    +  int  n, 
                    +  int  level 
                    +)
                    +
                    +
                    Inserts n new subtables in a unique table at level. + The number n should be positive, and level should be an existing level. + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddDestroySubtables + + +
                    Defined in cuddTable.c + +
                    +
                    +int 
                    +cuddIsInDeathRow(
                    +  DdManager * dd, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Checks whether a node is in the death row. Returns the + position of the first occurrence if the node is present; -1 + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_DelayedDerefBdd +cuddClearDeathRow + + +
                    Defined in cuddRef.c + +
                    +
                    +void 
                    +cuddLevelQueueDequeue(
                    +  DdLevelQueue * queue, 
                    +  int  level 
                    +)
                    +
                    +
                    Remove an item from the front of a level queue. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddLevelQueueEnqueue + + +
                    Defined in cuddLevelQ.c + +
                    +
                    +void * 
                    +cuddLevelQueueEnqueue(
                    +  DdLevelQueue * queue, level queue
                    +  void * key, key to be enqueued
                    +  int  level level at which to insert
                    +)
                    +
                    +
                    Inserts a new key in a level queue. A new entry is + created in the queue only if the node is not already + enqueued. Returns a pointer to the queue item if successful; NULL + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddLevelQueueInit +cuddLevelQueueDequeue + + +
                    Defined in cuddLevelQ.c + +
                    +
                    +void * 
                    +cuddLevelQueueFirst(
                    +  DdLevelQueue * queue, level queue
                    +  void * key, key to be enqueued
                    +  int  level level at which to insert
                    +)
                    +
                    +
                    Inserts the first key in a level queue. Returns a + pointer to the queue item if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddLevelQueueEnqueue + + +
                    Defined in cuddLevelQ.c + +
                    +
                    +DdLevelQueue * 
                    +cuddLevelQueueInit(
                    +  int  levels, number of levels
                    +  int  itemSize, size of the item
                    +  int  numBuckets initial number of hash buckets
                    +)
                    +
                    +
                    Initializes a level queue. A level queue is a queue + where inserts are based on the levels of the nodes. Within each + level the policy is FIFO. Level queues are useful in traversing a + BDD top-down. Queue items are kept in a free list when dequeued for + efficiency. Returns a pointer to the new queue if successful; NULL + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddLevelQueueQuit +cuddLevelQueueEnqueue +cuddLevelQueueDequeue + + +
                    Defined in cuddLevelQ.c + +
                    +
                    +void 
                    +cuddLevelQueueQuit(
                    +  DdLevelQueue * queue 
                    +)
                    +
                    +
                    Shuts down a level queue and releases all the + associated memory. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddLevelQueueInit + + +
                    Defined in cuddLevelQ.c + +
                    +
                    +int 
                    +cuddLinearAndSifting(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    BDD reduction based on combination of sifting and linear + transformations. Assumes that no dead nodes are present. +
                      +
                    1. Order all the variables according to the number of entries + in each unique table. +
                    2. Sift the variable up and down, remembering each time the + total size of the DD heap. At each position, linear transformation + of the two adjacent variables is tried and is accepted if it reduces + the size of the DD. +
                    3. Select the best permutation. +
                    4. Repeat 3 and 4 for all variables. +
                    + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLinear.c + +
                    +
                    +int 
                    +cuddLinearInPlace(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Linearly combines two adjacent variables. Specifically, + replaces the top variable with the exclusive nor of the two variables. + It assumes that no dead nodes are present on entry to this + procedure. The procedure then guarantees that no dead nodes will be + present when it terminates. cuddLinearInPlace assumes that x < + y. Returns the number of keys in the table if successful; 0 + otherwise. +

                    + +

                    Side Effects The two subtables corrresponding to variables x and y are + modified. The global counters of the unique table are also affected. +

                    + +

                    See Also cuddSwapInPlace + + +
                    Defined in cuddLinear.c + +
                    +
                    +static void 
                    +cuddLocalCacheAddToList(
                    +  DdLocalCache * cache 
                    +)
                    +
                    +
                    Inserts a local cache in the manager list. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLCache.c + +
                    +
                    +void 
                    +cuddLocalCacheClearAll(
                    +  DdManager * manager 
                    +)
                    +
                    +
                    Clears the local caches of a manager. + Used before reordering. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLCache.c + +
                    +
                    +void 
                    +cuddLocalCacheClearDead(
                    +  DdManager * manager 
                    +)
                    +
                    +
                    Clears the dead entries of the local caches of a manager. + Used during garbage collection. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLCache.c + +
                    +
                    +DdLocalCache * 
                    +cuddLocalCacheInit(
                    +  DdManager * manager, manager
                    +  unsigned int  keySize, size of the key (number of operands)
                    +  unsigned int  cacheSize, Initial size of the cache
                    +  unsigned int  maxCacheSize Size of the cache beyond which no resizing occurs
                    +)
                    +
                    +
                    Initializes a computed table. Returns a pointer the + the new local cache in case of success; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddInitCache + + +
                    Defined in cuddLCache.c + +
                    +
                    +void 
                    +cuddLocalCacheInsert(
                    +  DdLocalCache * cache, 
                    +  DdNodePtr * key, 
                    +  DdNode * value 
                    +)
                    +
                    +
                    Inserts a result in a local cache. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLCache.c + +
                    +
                    +DdNode * 
                    +cuddLocalCacheLookup(
                    +  DdLocalCache * cache, 
                    +  DdNodePtr * key 
                    +)
                    +
                    +
                    Looks up in a local cache. Returns the result if found; + it returns NULL if no result is found. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLCache.c + +
                    +
                    +int 
                    +cuddLocalCacheProfile(
                    +  DdLocalCache * cache 
                    +)
                    +
                    +
                    Computes and prints a profile of a local cache usage. + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLCache.c + +
                    +
                    +void 
                    +cuddLocalCacheQuit(
                    +  DdLocalCache * cache cache to be shut down
                    +)
                    +
                    +
                    Initializes the computed table. It is called by + Cudd_Init. Returns a pointer the the new local cache in case of + success; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddLocalCacheInit + + +
                    Defined in cuddLCache.c + +
                    +
                    +static void 
                    +cuddLocalCacheRemoveFromList(
                    +  DdLocalCache * cache 
                    +)
                    +
                    +
                    Removes a local cache from the manager list. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLCache.c + +
                    +
                    +static void 
                    +cuddLocalCacheResize(
                    +  DdLocalCache * cache 
                    +)
                    +
                    +
                    Resizes a local cache. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLCache.c + +
                    +
                    +DdNode	* 
                    +cuddMakeBddFromZddCover(
                    +  DdManager * dd, 
                    +  DdNode * node 
                    +)
                    +
                    +
                    Converts a ZDD cover to a BDD. If successful, it returns + a BDD node, otherwise it returns NULL. It is a recursive algorithm + that works as follows. First it computes 3 cofactors of a ZDD cover: + f1, f0 and fd. Second, it compute BDDs (b1, b0 and bd) of f1, f0 and fd. + Third, it computes T=b1+bd and E=b0+bd. Fourth, it computes ITE(v,T,E) where + v is the variable which has the index of the top node of the ZDD cover. + In this case, since the index of v can be larger than either the one of T + or the one of E, cuddUniqueInterIVO is called, where IVO stands for + independent from variable ordering. +

                    + +

                    See Also Cudd_MakeBddFromZddCover + + +
                    Defined in cuddZddIsop.c + +
                    +
                    +static int 
                    +cuddMinHammingDistRecur(
                    +  DdNode * f, 
                    +  int * minterm, 
                    +  DdHashTable * table, 
                    +  int  upperBound 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_MinHammingDist. + It is based on the following identity. Let H(f) be the + minimum Hamming distance of the minterms of f from the reference + minterm. Then: + + H(f) = min(H(f0)+h0,H(f1)+h1) + + where f0 and f1 are the two cofactors of f with respect to its top + variable; h0 is 1 if the minterm assigns 1 to the top variable of f; + h1 is 1 if the minterm assigns 0 to the top variable of f. + The upper bound on the distance is used to bound the depth of the + recursion. + Returns the minimum distance unless it exceeds the upper bound or + computation fails. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_MinHammingDist + + +
                    Defined in cuddPriority.c + +
                    +
                    +int 
                    +cuddNextHigh(
                    +  DdManager * table, 
                    +  int  x 
                    +)
                    +
                    +
                    Finds the next subtable with a larger index. Returns the + index. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddNextLow + + +
                    Defined in cuddReorder.c + +
                    +
                    +int 
                    +cuddNextLow(
                    +  DdManager * table, 
                    +  int  x 
                    +)
                    +
                    +
                    Finds the next subtable with a smaller index. Returns the + index. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddNextHigh + + +
                    Defined in cuddReorder.c + +
                    +
                    +static int 
                    +cuddNodeArrayRecur(
                    +  DdNode * f, 
                    +  DdNodePtr * table, 
                    +  int  index 
                    +)
                    +
                    +
                    Performs the recursive step of cuddNodeArray. Returns + an the number of nodes in the DD. Clear the least significant bit + of the next field that was used as visited flag by + cuddNodeArrayRecur when counting the nodes. node is supposed to be + regular; the invariant is maintained by this procedure. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +DdNodePtr * 
                    +cuddNodeArray(
                    +  DdNode * f, 
                    +  int * n 
                    +)
                    +
                    +
                    Traverses the DD f and collects all its nodes in an array. + The caller should free the array returned by cuddNodeArray. + Returns a pointer to the array of nodes in case of success; NULL + otherwise. The nodes are collected in reverse topological order, so + that a node is always preceded in the array by all its descendants. +

                    + +

                    Side Effects The number of nodes is returned as a side effect. +

                    + +

                    See Also Cudd_FirstNode + + +
                    Defined in cuddUtil.c + +
                    +
                    +static void 
                    +cuddOrderedInsert(
                    +  DdNodePtr * root, 
                    +  DdNodePtr  node 
                    +)
                    +
                    +
                    Inserts a DdNode in a red/black search tree. Nodes from + the same "page" (defined by DD_PAGE_MASK) are linked in a LIFO list. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddOrderedThread + + +
                    Defined in cuddTable.c + +
                    +
                    +static DdNode * 
                    +cuddOrderedThread(
                    +  DdNode * root, 
                    +  DdNode * list 
                    +)
                    +
                    +
                    Threads all the nodes of a search tree into a linear + list. For each node of the search tree, the "left" child, if non-null, has + a lower address than its parent, and the "right" child, if non-null, has a + higher address than its parent. + The list is sorted in order of increasing addresses. The search + tree is destroyed as a result of this operation. The last element of + the linear list is made to point to the address passed in list. Each + node if the search tree is a linearly-linked list of nodes from the + same memory page (as defined in DD_PAGE_MASK). When a node is added to + the linear list, all the elements of the linked list are added. +

                    + +

                    Side Effects The search tree is destroyed as a result of this operation. +

                    + +

                    See Also cuddOrderedInsert + + +
                    Defined in cuddTable.c + +
                    +
                    +void 
                    +cuddPrintNode(
                    +  DdNode * f, 
                    +  FILE * fp 
                    +)
                    +
                    +
                    Prints out information on a node. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCheck.c + +
                    +
                    +void 
                    +cuddPrintVarGroups(
                    +  DdManager * dd, manager
                    +  MtrNode * root, root of the group tree
                    +  int  zdd, 0: BDD; 1: ZDD
                    +  int  silent flag to check tree syntax only
                    +)
                    +
                    +
                    Prints the variable groups as a parenthesized list. + For each group the level range that it represents is printed. After + each group, the group's flags are printed, preceded by a `|'. For + each flag (except MTR_TERMINAL) a character is printed. +
                      +
                    • F: MTR_FIXED +
                    • N: MTR_NEWNODE +
                    • S: MTR_SOFT +
                    + The second argument, silent, if different from 0, causes + Cudd_PrintVarGroups to only check the syntax of the group tree. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCheck.c + +
                    +
                    +int 
                    +cuddP(
                    +  DdManager * dd, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Prints a DD to the standard output. One line per node is + printed. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_PrintDebug + + +
                    Defined in cuddUtil.c + +
                    +
                    +void 
                    +cuddReclaimZdd(
                    +  DdManager * table, 
                    +  DdNode * n 
                    +)
                    +
                    +
                    Brings children of a dead ZDD node back. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddReclaim + + +
                    Defined in cuddRef.c + +
                    +
                    +void 
                    +cuddReclaim(
                    +  DdManager * table, 
                    +  DdNode * n 
                    +)
                    +
                    +
                    Brings children of a dead node back. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddReclaimZdd + + +
                    Defined in cuddRef.c + +
                    +
                    +void 
                    +cuddRehash(
                    +  DdManager * unique, 
                    +  int  i 
                    +)
                    +
                    +
                    Doubles the size of a unique subtable and rehashes its + contents. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddTable.c + +
                    +
                    +DdNode * 
                    +cuddRemapUnderApprox(
                    +  DdManager * dd, DD manager
                    +  DdNode * f, current DD
                    +  int  numVars, maximum number of variables
                    +  int  threshold, threshold under which approximation stops
                    +  double  quality minimum improvement for accepted changes
                    +)
                    +
                    +
                    Applies the remapping underappoximation algorithm. + Proceeds in three phases: +
                      +
                    • collect information on each node in the BDD; this is done via DFS. +
                    • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
                    • traverse the BDD via DFS and actually perform the elimination. +
                    + Returns the approximated BDD if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_RemapUnderApprox + + +
                    Defined in cuddApprox.c + +
                    +
                    +int 
                    +cuddResizeLinear(
                    +  DdManager * table 
                    +)
                    +
                    +
                    Resizes the linear transform matrix. Returns 1 if + successful; 0 otherwise. +

                    + +

                    Side Effects none +

                    + +

                    Defined in cuddLinear.c + +
                    +
                    +int 
                    +cuddResizeTableZdd(
                    +  DdManager * unique, 
                    +  int  index 
                    +)
                    +
                    +
                    Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index. When new ZDD variables are created, it + is possible to preserve the functions unchanged, or it is possible to + preserve the covers unchanged, but not both. cuddResizeTableZdd preserves + the covers. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also ddResizeTable + + +
                    Defined in cuddTable.c + +
                    +
                    +void 
                    +cuddSetInteract(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Given a pair of variables 0 <= x < y < table->size, + sets the corresponding bit of the interaction matrix to 1. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddInteract.c + +
                    +
                    +void 
                    +cuddShrinkDeathRow(
                    +  DdManager * table 
                    +)
                    +
                    +
                    Shrinks the death row by a factor of four. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddClearDeathRow + + +
                    Defined in cuddRef.c + +
                    +
                    +void 
                    +cuddShrinkSubtable(
                    +  DdManager * unique, 
                    +  int  i 
                    +)
                    +
                    +
                    Shrinks a subtable. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddRehash + + +
                    Defined in cuddTable.c + +
                    +
                    +int 
                    +cuddSifting(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Implementation of Rudell's sifting algorithm. + Assumes that no dead nodes are present. +
                      +
                    1. Order all the variables according to the number of entries + in each unique table. +
                    2. Sift the variable up and down, remembering each time the + total size of the DD heap. +
                    3. Select the best permutation. +
                    4. Repeat 3 and 4 for all variables. +
                    + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +void 
                    +cuddSlowTableGrowth(
                    +  DdManager * unique 
                    +)
                    +
                    +
                    Adjusts parameters of a table to slow down its growth. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddTable.c + +
                    +
                    +DdNode * 
                    +cuddSolveEqnRecur(
                    +  DdManager * bdd, 
                    +  DdNode * F, the left-hand side of the equation
                    +  DdNode * Y, the cube of remaining y variables
                    +  DdNode ** G, the array of solutions
                    +  int  n, number of unknowns
                    +  int * yIndex, array holding the y variable indices
                    +  int  i level of recursion
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_SolveEqn. + Returns NULL if the intermediate solution blows up + or reordering occurs. The parametric solutions are + stored in the array G. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_SolveEqn +Cudd_VerifySol + + +
                    Defined in cuddSolve.c + +
                    +
                    +DdNode* 
                    +cuddSplitSetRecur(
                    +  DdManager * manager, 
                    +  st_table * mtable, 
                    +  int * varSeen, 
                    +  DdNode * p, 
                    +  double  n, 
                    +  double  max, 
                    +  int  index 
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_SplitSet. The + procedure recursively traverses the BDD and checks to see if any + node satisfies the minterm requirements as specified by 'n'. At any + node X, n is compared to the number of minterms in the onset of X's + children. If either of the child nodes have exactly n minterms, then + that node is returned; else, if n is greater than the onset of one + of the child nodes, that node is retained and the difference in the + number of minterms is extracted from the other child. In case n + minterms can be extracted from constant 1, the algorithm returns the + result with at most log(n) nodes. +

                    + +

                    Side Effects The array 'varSeen' is updated at every recursive call + to set the variables traversed by the procedure. +

                    + +

                    Defined in cuddSplit.c + +
                    +
                    +enum st_retval 
                    +cuddStCountfree(
                    +  char * key, 
                    +  char * value, 
                    +  char * arg 
                    +)
                    +
                    +
                    Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +DdNode * 
                    +cuddSubsetHeavyBranch(
                    +  DdManager * dd, DD manager
                    +  DdNode * f, current DD
                    +  int  numVars, maximum number of variables
                    +  int  threshold threshold size for the subset
                    +)
                    +
                    +
                    Here a subset BDD is built by throwing away one of the + children. Starting at root, annotate each node with the number of + minterms (in terms of the total number of variables specified - + numVars), number of nodes taken by the DAG rooted at this node and + number of additional nodes taken by the child that has the lesser + minterms. The child with the lower number of minterms is thrown away + and a dyanmic count of the nodes of the subset is kept. Once the + threshold is reached the subset is returned to the calling + procedure. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_SubsetHeavyBranch + + +
                    Defined in cuddSubsetHB.c + +
                    +
                    +DdNode * 
                    +cuddSubsetShortPaths(
                    +  DdManager * dd, DD manager
                    +  DdNode * f, function to be subset
                    +  int  numVars, total number of variables in consideration
                    +  int  threshold, maximum number of nodes allowed in the subset
                    +  int  hardlimit flag determining whether threshold should be respected strictly
                    +)
                    +
                    +
                    The outermost procedure to return a subset of the given + BDD with the largest cubes. The path lengths are calculated, the maximum + allowable path length is determined and the number of nodes of this + path length that can be used to build a subset. If the threshold is + larger than the size of the original BDD, the original BDD is + returned. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_SubsetShortPaths + + +
                    Defined in cuddSubsetSP.c + +
                    +
                    +int 
                    +cuddSwapInPlace(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Swaps two adjacent variables. It assumes that no dead + nodes are present on entry to this procedure. The procedure then + guarantees that no dead nodes will be present when it terminates. + cuddSwapInPlace assumes that x < y. Returns the number of keys in + the table if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +int 
                    +cuddSwapping(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper, 
                    +  Cudd_ReorderingType  heuristic 
                    +)
                    +
                    +
                    Implementation of Plessier's algorithm that reorders + variables by a sequence of (non-adjacent) swaps. +
                      +
                    1. Select two variables (RANDOM or HEURISTIC). +
                    2. Permute these variables. +
                    3. If the nodes have decreased accept the permutation. +
                    4. Otherwise reconstruct the original heap. +
                    5. Loop. +
                    + Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +int 
                    +cuddSymmCheck(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Checks for symmetry of x and y. Ignores projection + functions, unless they are isolated. Returns 1 in case of symmetry; 0 + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSymmetry.c + +
                    +
                    +int 
                    +cuddSymmSiftingConv(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Symmetric sifting to convergence algorithm. + Assumes that no dead nodes are present. +
                      +
                    1. Order all the variables according to the number of entries in + each unique subtable. +
                    2. Sift the variable up and down, remembering each time the total + size of the DD heap and grouping variables that are symmetric. +
                    3. Select the best permutation. +
                    4. Repeat 3 and 4 for all variables. +
                    5. Repeat 1-4 until no further improvement. +
                    + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddSymmSifting + + +
                    Defined in cuddSymmetry.c + +
                    +
                    +int 
                    +cuddSymmSifting(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Symmetric sifting algorithm. + Assumes that no dead nodes are present. +
                      +
                    1. Order all the variables according to the number of entries in + each unique subtable. +
                    2. Sift the variable up and down, remembering each time the total + size of the DD heap and grouping variables that are symmetric. +
                    3. Select the best permutation. +
                    4. Repeat 3 and 4 for all variables. +
                    + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddSymmSiftingConv + + +
                    Defined in cuddSymmetry.c + +
                    +
                    +int 
                    +cuddTestInteract(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Given a pair of variables 0 <= x < y < table->size, + tests whether the corresponding bit of the interaction matrix is 1. + Returns the value of the bit. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddInteract.c + +
                    +
                    +int 
                    +cuddTimesInDeathRow(
                    +  DdManager * dd, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Counts how many times a node is in the death row. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_DelayedDerefBdd +cuddClearDeathRow +cuddIsInDeathRow + + +
                    Defined in cuddRef.c + +
                    +
                    +int 
                    +cuddTreeSifting(
                    +  DdManager * table, DD table
                    +  Cudd_ReorderingType  method reordering method for the groups of leaves
                    +)
                    +
                    +
                    Tree sifting algorithm. Assumes that a tree representing + a group hierarchy is passed as a parameter. It then reorders each + group in postorder fashion by calling ddTreeSiftingAux. Assumes that + no dead nodes are present. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +DdNode * 
                    +cuddUnderApprox(
                    +  DdManager * dd, DD manager
                    +  DdNode * f, current DD
                    +  int  numVars, maximum number of variables
                    +  int  threshold, threshold under which approximation stops
                    +  int  safe, enforce safe approximation
                    +  double  quality minimum improvement for accepted changes
                    +)
                    +
                    +
                    Applies Tom Shiple's underappoximation algorithm. Proceeds + in three phases: +
                      +
                    • collect information on each node in the BDD; this is done via DFS. +
                    • traverse the BDD in top-down fashion and compute for each node + whether its elimination increases density. +
                    • traverse the BDD via DFS and actually perform the elimination. +
                    + Returns the approximated BDD if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_UnderApprox + + +
                    Defined in cuddApprox.c + +
                    +
                    +DdNode * 
                    +cuddUniqueConst(
                    +  DdManager * unique, 
                    +  CUDD_VALUE_TYPE  value 
                    +)
                    +
                    +
                    Checks the unique table for the existence of a constant node. + If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. Returns a + pointer to the new node. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddTable.c + +
                    +
                    +DdNode * 
                    +cuddUniqueInterIVO(
                    +  DdManager * unique, 
                    +  int  index, 
                    +  DdNode * T, 
                    +  DdNode * E 
                    +)
                    +
                    +
                    Wrapper for cuddUniqueInter that is independent of + variable ordering (IVO). This function does not require parameter + index to precede the indices of the top nodes of T and E in the + variable order. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddUniqueInter +Cudd_MakeBddFromZddCover + + +
                    Defined in cuddTable.c + +
                    +
                    +DdNode * 
                    +cuddUniqueInterZdd(
                    +  DdManager * unique, 
                    +  int  index, 
                    +  DdNode * T, 
                    +  DdNode * E 
                    +)
                    +
                    +
                    Checks the unique table for the existence of an internal + ZDD node. If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. For a newly + created node, increments the reference counts of what T and E point + to. Returns a pointer to the new node if successful; NULL if memory + is exhausted or if reordering took place. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddUniqueInter + + +
                    Defined in cuddTable.c + +
                    +
                    +DdNode * 
                    +cuddUniqueInter(
                    +  DdManager * unique, 
                    +  int  index, 
                    +  DdNode * T, 
                    +  DdNode * E 
                    +)
                    +
                    +
                    Checks the unique table for the existence of an internal + node. If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. For a newly + created node, increments the reference counts of what T and E point + to. Returns a pointer to the new node if successful; NULL if memory + is exhausted or if reordering took place. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddUniqueInterZdd + + +
                    Defined in cuddTable.c + +
                    +
                    +static DdNode * 
                    +cuddUniqueLookup(
                    +  DdManager * unique, 
                    +  int  index, 
                    +  DdNode * T, 
                    +  DdNode * E 
                    +)
                    +
                    +
                    Checks the unique table for the existence of an internal + node. Returns a pointer to the node if it is in the table; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddUniqueInter + + +
                    Defined in cuddUtil.c + +
                    +
                    +void 
                    +cuddUpdateInteractionMatrix(
                    +  DdManager * table, 
                    +  int  xindex, 
                    +  int  yindex 
                    +)
                    +
                    +
                    Updates the interaction matrix. +

                    + +

                    Side Effects none +

                    + +

                    Defined in cuddLinear.c + +
                    +
                    +DdNode * 
                    +cuddVerifySol(
                    +  DdManager * bdd, 
                    +  DdNode * F, the left-hand side of the equation
                    +  DdNode ** G, the array of solutions
                    +  int * yIndex, array holding the y variable indices
                    +  int  n number of unknowns
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_VerifySol. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_VerifySol + + +
                    Defined in cuddSolve.c + +
                    +
                    +int 
                    +cuddWindowReorder(
                    +  DdManager * table, DD table
                    +  int  low, lowest index to reorder
                    +  int  high, highest index to reorder
                    +  Cudd_ReorderingType  submethod window reordering option
                    +)
                    +
                    +
                    Reorders by applying the method of the sliding window. + Tries all possible permutations to the variables in a window that + slides from low to high. The size of the window is determined by + submethod. Assumes that no dead nodes are present. Returns 1 in + case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddWindow.c + +
                    +
                    +static void 
                    +cuddXorLinear(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    XORs two rows of the linear transform matrix and replaces + the first row with the result. +

                    + +

                    Side Effects none +

                    + +

                    Defined in cuddLinear.c + +
                    +
                    +int 
                    +cuddZddAlignToBdd(
                    +  DdManager * table DD manager
                    +)
                    +
                    +
                    Reorders ZDD variables according to the order of the + BDD variables. This function can be called at the end of BDD + reordering to insure that the order of the ZDD variables is + consistent with the order of the BDD variables. The number of ZDD + variables must be a multiple of the number of BDD variables. Let + M be the ratio of the two numbers. cuddZddAlignToBdd + then considers the ZDD variables from M*i to + (M+1)*i-1 as corresponding to BDD variable + i. This function should be normally called from + Cudd_ReduceHeap, which clears the cache. Returns 1 in case of + success; 0 otherwise. +

                    + +

                    Side Effects Changes the ZDD variable order for all diagrams and performs + garbage collection of the ZDD unique table. +

                    + +

                    See Also Cudd_zddShuffleHeap +Cudd_ReduceHeap + + +
                    Defined in cuddZddReord.c + +
                    +
                    +DdNode * 
                    +cuddZddChangeAux(
                    +  DdManager * zdd, 
                    +  DdNode * P, 
                    +  DdNode * zvar 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddChange. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSetop.c + +
                    +
                    +DdNode * 
                    +cuddZddChange(
                    +  DdManager * dd, 
                    +  DdNode * P, 
                    +  int  var 
                    +)
                    +
                    +
                    Substitutes a variable with its complement in a ZDD. + returns a pointer to the result if successful; NULL + otherwise. cuddZddChange performs the same function as + Cudd_zddChange, but does not restart if reordering has taken + place. Therefore it can be called from within a recursive + procedure. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_zddChange + + +
                    Defined in cuddZddSetop.c + +
                    +
                    +DdNode	* 
                    +cuddZddComplement(
                    +  DdManager * dd, 
                    +  DdNode * node 
                    +)
                    +
                    +
                    Computes the complement of a ZDD node. So far, since we + couldn't find a direct way to get the complement of a ZDD cover, we first + convert a ZDD cover to a BDD, then make the complement of the ZDD cover + from the complement of the BDD node by using ISOP. +

                    + +

                    Side Effects The result depends on current variable order. +

                    + +

                    Defined in cuddZddFuncs.c + +
                    +
                    +static double 
                    +cuddZddCountDoubleStep(
                    +  DdNode * P, 
                    +  st_table * table, 
                    +  DdNode * base, 
                    +  DdNode * empty 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddCountDouble. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddCount.c + +
                    +
                    +static int 
                    +cuddZddCountStep(
                    +  DdNode * P, 
                    +  st_table * table, 
                    +  DdNode * base, 
                    +  DdNode * empty 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddCount. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddCount.c + +
                    +
                    +static int 
                    +cuddZddDagInt(
                    +  DdNode * n, 
                    +  st_table * tab 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddDagSize. Does + not check for out-of-memory conditions. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddMisc.c + +
                    +
                    +DdNode * 
                    +cuddZddDiff(
                    +  DdManager * zdd, 
                    +  DdNode * P, 
                    +  DdNode * Q 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddDiff. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSetop.c + +
                    +
                    +DdNode	* 
                    +cuddZddDivideF(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddDivideF. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_zddDivideF + + +
                    Defined in cuddZddFuncs.c + +
                    +
                    +DdNode	* 
                    +cuddZddDivide(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddDivide. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_zddDivide + + +
                    Defined in cuddZddFuncs.c + +
                    +
                    +void 
                    +cuddZddFreeUniv(
                    +  DdManager * zdd 
                    +)
                    +
                    +
                    Frees the ZDD universe. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddZddInitUniv + + +
                    Defined in cuddInit.c + +
                    +
                    +int 
                    +cuddZddGetCofactors2(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  int  v, 
                    +  DdNode ** f1, 
                    +  DdNode ** f0 
                    +)
                    +
                    +
                    Computes the two-way decomposition of f w.r.t. v. +

                    + +

                    Side Effects The results are returned in f1 and f0. +

                    + +

                    See Also cuddZddGetCofactors3 + + +
                    Defined in cuddZddFuncs.c + +
                    +
                    +int 
                    +cuddZddGetCofactors3(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  int  v, 
                    +  DdNode ** f1, 
                    +  DdNode ** f0, 
                    +  DdNode ** fd 
                    +)
                    +
                    +
                    Computes the three-way decomposition of function f (represented + by a ZDD) wit respect to variable v. Returns 0 if successful; 1 otherwise. +

                    + +

                    Side Effects The results are returned in f1, f0, and fd. +

                    + +

                    See Also cuddZddGetCofactors2 + + +
                    Defined in cuddZddFuncs.c + +
                    +
                    +int 
                    +cuddZddGetNegVarIndex(
                    +  DdManager * dd, 
                    +  int  index 
                    +)
                    +
                    +
                    Returns the index of negative ZDD variable. +

                    + +

                    Defined in cuddZddFuncs.c + +
                    +
                    +int 
                    +cuddZddGetNegVarLevel(
                    +  DdManager * dd, 
                    +  int  index 
                    +)
                    +
                    +
                    Returns the level of negative ZDD variable. +

                    + +

                    Defined in cuddZddFuncs.c + +
                    +
                    +DdNode * 
                    +cuddZddGetNodeIVO(
                    +  DdManager * dd, 
                    +  int  index, 
                    +  DdNode * g, 
                    +  DdNode * h 
                    +)
                    +
                    +
                    Wrapper for cuddUniqueInterZdd that is independent of + variable ordering (IVO). This function does not require parameter + index to precede the indices of the top nodes of g and h in the + variable order. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddZddGetNode +cuddZddIsop + + +
                    Defined in cuddTable.c + +
                    +
                    +DdNode * 
                    +cuddZddGetNode(
                    +  DdManager * zdd, 
                    +  int  id, 
                    +  DdNode * T, 
                    +  DdNode * E 
                    +)
                    +
                    +
                    Wrapper for cuddUniqueInterZdd, which applies the ZDD + reduction rule. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddUniqueInterZdd + + +
                    Defined in cuddTable.c + +
                    +
                    +int 
                    +cuddZddGetPosVarIndex(
                    +  DdManager * dd, 
                    +  int  index 
                    +)
                    +
                    +
                    Returns the index of positive ZDD variable. +

                    + +

                    Defined in cuddZddFuncs.c + +
                    +
                    +int 
                    +cuddZddGetPosVarLevel(
                    +  DdManager * dd, 
                    +  int  index 
                    +)
                    +
                    +
                    Returns the level of positive ZDD variable. +

                    + +

                    Defined in cuddZddFuncs.c + +
                    +
                    +int 
                    +cuddZddInitUniv(
                    +  DdManager * zdd 
                    +)
                    +
                    +
                    Initializes the ZDD universe. Returns 1 if successful; 0 + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddZddFreeUniv + + +
                    Defined in cuddInit.c + +
                    +
                    +DdNode * 
                    +cuddZddIntersect(
                    +  DdManager * zdd, 
                    +  DdNode * P, 
                    +  DdNode * Q 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddIntersect. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSetop.c + +
                    +
                    +DdNode	* 
                    +cuddZddIsop(
                    +  DdManager * dd, 
                    +  DdNode * L, 
                    +  DdNode * U, 
                    +  DdNode ** zdd_I 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddIsop. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_zddIsop + + +
                    Defined in cuddZddIsop.c + +
                    +
                    +DdNode * 
                    +cuddZddIte(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g, 
                    +  DdNode * h 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddIte. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSetop.c + +
                    +
                    +static int 
                    +cuddZddLinearAux(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xLow, 
                    +  int  xHigh 
                    +)
                    +
                    +
                    Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddLin.c + +
                    +
                    +static int 
                    +cuddZddLinearBackward(
                    +  DdManager * table, 
                    +  int  size, 
                    +  Move * moves 
                    +)
                    +
                    +
                    Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddLin.c + +
                    +
                    +static Move * 
                    +cuddZddLinearDown(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xHigh, 
                    +  Move * prevMoves 
                    +)
                    +
                    +
                    Sifts a variable down. Moves x down until either it + reaches the bound (xHigh) or the size of the ZDD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddLin.c + +
                    +
                    +static int 
                    +cuddZddLinearInPlace(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Linearly combines two adjacent variables. It assumes + that no dead nodes are present on entry to this procedure. The + procedure then guarantees that no dead nodes will be present when it + terminates. cuddZddLinearInPlace assumes that x < y. Returns the + number of keys in the table if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddZddSwapInPlace +cuddLinearInPlace + + +
                    Defined in cuddZddLin.c + +
                    +
                    +int 
                    +cuddZddLinearSifting(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Implementation of the linear sifting algorithm for ZDDs. + Assumes that no dead nodes are present. +
                      +
                    1. Order all the variables according to the number of entries + in each unique table. +
                    2. Sift the variable up and down and applies the XOR transformation, + remembering each time the total size of the DD heap. +
                    3. Select the best permutation. +
                    4. Repeat 3 and 4 for all variables. +
                    + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddLin.c + +
                    +
                    +static Move * 
                    +cuddZddLinearUp(
                    +  DdManager * table, 
                    +  int  y, 
                    +  int  xLow, 
                    +  Move * prevMoves 
                    +)
                    +
                    +
                    Sifts a variable up applying the XOR + transformation. Moves y up until either it reaches the bound (xLow) + or the size of the ZDD heap increases too much. Returns the set of + moves in case of success; NULL if memory is full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddLin.c + +
                    +
                    +int 
                    +cuddZddNextHigh(
                    +  DdManager * table, 
                    +  int  x 
                    +)
                    +
                    +
                    Finds the next subtable with a larger index. Returns the + index. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +int 
                    +cuddZddNextLow(
                    +  DdManager * table, 
                    +  int  x 
                    +)
                    +
                    +
                    Finds the next subtable with a smaller index. Returns the + index. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +DdNode	* 
                    +cuddZddProduct(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddProduct. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_zddProduct + + +
                    Defined in cuddZddFuncs.c + +
                    +
                    +int 
                    +cuddZddP(
                    +  DdManager * zdd, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Prints a ZDD to the standard output. One line per node is + printed. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_zddPrintDebug + + +
                    Defined in cuddZddUtil.c + +
                    +
                    +static int 
                    +cuddZddSiftingAux(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  x_low, 
                    +  int  x_high 
                    +)
                    +
                    +
                    Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +static int 
                    +cuddZddSiftingBackward(
                    +  DdManager * table, 
                    +  Move * moves, 
                    +  int  size 
                    +)
                    +
                    +
                    Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +static Move * 
                    +cuddZddSiftingDown(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  x_high, 
                    +  int  initial_size 
                    +)
                    +
                    +
                    Sifts a variable down. Moves x down until either it + reaches the bound (x_high) or the size of the ZDD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +static Move * 
                    +cuddZddSiftingUp(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  x_low, 
                    +  int  initial_size 
                    +)
                    +
                    +
                    Sifts a variable up. Moves y up until either it reaches + the bound (x_low) or the size of the ZDD heap increases too much. + Returns the set of moves in case of success; NULL if memory is full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +int 
                    +cuddZddSifting(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Implementation of Rudell's sifting algorithm. + Assumes that no dead nodes are present. +
                      +
                    1. Order all the variables according to the number of entries + in each unique table. +
                    2. Sift the variable up and down, remembering each time the + total size of the DD heap. +
                    3. Select the best permutation. +
                    4. Repeat 3 and 4 for all variables. +
                    + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +DdNode * 
                    +cuddZddSubset0(
                    +  DdManager * dd, 
                    +  DdNode * P, 
                    +  int  var 
                    +)
                    +
                    +
                    Computes the negative cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is negated. Returns a pointer to + the result if successful; NULL otherwise. cuddZddSubset0 performs + the same function as Cudd_zddSubset0, but does not restart if + reordering has taken place. Therefore it can be called from within a + recursive procedure. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddZddSubset1 +Cudd_zddSubset0 + + +
                    Defined in cuddZddSetop.c + +
                    +
                    +DdNode * 
                    +cuddZddSubset1(
                    +  DdManager * dd, 
                    +  DdNode * P, 
                    +  int  var 
                    +)
                    +
                    +
                    Computes the positive cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is asserted. Returns a pointer to + the result if successful; NULL otherwise. cuddZddSubset1 performs + the same function as Cudd_zddSubset1, but does not restart if + reordering has taken place. Therefore it can be called from within a + recursive procedure. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddZddSubset0 +Cudd_zddSubset1 + + +
                    Defined in cuddZddSetop.c + +
                    +
                    +int 
                    +cuddZddSwapInPlace(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Swaps two adjacent variables. It assumes that no dead + nodes are present on entry to this procedure. The procedure then + guarantees that no dead nodes will be present when it terminates. + cuddZddSwapInPlace assumes that x < y. Returns the number of keys in + the table if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +int 
                    +cuddZddSwapping(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper, 
                    +  Cudd_ReorderingType  heuristic 
                    +)
                    +
                    +
                    Implementation of Plessier's algorithm that reorders + variables by a sequence of (non-adjacent) swaps. +
                      +
                    1. Select two variables (RANDOM or HEURISTIC). +
                    2. Permute these variables. +
                    3. If the nodes have decreased accept the permutation. +
                    4. Otherwise reconstruct the original heap. +
                    5. Loop. +
                    + Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +int 
                    +cuddZddSymmCheck(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Checks for symmetry of x and y. Ignores projection + functions, unless they are isolated. Returns 1 in case of + symmetry; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSymm.c + +
                    +
                    +static int 
                    +cuddZddSymmSiftingAux(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  x_low, 
                    +  int  x_high 
                    +)
                    +
                    +
                    Given x_low <= x <= x_high moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is not part of a symmetry group. Returns 1 if + successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSymm.c + +
                    +
                    +static int 
                    +cuddZddSymmSiftingBackward(
                    +  DdManager * table, 
                    +  Move * moves, 
                    +  int  size 
                    +)
                    +
                    +
                    Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSymm.c + +
                    +
                    +static int 
                    +cuddZddSymmSiftingConvAux(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  x_low, 
                    +  int  x_high 
                    +)
                    +
                    +
                    Given x_low <= x <= x_high moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is either an isolated variable, or it is the bottom of + a symmetry group. All symmetries may not have been found, because of + exceeded growth limit. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSymm.c + +
                    +
                    +int 
                    +cuddZddSymmSiftingConv(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Symmetric sifting to convergence algorithm for ZDDs. + Assumes that no dead nodes are present. +
                      +
                    1. Order all the variables according to the number of entries in + each unique subtable. +
                    2. Sift the variable up and down, remembering each time the total + size of the ZDD heap and grouping variables that are symmetric. +
                    3. Select the best permutation. +
                    4. Repeat 3 and 4 for all variables. +
                    5. Repeat 1-4 until no further improvement. +
                    + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddZddSymmSifting + + +
                    Defined in cuddZddSymm.c + +
                    +
                    +static Move * 
                    +cuddZddSymmSifting_down(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  x_high, 
                    +  int  initial_size 
                    +)
                    +
                    +
                    Moves x down until either it reaches the bound (x_high) + or the size of the ZDD heap increases too much. Assumes that x is the + bottom of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; ZDD_MV_OOM if memory is full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSymm.c + +
                    +
                    +static Move * 
                    +cuddZddSymmSifting_up(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  x_low, 
                    +  int  initial_size 
                    +)
                    +
                    +
                    Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much. Assumes that x is the top + of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; ZDD_MV_OOM if memory is full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSymm.c + +
                    +
                    +int 
                    +cuddZddSymmSifting(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Symmetric sifting algorithm. + Assumes that no dead nodes are present. +
                      +
                    1. Order all the variables according to the number of entries in + each unique subtable. +
                    2. Sift the variable up and down, remembering each time the total + size of the ZDD heap and grouping variables that are symmetric. +
                    3. Select the best permutation. +
                    4. Repeat 3 and 4 for all variables. +
                    + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddZddSymmSiftingConv + + +
                    Defined in cuddZddSymm.c + +
                    +
                    +static void 
                    +cuddZddSymmSummary(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper, 
                    +  int * symvars, 
                    +  int * symgroups 
                    +)
                    +
                    +
                    Counts numbers of symmetric variables and symmetry + groups. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSymm.c + +
                    +
                    +int 
                    +cuddZddTreeSifting(
                    +  DdManager * table, DD table
                    +  Cudd_ReorderingType  method reordering method for the groups of leaves
                    +)
                    +
                    +
                    Tree sifting algorithm for ZDDs. Assumes that a tree + representing a group hierarchy is passed as a parameter. It then + reorders each group in postorder fashion by calling + zddTreeSiftingAux. Assumes that no dead nodes are present. Returns + 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +DdNode	* 
                    +cuddZddUnateProduct(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddUnateProduct. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_zddUnateProduct + + +
                    Defined in cuddZddFuncs.c + +
                    +
                    +static Move* 
                    +cuddZddUndoMoves(
                    +  DdManager * table, 
                    +  Move * moves 
                    +)
                    +
                    +
                    Given a set of moves, returns the ZDD heap to the + order in effect before the moves. Returns 1 in case of success; + 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddLin.c + +
                    +
                    +DdNode * 
                    +cuddZddUnion(
                    +  DdManager * zdd, 
                    +  DdNode * P, 
                    +  DdNode * Q 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddUnion. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSetop.c + +
                    +
                    +int 
                    +cuddZddUniqueCompare(
                    +  int * ptr_x, 
                    +  int * ptr_y 
                    +)
                    +
                    +
                    Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +DdNode	* 
                    +cuddZddWeakDivF(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddWeakDivF. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_zddWeakDivF + + +
                    Defined in cuddZddFuncs.c + +
                    +
                    +DdNode	* 
                    +cuddZddWeakDiv(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * g 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddWeakDiv. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_zddWeakDiv + + +
                    Defined in cuddZddFuncs.c + +
                    +
                    +static DdNode * 
                    +ddBddMaximallyExpand(
                    +  DdManager * dd, manager
                    +  DdNode * lb, cube to be expanded
                    +  DdNode * ub, upper bound cube
                    +  DdNode * f function against which to expand
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_bddMaximallyExpand. + Returns set of primes or zero BDD if successful; NULL otherwise. On entry + to this function, ub and lb should be different from the zero BDD. The + function then maintains this invariant. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSat.c + +
                    +
                    +static int 
                    +ddBddShortestPathUnate(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  int * phases, 
                    +  st_table * table 
                    +)
                    +
                    +
                    Performs shortest path computation on a unate function. + Returns the length of the shortest path to one if successful; + CUDD_OUT_OF_MEM otherwise. This function is based on the observation + that in the BDD of a unate function no node except the constant is + reachable from the root via paths of different parity. +

                    + +

                    Side Effects None +

                    + +

                    See Also getShortest + + +
                    Defined in cuddSat.c + +
                    +
                    +static DdNode * 
                    +ddBddToAddRecur(
                    +  DdManager * dd, 
                    +  DdNode * B 
                    +)
                    +
                    +
                    Performs the recursive step for Cudd_BddToAdd. Returns a + pointer to the resulting ADD if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddBridge.c + +
                    +
                    +static int 
                    +ddCheckPermuation(
                    +  DdManager * table, 
                    +  MtrNode * treenode, 
                    +  int * perm, 
                    +  int * invperm 
                    +)
                    +
                    +
                    Checks the BDD variable group tree before a shuffle. + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects Changes the BDD variable group tree. +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +static void 
                    +ddClearFlag(
                    +  DdNode * f 
                    +)
                    +
                    +
                    Performs a DFS from f, clearing the LSB of the next + pointers. +

                    + +

                    Side Effects None +

                    + +

                    See Also ddSupportStep +ddFindSupport +ddLeavesInt +ddDagInt + + +
                    Defined in cuddUtil.c + +
                    +
                    +static void 
                    +ddClearGlobal(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  maxlevel 
                    +)
                    +
                    +
                    Scans the DD and clears the LSB of the next pointers. + The LSB of the next pointers are used as markers to tell whether a + node was reached. Once the roots are counted, these flags are + reset. +

                    + +

                    Side Effects None +

                    + +

                    See Also ddCountRoots + + +
                    Defined in cuddExact.c + +
                    +
                    +static void 
                    +ddClearGlobal(
                    +  DdManager * table 
                    +)
                    +
                    +
                    The LSB of the next pointers are used as markers to tell + whether a node was reached by at least one DFS. Once the interaction + matrix is built, these flags are reset. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddInteract.c + +
                    +
                    +static void 
                    +ddClearLocal(
                    +  DdNode * f 
                    +)
                    +
                    +
                    Performs a DFS from f, clearing the LSB of the then pointers. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddInteract.c + +
                    +
                    +static void 
                    +ddClearVars(
                    +  DdManager * dd, 
                    +  int  SP 
                    +)
                    +
                    +
                    Clears visited flags for variables. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +static double * 
                    +ddCofMintermAux(
                    +  DdManager * dd, 
                    +  DdNode * node, 
                    +  st_table * table 
                    +)
                    +
                    +
                    Traverses the DD node and computes the fraction of + minterms in the on-set of all positive cofactors simultaneously. + It allocates an array with two more entries than there are + variables below the one labeling the node. One extra entry (the + first in the array) is for the variable labeling the node. The other + entry (the last one in the array) holds the fraction of minterms of + the function rooted at node. Each other entry holds the value for + one cofactor. The array is put in a symbol table, to avoid repeated + computation, and its address is returned by the procedure, for use + by the caller. Returns a pointer to the array of cofactor measures. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSign.c + +
                    +
                    +static int 
                    +ddCountInternalMtrNodes(
                    +  DdManager * table, 
                    +  MtrNode * treenode 
                    +)
                    +
                    +
                    Counts the number of internal nodes of the group tree. + Returns the count. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static double 
                    +ddCountMintermAux(
                    +  DdNode * node, 
                    +  double  max, 
                    +  DdHashTable * table 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_CountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. Does not use the + identity |f'| = max - |f|, to minimize loss of accuracy due to + roundoff. Returns the number of minterms of the function rooted at + node. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +static double 
                    +ddCountPathAux(
                    +  DdNode * node, 
                    +  st_table * table 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_CountPath. + It is based on the following identity. Let |f| be the + number of paths of f. Then: + + |f| = |f0|+|f1| + + where f0 and f1 are the two cofactors of f. Uses the + identity |f'| = |f|, to improve the utilization of the (local) cache. + Returns the number of paths of the function rooted at node. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +static double 
                    +ddCountPathsToNonZero(
                    +  DdNode * N, 
                    +  st_table * table 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_CountPathsToNonZero. + It is based on the following identity. Let |f| be the + number of paths of f. Then: + + |f| = |f0|+|f1| + + where f0 and f1 are the two cofactors of f. Returns the number of + paths of the function rooted at node. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +static int 
                    +ddCountRoots(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Counts the number of roots at the levels between lower and + upper. The computation is based on breadth-first search. + A node is a root if it is not reachable from any previously visited node. + (All the nodes at level lower are therefore considered roots.) + The visited flag uses the LSB of the next pointer. Returns the root + count. The roots that are constant nodes are always ignored. +

                    + +

                    Side Effects None +

                    + +

                    See Also ddClearGlobal + + +
                    Defined in cuddExact.c + +
                    +
                    +static void 
                    +ddCreateGroup(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Creates a group encompassing variables from x to y in the + DD table. In the current implementation it must be y == x+1. + Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddDagInt(
                    +  DdNode * n 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_DagSize. Returns the + number of nodes in the graph rooted at n. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +static void 
                    +ddDissolveGroup(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    x and y are variables in a group to be cut in two. The cut + is to pass between x and y. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddDoDumpBlif(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  FILE * fp, 
                    +  st_table * visited, 
                    +  char ** names, 
                    +  int  mv 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_DumpBlif. Traverses + the BDD f and writes a multiplexer-network description to the file + pointed by fp in blif format. f is assumed to be a regular pointer + and ddDoDumpBlif guarantees this assumption in the recursive calls. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddExport.c + +
                    +
                    +static int 
                    +ddDoDumpDDcal(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  FILE * fp, 
                    +  st_table * visited, 
                    +  char ** names, 
                    +  ptruint  mask 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_DumpDDcal. Traverses + the BDD f and writes a line for each node to the file + pointed by fp in DDcal format. f is assumed to be a regular pointer + and ddDoDumpDDcal guarantees this assumption in the recursive calls. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddExport.c + +
                    +
                    +static int 
                    +ddDoDumpDaVinci(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  FILE * fp, 
                    +  st_table * visited, 
                    +  char ** names, 
                    +  ptruint  mask 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_DumpDaVinci. Traverses + the BDD f and writes a term expression to the file + pointed by fp in daVinci format. f is assumed to be a regular pointer + and ddDoDumpDaVinci guarantees this assumption in the recursive calls. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddExport.c + +
                    +
                    +static int 
                    +ddDoDumpFactoredForm(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  FILE * fp, 
                    +  char ** names 
                    +)
                    +
                    +
                    Performs the recursive step of + Cudd_DumpFactoredForm. Traverses the BDD f and writes a factored + form for each node to the file pointed by fp in terms of the + factored forms of the children. Constants are propagated, and + absorption is applied. f is assumed to be a regular pointer and + ddDoDumpFActoredForm guarantees this assumption in the recursive + calls. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_DumpFactoredForm + + +
                    Defined in cuddExport.c + +
                    +
                    +static int 
                    +ddEpdCountMintermAux(
                    +  DdNode * node, 
                    +  EpDouble * max, 
                    +  EpDouble * epd, 
                    +  st_table * table 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_EpdCountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. Does not use the + identity |f'| = max - |f|, to minimize loss of accuracy due to + roundoff. Returns the number of minterms of the function rooted at + node. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +static enum st_retval 
                    +ddEpdFree(
                    +  char * key, 
                    +  char * value, 
                    +  char * arg 
                    +)
                    +
                    +
                    Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +static int 
                    +ddExchange(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y, 
                    +  double  temp 
                    +)
                    +
                    +
                    This is the same funcion as ddSwapping except for + comparison expression. Use probability function, exp(-size_change/temp). +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAnneal.c + +
                    +
                    +static int 
                    +ddExtSymmCheck(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Checks for extended symmetry of x and y. Returns 1 in + case of extended symmetry; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static DdNode * 
                    +ddFindEssentialRecur(
                    +  DdManager * dd, 
                    +  DdNode * f 
                    +)
                    +
                    +
                    Implements the recursive step of Cudd_FindEssential. + Returns a pointer to the cube BDD if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddEssent.c + +
                    +
                    +static void 
                    +ddFindNodeHiLo(
                    +  DdManager * table, 
                    +  MtrNode * treenode, 
                    +  int * lower, 
                    +  int * upper 
                    +)
                    +
                    +
                    Finds the lower and upper bounds of the group + represented by treenode. From the index and size fields we need to + derive the current positions, and find maximum and minimum. +

                    + +

                    Side Effects The bounds are returned as side effects. +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static void 
                    +ddFindSupport(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  int * SP 
                    +)
                    +
                    +
                    Recursively find the support of f. This function uses the + LSB of the next field of the nodes of f as visited flag. It also uses the + LSB of the next field of the variables as flag to remember whether a + certain index has already been seen. Finally, it uses the manager stack + to record all seen indices. +

                    + +

                    Side Effects The stack pointer SP is modified by side-effect. The next + fields are changed and need to be reset. +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +static DdTlcInfo * 
                    +ddFindTwoLiteralClausesRecur(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  st_table * table 
                    +)
                    +
                    +
                    Implements the recursive step of + Cudd_FindTwoLiteralClauses. The DD node is assumed to be not + constant. Returns a pointer to a set of clauses if successful; NULL + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_FindTwoLiteralClauses + + +
                    Defined in cuddEssent.c + +
                    +
                    +static DdNode * 
                    +ddGetLargestCubeUnate(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  int * phases, 
                    +  st_table * table 
                    +)
                    +
                    +
                    Extracts largest prime of a unate function. Returns the BDD of + the prime if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also getPath + + +
                    Defined in cuddSat.c + +
                    +
                    +static int 
                    +ddGroupMoveBackward(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Undoes the swap two groups. Returns 1 in case of + success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddGroupMove(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y, 
                    +  Move ** moves 
                    +)
                    +
                    +
                    Swaps two groups and records the move. Returns the + number of keys in the DD table in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddGroupSiftingAux(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xLow, 
                    +  int  xHigh, 
                    +  DD_CHKFP  checkFunction, 
                    +  int  lazyFlag 
                    +)
                    +
                    +
                    Sifts one variable up and down until it has taken all + positions. Checks for aggregation. There may be at most two sweeps, + even if the group grows. Assumes that x is either an isolated + variable, or it is the bottom of a group. All groups may not have + been found. The variable being moved is returned to the best position + seen during sifting. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddGroupSiftingBackward(
                    +  DdManager * table, 
                    +  Move * moves, 
                    +  int  size, 
                    +  int  upFlag, 
                    +  int  lazyFlag 
                    +)
                    +
                    +
                    Determines the best position for a variables and returns + it there. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddGroupSiftingDown(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xHigh, 
                    +  DD_CHKFP  checkFunction, 
                    +  Move ** moves 
                    +)
                    +
                    +
                    Sifts down a variable until it reaches position xHigh. + Assumes that x is the bottom of a group (or a singleton). Records + all the moves. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddGroupSiftingUp(
                    +  DdManager * table, 
                    +  int  y, 
                    +  int  xLow, 
                    +  DD_CHKFP  checkFunction, 
                    +  Move ** moves 
                    +)
                    +
                    +
                    Sifts up a variable until either it reaches position + xLow or the size of the DD heap increases too much. Assumes that y is + the top of a group (or a singleton). Checks y for aggregation to the + adjacent variables. Records all the moves that are appended to the + list of moves received as input and returned as a side effect. + Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddGroupSifting(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper, 
                    +  DD_CHKFP  checkFunction, 
                    +  int  lazyFlag 
                    +)
                    +
                    +
                    Sifts from treenode->low to treenode->high. If + croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the + end of the initial sifting. If a group is created, it is then sifted + again. After sifting one variable, the group that contains it is + dissolved. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddIsVarHandled(
                    +  DdManager * dd, 
                    +  int  index 
                    +)
                    +
                    +
                    Checks whether a variables is already handled. This + function is used for lazy sifting. +

                    + +

                    Side Effects none +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddJumpingAux(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  x_low, 
                    +  int  x_high, 
                    +  double  temp 
                    +)
                    +
                    +
                    If x==x_low, it executes jumping_down. If x==x_high, it + executes jumping_up. This funcion is similar to ddSiftingAux. Returns + 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAnneal.c + +
                    +
                    +static Move * 
                    +ddJumpingDown(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  x_high, 
                    +  int  initial_size 
                    +)
                    +
                    +
                    This is a simplified version of ddSiftingDown. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAnneal.c + +
                    +
                    +static Move * 
                    +ddJumpingUp(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  x_low, 
                    +  int  initial_size 
                    +)
                    +
                    +
                    This is a simplified version of ddSiftingUp. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAnneal.c + +
                    +
                    +static int 
                    +ddLeavesInt(
                    +  DdNode * n 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_CountLeaves. Returns + the number of leaves in the DD rooted at n. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_CountLeaves + + +
                    Defined in cuddUtil.c + +
                    +
                    +static int 
                    +ddLinearAndSiftingAux(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xLow, 
                    +  int  xHigh 
                    +)
                    +
                    +
                    Given xLow <= x <= xHigh moves x up and down between the + boundaries. At each step a linear transformation is tried, and, if it + decreases the size of the DD, it is accepted. Finds the best position + and does the required changes. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLinear.c + +
                    +
                    +static int 
                    +ddLinearAndSiftingBackward(
                    +  DdManager * table, 
                    +  int  size, 
                    +  Move * moves 
                    +)
                    +
                    +
                    Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLinear.c + +
                    +
                    +static Move * 
                    +ddLinearAndSiftingDown(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xHigh, 
                    +  Move * prevMoves 
                    +)
                    +
                    +
                    Sifts a variable down and applies linear + transformations. Moves x down until either it reaches the bound + (xHigh) or the size of the DD heap increases too much. Returns the + set of moves in case of success; NULL if memory is full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLinear.c + +
                    +
                    +static Move * 
                    +ddLinearAndSiftingUp(
                    +  DdManager * table, 
                    +  int  y, 
                    +  int  xLow, 
                    +  Move * prevMoves 
                    +)
                    +
                    +
                    Sifts a variable up and applies linear transformations. + Moves y up until either it reaches the bound (xLow) or the size of + the DD heap increases too much. Returns the set of moves in case of + success; NULL if memory is full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLinear.c + +
                    +
                    +static int 
                    +ddLinearUniqueCompare(
                    +  int * ptrX, 
                    +  int * ptrY 
                    +)
                    +
                    +
                    Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLinear.c + +
                    +
                    +static void 
                    +ddMergeGroups(
                    +  DdManager * table, 
                    +  MtrNode * treenode, 
                    +  int  low, 
                    +  int  high 
                    +)
                    +
                    +
                    Creates a single group from low to high and adjusts the + index field of the tree node. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddNoCheck(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Pretends to check two variables for aggregation. Always + returns 0. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static void 
                    +ddPatchTree(
                    +  DdManager * dd, 
                    +  MtrNode * treenode 
                    +)
                    +
                    +
                    Fixes a variable tree after the insertion of new subtables. + After such an insertion, the low fields of the tree below the insertion + point are inconsistent. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddTable.c + +
                    +
                    +static int 
                    +ddPermuteWindow3(
                    +  DdManager * table, 
                    +  int  x 
                    +)
                    +
                    +
                    Tries all the permutations of the three variables between + x and x+2 and retains the best. Assumes that no dead nodes are + present. Returns the index of the best permutation (1-6) in case of + success; 0 otherwise.Assumes that no dead nodes are present. Returns + the index of the best permutation (1-6) in case of success; 0 + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddWindow.c + +
                    +
                    +static int 
                    +ddPermuteWindow4(
                    +  DdManager * table, 
                    +  int  w 
                    +)
                    +
                    +
                    Tries all the permutations of the four variables between + w and w+3 and retains the best. Assumes that no dead nodes are + present. Returns the index of the best permutation (1-24) in case of + success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddWindow.c + +
                    +
                    +static int 
                    +ddPickArbitraryMinterms(
                    +  DdManager * dd, 
                    +  DdNode * node, 
                    +  int  nvars, 
                    +  int  nminterms, 
                    +  char ** string 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_bddPickArbitraryMinterms. + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_bddPickArbitraryMinterms + + +
                    Defined in cuddUtil.c + +
                    +
                    +static int 
                    +ddPickRepresentativeCube(
                    +  DdManager * dd, 
                    +  DdNode * node, 
                    +  double * weight, 
                    +  char * string 
                    +)
                    +
                    +
                    Finds a representative cube of a BDD with the weight of + each variable. From the top variable, if the weight is greater than or + equal to 0.0, choose THEN branch unless the child is the constant 0. + Otherwise, choose ELSE branch unless the child is the constant 0. +

                    + +

                    Side Effects Cudd_SubsetWithMaskVars Cudd_bddPickOneCube +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +static void 
                    +ddPrintMintermAux(
                    +  DdManager * dd, manager
                    +  DdNode * node, current node
                    +  int * list current recursion path
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_PrintMinterm. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +static void 
                    +ddRehashZdd(
                    +  DdManager * unique, 
                    +  int  i 
                    +)
                    +
                    +
                    Rehashes a ZDD unique subtable. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddRehash + + +
                    Defined in cuddTable.c + +
                    +
                    +static int 
                    +ddReorderChildren(
                    +  DdManager * table, 
                    +  MtrNode * treenode, 
                    +  Cudd_ReorderingType  method 
                    +)
                    +
                    +
                    Reorders the children of a group tree node according to + the options. After reordering puts all the variables in the group + and/or its descendents in a single group. This allows hierarchical + reordering. If the variables in the group do not exist yet, simply + does nothing. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddReorderPostprocess(
                    +  DdManager * table 
                    +)
                    +
                    +
                    Cleans up at the end of reordering. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +static int 
                    +ddReorderPreprocess(
                    +  DdManager * table 
                    +)
                    +
                    +
                    Prepares the DD heap for dynamic reordering. Does + garbage collection, to guarantee that there are no dead nodes; + clears the cache, which is invalidated by dynamic reordering; initializes + the number of isolated projection functions; and initializes the + interaction matrix. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +static void 
                    +ddReportRefMess(
                    +  DdManager * unique, manager
                    +  int  i, table in which the problem occurred
                    +  const char * caller procedure that detected the problem
                    +)
                    +
                    +
                    Reports problem in garbage collection. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddGarbageCollect +cuddGarbageCollectZdd + + +
                    Defined in cuddTable.c + +
                    +
                    +static int 
                    +ddResetVarHandled(
                    +  DdManager * dd, 
                    +  int  index 
                    +)
                    +
                    +
                    Resets a variable to be processed. This function is used + for lazy sifting. +

                    + +

                    Side Effects none +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddResizeTable(
                    +  DdManager * unique, 
                    +  int  index, 
                    +  int  amount 
                    +)
                    +
                    +
                    Increases the number of subtables in a unique table so + that it meets or exceeds index. The parameter amount determines how + much spare space is allocated to prevent too frequent resizing. If + index is negative, the table is resized, but no new variables are + created. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_Reserve +cuddResizeTableZdd + + +
                    Defined in cuddTable.c + +
                    +
                    +static int 
                    +ddSecDiffCheck(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Checks two variables for aggregation. The check is based + on the second difference of the number of nodes as a function of the + layer. If the second difference is lower than a given threshold + (typically negative) then the two variables should be aggregated. + Returns 1 if the two variables pass the test; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddSetVarHandled(
                    +  DdManager * dd, 
                    +  int  index 
                    +)
                    +
                    +
                    Sets a variable to already handled. This function is used + for lazy sifting. +

                    + +

                    Side Effects none +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddShuffle(
                    +  DdManager * table, 
                    +  DdHalfWord * permutation, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Reorders variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. ddShuffle assumes that no + dead nodes are present and that the interaction matrix is properly + initialized. The reordering is achieved by a series of upward sifts. + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddExact.c + +
                    +
                    +static int 
                    +ddShuffle(
                    +  DdManager * table, 
                    +  int * permutation 
                    +)
                    +
                    +
                    Reorders variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. ddShuffle assumes that no + dead nodes are present and that the interaction matrix is properly + initialized. The reordering is achieved by a series of upward sifts. + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +static int 
                    +ddSiftUp(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xLow 
                    +)
                    +
                    +
                    Takes a variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddExact.c + +
                    +
                    +static int 
                    +ddSiftUp(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xLow 
                    +)
                    +
                    +
                    Takes a variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +static int 
                    +ddSiftingAux(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xLow, 
                    +  int  xHigh 
                    +)
                    +
                    +
                    Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +static int 
                    +ddSiftingBackward(
                    +  DdManager * table, 
                    +  int  size, 
                    +  Move * moves 
                    +)
                    +
                    +
                    Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +static Move * 
                    +ddSiftingDown(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xHigh 
                    +)
                    +
                    +
                    Sifts a variable down. Moves x down until either it + reaches the bound (xHigh) or the size of the DD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +static Move * 
                    +ddSiftingUp(
                    +  DdManager * table, 
                    +  int  y, 
                    +  int  xLow 
                    +)
                    +
                    +
                    Sifts a variable up. Moves y up until either it reaches + the bound (xLow) or the size of the DD heap increases too much. + Returns the set of moves in case of success; NULL if memory is full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +static void 
                    +ddSuppInteract(
                    +  DdNode * f, 
                    +  char * support 
                    +)
                    +
                    +
                    Performs a DFS from f. Uses the LSB of the then pointer + as visited flag. +

                    + +

                    Side Effects Accumulates in support the variables on which f depends. +

                    + +

                    Defined in cuddInteract.c + +
                    +
                    +static void 
                    +ddSupportStep(
                    +  DdNode * f, 
                    +  int * support 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_Support. Performs a + DFS from f. The support is accumulated in supp as a side effect. Uses + the LSB of the then pointer as visited flag. +

                    + +

                    Side Effects None +

                    + +

                    See Also ddClearFlag + + +
                    Defined in cuddUtil.c + +
                    +
                    +static Move * 
                    +ddSwapAny(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Swaps any two variables. Returns the set of moves. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +static int 
                    +ddSymmGroupMoveBackward(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Undoes the swap of two groups. x is assumed to be the + bottom variable of the first group. y is assumed to be the top + variable of the second group. Returns the number of keys in the table + if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSymmetry.c + +
                    +
                    +static int 
                    +ddSymmGroupMove(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y, 
                    +  Move ** moves 
                    +)
                    +
                    +
                    Swaps two groups. x is assumed to be the bottom variable + of the first group. y is assumed to be the top variable of the second + group. Updates the list of moves. Returns the number of keys in the + table if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSymmetry.c + +
                    +
                    +static int 
                    +ddSymmSiftingAux(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xLow, 
                    +  int  xHigh 
                    +)
                    +
                    +
                    Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is not part of a symmetry group. Returns 1 if + successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSymmetry.c + +
                    +
                    +static int 
                    +ddSymmSiftingBackward(
                    +  DdManager * table, 
                    +  Move * moves, 
                    +  int  size 
                    +)
                    +
                    +
                    Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSymmetry.c + +
                    +
                    +static int 
                    +ddSymmSiftingConvAux(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xLow, 
                    +  int  xHigh 
                    +)
                    +
                    +
                    Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is either an isolated variable, or it is the bottom of + a symmetry group. All symmetries may not have been found, because of + exceeded growth limit. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSymmetry.c + +
                    +
                    +static Move * 
                    +ddSymmSiftingDown(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xHigh 
                    +)
                    +
                    +
                    Moves x down until either it reaches the bound (xHigh) + or the size of the DD heap increases too much. Assumes that x is the + bottom of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; MV_OOM if memory is full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSymmetry.c + +
                    +
                    +static Move * 
                    +ddSymmSiftingUp(
                    +  DdManager * table, 
                    +  int  y, 
                    +  int  xLow 
                    +)
                    +
                    +
                    Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much. Assumes that x is the top + of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; MV_OOM if memory is full. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSymmetry.c + +
                    +
                    +static void 
                    +ddSymmSummary(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper, 
                    +  int * symvars, 
                    +  int * symgroups 
                    +)
                    +
                    +
                    Counts numbers of symmetric variables and symmetry + groups. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSymmetry.c + +
                    +
                    +static int 
                    +ddSymmUniqueCompare(
                    +  int * ptrX, 
                    +  int * ptrY 
                    +)
                    +
                    +
                    Comparison function used by qsort to order the variables + according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSymmetry.c + +
                    +
                    +static int 
                    +ddTreeSiftingAux(
                    +  DdManager * table, 
                    +  MtrNode * treenode, 
                    +  Cudd_ReorderingType  method 
                    +)
                    +
                    +
                    Recursively visits the group tree and reorders each + group in postorder fashion. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static Move* 
                    +ddUndoMoves(
                    +  DdManager * table, 
                    +  Move * moves 
                    +)
                    +
                    +
                    Given a set of moves, returns the DD heap to the + order in effect before the moves. Returns 1 in case of success; + 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLinear.c + +
                    +
                    +static int 
                    +ddUniqueCompareGroup(
                    +  int * ptrX, 
                    +  int * ptrY 
                    +)
                    +
                    +
                    Comparison function used by qsort to order the variables + according to the number of keys in the subtables. Returns the + difference in number of keys between the two variables being + compared. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddUniqueCompare(
                    +  int * ptrX, 
                    +  int * ptrY 
                    +)
                    +
                    +
                    Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +static void 
                    +ddUpdateInteract(
                    +  DdManager * table, 
                    +  char * support 
                    +)
                    +
                    +
                    If support[i +

                    + +

                    Side Effects Clears support. +

                    + +

                    Defined in cuddInteract.c + +
                    +
                    +static int 
                    +ddUpdateMtrTree(
                    +  DdManager * table, 
                    +  MtrNode * treenode, 
                    +  int * perm, 
                    +  int * invperm 
                    +)
                    +
                    +
                    Updates the BDD variable group tree before a shuffle. + Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects Changes the BDD variable group tree. +

                    + +

                    Defined in cuddReorder.c + +
                    +
                    +static int 
                    +ddVarGroupCheck(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Checks for grouping of x and y. Returns 1 in + case of grouping; 0 otherwise. This function is used for lazy sifting. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGroup.c + +
                    +
                    +static int 
                    +ddWindow2(
                    +  DdManager * table, 
                    +  int  low, 
                    +  int  high 
                    +)
                    +
                    +
                    Reorders by applying a sliding window of width 2. + Tries both permutations of the variables in a window + that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddWindow.c + +
                    +
                    +static int 
                    +ddWindow3(
                    +  DdManager * table, 
                    +  int  low, 
                    +  int  high 
                    +)
                    +
                    +
                    Reorders by applying a sliding window of width 3. + Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddWindow.c + +
                    +
                    +static int 
                    +ddWindow4(
                    +  DdManager * table, 
                    +  int  low, 
                    +  int  high 
                    +)
                    +
                    +
                    Reorders by applying a sliding window of width 4. + Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddWindow.c + +
                    +
                    +static int 
                    +ddWindowConv2(
                    +  DdManager * table, 
                    +  int  low, 
                    +  int  high 
                    +)
                    +
                    +
                    Reorders by repeatedly applying a sliding window of width + 2. Tries both permutations of the variables in a window + that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddWindow.c + +
                    +
                    +static int 
                    +ddWindowConv3(
                    +  DdManager * table, 
                    +  int  low, 
                    +  int  high 
                    +)
                    +
                    +
                    Reorders by repeatedly applying a sliding window of width + 3. Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddWindow.c + +
                    +
                    +static int 
                    +ddWindowConv4(
                    +  DdManager * table, 
                    +  int  low, 
                    +  int  high 
                    +)
                    +
                    +
                    Reorders by repeatedly applying a sliding window of width + 4. Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddWindow.c + +
                    +
                    +static void 
                    +debugCheckParent(
                    +  DdManager * table, 
                    +  DdNode * node 
                    +)
                    +
                    +
                    Searches all the subtables above node. Very expensive. + The same check is now implemented more efficiently in ddDebugCheck. +

                    + +

                    Side Effects None +

                    + +

                    See Also debugFindParent + + +
                    Defined in cuddCheck.c + +
                    +
                    +static void 
                    +debugFindParent(
                    +  DdManager * table, 
                    +  DdNode * node 
                    +)
                    +
                    +
                    Searches the subtables above node for its parents. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCheck.c + +
                    +
                    + 
                    +double *þprobþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +double þmgþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +double þmgþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +double þmþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +double þquality0þminimum improvement for accepted changes when b=0(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +double þquality0þminimum improvement for accepted changes when b=0(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +double þqualityþminimum improvement for accepted changes(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +double þqualityþminimum improvement for accepted changes(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +double þqualityþminimum improvement for accepted changes(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +double þqualityþminimum improvement for accepted changes(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    +static int 
                    +dp2(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  st_table * t 
                    +)
                    +
                    +
                    Performs the recursive step of cuddP. Returns 1 in case + of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +static DdTlcInfo * 
                    +emptyClauseSet(
                    +    
                    +)
                    +
                    +
                    Returns a pointer to an empty set of clauses if + successful; NULL otherwise. No bit vector for the phases is + allocated. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddEssent.c + +
                    +
                    +static int 
                    +equalp(
                    +  DdHalfWord  var1a, 
                    +  short  phase1a, 
                    +  DdHalfWord  var1b, 
                    +  short  phase1b, 
                    +  DdHalfWord  var2a, 
                    +  short  phase2a, 
                    +  DdHalfWord  var2b, 
                    +  short  phase2b 
                    +)
                    +
                    +
                    Returns true iff the two arguments are identical + clauses. Since literals are sorted, we only need to compare + literals in the same position. +

                    + +

                    Side Effects None +

                    + +

                    See Also beforep + + +
                    Defined in cuddEssent.c + +
                    +
                    +static int 
                    +find_best(
                    +    
                    +)
                    +
                    +
                    Returns the index of the fittest individual. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGenetic.c + +
                    +
                    +static void 
                    +fixVarTree(
                    +  MtrNode * treenode, 
                    +  int * perm, 
                    +  int  size 
                    +)
                    +
                    +
                    Fixes a variable group tree. +

                    + +

                    Side Effects Changes the variable group tree. +

                    + +

                    Defined in cuddAPI.c + +
                    +
                    +static void 
                    +freeMatrix(
                    +  DdHalfWord ** matrix 
                    +)
                    +
                    +
                    Frees a two-dimensional matrix allocated by getMatrix. +

                    + +

                    Side Effects None +

                    + +

                    See Also getMatrix + + +
                    Defined in cuddExact.c + +
                    +
                    +static enum st_retval 
                    +freePathPair(
                    +  char * key, 
                    +  char * value, 
                    +  char * arg 
                    +)
                    +
                    +
                    Frees the entries of the visited symbol table. Returns + ST_CONTINUE. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSat.c + +
                    +
                    +static NodeData * 
                    +gatherInfoAux(
                    +  DdNode * node, function to analyze
                    +  ApproxInfo * info, info on BDD
                    +  int  parity gather parity information
                    +)
                    +
                    +
                    Recursively counts minterms and computes reference + counts of each node in the BDD. Similar to the cuddCountMintermAux + which recursively counts the number of minterms for the dag rooted + at each node in terms of the total number of variables (max). It assumes + that the node pointer passed to it is regular and it maintains the + invariant. +

                    + +

                    Side Effects None +

                    + +

                    See Also gatherInfo + + +
                    Defined in cuddApprox.c + +
                    +
                    +static ApproxInfo * 
                    +gatherInfo(
                    +  DdManager * dd, manager
                    +  DdNode * node, function to be analyzed
                    +  int  numVars, number of variables node depends on
                    +  int  parity gather parity information
                    +)
                    +
                    +
                    Counts minterms and computes reference counts of each + node in the BDD. The minterm count is separately computed for the + node and its complement. This is to avoid cancellation + errors. Returns a pointer to the data structure holding the + information gathered if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddUnderApprox +gatherInfoAux + + +
                    Defined in cuddApprox.c + +
                    +
                    +static int 
                    +gcd(
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Returns the gcd of two integers. Uses the binary GCD + algorithm described in Cormen, Leiserson, and Rivest. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddExact.c + +
                    +
                    +static DdNode * 
                    +getCube(
                    +  DdManager * manager, 
                    +  st_table * visited, 
                    +  DdNode * f, 
                    +  int  cost 
                    +)
                    +
                    +
                    Build a BDD for a largest cube of f. + Given the minimum length from the root, and the minimum + lengths for each node (in visited), apply triangulation at each node. + Of the two children of each node on a shortest path, at least one is + on a shortest path. In case of ties the procedure chooses the THEN + children. + Returns a pointer to the cube BDD representing the path if + successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSat.c + +
                    +
                    +static cuddPathPair 
                    +getLargest(
                    +  DdNode * root, 
                    +  st_table * visited 
                    +)
                    +
                    +
                    Finds the size of the largest cube(s) in a DD. + This problem is translated into finding the shortest paths from a node + when both THEN and ELSE arcs have unit lengths. + Uses a local symbol table to store the lengths for each + node. Only the lengths for the regular nodes are entered in the table, + because those for the complement nodes are simply obtained by swapping + the two lenghts. + Returns a pair of lengths: the length of the shortest path to 1; + and the length of the shortest path to 0. This is done so as to take + complement arcs into account. +

                    + +

                    Side Effects none +

                    + +

                    Defined in cuddSat.c + +
                    +
                    +static int 
                    +getLevelKeys(
                    +  DdManager * table, 
                    +  int  l 
                    +)
                    +
                    +
                    Returns the number of nodes at one level of a unique table. + The projection function, if isolated, is not counted. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddExact.c + +
                    +
                    +static DdHalfWord ** 
                    +getMatrix(
                    +  int  rows, number of rows
                    +  int  cols number of columns
                    +)
                    +
                    +
                    Allocates a two-dimensional matrix of ints. + Returns the pointer to the matrix if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also freeMatrix + + +
                    Defined in cuddExact.c + +
                    +
                    +static int 
                    +getMaxBinomial(
                    +  int  n 
                    +)
                    +
                    +
                    Computes the maximum value of (n choose k) for a given + n. The maximum value occurs for k = n/2 when n is even, or k = + (n-1)/2 when n is odd. The algorithm used in this procedure avoids + intermediate overflow problems. It is based on the identity +
                    +    binomial(n,k) = n/k * binomial(n-1,k-1).
                    +  
                    + Returns the computed value if successful; -1 if out of range. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddExact.c + +
                    +
                    +static DdNode * 
                    +getPath(
                    +  DdManager * manager, 
                    +  st_table * visited, 
                    +  DdNode * f, 
                    +  int * weight, 
                    +  int  cost 
                    +)
                    +
                    +
                    Build a BDD for a shortest path of f. + Given the minimum length from the root, and the minimum + lengths for each node (in visited), apply triangulation at each node. + Of the two children of each node on a shortest path, at least one is + on a shortest path. In case of ties the procedure chooses the THEN + children. + Returns a pointer to the cube BDD representing the path if + successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSat.c + +
                    +
                    +static cuddPathPair 
                    +getShortest(
                    +  DdNode * root, 
                    +  int * cost, 
                    +  int * support, 
                    +  st_table * visited 
                    +)
                    +
                    +
                    Finds the length of the shortest path(s) in a DD. + Uses a local symbol table to store the lengths for each + node. Only the lengths for the regular nodes are entered in the table, + because those for the complement nodes are simply obtained by swapping + the two lenghts. + Returns a pair of lengths: the length of the shortest path to 1; + and the length of the shortest path to 0. This is done so as to take + complement arcs into account. +

                    + +

                    Side Effects Accumulates the support of the DD in support. +

                    + +

                    Defined in cuddSat.c + +
                    +
                    +static void 
                    +hashDelete(
                    +  DdLevelQueue * queue, 
                    +  DdQueueItem * item 
                    +)
                    +
                    +
                    Removes an item from the hash table of a level queue. + Nothing is done if the item is not in the table. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddLevelQueueDequeue +hashInsert + + +
                    Defined in cuddLevelQ.c + +
                    +
                    +static int 
                    +hashInsert(
                    +  DdLevelQueue * queue, 
                    +  DdQueueItem * item 
                    +)
                    +
                    +
                    Inserts an item in the hash table of a level queue. Returns + 1 if successful; 0 otherwise. No check is performed to see if an item with + the same key is already in the hash table. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddLevelQueueEnqueue + + +
                    Defined in cuddLevelQ.c + +
                    +
                    +static DdQueueItem * 
                    +hashLookup(
                    +  DdLevelQueue * queue, 
                    +  void * key 
                    +)
                    +
                    +
                    Looks up a key in the hash table of a level queue. Returns + a pointer to the item with the given key if the key is found; NULL + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddLevelQueueEnqueue +hashInsert + + +
                    Defined in cuddLevelQ.c + +
                    +
                    +static int 
                    +hashResize(
                    +  DdLevelQueue * queue 
                    +)
                    +
                    +
                    Resizes the hash table of a level queue. Returns 1 if + successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also hashInsert + + +
                    Defined in cuddLevelQ.c + +
                    +
                    +static int 
                    +impliedp(
                    +  DdHalfWord  var1, 
                    +  short  phase1, 
                    +  DdHalfWord  var2, 
                    +  short  phase2, 
                    +  BitVector * olv, 
                    +  BitVector * olp 
                    +)
                    +
                    +
                    Returns true iff either literal of a clause is in a set + of literals. The first four arguments specify the clause. The + remaining two arguments specify the literal set. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddEssent.c + +
                    +
                    +static int 
                    +indexCompare(
                    +  const void * a, 
                    +  const void * b 
                    +)
                    +
                    +
                    Compares indices for qsort. Subtracting these integers + cannot produce overflow, because they are non-negative. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddUtil.c + +
                    +
                    +static DdHalfWord * 
                    +initSymmInfo(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Translates the symmetry information stored in the next + field of each subtable from level to indices. This procedure is called + immediately after symmetric sifting, so that the next fields are correct. + By translating this informaton in terms of indices, we make it independent + of subsequent reorderings. The format used is that of the next fields: + a circular list where each variable points to the next variable in the + same symmetry group. Only the entries between lower and upper are + considered. The procedure returns a pointer to an array + holding the symmetry information if successful; NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also checkSymmInfo + + +
                    Defined in cuddExact.c + +
                    +
                    + 
                    +int **þcubeþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int **þcubeþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int **þindicesþarray containing (on return) the indices(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int **þindicesþarray containing (on return) the indices(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int **þpathþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int **þpathþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int *þarrayþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int *þarrayþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int *þdigitsþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int *þdistanceþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int *þinputsþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int *þlengthþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int *þlengthþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int *þpermutationþrequired variable permutation(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int *þpermutationþrequired variable permutation(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int *þpermutþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int *þpermutþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int *þphase2þ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int *þweightþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þNþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þamountþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þarcviolationþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þbinaryDigitsþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þbitþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þbitþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þcycleþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þdigitsþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þdirectionþunder (0) or over (1) approximation(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þdirectionþunder (0) or over (1) approximation(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þhardlimitþflag: 1 if threshold is a hard limit(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þhardlimitþflag: 1 if threshold is a hard limit(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþvariable index(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþvariable index(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþvariable index(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþvariable index(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþvariable index(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþvariable index(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þindexþvariable index(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þiþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þiþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þiþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þiþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þiþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þiþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þiþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þiþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þiþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þiþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þiþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þiþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þkþnumber of minterms to find(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þlevelþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þlevelþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þminsizeþbound below which no reordering occurs(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þminsizeþbound below which no reordering occurs(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þmultiplicityþhow many ZDD variables are created for each BDD variable(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þmvarsþsize of maskVars(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þmvþ0: blif, 1: blif-MV(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þmvþ0: blif, 1: blif-MV(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnVarsþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnumberXoversþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnvarsþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnvarsþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnvarsþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnvarsþsize of the support of f(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnzþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnzþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnzþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþlength of both arrays(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþnumbers of unknowns(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþnumbers of unknowns(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþsize of vars(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþsize of the array(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþsize of the array(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þnþsize of the array(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þpairIndexþcorresponding variable index(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þpathþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þphaseþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þphaseþ1: positive; 0: negative(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þpopulationSizeþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þpowerþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þprecisionþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þprecisionþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þprþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þprþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þprþverbosity level(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þprþverbosity level(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þrecombþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þsmsþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þsmvþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þsymmviolationþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þsyþstep of column variables(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þsyþstep of column variables(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þthresholdþmaximum number of nodes in the subset(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þthresholdþmaximum number of nodes in the subset(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þthresholdþmaximum number of nodes in the superset(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þthresholdþmaximum number of nodes in the superset(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þtopþindex of top variable(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þupperBoundþdistance above which an approximate answer is OK(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þupperþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þupperþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þvarþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þvarþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þvarþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þvþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þvþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þxþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +int þyþcolumn index(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    +static int 
                    +largest(
                    +    
                    +)
                    +
                    +
                    Finds the largest DD in the population. If an order is + repeated, it avoids choosing the copy that is in the computed table + (it has repeat[i +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGenetic.c + +
                    +
                    + 
                    +long þseedþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +long þsizeþsize of the allocation that failed(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    +static int 
                    +make_random(
                    +  DdManager * table, 
                    +  int  lower 
                    +)
                    +
                    +
                    Generates the random sequences for the initial population. + The sequences are permutations of the indices between lower and + upper in the current order. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGenetic.c + +
                    +
                    +static DdNode * 
                    +mintermsFromUniverse(
                    +  DdManager * manager, 
                    +  DdNode ** vars, 
                    +  int  numVars, 
                    +  double  n, 
                    +  int  index 
                    +)
                    +
                    +
                    Recursive procedure to extract n mintems from constant 1. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSplit.c + +
                    +
                    +static int 
                    +oneliteralp(
                    +  DdHalfWord  var 
                    +)
                    +
                    +
                    Returns true iff the argument is a one-literal clause. + A one-litaral clause has the constant FALSE as second literal. + Since the constant TRUE is never used, it is sufficient to test for + a constant. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddEssent.c + +
                    +
                    +static void 
                    +pushDown(
                    +  DdHalfWord * order, 
                    +  int  j, 
                    +  int  level 
                    +)
                    +
                    +
                    Pushes a variable in the order down to position "level." +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddExact.c + +
                    +
                    +static int 
                    +rand_int(
                    +  int  a 
                    +)
                    +
                    +
                    Generates a random number between 0 and the integer a. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGenetic.c + +
                    +
                    +static double 
                    +random_generator(
                    +    
                    +)
                    +
                    +
                    Returns a double precision value between 0.0 and 1.0. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAnneal.c + +
                    +
                    +static int 
                    +restoreOrder(
                    +  DdManager * table, 
                    +  int * array, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Restores the variable order in array by a series of sifts up. + Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAnneal.c + +
                    +
                    +static int 
                    +roulette(
                    +  int * p1, 
                    +  int * p2 
                    +)
                    +
                    +
                    Selects two distinct parents with the roulette wheel method. +

                    + +

                    Side Effects The indices of the selected parents are returned as side + effects. +

                    + +

                    Defined in cuddGenetic.c + +
                    +
                    +static DdNode * 
                    +selectMintermsFromUniverse(
                    +  DdManager * manager, 
                    +  int * varSeen, 
                    +  double  n 
                    +)
                    +
                    +
                    This function prepares an array of variables which have not been + encountered so far when traversing the procedure cuddSplitSetRecur. This + array is then used to extract the required number of minterms from a constant + 1. The algorithm guarantees that the size of BDD will be utmost log(n). +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSplit.c + +
                    +
                    +static int 
                    +sentinelp(
                    +  DdHalfWord  var1, 
                    +  DdHalfWord  var2 
                    +)
                    +
                    +
                    Returns true iff the argument is the sentinel clause. + A sentinel clause has both variables equal to 0. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddEssent.c + +
                    +
                    +static DdNode * 
                    +separateCube(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  CUDD_VALUE_TYPE * distance 
                    +)
                    +
                    +
                    Separates cube from distance. Returns the cube if + successful; NULL otherwise. +

                    + +

                    Side Effects The distance is returned as a side effect. +

                    + +

                    See Also cuddBddClosestCube +createResult + + +
                    Defined in cuddPriority.c + +
                    +
                    +static int 
                    +siftBackwardProb(
                    +  DdManager * table, 
                    +  Move * moves, 
                    +  int  size, 
                    +  double  temp 
                    +)
                    +
                    +
                    Otherwise, "tosses a coin" to decide whether to keep + the current configuration or return the DD to the original + one. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAnneal.c + +
                    +
                    +static int 
                    +sift_up(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  x_low 
                    +)
                    +
                    +
                    Takes a variable from position x and sifts it up to + position x_low; x_low should be less than x. Returns 1 if successful; + 0 otherwise +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGenetic.c + +
                    +
                    +static enum st_retval 
                    +stPathTableDdFree(
                    +  char * key, 
                    +  char * value, 
                    +  char * arg 
                    +)
                    +
                    +
                    None +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddSubsetSP.c + +
                    +
                    +static enum st_retval 
                    +st_zdd_count_dbl_free(
                    +  char * key, 
                    +  char * value, 
                    +  char * arg 
                    +)
                    +
                    +
                    Frees the memory associated with the computed table of + Cudd_zddCountDouble. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddCount.c + +
                    +
                    +static enum st_retval 
                    +st_zdd_countfree(
                    +  char * key, 
                    +  char * value, 
                    +  char * arg 
                    +)
                    +
                    +
                    Frees the memory associated with the computed table of + Cudd_zddCount. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddCount.c + +
                    +
                    +static int 
                    +stopping_criterion(
                    +  int  c1, 
                    +  int  c2, 
                    +  int  c3, 
                    +  int  c4, 
                    +  double  temp 
                    +)
                    +
                    +
                    If temperature is STOP_TEMP or there is no improvement + then terminates. Returns 1 if the termination criterion is met; 0 + otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddAnneal.c + +
                    +
                    +static DdTlcInfo * 
                    +tlcInfoAlloc(
                    +    
                    +)
                    +
                    +
                    Returns a pointer to a DdTlcInfo Structure if successful; + NULL otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also Cudd_tlcInfoFree + + +
                    Defined in cuddEssent.c + +
                    +
                    + 
                    +unsigned int þfactorþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þhrþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þlimitþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þlimitþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þlimitþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þlimitþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þlimitþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þlimitþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þlutþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þmaxLiveþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þmcþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þmrþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þnextþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þpþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þsecondDenþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þtypeþMTR_DEFAULT or MTR_FIXED(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þtypeþMTR_DEFAULT or MTR_FIXED(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned int þupperBþupper bound(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned long þincreaseþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned long þmaxMemoryþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned long þmaxMemoryþtarget maximum memory occupation(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned long þstþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +unsigned long þtlþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    +static int 
                    +updateEntry(
                    +  DdManager * table, 
                    +  DdHalfWord * order, 
                    +  int  level, 
                    +  int  cost, 
                    +  DdHalfWord ** orders, 
                    +  int * costs, 
                    +  int  subsets, 
                    +  char * mask, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Updates entry for a subset. Finds the subset, if it exists. + If the new order for the subset has lower cost, or if the subset did not + exist, it stores the new order and cost. Returns the number of subsets + currently in the table. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddExact.c + +
                    +
                    +static void 
                    +updateParity(
                    +  DdNode * node, function to analyze
                    +  ApproxInfo * info, info on BDD
                    +  int  newparity new parity for node
                    +)
                    +
                    +
                    Recursively update the parity of the paths reaching a node. + Assumes that node is regular and propagates the invariant. +

                    + +

                    Side Effects None +

                    + +

                    See Also gatherInfoAux + + +
                    Defined in cuddApprox.c + +
                    +
                    +static int 
                    +updateRefs(
                    +  DdManager * dd, 
                    +  DdNode * f, 
                    +  DdNode * skip, 
                    +  ApproxInfo * info, 
                    +  DdLevelQueue * queue 
                    +)
                    +
                    +
                    Update function reference counts to account for replacement. + Returns the number of nodes saved if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    See Also UAmarkNodes +RAmarkNodes +BAmarkNodes + + +
                    Defined in cuddApprox.c + +
                    +
                    +static int 
                    +updateUB(
                    +  DdManager * table, 
                    +  int  oldBound, 
                    +  DdHalfWord * bestOrder, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Updates the upper bound and saves the best order seen so far. + Returns the current value of the upper bound. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddExact.c + +
                    +
                    + 
                    +void *þdataþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +void *þdataþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +void *þdataþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    +static void 
                    +zddClearFlag(
                    +  DdNode * f 
                    +)
                    +
                    +
                    Performs a DFS from f, clearing the LSB of the next + pointers. +

                    + +

                    Side Effects None +

                    + +

                    See Also zddSupportStep + + +
                    Defined in cuddZddUtil.c + +
                    +
                    +static int 
                    +zddCountInternalMtrNodes(
                    +  DdManager * table, 
                    +  MtrNode * treenode 
                    +)
                    +
                    +
                    Counts the number of internal nodes of the group tree. + Returns the count. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +static void 
                    +zddFindNodeHiLo(
                    +  DdManager * table, 
                    +  MtrNode * treenode, 
                    +  int * lower, 
                    +  int * upper 
                    +)
                    +
                    +
                    Finds the lower and upper bounds of the group represented + by treenode. The high and low fields of treenode are indices. From + those we need to derive the current positions, and find maximum and + minimum. +

                    + +

                    Side Effects The bounds are returned as side effects. +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +static void 
                    +zddFixTree(
                    +  DdManager * table, 
                    +  MtrNode * treenode 
                    +)
                    +
                    +
                    Fixes the ZDD variable group tree after a + shuffle. Assumes that the order of the variables in a terminal node + has not been changed. +

                    + +

                    Side Effects Changes the ZDD variable group tree. +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +static int 
                    +zddGroupMoveBackward(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Undoes the swap two groups. Returns 1 in case of + success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +static int 
                    +zddGroupMove(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y, 
                    +  Move ** moves 
                    +)
                    +
                    +
                    Swaps two groups and records the move. Returns the + number of keys in the DD table in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +static int 
                    +zddGroupSiftingAux(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xLow, 
                    +  int  xHigh 
                    +)
                    +
                    +
                    Sifts one variable up and down until it has taken all + positions. Checks for aggregation. There may be at most two sweeps, + even if the group grows. Assumes that x is either an isolated + variable, or it is the bottom of a group. All groups may not have + been found. The variable being moved is returned to the best position + seen during sifting. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +static int 
                    +zddGroupSiftingBackward(
                    +  DdManager * table, 
                    +  Move * moves, 
                    +  int  size 
                    +)
                    +
                    +
                    Determines the best position for a variables and returns + it there. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +static int 
                    +zddGroupSiftingDown(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xHigh, 
                    +  Move ** moves 
                    +)
                    +
                    +
                    Sifts down a variable until it reaches position xHigh. + Assumes that x is the bottom of a group (or a singleton). Records + all the moves. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +static int 
                    +zddGroupSiftingUp(
                    +  DdManager * table, 
                    +  int  y, 
                    +  int  xLow, 
                    +  Move ** moves 
                    +)
                    +
                    +
                    Sifts up a variable until either it reaches position + xLow or the size of the DD heap increases too much. Assumes that y is + the top of a group (or a singleton). Checks y for aggregation to the + adjacent variables. Records all the moves that are appended to the + list of moves received as input and returned as a side effect. + Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +static int 
                    +zddGroupSifting(
                    +  DdManager * table, 
                    +  int  lower, 
                    +  int  upper 
                    +)
                    +
                    +
                    Sifts from treenode->low to treenode->high. If + croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the + end of the initial sifting. If a group is created, it is then sifted + again. After sifting one variable, the group that contains it is + dissolved. Returns 1 in case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +static void 
                    +zddMergeGroups(
                    +  DdManager * table, 
                    +  MtrNode * treenode, 
                    +  int  low, 
                    +  int  high 
                    +)
                    +
                    +
                    Creates a single group from low to high and adjusts the + idex field of the tree node. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +static DdNode * 
                    +zddPortFromBddStep(
                    +  DdManager * dd, 
                    +  DdNode * B, 
                    +  int  expected 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddPortFromBdd. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddPort.c + +
                    +
                    +static DdNode * 
                    +zddPortToBddStep(
                    +  DdManager * dd, manager
                    +  DdNode * f, ZDD to be converted
                    +  int  depth recursion depth
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddPortToBdd. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddPort.c + +
                    +
                    +static void 
                    +zddPrintCoverAux(
                    +  DdManager * zdd, manager
                    +  DdNode * node, current node
                    +  int  level, depth in the recursion
                    +  int * list current recursion path
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddPrintCover. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddUtil.c + +
                    +
                    +static int 
                    +zddReorderChildren(
                    +  DdManager * table, 
                    +  MtrNode * treenode, 
                    +  Cudd_ReorderingType  method 
                    +)
                    +
                    +
                    Reorders the children of a group tree node according to + the options. After reordering puts all the variables in the group + and/or its descendents in a single group. This allows hierarchical + reordering. If the variables in the group do not exist yet, simply + does nothing. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +static int 
                    +zddReorderPostprocess(
                    +  DdManager * table 
                    +)
                    +
                    +
                    Shrinks almost empty subtables at the end of reordering to + guarantee that they have a reasonable load factor. However, if there many + nodes are being reclaimed, then no resizing occurs. Returns 1 in case of + success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +static void 
                    +zddReorderPreprocess(
                    +  DdManager * table 
                    +)
                    +
                    +
                    Prepares the ZDD heap for dynamic reordering. Does + garbage collection, to guarantee that there are no dead nodes; + and clears the cache, which is invalidated by dynamic reordering. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +static int 
                    +zddShuffle(
                    +  DdManager * table, 
                    +  int * permutation 
                    +)
                    +
                    +
                    Reorders ZDD variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. zddShuffle assumes that no + dead nodes are present. The reordering is achieved by a series of + upward sifts. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +static int 
                    +zddSiftUp(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  xLow 
                    +)
                    +
                    +
                    Takes a ZDD variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +static void 
                    +zddSupportStep(
                    +  DdNode * f, 
                    +  int * support 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddSupport. Performs a + DFS from f. The support is accumulated in supp as a side effect. Uses + the LSB of the then pointer as visited flag. +

                    + +

                    Side Effects None +

                    + +

                    See Also zddClearFlag + + +
                    Defined in cuddZddUtil.c + +
                    +
                    +static Move * 
                    +zddSwapAny(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Swaps any two variables. Returns the set of moves. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddReord.c + +
                    +
                    +static int 
                    +zddTreeSiftingAux(
                    +  DdManager * table, 
                    +  MtrNode * treenode, 
                    +  Cudd_ReorderingType  method 
                    +)
                    +
                    +
                    Recursively visits the group tree and reorders each + group in postorder fashion. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +static int 
                    +zddUniqueCompareGroup(
                    +  int * ptrX, 
                    +  int * ptrY 
                    +)
                    +
                    +
                    Comparison function used by qsort to order the variables + according to the number of keys in the subtables. Returns the + difference in number of keys between the two variables being + compared. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddGroup.c + +
                    +
                    +static void 
                    +zddVarToConst(
                    +  DdNode * f, 
                    +  DdNode ** gp, 
                    +  DdNode ** hp, 
                    +  DdNode * base, 
                    +  DdNode * empty 
                    +)
                    +
                    +
                    Replaces variables with constants if possible (part of + canonical form). +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSetop.c + +
                    +
                    +static int 
                    +zdd_group_move_backward(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y 
                    +)
                    +
                    +
                    Undoes the swap of two groups. x is assumed to be the + bottom variable of the first group. y is assumed to be the top + variable of the second group. Returns 1 if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSymm.c + +
                    +
                    +static int 
                    +zdd_group_move(
                    +  DdManager * table, 
                    +  int  x, 
                    +  int  y, 
                    +  Move ** moves 
                    +)
                    +
                    +
                    Swaps two groups. x is assumed to be the bottom variable + of the first group. y is assumed to be the top variable of the second + group. Updates the list of moves. Returns the number of keys in the + table if successful; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSymm.c + +
                    +
                    +static void 
                    +zdd_print_minterm_aux(
                    +  DdManager * zdd, manager
                    +  DdNode * node, current node
                    +  int  level, depth in the recursion
                    +  int * list current recursion path
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddPrintMinterm. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddUtil.c + +
                    +
                    +static DdNode * 
                    +zdd_subset0_aux(
                    +  DdManager * zdd, 
                    +  DdNode * P, 
                    +  DdNode * zvar 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddSubset0. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSetop.c + +
                    +
                    +static DdNode * 
                    +zdd_subset1_aux(
                    +  DdManager * zdd, 
                    +  DdNode * P, 
                    +  DdNode * zvar 
                    +)
                    +
                    +
                    Performs the recursive step of Cudd_zddSubset1. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddSetop.c + +
                    +
                    +static int 
                    +zp2(
                    +  DdManager * zdd, 
                    +  DdNode * f, 
                    +  st_table * t 
                    +)
                    +
                    +
                    Performs the recursive step of cuddZddP. Returns 1 in + case of success; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddZddUtil.c + +
                    +
                    + 
                    +þþ(
                    +    
                    +)
                    +
                    +
                    +

                    + +

                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddAllocNode +cuddDynamicAllocNode +cuddDeallocMove + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddDeallocNode +cuddDynamicAllocNode + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Adjusts the values of table fields controlling the. + sizes of subtables and computed table. If the computed table is too small + according to the new values, it is resized. +

                    + +

                    Side Effects Modifies manager fields. May resize computed table. +

                    + +

                    Defined in cuddTable.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Clears a bit vector. The parameter size gives the + number of bits. +

                    + +

                    Side Effects None +

                    + +

                    See Also bitVectorAlloc + + +
                    Defined in cuddEssent.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Clears the 4 least significant bits of a pointer. +

                    + +

                    Side Effects none +

                    + +

                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Comparison of a function to the i-th ADD variable. Returns 1 if + the function is the i-th ADD variable; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCompose.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Comparison of a pair of functions to the i-th ADD + variable. Returns 1 if the functions are the i-th ADD variable and its + complement; 0 otherwise. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddCompose.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Complements a DD if condition c is true; c should be + either 0 or 1, because it is used directly (for efficiency). If in + doubt on the values c may take, use "(c) ? Cudd_Not(node) : node". +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_Not + + +
                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Complements a DD by flipping the complement attribute of + the pointer (the least significant bit). +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_NotCond + + +
                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Computes hash function for keys of one operand. +

                    + +

                    Side Effects None +

                    + +

                    See Also ddLCHash3 +ddLCHash + + +
                    Defined in cuddLCache.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Computes hash function for keys of three operands. +

                    + +

                    Side Effects None +

                    + +

                    See Also ddLCHash2 +ddLCHash + + +
                    Defined in cuddLCache.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Computes hash function for keys of two operands. +

                    + +

                    Side Effects None +

                    + +

                    See Also ddLCHash3 +ddLCHash + + +
                    Defined in cuddLCache.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Computes the absolute value of a number. +

                    + +

                    Side Effects none +

                    + +

                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Computes the hash value for a local cache. Returns the + bucket index. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddLCache.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Computes the maximum of two numbers. +

                    + +

                    Side Effects none +

                    + +

                    See Also ddMin + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Computes the minimum of two numbers. +

                    + +

                    Side Effects none +

                    + +

                    See Also ddMax + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Decreases the reference count of node. It is primarily + used in recursive procedures to decrease the ref count of a result + node before returning it. This accomplishes the goal of removing the + protection applied by a previous cuddRef. This being a macro, it is + faster than Cudd_Deref, but it cannot be used in constructs like + cuddDeref(a = b()). +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_Deref + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL. + Furthermore, if x <= DD_MINUS_INF_VAL/2, x is set to + DD_MINUS_INF_VAL. Similarly, if DD_PLUS_INF_VAL/2 <= x, x is set to + DD_PLUS_INF_VAL. Normally this macro is a NOOP. However, if + HAVE_IEEE_754 is not defined, it makes sure that a value does not + get larger than infinity in absolute value, and once it gets to + infinity, stays there. If the value overflows before this macro is + applied, no recovery is possible. +

                    + +

                    Side Effects none +

                    + +

                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Extract the least significant digit of a double digit. Used + in the manipulation of arbitrary precision integers. +

                    + +

                    Side Effects None +

                    + +

                    See Also DD_MSDIGIT + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Extract the most significant digit of a double digit. Used + in the manipulation of arbitrary precision integers. +

                    + +

                    Side Effects None +

                    + +

                    See Also DD_LSDIGIT + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Fast storage allocation for items in a hash table. The + first 4 bytes of a chunk contain a pointer to the next block; the + rest contains DD_MEM_CHUNK spaces for hash items. Returns a pointer to + a new item if successful; NULL is memory is full. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddAllocNode +cuddDynamicAllocNode + + +
                    Defined in cuddLCache.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Finds the current position of ZDD variable index in the + order. This macro duplicates the functionality of Cudd_ReadPermZdd, + but it does not check for out-of-bounds indices and it is more + efficient. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_ReadPermZdd + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Finds the current position of variable index in the + order. This macro duplicates the functionality of Cudd_ReadPerm, + but it does not check for out-of-bounds indices and it is more + efficient. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_ReadPerm + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Hash function for the cache for functions with two + operands. +

                    + +

                    Side Effects none +

                    + +

                    See Also ddHash +ddCHash + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Hash function for the cache. +

                    + +

                    Side Effects none +

                    + +

                    See Also ddHash +ddCHash2 + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Hash function for the table of a level queue. +

                    + +

                    Side Effects None +

                    + +

                    See Also hashInsert +hashLookup +hashDelete + + +
                    Defined in cuddLevelQ.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Hash function for the unique table. +

                    + +

                    Side Effects none +

                    + +

                    See Also ddCHash +ddCHash2 + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Increases the reference count of a node, if it is not + saturated. This being a macro, it is faster than Cudd_Ref, but it + cannot be used in constructs like cuddRef(a = b()). +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_Ref + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Iterates over the cubes of a decision diagram f. +
                      +
                    • DdManager *manager; +
                    • DdNode *f; +
                    • DdGen *gen; +
                    • int *cube; +
                    • CUDD_VALUE_TYPE value; +
                    + Cudd_ForeachCube allocates and frees the generator. Therefore the + application should not try to do that. Also, the cube is freed at the + end of Cudd_ForeachCube and hence is not available outside of the loop.

                    + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_ForeachNode +Cudd_FirstCube +Cudd_NextCube +Cudd_GenFree +Cudd_IsGenEmpty +Cudd_AutodynDisable + + +
                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Iterates over the nodes of a decision diagram f. +
                      +
                    • DdManager *manager; +
                    • DdNode *f; +
                    • DdGen *gen; +
                    • DdNode *node; +
                    + The nodes are returned in a seemingly random order. + Cudd_ForeachNode allocates and frees the generator. Therefore the + application should not try to do that.

                    + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_ForeachCube +Cudd_FirstNode +Cudd_NextNode +Cudd_GenFree +Cudd_IsGenEmpty +Cudd_AutodynDisable + + +
                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Iterates over the paths of a ZDD f. +
                      +
                    • DdManager *manager; +
                    • DdNode *f; +
                    • DdGen *gen; +
                    • int *path; +
                    + Cudd_zddForeachPath allocates and frees the generator. Therefore the + application should not try to do that. Also, the path is freed at the + end of Cudd_zddForeachPath and hence is not available outside of the loop.

                    + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_zddFirstPath +Cudd_zddNextPath +Cudd_GenFree +Cudd_IsGenEmpty +Cudd_AutodynDisable + + +
                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Iterates over the primes of a Boolean function producing + a prime and irredundant cover. +
                      +
                    • DdManager *manager; +
                    • DdNode *l; +
                    • DdNode *u; +
                    • DdGen *gen; +
                    • int *cube; +
                    + The Boolean function is described by an upper bound and a lower bound. If + the function is completely specified, the two bounds coincide. + Cudd_ForeachPrime allocates and frees the generator. Therefore the + application should not try to do that. Also, the cube is freed at the + end of Cudd_ForeachPrime and hence is not available outside of the loop.

                    + CAUTION: It is a mistake to change a diagram on which generation is ongoing. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_ForeachCube +Cudd_FirstPrime +Cudd_NextPrime +Cudd_GenFree +Cudd_IsGenEmpty + + +
                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Outputs a line of stats if DD_COUNT and DD_STATS are + defined. Increments the number of recursive calls if DD_COUNT is + defined. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Performs the left rotation for red/black trees. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddRotateRight + + +
                    Defined in cuddTable.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Performs the right rotation for red/black trees. +

                    + +

                    Side Effects None +

                    + +

                    See Also cuddRotateLeft + + +
                    Defined in cuddTable.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns 1 if a pointer is complemented. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_Regular +Cudd_Complement + + +
                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns 1 if the absolute value of the difference of the two + arguments x and y is less than e. +

                    + +

                    Side Effects none +

                    + +

                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns 1 if the node is a constant node (rather than an + internal node). All constant nodes have the same index + (CUDD_CONST_INDEX). The pointer passed to Cudd_IsConstant may be either + regular or complemented. +

                    + +

                    Side Effects none +

                    + +

                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns 1 if the node is a constant node (rather than an + internal node). All constant nodes have the same index + (CUDD_CONST_INDEX). The pointer passed to cuddIsConstant must be regular. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_IsConstant + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the arithmetic 0 constant node. This is different + from the logical zero. The latter is obtained by + Cudd_Not(DD_ONE(dd)). +

                    + +

                    Side Effects none +

                    + +

                    See Also DD_ONE +Cudd_Not +DD_PLUS_INFINITY +DD_MINUS_INFINITY + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the average fitness of the population. +

                    + +

                    Side Effects None +

                    + +

                    Defined in cuddGenetic.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the complemented version of a pointer. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_Regular +Cudd_IsComplement + + +
                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the constant 1 node. +

                    + +

                    Side Effects none +

                    + +

                    See Also DD_ZERO +DD_PLUS_INFINITY +DD_MINUS_INFINITY + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the current position in the order of variable + index. This macro is obsolete and is kept for compatibility. New + applications should use Cudd_ReadPerm instead. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_ReadPerm + + +
                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the else child of an internal node. If + node is a constant node, the result is unpredictable. + The pointer passed to cuddE must be regular. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_E + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the else child of an internal node. If + node is a constant node, the result is unpredictable. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_T +Cudd_V + + +
                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the i-th entry of a bit vector. +

                    + +

                    Side Effects None +

                    + +

                    See Also bitVectorSet + + +
                    Defined in cuddEssent.c + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the minus infinity constant node. +

                    + +

                    Side Effects none +

                    + +

                    See Also DD_ONE +DD_ZERO +DD_PLUS_INFINITY + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the plus infinity constant node. +

                    + +

                    Side Effects none +

                    + +

                    See Also DD_ONE +DD_ZERO +DD_MINUS_INFINITY + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the regular version of a pointer. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_Complement +Cudd_IsComplement + + +
                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the then child of an internal node. If + node is a constant node, the result is unpredictable. + The pointer passed to cuddT must be regular. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_T + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the then child of an internal node. If + node is a constant node, the result is unpredictable. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_E +Cudd_V + + +
                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the value of a constant node. If + node is an internal node, the result is unpredictable. + The pointer passed to cuddV must be regular. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_V + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Returns the value of a constant node. If + node is an internal node, the result is unpredictable. +

                    + +

                    Side Effects none +

                    + +

                    See Also Cudd_T +Cudd_E + + +
                    Defined in cudd.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Saturating decrement operator. +

                    + +

                    Side Effects none +

                    + +

                    See Also cuddSatInc + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Saturating increment operator. +

                    + +

                    Side Effects none +

                    + +

                    See Also cuddSatDec + + +
                    Defined in cuddInt.h + +
                    +
                    + 
                    +(
                    +    
                    +)
                    +
                    +
                    Sets the i-th entry of a bit vector to a value. +

                    + +

                    Side Effects None +

                    + +

                    See Also bitVectorRead + + +
                    Defined in cuddEssent.c + + +
                +
                +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllFile.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllFile.html new file mode 100644 index 000000000..9293943d3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddAllFile.html @@ -0,0 +1,4876 @@ + +The cudd package: files + + +
                +
                cuddAddAbs.c +
                Quantification functions for ADDs. +
                cuddAddApply.c +
                Apply functions for ADDs and their operators. +
                cuddAddFind.c +
                Functions to find maximum and minimum in an ADD and to + extract the i-th bit. +
                cuddAddInv.c +
                Function to compute the scalar inverse of an ADD. +
                cuddAddIte.c +
                ADD ITE function and satellites. +
                cuddAddNeg.c +
                Function to compute the negation of an ADD. +
                cuddAddWalsh.c +
                Functions that generate Walsh matrices and residue + functions in ADD form. +
                cuddAndAbs.c +
                Combined AND and existential abstraction for BDDs +
                cuddAnneal.c +
                Reordering of DDs based on simulated annealing +
                cuddApa.c +
                Arbitrary precision arithmetic functions. +
                cuddAPI.c +
                Application interface functions. +
                cuddApprox.c +
                Procedures to approximate a given BDD. +
                cuddBddAbs.c +
                Quantification functions for BDDs. +
                cuddBddCorr.c +
                Correlation between BDDs. +
                cuddBddIte.c +
                BDD ITE function and satellites. +
                cuddBridge.c +
                Translation from BDD to ADD and vice versa and transfer between + different managers. +
                cuddCache.c +
                Functions for cache insertion and lookup. +
                cuddCheck.c +
                Functions to check consistency of data structures. +
                cuddClip.c +
                Clipping functions. +
                cuddCof.c +
                Cofactoring functions. +
                cuddCompose.c +
                Functional composition and variable permutation of DDs. +
                cuddDecomp.c +
                Functions for BDD decomposition. +
                cuddEssent.c +
                Functions for the detection of essential variables. +
                cuddExact.c +
                Functions for exact variable reordering. +
                cuddExport.c +
                Export functions. +
                cuddGenCof.c +
                Generalized cofactors for BDDs and ADDs. +
                cuddGenetic.c +
                Genetic algorithm for variable reordering. +
                cuddGroup.c +
                Functions for group sifting. +
                cuddHarwell.c +
                Function to read a matrix in Harwell format. +
                cuddInit.c +
                Functions to initialize and shut down the DD manager. +
                cuddInteract.c +
                Functions to manipulate the variable interaction matrix. +
                cuddLCache.c +
                Functions for local caches. +
                cuddLevelQ.c +
                Procedure to manage level queues. +
                cuddLinear.c +
                Functions for DD reduction by linear transformations. +
                cuddLiteral.c +
                Functions for manipulation of literal sets represented by + BDDs. +
                cuddMatMult.c +
                Matrix multiplication functions. +
                cuddPriority.c +
                Priority functions. +
                cuddRead.c +
                Functions to read in a matrix +
                cuddRef.c +
                Functions that manipulate the reference counts. +
                cuddReorder.c +
                Functions for dynamic variable reordering. +
                cuddSat.c +
                Functions for the solution of satisfiability related problems. +
                cuddSign.c +
                Computation of signatures. +
                cuddSolve.c +
                Boolean equation solver and related functions. +
                cuddSplit.c +
                Returns a subset of minterms from a boolean function. +
                cuddSubsetHB.c +
                Procedure to subset the given BDD by choosing the heavier + branches. +
                cuddSubsetSP.c +
                Procedure to subset the given BDD choosing the shortest paths + (largest cubes) in the BDD. +
                cuddSymmetry.c +
                Functions for symmetry-based variable reordering. +
                cuddTable.c +
                Unique table management functions. +
                cuddUtil.c +
                Utility functions. +
                cuddWindow.c +
                Functions for variable reordering by window permutation. +
                cuddZddCount.c +
                Procedures to count the number of minterms of a ZDD. +
                cuddZddFuncs.c +
                Functions to manipulate covers represented as ZDDs. +
                cuddZddGroup.c +
                Functions for ZDD group sifting. +
                cuddZddIsop.c +
                Functions to find irredundant SOP covers as ZDDs from BDDs. +
                cuddZddLin.c +
                Procedures for dynamic variable ordering of ZDDs. +
                cuddZddMisc.c +
                Miscellaneous utility functions for ZDDs. +
                cuddZddPort.c +
                Functions that translate BDDs to ZDDs. +
                cuddZddReord.c +
                Procedures for dynamic variable ordering of ZDDs. +
                cuddZddSetop.c +
                Set operations on ZDDs. +
                cuddZddSymm.c +
                Functions for symmetry-based ZDD variable reordering. +
                cuddZddUtil.c +
                Utility functions for ZDDs. +

                +

                cuddAddAbs.c

                +Quantification functions for ADDs.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_addExistAbstract() +
                • Cudd_addUnivAbstract() +
                • Cudd_addOrAbstract() +
                + Internal procedures included in this module: +
                  +
                • cuddAddExistAbstractRecur() +
                • cuddAddUnivAbstractRecur() +
                • cuddAddOrAbstractRecur() +
                + Static procedures included in this module: +
                  +
                • addCheckPositiveCube() +

                +

                +
                Cudd_addExistAbstract() +
                Existentially Abstracts all the variables in cube from f. + +
                Cudd_addUnivAbstract() +
                Universally Abstracts all the variables in cube from f. + +
                Cudd_addOrAbstract() +
                Disjunctively abstracts all the variables in cube from the + 0-1 ADD f. + +
                cuddAddExistAbstractRecur() +
                Performs the recursive step of Cudd_addExistAbstract. + +
                cuddAddUnivAbstractRecur() +
                Performs the recursive step of Cudd_addUnivAbstract. + +
                cuddAddOrAbstractRecur() +
                Performs the recursive step of Cudd_addOrAbstract. + +
                addCheckPositiveCube() +
                Checks whether cube is an ADD representing the product + of positive literals. + +
                +
                +

                cuddAddApply.c

                +Apply functions for ADDs and their operators.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_addApply() +
                • Cudd_addMonadicApply() +
                • Cudd_addPlus() +
                • Cudd_addTimes() +
                • Cudd_addThreshold() +
                • Cudd_addSetNZ() +
                • Cudd_addDivide() +
                • Cudd_addMinus() +
                • Cudd_addMinimum() +
                • Cudd_addMaximum() +
                • Cudd_addOneZeroMaximum() +
                • Cudd_addDiff() +
                • Cudd_addAgreement() +
                • Cudd_addOr() +
                • Cudd_addNand() +
                • Cudd_addNor() +
                • Cudd_addXor() +
                • Cudd_addXnor() +
                + Internal procedures included in this module: +
                  +
                • cuddAddApplyRecur() +
                • cuddAddMonadicApplyRecur() +

                +

                +
                Cudd_addApply() +
                Applies op to the corresponding discriminants of f and g. + +
                Cudd_addPlus() +
                Integer and floating point addition. + +
                Cudd_addTimes() +
                Integer and floating point multiplication. + +
                Cudd_addThreshold() +
                f if f>=g; 0 if f<g. + +
                Cudd_addSetNZ() +
                This operator sets f to the value of g wherever g != 0. + +
                Cudd_addDivide() +
                Integer and floating point division. + +
                Cudd_addMinus() +
                Integer and floating point subtraction. + +
                Cudd_addMinimum() +
                Integer and floating point min. + +
                Cudd_addMaximum() +
                Integer and floating point max. + +
                Cudd_addOneZeroMaximum() +
                Returns 1 if f > g and 0 otherwise. + +
                Cudd_addDiff() +
                Returns plusinfinity if f=g; returns min(f,g) if f!=g. + +
                Cudd_addAgreement() +
                f if f==g; background if f!=g. + +
                Cudd_addOr() +
                Disjunction of two 0-1 ADDs. + +
                Cudd_addNand() +
                NAND of two 0-1 ADDs. + +
                Cudd_addNor() +
                NOR of two 0-1 ADDs. + +
                Cudd_addXor() +
                XOR of two 0-1 ADDs. + +
                Cudd_addXnor() +
                XNOR of two 0-1 ADDs. + +
                Cudd_addMonadicApply() +
                Applies op to the discriminants of f. + +
                Cudd_addLog() +
                Natural logarithm of an ADD. + +
                cuddAddApplyRecur() +
                Performs the recursive step of Cudd_addApply. + +
                cuddAddMonadicApplyRecur() +
                Performs the recursive step of Cudd_addMonadicApply. + +
                +
                +

                cuddAddFind.c

                +Functions to find maximum and minimum in an ADD and to + extract the i-th bit.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_addFindMax() +
                • Cudd_addFindMin() +
                • Cudd_addIthBit() +
                + Static functions included in this module: +
                  +
                • addDoIthBit() +

                +

                +
                Cudd_addFindMax() +
                Finds the maximum discriminant of f. + +
                Cudd_addFindMin() +
                Finds the minimum discriminant of f. + +
                Cudd_addIthBit() +
                Extracts the i-th bit from an ADD. + +
                addDoIthBit() +
                Performs the recursive step for Cudd_addIthBit. + +
                +
                +

                cuddAddInv.c

                +Function to compute the scalar inverse of an ADD.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_addScalarInverse() +
                + Internal procedures included in this module: +
                  +
                • cuddAddScalarInverseRecur() +

                +

                +
                Cudd_addScalarInverse() +
                Computes the scalar inverse of an ADD. + +
                cuddAddScalarInverseRecur() +
                Performs the recursive step of addScalarInverse. + +
                +
                +

                cuddAddIte.c

                +ADD ITE function and satellites.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_addIte() +
                • Cudd_addIteConstant() +
                • Cudd_addEvalConst() +
                • Cudd_addCmpl() +
                • Cudd_addLeq() +
                + Internal procedures included in this module: +
                  +
                • cuddAddIteRecur() +
                • cuddAddCmplRecur() +
                + Static procedures included in this module: +
                  +
                • addVarToConst() +

                +

                +
                Cudd_addIte() +
                Implements ITE(f,g,h). + +
                Cudd_addIteConstant() +
                Implements ITEconstant for ADDs. + +
                Cudd_addEvalConst() +
                Checks whether ADD g is constant whenever ADD f is 1. + +
                Cudd_addCmpl() +
                Computes the complement of an ADD a la C language. + +
                Cudd_addLeq() +
                Determines whether f is less than or equal to g. + +
                cuddAddIteRecur() +
                Implements the recursive step of Cudd_addIte(f,g,h). + +
                cuddAddCmplRecur() +
                Performs the recursive step of Cudd_addCmpl. + +
                addVarToConst() +
                Replaces variables with constants if possible (part of + canonical form). + +
                +
                +

                cuddAddNeg.c

                +Function to compute the negation of an ADD.

                +By: Fabio Somenzi, Balakrishna Kumthekar

                +External procedures included in this module: +

                  +
                • Cudd_addNegate() +
                • Cudd_addRoundOff() +
                + Internal procedures included in this module: +
                  +
                • cuddAddNegateRecur() +
                • cuddAddRoundOffRecur() +

                +

                +
                Cudd_addNegate() +
                Computes the additive inverse of an ADD. + +
                Cudd_addRoundOff() +
                Rounds off the discriminants of an ADD. + +
                cuddAddNegateRecur() +
                Implements the recursive step of Cudd_addNegate. + +
                cuddAddRoundOffRecur() +
                Implements the recursive step of Cudd_addRoundOff. + +
                +
                +

                cuddAddWalsh.c

                +Functions that generate Walsh matrices and residue + functions in ADD form.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_addWalsh() +
                • Cudd_addResidue() +
                + Static procedures included in this module: +
                  +
                • addWalshInt() +

                +

                +
                Cudd_addWalsh() +
                Generates a Walsh matrix in ADD form. + +
                Cudd_addResidue() +
                Builds an ADD for the residue modulo m of an n-bit + number. + +
                addWalshInt() +
                Implements the recursive step of Cudd_addWalsh. + +
                +
                +

                cuddAndAbs.c

                +Combined AND and existential abstraction for BDDs

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_bddAndAbstract() +
                • Cudd_bddAndAbstractLimit() +
                + Internal procedures included in this module: +
                  +
                • cuddBddAndAbstractRecur() +

                +

                +
                Cudd_bddAndAbstract() +
                Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                Cudd_bddAndAbstractLimit() +
                Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. Returns NULL if too many nodes are required. + +
                cuddBddAndAbstractRecur() +
                Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                +
                +

                cuddAnneal.c

                +Reordering of DDs based on simulated annealing

                +By: Jae-Young Jang, Jorgen Sivesind

                +Internal procedures included in this file: +

                  +
                • cuddAnnealing() +
                + Static procedures included in this file: +
                  +
                • stopping_criterion() +
                • random_generator() +
                • ddExchange() +
                • ddJumpingAux() +
                • ddJumpingUp() +
                • ddJumpingDown() +
                • siftBackwardProb() +
                • copyOrder() +
                • restoreOrder() +

                +

                +
                cuddAnnealing() +
                Get new variable-order by simulated annealing algorithm. + +
                stopping_criterion() +
                Checks termination condition. + +
                random_generator() +
                Random number generator. + +
                ddExchange() +
                This function is for exchanging two variables, x and y. + +
                ddJumpingAux() +
                Moves a variable to a specified position. + +
                ddJumpingUp() +
                This function is for jumping up. + +
                ddJumpingDown() +
                This function is for jumping down. + +
                siftBackwardProb() +
                Returns the DD to the best position encountered during + sifting if there was improvement. + +
                copyOrder() +
                Copies the current variable order to array. + +
                restoreOrder() +
                Restores the variable order in array by a series of sifts up. + +
                +
                +

                cuddApa.c

                +Arbitrary precision arithmetic functions.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_ApaNumberOfDigits() +
                • Cudd_NewApaNumber() +
                • Cudd_ApaCopy() +
                • Cudd_ApaAdd() +
                • Cudd_ApaSubtract() +
                • Cudd_ApaShortDivision() +
                • Cudd_ApaIntDivision() +
                • Cudd_ApaShiftRight() +
                • Cudd_ApaSetToLiteral() +
                • Cudd_ApaPowerOfTwo() +
                • Cudd_ApaCompare() +
                • Cudd_ApaCompareRatios() +
                • Cudd_ApaPrintHex() +
                • Cudd_ApaPrintDecimal() +
                • Cudd_ApaPrintExponential() +
                • Cudd_ApaCountMinterm() +
                • Cudd_ApaPrintMinterm() +
                • Cudd_ApaPrintMintermExp() +
                • Cudd_ApaPrintDensity() +
                + Static procedures included in this module: +
                  +
                • cuddApaCountMintermAux() +
                • cuddApaStCountfree() +

                +

                +
                Cudd_ApaNumberOfDigits() +
                Finds the number of digits for an arbitrary precision + integer. + +
                Cudd_NewApaNumber() +
                Allocates memory for an arbitrary precision integer. + +
                Cudd_ApaCopy() +
                Makes a copy of an arbitrary precision integer. + +
                Cudd_ApaAdd() +
                Adds two arbitrary precision integers. + +
                Cudd_ApaSubtract() +
                Subtracts two arbitrary precision integers. + +
                Cudd_ApaShortDivision() +
                Divides an arbitrary precision integer by a digit. + +
                Cudd_ApaIntDivision() +
                Divides an arbitrary precision integer by an integer. + +
                Cudd_ApaShiftRight() +
                Shifts right an arbitrary precision integer by one binary + place. + +
                Cudd_ApaSetToLiteral() +
                Sets an arbitrary precision integer to a one-digit literal. + +
                Cudd_ApaPowerOfTwo() +
                Sets an arbitrary precision integer to a power of two. + +
                Cudd_ApaCompare() +
                Compares two arbitrary precision integers. + +
                Cudd_ApaCompareRatios() +
                Compares the ratios of two arbitrary precision integers to two + unsigned ints. + +
                Cudd_ApaPrintHex() +
                Prints an arbitrary precision integer in hexadecimal format. + +
                Cudd_ApaPrintDecimal() +
                Prints an arbitrary precision integer in decimal format. + +
                Cudd_ApaPrintExponential() +
                Prints an arbitrary precision integer in exponential format. + +
                Cudd_ApaCountMinterm() +
                Counts the number of minterms of a DD. + +
                Cudd_ApaPrintMinterm() +
                Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic. + +
                Cudd_ApaPrintMintermExp() +
                Prints the number of minterms of a BDD or ADD in exponential + format using arbitrary precision arithmetic. + +
                Cudd_ApaPrintDensity() +
                Prints the density of a BDD or ADD using + arbitrary precision arithmetic. + +
                cuddApaCountMintermAux() +
                Performs the recursive step of Cudd_ApaCountMinterm. + +
                cuddApaStCountfree() +
                Frees the memory used to store the minterm counts recorded + in the visited table. + +
                +
                +

                cuddAPI.c

                +Application interface functions.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_addNewVar() +
                • Cudd_addNewVarAtLevel() +
                • Cudd_bddNewVar() +
                • Cudd_bddNewVarAtLevel() +
                • Cudd_addIthVar() +
                • Cudd_bddIthVar() +
                • Cudd_zddIthVar() +
                • Cudd_zddVarsFromBddVars() +
                • Cudd_addConst() +
                • Cudd_IsNonConstant() +
                • Cudd_ReadStartTime() +
                • Cudd_ReadElapsedTime() +
                • Cudd_SetStartTime() +
                • Cudd_ResetStartTime() +
                • Cudd_ReadTimeLimit() +
                • Cudd_SetTimeLimit() +
                • Cudd_UpdateTimeLimit() +
                • Cudd_IncreaseTimeLimit() +
                • Cudd_UnsetTimeLimit() +
                • Cudd_TimeLimited() +
                • Cudd_AutodynEnable() +
                • Cudd_AutodynDisable() +
                • Cudd_ReorderingStatus() +
                • Cudd_AutodynEnableZdd() +
                • Cudd_AutodynDisableZdd() +
                • Cudd_ReorderingStatusZdd() +
                • Cudd_zddRealignmentEnabled() +
                • Cudd_zddRealignEnable() +
                • Cudd_zddRealignDisable() +
                • Cudd_bddRealignmentEnabled() +
                • Cudd_bddRealignEnable() +
                • Cudd_bddRealignDisable() +
                • Cudd_ReadOne() +
                • Cudd_ReadZddOne() +
                • Cudd_ReadZero() +
                • Cudd_ReadLogicZero() +
                • Cudd_ReadPlusInfinity() +
                • Cudd_ReadMinusInfinity() +
                • Cudd_ReadBackground() +
                • Cudd_SetBackground() +
                • Cudd_ReadCacheSlots() +
                • Cudd_ReadCacheUsedSlots() +
                • Cudd_ReadCacheLookUps() +
                • Cudd_ReadCacheHits() +
                • Cudd_ReadMinHit() +
                • Cudd_SetMinHit() +
                • Cudd_ReadLooseUpTo() +
                • Cudd_SetLooseUpTo() +
                • Cudd_ReadMaxCache() +
                • Cudd_ReadMaxCacheHard() +
                • Cudd_SetMaxCacheHard() +
                • Cudd_ReadSize() +
                • Cudd_ReadSlots() +
                • Cudd_ReadUsedSlots() +
                • Cudd_ExpectedUsedSlots() +
                • Cudd_ReadKeys() +
                • Cudd_ReadDead() +
                • Cudd_ReadMinDead() +
                • Cudd_ReadReorderings() +
                • Cudd_ReadMaxReorderings() +
                • Cudd_SetMaxReorderings() +
                • Cudd_ReadReorderingTime() +
                • Cudd_ReadGarbageCollections() +
                • Cudd_ReadGarbageCollectionTime() +
                • Cudd_ReadNodesFreed() +
                • Cudd_ReadNodesDropped() +
                • Cudd_ReadUniqueLookUps() +
                • Cudd_ReadUniqueLinks() +
                • Cudd_ReadSiftMaxVar() +
                • Cudd_SetSiftMaxVar() +
                • Cudd_ReadMaxGrowth() +
                • Cudd_SetMaxGrowth() +
                • Cudd_ReadMaxGrowthAlternate() +
                • Cudd_SetMaxGrowthAlternate() +
                • Cudd_ReadReorderingCycle() +
                • Cudd_SetReorderingCycle() +
                • Cudd_ReadTree() +
                • Cudd_SetTree() +
                • Cudd_FreeTree() +
                • Cudd_ReadZddTree() +
                • Cudd_SetZddTree() +
                • Cudd_FreeZddTree() +
                • Cudd_NodeReadIndex() +
                • Cudd_ReadPerm() +
                • Cudd_ReadInvPerm() +
                • Cudd_ReadVars() +
                • Cudd_ReadEpsilon() +
                • Cudd_SetEpsilon() +
                • Cudd_ReadGroupCheck() +
                • Cudd_SetGroupcheck() +
                • Cudd_GarbageCollectionEnabled() +
                • Cudd_EnableGarbageCollection() +
                • Cudd_DisableGarbageCollection() +
                • Cudd_DeadAreCounted() +
                • Cudd_TurnOnCountDead() +
                • Cudd_TurnOffCountDead() +
                • Cudd_ReadRecomb() +
                • Cudd_SetRecomb() +
                • Cudd_ReadSymmviolation() +
                • Cudd_SetSymmviolation() +
                • Cudd_ReadArcviolation() +
                • Cudd_SetArcviolation() +
                • Cudd_ReadPopulationSize() +
                • Cudd_SetPopulationSize() +
                • Cudd_ReadNumberXovers() +
                • Cudd_SetNumberXovers() +
                • Cudd_ReadOrderRandomization() +
                • Cudd_SetOrderRandomization() +
                • Cudd_ReadMemoryInUse() +
                • Cudd_PrintInfo() +
                • Cudd_ReadPeakNodeCount() +
                • Cudd_ReadPeakLiveNodeCount() +
                • Cudd_ReadNodeCount() +
                • Cudd_zddReadNodeCount() +
                • Cudd_AddHook() +
                • Cudd_RemoveHook() +
                • Cudd_IsInHook() +
                • Cudd_StdPreReordHook() +
                • Cudd_StdPostReordHook() +
                • Cudd_EnableReorderingReporting() +
                • Cudd_DisableReorderingReporting() +
                • Cudd_ReorderingReporting() +
                • Cudd_PrintGroupedOrder() +
                • Cudd_EnableOrderingMonitoring() +
                • Cudd_DisableOrderingMonitoring() +
                • Cudd_OrderingMonitoring() +
                • Cudd_ReadErrorCode() +
                • Cudd_ClearErrorCode() +
                • Cudd_ReadStdout() +
                • Cudd_SetStdout() +
                • Cudd_ReadStderr() +
                • Cudd_SetStderr() +
                • Cudd_ReadNextReordering() +
                • Cudd_SetNextReordering() +
                • Cudd_ReadSwapSteps() +
                • Cudd_ReadMaxLive() +
                • Cudd_SetMaxLive() +
                • Cudd_ReadMaxMemory() +
                • Cudd_SetMaxMemory() +
                • Cudd_bddBindVar() +
                • Cudd_bddUnbindVar() +
                • Cudd_bddVarIsBound() +
                • Cudd_bddSetPiVar() +
                • Cudd_bddSetPsVar() +
                • Cudd_bddSetNsVar() +
                • Cudd_bddIsPiVar() +
                • Cudd_bddIsPsVar() +
                • Cudd_bddIsNsVar() +
                • Cudd_bddSetPairIndex() +
                • Cudd_bddReadPairIndex() +
                • Cudd_bddSetVarToBeGrouped() +
                • Cudd_bddSetVarHardGroup() +
                • Cudd_bddResetVarToBeGrouped() +
                • Cudd_bddIsVarToBeGrouped() +
                • Cudd_bddSetVarToBeUngrouped() +
                • Cudd_bddIsVarToBeUngrouped() +
                • Cudd_bddIsVarHardGroup() +
                + Static procedures included in this module: +
                  +
                • fixVarTree() +

                +

                +
                Cudd_addNewVar() +
                Returns a new ADD variable. + +
                Cudd_addNewVarAtLevel() +
                Returns a new ADD variable at a specified level. + +
                Cudd_bddNewVar() +
                Returns a new BDD variable. + +
                Cudd_bddNewVarAtLevel() +
                Returns a new BDD variable at a specified level. + +
                Cudd_addIthVar() +
                Returns the ADD variable with index i. + +
                Cudd_bddIthVar() +
                Returns the BDD variable with index i. + +
                Cudd_zddIthVar() +
                Returns the ZDD variable with index i. + +
                Cudd_zddVarsFromBddVars() +
                Creates one or more ZDD variables for each BDD variable. + +
                Cudd_addConst() +
                Returns the ADD for constant c. + +
                Cudd_IsNonConstant() +
                Returns 1 if a DD node is not constant. + +
                Cudd_ReadStartTime() +
                Returns the start time of the manager. + +
                Cudd_ReadElapsedTime() +
                Returns the time elapsed since the start time of the manager. + +
                Cudd_SetStartTime() +
                Sets the start time of the manager. + +
                Cudd_ResetStartTime() +
                Resets the start time of the manager. + +
                Cudd_ReadTimeLimit() +
                Returns the time limit for the manager. + +
                Cudd_SetTimeLimit() +
                Sets the time limit for the manager. + +
                Cudd_UpdateTimeLimit() +
                Updates the time limit for the manager. + +
                Cudd_IncreaseTimeLimit() +
                Increases the time limit for the manager. + +
                Cudd_UnsetTimeLimit() +
                Unsets the time limit for the manager. + +
                Cudd_TimeLimited() +
                Returns true if the time limit for the manager is set. + +
                Cudd_AutodynEnable() +
                Enables automatic dynamic reordering of BDDs and ADDs. + +
                Cudd_AutodynDisable() +
                Disables automatic dynamic reordering. + +
                Cudd_ReorderingStatus() +
                Reports the status of automatic dynamic reordering of BDDs + and ADDs. + +
                Cudd_AutodynEnableZdd() +
                Enables automatic dynamic reordering of ZDDs. + +
                Cudd_AutodynDisableZdd() +
                Disables automatic dynamic reordering of ZDDs. + +
                Cudd_ReorderingStatusZdd() +
                Reports the status of automatic dynamic reordering of ZDDs. + +
                Cudd_zddRealignmentEnabled() +
                Tells whether the realignment of ZDD order to BDD order is + enabled. + +
                Cudd_zddRealignEnable() +
                Enables realignment of ZDD order to BDD order. + +
                Cudd_zddRealignDisable() +
                Disables realignment of ZDD order to BDD order. + +
                Cudd_bddRealignmentEnabled() +
                Tells whether the realignment of BDD order to ZDD order is + enabled. + +
                Cudd_bddRealignEnable() +
                Enables realignment of BDD order to ZDD order. + +
                Cudd_bddRealignDisable() +
                Disables realignment of ZDD order to BDD order. + +
                Cudd_ReadOne() +
                Returns the one constant of the manager. + +
                Cudd_ReadZddOne() +
                Returns the ZDD for the constant 1 function. + +
                Cudd_ReadZero() +
                Returns the zero constant of the manager. + +
                Cudd_ReadLogicZero() +
                Returns the logic zero constant of the manager. + +
                Cudd_ReadPlusInfinity() +
                Reads the plus-infinity constant from the manager. + +
                Cudd_ReadMinusInfinity() +
                Reads the minus-infinity constant from the manager. + +
                Cudd_ReadBackground() +
                Reads the background constant of the manager. + +
                Cudd_SetBackground() +
                Sets the background constant of the manager. + +
                Cudd_ReadCacheSlots() +
                Reads the number of slots in the cache. + +
                Cudd_ReadCacheUsedSlots() +
                Reads the fraction of used slots in the cache. + +
                Cudd_ReadCacheLookUps() +
                Returns the number of cache look-ups. + +
                Cudd_ReadCacheHits() +
                Returns the number of cache hits. + +
                Cudd_ReadRecursiveCalls() +
                Returns the number of recursive calls. + +
                Cudd_ReadMinHit() +
                Reads the hit rate that causes resizinig of the computed + table. + +
                Cudd_SetMinHit() +
                Sets the hit rate that causes resizinig of the computed + table. + +
                Cudd_ReadLooseUpTo() +
                Reads the looseUpTo parameter of the manager. + +
                Cudd_SetLooseUpTo() +
                Sets the looseUpTo parameter of the manager. + +
                Cudd_ReadMaxCache() +
                Returns the soft limit for the cache size. + +
                Cudd_ReadMaxCacheHard() +
                Reads the maxCacheHard parameter of the manager. + +
                Cudd_SetMaxCacheHard() +
                Sets the maxCacheHard parameter of the manager. + +
                Cudd_ReadSize() +
                Returns the number of BDD variables in existance. + +
                Cudd_ReadZddSize() +
                Returns the number of ZDD variables in existance. + +
                Cudd_ReadSlots() +
                Returns the total number of slots of the unique table. + +
                Cudd_ReadUsedSlots() +
                Reads the fraction of used slots in the unique table. + +
                Cudd_ExpectedUsedSlots() +
                Computes the expected fraction of used slots in the unique + table. + +
                Cudd_ReadKeys() +
                Returns the number of nodes in the unique table. + +
                Cudd_ReadDead() +
                Returns the number of dead nodes in the unique table. + +
                Cudd_ReadMinDead() +
                Reads the minDead parameter of the manager. + +
                Cudd_ReadReorderings() +
                Returns the number of times reordering has occurred. + +
                Cudd_ReadMaxReorderings() +
                Returns the maximum number of times reordering may be invoked. + +
                Cudd_SetMaxReorderings() +
                Sets the maximum number of times reordering may be invoked. + +
                Cudd_ReadReorderingTime() +
                Returns the time spent in reordering. + +
                Cudd_ReadGarbageCollections() +
                Returns the number of times garbage collection has occurred. + +
                Cudd_ReadGarbageCollectionTime() +
                Returns the time spent in garbage collection. + +
                Cudd_ReadNodesFreed() +
                Returns the number of nodes freed. + +
                Cudd_ReadNodesDropped() +
                Returns the number of nodes dropped. + +
                Cudd_ReadUniqueLookUps() +
                Returns the number of look-ups in the unique table. + +
                Cudd_ReadUniqueLinks() +
                Returns the number of links followed in the unique table. + +
                Cudd_ReadSiftMaxVar() +
                Reads the siftMaxVar parameter of the manager. + +
                Cudd_SetSiftMaxVar() +
                Sets the siftMaxVar parameter of the manager. + +
                Cudd_ReadSiftMaxSwap() +
                Reads the siftMaxSwap parameter of the manager. + +
                Cudd_SetSiftMaxSwap() +
                Sets the siftMaxSwap parameter of the manager. + +
                Cudd_ReadMaxGrowth() +
                Reads the maxGrowth parameter of the manager. + +
                Cudd_SetMaxGrowth() +
                Sets the maxGrowth parameter of the manager. + +
                Cudd_ReadMaxGrowthAlternate() +
                Reads the maxGrowthAlt parameter of the manager. + +
                Cudd_SetMaxGrowthAlternate() +
                Sets the maxGrowthAlt parameter of the manager. + +
                Cudd_ReadReorderingCycle() +
                Reads the reordCycle parameter of the manager. + +
                Cudd_SetReorderingCycle() +
                Sets the reordCycle parameter of the manager. + +
                Cudd_ReadTree() +
                Returns the variable group tree of the manager. + +
                Cudd_SetTree() +
                Sets the variable group tree of the manager. + +
                Cudd_FreeTree() +
                Frees the variable group tree of the manager. + +
                Cudd_ReadZddTree() +
                Returns the variable group tree of the manager. + +
                Cudd_SetZddTree() +
                Sets the ZDD variable group tree of the manager. + +
                Cudd_FreeZddTree() +
                Frees the variable group tree of the manager. + +
                Cudd_NodeReadIndex() +
                Returns the index of the node. + +
                Cudd_ReadPerm() +
                Returns the current position of the i-th variable in the + order. + +
                Cudd_ReadPermZdd() +
                Returns the current position of the i-th ZDD variable in the + order. + +
                Cudd_ReadInvPerm() +
                Returns the index of the variable currently in the i-th + position of the order. + +
                Cudd_ReadInvPermZdd() +
                Returns the index of the ZDD variable currently in the i-th + position of the order. + +
                Cudd_ReadVars() +
                Returns the i-th element of the vars array. + +
                Cudd_ReadEpsilon() +
                Reads the epsilon parameter of the manager. + +
                Cudd_SetEpsilon() +
                Sets the epsilon parameter of the manager to ep. + +
                Cudd_ReadGroupcheck() +
                Reads the groupcheck parameter of the manager. + +
                Cudd_SetGroupcheck() +
                Sets the parameter groupcheck of the manager to gc. + +
                Cudd_GarbageCollectionEnabled() +
                Tells whether garbage collection is enabled. + +
                Cudd_EnableGarbageCollection() +
                Enables garbage collection. + +
                Cudd_DisableGarbageCollection() +
                Disables garbage collection. + +
                Cudd_DeadAreCounted() +
                Tells whether dead nodes are counted towards triggering + reordering. + +
                Cudd_TurnOnCountDead() +
                Causes the dead nodes to be counted towards triggering + reordering. + +
                Cudd_TurnOffCountDead() +
                Causes the dead nodes not to be counted towards triggering + reordering. + +
                Cudd_ReadRecomb() +
                Returns the current value of the recombination parameter used + in group sifting. + +
                Cudd_SetRecomb() +
                Sets the value of the recombination parameter used in group + sifting. + +
                Cudd_ReadSymmviolation() +
                Returns the current value of the symmviolation parameter used + in group sifting. + +
                Cudd_SetSymmviolation() +
                Sets the value of the symmviolation parameter used + in group sifting. + +
                Cudd_ReadArcviolation() +
                Returns the current value of the arcviolation parameter used + in group sifting. + +
                Cudd_SetArcviolation() +
                Sets the value of the arcviolation parameter used + in group sifting. + +
                Cudd_ReadPopulationSize() +
                Reads the current size of the population used by the + genetic algorithm for reordering. + +
                Cudd_SetPopulationSize() +
                Sets the size of the population used by the + genetic algorithm for reordering. + +
                Cudd_ReadNumberXovers() +
                Reads the current number of crossovers used by the + genetic algorithm for reordering. + +
                Cudd_SetNumberXovers() +
                Sets the number of crossovers used by the + genetic algorithm for reordering. + +
                Cudd_ReadOrderRandomization() +
                Returns the order randomization factor. + +
                Cudd_SetOrderRandomization() +
                Sets the order randomization factor. + +
                Cudd_ReadMemoryInUse() +
                Returns the memory in use by the manager measured in bytes. + +
                Cudd_PrintInfo() +
                Prints out statistics and settings for a CUDD manager. + +
                Cudd_ReadPeakNodeCount() +
                Reports the peak number of nodes. + +
                Cudd_ReadPeakLiveNodeCount() +
                Reports the peak number of live nodes. + +
                Cudd_ReadNodeCount() +
                Reports the number of nodes in BDDs and ADDs. + +
                Cudd_zddReadNodeCount() +
                Reports the number of nodes in ZDDs. + +
                Cudd_AddHook() +
                Adds a function to a hook. + +
                Cudd_RemoveHook() +
                Removes a function from a hook. + +
                Cudd_IsInHook() +
                Checks whether a function is in a hook. + +
                Cudd_StdPreReordHook() +
                Sample hook function to call before reordering. + +
                Cudd_StdPostReordHook() +
                Sample hook function to call after reordering. + +
                Cudd_EnableReorderingReporting() +
                Enables reporting of reordering stats. + +
                Cudd_DisableReorderingReporting() +
                Disables reporting of reordering stats. + +
                Cudd_ReorderingReporting() +
                Returns 1 if reporting of reordering stats is enabled. + +
                Cudd_PrintGroupedOrder() +
                Hook function to print the current variable order. + +
                Cudd_EnableOrderingMonitoring() +
                Enables monitoring of ordering. + +
                Cudd_DisableOrderingMonitoring() +
                Disables monitoring of ordering. + +
                Cudd_OrderingMonitoring() +
                Returns 1 if monitoring of ordering is enabled. + +
                Cudd_ReadErrorCode() +
                Returns the code of the last error. + +
                Cudd_ClearErrorCode() +
                Clear the error code of a manager. + +
                Cudd_ReadStdout() +
                Reads the stdout of a manager. + +
                Cudd_SetStdout() +
                Sets the stdout of a manager. + +
                Cudd_ReadStderr() +
                Reads the stderr of a manager. + +
                Cudd_SetStderr() +
                Sets the stderr of a manager. + +
                Cudd_ReadNextReordering() +
                Returns the threshold for the next dynamic reordering. + +
                Cudd_SetNextReordering() +
                Sets the threshold for the next dynamic reordering. + +
                Cudd_ReadSwapSteps() +
                Reads the number of elementary reordering steps. + +
                Cudd_ReadMaxLive() +
                Reads the maximum allowed number of live nodes. + +
                Cudd_SetMaxLive() +
                Sets the maximum allowed number of live nodes. + +
                Cudd_ReadMaxMemory() +
                Reads the maximum allowed memory. + +
                Cudd_SetMaxMemory() +
                Sets the maximum allowed memory. + +
                Cudd_bddBindVar() +
                Prevents sifting of a variable. + +
                Cudd_bddUnbindVar() +
                Allows the sifting of a variable. + +
                Cudd_bddVarIsBound() +
                Tells whether a variable can be sifted. + +
                Cudd_bddSetPiVar() +
                Sets a variable type to primary input. + +
                Cudd_bddSetPsVar() +
                Sets a variable type to present state. + +
                Cudd_bddSetNsVar() +
                Sets a variable type to next state. + +
                Cudd_bddIsPiVar() +
                Checks whether a variable is primary input. + +
                Cudd_bddIsPsVar() +
                Checks whether a variable is present state. + +
                Cudd_bddIsNsVar() +
                Checks whether a variable is next state. + +
                Cudd_bddSetPairIndex() +
                Sets a corresponding pair index for a given index. + +
                Cudd_bddReadPairIndex() +
                Reads a corresponding pair index for a given index. + +
                Cudd_bddSetVarToBeGrouped() +
                Sets a variable to be grouped. + +
                Cudd_bddSetVarHardGroup() +
                Sets a variable to be a hard group. + +
                Cudd_bddResetVarToBeGrouped() +
                Resets a variable not to be grouped. + +
                Cudd_bddIsVarToBeGrouped() +
                Checks whether a variable is set to be grouped. + +
                Cudd_bddSetVarToBeUngrouped() +
                Sets a variable to be ungrouped. + +
                Cudd_bddIsVarToBeUngrouped() +
                Checks whether a variable is set to be ungrouped. + +
                Cudd_bddIsVarHardGroup() +
                Checks whether a variable is set to be in a hard group. + +
                fixVarTree() +
                Fixes a variable group tree. + +
                addMultiplicityGroups() +
                Adds multiplicity groups to a ZDD variable group tree. + +
                +
                +

                cuddApprox.c

                +Procedures to approximate a given BDD.

                +By: Fabio Somenzi

                +External procedures provided by this module: +

                  +
                • Cudd_UnderApprox() +
                • Cudd_OverApprox() +
                • Cudd_RemapUnderApprox() +
                • Cudd_RemapOverApprox() +
                • Cudd_BiasedUnderApprox() +
                • Cudd_BiasedOverApprox() +
                + Internal procedures included in this module: +
                  +
                • cuddUnderApprox() +
                • cuddRemapUnderApprox() +
                • cuddBiasedUnderApprox() +
                + Static procedures included in this module: +
                  +
                • updateParity() +
                • gatherInfoAux() +
                • gatherInfo() +
                • computeSavings() +
                • updateRefs() +
                • UAmarkNodes() +
                • UAbuildSubset() +
                • RAmarkNodes() +
                • BAmarkNodes() +
                • RAbuildSubset() +
                • BAapplyBias() +

                +

                See AlsocuddSubsetHB.c +cuddSubsetSP.c +cuddGenCof.c +

                +
                Cudd_UnderApprox() +
                Extracts a dense subset from a BDD with Shiple's + underapproximation method. + +
                Cudd_OverApprox() +
                Extracts a dense superset from a BDD with Shiple's + underapproximation method. + +
                Cudd_RemapUnderApprox() +
                Extracts a dense subset from a BDD with the remapping + underapproximation method. + +
                Cudd_RemapOverApprox() +
                Extracts a dense superset from a BDD with the remapping + underapproximation method. + +
                Cudd_BiasedUnderApprox() +
                Extracts a dense subset from a BDD with the biased + underapproximation method. + +
                Cudd_BiasedOverApprox() +
                Extracts a dense superset from a BDD with the biased + underapproximation method. + +
                cuddUnderApprox() +
                Applies Tom Shiple's underappoximation algorithm. + +
                cuddRemapUnderApprox() +
                Applies the remapping underappoximation algorithm. + +
                cuddBiasedUnderApprox() +
                Applies the biased remapping underappoximation algorithm. + +
                updateParity() +
                Recursively update the parity of the paths reaching a node. + +
                gatherInfoAux() +
                Recursively counts minterms and computes reference counts + of each node in the BDD. + +
                gatherInfo() +
                Gathers information about each node. + +
                computeSavings() +
                Counts the nodes that would be eliminated if a given node + were replaced by zero. + +
                updateRefs() +
                Update function reference counts. + +
                UAmarkNodes() +
                Marks nodes for replacement by zero. + +
                UAbuildSubset() +
                Builds the subset BDD. + +
                RAmarkNodes() +
                Marks nodes for remapping. + +
                BAmarkNodes() +
                Marks nodes for remapping. + +
                RAbuildSubset() +
                Builds the subset BDD for cuddRemapUnderApprox. + +
                BAapplyBias() +
                Finds don't care nodes. + +
                +
                +

                cuddBddAbs.c

                +Quantification functions for BDDs.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_bddExistAbstract() +
                • Cudd_bddExistAbstractLimit() +
                • Cudd_bddXorExistAbstract() +
                • Cudd_bddUnivAbstract() +
                • Cudd_bddBooleanDiff() +
                • Cudd_bddVarIsDependent() +
                + Internal procedures included in this module: +
                  +
                • cuddBddExistAbstractRecur() +
                • cuddBddXorExistAbstractRecur() +
                • cuddBddBooleanDiffRecur() +
                + Static procedures included in this module: +
                  +
                • bddCheckPositiveCube() +

                +

                +
                Cudd_bddExistAbstract() +
                Existentially abstracts all the variables in cube from f. + +
                Cudd_bddExistAbstractLimit() +
                Existentially abstracts all the variables in cube from f. + +
                Cudd_bddXorExistAbstract() +
                Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
                Cudd_bddUnivAbstract() +
                Universally abstracts all the variables in cube from f. + +
                Cudd_bddBooleanDiff() +
                Computes the boolean difference of f with respect to x. + +
                Cudd_bddVarIsDependent() +
                Checks whether a variable is dependent on others in a + function. + +
                cuddBddExistAbstractRecur() +
                Performs the recursive steps of Cudd_bddExistAbstract. + +
                cuddBddXorExistAbstractRecur() +
                Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
                cuddBddBooleanDiffRecur() +
                Performs the recursive steps of Cudd_bddBoleanDiff. + +
                bddCheckPositiveCube() +
                Checks whether cube is an BDD representing the product of + positive literals. + +
                +
                +

                cuddBddCorr.c

                +Correlation between BDDs.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_bddCorrelation() +
                • Cudd_bddCorrelationWeights() +
                + Static procedures included in this module: +
                  +
                • bddCorrelationAux() +
                • bddCorrelationWeightsAux() +
                • CorrelCompare() +
                • CorrelHash() +
                • CorrelCleanUp() +

                +

                +
                Cudd_bddCorrelation() +
                Computes the correlation of f and g. + +
                Cudd_bddCorrelationWeights() +
                Computes the correlation of f and g for given input + probabilities. + +
                bddCorrelationAux() +
                Performs the recursive step of Cudd_bddCorrelation. + +
                bddCorrelationWeightsAux() +
                Performs the recursive step of Cudd_bddCorrelationWeigths. + +
                CorrelCompare() +
                Compares two hash table entries. + +
                CorrelHash() +
                Hashes a hash table entry. + +
                CorrelCleanUp() +
                Frees memory associated with hash table. + +
                +
                +

                cuddBddIte.c

                +BDD ITE function and satellites.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_bddIte() +
                • Cudd_bddIteLimit() +
                • Cudd_bddIteConstant() +
                • Cudd_bddIntersect() +
                • Cudd_bddAnd() +
                • Cudd_bddAndLimit() +
                • Cudd_bddOr() +
                • Cudd_bddOrLimit() +
                • Cudd_bddNand() +
                • Cudd_bddNor() +
                • Cudd_bddXor() +
                • Cudd_bddXnor() +
                • Cudd_bddXnorLimit() +
                • Cudd_bddLeq() +
                + Internal procedures included in this module: +
                  +
                • cuddBddIteRecur() +
                • cuddBddIntersectRecur() +
                • cuddBddAndRecur() +
                • cuddBddXorRecur() +
                + Static procedures included in this module: +
                  +
                • bddVarToConst() +
                • bddVarToCanonical() +
                • bddVarToCanonicalSimple() +

                +

                +
                Cudd_bddIte() +
                Implements ITE(f,g,h). + +
                Cudd_bddIteLimit() +
                Implements ITE(f,g,h). Returns + NULL if too many nodes are required. + +
                Cudd_bddIteConstant() +
                Implements ITEconstant(f,g,h). + +
                Cudd_bddIntersect() +
                Returns a function included in the intersection of f and g. + +
                Cudd_bddAnd() +
                Computes the conjunction of two BDDs f and g. + +
                Cudd_bddAndLimit() +
                Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                Cudd_bddOr() +
                Computes the disjunction of two BDDs f and g. + +
                Cudd_bddOrLimit() +
                Computes the disjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                Cudd_bddNand() +
                Computes the NAND of two BDDs f and g. + +
                Cudd_bddNor() +
                Computes the NOR of two BDDs f and g. + +
                Cudd_bddXor() +
                Computes the exclusive OR of two BDDs f and g. + +
                Cudd_bddXnor() +
                Computes the exclusive NOR of two BDDs f and g. + +
                Cudd_bddXnorLimit() +
                Computes the exclusive NOR of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                Cudd_bddLeq() +
                Determines whether f is less than or equal to g. + +
                cuddBddIteRecur() +
                Implements the recursive step of Cudd_bddIte. + +
                cuddBddIntersectRecur() +
                Implements the recursive step of Cudd_bddIntersect. + +
                cuddBddAndRecur() +
                Implements the recursive step of Cudd_bddAnd. + +
                cuddBddXorRecur() +
                Implements the recursive step of Cudd_bddXor. + +
                bddVarToConst() +
                Replaces variables with constants if possible. + +
                bddVarToCanonical() +
                Picks unique member from equiv expressions. + +
                bddVarToCanonicalSimple() +
                Picks unique member from equiv expressions. + +
                +
                +

                cuddBridge.c

                +Translation from BDD to ADD and vice versa and transfer between + different managers.

                +By: Fabio Somenzi

                +External procedures included in this file: +

                  +
                • Cudd_addBddThreshold() +
                • Cudd_addBddStrictThreshold() +
                • Cudd_addBddInterval() +
                • Cudd_addBddIthBit() +
                • Cudd_BddToAdd() +
                • Cudd_addBddPattern() +
                • Cudd_bddTransfer() +
                + Internal procedures included in this file: +
                  +
                • cuddBddTransfer() +
                • cuddAddBddDoPattern() +
                + Static procedures included in this file: +
                  +
                • addBddDoThreshold() +
                • addBddDoStrictThreshold() +
                • addBddDoInterval() +
                • addBddDoIthBit() +
                • ddBddToAddRecur() +
                • cuddBddTransferRecur() +

                +

                +
                Cudd_addBddThreshold() +
                Converts an ADD to a BDD. + +
                Cudd_addBddStrictThreshold() +
                Converts an ADD to a BDD. + +
                Cudd_addBddInterval() +
                Converts an ADD to a BDD. + +
                Cudd_addBddIthBit() +
                Converts an ADD to a BDD by extracting the i-th bit from + the leaves. + +
                Cudd_BddToAdd() +
                Converts a BDD to a 0-1 ADD. + +
                Cudd_addBddPattern() +
                Converts an ADD to a BDD. + +
                Cudd_bddTransfer() +
                Convert a BDD from a manager to another one. + +
                cuddBddTransfer() +
                Convert a BDD from a manager to another one. + +
                cuddAddBddDoPattern() +
                Performs the recursive step for Cudd_addBddPattern. + +
                addBddDoThreshold() +
                Performs the recursive step for Cudd_addBddThreshold. + +
                addBddDoStrictThreshold() +
                Performs the recursive step for Cudd_addBddStrictThreshold. + +
                addBddDoInterval() +
                Performs the recursive step for Cudd_addBddInterval. + +
                addBddDoIthBit() +
                Performs the recursive step for Cudd_addBddIthBit. + +
                ddBddToAddRecur() +
                Performs the recursive step for Cudd_BddToAdd. + +
                cuddBddTransferRecur() +
                Performs the recursive step of Cudd_bddTransfer. + +
                +
                +

                cuddCache.c

                +Functions for cache insertion and lookup.

                +By: Fabio Somenzi

                +Internal procedures included in this module: +

                  +
                • cuddInitCache() +
                • cuddCacheInsert() +
                • cuddCacheInsert2() +
                • cuddCacheLookup() +
                • cuddCacheLookupZdd() +
                • cuddCacheLookup2() +
                • cuddCacheLookup2Zdd() +
                • cuddConstantLookup() +
                • cuddCacheProfile() +
                • cuddCacheResize() +
                • cuddCacheFlush() +
                • cuddComputeFloorLog2() +
                + Static procedures included in this module: +
                  +

                +

                +
                cuddInitCache() +
                Initializes the computed table. + +
                cuddCacheInsert() +
                Inserts a result in the cache for a function with three + operands. + +
                cuddCacheInsert2() +
                Inserts a result in the cache for a function with two + operands. + +
                cuddCacheInsert1() +
                Inserts a result in the cache for a function with two + operands. + +
                cuddCacheLookup() +
                Looks up in the cache for the result of op applied to f, + g, and h. + +
                cuddCacheLookupZdd() +
                Looks up in the cache for the result of op applied to f, + g, and h. + +
                cuddCacheLookup2() +
                Looks up in the cache for the result of op applied to f + and g. + +
                cuddCacheLookup1() +
                Looks up in the cache for the result of op applied to f. + +
                cuddCacheLookup2Zdd() +
                Looks up in the cache for the result of op applied to f + and g. + +
                cuddCacheLookup1Zdd() +
                Looks up in the cache for the result of op applied to f. + +
                cuddConstantLookup() +
                Looks up in the cache for the result of op applied to f, + g, and h. + +
                cuddCacheProfile() +
                Computes and prints a profile of the cache usage. + +
                cuddCacheResize() +
                Resizes the cache. + +
                cuddCacheFlush() +
                Flushes the cache. + +
                cuddComputeFloorLog2() +
                Returns the floor of the logarithm to the base 2. + +
                +
                +

                cuddCheck.c

                +Functions to check consistency of data structures.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_DebugCheck() +
                • Cudd_CheckKeys() +
                + Internal procedures included in this module: +
                  +
                • cuddHeapProfile() +
                • cuddPrintNode() +
                • cuddPrintVarGroups() +
                + Static procedures included in this module: +
                  +
                • debugFindParent() +

                +

                +
                Cudd_DebugCheck() +
                Checks for inconsistencies in the DD heap. + +
                Cudd_CheckKeys() +
                Checks for several conditions that should not occur. + +
                cuddHeapProfile() +
                Prints information about the heap. + +
                cuddPrintNode() +
                Prints out information on a node. + +
                cuddPrintVarGroups() +
                Prints the variable groups as a parenthesized list. + +
                debugFindParent() +
                Searches the subtables above node for its parents. + +
                debugCheckParent() +
                Reports an error if a (dead) node has a non-dead parent. + +
                +
                +

                cuddClip.c

                +Clipping functions.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_bddClippingAnd() +
                • Cudd_bddClippingAndAbstract() +
                + Internal procedures included in this module: +
                  +
                • cuddBddClippingAnd() +
                • cuddBddClippingAndAbstract() +
                + Static procedures included in this module: +
                  +
                • cuddBddClippingAndRecur() +
                • cuddBddClipAndAbsRecur() +
                + + SeeAlso [

                +

                +
                Cudd_bddClippingAnd() +
                Approximates the conjunction of two BDDs f and g. + +
                Cudd_bddClippingAndAbstract() +
                Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
                cuddBddClippingAnd() +
                Approximates the conjunction of two BDDs f and g. + +
                cuddBddClippingAndAbstract() +
                Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
                cuddBddClippingAndRecur() +
                Implements the recursive step of Cudd_bddClippingAnd. + +
                cuddBddClipAndAbsRecur() +
                Approximates the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                +
                +

                cuddCof.c

                +Cofactoring functions.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_Cofactor() +
                • Cudd_CheckCube() +
                + Internal procedures included in this module: +
                  +
                • cuddGetBranches() +
                • cuddCofactorRecur() +

                +

                +
                Cudd_Cofactor() +
                Computes the cofactor of f with respect to g. + +
                Cudd_CheckCube() +
                Checks whether g is the BDD of a cube. + +
                cuddGetBranches() +
                Computes the children of g. + +
                cuddCofactorRecur() +
                Performs the recursive step of Cudd_Cofactor. + +
                +
                +

                cuddCompose.c

                +Functional composition and variable permutation of DDs.

                +By: Fabio Somenzi and Kavita Ravi

                +External procedures included in this module: +

                  +
                • Cudd_bddCompose() +
                • Cudd_addCompose() +
                • Cudd_addPermute() +
                • Cudd_addSwapVariables() +
                • Cudd_bddPermute() +
                • Cudd_bddVarMap() +
                • Cudd_SetVarMap() +
                • Cudd_bddSwapVariables() +
                • Cudd_bddAdjPermuteX() +
                • Cudd_addVectorCompose() +
                • Cudd_addGeneralVectorCompose() +
                • Cudd_addNonSimCompose() +
                • Cudd_bddVectorCompose() +
                + Internal procedures included in this module: +
                  +
                • cuddBddComposeRecur() +
                • cuddAddComposeRecur() +
                + Static procedures included in this module: +
                  +
                • cuddAddPermuteRecur() +
                • cuddBddPermuteRecur() +
                • cuddBddVarMapRecur() +
                • cuddAddVectorComposeRecur() +
                • cuddAddGeneralVectorComposeRecur() +
                • cuddAddNonSimComposeRecur() +
                • cuddBddVectorComposeRecur() +
                • ddIsIthAddVar() +
                • ddIsIthAddVarPair() +
                + The permutation functions use a local cache because the results to + be remembered depend on the permutation being applied. Since the + permutation is just an array, it cannot be stored in the global + cache. There are different procedured for BDDs and ADDs. This is + because bddPermuteRecur uses cuddBddIteRecur. If this were changed, + the procedures could be merged.

                +

                +
                Cudd_bddCompose() +
                Substitutes g for x_v in the BDD for f. + +
                Cudd_addCompose() +
                Substitutes g for x_v in the ADD for f. + +
                Cudd_addPermute() +
                Permutes the variables of an ADD. + +
                Cudd_addSwapVariables() +
                Swaps two sets of variables of the same size (x and y) in + the ADD f. + +
                Cudd_bddPermute() +
                Permutes the variables of a BDD. + +
                Cudd_bddVarMap() +
                Remaps the variables of a BDD using the default variable map. + +
                Cudd_SetVarMap() +
                Registers a variable mapping with the manager. + +
                Cudd_bddSwapVariables() +
                Swaps two sets of variables of the same size (x and y) in + the BDD f. + +
                Cudd_bddAdjPermuteX() +
                Rearranges a set of variables in the BDD B. + +
                Cudd_addVectorCompose() +
                Composes an ADD with a vector of 0-1 ADDs. + +
                Cudd_addGeneralVectorCompose() +
                Composes an ADD with a vector of ADDs. + +
                Cudd_addNonSimCompose() +
                Composes an ADD with a vector of 0-1 ADDs. + +
                Cudd_bddVectorCompose() +
                Composes a BDD with a vector of BDDs. + +
                cuddBddComposeRecur() +
                Performs the recursive step of Cudd_bddCompose. + +
                cuddAddComposeRecur() +
                Performs the recursive step of Cudd_addCompose. + +
                cuddAddPermuteRecur() +
                Implements the recursive step of Cudd_addPermute. + +
                cuddBddPermuteRecur() +
                Implements the recursive step of Cudd_bddPermute. + +
                cuddBddVarMapRecur() +
                Implements the recursive step of Cudd_bddVarMap. + +
                cuddAddVectorComposeRecur() +
                Performs the recursive step of Cudd_addVectorCompose. + +
                cuddAddGeneralVectorComposeRecur() +
                Performs the recursive step of Cudd_addGeneralVectorCompose. + +
                cuddAddNonSimComposeRecur() +
                Performs the recursive step of Cudd_addNonSimCompose. + +
                cuddBddVectorComposeRecur() +
                Performs the recursive step of Cudd_bddVectorCompose. + +
                () +
                Comparison of a function to the i-th ADD variable. + +
                () +
                Comparison of a pair of functions to the i-th ADD variable. + +
                +
                +

                cuddDecomp.c

                +Functions for BDD decomposition.

                +By: Kavita Ravi, Fabio Somenzi

                +External procedures included in this file: +

                  +
                • Cudd_bddApproxConjDecomp() +
                • Cudd_bddApproxDisjDecomp() +
                • Cudd_bddIterConjDecomp() +
                • Cudd_bddIterDisjDecomp() +
                • Cudd_bddGenConjDecomp() +
                • Cudd_bddGenDisjDecomp() +
                • Cudd_bddVarConjDecomp() +
                • Cudd_bddVarDisjDecomp() +
                + Static procedures included in this module: +
                  +
                • cuddConjunctsAux() +
                • CreateBotDist() +
                • BuildConjuncts() +
                • ConjunctsFree() +

                +

                +
                Cudd_bddApproxConjDecomp() +
                Performs two-way conjunctive decomposition of a BDD. + +
                Cudd_bddApproxDisjDecomp() +
                Performs two-way disjunctive decomposition of a BDD. + +
                Cudd_bddIterConjDecomp() +
                Performs two-way conjunctive decomposition of a BDD. + +
                Cudd_bddIterDisjDecomp() +
                Performs two-way disjunctive decomposition of a BDD. + +
                Cudd_bddGenConjDecomp() +
                Performs two-way conjunctive decomposition of a BDD. + +
                Cudd_bddGenDisjDecomp() +
                Performs two-way disjunctive decomposition of a BDD. + +
                Cudd_bddVarConjDecomp() +
                Performs two-way conjunctive decomposition of a BDD. + +
                Cudd_bddVarDisjDecomp() +
                Performs two-way disjunctive decomposition of a BDD. + +
                CreateBotDist() +
                Get longest distance of node from constant. + +
                CountMinterms() +
                Count the number of minterms of each node ina a BDD and + store it in a hash table. + +
                ConjunctsFree() +
                Free factors structure + +
                PairInTables() +
                Check whether the given pair is in the tables. + +
                CheckTablesCacheAndReturn() +
                Check the tables for the existence of pair and return one + combination, cache the result. + +
                PickOnePair() +
                Check the tables for the existence of pair and return one + combination, store in cache. + +
                CheckInTables() +
                Check if the two pairs exist in the table, If any of the + conjuncts do exist, store in the cache and return the corresponding pair. + +
                ZeroCase() +
                If one child is zero, do explicitly what Restrict does or better + +
                BuildConjuncts() +
                Builds the conjuncts recursively, bottom up. + +
                cuddConjunctsAux() +
                Procedure to compute two conjunctive factors of f and place in *c1 and *c2. + +
                +
                +

                cuddEssent.c

                +Functions for the detection of essential variables.

                +By: Fabio Somenzi

                +External procedures included in this file: +

                  +
                • Cudd_FindEssential() +
                • Cudd_bddIsVarEssential() +
                • Cudd_FindTwoLiteralClauses() +
                • Cudd_ReadIthClause() +
                • Cudd_PrintTwoLiteralClauses() +
                • Cudd_tlcInfoFree() +
                + Static procedures included in this module: +
                  +
                • ddFindEssentialRecur() +
                • ddFindTwoLiteralClausesRecur() +
                • computeClauses() +
                • computeClausesWithUniverse() +
                • emptyClauseSet() +
                • sentinelp() +
                • equalp() +
                • beforep() +
                • oneliteralp() +
                • impliedp() +
                • bitVectorAlloc() +
                • bitVectorClear() +
                • bitVectorFree() +
                • bitVectorRead() +
                • bitVectorSet() +
                • tlcInfoAlloc() +

                +

                +
                Cudd_FindEssential() +
                Finds the essential variables of a DD. + +
                Cudd_bddIsVarEssential() +
                Determines whether a given variable is essential with a + given phase in a BDD. + +
                Cudd_FindTwoLiteralClauses() +
                Finds the two literal clauses of a DD. + +
                Cudd_ReadIthClause() +
                Accesses the i-th clause of a DD. + +
                Cudd_PrintTwoLiteralClauses() +
                Prints the two literal clauses of a DD. + +
                Cudd_tlcInfoFree() +
                Frees a DdTlcInfo Structure. + +
                ddFindEssentialRecur() +
                Implements the recursive step of Cudd_FindEssential. + +
                ddFindTwoLiteralClausesRecur() +
                Implements the recursive step of Cudd_FindTwoLiteralClauses. + +
                computeClauses() +
                Computes the two-literal clauses for a node. + +
                computeClausesWithUniverse() +
                Computes the two-literal clauses for a node. + +
                emptyClauseSet() +
                Returns an enpty set of clauses. + +
                sentinelp() +
                Returns true iff the argument is the sentinel clause. + +
                equalp() +
                Returns true iff the two arguments are identical clauses. + +
                beforep() +
                Returns true iff the first argument precedes the second in + the clause order. + +
                oneliteralp() +
                Returns true iff the argument is a one-literal clause. + +
                impliedp() +
                Returns true iff either literal of a clause is in a set of + literals. + +
                bitVectorAlloc() +
                Allocates a bit vector. + +
                () +
                Clears a bit vector. + +
                bitVectorFree() +
                Frees a bit vector. + +
                () +
                Returns the i-th entry of a bit vector. + +
                () +
                Sets the i-th entry of a bit vector to a value. + +
                tlcInfoAlloc() +
                Allocates a DdTlcInfo Structure. + +
                +
                +

                cuddExact.c

                +Functions for exact variable reordering.

                +By: Cheng Hua, Fabio Somenzi

                +External procedures included in this file: +

                  +
                + Internal procedures included in this module: +
                  +
                • cuddExact() +
                + Static procedures included in this module: +
                  +
                • getMaxBinomial() +
                • gcd() +
                • getMatrix() +
                • freeMatrix() +
                • getLevelKeys() +
                • ddShuffle() +
                • ddSiftUp() +
                • updateUB() +
                • ddCountRoots() +
                • ddClearGlobal() +
                • computeLB() +
                • updateEntry() +
                • pushDown() +
                • initSymmInfo() +

                +

                +
                cuddExact() +
                Exact variable ordering algorithm. + +
                getMaxBinomial() +
                Returns the maximum value of (n choose k) for a given n. + +
                gcd() +
                Returns the gcd of two integers. + +
                getMatrix() +
                Allocates a two-dimensional matrix of ints. + +
                freeMatrix() +
                Frees a two-dimensional matrix allocated by getMatrix. + +
                getLevelKeys() +
                Returns the number of nodes at one level of a unique table. + +
                ddShuffle() +
                Reorders variables according to a given permutation. + +
                ddSiftUp() +
                Moves one variable up. + +
                updateUB() +
                Updates the upper bound and saves the best order seen so far. + +
                ddCountRoots() +
                Counts the number of roots. + +
                ddClearGlobal() +
                Scans the DD and clears the LSB of the next pointers. + +
                computeLB() +
                Computes a lower bound on the size of a BDD. + +
                updateEntry() +
                Updates entry for a subset. + +
                pushDown() +
                Pushes a variable in the order down to position "level." + +
                initSymmInfo() +
                Gathers symmetry information. + +
                checkSymmInfo() +
                Check symmetry condition. + +
                +
                +

                cuddExport.c

                +Export functions.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_DumpBlif() +
                • Cudd_DumpBlifBody() +
                • Cudd_DumpDot() +
                • Cudd_DumpDaVinci() +
                • Cudd_DumpDDcal() +
                • Cudd_DumpFactoredForm() +
                + Internal procedures included in this module: +
                  +
                + Static procedures included in this module: +
                  +
                • ddDoDumpBlif() +
                • ddDoDumpDaVinci() +
                • ddDoDumpDDcal() +
                • ddDoDumpFactoredForm() +

                +

                +
                Cudd_DumpBlif() +
                Writes a blif file representing the argument BDDs. + +
                Cudd_DumpBlifBody() +
                Writes a blif body representing the argument BDDs. + +
                Cudd_DumpDot() +
                Writes a dot file representing the argument DDs. + +
                Cudd_DumpDaVinci() +
                Writes a daVinci file representing the argument BDDs. + +
                Cudd_DumpDDcal() +
                Writes a DDcal file representing the argument BDDs. + +
                Cudd_DumpFactoredForm() +
                Writes factored forms representing the argument BDDs. + +
                ddDoDumpBlif() +
                Performs the recursive step of Cudd_DumpBlif. + +
                ddDoDumpDaVinci() +
                Performs the recursive step of Cudd_DumpDaVinci. + +
                ddDoDumpDDcal() +
                Performs the recursive step of Cudd_DumpDDcal. + +
                ddDoDumpFactoredForm() +
                Performs the recursive step of Cudd_DumpFactoredForm. + +
                +
                +

                cuddGenCof.c

                +Generalized cofactors for BDDs and ADDs.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_bddConstrain() +
                • Cudd_bddRestrict() +
                • Cudd_bddNPAnd() +
                • Cudd_addConstrain() +
                • Cudd_bddConstrainDecomp() +
                • Cudd_addRestrict() +
                • Cudd_bddCharToVect() +
                • Cudd_bddLICompaction() +
                • Cudd_bddSqueeze() +
                • Cudd_bddMinimize() +
                • Cudd_SubsetCompress() +
                • Cudd_SupersetCompress() +
                + Internal procedures included in this module: +
                  +
                • cuddBddConstrainRecur() +
                • cuddBddRestrictRecur() +
                • cuddBddNPAndRecur() +
                • cuddAddConstrainRecur() +
                • cuddAddRestrictRecur() +
                • cuddBddLICompaction() +
                + Static procedures included in this module: +
                  +
                • cuddBddConstrainDecomp() +
                • cuddBddCharToVect() +
                • cuddBddLICMarkEdges() +
                • cuddBddLICBuildResult() +
                • MarkCacheHash() +
                • MarkCacheCompare() +
                • MarkCacheCleanUp() +
                • cuddBddSqueeze() +

                +

                +
                Cudd_bddConstrain() +
                Computes f constrain c. + +
                Cudd_bddRestrict() +
                BDD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
                Cudd_bddNPAnd() +
                Computes f non-polluting-and g. + +
                Cudd_addConstrain() +
                Computes f constrain c for ADDs. + +
                Cudd_bddConstrainDecomp() +
                BDD conjunctive decomposition as in McMillan's CAV96 paper. + +
                Cudd_addRestrict() +
                ADD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
                Cudd_bddCharToVect() +
                Computes a vector whose image equals a non-zero function. + +
                Cudd_bddLICompaction() +
                Performs safe minimization of a BDD. + +
                Cudd_bddSqueeze() +
                Finds a small BDD in a function interval. + +
                Cudd_bddMinimize() +
                Finds a small BDD that agrees with f over + c. + +
                Cudd_SubsetCompress() +
                Find a dense subset of BDD f. + +
                Cudd_SupersetCompress() +
                Find a dense superset of BDD f. + +
                cuddBddConstrainRecur() +
                Performs the recursive step of Cudd_bddConstrain. + +
                cuddBddRestrictRecur() +
                Performs the recursive step of Cudd_bddRestrict. + +
                cuddBddNPAndRecur() +
                Implements the recursive step of Cudd_bddAnd. + +
                cuddAddConstrainRecur() +
                Performs the recursive step of Cudd_addConstrain. + +
                cuddAddRestrictRecur() +
                Performs the recursive step of Cudd_addRestrict. + +
                cuddBddLICompaction() +
                Performs safe minimization of a BDD. + +
                cuddBddConstrainDecomp() +
                Performs the recursive step of Cudd_bddConstrainDecomp. + +
                cuddBddCharToVect() +
                Performs the recursive step of Cudd_bddCharToVect. + +
                cuddBddLICMarkEdges() +
                Performs the edge marking step of Cudd_bddLICompaction. + +
                cuddBddLICBuildResult() +
                Builds the result of Cudd_bddLICompaction. + +
                MarkCacheHash() +
                Hash function for the computed table of cuddBddLICMarkEdges. + +
                MarkCacheCompare() +
                Comparison function for the computed table of + cuddBddLICMarkEdges. + +
                MarkCacheCleanUp() +
                Frees memory associated with computed table of + cuddBddLICMarkEdges. + +
                cuddBddSqueeze() +
                Performs the recursive step of Cudd_bddSqueeze. + +
                +
                +

                cuddGenetic.c

                +Genetic algorithm for variable reordering.

                +By: Curt Musfeldt, Alan Shuler, Fabio Somenzi

                +Internal procedures included in this file: +

                  +
                • cuddGa() +
                + Static procedures included in this module: +
                  +
                • make_random() +
                • sift_up() +
                • build_dd() +
                • largest() +
                • rand_int() +
                • array_hash() +
                • array_compare() +
                • find_best() +
                • find_average_fitness() +
                • PMX() +
                • roulette() +
                + + The genetic algorithm implemented here is as follows. We start with + the current DD order. We sift this order and use this as the + reference DD. We only keep 1 DD around for the entire process and + simply rearrange the order of this DD, storing the various orders + and their corresponding DD sizes. We generate more random orders to + build an initial population. This initial population is 3 times the + number of variables, with a maximum of 120. Each random order is + built (from the reference DD) and its size stored. Each random + order is also sifted to keep the DD sizes fairly small. Then a + crossover is performed between two orders (picked randomly) and the + two resulting DDs are built and sifted. For each new order, if its + size is smaller than any DD in the population, it is inserted into + the population and the DD with the largest number of nodes is thrown + out. The crossover process happens up to 50 times, and at this point + the DD in the population with the smallest size is chosen as the + result. This DD must then be built from the reference DD.

                +

                +
                cuddGa() +
                Genetic algorithm for DD reordering. + +
                make_random() +
                Generates the random sequences for the initial population. + +
                sift_up() +
                Moves one variable up. + +
                build_dd() +
                Builds a DD from a given order. + +
                largest() +
                Finds the largest DD in the population. + +
                rand_int() +
                Generates a random number between 0 and the integer a. + +
                array_hash() +
                Hash function for the computed table. + +
                array_compare() +
                Comparison function for the computed table. + +
                find_best() +
                Returns the index of the fittest individual. + +
                () +
                Returns the average fitness of the population. + +
                PMX() +
                Performs the crossover between two parents. + +
                roulette() +
                Selects two parents with the roulette wheel method. + +
                +
                +

                cuddGroup.c

                +Functions for group sifting.

                +By: Shipra Panda, Fabio Somenzi

                +External procedures included in this file: +

                  +
                • Cudd_MakeTreeNode() +
                + Internal procedures included in this file: +
                  +
                • cuddTreeSifting() +
                + Static procedures included in this module: +
                  +
                • ddTreeSiftingAux() +
                • ddCountInternalMtrNodes() +
                • ddReorderChildren() +
                • ddFindNodeHiLo() +
                • ddUniqueCompareGroup() +
                • ddGroupSifting() +
                • ddCreateGroup() +
                • ddGroupSiftingAux() +
                • ddGroupSiftingUp() +
                • ddGroupSiftingDown() +
                • ddGroupMove() +
                • ddGroupMoveBackward() +
                • ddGroupSiftingBackward() +
                • ddMergeGroups() +
                • ddDissolveGroup() +
                • ddNoCheck() +
                • ddSecDiffCheck() +
                • ddExtSymmCheck() +
                • ddVarGroupCheck() +
                • ddSetVarHandled() +
                • ddResetVarHandled() +
                • ddIsVarHandled() +
                • ddFixTree() +

                +

                +
                Cudd_MakeTreeNode() +
                Creates a new variable group. + +
                cuddTreeSifting() +
                Tree sifting algorithm. + +
                ddTreeSiftingAux() +
                Visits the group tree and reorders each group. + +
                ddCountInternalMtrNodes() +
                Counts the number of internal nodes of the group tree. + +
                ddReorderChildren() +
                Reorders the children of a group tree node according to + the options. + +
                ddFindNodeHiLo() +
                Finds the lower and upper bounds of the group represented + by treenode. + +
                ddUniqueCompareGroup() +
                Comparison function used by qsort. + +
                ddGroupSifting() +
                Sifts from treenode->low to treenode->high. + +
                ddCreateGroup() +
                Creates a group encompassing variables from x to y in the + DD table. + +
                ddGroupSiftingAux() +
                Sifts one variable up and down until it has taken all + positions. Checks for aggregation. + +
                ddGroupSiftingUp() +
                Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much. + +
                ddGroupSiftingDown() +
                Sifts down a variable until it reaches position xHigh. + +
                ddGroupMove() +
                Swaps two groups and records the move. + +
                ddGroupMoveBackward() +
                Undoes the swap two groups. + +
                ddGroupSiftingBackward() +
                Determines the best position for a variables and returns + it there. + +
                ddMergeGroups() +
                Merges groups in the DD table. + +
                ddDissolveGroup() +
                Dissolves a group in the DD table. + +
                ddNoCheck() +
                Pretends to check two variables for aggregation. + +
                ddSecDiffCheck() +
                Checks two variables for aggregation. + +
                ddExtSymmCheck() +
                Checks for extended symmetry of x and y. + +
                ddVarGroupCheck() +
                Checks for grouping of x and y. + +
                ddSetVarHandled() +
                Sets a variable to already handled. + +
                ddResetVarHandled() +
                Resets a variable to be processed. + +
                ddIsVarHandled() +
                Checks whether a variables is already handled. + +
                +
                +

                cuddHarwell.c

                +Function to read a matrix in Harwell format.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_addHarwell() +

                +

                +
                Cudd_addHarwell() +
                Reads in a matrix in the format of the Harwell-Boeing + benchmark suite. + +
                +
                +

                cuddInit.c

                +Functions to initialize and shut down the DD manager.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_Init() +
                • Cudd_Quit() +
                + Internal procedures included in this module: +
                  +
                • cuddZddInitUniv() +
                • cuddZddFreeUniv() +

                +

                +
                Cudd_Init() +
                Creates a new DD manager. + +
                Cudd_Quit() +
                Deletes resources associated with a DD manager. + +
                cuddZddInitUniv() +
                Initializes the ZDD universe. + +
                cuddZddFreeUniv() +
                Frees the ZDD universe. + +
                +
                +

                cuddInteract.c

                +Functions to manipulate the variable interaction matrix.

                +By: Fabio Somenzi

                +Internal procedures included in this file: +

                  +
                • cuddSetInteract() +
                • cuddTestInteract() +
                • cuddInitInteract() +
                + Static procedures included in this file: +
                  +
                • ddSuppInteract() +
                • ddClearLocal() +
                • ddUpdateInteract() +
                • ddClearGlobal() +
                + The interaction matrix tells whether two variables are + both in the support of some function of the DD. The main use of the + interaction matrix is in the in-place swapping. Indeed, if two + variables do not interact, there is no arc connecting the two layers; + therefore, the swap can be performed in constant time, without + scanning the subtables. Another use of the interaction matrix is in + the computation of the lower bounds for sifting. Finally, the + interaction matrix can be used to speed up aggregation checks in + symmetric and group sifting.

                + The computation of the interaction matrix is done with a series of + depth-first searches. The searches start from those nodes that have + only external references. The matrix is stored as a packed array of bits; + since it is symmetric, only the upper triangle is kept in memory. + As a final remark, we note that there may be variables that do + interact, but that for a given variable order have no arc connecting + their layers when they are adjacent. For instance, in ite(a,b,c) with + the order a +

                +
                cuddSetInteract() +
                Set interaction matrix entries. + +
                cuddTestInteract() +
                Test interaction matrix entries. + +
                cuddInitInteract() +
                Initializes the interaction matrix. + +
                ddSuppInteract() +
                Find the support of f. + +
                ddClearLocal() +
                Performs a DFS from f, clearing the LSB of the then pointers. + +
                ddUpdateInteract() +
                Marks as interacting all pairs of variables that appear in + support. + +
                ddClearGlobal() +
                Scans the DD and clears the LSB of the next pointers. + +
                +
                +

                cuddLCache.c

                +Functions for local caches.

                +By: Fabio Somenzi

                +Internal procedures included in this module: +

                  +
                • cuddLocalCacheInit() +
                • cuddLocalCacheQuit() +
                • cuddLocalCacheInsert() +
                • cuddLocalCacheLookup() +
                • cuddLocalCacheClearDead() +
                • cuddLocalCacheClearAll() +
                • cuddLocalCacheProfile() +
                • cuddHashTableInit() +
                • cuddHashTableQuit() +
                • cuddHashTableGenericQuit() +
                • cuddHashTableInsert() +
                • cuddHashTableLookup() +
                • cuddHashTableGenericInsert() +
                • cuddHashTableGenericLookup() +
                • cuddHashTableInsert2() +
                • cuddHashTableLookup2() +
                • cuddHashTableInsert3() +
                • cuddHashTableLookup3() +
                + Static procedures included in this module: +
                  +
                • cuddLocalCacheResize() +
                • ddLCHash() +
                • cuddLocalCacheAddToList() +
                • cuddLocalCacheRemoveFromList() +
                • cuddHashTableResize() +
                • cuddHashTableAlloc() +

                +

                +
                cuddLocalCacheInit() +
                Initializes a local computed table. + +
                cuddLocalCacheQuit() +
                Shuts down a local computed table. + +
                cuddLocalCacheInsert() +
                Inserts a result in a local cache. + +
                cuddLocalCacheLookup() +
                Looks up in a local cache. + +
                cuddLocalCacheClearDead() +
                Clears the dead entries of the local caches of a manager. + +
                cuddLocalCacheClearAll() +
                Clears the local caches of a manager. + +
                cuddLocalCacheProfile() +
                Computes and prints a profile of a local cache usage. + +
                cuddHashTableInit() +
                Initializes a hash table. + +
                cuddHashTableQuit() +
                Shuts down a hash table. + +
                cuddHashTableGenericQuit() +
                Shuts down a hash table. + +
                cuddHashTableInsert() +
                Inserts an item in a hash table. + +
                cuddHashTableLookup() +
                Looks up a key in a hash table. + +
                cuddHashTableInsert1() +
                Inserts an item in a hash table. + +
                cuddHashTableLookup1() +
                Looks up a key consisting of one pointer in a hash table. + +
                cuddHashTableGenericInsert() +
                Inserts an item in a hash table. + +
                cuddHashTableGenericLookup() +
                Looks up a key consisting of one pointer in a hash table. + +
                cuddHashTableInsert2() +
                Inserts an item in a hash table. + +
                cuddHashTableLookup2() +
                Looks up a key consisting of two pointers in a hash table. + +
                cuddHashTableInsert3() +
                Inserts an item in a hash table. + +
                cuddHashTableLookup3() +
                Looks up a key consisting of three pointers in a hash table. + +
                cuddLocalCacheResize() +
                Resizes a local cache. + +
                () +
                Computes the hash value for a local cache. + +
                cuddLocalCacheAddToList() +
                Inserts a local cache in the manager list. + +
                cuddLocalCacheRemoveFromList() +
                Removes a local cache from the manager list. + +
                cuddHashTableResize() +
                Resizes a hash table. + +
                () +
                Fast storage allocation for items in a hash table. + +
                +
                +

                cuddLevelQ.c

                +Procedure to manage level queues.

                +By: Fabio Somenzi

                +The functions in this file allow an application to + easily manipulate a queue where nodes are prioritized by level. The + emphasis is on efficiency. Therefore, the queue items can have + variable size. If the application does not need to attach + information to the nodes, it can declare the queue items to be of + type DdQueueItem. Otherwise, it can declare them to be of a + structure type such that the first three fields are data + pointers. The third pointer points to the node. The first two + pointers are used by the level queue functions. The remaining fields + are initialized to 0 when a new item is created, and are then left + to the exclusive use of the application. On the DEC Alphas the three + pointers must be 32-bit pointers when CUDD is compiled with 32-bit + pointers. The level queue functions make sure that each node + appears at most once in the queue. They do so by keeping a hash + table where the node is used as key. Queue items are recycled via a + free list for efficiency. + + Internal procedures provided by this module: +

                  +
                • cuddLevelQueueInit() +
                • cuddLevelQueueQuit() +
                • cuddLevelQueueEnqueue() +
                • cuddLevelQueueDequeue() +
                + Static procedures included in this module: +
                  +
                • hashLookup() +
                • hashInsert() +
                • hashDelete() +
                • hashResize() +

                +

                +
                cuddLevelQueueInit() +
                Initializes a level queue. + +
                cuddLevelQueueQuit() +
                Shuts down a level queue. + +
                cuddLevelQueueEnqueue() +
                Inserts a new key in a level queue. + +
                cuddLevelQueueFirst() +
                Inserts the first key in a level queue. + +
                cuddLevelQueueDequeue() +
                Remove an item from the front of a level queue. + +
                hashLookup() +
                Looks up a key in the hash table of a level queue. + +
                hashInsert() +
                Inserts an item in the hash table of a level queue. + +
                hashDelete() +
                Removes an item from the hash table of a level queue. + +
                hashResize() +
                Resizes the hash table of a level queue. + +
                +
                +

                cuddLinear.c

                +Functions for DD reduction by linear transformations.

                +By: Fabio Somenzi

                +Internal procedures included in this module: +

                  +
                • cuddLinearAndSifting() +
                • cuddLinearInPlace() +
                • cuddUpdateInteractionMatrix() +
                • cuddInitLinear() +
                • cuddResizeLinear() +
                + Static procedures included in this module: +
                  +
                • ddLinearUniqueCompare() +
                • ddLinearAndSiftingAux() +
                • ddLinearAndSiftingUp() +
                • ddLinearAndSiftingDown() +
                • ddLinearAndSiftingBackward() +
                • ddUndoMoves() +
                • cuddXorLinear() +

                +

                +
                Cudd_PrintLinear() +
                Prints the linear transform matrix. + +
                Cudd_ReadLinear() +
                Reads an entry of the linear transform matrix. + +
                cuddLinearAndSifting() +
                BDD reduction based on combination of sifting and linear + transformations. + +
                cuddLinearInPlace() +
                Linearly combines two adjacent variables. + +
                cuddUpdateInteractionMatrix() +
                Updates the interaction matrix. + +
                cuddInitLinear() +
                Initializes the linear transform matrix. + +
                cuddResizeLinear() +
                Resizes the linear transform matrix. + +
                ddLinearUniqueCompare() +
                Comparison function used by qsort. + +
                ddLinearAndSiftingAux() +
                Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                ddLinearAndSiftingUp() +
                Sifts a variable up and applies linear transformations. + +
                ddLinearAndSiftingDown() +
                Sifts a variable down and applies linear transformations. + +
                ddLinearAndSiftingBackward() +
                Given a set of moves, returns the DD heap to the order + giving the minimum size. + +
                ddUndoMoves() +
                Given a set of moves, returns the DD heap to the order + in effect before the moves. + +
                cuddXorLinear() +
                XORs two rows of the linear transform matrix. + +
                +
                +

                cuddLiteral.c

                +Functions for manipulation of literal sets represented by + BDDs.

                +By: Fabio Somenzi

                +External procedures included in this file: +

                  +
                • Cudd_bddLiteralSetIntersection() +
                + Internal procedures included in this file: +
                  +
                • cuddBddLiteralSetIntersectionRecur() +

                +

                +
                Cudd_bddLiteralSetIntersection() +
                Computes the intesection of two sets of literals + represented as BDDs. + +
                cuddBddLiteralSetIntersectionRecur() +
                Performs the recursive step of + Cudd_bddLiteralSetIntersection. + +
                +
                +

                cuddMatMult.c

                +Matrix multiplication functions.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_addMatrixMultiply() +
                • Cudd_addTimesPlus() +
                • Cudd_addTriangle() +
                • Cudd_addOuterSum() +
                + Static procedures included in this module: +
                  +
                • addMMRecur() +
                • addTriangleRecur() +
                • cuddAddOuterSumRecur() +

                +

                +
                Cudd_addMatrixMultiply() +
                Calculates the product of two matrices represented as + ADDs. + +
                Cudd_addTimesPlus() +
                Calculates the product of two matrices represented as + ADDs. + +
                Cudd_addTriangle() +
                Performs the triangulation step for the shortest path + computation. + +
                Cudd_addOuterSum() +
                Takes the minimum of a matrix and the outer sum of two vectors. + +
                addMMRecur() +
                Performs the recursive step of Cudd_addMatrixMultiply. + +
                addTriangleRecur() +
                Performs the recursive step of Cudd_addTriangle. + +
                cuddAddOuterSumRecur() +
                Performs the recursive step of Cudd_addOuterSum. + +
                +
                +

                cuddPriority.c

                +Priority functions.

                +By: Fabio Somenzi

                +External procedures included in this file: +

                  +
                • Cudd_PrioritySelect() +
                • Cudd_Xgty() +
                • Cudd_Xeqy() +
                • Cudd_addXeqy() +
                • Cudd_Dxygtdxz() +
                • Cudd_Dxygtdyz() +
                • Cudd_Inequality() +
                • Cudd_Disequality() +
                • Cudd_bddInterval() +
                • Cudd_CProjection() +
                • Cudd_addHamming() +
                • Cudd_MinHammingDist() +
                • Cudd_bddClosestCube() +
                + Internal procedures included in this module: +
                  +
                • cuddCProjectionRecur() +
                • cuddBddClosestCube() +
                + Static procedures included in this module: +
                  +
                • cuddMinHammingDistRecur() +
                • separateCube() +
                • createResult() +

                +

                +
                Cudd_PrioritySelect() +
                Selects pairs from R using a priority function. + +
                Cudd_Xgty() +
                Generates a BDD for the function x > y. + +
                Cudd_Xeqy() +
                Generates a BDD for the function x==y. + +
                Cudd_addXeqy() +
                Generates an ADD for the function x==y. + +
                Cudd_Dxygtdxz() +
                Generates a BDD for the function d(x,y) > d(x,z). + +
                Cudd_Dxygtdyz() +
                Generates a BDD for the function d(x,y) > d(y,z). + +
                Cudd_Inequality() +
                Generates a BDD for the function x - y ≥ c. + +
                Cudd_Disequality() +
                Generates a BDD for the function x - y != c. + +
                Cudd_bddInterval() +
                Generates a BDD for the function lowerB ≤ x ≤ upperB. + +
                Cudd_CProjection() +
                Computes the compatible projection of R w.r.t. cube Y. + +
                Cudd_addHamming() +
                Computes the Hamming distance ADD. + +
                Cudd_MinHammingDist() +
                Returns the minimum Hamming distance between f and minterm. + +
                Cudd_bddClosestCube() +
                Finds a cube of f at minimum Hamming distance from g. + +
                cuddCProjectionRecur() +
                Performs the recursive step of Cudd_CProjection. + +
                cuddBddClosestCube() +
                Performs the recursive step of Cudd_bddClosestCube. + +
                cuddMinHammingDistRecur() +
                Performs the recursive step of Cudd_MinHammingDist. + +
                separateCube() +
                Separates cube from distance. + +
                createResult() +
                Builds a result for cache storage. + +
                +
                +

                cuddRead.c

                +Functions to read in a matrix

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_addRead() +
                • Cudd_bddRead() +

                +

                See Alsocudd_addHarwell.c +

                +
                Cudd_addRead() +
                Reads in a sparse matrix. + +
                Cudd_bddRead() +
                Reads in a graph (without labels) given as a list of arcs. + +
                +
                +

                cuddRef.c

                +Functions that manipulate the reference counts.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_Ref() +
                • Cudd_RecursiveDeref() +
                • Cudd_IterDerefBdd() +
                • Cudd_DelayedDerefBdd() +
                • Cudd_RecursiveDerefZdd() +
                • Cudd_Deref() +
                • Cudd_CheckZeroRef() +
                + Internal procedures included in this module: +
                  +
                • cuddReclaim() +
                • cuddReclaimZdd() +
                • cuddClearDeathRow() +
                • cuddShrinkDeathRow() +
                • cuddIsInDeathRow() +
                • cuddTimesInDeathRow() +

                +

                +
                Cudd_Ref() +
                Increases the reference count of a node, if it is not + saturated. + +
                Cudd_RecursiveDeref() +
                Decreases the reference count of node n. + +
                Cudd_IterDerefBdd() +
                Decreases the reference count of BDD node n. + +
                Cudd_DelayedDerefBdd() +
                Decreases the reference count of BDD node n. + +
                Cudd_RecursiveDerefZdd() +
                Decreases the reference count of ZDD node n. + +
                Cudd_Deref() +
                Decreases the reference count of node. + +
                Cudd_CheckZeroRef() +
                Checks the unique table for nodes with non-zero reference + counts. + +
                cuddReclaim() +
                Brings children of a dead node back. + +
                cuddReclaimZdd() +
                Brings children of a dead ZDD node back. + +
                cuddShrinkDeathRow() +
                Shrinks the death row. + +
                cuddClearDeathRow() +
                Clears the death row. + +
                cuddIsInDeathRow() +
                Checks whether a node is in the death row. + +
                cuddTimesInDeathRow() +
                Counts how many times a node is in the death row. + +
                +
                +

                cuddReorder.c

                +Functions for dynamic variable reordering.

                +By: Shipra Panda, Bernard Plessier, Fabio Somenzi

                +External procedures included in this file: +

                  +
                • Cudd_ReduceHeap() +
                • Cudd_ShuffleHeap() +
                + Internal procedures included in this module: +
                  +
                • cuddDynamicAllocNode() +
                • cuddSifting() +
                • cuddSwapping() +
                • cuddNextHigh() +
                • cuddNextLow() +
                • cuddSwapInPlace() +
                • cuddBddAlignToZdd() +
                + Static procedures included in this module: +
                  +
                • ddUniqueCompare() +
                • ddSwapAny() +
                • ddSiftingAux() +
                • ddSiftingUp() +
                • ddSiftingDown() +
                • ddSiftingBackward() +
                • ddReorderPreprocess() +
                • ddReorderPostprocess() +
                • ddShuffle() +
                • ddSiftUp() +
                • bddFixTree() +

                +

                +
                Cudd_ReduceHeap() +
                Main dynamic reordering routine. + +
                Cudd_ShuffleHeap() +
                Reorders variables according to given permutation. + +
                cuddDynamicAllocNode() +
                Dynamically allocates a Node. + +
                cuddSifting() +
                Implementation of Rudell's sifting algorithm. + +
                cuddSwapping() +
                Reorders variables by a sequence of (non-adjacent) swaps. + +
                cuddNextHigh() +
                Finds the next subtable with a larger index. + +
                cuddNextLow() +
                Finds the next subtable with a smaller index. + +
                cuddSwapInPlace() +
                Swaps two adjacent variables. + +
                cuddBddAlignToZdd() +
                Reorders BDD variables according to the order of the ZDD + variables. + +
                ddUniqueCompare() +
                Comparison function used by qsort. + +
                ddSwapAny() +
                Swaps any two variables. + +
                ddSiftingAux() +
                Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                ddSiftingUp() +
                Sifts a variable up. + +
                ddSiftingDown() +
                Sifts a variable down. + +
                ddSiftingBackward() +
                Given a set of moves, returns the DD heap to the position + giving the minimum size. + +
                ddReorderPreprocess() +
                Prepares the DD heap for dynamic reordering. + +
                ddReorderPostprocess() +
                Cleans up at the end of reordering. + +
                ddShuffle() +
                Reorders variables according to a given permutation. + +
                ddSiftUp() +
                Moves one variable up. + +
                bddFixTree() +
                Fixes the BDD variable group tree after a shuffle. + +
                ddUpdateMtrTree() +
                Updates the BDD variable group tree before a shuffle. + +
                ddCheckPermuation() +
                Checks the BDD variable group tree before a shuffle. + +
                +
                +

                cuddSat.c

                +Functions for the solution of satisfiability related problems.

                +By: Seh-Woong Jeong, Fabio Somenzi

                +External procedures included in this file: +

                  +
                • Cudd_Eval() +
                • Cudd_ShortestPath() +
                • Cudd_LargestCube() +
                • Cudd_ShortestLength() +
                • Cudd_Decreasing() +
                • Cudd_Increasing() +
                • Cudd_EquivDC() +
                • Cudd_bddLeqUnless() +
                • Cudd_EqualSupNorm() +
                • Cudd_bddMakePrime() +
                • Cudd_bddMaximallyExpand() +
                • Cudd_bddLargestPrimeUnate() +
                + Internal procedures included in this module: +
                  +
                • cuddBddMakePrime() +
                + Static procedures included in this module: +
                  +
                • freePathPair() +
                • getShortest() +
                • getPath() +
                • getLargest() +
                • getCube() +
                • ddBddMaximallyExpand() +
                • ddShortestPathUnate() +

                +

                +
                Cudd_Eval() +
                Returns the value of a DD for a given variable assignment. + +
                Cudd_ShortestPath() +
                Finds a shortest path in a DD. + +
                Cudd_LargestCube() +
                Finds a largest cube in a DD. + +
                Cudd_ShortestLength() +
                Find the length of the shortest path(s) in a DD. + +
                Cudd_Decreasing() +
                Determines whether a BDD is negative unate in a + variable. + +
                Cudd_Increasing() +
                Determines whether a BDD is positive unate in a + variable. + +
                Cudd_EquivDC() +
                Tells whether F and G are identical wherever D is 0. + +
                Cudd_bddLeqUnless() +
                Tells whether f is less than of equal to G unless D is 1. + +
                Cudd_EqualSupNorm() +
                Compares two ADDs for equality within tolerance. + +
                Cudd_bddMakePrime() +
                Expands cube to a prime implicant of f. + +
                Cudd_bddMaximallyExpand() +
                Expands lb to prime implicants of (f and ub). + +
                Cudd_bddLargestPrimeUnate() +
                Find a largest prime of a unate function. + +
                cuddBddMakePrime() +
                Performs the recursive step of Cudd_bddMakePrime. + +
                freePathPair() +
                Frees the entries of the visited symbol table. + +
                getShortest() +
                Finds the length of the shortest path(s) in a DD. + +
                getPath() +
                Build a BDD for a shortest path of f. + +
                getLargest() +
                Finds the size of the largest cube(s) in a DD. + +
                getCube() +
                Build a BDD for a largest cube of f. + +
                ddBddMaximallyExpand() +
                Performs the recursive step of Cudd_bddMaximallyExpand. + +
                ddBddShortestPathUnate() +
                Performs shortest path computation on a unate function. + +
                ddGetLargestCubeUnate() +
                Extracts largest prime of a unate function. + +
                +
                +

                cuddSign.c

                +Computation of signatures.

                +By: Fabio Somenzi

                +External procedures included in this module: +

                  +
                • Cudd_CofMinterm(); +
                + Static procedures included in this module: +
                  +
                • ddCofMintermAux() +

                +

                +
                Cudd_CofMinterm() +
                Computes the fraction of minterms in the on-set of all the + positive cofactors of a BDD or ADD. + +
                ddCofMintermAux() +
                Recursive Step for Cudd_CofMinterm function. + +
                +
                +

                cuddSolve.c

                +Boolean equation solver and related functions.

                +By: Balakrishna Kumthekar

                +External functions included in this modoule: +

                  +
                • Cudd_SolveEqn() +
                • Cudd_VerifySol() +
                + Internal functions included in this module: +
                  +
                • cuddSolveEqnRecur() +
                • cuddVerifySol() +

                +

                +
                Cudd_SolveEqn() +
                Implements the solution of F(x,y) = 0. + +
                Cudd_VerifySol() +
                Checks the solution of F(x,y) = 0. + +
                cuddSolveEqnRecur() +
                Implements the recursive step of Cudd_SolveEqn. + +
                cuddVerifySol() +
                Implements the recursive step of Cudd_VerifySol. + +
                +
                +

                cuddSplit.c

                +Returns a subset of minterms from a boolean function.

                +By: Balakrishna Kumthekar

                +External functions included in this modoule: +

                  +
                • Cudd_SplitSet() +
                + Internal functions included in this module: +
                  +
                • cuddSplitSetRecur() + + Static functions included in this module: +
                    +
                  • selectMintermsFromUniverse() +
                  • mintermsFromUniverse() +
                  • bddAnnotateMintermCount() +

                  +

                  +
                  Cudd_SplitSet() +
                  Returns m minterms from a BDD. + +
                  cuddSplitSetRecur() +
                  Implements the recursive step of Cudd_SplitSet. + +
                  selectMintermsFromUniverse() +
                  This function prepares an array of variables which have not been + encountered so far when traversing the procedure cuddSplitSetRecur. + +
                  mintermsFromUniverse() +
                  Recursive procedure to extract n mintems from constant 1. + +
                  bddAnnotateMintermCount() +
                  Annotates every node in the BDD node with its minterm count. + +
                  +
                  +

                  cuddSubsetHB.c

                  +Procedure to subset the given BDD by choosing the heavier + branches.

                  +By: Kavita Ravi

                  +External procedures provided by this module: +

                    +
                  • Cudd_SubsetHeavyBranch() +
                  • Cudd_SupersetHeavyBranch() +
                  + Internal procedures included in this module: +
                    +
                  • cuddSubsetHeavyBranch() +
                  + Static procedures included in this module: +
                    +
                  • ResizeCountMintermPages(); +
                  • ResizeNodeDataPages() +
                  • ResizeCountNodePages() +
                  • SubsetCountMintermAux() +
                  • SubsetCountMinterm() +
                  • SubsetCountNodesAux() +
                  • SubsetCountNodes() +
                  • BuildSubsetBdd() +

                  +

                  See AlsocuddSubsetSP.c +

                  +
                  Cudd_SubsetHeavyBranch() +
                  Extracts a dense subset from a BDD with the heavy branch + heuristic. + +
                  Cudd_SupersetHeavyBranch() +
                  Extracts a dense superset from a BDD with the heavy branch + heuristic. + +
                  cuddSubsetHeavyBranch() +
                  The main procedure that returns a subset by choosing the heavier + branch in the BDD. + +
                  ResizeNodeDataPages() +
                  Resize the number of pages allocated to store the node data. + +
                  ResizeCountMintermPages() +
                  Resize the number of pages allocated to store the minterm + counts. + +
                  ResizeCountNodePages() +
                  Resize the number of pages allocated to store the node counts. + +
                  SubsetCountMintermAux() +
                  Recursively counts minterms of each node in the DAG. + +
                  SubsetCountMinterm() +
                  Counts minterms of each node in the DAG + +
                  SubsetCountNodesAux() +
                  Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node. + +
                  SubsetCountNodes() +
                  Counts the nodes under the current node and its lighter child + +
                  StoreNodes() +
                  Procedure to recursively store nodes that are retained in the subset. + +
                  BuildSubsetBdd() +
                  Builds the subset BDD using the heavy branch method. + +
                  +
                  +

                  cuddSubsetSP.c

                  +Procedure to subset the given BDD choosing the shortest paths + (largest cubes) in the BDD.

                  +By: Kavita Ravi

                  +External procedures included in this module: +

                    +
                  • Cudd_SubsetShortPaths() +
                  • Cudd_SupersetShortPaths() +
                  + Internal procedures included in this module: +
                    +
                  • cuddSubsetShortPaths() +
                  + Static procedures included in this module: +
                    +
                  • BuildSubsetBdd() +
                  • CreatePathTable() +
                  • AssessPathLength() +
                  • CreateTopDist() +
                  • CreateBotDist() +
                  • ResizeNodeDistPages() +
                  • ResizeQueuePages() +
                  • stPathTableDdFree() +

                  +

                  See AlsocuddSubsetHB.c +

                  +
                  Cudd_SubsetShortPaths() +
                  Extracts a dense subset from a BDD with the shortest paths + heuristic. + +
                  Cudd_SupersetShortPaths() +
                  Extracts a dense superset from a BDD with the shortest paths + heuristic. + +
                  cuddSubsetShortPaths() +
                  The outermost procedure to return a subset of the given BDD + with the shortest path lengths. + +
                  ResizeNodeDistPages() +
                  Resize the number of pages allocated to store the distances + related to each node. + +
                  ResizeQueuePages() +
                  Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd . + +
                  CreateTopDist() +
                  Labels each node with its shortest distance from the root + +
                  CreateBotDist() +
                  Labels each node with the shortest distance from the constant. + +
                  CreatePathTable() +
                  The outer procedure to label each node with its shortest + distance from the root and constant + +
                  AssessPathLength() +
                  Chooses the maximum allowable path length of nodes under the + threshold. + +
                  BuildSubsetBdd() +
                  Builds the BDD with nodes labeled with path length less than or equal to maxpath + +
                  stPathTableDdFree() +
                  Procedure to free te result dds stored in the NodeDist pages. + +
                  +
                  +

                  cuddSymmetry.c

                  +Functions for symmetry-based variable reordering.

                  +By: Shipra Panda, Fabio Somenzi

                  +External procedures included in this file: +

                    +
                  • Cudd_SymmProfile() +
                  + Internal procedures included in this module: +
                    +
                  • cuddSymmCheck() +
                  • cuddSymmSifting() +
                  • cuddSymmSiftingConv() +
                  + Static procedures included in this module: +
                    +
                  • ddSymmUniqueCompare() +
                  • ddSymmSiftingAux() +
                  • ddSymmSiftingConvAux() +
                  • ddSymmSiftingUp() +
                  • ddSymmSiftingDown() +
                  • ddSymmGroupMove() +
                  • ddSymmGroupMoveBackward() +
                  • ddSymmSiftingBackward() +
                  • ddSymmSummary() +

                  +

                  +
                  Cudd_SymmProfile() +
                  Prints statistics on symmetric variables. + +
                  cuddSymmCheck() +
                  Checks for symmetry of x and y. + +
                  cuddSymmSifting() +
                  Symmetric sifting algorithm. + +
                  cuddSymmSiftingConv() +
                  Symmetric sifting to convergence algorithm. + +
                  ddSymmUniqueCompare() +
                  Comparison function used by qsort. + +
                  ddSymmSiftingAux() +
                  Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                  ddSymmSiftingConvAux() +
                  Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                  ddSymmSiftingUp() +
                  Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much. + +
                  ddSymmSiftingDown() +
                  Moves x down until either it reaches the bound (xHigh) or + the size of the DD heap increases too much. + +
                  ddSymmGroupMove() +
                  Swaps two groups. + +
                  ddSymmGroupMoveBackward() +
                  Undoes the swap of two groups. + +
                  ddSymmSiftingBackward() +
                  Given a set of moves, returns the DD heap to the position + giving the minimum size. + +
                  ddSymmSummary() +
                  Counts numbers of symmetric variables and symmetry + groups. + +
                  +
                  +

                  cuddTable.c

                  +Unique table management functions.

                  +By: Fabio Somenzi

                  +External procedures included in this module: +

                    +
                  • Cudd_Prime() +
                  • Cudd_Reserve() +
                  + Internal procedures included in this module: +
                    +
                  • cuddAllocNode() +
                  • cuddInitTable() +
                  • cuddFreeTable() +
                  • cuddGarbageCollect() +
                  • cuddZddGetNode() +
                  • cuddZddGetNodeIVO() +
                  • cuddUniqueInter() +
                  • cuddUniqueInterIVO() +
                  • cuddUniqueInterZdd() +
                  • cuddUniqueConst() +
                  • cuddRehash() +
                  • cuddShrinkSubtable() +
                  • cuddInsertSubtables() +
                  • cuddDestroySubtables() +
                  • cuddResizeTableZdd() +
                  • cuddSlowTableGrowth() +
                  + Static procedures included in this module: +
                    +
                  • ddRehashZdd() +
                  • ddResizeTable() +
                  • cuddFindParent() +
                  • cuddOrderedInsert() +
                  • cuddOrderedThread() +
                  • cuddRotateLeft() +
                  • cuddRotateRight() +
                  • cuddDoRebalance() +
                  • cuddCheckCollisionOrdering() +

                  +

                  +
                  Cudd_Prime() +
                  Returns the next prime >= p. + +
                  Cudd_Reserve() +
                  Expand manager without creating variables. + +
                  cuddAllocNode() +
                  Fast storage allocation for DdNodes in the table. + +
                  cuddInitTable() +
                  Creates and initializes the unique table. + +
                  cuddFreeTable() +
                  Frees the resources associated to a unique table. + +
                  cuddGarbageCollect() +
                  Performs garbage collection on the unique tables. + +
                  cuddZddGetNode() +
                  Wrapper for cuddUniqueInterZdd. + +
                  cuddZddGetNodeIVO() +
                  Wrapper for cuddUniqueInterZdd that is independent of variable + ordering. + +
                  cuddUniqueInter() +
                  Checks the unique table for the existence of an internal node. + +
                  cuddUniqueInterIVO() +
                  Wrapper for cuddUniqueInter that is independent of variable + ordering. + +
                  cuddUniqueInterZdd() +
                  Checks the unique table for the existence of an internal + ZDD node. + +
                  cuddUniqueConst() +
                  Checks the unique table for the existence of a constant node. + +
                  cuddRehash() +
                  Rehashes a unique subtable. + +
                  cuddShrinkSubtable() +
                  Shrinks a subtable. + +
                  cuddInsertSubtables() +
                  Inserts n new subtables in a unique table at level. + +
                  cuddDestroySubtables() +
                  Destroys the n most recently created subtables in a unique table. + +
                  cuddResizeTableZdd() +
                  Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index. + +
                  cuddSlowTableGrowth() +
                  Adjusts parameters of a table to slow down its growth. + +
                  ddRehashZdd() +
                  Rehashes a ZDD unique subtable. + +
                  ddResizeTable() +
                  Increases the number of subtables in a unique table so + that it meets or exceeds index. + +
                  cuddFindParent() +
                  Searches the subtables above node for a parent. + +
                  () +
                  Adjusts the values of table limits. + +
                  cuddOrderedInsert() +
                  Inserts a DdNode in a red/black search tree. + +
                  cuddOrderedThread() +
                  Threads all the nodes of a search tree into a linear list. + +
                  () +
                  Performs the left rotation for red/black trees. + +
                  () +
                  Performs the right rotation for red/black trees. + +
                  cuddDoRebalance() +
                  Rebalances a red/black tree. + +
                  ddPatchTree() +
                  Fixes a variable tree after the insertion of new subtables. + +
                  cuddCheckCollisionOrdering() +
                  Checks whether a collision list is ordered. + +
                  ddReportRefMess() +
                  Reports problem in garbage collection. + +
                  +
                  +

                  cuddUtil.c

                  +Utility functions.

                  +By: Fabio Somenzi

                  +External procedures included in this module: +

                    +
                  • Cudd_PrintMinterm() +
                  • Cudd_bddPrintCover() +
                  • Cudd_PrintDebug() +
                  • Cudd_DagSize() +
                  • Cudd_EstimateCofactor() +
                  • Cudd_EstimateCofactorSimple() +
                  • Cudd_SharingSize() +
                  • Cudd_CountMinterm() +
                  • Cudd_EpdCountMinterm() +
                  • Cudd_CountPath() +
                  • Cudd_CountPathsToNonZero() +
                  • Cudd_SupportIndices() +
                  • Cudd_Support() +
                  • Cudd_SupportIndex() +
                  • Cudd_SupportSize() +
                  • Cudd_VectorSupportIndices() +
                  • Cudd_VectorSupport() +
                  • Cudd_VectorSupportIndex() +
                  • Cudd_VectorSupportSize() +
                  • Cudd_ClassifySupport() +
                  • Cudd_CountLeaves() +
                  • Cudd_bddPickOneCube() +
                  • Cudd_bddPickOneMinterm() +
                  • Cudd_bddPickArbitraryMinterms() +
                  • Cudd_SubsetWithMaskVars() +
                  • Cudd_FirstCube() +
                  • Cudd_NextCube() +
                  • Cudd_bddComputeCube() +
                  • Cudd_addComputeCube() +
                  • Cudd_FirstNode() +
                  • Cudd_NextNode() +
                  • Cudd_GenFree() +
                  • Cudd_IsGenEmpty() +
                  • Cudd_IndicesToCube() +
                  • Cudd_PrintVersion() +
                  • Cudd_AverageDistance() +
                  • Cudd_Random() +
                  • Cudd_Srandom() +
                  • Cudd_Density() +
                  + Internal procedures included in this module: +
                    +
                  • cuddP() +
                  • cuddStCountfree() +
                  • cuddCollectNodes() +
                  • cuddNodeArray() +
                  + Static procedures included in this module: +
                    +
                  • dp2() +
                  • ddPrintMintermAux() +
                  • ddDagInt() +
                  • ddCountMintermAux() +
                  • ddEpdCountMintermAux() +
                  • ddCountPathAux() +
                  • ddSupportStep() +
                  • ddClearFlag() +
                  • ddLeavesInt() +
                  • ddPickArbitraryMinterms() +
                  • ddPickRepresentativeCube() +
                  • ddEpdFree() +
                  • ddFindSupport() +
                  • ddClearVars() +
                  • indexCompare() +

                  +

                  +
                  Cudd_PrintMinterm() +
                  Prints a disjoint sum of products. + +
                  Cudd_bddPrintCover() +
                  Prints a sum of prime implicants of a BDD. + +
                  Cudd_PrintDebug() +
                  Prints to the standard output a DD and its statistics. + +
                  Cudd_DagSize() +
                  Counts the number of nodes in a DD. + +
                  Cudd_EstimateCofactor() +
                  Estimates the number of nodes in a cofactor of a DD. + +
                  Cudd_EstimateCofactorSimple() +
                  Estimates the number of nodes in a cofactor of a DD. + +
                  Cudd_SharingSize() +
                  Counts the number of nodes in an array of DDs. + +
                  Cudd_CountMinterm() +
                  Counts the number of minterms of a DD. + +
                  Cudd_CountPath() +
                  Counts the number of paths of a DD. + +
                  Cudd_EpdCountMinterm() +
                  Counts the number of minterms of a DD with extended precision. + +
                  Cudd_CountPathsToNonZero() +
                  Counts the number of paths to a non-zero terminal of a DD. + +
                  Cudd_SupportIndices() +
                  Finds the variables on which a DD depends. + +
                  Cudd_Support() +
                  Finds the variables on which a DD depends. + +
                  Cudd_SupportIndex() +
                  Finds the variables on which a DD depends. + +
                  Cudd_SupportSize() +
                  Counts the variables on which a DD depends. + +
                  Cudd_VectorSupportIndices() +
                  Finds the variables on which a set of DDs depends. + +
                  Cudd_VectorSupport() +
                  Finds the variables on which a set of DDs depends. + +
                  Cudd_VectorSupportIndex() +
                  Finds the variables on which a set of DDs depends. + +
                  Cudd_VectorSupportSize() +
                  Counts the variables on which a set of DDs depends. + +
                  Cudd_ClassifySupport() +
                  Classifies the variables in the support of two DDs. + +
                  Cudd_CountLeaves() +
                  Counts the number of leaves in a DD. + +
                  Cudd_bddPickOneCube() +
                  Picks one on-set cube randomly from the given DD. + +
                  Cudd_bddPickOneMinterm() +
                  Picks one on-set minterm randomly from the given DD. + +
                  Cudd_bddPickArbitraryMinterms() +
                  Picks k on-set minterms evenly distributed from given DD. + +
                  Cudd_SubsetWithMaskVars() +
                  Extracts a subset from a BDD. + +
                  Cudd_FirstCube() +
                  Finds the first cube of a decision diagram. + +
                  Cudd_NextCube() +
                  Generates the next cube of a decision diagram onset. + +
                  Cudd_FirstPrime() +
                  Finds the first prime of a Boolean function. + +
                  Cudd_NextPrime() +
                  Generates the next prime of a Boolean function. + +
                  Cudd_bddComputeCube() +
                  Computes the cube of an array of BDD variables. + +
                  Cudd_addComputeCube() +
                  Computes the cube of an array of ADD variables. + +
                  Cudd_CubeArrayToBdd() +
                  Builds the BDD of a cube from a positional array. + +
                  Cudd_BddToCubeArray() +
                  Builds a positional array from the BDD of a cube. + +
                  Cudd_FirstNode() +
                  Finds the first node of a decision diagram. + +
                  Cudd_NextNode() +
                  Finds the next node of a decision diagram. + +
                  Cudd_GenFree() +
                  Frees a CUDD generator. + +
                  Cudd_IsGenEmpty() +
                  Queries the status of a generator. + +
                  Cudd_IndicesToCube() +
                  Builds a cube of BDD variables from an array of indices. + +
                  Cudd_PrintVersion() +
                  Prints the package version number. + +
                  Cudd_AverageDistance() +
                  Computes the average distance between adjacent nodes. + +
                  Cudd_Random() +
                  Portable random number generator. + +
                  Cudd_Srandom() +
                  Initializer for the portable random number generator. + +
                  Cudd_Density() +
                  Computes the density of a BDD or ADD. + +
                  Cudd_OutOfMem() +
                  Warns that a memory allocation failed. + +
                  cuddP() +
                  Prints a DD to the standard output. One line per node is + printed. + +
                  cuddStCountfree() +
                  Frees the memory used to store the minterm counts recorded + in the visited table. + +
                  cuddCollectNodes() +
                  Recursively collects all the nodes of a DD in a symbol + table. + +
                  cuddNodeArray() +
                  Recursively collects all the nodes of a DD in an array. + +
                  dp2() +
                  Performs the recursive step of cuddP. + +
                  ddPrintMintermAux() +
                  Performs the recursive step of Cudd_PrintMinterm. + +
                  ddDagInt() +
                  Performs the recursive step of Cudd_DagSize. + +
                  cuddNodeArrayRecur() +
                  Performs the recursive step of cuddNodeArray. + +
                  cuddEstimateCofactor() +
                  Performs the recursive step of Cudd_CofactorEstimate. + +
                  cuddUniqueLookup() +
                  Checks the unique table for the existence of an internal node. + +
                  cuddEstimateCofactorSimple() +
                  Performs the recursive step of Cudd_CofactorEstimateSimple. + +
                  ddCountMintermAux() +
                  Performs the recursive step of Cudd_CountMinterm. + +
                  ddCountPathAux() +
                  Performs the recursive step of Cudd_CountPath. + +
                  ddEpdCountMintermAux() +
                  Performs the recursive step of Cudd_EpdCountMinterm. + +
                  ddCountPathsToNonZero() +
                  Performs the recursive step of Cudd_CountPathsToNonZero. + +
                  ddSupportStep() +
                  Performs the recursive step of Cudd_Support. + +
                  ddClearFlag() +
                  Performs a DFS from f, clearing the LSB of the next + pointers. + +
                  ddLeavesInt() +
                  Performs the recursive step of Cudd_CountLeaves. + +
                  ddPickArbitraryMinterms() +
                  Performs the recursive step of Cudd_bddPickArbitraryMinterms. + +
                  ddPickRepresentativeCube() +
                  Finds a representative cube of a BDD. + +
                  ddEpdFree() +
                  Frees the memory used to store the minterm counts recorded + in the visited table. + +
                  ddFindSupport() +
                  Recursively find the support of f. + +
                  ddClearVars() +
                  Clears visited flags for variables. + +
                  indexCompare() +
                  Compares indices for qsort. + +
                  +
                  +

                  cuddWindow.c

                  +Functions for variable reordering by window permutation.

                  +By: Fabio Somenzi

                  +Internal procedures included in this module: +

                    +
                  • cuddWindowReorder() +
                  + Static procedures included in this module: +
                    +
                  • ddWindow2() +
                  • ddWindowConv2() +
                  • ddPermuteWindow3() +
                  • ddWindow3() +
                  • ddWindowConv3() +
                  • ddPermuteWindow4() +
                  • ddWindow4() +
                  • ddWindowConv4() +

                  +

                  +
                  cuddWindowReorder() +
                  Reorders by applying the method of the sliding window. + +
                  ddWindow2() +
                  Reorders by applying a sliding window of width 2. + +
                  ddWindowConv2() +
                  Reorders by repeatedly applying a sliding window of width 2. + +
                  ddPermuteWindow3() +
                  Tries all the permutations of the three variables between + x and x+2 and retains the best. + +
                  ddWindow3() +
                  Reorders by applying a sliding window of width 3. + +
                  ddWindowConv3() +
                  Reorders by repeatedly applying a sliding window of width 3. + +
                  ddPermuteWindow4() +
                  Tries all the permutations of the four variables between w + and w+3 and retains the best. + +
                  ddWindow4() +
                  Reorders by applying a sliding window of width 4. + +
                  ddWindowConv4() +
                  Reorders by repeatedly applying a sliding window of width 4. + +
                  +
                  +

                  cuddZddCount.c

                  +Procedures to count the number of minterms of a ZDD.

                  +By: Hyong-Kyoon Shin, In-Ho Moon

                  +External procedures included in this module: +

                    +
                  • Cudd_zddCount(); +
                  • Cudd_zddCountDouble(); +
                  + Internal procedures included in this module: +
                    +
                  + Static procedures included in this module: +
                    +
                  • cuddZddCountStep(); +
                  • cuddZddCountDoubleStep(); +
                  • st_zdd_count_dbl_free() +
                  • st_zdd_countfree() +

                  +

                  +
                  Cudd_zddCount() +
                  Counts the number of minterms in a ZDD. + +
                  Cudd_zddCountDouble() +
                  Counts the number of minterms of a ZDD. + +
                  cuddZddCountStep() +
                  Performs the recursive step of Cudd_zddCount. + +
                  cuddZddCountDoubleStep() +
                  Performs the recursive step of Cudd_zddCountDouble. + +
                  st_zdd_countfree() +
                  Frees the memory associated with the computed table of + Cudd_zddCount. + +
                  st_zdd_count_dbl_free() +
                  Frees the memory associated with the computed table of + Cudd_zddCountDouble. + +
                  +
                  +

                  cuddZddFuncs.c

                  +Functions to manipulate covers represented as ZDDs.

                  +By: In-Ho Moon

                  +External procedures included in this module: +

                    +
                  • Cudd_zddProduct(); +
                  • Cudd_zddUnateProduct(); +
                  • Cudd_zddWeakDiv(); +
                  • Cudd_zddWeakDivF(); +
                  • Cudd_zddDivide(); +
                  • Cudd_zddDivideF(); +
                  • Cudd_zddComplement(); +
                  + Internal procedures included in this module: +
                    +
                  • cuddZddProduct(); +
                  • cuddZddUnateProduct(); +
                  • cuddZddWeakDiv(); +
                  • cuddZddWeakDivF(); +
                  • cuddZddDivide(); +
                  • cuddZddDivideF(); +
                  • cuddZddGetCofactors3() +
                  • cuddZddGetCofactors2() +
                  • cuddZddComplement(); +
                  • cuddZddGetPosVarIndex(); +
                  • cuddZddGetNegVarIndex(); +
                  • cuddZddGetPosVarLevel(); +
                  • cuddZddGetNegVarLevel(); +
                  + Static procedures included in this module: +
                    +

                  +

                  +
                  Cudd_zddProduct() +
                  Computes the product of two covers represented by ZDDs. + +
                  Cudd_zddUnateProduct() +
                  Computes the product of two unate covers. + +
                  Cudd_zddWeakDiv() +
                  Applies weak division to two covers. + +
                  Cudd_zddDivide() +
                  Computes the quotient of two unate covers. + +
                  Cudd_zddWeakDivF() +
                  Modified version of Cudd_zddWeakDiv. + +
                  Cudd_zddDivideF() +
                  Modified version of Cudd_zddDivide. + +
                  Cudd_zddComplement() +
                  Computes a complement cover for a ZDD node. + +
                  cuddZddProduct() +
                  Performs the recursive step of Cudd_zddProduct. + +
                  cuddZddUnateProduct() +
                  Performs the recursive step of Cudd_zddUnateProduct. + +
                  cuddZddWeakDiv() +
                  Performs the recursive step of Cudd_zddWeakDiv. + +
                  cuddZddWeakDivF() +
                  Performs the recursive step of Cudd_zddWeakDivF. + +
                  cuddZddDivide() +
                  Performs the recursive step of Cudd_zddDivide. + +
                  cuddZddDivideF() +
                  Performs the recursive step of Cudd_zddDivideF. + +
                  cuddZddGetCofactors3() +
                  Computes the three-way decomposition of f w.r.t. v. + +
                  cuddZddGetCofactors2() +
                  Computes the two-way decomposition of f w.r.t. v. + +
                  cuddZddComplement() +
                  Computes a complement of a ZDD node. + +
                  cuddZddGetPosVarIndex() +
                  Returns the index of positive ZDD variable. + +
                  cuddZddGetNegVarIndex() +
                  Returns the index of negative ZDD variable. + +
                  cuddZddGetPosVarLevel() +
                  Returns the level of positive ZDD variable. + +
                  cuddZddGetNegVarLevel() +
                  Returns the level of negative ZDD variable. + +
                  +
                  +

                  cuddZddGroup.c

                  +Functions for ZDD group sifting.

                  +By: Fabio Somenzi

                  +External procedures included in this file: +

                    +
                  • Cudd_MakeZddTreeNode() +
                  + Internal procedures included in this file: +
                    +
                  • cuddZddTreeSifting() +
                  + Static procedures included in this module: +
                    +
                  • zddTreeSiftingAux() +
                  • zddCountInternalMtrNodes() +
                  • zddReorderChildren() +
                  • zddFindNodeHiLo() +
                  • zddUniqueCompareGroup() +
                  • zddGroupSifting() +
                  • zddGroupSiftingAux() +
                  • zddGroupSiftingUp() +
                  • zddGroupSiftingDown() +
                  • zddGroupMove() +
                  • zddGroupMoveBackward() +
                  • zddGroupSiftingBackward() +
                  • zddMergeGroups() +

                  +

                  +
                  Cudd_MakeZddTreeNode() +
                  Creates a new ZDD variable group. + +
                  cuddZddTreeSifting() +
                  Tree sifting algorithm for ZDDs. + +
                  zddTreeSiftingAux() +
                  Visits the group tree and reorders each group. + +
                  zddCountInternalMtrNodes() +
                  Counts the number of internal nodes of the group tree. + +
                  zddReorderChildren() +
                  Reorders the children of a group tree node according to + the options. + +
                  zddFindNodeHiLo() +
                  Finds the lower and upper bounds of the group represented + by treenode. + +
                  zddUniqueCompareGroup() +
                  Comparison function used by qsort. + +
                  zddGroupSifting() +
                  Sifts from treenode->low to treenode->high. + +
                  zddGroupSiftingAux() +
                  Sifts one variable up and down until it has taken all + positions. Checks for aggregation. + +
                  zddGroupSiftingUp() +
                  Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much. + +
                  zddGroupSiftingDown() +
                  Sifts down a variable until it reaches position xHigh. + +
                  zddGroupMove() +
                  Swaps two groups and records the move. + +
                  zddGroupMoveBackward() +
                  Undoes the swap two groups. + +
                  zddGroupSiftingBackward() +
                  Determines the best position for a variables and returns + it there. + +
                  zddMergeGroups() +
                  Merges groups in the DD table. + +
                  +
                  +

                  cuddZddIsop.c

                  +Functions to find irredundant SOP covers as ZDDs from BDDs.

                  +By: In-Ho Moon

                  +External procedures included in this module: +

                    +
                  • Cudd_bddIsop() +
                  • Cudd_zddIsop() +
                  • Cudd_MakeBddFromZddCover() +
                  + Internal procedures included in this module: +
                    +
                  • cuddBddIsop() +
                  • cuddZddIsop() +
                  • cuddMakeBddFromZddCover() +
                  + Static procedures included in this module: +
                    +

                  +

                  +
                  Cudd_zddIsop() +
                  Computes an ISOP in ZDD form from BDDs. + +
                  Cudd_bddIsop() +
                  Computes a BDD in the interval between L and U with a + simple sum-of-product cover. + +
                  Cudd_MakeBddFromZddCover() +
                  Converts a ZDD cover to a BDD. + +
                  cuddZddIsop() +
                  Performs the recursive step of Cudd_zddIsop. + +
                  cuddBddIsop() +
                  Performs the recursive step of Cudd_bddIsop. + +
                  cuddMakeBddFromZddCover() +
                  Converts a ZDD cover to a BDD. + +
                  +
                  +

                  cuddZddLin.c

                  +Procedures for dynamic variable ordering of ZDDs.

                  +By: Fabio Somenzi

                  +Internal procedures included in this module: +

                    +
                  • cuddZddLinearSifting() +
                  + Static procedures included in this module: +
                    +
                  • cuddZddLinearInPlace() +
                  • cuddZddLinerAux() +
                  • cuddZddLinearUp() +
                  • cuddZddLinearDown() +
                  • cuddZddLinearBackward() +
                  • cuddZddUndoMoves() +

                  +

                  See AlsocuddLinear.c +cuddZddReord.c +

                  +
                  cuddZddLinearSifting() +
                  Implementation of the linear sifting algorithm for ZDDs. + +
                  cuddZddLinearInPlace() +
                  Linearly combines two adjacent variables. + +
                  cuddZddLinearAux() +
                  Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                  cuddZddLinearUp() +
                  Sifts a variable up applying the XOR transformation. + +
                  cuddZddLinearDown() +
                  Sifts a variable down and applies the XOR transformation. + +
                  cuddZddLinearBackward() +
                  Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
                  cuddZddUndoMoves() +
                  Given a set of moves, returns the ZDD heap to the order + in effect before the moves. + +
                  +
                  +

                  cuddZddMisc.c

                  +Miscellaneous utility functions for ZDDs.

                  +By: Hyong-Kyoon Shin, In-Ho Moon

                  +External procedures included in this module: +

                    +
                  • Cudd_zddDagSize() +
                  • Cudd_zddCountMinterm() +
                  • Cudd_zddPrintSubtable() +
                  + Internal procedures included in this module: +
                    +
                  + Static procedures included in this module: +
                    +
                  • cuddZddDagInt() +

                  +

                  +
                  Cudd_zddDagSize() +
                  Counts the number of nodes in a ZDD. + +
                  Cudd_zddCountMinterm() +
                  Counts the number of minterms of a ZDD. + +
                  Cudd_zddPrintSubtable() +
                  Prints the ZDD table. + +
                  cuddZddDagInt() +
                  Performs the recursive step of Cudd_zddDagSize. + +
                  +
                  +

                  cuddZddPort.c

                  +Functions that translate BDDs to ZDDs.

                  +By: Hyong-kyoon Shin, In-Ho Moon

                  +External procedures included in this module: +

                    +
                  • Cudd_zddPortFromBdd() +
                  • Cudd_zddPortToBdd() +
                  + Internal procedures included in this module: +
                    +
                  + Static procedures included in this module: +
                    +
                  • zddPortFromBddStep() +
                  • zddPortToBddStep() +

                  +

                  +
                  Cudd_zddPortFromBdd() +
                  Converts a BDD into a ZDD. + +
                  Cudd_zddPortToBdd() +
                  Converts a ZDD into a BDD. + +
                  zddPortFromBddStep() +
                  Performs the recursive step of Cudd_zddPortFromBdd. + +
                  zddPortToBddStep() +
                  Performs the recursive step of Cudd_zddPortToBdd. + +
                  +
                  +

                  cuddZddReord.c

                  +Procedures for dynamic variable ordering of ZDDs.

                  +By: Hyong-Kyoon Shin, In-Ho Moon

                  +External procedures included in this module: +

                    +
                  • Cudd_zddReduceHeap() +
                  • Cudd_zddShuffleHeap() +
                  + Internal procedures included in this module: +
                    +
                  • cuddZddAlignToBdd() +
                  • cuddZddNextHigh() +
                  • cuddZddNextLow() +
                  • cuddZddUniqueCompare() +
                  • cuddZddSwapInPlace() +
                  • cuddZddSwapping() +
                  • cuddZddSifting() +
                  + Static procedures included in this module: +
                    +
                  • zddSwapAny() +
                  • cuddZddSiftingAux() +
                  • cuddZddSiftingUp() +
                  • cuddZddSiftingDown() +
                  • cuddZddSiftingBackward() +
                  • zddReorderPreprocess() +
                  • zddReorderPostprocess() +
                  • zddShuffle() +
                  • zddSiftUp() +

                  +

                  +
                  Cudd_zddReduceHeap() +
                  Main dynamic reordering routine for ZDDs. + +
                  Cudd_zddShuffleHeap() +
                  Reorders ZDD variables according to given permutation. + +
                  cuddZddAlignToBdd() +
                  Reorders ZDD variables according to the order of the BDD + variables. + +
                  cuddZddNextHigh() +
                  Finds the next subtable with a larger index. + +
                  cuddZddNextLow() +
                  Finds the next subtable with a smaller index. + +
                  cuddZddUniqueCompare() +
                  Comparison function used by qsort. + +
                  cuddZddSwapInPlace() +
                  Swaps two adjacent variables. + +
                  cuddZddSwapping() +
                  Reorders variables by a sequence of (non-adjacent) swaps. + +
                  cuddZddSifting() +
                  Implementation of Rudell's sifting algorithm. + +
                  zddSwapAny() +
                  Swaps any two variables. + +
                  cuddZddSiftingAux() +
                  Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                  cuddZddSiftingUp() +
                  Sifts a variable up. + +
                  cuddZddSiftingDown() +
                  Sifts a variable down. + +
                  cuddZddSiftingBackward() +
                  Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
                  zddReorderPreprocess() +
                  Prepares the ZDD heap for dynamic reordering. + +
                  zddReorderPostprocess() +
                  Shrinks almost empty ZDD subtables at the end of reordering + to guarantee that they have a reasonable load factor. + +
                  zddShuffle() +
                  Reorders ZDD variables according to a given permutation. + +
                  zddSiftUp() +
                  Moves one ZDD variable up. + +
                  zddFixTree() +
                  Fixes the ZDD variable group tree after a shuffle. + +
                  +
                  +

                  cuddZddSetop.c

                  +Set operations on ZDDs.

                  +By: Hyong-Kyoon Shin, In-Ho Moon

                  +External procedures included in this module: +

                    +
                  • Cudd_zddIte() +
                  • Cudd_zddUnion() +
                  • Cudd_zddIntersect() +
                  • Cudd_zddDiff() +
                  • Cudd_zddDiffConst() +
                  • Cudd_zddSubset1() +
                  • Cudd_zddSubset0() +
                  • Cudd_zddChange() +
                  + Internal procedures included in this module: +
                    +
                  • cuddZddIte() +
                  • cuddZddUnion() +
                  • cuddZddIntersect() +
                  • cuddZddDiff() +
                  • cuddZddChangeAux() +
                  • cuddZddSubset1() +
                  • cuddZddSubset0() +
                  + Static procedures included in this module: +
                    +
                  • zdd_subset1_aux() +
                  • zdd_subset0_aux() +
                  • zddVarToConst() +

                  +

                  +
                  Cudd_zddIte() +
                  Computes the ITE of three ZDDs. + +
                  Cudd_zddUnion() +
                  Computes the union of two ZDDs. + +
                  Cudd_zddIntersect() +
                  Computes the intersection of two ZDDs. + +
                  Cudd_zddDiff() +
                  Computes the difference of two ZDDs. + +
                  Cudd_zddDiffConst() +
                  Performs the inclusion test for ZDDs (P implies Q). + +
                  Cudd_zddSubset1() +
                  Computes the positive cofactor of a ZDD w.r.t. a variable. + +
                  Cudd_zddSubset0() +
                  Computes the negative cofactor of a ZDD w.r.t. a variable. + +
                  Cudd_zddChange() +
                  Substitutes a variable with its complement in a ZDD. + +
                  cuddZddIte() +
                  Performs the recursive step of Cudd_zddIte. + +
                  cuddZddUnion() +
                  Performs the recursive step of Cudd_zddUnion. + +
                  cuddZddIntersect() +
                  Performs the recursive step of Cudd_zddIntersect. + +
                  cuddZddDiff() +
                  Performs the recursive step of Cudd_zddDiff. + +
                  cuddZddChangeAux() +
                  Performs the recursive step of Cudd_zddChange. + +
                  cuddZddSubset1() +
                  Computes the positive cofactor of a ZDD w.r.t. a variable. + +
                  cuddZddSubset0() +
                  Computes the negative cofactor of a ZDD w.r.t. a variable. + +
                  cuddZddChange() +
                  Substitutes a variable with its complement in a ZDD. + +
                  zdd_subset1_aux() +
                  Performs the recursive step of Cudd_zddSubset1. + +
                  zdd_subset0_aux() +
                  Performs the recursive step of Cudd_zddSubset0. + +
                  zddVarToConst() +
                  Replaces variables with constants if possible (part of + canonical form). + +
                  +
                  +

                  cuddZddSymm.c

                  +Functions for symmetry-based ZDD variable reordering.

                  +By: Hyong-Kyoon Shin, In-Ho Moon

                  +External procedures included in this module: +

                    +
                  • Cudd_zddSymmProfile() +
                  + Internal procedures included in this module: +
                    +
                  • cuddZddSymmCheck() +
                  • cuddZddSymmSifting() +
                  • cuddZddSymmSiftingConv() +
                  + Static procedures included in this module: +
                    +
                  • cuddZddUniqueCompare() +
                  • cuddZddSymmSiftingAux() +
                  • cuddZddSymmSiftingConvAux() +
                  • cuddZddSymmSifting_up() +
                  • cuddZddSymmSifting_down() +
                  • zdd_group_move() +
                  • cuddZddSymmSiftingBackward() +
                  • zdd_group_move_backward() +

                  +

                  See AlsocuddSymmetry.c +

                  +
                  Cudd_zddSymmProfile() +
                  Prints statistics on symmetric ZDD variables. + +
                  cuddZddSymmCheck() +
                  Checks for symmetry of x and y. + +
                  cuddZddSymmSifting() +
                  Symmetric sifting algorithm for ZDDs. + +
                  cuddZddSymmSiftingConv() +
                  Symmetric sifting to convergence algorithm for ZDDs. + +
                  cuddZddSymmSiftingAux() +
                  Given x_low <= x <= x_high moves x up and down between the + boundaries. + +
                  cuddZddSymmSiftingConvAux() +
                  Given x_low <= x <= x_high moves x up and down between the + boundaries. + +
                  cuddZddSymmSifting_up() +
                  Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much. + +
                  cuddZddSymmSifting_down() +
                  Moves x down until either it reaches the bound (x_high) or + the size of the ZDD heap increases too much. + +
                  cuddZddSymmSiftingBackward() +
                  Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
                  zdd_group_move() +
                  Swaps two groups. + +
                  zdd_group_move_backward() +
                  Undoes the swap of two groups. + +
                  cuddZddSymmSummary() +
                  Counts numbers of symmetric variables and symmetry + groups. + +
                  +
                  +

                  cuddZddUtil.c

                  +Utility functions for ZDDs.

                  +By: Hyong-Kyoon Shin, In-Ho Moon, Fabio Somenzi

                  +External procedures included in this module: +

                    +
                  • Cudd_zddPrintMinterm() +
                  • Cudd_zddPrintCover() +
                  • Cudd_zddPrintDebug() +
                  • Cudd_zddFirstPath() +
                  • Cudd_zddNextPath() +
                  • Cudd_zddCoverPathToString() +
                  • Cudd_zddSupport() +
                  • Cudd_zddDumpDot() +
                  + Internal procedures included in this module: +
                    +
                  • cuddZddP() +
                  + Static procedures included in this module: +
                    +
                  • zp2() +
                  • zdd_print_minterm_aux() +
                  • zddPrintCoverAux() +
                  • zddSupportStep() +
                  • zddClearFlag() +

                  +

                  +
                  Cudd_zddPrintMinterm() +
                  Prints a disjoint sum of product form for a ZDD. + +
                  Cudd_zddPrintCover() +
                  Prints a sum of products from a ZDD representing a cover. + +
                  Cudd_zddPrintDebug() +
                  Prints to the standard output a ZDD and its statistics. + +
                  Cudd_zddFirstPath() +
                  Finds the first path of a ZDD. + +
                  Cudd_zddNextPath() +
                  Generates the next path of a ZDD. + +
                  Cudd_zddCoverPathToString() +
                  Converts a path of a ZDD representing a cover to a string. + +
                  Cudd_zddSupport() +
                  Finds the variables on which a ZDD depends. + +
                  Cudd_zddDumpDot() +
                  Writes a dot file representing the argument ZDDs. + +
                  cuddZddP() +
                  Prints a ZDD to the standard output. One line per node is + printed. + +
                  zp2() +
                  Performs the recursive step of cuddZddP. + +
                  zdd_print_minterm_aux() +
                  Performs the recursive step of Cudd_zddPrintMinterm. + +
                  zddPrintCoverAux() +
                  Performs the recursive step of Cudd_zddPrintCover. + +
                  zddSupportStep() +
                  Performs the recursive step of Cudd_zddSupport. + +
                  zddClearFlag() +
                  Performs a DFS from f, clearing the LSB of the next + pointers. + +
                  +
                  +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddDesc.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddDesc.html new file mode 100644 index 000000000..5f27bf530 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddDesc.html @@ -0,0 +1,33 @@ + +The cudd package: Overview + + +

                  The cudd package

                  +

                  The University of Colorado decision diagram package.

                  +

                  By Fabio Somenzi

                  + + + +
                  + +External functions and data strucures of the CUDD package. +
                    +
                  • To turn on the gathering of statistics, define DD_STATS. +
                  • To link with mis, define DD_MIS. +
                  + Modified by Abelardo Pardo to interface it to VIS. + +
                  + +Last updated on 20120204 17h33 + + + +writing ./cuddExt.html diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExt.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExt.html new file mode 100644 index 000000000..24b63634a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExt.html @@ -0,0 +1,14 @@ + +The cudd Package for Programmers + + + + + + + + + + + +writing ./cuddAllByFunc.html diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtAbs.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtAbs.html new file mode 100644 index 000000000..a476db7b1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtAbs.html @@ -0,0 +1,1415 @@ + +cudd package abstract + + + + + +
                  +
                  Cudd_AddHook() +
                  Adds a function to a hook. + +
                  Cudd_ApaAdd() +
                  Adds two arbitrary precision integers. + +
                  Cudd_ApaCompareRatios() +
                  Compares the ratios of two arbitrary precision integers to two + unsigned ints. + +
                  Cudd_ApaCompare() +
                  Compares two arbitrary precision integers. + +
                  Cudd_ApaCopy() +
                  Makes a copy of an arbitrary precision integer. + +
                  Cudd_ApaCountMinterm() +
                  Counts the number of minterms of a DD. + +
                  Cudd_ApaIntDivision() +
                  Divides an arbitrary precision integer by an integer. + +
                  Cudd_ApaNumberOfDigits() +
                  Finds the number of digits for an arbitrary precision + integer. + +
                  Cudd_ApaPowerOfTwo() +
                  Sets an arbitrary precision integer to a power of two. + +
                  Cudd_ApaPrintDecimal() +
                  Prints an arbitrary precision integer in decimal format. + +
                  Cudd_ApaPrintDensity() +
                  Prints the density of a BDD or ADD using + arbitrary precision arithmetic. + +
                  Cudd_ApaPrintExponential() +
                  Prints an arbitrary precision integer in exponential format. + +
                  Cudd_ApaPrintHex() +
                  Prints an arbitrary precision integer in hexadecimal format. + +
                  Cudd_ApaPrintMintermExp() +
                  Prints the number of minterms of a BDD or ADD in exponential + format using arbitrary precision arithmetic. + +
                  Cudd_ApaPrintMinterm() +
                  Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic. + +
                  Cudd_ApaSetToLiteral() +
                  Sets an arbitrary precision integer to a one-digit literal. + +
                  Cudd_ApaShiftRight() +
                  Shifts right an arbitrary precision integer by one binary + place. + +
                  Cudd_ApaShortDivision() +
                  Divides an arbitrary precision integer by a digit. + +
                  Cudd_ApaSubtract() +
                  Subtracts two arbitrary precision integers. + +
                  Cudd_AutodynDisableZdd() +
                  Disables automatic dynamic reordering of ZDDs. + +
                  Cudd_AutodynDisable() +
                  Disables automatic dynamic reordering. + +
                  Cudd_AutodynEnableZdd() +
                  Enables automatic dynamic reordering of ZDDs. + +
                  Cudd_AutodynEnable() +
                  Enables automatic dynamic reordering of BDDs and ADDs. + +
                  Cudd_AverageDistance() +
                  Computes the average distance between adjacent nodes. + +
                  Cudd_BddToAdd() +
                  Converts a BDD to a 0-1 ADD. + +
                  Cudd_BddToCubeArray() +
                  Builds a positional array from the BDD of a cube. + +
                  Cudd_BiasedOverApprox() +
                  Extracts a dense superset from a BDD with the biased + underapproximation method. + +
                  Cudd_BiasedUnderApprox() +
                  Extracts a dense subset from a BDD with the biased + underapproximation method. + +
                  Cudd_CProjection() +
                  Computes the compatible projection of R w.r.t. cube Y. + +
                  Cudd_CheckCube() +
                  Checks whether g is the BDD of a cube. + +
                  Cudd_CheckKeys() +
                  Checks for several conditions that should not occur. + +
                  Cudd_CheckZeroRef() +
                  Checks the unique table for nodes with non-zero reference + counts. + +
                  Cudd_ClassifySupport() +
                  Classifies the variables in the support of two DDs. + +
                  Cudd_ClearErrorCode() +
                  Clear the error code of a manager. + +
                  Cudd_CofMinterm() +
                  Computes the fraction of minterms in the on-set of all the + positive cofactors of a BDD or ADD. + +
                  Cudd_Cofactor() +
                  Computes the cofactor of f with respect to g. + +
                  Cudd_CountLeaves() +
                  Counts the number of leaves in a DD. + +
                  Cudd_CountMinterm() +
                  Counts the number of minterms of a DD. + +
                  Cudd_CountPathsToNonZero() +
                  Counts the number of paths to a non-zero terminal of a DD. + +
                  Cudd_CountPath() +
                  Counts the number of paths of a DD. + +
                  Cudd_CubeArrayToBdd() +
                  Builds the BDD of a cube from a positional array. + +
                  Cudd_DagSize() +
                  Counts the number of nodes in a DD. + +
                  Cudd_DeadAreCounted() +
                  Tells whether dead nodes are counted towards triggering + reordering. + +
                  Cudd_DebugCheck() +
                  Checks for inconsistencies in the DD heap. + +
                  Cudd_Decreasing() +
                  Determines whether a BDD is negative unate in a + variable. + +
                  Cudd_DelayedDerefBdd() +
                  Decreases the reference count of BDD node n. + +
                  Cudd_Density() +
                  Computes the density of a BDD or ADD. + +
                  Cudd_Deref() +
                  Decreases the reference count of node. + +
                  Cudd_DisableGarbageCollection() +
                  Disables garbage collection. + +
                  Cudd_DisableOrderingMonitoring() +
                  Disables monitoring of ordering. + +
                  Cudd_DisableReorderingReporting() +
                  Disables reporting of reordering stats. + +
                  Cudd_Disequality() +
                  Generates a BDD for the function x - y != c. + +
                  Cudd_DumpBlifBody() +
                  Writes a blif body representing the argument BDDs. + +
                  Cudd_DumpBlif() +
                  Writes a blif file representing the argument BDDs. + +
                  Cudd_DumpDDcal() +
                  Writes a DDcal file representing the argument BDDs. + +
                  Cudd_DumpDaVinci() +
                  Writes a daVinci file representing the argument BDDs. + +
                  Cudd_DumpDot() +
                  Writes a dot file representing the argument DDs. + +
                  Cudd_DumpFactoredForm() +
                  Writes factored forms representing the argument BDDs. + +
                  Cudd_Dxygtdxz() +
                  Generates a BDD for the function d(x,y) > d(x,z). + +
                  Cudd_Dxygtdyz() +
                  Generates a BDD for the function d(x,y) > d(y,z). + +
                  Cudd_EnableGarbageCollection() +
                  Enables garbage collection. + +
                  Cudd_EnableOrderingMonitoring() +
                  Enables monitoring of ordering. + +
                  Cudd_EnableReorderingReporting() +
                  Enables reporting of reordering stats. + +
                  Cudd_EpdCountMinterm() +
                  Counts the number of minterms of a DD with extended precision. + +
                  Cudd_EqualSupNorm() +
                  Compares two ADDs for equality within tolerance. + +
                  Cudd_EquivDC() +
                  Tells whether F and G are identical wherever D is 0. + +
                  Cudd_EstimateCofactorSimple() +
                  Estimates the number of nodes in a cofactor of a DD. + +
                  Cudd_EstimateCofactor() +
                  Estimates the number of nodes in a cofactor of a DD. + +
                  Cudd_Eval() +
                  Returns the value of a DD for a given variable assignment. + +
                  Cudd_ExpectedUsedSlots() +
                  Computes the expected fraction of used slots in the unique + table. + +
                  Cudd_FindEssential() +
                  Finds the essential variables of a DD. + +
                  Cudd_FindTwoLiteralClauses() +
                  Finds the two literal clauses of a DD. + +
                  Cudd_FirstCube() +
                  Finds the first cube of a decision diagram. + +
                  Cudd_FirstNode() +
                  Finds the first node of a decision diagram. + +
                  Cudd_FirstPrime() +
                  Finds the first prime of a Boolean function. + +
                  Cudd_FreeTree() +
                  Frees the variable group tree of the manager. + +
                  Cudd_FreeZddTree() +
                  Frees the variable group tree of the manager. + +
                  Cudd_GarbageCollectionEnabled() +
                  Tells whether garbage collection is enabled. + +
                  Cudd_GenFree() +
                  Frees a CUDD generator. + +
                  Cudd_IncreaseTimeLimit() +
                  Increases the time limit for the manager. + +
                  Cudd_Increasing() +
                  Determines whether a BDD is positive unate in a + variable. + +
                  Cudd_IndicesToCube() +
                  Builds a cube of BDD variables from an array of indices. + +
                  Cudd_Inequality() +
                  Generates a BDD for the function x - y ≥ c. + +
                  Cudd_Init() +
                  Creates a new DD manager. + +
                  Cudd_IsGenEmpty() +
                  Queries the status of a generator. + +
                  Cudd_IsInHook() +
                  Checks whether a function is in a hook. + +
                  Cudd_IsNonConstant() +
                  Returns 1 if a DD node is not constant. + +
                  Cudd_IterDerefBdd() +
                  Decreases the reference count of BDD node n. + +
                  Cudd_LargestCube() +
                  Finds a largest cube in a DD. + +
                  Cudd_MakeBddFromZddCover() +
                  Converts a ZDD cover to a BDD. + +
                  Cudd_MakeTreeNode() +
                  Creates a new variable group. + +
                  Cudd_MakeZddTreeNode() +
                  Creates a new ZDD variable group. + +
                  Cudd_MinHammingDist() +
                  Returns the minimum Hamming distance between f and minterm. + +
                  Cudd_NewApaNumber() +
                  Allocates memory for an arbitrary precision integer. + +
                  Cudd_NextCube() +
                  Generates the next cube of a decision diagram onset. + +
                  Cudd_NextNode() +
                  Finds the next node of a decision diagram. + +
                  Cudd_NextPrime() +
                  Generates the next prime of a Boolean function. + +
                  Cudd_NodeReadIndex() +
                  Returns the index of the node. + +
                  Cudd_OrderingMonitoring() +
                  Returns 1 if monitoring of ordering is enabled. + +
                  Cudd_OutOfMem() +
                  Warns that a memory allocation failed. + +
                  Cudd_OverApprox() +
                  Extracts a dense superset from a BDD with Shiple's + underapproximation method. + +
                  Cudd_Prime() +
                  Returns the next prime >= p. + +
                  Cudd_PrintDebug() +
                  Prints to the standard output a DD and its statistics. + +
                  Cudd_PrintGroupedOrder() +
                  Hook function to print the current variable order. + +
                  Cudd_PrintInfo() +
                  Prints out statistics and settings for a CUDD manager. + +
                  Cudd_PrintLinear() +
                  Prints the linear transform matrix. + +
                  Cudd_PrintMinterm() +
                  Prints a disjoint sum of products. + +
                  Cudd_PrintTwoLiteralClauses() +
                  Prints the two literal clauses of a DD. + +
                  Cudd_PrintVersion() +
                  Prints the package version number. + +
                  Cudd_PrioritySelect() +
                  Selects pairs from R using a priority function. + +
                  Cudd_Quit() +
                  Deletes resources associated with a DD manager. + +
                  Cudd_Random() +
                  Portable random number generator. + +
                  Cudd_ReadArcviolation() +
                  Returns the current value of the arcviolation parameter used + in group sifting. + +
                  Cudd_ReadBackground() +
                  Reads the background constant of the manager. + +
                  Cudd_ReadCacheHits() +
                  Returns the number of cache hits. + +
                  Cudd_ReadCacheLookUps() +
                  Returns the number of cache look-ups. + +
                  Cudd_ReadCacheSlots() +
                  Reads the number of slots in the cache. + +
                  Cudd_ReadCacheUsedSlots() +
                  Reads the fraction of used slots in the cache. + +
                  Cudd_ReadDead() +
                  Returns the number of dead nodes in the unique table. + +
                  Cudd_ReadElapsedTime() +
                  Returns the time elapsed since the start time of the manager. + +
                  Cudd_ReadEpsilon() +
                  Reads the epsilon parameter of the manager. + +
                  Cudd_ReadErrorCode() +
                  Returns the code of the last error. + +
                  Cudd_ReadGarbageCollectionTime() +
                  Returns the time spent in garbage collection. + +
                  Cudd_ReadGarbageCollections() +
                  Returns the number of times garbage collection has occurred. + +
                  Cudd_ReadGroupcheck() +
                  Reads the groupcheck parameter of the manager. + +
                  Cudd_ReadInvPermZdd() +
                  Returns the index of the ZDD variable currently in the i-th + position of the order. + +
                  Cudd_ReadInvPerm() +
                  Returns the index of the variable currently in the i-th + position of the order. + +
                  Cudd_ReadIthClause() +
                  Accesses the i-th clause of a DD. + +
                  Cudd_ReadKeys() +
                  Returns the number of nodes in the unique table. + +
                  Cudd_ReadLinear() +
                  Reads an entry of the linear transform matrix. + +
                  Cudd_ReadLogicZero() +
                  Returns the logic zero constant of the manager. + +
                  Cudd_ReadLooseUpTo() +
                  Reads the looseUpTo parameter of the manager. + +
                  Cudd_ReadMaxCacheHard() +
                  Reads the maxCacheHard parameter of the manager. + +
                  Cudd_ReadMaxCache() +
                  Returns the soft limit for the cache size. + +
                  Cudd_ReadMaxGrowthAlternate() +
                  Reads the maxGrowthAlt parameter of the manager. + +
                  Cudd_ReadMaxGrowth() +
                  Reads the maxGrowth parameter of the manager. + +
                  Cudd_ReadMaxLive() +
                  Reads the maximum allowed number of live nodes. + +
                  Cudd_ReadMaxMemory() +
                  Reads the maximum allowed memory. + +
                  Cudd_ReadMaxReorderings() +
                  Returns the maximum number of times reordering may be invoked. + +
                  Cudd_ReadMemoryInUse() +
                  Returns the memory in use by the manager measured in bytes. + +
                  Cudd_ReadMinDead() +
                  Reads the minDead parameter of the manager. + +
                  Cudd_ReadMinHit() +
                  Reads the hit rate that causes resizinig of the computed + table. + +
                  Cudd_ReadMinusInfinity() +
                  Reads the minus-infinity constant from the manager. + +
                  Cudd_ReadNextReordering() +
                  Returns the threshold for the next dynamic reordering. + +
                  Cudd_ReadNodeCount() +
                  Reports the number of nodes in BDDs and ADDs. + +
                  Cudd_ReadNodesDropped() +
                  Returns the number of nodes dropped. + +
                  Cudd_ReadNodesFreed() +
                  Returns the number of nodes freed. + +
                  Cudd_ReadNumberXovers() +
                  Reads the current number of crossovers used by the + genetic algorithm for reordering. + +
                  Cudd_ReadOne() +
                  Returns the one constant of the manager. + +
                  Cudd_ReadOrderRandomization() +
                  Returns the order randomization factor. + +
                  Cudd_ReadPeakLiveNodeCount() +
                  Reports the peak number of live nodes. + +
                  Cudd_ReadPeakNodeCount() +
                  Reports the peak number of nodes. + +
                  Cudd_ReadPermZdd() +
                  Returns the current position of the i-th ZDD variable in the + order. + +
                  Cudd_ReadPerm() +
                  Returns the current position of the i-th variable in the + order. + +
                  Cudd_ReadPlusInfinity() +
                  Reads the plus-infinity constant from the manager. + +
                  Cudd_ReadPopulationSize() +
                  Reads the current size of the population used by the + genetic algorithm for reordering. + +
                  Cudd_ReadRecomb() +
                  Returns the current value of the recombination parameter used + in group sifting. + +
                  Cudd_ReadRecursiveCalls() +
                  Returns the number of recursive calls. + +
                  Cudd_ReadReorderingCycle() +
                  Reads the reordCycle parameter of the manager. + +
                  Cudd_ReadReorderingTime() +
                  Returns the time spent in reordering. + +
                  Cudd_ReadReorderings() +
                  Returns the number of times reordering has occurred. + +
                  Cudd_ReadSiftMaxSwap() +
                  Reads the siftMaxSwap parameter of the manager. + +
                  Cudd_ReadSiftMaxVar() +
                  Reads the siftMaxVar parameter of the manager. + +
                  Cudd_ReadSize() +
                  Returns the number of BDD variables in existance. + +
                  Cudd_ReadSlots() +
                  Returns the total number of slots of the unique table. + +
                  Cudd_ReadStartTime() +
                  Returns the start time of the manager. + +
                  Cudd_ReadStderr() +
                  Reads the stderr of a manager. + +
                  Cudd_ReadStdout() +
                  Reads the stdout of a manager. + +
                  Cudd_ReadSwapSteps() +
                  Reads the number of elementary reordering steps. + +
                  Cudd_ReadSymmviolation() +
                  Returns the current value of the symmviolation parameter used + in group sifting. + +
                  Cudd_ReadTimeLimit() +
                  Returns the time limit for the manager. + +
                  Cudd_ReadTree() +
                  Returns the variable group tree of the manager. + +
                  Cudd_ReadUniqueLinks() +
                  Returns the number of links followed in the unique table. + +
                  Cudd_ReadUniqueLookUps() +
                  Returns the number of look-ups in the unique table. + +
                  Cudd_ReadUsedSlots() +
                  Reads the fraction of used slots in the unique table. + +
                  Cudd_ReadVars() +
                  Returns the i-th element of the vars array. + +
                  Cudd_ReadZddOne() +
                  Returns the ZDD for the constant 1 function. + +
                  Cudd_ReadZddSize() +
                  Returns the number of ZDD variables in existance. + +
                  Cudd_ReadZddTree() +
                  Returns the variable group tree of the manager. + +
                  Cudd_ReadZero() +
                  Returns the zero constant of the manager. + +
                  Cudd_RecursiveDerefZdd() +
                  Decreases the reference count of ZDD node n. + +
                  Cudd_RecursiveDeref() +
                  Decreases the reference count of node n. + +
                  Cudd_ReduceHeap() +
                  Main dynamic reordering routine. + +
                  Cudd_Ref() +
                  Increases the reference count of a node, if it is not + saturated. + +
                  Cudd_RemapOverApprox() +
                  Extracts a dense superset from a BDD with the remapping + underapproximation method. + +
                  Cudd_RemapUnderApprox() +
                  Extracts a dense subset from a BDD with the remapping + underapproximation method. + +
                  Cudd_RemoveHook() +
                  Removes a function from a hook. + +
                  Cudd_ReorderingReporting() +
                  Returns 1 if reporting of reordering stats is enabled. + +
                  Cudd_ReorderingStatusZdd() +
                  Reports the status of automatic dynamic reordering of ZDDs. + +
                  Cudd_ReorderingStatus() +
                  Reports the status of automatic dynamic reordering of BDDs + and ADDs. + +
                  Cudd_Reserve() +
                  Expand manager without creating variables. + +
                  Cudd_ResetStartTime() +
                  Resets the start time of the manager. + +
                  Cudd_SetArcviolation() +
                  Sets the value of the arcviolation parameter used + in group sifting. + +
                  Cudd_SetBackground() +
                  Sets the background constant of the manager. + +
                  Cudd_SetEpsilon() +
                  Sets the epsilon parameter of the manager to ep. + +
                  Cudd_SetGroupcheck() +
                  Sets the parameter groupcheck of the manager to gc. + +
                  Cudd_SetLooseUpTo() +
                  Sets the looseUpTo parameter of the manager. + +
                  Cudd_SetMaxCacheHard() +
                  Sets the maxCacheHard parameter of the manager. + +
                  Cudd_SetMaxGrowthAlternate() +
                  Sets the maxGrowthAlt parameter of the manager. + +
                  Cudd_SetMaxGrowth() +
                  Sets the maxGrowth parameter of the manager. + +
                  Cudd_SetMaxLive() +
                  Sets the maximum allowed number of live nodes. + +
                  Cudd_SetMaxMemory() +
                  Sets the maximum allowed memory. + +
                  Cudd_SetMaxReorderings() +
                  Sets the maximum number of times reordering may be invoked. + +
                  Cudd_SetMinHit() +
                  Sets the hit rate that causes resizinig of the computed + table. + +
                  Cudd_SetNextReordering() +
                  Sets the threshold for the next dynamic reordering. + +
                  Cudd_SetNumberXovers() +
                  Sets the number of crossovers used by the + genetic algorithm for reordering. + +
                  Cudd_SetOrderRandomization() +
                  Sets the order randomization factor. + +
                  Cudd_SetPopulationSize() +
                  Sets the size of the population used by the + genetic algorithm for reordering. + +
                  Cudd_SetRecomb() +
                  Sets the value of the recombination parameter used in group + sifting. + +
                  Cudd_SetReorderingCycle() +
                  Sets the reordCycle parameter of the manager. + +
                  Cudd_SetSiftMaxSwap() +
                  Sets the siftMaxSwap parameter of the manager. + +
                  Cudd_SetSiftMaxVar() +
                  Sets the siftMaxVar parameter of the manager. + +
                  Cudd_SetStartTime() +
                  Sets the start time of the manager. + +
                  Cudd_SetStderr() +
                  Sets the stderr of a manager. + +
                  Cudd_SetStdout() +
                  Sets the stdout of a manager. + +
                  Cudd_SetSymmviolation() +
                  Sets the value of the symmviolation parameter used + in group sifting. + +
                  Cudd_SetTimeLimit() +
                  Sets the time limit for the manager. + +
                  Cudd_SetTree() +
                  Sets the variable group tree of the manager. + +
                  Cudd_SetVarMap() +
                  Registers a variable mapping with the manager. + +
                  Cudd_SetZddTree() +
                  Sets the ZDD variable group tree of the manager. + +
                  Cudd_SharingSize() +
                  Counts the number of nodes in an array of DDs. + +
                  Cudd_ShortestLength() +
                  Find the length of the shortest path(s) in a DD. + +
                  Cudd_ShortestPath() +
                  Finds a shortest path in a DD. + +
                  Cudd_ShuffleHeap() +
                  Reorders variables according to given permutation. + +
                  Cudd_SolveEqn() +
                  Implements the solution of F(x,y) = 0. + +
                  Cudd_SplitSet() +
                  Returns m minterms from a BDD. + +
                  Cudd_Srandom() +
                  Initializer for the portable random number generator. + +
                  Cudd_StdPostReordHook() +
                  Sample hook function to call after reordering. + +
                  Cudd_StdPreReordHook() +
                  Sample hook function to call before reordering. + +
                  Cudd_SubsetCompress() +
                  Find a dense subset of BDD f. + +
                  Cudd_SubsetHeavyBranch() +
                  Extracts a dense subset from a BDD with the heavy branch + heuristic. + +
                  Cudd_SubsetShortPaths() +
                  Extracts a dense subset from a BDD with the shortest paths + heuristic. + +
                  Cudd_SubsetWithMaskVars() +
                  Extracts a subset from a BDD. + +
                  Cudd_SupersetCompress() +
                  Find a dense superset of BDD f. + +
                  Cudd_SupersetHeavyBranch() +
                  Extracts a dense superset from a BDD with the heavy branch + heuristic. + +
                  Cudd_SupersetShortPaths() +
                  Extracts a dense superset from a BDD with the shortest paths + heuristic. + +
                  Cudd_SupportIndex() +
                  Finds the variables on which a DD depends. + +
                  Cudd_SupportIndices() +
                  Finds the variables on which a DD depends. + +
                  Cudd_SupportSize() +
                  Counts the variables on which a DD depends. + +
                  Cudd_Support() +
                  Finds the variables on which a DD depends. + +
                  Cudd_SymmProfile() +
                  Prints statistics on symmetric variables. + +
                  Cudd_TimeLimited() +
                  Returns true if the time limit for the manager is set. + +
                  Cudd_TurnOffCountDead() +
                  Causes the dead nodes not to be counted towards triggering + reordering. + +
                  Cudd_TurnOnCountDead() +
                  Causes the dead nodes to be counted towards triggering + reordering. + +
                  Cudd_UnderApprox() +
                  Extracts a dense subset from a BDD with Shiple's + underapproximation method. + +
                  Cudd_UnsetTimeLimit() +
                  Unsets the time limit for the manager. + +
                  Cudd_UpdateTimeLimit() +
                  Updates the time limit for the manager. + +
                  Cudd_VectorSupportIndex() +
                  Finds the variables on which a set of DDs depends. + +
                  Cudd_VectorSupportIndices() +
                  Finds the variables on which a set of DDs depends. + +
                  Cudd_VectorSupportSize() +
                  Counts the variables on which a set of DDs depends. + +
                  Cudd_VectorSupport() +
                  Finds the variables on which a set of DDs depends. + +
                  Cudd_VerifySol() +
                  Checks the solution of F(x,y) = 0. + +
                  Cudd_Xeqy() +
                  Generates a BDD for the function x==y. + +
                  Cudd_Xgty() +
                  Generates a BDD for the function x > y. + +
                  Cudd_addAgreement() +
                  f if f==g; background if f!=g. + +
                  Cudd_addApply() +
                  Applies op to the corresponding discriminants of f and g. + +
                  Cudd_addBddInterval() +
                  Converts an ADD to a BDD. + +
                  Cudd_addBddIthBit() +
                  Converts an ADD to a BDD by extracting the i-th bit from + the leaves. + +
                  Cudd_addBddPattern() +
                  Converts an ADD to a BDD. + +
                  Cudd_addBddStrictThreshold() +
                  Converts an ADD to a BDD. + +
                  Cudd_addBddThreshold() +
                  Converts an ADD to a BDD. + +
                  Cudd_addCmpl() +
                  Computes the complement of an ADD a la C language. + +
                  Cudd_addCompose() +
                  Substitutes g for x_v in the ADD for f. + +
                  Cudd_addComputeCube() +
                  Computes the cube of an array of ADD variables. + +
                  Cudd_addConstrain() +
                  Computes f constrain c for ADDs. + +
                  Cudd_addConst() +
                  Returns the ADD for constant c. + +
                  Cudd_addDiff() +
                  Returns plusinfinity if f=g; returns min(f,g) if f!=g. + +
                  Cudd_addDivide() +
                  Integer and floating point division. + +
                  Cudd_addEvalConst() +
                  Checks whether ADD g is constant whenever ADD f is 1. + +
                  Cudd_addExistAbstract() +
                  Existentially Abstracts all the variables in cube from f. + +
                  Cudd_addFindMax() +
                  Finds the maximum discriminant of f. + +
                  Cudd_addFindMin() +
                  Finds the minimum discriminant of f. + +
                  Cudd_addGeneralVectorCompose() +
                  Composes an ADD with a vector of ADDs. + +
                  Cudd_addHamming() +
                  Computes the Hamming distance ADD. + +
                  Cudd_addHarwell() +
                  Reads in a matrix in the format of the Harwell-Boeing + benchmark suite. + +
                  Cudd_addIteConstant() +
                  Implements ITEconstant for ADDs. + +
                  Cudd_addIte() +
                  Implements ITE(f,g,h). + +
                  Cudd_addIthBit() +
                  Extracts the i-th bit from an ADD. + +
                  Cudd_addIthVar() +
                  Returns the ADD variable with index i. + +
                  Cudd_addLeq() +
                  Determines whether f is less than or equal to g. + +
                  Cudd_addLog() +
                  Natural logarithm of an ADD. + +
                  Cudd_addMatrixMultiply() +
                  Calculates the product of two matrices represented as + ADDs. + +
                  Cudd_addMaximum() +
                  Integer and floating point max. + +
                  Cudd_addMinimum() +
                  Integer and floating point min. + +
                  Cudd_addMinus() +
                  Integer and floating point subtraction. + +
                  Cudd_addMonadicApply() +
                  Applies op to the discriminants of f. + +
                  Cudd_addNand() +
                  NAND of two 0-1 ADDs. + +
                  Cudd_addNegate() +
                  Computes the additive inverse of an ADD. + +
                  Cudd_addNewVarAtLevel() +
                  Returns a new ADD variable at a specified level. + +
                  Cudd_addNewVar() +
                  Returns a new ADD variable. + +
                  Cudd_addNonSimCompose() +
                  Composes an ADD with a vector of 0-1 ADDs. + +
                  Cudd_addNor() +
                  NOR of two 0-1 ADDs. + +
                  Cudd_addOneZeroMaximum() +
                  Returns 1 if f > g and 0 otherwise. + +
                  Cudd_addOrAbstract() +
                  Disjunctively abstracts all the variables in cube from the + 0-1 ADD f. + +
                  Cudd_addOr() +
                  Disjunction of two 0-1 ADDs. + +
                  Cudd_addOuterSum() +
                  Takes the minimum of a matrix and the outer sum of two vectors. + +
                  Cudd_addPermute() +
                  Permutes the variables of an ADD. + +
                  Cudd_addPlus() +
                  Integer and floating point addition. + +
                  Cudd_addRead() +
                  Reads in a sparse matrix. + +
                  Cudd_addResidue() +
                  Builds an ADD for the residue modulo m of an n-bit + number. + +
                  Cudd_addRestrict() +
                  ADD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
                  Cudd_addRoundOff() +
                  Rounds off the discriminants of an ADD. + +
                  Cudd_addScalarInverse() +
                  Computes the scalar inverse of an ADD. + +
                  Cudd_addSetNZ() +
                  This operator sets f to the value of g wherever g != 0. + +
                  Cudd_addSwapVariables() +
                  Swaps two sets of variables of the same size (x and y) in + the ADD f. + +
                  Cudd_addThreshold() +
                  f if f>=g; 0 if f<g. + +
                  Cudd_addTimesPlus() +
                  Calculates the product of two matrices represented as + ADDs. + +
                  Cudd_addTimes() +
                  Integer and floating point multiplication. + +
                  Cudd_addTriangle() +
                  Performs the triangulation step for the shortest path + computation. + +
                  Cudd_addUnivAbstract() +
                  Universally Abstracts all the variables in cube from f. + +
                  Cudd_addVectorCompose() +
                  Composes an ADD with a vector of 0-1 ADDs. + +
                  Cudd_addWalsh() +
                  Generates a Walsh matrix in ADD form. + +
                  Cudd_addXeqy() +
                  Generates an ADD for the function x==y. + +
                  Cudd_addXnor() +
                  XNOR of two 0-1 ADDs. + +
                  Cudd_addXor() +
                  XOR of two 0-1 ADDs. + +
                  Cudd_bddAdjPermuteX() +
                  Rearranges a set of variables in the BDD B. + +
                  Cudd_bddAndAbstractLimit() +
                  Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. Returns NULL if too many nodes are required. + +
                  Cudd_bddAndAbstract() +
                  Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                  Cudd_bddAndLimit() +
                  Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                  Cudd_bddAnd() +
                  Computes the conjunction of two BDDs f and g. + +
                  Cudd_bddApproxConjDecomp() +
                  Performs two-way conjunctive decomposition of a BDD. + +
                  Cudd_bddApproxDisjDecomp() +
                  Performs two-way disjunctive decomposition of a BDD. + +
                  Cudd_bddBindVar() +
                  Prevents sifting of a variable. + +
                  Cudd_bddBooleanDiff() +
                  Computes the boolean difference of f with respect to x. + +
                  Cudd_bddCharToVect() +
                  Computes a vector whose image equals a non-zero function. + +
                  Cudd_bddClippingAndAbstract() +
                  Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
                  Cudd_bddClippingAnd() +
                  Approximates the conjunction of two BDDs f and g. + +
                  Cudd_bddClosestCube() +
                  Finds a cube of f at minimum Hamming distance from g. + +
                  Cudd_bddCompose() +
                  Substitutes g for x_v in the BDD for f. + +
                  Cudd_bddComputeCube() +
                  Computes the cube of an array of BDD variables. + +
                  Cudd_bddConstrainDecomp() +
                  BDD conjunctive decomposition as in McMillan's CAV96 paper. + +
                  Cudd_bddConstrain() +
                  Computes f constrain c. + +
                  Cudd_bddCorrelationWeights() +
                  Computes the correlation of f and g for given input + probabilities. + +
                  Cudd_bddCorrelation() +
                  Computes the correlation of f and g. + +
                  Cudd_bddExistAbstractLimit() +
                  Existentially abstracts all the variables in cube from f. + +
                  Cudd_bddExistAbstract() +
                  Existentially abstracts all the variables in cube from f. + +
                  Cudd_bddGenConjDecomp() +
                  Performs two-way conjunctive decomposition of a BDD. + +
                  Cudd_bddGenDisjDecomp() +
                  Performs two-way disjunctive decomposition of a BDD. + +
                  Cudd_bddIntersect() +
                  Returns a function included in the intersection of f and g. + +
                  Cudd_bddInterval() +
                  Generates a BDD for the function lowerB ≤ x ≤ upperB. + +
                  Cudd_bddIsNsVar() +
                  Checks whether a variable is next state. + +
                  Cudd_bddIsPiVar() +
                  Checks whether a variable is primary input. + +
                  Cudd_bddIsPsVar() +
                  Checks whether a variable is present state. + +
                  Cudd_bddIsVarEssential() +
                  Determines whether a given variable is essential with a + given phase in a BDD. + +
                  Cudd_bddIsVarHardGroup() +
                  Checks whether a variable is set to be in a hard group. + +
                  Cudd_bddIsVarToBeGrouped() +
                  Checks whether a variable is set to be grouped. + +
                  Cudd_bddIsVarToBeUngrouped() +
                  Checks whether a variable is set to be ungrouped. + +
                  Cudd_bddIsop() +
                  Computes a BDD in the interval between L and U with a + simple sum-of-product cover. + +
                  Cudd_bddIteConstant() +
                  Implements ITEconstant(f,g,h). + +
                  Cudd_bddIteLimit() +
                  Implements ITE(f,g,h). Returns + NULL if too many nodes are required. + +
                  Cudd_bddIterConjDecomp() +
                  Performs two-way conjunctive decomposition of a BDD. + +
                  Cudd_bddIterDisjDecomp() +
                  Performs two-way disjunctive decomposition of a BDD. + +
                  Cudd_bddIte() +
                  Implements ITE(f,g,h). + +
                  Cudd_bddIthVar() +
                  Returns the BDD variable with index i. + +
                  Cudd_bddLICompaction() +
                  Performs safe minimization of a BDD. + +
                  Cudd_bddLargestPrimeUnate() +
                  Find a largest prime of a unate function. + +
                  Cudd_bddLeqUnless() +
                  Tells whether f is less than of equal to G unless D is 1. + +
                  Cudd_bddLeq() +
                  Determines whether f is less than or equal to g. + +
                  Cudd_bddLiteralSetIntersection() +
                  Computes the intesection of two sets of literals + represented as BDDs. + +
                  Cudd_bddMakePrime() +
                  Expands cube to a prime implicant of f. + +
                  Cudd_bddMaximallyExpand() +
                  Expands lb to prime implicants of (f and ub). + +
                  Cudd_bddMinimize() +
                  Finds a small BDD that agrees with f over + c. + +
                  Cudd_bddNPAnd() +
                  Computes f non-polluting-and g. + +
                  Cudd_bddNand() +
                  Computes the NAND of two BDDs f and g. + +
                  Cudd_bddNewVarAtLevel() +
                  Returns a new BDD variable at a specified level. + +
                  Cudd_bddNewVar() +
                  Returns a new BDD variable. + +
                  Cudd_bddNor() +
                  Computes the NOR of two BDDs f and g. + +
                  Cudd_bddOrLimit() +
                  Computes the disjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                  Cudd_bddOr() +
                  Computes the disjunction of two BDDs f and g. + +
                  Cudd_bddPermute() +
                  Permutes the variables of a BDD. + +
                  Cudd_bddPickArbitraryMinterms() +
                  Picks k on-set minterms evenly distributed from given DD. + +
                  Cudd_bddPickOneCube() +
                  Picks one on-set cube randomly from the given DD. + +
                  Cudd_bddPickOneMinterm() +
                  Picks one on-set minterm randomly from the given DD. + +
                  Cudd_bddPrintCover() +
                  Prints a sum of prime implicants of a BDD. + +
                  Cudd_bddReadPairIndex() +
                  Reads a corresponding pair index for a given index. + +
                  Cudd_bddRead() +
                  Reads in a graph (without labels) given as a list of arcs. + +
                  Cudd_bddRealignDisable() +
                  Disables realignment of ZDD order to BDD order. + +
                  Cudd_bddRealignEnable() +
                  Enables realignment of BDD order to ZDD order. + +
                  Cudd_bddRealignmentEnabled() +
                  Tells whether the realignment of BDD order to ZDD order is + enabled. + +
                  Cudd_bddResetVarToBeGrouped() +
                  Resets a variable not to be grouped. + +
                  Cudd_bddRestrict() +
                  BDD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
                  Cudd_bddSetNsVar() +
                  Sets a variable type to next state. + +
                  Cudd_bddSetPairIndex() +
                  Sets a corresponding pair index for a given index. + +
                  Cudd_bddSetPiVar() +
                  Sets a variable type to primary input. + +
                  Cudd_bddSetPsVar() +
                  Sets a variable type to present state. + +
                  Cudd_bddSetVarHardGroup() +
                  Sets a variable to be a hard group. + +
                  Cudd_bddSetVarToBeGrouped() +
                  Sets a variable to be grouped. + +
                  Cudd_bddSetVarToBeUngrouped() +
                  Sets a variable to be ungrouped. + +
                  Cudd_bddSqueeze() +
                  Finds a small BDD in a function interval. + +
                  Cudd_bddSwapVariables() +
                  Swaps two sets of variables of the same size (x and y) in + the BDD f. + +
                  Cudd_bddTransfer() +
                  Convert a BDD from a manager to another one. + +
                  Cudd_bddUnbindVar() +
                  Allows the sifting of a variable. + +
                  Cudd_bddUnivAbstract() +
                  Universally abstracts all the variables in cube from f. + +
                  Cudd_bddVarConjDecomp() +
                  Performs two-way conjunctive decomposition of a BDD. + +
                  Cudd_bddVarDisjDecomp() +
                  Performs two-way disjunctive decomposition of a BDD. + +
                  Cudd_bddVarIsBound() +
                  Tells whether a variable can be sifted. + +
                  Cudd_bddVarIsDependent() +
                  Checks whether a variable is dependent on others in a + function. + +
                  Cudd_bddVarMap() +
                  Remaps the variables of a BDD using the default variable map. + +
                  Cudd_bddVectorCompose() +
                  Composes a BDD with a vector of BDDs. + +
                  Cudd_bddXnorLimit() +
                  Computes the exclusive NOR of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                  Cudd_bddXnor() +
                  Computes the exclusive NOR of two BDDs f and g. + +
                  Cudd_bddXorExistAbstract() +
                  Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
                  Cudd_bddXor() +
                  Computes the exclusive OR of two BDDs f and g. + +
                  Cudd_tlcInfoFree() +
                  Frees a DdTlcInfo Structure. + +
                  Cudd_zddChange() +
                  Substitutes a variable with its complement in a ZDD. + +
                  Cudd_zddComplement() +
                  Computes a complement cover for a ZDD node. + +
                  Cudd_zddCountDouble() +
                  Counts the number of minterms of a ZDD. + +
                  Cudd_zddCountMinterm() +
                  Counts the number of minterms of a ZDD. + +
                  Cudd_zddCount() +
                  Counts the number of minterms in a ZDD. + +
                  Cudd_zddCoverPathToString() +
                  Converts a path of a ZDD representing a cover to a string. + +
                  Cudd_zddDagSize() +
                  Counts the number of nodes in a ZDD. + +
                  Cudd_zddDiffConst() +
                  Performs the inclusion test for ZDDs (P implies Q). + +
                  Cudd_zddDiff() +
                  Computes the difference of two ZDDs. + +
                  Cudd_zddDivideF() +
                  Modified version of Cudd_zddDivide. + +
                  Cudd_zddDivide() +
                  Computes the quotient of two unate covers. + +
                  Cudd_zddDumpDot() +
                  Writes a dot file representing the argument ZDDs. + +
                  Cudd_zddFirstPath() +
                  Finds the first path of a ZDD. + +
                  Cudd_zddIntersect() +
                  Computes the intersection of two ZDDs. + +
                  Cudd_zddIsop() +
                  Computes an ISOP in ZDD form from BDDs. + +
                  Cudd_zddIte() +
                  Computes the ITE of three ZDDs. + +
                  Cudd_zddIthVar() +
                  Returns the ZDD variable with index i. + +
                  Cudd_zddNextPath() +
                  Generates the next path of a ZDD. + +
                  Cudd_zddPortFromBdd() +
                  Converts a BDD into a ZDD. + +
                  Cudd_zddPortToBdd() +
                  Converts a ZDD into a BDD. + +
                  Cudd_zddPrintCover() +
                  Prints a sum of products from a ZDD representing a cover. + +
                  Cudd_zddPrintDebug() +
                  Prints to the standard output a ZDD and its statistics. + +
                  Cudd_zddPrintMinterm() +
                  Prints a disjoint sum of product form for a ZDD. + +
                  Cudd_zddPrintSubtable() +
                  Prints the ZDD table. + +
                  Cudd_zddProduct() +
                  Computes the product of two covers represented by ZDDs. + +
                  Cudd_zddReadNodeCount() +
                  Reports the number of nodes in ZDDs. + +
                  Cudd_zddRealignDisable() +
                  Disables realignment of ZDD order to BDD order. + +
                  Cudd_zddRealignEnable() +
                  Enables realignment of ZDD order to BDD order. + +
                  Cudd_zddRealignmentEnabled() +
                  Tells whether the realignment of ZDD order to BDD order is + enabled. + +
                  Cudd_zddReduceHeap() +
                  Main dynamic reordering routine for ZDDs. + +
                  Cudd_zddShuffleHeap() +
                  Reorders ZDD variables according to given permutation. + +
                  Cudd_zddSubset0() +
                  Computes the negative cofactor of a ZDD w.r.t. a variable. + +
                  Cudd_zddSubset1() +
                  Computes the positive cofactor of a ZDD w.r.t. a variable. + +
                  Cudd_zddSupport() +
                  Finds the variables on which a ZDD depends. + +
                  Cudd_zddSymmProfile() +
                  Prints statistics on symmetric ZDD variables. + +
                  Cudd_zddUnateProduct() +
                  Computes the product of two unate covers. + +
                  Cudd_zddUnion() +
                  Computes the union of two ZDDs. + +
                  Cudd_zddVarsFromBddVars() +
                  Creates one or more ZDD variables for each BDD variable. + +
                  Cudd_zddWeakDivF() +
                  Modified version of Cudd_zddWeakDiv. + +
                  Cudd_zddWeakDiv() +
                  Applies weak division to two covers. + +
                  + +
                  + +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtDet.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtDet.html new file mode 100644 index 000000000..f23e11e4f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddExtDet.html @@ -0,0 +1,4450 @@ + +The cudd package + + +
                  +
                  +
                  + 
                  +CUDD_VALUE_TYPE *þvalueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +CUDD_VALUE_TYPE *þvalueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +CUDD_VALUE_TYPE þcþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +CUDD_VALUE_TYPE þepþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +CUDD_VALUE_TYPE þupperþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +CUDD_VALUE_TYPE þvalueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +CUDD_VALUE_TYPE þvalueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +Cudd_AggregationType þgcþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +Cudd_HookType þwhereþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +Cudd_HookType þwhereþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +Cudd_HookType þwhereþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +Cudd_ReorderingType *þmethodþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +Cudd_ReorderingType *þmethodþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +Cudd_ReorderingType þmethodþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +Cudd_ReorderingType þmethodþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DD_PRFP þPifuncþfunction used to build Pi if it is NULL(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdApaDigit þliteralþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdApaNumber þbþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdApaNumber þdestþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdApaNumber þdiffþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdApaNumber þnumberþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdApaNumber þnumberþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdApaNumber þquotientþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdApaNumber þquotientþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdApaNumber þsecondþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdApaNumber þsumþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdGen *þgenþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdGen *þgenþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þddþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þmanagerþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þtableþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þtableþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þtableþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þtableþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdManager *þuniqueþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode ***þconjunctsþaddress of the array of conjuncts(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode ***þconjunctsþaddress of the array of conjuncts(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode ***þconjunctsþaddress of the array of conjuncts(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode ***þconjunctsþaddress of the first factor(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þonlyGþcube of variables only in g(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þvectorOffþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þvectorþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þvectorþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þvectorþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þyþarray of y variables(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þyþarray of y variables(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þyþarray of y variables(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þyþarray of y variables(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þyþarray of y variables(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þzdd_Iþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þzþarray of z variables(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode **þzþarray of z variables(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þBþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þBþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þDþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þDþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þPþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þPþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þQþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þQþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þQþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þQþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þUþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þYþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þbckþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcubeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcubeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcubeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcubeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcubeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcubeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcubeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þcþconstraint (care set)(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þepsilonþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþDD whose support is sought(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþDD whose support is sought(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþDD whose support size is sought(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþZDD whose support is sought(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþfunction against which to expand(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþfunction in which to remap variables(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þfþfunction of which the cube is to be made a prime(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þgþsecond operand(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þhþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þhþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þhþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þhþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þhþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þnþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þp_nodeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þphaseBddþcube of the phases(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þuþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þuþupper bound(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdNode *þvarþvariable(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +DdTlcInfo *þtþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +EpDouble *þepdþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +FILE *þfpþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +FILE *þfpþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +FILE *þfpþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +FILE *þfpþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +FILE *þfpþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +FILE *þfpþpointer to the dump file(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +FILE *þfpþpointer to the dump file(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +FILE *þfpþpointer to the dump file(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +FILE *þfpþpointer to the dump file(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +FILE *þfpþpointer to the dump file(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +MtrNode *þtreeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +MtrNode *þtreeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +char *þstringþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +char *þstrþpointer to string to use if != NULL(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +double *þprobþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +double þmgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +double þmgþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +double þmþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +double þquality0þminimum improvement for accepted changes when b=0(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +double þquality0þminimum improvement for accepted changes when b=0(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +double þqualityþminimum improvement for accepted changes(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +double þqualityþminimum improvement for accepted changes(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +double þqualityþminimum improvement for accepted changes(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +double þqualityþminimum improvement for accepted changes(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int **þcubeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int **þcubeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int **þindicesþarray containing (on return) the indices(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int **þindicesþarray containing (on return) the indices(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int **þpathþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int **þpathþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int *þarrayþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int *þarrayþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int *þdigitsþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int *þdistanceþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int *þinputsþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int *þlengthþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int *þlengthþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int *þpermutationþrequired variable permutation(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int *þpermutationþrequired variable permutation(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int *þpermutþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int *þpermutþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int *þphase2þ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int *þweightþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þNþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þamountþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þarcviolationþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þbinaryDigitsþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þbitþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þbitþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þcycleþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þdigitsþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þdirectionþunder (0) or over (1) approximation(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þdirectionþunder (0) or over (1) approximation(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þhardlimitþflag: 1 if threshold is a hard limit(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þhardlimitþflag: 1 if threshold is a hard limit(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþvariable index(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþvariable index(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþvariable index(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþvariable index(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþvariable index(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþvariable index(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þindexþvariable index(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þiþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þiþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þiþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þiþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þiþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þiþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þiþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þiþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þiþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þiþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þiþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þiþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þkþnumber of minterms to find(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þlevelþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þlevelþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þminsizeþbound below which no reordering occurs(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þminsizeþbound below which no reordering occurs(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þmultiplicityþhow many ZDD variables are created for each BDD variable(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þmvarsþsize of maskVars(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þmvþ0: blif, 1: blif-MV(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þmvþ0: blif, 1: blif-MV(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnVarsþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnumberXoversþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnvarsþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnvarsþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnvarsþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnvarsþsize of the support of f(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnzþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnzþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnzþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþlength of both arrays(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþnumbers of unknowns(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþnumbers of unknowns(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþsize of vars(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþsize of the array(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþsize of the array(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þnþsize of the array(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þpairIndexþcorresponding variable index(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þpathþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þphaseþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þphaseþ1: positive; 0: negative(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þpopulationSizeþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þpowerþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þprecisionþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þprecisionþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þprþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þprþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þprþverbosity level(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þprþverbosity level(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þrecombþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þsmsþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þsmvþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þsymmviolationþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þsyþstep of column variables(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þsyþstep of column variables(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þthresholdþmaximum number of nodes in the subset(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þthresholdþmaximum number of nodes in the subset(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þthresholdþmaximum number of nodes in the superset(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þthresholdþmaximum number of nodes in the superset(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þtopþindex of top variable(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þupperBoundþdistance above which an approximate answer is OK(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þupperþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þupperþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þvarþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þvarþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þvarþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þvþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þvþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þxþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +int þyþcolumn index(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +long þseedþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +long þsizeþsize of the allocation that failed(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þfactorþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þhrþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þlimitþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þlimitþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þlimitþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þlimitþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þlimitþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þlimitþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þlutþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þmaxLiveþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þmcþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þmrþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þnextþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þpþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þsecondDenþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þtypeþMTR_DEFAULT or MTR_FIXED(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þtypeþMTR_DEFAULT or MTR_FIXED(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned int þupperBþupper bound(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned long þincreaseþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned long þmaxMemoryþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned long þmaxMemoryþtarget maximum memory occupation(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned long þstþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +unsigned long þtlþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +void *þdataþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +void *þdataþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +void *þdataþ(
                  +    
                  +)
                  +
                  +
                  +

                  + +

                  +
                  + 
                  +þþ(
                  +    
                  +)
                  +
                  +
                  +

                  + + +

                  +
                  +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.css b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.css new file mode 100644 index 000000000..d1824aff4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.css @@ -0,0 +1,30 @@ +/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */ +.MATH { font-family: "Century Schoolbook", serif; } +.MATH I { font-family: "Century Schoolbook", serif; font-style: italic } +.BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold } + +/* implement both fixed-size and relative sizes */ +SMALL.XTINY { font-size : xx-small } +SMALL.TINY { font-size : x-small } +SMALL.SCRIPTSIZE { font-size : smaller } +SMALL.FOOTNOTESIZE { font-size : small } +SMALL.SMALL { } +BIG.LARGE { } +BIG.XLARGE { font-size : large } +BIG.XXLARGE { font-size : x-large } +BIG.HUGE { font-size : larger } +BIG.XHUGE { font-size : xx-large } + +/* heading styles */ +H1 { } +H2 { } +H3 { } +H4 { } +H5 { } + +/* mathematics styles */ +DIV.displaymath { } /* math displays */ +TD.eqno { } /* equation-number cells */ + + +/* document-specific styles come next */ diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.html new file mode 100644 index 000000000..e74c4fff5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddIntro.html @@ -0,0 +1,219 @@ + + + + + +CUDD: CU Decision Diagram Package +Release 2.5.0 + + + + + + + + + + + + + + + + +next +up +previous + +index +
                  + Next: Introduction +   Index +
                  +
                  + + +

                  CUDD: CU Decision Diagram Package +
                  +Release 2.5.0

                  +
                  + +

                  Fabio Somenzi

                  +

                  Department of Electrical, Computer, and Energy Engineering

                  +

                  University of Colorado at Boulder

                  +
                  + +

                  +


                  + + + + + +

                  +
                  +Fabio Somenzi +2012-02-04 +
                  + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddTitle.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddTitle.html new file mode 100644 index 000000000..de29df000 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/cuddTitle.html @@ -0,0 +1,18 @@ + +The cudd package: Title + + + + + + + + +
                  + Programmer view + Maintainer by function + Maintainer by file
                  + + + +writing ./cuddDesc.html diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/footnode.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/footnode.html new file mode 100644 index 000000000..985c42271 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/footnode.html @@ -0,0 +1,109 @@ + + + + + +Footnotes + + + + + + + + + + + + + + + + +
                  +
                  ... application.1
                  +
                  The + global statistical counters are used locally; hence they are + compatible with the use of multiple managers. + +
                  .
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +
                  +
                  +
                  ... +node.2
                  +
                  When the variables in a group are reordered, the + association between the low field and the index of the first + variable in the group is lost. The package updates the tree to keep + track of the changes. However, the application cannot rely on + low to determine the position of variables. + +
                  .
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +.
                  +
                  +
                  +
                  + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/blueball.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/blueball.png new file mode 100644 index 0000000000000000000000000000000000000000..9720c29504ba579244bfbd203fd05240cc94a536 GIT binary patch literal 333 zcmV-T0kZyyP)g#RC9xF*N@U2-YVd{{{fg2mrhj5B~=M<^TXndV0kN0Q~>~TBXMS zYhuj;0K5+mat8pM1^~uFF=$Bu0004WQchC fp6U^O_M`O)E)54>ni*oc00000NkvXXu0mjfsOawM_w&SE@R)n5>xJ5B z1F;(h|BF_wQV4l;JD~8s(vhjgCGtV$Ds2t(5_qDSm6|w|UPxb;>}t1HkZ N22WQ%mvv4FO#oUfIV%7F literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_begin.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/ch_begin.png new file mode 100644 index 0000000000000000000000000000000000000000..0b3a6e230df75ccef0955e1b346f3f5a94bc1a73 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^89*$-0VEh*g05=;X{M4OzhH*_y1vP(Kwi41i(^Q| zoVQaP`4|*An7cnV{yC!lYwO-a3y*wxkhkeenwPBWB3%~WiiqBfgF#DkMW*sCI@ojR z)Qg$b($DLkNv4UkZM&BfndB5)l8PiRLd~xnWZklNF;pM8tvX0WqPPyO z;)-K=4#W4F4}GJq1>p=*HTH~8Bx4Uw@L9auPP7>(8MU{?ml;f$b($DLkNv4UkZM&BfndB5)l8PiRLd~xnWZklNF;pM8tvX0WqPPyO z;)-K=4#W4F4}GJq1>p=*HTH~8Bx4Uw@L9auPP7>(8MU{?ml;fUD+8 zX^gy=OnEK3Q}m;lhza8yZV|7cVql)yXw0 z;)F+4%2HdS18kr6xbR7A&A75Cu)A%7Ys%EgTe~DWM4f D4qP>Q literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/contents.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/contents.png new file mode 100644 index 0000000000000000000000000000000000000000..0c752c66c876acaa2131d43788a7406f5979f746 GIT binary patch literal 278 zcmV+x0qOpUP)n_8B^;cn$O_g|3BG{!1Fj&^JiWpJWLeA$WK=+#U`gfB`ZJpvc?v;;IiS zWN}RlBW%jSmz3^2R|i?JM0KMv+9z;7ee@a!R<*>X0K7&N_)1@@}28%Z6=9 t-O~MHw|5t0`TuI#<-T9Me##YR_J!+(UN4n;@(5@ygQu&X%Q~loCIFb&G|K=0 literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/footnote.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/footnote.png new file mode 100644 index 0000000000000000000000000000000000000000..4591c0eca1231a8dd51f936b46363bcb9c35cefd GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^{2FS zrsoVLnH6~&F0zL+P8GD|SkqyVU@2Hw;H_Hnf}ux6|G)cetK3(c&T7OiHM_`p-Fn|I zk6S7tu`7hSPeski&6e)S+V5Vl<++E- m`l!8MrB+YxvAz2@`46M@GoAfWMa#rMF7kBsb6Mw<&;$UT-9{4t literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/greenball.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/greenball.png new file mode 100644 index 0000000000000000000000000000000000000000..a4d714533a8c5e836f167a2118108d4f68bcf2f6 GIT binary patch literal 333 zcmV-T0kZyyP)&2#{24FFmV07?x2oE8Aa z832?P0IV5GoK*nU90=AYkN=AR&L1KFKLAl@PcFG!4j{1mTA&&;ze)eFnmrpph=4*Wd1;<76Q uRfVXn4m>Ir2oglLH2I2lWqskW{Rg3J}7qSOsCi?q75nH?M zE^{77+Z<+1r-r1Nch|4lthS=d{J1PfXUU1#ym22LZu_2=vAt}Pd}!6<{pzf1?Y4jM u^4(GWO*wx3{4#&$%6k3J$8QJwOy|GN;;5Q**1ZVmMg~t;KbLh*2~7aKlwD!~ literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/next.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/next.png new file mode 100644 index 0000000000000000000000000000000000000000..1628652aac7cff4b24228abd9908c320c6026a7c GIT binary patch literal 245 zcmVQ2aP`rsfsL)H8>rF50IrEKQ7U2mrM!9=R9*Dw1X+@W9RTx^a-#5T6$bi^4|h!q3s vo9V3RdqZP$JTTh9!JZ)`voZLAB<&|;0_>J~#QNZkD16SAR=O4@7anKqmC5&ngT;#rH1+qK z20S~FlZynq-MY=T{~%>KNs884sExd44P^%bf!zNDPxW#x21^f><@$FgzM-=J5cLN5 WGDyh~oC>l40000tyuK1_JOFF_cfRLygYKXs-cjquE z6qZUgCnOS-qR#wjl*#Yu6x>pYvGz*5sgT3Ky$sw{E$HaO|9>UJNF+j;OnPJjVj%;{m_nqs0ZqV}||YZyJu#*Jw}23cUX_af%9 z{uS~*k`LH^Qb$R+lmwPEN^IYqTH-Vq0YzE^cOwaMk&itdVwtMByf}E>Y3%dwD5Z9*>tJ(L)x+ zsQ6o00>F0uiF$f}|EHc` gW14v)`Zh=L1v(Lj=i40@mjD0&07*qoM6N<$f}?G$umAu6 literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/orangeball.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/orangeball.png new file mode 100644 index 0000000000000000000000000000000000000000..10249c668abb037b32a1d537d66e9e2999bbc30e GIT binary patch literal 333 zcmV-T0kZyyP)AS^$Jp5VUCk#in}ymj~{O09rHvS~38OWibEI zrMztboOepzfdEP?07@wUtYiSqpJM--5C4`Aaz_u&dk|_o0L7(x)_4H_#*6==A;xn6 zazX&SY5-z60RN>ilvV(>R1Y8k0004WQchCd@h{G;iGOwP-k9UVO50Hcelh_;^S8s zlr19Cn;yHsWZodf)(Q_M@X|8FKV`iT$$re%Hlc^|+B?5ptZnip-JzW5walZJkLkqq fd#WKa^^evk#2W_K-Vq6^00000NkvXXu0mjf&K`=A literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/pinkball.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/pinkball.png new file mode 100644 index 0000000000000000000000000000000000000000..5b92325708e4bec4699d8b15e7ed285b55e9d6b6 GIT binary patch literal 332 zcmV-S0ki&zP)2P*}kMa>gUTJl$kP*V4^b)U_hOaP4 z(MBY9-{*nl_&|=WXFRCDeMJQS)O6OCS>LQ})^E1QPP=rmVxHz?hoKhgB esft+@KU$ytO$Rt^R9;{J0000fWJ4@hJr9=)Yx5|PDs2VC9?nk002ovPDHLkV1i^Ya=-up literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/prev_g.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/prev_g.png new file mode 100644 index 0000000000000000000000000000000000000000..476d9568c900e2ada6c2019b67eeee166a5f1288 GIT binary patch literal 327 zcmV-N0l5B&P)18~ zIpil5yY|hg&aw;rvXQ~olHp&x|G5Aw{ug* Z|8M28X+2RX!WaMm002ovPDHLkV1gF^iYx#C literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/purpleball.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/purpleball.png new file mode 100644 index 0000000000000000000000000000000000000000..d6d63fb822774678fbdd5da91b990f7b2be62997 GIT binary patch literal 332 zcmV-S0ki&zP)cTL6T*5C5-v#ny}en+VpE0M1bWa-{&~l>pYN0PeN`{l6jq+ok_+0GxpU zv@`%ph5)>_5C4q-#zp{QJ^)&S0K8%lgso!Df=ZlJ4{~V$lyNYNvH<;i0IaZj#WMg( zr9#fQ2meX{YCr&5ln~C}Z~OcJ0004WQchCK~#90#g)sEgfI+5A5%`N^P6zUU=N+dWI!5wkbi)oX1q1EeE{2PAz43` zjUI_tURl5+mNtM{cI5QxcaO3##>=)7a%RRi!C3=ixYOHP-y>bCt&dAl_~Pn=2Yv!r zIRI2Yf3EG_-QgN*3JYpS)}FGLc3w*194)5Q2wO$$?irWMpHpxZimD#{vRQw!W>{2Hx>KfrC3+}RpurNIMf0(44muQU=B5BoHh7m+`5KXsClX!R|pfonPY z@$RA_h4!9T%^dHQNzNCPkzC41E>31^)OKcj5cr=xaE@2f8U}+F0fQ(8 z@xKg#XOpV_8&*XzDC}XdxW?hQg~8w&gJTkdcngEZIj5{{1JAQb&3_p@_b?dT0~)*Z z-7^NqECvN5<(>$jGZ;&P{DK)Ap4~_Ta_T)@978JR)b{1_HyQA>>~8XV&C*`>K*a3H z*Z=>W%#XZaf2{g;vbWxJW{#qdHw)65`X_ZAm|s{r^NV26`?o^#C2y}csF>;cM0&1T zV{EB%-&)()&bP0l+XkKm7#uU literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/up.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/up.png new file mode 100644 index 0000000000000000000000000000000000000000..3937e168f44bc997766dbe3b9383bd1db44f094d GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)h#LU3J`0lmo0U(Dbz$e6Y|Ni~?`T5VEKaXZ$ zILr2UCs3TRB*-tA!Qt7BG$5zc)5S5QVoq$YAz!lrkL&!DV=`*aVJGv=2TrrsUKR?`=XF~0x$5q(BOL&qeQ?X^G$FnGH9 KxvX2RVNRAoooEaAn8>@(e1sRI!V#<^f)p#-WVQt^!{}{R!<_yH~7!&%|GmpxjXG& eckJV{U(78Bbom$-1qlM(%HZkh=d#Wzp$Pz8Iac=o literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/whiteball.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/icons/whiteball.png new file mode 100644 index 0000000000000000000000000000000000000000..9d3056253edcd186983168a96518bf84b7dfee94 GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^d?3sLBp7{FoMr=Qrjj7PV21s=zR9XU-aJni$B>FS zsb?1Q9Wsz`eRz4<$*!ykmsgzhGIFk9xyN|?aY7}F+Qi?6n?06!q!zxu(#FVQ(7fx} z9e>VQZk)e3KXoNpGz(q0`D$5is3xOo$~3v&=wIs&UUDHlX>5E z9S;zGC3EdoszqA)r|Kp{Ii!hv< zN=iup;^qMT{Q&>|5BmK8&COz_tN?Iw0M5-2`~L@zlmPqxAw^06#l?EAv;cyH5SN?) z|NAk|)(C`y0JgjU$Ibv2|F}*70004WQchC))ZYaU)ksQTISgKb3Rb} fo+=PU`=j*<1)c{R%U83*00000NkvXXu0mjfomZ1* literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img1.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img1.png new file mode 100644 index 0000000000000000000000000000000000000000..6082d1b9ad58139a0f3364a2754c623968379213 GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^LO`s*!py+HI4hJj1jx|}@Ck9kPs3Q;^E<8V`F1rV4$L+!o$O}V#SJ8`5V1~x)@7>{DK)Ap4~_Ta(q2q z9780gCMP&BuHksb%2qPrzyV$rOM@el5)lnE?lPQtB62{;$GVEUQ?}r0_?Id56g9l9u^1tybh2Gc(A~U@v?V{pT~#UB9LPc;1lAydGqEKD^|>zGiSnt z2`w!x6%`dZIXMXl2_YdN9v&VxHZ}$Z1}Z8l5)u+TJUl>6uOd&+15%77L4Lsu4$p3+ z0Xc!5E{-7_Gm{e>82G{rP98Y$y`fQ&LF)v+(u~T6BkXo;DF;}mF$m@|DMYd>Y<$2p z!62e-P0wfjDH~;-Hrni+&ah~ww1izlhCN#!r$A;MCo97-W8O3CLO8Ah4QKFl^>bP0 Hl+XkKMA<<` literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img11.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img11.png new file mode 100644 index 0000000000000000000000000000000000000000..9509b94b974ebceda7307b1464cff41d092dd978 GIT binary patch literal 476 zcmV<20VDp2P)RHR400001 zbW%=J06^y0W&i*IT1iAfR5*?8Qol>XKotIB65E(GNjEq1C-ff>`WKYWg3v*9G`mYc zaIUjUKyVYf6`Y)0z12av#Z`jfqUhOscNb401agtq6#GM((*ZSG0@&w*5zR?Vp&JFjHZYw)R1{_DDabix!g7 zN(IK0TlhoZj7&cRCMN4YA+4=D+ufyUsPT{OK+%!xlHHfY^?EQz@`3E<$=wK0#zIu; z?Kmo#9LSUeJ>819WYEjzJZg=MxOW2cC~DL6s2BJ#{L{wJ26OMV89dkC&AB{oS}{a@ zS|*E0000RHR400001 zbW%=J06^y0W&i*IsYygZR5*?8QoBw9K@>d;>@MIw(8|J?>1`-&jC=wywj?wfE3vYb z+5{gzKuD~O)K;1pTeq+^*-i@s8xkypWSu+vU>~4RnsAakb7t?HduPuK;3Ln2@yH-= zXxPW^uxQXtWmewiA%(2TqY%k5F&3>qnxu=-@q+F?qP2}zzC74`36mur+jDlA7po!b z@F>EwPMm`d=DH)ON8iBdWe4m*LPitEpbf4&2AoP8X08BCYkDLY7# zU6v%ZbS15lBu_|?hTDxvjvp^h4x>c*Tz^;UQ9_Ugh@RHR400001 zbW%=J06^y0W&i*Iu1Q2eR5*?8Rl82YP#FH&LR+A47@TXJT>A*jPP~9g-7q1hkHBV} zSO&QRoIk9)L%Y+im3u$m-yS?=LkV7l0n`^iWLJ`qUav>_=ie|0PP1MJE{ z+nQ?aDeF`tQ;eA%vrGG1KcrQ=r1xXtk=hxZ!_qqy^fYx9Yy29nn^K2wmF0bp((0nu zEQK516^9)B&APDr*fzWJUXKJltT&RBAdrcF1{(l&6WIR@gphBk>Wr&fDbxn);m9?3 zUlMsEI&~d<0GnPW6Y=s%5C>6vK}CZr1>`HzmwBnATIno*Vi2eYmB=2N)F|G*c2cWO%q0|3YX0000RHR400001 zbW%=J06^y0W&i*JAxT6*R7i>KR=-OeK@|RWz1utQ_Q%C4MF`v5Sfvy1PdGwa!Aer) zQiW8>)&Ud!2Sl(ItSv-AY;#50z;>|^9fU+kgvq?wnc110lW^F@`{3Ta_vV|AH$NV; zfQ7F3G3AFMVjRf;uP_5bU?QCuC=vaOUXmF!GX*k^ZDhB?zh?DV4y!=)CbJagBPA24 zAS9C@^H{P7&bnk4^~`U=L?gkb9m7{cHY;gAth9&ViShQd(>1A{@d`3x2RZ+P&gjLEJmR8tzuyAn&n?o3&zf7E2h9fFrk}Ln!rr6>qym%+Y|k zMX5;z#w*EO>FC~*mDnR=b~`co+<0_svZ3Vt#}EnUOx*%P^A-rMx-2a%LHa4plC@lO z4#+;?{8rbps2D*W{i-HqE!|5?SQ}L}u;CV9I`I5wtlSIT=ka(nC?z-DlIyKkpZbl9 z1?a2Saq@BEb5{!GM4>-8$Nz}-ftOmi@o8)MY_xTMEFLPStaE36O4I7DuW4g`=t#af z{rq-Q2i1!hT|WI0Z8#~1raHu-1~p)_=LD_-n@CmiWPI_%$YD@ zLQ6|aPEJljLPAJLh=GBDii(Pagai){4^XXaSl_!@p7{W0# z8K@zhp_!S7=L}E50p@hZqm5oOBqYwwi9FE2!zHnxs#2kasU!Npftp7=T}EwZjF&6& uOj8aJ>|@h7e4O#riv}sy5T#u+85vZgc_!?AeDx;KXa-MLKbLh*2~7aK8$K2Q literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img16.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img16.png new file mode 100644 index 0000000000000000000000000000000000000000..2a761cec18c990da32810254f9db52ffe85ad543 GIT binary patch literal 223 zcmeAS@N?(olHy`uVBq!ia0vp^LO{&V!py+Hn6rMEP z6IxnYDk>^+a&i(95<)^kJUl!M3=C9MR3s!MczAe#I-D8z?*>wgB|(0{3=Yq3qyaez zo-U3d95a&>8kh_XPO?7yu+dYS{A9%ziqp)c` zqwmi(<>w{8-3?;c6d`YD&~VkDz&{}&fPM2L5eW$et1u%21J#Dexm;@|H;OR)tmVHj TKVXU#&@Ki~S3j3^P6nbtJynBUmAxRH^~?nCoR&KQSBf4|4Eg#`R) zWcRT9!SJkxMNpnZMM)6 qi?$LrwtEZ)r<)qLKI~#)W@eB+CE3%V^>i=Leg;ohKbLh*2~7Y~L{>Ba literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img18.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img18.png new file mode 100644 index 0000000000000000000000000000000000000000..c08507b88acb3cffbe165f81eed7aedf44e8d0e2 GIT binary patch literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^hCr;q!py+HXlK8-9mp{V@Ck93?s|A38I*di0fMz(B`cdWH4eT>Il zHM|=_k~^9HvfUA26Yu!JaHPiJ4F3^fJDUarhZ%{pn3@isD_}gB$??G<=vc!UiIfF% zKJH;WER{0x-)Dhe^34C)R|wckot<#s;vsXGWFKdb40pqq-~Syx$a=PIZCrS8I_qq? u1(%xsd7n`F_y5230?Wy>P2zc-7#R39RlZ6w8GQh{nZeW5&t;ucLK6TQ_Gl;o literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img19.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img19.png new file mode 100644 index 0000000000000000000000000000000000000000..1b152d483a1e0fd81ba2349625b9a79bfd9b65a1 GIT binary patch literal 409 zcmV;K0cQS*P)RHR400001 zbW%=J06^y0W&i*I7fD1xR5*=eV1NLA1|EhF0$}C`eg+(X9hU?e*Z{-_fCe!nd>~Q> z1H%F&HXG0Ywgw=B?*UYV3F0&cW}?j_9R#589w3-7PXsK0@h(6F5?~4xpc2 z1g3c5wsE7TyNhrZ+hZ7ukNEU7l7O5XVKvC06OSCW5WWH;c>jX{FlRCq0XxoBs^R-~*dc0Az7YU|?7YHHEW*0WNm{$YT7&;NZi+kK!JA1r|7)UjfB* zo@f168Te4upUe0g0Ap`hfyGNa3bGK!1_FK`1rz}Qzxzn9e2?1q00000NkvXXu0mjf DYgU%k literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img2.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img2.png new file mode 100644 index 0000000000000000000000000000000000000000..022cc6a0bc1d2a79493d179c99d8c4c4924471d7 GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^LO`s*!py+HI4hJj1jtbd@Ck9eSqp2OM?7@862M7NCR^GJzX3_B&H?< zH9SagU}803vu2h`Xi4IEz_4(Kdc%pl9IXOo#*SFFgf8A3A>$LAI-DMA!Q3mvm2M=R s<@mOZRbbXm-bXUiR!XnPHe_L7NXcUVTK#DnJJ4tbPgg&ebxsLQ05*3!p8x;= literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img20.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img20.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd4c942bfc89fcf1ca31cd3bc57a7ec99ad4eda GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^VnD3G!py+HICEP z6IxnYDk>^+a&i(95<)^kJUl#XY-|h+3{+H9BqStwczA%CUPYds2c#HFg8YIR9G=}s z19EaaT^vIsrX~ZmC8Qi+6*6f3A=gmC!1;`A&Mk)rOrOIQD(6l;$gtk%kHT_UpN&Ny zV;F*LczBo`y5@H#GP%rPn(WE&Do6dtLm9pWSEX;rH{AThrNhJXhF9U)&Yt~@JZCtW j3{rdE|Ic60nat3>S8&(gLtWfJdl@`k{an^LB{Ts5Hv3VJ literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img21.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img21.png new file mode 100644 index 0000000000000000000000000000000000000000..49c39a27762847710af4a4887c3abb0f11b5fdb7 GIT binary patch literal 614 zcmV-s0-61ZP)RHR400001 zbW%=J06^y0W&i*IKRl82yKomXp`hj;HdzFfU!Zm63574QH_*5UDtW}!7y35+HIUSefL zMlO9m4YT(6BO0A2KgIt;>ntu8dCg(A@)O7o(AZa+RdGRC|A6D7AiwGBc$ATj+>Kw{ zP7}@Zuoa^yZfLD8Qx$+d!<6%LdLJ1Rd?O;+r?>Qj;zw!|iN7__(|5NuweWAwfVupvuZfs6jwL);01Oz#Rtc0kBSMH@@jOlp|s-@CKne1`O(>s|*AG{f4aw0^T=wDOz!UV!ujRB6< zc6T}THck|5sTFv&MO^}OORg_{!Rv;-eWi$ zY6qJUHCJIh2aa8D0E1UFO5$@dXX>%)1<&Z;XaF8riE+YcnaNlKdKjb-M03h(ZVuSJ zQK*LM@o+;h+DTsu3k-*cV#Z29%5n95Dp}bG@2_#Zpf8P&KX%M$thBzEY*vvFrYbSf8`Kt)>05d&Fuo_USeAM&=-q-j-<99mbn~dm^)lfE_+tWv5IUC2gt~S7;)I-Myni25rhdc%8FAy_;P1xQ zie8+Y$N^sVU$bWl?|dcST8yJIizf;53vvc&^ya2tPQDDJ(n$S6P&_P^gd2Oy3Dg3` znTi?5k)o&Do)0x^C&N-@ZK5>OK`0X}7J*eB;!Gpt=Zj+RQM?%uxUUobkYs&NU5%AD z#(BjlR?gE($ehOIRaOZ=Y63s6AhzwSNY$@Cb-ylLEJI=tQd{HD3`&q~`kp`epVXFL z{h0pXeT3H2Ge<2{%#3Qo9A}2-`r8~3+(GK5z>pG-K-Onp9Gwg*W#-90mcg=YJ8YUG7F3ve82K}jA2~g}(bARxMz&p|(e}Geq_n?{ zeIeC({iaR8BXB@50r871KuiqOG?2O+Xgde>L+N8QcD2odd$83*(Q=)PFFmP^Z>}zf zVset^iiJjg0Q*P8JTP{hCKO0d-XR)z7@re4eVJE&Kh(Q2{D8;|Nx-i*;AytHj@v_i zc!U_%t%^pk3r8PKrPjvBWCEmW?Ihh`L|Y4MzZITKy-?^^S~rtHv=yka@Y^l_(Z*)E z5KW6>8MIwD#LOL~hT;9@DG|3!}cQU4AY6kBb*DieI zf-OeQ%IoJ9?Vro8FN`Tv!};qF$X^xvN$S>C813CQE70$Je~q>!vUzl$FezxYkgW#2 z=G3RH`!v5d5wC3oIxqOup7MF{BGt3H#5X}PdR6W}@?E}RH_p{G*x3bmWFYG9BO8^c z&SHgy|1fOY1aC&6$53Gjy#a9yNHJ*o4eqeng`_XWY&~(YBFp%`B)2_jD7svFcYmfn zyh$f-l1BQ&dQ1>}bDvZ@Sp#aBV~nVZ9A*hwhyPG6HG9vWDO>1hR#9%@XM!bS(U5lHxF|#GV}tOjjgApvYCucQZvS@Yw7A{KDTjh zF7TIAUBUm*=TtDy?N~(#KE8S#9CR}ex&Os$0qzy533{=yvmf{ABm3z=2G>1z+ZW7; zTrczZfL~A$ShwxN;!nJgL>D7r)N5$@h#ak1ZCK{oklci#q7Auh`V`H*l>8jTi0bht z???~YVDt3)q%WWr{pu*Jv%SF1v$kHOEdC08ZSFgEu91tu(g?)~D;7W75pcDpGviK( z3b&%hvwvS7Oe&4{7pm19@vx64^b67H$BMbGjK5gVD0FJ^;uY68&w0sn2aihiy?;>w ze+H*U4QODdcQt~$I)8PHf=}66&2lQ+xdoGY(LdcKiC5u?r!vHa08$H2nKp}`!LSKU z@*8ztMi&!y=M@i)G+_^W0qNyNK}p4a+wA7iEf;1W` zsP;GXcPyMDQ}g2}-?*HG-jLR2kCtv4@_}Egg*Q2}4~UALn}qGC;pY^xzsKW#V_nt% zJjNWM;M|a$#FErd70q8>lZ?K^vOt99cl^tUB)-Cud(tuQsF1ES`_f_bMF5I>QlcjZ z{9^rRBH8_VP|u8Imdw9b}FF1XP?AfJ=0k zfruGQ2Fd&BM*h`MN*6yxwM=YMI1qxz@}O3|Af4Xrn>O~Pz(bmR*qaps_wwYR8{@9} zGCkB5bTl?j@^@fg-OqzRNf(buCf}i`BsyjZoTeCGkh?mbv%zaW=1M-RE7SSTQmLus z!S^;U-Mgn+;_2B{a4+h&E7^PLlAgEAy*cP7tZ5l|&yuJ1deJi=!2F~|mL+iu+ z(MVIhbKKyAi!9&AYetPV>j%%VrbzQO=`bebH36bs-drZ^F2Y0U6x`kfRJZ+}IWuiK zyhDnKiF2!(9K>5LH?V~R^N6Pd_@l2tvFI=M3jDib`l4X}Gg7q+nEFmG=0hF>`z^9u zy=0G)M41DIL8^v*VQ|#EAkmQ#Sl?);nZSz&7 zv=;A=;nLKRVzI^SSARE~-bLx=wKAVL->WjkoWnrw)d$#(`{hk{2i}b0E!&_#;*lH< zJ@YW(C2IKJ+#A%Yn;L0`oW&j#sY0cO^n$iw*KedYdT2L#OU4<$(74xHLxa>TF0f*p zdZ&@s(y*k$a-3?2(ebA;uefh#_nhbp2J-d{LMSHBOSb$kpbtmeH%%jb6<7SOm|j7j zH(OGTi^Be1ughBnb;aNa#lp9qZf4s|-UjGJ2Yk{9*xl=psG)XW!$ngwZn_62$L@io zvO)=?ZU~zuq|#D}WD7XfQ^ZMX8SZd>TM)TDrXkkzhyskoE-sx@2BPxr?jVU;7$(iC z@G#cGfXWtQ&FIeqtiKtb-5mo{^vC4g^f(|EPpz$PdFUK&Fz)1|o(r>Oj5C?I6Kjs= zPv1bGM;zjxZK#4kkW4;^eP88R0H5Giv~t^H*C*;M%9rHnXVmaLMqajI-#pfjDK?nj zLF+?98fX_7+9~5$P4{`WZ1fPZf~oA7QgR;N>qlp!MDK?@;*Ks{$KIdOVTOxuiWeuW z6Ga=(Y!4(NNx8EGKZU;i_PfFu2mRR9CgpnXtuM{LFx#S*K_3kfpL-SO~asd$tM_Q`0T5!WxA55 zf>Er7oEfwoGcma*`W{lMdR0XE`XWzjhf>8z$BBkigcsQQ!x)mGrc|2X!@p>Xk{<#q~8 zKPNx26n0&WSha^fzCce*Xnqkcr zN(*EOJv3e+%VDe{w(uVF#0@p`4m`CcAHe0dC^-$+8iMIQaOJ`Qp}^UM1t?uhYFMIe zwfVaLhb?=5cQ# zF@y9RXI=UwYo!V8nHwzGk{ggc>UlfccVHJ0Qx>ts@^lz4=HkS)(=F9C`&#?n#Om-x z2a}yLoz$(HRptTXktMj3fj4UG232z839T-!HbBM3}x7oKZ|!b8(HW+-m;W z*8+GS4I(5)P9d<$*G~jdWisMM7!;SQ^9@)t4aPt2T8H;at6VuFqEU0L`MkvM9PC5A zpN@M3%kf?m-7f+^rl;T5GN7=EVxX@82T@qhqb8(m4+To(U!udu84mJzi+@6$Aw+1b zkD~JS;b4`F9LRXcBA8p`otVl9N@ODZoiiJi_P_n*@^LuMxX*fUvhy*|#ep5#EiPf& zgSm%s0vWpn6HC8rr8D*OcD)z;ct{s2^7>lVErfc9+WwxW|A?A*{qF=KR3C|@%f

                  lnIoJ6UeWfl!#R{L6t(hB)q|}^BP`SG} zZHsc1FwMvt^SW)Amg5fF?-Ddn$l&+VtQq@19QEm!DV0am@_-6mN#|^8k#y7wT`2SQ z{|n*YR(UFBZ_(sK>LzA>_=9no#rr08wlk`!XKr)Zy;e)fOl*i*dJcDOBtA zrsZl1>sM;PwO_It&Dui zU+ZxTOjar!6|huubj`4!6b@dlMB*gV(BRKxL8fog{AEVeyD0MOgIh&&+04*Be*bR?v4^Ds~2iL&U?(}lnq7$ zY+gP;Gv7(@Ke+y8E|Xl28v!<3%I)godA5^R{2@J!V=p}s7byS&e!4bodfU2-R(Adk zR|Y>4C<0?hoyCc~3UDuvM{=IWe*j*W4fMTscOpJNyZ?>b5^&qjNh{95$Xwr?^DEe? zDP46r6v2max4U(G^hIsacg(^!c;%-O$qwuWxM^um)nv_Pw!R~Boq#U;{047O1B*S!&O)#c zGMCdHRx(?AXF1xict24t6}D>F=Y3&kO$nlXH(8HO;}7}x5Kf2kvwpfsf|%O+7C4L8 zfK0vL&vfCreqtCC&8^JQj0ih(FaO=&Bsj zS?EsVfEe?Y9L-ZNp)#QzG?3szY318B3kf{2*(O8`6VH5pjEsm@im@u8=8N)5YCOG^ z*7W^dX_^eCRI0WnQ-!A@>LPcPSZUN?kjWX7jJGBMK~zE6JAOj+tmlzwZIC zR?gQJy?$%Ixif(SlPJ^Qyy1%i^=Or!qI{}oFy53S9u&AQ<*Du5M+KQR4!yV)0~6eG zFBVYE;2t4Mmmjttd`bEpjS96q_qJQg{T*4D?J7%J(KiJ-#j#8^dYQZ&Q znX?W-0;{Y0>kl+39S&^f&c_Ttx*_LU3RwDoa2%h_Y()q%pVWduJIFSuE}MTqKR(2~ zk>`IUz<@!AqWaFc+7k+yK^DVkf#QVGLMFWAPyHFI9A^@>q-u^<_&d%n zdE)bH3VTYPPY~Nd3-tyaNIV17D+JeaAeRJbD0ec=f!{gFH)qip$0oCb#&{4m$RqA< zni;!yLY@~rM=4F+Cedp2|Tg3Juqg;T!I(pcj^PD+~Uo^l*B z{aHgt9Oqu=cpld~QiP!NdkMnW%sH4hZD|F9Kh*P9f{v7y&z5ipg{6o|PQ(^sS%fHB zeqx0xP`=#927!xWk97U)FpM;VXUC__?qHw}-e`^nu)w6i_PIQr7jf~gGf&mCFHspwW-gYYP zMlDZ1tKSe^ite4w!%WR1tkP!3mcA2>e(5>@fl0`l7PlYh?wzvGt}m`FdAe(&d}^+C z?iGtJ6v1YOU?(6saX&HYQC!eg>fZ4XCnF*u5cjQZQd&e?jc3AA4xx604-KV=V4;)_ z+8N!yEZUh0vpx{edhWFI!=)%~z{mxCl3c#umx8~GaQYo5*?WB zE1|*rb$ZUCZjn!JoROf?jFE9h={NctaWt_26K1eC>a4$HsLGtKCMvLoX}o5b*2^Ye z5JU4XnPrRMPUtMO;FI6s@5~j2{S~MKk_pBcg^^~|8Sye#f$|7S^bRB z;CO6rOt6fj0?WKrxzjBHR;e)idadD@U9N!VlhW*$5=O|QM{a*J{gw=H28B3LC1QSn zuSb1>{A$a?^u5w!kJI=R@U`NTY$_4fjeQO408c^Ys>M2c2lUE3S8ns|cEd=oa&re9 zc)JRUiWL*Y<~#2$>4)%CJec|A$E?Pma^%gBoLUP^|eA5@(?+bx&wE#W|kw_b)n2(6;=_eNYXY;9xEN@&|N;= zNJY&rq#XHcErV?G!58QjkSG&)gg|`%eIW6l(!oZROo6A2qf%x3K^}kfRSbpjYezgH z8eB%R##cz5WRi5u>wX;El%-G4bC&l&70A-w+Dwl68L7}p_&eja{9EFM{MwyW!0Y`m z_e1Neara4p=gZxN(duzBJx&Y<%aLcLP{7dafHnL&QfQk^-wLtc$8MCSDKQQ&x+7wr zDE|o$M_x6bAv-St$IaaZkb3B;NHY2kC04y%58*jEHtF}`Ux31q`>2Ru39=kLa+NeI zy+UGQDL#!As4x4-uNmBiWUKwmD!u&Gdj6#6>8_MpqnoMCT zlDjxgms>I7j?!-KS_d6Lc64V|u|sJX!&VQjG)&sBTDA0dm(x*6S)oaN!pBBL1E(at z?eD685VkZfr8YPYr*yX!IN!6!E9?^@lCn1lG%V$9n z@~&`Ej%#xgTHo?@4ydTf9lV&EQzg*2s$ag(UAlK^X>L$=%~!$~Bz*xpIf{>$O(b*IV& zeZx|6B0;QZkB{$p_w->z{fEL9^`-y!WdDcwztWHmpTHO<5^tZF=mD~|(@)9rwjgxz z(*D%$+dDkiNRZm)T-NjOl(3_4rTD`KjYmF#@8l_mqGuMk-J6+X>h9{f$GhP)vuI}o zXh+Guogh@>Tto_J~`7B`z`3aW>G&4Vo|^Ad<7Azc)M(~ zprSnz!6VbdDIZh}{So?3+*z@xuVBvS1c{L?JvI6pM%Xgh2P(p_{qS^jQJ)y1*Q1ZU z3a`xP@(vGr_}f2Aa`0`xKeY^Rm5?86|H z`2t$r%m(Z~DCVtCT%e#zC_M|}Gp1$>Kp~hXW=genD!l*TK-8P7#&td@Su~%)s9nqR z<+|PEQN;I@Gy&Y|cg(dm^3FGpBB9@Pm+x-pK3n0i2|4TQNoebOwX@G#=c^~mC4bnQ z@v9_T9pLLTc^Onr(l`6=epMH&1rZnBu14rb%46v2QX$fS8}lo8QQy~@!S(h(%Y_U? z?l%7y{PvD1`#d_oOUKWRHaKJeE$Ry?d>^DA+n&z_sY$tBki`D&4o6Jh&4 zFPfJOX2#3~Z3HJ7;}_8l-;E`nB`)f}B%Y(8S8zdAwA-6|(HBttxm)>??2oydMt*d+ z0<})LW$f!wQ2@#&Hw*pK{jb-fSgVaKSlU0lQrfWx5E`}lsrP%Ng92RdGJ*`(s zA96J)7{$NGfb=jL4`=<<0J5gm_DH02syGcEy9m(>$mC+t9ZS$BGDvK#qu>f_-ByZl zXZrrW@%U_mSQO z*(D{m^K~AXQBp8WQs*jN7lFjG${tbwwd>!3PPvF$LAOv_cMU4bC)cV0%4aqw6B^$4 z-#$Lb&^{jEJ1q+1CQlKqC`!>DinIguo?%5Fz*?ZsB#`A(*07fH0_*o~gdzdixPE?@ zuHyh&Bl0a0ZByZazXBuWv}zCTTnZ;0e|Qtc1B%DbY->U9k6@|uJCIQYcHxn zg-LL#t7lS%<`zrXR*2oL^8ak7d}0x-=0l7$1_lX*@jt`cWKTe>PLGVsTpT?G?Xmsx zX;Js`ESiKA5o+XFF%ikDiNbyn!`IWSr${EA(Vx(zBGtvC@Z*OSHP~N=`$M*g(kGXq zfwqLe`g?%ahHXsts7_uTMNp=TzVW9-?OI+8K`0z_FRyTH$Y znGV@`Om(q2%zZi!%h7OXUc&&zK1^k?6F=D$gQlLeNN4`N8jfENpOZD1yWu*0vDh+o zOX;SVFC*&m+l_<^lhb@!8rSS?B!*fv=zTz1>aRtwg=d=^G%cLody{#GYv_Z61zubO zQBGi?{*0tNeB4P3#{pds^=b15h6dzknC1nulB-e&96la#JlcuvzS)Rv@31#^@!i9a zi75KvkVfT-zDugCDJ_0UMc9#gvmIyZfacGC)qU5Sdg*xn;vgJPg>Cp~2E`Rs9S*Lw zo%MksEbQghsxk`rbU!yU`taVgZop~o3+Q^SZ(lxIl;Oai@p$fmt?tG7D_3cp&ak|$ z=$`wp8@b2?eXp_yD26PhImjaQ$Mm&yuS=y9q1{Hc;O$#GtoA~FK3f7cdjQfC&BL_I zFjCCzs1d&)YudRqDwp(^rT$h4P+s|`IxhRf@J6b`3qi$dL}w!5`r1KM2;mFaY06L> za6$m`Y9tOpXXOsz`cu(fVfI9_U+H_SBd(EKaEP?e2x^tSL1ZH_H%m%Lh!_aWi1;0rx%jvYL$ zzzDIg&1Z{0hHGM!DTRvQNT9MK9J#L9jJjiAc5CtOcXoXdmA5z#9K{a!9tUK)K({NZ z(f6F1gwZ`dgj)}05WEWb9_7>7+C^B<7FYNf+_@UjuNfH{v3+?;i+BychT0QQhaU)A zEgk-P4t9_X)d%QL=-XMG{{+^zrxid?)y0r9$F4f=-oGvzvh-OtARPhhN;r8Q)){`q zS+7902S_{5?4Y)ory|Q&lFMetE^+hEY0^_-uN_8l$WbtZBEHJ)D^Irj>U{ zUcPViYm6WoByPn}yq1c@AHjCe?9ckho8d_$k?>|Th9nwCV>guj@kAH$m~w+h#Il8; z@QxvuNtA!~U97cpy)!2P6Eek8>VNBM^TE#F8e2csEszxG9 zoJ4St_je*E;G)W8`BxMG`A++DuVlhXvjR^n?_}ny9I`!)@qxD*N|n7ClbTfv3dI}H zkcd@wQ_nH zW;oBv2l&^Xt*Rb^a+A|vcPmV!bNYe#6TWqIX0twjnO5|3Ze7Kv7u=Dzz6^iubw6>R z#Phtnbv@LKEC$k#_8O7oE*vgT;9%L|+Vq-0{zC>RJOV4mJ zu|4ZK-(Lb}bHF9Wz0p2#Sf#2Zq?%~WD;nb+2I3mFB$PAKRU3B&QI^}b;FjIM=etoT z(uuhR)9?+BsCV`vAbHErXsf~Hg0PaaC8fEYNCLL2=X8&o)94meh$=#uqynKc)0%^1 zQj~>dov2-BhU7&}+l1zC)2W(}sU5_YTV(L>X?rxQnw6Z&qDufHyi$_sewnGO`u0}K z>7FlZR(9_j92=h9oemkZcmgJu8aC#IbcyaPW8DPZ7uj&3Oy*<6f+yK_z}`88fxa5HtR)M}VjH^~ z9OshFXX`tXnodEkvDLv~l;!s;OLay+doz%2K-m@VJ7GDbMdN{utPGhkbT~T8O+iMCq^i?AX9!~Q>7J6` zWZsvqiMdYXv#*%Lgy=f0Bmi<3tK73nv3Ah$QmKlaP-Js@gBcNJ}#=KKVhEGT}bnH>39dF zE*v|0>o?3XiKwX2Rk>V*`RHtNh{YrSKAJ9?;(Y3 zSUTfr&dEGJb41lUce~nN-m#VDeDC1d9^QiAKHcvKGwxZqN|LXN(2eI}3bv6u}Rk%3>wxLHt>P`z&2GFd0Tf3uvh&#-9DrpyH z3sY^FRgXhv-2lOptf^9^R^G_uYQRF|BUY8$%0+Qg3-)eu@nNj>Hp02Vb5@s4(SwUa znE0+g@gsTWFha67UOcqCn%_n1Xf(4P%#m7d=(Y3eNa*gL z+1B~N`3PQNh45^Mi&&a;d~>MrzFWMsmMQ@@UCcU(y1YkEhxOOnd3wKhvk)~bIo~wL zdB1hXk7mME3n$@EYg{~e`Foc88|_IYBBiK$x;?hK3Mq!b@ec-KqD~6BmcMq@DJ5U8 z+&|lrwO^eB0_6gsmJ5Po1Uw7{mSxG&`}3@S+2t@?=Cw>$Bv~geeq%TJo?=qJk?`F2 z=?nU0VtqvRljk9#-gj|U@925k5d5Jv*?KZYvUYE{F8p=&QUmwoIoOix>_JRe|LZ)t zRVuFP>l!=7FLV>BJ^RHL>oe~bIe-`n&Y&V6*QnS!0_gAia8^Fw9+Xu^Io$kqV*w!} zQv6a37B~Fn5mKdaUA801kko>rBni zq-x~0J9(E4eP)}8j1IZ@951*z(co1V%_6PmE-A8);|j4_e0_p0yg1D2%kNsD6Uo1j zGpWmQ6j`%`it1wkemBAejzMD0UQL9Xb7`6=_PUFoR%u1AD1^&vGYk4Wq25?b2`!d4 zbLgeR!xUL=Jo;kMm7*e|enQf{yjW(ye`3gQgHzgyV7L8R9oUWeIJ-5;&#lYx4S7s9 zo732%zsJc!rv8LdQ`~;zyP0wrRv!T{I;oQ4ZNXIgKD(1FlH>73N(Wy&`{x!5?PVS! zG7Zr0y$)rIG2{C!N8+7UgKzS|T=1HMrVc-ec(Ph)5dW)v=C_Ky&~1Aii56QMIuz_s6}G@5s2N-pT6TW0}eW zqe^WRdQJP3Ua5cwT)ZfzLTgt_-=J`P`Q~!_i%rpwTCw%UzqmAGPzMjD%nO(4z(a&k zS8rgWR=bVjr#-4g*SphN)?Bx3ZFmzn?m~-lyA|iu!_2DiWRhHztm*5+wa^bfEF0g5 zja=#@Woy55` zGEWP!jiBnmUzi-#2Z6zop>Hp4Q|^o-6==dVcB-H8k&81ZK zF(}1UPum9>PO}Cez9IZaIJ-LqYd5z}N>%W`XA7*+_>HwA=w`R=k9)|&$I^#K6BHKer@iC{OxYrkl= zrApV1)~>DzD{y99hbLmAZ$ynI`)5~c*OZ(4^$k~6L|HBMkUWVCVV;_bhex&8ic7Ah z)Uux#W-{7AjWXz{h>B!fn;L)0J{es*>0DaY-_0XEhw#7xN#6HycAVA08H+)s&sZgp zYpKX@guf9jG^RHR400001 zbW%=J06^y0W&i*I4@pEpR49>SV1R%RZ~_Hz!3ivYAE-kBNQ1Bg4mDtqz`($0z`zMI zzW~T(@`s9ZVjOy&j}U(zy?&pAi)m}@(W;6j9USscp_Bqh6~}K(ER}ALNF4S z1;K?H!N5xsUr`A#w=1CVEhZvyfF80{r~xxM{(Jxnu)Xhn2a{y_!oaZr!huLKL^8BN z`0@7&bASH2`tvH!$#j0LjB88Fx9r?UZ9+!!Q=vL6ZNEGO+#w2K4{` vUoa%WAPQXo?EXa%?@oa7Sx#UHjKL28#KSt56Ur~300000NkvXXu0mjfprn~E literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img4.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img4.png new file mode 100644 index 0000000000000000000000000000000000000000..a709c3fd21312df2b667fcf4fe306de3cad16c5b GIT binary patch literal 204 zcmeAS@N?(olHy`uVBq!ia0vp^{2`Pl)U0&6`)OSTSeLoCy;q zw6wHTR8-{T5)u*<5;Pc+*wh5LS$4=uNQfIKFqWB3kcwku%W1gSEbU=Zz%Wx>$l;aMMlI)t ySx0uxb~KrN!;LMnqm_{-`aq8kTi$XeHU^7#TpRHR400001 zbW%=J06^y0W&i*Hxk*GpR2Y?GU;qO)21W>jfeVUZfS&;k{C)r=5*R)R0I3gP5he$8 zH4H%Gcqf2$bAY)Y_<+RzeZL_bUQG44K>^r7@d9uTKSRO-5Stn7JWhrUKn< zg@I!MT!$$`15ASV0|Va&1`NQ@!2baxhed)7$tVQy|Nq}X^8ZmZQ2<3vEJklyxX%Cp N002ovPDHLkV1iYGbMOEF literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img6.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img6.png new file mode 100644 index 0000000000000000000000000000000000000000..732c334023cbfffcb41fb9ca5d7c46ee1e6b1404 GIT binary patch literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^AT~b>GXn!-#I@qpK#p#JPl)U0&6`)OSTSeLoR*fB zii(PyoScM&gpiOB4-XF;8yf=y0~Hk&2?+@v9v+~M%!7WqK#H*>$S;_|;n|HeAjitn z#W93qW^w{UGn>Fc9wiIO9}*K7)CI09eB7xhqRb)A(0SP54~M56_rV_4lbf|{88%kR fI6O%#WMlXLmz$e6Y^XAPfR;-vaXU>EP z6IxnYDk>^+a&i(95<)^kJUl#XY-|h+3{+H9BqStwczA%CUPYds2c#HFg8YIR9G=}s z19DnCT^vI+CMG8^Fy*m@TsYuh^dKoAVfTRp2hJZjz_rkWJ;8TVkH;LAX>2U*Vh#*m zpB-Pe&wn^=qv|JRoqY$I66ANVBs$A_SsxE%Eco-YL5-zGiSnt z2`w!x6%`dZIXMXl2_YdN9v&VxHZ}$Z1}Z8l5)u+TJUl>6uOd&+15%77L4Lsu4$p3+ z0Xb2gE{-7*Q&GgH_oZm^+o=b4C5wuTOV1trFg{G?E3_KgaUm;^pIml$X< zaF$IF;O}_ADk%O@xIZFy7rfdU8wI%-n7Vjk%e{lv Q0BvFLboFyt=akR{0OjmNw*UYD literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/img9.png b/resources/3rdparty/cudd-2.5.0/cudd/doc/img9.png new file mode 100644 index 0000000000000000000000000000000000000000..1a46e4c82bbd694875097987add2292668562096 GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp@K&-&R%)r3t^WnZBkfR&m6XLpg^X3&RR?L|*XTpRD zEiEk-6%{!-ISB~~At50i9v(I}HU^GJUl=hf3lAN^)oP*1o;IsI6S+N2INF| zx;Tb#%uG&5c#!-c&4F>xikNFmY;8bP0l+XkKcWg(T literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/index.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/index.html new file mode 100644 index 000000000..e74c4fff5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/index.html @@ -0,0 +1,219 @@ + + + + + +CUDD: CU Decision Diagram Package +Release 2.5.0 + + + + + + + + + + + + + + + + +next +up +previous + +index +
                  + Next: Introduction +   Index +
                  +
                  + + +

                  CUDD: CU Decision Diagram Package +
                  +Release 2.5.0

                  +
                  + +

                  Fabio Somenzi

                  +

                  Department of Electrical, Computer, and Energy Engineering

                  +

                  University of Colorado at Boulder

                  +
                  + +

                  +


                  + + + + + +

                  +
                  +Fabio Somenzi +2012-02-04 +
                  + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node1.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node1.html new file mode 100644 index 000000000..2398d3652 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node1.html @@ -0,0 +1,174 @@ + + + + + +Introduction + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                  + Next: How to Get CUDD + Up: CUDD: CU Decision Diagram + Previous: CUDD: CU Decision Diagram +   Index +
                  +
                  + + +

                  + +
                  +Introduction +

                  + +

                  +The CUDD package provides functions to manipulate Binary Decision +Diagrams (BDDs) [5,3], +Algebraic Decision Diagrams (ADDs) +[1], and Zero-suppressed Binary Decision +Diagrams (ZDDs) +[12]. BDDs are used to represent +switching functions; ADDs are used to +represent function from $\{0,1\}^n$ to an arbitrary set. ZDDs +represent switching functions like BDDs; +however, they are much more efficient than BDDs when the functions to +be represented are characteristic +functions of cube sets, or in general, when the +ON-set of the function to be represented is +very sparse. They are inferior to BDDs in other cases. + +

                  +The package provides a large set of operations on BDDs, ADDs, and +ZDDs, functions to convert BDDs into ADDs or ZDDs and vice versa, and +a large assortment of variable reordering methods. + +

                  +The CUDD package can be used in three ways: + +

                    +
                  • As a black box. In this case, the application + program that needs to manipulate decision diagrams only uses the + exported functions of the package. The rich set of functions + included in the CUDD package allows many applications to be written + in this way. Section 3 describes how to use the + exported functions of the package. An application written in terms + of the exported functions of the package needs not concern itself + with the details of variable reordering, which may + take place behind the scenes. +Click here +for a list of the + exported functions. +
                  • +
                  • As a clear box. When writing a sophisticated + application based on decision diagrams, efficiency often dictates + that some functions be implemented as direct recursive manipulation + of the diagrams, instead of being written in terms of existing + primitive functions. Section 4 explains how to add new + functions to the CUDD package. It also details how to write a + recursive function that can be interrupted by + dynamic variable reordering. +Click here +for a list of the + exported and internal functions. +
                  • +
                  • Through an interface. Object-oriented languages like C++ and + Perl5 can free the programmer from the burden of memory management. + A C++ interface is included in the distribution of CUDD. It + automatically frees decision diagrams that are no longer used by the + application and overloads operators. Almost all the functionality + provided by the CUDD exported functions is available through the C++ + interface, which is especially recommended for fast prototyping. + Section 5 explains how to use the interface. A Perl5 + interface also exists and is ditributed separately. (See + Section 2.2.) Some applications define their own + interfaces. See for example Section 3.18. +
                  • +
                  +In the following, the reader is supposed to be familiar with the basic +ideas about decision diagrams, as found, for instance, in [3]. + +

                  +


                  + + +next + +up + +previous + +index +
                  + Next: How to Get CUDD + Up: CUDD: CU Decision Diagram + Previous: CUDD: CU Decision Diagram +   Index + +
                  +Fabio Somenzi +2012-02-04 +
                  + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node2.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node2.html new file mode 100644 index 000000000..f36d7ec2a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node2.html @@ -0,0 +1,175 @@ + + + + + +How to Get CUDD + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                  + Next: User's Manual + Up: CUDD: CU Decision Diagram + Previous: Introduction +   Index +
                  +
                  + + +Subsections + + + +
                  + +

                  + +
                  +How to Get CUDD +

                  + +

                  + +

                  + +
                  +The CUDD Package +

                  + +

                  +The CUDD package is available via anonymous FTP from +vlsi.Colorado.EDU. A compressed tar file named +cudd-2.5.0.tar.gz can be found in directory pub. +Once you have this file, +

                  +gzip -dc cudd-2.5.0.tar.gz | tar xvf - + +
                  +will create directory cudd-2.5.0 and its subdirectories. +These directories contain the decision diagram package, a few support +libraries, and a toy application based on the +decision diagram package. There is a README file +with instructions on configuration and +installation in cudd-2.5.0. You can use +a compiler for either ANSI C or C++. + +

                  +Once you have made the libraries and program, you can type: +

                  +cd nanotrav +
                  +nanotrav -p 1 -autodyn -reordering sifting -trav mult32a.blif + +
                  +This will run a simple-minded FSM traversal program. (On a 2.4 GHz +Pentium 4 (TM), it takes about 0.5 s.) The +output produced by the program can be checked against +cudd-2.5.0/nanotrav/mult32a.out. More information on the +nanotrav program can be found in +cudd-2.5.0/nanotrav/README. + +

                  +If you want to be notified of new releases of the CUDD package, send a +message to Fabio@Colorado.EDU. + +

                  + +

                  + +
                  +CUDD Friends +

                  + +

                  +Two CUDD extensions are available via anonymous FTP from +vlsi.Colorado.EDU. + +

                    +
                  • PerlDD is an object-oriented Perl5 interface to CUDD. It + is organized as a standard Perl extension module. The Perl interface + is at a somewhat higher level than the C++ interface, but it is not + as complete. +
                  • +
                  • DDcal is a graphic BDD calculator based on CUDD, Perl-Tk, + and dot. (See Section 3.19 for information on dot.) + +

                    +

                  • +

                  + + +next + +up + +previous + +index +
                  + Next: User's Manual + Up: CUDD: CU Decision Diagram + Previous: Introduction +   Index + +
                  +Fabio Somenzi +2012-02-04 +
                  + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node3.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node3.html new file mode 100644 index 000000000..d91378b2e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node3.html @@ -0,0 +1,1637 @@ + + + + + +User's Manual + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                  + Next: Programmer's Manual + Up: CUDD: CU Decision Diagram + Previous: How to Get CUDD +   Index +
                  +
                  + + +Subsections + + + +
                  + +

                  + +
                  +User's Manual +

                  + +

                  +This section describes the use of the CUDD package as a black box. + +

                  + +

                  + +
                  +Compiling and Linking +

                  + +

                  +To build an application that uses the CUDD package, you should add +

                  +#include "util.h"
                  +#include "cudd.h"
                  +
                  + +to your source files, and should link +libcudd.a, +libmtr.a, +libst.a, and +libutil.a to your executable. (All these +libraries are part of the distribution.) Some +platforms require specific compiler and linker flags. Refer to the +Makefile in the top level directory of the +distribution. + +

                  +Keep in mind that whatever flags affect the size of data +structures--for instance the flags used to use 64-bit pointers where +available--must be specified when compiling both CUDD and the files +that include its header files. + +

                  + +

                  + +
                  +Basic Data Structures +

                  + +

                  + +

                  + +
                  +Nodes +

                  + +

                  +BDDs, ADDs, and ZDDs are made of DdNode's. A DdNode +(node for short) is a structure with several fields. Those +that are of interest to the application that uses the CUDD package as +a black box are the variable index, the +reference count, and the value. The +remaining fields are pointers that connect nodes among themselves and +that are used to implement the unique table. (See +Section 3.2.2.) + +

                  +The index field holds the name of the variable that labels the +node. The index of a variable is a permanent attribute that reflects +the order of creation. Index 0 corresponds to +the variable created first. On a machine with 32-bit pointers, the +maximum number of variables is the largest value that can be stored in +an unsigned short integer minus 1. The largest index is reserved for +the constant nodes. When 64-bit pointers are +used, the maximum number of variables is the largest value that can be +stored in an unsigned integer minus 1. + +

                  +When variables are reordered to reduce the size of the decision +diagrams, the variables may shift in the order, but they retain their +indices. The package keeps track of the variable +permutation (and its inverse). The +application is not affected by variable reordering, +except in the following cases. + +

                    +
                  • If the application uses generators + (Cudd_ForeachCube and + Cudd_ForeachNode) and reordering is + enabled, then it must take care not to call any operation that may + create new nodes (and hence possibly trigger reordering). This is + because the cubes (i.e., paths) and nodes of a diagram change as a + result of reordering. +
                  • +
                  • If the application uses + Cudd_bddConstrain and reordering + takes place, then the property of Cudd_bddConstrain of + being an image restrictor is lost. +
                  • +
                  + +

                  +The CUDD package relies on garbage +collection to reclaim the memory used by diagrams that are no longer +in use. The scheme employed for garbage collection is based on keeping +a reference count for each node. The +references that are counted are both the internal references +(references from other nodes) and external references (typically +references from the calling environment). When an application creates +a new BDD, ADD, or ZDD, it must +increase its reference count explicitly, through a call to +Cudd_Ref. Similarly, when a diagram is no +longer needed, the application must call +Cudd_RecursiveDeref (for BDDs and +ADDs) or Cudd_RecursiveDerefZdd +(for ZDDs) to ``recycle'' the nodes of the +diagram. + +

                  +Terminal nodes carry a value. This is especially +important for ADDs. By default, the value is a double. +To change to something different (e.g., an integer), the +package must be modified and recompiled. Support for this process is +currently very rudimentary. + +

                  + +

                  + +
                  +The Manager +

                  + +

                  +All nodes used in BDDs, ADDs, and ZDDs are kept in special +hash tables called the +unique tables. Specifically, BDDs and ADDs +share the same unique table, whereas ZDDs have their own table. As +the name implies, the main purpose of the unique table is to guarantee +that each node is unique; that is, there is no other node labeled by +the same variable and with the same children. This uniqueness +property makes decision diagrams canonical. The +unique tables and some auxiliary data structures +make up the DdManager (manager for +short). Though the application that uses only the exported functions +needs not be concerned with most details of the manager, it has to +deal with the manager in the following sense. The application must +initialize the manager by calling an appropriate function. (See +Section 3.3.) Subsequently, it must pass a pointer to the +manager to all the functions that operate on decision diagrams. + +

                  +With the exception of a few statistical counters, there are no global variables in +the CUDD package. Therefore, it is quite possible to have multiple +managers simultaneously active in the same application.1 It is the pointers to +the managers that tell the functions on what data they should operate. + +

                  + +

                  + +
                  +Cache +

                  + +

                  +Efficient recursive manipulation of decision diagrams requires the use +of a table to store computed results. This table +is called here the cache because it is +effectively handled like a cache of variable but limited capacity. The +CUDD package starts by default with a small cache, and increases its +size until either no further benefit is achieved, or a limit size is +reached. The user can influence this policy by choosing initial and +limit values for the cache size. + +

                  +Too small a cache will cause frequent overwriting of useful results. +Too large a cache will cause overhead, because the whole cache is +scanned every time garbage collection takes +place. The optimal parameters depend on the specific application. The +default parameters work reasonably well for a large spectrum of +applications. + +

                  +The cache of the CUDD package is used by most recursive +functions of the package, and can be used by user-supplied functions +as well. (See Section 4.4.) + +

                  + +

                  + +
                  +Initializing and Shutting Down a DdManager +

                  + +

                  +To use the functions in the CUDD package, one has first to initialize +the package itself by calling Cudd_Init. +This function takes four parameters: + +

                    +
                  • numVars: It is the initial number of variables + for BDDs and ADDs. If the total number of variables needed by the + application is known, then it is slightly more efficient to create a + manager with that number of variables. If the number is unknown, it + can be set to 0, or to any other lower bound on the number of + variables. Requesting more variables than are actually needed is + not incorrect, but is not efficient. +
                  • +
                  • numVarsZ: It is the initial number of variables + for ZDDs. See Sections 3.9 and 3.11 for + a discussion of the value of this argument. +
                  • +
                  • numSlots: Determines the initial size of each + subtable of the unique table. + There is a subtable for each variable. The size of each subtable is + dynamically adjusted to reflect the number of nodes. It is normally + O.K. to use the default value for this parameter, which is + CUDD_UNIQUE_SLOTS. +
                  • +
                  • cacheSize: It is the initial size (number of + entries) of the cache. Its default value is + CUDD_CACHE_SLOTS. +
                  • +
                  • maxMemory: It is the target value for the + maximum memory occupation (in bytes). The package uses this value to + decide two parameters. + +
                      +
                    • the maximum size to which the cache will grow, regardless of + the hit rate or the size of the unique table. +
                    • +
                    • the maximum size to which growth of the unique table will be + preferred to garbage collection. + +
                    • +
                    + If maxMemory is set to 0, CUDD tries to guess a good value based on + the available memory. +
                  • +
                  +A typical call to Cudd_Init may look +like this: +
                  +  manager = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0);
                  +
                  +To reclaim all the memory associated with a manager, an application +must call Cudd_Quit. This is normally +done before exiting. + +

                  + +

                  + +
                  +Setting Parameters +

                  + +

                  +The package provides several functions to set the parameters that +control various functions. For instance, the package has an automatic +way of determining whether a larger unique table +would make the application run faster. In that case, the package +enters a ``fast growth'' mode in which resizing of +the unique subtables is favored over garbage +collection. When the unique table reaches a given size, however, the +package returns to the normal ``slow growth'' mode, even though the +conditions that caused the transition to fast growth still prevail. +The limit size for fast growth can be read by +Cudd_ReadLooseUpTo and changed by +Cudd_SetLooseUpTo. Similar pairs of +functions exist for several other parameters. See also +Section 4.8. + +

                  + +

                  + +
                  +Constant Functions +

                  + +

                  +The CUDD Package defines several constant functions. These functions +are created when the manager is initialized, and are accessible +through the manager itself. + +

                  + +

                  + +
                  +One, Logic Zero, and Arithmetic Zero +

                  + +

                  +The constant 1 (returned by +Cudd_ReadOne) is common to BDDs, ADDs, and +ZDDs. However, its meaning is different for ADDs and BDDs, on the one +hand, and ZDDs, on the other hand. The diagram consisting of the +constant 1 node only represents the constant 1 function for ADDs and +BDDs. For ZDDs, its meaning depends on the number of variables: It is +the conjunction of the complements of all variables. Conversely, the +representation of the constant 1 function depends on the number of +variables. The constant 1 function of $n$ variables is returned by +Cudd_ReadZddOne. + +

                  +The constant 0 is common to ADDs and ZDDs, but not to BDDs. The +BDD logic 0 is not associated with the constant 0 +function: It is obtained by complementation +(Cudd_Not) of the constant 1. (It is also +returned by Cudd_ReadLogicZero.) +All other constants are specific to ADDs. + +

                  + +

                  + +
                  +Predefined Constants +

                  + +

                  +Besides 0 (returned by Cudd_ReadZero) +and 1, the following constant functions are +created at initialization time. + +

                    +
                  1. PlusInfinity and + MinusInfinity: On computers implementing the + IEEE standard 754 for + floating-point arithmetic, these two constants + are set to the signed infinities. On the DEC + Alphas, the option -ieee_with_no_inexact or + -ieee_with_inexact must be passed to the DEC compiler to get + support of the IEEE standard. (The compiler still produces a + warning, but it can be ignored.) Compiling with + those options may cause substantial performance degradation on the + Evolution IV CPUs. (Especially if the application does use the + infinities.) The problem is reportedly solved in the Evolution V + CPUs. If gcc is used to compile CUDD on the + Alphas, the symbol HAVE_IEEE_754 + must be undefined. (See the Makefile for the + details.) The values of these constants are returned by + Cudd_ReadPlusInfinity and + Cudd_ReadMinusInfinity. +
                  2. +
                  3. Epsilon: This constant, initially set to + $10^{-12}$, is used in comparing floating point values for equality. + Its value is returned by + Cudd_ReadEpsilon, and it can be + modified by calling Cudd_SetEpsilon. + Unlike the other constants, it does not correspond to a node. +
                  4. +
                  + +

                  + +

                  + +
                  +Background +

                  + +

                  +The background value is a constant typically used +to represent non-existing arcs in graphs. Consider a shortest path +problem. Two nodes that are not connected by an arc can be regarded as +being joined by an arc of infinite length. In +shortest path problems, it is therefore convenient to set the +background value to PlusInfinity. In network flow +problems, on the other hand, two nodes not connected by an arc can be +regarded as joined by an arc of 0 capacity. +For these problems, therefore, it is more convenient to set the +background value to 0. In general, when representing +sparse matrices, the background value is the value that +is assumed implicitly. + +

                  +At initialization, the background value is set to 0. It can be read +with Cudd_ReadBackground, and +modified with Cudd_SetBackground. The background value +affects procedures that read sparse matrices/graphs +(Cudd_addRead and +Cudd_addHarwell), procedures that print +out sum-of-product expressions for +ADDs (Cudd_PrintMinterm), generators +of cubes (Cudd_ForeachCube), and +procedures that count minterms +(Cudd_CountMinterm). + +

                  + +

                  + +
                  +New Constants +

                  + +

                  +New constant can be created by calling +Cudd_addConst. This function will +retrieve the ADD for the desired constant, if it already +exist, or it will create a new one. Obviously, new constants should +only be used when manipulating ADDs. + +

                  + +

                  + +
                  +Creating Variables +

                  + +

                  +Decision diagrams are typically created by combining simpler decision +diagrams. The simplest decision diagrams, of course, cannot be +created in that way. Constant functions have been discussed in +Section 3.5. In this section we discuss the simple +variable functions, also known as projection functions. + +

                  + +

                  + +
                  +New BDD and ADD Variables +

                  + +

                  +The projection functions are distinct for +BDDs and ADDs. A projection function for BDDs consists of an internal +node with both outgoing arcs pointing to the constant 1. The +else arc is complemented. + +

                  +An ADD projection function, on the other hand, has the else +pointer directed to the arithmetic zero +function. One should never mix the two types of variables. BDD +variables should be used when manipulating BDDs, and ADD variables +should be used when manipulating ADDs. Three functions are provided +to create BDD variables: + +

                    +
                  • Cudd_bddIthVar: Returns + the projection function with index $i$. + If the function does not exist, it is created. +
                  • +
                  • Cudd_bddNewVar: Returns a + new projection function, whose index is + the largest index in use at the time of the call, plus 1. +
                  • +
                  • Cudd_bddNewVarAtLevel: + Similar to Cudd_bddNewVar. In + addition it allows to specify the position in the variable + order at which the new variable should be + inserted. In contrast, Cudd_bddNewVar + adds the new variable at the end of the order. +
                  • +
                  +The analogous functions for ADDs are +Cudd_addIthVar, +Cudd_addNewVar, and +Cudd_addNewVarAtLevel. + +

                  + +

                  + +
                  +New ZDD Variables +

                  + +

                  +Unlike the projection functions of BDDs and ADDs, the +projection functions of ZDDs have diagrams +with $n+1$ nodes, where $n$ is the number of variables. Therefore the +ZDDs of the projection functions change when new variables are added. +This will be discussed in Section 3.9. Here we assume +that the number of variables is fixed. The ZDD of the $i$-th +projection function is returned by +Cudd_zddIthVar. + +

                  + +

                  + +
                  +Basic BDD Manipulation +

                  + +

                  +Common manipulations of BDDs can be accomplished by calling +Cudd_bddIte. This function takes three BDDs, $f$, $g$, and +$h$, as arguments and computes +$f\cdot g + f'\cdot h$. Like all the +functions that create new BDDs or ADDs, Cudd_bddIte returns a result that must be +explicitly referenced by the caller. Cudd_bddIte can be used +to implement all two-argument boolean functions. However, the package +also provides Cudd_bddAnd as well as the +other two-operand boolean functions, which are slightly more efficient +when a two-operand function is called for. The following fragment of +code illustrates how to build the BDD for the function +$f =
+x_0'x_1'x_2'x_3'$. +

                  +	DdManager *manager;
                  +	DdNode *f, *var, *tmp;
                  +	int i;
                  +
                  +	...
                  +
                  +	f = Cudd_ReadOne(manager);
                  +	Cudd_Ref(f);
                  +	for (i = 3; i >= 0; i--) {
                  +	    var = Cudd_bddIthVar(manager,i);
                  +	    tmp = Cudd_bddAnd(manager,Cudd_Not(var),f);
                  +	    Cudd_Ref(tmp);
                  +	    Cudd_RecursiveDeref(manager,f);
                  +	    f = tmp;
                  +	}
                  +
                  +This example illustrates the following points: + +
                    +
                  • Intermediate results must be ``referenced'' and + ``dereferenced.'' However, var is a + projection function, and its + reference count is always greater than + 0. Therefore, there is no call to Cudd_Ref. +
                  • +
                  • The new f must be assigned to a temporary variable + (tmp in this example). If the result of + Cudd_bddAnd were assigned directly to + f, the old f would be lost, and there would be no + way to free its nodes. +
                  • +
                  • The statement f = tmp has the same effect as: +
                    +	    f = tmp;
                    +	    Cudd_Ref(f);
                    +	    Cudd_RecursiveDeref(manager,tmp);
                    +
                    + but is more efficient. The reference is + ``passed'' from tmp to f, and tmp is now + ready to be reutilized. +
                  • +
                  • It is normally more efficient to build BDDs ``bottom-up.'' This + is why the loop goes from 3 to 0. Notice, however, that after + variable reordering, higher index does not necessarily mean ``closer + to the bottom.'' Of course, in this simple example, efficiency is + not a concern. +
                  • +
                  • Had we wanted to conjoin the variables in a bottom-up fashion + even after reordering, we should have used + Cudd_ReadInvPerm. One has to be + careful, though, to fix the order of conjunction before entering the + loop. Otherwise, if reordering takes place, it is possible to use + one variable twice and skip another variable. +
                  • +
                  + +

                  + +

                  + +
                  +Basic ADD Manipulation +

                  + +

                  +The most common way to manipulate ADDs is via +Cudd_addApply. This function can apply a +wide variety of operators to a pair of ADDs. Among the available +operators are addition, multiplication, division, minimum, maximum, +and boolean operators that work on ADDs whose leaves are restricted to +0 and 1 (0-1 ADDs). + +

                  +The following fragment of code illustrates how to build the ADD for +the function +$f = 5x_0x_1x_2x_3$. +

                  +	DdManager *manager;
                  +	DdNode *f, *var, *tmp;
                  +	int i;
                  +
                  +	...
                  +
                  +	f = Cudd_addConst(manager,5);
                  +	Cudd_Ref(f);
                  +	for (i = 3; i >= 0; i--) {
                  +	    var = Cudd_addIthVar(manager,i);
                  +	    Cudd_Ref(var);
                  +	    tmp = Cudd_addApply(manager,Cudd_addTimes,var,f);
                  +	    Cudd_Ref(tmp);
                  +	    Cudd_RecursiveDeref(manager,f);
                  +	    Cudd_RecursiveDeref(manager,var);
                  +	    f = tmp;
                  +	}
                  +
                  +This example, contrasted to the example of BDD manipulation, +illustrates the following points: + +
                    +
                  • The ADD projection function are not + maintained by the manager. It is therefore necessary to + reference and + dereference them. +
                  • +
                  • The product of two ADDs is computed by calling + Cudd_addApply with + Cudd_addTimes as parameter. There is + no ``apply'' function for BDDs, because + Cudd_bddAnd and + Cudd_bddXor plus complementation are + sufficient to implement all two-argument boolean functions. +
                  • +
                  + +

                  + +

                  + +
                  +Basic ZDD Manipulation +

                  + +

                  +ZDDs are often generated by converting +existing BDDs. (See Section 3.11.) However, it is also +possible to build ZDDs by applying boolean operators to other ZDDs, +starting from constants and projection +functions. The following fragment of code illustrates how to build +the ZDD for the function +$f = x_0'+x_1'+x_2'+x_3'$. We assume that the +four variables already exist in the manager when the ZDD for $f$ is +built. Note the use of De Morgan's law. +

                  +	DdManager *manager;
                  +	DdNode *f, *var, *tmp;
                  +	int i;
                  +
                  +	manager = Cudd_Init(0,4,CUDD_UNIQUE_SLOTS,
                  +			    CUDD_CACHE_SLOTS,0);
                  +	...
                  +
                  +	tmp = Cudd_ReadZddOne(manager,0);
                  +	Cudd_Ref(tmp);
                  +	for (i = 3; i >= 0; i--) {
                  +	    var = Cudd_zddIthVar(manager,i);
                  +	    Cudd_Ref(var);
                  +	    f = Cudd_zddIntersect(manager,var,tmp);
                  +	    Cudd_Ref(f);
                  +	    Cudd_RecursiveDerefZdd(manager,tmp);
                  +	    Cudd_RecursiveDerefZdd(manager,var);
                  +	    tmp = f;
                  +	}
                  +	f = Cudd_zddDiff(manager,Cudd_ReadZddOne(manager,0),tmp);
                  +	Cudd_Ref(f);
                  +	Cudd_RecursiveDerefZdd(manager,tmp);
                  +
                  +This example illustrates the following points: + +
                    +
                  • The projection functions are + referenced, because they are not maintained by the manager. +
                  • +
                  • Complementation is obtained by subtracting from the constant 1 + function. +
                  • +
                  • The result of Cudd_ReadZddOne + does not require referencing. +
                  • +
                  +CUDD provides functions for the manipulation of +covers represented by ZDDs. For instance, +Cudd_zddIsop builds a ZDD representing an +irredundant sum of products for the +incompletely specified function defined by the two BDDs $L$ and $U$. +Cudd_zddWeakDiv performs the weak +division of two covers given as ZDDs. These functions expect the two +ZDD variables corresponding to the two literals of the function +variable to be adjacent. One has to create variable groups (see +Section 3.14) for reordering of +the ZDD variables to work. BDD automatic reordering is safe even +without groups: If realignment of ZDD and ADD/BDD variables is +requested (see Section 3.15) groups will be kept +adjacent. + +

                  + +

                  + + +
                  +Converting ADDs to BDDs and Vice Versa +

                  + +

                  +Several procedures are provided to convert ADDs to BDDs, according to +different criteria. +(Cudd_addBddPattern, +Cudd_addBddInterval, and +Cudd_addBddThreshold.) The +conversion from BDDs to ADDs +(Cudd_BddToAdd) is based on the simple +principle of mapping the logical 0 and 1 on the +arithmetic 0 and 1. It is also possible to +convert an ADD with integer values (more precisely, floating point +numbers with 0 fractional part) to an array of BDDs by repeatedly +calling Cudd_addIthBit. + +

                  + +

                  + + +
                  +Converting BDDs to ZDDs and Vice Versa +

                  + +

                  +Many applications first build a set of BDDs and then derive ZDDs from +the BDDs. These applications should create the manager with 0 +ZDD variables and create the BDDs. Then they should call +Cudd_zddVarsFromBddVars to +create the necessary ZDD variables--whose number is likely to be +known once the BDDs are available. This approach eliminates the +difficulties that arise when the number of ZDD variables changes while +ZDDs are being built. + +

                  +The simplest conversion from BDDs to ZDDs is a simple change of +representation, which preserves the functions. Simply put, given a BDD +for $f$, a ZDD for $f$ is requested. In this case the correspondence +between the BDD variables and ZDD variables is one-to-one. Hence, +Cudd_zddVarsFromBddVars should be called with the +multiplicity parameter equal to 1. The conversion proper can +then be performed by calling +Cudd_zddPortFromBdd. The inverse +transformation is performed by +Cudd_zddPortToBdd. + +

                  +ZDDs are quite often used for the representation of +covers. This is normally done by +associating two ZDD variables to each variable of the function. (And +hence, typically, to each BDD variable.) One ZDD variable is +associated with the positive literal of the BDD variable, while the +other ZDD variable is associated with the negative literal. A call to +Cudd_zddVarsFromBddVars with +multiplicity equal to 2 will associate to BDD variable $i$ the +two ZDD variables $2i$ and $2i+1$. + +

                  +If a BDD variable group tree exists when +Cudd_zddVarsFromBddVars is called (see +Section 3.13) the function generates a ZDD variable group +tree consistent to it. In any case, all the ZDD variables derived +from the same BDD variable are clustered into a group. + +

                  +If the ZDD for $f$ is created and later a new ZDD variable is added to +the manager, the function represented by the existing ZDD changes. +Suppose, for instance, that two variables are initially created, and +that the ZDD for $f = x_0 + x_1$ is built. If a third variable is +added, say $x_2$, then the ZDD represents +$g = (x_0 + x_1) x_2'$ +instead. This change in function obviously applies regardless of what +use is made of the ZDD. However, if the ZDD is used to represent a +cover, the cover itself is not changed by the +addition of new variable. (What changes is the +characteristic function of the cover.) + +

                  + +

                  + +
                  +Variable Reordering for BDDs and ADDs +

                  + +

                  +The CUDD package provides a rich set of +dynamic reordering algorithms. Some of them +are slight variations of existing techniques +[16,6,2,10,15,11]; some +others have been developed specifically for this package +[14,13]. + +

                  +Reordering affects a unique table. This means that +BDDs and ADDs, which share the same unique table are simultaneously +reordered. ZDDs, on the other hand, are reordered separately. In the +following we discuss the reordering of BDDs and ADDs. Reordering for +ZDDs is the subject of Section 3.14. + +

                  +Reordering of the variables can be invoked directly by the application +by calling Cudd_ReduceHeap. Or it can +be automatically triggered by the package when the number of nodes has +reached a given threshold. (The threshold +is initialized and automatically adjusted after each reordering by the +package.) To enable automatic dynamic reordering (also called +asynchronous dynamic reordering +in this document) the application must call +Cudd_AutodynEnable. Automatic +dynamic reordering can subsequently be disabled by calling +Cudd_AutodynDisable. + +

                  +All reordering methods are available in both the case of direct call +to Cudd_ReduceHeap and the case of +automatic invocation. For many methods, the reordering procedure is +iterated until no further improvement is obtained. We call these +methods the converging methods. +When constraints are imposed on the relative position of variables +(see Section 3.13) the reordering methods apply inside the +groups. The groups themselves are reordered +by sifting. Each method is identified by a +constant of the enumerated type +Cudd_ReorderingType +defined in cudd.h (the external +header file of the CUDD package): + +

                  +

                  +
                  CUDD_REORDER_NONE:
                  +
                  This method + causes no reordering. +
                  +
                  CUDD_REORDER_SAME:
                  +
                  If passed to + Cudd_AutodynEnable, this + method leaves the current method for automatic reordering unchanged. + If passed to Cudd_ReduceHeap, + this method causes the current method for automatic reordering to be + used. +
                  +
                  CUDD_REORDER_RANDOM:
                  +
                  Pairs of + variables are randomly chosen, and swapped in the order. The swap is + performed by a series of swaps of adjacent variables. The best order + among those obtained by the series of swaps is retained. The number + of pairs chosen for swapping equals the + number of variables in the diagram. +
                  +
                  CUDD_REORDER_RANDOM_PIVOT:
                  +
                  Same as CUDD_REORDER_RANDOM, but the two variables are chosen so + that the first is above the variable with the largest number of + nodes, and the second is below that variable. In case there are + several variables tied for the maximum number of nodes, the one + closest to the root is used. +
                  +
                  CUDD_REORDER_SIFT:
                  +
                  This method is + an implementation of Rudell's sifting + algorithm [16]. A simplified description of sifting is as + follows: Each variable is considered in turn. A variable is moved up + and down in the order so that it takes all possible positions. The + best position is identified and the variable is returned to that + position. + +

                  +In reality, things are a bit more complicated. For instance, there + is a limit on the number of variables that will be sifted. This + limit can be read with + Cudd_ReadSiftMaxVar and set with + Cudd_SetSiftMaxVar. In addition, + if the diagram grows too much while moving a variable up or down, + that movement is terminated before the variable has reached one end + of the order. The maximum ratio by which the diagram is allowed to + grow while a variable is being sifted can be read with + Cudd_ReadMaxGrowth and set with + Cudd_SetMaxGrowth. +

                  +
                  CUDD_REORDER_SIFT_CONVERGE:
                  +
                  This is the converging variant of + CUDD_REORDER_SIFT. +
                  +
                  CUDD_REORDER_SYMM_SIFT:
                  +
                  This method is an implementation of + symmetric sifting [14]. It is + similar to sifting, with one addition: Variables that become + adjacent during sifting are tested for symmetry. If + they are symmetric, they are linked in a group. Sifting then + continues with a group being moved, instead of a single variable. + After symmetric sifting has been run, + Cudd_SymmProfile can be called to + report on the symmetry groups found. (Both positive and negative + symmetries are reported.) +
                  +
                  CUDD_REORDER_SYMM_SIFT_CONV:
                  +
                  This is the converging variant of + CUDD_REORDER_SYMM_SIFT. +
                  +
                  CUDD_REORDER_GROUP_SIFT:
                  +
                  This method is an implementation of group + sifting [13]. It is similar to symmetric sifting, but + aggregation is not restricted to symmetric + variables. +
                  +
                  CUDD_REORDER_GROUP_SIFT_CONV:
                  +
                  This method repeats until convergence the combination of + CUDD_REORDER_GROUP_SIFT and CUDD_REORDER_WINDOW4. +
                  +
                  CUDD_REORDER_WINDOW2:
                  +
                  This + method implements the window permutation + approach of Fujita [8] and Ishiura [10]. + The size of the window is 2. +
                  +
                  CUDD_REORDER_WINDOW3:
                  +
                  Similar + to CUDD_REORDER_WINDOW2, but with a window of size 3. +
                  +
                  CUDD_REORDER_WINDOW4:
                  +
                  Similar + to CUDD_REORDER_WINDOW2, but with a window of size 4. +
                  +
                  CUDD_REORDER_WINDOW2_CONV:
                  +
                  This is the converging variant of + CUDD_REORDER_WINDOW2. +
                  +
                  CUDD_REORDER_WINDOW3_CONV:
                  +
                  This is the converging variant of CUDD_REORDER_WINDOW3. +
                  +
                  CUDD_REORDER_WINDOW4_CONV:
                  +
                  This is the converging variant of CUDD_REORDER_WINDOW4. +
                  +
                  CUDD_REORDER_ANNEALING:
                  +
                  This + method is an implementation of simulated + annealing for variable + ordering, vaguely resemblant of the algorithm of [2]. + This method is potentially very slow. +
                  +
                  CUDD_REORDER_GENETIC:
                  +
                  This + method is an implementation of a genetic + algorithm for variable ordering, inspired by the work of Drechsler + [6]. This method is potentially very slow. +
                  +
                  CUDD_REORDER_EXACT:
                  +
                  This method + implements a dynamic programming approach to + exact reordering + [9,7,10], with improvements described in + [11]. It only stores one BDD at the time. Therefore, it is + relatively efficient in terms of memory. Compared to other + reordering strategies, it is very slow, and is not recommended for + more than 16 variables. +
                  +
                  +So far we have described methods whereby the package selects an order +automatically. A given order of the variables can also be imposed by +calling Cudd_ShuffleHeap. + +

                  + +

                  + +
                  +Grouping Variables +

                  + +

                  +CUDD allows the application to specify constraints on the positions of +group of variables. It is possible to request that a group of +contiguous variables be kept contiguous by the reordering procedures. +It is also possible to request that the relative order of some groups +of variables be left unchanged. The constraints on the order are +specified by means of a tree, which is created in +one of two ways: + +

                    +
                  • By calling Cudd_MakeTreeNode. +
                  • +
                  • By calling the functions of the MTR library + (part of the distribution), and by registering the result with the + manager using Cudd_SetTree. The current + tree registered with the manager can be read with + Cudd_ReadTree. +
                  • +
                  + +

                  +Each node in the tree represents a range of variables. The lower bound +of the range is given by the low field of the node, and the +size of the group is given by the size field of the +node.2 The variables +in each range are kept contiguous. Furthermore, if a node is marked +with the MTR_FIXED flag, then the relative order of +the variable ranges associated to its children is not changed. As an +example, suppose the initial variable order is: +

                  +	x0, y0, z0, x1, y1, z1, ... , x9, y9, z9.
                  +
                  +Suppose we want to keep each group of three variables with the same +index (e.g., x3, y3, z3) contiguous, while allowing the package +to change the order of the groups. We can accomplish this with the +following code: +
                  +	for (i = 0; i < 10; i++) {
                  +	    (void) Cudd_MakeTreeNode(manager,i*3,3,MTR_DEFAULT);
                  +	}
                  +
                  +If we want to keep the order within each group of variables +fixed (i.e., x before y before z) we need to +change MTR_DEFAULT into MTR_FIXED. + +

                  +The low parameter passed to +Cudd_MakeTreeNode is the index of a +variable (as opposed to its level or position in the order). The +group tree can be created at any time. The +result obviously depends on the variable order in effect at creation +time. + +

                  +It is possible to create a variable group tree also before the +variables themselves are created. The package assumes in this case +that the index of the variables not yet in existence will equal their +position in the order when they are created. Therefore, applications +that rely on +Cudd_bddNewVarAtLevel or +Cudd_addNewVarAtLevel to create +new variables have to create the variables before they group them. + +

                  +The reordering procedure will skip all groups whose variables are not +yet in existence. For groups that are only partially in existence, the +reordering procedure will try to reorder the variables already +instantiated, without violating the adjacency constraints. + +

                  + +

                  + +
                  +Variable Reordering for ZDDs +

                  + +

                  +Reordering of ZDDs is done in much the same way as the reordering of +BDDs and ADDs. The functions corresponding to Cudd_ReduceHeap +and Cudd_ShuffleHeap are +Cudd_zddReduceHeap and +Cudd_zddShuffleHeap. To enable +dynamic reordering, the application must +call Cudd_AutodynEnableZdd, and +to disable dynamic reordering, it must call +Cudd_AutodynDisableZdd. In the +current implementation, however, the choice of reordering methods for +ZDDs is more limited. Specifically, these methods are available: + +

                  +

                  +
                  CUDD_REORDER_NONE;
                  +
                  +
                  +
                  CUDD_REORDER_SAME;
                  +
                  +
                  +
                  CUDD_REORDER_RANDOM;
                  +
                  +
                  +
                  CUDD_REORDER_RANDOM_PIVOT;
                  +
                  +
                  +
                  CUDD_REORDER_SIFT;
                  +
                  +
                  +
                  CUDD_REORDER_SIFT_CONVERGE;
                  +
                  +
                  +
                  CUDD_REORDER_SYMM_SIFT;
                  +
                  +
                  +
                  CUDD_REORDER_SYMM_SIFT_CONV.
                  +
                  +
                  +
                  + +

                  +To create ZDD variable groups, the application calls +Cudd_MakeZddTreeNode. + +

                  + +

                  + +
                  +Keeping Consistent Variable Orders for BDDs and ZDDs +

                  + +

                  +Several applications that manipulate both BDDs and ZDDs benefit from +keeping a fixed correspondence between the order of the BDD variables +and the order of the ZDD variables. If each BDD variable corresponds +to a group of ZDD variables, then it is often desirable that the +groups of ZDD variables be in the same order as the corresponding BDD +variables. CUDD allows the ZDD order to track the BDD order and vice +versa. To have the ZDD order track the BDD order, the application +calls Cudd_zddRealignEnable. The +effect of this call can be reversed by calling +Cudd_zddRealignDisable. When +ZDD realignment is in effect, automatic reordering of ZDDs should be +disabled. + +

                  + +

                  + +
                  +Hooks +

                  + +

                  +Hooks in CUDD are lists of application-specified functions to be run on +certain occasions. Each hook is identified by a constant of the +enumerated type Cudd_HookType. In Version +2.5.0 hooks are defined for these occasions: + +

                    +
                  • before garbage collection (CUDD_PRE_GC_HOOK); +
                  • +
                  • after garbage collection (CUDD_POST_GC_HOOK); +
                  • +
                  • before variable reordering (CUDD_PRE_REORDERING_HOOK); +
                  • +
                  • after variable reordering (CUDD_POST_REORDERING_HOOK). +
                  • +
                  +The current implementation of hooks is experimental. A function added +to a hook receives a pointer to the manager, a pointer to a constant +string, and a pointer to void as arguments; it must return 1 if +successful; 0 otherwise. The second argument is one of ``DD,'' +``BDD,'' and ``ZDD.'' This allows the hook functions to tell the type +of diagram for which reordering or garbage collection takes place. The +third argument varies depending on the hook. The hook functions called +before or after garbage collection do +not use it. The hook functions called before +reordering are passed, in addition to the +pointer to the manager, also the method used for reordering. The hook +functions called after reordering are passed the start time. To add a +function to a hook, one uses Cudd_AddHook. +The function of a given hook +are called in the order in which they were added to the hook. For +sample hook functions, one may look at +Cudd_StdPreReordHook and +Cudd_StdPostReordHook. + +

                  + +

                  + +
                  +Timeouts and Limits +

                  + +

                  +It is possible to set a time limit for a manger with +Cudd_SetTimeLimit. Once set, the +time available to the manager can be modified through other API +functions. CUDD checks for expiration periodically. When time has +expired, it returns NULL from the call in progress, but it leaves the +manager in a consistent state. The invoking application must be +designed to handle the NULL values returned. + +

                  +When reordering, if a timout is approaching, CUDD will quit reordering +to give the application a chance to finish some computation. + +

                  +It is also possible to invoke some functions that return NULL if they +cannot complete without creating more than a set number of nodes. +See, for instance, Cudd_bddAndLimit. + +

                  + +

                  + +
                  +The SIS/VIS Interface +

                  + +

                  +The CUDD package contains interface functions that emulate the +behavior of the original BDD package used in SIS [17] and +in the newer +VIS +[4]. How to build VIS with CUDD is described +in the installation documents of VIS. (Version 1.1 and later.) + +

                  + +

                  + +
                  +Using the CUDD Package in SIS +

                  + +

                  +This section describes how to build SIS with the CUDD package. Let +SISDIR designate the root of the directory +hierarchy where the sources for SIS reside. Let +CUDDDIR be the root of the directory hierarchy +where the distribution of the CUDD package resides. To build SIS with +the CUDD package, follow these steps. + +

                    +
                  1. Create directories SISDIR/sis/cudd and + SISDIR/sis/mtr. +
                  2. +
                  3. Copy all files from CUDDDIR/cudd and + CUDDDIR/sis to SISDIR/sis/cudd and all files from + CUDDDIR/mtr to SISDIR/sis/mtr. +
                  4. +
                  5. Copy CUDDDIR/cudd/doc/cudd.doc to + SISDIR/sis/cudd; also copy CUDDDIR/mtr/doc/mtr.doc + to SISDIR/sis/mtr. +
                  6. +
                  7. In SISDIR/sis/cudd make bdd.h a symbolic link + to cuddBdd.h. (That is: ln -s cuddBdd.h bdd.h.) +
                  8. +
                  9. In SISDIR/sis/cudd delete Makefile and rename + Makefile.sis as Makefile. Do the same in + SISDIR/sis/mtr. +
                  10. +
                  11. Copy CUDDDIR/sis/st.[ch] and CUDDDIR/st/doc/st.doc + to SISDIR/sis/st. (This will overwrite the original files: You + may want to save them beforehand.) +
                  12. +
                  13. From CUDDDIR/util copy datalimit.c to + SISDIR/sis/util. Update util.h and + Makefile in SISDIR/sis/util. Specifically, add the + declaration EXTERN long getSoftDataLimit(); to + util.h and add datalimit.c to the list of source + files (PSRC) in Makefile. +
                  14. +
                  15. In SISDIR/sis remove the link from bdd to + bdd_cmu or bdd_ucb (that is, rm bdd) + and make bdd a symbolic link to cudd. (That is: + ln -s cudd bdd.) +
                  16. +
                  17. Still in SISDIR/sis, edit Makefile, Makefile.oct, and Makefile.nooct. In all three files add + mtr to the list of directories to be made (DIRS). +
                  18. +
                  19. In SISDIR/sis/include make mtr.h a symbolic + link to ../mtr/mtr.h. +
                  20. +
                  21. In SISDIR/sis/doc make cudd.doc a symbolic + link to ../cudd/cudd.doc and mtr.doc a symbolic + link to ../mtr/mtr.doc. (That is: ln -s + ../cudd/cudd.doc .; ln -s ../mtr/mtr.doc ..) +
                  22. +
                  23. From SISDIR do make clean followed by + make -i. This should create a working copy of SIS that + uses the CUDD package. +
                  24. +
                  + +

                  +The replacement for the st library is because the version +shipped with the CUDD package tests for out-of-memory conditions. +Notice that the version of the st library to be used for +replacement is not the one used for the normal build, because the +latter has been modified for C++ compatibility. The above installation +procedure has been tested on SIS 1.3. SIS can be obtained via +anonymous FTP from +ic.eecs.berkeley.edu. +To build SIS 1.3, you need sis-1.2.tar.Z and +sis-1.2.patch1.Z. When compiling on a DEC Alpha, you should add the -ieee_with_no_inexact flag. +(See Section 3.5.2.) Refer to the Makefile +in the top level directory of the distribution for how to compile with +32-bit pointers. + +

                  + +

                  + +
                  +Writing Decision Diagrams to a File +

                  + +

                  +The CUDD package provides several functions to write decision diagrams +to a file. Cudd_DumpBlif writes a +file in blif format. It is restricted to BDDs. The diagrams +are written as a network of multiplexers, one multiplexer for each +internal node of the BDD. + +

                  +Cudd_DumpDot produces input suitable to +the graph-drawing program +dot +written by Eleftherios Koutsofios and Stephen C. North. An example of +drawing produced by dot from the output of Cudd_DumpDot is +shown in Figure 1. It is restricted to BDDs and ADDs. + +

                  + + + +
                  Figure 1: +A BDD representing a phase constraint for the optimization of + fixed-polarity Reed-Muller forms. The label of each node is the + unique part of the node address. All nodes on the same level + correspond to the same variable, whose name is shown at the left of + the diagram. Dotted lines indicate complement + arcs. Dashed lines indicate regular ``else'' + arcs.
                  +
                  +\includegraphics[height=15.5cm]{phase.ps}
                  +
                  + +Cudd_zddDumpDot is the analog of +Cudd_DumpDot for ZDDs. + +

                  +Cudd_DumpDaVinci produces input +suitable to the graph-drawing program +daVinci +developed at the University of Bremen. It is restricted to BDDs and +ADDs. + +

                  +Functions are also available to produce the input format of +DDcal (see Section 2.2) and factored forms. + +

                  + +

                  + +
                  +Saving and Restoring BDDs +

                  + +

                  +The +dddmp +library by Gianpiero Cabodi and Stefano Quer +allows a CUDD application to save BDDs to disk in compact form for +later retrieval. See the library's own documentation for the details. + +

                  +


                  + + +next + +up + +previous + +index +
                  + Next: Programmer's Manual + Up: CUDD: CU Decision Diagram + Previous: How to Get CUDD +   Index + +
                  +Fabio Somenzi +2012-02-04 +
                  + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node4.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node4.html new file mode 100644 index 000000000..e1697b331 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node4.html @@ -0,0 +1,1165 @@ + + + + + +Programmer's Manual + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                  + Next: The C++ Interface + Up: CUDD: CU Decision Diagram + Previous: User's Manual +   Index +
                  +
                  + + +Subsections + + + +
                  + +

                  + +
                  +Programmer's Manual +

                  + +

                  +This section provides additional detail on the working of the CUDD +package and on the programming conventions followed in its writing. +The additional detail should help those who want to write procedures +that directly manipulate the CUDD data structures. + +

                  + +

                  + +
                  +Compiling and Linking +

                  + +

                  +If you plan to use the CUDD package as a clear box +(for instance, you want to write a procedure that traverses a decision +diagram) you need to add +

                  +#include "cuddInt.h"
                  +
                  +to your source files. In addition, you should link libcudd.a to +your executable. Some platforms require specific compiler and linker +flags. Refer to the Makefile in the top level directory of +the distribution. + +

                  + +

                  + +
                  +Reference Counts +

                  + +

                  +Garbage collection in the CUDD package is +based on reference counts. Each node stores the sum of the external +references and internal references. An internal BDD or ADD node is +created by a call to cuddUniqueInter, an +internal ZDD node is created by a call to +cuddUniqueInterZdd, and a +terminal node is created by a call to +cuddUniqueConst. If the node returned by +these functions is new, its reference count is zero. The function +that calls cuddUniqueInter, +cuddUniqueInterZdd, or +cuddUniqueConst is responsible for +increasing the reference count of the node. This is accomplished by +calling Cudd_Ref. + +

                  +When a function is no longer needed by an application, the memory used +by its diagram can be recycled by calling +Cudd_RecursiveDeref (BDDs and ADDs) +or Cudd_RecursiveDerefZdd +(ZDDs). These functions decrease the reference count of the node passed to them. If the reference count +becomes 0, then two things happen: + +

                    +
                  1. The node is declared ``dead;'' this entails + increasing the counters of the dead + nodes. (One counter for the subtable to which the + node belongs, and one global counter for the + unique table to which the node belongs.) The + node itself is not affected. +
                  2. +
                  3. The function is recursively called on the two children of the + node. +
                  4. +
                  +For instance, if the diagram of a function does not share any nodes +with other diagrams, then calling +Cudd_RecursiveDeref or +Cudd_RecursiveDerefZdd on its +root will cause all the nodes of the diagram to become dead. + +

                  +When the number of dead nodes reaches a given level (dynamically +determined by the package) garbage collection takes place. During +garbage collection dead nodes are returned +to the node free list. + +

                  +When a new node is created, it is important to increase its +reference count before one of the two +following events occurs: + +

                    +
                  1. A call to cuddUniqueInter, + to cuddUniqueInterZdd, to + cuddUniqueConst, or to a + function that may eventually cause a call to them. +
                  2. +
                  3. A call to + Cudd_RecursiveDeref, to + Cudd_RecursiveDerefZdd, or to + a function that may eventually cause a call to them. +
                  4. +
                  +In practice, it is recommended to increase the reference count as soon +as the returned pointer has been tested for not being NULL. + +

                  + +

                  + +
                  +NULL Return Values +

                  + +

                  +The interface to the memory management functions (e.g., malloc) used +by CUDD intercepts NULL return values and calls a handler. The +default handler exits with an error message. If the application does +not install another handler, therefore, a NULL return value from an +exported function of CUDD signals an internal error. + +

                  +If the aplication, however, installs another handler that lets +execution continue, a NULL pointer returned by an exported function +typically indicates that the process has run out of memory. +Cudd_ReadErrorCode can be used to +ascertain the nature of the problem. + +

                  +An application that tests for the result being NULL can try some +remedial action, if it runs out of memory. For instance, it may free +some memory that is not strictly necessary, or try a slower algorithm +that takes less space. As an example, CUDD overrides the default +handler when trying to enlarge the cache or increase the number of +slots of the unique table. If the allocation fails, the package prints +out a message and continues without resizing the cache. + +

                  + +

                  + +
                  +Cudd_RecursiveDeref vs. Cudd_Deref +

                  + +

                  +It is often the case that a recursive procedure has to protect the +result it is going to return, while it disposes of intermediate +results. (See the previous discussion on when to increase reference +counts.) Once the intermediate results have been properly disposed +of, the final result must be returned to its pristine state, in which +the root node may have a reference count of 0. One cannot use +Cudd_RecursiveDeref (or +Cudd_RecursiveDerefZdd) for this purpose, because it may +erroneously make some nodes dead. Therefore, the package provides a +different function: Cudd_Deref. This +function is not recursive, and does not change the dead node counts. +Its use is almost exclusively the one just described: Decreasing the +reference count of the root of the final result before returning from +a recursive procedure. + +

                  + +

                  + +
                  +When Increasing the Reference Count is Unnecessary +

                  + +

                  +When a copy of a predefined constant or of a +simple BDD variable is needed for comparison purposes, then calling +Cudd_Ref is not necessary, because these +simple functions are guaranteed to have reference counts greater than +0 at all times. If no call to Cudd_Ref is made, then no +attempt to free the diagram by calling +Cudd_RecursiveDeref or +Cudd_RecursiveDerefZdd should be +made. + +

                  + +

                  + +
                  +Saturating Increments and Decrements +

                  + +

                  +On 32-bit machines, the CUDD package stores the +reference counts in unsigned short int's. +For large diagrams, it is possible for some reference counts to exceed +the capacity of an unsigned short int. Therefore, increments and +decrements of reference counts are saturating. This means that +once a reference count has reached the maximum possible value, it is +no longer changed by calls to Cudd_Ref, +Cudd_RecursiveDeref, +Cudd_RecursiveDerefZdd, or +Cudd_Deref. As a consequence, some nodes +that have no references may not be declared dead. This may result in a +small waste of memory, which is normally more than offset by the +reduction in size of the node structure. + +

                  +When using 64-bit pointers, there is normally no memory advantage from +using short int's instead of int's in a DdNode. Therefore, increments +and decrements are not saturating in that case. What option is in +effect depends on two macros, SIZEOF_VOID_P +and SIZEOF_INT, defined in the external +header file (cudd.h). The +increments and decrements of the reference counts are performed using +two macros: cuddSatInc and +cuddSatDec, whose definitions depend on +SIZEOF_VOID_P and +SIZEOF_INT. + +

                  + +

                  + +
                  +Complement Arcs +

                  + +

                  +If ADDs are restricted to use only the constants 0 and 1, they behave +like BDDs without complement arcs. It is normally easier to write code +that manipulates 0-1 ADDs, than to write code for BDDs. However, +complementation is trivial with complement arcs, and is not trivial +without. As a consequence, with complement arcs it is possible to +check for more terminal cases and it is possible to apply De Morgan's +laws to reduce problems that are essentially identical to a standard +form. This in turn increases the utilization of the cache. + +

                  +The complement attribute is stored in the least significant bit of the +``else'' pointer of each node. An external pointer to a function can +also be complemented. The ``then'' pointer to a node, on the other +hand, is always regular. It is a mistake to +use a complement pointer as it is to address +memory. Instead, it is always necessary to obtain a regular version +of it. This is normally done by calling +Cudd_Regular. It is also a mistake to +call cuddUniqueInter with a complemented +``then'' child as argument. The calling procedure must apply De +Morgan's laws by complementing both pointers passed to +cuddUniqueInter and then taking the +complement of the result. + +

                  + +

                  + +
                  +The Cache +

                  + +

                  +Each entry of the cache consists of five fields: The operator, three +pointers to operands and a pointer to the result. The operator and the +three pointers to the operands are combined to form three words. The +combination relies on two facts: + +

                    +
                  • Most operations have one or two operands. A few bits are + sufficient to discriminate all three-operands operations. +
                  • +
                  • All nodes are aligned to 16-byte boundaries. (32-byte boundaries + if 64-bit pointers are used.) Hence, there are a few bits available + to distinguish the three-operand operations from te others and to + assign unique codes to them. +
                  • +
                  + +

                  +The cache does not contribute to the reference + +counts of the nodes. The fact that the cache contains a +pointer to a node does not imply that the node is alive. Instead, when +garbage collection takes place, all entries +of the cache pointing to dead nodes are cleared. + +

                  +The cache is also cleared (of all entries) when dynamic +reordering takes place. In both cases, the entries +removed from the cache are about to become invalid. + +

                  +All operands and results in a cache entry must be pointers to +DdNodes. If a function produces more than one result, +or uses more than three arguments, there are currently two solutions: + +

                    +
                  • Build a separate, local, cache. (Using, for + instance, the st library.) +
                  • +
                  • Combine multiple results, or multiple operands, into a single + diagram, by building a ``multiplexing structure'' with reserved + variables. +
                  • +
                  +Support of the former solution is under development. (See +cuddLCache.c..) Support for the latter solution may be +provided in future versions of the package. + +

                  +There are three sets of interface functions to +the cache. The first set is for functions with three operands: +cuddCacheInsert and +cuddCacheLookup. The second set is for +functions with two operands: +cuddCacheInsert2 and +cuddCacheLookup2. The second set is for +functions with one operand: +cuddCacheInsert1 and +cuddCacheLookup1. The second set is +slightly faster than the first, and the third set is slightly faster +than the second. + +

                  + +

                  + +
                  +Cache Sizing +

                  + +

                  +The size of the cache can increase during the execution of an +application. (There is currently no way to decrease the size of the +cache, though it would not be difficult to do it.) When a cache miss +occurs, the package uses the following criteria to decide whether to +resize the cache: + +

                    +
                  1. If the cache already exceeds the limit given by the + maxCache field of the manager, no resizing + takes place. The limit is the minimum of two values: a value set at + initialization time and possibly modified by the application, which + constitutes the hard limit beyond which the cache will never grow; + and a number that depends on the current total number of slots in + the unique table. +
                  2. +
                  3. If the cache is not too large already, resizing is decided based + on the hit rate. The policy adopted by the CUDD package is + ``reward-based.'' If the cache hit + rate is high, then it is worthwhile to increase the size of the + cache. +
                  4. +
                  +When resizing takes place, the statistical counters used to compute the hit rate are reinitialized so as to +prevent immediate resizing. The number of entries is doubled. + +

                  +The rationale for the ``reward-based'' +policy is as follows. In many BDD/ADD applications the hit rate is +not very sensitive to the size of the cache: It is primarily a +function of the problem instance at hand. If a large hit rate is +observed, chances are that by using a large cache, the results of +large problems (those that would take longer to solve) will survive in +the cache without being overwritten long enough to cause a valuable +cache hit. Notice that when a large problem is solved more than once, +so are its recursively generated subproblems. If the hit rate is +low, the probability of large problems being solved more than once is +low. + +

                  +The other observation about the cache sizing policy is that there is +little point in keeping a cache which is much larger than the unique +table. Every time the unique table ``fills up,'' garbage collection is +invoked and the cache is cleared of all dead entries. A cache that is +much larger than the unique table is therefore +less than fully utilized. + +

                  + +

                  + +
                  +Local Caches +

                  + +

                  +Sometimes it may be necessary or convenient to use a local cache. A +local cache can be lossless (no results are ever +overwritten), or it may store objects for which +canonical representations are not available. One +important fact to keep in mind when using a local cache is that local +caches are not cleared during garbage +collection or before reordering. Therefore, it is necessary to +increment the reference count of all nodes +pointed by a local cache. (Unless their reference counts are +guaranteed positive in some other way. One such way is by including +all partial results in the global result.) Before disposing of the +local cache, all elements stored in it must be passed to +Cudd_RecursiveDeref. As consequence +of the fact that all results in a local cache are referenced, it is +generally convenient to store in the local cache also the result of +trivial problems, which are not usually stored in the global cache. +Otherwise, after a recursive call, it is difficult to tell whether the +result is in the cache, and therefore referenced, or not in the cache, +and therefore not referenced. + +

                  +An alternative approach to referencing the results in the local caches +is to install hook functions (see Section 3.16) to be +executed before garbage collection. + +

                  + +

                  + +
                  +The Unique Table +

                  + +

                  +A recursive procedure typically splits the operands by expanding with +respect to the topmost variable. Topmost in this context refers to the +variable that is closest to the roots in the current variable order. +The nodes, on the other hand, hold the index, which is invariant with +reordering. Therefore, when splitting, one must use the +permutation array maintained by the +package to get the right level. Access to the permutation array is +provided by the macro cuddI for BDDs and ADDs, +and by the macro cuddIZ for ZDDs. + +

                  +The unique table consists of as many hash tables as +there are variables in use. These has tables are called unique + subtables. The sizes of the unique subtables are determined by two +criteria: + +

                    +
                  1. The collision lists should be short + to keep access time down. +
                  2. +
                  3. There should be enough room for dead nodes, to + prevent too frequent garbage collections. +
                  4. +
                  +While the first criterion is fairly straightforward to implement, the +second leaves more room to creativity. The CUDD package tries to +figure out whether more dead node should be allowed to increase +performance. (See also Section 3.4.) There are two +reasons for not doing garbage collection too often. The obvious one is +that it is expensive. The second is that dead nodes may be +reclaimed, if they are the result of a +successful cache lookup. Hence dead nodes may provide a substantial +speed-up if they are kept around long enough. The usefulness of +keeping many dead nodes around varies from application to application, +and from problem instance to problem instance. As in the sizing of the +cache, the CUDD package adopts a +``reward-based'' policy to +decide how much room should be used for the unique table. If the +number of dead nodes reclaimed is large compared to the number of +nodes directly requested from the memory manager, then the CUDD +package assumes that it will be beneficial to allow more room for the +subtables, thereby reducing the frequency of garbage collection. The +package does so by switching between two modes of operation: + +
                    +
                  1. Fast growth: In this mode, the + ratio of dead nodes to total nodes required for garbage collection + is higher than in the slow growth mode to favor resizing + of the subtables. +
                  2. +
                  3. Slow growth: In this + mode keeping many dead nodes around is not as important as + keeping memory requirements low. +
                  4. +
                  +Switching from one mode to the other is based on the following +criteria: + +
                    +
                  1. If the unique table is already large, only slow growth is + possible. +
                  2. +
                  3. If the table is small and many dead nodes are being reclaimed, + then fast growth is selected. +
                  4. +
                  +This policy is especially effective when the diagrams being +manipulated have lots of recombination. Notice the interplay of the +cache sizing and unique sizing: Fast growth normally occurs when the +cache hit rate is large. The cache and the unique table then grow in +concert, preserving a healthy balance between their sizes. + +

                  + +

                  + +
                  +Allowing Asynchronous Reordering +

                  + +

                  +Asynchronous reordering is the reordering that is triggered +automatically by the increase of the number of nodes. Asynchronous +reordering takes place when a new internal node must be created, and +the number of nodes has reached a given +threshold. (The threshold is adjusted by +the package every time reordering takes place.) + +

                  +Those procedures that do not create new nodes (e.g., procedures that +count the number of nodes or minterms) need +not worry about asynchronous reordering: No special precaution is +necessary in writing them. + +

                  +Procedures that only manipulate decision diagrams through the exported +functions of the CUDD package also need not concern themselves with +asynchronous reordering. (See Section 3.2.1 for the +exceptions.) + +

                  +The remaining class of procedures is composed of functions that visit +the diagrams and may create new nodes. All such procedures in the CUDD +package are written so that they can be interrupted by dynamic +reordering. The general approach followed goes under the name of +``abort and retry.'' As the name +implies, a computation that is interrupted by dynamic reordering is +aborted and tried again. + +

                  +A recursive procedure that can be interrupted by dynamic reordering +(an interruptible procedure +from now on) is composed of two functions. One is responsible for the +real computation. The other is a simple +wrapper, which tests whether +reordering occurred and restarts the computation if it did. + +

                  +Asynchronous reordering of BDDs and ADDs can only be triggered inside +cuddUniqueInter, when a new node is about +to be created. Likewise, asynchronous reordering of ZDDs can only be +triggered inside cuddUniqueInterZdd. +When reordering is triggered, three things happen: + +

                    +
                  1. cuddUniqueInter returns a NULL + value; +
                  2. +
                  3. The flag reordered of the manager is set to 1. (0 means + no reordering, while 2 indicates an error occurred during + reordering.) +
                  4. +
                  5. The counter reorderings of the manager is incremented. + The counter is initialized to 0 when the manager is started and can + be accessed by calling + Cudd_ReadReorderings. By taking + two readings of the counter, an application can determine if + variable reordering has taken place between the first and the second + reading. The package itself, however, does not make use of the + counter: It is mentioned here for completeness. +
                  6. +
                  + +

                  +The recursive procedure that receives a NULL value from +cuddUniqueInter must free all +intermediate results that it may have computed before, and return NULL +in its turn. + +

                  +The wrapper function does not +decide whether reordering occurred based on the NULL return value, +because the NULL value may be the result of lack of memory. Instead, +it checks the reordered flag. + +

                  +When a recursive procedure calls another recursive procedure that may +cause reordering, it should bypass the wrapper and call the recursive +procedure directly. Otherwise, the calling procedure will not know +whether reordering occurred, and will not be able to restart. This is +the main reason why most recursive procedures are internal, rather +than static. (The wrappers, on the other hand, are mostly exported.) + +

                  + +

                  + +
                  +Debugging +

                  + +

                  +By defining the symbol DD_DEBUG during compilation, +numerous checks are added to the code. In addition, the procedures +Cudd_DebugCheck, +Cudd_CheckKeys, and +cuddHeapProfile can be called at any +point to verify the consistency of the data structure. +(cuddHeapProfile is an internal procedure. It is declared in +cuddInt.h.) Procedures +Cudd_DebugCheck and Cudd_CheckKeys are especially +useful when CUDD reports that during garbage collection the number of +nodes actually deleted from the unique table is different from the +count of dead nodes kept by the manager. The error causing the +discrepancy may have occurred much earlier than it is discovered. A +few strategicaly placed calls to the debugging procedures can +considerably narrow down the search for the source of the problem. +(For instance, a call to Cudd_RecursiveDeref where one to +Cudd_Deref was required may be identified in this way.) + +

                  +One of the most common problems encountered in debugging code based on +the CUDD package is a missing call to +Cudd_RecursiveDeref. To help +identify this type of problems, the package provides a function called +Cudd_CheckZeroRef. This function +should be called immediately before shutting down the manager. +Cudd_CheckZeroRef checks that the only nodes left with +non-zero reference counts are the +predefined constants, the BDD projection +functions, and nodes whose reference counts are +saturated. + +

                  +For this function to be effective the application must explicitly +dispose of all diagrams to which it has pointers before calling it. + +

                  + +

                  + +
                  +Gathering and Interpreting Statistics +

                  + +

                  +Function Cudd_PrintInfo can be called to +print out the values of parameters and statistics for a manager. The +output of Cudd_PrintInfo is divided in two sections. The +first reports the values of parameters that are under the application +control. The second reports the values of statistical counters and +other non-modifiable parameters. A quick guide to the interpretation +of all these quantities follows. For ease of exposition, we reverse +the order and describe the non-modifiable parameters first. We'll use +a sample run as example. There is nothing special about this run. + +

                  + +

                  + +
                  +Non Modifiable Parameters +

                  + +

                  +The list of non-modifiable parameters starts with: +

                  +    **** CUDD non-modifiable parameters ****
                  +    Memory in use: 32544220
                  +
                  +This is the memory used by CUDD for three things mainly: Unique table +(including all DD nodes in use), node free list, and computed table. +This number almost never decreases in the lifetime of a CUDD manager, +because CUDD does not release memory when it frees nodes. Rather, it +puts the nodes on its own free list. This number is in bytes. It does +not represent the peak memory occupation, because it does not include +the size of data structures created temporarily by some functions (e.g., +local look-up tables). + +

                  +

                  +    Peak number of nodes: 837018
                  +
                  +This number is the number of nodes that the manager has allocated. +This is not the largest size of the BDDs, because the manager will +normally have some dead nodes and some nodes on the free list. + +

                  +

                  +    Peak number of live nodes: 836894
                  +
                  +This is the largest number of live nodes that the manager has held +since its creation. + +

                  +

                  +    Number of BDD variables: 198
                  +    Number of ZDD variables: 0
                  +
                  +These numbers tell us this run was not using ZDDs. + +

                  +

                  +    Number of cache entries: 1048576
                  +
                  +Current number of slots of the computed table. If one has a +performance problem, this is one of the numbers to look at. The cache +size is always a power of 2. + +

                  +

                  +    Number of cache look-ups: 2996536
                  +    Number of cache hits: 1187087
                  +
                  +These numbers give an indication of the hit rate in the computed +table. It is not unlikely for model checking runs to get +hit rates even higher than this one (39.62%). + +

                  +

                  +    Number of cache insertions: 1809473
                  +    Number of cache collisions: 961208
                  +    Number of cache deletions: 0
                  +
                  +A collision occurs when a cache entry is +overwritten. A deletion +occurs when a cache entry is invalidated (e.g., during garbage +collection). If the number of deletions is high compared to the +number of collisions, it means that garbage collection occurs too +often. In this case there were no garbage collections; hence, no +deletions. + +

                  +

                  +    Cache used slots = 80.90% (expected 82.19%)
                  +
                  +Percentage of cache slots that contain a valid entry. If this +number is small, it may signal one of three conditions: + +
                    +
                  1. The cache may have been recently resized and it is still filling + up. +
                  2. +
                  3. The cache is too large for the BDDs. This should not happen if + the size of the cache is determined by CUDD. +
                  4. +
                  5. The hash function is not working properly. This is accompanied + by a degradation in performance. Conversely, a degradation in + performance may be due to bad hash function behavior. +
                  6. +
                  +The expected value is computed assuming a uniformly random +distribution of the accesses. If the difference between the measured +value and the expected value is large (unlike this case), the cache is +not working properly. + +

                  +

                  +    Soft limit for cache size: 1318912
                  +
                  +This number says how large the cache can grow. This limit is based on +the size of the unique table. CUDD uses a reward-based policy for +growing the cache. (See Section 4.4.1.) The default +hit rate for resizing is 30% and the value in effect is reported +among the modifiable parameters. + +

                  +

                  +    Number of buckets in unique table: 329728
                  +
                  +This number is exactly one quarter of the one above. This is indeed +how the soft limit is determined currently, unless the computed table +hits the specified hard limit. (See below.) + +

                  +

                  +    Used buckets in unique table: 87.96% (expected 87.93%)
                  +
                  +Percentage of unique table buckets that contain at least one +node. Remarks analogous to those made about the used cache slots apply. + +

                  +

                  +    Number of BDD and ADD nodes: 836894
                  +    Number of ZDD nodes: 0
                  +
                  +How many nodes are currently in the unique table, either alive or dead. + +

                  +

                  +    Number of dead BDD and ADD nodes: 0
                  +    Number of dead ZDD nodes: 0
                  +
                  +Subtract these numbers from those above to get the number of live +nodes. In this case there are no dead nodes because the application +uses delayed dereferencing +Cudd_DelayedDerefBdd. + +

                  +

                  +    Total number of nodes allocated: 836894
                  +
                  +This is the total number of nodes that were requested and obtained +from the free list. It never decreases, and is not an indication of +memory occupation after the first garbage collection. Rather, it is a +measure of the package activity. + +

                  +

                  +    Total number of nodes reclaimed: 0
                  +
                  +These are the nodes that were resuscitated from the dead. If they are +many more than the allocated nodes, and the total +number of slots is low relative to the number of nodes, then one may +want to increase the limit for fast unique table growth. In this case, +the number is 0 because of delayed dereferencing. + +

                  +

                  +    Garbage collections so far: 0
                  +    Time for garbage collections: 0.00 sec
                  +    Reorderings so far: 0
                  +    Time for reordering: 0.00 sec
                  +
                  +There is a GC for each reordering. Hence the first count will always be +at least as large as the second. + +

                  +

                  +    Node swaps in reordering: 0
                  +
                  +This is the number of elementary reordering steps. Each step consists +of the re-expression of one node while swapping two adjacent +variables. This number is a good measure of the amount of work done in +reordering. + +

                  + +

                  + +
                  +Modifiable Parameters +

                  + +

                  +Let us now consider the modifiable parameters, that is, those settings on +which the application or the user has control. + +

                  +

                  +    **** CUDD modifiable parameters ****
                  +    Hard limit for cache size: 8388608
                  +
                  +This number counts entries. Each entry is 16 bytes if CUDD is compiled +to use 32-bit pointers. Two important observations are in order: + +
                    +
                  1. If the datasize limit is set, CUDD will use it to determine this + number automatically. On a Unix system, one can type ``limit'' or + ``ulimit'' to verify if this value is set. If the datasize limit is + not set, CUDD uses a default which is rather small. If you have + enough memory (say 64MB or more) you should seriously consider + not using the default. So, either set the datasize limit, or + override the default with + Cudd_SetMaxCacheHard. +
                  2. +
                  3. If a process seems to be going nowhere, a small value for + this parameter may be the culprit. One cannot overemphasize the + importance of the computed table in BDD algorithms. +
                  4. +
                  +In this case the limit was automatically set for a target maximum +memory occupation of 104 MB. + +

                  +

                  +    Cache hit threshold for resizing: 15%
                  +
                  +This number can be changed if one suspects performance is hindered by +the small size of the cache, and the cache is not growing towards the +soft limit sufficiently fast. In such a case one can change the +default 30% to 15% (as in this case) or even 1%. + +

                  +

                  +    Garbage collection enabled: yes
                  +
                  +One can disable it, but there are few good reasons for doing +so. It is normally preferable to raise the limit for fast unique table +growth. (See below.) + +

                  +

                  +    Limit for fast unique table growth: 1363148
                  +
                  +See Section 4.5 and the comments above about reclaimed +nodes and hard limit for the cache size. This value was chosen +automatically by CUDD for a datasize limit of 1 GB. + +

                  +

                  +    Maximum number of variables sifted per reordering: 1000
                  +    Maximum number of variable swaps per reordering: 2000000
                  +    Maximum growth while sifting a variable: 1.2
                  +
                  +Lowering these numbers will cause reordering to be less accurate and +faster. Results are somewhat unpredictable, because larger BDDs after one +reordering do not necessarily mean the process will go faster or slower. + +

                  +

                  +    Dynamic reordering of BDDs enabled: yes
                  +    Default BDD reordering method: 4
                  +    Dynamic reordering of ZDDs enabled: no
                  +    Default ZDD reordering method: 4
                  +
                  +These lines tell whether automatic reordering can take place and what +method would be used. The mapping from numbers to methods is in +cudd.h. One may want to try different BDD reordering +methods. If variable groups are used, however, one should not expect +to see big differences, because CUDD uses the reported method only to +reorder each leaf variable group (typically corresponding present and +next state variables). For the relative order of the groups, it +always uses the same algorithm, which is effectively sifting. + +

                  +As for enabling dynamic reordering or not, a sensible recommendation is the +following: Unless the circuit is rather small or one has a pretty good +idea of what the order should be, reordering should be enabled. + +

                  +

                  +    Realignment of ZDDs to BDDs enabled: no
                  +    Realignment of BDDs to ZDDs enabled: no
                  +    Dead nodes counted in triggering reordering: no
                  +    Group checking criterion: 7
                  +    Recombination threshold: 0
                  +    Symmetry violation threshold: 0
                  +    Arc violation threshold: 0
                  +    GA population size: 0
                  +    Number of crossovers for GA: 0
                  +
                  +Parameters for reordering. See the documentation of the functions used +to control these parameters for the details. + +

                  +

                  +    Next reordering threshold: 100000
                  +
                  +When the number of nodes crosses this threshold, reordering will be +triggered. (If enabled; in this case it is not.) This parameter is +updated by the package whenever reordering takes place. The +application can change it, for instance at start-up. Another +possibility is to use a hook function (see Section 3.16) to +override the default updating policy. + +

                  + +

                  + +
                  +Extended Statistics and Reporting +

                  + +

                  +The following symbols can be defined during compilation to increase +the amount of statistics gathered and the number of messages produced +by the package: + +

                    +
                  • DD_STATS; +
                  • +
                  • DD_CACHE_PROFILE; +
                  • +
                  • DD_UNIQUE_PROFILE. +
                  • +
                  • DD_VERBOSE; +
                  • +
                  +Defining DD_CACHE_PROFILE causes each entry of the cache to include +an access counter, which is used to compute simple statistics on the +distribution of the keys. + +

                  + +

                  + +
                  +Guidelines for Documentation +

                  + +

                  +The documentation of the CUDD functions is extracted automatically +from the sources by Stephen Edwards's extdoc. (The Ext system is +available via anonymous FTP from +ic.eecs.berkeley.edu.) +The following guidelines are followed in CUDD to insure consistent and +effective use of automatic extraction. It is recommended that +extensions to CUDD follow the same documentation guidelines. + +

                    +
                  • The documentation of an exported procedure should be sufficient + to allow one to use it without reading the code. It is not necessary + to explain how the procedure works; only what it does. +
                  • +
                  • The SeeAlso + fields should be space-separated lists of function names. The + SeeAlso field of an exported procedure should only reference + other exported procedures. The SeeAlso field of an internal + procedure may reference other internal procedures as well as + exported procedures, but no static procedures. +
                  • +
                  • The return values are detailed in the + Description + field, not in the + Synopsis field. +
                  • +
                  • The parameters are documented alongside their declarations. + Further comments may appear in the Description field. +
                  • +
                  • If the Description field is non-empty--which is the + normal case for an exported procedure--then the synopsis is + repeated--possibly slightly changed--at the beginning of the + Description field. This is so because extdoc will not put the + synopsis in the same HTML file as + the description. +
                  • +
                  • The Synopsis field should be about one line long. +
                  • +
                  + +

                  +


                  + + +next + +up + +previous + +index +
                  + Next: The C++ Interface + Up: CUDD: CU Decision Diagram + Previous: User's Manual +   Index + +
                  +Fabio Somenzi +2012-02-04 +
                  + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node5.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node5.html new file mode 100644 index 000000000..b519a2f97 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node5.html @@ -0,0 +1,130 @@ + + + + + +The C++ Interface + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                  + Next: Acknowledgments + Up: CUDD: CU Decision Diagram + Previous: Programmer's Manual +   Index +
                  +
                  + + +Subsections + + + +
                  + +

                  + +
                  +The C++ Interface +

                  + +

                  + +

                  + +
                  +Compiling and Linking +

                  + +

                  +To build an application that uses the CUDD C++ interface, you should +add +

                  +#include "cuddObj.hh"
                  +
                  +to your source files. In addition to the normal CUDD libraries (see +Section 3.1) you should link +libobj.a to your executable. Refer to the +Makefile in the top level directory of the +distribution for further details. + +

                  + +

                  + +
                  +Basic Manipulation +

                  + +

                  +The following fragment of code illustrates some simple operations on +BDDs using the C++ interface. +

                  +	Cudd mgr(0,0);
                  +	BDD x = mgr.bddVar();
                  +	BDD y = mgr.bddVar();
                  +	BDD f = x * y;
                  +	BDD g = y + !x;
                  +	cout << "f is" << (f <= g ? "" : " not")
                  +	     << " less than or equal to g\n";
                  +
                  +This code creates a manager called mgr and two variables in it. +It then defines two functions f and g in terms of the +variables. Finally, it prints a message based on the comparison of the +two functions. No explicit referencing or dereferencing is required. +The operators are overloaded in the intuitive way. BDDs are freed when +execution leaves the scope in which they are defined or when the +variables referring to them are overwritten. + +

                  +


                  +
                  +Fabio Somenzi +2012-02-04 +
                  + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node6.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node6.html new file mode 100644 index 000000000..1f42c860e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node6.html @@ -0,0 +1,132 @@ + + + + + +Acknowledgments + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                  + Next: Bibliography + Up: CUDD: CU Decision Diagram + Previous: The C++ Interface +   Index +
                  +
                  + + +

                  + +
                  +Acknowledgments +

                  + +

                  +The contributors: Iris Bahar, Hyunwoo Cho, Erica Frohm, Charlie Gaona, +Cheng Hua, Jae-Young Jang, Seh-Woong Jeong, Balakrishna Kumthekar, +Enrico Macii, Bobbie Manne, In-Ho Moon, Curt Musfeldt, Shipra Panda, +Abelardo Pardo, Bernard Plessier, Kavita Ravi, Hyongkyoon Shin, Alan +Shuler, Arun Sivakumaran, Jorgen Sivesind. + +

                  +The early adopters: Gianpiero Cabodi, Jordi Cortadella, Mario Escobar, +Gayani Gamage, Gary Hachtel, Mariano Hermida, Woohyuk Lee, Enric +Pastor, Massimo Poncino, Ellen Sentovich, the students of ECEN5139. + +

                  +I am also particularly indebted to the following people for in-depth +discussions on BDDs: Armin Biere, Olivier Coudert, Arie Gurfinkel, +Geert Janssen, Don Knuth, David Long, Jean Christophe Madre, Ken +McMillan, Shin-Ichi Minato, Jaehong Park, Rajeev Ranjan, Rick Rudell, +Ellen Sentovich, Tom Shiple, Christian Stangier, and Bwolen Yang. + +

                  +Special thanks to Norris Ip for guiding my faltering steps +in the design of the C++ interface. +Gianpiero Cabodi and Stefano Quer have graciously agreed to let me +distribute their dddmp library with CUDD. + +

                  +Masahiro Fujita, Gary Hachtel, and Carl Pixley have provided +encouragement and advice. + +

                  +The National Science Foundation and the Semiconductor Research +Corporation have supported in part the development of this package. + +

                  + +


                  + + +next + +up + +previous + +index +
                  + Next: Bibliography + Up: CUDD: CU Decision Diagram + Previous: The C++ Interface +   Index + +
                  +Fabio Somenzi +2012-02-04 +
                  + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node7.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node7.html new file mode 100644 index 000000000..d7e967ef5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node7.html @@ -0,0 +1,195 @@ + + + + + +Bibliography + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                  + Next: Index + Up: CUDD: CU Decision Diagram + Previous: Acknowledgments +   Index +

                  + + +

                  +Bibliography +

                  1 +
                  +R. I. Bahar, E. A. Frohm, C. M. Gaona, G. D. Hachtel, E. Macii, A. Pardo, and + F. Somenzi. +
                  Algebraic decision diagrams and their applications. +
                  In Proceedings of the International Conference on Computer-Aided + Design, pages 188-191, Santa Clara, CA, November 1993. + +

                  2 +
                  +B. Bollig, M. Löbbing, and I. Wegener. +
                  Simulated annealing to improve variable orderings for OBDDs. +
                  Presented at the International Workshop on Logic Synthesis, + Granlibakken, CA, May 1995. + +

                  3 +
                  +K. S. Brace, R. L. Rudell, and R. E. Bryant. +
                  Efficient implementation of a BDD package. +
                  In Proceedings of the 27th Design Automation Conference, pages + 40-45, Orlando, FL, June 1990. + +

                  4 +
                  +R. K. Brayton et al. +
                  VIS: A system for verification and synthesis. +
                  Technical Report UCB/ERL M95/104, Electronics Research Lab, Univ. of + California, December 1995. + +

                  5 +
                  +R. E. Bryant. +
                  Graph-based algorithms for Boolean function manipulation. +
                  IEEE Transactions on Computers, C-35(8):677-691, August 1986. + +

                  6 +
                  +R. Drechsler, B. Becker, and N. Göckel. +
                  A genetic algorithm for variable ordering of OBDDs. +
                  Presented at the International Workshop on Logic Synthesis, + Granlibakken, CA, May 1995. + +

                  7 +
                  +S. J. Friedman and K. J. Supowit. +
                  Finding the optimal variable ordering for binary decision diagrams. +
                  IEEE Transactions on Computers, 39(5):710-713, May 1990. + +

                  8 +
                  +M. Fujita, Y. Matsunaga, and T. Kakuda. +
                  On variable ordering of binary decision diagrams for the application + of multi-level logic synthesis. +
                  In Proceedings of the European Conference on Design Automation, + pages 50-54, Amsterdam, February 1991. + +

                  9 +
                  +M. Held and R. M. Karp. +
                  A dynamic programming approach to sequencing problems. +
                  J. SIAM, 10(1):196-210, 1962. + +

                  10 +
                  +N. Ishiura, H. Sawada, and S. Yajima. +
                  Minimization of binary decision diagrams based on exchanges of + variables. +
                  In Proceedings of the International Conference on Computer-Aided + Design, pages 472-475, Santa Clara, CA, November 1991. + +

                  11 +
                  +S.-W. Jeong, T.-S. Kim, and F. Somenzi. +
                  An efficient method for optimal BDD ordering computation. +
                  In International Conference on VLSI and CAD (ICVC'93), Taejon, + Korea, November 1993. + +

                  12 +
                  +S.-I. Minato. +
                  Zero-suppressed BDDs for set manipulation in combinatorial + problems. +
                  In Proceedings of the Design Automation Conference, pages + 272-277, Dallas, TX, June 1993. + +

                  13 +
                  +S. Panda and F. Somenzi. +
                  Who are the variables in your neighborhood. +
                  In Proceedings of the International Conference on Computer-Aided + Design, pages 74-77, San Jose, CA, November 1995. + +

                  14 +
                  +S. Panda, F. Somenzi, and B. F. Plessier. +
                  Symmetry detection and dynamic variable ordering of decision + diagrams. +
                  In Proceedings of the International Conference on Computer-Aided + Design, pages 628-631, San Jose, CA, November 1994. + +

                  15 +
                  +B. F. Plessier. +
                  A General Framework for Verification of Sequential Circuits. +
                  PhD thesis, University of Colorado at Boulder, Dept. of Electrical + and Computer Engineering, 1993. + +

                  16 +
                  +R. Rudell. +
                  Dynamic variable ordering for ordered binary decision diagrams. +
                  In Proceedings of the International Conference on Computer-Aided + Design, pages 42-47, Santa Clara, CA, November 1993. + +

                  17 +
                  +E. M. Sentovich, K. J. Singh, C. Moon, H. Savoj, R. K. Brayton, and + A. Sangiovanni-Vincentelli. +
                  Sequential circuit design using synthesis and optimization. +
                  In Proceedings of the International Conference on Computer + Design, pages 328-333, Cambridge, MA, October 1992. +
                  + + + + + + + +

                  +


                  +
                  +Fabio Somenzi +2012-02-04 +
                  + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/doc/node8.html b/resources/3rdparty/cudd-2.5.0/cudd/doc/node8.html new file mode 100644 index 000000000..a723fa181 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/doc/node8.html @@ -0,0 +1,848 @@ + + + + + +Index + + + + + + + + + + + + + + + + +next + +up + +previous +
                  + Up: CUDD: CU Decision Diagram + Previous: Bibliography +
                  +
                  + +
                  + +

                  +Index +

                  +
                  ADD +
                  Introduction + | Nodes + | New Constants + | Basic ADD Manipulation +
                  aggregation +
                  Variable Reordering for BDDs +
                  Algebraic Decision Diagram +
                  see ADD +
                  arc +
                  +
                  complement +
                  New BDD and ADD + | Writing Decision Diagrams to + | Writing Decision Diagrams to + | Complement Arcs + | Complement Arcs +
                  regular +
                  Writing Decision Diagrams to + | Writing Decision Diagrams to + | Complement Arcs +
                  +
                  background value +
                  Background +
                  BDD +
                  Introduction + | Nodes + | One, Logic Zero, and + | Basic BDD Manipulation +
                  Binary Decision Diagram +
                  see BDD +
                  box +
                  +
                  black +
                  Introduction +
                  clear +
                  Introduction + | Compiling and Linking +
                  +
                  cache +
                  Cache + | Cache + | Cache + | Initializing and Shutting Down + | Complement Arcs + | The Cache +
                  +
                  collision +
                  Non Modifiable Parameters +
                  collision list +
                  The Unique Table +
                  deletion +
                  Non Modifiable Parameters +
                  local +
                  The Cache + | Local Caches +
                  lossless +
                  Local Caches +
                  reward-based resizing +
                  Cache Sizing + | Cache Sizing +
                  sizing +
                  Cache Sizing +
                  +
                  cacheSize +
                  Initializing and Shutting Down +
                  canonical +
                  The Manager + | Local Caches +
                  compiling +
                  Compiling and Linking + | Predefined Constants + | Compiling and Linking +
                  configuration +
                  The CUDD Package +
                  conversion +
                  +
                  of ADDs to BDDs +
                  Converting ADDs to BDDs +
                  of BDDs to ADDs +
                  Converting ADDs to BDDs +
                  of BDDs to ZDDs +
                  Basic ZDD Manipulation + | Converting BDDs to ZDDs +
                  of ZDDs to BDDs +
                  Converting BDDs to ZDDs +
                  +
                  cube sets +
                  Introduction +
                  cudd.h +
                  Compiling and Linking + | Variable Reordering for BDDs + | Saturating Increments and Decrements +
                  Cudd_addApply +
                  Basic ADD Manipulation + | Basic ADD Manipulation +
                  Cudd_addBddInterval +
                  Converting ADDs to BDDs +
                  Cudd_addBddPattern +
                  Converting ADDs to BDDs +
                  Cudd_addBddThreshold +
                  Converting ADDs to BDDs +
                  Cudd_addConst +
                  New Constants +
                  Cudd_addHarwell +
                  Background +
                  Cudd_AddHook +
                  Hooks +
                  Cudd_addIthBit +
                  Converting ADDs to BDDs +
                  Cudd_addIthVar +
                  New BDD and ADD +
                  Cudd_addNewVar +
                  New BDD and ADD +
                  Cudd_addNewVarAtLevel +
                  New BDD and ADD + | Grouping Variables +
                  Cudd_addRead +
                  Background +
                  Cudd_addTimes +
                  Basic ADD Manipulation +
                  Cudd_AutodynDisable +
                  Variable Reordering for BDDs +
                  Cudd_AutodynDisableZdd +
                  Variable Reordering for ZDDs +
                  Cudd_AutodynEnable +
                  Variable Reordering for BDDs + | Variable Reordering for BDDs +
                  Cudd_AutodynEnableZdd +
                  Variable Reordering for ZDDs +
                  Cudd_bddAnd +
                  Basic BDD Manipulation + | Basic BDD Manipulation + | Basic ADD Manipulation +
                  Cudd_bddAndLimit +
                  Timeouts and Limits +
                  Cudd_bddConstrain +
                  Nodes +
                  Cudd_bddIte +
                  Basic BDD Manipulation +
                  Cudd_bddIthVar +
                  New BDD and ADD +
                  Cudd_bddNewVar +
                  New BDD and ADD + | New BDD and ADD + | New BDD and ADD +
                  Cudd_bddNewVarAtLevel +
                  New BDD and ADD + | Grouping Variables +
                  Cudd_BddToAdd +
                  Converting ADDs to BDDs +
                  Cudd_bddXor +
                  Basic ADD Manipulation +
                  CUDD_CACHE_SLOTS +
                  Initializing and Shutting Down +
                  Cudd_CheckKeys +
                  Debugging +
                  Cudd_CheckZeroRef +
                  Debugging +
                  Cudd_CountMinterm +
                  Background +
                  Cudd_DebugCheck +
                  Debugging +
                  Cudd_DelayedDerefBdd +
                  Non Modifiable Parameters +
                  Cudd_Deref +
                  Cudd_RecursiveDeref vs. Cudd_Deref + | Saturating Increments and Decrements +
                  Cudd_DumpBlif +
                  Writing Decision Diagrams to +
                  Cudd_DumpDaVinci +
                  Writing Decision Diagrams to +
                  Cudd_DumpDot +
                  Writing Decision Diagrams to +
                  Cudd_ForeachCube +
                  Nodes + | Background +
                  Cudd_ForeachNode +
                  Nodes +
                  Cudd_HookType +
                  Hooks +
                  Cudd_Init +
                  Initializing and Shutting Down + | Initializing and Shutting Down +
                  Cudd_MakeTreeNode +
                  Grouping Variables + | Grouping Variables +
                  Cudd_MakeZddTreeNode +
                  Variable Reordering for ZDDs +
                  Cudd_Not +
                  One, Logic Zero, and +
                  Cudd_PrintInfo +
                  Gathering and Interpreting Statistics +
                  Cudd_PrintMinterm +
                  Background +
                  Cudd_Quit +
                  Initializing and Shutting Down +
                  Cudd_ReadBackground +
                  Background +
                  Cudd_ReadEpsilon +
                  Predefined Constants +
                  Cudd_ReadErrorCode +
                  NULL Return Values +
                  Cudd_ReadInvPerm +
                  Basic BDD Manipulation +
                  Cudd_ReadLogicZero +
                  One, Logic Zero, and +
                  Cudd_ReadLooseUpto +
                  Setting Parameters +
                  Cudd_ReadMaxGrowth +
                  Variable Reordering for BDDs +
                  Cudd_ReadMinusInfinity +
                  Predefined Constants +
                  Cudd_ReadOne +
                  One, Logic Zero, and +
                  Cudd_ReadPlusInfinity +
                  Predefined Constants +
                  Cudd_ReadReorderings +
                  Allowing Asynchronous Reordering +
                  Cudd_ReadSiftMaxVar +
                  Variable Reordering for BDDs +
                  Cudd_ReadTree +
                  Grouping Variables +
                  Cudd_ReadZddOne +
                  One, Logic Zero, and + | Basic ZDD Manipulation +
                  Cudd_ReadZero +
                  Predefined Constants +
                  Cudd_RecursiveDeref +
                  Nodes + | Reference Counts + | Reference Counts + | Reference Counts + | Cudd_RecursiveDeref vs. Cudd_Deref + | When Increasing the Reference + | Saturating Increments and Decrements + | Local Caches + | Debugging +
                  Cudd_RecursiveDerefZdd +
                  Nodes + | Reference Counts + | Reference Counts + | Reference Counts + | When Increasing the Reference + | Saturating Increments and Decrements +
                  Cudd_ReduceHeap +
                  Variable Reordering for BDDs + | Variable Reordering for BDDs + | Variable Reordering for BDDs +
                  Cudd_Ref +
                  Nodes + | Basic BDD Manipulation + | Reference Counts + | When Increasing the Reference +
                  Cudd_Regular +
                  Complement Arcs +
                  CUDD_REORDER_ANNEALING +
                  Variable Reordering for BDDs +
                  CUDD_REORDER_EXACT +
                  Variable Reordering for BDDs +
                  CUDD_REORDER_GENETIC +
                  Variable Reordering for BDDs +
                  CUDD_REORDER_GROUP_SIFT +
                  Variable Reordering for BDDs +
                  CUDD_REORDER_GROUP_SIFT_CONV +
                  Variable Reordering for BDDs +
                  CUDD_REORDER_NONE +
                  Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                  CUDD_REORDER_RANDOM +
                  Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                  CUDD_REORDER_RANDOM_PIVOT +
                  Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                  CUDD_REORDER_SAME +
                  Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                  CUDD_REORDER_SIFT +
                  Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                  CUDD_REORDER_SIFT_CONVERGE +
                  Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                  CUDD_REORDER_SYMM_SIFT +
                  Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                  CUDD_REORDER_SYMM_SIFT_CONV +
                  Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                  CUDD_REORDER_WINDOW2 +
                  Variable Reordering for BDDs +
                  CUDD_REORDER_WINDOW2_CONV +
                  Variable Reordering for BDDs +
                  CUDD_REORDER_WINDOW3 +
                  Variable Reordering for BDDs +
                  CUDD_REORDER_WINDOW3_CONV +
                  Variable Reordering for BDDs +
                  CUDD_REORDER_WINDOW4 +
                  Variable Reordering for BDDs +
                  CUDD_REORDER_WINDOW4_CONV +
                  Variable Reordering for BDDs +
                  Cudd_SetEpsilon +
                  Predefined Constants +
                  Cudd_SetLooseUpTo +
                  Setting Parameters +
                  Cudd_SetMaxCacheHard +
                  Modifiable Parameters +
                  Cudd_SetMaxGrowth +
                  Variable Reordering for BDDs +
                  Cudd_SetSiftMaxVar +
                  Variable Reordering for BDDs +
                  Cudd_SetTimeLimit +
                  Timeouts and Limits +
                  Cudd_SetTree +
                  Grouping Variables +
                  Cudd_ShuffleHeap +
                  Variable Reordering for BDDs +
                  Cudd_StdPostReordHook +
                  Hooks +
                  Cudd_StdPreReordHook +
                  Hooks +
                  Cudd_SymmProfile +
                  Variable Reordering for BDDs +
                  CUDD_UNIQUE_SLOTS +
                  Initializing and Shutting Down +
                  Cudd_zddDumpDot +
                  Writing Decision Diagrams to +
                  Cudd_zddIsop +
                  Basic ZDD Manipulation +
                  Cudd_zddIthVar +
                  New ZDD Variables +
                  Cudd_zddPortFromBdd +
                  Converting BDDs to ZDDs +
                  Cudd_zddPortToBdd +
                  Converting BDDs to ZDDs +
                  Cudd_zddRealignDisable +
                  Keeping Consistent Variable Orders +
                  Cudd_zddRealignEnable +
                  Keeping Consistent Variable Orders +
                  Cudd_zddReduceHeap +
                  Variable Reordering for ZDDs +
                  Cudd_zddShuffleHeap +
                  Variable Reordering for ZDDs +
                  Cudd_zddVarsFromBddVars +
                  Converting BDDs to ZDDs + | Converting BDDs to ZDDs +
                  Cudd_zddWeakDiv +
                  Basic ZDD Manipulation +
                  cuddCacheInsert +
                  The Cache +
                  cuddCacheInsert1 +
                  The Cache +
                  cuddCacheInsert2 +
                  The Cache +
                  cuddCacheLookup +
                  The Cache +
                  cuddCacheLookup1 +
                  The Cache +
                  cuddCacheLookup2 +
                  The Cache +
                  CUDDDIR +
                  Using the CUDD Package +
                  cuddHeapProfile +
                  Debugging +
                  cuddI +
                  The Unique Table +
                  cuddInt.h +
                  Debugging +
                  cuddIZ +
                  The Unique Table +
                  cuddSatDec +
                  Saturating Increments and Decrements +
                  cuddSatInc +
                  Saturating Increments and Decrements +
                  cuddUniqueConst +
                  Reference Counts + | Reference Counts + | Reference Counts +
                  cuddUniqueInter +
                  Reference Counts + | Reference Counts + | Reference Counts + | Complement Arcs + | Complement Arcs + | Allowing Asynchronous Reordering + | Allowing Asynchronous Reordering + | Allowing Asynchronous Reordering +
                  cuddUniqueInterZdd +
                  Reference Counts + | Reference Counts + | Reference Counts + | Allowing Asynchronous Reordering +
                  DD_CACHE_PROFILE +
                  Extended Statistics and Reporting +
                  DD_DEBUG +
                  Debugging +
                  DD_STATS +
                  Extended Statistics and Reporting +
                  DD_UNIQUE_PROFILE +
                  Extended Statistics and Reporting +
                  DD_VERBOSE +
                  Extended Statistics and Reporting +
                  DdManager +
                  The Manager + | Initializing and Shutting Down +
                  DdNode +
                  Nodes + | The Cache +
                  debugging +
                  Debugging +
                  DEC Alpha +
                  Predefined Constants + | Using the CUDD Package +
                  documentation +
                  Guidelines for Documentation +
                  +
                  Description +
                  Guidelines for Documentation +
                  HTML files +
                  Guidelines for Documentation +
                  SeeAlso +
                  Guidelines for Documentation +
                  Synopsis +
                  Guidelines for Documentation +
                  +
                  dot +
                  see graph, drawing +
                  Epsilon +
                  Predefined Constants +
                  extdoc +
                  see documentation +
                  floating point +
                  Predefined Constants +
                  +
                  double (C type) +
                  Nodes +
                  IEEE Standard 754 +
                  Predefined Constants +
                  +
                  free list +
                  Reference Counts +
                  FTP +
                  The CUDD Package + | CUDD Friends + | Using the CUDD Package + | Guidelines for Documentation +
                  function +
                  +
                  characteristic +
                  Introduction + | Converting BDDs to ZDDs +
                  cover +
                  Basic ZDD Manipulation + | Converting BDDs to ZDDs + | Converting BDDs to ZDDs +
                  +
                  irredundant +
                  Basic ZDD Manipulation +
                  +
                  minterms +
                  Background + | Allowing Asynchronous Reordering +
                  ON-set +
                  Introduction +
                  sum of products +
                  Background +
                  switching +
                  Introduction + | Introduction +
                  +
                  garbage collection +
                  Nodes + | Cache + | Setting Parameters + | Reference Counts + | Reference Counts + | The Cache + | Local Caches + | The Unique Table +
                  +
                  hooks +
                  Hooks +
                  +
                  gcc +
                  Predefined Constants +
                  generator +
                  Nodes +
                  global variables +
                  The Manager +
                  graph +
                  +
                  arc capacity +
                  Background +
                  arc length +
                  Background +
                  drawing +
                  Writing Decision Diagrams to + | Writing Decision Diagrams to +
                  +
                  growth +
                  Setting Parameters +
                  gzip +
                  The CUDD Package +
                  HAVE_IEEE_754 +
                  Predefined Constants +
                  header files +
                  Variable Reordering for BDDs + | Saturating Increments and Decrements +
                  hook +
                  Hooks +
                  infinities +
                  Predefined Constants +
                  installation +
                  The CUDD Package +
                  Intel Pentium 4 +
                  The CUDD Package +
                  interface +
                  +
                  cache +
                  The Cache +
                  SIS +
                  The SIS/VIS Interface + | Using the CUDD Package +
                  VIS +
                  The SIS/VIS Interface +
                  +
                  libraries +
                  The CUDD Package +
                  +
                  cudd +
                  Compiling and Linking +
                  dddmp +
                  Saving and Restoring BDDs +
                  mtr +
                  Compiling and Linking + | Grouping Variables +
                  obj +
                  Compiling and Linking +
                  st +
                  Compiling and Linking + | The Cache +
                  util +
                  Compiling and Linking +
                  +
                  Makefile +
                  Compiling and Linking + | Predefined Constants + | Compiling and Linking +
                  manager +
                  The Manager + | The Manager + | Constant Functions +
                  matrix +
                  +
                  sparse +
                  Background +
                  +
                  maxCache +
                  Cache Sizing +
                  maxMemory +
                  Initializing and Shutting Down +
                  MinusInfinity +
                  Predefined Constants +
                  MTR_DEFAULT +
                  Grouping Variables +
                  MTR_FIXED +
                  Grouping Variables +
                  nanotrav +
                  The CUDD Package + | The CUDD Package +
                  node +
                  Nodes +
                  +
                  constant +
                  Nodes + | Constant Functions + | One, Logic Zero, and + | Predefined Constants + | Background + | New Constants + | Reference Counts + | When Increasing the Reference +
                  +
                  value +
                  Nodes +
                  +
                  dead +
                  Reference Counts + | The Cache + | The Unique Table +
                  dereference +
                  Basic ADD Manipulation +
                  reclaimed +
                  The Unique Table +
                  recycling +
                  Nodes +
                  reference +
                  Basic ADD Manipulation +
                  reference count +
                  Nodes + | Nodes + | Basic BDD Manipulation + | Basic BDD Manipulation + | Reference Counts + | Reference Counts + | Reference Counts + | When Increasing the Reference + | Saturating Increments and Decrements + | The Cache + | Local Caches + | Debugging +
                  +
                  saturated +
                  Debugging +
                  +
                  terminal +
                  see node, constant +
                  variable index +
                  Nodes +
                  +
                  numSlots +
                  Initializing and Shutting Down +
                  numVars +
                  Initializing and Shutting Down +
                  numVarsZ +
                  Initializing and Shutting Down +
                  PlusInfinity +
                  Predefined Constants + | Background +
                  projection functions +
                  Creating Variables + | New BDD and ADD + | New BDD and ADD + | New BDD and ADD + | New ZDD Variables + | Basic BDD Manipulation + | Basic ADD Manipulation + | Basic ZDD Manipulation + | Basic ZDD Manipulation + | Debugging +
                  README file +
                  The CUDD Package + | The CUDD Package +
                  reordering +
                  Introduction + | Introduction + | Nodes + | The Cache +
                  +
                  abort and retry +
                  Allowing Asynchronous Reordering +
                  asynchronous +
                  Variable Reordering for BDDs + | Allowing Asynchronous Reordering +
                  converging +
                  Variable Reordering for BDDs + | Variable Reordering for BDDs + | Variable Reordering for BDDs + | Variable Reordering for BDDs +
                  Cudd_ReorderingType +
                  Variable Reordering for BDDs +
                  dynamic +
                  Introduction + | Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                  exact +
                  Variable Reordering for BDDs +
                  function wrapper +
                  Allowing Asynchronous Reordering + | Allowing Asynchronous Reordering +
                  genetic +
                  Variable Reordering for BDDs +
                  group +
                  Variable Reordering for BDDs + | Variable Reordering for BDDs +
                  hooks +
                  Hooks +
                  interruptible procedure +
                  Allowing Asynchronous Reordering +
                  of BDDs and ADDs +
                  Variable Reordering for BDDs +
                  of ZDDs +
                  Basic ZDD Manipulation + | Variable Reordering for ZDDs +
                  random +
                  Variable Reordering for BDDs +
                  sifting +
                  Variable Reordering for BDDs + | Variable Reordering for BDDs +
                  simulated annealing +
                  Variable Reordering for BDDs +
                  symmetric +
                  Variable Reordering for BDDs +
                  threshold +
                  Variable Reordering for BDDs + | Allowing Asynchronous Reordering +
                  window +
                  Variable Reordering for BDDs +
                  +
                  saturating +
                  +
                  decrements +
                  Saturating Increments and Decrements +
                  increments +
                  Saturating Increments and Decrements +
                  +
                  SISDIR +
                  Using the CUDD Package +
                  SIZEOF_INT +
                  Saturating Increments and Decrements + | Saturating Increments and Decrements +
                  SIZEOF_VOID_P +
                  Saturating Increments and Decrements + | Saturating Increments and Decrements +
                  statistical counters +
                  The Manager + | Reference Counts + | Cache Sizing +
                  statistics +
                  Gathering and Interpreting Statistics +
                  subtable +
                  Initializing and Shutting Down + | Reference Counts +
                  symmetry +
                  Variable Reordering for BDDs +
                  table +
                  +
                  computed +
                  Cache +
                  growth +
                  Setting Parameters +
                  hash +
                  The Manager + | The Unique Table +
                  unique +
                  Nodes + | The Manager + | The Manager + | Initializing and Shutting Down + | Initializing and Shutting Down + | Setting Parameters + | Variable Reordering for BDDs + | Reference Counts + | Cache Sizing + | Cache Sizing + | The Unique Table +
                  +
                  fast growth +
                  The Unique Table +
                  reward-based resizing +
                  The Unique Table +
                  slow growth +
                  The Unique Table +
                  +
                  +
                  timeout +
                  Timeouts and Limits +
                  variable +
                  +
                  groups +
                  Grouping Variables +
                  order +
                  Nodes + | New BDD and ADD +
                  permutation +
                  Nodes + | The Unique Table +
                  tree +
                  Grouping Variables + | Grouping Variables +
                  +
                  ZDD +
                  Introduction + | Nodes + | New ZDD Variables + | Basic ZDD Manipulation + | Converting BDDs to ZDDs +
                  zero +
                  +
                  arithmetic +
                  One, Logic Zero, and + | New BDD and ADD + | Converting ADDs to BDDs +
                  logical +
                  One, Logic Zero, and + | Converting ADDs to BDDs +
                  +
                  Zero-suppressed Binary Decision Diagram +
                  see ZDD + +
                  +

                  +
                  +Fabio Somenzi +2012-02-04 +
                  + + diff --git a/resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.mat b/resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.mat new file mode 100644 index 000000000..b0dd0a0a8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.mat @@ -0,0 +1,53 @@ +7 9 +0 0 1 +0 1 1 +0 2 1 +0 3 4 +0 4 3 +0 5 3 +0 6 3 +0 8 3 +1 0 4 +1 1 3 +1 2 2 +1 3 4 +1 4 1 +1 5 2 +1 6 4 +1 8 3 +2 0 1 +2 1 1 +2 2 4 +2 4 2 +2 5 3 +2 6 3 +2 8 3 +3 0 2 +3 1 1 +3 3 4 +3 4 4 +3 5 1 +3 8 1 +4 0 2 +4 1 3 +4 2 2 +4 3 4 +4 4 1 +4 5 1 +4 6 2 +4 8 2 +5 0 3 +5 1 3 +5 2 4 +5 3 4 +5 4 1 +5 5 3 +5 6 3 +5 8 4 +6 1 1 +6 2 1 +6 3 4 +6 4 2 +6 5 4 +6 6 4 +6 8 2 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.out b/resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.out new file mode 100644 index 000000000..4dc72222d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/r7x8.1.out @@ -0,0 +1,396 @@ +# TestCudd Version #1.0, Release date 3/17/01 +# ./testcudd -p2 r7x8.1.mat +:name: r7x8.1.mat: 7 rows 9 columns +:1: M: 63 nodes 5 leaves 52 minterms +000000-- 1 +000001-0 1 +000001-1 4 +000010-0 4 +000010-1 3 +000011-0 2 +000011-1 4 +000100-- 3 +000101-0 3 +000110-0 1 +000110-1 2 +000111-0 4 +001000-- 1 +001001-0 4 +001010-0 2 +001010-1 1 +001011-1 4 +001100-0 2 +001100-1 3 +001101-0 3 +001110-0 4 +001110-1 1 +0100-0-0 3 +011000-0 3 +011010-0 1 +100000-0 2 +100000-1 3 +100001-0 2 +100001-1 4 +100010-- 3 +100011-- 4 +100100-- 1 +100101-0 2 +100110-0 1 +100110-1 3 +100111-0 3 +101000-1 1 +101001-0 1 +101001-1 4 +101100-0 2 +101100-1 4 +101101-0 4 +110000-0 2 +110010-0 4 +111000-0 2 + +:2: time to read the matrix = 0.00 sec +:3: C: 22 nodes 1 leaves 52 minterms +0000---- 1 +0001-0-- 1 +0001-1-0 1 +001000-- 1 +001001-0 1 +001010-- 1 +001011-1 1 +001100-- 1 +001101-0 1 +001110-- 1 +01-0-0-0 1 +1000---- 1 +1001-0-- 1 +1001-1-0 1 +101000-1 1 +101001-- 1 +101100-- 1 +101101-0 1 +1100-0-0 1 +111000-0 1 + +Testing iterator on cubes: +000000-- 1 +000001-0 1 +000001-1 4 +000010-0 4 +000010-1 3 +000011-0 2 +000011-1 4 +000100-- 3 +000101-0 3 +000110-0 1 +000110-1 2 +000111-0 4 +001000-- 1 +001001-0 4 +001010-0 2 +001010-1 1 +001011-1 4 +001100-0 2 +001100-1 3 +001101-0 3 +001110-0 4 +001110-1 1 +0100-0-0 3 +011000-0 3 +011010-0 1 +100000-0 2 +100000-1 3 +100001-0 2 +100001-1 4 +100010-- 3 +100011-- 4 +100100-- 1 +100101-0 2 +100110-0 1 +100110-1 3 +100111-0 3 +101000-1 1 +101001-0 1 +101001-1 4 +101100-0 2 +101100-1 4 +101101-0 4 +110000-0 2 +110010-0 4 +111000-0 2 + +Testing prime expansion of cubes: +-000---- 1 +-00--0-- 1 +0--0-0-0 1 +--00-0-0 1 +-0-100-- 1 +10-001-- 1 +-00----0 1 +00---0-- 1 +-1-000-0 1 +-0--01-0 1 +-0--00-1 1 +00-01--1 1 + +Testing iterator on primes (CNF): +-0-0---- 1 +-0---0-- 1 +0-0-0--- 1 +-0-----0 1 +---0-0-0 1 +0101-1-1 1 +--0-00-1 1 +1-0-10-0 1 + +Cache used slots = 58.06% (expected 58.94%) +xor1: 14 nodes 1 leaves 28 minterms +000--1-1 1 +001-11-1 1 +01---0-0 1 +100--1-1 1 +101-00-0 1 +101-01-1 1 +110--0-0 1 +111-00-0 1 + +Chosen minterm for Hamming distance test: : 9 nodes 1 leaves 1 minterms +11110010 1 + +Minimum Hamming distance = 1 +ycube: 5 nodes 1 leaves 8 minterms +-0-0-0-0 1 + +CP: 11 nodes 1 leaves 7 minterms +00-0-0-0 1 +1000-0-0 1 +101000-1 1 + +:4: ineq: 10 nodes 1 leaves 42 minterms +001000-- 1 +00101--- 1 +1000---- 1 +100100-- 1 +10011--- 1 +101----- 1 +111000-- 1 +11101--- 1 + +10------ 1 +-01----- 1 +1-1----- 1 +-0-0---- 1 +1--0---- 1 +-0--10-- 1 +--1010-- 1 +1---10-- 1 + +:4: ess: 1 nodes 1 leaves 128 minterms +-------- 1 + +:5: shortP: 7 nodes 1 leaves 2 minterms +000000-- 1 + +:5b: largest: 4 nodes 1 leaves 16 minterms +01-1---- 1 + +The value of M along the chosen shortest path is 1 +:6: shortP: 5 nodes 1 leaves 8 minterms +0000---- 1 + +Support of f: : 8 nodes 1 leaves 2 minterms +111111-1 1 + +Size of the support of f: 7 +Size of the support of f: 7 +Support of f and g: : 8 nodes 1 leaves 2 minterms +111111-1 1 + +Size of the support of f and g: 7 +Size of the support of f and g: 7 +Support common to f and g: : 5 nodes 1 leaves 16 minterms +-1-1-1-1 1 + +Support private to f: : 4 nodes 1 leaves 32 minterms +1-1-1--- 1 + +Support private to g: : 1 nodes 1 leaves 256 minterms +-------- 1 + +Average distance: 4138.57 +Number of variables = 8 Number of slots = 2304 +Number of keys = 999 Number of min dead = 9216 +walsh1: 16 nodes 2 leaves 256 minterms +-0--0--0--0- 1 +-0--0--0--10 1 +-0--0--0--11 -1 +-0--0--10-0- 1 +-0--0--10-10 1 +-0--0--10-11 -1 +-0--0--11-0- -1 +-0--0--11-10 -1 +-0--0--11-11 1 +-0--10-0--0- 1 +-0--10-0--10 1 +-0--10-0--11 -1 +-0--10-10-0- 1 +-0--10-10-10 1 +-0--10-10-11 -1 +-0--10-11-0- -1 +-0--10-11-10 -1 +-0--10-11-11 1 +-0--11-0--0- -1 +-0--11-0--10 -1 +-0--11-0--11 1 +-0--11-10-0- -1 +-0--11-10-10 -1 +-0--11-10-11 1 +-0--11-11-0- 1 +-0--11-11-10 1 +-0--11-11-11 -1 +-10-0--0--0- 1 +-10-0--0--10 1 +-10-0--0--11 -1 +-10-0--10-0- 1 +-10-0--10-10 1 +-10-0--10-11 -1 +-10-0--11-0- -1 +-10-0--11-10 -1 +-10-0--11-11 1 +-10-10-0--0- 1 +-10-10-0--10 1 +-10-10-0--11 -1 +-10-10-10-0- 1 +-10-10-10-10 1 +-10-10-10-11 -1 +-10-10-11-0- -1 +-10-10-11-10 -1 +-10-10-11-11 1 +-10-11-0--0- -1 +-10-11-0--10 -1 +-10-11-0--11 1 +-10-11-10-0- -1 +-10-11-10-10 -1 +-10-11-10-11 1 +-10-11-11-0- 1 +-10-11-11-10 1 +-10-11-11-11 -1 +-11-0--0--0- -1 +-11-0--0--10 -1 +-11-0--0--11 1 +-11-0--10-0- -1 +-11-0--10-10 -1 +-11-0--10-11 1 +-11-0--11-0- 1 +-11-0--11-10 1 +-11-0--11-11 -1 +-11-10-0--0- -1 +-11-10-0--10 -1 +-11-10-0--11 1 +-11-10-10-0- -1 +-11-10-10-10 -1 +-11-10-10-11 1 +-11-10-11-0- 1 +-11-10-11-10 1 +-11-10-11-11 -1 +-11-11-0--0- 1 +-11-11-0--10 1 +-11-11-0--11 -1 +-11-11-10-0- 1 +-11-11-10-10 1 +-11-11-10-11 -1 +-11-11-11-0- -1 +-11-11-11-10 -1 +-11-11-11-11 1 + +wtw: 14 nodes 2 leaves 16 minterms +0-00-00-00-0 16 +0-00-00-01-1 16 +0-00-01-10-0 16 +0-00-01-11-1 16 +0-01-10-00-0 16 +0-01-10-01-1 16 +0-01-11-10-0 16 +0-01-11-11-1 16 +1-10-00-00-0 16 +1-10-00-01-1 16 +1-10-01-10-0 16 +1-10-01-11-1 16 +1-11-10-00-0 16 +1-11-10-01-1 16 +1-11-11-10-0 16 +1-11-11-11-1 16 + +Average length of non-empty lists = 1 +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000 +Maximum number of variable swaps per reordering: 2000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: no +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: no +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 0 +Arc violation threshold: 0 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 4004 +**** CUDD non-modifiable parameters **** +Memory in use: 4274508 +Peak number of nodes: 2044 +Peak number of live nodes: 119 +Number of BDD variables: 9 +Number of ZDD variables: 0 +Number of cache entries: 2048 +Number of cache look-ups: 2864 +Number of cache hits: 729 +Number of cache insertions: 2301 +Number of cache collisions: 947 +Number of cache deletions: 1351 +Cache used slots = 66.11% (expected 67.49%) +Soft limit for cache size: 13312 +Number of buckets in unique table: 2560 +Used buckets in unique table: 0.51% (expected 0.51%) +Number of BDD and ADD nodes: 13 +Number of ZDD nodes: 0 +Number of dead BDD and ADD nodes: 0 +Number of dead ZDD nodes: 0 +Total number of nodes allocated: 1095 +Total number of nodes reclaimed: 967 +Garbage collections so far: 1 +Time for garbage collection: 0.00 sec +Reorderings so far: 0 +Time for reordering: 0.00 sec +total time = 0.00 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 0.0 seconds +System time 0.0 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131653K +Virtual data size = 152K + data size initialized = 18K + data size uninitialized = 1K + data size sbrk = 133K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 0 +Minor page faults = 1330 +Swaps = 0 +Input blocks = 0 +Output blocks = 16 +Context switch (voluntary) = 0 +Context switch (involuntary) = 1 diff --git a/resources/3rdparty/cudd-2.5.0/cudd/testcudd.c b/resources/3rdparty/cudd-2.5.0/cudd/testcudd.c new file mode 100644 index 000000000..a5d4aa232 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/cudd/testcudd.c @@ -0,0 +1,1178 @@ +/**CFile*********************************************************************** + + FileName [testcudd.c] + + PackageName [cudd] + + Synopsis [Sanity check tests for some CUDD functions.] + + Description [testcudd reads a matrix with real coefficients and + transforms it into an ADD. It then performs various operations on + the ADD and on the BDD corresponding to the ADD pattern. Finally, + testcudd tests functions relate to Walsh matrices and matrix + multiplication.] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define TESTCUDD_VERSION "TestCudd Version #1.0, Release date 3/17/01" + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: testcudd.c,v 1.23 2012/02/05 05:30:29 fabio Exp $"; +#endif + +static const char *onames[] = { "C", "M" }; /* names of functions to be dumped */ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void usage (char * prog); +static FILE *open_file (char *filename, const char *mode); +static int testIterators (DdManager *dd, DdNode *M, DdNode *C, int pr); +static int testXor (DdManager *dd, DdNode *f, int pr, int nvars); +static int testHamming (DdManager *dd, DdNode *f, int pr); +static int testWalsh (DdManager *dd, int N, int cmu, int approach, int pr); +static int testSupport(DdManager *dd, DdNode *f, DdNode *g, int pr); + +/**AutomaticEnd***************************************************************/ + + +/**Function******************************************************************** + + Synopsis [Main function for testcudd.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +main(int argc, char * const *argv) +{ + FILE *fp; /* pointer to input file */ + char *file = (char *) ""; /* input file name */ + FILE *dfp = NULL; /* pointer to dump file */ + FILE *savefp = NULL;/* pointer to save current manager's stdout setting */ + char *dfile; /* file for DD dump */ + DdNode *dfunc[2]; /* addresses of the functions to be dumped */ + DdManager *dd; /* pointer to DD manager */ + DdNode *one; /* fast access to constant function */ + DdNode *M; + DdNode **x; /* pointers to variables */ + DdNode **y; /* pointers to variables */ + DdNode **xn; /* complements of row variables */ + DdNode **yn_; /* complements of column variables */ + DdNode **xvars; + DdNode **yvars; + DdNode *C; /* result of converting from ADD to BDD */ + DdNode *ess; /* cube of essential variables */ + DdNode *shortP; /* BDD cube of shortest path */ + DdNode *largest; /* BDD of largest cube */ + DdNode *shortA; /* ADD cube of shortest path */ + DdNode *constN; /* value returned by evaluation of ADD */ + DdNode *ycube; /* cube of the negated y vars for c-proj */ + DdNode *CP; /* C-Projection of C */ + DdNode *CPr; /* C-Selection of C */ + int length; /* length of the shortest path */ + int nx; /* number of variables */ + int ny; + int maxnx; + int maxny; + int m; + int n; + int N; + int cmu; /* use CMU multiplication */ + int pr; /* verbose printout level */ + int harwell; + int multiple; /* read multiple matrices */ + int ok; + int c; /* variable to read in options */ + int approach; /* reordering approach */ + int autodyn; /* automatic reordering */ + int groupcheck; /* option for group sifting */ + int profile; /* print heap profile if != 0 */ + int keepperm; /* keep track of permutation */ + int clearcache; /* clear the cache after each matrix */ + int blifOrDot; /* dump format: 0 -> dot, 1 -> blif, ... */ + int retval; /* return value */ + int i; /* loop index */ + unsigned long startTime; /* initial time */ + unsigned long lapTime; + int size; + unsigned int cacheSize, maxMemory; + unsigned int nvars,nslots; + + startTime = util_cpu_time(); + + approach = CUDD_REORDER_NONE; + autodyn = 0; + pr = 0; + harwell = 0; + multiple = 0; + profile = 0; + keepperm = 0; + cmu = 0; + N = 4; + nvars = 4; + cacheSize = 127; + maxMemory = 0; + nslots = CUDD_UNIQUE_SLOTS; + clearcache = 0; + groupcheck = CUDD_GROUP_CHECK7; + dfile = NULL; + blifOrDot = 0; /* dot format */ + + /* Parse command line. */ + while ((c = getopt(argc, argv, "CDHMPS:a:bcd:g:hkmn:p:v:x:X:")) + != EOF) { + switch(c) { + case 'C': + cmu = 1; + break; + case 'D': + autodyn = 1; + break; + case 'H': + harwell = 1; + break; + case 'M': +#ifdef MNEMOSYNE + (void) mnem_setrecording(0); +#endif + break; + case 'P': + profile = 1; + break; + case 'S': + nslots = atoi(optarg); + break; + case 'X': + maxMemory = atoi(optarg); + break; + case 'a': + approach = atoi(optarg); + break; + case 'b': + blifOrDot = 1; /* blif format */ + break; + case 'c': + clearcache = 1; + break; + case 'd': + dfile = optarg; + break; + case 'g': + groupcheck = atoi(optarg); + break; + case 'k': + keepperm = 1; + break; + case 'm': + multiple = 1; + break; + case 'n': + N = atoi(optarg); + break; + case 'p': + pr = atoi(optarg); + break; + case 'v': + nvars = atoi(optarg); + break; + case 'x': + cacheSize = atoi(optarg); + break; + case 'h': + default: + usage(argv[0]); + break; + } + } + + if (argc - optind == 0) { + file = (char *) "-"; + } else if (argc - optind == 1) { + file = argv[optind]; + } else { + usage(argv[0]); + } + if ((approach<0) || (approach>17)) { + (void) fprintf(stderr,"Invalid approach: %d \n",approach); + usage(argv[0]); + } + + if (pr > 0) { + (void) printf("# %s\n", TESTCUDD_VERSION); + /* Echo command line and arguments. */ + (void) printf("#"); + for (i = 0; i < argc; i++) { + (void) printf(" %s", argv[i]); + } + (void) printf("\n"); + (void) fflush(stdout); + } + + /* Initialize manager and provide easy reference to terminals. */ + dd = Cudd_Init(nvars,0,nslots,cacheSize,maxMemory); + one = DD_ONE(dd); + dd->groupcheck = (Cudd_AggregationType) groupcheck; + if (autodyn) Cudd_AutodynEnable(dd,CUDD_REORDER_SAME); + + /* Open input file. */ + fp = open_file(file, "r"); + + /* Open dump file if requested */ + if (dfile != NULL) { + dfp = open_file(dfile, "w"); + } + + x = y = xn = yn_ = NULL; + do { + /* We want to start anew for every matrix. */ + maxnx = maxny = 0; + nx = maxnx; ny = maxny; + if (pr>0) lapTime = util_cpu_time(); + if (harwell) { + if (pr > 0) (void) printf(":name: "); + ok = Cudd_addHarwell(fp, dd, &M, &x, &y, &xn, &yn_, &nx, &ny, + &m, &n, 0, 2, 1, 2, pr); + } else { + ok = Cudd_addRead(fp, dd, &M, &x, &y, &xn, &yn_, &nx, &ny, + &m, &n, 0, 2, 1, 2); + if (pr > 0) + (void) printf(":name: %s: %d rows %d columns\n", file, m, n); + } + if (!ok) { + (void) fprintf(stderr, "Error reading matrix\n"); + exit(1); + } + + if (nx > maxnx) maxnx = nx; + if (ny > maxny) maxny = ny; + + /* Build cube of negated y's. */ + ycube = DD_ONE(dd); + Cudd_Ref(ycube); + for (i = maxny - 1; i >= 0; i--) { + DdNode *tmpp; + tmpp = Cudd_bddAnd(dd,Cudd_Not(dd->vars[y[i]->index]),ycube); + if (tmpp == NULL) exit(2); + Cudd_Ref(tmpp); + Cudd_RecursiveDeref(dd,ycube); + ycube = tmpp; + } + /* Initialize vectors of BDD variables used by priority func. */ + xvars = ALLOC(DdNode *, nx); + if (xvars == NULL) exit(2); + for (i = 0; i < nx; i++) { + xvars[i] = dd->vars[x[i]->index]; + } + yvars = ALLOC(DdNode *, ny); + if (yvars == NULL) exit(2); + for (i = 0; i < ny; i++) { + yvars[i] = dd->vars[y[i]->index]; + } + + /* Clean up */ + for (i=0; i < maxnx; i++) { + Cudd_RecursiveDeref(dd, x[i]); + Cudd_RecursiveDeref(dd, xn[i]); + } + FREE(x); + FREE(xn); + for (i=0; i < maxny; i++) { + Cudd_RecursiveDeref(dd, y[i]); + Cudd_RecursiveDeref(dd, yn_[i]); + } + FREE(y); + FREE(yn_); + + if (pr>0) {(void) printf(":1: M"); Cudd_PrintDebug(dd,M,nx+ny,pr);} + + if (pr>0) (void) printf(":2: time to read the matrix = %s\n", + util_print_time(util_cpu_time() - lapTime)); + + C = Cudd_addBddPattern(dd, M); + if (C == 0) exit(2); + Cudd_Ref(C); + if (pr>0) {(void) printf(":3: C"); Cudd_PrintDebug(dd,C,nx+ny,pr);} + + /* Test iterators. */ + retval = testIterators(dd,M,C,pr); + if (retval == 0) exit(2); + + if (pr > 0) + cuddCacheProfile(dd,stdout); + + /* Test XOR */ + retval = testXor(dd,C,pr,nx+ny); + if (retval == 0) exit(2); + + /* Test Hamming distance functions. */ + retval = testHamming(dd,C,pr); + if (retval == 0) exit(2); + + /* Test selection functions. */ + CP = Cudd_CProjection(dd,C,ycube); + if (CP == NULL) exit(2); + Cudd_Ref(CP); + if (pr>0) {(void) printf("ycube"); Cudd_PrintDebug(dd,ycube,nx+ny,pr);} + if (pr>0) {(void) printf("CP"); Cudd_PrintDebug(dd,CP,nx+ny,pr);} + + if (nx == ny) { + CPr = Cudd_PrioritySelect(dd,C,xvars,yvars,(DdNode **)NULL, + (DdNode *)NULL,ny,Cudd_Xgty); + if (CPr == NULL) exit(2); + Cudd_Ref(CPr); + if (pr>0) {(void) printf(":4: CPr"); Cudd_PrintDebug(dd,CPr,nx+ny,pr);} + if (CP != CPr) { + (void) printf("CP != CPr!\n"); + } + Cudd_RecursiveDeref(dd, CPr); + } + + /* Test inequality generator. */ + { + int Nmin = ddMin(nx,ny); + int q; + DdGen *gen; + int *cube; + DdNode *f = Cudd_Inequality(dd,Nmin,2,xvars,yvars); + if (f == NULL) exit(2); + Cudd_Ref(f); + if (pr>0) { + (void) printf(":4: ineq"); + Cudd_PrintDebug(dd,f,nx+ny,pr); + if (pr>1) { + Cudd_ForeachPrime(dd,Cudd_Not(f),Cudd_Not(f),gen,cube) { + for (q = 0; q < dd->size; q++) { + switch (cube[q]) { + case 0: + (void) printf("1"); + break; + case 1: + (void) printf("0"); + break; + case 2: + (void) printf("-"); + break; + default: + (void) printf("?"); + } + } + (void) printf(" 1\n"); + } + (void) printf("\n"); + } + } + Cudd_IterDerefBdd(dd, f); + } + FREE(xvars); FREE(yvars); + + Cudd_RecursiveDeref(dd, CP); + + /* Test functions for essential variables. */ + ess = Cudd_FindEssential(dd,C); + if (ess == NULL) exit(2); + Cudd_Ref(ess); + if (pr>0) {(void) printf(":4: ess"); Cudd_PrintDebug(dd,ess,nx+ny,pr);} + Cudd_RecursiveDeref(dd, ess); + + /* Test functions for shortest paths. */ + shortP = Cudd_ShortestPath(dd, M, NULL, NULL, &length); + if (shortP == NULL) exit(2); + Cudd_Ref(shortP); + if (pr>0) { + (void) printf(":5: shortP"); Cudd_PrintDebug(dd,shortP,nx+ny,pr); + } + /* Test functions for largest cubes. */ + largest = Cudd_LargestCube(dd, Cudd_Not(C), &length); + if (largest == NULL) exit(2); + Cudd_Ref(largest); + if (pr>0) { + (void) printf(":5b: largest"); + Cudd_PrintDebug(dd,largest,nx+ny,pr); + } + Cudd_RecursiveDeref(dd, largest); + + /* Test Cudd_addEvalConst and Cudd_addIteConstant. */ + shortA = Cudd_BddToAdd(dd,shortP); + if (shortA == NULL) exit(2); + Cudd_Ref(shortA); + Cudd_RecursiveDeref(dd, shortP); + constN = Cudd_addEvalConst(dd,shortA,M); + if (constN == DD_NON_CONSTANT) exit(2); + if (Cudd_addIteConstant(dd,shortA,M,constN) != constN) exit(2); + if (pr>0) {(void) printf("The value of M along the chosen shortest path is %g\n", cuddV(constN));} + Cudd_RecursiveDeref(dd, shortA); + + shortP = Cudd_ShortestPath(dd, C, NULL, NULL, &length); + if (shortP == NULL) exit(2); + Cudd_Ref(shortP); + if (pr>0) { + (void) printf(":6: shortP"); Cudd_PrintDebug(dd,shortP,nx+ny,pr); + } + + /* Test Cudd_bddIteConstant and Cudd_bddLeq. */ + if (!Cudd_bddLeq(dd,shortP,C)) exit(2); + if (Cudd_bddIteConstant(dd,Cudd_Not(shortP),one,C) != one) exit(2); + Cudd_RecursiveDeref(dd, shortP); + + /* Experiment with support functions. */ + if (!testSupport(dd,M,ycube,pr)) { + exit(2); + } + Cudd_RecursiveDeref(dd, ycube); + + if (profile) { + retval = cuddHeapProfile(dd); + } + + size = dd->size; + + if (pr>0) { + (void) printf("Average distance: %g\n", Cudd_AverageDistance(dd)); + } + + /* Reorder if so requested. */ + if (approach != CUDD_REORDER_NONE) { +#ifndef DD_STATS + retval = Cudd_EnableReorderingReporting(dd); + if (retval == 0) { + (void) fprintf(stderr,"Error reported by Cudd_EnableReorderingReporting\n"); + exit(3); + } +#endif +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + exit(3); + } + retval = Cudd_CheckKeys(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + exit(3); + } +#endif + retval = Cudd_ReduceHeap(dd,(Cudd_ReorderingType)approach,5); + if (retval == 0) { + (void) fprintf(stderr,"Error reported by Cudd_ReduceHeap\n"); + exit(3); + } +#ifndef DD_STATS + retval = Cudd_DisableReorderingReporting(dd); + if (retval == 0) { + (void) fprintf(stderr,"Error reported by Cudd_DisableReorderingReporting\n"); + exit(3); + } +#endif +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + exit(3); + } + retval = Cudd_CheckKeys(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + exit(3); + } +#endif + if (approach == CUDD_REORDER_SYMM_SIFT || + approach == CUDD_REORDER_SYMM_SIFT_CONV) { + Cudd_SymmProfile(dd,0,dd->size-1); + } + + if (pr>0) { + (void) printf("Average distance: %g\n", Cudd_AverageDistance(dd)); + } + + if (keepperm) { + /* Print variable permutation. */ + (void) printf("Variable Permutation:"); + for (i=0; iinvperm[i]); + } + (void) printf("\n"); + (void) printf("Inverse Permutation:"); + for (i=0; iperm[i]); + } + (void) printf("\n"); + } + + if (pr>0) {(void) printf("M"); Cudd_PrintDebug(dd,M,nx+ny,pr);} + + if (profile) { + retval = cuddHeapProfile(dd); + } + + } + + /* Dump DDs of C and M if so requested. */ + if (dfile != NULL) { + dfunc[0] = C; + dfunc[1] = M; + if (blifOrDot == 1) { + /* Only dump C because blif cannot handle ADDs */ + retval = Cudd_DumpBlif(dd,1,dfunc,NULL,(char **)onames, + NULL,dfp,0); + } else { + retval = Cudd_DumpDot(dd,2,dfunc,NULL,(char **)onames,dfp); + } + if (retval != 1) { + (void) fprintf(stderr,"abnormal termination\n"); + exit(2); + } + } + + Cudd_RecursiveDeref(dd, C); + Cudd_RecursiveDeref(dd, M); + + if (clearcache) { + if (pr>0) {(void) printf("Clearing the cache... ");} + for (i = dd->cacheSlots - 1; i>=0; i--) { + dd->cache[i].data = NULL; + } + if (pr>0) {(void) printf("done\n");} + } + if (pr>0) { + (void) printf("Number of variables = %6d\t",dd->size); + (void) printf("Number of slots = %6u\n",dd->slots); + (void) printf("Number of keys = %6u\t",dd->keys); + (void) printf("Number of min dead = %6u\n",dd->minDead); + } + + } while (multiple && !feof(fp)); + + fclose(fp); + if (dfile != NULL) { + fclose(dfp); + } + + /* Second phase: experiment with Walsh matrices. */ + if (!testWalsh(dd,N,cmu,approach,pr)) { + exit(2); + } + + /* Check variable destruction. */ + assert(cuddDestroySubtables(dd,3)); + if (pr == 0) { + savefp = Cudd_ReadStdout(dd); + Cudd_SetStdout(dd,fopen("/dev/null","a")); + } + assert(Cudd_DebugCheck(dd) == 0); + assert(Cudd_CheckKeys(dd) == 0); + if (pr == 0) { + Cudd_SetStdout(dd,savefp); + } + + retval = Cudd_CheckZeroRef(dd); + ok = retval != 0; /* ok == 0 means O.K. */ + if (retval != 0) { + (void) fprintf(stderr, + "%d non-zero DD reference counts after dereferencing\n", retval); + } + + if (pr > 0) { + (void) Cudd_PrintInfo(dd,stdout); + } + + Cudd_Quit(dd); + +#ifdef MNEMOSYNE + mnem_writestats(); +#endif + + if (pr>0) (void) printf("total time = %s\n", + util_print_time(util_cpu_time() - startTime)); + + if (pr > 0) util_print_cpu_stats(stdout); + return ok; + /* NOTREACHED */ + +} /* end of main */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints usage info for testcudd.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +usage(char *prog) +{ + (void) fprintf(stderr, "usage: %s [options] [file]\n", prog); + (void) fprintf(stderr, " -C\t\tuse CMU multiplication algorithm\n"); + (void) fprintf(stderr, " -D\t\tenable automatic dynamic reordering\n"); + (void) fprintf(stderr, " -H\t\tread matrix in Harwell format\n"); + (void) fprintf(stderr, " -M\t\tturns off memory allocation recording\n"); + (void) fprintf(stderr, " -P\t\tprint BDD heap profile\n"); + (void) fprintf(stderr, " -S n\t\tnumber of slots for each subtable\n"); + (void) fprintf(stderr, " -X n\t\ttarget maximum memory in bytes\n"); + (void) fprintf(stderr, " -a n\t\tchoose reordering approach (0-13)\n"); + (void) fprintf(stderr, " \t\t\t0: same as autoMethod\n"); + (void) fprintf(stderr, " \t\t\t1: no reordering (default)\n"); + (void) fprintf(stderr, " \t\t\t2: random\n"); + (void) fprintf(stderr, " \t\t\t3: pivot\n"); + (void) fprintf(stderr, " \t\t\t4: sifting\n"); + (void) fprintf(stderr, " \t\t\t5: sifting to convergence\n"); + (void) fprintf(stderr, " \t\t\t6: symmetric sifting\n"); + (void) fprintf(stderr, " \t\t\t7: symmetric sifting to convergence\n"); + (void) fprintf(stderr, " \t\t\t8-10: window of size 2-4\n"); + (void) fprintf(stderr, " \t\t\t11-13: window of size 2-4 to conv.\n"); + (void) fprintf(stderr, " \t\t\t14: group sifting\n"); + (void) fprintf(stderr, " \t\t\t15: group sifting to convergence\n"); + (void) fprintf(stderr, " \t\t\t16: simulated annealing\n"); + (void) fprintf(stderr, " \t\t\t17: genetic algorithm\n"); + (void) fprintf(stderr, " -b\t\tuse blif as format for dumps\n"); + (void) fprintf(stderr, " -c\t\tclear the cache after each matrix\n"); + (void) fprintf(stderr, " -d file\tdump DDs to file\n"); + (void) fprintf(stderr, " -g\t\tselect aggregation criterion (0,5,7)\n"); + (void) fprintf(stderr, " -h\t\tprints this message\n"); + (void) fprintf(stderr, " -k\t\tprint the variable permutation\n"); + (void) fprintf(stderr, " -m\t\tread multiple matrices (only with -H)\n"); + (void) fprintf(stderr, " -n n\t\tnumber of variables\n"); + (void) fprintf(stderr, " -p n\t\tcontrol verbosity\n"); + (void) fprintf(stderr, " -v n\t\tinitial variables in the unique table\n"); + (void) fprintf(stderr, " -x n\t\tinitial size of the cache\n"); + exit(2); +} /* end of usage */ + + +/**Function******************************************************************** + + Synopsis [Opens a file.] + + Description [Opens a file, or fails with an error message and exits. + Allows '-' as a synonym for standard input.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static FILE * +open_file(char *filename, const char *mode) +{ + FILE *fp; + + if (strcmp(filename, "-") == 0) { + return mode[0] == 'r' ? stdin : stdout; + } else if ((fp = fopen(filename, mode)) == NULL) { + perror(filename); + exit(1); + } + return fp; + +} /* end of open_file */ + + +/**Function******************************************************************** + + Synopsis [Tests Walsh matrix multiplication.] + + Description [Tests Walsh matrix multiplication. Return 1 if successful; + 0 otherwise.] + + SideEffects [May create new variables in the manager.] + + SeeAlso [] + +******************************************************************************/ +static int +testWalsh( + DdManager *dd /* manager */, + int N /* number of variables */, + int cmu /* use CMU approach to matrix multiplication */, + int approach /* reordering approach */, + int pr /* verbosity level */) +{ + DdNode *walsh1, *walsh2, *wtw; + DdNode **x, **v, **z; + int i, retval; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + + if (N > 3) { + x = ALLOC(DdNode *,N); + v = ALLOC(DdNode *,N); + z = ALLOC(DdNode *,N); + + for (i = N-1; i >= 0; i--) { + Cudd_Ref(x[i]=cuddUniqueInter(dd,3*i,one,zero)); + Cudd_Ref(v[i]=cuddUniqueInter(dd,3*i+1,one,zero)); + Cudd_Ref(z[i]=cuddUniqueInter(dd,3*i+2,one,zero)); + } + Cudd_Ref(walsh1 = Cudd_addWalsh(dd,v,z,N)); + if (pr>0) {(void) printf("walsh1"); Cudd_PrintDebug(dd,walsh1,2*N,pr);} + Cudd_Ref(walsh2 = Cudd_addWalsh(dd,x,v,N)); + if (cmu) { + Cudd_Ref(wtw = Cudd_addTimesPlus(dd,walsh2,walsh1,v,N)); + } else { + Cudd_Ref(wtw = Cudd_addMatrixMultiply(dd,walsh2,walsh1,v,N)); + } + if (pr>0) {(void) printf("wtw"); Cudd_PrintDebug(dd,wtw,2*N,pr);} + + if (approach != CUDD_REORDER_NONE) { +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + return(0); + } +#endif + retval = Cudd_ReduceHeap(dd,(Cudd_ReorderingType)approach,5); + if (retval == 0) { + (void) fprintf(stderr,"Error reported by Cudd_ReduceHeap\n"); + return(0); + } +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + return(0); + } +#endif + if (approach == CUDD_REORDER_SYMM_SIFT || + approach == CUDD_REORDER_SYMM_SIFT_CONV) { + Cudd_SymmProfile(dd,0,dd->size-1); + } + } + /* Clean up. */ + Cudd_RecursiveDeref(dd, wtw); + Cudd_RecursiveDeref(dd, walsh1); + Cudd_RecursiveDeref(dd, walsh2); + for (i=0; i < N; i++) { + Cudd_RecursiveDeref(dd, x[i]); + Cudd_RecursiveDeref(dd, v[i]); + Cudd_RecursiveDeref(dd, z[i]); + } + FREE(x); + FREE(v); + FREE(z); + } + return(1); + +} /* end of testWalsh */ + +/**Function******************************************************************** + + Synopsis [Tests iterators.] + + Description [Tests iterators on cubes and nodes.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +testIterators( + DdManager *dd, + DdNode *M, + DdNode *C, + int pr) +{ + int *cube; + CUDD_VALUE_TYPE value; + DdGen *gen; + int q; + + /* Test iterator for cubes. */ + if (pr>1) { + (void) printf("Testing iterator on cubes:\n"); + Cudd_ForeachCube(dd,M,gen,cube,value) { + for (q = 0; q < dd->size; q++) { + switch (cube[q]) { + case 0: + (void) printf("0"); + break; + case 1: + (void) printf("1"); + break; + case 2: + (void) printf("-"); + break; + default: + (void) printf("?"); + } + } + (void) printf(" %g\n",value); + } + (void) printf("\n"); + } + + if (pr>1) { + (void) printf("Testing prime expansion of cubes:\n"); + if (!Cudd_bddPrintCover(dd,C,C)) return(0); + } + + if (pr>1) { + (void) printf("Testing iterator on primes (CNF):\n"); + Cudd_ForeachPrime(dd,Cudd_Not(C),Cudd_Not(C),gen,cube) { + for (q = 0; q < dd->size; q++) { + switch (cube[q]) { + case 0: + (void) printf("1"); + break; + case 1: + (void) printf("0"); + break; + case 2: + (void) printf("-"); + break; + default: + (void) printf("?"); + } + } + (void) printf(" 1\n"); + } + (void) printf("\n"); + } + + /* Test iterator on nodes. */ + if (pr>2) { + DdNode *node; + (void) printf("Testing iterator on nodes:\n"); + Cudd_ForeachNode(dd,M,gen,node) { + if (Cudd_IsConstant(node)) { +#if SIZEOF_VOID_P == 8 + (void) printf("ID = 0x%lx\tvalue = %-9g\n", + (ptruint) node / + (ptruint) sizeof(DdNode), + Cudd_V(node)); +#else + (void) printf("ID = 0x%x\tvalue = %-9g\n", + (ptruint) node / + (ptruint) sizeof(DdNode), + Cudd_V(node)); +#endif + } else { +#if SIZEOF_VOID_P == 8 + (void) printf("ID = 0x%lx\tindex = %u\tr = %u\n", + (ptruint) node / + (ptruint) sizeof(DdNode), + node->index, node->ref); +#else + (void) printf("ID = 0x%x\tindex = %u\tr = %u\n", + (ptruint) node / + (ptruint) sizeof(DdNode), + node->index, node->ref); +#endif + } + } + (void) printf("\n"); + } + return(1); + +} /* end of testIterators */ + + +/**Function******************************************************************** + + Synopsis [Tests the functions related to the exclusive OR.] + + Description [Tests the functions related to the exclusive OR. It + builds the boolean difference of the given function in three + different ways and checks that the results is the same. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +testXor(DdManager *dd, DdNode *f, int pr, int nvars) +{ + DdNode *f1, *f0, *res1, *res2; + int x; + + /* Extract cofactors w.r.t. mid variable. */ + x = nvars / 2; + f1 = Cudd_Cofactor(dd,f,dd->vars[x]); + if (f1 == NULL) return(0); + Cudd_Ref(f1); + + f0 = Cudd_Cofactor(dd,f,Cudd_Not(dd->vars[x])); + if (f0 == NULL) { + Cudd_RecursiveDeref(dd,f1); + return(0); + } + Cudd_Ref(f0); + + /* Compute XOR of cofactors with ITE. */ + res1 = Cudd_bddIte(dd,f1,Cudd_Not(f0),f0); + if (res1 == NULL) return(0); + Cudd_Ref(res1); + + if (pr>0) {(void) printf("xor1"); Cudd_PrintDebug(dd,res1,nvars,pr);} + + /* Compute XOR of cofactors with XOR. */ + res2 = Cudd_bddXor(dd,f1,f0); + if (res2 == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(0); + } + Cudd_Ref(res2); + + if (res1 != res2) { + if (pr>0) {(void) printf("xor2"); Cudd_PrintDebug(dd,res2,nvars,pr);} + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(0); + } + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,f1); + Cudd_RecursiveDeref(dd,f0); + + /* Compute boolean difference directly. */ + res1 = Cudd_bddBooleanDiff(dd,f,x); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd,res2); + return(0); + } + Cudd_Ref(res1); + + if (res1 != res2) { + if (pr>0) {(void) printf("xor3"); Cudd_PrintDebug(dd,res1,nvars,pr);} + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(0); + } + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(1); + +} /* end of testXor */ + + +/**Function******************************************************************** + + Synopsis [Tests the Hamming distance functions.] + + Description [Tests the Hammming distance functions. Returns + 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +testHamming( + DdManager *dd, + DdNode *f, + int pr) +{ + DdNode **vars, *minBdd, *zero, *scan; + int i; + int d; + int *minterm; + int size = Cudd_ReadSize(dd); + + vars = ALLOC(DdNode *, size); + if (vars == NULL) return(0); + for (i = 0; i < size; i++) { + vars[i] = Cudd_bddIthVar(dd,i); + } + + minBdd = Cudd_bddPickOneMinterm(dd,Cudd_Not(f),vars,size); + Cudd_Ref(minBdd); + if (pr > 0) { + (void) printf("Chosen minterm for Hamming distance test: "); + Cudd_PrintDebug(dd,minBdd,size,pr); + } + + minterm = ALLOC(int,size); + if (minterm == NULL) { + FREE(vars); + Cudd_RecursiveDeref(dd,minBdd); + return(0); + } + scan = minBdd; + zero = Cudd_Not(DD_ONE(dd)); + while (!Cudd_IsConstant(scan)) { + DdNode *R = Cudd_Regular(scan); + DdNode *T = Cudd_T(R); + DdNode *E = Cudd_E(R); + if (R != scan) { + T = Cudd_Not(T); + E = Cudd_Not(E); + } + if (T == zero) { + minterm[R->index] = 0; + scan = E; + } else { + minterm[R->index] = 1; + scan = T; + } + } + Cudd_RecursiveDeref(dd,minBdd); + + d = Cudd_MinHammingDist(dd,f,minterm,size); + + if (pr > 0) + (void) printf("Minimum Hamming distance = %d\n", d); + + FREE(vars); + FREE(minterm); + return(1); + +} /* end of testHamming */ + + +/**Function******************************************************************** + + Synopsis [Tests the support functions.] + + Description [Tests the support functions. Returns + 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +testSupport( + DdManager *dd, + DdNode *f, + DdNode *g, + int pr) +{ + DdNode *sb, *common, *onlyF, *onlyG; + DdNode *F[2]; + int *support; + int ret, ssize; + int size = Cudd_ReadSize(dd); + + sb = Cudd_Support(dd, f); + if (sb == NULL) return(0); + Cudd_Ref(sb); + if (pr > 0) { + (void) printf("Support of f: "); + Cudd_PrintDebug(dd,sb,size,pr); + } + Cudd_RecursiveDeref(dd, sb); + + ssize = Cudd_SupportIndices(dd, f, &support); + if (ssize == CUDD_OUT_OF_MEM) return(0); + if (pr > 0) { + (void) printf("Size of the support of f: %d\n", ssize); + } + FREE(support); + + ssize = Cudd_SupportSize(dd, f); + if (pr > 0) { + (void) printf("Size of the support of f: %d\n", ssize); + } + + F[0] = f; + F[1] = g; + sb = Cudd_VectorSupport(dd, F, 2); + if (sb == NULL) return(0); + Cudd_Ref(sb); + if (pr > 0) { + (void) printf("Support of f and g: "); + Cudd_PrintDebug(dd,sb,size,pr); + } + Cudd_RecursiveDeref(dd, sb); + + ssize = Cudd_VectorSupportIndices(dd, F, 2, &support); + if (ssize == CUDD_OUT_OF_MEM) return(0); + if (pr > 0) { + (void) printf("Size of the support of f and g: %d\n", ssize); + } + FREE(support); + + ssize = Cudd_VectorSupportSize(dd, F, 2); + if (pr > 0) { + (void) printf("Size of the support of f and g: %d\n", ssize); + } + + ret = Cudd_ClassifySupport(dd, f, g, &common, &onlyF, &onlyG); + if (ret == 0) return(0); + Cudd_Ref(common); Cudd_Ref(onlyF); Cudd_Ref(onlyG); + if (pr > 0) { + (void) printf("Support common to f and g: "); + Cudd_PrintDebug(dd,common,size,pr); + (void) printf("Support private to f: "); + Cudd_PrintDebug(dd,onlyF,size,pr); + (void) printf("Support private to g: "); + Cudd_PrintDebug(dd,onlyG,size,pr); + } + Cudd_RecursiveDeref(dd, common); + Cudd_RecursiveDeref(dd, onlyF); + Cudd_RecursiveDeref(dd, onlyG); + + return(1); + +} /* end of testSupport */ diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/Makefile b/resources/3rdparty/cudd-2.5.0/dddmp/Makefile new file mode 100644 index 000000000..d84881a16 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/Makefile @@ -0,0 +1,243 @@ +#----------------------------------------------------------------------------# +# Makefile for the dddmp distribution kit # +# dddmp: Decision Diagram DuMP # +# (storage and retrieval of BDDs, ADDs and CNF formulas) # +# Revision: Version 2.0.2, February 01, 2004 # +#----------------------------------------------------------------------------# + +# Commands Available: +# make +# it makes the library libdddmp.a +# make testdddmp +# it makes the testdddmp program, which allows to test the dddmp +# package +# make clean +# it cleans dddmp +# make distclean +# it cleans dddmp (as clean) with libraries and executable +# files + +#----------------------------------------------------------------------------# +# Configuration Section # +# uncomment the desired options/sections # +#----------------------------------------------------------------------------# + +#--------------------# +# Define Directories # +#--------------------# + +# Cudd directory +WHERE = .. +#WHERE = ../cudd-2.4.0 + +# Include directory (Cudd include files) +INCLUDE = $(WHERE)/include + +#------------------------# +# Define C Compiler Used # +#------------------------# + +CC = gcc +#CC = g++ +#CC = cc +#CC = icc +#CC = ecc +#CC = /usr/ucb/cc +#CC = c89 + +.SUFFIXES: .o .c .u + +#---------------# +# Define ranlib # +#---------------# + +# For machines with ranlib and you think it is needed +RANLIB = ranlib +# For machines which either do not have ranlib or can do without it +#RANLIB = : + +#----------------------------------# +# Define Machine Independent Flags # +#----------------------------------# + +# Settings for cc +#ICFLAGS = +#ICFLAGS = -g +#ICFLAGS = -O +# Settings for optimized code with gcc +#ICFLAGS = -g -Wall +#ICFLAGS = -g -O3 -Wall +ICFLAGS = -g -O6 -Wall + +#--------------------------------# +# Define Machine Dependent Flags # +#--------------------------------# + +# When no special flags are needed +#XCFLAGS = -DHAVE_IEEE_754 -DBSD +# Linux with Gcc 2.8.1 or higher on i686. +#XCFLAGS = -mcpu=pentiumpro -malign-double -DHAVE_IEEE_754 -DBSD +# Gcc 3.3.2 or higher on i686. +XCFLAGS = -mcpu=pentium4 -malign-double -DHAVE_IEEE_754 -DBSD +# For Solaris, BSD should not be replaced by UNIX100. +#XCFLAGS = -DHAVE_IEEE_754 -DUNIX100 -DEPD_BIG_ENDIAN +# New native compiler for the Alphas; 64-bit pointers. +#XCFLAGS = -g3 -O4 -std -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# New native compiler for the Alphas; 32-bit pointers. +#XCFLAGS = -g3 -O4 -std -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -xtaso -DSIZEOF_LONG=8 +# Windows95/98/NT/XP with Cygwin tools +#XCFLAGS = -mcpu=pentiumpro -malign-double -DHAVE_IEEE_754 -DHAVE_GETRLIMIT=0 -DRLIMIT_DATA_DEFAULT=67108864 + +#---------------------------------------------# +# Define Level of Self-Checking and Verbosity # +#---------------------------------------------# + +# ... for the CUDD package +#DDDEBUG = -DDD_DEBUG -DDD_VERBOSE -DDD_STATS -DDD_CACHE_PROFILE -DDD_UNIQUE_PROFILE -DDD_COUNT +DDDEBUG = + +# ... for the MTR package +#MTRDEBUG = -DMTR_DEBUG +MTRDEBUG = + +# ... for the DDDMP package +#DDDMPDEBUG = -DDDDMP_DEBUG +DDDMPDEBUG = + +#-----------------------# +# Define Loader Options # +#-----------------------# + +LDFLAGS = +# This may produce faster code on the DECstations. +#LDFLAGS = -jmpopt -Olimit 1000 +# This may be necessary under some old versions of Linux. +#LDFLAGS = -static +# This normally makes the program faster on the DEC Alphas. +#LDFLAGS = -non_shared -om +# This is for 32-bit pointers on the DEC Alphas. +#LDFLAGS = -non_shared -om -taso +#LDFLAGS = -non_shared -taso + +#-------------# +# Define PURE # +#-------------# + +PURE = +# ... as purify to link with purify. +#PURE = purify +# ... as quantify to link with quantify. +#PURE = quantify + +#------------# +# Define EXE # +#------------# + +EXE = +# ... as .exe for MS-DOS and derivatives. +#EXE = .exe + +#----------------------------------------------------------------------------# +# Files for the Package # +#----------------------------------------------------------------------------# + +P = dddmp +PSRC = dddmpStoreBdd.c dddmpStoreAdd.c dddmpStoreCnf.c \ + dddmpLoad.c dddmpLoadCnf.c \ + dddmpNodeBdd.c dddmpNodeAdd.c dddmpNodeCnf.c \ + dddmpStoreMisc.c dddmpUtil.c dddmpBinary.c dddmpConvert.c \ + dddmpDbg.c +PHDR = dddmp.h dddmpInt.h $(INCLUDE)/cudd.h $(INCLUDE)/cuddInt.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +TARGET = test$(P)$(EXE) +TARGETu = test$(P)-u + +# files for the test program +SRC = test$(P).c +OBJ = $(SRC:.c=.o) +UBJ = $(SRC:.c=.u) + +#----------------------------------------------------------------------------# +# Rules to compile and build libraries and executables # +#----------------------------------------------------------------------------# + +#MFLAG = +MFLAG = -DMNEMOSYNE +MNEMLIB = ../mnemosyne/libmnem.a + +# This is to create the lint library +LINTFLAGS = -u -n +LINTSWITCH = -o + +LIBS = ./libdddmp.a $(WHERE)/cudd/libcudd.a $(WHERE)/mtr/libmtr.a \ + $(WHERE)/st/libst.a $(WHERE)/util/libutil.a $(WHERE)/epd/libepd.a + +MNEMLIB = + +BLIBS = -kL. -kldddmp -kL$(WHERE)/cudd -klcudd -kL$(WHERE)/mtr -klmtr \ + -kL$(WHERE)/st -klst -kL$(WHERE)/util -klutil + +LINTLIBS = ./llib-ldddmp.ln $(WHERE)/cudd/llib-lcudd.ln \ + $(WHERE)/mtr/llib-lmtr.ln $(WHERE)/st/llib-lst.ln \ + $(WHERE)/util/llib-lutil.ln + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(ICFLAGS) $(XCFLAGS) $(DDDEBUG) $(MTRDEBUG) $(DDDMPDEBUG) $(LDFLAGS) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PHDR) + cc -c $< -I$(INCLUDE) $(CFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) +$(OBJ): $(PHDR) +$(UBJ): $(PHDR) + +$(TARGET): $(SRC) $(OBJ) $(PHDR) $(LIBS) $(MNEMLIB) + $(PURE) $(CC) $(ICFLAGS) $(XCFLAGS) $(DDDEBUG) $(MTRDEBUG) $(DDDMPDEBUG) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +# optimize (DECstations and Alphas only: uses u-code) +$(TARGETu): $(SRC) $(UBJ) $(PHDR) $(LIBS:.a=.b) + cc -O3 -Olimit 1000 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +lintpgm: lint + lint $(LINTFLAGS) -I$(INCLUDE) $(SRC) $(LINTLIBS) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +programs: $(TARGET) $(TARGETu) lintpgm + +#----------------------------------------------------------------------------# +# Clean the Package # +#----------------------------------------------------------------------------# + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \ + *.bak *~ tags .gdb_history *.qv *.qx + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/README.dddmp b/resources/3rdparty/cudd-2.5.0/dddmp/README.dddmp new file mode 100644 index 000000000..704bd19a0 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/README.dddmp @@ -0,0 +1,64 @@ +README file for the DDDMP-2.0 package +Revision: Version 2.0.2, February 01, 2004 + + + +WHAT IS DDDMP +============= + +The DDDMP package defines formats for DD storage on file, and it contains a +set of functions to dump DDs and DD forests on file. + +In the version 1.0, only BDDs (ROBDDs) of the CUDD package (version 2.2.0 +or higher) were supported. +The version 2.0 includes supports for ADDs and CNF formulas. +The version 2.0.2 is for bug fixes. + + + +MAKE DDDMP +========== + +Before you build the libraries and programs, you need to check the +Makefile in the top directory. +Go through the definitions contained in the configuration section, and +select the desired compiler and compilation flags. +Instructions are provided in the comments of the Makefile. + +Then run "make". +This should produce the dddmplib.a library. + + + +DOCUMENTATION +============= + +Directory dddmp/doc contains HTML documentation for the package. +The recommended starting point is package.html. +Documentation in both postscript format and plain text format is also +provided. + + + +FTP SITE +======== + +The package is singularly available from the author home page: +http://staff.polito.it/{gianpiero.cabodi,stefano.quer} + + + + +FEEDBACK +======== + +Send feedback to: + +Stefano Quer & Gianpiero Cabodi +Politecnico di Torino +Dip. Automatica e Informatica +C.so Duca degli Abruzzi 24 +I-10129 Torino +Italy +E-mail: {gianpiero.cabodi,stefano.quer}@polito.it +WEB page: http://staff.polito.it/{gianpiero.cabodi,stefano.quer} diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/README.testdddmp b/resources/3rdparty/cudd-2.5.0/dddmp/README.testdddmp new file mode 100644 index 000000000..e1e1acfed --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/README.testdddmp @@ -0,0 +1,79 @@ +README file for the test program of the DDDMP-2.0 package +Revision: Version 2.0.2, February 01, 2004 + + + +WHAT IS TESTDDDMP +================= + +testdddmp is a test program for the dddmp package. +Practically, it is a naive user interface to load, store and execute +operations with BDDs. +It is included to provide a sanity check for the installation of the +package and an easy tool to play with BDDs and BDD on files. + + + +MAKE TESTDDDMP +============== + +Run "make testdddmp". +This should produce the testdddmp executable file. + + + +TEST DDDMP +========== + +Run the runAllTest.script file in the exp directory. +This should run all the test?.script files in the same directory. +Each of them is specifically written to check a particular feature of +the package (e.g., store and load of BDDs, store of CNF formulas and +retrieval, etc.). +Each test?.script should terminate with a comparison with a previously +generated set of files, then with the following set of messages: + +Files 0or1.bdd and 0or1.bdd2 are identical +Files 2and3.bdd and 2and3.bdd2 are identical +... + +If so everything is OK. + +Notice that mismatches may be caused by the presence of CR - LF characters at +the end of each BDD file line. + + + +WORK WITH DDDMPTEST +=================== + +To work with dddmptest (once the executable file has been built) it is enough +to run it (no parameter is necessary). +The help command print out the main commands available. +For each command further inputs are eventually required on an interactive +basis. +BDDs and ADDs can be loaded from files by choosing the file name or they +can be directly created (randomly for example). +They can be maintained into the main memory trough an array of BDD pointers. +Operations (logical and re-ordering) can be performed on any BDD into this +array. +Eventually any of them can be stored in a file giving the file name. +BDDs can also be stored in a CNF format using three different possible +solution to store them. + + + +FEEDBACK +======== + +Send feedback to: + +Gianpiero Cabodi and Stefano Quer +Politecnico di Torino +Dip. Automatica e Informatica +C.so Duca degli Abruzzi 24 +I-10129 Torino +Italy +E-mail: {gianpiero.cabodi,stefano.quer}@polito.it +WEB page: http://staff.polito.it/{gianpiero.cabodi,stefano.quer} + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/RELEASE_NOTES b/resources/3rdparty/cudd-2.5.0/dddmp/RELEASE_NOTES new file mode 100644 index 000000000..c8f4b9a6e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/RELEASE_NOTES @@ -0,0 +1,60 @@ +RELEASE NOTES FOR DDDMP +Revision: Version 2.0.2 +Turin, Italy, February 01, 2004 + +dddmp-2.0.2 is now available at +WEB page: http://staff.polito.it/{gianpiero.cabodi,stefano.quer} +dddmp-2.0.2 has a few bug fixes with respect to dddmp-2.0 + +Release 2.0.2 of DDDMP improves DDDMP-1.2 in the following areas: + + 1. Support to store and load ADD has been inserted in the dddmp tool + + 2. Support to store BDDs as CNF formulas has been inserted in the + dddmp tool. + As far as the storing process is concerned three possible formats + are available: + + DDDMP_CNF_MODE_NODE + store a BDD by introducing an auxiliary variable for each BDD node + + DDDMP_CNF_MODE_MAXTERM + store a BDD by following the maxterm of the represented function + + DDDMP_CNF_MODE_BEST + trade-of between the two previous solution, trying to optimize + the number of literals stored. + + As far as the loading process is concerned three possible formats + are available: + + DDDMP_CNF_MODE_NO_CONJ + Return the Clauses without Conjunction + + DDDMP_CNF_MODE_NO_QUANT + Return the sets of BDDs without Quantification + + DDDMP_CNF_MODE_CONJ_QUANT + Return the sets of BDDs AFTER Existential Quantification + + 3. Functions to load the header of a BDD/ADD/CNF file, so collecting + information regarding variables, variable ordering, etc. + This can be seen as a pre-processing step prior a possible BDD/ADD/CNF + load of the entire structure. + Moreover it can be used in a manager initialization phase. + + 4. More precise information are stored in each BDD/ADD header during + the storing phase. + In particular this information may be used to make up the exact + variable ordering present in the manager used during the storing + phase. + Full compatibility with previously versions of the files (from + dddmp-1.0 on) is guaranteed. + + 5. Miscellaneous + Debugging has been performed on different hardware architectures + + 6. The test program, testdddmp has been improved. + Now it allows to perform more operations and to better debug the + different options. + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmp.h b/resources/3rdparty/cudd-2.5.0/dddmp/dddmp.h new file mode 100644 index 000000000..7228fe7ff --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmp.h @@ -0,0 +1,330 @@ +/**CHeaderFile***************************************************************** + + FileName [dddmp.h] + + PackageName [dddmp] + + Synopsis [Functions to read in and write out BDDs, ADDs + and CNF formulas from and to files.] + + Description [] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2002 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#ifndef _DDDMP +#define _DDDMP + +#if 0 +#define DDDMP_DEBUG +#endif + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include "util.h" +#include "cudd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* + * Dddmp format version + */ + +#define DDDMP_VERSION "DDDMP-2.0" + +/* + * Returned values (for theorically ALL the function of the package) + */ + +#define DDDMP_FAILURE ((int) 0) +#define DDDMP_SUCCESS ((int) 1) + +/* + * Format modes for DD (BDD and ADD) files + */ + +#define DDDMP_MODE_TEXT ((int)'A') +#define DDDMP_MODE_BINARY ((int)'B') +#define DDDMP_MODE_DEFAULT ((int)'D') + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/**Enum************************************************************************ + + Synopsis [Format modes for storing CNF files] + + Description [Type supported for storing BDDs into CNF + formulas. + Used internally to select the proper storing format: + DDDMP_CNF_MODE_NODE: create a CNF temporary variables for + each BDD node + DDDMP_CNF_MODE_MAXTERM: no temporary variables + DDDMP_CNF_MODE_BEST: trade-off between the two previous methods + ] + +******************************************************************************/ + +typedef enum { + DDDMP_CNF_MODE_NODE, + DDDMP_CNF_MODE_MAXTERM, + DDDMP_CNF_MODE_BEST +} Dddmp_DecompCnfStoreType; + +/**Enum************************************************************************ + + Synopsis [Format modes for loading CNF files.] + + Description [Type supported for loading CNF formulas into BDDs. + Used internally to select the proper returning format: + ] + +******************************************************************************/ + +typedef enum { + DDDMP_CNF_MODE_NO_CONJ, + DDDMP_CNF_MODE_NO_QUANT, + DDDMP_CNF_MODE_CONJ_QUANT +} Dddmp_DecompCnfLoadType; + +/**Enum************************************************************************ + + Synopsis [Type for supported decomposition types.] + + Description [Type for supported decomposition types. + Used internally to select the proper type (bdd, add, ...). + Given externally as information fule content. + ] + +******************************************************************************/ + +typedef enum { + DDDMP_BDD, + DDDMP_ADD, + DDDMP_CNF, + DDDMP_NONE +} Dddmp_DecompType; + + +/**Enum************************************************************************ + + Synopsis [Type for variable extra info.] + + Description [Type for variable extra info. Used to specify info stored + in text mode.] + +******************************************************************************/ + +typedef enum { + DDDMP_VARIDS, + DDDMP_VARPERMIDS, + DDDMP_VARAUXIDS, + DDDMP_VARNAMES, + DDDMP_VARDEFAULT +} Dddmp_VarInfoType; + +/**Enum************************************************************************ + + Synopsis [Type for variable matching in BDD load.] + + Description [] + +******************************************************************************/ + +typedef enum { + DDDMP_VAR_MATCHIDS, + DDDMP_VAR_MATCHPERMIDS, + DDDMP_VAR_MATCHAUXIDS, + DDDMP_VAR_MATCHNAMES, + DDDMP_VAR_COMPOSEIDS +} Dddmp_VarMatchType; + +/**Enum************************************************************************ + + Synopsis [Type for BDD root matching in BDD load.] + + Description [] + +******************************************************************************/ + +typedef enum { + DDDMP_ROOT_MATCHNAMES, + DDDMP_ROOT_MATCHLIST +} Dddmp_RootMatchType; + +typedef struct Dddmp_Hdr_s Dddmp_Hdr_t; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Checks for fatal bugs] + + Description [Conditional safety assertion. It prints out the file + name and line number where the fatal error occurred. + Messages are printed out on stderr. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#ifdef DDDMP_DEBUG +# define Dddmp_Assert(expr,errMsg) \ + { \ + if ((expr) == 0) { \ + fprintf (stderr, "FATAL ERROR: %s\n", errMsg); \ + fprintf (stderr, " File %s -> Line %d\n", \ + __FILE__, __LINE__); \ + fflush (stderr); \ + exit (DDDMP_FAILURE); \ + } \ + } +#else +# define Dddmp_Assert(expr,errMsg) \ + {} +#endif + +/**Macro*********************************************************************** + + Synopsis [Checks for Warnings: If expr==1 it prints out the warning + on stderr.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#define Dddmp_Warning(expr,errMsg) \ + { \ + if ((expr) == 1) { \ + fprintf (stderr, "WARNING: %s\n", errMsg); \ + fprintf (stderr, " File %s -> Line %d\n", \ + __FILE__, __LINE__); \ + fflush (stderr); \ + } \ + } + +/**Macro*********************************************************************** + + Synopsis [Checks for fatal bugs and return the DDDMP_FAILURE flag.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#define Dddmp_CheckAndReturn(expr,errMsg) \ + { \ + if ((expr) == 1) { \ + fprintf (stderr, "FATAL ERROR: %s\n", errMsg); \ + fprintf (stderr, " File %s -> Line %d\n", \ + __FILE__, __LINE__); \ + fflush (stderr); \ + return (DDDMP_FAILURE); \ + } \ + } + +/**Macro*********************************************************************** + + Synopsis [Checks for fatal bugs and go to the label to deal with + the error. + ] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#define Dddmp_CheckAndGotoLabel(expr,errMsg,label) \ + { \ + if ((expr) == 1) { \ + fprintf (stderr, "FATAL ERROR: %s\n", errMsg); \ + fprintf (stderr, " File %s -> Line %d\n", \ + __FILE__, __LINE__); \ + fflush (stderr); \ + goto label; \ + } \ + } + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern int Dddmp_Text2Bin(char *filein, char *fileout); +extern int Dddmp_Bin2Text(char *filein, char *fileout); +extern int Dddmp_cuddBddDisplayBinary(char *fileIn, char *fileOut); +extern DdNode * Dddmp_cuddBddLoad(DdManager *ddMgr, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp); +extern int Dddmp_cuddBddArrayLoad(DdManager *ddMgr, Dddmp_RootMatchType rootMatchMode, char **rootmatchnames, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***pproots); +extern DdNode * Dddmp_cuddAddLoad(DdManager *ddMgr, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp); +extern int Dddmp_cuddAddArrayLoad(DdManager *ddMgr, Dddmp_RootMatchType rootMatchMode, char **rootmatchnames, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***pproots); +extern int Dddmp_cuddHeaderLoad (Dddmp_DecompType *ddType, int *nVars, int *nsuppvars, char ***suppVarNames, char ***orderedVarNames, int **varIds, int **composeIds, int **auxIds, int *nRoots, char *file, FILE *fp); +extern int Dddmp_cuddBddLoadCnf(DdManager *ddMgr, Dddmp_VarMatchType varmatchmode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***rootsPtrPtr, int *nRoots); +extern int Dddmp_cuddBddArrayLoadCnf(DdManager *ddMgr, Dddmp_RootMatchType rootmatchmode, char **rootmatchnames, Dddmp_VarMatchType varmatchmode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***rootsPtrPtr, int *nRoots); +extern int Dddmp_cuddHeaderLoadCnf (int *nVars, int *nsuppvars, char ***suppVarNames, char ***orderedVarNames, int **varIds, int **composeIds, int **auxIds, int *nRoots, char *file, FILE *fp); +extern int Dddmp_cuddAddStore(DdManager *ddMgr, char *ddname, DdNode *f, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int Dddmp_cuddAddArrayStore(DdManager *ddMgr, char *ddname, int nRoots, DdNode **f, char **rootnames, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int Dddmp_cuddBddStore(DdManager *ddMgr, char *ddname, DdNode *f, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int Dddmp_cuddBddArrayStore(DdManager *ddMgr, char *ddname, int nRoots, DdNode **f, char **rootnames, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int Dddmp_cuddBddStoreCnf(DdManager *ddMgr, DdNode *f, Dddmp_DecompCnfStoreType mode, int noHeader, char **varNames, int *bddIds, int *bddAuxIds, int *cnfIds, int idInitial, int edgeInTh, int pathLengthTh, char *fname, FILE *fp, int *clauseNPtr, int *varNewNPtr); +extern int Dddmp_cuddBddArrayStoreCnf(DdManager *ddMgr, DdNode **f, int rootN, Dddmp_DecompCnfStoreType mode, int noHeader, char **varNames, int *bddIds, int *bddAuxIds, int *cnfIds, int idInitial, int edgeInTh, int pathLengthTh, char *fname, FILE *fp, int *clauseNPtr, int *varNewNPtr); +extern int Dddmp_cuddBddStorePrefix(DdManager *ddMgr, int nRoots, DdNode *f, char **inputNames, char **outputNames, char *modelName, char *fileName, FILE *fp); +extern int Dddmp_cuddBddArrayStorePrefix(DdManager *ddMgr, int nroots, DdNode **f, char **inputNames, char **outputNames, char *modelName, char *fname, FILE *fp); +extern int Dddmp_cuddBddStoreBlif(DdManager *ddMgr, int nRoots, DdNode *f, char **inputNames, char **outputNames, char *modelName, char *fileName, FILE *fp); +extern int Dddmp_cuddBddArrayStoreBlif(DdManager *ddMgr, int nroots, DdNode **f, char **inputNames, char **outputNames, char *modelName, char *fname, FILE *fp); +extern int Dddmp_cuddBddStoreSmv(DdManager *ddMgr, int nRoots, DdNode *f, char **inputNames, char **outputNames, char *modelName, char *fileName, FILE *fp); +extern int Dddmp_cuddBddArrayStoreSmv(DdManager *ddMgr, int nroots, DdNode **f, char **inputNames, char **outputNames, char *modelName, char *fname, FILE *fp); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpBinary.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpBinary.c new file mode 100644 index 000000000..a7cd67482 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpBinary.c @@ -0,0 +1,343 @@ +/**CFile********************************************************************** + + FileName [dddmpBinary.c] + + PackageName [dddmp] + + Synopsis [Input and output BDD codes and integers from/to file] + + Description [Input and output BDD codes and integers from/to file + in binary mode. + DD node codes are written as one byte. + Integers of any length are written as sequences of "linked" bytes. + For each byte 7 bits are used for data and one (MSBit) as link with + a further byte (MSB = 1 means one more byte). + Low level read/write of bytes filter , and + with escape sequences. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int WriteByteBinary(FILE *fp, unsigned char c); +static int ReadByteBinary(FILE *fp, unsigned char *cp); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes 1 byte node code] + + Description [outputs a 1 byte node code using the following format: +
                  +     Unused      : 1 bit;
                  +     V           : 2 bits;     (variable code)
                  +     T           : 2 bits;     (Then code)
                  +     Ecompl      : 1 bit;      (Else complemented)
                  +     E           : 2 bits;     (Else code)
                  +    
                  + Ecompl is set with complemented edges. + ] + + SideEffects [None] + + SeeAlso [DddmpReadCode()] + +******************************************************************************/ + +int +DddmpWriteCode ( + FILE *fp /* IN: file where to write the code */, + struct binary_dd_code code /* IN: the code to be written */ + ) +{ + unsigned char c; + int retValue; + + c = (code.Unused<<7)|(code.V<<5)|(code.T<<3)| + (code.Ecompl<<2)|(code.E); + + retValue = WriteByteBinary (fp, c); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Reads a 1 byte node code] + + Description [Reads a 1 byte node code. See DddmpWriteCode() + for code description.] + + SideEffects [None] + + SeeAlso [DddmpWriteCode()] + +******************************************************************************/ + +int +DddmpReadCode ( + FILE *fp /* IN: file where to read the code */, + struct binary_dd_code *pcode /* OUT: the read code */ + ) +{ + unsigned char c; + + if (ReadByteBinary (fp, &c) == EOF) { + return (0); + } + + pcode->Unused = c>>7; + pcode->V = (c>>5) & 3; + pcode->T = (c>>3) & 3; + pcode->Ecompl = (c>>2) & 1; + pcode->E = c & 3; + + return (1); +} + +/**Function******************************************************************** + + Synopsis [Writes a "packed integer"] + + Description [Writes an integer as a sequence of bytes (MSByte first). + For each byte 7 bits are used for data and one (LSBit) as link + with a further byte (LSB = 1 means one more byte). + ] + + SideEffects [None] + + SeeAlso [DddmpReadInt()] + +******************************************************************************/ + +int +DddmpWriteInt ( + FILE *fp /* IN: file where to write the integer */, + int id /* IN: integer to be written */ + ) +{ + char cvet[4]; + int i; + + for (i=0; i<4; i++) { + cvet[i] = (char)((id & 0x0000007f) << 1); + id >>= 7; + } + + for (i=3; (i>0) && (cvet[i] == 0); i--); + + for (; i>0; i--) { + cvet[i] |= (char)1; + if (WriteByteBinary (fp, cvet[i]) == EOF) + return (0); + } + + if (WriteByteBinary (fp, cvet[0]) == EOF) { + return (0); + } + + return (1); +} + + +/**Function******************************************************************** + + Synopsis [Reads a "packed integer"] + + Description [Reads an integer coded on a sequence of bytes. See + DddmpWriteInt() for format.] + + SideEffects [None] + + SeeAlso [DddmpWriteInt()] + +******************************************************************************/ + +int +DddmpReadInt ( + FILE *fp /* IN: file where to read the integer */, + int *pid /* OUT: the read integer */ + ) +{ + unsigned char c; + int i; + unsigned int id; + + id = 0; + for (i=0; i<4; i++) { + if (ReadByteBinary (fp, &c) == EOF) + return (0); + id = (id<<7) | (c>>1); + if ((c & 1) == 0) + break; + } + + /* Check for correct format: last char should + be found before i = 4 */ + assert(i<4); + + *pid = id; + + return (i+1); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a byte to file filtering , and ] + + Description [outputs a byte to file fp. Uses 0x00 as escape character + to filter , and . + This is done for compatibility between unix and dos/windows systems. + ] + + SideEffects [None] + + SeeAlso [ReadByteBinary()] + +******************************************************************************/ + +static int +WriteByteBinary ( + FILE *fp /* IN: file where to write the byte */, + unsigned char c /* IN: the byte to be written */ + ) +{ + unsigned char BinaryEscape; + + switch (c) { + + case 0x00: /* Escape */ + BinaryEscape = 0x00; + if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) + return (0); + c = 0x00; + break; + case 0x0a: /* */ + BinaryEscape = 0x00; + if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) + return (0); + c = 0x01; + break; + case 0x0d: /* */ + BinaryEscape = 0x00; + if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) + return (0); + c = 0x02; + break; + case 0x1a: /* */ + BinaryEscape = 0x00; + if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) + return (0); + c = 0x03; + break; + } + if (fwrite (&c, sizeof(char), 1, fp) != sizeof(char)) + return (0); + + return (1); +} + +/**Function******************************************************************** + + Synopsis [Reads a byte from file with escaped , and ] + + Description [inputs a byte to file fp. 0x00 has been used as escape character + to filter , and . This is done for + compatibility between unix and dos/windows systems. + ] + + SideEffects [None] + + SeeAlso [WriteByteBinary()] + +******************************************************************************/ + +static int +ReadByteBinary ( + FILE *fp /* IN: file where to read the byte */, + unsigned char *cp /* OUT: the read byte */ + ) +{ + + if (fread (cp, sizeof(char), 1, fp) != sizeof(char)) { + return (0); + } + + if (*cp == 0x00) { /* Escape */ + if (fread (cp, sizeof(char), 1, fp) != sizeof(char)) { + return (0); + } + + switch (*cp) { + + case 0x00: /* Escape */ + break; + case 0x01: /* */ + *cp = 0x0a; + break; + case 0x02: /* */ + *cp = 0x0d; + break; + case 0x03: /* */ + *cp = 0x1a; + break; + } + } + + return (1); +} + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpConvert.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpConvert.c new file mode 100644 index 000000000..c24292e8c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpConvert.c @@ -0,0 +1,180 @@ +/**CFile********************************************************************** + + FileName [dddmpConvert.c] + + PackageName [dddmp] + + Synopsis [Conversion between ASCII and binary formats] + + Description [Conversion between ASCII and binary formats is presently + supported by loading a BDD in the source format and storing it + in the target one. We plan to introduce ad hoc procedures + avoiding explicit BDD node generation. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Converts from ASCII to binary format] + + Description [Converts from ASCII to binary format. A BDD array is loaded and + and stored to the target file.] + + SideEffects [None] + + SeeAlso [Dddmp_Bin2Text()] + +******************************************************************************/ + +int +Dddmp_Text2Bin ( + char *filein /* IN: name of ASCII file */, + char *fileout /* IN: name of binary file */ + ) +{ + DdManager *ddMgr; /* pointer to DD manager */ + DdNode **roots; /* array of BDD roots to be loaded */ + int nRoots; /* number of BDD roots */ + int retValue; + + ddMgr = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); + if (ddMgr == NULL) { + return (0); + } + + nRoots = Dddmp_cuddBddArrayLoad(ddMgr,DDDMP_ROOT_MATCHLIST,NULL, + DDDMP_VAR_MATCHIDS,NULL,NULL,NULL, + DDDMP_MODE_TEXT,filein,NULL,&roots); + + Dddmp_CheckAndGotoLabel (nRoots<=0, + "Negative Number of Roots.", failure); + + retValue = Dddmp_cuddBddArrayStore (ddMgr,NULL,nRoots,roots,NULL, + NULL,NULL,DDDMP_MODE_BINARY,DDDMP_VARIDS,fileout,NULL); + + Dddmp_CheckAndGotoLabel (retValue<=0, + "Error code returned.", failure); + + Cudd_Quit(ddMgr); + return (1); + + failure: + printf("error converting BDD format\n"); + Cudd_Quit(ddMgr); + return (0); +} + +/**Function******************************************************************** + + Synopsis [Converts from binary to ASCII format] + + Description [Converts from binary to ASCII format. A BDD array is loaded and + and stored to the target file.] + + SideEffects [None] + + SeeAlso [Dddmp_Text2Bin()] + +******************************************************************************/ + +int +Dddmp_Bin2Text ( + char *filein /* IN: name of binary file */, + char *fileout /* IN: name of ASCII file */ + ) +{ + DdManager *ddMgr; /* pointer to DD manager */ + DdNode **roots; /* array of BDD roots to be loaded */ + int nRoots; /* number of BDD roots */ + int retValue; + + ddMgr = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); + if (ddMgr == NULL) { + return (0); + } + + nRoots = Dddmp_cuddBddArrayLoad(ddMgr,DDDMP_ROOT_MATCHLIST,NULL, + DDDMP_VAR_MATCHIDS,NULL,NULL,NULL, + DDDMP_MODE_BINARY,filein,NULL,&roots); + + Dddmp_CheckAndGotoLabel (nRoots<=0, + "Negative Number of Roots.", failure); + + retValue = Dddmp_cuddBddArrayStore (ddMgr,NULL,nRoots,roots,NULL, + NULL,NULL,DDDMP_MODE_TEXT,DDDMP_VARIDS,fileout,NULL); + + Dddmp_CheckAndGotoLabel (retValue<=0, + "Error code returned.", failure); + + Cudd_Quit(ddMgr); + return (1); + + failure: + printf("error converting BDD format\n"); + Cudd_Quit(ddMgr); + return (0); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDbg.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDbg.c new file mode 100644 index 000000000..88304f5af --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDbg.c @@ -0,0 +1,166 @@ +/**CFile********************************************************************** + + FileName [dddmpDbg.c] + + PackageName [dddmp] + + Synopsis [Functions to display BDD files] + + Description [Functions to display BDD files in binary format + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Display a binary dump file in a text file] + + Description [Display a binary dump file in a text file] + + SideEffects [None] + + SeeAlso [Dddmp_cuddBddStore , Dddmp_cuddBddLoad ] + +******************************************************************************/ + +int +Dddmp_cuddBddDisplayBinary( + char *fileIn /* IN: name of binary file */, + char *fileOut /* IN: name of text file */ + ) +{ + FILE *fp, *fpo; + int id, size; + struct binary_dd_code code; + char buf[1000]; + int nnodes, i; + + fp = fopen (fileIn, "rb"); + if (fp == 0) { + return (0); + } + + fpo = fopen (fileOut, "w"); + if (fpo == 0) { + return (0); + } + + while (fgets(buf, 999,fp)!=NULL) { + fprintf (fpo, "%s", buf); + if (strncmp(buf, ".nnodes", 7) == 0) { + sscanf (buf, "%*s %d", &nnodes); + } + if (strncmp(buf, ".rootids", 8) == 0) { + break; + } + } + + for (i=1; i<=nnodes; i++) { + if (feof(fp)) { + return (0); + } + if (DddmpReadCode(fp,&code) == 0) { + return (0); + } + fprintf (fpo, "c : v %d | T %d | E %d\n", + (int)code.V, (int)code.T, + (code.Ecompl ? -(int)(code.E) : (int)(code.E))); + if (code.V == DDDMP_TERMINAL) { + continue; + } + if (code.V <= DDDMP_RELATIVE_ID) { + size = DddmpReadInt(fp,&id); + if (size == 0) { + return (0); + } + fprintf(fpo, "v(%d): %d\n", size, id); + } + if (code.T <= DDDMP_RELATIVE_ID) { + size = DddmpReadInt(fp,&id); + if (size == 0) { + return (0); + } + fprintf(fpo, "T(%d): %d\n", size, id); + } + if (code.E <= DDDMP_RELATIVE_ID) { + size = DddmpReadInt(fp,&id); + if (size == 0) { + return (0); + } + fprintf(fpo, "E(%d): %d\n", size, id); + } + + } + + fgets(buf, 999,fp); + if (strncmp(buf, ".end", 4) != 0) { + return (0); + } + + fprintf(fpo, ".end"); + + fclose(fp); + fclose(fpo); + + return (1); +} + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeBdd.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeBdd.c new file mode 100644 index 000000000..443ef5dbf --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeBdd.c @@ -0,0 +1,455 @@ +/**CFile********************************************************************** + + FileName [dddmpDdNodeBdd.c] + + PackageName [dddmp] + + Synopsis [Functions to handle BDD node infos and numbering] + + Description [Functions to handle BDD node infos and numbering. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NumberNodeRecur(DdNode *f, int id); +static void RemoveFromUniqueRecur(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecur(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and number them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodes()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecur(), NumberNodeRecur(), + DddmpUnnumberDdNodes()] + +******************************************************************************/ + +int +DddmpNumberDdNodes ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int n /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int id=0, i; + + for (i=0; inext = (struct DdNode *)((ptruint)((id)<<1)); + } + + return; +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndex(), DddmpSetVisited (), DddmpVisited ()] + +******************************************************************************/ + +int +DddmpReadNodeIndex ( + DdNode *f /* IN: BDD node */ + ) +{ + +#if 0 + if (1 || !Cudd_IsConstant (f)) { +#else + if (!Cudd_IsConstant (f)) { +#endif + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisited (), DddmpClearVisited ()] + +******************************************************************************/ + +int +DddmpVisited ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisited (), DddmpClearVisited ()] + +******************************************************************************/ + +void +DddmpSetVisited ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisited (), DddmpSetVisited ()] + +******************************************************************************/ + +void +DddmpClearVisited ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecur( + DdNode *f /* IN: root of the BDD to be numbered */, + int id /* IN/OUT: index to be assigned to the node */ + ) +{ + f = Cudd_Regular(f); + + if (!DddmpVisited (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecur (cuddT (f), id); + id = NumberNodeRecur (cuddE (f), id); + } + + DddmpWriteNodeIndex (f, ++id); + DddmpClearVisited (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecur()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisited (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecur (ddMgr, cuddT (f)); + RemoveFromUniqueRecur (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisited (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursively)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUnique()] + +******************************************************************************/ + +static void +RestoreInUniqueRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + DddmpClearVisited (f); + /*f->next = NULL;*/ + return; + } + + RestoreInUniqueRecur (ddMgr, cuddT (f)); + RestoreInUniqueRecur (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + f->next = *previousP; + *previousP = f; + + return; +} + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeCnf.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeCnf.c new file mode 100644 index 000000000..421d920e9 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpDdNodeCnf.c @@ -0,0 +1,944 @@ +/**CFile********************************************************************** + + FileName [dddmpDdNodeCnf.c] + + PackageName [dddmp] + + Synopsis [Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs] + + Description [Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMP_DEBUG_CNF 0 + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpWriteNodeIndexCnf(DdNode *f, int *cnfIds, int id); +static int DddmpReadNodeIndexCnf(DdNode *f); +static int DddmpClearVisitedCnfRecur(DdNode *f); +static int DddmpVisitedCnf(DdNode *f); +static void DddmpSetVisitedCnf(DdNode *f); +static void DddmpClearVisitedCnf(DdNode *f); +static int NumberNodeRecurCnf(DdNode *f, int *cnfIds, int id); +static void DddmpDdNodesCheckIncomingAndScanPath(DdNode *f, int pathLengthCurrent, int edgeInTh, int pathLengthTh); +static int DddmpDdNodesNumberEdgesRecur(DdNode *f, int *cnfIds, int id); +static int DddmpDdNodesResetCountRecur(DdNode *f); +static int DddmpDdNodesCountEdgesRecur(DdNode *f); +static void RemoveFromUniqueRecurCnf(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecurCnf(DdManager *ddMgr, DdNode *f); +static int DddmpPrintBddAndNextRecur(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and numbers them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodesCnf()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecurCnf(), NumberNodeRecurCnf(), + DddmpUnnumberDdNodesCnf()] + +******************************************************************************/ + +int +DddmpNumberDdNodesCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int rootN /* IN: number of BDD roots in the array of BDDs */, + int *cnfIds /* OUT: CNF identifiers for variables */, + int id /* OUT: number of Temporary Variables Introduced */ + ) +{ + int i; + + for (i=0; i BDDs After Count Reset:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*----------------------- Count Incoming Edges ----------------------------*/ + + for (i=0; i BDDs After Count Recur:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*------------------------- Count Path Length ----------------------------*/ + + for (i=0; i BDDs After Check Incoming And Scan Path:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*-------------------- Number Nodes and Set Visited -----------------------*/ + + for (i=0; i BDDs After Count Edges Recur:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*---------------------------- Clear Visited ------------------------------*/ + +#if DDDMP_DEBUG_CNF + for (i=0; i BDDs After All Numbering Process:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif +#endif + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Restores nodes in unique table, loosing numbering] + + Description [Node indexes are no more needed. Nodes are re-linked in the + unique table. + ] + + SideEffects [None] + + SeeAlso [DddmpNumberDdNode()] + +******************************************************************************/ + +void +DddmpUnnumberDdNodesCnf( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int rootN /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int i; + + for (i=0; i Bdd %d:\n", i); + fflush (stdout); + DddmpPrintBddAndNextRecur (ddMgr, f[i]); + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Write index to node] + + Description [The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. + ] + + SideEffects [None] + + SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf () + ] + +******************************************************************************/ + +int +DddmpWriteNodeIndexCnfBis ( + DdNode *f /* IN: BDD node */, + int id /* IN: index to be written */ + ) +{ + if (!Cudd_IsConstant (f)) { + f->next = (struct DdNode *)((ptruint)((id)<<1)); + } + + return (DDDMP_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Write index to node] + + Description [The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. The index corresponds to + the BDD node variable if both the node's children are a + constant node, otherwise a new CNF variable is used. + ] + + SideEffects [None] + + SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf ()] + +*****************************************************************************/ + +static int +DddmpWriteNodeIndexCnf ( + DdNode *f /* IN: BDD node */, + int *cnfIds /* IN: possible source for the index to be written */, + int id /* IN: possible source for the index to be written */ + ) +{ + if (!Cudd_IsConstant (f)) { + if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) { + /* If Variable SET ID as Variable ID */ + f->next = (struct DdNode *)((ptruint)((cnfIds[f->index])<<1)); + } else { + f->next = (struct DdNode *)((ptruint)((id)<<1)); + id++; + } + } + + return(id); +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf ()] + +******************************************************************************/ + +static int +DddmpReadNodeIndexCnf ( + DdNode *f /* IN: BDD node */ + ) +{ + if (!Cudd_IsConstant (f)) { + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Mark ALL nodes as not visited] + + Description [Mark ALL nodes as not visited (it recurs on the node children)] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()] + +******************************************************************************/ + +static int +DddmpClearVisitedCnfRecur ( + DdNode *f /* IN: root of the BDD to be marked */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (cuddIsConstant (f)) { + return (DDDMP_SUCCESS); + } + + if (!DddmpVisitedCnf (f)) { + return (DDDMP_SUCCESS); + } + + retValue = DddmpClearVisitedCnfRecur (cuddT (f)); + retValue = DddmpClearVisitedCnfRecur (cuddE (f)); + + DddmpClearVisitedCnf (f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisitedCnf (), DddmpClearVisitedCnf ()] + +******************************************************************************/ + +static int +DddmpVisitedCnf ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpClearVisitedCnf ()] + +******************************************************************************/ + +static void +DddmpSetVisitedCnf ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()] + +******************************************************************************/ + +static void +DddmpClearVisitedCnf ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecurCnf( + DdNode *f /* IN: root of the BDD to be numbered */, + int *cnfIds /* IN: possible source for numbering */, + int id /* IN/OUT: possible source for numbering */ + ) +{ + f = Cudd_Regular(f); + + if (!DddmpVisitedCnf (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecurCnf (cuddT (f), cnfIds, id); + id = NumberNodeRecurCnf (cuddE (f), cnfIds, id); + } + + id = DddmpWriteNodeIndexCnf (f, cnfIds, id); + DddmpClearVisitedCnf (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with the right polarity. + The node is assigned to a new CNF variable only if it is a "shared" + node (i.e. the number of its incoming edges is greater than 1). + ] + + SideEffects ["visited" flags are set.] + + SeeAlso [] + +******************************************************************************/ + +static void +DddmpDdNodesCheckIncomingAndScanPath ( + DdNode *f /* IN: BDD node to be numbered */, + int pathLengthCurrent /* IN: Current Path Length */, + int edgeInTh /* IN: Max # In-Edges, after a Insert Cut Point */, + int pathLengthTh /* IN: Max Path Length (after, Insert a Cut Point) */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (DddmpVisitedCnf (f)) { + return; + } + + if (cuddIsConstant (f)) { + return; + } + + pathLengthCurrent++; + retValue = DddmpReadNodeIndexCnf (f); + + if ( ((edgeInTh >= 0) && (retValue > edgeInTh)) || + ((pathLengthTh >= 0) && (pathLengthCurrent > pathLengthTh)) + ) { + DddmpWriteNodeIndexCnfBis (f, 1); + pathLengthCurrent = 0; + } else { + DddmpWriteNodeIndexCnfBis (f, 0); + } + + DddmpDdNodesCheckIncomingAndScanPath (cuddT (f), pathLengthCurrent, + edgeInTh, pathLengthTh); + DddmpDdNodesCheckIncomingAndScanPath (cuddE (f), pathLengthCurrent, + edgeInTh, pathLengthTh); + + DddmpSetVisitedCnf (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with the inverse polarity. + Numbering follows the subsequent strategy: + * if the index = 0 it remains so + * if the index >= 1 it gets enumerated. + This implies that the node is assigned to a new CNF variable only if + it is not a terminal node otherwise it is assigned the index of + the BDD variable. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesNumberEdgesRecur ( + DdNode *f /* IN: BDD node to be numbered */, + int *cnfIds /* IN: possible source for numbering */, + int id /* IN/OUT: possible source for numbering */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (!DddmpVisitedCnf (f)) { + return (id); + } + + if (cuddIsConstant (f)) { + return (id); + } + + id = DddmpDdNodesNumberEdgesRecur (cuddT (f), cnfIds, id); + id = DddmpDdNodesNumberEdgesRecur (cuddE (f), cnfIds, id); + + retValue = DddmpReadNodeIndexCnf (f); + if (retValue >= 1) { + id = DddmpWriteNodeIndexCnf (f, cnfIds, id); + } else { + DddmpWriteNodeIndexCnfBis (f, 0); + } + + DddmpClearVisitedCnf (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Resets counter and visited flag for ALL nodes of a BDD] + + Description [Resets counter and visited flag for ALL nodes of a BDD (it + recurs on the node children). The index field of the node is + used as counter. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesResetCountRecur ( + DdNode *f /* IN: root of the BDD whose counters are reset */ + ) +{ + int retValue; + + f = Cudd_Regular (f); + + if (!DddmpVisitedCnf (f)) { + return (DDDMP_SUCCESS); + } + + if (!cuddIsConstant (f)) { + retValue = DddmpDdNodesResetCountRecur (cuddT (f)); + retValue = DddmpDdNodesResetCountRecur (cuddE (f)); + } + + DddmpWriteNodeIndexCnfBis (f, 0); + DddmpClearVisitedCnf (f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Counts the number of incoming edges for each node of a BDD] + + Description [Counts (recursively) the number of incoming edges for each + node of a BDD. This number is stored in the index field. + ] + + SideEffects ["visited" flags remain untouched.] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesCountEdgesRecur ( + DdNode *f /* IN: root of the BDD */ + ) +{ + int indexValue, retValue; + + f = Cudd_Regular (f); + + if (cuddIsConstant (f)) { + return (DDDMP_SUCCESS); + } + + if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) { + return (DDDMP_SUCCESS); + } + + indexValue = DddmpReadNodeIndexCnf (f); + + /* IF (first time) THEN recur */ + if (indexValue == 0) { + retValue = DddmpDdNodesCountEdgesRecur (cuddT (f)); + retValue = DddmpDdNodesCountEdgesRecur (cuddE (f)); + } + + /* Increment Incoming-Edge Count Flag */ + indexValue++; + DddmpWriteNodeIndexCnfBis (f, indexValue); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on son nodes. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecurCnf()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecurCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisitedCnf (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecurCnf (ddMgr, cuddT (f)); + RemoveFromUniqueRecurCnf (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisitedCnf (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursive)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUnique()] + +******************************************************************************/ + +static void +RestoreInUniqueRecurCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + DddmpClearVisitedCnf (f); + /*f->next = NULL;*/ + return; + } + + RestoreInUniqueRecurCnf (ddMgr, cuddT (f)); + RestoreInUniqueRecurCnf (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + f->next = *previousP; + *previousP = f; + + return; +} + +/**Function******************************************************************** + + Synopsis [Prints debug info] + + Description [Prints debug info for a BDD on the screen. It recurs on + node's children. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpPrintBddAndNextRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be displayed */ + ) +{ + int retValue; + DdNode *fPtr, *tPtr, *ePtr; + + fPtr = Cudd_Regular (f); + + if (Cudd_IsComplement (f)) { + fprintf (stdout, "sign=- ptr=%ld ", ((long int) fPtr)); + } else { + fprintf (stdout, "sign=+ ptr=%ld ", ((long int) fPtr)); + } + + if (cuddIsConstant (fPtr)) { + fprintf (stdout, "one\n"); + fflush (stdout); + return (DDDMP_SUCCESS); + } + + fprintf (stdout, + "thenPtr=%ld elsePtr=%ld BddId=%d CnfId=%d Visited=%d\n", + ((long int) cuddT (fPtr)), ((long int) cuddE (fPtr)), + fPtr->index, DddmpReadNodeIndexCnf (fPtr), + DddmpVisitedCnf (fPtr)); + + tPtr = cuddT (fPtr); + ePtr = cuddE (fPtr); + if (Cudd_IsComplement (f)) { + tPtr = Cudd_Not (tPtr); + ePtr = Cudd_Not (ePtr); + } + + retValue = DddmpPrintBddAndNextRecur (ddMgr, tPtr); + retValue = DddmpPrintBddAndNextRecur (ddMgr, ePtr); + + return (DDDMP_SUCCESS); +} + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpInt.h b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpInt.h new file mode 100644 index 000000000..7d0f54dfc --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpInt.h @@ -0,0 +1,216 @@ +/**CHeaderFile***************************************************************** + + FileName [dddmpInt.h] + + PackageName [dddmp] + + Synopsis [Low level functions to read in and write out bdds to file] + + Description [A set of internal low-level routines of the dddmp package + doing: +
                    +
                  • read and write of node codes in binary mode, +
                  • read and write of integers in binary mode, +
                  • marking/unmarking nodes as visited, +
                  • numbering nodes. +
                  + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2002 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#ifndef _DDDMPINT +#define _DDDMPINT + +#include "dddmp.h" +#include "cuddInt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* constants for code fields */ +#define DDDMP_TERMINAL 0 +#define DDDMP_ABSOLUTE_ID 1 +#define DDDMP_RELATIVE_ID 2 +#define DDDMP_RELATIVE_1 3 + +#define DDDMP_MAXSTRLEN 500 + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + +/**Struct********************************************************************** + Synopsis [used in binary mode to store code info of a dd node] + Description [V , T , E store the mode used to represent variable, Then + and Else indexes. An index is either an absolute + ( DDDMP_ABSOLUTE_ID ), + a relative numbers ( DDDMP_RELATIVE_ID , DDDMP_RELATIVE_1 ) or + a terminal node ( DDDMP_TERMINAL ) . + Ecomp is used for the complemented edge attribute. + ] + SideEffect [none] + SeeAlso [DddmpWriteCode DddmpReadCode] +******************************************************************************/ + +struct binary_dd_code { + unsigned Unused : 1; + unsigned V : 2; + unsigned T : 2; + unsigned Ecompl : 1; + unsigned E : 2; +}; + +/**Struct********************************************************************* + + Synopsis [BDD file header] + + Description [Structure containing the BDD header file infos] + +******************************************************************************/ + +struct Dddmp_Hdr_s { + char *ver; + char mode; + Dddmp_DecompType ddType; + Dddmp_VarInfoType varinfo; + char *dd; + int nnodes; + int nVars; + int nsuppvars; + char **orderedVarNames; + char **suppVarNames; + int *ids; + int *permids; + int *auxids; + int *cnfids; + int nRoots; + int *rootids; + char **rootnames; + int nAddedCnfVar; + int nVarsCnf; + int nClausesCnf; +}; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Memory Allocation Macro for DDDMP] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#ifdef ALLOC +# define DDDMP_ALLOC(type, num) ALLOC(type,num) +#else +# define DDDMP_ALLOC(type, num) \ + ((type *) malloc(sizeof(type) * (num))) +#endif + +/**Macro*********************************************************************** + + Synopsis [Memory Free Macro for DDDMP] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#ifdef FREE +#define DDDMP_FREE(p) (FREE(p)) +#else +#define DDDMP_FREE(p) \ + ((p)!=NULL)?(free(p)):0) +#endif + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern int DddmpWriteCode(FILE *fp, struct binary_dd_code code); +extern int DddmpReadCode(FILE *fp, struct binary_dd_code *pcode); +extern int DddmpWriteInt(FILE *fp, int id); +extern int DddmpReadInt(FILE *fp, int *pid); +extern int DddmpNumberAddNodes(DdManager *ddMgr, DdNode **f, int n); +extern void DddmpUnnumberAddNodes(DdManager *ddMgr, DdNode **f, int n); +extern void DddmpWriteNodeIndexAdd(DdNode *f, int id); +extern int DddmpReadNodeIndexAdd(DdNode *f); +extern int DddmpVisitedAdd(DdNode *f); +extern void DddmpSetVisitedAdd(DdNode *f); +extern void DddmpClearVisitedAdd(DdNode *f); +extern int DddmpNumberBddNodes(DdManager *ddMgr, DdNode **f, int n); +extern void DddmpUnnumberBddNodes(DdManager *ddMgr, DdNode **f, int n); +extern void DddmpWriteNodeIndexBdd(DdNode *f, int id); +extern int DddmpReadNodeIndexBdd(DdNode *f); +extern int DddmpVisitedBdd(DdNode *f); +extern void DddmpSetVisitedBdd(DdNode *f); +extern void DddmpClearVisitedBdd(DdNode *f); +extern int DddmpNumberDdNodesCnf(DdManager *ddMgr, DdNode **f, int rootN, int *cnfIds, int id); +extern int DddmpDdNodesCountEdgesAndNumber(DdManager *ddMgr, DdNode **f, int rootN, int edgeInTh, int pathLengthTh, int *cnfIds, int id); +extern void DddmpUnnumberDdNodesCnf(DdManager *ddMgr, DdNode **f, int rootN); +extern int DddmpPrintBddAndNext(DdManager *ddMgr, DdNode **f, int rootN); +extern int DddmpWriteNodeIndexCnf(DdNode *f, int id); +extern int DddmpVisitedCnf(DdNode *f); +extern void DddmpSetVisitedCnf(DdNode *f); +extern int DddmpReadNodeIndexCnf(DdNode *f); +extern int DddmpCuddDdArrayStoreBdd(Dddmp_DecompType ddType, DdManager *ddMgr, char *ddname, int nRoots, DdNode **f, char **rootnames, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int DddmpCuddBddArrayStore(Dddmp_DecompType ddType, DdManager *ddMgr, char *ddname, int nRoots, DdNode **f, char **rootnames, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int QsortStrcmp(const void *ps1, const void *ps2); +extern int FindVarname(char *name, char **array, int n); +extern char * DddmpStrDup(char *str); +extern char ** DddmpStrArrayDup(char **array, int n); +extern char ** DddmpStrArrayRead(FILE *fp, int n); +extern int DddmpStrArrayWrite(FILE *fp, char **array, int n); +extern void DddmpStrArrayFree(char **array, int n); +extern int * DddmpIntArrayDup(int *array, int n); +extern int * DddmpIntArrayRead(FILE *fp, int n); +extern int DddmpIntArrayWrite(FILE *fp, int *array, int n); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoad.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoad.c new file mode 100644 index 000000000..27d9f0918 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoad.c @@ -0,0 +1,1486 @@ +/**CFile********************************************************************** + + FileName [dddmpLoad.c] + + PackageName [dddmp] + + Synopsis [Functions to read in bdds to file] + + Description [Functions to read in bdds to file. BDDs + are represended on file either in text or binary format under the + following rules. A file contains a forest of BDDs (a vector of + Boolean functions). BDD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to BDD + functions, followed by the list of nodes. BDD nodes are listed + according to their numbering, and in the present implementation + numbering follows a post-order strategy, in such a way that a node + is never listed before its Then/Else children. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define matchkeywd(str,key) (strncmp(str,key,strlen(key))==0) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpCuddDdArrayLoad(Dddmp_DecompType ddType, DdManager *ddMgr, Dddmp_RootMatchType rootMatchMode, char **rootmatchnames, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***pproots); +static Dddmp_Hdr_t * DddmpBddReadHeader(char *file, FILE *fp); +static void DddmpFreeHeader(Dddmp_Hdr_t *Hdr); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads a dump file representing the argument BDD.] + + Description [Reads a dump file representing the argument BDD. + Dddmp_cuddBddArrayLoad is used through a dummy array (see this + function's description for more details). + Mode, the requested input file format, is checked against + the file format. + The loaded BDDs is referenced before returning it. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddStore, Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +DdNode * +Dddmp_cuddBddLoad ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names - by IDs */, + int *varmatchauxids /* IN: array of variable auxids - by IDs */, + int *varcomposeids /* IN: array of new ids accessed - by IDs */, + int mode /* IN: requested input file format */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + DdNode *f , **tmpArray; + int i, nRoots; + + nRoots = Dddmp_cuddBddArrayLoad(ddMgr,DDDMP_ROOT_MATCHLIST,NULL, + varMatchMode,varmatchnames,varmatchauxids,varcomposeids, + mode,file,fp,&tmpArray); + + if (nRoots == 0) { + return (NULL); + } else { + f = tmpArray[0]; + if (nRoots > 1) { + fprintf (stderr, + "Warning: %d BDD roots found in file. Only first retrieved.\n", + nRoots); + for (i=1; i +
                • varMatchMode=DDDMP_VAR_MATCHIDS

                  + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

                • varMatchMode=DDDMP_VAR_MATCHPERMIDS

                  + is used to allow variable match according to the position in the + ordering. + +

                • varMatchMode=DDDMP_VAR_MATCHNAMES

                  + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

                • varMatchMode=DDDMP_VAR_MATCHIDS

                  + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

                • varMatchMode=DDDMP_VAR_COMPOSEIDS

                  + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. + + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. + + All the loaded BDDs are referenced before returning them. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddArrayStore] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayLoad ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_RootMatchType rootMatchMode /* IN: storing mode selector */, + char **rootmatchnames /* IN: sorted names for loaded roots */, + Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by ids */, + int *varmatchauxids /* IN: array of variable auxids, by ids */, + int *varcomposeids /* IN: array of new ids, by ids */, + int mode /* IN: requested input file format */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***pproots /* OUT: array of returned BDD roots */ + ) +{ + int retValue; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Load.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Load.\n"); + fflush (stderr); + } + } +#endif +#endif + + retValue = DddmpCuddDdArrayLoad (DDDMP_BDD, ddMgr, rootMatchMode, + rootmatchnames, varMatchMode, varmatchnames, varmatchauxids, + varcomposeids, mode, file, fp, pproots); + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Load.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Load.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Reads a dump file representing the argument ADD.] + + Description [Reads a dump file representing the argument ADD. + Dddmp_cuddAddArrayLoad is used through a dummy array. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddAddStore, Dddmp_cuddAddArrayLoad] + +******************************************************************************/ + +DdNode * +Dddmp_cuddAddLoad ( + DdManager *ddMgr /* IN: Manager */, + Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names by IDs */, + int *varmatchauxids /* IN: array of variable auxids by IDs */, + int *varcomposeids /* IN: array of new ids by IDs */, + int mode /* IN: requested input file format */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + DdNode *f , **tmpArray; + int i, nRoots; + + nRoots = Dddmp_cuddAddArrayLoad (ddMgr, DDDMP_ROOT_MATCHLIST,NULL, + varMatchMode, varmatchnames, varmatchauxids, varcomposeids, + mode, file, fp, &tmpArray); + + if (nRoots == 0) { + return (NULL); + } else { + f = tmpArray[0]; + if (nRoots > 1) { + fprintf (stderr, + "Warning: %d BDD roots found in file. Only first retrieved.\n", + nRoots); + for (i=1; innodes==0, "Zero number of nodes.", + failure); + + /* + * Type, number of variables (tot and support) + */ + + *ddType = Hdr->ddType; + *nVars = Hdr->nVars; + *nsuppvars = Hdr->nsuppvars; + + /* + * Support Varnames + */ + + if (Hdr->suppVarNames != NULL) { + *suppVarNames = DDDMP_ALLOC (char *, *nsuppvars); + Dddmp_CheckAndGotoLabel (*suppVarNames==NULL, + "Error allocating memory.", failure); + + for (i=0; i<*nsuppvars; i++) { + (*suppVarNames)[i] = DDDMP_ALLOC (char, + (strlen (Hdr->suppVarNames[i]) + 1)); + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + strcpy ((*suppVarNames)[i], Hdr->suppVarNames[i]); + } + } else { + *suppVarNames = NULL; + } + + /* + * Ordered Varnames + */ + + if (Hdr->orderedVarNames != NULL) { + *orderedVarNames = DDDMP_ALLOC (char *, *nVars); + Dddmp_CheckAndGotoLabel (*orderedVarNames==NULL, + "Error allocating memory.", failure); + + for (i=0; i<*nVars; i++) { + (*orderedVarNames)[i] = DDDMP_ALLOC (char, + (strlen (Hdr->orderedVarNames[i]) + 1)); + Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + strcpy ((*orderedVarNames)[i], Hdr->orderedVarNames[i]); + } + } else { + *orderedVarNames = NULL; + } + + /* + * Variable Ids + */ + + if (Hdr->ids != NULL) { + tmpVarIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarIds==NULL, "Error allocating memory.", + failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarIds[i] = Hdr->ids[i]; + } + + *varIds = tmpVarIds; + } else { + *varIds = NULL; + } + + /* + * Variable Compose Ids + */ + + if (Hdr->permids != NULL) { + tmpVarComposeIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarComposeIds==NULL, + "Error allocating memory.", failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarComposeIds[i] = Hdr->permids[i]; + } + + *varComposeIds = tmpVarComposeIds; + } else { + *varComposeIds = NULL; + } + + /* + * Variable Auxiliary Ids + */ + + if (Hdr->auxids != NULL) { + tmpVarAuxIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarAuxIds==NULL, + "Error allocating memory.", failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarAuxIds[i] = Hdr->auxids[i]; + } + + *varAuxIds = tmpVarAuxIds; + } else { + *varAuxIds = NULL; + } + + /* + * Number of roots + */ + + *nRoots = Hdr->nRoots; + + /* + * Free and Return + */ + + if (fileToClose == 1) { + fclose (fp); + } + + DddmpFreeHeader(Hdr); + + return (DDDMP_SUCCESS); + + failure: + return (DDDMP_FAILURE); +} + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads a dump file representing the argument BDDs.] + + Description [Reads a dump file representing the argument BDDs. The header is + common to both text and binary mode. The node list is either + in text or binary format. A dynamic vector of DD pointers + is allocated to support conversion from DD indexes to pointers. + Several criteria are supported for variable match between file + and dd manager. Several changes/permutations/compositions are allowed + for variables while loading DDs. Variable of the dd manager are allowed + to match with variables on file on ids, permids, varnames, + varauxids; also direct composition between ids and + composeids is supported. More in detail: +

                    +
                  1. varMatchMode=DDDMP_VAR_MATCHIDS

                    + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

                  2. varMatchMode=DDDMP_VAR_MATCHPERMIDS

                    + is used to allow variable match according to the position in the ordering. + +

                  3. varMatchMode=DDDMP_VAR_MATCHNAMES

                    + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

                  4. varMatchMode=DDDMP_VAR_MATCHIDS

                    + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

                  5. varMatchMode=DDDMP_VAR_COMPOSEIDS

                    + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. +

                  + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddArrayStore] + +******************************************************************************/ + +static int +DddmpCuddDdArrayLoad ( + Dddmp_DecompType ddType /* IN: Selects decomp type */, + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_RootMatchType rootMatchMode /* IN: storing mode selector */, + char **rootmatchnames /* IN: sorted names for loaded roots */, + Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by ids */, + int *varmatchauxids /* IN: array of variable auxids, by ids */, + int *varcomposeids /* IN: array of new ids, by ids */, + int mode /* IN: requested input file format */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***pproots /* OUT: array BDD roots (by reference) */ + ) +{ + Dddmp_Hdr_t *Hdr = NULL; + DdNode *f = NULL; + DdNode *T = NULL; + DdNode *E = NULL; + struct binary_dd_code code; + char buf[DDDMP_MAXSTRLEN]; + int retValue, id, size, maxv; + int i, j, k, maxaux, var, vT, vE, idT, idE; + double addConstant; + int *permsupport = NULL; + int *convertids = NULL; + int *invconvertids = NULL; + int *invauxids = NULL; + char **sortedvarnames = NULL; + int nddvars, nRoots; + DdNode **pnodes = NULL; + unsigned char *pvars1byte = NULL; + unsigned short *pvars2byte = NULL; + DdNode **proots = NULL; + int fileToClose = 0; + + *pproots = NULL; + + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + nddvars = ddMgr->size; + + Hdr = DddmpBddReadHeader (NULL, fp); + + Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.", + failure); + + nRoots = Hdr->nRoots; + + if (Hdr->ddType != ddType) { + (void) fprintf (stderr, "DdLoad Error: ddType mismatch\n"); + + if (Hdr->ddType == DDDMP_BDD) + (void) fprintf (stderr, "BDD found\n"); + if (Hdr->ddType == DDDMP_ADD) + (void) fprintf (stderr, "ADD found\n"); + if (ddType == DDDMP_BDD) + (void) fprintf (stderr, "when loading a BDD\n"); + if (ddType == DDDMP_ADD) + (void) fprintf (stderr, "when loading an ADD\n"); + + fflush (stderr); + goto failure; + } + + if (Hdr->mode != mode) { + Dddmp_CheckAndGotoLabel (mode!=DDDMP_MODE_DEFAULT, + "Mode Mismatch.", failure); + mode = Hdr->mode; + } + + /* + * For each variable in the support + * compute the relative position in the ordering + * (within the support only) + */ + + permsupport = DDDMP_ALLOC (int, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (permsupport==NULL, "Error allocating memory.", + failure); + for (i=0,k=0; i < Hdr->nVars; i++) { + for (j=0; j < Hdr->nsuppvars; j++) { + if (Hdr->permids[j] == i) { + permsupport[j] = k++; + } + } + } + Dddmp_Assert (k==Hdr->nsuppvars, "k==Hdr->nsuppvars"); + + if (Hdr->suppVarNames != NULL) { + /* + * Varnames are sorted for binary search + */ + + sortedvarnames = DDDMP_ALLOC(char *, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (sortedvarnames==NULL, "Error allocating memory.", + failure); + for (i=0; insuppvars; i++) { + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + sortedvarnames[i] = Hdr->suppVarNames[i]; + } + + qsort ((void *) sortedvarnames, Hdr->nsuppvars, + sizeof(char *), QsortStrcmp); + + } + + /* + * Convertids is the array used to convert variable ids from positional + * (shrinked) ids used within the DD file. + * Positions in the file are from 0 to nsuppvars-1. + */ + + convertids = DDDMP_ALLOC (int, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (convertids==NULL, "Error allocating memory.", + failure); + + again_matchmode: + switch (varMatchMode) { + case DDDMP_VAR_MATCHIDS: + for (i=0; insuppvars; i++) { + convertids[permsupport[i]] = Hdr->ids[i]; + } + break; + case DDDMP_VAR_MATCHPERMIDS: + for (i=0; insuppvars; i++) { + convertids[permsupport[i]] = Cudd_ReadInvPerm (ddMgr, + Hdr->permids[i]); + } + break; + case DDDMP_VAR_MATCHAUXIDS: + if (Hdr->auxids == NULL) { + (void) fprintf (stderr, + "DdLoad Error: variable auxids matching requested\n"); + (void) fprintf (stderr, "but .auxids not found in BDD file\n"); + (void) fprintf (stderr, "Matching IDs forced.\n"); + fflush (stderr); + varMatchMode = DDDMP_VAR_MATCHIDS; + goto again_matchmode; + } + /* find max auxid value to alloc invaux array */ + for (i=0,maxaux= -1; imaxaux) { + maxaux = varmatchauxids[i]; + } + } + /* generate invaux array */ + invauxids = DDDMP_ALLOC (int, maxaux+1); + Dddmp_CheckAndGotoLabel (invauxids==NULL, "Error allocating memory.", + failure); + + for (i=0; i<=maxaux; i++) { + invauxids[i] = -1; + } + + for (i=0; insuppvars; i++) { + invauxids[varmatchauxids[Hdr->ids[i]]] = Hdr->ids[i]; + } + + /* generate convertids array */ + for (i=0; insuppvars; i++) { + if ((Hdr->auxids[i]>maxaux) || (invauxids[Hdr->auxids[i]]<0)) { + (void) fprintf (stderr, + "DdLoad Error: auxid %d not found in DD manager.\n", + Hdr->auxids[i]); + (void) fprintf (stderr, "ID matching forced (%d).\n", i); + (void) fprintf (stderr, + "Beware of possible overlappings with other variables\n"); + fflush (stderr); + convertids[permsupport[i]] = i; + } else { + convertids[permsupport[i]] = invauxids[Hdr->auxids[i]]; + } + } + break; + case DDDMP_VAR_MATCHNAMES: + if (Hdr->suppVarNames == NULL) { + (void) fprintf (stderr, + "DdLoad Error: variable names matching requested\n"); + (void) fprintf (stderr, "but .suppvarnames not found in BDD file\n"); + (void) fprintf (stderr, "Matching IDs forced.\n"); + fflush (stderr); + varMatchMode = DDDMP_VAR_MATCHIDS; + goto again_matchmode; + } + + /* generate invaux array */ + invauxids = DDDMP_ALLOC (int, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (invauxids==NULL, "Error allocating memory.", + failure); + + for (i=0; insuppvars; i++) { + invauxids[i] = -1; + } + + for (i=0; insuppvars)) + >=0) { + Dddmp_Assert (jnsuppvars, "jnsuppvars"); + invauxids[j] = i; + } + } + /* generate convertids array */ + for (i=0; insuppvars; i++) { + Dddmp_Assert (Hdr->suppVarNames[i]!=NULL, + "Hdr->suppVarNames[i] != NULL"); + j=FindVarname(Hdr->suppVarNames[i],sortedvarnames,Hdr->nsuppvars); + Dddmp_Assert ((j>=0) && (jnsuppvars), + "(j>=0) && (jnsuppvars)"); + if (invauxids[j]<0) { + fprintf (stderr, + "DdLoad Error: varname %s not found in DD manager.", + Hdr->suppVarNames[i]); + fprintf (stderr, "ID matching forced (%d)\n", i); + fflush (stderr); + convertids[permsupport[i]]=i; + } else { + convertids[permsupport[i]] = invauxids[j]; + } + } + break; + case DDDMP_VAR_COMPOSEIDS: + for (i=0; insuppvars; i++) { + convertids[permsupport[i]] = varcomposeids[Hdr->ids[i]]; + } + break; + } + + maxv = (-1); + for (i=0; insuppvars; i++) { + if (convertids[i] > maxv) { + maxv = convertids[i]; + } + } + + invconvertids = DDDMP_ALLOC (int, maxv+1); + Dddmp_CheckAndGotoLabel (invconvertids==NULL, "Error allocating memory.", + failure); + + for (i=0; i<=maxv; i++) { + invconvertids[i]= -1; + } + + for (i=0; insuppvars; i++) { + invconvertids[convertids[i]] = i; + } + + pnodes = DDDMP_ALLOC(DdNode *,(Hdr->nnodes+1)); + Dddmp_CheckAndGotoLabel (pnodes==NULL, "Error allocating memory.", + failure); + + if (Hdr->nsuppvars < 256) { + pvars1byte = DDDMP_ALLOC(unsigned char,(Hdr->nnodes+1)); + Dddmp_CheckAndGotoLabel (pvars1byte==NULL, "Error allocating memory.", + failure); + } + else if (Hdr->nsuppvars < 0xffff) { + pvars2byte = DDDMP_ALLOC(unsigned short,(Hdr->nnodes+1)); + Dddmp_CheckAndGotoLabel (pvars2byte==NULL, "Error allocating memory.", + failure); + } else { + (void) fprintf (stderr, + "DdLoad Error: more than %d variables. Not supported.\n", 0xffff); + fflush (stderr); + goto failure; + } + + /*-------------- Deal With Nodes ... One Row File at a Time --------------*/ + + for (i=1; i<=Hdr->nnodes; i++) { + + Dddmp_CheckAndGotoLabel (feof(fp), + "Unexpected EOF While Reading DD Nodes.", failure); + + switch (mode) { + + /* + * Text FORMAT + */ + + case DDDMP_MODE_TEXT: + + switch (Hdr->varinfo) { + case DDDMP_VARIDS: + case DDDMP_VARPERMIDS: + case DDDMP_VARAUXIDS: + case DDDMP_VARNAMES: + retValue = fscanf(fp, "%d %*s %s %d %d\n", &id, buf, &idT, &idE); + Dddmp_CheckAndGotoLabel (retValue<4, + "Error Reading Nodes in Text Mode.", failure); + break; + case DDDMP_VARDEFAULT: + retValue = fscanf(fp, "%d %s %d %d\n", &id, buf, &idT, &idE); + Dddmp_CheckAndGotoLabel (retValue<4, + "Error Reading Nodes in Text Mode.", failure); + break; + } +#ifdef DDDMP_DEBUG + Dddmp_Assert (id==i, "id == i"); +#endif + if (idT==0 && idE==0) { + /* leaf node: a constant */ + if (strcmp(buf, "1") == 0) { + pnodes[i] = Cudd_ReadOne (ddMgr); + } else { + /* this is an ADD constant ! */ + if (strcmp(buf, "0") == 0) { + pnodes[i] = Cudd_ReadZero (ddMgr); + } else { + addConstant = atof(buf); + pnodes[i] = Cudd_addConst (ddMgr, + (CUDD_VALUE_TYPE) addConstant); + } + } + + /* StQ 11.02.2004: + Bug fixed --> Reference All Nodes for ADD */ + Cudd_Ref (pnodes[i]); + Dddmp_CheckAndGotoLabel (pnodes[i]==NULL, "NULL pnodes.", + failure); + continue; + } else { +#ifdef DDDMP_DEBUG + Dddmp_Assert (idT>0, "id > 0"); +#endif + var = atoi(buf); + T = pnodes[idT]; + if(idE<0) { + idE = -idE; + E = pnodes[idE]; + E = Cudd_Not(E); + } else { + E = pnodes[idE]; + } + } + + break; + + /* + * Binary FORMAT + */ + + case DDDMP_MODE_BINARY: + + Dddmp_CheckAndGotoLabel (DddmpReadCode(fp,&code) == 0, + "Error Reading witn ReadCode.", failure); + + switch (code.V) { + case DDDMP_TERMINAL: + /* only 1 terminal presently supported */ + pnodes[i] = Cudd_ReadOne (ddMgr); + continue; + break; + case DDDMP_RELATIVE_1: + break; + case DDDMP_RELATIVE_ID: + case DDDMP_ABSOLUTE_ID: + size = DddmpReadInt (fp, &var); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + break; + } + + switch (code.T) { + case DDDMP_TERMINAL: + idT = 1; + break; + case DDDMP_RELATIVE_1: + idT = i-1; + break; + case DDDMP_RELATIVE_ID: + size = DddmpReadInt (fp, &id); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + idT = i-id; + break; + case DDDMP_ABSOLUTE_ID: + size = DddmpReadInt (fp, &idT); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + break; + } + + switch (code.E) { + case DDDMP_TERMINAL: + idE = 1; + break; + case DDDMP_RELATIVE_1: + idE = i-1; + break; + case DDDMP_RELATIVE_ID: + size = DddmpReadInt (fp, &id); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + idE = i-id; + break; + case DDDMP_ABSOLUTE_ID: + size = DddmpReadInt (fp, &idE); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + break; + } + +#ifdef DDDMP_DEBUG + Dddmp_Assert (idTnsuppvars; + else { + if (pvars1byte != NULL) + vT = pvars1byte[idT]; + else if (pvars2byte != NULL) + vT = pvars2byte[idT]; + else + vT = invconvertids[T->index]; + } +#ifdef DDDMP_DEBUG + Dddmp_Assert (vT>0, "vT > 0"); + Dddmp_Assert (vT<=Hdr->nsuppvars, "vT <= Hdr->nsuppvars"); +#endif + +#ifdef DDDMP_DEBUG + Dddmp_Assert (idEnsuppvars; + else { + if (pvars1byte != NULL) + vE = pvars1byte[idE]; + else if (pvars2byte != NULL) + vE = pvars2byte[idE]; + else + vE = invconvertids[E->index]; + } +#ifdef DDDMP_DEBUG + Dddmp_Assert (vE>0, "vE > 0"); + Dddmp_Assert (vE<=Hdr->nsuppvars, "vE <= Hdr->nsuppvars"); +#endif + + switch (code.V) { + case DDDMP_TERMINAL: + case DDDMP_ABSOLUTE_ID: + break; + case DDDMP_RELATIVE_1: + var = (vTnsuppvars, "var < Hdr->nsuppvars"); +#endif + + break; + } + + if (pvars1byte != NULL) { + pvars1byte[i] = (unsigned char) var; + } else { + if (pvars2byte != NULL) { + pvars2byte[i] = (unsigned short) var; + } + } + + var = convertids[var]; + switch (ddType) { + case DDDMP_BDD: + pnodes[i] = Cudd_bddIte (ddMgr, Cudd_bddIthVar (ddMgr, var), + T, E); + break; + case DDDMP_ADD: + { + DdNode *tmp = Cudd_addIthVar (ddMgr, var); + Cudd_Ref (tmp); + pnodes[i] = Cudd_addIte (ddMgr, tmp, T, E); + Cudd_RecursiveDeref (ddMgr, tmp); + break; + } + case DDDMP_CNF: + case DDDMP_NONE: + Dddmp_Warning (1, "Wrong DD Type."); + break; + } + + cuddRef (pnodes[i]); + } + + /*------------------------ Deal With the File Tail -----------------------*/ + + fgets (buf, DDDMP_MAXSTRLEN-1,fp); + Dddmp_CheckAndGotoLabel (!matchkeywd(buf, ".end"), + "Error .end not found.", failure); + + /* Close File IFF Necessary */ + if (fileToClose) { + fclose (fp); + } + + /* BDD Roots */ + proots = DDDMP_ALLOC(DdNode *,nRoots); + Dddmp_CheckAndGotoLabel (proots==NULL, "Error allocating memory.", + failure); + + for(i=0; irootnames[j]) == 0) + break; + } + if (j>=nRoots) { + /* rootname not found */ + fprintf (stderr, "Warning: unable to match root name <%s>\n", + rootmatchnames[i]); + } + break; + case DDDMP_ROOT_MATCHLIST: + j = i; + break; + } + + id = Hdr->rootids[i]; + if (id==0) { + (void) fprintf (stderr, "DdLoad Warning: NULL root found in file\n"); + fflush (stderr); + f = NULL; + } else { + if (id<0) { + f = Cudd_Not(pnodes[-id]); + } else { + f = pnodes[id]; + } + } + proots[i] = f; + + cuddRef (f); + } /* end for i = 0..nRoots */ + + /* + * Decrease Reference for all Nodes + */ + + /* StQ 11.02.2004: + Bug fixed --> De-Reference All Nodes for ADD */ + for (i=1; i<=Hdr->nnodes; i++) { + f = pnodes[i]; + Cudd_RecursiveDeref (ddMgr, f); + } + + /* + * Free Memory: load_end label + */ + +load_end: + + DddmpFreeHeader(Hdr); + + DDDMP_FREE (pnodes); + DDDMP_FREE (pvars1byte); + DDDMP_FREE (pvars2byte); + + /* variable names are not freed because they were shared with varnames */ + DDDMP_FREE (sortedvarnames); + + DDDMP_FREE (permsupport); + DDDMP_FREE (convertids); + DDDMP_FREE (invconvertids); + DDDMP_FREE (invauxids); + + *pproots = proots; + return (nRoots); + + /* + * Failure Condition + */ + +failure: + + if (fileToClose) { + fclose (fp); + } + + nRoots = 0; /* return 0 on error ! */ + + DDDMP_FREE (proots); + + goto load_end; /* this is done to free memory */ +} + +/**Function******************************************************************** + + Synopsis [Reads a the header of a dump file representing the + argument BDDs. + ] + + Description [Reads the header of a dump file. Builds a Dddmp_Hdr_t struct + containing all infos in the header, for next manipulations. + ] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ + +static Dddmp_Hdr_t * +DddmpBddReadHeader ( + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + Dddmp_Hdr_t *Hdr = NULL; + char buf[DDDMP_MAXSTRLEN]; + int retValue, fileToClose = 0; + + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /* START HEADER */ + + Hdr = DDDMP_ALLOC (Dddmp_Hdr_t,1); + if (Hdr == NULL) { + return NULL; + } + Hdr->ver = NULL; + Hdr->mode = 0; + Hdr->ddType = DDDMP_BDD; + Hdr->varinfo = DDDMP_VARIDS; + Hdr->dd = NULL; + Hdr->nnodes = 0; + Hdr->nVars = 0; + Hdr->nsuppvars = 0; + Hdr->suppVarNames = NULL; + Hdr->orderedVarNames = NULL; + Hdr->ids = NULL; + Hdr->permids = NULL; + Hdr->auxids = NULL; + Hdr->cnfids = NULL; + Hdr->nRoots = 0; + Hdr->rootids = NULL; + Hdr->rootnames = NULL; + Hdr->nAddedCnfVar = 0; + Hdr->nVarsCnf = 0; + Hdr->nClausesCnf = 0; + + while (fscanf(fp, "%s", buf)!=EOF) { + + /* comment */ + if (buf[0] == '#') { + fgets(buf,DDDMP_MAXSTRLEN,fp); + continue; + } + + Dddmp_CheckAndGotoLabel (buf[0] != '.', + "Error; line must begin with '.' or '#'.", + failure); + + if (matchkeywd(buf, ".ver")) { + /* this not checked so far: only read */ + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading from file.", + failure); + + Hdr->ver=DddmpStrDup(buf); + Dddmp_CheckAndGotoLabel (Hdr->ver==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".add")) { + Hdr->ddType = DDDMP_ADD; + continue; + } + + if (matchkeywd(buf, ".bdd")) { + Hdr->ddType = DDDMP_BDD; + continue; + } + + if (matchkeywd(buf, ".mode")) { + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading to file.", + failure); + + Hdr->mode = buf[0]; + continue; + } + + if (matchkeywd(buf, ".varinfo")) { + int readMe; + retValue = fscanf (fp, "%d", &readMe); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + Hdr->varinfo = (Dddmp_VarInfoType) readMe; + + continue; + } + + if (matchkeywd(buf, ".dd")) { + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + Hdr->dd = DddmpStrDup (buf); + Dddmp_CheckAndGotoLabel (Hdr->dd==NULL, "Error allocating memory.", + failure); + + continue; + } + + if (matchkeywd(buf, ".nnodes")) { + retValue = fscanf (fp, "%d", &(Hdr->nnodes)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd(buf, ".nvars")) { + retValue = fscanf (fp, "%d", &(Hdr->nVars)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd(buf, ".nsuppvars")) { + retValue = fscanf (fp, "%d", &(Hdr->nsuppvars)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd(buf, ".orderedvarnames")) { + Hdr->orderedVarNames = DddmpStrArrayRead (fp, Hdr->nVars); + Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".suppvarnames") || + ((strcmp (Hdr->ver, "DDDMP-1.0") == 0) && + matchkeywd (buf, ".varnames"))) { + Hdr->suppVarNames = DddmpStrArrayRead (fp, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if matchkeywd(buf, ".ids") { + Hdr->ids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->ids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".permids")) { + Hdr->permids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->permids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".auxids")) { + Hdr->auxids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->auxids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".nroots")) { + retValue = fscanf (fp, "%d", &(Hdr->nRoots)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd(buf, ".rootids")) { + Hdr->rootids = DddmpIntArrayRead(fp,Hdr->nRoots); + Dddmp_CheckAndGotoLabel (Hdr->rootids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".rootnames")) { + Hdr->rootnames = DddmpStrArrayRead(fp,Hdr->nRoots); + Dddmp_CheckAndGotoLabel (Hdr->rootnames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".nodes")) { + fgets(buf,DDDMP_MAXSTRLEN,fp); + break; + } + + } + + /* END HEADER */ + + return (Hdr); + +failure: + + if (fileToClose == 1) { + fclose (fp); + } + + DddmpFreeHeader(Hdr); + + return (NULL); +} + + +/**Function******************************************************************** + + Synopsis [Frees the internal header structure.] + + Description [Frees the internal header structureby freeing all internal + fields first. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +DddmpFreeHeader ( + Dddmp_Hdr_t *Hdr /* IN: pointer to header */ + ) +{ + DDDMP_FREE (Hdr->ver); + DDDMP_FREE (Hdr->dd); + DddmpStrArrayFree (Hdr->orderedVarNames, Hdr->nVars); + DddmpStrArrayFree (Hdr->suppVarNames, Hdr->nsuppvars); + DDDMP_FREE (Hdr->ids); + DDDMP_FREE (Hdr->permids); + DDDMP_FREE (Hdr->auxids); + DDDMP_FREE (Hdr->rootids); + DddmpStrArrayFree (Hdr->rootnames, Hdr->nRoots); + + DDDMP_FREE (Hdr); + + return; +} + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoadCnf.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoadCnf.c new file mode 100644 index 000000000..35bec273b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpLoadCnf.c @@ -0,0 +1,1072 @@ +/**CFile********************************************************************** + + FileName [dddmpLoadCnf.c] + + PackageName [dddmp] + + Synopsis [Functions to read in CNF from file as BDDs.] + + Description [Functions to read in CNF from file as BDDs. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMP_MAX_CNF_ROW_LENGTH 1000 +#define DDDMP_DEBUG_CNF 0 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define matchkeywd(str,key) (strncmp(str,key,strlen(key))==0) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpCuddDdArrayLoadCnf(DdManager *ddMgr, Dddmp_RootMatchType rootmatchmode, char **rootmatchnames, Dddmp_VarMatchType varmatchmode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***rootsPtrPtr, int *nRoots); +static Dddmp_Hdr_t * DddmpBddReadHeaderCnf(char *file, FILE *fp); +static void DddmpFreeHeaderCnf(Dddmp_Hdr_t *Hdr); +static int DddmpReadCnfClauses(Dddmp_Hdr_t *Hdr, int ***cnfTable, FILE *fp); +static int DddmpCnfClauses2Bdd(Dddmp_Hdr_t *Hdr, DdManager *ddMgr, int **cnfTable, int mode, DdNode ***rootsPtrPtr); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads a dump file in a CNF format.] + + Description [Reads a dump file representing the argument BDD in a + CNF formula. + Dddmp_cuddBddArrayLoadCnf is used through a dummy array. + The results is returned in different formats depending on the + mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddLoad, Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddBddLoadCnf ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_VarMatchType varmatchmode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by IDs */, + int *varmatchauxids /* IN: array of variable auxids, by IDs */, + int *varcomposeids /* IN: array of new ids accessed, by IDs */, + int mode /* IN: computation mode */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots */, + int *nRoots /* OUT: number of BDDs returned */ + ) +{ + int i, retValue; + + retValue = Dddmp_cuddBddArrayLoadCnf (ddMgr, DDDMP_ROOT_MATCHLIST, NULL, + varmatchmode, varmatchnames, varmatchauxids, varcomposeids, mode, + file, fp, rootsPtrPtr, nRoots); + + if (retValue == DDDMP_FAILURE) { + return (DDDMP_FAILURE); + } + + if (*nRoots > 1) { + fprintf (stderr, + "Warning: %d BDD roots found in file. Only first retrieved.\n", + *nRoots); + for (i=1; i<*nRoots; i++) { + Cudd_RecursiveDeref (ddMgr, *rootsPtrPtr[i]); + } + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Reads a dump file in a CNF format.] + + Description [Reads a dump file representing the argument BDD in a + CNF formula. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayLoadCnf ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_RootMatchType rootmatchmode/* IN: storing mode selector */, + char **rootmatchnames /* IN: sorted names for loaded roots */, + Dddmp_VarMatchType varmatchmode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by IDs */, + int *varmatchauxids /* IN: array of variable auxids, by IDs */, + int *varcomposeids /* IN: array of new ids, by IDs */, + int mode /* IN: computation Mode */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots */, + int *nRoots /* OUT: number of BDDs returned */ + ) +{ + int retValue; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During CNF Load.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During CNF Load.\n"); + fflush (stderr); + } + } +#endif +#endif + + retValue = DddmpCuddDdArrayLoadCnf (ddMgr, rootmatchmode, + rootmatchnames, varmatchmode, varmatchnames, varmatchauxids, + varcomposeids, mode, file, fp, rootsPtrPtr, nRoots); + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During CNF Load.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During CNF Load.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Reads the header of a dump file representing the argument BDDs] + + Description [Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddHeaderLoadCnf ( + int *nVars /* OUT: number of DD variables */, + int *nsuppvars /* OUT: number of support variables */, + char ***suppVarNames /* OUT: array of support variable names */, + char ***orderedVarNames /* OUT: array of variable names */, + int **varIds /* OUT: array of variable ids */, + int **varComposeIds /* OUT: array of permids ids */, + int **varAuxIds /* OUT: array of variable aux ids */, + int *nRoots /* OUT: number of root in the file */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + Dddmp_Hdr_t *Hdr; + int i, fileToClose; + char **tmpOrderedVarNames = NULL; + char **tmpSuppVarNames = NULL; + int *tmpVarIds = NULL; + int *tmpVarComposeIds = NULL; + int *tmpVarAuxIds = NULL; + + fileToClose = 0; + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + Hdr = DddmpBddReadHeaderCnf (NULL, fp); + + Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.", + failure); + + /* + * Number of variables (tot and support) + */ + + *nVars = Hdr->nVars; + *nsuppvars = Hdr->nsuppvars; + + /* + * Support Varnames + */ + + if (Hdr->suppVarNames != NULL) { + tmpSuppVarNames = DDDMP_ALLOC (char *, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpSuppVarNames==NULL, "Error allocating memory.", + failure); + + for (i=0; i<*nsuppvars; i++) { + tmpSuppVarNames[i] = DDDMP_ALLOC (char, + (strlen (Hdr->suppVarNames[i]) + 1)); + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + strcpy (tmpSuppVarNames[i], Hdr->suppVarNames[i]); + } + + *suppVarNames = tmpSuppVarNames; + } else { + *suppVarNames = NULL; + } + + /* + * Ordered Varnames + */ + + if (Hdr->orderedVarNames != NULL) { + tmpOrderedVarNames = DDDMP_ALLOC (char *, *nVars); + Dddmp_CheckAndGotoLabel (tmpOrderedVarNames==NULL, + "Error allocating memory.", failure); + + for (i=0; i<*nVars; i++) { + tmpOrderedVarNames[i] = DDDMP_ALLOC (char, + (strlen (Hdr->orderedVarNames[i]) + 1)); + Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + strcpy (tmpOrderedVarNames[i], Hdr->orderedVarNames[i]); + } + + *orderedVarNames = tmpOrderedVarNames; + } else { + *orderedVarNames = NULL; + } + + /* + * Variable Ids + */ + + if (Hdr->ids != NULL) { + tmpVarIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarIds==NULL, "Error allocating memory.", + failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarIds[i] = Hdr->ids[i]; + } + + *varIds = tmpVarIds; + } else { + *varIds = NULL; + } + + /* + * Variable Compose Ids + */ + + if (Hdr->permids != NULL) { + tmpVarComposeIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarComposeIds==NULL, + "Error allocating memory.", failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarComposeIds[i] = Hdr->permids[i]; + } + + *varComposeIds = tmpVarComposeIds; + } else { + *varComposeIds = NULL; + } + + /* + * Variable Auxiliary Ids + */ + + if (Hdr->auxids != NULL) { + tmpVarAuxIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarAuxIds==NULL, + "Error allocating memory.", failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarAuxIds[i] = Hdr->auxids[i]; + } + + *varAuxIds = tmpVarAuxIds; + } else { + *varAuxIds = NULL; + } + + /* + * Number of roots + */ + + *nRoots = Hdr->nRoots; + + /* + * Free and Return + */ + + if (fileToClose == 1) { + fclose (fp); + } + + DddmpFreeHeaderCnf (Hdr); + + return (DDDMP_SUCCESS); + + failure: + return (DDDMP_FAILURE); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads a dump file representing the argument BDDs in CNF + format. + ] + + Description [Reads a dump file representing the argument BDDs in CNF + format. + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +static int +DddmpCuddDdArrayLoadCnf ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_RootMatchType rootmatchmode/* IN: storing mode selector */, + char **rootmatchnames /* IN: sorted names for loaded roots */, + Dddmp_VarMatchType varmatchmode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by ids */, + int *varmatchauxids /* IN: array of variable auxids, by ids */, + int *varcomposeids /* IN: array of new ids, by ids */, + int mode /* IN: computation mode */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***rootsPtrPtr /* OUT: array of BDD roots */, + int *nRoots /* OUT: number of BDDs returned */ + ) +{ + Dddmp_Hdr_t *Hdr = NULL; + int **cnfTable = NULL; + int fileToClose = 0; + int retValue, i; + + fileToClose = 0; + *rootsPtrPtr = NULL; + + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /*--------------------------- Read the Header -----------------------------*/ + + Hdr = DddmpBddReadHeaderCnf (NULL, fp); + + Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.", + failure); + + /*------------------------ Read the CNF Clauses ---------------------------*/ + + retValue = DddmpReadCnfClauses (Hdr, &cnfTable, fp); + + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "Read CNF Clauses Failure.", failure); + + /*------------------------- From Clauses to BDDs --------------------------*/ + + retValue = DddmpCnfClauses2Bdd (Hdr, ddMgr, cnfTable, mode, rootsPtrPtr); + + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "CNF Clauses To BDDs Failure.", failure); + + *nRoots = Hdr->nRoots; + + if (fileToClose) { + fclose (fp); + } + + for (i=0; inClausesCnf; i++) { + DDDMP_FREE (cnfTable[i]); + } + DDDMP_FREE (cnfTable); + + DddmpFreeHeaderCnf (Hdr); + + return (DDDMP_SUCCESS); + + /* + * Failure Condition + */ + +failure: + + if (fileToClose) { + fclose (fp); + } + + for (i=0; inClausesCnf; i++) { + DDDMP_FREE (cnfTable[i]); + } + DDDMP_FREE (cnfTable); + + DddmpFreeHeaderCnf (Hdr); + + /* return 0 on error ! */ + nRoots = 0; + + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Reads a the header of a dump file representing the argument + BDDs. + ] + + Description [Reads the header of a dump file. Builds a Dddmp_Hdr_t struct + containing all infos in the header, for next manipulations. + ] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ + +static Dddmp_Hdr_t * +DddmpBddReadHeaderCnf ( + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + Dddmp_Hdr_t *Hdr = NULL; + char buf[DDDMP_MAXSTRLEN]; + int nv, nc, retValue, fileToClose = 0; + + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /* Start Header */ + Hdr = DDDMP_ALLOC (Dddmp_Hdr_t, 1); + if (Hdr == NULL) { + return NULL; + } + + Hdr->ver = NULL; + Hdr->mode = 0; + Hdr->ddType = DDDMP_CNF; + Hdr->varinfo = DDDMP_VARIDS; + Hdr->dd = NULL; + Hdr->nnodes = 0; + Hdr->nVars = 0; + Hdr->nsuppvars = 0; + Hdr->orderedVarNames = NULL; + Hdr->suppVarNames = NULL; + Hdr->ids = NULL; + Hdr->permids = NULL; + Hdr->auxids = NULL; + Hdr->cnfids = NULL; + Hdr->nRoots = 0; + Hdr->rootids = NULL; + Hdr->rootnames = NULL; + Hdr->nAddedCnfVar = 0; + Hdr->nVarsCnf = 0; + Hdr->nClausesCnf = 0; + + while (fscanf (fp, "%s", buf) != EOF) { + + /* Init Problem Line */ + if (buf[0] == 'p') { + fscanf (fp, "%*s %d %d", &nv, &nc); + Hdr->nVarsCnf = nv; + Hdr->nClausesCnf = nc; + break; + } + + /* CNF Comment Line */ + if (buf[0] == 'c') { + if (fscanf (fp, "%s", buf) == EOF) { + break; + } + } + + /* Skip Comment? */ + if (buf[0] != '.') { + fgets (buf, DDDMP_MAXSTRLEN, fp); + continue; + } + + if (matchkeywd (buf, ".ver")) { + /* this not checked so far: only read */ + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading from file.", + failure); + + Hdr->ver=DddmpStrDup(buf); + Dddmp_CheckAndGotoLabel (Hdr->ver==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".dd")) { + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + Hdr->dd = DddmpStrDup (buf); + Dddmp_CheckAndGotoLabel (Hdr->dd==NULL, "Error allocating memory.", + failure); + + continue; + } + + if (matchkeywd (buf, ".nnodes")) { + retValue = fscanf (fp, "%d", &(Hdr->nnodes)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd (buf, ".nvars")) { + retValue = fscanf (fp, "%d", &(Hdr->nVars)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd (buf, ".nsuppvars")) { + retValue = fscanf (fp, "%d", &(Hdr->nsuppvars)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd (buf, ".orderedvarnames")) { + Hdr->orderedVarNames = DddmpStrArrayRead (fp, Hdr->nVars); + Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".suppvarnames")) { + Hdr->suppVarNames = DddmpStrArrayRead (fp, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if matchkeywd (buf, ".ids") { + Hdr->ids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->ids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".permids")) { + Hdr->permids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->permids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".auxids")) { + Hdr->auxids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->auxids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".cnfids")) { + Hdr->cnfids = DddmpIntArrayRead (fp, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->cnfids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".nroots")) { + retValue = fscanf (fp, "%d", &(Hdr->nRoots)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd (buf, ".rootids")) { + Hdr->rootids = DddmpIntArrayRead(fp,Hdr->nRoots); + Dddmp_CheckAndGotoLabel (Hdr->rootids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".rootnames")) { + Hdr->rootnames = DddmpStrArrayRead(fp,Hdr->nRoots); + Dddmp_CheckAndGotoLabel (Hdr->rootnames==NULL, + "Error allocating memory.", failure); + + continue; + } + + + if (matchkeywd (buf, ".nAddedCnfVar")) { + retValue = fscanf (fp, "%d", &(Hdr->nAddedCnfVar)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + } + + /* END HEADER */ + return (Hdr); + +failure: + + if (fileToClose == 1) { + fclose (fp); + } + + DddmpFreeHeaderCnf (Hdr); + + return (NULL); +} + + +/**Function******************************************************************** + + Synopsis [Frees the internal header structure.] + + Description [Frees the internal header structure by freeing all internal + fields first. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +DddmpFreeHeaderCnf ( + Dddmp_Hdr_t *Hdr /* IN: pointer to header */ + ) +{ + if (Hdr==NULL) { + return; + } + + DDDMP_FREE (Hdr->ver); + DDDMP_FREE (Hdr->dd); + DddmpStrArrayFree (Hdr->orderedVarNames, Hdr->nVars); + DddmpStrArrayFree (Hdr->suppVarNames, Hdr->nsuppvars); + DDDMP_FREE (Hdr->ids); + DDDMP_FREE (Hdr->permids); + DDDMP_FREE (Hdr->auxids); + DDDMP_FREE (Hdr->cnfids); + DDDMP_FREE (Hdr->rootids); + DddmpStrArrayFree (Hdr->rootnames, Hdr->nRoots); + + DDDMP_FREE (Hdr); + + return; +} + +/**Function******************************************************************** + + Synopsis [Read the CNF clauses from the file in the standard DIMACS + format. + ] + + Description [Read the CNF clauses from the file in the standard DIMACS + format. Store all the clauses in an internal structure for + future transformation into BDDs. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpReadCnfClauses ( + Dddmp_Hdr_t *Hdr /* IN: file header */, + int ***cnfTable /* OUT: CNF table for clauses */, + FILE *fp /* IN: source file */ + ) +{ + char word[DDDMP_MAX_CNF_ROW_LENGTH]; + int i, j, var; + int **cnfTableLocal = NULL; + int *clause = NULL; + + cnfTableLocal = DDDMP_ALLOC (int *, Hdr->nClausesCnf); + clause = DDDMP_ALLOC (int, 2*Hdr->nVarsCnf+1); + + for (i=0; inClausesCnf; i++) { + cnfTableLocal[i] = NULL; + } + + for (i=0; i<=2*Hdr->nVarsCnf; i++) { + clause[i] = 0; + } + + i = j = 0; + do { + if (fscanf(fp, "%s", word)==EOF) { + if (j>0) { + /* force last zero */ + strcpy(word,"0"); + } + else break; + } + + /* Check for Comment */ + if (word[0] == 'c') { + /* Comment Found: Skip line */ + fgets (word, DDDMP_MAX_CNF_ROW_LENGTH-1, fp); + break; + } + + var = atoi (word); + Dddmp_Assert ((var>=(-Hdr->nVarsCnf))&&(var<=Hdr->nVarsCnf), + "Wrong num found"); + clause[j++] = var; + if (var == 0) { + cnfTableLocal[i] = DDDMP_ALLOC (int, j); + while (--j >=0) { + cnfTableLocal[i][j] = clause[j]; + } + i++; + j=0; + } + + } while (!feof(fp)); + + Dddmp_Assert (i==Hdr->nClausesCnf, + "Wrong number of clauses in file"); + +#if DDDMP_DEBUG_CNF + for (i=0; inClausesCnf; i++) { + fprintf (stdout, "[%4d] ", i); + j=0; + while ((var = cnfTableLocal[i][j++]) != 0) { + fprintf (stdout, "%d ", var); + } + fprintf (stdout, "0\n"); + } +#endif + + DDDMP_FREE (clause); + + *cnfTable = cnfTableLocal; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Transforms CNF clauses into BDDs.] + + Description [Transforms CNF clauses into BDDs. Clauses are stored in an + internal structure previously read. The results can be given in + different format according to the mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpCnfClauses2Bdd ( + Dddmp_Hdr_t *Hdr /* IN: file header */, + DdManager *ddMgr /* IN: DD Manager */, + int **cnfTable /* IN: CNF table for clauses */, + int mode /* IN: computation mode */, + DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots (by reference) */ + ) +{ + DdNode **rel = NULL; + DdNode *lit = NULL; + DdNode *tmp1 = NULL; + DdNode *tmp2 = NULL; + DdNode **rootsPtr = NULL; + DdNode *cubeAllVar = NULL; + DdNode *cubeBddVar = NULL; + DdNode *cubeCnfVar = NULL; + int i, j, k, n, var1, var2, fromLine, toLine; + + rootsPtr = NULL; + *rootsPtrPtr = NULL; + + /*-------------------------- Read The Clauses -----------------------------*/ + + rel = DDDMP_ALLOC (DdNode *, Hdr->nClausesCnf); + + cubeBddVar = Cudd_ReadOne (ddMgr); + cubeCnfVar = Cudd_ReadOne (ddMgr); + cubeAllVar = Cudd_ReadOne (ddMgr); + Cudd_Ref (cubeBddVar); + Cudd_Ref (cubeCnfVar); + Cudd_Ref (cubeAllVar); + + for (i=0; inClausesCnf; i++) { + rel[i] = Cudd_Not (Cudd_ReadOne (ddMgr)); + Cudd_Ref (rel[i]); + j=0; + while ((var1 = cnfTable[i][j++]) != 0) { + + /* Deal with the Literal */ + var2 = abs (var1); + n = (-1); + for (k=0; knsuppvars; k++) { + if (Hdr->cnfids[k] == var2) { + n = k; + break; + } + } + + if (n == (-1)) { + lit = Cudd_bddIthVar (ddMgr, var2); + + /* Create the cubes of CNF Variables */ + tmp1 = Cudd_bddAnd (ddMgr, cubeCnfVar, lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, cubeCnfVar); + cubeCnfVar = tmp1; + + } else { + lit = Cudd_bddIthVar (ddMgr, Hdr->ids[n]); + + /* Create the cubes of BDD Variables */ + tmp1 = Cudd_bddAnd (ddMgr, cubeBddVar, lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, cubeBddVar); + cubeBddVar = tmp1; + } + + /* Create the cubes of ALL Variables */ + tmp1 = Cudd_bddAnd (ddMgr, cubeAllVar, lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, cubeAllVar); + cubeAllVar = tmp1; + + /* Deal with Relations */ + if (var1<0) { + lit = Cudd_Not (lit); + } + tmp1 = Cudd_bddOr (ddMgr, rel[i], lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, rel[i]); + rel[i] = tmp1; + } + } + + /* + * Mode == 0 Return the Clauses without Conjunction + */ + + if (mode == 0) { + return (DDDMP_SUCCESS); + } + + rootsPtr = DDDMP_ALLOC (DdNode *, Hdr->nRoots); + Dddmp_CheckAndGotoLabel (rootsPtr==NULL, "Error allocating memory.", + failure); + + for (i=0; inRoots; i++) { + if (i == (Hdr->nRoots-1)) { + fromLine = Hdr->rootids[i] - 1; + toLine = Hdr->nClausesCnf; + } else { + fromLine = Hdr->rootids[i] - 1; + toLine = Hdr->rootids[i+1]; + } + + tmp1 = Cudd_ReadOne (ddMgr); + Cudd_Ref (tmp1); + for (j=fromLine; jnsuppvars; i++) { + lit = Cudd_bddIthVar (ddMgr, Hdr->ids[i]); + tmp1 = Cudd_bddAnd (ddMgr, cubeBddVar, lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, cubeBddVar); + cubeBddVar = tmp1; + } + + cubeCnfVar = Cudd_bddExistAbstract (ddMgr, cubeAllVar, cubeBddVar); +#endif + + for (i=0; inRoots; i++) { +#if DDDMP_DEBUG_CNF + fprintf (stdout, "rootsPtr Before Exist:\n"); + Cudd_PrintDebug (ddMgr, rootsPtr[i], 0, 3); +#endif + + tmp1 = Cudd_bddExistAbstract (ddMgr, rootsPtr[i], cubeCnfVar); + Cudd_RecursiveDeref (ddMgr, rootsPtr[i]); + rootsPtr[i] = tmp1; + +#if DDDMP_DEBUG_CNF + fprintf (stdout, "rootsPtr After Exist:\n"); + Cudd_PrintDebug (ddMgr, rootsPtr[i], 0, 3); +#endif + } + +#if DDDMP_DEBUG_CNF + fprintf (stdout, "cubeAllVar:\n"); + Cudd_PrintDebug (ddMgr, cubeAllVar, 0, 3); + fprintf (stdout, "cubeBddVar:\n"); + Cudd_PrintDebug (ddMgr, cubeBddVar, 0, 3); + fprintf (stdout, "cubeCnfVar:\n"); + Cudd_PrintDebug (ddMgr, cubeCnfVar, 0, 3); +#endif + + Cudd_RecursiveDeref (ddMgr, cubeAllVar); + Cudd_RecursiveDeref (ddMgr, cubeBddVar); + Cudd_RecursiveDeref (ddMgr, cubeCnfVar); + *rootsPtrPtr = rootsPtr; + + return (DDDMP_SUCCESS); + + /* + * Failure Condition + */ + +failure: + + DDDMP_FREE (rel); + DDDMP_FREE (rootsPtrPtr); + + return (DDDMP_FAILURE); +} + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeAdd.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeAdd.c new file mode 100644 index 000000000..6fca772f1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeAdd.c @@ -0,0 +1,451 @@ +/**CFile********************************************************************** + + FileName [dddmpNodeAdd.c] + + PackageName [dddmp] + + Synopsis [Functions to handle ADD node infos and numbering] + + Description [Functions to handle ADD node infos and numbering. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NumberNodeRecurAdd(DdNode *f, int id); +static void RemoveFromUniqueRecurAdd(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecurAdd(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and number them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodes()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecurAdd (), NumberNodeRecurAdd (), + DddmpUnnumberDdNodesAdd ()] + +******************************************************************************/ + +int +DddmpNumberAddNodes ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int n /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int id=0, i; + + for (i=0; inext = (struct DdNode *)((ptruint)((id)<<1)); + } + + return; +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndexAdd (), DddmpSetVisitedAdd (), + DddmpVisitedAdd ()] + +******************************************************************************/ + +int +DddmpReadNodeIndexAdd ( + DdNode *f /* IN: BDD node */ + ) +{ + if (1 || !Cudd_IsConstant (f)) { + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisitedAdd (), DddmpClearVisitedAdd ()] + +******************************************************************************/ + +int +DddmpVisitedAdd ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedAdd (), DddmpClearVisitedAdd ()] + +******************************************************************************/ + +void +DddmpSetVisitedAdd ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedAdd (), DddmpSetVisitedAdd ()] + +******************************************************************************/ + +void +DddmpClearVisitedAdd ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecurAdd ( + DdNode *f /* IN: root of the BDD to be numbered */, + int id /* IN/OUT: index to be assigned to the node */ + ) +{ + f = Cudd_Regular(f); + + if (!DddmpVisitedAdd (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecurAdd (cuddT (f), id); + id = NumberNodeRecurAdd (cuddE (f), id); + } + + DddmpWriteNodeIndexAdd (f, ++id); + DddmpClearVisitedAdd (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. Constants remain untouched. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecurAdd ()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecurAdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisitedAdd (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecurAdd (ddMgr, cuddT (f)); + RemoveFromUniqueRecurAdd (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisitedAdd (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursively)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUniqueAdd ()] + +******************************************************************************/ + +static void +RestoreInUniqueRecurAdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + /* StQ 11.02.2004: + Bug fixed --> restore NULL within the next field */ + /*DddmpClearVisitedAdd (f);*/ + f->next = NULL; + + return; + } + + RestoreInUniqueRecurAdd (ddMgr, cuddT (f)); + RestoreInUniqueRecurAdd (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + f->next = *previousP; + *previousP = f; + + return; +} + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeBdd.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeBdd.c new file mode 100644 index 000000000..17f7fe39a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeBdd.c @@ -0,0 +1,452 @@ +/**CFile********************************************************************** + + FileName [dddmpNodeBdd.c] + + PackageName [dddmp] + + Synopsis [Functions to handle BDD node infos and numbering] + + Description [Functions to handle BDD node infos and numbering. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NumberNodeRecurBdd(DdNode *f, int id); +static void RemoveFromUniqueRecurBdd(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecurBdd(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and number them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberBddNodes ()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecur(), NumberNodeRecur(), + DddmpUnnumberBddNodes ()] + +******************************************************************************/ + +int +DddmpNumberBddNodes ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int n /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int id=0, i; + + for (i=0; inext = (struct DdNode *)((ptruint)((id)<<1)); + } + + return; +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndexBdd (), DddmpSetVisitedBdd (), + DddmpVisitedBdd ()] + +******************************************************************************/ + +int +DddmpReadNodeIndexBdd ( + DdNode *f /* IN: BDD node */ + ) +{ + if (!Cudd_IsConstant (f)) { + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisitedBdd (), DddmpClearVisitedBdd ()] + +******************************************************************************/ + +int +DddmpVisitedBdd ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedBdd (), DddmpClearVisitedBdd ()] + +******************************************************************************/ + +void +DddmpSetVisitedBdd ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisited (), DddmpSetVisited ()] + +******************************************************************************/ + +void +DddmpClearVisitedBdd ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecurBdd ( + DdNode *f /* IN: root of the BDD to be numbered */, + int id /* IN/OUT: index to be assigned to the node */ + ) +{ + f = Cudd_Regular (f); + + if (!DddmpVisitedBdd (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecurBdd (cuddT (f), id); + id = NumberNodeRecurBdd (cuddE (f), id); + } + + DddmpWriteNodeIndexBdd (f, ++id); + DddmpClearVisitedBdd (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. Constants remain untouched. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecurBdd ()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecurBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisitedBdd (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecurBdd (ddMgr, cuddT (f)); + RemoveFromUniqueRecurBdd (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisitedBdd (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursively)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUnique()] + +******************************************************************************/ + +static void +RestoreInUniqueRecurBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + /* StQ 11.02.2004: + Bug fixed --> restore NULL within the next field */ + /*DddmpClearVisitedBdd (f);*/ + f->next = NULL; + + return; + } + + RestoreInUniqueRecurBdd (ddMgr, cuddT (f)); + RestoreInUniqueRecurBdd (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + f->next = *previousP; + *previousP = f; + + return; +} + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeCnf.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeCnf.c new file mode 100644 index 000000000..fa61ace69 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpNodeCnf.c @@ -0,0 +1,932 @@ +/**CFile********************************************************************** + + FileName [dddmpNodeCnf.c] + + PackageName [dddmp] + + Synopsis [Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs] + + Description [Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMP_DEBUG_CNF 0 + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpWriteNodeIndexCnfWithTerminalCheck(DdNode *f, int *cnfIds, int id); +static int DddmpClearVisitedCnfRecur(DdNode *f); +static void DddmpClearVisitedCnf(DdNode *f); +static int NumberNodeRecurCnf(DdNode *f, int *cnfIds, int id); +static void DddmpDdNodesCheckIncomingAndScanPath(DdNode *f, int pathLengthCurrent, int edgeInTh, int pathLengthTh); +static int DddmpDdNodesNumberEdgesRecur(DdNode *f, int *cnfIds, int id); +static int DddmpDdNodesResetCountRecur(DdNode *f); +static int DddmpDdNodesCountEdgesRecur(DdNode *f); +static void RemoveFromUniqueRecurCnf(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecurCnf(DdManager *ddMgr, DdNode *f); +static int DddmpPrintBddAndNextRecur(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and numbers them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodesCnf()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecurCnf(), NumberNodeRecurCnf(), + DddmpUnnumberDdNodesCnf()] + +******************************************************************************/ + +int +DddmpNumberDdNodesCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int rootN /* IN: number of BDD roots in the array of BDDs */, + int *cnfIds /* OUT: CNF identifiers for variables */, + int id /* OUT: number of Temporary Variables Introduced */ + ) +{ + int i; + + for (i=0; i BDDs After Count Reset:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*----------------------- Count Incoming Edges ----------------------------*/ + + for (i=0; i BDDs After Count Recur:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*------------------------- Count Path Length ----------------------------*/ + + for (i=0; i BDDs After Check Incoming And Scan Path:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*-------------------- Number Nodes and Set Visited -----------------------*/ + + for (i=0; i BDDs After Count Edges Recur:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Restores nodes in unique table, loosing numbering] + + Description [Node indexes are no more needed. Nodes are re-linked in the + unique table. + ] + + SideEffects [None] + + SeeAlso [DddmpNumberDdNode()] + +******************************************************************************/ + +void +DddmpUnnumberDdNodesCnf( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int rootN /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int i; + + for (i=0; i Bdd %d:\n", i); + fflush (stdout); + DddmpPrintBddAndNextRecur (ddMgr, f[i]); + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Write index to node] + + Description [The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. + ] + + SideEffects [None] + + SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf () + ] + +******************************************************************************/ + +int +DddmpWriteNodeIndexCnf ( + DdNode *f /* IN: BDD node */, + int id /* IN: index to be written */ + ) +{ + if (!Cudd_IsConstant (f)) { + f->next = (struct DdNode *)((ptruint)((id)<<1)); + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisitedCnf (), DddmpClearVisitedCnf ()] + +******************************************************************************/ + +int +DddmpVisitedCnf ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpClearVisitedCnf ()] + +******************************************************************************/ + +void +DddmpSetVisitedCnf ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf ()] + +******************************************************************************/ + +int +DddmpReadNodeIndexCnf ( + DdNode *f /* IN: BDD node */ + ) +{ + if (!Cudd_IsConstant (f)) { + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Write index to node] + + Description [The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. The index corresponds to + the BDD node variable if both the node's children are a + constant node, otherwise a new CNF variable is used. + ] + + SideEffects [None] + + SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf ()] + +*****************************************************************************/ + +static int +DddmpWriteNodeIndexCnfWithTerminalCheck ( + DdNode *f /* IN: BDD node */, + int *cnfIds /* IN: possible source for the index to be written */, + int id /* IN: possible source for the index to be written */ + ) +{ + if (!Cudd_IsConstant (f)) { + if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) { + /* If Variable SET ID as Variable ID */ + f->next = (struct DdNode *)((ptruint)((cnfIds[f->index])<<1)); + } else { + f->next = (struct DdNode *)((ptruint)((id)<<1)); + id++; + } + } + + return(id); +} + +/**Function******************************************************************** + + Synopsis [Mark ALL nodes as not visited] + + Description [Mark ALL nodes as not visited (it recurs on the node children)] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()] + +******************************************************************************/ + +static int +DddmpClearVisitedCnfRecur ( + DdNode *f /* IN: root of the BDD to be marked */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (cuddIsConstant (f)) { + return (DDDMP_SUCCESS); + } + + if (!DddmpVisitedCnf (f)) { + return (DDDMP_SUCCESS); + } + + retValue = DddmpClearVisitedCnfRecur (cuddT (f)); + retValue = DddmpClearVisitedCnfRecur (cuddE (f)); + + DddmpClearVisitedCnf (f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()] + +******************************************************************************/ + +static void +DddmpClearVisitedCnf ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecurCnf( + DdNode *f /* IN: root of the BDD to be numbered */, + int *cnfIds /* IN: possible source for numbering */, + int id /* IN/OUT: possible source for numbering */ + ) +{ + f = Cudd_Regular(f); + + if (!DddmpVisitedCnf (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecurCnf (cuddT (f), cnfIds, id); + id = NumberNodeRecurCnf (cuddE (f), cnfIds, id); + } + + id = DddmpWriteNodeIndexCnfWithTerminalCheck (f, cnfIds, id); + DddmpClearVisitedCnf (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with the right polarity. + The node is assigned to a new CNF variable only if it is a "shared" + node (i.e. the number of its incoming edges is greater than 1). + ] + + SideEffects ["visited" flags are set.] + + SeeAlso [] + +******************************************************************************/ + +static void +DddmpDdNodesCheckIncomingAndScanPath ( + DdNode *f /* IN: BDD node to be numbered */, + int pathLengthCurrent /* IN: Current Path Length */, + int edgeInTh /* IN: Max # In-Edges, after a Insert Cut Point */, + int pathLengthTh /* IN: Max Path Length (after, Insert a Cut Point) */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (DddmpVisitedCnf (f)) { + return; + } + + if (cuddIsConstant (f)) { + return; + } + + pathLengthCurrent++; + retValue = DddmpReadNodeIndexCnf (f); + + if ( ((edgeInTh >= 0) && (retValue > edgeInTh)) || + ((pathLengthTh >= 0) && (pathLengthCurrent > pathLengthTh)) + ) { + DddmpWriteNodeIndexCnf (f, 1); + pathLengthCurrent = 0; + } else { + DddmpWriteNodeIndexCnf (f, 0); + } + + DddmpDdNodesCheckIncomingAndScanPath (cuddT (f), pathLengthCurrent, + edgeInTh, pathLengthTh); + DddmpDdNodesCheckIncomingAndScanPath (cuddE (f), pathLengthCurrent, + edgeInTh, pathLengthTh); + + DddmpSetVisitedCnf (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with the inverse polarity. + Numbering follows the subsequent strategy: + * if the index = 0 it remains so + * if the index >= 1 it gets enumerated. + This implies that the node is assigned to a new CNF variable only if + it is not a terminal node otherwise it is assigned the index of + the BDD variable. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesNumberEdgesRecur ( + DdNode *f /* IN: BDD node to be numbered */, + int *cnfIds /* IN: possible source for numbering */, + int id /* IN/OUT: possible source for numbering */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (!DddmpVisitedCnf (f)) { + return (id); + } + + if (cuddIsConstant (f)) { + return (id); + } + + id = DddmpDdNodesNumberEdgesRecur (cuddT (f), cnfIds, id); + id = DddmpDdNodesNumberEdgesRecur (cuddE (f), cnfIds, id); + + retValue = DddmpReadNodeIndexCnf (f); + if (retValue >= 1) { + id = DddmpWriteNodeIndexCnfWithTerminalCheck (f, cnfIds, id); + } else { + DddmpWriteNodeIndexCnf (f, 0); + } + + DddmpClearVisitedCnf (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Resets counter and visited flag for ALL nodes of a BDD] + + Description [Resets counter and visited flag for ALL nodes of a BDD (it + recurs on the node children). The index field of the node is + used as counter. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesResetCountRecur ( + DdNode *f /* IN: root of the BDD whose counters are reset */ + ) +{ + int retValue; + + f = Cudd_Regular (f); + + if (!DddmpVisitedCnf (f)) { + return (DDDMP_SUCCESS); + } + + if (!cuddIsConstant (f)) { + retValue = DddmpDdNodesResetCountRecur (cuddT (f)); + retValue = DddmpDdNodesResetCountRecur (cuddE (f)); + } + + DddmpWriteNodeIndexCnf (f, 0); + DddmpClearVisitedCnf (f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Counts the number of incoming edges for each node of a BDD] + + Description [Counts (recursively) the number of incoming edges for each + node of a BDD. This number is stored in the index field. + ] + + SideEffects ["visited" flags remain untouched.] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesCountEdgesRecur ( + DdNode *f /* IN: root of the BDD */ + ) +{ + int indexValue, retValue; + + f = Cudd_Regular (f); + + if (cuddIsConstant (f)) { + return (DDDMP_SUCCESS); + } + + if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) { + return (DDDMP_SUCCESS); + } + + indexValue = DddmpReadNodeIndexCnf (f); + + /* IF (first time) THEN recur */ + if (indexValue == 0) { + retValue = DddmpDdNodesCountEdgesRecur (cuddT (f)); + retValue = DddmpDdNodesCountEdgesRecur (cuddE (f)); + } + + /* Increment Incoming-Edge Count Flag */ + indexValue++; + DddmpWriteNodeIndexCnf (f, indexValue); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on on the + children of the node. Constants remain untouched. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecurCnf()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecurCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisitedCnf (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecurCnf (ddMgr, cuddT (f)); + RemoveFromUniqueRecurCnf (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisitedCnf (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursive)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUnique()] + +******************************************************************************/ + +static void +RestoreInUniqueRecurCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + /* StQ 11.02.2004: + Bug fixed --> restore NULL within the next field */ + /*DddmpClearVisitedCnf (f);*/ + f->next = NULL; + + return; + } + + RestoreInUniqueRecurCnf (ddMgr, cuddT (f)); + RestoreInUniqueRecurCnf (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + f->next = *previousP; + *previousP = f; + + return; +} + +/**Function******************************************************************** + + Synopsis [Prints debug info] + + Description [Prints debug info for a BDD on the screen. It recurs on + node's children. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpPrintBddAndNextRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be displayed */ + ) +{ + int retValue; + DdNode *fPtr, *tPtr, *ePtr; + + fPtr = Cudd_Regular (f); + + if (Cudd_IsComplement (f)) { + fprintf (stdout, "sign=- ptr=%ld ", ((long int) fPtr)); + } else { + fprintf (stdout, "sign=+ ptr=%ld ", ((long int) fPtr)); + } + + if (cuddIsConstant (fPtr)) { + fprintf (stdout, "one\n"); + fflush (stdout); + return (DDDMP_SUCCESS); + } + + fprintf (stdout, + "thenPtr=%ld elsePtr=%ld BddId=%d CnfId=%d Visited=%d\n", + ((long int) cuddT (fPtr)), ((long int) cuddE (fPtr)), + fPtr->index, DddmpReadNodeIndexCnf (fPtr), + DddmpVisitedCnf (fPtr)); + + tPtr = cuddT (fPtr); + ePtr = cuddE (fPtr); + if (Cudd_IsComplement (f)) { + tPtr = Cudd_Not (tPtr); + ePtr = Cudd_Not (ePtr); + } + + retValue = DddmpPrintBddAndNextRecur (ddMgr, tPtr); + retValue = DddmpPrintBddAndNextRecur (ddMgr, ePtr); + + return (DDDMP_SUCCESS); +} + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreAdd.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreAdd.c new file mode 100644 index 000000000..a86e39ada --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreAdd.c @@ -0,0 +1,957 @@ +/**CFile********************************************************************** + FileName [dddmpStoreAdd.c] + + PackageName [dddmp] + + Synopsis [Functions to write ADDs to file.] + + Description [Functions to write ADDs to file. + ADDs are represended on file either in text or binary format under the + following rules. A file contains a forest of ADDs (a vector of + Boolean functions). ADD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to ADD + functions, followed by the list of nodes. + ADD nodes are listed according to their numbering, and in the present + implementation numbering follows a post-order strategy, in such a way + that a node is never listed before its Then/Else children. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NodeStoreRecurAdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp); +static int NodeTextStoreAdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp, int idf, int vf, int idT, int idE); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument ADD.] + + Description [Dumps the argument ADD to file. Dumping is done through + Dddmp_cuddAddArrayStore, And a dummy array of 1 ADD root is + used for this purpose. + ] + + SideEffects [Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order.] + + SeeAlso [Dddmp_cuddAddLoad Dddmp_cuddAddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddAddStore ( + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + DdNode *f /* IN: ADD root to be stored */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var ids */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + retValue = Dddmp_cuddAddArrayStore (ddMgr, ddname, 1, tmpArray, NULL, + varnames, auxids, mode, varinfo, fname, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of ADDs.] + + Description [Dumps the argument array of ADDs to file. Dumping is + either in text or binary form. see the corresponding BDD dump + function for further details. + ] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + ] + + SeeAlso [Dddmp_cuddAddStore, Dddmp_cuddAddLoad, + Dddmp_cuddAddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddAddArrayStore ( + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + int nRoots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of ADD roots to be stored */, + char **rootnames /* IN: array of root names (or NULL) */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var IDs */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + +#if 0 +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During ADD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During ADD Store.\n"); + fflush (stderr); + } + } +#endif +#endif +#endif + + retValue = DddmpCuddDdArrayStoreBdd (DDDMP_ADD, ddMgr, ddname, nRoots, f, + rootnames, varnames, auxids, mode, varinfo, fname, fp); + +#if 0 +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During ADD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During ADD Store.\n"); + fflush (stderr); + } + } +#endif +#endif +#endif + + return (retValue); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of + BDDs/ADDs. + ] + + Description [Dumps the argument array of BDDs/ADDs to file. Internal + function doing inner steps of store for BDDs and ADDs. + ADD store is presently supported only with the text format. + ] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + ] + + SeeAlso [Dddmp_cuddBddStore, Dddmp_cuddBddLoad, + Dddmp_cuddBddArrayLoad + ] + +******************************************************************************/ + +int +DddmpCuddDdArrayStoreBdd ( + Dddmp_DecompType ddType /* IN: Selects the decomp type: BDD or ADD */, + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + int nRoots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of DD roots to be stored */, + char **rootnames /* IN: array of root names (or NULL) */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var IDs */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *ids = NULL; + int *permids = NULL; + int *invpermids = NULL; + int *supportids = NULL; + int *outids = NULL; + char **outvarnames = NULL; + int nVars = ddMgr->size; + int nnodes; + int retValue; + int i, var; + int fileToClose = 0; + + /* + * Check DD Type and Mode + */ + + Dddmp_CheckAndGotoLabel (ddType==DDDMP_BDD, + "Error writing to file: BDD Type.", failure); + Dddmp_CheckAndGotoLabel (mode==DDDMP_MODE_BINARY, + "Error writing to file: ADD Type with Binary Mode.", failure); + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /* + * Force binary mode if automatic. + */ + + switch (mode) { + case DDDMP_MODE_TEXT: + case DDDMP_MODE_BINARY: + break; + case DDDMP_MODE_DEFAULT: + mode = DDDMP_MODE_BINARY; + break; + default: + mode = DDDMP_MODE_BINARY; + break; + } + + /* + * Alloc vectors for variable IDs, perm IDs and support IDs. + * +1 to include a slot for terminals. + */ + + ids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (ids==NULL, "Error allocating memory.", failure); + permids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (permids==NULL, "Error allocating memory.", failure); + invpermids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (invpermids==NULL, "Error allocating memory.", + failure); + supportids = DDDMP_ALLOC (int, nVars+1); + Dddmp_CheckAndGotoLabel (supportids==NULL, "Error allocating memory.", + failure); + + for (i=0; iindex] = scan->index; + permids[scan->index] = ddMgr->perm[scan->index]; + invpermids[ddMgr->perm[scan->index]] = scan->index; + scan = cuddT (scan); + } + Cudd_RecursiveDeref (ddMgr, support); + } + /* so that we do not try to free it in case of failure */ + support = NULL; + + /* + * Set supportids to incremental (shrinked) values following the ordering. + */ + + for (i=0, var=0; i= 0) { + supportids[invpermids[i]] = var++; + } + } + /* set a dummy id for terminal nodes */ + supportids[nVars] = var; + + /* + * Select conversion array for extra var info + */ + + switch (mode) { + case DDDMP_MODE_TEXT: + switch (varinfo) { + case DDDMP_VARIDS: + outids = ids; + break; + case DDDMP_VARPERMIDS: + outids = permids; + break; + case DDDMP_VARAUXIDS: + outids = auxids; + break; + case DDDMP_VARNAMES: + outvarnames = varnames; + break; + case DDDMP_VARDEFAULT: + break; + } + break; + case DDDMP_MODE_BINARY: + outids = NULL; + break; + } + + /* + * Number dd nodes and count them (numbering is from 1 to nnodes) + */ + + nnodes = DddmpNumberAddNodes (ddMgr, f, nRoots); + + /* + * Start Header + */ + +#ifdef DDDMP_VERSION + retValue = fprintf (fp, ".ver %s\n", DDDMP_VERSION); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); +#endif + + retValue = fprintf (fp, ".add\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".mode %c\n", mode); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (mode == DDDMP_MODE_TEXT) { + retValue = fprintf (fp, ".varinfo %d\n", varinfo); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + if (ddname != NULL) { + retValue = fprintf (fp, ".dd %s\n",ddname); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, ".nnodes %d\n", nnodes); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nvars %d\n", nVars); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nsuppvars %d\n", var); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /*------------ Write the Var Names by scanning the ids array -------------*/ + + if (varnames != NULL) { + + retValue = fprintf (fp, ".suppvarnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; i= 0) { + if (varnames[ids[i]] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. DUMMY%d generated\n", i); + fflush (stderr); + varnames[ids[i]] = DDDMP_ALLOC (char, 10); + Dddmp_CheckAndGotoLabel (varnames[ids[i]] == NULL, + "Error allocating memory.", failure); + sprintf (varnames[ids[i]], "DUMMY%d", i); + } + retValue = fprintf (fp, " %s", varnames[ids[i]]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /*--------- Write the Var SUPPORT Names by scanning the ids array ---------*/ + + if (varnames != NULL) { + retValue = fprintf (fp, ".orderedvarnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; iinvperm[i]] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. DUMMY%d generated\n", i); + fflush (stderr); + varnames[ddMgr->invperm[i]] = DDDMP_ALLOC (char, 10); + Dddmp_CheckAndGotoLabel (varnames[ddMgr->invperm[i]] == NULL, + "Error allocating memory.", failure); + sprintf (varnames[ddMgr->invperm[i]], "DUMMY%d", i); + } + + retValue = fprintf (fp, " %s", varnames[ddMgr->invperm[i]]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /*------------ Write the var ids by scanning the ids array ---------------*/ + + retValue = fprintf (fp, ".ids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; i= 0) { + retValue = fprintf (fp, " %d", i); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * Write the var permids by scanning the permids array. + */ + + retValue = fprintf (fp, ".permids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + for (i = 0; i < nVars; i++) { + if (permids[i] >= 0) { + retValue = fprintf (fp, " %d", permids[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (auxids != NULL) { + + /* + * Write the var auxids by scanning the ids array. + */ + + retValue = fprintf (fp, ".auxids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + for (i = 0; i < nVars; i++) { + if (ids[i] >= 0) { + retValue = fprintf (fp, " %d", auxids[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /* + * Write the roots info. + */ + + retValue = fprintf (fp, ".nroots %d\n", nRoots); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (rootnames != NULL) { + + /* + * Write the root names. + */ + + retValue = fprintf (fp, ".rootnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i = 0; i < nRoots; i++) { + if (rootnames[i] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. ROOT%d generated\n",i); + fflush (stderr); + rootnames[i] = DDDMP_ALLOC(char,10); + Dddmp_CheckAndGotoLabel (rootnames[i]==NULL, + "Error writing to file.", failure); + sprintf(rootnames[ids[i]], "ROOT%d",i); + } + retValue = fprintf (fp, " %s", rootnames[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, ".rootids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * Write BDD indexes of function roots. + * Use negative integers for complemented edges. + */ + + for (i = 0; i < nRoots; i++) { + if (f[i] == NULL) { + (void) fprintf (stderr, "DdStore Warning: %d-th root is NULL\n",i); + fflush (stderr); + retValue = fprintf (fp, " 0"); + } + if (Cudd_IsComplement(f[i])) { + retValue = fprintf (fp, " -%d", + DddmpReadNodeIndexAdd (Cudd_Regular (f[i]))); + } else { + retValue = fprintf (fp, " %d", + DddmpReadNodeIndexAdd (Cudd_Regular (f[i]))); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nodes\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * END HEADER + */ + + /* + * Call the function that really gets the job done. + */ + + for (i = 0; i < nRoots; i++) { + if (f[i] != NULL) { + retValue = NodeStoreRecurAdd (ddMgr, Cudd_Regular(f[i]), + mode, supportids, outvarnames, outids, fp); + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "Error writing to file.", failure); + } + } + + /* + * Write trailer and return. + */ + + retValue = fprintf (fp, ".end\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (fileToClose) { + fclose (fp); + } + + DddmpUnnumberAddNodes (ddMgr, f, nRoots); + DDDMP_FREE (ids); + DDDMP_FREE (permids); + DDDMP_FREE (invpermids); + DDDMP_FREE (supportids); + + return (DDDMP_SUCCESS); + + failure: + + if (ids != NULL) { + DDDMP_FREE (ids); + } + if (permids != NULL) { + DDDMP_FREE (permids); + } + if (invpermids != NULL) { + DDDMP_FREE (invpermids); + } + if (supportids != NULL) { + DDDMP_FREE (supportids); + } + if (support != NULL) { + Cudd_RecursiveDeref (ddMgr, support); + } + + return (DDDMP_FAILURE); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Dddmp_bddStore.] + + Description [Stores a node to file in either test or binary mode. + In text mode a node is represented (on a text line basis) as +
                    +
                  • node-index \[var-extrainfo\] var-index Then-index Else-index +
                  + + where all indexes are integer numbers and var-extrainfo + (optional redundant field) is either an integer or a string + (variable name). Node-index is redundant (due to the node + ordering) but we keep it for readability.

                  + + In binary mode nodes are represented as a sequence of bytes, + representing var-index, Then-index, and Else-index in an + optimized way. Only the first byte (code) is mandatory. + Integer indexes are represented in absolute or relative mode, + where relative means offset wrt. a Then/Else node info. + Suppose Var(NodeId), Then(NodeId) and Else(NodeId) represent + infos about a given node.

                  + + The generic "NodeId" node is stored as + +

                    +
                  • code-byte +
                  • \[var-info\] +
                  • \[Then-info\] +
                  • \[Else-info\] +
                  + + where code-byte contains bit fields + +
                    +
                  • Unused : 1 bit +
                  • Variable: 2 bits, one of the following codes +
                      +
                    • DDDMP_ABSOLUTE_ID var-info = Var(NodeId) follows +
                    • DDDMP_RELATIVE_ID Var(NodeId) is represented in relative form as + var-info = Min(Var(Then(NodeId)),Var(Else(NodeId))) -Var(NodeId) +
                    • DDDMP_RELATIVE_1 No var-info follows, because + Var(NodeId) = Min(Var(Then(NodeId)),Var(Else(NodeId)))-1 +
                    • DDDMP_TERMINAL Node is a terminal, no var info required +
                    +
                  • T : 2 bits, with codes similar to V +
                      +
                    • DDDMP_ABSOLUTE_ID Then-info = Then(NodeId) follows +
                    • DDDMP_RELATIVE_ID Then(NodeId) is represented in relative form as + Then-info = Nodeid-Then(NodeId) +
                    • DDDMP_RELATIVE_1 No info on Then(NodeId) follows, because + Then(NodeId) = NodeId-1 +
                    • DDDMP_TERMINAL Then Node is a terminal, no info required (for BDDs) +
                    +
                  • Ecompl : 1 bit, if 1 means complemented edge +
                  • E : 2 bits, with codes and meanings as for the Then edge +
                  + var-info, Then-info, Else-info (if required) are represented as unsigned + integer values on a sufficient set of bytes (MSByte first). + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +NodeStoreRecurAdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: store file */ + ) +{ + DdNode *T = NULL; + DdNode *E = NULL; + int idf = (-1); + int idT = (-1); + int idE = (-1); + int vf = (-1); + int vT = (-1); + int vE = (-1); + int retValue; + int nVars; + + nVars = ddMgr->size; + T = E = NULL; + idf = idT = idE = (-1); + +#ifdef DDDMP_DEBUG + assert(!Cudd_IsComplement(f)); + assert(f!=NULL); + assert(supportids!=NULL); +#endif + + /* If already visited, nothing to do. */ + if (DddmpVisitedAdd (f)) { + return (DDDMP_SUCCESS); + } + + /* Mark node as visited. */ + DddmpSetVisitedAdd (f); + + if (Cudd_IsConstant(f)) { + /* Check for special case: don't recur */ + idf = DddmpReadNodeIndexAdd (f); + } else { + +#ifdef DDDMP_DEBUG + /* BDDs! Only one constant supported */ + assert (!cuddIsConstant(f)); +#endif + + /* + * Recursive call for Then edge + */ + + T = cuddT(f); +#ifdef DDDMP_DEBUG + /* ROBDDs! No complemented Then edge */ + assert (!Cudd_IsComplement(T)); +#endif + /* recur */ + retValue = NodeStoreRecurAdd (ddMgr, T, mode, supportids, varnames, outids, + fp); + if (retValue != DDDMP_SUCCESS) { + return (retValue); + } + + /* + * Recursive call for Else edge + */ + + E = Cudd_Regular (cuddE (f)); + retValue = NodeStoreRecurAdd (ddMgr, E, mode, supportids, varnames, outids, + fp); + if (retValue != DDDMP_SUCCESS) { + return (retValue); + } + + /* + * Obtain nodeids and variable ids of f, T, E + */ + + idf = DddmpReadNodeIndexAdd (f); + vf = f->index; + + idT = DddmpReadNodeIndexAdd (T); + if (Cudd_IsConstant(T)) { + vT = nVars; + } else { + vT = T->index; + } + + idE = DddmpReadNodeIndexAdd (E); + if (Cudd_IsConstant(E)) { + vE = nVars; + } else { + vE = E->index; + } + } + + retValue = NodeTextStoreAdd (ddMgr, f, mode, supportids, varnames, + outids, fp, idf, vf, idT, idE); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Store One Single Node in Text Format.] + + Description [Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. + ] + + SideEffects [None] + + SeeAlso [NodeBinaryStore] + +******************************************************************************/ + +static int +NodeTextStoreAdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: Store file */, + int idf /* IN: index of the current node */, + int vf /* IN: variable of the current node */, + int idT /* IN: index of the Then node */, + int idE /* IN: index of the Else node */ + ) +{ + int retValue; + + /* + * Check for Constant + */ + + if (Cudd_IsConstant(f)) { + + if (f == Cudd_ReadOne(ddMgr)) { + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T 1 0 0\n", idf); + } else { + retValue = fprintf (fp, "%d 1 0 0\n", idf); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + if (f == Cudd_ReadZero(ddMgr)) { + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T 0 0 0\n", idf); + } else { + retValue = fprintf (fp, "%d 0 0 0\n", idf); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * A constant node different from 1: an ADD constant + */ + + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T %g 0 0\n",idf,Cudd_V(f)); + } else { + retValue = fprintf (fp, "%d %g 0 0\n",idf, Cudd_V(f)); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * ... Not A Constant + */ + + if (Cudd_IsComplement (cuddE(f))) { + idE = -idE; + } + + if (varnames != NULL) { + retValue = fprintf (fp, "%d %s %d %d %d\n", + idf, varnames[vf], supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + if (outids != NULL) { + retValue = fprintf (fp, "%d %d %d %d %d\n", + idf, outids[vf], supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + retValue = fprintf (fp, "%d %d %d %d\n", + idf, supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } +} diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreBdd.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreBdd.c new file mode 100644 index 000000000..cdc796843 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreBdd.c @@ -0,0 +1,1114 @@ +/**CFile********************************************************************** + + FileName [dddmpStoreBdd.c] + + PackageName [dddmp] + + Synopsis [Functions to write BDDs to file.] + + Description [Functions to write BDDs to file. + BDDs are represended on file either in text or binary format under the + following rules. A file contains a forest of BDDs (a vector of + Boolean functions). BDD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to BDD + functions, followed by the list of nodes. BDD nodes are listed + according to their numbering, and in the present implementation + numbering follows a post-order strategy, in such a way that a node + is never listed before its Then/Else children. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NodeStoreRecurBdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp); +static int NodeTextStoreBdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp, int idf, int vf, int idT, int idE); +static int NodeBinaryStoreBdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp, int idf, int vf, int idT, int idE, int vT, int vE, DdNode *T, DdNode *E); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD.] + + Description [Dumps the argument BDD to file. Dumping is done through + Dddmp_cuddBddArrayStore. A dummy array of 1 BDD root is + used for this purpose. + ] + + SideEffects [Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. + ] + + SeeAlso [Dddmp_cuddBddLoad Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddBddStore ( + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + DdNode *f /* IN: BDD root to be stored */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var ids */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStore (ddMgr,ddname,1,tmpArray,NULL, + varnames, auxids, mode, varinfo, fname, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of BDDs.] + + Description [Dumps the argument array of BDDs to file. Dumping is either + in text or binary form. BDDs are stored to the fp (already + open) file if not NULL. Otherwise the file whose name is + fname is opened in write mode. The header has the same format + for both textual and binary dump. Names are allowed for input + variables (vnames) and for represented functions (rnames). + For sake of generality and because of dynamic variable + ordering both variable IDs and permuted IDs are included. + New IDs are also supported (auxids). Variables are identified + with incremental numbers. according with their positiom in + the support set. In text mode, an extra info may be added, + chosen among the following options: name, ID, PermID, or an + auxiliary id. Since conversion from DD pointers to integers + is required, DD nodes are temporarily removed from the unique + hash table. This allows the use of the next field to store + node IDs. + ] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + ] + + SeeAlso [Dddmp_cuddBddStore, Dddmp_cuddBddLoad, + Dddmp_cuddBddArrayLoad + ] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStore ( + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: dd name (or NULL) */, + int nRoots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of BDD roots to be stored */, + char **rootnames /* IN: array of root names (or NULL) */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var IDs */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + retValue = DddmpCuddBddArrayStore (DDDMP_BDD, ddMgr, ddname, nRoots, f, + rootnames, varnames, auxids, mode, varinfo, fname, fp); + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of + BDDs. + ] + + Description [Dumps the argument array of BDDs to file. + Internal function doing inner steps of store for BDDs. + ] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + ] + + SeeAlso [Dddmp_cuddBddStore, Dddmp_cuddBddLoad, + Dddmp_cuddBddArrayLoad + ] + +******************************************************************************/ + +int +DddmpCuddBddArrayStore ( + Dddmp_DecompType ddType /* IN: Selects the decomp type BDD */, + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + int nRoots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of DD roots to be stored */, + char **rootnames /* IN: array of root names (or NULL) */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var IDs */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *ids = NULL; + int *permids = NULL; + int *invpermids = NULL; + int *supportids = NULL; + int *outids = NULL; + char **outvarnames = NULL; + int nVars = ddMgr->size; + int nnodes; + int retValue; + int i, var; + int fileToClose = 0; + + /* + * Check DD Type + */ + + Dddmp_CheckAndGotoLabel (ddType==DDDMP_ADD, + "Error writing to file: ADD Type.", failure); + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /* + * Force binary mode if automatic. + */ + + switch (mode) { + case DDDMP_MODE_TEXT: + case DDDMP_MODE_BINARY: + break; + case DDDMP_MODE_DEFAULT: + mode = DDDMP_MODE_BINARY; + break; + default: + mode = DDDMP_MODE_BINARY; + break; + } + + /* + * Alloc vectors for variable IDs, perm IDs and support IDs. + * +1 to include a slot for terminals. + */ + + ids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (ids==NULL, "Error allocating memory.", failure); + permids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (permids==NULL, "Error allocating memory.", failure); + invpermids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (invpermids==NULL, "Error allocating memory.", + failure); + supportids = DDDMP_ALLOC (int, nVars+1); + Dddmp_CheckAndGotoLabel (supportids==NULL, "Error allocating memory.", + failure); + + for (i=0; iindex] = scan->index; + permids[scan->index] = ddMgr->perm[scan->index]; + invpermids[ddMgr->perm[scan->index]] = scan->index; + scan = cuddT (scan); + } + Cudd_RecursiveDeref (ddMgr, support); + } + /* so that we do not try to free it in case of failure */ + support = NULL; + + /* + * Set supportids to incremental (shrinked) values following the ordering. + */ + + for (i=0, var=0; i= 0) { + supportids[invpermids[i]] = var++; + } + } + /* set a dummy id for terminal nodes */ + supportids[nVars] = var; + + /* + * Select conversion array for extra var info + */ + + switch (mode) { + case DDDMP_MODE_TEXT: + switch (varinfo) { + case DDDMP_VARIDS: + outids = ids; + break; + case DDDMP_VARPERMIDS: + outids = permids; + break; + case DDDMP_VARAUXIDS: + outids = auxids; + break; + case DDDMP_VARNAMES: + outvarnames = varnames; + break; + case DDDMP_VARDEFAULT: + break; + } + break; + case DDDMP_MODE_BINARY: + outids = NULL; + break; + } + + /* + * Number dd nodes and count them (numbering is from 1 to nnodes) + */ + + nnodes = DddmpNumberBddNodes (ddMgr, f, nRoots); + + /* + * Start Header + */ + +#ifdef DDDMP_VERSION + retValue = fprintf (fp, ".ver %s\n", DDDMP_VERSION); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); +#endif + + retValue = fprintf (fp, ".mode %c\n", mode); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (mode == DDDMP_MODE_TEXT) { + retValue = fprintf (fp, ".varinfo %d\n", varinfo); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + if (ddname != NULL) { + retValue = fprintf (fp, ".dd %s\n",ddname); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, ".nnodes %d\n", nnodes); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nvars %d\n", nVars); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nsuppvars %d\n", var); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /*------------ Write the Var Names by scanning the ids array -------------*/ + + if (varnames != NULL) { + + retValue = fprintf (fp, ".suppvarnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; i= 0) { + if (varnames[ids[i]] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. DUMMY%d generated\n", i); + fflush (stderr); + varnames[ids[i]] = DDDMP_ALLOC (char, 10); + Dddmp_CheckAndGotoLabel (varnames[ids[i]] == NULL, + "Error allocating memory.", failure); + sprintf (varnames[ids[i]], "DUMMY%d", i); + } + retValue = fprintf (fp, " %s", varnames[ids[i]]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /*--------- Write the Var SUPPORT Names by scanning the ids array ---------*/ + + if (varnames != NULL) { + retValue = fprintf (fp, ".orderedvarnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; iinvperm[i]] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. DUMMY%d generated\n", i); + fflush (stderr); + varnames[ddMgr->invperm[i]] = DDDMP_ALLOC (char, 10); + Dddmp_CheckAndGotoLabel (varnames[ddMgr->invperm[i]] == NULL, + "Error allocating memory.", failure); + sprintf (varnames[ddMgr->invperm[i]], "DUMMY%d", i); + } + + retValue = fprintf (fp, " %s", varnames[ddMgr->invperm[i]]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /*------------ Write the var ids by scanning the ids array ---------------*/ + + retValue = fprintf (fp, ".ids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; i= 0) { + retValue = fprintf (fp, " %d", i); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * Write the var permids by scanning the permids array. + */ + + retValue = fprintf (fp, ".permids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + for (i = 0; i < nVars; i++) { + if (permids[i] >= 0) { + retValue = fprintf (fp, " %d", permids[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (auxids != NULL) { + + /* + * Write the var auxids by scanning the ids array. + */ + + retValue = fprintf (fp, ".auxids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + for (i = 0; i < nVars; i++) { + if (ids[i] >= 0) { + retValue = fprintf (fp, " %d", auxids[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /* + * Write the roots info. + */ + + retValue = fprintf (fp, ".nroots %d\n", nRoots); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (rootnames != NULL) { + + /* + * Write the root names. + */ + + retValue = fprintf (fp, ".rootnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i = 0; i < nRoots; i++) { + if (rootnames[i] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. ROOT%d generated\n",i); + fflush (stderr); + rootnames[i] = DDDMP_ALLOC(char,10); + Dddmp_CheckAndGotoLabel (rootnames[i]==NULL, + "Error writing to file.", failure); + sprintf(rootnames[ids[i]], "ROOT%d",i); + } + retValue = fprintf (fp, " %s", rootnames[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, ".rootids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * Write BDD indexes of function roots. + * Use negative integers for complemented edges. + */ + + for (i = 0; i < nRoots; i++) { + if (f[i] == NULL) { + (void) fprintf (stderr, "DdStore Warning: %d-th root is NULL\n",i); + fflush (stderr); + retValue = fprintf (fp, " 0"); + } + if (Cudd_IsComplement(f[i])) { + retValue = fprintf (fp, " -%d", + DddmpReadNodeIndexBdd (Cudd_Regular (f[i]))); + } else { + retValue = fprintf (fp, " %d", + DddmpReadNodeIndexBdd (Cudd_Regular (f[i]))); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nodes\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * END HEADER + */ + + /* + * Call the function that really gets the job done. + */ + + for (i = 0; i < nRoots; i++) { + if (f[i] != NULL) { + retValue = NodeStoreRecurBdd (ddMgr, Cudd_Regular(f[i]), + mode, supportids, outvarnames, outids, fp); + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "Error writing to file.", failure); + } + } + + /* + * Write trailer and return. + */ + + retValue = fprintf (fp, ".end\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (fileToClose) { + fclose (fp); + } + + DddmpUnnumberBddNodes (ddMgr, f, nRoots); + DDDMP_FREE (ids); + DDDMP_FREE (permids); + DDDMP_FREE (invpermids); + DDDMP_FREE (supportids); + + return (DDDMP_SUCCESS); + + failure: + + if (ids != NULL) { + DDDMP_FREE (ids); + } + if (permids != NULL) { + DDDMP_FREE (permids); + } + if (invpermids != NULL) { + DDDMP_FREE (invpermids); + } + if (supportids != NULL) { + DDDMP_FREE (supportids); + } + if (support != NULL) { + Cudd_RecursiveDeref (ddMgr, support); + } + + return (DDDMP_FAILURE); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Dddmp_bddStore.] + + Description [Stores a node to file in either test or binary mode. + In text mode a node is represented (on a text line basis) as +
                    +
                  • node-index \[var-extrainfo\] var-index Then-index Else-index +
                  + + where all indexes are integer numbers and var-extrainfo + (optional redundant field) is either an integer or a string + (variable name). Node-index is redundant (due to the node + ordering) but we keep it for readability.

                  + + In binary mode nodes are represented as a sequence of bytes, + representing var-index, Then-index, and Else-index in an + optimized way. Only the first byte (code) is mandatory. + Integer indexes are represented in absolute or relative mode, + where relative means offset wrt. a Then/Else node info. + Suppose Var(NodeId), Then(NodeId) and Else(NodeId) represent + infos about a given node.

                  + + The generic "NodeId" node is stored as + +

                    +
                  • code-byte +
                  • \[var-info\] +
                  • \[Then-info\] +
                  • \[Else-info\] +
                  + + where code-byte contains bit fields + +
                    +
                  • Unused : 1 bit +
                  • Variable: 2 bits, one of the following codes +
                      +
                    • DDDMP_ABSOLUTE_ID var-info = Var(NodeId) follows +
                    • DDDMP_RELATIVE_ID Var(NodeId) is represented in relative form as + var-info = Min(Var(Then(NodeId)),Var(Else(NodeId))) -Var(NodeId) +
                    • DDDMP_RELATIVE_1 No var-info follows, because + Var(NodeId) = Min(Var(Then(NodeId)),Var(Else(NodeId)))-1 +
                    • DDDMP_TERMINAL Node is a terminal, no var info required +
                    +
                  • T : 2 bits, with codes similar to V +
                      +
                    • DDDMP_ABSOLUTE_ID Then-info = Then(NodeId) follows +
                    • DDDMP_RELATIVE_ID Then(NodeId) is represented in relative form as + Then-info = Nodeid-Then(NodeId) +
                    • DDDMP_RELATIVE_1 No info on Then(NodeId) follows, because + Then(NodeId) = NodeId-1 +
                    • DDDMP_TERMINAL Then Node is a terminal, no info required (for BDDs) +
                    +
                  • Ecompl : 1 bit, if 1 means complemented edge +
                  • E : 2 bits, with codes and meanings as for the Then edge +
                  + var-info, Then-info, Else-info (if required) are represented as unsigned + integer values on a sufficient set of bytes (MSByte first). + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +NodeStoreRecurBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: store file */ + ) +{ + DdNode *T = NULL; + DdNode *E = NULL; + int idf = (-1); + int idT = (-1); + int idE = (-1); + int vf = (-1); + int vT = (-1); + int vE = (-1); + int retValue; + int nVars; + + nVars = ddMgr->size; + T = E = NULL; + idf = idT = idE = (-1); + +#ifdef DDDMP_DEBUG + assert(!Cudd_IsComplement(f)); + assert(f!=NULL); + assert(supportids!=NULL); +#endif + + /* If already visited, nothing to do. */ + if (DddmpVisitedBdd (f)) { + return (DDDMP_SUCCESS); + } + + /* Mark node as visited. */ + DddmpSetVisitedBdd (f); + + if (Cudd_IsConstant(f)) { + /* Check for special case: don't recur */ + idf = DddmpReadNodeIndexBdd (f); + } else { + +#ifdef DDDMP_DEBUG + /* BDDs! Only one constant supported */ + assert (!cuddIsConstant(f)); +#endif + + /* + * Recursive call for Then edge + */ + + T = cuddT(f); +#ifdef DDDMP_DEBUG + /* ROBDDs! No complemented Then edge */ + assert (!Cudd_IsComplement(T)); +#endif + /* recur */ + retValue = NodeStoreRecurBdd (ddMgr, T, mode, supportids, varnames, outids, + fp); + if (retValue != DDDMP_SUCCESS) { + return (retValue); + } + + /* + * Recursive call for Else edge + */ + + E = Cudd_Regular (cuddE (f)); + retValue = NodeStoreRecurBdd (ddMgr, E, mode, supportids, varnames, outids, + fp); + if (retValue != DDDMP_SUCCESS) { + return (retValue); + } + + /* + * Obtain nodeids and variable ids of f, T, E + */ + + idf = DddmpReadNodeIndexBdd (f); + vf = f->index; + + idT = DddmpReadNodeIndexBdd (T); + if (Cudd_IsConstant(T)) { + vT = nVars; + } else { + vT = T->index; + } + + idE = DddmpReadNodeIndexBdd (E); + if (Cudd_IsConstant(E)) { + vE = nVars; + } else { + vE = E->index; + } + } + + switch (mode) { + case DDDMP_MODE_TEXT: + retValue = NodeTextStoreBdd (ddMgr, f, mode, supportids, varnames, + outids, fp, idf, vf, idT, idE); + break; + case DDDMP_MODE_BINARY: + retValue = NodeBinaryStoreBdd (ddMgr, f, mode, supportids, varnames, + outids, fp, idf, vf, idT, idE, vT, vE, T, E); + break; + default: + return (DDDMP_FAILURE); + } + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Store One Single Node in Text Format.] + + Description [Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. + ] + + SideEffects [None] + + SeeAlso [NodeBinaryStoreBdd] + +******************************************************************************/ + +static int +NodeTextStoreBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: Store file */, + int idf /* IN: index of the current node */, + int vf /* IN: variable of the current node */, + int idT /* IN: index of the Then node */, + int idE /* IN: index of the Else node */ + ) +{ + int retValue = EOF; + + /* + * Check for Constant + */ + + if (Cudd_IsConstant(f)) { + + if (f == Cudd_ReadOne(ddMgr)) { + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T 1 0 0\n", idf); + } else { + retValue = fprintf (fp, "%d 1 0 0\n", idf); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + if (f == Cudd_ReadZero(ddMgr)) { + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T 0 0 0\n", idf); + } else { + retValue = fprintf (fp, "%d 0 0 0\n", idf); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * A constant node different from 1: an ADD constant + */ + + Dddmp_CheckAndReturn (((varnames!=NULL)||(outids!=NULL)), + "Error writing to file: ADD Type."); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * ... Not A Constant + */ + + if (Cudd_IsComplement (cuddE(f))) { + idE = -idE; + } + + if (varnames != NULL) { + retValue = fprintf (fp, "%d %s %d %d %d\n", + idf, varnames[vf], supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + if (outids != NULL) { + retValue = fprintf (fp, "%d %d %d %d %d\n", + idf, outids[vf], supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + retValue = fprintf (fp, "%d %d %d %d\n", + idf, supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } +} + +/**Function******************************************************************** + + Synopsis [Store One Single Node in Binary Format.] + + Description [Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. + Store every information as coded binary values.] + + SideEffects [None] + + SeeAlso [NodeTextStoreBdd] + +******************************************************************************/ + +static int +NodeBinaryStoreBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: store file */, + int idf /* IN: index of the node */, + int vf /* IN: variable of the node */, + int idT /* IN: index of the Then node */, + int idE /* IN: index of the Else node */, + int vT /* IN: variable of the Then node */, + int vE /* IN: variable of the Else node */, + DdNode *T /* IN: Then node */, + DdNode *E /* IN: Else node */ + ) +{ + int retValue, diff, var; + struct binary_dd_code code; + + /* + * Check for Constant + */ + + /* only integer ids used, varnames ignored */ + /* Terminal one is coded as DDDMP_TERMINAL, all other fields are 0 */ + if (Cudd_IsConstant(f)) { + code.Unused = 0; + code.V = DDDMP_TERMINAL; + code.T = 0; + code.E = 0; + code.Ecompl = 0; + retValue = DddmpWriteCode (fp,code); + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * Non terminal: output variable id + */ + + var = supportids[vf]; + diff = (supportids[vT] +#include "dddmpInt.h" + +/*-------------------------------1--------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMP_DEBUG_CNF 0 + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define GET_MAX(x,y) (x>y?x:y) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpCuddBddArrayStoreCnf(DdManager *ddMgr, DdNode **f, int rootN, Dddmp_DecompCnfStoreType mode, int noHeader, char **varNames, int *bddIds, int *bddAuxIds, int *cnfIds, int idInitial, int edgeInTh, int pathLengthTh, char *fname, FILE *fp, int *clauseNPtr, int *varNewNPtr); +static int StoreCnfNodeByNode(DdManager *ddMgr, DdNode **f, int rootN, int *bddIds, int *cnfIds, FILE *fp, int *clauseN, int *varMax, int *rootStartLine); +static int StoreCnfNodeByNodeRecur(DdManager *ddMgr, DdNode *f, int *bddIds, int *cnfIds, FILE *fp, int *clauseN, int *varMax); +static int StoreCnfOneNode(DdNode *f, int idf, int vf, int idT, int idE, FILE *fp, int *clauseN, int *varMax); +static int StoreCnfMaxtermByMaxterm(DdManager *ddMgr, DdNode **f, int rootN, int *bddIds, int *cnfIds, int idInitial, FILE *fp, int *varMax, int *clauseN, int *rootStartLine); +static int StoreCnfBest(DdManager *ddMgr, DdNode **f, int rootN, int *bddIds, int *cnfIds, int idInitial, FILE *fp, int *varMax, int *clauseN, int *rootStartLine); +static void StoreCnfMaxtermByMaxtermRecur(DdManager *ddMgr, DdNode *node, int *bddIds, int *cnfIds, FILE *fp, int *list, int *clauseN, int *varMax); +static int StoreCnfBestNotSharedRecur(DdManager *ddMgr, DdNode *node, int idf, int *bddIds, int *cnfIds, FILE *fp, int *list, int *clauseN, int *varMax); +static int StoreCnfBestSharedRecur(DdManager *ddMgr, DdNode *node, int *bddIds, int *cnfIds, FILE *fp, int *list, int *clauseN, int *varMax); +static int printCubeCnf(DdManager *ddMgr, DdNode *node, int *cnfIds, FILE *fp, int *list, int *varMax); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a CNF format. + ] + + Description [Dumps the argument BDD to file. + This task is performed by calling the function + Dddmp_cuddBddArrayStoreCnf. + ] + + SideEffects [Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. + ] + + SeeAlso [Dddmp_cuddBddArrayStoreCnf] + +******************************************************************************/ + +int +Dddmp_cuddBddStoreCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: BDD root to be stored */, + Dddmp_DecompCnfStoreType mode /* IN: format selection */, + int noHeader /* IN: do not store header iff 1 */, + char **varNames /* IN: array of variable names (or NULL) */, + int *bddIds /* IN: array of var ids */, + int *bddAuxIds /* IN: array of BDD node Auxiliary Ids */, + int *cnfIds /* IN: array of CNF var ids */, + int idInitial /* IN: starting id for cutting variables */, + int edgeInTh /* IN: Max # Incoming Edges */, + int pathLengthTh /* IN: Max Path Length */, + char *fname /* IN: file name */, + FILE *fp /* IN: pointer to the store file */, + int *clauseNPtr /* OUT: number of clause stored */, + int *varNewNPtr /* OUT: number of new variable created */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStoreCnf (ddMgr, tmpArray, 1, mode, + noHeader, varNames, bddIds, bddAuxIds, cnfIds, idInitial, edgeInTh, + pathLengthTh, fname, fp, clauseNPtr, varNewNPtr); + + Dddmp_CheckAndReturn (retValue==DDDMP_FAILURE, "Failure."); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument array of BDDs + in CNF format. + ] + + Description [Dumps the argument array of BDDs to file.] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + Three methods are allowed: + * NodeByNode method: Insert a cut-point for each BDD node (but the + terminal nodes) + * MaxtermByMaxterm method: Insert no cut-points, i.e. the off-set of + trhe function is stored + * Best method: Tradeoff between the previous two methods. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. + The stored file can contain a file header or not depending on the + noHeader parameter (IFF 0, usual setting, the header is usually stored. + This option can be useful in storing multiple BDDs, as separate BDDs, + on the same file leaving the opening of the file to the caller. + ] + + SeeAlso [] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStoreCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDD roots to be stored */, + int rootN /* IN: # output BDD roots to be stored */, + Dddmp_DecompCnfStoreType mode /* IN: format selection */, + int noHeader /* IN: do not store header iff 1 */, + char **varNames /* IN: array of variable names (or NULL) */, + int *bddIds /* IN: array of converted var IDs */, + int *bddAuxIds /* IN: array of BDD node Auxiliary Ids */, + int *cnfIds /* IN: array of converted var IDs */, + int idInitial /* IN: starting id for cutting variables */, + int edgeInTh /* IN: Max # Incoming Edges */, + int pathLengthTh /* IN: Max Path Length */, + char *fname /* IN: file name */, + FILE *fp /* IN: pointer to the store file */, + int *clauseNPtr /* OUT: number of clause stored */, + int *varNewNPtr /* OUT: number of new variable created */ + ) +{ + int retValue2; + +#if 0 +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValue1; + + retValue1 = Cudd_DebugCheck (ddMgr); + Dddmp_CheckAndReturn (retValue1==1, + "Inconsistency Found During CNF Store."); + Dddmp_CheckAndReturn (retValue1==CUDD_OUT_OF_MEM, + "Out of Memory During CNF Store."); +#endif +#endif +#endif + + retValue2 = DddmpCuddBddArrayStoreCnf (ddMgr, f, rootN, mode, noHeader, + varNames, bddIds, bddAuxIds, cnfIds, idInitial, edgeInTh, pathLengthTh, + fname, fp, clauseNPtr, varNewNPtr); + +#if 0 +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValue1 = Cudd_DebugCheck (ddMgr); + Dddmp_CheckAndReturn (retValue1==1, + "Inconsistency Found During CNF Store."); + Dddmp_CheckAndReturn (retValue1==CUDD_OUT_OF_MEM, + "Out of Memory During CNF Store."); +#endif +#endif +#endif + + return (retValue2); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of + BDDs in the CNF standard format. + ] + + Description [Dumps the argument array of BDDs/ADDs to file in CNF format. + The following arrays: varNames, bddIds, bddAuxIds, and cnfIds + fix the correspondence among variable names, BDD ids, BDD + auxiliary ids and the ids used to store the CNF problem. + All these arrays are automatically created iff NULL. + Auxiliary variable, iff necessary, are created starting from value + idInitial. + Iff idInitial is <= 0 its value is selected as the number of internal + CUDD variable + 2. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. + ] + + SideEffects [Nodes are temporarily removed from the unique hash table. + They are re-linked after the store operation in a modified + order. + ] + + SeeAlso [Dddmp_cuddBddStore] + +******************************************************************************/ + +static int +DddmpCuddBddArrayStoreCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDD roots to be stored */, + int rootN /* IN: # of output BDD roots to be stored */, + Dddmp_DecompCnfStoreType mode /* IN: format selection */, + int noHeader /* IN: do not store header iff 1 */, + char **varNames /* IN: array of variable names (or NULL) */, + int *bddIds /* IN: array of BDD node Ids (or NULL) */, + int *bddAuxIds /* IN: array of BDD Aux Ids (or NULL) */, + int *cnfIds /* IN: array of CNF ids (or NULL) */, + int idInitial /* IN: starting id for cutting variables */, + int edgeInTh /* IN: Max # Incoming Edges */, + int pathLengthTh /* IN: Max Path Length */, + char *fname /* IN: file name */, + FILE *fp /* IN: pointer to the store file */, + int *clauseNPtr /* OUT: number of clause stored */, + int *varNewNPtr /* OUT: number of new variable created */ + ) +{ + DdNode *support = NULL; + DdNode *scan = NULL; + int *bddIdsInSupport = NULL; + int *permIdsInSupport = NULL; + int *rootStartLine = NULL; + int nVar, nVarInSupport, retValue, i, j, fileToClose; + int varMax, clauseN, flagVar, intStringLength; + int bddIdsToFree = 0; + int bddAuxIdsToFree = 0; + int cnfIdsToFree = 0; + int varNamesToFree = 0; + char intString[DDDMP_MAXSTRLEN]; + char tmpString[DDDMP_MAXSTRLEN]; + fpos_t posFile1, posFile2; + + /*---------------------------- Set Initial Values -------------------------*/ + + support = scan = NULL; + bddIdsInSupport = permIdsInSupport = rootStartLine = NULL; + nVar = ddMgr->size; + fileToClose = 0; + sprintf (intString, "%d", INT_MAX); + intStringLength = strlen (intString); + + /*---------- Check if File needs to be opened in the proper mode ----------*/ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /*--------- Generate Bdd LOCAL IDs and Perm IDs and count them ------------*/ + + /* BDD Ids */ + bddIdsInSupport = DDDMP_ALLOC (int, nVar); + Dddmp_CheckAndGotoLabel (bddIdsInSupport==NULL, "Error allocating memory.", + failure); + /* BDD PermIds */ + permIdsInSupport = DDDMP_ALLOC (int, nVar); + Dddmp_CheckAndGotoLabel (permIdsInSupport==NULL, "Error allocating memory.", + failure); + /* Support Size (Number of BDD Ids-PermIds */ + nVarInSupport = 0; + + for (i=0; iindex] = scan->index; + permIdsInSupport[scan->index] = ddMgr->perm[scan->index]; + scan = cuddT (scan); + } + Cudd_RecursiveDeref (ddMgr, support); + } + /* so that we do not try to free it in case of failure */ + support = NULL; + + /*---------------------------- Start HEADER -------------------------------*/ + + if (noHeader==0) { + + retValue = fprintf (fp, + "c # BDD stored by the DDDMP tool in CNF format\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing on file.", + failure); + fprintf (fp, "c #\n"); + } + + /*-------------------- Generate Bdd IDs IFF necessary ---------------------*/ + + if (bddIds == NULL) { + if (noHeader==0) { + fprintf (fp, "c # Warning: BDD IDs missing ... evaluating them.\n"); + fprintf (fp, "c # \n"); + fflush (fp); + } + + bddIdsToFree = 1; + bddIds = DDDMP_ALLOC (int, nVar); + Dddmp_CheckAndGotoLabel (bddIds==NULL, "Error allocating memory.", + failure); + + /* Get BDD-IDs Directly from Cudd Manager */ + for (i=0; i= 0) { + fprintf (fp, " %s", varNames[i]); + } + } + fprintf (fp, "\n"); + } + + /* Ordered Variable Names */ + if (varNames != NULL) { + fprintf (fp, "c .orderedvarnames"); + for (i=0; i= 0) { + fprintf (fp, " %d", bddIdsInSupport[i]); + } + } + fprintf (fp, "\n"); + + /* BDD Variable Permutation Ids */ + fprintf (fp, "c .permids "); + for (i=0; i= 0) { + fprintf (fp, " %d", permIdsInSupport[i]); + } + } + fprintf (fp, "\n"); + + /* BDD Variable Auxiliary Ids */ + fprintf (fp, "c .auxids "); + for (i=0; i= 0) { + fprintf (fp, " %d", bddAuxIds[i]); + } + } + fprintf (fp, "\n"); + + /* CNF Ids */ + fprintf (fp, "c .cnfids "); + for (i=0; i= 0) { + fprintf (fp, " %d", cnfIds[i]); + } + } + fprintf (fp, "\n"); + + /* Number of Roots */ + fprintf (fp, "c .nroots %d", rootN); + fprintf (fp, "\n"); + + /* Root Starting Line */ + fgetpos (fp, &posFile1); + fprintf (fp, "c .rootids"); + for (i=0; i \n", i); +#endif + if (Cudd_IsComplement (f[i])) { + retValue = fprintf (fp, "-%d 0\n", idf); + } else { + retValue = fprintf (fp, "%d 0\n", idf); + } + *varMax = GET_MAX (*varMax, idf); + *clauseN = *clauseN + 1; + + if (retValue == EOF) { + (void) fprintf (stderr, + "DdStoreCnf: Error in recursive node store\n"); + fflush (stderr); + } + } + } + } + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Dddmp_bddStore.] + + Description [Performs the recursive step of Dddmp_bddStore. + Traverse the BDD and store a CNF formula for each "terminal" node. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +StoreCnfNodeByNodeRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: BDD node to be stored */, + int *bddIds /* IN: BDD ids for variables */, + int *cnfIds /* IN: CNF ids for variables */, + FILE *fp /* IN: store file */, + int *clauseN /* OUT: number of clauses written in the CNF file */, + int *varMax /* OUT: maximum value of id written in the CNF file */ + ) +{ + DdNode *T, *E; + int idf, idT, idE, vf; + int retValue; + +#ifdef DDDMP_DEBUG + assert(!Cudd_IsComplement(f)); + assert(f!=NULL); +#endif + + /* If constant, nothing to do. */ + if (Cudd_IsConstant(f)) { + return (1); + } + + /* If already visited, nothing to do. */ + if (DddmpVisitedCnf (f)) { + return (1); + } + + /* Mark node as visited. */ + DddmpSetVisitedCnf (f); + + /*------------------ Non Terminal Node -------------------------------*/ + +#ifdef DDDMP_DEBUG + /* BDDs! Only one constant supported */ + assert (!cuddIsConstant(f)); +#endif + + /* + * Recursive call for Then edge + */ + + T = cuddT (f); +#ifdef DDDMP_DEBUG + /* ROBDDs! No complemented Then edge */ + assert (!Cudd_IsComplement(T)); +#endif + /* recur */ + retValue = StoreCnfNodeByNodeRecur (ddMgr, T, bddIds, cnfIds, fp, + clauseN, varMax); + if (retValue != 1) { + return(retValue); + } + + /* + * Recursive call for Else edge + */ + + E = Cudd_Regular (cuddE (f)); + retValue = StoreCnfNodeByNodeRecur (ddMgr, E, bddIds, cnfIds, fp, + clauseN, varMax); + if (retValue != 1) { + return (retValue); + } + + /* + * Obtain nodeids and variable ids of f, T, E + */ + + idf = DddmpReadNodeIndexCnf (f); + vf = f->index; + + if (bddIds[vf] != vf) { + (void) fprintf (stderr, "DdStoreCnf: Error writing to file\n"); + fflush (stderr); + return (0); + } + + idT = DddmpReadNodeIndexCnf (T); + + idE = DddmpReadNodeIndexCnf (E); + if (Cudd_IsComplement (cuddE (f))) { + idE = -idE; + } + + retValue = StoreCnfOneNode (f, idf, cnfIds[vf], idT, idE, fp, + clauseN, varMax); + + if (retValue == EOF) { + return (0); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Store One Single BDD Node.] + + Description [Store One Single BDD Node translating it as a multiplexer.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +StoreCnfOneNode ( + DdNode *f /* IN: node to be stored */, + int idf /* IN: node CNF Index */, + int vf /* IN: node BDD Index */, + int idT /* IN: Then CNF Index with sign = inverted edge */, + int idE /* IN: Else CNF Index with sign = inverted edge */, + FILE *fp /* IN: store file */, + int *clauseN /* OUT: number of clauses */, + int *varMax /* OUT: maximun Index of variable stored */ + ) +{ + int retValue = 0; + int idfAbs, idTAbs, idEAbs; + + idfAbs = abs (idf); + idTAbs = abs (idT); + idEAbs = abs (idE); + + /*----------------------------- Check for Constant ------------------------*/ + + assert(!Cudd_IsConstant(f)); + + /*------------------------- Check for terminal nodes ----------------------*/ + + if ((idTAbs==1) && (idEAbs==1)) { + return (1); + } + + /*------------------------------ Internal Node ----------------------------*/ + +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "id=%d var=%d idT=%d idE=%d\n", + idf, vf, idT, idE); +#endif + + /* + * Then to terminal + */ + + if ((idTAbs==1) && (idEAbs!=1)) { +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "CASE 1 -->\n"); +#endif + retValue = fprintf (fp, "%d %d 0\n", + idf, -vf); + retValue = fprintf (fp, "%d %d 0\n", + idf, -idE); + retValue = fprintf (fp, "%d %d %d 0\n", + -idf, vf, idE); + *clauseN = *clauseN + 3; + + *varMax = GET_MAX (*varMax, idfAbs); + *varMax = GET_MAX (*varMax, vf); + *varMax = GET_MAX (*varMax, idEAbs); + } + + /* + * Else to terminal + */ + + if ((idTAbs!=1) && (idEAbs==1)) { + if (idE == 1) { +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "CASE 2 -->\n"); +#endif + retValue = fprintf (fp, "%d %d 0\n", + idf, vf); + retValue = fprintf (fp, "%d %d 0\n", + idf, -idT); + retValue = fprintf (fp, "%d %d %d 0\n", + -idf, -vf, idT); + } else { +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "CASE 3 -->\n"); +#endif + retValue = fprintf (fp, "%d %d 0\n", + -idf, vf); + retValue = fprintf (fp, "%d %d 0\n", + -idf, idT); + retValue = fprintf (fp, "%d %d %d 0\n", + idf, -vf, -idT); + } + + *varMax = GET_MAX (*varMax, idfAbs); + *varMax = GET_MAX (*varMax, vf); + *varMax = GET_MAX (*varMax, idTAbs); + + *clauseN = *clauseN + 3; + } + + /* + * Nor Then or Else to terminal + */ + + if ((idTAbs!=1) && (idEAbs!=1)) { +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "CASE 4 -->\n"); +#endif + retValue = fprintf (fp, "%d %d %d 0\n", + idf, vf, -idE); + retValue = fprintf (fp, "%d %d %d 0\n", + -idf, vf, idE); + retValue = fprintf (fp, "%d %d %d 0\n", + idf, -vf, -idT); + retValue = fprintf (fp, "%d %d %d 0\n", + -idf, -vf, idT); + + *varMax = GET_MAX (*varMax, idfAbs); + *varMax = GET_MAX (*varMax, vf); + *varMax = GET_MAX (*varMax, idTAbs); + *varMax = GET_MAX (*varMax, idEAbs); + + *clauseN = *clauseN + 4; + } + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Prints a disjoint sum of products.] + + Description [Prints a disjoint sum of product cover for the function + rooted at node. Each product corresponds to a path from node a + leaf node different from the logical zero, and different from + the background value. Uses the standard output. Returns 1 if + successful, 0 otherwise. + ] + + SideEffects [None] + + SeeAlso [StoreCnfBest] + +******************************************************************************/ + +static int +StoreCnfMaxtermByMaxterm ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs to store */, + int rootN /* IN: number of BDDs in the array */, + int *bddIds /* IN: BDD Identifiers */, + int *cnfIds /* IN: corresponding CNF Identifiers */, + int idInitial /* IN: initial value for numbering new CNF variables */, + FILE *fp /* IN: file pointer */, + int *varMax /* OUT: maximum identifier of the variables created */, + int *clauseN /* OUT: number of stored clauses */, + int *rootStartLine /* OUT: line where root starts */ + ) +{ + int i, j, *list; + + list = DDDMP_ALLOC (int, ddMgr->size); + if (list == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + return (DDDMP_FAILURE); + } + + for (i=0; isize; j++) { + list[j] = 2; + } + + /* + * Set Starting Line for this Root + */ + + rootStartLine[i] = *clauseN + 1; + + StoreCnfMaxtermByMaxtermRecur (ddMgr, f[i], bddIds, cnfIds, fp, + list, clauseN, varMax); + } + } + } + + FREE (list); + + return (1); +} + +/**Function******************************************************************** + + Synopsis [Prints a disjoint sum of products with intermediate + cutting points.] + + Description [Prints a disjoint sum of product cover for the function + rooted at node intorducing cutting points whenever necessary. + Each product corresponds to a path from node a leaf + node different from the logical zero, and different from the + background value. Uses the standard output. Returns 1 if + successful, 0 otherwise. + ] + + SideEffects [None] + + SeeAlso [StoreCnfMaxtermByMaxterm] + +******************************************************************************/ + +static int +StoreCnfBest ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs to store */, + int rootN /* IN: number of BDD in the array */, + int *bddIds /* IN: BDD identifiers */, + int *cnfIds /* IN: corresponding CNF identifiers */, + int idInitial /* IN: initial value for numbering new CNF variables */, + FILE *fp /* IN: file pointer */, + int *varMax /* OUT: maximum identifier of the variables created */, + int *clauseN /* OUT: number of stored clauses */, + int *rootStartLine /* OUT: line where root starts */ + ) +{ + int i, j, *list; + + list = DDDMP_ALLOC (int, ddMgr->size); + if (list == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + return (DDDMP_FAILURE); + } + + for (i=0; isize; j++) { + list[j] = 2; + } + + /* + * Set Starting Line for this Root + */ + + rootStartLine[i] = *clauseN + 1; + +#if DDDMP_DEBUG_CNF + fprintf (fp, "root NOT shared BDDs %d --> \n", i); +#endif + StoreCnfBestNotSharedRecur (ddMgr, f[i], 0, bddIds, cnfIds, fp, list, + clauseN, varMax); + +#if DDDMP_DEBUG_CNF + fprintf (fp, "root SHARED BDDs %d --> \n", i); +#endif + StoreCnfBestSharedRecur (ddMgr, Cudd_Regular (f[i]), bddIds, cnfIds, + fp, list, clauseN, varMax); + } + } + } + +#if DDDMP_DEBUG_CNF + fprintf (stdout, "###---> BDDs After the Storing Process:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + FREE (list); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Print Maxterm.] + + Description [Performs the recursive step of Print Maxterm. + Traverse a BDD a print out a cube in CNF format each time a terminal + node is reached. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static void +StoreCnfMaxtermByMaxtermRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *node /* IN: BDD to store */, + int *bddIds /* IN: BDD identifiers */, + int *cnfIds /* IN: corresponding CNF identifiers */, + FILE *fp /* IN: file pointer */, + int *list /* IN: temporary array to store cubes */, + int *clauseN /* OUT: number of stored clauses */, + int *varMax /* OUT: maximum identifier of the variables created */ + ) +{ + DdNode *N, *Nv, *Nnv; + int retValue, index; + + N = Cudd_Regular (node); + + /* + * Terminal case: Print one cube based on the current recursion + */ + + if (cuddIsConstant (N)) { + retValue = printCubeCnf (ddMgr, node, cnfIds, fp, list, varMax); + if (retValue == DDDMP_SUCCESS) { + fprintf (fp, "0\n"); + *clauseN = *clauseN + 1; + } + return; + } + + /* + * NON Terminal case: Recur + */ + + Nv = cuddT (N); + Nnv = cuddE (N); + if (Cudd_IsComplement (node)) { + Nv = Cudd_Not (Nv); + Nnv = Cudd_Not (Nnv); + } + index = N->index; + + /* + * StQ 06.05.2003 + * Perform the optimization: + * f = (a + b)' = (a') ^ (a + b') = (a') ^ (b') + * i.e., if the THEN node is the constant ZERO then that variable + * can be forgotten (list[index] = 2) for subsequent ELSE cubes + */ + if (cuddIsConstant (Cudd_Regular (Nv)) && Nv != ddMgr->one) { + list[index] = 2; + } else { + list[index] = 0; + } + StoreCnfMaxtermByMaxtermRecur (ddMgr, Nnv, bddIds, cnfIds, fp, list, + clauseN, varMax); + + /* + * StQ 06.05.2003 + * Perform the optimization: + * f = a ^ b = (a) ^ (a' + b) = (a) ^ (b) + * i.e., if the ELSE node is the constant ZERO then that variable + * can be forgotten (list[index] = 2) for subsequent THEN cubes + */ + if (cuddIsConstant (Cudd_Regular (Nnv)) && Nnv != ddMgr->one) { + list[index] = 2; + } else { + list[index] = 1; + } + StoreCnfMaxtermByMaxtermRecur (ddMgr, Nv, bddIds, cnfIds, fp, list, + clauseN, varMax); + list[index] = 2; + + return; +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Print Best on Not Shared + sub-BDDs.] + + Description [Performs the recursive step of Print Best on Not Shared + sub-BDDs, i.e., print out information for the nodes belonging to + BDDs not shared (whose root has just one incoming edge). + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +StoreCnfBestNotSharedRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *node /* IN: BDD to store */, + int idf /* IN: Id to store */, + int *bddIds /* IN: BDD identifiers */, + int *cnfIds /* IN: corresponding CNF identifiers */, + FILE *fp /* IN: file pointer */, + int *list /* IN: temporary array to store cubes */, + int *clauseN /* OUT: number of stored clauses */, + int *varMax /* OUT: maximum identifier of the variables created */ + ) +{ + DdNode *N, *Nv, *Nnv; + int index, retValue; + DdNode *one; + + one = ddMgr->one; + + N = Cudd_Regular (node); + + /* + * Terminal case or Already Visited: + * Print one cube based on the current recursion + */ + + if (cuddIsConstant (N)) { + retValue = printCubeCnf (ddMgr, node, cnfIds, fp, list, varMax); + if (retValue == DDDMP_SUCCESS) { + if (idf != 0) { + fprintf (fp, "%d ", idf); + } + fprintf (fp, "0\n"); + *varMax = GET_MAX (*varMax, abs(idf)); + *clauseN = *clauseN + 1; + } + return (DDDMP_SUCCESS); + } + + /* + * Shared Sub-Tree: Print Cube + */ + + index = DddmpReadNodeIndexCnf (N); + if (index > 0) { + if (idf != 0) { + fprintf (fp, "%d ", idf); + } + if (Cudd_IsComplement (node)) { + retValue = fprintf (fp, "-%d ", index); + } else { + retValue = fprintf (fp, "%d ", index); + } + retValue = printCubeCnf (ddMgr, node, cnfIds, fp, list, varMax); + fprintf (fp, "0\n"); + *varMax = GET_MAX (*varMax, abs(index)); + *clauseN = *clauseN + 1; + return (DDDMP_SUCCESS); + } + + /* + * NON Terminal case: Recur + */ + + Nv = cuddT (N); + Nnv = cuddE (N); + if (Cudd_IsComplement (node)) { + Nv = Cudd_Not (Nv); + Nnv = Cudd_Not (Nnv); + } + index = N->index; + + /* + * StQ 06.05.2003 + * Perform the optimization: + * f = (a + b)' = (a') ^ (a + b') = (a') ^ (b') + * i.e., if the THEN node is the constant ZERO then that variable + * can be forgotten (list[index] = 2) for subsequent ELSE cubes + */ + if (cuddIsConstant (Cudd_Regular (Nv)) && Nv != ddMgr->one) { + list[index] = 2; + } else { + list[index] = 0; + } + StoreCnfBestNotSharedRecur (ddMgr, Nnv, idf, bddIds, cnfIds, fp, list, + clauseN, varMax); + + /* + * StQ 06.05.2003 + * Perform the optimization: + * f = a ^ b = (a) ^ (a' + b) = (a) ^ (b) + * i.e., if the ELSE node is the constant ZERO then that variable + * can be forgotten (list[index] = 2) for subsequent THEN cubes + */ + if (cuddIsConstant (Cudd_Regular (Nnv)) && Nnv != ddMgr->one) { + list[index] = 2; + } else { + list[index] = 1; + } + StoreCnfBestNotSharedRecur (ddMgr, Nv, idf, bddIds, cnfIds, fp, list, + clauseN, varMax); + list[index] = 2; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Print Best on Shared + sub-BDDs. + ] + + Description [Performs the recursive step of Print Best on Not Shared + sub-BDDs, i.e., print out information for the nodes belonging to + BDDs not shared (whose root has just one incoming edge). + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +StoreCnfBestSharedRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *node /* IN: BDD to store */, + int *bddIds /* IN: BDD identifiers */, + int *cnfIds /* IN: corresponding CNF identifiers */, + FILE *fp /* IN: file pointer */, + int *list /* IN: temporary array to store cubes */, + int *clauseN /* OUT: number of stored clauses */, + int *varMax /* OUT: maximum identifier of the variables created */ + ) +{ + DdNode *nodeThen, *nodeElse; + int i, idf, index; + DdNode *one; + + one = ddMgr->one; + + Dddmp_Assert (node==Cudd_Regular(node), + "Inverted Edge during Shared Printing."); + + /* If constant, nothing to do. */ + if (cuddIsConstant (node)) { + return (DDDMP_SUCCESS); + } + + /* If already visited, nothing to do. */ + if (DddmpVisitedCnf (node)) { + return (DDDMP_SUCCESS); + } + + /* + * Shared Sub-Tree: Print Cube + */ + + idf = DddmpReadNodeIndexCnf (node); + if (idf > 0) { + /* Cheat the Recur Function about the Index of the Current Node */ + DddmpWriteNodeIndexCnf (node, 0); + +#if DDDMP_DEBUG_CNF + fprintf (fp, "Else of XNOR\n"); +#endif + for (i=0; isize; i++) { + list[i] = 2; + } + StoreCnfBestNotSharedRecur (ddMgr, Cudd_Not (node), idf, bddIds, cnfIds, + fp, list, clauseN, varMax); + +#if DDDMP_DEBUG_CNF + fprintf (fp, "Then of XNOR\n"); +#endif + for (i=0; isize; i++) { + list[i] = 2; + } + StoreCnfBestNotSharedRecur (ddMgr, node, -idf, bddIds, cnfIds, + fp, list, clauseN, varMax); + + /* Set Back Index of Current Node */ + DddmpWriteNodeIndexCnf (node, idf); + } + + /* Mark node as visited. */ + DddmpSetVisitedCnf (node); + + /* + * Recur + */ + + nodeThen = cuddT (node); + nodeElse = cuddE (node); + index = node->index; + + StoreCnfBestSharedRecur (ddMgr, Cudd_Regular (nodeThen), bddIds, cnfIds, + fp, list, clauseN, varMax); + StoreCnfBestSharedRecur (ddMgr, Cudd_Regular (nodeElse), bddIds, cnfIds, + fp, list, clauseN, varMax); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Print One Cube in CNF Format.] + + Description [Print One Cube in CNF Format. + Return DDDMP_SUCCESS if something is printed out, DDDMP_FAILURE + is nothing is printed out. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +printCubeCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *node /* IN: BDD to store */, + int *cnfIds /* IN: CNF identifiers */, + FILE *fp /* IN: file pointer */, + int *list /* IN: temporary array to store cubes */, + int *varMax /* OUT: maximum identifier of the variables created */ + ) +{ + int i, retValue; + DdNode *one; + + retValue = DDDMP_FAILURE; + one = ddMgr->one; + + if (node != one) { + for (i=0; isize; i++) { + if (list[i] == 0) { + retValue = DDDMP_SUCCESS; + (void) fprintf (fp, "%d ", cnfIds[i]); + *varMax = GET_MAX(*varMax, cnfIds[i]); + } else { + if (list[i] == 1) { + retValue = DDDMP_SUCCESS; + (void) fprintf (fp, "-%d ", cnfIds[i]); + *varMax = GET_MAX(*varMax, cnfIds[i]); + } + } + } + } + + return (retValue); +} + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreMisc.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreMisc.c new file mode 100644 index 000000000..2dc18f046 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpStoreMisc.c @@ -0,0 +1,1641 @@ +/**CFile********************************************************************** + + FileName [dddmpStoreMisc.c] + + PackageName [dddmp] + + Synopsis [Functions to write out bdds to file in prefixed + and in Blif form.] + + Description [Functions to write out bdds to file. + BDDs are represended on file in text format. + Each node is stored as a multiplexer in a prefix notation format for + the prefix notation file or in PLA format for the blif file. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpCuddDdArrayStorePrefix(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp); +static int DddmpCuddDdArrayStorePrefixBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp); +static int DddmpCuddDdArrayStorePrefixStep(DdManager * ddMgr, DdNode * f, FILE * fp, st_table * visited, char ** names); +static int DddmpCuddDdArrayStoreBlif(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp); +static int DddmpCuddDdArrayStoreBlifBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp); +static int DddmpCuddDdArrayStoreBlifStep(DdManager *ddMgr, DdNode *f, FILE *fp, st_table *visited, char **names); +static int DddmpCuddDdArrayStoreSmv(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp); +static int DddmpCuddDdArrayStoreSmvBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp); +static int DddmpCuddDdArrayStoreSmvStep(DdManager * ddMgr, DdNode * f, FILE * fp, st_table * visited, char ** names); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a prefix notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddStore] + +******************************************************************************/ + +int +Dddmp_cuddBddStorePrefix ( + DdManager *ddMgr /* IN: DD Manager */, + int nRoots /* IN: Number of BDD roots */, + DdNode *f /* IN: BDD root to be stored */, + char **inputNames /* IN: Array of variable names */, + char **outputNames /* IN: Array of root names */, + char *modelName /* IN: Model Name */, + char *fileName /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStorePrefix (ddMgr, 1, tmpArray, + inputNames, outputNames, modelName, fileName, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a prefix notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddArrayStore] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStorePrefix ( + DdManager *ddMgr /* IN: DD Manager */, + int nroots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of BDD roots to be stored */, + char **inputNames /* IN: array of variable names (or NULL) */, + char **outputNames /* IN: array of root names (or NULL) */, + char *modelName /* IN: Model Name */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + int fileToClose = 0; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + retValue = DddmpCuddDdArrayStorePrefix (ddMgr, nroots, f, + inputNames, outputNames, modelName, fp); + + if (fileToClose) { + fclose (fp); + } + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); + + failure: + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a Blif/Exlif notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBlif. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddStorePrefix] + +******************************************************************************/ + +int +Dddmp_cuddBddStoreBlif ( + DdManager *ddMgr /* IN: DD Manager */, + int nRoots /* IN: Number of BDD roots */, + DdNode *f /* IN: BDD root to be stored */, + char **inputNames /* IN: Array of variable names */, + char **outputNames /* IN: Array of root names */, + char *modelName /* IN: Model Name */, + char *fileName /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStoreBlif (ddMgr, 1, tmpArray, + inputNames, outputNames, modelName, fileName, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a Blif/Exlif notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBLif. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddArrayStorePrefix] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStoreBlif ( + DdManager *ddMgr /* IN: DD Manager */, + int nroots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of BDD roots to be stored */, + char **inputNames /* IN: array of variable names (or NULL) */, + char **outputNames /* IN: array of root names (or NULL) */, + char *modelName /* IN: Model Name */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + int fileToClose = 0; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + retValue = DddmpCuddDdArrayStoreBlif (ddMgr, nroots, f, + inputNames, outputNames, modelName, fp); + + if (fileToClose) { + fclose (fp); + } + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); + + failure: + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a prefix notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddStore] + +******************************************************************************/ + +int +Dddmp_cuddBddStoreSmv ( + DdManager *ddMgr /* IN: DD Manager */, + int nRoots /* IN: Number of BDD roots */, + DdNode *f /* IN: BDD root to be stored */, + char **inputNames /* IN: Array of variable names */, + char **outputNames /* IN: Array of root names */, + char *modelName /* IN: Model Name */, + char *fileName /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStoreSmv (ddMgr, 1, tmpArray, + inputNames, outputNames, modelName, fileName, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a prefix notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddArrayStore] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStoreSmv ( + DdManager *ddMgr /* IN: DD Manager */, + int nroots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of BDD roots to be stored */, + char **inputNames /* IN: array of variable names (or NULL) */, + char **outputNames /* IN: array of root names (or NULL) */, + char *modelName /* IN: Model Name */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + int fileToClose = 0; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + retValue = DddmpCuddDdArrayStoreSmv (ddMgr, nroots, f, + inputNames, outputNames, modelName, fp); + + if (fileToClose) { + fclose (fp); + } + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); + + failure: + return (DDDMP_FAILURE); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Internal function to writes a dump file representing the + argument BDD in a prefix notation.] + + Description [One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + Comments (COMMENT) are added at the beginning of the description to + describe inputs and outputs of the design. + A buffer (BUF) is add on the output to cope with complemented functions. + ] + + SideEffects [None] + + SeeAlso [DddmpCuddDdArrayStoreBlif] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStorePrefix ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + char *modelName /* IN: Model name (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nVars = ddMgr->size; + int retValue; + int i; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int, nVars); + if (sorted == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure); + } + for (i = 0; i < nVars; i++) { + sorted[i] = 0; + } + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(ddMgr,f,n); + Dddmp_CheckAndGotoLabel (support==NULL, + "Error in function Cudd_VectorSupport.", failure); + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(ddMgr,support); + /* so that we do not try to free it in case of failure */ + support = NULL; + + /* Write the header (.model .inputs .outputs). */ + if (modelName == NULL) { + retValue = fprintf (fp, "(COMMENT - model name: Unknown )\n"); + } else { + retValue = fprintf (fp, "(COMMENT - model name: %s )\n", modelName); + } + if (retValue == EOF) { + return(0); + } + + retValue = fprintf(fp, "(COMMENT - input names: "); + if (retValue == EOF) { + return(0); + } + /* Write the input list by scanning the support array. */ + for (i = 0; i < nVars; i++) { + if (sorted[i]) { + if (inputNames == NULL) { + retValue = fprintf(fp," inNode%d", i); + } else { + retValue = fprintf(fp," %s", inputNames[i]); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + } + FREE(sorted); + sorted = NULL; + retValue = fprintf(fp, " )\n"); + if (retValue == EOF) { + return(0); + } + + /* Write the .output line. */ + retValue = fprintf(fp,"(COMMENT - output names: "); + if (retValue == EOF) { + return(0); + } + for (i = 0; i < n; i++) { + if (outputNames == NULL) { + retValue = fprintf (fp," outNode%d", i); + } else { + retValue = fprintf (fp," %s", outputNames[i]); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + retValue = fprintf(fp, " )\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + + retValue = DddmpCuddDdArrayStorePrefixBody (ddMgr, n, f, inputNames, + outputNames, fp); + Dddmp_CheckAndGotoLabel (retValue==0, + "Error in function DddmpCuddDdArrayStorePrefixBody.", failure); + + return(1); + +failure: + if (sorted != NULL) { + FREE(sorted); + } + if (support != NULL) { + Cudd_RecursiveDeref(ddMgr,support); + } + return(0); +} + +/**Function******************************************************************** + + Synopsis [Internal function to writes a dump file representing the + argument BDD in a prefix notation. Writes the body of the file.] + + Description [One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + ] + + SideEffects [None] + + SeeAlso [DddmpCuddDdArrayStoreBlif] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStorePrefixBody ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + st_table *visited = NULL; + int retValue; + int i; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + Dddmp_CheckAndGotoLabel (visited==NULL, + "Error if function st_init_table.", failure); + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + retValue = DddmpCuddDdArrayStorePrefixStep (ddMgr, Cudd_Regular(f[i]), + fp, visited, inputNames); + Dddmp_CheckAndGotoLabel (retValue==0, + "Error if function DddmpCuddDdArrayStorePrefixStep.", failure); + } + + /* To account for the possible complement on the root, + ** we put either a buffer or an inverter at the output of + ** the multiplexer representing the top node. + */ + for (i=0; iindex]); + } else { + retValue = fprintf(fp, "inNode%d ", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + retValue = fprintf (fp, "node%lx) (AND (NOT ", + (unsigned long) T / (unsigned long) sizeof(DdNode)); +#else + retValue = fprintf (fp, "node%x) (AND (NOT ", + (unsigned) T / (unsigned) sizeof(DdNode)); +#endif + if (retValue == EOF) { + return(0); + } + + if (names != NULL) { + retValue = fprintf (fp, "%s", names[f->index]); + } else { + retValue = fprintf (fp, "inNode%d", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf (fp, ") (NOT node%lx)))\n", + (unsigned long) E / (unsigned long) sizeof(DdNode)); + } else { + retValue = fprintf (fp, ") node%lx))\n", + (unsigned long) E / (unsigned long) sizeof(DdNode)); + } +#else + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf (fp, ") (NOT node%x)))\n", + (unsigned) E / (unsigned) sizeof(DdNode)); + } else { + retValue = fprintf (fp, ") node%x))\n", + (unsigned) E / (unsigned) sizeof(DdNode)); + } +#endif + + if (retValue == EOF) { + return(0); + } else { + return(1); + } +} + +/**Function******************************************************************** + + Synopsis [Writes a blif file representing the argument BDDs.] + + Description [Writes a blif file representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). + DddmpCuddDdArrayStoreBlif does not close the file: This is the + caller responsibility. + DddmpCuddDdArrayStoreBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for outputNames. + It prefixes the string "NODE" to each nome to have "regular" names + for each elements. + ] + + SideEffects [None] + + SeeAlso [DddmpCuddDdArrayStoreBlifBody,Cudd_DumpBlif] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStoreBlif ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + char *modelName /* IN: Model name (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nVars = ddMgr->size; + int retValue; + int i; + + /* Build a bit array with the support of f. */ + sorted = ALLOC (int, nVars); + if (sorted == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure); + } + for (i = 0; i < nVars; i++) { + sorted[i] = 0; + } + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(ddMgr,f,n); + Dddmp_CheckAndGotoLabel (support==NULL, + "Error in function Cudd_VectorSupport.", failure); + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(ddMgr,support); + support = NULL; + /* so that we do not try to free it in case of failure */ + + /* Write the header (.model .inputs .outputs). */ + if (modelName == NULL) { + retValue = fprintf(fp,".model DD\n.inputs"); + } else { + retValue = fprintf(fp,".model %s\n.inputs", modelName); + } + if (retValue == EOF) { + return(0); + } + + /* Write the input list by scanning the support array. */ + for (i = 0; i < nVars; i++) { + if (sorted[i]) { + if (inputNames == NULL || (inputNames[i] == NULL)) { + retValue = fprintf(fp," inNode%d", i); + } else { + retValue = fprintf(fp," %s", inputNames[i]); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + } + FREE(sorted); + sorted = NULL; + + /* Write the .output line. */ + retValue = fprintf(fp,"\n.outputs"); + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + for (i = 0; i < n; i++) { + if (outputNames == NULL || (outputNames[i] == NULL)) { + retValue = fprintf(fp," outNode%d", i); + } else { + retValue = fprintf(fp," %s", outputNames[i]); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + retValue = fprintf(fp,"\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + + retValue = DddmpCuddDdArrayStoreBlifBody(ddMgr, n, f, inputNames, + outputNames, fp); + Dddmp_CheckAndGotoLabel (retValue==0, + "Error if function DddmpCuddDdArrayStoreBlifBody.", failure); + + /* Write trailer and return. */ + retValue = fprintf (fp, ".end\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + + return(1); + +failure: + if (sorted != NULL) { + FREE(sorted); + } + if (support != NULL) { + Cudd_RecursiveDeref(ddMgr,support); + } + + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Writes a blif body representing the argument BDDs.] + + Description [Writes a blif body representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). + DddmpCuddDdArrayStoreBlif does not close the file: This is the + caller responsibility. + DddmpCuddDdArrayStoreBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inputNames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for outputNames. This function prints out only + .names part. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStoreBlifBody ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + st_table *visited = NULL; + int retValue; + int i; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + Dddmp_CheckAndGotoLabel (visited==NULL, + "Error if function st_init_table.", failure); + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + retValue = DddmpCuddDdArrayStoreBlifStep (ddMgr, Cudd_Regular(f[i]), + fp, visited, inputNames); + Dddmp_CheckAndGotoLabel (retValue==0, + "Error if function DddmpCuddDdArrayStoreBlifStep.", failure); + } + + /* + * To account for the possible complement on the root, + * we put either a buffer or an inverter at the output of + * the multiplexer representing the top node. + */ + + for (i = 0; i < n; i++) { + if (outputNames == NULL) { + retValue = fprintf(fp, +#if SIZEOF_VOID_P == 8 + ".names node%lx outNode%d\n", + (unsigned long) f[i] / (unsigned long) sizeof(DdNode), i); +#else + ".names node%x outNode%d\n", + (unsigned) f[i] / (unsigned) sizeof(DdNode), i); +#endif + } else { + retValue = fprintf(fp, +#if SIZEOF_VOID_P == 8 + ".names node%lx %s\n", + (unsigned long) f[i] / (unsigned long) sizeof(DdNode), outputNames[i]); +#else + ".names node%x %s\n", + (unsigned) f[i] / (unsigned) sizeof(DdNode), outputNames[i]); +#endif + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + if (Cudd_IsComplement(f[i])) { + retValue = fprintf(fp,"0 1\n"); + } else { + retValue = fprintf(fp,"1 1\n"); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + + st_free_table(visited); + return(1); + +failure: + if (visited != NULL) { + st_free_table(visited); + } + return(0); +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of DddmpCuddDdArrayStoreBlif.] + + Description [Performs the recursive step of DddmpCuddDdArrayStoreBlif. + Traverses the BDD f and writes a multiplexer-network description to + the file pointed by fp in blif format. + f is assumed to be a regular pointer and DddmpCuddDdArrayStoreBlifStep + guarantees this assumption in the recursive calls. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStoreBlifStep ( + DdManager *ddMgr, + DdNode *f, + FILE *fp, + st_table *visited, + char **names + ) +{ + DdNode *T, *E; + int retValue; + +#ifdef DDDMP_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + /* If already visited, nothing to do. */ + if (st_is_member(visited, (char *) f) == 1) { + return(1); + } + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) { + return(0); + } + + /* Mark node as visited. */ + if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) { + return(0); + } + + /* Check for special case: If constant node, generate constant 1. */ + if (f == DD_ONE(ddMgr)) { +#if SIZEOF_VOID_P == 8 + retValue = fprintf(fp, ".names node%lx\n1\n", + (unsigned long) f / (unsigned long) sizeof(DdNode)); +#else + retValue = fprintf(fp, ".names node%x\n1\n", + (unsigned) f / (unsigned) sizeof(DdNode)); +#endif + if (retValue == EOF) { + return(0); + } else { + return(1); + } + } + + /* Check whether this is an ADD. We deal with 0-1 ADDs, but not + ** with the general case. + */ + if (f == DD_ZERO(ddMgr)) { +#if SIZEOF_VOID_P == 8 + retValue = fprintf(fp, ".names node%lx\n", + (unsigned long) f / (unsigned long) sizeof(DdNode)); +#else + retValue = fprintf(fp, ".names node%x\n", + (unsigned) f / (unsigned) sizeof(DdNode)); +#endif + if (retValue == EOF) { + return(0); + } else { + return(1); + } + } + if (cuddIsConstant(f)) { + return(0); + } + + /* Recursive calls. */ + T = cuddT(f); + retValue = DddmpCuddDdArrayStoreBlifStep(ddMgr,T,fp,visited,names); + if (retValue != 1) return(retValue); + E = Cudd_Regular(cuddE(f)); + retValue = DddmpCuddDdArrayStoreBlifStep(ddMgr,E,fp,visited,names); + if (retValue != 1) return(retValue); + + /* Write multiplexer taking complement arc into account. */ + if (names != NULL) { + retValue = fprintf(fp,".names %s", names[f->index]); + } else { + retValue = fprintf(fp,".names inNode%d", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf(fp," node%lx node%lx node%lx\n11- 1\n0-0 1\n", + (unsigned long) T / (unsigned long) sizeof(DdNode), + (unsigned long) E / (unsigned long) sizeof(DdNode), + (unsigned long) f / (unsigned long) sizeof(DdNode)); + } else { + retValue = fprintf(fp," node%lx node%lx node%lx\n11- 1\n0-1 1\n", + (unsigned long) T / (unsigned long) sizeof(DdNode), + (unsigned long) E / (unsigned long) sizeof(DdNode), + (unsigned long) f / (unsigned long) sizeof(DdNode)); + } +#else + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf(fp," node%x node%x node%x\n11- 1\n0-0 1\n", + (unsigned) T / (unsigned) sizeof(DdNode), + (unsigned) E / (unsigned) sizeof(DdNode), + (unsigned) f / (unsigned) sizeof(DdNode)); + } else { + retValue = fprintf(fp," node%x node%x node%x\n11- 1\n0-1 1\n", + (unsigned) T / (unsigned) sizeof(DdNode), + (unsigned) E / (unsigned) sizeof(DdNode), + (unsigned) f / (unsigned) sizeof(DdNode)); + } +#endif + if (retValue == EOF) { + return(0); + } else { + return(1); + } +} + +/**Function******************************************************************** + + Synopsis [Internal function to writes a dump file representing the + argument BDD in a SMV notation.] + + Description [One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + Comments (COMMENT) are added at the beginning of the description to + describe inputs and outputs of the design. + A buffer (BUF) is add on the output to cope with complemented functions. + ] + + SideEffects [None] + + SeeAlso [DddmpCuddDdArrayStoreBlif] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStoreSmv ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + char *modelName /* IN: Model name (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nVars = ddMgr->size; + int retValue; + int i; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int, nVars); + if (sorted == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure); + } + for (i = 0; i < nVars; i++) { + sorted[i] = 0; + } + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(ddMgr,f,n); + Dddmp_CheckAndGotoLabel (support==NULL, + "Error in function Cudd_VectorSupport.", failure); + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(ddMgr,support); + /* so that we do not try to free it in case of failure */ + support = NULL; + + /* Write the header */ + if (modelName == NULL) { + retValue = fprintf (fp, "MODULE main -- Unknown\n"); + } else { + retValue = fprintf (fp, "MODULE main -- %s\n", modelName); + } + if (retValue == EOF) { + return(0); + } + + retValue = fprintf(fp, "IVAR\n"); + if (retValue == EOF) { + return(0); + } + + /* Write the input list by scanning the support array. */ + for (i=0; iindex]); + } else { + retValue = fprintf(fp, "inNode%d ", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + retValue = fprintf (fp, "& node%lx | ", + (unsigned long) T / (unsigned long) sizeof(DdNode)); +#else + retValue = fprintf (fp, "& node%x | ", + (unsigned) T / (unsigned) sizeof(DdNode)); +#endif + if (retValue == EOF) { + return(0); + } + + if (names != NULL) { + retValue = fprintf (fp, "!%s ", names[f->index]); + } else { + retValue = fprintf (fp, "!inNode%d ", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf (fp, "& !node%lx\n", + (unsigned long) E / (unsigned long) sizeof(DdNode)); + } else { + retValue = fprintf (fp, "& node%lx\n", + (unsigned long) E / (unsigned long) sizeof(DdNode)); + } +#else + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf (fp, "& !node%x\n", + (unsigned) E / (unsigned) sizeof(DdNode)); + } else { + retValue = fprintf (fp, "& node%x\n", + (unsigned) E / (unsigned) sizeof(DdNode)); + } +#endif + + if (retValue == EOF) { + return(0); + } else { + return(1); + } +} + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/dddmpUtil.c b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpUtil.c new file mode 100644 index 000000000..feff43943 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/dddmpUtil.c @@ -0,0 +1,436 @@ +/**CFile********************************************************************** + + FileName [dddmpUtil.c] + + PackageName [dddmp] + + Synopsis [Util Functions for the dddmp package] + + Description [Functions to manipulate arrays.] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [String compare for qsort] + + Description [String compare for qsort] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +int +QsortStrcmp( + const void *ps1 /* IN: pointer to the first string */, + const void *ps2 /* IN: pointer to the second string */ + ) +{ + return (strcmp (*((char**)ps1),*((char **)ps2))); +} + +/**Function******************************************************************** + + Synopsis [Performs binary search of a name within a sorted array] + + Description [Binary search of a name within a sorted array of strings. + Used when matching names of variables. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +int +FindVarname ( + char *name /* IN: name to look for */, + char **array /* IN: search array */, + int n /* IN: size of the array */ + ) +{ + int d, m, u, t; + + d = 0; u = n-1; + + while (u>=d) { + m = (u+d)/2; + t=strcmp(name,array[m]); + if (t==0) + return m; + if (t<0) + u=m-1; + else + d=m+1; + } + + return (-1); +} + + +/**Function******************************************************************** + + Synopsis [Duplicates a string] + + Description [Allocates memory and copies source string] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +char * +DddmpStrDup ( + char *str /* IN: string to be duplicated */ + ) +{ + char *str2; + + str2 = DDDMP_ALLOC(char,strlen(str)+1); + if (str2 != NULL) { + strcpy (str2,str); + } + + return (str2); +} + +/**Function******************************************************************** + + Synopsis [Duplicates an array of strings] + + Description [Allocates memory and copies source array] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +char ** +DddmpStrArrayDup ( + char **array /* IN: array of strings to be duplicated */, + int n /* IN: size of the array */ + ) +{ + char **array2; + int i; + + array2 = DDDMP_ALLOC(char *, n); + if (array2 == NULL) { + (void) fprintf (stderr, "DddmpStrArrayDup: Error allocating memory\n"); + fflush (stderr); + return NULL; + } + + /* + * initialize all slots to NULL for fair FREEing in case of failure + */ + + for (i=0; i +Command Documentation + + +

                  Command Documentation


                  +
                  +
                  +Last updated on 1040218 17h15 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/commands.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/commands.html new file mode 100644 index 000000000..2609aafcd --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/commands.html @@ -0,0 +1,12 @@ + +Command Documentation + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/credit.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/credit.html new file mode 100644 index 000000000..868097be4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/credit.html @@ -0,0 +1,15 @@ + +Credit + + + + + + + +
                  + Command Documentation + Package Documentation Generated by + the Ext system
                  + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-A4.ps b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-A4.ps new file mode 100644 index 000000000..7c1010a10 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-A4.ps @@ -0,0 +1,1261 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software +%%Title: dddmp-2.0.dvi +%%Pages: 10 +%%PageOrder: Ascend +%%BoundingBox: 0 0 596 842 +%%DocumentFonts: Times-Bold Times-Roman Courier Times-Italic Helvetica +%%DocumentPaperSizes: a4 +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -t a4 -f dddmp-2.0 +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2002.12.11:0557 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", +% version = "0.6", +% date = "22 June 1996", +% filename = "8r.enc", +% email = "kb@@mail.tug.org", +% address = "135 Center Hill Rd. // Plymouth, MA 02360", +% codetable = "ISO/ASCII", +% checksum = "119 662 4424", +% docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." +% @} +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both ASCII and Windows. +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there down to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics +exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub +dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} +ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict +end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ +dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 +roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def +dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} +if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} +def end + +%%EndProcSet +%%BeginProcSet: special.pro +%! +TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N +/vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N +/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N +/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ +/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho +X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B +/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ +/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known +{userdict/md get type/dicttype eq{userdict begin md length 10 add md +maxlength ge{/md md dup length 20 add dict copy def}if end md begin +/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S +atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ +itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll +transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll +curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf +pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} +if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 +-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 +get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip +yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub +neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ +noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop +90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get +neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr +1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr +2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 +-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S +TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ +Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale +}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState +save N userdict maxlength dict begin/magscale true def normalscale +currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts +/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x +psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx +psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub +TR/showpage{}N/erasepage{}N/copypage{}N/p 3 def @MacSetUp}N/doclip{ +psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 +roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath +moveto}N/endTexFig{end psf$SavedState restore}N/@beginspecial{SDict +begin/SpecialSave save N gsave normalscale currentpoint TR +@SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{ +CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto +closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx +sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR +}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse +CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury +lineto closepath clip}if/showpage{}N/erasepage{}N/copypage{}N newpath}N +/@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{end} +repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N +/@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX +currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY +moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X +/yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0 +1 startangle endangle arc savematrix setmatrix}N end + +%%EndProcSet +TeXDict begin 39158280 55380996 1000 600 600 (dddmp-2.0.dvi) +@start /Fa 143[55 1[55 7[28 2[50 99[{TeXBase1Encoding ReEncodeFont}4 +99.6264 /Helvetica rf +%DVIPSBitmapFont: Fb cmr12 12 3 +/Fb 3 53 df<14FF010713E090381F81F890383E007C01FC133F4848EB1F8049130F4848 +EB07C04848EB03E0A2000F15F0491301001F15F8A2003F15FCA390C8FC4815FEA54815FF +B3A46C15FEA56D1301003F15FCA3001F15F8A26C6CEB03F0A36C6CEB07E0000315C06D13 +0F6C6CEB1F806C6CEB3F00013E137C90381F81F8903807FFE0010090C7FC28447CC131> +48 D<143014F013011303131F13FFB5FC13E713071200B3B3B0497E497E007FB6FCA320 +4278C131>I52 D E +%EndDVIPSBitmapFont +/Fc 64[50 29[39 12[55 55 25[44 44 66 44 50 28 39 39 1[50 +50 50 72 28 44 1[28 50 50 28 44 50 44 50 50 10[61 2[50 +4[66 83 55 2[33 2[61 1[72 66 61 61 15[50 2[25 33 25 2[33 +33 37[50 2[{TeXBase1Encoding ReEncodeFont}45 99.6264 +/Times-Italic rf +%DVIPSBitmapFont: Fd cmmi12 12 3 +/Fd 3 103 df60 D<127012FCB4FCEA7FC0EA1FF0EA +07FCEA01FF38007FC0EB1FF0EB07FE903801FF809038007FE0EC1FF8EC03FE913800FF80 +ED3FE0ED0FF8ED03FF030013C0EE3FF0EE0FFCEE01FF9338007FC0EF1FF0EF07FCEF01FF +9438007FC0F01FE0A2F07FC0943801FF00EF07FCEF1FF0EF7FC04C48C7FCEE0FFCEE3FF0 +EEFFC0030390C8FCED0FF8ED3FE0EDFF80DA03FEC9FCEC1FF8EC7FE0903801FF80D907FE +CAFCEB1FF0EB7FC04848CBFCEA07FCEA1FF0EA7FC048CCFC12FC12703B3878B44C>62 +D102 +D E +%EndDVIPSBitmapFont +/Fe 134[42 2[42 42 23 32 28 1[42 42 42 65 23 2[23 42 +42 28 37 42 1[42 37 12[51 10[28 4[60 1[55 19[21 28 21 +44[{TeXBase1Encoding ReEncodeFont}26 83.022 /Times-Roman +rf +%DVIPSBitmapFont: Ff cmr7 7 2 +/Ff 2 51 df<13381378EA01F8121F12FE12E01200B3AB487EB512F8A215267BA521>49 +D<13FF000313E0380E03F0381800F848137C48137E00787F12FC6CEB1F80A4127CC7FC15 +005C143E147E147C5C495A495A5C495A010EC7FC5B5B903870018013E0EA018039030003 +0012065A001FB5FC5A485BB5FCA219267DA521>I E +%EndDVIPSBitmapFont +/Fg 103[60 26[60 1[60 60 60 60 60 60 60 60 60 60 60 60 +60 60 60 60 2[60 60 60 60 60 60 60 60 60 3[60 1[60 3[60 +60 1[60 60 1[60 60 1[60 60 3[60 1[60 1[60 60 60 1[60 +60 1[60 1[60 1[60 60 60 60 60 60 60 60 60 60 60 60 60 +60 60 5[60 38[{TeXBase1Encoding ReEncodeFont}62 99.6264 +/Courier rf +%DVIPSBitmapFont: Fh cmr8 8 2 +/Fh 2 51 df<130C133C137CEA03FC12FFEAFC7C1200B3B113FE387FFFFEA2172C7AAB23 +>49 DI E +%EndDVIPSBitmapFont +/Fi 105[50 28[50 50 2[55 33 39 44 1[55 50 55 83 28 2[28 +1[50 33 44 55 44 55 50 10[72 1[66 55 3[78 72 94 66 3[78 +1[61 66 72 72 66 72 13[50 50 50 1[28 25 33 45[{ +TeXBase1Encoding ReEncodeFont}40 99.6264 /Times-Bold +rf /Fj 139[40 1[53 1[66 60 66 100 33 2[33 3[53 3[60 23[47 +2[73 18[60 60 60 2[30 46[{TeXBase1Encoding ReEncodeFont}16 +119.552 /Times-Bold rf +%DVIPSBitmapFont: Fk cmsy10 12 1 +/Fk 1 16 df<49B4FC010F13E0013F13F8497F48B6FC4815804815C04815E04815F0A248 +15F8A24815FCA3B712FEA96C15FCA36C15F8A26C15F0A26C15E06C15C06C15806C15006C +6C13FC6D5B010F13E0010190C7FC27277BAB32>15 D E +%EndDVIPSBitmapFont +/Fl 64[44 42[44 44 24[44 50 50 72 50 50 28 39 33 50 50 +50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 6[61 1[72 +94 72 72 61 55 66 72 55 72 72 89 61 1[39 33 72 72 55 +61 72 66 66 72 3[56 1[28 28 50 50 50 50 50 50 50 50 50 +50 28 25 33 25 2[33 33 36[55 55 2[{TeXBase1Encoding ReEncodeFont}74 +99.6264 /Times-Roman rf +%DVIPSBitmapFont: Fm cmsy10 14.4 2 +/Fm 2 104 df102 +DI E +%EndDVIPSBitmapFont +/Fn 105[60 27[53 4[60 33 47 40 60 60 60 60 93 33 2[33 +1[60 40 53 60 53 60 53 7[86 4[73 66 1[86 66 3[73 2[40 +1[86 1[73 86 80 1[86 110 5[33 60 4[60 1[60 60 60 1[30 +40 30 44[{TeXBase1Encoding ReEncodeFont}42 119.552 /Times-Roman +rf /Fo 136[104 1[80 48 56 64 1[80 72 80 120 40 80 1[40 +1[72 1[64 80 64 80 72 12[96 80 104 1[88 1[104 135 3[56 +2[88 1[104 104 96 104 6[48 1[72 72 72 72 72 72 72 72 +72 1[36 46[{TeXBase1Encoding ReEncodeFont}41 143.462 +/Times-Bold rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin +%%BeginPaperSize: a4 +a4 +%%EndPaperSize + +%%EndSetup +%%Page: 1 1 +1 0 bop 472 600 a Fo(DDDMP:)35 b(Decision)f(Diagram)f(DuMP)j(package) +1480 830 y(Release)e(2.0)462 1230 y Fn(Gianpiero)c(Cabodi)2402 +1232 y(Stef)o(ano)g(Quer)1316 1506 y(Politecnico)g(di)g(T)-10 +b(orino)1024 1656 y(Dip.)30 b(di)g(Automatica)g(e)g(Informatica)1119 +1805 y(Corso)f(Duca)h(de)n(gli)g(Abruzzi)g(24)1277 1955 +y(I\22610129)e(T)-5 b(urin,)29 b(IT)-11 b(AL)f(Y)1038 +2104 y(E-mail:)38 b Fm(f)p Fn(cabodi,quer)p Fm(g)p Fn(@polito.it)-189 +2614 y Fo(1)143 b(Intr)m(oduction)-189 2837 y Fl(The)27 +b(DDDMP)h(package)f(de\002nes)h(formats)f(and)g(rules)g(to)g(store)g +(DD)g(on)g(\002le.)39 b(More)27 b(in)g(particular)g(it)g(contains)g(a) +-189 2958 y(set)e(of)g(functions)e(to)i(dump)e(\(store)i(and)g(load\))g +(DDs)f(and)h(DD)g(forests)f(on)h(\002le)g(in)f(dif)n(ferent)h(formats.) +47 3078 y(In)30 b(the)g(present)g(implementation,)f(BDDs)h(\(R)l +(OBDDs\))h(and)f(ADD)g(\(Algebraic)g(Decision)g(Diagram\))g(of)-189 +3199 y(the)g(CUDD)g(package)g(\(v)o(ersion)f(2.3.0)g(or)h(higher\))g +(are)g(supported.)45 b(These)30 b(structures)f(can)h(be)g(represented)g +(on)-189 3319 y(\002les)25 b(either)g(in)f(te)o(xt,)g(binary)-6 +b(,)24 b(or)h(CNF)g(\(DIMA)l(CS\))h(formats.)47 3439 +y(The)f(main)f(rules)h(used)f(are)i(follo)n(wing)d(rules:)-44 +3643 y Fk(\017)49 b Fl(A)30 b(\002le)h(contains)e(a)i(single)e(BDD/ADD) +h(or)g(a)h(forest)f(of)g(BDDs/ADD,)g(i.e.,)i(a)e(v)o(ector)g(of)g +(Boolean)h(func-)55 3763 y(tions.)-44 3966 y Fk(\017)49 +b Fl(Inte)o(ger)21 b(inde)o(x)o(es)f(are)i(used)f(instead)g(of)g +(pointers)g(to)g(reference)i(nodes.)29 b(BDD/ADD)21 b(nodes)g(are)h +(numbered)55 4087 y(with)j(contiguous)g(numbers,)g(from)h(1)g(to)f +(NNodes)h(\(total)f(number)h(of)g(nodes)g(on)f(a)i(\002le\).)35 +b(0)26 b(is)f(not)h(used)f(to)55 4207 y(allo)n(w)f(ne)o(gati)n(v)o(e)e +(inde)o(x)o(es)h(for)i(complemented)f(edges.)-44 4411 +y Fk(\017)49 b Fl(A)23 b(\002le)g(contains)f(a)h(header)l(,)h +(including)d(se)n(v)o(eral)h(informations)f(about)h(v)n(ariables)h(and) +f(roots)g(of)h(BDD)h(func-)55 4531 y(tions,)32 b(then)e(the)h(list)g +(of)g(nodes.)49 b(The)32 b(header)f(is)g(al)o(w)o(ays)g(represented)h +(in)f(te)o(xt)f(format)h(\(also)g(for)g(binary)55 4651 +y(\002les\).)g(BDDs,)25 b(ADDs,)f(and)h(CNF)h(\002les)f(share)g(a)g +(similar)f(format)g(header)-5 b(.)-44 4855 y Fk(\017)49 +b Fl(BDD/ADD)40 b(nodes)g(are)h(listed)f(follo)n(wing)e(their)i +(numbering,)j(which)d(is)g(produced)g(by)h(a)f(post-order)55 +4975 y(tra)n(v)o(ersal,)24 b(in)h(such)f(a)h(w)o(ay)g(that)g(a)g(node)f +(is)h(al)o(w)o(ays)f(listed)g(after)h(its)f(Then/Else)g(children.)47 +5179 y(In)32 b(the)f(sequel)g(we)g(describe)h(more)f(in)g(detail)f(the) +h(dif)n(ferent)g(formats)g(and)g(procedures)h(a)n(v)n(ailable.)49 +b(First)-189 5299 y(of)26 b(all,)f(we)h(describe)f(BDDs)h(and)g(ADDs)f +(formats)g(and)g(procedure.)33 b(Secondly)-6 b(,)26 b(we)f(concentrate) +h(on)f(CNF)i(\002les,)-189 5419 y(i.e.,)e(ho)n(w)f(to)g(translate)g(a)i +(BDD)f(or)g(a)g(forest)g(of)f(BDDs)h(into)f(a)h(CNF)h(formula)e(and)h +(vice-v)o(ersa.)1794 5800 y(1)p eop +%%Page: 2 2 +2 1 bop -189 218 a Fo(2)143 b(BDD)35 b(and)g(ADD)g(Support)-189 +441 y Fl(In)23 b(this)f(section)g(we)g(describe)h(format)g(and)f +(procedure)h(re)o(garding)f(BDDs)h(and)f(ADDs.)30 b(W)-8 +b(e)23 b(speci\002cally)g(refer)g(to)-189 562 y(BDDs)h(in)g(the)g +(description)e(as)j(ADD)e(may)h(be)g(seen)g(as)h(an)f(e)o(xtension)e +(and)i(will)f(be)h(described)g(later)-5 b(.)30 b(First)24 +b(of)g(all,)-189 682 y(we)29 b(concentrate)f(on)g(the)g(format)g(used)g +(to)g(store)g(these)g(structure,)h(then)f(we)g(describe)h(the)f +(procedure)h(a)n(v)n(ailable)-189 802 y(to)24 b(store)h(and)g(load)f +(them.)-189 1094 y Fj(2.1)119 b(F)m(ormat)-189 1281 y +Fl(BDD)30 b(dump)f(\002les)g(are)i(composed)e(of)g(tw)o(o)g(sections:) +40 b(The)29 b(header)h(and)g(the)f(list)g(of)h(nodes.)44 +b(The)30 b(header)g(has)g(a)-189 1402 y(common)c(\(te)o(xt\))h(format,) +h(while)e(the)i(list)e(of)h(nodes)g(is)g(either)g(in)g(te)o(xt)g(or)g +(binary)g(format.)38 b(In)28 b(te)o(xt)e(format)h(nodes)-189 +1522 y(are)33 b(represented)f(with)f(redundant)g(informations,)h(where) +h(the)f(main)f(goal)g(is)h(readability)-6 b(,)32 b(while)g(the)f +(purpose)-189 1642 y(of)i(binary)f(format)g(is)g(minimizing)e(the)i(o)o +(v)o(erall)f(storage)h(size)h(for)g(BDD)f(nodes.)54 b(The)32 +b(header)h(format)f(is)g(k)o(ept)-189 1763 y(common)h(to)h(te)o(xt)g +(and)g(binary)g(formats)g(for)h(sak)o(e)f(of)h(simplicity:)47 +b(No)34 b(particular)g(optimization)f(is)h(presently)-189 +1883 y(done)29 b(on)f(binary)h(\002le)g(headers,)h(whose)f(size)g(is)f +(by)h(f)o(ar)g(dominated)f(by)h(node)f(lists)g(in)g(the)h(case)g(of)g +(lar)n(ge)h(BDDs)-189 2003 y(\(se)n(v)o(eral)24 b(thousands)g(of)h(DD)f +(nodes\).)-189 2266 y Fi(2.1.1)99 b(Header)-189 2453 +y Fl(The)23 b(header)h(has)f(the)g(same)g(format)g(both)g(for)g(te)o +(xtual)f(and)i(binary)e(dump.)30 b(F)o(or)23 b(sak)o(e)g(of)h +(generality)e(and)h(because)-189 2574 y(of)f(dynamic)g(v)n(ariable)g +(ordering)g(both)f(v)n(ariable)h(IDs)g(and)g(permutations)2377 +2537 y Fh(1)2438 2574 y Fl(are)h(included.)29 b(Names)22 +b(are)h(optionally)-189 2694 y(listed)35 b(for)h(input)f(v)n(ariables)g +(and)h(for)h(the)e(stored)h(functions.)63 b(Ne)n(w)36 +b(auxiliary)f(IDs)h(are)h(also)e(allo)n(wed.)64 b(Only)-189 +2814 y(the)34 b(v)n(ariables)f(in)g(the)h(true)g(support)f(of)h(the)f +(stored)h(BDDs)g(are)h(listed.)56 b(All)34 b(information)e(on)i(v)n +(ariables)f(\(IDs,)-189 2935 y(permutations,)c(names,)i(auxiliary)e +(IDs\))h(sorted)g(by)g(IDs,)h(and)e(the)o(y)h(are)g(restricted)g(to)f +(the)h(true)g(support)f(of)h(the)-189 3055 y(dumped)22 +b(BDD,)h(while)g(IDs)g(and)f(permutations)g(are)h(referred)i(to)d(the)h +(writing)f(BDD)h(manager)-5 b(.)30 b(Names)22 b(can)i(thus)-189 +3175 y(be)h(sorted)f(by)h(v)n(ariable)f(ordering)h(by)f(permuting)g +(them)g(according)h(to)f(the)h(permutations)e(stored)h(in)h(the)f +(\002le.)47 3296 y(As)h(an)g(e)o(xample,)f(the)g(header)i(\(in)e(te)o +(xt)g(mode\))h(of)f(the)h(ne)o(xt)f(state)h(functions)e(of)i(circuit)g +(s27)f(follo)n(ws:)-189 3494 y Fg(.ver)59 b(DDDMP-2.0)-189 +3615 y(.mode)g(A)-189 3735 y(.varinfo)f(3)-189 3855 y(.dd)h(s27-delta) +-189 3976 y(.nnodes)f(16)-189 4096 y(.nvars)g(10)-189 +4216 y(.nsuppvars)g(7)-189 4337 y(.varnames)g(G0)h(G1)g(G2)h(G3)f(G5)g +(G6)h(G7)-189 4457 y(.orderedvarnames)c(G0)k(G1)f(G2)g(G3)h(G5)f(G6)g +(G7)-189 4578 y(.ids)g(0)g(1)h(2)g(3)f(4)h(5)f(6)-189 +4698 y(.permids)f(0)i(1)f(2)h(3)f(5)h(7)f(9)-189 4818 +y(.auxids)f(1)i(2)f(3)h(4)f(5)h(6)g(7)-189 4939 y(.nroots)e(3)-189 +5059 y(.rootids)g(6)i(-13)f(-16)-189 5179 y(.rootnames)f(G10)h(G11)g +(G13)47 5378 y Fl(The)25 b(lines)f(contain)g(the)h(follo)n(wing)e +(informations:)p -189 5460 1607 4 v -77 5521 a Ff(1)-40 +5551 y Fe(The)d(permutation)e(of)i(the)g(i-th)h(v)n(ariable)e(ID)h(is)h +(the)f(relati)n(v)o(e)g(position)f(of)h(the)g(v)n(ariable)f(in)i(the)f +(ordering.)1794 5800 y Fl(2)p eop +%%Page: 3 3 +3 2 bop -44 218 a Fk(\017)49 b Fl(Dddmp)24 b(v)o(ersion)f(information.) +-44 411 y Fk(\017)49 b Fl(File)25 b(mode)f(\(A)h(for)g(ASCII)h(te)o +(xt,)e(B)h(for)g(binary)g(mode\).)-44 604 y Fk(\017)49 +b Fl(V)-11 b(ar)n(-e)o(xtra-info)25 b(\(0:)30 b(v)n(ariable)24 +b(ID,)h(1:)31 b(permID,)24 b(2:)31 b(aux)25 b(ID,)g(3:)30 +b(v)n(ariable)24 b(name,)h(4)g(no)f(e)o(xtra)h(info\).)-44 +797 y Fk(\017)49 b Fl(Name)25 b(of)g(dd)f(\(optional\).)-44 +990 y Fk(\017)49 b Fl(T)-8 b(otal)24 b(number)g(of)h(nodes)g(in)f(the)h +(\002le.)-44 1183 y Fk(\017)49 b Fl(Number)24 b(of)h(v)n(ariables)f(of) +h(the)g(writing)f(DD)g(manager)-5 b(.)-44 1375 y Fk(\017)49 +b Fl(Number)24 b(of)h(v)n(ariables)f(in)h(the)f(true)h(support)f(of)h +(the)f(stored)h(DDs.)-44 1568 y Fk(\017)49 b Fl(V)-11 +b(ariable)25 b(names)f(\(optional\))g(for)h(all)g(the)f(v)n(ariables)g +(in)h(the)f(BDD/ADD)h(support.)-44 1761 y Fk(\017)49 +b Fl(V)-11 b(ariable)20 b(names)g(for)h(all)f(the)g(v)n(ariables)f(in)h +(the)g(DD)h(manager)f(during)g(the)g(storing)f(phase.)29 +b(Notice)20 b(that)g(this)55 1882 y(information)k(w)o(as)h(not)g +(stored)g(by)g(pre)n(vious)f(v)o(ersions)g(of)i(the)f(same)g(tool.)32 +b(Full)25 b(backw)o(ard)g(compatibility)55 2002 y(is)f(guaranteed)h(by) +g(the)f(present)h(implementation)d(of)j(the)g(tool.)-44 +2195 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(IDs.)-44 +2388 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(permuted)f(IDs.)-44 +2581 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(auxiliary)f(IDs)h +(\(optional\).)-44 2774 y Fk(\017)49 b Fl(Number)24 b(of)h(BDD)g +(roots.)-44 2967 y Fk(\017)49 b Fl(Inde)o(x)o(es)24 b(of)h(BDD)g(roots) +f(\(complemented)g(edges)g(allo)n(wed\).)-44 3160 y Fk(\017)49 +b Fl(Names)24 b(of)h(BDD)h(roots)e(\(optional\).)-189 +3332 y(Notice)h(that)f(a)h(\002eld)-189 3504 y Fg(.add)-189 +3676 y Fl(is)f(present)h(after)g(the)g(dddmp)f(v)o(ersion)f(for)j +(\002les)e(containing)g(ADDs.)-189 3936 y Fi(2.1.2)99 +b(T)-9 b(ext)25 b(F)n(ormat)-189 4124 y Fl(In)g(te)o(xt)f(mode)g(nodes) +g(are)i(listed)e(on)g(a)h(te)o(xt)f(line)h(basis.)30 +b(Each)25 b(a)g(node)f(is)h(represented)g(as)-189 4296 +y Fg()57 b([])f()588 +4416 y()h()-189 4588 y Fl(where)25 +b(all)g(inde)o(x)o(es)e(are)j(inte)o(ger)e(numbers.)47 +4709 y(This)h(format)g(is)g(redundant)f(\(due)i(to)f(the)g(node)g +(ordering,)g Fd(<)p Fl(Node-inde)o(x)p Fd(>)f Fl(is)g(and)i +(incremental)e(inte)o(ger\))-189 4829 y(b)n(ut)g(we)h(k)o(eep)g(it)g +(for)g(readability)-6 b(.)47 4949 y Fd(<)p Fl(V)-11 b(ar)n(-e)o +(xtra-info)p Fd(>)34 b Fl(\(optional)e(redundant)i(\002eld\))g(is)f +(either)h(an)g(inte)o(ger)f(\(ID,)h(PermID,)g(or)g(auxID\))g(or)g(a) +-189 5070 y(string)k(\(v)n(ariable)h(name\).)75 b Fd(<)p +Fl(V)-11 b(ar)n(-internal-inde)o(x)p Fd(>)38 b Fl(is)h(an)g(internal)g +(v)n(ariable)g(inde)o(x:)59 b(V)-11 b(ariables)39 b(in)g(the)g(true) +-189 5190 y(support)25 b(of)h(the)g(stored)g(BDDs)g(are)h(numbered)e +(with)g(ascending)h(inte)o(gers)f(starting)g(from)h(0,)g(and)g(follo)n +(wing)e(the)-189 5311 y(v)n(ariable)g(ordering.)31 b +Fd(<)p Fl(Then-inde)o(x)p Fd(>)23 b Fl(and)i Fd(<)p Fl(Else-inde)o(x)p +Fd(>)e Fl(are)j(signed)e(inde)o(x)o(es)f(of)i(children)f(nodes.)47 +5431 y(In)h(the)f(follo)n(wing,)f(we)i(report)f(the)g(list)g(of)h +(nodes)f(of)g(the)h(s27)f(ne)o(xt)f(state)i(functions)e(\(see)i(pre)n +(vious)e(header)-189 5551 y(e)o(xample\):)1794 5800 y(3)p +eop +%%Page: 4 4 +4 3 bop -189 218 a Fg(.nodes)-189 338 y(1)60 b(T)f(1)h(0)f(0)-189 +459 y(2)h(G7)f(6)g(1)h(-1)-189 579 y(3)g(G5)f(4)g(1)h(2)-189 +699 y(4)g(G3)f(3)g(3)h(1)-189 820 y(5)g(G1)f(1)g(1)h(4)-189 +940 y(6)g(G0)f(0)g(5)h(-1)-189 1061 y(7)g(G6)f(5)g(1)h(-1)-189 +1181 y(8)g(G5)f(4)g(1)h(-7)-189 1301 y(9)g(G6)f(5)g(1)h(-2)-189 +1422 y(10)f(G5)h(4)f(1)h(-9)-189 1542 y(11)f(G3)h(3)f(10)h(8)-189 +1662 y(12)f(G1)h(1)f(8)h(11)-189 1783 y(13)f(G0)h(0)f(5)h(12)-189 +1903 y(14)f(G2)h(2)f(1)h(-1)-189 2024 y(15)f(G2)h(2)f(1)h(-2)-189 +2144 y(16)f(G1)h(1)f(14)h(15)-189 2264 y(.end)-189 2468 +y Fl(The)27 b(list)f(is)h(enclosed)g(between)g(the)g +Fg(.nodes)f Fl(and)h Fg(.end)f Fl(lines.)37 b(First)27 +b(node)g(is)g(the)g(one)g(constant,)f(each)i(node)-189 +2588 y(contains)c(the)h(optional)e(v)n(ariable)h(name.)47 +2708 y(F)o(or)29 b(ADDs)f(more)h(than)f(one)h(constant)e(is)i(stored)f +(in)g(the)g(\002le.)43 b(Each)29 b(constant)f(has)g(the)h(same)f +(format)h(we)-189 2829 y(ha)n(v)o(e)c(just)e(analyzed)i(for)g(the)g +(BDD)g(b)n(ut)g(the)f(represented)h(v)n(alue)f(is)h(stored)f(as)h(a)g +(\003oat)g(number)-5 b(.)-189 3095 y Fi(2.1.3)99 b(Binary)25 +b(F)n(ormat)-189 3283 y Fl(The)h(binary)g(format)f(is)h(not)f(allo)n +(wed)g(for)i(ADDs.)33 b(As)26 b(a)h(consequence)f(we)g(concentrate)g +(only)f(on)h(BDDs)g(in)g(this)-189 3403 y(section.)k(In)25 +b(binary)f(mode)h(nodes)f(are)i(represented)f(as)g(a)g(sequence)g(of)g +(bytes,)f(encoding)g(tuples)-189 3606 y Fg()-189 +3727 y([])-189 3847 y([])-189 +3968 y([])-189 4171 y Fl(in)30 b(an)g(optimized)f(w)o(ay)-6 +b(.)46 b(Only)29 b(the)h(\002rst)g(byte)g(\(code\))h(is)e(mandatory)-6 +b(,)30 b(while)g(inte)o(ger)f(inde)o(x)o(es)g(are)i(represented)-189 +4291 y(in)c(absolute)f(or)h(relati)n(v)o(e)f(mode,)h(where)h(relati)n +(v)o(e)e(means)g(of)n(fset)h(with)f(respect)i(to)e(a)i(Then/Else)e +(node)h(info.)37 b(The)-189 4412 y(best)23 b(between)g(absolute)f(and)h +(relati)n(v)o(e)e(representation)i(is)f(chosen)h(and)g(relati)n(v)o(e)f +(1)h(is)f(directly)g(coded)h(in)g Fd(<)p Fl(Node-)-189 +4532 y(code)p Fd(>)e Fl(without)f(an)o(y)g(e)o(xtra)h(info.)29 +b(Suppose)21 b(V)-11 b(ar\(NodeId\),)22 b(Then\(NodeId\))f(and)g +(Else\(NodeId\))f(represent)i(infos)-189 4652 y(about)i(a)h(gi)n(v)o +(en)f(node.)30 b Fd(<)p Fl(Node-code)p Fd(>)25 b Fl(is)f(a)h(byte)g +(which)f(contains)g(the)h(follo)n(wing)e(bit)h(\002elds)h(\(MSB)g(to)g +(LSB\))-44 4856 y Fk(\017)49 b Fl(Unused)24 b(:)31 b(1)24 +b(bit)-44 5059 y Fk(\017)49 b Fl(V)-11 b(ariable:)30 +b(2)25 b(bits,)f(one)h(of)g(the)f(follo)n(wing)f(codes)171 +5288 y Fi(\226)49 b Fl(DDDMP)p 636 5288 30 4 v 35 w(ABSOLUTE)p +1191 5288 V 36 w(ID:)22 b(V)-11 b(ar\(NodeId\))22 b(is)f(represented)h +(in)g(absolute)f(form)g(as)h Fd(<)p Fl(V)-11 b(ar)n(-internal-)270 +5408 y(info)p Fd(>)24 b Fl(=)h(V)-11 b(ar\(NodeId\))25 +b(follo)n(ws)e(\(absolute)i(info\))1794 5800 y(4)p eop +%%Page: 5 5 +5 4 bop 171 218 a Fi(\226)49 b Fl(DDDMP)p 636 218 30 +4 v 35 w(RELA)-11 b(TIVE)p 1147 218 V 36 w(ID:)32 b(V)-11 +b(ar\(NodeId\))32 b(is)g(represented)g(in)f(relati)n(v)o(e)g(form)h(as) +g Fd(<)p Fl(V)-11 b(ar)n(-internal-)270 338 y(info\277)24 +b(=)h(Min\(V)-11 b(ar\(Then\(NodeId\)\),V)g(ar\(Else\(NodeId\)\)\)-V)g +(ar\(NodeId\))171 500 y Fi(\226)49 b Fl(DDDMP)p 636 500 +V 35 w(RELA)-11 b(TIVE)p 1147 500 V 36 w(1:)27 b(the)19 +b(\002eld)g Fd(<)p Fl(V)-11 b(ar)n(-internal-info)p Fd(>)18 +b Fl(does)h(not)f(follo)n(w)-6 b(,)18 b(because)h(V)-11 +b(ar\(NodeId\))270 620 y(=)25 b(Min\(V)-11 b(ar\(Then\(NodeId\)\),V)g +(ar\(Else\(NodeId\)\)\)-1)171 782 y Fi(\226)49 b Fl(DDDMP)p +636 782 V 35 w(TERMIN)m(AL:)24 b(Node)h(is)f(a)h(terminal,)f(no)g(v)n +(ar)h(info)g(required)-44 1011 y Fk(\017)49 b Fl(T)25 +b(:)f(2)h(bits,)f(with)g(codes)h(similar)e(to)i(V)171 +1214 y Fi(\226)49 b Fl(DDDMP)p 636 1214 V 35 w(ABSOLUTE)p +1191 1214 V 36 w(ID:)20 b Fd(<)p Fl(Then-info)p Fd(>)f +Fl(is)h(represented)g(in)g(absolute)f(form)h(as)g Fd(<)p +Fl(Then-info)p Fd(>)270 1334 y Fl(=)25 b(Then\(NodeId\))171 +1496 y Fi(\226)49 b Fl(DDDMP)p 636 1496 V 35 w(RELA)-11 +b(TIVE)p 1147 1496 V 36 w(ID:)28 b(Then\(NodeId\))f(is)g(represented)h +(in)g(relati)n(v)o(e)e(form)i(as)g Fd(<)p Fl(Then-info)p +Fd(>)270 1617 y Fl(=)d(Nodeid-Then\(NodeId\))171 1779 +y Fi(\226)49 b Fl(DDDMP)p 636 1779 V 35 w(RELA)-11 b(TIVE)p +1147 1779 V 36 w(1:)30 b(no)25 b Fd(<)p Fl(Then-info)p +Fd(>)f Fl(follo)n(ws,)f(because)i(Then\(NodeId\))g(=)g(NodeId-1)171 +1941 y Fi(\226)49 b Fl(DDDMP)p 636 1941 V 35 w(TERMIN)m(AL:)24 +b(Then)h(Node)f(is)h(a)g(terminal,)f(no)g(info)h(required)f(\(for)i(R)l +(OBDDs\))-44 2144 y Fk(\017)49 b Fl(Ecompl)24 b(:)30 +b(1)25 b(bit,)f(if)h(1)g(means)f(that)g(the)h(else)g(edge)g(is)f +(complemented)-44 2347 y Fk(\017)49 b Fl(E)25 b(:)f(2)h(bits,)f(with)g +(codes)h(and)f(meanings)g(as)h(for)g(the)g(Then)f(edge)-189 +2551 y(DD)35 b(node)f(codes)h(are)h(written)e(as)h(one)g(byte.)60 +b Fd(<)p Fl(V)-11 b(ar)n(-internal-inde)o(x)p Fd(>)p +Fl(,)36 b Fd(<)p Fl(Then-inde)o(x)p Fd(>)p Fl(,)g Fd(<)p +Fl(Else-inde)o(x)p Fd(>)e Fl(\(if)-189 2671 y(required\))25 +b(are)h(represented)f(as)g(unsigned)e(inte)o(ger)h(v)n(alues)g(on)h(a)g +(suf)n(\002cient)f(set)h(of)g(bytes)f(\(MSByte)h(\002rst\).)47 +2792 y(Inte)o(gers)h(of)f(an)o(y)h(length)e(are)j(written)e(as)h +(sequences)g(of)g(\224link)o(ed\224)f(bytes)g(\(MSByte)h(\002rst\).)34 +b(F)o(or)26 b(each)g(byte)-189 2912 y(7)f(bits)f(are)h(used)g(for)g +(data)g(and)f(one)h(\(MSBit\))g(as)g(link)f(with)g(a)h(further)g(byte)g +(\(MSB)g(=)g(1)g(means)f(one)h(more)g(byte\).)47 3032 +y(Lo)n(w)f(le)n(v)o(el)g(read/write)h(of)g(bytes)f(\002lters)h +Fd(<)p Fl(CR)p Fd(>)p Fl(,)g Fd(<)p Fl(LF)p Fd(>)g Fl(and)g +Fd(<)p Fl(ctrl-Z)p Fd(>)f Fl(through)g(escape)h(sequences.)-189 +3327 y Fj(2.2)119 b(Implementation)-189 3515 y Fl(Store)24 +b(and)g(load)g(for)g(single)g(Boolean)g(functions)f(and)h(arrays)g(of)g +(Boolean)g(functions)f(are)i(implemented.)k(More-)-189 +3635 y(o)o(v)o(er)l(,)37 b(the)e(current)h(presentation)f(includes)f +(functions)h(to)g(retrie)n(v)o(e)g(v)n(ariables)f(names,)k(auxiliary)d +(identi\002erss,)-189 3756 y(and)c(all)g(the)g(information)f(contained) +h(in)f(the)h(header)h(of)f(the)h(\002les.)50 b(This)30 +b(information)g(can)h(be)h(used)f(as)g(a)g(pre-)-189 +3876 y(processing)19 b(step)g(for)i(load)e(operations.)28 +b(These)20 b(functions)f(allo)n(w)f(to)i(o)o(v)o(ercome)f(fe)n(w)g +(limitations)f(of)h(the)h(pre)n(vious)-189 3997 y(implementations.)-189 +4263 y Fi(2.2.1)99 b(Storing)25 b(Decision)g(Diagrams)-189 +4450 y Fc(Dddmp)p 111 4450 V 35 w(cuddBddStor)l(e)f Fl(and)h +Fc(Dddmp)p 1195 4450 V 35 w(cuddBddArr)o(ayStor)l(e)e +Fl(are)j(the)f(tw)o(o)f(store)h(functions,)f(used)h(to)g(store)f(sin-) +-189 4571 y(gle)f(BDD)h(or)g(a)f(forest)h(of)f(BDDs,)h(respecti)n(v)o +(ely)-6 b(.)28 b(Internally)-6 b(,)23 b Fc(Dddmp)p 2275 +4571 V 35 w(cuddBddStor)l(e)f Fl(b)n(uilds)g(a)i(dummy)e(1)h(entry)-189 +4691 y(array)j(of)e(BDDs,)h(and)g(calls)g Fc(dddmp)p +1102 4691 V 35 w(cuddBddArr)o(ayStor)l(e)p Fl(.)47 4811 +y(Since)30 b(con)l(v)o(ersion)e(from)h(DD)h(pointers)e(to)h(inte)o(ger) +f(is)h(required,)i(DD)e(nodes)g(are)h(temporarily)e(remo)o(v)o(ed)-189 +4932 y(from)23 b(the)f(unique)h(hash.)29 b(This)23 b(mak)o(es)f(room)g +(in)h(their)f Fc(ne)n(xt)h Fl(\002eld)h(to)e(store)h(node)f(IDs.)30 +b(Nodes)23 b(are)h(re-link)o(ed)e(after)-189 5052 y(the)i(store)g +(operation,)g(possible)f(in)g(a)i(modi\002ed)e(order)-5 +b(.)31 b(Dumping)22 b(is)i(either)g(in)g(te)o(xt)f(or)i(binary)f(form.) +30 b(Both)24 b(a)g(\002le)-189 5173 y(pointer)31 b(\()p +Fc(fp)p Fl(\))g(and)g(a)h(\002le)g(name)f(\()p Fc(fname)p +Fl(\))h(are)g(pro)o(vided)e(as)h(inputs)f(parameters)i(to)f(store)g +(routines.)50 b(BDDs)31 b(are)-189 5293 y(stored)c(to)g(the)g(already)g +(open)h(\002le)f Fc(fp)p Fl(,)h(if)f(not)g(NULL.)g(Otherwise)f(\002le)i +(whose)f(name)g(is)g Fc(fname)g Fl(is)g(opened.)38 b(This)-189 +5413 y(is)24 b(intended)g(to)h(allo)n(w)f(either)g(DD)h(storage)g +(within)e(\002les)i(containing)f(other)g(data,)h(or)g(to)g(speci\002c)g +(\002les.)1794 5800 y(5)p eop +%%Page: 6 6 +6 5 bop -189 218 a Fi(2.2.2)99 b(Loading)25 b(Decision)g(Diagrams)-189 +405 y Fc(Dddmp)p 111 405 30 4 v 35 w(cuddBddLoad)37 b +Fl(and)h Fc(Dddmp)p 1219 405 V 35 w(cuddBddArr)o(ayLoad)f +Fl(are)h(the)g(load)g(functions,)i(which)e(read)g(a)g(BDD)-189 +526 y(dump)24 b(\002le.)47 646 y(F)o(ollo)n(wing)34 b(the)h(store)h +(function,)h(the)f(main)f(BDD)h(load)f(function,)j Fc(Dddmp)p +2813 646 V 35 w(cuddBddLoad)p Fl(,)f(is)f(imple-)-189 +767 y(mented)g(by)g(calling)f(the)h(main)g(BDD-array)h(loading)f +(function)f Fc(Dddmp)p 2466 767 V 35 w(cuddBddArr)o(ayLoad)p +Fl(.)63 b(A)37 b(dynamic)-189 887 y(v)o(ector)24 b(of)h(DD)g(pointers)f +(is)g(temporarily)g(allocated)h(to)f(support)g(con)l(v)o(ersion)f(from) +i(DD)g(inde)o(x)o(es)e(to)h(pointers.)47 1007 y(Se)n(v)o(eral)40 +b(criteria)f(are)i(supported)d(for)i(v)n(ariable)f(match)g(between)g +(\002le)h(and)g(DD)f(manager)l(,)k(practically)-189 1128 +y(allo)n(wing)37 b(v)n(ariable)h(permutations)f(or)i(compositions)d +(while)i(loading)g(DDs.)71 b(V)-11 b(ariable)39 b(match)f(between)h +(the)-189 1248 y(DD)32 b(manager)g(and)g(the)g(BDD)g(\002le)g(is)g +(optionally)e(based)i(in)f Fc(IDs)p Fl(,)j Fc(perids)p +Fl(,)f Fc(varnames)p Fl(,)g Fc(var)o(auxids)p Fl(;)g(also)f(direct)-189 +1369 y(composition)j(between)j Fc(IDs)g Fl(and)f Fc(composeids)g +Fl(is)g(supported.)68 b(The)38 b Fc(varmatc)o(hmode)e +Fl(parameter)i(is)f(used)g(to)-189 1489 y(select)27 b(mathing)e(mode.) +37 b(More)27 b(in)f(detail,)h(tw)o(o)f(match)h(modes)f(use)h(the)f +(information)g(within)f(the)i(DD)g(manager)l(,)-189 1609 +y(the)e(other)f(ones)h(use)g(e)o(xtra)f(information,)f(which)i(support) +f(an)o(y)g(v)n(ariable)g(remap)h(or)g(change)g(in)f(the)h(ordering.)-44 +1813 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 1813 +V 35 w(V)-13 b(AR)p 1272 1813 V 35 w(MA)i(TCHIDS)19 b(allo)n(ws)f +(loading)g(a)h(DD)g(k)o(eeping)f(v)n(ariable)g(IDs)h(unchanged)55 +1933 y(\(re)o(gardless)24 b(of)h(the)f(v)n(ariable)h(ordering)f(of)h +(the)g(reading)f(manager)-5 b(.)55 2095 y(This)24 b(is)g(useful,)g(for) +h(e)o(xample,)f(when)g(sw)o(apping)g(DDs)g(to)h(\002le)g(and)f +(restoring)g(them)g(later)h(from)f(\002le,)h(after)55 +2215 y(possible)e(v)n(ariable)i(reordering)g(acti)n(v)n(ations.)-44 +2419 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 2419 +V 35 w(V)-13 b(AR)p 1272 2419 V 35 w(MA)i(TCHPERMIDS)36 +b(is)e(used)h(to)f(allo)n(w)g(v)n(ariable)g(match)h(according)55 +2539 y(to)h(the)h(position)e(in)i(the)g(ordering)f(\(retrie)n(v)o(ed)g +(by)h(array)h(of)f(permutations)e(stored)h(on)h(\002le)g(and)g(within) +55 2660 y(the)h(reading)g(DD)h(manager\).)72 b(A)38 b(possible)f +(application)h(is)g(retrie)n(ving)f(BDDs)i(stored)f(after)h(dynamic)55 +2780 y(reordering,)28 b(from)g(a)g(DD)g(manager)g(where)h(all)e(v)n +(ariable)h(IDs)f(map)h(their)f(position)g(in)g(the)h(ordering,)g(and)55 +2900 y(the)d(loaded)f(BDD)h(k)o(eeps)g(the)g(ordering)f(as)h(stored)f +(on)h(\002le.)-44 3104 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p +1040 3104 V 35 w(V)-13 b(AR)p 1272 3104 V 35 w(MA)i(TCHN)m(AMES)26 +b(requires)h(a)h(not)e(NULL)h(v)n(armatchmodes)f(param-)55 +3224 y(eter;)34 b(this)c(is)g(a)h(v)o(ector)g(of)g(strings)e(in)i +(one-to-one)f(correspondence)h(with)f(v)n(ariable)h(IDs)f(of)h(the)g +(reading)55 3344 y(manager)-5 b(.)40 b(V)-11 b(ariables)28 +b(in)g(the)g(DD)g(\002le)g(read)h(are)g(matched)f(with)f(manager)h(v)n +(ariables)f(according)h(to)g(their)55 3465 y(name)35 +b(\(a)h(not)f(NULL)g(v)n(arnames)g(parameter)h(w)o(as)f(required)h +(while)f(storing)f(the)h(DD)g(\002le\).)64 b(The)35 b(most)55 +3585 y(common)c(usage)h(of)g(this)f(feature)i(is)e(in)h(combination)e +(with)i(a)g(v)n(ariable)g(ordering)g(stored)f(on)h(a)g(\002le)h(and)55 +3706 y(based)28 b(on)h(v)n(ariables)f(names.)41 b(Names)29 +b(must)e(be)i(loaded)f(in)g(an)h(array)g(of)g(strings)e(and)i(passed)f +(to)g(the)h(DD)55 3826 y(load)24 b(procedure.)-44 4029 +y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 4029 V +35 w(V)-13 b(AR)p 1272 4029 V 35 w(MA)i(TCHIDS)25 b(has)g(a)g(meaning)f +(similar)g(to)55 4150 y(DDDMP)p 421 4150 V 36 w(V)-13 +b(AR)p 654 4150 V 35 w(MA)i(TCHN)m(AMES)26 b(b)n(ut)h(inte)o(ger)f +(auxiliary)g(IDs)h(are)h(used)f(instead)f(of)h(strings.)36 +b(The)28 b(ad-)55 4270 y(ditional)23 b(not)h(NULL)h(v)n(armathauxids)e +(parameter)i(is)g(needed.)-44 4474 y Fk(\017)49 b Fl(v)n +(armatchnode=DDDMP)p 1040 4474 V 35 w(V)-13 b(AR)p 1272 +4474 V 35 w(COMPOSEIDS,)38 b(uses)f(the)f(additional)f(v)n +(arcomposeids)g(parameter)55 4594 y(as)25 b(an)g(array)g(of)g(v)n +(ariable)f(IDs)h(to)g(be)g(composed)f(with)g(IDs)g(stored)h(in)f +(\002le.)-189 4860 y Fi(2.2.3)99 b(DD)25 b(Load/Stor)n(e)h(and)f(V)-9 +b(ariable)25 b(Ordering)-189 5048 y Fl(Loading)31 b(of)i(Decision)e +(Diagrams)h(from)g(\002le)g(supports)f(dif)n(ferent)h(v)n(ariables)g +(ordering)f(strate)o(gies,)i(as)g(already)-189 5168 y(pointed)23 +b(out)h(in)g(the)h(pre)n(vious)e(section.)30 b(This)24 +b(allo)n(ws)f(or)h(e)o(xample)g(storing)f(dif)n(ferent)i(BDDs)f(each)h +(with)f(its)g(o)n(wn)-189 5288 y(v)n(ariable)29 b(ordering,)h(and)g(to) +f(mer)n(ge)h(them)f(within)f(the)i(same)f(DD)h(manager)f(by)h(means)f +(of)g(proper)h(load)f(opera-)-189 5409 y(tions.)44 b(W)-8 +b(e)30 b(suggest)f(using)f(DDDMP)p 1175 5409 V 36 w(V)-13 +b(AR)p 1408 5409 V 36 w(MA)i(TCHIDS)30 b(whene)n(v)o(er)f(IDs)g(k)o +(eeps)h(on)f(representing)h(the)f(same)-189 5529 y(entities)24 +b(while)h(changing)f(v)n(ariable)h(ordering.)31 b(If)25 +b(this)f(is)h(not)f(true,)h(v)n(ariable)g(names)g(\(if)g(a)n(v)n +(ailable\))f(or)i(auxiliary)1794 5800 y(6)p eop +%%Page: 7 7 +7 6 bop -189 218 a Fl(IDs)34 b(are)h(a)g(good)e(w)o(ay)i(to)f +(represent)g(in)l(v)n(ariant)f(attrib)n(uted)g(of)i(v)n(ariables)e +(across)h(se)n(v)o(eral)g(runs)g(with)f(dif)n(ferent)-189 +338 y(orderings.)50 b(DDDMP)p 629 338 30 4 v 35 w(V)-13 +b(AR)p 861 338 V 36 w(COMPOSEIDS)32 b(is)f(an)h(alternati)n(v)o(e)e +(solution,)h(that)g(practically)f(corresponds)h(to)-189 +459 y(cascading)23 b(DDDMP)p 593 459 V 36 w(V)-13 b(AR)p +826 459 V 36 w(MA)i(TCHIDS)23 b(and)h(v)n(ariable)f(composition)e(with) +h(a)i(gi)n(v)o(en)e(array)i(of)g(ne)n(w)f(v)n(ariables.)-189 +797 y Fo(3)143 b(CNF)35 b(Support)-189 1050 y Fj(3.1)119 +b(F)m(ormat)-189 1237 y Fl(Gi)n(v)o(en)30 b(a)h(BDD)g(representing)g(a) +g(function)f Fd(f)11 b Fl(,)32 b(we)f(de)n(v)o(elop)f(three)h(basic)g +(possible)e(w)o(ays)i(to)g(store)f(it)h(as)g(a)g(CNF)-189 +1358 y(formula.)54 b(In)33 b(each)h(method)d(the)i(set)g(of)f(clauses)h +(is)f(written)h(after)g(an)g(header)g(part.)55 b(Only)32 +b(the)h(te)o(xt)f(format)g(is)-189 1478 y(allo)n(wed.)-189 +1743 y Fi(3.1.1)99 b(Header)-189 1931 y Fl(The)23 b(header)h(part)f(of) +g(each)h(CNF)g(\002le)f(has)g(basically)g(the)f(same)h(format)g +(analyzed)g(for)h(the)f(BDD/ADD)g(\002les.)30 b(F)o(or)-189 +2051 y(e)o(xample)h(the)g Fg(.rootids)f Fl(line)h(indicates)f(the)i(be) +o(ginning)d(of)j(each)g(CNF)g(formula)f(represented)h(by)f(a)h(single) +-189 2172 y(BDD.)j(T)-8 b(o)34 b(be)g(compatible)f(with)h(the)g(DIMA)l +(CS)h(format)f(each)h(header)f(line)g(start)g(with)g(the)g(character)h +(\223c\224)g(to)-189 2292 y(indicate)24 b(a)h(comment.)-189 +2557 y Fi(3.1.2)99 b(T)-9 b(ext)25 b(F)n(ormat)-189 2745 +y Fl(The)j(\002rst)g(method,)g(which)f(we)h(call)g Fi(Single-Node-Cut)p +Fl(,)j(models)26 b(each)j(BDD)f(nodes,)h(b)n(ut)e(the)h(ones)f(with)h +(both)-189 2865 y(the)c(children)g(equal)h(to)f(the)g(constant)g(node)g +Fb(1)p Fl(,)g(as)h(a)g(multiple)o(x)o(er)-5 b(.)27 b(Each)e(multiple)o +(x)o(er)d(has)i(tw)o(o)g(data)h(inputs)e(\(i.e.,)-189 +2985 y(the)k(node)h(children\),)f(a)h(selection)f(input)f(\(i.e.,)i +(the)g(node)f(v)n(ariable\))g(and)h(one)f(output)f(\(i.e.,)i(the)g +(function)e(v)n(alue\))-189 3106 y(whose)h(v)n(alue)f(is)h(assigned)f +(to)h(an)g(additional)f(CNF)i(v)n(ariable.)37 b(The)27 +b(\002nal)h(number)e(of)h(v)n(ariables)g(is)f(equal)h(to)g(the)-189 +3226 y(number)d(of)h(original)f(BDD)h(v)n(ariables)f(plus)g(the)h +(number)f(of)h(\223internal\224)g(nodes)f(of)h(the)g(BDD.)47 +3346 y(The)k(second)f(method,)g(which)h(we)f(call)h Fi(Maxterm-Cut)p +Fl(,)h(create)g(clauses)e(starting)g(from)g Fd(f)39 b +Fl(corresponds)-189 3467 y(to)25 b(the)h(of)n(f-set)g(\(i.e.,)f(all)h +(the)g(paths-cubes)f(from)g(the)h(root)g(node)f(to)h(the)f(terminal)g +Fg(0)p Fl(\))h(of)g(the)g(function)e Fd(f)11 b Fl(.)34 +b(W)l(ithin)-189 3587 y(the)29 b(BDD)g(for)g Fd(f)11 +b Fl(,)30 b(such)f(clauses)f(are)i(found)e(by)h(follo)n(wing)e(all)i +(the)f(paths)h(from)f(the)h(root)g(node)f(of)h(the)g(BDD)g(to)-189 +3708 y(the)c(constant)f(node)g Fb(0)p Fl(.)31 b(The)25 +b(\002nal)g(number)f(of)h(v)n(ariables)f(is)g(equal)h(to)f(the)h +(number)f(of)h(original)f(BDD)h(v)n(ariables.)47 3828 +y(The)k(third)g(method,)g(which)g(we)g(call)g Fi(A)-5 +b(uxiliary-V)c(ariable-Cut)p Fl(,)30 b(is)f(a)h(trade-of)n(f)f(between) +g(the)g(\002rst)g(tw)o(o)-189 3948 y(strate)o(gies.)69 +b(Internal)37 b(v)n(ariables,)j(i.e.,)h(cutting)c(points,)j(are)e +(added)g(in)f(order)h(to)g(decompose)f(the)h(BDD)g(into)-189 +4069 y(multiple)27 b(sub-trees)i(each)h(of)f(which)f(is)h(stored)g +(follo)n(wing)e(the)h(second)h(strate)o(gy)-6 b(.)42 +b(The)29 b(trade-of)n(f)g(is)g(guided)f(by)-189 4189 +y(the)23 b(cutting)f(point)g(selection)g(strate)o(gy)-6 +b(,)22 b(and)h(we)g(e)o(xperiment)f(with)g(tw)o(o)g(methodologies.)28 +b(In)23 b(the)g(\002rst)g(method,)g(a)-189 4310 y(ne)n(w)f(CNF)h(v)n +(ariable)f(is)f(inserted)h(in)g(correspondence)g(to)g(the)g(shared)g +(nodes)g(of)g(the)h(BDD,)f(i.e.,)h(the)f(nodes)f(which)-189 +4430 y(ha)n(v)o(e)29 b(more)g(than)h(one)f(incoming)f(edge.)45 +b(This)29 b(technique,)h(albeit)e(optimizing)g(the)h(number)g(of)h +(literals)e(stored,)-189 4550 y(can)35 b(produce)g(clauses)f(with)g(a)h +(high)f(number)h(of)f(literals)1894 4514 y Fh(2)1933 +4550 y Fl(.)60 b(T)-8 b(o)35 b(a)n(v)n(oid)f(this)g(dra)o(wback,)j(the) +e(second)f(method,)-189 4671 y(introduces)28 b(all)g(the)g(pre)n +(viously)e(indicated)i(cutting)f(points)g(more)h(the)h(ones)f +(necessary)g(to)g(break)h(the)f(length)g(of)-189 4791 +y(the)d(path)f(to)h(a)g(maximum)e(\(user\))i(selected)g(v)n(alue.)47 +4911 y(Actually)-6 b(,)37 b(all)f(the)f(methods)g(described)h(abo)o(v)o +(e)e(can)j(be)e(re-conducted)h(to)g(the)f(basic)h(idea)g(of)g(possibly) +-189 5032 y(breaking)24 b(the)h(BDD)g(through)f(the)g(use)h(of)f +(additional)g(cutting)f(v)n(ariables)h(and)h(dumping)e(the)h(paths)g +(between)h(the)-189 5152 y(root)34 b(of)h(the)f(BDD,)h(the)g(cutting)e +(v)n(ariables)h(and)g(the)h(terminal)e(nodes.)60 b(Such)35 +b(internal)f(cutting)f(v)n(ariables)h(are)-189 5273 y(added)25 +b(al)o(w)o(ays)f(\(for)i(each)f(node\),)g(ne)n(v)o(er)f(or)h(sometimes) +e(respecti)n(v)o(ely)-6 b(.)p -189 5360 1607 4 v -77 +5422 a Ff(2)-40 5452 y Fe(This)27 b(v)n(alue)f(is)i(superiorly)d +(limited)h(by)g(the)h(number)e(of)h(v)n(ariables)g(of)g(the)h(BDD,)g +(i.e.,)h(the)f(longest)f(path)g(from)g(the)h(root)f(to)g(the)-189 +5551 y(terminal)19 b(node.)1794 5800 y Fl(7)p eop +%%Page: 8 8 +8 7 bop 47 218 a Fl(While)33 b(the)f Fc(Single-Node-Cut)h +Fl(method)f(minimizes)f(the)i(length)f(of)h(the)f(clauses)h(produced,)i +(b)n(ut)d(it)g(also)-189 338 y(requires)d(the)h(higher)f(number)g(of)g +(CNF)i(v)n(ariables,)e(the)h Fc(Maxterm-Cut)f Fl(technique)g(minimizes) +f(the)h(number)g(of)-189 459 y(CNF)36 b(v)n(ariables)d(required.)61 +b(This)34 b(adv)n(antage)g(is)g(counter)n(-balanced)h(by)f(the)h(f)o +(act)g(that)f(in)g(the)h(w)o(orst)f(case)h(the)-189 579 +y(number)23 b(of)g(clauses,)g(as)h(well)e(as)i(the)f(total)f(number)h +(of)g(literals,)g(produced)g(is)g(e)o(xponential)e(in)i(the)g(BDD)h +(size)f(\(in)-189 699 y(terms)28 b(of)i(number)e(of)h(nodes\).)43 +b(The)29 b(application)f(of)h(this)f(method)g(is)g(then)h(limited)e(to) +i(the)g(cases)g(in)f(which)h(the)-189 820 y(\223of)n(f-set\224)c(of)f +(the)g(represented)h(function)f Fd(f)35 b Fl(has)24 b(a)h(small)f +(cardinality)-6 b(.)29 b(The)c Fc(A)n(uxiliary-V)-11 +b(ariable-Cut)22 b Fl(strate)o(gy)h(is)-189 940 y(a)k(trade-of)n(f)h +(between)f(the)g(\002rst)g(tw)o(o)g(methods)f(and)h(the)g(ones)f(which) +h(gi)n(v)o(es)f(more)h(compact)f(results.)37 b(As)27 +b(a)h(\002nal)-189 1061 y(remark)f(notice)e(that)h(the)g(method)g(is)f +(able)i(to)f(store)g(both)f(monolithic)f(BDDs)j(and)f(conjuncti)n(v)o +(e)e(forms.)35 b(In)26 b(each)-189 1181 y(case)f(we)g(generate)h(CNF)f +(\002les)g(using)f(the)h(standard)f(DIMA)l(CS)i(format.)-189 +1365 y Fi(Example)f(1)49 b Fc(F)l(igur)l(e)20 b(1)h(shows)f(an)h(e)n +(xample)g(of)f(how)h(our)f(pr)l(ocedur)l(e)h(works)f(to)h(stor)l(e)f(a) +h(small)f(monolithic)f(BDD.)-189 1486 y(F)l(igur)l(e)j(1\(a\))h(r)l +(epr)l(esents)g(a)g(BDD)g(with)g Fb(4)g Fc(nodes.)30 +b(BDD)23 b(variables)f(ar)l(e)h(named)g(after)f(inte)l(g)o(er)g(number) +o(s)h(r)o(anging)-189 1606 y(fr)l(om)k Fb(1)h Fc(to)g +Fb(4)p Fc(,)h(to)f(have)g(an)g(easy-to-follow)f(corr)l(espondence)h +(with)g(the)g(CNF)h(variables.)40 b(F)l(igur)l(e)27 b(1\(b\),)i(\(c\))g +(and)-189 1727 y(\(d\))c(show)g(the)f(corr)l(esponding)f(CNF)j(r)l(epr) +l(esentations)d(g)o(ener)o(ated)h(by)h(our)f(thr)l(ee)h(methods.)30 +b(As)24 b(in)h(the)f(standar)l(d)-189 1847 y(format)i +Fa(p)i Fc(indicates)e(the)h(total)f(number)g(of)h(variables)f(used)h +(\()p Fb(4)g Fc(is)g(the)g(minimum)f(value)h(as)g(the)g(BDD)g(itself)f +(has)-189 1967 y Fb(4)f Fc(variables\),)e(and)i Fa(cnf)g +Fc(the)f(total)g(number)g(of)h(clauses.)47 2088 y(As)i(a)g(\002nal)f(r) +l(emark)h(notice)f(that)g(for)g(this)g(speci\002c)h(e)n(xample)g(the)f +(\223Maxterm-Cut\224)i(appr)l(oac)o(h)d(is)h(the)h(one)-189 +2208 y(whic)o(h)36 b(gives)g(the)g(most)f(compact)h(CNF)h(r)l(epr)l +(esentation)e(b)n(ut)h(also)f(the)h(clause)g(with)g(the)g(lar)l(g)o +(est)g(number)f(of)-189 2328 y(liter)o(als)23 b(\()p +Fb(4)p Fc(\).)188 2471 y + 6339814 10777681 0 0 11709153 19997655 startTexFig + 188 2471 a +%%BeginDocument: bdd.eps +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: bdd.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3c +%%CreationDate: Mon Sep 9 14:21:26 2002 +%%For: quer@pcsq (Stefano Quer) +%%BoundingBox: 0 0 178 304 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 304 moveto 0 0 lineto 178 0 lineto 178 304 lineto closepath clip newpath +-51.0 319.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawEllipse { + /endangle exch def + /startangle exch def + /yrad exch def + /xrad exch def + /y exch def + /x exch def + /savematrix mtrx currentmatrix def + x y tr xrad yrad sc 0 0 1 startangle endangle arc + closepath + savematrix setmatrix + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06299 0.06299 sc +% +% Fig objects follow +% +% Polyline +15.000 slw +n 2010 4515 m 2550 4515 l 2550 5040 l 2010 5040 l + cp gs col0 s gr +/Times-Roman ff 300.00 scf sf +2205 4875 m +gs 1 -1 sc (1) col0 sh gr +% Ellipse +n 1515 1800 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2250 900 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2970 2715 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2280 3705 270 270 0 360 DrawEllipse gs col0 s gr + +7.500 slw +% Ellipse +n 3555 3555 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2712 1726 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2430 4230 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Polyline +15.000 slw +n 2805 2910 m + 2250 3450 l gs col0 s gr +% Polyline + [90] 0 sd +gs clippath +2940 2472 m 3010 2445 l 2931 2239 l 2957 2411 l 2861 2266 l cp +eoclip +n 2460 1110 m + 2970 2445 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 2861 2266 m 2957 2411 l 2931 2239 l 2908 2284 l 2861 2266 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +1478 1511 m 1528 1568 l 1693 1422 l 1542 1506 l 1643 1366 l cp +eoclip +n 2025 1080 m + 1515 1530 l gs col0 s gr gr + +% arrowhead +n 1643 1366 m 1542 1506 l 1693 1422 l 1643 1416 l 1643 1366 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +2212 645 m 2287 645 l 2287 425 l 2250 594 l 2212 425 l cp +eoclip +n 2250 270 m + 2250 630 l gs col0 s gr gr + +% arrowhead +n 2212 425 m 2250 594 l 2287 425 l 2250 459 l 2212 425 l + cp gs 0.00 setgray ef gr col0 s +% Polyline + [90] 0 sd +gs clippath +2692 2664 m 2732 2601 l 2546 2485 l 2670 2606 l 2506 2548 l cp +eoclip +n 1710 2010 m + 2700 2625 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 2506 2548 m 2670 2606 l 2546 2485 l 2555 2534 l 2506 2548 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj + [90] 0 sd +gs clippath +2504 4653 m 2539 4720 l 2733 4616 l 2567 4663 l 2698 4550 l cp +eoclip +n 3180 2910 m 3181 2911 l 3183 2913 l 3186 2916 l 3192 2921 l 3200 2929 l + 3210 2939 l 3223 2951 l 3238 2966 l 3255 2984 l 3274 3003 l + 3295 3025 l 3317 3049 l 3339 3075 l 3362 3103 l 3385 3131 l + 3407 3161 l 3429 3192 l 3450 3225 l 3470 3258 l 3488 3293 l + 3504 3329 l 3519 3367 l 3531 3406 l 3541 3447 l 3548 3490 l + 3552 3536 l 3552 3583 l 3548 3634 l 3540 3686 l 3528 3740 l + 3510 3795 l 3490 3844 l 3467 3892 l 3441 3939 l 3413 3985 l + 3382 4028 l 3350 4070 l 3317 4110 l 3283 4148 l 3248 4184 l + 3211 4219 l 3174 4253 l 3136 4285 l 3098 4316 l 3059 4347 l + 3020 4376 l 2980 4405 l 2941 4432 l 2901 4459 l 2862 4484 l + 2824 4509 l 2787 4532 l 2751 4554 l 2717 4575 l 2686 4593 l + 2657 4610 l 2631 4626 l 2608 4639 l 2589 4650 l 2572 4659 l + 2559 4666 l 2550 4672 l + 2535 4680 l gs col0 s gr gr + [] 0 sd +% arrowhead +0 slj +n 2698 4550 m 2567 4663 l 2733 4616 l 2686 4599 l 2698 4550 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +1985 4734 m 2028 4672 l 1847 4548 l 1965 4675 l 1804 4609 l cp +eoclip +n 1350 2025 m 1349 2026 l 1348 2027 l 1345 2030 l 1340 2035 l 1334 2042 l + 1325 2051 l 1314 2063 l 1301 2078 l 1286 2095 l 1268 2114 l + 1249 2137 l 1227 2161 l 1205 2188 l 1181 2218 l 1156 2249 l + 1131 2282 l 1105 2316 l 1080 2352 l 1054 2390 l 1029 2428 l + 1005 2468 l 981 2509 l 959 2552 l 938 2595 l 918 2640 l + 900 2687 l 884 2736 l 870 2786 l 858 2839 l 848 2894 l + 841 2951 l 837 3011 l 836 3074 l 838 3139 l 845 3206 l + 855 3275 l 870 3345 l 888 3412 l 910 3477 l 934 3542 l + 961 3604 l 990 3665 l 1022 3723 l 1054 3779 l 1088 3833 l + 1124 3885 l 1160 3935 l 1198 3983 l 1236 4029 l 1275 4074 l + 1315 4118 l 1356 4160 l 1397 4201 l 1438 4241 l 1480 4280 l + 1522 4318 l 1563 4355 l 1605 4390 l 1645 4424 l 1685 4457 l + 1723 4488 l 1760 4517 l 1795 4545 l 1827 4570 l 1857 4593 l + 1884 4613 l 1909 4632 l 1930 4647 l 1947 4660 l 1962 4671 l + 1973 4679 l 1982 4686 l + 1995 4695 l gs col0 s gr gr + +% arrowhead +0 slj +n 1804 4609 m 1965 4675 l 1847 4548 l 1854 4598 l 1804 4609 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj + [90] 0 sd +gs clippath +2300 4492 m 2363 4532 l 2481 4347 l 2359 4470 l 2417 4307 l cp +eoclip +n 2340 3960 m 2341 3962 l 2344 3966 l 2348 3973 l 2354 3982 l 2362 3995 l + 2370 4010 l 2379 4028 l 2389 4046 l 2397 4066 l 2406 4088 l + 2413 4111 l 2420 4137 l 2425 4165 l 2429 4197 l 2430 4230 l + 2429 4263 l 2425 4295 l 2420 4323 l 2413 4349 l 2406 4372 l + 2397 4394 l 2389 4414 l 2379 4433 l 2370 4450 l 2362 4465 l + 2354 4478 l + 2340 4500 l gs col0 s gr gr + [] 0 sd +% arrowhead +0 slj +n 2417 4307 m 2359 4470 l 2481 4347 l 2431 4356 l 2417 4307 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +2136 4532 m 2199 4492 l 2082 4307 l 2141 4470 l 2018 4347 l cp +eoclip +n 2160 3960 m 2159 3962 l 2156 3966 l 2152 3973 l 2146 3982 l 2138 3995 l + 2130 4010 l 2121 4028 l 2111 4046 l 2103 4066 l 2094 4088 l + 2087 4111 l 2080 4137 l 2075 4165 l 2071 4197 l 2070 4230 l + 2071 4263 l 2075 4295 l 2080 4323 l 2087 4349 l 2094 4372 l + 2103 4394 l 2111 4414 l 2121 4433 l 2130 4450 l 2138 4465 l + 2146 4478 l + 2160 4500 l gs col0 s gr gr + +% arrowhead +0 slj +n 2018 4347 m 2141 4470 l 2082 4307 l 2068 4356 l 2018 4347 l + cp gs 0.00 setgray ef gr col0 s +/Times-Roman ff 300.00 scf sf +2175 990 m +gs 1 -1 sc (1) col0 sh gr +/Times-Roman ff 300.00 scf sf +1440 1890 m +gs 1 -1 sc (2) col0 sh gr +/Times-Roman ff 300.00 scf sf +2895 2805 m +gs 1 -1 sc (3) col0 sh gr +/Times-Roman ff 300.00 scf sf +2205 3795 m +gs 1 -1 sc (4) col0 sh gr +$F2psEnd +rs + +%%EndDocument + + endTexFig + 531 3990 a Fc(\(a\))1512 2504 y Fg(p)60 b(cnf)f(7)g(11)1512 +2624 y(-5)g(3)h(0)1512 2745 y(-5)f(4)h(0)1512 2865 y(5)g(-3)f(-4)g(0) +1512 2985 y(6)h(-2)f(0)1512 3106 y(6)h(-5)f(0)1512 3226 +y(-6)g(2)h(5)f(0)1512 3347 y(7)h(1)f(5)h(0)1512 3467 +y(-7)f(1)h(-5)f(0)1512 3587 y(7)h(-1)f(-6)g(0)1512 3708 +y(-7)g(-1)h(6)f(0)1512 3828 y(7)h(0)1836 3990 y Fc(\(b\))2541 +2525 y Fg(p)f(cnf)g(4)h(3)2541 2645 y(1)f(-3)h(-4)f(0)2541 +2766 y(-1)g(2)h(3)f(0)2541 2886 y(-1)g(2)h(-3)f(4)h(0)2868 +3048 y Fc(\(c\))2541 3251 y Fg(p)f(cnf)g(5)h(5)2541 3371 +y(-5)f(1)h(0)2541 3492 y(5)f(-1)h(2)f(0)2541 3612 y(-3)g(-4)g(5)h(0) +2541 3733 y(3)f(-5)h(0)2541 3853 y(-3)f(4)h(-5)f(0)2865 +3990 y Fc(\(d\))-189 4138 y Fl(Figure)46 b(1:)71 b(\(a\))47 +b(BDD;)e(\(b\))h(\223Single-Node-Cut\224)g(format;)55 +b(\(c\))46 b(\223Maxterm-Cut\224)g(format;)55 b(\(d\))45 +b(\223)-8 b(Auxiliary-)-189 4258 y(V)d(ariable-Cut\224)25 +b(F)o(ormat.)-189 4625 y Fj(3.2)119 b(Implementation)-189 +4813 y Fl(Store)25 b(and)g(Load)g(for)g(a)g(single)f(BDD)h(or)g(a)g +(forest)g(of)g(BDDs)g(is)f(currently)h(implemented.)-189 +5073 y Fi(3.2.1)99 b(Storing)25 b(Decision)g(Diagrams)f(as)g(CNF)h(F)n +(ormulas)-189 5260 y Fl(As)g(f)o(ar)g(as)g(the)g(storing)e(process)i +(is)f(concerned)i(three)f(possible)e(formats)h(are)i(a)n(v)n(ailable:) +-44 5431 y Fk(\017)49 b Fl(DDDMP)p 421 5431 30 4 v 36 +w(CNF)p 650 5431 V 36 w(MODE)p 980 5431 V 35 w(NODE:)21 +b(store)f(a)h(BDD)h(by)e(introducing)f(an)i(auxiliary)g(v)n(ariable)f +(for)h(each)g(BDD)55 5551 y(node)1794 5800 y(8)p eop +%%Page: 9 9 +9 8 bop -44 218 a Fk(\017)49 b Fl(DDDMP)p 421 218 30 +4 v 36 w(CNF)p 650 218 V 36 w(MODE)p 980 218 V 35 w(MAXTERM:)20 +b(store)g(a)h(BDD)h(by)e(follo)n(wing)f(the)h(maxterm)g(of)h(the)g +(represented)55 338 y(function)-44 542 y Fk(\017)49 b +Fl(DDDMP)p 421 542 V 36 w(CNF)p 650 542 V 36 w(MODE)p +980 542 V 35 w(BEST)-5 b(:)32 b(trade-of)f(between)h(the)f(tw)o(o)f +(pre)n(vious)g(solution,)h(trying)f(to)h(optimize)55 +662 y(the)25 b(number)f(of)h(literals)f(stored.)-189 +865 y(See)c(procedures)f(Dddmp)p 736 865 V 35 w(cuddBddStoreCnf)g(\(to) +g(store)f(a)h(single)f(BDD)i(as)e(a)i(CNF)f(formula\))g(and)g(Dddmp)p +3609 865 V 34 w(cuddBddArrayStoreCnf)-189 986 y(\(to)25 +b(store)f(an)h(array)h(of)f(BDDs)g(as)f(a)i(CNF)f(formula\).)-189 +1252 y Fi(3.2.2)99 b(Loadinf)26 b(CNF)e(F)n(ormulas)g(as)h(BDDs)-189 +1439 y Fl(As)g(f)o(ar)g(as)g(the)g(loading)e(process)i(is)f(concerned)i +(three)f(possible)e(formats)i(are)g(a)n(v)n(ailable:)-44 +1643 y Fk(\017)49 b Fl(DDDMP)p 421 1643 V 36 w(CNF)p +650 1643 V 36 w(MODE)p 980 1643 V 35 w(NO)p 1159 1643 +V 36 w(CONJ:)25 b(Return)g(the)f(Clauses)h(without)f(Conjunction)-44 +1846 y Fk(\017)49 b Fl(DDDMP)p 421 1846 V 36 w(CNF)p +650 1846 V 36 w(MODE)p 980 1846 V 35 w(NO)p 1159 1846 +V 36 w(Q)o(U)l(ANT)-5 b(:)24 b(Return)h(the)g(sets)f(of)h(BDDs)g +(without)f(Quanti\002cation)-44 2050 y Fk(\017)49 b Fl(DDDMP)p +421 2050 V 36 w(CNF)p 650 2050 V 36 w(MODE)p 980 2050 +V 35 w(CONJ)p 1264 2050 V 36 w(Q)o(U)l(ANT)-5 b(:)23 +b(Return)h(the)g(sets)f(of)h(BDDs)g(AFTER)g(Existential)e(Quanti\002-) +55 2170 y(cation)-189 2373 y(See)e(procedures)f(Dddmp)p +736 2373 V 35 w(cuddBddLoadCnf)f(\(to)h(load)f(a)i(CNF)f(formula)g(as)g +(a)g(single)f(BDD\))h(and)g(Dddmp)p 3581 2373 V 35 w +(cuddBddArrayLoadCnf)-189 2494 y(\(to)35 b(load)h(a)g(CNF)g(formula)f +(as)h(an)g(array)g(of)g(BDDs\).)63 b(See)36 b(also)g(Dddmp)p +2485 2494 V 34 w(cuddHeaderLoadCnf)h(to)e(load)g(the)-189 +2614 y(header)25 b(of)g(a)g(CNF)h(\002le)f(to)g(gather)f(information)f +(on)i(the)g(sa)n(v)o(ed)f(structure.)-189 2954 y Fo(4)143 +b(T)-13 b(est)35 b(Pr)m(ogram)f(and)h(Regr)m(ession)f(T)-13 +b(ests)-189 3177 y Fl(The)20 b Fc(testddmp.c)e Fl(\002le,)j(pro)o +(vided)d(with)h(this)f(distrib)n(ution,)g(e)o(x)o(empli\002es)g(some)h +(of)h(the)f(abo)o(v)o(e)g(features.)29 b(Moreo)o(v)o(er)l(,)-189 +3298 y(in)d(the)h Fc(e)n(xp)g Fl(e)o(xperiments)e(a)j(fe)n(w)e +(scripts,)h(named)f Fc(test\241n\277.script)f Fl(are)i(a)n(v)n(ailable) +f(for)h(a)g(sanity)f(check)h(of)g(the)g(tool)-189 3418 +y(and)e(to)f(tak)o(e)h(a)g(look)f(at)h(some)f(runs)h(e)o(x)o +(empli\002cation.)-189 3758 y Fo(5)143 b(Documentation)-189 +3981 y Fl(F)o(or)27 b(further)f(documentation)f(on)i(the)f(package)h +(see)g(the)g(on-line)f(documentation)f(automatically)g(created)i(from) +-189 4102 y(the)e(source)g(code)g(\002les.)-189 4441 +y Fo(6)143 b(Ackno)o(wledgments)-189 4665 y Fl(W)-8 b(e)19 +b(are)h(particular)f(indebted)f(with)g(F)o(abio)g(Somenzi,)i(for)f +(discussions,)f(advice,)i(and)f(for)g(including)e(the)i(DDDMP)-189 +4785 y(package)28 b(into)f(the)h(CUDD)g(distrib)n(ution.)37 +b(W)-8 b(e)29 b(also)e(thank)g(all)h(the)g(user)g(of)g(the)f(package)i +(for)f(their)f(useful)h(indi-)-189 4905 y(cation)c(and)h(comments)f(on) +g(the)h(it.)1794 5800 y(9)p eop +%%Page: 10 10 +10 9 bop -189 218 a Fo(7)143 b(FTP)35 b(Site)-189 441 +y Fl(The)25 b(package)g(is)f(singularly)g(a)n(v)n(ailable)g(from:)-189 +645 y Fg(site:)59 b(ftp.polito.it)-189 765 y(user:)g(anonymous)-189 +885 y(directory:)f(/pub/research/dddmp)-189 1089 y Fl(or)25 +b(directly)f(from)h(the)f(author)h(WEB)g(pages:)-189 +1292 y Fg(WWW:)59 b(http://www.polito.it/\230{cabodi)o(,quer)o(})-189 +1632 y Fo(8)143 b(F)l(eedback)-189 1855 y Fl(Send)25 +b(feedback)h(to:)-189 2059 y Fg(Gianpiero)58 b(Cabodi)g(&)i(Stefano)e +(Quer)-189 2179 y(Politecnico)f(di)j(Torino)-189 2300 +y(Dipartimento)d(di)i(Automatica)f(e)i(Informatica)-189 +2420 y(Corso)f(Duca)g(degli)f(Abruzzi,)g(24)-189 2540 +y(I-10129)g(Torino)-189 2661 y(Italy)-189 2781 y(E-mail:)g +({cabodi,quer}@polito.it)-189 2901 y(WWW:)h +(http://www.polito.it/\230{cabodi)o(,quer)o(})1769 5800 +y Fl(10)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-Letter.ps b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-Letter.ps new file mode 100644 index 000000000..ad51df7c2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmp-2.0-Letter.ps @@ -0,0 +1,1260 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software +%%Title: dddmp-2.0.dvi +%%Pages: 10 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%DocumentFonts: Times-Bold Times-Roman Courier Times-Italic Helvetica +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -t letter -f dddmp-2.0 +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2002.12.11:0557 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", +% version = "0.6", +% date = "22 June 1996", +% filename = "8r.enc", +% email = "kb@@mail.tug.org", +% address = "135 Center Hill Rd. // Plymouth, MA 02360", +% codetable = "ISO/ASCII", +% checksum = "119 662 4424", +% docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." +% @} +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both ASCII and Windows. +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there down to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics +exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub +dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} +ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict +end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ +dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 +roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def +dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} +if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} +def end + +%%EndProcSet +%%BeginProcSet: special.pro +%! +TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N +/vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N +/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N +/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ +/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho +X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B +/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ +/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known +{userdict/md get type/dicttype eq{userdict begin md length 10 add md +maxlength ge{/md md dup length 20 add dict copy def}if end md begin +/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S +atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ +itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll +transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll +curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf +pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} +if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 +-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 +get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip +yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub +neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ +noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop +90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get +neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr +1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr +2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 +-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S +TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ +Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale +}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState +save N userdict maxlength dict begin/magscale true def normalscale +currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts +/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x +psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx +psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub +TR/showpage{}N/erasepage{}N/copypage{}N/p 3 def @MacSetUp}N/doclip{ +psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 +roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath +moveto}N/endTexFig{end psf$SavedState restore}N/@beginspecial{SDict +begin/SpecialSave save N gsave normalscale currentpoint TR +@SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{ +CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto +closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx +sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR +}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse +CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury +lineto closepath clip}if/showpage{}N/erasepage{}N/copypage{}N newpath}N +/@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{end} +repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N +/@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX +currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY +moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X +/yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0 +1 startangle endangle arc savematrix setmatrix}N end + +%%EndProcSet +TeXDict begin 40258431 52099146 1000 600 600 (dddmp-2.0.dvi) +@start /Fa 143[55 1[55 7[28 2[50 99[{TeXBase1Encoding ReEncodeFont}4 +99.6264 /Helvetica rf +%DVIPSBitmapFont: Fb cmr12 12 3 +/Fb 3 53 df<14FF010713E090381F81F890383E007C01FC133F4848EB1F8049130F4848 +EB07C04848EB03E0A2000F15F0491301001F15F8A2003F15FCA390C8FC4815FEA54815FF +B3A46C15FEA56D1301003F15FCA3001F15F8A26C6CEB03F0A36C6CEB07E0000315C06D13 +0F6C6CEB1F806C6CEB3F00013E137C90381F81F8903807FFE0010090C7FC28447CC131> +48 D<143014F013011303131F13FFB5FC13E713071200B3B3B0497E497E007FB6FCA320 +4278C131>I52 D E +%EndDVIPSBitmapFont +/Fc 64[50 29[39 12[55 55 25[44 44 66 44 50 28 39 39 1[50 +50 50 72 28 44 1[28 50 50 28 44 50 44 50 50 10[61 2[50 +4[66 83 55 2[33 2[61 1[72 66 61 61 15[50 2[25 33 25 2[33 +33 37[50 2[{TeXBase1Encoding ReEncodeFont}45 99.6264 +/Times-Italic rf +%DVIPSBitmapFont: Fd cmmi12 12 3 +/Fd 3 103 df60 D<127012FCB4FCEA7FC0EA1FF0EA +07FCEA01FF38007FC0EB1FF0EB07FE903801FF809038007FE0EC1FF8EC03FE913800FF80 +ED3FE0ED0FF8ED03FF030013C0EE3FF0EE0FFCEE01FF9338007FC0EF1FF0EF07FCEF01FF +9438007FC0F01FE0A2F07FC0943801FF00EF07FCEF1FF0EF7FC04C48C7FCEE0FFCEE3FF0 +EEFFC0030390C8FCED0FF8ED3FE0EDFF80DA03FEC9FCEC1FF8EC7FE0903801FF80D907FE +CAFCEB1FF0EB7FC04848CBFCEA07FCEA1FF0EA7FC048CCFC12FC12703B3878B44C>62 +D102 +D E +%EndDVIPSBitmapFont +/Fe 134[42 2[42 42 23 32 28 1[42 42 42 65 23 2[23 42 +42 28 37 42 1[42 37 12[51 10[28 4[60 1[55 19[21 28 21 +44[{TeXBase1Encoding ReEncodeFont}26 83.022 /Times-Roman +rf +%DVIPSBitmapFont: Ff cmr7 7 2 +/Ff 2 51 df<13381378EA01F8121F12FE12E01200B3AB487EB512F8A215267BA521>49 +D<13FF000313E0380E03F0381800F848137C48137E00787F12FC6CEB1F80A4127CC7FC15 +005C143E147E147C5C495A495A5C495A010EC7FC5B5B903870018013E0EA018039030003 +0012065A001FB5FC5A485BB5FCA219267DA521>I E +%EndDVIPSBitmapFont +/Fg 103[60 26[60 1[60 60 60 60 60 60 60 60 60 60 60 60 +60 60 60 60 2[60 60 60 60 60 60 60 60 60 3[60 1[60 3[60 +60 1[60 60 1[60 60 1[60 60 3[60 1[60 1[60 60 60 1[60 +60 1[60 1[60 1[60 60 60 60 60 60 60 60 60 60 60 60 60 +60 60 5[60 38[{TeXBase1Encoding ReEncodeFont}62 99.6264 +/Courier rf +%DVIPSBitmapFont: Fh cmr8 8 2 +/Fh 2 51 df<130C133C137CEA03FC12FFEAFC7C1200B3B113FE387FFFFEA2172C7AAB23 +>49 DI E +%EndDVIPSBitmapFont +/Fi 105[50 28[50 50 2[55 33 39 44 1[55 50 55 83 28 2[28 +1[50 33 44 55 44 55 50 10[72 1[66 55 3[78 72 94 66 3[78 +1[61 66 72 72 66 72 13[50 50 50 1[28 25 33 45[{ +TeXBase1Encoding ReEncodeFont}40 99.6264 /Times-Bold +rf /Fj 139[40 1[53 1[66 60 66 100 33 2[33 3[53 3[60 23[47 +2[73 18[60 60 60 2[30 46[{TeXBase1Encoding ReEncodeFont}16 +119.552 /Times-Bold rf +%DVIPSBitmapFont: Fk cmsy10 12 1 +/Fk 1 16 df<49B4FC010F13E0013F13F8497F48B6FC4815804815C04815E04815F0A248 +15F8A24815FCA3B712FEA96C15FCA36C15F8A26C15F0A26C15E06C15C06C15806C15006C +6C13FC6D5B010F13E0010190C7FC27277BAB32>15 D E +%EndDVIPSBitmapFont +/Fl 64[44 42[44 44 24[44 50 50 72 50 50 28 39 33 50 50 +50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 6[61 1[72 +94 72 72 61 55 66 72 55 72 72 89 61 1[39 33 72 72 55 +61 72 66 66 72 3[56 1[28 28 50 50 50 50 50 50 50 50 50 +50 28 25 33 25 2[33 33 36[55 55 2[{TeXBase1Encoding ReEncodeFont}74 +99.6264 /Times-Roman rf +%DVIPSBitmapFont: Fm cmsy10 14.4 2 +/Fm 2 104 df102 +DI E +%EndDVIPSBitmapFont +/Fn 105[60 27[53 4[60 33 47 40 60 60 60 60 93 33 2[33 +1[60 40 53 60 53 60 53 7[86 4[73 66 1[86 66 3[73 2[40 +1[86 1[73 86 80 1[86 110 5[33 60 4[60 1[60 60 60 1[30 +40 30 44[{TeXBase1Encoding ReEncodeFont}42 119.552 /Times-Roman +rf /Fo 136[104 1[80 48 56 64 1[80 72 80 120 40 80 1[40 +1[72 1[64 80 64 80 72 12[96 80 104 1[88 1[104 135 3[56 +2[88 1[104 104 96 104 6[48 1[72 72 72 72 72 72 72 72 +72 1[36 46[{TeXBase1Encoding ReEncodeFont}41 143.462 +/Times-Bold rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin +%%BeginPaperSize: Letter +letter +%%EndPaperSize + +%%EndSetup +%%Page: 1 1 +1 0 bop 472 600 a Fo(DDDMP:)35 b(Decision)f(Diagram)f(DuMP)j(package) +1480 830 y(Release)e(2.0)462 1230 y Fn(Gianpiero)c(Cabodi)2402 +1232 y(Stef)o(ano)g(Quer)1316 1506 y(Politecnico)g(di)g(T)-10 +b(orino)1024 1656 y(Dip.)30 b(di)g(Automatica)g(e)g(Informatica)1119 +1805 y(Corso)f(Duca)h(de)n(gli)g(Abruzzi)g(24)1277 1955 +y(I\22610129)e(T)-5 b(urin,)29 b(IT)-11 b(AL)f(Y)1038 +2104 y(E-mail:)38 b Fm(f)p Fn(cabodi,quer)p Fm(g)p Fn(@polito.it)-189 +2614 y Fo(1)143 b(Intr)m(oduction)-189 2837 y Fl(The)27 +b(DDDMP)h(package)f(de\002nes)h(formats)f(and)g(rules)g(to)g(store)g +(DD)g(on)g(\002le.)39 b(More)27 b(in)g(particular)g(it)g(contains)g(a) +-189 2958 y(set)e(of)g(functions)e(to)i(dump)e(\(store)i(and)g(load\))g +(DDs)f(and)h(DD)g(forests)f(on)h(\002le)g(in)f(dif)n(ferent)h(formats.) +47 3078 y(In)30 b(the)g(present)g(implementation,)f(BDDs)h(\(R)l +(OBDDs\))h(and)f(ADD)g(\(Algebraic)g(Decision)g(Diagram\))g(of)-189 +3199 y(the)g(CUDD)g(package)g(\(v)o(ersion)f(2.3.0)g(or)h(higher\))g +(are)g(supported.)45 b(These)30 b(structures)f(can)h(be)g(represented)g +(on)-189 3319 y(\002les)25 b(either)g(in)f(te)o(xt,)g(binary)-6 +b(,)24 b(or)h(CNF)g(\(DIMA)l(CS\))h(formats.)47 3439 +y(The)f(main)f(rules)h(used)f(are)i(follo)n(wing)d(rules:)-44 +3643 y Fk(\017)49 b Fl(A)30 b(\002le)h(contains)e(a)i(single)e(BDD/ADD) +h(or)g(a)h(forest)f(of)g(BDDs/ADD,)g(i.e.,)i(a)e(v)o(ector)g(of)g +(Boolean)h(func-)55 3763 y(tions.)-44 3966 y Fk(\017)49 +b Fl(Inte)o(ger)21 b(inde)o(x)o(es)f(are)i(used)f(instead)g(of)g +(pointers)g(to)g(reference)i(nodes.)29 b(BDD/ADD)21 b(nodes)g(are)h +(numbered)55 4087 y(with)j(contiguous)g(numbers,)g(from)h(1)g(to)f +(NNodes)h(\(total)f(number)h(of)g(nodes)g(on)f(a)i(\002le\).)35 +b(0)26 b(is)f(not)h(used)f(to)55 4207 y(allo)n(w)f(ne)o(gati)n(v)o(e)e +(inde)o(x)o(es)h(for)i(complemented)f(edges.)-44 4411 +y Fk(\017)49 b Fl(A)23 b(\002le)g(contains)f(a)h(header)l(,)h +(including)d(se)n(v)o(eral)h(informations)f(about)h(v)n(ariables)h(and) +f(roots)g(of)h(BDD)h(func-)55 4531 y(tions,)32 b(then)e(the)h(list)g +(of)g(nodes.)49 b(The)32 b(header)f(is)g(al)o(w)o(ays)g(represented)h +(in)f(te)o(xt)f(format)h(\(also)g(for)g(binary)55 4651 +y(\002les\).)g(BDDs,)25 b(ADDs,)f(and)h(CNF)h(\002les)f(share)g(a)g +(similar)f(format)g(header)-5 b(.)-44 4855 y Fk(\017)49 +b Fl(BDD/ADD)40 b(nodes)g(are)h(listed)f(follo)n(wing)e(their)i +(numbering,)j(which)d(is)g(produced)g(by)h(a)f(post-order)55 +4975 y(tra)n(v)o(ersal,)24 b(in)h(such)f(a)h(w)o(ay)g(that)g(a)g(node)f +(is)h(al)o(w)o(ays)f(listed)g(after)h(its)f(Then/Else)g(children.)47 +5179 y(In)32 b(the)f(sequel)g(we)g(describe)h(more)f(in)g(detail)f(the) +h(dif)n(ferent)g(formats)g(and)g(procedures)h(a)n(v)n(ailable.)49 +b(First)-189 5299 y(of)26 b(all,)f(we)h(describe)f(BDDs)h(and)g(ADDs)f +(formats)g(and)g(procedure.)33 b(Secondly)-6 b(,)26 b(we)f(concentrate) +h(on)f(CNF)i(\002les,)-189 5419 y(i.e.,)e(ho)n(w)f(to)g(translate)g(a)i +(BDD)f(or)g(a)g(forest)g(of)f(BDDs)h(into)f(a)h(CNF)h(formula)e(and)h +(vice-v)o(ersa.)1794 5800 y(1)p eop +%%Page: 2 2 +2 1 bop -189 218 a Fo(2)143 b(BDD)35 b(and)g(ADD)g(Support)-189 +441 y Fl(In)23 b(this)f(section)g(we)g(describe)h(format)g(and)f +(procedure)h(re)o(garding)f(BDDs)h(and)f(ADDs.)30 b(W)-8 +b(e)23 b(speci\002cally)g(refer)g(to)-189 562 y(BDDs)h(in)g(the)g +(description)e(as)j(ADD)e(may)h(be)g(seen)g(as)h(an)f(e)o(xtension)e +(and)i(will)f(be)h(described)g(later)-5 b(.)30 b(First)24 +b(of)g(all,)-189 682 y(we)29 b(concentrate)f(on)g(the)g(format)g(used)g +(to)g(store)g(these)g(structure,)h(then)f(we)g(describe)h(the)f +(procedure)h(a)n(v)n(ailable)-189 802 y(to)24 b(store)h(and)g(load)f +(them.)-189 1094 y Fj(2.1)119 b(F)m(ormat)-189 1281 y +Fl(BDD)30 b(dump)f(\002les)g(are)i(composed)e(of)g(tw)o(o)g(sections:) +40 b(The)29 b(header)h(and)g(the)f(list)g(of)h(nodes.)44 +b(The)30 b(header)g(has)g(a)-189 1402 y(common)c(\(te)o(xt\))h(format,) +h(while)e(the)i(list)e(of)h(nodes)g(is)g(either)g(in)g(te)o(xt)g(or)g +(binary)g(format.)38 b(In)28 b(te)o(xt)e(format)h(nodes)-189 +1522 y(are)33 b(represented)f(with)f(redundant)g(informations,)h(where) +h(the)f(main)f(goal)g(is)h(readability)-6 b(,)32 b(while)g(the)f +(purpose)-189 1642 y(of)i(binary)f(format)g(is)g(minimizing)e(the)i(o)o +(v)o(erall)f(storage)h(size)h(for)g(BDD)f(nodes.)54 b(The)32 +b(header)h(format)f(is)g(k)o(ept)-189 1763 y(common)h(to)h(te)o(xt)g +(and)g(binary)g(formats)g(for)h(sak)o(e)f(of)h(simplicity:)47 +b(No)34 b(particular)g(optimization)f(is)h(presently)-189 +1883 y(done)29 b(on)f(binary)h(\002le)g(headers,)h(whose)f(size)g(is)f +(by)h(f)o(ar)g(dominated)f(by)h(node)f(lists)g(in)g(the)h(case)g(of)g +(lar)n(ge)h(BDDs)-189 2003 y(\(se)n(v)o(eral)24 b(thousands)g(of)h(DD)f +(nodes\).)-189 2266 y Fi(2.1.1)99 b(Header)-189 2453 +y Fl(The)23 b(header)h(has)f(the)g(same)g(format)g(both)g(for)g(te)o +(xtual)f(and)i(binary)e(dump.)30 b(F)o(or)23 b(sak)o(e)g(of)h +(generality)e(and)h(because)-189 2574 y(of)f(dynamic)g(v)n(ariable)g +(ordering)g(both)f(v)n(ariable)h(IDs)g(and)g(permutations)2377 +2537 y Fh(1)2438 2574 y Fl(are)h(included.)29 b(Names)22 +b(are)h(optionally)-189 2694 y(listed)35 b(for)h(input)f(v)n(ariables)g +(and)h(for)h(the)e(stored)h(functions.)63 b(Ne)n(w)36 +b(auxiliary)f(IDs)h(are)h(also)e(allo)n(wed.)64 b(Only)-189 +2814 y(the)34 b(v)n(ariables)f(in)g(the)h(true)g(support)f(of)h(the)f +(stored)h(BDDs)g(are)h(listed.)56 b(All)34 b(information)e(on)i(v)n +(ariables)f(\(IDs,)-189 2935 y(permutations,)c(names,)i(auxiliary)e +(IDs\))h(sorted)g(by)g(IDs,)h(and)e(the)o(y)h(are)g(restricted)g(to)f +(the)h(true)g(support)f(of)h(the)-189 3055 y(dumped)22 +b(BDD,)h(while)g(IDs)g(and)f(permutations)g(are)h(referred)i(to)d(the)h +(writing)f(BDD)h(manager)-5 b(.)30 b(Names)22 b(can)i(thus)-189 +3175 y(be)h(sorted)f(by)h(v)n(ariable)f(ordering)h(by)f(permuting)g +(them)g(according)h(to)f(the)h(permutations)e(stored)h(in)h(the)f +(\002le.)47 3296 y(As)h(an)g(e)o(xample,)f(the)g(header)i(\(in)e(te)o +(xt)g(mode\))h(of)f(the)h(ne)o(xt)f(state)h(functions)e(of)i(circuit)g +(s27)f(follo)n(ws:)-189 3494 y Fg(.ver)59 b(DDDMP-2.0)-189 +3615 y(.mode)g(A)-189 3735 y(.varinfo)f(3)-189 3855 y(.dd)h(s27-delta) +-189 3976 y(.nnodes)f(16)-189 4096 y(.nvars)g(10)-189 +4216 y(.nsuppvars)g(7)-189 4337 y(.varnames)g(G0)h(G1)g(G2)h(G3)f(G5)g +(G6)h(G7)-189 4457 y(.orderedvarnames)c(G0)k(G1)f(G2)g(G3)h(G5)f(G6)g +(G7)-189 4578 y(.ids)g(0)g(1)h(2)g(3)f(4)h(5)f(6)-189 +4698 y(.permids)f(0)i(1)f(2)h(3)f(5)h(7)f(9)-189 4818 +y(.auxids)f(1)i(2)f(3)h(4)f(5)h(6)g(7)-189 4939 y(.nroots)e(3)-189 +5059 y(.rootids)g(6)i(-13)f(-16)-189 5179 y(.rootnames)f(G10)h(G11)g +(G13)47 5378 y Fl(The)25 b(lines)f(contain)g(the)h(follo)n(wing)e +(informations:)p -189 5460 1607 4 v -77 5521 a Ff(1)-40 +5551 y Fe(The)d(permutation)e(of)i(the)g(i-th)h(v)n(ariable)e(ID)h(is)h +(the)f(relati)n(v)o(e)g(position)f(of)h(the)g(v)n(ariable)f(in)i(the)f +(ordering.)1794 5800 y Fl(2)p eop +%%Page: 3 3 +3 2 bop -44 218 a Fk(\017)49 b Fl(Dddmp)24 b(v)o(ersion)f(information.) +-44 411 y Fk(\017)49 b Fl(File)25 b(mode)f(\(A)h(for)g(ASCII)h(te)o +(xt,)e(B)h(for)g(binary)g(mode\).)-44 604 y Fk(\017)49 +b Fl(V)-11 b(ar)n(-e)o(xtra-info)25 b(\(0:)30 b(v)n(ariable)24 +b(ID,)h(1:)31 b(permID,)24 b(2:)31 b(aux)25 b(ID,)g(3:)30 +b(v)n(ariable)24 b(name,)h(4)g(no)f(e)o(xtra)h(info\).)-44 +797 y Fk(\017)49 b Fl(Name)25 b(of)g(dd)f(\(optional\).)-44 +990 y Fk(\017)49 b Fl(T)-8 b(otal)24 b(number)g(of)h(nodes)g(in)f(the)h +(\002le.)-44 1183 y Fk(\017)49 b Fl(Number)24 b(of)h(v)n(ariables)f(of) +h(the)g(writing)f(DD)g(manager)-5 b(.)-44 1375 y Fk(\017)49 +b Fl(Number)24 b(of)h(v)n(ariables)f(in)h(the)f(true)h(support)f(of)h +(the)f(stored)h(DDs.)-44 1568 y Fk(\017)49 b Fl(V)-11 +b(ariable)25 b(names)f(\(optional\))g(for)h(all)g(the)f(v)n(ariables)g +(in)h(the)f(BDD/ADD)h(support.)-44 1761 y Fk(\017)49 +b Fl(V)-11 b(ariable)20 b(names)g(for)h(all)f(the)g(v)n(ariables)f(in)h +(the)g(DD)h(manager)f(during)g(the)g(storing)f(phase.)29 +b(Notice)20 b(that)g(this)55 1882 y(information)k(w)o(as)h(not)g +(stored)g(by)g(pre)n(vious)f(v)o(ersions)g(of)i(the)f(same)g(tool.)32 +b(Full)25 b(backw)o(ard)g(compatibility)55 2002 y(is)f(guaranteed)h(by) +g(the)f(present)h(implementation)d(of)j(the)g(tool.)-44 +2195 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(IDs.)-44 +2388 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(permuted)f(IDs.)-44 +2581 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(auxiliary)f(IDs)h +(\(optional\).)-44 2774 y Fk(\017)49 b Fl(Number)24 b(of)h(BDD)g +(roots.)-44 2967 y Fk(\017)49 b Fl(Inde)o(x)o(es)24 b(of)h(BDD)g(roots) +f(\(complemented)g(edges)g(allo)n(wed\).)-44 3160 y Fk(\017)49 +b Fl(Names)24 b(of)h(BDD)h(roots)e(\(optional\).)-189 +3332 y(Notice)h(that)f(a)h(\002eld)-189 3504 y Fg(.add)-189 +3676 y Fl(is)f(present)h(after)g(the)g(dddmp)f(v)o(ersion)f(for)j +(\002les)e(containing)g(ADDs.)-189 3936 y Fi(2.1.2)99 +b(T)-9 b(ext)25 b(F)n(ormat)-189 4124 y Fl(In)g(te)o(xt)f(mode)g(nodes) +g(are)i(listed)e(on)g(a)h(te)o(xt)f(line)h(basis.)30 +b(Each)25 b(a)g(node)f(is)h(represented)g(as)-189 4296 +y Fg()57 b([])f()588 +4416 y()h()-189 4588 y Fl(where)25 +b(all)g(inde)o(x)o(es)e(are)j(inte)o(ger)e(numbers.)47 +4709 y(This)h(format)g(is)g(redundant)f(\(due)i(to)f(the)g(node)g +(ordering,)g Fd(<)p Fl(Node-inde)o(x)p Fd(>)f Fl(is)g(and)i +(incremental)e(inte)o(ger\))-189 4829 y(b)n(ut)g(we)h(k)o(eep)g(it)g +(for)g(readability)-6 b(.)47 4949 y Fd(<)p Fl(V)-11 b(ar)n(-e)o +(xtra-info)p Fd(>)34 b Fl(\(optional)e(redundant)i(\002eld\))g(is)f +(either)h(an)g(inte)o(ger)f(\(ID,)h(PermID,)g(or)g(auxID\))g(or)g(a) +-189 5070 y(string)k(\(v)n(ariable)h(name\).)75 b Fd(<)p +Fl(V)-11 b(ar)n(-internal-inde)o(x)p Fd(>)38 b Fl(is)h(an)g(internal)g +(v)n(ariable)g(inde)o(x:)59 b(V)-11 b(ariables)39 b(in)g(the)g(true) +-189 5190 y(support)25 b(of)h(the)g(stored)g(BDDs)g(are)h(numbered)e +(with)g(ascending)h(inte)o(gers)f(starting)g(from)h(0,)g(and)g(follo)n +(wing)e(the)-189 5311 y(v)n(ariable)g(ordering.)31 b +Fd(<)p Fl(Then-inde)o(x)p Fd(>)23 b Fl(and)i Fd(<)p Fl(Else-inde)o(x)p +Fd(>)e Fl(are)j(signed)e(inde)o(x)o(es)f(of)i(children)f(nodes.)47 +5431 y(In)h(the)f(follo)n(wing,)f(we)i(report)f(the)g(list)g(of)h +(nodes)f(of)g(the)h(s27)f(ne)o(xt)f(state)i(functions)e(\(see)i(pre)n +(vious)e(header)-189 5551 y(e)o(xample\):)1794 5800 y(3)p +eop +%%Page: 4 4 +4 3 bop -189 218 a Fg(.nodes)-189 338 y(1)60 b(T)f(1)h(0)f(0)-189 +459 y(2)h(G7)f(6)g(1)h(-1)-189 579 y(3)g(G5)f(4)g(1)h(2)-189 +699 y(4)g(G3)f(3)g(3)h(1)-189 820 y(5)g(G1)f(1)g(1)h(4)-189 +940 y(6)g(G0)f(0)g(5)h(-1)-189 1061 y(7)g(G6)f(5)g(1)h(-1)-189 +1181 y(8)g(G5)f(4)g(1)h(-7)-189 1301 y(9)g(G6)f(5)g(1)h(-2)-189 +1422 y(10)f(G5)h(4)f(1)h(-9)-189 1542 y(11)f(G3)h(3)f(10)h(8)-189 +1662 y(12)f(G1)h(1)f(8)h(11)-189 1783 y(13)f(G0)h(0)f(5)h(12)-189 +1903 y(14)f(G2)h(2)f(1)h(-1)-189 2024 y(15)f(G2)h(2)f(1)h(-2)-189 +2144 y(16)f(G1)h(1)f(14)h(15)-189 2264 y(.end)-189 2468 +y Fl(The)27 b(list)f(is)h(enclosed)g(between)g(the)g +Fg(.nodes)f Fl(and)h Fg(.end)f Fl(lines.)37 b(First)27 +b(node)g(is)g(the)g(one)g(constant,)f(each)i(node)-189 +2588 y(contains)c(the)h(optional)e(v)n(ariable)h(name.)47 +2708 y(F)o(or)29 b(ADDs)f(more)h(than)f(one)h(constant)e(is)i(stored)f +(in)g(the)g(\002le.)43 b(Each)29 b(constant)f(has)g(the)h(same)f +(format)h(we)-189 2829 y(ha)n(v)o(e)c(just)e(analyzed)i(for)g(the)g +(BDD)g(b)n(ut)g(the)f(represented)h(v)n(alue)f(is)h(stored)f(as)h(a)g +(\003oat)g(number)-5 b(.)-189 3095 y Fi(2.1.3)99 b(Binary)25 +b(F)n(ormat)-189 3283 y Fl(The)h(binary)g(format)f(is)h(not)f(allo)n +(wed)g(for)i(ADDs.)33 b(As)26 b(a)h(consequence)f(we)g(concentrate)g +(only)f(on)h(BDDs)g(in)g(this)-189 3403 y(section.)k(In)25 +b(binary)f(mode)h(nodes)f(are)i(represented)f(as)g(a)g(sequence)g(of)g +(bytes,)f(encoding)g(tuples)-189 3606 y Fg()-189 +3727 y([])-189 3847 y([])-189 +3968 y([])-189 4171 y Fl(in)30 b(an)g(optimized)f(w)o(ay)-6 +b(.)46 b(Only)29 b(the)h(\002rst)g(byte)g(\(code\))h(is)e(mandatory)-6 +b(,)30 b(while)g(inte)o(ger)f(inde)o(x)o(es)g(are)i(represented)-189 +4291 y(in)c(absolute)f(or)h(relati)n(v)o(e)f(mode,)h(where)h(relati)n +(v)o(e)e(means)g(of)n(fset)h(with)f(respect)i(to)e(a)i(Then/Else)e +(node)h(info.)37 b(The)-189 4412 y(best)23 b(between)g(absolute)f(and)h +(relati)n(v)o(e)e(representation)i(is)f(chosen)h(and)g(relati)n(v)o(e)f +(1)h(is)f(directly)g(coded)h(in)g Fd(<)p Fl(Node-)-189 +4532 y(code)p Fd(>)e Fl(without)f(an)o(y)g(e)o(xtra)h(info.)29 +b(Suppose)21 b(V)-11 b(ar\(NodeId\),)22 b(Then\(NodeId\))f(and)g +(Else\(NodeId\))f(represent)i(infos)-189 4652 y(about)i(a)h(gi)n(v)o +(en)f(node.)30 b Fd(<)p Fl(Node-code)p Fd(>)25 b Fl(is)f(a)h(byte)g +(which)f(contains)g(the)h(follo)n(wing)e(bit)h(\002elds)h(\(MSB)g(to)g +(LSB\))-44 4856 y Fk(\017)49 b Fl(Unused)24 b(:)31 b(1)24 +b(bit)-44 5059 y Fk(\017)49 b Fl(V)-11 b(ariable:)30 +b(2)25 b(bits,)f(one)h(of)g(the)f(follo)n(wing)f(codes)171 +5288 y Fi(\226)49 b Fl(DDDMP)p 636 5288 30 4 v 35 w(ABSOLUTE)p +1191 5288 V 36 w(ID:)22 b(V)-11 b(ar\(NodeId\))22 b(is)f(represented)h +(in)g(absolute)f(form)g(as)h Fd(<)p Fl(V)-11 b(ar)n(-internal-)270 +5408 y(info)p Fd(>)24 b Fl(=)h(V)-11 b(ar\(NodeId\))25 +b(follo)n(ws)e(\(absolute)i(info\))1794 5800 y(4)p eop +%%Page: 5 5 +5 4 bop 171 218 a Fi(\226)49 b Fl(DDDMP)p 636 218 30 +4 v 35 w(RELA)-11 b(TIVE)p 1147 218 V 36 w(ID:)32 b(V)-11 +b(ar\(NodeId\))32 b(is)g(represented)g(in)f(relati)n(v)o(e)g(form)h(as) +g Fd(<)p Fl(V)-11 b(ar)n(-internal-)270 338 y(info\277)24 +b(=)h(Min\(V)-11 b(ar\(Then\(NodeId\)\),V)g(ar\(Else\(NodeId\)\)\)-V)g +(ar\(NodeId\))171 500 y Fi(\226)49 b Fl(DDDMP)p 636 500 +V 35 w(RELA)-11 b(TIVE)p 1147 500 V 36 w(1:)27 b(the)19 +b(\002eld)g Fd(<)p Fl(V)-11 b(ar)n(-internal-info)p Fd(>)18 +b Fl(does)h(not)f(follo)n(w)-6 b(,)18 b(because)h(V)-11 +b(ar\(NodeId\))270 620 y(=)25 b(Min\(V)-11 b(ar\(Then\(NodeId\)\),V)g +(ar\(Else\(NodeId\)\)\)-1)171 782 y Fi(\226)49 b Fl(DDDMP)p +636 782 V 35 w(TERMIN)m(AL:)24 b(Node)h(is)f(a)h(terminal,)f(no)g(v)n +(ar)h(info)g(required)-44 1011 y Fk(\017)49 b Fl(T)25 +b(:)f(2)h(bits,)f(with)g(codes)h(similar)e(to)i(V)171 +1214 y Fi(\226)49 b Fl(DDDMP)p 636 1214 V 35 w(ABSOLUTE)p +1191 1214 V 36 w(ID:)20 b Fd(<)p Fl(Then-info)p Fd(>)f +Fl(is)h(represented)g(in)g(absolute)f(form)h(as)g Fd(<)p +Fl(Then-info)p Fd(>)270 1334 y Fl(=)25 b(Then\(NodeId\))171 +1496 y Fi(\226)49 b Fl(DDDMP)p 636 1496 V 35 w(RELA)-11 +b(TIVE)p 1147 1496 V 36 w(ID:)28 b(Then\(NodeId\))f(is)g(represented)h +(in)g(relati)n(v)o(e)e(form)i(as)g Fd(<)p Fl(Then-info)p +Fd(>)270 1617 y Fl(=)d(Nodeid-Then\(NodeId\))171 1779 +y Fi(\226)49 b Fl(DDDMP)p 636 1779 V 35 w(RELA)-11 b(TIVE)p +1147 1779 V 36 w(1:)30 b(no)25 b Fd(<)p Fl(Then-info)p +Fd(>)f Fl(follo)n(ws,)f(because)i(Then\(NodeId\))g(=)g(NodeId-1)171 +1941 y Fi(\226)49 b Fl(DDDMP)p 636 1941 V 35 w(TERMIN)m(AL:)24 +b(Then)h(Node)f(is)h(a)g(terminal,)f(no)g(info)h(required)f(\(for)i(R)l +(OBDDs\))-44 2144 y Fk(\017)49 b Fl(Ecompl)24 b(:)30 +b(1)25 b(bit,)f(if)h(1)g(means)f(that)g(the)h(else)g(edge)g(is)f +(complemented)-44 2347 y Fk(\017)49 b Fl(E)25 b(:)f(2)h(bits,)f(with)g +(codes)h(and)f(meanings)g(as)h(for)g(the)g(Then)f(edge)-189 +2551 y(DD)35 b(node)f(codes)h(are)h(written)e(as)h(one)g(byte.)60 +b Fd(<)p Fl(V)-11 b(ar)n(-internal-inde)o(x)p Fd(>)p +Fl(,)36 b Fd(<)p Fl(Then-inde)o(x)p Fd(>)p Fl(,)g Fd(<)p +Fl(Else-inde)o(x)p Fd(>)e Fl(\(if)-189 2671 y(required\))25 +b(are)h(represented)f(as)g(unsigned)e(inte)o(ger)h(v)n(alues)g(on)h(a)g +(suf)n(\002cient)f(set)h(of)g(bytes)f(\(MSByte)h(\002rst\).)47 +2792 y(Inte)o(gers)h(of)f(an)o(y)h(length)e(are)j(written)e(as)h +(sequences)g(of)g(\224link)o(ed\224)f(bytes)g(\(MSByte)h(\002rst\).)34 +b(F)o(or)26 b(each)g(byte)-189 2912 y(7)f(bits)f(are)h(used)g(for)g +(data)g(and)f(one)h(\(MSBit\))g(as)g(link)f(with)g(a)h(further)g(byte)g +(\(MSB)g(=)g(1)g(means)f(one)h(more)g(byte\).)47 3032 +y(Lo)n(w)f(le)n(v)o(el)g(read/write)h(of)g(bytes)f(\002lters)h +Fd(<)p Fl(CR)p Fd(>)p Fl(,)g Fd(<)p Fl(LF)p Fd(>)g Fl(and)g +Fd(<)p Fl(ctrl-Z)p Fd(>)f Fl(through)g(escape)h(sequences.)-189 +3327 y Fj(2.2)119 b(Implementation)-189 3515 y Fl(Store)24 +b(and)g(load)g(for)g(single)g(Boolean)g(functions)f(and)h(arrays)g(of)g +(Boolean)g(functions)f(are)i(implemented.)k(More-)-189 +3635 y(o)o(v)o(er)l(,)37 b(the)e(current)h(presentation)f(includes)f +(functions)h(to)g(retrie)n(v)o(e)g(v)n(ariables)f(names,)k(auxiliary)d +(identi\002erss,)-189 3756 y(and)c(all)g(the)g(information)f(contained) +h(in)f(the)h(header)h(of)f(the)h(\002les.)50 b(This)30 +b(information)g(can)h(be)h(used)f(as)g(a)g(pre-)-189 +3876 y(processing)19 b(step)g(for)i(load)e(operations.)28 +b(These)20 b(functions)f(allo)n(w)f(to)i(o)o(v)o(ercome)f(fe)n(w)g +(limitations)f(of)h(the)h(pre)n(vious)-189 3997 y(implementations.)-189 +4263 y Fi(2.2.1)99 b(Storing)25 b(Decision)g(Diagrams)-189 +4450 y Fc(Dddmp)p 111 4450 V 35 w(cuddBddStor)l(e)f Fl(and)h +Fc(Dddmp)p 1195 4450 V 35 w(cuddBddArr)o(ayStor)l(e)e +Fl(are)j(the)f(tw)o(o)f(store)h(functions,)f(used)h(to)g(store)f(sin-) +-189 4571 y(gle)f(BDD)h(or)g(a)f(forest)h(of)f(BDDs,)h(respecti)n(v)o +(ely)-6 b(.)28 b(Internally)-6 b(,)23 b Fc(Dddmp)p 2275 +4571 V 35 w(cuddBddStor)l(e)f Fl(b)n(uilds)g(a)i(dummy)e(1)h(entry)-189 +4691 y(array)j(of)e(BDDs,)h(and)g(calls)g Fc(dddmp)p +1102 4691 V 35 w(cuddBddArr)o(ayStor)l(e)p Fl(.)47 4811 +y(Since)30 b(con)l(v)o(ersion)e(from)h(DD)h(pointers)e(to)h(inte)o(ger) +f(is)h(required,)i(DD)e(nodes)g(are)h(temporarily)e(remo)o(v)o(ed)-189 +4932 y(from)23 b(the)f(unique)h(hash.)29 b(This)23 b(mak)o(es)f(room)g +(in)h(their)f Fc(ne)n(xt)h Fl(\002eld)h(to)e(store)h(node)f(IDs.)30 +b(Nodes)23 b(are)h(re-link)o(ed)e(after)-189 5052 y(the)i(store)g +(operation,)g(possible)f(in)g(a)i(modi\002ed)e(order)-5 +b(.)31 b(Dumping)22 b(is)i(either)g(in)g(te)o(xt)f(or)i(binary)f(form.) +30 b(Both)24 b(a)g(\002le)-189 5173 y(pointer)31 b(\()p +Fc(fp)p Fl(\))g(and)g(a)h(\002le)g(name)f(\()p Fc(fname)p +Fl(\))h(are)g(pro)o(vided)e(as)h(inputs)f(parameters)i(to)f(store)g +(routines.)50 b(BDDs)31 b(are)-189 5293 y(stored)c(to)g(the)g(already)g +(open)h(\002le)f Fc(fp)p Fl(,)h(if)f(not)g(NULL.)g(Otherwise)f(\002le)i +(whose)f(name)g(is)g Fc(fname)g Fl(is)g(opened.)38 b(This)-189 +5413 y(is)24 b(intended)g(to)h(allo)n(w)f(either)g(DD)h(storage)g +(within)e(\002les)i(containing)f(other)g(data,)h(or)g(to)g(speci\002c)g +(\002les.)1794 5800 y(5)p eop +%%Page: 6 6 +6 5 bop -189 218 a Fi(2.2.2)99 b(Loading)25 b(Decision)g(Diagrams)-189 +405 y Fc(Dddmp)p 111 405 30 4 v 35 w(cuddBddLoad)37 b +Fl(and)h Fc(Dddmp)p 1219 405 V 35 w(cuddBddArr)o(ayLoad)f +Fl(are)h(the)g(load)g(functions,)i(which)e(read)g(a)g(BDD)-189 +526 y(dump)24 b(\002le.)47 646 y(F)o(ollo)n(wing)34 b(the)h(store)h +(function,)h(the)f(main)f(BDD)h(load)f(function,)j Fc(Dddmp)p +2813 646 V 35 w(cuddBddLoad)p Fl(,)f(is)f(imple-)-189 +767 y(mented)g(by)g(calling)f(the)h(main)g(BDD-array)h(loading)f +(function)f Fc(Dddmp)p 2466 767 V 35 w(cuddBddArr)o(ayLoad)p +Fl(.)63 b(A)37 b(dynamic)-189 887 y(v)o(ector)24 b(of)h(DD)g(pointers)f +(is)g(temporarily)g(allocated)h(to)f(support)g(con)l(v)o(ersion)f(from) +i(DD)g(inde)o(x)o(es)e(to)h(pointers.)47 1007 y(Se)n(v)o(eral)40 +b(criteria)f(are)i(supported)d(for)i(v)n(ariable)f(match)g(between)g +(\002le)h(and)g(DD)f(manager)l(,)k(practically)-189 1128 +y(allo)n(wing)37 b(v)n(ariable)h(permutations)f(or)i(compositions)d +(while)i(loading)g(DDs.)71 b(V)-11 b(ariable)39 b(match)f(between)h +(the)-189 1248 y(DD)32 b(manager)g(and)g(the)g(BDD)g(\002le)g(is)g +(optionally)e(based)i(in)f Fc(IDs)p Fl(,)j Fc(perids)p +Fl(,)f Fc(varnames)p Fl(,)g Fc(var)o(auxids)p Fl(;)g(also)f(direct)-189 +1369 y(composition)j(between)j Fc(IDs)g Fl(and)f Fc(composeids)g +Fl(is)g(supported.)68 b(The)38 b Fc(varmatc)o(hmode)e +Fl(parameter)i(is)f(used)g(to)-189 1489 y(select)27 b(mathing)e(mode.) +37 b(More)27 b(in)f(detail,)h(tw)o(o)f(match)h(modes)f(use)h(the)f +(information)g(within)f(the)i(DD)g(manager)l(,)-189 1609 +y(the)e(other)f(ones)h(use)g(e)o(xtra)f(information,)f(which)i(support) +f(an)o(y)g(v)n(ariable)g(remap)h(or)g(change)g(in)f(the)h(ordering.)-44 +1813 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 1813 +V 35 w(V)-13 b(AR)p 1272 1813 V 35 w(MA)i(TCHIDS)19 b(allo)n(ws)f +(loading)g(a)h(DD)g(k)o(eeping)f(v)n(ariable)g(IDs)h(unchanged)55 +1933 y(\(re)o(gardless)24 b(of)h(the)f(v)n(ariable)h(ordering)f(of)h +(the)g(reading)f(manager)-5 b(.)55 2095 y(This)24 b(is)g(useful,)g(for) +h(e)o(xample,)f(when)g(sw)o(apping)g(DDs)g(to)h(\002le)g(and)f +(restoring)g(them)g(later)h(from)f(\002le,)h(after)55 +2215 y(possible)e(v)n(ariable)i(reordering)g(acti)n(v)n(ations.)-44 +2419 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 2419 +V 35 w(V)-13 b(AR)p 1272 2419 V 35 w(MA)i(TCHPERMIDS)36 +b(is)e(used)h(to)f(allo)n(w)g(v)n(ariable)g(match)h(according)55 +2539 y(to)h(the)h(position)e(in)i(the)g(ordering)f(\(retrie)n(v)o(ed)g +(by)h(array)h(of)f(permutations)e(stored)h(on)h(\002le)g(and)g(within) +55 2660 y(the)h(reading)g(DD)h(manager\).)72 b(A)38 b(possible)f +(application)h(is)g(retrie)n(ving)f(BDDs)i(stored)f(after)h(dynamic)55 +2780 y(reordering,)28 b(from)g(a)g(DD)g(manager)g(where)h(all)e(v)n +(ariable)h(IDs)f(map)h(their)f(position)g(in)g(the)h(ordering,)g(and)55 +2900 y(the)d(loaded)f(BDD)h(k)o(eeps)g(the)g(ordering)f(as)h(stored)f +(on)h(\002le.)-44 3104 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p +1040 3104 V 35 w(V)-13 b(AR)p 1272 3104 V 35 w(MA)i(TCHN)m(AMES)26 +b(requires)h(a)h(not)e(NULL)h(v)n(armatchmodes)f(param-)55 +3224 y(eter;)34 b(this)c(is)g(a)h(v)o(ector)g(of)g(strings)e(in)i +(one-to-one)f(correspondence)h(with)f(v)n(ariable)h(IDs)f(of)h(the)g +(reading)55 3344 y(manager)-5 b(.)40 b(V)-11 b(ariables)28 +b(in)g(the)g(DD)g(\002le)g(read)h(are)g(matched)f(with)f(manager)h(v)n +(ariables)f(according)h(to)g(their)55 3465 y(name)35 +b(\(a)h(not)f(NULL)g(v)n(arnames)g(parameter)h(w)o(as)f(required)h +(while)f(storing)f(the)h(DD)g(\002le\).)64 b(The)35 b(most)55 +3585 y(common)c(usage)h(of)g(this)f(feature)i(is)e(in)h(combination)e +(with)i(a)g(v)n(ariable)g(ordering)g(stored)f(on)h(a)g(\002le)h(and)55 +3706 y(based)28 b(on)h(v)n(ariables)f(names.)41 b(Names)29 +b(must)e(be)i(loaded)f(in)g(an)h(array)g(of)g(strings)e(and)i(passed)f +(to)g(the)h(DD)55 3826 y(load)24 b(procedure.)-44 4029 +y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 4029 V +35 w(V)-13 b(AR)p 1272 4029 V 35 w(MA)i(TCHIDS)25 b(has)g(a)g(meaning)f +(similar)g(to)55 4150 y(DDDMP)p 421 4150 V 36 w(V)-13 +b(AR)p 654 4150 V 35 w(MA)i(TCHN)m(AMES)26 b(b)n(ut)h(inte)o(ger)f +(auxiliary)g(IDs)h(are)h(used)f(instead)f(of)h(strings.)36 +b(The)28 b(ad-)55 4270 y(ditional)23 b(not)h(NULL)h(v)n(armathauxids)e +(parameter)i(is)g(needed.)-44 4474 y Fk(\017)49 b Fl(v)n +(armatchnode=DDDMP)p 1040 4474 V 35 w(V)-13 b(AR)p 1272 +4474 V 35 w(COMPOSEIDS,)38 b(uses)f(the)f(additional)f(v)n +(arcomposeids)g(parameter)55 4594 y(as)25 b(an)g(array)g(of)g(v)n +(ariable)f(IDs)h(to)g(be)g(composed)f(with)g(IDs)g(stored)h(in)f +(\002le.)-189 4860 y Fi(2.2.3)99 b(DD)25 b(Load/Stor)n(e)h(and)f(V)-9 +b(ariable)25 b(Ordering)-189 5048 y Fl(Loading)31 b(of)i(Decision)e +(Diagrams)h(from)g(\002le)g(supports)f(dif)n(ferent)h(v)n(ariables)g +(ordering)f(strate)o(gies,)i(as)g(already)-189 5168 y(pointed)23 +b(out)h(in)g(the)h(pre)n(vious)e(section.)30 b(This)24 +b(allo)n(ws)f(or)h(e)o(xample)g(storing)f(dif)n(ferent)i(BDDs)f(each)h +(with)f(its)g(o)n(wn)-189 5288 y(v)n(ariable)29 b(ordering,)h(and)g(to) +f(mer)n(ge)h(them)f(within)f(the)i(same)f(DD)h(manager)f(by)h(means)f +(of)g(proper)h(load)f(opera-)-189 5409 y(tions.)44 b(W)-8 +b(e)30 b(suggest)f(using)f(DDDMP)p 1175 5409 V 36 w(V)-13 +b(AR)p 1408 5409 V 36 w(MA)i(TCHIDS)30 b(whene)n(v)o(er)f(IDs)g(k)o +(eeps)h(on)f(representing)h(the)f(same)-189 5529 y(entities)24 +b(while)h(changing)f(v)n(ariable)h(ordering.)31 b(If)25 +b(this)f(is)h(not)f(true,)h(v)n(ariable)g(names)g(\(if)g(a)n(v)n +(ailable\))f(or)i(auxiliary)1794 5800 y(6)p eop +%%Page: 7 7 +7 6 bop -189 218 a Fl(IDs)34 b(are)h(a)g(good)e(w)o(ay)i(to)f +(represent)g(in)l(v)n(ariant)f(attrib)n(uted)g(of)i(v)n(ariables)e +(across)h(se)n(v)o(eral)g(runs)g(with)f(dif)n(ferent)-189 +338 y(orderings.)50 b(DDDMP)p 629 338 30 4 v 35 w(V)-13 +b(AR)p 861 338 V 36 w(COMPOSEIDS)32 b(is)f(an)h(alternati)n(v)o(e)e +(solution,)h(that)g(practically)f(corresponds)h(to)-189 +459 y(cascading)23 b(DDDMP)p 593 459 V 36 w(V)-13 b(AR)p +826 459 V 36 w(MA)i(TCHIDS)23 b(and)h(v)n(ariable)f(composition)e(with) +h(a)i(gi)n(v)o(en)e(array)i(of)g(ne)n(w)f(v)n(ariables.)-189 +797 y Fo(3)143 b(CNF)35 b(Support)-189 1050 y Fj(3.1)119 +b(F)m(ormat)-189 1237 y Fl(Gi)n(v)o(en)30 b(a)h(BDD)g(representing)g(a) +g(function)f Fd(f)11 b Fl(,)32 b(we)f(de)n(v)o(elop)f(three)h(basic)g +(possible)e(w)o(ays)i(to)g(store)f(it)h(as)g(a)g(CNF)-189 +1358 y(formula.)54 b(In)33 b(each)h(method)d(the)i(set)g(of)f(clauses)h +(is)f(written)h(after)g(an)g(header)g(part.)55 b(Only)32 +b(the)h(te)o(xt)f(format)g(is)-189 1478 y(allo)n(wed.)-189 +1743 y Fi(3.1.1)99 b(Header)-189 1931 y Fl(The)23 b(header)h(part)f(of) +g(each)h(CNF)g(\002le)f(has)g(basically)g(the)f(same)h(format)g +(analyzed)g(for)h(the)f(BDD/ADD)g(\002les.)30 b(F)o(or)-189 +2051 y(e)o(xample)h(the)g Fg(.rootids)f Fl(line)h(indicates)f(the)i(be) +o(ginning)d(of)j(each)g(CNF)g(formula)f(represented)h(by)f(a)h(single) +-189 2172 y(BDD.)j(T)-8 b(o)34 b(be)g(compatible)f(with)h(the)g(DIMA)l +(CS)h(format)f(each)h(header)f(line)g(start)g(with)g(the)g(character)h +(\223c\224)g(to)-189 2292 y(indicate)24 b(a)h(comment.)-189 +2557 y Fi(3.1.2)99 b(T)-9 b(ext)25 b(F)n(ormat)-189 2745 +y Fl(The)j(\002rst)g(method,)g(which)f(we)h(call)g Fi(Single-Node-Cut)p +Fl(,)j(models)26 b(each)j(BDD)f(nodes,)h(b)n(ut)e(the)h(ones)f(with)h +(both)-189 2865 y(the)c(children)g(equal)h(to)f(the)g(constant)g(node)g +Fb(1)p Fl(,)g(as)h(a)g(multiple)o(x)o(er)-5 b(.)27 b(Each)e(multiple)o +(x)o(er)d(has)i(tw)o(o)g(data)h(inputs)e(\(i.e.,)-189 +2985 y(the)k(node)h(children\),)f(a)h(selection)f(input)f(\(i.e.,)i +(the)g(node)f(v)n(ariable\))g(and)h(one)f(output)f(\(i.e.,)i(the)g +(function)e(v)n(alue\))-189 3106 y(whose)h(v)n(alue)f(is)h(assigned)f +(to)h(an)g(additional)f(CNF)i(v)n(ariable.)37 b(The)27 +b(\002nal)h(number)e(of)h(v)n(ariables)g(is)f(equal)h(to)g(the)-189 +3226 y(number)d(of)h(original)f(BDD)h(v)n(ariables)f(plus)g(the)h +(number)f(of)h(\223internal\224)g(nodes)f(of)h(the)g(BDD.)47 +3346 y(The)k(second)f(method,)g(which)h(we)f(call)h Fi(Maxterm-Cut)p +Fl(,)h(create)g(clauses)e(starting)g(from)g Fd(f)39 b +Fl(corresponds)-189 3467 y(to)25 b(the)h(of)n(f-set)g(\(i.e.,)f(all)h +(the)g(paths-cubes)f(from)g(the)h(root)g(node)f(to)h(the)f(terminal)g +Fg(0)p Fl(\))h(of)g(the)g(function)e Fd(f)11 b Fl(.)34 +b(W)l(ithin)-189 3587 y(the)29 b(BDD)g(for)g Fd(f)11 +b Fl(,)30 b(such)f(clauses)f(are)i(found)e(by)h(follo)n(wing)e(all)i +(the)f(paths)h(from)f(the)h(root)g(node)f(of)h(the)g(BDD)g(to)-189 +3708 y(the)c(constant)f(node)g Fb(0)p Fl(.)31 b(The)25 +b(\002nal)g(number)f(of)h(v)n(ariables)f(is)g(equal)h(to)f(the)h +(number)f(of)h(original)f(BDD)h(v)n(ariables.)47 3828 +y(The)k(third)g(method,)g(which)g(we)g(call)g Fi(A)-5 +b(uxiliary-V)c(ariable-Cut)p Fl(,)30 b(is)f(a)h(trade-of)n(f)f(between) +g(the)g(\002rst)g(tw)o(o)-189 3948 y(strate)o(gies.)69 +b(Internal)37 b(v)n(ariables,)j(i.e.,)h(cutting)c(points,)j(are)e +(added)g(in)f(order)h(to)g(decompose)f(the)h(BDD)g(into)-189 +4069 y(multiple)27 b(sub-trees)i(each)h(of)f(which)f(is)h(stored)g +(follo)n(wing)e(the)h(second)h(strate)o(gy)-6 b(.)42 +b(The)29 b(trade-of)n(f)g(is)g(guided)f(by)-189 4189 +y(the)23 b(cutting)f(point)g(selection)g(strate)o(gy)-6 +b(,)22 b(and)h(we)g(e)o(xperiment)f(with)g(tw)o(o)g(methodologies.)28 +b(In)23 b(the)g(\002rst)g(method,)g(a)-189 4310 y(ne)n(w)f(CNF)h(v)n +(ariable)f(is)f(inserted)h(in)g(correspondence)g(to)g(the)g(shared)g +(nodes)g(of)g(the)h(BDD,)f(i.e.,)h(the)f(nodes)f(which)-189 +4430 y(ha)n(v)o(e)29 b(more)g(than)h(one)f(incoming)f(edge.)45 +b(This)29 b(technique,)h(albeit)e(optimizing)g(the)h(number)g(of)h +(literals)e(stored,)-189 4550 y(can)35 b(produce)g(clauses)f(with)g(a)h +(high)f(number)h(of)f(literals)1894 4514 y Fh(2)1933 +4550 y Fl(.)60 b(T)-8 b(o)35 b(a)n(v)n(oid)f(this)g(dra)o(wback,)j(the) +e(second)f(method,)-189 4671 y(introduces)28 b(all)g(the)g(pre)n +(viously)e(indicated)i(cutting)f(points)g(more)h(the)h(ones)f +(necessary)g(to)g(break)h(the)f(length)g(of)-189 4791 +y(the)d(path)f(to)h(a)g(maximum)e(\(user\))i(selected)g(v)n(alue.)47 +4911 y(Actually)-6 b(,)37 b(all)f(the)f(methods)g(described)h(abo)o(v)o +(e)e(can)j(be)e(re-conducted)h(to)g(the)f(basic)h(idea)g(of)g(possibly) +-189 5032 y(breaking)24 b(the)h(BDD)g(through)f(the)g(use)h(of)f +(additional)g(cutting)f(v)n(ariables)h(and)h(dumping)e(the)h(paths)g +(between)h(the)-189 5152 y(root)34 b(of)h(the)f(BDD,)h(the)g(cutting)e +(v)n(ariables)h(and)g(the)h(terminal)e(nodes.)60 b(Such)35 +b(internal)f(cutting)f(v)n(ariables)h(are)-189 5273 y(added)25 +b(al)o(w)o(ays)f(\(for)i(each)f(node\),)g(ne)n(v)o(er)f(or)h(sometimes) +e(respecti)n(v)o(ely)-6 b(.)p -189 5360 1607 4 v -77 +5422 a Ff(2)-40 5452 y Fe(This)27 b(v)n(alue)f(is)i(superiorly)d +(limited)h(by)g(the)h(number)e(of)h(v)n(ariables)g(of)g(the)h(BDD,)g +(i.e.,)h(the)f(longest)f(path)g(from)g(the)h(root)f(to)g(the)-189 +5551 y(terminal)19 b(node.)1794 5800 y Fl(7)p eop +%%Page: 8 8 +8 7 bop 47 218 a Fl(While)33 b(the)f Fc(Single-Node-Cut)h +Fl(method)f(minimizes)f(the)i(length)f(of)h(the)f(clauses)h(produced,)i +(b)n(ut)d(it)g(also)-189 338 y(requires)d(the)h(higher)f(number)g(of)g +(CNF)i(v)n(ariables,)e(the)h Fc(Maxterm-Cut)f Fl(technique)g(minimizes) +f(the)h(number)g(of)-189 459 y(CNF)36 b(v)n(ariables)d(required.)61 +b(This)34 b(adv)n(antage)g(is)g(counter)n(-balanced)h(by)f(the)h(f)o +(act)g(that)f(in)g(the)h(w)o(orst)f(case)h(the)-189 579 +y(number)23 b(of)g(clauses,)g(as)h(well)e(as)i(the)f(total)f(number)h +(of)g(literals,)g(produced)g(is)g(e)o(xponential)e(in)i(the)g(BDD)h +(size)f(\(in)-189 699 y(terms)28 b(of)i(number)e(of)h(nodes\).)43 +b(The)29 b(application)f(of)h(this)f(method)g(is)g(then)h(limited)e(to) +i(the)g(cases)g(in)f(which)h(the)-189 820 y(\223of)n(f-set\224)c(of)f +(the)g(represented)h(function)f Fd(f)35 b Fl(has)24 b(a)h(small)f +(cardinality)-6 b(.)29 b(The)c Fc(A)n(uxiliary-V)-11 +b(ariable-Cut)22 b Fl(strate)o(gy)h(is)-189 940 y(a)k(trade-of)n(f)h +(between)f(the)g(\002rst)g(tw)o(o)g(methods)f(and)h(the)g(ones)f(which) +h(gi)n(v)o(es)f(more)h(compact)f(results.)37 b(As)27 +b(a)h(\002nal)-189 1061 y(remark)f(notice)e(that)h(the)g(method)g(is)f +(able)i(to)f(store)g(both)f(monolithic)f(BDDs)j(and)f(conjuncti)n(v)o +(e)e(forms.)35 b(In)26 b(each)-189 1181 y(case)f(we)g(generate)h(CNF)f +(\002les)g(using)f(the)h(standard)f(DIMA)l(CS)i(format.)-189 +1365 y Fi(Example)f(1)49 b Fc(F)l(igur)l(e)20 b(1)h(shows)f(an)h(e)n +(xample)g(of)f(how)h(our)f(pr)l(ocedur)l(e)h(works)f(to)h(stor)l(e)f(a) +h(small)f(monolithic)f(BDD.)-189 1486 y(F)l(igur)l(e)j(1\(a\))h(r)l +(epr)l(esents)g(a)g(BDD)g(with)g Fb(4)g Fc(nodes.)30 +b(BDD)23 b(variables)f(ar)l(e)h(named)g(after)f(inte)l(g)o(er)g(number) +o(s)h(r)o(anging)-189 1606 y(fr)l(om)k Fb(1)h Fc(to)g +Fb(4)p Fc(,)h(to)f(have)g(an)g(easy-to-follow)f(corr)l(espondence)h +(with)g(the)g(CNF)h(variables.)40 b(F)l(igur)l(e)27 b(1\(b\),)i(\(c\))g +(and)-189 1727 y(\(d\))c(show)g(the)f(corr)l(esponding)f(CNF)j(r)l(epr) +l(esentations)d(g)o(ener)o(ated)h(by)h(our)f(thr)l(ee)h(methods.)30 +b(As)24 b(in)h(the)f(standar)l(d)-189 1847 y(format)i +Fa(p)i Fc(indicates)e(the)h(total)f(number)g(of)h(variables)f(used)h +(\()p Fb(4)g Fc(is)g(the)g(minimum)f(value)h(as)g(the)g(BDD)g(itself)f +(has)-189 1967 y Fb(4)f Fc(variables\),)e(and)i Fa(cnf)g +Fc(the)f(total)g(number)g(of)h(clauses.)47 2088 y(As)i(a)g(\002nal)f(r) +l(emark)h(notice)f(that)g(for)g(this)g(speci\002c)h(e)n(xample)g(the)f +(\223Maxterm-Cut\224)i(appr)l(oac)o(h)d(is)h(the)h(one)-189 +2208 y(whic)o(h)36 b(gives)g(the)g(most)f(compact)h(CNF)h(r)l(epr)l +(esentation)e(b)n(ut)h(also)f(the)h(clause)g(with)g(the)g(lar)l(g)o +(est)g(number)f(of)-189 2328 y(liter)o(als)23 b(\()p +Fb(4)p Fc(\).)188 2471 y + 6339814 10777681 0 0 11709153 19997655 startTexFig + 188 2471 a +%%BeginDocument: bdd.eps +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: bdd.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3c +%%CreationDate: Mon Sep 9 14:21:26 2002 +%%For: quer@pcsq (Stefano Quer) +%%BoundingBox: 0 0 178 304 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 304 moveto 0 0 lineto 178 0 lineto 178 304 lineto closepath clip newpath +-51.0 319.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawEllipse { + /endangle exch def + /startangle exch def + /yrad exch def + /xrad exch def + /y exch def + /x exch def + /savematrix mtrx currentmatrix def + x y tr xrad yrad sc 0 0 1 startangle endangle arc + closepath + savematrix setmatrix + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06299 0.06299 sc +% +% Fig objects follow +% +% Polyline +15.000 slw +n 2010 4515 m 2550 4515 l 2550 5040 l 2010 5040 l + cp gs col0 s gr +/Times-Roman ff 300.00 scf sf +2205 4875 m +gs 1 -1 sc (1) col0 sh gr +% Ellipse +n 1515 1800 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2250 900 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2970 2715 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2280 3705 270 270 0 360 DrawEllipse gs col0 s gr + +7.500 slw +% Ellipse +n 3555 3555 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2712 1726 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2430 4230 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Polyline +15.000 slw +n 2805 2910 m + 2250 3450 l gs col0 s gr +% Polyline + [90] 0 sd +gs clippath +2940 2472 m 3010 2445 l 2931 2239 l 2957 2411 l 2861 2266 l cp +eoclip +n 2460 1110 m + 2970 2445 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 2861 2266 m 2957 2411 l 2931 2239 l 2908 2284 l 2861 2266 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +1478 1511 m 1528 1568 l 1693 1422 l 1542 1506 l 1643 1366 l cp +eoclip +n 2025 1080 m + 1515 1530 l gs col0 s gr gr + +% arrowhead +n 1643 1366 m 1542 1506 l 1693 1422 l 1643 1416 l 1643 1366 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +2212 645 m 2287 645 l 2287 425 l 2250 594 l 2212 425 l cp +eoclip +n 2250 270 m + 2250 630 l gs col0 s gr gr + +% arrowhead +n 2212 425 m 2250 594 l 2287 425 l 2250 459 l 2212 425 l + cp gs 0.00 setgray ef gr col0 s +% Polyline + [90] 0 sd +gs clippath +2692 2664 m 2732 2601 l 2546 2485 l 2670 2606 l 2506 2548 l cp +eoclip +n 1710 2010 m + 2700 2625 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 2506 2548 m 2670 2606 l 2546 2485 l 2555 2534 l 2506 2548 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj + [90] 0 sd +gs clippath +2504 4653 m 2539 4720 l 2733 4616 l 2567 4663 l 2698 4550 l cp +eoclip +n 3180 2910 m 3181 2911 l 3183 2913 l 3186 2916 l 3192 2921 l 3200 2929 l + 3210 2939 l 3223 2951 l 3238 2966 l 3255 2984 l 3274 3003 l + 3295 3025 l 3317 3049 l 3339 3075 l 3362 3103 l 3385 3131 l + 3407 3161 l 3429 3192 l 3450 3225 l 3470 3258 l 3488 3293 l + 3504 3329 l 3519 3367 l 3531 3406 l 3541 3447 l 3548 3490 l + 3552 3536 l 3552 3583 l 3548 3634 l 3540 3686 l 3528 3740 l + 3510 3795 l 3490 3844 l 3467 3892 l 3441 3939 l 3413 3985 l + 3382 4028 l 3350 4070 l 3317 4110 l 3283 4148 l 3248 4184 l + 3211 4219 l 3174 4253 l 3136 4285 l 3098 4316 l 3059 4347 l + 3020 4376 l 2980 4405 l 2941 4432 l 2901 4459 l 2862 4484 l + 2824 4509 l 2787 4532 l 2751 4554 l 2717 4575 l 2686 4593 l + 2657 4610 l 2631 4626 l 2608 4639 l 2589 4650 l 2572 4659 l + 2559 4666 l 2550 4672 l + 2535 4680 l gs col0 s gr gr + [] 0 sd +% arrowhead +0 slj +n 2698 4550 m 2567 4663 l 2733 4616 l 2686 4599 l 2698 4550 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +1985 4734 m 2028 4672 l 1847 4548 l 1965 4675 l 1804 4609 l cp +eoclip +n 1350 2025 m 1349 2026 l 1348 2027 l 1345 2030 l 1340 2035 l 1334 2042 l + 1325 2051 l 1314 2063 l 1301 2078 l 1286 2095 l 1268 2114 l + 1249 2137 l 1227 2161 l 1205 2188 l 1181 2218 l 1156 2249 l + 1131 2282 l 1105 2316 l 1080 2352 l 1054 2390 l 1029 2428 l + 1005 2468 l 981 2509 l 959 2552 l 938 2595 l 918 2640 l + 900 2687 l 884 2736 l 870 2786 l 858 2839 l 848 2894 l + 841 2951 l 837 3011 l 836 3074 l 838 3139 l 845 3206 l + 855 3275 l 870 3345 l 888 3412 l 910 3477 l 934 3542 l + 961 3604 l 990 3665 l 1022 3723 l 1054 3779 l 1088 3833 l + 1124 3885 l 1160 3935 l 1198 3983 l 1236 4029 l 1275 4074 l + 1315 4118 l 1356 4160 l 1397 4201 l 1438 4241 l 1480 4280 l + 1522 4318 l 1563 4355 l 1605 4390 l 1645 4424 l 1685 4457 l + 1723 4488 l 1760 4517 l 1795 4545 l 1827 4570 l 1857 4593 l + 1884 4613 l 1909 4632 l 1930 4647 l 1947 4660 l 1962 4671 l + 1973 4679 l 1982 4686 l + 1995 4695 l gs col0 s gr gr + +% arrowhead +0 slj +n 1804 4609 m 1965 4675 l 1847 4548 l 1854 4598 l 1804 4609 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj + [90] 0 sd +gs clippath +2300 4492 m 2363 4532 l 2481 4347 l 2359 4470 l 2417 4307 l cp +eoclip +n 2340 3960 m 2341 3962 l 2344 3966 l 2348 3973 l 2354 3982 l 2362 3995 l + 2370 4010 l 2379 4028 l 2389 4046 l 2397 4066 l 2406 4088 l + 2413 4111 l 2420 4137 l 2425 4165 l 2429 4197 l 2430 4230 l + 2429 4263 l 2425 4295 l 2420 4323 l 2413 4349 l 2406 4372 l + 2397 4394 l 2389 4414 l 2379 4433 l 2370 4450 l 2362 4465 l + 2354 4478 l + 2340 4500 l gs col0 s gr gr + [] 0 sd +% arrowhead +0 slj +n 2417 4307 m 2359 4470 l 2481 4347 l 2431 4356 l 2417 4307 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +2136 4532 m 2199 4492 l 2082 4307 l 2141 4470 l 2018 4347 l cp +eoclip +n 2160 3960 m 2159 3962 l 2156 3966 l 2152 3973 l 2146 3982 l 2138 3995 l + 2130 4010 l 2121 4028 l 2111 4046 l 2103 4066 l 2094 4088 l + 2087 4111 l 2080 4137 l 2075 4165 l 2071 4197 l 2070 4230 l + 2071 4263 l 2075 4295 l 2080 4323 l 2087 4349 l 2094 4372 l + 2103 4394 l 2111 4414 l 2121 4433 l 2130 4450 l 2138 4465 l + 2146 4478 l + 2160 4500 l gs col0 s gr gr + +% arrowhead +0 slj +n 2018 4347 m 2141 4470 l 2082 4307 l 2068 4356 l 2018 4347 l + cp gs 0.00 setgray ef gr col0 s +/Times-Roman ff 300.00 scf sf +2175 990 m +gs 1 -1 sc (1) col0 sh gr +/Times-Roman ff 300.00 scf sf +1440 1890 m +gs 1 -1 sc (2) col0 sh gr +/Times-Roman ff 300.00 scf sf +2895 2805 m +gs 1 -1 sc (3) col0 sh gr +/Times-Roman ff 300.00 scf sf +2205 3795 m +gs 1 -1 sc (4) col0 sh gr +$F2psEnd +rs + +%%EndDocument + + endTexFig + 531 3990 a Fc(\(a\))1512 2504 y Fg(p)60 b(cnf)f(7)g(11)1512 +2624 y(-5)g(3)h(0)1512 2745 y(-5)f(4)h(0)1512 2865 y(5)g(-3)f(-4)g(0) +1512 2985 y(6)h(-2)f(0)1512 3106 y(6)h(-5)f(0)1512 3226 +y(-6)g(2)h(5)f(0)1512 3347 y(7)h(1)f(5)h(0)1512 3467 +y(-7)f(1)h(-5)f(0)1512 3587 y(7)h(-1)f(-6)g(0)1512 3708 +y(-7)g(-1)h(6)f(0)1512 3828 y(7)h(0)1836 3990 y Fc(\(b\))2541 +2525 y Fg(p)f(cnf)g(4)h(3)2541 2645 y(1)f(-3)h(-4)f(0)2541 +2766 y(-1)g(2)h(3)f(0)2541 2886 y(-1)g(2)h(-3)f(4)h(0)2868 +3048 y Fc(\(c\))2541 3251 y Fg(p)f(cnf)g(5)h(5)2541 3371 +y(-5)f(1)h(0)2541 3492 y(5)f(-1)h(2)f(0)2541 3612 y(-3)g(-4)g(5)h(0) +2541 3733 y(3)f(-5)h(0)2541 3853 y(-3)f(4)h(-5)f(0)2865 +3990 y Fc(\(d\))-189 4138 y Fl(Figure)46 b(1:)71 b(\(a\))47 +b(BDD;)e(\(b\))h(\223Single-Node-Cut\224)g(format;)55 +b(\(c\))46 b(\223Maxterm-Cut\224)g(format;)55 b(\(d\))45 +b(\223)-8 b(Auxiliary-)-189 4258 y(V)d(ariable-Cut\224)25 +b(F)o(ormat.)-189 4625 y Fj(3.2)119 b(Implementation)-189 +4813 y Fl(Store)25 b(and)g(Load)g(for)g(a)g(single)f(BDD)h(or)g(a)g +(forest)g(of)g(BDDs)g(is)f(currently)h(implemented.)-189 +5073 y Fi(3.2.1)99 b(Storing)25 b(Decision)g(Diagrams)f(as)g(CNF)h(F)n +(ormulas)-189 5260 y Fl(As)g(f)o(ar)g(as)g(the)g(storing)e(process)i +(is)f(concerned)i(three)f(possible)e(formats)h(are)i(a)n(v)n(ailable:) +-44 5431 y Fk(\017)49 b Fl(DDDMP)p 421 5431 30 4 v 36 +w(CNF)p 650 5431 V 36 w(MODE)p 980 5431 V 35 w(NODE:)21 +b(store)f(a)h(BDD)h(by)e(introducing)f(an)i(auxiliary)g(v)n(ariable)f +(for)h(each)g(BDD)55 5551 y(node)1794 5800 y(8)p eop +%%Page: 9 9 +9 8 bop -44 218 a Fk(\017)49 b Fl(DDDMP)p 421 218 30 +4 v 36 w(CNF)p 650 218 V 36 w(MODE)p 980 218 V 35 w(MAXTERM:)20 +b(store)g(a)h(BDD)h(by)e(follo)n(wing)f(the)h(maxterm)g(of)h(the)g +(represented)55 338 y(function)-44 542 y Fk(\017)49 b +Fl(DDDMP)p 421 542 V 36 w(CNF)p 650 542 V 36 w(MODE)p +980 542 V 35 w(BEST)-5 b(:)32 b(trade-of)f(between)h(the)f(tw)o(o)f +(pre)n(vious)g(solution,)h(trying)f(to)h(optimize)55 +662 y(the)25 b(number)f(of)h(literals)f(stored.)-189 +865 y(See)c(procedures)f(Dddmp)p 736 865 V 35 w(cuddBddStoreCnf)g(\(to) +g(store)f(a)h(single)f(BDD)i(as)e(a)i(CNF)f(formula\))g(and)g(Dddmp)p +3609 865 V 34 w(cuddBddArrayStoreCnf)-189 986 y(\(to)25 +b(store)f(an)h(array)h(of)f(BDDs)g(as)f(a)i(CNF)f(formula\).)-189 +1252 y Fi(3.2.2)99 b(Loadinf)26 b(CNF)e(F)n(ormulas)g(as)h(BDDs)-189 +1439 y Fl(As)g(f)o(ar)g(as)g(the)g(loading)e(process)i(is)f(concerned)i +(three)f(possible)e(formats)i(are)g(a)n(v)n(ailable:)-44 +1643 y Fk(\017)49 b Fl(DDDMP)p 421 1643 V 36 w(CNF)p +650 1643 V 36 w(MODE)p 980 1643 V 35 w(NO)p 1159 1643 +V 36 w(CONJ:)25 b(Return)g(the)f(Clauses)h(without)f(Conjunction)-44 +1846 y Fk(\017)49 b Fl(DDDMP)p 421 1846 V 36 w(CNF)p +650 1846 V 36 w(MODE)p 980 1846 V 35 w(NO)p 1159 1846 +V 36 w(Q)o(U)l(ANT)-5 b(:)24 b(Return)h(the)g(sets)f(of)h(BDDs)g +(without)f(Quanti\002cation)-44 2050 y Fk(\017)49 b Fl(DDDMP)p +421 2050 V 36 w(CNF)p 650 2050 V 36 w(MODE)p 980 2050 +V 35 w(CONJ)p 1264 2050 V 36 w(Q)o(U)l(ANT)-5 b(:)23 +b(Return)h(the)g(sets)f(of)h(BDDs)g(AFTER)g(Existential)e(Quanti\002-) +55 2170 y(cation)-189 2373 y(See)e(procedures)f(Dddmp)p +736 2373 V 35 w(cuddBddLoadCnf)f(\(to)h(load)f(a)i(CNF)f(formula)g(as)g +(a)g(single)f(BDD\))h(and)g(Dddmp)p 3581 2373 V 35 w +(cuddBddArrayLoadCnf)-189 2494 y(\(to)35 b(load)h(a)g(CNF)g(formula)f +(as)h(an)g(array)g(of)g(BDDs\).)63 b(See)36 b(also)g(Dddmp)p +2485 2494 V 34 w(cuddHeaderLoadCnf)h(to)e(load)g(the)-189 +2614 y(header)25 b(of)g(a)g(CNF)h(\002le)f(to)g(gather)f(information)f +(on)i(the)g(sa)n(v)o(ed)f(structure.)-189 2954 y Fo(4)143 +b(T)-13 b(est)35 b(Pr)m(ogram)f(and)h(Regr)m(ession)f(T)-13 +b(ests)-189 3177 y Fl(The)20 b Fc(testddmp.c)e Fl(\002le,)j(pro)o +(vided)d(with)h(this)f(distrib)n(ution,)g(e)o(x)o(empli\002es)g(some)h +(of)h(the)f(abo)o(v)o(e)g(features.)29 b(Moreo)o(v)o(er)l(,)-189 +3298 y(in)d(the)h Fc(e)n(xp)g Fl(e)o(xperiments)e(a)j(fe)n(w)e +(scripts,)h(named)f Fc(test\241n\277.script)f Fl(are)i(a)n(v)n(ailable) +f(for)h(a)g(sanity)f(check)h(of)g(the)g(tool)-189 3418 +y(and)e(to)f(tak)o(e)h(a)g(look)f(at)h(some)f(runs)h(e)o(x)o +(empli\002cation.)-189 3758 y Fo(5)143 b(Documentation)-189 +3981 y Fl(F)o(or)27 b(further)f(documentation)f(on)i(the)f(package)h +(see)g(the)g(on-line)f(documentation)f(automatically)g(created)i(from) +-189 4102 y(the)e(source)g(code)g(\002les.)-189 4441 +y Fo(6)143 b(Ackno)o(wledgments)-189 4665 y Fl(W)-8 b(e)19 +b(are)h(particular)f(indebted)f(with)g(F)o(abio)g(Somenzi,)i(for)f +(discussions,)f(advice,)i(and)f(for)g(including)e(the)i(DDDMP)-189 +4785 y(package)28 b(into)f(the)h(CUDD)g(distrib)n(ution.)37 +b(W)-8 b(e)29 b(also)e(thank)g(all)h(the)g(user)g(of)g(the)f(package)i +(for)f(their)f(useful)h(indi-)-189 4905 y(cation)c(and)h(comments)f(on) +g(the)h(it.)1794 5800 y(9)p eop +%%Page: 10 10 +10 9 bop -189 218 a Fo(7)143 b(FTP)35 b(Site)-189 441 +y Fl(The)25 b(package)g(is)f(singularly)g(a)n(v)n(ailable)g(from:)-189 +645 y Fg(site:)59 b(ftp.polito.it)-189 765 y(user:)g(anonymous)-189 +885 y(directory:)f(/pub/research/dddmp)-189 1089 y Fl(or)25 +b(directly)f(from)h(the)f(author)h(WEB)g(pages:)-189 +1292 y Fg(WWW:)59 b(http://www.polito.it/\230{cabodi)o(,quer)o(})-189 +1632 y Fo(8)143 b(F)l(eedback)-189 1855 y Fl(Send)25 +b(feedback)h(to:)-189 2059 y Fg(Gianpiero)58 b(Cabodi)g(&)i(Stefano)e +(Quer)-189 2179 y(Politecnico)f(di)j(Torino)-189 2300 +y(Dipartimento)d(di)i(Automatica)f(e)i(Informatica)-189 +2420 y(Corso)f(Duca)g(degli)f(Abruzzi,)g(24)-189 2540 +y(I-10129)g(Torino)-189 2661 y(Italy)-189 2781 y(E-mail:)g +({cabodi,quer}@polito.it)-189 2901 y(WWW:)h +(http://www.polito.it/\230{cabodi)o(,quer)o(})1769 5800 +y Fl(10)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllAbs.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllAbs.html new file mode 100644 index 000000000..5cd6c2a3e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllAbs.html @@ -0,0 +1,483 @@ + +dddmp package abstract + + + + + +
                  +
                  DddmpBddReadHeaderCnf() +
                  Reads a the header of a dump file representing the argument + BDDs. + +
                  DddmpBddReadHeader() +
                  Reads a the header of a dump file representing the + argument BDDs. + +
                  DddmpClearVisitedAdd() +
                  Marks a node as not visited + +
                  DddmpClearVisitedBdd() +
                  Marks a node as not visited + +
                  DddmpClearVisitedCnfRecur() +
                  Mark ALL nodes as not visited + +
                  DddmpClearVisitedCnfRecur() +
                  Mark ALL nodes as not visited + +
                  DddmpClearVisitedCnf() +
                  Marks a node as not visited + +
                  DddmpClearVisitedCnf() +
                  Marks a node as not visited + +
                  DddmpClearVisited() +
                  Marks a node as not visited + +
                  DddmpCnfClauses2Bdd() +
                  Transforms CNF clauses into BDDs. + +
                  DddmpCuddBddArrayStoreCnf() +
                  Writes a dump file representing the argument Array of + BDDs in the CNF standard format. + +
                  DddmpCuddBddArrayStore() +
                  Writes a dump file representing the argument Array of + BDDs. + +
                  DddmpCuddDdArrayLoadCnf() +
                  Reads a dump file representing the argument BDDs in CNF + format. + +
                  DddmpCuddDdArrayLoad() +
                  Reads a dump file representing the argument BDDs. + +
                  DddmpCuddDdArrayStoreBdd() +
                  Writes a dump file representing the argument Array of + BDDs/ADDs. + +
                  DddmpCuddDdArrayStoreBlifBody() +
                  Writes a blif body representing the argument BDDs. + +
                  DddmpCuddDdArrayStoreBlifStep() +
                  Performs the recursive step of DddmpCuddDdArrayStoreBlif. + +
                  DddmpCuddDdArrayStoreBlif() +
                  Writes a blif file representing the argument BDDs. + +
                  DddmpCuddDdArrayStorePrefixBody() +
                  Internal function to writes a dump file representing the + argument BDD in a prefix notation. Writes the body of the file. + +
                  DddmpCuddDdArrayStorePrefixStep() +
                  Performs the recursive step of + DddmpCuddDdArrayStorePrefixBody. + +
                  DddmpCuddDdArrayStorePrefix() +
                  Internal function to writes a dump file representing the + argument BDD in a prefix notation. + +
                  DddmpCuddDdArrayStoreSmvBody() +
                  Internal function to writes a dump file representing the + argument BDD in a SMV notation. Writes the body of the file. + +
                  DddmpCuddDdArrayStoreSmvStep() +
                  Performs the recursive step of + DddmpCuddDdArrayStoreSmvBody. + +
                  DddmpCuddDdArrayStoreSmv() +
                  Internal function to writes a dump file representing the + argument BDD in a SMV notation. + +
                  DddmpDdNodesCheckIncomingAndScanPath() +
                  Number nodes recursively in post-order + +
                  DddmpDdNodesCheckIncomingAndScanPath() +
                  Number nodes recursively in post-order + +
                  DddmpDdNodesCountEdgesAndNumber() +
                  Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. + +
                  DddmpDdNodesCountEdgesAndNumber() +
                  Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. + +
                  DddmpDdNodesCountEdgesRecur() +
                  Counts the number of incoming edges for each node of a BDD + +
                  DddmpDdNodesCountEdgesRecur() +
                  Counts the number of incoming edges for each node of a BDD + +
                  DddmpDdNodesNumberEdgesRecur() +
                  Number nodes recursively in post-order + +
                  DddmpDdNodesNumberEdgesRecur() +
                  Number nodes recursively in post-order + +
                  DddmpDdNodesResetCountRecur() +
                  Resets counter and visited flag for ALL nodes of a BDD + +
                  DddmpDdNodesResetCountRecur() +
                  Resets counter and visited flag for ALL nodes of a BDD + +
                  DddmpFreeHeaderCnf() +
                  Frees the internal header structure. + +
                  DddmpFreeHeader() +
                  Frees the internal header structure. + +
                  DddmpIntArrayDup() +
                  Duplicates an array of ints + +
                  DddmpIntArrayRead() +
                  Inputs an array of ints + +
                  DddmpIntArrayWrite() +
                  Outputs an array of ints + +
                  DddmpNumberAddNodes() +
                  Removes nodes from unique table and number them + +
                  DddmpNumberBddNodes() +
                  Removes nodes from unique table and number them + +
                  DddmpNumberDdNodesCnf() +
                  Removes nodes from unique table and numbers them + +
                  DddmpNumberDdNodesCnf() +
                  Removes nodes from unique table and numbers them + +
                  DddmpNumberDdNodes() +
                  Removes nodes from unique table and number them + +
                  DddmpPrintBddAndNextRecur() +
                  Prints debug info + +
                  DddmpPrintBddAndNextRecur() +
                  Prints debug info + +
                  DddmpPrintBddAndNext() +
                  Prints debug information + +
                  DddmpPrintBddAndNext() +
                  Prints debug information + +
                  DddmpReadCnfClauses() +
                  Read the CNF clauses from the file in the standard DIMACS + format. + +
                  DddmpReadCode() +
                  Reads a 1 byte node code + +
                  DddmpReadInt() +
                  Reads a "packed integer" + +
                  DddmpReadNodeIndexAdd() +
                  Reads the index of a node + +
                  DddmpReadNodeIndexBdd() +
                  Reads the index of a node + +
                  DddmpReadNodeIndexCnf() +
                  Reads the index of a node + +
                  DddmpReadNodeIndexCnf() +
                  Reads the index of a node + +
                  DddmpReadNodeIndex() +
                  Reads the index of a node + +
                  DddmpSetVisitedAdd() +
                  Marks a node as visited + +
                  DddmpSetVisitedBdd() +
                  Marks a node as visited + +
                  DddmpSetVisitedCnf() +
                  Marks a node as visited + +
                  DddmpSetVisitedCnf() +
                  Marks a node as visited + +
                  DddmpSetVisited() +
                  Marks a node as visited + +
                  DddmpStrArrayDup() +
                  Duplicates an array of strings + +
                  DddmpStrArrayFree() +
                  Frees an array of strings + +
                  DddmpStrArrayRead() +
                  Inputs an array of strings + +
                  DddmpStrArrayWrite() +
                  Outputs an array of strings + +
                  DddmpStrDup() +
                  Duplicates a string + +
                  DddmpUnnumberAddNodes() +
                  Restores nodes in unique table, loosing numbering + +
                  DddmpUnnumberBddNodes() +
                  Restores nodes in unique table, loosing numbering + +
                  DddmpUnnumberDdNodesCnf() +
                  Restores nodes in unique table, loosing numbering + +
                  DddmpUnnumberDdNodesCnf() +
                  Restores nodes in unique table, loosing numbering + +
                  DddmpUnnumberDdNodes() +
                  Restores nodes in unique table, loosing numbering + +
                  DddmpVisitedAdd() +
                  Returns true if node is visited + +
                  DddmpVisitedBdd() +
                  Returns true if node is visited + +
                  DddmpVisitedCnf() +
                  Returns true if node is visited + +
                  DddmpVisitedCnf() +
                  Returns true if node is visited + +
                  DddmpVisited() +
                  Returns true if node is visited + +
                  DddmpWriteCode() +
                  Writes 1 byte node code + +
                  DddmpWriteInt() +
                  Writes a "packed integer" + +
                  DddmpWriteNodeIndexAdd() +
                  Write index to node + +
                  DddmpWriteNodeIndexBdd() +
                  Write index to node + +
                  DddmpWriteNodeIndexCnfBis() +
                  Write index to node + +
                  DddmpWriteNodeIndexCnfWithTerminalCheck() +
                  Write index to node + +
                  DddmpWriteNodeIndexCnf() +
                  Write index to node + +
                  DddmpWriteNodeIndexCnf() +
                  Write index to node + +
                  DddmpWriteNodeIndex() +
                  Write index to node + +
                  Dddmp_Bin2Text() +
                  Converts from binary to ASCII format + +
                  Dddmp_Text2Bin() +
                  Converts from ASCII to binary format + +
                  Dddmp_cuddAddArrayLoad() +
                  Reads a dump file representing the argument ADDs. + +
                  Dddmp_cuddAddArrayStore() +
                  Writes a dump file representing the argument Array of ADDs. + +
                  Dddmp_cuddAddLoad() +
                  Reads a dump file representing the argument ADD. + +
                  Dddmp_cuddAddStore() +
                  Writes a dump file representing the argument ADD. + +
                  Dddmp_cuddBddArrayLoadCnf() +
                  Reads a dump file in a CNF format. + +
                  Dddmp_cuddBddArrayLoad() +
                  Reads a dump file representing the argument BDDs. + +
                  Dddmp_cuddBddArrayStoreBlif() +
                  Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
                  Dddmp_cuddBddArrayStoreCnf() +
                  Writes a dump file representing the argument array of BDDs + in CNF format. + +
                  Dddmp_cuddBddArrayStorePrefix() +
                  Writes a dump file representing the argument BDD in + a prefix notation. + +
                  Dddmp_cuddBddArrayStoreSmv() +
                  Writes a dump file representing the argument BDD in + a prefix notation. + +
                  Dddmp_cuddBddArrayStore() +
                  Writes a dump file representing the argument Array of BDDs. + +
                  Dddmp_cuddBddDisplayBinary() +
                  Display a binary dump file in a text file + +
                  Dddmp_cuddBddLoadCnf() +
                  Reads a dump file in a CNF format. + +
                  Dddmp_cuddBddLoad() +
                  Reads a dump file representing the argument BDD. + +
                  Dddmp_cuddBddStoreBlif() +
                  Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
                  Dddmp_cuddBddStoreCnf() +
                  Writes a dump file representing the argument BDD in + a CNF format. + +
                  Dddmp_cuddBddStorePrefix() +
                  Writes a dump file representing the argument BDD in + a prefix notation. + +
                  Dddmp_cuddBddStoreSmv() +
                  Writes a dump file representing the argument BDD in + a prefix notation. + +
                  Dddmp_cuddBddStore() +
                  Writes a dump file representing the argument BDD. + +
                  Dddmp_cuddHeaderLoadCnf() +
                  Reads the header of a dump file representing the argument BDDs + +
                  Dddmp_cuddHeaderLoad() +
                  Reads the header of a dump file representing the argument BDDs + +
                  FindVarname() +
                  Performs binary search of a name within a sorted array + +
                  NodeBinaryStoreBdd() +
                  Store One Single Node in Binary Format. + +
                  NodeStoreRecurAdd() +
                  Performs the recursive step of Dddmp_bddStore. + +
                  NodeStoreRecurBdd() +
                  Performs the recursive step of Dddmp_bddStore. + +
                  NodeTextStoreAdd() +
                  Store One Single Node in Text Format. + +
                  NodeTextStoreBdd() +
                  Store One Single Node in Text Format. + +
                  NumberNodeRecurAdd() +
                  Number nodes recursively in post-order + +
                  NumberNodeRecurBdd() +
                  Number nodes recursively in post-order + +
                  NumberNodeRecurCnf() +
                  Number nodes recursively in post-order + +
                  NumberNodeRecurCnf() +
                  Number nodes recursively in post-order + +
                  NumberNodeRecur() +
                  Number nodes recursively in post-order + +
                  QsortStrcmp() +
                  String compare for qsort + +
                  ReadByteBinary() +
                  Reads a byte from file with escaped , and + +
                  RemoveFromUniqueRecurAdd() +
                  Removes a node from unique table + +
                  RemoveFromUniqueRecurBdd() +
                  Removes a node from unique table + +
                  RemoveFromUniqueRecurCnf() +
                  Removes a node from unique table + +
                  RemoveFromUniqueRecurCnf() +
                  Removes a node from unique table + +
                  RemoveFromUniqueRecur() +
                  Removes a node from unique table + +
                  RestoreInUniqueRecurAdd() +
                  Restores a node in unique table + +
                  RestoreInUniqueRecurBdd() +
                  Restores a node in unique table + +
                  RestoreInUniqueRecurCnf() +
                  Restores a node in unique table + +
                  RestoreInUniqueRecurCnf() +
                  Restores a node in unique table + +
                  RestoreInUniqueRecur() +
                  Restores a node in unique table + +
                  StoreCnfBestNotSharedRecur() +
                  Performs the recursive step of Print Best on Not Shared + sub-BDDs. + +
                  StoreCnfBestSharedRecur() +
                  Performs the recursive step of Print Best on Shared + sub-BDDs. + +
                  StoreCnfBest() +
                  Prints a disjoint sum of products with intermediate + cutting points. + +
                  StoreCnfMaxtermByMaxtermRecur() +
                  Performs the recursive step of Print Maxterm. + +
                  StoreCnfMaxtermByMaxterm() +
                  Prints a disjoint sum of products. + +
                  StoreCnfNodeByNodeRecur() +
                  Performs the recursive step of Dddmp_bddStore. + +
                  StoreCnfNodeByNode() +
                  Store the BDD as CNF clauses. + +
                  StoreCnfOneNode() +
                  Store One Single BDD Node. + +
                  WriteByteBinary() +
                  Writes a byte to file filtering , and + +
                  printCubeCnf() +
                  Print One Cube in CNF Format. + +
                  () +
                  Checks for Warnings: If expr==1 it prints out the warning + on stderr. + +
                  () +
                  Checks for fatal bugs + +
                  () +
                  Checks for fatal bugs and go to the label to deal with + the error. + +
                  () +
                  Checks for fatal bugs and return the DDDMP_FAILURE flag. + +
                  () +
                  Memory Allocation Macro for DDDMP + +
                  () +
                  Memory Free Macro for DDDMP + +
                  + +
                  + +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFile.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFile.html new file mode 100644 index 000000000..f414ee60d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFile.html @@ -0,0 +1,13 @@ + +The dddmp package for maintainers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFunc.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFunc.html new file mode 100644 index 000000000..76671dac0 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllByFunc.html @@ -0,0 +1,13 @@ + +The dddmp package for maintainers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllDet.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllDet.html new file mode 100644 index 000000000..9d8e7ba33 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllDet.html @@ -0,0 +1,3704 @@ + +The dddmp package: all functions + + +A set of internal low-level routines of the dddmp package + doing: +
                    +
                  • read and write of node codes in binary mode, +
                  • read and write of integers in binary mode, +
                  • marking/unmarking nodes as visited, +
                  • numbering nodes. +
                  +
                  +
                  +
                  +
                  +static Dddmp_Hdr_t * 
                  +DddmpBddReadHeaderCnf(
                  +  char * file, IN: file name
                  +  FILE * fp IN: file pointer
                  +)
                  +
                  +
                  Reads the header of a dump file. Builds a Dddmp_Hdr_t struct + containing all infos in the header, for next manipulations. +

                  + +

                  Side Effects none +

                  + +

                  Defined in dddmpLoadCnf.c + +
                  +
                  +static Dddmp_Hdr_t * 
                  +DddmpBddReadHeader(
                  +  char * file, IN: file name
                  +  FILE * fp IN: file pointer
                  +)
                  +
                  +
                  Reads the header of a dump file. Builds a Dddmp_Hdr_t struct + containing all infos in the header, for next manipulations. +

                  + +

                  Side Effects none +

                  + +

                  Defined in dddmpLoad.c + +
                  +
                  +void 
                  +DddmpClearVisitedAdd(
                  +  DdNode * f IN: BDD node to be marked (as not visited)
                  +)
                  +
                  +
                  Marks a node as not visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpVisitedAdd +() +DddmpSetVisitedAdd +() + + +
                  Defined in dddmpNodeAdd.c + +
                  +
                  +void 
                  +DddmpClearVisitedBdd(
                  +  DdNode * f IN: BDD node to be marked (as not visited)
                  +)
                  +
                  +
                  Marks a node as not visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpVisited +() +DddmpSetVisited +() + + +
                  Defined in dddmpNodeBdd.c + +
                  +
                  +static int 
                  +DddmpClearVisitedCnfRecur(
                  +  DdNode * f IN: root of the BDD to be marked
                  +)
                  +
                  +
                  Mark ALL nodes as not visited (it recurs on the node children) +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpVisitedCnf +() +DddmpSetVisitedCnf +() + + +
                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +static int 
                  +DddmpClearVisitedCnfRecur(
                  +  DdNode * f IN: root of the BDD to be marked
                  +)
                  +
                  +
                  Mark ALL nodes as not visited (it recurs on the node children) +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpVisitedCnf +() +DddmpSetVisitedCnf +() + + +
                  Defined in dddmpNodeCnf.c + +
                  +
                  +static void 
                  +DddmpClearVisitedCnf(
                  +  DdNode * f IN: BDD node to be marked (as not visited)
                  +)
                  +
                  +
                  Marks a node as not visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpVisitedCnf +() +DddmpSetVisitedCnf +() + + +
                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +static void 
                  +DddmpClearVisitedCnf(
                  +  DdNode * f IN: BDD node to be marked (as not visited)
                  +)
                  +
                  +
                  Marks a node as not visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpVisitedCnf +() +DddmpSetVisitedCnf +() + + +
                  Defined in dddmpNodeCnf.c + +
                  +
                  +void 
                  +DddmpClearVisited(
                  +  DdNode * f IN: BDD node to be marked (as not visited)
                  +)
                  +
                  +
                  Marks a node as not visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpVisited +() +DddmpSetVisited +() + + +
                  Defined in dddmpDdNodeBdd.c + +
                  +
                  +static int 
                  +DddmpCnfClauses2Bdd(
                  +  Dddmp_Hdr_t * Hdr, IN: file header
                  +  DdManager * ddMgr, IN: DD Manager
                  +  int ** cnfTable, IN: CNF table for clauses
                  +  int  mode, IN: computation mode
                  +  DdNode *** rootsPtrPtr OUT: array of returned BDD roots (by reference)
                  +)
                  +
                  +
                  Transforms CNF clauses into BDDs. Clauses are stored in an + internal structure previously read. The results can be given in + different format according to the mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification +

                  + +

                  Defined in dddmpLoadCnf.c + +
                  +
                  +static int 
                  +DddmpCuddBddArrayStoreCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDD roots to be stored
                  +  int  rootN, IN: # of output BDD roots to be stored
                  +  Dddmp_DecompCnfStoreType  mode, IN: format selection
                  +  int  noHeader, IN: do not store header iff 1
                  +  char ** varNames, IN: array of variable names (or NULL)
                  +  int * bddIds, IN: array of BDD node Ids (or NULL)
                  +  int * bddAuxIds, IN: array of BDD Aux Ids (or NULL)
                  +  int * cnfIds, IN: array of CNF ids (or NULL)
                  +  int  idInitial, IN: starting id for cutting variables
                  +  int  edgeInTh, IN: Max # Incoming Edges
                  +  int  pathLengthTh, IN: Max Path Length
                  +  char * fname, IN: file name
                  +  FILE * fp, IN: pointer to the store file
                  +  int * clauseNPtr, OUT: number of clause stored
                  +  int * varNewNPtr OUT: number of new variable created
                  +)
                  +
                  +
                  Dumps the argument array of BDDs/ADDs to file in CNF format. + The following arrays: varNames, bddIds, bddAuxIds, and cnfIds + fix the correspondence among variable names, BDD ids, BDD + auxiliary ids and the ids used to store the CNF problem. + All these arrays are automatically created iff NULL. + Auxiliary variable, iff necessary, are created starting from value + idInitial. + Iff idInitial is <= 0 its value is selected as the number of internal + CUDD variable + 2. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. +

                  + +

                  Side Effects Nodes are temporarily removed from the unique hash table. + They are re-linked after the store operation in a modified + order. +

                  + +

                  See Also Dddmp_cuddBddStore + + +
                  Defined in dddmpStoreCnf.c + +
                  +
                  +int 
                  +DddmpCuddBddArrayStore(
                  +  Dddmp_DecompType  ddType, IN: Selects the decomp type BDD
                  +  DdManager * ddMgr, IN: DD Manager
                  +  char * ddname, IN: DD name (or NULL)
                  +  int  nRoots, IN: number of output BDD roots to be stored
                  +  DdNode ** f, IN: array of DD roots to be stored
                  +  char ** rootnames, IN: array of root names (or NULL)
                  +  char ** varnames, IN: array of variable names (or NULL)
                  +  int * auxids, IN: array of converted var IDs
                  +  int  mode, IN: storing mode selector
                  +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument array of BDDs to file. + Internal function doing inner steps of store for BDDs. +

                  + +

                  Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

                  + +

                  See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                  Defined in dddmpStoreBdd.c + +
                  +
                  +static int 
                  +DddmpCuddDdArrayLoadCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  Dddmp_RootMatchType  rootmatchmode, IN: storing mode selector
                  +  char ** rootmatchnames, IN: sorted names for loaded roots
                  +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names, by ids
                  +  int * varmatchauxids, IN: array of variable auxids, by ids
                  +  int * varcomposeids, IN: array of new ids, by ids
                  +  int  mode, IN: computation mode
                  +  char * file, IN: file name
                  +  FILE * fp, IN: file pointer
                  +  DdNode *** rootsPtrPtr, OUT: array of BDD roots
                  +  int * nRoots OUT: number of BDDs returned
                  +)
                  +
                  +
                  Reads a dump file representing the argument BDDs in CNF + format. + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddBddArrayLoad + + +
                  Defined in dddmpLoadCnf.c + +
                  +
                  +static int 
                  +DddmpCuddDdArrayLoad(
                  +  Dddmp_DecompType  ddType, IN: Selects decomp type
                  +  DdManager * ddMgr, IN: DD Manager
                  +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
                  +  char ** rootmatchnames, IN: sorted names for loaded roots
                  +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names, by ids
                  +  int * varmatchauxids, IN: array of variable auxids, by ids
                  +  int * varcomposeids, IN: array of new ids, by ids
                  +  int  mode, IN: requested input file format
                  +  char * file, IN: file name
                  +  FILE * fp, IN: file pointer
                  +  DdNode *** pproots OUT: array BDD roots (by reference)
                  +)
                  +
                  +
                  Reads a dump file representing the argument BDDs. The header is + common to both text and binary mode. The node list is either + in text or binary format. A dynamic vector of DD pointers + is allocated to support conversion from DD indexes to pointers. + Several criteria are supported for variable match between file + and dd manager. Several changes/permutations/compositions are allowed + for variables while loading DDs. Variable of the dd manager are allowed + to match with variables on file on ids, permids, varnames, + varauxids; also direct composition between ids and + composeids is supported. More in detail: +
                    +
                  1. varMatchMode=DDDMP_VAR_MATCHIDS

                    + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

                  2. varMatchMode=DDDMP_VAR_MATCHPERMIDS

                    + is used to allow variable match according to the position in the ordering. + +

                  3. varMatchMode=DDDMP_VAR_MATCHNAMES

                    + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

                  4. varMatchMode=DDDMP_VAR_MATCHIDS

                    + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

                  5. varMatchMode=DDDMP_VAR_COMPOSEIDS

                    + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. +

                  + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddBddArrayStore + + +
                  Defined in dddmpLoad.c + +
                  +
                  +int 
                  +DddmpCuddDdArrayStoreBdd(
                  +  Dddmp_DecompType  ddType, IN: Selects the decomp type: BDD or ADD
                  +  DdManager * ddMgr, IN: DD Manager
                  +  char * ddname, IN: DD name (or NULL)
                  +  int  nRoots, IN: number of output BDD roots to be stored
                  +  DdNode ** f, IN: array of DD roots to be stored
                  +  char ** rootnames, IN: array of root names (or NULL)
                  +  char ** varnames, IN: array of variable names (or NULL)
                  +  int * auxids, IN: array of converted var IDs
                  +  int  mode, IN: storing mode selector
                  +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument array of BDDs/ADDs to file. Internal + function doing inner steps of store for BDDs and ADDs. + ADD store is presently supported only with the text format. +

                  + +

                  Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

                  + +

                  See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                  Defined in dddmpStoreAdd.c + +
                  +
                  +static int 
                  +DddmpCuddDdArrayStoreBlifBody(
                  +  DdManager * ddMgr, IN: Manager
                  +  int  n, IN: Number of output nodes to be dumped
                  +  DdNode ** f, IN: Array of output nodes to be dumped
                  +  char ** inputNames, IN: Array of input names (or NULL)
                  +  char ** outputNames, IN: Array of output names (or NULL)
                  +  FILE * fp IN: Pointer to the dump file
                  +)
                  +
                  +
                  Writes a blif body representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). + DddmpCuddDdArrayStoreBlif does not close the file: This is the + caller responsibility. + DddmpCuddDdArrayStoreBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inputNames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for outputNames. This function prints out only + .names part. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpStoreMisc.c + +
                  +
                  +static int 
                  +DddmpCuddDdArrayStoreBlifStep(
                  +  DdManager * ddMgr, 
                  +  DdNode * f, 
                  +  FILE * fp, 
                  +  st_table * visited, 
                  +  char ** names 
                  +)
                  +
                  +
                  Performs the recursive step of DddmpCuddDdArrayStoreBlif. + Traverses the BDD f and writes a multiplexer-network description to + the file pointed by fp in blif format. + f is assumed to be a regular pointer and DddmpCuddDdArrayStoreBlifStep + guarantees this assumption in the recursive calls. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpStoreMisc.c + +
                  +
                  +static int 
                  +DddmpCuddDdArrayStoreBlif(
                  +  DdManager * ddMgr, IN: Manager
                  +  int  n, IN: Number of output nodes to be dumped
                  +  DdNode ** f, IN: Array of output nodes to be dumped
                  +  char ** inputNames, IN: Array of input names (or NULL)
                  +  char ** outputNames, IN: Array of output names (or NULL)
                  +  char * modelName, IN: Model name (or NULL)
                  +  FILE * fp IN: Pointer to the dump file
                  +)
                  +
                  +
                  Writes a blif file representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). + DddmpCuddDdArrayStoreBlif does not close the file: This is the + caller responsibility. + DddmpCuddDdArrayStoreBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for outputNames. + It prefixes the string "NODE" to each nome to have "regular" names + for each elements. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpCuddDdArrayStoreBlifBody +Cudd_DumpBlif + + +
                  Defined in dddmpStoreMisc.c + +
                  +
                  +static int 
                  +DddmpCuddDdArrayStorePrefixBody(
                  +  DdManager * ddMgr, IN: Manager
                  +  int  n, IN: Number of output nodes to be dumped
                  +  DdNode ** f, IN: Array of output nodes to be dumped
                  +  char ** inputNames, IN: Array of input names (or NULL)
                  +  char ** outputNames, IN: Array of output names (or NULL)
                  +  FILE * fp IN: Pointer to the dump file
                  +)
                  +
                  +
                  One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpCuddDdArrayStoreBlif + + +
                  Defined in dddmpStoreMisc.c + +
                  +
                  +static int 
                  +DddmpCuddDdArrayStorePrefixStep(
                  +  DdManager * ddMgr, 
                  +  DdNode * f, 
                  +  FILE * fp, 
                  +  st_table * visited, 
                  +  char ** names 
                  +)
                  +
                  +
                  Performs the recursive step of + DddmpCuddDdArrayStorePrefixBody. + Traverses the BDD f and writes a multiplexer-network description to the + file pointed by fp. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + f is assumed to be a regular pointer and the function guarantees this + assumption in the recursive calls. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpStoreMisc.c + +
                  +
                  +static int 
                  +DddmpCuddDdArrayStorePrefix(
                  +  DdManager * ddMgr, IN: Manager
                  +  int  n, IN: Number of output nodes to be dumped
                  +  DdNode ** f, IN: Array of output nodes to be dumped
                  +  char ** inputNames, IN: Array of input names (or NULL)
                  +  char ** outputNames, IN: Array of output names (or NULL)
                  +  char * modelName, IN: Model name (or NULL)
                  +  FILE * fp IN: Pointer to the dump file
                  +)
                  +
                  +
                  One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + Comments (COMMENT) are added at the beginning of the description to + describe inputs and outputs of the design. + A buffer (BUF) is add on the output to cope with complemented functions. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpCuddDdArrayStoreBlif + + +
                  Defined in dddmpStoreMisc.c + +
                  +
                  +static int 
                  +DddmpCuddDdArrayStoreSmvBody(
                  +  DdManager * ddMgr, IN: Manager
                  +  int  n, IN: Number of output nodes to be dumped
                  +  DdNode ** f, IN: Array of output nodes to be dumped
                  +  char ** inputNames, IN: Array of input names (or NULL)
                  +  char ** outputNames, IN: Array of output names (or NULL)
                  +  FILE * fp IN: Pointer to the dump file
                  +)
                  +
                  +
                  One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpCuddDdArrayStoreBlif + + +
                  Defined in dddmpStoreMisc.c + +
                  +
                  +static int 
                  +DddmpCuddDdArrayStoreSmvStep(
                  +  DdManager * ddMgr, 
                  +  DdNode * f, 
                  +  FILE * fp, 
                  +  st_table * visited, 
                  +  char ** names 
                  +)
                  +
                  +
                  Performs the recursive step of + DddmpCuddDdArrayStoreSmvBody. + Traverses the BDD f and writes a multiplexer-network description to the + file pointed by fp. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + f is assumed to be a regular pointer and the function guarantees this + assumption in the recursive calls. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpStoreMisc.c + +
                  +
                  +static int 
                  +DddmpCuddDdArrayStoreSmv(
                  +  DdManager * ddMgr, IN: Manager
                  +  int  n, IN: Number of output nodes to be dumped
                  +  DdNode ** f, IN: Array of output nodes to be dumped
                  +  char ** inputNames, IN: Array of input names (or NULL)
                  +  char ** outputNames, IN: Array of output names (or NULL)
                  +  char * modelName, IN: Model name (or NULL)
                  +  FILE * fp IN: Pointer to the dump file
                  +)
                  +
                  +
                  One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + Comments (COMMENT) are added at the beginning of the description to + describe inputs and outputs of the design. + A buffer (BUF) is add on the output to cope with complemented functions. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpCuddDdArrayStoreBlif + + +
                  Defined in dddmpStoreMisc.c + +
                  +
                  +static void 
                  +DddmpDdNodesCheckIncomingAndScanPath(
                  +  DdNode * f, IN: BDD node to be numbered
                  +  int  pathLengthCurrent, IN: Current Path Length
                  +  int  edgeInTh, IN: Max # In-Edges, after a Insert Cut Point
                  +  int  pathLengthTh IN: Max Path Length (after, Insert a Cut Point)
                  +)
                  +
                  +
                  Number nodes recursively in post-order. + The "visited" flag is used with the right polarity. + The node is assigned to a new CNF variable only if it is a "shared" + node (i.e. the number of its incoming edges is greater than 1). +

                  + +

                  Side Effects "visited" flags are set. +

                  + +

                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +static void 
                  +DddmpDdNodesCheckIncomingAndScanPath(
                  +  DdNode * f, IN: BDD node to be numbered
                  +  int  pathLengthCurrent, IN: Current Path Length
                  +  int  edgeInTh, IN: Max # In-Edges, after a Insert Cut Point
                  +  int  pathLengthTh IN: Max Path Length (after, Insert a Cut Point)
                  +)
                  +
                  +
                  Number nodes recursively in post-order. + The "visited" flag is used with the right polarity. + The node is assigned to a new CNF variable only if it is a "shared" + node (i.e. the number of its incoming edges is greater than 1). +

                  + +

                  Side Effects "visited" flags are set. +

                  + +

                  Defined in dddmpNodeCnf.c + +
                  +
                  +int 
                  +DddmpDdNodesCountEdgesAndNumber(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: Array of BDDs
                  +  int  rootN, IN: Number of BDD roots in the array of BDDs
                  +  int  edgeInTh, IN: Max # In-Edges, after a Insert Cut Point
                  +  int  pathLengthTh, IN: Max Path Length (after, Insert a Cut Point)
                  +  int * cnfIds, OUT: CNF identifiers for variables
                  +  int  id OUT: Number of Temporary Variables Introduced
                  +)
                  +
                  +
                  Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. +

                  + +

                  Side Effects Nodes are temporarily removed from unique table +

                  + +

                  See Also RemoveFromUniqueRecurCnf() + + +
                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +int 
                  +DddmpDdNodesCountEdgesAndNumber(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: Array of BDDs
                  +  int  rootN, IN: Number of BDD roots in the array of BDDs
                  +  int  edgeInTh, IN: Max # In-Edges, after a Insert Cut Point
                  +  int  pathLengthTh, IN: Max Path Length (after, Insert a Cut Point)
                  +  int * cnfIds, OUT: CNF identifiers for variables
                  +  int  id OUT: Number of Temporary Variables Introduced
                  +)
                  +
                  +
                  Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. +

                  + +

                  Side Effects Nodes are temporarily removed from unique table +

                  + +

                  See Also RemoveFromUniqueRecurCnf() + + +
                  Defined in dddmpNodeCnf.c + +
                  +
                  +static int 
                  +DddmpDdNodesCountEdgesRecur(
                  +  DdNode * f IN: root of the BDD
                  +)
                  +
                  +
                  Counts (recursively) the number of incoming edges for each + node of a BDD. This number is stored in the index field. +

                  + +

                  Side Effects "visited" flags remain untouched. +

                  + +

                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +static int 
                  +DddmpDdNodesCountEdgesRecur(
                  +  DdNode * f IN: root of the BDD
                  +)
                  +
                  +
                  Counts (recursively) the number of incoming edges for each + node of a BDD. This number is stored in the index field. +

                  + +

                  Side Effects "visited" flags remain untouched. +

                  + +

                  Defined in dddmpNodeCnf.c + +
                  +
                  +static int 
                  +DddmpDdNodesNumberEdgesRecur(
                  +  DdNode * f, IN: BDD node to be numbered
                  +  int * cnfIds, IN: possible source for numbering
                  +  int  id IN/OUT: possible source for numbering
                  +)
                  +
                  +
                  Number nodes recursively in post-order. + The "visited" flag is used with the inverse polarity. + Numbering follows the subsequent strategy: + * if the index = 0 it remains so + * if the index >= 1 it gets enumerated. + This implies that the node is assigned to a new CNF variable only if + it is not a terminal node otherwise it is assigned the index of + the BDD variable. +

                  + +

                  Side Effects "visited" flags are reset. +

                  + +

                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +static int 
                  +DddmpDdNodesNumberEdgesRecur(
                  +  DdNode * f, IN: BDD node to be numbered
                  +  int * cnfIds, IN: possible source for numbering
                  +  int  id IN/OUT: possible source for numbering
                  +)
                  +
                  +
                  Number nodes recursively in post-order. + The "visited" flag is used with the inverse polarity. + Numbering follows the subsequent strategy: + * if the index = 0 it remains so + * if the index >= 1 it gets enumerated. + This implies that the node is assigned to a new CNF variable only if + it is not a terminal node otherwise it is assigned the index of + the BDD variable. +

                  + +

                  Side Effects "visited" flags are reset. +

                  + +

                  Defined in dddmpNodeCnf.c + +
                  +
                  +static int 
                  +DddmpDdNodesResetCountRecur(
                  +  DdNode * f IN: root of the BDD whose counters are reset
                  +)
                  +
                  +
                  Resets counter and visited flag for ALL nodes of a BDD (it + recurs on the node children). The index field of the node is + used as counter. +

                  + +

                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +static int 
                  +DddmpDdNodesResetCountRecur(
                  +  DdNode * f IN: root of the BDD whose counters are reset
                  +)
                  +
                  +
                  Resets counter and visited flag for ALL nodes of a BDD (it + recurs on the node children). The index field of the node is + used as counter. +

                  + +

                  Defined in dddmpNodeCnf.c + +
                  +
                  +static void 
                  +DddmpFreeHeaderCnf(
                  +  Dddmp_Hdr_t * Hdr IN: pointer to header
                  +)
                  +
                  +
                  Frees the internal header structure by freeing all internal + fields first. +

                  + +

                  Defined in dddmpLoadCnf.c + +
                  +
                  +static void 
                  +DddmpFreeHeader(
                  +  Dddmp_Hdr_t * Hdr IN: pointer to header
                  +)
                  +
                  +
                  Frees the internal header structureby freeing all internal + fields first. +

                  + +

                  Defined in dddmpLoad.c + +
                  +
                  +int * 
                  +DddmpIntArrayDup(
                  +  int * array, IN: array of ints to be duplicated
                  +  int  n IN: size of the array
                  +)
                  +
                  +
                  Allocates memory and copies source array +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpUtil.c + +
                  +
                  +int * 
                  +DddmpIntArrayRead(
                  +  FILE * fp, IN: input file
                  +  int  n IN: size of the array
                  +)
                  +
                  +
                  Allocates memory and inputs source array +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpUtil.c + +
                  +
                  +int 
                  +DddmpIntArrayWrite(
                  +  FILE * fp, IN: output file
                  +  int * array, IN: array of ints
                  +  int  n IN: size of the array
                  +)
                  +
                  +
                  Outputs an array of ints to a specified file +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpUtil.c + +
                  +
                  +int 
                  +DddmpNumberAddNodes(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDDs
                  +  int  n IN: number of BDD roots in the array of BDDs
                  +)
                  +
                  +
                  Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodes()). +

                  + +

                  Side Effects Nodes are temporarily removed from unique table +

                  + +

                  See Also RemoveFromUniqueRecurAdd +() +NumberNodeRecurAdd +() +DddmpUnnumberDdNodesAdd +() + + +
                  Defined in dddmpNodeAdd.c + +
                  +
                  +int 
                  +DddmpNumberBddNodes(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDDs
                  +  int  n IN: number of BDD roots in the array of BDDs
                  +)
                  +
                  +
                  Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberBddNodes ()). +

                  + +

                  Side Effects Nodes are temporarily removed from unique table +

                  + +

                  See Also RemoveFromUniqueRecur() +NumberNodeRecur() +DddmpUnnumberBddNodes +() + + +
                  Defined in dddmpNodeBdd.c + +
                  +
                  +int 
                  +DddmpNumberDdNodesCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDDs
                  +  int  rootN, IN: number of BDD roots in the array of BDDs
                  +  int * cnfIds, OUT: CNF identifiers for variables
                  +  int  id OUT: number of Temporary Variables Introduced
                  +)
                  +
                  +
                  Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodesCnf()). +

                  + +

                  Side Effects Nodes are temporarily removed from unique table +

                  + +

                  See Also RemoveFromUniqueRecurCnf() +NumberNodeRecurCnf() +DddmpUnnumberDdNodesCnf() + + +
                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +int 
                  +DddmpNumberDdNodesCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDDs
                  +  int  rootN, IN: number of BDD roots in the array of BDDs
                  +  int * cnfIds, OUT: CNF identifiers for variables
                  +  int  id OUT: number of Temporary Variables Introduced
                  +)
                  +
                  +
                  Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodesCnf()). +

                  + +

                  Side Effects Nodes are temporarily removed from unique table +

                  + +

                  See Also RemoveFromUniqueRecurCnf() +NumberNodeRecurCnf() +DddmpUnnumberDdNodesCnf() + + +
                  Defined in dddmpNodeCnf.c + +
                  +
                  +int 
                  +DddmpNumberDdNodes(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDDs
                  +  int  n IN: number of BDD roots in the array of BDDs
                  +)
                  +
                  +
                  Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodes()). +

                  + +

                  Side Effects Nodes are temporarily removed from unique table +

                  + +

                  See Also RemoveFromUniqueRecur() +NumberNodeRecur() +DddmpUnnumberDdNodes() + + +
                  Defined in dddmpDdNodeBdd.c + +
                  +
                  +static int 
                  +DddmpPrintBddAndNextRecur(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f IN: root of the BDD to be displayed
                  +)
                  +
                  +
                  Prints debug info for a BDD on the screen. It recurs on + node's children. +

                  + +

                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +static int 
                  +DddmpPrintBddAndNextRecur(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f IN: root of the BDD to be displayed
                  +)
                  +
                  +
                  Prints debug info for a BDD on the screen. It recurs on + node's children. +

                  + +

                  Defined in dddmpNodeCnf.c + +
                  +
                  +int 
                  +DddmpPrintBddAndNext(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: Array of BDDs to be displayed
                  +  int  rootN IN: Number of BDD roots in the array of BDDs
                  +)
                  +
                  +
                  Prints debug information for an array of BDDs on the screen +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +int 
                  +DddmpPrintBddAndNext(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: Array of BDDs to be displayed
                  +  int  rootN IN: Number of BDD roots in the array of BDDs
                  +)
                  +
                  +
                  Prints debug information for an array of BDDs on the screen +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpNodeCnf.c + +
                  +
                  +static int 
                  +DddmpReadCnfClauses(
                  +  Dddmp_Hdr_t * Hdr, IN: file header
                  +  int *** cnfTable, OUT: CNF table for clauses
                  +  FILE * fp IN: source file
                  +)
                  +
                  +
                  Read the CNF clauses from the file in the standard DIMACS + format. Store all the clauses in an internal structure for + future transformation into BDDs. +

                  + +

                  Defined in dddmpLoadCnf.c + +
                  +
                  +int 
                  +DddmpReadCode(
                  +  FILE * fp, IN: file where to read the code
                  +  struct binary_dd_code * pcode OUT: the read code
                  +)
                  +
                  +
                  Reads a 1 byte node code. See DddmpWriteCode() + for code description. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpWriteCode() + + +
                  Defined in dddmpBinary.c + +
                  +
                  +int 
                  +DddmpReadInt(
                  +  FILE * fp, IN: file where to read the integer
                  +  int * pid OUT: the read integer
                  +)
                  +
                  +
                  Reads an integer coded on a sequence of bytes. See + DddmpWriteInt() for format. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpWriteInt() + + +
                  Defined in dddmpBinary.c + +
                  +
                  +int 
                  +DddmpReadNodeIndexAdd(
                  +  DdNode * f IN: BDD node
                  +)
                  +
                  +
                  Reads the index of a node. LSB is skipped (used as visited + flag). +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpWriteNodeIndexAdd +() +DddmpSetVisitedAdd +() +DddmpVisitedAdd +() + + +
                  Defined in dddmpNodeAdd.c + +
                  +
                  +int 
                  +DddmpReadNodeIndexBdd(
                  +  DdNode * f IN: BDD node
                  +)
                  +
                  +
                  Reads the index of a node. LSB is skipped (used as visited + flag). +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpWriteNodeIndexBdd +() +DddmpSetVisitedBdd +() +DddmpVisitedBdd +() + + +
                  Defined in dddmpNodeBdd.c + +
                  +
                  +int 
                  +DddmpReadNodeIndexCnf(
                  +  DdNode * f IN: BDD node
                  +)
                  +
                  +
                  Reads the index of a node. LSB is skipped (used as visited + flag). +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpWriteNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
                  Defined in dddmpNodeCnf.c + +
                  +
                  +static int 
                  +DddmpReadNodeIndexCnf(
                  +  DdNode * f IN: BDD node
                  +)
                  +
                  +
                  Reads the index of a node. LSB is skipped (used as visited + flag). +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpWriteNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +int 
                  +DddmpReadNodeIndex(
                  +  DdNode * f IN: BDD node
                  +)
                  +
                  +
                  Reads the index of a node. LSB is skipped (used as visited + flag). +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpWriteNodeIndex() +DddmpSetVisited +() +DddmpVisited +() + + +
                  Defined in dddmpDdNodeBdd.c + +
                  +
                  +void 
                  +DddmpSetVisitedAdd(
                  +  DdNode * f IN: BDD node to be marked (as visited)
                  +)
                  +
                  +
                  Marks a node as visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpVisitedAdd +() +DddmpClearVisitedAdd +() + + +
                  Defined in dddmpNodeAdd.c + +
                  +
                  +void 
                  +DddmpSetVisitedBdd(
                  +  DdNode * f IN: BDD node to be marked (as visited)
                  +)
                  +
                  +
                  Marks a node as visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpVisitedBdd +() +DddmpClearVisitedBdd +() + + +
                  Defined in dddmpNodeBdd.c + +
                  +
                  +static void 
                  +DddmpSetVisitedCnf(
                  +  DdNode * f IN: BDD node to be marked (as visited)
                  +)
                  +
                  +
                  Marks a node as visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpVisitedCnf +() +DddmpClearVisitedCnf +() + + +
                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +void 
                  +DddmpSetVisitedCnf(
                  +  DdNode * f IN: BDD node to be marked (as visited)
                  +)
                  +
                  +
                  Marks a node as visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpVisitedCnf +() +DddmpClearVisitedCnf +() + + +
                  Defined in dddmpNodeCnf.c + +
                  +
                  +void 
                  +DddmpSetVisited(
                  +  DdNode * f IN: BDD node to be marked (as visited)
                  +)
                  +
                  +
                  Marks a node as visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpVisited +() +DddmpClearVisited +() + + +
                  Defined in dddmpDdNodeBdd.c + +
                  +
                  +char ** 
                  +DddmpStrArrayDup(
                  +  char ** array, IN: array of strings to be duplicated
                  +  int  n IN: size of the array
                  +)
                  +
                  +
                  Allocates memory and copies source array +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpUtil.c + +
                  +
                  +void 
                  +DddmpStrArrayFree(
                  +  char ** array, IN: array of strings
                  +  int  n IN: size of the array
                  +)
                  +
                  +
                  Frees memory for strings and the array of pointers +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpUtil.c + +
                  +
                  +char ** 
                  +DddmpStrArrayRead(
                  +  FILE * fp, IN: input file
                  +  int  n IN: size of the array
                  +)
                  +
                  +
                  Allocates memory and inputs source array +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpUtil.c + +
                  +
                  +int 
                  +DddmpStrArrayWrite(
                  +  FILE * fp, IN: output file
                  +  char ** array, IN: array of strings
                  +  int  n IN: size of the array
                  +)
                  +
                  +
                  Outputs an array of strings to a specified file +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpUtil.c + +
                  +
                  +char * 
                  +DddmpStrDup(
                  +  char * str IN: string to be duplicated
                  +)
                  +
                  +
                  Allocates memory and copies source string +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpUtil.c + +
                  +
                  +void 
                  +DddmpUnnumberAddNodes(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDDs
                  +  int  n IN: number of BDD roots in the array of BDDs
                  +)
                  +
                  +
                  Node indexes are no more needed. Nodes are re-linked in the + unique table. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpNumberDdNodeAdd +() + + +
                  Defined in dddmpNodeAdd.c + +
                  +
                  +void 
                  +DddmpUnnumberBddNodes(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDDs
                  +  int  n IN: number of BDD roots in the array of BDDs
                  +)
                  +
                  +
                  Node indexes are no more needed. Nodes are re-linked in the + unique table. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpNumberBddNode +() + + +
                  Defined in dddmpNodeBdd.c + +
                  +
                  +void 
                  +DddmpUnnumberDdNodesCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDDs
                  +  int  rootN IN: number of BDD roots in the array of BDDs
                  +)
                  +
                  +
                  Node indexes are no more needed. Nodes are re-linked in the + unique table. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpNumberDdNode() + + +
                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +void 
                  +DddmpUnnumberDdNodesCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDDs
                  +  int  rootN IN: number of BDD roots in the array of BDDs
                  +)
                  +
                  +
                  Node indexes are no more needed. Nodes are re-linked in the + unique table. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpNumberDdNode() + + +
                  Defined in dddmpNodeCnf.c + +
                  +
                  +void 
                  +DddmpUnnumberDdNodes(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDDs
                  +  int  n IN: number of BDD roots in the array of BDDs
                  +)
                  +
                  +
                  Node indexes are no more needed. Nodes are re-linked in the + unique table. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpNumberDdNode() + + +
                  Defined in dddmpDdNodeBdd.c + +
                  +
                  +int 
                  +DddmpVisitedAdd(
                  +  DdNode * f IN: BDD node to be tested
                  +)
                  +
                  +
                  Returns true if node is visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpSetVisitedAdd +() +DddmpClearVisitedAdd +() + + +
                  Defined in dddmpNodeAdd.c + +
                  +
                  +int 
                  +DddmpVisitedBdd(
                  +  DdNode * f IN: BDD node to be tested
                  +)
                  +
                  +
                  Returns true if node is visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpSetVisitedBdd +() +DddmpClearVisitedBdd +() + + +
                  Defined in dddmpNodeBdd.c + +
                  +
                  +int 
                  +DddmpVisitedCnf(
                  +  DdNode * f IN: BDD node to be tested
                  +)
                  +
                  +
                  Returns true if node is visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpSetVisitedCnf +() +DddmpClearVisitedCnf +() + + +
                  Defined in dddmpNodeCnf.c + +
                  +
                  +static int 
                  +DddmpVisitedCnf(
                  +  DdNode * f IN: BDD node to be tested
                  +)
                  +
                  +
                  Returns true if node is visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpSetVisitedCnf +() +DddmpClearVisitedCnf +() + + +
                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +int 
                  +DddmpVisited(
                  +  DdNode * f IN: BDD node to be tested
                  +)
                  +
                  +
                  Returns true if node is visited +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpSetVisited +() +DddmpClearVisited +() + + +
                  Defined in dddmpDdNodeBdd.c + +
                  +
                  +int 
                  +DddmpWriteCode(
                  +  FILE * fp, IN: file where to write the code
                  +  struct binary_dd_code  code IN: the code to be written
                  +)
                  +
                  +
                  outputs a 1 byte node code using the following format: +
                  +     Unused      : 1 bit;
                  +     V           : 2 bits;     (variable code)
                  +     T           : 2 bits;     (Then code)
                  +     Ecompl      : 1 bit;      (Else complemented)
                  +     E           : 2 bits;     (Else code)
                  +    
                  + Ecompl is set with complemented edges. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpReadCode() + + +
                  Defined in dddmpBinary.c + +
                  +
                  +int 
                  +DddmpWriteInt(
                  +  FILE * fp, IN: file where to write the integer
                  +  int  id IN: integer to be written
                  +)
                  +
                  +
                  Writes an integer as a sequence of bytes (MSByte first). + For each byte 7 bits are used for data and one (LSBit) as link + with a further byte (LSB = 1 means one more byte). +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpReadInt() + + +
                  Defined in dddmpBinary.c + +
                  +
                  +void 
                  +DddmpWriteNodeIndexAdd(
                  +  DdNode * f, IN: BDD node
                  +  int  id IN: index to be written
                  +)
                  +
                  +
                  The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpReadNodeIndexAdd +() +DddmpSetVisitedAdd +() +DddmpVisitedAdd +() + + +
                  Defined in dddmpNodeAdd.c + +
                  +
                  +void 
                  +DddmpWriteNodeIndexBdd(
                  +  DdNode * f, IN: BDD node
                  +  int  id IN: index to be written
                  +)
                  +
                  +
                  The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpReadNodeIndexBdd() +DddmpSetVisitedBdd +() +DddmpVisitedBdd +() + + +
                  Defined in dddmpNodeBdd.c + +
                  +
                  +int 
                  +DddmpWriteNodeIndexCnfBis(
                  +  DdNode * f, IN: BDD node
                  +  int  id IN: index to be written
                  +)
                  +
                  +
                  The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpReadNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +static int 
                  +DddmpWriteNodeIndexCnfWithTerminalCheck(
                  +  DdNode * f, IN: BDD node
                  +  int * cnfIds, IN: possible source for the index to be written
                  +  int  id IN: possible source for the index to be written
                  +)
                  +
                  +
                  The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. The index corresponds to + the BDD node variable if both the node's children are a + constant node, otherwise a new CNF variable is used. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpReadNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
                  Defined in dddmpNodeCnf.c + +
                  +
                  +int 
                  +DddmpWriteNodeIndexCnf(
                  +  DdNode * f, IN: BDD node
                  +  int  id IN: index to be written
                  +)
                  +
                  +
                  The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpReadNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
                  Defined in dddmpNodeCnf.c + +
                  +
                  +static int 
                  +DddmpWriteNodeIndexCnf(
                  +  DdNode * f, IN: BDD node
                  +  int * cnfIds, IN: possible source for the index to be written
                  +  int  id IN: possible source for the index to be written
                  +)
                  +
                  +
                  The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. The index corresponds to + the BDD node variable if both the node's children are a + constant node, otherwise a new CNF variable is used. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpReadNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +void 
                  +DddmpWriteNodeIndex(
                  +  DdNode * f, IN: BDD node
                  +  int  id IN: index to be written
                  +)
                  +
                  +
                  The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

                  + +

                  Side Effects None +

                  + +

                  See Also DddmpReadNodeIndex() +DddmpSetVisited +() +DddmpVisited +() + + +
                  Defined in dddmpDdNodeBdd.c + +
                  +
                  +int 
                  +Dddmp_Bin2Text(
                  +  char * filein, IN: name of binary file
                  +  char * fileout IN: name of ASCII file
                  +)
                  +
                  +
                  Converts from binary to ASCII format. A BDD array is loaded and + and stored to the target file. +

                  + +

                  Side Effects None +

                  + +

                  See Also Dddmp_Text2Bin() + + +
                  Defined in dddmpConvert.c + +
                  +
                  +int 
                  +Dddmp_Text2Bin(
                  +  char * filein, IN: name of ASCII file
                  +  char * fileout IN: name of binary file
                  +)
                  +
                  +
                  Converts from ASCII to binary format. A BDD array is loaded and + and stored to the target file. +

                  + +

                  Side Effects None +

                  + +

                  See Also Dddmp_Bin2Text() + + +
                  Defined in dddmpConvert.c + +
                  +
                  +int 
                  +Dddmp_cuddAddArrayLoad(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
                  +  char ** rootmatchnames, IN: sorted names for loaded roots
                  +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names, by ids
                  +  int * varmatchauxids, IN: array of variable auxids, by ids
                  +  int * varcomposeids, IN: array of new ids, by ids
                  +  int  mode, IN: requested input file format
                  +  char * file, IN: file name
                  +  FILE * fp, IN: file pointer
                  +  DdNode *** pproots OUT: array of returned BDD roots
                  +)
                  +
                  +
                  Reads a dump file representing the argument ADDs. See + BDD load functions for detailed explanation. +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddBddArrayStore + + +
                  Defined in dddmpLoad.c + +
                  +
                  +int 
                  +Dddmp_cuddAddArrayStore(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  char * ddname, IN: DD name (or NULL)
                  +  int  nRoots, IN: number of output BDD roots to be stored
                  +  DdNode ** f, IN: array of ADD roots to be stored
                  +  char ** rootnames, IN: array of root names (or NULL)
                  +  char ** varnames, IN: array of variable names (or NULL)
                  +  int * auxids, IN: array of converted var IDs
                  +  int  mode, IN: storing mode selector
                  +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument array of ADDs to file. Dumping is + either in text or binary form. see the corresponding BDD dump + function for further details. +

                  + +

                  Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

                  + +

                  See Also Dddmp_cuddAddStore +Dddmp_cuddAddLoad +Dddmp_cuddAddArrayLoad + + +
                  Defined in dddmpStoreAdd.c + +
                  +
                  +DdNode * 
                  +Dddmp_cuddAddLoad(
                  +  DdManager * ddMgr, IN: Manager
                  +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names by IDs
                  +  int * varmatchauxids, IN: array of variable auxids by IDs
                  +  int * varcomposeids, IN: array of new ids by IDs
                  +  int  mode, IN: requested input file format
                  +  char * file, IN: file name
                  +  FILE * fp IN: file pointer
                  +)
                  +
                  +
                  Reads a dump file representing the argument ADD. + Dddmp_cuddAddArrayLoad is used through a dummy array. +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddAddStore +Dddmp_cuddAddArrayLoad + + +
                  Defined in dddmpLoad.c + +
                  +
                  +int 
                  +Dddmp_cuddAddStore(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  char * ddname, IN: DD name (or NULL)
                  +  DdNode * f, IN: ADD root to be stored
                  +  char ** varnames, IN: array of variable names (or NULL)
                  +  int * auxids, IN: array of converted var ids
                  +  int  mode, IN: storing mode selector
                  +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument ADD to file. Dumping is done through + Dddmp_cuddAddArrayStore, And a dummy array of 1 ADD root is + used for this purpose. +

                  + +

                  Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

                  + +

                  See Also Dddmp_cuddAddLoad +Dddmp_cuddAddArrayLoad + + +
                  Defined in dddmpStoreAdd.c + +
                  +
                  +int 
                  +Dddmp_cuddBddArrayLoadCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  Dddmp_RootMatchType  rootmatchmode, IN: storing mode selector
                  +  char ** rootmatchnames, IN: sorted names for loaded roots
                  +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names, by IDs
                  +  int * varmatchauxids, IN: array of variable auxids, by IDs
                  +  int * varcomposeids, IN: array of new ids, by IDs
                  +  int  mode, IN: computation Mode
                  +  char * file, IN: file name
                  +  FILE * fp, IN: file pointer
                  +  DdNode *** rootsPtrPtr, OUT: array of returned BDD roots
                  +  int * nRoots OUT: number of BDDs returned
                  +)
                  +
                  +
                  Reads a dump file representing the argument BDD in a + CNF formula. +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddBddArrayLoad + + +
                  Defined in dddmpLoadCnf.c + +
                  +
                  +int 
                  +Dddmp_cuddBddArrayLoad(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
                  +  char ** rootmatchnames, IN: sorted names for loaded roots
                  +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names, by ids
                  +  int * varmatchauxids, IN: array of variable auxids, by ids
                  +  int * varcomposeids, IN: array of new ids, by ids
                  +  int  mode, IN: requested input file format
                  +  char * file, IN: file name
                  +  FILE * fp, IN: file pointer
                  +  DdNode *** pproots OUT: array of returned BDD roots
                  +)
                  +
                  +
                  Reads a dump file representing the argument BDDs. The header is + common to both text and binary mode. The node list is either + in text or binary format. A dynamic vector of DD pointers + is allocated to support conversion from DD indexes to pointers. + Several criteria are supported for variable match between file + and dd manager. Several changes/permutations/compositions are allowed + for variables while loading DDs. Variable of the dd manager are allowed + to match with variables on file on ids, permids, varnames, + varauxids; also direct composition between ids and + composeids is supported. More in detail: +
                    +
                  1. varMatchMode=DDDMP_VAR_MATCHIDS

                    + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

                  2. varMatchMode=DDDMP_VAR_MATCHPERMIDS

                    + is used to allow variable match according to the position in the + ordering. + +

                  3. varMatchMode=DDDMP_VAR_MATCHNAMES

                    + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

                  4. varMatchMode=DDDMP_VAR_MATCHIDS

                    + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

                  5. varMatchMode=DDDMP_VAR_COMPOSEIDS

                    + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. +

                  + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. + + All the loaded BDDs are referenced before returning them. +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddBddArrayStore + + +
                  Defined in dddmpLoad.c + +
                  +
                  +int 
                  +Dddmp_cuddBddArrayStoreBlif(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  int  nroots, IN: number of output BDD roots to be stored
                  +  DdNode ** f, IN: array of BDD roots to be stored
                  +  char ** inputNames, IN: array of variable names (or NULL)
                  +  char ** outputNames, IN: array of root names (or NULL)
                  +  char * modelName, IN: Model Name
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBLif. + A dummy array of 1 BDD root is used for this purpose. +

                  + +

                  See Also Dddmp_cuddBddArrayStorePrefix + + +
                  Defined in dddmpStoreMisc.c + +
                  +
                  +int 
                  +Dddmp_cuddBddArrayStoreCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDD roots to be stored
                  +  int  rootN, IN: # output BDD roots to be stored
                  +  Dddmp_DecompCnfStoreType  mode, IN: format selection
                  +  int  noHeader, IN: do not store header iff 1
                  +  char ** varNames, IN: array of variable names (or NULL)
                  +  int * bddIds, IN: array of converted var IDs
                  +  int * bddAuxIds, IN: array of BDD node Auxiliary Ids
                  +  int * cnfIds, IN: array of converted var IDs
                  +  int  idInitial, IN: starting id for cutting variables
                  +  int  edgeInTh, IN: Max # Incoming Edges
                  +  int  pathLengthTh, IN: Max Path Length
                  +  char * fname, IN: file name
                  +  FILE * fp, IN: pointer to the store file
                  +  int * clauseNPtr, OUT: number of clause stored
                  +  int * varNewNPtr OUT: number of new variable created
                  +)
                  +
                  +
                  Dumps the argument array of BDDs to file. +

                  + +

                  Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + Three methods are allowed: + * NodeByNode method: Insert a cut-point for each BDD node (but the + terminal nodes) + * MaxtermByMaxterm method: Insert no cut-points, i.e. the off-set of + trhe function is stored + * Best method: Tradeoff between the previous two methods. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. + The stored file can contain a file header or not depending on the + noHeader parameter (IFF 0, usual setting, the header is usually stored. + This option can be useful in storing multiple BDDs, as separate BDDs, + on the same file leaving the opening of the file to the caller. +

                  + +

                  Defined in dddmpStoreCnf.c + +
                  +
                  +int 
                  +Dddmp_cuddBddArrayStorePrefix(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  int  nroots, IN: number of output BDD roots to be stored
                  +  DdNode ** f, IN: array of BDD roots to be stored
                  +  char ** inputNames, IN: array of variable names (or NULL)
                  +  char ** outputNames, IN: array of root names (or NULL)
                  +  char * modelName, IN: Model Name
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                  + +

                  See Also Dddmp_cuddBddArrayStore + + +
                  Defined in dddmpStoreMisc.c + +
                  +
                  +int 
                  +Dddmp_cuddBddArrayStoreSmv(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  int  nroots, IN: number of output BDD roots to be stored
                  +  DdNode ** f, IN: array of BDD roots to be stored
                  +  char ** inputNames, IN: array of variable names (or NULL)
                  +  char ** outputNames, IN: array of root names (or NULL)
                  +  char * modelName, IN: Model Name
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                  + +

                  See Also Dddmp_cuddBddArrayStore + + +
                  Defined in dddmpStoreMisc.c + +
                  +
                  +int 
                  +Dddmp_cuddBddArrayStore(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  char * ddname, IN: dd name (or NULL)
                  +  int  nRoots, IN: number of output BDD roots to be stored
                  +  DdNode ** f, IN: array of BDD roots to be stored
                  +  char ** rootnames, IN: array of root names (or NULL)
                  +  char ** varnames, IN: array of variable names (or NULL)
                  +  int * auxids, IN: array of converted var IDs
                  +  int  mode, IN: storing mode selector
                  +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument array of BDDs to file. Dumping is either + in text or binary form. BDDs are stored to the fp (already + open) file if not NULL. Otherwise the file whose name is + fname is opened in write mode. The header has the same format + for both textual and binary dump. Names are allowed for input + variables (vnames) and for represented functions (rnames). + For sake of generality and because of dynamic variable + ordering both variable IDs and permuted IDs are included. + New IDs are also supported (auxids). Variables are identified + with incremental numbers. according with their positiom in + the support set. In text mode, an extra info may be added, + chosen among the following options: name, ID, PermID, or an + auxiliary id. Since conversion from DD pointers to integers + is required, DD nodes are temporarily removed from the unique + hash table. This allows the use of the next field to store + node IDs. +

                  + +

                  Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

                  + +

                  See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                  Defined in dddmpStoreBdd.c + +
                  +
                  +int 
                  +Dddmp_cuddBddDisplayBinary(
                  +  char * fileIn, IN: name of binary file
                  +  char * fileOut IN: name of text file
                  +)
                  +
                  +
                  Display a binary dump file in a text file +

                  + +

                  Side Effects None +

                  + +

                  See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad + + +
                  Defined in dddmpDbg.c + +
                  +
                  +int 
                  +Dddmp_cuddBddLoadCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names, by IDs
                  +  int * varmatchauxids, IN: array of variable auxids, by IDs
                  +  int * varcomposeids, IN: array of new ids accessed, by IDs
                  +  int  mode, IN: computation mode
                  +  char * file, IN: file name
                  +  FILE * fp, IN: file pointer
                  +  DdNode *** rootsPtrPtr, OUT: array of returned BDD roots
                  +  int * nRoots OUT: number of BDDs returned
                  +)
                  +
                  +
                  Reads a dump file representing the argument BDD in a + CNF formula. + Dddmp_cuddBddArrayLoadCnf is used through a dummy array. + The results is returned in different formats depending on the + mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                  Defined in dddmpLoadCnf.c + +
                  +
                  +DdNode * 
                  +Dddmp_cuddBddLoad(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names - by IDs
                  +  int * varmatchauxids, IN: array of variable auxids - by IDs
                  +  int * varcomposeids, IN: array of new ids accessed - by IDs
                  +  int  mode, IN: requested input file format
                  +  char * file, IN: file name
                  +  FILE * fp IN: file pointer
                  +)
                  +
                  +
                  Reads a dump file representing the argument BDD. + Dddmp_cuddBddArrayLoad is used through a dummy array (see this + function's description for more details). + Mode, the requested input file format, is checked against + the file format. + The loaded BDDs is referenced before returning it. +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddBddStore +Dddmp_cuddBddArrayLoad + + +
                  Defined in dddmpLoad.c + +
                  +
                  +int 
                  +Dddmp_cuddBddStoreBlif(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  int  nRoots, IN: Number of BDD roots
                  +  DdNode * f, IN: BDD root to be stored
                  +  char ** inputNames, IN: Array of variable names
                  +  char ** outputNames, IN: Array of root names
                  +  char * modelName, IN: Model Name
                  +  char * fileName, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBlif. + A dummy array of 1 BDD root is used for this purpose. +

                  + +

                  See Also Dddmp_cuddBddStorePrefix + + +
                  Defined in dddmpStoreMisc.c + +
                  +
                  +int 
                  +Dddmp_cuddBddStoreCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f, IN: BDD root to be stored
                  +  Dddmp_DecompCnfStoreType  mode, IN: format selection
                  +  int  noHeader, IN: do not store header iff 1
                  +  char ** varNames, IN: array of variable names (or NULL)
                  +  int * bddIds, IN: array of var ids
                  +  int * bddAuxIds, IN: array of BDD node Auxiliary Ids
                  +  int * cnfIds, IN: array of CNF var ids
                  +  int  idInitial, IN: starting id for cutting variables
                  +  int  edgeInTh, IN: Max # Incoming Edges
                  +  int  pathLengthTh, IN: Max Path Length
                  +  char * fname, IN: file name
                  +  FILE * fp, IN: pointer to the store file
                  +  int * clauseNPtr, OUT: number of clause stored
                  +  int * varNewNPtr OUT: number of new variable created
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + This task is performed by calling the function + Dddmp_cuddBddArrayStoreCnf. +

                  + +

                  Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

                  + +

                  See Also Dddmp_cuddBddArrayStoreCnf + + +
                  Defined in dddmpStoreCnf.c + +
                  +
                  +int 
                  +Dddmp_cuddBddStorePrefix(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  int  nRoots, IN: Number of BDD roots
                  +  DdNode * f, IN: BDD root to be stored
                  +  char ** inputNames, IN: Array of variable names
                  +  char ** outputNames, IN: Array of root names
                  +  char * modelName, IN: Model Name
                  +  char * fileName, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                  + +

                  See Also Dddmp_cuddBddStore + + +
                  Defined in dddmpStoreMisc.c + +
                  +
                  +int 
                  +Dddmp_cuddBddStoreSmv(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  int  nRoots, IN: Number of BDD roots
                  +  DdNode * f, IN: BDD root to be stored
                  +  char ** inputNames, IN: Array of variable names
                  +  char ** outputNames, IN: Array of root names
                  +  char * modelName, IN: Model Name
                  +  char * fileName, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                  + +

                  See Also Dddmp_cuddBddStore + + +
                  Defined in dddmpStoreMisc.c + +
                  +
                  +int 
                  +Dddmp_cuddBddStore(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  char * ddname, IN: DD name (or NULL)
                  +  DdNode * f, IN: BDD root to be stored
                  +  char ** varnames, IN: array of variable names (or NULL)
                  +  int * auxids, IN: array of converted var ids
                  +  int  mode, IN: storing mode selector
                  +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. Dumping is done through + Dddmp_cuddBddArrayStore. A dummy array of 1 BDD root is + used for this purpose. +

                  + +

                  Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

                  + +

                  See Also Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                  Defined in dddmpStoreBdd.c + +
                  +
                  +int 
                  +Dddmp_cuddHeaderLoadCnf(
                  +  int * nVars, OUT: number of DD variables
                  +  int * nsuppvars, OUT: number of support variables
                  +  char *** suppVarNames, OUT: array of support variable names
                  +  char *** orderedVarNames, OUT: array of variable names
                  +  int ** varIds, OUT: array of variable ids
                  +  int ** varComposeIds, OUT: array of permids ids
                  +  int ** varAuxIds, OUT: array of variable aux ids
                  +  int * nRoots, OUT: number of root in the file
                  +  char * file, IN: file name
                  +  FILE * fp IN: file pointer
                  +)
                  +
                  +
                  Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. +

                  + +

                  See Also Dddmp_cuddBddArrayLoad + + +
                  Defined in dddmpLoadCnf.c + +
                  +
                  +int 
                  +Dddmp_cuddHeaderLoad(
                  +  Dddmp_DecompType * ddType, OUT: selects the proper decomp type
                  +  int * nVars, OUT: number of DD variables
                  +  int * nsuppvars, OUT: number of support variables
                  +  char *** suppVarNames, OUT: array of support variable names
                  +  char *** orderedVarNames, OUT: array of variable names
                  +  int ** varIds, OUT: array of variable ids
                  +  int ** varComposeIds, OUT: array of permids ids
                  +  int ** varAuxIds, OUT: array of variable aux ids
                  +  int * nRoots, OUT: number of root in the file
                  +  char * file, IN: file name
                  +  FILE * fp IN: file pointer
                  +)
                  +
                  +
                  Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. +

                  + +

                  See Also Dddmp_cuddBddArrayLoad + + +
                  Defined in dddmpLoad.c + +
                  +
                  +int 
                  +FindVarname(
                  +  char * name, IN: name to look for
                  +  char ** array, IN: search array
                  +  int  n IN: size of the array
                  +)
                  +
                  +
                  Binary search of a name within a sorted array of strings. + Used when matching names of variables. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpUtil.c + +
                  +
                  +static int 
                  +NodeBinaryStoreBdd(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f, IN: DD node to be stored
                  +  int  mode, IN: store mode
                  +  int * supportids, IN: internal ids for variables
                  +  char ** varnames, IN: names of variables: to be stored with nodes
                  +  int * outids, IN: output ids for variables
                  +  FILE * fp, IN: store file
                  +  int  idf, IN: index of the node
                  +  int  vf, IN: variable of the node
                  +  int  idT, IN: index of the Then node
                  +  int  idE, IN: index of the Else node
                  +  int  vT, IN: variable of the Then node
                  +  int  vE, IN: variable of the Else node
                  +  DdNode * T, IN: Then node
                  +  DdNode * E IN: Else node
                  +)
                  +
                  +
                  Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. + Store every information as coded binary values. +

                  + +

                  Side Effects None +

                  + +

                  See Also NodeTextStoreBdd + + +
                  Defined in dddmpStoreBdd.c + +
                  +
                  +static int 
                  +NodeStoreRecurAdd(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f, IN: DD node to be stored
                  +  int  mode, IN: store mode
                  +  int * supportids, IN: internal ids for variables
                  +  char ** varnames, IN: names of variables: to be stored with nodes
                  +  int * outids, IN: output ids for variables
                  +  FILE * fp IN: store file
                  +)
                  +
                  +
                  Stores a node to file in either test or binary mode. + In text mode a node is represented (on a text line basis) as +
                    +
                  • node-index [var-extrainfo] var-index Then-index Else-index +
                  + + where all indexes are integer numbers and var-extrainfo + (optional redundant field) is either an integer or a string + (variable name). Node-index is redundant (due to the node + ordering) but we keep it for readability.

                  + + In binary mode nodes are represented as a sequence of bytes, + representing var-index, Then-index, and Else-index in an + optimized way. Only the first byte (code) is mandatory. + Integer indexes are represented in absolute or relative mode, + where relative means offset wrt. a Then/Else node info. + Suppose Var(NodeId), Then(NodeId) and Else(NodeId) represent + infos about a given node.

                  + + The generic "NodeId" node is stored as + +

                    +
                  • code-byte +
                  • [var-info] +
                  • [Then-info] +
                  • [Else-info] +
                  + + where code-byte contains bit fields + +
                    +
                  • Unused : 1 bit +
                  • Variable: 2 bits, one of the following codes +
                      +
                    • DDDMP_ABSOLUTE_ID var-info = Var(NodeId) follows +
                    • DDDMP_RELATIVE_ID Var(NodeId) is represented in relative form as + var-info = Min(Var(Then(NodeId)),Var(Else(NodeId))) -Var(NodeId) +
                    • DDDMP_RELATIVE_1 No var-info follows, because + Var(NodeId) = Min(Var(Then(NodeId)),Var(Else(NodeId)))-1 +
                    • DDDMP_TERMINAL Node is a terminal, no var info required +
                    +
                  • T : 2 bits, with codes similar to V +
                      +
                    • DDDMP_ABSOLUTE_ID Then-info = Then(NodeId) follows +
                    • DDDMP_RELATIVE_ID Then(NodeId) is represented in relative form as + Then-info = Nodeid-Then(NodeId) +
                    • DDDMP_RELATIVE_1 No info on Then(NodeId) follows, because + Then(NodeId) = NodeId-1 +
                    • DDDMP_TERMINAL Then Node is a terminal, no info required (for BDDs) +
                    +
                  • Ecompl : 1 bit, if 1 means complemented edge +
                  • E : 2 bits, with codes and meanings as for the Then edge +
                  + var-info, Then-info, Else-info (if required) are represented as unsigned + integer values on a sufficient set of bytes (MSByte first). +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpStoreAdd.c + +
                  +
                  +static int 
                  +NodeStoreRecurBdd(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f, IN: DD node to be stored
                  +  int  mode, IN: store mode
                  +  int * supportids, IN: internal ids for variables
                  +  char ** varnames, IN: names of variables: to be stored with nodes
                  +  int * outids, IN: output ids for variables
                  +  FILE * fp IN: store file
                  +)
                  +
                  +
                  Stores a node to file in either test or binary mode. + In text mode a node is represented (on a text line basis) as +
                    +
                  • node-index [var-extrainfo] var-index Then-index Else-index +
                  + + where all indexes are integer numbers and var-extrainfo + (optional redundant field) is either an integer or a string + (variable name). Node-index is redundant (due to the node + ordering) but we keep it for readability.

                  + + In binary mode nodes are represented as a sequence of bytes, + representing var-index, Then-index, and Else-index in an + optimized way. Only the first byte (code) is mandatory. + Integer indexes are represented in absolute or relative mode, + where relative means offset wrt. a Then/Else node info. + Suppose Var(NodeId), Then(NodeId) and Else(NodeId) represent + infos about a given node.

                  + + The generic "NodeId" node is stored as + +

                    +
                  • code-byte +
                  • [var-info] +
                  • [Then-info] +
                  • [Else-info] +
                  + + where code-byte contains bit fields + +
                    +
                  • Unused : 1 bit +
                  • Variable: 2 bits, one of the following codes +
                      +
                    • DDDMP_ABSOLUTE_ID var-info = Var(NodeId) follows +
                    • DDDMP_RELATIVE_ID Var(NodeId) is represented in relative form as + var-info = Min(Var(Then(NodeId)),Var(Else(NodeId))) -Var(NodeId) +
                    • DDDMP_RELATIVE_1 No var-info follows, because + Var(NodeId) = Min(Var(Then(NodeId)),Var(Else(NodeId)))-1 +
                    • DDDMP_TERMINAL Node is a terminal, no var info required +
                    +
                  • T : 2 bits, with codes similar to V +
                      +
                    • DDDMP_ABSOLUTE_ID Then-info = Then(NodeId) follows +
                    • DDDMP_RELATIVE_ID Then(NodeId) is represented in relative form as + Then-info = Nodeid-Then(NodeId) +
                    • DDDMP_RELATIVE_1 No info on Then(NodeId) follows, because + Then(NodeId) = NodeId-1 +
                    • DDDMP_TERMINAL Then Node is a terminal, no info required (for BDDs) +
                    +
                  • Ecompl : 1 bit, if 1 means complemented edge +
                  • E : 2 bits, with codes and meanings as for the Then edge +
                  + var-info, Then-info, Else-info (if required) are represented as unsigned + integer values on a sufficient set of bytes (MSByte first). +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpStoreBdd.c + +
                  +
                  +static int 
                  +NodeTextStoreAdd(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f, IN: DD node to be stored
                  +  int  mode, IN: store mode
                  +  int * supportids, IN: internal ids for variables
                  +  char ** varnames, IN: names of variables: to be stored with nodes
                  +  int * outids, IN: output ids for variables
                  +  FILE * fp, IN: Store file
                  +  int  idf, IN: index of the current node
                  +  int  vf, IN: variable of the current node
                  +  int  idT, IN: index of the Then node
                  +  int  idE IN: index of the Else node
                  +)
                  +
                  +
                  Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. +

                  + +

                  Side Effects None +

                  + +

                  See Also NodeBinaryStore + + +
                  Defined in dddmpStoreAdd.c + +
                  +
                  +static int 
                  +NodeTextStoreBdd(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f, IN: DD node to be stored
                  +  int  mode, IN: store mode
                  +  int * supportids, IN: internal ids for variables
                  +  char ** varnames, IN: names of variables: to be stored with nodes
                  +  int * outids, IN: output ids for variables
                  +  FILE * fp, IN: Store file
                  +  int  idf, IN: index of the current node
                  +  int  vf, IN: variable of the current node
                  +  int  idT, IN: index of the Then node
                  +  int  idE IN: index of the Else node
                  +)
                  +
                  +
                  Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. +

                  + +

                  Side Effects None +

                  + +

                  See Also NodeBinaryStoreBdd + + +
                  Defined in dddmpStoreBdd.c + +
                  +
                  +static int 
                  +NumberNodeRecurAdd(
                  +  DdNode * f, IN: root of the BDD to be numbered
                  +  int  id IN/OUT: index to be assigned to the node
                  +)
                  +
                  +
                  Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

                  + +

                  Side Effects "visited" flags are reset. +

                  + +

                  Defined in dddmpNodeAdd.c + +
                  +
                  +static int 
                  +NumberNodeRecurBdd(
                  +  DdNode * f, IN: root of the BDD to be numbered
                  +  int  id IN/OUT: index to be assigned to the node
                  +)
                  +
                  +
                  Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

                  + +

                  Side Effects "visited" flags are reset. +

                  + +

                  Defined in dddmpNodeBdd.c + +
                  +
                  +static int 
                  +NumberNodeRecurCnf(
                  +  DdNode * f, IN: root of the BDD to be numbered
                  +  int * cnfIds, IN: possible source for numbering
                  +  int  id IN/OUT: possible source for numbering
                  +)
                  +
                  +
                  Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

                  + +

                  Side Effects "visited" flags are reset. +

                  + +

                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +static int 
                  +NumberNodeRecurCnf(
                  +  DdNode * f, IN: root of the BDD to be numbered
                  +  int * cnfIds, IN: possible source for numbering
                  +  int  id IN/OUT: possible source for numbering
                  +)
                  +
                  +
                  Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

                  + +

                  Side Effects "visited" flags are reset. +

                  + +

                  Defined in dddmpNodeCnf.c + +
                  +
                  +static int 
                  +NumberNodeRecur(
                  +  DdNode * f, IN: root of the BDD to be numbered
                  +  int  id IN/OUT: index to be assigned to the node
                  +)
                  +
                  +
                  Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

                  + +

                  Side Effects "visited" flags are reset. +

                  + +

                  Defined in dddmpDdNodeBdd.c + +
                  +
                  +int 
                  +QsortStrcmp(
                  +  const void * ps1, IN: pointer to the first string
                  +  const void * ps2 IN: pointer to the second string
                  +)
                  +
                  +
                  String compare for qsort +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpUtil.c + +
                  +
                  +static int 
                  +ReadByteBinary(
                  +  FILE * fp, IN: file where to read the byte
                  +  unsigned char * cp OUT: the read byte
                  +)
                  +
                  +
                  inputs a byte to file fp. 0x00 has been used as escape character + to filter , and . This is done for + compatibility between unix and dos/windows systems. +

                  + +

                  Side Effects None +

                  + +

                  See Also WriteByteBinary() + + +
                  Defined in dddmpBinary.c + +
                  +
                  +static void 
                  +RemoveFromUniqueRecurAdd(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f IN: root of the BDD to be extracted
                  +)
                  +
                  +
                  Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. Constants remain untouched. +

                  + +

                  Side Effects Nodes are left with the "visited" flag true. +

                  + +

                  See Also RestoreInUniqueRecurAdd +() + + +
                  Defined in dddmpNodeAdd.c + +
                  +
                  +static void 
                  +RemoveFromUniqueRecurBdd(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f IN: root of the BDD to be extracted
                  +)
                  +
                  +
                  Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. Constants remain untouched. +

                  + +

                  Side Effects Nodes are left with the "visited" flag true. +

                  + +

                  See Also RestoreInUniqueRecurBdd +() + + +
                  Defined in dddmpNodeBdd.c + +
                  +
                  +static void 
                  +RemoveFromUniqueRecurCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f IN: root of the BDD to be extracted
                  +)
                  +
                  +
                  Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on on the + children of the node. Constants remain untouched. +

                  + +

                  Side Effects Nodes are left with the "visited" flag true. +

                  + +

                  See Also RestoreInUniqueRecurCnf() + + +
                  Defined in dddmpNodeCnf.c + +
                  +
                  +static void 
                  +RemoveFromUniqueRecurCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f IN: root of the BDD to be extracted
                  +)
                  +
                  +
                  Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on son nodes. +

                  + +

                  Side Effects Nodes are left with the "visited" flag true. +

                  + +

                  See Also RestoreInUniqueRecurCnf() + + +
                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +static void 
                  +RemoveFromUniqueRecur(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f IN: root of the BDD to be extracted
                  +)
                  +
                  +
                  Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. +

                  + +

                  Side Effects Nodes are left with the "visited" flag true. +

                  + +

                  See Also RestoreInUniqueRecur() + + +
                  Defined in dddmpDdNodeBdd.c + +
                  +
                  +static void 
                  +RestoreInUniqueRecurAdd(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f IN: root of the BDD to be restored
                  +)
                  +
                  +
                  Restores a node in unique table (recursively) +

                  + +

                  Side Effects Nodes are not restored in the same order as before removal +

                  + +

                  See Also RemoveFromUniqueAdd +() + + +
                  Defined in dddmpNodeAdd.c + +
                  +
                  +static void 
                  +RestoreInUniqueRecurBdd(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f IN: root of the BDD to be restored
                  +)
                  +
                  +
                  Restores a node in unique table (recursively) +

                  + +

                  Side Effects Nodes are not restored in the same order as before removal +

                  + +

                  See Also RemoveFromUnique() + + +
                  Defined in dddmpNodeBdd.c + +
                  +
                  +static void 
                  +RestoreInUniqueRecurCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f IN: root of the BDD to be restored
                  +)
                  +
                  +
                  Restores a node in unique table (recursive) +

                  + +

                  Side Effects Nodes are not restored in the same order as before removal +

                  + +

                  See Also RemoveFromUnique() + + +
                  Defined in dddmpDdNodeCnf.c + +
                  +
                  +static void 
                  +RestoreInUniqueRecurCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f IN: root of the BDD to be restored
                  +)
                  +
                  +
                  Restores a node in unique table (recursive) +

                  + +

                  Side Effects Nodes are not restored in the same order as before removal +

                  + +

                  See Also RemoveFromUnique() + + +
                  Defined in dddmpNodeCnf.c + +
                  +
                  +static void 
                  +RestoreInUniqueRecur(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f IN: root of the BDD to be restored
                  +)
                  +
                  +
                  Restores a node in unique table (recursively) +

                  + +

                  Side Effects Nodes are not restored in the same order as before removal +

                  + +

                  See Also RemoveFromUnique() + + +
                  Defined in dddmpDdNodeBdd.c + +
                  +
                  +static int 
                  +StoreCnfBestNotSharedRecur(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * node, IN: BDD to store
                  +  int  idf, IN: Id to store
                  +  int * bddIds, IN: BDD identifiers
                  +  int * cnfIds, IN: corresponding CNF identifiers
                  +  FILE * fp, IN: file pointer
                  +  int * list, IN: temporary array to store cubes
                  +  int * clauseN, OUT: number of stored clauses
                  +  int * varMax OUT: maximum identifier of the variables created
                  +)
                  +
                  +
                  Performs the recursive step of Print Best on Not Shared + sub-BDDs, i.e., print out information for the nodes belonging to + BDDs not shared (whose root has just one incoming edge). +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpStoreCnf.c + +
                  +
                  +static int 
                  +StoreCnfBestSharedRecur(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * node, IN: BDD to store
                  +  int * bddIds, IN: BDD identifiers
                  +  int * cnfIds, IN: corresponding CNF identifiers
                  +  FILE * fp, IN: file pointer
                  +  int * list, IN: temporary array to store cubes
                  +  int * clauseN, OUT: number of stored clauses
                  +  int * varMax OUT: maximum identifier of the variables created
                  +)
                  +
                  +
                  Performs the recursive step of Print Best on Not Shared + sub-BDDs, i.e., print out information for the nodes belonging to + BDDs not shared (whose root has just one incoming edge). +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpStoreCnf.c + +
                  +
                  +static int 
                  +StoreCnfBest(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDDs to store
                  +  int  rootN, IN: number of BDD in the array
                  +  int * bddIds, IN: BDD identifiers
                  +  int * cnfIds, IN: corresponding CNF identifiers
                  +  int  idInitial, IN: initial value for numbering new CNF variables
                  +  FILE * fp, IN: file pointer
                  +  int * varMax, OUT: maximum identifier of the variables created
                  +  int * clauseN, OUT: number of stored clauses
                  +  int * rootStartLine OUT: line where root starts
                  +)
                  +
                  +
                  Prints a disjoint sum of product cover for the function + rooted at node intorducing cutting points whenever necessary. + Each product corresponds to a path from node a leaf + node different from the logical zero, and different from the + background value. Uses the standard output. Returns 1 if + successful, 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also StoreCnfMaxtermByMaxterm + + +
                  Defined in dddmpStoreCnf.c + +
                  +
                  +static void 
                  +StoreCnfMaxtermByMaxtermRecur(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * node, IN: BDD to store
                  +  int * bddIds, IN: BDD identifiers
                  +  int * cnfIds, IN: corresponding CNF identifiers
                  +  FILE * fp, IN: file pointer
                  +  int * list, IN: temporary array to store cubes
                  +  int * clauseN, OUT: number of stored clauses
                  +  int * varMax OUT: maximum identifier of the variables created
                  +)
                  +
                  +
                  Performs the recursive step of Print Maxterm. + Traverse a BDD a print out a cube in CNF format each time a terminal + node is reached. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpStoreCnf.c + +
                  +
                  +static int 
                  +StoreCnfMaxtermByMaxterm(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDDs to store
                  +  int  rootN, IN: number of BDDs in the array
                  +  int * bddIds, IN: BDD Identifiers
                  +  int * cnfIds, IN: corresponding CNF Identifiers
                  +  int  idInitial, IN: initial value for numbering new CNF variables
                  +  FILE * fp, IN: file pointer
                  +  int * varMax, OUT: maximum identifier of the variables created
                  +  int * clauseN, OUT: number of stored clauses
                  +  int * rootStartLine OUT: line where root starts
                  +)
                  +
                  +
                  Prints a disjoint sum of product cover for the function + rooted at node. Each product corresponds to a path from node a + leaf node different from the logical zero, and different from + the background value. Uses the standard output. Returns 1 if + successful, 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also StoreCnfBest + + +
                  Defined in dddmpStoreCnf.c + +
                  +
                  +static int 
                  +StoreCnfNodeByNodeRecur(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f, IN: BDD node to be stored
                  +  int * bddIds, IN: BDD ids for variables
                  +  int * cnfIds, IN: CNF ids for variables
                  +  FILE * fp, IN: store file
                  +  int * clauseN, OUT: number of clauses written in the CNF file
                  +  int * varMax OUT: maximum value of id written in the CNF file
                  +)
                  +
                  +
                  Performs the recursive step of Dddmp_bddStore. + Traverse the BDD and store a CNF formula for each "terminal" node. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpStoreCnf.c + +
                  +
                  +static int 
                  +StoreCnfNodeByNode(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: BDD array to be stored
                  +  int  rootN, IN: number of BDDs in the array
                  +  int * bddIds, IN: BDD ids for variables
                  +  int * cnfIds, IN: CNF ids for variables
                  +  FILE * fp, IN: store file
                  +  int * clauseN, IN/OUT: number of clauses written in the CNF file
                  +  int * varMax, IN/OUT: maximum value of id written in the CNF file
                  +  int * rootStartLine OUT: CNF line where root starts
                  +)
                  +
                  +
                  Store the BDD as CNF clauses. + Use a multiplexer description for each BDD node. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpStoreCnf.c + +
                  +
                  +static int 
                  +StoreCnfOneNode(
                  +  DdNode * f, IN: node to be stored
                  +  int  idf, IN: node CNF Index
                  +  int  vf, IN: node BDD Index
                  +  int  idT, IN: Then CNF Index with sign = inverted edge
                  +  int  idE, IN: Else CNF Index with sign = inverted edge
                  +  FILE * fp, IN: store file
                  +  int * clauseN, OUT: number of clauses
                  +  int * varMax OUT: maximun Index of variable stored
                  +)
                  +
                  +
                  Store One Single BDD Node translating it as a multiplexer. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpStoreCnf.c + +
                  +
                  +static int 
                  +WriteByteBinary(
                  +  FILE * fp, IN: file where to write the byte
                  +  unsigned char  c IN: the byte to be written
                  +)
                  +
                  +
                  outputs a byte to file fp. Uses 0x00 as escape character + to filter , and . + This is done for compatibility between unix and dos/windows systems. +

                  + +

                  Side Effects None +

                  + +

                  See Also ReadByteBinary() + + +
                  Defined in dddmpBinary.c + +
                  +
                  +static int 
                  +printCubeCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * node, IN: BDD to store
                  +  int * cnfIds, IN: CNF identifiers
                  +  FILE * fp, IN: file pointer
                  +  int * list, IN: temporary array to store cubes
                  +  int * varMax OUT: maximum identifier of the variables created
                  +)
                  +
                  +
                  Print One Cube in CNF Format. + Return DDDMP_SUCCESS if something is printed out, DDDMP_FAILURE + is nothing is printed out. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpStoreCnf.c + +
                  +
                  + 
                  +(
                  +    
                  +)
                  +
                  +
                  Checks for Warnings: If expr==1 it prints out the warning + on stderr. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmp.h + +
                  +
                  + 
                  +(
                  +    
                  +)
                  +
                  +
                  Checks for fatal bugs and go to the label to deal with + the error. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmp.h + +
                  +
                  + 
                  +(
                  +    
                  +)
                  +
                  +
                  Checks for fatal bugs and return the DDDMP_FAILURE flag. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmp.h + +
                  +
                  + 
                  +(
                  +    
                  +)
                  +
                  +
                  Conditional safety assertion. It prints out the file + name and line number where the fatal error occurred. + Messages are printed out on stderr. +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmp.h + +
                  +
                  + 
                  +(
                  +    
                  +)
                  +
                  +
                  Memory Allocation Macro for DDDMP +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpInt.h + +
                  +
                  + 
                  +(
                  +    
                  +)
                  +
                  +
                  Memory Free Macro for DDDMP +

                  + +

                  Side Effects None +

                  + +

                  Defined in dddmpInt.h + + +
                  +
                  +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllFile.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllFile.html new file mode 100644 index 000000000..2664d07f4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpAllFile.html @@ -0,0 +1,679 @@ + +The dddmp package: files + + +
                  +
                  dddmp.h +
                  External header file +
                  dddmpInt.h +
                  Internal header file +
                  dddmpBinary.c +
                  Input and output BDD codes and integers from/to file +
                  dddmpConvert.c +
                  Conversion between ASCII and binary formats +
                  dddmpDbg.c +
                  Functions to display BDD files +
                  dddmpDdNodeBdd.c +
                  Functions to handle BDD node infos and numbering +
                  dddmpDdNodeCnf.c +
                  Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs +
                  dddmpLoad.c +
                  Functions to read in bdds to file +
                  dddmpLoadCnf.c +
                  Functions to read in CNF from file as BDDs. +
                  dddmpNodeAdd.c +
                  Functions to handle ADD node infos and numbering +
                  dddmpNodeBdd.c +
                  Functions to handle BDD node infos and numbering +
                  dddmpNodeCnf.c +
                  Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs +
                  dddmpStoreAdd.c +
                  Functions to write ADDs to file. +
                  dddmpStoreBdd.c +
                  Functions to write BDDs to file. +
                  dddmpStoreCnf.c +
                  Functions to write out BDDs to file in a CNF format +
                  dddmpStoreMisc.c +
                  Functions to write out bdds to file in prefixed + and in Blif form. +
                  dddmpUtil.c +
                  Util Functions for the dddmp package +

                  +

                  dddmp.h

                  +External header file

                  +By: Gianpiero Cabodi and Stefano Quer

                  +

                  +
                  () +
                  Checks for fatal bugs + +
                  () +
                  Checks for Warnings: If expr==1 it prints out the warning + on stderr. + +
                  () +
                  Checks for fatal bugs and return the DDDMP_FAILURE flag. + +
                  () +
                  Checks for fatal bugs and go to the label to deal with + the error. + +
                  +
                  +

                  dddmpInt.h

                  +Internal header file

                  +By: Gianpiero Cabodi and Stefano Quer

                  +

                  +
                  () +
                  Memory Allocation Macro for DDDMP + +
                  () +
                  Memory Free Macro for DDDMP + +
                  +
                  +

                  dddmpBinary.c

                  +Input and output BDD codes and integers from/to file

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Input and output BDD codes and integers from/to file + in binary mode. + DD node codes are written as one byte. + Integers of any length are written as sequences of "linked" bytes. + For each byte 7 bits are used for data and one (MSBit) as link with + a further byte (MSB = 1 means one more byte). + Low level read/write of bytes filter , and + with escape sequences.

                  +

                  +
                  DddmpWriteCode() +
                  Writes 1 byte node code + +
                  DddmpReadCode() +
                  Reads a 1 byte node code + +
                  DddmpWriteInt() +
                  Writes a "packed integer" + +
                  DddmpReadInt() +
                  Reads a "packed integer" + +
                  WriteByteBinary() +
                  Writes a byte to file filtering , and + +
                  ReadByteBinary() +
                  Reads a byte from file with escaped , and + +
                  +
                  +

                  dddmpConvert.c

                  +Conversion between ASCII and binary formats

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Conversion between ASCII and binary formats is presently + supported by loading a BDD in the source format and storing it + in the target one. We plan to introduce ad hoc procedures + avoiding explicit BDD node generation.

                  +

                  +
                  Dddmp_Text2Bin() +
                  Converts from ASCII to binary format + +
                  Dddmp_Bin2Text() +
                  Converts from binary to ASCII format + +
                  +
                  +

                  dddmpDbg.c

                  +Functions to display BDD files

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Functions to display BDD files in binary format

                  +

                  +
                  Dddmp_cuddBddDisplayBinary() +
                  Display a binary dump file in a text file + +
                  +
                  +

                  dddmpDdNodeBdd.c

                  +Functions to handle BDD node infos and numbering

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Functions to handle BDD node infos and numbering.

                  +

                  +
                  DddmpNumberDdNodes() +
                  Removes nodes from unique table and number them + +
                  DddmpUnnumberDdNodes() +
                  Restores nodes in unique table, loosing numbering + +
                  DddmpWriteNodeIndex() +
                  Write index to node + +
                  DddmpReadNodeIndex() +
                  Reads the index of a node + +
                  DddmpVisited() +
                  Returns true if node is visited + +
                  DddmpSetVisited() +
                  Marks a node as visited + +
                  DddmpClearVisited() +
                  Marks a node as not visited + +
                  NumberNodeRecur() +
                  Number nodes recursively in post-order + +
                  RemoveFromUniqueRecur() +
                  Removes a node from unique table + +
                  RestoreInUniqueRecur() +
                  Restores a node in unique table + +
                  +
                  +

                  dddmpDdNodeCnf.c

                  +Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs.

                  +

                  +
                  DddmpNumberDdNodesCnf() +
                  Removes nodes from unique table and numbers them + +
                  DddmpDdNodesCountEdgesAndNumber() +
                  Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. + +
                  DddmpUnnumberDdNodesCnf() +
                  Restores nodes in unique table, loosing numbering + +
                  DddmpPrintBddAndNext() +
                  Prints debug information + +
                  DddmpWriteNodeIndexCnfBis() +
                  Write index to node + +
                  DddmpWriteNodeIndexCnf() +
                  Write index to node + +
                  DddmpReadNodeIndexCnf() +
                  Reads the index of a node + +
                  DddmpClearVisitedCnfRecur() +
                  Mark ALL nodes as not visited + +
                  DddmpVisitedCnf() +
                  Returns true if node is visited + +
                  DddmpSetVisitedCnf() +
                  Marks a node as visited + +
                  DddmpClearVisitedCnf() +
                  Marks a node as not visited + +
                  NumberNodeRecurCnf() +
                  Number nodes recursively in post-order + +
                  DddmpDdNodesCheckIncomingAndScanPath() +
                  Number nodes recursively in post-order + +
                  DddmpDdNodesNumberEdgesRecur() +
                  Number nodes recursively in post-order + +
                  DddmpDdNodesResetCountRecur() +
                  Resets counter and visited flag for ALL nodes of a BDD + +
                  DddmpDdNodesCountEdgesRecur() +
                  Counts the number of incoming edges for each node of a BDD + +
                  RemoveFromUniqueRecurCnf() +
                  Removes a node from unique table + +
                  RestoreInUniqueRecurCnf() +
                  Restores a node in unique table + +
                  DddmpPrintBddAndNextRecur() +
                  Prints debug info + +
                  +
                  +

                  dddmpLoad.c

                  +Functions to read in bdds to file

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Functions to read in bdds to file. BDDs + are represended on file either in text or binary format under the + following rules. A file contains a forest of BDDs (a vector of + Boolean functions). BDD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to BDD + functions, followed by the list of nodes. BDD nodes are listed + according to their numbering, and in the present implementation + numbering follows a post-order strategy, in such a way that a node + is never listed before its Then/Else children.

                  +

                  +
                  Dddmp_cuddBddLoad() +
                  Reads a dump file representing the argument BDD. + +
                  Dddmp_cuddBddArrayLoad() +
                  Reads a dump file representing the argument BDDs. + +
                  Dddmp_cuddAddLoad() +
                  Reads a dump file representing the argument ADD. + +
                  Dddmp_cuddAddArrayLoad() +
                  Reads a dump file representing the argument ADDs. + +
                  Dddmp_cuddHeaderLoad() +
                  Reads the header of a dump file representing the argument BDDs + +
                  DddmpCuddDdArrayLoad() +
                  Reads a dump file representing the argument BDDs. + +
                  DddmpBddReadHeader() +
                  Reads a the header of a dump file representing the + argument BDDs. + +
                  DddmpFreeHeader() +
                  Frees the internal header structure. + +
                  +
                  +

                  dddmpLoadCnf.c

                  +Functions to read in CNF from file as BDDs.

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Functions to read in CNF from file as BDDs.

                  +

                  +
                  Dddmp_cuddBddLoadCnf() +
                  Reads a dump file in a CNF format. + +
                  Dddmp_cuddBddArrayLoadCnf() +
                  Reads a dump file in a CNF format. + +
                  Dddmp_cuddHeaderLoadCnf() +
                  Reads the header of a dump file representing the argument BDDs + +
                  DddmpCuddDdArrayLoadCnf() +
                  Reads a dump file representing the argument BDDs in CNF + format. + +
                  DddmpBddReadHeaderCnf() +
                  Reads a the header of a dump file representing the argument + BDDs. + +
                  DddmpFreeHeaderCnf() +
                  Frees the internal header structure. + +
                  DddmpReadCnfClauses() +
                  Read the CNF clauses from the file in the standard DIMACS + format. + +
                  DddmpCnfClauses2Bdd() +
                  Transforms CNF clauses into BDDs. + +
                  +
                  +

                  dddmpNodeAdd.c

                  +Functions to handle ADD node infos and numbering

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Functions to handle ADD node infos and numbering.

                  +

                  +
                  DddmpNumberAddNodes() +
                  Removes nodes from unique table and number them + +
                  DddmpUnnumberAddNodes() +
                  Restores nodes in unique table, loosing numbering + +
                  DddmpWriteNodeIndexAdd() +
                  Write index to node + +
                  DddmpReadNodeIndexAdd() +
                  Reads the index of a node + +
                  DddmpVisitedAdd() +
                  Returns true if node is visited + +
                  DddmpSetVisitedAdd() +
                  Marks a node as visited + +
                  DddmpClearVisitedAdd() +
                  Marks a node as not visited + +
                  NumberNodeRecurAdd() +
                  Number nodes recursively in post-order + +
                  RemoveFromUniqueRecurAdd() +
                  Removes a node from unique table + +
                  RestoreInUniqueRecurAdd() +
                  Restores a node in unique table + +
                  +
                  +

                  dddmpNodeBdd.c

                  +Functions to handle BDD node infos and numbering

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Functions to handle BDD node infos and numbering.

                  +

                  +
                  DddmpNumberBddNodes() +
                  Removes nodes from unique table and number them + +
                  DddmpUnnumberBddNodes() +
                  Restores nodes in unique table, loosing numbering + +
                  DddmpWriteNodeIndexBdd() +
                  Write index to node + +
                  DddmpReadNodeIndexBdd() +
                  Reads the index of a node + +
                  DddmpVisitedBdd() +
                  Returns true if node is visited + +
                  DddmpSetVisitedBdd() +
                  Marks a node as visited + +
                  DddmpClearVisitedBdd() +
                  Marks a node as not visited + +
                  NumberNodeRecurBdd() +
                  Number nodes recursively in post-order + +
                  RemoveFromUniqueRecurBdd() +
                  Removes a node from unique table + +
                  RestoreInUniqueRecurBdd() +
                  Restores a node in unique table + +
                  +
                  +

                  dddmpNodeCnf.c

                  +Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs.

                  +

                  +
                  DddmpNumberDdNodesCnf() +
                  Removes nodes from unique table and numbers them + +
                  DddmpDdNodesCountEdgesAndNumber() +
                  Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. + +
                  DddmpUnnumberDdNodesCnf() +
                  Restores nodes in unique table, loosing numbering + +
                  DddmpPrintBddAndNext() +
                  Prints debug information + +
                  DddmpWriteNodeIndexCnf() +
                  Write index to node + +
                  DddmpVisitedCnf() +
                  Returns true if node is visited + +
                  DddmpSetVisitedCnf() +
                  Marks a node as visited + +
                  DddmpReadNodeIndexCnf() +
                  Reads the index of a node + +
                  DddmpWriteNodeIndexCnfWithTerminalCheck() +
                  Write index to node + +
                  DddmpClearVisitedCnfRecur() +
                  Mark ALL nodes as not visited + +
                  DddmpClearVisitedCnf() +
                  Marks a node as not visited + +
                  NumberNodeRecurCnf() +
                  Number nodes recursively in post-order + +
                  DddmpDdNodesCheckIncomingAndScanPath() +
                  Number nodes recursively in post-order + +
                  DddmpDdNodesNumberEdgesRecur() +
                  Number nodes recursively in post-order + +
                  DddmpDdNodesResetCountRecur() +
                  Resets counter and visited flag for ALL nodes of a BDD + +
                  DddmpDdNodesCountEdgesRecur() +
                  Counts the number of incoming edges for each node of a BDD + +
                  RemoveFromUniqueRecurCnf() +
                  Removes a node from unique table + +
                  RestoreInUniqueRecurCnf() +
                  Restores a node in unique table + +
                  DddmpPrintBddAndNextRecur() +
                  Prints debug info + +
                  +
                  +

                  dddmpStoreAdd.c

                  +Functions to write ADDs to file.

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Functions to write ADDs to file. + ADDs are represended on file either in text or binary format under the + following rules. A file contains a forest of ADDs (a vector of + Boolean functions). ADD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to ADD + functions, followed by the list of nodes. + ADD nodes are listed according to their numbering, and in the present + implementation numbering follows a post-order strategy, in such a way + that a node is never listed before its Then/Else children.

                  +

                  +
                  Dddmp_cuddAddStore() +
                  Writes a dump file representing the argument ADD. + +
                  Dddmp_cuddAddArrayStore() +
                  Writes a dump file representing the argument Array of ADDs. + +
                  DddmpCuddDdArrayStoreBdd() +
                  Writes a dump file representing the argument Array of + BDDs/ADDs. + +
                  NodeStoreRecurAdd() +
                  Performs the recursive step of Dddmp_bddStore. + +
                  NodeTextStoreAdd() +
                  Store One Single Node in Text Format. + +
                  +
                  +

                  dddmpStoreBdd.c

                  +Functions to write BDDs to file.

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Functions to write BDDs to file. + BDDs are represended on file either in text or binary format under the + following rules. A file contains a forest of BDDs (a vector of + Boolean functions). BDD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to BDD + functions, followed by the list of nodes. BDD nodes are listed + according to their numbering, and in the present implementation + numbering follows a post-order strategy, in such a way that a node + is never listed before its Then/Else children.

                  +

                  +
                  Dddmp_cuddBddStore() +
                  Writes a dump file representing the argument BDD. + +
                  Dddmp_cuddBddArrayStore() +
                  Writes a dump file representing the argument Array of BDDs. + +
                  DddmpCuddBddArrayStore() +
                  Writes a dump file representing the argument Array of + BDDs. + +
                  NodeStoreRecurBdd() +
                  Performs the recursive step of Dddmp_bddStore. + +
                  NodeTextStoreBdd() +
                  Store One Single Node in Text Format. + +
                  NodeBinaryStoreBdd() +
                  Store One Single Node in Binary Format. + +
                  +
                  +

                  dddmpStoreCnf.c

                  +Functions to write out BDDs to file in a CNF format

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Functions to write out BDDs to file in a CNF format.

                  +

                  +
                  Dddmp_cuddBddStoreCnf() +
                  Writes a dump file representing the argument BDD in + a CNF format. + +
                  Dddmp_cuddBddArrayStoreCnf() +
                  Writes a dump file representing the argument array of BDDs + in CNF format. + +
                  DddmpCuddBddArrayStoreCnf() +
                  Writes a dump file representing the argument Array of + BDDs in the CNF standard format. + +
                  StoreCnfNodeByNode() +
                  Store the BDD as CNF clauses. + +
                  StoreCnfNodeByNodeRecur() +
                  Performs the recursive step of Dddmp_bddStore. + +
                  StoreCnfOneNode() +
                  Store One Single BDD Node. + +
                  StoreCnfMaxtermByMaxterm() +
                  Prints a disjoint sum of products. + +
                  StoreCnfBest() +
                  Prints a disjoint sum of products with intermediate + cutting points. + +
                  StoreCnfMaxtermByMaxtermRecur() +
                  Performs the recursive step of Print Maxterm. + +
                  StoreCnfBestNotSharedRecur() +
                  Performs the recursive step of Print Best on Not Shared + sub-BDDs. + +
                  StoreCnfBestSharedRecur() +
                  Performs the recursive step of Print Best on Shared + sub-BDDs. + +
                  printCubeCnf() +
                  Print One Cube in CNF Format. + +
                  +
                  +

                  dddmpStoreMisc.c

                  +Functions to write out bdds to file in prefixed + and in Blif form.

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Functions to write out bdds to file. + BDDs are represended on file in text format. + Each node is stored as a multiplexer in a prefix notation format for + the prefix notation file or in PLA format for the blif file.

                  +

                  +
                  Dddmp_cuddBddStorePrefix() +
                  Writes a dump file representing the argument BDD in + a prefix notation. + +
                  Dddmp_cuddBddArrayStorePrefix() +
                  Writes a dump file representing the argument BDD in + a prefix notation. + +
                  Dddmp_cuddBddStoreBlif() +
                  Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
                  Dddmp_cuddBddArrayStoreBlif() +
                  Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
                  Dddmp_cuddBddStoreSmv() +
                  Writes a dump file representing the argument BDD in + a prefix notation. + +
                  Dddmp_cuddBddArrayStoreSmv() +
                  Writes a dump file representing the argument BDD in + a prefix notation. + +
                  DddmpCuddDdArrayStorePrefix() +
                  Internal function to writes a dump file representing the + argument BDD in a prefix notation. + +
                  DddmpCuddDdArrayStorePrefixBody() +
                  Internal function to writes a dump file representing the + argument BDD in a prefix notation. Writes the body of the file. + +
                  DddmpCuddDdArrayStorePrefixStep() +
                  Performs the recursive step of + DddmpCuddDdArrayStorePrefixBody. + +
                  DddmpCuddDdArrayStoreBlif() +
                  Writes a blif file representing the argument BDDs. + +
                  DddmpCuddDdArrayStoreBlifBody() +
                  Writes a blif body representing the argument BDDs. + +
                  DddmpCuddDdArrayStoreBlifStep() +
                  Performs the recursive step of DddmpCuddDdArrayStoreBlif. + +
                  DddmpCuddDdArrayStoreSmv() +
                  Internal function to writes a dump file representing the + argument BDD in a SMV notation. + +
                  DddmpCuddDdArrayStoreSmvBody() +
                  Internal function to writes a dump file representing the + argument BDD in a SMV notation. Writes the body of the file. + +
                  DddmpCuddDdArrayStoreSmvStep() +
                  Performs the recursive step of + DddmpCuddDdArrayStoreSmvBody. + +
                  +
                  +

                  dddmpUtil.c

                  +Util Functions for the dddmp package

                  +By: Gianpiero Cabodi and Stefano Quer

                  +Functions to manipulate arrays.

                  +

                  +
                  QsortStrcmp() +
                  String compare for qsort + +
                  FindVarname() +
                  Performs binary search of a name within a sorted array + +
                  DddmpStrDup() +
                  Duplicates a string + +
                  DddmpStrArrayDup() +
                  Duplicates an array of strings + +
                  DddmpStrArrayRead() +
                  Inputs an array of strings + +
                  DddmpStrArrayWrite() +
                  Outputs an array of strings + +
                  DddmpStrArrayFree() +
                  Frees an array of strings + +
                  DddmpIntArrayDup() +
                  Duplicates an array of ints + +
                  DddmpIntArrayRead() +
                  Inputs an array of ints + +
                  DddmpIntArrayWrite() +
                  Outputs an array of ints + +
                  +
                  +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDesc.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDesc.html new file mode 100644 index 000000000..a27b1847f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDesc.html @@ -0,0 +1,28 @@ + +The dddmp package: Overview + + +

                  The dddmp package

                  +

                  Functions to read in and write out BDDs, ADDs + and CNF formulas from and to files.

                  +

                  By Gianpiero Cabodi and Stefano Quer

                  + + + +
                  + + + +
                  + +Last updated on 1040218 17h14 + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDoc.txt b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpDoc.txt new file mode 100644 index 0000000000000000000000000000000000000000..5912f35f54c29c1caf93c15e3b802fc8e0e0aba1 GIT binary patch literal 32768 zcmeHQ|9f0TxnI3j_Bnc`T$)1fFAiUn05y%+N`z3;BrOS~CAI;AB4(4_G;24z%kHM6 z-d^t(Dy&!_Xw|5dE?P7|ivbD*sP=hg{;~V{yfd?3l5A#y`sfdxWY5l=_kBO}&dhse z&b()K&e%*!C6me7yvir0jwBAJqG;b-cB+)lWs9nmQ-xF_snS`M$R^cOg>)&Ua&sls zKR8(2uJ+)l7)TsAuuo0r3bS*WL{Uu_a#!Pr&EQT8c0m$l4)T-R7y=J zvN`p=xl|!iA;8E3Ql;s1CROZ0wtDeyrBYpLa3<0}N4hsz+O2vMYNn8yzVBu!)t*dd zFjeZBDa}TiTLxLqA5G0AlS3#~sxXpEByUz@dk)^eckI5K_eXn%58S-FcPf`m?OuQ|)L=Jw`B8;*wlpv|nHtDW zt3q^4B~vOjHCI5vcuZ##nSq(q)DeXS>AD>?g^<*LReef5B?*7%Voe;|9(Ce`)W-hQ zY_4!j?JJ~GYJXx1)lX#x2M445qx`}Vib>>0`}PcvJbZAkn$9E+cSTehZDng~HC^wtV9%iGdRPrzz12jspX{bo_zfj_L(4=>83{A2}4ISLOuenJg zv`OZchU&MqKk(4t-rb$I_wE>YC_=1v#~##ft%fYYokwesXpa=LF{OMwQc`tILaeSQ z@v%l3ZD5sPLIIOsAbP-4HOs~^qtm1)l6b;KAkL@XFi7#m<9coQbQ=p zv^tt7q!W{wlmbH}JloZzc{LVm;4;tXe}Hc)H=EBDQv##^F&q&N-v{n7Ct{7DPbshf zjB)78BKBu8swGO4Kh~tP$R4;yYBmC2HZe=Q z%ln2$9&2J04wcU_`)nyyAk$#-KrZYr69v-_#B?^T^gwHW{tc6r* zu8>V7rNIli9Qxpcd-vw;Sg^ZmM>03H!w+`**a6diaV-f0vrwv(&U8(wgcXr9axfRo zA2-F_+1@(Uj_Qt2FRQ+24-&WIGo#GkHg7|uIG0Zqic^JjzEng9Se%1c$SS z=JNT>T}r=ch0SmE`-KQ&l9kVAQnRUSDUm^Gb59i$7&6YIK9=>HUMGi;5(2Z=i|Wv{ z7e}2p%1?q^#pe`{3?d!nGrN?2LrD)f{`ix-ZUP0$*D{|?aJ-vMl+sg)Ob&%glyU`M z0ZxJFTcQCwQT>k6XNcYiQaF|`q@$yWQfjW4O5m0WWx=h0zQ8Z1NItVO;t7JNTOQ5@DH+#6ompF+af$QmN<+$I;=+7Pz-mPU+I_3 zYuChJVx&d(3oKG$WP!|NBKuTA=?l?M%%9BJ9-alaJ<9~ba29+hVz+)PVxPdEKhT$x z=EE<cD*ZPrVJ>dc@0rs~lt?GYvahhQRA%n*9J!Yr_c{G% z^GlkQDhVwD88+nUW2pjea}pV)-?sLv^jrGuPSzSOVj<;ut2_tW$)U<%8mz0gZG(-0 zZ)_%!$R^lmAW1N%%q!-?7h{01G-ay#olTMb5*7%h5$W&K?@Ah^U0*e?eZk74VXZ=E zx9Awg(vzuDBCERfMJu6S>4|#olz7R}l&6j0?wyvQ^n1{dSA+T86MDg1zLxczE@e_v ziDD{~Dxr+54U0ICwNflRjM1g))@7d8uj+G;k~o)56pK+YeVARAgyHPN+4OW8moaRN z_HQnm3;ImyX5=_0l;o83O|?Wek;J3{vxP$XFq@!wER(@Nn4S_VP|D&ZhsDZR2K|OP zdq7ts0~N*xRA)tSPdYN$EA&uMQB8O&McX?%^Tlk0^NZS{q-|47r{_iOK4AA zfKp3Ko4;)Scx@xMt)$3Tl{3QO>?0h?N@8b}RBF4eHW}h%W`+8ls&_Mw&ZJ9G>QEln z2rP}koG`E5Yfez?DG*ad%p6ioJ(l*Z=PW8wM8*G|GRM+j7|uSHK8VT_W8_)0R5ZWr zwe$iA=;R{QCr?=JL#SFsOOitV>{|1>E`JHMW9edq4=Wy{G6ZNqdO=@|qC2igh$1`5 z>Q86y8cWTWI^{|fz3gEimpz&)V6>CT-z4k+LkDiO_Z%7+9(JR$t=I;k)zNk4H(+U+ z;RG?(nE|by00l8tO^`&*Rg@OgU`iQdn&XP3d+V7$G&?hrfYL`yZhLqZt5H05sA&q>$umV_{zH^t9c*PXJ4FyL*mjkTe- zWo>&lo#{ksV`q%NPj3=yPHg0>@jY3nG_8F(e!>h_M{~AoQtP{V>~tE;c0wHjS(25+rKq_8Ht+z1FvL+CbYQKqhUODN z{}%lR%_3`3LH7c@3n7eFo?Ge4Fny)>A%qd~PFSZx%{38%Lpkfd1^NuudN7(j7a>6J zGg;5QvD&c_!fH~k?)X^G=@EkRYBjn=TKhyoXq=&l_eI<$0iQ_-tl6>B(y0=Hq1VM( zZ7a7+2m&5Xh7G+kE{j%QO-`FuOgtaF^#G5X2v`_;dTdOoJ&14soC%d^1Ba0H4g~>f z4w6-#qE&vP5YGCJB$lVyjTFLxK$DxPg_kJ=<7dt;^A=915Q_6~!9CU5M-{@bZn&Te zD+B`fRuP9boW(g%q(aw$}bJo4@yuh0p?CG|n{OQ4FCl&$SLVt4Ynp76NJE zg2VVBK2f5J*InSgsRgk_zJ?RgJvhAofnI2YkO3~AJ^?@{y^3-|Nl&fLf|Ngz5ULyB$W zwrp@(hG5|ET+gW)@M(rnLk`e3JA>8!(Dl8cA!Ro5m#*s~g@-hRS#zgu=uHiwh_{su zzOlbG1Ota`oBmklwLxg#T??aePf%LJiRXI*cdket4HZtjz+6YO*4yixy&(kTv#uxD zYTn=r4gvY+4~^bp3)0{)4uMdcwcg~luH+ET`p)L{9L?52Oy}@j@Dc|c#MUhg|FH8E zb1_n)|biyHcpNDL4vy35L>6+^Z}gqL+9hs82H?CrH(& zKvw3(j!+9LESiA0(&sEcj!Zzh2hysCYdK1ANJ&a)mt>8D@U=MTOAw#H6JuEkVovLq zY?AEeG-&gnnF^sZ_c0Yx66_*-e&=RP6d_yH=Qk;HUcYstq=mXmsZP+wISbWQF0cp$ zFj)~VKC#~|%hBghVx|~&?g~Q9gVikQ3!4;OWK1!PK%*h^>kg>%7Lt2yDhLMFBqS#& zIZsJ*-kjTF(}X<^qN$RK=j|XTu@XVjA!N@-5ZDW0Rsa)^bCPS8AHFee(=n3Ilf0xq z+KM>HJ7w_|)1h1_+$4Y#fI100r9Z}Jk>vb6E-Az_;VL#~sL+Cb5eRlxe!ou(#Km2k z> zQzTY{h>+H0nXs5YY@vX~Hs`**84W`HRhX!XAiK>_}Gi zE9hv<-?zrGCP^v$u0RsHqTk&FFGG(@lUU-NEkgIVsA#Bu>Y&YX@LQSFKSC@GK zLDLmh6goqUP{`>x=K%XdP~fgY3_f;bU6xfv)jcjvRJ}qfE*e}w?}6pqeK#T*L=_3j zn*|oJf;CK|lpoTsx}*@7?%oUz^8xB*AJ0D$0(NY~rIZAi16GfHuvHBbW64yvxU{Fj zM$w{|Kn;#kVp=tB43;8`wpZOC^&pqHISruWyv!vDk{SYSl(doiLj?eLvjB1^nDu7D;b zkYq@4CnXrmJ)7fLUHQkYN>>T8WM19kPLR$gfj9@U8b^w@s+Yp}bzTv5Kp5Q5Y>jt= zXv*lEY%&I74{}kW!_s&Nypb0|=gb>htSmDbrMi_IPLz?0zJ!TCk|9X&Gt5x9ibT(2 z09cgKz>#zrG+ba6Wbs%C4p86q+{D$36kalw4rMBU&g+kSTFA>FEAw+utB-~6mTR20 z{Uu2lQvnP*X>^$5-$(2eZrRvrBQ50WchIp^^gRrsFm-)X3D18 z5jW>2JJiIzV3DNIgLfmV*ddG_sv}M>4J>g9TH7?xI&qUWZ(it7$3eu}L8ZVuS7NcxN?cE})*-flSB^ z{sJ>;<7NSOKDa9#gd?q6T1t`xH%s^6_GeMnoK1cq85o70f()PMGA zfySD2==lI{CDCg?ZazdsmCc7C?b@Jp|T}eJM3HljX|idiEo;b{+NOKM3K7 z%%LNy9~~Ya1;0=SVQe@%@Z%!`xo;`_)}?2zuCwc2FF1C-2d*s-A!H zdrKQ_I95yrE8Z`e*ROA9FtkwRCp~5ZkmONMdu{c?OxyZ4Y3l$?btmrem*Fs;nNjKy zmZtn<2oWr>wM*vB>v6XZi3RiaweinU)@kX$)x5h4@#$cn;TT0zT#B}0y)=3yJPc5y z4zvwLy`=rduO8&jYxy6z!>87!!fU4?G-V&E43TS+Xh6ak#>rlJhduWRRc@uQUin62 z9;g;1eRZ{=ZzH=0%5P^y+{V^);Gam@)v9iCb^F;=T~EbEkFHa_Niu)etuL!R7c@U0s-mFK>=x zo>dF*-uwcI_SE)#JD*Yt_wQ=xaUA%uKW9P20xeKqf6avS^?a+piN;`-P4&9CjoafV z(%Hg#alL3>xehlA=InK_T~mc0)l|L!3#P`sX5~8Ro@(Wxa7cd(?X~wA&FkO#sQvzg zN_*iU-eSV6euG|&kPYf~ucK}|%6e5l`*$d}&z{3-gsVB$FRayd^Xb!9YxQcaemd*9 zYB^Ue=c?tjs)4Il$JMK&m2GT%{;K6%wVaJDq!snbS&o{-E+Yv2>16sKzDCXY_FPiO z^vk>9JgrHp;}0_hC+Wa6*D|Z)Atk}9Pds>FqEU!zHC#HE#f}(Z4D*5hSidYQ#E>(E z;DY+n_3`UsqDmow9pBWTMK!-RFXha;5xi624PrO53ljGeVHg}pXVay0!lrB`gz%(_ zNA{`=yuJ*k{Gc+wz6LQ*QI3Li2#n1&@(`W_-Ak`7r?r>*zHto-X0aZ^896WML&)Os z5MnYdY)%Z@p`0^s>pyRbS@l4J#+O;Iu^97s^bkC?Jh2TY%!m5f-kZMYcpp6!%4=h3 z*ah}IaaqAteFUY#qtVM$0h^pap;3H7c^m=HS}BX6)NSUBxd?-=HDw46jqUx^X#8R> zgPla2#j7qXVfh&WJS7B%ErIZ$f?;rA7Q3PV+BLm?8eRan+iH{$lvfH!SoDSsn>^Cc zjJ`yi8X<%v%$7gbUq~gq1>N1I;NU=UHi1n`CTdnuF(;1ecdm(12TQA&5KcTfhb@`p z1WjoBf15ui^J{thKQ$s1;HrvQpPg)Mkg|GY;_nu~|$ zzbIfr;qxe$(O~*;P(Sdb(c^MIp69lR|L&2m-^S$~$jXv%F;|$x){fXa&Bj_D!NRS9 z`e(e%txw!#{=mw26p=I^!bPuF4&YH|2#`F$!z1Euy#!$n1Tw^!_qWB-lgNn~EC4Vs z#c)^%FRdUGJ1G5{efV_;K!$J;j^GZ|wRzkUYie6R*>Q}g;{8)!}vj#9Z6Y_e1T%p;;|%eF7ApJ@@pTDb z*lI$`e9#f!ENzEV6Zyx=QLp%j zE{yWZc44BO$I|GGpY{T%?vy>I&epq~M{e)}SlsdB zdO}w*GWnnv!_x=PYsw9lV-^|{i^2PRg80Eu0QK^u2L@$nqMk4d!8Hnv+|`MC*~|(? zRP!OQ#xdrgZTkzi1qZP0lJ&SQmKxlQg4W57xRcQp#M6@O*WVawQLG zlcX}>(P-K?>{$!SAIbKZr?FD^oVj4{9H?&y z%L;dP;oGeplC_`uJQc!f^Xua_&6{I$Za>#iBK!6{kabq(BB`3*k|R$uungwZ%^_XE zV)i=6pQt zNW$KPQT=<@kRC&(((JFTzWqFp0TP|K59n-9Y>9{On<;2ny`=AUneJ;$m`bpl70;Xn zGRp@y$2}&yOdtA!-J<0*Rdjq_2wI|BsD;Kv9}*!mQDmw~Pc$Yl8EPP5opc*$H6(03 zj`*$k=w-%yfQtePim}nVKhgSohKo)y#B<;NTDS?ZKJ$+)@x!o zDE=M-Bo7J(?md)P;MH{-Vx9OfX!?pxIVQB*H;JT0TGsIPpBVSv0TKn@bih-VMHB|13X&qf*K|yG=cY@9#6d zoV+1!Z)~1Hasqu=H@?3aD)u+QB))_@@x2|NPDFegndJ$9K994qdeD?nyTRU%Jdj|6 zWAcis_o=-8W!+(hb?g{T?g*)8J!#|S#cj2E8#kA?#q|qt80!~t80V({QdDHvhhMFX z<2(FIl^Q3w<@Y~*h|rXj`PDY1&my9$ILx5A+N#96D6vFgcA*3Kpn+e*IoLeLaY>`q z`ViR@E;TLsgL>8JMS#{@7rwK1l;Rx)t{PmR=It%24X@7uFypZhkWOHJhi_`hZmL6C zi=!NzOmFcwiJu4T%i%5`JdjzI--JS%VTMhPW{}YhtqdFWtz(vtZi_zS(Z_yFuY6Vr3vI_rUW!^DoH^rQ!oU;en!ymO01Y^BP zFfZZB-1F9z?4&(OJ(?>dkqDyI!Cv?}cC34e08X}sHEth51hKrpqxu&&o7cY>qaVaS zzCZ);c>{+%{9Nn$el*anW-;h(Ymdukj0T2X-Gn5vQS-d8UC?Djb_A=ISJ@2u1YRnb z)~eAR_In@V<2-?2{`A!t?qKf^fq}&e@M2bZjt4I2GPe-GMIrm4dyWQ@}lxZ+8<10VEwNPQuMC`@2y7-C26f~oBCQ512}Twb-k3HOik zd+k`pwfhl$ioKA~wN^W7t%^DB-z_-Jk(-I|{wFx_%RrxRd^$8PKP9(NZ49H1QG{rJ zG&}iu`~!$^G#C$6D|l=$3kk?R6T{(T@QEIOpUPPUTUJ-l%(W4xBClexknJ4xB0DY@ z^hzFA2NJv5P+NZINW1~oa^*6VdXXS582LFj z&2t!^Huj*kZ2a}J?=c7$jn1$gmmC`gjq$5(aYQ6^&-fU+{{A+e4%g-mvR#3{ z#)dfgHy>esXm4W7tN5Mi3xL)yhN`K775w+&V}AE}%t+Shw)`egR^_$b)@Rv9O$HGQ zy#5it?{P1+;dX=AXRT?AHIccJn^QGy_x0KLSrcWOy8VBevY&c?HPO*;t@h8Y(9gDi znkeeGPW!i4wCSq3!mZA$hW*j)GDnrFu(KBzm9M6K^y;s(X|P6nDRVo{8F_gx-;CI5 z*UnIX@<}%J@w5X(@siajSy}LbG zB}(JQpkEy55995g*nA$ZW!|u&Jkh?|yXnQ$eAQBW!hA!x>K#R$VQ)!PJp z3>>B8)oooCh3^Y*PdMRTDlTt9#fz-5{WrJnY)`np!KdgBrMcFjpVI3aH(zpI3ysF@ zUOv~pZP!qGBhEY9d8u6&T!b9k?bf8}qRL=ChRWs($M`97J7Ly2Han)#m9Rl^ikAy7 zOZ24h!Eo{A-sx$)Ww3aUI*`lSEAb{NxOw+lZUKWMJbdpq`24x?lM8l=4Byg4@Y-Y9 zRKDCtGTv~xlPzB<^s;k5i|Pt8nZ(6yRb+2EeM{9 z0;La|g7uM#tyA=KAj`L7$JCsvD<169Cd_{%$YUDw7H9}8>W*Z(c;w+C%U(8Vq#C5JT z-Gd`eGQ#}(SbH%<;JZYLK`%00_`rk1zDk~%j3E;64pcd2Gh4Ba@X b|H3R}$q;wm<>{I!fLyZ%TR+|Ay=(s;!vX;I literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExt.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExt.html new file mode 100644 index 000000000..fe026ec6f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExt.html @@ -0,0 +1,13 @@ + +The dddmp Package for Programmers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtAbs.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtAbs.html new file mode 100644 index 000000000..612554f58 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtAbs.html @@ -0,0 +1,91 @@ + +dddmp package abstract + + + + + +
                  +
                  Dddmp_Bin2Text() +
                  Converts from binary to ASCII format + +
                  Dddmp_Text2Bin() +
                  Converts from ASCII to binary format + +
                  Dddmp_cuddAddArrayLoad() +
                  Reads a dump file representing the argument ADDs. + +
                  Dddmp_cuddAddArrayStore() +
                  Writes a dump file representing the argument Array of ADDs. + +
                  Dddmp_cuddAddLoad() +
                  Reads a dump file representing the argument ADD. + +
                  Dddmp_cuddAddStore() +
                  Writes a dump file representing the argument ADD. + +
                  Dddmp_cuddBddArrayLoadCnf() +
                  Reads a dump file in a CNF format. + +
                  Dddmp_cuddBddArrayLoad() +
                  Reads a dump file representing the argument BDDs. + +
                  Dddmp_cuddBddArrayStoreBlif() +
                  Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
                  Dddmp_cuddBddArrayStoreCnf() +
                  Writes a dump file representing the argument array of BDDs + in CNF format. + +
                  Dddmp_cuddBddArrayStorePrefix() +
                  Writes a dump file representing the argument BDD in + a prefix notation. + +
                  Dddmp_cuddBddArrayStoreSmv() +
                  Writes a dump file representing the argument BDD in + a prefix notation. + +
                  Dddmp_cuddBddArrayStore() +
                  Writes a dump file representing the argument Array of BDDs. + +
                  Dddmp_cuddBddDisplayBinary() +
                  Display a binary dump file in a text file + +
                  Dddmp_cuddBddLoadCnf() +
                  Reads a dump file in a CNF format. + +
                  Dddmp_cuddBddLoad() +
                  Reads a dump file representing the argument BDD. + +
                  Dddmp_cuddBddStoreBlif() +
                  Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
                  Dddmp_cuddBddStoreCnf() +
                  Writes a dump file representing the argument BDD in + a CNF format. + +
                  Dddmp_cuddBddStorePrefix() +
                  Writes a dump file representing the argument BDD in + a prefix notation. + +
                  Dddmp_cuddBddStoreSmv() +
                  Writes a dump file representing the argument BDD in + a prefix notation. + +
                  Dddmp_cuddBddStore() +
                  Writes a dump file representing the argument BDD. + +
                  Dddmp_cuddHeaderLoadCnf() +
                  Reads the header of a dump file representing the argument BDDs + +
                  Dddmp_cuddHeaderLoad() +
                  Reads the header of a dump file representing the argument BDDs + +
                  + +
                  + +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtDet.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtDet.html new file mode 100644 index 000000000..38fb590a4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpExtDet.html @@ -0,0 +1,693 @@ + +The dddmp package + + +
                  +
                  +
                  +int 
                  +Dddmp_Bin2Text(
                  +  char * filein, IN: name of binary file
                  +  char * fileout IN: name of ASCII file
                  +)
                  +
                  +
                  Converts from binary to ASCII format. A BDD array is loaded and + and stored to the target file. +

                  + +

                  Side Effects None +

                  + +

                  See Also Dddmp_Text2Bin() + + +
                  +
                  +int 
                  +Dddmp_Text2Bin(
                  +  char * filein, IN: name of ASCII file
                  +  char * fileout IN: name of binary file
                  +)
                  +
                  +
                  Converts from ASCII to binary format. A BDD array is loaded and + and stored to the target file. +

                  + +

                  Side Effects None +

                  + +

                  See Also Dddmp_Bin2Text() + + +
                  +
                  +int 
                  +Dddmp_cuddAddArrayLoad(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
                  +  char ** rootmatchnames, IN: sorted names for loaded roots
                  +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names, by ids
                  +  int * varmatchauxids, IN: array of variable auxids, by ids
                  +  int * varcomposeids, IN: array of new ids, by ids
                  +  int  mode, IN: requested input file format
                  +  char * file, IN: file name
                  +  FILE * fp, IN: file pointer
                  +  DdNode *** pproots OUT: array of returned BDD roots
                  +)
                  +
                  +
                  Reads a dump file representing the argument ADDs. See + BDD load functions for detailed explanation. +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddBddArrayStore + + +
                  +
                  +int 
                  +Dddmp_cuddAddArrayStore(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  char * ddname, IN: DD name (or NULL)
                  +  int  nRoots, IN: number of output BDD roots to be stored
                  +  DdNode ** f, IN: array of ADD roots to be stored
                  +  char ** rootnames, IN: array of root names (or NULL)
                  +  char ** varnames, IN: array of variable names (or NULL)
                  +  int * auxids, IN: array of converted var IDs
                  +  int  mode, IN: storing mode selector
                  +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument array of ADDs to file. Dumping is + either in text or binary form. see the corresponding BDD dump + function for further details. +

                  + +

                  Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

                  + +

                  See Also Dddmp_cuddAddStore +Dddmp_cuddAddLoad +Dddmp_cuddAddArrayLoad + + +
                  +
                  +DdNode * 
                  +Dddmp_cuddAddLoad(
                  +  DdManager * ddMgr, IN: Manager
                  +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names by IDs
                  +  int * varmatchauxids, IN: array of variable auxids by IDs
                  +  int * varcomposeids, IN: array of new ids by IDs
                  +  int  mode, IN: requested input file format
                  +  char * file, IN: file name
                  +  FILE * fp IN: file pointer
                  +)
                  +
                  +
                  Reads a dump file representing the argument ADD. + Dddmp_cuddAddArrayLoad is used through a dummy array. +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddAddStore +Dddmp_cuddAddArrayLoad + + +
                  +
                  +int 
                  +Dddmp_cuddAddStore(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  char * ddname, IN: DD name (or NULL)
                  +  DdNode * f, IN: ADD root to be stored
                  +  char ** varnames, IN: array of variable names (or NULL)
                  +  int * auxids, IN: array of converted var ids
                  +  int  mode, IN: storing mode selector
                  +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument ADD to file. Dumping is done through + Dddmp_cuddAddArrayStore, And a dummy array of 1 ADD root is + used for this purpose. +

                  + +

                  Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

                  + +

                  See Also Dddmp_cuddAddLoad +Dddmp_cuddAddArrayLoad + + +
                  +
                  +int 
                  +Dddmp_cuddBddArrayLoadCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  Dddmp_RootMatchType  rootmatchmode, IN: storing mode selector
                  +  char ** rootmatchnames, IN: sorted names for loaded roots
                  +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names, by IDs
                  +  int * varmatchauxids, IN: array of variable auxids, by IDs
                  +  int * varcomposeids, IN: array of new ids, by IDs
                  +  int  mode, IN: computation Mode
                  +  char * file, IN: file name
                  +  FILE * fp, IN: file pointer
                  +  DdNode *** rootsPtrPtr, OUT: array of returned BDD roots
                  +  int * nRoots OUT: number of BDDs returned
                  +)
                  +
                  +
                  Reads a dump file representing the argument BDD in a + CNF formula. +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddBddArrayLoad + + +
                  +
                  +int 
                  +Dddmp_cuddBddArrayLoad(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
                  +  char ** rootmatchnames, IN: sorted names for loaded roots
                  +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names, by ids
                  +  int * varmatchauxids, IN: array of variable auxids, by ids
                  +  int * varcomposeids, IN: array of new ids, by ids
                  +  int  mode, IN: requested input file format
                  +  char * file, IN: file name
                  +  FILE * fp, IN: file pointer
                  +  DdNode *** pproots OUT: array of returned BDD roots
                  +)
                  +
                  +
                  Reads a dump file representing the argument BDDs. The header is + common to both text and binary mode. The node list is either + in text or binary format. A dynamic vector of DD pointers + is allocated to support conversion from DD indexes to pointers. + Several criteria are supported for variable match between file + and dd manager. Several changes/permutations/compositions are allowed + for variables while loading DDs. Variable of the dd manager are allowed + to match with variables on file on ids, permids, varnames, + varauxids; also direct composition between ids and + composeids is supported. More in detail: +
                    +
                  1. varMatchMode=DDDMP_VAR_MATCHIDS

                    + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

                  2. varMatchMode=DDDMP_VAR_MATCHPERMIDS

                    + is used to allow variable match according to the position in the + ordering. + +

                  3. varMatchMode=DDDMP_VAR_MATCHNAMES

                    + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

                  4. varMatchMode=DDDMP_VAR_MATCHIDS

                    + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

                  5. varMatchMode=DDDMP_VAR_COMPOSEIDS

                    + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. +

                  + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. + + All the loaded BDDs are referenced before returning them. +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddBddArrayStore + + +
                  +
                  +int 
                  +Dddmp_cuddBddArrayStoreBlif(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  int  nroots, IN: number of output BDD roots to be stored
                  +  DdNode ** f, IN: array of BDD roots to be stored
                  +  char ** inputNames, IN: array of variable names (or NULL)
                  +  char ** outputNames, IN: array of root names (or NULL)
                  +  char * modelName, IN: Model Name
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBLif. + A dummy array of 1 BDD root is used for this purpose. +

                  + +

                  See Also Dddmp_cuddBddArrayStorePrefix + + +
                  +
                  +int 
                  +Dddmp_cuddBddArrayStoreCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode ** f, IN: array of BDD roots to be stored
                  +  int  rootN, IN: # output BDD roots to be stored
                  +  Dddmp_DecompCnfStoreType  mode, IN: format selection
                  +  int  noHeader, IN: do not store header iff 1
                  +  char ** varNames, IN: array of variable names (or NULL)
                  +  int * bddIds, IN: array of converted var IDs
                  +  int * bddAuxIds, IN: array of BDD node Auxiliary Ids
                  +  int * cnfIds, IN: array of converted var IDs
                  +  int  idInitial, IN: starting id for cutting variables
                  +  int  edgeInTh, IN: Max # Incoming Edges
                  +  int  pathLengthTh, IN: Max Path Length
                  +  char * fname, IN: file name
                  +  FILE * fp, IN: pointer to the store file
                  +  int * clauseNPtr, OUT: number of clause stored
                  +  int * varNewNPtr OUT: number of new variable created
                  +)
                  +
                  +
                  Dumps the argument array of BDDs to file. +

                  + +

                  Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + Three methods are allowed: + * NodeByNode method: Insert a cut-point for each BDD node (but the + terminal nodes) + * MaxtermByMaxterm method: Insert no cut-points, i.e. the off-set of + trhe function is stored + * Best method: Tradeoff between the previous two methods. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. + The stored file can contain a file header or not depending on the + noHeader parameter (IFF 0, usual setting, the header is usually stored. + This option can be useful in storing multiple BDDs, as separate BDDs, + on the same file leaving the opening of the file to the caller. +

                  + +

                  +
                  +int 
                  +Dddmp_cuddBddArrayStorePrefix(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  int  nroots, IN: number of output BDD roots to be stored
                  +  DdNode ** f, IN: array of BDD roots to be stored
                  +  char ** inputNames, IN: array of variable names (or NULL)
                  +  char ** outputNames, IN: array of root names (or NULL)
                  +  char * modelName, IN: Model Name
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                  + +

                  See Also Dddmp_cuddBddArrayStore + + +
                  +
                  +int 
                  +Dddmp_cuddBddArrayStoreSmv(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  int  nroots, IN: number of output BDD roots to be stored
                  +  DdNode ** f, IN: array of BDD roots to be stored
                  +  char ** inputNames, IN: array of variable names (or NULL)
                  +  char ** outputNames, IN: array of root names (or NULL)
                  +  char * modelName, IN: Model Name
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                  + +

                  See Also Dddmp_cuddBddArrayStore + + +
                  +
                  +int 
                  +Dddmp_cuddBddArrayStore(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  char * ddname, IN: dd name (or NULL)
                  +  int  nRoots, IN: number of output BDD roots to be stored
                  +  DdNode ** f, IN: array of BDD roots to be stored
                  +  char ** rootnames, IN: array of root names (or NULL)
                  +  char ** varnames, IN: array of variable names (or NULL)
                  +  int * auxids, IN: array of converted var IDs
                  +  int  mode, IN: storing mode selector
                  +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument array of BDDs to file. Dumping is either + in text or binary form. BDDs are stored to the fp (already + open) file if not NULL. Otherwise the file whose name is + fname is opened in write mode. The header has the same format + for both textual and binary dump. Names are allowed for input + variables (vnames) and for represented functions (rnames). + For sake of generality and because of dynamic variable + ordering both variable IDs and permuted IDs are included. + New IDs are also supported (auxids). Variables are identified + with incremental numbers. according with their positiom in + the support set. In text mode, an extra info may be added, + chosen among the following options: name, ID, PermID, or an + auxiliary id. Since conversion from DD pointers to integers + is required, DD nodes are temporarily removed from the unique + hash table. This allows the use of the next field to store + node IDs. +

                  + +

                  Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

                  + +

                  See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                  +
                  +int 
                  +Dddmp_cuddBddDisplayBinary(
                  +  char * fileIn, IN: name of binary file
                  +  char * fileOut IN: name of text file
                  +)
                  +
                  +
                  Display a binary dump file in a text file +

                  + +

                  Side Effects None +

                  + +

                  See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad + + +
                  +
                  +int 
                  +Dddmp_cuddBddLoadCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names, by IDs
                  +  int * varmatchauxids, IN: array of variable auxids, by IDs
                  +  int * varcomposeids, IN: array of new ids accessed, by IDs
                  +  int  mode, IN: computation mode
                  +  char * file, IN: file name
                  +  FILE * fp, IN: file pointer
                  +  DdNode *** rootsPtrPtr, OUT: array of returned BDD roots
                  +  int * nRoots OUT: number of BDDs returned
                  +)
                  +
                  +
                  Reads a dump file representing the argument BDD in a + CNF formula. + Dddmp_cuddBddArrayLoadCnf is used through a dummy array. + The results is returned in different formats depending on the + mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                  +
                  +DdNode * 
                  +Dddmp_cuddBddLoad(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                  +  char ** varmatchnames, IN: array of variable names - by IDs
                  +  int * varmatchauxids, IN: array of variable auxids - by IDs
                  +  int * varcomposeids, IN: array of new ids accessed - by IDs
                  +  int  mode, IN: requested input file format
                  +  char * file, IN: file name
                  +  FILE * fp IN: file pointer
                  +)
                  +
                  +
                  Reads a dump file representing the argument BDD. + Dddmp_cuddBddArrayLoad is used through a dummy array (see this + function's description for more details). + Mode, the requested input file format, is checked against + the file format. + The loaded BDDs is referenced before returning it. +

                  + +

                  Side Effects A vector of pointers to DD nodes is allocated and freed. +

                  + +

                  See Also Dddmp_cuddBddStore +Dddmp_cuddBddArrayLoad + + +
                  +
                  +int 
                  +Dddmp_cuddBddStoreBlif(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  int  nRoots, IN: Number of BDD roots
                  +  DdNode * f, IN: BDD root to be stored
                  +  char ** inputNames, IN: Array of variable names
                  +  char ** outputNames, IN: Array of root names
                  +  char * modelName, IN: Model Name
                  +  char * fileName, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBlif. + A dummy array of 1 BDD root is used for this purpose. +

                  + +

                  See Also Dddmp_cuddBddStorePrefix + + +
                  +
                  +int 
                  +Dddmp_cuddBddStoreCnf(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  DdNode * f, IN: BDD root to be stored
                  +  Dddmp_DecompCnfStoreType  mode, IN: format selection
                  +  int  noHeader, IN: do not store header iff 1
                  +  char ** varNames, IN: array of variable names (or NULL)
                  +  int * bddIds, IN: array of var ids
                  +  int * bddAuxIds, IN: array of BDD node Auxiliary Ids
                  +  int * cnfIds, IN: array of CNF var ids
                  +  int  idInitial, IN: starting id for cutting variables
                  +  int  edgeInTh, IN: Max # Incoming Edges
                  +  int  pathLengthTh, IN: Max Path Length
                  +  char * fname, IN: file name
                  +  FILE * fp, IN: pointer to the store file
                  +  int * clauseNPtr, OUT: number of clause stored
                  +  int * varNewNPtr OUT: number of new variable created
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + This task is performed by calling the function + Dddmp_cuddBddArrayStoreCnf. +

                  + +

                  Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

                  + +

                  See Also Dddmp_cuddBddArrayStoreCnf + + +
                  +
                  +int 
                  +Dddmp_cuddBddStorePrefix(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  int  nRoots, IN: Number of BDD roots
                  +  DdNode * f, IN: BDD root to be stored
                  +  char ** inputNames, IN: Array of variable names
                  +  char ** outputNames, IN: Array of root names
                  +  char * modelName, IN: Model Name
                  +  char * fileName, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                  + +

                  See Also Dddmp_cuddBddStore + + +
                  +
                  +int 
                  +Dddmp_cuddBddStoreSmv(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  int  nRoots, IN: Number of BDD roots
                  +  DdNode * f, IN: BDD root to be stored
                  +  char ** inputNames, IN: Array of variable names
                  +  char ** outputNames, IN: Array of root names
                  +  char * modelName, IN: Model Name
                  +  char * fileName, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                  + +

                  See Also Dddmp_cuddBddStore + + +
                  +
                  +int 
                  +Dddmp_cuddBddStore(
                  +  DdManager * ddMgr, IN: DD Manager
                  +  char * ddname, IN: DD name (or NULL)
                  +  DdNode * f, IN: BDD root to be stored
                  +  char ** varnames, IN: array of variable names (or NULL)
                  +  int * auxids, IN: array of converted var ids
                  +  int  mode, IN: storing mode selector
                  +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                  +  char * fname, IN: File name
                  +  FILE * fp IN: File pointer to the store file
                  +)
                  +
                  +
                  Dumps the argument BDD to file. Dumping is done through + Dddmp_cuddBddArrayStore. A dummy array of 1 BDD root is + used for this purpose. +

                  + +

                  Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

                  + +

                  See Also Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                  +
                  +int 
                  +Dddmp_cuddHeaderLoadCnf(
                  +  int * nVars, OUT: number of DD variables
                  +  int * nsuppvars, OUT: number of support variables
                  +  char *** suppVarNames, OUT: array of support variable names
                  +  char *** orderedVarNames, OUT: array of variable names
                  +  int ** varIds, OUT: array of variable ids
                  +  int ** varComposeIds, OUT: array of permids ids
                  +  int ** varAuxIds, OUT: array of variable aux ids
                  +  int * nRoots, OUT: number of root in the file
                  +  char * file, IN: file name
                  +  FILE * fp IN: file pointer
                  +)
                  +
                  +
                  Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. +

                  + +

                  See Also Dddmp_cuddBddArrayLoad + + +
                  +
                  +int 
                  +Dddmp_cuddHeaderLoad(
                  +  Dddmp_DecompType * ddType, OUT: selects the proper decomp type
                  +  int * nVars, OUT: number of DD variables
                  +  int * nsuppvars, OUT: number of support variables
                  +  char *** suppVarNames, OUT: array of support variable names
                  +  char *** orderedVarNames, OUT: array of variable names
                  +  int ** varIds, OUT: array of variable ids
                  +  int ** varComposeIds, OUT: array of permids ids
                  +  int ** varAuxIds, OUT: array of variable aux ids
                  +  int * nRoots, OUT: number of root in the file
                  +  char * file, IN: file name
                  +  FILE * fp IN: file pointer
                  +)
                  +
                  +
                  Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. +

                  + +

                  See Also Dddmp_cuddBddArrayLoad + + + +
                  +
                  +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpTitle.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpTitle.html new file mode 100644 index 000000000..25a369433 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/dddmpTitle.html @@ -0,0 +1,17 @@ + +The dddmp package: Title + + + + + + + + +
                  + Programmer view + Maintainer by function + Maintainer by file
                  + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/packages.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/packages.html new file mode 100644 index 000000000..27e4ace19 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/packages.html @@ -0,0 +1,12 @@ + +Package Documentation + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/doc/pkgIndex.html b/resources/3rdparty/cudd-2.5.0/dddmp/doc/pkgIndex.html new file mode 100644 index 000000000..f2efd6bc8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/doc/pkgIndex.html @@ -0,0 +1,13 @@ + +Package Documentation + +

                  Package Documentation


                  + + + + +
                  dddmpFunctions to read in and write out BDDs, ADDs +
                  +
                  +Last updated on 1040218 17h15 + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/0.add b/resources/3rdparty/cudd-2.5.0/dddmp/exp/0.add new file mode 100644 index 000000000..ba6bb3dcf --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/0.add @@ -0,0 +1,21 @@ +.ver DDDMP-2.0 +.add +.mode A +.varinfo 0 +.nnodes 5 +.nvars 3 +.nsuppvars 2 +.suppvarnames DUMMY1 DUMMY2 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 +.ids 1 2 +.permids 1 2 +.auxids 1 2 +.nroots 1 +.rootids 5 +.nodes +1 T 1 0 0 +2 T 2 0 0 +3 T 0 0 0 +4 2 1 2 3 +5 1 0 1 4 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/0.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/0.bdd new file mode 100644 index 000000000..5092978ef --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/0.bdd @@ -0,0 +1,19 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 5 +.nvars 50 +.nsuppvars 3 +.suppvarnames DUMMY1 DUMMY2 DUMMY3 +.ids 1 2 3 +.permids 1 2 3 +.auxids 1 2 3 +.nroots 1 +.rootids -5 +.nodes +1 T 1 0 0 +2 3 2 1 -1 +3 2 1 1 2 +4 2 1 1 -2 +5 1 0 3 4 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/0or1.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/0or1.bdd new file mode 100644 index 000000000..4fda5f20f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/0or1.bdd @@ -0,0 +1,119 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 104 +.nvars 50 +.nsuppvars 16 +.suppvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY6 DUMMY7 DUMMY8 DUMMY9 DUMMY10 DUMMY11 DUMMY12 DUMMY13 DUMMY14 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 +.ids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -104 +.nodes +1 T 1 0 0 +2 22 15 1 -1 +3 21 14 1 -2 +4 20 13 1 3 +5 19 12 1 4 +6 20 13 3 1 +7 21 14 1 2 +8 20 13 1 7 +9 19 12 6 8 +10 18 11 5 9 +11 17 10 1 10 +12 18 11 1 9 +13 17 10 1 12 +14 16 9 11 13 +15 20 13 7 -1 +16 21 14 2 -1 +17 20 13 16 -3 +18 19 12 15 -17 +19 21 14 2 1 +20 20 13 19 7 +21 19 12 6 20 +22 18 11 18 21 +23 17 10 1 22 +24 16 9 23 13 +25 18 11 18 9 +26 17 10 1 25 +27 16 9 26 13 +28 15 8 24 27 +29 12 7 28 27 +30 11 6 28 29 +31 11 6 28 27 +32 10 5 30 31 +33 4 4 14 32 +34 3 3 33 -1 +35 2 2 33 34 +36 19 12 1 8 +37 18 11 5 36 +38 17 10 1 37 +39 16 9 38 1 +40 19 12 1 20 +41 18 11 18 40 +42 17 10 1 41 +43 16 9 42 1 +44 18 11 18 36 +45 17 10 1 44 +46 16 9 45 1 +47 15 8 43 46 +48 12 7 47 46 +49 11 6 47 48 +50 11 6 47 46 +51 10 5 49 50 +52 4 4 39 51 +53 3 3 1 -52 +54 2 2 52 -53 +55 1 1 35 54 +56 20 13 16 -1 +57 21 14 1 -1 +58 20 13 1 57 +59 19 12 56 -58 +60 18 11 59 -9 +61 17 10 1 -60 +62 19 12 56 -8 +63 18 11 62 -9 +64 17 10 1 -63 +65 16 9 61 64 +66 21 14 2 -2 +67 20 13 66 1 +68 20 13 16 -57 +69 19 12 67 68 +70 18 11 69 -21 +71 17 10 1 -70 +72 16 9 71 64 +73 18 11 69 -9 +74 17 10 1 -73 +75 16 9 74 64 +76 15 8 72 75 +77 12 7 76 75 +78 11 6 76 77 +79 11 6 76 75 +80 10 5 78 79 +81 4 4 65 80 +82 3 3 81 -1 +83 2 2 81 82 +84 18 11 59 -36 +85 17 10 1 -84 +86 18 11 62 -1 +87 17 10 1 -86 +88 16 9 85 87 +89 18 11 69 -40 +90 17 10 1 -89 +91 16 9 90 87 +92 18 11 69 -36 +93 17 10 1 -92 +94 16 9 93 87 +95 15 8 91 94 +96 12 7 95 94 +97 11 6 95 96 +98 11 6 95 94 +99 10 5 97 98 +100 4 4 88 99 +101 3 3 1 -100 +102 2 2 100 -101 +103 1 1 83 102 +104 0 0 55 103 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/1.add b/resources/3rdparty/cudd-2.5.0/dddmp/exp/1.add new file mode 100644 index 000000000..ab6ab4d94 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/1.add @@ -0,0 +1,28 @@ +.ver DDDMP-2.0 +.add +.mode A +.varinfo 0 +.nnodes 12 +.nvars 50 +.nsuppvars 4 +.suppvarnames DUMMY1 DUMMY2 DUMMY3 DUMMY4 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY6 DUMMY7 DUMMY8 DUMMY9 DUMMY10 DUMMY11 DUMMY12 DUMMY13 DUMMY14 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 +.ids 1 2 3 4 +.permids 1 2 3 4 +.auxids 2 3 4 0 +.nroots 1 +.rootids 12 +.nodes +1 T 0 0 0 +2 T 2 0 0 +3 4 3 1 2 +4 T 1 0 0 +5 4 3 4 1 +6 3 2 3 5 +7 4 3 2 4 +8 3 2 7 3 +9 2 1 6 8 +10 3 2 5 7 +11 2 1 10 6 +12 1 0 9 11 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/1.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/1.bdd new file mode 100644 index 000000000..b7139aa06 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/1.bdd @@ -0,0 +1,110 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 96 +.nvars 50 +.nsuppvars 14 +.suppvarnames DUMMY0 DUMMY1 DUMMY4 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.ids 0 1 4 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 4 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 4 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -96 +.nodes +1 T 1 0 0 +2 22 13 1 -1 +3 21 12 1 -2 +4 20 11 1 3 +5 19 10 1 4 +6 20 11 3 1 +7 21 12 1 2 +8 20 11 1 7 +9 19 10 6 8 +10 18 9 5 9 +11 17 8 1 10 +12 18 9 1 9 +13 17 8 1 12 +14 16 7 11 13 +15 20 11 7 -1 +16 21 12 2 -1 +17 20 11 16 -3 +18 19 10 15 -17 +19 21 12 2 1 +20 20 11 19 7 +21 19 10 6 20 +22 18 9 18 21 +23 17 8 1 22 +24 16 7 23 13 +25 18 9 18 9 +26 17 8 1 25 +27 16 7 26 13 +28 15 6 24 27 +29 12 5 28 27 +30 11 4 28 29 +31 11 4 28 27 +32 10 3 30 31 +33 4 2 14 32 +34 19 10 1 8 +35 18 9 5 34 +36 17 8 1 35 +37 16 7 36 1 +38 19 10 1 20 +39 18 9 18 38 +40 17 8 1 39 +41 16 7 40 1 +42 18 9 18 34 +43 17 8 1 42 +44 16 7 43 1 +45 15 6 41 44 +46 12 5 45 44 +47 11 4 45 46 +48 11 4 45 44 +49 10 3 47 48 +50 4 2 37 49 +51 1 1 33 50 +52 20 11 16 -1 +53 21 12 1 -1 +54 20 11 1 53 +55 19 10 52 -54 +56 18 9 55 -9 +57 17 8 1 -56 +58 19 10 52 -8 +59 18 9 58 -9 +60 17 8 1 -59 +61 16 7 57 60 +62 21 12 2 -2 +63 20 11 62 1 +64 20 11 16 -53 +65 19 10 63 64 +66 18 9 65 -21 +67 17 8 1 -66 +68 16 7 67 60 +69 18 9 65 -9 +70 17 8 1 -69 +71 16 7 70 60 +72 15 6 68 71 +73 12 5 72 71 +74 11 4 72 73 +75 11 4 72 71 +76 10 3 74 75 +77 4 2 61 76 +78 18 9 55 -34 +79 17 8 1 -78 +80 18 9 58 -1 +81 17 8 1 -80 +82 16 7 79 81 +83 18 9 65 -38 +84 17 8 1 -83 +85 16 7 84 81 +86 18 9 65 -34 +87 17 8 1 -86 +88 16 7 87 81 +89 15 6 85 88 +90 12 5 89 88 +91 11 4 89 90 +92 11 4 89 88 +93 10 3 91 92 +94 4 2 82 93 +95 1 1 77 94 +96 0 0 51 95 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/2.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/2.bdd new file mode 100644 index 000000000..c23a16081 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/2.bdd @@ -0,0 +1,118 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 104 +.nvars 50 +.nsuppvars 16 +.suppvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.ids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -104 +.nodes +1 T 1 0 0 +2 22 15 1 -1 +3 21 14 1 -2 +4 20 13 1 3 +5 19 12 1 4 +6 20 13 3 1 +7 21 14 1 2 +8 20 13 1 7 +9 19 12 6 8 +10 18 11 5 9 +11 17 10 1 10 +12 18 11 1 9 +13 17 10 1 12 +14 16 9 11 13 +15 20 13 7 -1 +16 21 14 2 -1 +17 20 13 16 -3 +18 19 12 15 -17 +19 21 14 2 1 +20 20 13 19 7 +21 19 12 6 20 +22 18 11 18 21 +23 17 10 1 22 +24 16 9 23 13 +25 18 11 18 9 +26 17 10 1 25 +27 16 9 26 13 +28 15 8 24 27 +29 12 7 28 27 +30 11 6 28 29 +31 11 6 28 27 +32 10 5 30 31 +33 4 4 14 32 +34 3 3 1 33 +35 2 2 1 34 +36 19 12 1 8 +37 18 11 5 36 +38 17 10 1 37 +39 16 9 38 1 +40 19 12 1 20 +41 18 11 18 40 +42 17 10 1 41 +43 16 9 42 1 +44 18 11 18 36 +45 17 10 1 44 +46 16 9 45 1 +47 15 8 43 46 +48 12 7 47 46 +49 11 6 47 48 +50 11 6 47 46 +51 10 5 49 50 +52 4 4 39 51 +53 3 3 52 1 +54 2 2 1 53 +55 1 1 35 54 +56 20 13 16 -1 +57 21 14 1 -1 +58 20 13 1 57 +59 19 12 56 -58 +60 18 11 59 -9 +61 17 10 1 -60 +62 19 12 56 -8 +63 18 11 62 -9 +64 17 10 1 -63 +65 16 9 61 64 +66 21 14 2 -2 +67 20 13 66 1 +68 20 13 16 -57 +69 19 12 67 68 +70 18 11 69 -21 +71 17 10 1 -70 +72 16 9 71 64 +73 18 11 69 -9 +74 17 10 1 -73 +75 16 9 74 64 +76 15 8 72 75 +77 12 7 76 75 +78 11 6 76 77 +79 11 6 76 75 +80 10 5 78 79 +81 4 4 65 80 +82 3 3 1 81 +83 2 2 1 82 +84 18 11 59 -36 +85 17 10 1 -84 +86 18 11 62 -1 +87 17 10 1 -86 +88 16 9 85 87 +89 18 11 69 -40 +90 17 10 1 -89 +91 16 9 90 87 +92 18 11 69 -36 +93 17 10 1 -92 +94 16 9 93 87 +95 15 8 91 94 +96 12 7 95 94 +97 11 6 95 96 +98 11 6 95 94 +99 10 5 97 98 +100 4 4 88 99 +101 3 3 100 1 +102 2 2 1 101 +103 1 1 83 102 +104 0 0 55 103 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/2and3.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/2and3.bdd new file mode 100644 index 000000000..650c45492 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/2and3.bdd @@ -0,0 +1,76 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 61 +.nvars 50 +.nsuppvars 16 +.suppvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY6 DUMMY7 DUMMY8 DUMMY9 DUMMY10 DUMMY11 DUMMY12 DUMMY13 DUMMY14 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 +.ids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -61 +.nodes +1 T 1 0 0 +2 22 15 1 -1 +3 21 14 1 2 +4 20 13 3 -1 +5 21 14 2 -1 +6 20 13 5 -1 +7 19 12 4 -6 +8 21 14 2 1 +9 20 13 8 1 +10 19 12 1 9 +11 18 11 7 10 +12 17 10 1 11 +13 16 9 12 1 +14 19 12 4 1 +15 18 11 14 1 +16 17 10 1 15 +17 16 9 16 1 +18 15 8 13 17 +19 18 11 7 1 +20 17 10 1 19 +21 16 9 20 1 +22 15 8 21 17 +23 12 7 18 22 +24 11 6 18 23 +25 11 6 23 22 +26 10 5 24 25 +27 4 4 1 26 +28 3 3 1 27 +29 2 2 1 28 +30 3 3 27 1 +31 2 2 1 30 +32 1 1 29 31 +33 19 12 6 -1 +34 18 11 33 -1 +35 17 10 1 -34 +36 21 14 2 -2 +37 20 13 36 1 +38 19 12 37 6 +39 18 11 38 -10 +40 17 10 1 -39 +41 16 9 40 35 +42 19 12 37 -1 +43 18 11 42 -1 +44 17 10 1 -43 +45 16 9 44 35 +46 15 8 41 45 +47 18 11 38 -1 +48 17 10 1 -47 +49 16 9 48 35 +50 15 8 49 45 +51 12 7 46 50 +52 11 6 46 51 +53 11 6 51 50 +54 10 5 52 53 +55 4 4 35 54 +56 3 3 1 55 +57 2 2 1 56 +58 3 3 55 1 +59 2 2 1 58 +60 1 1 57 59 +61 0 0 32 60 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/3.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/3.bdd new file mode 100644 index 000000000..33d6ddf54 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/3.bdd @@ -0,0 +1,304 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 290 +.nvars 50 +.nsuppvars 17 +.suppvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.ids 0 1 2 3 4 5 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 2 3 4 5 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 2 3 4 5 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -290 +.nodes +1 T 1 0 0 +2 22 16 1 -1 +3 21 15 2 1 +4 20 14 3 1 +5 19 13 4 1 +6 18 12 1 5 +7 17 11 1 6 +8 20 14 2 1 +9 19 13 8 1 +10 18 12 1 9 +11 17 11 1 10 +12 5 5 7 11 +13 21 15 1 2 +14 20 14 13 -1 +15 21 15 2 -1 +16 20 14 15 -1 +17 19 13 14 -16 +18 20 14 3 -1 +19 21 15 1 -1 +20 20 14 19 -1 +21 19 13 18 -20 +22 18 12 17 21 +23 17 11 1 22 +24 20 14 13 -15 +25 19 13 24 1 +26 20 14 3 -15 +27 19 13 26 1 +28 18 12 25 27 +29 17 11 1 28 +30 16 10 23 29 +31 19 13 14 1 +32 19 13 18 1 +33 18 12 31 32 +34 17 11 1 33 +35 16 10 34 29 +36 15 9 30 35 +37 19 13 18 -16 +38 18 12 17 37 +39 17 11 1 38 +40 16 10 39 29 +41 15 9 40 35 +42 12 8 36 41 +43 11 7 36 42 +44 11 7 42 36 +45 10 6 43 44 +46 20 14 2 -1 +47 19 13 46 -20 +48 18 12 17 47 +49 17 11 1 48 +50 20 14 2 -15 +51 19 13 50 1 +52 18 12 25 51 +53 17 11 1 52 +54 16 10 49 53 +55 19 13 46 1 +56 18 12 31 55 +57 17 11 1 56 +58 16 10 57 53 +59 15 9 54 58 +60 19 13 46 -16 +61 18 12 17 60 +62 17 11 1 61 +63 16 10 62 53 +64 15 9 63 58 +65 12 8 59 64 +66 11 7 59 65 +67 11 7 65 59 +68 10 6 66 67 +69 5 5 45 68 +70 4 4 12 69 +71 21 15 2 -2 +72 20 14 71 1 +73 19 13 72 1 +74 18 12 1 73 +75 17 11 1 74 +76 20 14 1 13 +77 19 13 72 76 +78 18 12 1 77 +79 17 11 1 78 +80 16 10 75 79 +81 20 14 15 1 +82 19 13 81 1 +83 18 12 1 82 +84 17 11 1 83 +85 19 13 81 76 +86 18 12 1 85 +87 17 11 1 86 +88 16 10 84 87 +89 5 5 80 88 +90 20 14 71 -1 +91 19 13 90 -20 +92 18 12 17 91 +93 17 11 1 92 +94 20 14 71 -15 +95 19 13 94 76 +96 18 12 25 95 +97 17 11 1 96 +98 16 10 93 97 +99 19 13 90 1 +100 18 12 31 99 +101 17 11 1 100 +102 16 10 101 97 +103 15 9 98 102 +104 19 13 90 -16 +105 18 12 17 104 +106 17 11 1 105 +107 16 10 106 97 +108 15 9 107 102 +109 12 8 103 108 +110 11 7 103 109 +111 11 7 109 103 +112 10 6 110 111 +113 19 13 16 -20 +114 18 12 17 113 +115 17 11 1 114 +116 20 14 15 -15 +117 19 13 116 76 +118 18 12 25 117 +119 17 11 1 118 +120 16 10 115 119 +121 19 13 16 1 +122 18 12 31 121 +123 17 11 1 122 +124 16 10 123 119 +125 15 9 120 124 +126 19 13 16 -16 +127 18 12 17 126 +128 17 11 1 127 +129 16 10 128 119 +130 15 9 129 124 +131 12 8 125 130 +132 11 7 125 131 +133 11 7 131 125 +134 10 6 132 133 +135 5 5 112 134 +136 4 4 89 135 +137 3 3 70 136 +138 5 5 75 84 +139 19 13 94 1 +140 18 12 25 139 +141 17 11 1 140 +142 16 10 93 141 +143 16 10 101 141 +144 15 9 142 143 +145 16 10 106 141 +146 15 9 145 143 +147 12 8 144 146 +148 11 7 144 147 +149 11 7 147 144 +150 10 6 148 149 +151 19 13 116 1 +152 18 12 25 151 +153 17 11 1 152 +154 16 10 115 153 +155 16 10 123 153 +156 15 9 154 155 +157 16 10 128 153 +158 15 9 157 155 +159 12 8 156 158 +160 11 7 156 159 +161 11 7 159 156 +162 10 6 160 161 +163 5 5 150 162 +164 4 4 138 163 +165 3 3 70 164 +166 2 2 137 165 +167 1 1 70 166 +168 19 13 16 -1 +169 18 12 168 -5 +170 17 11 1 -169 +171 18 12 168 -9 +172 17 11 1 -171 +173 5 5 170 172 +174 19 13 72 16 +175 18 12 174 -21 +176 17 11 1 -175 +177 20 14 71 15 +178 19 13 177 -1 +179 18 12 178 -27 +180 17 11 1 -179 +181 16 10 176 180 +182 19 13 72 -1 +183 18 12 182 -32 +184 17 11 1 -183 +185 16 10 184 180 +186 15 9 181 185 +187 18 12 174 -37 +188 17 11 1 -187 +189 16 10 188 180 +190 15 9 189 185 +191 12 8 186 190 +192 11 7 186 191 +193 11 7 191 186 +194 10 6 192 193 +195 18 12 174 -47 +196 17 11 1 -195 +197 18 12 178 -51 +198 17 11 1 -197 +199 16 10 196 198 +200 18 12 182 -55 +201 17 11 1 -200 +202 16 10 201 198 +203 15 9 199 202 +204 18 12 174 -60 +205 17 11 1 -204 +206 16 10 205 198 +207 15 9 206 202 +208 12 8 203 207 +209 11 7 203 208 +210 11 7 208 203 +211 10 6 209 210 +212 5 5 194 211 +213 4 4 173 212 +214 18 12 168 -73 +215 17 11 1 -214 +216 18 12 168 -77 +217 17 11 1 -216 +218 16 10 215 217 +219 18 12 168 -82 +220 17 11 1 -219 +221 18 12 168 -85 +222 17 11 1 -221 +223 16 10 220 222 +224 5 5 218 223 +225 18 12 174 -91 +226 17 11 1 -225 +227 18 12 178 -95 +228 17 11 1 -227 +229 16 10 226 228 +230 18 12 182 -99 +231 17 11 1 -230 +232 16 10 231 228 +233 15 9 229 232 +234 18 12 174 -104 +235 17 11 1 -234 +236 16 10 235 228 +237 15 9 236 232 +238 12 8 233 237 +239 11 7 233 238 +240 11 7 238 233 +241 10 6 239 240 +242 18 12 174 -113 +243 17 11 1 -242 +244 18 12 178 -117 +245 17 11 1 -244 +246 16 10 243 245 +247 18 12 182 -121 +248 17 11 1 -247 +249 16 10 248 245 +250 15 9 246 249 +251 18 12 174 -126 +252 17 11 1 -251 +253 16 10 252 245 +254 15 9 253 249 +255 12 8 250 254 +256 11 7 250 255 +257 11 7 255 250 +258 10 6 256 257 +259 5 5 241 258 +260 4 4 224 259 +261 3 3 213 260 +262 5 5 215 220 +263 18 12 178 -139 +264 17 11 1 -263 +265 16 10 226 264 +266 16 10 231 264 +267 15 9 265 266 +268 16 10 235 264 +269 15 9 268 266 +270 12 8 267 269 +271 11 7 267 270 +272 11 7 270 267 +273 10 6 271 272 +274 18 12 178 -151 +275 17 11 1 -274 +276 16 10 243 275 +277 16 10 248 275 +278 15 9 276 277 +279 16 10 252 275 +280 15 9 279 277 +281 12 8 278 280 +282 11 7 278 281 +283 11 7 281 278 +284 10 6 282 283 +285 5 5 273 284 +286 4 4 262 285 +287 3 3 213 286 +288 2 2 261 287 +289 1 1 213 288 +290 0 0 167 289 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd new file mode 100644 index 000000000..fb774baab --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 3 +.nnodes 35 +.nvars 50 +.nsuppvars 15 +.suppvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +.orderedvarnames V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 3 5 15 17 19 23 43 45 47 73 75 77 95 97 99 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 V50 14 1 -1 +3 V49 13 1 2 +4 V48 12 3 1 +5 V48 12 1 -1 +6 V48 12 2 1 +7 V39 11 5 -6 +8 V49 13 1 -1 +9 V48 12 8 1 +10 V39 11 9 4 +11 V38 10 7 -10 +12 V37 9 1 -11 +13 V38 10 5 -9 +14 V37 9 1 -13 +15 V24 8 12 14 +16 V37 9 1 -7 +17 V37 9 1 -5 +18 V24 8 16 17 +19 V23 7 15 18 +20 V22 6 19 1 +21 V23 7 14 17 +22 V22 6 21 1 +23 V12 5 20 22 +24 V10 4 23 1 +25 V22 6 18 1 +26 V12 5 20 25 +27 V10 4 26 1 +28 V9 3 24 27 +29 V12 5 20 1 +30 V10 4 29 1 +31 V10 4 20 1 +32 V9 3 30 31 +33 V8 2 28 32 +34 V3 1 4 33 +35 V2 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis1 b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis1 new file mode 100644 index 000000000..220059d0c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis1 @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 35 +.nvars 150 +.nsuppvars 15 +.suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 49 14 1 -1 +3 48 13 1 2 +4 47 12 3 1 +5 47 12 1 -1 +6 47 12 2 1 +7 38 11 5 -6 +8 48 13 1 -1 +9 47 12 8 1 +10 38 11 9 4 +11 37 10 7 -10 +12 36 9 1 -11 +13 37 10 5 -9 +14 36 9 1 -13 +15 23 8 12 14 +16 36 9 1 -7 +17 36 9 1 -5 +18 23 8 16 17 +19 22 7 15 18 +20 21 6 19 1 +21 22 7 14 17 +22 21 6 21 1 +23 11 5 20 22 +24 9 4 23 1 +25 21 6 18 1 +26 11 5 20 25 +27 9 4 26 1 +28 8 3 24 27 +29 11 5 20 1 +30 9 4 29 1 +31 9 4 20 1 +32 8 3 30 31 +33 7 2 28 32 +34 2 1 4 33 +35 1 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis2 b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis2 new file mode 100644 index 000000000..220059d0c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis2 @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 35 +.nvars 150 +.nsuppvars 15 +.suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 49 14 1 -1 +3 48 13 1 2 +4 47 12 3 1 +5 47 12 1 -1 +6 47 12 2 1 +7 38 11 5 -6 +8 48 13 1 -1 +9 47 12 8 1 +10 38 11 9 4 +11 37 10 7 -10 +12 36 9 1 -11 +13 37 10 5 -9 +14 36 9 1 -13 +15 23 8 12 14 +16 36 9 1 -7 +17 36 9 1 -5 +18 23 8 16 17 +19 22 7 15 18 +20 21 6 19 1 +21 22 7 14 17 +22 21 6 21 1 +23 11 5 20 22 +24 9 4 23 1 +25 21 6 18 1 +26 11 5 20 25 +27 9 4 26 1 +28 8 3 24 27 +29 11 5 20 1 +30 9 4 29 1 +31 9 4 20 1 +32 8 3 30 31 +33 7 2 28 32 +34 2 1 4 33 +35 1 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis3 b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis3 new file mode 100644 index 000000000..220059d0c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis3 @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 35 +.nvars 150 +.nsuppvars 15 +.suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 49 14 1 -1 +3 48 13 1 2 +4 47 12 3 1 +5 47 12 1 -1 +6 47 12 2 1 +7 38 11 5 -6 +8 48 13 1 -1 +9 47 12 8 1 +10 38 11 9 4 +11 37 10 7 -10 +12 36 9 1 -11 +13 37 10 5 -9 +14 36 9 1 -13 +15 23 8 12 14 +16 36 9 1 -7 +17 36 9 1 -5 +18 23 8 16 17 +19 22 7 15 18 +20 21 6 19 1 +21 22 7 14 17 +22 21 6 21 1 +23 11 5 20 22 +24 9 4 23 1 +25 21 6 18 1 +26 11 5 20 25 +27 9 4 26 1 +28 8 3 24 27 +29 11 5 20 1 +30 9 4 29 1 +31 9 4 20 1 +32 8 3 30 31 +33 7 2 28 32 +34 2 1 4 33 +35 1 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis4 b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis4 new file mode 100644 index 000000000..220059d0c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.bdd.bis4 @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 35 +.nvars 150 +.nsuppvars 15 +.suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 49 14 1 -1 +3 48 13 1 2 +4 47 12 3 1 +5 47 12 1 -1 +6 47 12 2 1 +7 38 11 5 -6 +8 48 13 1 -1 +9 47 12 8 1 +10 38 11 9 4 +11 37 10 7 -10 +12 36 9 1 -11 +13 37 10 5 -9 +14 36 9 1 -13 +15 23 8 12 14 +16 36 9 1 -7 +17 36 9 1 -5 +18 23 8 16 17 +19 22 7 15 18 +20 21 6 19 1 +21 22 7 14 17 +22 21 6 21 1 +23 11 5 20 22 +24 9 4 23 1 +25 21 6 18 1 +26 11 5 20 25 +27 9 4 26 1 +28 8 3 24 27 +29 11 5 20 1 +30 9 4 29 1 +31 9 4 20 1 +32 8 3 30 31 +33 7 2 28 32 +34 2 1 4 33 +35 1 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf new file mode 100644 index 000000000..d1a946c2d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf @@ -0,0 +1,130 @@ +c # BDD stored by the DDDMP tool in CNF format +c # +c # Warning: AUX IDs missing ... equal to BDD IDs. +c # +c .ver DDDMP-2.0 +c .nnodes 35 +c .nvars 50 +c .nsuppvars 15 +c .suppvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +c .orderedvarnames V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +c .ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .cnfids 2 3 8 9 10 12 22 23 24 37 38 39 48 49 50 +c .nroots 1 +c .rootids 1 +c .nAddedCnfVar 31 +c # +c # Init CNF Clauses +c # +p cnf 130 108 +100 -49 0 +100 -50 0 +-100 49 50 0 +101 48 0 +101 -100 0 +-101 -48 100 0 +102 48 0 +102 -50 0 +-102 -48 50 0 +103 39 102 0 +-103 39 -102 0 +103 -39 -48 0 +-103 -39 48 0 +104 48 0 +104 -49 0 +-104 -48 49 0 +105 39 -101 0 +-105 39 101 0 +105 -39 -104 0 +-105 -39 104 0 +106 38 105 0 +-106 38 -105 0 +106 -38 -103 0 +-106 -38 103 0 +107 -37 0 +107 106 0 +-107 37 -106 0 +108 38 104 0 +-108 38 -104 0 +108 -38 -48 0 +-108 -38 48 0 +109 -37 0 +109 108 0 +-109 37 -108 0 +110 24 -109 0 +-110 24 109 0 +110 -24 -107 0 +-110 -24 107 0 +111 -37 0 +111 103 0 +-111 37 -103 0 +112 -37 0 +112 48 0 +-112 37 -48 0 +113 24 -112 0 +-113 24 112 0 +113 -24 -111 0 +-113 -24 111 0 +114 23 -113 0 +-114 23 113 0 +114 -23 -110 0 +-114 -23 110 0 +115 22 0 +115 -114 0 +-115 -22 114 0 +116 23 -112 0 +-116 23 112 0 +116 -23 -109 0 +-116 -23 109 0 +117 22 0 +117 -116 0 +-117 -22 116 0 +118 12 -117 0 +-118 12 117 0 +118 -12 -115 0 +-118 -12 115 0 +119 10 0 +119 -118 0 +-119 -10 118 0 +120 22 0 +120 -113 0 +-120 -22 113 0 +121 12 -120 0 +-121 12 120 0 +121 -12 -115 0 +-121 -12 115 0 +122 10 0 +122 -121 0 +-122 -10 121 0 +123 9 -122 0 +-123 9 122 0 +123 -9 -119 0 +-123 -9 119 0 +124 12 0 +124 -115 0 +-124 -12 115 0 +125 10 0 +125 -124 0 +-125 -10 124 0 +126 10 0 +126 -115 0 +-126 -10 115 0 +127 9 -126 0 +-127 9 126 0 +127 -9 -125 0 +-127 -9 125 0 +128 8 -127 0 +-128 8 127 0 +128 -8 -123 0 +-128 -8 123 0 +129 3 -128 0 +-129 3 128 0 +129 -3 -101 0 +-129 -3 101 0 +130 -2 0 +130 -129 0 +-130 2 129 0 +-130 0 +c # End of Cnf From dddmp-2.0 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf.bis b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf.bis new file mode 100644 index 000000000..d4faf78e8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.cnf.bis @@ -0,0 +1,130 @@ +c # BDD stored by the DDDMP tool in CNF format +c # +c # Warning: AUX IDs missing ... equal to BDD IDs. +c # +c .ver DDDMP-2.0 +c .nnodes 35 +c .nvars 150 +c .nsuppvars 15 +c .suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +c .orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +c .ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .cnfids 2 3 8 9 10 12 22 23 24 37 38 39 48 49 50 +c .nroots 1 +c .rootids 1 +c .nAddedCnfVar 31 +c # +c # Init CNF Clauses +c # +p cnf 130 108 +100 -49 0 +100 -50 0 +-100 49 50 0 +101 48 0 +101 -100 0 +-101 -48 100 0 +102 48 0 +102 -50 0 +-102 -48 50 0 +103 39 102 0 +-103 39 -102 0 +103 -39 -48 0 +-103 -39 48 0 +104 48 0 +104 -49 0 +-104 -48 49 0 +105 39 -101 0 +-105 39 101 0 +105 -39 -104 0 +-105 -39 104 0 +106 38 105 0 +-106 38 -105 0 +106 -38 -103 0 +-106 -38 103 0 +107 -37 0 +107 106 0 +-107 37 -106 0 +108 38 104 0 +-108 38 -104 0 +108 -38 -48 0 +-108 -38 48 0 +109 -37 0 +109 108 0 +-109 37 -108 0 +110 24 -109 0 +-110 24 109 0 +110 -24 -107 0 +-110 -24 107 0 +111 -37 0 +111 103 0 +-111 37 -103 0 +112 -37 0 +112 48 0 +-112 37 -48 0 +113 24 -112 0 +-113 24 112 0 +113 -24 -111 0 +-113 -24 111 0 +114 23 -113 0 +-114 23 113 0 +114 -23 -110 0 +-114 -23 110 0 +115 22 0 +115 -114 0 +-115 -22 114 0 +116 23 -112 0 +-116 23 112 0 +116 -23 -109 0 +-116 -23 109 0 +117 22 0 +117 -116 0 +-117 -22 116 0 +118 12 -117 0 +-118 12 117 0 +118 -12 -115 0 +-118 -12 115 0 +119 10 0 +119 -118 0 +-119 -10 118 0 +120 22 0 +120 -113 0 +-120 -22 113 0 +121 12 -120 0 +-121 12 120 0 +121 -12 -115 0 +-121 -12 115 0 +122 10 0 +122 -121 0 +-122 -10 121 0 +123 9 -122 0 +-123 9 122 0 +123 -9 -119 0 +-123 -9 119 0 +124 12 0 +124 -115 0 +-124 -12 115 0 +125 10 0 +125 -124 0 +-125 -10 124 0 +126 10 0 +126 -115 0 +-126 -10 115 0 +127 9 -126 0 +-127 9 126 0 +127 -9 -125 0 +-127 -9 125 0 +128 8 -127 0 +-128 8 127 0 +128 -8 -123 0 +-128 -8 123 0 +129 3 -128 0 +-129 3 128 0 +129 -3 -101 0 +-129 -3 101 0 +130 -2 0 +130 -129 0 +-130 2 129 0 +-130 0 +c # End of Cnf From dddmp-2.0 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max1 b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max1 new file mode 100644 index 000000000..d9a498414 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max1 @@ -0,0 +1,125 @@ +c # BDD stored by the DDDMP tool in CNF format +c # +c # Warning: AUX IDs missing ... equal to BDD IDs. +c # +c .ver DDDMP-2.0 +c .nnodes 35 +c .nvars 150 +c .nsuppvars 15 +c .suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +c .orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +c .ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .cnfids 2 3 8 9 10 12 22 23 24 37 38 39 48 49 50 +c .nroots 1 +c .rootids 1 +c .nAddedCnfVar 0 +c # +c # Init CNF Clauses +c # +p cnf 50 103 +3 8 9 10 0 +3 8 9 22 0 +3 8 9 23 24 48 0 +3 8 9 23 24 -37 0 +3 8 9 23 -24 39 48 0 +3 8 9 23 -24 39 -50 0 +3 8 9 23 -24 -39 48 0 +3 8 9 23 -24 -37 0 +3 8 9 -23 24 38 48 0 +3 8 9 -23 24 38 -49 0 +3 8 9 -23 24 -38 48 0 +3 8 9 -23 24 -37 0 +3 8 9 -23 -24 38 39 48 0 +3 8 9 -23 -24 38 39 -50 0 +3 8 9 -23 -24 38 39 -49 0 +3 8 9 -23 -24 38 -39 48 0 +3 8 9 -23 -24 38 -39 -49 0 +3 8 9 -23 -24 -38 39 48 0 +3 8 9 -23 -24 -38 39 -50 0 +3 8 9 -23 -24 -38 -39 48 0 +3 8 9 -23 -24 -37 0 +3 8 -9 10 0 +3 8 -9 12 0 +3 8 -9 22 0 +3 8 -9 23 24 48 0 +3 8 -9 23 24 -37 0 +3 8 -9 23 -24 39 48 0 +3 8 -9 23 -24 39 -50 0 +3 8 -9 23 -24 -39 48 0 +3 8 -9 23 -24 -37 0 +3 8 -9 -23 24 38 48 0 +3 8 -9 -23 24 38 -49 0 +3 8 -9 -23 24 -38 48 0 +3 8 -9 -23 24 -37 0 +3 8 -9 -23 -24 38 39 48 0 +3 8 -9 -23 -24 38 39 -50 0 +3 8 -9 -23 -24 38 39 -49 0 +3 8 -9 -23 -24 38 -39 48 0 +3 8 -9 -23 -24 38 -39 -49 0 +3 8 -9 -23 -24 -38 39 48 0 +3 8 -9 -23 -24 -38 39 -50 0 +3 8 -9 -23 -24 -38 -39 48 0 +3 8 -9 -23 -24 -37 0 +3 -8 9 10 0 +3 -8 9 12 22 0 +3 -8 9 12 24 48 0 +3 -8 9 12 24 -37 0 +3 -8 9 12 -24 39 48 0 +3 -8 9 12 -24 39 -50 0 +3 -8 9 12 -24 -39 48 0 +3 -8 9 12 -24 -37 0 +3 -8 9 -12 22 0 +3 -8 9 -12 23 24 48 0 +3 -8 9 -12 23 24 -37 0 +3 -8 9 -12 23 -24 39 48 0 +3 -8 9 -12 23 -24 39 -50 0 +3 -8 9 -12 23 -24 -39 48 0 +3 -8 9 -12 23 -24 -37 0 +3 -8 9 -12 -23 24 38 48 0 +3 -8 9 -12 -23 24 38 -49 0 +3 -8 9 -12 -23 24 -38 48 0 +3 -8 9 -12 -23 24 -37 0 +3 -8 9 -12 -23 -24 38 39 48 0 +3 -8 9 -12 -23 -24 38 39 -50 0 +3 -8 9 -12 -23 -24 38 39 -49 0 +3 -8 9 -12 -23 -24 38 -39 48 0 +3 -8 9 -12 -23 -24 38 -39 -49 0 +3 -8 9 -12 -23 -24 -38 39 48 0 +3 -8 9 -12 -23 -24 -38 39 -50 0 +3 -8 9 -12 -23 -24 -38 -39 48 0 +3 -8 9 -12 -23 -24 -37 0 +3 -8 -9 10 0 +3 -8 -9 12 22 0 +3 -8 -9 12 23 48 0 +3 -8 -9 12 23 -37 0 +3 -8 -9 12 -23 38 48 0 +3 -8 -9 12 -23 38 -49 0 +3 -8 -9 12 -23 -38 48 0 +3 -8 -9 12 -23 -37 0 +3 -8 -9 -12 22 0 +3 -8 -9 -12 23 24 48 0 +3 -8 -9 -12 23 24 -37 0 +3 -8 -9 -12 23 -24 39 48 0 +3 -8 -9 -12 23 -24 39 -50 0 +3 -8 -9 -12 23 -24 -39 48 0 +3 -8 -9 -12 23 -24 -37 0 +3 -8 -9 -12 -23 24 38 48 0 +3 -8 -9 -12 -23 24 38 -49 0 +3 -8 -9 -12 -23 24 -38 48 0 +3 -8 -9 -12 -23 24 -37 0 +3 -8 -9 -12 -23 -24 38 39 48 0 +3 -8 -9 -12 -23 -24 38 39 -50 0 +3 -8 -9 -12 -23 -24 38 39 -49 0 +3 -8 -9 -12 -23 -24 38 -39 48 0 +3 -8 -9 -12 -23 -24 38 -39 -49 0 +3 -8 -9 -12 -23 -24 -38 39 48 0 +3 -8 -9 -12 -23 -24 -38 39 -50 0 +3 -8 -9 -12 -23 -24 -38 -39 48 0 +3 -8 -9 -12 -23 -24 -37 0 +-3 48 0 +-3 -50 0 +-3 -49 0 +-2 0 +c # End of Cnf From dddmp-2.0 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max2 b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max2 new file mode 100644 index 000000000..d9a498414 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4.max2 @@ -0,0 +1,125 @@ +c # BDD stored by the DDDMP tool in CNF format +c # +c # Warning: AUX IDs missing ... equal to BDD IDs. +c # +c .ver DDDMP-2.0 +c .nnodes 35 +c .nvars 150 +c .nsuppvars 15 +c .suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +c .orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +c .ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .cnfids 2 3 8 9 10 12 22 23 24 37 38 39 48 49 50 +c .nroots 1 +c .rootids 1 +c .nAddedCnfVar 0 +c # +c # Init CNF Clauses +c # +p cnf 50 103 +3 8 9 10 0 +3 8 9 22 0 +3 8 9 23 24 48 0 +3 8 9 23 24 -37 0 +3 8 9 23 -24 39 48 0 +3 8 9 23 -24 39 -50 0 +3 8 9 23 -24 -39 48 0 +3 8 9 23 -24 -37 0 +3 8 9 -23 24 38 48 0 +3 8 9 -23 24 38 -49 0 +3 8 9 -23 24 -38 48 0 +3 8 9 -23 24 -37 0 +3 8 9 -23 -24 38 39 48 0 +3 8 9 -23 -24 38 39 -50 0 +3 8 9 -23 -24 38 39 -49 0 +3 8 9 -23 -24 38 -39 48 0 +3 8 9 -23 -24 38 -39 -49 0 +3 8 9 -23 -24 -38 39 48 0 +3 8 9 -23 -24 -38 39 -50 0 +3 8 9 -23 -24 -38 -39 48 0 +3 8 9 -23 -24 -37 0 +3 8 -9 10 0 +3 8 -9 12 0 +3 8 -9 22 0 +3 8 -9 23 24 48 0 +3 8 -9 23 24 -37 0 +3 8 -9 23 -24 39 48 0 +3 8 -9 23 -24 39 -50 0 +3 8 -9 23 -24 -39 48 0 +3 8 -9 23 -24 -37 0 +3 8 -9 -23 24 38 48 0 +3 8 -9 -23 24 38 -49 0 +3 8 -9 -23 24 -38 48 0 +3 8 -9 -23 24 -37 0 +3 8 -9 -23 -24 38 39 48 0 +3 8 -9 -23 -24 38 39 -50 0 +3 8 -9 -23 -24 38 39 -49 0 +3 8 -9 -23 -24 38 -39 48 0 +3 8 -9 -23 -24 38 -39 -49 0 +3 8 -9 -23 -24 -38 39 48 0 +3 8 -9 -23 -24 -38 39 -50 0 +3 8 -9 -23 -24 -38 -39 48 0 +3 8 -9 -23 -24 -37 0 +3 -8 9 10 0 +3 -8 9 12 22 0 +3 -8 9 12 24 48 0 +3 -8 9 12 24 -37 0 +3 -8 9 12 -24 39 48 0 +3 -8 9 12 -24 39 -50 0 +3 -8 9 12 -24 -39 48 0 +3 -8 9 12 -24 -37 0 +3 -8 9 -12 22 0 +3 -8 9 -12 23 24 48 0 +3 -8 9 -12 23 24 -37 0 +3 -8 9 -12 23 -24 39 48 0 +3 -8 9 -12 23 -24 39 -50 0 +3 -8 9 -12 23 -24 -39 48 0 +3 -8 9 -12 23 -24 -37 0 +3 -8 9 -12 -23 24 38 48 0 +3 -8 9 -12 -23 24 38 -49 0 +3 -8 9 -12 -23 24 -38 48 0 +3 -8 9 -12 -23 24 -37 0 +3 -8 9 -12 -23 -24 38 39 48 0 +3 -8 9 -12 -23 -24 38 39 -50 0 +3 -8 9 -12 -23 -24 38 39 -49 0 +3 -8 9 -12 -23 -24 38 -39 48 0 +3 -8 9 -12 -23 -24 38 -39 -49 0 +3 -8 9 -12 -23 -24 -38 39 48 0 +3 -8 9 -12 -23 -24 -38 39 -50 0 +3 -8 9 -12 -23 -24 -38 -39 48 0 +3 -8 9 -12 -23 -24 -37 0 +3 -8 -9 10 0 +3 -8 -9 12 22 0 +3 -8 -9 12 23 48 0 +3 -8 -9 12 23 -37 0 +3 -8 -9 12 -23 38 48 0 +3 -8 -9 12 -23 38 -49 0 +3 -8 -9 12 -23 -38 48 0 +3 -8 -9 12 -23 -37 0 +3 -8 -9 -12 22 0 +3 -8 -9 -12 23 24 48 0 +3 -8 -9 -12 23 24 -37 0 +3 -8 -9 -12 23 -24 39 48 0 +3 -8 -9 -12 23 -24 39 -50 0 +3 -8 -9 -12 23 -24 -39 48 0 +3 -8 -9 -12 23 -24 -37 0 +3 -8 -9 -12 -23 24 38 48 0 +3 -8 -9 -12 -23 24 38 -49 0 +3 -8 -9 -12 -23 24 -38 48 0 +3 -8 -9 -12 -23 24 -37 0 +3 -8 -9 -12 -23 -24 38 39 48 0 +3 -8 -9 -12 -23 -24 38 39 -50 0 +3 -8 -9 -12 -23 -24 38 39 -49 0 +3 -8 -9 -12 -23 -24 38 -39 48 0 +3 -8 -9 -12 -23 -24 38 -39 -49 0 +3 -8 -9 -12 -23 -24 -38 39 48 0 +3 -8 -9 -12 -23 -24 -38 39 -50 0 +3 -8 -9 -12 -23 -24 -38 -39 48 0 +3 -8 -9 -12 -23 -24 -37 0 +-3 48 0 +-3 -50 0 +-3 -49 0 +-2 0 +c # End of Cnf From dddmp-2.0 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4bis.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4bis.bdd new file mode 100644 index 000000000..fc242f3c1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4bis.bdd @@ -0,0 +1,47 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 3 +.nnodes 35 +.nvars 50 +.nsuppvars 15 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 1 0 0 +2 14 1 -1 +3 13 1 2 +4 12 3 1 +5 12 1 -1 +6 12 2 1 +7 11 5 -6 +8 13 1 -1 +9 12 8 1 +10 11 9 4 +11 10 7 -10 +12 9 1 -11 +13 10 5 -9 +14 9 1 -13 +15 8 12 14 +16 9 1 -7 +17 9 1 -5 +18 8 16 17 +19 7 15 18 +20 6 19 1 +21 7 14 17 +22 6 21 1 +23 5 20 22 +24 4 23 1 +25 6 18 1 +26 5 20 25 +27 4 26 1 +28 3 24 27 +29 5 20 1 +30 4 29 1 +31 4 20 1 +32 3 30 31 +33 2 28 32 +34 1 4 33 +35 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/4xor5.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4xor5.bdd new file mode 100644 index 000000000..9967a6767 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/4xor5.bdd @@ -0,0 +1,120 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 105 +.nvars 50 +.nsuppvars 18 +.suppvarnames DUMMY1 DUMMY2 DUMMY7 DUMMY8 DUMMY9 DUMMY11 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY6 DUMMY7 DUMMY8 DUMMY9 DUMMY10 DUMMY11 DUMMY12 DUMMY13 DUMMY14 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 +.ids 1 2 7 8 9 11 19 20 21 22 23 24 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 19 20 21 22 23 24 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 19 20 21 22 23 24 36 37 38 47 48 49 +.nroots 1 +.rootids 105 +.nodes +1 T 1 0 0 +2 24 11 1 -1 +3 23 10 1 -2 +4 22 9 3 -2 +5 21 8 4 -2 +6 23 10 1 -1 +7 22 9 6 -1 +8 21 8 7 -1 +9 20 7 5 8 +10 23 10 2 -1 +11 22 9 2 10 +12 21 8 11 2 +13 23 10 2 -2 +14 22 9 3 -13 +15 21 8 4 14 +16 20 7 12 15 +17 19 6 9 -16 +18 49 17 1 -1 +19 48 16 1 18 +20 47 15 19 1 +21 24 11 20 -20 +22 23 10 20 -21 +23 22 9 22 -21 +24 21 8 23 -21 +25 23 10 20 -20 +26 22 9 25 -20 +27 21 8 26 -20 +28 20 7 24 27 +29 23 10 21 -20 +30 22 9 21 29 +31 21 8 30 21 +32 23 10 21 -21 +33 22 9 22 -32 +34 21 8 23 33 +35 20 7 31 34 +36 19 6 28 -35 +37 47 15 1 -1 +38 47 15 18 1 +39 38 14 37 -38 +40 48 16 1 -1 +41 47 15 40 1 +42 38 14 41 20 +43 37 13 39 -42 +44 36 12 1 -43 +45 37 13 37 -41 +46 36 12 1 -45 +47 24 11 46 -46 +48 23 10 44 -47 +49 36 12 1 -39 +50 24 11 49 -49 +51 36 12 1 -37 +52 24 11 51 -51 +53 23 10 50 52 +54 22 9 48 -53 +55 21 8 54 -2 +56 23 10 44 -46 +57 23 10 49 51 +58 22 9 56 -57 +59 21 8 58 -1 +60 20 7 55 59 +61 24 11 44 -44 +62 23 10 61 47 +63 23 10 50 -51 +64 22 9 62 63 +65 21 8 64 2 +66 21 8 54 14 +67 20 7 65 66 +68 19 6 60 -67 +69 23 10 46 -47 +70 22 9 69 -52 +71 21 8 70 -2 +72 23 10 46 -46 +73 22 9 72 -51 +74 21 8 73 -1 +75 20 7 71 74 +76 23 10 52 -51 +77 22 9 47 76 +78 21 8 77 2 +79 21 8 70 14 +80 20 7 78 79 +81 19 6 75 -80 +82 11 5 68 81 +83 9 4 82 17 +84 23 10 49 -52 +85 22 9 84 -53 +86 21 8 85 -2 +87 23 10 49 -51 +88 22 9 87 -57 +89 21 8 88 -1 +90 20 7 86 89 +91 22 9 53 63 +92 21 8 91 2 +93 21 8 85 14 +94 20 7 92 93 +95 19 6 90 -94 +96 11 5 68 95 +97 9 4 96 17 +98 8 3 83 97 +99 11 5 68 17 +100 9 4 99 17 +101 9 4 68 17 +102 8 3 100 101 +103 7 2 98 102 +104 2 1 36 103 +105 1 0 17 104 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/5.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/5.bdd new file mode 100644 index 000000000..198f6bfa7 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/5.bdd @@ -0,0 +1,31 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 17 +.nvars 50 +.nsuppvars 6 +.suppvarnames DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 +.ids 19 20 21 22 23 24 +.permids 19 20 21 22 23 24 +.auxids 19 20 21 22 23 24 +.nroots 1 +.rootids 17 +.nodes +1 T 1 0 0 +2 24 5 1 -1 +3 23 4 1 -2 +4 22 3 3 -2 +5 21 2 4 -2 +6 23 4 1 -1 +7 22 3 6 -1 +8 21 2 7 -1 +9 20 1 5 8 +10 23 4 2 -1 +11 22 3 2 10 +12 21 2 11 2 +13 23 4 2 -2 +14 22 3 3 -13 +15 21 2 4 14 +16 20 1 12 15 +17 19 0 9 -16 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/composeids.txt b/resources/3rdparty/cudd-2.5.0/dddmp/exp/composeids.txt new file mode 100644 index 000000000..0e1340fed --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/composeids.txt @@ -0,0 +1,20 @@ +0 +2 +4 +6 +8 +10 +12 +14 +16 +18 +20 +22 +24 +26 +28 +30 +32 +34 +36 +38 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/one.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/one.bdd new file mode 100644 index 000000000..836566fbe --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/one.bdd @@ -0,0 +1,13 @@ +.ver DDDMP-1.0 +.mode A +.varinfo 0 +.nnodes 1 +.nvars 100 +.nsuppvars 0 +.ids +.permids +.nroots 1 +.rootids 1 +.nodes +1 T 1 0 0 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.out new file mode 100644 index 000000000..321532e3c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.out @@ -0,0 +1,269 @@ +--------------------------------------------------------------------------- +--------------------- TESTING Load and Write Header ----------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> DD TYPE: DDDMP_BDD +Number of variables: 50 +Number of support variables: 15 +suppVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +orderedVarNames: V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varAuxIds: 3 5 15 17 19 23 43 45 47 73 75 77 95 97 99 +varAuxIds for ALL Manager Variables: -1 3 5 -1 -1 -1 -1 15 17 19 -1 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 43 45 47 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 73 75 77 -1 -1 -1 -1 -1 -1 -1 -1 95 97 99 +Number of roots: 1 +TestDddmp> File : TestDddmp> DD TYPE: DDDMP_ADD +Number of variables: 3 +Number of support variables: 2 +suppVarNames: DUMMY1 DUMMY2 +orderedVarNames: DUMMY0 DUMMY1 DUMMY2 +varIds: 1 2 +varIds for ALL Manager Variables: -1 1 2 +varComposeIds: 1 2 +varComposeIds for ALL Manager Variables: -1 1 2 +varAuxIds: 1 2 +varAuxIds for ALL Manager Variables: -1 1 2 +Number of roots: 1 +TestDddmp> File : TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 50 +Number of support variables: 15 +suppVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +orderedVarNames: V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +Number of roots: 1 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +-------------------- TESTING Load BDD from DDDMP-1.0 ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> DD TYPE: DDDMP_BDD +Number of variables: 10 +Number of support variables: 7 +suppVarNames: G0 G1 G2 G3 G5 G6 G7 +orderedVarNames: G0 G1 G2 G3 G5 G6 G7 DUMMY7 DUMMY8 DUMMY9 +varIds: 0 1 2 3 4 5 6 +varIds for ALL Manager Variables: 0 1 2 3 4 5 6 -1 -1 -1 +varComposeIds: 0 1 2 3 4 6 8 +varComposeIds for ALL Manager Variables: 0 1 2 3 4 6 8 -1 -1 -1 +varAuxIds: 0 1 2 3 4 5 6 +varAuxIds for ALL Manager Variables: 0 1 2 3 4 5 6 -1 -1 -1 +Number of roots: 3 +TestDddmp> File : Which Array of BDDs [0..19]: TestDddmp> File : Which Array of BDDs [0..19]: Storing Array of BDDs in file s27deltaDddmp1.bdd.tmp ... +done. +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +----------------------- TESTING basic Load/Store ... ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 0.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 1.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 0or1.bdd.tmp ... +TestDddmp> File : Which BDDs [0..19]: Loading 2.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 3.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 2and3.bdd.tmp ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 5.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 4xor5.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +---------- TESTING Load/Store with sifting, varnames & varauxids ---------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Storing 4a.bdd.tmp ... +TestDddmp> Reordering Approach (1..17): TestDddmp> File : Which BDDs [0..19]: Storing 4b.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +------------------------- ... END PHASE 1 ... ----------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> Variable matchmode: +Match IDs (1) +Match permIDs (2) +Match names (must have been loaded) (3) +Match auxids (must have been loaded) (4) +Match composeids (must have been loaded) (5) +Your choice: TestDddmp> File : Which BDDs [0..19]: Loading 4b.bdd.tmp ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Storing 4c.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load ADD and Store ADD ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 0.add ... +Load: +-01 2 +-1- 1 +TestDddmp> File : Which BDDs [0..19]: Storing 0.add.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 1.add ... +Load: +-0001--------------------------------------------- 1 +-0010--------------------------------------------- 2 +-0100--------------------------------------------- 1 +-0101--------------------------------------------- 2 +-0111--------------------------------------------- 1 +-1000--------------------------------------------- 2 +-1010--------------------------------------------- 1 +-1011--------------------------------------------- 2 +-1101--------------------------------------------- 1 +-1110--------------------------------------------- 2 +TestDddmp> File : Which BDDs [0..19]: Storing 1.add.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load BDD and Store CNF ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.cnf.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +--------------------- TESTING Load CNF and Store BDD ---------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.cnf.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load BDD and Store CNF ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.node1.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.max1.tmp ... +Number of Clauses Stored = 103 +Number of New Variable Created Storing = 0 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.node2.tmp ... +Number of Clauses Stored = 114 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.node3.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.max2.tmp ... +Number of Clauses Stored = 103 +Number of New Variable Created Storing = 0 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.best1.tmp ... +Number of Clauses Stored = 53 +Number of New Variable Created Storing = 7 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.best2.tmp ... +Number of Clauses Stored = 69 +Number of New Variable Created Storing = 12 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +--------------------------------------------------------------------------- +--------------------- TESTING Load CNF and Store BDD ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.node2.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.node2.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.node3.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.node3.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.best1.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.best1.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.best2.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.best2.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.script new file mode 100755 index 000000000..8d792ef42 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/runAllTest.script @@ -0,0 +1,11 @@ +# !/bin/sh +# +# Run All Test Files +# +./test1.script +./test2.script +./test3.script +./test4.script +./test5.script +./test6.script +./test7.script diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27RP1.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27RP1.bdd new file mode 100644 index 000000000..56532603a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27RP1.bdd @@ -0,0 +1,18 @@ +# MONO +.ver DDDMP-1.0 +.mode A +.varinfo 3 +.nnodes 3 +.nvars 10 +.nsuppvars 2 +.varnames G5 G6 +.ids 4 5 +.permids 4 6 +.auxids 4 5 +.nroots 1 +.rootids -3 +.nodes +1 T 1 0 0 +2 5 1 1 -1 +3 4 0 2 -1 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd new file mode 100644 index 000000000..11a595687 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd @@ -0,0 +1,31 @@ +.ver DDDMP-1.0 +.mode A +.varinfo 0 +.dd s27adelta.bdd +.nnodes 16 +.nvars 10 +.nsuppvars 7 +.varnames G0 G1 G2 G3 G5 G6 G7 +.ids 0 1 2 3 4 5 6 +.permids 0 1 2 3 4 6 8 +.auxids 0 1 2 3 4 5 6 +.nroots 3 +.rootids 6 -13 -16 +.nodes +1 T 1 0 0 +2 6 6 1 -1 +3 4 4 1 2 +4 3 3 3 1 +5 1 1 1 4 +6 0 0 5 -1 +7 5 5 1 -1 +8 4 4 1 -7 +9 5 5 1 -2 +10 4 4 1 -9 +11 3 3 10 8 +12 1 1 8 11 +13 0 0 5 12 +14 2 2 1 -1 +15 2 2 1 -2 +16 1 1 14 15 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd.bis b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd.bis new file mode 100644 index 000000000..b7fb86bfe --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp1.bdd.bis @@ -0,0 +1,31 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 16 +.nvars 10 +.nsuppvars 7 +.suppvarnames G0 G1 G2 G3 G5 G6 G7 +.orderedvarnames G0 G1 G2 G3 G5 G6 G7 DUMMY7 DUMMY8 DUMMY9 +.ids 0 1 2 3 4 5 6 +.permids 0 1 2 3 4 5 6 +.auxids 0 1 2 3 4 5 6 +.nroots 3 +.rootids 6 -13 -16 +.nodes +1 T 1 0 0 +2 6 6 1 -1 +3 4 4 1 2 +4 3 3 3 1 +5 1 1 1 4 +6 0 0 5 -1 +7 5 5 1 -1 +8 4 4 1 -7 +9 5 5 1 -2 +10 4 4 1 -9 +11 3 3 10 8 +12 1 1 8 11 +13 0 0 5 12 +14 2 2 1 -1 +15 2 2 1 -2 +16 1 1 14 15 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp2.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp2.bdd new file mode 100644 index 000000000..d247bd1fd --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/s27deltaDddmp2.bdd @@ -0,0 +1,32 @@ +.ver DDDMP-1.0 +.mode A +.varinfo 0 +.dd s27adelta.bdd +.nnodes 16 +.nvars 10 +.nsuppvars 7 +.orderedvarnames G0 G1 G2 G3 G5 G6 G7 TMP1 TMP2 TMP3 +.suppvarnames G0 G1 G2 G3 G5 G6 G7 +.ids 0 1 2 3 4 5 6 +.permids 0 1 2 3 4 6 8 +.auxids 0 1 2 3 4 5 6 +.nroots 3 +.rootids 6 -13 -16 +.nodes +1 T 1 0 0 +2 6 6 1 -1 +3 4 4 1 2 +4 3 3 3 1 +5 1 1 1 4 +6 0 0 5 -1 +7 5 5 1 -1 +8 4 4 1 -7 +9 5 5 1 -2 +10 4 4 1 -9 +11 3 3 10 8 +12 1 1 8 11 +13 0 0 5 12 +14 2 2 1 -1 +15 2 2 1 -2 +16 1 1 14 15 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.out new file mode 100644 index 000000000..96b2a3ac3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.out @@ -0,0 +1,44 @@ +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load and Write Header ----------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> DD TYPE: DDDMP_BDD +Number of variables: 50 +Number of support variables: 15 +suppVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +orderedVarNames: V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varAuxIds: 3 5 15 17 19 23 43 45 47 73 75 77 95 97 99 +varAuxIds for ALL Manager Variables: -1 3 5 -1 -1 -1 -1 15 17 19 -1 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 43 45 47 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 73 75 77 -1 -1 -1 -1 -1 -1 -1 -1 95 97 99 +Number of roots: 1 +TestDddmp> File : TestDddmp> DD TYPE: DDDMP_ADD +Number of variables: 3 +Number of support variables: 2 +suppVarNames: DUMMY1 DUMMY2 +orderedVarNames: DUMMY0 DUMMY1 DUMMY2 +varIds: 1 2 +varIds for ALL Manager Variables: -1 1 2 +varComposeIds: 1 2 +varComposeIds for ALL Manager Variables: -1 1 2 +varAuxIds: 1 2 +varAuxIds for ALL Manager Variables: -1 1 2 +Number of roots: 1 +TestDddmp> File : TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 50 +Number of support variables: 15 +suppVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +orderedVarNames: V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +Number of roots: 1 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.script new file mode 100755 index 000000000..843e3650c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test1.script @@ -0,0 +1,26 @@ +# !/bin/sh +# +# Check Header Load/Store for BDD/ADD/CNFs: +# Load Header +# Write Information on Standard Output +# +rm -f *.*.tmp +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load and Write Header -----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END +mi +50 +hlb +4.bdd +hw +hlb +0.add +hw +hlc +4.cnf +hw +mq +quit +END +echo "-------------------------------- ... END ----------------------------------" diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.out new file mode 100644 index 000000000..22d6e39d1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.out @@ -0,0 +1,23 @@ +rm: No match. +--------------------------------------------------------------------------- +-------------------- TESTING Load BDD from DDDMP-1.0 ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> DD TYPE: DDDMP_BDD +Number of variables: 10 +Number of support variables: 7 +suppVarNames: G0 G1 G2 G3 G5 G6 G7 +orderedVarNames: G0 G1 G2 G3 G5 G6 G7 DUMMY7 DUMMY8 DUMMY9 +varIds: 0 1 2 3 4 5 6 +varIds for ALL Manager Variables: 0 1 2 3 4 5 6 -1 -1 -1 +varComposeIds: 0 1 2 3 4 6 8 +varComposeIds for ALL Manager Variables: 0 1 2 3 4 6 8 -1 -1 -1 +varAuxIds: 0 1 2 3 4 5 6 +varAuxIds for ALL Manager Variables: 0 1 2 3 4 5 6 -1 -1 -1 +Number of roots: 3 +TestDddmp> File : Which Array of BDDs [0..19]: TestDddmp> File : Which Array of BDDs [0..19]: Storing Array of BDDs in file s27deltaDddmp1.bdd.tmp ... +done. +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.script new file mode 100755 index 000000000..f719ed2bb --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test2.script @@ -0,0 +1,30 @@ +# !/bin/sh +# +# Check BDDs from DDDMP-1.0: +# Load an Array of BDDs from DDDMP-1.0 +# Store them +# +rm -f *.*.tmp +echo "---------------------------------------------------------------------------" +echo "-------------------- TESTING Load BDD from DDDMP-1.0 ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END +mi +10 +hlb +s27deltaDddmp1.bdd +hw +bal +s27deltaDddmp1.bdd +0 +bas +s27deltaDddmp1.bdd.tmp +0 +mq +quit +END +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief s27deltaDddmp1.bdd.tmp s27deltaDddmp1.bdd.bis +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp + diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.out new file mode 100644 index 000000000..0c296c095 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.out @@ -0,0 +1,18 @@ +rm: No match. +--------------------------------------------------------------------------- +----------------------- TESTING basic Load/Store ... ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 0.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 1.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 0or1.bdd.tmp ... +TestDddmp> File : Which BDDs [0..19]: Loading 2.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 3.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 2and3.bdd.tmp ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 5.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 4xor5.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.script new file mode 100755 index 000000000..408496c2d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test3.script @@ -0,0 +1,69 @@ +# !/bin/sh +# +# BDD check: +# Load BDDs +# Make some operations +# Store BDDs +# +rm -f *.*.tmp +echo "---------------------------------------------------------------------------" +echo "----------------------- TESTING basic Load/Store ... ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END +mi +50 +hlb +0or1.bdd +bl +0.bdd +0 +bl +1.bdd +1 +op +or +0 +1 +2 +bs +0or1.bdd.tmp +2 +bl +2.bdd +2 +bl +3.bdd +3 +op +and +2 +3 +4 +bs +2and3.bdd.tmp +4 +hlb +4xor5.bdd +bl +4.bdd +4 +bl +5.bdd +5 +op +xor +4 +5 +6 +bs +4xor5.bdd.tmp +6 +mq +quit +END +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 0or1.bdd 0or1.bdd.tmp +diff --brief 2and3.bdd 2and3.bdd.tmp +diff --brief 4xor5.bdd 4xor5.bdd.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.out new file mode 100644 index 000000000..367602d90 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.out @@ -0,0 +1,24 @@ +rm: No match. +--------------------------------------------------------------------------- +---------- TESTING Load/Store with sifting, varnames & varauxids ---------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Storing 4a.bdd.tmp ... +TestDddmp> Reordering Approach (1..17): TestDddmp> File : Which BDDs [0..19]: Storing 4b.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +------------------------- ... END PHASE 1 ... ----------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> Variable matchmode: +Match IDs (1) +Match permIDs (2) +Match names (must have been loaded) (3) +Match auxids (must have been loaded) (4) +Match composeids (must have been loaded) (5) +Your choice: TestDddmp> File : Which BDDs [0..19]: Loading 4b.bdd.tmp ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Storing 4c.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.script new file mode 100755 index 000000000..2c50992b1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test4.script @@ -0,0 +1,56 @@ +# !/bin/sh +# +# BDD Check: +# Load BDDs +# Make some operations (with reordering) +# Store BDDs +# +rm -f *.*/tmp +echo "---------------------------------------------------------------------------" +echo "---------- TESTING Load/Store with sifting, varnames & varauxids ----------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END1 +mi +50 +onl +varnames.ord +bl +4.bdd +4 +oil +varauxids.ord +bs +4a.bdd.tmp +4 +dr +4 +bs +4b.bdd.tmp +4 +mq +quit +END1 +echo "------------------------- ... END PHASE 1 ... -----------------------------" +./../testdddmp << END2 +mi +50 +onl +varnames.ord +slm +3 +bl +4b.bdd.tmp +4 +oil +varauxids.ord +bs +4c.bdd.tmp +4 +mq +quit +END2 +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 4.bdd 4a.bdd.tmp +diff --brief 4a.bdd.tmp 4c.bdd.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.out new file mode 100644 index 000000000..a883f515f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.out @@ -0,0 +1,28 @@ +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load ADD and Store ADD ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 0.add ... +Load: +-01 2 +-1- 1 +TestDddmp> File : Which BDDs [0..19]: Storing 0.add.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 1.add ... +Load: +-0001--------------------------------------------- 1 +-0010--------------------------------------------- 2 +-0100--------------------------------------------- 1 +-0101--------------------------------------------- 2 +-0111--------------------------------------------- 1 +-1000--------------------------------------------- 2 +-1010--------------------------------------------- 1 +-1011--------------------------------------------- 2 +-1101--------------------------------------------- 1 +-1110--------------------------------------------- 2 +TestDddmp> File : Which BDDs [0..19]: Storing 1.add.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.script new file mode 100755 index 000000000..9676c944e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test5.script @@ -0,0 +1,42 @@ +# !/bin/sh +# +# Check ADD: +# Load an ADD +# Store the same ADD +# Compare the two +# (done twice on a small - 0.add - and a medium - 1.add - ADD). +# +rm -f *.tmp* +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load ADD and Store ADD ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END1 +mi +3 +hlb +0.add +al +0.add +0 +as +0.add.tmp +0 +mq +mi +50 +hlb +1.add +al +1.add +1 +as +1.add.tmp +1 +mq +quit +END1 +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 0.add 0.add.tmp +diff --brief 1.add 1.add.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.out new file mode 100644 index 000000000..f10b48490 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.out @@ -0,0 +1,31 @@ +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load BDD and Store CNF ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.cnf.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +--------------------- TESTING Load CNF and Store BDD ---------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.cnf.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.script new file mode 100755 index 000000000..0b4295e29 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test6.script @@ -0,0 +1,50 @@ +# !/bin/sh +# +# Check CNF (short check - only NodeByNode method involved): +# Load BDDs +# Store corresponding CNF +# Read CNF +# Store corresponding BDD +# Compare original and final BDDs +# +rm -f *.tmp* +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load BDD and Store CNF ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END1 +mi +150 +hlc +4.cnf.bis +bl +4.bdd +0 +cs +4.cnf.tmp +0 +N +100 +mq +quit +END1 +echo "--------------------- TESTING Load CNF and Store BDD ----------------------" +./../testdddmp << END2 +mi +150 +hlc +4.cnf.bis +cl +4.cnf.tmp +0 +hw +bs +4.bdd.tmp +0 +mq +quit +END2 +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 4.cnf.bis 4.cnf.tmp +diff --brief 4.bdd.bis1 4.bdd.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.out b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.out new file mode 100644 index 000000000..d5cd7d3e0 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.out @@ -0,0 +1,102 @@ +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load BDD and Store CNF ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.node1.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.max1.tmp ... +Number of Clauses Stored = 103 +Number of New Variable Created Storing = 0 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.node2.tmp ... +Number of Clauses Stored = 114 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.node3.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.max2.tmp ... +Number of Clauses Stored = 103 +Number of New Variable Created Storing = 0 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.best1.tmp ... +Number of Clauses Stored = 53 +Number of New Variable Created Storing = 7 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.best2.tmp ... +Number of Clauses Stored = 69 +Number of New Variable Created Storing = 12 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +--------------------------------------------------------------------------- +--------------------- TESTING Load CNF and Store BDD ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.node2.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.node2.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.node3.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.node3.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.best1.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.best1.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.best2.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.best2.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.script b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.script new file mode 100755 index 000000000..dcef83f49 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/test7.script @@ -0,0 +1,150 @@ +# !/bin/sh +# +# Check CNF (long check - all methods involved): +# Load BDDs +# Store corresponding CNF in different format: +# NodeByNode method -> file 4.node1.tmp +# MaxtermByMaxterm -> file 4.max1.tmp +# Best with different options: +# MaxEdge=-1 MaxPath= 0 -> similar to NodeByNode -> file 4.node2.tmp +# MaxEdge= 0 MaxPath=-1 -> similar to NodeByNode -> file 4.node3.tmp +# MaxEdge=-1 MaxPath=-1 -> = MaxtermByMaxterm -> file 4.max2.tmp +# MaxEdge= 1 MaxPath=-1 -> = Original Best -> file 4.best1.tmp +# MaxEdge= 1 MaxPath= 2 -> = Original Best, With Path Shorter than 3 +# file 4.best2.tmp +# Read CNF +# Store corresponding BDD +# Compare original and final BDDs +# +rm -f *.tmp* +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load BDD and Store CNF ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END1 +mi +150 +hlc +4.cnf.bis +bl +4.bdd +0 +cs +4.node1.tmp +0 +N +100 +cs +4.max1.tmp +0 +M +100 +cs +4.node2.tmp +0 +B +-1 +0 +100 +cs +4.node3.tmp +0 +B +0 +-1 +100 +cs +4.max2.tmp +0 +B +-1 +-1 +100 +cs +4.best1.tmp +0 +B +1 +-1 +100 +cs +4.best2.tmp +0 +B +1 +2 +100 +mq +quit +END1 +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load CNF and Store BDD ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END2 +mi +150 +hlc +4.node2.tmp +cl +4.node2.tmp +0 +hw +bs +4.node2.bdd.tmp +0 +mq +quit +END2 +./../testdddmp << END3 +mi +150 +hlc +4.node3.tmp +cl +4.node3.tmp +0 +hw +bs +4.node3.bdd.tmp +0 +mq +quit +END3 +./../testdddmp << END4 +mi +150 +hlc +4.best1.tmp +cl +4.best1.tmp +0 +hw +bs +4.best1.bdd.tmp +0 +mq +quit +END4 +./../testdddmp << END5 +mi +150 +hlc +4.best2.tmp +cl +4.best2.tmp +0 +hw +bs +4.best2.bdd.tmp +0 +mq +quit +END5 +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 4.max1 4.max1.tmp +diff --brief 4.max2 4.max2.tmp +diff --brief 4.bdd.bis1 4.node2.bdd.tmp +diff --brief 4.bdd.bis2 4.node3.bdd.tmp +diff --brief 4.bdd.bis3 4.best1.bdd.tmp +diff --brief 4.bdd.bis4 4.best2.bdd.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.tmp* diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/varauxids.ord b/resources/3rdparty/cudd-2.5.0/dddmp/exp/varauxids.ord new file mode 100644 index 000000000..9dc88561e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/varauxids.ord @@ -0,0 +1,50 @@ +1 +3 +5 +7 +9 +11 +13 +15 +17 +19 +21 +23 +25 +27 +29 +31 +33 +35 +37 +39 +41 +43 +45 +47 +49 +51 +53 +55 +57 +59 +61 +63 +65 +67 +69 +71 +73 +75 +77 +79 +81 +83 +85 +87 +89 +91 +93 +95 +97 +99 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/varnames.ord b/resources/3rdparty/cudd-2.5.0/dddmp/exp/varnames.ord new file mode 100644 index 000000000..541f21e65 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/varnames.ord @@ -0,0 +1,50 @@ +V1 +V2 +V3 +V4 +V5 +V6 +V7 +V8 +V9 +V10 +V11 +V12 +V13 +V14 +V15 +V16 +V17 +V18 +V19 +V20 +V21 +V22 +V23 +V24 +V25 +V26 +V27 +V28 +V29 +V30 +V31 +V32 +V33 +V34 +V35 +V36 +V37 +V38 +V39 +V40 +V41 +V42 +V43 +V44 +V45 +V46 +V47 +V48 +V49 +V50 diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/exp/zero.bdd b/resources/3rdparty/cudd-2.5.0/dddmp/exp/zero.bdd new file mode 100644 index 000000000..4c229f757 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/exp/zero.bdd @@ -0,0 +1,13 @@ +.ver DDDMP-1.0 +.mode A +.varinfo 0 +.nnodes 1 +.nvars 100 +.nsuppvars 0 +.ids +.permids +.nroots 1 +.rootids -1 +.nodes +1 T 1 0 0 +.end diff --git a/resources/3rdparty/cudd-2.5.0/dddmp/testdddmp.c b/resources/3rdparty/cudd-2.5.0/dddmp/testdddmp.c new file mode 100644 index 000000000..6879dccb6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/dddmp/testdddmp.c @@ -0,0 +1,2279 @@ +/**CFile********************************************************************** + + FileName [testdddmp.c] + + PackageName [dddmp] + + Synopsis [A simple test function for Dddmp package] + + Description [This program constitutes a simple test program + for the dddmp library (version 2.0). + A simple interactive command selection allow the users to perform the + main operation on BDDs, ADDs, and CNF, such as loading and storing. + It can work also as a BDD calculators. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include +#include +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMPTEST_MAX_FILENAME_LENGTH 256 +#define DDDMPTEST_MAX_STRING_LENGTH 80 +#define DDDMPTEST_MAX_OPERAND 20 +#define DDDMPTEST_MAX_VARIABLE 50 +#define DDDMP_MAX_BDDARRAY_LEN 1000 + +/**Enum************************************************************************ + + Synopsis [Message type for output messages] + + Description [Type supported by the output function to print-out + the proper message. + ] + +******************************************************************************/ + +typedef enum { + /* Int Messages */ + DDDMP_MESSAGE_MANAGER_VAR, + DDDMP_MESSAGE_BDD, + DDDMP_MESSAGE_BDD_ARRAY, + DDDMP_MESSAGE_SOURCE1, + DDDMP_MESSAGE_SOURCE2, + DDDMP_MESSAGE_DESTINATION, + DDDMP_MESSAGE_CUBE, + DDDMP_MESSAGE_INDEX, + DDDMP_MESSAGE_I_ID, + DDDMP_MESSAGE_EDGE_MAX, + DDDMP_MESSAGE_LENGHT_MAX, + DDDMP_MESSAGE_REORDERING, + /* String Messages */ + DDDMP_MESSAGE_PROMPT, + DDDMP_MESSAGE_FILE, + DDDMP_MESSAGE_OP, + DDDMP_MESSAGE_FORMAT +} Dddmp_MessageType; + +#if !defined(RAND_MAX) && defined(sun) && defined(sparc) +#define RAND_MAX 2147483647 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct dddmpVarInfo { + /* + * Local Information + */ + + int nDdVars; /* Local Manager Number of Variables */ + char **rootNames; /* Root Names */ + + /* + * Header File Information + */ + + Dddmp_DecompType ddType; + + int nVars; /* File Manager Number of Variables */ + int nSuppVars; /* File Structure Number of Variables */ + + int varNamesFlagUpdate; /* 0 to NOT Update */ + char **suppVarNames; + char **orderedVarNames; + + int varIdsFlagUpdate; /* 0 to NOT Update */ + int *varIds; /* File ids - nSuppVars size */ + int *varIdsAll; /* ALL ids - nVars size */ + + int varComposeIdsFlagUpdate; /* 0 to NOT Update */ + int *varComposeIds; /* File permids - nSuppVars size */ + int *varComposeIdsAll; /* ALL permids - nVars size */ + + int varAuxIdsFlagUpdate; /* 0 to NOT Update */ + int *varAuxIds; /* File auxids - nSuppVars size */ + int *varAuxIdsAll; /* ALL auxids - nVars size */ + + int nRoots; +} dddmpVarInfo_t; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +Dddmp_RootMatchType rootmatchmode; +Dddmp_VarMatchType varmatchmode; +Dddmp_VarInfoType varoutinfo; +char varname[DDDMPTEST_MAX_STRING_LENGTH]; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdManager *ManagerInit (dddmpVarInfo_t *varInfo); +static void ManagerQuit (DdManager **ddMgr, dddmpVarInfo_t *varInfo); +static int OneCreate(DdManager *ddMgr, DdNode **operandBdd); +static int BddZeroCreate(DdManager *ddMgr, DdNode **operandBdd); +static int LeafCreate(DdManager *ddMgr, DdNode **operandBdd); +static int BddCreate(DdManager *ddMgr, DdNode **operandBdd); +static int A2B(void); +static int B2A(void); +static int HeaderLoadBdd(dddmpVarInfo_t *varInfo); +static int HeaderLoadCnf(dddmpVarInfo_t *varInfo); +static int HeaderWrite(dddmpVarInfo_t *varInfo); +static int Help(void); +static int OrderNamesLoad(dddmpVarInfo_t *varInfo); +static int IntArrayLoad(dddmpVarInfo_t *varInfo, const char *mode); +static int BddLoad(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int BddArrayLoad(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int AddLoad(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int AddArrayLoad(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int BddLoadCnf(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int BddArrayLoadCnf(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int Operation(DdManager *ddMgr, DdNode **operandBdd); +static int BddStore(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int BddArrayStore(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int AddStore(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int AddArrayStore(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int BddStoreCnf(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int BddArrayStoreCnf(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int DynamicReordering(DdManager *ddMgr); +static int SetLoadMatchmode(); +static int CompleteInfoStruct(Dddmp_DecompType ddType, int nVars, int nSuppVars, char **suppVarNames, char **orderedVarNames, int *varIds, int *varComposeIds, int *varAuxIds, int nRoots, dddmpVarInfo_t *varInfo); +static void ReadInt(Dddmp_MessageType message, int *i); +static void ReadString(Dddmp_MessageType message, char string[]); + +/**AutomaticEnd***************************************************************/ + +int +main( + int argc, + char **argv + ) +{ + DdManager *ddMgr = NULL; + DdNode **operandBdd = NULL; + DdNode ***operandBddArray = NULL; + int *operandBddArraySize = NULL; + char *row = NULL; + dddmpVarInfo_t varInfo; + int i; + + /*--------------------- Echo command line and arguments -------------------*/ + + fprintf (stdout, "#"); + for (i=0; i1) { + Help(); + } + + /*-------------------------- Init Array of BDDs ---------------------------*/ + + rootmatchmode = DDDMP_ROOT_MATCHLIST; +#if 1 + varmatchmode = DDDMP_VAR_MATCHIDS; +#else + varmatchmode = DDDMP_VAR_MATCHNAMES; +#endif + varoutinfo = DDDMP_VARIDS; + + row = DDDMP_ALLOC (char, DDDMPTEST_MAX_STRING_LENGTH); + Dddmp_CheckAndReturn (row==NULL, "Allocation error."); + + operandBdd = DDDMP_ALLOC (DdNode *, DDDMPTEST_MAX_OPERAND); + Dddmp_CheckAndReturn (operandBdd==NULL, "Allocation error."); + + operandBddArray = DDDMP_ALLOC (DdNode **, DDDMPTEST_MAX_OPERAND); + Dddmp_CheckAndReturn (operandBddArray==NULL, "Allocation error."); + + operandBddArraySize = DDDMP_ALLOC (int, DDDMPTEST_MAX_OPERAND); + Dddmp_CheckAndReturn (operandBddArraySize==NULL, "Allocation error."); + + for (i=0; inDdVars = nVars; + + varInfo->rootNames = NULL; + varInfo->ddType = DDDMP_NONE; + varInfo->nVars = (-1); + varInfo->nSuppVars = (-1); + varInfo->varNamesFlagUpdate = 1; + varInfo->suppVarNames = NULL; + varInfo->orderedVarNames = NULL; + varInfo->varIdsFlagUpdate = 1; + varInfo->varIds = NULL; + varInfo->varIdsAll = NULL; + varInfo->varComposeIdsFlagUpdate = 1; + varInfo->varComposeIds = NULL; + varInfo->varComposeIdsAll = NULL; + varInfo->varAuxIdsFlagUpdate = 1; + varInfo->varAuxIds = NULL; + varInfo->varAuxIdsAll = NULL; + varInfo->nRoots = (-1); + + /*------------------------------ Init DD Manager --------------------------*/ + + ddMgr = Cudd_Init (nVars, 0, CUDD_UNIQUE_SLOTS, + CUDD_CACHE_SLOTS, 0); + + Dddmp_CheckAndReturn (ddMgr==NULL, "DdManager NOT inizializated."); + + return (ddMgr); +} + +/**Function******************************************************************** + + Synopsis [Quit a CUDD Manager.] + + Description [Quit a CUDD Manager.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +ManagerQuit ( + DdManager **ddMgrPtr /* IN: CUDD Manager */, + dddmpVarInfo_t *varInfo /* IN: Internal Manager */ + ) +{ + if (*ddMgrPtr == NULL) { + return; + } + + fprintf (stdout, "Quitting CUDD Manager.\n"); + Cudd_Quit (*ddMgrPtr); + *ddMgrPtr = NULL; + + DddmpStrArrayFree (varInfo->rootNames, varInfo->nRoots); + DddmpStrArrayFree (varInfo->suppVarNames, varInfo->nSuppVars); + DddmpStrArrayFree (varInfo->orderedVarNames, varInfo->nVars); + DDDMP_FREE (varInfo->varIds); + DDDMP_FREE (varInfo->varIdsAll); + DDDMP_FREE (varInfo->varComposeIds); + DDDMP_FREE (varInfo->varComposeIdsAll); + DDDMP_FREE (varInfo->varAuxIds); + DDDMP_FREE (varInfo->varAuxIdsAll); + + varInfo->nDdVars = (-1); + varInfo->rootNames = NULL; + varInfo->ddType = DDDMP_NONE; + varInfo->nVars = (-1); + varInfo->nSuppVars = (-1); + varInfo->varNamesFlagUpdate = 1; + varInfo->suppVarNames = NULL; + varInfo->orderedVarNames = NULL; + varInfo->varIdsFlagUpdate = 1; + varInfo->varIds = NULL; + varInfo->varIdsAll = NULL; + varInfo->varComposeIdsFlagUpdate = 1; + varInfo->varComposeIds = NULL; + varInfo->varComposeIdsAll = NULL; + varInfo->varAuxIdsFlagUpdate = 1; + varInfo->varAuxIds = NULL; + varInfo->varAuxIdsAll = NULL; + varInfo->nRoots = (-1); + + return; +} + +/**Function******************************************************************** + + Synopsis [Create a One-BDD Leaf.] + + Description [Create a One-BDD Leaf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +OneCreate( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* In/OUT: Array of operand */ + ) +{ + int i; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_BDD, &i); + + operandBdd[i] = Cudd_ReadOne (ddMgr); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Create a Zero-BDD Leaf.] + + Description [Create a Zero-BDD Leaf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddZeroCreate( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN/OUT: array of operand */ + ) +{ + int i; + DdNode *one = NULL; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_BDD, &i); + + one = Cudd_ReadOne(ddMgr); + operandBdd[i] = Cudd_Not(one); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Create a One-Node BDD.] + + Description [Create a One-Node BDD.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +LeafCreate( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN/OUT: Array of operandBdd */ + ) +{ + int i, j; + DdNode *f = NULL; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_BDD, &i); + ReadInt (DDDMP_MESSAGE_INDEX, &j); + + f = Cudd_bddIthVar (ddMgr, j); + Cudd_Ref(f); + operandBdd[i] = f; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Create a BDD.] + + Description [Create a BDD: Variable index and number of cubes selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddCreate ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* array of operandBdd */ + ) +{ + DdNode **vet, *f, *g, *h; + int nb, nv, vi0, vi1, nc, i, j; + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_BDD, &nb); + + fprintf (stdout, "Variables Index [n-m] (m-n = number of variables): "); + fgets (row, DDDMPTEST_MAX_STRING_LENGTH, stdin); + sscanf (row, "%d-%d", &vi0, &vi1); + nv = vi1-vi0+1; + + ReadInt (DDDMP_MESSAGE_CUBE, &nc); + + /* Leaf Creation */ + vet = DDDMP_ALLOC (DdNode *, nv); + for (i=0; i 0.5 ) { + h = Cudd_bddAnd (ddMgr, g, vet[j]); + } else { + h = Cudd_bddAnd (ddMgr, g, Cudd_Not (vet[j])); + } + Cudd_Ref (h); + Cudd_RecursiveDeref (ddMgr, g); + g = h; + } + h = Cudd_bddOr (ddMgr, f, g); + Cudd_Ref (h); + Cudd_RecursiveDeref (ddMgr, f); + Cudd_RecursiveDeref (ddMgr, g); + f = h; + } + + operandBdd[nb] = f; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Transform a BDD from the ASCII to the Binary format].] + + Description [Input and Output file selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +A2B( + void +) +{ + fprintf (stderr, "Not yet Implemented!!!\n"); + + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Transform a BDD from the Binary to the ASCII format].] + + Description [Input and Output file selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +B2A( + void +) +{ + fprintf (stderr, "Not yet Implemented!!!\n"); + + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Read the Header of a file containing a BDD.] + + Description [File name Selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +HeaderLoadBdd ( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + Dddmp_DecompType ddType; + int retValue, nRoots, nVars, nSuppVars; + int *tmpVarIds = NULL; + int *tmpVarAuxIds = NULL; + int *tmpVarComposeIds = NULL; + char **tmpOrderedVarNames = NULL; + char **tmpSuppVarNames = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + + retValue = Dddmp_cuddHeaderLoad (&ddType, &nVars, &nSuppVars, + &tmpSuppVarNames, &tmpOrderedVarNames, &tmpVarIds, &tmpVarComposeIds, + &tmpVarAuxIds, &nRoots, fileName, NULL); + + if (retValue == DDDMP_FAILURE) { + return (DDDMP_FAILURE); + } + + /*---------------------------- Tail Operations ----------------------------*/ + + CompleteInfoStruct (ddType, nVars, nSuppVars, + tmpSuppVarNames, tmpOrderedVarNames, tmpVarIds, tmpVarComposeIds, + tmpVarAuxIds, nRoots, varInfo); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Read the Header of a file containing a CNF formula.] + + Description [File name Selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +HeaderLoadCnf ( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + int retValue, nRoots, nVars, nSuppVars; + int *tmpVarIds = NULL; + int *tmpVarComposeIds = NULL; + int *tmpVarAuxIds = NULL; + char **tmpOrderedVarNames = NULL; + char **tmpSuppVarNames = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + + retValue = Dddmp_cuddHeaderLoadCnf (&nVars, &nSuppVars, + &tmpSuppVarNames, &tmpOrderedVarNames, &tmpVarIds, &tmpVarComposeIds, + &tmpVarAuxIds, &nRoots, fileName, NULL); + + if (retValue == DDDMP_FAILURE) { + return (DDDMP_FAILURE); + } + + /*---------------------------- Tail Operations ----------------------------*/ + + CompleteInfoStruct (DDDMP_CNF, nVars, nSuppVars, + tmpSuppVarNames, tmpOrderedVarNames, tmpVarIds, tmpVarComposeIds, + tmpVarAuxIds, nRoots, varInfo); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Read the Header of a filke containing a BDD.] + + Description [File name Selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +HeaderWrite( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + int i; + + switch (varInfo->ddType) { + case DDDMP_BDD: + fprintf (stdout, "DD TYPE: DDDMP_BDD\n"); + break; + case DDDMP_ADD: + fprintf (stdout, "DD TYPE: DDDMP_ADD\n"); + break; + case DDDMP_CNF: + fprintf (stdout, "DD TYPE: DDDMP_CNF\n"); + break; + case DDDMP_NONE: + fprintf (stdout, "DD TYPE: NONE - Error\n"); + break; + } + + fprintf (stdout, "Number of variables: %d\n", varInfo->nVars); + fprintf (stdout, "Number of support variables: %d\n", varInfo->nSuppVars); + + if (varInfo->suppVarNames != NULL) { + fprintf (stdout, "suppVarNames: "); + for (i=0; inSuppVars; i++) { + if (varInfo->suppVarNames[i] != NULL) { + fprintf (stdout, "%s ", varInfo->suppVarNames[i]); + } + } + fprintf (stdout, "\n"); + } + + if (varInfo->orderedVarNames != NULL) { + fprintf (stdout, "orderedVarNames: "); + for (i=0; inVars; i++) { + if (varInfo->orderedVarNames[i] != NULL) { + fprintf (stdout, "%s ", varInfo->orderedVarNames[i]); + } + } + fprintf (stdout, "\n"); + } + + if (varInfo->varIds != NULL) { + fprintf (stdout, "varIds: "); + for (i=0; inSuppVars; i++) { + fprintf (stdout, "%d ", varInfo->varIds[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varIdsAll != NULL) { + fprintf (stdout, "varIds for ALL Manager Variables: "); + for (i=0; inVars; i++) { + fprintf (stdout, "%d ", varInfo->varIdsAll[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varComposeIds != NULL) { + fprintf (stdout, "varComposeIds: "); + for (i=0; inSuppVars; i++) { + fprintf (stdout, "%d ", varInfo->varComposeIds[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varComposeIdsAll != NULL) { + fprintf (stdout, "varComposeIds for ALL Manager Variables: "); + for (i=0; inVars; i++) { + fprintf (stdout, "%d ", varInfo->varComposeIdsAll[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varAuxIds != NULL) { + fprintf (stdout, "varAuxIds: "); + for (i=0; inSuppVars; i++) { + fprintf (stdout, "%d ", varInfo->varAuxIds[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varAuxIdsAll != NULL) { + fprintf (stdout, "varAuxIds for ALL Manager Variables: "); + for (i=0; inVars; i++) { + fprintf (stdout, "%d ", varInfo->varAuxIdsAll[i]); + } + fprintf (stdout, "\n"); + } + + fprintf (stdout, "Number of roots: %d\n", varInfo->nRoots); + + fflush (stdout); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Print the Help messages.] + + Description [Print the Help messages.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +Help( + void + ) +{ + fprintf (stdout, "Commands:\n"); + fprintf (stdout, "MAIN\n"); + + fprintf (stdout, "\thelp : Print this set of messages.\n"); + fprintf (stdout, "\tquit : Quit the test program.\n"); + + fprintf (stdout, "MANAGER OPERATIONs\n"); + + fprintf (stdout, + "\thmi : Manager Init (To do BEFORE any BDD/ADD operation).\n"); + fprintf (stdout, "\thmq : Manager Quit.\n"); + + fprintf (stdout, "LOAD\n"); + + fprintf (stdout, "\thlb : Load the header from a BDD/ADD file.\n"); + fprintf (stdout, "\thlc : Load the header from a CNF file.\n"); + fprintf (stdout, "\tbl : Load a BDD from a file.\n"); + fprintf (stdout, "\tbal : Load an Array-BDD from a file.\n"); + fprintf (stdout, "\tal : Load an ADD from a file.\n"); + fprintf (stdout, "\taal : Load an Array-ADD from a file.\n"); + fprintf (stdout, "\tcl : Load a CNF Formula from a file.\n"); + fprintf (stdout, "\tcal : Load an Array of CNF Formulas from a file.\n"); + + fprintf (stdout, "STORE\n"); + + fprintf (stdout, + "\thw : (Header) Write variable information on stdout.\n"); + fprintf (stdout, "\tbs : Store a BDD into a file.\n"); + fprintf (stdout, "\tbas : Store an Array-BDD from a file.\n"); + fprintf (stdout, "\tas : Store an ADD into a file.\n"); + fprintf (stdout, "\taas : Store an Array-ADD into a file.\n"); + fprintf (stdout, "\tcs : Store BDD as a CNF formula.\n"); + fprintf (stdout, "\tcas : Store and Array of BDDs as a CNF formula.\n"); + + fprintf (stdout, "MISC\n"); + + fprintf (stdout, "\tdr : Activate Dynamic Reordering.\n"); + fprintf (stdout, "\tonl : Load the order from a file (varNames).\n"); + fprintf (stdout, "\toil : Load the order from a file (varAuxIds).\n"); + fprintf (stdout, "\tcil : Load compose IDs from a file.\n"); + fprintf (stdout, "\tslm : Set Load matchmode for variables.\n"); + fprintf (stdout, + "\top : Operation (or, and, xor, not, =) between BDDs.\n"); + fprintf (stdout, "\toc : Create a terminal-one BDD.\n"); + fprintf (stdout, "\tzc : Create a terminal-zero BDD.\n"); + fprintf (stdout, "\tlc : Create a single variable BDD (1 node).\n"); + fprintf (stdout, "\tbc : Create a random BDD.\n"); + + fprintf (stdout, "NOT YET IMPLEMENTED\n"); + + fprintf (stdout, + "\ta2b : Convert a file from the ASCII format to the binary one.\n"); + fprintf (stdout, + "\tb2a : Convert a file from the binary format to the ASCII one.\n"); + + fprintf (stdout, "HINT\n"); + + fprintf (stdout, + " Command 'mi' has to be the first instruction to build:\n"); + fprintf (stdout, " a) The CUDD manager.\n"); + fprintf (stdout, + " b) The internal manager (containing name and variable IDs).\n"); + fprintf (stdout, + " After that load an header file with 'hlb' or 'hlc' to have proper\n"); + fprintf (stdout, + " names and ids for each subsequent load/store operation.\n"); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load the BDD order from a file (varNames).] + + Description [Load the BDD order from a file (varNames). + Force the orderedVarNames field of the varInfo structure, + i.e., the local manager, to be stucked to this array of values. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +OrderNamesLoad( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + FILE *fp = NULL; + int i; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + char tmpBuf[DDDMPTEST_MAX_STRING_LENGTH]; + char tmpName[DDDMPTEST_MAX_STRING_LENGTH]; + char **tmpOrderedVarNames = NULL; + + /*------------------------- Red New Var Names Array ----------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + + fp = fopen (fileName, "r"); + Dddmp_CheckAndReturn (fp==NULL, "Cannot open file."); + + varoutinfo = DDDMP_VARNAMES; + tmpOrderedVarNames = DDDMP_ALLOC (char *, varInfo->nDdVars); + + i=0; + while (fgets (tmpBuf, DDDMPTEST_MAX_STRING_LENGTH, fp)!=NULL) { + if (tmpBuf[0]=='#') { + continue; + } + + if (i>=varInfo->nDdVars) { + fprintf (stdout, + "Number of variables in files higher than DD manager vars (%d)\n", + varInfo->nDdVars); + fprintf (stdout, "Exceeding variables ignored\n"); + fprintf (stdout, + "You might increase the DDDMPTEST_MAX_VARIABLE constant\n"); + break; + } + + sscanf (tmpBuf, "%s", tmpName); + tmpOrderedVarNames[i] = DDDMP_ALLOC (char, (strlen (tmpName) + 1)); + if (tmpOrderedVarNames[i]==NULL) { + fprintf (stdout, "Error allocating memory\n"); + } else { + strcpy (tmpOrderedVarNames[i], tmpName); + } + i++; + } + + for ( ;inDdVars; i++) { + tmpOrderedVarNames[i] = NULL; + } + + fclose(fp); + + /*----------------------- Free and Set Var Names Array --------------------*/ + + DddmpStrArrayFree (varInfo->orderedVarNames, varInfo->nVars); + varInfo->orderedVarNames = tmpOrderedVarNames; + varInfo->nVars = varInfo->nDdVars; + + /* DO NOT ALLOW FURTHER UPDATES */ + varInfo->varNamesFlagUpdate = 0; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load the BDD order from a file (varauxids).] + + Description [Load the BDD order from a file (varauxids). + Force the + varAuxIds and varAuxIdsAll + or the + varComposeIds and varComposeIdsAll + fields of the varInfo structure, i.e., the local manager, to be + stucked to this array of values. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +IntArrayLoad ( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */, + const char *mode + ) +{ + FILE *fp = NULL; + int i; + int *tmpArray1 = NULL; + int *tmpArray2 = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + char buf[DDDMPTEST_MAX_STRING_LENGTH]; + + ReadString (DDDMP_MESSAGE_FILE, fileName); + + fp = fopen(fileName, "r"); + Dddmp_CheckAndReturn (fp==NULL, "Cannot open file."); + + tmpArray1 = DDDMP_ALLOC (int, varInfo->nDdVars); + tmpArray2 = DDDMP_ALLOC (int, varInfo->nDdVars); + Dddmp_CheckAndReturn (tmpArray1==NULL, "Error allocating memory."); + Dddmp_CheckAndReturn (tmpArray2==NULL, "Error allocating memory."); + + i=0; + while (fgets(buf, DDDMPTEST_MAX_STRING_LENGTH, fp)!=NULL) { + if (buf[0]=='#') { + continue; + } + if (i>=varInfo->nDdVars) { + fprintf (stdout, + "Number of variables in files higher than DD manager vars (%d)\n", + varInfo->nDdVars); + fprintf (stdout, "Exceeding variables ignored.\n"); + fprintf (stdout, "(Increase the DDDMPTEST_MAX_VARIABLE constant.)\n"); + break; + } + sscanf(buf, "%d", &tmpArray1[i]); + sscanf(buf, "%d", &tmpArray2[i++]); + } + + for (;inDdVars;i++) { + tmpArray1[i]= -1; + tmpArray2[i]= -1; + } + + fclose(fp); + + if (strcmp (mode, "oil") == 0) { + varInfo->varAuxIds = tmpArray1; + varInfo->varAuxIdsAll = tmpArray2; + + /* DO NOT ALLOW FURTHER UPDATES */ + varInfo->varAuxIdsFlagUpdate = 0; + } else { + if (strcmp (mode, "cil") == 0) { + varInfo->varComposeIds = tmpArray1; + varInfo->varComposeIdsAll = tmpArray2; + + /* DO NOT ALLOW FURTHER UPDATES */ + varInfo->varComposeIdsFlagUpdate = 0; + } + } + + varInfo->nVars = varInfo->nDdVars; + varInfo->nSuppVars = varInfo->nDdVars; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load a BDD from a file.] + + Description [Load a BDD from a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddLoad ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN: Operand BDD */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode *f = NULL; + int i; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD, &i); + + /*-------------------------------- Load BDD -------------------------------*/ + + fprintf (stdout, "Loading %s ...\n", fileName); + + f = Dddmp_cuddBddLoad (ddMgr, varmatchmode, varInfo->orderedVarNames, + varInfo->varIdsAll, varInfo->varComposeIdsAll, DDDMP_MODE_DEFAULT, + fileName, NULL); + + if (f==NULL) { + fprintf (stderr, "Dddmp Test Error : %s is not loaded from file\n", + fileName); + } else { + operandBdd[i] = f; + } + + /*---------------------------- Tail Operations ----------------------------*/ + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load an array of BDDs from a file.] + + Description [Load an array of BDDs from a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddArrayLoad( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand BDD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode **bddArray = NULL; + int i, j, nRoots; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + /*---------------------------- Load BDDs ----------------------------------*/ + + nRoots = Dddmp_cuddBddArrayLoad (ddMgr, rootmatchmode, + varInfo->rootNames, varmatchmode, + varInfo->orderedVarNames, varInfo->varIdsAll, varInfo->varComposeIdsAll, + DDDMP_MODE_DEFAULT, fileName, NULL, &bddArray); + + Dddmp_CheckAndReturn (nRoots>DDDMP_MAX_BDDARRAY_LEN, + "DDDMP_MAX_BDDARRAY_LEN exceeded by BDD array len (increase it)."); + + if (nRoots<=0) { + return (DDDMP_FAILURE); + } + + varInfo->nRoots = nRoots; + operandBddArray[i] = DDDMP_ALLOC (DdNode *, nRoots); + Dddmp_CheckAndReturn (operandBddArray[i]==NULL, "Allocation error."); + + for (j=0; jorderedVarNames, + varInfo->varIdsAll, varInfo->varComposeIdsAll, DDDMP_MODE_DEFAULT, + fileName, NULL); + + if (f==NULL) { + fprintf (stderr, "Dddmp Test Error : %s is not loaded from file\n", + fileName); + } else { + operandBdd[i] = f; + } + + /*---------------------------- Tail Operations ----------------------------*/ + + fprintf (stdout, "Load:\n"); + Cudd_PrintMinterm (ddMgr, f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load an array of ADDs from a file.] + + Description [Load an array of ADDs from a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +AddArrayLoad( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand BDD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + int i, j, nRoots; + DdNode **bddArray = NULL; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + /*------------------------------- Load ADDs -------------------------------*/ + + nRoots = Dddmp_cuddAddArrayLoad (ddMgr, rootmatchmode, + varInfo->rootNames, varmatchmode, + varInfo->orderedVarNames, varInfo->varIdsAll, varInfo->varComposeIdsAll, + DDDMP_MODE_DEFAULT, fileName, NULL, &bddArray); + + Dddmp_CheckAndReturn (nRoots>DDDMP_MAX_BDDARRAY_LEN, + "DDDMP_MAX_BDDARRAY_LEN exceeded by BDD array len (increase it)."); + + if (nRoots<=0) { + return (DDDMP_FAILURE); + } + + varInfo->nRoots = nRoots; + operandBddArray[i] = DDDMP_ALLOC (DdNode *, nRoots); + Dddmp_CheckAndReturn (operandBddArray[i]==NULL, "Allocation error."); + + for (j=0; jorderedVarNames, varInfo->varAuxIdsAll, varInfo->varComposeIdsAll, + loadingMode, fileName, NULL, &rootsPtr, &nRoots); + + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "Dddmp Test: Load From File Error.\n", failure); + + operandBdd[i] = rootsPtr[0]; + + /*---------------------------- Tail Operations ----------------------------*/ + + /* Free array */ + DDDMP_FREE (rootsPtr); + + return (DDDMP_SUCCESS); + + failure: + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Load a CNF formula from a file, and create an array of + BDDs. + ] + + Description [Load a CNF formula from a file, and create an array of + BDDs. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddArrayLoadCnf ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand BDD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode **rootsPtr = NULL; + Dddmp_DecompCnfLoadType loadingMode = DDDMP_CNF_MODE_CONJ_QUANT; + int i, j, nRoots, retValue; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + /*--------------------------- Loading BDDs --------------------------------*/ + + retValue = Dddmp_cuddBddArrayLoadCnf (ddMgr, rootmatchmode, + varInfo->rootNames, varmatchmode, + varInfo->orderedVarNames, varInfo->varIdsAll, varInfo->varComposeIdsAll, + loadingMode, fileName, NULL, &rootsPtr, &nRoots); + + Dddmp_CheckAndReturn (nRoots>DDDMP_MAX_BDDARRAY_LEN, + "DDDMP_MAX_BDDARRAY_LEN exceeded by BDD array len (increase it)."); + + if (nRoots<=0) { + return (DDDMP_FAILURE); + } + + varInfo->nRoots = nRoots; + operandBddArray[i] = DDDMP_ALLOC (DdNode *, nRoots); + Dddmp_CheckAndReturn (operandBddArray[i]==NULL, "Allocation error."); + + for (j=0; jorderedVarNames, + varInfo->varAuxIdsAll, DDDMP_MODE_TEXT, varoutinfo, fileName, NULL); + + Dddmp_CheckAndGotoLabel (retValue!=DDDMP_SUCCESS, "BDD NOT stored.", + failure); + + return (DDDMP_SUCCESS); + + failure: + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Store an Array of BDD in a file.] + + Description [Store an Array of BDD in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddArrayStore ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand BDD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + int i, retValue, nRoots; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + nRoots = operandBddArraySize[i]; + + /*----------------------------- Store BDDs -------------------------------*/ + + fprintf (stdout, "Storing Array of BDDs in file %s ...\n", fileName); + fflush (stdout); + + retValue = Dddmp_cuddBddArrayStore (ddMgr, NULL, nRoots, operandBddArray[i], + NULL, varInfo->orderedVarNames, varInfo->varAuxIdsAll, DDDMP_MODE_TEXT, + DDDMP_VARIDS, fileName, NULL); + + Dddmp_CheckAndGotoLabel (retValue!=DDDMP_SUCCESS, "BDD NOT stored.", + failure); + fprintf (stdout, "done.\n"); + + return (DDDMP_SUCCESS); + + failure: + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Store an ADD in a file.] + + Description [Store an ADD in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +AddStore( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN: operand Bdd */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode *f; + int i, retValue; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD, &i); + + fprintf (stdout, "Storing %s ...\n", fileName); + fflush (stdout); + f = operandBdd[i]; + +#if 0 + /* StQ Patch - CREATE temporary ADD to Store */ + f = Cudd_addResidue (ddMgr, 4, 3, 1, 1); + fprintf (stderr, "Store:\n"); + Cudd_PrintMinterm (ddMgr, f); + /* end ... StQ Patch */ +#endif + + retValue = Dddmp_cuddAddStore (ddMgr, NULL, f, varInfo->orderedVarNames, + varInfo->varAuxIdsAll, DDDMP_MODE_TEXT, varoutinfo, fileName, NULL); + + Dddmp_CheckAndReturn (retValue!=DDDMP_SUCCESS, "BDD NOT stored."); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Store a BDD in a file.] + + Description [Store a BDD in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +AddArrayStore ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand ADD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo + ) +{ + int i, retValue, nRoots; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + nRoots = operandBddArraySize[i]; + + fprintf (stdout, "Storing Array of BDDs in file %s ...\n", fileName); + fflush (stdout); + + retValue = Dddmp_cuddAddArrayStore (ddMgr, NULL, nRoots, operandBddArray[i], + NULL, varInfo->orderedVarNames, varInfo->varAuxIdsAll, DDDMP_MODE_TEXT, + DDDMP_VARIDS, fileName, NULL); + + Dddmp_CheckAndReturn (retValue!=DDDMP_SUCCESS, "BDD NOT stored."); + + fprintf (stdout, "done.\n"); + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Store a BDD as CNF format in a file.] + + Description [Store a BDD as CNF format in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddStoreCnf( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN: Array of operand ADD */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode *f = NULL; + Dddmp_DecompCnfStoreType storingMode = DDDMP_CNF_MODE_BEST; + int noHeader = 0; + int i, nVars, retValue, idInitial, varNewN, clauseNewN; + int edgeInTh = (-1); + int pathLengthTh = (-1); + int *tmpBddIds = NULL; + int *tmpCnfIds = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD, &i); + ReadString (DDDMP_MESSAGE_FORMAT, row); + + switch (row[0]) { + case 'N': + storingMode = DDDMP_CNF_MODE_NODE; + break; + case 'M': + storingMode = DDDMP_CNF_MODE_MAXTERM; + break; + case 'B': + storingMode = DDDMP_CNF_MODE_BEST; + ReadInt (DDDMP_MESSAGE_EDGE_MAX, &edgeInTh); + ReadInt (DDDMP_MESSAGE_LENGHT_MAX, &pathLengthTh); + break; + } + ReadInt (DDDMP_MESSAGE_I_ID, &idInitial); + + fprintf (stdout, "Storing %s ...\n", fileName); + fflush (stdout); + + f = operandBdd[i]; + + nVars = varInfo->nDdVars; + + /*------------ From BDD and CNF ids to Proper Array of ids ----------------*/ + + tmpBddIds = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (tmpBddIds==NULL, "Error allocating memory.", + failure); + tmpCnfIds = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (tmpBddIds==NULL, "Error allocating memory.", + failure); + + for (i=0; iorderedVarNames, tmpBddIds, NULL, tmpCnfIds, idInitial, + edgeInTh, pathLengthTh, fileName, NULL, &clauseNewN, &varNewN); + + Dddmp_CheckAndGotoLabel (retValue!=DDDMP_SUCCESS, "BDD NOT stored.", + failure); + + fprintf (stdout, "Number of Clauses Stored = %d\n", clauseNewN); + fprintf (stdout, "Number of New Variable Created Storing = %d\n", + varNewN); + fflush (stdout); + + DDDMP_FREE (tmpBddIds); + DDDMP_FREE (tmpCnfIds); + + return (DDDMP_SUCCESS); + + failure: + DDDMP_FREE (tmpBddIds); + DDDMP_FREE (tmpCnfIds); + + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Store a BDD as CNF format in a file.] + + Description [Store a BDD as CNF format in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddArrayStoreCnf( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand ADD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + Dddmp_DecompCnfStoreType storingMode = DDDMP_CNF_MODE_BEST; + int noHeader = 0; + int i, nVars, bddN, retValue, idInitial, varNewN, clauseNewN; + int edgeInTh = (-1); + int pathLengthTh = (-1); + int *tmpBddIds = NULL; + int *tmpCnfIds = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &bddN); + ReadString (DDDMP_MESSAGE_FORMAT, row); + switch (row[0]) { + case 'N': + storingMode = DDDMP_CNF_MODE_NODE; + break; + case 'M': + storingMode = DDDMP_CNF_MODE_MAXTERM; + break; + case 'B': + storingMode = DDDMP_CNF_MODE_BEST; + ReadInt (DDDMP_MESSAGE_EDGE_MAX, &edgeInTh); + ReadInt (DDDMP_MESSAGE_LENGHT_MAX, &pathLengthTh); + break; + } + ReadInt (DDDMP_MESSAGE_I_ID, &idInitial); + + nVars = varInfo->nDdVars; + + /*------------ From BDD and CNF ids to Proper Array of ids ----------------*/ + + tmpBddIds = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (tmpBddIds==NULL, "Allocation error."); + tmpCnfIds = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (tmpCnfIds==NULL, "Allocation error."); + + for (i=0; iorderedVarNames, + tmpBddIds, NULL, tmpCnfIds, idInitial, edgeInTh, pathLengthTh, fileName, + NULL, &varNewN, &clauseNewN); + + Dddmp_CheckAndGotoLabel (retValue!=DDDMP_SUCCESS, "BDD NOT stored.", + failure); + + fprintf (stdout, "Number of Clauses Stored = %d\n", clauseNewN); + fprintf (stdout, "Number of New Variable Created Storing = %d\n", + varNewN); + fflush (stdout); + + DDDMP_FREE (tmpBddIds); + DDDMP_FREE (tmpCnfIds); + + return (DDDMP_SUCCESS); + + failure: + DDDMP_FREE (tmpBddIds); + DDDMP_FREE (tmpCnfIds); + + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Dynamic Reordering BDDs.] + + Description [Dynamic Reordering BDDs using one of the allowed CUDD + methods.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DynamicReordering ( + DdManager *ddMgr /* IN: CUDD Manager */ + ) +{ + Cudd_ReorderingType approach = CUDD_REORDER_SIFT; + int method; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_REORDERING, &method); + approach = (Cudd_ReorderingType) method; + + Cudd_ReduceHeap (ddMgr, approach, 5); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Selects variable matching mode.] + + Description [Selects variable matching mode.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +SetLoadMatchmode ( + ) +{ + int sel; + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + fprintf (stdout, "Variable matchmode:\n"); + fprintf (stdout, "Match IDs (1)\n"); + fprintf (stdout, "Match permIDs (2)\n"); + fprintf (stdout, "Match names (must have been loaded) (3)\n"); + fprintf (stdout, "Match auxids (must have been loaded) (4)\n"); + fprintf (stdout, "Match composeids (must have been loaded) (5)\n"); + fprintf (stdout, "Your choice: "); + fflush (stdout); + + fgets (row, DDDMPTEST_MAX_STRING_LENGTH, stdin); + sscanf (row, "%d", &sel); + + switch (sel) { + case 1: + varmatchmode = DDDMP_VAR_MATCHIDS; + break; + case 2: + varmatchmode = DDDMP_VAR_MATCHPERMIDS; + break; + case 3: + varmatchmode = DDDMP_VAR_MATCHNAMES; + break; + case 4: + varmatchmode = DDDMP_VAR_MATCHAUXIDS; + break; + case 5: + varmatchmode = DDDMP_VAR_COMPOSEIDS; + break; + default: + fprintf (stderr, "Wrong choice!\n"); + break; + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Complete the internal manager structure for subsequent + BDD/ADD/CNF operations. + ] + + Description [Complete the internal manager structure for subsequent + BDD/ADD/CNF operations. + The phylosophy is simple: to have proper names and ids it is necessary + to load an header before each actual load/store operation. + An header load should initialize variable names, variable ids, + variable compose ids, and variable auxiliary ids for all variables + stored in the file. + This information has to be extended for all variables in the + *current* CUDD manager (before any store operation). + CompleteInfoStruct does this job. + Arrays varIds, varComposeIds, and varAuxIds contain information for + all the variable in the BDD/ADD/CNF while arrays varIdsAll, + varComposeIdsAll, and varAuxIdsAll contain information for *all* + variable in the current CUDD manager. + ] + + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +CompleteInfoStruct ( + Dddmp_DecompType ddType /* IN: selects the proper decomp type */, + int nVars /* IN: number of DD variables */, + int nSuppVars /* IN: number of support variables */, + char **suppVarNames /* IN: array of support variable names */, + char **orderedVarNames /* IN: array of variable names */, + int *varIds /* IN: array of variable ids */, + int *varComposeIds /* IN: array of permids ids */, + int *varAuxIds /* IN: array of variable aux ids */, + int nRoots /* IN: number of root in the file */, + dddmpVarInfo_t *varInfo /* IN: Variable Information */ + ) +{ + int i; + char tmpString[DDDMPTEST_MAX_STRING_LENGTH]; + + /*------------------------- Updates Variable Names ------------------------*/ + + DddmpStrArrayFree (varInfo->suppVarNames, varInfo->nSuppVars); + varInfo->suppVarNames = suppVarNames; + + if (varInfo->varNamesFlagUpdate == 1) { + + DddmpStrArrayFree (varInfo->orderedVarNames, varInfo->nVars); + + if (orderedVarNames != NULL) { + varInfo->orderedVarNames = orderedVarNames; + } else { + varInfo->orderedVarNames = DDDMP_ALLOC (char *, nVars); + Dddmp_CheckAndReturn (varInfo->orderedVarNames==NULL, + "Allocation error."); + + for (i=0; iorderedVarNames[i] = NULL; + } + + if (varInfo->suppVarNames != NULL) { + for (i=0; iorderedVarNames[i] = DDDMP_ALLOC (char, + (strlen (varInfo->suppVarNames[i]) + 1)); + strcpy (varInfo->orderedVarNames[i], varInfo->suppVarNames[i]); + } + } + + for (i=0; iorderedVarNames[i] == NULL) { + sprintf (tmpString, "DUMMY%d", i); + varInfo->orderedVarNames[i] = DDDMP_ALLOC (char, + (strlen (tmpString) + 1)); + strcpy (varInfo->orderedVarNames[i], tmpString); + } + } + } + } + + /*------------------------------ Updates IDs ------------------------------*/ + + DDDMP_FREE (varInfo->varIds); + varInfo->varIds = varIds; + + if (varInfo->varIdsFlagUpdate == 1) { + + /* Free Previously Allocated Memory */ + DDDMP_FREE (varInfo->varIdsAll); + + /* Allocate New Memory and Check */ + varInfo->varIdsAll = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (varInfo->varIdsAll==NULL, "Allocation error."); + + /* Set New Values */ + for (i=0; ivarIdsAll[i] = (-1); + } + + if (varInfo->varIds != NULL) { + for (i=0; ivarIdsAll[varInfo->varIds[i]] = varInfo->varIds[i]; + } + } + } + + + /*-------------------------- Updates Compose IDs --------------------------*/ + + DDDMP_FREE (varInfo->varComposeIds); + varInfo->varComposeIds = varComposeIds; + + if (varInfo->varComposeIdsFlagUpdate == 1) { + + /* Free Previously Allocated Memory */ + DDDMP_FREE (varInfo->varComposeIdsAll); + + /* Allocate New Memory and Check */ + varInfo->varComposeIdsAll = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (varInfo->varComposeIdsAll==NULL, + "Allocation error."); + + /* Set New Values */ + for (i=0; ivarComposeIdsAll[i] = (-1); + } + + if (varInfo->varComposeIds != NULL) { + for (i=0; ivarComposeIdsAll[varInfo->varIds[i]] = + varInfo->varComposeIds[i]; + } + } + } + + /*------------------------- Updates Auxiliary IDs -------------------------*/ + + DDDMP_FREE (varInfo->varAuxIds); + varInfo->varAuxIds = varAuxIds; + + if (varInfo->varAuxIdsFlagUpdate == 1) { + + /* Free Previously Allocated Memory */ + DDDMP_FREE (varInfo->varAuxIdsAll); + + /* Allocate New Memory and Check */ + varInfo->varAuxIdsAll = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (varInfo->varAuxIdsAll==NULL, "Allocation error."); + + /* Set New Values */ + for (i=0; ivarAuxIdsAll[i] = (-1); + } + + if (varInfo->varAuxIds != NULL) { + for (i=0; ivarAuxIdsAll[varInfo->varIds[i]] = varInfo->varAuxIds[i]; + } + } + } + + /*----------------------------- Updates Sizes -----------------------------*/ + + varInfo->ddType = ddType; + varInfo->nVars = nVars; + varInfo->nSuppVars = nSuppVars; + Dddmp_CheckAndReturn (varInfo->nDdVarsnVars, + "Local Manager with Not Enough Variables."); + varInfo->nRoots = nRoots; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Reads an integer value from standard input.] + + Description [Reads an integer value from standard input.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +ReadInt ( + Dddmp_MessageType message, + int *i + ) +{ + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + switch (message) { + case DDDMP_MESSAGE_MANAGER_VAR: + fprintf (stdout, "Number of Variables: "); + break; + case DDDMP_MESSAGE_BDD: + fprintf (stdout, "Which BDDs [0..%d]: ", + DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_BDD_ARRAY: + fprintf (stdout, "Which Array of BDDs [0..%d]: ", + DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_CUBE: + fprintf (stdout, "How many cubes [1..]: "); + break; + case DDDMP_MESSAGE_INDEX: + fprintf (stdout, "Index: "); + break; + case DDDMP_MESSAGE_SOURCE1: + fprintf (stdout, "Source1 [0..%d]: ", DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_SOURCE2: + fprintf (stdout, "Source2 [0..%d]: ", DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_DESTINATION: + fprintf (stdout, "Destination [0..%d]: ", DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_I_ID: + fprintf (stdout, "Initial ID : "); + break; + case DDDMP_MESSAGE_EDGE_MAX: + fprintf (stdout, + "Max Number of Edges (Insert cut-point from there on) : "); + break; + case DDDMP_MESSAGE_LENGHT_MAX: + fprintf (stdout, + "Max BDD-Path Length (Insert cut-point from there on) : "); + break; + case DDDMP_MESSAGE_REORDERING: + fprintf (stdout, "Reordering Approach (1..17): "); + break; + default: + fprintf (stdout, "Input Generic Integer: "); + break; + } + fflush (stdout); + + fgets (row, DDDMPTEST_MAX_STRING_LENGTH, stdin); + sscanf (row, "%d", i); + fflush (stdin); + + return; +} + + +/**Function******************************************************************** + + Synopsis [Reads a string from standard input.] + + Description [Reads a string from standard input.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +ReadString ( + Dddmp_MessageType message, + char string[] + ) +{ + char localString[DDDMPTEST_MAX_STRING_LENGTH]; + + switch (message) { + case DDDMP_MESSAGE_PROMPT: + fprintf (stdout, "TestDddmp> "); + break; + case DDDMP_MESSAGE_FILE: + fprintf (stdout, "File : "); + break; + case DDDMP_MESSAGE_OP: + fprintf (stdout, "Operation [or,and,xor,!,buf(=)] : "); + break; + case DDDMP_MESSAGE_FORMAT: + fprintf (stdout, "Format (Node=N, Maxterm=M, Best=B) : "); + break; + default: + fprintf (stdout, "Input Generic String : "); + break; + } + fflush (stdout); + + fgets (localString, DDDMPTEST_MAX_STRING_LENGTH, stdin); + sscanf (localString, "%s", string); + fflush (stdin); + + return; +} + + + + diff --git a/resources/3rdparty/cudd-2.5.0/epd/Makefile b/resources/3rdparty/cudd-2.5.0/epd/Makefile new file mode 100644 index 000000000..3b26bc9a9 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/epd/Makefile @@ -0,0 +1,64 @@ +# $Id$ +# +# epd -- extended precision +#--------------------------------------------------------------------------- +.SUFFIXES: .c .o .u + +CC = gcc +RANLIB = ranlib + +MFLAG = +ICFLAGS = -g -O6 -Wall +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) + +LINTFLAGS = -u -n + +# this is to create the lint library +LINTSWITCH = -o + +P = epd +PSRC = epd.c +PHDR = epd.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) + +WHERE = .. +INCLUDE = $(WHERE)/include + +#--------------------------- + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PSRC) $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +clean: + rm -f *.o *.u .pure *.warnings + +distclean: clean + rm -f lib*.a lib$(P).b llib-l$(P).ln tags *~ *.bak *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/epd/epd.c b/resources/3rdparty/cudd-2.5.0/epd/epd.c new file mode 100644 index 000000000..14f314fab --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/epd/epd.c @@ -0,0 +1,1344 @@ +/**CFile*********************************************************************** + + FileName [epd.c] + + PackageName [epd] + + Synopsis [Arithmetic functions with extended double precision.] + + Description [] + + SeeAlso [] + + Author [In-Ho Moon] + + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: epd.c,v 1.10 2004/08/13 18:20:30 fabio Exp $] + +******************************************************************************/ + +#include +#include +#include +#include +#include "util.h" +#include "epd.h" + + +/**Function******************************************************************** + + Synopsis [Allocates an EpDouble struct.] + + Description [Allocates an EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +EpDouble * +EpdAlloc(void) +{ + EpDouble *epd; + + epd = ALLOC(EpDouble, 1); + return(epd); +} + + +/**Function******************************************************************** + + Synopsis [Compares two EpDouble struct.] + + Description [Compares two EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdCmp(const char *key1, const char *key2) +{ + EpDouble *epd1 = (EpDouble *) key1; + EpDouble *epd2 = (EpDouble *) key2; + if (epd1->type.value != epd2->type.value || + epd1->exponent != epd2->exponent) { + return(1); + } + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Frees an EpDouble struct.] + + Description [Frees an EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdFree(EpDouble *epd) +{ + FREE(epd); +} + + +/**Function******************************************************************** + + Synopsis [Converts an arbitrary precision double value to a string.] + + Description [Converts an arbitrary precision double value to a string.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdGetString(EpDouble *epd, char *str) +{ + double value; + int exponent; + char *pos; + + if (IsNanDouble(epd->type.value)) { + sprintf(str, "NaN"); + return; + } else if (IsInfDouble(epd->type.value)) { + if (epd->type.bits.sign == 1) + sprintf(str, "-Inf"); + else + sprintf(str, "Inf"); + return; + } + + assert(epd->type.bits.exponent == EPD_MAX_BIN || + epd->type.bits.exponent == 0); + + EpdGetValueAndDecimalExponent(epd, &value, &exponent); + sprintf(str, "%e", value); + pos = strstr(str, "e"); + if (exponent >= 0) { + if (exponent < 10) + sprintf(pos + 1, "+0%d", exponent); + else + sprintf(pos + 1, "+%d", exponent); + } else { + exponent *= -1; + if (exponent < 10) + sprintf(pos + 1, "-0%d", exponent); + else + sprintf(pos + 1, "-%d", exponent); + } +} + + +/**Function******************************************************************** + + Synopsis [Converts double to EpDouble struct.] + + Description [Converts double to EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdConvert(double value, EpDouble *epd) +{ + epd->type.value = value; + epd->exponent = 0; + EpdNormalize(epd); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply(EpDouble *epd1, double value) +{ + EpDouble epd2; + double tmp; + int exponent; + + if (EpdIsNan(epd1) || IsNanDouble(value)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || IsInfDouble(value)) { + int sign; + + EpdConvert(value, &epd2); + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + EpdMakeInf(epd1, sign); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + + EpdConvert(value, &epd2); + tmp = epd1->type.value * epd2.type.value; + exponent = epd1->exponent + epd2.exponent; + epd1->type.value = tmp; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply2(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd1, sign); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + value = epd1->type.value * epd2->type.value; + exponent = epd1->exponent + epd2->exponent; + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply2Decimal(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd1, sign); + return; + } + + value = epd1->type.value * epd2->type.value; + exponent = epd1->exponent + epd2->exponent; + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalizeDecimal(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd3, sign); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + epd3->type.value = epd1->type.value * epd2->type.value; + epd3->exponent = epd1->exponent + epd2->exponent; + EpdNormalize(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply3Decimal(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd3, sign); + return; + } + + epd3->type.value = epd1->type.value * epd2->type.value; + epd3->exponent = epd1->exponent + epd2->exponent; + EpdNormalizeDecimal(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Divides two arbitrary precision double values.] + + Description [Divides two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdDivide(EpDouble *epd1, double value) +{ + EpDouble epd2; + double tmp; + int exponent; + + if (EpdIsNan(epd1) || IsNanDouble(value)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || IsInfDouble(value)) { + int sign; + + EpdConvert(value, &epd2); + if (EpdIsInf(epd1) && IsInfDouble(value)) { + EpdMakeNan(epd1); + } else if (EpdIsInf(epd1)) { + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + EpdMakeInf(epd1, sign); + } else { + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + EpdMakeZero(epd1, sign); + } + return; + } + + if (value == 0.0) { + EpdMakeNan(epd1); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + + EpdConvert(value, &epd2); + tmp = epd1->type.value / epd2.type.value; + exponent = epd1->exponent - epd2.exponent; + epd1->type.value = tmp; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Divides two arbitrary precision double values.] + + Description [Divides two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdDivide2(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + EpdMakeNan(epd1); + } else if (EpdIsInf(epd1)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd1, sign); + } else { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeZero(epd1, sign); + } + return; + } + + if (epd2->type.value == 0.0) { + EpdMakeNan(epd1); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + value = epd1->type.value / epd2->type.value; + exponent = epd1->exponent - epd2->exponent; + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Divides two arbitrary precision double values.] + + Description [Divides two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdDivide3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd3); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + EpdMakeNan(epd3); + } else if (EpdIsInf(epd1)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd3, sign); + } else { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeZero(epd3, sign); + } + return; + } + + if (epd2->type.value == 0.0) { + EpdMakeNan(epd3); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + epd3->type.value = epd1->type.value / epd2->type.value; + epd3->exponent = epd1->exponent - epd2->exponent; + EpdNormalize(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Adds two arbitrary precision double values.] + + Description [Adds two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdAdd(EpDouble *epd1, double value) +{ + EpDouble epd2; + double tmp; + int exponent, diff; + + if (EpdIsNan(epd1) || IsNanDouble(value)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || IsInfDouble(value)) { + int sign; + + EpdConvert(value, &epd2); + if (EpdIsInf(epd1) && IsInfDouble(value)) { + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + if (sign == 1) + EpdMakeNan(epd1); + } else if (EpdIsInf(&epd2)) { + EpdCopy(&epd2, epd1); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + + EpdConvert(value, &epd2); + if (epd1->exponent > epd2.exponent) { + diff = epd1->exponent - epd2.exponent; + if (diff <= EPD_MAX_BIN) + tmp = epd1->type.value + epd2.type.value / pow((double)2.0, (double)diff); + else + tmp = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2.exponent) { + diff = epd2.exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) + tmp = epd1->type.value / pow((double)2.0, (double)diff) + epd2.type.value; + else + tmp = epd2.type.value; + exponent = epd2.exponent; + } else { + tmp = epd1->type.value + epd2.type.value; + exponent = epd1->exponent; + } + epd1->type.value = tmp; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Adds two arbitrary precision double values.] + + Description [Adds two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdAdd2(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent, diff; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + if (sign == 1) + EpdMakeNan(epd1); + } else if (EpdIsInf(epd2)) { + EpdCopy(epd2, epd1); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + if (epd1->exponent > epd2->exponent) { + diff = epd1->exponent - epd2->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value + + epd2->type.value / pow((double)2.0, (double)diff); + } else + value = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2->exponent) { + diff = epd2->exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value / pow((double)2.0, (double)diff) + + epd2->type.value; + } else + value = epd2->type.value; + exponent = epd2->exponent; + } else { + value = epd1->type.value + epd2->type.value; + exponent = epd1->exponent; + } + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Adds two arbitrary precision double values.] + + Description [Adds two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + double value; + int exponent, diff; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd3); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + if (sign == 1) + EpdMakeNan(epd3); + else + EpdCopy(epd1, epd3); + } else if (EpdIsInf(epd1)) { + EpdCopy(epd1, epd3); + } else { + EpdCopy(epd2, epd3); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + if (epd1->exponent > epd2->exponent) { + diff = epd1->exponent - epd2->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value + + epd2->type.value / pow((double)2.0, (double)diff); + } else + value = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2->exponent) { + diff = epd2->exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value / pow((double)2.0, (double)diff) + + epd2->type.value; + } else + value = epd2->type.value; + exponent = epd2->exponent; + } else { + value = epd1->type.value + epd2->type.value; + exponent = epd1->exponent; + } + epd3->type.value = value; + epd3->exponent = exponent; + EpdNormalize(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Subtracts two arbitrary precision double values.] + + Description [Subtracts two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdSubtract(EpDouble *epd1, double value) +{ + EpDouble epd2; + double tmp; + int exponent, diff; + + if (EpdIsNan(epd1) || IsNanDouble(value)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || IsInfDouble(value)) { + int sign; + + EpdConvert(value, &epd2); + if (EpdIsInf(epd1) && IsInfDouble(value)) { + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + if (sign == 0) + EpdMakeNan(epd1); + } else if (EpdIsInf(&epd2)) { + EpdCopy(&epd2, epd1); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + + EpdConvert(value, &epd2); + if (epd1->exponent > epd2.exponent) { + diff = epd1->exponent - epd2.exponent; + if (diff <= EPD_MAX_BIN) + tmp = epd1->type.value - epd2.type.value / pow((double)2.0, (double)diff); + else + tmp = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2.exponent) { + diff = epd2.exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) + tmp = epd1->type.value / pow((double)2.0, (double)diff) - epd2.type.value; + else + tmp = epd2.type.value * (double)(-1.0); + exponent = epd2.exponent; + } else { + tmp = epd1->type.value - epd2.type.value; + exponent = epd1->exponent; + } + epd1->type.value = tmp; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Subtracts two arbitrary precision double values.] + + Description [Subtracts two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdSubtract2(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent, diff; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + if (sign == 0) + EpdMakeNan(epd1); + } else if (EpdIsInf(epd2)) { + EpdCopy(epd2, epd1); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + if (epd1->exponent > epd2->exponent) { + diff = epd1->exponent - epd2->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value - + epd2->type.value / pow((double)2.0, (double)diff); + } else + value = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2->exponent) { + diff = epd2->exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value / pow((double)2.0, (double)diff) - + epd2->type.value; + } else + value = epd2->type.value * (double)(-1.0); + exponent = epd2->exponent; + } else { + value = epd1->type.value - epd2->type.value; + exponent = epd1->exponent; + } + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Subtracts two arbitrary precision double values.] + + Description [Subtracts two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + double value; + int exponent, diff; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd3); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + if (sign == 0) + EpdCopy(epd1, epd3); + else + EpdMakeNan(epd3); + } else if (EpdIsInf(epd1)) { + EpdCopy(epd1, epd1); + } else { + sign = epd2->type.bits.sign ^ 0x1; + EpdMakeInf(epd3, sign); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + if (epd1->exponent > epd2->exponent) { + diff = epd1->exponent - epd2->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value - + epd2->type.value / pow((double)2.0, (double)diff); + } else + value = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2->exponent) { + diff = epd2->exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value / pow((double)2.0, (double)diff) - + epd2->type.value; + } else + value = epd2->type.value * (double)(-1.0); + exponent = epd2->exponent; + } else { + value = epd1->type.value - epd2->type.value; + exponent = epd1->exponent; + } + epd3->type.value = value; + epd3->exponent = exponent; + EpdNormalize(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Computes arbitrary precision pow of base 2.] + + Description [Computes arbitrary precision pow of base 2.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdPow2(int n, EpDouble *epd) +{ + if (n <= EPD_MAX_BIN) { + EpdConvert(pow((double)2.0, (double)n), epd); + } else { + EpDouble epd1, epd2; + int n1, n2; + + n1 = n / 2; + n2 = n - n1; + EpdPow2(n1, &epd1); + EpdPow2(n2, &epd2); + EpdMultiply3(&epd1, &epd2, epd); + } +} + + +/**Function******************************************************************** + + Synopsis [Computes arbitrary precision pow of base 2.] + + Description [Computes arbitrary precision pow of base 2.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdPow2Decimal(int n, EpDouble *epd) +{ + if (n <= EPD_MAX_BIN) { + epd->type.value = pow((double)2.0, (double)n); + epd->exponent = 0; + EpdNormalizeDecimal(epd); + } else { + EpDouble epd1, epd2; + int n1, n2; + + n1 = n / 2; + n2 = n - n1; + EpdPow2Decimal(n1, &epd1); + EpdPow2Decimal(n2, &epd2); + EpdMultiply3Decimal(&epd1, &epd2, epd); + } +} + + +/**Function******************************************************************** + + Synopsis [Normalize an arbitrary precision double value.] + + Description [Normalize an arbitrary precision double value.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdNormalize(EpDouble *epd) +{ + int exponent; + + if (IsNanOrInfDouble(epd->type.value)) { + epd->exponent = 0; + return; + } + + exponent = EpdGetExponent(epd->type.value); + if (exponent == EPD_MAX_BIN) + return; + exponent -= EPD_MAX_BIN; + epd->type.bits.exponent = EPD_MAX_BIN; + epd->exponent += exponent; +} + + +/**Function******************************************************************** + + Synopsis [Normalize an arbitrary precision double value.] + + Description [Normalize an arbitrary precision double value.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdNormalizeDecimal(EpDouble *epd) +{ + int exponent; + + if (IsNanOrInfDouble(epd->type.value)) { + epd->exponent = 0; + return; + } + + exponent = EpdGetExponentDecimal(epd->type.value); + epd->type.value /= pow((double)10.0, (double)exponent); + epd->exponent += exponent; +} + + +/**Function******************************************************************** + + Synopsis [Returns value and decimal exponent of EpDouble.] + + Description [Returns value and decimal exponent of EpDouble.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdGetValueAndDecimalExponent(EpDouble *epd, double *value, int *exponent) +{ + EpDouble epd1, epd2; + + if (EpdIsNanOrInf(epd)) + return; + + if (EpdIsZero(epd)) { + *value = 0.0; + *exponent = 0; + return; + } + + epd1.type.value = epd->type.value; + epd1.exponent = 0; + EpdPow2Decimal(epd->exponent, &epd2); + EpdMultiply2Decimal(&epd1, &epd2); + + *value = epd1.type.value; + *exponent = epd1.exponent; +} + +/**Function******************************************************************** + + Synopsis [Returns the exponent value of a double.] + + Description [Returns the exponent value of a double.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdGetExponent(double value) +{ + int exponent; + EpDouble epd; + + epd.type.value = value; + exponent = epd.type.bits.exponent; + return(exponent); +} + + +/**Function******************************************************************** + + Synopsis [Returns the decimal exponent value of a double.] + + Description [Returns the decimal exponent value of a double.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdGetExponentDecimal(double value) +{ + char *pos, str[24]; + int exponent; + + sprintf(str, "%E", value); + pos = strstr(str, "E"); + sscanf(pos, "E%d", &exponent); + return(exponent); +} + + +/**Function******************************************************************** + + Synopsis [Makes EpDouble Inf.] + + Description [Makes EpDouble Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMakeInf(EpDouble *epd, int sign) +{ + epd->type.bits.mantissa1 = 0; + epd->type.bits.mantissa0 = 0; + epd->type.bits.exponent = EPD_EXP_INF; + epd->type.bits.sign = sign; + epd->exponent = 0; +} + + +/**Function******************************************************************** + + Synopsis [Makes EpDouble Zero.] + + Description [Makes EpDouble Zero.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMakeZero(EpDouble *epd, int sign) +{ + epd->type.bits.mantissa1 = 0; + epd->type.bits.mantissa0 = 0; + epd->type.bits.exponent = 0; + epd->type.bits.sign = sign; + epd->exponent = 0; +} + + +/**Function******************************************************************** + + Synopsis [Makes EpDouble NaN.] + + Description [Makes EpDouble NaN.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMakeNan(EpDouble *epd) +{ + epd->type.nan.mantissa1 = 0; + epd->type.nan.mantissa0 = 0; + epd->type.nan.quiet_bit = 1; + epd->type.nan.exponent = EPD_EXP_INF; + epd->type.nan.sign = 1; + epd->exponent = 0; +} + + +/**Function******************************************************************** + + Synopsis [Copies a EpDouble struct.] + + Description [Copies a EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdCopy(EpDouble *from, EpDouble *to) +{ + to->type.value = from->type.value; + to->exponent = from->exponent; +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is Inf.] + + Description [Checks whether the value is Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdIsInf(EpDouble *epd) +{ + return(IsInfDouble(epd->type.value)); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is Zero.] + + Description [Checks whether the value is Zero.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdIsZero(EpDouble *epd) +{ + if (epd->type.value == 0.0) + return(1); + else + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is NaN.] + + Description [Checks whether the value is NaN.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdIsNan(EpDouble *epd) +{ + return(IsNanDouble(epd->type.value)); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is NaN or Inf.] + + Description [Checks whether the value is NaN or Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdIsNanOrInf(EpDouble *epd) +{ + return(IsNanOrInfDouble(epd->type.value)); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is Inf.] + + Description [Checks whether the value is Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +IsInfDouble(double value) +{ + EpType val; + + val.value = value; + if (val.bits.exponent == EPD_EXP_INF && + val.bits.mantissa0 == 0 && + val.bits.mantissa1 == 0) { + if (val.bits.sign == 0) + return(1); + else + return(-1); + } + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is NaN.] + + Description [Checks whether the value is NaN.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +IsNanDouble(double value) +{ + EpType val; + + val.value = value; + if (val.nan.exponent == EPD_EXP_INF && + val.nan.sign == 1 && + val.nan.quiet_bit == 1 && + val.nan.mantissa0 == 0 && + val.nan.mantissa1 == 0) { + return(1); + } + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is NaN or Inf.] + + Description [Checks whether the value is NaN or Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +IsNanOrInfDouble(double value) +{ + EpType val; + + val.value = value; + if (val.nan.exponent == EPD_EXP_INF && + val.nan.mantissa0 == 0 && + val.nan.mantissa1 == 0 && + (val.nan.sign == 1 || val.nan.quiet_bit == 0)) { + return(1); + } + return(0); +} diff --git a/resources/3rdparty/cudd-2.5.0/epd/epd.h b/resources/3rdparty/cudd-2.5.0/epd/epd.h new file mode 100644 index 000000000..4b538c016 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/epd/epd.h @@ -0,0 +1,200 @@ +/**CHeaderFile***************************************************************** + + FileName [epd.h] + + PackageName [epd] + + Synopsis [The University of Colorado extended double precision package.] + + Description [arithmetic functions with extended double precision.] + + SeeAlso [] + + Author [In-Ho Moon] + + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: epd.h,v 1.9 2004/08/13 18:20:30 fabio Exp $] + +******************************************************************************/ + +#ifndef _EPD +#define _EPD + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define EPD_MAX_BIN 1023 +#define EPD_MAX_DEC 308 +#define EPD_EXP_INF 0x7ff + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + +/**Struct********************************************************************** + + Synopsis [IEEE double struct.] + + Description [IEEE double struct.] + + SeeAlso [] + +******************************************************************************/ +#ifdef EPD_BIG_ENDIAN +struct IeeeDoubleStruct { /* BIG_ENDIAN */ + unsigned int sign: 1; + unsigned int exponent: 11; + unsigned int mantissa0: 20; + unsigned int mantissa1: 32; +}; +#else +struct IeeeDoubleStruct { /* LITTLE_ENDIAN */ + unsigned int mantissa1: 32; + unsigned int mantissa0: 20; + unsigned int exponent: 11; + unsigned int sign: 1; +}; +#endif + +/**Struct********************************************************************** + + Synopsis [IEEE double NaN struct.] + + Description [IEEE double NaN struct.] + + SeeAlso [] + +******************************************************************************/ +#ifdef EPD_BIG_ENDIAN +struct IeeeNanStruct { /* BIG_ENDIAN */ + unsigned int sign: 1; + unsigned int exponent: 11; + unsigned int quiet_bit: 1; + unsigned int mantissa0: 19; + unsigned int mantissa1: 32; +}; +#else +struct IeeeNanStruct { /* LITTLE_ENDIAN */ + unsigned int mantissa1: 32; + unsigned int mantissa0: 19; + unsigned int quiet_bit: 1; + unsigned int exponent: 11; + unsigned int sign: 1; +}; +#endif + +/**Struct********************************************************************** + + Synopsis [Extended precision double to keep very large value.] + + Description [Extended precision double to keep very large value.] + + SeeAlso [] + +******************************************************************************/ +union EpTypeUnion { + double value; + struct IeeeDoubleStruct bits; + struct IeeeNanStruct nan; +}; + +struct EpDoubleStruct { + union EpTypeUnion type; + int exponent; +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ +typedef struct EpDoubleStruct EpDouble; +typedef struct IeeeDoubleStruct IeeeDouble; +typedef struct IeeeNanStruct IeeeNan; +typedef union EpTypeUnion EpType; + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern EpDouble *EpdAlloc(void); +extern int EpdCmp(const char *key1, const char *key2); +extern void EpdFree(EpDouble *epd); +extern void EpdGetString(EpDouble *epd, char *str); +extern void EpdConvert(double value, EpDouble *epd); +extern void EpdMultiply(EpDouble *epd1, double value); +extern void EpdMultiply2(EpDouble *epd1, EpDouble *epd2); +extern void EpdMultiply2Decimal(EpDouble *epd1, EpDouble *epd2); +extern void EpdMultiply3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdMultiply3Decimal(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdDivide(EpDouble *epd1, double value); +extern void EpdDivide2(EpDouble *epd1, EpDouble *epd2); +extern void EpdDivide3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdAdd(EpDouble *epd1, double value); +extern void EpdAdd2(EpDouble *epd1, EpDouble *epd2); +extern void EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdSubtract(EpDouble *epd1, double value); +extern void EpdSubtract2(EpDouble *epd1, EpDouble *epd2); +extern void EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdPow2(int n, EpDouble *epd); +extern void EpdPow2Decimal(int n, EpDouble *epd); +extern void EpdNormalize(EpDouble *epd); +extern void EpdNormalizeDecimal(EpDouble *epd); +extern void EpdGetValueAndDecimalExponent(EpDouble *epd, double *value, int *exponent); +extern int EpdGetExponent(double value); +extern int EpdGetExponentDecimal(double value); +extern void EpdMakeInf(EpDouble *epd, int sign); +extern void EpdMakeZero(EpDouble *epd, int sign); +extern void EpdMakeNan(EpDouble *epd); +extern void EpdCopy(EpDouble *from, EpDouble *to); +extern int EpdIsInf(EpDouble *epd); +extern int EpdIsZero(EpDouble *epd); +extern int EpdIsNan(EpDouble *epd); +extern int EpdIsNanOrInf(EpDouble *epd); +extern int IsInfDouble(double value); +extern int IsNanDouble(double value); +extern int IsNanOrInfDouble(double value); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* _EPD */ diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/Makefile b/resources/3rdparty/cudd-2.5.0/mnemosyne/Makefile new file mode 100644 index 000000000..3c593a2a3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/Makefile @@ -0,0 +1,53 @@ +# $Id$ +# +# Makefile for the Mnemosyne memory allocation tracker. +# +# Marcus J. Ranum, 1990 +# +#Options: +# define MALLOC_IS_VOIDSTAR if your system's malloc is declared as a (void *) +# otherwise, it is assumed to be a (char *). a "mall_t" is typedeffed in +# mnemconf.h and mnemosyne.h to implement this. +OPTNS = -DMALLOC_IS_VOIDSTAR +#OPTNS = + +CC = cc +RANLIB = ranlib + +#compiler flags +CFLAGS = -g $(OPTNS) $(XCFLAGS) + +#loader flags +LDFLGS = + +HDRS = mnemosyne.h mnemconf.h + +all: mnemalyse libmnem.a + +mnemalyse: mnemalyse.o + $(CC) $(LDFLGS) -o $@ mnemalyse.o + +libmnem.a: mnemosyne.o + ar rcv $@ mnemosyne.o + $(RANLIB) $@ + +mtest: mtest.o libmnem.a + $(CC) $(LDFLGS) -o $@ mtest.o libmnem.a + +runmtest: all mtest + @echo "running memory waster" + mtest + @echo "press return for symbol list"; read ff + @cat mnem.syms + @echo "press return for waste analysis"; read ff + mnemalyse + +clean: + rm -f mtest core *.o mnem.dat mnem.syms + +distclean: clean + rm -f *.bak *~ libmnem.a mnemalyse + + +mnemosyne.o: Makefile mnemosyne.c $(HDRS) +mnemalyse.o: Makefile mnemalyse.c $(HDRS) diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/README b/resources/3rdparty/cudd-2.5.0/mnemosyne/README new file mode 100644 index 000000000..182bbd29e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/README @@ -0,0 +1,39 @@ + + This is a set of tools designed to help find memory leaks in +programs, and to locate memory-hogging functions. It's implemented as +a wrapper library that goes around malloc/free/etc, and an include file +that "intercepts" calls to malloc/free/etc and makes them call the +wrappers. Thus, you can get extensive memory profiling and leak +detection by just adding one #include directive at the top of your +file and recompiling/linking. + + Unlike some similar tools I've seen in the past, this makes +sure that it keeps its on-disk data current, so that if the program +is crashed or interrupted, the results still have some validity. The +on-disk data is as compacted as I could make it, to give a chance of +this being useable in debugging big memory pigs. It adds some cost +in performance and memory size (since it keeps its own in-memory +symbol tables) but since it's only a debugging tool, I think the +cost is worth the benefit. This library can also be used to track +only allocations in a single module, or set of modules, and doesn't +interfere with calls to the "real" malloc() that are made in other +library routines. + + Every effort has been made to ensure that the code is +portable and won't interfere with running code - it should just +plug in or out. The biggest hindrances are forward declarations of +malloc() [which the preprocessor gleefully turns into syntax errors +for you] and structure elements named "free". The code has been +tested under Ultrix on DEC Risc and VAX systems, and under SunOS +on a Motorola platform. Please send patches, suggestions, etc, +to the author, who will probably not have time to do anything with +them. + +Compiling and building: + You may wish to edit the Makefile and glance at mnemconf.h, +then simply type "make". "make mtest" will build a simple test program +that will give you an idea of how things work. "make runmtest" will +run the test and do analysis on it. + +Marcus J. Ranum +mjr@decuac.dec.com diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemalyse.c b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemalyse.c new file mode 100644 index 000000000..60d2b914e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemalyse.c @@ -0,0 +1,197 @@ +/************************************************************************ + * * + * Copyright (c) 1985 by * + * Digital Equipment Corporation, Maynard, MA * + * All rights reserved. * + * * + * The information in this software is subject to change without * + * notice and should not be construed as a commitment by Digital * + * Equipment Corporation. * + * * + * Digital assumes no responsibility for the use or reliability * + * of its software on equipment which is not supplied by Digital. * + * * + * Redistribution and use in source and binary forms are permitted * + * provided that the above copyright notice and this paragraph are * + * duplicated in all such forms and that any documentation, * + * advertising materials, and other materials related to such * + * distribution and use acknowledge that the software was developed * + * by Digital Equipment Corporation. The name of Digital Equipment * + * Corporation may not be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.* + * Do not take internally. In case of accidental ingestion, contact * + * your physician immediately. * + * * + ************************************************************************/ + +/* DO NOT INCLUDE "mnemosyne.h" !!! */ +#include +#include +#include +#include + +static char rcsid[] = "/fats/tools/hsv/mnemosyne/mnemalyse.c,v 1.1.1.1 1995/06/06 18:18:28 fabio Exp"; + +#include "mnemconf.h" + +extern char *index(); + +/* +post-processor to interpret memory allocation maps and search for +pointers that were allocated but never freed. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + +/* +simple and braindead, read in the ".lines" file, and store it in a +table by number. then read the pointer map, and crossref any unfreed +pointers. simple as dereferencing NULL... + +this could use some cleaning and buffing, but it's damn effective as +it is. again, fancier symbol table routines would make this faster, +but who gives a damn? it only has to be faster than finding memory +leaks by hand... +*/ + +struct xsym { + char *dat; + int lnum; + int map; + struct xsym *nxt; +}; + + + +main() +{ + register struct xsym *sp; + register struct xsym *zp; + struct ptr p; + struct xsym *shash[HASHSIZ]; + char inbuf[BUFSIZ]; + FILE *lp; + int fd; + + /* statistics */ + int ptrcnt = 0; + int ptrbad = 0; + int ptrlos = 0; + + /* to chop up lines */ + char *cpmap; + char *cpcalls; + char *cpave; + char *cplnum; + char *cpfnam; + + for(fd = 0; fd < HASHSIZ; fd++) + shash[fd] = (struct xsym *)0; + + if((lp = fopen(LINESFILE,"r")) == (FILE *)0) { + perror(LINESFILE); + exit(1); + } + + if((fd = open(PTRFILE,O_RDONLY|O_RDWR)) < 0) { + perror(PTRFILE); + exit(1); + } + + /* this is ugly, but I refuse to trust !@(#&U!@#&! sscanf() */ + while((cpmap = fgets(inbuf,sizeof(inbuf),lp)) != (char *)0) { + if(inbuf[0] == '#') + continue; + + sp = (struct xsym *)malloc(sizeof(struct xsym)); + if(sp == (struct xsym *)0) { + perror("malloc"); + exit(1); + } + sp->lnum = sp->map = 0; + + if((cpcalls = index(cpmap,'\t')) != (char *)0) + *cpcalls++ = '\0'; + + if((cpave = index(cpcalls,'\t')) != (char *)0) + *cpave++ = '\0'; + + if((cplnum = index(cpave,'\t')) != (char *)0) + *cplnum++ = '\0'; + + if((cpfnam = index(cplnum,'\t')) != (char *)0) + *cpfnam++ = '\0'; + + /* setup symbol */ + sp->map = atoi(cpmap); + + if(cplnum == (char *)0) + sp->lnum = -1; + else + sp->lnum = atoi(cplnum); + + if(cpfnam != (char *)0) { + char *x; + if((x = index(cpfnam,'\n')) != (char *)0) + *x = '\0'; + + sp->dat = malloc((unsigned)(strlen(cpfnam) + 1)); + if(sp->dat == (char *)0) { + perror("malloc"); + exit(1); + } + (void)strcpy(sp->dat,cpfnam); + } else + sp->dat = "unknown"; + + /* check to make sure it is not already in table */ + zp = shash[sp->map % HASHSIZ]; + while(zp != (struct xsym *)0) { + if(zp->map == sp->map) { + (void)fprintf(stderr, + "mnemalyse: duplicate map entry ignored"); + (void)fprintf(stderr, + " (point at both %s and %s)\n",sp->dat,zp->dat); + (void)free(sp); + + /* can't free dat - may not be malloced! */ + sp = (struct xsym *)0; + break; + } + zp = zp->nxt; + } + + /* shrug, link it in */ + if(sp != (struct xsym *)0) { + sp->nxt = shash[sp->map % HASHSIZ]; + shash[sp->map % HASHSIZ] = sp; + } + } + (void)fclose(lp); + + while(read(fd,(char *)&(p.dsk),sizeof(p.dsk)) == sizeof(p.dsk)) { + + /* if the pointer was not deallocated, note it */ + if(p.dsk.siz != 0) { + zp = shash[p.dsk.smap % HASHSIZ]; + while(zp != (struct xsym *)0) { + if(zp->map == p.dsk.smap) { + printf("%d bytes missing %s line:%d\n", + p.dsk.siz,zp->dat,zp->lnum); + } + zp = zp->nxt; + } + ptrbad++; + ptrlos += p.dsk.siz; + } + ptrcnt++; + } + + printf("%d pointers, %d lost totalling %d bytes\n", + ptrcnt,ptrbad,ptrlos); + exit(0); +} diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemconf.h b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemconf.h new file mode 100644 index 000000000..9ea8f75bf --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemconf.h @@ -0,0 +1,89 @@ +/************************************************************************ + * * + * Copyright (c) 1985 by * + * Digital Equipment Corporation, Maynard, MA * + * All rights reserved. * + * * + * The information in this software is subject to change without * + * notice and should not be construed as a commitment by Digital * + * Equipment Corporation. * + * * + * Digital assumes no responsibility for the use or reliability * + * of its software on equipment which is not supplied by Digital. * + * * + * Redistribution and use in source and binary forms are permitted * + * provided that the above copyright notice and this paragraph are * + * duplicated in all such forms and that any documentation, * + * advertising materials, and other materials related to such * + * distribution and use acknowledge that the software was developed * + * by Digital Equipment Corporation. The name of Digital Equipment * + * Corporation may not be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.* + * Do not take internally. In case of accidental ingestion, contact * + * your physician immediately. * + * * + ************************************************************************/ + +#ifndef _INCL_MNEMCONF_H + +/* +/fats/tools/hsv/mnemosyne/mnemconf.h,v 1.1.1.1 1995/06/06 18:18:29 fabio Exp +*/ + +/* +site specific and shared internal data structures used by mnemosyne. +the only data structure that may need to be shared is the struct ptr, +which is defined herein. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + + +/* if your machine has malloc and all declared as a (void *) not a (char *) */ +#ifdef MALLOC_IS_VOIDSTAR +typedef void *mall_t; +#else +typedef char *mall_t; +#endif + + +/* size of internal hash tables - don't go wild - this is slow anyhow */ +#define HASHSIZ 2027 + + +/* names of files to write */ +#define LINESFILE "mnem.syms" +#define PTRFILE "mnem.dat" + + +extern mall_t malloc(); +extern mall_t realloc(); +extern mall_t calloc(); +extern void free(); + + +/* +storage for a pointer map entry - the only data structure we share +a whole mess of these get written to mnem.dat as calls to malloc and +whatnot are made. the distinction between an *allocated* pointer and +and unallocated one is that 'siz' is 0 in freed ptrs. this is used +by the post-processor to look for memory leaks. +*/ +struct ptr { + mall_t ptr; /* pointer to allocated memory */ + int map; /* this pointer's map # */ + struct ptr *next; + + /* only part that gets written to the disk */ + struct { + unsigned siz; /* size allocated (or 0) */ + int smap; /* symbol map # */ + } dsk; +}; + +#define _INCL_MNEMCONF_H +#endif diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.c b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.c new file mode 100644 index 000000000..0d759da18 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.c @@ -0,0 +1,670 @@ +/************************************************************************ + * * + * Copyright (c) 1985 by * + * Digital Equipment Corporation, Maynard, MA * + * All rights reserved. * + * * + * The information in this software is subject to change without * + * notice and should not be construed as a commitment by Digital * + * Equipment Corporation. * + * * + * Digital assumes no responsibility for the use or reliability * + * of its software on equipment which is not supplied by Digital. * + * * + * Redistribution and use in source and binary forms are permitted * + * provided that the above copyright notice and this paragraph are * + * duplicated in all such forms and that any documentation, * + * advertising materials, and other materials related to such * + * distribution and use acknowledge that the software was developed * + * by Digital Equipment Corporation. The name of Digital Equipment * + * Corporation may not be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.* + * Do not take internally. In case of accidental ingestion, contact * + * your physician immediately. * + * * + ************************************************************************/ + +/* DO NOT INCLUDE "mnemosyne.h" !!! */ +#include +#include +#include + +/* shared stuff - and decl of struct ptr */ +#include "mnemconf.h" + +static char rcsid[] = "/fats/tools/hsv/mnemosyne/mnemosyne.c,v 1.1.1.1 1995/06/06 18:18:28 fabio Exp"; + + +/* +malloc() realloc() and family wrappers - these functions manage a set +of data files that are updated whenever a pointer is allocated or freed, +as well as gathering stats about dynamic memory use and leakage. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + +/* +there is some egregious use of globals, void functions, and whatnot +in this code. it is mostly due to the constraint that nothing must +be visible to the outside, and that the code must be structurally +simple. error checking is pitched out the window in spots, since an +error in the mnemosyne code should not affect whatever is being +instrumented if at all possible. this means no errors, no signals, +nothing. (this message brought to you by my ego, in case you think +I don't know how to write better code than this) :) + +mjr, hacking on Christmas, 1990. +*/ + +#define REC_UNINIT 000 +#define REC_INITTED 001 +#define REC_ERR 002 +#define REC_ON 010 +#define REC_ONOFF 020 +static int rec_state = REC_UNINIT; + +/* +this method of storing the symbol maps is not the most efficient, but +then that's not important here, since all we're trying to do is find +memory leaks. if you choose to improve the symbol management to use +bucketed hash tables, please contact the author and the code will be +updated :) - besides, since we do file I/O every time you malloc or +free something, there's no way in hell this is going to set any new +records for speed. +*/ + + +/* storage for code/line # entry */ +struct sym { + char *labl; + int lineno; + int mapno; + int mallcnt; + float avsiz; + struct sym *next; +}; + + + +/* static symbol map */ +static struct { + FILE *fp; + FILE *log; + int fd; + + long nalloc; /* count of allocations */ + long nrlloc; /* count of re-allocations */ + long nfree; /* count of frees */ + long nbfree; /* count of bad frees */ + long ninuse; /* known allocated memory in use */ + float avgsiz; /* average malloc size */ + + /* one entry per pointer returned by malloc */ + int pmap; /* current next ptr map to alloc */ + struct ptr *phash[HASHSIZ]; + + /* one entry per line of code that calls malloc/realloc, etc */ + int lmap; /* current next line map to alloc */ + struct sym *shash[HASHSIZ]; /* hash access */ +} map; + + + + +/* print a locale record with checks for closed log file */ +static void +ploc(lab,lin,siz) +char *lab; +int lin; +int siz; +{ + if(map.log == (FILE *)0) + return; + if(lab != (char *)0) + (void)fprintf(map.log," \"%s\"",lab); + else + (void)fprintf(map.log," unknown"); + if(lin != -1) + (void)fprintf(map.log," line:%d",lin); + if(siz != -1) + (void)fprintf(map.log," size:%d",siz); +} + + + + +/* print a symbol map entry with checks for closed log file */ +static void +psym(s) +struct sym *s; +{ + if(map.log == (FILE *)0) + return; + (void)fprintf(map.log," \"%s\"",s->labl); + if(s->lineno != -1) + (void)fprintf(map.log," line:%d",s->lineno); +} + + + + +/* output a warning message with checks for closed log file */ +static void +pmsg(s) +char *s; +{ + if(map.log == (FILE *)0) + return; + (void)fprintf(map.log,"%s",s); +} + + + + +/* save an entry to the .lines file */ +static void +savesym(s) +struct sym *s; +{ + if(map.fp == (FILE *)0) + return; + + (void)fprintf(map.fp,"%d\t%d\t%.1f\t%d\t%s\n", + s->mapno,s->mallcnt,s->avsiz,s->lineno,s->labl); +} + + + + +/* save an entry in the pointer map file */ +static void +saveptr(p) +register struct ptr *p; +{ + if(lseek(map.fd,(off_t)(p->map * sizeof(p->dsk)),0) != + (off_t)(p->map * sizeof(p->dsk))) { + pmsg("mnemosyne: cannot seek in pointer map file\n"); + rec_state |= REC_ERR; + return; + } + + if(write(map.fd,(char *)&(p->dsk),sizeof(p->dsk)) != sizeof(p->dsk)) { + pmsg("mnemosyne: cannot write in pointer map file\n"); + rec_state |= REC_ERR; + return; + } +} + + + + +/* initialize everything - symbol tables, files, and maps */ +static void +initmap() +{ + register int xp; + + if(rec_state & REC_INITTED) + return; + + if((map.fp = fopen(LINESFILE,"w")) == (FILE *)0) + return; + if((map.fd = open(PTRFILE,O_RDWR|O_CREAT|O_TRUNC,0600)) < 0) { + (void)fclose(map.fp); + return; + } + + map.log = stderr; + map.lmap = map.pmap = 0; + map.nalloc = map.nrlloc = map.nfree = map.nbfree = 0L; + map.ninuse = 0L; + map.avgsiz = 0.0; + + for(xp = 0; xp < HASHSIZ; xp++) { + map.phash[xp] = (struct ptr *)0; + map.shash[xp] = (struct sym *)0; + } + + rec_state = REC_INITTED | REC_ON; +} + + + + +/* set logging to a FILE * */ +void +mnem_setlog(fp) +FILE *fp; +{ + map.log = fp; +} + + + + +/* return state of the recorder */ +int +mnem_recording() +{ + return((rec_state & REC_ON) && !(rec_state & REC_ERR)); +} + + + + +/* turn on or off recording */ +int +mnem_setrecording(val) +int val; +{ + if(!(rec_state & REC_INITTED)) + initmap(); + + if(val) + rec_state |= REC_ON; + else + rec_state &= ~REC_ON; + + if(map.fp != (FILE *)0) + (void)fflush(map.fp); + + rec_state |= REC_ONOFF; + return(0); +} + + + + +/* lookup a pointer record - search pointer hash table */ +static struct ptr * +lookupptr(ptr) +mall_t ptr; +{ + register struct ptr *p; + + /* this probably give simply terrible hash performance */ + p = map.phash[(unsigned long)ptr % HASHSIZ]; + while(p != (struct ptr *)0) { + if(ptr == p->ptr) + return(p); + p = p->next; + } + return((struct ptr *)0); +} + + + + +/* + * polynomial conversion ignoring overflows + * [this seems to work remarkably well, in fact better + * then the ndbm hash function. Replace at your own risk] + * use: 65599 nice. + * 65587 even better. + * author: oz@nexus.yorku.ca + */ +static unsigned int +dbm_hash(str) +register char *str; +{ + register unsigned int n = 0; + + while(*str != '\0') + n = *str++ + 65599 * n; + return(n); +} + + + + +/* lookup a line/source entry by name (search hash table) */ +static struct sym * +lookupsymbyname(nam,lin) +char *nam; +int lin; +{ + register struct sym *s; + char *p = nam; + + if(p == (char *)0) + p = "unknown"; + + s = map.shash[(dbm_hash(p) + lin) % HASHSIZ]; + while(s != (struct sym *)0) { + if(!strcmp(s->labl,nam) && s->lineno == lin) + return(s); + s = s->next; + } + + return((struct sym *)0); +} + + + + +/* lookup a line/source entry by number (exhaustively search hash table) */ +static struct sym * +lookupsymbynum(num) +int num; +{ + register struct sym *s; + register int x; + + for(x = 0; x < HASHSIZ; x++) { + s = map.shash[x]; + while(s != (struct sym *)0) { + if(s->mapno == num) + return(s); + s = s->next; + } + } + return((struct sym *)0); +} + + + +/* stuff a pointer's value in the pointer map table */ +static void +storeptr(ptr,siz,lab,lin) +mall_t ptr; +int siz; +char *lab; +int lin; +{ + register struct ptr *p; + register struct sym *s; + int hv; + + /* + is there is no existing symbol entry for this line of code... + we must needs make one - and painful it is... + */ + if((s = lookupsymbyname(lab,lin)) == (struct sym *)0) { + s = (struct sym *)malloc(sizeof(struct sym)); + if(s == (struct sym *)0) { + pmsg("mnemosyne: cannot allocate sym entry\n"); + rec_state |= REC_ERR; + return; + } + + /* + this is funky - since we know the label is (?) + compiled-in, we can just keep a pointer to it, + rather than copying our own version of it. + */ + if(lab != (char *)0) + s->labl = lab; + else + s->labl = "unknown"; + + s->mapno = map.lmap++; + + /* add sym to hash table */ + s->next = map.shash[hv = ((dbm_hash(s->labl) + lin) % HASHSIZ)]; + map.shash[hv] = s; + + s->lineno = lin; + s->mallcnt = 1; + s->avsiz = siz; + savesym(s); + } else { + /* found an already defined symbol. store some averages */ + s->avsiz = ((s->avsiz * s->mallcnt) + siz) / (s->mallcnt + 1); + (s->mallcnt)++; + } + + p = lookupptr(ptr); + if(p != (struct ptr *)0 && p->dsk.siz != 0) { + struct sym *x; + + pmsg("pointer re-allocated without being freed"); + ploc(lab,lin,(int)siz); + if((x = lookupsymbynum(p->dsk.smap)) != (struct sym *)0) { + pmsg(" last allocated "); + psym(x); + } + pmsg("\n"); + } + + /* heavy sigh. no entry for this pointer. make one. */ + if(p == (struct ptr *)0) { + p = (struct ptr *)malloc(sizeof(struct ptr)); + if(p == (struct ptr *)0) { + pmsg("mnemosyne: cannot expand pointer table\n"); + rec_state |= REC_ERR; + return; + } + + /* link it in */ + p->next = map.phash[(unsigned long)ptr % HASHSIZ]; + map.phash[(unsigned long)ptr % HASHSIZ] = p; + } + + /* if we get to here (hazoo! hazaa!) both 's' and 'p' are OK */ + p->ptr = ptr; + p->dsk.siz = siz; + p->dsk.smap = s->mapno; + p->map = map.pmap++; + + /* store the size */ + map.ninuse += siz; + + saveptr(p); +} + + + + +/* +mark a pointer as now being free. note that a 1 is returned IF +the actual value should NOT be really passed to free() +*/ +static int +freeptr(ptr,lab,lin) +mall_t ptr; +char *lab; +int lin; +{ + register struct ptr *p; + + p = lookupptr(ptr); + if(p == (struct ptr *)0) { + pmsg("pointer freed that was never allocated"); + ploc(lab,lin,-1); + pmsg("\n"); + return(1); + } + + if(p != (struct ptr *)0 && p->dsk.siz == 0) { + struct sym *x; + + pmsg("pointer re-freed when already free"); + ploc(lab,lin,-1); + if((x = lookupsymbynum(p->dsk.smap)) != (struct sym *)0) { + pmsg(" last allocated:"); + psym(x); + } + pmsg("\n"); + return(1); + } + + /* get some free */ + map.ninuse -= p->dsk.siz; + + /* write in the map that it is free */ + p->dsk.siz = 0; + saveptr(p); + + return(0); +} + + + + +/* pretend we are malloc() */ +mall_t +mnem_malloc(siz,lab,lin) +unsigned siz; +char *lab; +int lin; +{ + mall_t ret; + + if(!(rec_state & REC_INITTED)) + initmap(); + + if((ret = malloc(siz)) == (mall_t)0) { + pmsg("malloc returned null pointer at"); + ploc(lab,lin,(int)siz); + pmsg("\n"); + return(ret); + } + + if((rec_state & REC_ON) && !(rec_state & REC_ERR)) + storeptr(ret,(int)siz,lab,lin); + + map.avgsiz = ((map.avgsiz * map.nalloc) + siz) / (map.nalloc + 1); + map.nalloc++; + return(ret); +} + + + + +/* pretend we are calloc() */ +mall_t +mnem_calloc(cnt,siz,lab,lin) +unsigned cnt; +unsigned siz; +char *lab; +int lin; +{ + mall_t ret; + + if(!(rec_state & REC_INITTED)) + initmap(); + + if((ret = calloc(cnt,siz)) == (mall_t)0) { + pmsg("calloc returned null pointer at"); + ploc(lab,lin,(int)(siz * cnt)); + pmsg("\n"); + return(ret); + } + + if((rec_state & REC_ON) && !(rec_state & REC_ERR)) + storeptr(ret,(int)(cnt * siz),lab,lin); + + map.avgsiz = ((map.avgsiz * map.nalloc) + siz) / (map.nalloc + 1); + map.nalloc++; + return(ret); +} + + + + +/* pretend we are realloc() */ +mall_t +mnem_realloc(ptr,siz,lab,lin) +mall_t ptr; +unsigned siz; +char *lab; +int lin; +{ + mall_t ret; + + if(!(rec_state & REC_INITTED)) + initmap(); + + if((ret = realloc(ptr,siz)) == (mall_t)0) { + pmsg("realloc returned null pointer at"); + ploc(lab,lin,(int)siz); + pmsg("\n"); + return(ret); + } + + if((rec_state & REC_ON) && !(rec_state & REC_ERR)) { + if(!freeptr(ptr,lab,lin)) + storeptr(ret,(int)siz,lab,lin); + } + + map.nrlloc++; + return(ret); +} + + + + + +/* pretend we are free() */ +void +mnem_free(ptr,lab,lin) +mall_t ptr; +char *lab; +int lin; +{ + if(!(rec_state & REC_INITTED)) + initmap(); + + if((rec_state & REC_ON) && !(rec_state & REC_ERR)) + if(freeptr(ptr,lab,lin) == 0) { + (void)free(ptr); + map.nfree++; + } else + map.nbfree++; +} + + + + +/* dump everything we know about nothing in particular */ +int +mnem_writestats() +{ + register struct sym *s; + register int x; + + if(map.fp == (FILE *)0) + return(-1); + + (void)fseek(map.fp,0L,0); + + /* dump our life's story */ + (void)fprintf(map.fp,"#total allocations:%ld\n",map.nalloc); + (void)fprintf(map.fp,"#total re-allocations:%ld\n",map.nrlloc); + (void)fprintf(map.fp,"#total frees:%ld\n",map.nfree); + + if(map.nbfree != 0L) + (void)fprintf(map.fp,"#bad/dup frees:%ld\n",map.nbfree); + + (void)fprintf(map.fp,"#total allocated never freed:%ld\n",map.ninuse); + + (void)fprintf(map.fp,"#average size of allocations:%.1f\n",map.avgsiz); + + /* note if we detected an internal error */ + if(rec_state & REC_ERR) + (void)fprintf(map.fp, + "#(figures likely inaccurate due to error)\n"); + + /* note if the system was on all the time ? */ + if(!(rec_state & REC_ON) || (rec_state & REC_ONOFF)) + (void)fprintf(map.fp, + "#(figures likely inaccurate as recording was off)\n"); + + /* write the legend */ + (void)fprintf(map.fp,"#map#\tcalls\tave\tline#\tfile\n"); + + for(x = 0; x < HASHSIZ; x++) { + s = map.shash[x]; + while(s != (struct sym *)0) { + savesym(s); + s = s->next; + } + } + + (void)fflush(map.fp); + return(0); +} diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.h b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.h new file mode 100644 index 000000000..910af91d5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/mnemosyne.h @@ -0,0 +1,73 @@ +/************************************************************************ + * * + * Copyright (c) 1985 by * + * Digital Equipment Corporation, Maynard, MA * + * All rights reserved. * + * * + * The information in this software is subject to change without * + * notice and should not be construed as a commitment by Digital * + * Equipment Corporation. * + * * + * Digital assumes no responsibility for the use or reliability * + * of its software on equipment which is not supplied by Digital. * + * * + * Redistribution and use in source and binary forms are permitted * + * provided that the above copyright notice and this paragraph are * + * duplicated in all such forms and that any documentation, * + * advertising materials, and other materials related to such * + * distribution and use acknowledge that the software was developed * + * by Digital Equipment Corporation. The name of Digital Equipment * + * Corporation may not be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.* + * Do not take internally. In case of accidental ingestion, contact * + * your physician immediately. * + * * + ************************************************************************/ + +#ifndef _INCL_MNEMOSYNE_H + +/* +/fats/tools/hsv/mnemosyne/mnemosyne.h,v 1.1.1.1 1995/06/06 18:18:28 fabio Exp +*/ + + +/* +main include file for the mnemosyne memory allocation tracker. this file +provides some pre-processor fakes for malloc(), realloc() and family, +as well as forward declarations for the mnemosyne functions. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + +/* these disguise mnemosyne calls as calls to malloc and family */ +#ifndef NOFAKEMALLOC +#define malloc(siz) mnem_malloc(siz,__FILE__,__LINE__) +#define calloc(siz,cnt) mnem_calloc(siz,cnt,__FILE__,__LINE__) +#define realloc(ptr,siz) mnem_realloc(ptr,siz,__FILE__,__LINE__) +#define free(ptr) mnem_free(ptr,__FILE__,__LINE__) +#endif + + +#ifdef MALLOC_IS_VOIDSTAR +typedef void *mall_t; +#else +typedef char *mall_t; +#endif + +extern mall_t mnem_malloc(); +extern mall_t mnem_calloc(); +extern mall_t mnem_realloc(); +extern void mnem_free(); + +/* some internal functions and oddimentia */ +extern int mnem_recording(); +extern int mnem_setrecording(); +extern void mnem_setlog(); +extern int mnem_writestats(); + +#define _INCL_MNEMOSYNE_H +#endif diff --git a/resources/3rdparty/cudd-2.5.0/mnemosyne/mtest.c b/resources/3rdparty/cudd-2.5.0/mnemosyne/mtest.c new file mode 100644 index 000000000..5a51a0a04 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mnemosyne/mtest.c @@ -0,0 +1,38 @@ +#include "mnemosyne.h" + +static char rcsid[] = "/fats/tools/hsv/mnemosyne/mtest.c,v 1.1.1.1 1995/06/06 18:18:27 fabio Exp"; + +/* +test harness/demo of mnemosyne library. deliberately leaks memory on the +floor, double frees, frees unallocated memory, etc. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + +main() +{ + char *d = "foobar"; + char *xx; + int x; + + xx = malloc(922); + xx = malloc(123); + + /* huh ? */ + xx = malloc(-9); + + /* waste some memory */ + for(x = 1; x < 8; x++) + xx = malloc(x); + + /* free something we don't own */ + free(d); + + /* double free something */ + free(xx); + free(xx); + + /* not necessary - this triggers a better printout of statistics */ + mnem_writestats(); +} diff --git a/resources/3rdparty/cudd-2.5.0/mtr/Makefile b/resources/3rdparty/cudd-2.5.0/mtr/Makefile new file mode 100644 index 000000000..b62b7c5da --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/Makefile @@ -0,0 +1,96 @@ +# $Id: Makefile,v 1.2 1994/10/03 23:30:34 fabio Exp fabio $ +# +# mtr - multiway-branching tree package +#--------------------------- +.SUFFIXES: .o .c .u + +CC = cc +RANLIB = ranlib +PURE = +# Define EXE as .exe for MS-DOS and derivatives. +EXE = +#EXE = .exe + +MFLAG = +ICFLAGS = -g +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) +MTRDEBUG = -DMTR_STATS -DMTR_VERBOSE -DMTR_DEBUG + +LINTFLAGS = -u -n -DMTR_STATS -DMTR_VERBOSE -DMTR_DEBUG + +# this is to create the lint library +LINTSWITCH = -o + +LDFLAGS = + +WHERE = .. + +INCLUDE = $(WHERE)/include + +P = mtr +PSRC = mtrBasic.c mtrGroup.c +PHDR = mtr.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +SRC = test$(P).c +HDR = +OBJ = $(SRC:.c=.o) +UBJ = $(SRC:.c=.u) +TARGET = test$(P)$(EXE) +TARGETu = test$(P)-u + +LIBS = ./libmtr.a $(WHERE)/util/libutil.a + +BLIBS = -kL. -klmtr -kL$(WHERE)/util -klutil + +MNEMLIB = + +LINTLIBS = llib-l$(P).ln + +#--------------------------- + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PSRC) $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) $(MTRDEBUG) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) +$(OBJ): $(PHDR) +$(UBJ): $(PHDR) + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +$(TARGET): $(POBJ) $(OBJ) $(LIBS) $(MNEMLIB) + $(PURE) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +$(TARGETu): $(SRC) $(PSRC) $(PHDR) $(UBJ) $(PUBJ) $(LIBS:.a=.b) + cc -O3 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \ + *.bak *~ tags *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/mtr/Makefile.sis b/resources/3rdparty/cudd-2.5.0/mtr/Makefile.sis new file mode 100644 index 000000000..d920cabf7 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/Makefile.sis @@ -0,0 +1,83 @@ +# $Id$ +# +# Cudd - DD package +#--------------------------- +.SUFFIXES: .o .c .u + +RANLIB = ranlib + +CAD = /projects/octtools/octtools/$(MACHINE) +SIS = .. +LINTCREATEFLAG = -C + +# files for the package +P = mtr +PSRC = mtrBasic.c mtrGroup.c +PHDR = mtr.h +POBJ = $(PSRC:.c=.o) + +# files for the test program +TARGET = test$(P) +SRC = test$(P).c +OBJ = $(SRC:.c=.o) +HDR = + +LIBS = ../util/libutil.a +LINTLIBS= ../util/llib-lutil.ln +INCLUDE = -I$(CAD)/include -I$(SIS)/include + +CFLAGS = -g $(INCLUDE) +LDFLAGS = -g +LINTFLAGS = $(INCLUDE) ${LINTEXTRAS} + +#------------------------------------------------------ + +$(TARGET): $(PHDR) $(OBJ) $(POBJ) $(LIBS) + $(CC) $(LDFLAGS) -o $(TARGET) $(OBJ) $(POBJ) $(LIBS) + +lint: $(PSRC) $(PHDR) $(SRC) $(HDR) + lint $(LINTFLAGS) $(SRC) $(PSRC) $(LINTLIBS) + +install: lib$(P).a llib-l$(P).ln + +lib$(P).a: $(POBJ) + ar cr $@ $? + $(RANLIB) $@ + +unpack: lib$(P).a + @for i in $(POBJ); do \ + ln -s $(SIS)/$(P)/$$i $(SIS)/unpack; \ + done + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) ${LINTCREATEFLAG}$(P) -n $(PSRC) + +clean: + rm -f $(TARGET) *.a *.ln *.o \ + [Tt]ags [Mm]ake.out lint malloc.out gmon.out __.SYMDEF + +tags: _force + @for i in $(PSRC) $(PHDR); do \ + cwd=`pwd`; ctags -a $$cwd/$$i; + done; + +strip_depend: + sed '/^#--DO NOT CHANGE ANYTHING AFTER THIS LINE/,$$d' Makefile >mktemp + mv mktemp Makefile + +depend: + sed '/^#--DO NOT CHANGE ANYTHING AFTER THIS LINE/,$$d' Makefile >mktemp + echo '#--DO NOT CHANGE ANYTHING AFTER THIS LINE' >>mktemp + $(CAD)/bin/cc-M $(CFLAGS) $(PSRC) | \ + sed 's|$(CAD)|$$(CAD)|g' | \ + grep -v '/usr/include' >>mktemp + mv mktemp Makefile + +#-------------------------- IBM 3090 support ----------------- +IBMHOST = opua +IBMDIST = /users2/sis +ibmdist: $(PSRC) $(PHDR) + rdist -Richw $(PSRC) $(PHDR) $(IBMHOST):$(IBMDIST) +#------------------------------------------------------------- +_force: + diff --git a/resources/3rdparty/cudd-2.5.0/mtr/doc/mtr.doc b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtr.doc new file mode 100644 index 000000000..2815d2948 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtr.doc @@ -0,0 +1,252 @@ +The mtr package + +Multiway-branch tree manipulation + +Fabio Somenzi + +********************************************************************** + +Mtr_AllocNode() Allocates new tree node. + +Mtr_CopyTree() Makes a copy of tree. + +Mtr_CreateFirstChild() Creates a new node and makes it the first child + of parent. + +Mtr_CreateLastChild() Creates a new node and makes it the last child + of parent. + +Mtr_DeallocNode() Deallocates tree node. + +Mtr_DissolveGroup() Merges the children of `group' with the + children of its parent. + +Mtr_FindGroup() Finds a group with size leaves starting at low, + if it exists. + +Mtr_FreeTree() Disposes of tree rooted at node. + +Mtr_InitGroupTree() Allocate new tree. + +Mtr_InitTree() Initializes tree with one node. + +Mtr_MakeFirstChild() Makes child the first child of parent. + +Mtr_MakeGroup() Makes a new group with size leaves starting at + low. + +Mtr_MakeLastChild() Makes child the last child of parent. + +Mtr_MakeNextSibling() Makes second the next sibling of first. + +Mtr_PrintGroups() Prints the groups as a parenthesized list. + +Mtr_PrintTree() Prints a tree, one node per line. + +Mtr_ReadGroups() Reads groups from a file and creates a group + tree. + +Mtr_SwapGroups() Swaps two children of a tree node. + +********************************************************************** + +This package provides two layers of functions. Functions of the lower level +manipulate multiway-branch trees, implemented according to the classical +scheme whereby each node points to its first child and its previous and +next siblings. These functions are collected in mtrBasic.c. Functions +of the upper layer deal with group trees, that is the trees used by group +sifting to represent the grouping of variables. These functions are +collected in mtrGroup.c. + +MtrNode * +Mtr_AllocNode( + +) + Allocates new tree node. Returns pointer to node. + + Side Effects: None + +MtrNode * +Mtr_CopyTree( + MtrNode * node, + int expansion +) + Makes a copy of tree. If parameter expansion is greater than 1, it will + expand the tree by that factor. It is an error for expansion to be less than + 1. Returns a pointer to the copy if successful; NULL otherwise. + + Side Effects: None + +MtrNode * +Mtr_CreateFirstChild( + MtrNode * parent +) + Creates a new node and makes it the first child of parent. Returns pointer + to new child. + + Side Effects: None + +MtrNode * +Mtr_CreateLastChild( + MtrNode * parent +) + Creates a new node and makes it the last child of parent. Returns pointer to + new child. + + Side Effects: None + +void +Mtr_DeallocNode( + MtrNode * node node to be deallocated +) + Deallocates tree node. + + Side Effects: None + +MtrNode * +Mtr_DissolveGroup( + MtrNode * group group to be dissolved +) + Merges the children of `group' with the children of its parent. Disposes of + the node pointed by group. If group is the root of the group tree, this + procedure leaves the tree unchanged. Returns the pointer to the parent of + `group' upon successful termination; NULL otherwise. + + Side Effects: None + +MtrNode * +Mtr_FindGroup( + MtrNode * root, root of the group tree + unsigned int low, lower bound of the group + unsigned int size upper bound of the group +) + Finds a group with size leaves starting at low, if it exists. This procedure + relies on the low and size fields of each node. It also assumes that the + children of each node are sorted in order of increasing low. Returns the + pointer to the root of the group upon successful termination; NULL + otherwise. + + Side Effects: None + +void +Mtr_FreeTree( + MtrNode * node +) + Disposes of tree rooted at node. + + Side Effects: None + +MtrNode * +Mtr_InitGroupTree( + int lower, + int size +) + Allocate new tree with one node, whose low and size fields are specified by + the lower and size parameters. Returns pointer to tree root. + + Side Effects: None + +MtrNode * +Mtr_InitTree( + +) + Initializes tree with one node. Returns pointer to node. + + Side Effects: None + +void +Mtr_MakeFirstChild( + MtrNode * parent, + MtrNode * child +) + Makes child the first child of parent. + + Side Effects: None + +MtrNode * +Mtr_MakeGroup( + MtrNode * root, root of the group tree + unsigned int low, lower bound of the group + unsigned int size, upper bound of the group + unsigned int flags flags for the new group +) + Makes a new group with size leaves starting at low. If the new group + intersects an existing group, it must either contain it or be contained by + it. This procedure relies on the low and size fields of each node. It also + assumes that the children of each node are sorted in order of increasing + low. In case of a valid request, the flags of the new group are set to the + value passed in `flags.' This can also be used to change the flags of an + existing group. Returns the pointer to the root of the new group upon + successful termination; NULL otherwise. If the group already exists, the + pointer to its root is returned. + + Side Effects: None + +void +Mtr_MakeLastChild( + MtrNode * parent, + MtrNode * child +) + Makes child the last child of parent. + + Side Effects: None + +void +Mtr_MakeNextSibling( + MtrNode * first, + MtrNode * second +) + Makes second the next sibling of first. Second becomes a child of the parent + of first. + + Side Effects: None + +void +Mtr_PrintGroups( + MtrNode * root, root of the group tree + int silent flag to check tree syntax only +) + Prints the groups as a parenthesized list. After each group, the group's + flag are printed, preceded by a `|'. For each flag (except MTR_TERMINAL) a + character is printed. F: MTR_FIXED N: MTR_NEWNODE S: + MTR_SOFT The second argument, silent, if different from 0, causes + Mtr_PrintGroups to only check the syntax of the group tree. + + Side Effects: None + +void +Mtr_PrintTree( + MtrNode * node +) + Prints a tree, one node per line. + + Side Effects: None + +MtrNode * +Mtr_ReadGroups( + FILE * fp, file pointer + int nleaves number of leaves of the new tree +) + Reads groups from a file and creates a group tree. Each group is specified + by three fields: low size flags. Low and size are (short) + integers. Flags is a string composed of the following characters (with + associated translation): D: MTR_DEFAULT F: MTR_FIXED N: + MTR_NEWNODE S: MTR_SOFT T: MTR_TERMINAL Normally, the only + flags that are needed are D and F. Groups and fields are separated by white + space (spaces, tabs, and newlines). Returns a pointer to the group tree if + successful; NULL otherwise. + + Side Effects: None + +int +Mtr_SwapGroups( + MtrNode * first, first node to be swapped + MtrNode * second second node to be swapped +) + Swaps two children of a tree node. Adjusts the high and low fields of the + two nodes and their descendants. The two children must be adjacent. However, + first may be the younger sibling of second. Returns 1 in case of success; 0 + otherwise. + + Side Effects: None + diff --git a/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllAbs.html b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllAbs.html new file mode 100644 index 000000000..9a59faada --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllAbs.html @@ -0,0 +1,72 @@ + +mtr package abstract (Internal) + + +

                  mtr package abstract (Internal)

                  +

                  Internal data structures of the mtr package

                  +
                  + + + +
                  +
                  Mtr_AllocNode() +
                  Allocates new tree node. + +
                  Mtr_CopyTree() +
                  Makes a copy of tree. + +
                  Mtr_CreateFirstChild() +
                  Creates a new node and makes it the first child of parent. + +
                  Mtr_CreateLastChild() +
                  Creates a new node and makes it the last child of parent. + +
                  Mtr_DeallocNode() +
                  Deallocates tree node. + +
                  Mtr_DissolveGroup() +
                  Merges the children of `group' with the children of its parent. + +
                  Mtr_FindGroup() +
                  Finds a group with size leaves starting at low, if it exists. + +
                  Mtr_FreeTree() +
                  Disposes of tree rooted at node. + +
                  Mtr_InitGroupTree() +
                  Allocate new tree. + +
                  Mtr_InitTree() +
                  Initializes tree with one node. + +
                  Mtr_MakeFirstChild() +
                  Makes child the first child of parent. + +
                  Mtr_MakeGroup() +
                  Makes a new group with size leaves starting at low. + +
                  Mtr_MakeLastChild() +
                  Makes child the last child of parent. + +
                  Mtr_MakeNextSibling() +
                  Makes second the next sibling of first. + +
                  Mtr_PrintGroups() +
                  Prints the groups as a parenthesized list. + +
                  Mtr_PrintTree() +
                  Prints a tree, one node per line. + +
                  Mtr_ReadGroups() +
                  Reads groups from a file and creates a group tree. + +
                  Mtr_SwapGroups() +
                  Swaps two children of a tree node. + +
                  + +
                  + +Generated automatically by extdoc on 970123 + + diff --git a/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllDet.html b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllDet.html new file mode 100644 index 000000000..e7b789074 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrAllDet.html @@ -0,0 +1,317 @@ + +The mtr package (Internal) + + +

                  The mtr package (Internal)

                  +

                  Internal data structures of the mtr package

                  +

                  +
                  + + +
                  + + +In this package all definitions are external. + + +
                  + + +
                  + +
                  +MtrNode * 
                  +Mtr_AllocNode(
                  +    
                  +)
                  +
                  +
                  Allocates new tree node. Returns pointer to node. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_DeallocNode + + +
                  +MtrNode * 
                  +Mtr_CopyTree(
                  +  MtrNode * node, 
                  +  int  expansion 
                  +)
                  +
                  +
                  Makes a copy of tree. If parameter expansion is greater than 1, it will expand the tree by that factor. It is an error for expansion to be less than 1. Returns a pointer to the copy if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_InitTree + + +
                  +MtrNode * 
                  +Mtr_CreateFirstChild(
                  +  MtrNode * parent 
                  +)
                  +
                  +
                  Creates a new node and makes it the first child of parent. Returns pointer to new child. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_MakeFirstChild +Mtr_CreateLastChild + + +
                  +MtrNode * 
                  +Mtr_CreateLastChild(
                  +  MtrNode * parent 
                  +)
                  +
                  +
                  Creates a new node and makes it the last child of parent. Returns pointer to new child. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_MakeLastChild +Mtr_CreateFirstChild + + +
                  +void 
                  +Mtr_DeallocNode(
                  +  MtrNode * node node to be deallocated
                  +)
                  +
                  +
                  Deallocates tree node. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_AllocNode + + +
                  +MtrNode * 
                  +Mtr_DissolveGroup(
                  +  MtrNode * group group to be dissolved
                  +)
                  +
                  +
                  Merges the children of `group' with the children of its parent. Disposes of the node pointed by group. If group is the root of the group tree, this procedure leaves the tree unchanged. Returns the pointer to the parent of `group' upon successful termination; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_MakeGroup + + +
                  +MtrNode * 
                  +Mtr_FindGroup(
                  +  MtrNode * root, root of the group tree
                  +  unsigned int  low, lower bound of the group
                  +  unsigned int  size upper bound of the group
                  +)
                  +
                  +
                  Finds a group with size leaves starting at low, if it exists. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. Returns the pointer to the root of the group upon successful termination; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +void 
                  +Mtr_FreeTree(
                  +  MtrNode * node 
                  +)
                  +
                  +
                  Disposes of tree rooted at node. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_InitTree + + +
                  +MtrNode * 
                  +Mtr_InitGroupTree(
                  +  int  lower, 
                  +  int  size 
                  +)
                  +
                  +
                  Allocate new tree with one node, whose low and size fields are specified by the lower and size parameters. Returns pointer to tree root. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_InitTree +Mtr_FreeTree + + +
                  +MtrNode * 
                  +Mtr_InitTree(
                  +    
                  +)
                  +
                  +
                  Initializes tree with one node. Returns pointer to node. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_FreeTree +Mtr_InitGroupTree + + +
                  +void 
                  +Mtr_MakeFirstChild(
                  +  MtrNode * parent, 
                  +  MtrNode * child 
                  +)
                  +
                  +
                  Makes child the first child of parent. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_MakeLastChild +Mtr_CreateFirstChild + + +
                  +MtrNode * 
                  +Mtr_MakeGroup(
                  +  MtrNode * root, root of the group tree
                  +  unsigned int  low, lower bound of the group
                  +  unsigned int  size, upper bound of the group
                  +  unsigned int  flags flags for the new group
                  +)
                  +
                  +
                  Makes a new group with size leaves starting at low. If the new group intersects an existing group, it must either contain it or be contained by it. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. In case of a valid request, the flags of the new group are set to the value passed in `flags.' This can also be used to change the flags of an existing group. Returns the pointer to the root of the new group upon successful termination; NULL otherwise. If the group already exists, the pointer to its root is returned. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_DissolveGroup +Mtr_ReadGroups +Mtr_FindGroup + + +
                  +void 
                  +Mtr_MakeLastChild(
                  +  MtrNode * parent, 
                  +  MtrNode * child 
                  +)
                  +
                  +
                  Makes child the last child of parent. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_MakeFirstChild +Mtr_CreateLastChild + + +
                  +void 
                  +Mtr_MakeNextSibling(
                  +  MtrNode * first, 
                  +  MtrNode * second 
                  +)
                  +
                  +
                  Makes second the next sibling of first. Second becomes a child of the parent of first. +

                  + +

                  Side Effects None +

                  + +

                  +void 
                  +Mtr_PrintGroups(
                  +  MtrNode * root, root of the group tree
                  +  int  silent flag to check tree syntax only
                  +)
                  +
                  +
                  Prints the groups as a parenthesized list. After each group, the group's flag are printed, preceded by a `|'. For each flag (except MTR_TERMINAL) a character is printed.
                  • F: MTR_FIXED
                  • N: MTR_NEWNODE
                  • S: MTR_SOFT
                  The second argument, silent, if different from 0, causes Mtr_PrintGroups to only check the syntax of the group tree. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_PrintTree + + +
                  +void 
                  +Mtr_PrintTree(
                  +  MtrNode * node 
                  +)
                  +
                  +
                  Prints a tree, one node per line. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_PrintGroups + + +
                  +MtrNode * 
                  +Mtr_ReadGroups(
                  +  FILE * fp, file pointer
                  +  int  nleaves number of leaves of the new tree
                  +)
                  +
                  +
                  Reads groups from a file and creates a group tree. Each group is specified by three fields: low size flags. Low and size are (short) integers. Flags is a string composed of the following characters (with associated translation):
                  • D: MTR_DEFAULT
                  • F: MTR_FIXED
                  • N: MTR_NEWNODE
                  • S: MTR_SOFT
                  • T: MTR_TERMINAL
                  Normally, the only flags that are needed are D and F. Groups and fields are separated by white space (spaces, tabs, and newlines). Returns a pointer to the group tree if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_InitGroupTree +Mtr_MakeGroup + + +
                  +int 
                  +Mtr_SwapGroups(
                  +  MtrNode * first, first node to be swapped
                  +  MtrNode * second second node to be swapped
                  +)
                  +
                  +
                  Swaps two children of a tree node. Adjusts the high and low fields of the two nodes and their descendants. The two children must be adjacent. However, first may be the younger sibling of second. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + + +

                  + +
                  + +Generated automatically by extdoc on 970123 + + diff --git a/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtAbs.html b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtAbs.html new file mode 100644 index 000000000..9f48acbad --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtAbs.html @@ -0,0 +1,72 @@ + +mtr package abstract + + +

                  mtr package abstract

                  +

                  Multiway-branch tree manipulation

                  +
                  + + + +
                  +
                  Mtr_AllocNode() +
                  Allocates new tree node. + +
                  Mtr_CopyTree() +
                  Makes a copy of tree. + +
                  Mtr_CreateFirstChild() +
                  Creates a new node and makes it the first child of parent. + +
                  Mtr_CreateLastChild() +
                  Creates a new node and makes it the last child of parent. + +
                  Mtr_DeallocNode() +
                  Deallocates tree node. + +
                  Mtr_DissolveGroup() +
                  Merges the children of `group' with the children of its parent. + +
                  Mtr_FindGroup() +
                  Finds a group with size leaves starting at low, if it exists. + +
                  Mtr_FreeTree() +
                  Disposes of tree rooted at node. + +
                  Mtr_InitGroupTree() +
                  Allocate new tree. + +
                  Mtr_InitTree() +
                  Initializes tree with one node. + +
                  Mtr_MakeFirstChild() +
                  Makes child the first child of parent. + +
                  Mtr_MakeGroup() +
                  Makes a new group with size leaves starting at low. + +
                  Mtr_MakeLastChild() +
                  Makes child the last child of parent. + +
                  Mtr_MakeNextSibling() +
                  Makes second the next sibling of first. + +
                  Mtr_PrintGroups() +
                  Prints the groups as a parenthesized list. + +
                  Mtr_PrintTree() +
                  Prints a tree, one node per line. + +
                  Mtr_ReadGroups() +
                  Reads groups from a file and creates a group tree. + +
                  Mtr_SwapGroups() +
                  Swaps two children of a tree node. + +
                  + +
                  + +Generated automatically by extdoc on 970123 + + diff --git a/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtDet.html b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtDet.html new file mode 100644 index 000000000..8300c3d6a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/doc/mtrExtDet.html @@ -0,0 +1,324 @@ + +The mtr package + + +

                  The mtr package

                  +

                  Multiway-branch tree manipulation

                  +

                  +
                  + + +
                  + + +This package provides two layers of functions. Functions + of the lower level manipulate multiway-branch trees, implemented + according to the classical scheme whereby each node points to its + first child and its previous and next siblings. These functions are + collected in mtrBasic.c.

                  + Functions of the upper layer deal with group trees, that is the trees + used by group sifting to represent the grouping of variables. These + functions are collected in mtrGroup.c. + + +


                  + + +
                  + +
                  +MtrNode * 
                  +Mtr_AllocNode(
                  +    
                  +)
                  +
                  +
                  Allocates new tree node. Returns pointer to node. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_DeallocNode + + +
                  +MtrNode * 
                  +Mtr_CopyTree(
                  +  MtrNode * node, 
                  +  int  expansion 
                  +)
                  +
                  +
                  Makes a copy of tree. If parameter expansion is greater than 1, it will expand the tree by that factor. It is an error for expansion to be less than 1. Returns a pointer to the copy if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_InitTree + + +
                  +MtrNode * 
                  +Mtr_CreateFirstChild(
                  +  MtrNode * parent 
                  +)
                  +
                  +
                  Creates a new node and makes it the first child of parent. Returns pointer to new child. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_MakeFirstChild +Mtr_CreateLastChild + + +
                  +MtrNode * 
                  +Mtr_CreateLastChild(
                  +  MtrNode * parent 
                  +)
                  +
                  +
                  Creates a new node and makes it the last child of parent. Returns pointer to new child. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_MakeLastChild +Mtr_CreateFirstChild + + +
                  +void 
                  +Mtr_DeallocNode(
                  +  MtrNode * node node to be deallocated
                  +)
                  +
                  +
                  Deallocates tree node. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_AllocNode + + +
                  +MtrNode * 
                  +Mtr_DissolveGroup(
                  +  MtrNode * group group to be dissolved
                  +)
                  +
                  +
                  Merges the children of `group' with the children of its parent. Disposes of the node pointed by group. If group is the root of the group tree, this procedure leaves the tree unchanged. Returns the pointer to the parent of `group' upon successful termination; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_MakeGroup + + +
                  +MtrNode * 
                  +Mtr_FindGroup(
                  +  MtrNode * root, root of the group tree
                  +  unsigned int  low, lower bound of the group
                  +  unsigned int  size upper bound of the group
                  +)
                  +
                  +
                  Finds a group with size leaves starting at low, if it exists. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. Returns the pointer to the root of the group upon successful termination; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +void 
                  +Mtr_FreeTree(
                  +  MtrNode * node 
                  +)
                  +
                  +
                  Disposes of tree rooted at node. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_InitTree + + +
                  +MtrNode * 
                  +Mtr_InitGroupTree(
                  +  int  lower, 
                  +  int  size 
                  +)
                  +
                  +
                  Allocate new tree with one node, whose low and size fields are specified by the lower and size parameters. Returns pointer to tree root. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_InitTree +Mtr_FreeTree + + +
                  +MtrNode * 
                  +Mtr_InitTree(
                  +    
                  +)
                  +
                  +
                  Initializes tree with one node. Returns pointer to node. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_FreeTree +Mtr_InitGroupTree + + +
                  +void 
                  +Mtr_MakeFirstChild(
                  +  MtrNode * parent, 
                  +  MtrNode * child 
                  +)
                  +
                  +
                  Makes child the first child of parent. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_MakeLastChild +Mtr_CreateFirstChild + + +
                  +MtrNode * 
                  +Mtr_MakeGroup(
                  +  MtrNode * root, root of the group tree
                  +  unsigned int  low, lower bound of the group
                  +  unsigned int  size, upper bound of the group
                  +  unsigned int  flags flags for the new group
                  +)
                  +
                  +
                  Makes a new group with size leaves starting at low. If the new group intersects an existing group, it must either contain it or be contained by it. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. In case of a valid request, the flags of the new group are set to the value passed in `flags.' This can also be used to change the flags of an existing group. Returns the pointer to the root of the new group upon successful termination; NULL otherwise. If the group already exists, the pointer to its root is returned. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_DissolveGroup +Mtr_ReadGroups +Mtr_FindGroup + + +
                  +void 
                  +Mtr_MakeLastChild(
                  +  MtrNode * parent, 
                  +  MtrNode * child 
                  +)
                  +
                  +
                  Makes child the last child of parent. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_MakeFirstChild +Mtr_CreateLastChild + + +
                  +void 
                  +Mtr_MakeNextSibling(
                  +  MtrNode * first, 
                  +  MtrNode * second 
                  +)
                  +
                  +
                  Makes second the next sibling of first. Second becomes a child of the parent of first. +

                  + +

                  Side Effects None +

                  + +

                  +void 
                  +Mtr_PrintGroups(
                  +  MtrNode * root, root of the group tree
                  +  int  silent flag to check tree syntax only
                  +)
                  +
                  +
                  Prints the groups as a parenthesized list. After each group, the group's flag are printed, preceded by a `|'. For each flag (except MTR_TERMINAL) a character is printed.
                  • F: MTR_FIXED
                  • N: MTR_NEWNODE
                  • S: MTR_SOFT
                  The second argument, silent, if different from 0, causes Mtr_PrintGroups to only check the syntax of the group tree. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_PrintTree + + +
                  +void 
                  +Mtr_PrintTree(
                  +  MtrNode * node 
                  +)
                  +
                  +
                  Prints a tree, one node per line. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_PrintGroups + + +
                  +MtrNode * 
                  +Mtr_ReadGroups(
                  +  FILE * fp, file pointer
                  +  int  nleaves number of leaves of the new tree
                  +)
                  +
                  +
                  Reads groups from a file and creates a group tree. Each group is specified by three fields: low size flags. Low and size are (short) integers. Flags is a string composed of the following characters (with associated translation):
                  • D: MTR_DEFAULT
                  • F: MTR_FIXED
                  • N: MTR_NEWNODE
                  • S: MTR_SOFT
                  • T: MTR_TERMINAL
                  Normally, the only flags that are needed are D and F. Groups and fields are separated by white space (spaces, tabs, and newlines). Returns a pointer to the group tree if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Mtr_InitGroupTree +Mtr_MakeGroup + + +
                  +int 
                  +Mtr_SwapGroups(
                  +  MtrNode * first, first node to be swapped
                  +  MtrNode * second second node to be swapped
                  +)
                  +
                  +
                  Swaps two children of a tree node. Adjusts the high and low fields of the two nodes and their descendants. The two children must be adjacent. However, first may be the younger sibling of second. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + + +

                  + +
                  + +Generated automatically by extdoc on 970123 + + diff --git a/resources/3rdparty/cudd-2.5.0/mtr/mtr.h b/resources/3rdparty/cudd-2.5.0/mtr/mtr.h new file mode 100644 index 000000000..9cbb2d3a4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/mtr.h @@ -0,0 +1,187 @@ +/**CHeaderFile***************************************************************** + + FileName [mtr.h] + + PackageName [mtr] + + Synopsis [Multiway-branch tree manipulation] + + Description [This package provides two layers of functions. Functions + of the lower level manipulate multiway-branch trees, implemented + according to the classical scheme whereby each node points to its + first child and its previous and next siblings. These functions are + collected in mtrBasic.c.

                  + Functions of the upper layer deal with group trees, that is the trees + used by group sifting to represent the grouping of variables. These + functions are collected in mtrGroup.c.] + + SeeAlso [The CUDD package documentation; specifically on group + sifting.] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: mtr.h,v 1.17 2012/02/05 01:06:19 fabio Exp $] + +******************************************************************************/ + +#ifndef __MTR +#define __MTR + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef SIZEOF_VOID_P +#define SIZEOF_VOID_P 4 +#endif +#ifndef SIZEOF_INT +#define SIZEOF_INT 4 +#endif + +#if defined(__GNUC__) +#define MTR_INLINE __inline__ +# if (__GNUC__ >2 || __GNUC_MINOR__ >=7) +# define MTR_UNUSED __attribute__ ((unused)) +# else +# define MTR_UNUSED +# endif +#else +#define MTR_INLINE +#define MTR_UNUSED +#endif + +/* Flag definitions */ +#define MTR_DEFAULT 0x00000000 +#define MTR_TERMINAL 0x00000001 +#define MTR_SOFT 0x00000002 +#define MTR_FIXED 0x00000004 +#define MTR_NEWNODE 0x00000008 + +/* MTR_MAXHIGH is defined in such a way that on 32-bit and 64-bit +** machines one can cast a value to (int) without generating a negative +** number. +*/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define MTR_MAXHIGH (((MtrHalfWord) ~0) >> 1) +#else +#define MTR_MAXHIGH ((MtrHalfWord) ~0) +#endif + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +typedef unsigned int MtrHalfWord; +#else +typedef unsigned short MtrHalfWord; +#endif + +typedef struct MtrNode { + MtrHalfWord flags; + MtrHalfWord low; + MtrHalfWord size; + MtrHalfWord index; + struct MtrNode *parent; + struct MtrNode *child; + struct MtrNode *elder; + struct MtrNode *younger; +} MtrNode; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/* Flag manipulation macros */ +#define MTR_SET(node, flag) (node->flags |= (flag)) +#define MTR_RESET(node, flag) (node->flags &= ~ (flag)) +#define MTR_TEST(node, flag) (node->flags & (flag)) + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern MtrNode * Mtr_AllocNode (void); +extern void Mtr_DeallocNode (MtrNode *node); +extern MtrNode * Mtr_InitTree (void); +extern void Mtr_FreeTree (MtrNode *node); +extern MtrNode * Mtr_CopyTree (MtrNode *node, int expansion); +extern void Mtr_MakeFirstChild (MtrNode *parent, MtrNode *child); +extern void Mtr_MakeLastChild (MtrNode *parent, MtrNode *child); +extern MtrNode * Mtr_CreateFirstChild (MtrNode *parent); +extern MtrNode * Mtr_CreateLastChild (MtrNode *parent); +extern void Mtr_MakeNextSibling (MtrNode *first, MtrNode *second); +extern void Mtr_PrintTree (MtrNode *node); +extern MtrNode * Mtr_InitGroupTree (int lower, int size); +extern MtrNode * Mtr_MakeGroup (MtrNode *root, unsigned int low, unsigned int high, unsigned int flags); +extern MtrNode * Mtr_DissolveGroup (MtrNode *group); +extern MtrNode * Mtr_FindGroup (MtrNode *root, unsigned int low, unsigned int high); +extern int Mtr_SwapGroups (MtrNode *first, MtrNode *second); +extern void Mtr_ReorderGroups(MtrNode *treenode, int *permutation); + +extern void Mtr_PrintGroups (MtrNode *root, int silent); + extern int Mtr_PrintGroupedOrder(MtrNode * root, int *invperm, FILE *fp); +extern MtrNode * Mtr_ReadGroups (FILE *fp, int nleaves); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* __MTR */ diff --git a/resources/3rdparty/cudd-2.5.0/mtr/mtrBasic.c b/resources/3rdparty/cudd-2.5.0/mtr/mtrBasic.c new file mode 100644 index 000000000..f91c63430 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/mtrBasic.c @@ -0,0 +1,450 @@ +/**CFile*********************************************************************** + + FileName [mtrBasic.c] + + PackageName [mtr] + + Synopsis [Basic manipulation of multiway branching trees.] + + Description [External procedures included in this module: +

                    +
                  • Mtr_AllocNode() +
                  • Mtr_DeallocNode() +
                  • Mtr_InitTree() +
                  • Mtr_FreeTree() +
                  • Mtr_CopyTree() +
                  • Mtr_MakeFirstChild() +
                  • Mtr_MakeLastChild() +
                  • Mtr_CreateFirstChild() +
                  • Mtr_CreateLastChild() +
                  • Mtr_MakeNextSibling() +
                  • Mtr_PrintTree() +
                  + ] + + SeeAlso [cudd package] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "mtrInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] MTR_UNUSED = "$Id: mtrBasic.c,v 1.15 2012/02/05 01:06:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Allocates new tree node.] + + Description [Allocates new tree node. Returns pointer to node.] + + SideEffects [None] + + SeeAlso [Mtr_DeallocNode] + +******************************************************************************/ +MtrNode * +Mtr_AllocNode(void) +{ + MtrNode *node; + + node = ALLOC(MtrNode,1); + return node; + +} /* Mtr_AllocNode */ + + +/**Function******************************************************************** + + Synopsis [Deallocates tree node.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_AllocNode] + +******************************************************************************/ +void +Mtr_DeallocNode( + MtrNode * node /* node to be deallocated */) +{ + FREE(node); + return; + +} /* end of Mtr_DeallocNode */ + + +/**Function******************************************************************** + + Synopsis [Initializes tree with one node.] + + Description [Initializes tree with one node. Returns pointer to node.] + + SideEffects [None] + + SeeAlso [Mtr_FreeTree Mtr_InitGroupTree] + +******************************************************************************/ +MtrNode * +Mtr_InitTree(void) +{ + MtrNode *node; + + node = Mtr_AllocNode(); + if (node == NULL) return(NULL); + + node->parent = node->child = node->elder = node->younger = NULL; + node->flags = 0; + + return(node); + +} /* end of Mtr_InitTree */ + + +/**Function******************************************************************** + + Synopsis [Disposes of tree rooted at node.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_InitTree] + +******************************************************************************/ +void +Mtr_FreeTree( + MtrNode * node) +{ + if (node == NULL) return; + if (! MTR_TEST(node,MTR_TERMINAL)) Mtr_FreeTree(node->child); + Mtr_FreeTree(node->younger); + Mtr_DeallocNode(node); + return; + +} /* end of Mtr_FreeTree */ + + +/**Function******************************************************************** + + Synopsis [Makes a copy of tree.] + + Description [Makes a copy of tree. If parameter expansion is greater + than 1, it will expand the tree by that factor. It is an error for + expansion to be less than 1. Returns a pointer to the copy if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Mtr_InitTree] + +******************************************************************************/ +MtrNode * +Mtr_CopyTree( + MtrNode * node, + int expansion) +{ + MtrNode *copy; + + if (node == NULL) return(NULL); + if (expansion < 1) return(NULL); + copy = Mtr_AllocNode(); + if (copy == NULL) return(NULL); + copy->parent = copy->elder = copy->child = copy->younger = NULL; + if (node->child != NULL) { + copy->child = Mtr_CopyTree(node->child, expansion); + if (copy->child == NULL) { + Mtr_DeallocNode(copy); + return(NULL); + } + } + if (node->younger != NULL) { + copy->younger = Mtr_CopyTree(node->younger, expansion); + if (copy->younger == NULL) { + Mtr_FreeTree(copy); + return(NULL); + } + } + copy->flags = node->flags; + copy->low = node->low * expansion; + copy->size = node->size * expansion; + copy->index = node->index * expansion; + if (copy->younger) copy->younger->elder = copy; + if (copy->child) { + MtrNode *auxnode = copy->child; + while (auxnode != NULL) { + auxnode->parent = copy; + auxnode = auxnode->younger; + } + } + return(copy); + +} /* end of Mtr_CopyTree */ + + +/**Function******************************************************************** + + Synopsis [Makes child the first child of parent.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_MakeLastChild Mtr_CreateFirstChild] + +******************************************************************************/ +void +Mtr_MakeFirstChild( + MtrNode * parent, + MtrNode * child) +{ + child->parent = parent; + child->younger = parent->child; + child->elder = NULL; + if (parent->child != NULL) { +#ifdef MTR_DEBUG + assert(parent->child->elder == NULL); +#endif + parent->child->elder = child; + } + parent->child = child; + return; + +} /* end of Mtr_MakeFirstChild */ + + +/**Function******************************************************************** + + Synopsis [Makes child the last child of parent.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_MakeFirstChild Mtr_CreateLastChild] + +******************************************************************************/ +void +Mtr_MakeLastChild( + MtrNode * parent, + MtrNode * child) +{ + MtrNode *node; + + child->younger = NULL; + + if (parent->child == NULL) { + parent->child = child; + child->elder = NULL; + } else { + for (node = parent->child; + node->younger != NULL; + node = node->younger); + node->younger = child; + child->elder = node; + } + child->parent = parent; + return; + +} /* end of Mtr_MakeLastChild */ + + +/**Function******************************************************************** + + Synopsis [Creates a new node and makes it the first child of parent.] + + Description [Creates a new node and makes it the first child of + parent. Returns pointer to new child.] + + SideEffects [None] + + SeeAlso [Mtr_MakeFirstChild Mtr_CreateLastChild] + +******************************************************************************/ +MtrNode * +Mtr_CreateFirstChild( + MtrNode * parent) +{ + MtrNode *child; + + child = Mtr_AllocNode(); + if (child == NULL) return(NULL); + + child->child = NULL; + child->flags = 0; + Mtr_MakeFirstChild(parent,child); + return(child); + +} /* end of Mtr_CreateFirstChild */ + + +/**Function******************************************************************** + + Synopsis [Creates a new node and makes it the last child of parent.] + + Description [Creates a new node and makes it the last child of parent. + Returns pointer to new child.] + + SideEffects [None] + + SeeAlso [Mtr_MakeLastChild Mtr_CreateFirstChild] + +******************************************************************************/ +MtrNode * +Mtr_CreateLastChild( + MtrNode * parent) +{ + MtrNode *child; + + child = Mtr_AllocNode(); + if (child == NULL) return(NULL); + + child->child = NULL; + child->flags = 0; + Mtr_MakeLastChild(parent,child); + return(child); + +} /* end of Mtr_CreateLastChild */ + + +/**Function******************************************************************** + + Synopsis [Makes second the next sibling of first.] + + Description [Makes second the next sibling of first. Second becomes a + child of the parent of first.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Mtr_MakeNextSibling( + MtrNode * first, + MtrNode * second) +{ + second->parent = first->parent; + second->elder = first; + second->younger = first->younger; + if (first->younger != NULL) { + first->younger->elder = second; + } + first->younger = second; + return; + +} /* end of Mtr_MakeNextSibling */ + + +/**Function******************************************************************** + + Synopsis [Prints a tree, one node per line.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_PrintGroups] + +******************************************************************************/ +void +Mtr_PrintTree( + MtrNode * node) +{ + if (node == NULL) return; + (void) fprintf(stdout, +#if SIZEOF_VOID_P == 8 + "N=0x%-8lx C=0x%-8lx Y=0x%-8lx E=0x%-8lx P=0x%-8lx F=%x L=%u S=%u\n", + (unsigned long) node, (unsigned long) node->child, + (unsigned long) node->younger, (unsigned long) node->elder, + (unsigned long) node->parent, node->flags, node->low, node->size); +#else + "N=0x%-8x C=0x%-8x Y=0x%-8x E=0x%-8x P=0x%-8x F=%x L=%hu S=%hu\n", + (unsigned) node, (unsigned) node->child, + (unsigned) node->younger, (unsigned) node->elder, + (unsigned) node->parent, node->flags, node->low, node->size); +#endif + if (!MTR_TEST(node,MTR_TERMINAL)) Mtr_PrintTree(node->child); + Mtr_PrintTree(node->younger); + return; + +} /* end of Mtr_PrintTree */ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/mtr/mtrGroup.c b/resources/3rdparty/cudd-2.5.0/mtr/mtrGroup.c new file mode 100644 index 000000000..4269cf848 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/mtrGroup.c @@ -0,0 +1,877 @@ +/**CFile*********************************************************************** + + FileName [mtrGroup.c] + + PackageName [mtr] + + Synopsis [Functions to support group specification for reordering.] + + Description [External procedures included in this module: +
                    +
                  • Mtr_InitGroupTree() +
                  • Mtr_MakeGroup() +
                  • Mtr_DissolveGroup() +
                  • Mtr_FindGroup() +
                  • Mtr_SwapGroups() +
                  • Mtr_ReorderGroups() +
                  • Mtr_PrintGroups() +
                  • Mtr_ReadGroups() +
                  + Static procedures included in this module: +
                    +
                  • mtrShiftHL +
                  + ] + + SeeAlso [cudd package] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "mtrInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] MTR_UNUSED = "$Id: mtrGroup.c,v 1.21 2012/02/05 01:06:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int mtrShiftHL (MtrNode *node, int shift); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Allocate new tree.] + + Description [Allocate new tree with one node, whose low and size + fields are specified by the lower and size parameters. + Returns pointer to tree root.] + + SideEffects [None] + + SeeAlso [Mtr_InitTree Mtr_FreeTree] + +******************************************************************************/ +MtrNode * +Mtr_InitGroupTree( + int lower, + int size) +{ + MtrNode *root; + + root = Mtr_InitTree(); + if (root == NULL) return(NULL); + root->flags = MTR_DEFAULT; + root->low = lower; + root->size = size; + return(root); + +} /* end of Mtr_InitGroupTree */ + + +/**Function******************************************************************** + + Synopsis [Makes a new group with size leaves starting at low.] + + Description [Makes a new group with size leaves starting at low. + If the new group intersects an existing group, it must + either contain it or be contained by it. This procedure relies on + the low and size fields of each node. It also assumes that the + children of each node are sorted in order of increasing low. In + case of a valid request, the flags of the new group are set to the + value passed in `flags.' Returns the pointer to the root of the new + group upon successful termination; NULL otherwise. If the group + already exists, the pointer to its root is returned.] + + SideEffects [None] + + SeeAlso [Mtr_DissolveGroup Mtr_ReadGroups Mtr_FindGroup] + +******************************************************************************/ +MtrNode * +Mtr_MakeGroup( + MtrNode * root /* root of the group tree */, + unsigned int low /* lower bound of the group */, + unsigned int size /* size of the group */, + unsigned int flags /* flags for the new group */) +{ + MtrNode *node, + *first, + *last, + *previous, + *newn; + + /* Sanity check. */ + if (size == 0) + return(NULL); + + /* Check whether current group includes new group. This check is + ** necessary at the top-level call. In the subsequent calls it is + ** redundant. */ + if (low < (unsigned int) root->low || + low + size > (unsigned int) (root->low + root->size)) + return(NULL); + + /* At this point we know that the new group is contained + ** in the group of root. We have two possible cases here: + ** - root is a terminal node; + ** - root has children. */ + + /* Root has no children: create a new group. */ + if (root->child == NULL) { + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->parent = root; + newn->elder = newn->younger = newn->child = NULL; + root->child = newn; + return(newn); + } + + /* Root has children: Find all children of root that are included + ** in the new group. If the group of any child entirely contains + ** the new group, call Mtr_MakeGroup recursively. */ + previous = NULL; + first = root->child; /* guaranteed to be non-NULL */ + while (first != NULL && low >= (unsigned int) (first->low + first->size)) { + previous = first; + first = first->younger; + } + if (first == NULL) { + /* We have scanned the entire list and we need to append a new + ** child at the end of it. Previous points to the last child + ** of root. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->parent = root; + newn->elder = previous; + previous->younger = newn; + newn->younger = newn->child = NULL; + return(newn); + } + /* Here first is non-NULL and low < first->low + first->size. */ + if (low >= (unsigned int) first->low && + low + size <= (unsigned int) (first->low + first->size)) { + /* The new group is contained in the group of first. */ + newn = Mtr_MakeGroup(first, low, size, flags); + return(newn); + } else if (low + size <= first->low) { + /* The new group is entirely contained in the gap between + ** previous and first. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->child = NULL; + newn->parent = root; + newn->elder = previous; + newn->younger = first; + first->elder = newn; + if (previous != NULL) { + previous->younger = newn; + } else { + root->child = newn; + } + return(newn); + } else if (low < (unsigned int) first->low && + low + size < (unsigned int) (first->low + first->size)) { + /* Trying to cut an existing group: not allowed. */ + return(NULL); + } else if (low > first->low) { + /* The new group neither is contained in the group of first + ** (this was tested above) nor contains it. It is therefore + ** trying to cut an existing group: not allowed. */ + return(NULL); + } + + /* First holds the pointer to the first child contained in the new + ** group. Here low <= first->low and low + size >= first->low + + ** first->size. One of the two inequalities is strict. */ + last = first->younger; + while (last != NULL && + (unsigned int) (last->low + last->size) < low + size) { + last = last->younger; + } + if (last == NULL) { + /* All the chilren of root from first onward become children + ** of the new group. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->child = first; + newn->parent = root; + newn->elder = previous; + newn->younger = NULL; + first->elder = NULL; + if (previous != NULL) { + previous->younger = newn; + } else { + root->child = newn; + } + last = first; + while (last != NULL) { + last->parent = newn; + last = last->younger; + } + return(newn); + } + + /* Here last != NULL and low + size <= last->low + last->size. */ + if (low + size - 1 >= (unsigned int) last->low && + low + size < (unsigned int) (last->low + last->size)) { + /* Trying to cut an existing group: not allowed. */ + return(NULL); + } + + /* First and last point to the first and last of the children of + ** root that are included in the new group. Allocate a new node + ** and make all children of root between first and last chidren of + ** the new node. Previous points to the child of root immediately + ** preceeding first. If it is NULL, then first is the first child + ** of root. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->child = first; + newn->parent = root; + if (previous == NULL) { + root->child = newn; + } else { + previous->younger = newn; + } + newn->elder = previous; + newn->younger = last->younger; + if (last->younger != NULL) { + last->younger->elder = newn; + } + last->younger = NULL; + first->elder = NULL; + for (node = first; node != NULL; node = node->younger) { + node->parent = newn; + } + + return(newn); + +} /* end of Mtr_MakeGroup */ + + +/**Function******************************************************************** + + Synopsis [Merges the children of `group' with the children of its + parent.] + + Description [Merges the children of `group' with the children of its + parent. Disposes of the node pointed by group. If group is the + root of the group tree, this procedure leaves the tree unchanged. + Returns the pointer to the parent of `group' upon successful + termination; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Mtr_MakeGroup] + +******************************************************************************/ +MtrNode * +Mtr_DissolveGroup( + MtrNode * group /* group to be dissolved */) +{ + MtrNode *parent; + MtrNode *last; + + parent = group->parent; + + if (parent == NULL) return(NULL); + if (MTR_TEST(group,MTR_TERMINAL) || group->child == NULL) return(NULL); + + /* Make all children of group children of its parent, and make + ** last point to the last child of group. */ + for (last = group->child; last->younger != NULL; last = last->younger) { + last->parent = parent; + } + last->parent = parent; + + last->younger = group->younger; + if (group->younger != NULL) { + group->younger->elder = last; + } + + group->child->elder = group->elder; + if (group == parent->child) { + parent->child = group->child; + } else { + group->elder->younger = group->child; + } + + Mtr_DeallocNode(group); + return(parent); + +} /* end of Mtr_DissolveGroup */ + + +/**Function******************************************************************** + + Synopsis [Finds a group with size leaves starting at low, if it exists.] + + Description [Finds a group with size leaves starting at low, if it + exists. This procedure relies on the low and size fields of each + node. It also assumes that the children of each node are sorted in + order of increasing low. Returns the pointer to the root of the + group upon successful termination; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +MtrNode * +Mtr_FindGroup( + MtrNode * root /* root of the group tree */, + unsigned int low /* lower bound of the group */, + unsigned int size /* upper bound of the group */) +{ + MtrNode *node; + +#ifdef MTR_DEBUG + /* We cannot have a non-empty proper subgroup of a singleton set. */ + assert(!MTR_TEST(root,MTR_TERMINAL)); +#endif + + /* Sanity check. */ + if (size < 1) return(NULL); + + /* Check whether current group includes the group sought. This + ** check is necessary at the top-level call. In the subsequent + ** calls it is redundant. */ + if (low < (unsigned int) root->low || + low + size > (unsigned int) (root->low + root->size)) + return(NULL); + + if (root->size == size && root->low == low) + return(root); + + if (root->child == NULL) + return(NULL); + + /* Find all chidren of root that are included in the new group. If + ** the group of any child entirely contains the new group, call + ** Mtr_MakeGroup recursively. */ + node = root->child; + while (low >= (unsigned int) (node->low + node->size)) { + node = node->younger; + } + if (low + size <= (unsigned int) (node->low + node->size)) { + /* The group is contained in the group of node. */ + node = Mtr_FindGroup(node, low, size); + return(node); + } else { + return(NULL); + } + +} /* end of Mtr_FindGroup */ + + +/**Function******************************************************************** + + Synopsis [Swaps two children of a tree node.] + + Description [Swaps two children of a tree node. Adjusts the high and + low fields of the two nodes and their descendants. The two children + must be adjacent. However, first may be the younger sibling of second. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Mtr_SwapGroups( + MtrNode * first /* first node to be swapped */, + MtrNode * second /* second node to be swapped */) +{ + MtrNode *node; + MtrNode *parent; + int sizeFirst; + int sizeSecond; + + if (second->younger == first) { /* make first first */ + node = first; + first = second; + second = node; + } else if (first->younger != second) { /* non-adjacent */ + return(0); + } + + sizeFirst = first->size; + sizeSecond = second->size; + + /* Swap the two nodes. */ + parent = first->parent; + if (parent == NULL || second->parent != parent) return(0); + if (parent->child == first) { + parent->child = second; + } else { /* first->elder != NULL */ + first->elder->younger = second; + } + if (second->younger != NULL) { + second->younger->elder = first; + } + first->younger = second->younger; + second->elder = first->elder; + first->elder = second; + second->younger = first; + + /* Adjust the high and low fields. */ + if (!mtrShiftHL(first,sizeSecond)) return(0); + if (!mtrShiftHL(second,-sizeFirst)) return(0); + + return(1); + +} /* end of Mtr_SwapGroups */ + + +/**Function******************************************************************** + + Synopsis [Fix variable tree at the end of tree sifting.] + + Description [Fix the levels in the variable tree sorting siblings + according to them. It should be called on a non-NULL tree. It then + maintains this invariant. It applies insertion sorting to the list of + siblings The order is determined by permutation, which is used to find + the new level of the node index. Index must refer to the first variable + in the group.] + + SideEffects [The tree is modified.] + + SeeAlso [] + +******************************************************************************/ +void +Mtr_ReorderGroups( + MtrNode *treenode, + int *permutation) +{ + MtrNode *auxnode; + /* Initialize sorted list to first element. */ + MtrNode *sorted = treenode; + sorted->low = permutation[sorted->index]; + if (sorted->child != NULL) + Mtr_ReorderGroups(sorted->child, permutation); + + auxnode = treenode->younger; + while (auxnode != NULL) { + MtrNode *rightplace; + MtrNode *moving = auxnode; + auxnode->low = permutation[auxnode->index]; + if (auxnode->child != NULL) + Mtr_ReorderGroups(auxnode->child, permutation); + rightplace = auxnode->elder; + /* Find insertion point. */ + while (rightplace != NULL && auxnode->low < rightplace->low) + rightplace = rightplace->elder; + auxnode = auxnode->younger; + if (auxnode != NULL) { + auxnode->elder = moving->elder; + auxnode->elder->younger = auxnode; + } else { + moving->elder->younger = NULL; + } + if (rightplace == NULL) { /* Move to head of sorted list. */ + sorted->elder = moving; + moving->elder = NULL; + moving->younger = sorted; + sorted = moving; + } else { /* Splice. */ + moving->elder = rightplace; + moving->younger = rightplace->younger; + if (rightplace->younger != NULL) + rightplace->younger->elder = moving; + rightplace->younger = moving; + } + } + /* Fix parent. */ + if (sorted->parent != NULL) + sorted->parent->child = sorted; + +} /* end of Mtr_ReorderGroups */ + + +/**Function******************************************************************** + + Synopsis [Prints the groups as a parenthesized list.] + + Description [Prints the groups as a parenthesized list. After each + group, the group's flag are printed, preceded by a `|'. For each + flag (except MTR_TERMINAL) a character is printed. +
                    +
                  • F: MTR_FIXED +
                  • N: MTR_NEWNODE +
                  • S: MTR_SOFT +
                  + The second argument, silent, if different from 0, causes + Mtr_PrintGroups to only check the syntax of the group tree. + ] + + SideEffects [None] + + SeeAlso [Mtr_PrintTree] + +******************************************************************************/ +void +Mtr_PrintGroups( + MtrNode * root /* root of the group tree */, + int silent /* flag to check tree syntax only */) +{ + MtrNode *node; + + assert(root != NULL); + assert(root->younger == NULL || root->younger->elder == root); + assert(root->elder == NULL || root->elder->younger == root); +#if SIZEOF_VOID_P == 8 + if (!silent) (void) printf("(%u",root->low); +#else + if (!silent) (void) printf("(%hu",root->low); +#endif + if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) { + if (!silent) (void) printf(","); + } else { + node = root->child; + while (node != NULL) { + assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size)); + assert(node->parent == root); + Mtr_PrintGroups(node,silent); + node = node->younger; + } + } + if (!silent) { +#if SIZEOF_VOID_P == 8 + (void) printf("%u", root->low + root->size - 1); +#else + (void) printf("%hu", root->low + root->size - 1); +#endif + if (root->flags != MTR_DEFAULT) { + (void) printf("|"); + if (MTR_TEST(root,MTR_FIXED)) (void) printf("F"); + if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N"); + if (MTR_TEST(root,MTR_SOFT)) (void) printf("S"); + } + (void) printf(")"); + if (root->parent == NULL) (void) printf("\n"); + } + assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0); + return; + +} /* end of Mtr_PrintGroups */ + + +/**Function******************************************************************** + + Synopsis [Prints the variable order as a parenthesized list.] + + Description [Prints the variable order as a parenthesized list. After each + group, the group's flag are printed, preceded by a `|'. For each + flag (except MTR_TERMINAL) a character is printed. +
                    +
                  • F: MTR_FIXED +
                  • N: MTR_NEWNODE +
                  • S: MTR_SOFT +
                  + The second argument, gives the map from levels to variable indices. + ] + + SideEffects [None] + + SeeAlso [Mtr_PrintGroups] + +******************************************************************************/ +int +Mtr_PrintGroupedOrder( + MtrNode * root /* root of the group tree */, + int *invperm /* map from levels to indices */, + FILE *fp /* output file */) +{ + MtrNode *child; + MtrHalfWord level; + int retval; + + assert(root != NULL); + assert(root->younger == NULL || root->younger->elder == root); + assert(root->elder == NULL || root->elder->younger == root); + retval = fprintf(fp,"("); + if (retval == EOF) return(0); + level = root->low; + child = root->child; + while (child != NULL) { + assert(child->low >= root->low && (child->low + child->size) <= (root->low + root->size)); + assert(child->parent == root); + while (level < child->low) { + retval = fprintf(fp,"%d%s", invperm[level], (level < root->low + root->size - 1) ? "," : ""); + if (retval == EOF) return(0); + level++; + } + retval = Mtr_PrintGroupedOrder(child,invperm,fp); + if (retval == 0) return(0); + level += child->size; + if (level < root->low + root->size - 1) { + retval = fprintf(fp,","); + if (retval == EOF) return(0); + } + child = child->younger; + } + while (level < root->low + root->size) { + retval = fprintf(fp,"%d%s", invperm[level], (level < root->low + root->size - 1) ? "," : ""); + if (retval == EOF) return(0); + level++; + } + if (root->flags != MTR_DEFAULT) { + retval = fprintf(fp,"|"); + if (retval == EOF) return(0); + if (MTR_TEST(root,MTR_FIXED)) { + retval = fprintf(fp,"F"); + if (retval == EOF) return(0); + } + if (MTR_TEST(root,MTR_NEWNODE)) { + retval = fprintf(fp,"N"); + if (retval == EOF) return(0); + } + if (MTR_TEST(root,MTR_SOFT)) { + retval = fprintf(fp,"S"); + if (retval == EOF) return(0); + } + } + retval = fprintf(fp,")"); + if (retval == EOF) return(0); + if (root->parent == NULL) { + retval = fprintf(fp,"\n"); + if (retval == EOF) return(0); + } + assert((root->flags &~(MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0); + return(1); + +} /* end of Mtr_PrintGroupedOrder */ + + +/**Function******************************************************************** + + Synopsis [Reads groups from a file and creates a group tree.] + + Description [Reads groups from a file and creates a group tree. + Each group is specified by three fields: + + low size flags. + + Low and size are (short) integers. Flags is a string composed of the + following characters (with associated translation): +
                    +
                  • D: MTR_DEFAULT +
                  • F: MTR_FIXED +
                  • N: MTR_NEWNODE +
                  • S: MTR_SOFT +
                  • T: MTR_TERMINAL +
                  + Normally, the only flags that are needed are D and F. Groups and + fields are separated by white space (spaces, tabs, and newlines). + Returns a pointer to the group tree if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Mtr_InitGroupTree Mtr_MakeGroup] + +******************************************************************************/ +MtrNode * +Mtr_ReadGroups( + FILE * fp /* file pointer */, + int nleaves /* number of leaves of the new tree */) +{ + int low; + int size; + int err; + unsigned int flags; + MtrNode *root; + MtrNode *node; + char attrib[8*sizeof(unsigned int)+1]; + char *c; + + root = Mtr_InitGroupTree(0,nleaves); + if (root == NULL) return NULL; + + while (! feof(fp)) { + /* Read a triple and check for consistency. */ + err = fscanf(fp, "%d %d %s", &low, &size, attrib); + if (err == EOF) { + break; + } else if (err != 3) { + Mtr_FreeTree(root); + return(NULL); + } else if (low < 0 || low+size > nleaves || size < 1) { + Mtr_FreeTree(root); + return(NULL); + } else if (strlen(attrib) > 8 * sizeof(MtrHalfWord)) { + /* Not enough bits in the flags word to store these many + ** attributes. */ + Mtr_FreeTree(root); + return(NULL); + } + + /* Parse the flag string. Currently all flags are permitted, + ** to make debugging easier. Normally, specifying NEWNODE + ** wouldn't be allowed. */ + flags = MTR_DEFAULT; + for (c=attrib; *c != 0; c++) { + switch (*c) { + case 'D': + break; + case 'F': + flags |= MTR_FIXED; + break; + case 'N': + flags |= MTR_NEWNODE; + break; + case 'S': + flags |= MTR_SOFT; + break; + case 'T': + flags |= MTR_TERMINAL; + break; + default: + return NULL; + } + } + node = Mtr_MakeGroup(root, (MtrHalfWord) low, (MtrHalfWord) size, + flags); + if (node == NULL) { + Mtr_FreeTree(root); + return(NULL); + } + } + + return(root); + +} /* end of Mtr_ReadGroups */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Adjusts the low fields of a node and its descendants.] + + Description [Adjusts the low fields of a node and its + descendants. Adds shift to low of each node. Checks that no + out-of-bounds values result. Returns 1 in case of success; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +mtrShiftHL( + MtrNode * node /* group tree node */, + int shift /* amount by which low should be changed */) +{ + MtrNode *auxnode; + int low; + + low = (int) node->low; + + + low += shift; + + if (low < 0 || low + (int) (node->size - 1) > (int) MTR_MAXHIGH) return(0); + + node->low = (MtrHalfWord) low; + + if (!MTR_TEST(node,MTR_TERMINAL) && node->child != NULL) { + auxnode = node->child; + do { + if (!mtrShiftHL(auxnode,shift)) return(0); + auxnode = auxnode->younger; + } while (auxnode != NULL); + } + + return(1); + +} /* end of mtrShiftHL */ diff --git a/resources/3rdparty/cudd-2.5.0/mtr/mtrInt.h b/resources/3rdparty/cudd-2.5.0/mtr/mtrInt.h new file mode 100644 index 000000000..00b2e9969 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/mtrInt.h @@ -0,0 +1,92 @@ +/**CHeaderFile***************************************************************** + + FileName [mtrInt.h] + + PackageName [mtr] + + Synopsis [Internal data structures of the mtr package] + + Description [In this package all definitions are external.] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: mtrInt.h,v 1.3 2012/02/05 01:06:19 fabio Exp $] + +******************************************************************************/ + +#ifndef _MTRINT +#define _MTRINT + +#include "mtr.h" + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + +#endif /* _MTRINT */ diff --git a/resources/3rdparty/cudd-2.5.0/mtr/test.groups b/resources/3rdparty/cudd-2.5.0/mtr/test.groups new file mode 100644 index 000000000..fbedcaf1e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/test.groups @@ -0,0 +1,5 @@ +0 6 D +6 6 F +0 2 D +2 2 D +4 2 D diff --git a/resources/3rdparty/cudd-2.5.0/mtr/testmtr.c b/resources/3rdparty/cudd-2.5.0/mtr/testmtr.c new file mode 100644 index 000000000..54f069d56 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/mtr/testmtr.c @@ -0,0 +1,270 @@ +/**CFile*********************************************************************** + + FileName [testmtr.c] + + PackageName [mtr] + + Synopsis [Test program for the mtr package.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "mtr.h" + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] MTR_UNUSED = "$Id: testmtr.c,v 1.5 2012/02/05 06:10:35 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define TESTMTR_VERSION\ + "TestMtr Version #0.6, Release date 2/6/12" + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void usage (char *prog); +static FILE * open_file (const char *filename, const char *mode); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Main program for testmtr.] + + Description [Main program for testmtr. Performs initialization. + Reads command line options and network(s). Builds some simple trees + and prints them out.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +main( + int argc, + char ** argv) +{ + MtrNode *root, + *node; + int i, + c, + pr = 0; + FILE *fp; + const char *file = NULL; + + (void) printf("# %s\n", TESTMTR_VERSION); + /* Echo command line and arguments. */ + (void) printf("#"); + for(i = 0; i < argc; i++) { + (void) printf(" %s", argv[i]); + } + (void) printf("\n"); + (void) fflush(stdout); + + while ((c = getopt(argc, argv, "Mhp:")) != EOF) { + switch(c) { + case 'M': +#ifdef MNEMOSYNE + (void) mnem_setrecording(0); +#endif + break; + case 'p': + pr = atoi(optarg); + break; + case 'h': + default: + usage(argv[0]); + break; + } + } + + if (argc - optind == 0) { + file = "-"; + } else if (argc - optind == 1) { + file = argv[optind]; + } else { + usage(argv[0]); + } + + /* Create and print a simple tree. */ + root = Mtr_InitTree(); + root->flags = 0; + node = Mtr_CreateFirstChild(root); + node->flags = 1; + node = Mtr_CreateLastChild(root); + node->flags = 2; + node = Mtr_CreateFirstChild(root); + node->flags = 3; + node = Mtr_AllocNode(); + node->flags = 4; + Mtr_MakeNextSibling(root->child,node); + Mtr_PrintTree(root); + Mtr_FreeTree(root); + (void) printf("#------------------------\n"); + + /* Create an initial tree in which all variables belong to one group. */ + root = Mtr_InitGroupTree(0,12); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + node = Mtr_MakeGroup(root,0,6,MTR_DEFAULT); + node = Mtr_MakeGroup(root,6,6,MTR_DEFAULT); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + for (i = 0; i < 6; i+=2) { + node = Mtr_MakeGroup(root,(unsigned) i,(unsigned) 2,MTR_DEFAULT); + } + node = Mtr_MakeGroup(root,0,12,MTR_FIXED); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + /* Print a partial tree. */ + (void) printf("# "); + Mtr_PrintGroups(root->child,pr == 0); (void) printf("\n"); + node = Mtr_FindGroup(root,0,6); + node = Mtr_DissolveGroup(node); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + node = Mtr_FindGroup(root,4,2); + if (!Mtr_SwapGroups(node,node->younger)) { + (void) printf("error in Mtr_SwapGroups\n"); + exit(3); + } + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); + Mtr_FreeTree(root); + (void) printf("#------------------------\n"); + + /* Create a group tree with fixed subgroups. */ + root = Mtr_InitGroupTree(0,4); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + node = Mtr_MakeGroup(root,0,2,MTR_FIXED); + node = Mtr_MakeGroup(root,2,2,MTR_FIXED); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + Mtr_FreeTree(root); + (void) printf("#------------------------\n"); + + /* Open input file. */ + fp = open_file(file, "r"); + root = Mtr_ReadGroups(fp,12); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + + Mtr_FreeTree(root); + +#ifdef MNEMOSYNE + mnem_writestats(); +#endif + + exit(0); + /* NOTREACHED */ + +} /* end of main */ + + +/**Function******************************************************************** + + Synopsis [Prints usage message and exits.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static void +usage( + char * prog) +{ + (void) fprintf(stderr, "usage: %s [options] [file]\n", prog); + (void) fprintf(stderr, " -M\t\tturns off memory allocation recording\n"); + (void) fprintf(stderr, " -h\t\tprints this message\n"); + (void) fprintf(stderr, " -p n\t\tcontrols verbosity\n"); + exit(2); + +} /* end of usage */ + + +/**Function******************************************************************** + + Synopsis [Opens a file.] + + Description [Opens a file, or fails with an error message and exits. + Allows '-' as a synonym for standard input.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static FILE * +open_file( + const char * filename, + const char * mode) +{ + FILE *fp; + + if (strcmp(filename, "-") == 0) { + return mode[0] == 'r' ? stdin : stdout; + } else if ((fp = fopen(filename, mode)) == NULL) { + perror(filename); + exit(1); + } + return(fp); + +} /* end of open_file */ + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/C17.blif b/resources/3rdparty/cudd-2.5.0/nanotrav/C17.blif new file mode 100644 index 000000000..b022c7f95 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/C17.blif @@ -0,0 +1,16 @@ +.model C17.iscas +.inputs 1GAT(0) 2GAT(1) 3GAT(2) 6GAT(3) 7GAT(4) +.outputs 22GAT(10) 23GAT(9) +.names 3GAT(2) 6GAT(3) 11GAT(5) +11 0 +.names 1GAT(0) 3GAT(2) 10GAT(6) +11 0 +.names 11GAT(5) 7GAT(4) 19GAT(7) +11 0 +.names 2GAT(1) 11GAT(5) 16GAT(8) +11 0 +.names 16GAT(8) 19GAT(7) 23GAT(9) +11 0 +.names 10GAT(6) 16GAT(8) 22GAT(10) +11 0 +.end diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/C17.out b/resources/3rdparty/cudd-2.5.0/nanotrav/C17.out new file mode 100644 index 000000000..dd7302744 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/C17.out @@ -0,0 +1,101 @@ +# Nanotrav Version #0.12, Release date 2003/12/31 +# ./nanotrav -p 1 -cover C17.blif +# CUDD Version 2.4.2 +Order before final reordering +1GAT(0) 2GAT(1) 3GAT(2) 6GAT(3) 7GAT(4) +22GAT(10): 8 nodes 18 minterms +23GAT(9): 8 nodes 18 minterms +22GAT(10): 5 nodes 3 minterms +Testing iterator on ZDD paths: +-1-0- 1 +-10-- 1 +1-1-- 1 + +1-1-- 1 +-10-- 1 +-1-0- 1 +23GAT(9): 6 nodes 4 minterms +Testing iterator on ZDD paths: +---01 1 +--0-1 1 +-1-0- 1 +-10-- 1 + +-10-- 1 +-1-0- 1 +--0-1 1 +---01 1 +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000 +Maximum number of variable swaps per reordering: 2000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: no +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: yes +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 10 +Arc violation threshold: 10 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 4004 +**** CUDD non-modifiable parameters **** +Memory in use: 4737732 +Peak number of nodes: 1022 +Peak number of live nodes: 19 +Number of BDD variables: 5 +Number of ZDD variables: 10 +Number of cache entries: 32768 +Number of cache look-ups: 125 +Number of cache hits: 21 +Number of cache insertions: 117 +Number of cache collisions: 0 +Number of cache deletions: 35 +Cache used slots = 0.33% (expected 0.25%) +Soft limit for cache size: 16384 +Number of buckets in unique table: 4096 +Used buckets in unique table: 1.22% (expected 1.24%) +Number of BDD and ADD nodes: 24 +Number of ZDD nodes: 27 +Number of dead BDD and ADD nodes: 8 +Number of dead ZDD nodes: 17 +Total number of nodes allocated: 67 +Total number of nodes reclaimed: 8 +Garbage collections so far: 1 +Time for garbage collection: 0.00 sec +Reorderings so far: 0 +Time for reordering: 0.00 sec +Final size: 11 +total time = 0.00 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 0.0 seconds +System time 0.0 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131815K +Virtual data size = 297K + data size initialized = 25K + data size uninitialized = 137K + data size sbrk = 135K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 8 +Minor page faults = 1413 +Swaps = 0 +Input blocks = 0 +Output blocks = 0 +Context switch (voluntary) = 12 +Context switch (involuntary) = 0 diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/C880.blif b/resources/3rdparty/cudd-2.5.0/nanotrav/C880.blif new file mode 100644 index 000000000..38ee2c965 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/C880.blif @@ -0,0 +1,770 @@ +.model C880.iscas +.inputs 1GAT(0) 8GAT(1) 13GAT(2) 17GAT(3) 26GAT(4) 29GAT(5) 36GAT(6) 42GAT(7) 51GAT(8) 55GAT(9) 59GAT(10) 68GAT(11) 72GAT(12) 73GAT(13) 74GAT(14) 75GAT(15) 80GAT(16) 85GAT(17) 86GAT(18) 87GAT(19) 88GAT(20) 89GAT(21) 90GAT(22) 91GAT(23) 96GAT(24) 101GAT(25) 106GAT(26) 111GAT(27) 116GAT(28) 121GAT(29) 126GAT(30) 130GAT(31) 135GAT(32) 138GAT(33) 143GAT(34) 146GAT(35) 149GAT(36) 152GAT(37) 153GAT(38) 156GAT(39) 159GAT(40) 165GAT(41) 171GAT(42) 177GAT(43) 183GAT(44) 189GAT(45) 195GAT(46) 201GAT(47) 207GAT(48) 210GAT(49) 219GAT(50) 228GAT(51) 237GAT(52) 246GAT(53) 255GAT(54) 259GAT(55) 260GAT(56) 261GAT(57) 267GAT(58) 268GAT(59) +.outputs 388GAT(133) 389GAT(132) 390GAT(131) 391GAT(124) 418GAT(168) 419GAT(164) 420GAT(158) 421GAT(162) 422GAT(161) 423GAT(155) 446GAT(183) 447GAT(182) 448GAT(179) 449GAT(176) 450GAT(173) 767GAT(349) 768GAT(334) 850GAT(404) 863GAT(424) 864GAT(423) 865GAT(422) 866GAT(426) 874GAT(433) 878GAT(442) 879GAT(441) 880GAT(440) +.names 268GAT(59) 310GAT(60) +1 0 +.names 255GAT(54) 267GAT(58) 341GAT(61) +11 1 +.names 255GAT(54) 260GAT(56) 339GAT(62) +11 1 +.names 255GAT(54) 259GAT(55) 337GAT(63) +11 1 +.names 195GAT(46) 201GAT(47) 331GAT(64) +00 0 +.names 195GAT(46) 201GAT(47) 330GAT(65) +11 0 +.names 183GAT(44) 189GAT(45) 329GAT(66) +00 0 +.names 183GAT(44) 189GAT(45) 328GAT(67) +11 0 +.names 171GAT(42) 177GAT(43) 327GAT(68) +00 0 +.names 171GAT(42) 177GAT(43) 326GAT(69) +11 0 +.names 159GAT(40) 165GAT(41) 325GAT(70) +00 0 +.names 159GAT(40) 165GAT(41) 324GAT(71) +11 0 +.names 152GAT(37) 138GAT(33) 318GAT(72) +11 1 +.names 210GAT(49) 121GAT(29) 340GAT(73) +11 1 +.names 121GAT(29) 126GAT(30) 308GAT(74) +00 0 +.names 121GAT(29) 126GAT(30) 307GAT(75) +11 0 +.names 210GAT(49) 116GAT(28) 338GAT(76) +11 1 +.names 210GAT(49) 111GAT(27) 336GAT(77) +11 1 +.names 111GAT(27) 116GAT(28) 306GAT(78) +00 0 +.names 111GAT(27) 116GAT(28) 305GAT(79) +11 0 +.names 210GAT(49) 106GAT(26) 335GAT(80) +11 1 +.names 210GAT(49) 101GAT(25) 334GAT(81) +11 1 +.names 101GAT(25) 106GAT(26) 304GAT(82) +00 0 +.names 101GAT(25) 106GAT(26) 303GAT(83) +11 0 +.names 210GAT(49) 96GAT(24) 333GAT(84) +11 1 +.names 210GAT(49) 91GAT(23) 332GAT(85) +11 1 +.names 91GAT(23) 96GAT(24) 302GAT(86) +00 0 +.names 91GAT(23) 96GAT(24) 301GAT(87) +11 0 +.names 87GAT(19) 88GAT(20) 298GAT(88) +00 0 +.names 85GAT(17) 86GAT(18) 297GAT(89) +11 1 +.names 59GAT(10) 156GAT(39) 319GAT(90) +11 0 +.names 59GAT(10) 75GAT(15) 80GAT(16) 293GAT(91) +111 1 +.names 59GAT(10) 68GAT(11) 74GAT(14) 286GAT(92) +111 0 +.names 51GAT(8) 138GAT(33) 316GAT(93) +11 1 +.names 59GAT(10) 75GAT(15) 42GAT(7) 294GAT(94) +111 1 +.names 59GAT(10) 42GAT(7) 68GAT(11) 72GAT(12) 284GAT(95) +1111 0 +.names 59GAT(10) 36GAT(6) 42GAT(7) 296GAT(96) +111 1 +.names 59GAT(10) 36GAT(6) 80GAT(16) 295GAT(97) +111 1 +.names 29GAT(5) 36GAT(6) 42GAT(7) 292GAT(98) +111 1 +.names 29GAT(5) 36GAT(6) 80GAT(16) 291GAT(99) +111 1 +.names 29GAT(5) 75GAT(15) 42GAT(7) 290GAT(100) +111 1 +.names 29GAT(5) 75GAT(15) 80GAT(16) 287GAT(101) +111 1 +.names 29GAT(5) 68GAT(11) 285GAT(102) +11 0 +.names 29GAT(5) 36GAT(6) 42GAT(7) 273GAT(103) +111 1 +.names 17GAT(3) 42GAT(7) 323GAT(104) +11 1 +.names 17GAT(3) 42GAT(7) 322GAT(105) +00 1 +.names 17GAT(3) 138GAT(33) 317GAT(106) +11 1 +.names 8GAT(1) 138GAT(33) 309GAT(107) +11 1 +.names 1GAT(0) 8GAT(1) 13GAT(2) 55GAT(9) 280GAT(108) +1111 0 +.names 1GAT(0) 8GAT(1) 51GAT(8) 17GAT(3) 279GAT(109) +1111 0 +.names 1GAT(0) 26GAT(4) 51GAT(8) 276GAT(110) +111 1 +.names 1GAT(0) 26GAT(4) 13GAT(2) 17GAT(3) 270GAT(111) +1111 0 +.names 1GAT(0) 8GAT(1) 13GAT(2) 17GAT(3) 269GAT(112) +1111 0 +.names 310GAT(60) 369GAT(113) +1 0 +.names 330GAT(65) 331GAT(64) 385GAT(114) +11 0 +.names 328GAT(67) 329GAT(66) 382GAT(115) +11 0 +.names 326GAT(69) 327GAT(68) 379GAT(116) +11 0 +.names 324GAT(71) 325GAT(70) 376GAT(117) +11 0 +.names 307GAT(75) 308GAT(74) 366GAT(118) +11 0 +.names 305GAT(79) 306GAT(78) 363GAT(119) +11 0 +.names 303GAT(83) 304GAT(82) 360GAT(120) +11 0 +.names 301GAT(87) 302GAT(86) 357GAT(121) +11 0 +.names 90GAT(22) 298GAT(88) 356GAT(122) +11 1 +.names 89GAT(21) 298GAT(88) 355GAT(123) +11 0 +.names 297GAT(89) 391GAT(124) +1 1 +.names 293GAT(91) 351GAT(125) +1 0 +.names 280GAT(108) 286GAT(92) 350GAT(126) +00 0 +.names 294GAT(94) 352GAT(127) +1 0 +.names 280GAT(108) 284GAT(95) 348GAT(128) +00 1 +.names 296GAT(96) 354GAT(129) +1 0 +.names 295GAT(97) 353GAT(130) +1 0 +.names 292GAT(98) 390GAT(131) +1 1 +.names 291GAT(99) 389GAT(132) +1 1 +.names 290GAT(100) 388GAT(133) +1 1 +.names 280GAT(108) 285GAT(102) 349GAT(134) +00 0 +.names 273GAT(103) 343GAT(135) +1 0 +.names 270GAT(111) 273GAT(103) 344GAT(136) +00 0 +.names 322GAT(105) 323GAT(104) 375GAT(137) +00 1 +.names 279GAT(109) 347GAT(138) +1 0 +.names 276GAT(110) 345GAT(139) +1 0 +.names 276GAT(110) 346GAT(140) +1 0 +.names 269GAT(112) 342GAT(141) +1 0 +.names 210GAT(49) 369GAT(113) 417GAT(142) +11 1 +.names 385GAT(114) 415GAT(143) +1 0 +.names 382GAT(115) 385GAT(114) 416GAT(144) +11 1 +.names 382GAT(115) 414GAT(145) +1 0 +.names 379GAT(116) 412GAT(146) +1 0 +.names 376GAT(117) 379GAT(116) 413GAT(147) +11 1 +.names 376GAT(117) 411GAT(148) +1 0 +.names 366GAT(118) 408GAT(149) +1 0 +.names 363GAT(119) 366GAT(118) 409GAT(150) +11 1 +.names 363GAT(119) 407GAT(151) +1 0 +.names 360GAT(120) 405GAT(152) +1 0 +.names 357GAT(121) 360GAT(120) 406GAT(153) +11 1 +.names 357GAT(121) 404GAT(154) +1 0 +.names 356GAT(122) 423GAT(155) +1 1 +.names 355GAT(123) 403GAT(156) +1 0 +.names 348GAT(128) 73GAT(13) 400GAT(157) +11 1 +.names 351GAT(125) 420GAT(158) +1 1 +.names 350GAT(126) 402GAT(159) +1 0 +.names 347GAT(138) 352GAT(127) 410GAT(160) +11 0 +.names 354GAT(129) 422GAT(161) +1 1 +.names 353GAT(130) 421GAT(162) +1 1 +.names 349GAT(134) 401GAT(163) +1 0 +.names 344GAT(136) 419GAT(164) +1 1 +.names 345GAT(139) 393GAT(165) +1 0 +.names 346GAT(140) 399GAT(166) +1 0 +.names 270GAT(111) 343GAT(135) 392GAT(167) +00 0 +.names 342GAT(141) 418GAT(168) +1 1 +.names 414GAT(145) 415GAT(143) 445GAT(169) +11 1 +.names 411GAT(148) 412GAT(146) 444GAT(170) +11 1 +.names 407GAT(151) 408GAT(149) 426GAT(171) +11 1 +.names 404GAT(154) 405GAT(152) 425GAT(172) +11 1 +.names 403GAT(156) 450GAT(173) +1 1 +.names 400GAT(157) 424GAT(174) +1 0 +.names 375GAT(137) 59GAT(10) 156GAT(39) 393GAT(165) 442GAT(175) +1111 0 +.names 402GAT(159) 449GAT(176) +1 1 +.names 393GAT(165) 287GAT(101) 55GAT(9) 437GAT(177) +111 0 +.names 319GAT(90) 393GAT(165) 55GAT(9) 427GAT(178) +111 1 +.names 401GAT(163) 448GAT(179) +1 1 +.names 393GAT(165) 319GAT(90) 17GAT(3) 443GAT(180) +111 0 +.names 393GAT(165) 17GAT(3) 287GAT(101) 432GAT(181) +111 1 +.names 399GAT(166) 447GAT(182) +1 1 +.names 392GAT(167) 446GAT(183) +1 1 +.names 369GAT(113) 437GAT(177) 488GAT(184) +00 0 +.names 369GAT(113) 437GAT(177) 489GAT(185) +00 0 +.names 369GAT(113) 437GAT(177) 490GAT(186) +00 0 +.names 369GAT(113) 437GAT(177) 491GAT(187) +00 0 +.names 310GAT(60) 432GAT(181) 476GAT(188) +11 1 +.names 310GAT(60) 432GAT(181) 478GAT(189) +11 1 +.names 310GAT(60) 432GAT(181) 480GAT(190) +11 1 +.names 310GAT(60) 432GAT(181) 482GAT(191) +11 1 +.names 416GAT(144) 445GAT(169) 495GAT(192) +00 1 +.names 413GAT(147) 444GAT(170) 492GAT(193) +00 1 +.names 153GAT(38) 427GAT(178) 481GAT(194) +11 1 +.names 149GAT(36) 427GAT(178) 479GAT(195) +11 1 +.names 146GAT(35) 427GAT(178) 477GAT(196) +11 1 +.names 143GAT(34) 427GAT(178) 475GAT(197) +11 1 +.names 409GAT(150) 426GAT(171) 463GAT(198) +00 1 +.names 406GAT(153) 425GAT(172) 460GAT(199) +00 1 +.names 424GAT(174) 451GAT(200) +1 0 +.names 442GAT(175) 410GAT(160) 466GAT(201) +11 0 +.names 443GAT(180) 1GAT(0) 483GAT(202) +11 0 +.names 475GAT(197) 476GAT(188) 503GAT(203) +00 1 +.names 477GAT(196) 478GAT(189) 505GAT(204) +00 1 +.names 479GAT(195) 480GAT(190) 507GAT(205) +00 1 +.names 481GAT(194) 482GAT(191) 509GAT(206) +00 1 +.names 495GAT(192) 207GAT(48) 521GAT(207) +00 0 +.names 495GAT(192) 207GAT(48) 520GAT(208) +11 0 +.names 451GAT(200) 201GAT(47) 529GAT(209) +11 0 +.names 451GAT(200) 195GAT(46) 528GAT(210) +11 0 +.names 451GAT(200) 189GAT(45) 527GAT(211) +11 0 +.names 451GAT(200) 183GAT(44) 526GAT(212) +11 1 +.names 451GAT(200) 177GAT(43) 525GAT(213) +11 1 +.names 451GAT(200) 171GAT(42) 524GAT(214) +11 1 +.names 451GAT(200) 165GAT(41) 523GAT(215) +11 1 +.names 451GAT(200) 159GAT(40) 522GAT(216) +11 1 +.names 153GAT(38) 483GAT(202) 516GAT(217) +11 1 +.names 149GAT(36) 483GAT(202) 514GAT(218) +11 1 +.names 146GAT(35) 483GAT(202) 512GAT(219) +11 1 +.names 143GAT(34) 483GAT(202) 510GAT(220) +11 1 +.names 463GAT(198) 135GAT(32) 501GAT(221) +00 0 +.names 463GAT(198) 135GAT(32) 500GAT(222) +11 0 +.names 130GAT(31) 492GAT(193) 519GAT(223) +00 0 +.names 130GAT(31) 492GAT(193) 518GAT(224) +11 0 +.names 130GAT(31) 460GAT(199) 499GAT(225) +00 0 +.names 130GAT(31) 460GAT(199) 498GAT(226) +11 0 +.names 126GAT(30) 466GAT(201) 517GAT(227) +11 1 +.names 121GAT(29) 466GAT(201) 515GAT(228) +11 1 +.names 116GAT(28) 466GAT(201) 513GAT(229) +11 1 +.names 111GAT(27) 466GAT(201) 511GAT(230) +11 1 +.names 106GAT(26) 466GAT(201) 508GAT(231) +11 1 +.names 101GAT(25) 466GAT(201) 506GAT(232) +11 1 +.names 96GAT(24) 466GAT(201) 504GAT(233) +11 1 +.names 91GAT(23) 466GAT(201) 502GAT(234) +11 1 +.names 520GAT(208) 521GAT(207) 547GAT(235) +11 0 +.names 516GAT(217) 517GAT(227) 543GAT(236) +00 1 +.names 514GAT(218) 515GAT(228) 542GAT(237) +00 1 +.names 512GAT(219) 513GAT(229) 541GAT(238) +00 1 +.names 510GAT(220) 511GAT(230) 540GAT(239) +00 1 +.names 318GAT(72) 508GAT(231) 539GAT(240) +00 1 +.names 500GAT(222) 501GAT(221) 533GAT(241) +11 0 +.names 518GAT(224) 519GAT(223) 544GAT(242) +11 0 +.names 498GAT(226) 499GAT(225) 530GAT(243) +11 0 +.names 316GAT(93) 504GAT(233) 537GAT(244) +00 1 +.names 317GAT(106) 506GAT(232) 538GAT(245) +00 1 +.names 309GAT(107) 502GAT(234) 536GAT(246) +00 1 +.names 488GAT(184) 540GAT(239) 569GAT(247) +11 0 +.names 489GAT(185) 541GAT(238) 573GAT(248) +11 0 +.names 490GAT(186) 542GAT(237) 577GAT(249) +11 0 +.names 491GAT(187) 543GAT(236) 581GAT(250) +11 0 +.names 536GAT(246) 503GAT(203) 553GAT(251) +11 0 +.names 537GAT(244) 505GAT(204) 557GAT(252) +11 0 +.names 538GAT(245) 507GAT(205) 561GAT(253) +11 0 +.names 539GAT(240) 509GAT(206) 565GAT(254) +11 0 +.names 547GAT(235) 586GAT(255) +1 0 +.names 544GAT(242) 547GAT(235) 587GAT(256) +11 1 +.names 533GAT(241) 551GAT(257) +1 0 +.names 530GAT(243) 533GAT(241) 552GAT(258) +11 1 +.names 544GAT(242) 585GAT(259) +1 0 +.names 530GAT(243) 550GAT(260) +1 0 +.names 246GAT(53) 581GAT(250) 659GAT(261) +11 1 +.names 246GAT(53) 577GAT(249) 650GAT(262) +11 1 +.names 246GAT(53) 573GAT(248) 640GAT(263) +11 1 +.names 246GAT(53) 569GAT(247) 631GAT(264) +11 1 +.names 246GAT(53) 565GAT(254) 624GAT(265) +11 1 +.names 246GAT(53) 561GAT(253) 615GAT(266) +11 1 +.names 246GAT(53) 557GAT(252) 605GAT(267) +11 1 +.names 246GAT(53) 553GAT(251) 596GAT(268) +11 1 +.names 585GAT(259) 586GAT(255) 589GAT(269) +11 1 +.names 581GAT(250) 201GAT(47) 654GAT(270) +00 0 +.names 581GAT(250) 201GAT(47) 651GAT(271) +11 0 +.names 577GAT(249) 195GAT(46) 644GAT(272) +00 0 +.names 577GAT(249) 195GAT(46) 641GAT(273) +11 0 +.names 573GAT(248) 189GAT(45) 635GAT(274) +00 0 +.names 573GAT(248) 189GAT(45) 632GAT(275) +11 0 +.names 569GAT(247) 183GAT(44) 628GAT(276) +00 0 +.names 569GAT(247) 183GAT(44) 625GAT(277) +11 0 +.names 565GAT(254) 177GAT(43) 619GAT(278) +00 0 +.names 565GAT(254) 177GAT(43) 616GAT(279) +11 0 +.names 561GAT(253) 171GAT(42) 609GAT(280) +00 0 +.names 561GAT(253) 171GAT(42) 606GAT(281) +11 0 +.names 557GAT(252) 165GAT(41) 600GAT(282) +00 0 +.names 557GAT(252) 165GAT(41) 597GAT(283) +11 0 +.names 553GAT(251) 159GAT(40) 593GAT(284) +00 0 +.names 553GAT(251) 159GAT(40) 590GAT(285) +11 0 +.names 550GAT(260) 551GAT(257) 588GAT(286) +11 1 +.names 635GAT(274) 644GAT(272) 654GAT(270) 261GAT(57) 734GAT(287) +1111 0 +.names 644GAT(272) 654GAT(270) 261GAT(57) 733GAT(288) +111 0 +.names 654GAT(270) 261GAT(57) 732GAT(289) +11 0 +.names 341GAT(61) 659GAT(261) 731GAT(290) +00 1 +.names 339GAT(62) 650GAT(262) 721GAT(291) +00 1 +.names 337GAT(63) 640GAT(263) 712GAT(292) +00 1 +.names 587GAT(256) 589GAT(269) 661GAT(293) +00 1 +.names 654GAT(270) 651GAT(271) 727GAT(294) +11 1 +.names 651GAT(271) 722GAT(295) +1 0 +.names 644GAT(272) 641GAT(273) 717GAT(296) +11 1 +.names 641GAT(273) 713GAT(297) +1 0 +.names 635GAT(274) 632GAT(275) 708GAT(298) +11 1 +.names 632GAT(275) 705GAT(299) +1 0 +.names 628GAT(276) 625GAT(277) 700GAT(300) +11 1 +.names 625GAT(277) 697GAT(301) +1 0 +.names 631GAT(264) 526GAT(212) 704GAT(302) +00 1 +.names 619GAT(278) 616GAT(279) 692GAT(303) +11 1 +.names 616GAT(279) 687GAT(304) +1 0 +.names 624GAT(265) 525GAT(213) 696GAT(305) +00 1 +.names 609GAT(280) 606GAT(281) 682GAT(306) +11 1 +.names 606GAT(281) 678GAT(307) +1 0 +.names 615GAT(266) 524GAT(214) 686GAT(308) +00 1 +.names 600GAT(282) 597GAT(283) 673GAT(309) +11 1 +.names 597GAT(283) 670GAT(310) +1 0 +.names 605GAT(267) 523GAT(215) 677GAT(311) +00 1 +.names 593GAT(284) 590GAT(285) 665GAT(312) +11 1 +.names 590GAT(285) 662GAT(313) +1 0 +.names 596GAT(268) 522GAT(216) 669GAT(314) +00 1 +.names 552GAT(258) 588GAT(286) 660GAT(315) +00 1 +.names 727GAT(294) 261GAT(57) 758GAT(316) +11 1 +.names 727GAT(294) 261GAT(57) 757GAT(317) +00 1 +.names 237GAT(52) 722GAT(295) 760GAT(318) +11 1 +.names 237GAT(52) 713GAT(297) 755GAT(319) +11 1 +.names 237GAT(52) 705GAT(299) 752GAT(320) +11 1 +.names 237GAT(52) 697GAT(301) 749GAT(321) +11 1 +.names 237GAT(52) 687GAT(304) 746GAT(322) +11 1 +.names 237GAT(52) 678GAT(307) 743GAT(323) +11 1 +.names 237GAT(52) 670GAT(310) 740GAT(324) +11 1 +.names 237GAT(52) 662GAT(313) 737GAT(325) +11 1 +.names 228GAT(51) 727GAT(294) 759GAT(326) +11 1 +.names 228GAT(51) 717GAT(296) 754GAT(327) +11 1 +.names 228GAT(51) 708GAT(298) 751GAT(328) +11 1 +.names 228GAT(51) 700GAT(300) 748GAT(329) +11 1 +.names 228GAT(51) 692GAT(303) 745GAT(330) +11 1 +.names 228GAT(51) 682GAT(306) 742GAT(331) +11 1 +.names 228GAT(51) 673GAT(309) 739GAT(332) +11 1 +.names 228GAT(51) 665GAT(312) 736GAT(333) +11 1 +.names 661GAT(293) 768GAT(334) +1 1 +.names 722GAT(295) 756GAT(335) +1 0 +.names 644GAT(272) 722GAT(295) 761GAT(336) +11 0 +.names 635GAT(274) 644GAT(272) 722GAT(295) 763GAT(337) +111 0 +.names 713GAT(297) 753GAT(338) +1 0 +.names 635GAT(274) 713GAT(297) 762GAT(339) +11 0 +.names 705GAT(299) 750GAT(340) +1 0 +.names 697GAT(301) 747GAT(341) +1 0 +.names 687GAT(304) 744GAT(342) +1 0 +.names 609GAT(280) 687GAT(304) 764GAT(343) +11 0 +.names 600GAT(282) 609GAT(280) 687GAT(304) 766GAT(344) +111 0 +.names 678GAT(307) 741GAT(345) +1 0 +.names 600GAT(282) 678GAT(307) 765GAT(346) +11 0 +.names 670GAT(310) 738GAT(347) +1 0 +.names 662GAT(313) 735GAT(348) +1 0 +.names 660GAT(315) 767GAT(349) +1 1 +.names 757GAT(317) 758GAT(316) 786GAT(350) +00 1 +.names 750GAT(340) 762GAT(339) 763GAT(337) 734GAT(287) 773GAT(351) +1111 0 +.names 753GAT(338) 761GAT(336) 733GAT(288) 778GAT(352) +111 0 +.names 756GAT(335) 732GAT(289) 782GAT(353) +11 0 +.names 759GAT(326) 760GAT(318) 787GAT(354) +00 1 +.names 754GAT(327) 755GAT(319) 785GAT(355) +00 1 +.names 751GAT(328) 752GAT(320) 781GAT(356) +00 1 +.names 748GAT(329) 749GAT(321) 777GAT(357) +00 1 +.names 745GAT(330) 746GAT(322) 772GAT(358) +00 1 +.names 742GAT(331) 743GAT(323) 771GAT(359) +00 1 +.names 739GAT(332) 740GAT(324) 770GAT(360) +00 1 +.names 736GAT(333) 737GAT(325) 769GAT(361) +00 1 +.names 219GAT(50) 786GAT(350) 794GAT(362) +11 1 +.names 717GAT(296) 782GAT(353) 792GAT(363) +00 1 +.names 717GAT(296) 782GAT(353) 793GAT(364) +11 1 +.names 708GAT(298) 778GAT(352) 790GAT(365) +00 1 +.names 708GAT(298) 778GAT(352) 791GAT(366) +11 1 +.names 700GAT(300) 773GAT(351) 788GAT(367) +00 1 +.names 700GAT(300) 773GAT(351) 789GAT(368) +11 1 +.names 628GAT(276) 773GAT(351) 795GAT(369) +11 0 +.names 792GAT(363) 793GAT(364) 804GAT(370) +00 1 +.names 790GAT(365) 791GAT(366) 803GAT(371) +00 1 +.names 788GAT(367) 789GAT(368) 802GAT(372) +00 1 +.names 795GAT(369) 747GAT(341) 796GAT(373) +11 0 +.names 340GAT(73) 794GAT(362) 805GAT(374) +00 1 +.names 219GAT(50) 804GAT(370) 810GAT(375) +11 1 +.names 219GAT(50) 803GAT(371) 809GAT(376) +11 1 +.names 219GAT(50) 802GAT(372) 808GAT(377) +11 1 +.names 805GAT(374) 787GAT(354) 731GAT(290) 529GAT(209) 811GAT(378) +1111 0 +.names 692GAT(303) 796GAT(373) 806GAT(379) +00 1 +.names 692GAT(303) 796GAT(373) 807GAT(380) +11 1 +.names 619GAT(278) 796GAT(373) 812GAT(381) +11 0 +.names 609GAT(280) 619GAT(278) 796GAT(373) 813GAT(382) +111 0 +.names 600GAT(282) 609GAT(280) 619GAT(278) 796GAT(373) 814GAT(383) +1111 0 +.names 811GAT(378) 829GAT(384) +1 0 +.names 806GAT(379) 807GAT(380) 825GAT(385) +00 1 +.names 744GAT(342) 812GAT(381) 822GAT(386) +11 0 +.names 741GAT(345) 764GAT(343) 813GAT(382) 819GAT(387) +111 0 +.names 738GAT(347) 765GAT(346) 766GAT(344) 814GAT(383) 815GAT(388) +1111 0 +.names 338GAT(76) 810GAT(375) 828GAT(389) +00 1 +.names 336GAT(77) 809GAT(376) 827GAT(390) +00 1 +.names 335GAT(80) 808GAT(377) 826GAT(391) +00 1 +.names 219GAT(50) 825GAT(385) 836GAT(392) +11 1 +.names 829GAT(384) 840GAT(393) +1 0 +.names 828GAT(389) 785GAT(355) 721GAT(291) 528GAT(210) 839GAT(394) +1111 0 +.names 827GAT(390) 781GAT(356) 712GAT(292) 527GAT(211) 838GAT(395) +1111 0 +.names 826GAT(391) 777GAT(357) 704GAT(302) 837GAT(396) +111 0 +.names 682GAT(306) 822GAT(386) 834GAT(397) +00 1 +.names 682GAT(306) 822GAT(386) 835GAT(398) +11 1 +.names 673GAT(309) 819GAT(387) 832GAT(399) +00 1 +.names 673GAT(309) 819GAT(387) 833GAT(400) +11 1 +.names 665GAT(312) 815GAT(388) 830GAT(401) +00 1 +.names 665GAT(312) 815GAT(388) 831GAT(402) +11 1 +.names 815GAT(388) 593GAT(284) 841GAT(403) +11 0 +.names 840GAT(393) 850GAT(404) +1 1 +.names 839GAT(394) 848GAT(405) +1 0 +.names 838GAT(395) 847GAT(406) +1 0 +.names 837GAT(396) 846GAT(407) +1 0 +.names 834GAT(397) 835GAT(398) 844GAT(408) +00 1 +.names 832GAT(399) 833GAT(400) 843GAT(409) +00 1 +.names 830GAT(401) 831GAT(402) 842GAT(410) +00 1 +.names 735GAT(348) 841GAT(403) 849GAT(411) +11 1 +.names 334GAT(81) 836GAT(392) 845GAT(412) +00 1 +.names 219GAT(50) 844GAT(408) 853GAT(413) +11 1 +.names 219GAT(50) 843GAT(409) 852GAT(414) +11 1 +.names 219GAT(50) 842GAT(410) 851GAT(415) +11 1 +.names 848GAT(405) 857GAT(416) +1 0 +.names 847GAT(406) 856GAT(417) +1 0 +.names 846GAT(407) 855GAT(418) +1 0 +.names 845GAT(412) 772GAT(358) 696GAT(305) 854GAT(419) +111 0 +.names 849GAT(411) 858GAT(420) +1 0 +.names 417GAT(142) 851GAT(415) 859GAT(421) +00 1 +.names 857GAT(416) 865GAT(422) +1 1 +.names 856GAT(417) 864GAT(423) +1 1 +.names 855GAT(418) 863GAT(424) +1 1 +.names 854GAT(419) 862GAT(425) +1 0 +.names 858GAT(420) 866GAT(426) +1 1 +.names 333GAT(84) 853GAT(413) 861GAT(427) +00 1 +.names 332GAT(85) 852GAT(414) 860GAT(428) +00 1 +.names 862GAT(425) 870GAT(429) +1 0 +.names 861GAT(427) 771GAT(359) 686GAT(308) 869GAT(430) +111 0 +.names 860GAT(428) 770GAT(360) 677GAT(311) 868GAT(431) +111 0 +.names 859GAT(421) 769GAT(361) 669GAT(314) 867GAT(432) +111 0 +.names 870GAT(429) 874GAT(433) +1 1 +.names 869GAT(430) 873GAT(434) +1 0 +.names 868GAT(431) 872GAT(435) +1 0 +.names 867GAT(432) 871GAT(436) +1 0 +.names 873GAT(434) 877GAT(437) +1 0 +.names 872GAT(435) 876GAT(438) +1 0 +.names 871GAT(436) 875GAT(439) +1 0 +.names 877GAT(437) 880GAT(440) +1 1 +.names 876GAT(438) 879GAT(441) +1 1 +.names 875GAT(439) 878GAT(442) +1 1 +.end diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/C880.out b/resources/3rdparty/cudd-2.5.0/nanotrav/C880.out new file mode 100644 index 000000000..71dcb6295 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/C880.out @@ -0,0 +1,101 @@ +# Nanotrav Version #0.12, Release date 2003/12/31 +# ./nanotrav -p 1 -ordering dfs -autodyn -automethod sifting -reordering sifting -drop C880.blif +# CUDD Version 2.4.2 +BDD reordering with sifting: from 3974 to ... 2432 nodes in 0.039 sec +BDD reordering with sifting: from 4893 to ... 3549 nodes in 0.044 sec +BDD reordering with sifting: from 7133 to ... 6246 nodes in 0.072 sec +BDD reordering with sifting: from 12522 to ... 6465 nodes in 0.113 sec +Order before final reordering +86GAT(18) 85GAT(17) 90GAT(22) 89GAT(21) 88GAT(20) 87GAT(19) 1GAT(0) 51GAT(8) +75GAT(15) 26GAT(4) 268GAT(59) 36GAT(6) 29GAT(5) 80GAT(16) 59GAT(10) 42GAT(7) +156GAT(39) 17GAT(3) 74GAT(14) 55GAT(9) 8GAT(1) 219GAT(50) 210GAT(49) 91GAT(23) +101GAT(25) 138GAT(33) 96GAT(24) 171GAT(42) 152GAT(37) 146GAT(35) 116GAT(28) 189GAT(45) +149GAT(36) 121GAT(29) 195GAT(46) 153GAT(38) 126GAT(30) 261GAT(57) 201GAT(47) 143GAT(34) +111GAT(27) 183GAT(44) 130GAT(31) 135GAT(32) 106GAT(26) 177GAT(43) 165GAT(41) 207GAT(48) +159GAT(40) 228GAT(51) 237GAT(52) 246GAT(53) 73GAT(13) 72GAT(12) 68GAT(11) 13GAT(2) +260GAT(56) 267GAT(58) 259GAT(55) 255GAT(54) +Number of inputs = 60 +BDD reordering with sifting: from 6204 to ... 4623 nodes in 0.07 sec +New order +135GAT(32) 207GAT(48) 130GAT(31) 86GAT(18) 85GAT(17) 89GAT(21) 90GAT(22) 88GAT(20) +87GAT(19) 1GAT(0) 51GAT(8) 26GAT(4) 268GAT(59) 29GAT(5) 80GAT(16) 59GAT(10) +42GAT(7) 75GAT(15) 156GAT(39) 36GAT(6) 17GAT(3) 74GAT(14) 55GAT(9) 8GAT(1) +210GAT(49) 91GAT(23) 138GAT(33) 165GAT(41) 96GAT(24) 159GAT(40) 101GAT(25) 171GAT(42) +152GAT(37) 149GAT(36) 146GAT(35) 116GAT(28) 189GAT(45) 121GAT(29) 195GAT(46) 153GAT(38) +143GAT(34) 126GAT(30) 201GAT(47) 261GAT(57) 111GAT(27) 106GAT(26) 183GAT(44) 177GAT(43) +219GAT(50) 246GAT(53) 237GAT(52) 228GAT(51) 73GAT(13) 72GAT(12) 68GAT(11) 13GAT(2) +260GAT(56) 267GAT(58) 259GAT(55) 255GAT(54) +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000000 +Maximum number of variable swaps per reordering: 1000000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: yes +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: no +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 10 +Arc violation threshold: 10 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 9340 +**** CUDD non-modifiable parameters **** +Memory in use: 5611044 +Peak number of nodes: 19418 +Peak number of live nodes: 12568 +Number of BDD variables: 60 +Number of ZDD variables: 0 +Number of cache entries: 65536 +Number of cache look-ups: 59167 +Number of cache hits: 28642 +Number of cache insertions: 30604 +Number of cache collisions: 2547 +Number of cache deletions: 28057 +Cache used slots = 18.04% (expected 0.00%) +Soft limit for cache size: 62464 +Number of buckets in unique table: 15616 +Used buckets in unique table: 20.84% (expected 20.96%) +Number of BDD and ADD nodes: 4671 +Number of ZDD nodes: 0 +Number of dead BDD and ADD nodes: 0 +Number of dead ZDD nodes: 0 +Total number of nodes allocated: 32671 +Total number of nodes reclaimed: 1974 +Garbage collections so far: 5 +Time for garbage collection: 0.00 sec +Reorderings so far: 5 +Time for reordering: 0.34 sec +Final size: 4623 +total time = 0.36 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 0.4 seconds +System time 0.0 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131815K +Virtual data size = 297K + data size initialized = 25K + data size uninitialized = 137K + data size sbrk = 135K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 0 +Minor page faults = 1778 +Swaps = 0 +Input blocks = 0 +Output blocks = 0 +Context switch (voluntary) = 1 +Context switch (involuntary) = 6 diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/Makefile b/resources/3rdparty/cudd-2.5.0/nanotrav/Makefile new file mode 100644 index 000000000..b40b547bd --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/Makefile @@ -0,0 +1,98 @@ +# $Id: Makefile,v 1.12 1999/08/31 19:10:05 fabio Exp fabio $ +# +# nanotrav: simple FSM traversal program +#--------------------------------------------------------------------------- +.SUFFIXES: .o .c .u + +CC = gcc +#CC = cc +RANLIB = ranlib +#RANLIB = : +PURE = + +EXE = +#EXE = .exe +TARGET = nanotrav$(EXE) +TARGETu = nanotrav-u + +WHERE = .. + +INCLUDE = $(WHERE)/include + +LIBS = $(WHERE)/dddmp/libdddmp.a $(WHERE)/cudd/libcudd.a \ + $(WHERE)/mtr/libmtr.a $(WHERE)/st/libst.a $(WHERE)/util/libutil.a \ + $(WHERE)/epd/libepd.a + +MNEMLIB = +#MNEMLIB = $(WHERE)/mnemosyne/libmnem.a + +BLIBS = -kL$(WHERE)/dddmp -kldddmp -kL$(WHERE)/cudd -klcudd -kL$(WHERE)/mtr \ + -klmtr -kL$(WHERE)/st -klst -kL$(WHERE)/util -klutil \ + -kL$(WHERE)/epd -klepd + +LINTLIBS = $(WHERE)/llib-ldddmp.a $(WHERE)/cudd/llib-lcudd.ln \ + $(WHERE)/mtr/llib-lmtr.ln $(WHERE)/st/llib-lst.ln \ + $(WHERE)/util/llib-lutil.ln $(WHERE)/epd/llib-lepd.ln + +SRC = main.c bnet.c ntr.c ntrHeap.c ntrBddTest.c ntrMflow.c ntrZddTest.c \ + ntrShort.c chkMterm.c ucbqsort.c +HDR = bnet.h ntr.h $(WHERE)/include/dddmp.h $(WHERE)/include/cudd.h \ + $(WHERE)/include/cuddInt.h + +OBJ = $(SRC:.c=.o) +UBJ = $(SRC:.c=.u) + +MFLAG = +#MFLAG = -DMNEMOSYNE +ICFLAGS = -g -O6 -Wall +#ICFLAGS = -g -Wall +XCFLAGS = -DHAVE_IEEE_754 -DBSD +#XCFLAGS = -xtaso -ieee_with_no_inexact -tune host +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) +DDDEBUG = +#DDDEBUG = -DDD_STATS -DDD_VERBOSE -DDD_CACHE_PROFILE -DDD_UNIQUE_PROFILE -DDD_DEBUG + +LDFLAGS = +#LDFLAGS = -jmpopt +#LDFLAGS = -non_shared -om -taso + +LINTFLAGS = -u -n -DDD_STATS -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_DEBUG -DDD_UNIQUE_PROFILE + +#------------------------------------------------------ + +$(TARGET): $(SRC) $(OBJ) $(HDR) $(LIBS) $(MNEMLIB) + $(PURE) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +.c.o: $(HDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) $(DDDEBUG) + +# if the header files change, recompile +$(OBJ): $(HDR) +$(UBJ): $(HDR) + +optimize_dec: $(TARGETu) + +# optimize (DECstations only: uses u-code) +$(TARGETu): $(SRC) $(UBJ) $(HDR) $(LIBS:.a=.b) + cc -O3 $(XCFLAGS) $(LDFLAGS) $(UBJ) -o $@ $(BLIBS) -lm + +.c.u: $(SRC) $(HDR) + cc -j -I$(INCLUDE) $(XCFLAGS) $< + +lint: $(SRC) $(HDR) $(LINTLIBS) + lint $(LINTFLAGS) -I$(INCLUDE) $(SRC) $(LINTLIBS) + +tags: $(SRC) $(HDR) + ctags $(SRC) $(HDR) + +all: $(TARGET) $(TARGETu) lint tags + +pixie: $(TARGETu) + pixie $(TARGETu) + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) *.bak *~ .gdb_history *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/README b/resources/3rdparty/cudd-2.5.0/nanotrav/README new file mode 100644 index 000000000..cf09d9c12 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/README @@ -0,0 +1,47 @@ +$Id: README,v 1.8 1997/01/23 07:33:22 fabio Exp fabio $ + +WHAT IS NANOTRAV +================ + +This directory contains nanotrav, a simple reachability analysis program +based on the CUDD package. Nanotrav uses a very naive approach and is +only included to provide a sanity check for the installation of the +CUDD package. + +Nanotrav reads a circuit written in a small subset of blif. This +format is described in the comments in bnet.c. Nanotrav then creates +BDDs for the primary outputs and the next state functions (if any) of +the circuit. + +If, passed the -trav option, nanotrav builds a BDD for the +characteristic function of the transition relation of the graph. It then +builds a BDD for the initial state(s), and performs reachability +analysis. Reachability analysys is performed with either the method +known as "monolithic transition relation method," whose main virtue is +simplicity, or with a unsophisticated partitioned transition relation +method. + +Once it has completed reachability analysis, nanotrav prints results and +exits. The amount of information printed, as well as several other +features are controlled by the options. For a complete list of the +options, consult the man page. Here, we only mention that the options allow +the user of nanotrav to select among different reordering options. + +TEST CIRCUITS +============= + +Five test circuits are contained in this directory: C17.blif, +C880.blif, s27.blif, mult32a.blif, and rcn25.blif. The first two are +combinational, while the last three are sequential. The results or +running + + nanotrav -p 1 -cover C17.blif > C17.out + nanotrav -p 1 -ordering dfs -autodyn -automethod sifting -reordering sifting -drop C880.blif > C880.out + nanotrav -p 1 -trav s27.blif > s27.out + nanotrav -p 1 -autodyn -reordering sifting -trav mult32a.blif > mult32a.out + nanotrav -p 1 -envelope rcn25.blif > rcn25.out + +are also included. They have been obtained on a 200 MHz P6-based +machine with 128MB of memory. These tests can be run with the shell +script tst.sh. Notice that rcn25 requires approximately 500 sec. All +other tests run in a few seconds. diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/bnet.c b/resources/3rdparty/cudd-2.5.0/nanotrav/bnet.c new file mode 100644 index 000000000..d1b3f0987 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/bnet.c @@ -0,0 +1,2252 @@ +/**CFile*********************************************************************** + + FileName [bnet.c] + + PackageName [bnet] + + Synopsis [Functions to read in a boolean network.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "bnet.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define MAXLENGTH 131072 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: bnet.c,v 1.26 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +static char BuffLine[MAXLENGTH]; +static char *CurPos; +static int newNameNumber = 0; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static char * readString (FILE *fp); +static char ** readList (FILE *fp, int *n); +static void printList (char **list, int n); +static char ** bnetGenerateNewNames (st_table *hash, int n); +static int bnetDumpReencodingLogic (DdManager *dd, char *mname, int noutputs, DdNode **outputs, char **inames, char **altnames, char **onames, FILE *fp); +#if 0 +static int bnetBlifXnorTable (FILE *fp, int n); +#endif +static int bnetBlifWriteReencode (DdManager *dd, char *mname, char **inames, char **altnames, int *support, FILE *fp); +static int * bnetFindVectorSupport (DdManager *dd, DdNode **list, int n); +static int buildExorBDD (DdManager *dd, BnetNode *nd, st_table *hash, int params, int nodrop); +static int buildMuxBDD (DdManager * dd, BnetNode * nd, st_table * hash, int params, int nodrop); +static int bnetSetLevel (BnetNetwork *net); +static int bnetLevelDFS (BnetNetwork *net, BnetNode *node); +static BnetNode ** bnetOrderRoots (BnetNetwork *net, int *nroots); +static int bnetLevelCompare (BnetNode **x, BnetNode **y); +static int bnetDfsOrder (DdManager *dd, BnetNetwork *net, BnetNode *node); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Reads boolean network from blif file.] + + Description [Reads a boolean network from a blif file. A very restricted + subset of blif is supported. Specifically: +
                    +
                  • The only directives recognized are: +
                      +
                    • .model +
                    • .inputs +
                    • .outputs +
                    • .latch +
                    • .names +
                    • .exdc +
                    • .wire_load_slope +
                    • .end +
                    +
                  • Latches must have an initial values and no other parameters + specified. +
                  • Lines must not exceed MAXLENGTH-1 characters, and individual names must + not exceed 1023 characters. +
                  + Caveat emptor: There may be other limitations as well. One should + check the syntax of the blif file with some other tool before relying + on this parser. Bnet_ReadNetwork returns a pointer to the network if + successful; NULL otherwise. + ] + + SideEffects [None] + + SeeAlso [Bnet_PrintNetwork Bnet_FreeNetwork] + +******************************************************************************/ +BnetNetwork * +Bnet_ReadNetwork( + FILE * fp /* pointer to the blif file */, + int pr /* verbosity level */) +{ + char *savestring; + char **list; + int i, j, n; + BnetNetwork *net; + BnetNode *newnode; + BnetNode *lastnode = NULL; + BnetTabline *newline; + BnetTabline *lastline; + char ***latches = NULL; + int maxlatches = 0; + int exdc = 0; + BnetNode *node; + int count; + + /* Allocate network object and initialize symbol table. */ + net = ALLOC(BnetNetwork,1); + if (net == NULL) goto failure; + memset((char *) net, 0, sizeof(BnetNetwork)); + net->hash = st_init_table(strcmp,st_strhash); + if (net->hash == NULL) goto failure; + + savestring = readString(fp); + if (savestring == NULL) goto failure; + net->nlatches = 0; + while (strcmp(savestring, ".model") == 0 || + strcmp(savestring, ".inputs") == 0 || + strcmp(savestring, ".outputs") == 0 || + strcmp(savestring, ".latch") == 0 || + strcmp(savestring, ".wire_load_slope") == 0 || + strcmp(savestring, ".exdc") == 0 || + strcmp(savestring, ".names") == 0 || strcmp(savestring,".end") == 0) { + if (strcmp(savestring, ".model") == 0) { + /* Read .model directive. */ + FREE(savestring); + /* Read network name. */ + savestring = readString(fp); + if (savestring == NULL) goto failure; + net->name = savestring; + } else if (strcmp(savestring, ".inputs") == 0) { + /* Read .inputs directive. */ + FREE(savestring); + /* Read input names. */ + list = readList(fp,&n); + if (list == NULL) goto failure; + if (pr > 2) printList(list,n); + /* Expect at least one input. */ + if (n < 1) { + (void) fprintf(stdout,"Empty input list.\n"); + goto failure; + } + if (exdc) { + for (i = 0; i < n; i++) + FREE(list[i]); + FREE(list); + savestring = readString(fp); + if (savestring == NULL) goto failure; + continue; + } + if (net->ninputs) { + net->inputs = REALLOC(char *, net->inputs, + (net->ninputs + n) * sizeof(char *)); + for (i = 0; i < n; i++) + net->inputs[net->ninputs + i] = list[i]; + } + else + net->inputs = list; + /* Create a node for each primary input. */ + for (i = 0; i < n; i++) { + newnode = ALLOC(BnetNode,1); + memset((char *) newnode, 0, sizeof(BnetNode)); + if (newnode == NULL) goto failure; + newnode->name = list[i]; + newnode->inputs = NULL; + newnode->type = BNET_INPUT_NODE; + newnode->active = FALSE; + newnode->nfo = 0; + newnode->ninp = 0; + newnode->f = NULL; + newnode->polarity = 0; + newnode->dd = NULL; + newnode->next = NULL; + if (lastnode == NULL) { + net->nodes = newnode; + } else { + lastnode->next = newnode; + } + lastnode = newnode; + } + net->npis += n; + net->ninputs += n; + } else if (strcmp(savestring, ".outputs") == 0) { + /* Read .outputs directive. We do not create nodes for the primary + ** outputs, because the nodes will be created when the same names + ** appear as outputs of some gates. + */ + FREE(savestring); + /* Read output names. */ + list = readList(fp,&n); + if (list == NULL) goto failure; + if (pr > 2) printList(list,n); + if (n < 1) { + (void) fprintf(stdout,"Empty .outputs list.\n"); + goto failure; + } + if (exdc) { + for (i = 0; i < n; i++) + FREE(list[i]); + FREE(list); + savestring = readString(fp); + if (savestring == NULL) goto failure; + continue; + } + if (net->noutputs) { + net->outputs = REALLOC(char *, net->outputs, + (net->noutputs + n) * sizeof(char *)); + for (i = 0; i < n; i++) + net->outputs[net->noutputs + i] = list[i]; + } else { + net->outputs = list; + } + net->npos += n; + net->noutputs += n; + } else if (strcmp(savestring,".wire_load_slope") == 0) { + FREE(savestring); + savestring = readString(fp); + net->slope = savestring; + } else if (strcmp(savestring,".latch") == 0) { + FREE(savestring); + newnode = ALLOC(BnetNode,1); + if (newnode == NULL) goto failure; + memset((char *) newnode, 0, sizeof(BnetNode)); + newnode->type = BNET_PRESENT_STATE_NODE; + list = readList(fp,&n); + if (list == NULL) goto failure; + if (pr > 2) printList(list,n); + /* Expect three names. */ + if (n != 3) { + (void) fprintf(stdout, + ".latch not followed by three tokens.\n"); + goto failure; + } + newnode->name = list[1]; + newnode->inputs = NULL; + newnode->ninp = 0; + newnode->f = NULL; + newnode->active = FALSE; + newnode->nfo = 0; + newnode->polarity = 0; + newnode->dd = NULL; + newnode->next = NULL; + if (lastnode == NULL) { + net->nodes = newnode; + } else { + lastnode->next = newnode; + } + lastnode = newnode; + /* Add next state variable to list. */ + if (maxlatches == 0) { + maxlatches = 20; + latches = ALLOC(char **,maxlatches); + } else if (maxlatches <= net->nlatches) { + maxlatches += 20; + latches = REALLOC(char **,latches,maxlatches); + } + latches[net->nlatches] = list; + net->nlatches++; + savestring = readString(fp); + if (savestring == NULL) goto failure; + } else if (strcmp(savestring,".names") == 0) { + FREE(savestring); + newnode = ALLOC(BnetNode,1); + memset((char *) newnode, 0, sizeof(BnetNode)); + if (newnode == NULL) goto failure; + list = readList(fp,&n); + if (list == NULL) goto failure; + if (pr > 2) printList(list,n); + /* Expect at least one name (the node output). */ + if (n < 1) { + (void) fprintf(stdout,"Missing output name.\n"); + goto failure; + } + newnode->name = list[n-1]; + newnode->inputs = list; + newnode->ninp = n-1; + newnode->active = FALSE; + newnode->nfo = 0; + newnode->polarity = 0; + if (newnode->ninp > 0) { + newnode->type = BNET_INTERNAL_NODE; + for (i = 0; i < net->noutputs; i++) { + if (strcmp(net->outputs[i], newnode->name) == 0) { + newnode->type = BNET_OUTPUT_NODE; + break; + } + } + } else { + newnode->type = BNET_CONSTANT_NODE; + } + newnode->dd = NULL; + newnode->next = NULL; + if (lastnode == NULL) { + net->nodes = newnode; + } else { + lastnode->next = newnode; + } + lastnode = newnode; + /* Read node function. */ + newnode->f = NULL; + if (exdc) { + newnode->exdc_flag = 1; + node = net->nodes; + while (node) { + if (node->type == BNET_OUTPUT_NODE && + strcmp(node->name, newnode->name) == 0) { + node->exdc = newnode; + break; + } + node = node->next; + } + } + savestring = readString(fp); + if (savestring == NULL) goto failure; + lastline = NULL; + while (savestring[0] != '.') { + /* Reading a table line. */ + newline = ALLOC(BnetTabline,1); + if (newline == NULL) goto failure; + newline->next = NULL; + if (lastline == NULL) { + newnode->f = newline; + } else { + lastline->next = newline; + } + lastline = newline; + if (newnode->type == BNET_INTERNAL_NODE || + newnode->type == BNET_OUTPUT_NODE) { + newline->values = savestring; + /* Read output 1 or 0. */ + savestring = readString(fp); + if (savestring == NULL) goto failure; + } else { + newline->values = NULL; + } + if (savestring[0] == '0') newnode->polarity = 1; + FREE(savestring); + savestring = readString(fp); + if (savestring == NULL) goto failure; + } + } else if (strcmp(savestring,".exdc") == 0) { + FREE(savestring); + exdc = 1; + } else if (strcmp(savestring,".end") == 0) { + FREE(savestring); + break; + } + if ((!savestring) || savestring[0] != '.') + savestring = readString(fp); + if (savestring == NULL) goto failure; + } + + /* Put nodes in symbol table. */ + newnode = net->nodes; + while (newnode != NULL) { + int retval = st_insert(net->hash,newnode->name,(char *) newnode); + if (retval == ST_OUT_OF_MEM) { + goto failure; + } else if (retval == 1) { + printf("Error: Multiple drivers for node %s\n", newnode->name); + goto failure; + } else { + if (pr > 2) printf("Inserted %s\n",newnode->name); + } + newnode = newnode->next; + } + + if (latches) { + net->latches = latches; + + count = 0; + net->outputs = REALLOC(char *, net->outputs, + (net->noutputs + net->nlatches) * sizeof(char *)); + for (i = 0; i < net->nlatches; i++) { + for (j = 0; j < net->noutputs; j++) { + if (strcmp(latches[i][0], net->outputs[j]) == 0) + break; + } + if (j < net->noutputs) + continue; + savestring = ALLOC(char, strlen(latches[i][0]) + 1); + strcpy(savestring, latches[i][0]); + net->outputs[net->noutputs + count] = savestring; + count++; + if (st_lookup(net->hash, savestring, &node)) { + if (node->type == BNET_INTERNAL_NODE) { + node->type = BNET_OUTPUT_NODE; + } + } + } + net->noutputs += count; + + net->inputs = REALLOC(char *, net->inputs, + (net->ninputs + net->nlatches) * sizeof(char *)); + for (i = 0; i < net->nlatches; i++) { + savestring = ALLOC(char, strlen(latches[i][1]) + 1); + strcpy(savestring, latches[i][1]); + net->inputs[net->ninputs + i] = savestring; + } + net->ninputs += net->nlatches; + } + + /* Compute fanout counts. For each node in the linked list, fetch + ** all its fanins using the symbol table, and increment the fanout of + ** each fanin. + */ + newnode = net->nodes; + while (newnode != NULL) { + BnetNode *auxnd; + for (i = 0; i < newnode->ninp; i++) { + if (!st_lookup(net->hash,newnode->inputs[i],&auxnd)) { + (void) fprintf(stdout,"%s not driven\n", newnode->inputs[i]); + goto failure; + } + auxnd->nfo++; + } + newnode = newnode->next; + } + + if (!bnetSetLevel(net)) goto failure; + + return(net); + +failure: + /* Here we should clean up the mess. */ + (void) fprintf(stdout,"Error in reading network from file.\n"); + return(NULL); + +} /* end of Bnet_ReadNetwork */ + + +/**Function******************************************************************** + + Synopsis [Prints a boolean network created by readNetwork.] + + Description [Prints to the standard output a boolean network created + by Bnet_ReadNetwork. Uses the blif format; this way, one can verify the + equivalence of the input and the output with, say, sis.] + + SideEffects [None] + + SeeAlso [Bnet_ReadNetwork] + +******************************************************************************/ +void +Bnet_PrintNetwork( + BnetNetwork * net /* boolean network */) +{ + BnetNode *nd; + BnetTabline *tl; + int i; + + if (net == NULL) return; + + (void) fprintf(stdout,".model %s\n", net->name); + (void) fprintf(stdout,".inputs"); + printList(net->inputs,net->npis); + (void) fprintf(stdout,".outputs"); + printList(net->outputs,net->npos); + for (i = 0; i < net->nlatches; i++) { + (void) fprintf(stdout,".latch"); + printList(net->latches[i],3); + } + nd = net->nodes; + while (nd != NULL) { + if (nd->type != BNET_INPUT_NODE && nd->type != BNET_PRESENT_STATE_NODE) { + (void) fprintf(stdout,".names"); + for (i = 0; i < nd->ninp; i++) { + (void) fprintf(stdout," %s",nd->inputs[i]); + } + (void) fprintf(stdout," %s\n",nd->name); + tl = nd->f; + while (tl != NULL) { + if (tl->values != NULL) { + (void) fprintf(stdout,"%s %d\n",tl->values, + 1 - nd->polarity); + } else { + (void) fprintf(stdout,"%d\n", 1 - nd->polarity); + } + tl = tl->next; + } + } + nd = nd->next; + } + (void) fprintf(stdout,".end\n"); + +} /* end of Bnet_PrintNetwork */ + + +/**Function******************************************************************** + + Synopsis [Frees a boolean network created by Bnet_ReadNetwork.] + + Description [] + + SideEffects [None] + + SeeAlso [Bnet_ReadNetwork] + +******************************************************************************/ +void +Bnet_FreeNetwork( + BnetNetwork * net) +{ + BnetNode *node, *nextnode; + BnetTabline *line, *nextline; + int i; + + FREE(net->name); + /* The input name strings are already pointed by the input nodes. + ** Here we only need to free the latch names and the array that + ** points to them. + */ + for (i = 0; i < net->nlatches; i++) { + FREE(net->inputs[net->npis + i]); + } + FREE(net->inputs); + /* Free the output name strings and then the array pointing to them. */ + for (i = 0; i < net->noutputs; i++) { + FREE(net->outputs[i]); + } + FREE(net->outputs); + + for (i = 0; i < net->nlatches; i++) { + FREE(net->latches[i][0]); + FREE(net->latches[i][1]); + FREE(net->latches[i][2]); + FREE(net->latches[i]); + } + if (net->nlatches) FREE(net->latches); + node = net->nodes; + while (node != NULL) { + nextnode = node->next; + if (node->type != BNET_PRESENT_STATE_NODE) + FREE(node->name); + for (i = 0; i < node->ninp; i++) { + FREE(node->inputs[i]); + } + if (node->inputs != NULL) { + FREE(node->inputs); + } + /* Free the function table. */ + line = node->f; + while (line != NULL) { + nextline = line->next; + FREE(line->values); + FREE(line); + line = nextline; + } + FREE(node); + node = nextnode; + } + st_free_table(net->hash); + if (net->slope != NULL) FREE(net->slope); + FREE(net); + +} /* end of Bnet_FreeNetwork */ + + +/**Function******************************************************************** + + Synopsis [Builds the BDD for the function of a node.] + + Description [Builds the BDD for the function of a node and stores a + pointer to it in the dd field of the node itself. The reference count + of the BDD is incremented. If params is BNET_LOCAL_DD, then the BDD is + built in terms of the local inputs to the node; otherwise, if params + is BNET_GLOBAL_DD, the BDD is built in terms of the network primary + inputs. To build the global BDD of a node, the BDDs for its local + inputs must exist. If that is not the case, Bnet_BuildNodeBDD + recursively builds them. Likewise, to create the local BDD for a node, + the local inputs must have variables assigned to them. If that is not + the case, Bnet_BuildNodeBDD recursively assigns variables to nodes. + Bnet_BuildNodeBDD returns 1 in case of success; 0 otherwise.] + + SideEffects [Sets the dd field of the node.] + + SeeAlso [] + +******************************************************************************/ +int +Bnet_BuildNodeBDD( + DdManager * dd /* DD manager */, + BnetNode * nd /* node of the boolean network */, + st_table * hash /* symbol table of the boolean network */, + int params /* type of DD to be built */, + int nodrop /* retain the intermediate node DDs until the end */) +{ + DdNode *func; + BnetNode *auxnd; + DdNode *tmp; + DdNode *prod, *var; + BnetTabline *line; + int i; + + if (nd->dd != NULL) return(1); + + if (nd->type == BNET_CONSTANT_NODE) { + if (nd->f == NULL) { /* constant 0 */ + func = Cudd_ReadLogicZero(dd); + } else { /* either constant depending on the polarity */ + func = Cudd_ReadOne(dd); + } + Cudd_Ref(func); + } else if (nd->type == BNET_INPUT_NODE || + nd->type == BNET_PRESENT_STATE_NODE) { + if (nd->active == TRUE) { /* a variable is already associated: use it */ + func = Cudd_ReadVars(dd,nd->var); + if (func == NULL) goto failure; + } else { /* no variable associated: get a new one */ + func = Cudd_bddNewVar(dd); + if (func == NULL) goto failure; + nd->var = func->index; + nd->active = TRUE; + } + Cudd_Ref(func); + } else if (buildExorBDD(dd,nd,hash,params,nodrop)) { + func = nd->dd; + } else if (buildMuxBDD(dd,nd,hash,params,nodrop)) { + func = nd->dd; + } else { /* type == BNET_INTERNAL_NODE or BNET_OUTPUT_NODE */ + /* Initialize the sum to logical 0. */ + func = Cudd_ReadLogicZero(dd); + Cudd_Ref(func); + + /* Build a term for each line of the table and add it to the + ** accumulator (func). + */ + line = nd->f; + while (line != NULL) { +#ifdef BNET_DEBUG + (void) fprintf(stdout,"line = %s\n", line->values); +#endif + /* Initialize the product to logical 1. */ + prod = Cudd_ReadOne(dd); + Cudd_Ref(prod); + /* Scan the table line. */ + for (i = 0; i < nd->ninp; i++) { + if (line->values[i] == '-') continue; + if (!st_lookup(hash,nd->inputs[i],&auxnd)) { + goto failure; + } + if (params == BNET_LOCAL_DD) { + if (auxnd->active == FALSE) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + var = Cudd_ReadVars(dd,auxnd->var); + if (var == NULL) goto failure; + Cudd_Ref(var); + if (line->values[i] == '0') { + var = Cudd_Not(var); + } + } else { /* params == BNET_GLOBAL_DD */ + if (auxnd->dd == NULL) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + if (line->values[i] == '1') { + var = auxnd->dd; + } else { /* line->values[i] == '0' */ + var = Cudd_Not(auxnd->dd); + } + } + tmp = Cudd_bddAnd(dd,prod,var); + if (tmp == NULL) goto failure; + Cudd_Ref(tmp); + Cudd_IterDerefBdd(dd,prod); + if (params == BNET_LOCAL_DD) { + Cudd_IterDerefBdd(dd,var); + } + prod = tmp; + } + tmp = Cudd_bddOr(dd,func,prod); + if (tmp == NULL) goto failure; + Cudd_Ref(tmp); + Cudd_IterDerefBdd(dd,func); + Cudd_IterDerefBdd(dd,prod); + func = tmp; + line = line->next; + } + /* Associate a variable to this node if local BDDs are being + ** built. This is done at the end, so that the primary inputs tend + ** to get lower indices. + */ + if (params == BNET_LOCAL_DD && nd->active == FALSE) { + DdNode *auxfunc = Cudd_bddNewVar(dd); + if (auxfunc == NULL) goto failure; + Cudd_Ref(auxfunc); + nd->var = auxfunc->index; + nd->active = TRUE; + Cudd_IterDerefBdd(dd,auxfunc); + } + } + if (nd->polarity == 1) { + nd->dd = Cudd_Not(func); + } else { + nd->dd = func; + } + + if (params == BNET_GLOBAL_DD && nodrop == FALSE) { + /* Decrease counters for all faninis. + ** When count reaches 0, the DD is freed. + */ + for (i = 0; i < nd->ninp; i++) { + if (!st_lookup(hash,nd->inputs[i],&auxnd)) { + goto failure; + } + auxnd->count--; + if (auxnd->count == 0) { + Cudd_IterDerefBdd(dd,auxnd->dd); + if (auxnd->type == BNET_INTERNAL_NODE || + auxnd->type == BNET_CONSTANT_NODE) auxnd->dd = NULL; + } + } + } + return(1); + +failure: + /* Here we should clean up the mess. */ + return(0); + +} /* end of Bnet_BuildNodeBDD */ + + +/**Function******************************************************************** + + Synopsis [Orders the BDD variables by DFS.] + + Description [Orders the BDD variables by DFS. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [Uses the visited flags of the nodes.] + + SeeAlso [] + +******************************************************************************/ +int +Bnet_DfsVariableOrder( + DdManager * dd, + BnetNetwork * net) +{ + BnetNode **roots; + BnetNode *node; + int nroots; + int i; + + roots = bnetOrderRoots(net,&nroots); + if (roots == NULL) return(0); + for (i = 0; i < nroots; i++) { + if (!bnetDfsOrder(dd,net,roots[i])) { + FREE(roots); + return(0); + } + } + /* Clear visited flags. */ + node = net->nodes; + while (node != NULL) { + node->visited = 0; + node = node->next; + } + FREE(roots); + return(1); + +} /* end of Bnet_DfsVariableOrder */ + + +/**Function******************************************************************** + + Synopsis [Writes the network BDDs to a file in dot, blif, or daVinci + format.] + + Description [Writes the network BDDs to a file in dot, blif, or daVinci + format. If "-" is passed as file name, the BDDs are dumped to the + standard output. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Bnet_bddDump( + DdManager * dd /* DD manager */, + BnetNetwork * network /* network whose BDDs should be dumped */, + char * dfile /* file name */, + int dumpFmt /* 0 -> dot */, + int reencoded /* whether variables have been reencoded */) +{ + int noutputs; + FILE *dfp = NULL; + DdNode **outputs = NULL; + char **inames = NULL; + char **onames = NULL; + char **altnames = NULL; + BnetNode *node; + int i; + int retval = 0; /* 0 -> failure; 1 -> success */ + + /* Open dump file. */ + if (strcmp(dfile, "-") == 0) { + dfp = stdout; + } else { + dfp = fopen(dfile,"w"); + } + if (dfp == NULL) goto endgame; + + /* Initialize data structures. */ + noutputs = network->noutputs; + outputs = ALLOC(DdNode *,noutputs); + if (outputs == NULL) goto endgame; + onames = ALLOC(char *,noutputs); + if (onames == NULL) goto endgame; + inames = ALLOC(char *,Cudd_ReadSize(dd)); + if (inames == NULL) goto endgame; + + /* Find outputs and their names. */ + for (i = 0; i < network->nlatches; i++) { + onames[i] = network->latches[i][0]; + if (!st_lookup(network->hash,network->latches[i][0],&node)) { + goto endgame; + } + outputs[i] = node->dd; + } + for (i = 0; i < network->npos; i++) { + onames[i + network->nlatches] = network->outputs[i]; + if (!st_lookup(network->hash,network->outputs[i],&node)) { + goto endgame; + } + outputs[i + network->nlatches] = node->dd; + } + + /* Find the input names. */ + for (i = 0; i < network->ninputs; i++) { + if (!st_lookup(network->hash,network->inputs[i],&node)) { + goto endgame; + } + inames[node->var] = network->inputs[i]; + } + for (i = 0; i < network->nlatches; i++) { + if (!st_lookup(network->hash,network->latches[i][1],&node)) { + goto endgame; + } + inames[node->var] = network->latches[i][1]; + } + + if (reencoded == 1 && dumpFmt == 1) { + altnames = bnetGenerateNewNames(network->hash,network->ninputs); + if (altnames == NULL) { + retval = 0; + goto endgame; + } + retval = bnetDumpReencodingLogic(dd,network->name,noutputs,outputs, + inames,altnames,onames,dfp); + for (i = 0; i < network->ninputs; i++) { + FREE(altnames[i]); + } + FREE(altnames); + if (retval == 0) goto endgame; + } + + /* Dump the BDDs. */ + if (dumpFmt == 1) { + retval = Cudd_DumpBlif(dd,noutputs,outputs,inames,onames, + network->name,dfp,0); + } else if (dumpFmt == 2) { + retval = Cudd_DumpDaVinci(dd,noutputs,outputs,inames,onames,dfp); + } else if (dumpFmt == 3) { + retval = Cudd_DumpDDcal(dd,noutputs,outputs,inames,onames,dfp); + } else if (dumpFmt == 4) { + retval = Cudd_DumpFactoredForm(dd,noutputs,outputs,inames,onames,dfp); + } else if (dumpFmt == 5) { + retval = Cudd_DumpBlif(dd,noutputs,outputs,inames,onames, + network->name,dfp,1); + } else { + retval = Cudd_DumpDot(dd,noutputs,outputs,inames,onames,dfp); + } + +endgame: + if (dfp != stdout && dfp != NULL) { + if (fclose(dfp) == EOF) retval = 0; + } + if (outputs != NULL) FREE(outputs); + if (onames != NULL) FREE(onames); + if (inames != NULL) FREE(inames); + + return(retval); + +} /* end of Bnet_bddDump */ + + +/**Function******************************************************************** + + Synopsis [Writes an array of BDDs to a file in dot, blif, DDcal, + factored-form, daVinci, or blif-MV format.] + + Description [Writes an array of BDDs to a file in dot, blif, DDcal, + factored-form, daVinci, or blif-MV format. The BDDs and their names + are passed as arguments. The inputs and their names are taken from + the network. If "-" is passed as file name, the BDDs are dumped to + the standard output. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Bnet_bddArrayDump( + DdManager * dd /* DD manager */, + BnetNetwork * network /* network whose BDDs should be dumped */, + char * dfile /* file name */, + DdNode ** outputs /* BDDs to be dumped */, + char ** onames /* names of the BDDs to be dumped */, + int noutputs /* number of BDDs to be dumped */, + int dumpFmt /* 0 -> dot */) +{ + FILE *dfp = NULL; + char **inames = NULL; + BnetNode *node; + int i; + int retval = 0; /* 0 -> failure; 1 -> success */ + + /* Open dump file. */ + if (strcmp(dfile, "-") == 0) { + dfp = stdout; + } else { + dfp = fopen(dfile,"w"); + } + if (dfp == NULL) goto endgame; + + /* Initialize data structures. */ + inames = ALLOC(char *,Cudd_ReadSize(dd)); + if (inames == NULL) goto endgame; + for (i = 0; i < Cudd_ReadSize(dd); i++) { + inames[i] = NULL; + } + + /* Find the input names. */ + for (i = 0; i < network->ninputs; i++) { + if (!st_lookup(network->hash,network->inputs[i],&node)) { + goto endgame; + } + inames[node->var] = network->inputs[i]; + } + for (i = 0; i < network->nlatches; i++) { + if (!st_lookup(network->hash,network->latches[i][1],&node)) { + goto endgame; + } + inames[node->var] = network->latches[i][1]; + } + + /* Dump the BDDs. */ + if (dumpFmt == 1) { + retval = Cudd_DumpBlif(dd,noutputs,outputs,inames,onames, + network->name,dfp,0); + } else if (dumpFmt == 2) { + retval = Cudd_DumpDaVinci(dd,noutputs,outputs,inames,onames,dfp); + } else if (dumpFmt == 3) { + retval = Cudd_DumpDDcal(dd,noutputs,outputs,inames,onames,dfp); + } else if (dumpFmt == 4) { + retval = Cudd_DumpFactoredForm(dd,noutputs,outputs,inames,onames,dfp); + } else if (dumpFmt == 5) { + retval = Cudd_DumpBlif(dd,noutputs,outputs,inames,onames, + network->name,dfp,1); + } else { + retval = Cudd_DumpDot(dd,noutputs,outputs,inames,onames,dfp); + } + +endgame: + if (dfp != stdout && dfp != NULL) { + if (fclose(dfp) == EOF) retval = 0; + } + if (inames != NULL) FREE(inames); + + return(retval); + +} /* end of Bnet_bddArrayDump */ + + +/**Function******************************************************************** + + Synopsis [Reads the variable order from a file.] + + Description [Reads the variable order from a file. + Returns 1 if successful; 0 otherwise.] + + SideEffects [The BDDs for the primary inputs and present state variables + are built.] + + SeeAlso [] + +*****************************************************************************/ +int +Bnet_ReadOrder( + DdManager * dd, + char * ordFile, + BnetNetwork * net, + int locGlob, + int nodrop) +{ + FILE *fp; + st_table *dict; + int result; + BnetNode *node; + char name[MAXLENGTH]; + + if (ordFile == NULL) { + return(0); + } + + dict = st_init_table(strcmp,st_strhash); + if (dict == NULL) { + return(0); + } + + if ((fp = fopen(ordFile,"r")) == NULL) { + (void) fprintf(stderr,"Unable to open %s\n",ordFile); + st_free_table(dict); + return(0); + } + + while (!feof(fp)) { + result = fscanf(fp, "%s", name); + if (result == EOF) { + break; + } else if (result != 1) { + st_free_table(dict); + return(0); + } else if (strlen(name) > MAXLENGTH) { + st_free_table(dict); + return(0); + } + /* There should be a node named "name" in the network. */ + if (!st_lookup(net->hash,name,&node)) { + (void) fprintf(stderr,"Unknown name in order file (%s)\n", name); + st_free_table(dict); + return(0); + } + /* A name should not appear more than once in the order. */ + if (st_is_member(dict,name)) { + (void) fprintf(stderr,"Duplicate name in order file (%s)\n", name); + st_free_table(dict); + return(0); + } + /* The name should correspond to a primary input or present state. */ + if (node->type != BNET_INPUT_NODE && + node->type != BNET_PRESENT_STATE_NODE) { + (void) fprintf(stderr,"%s has the wrong type (%d)\n", name, + node->type); + st_free_table(dict); + return(0); + } + /* Insert in table. Use node->name rather than name, because the + ** latter gets overwritten. + */ + if (st_insert(dict,node->name,NULL) == ST_OUT_OF_MEM) { + (void) fprintf(stderr,"Out of memory in Bnet_ReadOrder\n"); + st_free_table(dict); + return(0); + } + result = Bnet_BuildNodeBDD(dd,node,net->hash,locGlob,nodrop); + if (result == 0) { + (void) fprintf(stderr,"Construction of BDD failed\n"); + st_free_table(dict); + return(0); + } + } /* while (!feof(fp)) */ + result = fclose(fp); + if (result == EOF) { + (void) fprintf(stderr,"Error closing order file %s\n", ordFile); + st_free_table(dict); + return(0); + } + + /* The number of names in the order file should match exactly the + ** number of primary inputs and present states. + */ + if (st_count(dict) != net->ninputs) { + (void) fprintf(stderr,"Order incomplete: %d names instead of %d\n", + st_count(dict), net->ninputs); + st_free_table(dict); + return(0); + } + + st_free_table(dict); + return(1); + +} /* end of Bnet_ReadOrder */ + + +/**Function******************************************************************** + + Synopsis [Prints the order of the DD variables of a network.] + + Description [Prints the order of the DD variables of a network. + Only primary inputs and present states are printed. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +int +Bnet_PrintOrder( + BnetNetwork * net, + DdManager *dd) +{ + char **names; /* array used to print variable orders */ + int level; /* position of a variable in current order */ + BnetNode *node; /* auxiliary pointer to network node */ + int i,j; + int retval; + int nvars; + + nvars = Cudd_ReadSize(dd); + names = ALLOC(char *, nvars); + if (names == NULL) return(0); + for (i = 0; i < nvars; i++) { + names[i] = NULL; + } + for (i = 0; i < net->npis; i++) { + if (!st_lookup(net->hash,net->inputs[i],&node)) { + FREE(names); + return(0); + } + if (node->dd == NULL) { + FREE(names); + return(0); + } + level = Cudd_ReadPerm(dd,node->var); + names[level] = node->name; + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + FREE(names); + return(0); + } + if (node->dd == NULL) { + FREE(names); + return(0); + } + level = Cudd_ReadPerm(dd,node->var); + names[level] = node->name; + } + for (i = 0, j = 0; i < nvars; i++) { + if (names[i] == NULL) continue; + if ((j%8 == 0)&&j) { + retval = printf("\n"); + if (retval == EOF) { + FREE(names); + return(0); + } + } + retval = printf("%s ",names[i]); + if (retval == EOF) { + FREE(names); + return(0); + } + j++; + } + FREE(names); + retval = printf("\n"); + if (retval == EOF) { + return(0); + } + return(1); + +} /* end of Bnet_PrintOrder */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Reads a string from a file.] + + Description [Reads a string from a file. The string can be MAXLENGTH-1 + characters at most. readString allocates memory to hold the string and + returns a pointer to the result if successful. It returns NULL + otherwise.] + + SideEffects [None] + + SeeAlso [readList] + +******************************************************************************/ +static char * +readString( + FILE * fp /* pointer to the file from which the string is read */) +{ + char *savestring; + int length; + + while (!CurPos) { + if (!fgets(BuffLine, MAXLENGTH, fp)) + return(NULL); + BuffLine[strlen(BuffLine) - 1] = '\0'; + CurPos = strtok(BuffLine, " \t"); + if (CurPos && CurPos[0] == '#') CurPos = (char *)NULL; + } + length = strlen(CurPos); + savestring = ALLOC(char,length+1); + if (savestring == NULL) + return(NULL); + strcpy(savestring,CurPos); + CurPos = strtok(NULL, " \t"); + return(savestring); + +} /* end of readString */ + + +/**Function******************************************************************** + + Synopsis [Reads a list of strings from a file.] + + Description [Reads a list of strings from a line of a file. + The strings are sequences of characters separated by spaces or tabs. + The total length of the list, white space included, must not exceed + MAXLENGTH-1 characters. readList allocates memory for the strings and + creates an array of pointers to the individual lists. Only two pieces + of memory are allocated by readList: One to hold all the strings, + and one to hold the pointers to them. Therefore, when freeing the + memory allocated by readList, only the pointer to the list of + pointers, and the pointer to the beginning of the first string should + be freed. readList returns the pointer to the list of pointers if + successful; NULL otherwise.] + + SideEffects [n is set to the number of strings in the list.] + + SeeAlso [readString printList] + +******************************************************************************/ +static char ** +readList( + FILE * fp /* pointer to the file from which the list is read */, + int * n /* on return, number of strings in the list */) +{ + char *savestring; + int length; + char *stack[8192]; + char **list; + int i, count = 0; + + while (CurPos) { + if (strcmp(CurPos, "\\") == 0) { + CurPos = (char *)NULL; + while (!CurPos) { + if (!fgets(BuffLine, MAXLENGTH, fp)) return(NULL); + BuffLine[strlen(BuffLine) - 1] = '\0'; + CurPos = strtok(BuffLine, " \t"); + } + } + length = strlen(CurPos); + savestring = ALLOC(char,length+1); + if (savestring == NULL) return(NULL); + strcpy(savestring,CurPos); + stack[count] = savestring; + count++; + CurPos = strtok(NULL, " \t"); + } + list = ALLOC(char *, count); + for (i = 0; i < count; i++) + list[i] = stack[i]; + *n = count; + return(list); + +} /* end of readList */ + + +/**Function******************************************************************** + + Synopsis [Prints a list of strings to the standard output.] + + Description [Prints a list of strings to the standard output. The list + is in the format created by readList.] + + SideEffects [None] + + SeeAlso [readList Bnet_PrintNetwork] + +******************************************************************************/ +static void +printList( + char ** list /* list of pointers to strings */, + int n /* length of the list */) +{ + int i; + + for (i = 0; i < n; i++) { + (void) fprintf(stdout," %s",list[i]); + } + (void) fprintf(stdout,"\n"); + +} /* end of printList */ + + +/**Function******************************************************************** + + Synopsis [Generates names not currently in a symbol table.] + + Description [Generates n names not currently in the symbol table hash. + The pointer to the symbol table may be NULL, in which case no test is + made. The names generated by the procedure are unique. So, if there is + no possibility of conflict with pre-existing names, NULL can be passed + for the hash table. Returns an array of names if succesful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static char ** +bnetGenerateNewNames( + st_table * hash /* table of existing names (or NULL) */, + int n /* number of names to be generated */) +{ + char **list; + char name[256]; + int i; + + if (n < 1) return(NULL); + + list = ALLOC(char *,n); + if (list == NULL) return(NULL); + for (i = 0; i < n; i++) { + do { + sprintf(name, "var%d", newNameNumber); + newNameNumber++; + } while (hash != NULL && st_is_member(hash,name)); + list[i] = util_strsav(name); + } + + return(list); + +} /* bnetGenerateNewNames */ + + +/**Function******************************************************************** + + Synopsis [Writes blif for the reencoding logic.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +bnetDumpReencodingLogic( + DdManager * dd /* DD manager */, + char * mname /* model name */, + int noutputs /* number of outputs */, + DdNode ** outputs /* array of network outputs */, + char ** inames /* array of network input names */, + char ** altnames /* array of names of reencoded inputs */, + char ** onames /* array of network output names */, + FILE * fp /* file pointer */) +{ + int i; + int retval; + int nvars = Cudd_ReadSize(dd); + int *support = NULL; + + support = bnetFindVectorSupport(dd,outputs,noutputs); + if (support == NULL) return(0); + + /* Write the header (.model .inputs .outputs). */ + retval = fprintf(fp,".model %s.global\n.inputs",mname); + if (retval == EOF) goto failure; + + for (i = 0; i < nvars; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + retval = fprintf(fp," %s", inames[i]); + if (retval == EOF) goto failure; + } + + /* Write the .output line. */ + retval = fprintf(fp,"\n.outputs"); + if (retval == EOF) goto failure; + for (i = 0; i < noutputs; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + retval = fprintf(fp," %s", onames[i]); + if (retval == EOF) goto failure; + } + retval = fprintf(fp,"\n"); + if (retval == EOF) goto failure; + + /* Instantiate main subcircuit. */ + retval = fprintf(fp,"\n.subckt %s", mname); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + if (support[i] == 1) { + retval = fprintf(fp," %s=%s", inames[i], altnames[i]); + if (retval == EOF) goto failure; + } + } + for (i = 0; i < noutputs; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + retval = fprintf(fp," %s=%s", onames[i], onames[i]); + if (retval == EOF) goto failure; + } + retval = fprintf(fp,"\n"); + if (retval == EOF) goto failure; + + /* Instantiate reencoding subcircuit. */ + retval = fprintf(fp,"\n.subckt %s.reencode",mname); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + retval = fprintf(fp," %s=%s", inames[i], inames[i]); + if (retval == EOF) goto failure; + } + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + if (support[i] == 1) { + retval = fprintf(fp," %s=%s", altnames[i],altnames[i]); + if (retval == EOF) goto failure; + } + } + retval = fprintf(fp,"\n"); + if (retval == EOF) goto failure; + + /* Write trailer. */ + retval = fprintf(fp,".end\n\n"); + if (retval == EOF) goto failure; + + /* Write reencoding subcircuit. */ + retval = bnetBlifWriteReencode(dd,mname,inames,altnames,support,fp); + if (retval == EOF) goto failure; + + FREE(support); + return(1); + +failure: + if (support != NULL) FREE(support); + return(0); + +} /* end of bnetDumpReencodingLogic */ + + +/**Function******************************************************************** + + Synopsis [Writes blif for the truth table of an n-input xnor.] + + Description [Writes blif for the truth table of an n-input + xnor. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +#if 0 +static int +bnetBlifXnorTable( + FILE * fp /* file pointer */, + int n /* number of inputs */) +{ + int power; /* 2 to the power n */ + int i,j,k; + int nzeroes; + int retval; + char *line; + + line = ALLOC(char,n+1); + if (line == NULL) return(0); + line[n] = '\0'; + + for (i = 0, power = 1; i < n; i++) { + power *= 2; + } + + for (i = 0; i < power; i++) { + k = i; + nzeroes = 0; + for (j = 0; j < n; j++) { + if (k & 1) { + line[j] = '1'; + } else { + line[j] = '0'; + nzeroes++; + } + k >>= 1; + } + if ((nzeroes & 1) == 0) { + retval = fprintf(fp,"%s 1\n",line); + if (retval == 0) return(0); + } + } + return(1); + +} /* end of bnetBlifXnorTable */ +#endif + + +/**Function******************************************************************** + + Synopsis [Writes blif for the reencoding logic.] + + Description [Writes blif for the reencoding logic. Exclusive NORs + with more than two inputs are decomposed into cascaded two-input + gates. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +bnetBlifWriteReencode( + DdManager * dd, + char * mname, + char ** inames, + char ** altnames, + int * support, + FILE * fp) +{ + int retval; + int nvars = Cudd_ReadSize(dd); + int i,j; + int ninp; + + /* Write the header (.model .inputs .outputs). */ + retval = fprintf(fp,".model %s.reencode\n.inputs",mname); + if (retval == EOF) return(0); + + for (i = 0; i < nvars; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + retval = fprintf(fp," %s", inames[i]); + if (retval == EOF) goto failure; + } + + /* Write the .output line. */ + retval = fprintf(fp,"\n.outputs"); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if ((i%8 == 0)&&i) { + retval = fprintf(fp," \\\n"); + if (retval == EOF) goto failure; + } + if (support[i] == 1) { + retval = fprintf(fp," %s", altnames[i]); + if (retval == EOF) goto failure; + } + } + retval = fprintf(fp,"\n"); + if (retval == EOF) goto failure; + + /* Instantiate exclusive nors. */ + for (i = 0; i < nvars; i++) { + char *in1 = NULL; + char *in2 = NULL; + char **oname; + if (support[i] == 0) continue; + ninp = 0; + for (j = 0; j < nvars; j++) { + if (Cudd_ReadLinear(dd,i,j)) { + switch (ninp) { + case 0: + in1 = inames[j]; + ninp++; + break; + case 1: + in2 = inames[j]; + ninp++; + break; + case 2: + oname = bnetGenerateNewNames(NULL,1); + retval = fprintf(fp,".names %s %s %s\n11 1\n00 1\n", + in1, in2, oname[0]); + if (retval == EOF) goto failure; + in1 = oname[0]; + in2 = inames[j]; + FREE(oname); + break; + default: + goto failure; + } + } + } + switch (ninp) { + case 1: + retval = fprintf(fp,".names %s %s\n1 1\n", in1, altnames[i]); + if (retval == EOF) goto failure; + break; + case 2: + retval = fprintf(fp,".names %s %s %s\n11 1\n00 1\n", + in1, in2, altnames[i]); + if (retval == EOF) goto failure; + break; + default: + goto failure; + } + } + + /* Write trailer. */ + retval = fprintf(fp,"\n.end\n\n"); + if (retval == EOF) goto failure; + + return(1); + +failure: + return(0); + +} /* end of bnetBlifWriteReencode */ + + +/**Function******************************************************************** + + Synopsis [Finds the support of a list of DDs.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int * +bnetFindVectorSupport( + DdManager * dd, + DdNode ** list, + int n) +{ + DdNode *support = NULL; + DdNode *scan; + int *array = NULL; + int nvars = Cudd_ReadSize(dd); + int i; + + /* Build an array with the support of the functions in list. */ + array = ALLOC(int,nvars); + if (array == NULL) return(NULL); + for (i = 0; i < nvars; i++) { + array[i] = 0; + } + + /* Take the union of the supports of each output function. */ + for (i = 0; i < n; i++) { + support = Cudd_Support(dd,list[i]); + if (support == NULL) { + FREE(array); + return(NULL); + } + Cudd_Ref(support); + scan = support; + while (!Cudd_IsConstant(scan)) { + array[scan->index] = 1; + scan = Cudd_T(scan); + } + Cudd_IterDerefBdd(dd,support); + } + + return(array); + +} /* end of bnetFindVectorSupport */ + + +/**Function******************************************************************** + + Synopsis [Builds BDD for a XOR function.] + + Description [Checks whether a function is a XOR with 2 or 3 inputs. If so, + it builds the BDD. Returns 1 if the BDD has been built; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +buildExorBDD( + DdManager * dd, + BnetNode * nd, + st_table * hash, + int params, + int nodrop) +{ + int check[8]; + int i; + int nlines; + BnetTabline *line; + DdNode *func, *var, *tmp; + BnetNode *auxnd; + + if (nd->ninp < 2 || nd->ninp > 3) return(0); + + nlines = 1 << (nd->ninp - 1); + for (i = 0; i < 8; i++) check[i] = 0; + line = nd->f; + while (line != NULL) { + int num = 0; + int count = 0; + nlines--; + for (i = 0; i < nd->ninp; i++) { + num <<= 1; + if (line->values[i] == '-') { + return(0); + } else if (line->values[i] == '1') { + count++; + num++; + } + } + if ((count & 1) == 0) return(0); + if (check[num]) return(0); + line = line->next; + } + if (nlines != 0) return(0); + + /* Initialize the exclusive sum to logical 0. */ + func = Cudd_ReadLogicZero(dd); + Cudd_Ref(func); + + /* Scan the inputs. */ + for (i = 0; i < nd->ninp; i++) { + if (!st_lookup(hash, nd->inputs[i], &auxnd)) { + goto failure; + } + if (params == BNET_LOCAL_DD) { + if (auxnd->active == FALSE) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + var = Cudd_ReadVars(dd,auxnd->var); + if (var == NULL) goto failure; + Cudd_Ref(var); + } else { /* params == BNET_GLOBAL_DD */ + if (auxnd->dd == NULL) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + var = auxnd->dd; + } + tmp = Cudd_bddXor(dd,func,var); + if (tmp == NULL) goto failure; + Cudd_Ref(tmp); + Cudd_IterDerefBdd(dd,func); + if (params == BNET_LOCAL_DD) { + Cudd_IterDerefBdd(dd,var); + } + func = tmp; + } + nd->dd = func; + + /* Associate a variable to this node if local BDDs are being + ** built. This is done at the end, so that the primary inputs tend + ** to get lower indices. + */ + if (params == BNET_LOCAL_DD && nd->active == FALSE) { + DdNode *auxfunc = Cudd_bddNewVar(dd); + if (auxfunc == NULL) goto failure; + Cudd_Ref(auxfunc); + nd->var = auxfunc->index; + nd->active = TRUE; + Cudd_IterDerefBdd(dd,auxfunc); + } + + return(1); +failure: + return(0); + +} /* end of buildExorBDD */ + + +/**Function******************************************************************** + + Synopsis [Builds BDD for a multiplexer.] + + Description [Checks whether a function is a 2-to-1 multiplexer. If so, + it builds the BDD. Returns 1 if the BDD has been built; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +buildMuxBDD( + DdManager * dd, + BnetNode * nd, + st_table * hash, + int params, + int nodrop) +{ + BnetTabline *line; + char *values[2]; + int mux[2]; + int phase[2]; + int j; + int nlines = 0; + int controlC = -1; + int controlR = -1; + DdNode *func, *f, *g, *h; + BnetNode *auxnd; + + if (nd->ninp != 3) return(0); + + for (line = nd->f; line != NULL; line = line->next) { + int dc = 0; + if (nlines > 1) return(0); + values[nlines] = line->values; + for (j = 0; j < 3; j++) { + if (values[nlines][j] == '-') { + if (dc) return(0); + dc = 1; + } + } + if (!dc) return(0); + nlines++; + } + /* At this point we know we have: + ** 3 inputs + ** 2 lines + ** 1 dash in each line + ** If the two dashes are not in the same column, then there is + ** exaclty one column without dashes: the control column. + */ + for (j = 0; j < 3; j++) { + if (values[0][j] == '-' && values[1][j] == '-') return(0); + if (values[0][j] != '-' && values[1][j] != '-') { + if (values[0][j] == values[1][j]) return(0); + controlC = j; + controlR = values[0][j] == '0'; + } + } + assert(controlC != -1 && controlR != -1); + /* At this point we know that there is indeed no column with two + ** dashes. The control column has been identified, and we know that + ** its two elelments are different. */ + for (j = 0; j < 3; j++) { + if (j == controlC) continue; + if (values[controlR][j] == '1') { + mux[0] = j; + phase[0] = 0; + } else if (values[controlR][j] == '0') { + mux[0] = j; + phase[0] = 1; + } else if (values[1-controlR][j] == '1') { + mux[1] = j; + phase[1] = 0; + } else if (values[1-controlR][j] == '0') { + mux[1] = j; + phase[1] = 1; + } + } + + /* Get the inputs. */ + if (!st_lookup(hash, nd->inputs[controlC], &auxnd)) { + goto failure; + } + if (params == BNET_LOCAL_DD) { + if (auxnd->active == FALSE) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + f = Cudd_ReadVars(dd,auxnd->var); + if (f == NULL) goto failure; + Cudd_Ref(f); + } else { /* params == BNET_GLOBAL_DD */ + if (auxnd->dd == NULL) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + f = auxnd->dd; + } + if (!st_lookup(hash, nd->inputs[mux[0]], &auxnd)) { + goto failure; + } + if (params == BNET_LOCAL_DD) { + if (auxnd->active == FALSE) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + g = Cudd_ReadVars(dd,auxnd->var); + if (g == NULL) goto failure; + Cudd_Ref(g); + } else { /* params == BNET_GLOBAL_DD */ + if (auxnd->dd == NULL) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + g = auxnd->dd; + } + g = Cudd_NotCond(g,phase[0]); + if (!st_lookup(hash, nd->inputs[mux[1]], &auxnd)) { + goto failure; + } + if (params == BNET_LOCAL_DD) { + if (auxnd->active == FALSE) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + h = Cudd_ReadVars(dd,auxnd->var); + if (h == NULL) goto failure; + Cudd_Ref(h); + } else { /* params == BNET_GLOBAL_DD */ + if (auxnd->dd == NULL) { + if (!Bnet_BuildNodeBDD(dd,auxnd,hash,params,nodrop)) { + goto failure; + } + } + h = auxnd->dd; + } + h = Cudd_NotCond(h,phase[1]); + func = Cudd_bddIte(dd,f,g,h); + if (func == NULL) goto failure; + Cudd_Ref(func); + if (params == BNET_LOCAL_DD) { + Cudd_IterDerefBdd(dd,f); + Cudd_IterDerefBdd(dd,g); + Cudd_IterDerefBdd(dd,h); + } + nd->dd = func; + + /* Associate a variable to this node if local BDDs are being + ** built. This is done at the end, so that the primary inputs tend + ** to get lower indices. + */ + if (params == BNET_LOCAL_DD && nd->active == FALSE) { + DdNode *auxfunc = Cudd_bddNewVar(dd); + if (auxfunc == NULL) goto failure; + Cudd_Ref(auxfunc); + nd->var = auxfunc->index; + nd->active = TRUE; + Cudd_IterDerefBdd(dd,auxfunc); + } + + return(1); +failure: + return(0); + +} /* end of buildExorBDD */ + + +/**Function******************************************************************** + + Synopsis [Sets the level of each node.] + + Description [Sets the level of each node. Returns 1 if successful; 0 + otherwise.] + + SideEffects [Changes the level and visited fields of the nodes it + visits.] + + SeeAlso [bnetLevelDFS] + +******************************************************************************/ +static int +bnetSetLevel( + BnetNetwork * net) +{ + BnetNode *node; + + /* Recursively visit nodes. This is pretty inefficient, because we + ** visit all nodes in this loop, and most of them in the recursive + ** calls to bnetLevelDFS. However, this approach guarantees that + ** all nodes will be reached ven if there are dangling outputs. */ + node = net->nodes; + while (node != NULL) { + if (!bnetLevelDFS(net,node)) return(0); + node = node->next; + } + + /* Clear visited flags. */ + node = net->nodes; + while (node != NULL) { + node->visited = 0; + node = node->next; + } + return(1); + +} /* end of bnetSetLevel */ + + +/**Function******************************************************************** + + Synopsis [Does a DFS from a node setting the level field.] + + Description [Does a DFS from a node setting the level field. Returns + 1 if successful; 0 otherwise.] + + SideEffects [Changes the level and visited fields of the nodes it + visits.] + + SeeAlso [bnetSetLevel] + +******************************************************************************/ +static int +bnetLevelDFS( + BnetNetwork * net, + BnetNode * node) +{ + int i; + BnetNode *auxnd; + + if (node->visited == 1) { + return(1); + } + + node->visited = 1; + + /* Graphical sources have level 0. This is the final value if the + ** node has no fan-ins. Otherwise the successive loop will + ** increase the level. */ + node->level = 0; + for (i = 0; i < node->ninp; i++) { + if (!st_lookup(net->hash, node->inputs[i], &auxnd)) { + return(0); + } + if (!bnetLevelDFS(net,auxnd)) { + return(0); + } + if (auxnd->level >= node->level) node->level = 1 + auxnd->level; + } + return(1); + +} /* end of bnetLevelDFS */ + + +/**Function******************************************************************** + + Synopsis [Orders network roots for variable ordering.] + + Description [Orders network roots for variable ordering. Returns + an array with the ordered outputs and next state variables if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static BnetNode ** +bnetOrderRoots( + BnetNetwork * net, + int * nroots) +{ + int i, noutputs; + BnetNode *node; + BnetNode **nodes = NULL; + + /* Initialize data structures. */ + noutputs = net->noutputs; + nodes = ALLOC(BnetNode *, noutputs); + if (nodes == NULL) goto endgame; + + /* Find output names and levels. */ + for (i = 0; i < net->noutputs; i++) { + if (!st_lookup(net->hash,net->outputs[i],&node)) { + goto endgame; + } + nodes[i] = node; + } + + qsort((void *)nodes, noutputs, sizeof(BnetNode *), + (DD_QSFP)bnetLevelCompare); + *nroots = noutputs; + return(nodes); + +endgame: + if (nodes != NULL) FREE(nodes); + return(NULL); + +} /* end of bnetOrderRoots */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + +******************************************************************************/ +static int +bnetLevelCompare( + BnetNode ** x, + BnetNode ** y) +{ + return((*y)->level - (*x)->level); + +} /* end of bnetLevelCompare */ + + +/**Function******************************************************************** + + Synopsis [Does a DFS from a node ordering the inputs.] + + Description [Does a DFS from a node ordering the inputs. Returns + 1 if successful; 0 otherwise.] + + SideEffects [Changes visited fields of the nodes it visits.] + + SeeAlso [Bnet_DfsVariableOrder] + +******************************************************************************/ +static int +bnetDfsOrder( + DdManager * dd, + BnetNetwork * net, + BnetNode * node) +{ + int i; + BnetNode *auxnd; + BnetNode **fanins; + + if (node->visited == 1) { + return(1); + } + + node->visited = 1; + if (node->type == BNET_INPUT_NODE || + node->type == BNET_PRESENT_STATE_NODE) { + node->dd = Cudd_bddNewVar(dd); + if (node->dd == NULL) return(0); + Cudd_Ref(node->dd); + node->active = TRUE; + node->var = node->dd->index; + return(1); + } + + fanins = ALLOC(BnetNode *, node->ninp); + if (fanins == NULL) return(0); + + for (i = 0; i < node->ninp; i++) { + if (!st_lookup(net->hash, node->inputs[i], &auxnd)) { + FREE(fanins); + return(0); + } + fanins[i] = auxnd; + } + + qsort((void *)fanins, node->ninp, sizeof(BnetNode *), + (DD_QSFP)bnetLevelCompare); + for (i = 0; i < node->ninp; i++) { + /* for (i = node->ninp - 1; i >= 0; i--) { */ + int res = bnetDfsOrder(dd,net,fanins[i]); + if (res == 0) { + FREE(fanins); + return(0); + } + } + FREE(fanins); + return(1); + +} /* end of bnetLevelDFS */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/bnet.h b/resources/3rdparty/cudd-2.5.0/nanotrav/bnet.h new file mode 100644 index 000000000..ec468abce --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/bnet.h @@ -0,0 +1,187 @@ +/**CHeaderFile***************************************************************** + + FileName [bnet.h] + + PackageName [bnet] + + Synopsis [Simple-minded package to read a blif file.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: bnet.h,v 1.13 2012/02/05 01:53:01 fabio Exp fabio $] + +******************************************************************************/ + +#ifndef _BNET +#define _BNET + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include "util.h" +#include "st.h" +#include "cudd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Different types of nodes. (Used in the "BnetNode" type.) */ +#define BNET_CONSTANT_NODE 0 +#define BNET_INPUT_NODE 1 +#define BNET_PRESENT_STATE_NODE 2 +#define BNET_INTERNAL_NODE 3 +#define BNET_OUTPUT_NODE 4 +#define BNET_NEXT_STATE_NODE 5 + +/* Type of DD of a node. */ +#define BNET_LOCAL_DD 0 +#define BNET_GLOBAL_DD 1 + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/* The following types implement a very simple data structure for a boolean +** network. The intent is to be able to read a minimal subset of the blif +** format in a data structure from which it's easy to build DDs for the +** circuit. +*/ + +/* Type to store a line of the truth table of a node. The entire truth table +** implemented as a linked list of objects of this type. +*/ +typedef struct BnetTabline { + char *values; /* string of 1, 0, and - */ + struct BnetTabline *next; /* pointer to next table line */ +} BnetTabline; + +/* Node of the boolean network. There is one node in the network for each +** primary input and for each .names directive. This structure +** has a field to point to the DD of the node function. The function may +** be either in terms of primary inputs, or it may be in terms of the local +** inputs. The latter implies that each node has a variable index +** associated to it at some point in time. The field "var" stores that +** variable index, and "active" says if the association is currently valid. +** (It is indeed possible for an index to be associated to different nodes +** at different times.) +*/ +typedef struct BnetNode { + char *name; /* name of the output signal */ + int type; /* input, internal, constant, ... */ + int ninp; /* number of inputs to the node */ + int nfo; /* number of fanout nodes for this node */ + char **inputs; /* input names */ + BnetTabline *f; /* truth table for this node */ + int polarity; /* f is the onset (0) or the offset (1) */ + int active; /* node has variable associated to it (1) or not (0) */ + int var; /* DD variable index associated to this node */ + DdNode *dd; /* decision diagram for the function of this node */ + int exdc_flag; /* whether an exdc node or not */ + struct BnetNode *exdc; /* pointer to exdc of dd node */ + int count; /* auxiliary field for DD dropping */ + int level; /* maximum distance from the inputs */ + int visited; /* flag for search */ + struct BnetNode *next; /* pointer to implement the linked list of nodes */ +} BnetNode; + +/* Very simple boolean network data structure. */ +typedef struct BnetNetwork { + char *name; /* network name: from the .model directive */ + int npis; /* number of primary inputs */ + int ninputs; /* number of inputs */ + char **inputs; /* primary input names: from the .inputs directive */ + int npos; /* number of primary outputs */ + int noutputs; /* number of outputs */ + char **outputs; /* primary output names: from the .outputs directive */ + int nlatches; /* number of latches */ + char ***latches; /* next state names: from the .latch directives */ + BnetNode *nodes; /* linked list of the nodes */ + st_table *hash; /* symbol table to access nodes by name */ + char *slope; /* wire_load_slope */ +} BnetNetwork; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef TRUE +# define TRUE 1 +#endif +#ifndef FALSE +# define FALSE 0 +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern BnetNetwork * Bnet_ReadNetwork (FILE *fp, int pr); +extern void Bnet_PrintNetwork (BnetNetwork *net); +extern void Bnet_FreeNetwork (BnetNetwork *net); +extern int Bnet_BuildNodeBDD (DdManager *dd, BnetNode *nd, st_table *hash, int params, int nodrop); +extern int Bnet_DfsVariableOrder (DdManager *dd, BnetNetwork *net); +extern int Bnet_bddDump (DdManager *dd, BnetNetwork *network, char *dfile, int dumpFmt, int reencoded); +extern int Bnet_bddArrayDump (DdManager *dd, BnetNetwork *network, char *dfile, DdNode **outputs, char **onames, int noutputs, int dumpFmt); +extern int Bnet_ReadOrder (DdManager *dd, char *ordFile, BnetNetwork *net, int locGlob, int nodrop); +extern int Bnet_PrintOrder (BnetNetwork * net, DdManager *dd); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _BNET */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/chkMterm.c b/resources/3rdparty/cudd-2.5.0/nanotrav/chkMterm.c new file mode 100644 index 000000000..a5ef2f36e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/chkMterm.c @@ -0,0 +1,235 @@ +/**CFile*********************************************************************** + + FileName [chkMterm.c] + + PackageName [ntr] + + Synopsis [Functions to check that the minterm counts have not + changed.] + + Description [Functions to check that the minterm counts have not + changed during reordering.

                  + Internal procedures included in this module: +

                    +
                  • check_minterms() +
                  + Static procedures included in this module: +
                    +
                  • stFree() +
                  ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: chkMterm.c,v 1.9 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static enum st_retval stFree (char *key, char *value, char *arg); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Check that minterm counts have not changed.] + + Description [Counts the minterms in the global functions of the + primary outputs of the network passed as argument. + When it is calld with the second argument set to NULL, it allocates + a symbol table and stores, for each output, the minterm count. If + an output does not have a BDD, it stores a NULL pointer for it. + If it is called with a non-null second argument, it assumes that + the symbol table contains the minterm counts measured previously + and it compares the new counts to the old ones. Finally, it frees + the symbol table. + check_minterms is designed so that it can be called twice: once before + reordering, and once after reordering. + Returns a pointer to the symbol table on the first invocation and NULL + on the second invocation.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +st_table * +checkMinterms( + BnetNetwork * net, + DdManager * dd, + st_table * previous) +{ + BnetNode *po; + int numPi; + char *name; + double *count, newcount, *oldcount; + int flag,err,i; + + numPi = net->ninputs; + + if (previous == NULL) { + previous = st_init_table(strcmp,st_strhash); + if (previous == NULL) { + (void) printf("checkMinterms out-of-memory\n"); + return(NULL); + } + for (i = 0; i < net->noutputs; i++) { + if (!st_lookup(net->hash,net->outputs[i],&po)) { + exit(2); + } + name = net->outputs[i]; + if (po->dd != NULL) { + count = ALLOC(double,1); + *count = Cudd_CountMinterm(dd,po->dd,numPi); + err = st_insert(previous, name, (char *) count); + } else { + err = st_insert(previous, name, NULL); + } + if (err) { + (void) printf("Duplicate input name (%s)\n",name); + return(NULL); + } + } + return(previous); + } else { + flag = 0; + if (st_count(previous) != net->noutputs) { + (void) printf("Number of outputs has changed from %d to %d\n", + st_count(previous), net->noutputs); + flag = 1; + } + for (i = 0; i < net->noutputs; i++) { + if (!st_lookup(net->hash,net->outputs[i],&po)) { + exit(2); + } + name = net->outputs[i]; + if (st_lookup(previous,name,&oldcount)) { + if (po->dd != NULL) { + newcount = Cudd_CountMinterm(dd,po->dd,numPi); + if (newcount != *oldcount) { + (void) printf("Number of minterms of %s has changed from %g to %g\n",name,*oldcount,newcount); + flag = 1; + } + } else { + if (oldcount != NULL) { + (void) printf("Output %s lost its BDD!\n",name); + flag = 1; + } + } + } else { + (void) printf("Output %s is new!\n",name); + flag = 1; + } + } + /*st_foreach(previous,(enum st_retval)stFree,NULL);*/ + st_foreach(previous,(ST_PFSR)stFree,NULL); + st_free_table(previous); + if (flag) { + return((st_table *) 1); + } else { + return(NULL); + } + } + +} /* end of checkMinterms */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Frees the data of the symbol table.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +static enum st_retval +stFree( + char *key, + char *value, + char *arg) +{ + if (value != NULL) { + FREE(value); + } + return(ST_CONTINUE); + +} /* end of stFree */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllAbs.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllAbs.html new file mode 100644 index 000000000..22ddf6667 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllAbs.html @@ -0,0 +1,45 @@ + +bnet package abstract (Internal) + + +

                  bnet package abstract (Internal)

                  +

                  +
                  + + + +
                  +
                  Bnet_BuildNodeBDD() +
                  Builds the BDD for the function of a node. + +
                  Bnet_DfsVariableOrder() +
                  Orders the BDD variables by DFS. + +
                  Bnet_FreeNetwork() +
                  Frees a boolean network created by Bnet_ReadNetwork. + +
                  Bnet_PrintNetwork() +
                  Prints a boolean network created by readNetwork. + +
                  Bnet_PrintOrder() +
                  Prints the order of the DD variables of a network. + +
                  Bnet_ReadNetwork() +
                  Reads boolean network from blif file. + +
                  Bnet_ReadOrder() +
                  Reads the variable order from a file. + +
                  Bnet_bddArrayDump() +
                  Writes an array of BDDs to a file in dot, blif, DDcal, factored-form, or daVinci format. + +
                  Bnet_bddDump() +
                  Writes the network BDDs to a file in dot, blif, or daVinci format. + +
                  + +
                  + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllDet.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllDet.html new file mode 100644 index 000000000..352011e23 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetAllDet.html @@ -0,0 +1,173 @@ + +The bnet package (Internal) + + +

                  The bnet package (Internal)

                  +

                  +

                  +
                  + + +
                  + + + + + +
                  + + +
                  + +
                  +int 
                  +Bnet_BuildNodeBDD(
                  +  DdManager * dd, DD manager
                  +  BnetNode * nd, node of the boolean network
                  +  st_table * hash, symbol table of the boolean network
                  +  int  params, type of DD to be built
                  +  int  nodrop retain the intermediate node DDs until the end
                  +)
                  +
                  +
                  Builds the BDD for the function of a node and stores a pointer to it in the dd field of the node itself. The reference count of the BDD is incremented. If params is BNET_LOCAL_DD, then the BDD is built in terms of the local inputs to the node; otherwise, if params is BNET_GLOBAL_DD, the BDD is built in terms of the network primary inputs. To build the global BDD of a node, the BDDs for its local inputs must exist. If that is not the case, Bnet_BuildNodeBDD recursively builds them. Likewise, to create the local BDD for a node, the local inputs must have variables assigned to them. If that is not the case, Bnet_BuildNodeBDD recursively assigns variables to nodes. Bnet_BuildNodeBDD returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects Sets the dd field of the node. +

                  + +

                  +int 
                  +Bnet_DfsVariableOrder(
                  +  DdManager * dd, 
                  +  BnetNetwork * net 
                  +)
                  +
                  +
                  Orders the BDD variables by DFS. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects Uses the visited flags of the nodes. +

                  + +

                  +void 
                  +Bnet_FreeNetwork(
                  +  BnetNetwork * net 
                  +)
                  +
                  +
                  Frees a boolean network created by Bnet_ReadNetwork. +

                  + +

                  Side Effects None +

                  + +

                  See Also Bnet_ReadNetwork + + +
                  +void 
                  +Bnet_PrintNetwork(
                  +  BnetNetwork * net boolean network
                  +)
                  +
                  +
                  Prints to the standard output a boolean network created by Bnet_ReadNetwork. Uses the blif format; this way, one can verify the equivalence of the input and the output with, say, sis. +

                  + +

                  Side Effects None +

                  + +

                  See Also Bnet_ReadNetwork + + +
                  +int 
                  +Bnet_PrintOrder(
                  +  BnetNetwork * net, 
                  +  DdManager * dd 
                  +)
                  +
                  +
                  Prints the order of the DD variables of a network. Only primary inputs and present states are printed. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +BnetNetwork * 
                  +Bnet_ReadNetwork(
                  +  FILE * fp, pointer to the blif file
                  +  int  pr verbosity level
                  +)
                  +
                  +
                  Reads a boolean network from a blif file. A very restricted subset of blif is supported. Specifically:
                  • The only directives recognized are:
                    • .model
                    • .inputs
                    • .outputs
                    • .latch
                    • .names
                    • .exdc
                    • .wire_load_slope
                    • .end
                  • Latches must have an initial values and no other parameters specified.
                  • Lines must not exceed MAXLENGTH-1 characters, and individual names must not exceed 1023 characters.
                  Caveat emptor: There may be other limitations as well. One should check the syntax of the blif file with some other tool before relying on this parser. Bnet_ReadNetwork returns a pointer to the network if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Bnet_PrintNetwork +Bnet_FreeNetwork + + +
                  +int 
                  +Bnet_ReadOrder(
                  +  DdManager * dd, 
                  +  char * ordFile, 
                  +  BnetNetwork * net, 
                  +  int  locGlob, 
                  +  int  nodrop 
                  +)
                  +
                  +
                  Reads the variable order from a file. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects The BDDs for the primary inputs and present state variables are built. +

                  + +

                  +int 
                  +Bnet_bddArrayDump(
                  +  DdManager * dd, DD manager
                  +  BnetNetwork * network, network whose BDDs should be dumped
                  +  char * dfile, file name
                  +  DdNode ** outputs, BDDs to be dumped
                  +  char ** onames, names of the BDDs to be dumped
                  +  int  noutputs, number of BDDs to be dumped
                  +  int  dumpFmt 0 -> dot
                  +)
                  +
                  +
                  Writes an array of BDDs to a file in dot, blif, DDcal, factored-form, or daVinci format. The BDDs and their names are passed as arguments. The inputs and their names are taken from the network. If "-" is passed as file name, the BDDs are dumped to the standard output. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Bnet_bddDump(
                  +  DdManager * dd, DD manager
                  +  BnetNetwork * network, network whose BDDs should be dumped
                  +  char * dfile, file name
                  +  int  dumpFmt, 0 -> dot
                  +  int  reencoded whether variables have been reencoded
                  +)
                  +
                  +
                  Writes the network BDDs to a file in dot, blif, or daVinci format. If "-" is passed as file name, the BDDs are dumped to the standard output. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + + +

                  + +
                  + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtAbs.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtAbs.html new file mode 100644 index 000000000..d8f645ce4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtAbs.html @@ -0,0 +1,45 @@ + +bnet package abstract + + +

                  bnet package abstract

                  +

                  Simple-minded package to read a blif file.

                  +
                  + + + +
                  +
                  Bnet_BuildNodeBDD() +
                  Builds the BDD for the function of a node. + +
                  Bnet_DfsVariableOrder() +
                  Orders the BDD variables by DFS. + +
                  Bnet_FreeNetwork() +
                  Frees a boolean network created by Bnet_ReadNetwork. + +
                  Bnet_PrintNetwork() +
                  Prints a boolean network created by readNetwork. + +
                  Bnet_PrintOrder() +
                  Prints the order of the DD variables of a network. + +
                  Bnet_ReadNetwork() +
                  Reads boolean network from blif file. + +
                  Bnet_ReadOrder() +
                  Reads the variable order from a file. + +
                  Bnet_bddArrayDump() +
                  Writes an array of BDDs to a file in dot, blif, DDcal, factored-form, or daVinci format. + +
                  Bnet_bddDump() +
                  Writes the network BDDs to a file in dot, blif, or daVinci format. + +
                  + +
                  + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtDet.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtDet.html new file mode 100644 index 000000000..aee62c09d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/bnetExtDet.html @@ -0,0 +1,173 @@ + +The bnet package + + +

                  The bnet package

                  +

                  Simple-minded package to read a blif file.

                  +

                  +
                  + + +
                  + + + + + +
                  + + +
                  + +
                  +int 
                  +Bnet_BuildNodeBDD(
                  +  DdManager * dd, DD manager
                  +  BnetNode * nd, node of the boolean network
                  +  st_table * hash, symbol table of the boolean network
                  +  int  params, type of DD to be built
                  +  int  nodrop retain the intermediate node DDs until the end
                  +)
                  +
                  +
                  Builds the BDD for the function of a node and stores a pointer to it in the dd field of the node itself. The reference count of the BDD is incremented. If params is BNET_LOCAL_DD, then the BDD is built in terms of the local inputs to the node; otherwise, if params is BNET_GLOBAL_DD, the BDD is built in terms of the network primary inputs. To build the global BDD of a node, the BDDs for its local inputs must exist. If that is not the case, Bnet_BuildNodeBDD recursively builds them. Likewise, to create the local BDD for a node, the local inputs must have variables assigned to them. If that is not the case, Bnet_BuildNodeBDD recursively assigns variables to nodes. Bnet_BuildNodeBDD returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects Sets the dd field of the node. +

                  + +

                  +int 
                  +Bnet_DfsVariableOrder(
                  +  DdManager * dd, 
                  +  BnetNetwork * net 
                  +)
                  +
                  +
                  Orders the BDD variables by DFS. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects Uses the visited flags of the nodes. +

                  + +

                  +void 
                  +Bnet_FreeNetwork(
                  +  BnetNetwork * net 
                  +)
                  +
                  +
                  Frees a boolean network created by Bnet_ReadNetwork. +

                  + +

                  Side Effects None +

                  + +

                  See Also Bnet_ReadNetwork + + +
                  +void 
                  +Bnet_PrintNetwork(
                  +  BnetNetwork * net boolean network
                  +)
                  +
                  +
                  Prints to the standard output a boolean network created by Bnet_ReadNetwork. Uses the blif format; this way, one can verify the equivalence of the input and the output with, say, sis. +

                  + +

                  Side Effects None +

                  + +

                  See Also Bnet_ReadNetwork + + +
                  +int 
                  +Bnet_PrintOrder(
                  +  BnetNetwork * net, 
                  +  DdManager * dd 
                  +)
                  +
                  +
                  Prints the order of the DD variables of a network. Only primary inputs and present states are printed. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +BnetNetwork * 
                  +Bnet_ReadNetwork(
                  +  FILE * fp, pointer to the blif file
                  +  int  pr verbosity level
                  +)
                  +
                  +
                  Reads a boolean network from a blif file. A very restricted subset of blif is supported. Specifically:
                  • The only directives recognized are:
                    • .model
                    • .inputs
                    • .outputs
                    • .latch
                    • .names
                    • .exdc
                    • .wire_load_slope
                    • .end
                  • Latches must have an initial values and no other parameters specified.
                  • Lines must not exceed MAXLENGTH-1 characters, and individual names must not exceed 1023 characters.
                  Caveat emptor: There may be other limitations as well. One should check the syntax of the blif file with some other tool before relying on this parser. Bnet_ReadNetwork returns a pointer to the network if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Bnet_PrintNetwork +Bnet_FreeNetwork + + +
                  +int 
                  +Bnet_ReadOrder(
                  +  DdManager * dd, 
                  +  char * ordFile, 
                  +  BnetNetwork * net, 
                  +  int  locGlob, 
                  +  int  nodrop 
                  +)
                  +
                  +
                  Reads the variable order from a file. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects The BDDs for the primary inputs and present state variables are built. +

                  + +

                  +int 
                  +Bnet_bddArrayDump(
                  +  DdManager * dd, DD manager
                  +  BnetNetwork * network, network whose BDDs should be dumped
                  +  char * dfile, file name
                  +  DdNode ** outputs, BDDs to be dumped
                  +  char ** onames, names of the BDDs to be dumped
                  +  int  noutputs, number of BDDs to be dumped
                  +  int  dumpFmt 0 -> dot
                  +)
                  +
                  +
                  Writes an array of BDDs to a file in dot, blif, DDcal, factored-form, or daVinci format. The BDDs and their names are passed as arguments. The inputs and their names are taken from the network. If "-" is passed as file name, the BDDs are dumped to the standard output. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Bnet_bddDump(
                  +  DdManager * dd, DD manager
                  +  BnetNetwork * network, network whose BDDs should be dumped
                  +  char * dfile, file name
                  +  int  dumpFmt, 0 -> dot
                  +  int  reencoded whether variables have been reencoded
                  +)
                  +
                  +
                  Writes the network BDDs to a file in dot, blif, or daVinci format. If "-" is passed as file name, the BDDs are dumped to the standard output. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + + +

                  + +
                  + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllAbs.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllAbs.html new file mode 100644 index 000000000..360a4e748 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllAbs.html @@ -0,0 +1,114 @@ + +ntr package abstract (Internal) + + +

                  ntr package abstract (Internal)

                  +

                  +
                  + + + +
                  +
                  Ntr_ClosureTrav() +
                  Transitive closure traversal procedure. + +
                  Ntr_Envelope() +
                  Poor man's outer envelope computation. + +
                  Ntr_FreeHeap() +
                  Frees a priority queue. + +
                  Ntr_HeapClone() +
                  Clones a priority queue. + +
                  Ntr_HeapCount() +
                  Returns the number of items in a priority queue. + +
                  Ntr_HeapExtractMin() +
                  Extracts the element with the minimum key from a priority queue. + +
                  Ntr_HeapInsert() +
                  Inserts an item in a priority queue. + +
                  Ntr_InitHeap() +
                  Initializes a priority queue. + +
                  Ntr_SCC() +
                  Computes the SCCs of the STG. + +
                  Ntr_ShortestPaths() +
                  Computes shortest paths in a state graph. + +
                  Ntr_TestClipping() +
                  Tests BDD clipping functions. + +
                  Ntr_TestClosestCube() +
                  Tests the Cudd_bddClosestCube function. + +
                  Ntr_TestCofactorEstimate() +
                  Tests BDD cofactor estimate functions. + +
                  Ntr_TestDecomp() +
                  Tests BDD decomposition functions. + +
                  Ntr_TestDensity() +
                  Tests BDD density-related functions. + +
                  Ntr_TestEquivAndContain() +
                  Tests BDD equivalence and containment with don't cares. + +
                  Ntr_TestHeap() +
                  Tests the heap property of a priority queue. + +
                  Ntr_TestMinimization() +
                  Tests BDD minimization functions. + +
                  Ntr_TransitiveClosure() +
                  Builds the transitive closure of a transition relation. + +
                  Ntr_Trav() +
                  Poor man's traversal procedure. + +
                  Ntr_VerifyEquivalence() +
                  Verify equivalence of combinational networks. + +
                  Ntr_buildDDs() +
                  Builds DDs for a network outputs and next state functions. + +
                  Ntr_buildTR() +
                  Builds the transition relation for a network. + +
                  Ntr_cloneTR() +
                  Makes a copy of a transition relation. + +
                  Ntr_freeTR() +
                  Frees the transition relation for a network. + +
                  Ntr_getStateCube() +
                  Reads a state cube from a file or creates a random one. + +
                  Ntr_initState() +
                  Builds the BDD of the initial state(s). + +
                  Ntr_maxflow() +
                  Maximum 0-1 flow between source and sink states. + +
                  Ntr_maximum01Flow() +
                  + +
                  Ntr_testISOP() +
                  Builds ZDD covers. + +
                  Ntr_testZDD() +
                  Tests ZDDs. + +
                  STRING_EQUAL() +
                  Returns 1 if the two arguments are identical strings. + +
                  + +
                  + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllDet.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllDet.html new file mode 100644 index 000000000..5daa930d8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrAllDet.html @@ -0,0 +1,513 @@ + +The ntr package (Internal) + + +

                  The ntr package (Internal)

                  +

                  +

                  +
                  + + +
                  + + + + + +
                  + + +
                  + +
                  +int 
                  +Ntr_ClosureTrav(
                  +  DdManager * dd, DD manager
                  +  BnetNetwork * net, network
                  +  NtrOptions * option options
                  +)
                  +
                  +
                  Traversal procedure. based on the transitive closure of the transition relation. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_Trav + + +
                  +int 
                  +Ntr_Envelope(
                  +  DdManager * dd, DD manager
                  +  NtrPartTR * TR, transition relation
                  +  FILE * dfp, pointer to file for DD dump
                  +  NtrOptions * option program options
                  +)
                  +
                  +
                  Poor man's outer envelope computation based on the monolithic transition relation. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +void 
                  +Ntr_FreeHeap(
                  +  NtrHeap * heap 
                  +)
                  +
                  +
                  Frees a priority queue. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_InitHeap + + +
                  +NtrHeap * 
                  +Ntr_HeapClone(
                  +  NtrHeap * source 
                  +)
                  +
                  +
                  Clones a priority queue. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_InitHeap + + +
                  +int 
                  +Ntr_HeapCount(
                  +  NtrHeap * heap 
                  +)
                  +
                  +
                  Returns the number of items in a priority queue. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_HeapExtractMin(
                  +  NtrHeap * heap, 
                  +  void ** item, 
                  +  int * key 
                  +)
                  +
                  +
                  Extracts the element with the minimum key from a priority queue. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects The minimum key and the associated item are returned as side effects. +

                  + +

                  See Also Ntr_HeapInsert + + +
                  +int 
                  +Ntr_HeapInsert(
                  +  NtrHeap * heap, 
                  +  void * item, 
                  +  int  key 
                  +)
                  +
                  +
                  Inserts an item in a priority queue. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_HeapExtractMin + + +
                  +NtrHeap * 
                  +Ntr_InitHeap(
                  +  int  size 
                  +)
                  +
                  +
                  Initializes a priority queue. Returns a pointer to the heap if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_FreeHeap + + +
                  +int 
                  +Ntr_SCC(
                  +  DdManager * dd, DD manager
                  +  BnetNetwork * net, network
                  +  NtrOptions * option options
                  +)
                  +
                  +
                  Computes the strongly connected components of the state transition graph. Only the first 10 SCCs are computed. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_Trav + + +
                  +int 
                  +Ntr_ShortestPaths(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Computes shortest paths in the state transition graph of a network. Three methods are availabe:
                  • Bellman-Ford algorithm for single-source shortest paths; the algorithm computes the distance (number of transitions) from the initial states to all states.
                  • Floyd-Warshall algorithm for all-pair shortest paths.
                  • Repeated squaring algorithm for all-pair shortest paths.
                  The function returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects ADD variables are created in the manager. +

                  + +

                  +int 
                  +Ntr_TestClipping(
                  +  DdManager * dd, 
                  +  BnetNetwork * net1, 
                  +  BnetNetwork * net2, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests BDD clipping functions. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestClosestCube(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests the Cudd_bddClosestCube function. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestCofactorEstimate(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests BDD cofactor estimate functions. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestDecomp(
                  +  DdManager * dd, 
                  +  BnetNetwork * net1, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests BDD decomposition functions. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestDensity(
                  +  DdManager * dd, 
                  +  BnetNetwork * net1, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests BDD density-related functions. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestEquivAndContain(
                  +  DdManager * dd, 
                  +  BnetNetwork * net1, 
                  +  BnetNetwork * net2, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests functions for BDD equivalence and containment with don't cares, including Cudd_EquivDC and Cudd_bddLeqUnless. This function uses as care set the first output of net2 and checkes equivalence and containment for of all the output pairs of net1. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestHeap(
                  +  NtrHeap * heap, 
                  +  int  i 
                  +)
                  +
                  +
                  Tests the heap property of a priority queue. Returns 1 if Successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestMinimization(
                  +  DdManager * dd, 
                  +  BnetNetwork * net1, 
                  +  BnetNetwork * net2, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests BDD minimization functions, including leaf-identifying compaction, squeezing, and restrict. This function uses as constraint the first output of net2 and computes positive and negative cofactors of all the outputs of net1. For each cofactor, it checks whether compaction was safe (cofactor not larger than original function) and that the expansion based on each minimization function (used as a generalized cofactor) equals the original function. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +DdNode * 
                  +Ntr_TransitiveClosure(
                  +  DdManager * dd, 
                  +  NtrPartTR * TR, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Builds the transitive closure of a transition relation. Returns a BDD if successful; NULL otherwise. Uses a simple squaring algorithm. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_Trav(
                  +  DdManager * dd, DD manager
                  +  BnetNetwork * net, network
                  +  NtrOptions * option options
                  +)
                  +
                  +
                  Poor man's traversal procedure. based on the monolithic transition relation. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_ClosureTrav + + +
                  +int 
                  +Ntr_VerifyEquivalence(
                  +  DdManager * dd, 
                  +  BnetNetwork * net1, 
                  +  BnetNetwork * net2, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Verify equivalence of combinational networks. Returns 1 if successful and if the networks are equivalent; -1 if successful, but the networks are not equivalent; 0 otherwise. The two networks are supposed to have the same names for inputs and outputs. The only exception is that the second network may miss output buffers that are present in the first network. This function tries to match both the output and the input of the buffer. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_buildDDs(
                  +  BnetNetwork * net, network for which DDs are to be built
                  +  DdManager * dd, DD manager
                  +  NtrOptions * option, option structure
                  +  BnetNetwork * net2 companion network with which inputs may be shared
                  +)
                  +
                  +
                  Builds DDs for a network outputs and next state functions. The method is really brain-dead, but it is very simple. Returns 1 in case of success; 0 otherwise. Some inputs to the network may be shared with another network whose DDs have already been built. In this case we want to share the DDs as well. +

                  + +

                  Side Effects the dd fields of the network nodes are modified. Uses the count fields of the nodes. +

                  + +

                  +NtrPartTR * 
                  +Ntr_buildTR(
                  +  DdManager * dd, manager
                  +  BnetNetwork * net, network
                  +  NtrOptions * option, options
                  +  int  image image type: monolithic ...
                  +)
                  +
                  +
                  Builds the transition relation for a network. Returns a pointer to the transition relation structure if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +NtrPartTR * 
                  +Ntr_cloneTR(
                  +  NtrPartTR * TR 
                  +)
                  +
                  +
                  Makes a copy of a transition relation. Returns a pointer to the copy if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_buildTR +Ntr_freeTR + + +
                  +void 
                  +Ntr_freeTR(
                  +  DdManager * dd, 
                  +  NtrPartTR * TR 
                  +)
                  +
                  +
                  Frees the transition relation for a network. +

                  + +

                  Side Effects None +

                  + +

                  +DdNode * 
                  +Ntr_getStateCube(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  char * filename, 
                  +  int  pr 
                  +)
                  +
                  +
                  Reads a state cube from a file or create a random one. Returns a pointer to the BDD of the sink nodes if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +DdNode * 
                  +Ntr_initState(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Builds the BDD of the initial state(s). Returns a BDD if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_maxflow(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Maximum 0-1 flow between source and sink states. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects Creates two new sets of variables. +

                  + +

                  +double 
                  +Ntr_maximum01Flow(
                  +  DdManager * bdd, manager
                  +  DdNode * sx, source node
                  +  DdNode * ty, sink node
                  +  DdNode * E, edge relation
                  +  DdNode ** F, flow relation
                  +  DdNode ** cut, cutset relation
                  +  DdNode ** x, array of row variables
                  +  DdNode ** y, array of column variables
                  +  DdNode ** z, arrays of auxiliary variables
                  +  int  n, number of variables in each array
                  +  int  pr verbosity level
                  +)
                  +
                  +
                  This function implements Dinits's algorithm for (0-1) max flow, using BDDs and a symbolic technique to trace multiple edge-disjoint augmenting paths to complete a phase. The outer forever loop is over phases, and the inner forever loop is to propagate a (not yet) maximal flow of edge-disjoint augmenting paths from one layer to the previous. The subprocedure call implements a least fixed point iteration to compute a (not yet) maximal flow update between layers. At the end of each phase (except the last one) the flow is actually pushed from the source to the sink. Data items:
                  • sx(ty) BDD representations of s(t).
                  • x(y) The variables encoding the from(to)-node u(v) of an edge (u,v) in the given digraph.
                  • z Another set of variables.
                  • E(x,y) The edge relation.
                  • F(x,y) BDD representation of the current flow, initialized to 0 for each arc, and updated by +1, -1, or 0 at the end of each phase.
                  • Ms Mt The maximum flow, that is, the cardinality of a minimum cut, measured at the source and at the sink, respectively. The two values should be identical.
                  • reached The set of nodes already visited in the BFS of the digraph.
                  • fos fanout of the source node s.
                  • fit fanin of the sink node t.
                  +

                  + +

                  Side Effects The flow realtion F and the cutset relation cut are returned as side effects. +

                  + +

                  +int 
                  +Ntr_testISOP(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Builds ZDD covers. +

                  + +

                  Side Effects Creates ZDD variables in the manager. +

                  + +

                  +int 
                  +Ntr_testZDD(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests ZDDs. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects Creates ZDD variables in the manager. +

                  + +

                  + 
                  +STRING_EQUAL(
                  +   s1, 
                  +   s2 
                  +)
                  +
                  +
                  Returns 1 if the two arguments are identical strings. +

                  + +

                  Side Effects none +

                  + + +

                  + +
                  + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtAbs.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtAbs.html new file mode 100644 index 000000000..485d34676 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtAbs.html @@ -0,0 +1,111 @@ + +ntr package abstract + + +

                  ntr package abstract

                  +

                  Simple-minded package to do traversal.

                  +
                  + + + +
                  +
                  Ntr_ClosureTrav() +
                  Transitive closure traversal procedure. + +
                  Ntr_Envelope() +
                  Poor man's outer envelope computation. + +
                  Ntr_FreeHeap() +
                  Frees a priority queue. + +
                  Ntr_HeapClone() +
                  Clones a priority queue. + +
                  Ntr_HeapCount() +
                  Returns the number of items in a priority queue. + +
                  Ntr_HeapExtractMin() +
                  Extracts the element with the minimum key from a priority queue. + +
                  Ntr_HeapInsert() +
                  Inserts an item in a priority queue. + +
                  Ntr_InitHeap() +
                  Initializes a priority queue. + +
                  Ntr_SCC() +
                  Computes the SCCs of the STG. + +
                  Ntr_ShortestPaths() +
                  Computes shortest paths in a state graph. + +
                  Ntr_TestClipping() +
                  Tests BDD clipping functions. + +
                  Ntr_TestClosestCube() +
                  Tests the Cudd_bddClosestCube function. + +
                  Ntr_TestCofactorEstimate() +
                  Tests BDD cofactor estimate functions. + +
                  Ntr_TestDecomp() +
                  Tests BDD decomposition functions. + +
                  Ntr_TestDensity() +
                  Tests BDD density-related functions. + +
                  Ntr_TestEquivAndContain() +
                  Tests BDD equivalence and containment with don't cares. + +
                  Ntr_TestHeap() +
                  Tests the heap property of a priority queue. + +
                  Ntr_TestMinimization() +
                  Tests BDD minimization functions. + +
                  Ntr_TransitiveClosure() +
                  Builds the transitive closure of a transition relation. + +
                  Ntr_Trav() +
                  Poor man's traversal procedure. + +
                  Ntr_VerifyEquivalence() +
                  Verify equivalence of combinational networks. + +
                  Ntr_buildDDs() +
                  Builds DDs for a network outputs and next state functions. + +
                  Ntr_buildTR() +
                  Builds the transition relation for a network. + +
                  Ntr_cloneTR() +
                  Makes a copy of a transition relation. + +
                  Ntr_freeTR() +
                  Frees the transition relation for a network. + +
                  Ntr_getStateCube() +
                  Reads a state cube from a file or creates a random one. + +
                  Ntr_initState() +
                  Builds the BDD of the initial state(s). + +
                  Ntr_maxflow() +
                  Maximum 0-1 flow between source and sink states. + +
                  Ntr_maximum01Flow() +
                  + +
                  Ntr_testISOP() +
                  Builds ZDD covers. + +
                  Ntr_testZDD() +
                  Tests ZDDs. + +
                  + +
                  + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtDet.html b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtDet.html new file mode 100644 index 000000000..ae06139ec --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/doc/ntrExtDet.html @@ -0,0 +1,500 @@ + +The ntr package + + +

                  The ntr package

                  +

                  Simple-minded package to do traversal.

                  +

                  +
                  + + +
                  + + + + + +
                  + + +
                  + +
                  +int 
                  +Ntr_ClosureTrav(
                  +  DdManager * dd, DD manager
                  +  BnetNetwork * net, network
                  +  NtrOptions * option options
                  +)
                  +
                  +
                  Traversal procedure. based on the transitive closure of the transition relation. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_Trav + + +
                  +int 
                  +Ntr_Envelope(
                  +  DdManager * dd, DD manager
                  +  NtrPartTR * TR, transition relation
                  +  FILE * dfp, pointer to file for DD dump
                  +  NtrOptions * option program options
                  +)
                  +
                  +
                  Poor man's outer envelope computation based on the monolithic transition relation. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +void 
                  +Ntr_FreeHeap(
                  +  NtrHeap * heap 
                  +)
                  +
                  +
                  Frees a priority queue. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_InitHeap + + +
                  +NtrHeap * 
                  +Ntr_HeapClone(
                  +  NtrHeap * source 
                  +)
                  +
                  +
                  Clones a priority queue. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_InitHeap + + +
                  +int 
                  +Ntr_HeapCount(
                  +  NtrHeap * heap 
                  +)
                  +
                  +
                  Returns the number of items in a priority queue. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_HeapExtractMin(
                  +  NtrHeap * heap, 
                  +  void ** item, 
                  +  int * key 
                  +)
                  +
                  +
                  Extracts the element with the minimum key from a priority queue. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects The minimum key and the associated item are returned as side effects. +

                  + +

                  See Also Ntr_HeapInsert + + +
                  +int 
                  +Ntr_HeapInsert(
                  +  NtrHeap * heap, 
                  +  void * item, 
                  +  int  key 
                  +)
                  +
                  +
                  Inserts an item in a priority queue. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_HeapExtractMin + + +
                  +NtrHeap * 
                  +Ntr_InitHeap(
                  +  int  size 
                  +)
                  +
                  +
                  Initializes a priority queue. Returns a pointer to the heap if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_FreeHeap + + +
                  +int 
                  +Ntr_SCC(
                  +  DdManager * dd, DD manager
                  +  BnetNetwork * net, network
                  +  NtrOptions * option options
                  +)
                  +
                  +
                  Computes the strongly connected components of the state transition graph. Only the first 10 SCCs are computed. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_Trav + + +
                  +int 
                  +Ntr_ShortestPaths(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Computes shortest paths in the state transition graph of a network. Three methods are availabe:
                  • Bellman-Ford algorithm for single-source shortest paths; the algorithm computes the distance (number of transitions) from the initial states to all states.
                  • Floyd-Warshall algorithm for all-pair shortest paths.
                  • Repeated squaring algorithm for all-pair shortest paths.
                  The function returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects ADD variables are created in the manager. +

                  + +

                  +int 
                  +Ntr_TestClipping(
                  +  DdManager * dd, 
                  +  BnetNetwork * net1, 
                  +  BnetNetwork * net2, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests BDD clipping functions. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestClosestCube(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests the Cudd_bddClosestCube function. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestCofactorEstimate(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests BDD cofactor estimate functions. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestDecomp(
                  +  DdManager * dd, 
                  +  BnetNetwork * net1, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests BDD decomposition functions. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestDensity(
                  +  DdManager * dd, 
                  +  BnetNetwork * net1, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests BDD density-related functions. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestEquivAndContain(
                  +  DdManager * dd, 
                  +  BnetNetwork * net1, 
                  +  BnetNetwork * net2, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests functions for BDD equivalence and containment with don't cares, including Cudd_EquivDC and Cudd_bddLeqUnless. This function uses as care set the first output of net2 and checkes equivalence and containment for of all the output pairs of net1. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestHeap(
                  +  NtrHeap * heap, 
                  +  int  i 
                  +)
                  +
                  +
                  Tests the heap property of a priority queue. Returns 1 if Successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_TestMinimization(
                  +  DdManager * dd, 
                  +  BnetNetwork * net1, 
                  +  BnetNetwork * net2, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests BDD minimization functions, including leaf-identifying compaction, squeezing, and restrict. This function uses as constraint the first output of net2 and computes positive and negative cofactors of all the outputs of net1. For each cofactor, it checks whether compaction was safe (cofactor not larger than original function) and that the expansion based on each minimization function (used as a generalized cofactor) equals the original function. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +DdNode * 
                  +Ntr_TransitiveClosure(
                  +  DdManager * dd, 
                  +  NtrPartTR * TR, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Builds the transitive closure of a transition relation. Returns a BDD if successful; NULL otherwise. Uses a simple squaring algorithm. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_Trav(
                  +  DdManager * dd, DD manager
                  +  BnetNetwork * net, network
                  +  NtrOptions * option options
                  +)
                  +
                  +
                  Poor man's traversal procedure. based on the monolithic transition relation. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_ClosureTrav + + +
                  +int 
                  +Ntr_VerifyEquivalence(
                  +  DdManager * dd, 
                  +  BnetNetwork * net1, 
                  +  BnetNetwork * net2, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Verify equivalence of combinational networks. Returns 1 if successful and if the networks are equivalent; -1 if successful, but the networks are not equivalent; 0 otherwise. The two networks are supposed to have the same names for inputs and outputs. The only exception is that the second network may miss output buffers that are present in the first network. This function tries to match both the output and the input of the buffer. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_buildDDs(
                  +  BnetNetwork * net, network for which DDs are to be built
                  +  DdManager * dd, DD manager
                  +  NtrOptions * option, option structure
                  +  BnetNetwork * net2 companion network with which inputs may be shared
                  +)
                  +
                  +
                  Builds DDs for a network outputs and next state functions. The method is really brain-dead, but it is very simple. Returns 1 in case of success; 0 otherwise. Some inputs to the network may be shared with another network whose DDs have already been built. In this case we want to share the DDs as well. +

                  + +

                  Side Effects the dd fields of the network nodes are modified. Uses the count fields of the nodes. +

                  + +

                  +NtrPartTR * 
                  +Ntr_buildTR(
                  +  DdManager * dd, manager
                  +  BnetNetwork * net, network
                  +  NtrOptions * option, options
                  +  int  image image type: monolithic ...
                  +)
                  +
                  +
                  Builds the transition relation for a network. Returns a pointer to the transition relation structure if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +NtrPartTR * 
                  +Ntr_cloneTR(
                  +  NtrPartTR * TR 
                  +)
                  +
                  +
                  Makes a copy of a transition relation. Returns a pointer to the copy if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also Ntr_buildTR +Ntr_freeTR + + +
                  +void 
                  +Ntr_freeTR(
                  +  DdManager * dd, 
                  +  NtrPartTR * TR 
                  +)
                  +
                  +
                  Frees the transition relation for a network. +

                  + +

                  Side Effects None +

                  + +

                  +DdNode * 
                  +Ntr_getStateCube(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  char * filename, 
                  +  int  pr 
                  +)
                  +
                  +
                  Reads a state cube from a file or create a random one. Returns a pointer to the BDD of the sink nodes if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +DdNode * 
                  +Ntr_initState(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Builds the BDD of the initial state(s). Returns a BDD if successful; NULL otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +Ntr_maxflow(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Maximum 0-1 flow between source and sink states. Returns 1 in case of success; 0 otherwise. +

                  + +

                  Side Effects Creates two new sets of variables. +

                  + +

                  +double 
                  +Ntr_maximum01Flow(
                  +  DdManager * bdd, manager
                  +  DdNode * sx, source node
                  +  DdNode * ty, sink node
                  +  DdNode * E, edge relation
                  +  DdNode ** F, flow relation
                  +  DdNode ** cut, cutset relation
                  +  DdNode ** x, array of row variables
                  +  DdNode ** y, array of column variables
                  +  DdNode ** z, arrays of auxiliary variables
                  +  int  n, number of variables in each array
                  +  int  pr verbosity level
                  +)
                  +
                  +
                  This function implements Dinits's algorithm for (0-1) max flow, using BDDs and a symbolic technique to trace multiple edge-disjoint augmenting paths to complete a phase. The outer forever loop is over phases, and the inner forever loop is to propagate a (not yet) maximal flow of edge-disjoint augmenting paths from one layer to the previous. The subprocedure call implements a least fixed point iteration to compute a (not yet) maximal flow update between layers. At the end of each phase (except the last one) the flow is actually pushed from the source to the sink. Data items:
                  • sx(ty) BDD representations of s(t).
                  • x(y) The variables encoding the from(to)-node u(v) of an edge (u,v) in the given digraph.
                  • z Another set of variables.
                  • E(x,y) The edge relation.
                  • F(x,y) BDD representation of the current flow, initialized to 0 for each arc, and updated by +1, -1, or 0 at the end of each phase.
                  • Ms Mt The maximum flow, that is, the cardinality of a minimum cut, measured at the source and at the sink, respectively. The two values should be identical.
                  • reached The set of nodes already visited in the BFS of the digraph.
                  • fos fanout of the source node s.
                  • fit fanin of the sink node t.
                  +

                  + +

                  Side Effects The flow realtion F and the cutset relation cut are returned as side effects. +

                  + +

                  +int 
                  +Ntr_testISOP(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Builds ZDD covers. +

                  + +

                  Side Effects Creates ZDD variables in the manager. +

                  + +

                  +int 
                  +Ntr_testZDD(
                  +  DdManager * dd, 
                  +  BnetNetwork * net, 
                  +  NtrOptions * option 
                  +)
                  +
                  +
                  Tests ZDDs. Returns 1 if successful; 0 otherwise. +

                  + +

                  Side Effects Creates ZDD variables in the manager. +

                  + + +

                  + +
                  + +Generated automatically by extdoc on 1010215 + + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/main.c b/resources/3rdparty/cudd-2.5.0/nanotrav/main.c new file mode 100644 index 000000000..f0a37d660 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/main.c @@ -0,0 +1,1394 @@ +/**CFile*********************************************************************** + + FileName [main.c] + + PackageName [ntr] + + Synopsis [Main program for the nanotrav program.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define NTR_VERSION\ + "Nanotrav Version #0.12, Release date 2003/12/31" + +#define BUFLENGTH 8192 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: main.c,v 1.41 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +static char buffer[BUFLENGTH]; +#ifdef DD_DEBUG +extern st_table *checkMinterms (BnetNetwork *net, DdManager *dd, st_table *previous); +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static NtrOptions * mainInit (); +static void ntrReadOptions (int argc, char **argv, NtrOptions *option); +static void ntrReadOptionsFile (char *name, char ***argv, int *argc); +static char* readLine (FILE *fp); +static FILE * open_file (char *filename, const char *mode); +static int reorder (BnetNetwork *net, DdManager *dd, NtrOptions *option); +static void freeOption (NtrOptions *option); +static DdManager * startCudd (NtrOptions *option, int nvars); +static int ntrReadTree (DdManager *dd, char *treefile, int nvars); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Main program for ntr.] + + Description [Main program for ntr. Performs initialization. Reads command + line options and network(s). Builds BDDs with reordering, and optionally + does reachability analysis. Prints stats.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +main( + int argc, + char ** argv) +{ + NtrOptions *option; /* options */ + FILE *fp1; /* first network file pointer */ + BnetNetwork *net1 = NULL; /* first network */ + FILE *fp2; /* second network file pointer */ + BnetNetwork *net2 = NULL; /* second network */ + DdManager *dd; /* pointer to DD manager */ + int exitval; /* return value of Cudd_CheckZeroRef */ + int ok; /* overall return value from main() */ + int result; /* stores the return value of functions */ + BnetNode *node; /* auxiliary pointer to network node */ + int i; /* loop index */ + int j; /* loop index */ + double *signatures; /* array of signatures */ + int pr; /* verbosity level */ + int reencoded; /* linear transformations attempted */ + + /* Initialize. */ + option = mainInit(); + ntrReadOptions(argc,argv,option); + pr = option->verb; + reencoded = option->reordering == CUDD_REORDER_LINEAR || + option->reordering == CUDD_REORDER_LINEAR_CONVERGE || + option->autoMethod == CUDD_REORDER_LINEAR || + option->autoMethod == CUDD_REORDER_LINEAR_CONVERGE; + /* Currently traversal requires global BDDs. Override whatever + ** was specified for locGlob. + */ + if (option->traverse == TRUE || option->envelope == TRUE || + option->scc == TRUE) { + option->locGlob = BNET_GLOBAL_DD; + } + + /* Read the first network... */ + fp1 = open_file(option->file1, "r"); + net1 = Bnet_ReadNetwork(fp1,pr); + (void) fclose(fp1); + if (net1 == NULL) { + (void) fprintf(stderr,"Syntax error in %s.\n",option->file1); + exit(2); + } + /* ... and optionally echo it to the standard output. */ + if (pr > 2) { + Bnet_PrintNetwork(net1); + } + + /* Read the second network... */ + if (option->verify == TRUE || option->second == TRUE || + option->clip > 0.0 || option->dontcares) { + fp2 = open_file(option->file2, "r"); + net2 = Bnet_ReadNetwork(fp2,pr); + (void) fclose(fp2); + if (net2 == NULL) { + (void) fprintf(stderr,"Syntax error in %s.\n",option->file2); + exit(2); + } + /* ... and optionally echo it to the standard output. */ + if (pr > 2) { + Bnet_PrintNetwork(net2); + } + } + + /* Initialize manager. We start with 0 variables, because + ** Ntr_buildDDs will create new variables rather than using + ** whatever already exists. + */ + dd = startCudd(option,net1->ninputs); + if (dd == NULL) { exit(2); } + + /* Build the BDDs for the nodes of the first network. */ + result = Ntr_buildDDs(net1,dd,option,NULL); + if (result == 0) { exit(2); } + + /* Build the BDDs for the nodes of the second network if requested. */ + if (option->verify == TRUE || option->second == TRUE || + option->clip > 0.0 || option->dontcares == TRUE) { + char *nodesave = option->node; + option->node = NULL; + result = Ntr_buildDDs(net2,dd,option,net1); + option->node = nodesave; + if (result == 0) { exit(2); } + } + + if (option->noBuild == TRUE) { + Bnet_FreeNetwork(net1); + if (option->verify == TRUE || option->second == TRUE || + option->clip > 0.0) { + Bnet_FreeNetwork(net2); + } + freeOption(option); + exit(0); + } + if (option->locGlob != BNET_LOCAL_DD) { + /* Print the order before the final reordering. */ + (void) printf("Order before final reordering\n"); + result = Bnet_PrintOrder(net1,dd); + if (result == 0) exit(2); + } + + /* Perform final reordering */ + if (option->zddtest == FALSE) { + result = reorder(net1,dd,option); + if (result == 0) exit(2); + + /* Print final order. */ + if ((option->reordering != CUDD_REORDER_NONE || option->gaOnOff) && + option->locGlob != BNET_LOCAL_DD) { + (void) printf("New order\n"); + result = Bnet_PrintOrder(net1,dd); + if (result == 0) exit(2); + } + + /* Print the re-encoded inputs. */ + if (pr >= 1 && reencoded == 1) { + for (i = 0; i < net1->npis; i++) { + if (!st_lookup(net1->hash,net1->inputs[i],&node)) { + exit(2); + } + (void) fprintf(stdout,"%s:",node->name); + Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr); + } + for (i = 0; i < net1->nlatches; i++) { + if (!st_lookup(net1->hash,net1->latches[i][1],&node)) { + exit(2); + } + (void) fprintf(stdout,"%s:",node->name); + Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr); + } + if (pr >= 3) { + result = Cudd_PrintLinear(dd); + if (result == 0) exit(2); + } + } + } + + /* Verify (combinational) equivalence. */ + if (option->verify == TRUE) { + result = Ntr_VerifyEquivalence(dd,net1,net2,option); + if (result == 0) { + (void) printf("Verification abnormally terminated\n"); + exit(2); + } else if (result == -1) { + (void) printf("Combinational verification failed\n"); + } else { + (void) printf("Verification succeeded\n"); + } + } + + /* Traverse if requested and if the circuit is sequential. */ + result = Ntr_Trav(dd,net1,option); + if (result == 0) exit(2); + + /* Traverse with trasitive closure. */ + result = Ntr_ClosureTrav(dd,net1,option); + if (result == 0) exit(2); + + /* Compute outer envelope if requested and if the circuit is sequential. */ + if (option->envelope == TRUE && net1->nlatches > 0) { + NtrPartTR *T; + T = Ntr_buildTR(dd,net1,option,option->image); + result = Ntr_Envelope(dd,T,NULL,option); + Ntr_freeTR(dd,T); + } + + /* Compute SCCs if requested and if the circuit is sequential. */ + result = Ntr_SCC(dd,net1,option); + if (result == 0) exit(2); + + /* Test Constrain Decomposition. */ + if (option->partition == TRUE && net1->nlatches > 0) { + NtrPartTR *T; + DdNode *product; + DdNode **decomp; + int sharingSize; + T = Ntr_buildTR(dd,net1,option,NTR_IMAGE_MONO); + decomp = Cudd_bddConstrainDecomp(dd,T->part[0]); + if (decomp == NULL) exit(2); + sharingSize = Cudd_SharingSize(decomp, Cudd_ReadSize(dd)); + (void) fprintf(stdout, "Decomposition Size: %d components %d nodes\n", + Cudd_ReadSize(dd), sharingSize); + product = Cudd_ReadOne(dd); + Cudd_Ref(product); + for (i = 0; i < Cudd_ReadSize(dd); i++) { + DdNode *intermediate = Cudd_bddAnd(dd, product, decomp[i]); + if (intermediate == NULL) { + exit(2); + } + Cudd_Ref(intermediate); + Cudd_IterDerefBdd(dd, product); + product = intermediate; + } + if (product != T->part[0]) + exit(2); + Cudd_IterDerefBdd(dd, product); + for (i = 0; i < Cudd_ReadSize(dd); i++) { + Cudd_IterDerefBdd(dd, decomp[i]); + } + FREE(decomp); + Ntr_freeTR(dd,T); + } + + /* Test char-to-vect conversion. */ + result = Ntr_TestCharToVect(dd,net1,option); + if (result == 0) exit(2); + + /* Test extraction of two-literal clauses. */ + result = Ntr_TestTwoLiteralClauses(dd,net1,option); + if (result == 0) exit(2); + + /* Test BDD minimization functions. */ + result = Ntr_TestMinimization(dd,net1,net2,option); + if (result == 0) exit(2); + + /* Test density-related functions. */ + result = Ntr_TestDensity(dd,net1,option); + if (result == 0) exit(2); + + /* Test decomposition functions. */ + result = Ntr_TestDecomp(dd,net1,option); + if (result == 0) exit(2); + + /* Test cofactor estimation functions. */ + result = Ntr_TestCofactorEstimate(dd,net1,option); + if (result == 0) exit(2); + + /* Test BDD clipping functions. */ + result = Ntr_TestClipping(dd,net1,net2,option); + if (result == 0) exit(2); + + /* Test BDD equivalence and containment under DC functions. */ + result = Ntr_TestEquivAndContain(dd,net1,net2,option); + if (result == 0) exit(2); + + /* Test BDD Cudd_bddClosestCube. */ + result = Ntr_TestClosestCube(dd,net1,option); + if (result == 0) exit(2); + + /* Test ZDDs if requested. */ + if (option->stateOnly == FALSE && option->zddtest == TRUE) { + result = Ntr_testZDD(dd,net1,option); + if (result == 0) + (void) fprintf(stdout,"ZDD test failed.\n"); + result = Ntr_testISOP(dd,net1,option); + if (result == 0) + (void) fprintf(stdout,"ISOP test failed.\n"); + } + + /* Compute maximum flow if requested and if the circuit is sequential. */ + if (option->maxflow == TRUE && net1->nlatches > 0) { + result = Ntr_maxflow(dd,net1,option); + if (result == 0) + (void) fprintf(stdout,"Maxflow computation failed.\n"); + } + + /* Compute shortest paths if requested and if the circuit is sequential. */ + if (option->shortPath != NTR_SHORT_NONE && net1->nlatches > 0) { + result = Ntr_ShortestPaths(dd,net1,option); + if (result == 0) + (void) fprintf(stdout,"Shortest paths computation failed.\n"); + } + + /* Compute output signatures if so requested. */ + if (option->signatures) { + (void) printf("Positive cofactor measures\n"); + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + exit(2); + } + signatures = Cudd_CofMinterm(dd, node->dd); + if (signatures) { + (void) printf("%s:\n", node->name); + for (j = 0; j < Cudd_ReadSize(dd); j++) { + if((j%5 == 0)&&i) (void) printf("\n"); + (void) printf("%5d: %-#8.4g ", j, signatures[j]); + } + (void) printf("\n"); + FREE(signatures); + } else { + (void) printf("Signature computation failed.\n"); + } + } + } + + /* Dump BDDs if so requested. */ + if (option->bdddump && option->second == FALSE && + option->density == FALSE && option->decomp == FALSE && + option->cofest == FALSE && option->clip < 0.0 && + option->scc == FALSE) { + (void) printf("Dumping BDDs to %s\n", option->dumpfile); + if (option->node != NULL) { + if (!st_lookup(net1->hash,option->node,&node)) { + exit(2); + } + result = Bnet_bddArrayDump(dd,net1,option->dumpfile,&(node->dd), + &(node->name),1,option->dumpFmt); + } else { + result = Bnet_bddDump(dd, net1, option->dumpfile, + option->dumpFmt, reencoded); + } + if (result != 1) { + (void) printf("BDD dump failed.\n"); + } + } + + /* Print stats and clean up. */ + if (pr >= 0) { + result = Cudd_PrintInfo(dd,stdout); + if (result != 1) { + (void) printf("Cudd_PrintInfo failed.\n"); + } + } + +#if defined(DD_DEBUG) && !defined(DD_NO_DEATH_ROW) + (void) fprintf(dd->err,"%d empty slots in death row\n", + cuddTimesInDeathRow(dd,NULL)); +#endif + (void) printf("Final size: %ld\n", Cudd_ReadNodeCount(dd)); + + /* Dispose of node BDDs. */ + node = net1->nodes; + while (node != NULL) { + if (node->dd != NULL && + node->type != BNET_INPUT_NODE && + node->type != BNET_PRESENT_STATE_NODE) { + Cudd_IterDerefBdd(dd,node->dd); + } + node = node->next; + } + /* Dispose of network. */ + Bnet_FreeNetwork(net1); + /* Do the same cleanup for the second network if it was created. */ + if (option->verify == TRUE || option->second == TRUE || + option->clip > 0.0 || option->dontcares == TRUE) { + node = net2->nodes; + while (node != NULL) { + if (node->dd != NULL && + node->type != BNET_INPUT_NODE && + node->type != BNET_PRESENT_STATE_NODE) { + Cudd_IterDerefBdd(dd,node->dd); + } + node = node->next; + } + Bnet_FreeNetwork(net2); + } + + /* Check reference counts: At this point we should have dereferenced + ** everything we had, except in the case of re-encoding. + */ + exitval = Cudd_CheckZeroRef(dd); + ok = exitval != 0; /* ok == 0 means O.K. */ + if (exitval != 0) { + (void) fflush(stdout); + (void) fprintf(stderr, + "%d non-zero DD reference counts after dereferencing\n", exitval); + } + +#ifdef DD_DEBUG + Cudd_CheckKeys(dd); +#endif + + Cudd_Quit(dd); + + if (pr >= 0) (void) printf("total time = %s\n", + util_print_time(util_cpu_time() - option->initialTime)); + freeOption(option); + if (pr >= 0) util_print_cpu_stats(stdout); + +#ifdef MNEMOSYNE + mnem_writestats(); +#endif + + exit(ok); + /* NOTREACHED */ + +} /* end of main */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Allocates the option structure and initializes it.] + + Description [] + + SideEffects [none] + + SeeAlso [ntrReadOptions] + +******************************************************************************/ +static NtrOptions * +mainInit( + ) +{ + NtrOptions *option; + + /* Initialize option structure. */ + option = ALLOC(NtrOptions,1); + option->initialTime = util_cpu_time(); + option->verify = FALSE; + option->second = FALSE; + option->file1 = NULL; + option->file2 = NULL; + option->traverse = FALSE; + option->depend = FALSE; + option->image = NTR_IMAGE_MONO; + option->imageClip = 1.0; + option->approx = NTR_UNDER_APPROX; + option->threshold = -1; + option->from = NTR_FROM_NEW; + option->groupnsps = NTR_GROUP_NONE; + option->closure = FALSE; + option->closureClip = 1.0; + option->envelope = FALSE; + option->scc = FALSE; + option->maxflow = FALSE; + option->shortPath = NTR_SHORT_NONE; + option->selectiveTrace = FALSE; + option->zddtest = FALSE; + option->printcover = FALSE; + option->sinkfile = NULL; + option->partition = FALSE; + option->char2vect = FALSE; + option->density = FALSE; + option->quality = 1.0; + option->decomp = FALSE; + option->cofest = FALSE; + option->clip = -1.0; + option->dontcares = FALSE; + option->closestCube = FALSE; + option->clauses = FALSE; + option->noBuild = FALSE; + option->stateOnly = FALSE; + option->node = NULL; + option->locGlob = BNET_GLOBAL_DD; + option->progress = FALSE; + option->cacheSize = 32768; + option->maxMemory = 0; /* set automatically */ + option->maxMemHard = 0; /* don't set */ + option->maxLive = ~0; /* very large number */ + option->slots = CUDD_UNIQUE_SLOTS; + option->ordering = PI_PS_FROM_FILE; + option->orderPiPs = NULL; + option->reordering = CUDD_REORDER_NONE; + option->autoMethod = CUDD_REORDER_SIFT; + option->autoDyn = 0; + option->treefile = NULL; + option->firstReorder = DD_FIRST_REORDER; + option->countDead = FALSE; + option->maxGrowth = 20; + option->groupcheck = CUDD_GROUP_CHECK7; + option->arcviolation = 10; + option->symmviolation = 10; + option->recomb = DD_DEFAULT_RECOMB; + option->nodrop = TRUE; + option->signatures = FALSE; + option->verb = 0; + option->gaOnOff = 0; + option->populationSize = 0; /* use default */ + option->numberXovers = 0; /* use default */ + option->bdddump = FALSE; + option->dumpFmt = 0; /* dot */ + option->dumpfile = NULL; + option->store = -1; /* do not store */ + option->storefile = NULL; + option->load = FALSE; + option->loadfile = NULL; + + return(option); + +} /* end of mainInit */ + + +/**Function******************************************************************** + + Synopsis [Reads the command line options.] + + Description [Reads the command line options. Scans the command line + one argument at a time and performs a switch on each arguement it + hits. Some arguemnts also read in the following arg from the list + (i.e., -f also gets the filename which should folow.) + Gives a usage message and exits if any unrecognized args are found.] + + SideEffects [May initialize the random number generator.] + + SeeAlso [mainInit ntrReadOptionsFile] + +******************************************************************************/ +static void +ntrReadOptions( + int argc, + char ** argv, + NtrOptions * option) +{ + int i = 0; + + if (argc < 2) goto usage; + + if (STRING_EQUAL(argv[1],"-f")) { + ntrReadOptionsFile(argv[2],&argv,&argc); + } + + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-' ) { + if (option->file1 == NULL) { + option->file1 = util_strsav(argv[i]); + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-second")) { + i++; + option->file2 = util_strsav(argv[i]); + option->second = TRUE; + } else if (STRING_EQUAL(argv[i],"-verify")) { + i++; + option->file2 = util_strsav(argv[i]); + option->verify = TRUE; + } else if (STRING_EQUAL(argv[i],"-trav")) { + option->traverse = TRUE; + } else if (STRING_EQUAL(argv[i],"-depend")) { + option->traverse = TRUE; + option->depend = TRUE; + } else if (STRING_EQUAL(argv[i],"-image")) { + i++; + if (STRING_EQUAL(argv[i],"part")) { + option->image = NTR_IMAGE_PART; + } else if (STRING_EQUAL(argv[i],"clip")) { + option->image = NTR_IMAGE_CLIP; + } else if (STRING_EQUAL(argv[i],"depend")) { + option->image = NTR_IMAGE_DEPEND; + } else if (STRING_EQUAL(argv[i],"mono")) { + option->image = NTR_IMAGE_MONO; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-depth")) { + i++; + option->imageClip = (double) atof(argv[i]); + } else if (STRING_EQUAL(argv[i],"-cdepth")) { + i++; + option->closureClip = (double) atof(argv[i]); + } else if (STRING_EQUAL(argv[i],"-approx")) { + i++; + if (STRING_EQUAL(argv[i],"under")) { + option->approx = NTR_UNDER_APPROX; + } else if (STRING_EQUAL(argv[i],"over")) { + option->approx = NTR_OVER_APPROX; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-threshold")) { + i++; + option->threshold = (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-from")) { + i++; + if (STRING_EQUAL(argv[i],"new")) { + option->from = NTR_FROM_NEW; + } else if (STRING_EQUAL(argv[i],"reached")) { + option->from = NTR_FROM_REACHED; + } else if (STRING_EQUAL(argv[i],"restrict")) { + option->from = NTR_FROM_RESTRICT; + } else if (STRING_EQUAL(argv[i],"compact")) { + option->from = NTR_FROM_COMPACT; + } else if (STRING_EQUAL(argv[i],"squeeze")) { + option->from = NTR_FROM_SQUEEZE; + } else if (STRING_EQUAL(argv[i],"subset")) { + option->from = NTR_FROM_UNDERAPPROX; + } else if (STRING_EQUAL(argv[i],"superset")) { + option->from = NTR_FROM_OVERAPPROX; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-groupnsps")) { + i++; + if (STRING_EQUAL(argv[i],"none")) { + option->groupnsps = NTR_GROUP_NONE; + } else if (STRING_EQUAL(argv[i],"default")) { + option->groupnsps = NTR_GROUP_DEFAULT; + } else if (STRING_EQUAL(argv[i],"fixed")) { + option->groupnsps = NTR_GROUP_FIXED; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-closure")) { + option->closure = TRUE; + } else if (STRING_EQUAL(argv[i],"-envelope")) { + option->envelope = TRUE; + } else if (STRING_EQUAL(argv[i],"-scc")) { + option->scc = TRUE; + } else if (STRING_EQUAL(argv[i],"-maxflow")) { + option->maxflow = TRUE; + } else if (STRING_EQUAL(argv[i],"-shortpaths")) { + i++; + if (STRING_EQUAL(argv[i],"none")) { + option->shortPath = NTR_SHORT_NONE; + } else if (STRING_EQUAL(argv[i],"bellman")) { + option->shortPath = NTR_SHORT_BELLMAN; + } else if (STRING_EQUAL(argv[i],"floyd")) { + option->shortPath = NTR_SHORT_FLOYD; + } else if (STRING_EQUAL(argv[i],"square")) { + option->shortPath = NTR_SHORT_SQUARE; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-selective")) { + option->selectiveTrace = TRUE; + } else if (STRING_EQUAL(argv[i],"-zdd")) { + option->zddtest = TRUE; + } else if (STRING_EQUAL(argv[i],"-cover")) { + option->zddtest = TRUE; + option->printcover = TRUE; + } else if (STRING_EQUAL(argv[i],"-sink")) { + i++; + option->maxflow = TRUE; + option->sinkfile = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-part")) { + option->partition = TRUE; + } else if (STRING_EQUAL(argv[i],"-char2vect")) { + option->char2vect = TRUE; + } else if (STRING_EQUAL(argv[i],"-density")) { + option->density = TRUE; + } else if (STRING_EQUAL(argv[i],"-quality")) { + i++; + option->quality = (double) atof(argv[i]); + } else if (STRING_EQUAL(argv[i],"-decomp")) { + option->decomp = TRUE; + } else if (STRING_EQUAL(argv[i],"-cofest")) { + option->cofest = TRUE; + } else if (STRING_EQUAL(argv[i],"-clip")) { + i++; + option->clip = (double) atof(argv[i]); + i++; + option->file2 = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-dctest")) { + option->dontcares = TRUE; + i++; + option->file2 = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-closest")) { + option->closestCube = TRUE; + } else if (STRING_EQUAL(argv[i],"-clauses")) { + option->clauses = TRUE; + } else if (STRING_EQUAL(argv[i],"-nobuild")) { + option->noBuild = TRUE; + option->reordering = CUDD_REORDER_NONE; + } else if (STRING_EQUAL(argv[i],"-delta")) { + option->stateOnly = TRUE; + } else if (STRING_EQUAL(argv[i],"-node")) { + i++; + option->node = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-local")) { + option->locGlob = BNET_LOCAL_DD; + } else if (STRING_EQUAL(argv[i],"-progress")) { + option->progress = TRUE; + } else if (STRING_EQUAL(argv[i],"-cache")) { + i++; + option->cacheSize = (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-maxmem")) { + i++; + option->maxMemory = 1048576 * (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-memhard")) { + i++; + option->maxMemHard = 1048576 * (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-maxlive")) { + i++; + option->maxLive = (unsigned int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-slots")) { + i++; + option->slots = (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-ordering")) { + i++; + if (STRING_EQUAL(argv[i],"dfs")) { + option->ordering = PI_PS_DFS; + } else if (STRING_EQUAL(argv[i],"hw")) { + option->ordering = PI_PS_FROM_FILE; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-order")) { + i++; + option->ordering = PI_PS_GIVEN; + option->orderPiPs = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-reordering")) { + i++; + if (STRING_EQUAL(argv[i],"none")) { + option->reordering = CUDD_REORDER_NONE; + } else if (STRING_EQUAL(argv[i],"random")) { + option->reordering = CUDD_REORDER_RANDOM; + } else if (STRING_EQUAL(argv[i],"bernard") || + STRING_EQUAL(argv[i],"pivot")) { + option->reordering = CUDD_REORDER_RANDOM_PIVOT; + } else if (STRING_EQUAL(argv[i],"sifting")) { + option->reordering = CUDD_REORDER_SIFT; + } else if (STRING_EQUAL(argv[i],"converge")) { + option->reordering = CUDD_REORDER_SIFT_CONVERGE; + } else if (STRING_EQUAL(argv[i],"symm")) { + option->reordering = CUDD_REORDER_SYMM_SIFT; + } else if (STRING_EQUAL(argv[i],"cosymm")) { + option->reordering = CUDD_REORDER_SYMM_SIFT_CONV; + } else if (STRING_EQUAL(argv[i],"tree") || + STRING_EQUAL(argv[i],"group")) { + option->reordering = CUDD_REORDER_GROUP_SIFT; + } else if (STRING_EQUAL(argv[i],"cotree") || + STRING_EQUAL(argv[i],"cogroup")) { + option->reordering = CUDD_REORDER_GROUP_SIFT_CONV; + } else if (STRING_EQUAL(argv[i],"win2")) { + option->reordering = CUDD_REORDER_WINDOW2; + } else if (STRING_EQUAL(argv[i],"win3")) { + option->reordering = CUDD_REORDER_WINDOW3; + } else if (STRING_EQUAL(argv[i],"win4")) { + option->reordering = CUDD_REORDER_WINDOW4; + } else if (STRING_EQUAL(argv[i],"win2conv")) { + option->reordering = CUDD_REORDER_WINDOW2_CONV; + } else if (STRING_EQUAL(argv[i],"win3conv")) { + option->reordering = CUDD_REORDER_WINDOW3_CONV; + } else if (STRING_EQUAL(argv[i],"win4conv")) { + option->reordering = CUDD_REORDER_WINDOW4_CONV; + } else if (STRING_EQUAL(argv[i],"annealing")) { + option->reordering = CUDD_REORDER_ANNEALING; + } else if (STRING_EQUAL(argv[i],"genetic")) { + option->reordering = CUDD_REORDER_GENETIC; + } else if (STRING_EQUAL(argv[i],"linear")) { + option->reordering = CUDD_REORDER_LINEAR; + } else if (STRING_EQUAL(argv[i],"linconv")) { + option->reordering = CUDD_REORDER_LINEAR_CONVERGE; + } else if (STRING_EQUAL(argv[i],"exact")) { + option->reordering = CUDD_REORDER_EXACT; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-autodyn")) { + option->autoDyn = 3; + } else if (STRING_EQUAL(argv[i],"-autodynB")) { + option->autoDyn |= 1; + } else if (STRING_EQUAL(argv[i],"-autodynZ")) { + option->autoDyn |= 2; + } else if (STRING_EQUAL(argv[i],"-automethod")) { + i++; + if (STRING_EQUAL(argv[i],"none")) { + option->autoMethod = CUDD_REORDER_NONE; + } else if (STRING_EQUAL(argv[i],"random")) { + option->autoMethod = CUDD_REORDER_RANDOM; + } else if (STRING_EQUAL(argv[i],"bernard") || + STRING_EQUAL(argv[i],"pivot")) { + option->autoMethod = CUDD_REORDER_RANDOM_PIVOT; + } else if (STRING_EQUAL(argv[i],"sifting")) { + option->autoMethod = CUDD_REORDER_SIFT; + } else if (STRING_EQUAL(argv[i],"converge")) { + option->autoMethod = CUDD_REORDER_SIFT_CONVERGE; + } else if (STRING_EQUAL(argv[i],"symm")) { + option->autoMethod = CUDD_REORDER_SYMM_SIFT; + } else if (STRING_EQUAL(argv[i],"cosymm")) { + option->autoMethod = CUDD_REORDER_SYMM_SIFT_CONV; + } else if (STRING_EQUAL(argv[i],"tree") || + STRING_EQUAL(argv[i],"group")) { + option->autoMethod = CUDD_REORDER_GROUP_SIFT; + } else if (STRING_EQUAL(argv[i],"cotree") || + STRING_EQUAL(argv[i],"cogroup")) { + option->autoMethod = CUDD_REORDER_GROUP_SIFT_CONV; + } else if (STRING_EQUAL(argv[i],"win2")) { + option->autoMethod = CUDD_REORDER_WINDOW2; + } else if (STRING_EQUAL(argv[i],"win3")) { + option->autoMethod = CUDD_REORDER_WINDOW3; + } else if (STRING_EQUAL(argv[i],"win4")) { + option->autoMethod = CUDD_REORDER_WINDOW4; + } else if (STRING_EQUAL(argv[i],"win2conv")) { + option->autoMethod = CUDD_REORDER_WINDOW2_CONV; + } else if (STRING_EQUAL(argv[i],"win3conv")) { + option->autoMethod = CUDD_REORDER_WINDOW3_CONV; + } else if (STRING_EQUAL(argv[i],"win4conv")) { + option->autoMethod = CUDD_REORDER_WINDOW4_CONV; + } else if (STRING_EQUAL(argv[i],"annealing")) { + option->autoMethod = CUDD_REORDER_ANNEALING; + } else if (STRING_EQUAL(argv[i],"genetic")) { + option->autoMethod = CUDD_REORDER_GENETIC; + } else if (STRING_EQUAL(argv[i],"linear")) { + option->autoMethod = CUDD_REORDER_LINEAR; + } else if (STRING_EQUAL(argv[i],"linconv")) { + option->autoMethod = CUDD_REORDER_LINEAR_CONVERGE; + } else if (STRING_EQUAL(argv[i],"exact")) { + option->autoMethod = CUDD_REORDER_EXACT; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-tree")) { + i++; + option->treefile = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-first")) { + i++; + option->firstReorder = (int)atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-countdead")) { + option->countDead = TRUE; + } else if (STRING_EQUAL(argv[i],"-growth")) { + i++; + option->maxGrowth = (int)atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-groupcheck")) { + i++; + if (STRING_EQUAL(argv[i],"check")) { + option->groupcheck = CUDD_GROUP_CHECK; + } else if (STRING_EQUAL(argv[i],"nocheck")) { + option->groupcheck = CUDD_NO_CHECK; + } else if (STRING_EQUAL(argv[i],"check2")) { + option->groupcheck = CUDD_GROUP_CHECK2; + } else if (STRING_EQUAL(argv[i],"check3")) { + option->groupcheck = CUDD_GROUP_CHECK3; + } else if (STRING_EQUAL(argv[i],"check4")) { + option->groupcheck = CUDD_GROUP_CHECK4; + } else if (STRING_EQUAL(argv[i],"check5")) { + option->groupcheck = CUDD_GROUP_CHECK5; + } else if (STRING_EQUAL(argv[i],"check6")) { + option->groupcheck = CUDD_GROUP_CHECK6; + } else if (STRING_EQUAL(argv[i],"check7")) { + option->groupcheck = CUDD_GROUP_CHECK7; + } else if (STRING_EQUAL(argv[i],"check8")) { + option->groupcheck = CUDD_GROUP_CHECK8; + } else if (STRING_EQUAL(argv[i],"check9")) { + option->groupcheck = CUDD_GROUP_CHECK9; + } else { + goto usage; + } + } else if (STRING_EQUAL(argv[i],"-arcviolation")) { + i++; + option->arcviolation = (int)atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-symmviolation")) { + i++; + option->symmviolation = (int)atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-recomb")) { + i++; + option->recomb = (int)atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-drop")) { + option->nodrop = FALSE; + } else if (STRING_EQUAL(argv[i],"-sign")) { + option->signatures = TRUE; + } else if (STRING_EQUAL(argv[i],"-genetic")) { + option->gaOnOff = 1; + } else if (STRING_EQUAL(argv[i],"-genepop")) { + option->gaOnOff = 1; + i++; + option->populationSize = (int)atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-genexover")) { + option->gaOnOff = 1; + i++; + option->numberXovers = (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-seed")) { + i++; + Cudd_Srandom((long)atoi(argv[i])); + } else if (STRING_EQUAL(argv[i],"-dumpfile")) { + i++; + option->bdddump = TRUE; + option->dumpfile = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-dumpblif")) { + option->dumpFmt = 1; /* blif */ + } else if (STRING_EQUAL(argv[i],"-dumpdaVinci")) { + option->dumpFmt = 2; /* daVinci */ + } else if (STRING_EQUAL(argv[i],"-dumpddcal")) { + option->dumpFmt = 3; /* DDcal */ + } else if (STRING_EQUAL(argv[i],"-dumpfact")) { + option->dumpFmt = 4; /* factored form */ + } else if (STRING_EQUAL(argv[i],"-dumpmv")) { + option->dumpFmt = 5; /* blif-MV */ + } else if (STRING_EQUAL(argv[i],"-store")) { + i++; + option->store = (int) atoi(argv[i]); + } else if (STRING_EQUAL(argv[i],"-storefile")) { + i++; + option->storefile = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-loadfile")) { + i++; + option->load = 1; + option->loadfile = util_strsav(argv[i]); + } else if (STRING_EQUAL(argv[i],"-p")) { + i++; + option->verb = (int) atoi(argv[i]); + } else { + goto usage; + } + } + + if (option->store >= 0 && option->storefile == NULL) { + (void) fprintf(stdout,"-storefile mandatory with -store\n"); + exit(-1); + } + + if (option->verb >= 0) { + (void) printf("# %s\n", NTR_VERSION); + /* echo command line and arguments */ + (void) printf("#"); + for (i = 0; i < argc; i++) { + (void) printf(" %s", argv[i]); + } + (void) printf("\n"); + (void) printf("# CUDD Version "); + Cudd_PrintVersion(stdout); + (void) fflush(stdout); + } + + return; + +usage: /* convenient goto */ + printf("Usage: please read man page\n"); + if (i == 0) { + (void) fprintf(stdout,"too few arguments\n"); + } else { + (void) fprintf(stdout,"option: %s is not defined\n",argv[i]); + } + exit(-1); + +} /* end of ntrReadOptions */ + + +/**Function******************************************************************** + + Synopsis [Reads the program options from a file.] + + Description [Reads the program options from a file. Opens file. Reads + the command line from the otpions file using the read_line func. Scans + the line looking for spaces, each space is a searator and demarks a + new option. When a space is found, it is changed to a \0 to terminate + that string; then the next value of slot points to the next non-space + character. There is a limit of 1024 options. + Should produce an error (presently doesn't) on overrun of options, but + this is very unlikely to happen.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static void +ntrReadOptionsFile( + char * name, + char *** argv, + int * argc) +{ + char **slot; + char *line; + char c; + int index,flag; + FILE *fp; + + if ((fp = fopen(name,"r")) == NULL) { + fprintf(stderr,"Error: can not find cmd file %s\n",name); + exit(-1); + } + + slot = ALLOC(char *,1024); + index = 1; + line = readLine(fp); + flag = TRUE; + + do { + c = *line; + if ( c == ' ') { + flag = TRUE; + *line = '\0'; + } else if ( c != ' ' && flag == TRUE) { + flag = FALSE; + slot[index] = line; + index++; + } + line++; + } while ( *line != '\0'); + + + *argv = slot; + *argc = index; + + fclose(fp); + +} /* end of ntrReadOptionsFile */ + + +/**Function******************************************************************** + + Synopsis [Reads a line from the option file.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static char* +readLine( + FILE * fp) +{ + int c; + char *pbuffer; + + pbuffer = buffer; + + /* Strip white space from beginning of line. */ + for(;;) { + c = getc(fp); + if ( c == EOF) return(NULL); + if ( c == '\n') { + *pbuffer = '\0'; + return(buffer); /* got a blank line */ + } + if ( c != ' ') break; + } + do { + if ( c == '\\' ) { /* if we have a continuation character.. */ + do { /* scan to end of line */ + c = getc(fp); + if ( c == '\n' ) break; + } while ( c != EOF); + if ( c != EOF) { + *pbuffer = ' '; + pbuffer++; + } else return( buffer); + c = getc(fp); + continue; + } + *pbuffer = (char) c; + pbuffer++; + c = getc(fp); + } while( c != '\n' && c != EOF); + *pbuffer = '\0'; + return(buffer); + +} /* end of readLine */ + + +/**Function******************************************************************** + + Synopsis [Opens a file.] + + Description [Opens a file, or fails with an error message and exits. + Allows '-' as a synonym for standard input.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static FILE * +open_file( + char * filename, + const char * mode) +{ + FILE *fp; + + if (strcmp(filename, "-") == 0) { + return mode[0] == 'r' ? stdin : stdout; + } else if ((fp = fopen(filename, mode)) == NULL) { + perror(filename); + exit(1); + } + return(fp); + +} /* end of open_file */ + + +/**Function******************************************************************** + + Synopsis [Applies reordering to the DDs.] + + Description [Explicitly applies reordering to the DDs. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +static int +reorder( + BnetNetwork * net, + DdManager * dd /* DD Manager */, + NtrOptions * option) +{ +#ifdef DD_DEBUG + st_table *mintermTable; /* minterm counts for each output */ +#endif + int result; /* return value from functions */ + + (void) printf("Number of inputs = %d\n",net->ninputs); + + /* Perform the final reordering */ + if (option->reordering != CUDD_REORDER_NONE) { +#ifdef DD_DEBUG + result = Cudd_DebugCheck(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + return(0); + } + result = Cudd_CheckKeys(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + return(0); + } + mintermTable = checkMinterms(net,dd,NULL); + if (mintermTable == NULL) exit(2); +#endif + + dd->siftMaxVar = 1000000; + dd->siftMaxSwap = 1000000000; + result = Cudd_ReduceHeap(dd,option->reordering,1); + if (result == 0) return(0); +#ifdef DD_DEBUG + result = Cudd_DebugCheck(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + return(0); + } + result = Cudd_CheckKeys(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + return(0); + } + mintermTable = checkMinterms(net,dd,mintermTable); +#endif + + /* Print symmetry stats if pertinent */ + if (dd->tree == NULL && + (option->reordering == CUDD_REORDER_SYMM_SIFT || + option->reordering == CUDD_REORDER_SYMM_SIFT_CONV)) + Cudd_SymmProfile(dd,0,dd->size - 1); + } + + if (option->gaOnOff) { + result = Cudd_ReduceHeap(dd,CUDD_REORDER_GENETIC,1); + if (result == 0) { + (void) printf("Something went wrong in cuddGa\n"); + return(0); + } + } + + return(1); + +} /* end of reorder */ + + +/**Function******************************************************************** + + Synopsis [Frees the option structure and its appendages.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +static void +freeOption( + NtrOptions * option) +{ + if (option->file1 != NULL) FREE(option->file1); + if (option->file2 != NULL) FREE(option->file2); + if (option->orderPiPs != NULL) FREE(option->orderPiPs); + if (option->treefile != NULL) FREE(option->treefile); + if (option->sinkfile != NULL) FREE(option->sinkfile); + if (option->dumpfile != NULL) FREE(option->dumpfile); + if (option->loadfile != NULL) FREE(option->loadfile); + if (option->storefile != NULL) FREE(option->storefile); + if (option->node != NULL) FREE(option->node); + FREE(option); + +} /* end of freeOption */ + + +/**Function******************************************************************** + + Synopsis [Starts the CUDD manager with the desired options.] + + Description [Starts the CUDD manager with the desired options. + We start with 0 variables, because Ntr_buildDDs will create new + variables rather than using whatever already exists.] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +static DdManager * +startCudd( + NtrOptions * option, + int nvars) +{ + DdManager *dd; + int result; + + dd = Cudd_Init(0, 0, option->slots, option->cacheSize, option->maxMemory); + if (dd == NULL) return(NULL); + + if (option->maxMemHard != 0) { + Cudd_SetMaxMemory(dd,option->maxMemHard); + } + Cudd_SetMaxLive(dd,option->maxLive); + Cudd_SetGroupcheck(dd,option->groupcheck); + if (option->autoDyn & 1) { + Cudd_AutodynEnable(dd,option->autoMethod); + } + dd->nextDyn = option->firstReorder; + dd->countDead = (option->countDead == FALSE) ? ~0 : 0; + dd->maxGrowth = 1.0 + ((float) option->maxGrowth / 100.0); + dd->recomb = option->recomb; + dd->arcviolation = option->arcviolation; + dd->symmviolation = option->symmviolation; + dd->populationSize = option->populationSize; + dd->numberXovers = option->numberXovers; + result = ntrReadTree(dd,option->treefile,nvars); + if (result == 0) { + Cudd_Quit(dd); + return(NULL); + } +#ifndef DD_STATS + result = Cudd_EnableReorderingReporting(dd); + if (result == 0) { + (void) fprintf(stderr, + "Error reported by Cudd_EnableReorderingReporting\n"); + Cudd_Quit(dd); + return(NULL); + } +#endif + + return(dd); + +} /* end of startCudd */ + + +/**Function******************************************************************** + + Synopsis [Reads the variable group tree from a file.] + + Description [Reads the variable group tree from a file. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +static int +ntrReadTree( + DdManager * dd, + char * treefile, + int nvars) +{ + FILE *fp; + MtrNode *root; + + if (treefile == NULL) { + return(1); + } + + if ((fp = fopen(treefile,"r")) == NULL) { + (void) fprintf(stderr,"Unable to open %s\n",treefile); + return(0); + } + + root = Mtr_ReadGroups(fp,ddMax(Cudd_ReadSize(dd),nvars)); + if (root == NULL) { + return(0); + } + + Cudd_SetTree(dd,root); + + return(1); + +} /* end of ntrReadTree */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.blif b/resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.blif new file mode 100644 index 000000000..5fafc00d9 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.blif @@ -0,0 +1,745 @@ +.model MultiplierA_32 +.inputs 1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 +.outputs 68 +.latch 67 2 0 +.latch 69 36 0 +.latch 70 37 0 +.latch 71 38 0 +.latch 72 39 0 +.latch 73 40 0 +.latch 74 41 0 +.latch 75 42 0 +.latch 76 43 0 +.latch 77 44 0 +.latch 78 45 0 +.latch 79 46 0 +.latch 80 47 0 +.latch 81 48 0 +.latch 82 49 0 +.latch 83 50 0 +.latch 84 51 0 +.latch 85 52 0 +.latch 86 53 0 +.latch 87 54 0 +.latch 88 55 0 +.latch 89 56 0 +.latch 90 57 0 +.latch 91 58 0 +.latch 92 59 0 +.latch 93 60 0 +.latch 94 61 0 +.latch 95 62 0 +.latch 96 63 0 +.latch 97 64 0 +.latch 98 65 0 +.latch 99 66 0 +.names 101 100 +0 1 +.names 1 204 101 +00 1 +11 1 +.names 3 102 +1 1 +.names 4 103 +1 1 +.names 5 104 +1 1 +.names 6 105 +1 1 +.names 7 106 +1 1 +.names 8 107 +1 1 +.names 9 108 +1 1 +.names 10 109 +1 1 +.names 11 110 +1 1 +.names 12 111 +1 1 +.names 13 112 +1 1 +.names 14 113 +1 1 +.names 15 114 +1 1 +.names 16 115 +1 1 +.names 17 116 +1 1 +.names 18 117 +1 1 +.names 19 118 +1 1 +.names 20 119 +1 1 +.names 21 120 +1 1 +.names 22 121 +1 1 +.names 23 122 +1 1 +.names 24 123 +1 1 +.names 25 124 +1 1 +.names 26 125 +1 1 +.names 27 126 +1 1 +.names 28 127 +1 1 +.names 29 128 +1 1 +.names 30 129 +1 1 +.names 31 130 +1 1 +.names 32 131 +1 1 +.names 33 132 +1 1 +.names 34 133 +1 1 +.names 134 +.names 135 +.names 136 +.names 137 +.names 138 +.names 139 +.names 140 +.names 141 +.names 142 +.names 143 +.names 144 +.names 145 +.names 146 +.names 147 +.names 148 +.names 149 +.names 150 +.names 151 +.names 152 +.names 153 +.names 154 +.names 155 +.names 156 +.names 157 +.names 158 +.names 159 +.names 160 +.names 161 +.names 162 +.names 163 +.names 164 +.names 165 +.names 66 265 266 166 +-11 1 +1-1 1 +11- 1 +.names 36 205 206 167 +010 1 +001 1 +100 1 +111 1 +.names 37 207 208 168 +010 1 +001 1 +100 1 +111 1 +.names 38 209 210 169 +010 1 +001 1 +100 1 +111 1 +.names 39 211 212 170 +010 1 +001 1 +100 1 +111 1 +.names 40 213 214 171 +010 1 +001 1 +100 1 +111 1 +.names 41 215 216 172 +010 1 +001 1 +100 1 +111 1 +.names 42 217 218 173 +010 1 +001 1 +100 1 +111 1 +.names 43 219 220 174 +010 1 +001 1 +100 1 +111 1 +.names 44 221 222 175 +010 1 +001 1 +100 1 +111 1 +.names 45 223 224 176 +010 1 +001 1 +100 1 +111 1 +.names 46 225 226 177 +010 1 +001 1 +100 1 +111 1 +.names 47 227 228 178 +010 1 +001 1 +100 1 +111 1 +.names 48 229 230 179 +010 1 +001 1 +100 1 +111 1 +.names 49 231 232 180 +010 1 +001 1 +100 1 +111 1 +.names 50 233 234 181 +010 1 +001 1 +100 1 +111 1 +.names 51 235 236 182 +010 1 +001 1 +100 1 +111 1 +.names 52 237 238 183 +010 1 +001 1 +100 1 +111 1 +.names 53 239 240 184 +010 1 +001 1 +100 1 +111 1 +.names 54 241 242 185 +010 1 +001 1 +100 1 +111 1 +.names 55 243 244 186 +010 1 +001 1 +100 1 +111 1 +.names 56 245 246 187 +010 1 +001 1 +100 1 +111 1 +.names 57 247 248 188 +010 1 +001 1 +100 1 +111 1 +.names 58 249 250 189 +010 1 +001 1 +100 1 +111 1 +.names 59 251 252 190 +010 1 +001 1 +100 1 +111 1 +.names 60 253 254 191 +010 1 +001 1 +100 1 +111 1 +.names 61 255 256 192 +010 1 +001 1 +100 1 +111 1 +.names 62 257 258 193 +010 1 +001 1 +100 1 +111 1 +.names 63 259 260 194 +010 1 +001 1 +100 1 +111 1 +.names 64 261 262 195 +010 1 +001 1 +100 1 +111 1 +.names 65 263 264 196 +010 1 +001 1 +100 1 +111 1 +.names 66 265 266 197 +010 1 +001 1 +100 1 +111 1 +.names 2 268 198 +10 1 +01 1 +.names 269 270 199 +11 1 +.names 166 272 200 +11 1 +.names 166 274 201 +11 1 +.names 166 275 202 +11 1 +.names 276 277 203 +-1 1 +1- 1 +.names 204 +.names 205 +.names 340 341 206 +-1 1 +1- 1 +.names 36 205 206 207 +-11 1 +1-1 1 +11- 1 +.names 338 339 208 +-1 1 +1- 1 +.names 37 207 208 209 +-11 1 +1-1 1 +11- 1 +.names 336 337 210 +-1 1 +1- 1 +.names 38 209 210 211 +-11 1 +1-1 1 +11- 1 +.names 334 335 212 +-1 1 +1- 1 +.names 39 211 212 213 +-11 1 +1-1 1 +11- 1 +.names 332 333 214 +-1 1 +1- 1 +.names 40 213 214 215 +-11 1 +1-1 1 +11- 1 +.names 330 331 216 +-1 1 +1- 1 +.names 41 215 216 217 +-11 1 +1-1 1 +11- 1 +.names 328 329 218 +-1 1 +1- 1 +.names 42 217 218 219 +-11 1 +1-1 1 +11- 1 +.names 326 327 220 +-1 1 +1- 1 +.names 43 219 220 221 +-11 1 +1-1 1 +11- 1 +.names 324 325 222 +-1 1 +1- 1 +.names 44 221 222 223 +-11 1 +1-1 1 +11- 1 +.names 322 323 224 +-1 1 +1- 1 +.names 45 223 224 225 +-11 1 +1-1 1 +11- 1 +.names 320 321 226 +-1 1 +1- 1 +.names 46 225 226 227 +-11 1 +1-1 1 +11- 1 +.names 318 319 228 +-1 1 +1- 1 +.names 47 227 228 229 +-11 1 +1-1 1 +11- 1 +.names 316 317 230 +-1 1 +1- 1 +.names 48 229 230 231 +-11 1 +1-1 1 +11- 1 +.names 314 315 232 +-1 1 +1- 1 +.names 49 231 232 233 +-11 1 +1-1 1 +11- 1 +.names 312 313 234 +-1 1 +1- 1 +.names 50 233 234 235 +-11 1 +1-1 1 +11- 1 +.names 310 311 236 +-1 1 +1- 1 +.names 51 235 236 237 +-11 1 +1-1 1 +11- 1 +.names 308 309 238 +-1 1 +1- 1 +.names 52 237 238 239 +-11 1 +1-1 1 +11- 1 +.names 306 307 240 +-1 1 +1- 1 +.names 53 239 240 241 +-11 1 +1-1 1 +11- 1 +.names 304 305 242 +-1 1 +1- 1 +.names 54 241 242 243 +-11 1 +1-1 1 +11- 1 +.names 302 303 244 +-1 1 +1- 1 +.names 55 243 244 245 +-11 1 +1-1 1 +11- 1 +.names 300 301 246 +-1 1 +1- 1 +.names 56 245 246 247 +-11 1 +1-1 1 +11- 1 +.names 298 299 248 +-1 1 +1- 1 +.names 57 247 248 249 +-11 1 +1-1 1 +11- 1 +.names 296 297 250 +-1 1 +1- 1 +.names 58 249 250 251 +-11 1 +1-1 1 +11- 1 +.names 294 295 252 +-1 1 +1- 1 +.names 59 251 252 253 +-11 1 +1-1 1 +11- 1 +.names 292 293 254 +-1 1 +1- 1 +.names 60 253 254 255 +-11 1 +1-1 1 +11- 1 +.names 290 291 256 +-1 1 +1- 1 +.names 61 255 256 257 +-11 1 +1-1 1 +11- 1 +.names 288 289 258 +-1 1 +1- 1 +.names 62 257 258 259 +-11 1 +1-1 1 +11- 1 +.names 286 287 260 +-1 1 +1- 1 +.names 63 259 260 261 +-11 1 +1-1 1 +11- 1 +.names 284 285 262 +-1 1 +1- 1 +.names 64 261 262 263 +-11 1 +1-1 1 +11- 1 +.names 282 283 264 +-1 1 +1- 1 +.names 65 263 264 265 +-11 1 +1-1 1 +11- 1 +.names 280 281 266 +-1 1 +1- 1 +.names 278 279 267 +-1 1 +1- 1 +.names 166 267 268 +01 1 +10 1 +.names 2 267 269 +11 1 +.names 166 270 +0 1 +.names 267 271 +0 1 +.names 2 271 272 +11 1 +.names 2 273 +0 1 +.names 267 273 274 +11 1 +.names 2 267 275 +11 1 +.names 199 200 276 +-1 1 +1- 1 +.names 201 202 277 +-1 1 +1- 1 +.names 203 67 +1 1 +.names 167 68 +1 1 +.names 168 69 +1 1 +.names 169 70 +1 1 +.names 170 71 +1 1 +.names 171 72 +1 1 +.names 172 73 +1 1 +.names 173 74 +1 1 +.names 174 75 +1 1 +.names 175 76 +1 1 +.names 176 77 +1 1 +.names 177 78 +1 1 +.names 178 79 +1 1 +.names 179 80 +1 1 +.names 180 81 +1 1 +.names 181 82 +1 1 +.names 182 83 +1 1 +.names 183 84 +1 1 +.names 184 85 +1 1 +.names 185 86 +1 1 +.names 186 87 +1 1 +.names 187 88 +1 1 +.names 188 89 +1 1 +.names 189 90 +1 1 +.names 190 91 +1 1 +.names 191 92 +1 1 +.names 192 93 +1 1 +.names 193 94 +1 1 +.names 194 95 +1 1 +.names 195 96 +1 1 +.names 196 97 +1 1 +.names 197 98 +1 1 +.names 198 99 +1 1 +.names 100 133 278 +11 1 +.names 101 165 279 +11 1 +.names 100 132 280 +11 1 +.names 101 164 281 +11 1 +.names 100 131 282 +11 1 +.names 101 163 283 +11 1 +.names 100 130 284 +11 1 +.names 101 162 285 +11 1 +.names 100 129 286 +11 1 +.names 101 161 287 +11 1 +.names 100 128 288 +11 1 +.names 101 160 289 +11 1 +.names 100 127 290 +11 1 +.names 101 159 291 +11 1 +.names 100 126 292 +11 1 +.names 101 158 293 +11 1 +.names 100 125 294 +11 1 +.names 101 157 295 +11 1 +.names 100 124 296 +11 1 +.names 101 156 297 +11 1 +.names 100 123 298 +11 1 +.names 101 155 299 +11 1 +.names 100 122 300 +11 1 +.names 101 154 301 +11 1 +.names 100 121 302 +11 1 +.names 101 153 303 +11 1 +.names 100 120 304 +11 1 +.names 101 152 305 +11 1 +.names 100 119 306 +11 1 +.names 101 151 307 +11 1 +.names 100 118 308 +11 1 +.names 101 150 309 +11 1 +.names 100 117 310 +11 1 +.names 101 149 311 +11 1 +.names 100 116 312 +11 1 +.names 101 148 313 +11 1 +.names 100 115 314 +11 1 +.names 101 147 315 +11 1 +.names 100 114 316 +11 1 +.names 101 146 317 +11 1 +.names 100 113 318 +11 1 +.names 101 145 319 +11 1 +.names 100 112 320 +11 1 +.names 101 144 321 +11 1 +.names 100 111 322 +11 1 +.names 101 143 323 +11 1 +.names 100 110 324 +11 1 +.names 101 142 325 +11 1 +.names 100 109 326 +11 1 +.names 101 141 327 +11 1 +.names 100 108 328 +11 1 +.names 101 140 329 +11 1 +.names 100 107 330 +11 1 +.names 101 139 331 +11 1 +.names 100 106 332 +11 1 +.names 101 138 333 +11 1 +.names 100 105 334 +11 1 +.names 101 137 335 +11 1 +.names 100 104 336 +11 1 +.names 101 136 337 +11 1 +.names 100 103 338 +11 1 +.names 101 135 339 +11 1 +.names 100 102 340 +11 1 +.names 101 134 341 +11 1 +.end diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.out b/resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.out new file mode 100644 index 000000000..f0933305e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/mult32a.out @@ -0,0 +1,258 @@ +# Nanotrav Version #0.12, Release date 2003/12/31 +# ./nanotrav -p 1 -autodyn -reordering sifting -trav mult32a.blif +# CUDD Version 2.4.2 +BDD reordering with sifting: from 4001 to ... 268 nodes in 0.005 sec +BDD reordering with sifting: from 537 to ... 246 nodes in 0.006 sec +BDD reordering with sifting: from 493 to ... 250 nodes in 0.009 sec +BDD reordering with sifting: from 501 to ... 280 nodes in 0.012 sec +BDD reordering with sifting: from 561 to ... 296 nodes in 0.015 sec +Order before final reordering +2 34 33 66 32 65 31 64 +63 30 62 29 28 61 27 60 +26 59 25 58 24 57 23 56 +22 55 21 54 20 53 19 52 +51 18 50 17 49 16 48 15 +47 14 46 13 45 12 36 3 +37 4 38 5 39 6 40 7 +41 8 42 9 43 10 44 11 +1 +Number of inputs = 65 +BDD reordering with sifting: from 380 to ... 317 nodes in 0.012 sec +New order +1 2 34 66 33 65 32 64 +31 63 30 62 29 61 28 60 +27 59 26 58 25 57 24 56 +23 55 22 54 21 53 20 52 +19 51 18 50 17 49 16 48 +15 47 14 46 13 45 12 36 +3 4 37 5 38 6 39 7 +40 8 41 9 42 10 43 44 +11 +Building transition relation. Time = 0.06 sec +BDD reordering with sifting: from 670 to ... 453 nodes in 0.029 sec +@@BDD reordering with sifting: from 940 to ... 700 nodes in 0.03 sec +@@BDD reordering with sifting: from 1433 to ... 832 nodes in 0.039 sec +@@BDD reordering with sifting: from 1697 to ... 1063 nodes in 0.045 sec +@@@BDD reordering with sifting: from 2159 to ... 786 nodes in 0.049 sec +@@@@BDD reordering with sifting: from 1605 to ... 893 nodes in 0.043 sec +@@@@BDD reordering with sifting: from 1819 to ... 951 nodes in 0.048 sec +@@@@@BDD reordering with sifting: from 1935 to ... 965 nodes in 0.055 sec +@@@@@BDD reordering with sifting: from 1963 to ... 1055 nodes in 0.059 sec +@@@@@ +Transition relation: 1 parts 32 latches 199 nodes +Traversing. Time = 0.46 sec +S0: 33 nodes 1 leaves 1 minterms +From[1]: 33 nodes 1 leaves 2.14748e+09 minterms +Reached[1]: 2 nodes 1 leaves 2.14748e+09 minterms +2147483648 +2.14748e+9 +From[2]: 3 nodes 1 leaves 1.07374e+09 minterms +Reached[2]: 3 nodes 1 leaves 3.22123e+09 minterms +3221225472 +3.22122e+9 +From[3]: 4 nodes 1 leaves 5.36871e+08 minterms +Reached[3]: 4 nodes 1 leaves 3.7581e+09 minterms +3758096384 +3.75809e+9 +From[4]: 5 nodes 1 leaves 2.68435e+08 minterms +Reached[4]: 5 nodes 1 leaves 4.02653e+09 minterms +4026531840 +4.02653e+9 +From[5]: 6 nodes 1 leaves 1.34218e+08 minterms +Reached[5]: 6 nodes 1 leaves 4.16075e+09 minterms +4160749568 +4.16074e+9 +From[6]: 7 nodes 1 leaves 6.71089e+07 minterms +Reached[6]: 7 nodes 1 leaves 4.22786e+09 minterms +4227858432 +4.22785e+9 +From[7]: 8 nodes 1 leaves 3.35544e+07 minterms +Reached[7]: 8 nodes 1 leaves 4.26141e+09 minterms +4261412864 +4.26141e+9 +From[8]: 9 nodes 1 leaves 1.67772e+07 minterms +Reached[8]: 9 nodes 1 leaves 4.27819e+09 minterms +4278190080 +4.27819e+9 +From[9]: 10 nodes 1 leaves 8.38861e+06 minterms +Reached[9]: 10 nodes 1 leaves 4.28658e+09 minterms +4286578688 +4.28657e+9 +From[10]: 11 nodes 1 leaves 4.1943e+06 minterms +Reached[10]: 11 nodes 1 leaves 4.29077e+09 minterms +4290772992 +4.29077e+9 +From[11]: 12 nodes 1 leaves 2.09715e+06 minterms +Reached[11]: 12 nodes 1 leaves 4.29287e+09 minterms +4292870144 +4.29287e+9 +From[12]: 13 nodes 1 leaves 1.04858e+06 minterms +Reached[12]: 13 nodes 1 leaves 4.29392e+09 minterms +4293918720 +4.29391e+9 +From[13]: 14 nodes 1 leaves 524288 minterms +Reached[13]: 14 nodes 1 leaves 4.29444e+09 minterms +4294443008 +4.29444e+9 +From[14]: 15 nodes 1 leaves 262144 minterms +Reached[14]: 15 nodes 1 leaves 4.29471e+09 minterms +4294705152 +4.29470e+9 +From[15]: 16 nodes 1 leaves 131072 minterms +Reached[15]: 16 nodes 1 leaves 4.29484e+09 minterms +4294836224 +4.29483e+9 +From[16]: 17 nodes 1 leaves 65536 minterms +Reached[16]: 17 nodes 1 leaves 4.2949e+09 minterms +4294901760 +4.29490e+9 +From[17]: 18 nodes 1 leaves 32768 minterms +Reached[17]: 18 nodes 1 leaves 4.29493e+09 minterms +4294934528 +4.29493e+9 +From[18]: 19 nodes 1 leaves 16384 minterms +Reached[18]: 19 nodes 1 leaves 4.29495e+09 minterms +4294950912 +4.29495e+9 +From[19]: 20 nodes 1 leaves 8192 minterms +Reached[19]: 20 nodes 1 leaves 4.29496e+09 minterms +4294959104 +4.29495e+9 +From[20]: 21 nodes 1 leaves 4096 minterms +Reached[20]: 21 nodes 1 leaves 4.29496e+09 minterms +4294963200 +4.29496e+9 +From[21]: 22 nodes 1 leaves 2048 minterms +Reached[21]: 22 nodes 1 leaves 4.29497e+09 minterms +4294965248 +4.29496e+9 +From[22]: 23 nodes 1 leaves 1024 minterms +Reached[22]: 23 nodes 1 leaves 4.29497e+09 minterms +4294966272 +4.29496e+9 +From[23]: 24 nodes 1 leaves 512 minterms +Reached[23]: 24 nodes 1 leaves 4.29497e+09 minterms +4294966784 +4.29496e+9 +From[24]: 25 nodes 1 leaves 256 minterms +Reached[24]: 25 nodes 1 leaves 4.29497e+09 minterms +4294967040 +4.29496e+9 +From[25]: 26 nodes 1 leaves 128 minterms +Reached[25]: 26 nodes 1 leaves 4.29497e+09 minterms +4294967168 +4.29496e+9 +From[26]: 27 nodes 1 leaves 64 minterms +Reached[26]: 27 nodes 1 leaves 4.29497e+09 minterms +4294967232 +4.29496e+9 +From[27]: 28 nodes 1 leaves 32 minterms +Reached[27]: 28 nodes 1 leaves 4.29497e+09 minterms +4294967264 +4.29496e+9 +From[28]: 29 nodes 1 leaves 16 minterms +Reached[28]: 29 nodes 1 leaves 4.29497e+09 minterms +4294967280 +4.29496e+9 +From[29]: 30 nodes 1 leaves 8 minterms +Reached[29]: 30 nodes 1 leaves 4.29497e+09 minterms +4294967288 +4.29496e+9 +From[30]: 31 nodes 1 leaves 4 minterms +Reached[30]: 31 nodes 1 leaves 4.29497e+09 minterms +4294967292 +4.29496e+9 +From[31]: 32 nodes 1 leaves 2 minterms +Reached[31]: 32 nodes 1 leaves 4.29497e+09 minterms +4294967294 +4.29496e+9 +From[32]: 33 nodes 1 leaves 1 minterms +Reached[32]: 33 nodes 1 leaves 4.29497e+09 minterms +4294967295 +4.29496e+9 +depth = 32 +R: 33 nodes 1 leaves 4.29497e+09 minterms +Order at the end of reachability analysis +1 2 34 33 66 32 65 31 +64 63 30 29 62 28 61 60 +27 59 26 58 25 57 24 56 +23 55 22 54 21 20 53 19 +52 18 51 17 50 16 49 15 +48 14 47 13 46 12 45 11 +44 10 43 3 36 4 37 5 +38 6 39 7 40 8 41 42 +9 +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000000 +Maximum number of variable swaps per reordering: 1000000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: yes +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: no +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 10 +Arc violation threshold: 10 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 2178 +**** CUDD non-modifiable parameters **** +Memory in use: 5461692 +Peak number of nodes: 7154 +Peak number of live nodes: 4004 +Number of BDD variables: 97 +Number of ZDD variables: 0 +Number of cache entries: 65536 +Number of cache look-ups: 48730 +Number of cache hits: 20857 +Number of cache insertions: 27828 +Number of cache collisions: 997 +Number of cache deletions: 20076 +Cache used slots = 17.56% (expected 10.31%) +Soft limit for cache size: 100352 +Number of buckets in unique table: 25088 +Used buckets in unique table: 12.29% (expected 12.30%) +Number of BDD and ADD nodes: 3533 +Number of ZDD nodes: 0 +Number of dead BDD and ADD nodes: 3186 +Number of dead ZDD nodes: 0 +Total number of nodes allocated: 23948 +Total number of nodes reclaimed: 3937 +Garbage collections so far: 15 +Time for garbage collection: 0.00 sec +Reorderings so far: 15 +Time for reordering: 0.46 sec +Final size: 275 +total time = 0.47 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 0.5 seconds +System time 0.0 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131815K +Virtual data size = 297K + data size initialized = 25K + data size uninitialized = 137K + data size sbrk = 135K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 0 +Minor page faults = 1754 +Swaps = 0 +Input blocks = 0 +Output blocks = 0 +Context switch (voluntary) = 1 +Context switch (involuntary) = 21 diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/nanotrav.1 b/resources/3rdparty/cudd-2.5.0/nanotrav/nanotrav.1 new file mode 100644 index 000000000..ba50f469b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/nanotrav.1 @@ -0,0 +1,379 @@ +.\" $Id: nanotrav.1,v 1.23 2009/02/21 06:00:31 fabio Exp fabio $ +.\" +.TH NANOTRAV 1 "18 June 2002" "Release 0.11" +.SH NAME +nanotrav \- a simple state graph traversal program +.SH SYNOPSIS +.B nanotrav +[option ...] +.SH DESCRIPTION + +nanotrav builds the BDDs of a circuit and applies various reordering +methods to the BDDs. It then traverses the state transition graph of +the circuit if the circuit is sequential, and if the user so requires. +nanotrav is based on the CUDD package. The ordering of the variables +is affected by three sets of options: the options that specify the +initial order (-order -ordering); the options that specify the +reordering while the BDDs are being built (-autodyn -automethod); and +the options to specify the final reordering (-reordering +-genetic). Notice that both -autodyn and -automethod must be specified +to get dynamic reordering. The first enables reordering, while the +second says what method to use. +.SH OPTIONS +.TP 10 +.B \fIfile\fB +read input in blif format from \fIfile\fR. +.TP 10 +.B \-f \fIfile\fB +read options from \fIfile\fR. +.TP 10 +.B \-trav +traverse the state transition graph after building the BDDs. This +option has effect only if the circuit is sequential. The initial +states for traversal are taken from the blif file. +.TP 10 +.B \-depend +perform dependent variable analysis after traversal. +.TP 10 +.B \-from \fImethod\fB +use \fImethod\fR to choose the frontier states for image computation +during traversal. Allowed methods are: \fInew\fR (default), \fIreached\fR, +\fIrestrict\fR, \fIcompact\fR, \fIsqueeze\fR, \fIsubset\fR, \fIsuperset\fR. +.TP 10 +.B \-groupnsps \fImethod\fB +use \fImethod\fR to group the corresponding current and next state +variables. Allowed methods are: \fInone\fR (default), \fIdefault\fR, +\fIfixed\fR. +.TP 10 +.B \-image \fImethod\fB +use \fImethod\fR for image computation during traversal. Allowed +methods are: \fImono\fR (default), \fIpart\fR, \fIdepend\fR, and +\fIclip\fR. +.TP 10 +.B \-depth \fIn\fB +use \fIn\fR to derive the clipping depth for image +computation. It should be a number between 0 and 1. The default value +is 1 (no clipping). +.TP 10 +.B \-verify \fIfile\fB +perform combinational verification checking for equivalence to +the network in \fIfile\fR. The two networks being compared must use +the same names for inputs, outputs, and present and next state +variables. The method used for verification is extremely +simplistic. BDDs are built for all outputs of both networks, and are +then compared. +.TP 10 +.B \-closure +perform reachability analysis using the transitive closure of the +transition relation. +.TP 10 +.B \-cdepth \fIn\fB +use \fIn\fR to derive the clipping depth for transitive closure +computation. It should be a number between 0 and 1. The default value +is 1 (no clipping). +.TP 10 +.B \-envelope +compute the greatest fixed point of the state transition +relation. (This greatest fixed point is also called the outer envelope +of the graph.) +.TP 10 +.B \-scc +compute the strongly connected components of the state transition +graph. The algorithm enumerates the SCCs; therefore it stops after a +small number of them has been computed. +.TP 10 +.B \-maxflow +compute the maximum flow in the network defined by the state graph. +.TP 10 +.B \-sink \fIfile\fB +read the sink for maximum flow computation from \fIfile\fR. The source +is given by the initial states. +.TP 10 +.B \-shortpaths \fImethod\fB +compute the distances between states. Allowed methods are: \fInone\fR +(default), \fIbellman\fR, \fIfloyd\fR, and \fIsquare\fR. +.TP 10 +.B \-selective +use selective tracing variant of the \fIsquare\fR method for shortest +paths. +.TP 10 +.B \-part +compute the conjunctive decomposition of the transition relation. The +network must be sequential for the test to take place. +.TP 10 +.B \-sign +compute signatures. For each output of the circuit, all inputs are +assigned a signature. The signature is the fraction of minterms in the +ON\-set of the positive cofactor of the output with respect to the +input. Signatures are useful in identifying the equivalence of circuits +with unknown input or output correspondence. +.TP 10 +.B \-zdd +perform a simple test of ZDD functions. This test is not executed if +-delta is also specified, because it uses the BDDs of the primary +outputs of the circuit. These are converted to ZDDs and the ZDDs are +then converted back to BDDs and checked against the original ones. A +few more functions are exercised and reordering is applied if it is +enabled. Then irredundant sums of products are produced for the +primary outputs. +.TP 10 +.B \-cover +print irredundant sums of products for the primary outputs. This +option implies \fB\-zdd\fR. +.TP 10 +.B \-second \fIfile\fB +read a second network from \fIfile\fR. Currently, if this option is +specified, a test of BDD minimization algorithms is performed using +the largest output of the second network as constraint. Inputs of the +two networks with the same names are merged. +.TP 10 +.B \-density +test BDD approximation functions. +.TP 10 +.B \-approx \fImethod\fB +if \fImethod\fR is \fIunder\fR (default) perform underapproximation +when BDDs are approximated. If \fImethod\fR is \fIover\fR perform +overapproximation when BDDs are approximated. +.TP 10 +.B \-threshold \fIn\fB +Use \fIn\fR as threshold when approximating BDDs. +.TP 10 +.B \-quality \fIn\fB +Use \fIn\fR (a floating point number) as quality factor when +approximating BDDs. Default value is 1. +.TP 10 +.B \-decomp +test BDD decomposition functions. +.TP 10 +.B \-cofest +test cofactor estimation functions. +.TP 10 +.B \-clip \fIn file\fB +test clipping functions using \fIn\fR to determine the clipping depth +and taking one operand from the network in \fIfile\fR. +.TP 10 +.B \-dctest \fIfile\fB +test functions for equality and containment under don't care +conditions taking the don't care conditions from \fIfile\fR. +.TP 10 +.B \-closest +test function that finds a cube in a BDD at minimum Hamming distance +from another BDD. +.TP 10 +.B \-clauses +test function that extracts two-literal clauses from a DD. +.TP 10 +.B \-char2vect +perform a simple test of the conversion from characteristic function +to functional vector. If the network is sequential, the test is +applied to the monolithic transition relation; otherwise to the primary +outputs. +.TP 10 +.B \-local +build local BDDs for each gate of the circuit. This option is not in +effect if traversal, outer envelope computation, or maximum flow +computation are requested. The local BDD of a gate is in terms of its +local inputs. +.TP 10 +.B \-cache \fIn\fB +set the initial size of the computed table to \fIn\fR. +.TP 10 +.B \-slots \fIn\fB +set the initial size of each unique subtable to \fIn\fR. +.TP 10 +.B \-maxmem \fIn\fB +set the target maximum memory occupation to \fIn\fR MB. If this +parameter is not specified or if \fIn\fR is 0, then a suitable value +is computed automatically. +.TP 10 +.B \-memhard \fIn\fB +set the hard limit to memory occupation to \fIn\fR MB. If this +parameter is not specified or if \fIn\fR is 0, no hard limit is +enforced by the program. +.TP 10 +.B \-maxlive \fIn\fB +set the hard limit to the number of live BDD nodes to \fIn\fR. If +this parameter is not specified, the limit is four billion nodes. +.TP 10 +.B \-dumpfile \fIfile\fB +dump BDDs to \fIfile\fR. The BDDs are dumped just before program +termination. (Hence, after reordering, if reordering is specified.) +.TP 10 +.B \-dumpblif +use blif format for dump of BDDs (default is dot format). If blif is +used, the BDDs are dumped as a network of multiplexers. The dot format +is suitable for input to the dot program, which produces a +drawing of the BDDs. +.TP 10 +.B \-dumpmv +use blif-MV format for dump of BDDs. The BDDs are dumped as a network +of multiplexers. +.TP 10 +.B \-dumpdaVinci +use daVinci format for dump of BDDs. +.TP 10 +.B \-dumpddcal +use DDcal format for dump of BDDs. This option may produce an invalid +output if the variable and output names of the BDDs being dumped do +not comply with the restrictions imposed by the DDcal format. +.TP 10 +.B \-dumpfact +use factored form format for dump of BDDs. This option must be used +with caution because the size of the output is proportional to the +number of paths in the BDD. +.TP 10 +.B \-storefile \fIfile\fB +Save the BDD of the reachable states to \fIfile\fR. The BDD is stored at +the iteration specified by \fB\-store\fR. This option uses the format of +the \fIdddmp\fR library. Together with \fB\-loadfile\fR, it implements a +primitive checkpointing capability. It is primitive because the transition +relation is not saved; because the frontier states are not saved; and +because only one check point can be specified. +.TP 10 +.B \-store \fIn\fB +Save the BDD of the reached states at iteration \fIn\fR. This option +requires \fB\-storefile\fR. +.TP 10 +.B \-loadfile \fIfile\fB +Load the BDD of the initial states from \fIfile\fR. This option uses the +format of the \fIdddmp\fR library. Together with \fB\-storefile\fR, it +implements a primitive checkpointing capability. +.TP 10 +.B \-nobuild +do not build the BDDs. Quit after determining the initial variable +order. +.TP 10 +.B \-drop +drop BDDs for intermediate nodes as soon as possible. If this option is +not specified, the BDDs for the intermediate nodes of the circuit are +dropped just before the final reordering. +.TP 10 +.B \-delta +build BDDs only for the next state functions of a sequential circuit. +.TP 10 +.B \-node +build BDD only for \fInode\fR. +.TP 10 +.B \-order \fIfile\fB +read the variable order from \fIfile\fR. This file must contain the +names of the inputs (and present state variables) in the desired order. +Names must be separated by white space or newlines. +.TP 10 +.B \-ordering \fImethod\fB +use \fImethod\fR to derive an initial variable order. \fImethod\fR can +be one of \fIhw\fR, \fIdfs\fR. Method \fIhw\fR uses the order in which the +inputs are listed in the circuit description. +.TP 10 +.B \-autodyn +enable dynamic reordering. By default, dynamic reordering is disabled. +If enabled, the default method is sifting. +.TP 10 +.B \-first \fIn\fB +do first dynamic reordering when the BDDs reach \fIn\fR nodes. +The default value is 4004. (Don't ask why.) +.TP 10 +.B \-countdead +include dead nodes in node count when deciding whether to reorder +dynamically. By default, only live nodes are counted. +.TP 10 +.B \-growth \fIn\fB +maximum percentage by which the BDDs may grow while sifting one +variable. The default value is 20. +.TP 10 +.B \-automethod \fImethod\fB +use \fImethod\fR for dynamic reordering of the BDDs. \fImethod\fR can +be one of none, random, pivot, sifting, converge, symm, cosymm, group, +cogroup, win2, win3, win4, win2conv, win3conv, win4conv, annealing, +genetic, exact. The default method is sifting. +.TP 10 +.B \-reordering \fImethod\fB +use \fImethod\fR for the final reordering of the BDDs. \fImethod\fR can +be one of none, random, pivot, sifting, converge, symm, cosymm, group, +cogroup, win2, win3, win4, win2conv, win3conv, win4conv, annealing, +genetic, exact. The default method is none. +.TP 10 +.B \-genetic +run the genetic algorithm after the final reordering (which in this case +is no longer final). This allows the genetic algorithm to have one good +solution generated by, say, sifting, in the initial population. +.TP 10 +.B \-groupcheck \fImethod\fB +use \fImethod\fR for the the creation of groups in group sifting. +\fImethod\fR can be one of nocheck, check5, check7. Method check5 uses +extended symmetry as aggregation criterion; group7, in addition, also +uses the second difference criterion. The default value is check7. +.TP 10 +.B \-arcviolation \fIn\fB +percentage of arcs that violate the symmetry condition in the aggregation +check of group sifting. Should be between 0 and 100. The default value is +10. A larger value causes more aggregation. +.TP 10 +.B \-symmviolation \fIn\fB +percentage of nodes that violate the symmetry condition in the aggregation +check of group sifting. Should be between 0 and 100. The default value is +10. A larger value causes more aggregation. +.TP 10 +.B \-recomb \fIn\fB +threshold used in the second difference criterion for aggregation. (Used +by check7.) The default value is 0. A larger value causes more +aggregation. It can be either positive or negative. +.TP 10 +.B \-tree \fIfile\fB +read the variable group tree from \fIfile\fR. The format of this file is +a sequence of triplets: \fIlb ub flag\fR. Each triplet describes a +group: \fIlb\fR is the lowest index of the group; \fIub\fR is the +highest index of the group; \fIflag\fR can be either D (default) or F +(fixed). Fixed groups are not reordered. +.TP 10 +.B \-genepop \fIn\fB +size of the population for genetic algorithm. By default, the size of +the population is 3 times the number of variables, with a maximum of 120. +.TP 10 +.B \-genexover \fIn\fB +number of crossovers at each generation for the genetic algorithm. By +default, the number of crossovers is 3 times the number of variables, +with a maximum of 50. +.TP 10 +.B \-seed \fIn\fB +random number generator seed for the genetic algorithm and the random +and pivot reordering methods. +.TP 10 +.B \-progress +report progress when building the BDDs for a network. This option +causes the name of each primary output or next state function to be +printed after its BDD is built. It does not take effect if local BDDs +are requested. +.TP 10 +.B -p \fIn\fB +verbosity level. If negative, the program is very quiet. Larger values cause +more information to be printed. +.SH SEE ALSO +The documentation for the CUDD package explains the various +reordering methods. + +The documentation for the MTR package provides details on the variable +groups. + +dot(1) +.SH REFERENCES +F. Somenzi, +"Efficient Manipulation of Decision Diagrams," +Software Tools for Technology Transfer, +vol. 3, no. 2, pp. 171-181, 2001. + +S. Panda, F. Somenzi, and B. F. Plessier, +"Symmetry Detection and Dynamic Variable Ordering of Decision Diagrams," +IEEE International Conference on Computer-Aided Design, +pp. 628-631, November 1994. + +S. Panda and F. Somenzi, +"Who Are the Variables in Your Neighborhood," +IEEE International Conference on Computer-Aided Design, +pp. 74-77, November 1995. + +G. D. Hachtel and F. Somenzi, +"A Symbolic Algorithm for Maximum Flow in 0-1 Networks," +IEEE International Conference on Computer-Aided Design, +pp. 403-406, November 1993. +.SH AUTHOR +Fabio Somenzi, University of Colorado at Boulder. diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntr.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ntr.c new file mode 100644 index 000000000..3e07cd55b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntr.c @@ -0,0 +1,2988 @@ +/**CFile*********************************************************************** + + FileName [ntr.c] + + PackageName [ntr] + + Synopsis [A very simple reachability analysis program.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define NTR_MAX_DEP_SIZE 20 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: ntr.c,v 1.28 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +static const char *onames[] = { "T", "R" }; /* names of functions to be dumped */ +static double *signatures; /* signatures for all variables */ +static BnetNetwork *staticNet; /* pointer to network used by qsort + ** comparison function */ +static DdNode **staticPart; /* pointer to parts used by qsort + ** comparison function */ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * makecube (DdManager *dd, DdNode **x, int n); +static void ntrInitializeCount (BnetNetwork *net, NtrOptions *option); +static void ntrCountDFS (BnetNetwork *net, BnetNode *node); +static DdNode * ntrImage (DdManager *dd, NtrPartTR *TR, DdNode *from, NtrOptions *option); +static DdNode * ntrPreimage (DdManager *dd, NtrPartTR *T, DdNode *from); +static DdNode * ntrChooseFrom (DdManager *dd, DdNode *neW, DdNode *reached, NtrOptions *option); +static DdNode * ntrUpdateReached (DdManager *dd, DdNode *oldreached, DdNode *to); +static int ntrLatchDependencies (DdManager *dd, DdNode *reached, BnetNetwork *net, NtrOptions *option); +static NtrPartTR * ntrEliminateDependencies (DdManager *dd, NtrPartTR *TR, DdNode **states, NtrOptions *option); +static int ntrUpdateQuantificationSchedule (DdManager *dd, NtrPartTR *T); +static int ntrSignatureCompare (int * ptrX, int * ptrY); +static int ntrSignatureCompare2 (int * ptrX, int * ptrY); +static int ntrPartCompare (int * ptrX, int * ptrY); +static char ** ntrAllocMatrix (int nrows, int ncols); +static void ntrFreeMatrix (char **matrix); +static void ntrPermuteParts (DdNode **a, DdNode **b, int *comesFrom, int *goesTo, int size); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Builds DDs for a network outputs and next state + functions.] + + Description [Builds DDs for a network outputs and next state + functions. The method is really brain-dead, but it is very simple. + Returns 1 in case of success; 0 otherwise. Some inputs to the network + may be shared with another network whose DDs have already been built. + In this case we want to share the DDs as well.] + + SideEffects [the dd fields of the network nodes are modified. Uses the + count fields of the nodes.] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_buildDDs( + BnetNetwork * net /* network for which DDs are to be built */, + DdManager * dd /* DD manager */, + NtrOptions * option /* option structure */, + BnetNetwork * net2 /* companion network with which inputs may be shared */) +{ + int pr = option->verb; + int result; + int i; + BnetNode *node, *node2; + + /* If some inputs or present state variables are shared with + ** another network, we initialize their BDDs from that network. + */ + if (net2 != NULL) { + for (i = 0; i < net->npis; i++) { + if (!st_lookup(net->hash,net->inputs[i],&node)) { + return(0); + } + if (!st_lookup(net2->hash,net->inputs[i],&node2)) { + /* This input is not shared. */ + result = Bnet_BuildNodeBDD(dd,node,net->hash, + option->locGlob,option->nodrop); + if (result == 0) return(0); + } else { + if (node2->dd == NULL) return(0); + node->dd = node2->dd; + Cudd_Ref(node->dd); + node->var = node2->var; + node->active = node2->active; + } + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + return(0); + } + if (!st_lookup(net2->hash,net->latches[i][1],&node2)) { + /* This present state variable is not shared. */ + result = Bnet_BuildNodeBDD(dd,node,net->hash, + option->locGlob,option->nodrop); + if (result == 0) return(0); + } else { + if (node2->dd == NULL) return(0); + node->dd = node2->dd; + Cudd_Ref(node->dd); + node->var = node2->var; + node->active = node2->active; + } + } + } else { + /* First assign variables to inputs if the order is provided. + ** (Either in the .blif file or in an order file.) + */ + if (option->ordering == PI_PS_FROM_FILE) { + /* Follow order given in input file. First primary inputs + ** and then present state variables. + */ + for (i = 0; i < net->npis; i++) { + if (!st_lookup(net->hash,net->inputs[i],&node)) { + return(0); + } + result = Bnet_BuildNodeBDD(dd,node,net->hash, + option->locGlob,option->nodrop); + if (result == 0) return(0); + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + return(0); + } + result = Bnet_BuildNodeBDD(dd,node,net->hash, + option->locGlob,option->nodrop); + if (result == 0) return(0); + } + } else if (option->ordering == PI_PS_GIVEN) { + result = Bnet_ReadOrder(dd,option->orderPiPs,net,option->locGlob, + option->nodrop); + if (result == 0) return(0); + } else { + result = Bnet_DfsVariableOrder(dd,net); + if (result == 0) return(0); + } + } + /* At this point the BDDs of all primary inputs and present state + ** variables have been built. */ + + /* Currently noBuild doesn't do much. */ + if (option->noBuild == TRUE) + return(1); + + if (option->locGlob == BNET_LOCAL_DD) { + node = net->nodes; + while (node != NULL) { + result = Bnet_BuildNodeBDD(dd,node,net->hash,BNET_LOCAL_DD,TRUE); + if (result == 0) { + return(0); + } + if (pr > 2) { + (void) fprintf(stdout,"%s",node->name); + Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr); + } + node = node->next; + } + } else { /* option->locGlob == BNET_GLOBAL_DD */ + /* Create BDDs with DFS from the primary outputs and the next + ** state functions. If the inputs had not been ordered yet, + ** this would result in a DFS order for the variables. + */ + + ntrInitializeCount(net,option); + + if (option->node != NULL && + option->closestCube == FALSE && option->dontcares == FALSE) { + if (!st_lookup(net->hash,option->node,&node)) { + return(0); + } + result = Bnet_BuildNodeBDD(dd,node,net->hash,BNET_GLOBAL_DD, + option->nodrop); + if (result == 0) return(0); + } else { + if (option->stateOnly == FALSE) { + for (i = 0; i < net->npos; i++) { + if (!st_lookup(net->hash,net->outputs[i],&node)) { + continue; + } + result = Bnet_BuildNodeBDD(dd,node,net->hash, + BNET_GLOBAL_DD,option->nodrop); + if (result == 0) return(0); + if (option->progress) { + (void) fprintf(stdout,"%s\n",node->name); + } +#if 0 + Cudd_PrintDebug(dd,node->dd,net->ninputs,option->verb); +#endif + } + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][0],&node)) { + continue; + } + result = Bnet_BuildNodeBDD(dd,node,net->hash,BNET_GLOBAL_DD, + option->nodrop); + if (result == 0) return(0); + if (option->progress) { + (void) fprintf(stdout,"%s\n",node->name); + } +#if 0 + Cudd_PrintDebug(dd,node->dd,net->ninputs,option->verb); +#endif + } + } + /* Make sure all inputs have a DD and dereference the DDs of + ** the nodes that are not reachable from the outputs. + */ + for (i = 0; i < net->npis; i++) { + if (!st_lookup(net->hash,net->inputs[i],&node)) { + return(0); + } + result = Bnet_BuildNodeBDD(dd,node,net->hash,BNET_GLOBAL_DD, + option->nodrop); + if (result == 0) return(0); + if (node->count == -1) Cudd_RecursiveDeref(dd,node->dd); + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + return(0); + } + result = Bnet_BuildNodeBDD(dd,node,net->hash,BNET_GLOBAL_DD, + option->nodrop); + if (result == 0) return(0); + if (node->count == -1) Cudd_RecursiveDeref(dd,node->dd); + } + + /* Dispose of the BDDs of the internal nodes if they have not + ** been dropped already. + */ + if (option->nodrop == TRUE) { + for (node = net->nodes; node != NULL; node = node->next) { + if (node->dd != NULL && node->count != -1 && + (node->type == BNET_INTERNAL_NODE || + node->type == BNET_INPUT_NODE || + node->type == BNET_PRESENT_STATE_NODE)) { + Cudd_RecursiveDeref(dd,node->dd); + if (node->type == BNET_INTERNAL_NODE) node->dd = NULL; + } + } + } + } + + return(1); + +} /* end of buildDD */ + + +/**Function******************************************************************** + + Synopsis [Builds the transition relation for a network.] + + Description [Builds the transition relation for a network. Returns a + pointer to the transition relation structure if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +NtrPartTR * +Ntr_buildTR( + DdManager * dd /* manager */, + BnetNetwork * net /* network */, + NtrOptions * option /* options */, + int image /* image type: monolithic ... */) +{ + NtrPartTR *TR; + DdNode *T, *delta, *support, *scan, *tmp, *preiabs, *prepabs; + DdNode **part, **absicubes, **abspcubes, **nscube, *mnscube; + DdNode **x, **y; + DdNode **pi; + int i; + int xlevel; + BnetNode *node; + int *schedule; + int depth = 0; + + /* Initialize transition relation structure. */ + TR = ALLOC(NtrPartTR,1); + if (TR == NULL) goto endgame; + TR->nlatches = net->nlatches; + if (image == NTR_IMAGE_MONO) { + TR->nparts = 1; + } else if (image == NTR_IMAGE_PART || image == NTR_IMAGE_CLIP || + image == NTR_IMAGE_DEPEND) { + TR->nparts = net->nlatches; + } else { + (void) fprintf(stderr,"Unrecognized image method (%d). Using part.\n", + image); + TR->nparts = net->nlatches; + } + TR->factors = Ntr_InitHeap(TR->nlatches); + if (TR->factors == NULL) goto endgame; + /* Allocate arrays for present state and next state variables. */ + TR->x = x = ALLOC(DdNode *,TR->nlatches); + if (x == NULL) goto endgame; + TR->y = y = ALLOC(DdNode *,TR->nlatches); + if (y == NULL) goto endgame; + /* Allocate array for primary input variables. */ + pi = ALLOC(DdNode *,net->npis); + if (pi == NULL) goto endgame; + /* Allocate array for partitioned transition relation. */ + part = ALLOC(DdNode *,net->nlatches); + if (part == NULL) goto endgame; + /* Allocate array of next state cubes. */ + nscube = ALLOC(DdNode *,net->nlatches); + if (nscube == NULL) goto endgame; + /* Allocate array for quantification schedule and initialize it. */ + schedule = ALLOC(int,Cudd_ReadSize(dd)); + if (schedule == NULL) goto endgame; + for (i = 0; i < Cudd_ReadSize(dd); i++) { + schedule[i] = -1; + } + + /* Create partitioned transition relation from network. */ + TR->xw = Cudd_ReadOne(dd); + Cudd_Ref(TR->xw); + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + goto endgame; + } + x[i] = node->dd; + Cudd_Ref(x[i]); + /* Add present state variable to cube TR->xw. */ + tmp = Cudd_bddAnd(dd,TR->xw,x[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,TR->xw); + TR->xw = tmp; + /* Create new y variable immediately above the x variable. */ + xlevel = Cudd_ReadPerm(dd,x[i]->index); + y[i] = Cudd_bddNewVarAtLevel(dd,xlevel); + Cudd_Ref(y[i]); + /* Initialize cube of next state variables for this part. */ + nscube[i] = y[i]; + Cudd_Ref(nscube[i]); + /* Group present and next state variable if so requested. */ + if (option->groupnsps != NTR_GROUP_NONE) { + int method = option->groupnsps == NTR_GROUP_DEFAULT ? + MTR_DEFAULT : MTR_FIXED; + if (Cudd_MakeTreeNode(dd,y[i]->index,2,method) == NULL) + goto endgame; + } + /* Get next state function and create transition relation part. */ + if (!st_lookup(net->hash,net->latches[i][0],&node)) { + goto endgame; + } + delta = node->dd; + if (image != NTR_IMAGE_DEPEND) { + part[i] = Cudd_bddXnor(dd,delta,y[i]); + if (part[i] == NULL) goto endgame; + } else { + part[i] = delta; + } + Cudd_Ref(part[i]); + /* Collect scheduling info for this delta. At the end of this loop + ** schedule[i] == j means that the variable of index i does not + ** appear in any part with index greater than j, unless j == -1, + ** in which case the variable appears in no part. + */ + support = Cudd_Support(dd,delta); + Cudd_Ref(support); + scan = support; + while (!Cudd_IsConstant(scan)) { + schedule[scan->index] = i; + scan = Cudd_T(scan); + } + Cudd_RecursiveDeref(dd,support); + } + + /* Collect primary inputs. */ + for (i = 0; i < net->npis; i++) { + if (!st_lookup(net->hash,net->inputs[i],&node)) { + goto endgame; + } + pi[i] = node->dd; + tmp = Cudd_bddAnd(dd,TR->xw,pi[i]); + if (tmp == NULL) goto endgame; Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,TR->xw); + TR->xw = tmp; + } + + /* Build abstraction cubes. First primary input variables that go + ** in the abstraction cubes for both monolithic and partitioned + ** transition relations. */ + absicubes = ALLOC(DdNode *, net->nlatches); + if (absicubes == NULL) goto endgame; + abspcubes = ALLOC(DdNode *, net->nlatches); + if (abspcubes == NULL) goto endgame; + + for (i = 0; i < net->nlatches; i++) { + absicubes[i] = Cudd_ReadOne(dd); + Cudd_Ref(absicubes[i]); + } + preiabs = Cudd_ReadOne(dd); + Cudd_Ref(preiabs); + + for (i = 0; i < net->npis; i++) { + int j = pi[i]->index; + int k = schedule[j]; + if (k >= 0) { + tmp = Cudd_bddAnd(dd,absicubes[k],pi[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,absicubes[k]); + absicubes[k] = tmp; + } else { + tmp = Cudd_bddAnd(dd,preiabs,pi[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,preiabs); + preiabs = tmp; + } + } + FREE(pi); + + /* Build preimage abstraction cubes from image abstraction cubes. */ + for (i = 0; i < net->nlatches; i++) { + abspcubes[i] = Cudd_bddAnd(dd,absicubes[i],nscube[i]); + if (abspcubes[i] == NULL) return(NULL); + Cudd_Ref(abspcubes[i]); + } + Cudd_Ref(prepabs = preiabs); + + /* For partitioned transition relations we add present state variables + ** to the image abstraction cubes. */ + if (image != NTR_IMAGE_MONO) { + for (i = 0; i < net->nlatches; i++) { + int j = x[i]->index; + int k = schedule[j]; + if (k >= 0) { + tmp = Cudd_bddAnd(dd,absicubes[k],x[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,absicubes[k]); + absicubes[k] = tmp; + } else { + tmp = Cudd_bddAnd(dd,preiabs,x[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,preiabs); + preiabs = tmp; + } + } + } + FREE(schedule); + + if (image != NTR_IMAGE_MONO) { + TR->part = part; + TR->icube = absicubes; + TR->pcube = abspcubes; + TR->nscube = nscube; + TR->preiabs = preiabs; + TR->prepabs = prepabs; + return(TR); + } + + /* Here we are building a monolithic TR. */ + + /* Reinitialize the cube of variables to be quantified before + ** image computation. */ + Cudd_RecursiveDeref(dd,preiabs); + preiabs = Cudd_ReadOne(dd); + Cudd_Ref(preiabs); + + if (option->imageClip != 1.0) { + depth = (int) ((double) Cudd_ReadSize(dd) * option->imageClip); + } + + /* Collapse transition relation. */ + T = Cudd_ReadOne(dd); + Cudd_Ref(T); + mnscube = Cudd_ReadOne(dd); + Cudd_Ref(mnscube); + for (i = 0; i < net->nlatches; i++) { + /* Eliminate the primary inputs that do not appear in other parts. */ + if (depth != 0) { + tmp = Cudd_bddClippingAndAbstract(dd,T,part[i],absicubes[i], + depth,option->approx); + } else { + tmp = Cudd_bddAndAbstract(dd,T,part[i],absicubes[i]); + } + Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,part[i]); + Cudd_RecursiveDeref(dd,absicubes[i]); + Cudd_RecursiveDeref(dd,abspcubes[i]); + if (option->threshold >= 0) { + if (option->approx) { + T = Cudd_RemapOverApprox(dd,tmp,2*net->nlatches, + option->threshold,option->quality); + } else { + T = Cudd_RemapUnderApprox(dd,tmp,2*net->nlatches, + option->threshold,option->quality); + } + } else { + T = tmp; + } + if (T == NULL) return(NULL); + Cudd_Ref(T); + Cudd_RecursiveDeref(dd,tmp); + /* Add the next state variables of this part to the cube of all + ** next state variables. */ + tmp = Cudd_bddAnd(dd,mnscube,nscube[i]); + if (tmp == NULL) return(NULL); + Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,mnscube); + mnscube = tmp; + Cudd_RecursiveDeref(dd,nscube[i]); + (void) printf("@"); fflush(stdout); + } + (void) printf("\n"); +#if 0 + (void) printf("T"); Cudd_PrintDebug(dd,T,2*net->nlatches,2); +#endif + + /* Clean up. */ + FREE(absicubes); + FREE(abspcubes); + FREE(part); + FREE(nscube); + + TR->part = part = ALLOC(DdNode *,1); + if (part == NULL) goto endgame; + part[0] = T; + + /* Build cube of x (present state) variables for abstraction. */ + TR->icube = absicubes = ALLOC(DdNode *,1); + if (absicubes == NULL) goto endgame; + absicubes[0] = makecube(dd,x,TR->nlatches); + if (absicubes[0] == NULL) return(0); + Cudd_Ref(absicubes[0]); + /* Build cube of y (next state) variables for abstraction. */ + TR->pcube = abspcubes = ALLOC(DdNode *,1); + if (abspcubes == NULL) goto endgame; + abspcubes[0] = makecube(dd,y,TR->nlatches); + if (abspcubes[0] == NULL) return(0); + Cudd_Ref(abspcubes[0]); + TR->preiabs = preiabs; + TR->prepabs = prepabs; + + TR->nscube = ALLOC(DdNode *,1); + if (TR->nscube == NULL) return(NULL); + TR->nscube[0] = mnscube; + + return(TR); + +endgame: + + return(NULL); + +} /* end of Ntr_buildTR */ + + +/**Function******************************************************************** + + Synopsis [Frees the transition relation for a network.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Ntr_freeTR( + DdManager * dd, + NtrPartTR * TR) +{ + int i; + for (i = 0; i < TR->nlatches; i++) { + Cudd_RecursiveDeref(dd,TR->x[i]); + Cudd_RecursiveDeref(dd,TR->y[i]); + } + FREE(TR->x); + FREE(TR->y); + for (i = 0; i < TR->nparts; i++) { + Cudd_RecursiveDeref(dd,TR->part[i]); + Cudd_RecursiveDeref(dd,TR->icube[i]); + Cudd_RecursiveDeref(dd,TR->pcube[i]); + Cudd_RecursiveDeref(dd,TR->nscube[i]); + } + FREE(TR->part); + FREE(TR->icube); + FREE(TR->pcube); + FREE(TR->nscube); + Cudd_RecursiveDeref(dd,TR->preiabs); + Cudd_RecursiveDeref(dd,TR->prepabs); + Cudd_RecursiveDeref(dd,TR->xw); + for (i = 0; i < TR->factors->nslots; i++) { + Cudd_RecursiveDeref(dd, (DdNode *) TR->factors->slots[i].item); + } + Ntr_FreeHeap(TR->factors); + FREE(TR); + + return; + +} /* end of Ntr_freeTR */ + + +/**Function******************************************************************** + + Synopsis [Makes a copy of a transition relation.] + + Description [Makes a copy of a transition relation. Returns a pointer + to the copy if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_buildTR Ntr_freeTR] + +******************************************************************************/ +NtrPartTR * +Ntr_cloneTR( + NtrPartTR *TR) +{ + NtrPartTR *T; + int nparts, nlatches, i; + + T = ALLOC(NtrPartTR,1); + if (T == NULL) return(NULL); + nparts = T->nparts = TR->nparts; + nlatches = T->nlatches = TR->nlatches; + T->part = ALLOC(DdNode *,nparts); + if (T->part == NULL) { + FREE(T); + return(NULL); + } + T->icube = ALLOC(DdNode *,nparts); + if (T->icube == NULL) { + FREE(T->part); + FREE(T); + return(NULL); + } + T->pcube = ALLOC(DdNode *,nparts); + if (T->pcube == NULL) { + FREE(T->icube); + FREE(T->part); + FREE(T); + return(NULL); + } + T->x = ALLOC(DdNode *,nlatches); + if (T->x == NULL) { + FREE(T->pcube); + FREE(T->icube); + FREE(T->part); + FREE(T); + return(NULL); + } + T->y = ALLOC(DdNode *,nlatches); + if (T->y == NULL) { + FREE(T->x); + FREE(T->pcube); + FREE(T->icube); + FREE(T->part); + FREE(T); + return(NULL); + } + T->nscube = ALLOC(DdNode *,nparts); + if (T->nscube == NULL) { + FREE(T->y); + FREE(T->x); + FREE(T->pcube); + FREE(T->icube); + FREE(T->part); + FREE(T); + return(NULL); + } + T->factors = Ntr_HeapClone(TR->factors); + if (T->factors == NULL) { + FREE(T->nscube); + FREE(T->y); + FREE(T->x); + FREE(T->pcube); + FREE(T->icube); + FREE(T->part); + FREE(T); + return(NULL); + } + for (i = 0; i < T->factors->nslots; i++) { + Cudd_Ref((DdNode *) T->factors->slots[i].item); + } + for (i = 0; i < nparts; i++) { + T->part[i] = TR->part[i]; + Cudd_Ref(T->part[i]); + T->icube[i] = TR->icube[i]; + Cudd_Ref(T->icube[i]); + T->pcube[i] = TR->pcube[i]; + Cudd_Ref(T->pcube[i]); + T->nscube[i] = TR->nscube[i]; + Cudd_Ref(T->nscube[i]); + } + T->preiabs = TR->preiabs; + Cudd_Ref(T->preiabs); + T->prepabs = TR->prepabs; + Cudd_Ref(T->prepabs); + T->xw = TR->xw; + Cudd_Ref(T->xw); + for (i = 0; i < nlatches; i++) { + T->x[i] = TR->x[i]; + Cudd_Ref(T->x[i]); + T->y[i] = TR->y[i]; + Cudd_Ref(T->y[i]); + } + + return(T); + +} /* end of Ntr_cloneTR */ + + +/**Function******************************************************************** + + Synopsis [Poor man's traversal procedure.] + + Description [Poor man's traversal procedure. based on the monolithic + transition relation. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_ClosureTrav] + +******************************************************************************/ +int +Ntr_Trav( + DdManager * dd /* DD manager */, + BnetNetwork * net /* network */, + NtrOptions * option /* options */) +{ + NtrPartTR *TR; /* Transition relation */ + DdNode *init; /* initial state(s) */ + DdNode *from; + DdNode *to; + DdNode *reached; + DdNode *neW; + DdNode *one, *zero; + int depth; + int retval; + int pr = option->verb; + int initReord = Cudd_ReadReorderings(dd); + + if (option->traverse == FALSE || net->nlatches == 0) return(1); + (void) printf("Building transition relation. Time = %s\n", + util_print_time(util_cpu_time() - option->initialTime)); + one = Cudd_ReadOne(dd); + zero = Cudd_Not(one); + + /* Build transition relation and initial states. */ + TR = Ntr_buildTR(dd,net,option,option->image); + if (TR == NULL) return(0); + retval = Cudd_SetVarMap(dd,TR->x,TR->y,TR->nlatches); + (void) printf("Transition relation: %d parts %d latches %d nodes\n", + TR->nparts, TR->nlatches, + Cudd_SharingSize(TR->part, TR->nparts)); + (void) printf("Traversing. Time = %s\n", + util_print_time(util_cpu_time() - option->initialTime)); + init = Ntr_initState(dd,net,option); + if (init == NULL) return(0); + + /* Initialize From. */ + Cudd_Ref(from = init); + (void) printf("S0"); Cudd_PrintDebug(dd,from,TR->nlatches,pr); + + /* Initialize Reached. */ + Cudd_Ref(reached = from); + + /* Start traversal. */ + for (depth = 0; ; depth++) { + /* Image computation. */ + to = ntrImage(dd,TR,from,option); + if (to == NULL) { + Cudd_RecursiveDeref(dd,reached); + Cudd_RecursiveDeref(dd,from); + return(0); + } + Cudd_RecursiveDeref(dd,from); + + /* Find new states. */ + neW = Cudd_bddAnd(dd,to,Cudd_Not(reached)); + if (neW == NULL) { + Cudd_RecursiveDeref(dd,reached); + Cudd_RecursiveDeref(dd,to); + return(0); + } + Cudd_Ref(neW); + Cudd_RecursiveDeref(dd,to); + + /* Check for convergence. */ + if (neW == zero) break; + + /* Dump current reached states if requested. */ + if (option->store == depth) { + int ok = Dddmp_cuddBddStore(dd, NULL, reached, NULL, + NULL, DDDMP_MODE_TEXT, DDDMP_VARIDS, + option->storefile, NULL); + if (ok == 0) return(0); + (void) printf("Storing reached in %s after %i iterations.\n", + option->storefile, depth); + break; + } + + /* Update reached. */ + reached = ntrUpdateReached(dd,reached,neW); + if (reached == NULL) { + Cudd_RecursiveDeref(dd,neW); + return(0); + } + + /* Prepare for new iteration. */ + from = ntrChooseFrom(dd,neW,reached,option); + if (from == NULL) { + Cudd_RecursiveDeref(dd,reached); + Cudd_RecursiveDeref(dd,neW); + return(0); + } + Cudd_RecursiveDeref(dd,neW); + (void) printf("From[%d]",depth+1); + Cudd_PrintDebug(dd,from,TR->nlatches,pr); + (void) printf("Reached[%d]",depth+1); + Cudd_PrintDebug(dd,reached,TR->nlatches,pr); + if (pr > 0) { + if (!Cudd_ApaPrintMinterm(stdout, dd, reached, TR->nlatches)) + return(0); + if (!Cudd_ApaPrintMintermExp(stdout, dd, reached, TR->nlatches, 6)) + return(0); + } else { + (void) printf("\n"); + } + } + + /* Print out result. */ + (void) printf("depth = %d\n", depth); + (void) printf("R"); Cudd_PrintDebug(dd,reached,TR->nlatches,pr); + + /* Dump to file if requested. */ + if (option->bdddump) { + DdNode *dfunc[2]; /* addresses of the functions to be dumped */ + char *onames[2]; /* names of the functions to be dumped */ + dfunc[0] = TR->part[0]; onames[0] = (char *) "T"; + dfunc[1] = reached; onames[1] = (char *) "R"; + retval = Bnet_bddArrayDump(dd, net, option->dumpfile, dfunc, + onames, 2, option->dumpFmt); + if (retval == 0) return(0); + } + + if (option->depend) { + retval = ntrLatchDependencies(dd, reached, net, option); + if (retval == -1) return(0); + (void) printf("%d latches are redundant\n", retval); + } + /* Clean up. */ + Cudd_RecursiveDeref(dd,reached); + Cudd_RecursiveDeref(dd,neW); + Cudd_RecursiveDeref(dd,init); + Ntr_freeTR(dd,TR); + + if (Cudd_ReadReorderings(dd) > initReord) { + (void) printf("Order at the end of reachability analysis\n"); + retval = Bnet_PrintOrder(net,dd); + if (retval == 0) return(0); + } + return(1); + +} /* end of Ntr_Trav */ + + +/**Function******************************************************************** + + Synopsis [Computes the SCCs of the STG.] + + Description [Computes the strongly connected components of the state + transition graph. Only the first 10 SCCs are computed. Returns 1 in + case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_Trav] + +******************************************************************************/ +int +Ntr_SCC( + DdManager * dd /* DD manager */, + BnetNetwork * net /* network */, + NtrOptions * option /* options */) +{ + NtrPartTR *TR; /* Transition relation */ + DdNode *init; /* initial state(s) */ + DdNode *from; + DdNode *to; + DdNode *reached, *reaching; + DdNode *neW; + DdNode *one, *zero; + DdNode *states, *scc; + DdNode *tmp; + DdNode *SCCs[10]; + int depth; + int nscc = 0; + int retval; + int pr = option->verb; + int i; + + if (option->scc == FALSE || net->nlatches == 0) return(1); + (void) printf("Building transition relation. Time = %s\n", + util_print_time(util_cpu_time() - option->initialTime)); + one = Cudd_ReadOne(dd); + zero = Cudd_Not(one); + + /* Build transition relation and initial states. */ + TR = Ntr_buildTR(dd,net,option,option->image); + if (TR == NULL) return(0); + retval = Cudd_SetVarMap(dd,TR->x,TR->y,TR->nlatches); + (void) printf("Transition relation: %d parts %d latches %d nodes\n", + TR->nparts, TR->nlatches, + Cudd_SharingSize(TR->part, TR->nparts)); + (void) printf("Computing SCCs. Time = %s\n", + util_print_time(util_cpu_time() - option->initialTime)); + + /* Consider all SCCs, including those not reachable. */ + states = one; + Cudd_Ref(states); + + while (states != zero) { + if (nscc == 0) { + tmp = Ntr_initState(dd,net,option); + if (tmp == NULL) return(0); + init = Cudd_bddPickOneMinterm(dd,tmp,TR->x,TR->nlatches); + } else { + init = Cudd_bddPickOneMinterm(dd,states,TR->x,TR->nlatches); + } + if (init == NULL) return(0); + Cudd_Ref(init); + if (nscc == 0) { + Cudd_RecursiveDeref(dd,tmp); + } + /* Initialize From. */ + Cudd_Ref(from = init); + (void) printf("S0"); Cudd_PrintDebug(dd,from,TR->nlatches,pr); + + /* Initialize Reached. */ + Cudd_Ref(reached = from); + + /* Start forward traversal. */ + for (depth = 0; ; depth++) { + /* Image computation. */ + to = ntrImage(dd,TR,from,option); + if (to == NULL) { + return(0); + } + Cudd_RecursiveDeref(dd,from); + + /* Find new states. */ + tmp = Cudd_bddAnd(dd,to,states); + if (tmp == NULL) return(0); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,to); + neW = Cudd_bddAnd(dd,tmp,Cudd_Not(reached)); + if (neW == NULL) return(0); Cudd_Ref(neW); + Cudd_RecursiveDeref(dd,tmp); + + /* Check for convergence. */ + if (neW == zero) break; + + /* Update reached. */ + reached = ntrUpdateReached(dd,reached,neW); + if (reached == NULL) { + return(0); + } + + /* Prepare for new iteration. */ + from = ntrChooseFrom(dd,neW,reached,option); + if (from == NULL) { + return(0); + } + Cudd_RecursiveDeref(dd,neW); + (void) printf("From[%d]",depth+1); + Cudd_PrintDebug(dd,from,TR->nlatches,pr); + (void) printf("Reached[%d]",depth+1); + Cudd_PrintDebug(dd,reached,TR->nlatches,pr); + if (pr <= 0) { + (void) printf("\n"); + } + } + Cudd_RecursiveDeref(dd,neW); + + /* Express reached in terms of y variables. This allows us to + ** efficiently test for termination during the backward traversal. */ + tmp = Cudd_bddVarMap(dd,reached); + if (tmp == NULL) return(0); + Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,reached); + reached = tmp; + + /* Initialize from and reaching. */ + from = Cudd_bddVarMap(dd,init); + Cudd_Ref(from); + (void) printf("S0"); Cudd_PrintDebug(dd,from,TR->nlatches,pr); + Cudd_Ref(reaching = from); + + /* Start backward traversal. */ + for (depth = 0; ; depth++) { + /* Preimage computation. */ + to = ntrPreimage(dd,TR,from); + if (to == NULL) { + return(0); + } + Cudd_RecursiveDeref(dd,from); + + /* Find new states. */ + tmp = Cudd_bddAnd(dd,to,reached); + if (tmp == NULL) return(0); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,to); + neW = Cudd_bddAnd(dd,tmp,Cudd_Not(reaching)); + if (neW == NULL) return(0); Cudd_Ref(neW); + Cudd_RecursiveDeref(dd,tmp); + + /* Check for convergence. */ + if (neW == zero) break; + + /* Update reaching. */ + reaching = ntrUpdateReached(dd,reaching,neW); + if (reaching == NULL) { + return(0); + } + + /* Prepare for new iteration. */ + from = ntrChooseFrom(dd,neW,reaching,option); + if (from == NULL) { + return(0); + } + Cudd_RecursiveDeref(dd,neW); + (void) printf("From[%d]",depth+1); + Cudd_PrintDebug(dd,from,TR->nlatches,pr); + (void) printf("Reaching[%d]",depth+1); + Cudd_PrintDebug(dd,reaching,TR->nlatches,pr); + if (pr <= 0) { + (void) printf("\n"); + } + } + + scc = Cudd_bddAnd(dd,reached,reaching); + if (scc == NULL) { + return(0); + } + Cudd_Ref(scc); + SCCs[nscc] = Cudd_bddVarMap(dd,scc); + if (SCCs[nscc] == NULL) return(0); + Cudd_Ref(SCCs[nscc]); + Cudd_RecursiveDeref(dd,scc); + /* Print out result. */ + (void) printf("SCC[%d]",nscc); + Cudd_PrintDebug(dd,SCCs[nscc],TR->nlatches,pr); + tmp = Cudd_bddAnd(dd,states,Cudd_Not(SCCs[nscc])); + if (tmp == NULL) { + return(0); + } + Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,states); + states = tmp; + Cudd_RecursiveDeref(dd,reached); + Cudd_RecursiveDeref(dd,reaching); + Cudd_RecursiveDeref(dd,neW); + Cudd_RecursiveDeref(dd,init); + nscc++; + if (nscc > 9) break; + } + + if (states != zero) { + (void) fprintf(stdout,"More than 10 SCCs. Only the first 10 are computed.\n"); + } + + /* Dump to file if requested. */ + if (option->bdddump) { + char *sccnames[10]; /* names of the SCCs */ + sccnames[0] = (char *) "SCC0"; + sccnames[1] = (char *) "SCC1"; + sccnames[2] = (char *) "SCC2"; + sccnames[3] = (char *) "SCC3"; + sccnames[4] = (char *) "SCC4"; + sccnames[5] = (char *) "SCC5"; + sccnames[6] = (char *) "SCC6"; + sccnames[7] = (char *) "SCC7"; + sccnames[8] = (char *) "SCC8"; + sccnames[9] = (char *) "SCC9"; + retval = Bnet_bddArrayDump(dd, net, option->dumpfile, SCCs, + sccnames, nscc, option->dumpFmt); + if (retval == 0) return(0); + } + + /* Verify that the SCCs form a partition of the universe. */ + scc = zero; + Cudd_Ref(scc); + for (i = 0; i < nscc; i++) { + assert(Cudd_bddLeq(dd,SCCs[i],Cudd_Not(scc))); + tmp = Cudd_bddOr(dd,SCCs[i],scc); + if (tmp == NULL) return(0); + Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,scc); + scc = tmp; + Cudd_RecursiveDeref(dd,SCCs[i]); + } + assert(scc == Cudd_Not(states)); + + /* Clean up. */ + Cudd_RecursiveDeref(dd,scc); + Cudd_RecursiveDeref(dd,states); + Ntr_freeTR(dd,TR); + + return(1); + +} /* end of Ntr_SCC */ + + +/**Function******************************************************************** + + Synopsis [Transitive closure traversal procedure.] + + Description [Traversal procedure. based on the transitive closure of the + transition relation. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_Trav] + +******************************************************************************/ +int +Ntr_ClosureTrav( + DdManager * dd /* DD manager */, + BnetNetwork * net /* network */, + NtrOptions * option /* options */) +{ + DdNode *init; + DdNode *T; + NtrPartTR *TR; + int retval; + int pr = option->verb; /* verbosity level */ + DdNode *dfunc[2]; /* addresses of the functions to be dumped */ + char *onames[2]; /* names of the functions to be dumped */ + DdNode *reached, *reachedy, *reachedx; + + /* Traverse if requested and if the circuit is sequential. */ + if (option->closure == FALSE || net->nlatches == 0) return(1); + + TR = Ntr_buildTR(dd,net,option,NTR_IMAGE_MONO); + if (TR == NULL) return(0); + (void) printf("TR"); Cudd_PrintDebug(dd,TR->part[0],2*TR->nlatches,pr); + T = Ntr_TransitiveClosure(dd,TR,option); + if (T == NULL) return(0); + Cudd_Ref(T); + (void) printf("TC"); Cudd_PrintDebug(dd,T,2*TR->nlatches,pr); + + init = Ntr_initState(dd,net,option); + if (init == NULL) return(0); + (void) printf("S0"); Cudd_PrintDebug(dd,init,TR->nlatches,pr); + + /* Image computation. */ + if (option->closureClip != 1.0) { + int depth = (int) ((double) Cudd_ReadSize(dd) * option->closureClip); + reachedy = Cudd_bddClippingAndAbstract(dd,T,init,TR->icube[0], + depth,option->approx); + } else { + reachedy = Cudd_bddAndAbstract(dd,T,init,TR->icube[0]); + } + if (reachedy == NULL) return(0); + Cudd_Ref(reachedy); + + /* Express in terms of present state variables. */ + reachedx = Cudd_bddSwapVariables(dd,reachedy,TR->x,TR->y,TR->nlatches); + if (reachedx == NULL) return(0); + Cudd_Ref(reachedx); + Cudd_RecursiveDeref(dd,reachedy); + + /* Add initial state. */ + reached = Cudd_bddOr(dd,reachedx,init); + if (reached == NULL) return(0); + Cudd_Ref(reached); + Cudd_RecursiveDeref(dd,reachedx); + + /* Print out result. */ + (void) printf("R"); Cudd_PrintDebug(dd,reached,TR->nlatches,pr); + + /* Dump to file if requested. */ + if (option->bdddump) { + dfunc[0] = T; onames[0] = (char *) "TC"; + dfunc[1] = reached; onames[1] = (char *) "R"; + retval = Bnet_bddArrayDump(dd, net, option->dumpfile, dfunc, + onames, 2, option->dumpFmt); + if (retval == 0) return(0); + } + + /* Clean up. */ + Cudd_RecursiveDeref(dd,reached); + Cudd_RecursiveDeref(dd,init); + Cudd_RecursiveDeref(dd,T); + Ntr_freeTR(dd,TR); + + return(1); + +} /* end of Ntr_ClosureTrav */ + + +/**Function******************************************************************** + + Synopsis [Builds the transitive closure of a transition relation.] + + Description [Builds the transitive closure of a transition relation. + Returns a BDD if successful; NULL otherwise. Uses a simple squaring + algorithm.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Ntr_TransitiveClosure( + DdManager * dd, + NtrPartTR * TR, + NtrOptions * option) +{ + DdNode *T,*oldT,*Txz,*Tzy,*Tred,*square,*zcube; + DdNode **z; + int i; + int depth = 0; + int ylevel; + int done; + + if (option->image != NTR_IMAGE_MONO) return(NULL); + + /* Create array of auxiliary variables. */ + z = ALLOC(DdNode *,TR->nlatches); + if (z == NULL) + return(NULL); + for (i = 0; i < TR->nlatches; i++) { + ylevel = Cudd_ReadIndex(dd,TR->y[i]->index); + z[i] = Cudd_bddNewVarAtLevel(dd,ylevel); + if (z[i] == NULL) + return(NULL); + } + /* Build cube of auxiliary variables. */ + zcube = makecube(dd,z,TR->nlatches); + if (zcube == NULL) return(NULL); + Cudd_Ref(zcube); + + if (option->closureClip != 1.0) { + depth = (int) ((double) Cudd_ReadSize(dd) * option->imageClip); + } + + T = TR->part[0]; + Cudd_Ref(T); + for (i = 0; ; i++) { + if (option->threshold >= 0) { + if (option->approx) { + Tred = Cudd_RemapOverApprox(dd,T,TR->nlatches*2, + option->threshold, + option->quality); + } else { + Tred = Cudd_RemapUnderApprox(dd,T,TR->nlatches*2, + option->threshold, + option->quality); + } + } else { + Tred = T; + } + if (Tred == NULL) return(NULL); + Cudd_Ref(Tred); + /* Express T in terms of z and y variables. */ + Tzy = Cudd_bddSwapVariables(dd,Tred,TR->x,z,TR->nlatches); + if (Tzy == NULL) return(NULL); + Cudd_Ref(Tzy); + /* Express T in terms of x and z variables. */ + Txz = Cudd_bddSwapVariables(dd,Tred,TR->y,z,TR->nlatches); + if (Txz == NULL) return(NULL); + Cudd_Ref(Txz); + Cudd_RecursiveDeref(dd,Tred); + /* Square */ + if (depth == 0) { + square = Cudd_bddAndAbstract(dd,Txz,Tzy,zcube); + } else { + square = Cudd_bddClippingAndAbstract(dd,Txz,Tzy,zcube,depth, + option->approx); + } + if (square == NULL) return(NULL); + Cudd_Ref(square); + Cudd_RecursiveDeref(dd,Tzy); + Cudd_RecursiveDeref(dd,Txz); + oldT = T; + T = Cudd_bddOr(dd,square,TR->part[0]); + if (T == NULL) return(NULL); + Cudd_Ref(T); + Cudd_RecursiveDeref(dd,square); + done = T == oldT; + Cudd_RecursiveDeref(dd,oldT); + if (done) break; + (void) fprintf(stdout,"@"); fflush(stdout); + } + (void) fprintf(stdout, "\n"); + + Cudd_RecursiveDeref(dd,zcube); + Cudd_Deref(T); + FREE(z); + return(T); + +} /* end of Ntr_TransitiveClosure */ + + +/**Function******************************************************************** + + Synopsis [Builds the BDD of the initial state(s).] + + Description [Builds the BDD of the initial state(s). Returns a BDD + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Ntr_initState( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + DdNode *res, *x, *w, *one; + BnetNode *node; + int i; + + if (option->load) { + res = Dddmp_cuddBddLoad(dd, DDDMP_VAR_MATCHIDS, NULL, NULL, NULL, + DDDMP_MODE_DEFAULT, option->loadfile, NULL); + } else { + one = Cudd_ReadOne(dd); + Cudd_Ref(res = one); + + if (net->nlatches == 0) return(res); + + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + goto endgame; + } + x = node->dd; + switch (net->latches[i][2][0]) { + case '0': + w = Cudd_bddAnd(dd,res,Cudd_Not(x)); + break; + case '1': + w = Cudd_bddAnd(dd,res,x); + break; + default: /* don't care */ + w = res; + break; + } + + if (w == NULL) { + Cudd_RecursiveDeref(dd,res); + return(NULL); + } + Cudd_Ref(w); + Cudd_RecursiveDeref(dd,res); + res = w; + } + } + return(res); + +endgame: + + return(NULL); + +} /* end of Ntr_initState */ + + +/**Function******************************************************************** + + Synopsis [Reads a state cube from a file or creates a random one.] + + Description [Reads a state cube from a file or create a random one. + Returns a pointer to the BDD of the sink nodes if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +DdNode * +Ntr_getStateCube( + DdManager * dd, + BnetNetwork * net, + char * filename, + int pr) +{ + FILE *fp; + DdNode *cube; + DdNode *w; + char *state; + int i; + int err; + BnetNode *node; + DdNode *x; + char c[2]; + + cube = Cudd_ReadOne(dd); + if (net->nlatches == 0) { + Cudd_Ref(cube); + return(cube); + } + + state = ALLOC(char,net->nlatches+1); + if (state == NULL) + return(NULL); + state[net->nlatches] = 0; + + if (filename == NULL) { + /* Pick one random minterm. */ + for (i = 0; i < net->nlatches; i++) { + state[i] = (char) ((Cudd_Random() & 0x2000) ? '1' : '0'); + } + } else { + if ((fp = fopen(filename,"r")) == NULL) { + (void) fprintf(stderr,"Unable to open %s\n",filename); + return(NULL); + } + + /* Read string from file. Allow arbitrary amount of white space. */ + for (i = 0; !feof(fp); i++) { + err = fscanf(fp, "%1s", c); + state[i] = c[0]; + if (err == EOF || i == net->nlatches - 1) { + break; + } else if (err != 1 || strchr("012xX-", c[0]) == NULL ) { + FREE(state); + return(NULL); + } + } + err = fclose(fp); + if (err == EOF) { + FREE(state); + return(NULL); + } + } + + /* Echo the chosen state(s). */ + if (pr > 0) {(void) fprintf(stdout,"%s\n", state);} + + Cudd_Ref(cube); + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + Cudd_RecursiveDeref(dd,cube); + FREE(state); + return(NULL); + } + x = node->dd; + switch (state[i]) { + case '0': + w = Cudd_bddAnd(dd,cube,Cudd_Not(x)); + break; + case '1': + w = Cudd_bddAnd(dd,cube,x); + break; + default: /* don't care */ + w = cube; + break; + } + + if (w == NULL) { + Cudd_RecursiveDeref(dd,cube); + FREE(state); + return(NULL); + } + Cudd_Ref(w); + Cudd_RecursiveDeref(dd,cube); + cube = w; + } + + FREE(state); + return(cube); + +} /* end of Ntr_getStateCube */ + + +/**Function******************************************************************** + + Synopsis [Poor man's outer envelope computation.] + + Description [ Poor man's outer envelope computation based on the + monolithic transition relation. Returns 1 in case of success; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_Envelope( + DdManager * dd /* DD manager */, + NtrPartTR * TR /* transition relation */, + FILE * dfp /* pointer to file for DD dump */, + NtrOptions * option /* program options */) +{ + DdNode **x; /* array of x variables */ + DdNode **y; /* array of y variables */ + int ns; /* number of x and y variables */ + DdNode *dfunc[2]; /* addresses of the functions to be dumped */ + DdNode *envelope, *oldEnvelope; + DdNode *one; + int depth; + int retval; + int pr = option->verb; + int dumpFmt = option->dumpFmt; + + x = TR->x; + y = TR->y; + ns = TR->nlatches; + + one = Cudd_ReadOne(dd); + retval = Cudd_SetVarMap(dd,x,y,ns); + + /* Initialize From. */ + envelope = one; + if (envelope == NULL) return(0); + Cudd_Ref(envelope); + (void) printf("S0"); Cudd_PrintDebug(dd,envelope,ns,pr); + + /* Start traversal. */ + for (depth = 0; ; depth++) { + oldEnvelope = envelope; + /* Image computation. */ + envelope = ntrImage(dd,TR,oldEnvelope,option); + if (envelope == NULL) { + Cudd_RecursiveDeref(dd,oldEnvelope); + return(0); + } + + /* Check for convergence. */ + if (envelope == oldEnvelope) break; + + /* Prepare for new iteration. */ + Cudd_RecursiveDeref(dd,oldEnvelope); + (void) fprintf(stdout,"Envelope[%d]%s",depth+1,(pr>0)? "" : "\n"); + Cudd_PrintDebug(dd,envelope,ns,pr); + + } + /* Clean up. */ + Cudd_RecursiveDeref(dd,oldEnvelope); + + /* Print out result. */ + (void) printf("depth = %d\n", depth); + (void) printf("Envelope"); Cudd_PrintDebug(dd,envelope,ns,pr); + + /* Write dump file if requested. */ + if (dfp != NULL) { + dfunc[0] = TR->part[0]; + dfunc[1] = envelope; + if (dumpFmt == 1) { + retval = Cudd_DumpBlif(dd,2,dfunc,NULL,(char **)onames,NULL,dfp,0); + } else if (dumpFmt == 2) { + retval = Cudd_DumpDaVinci(dd,2,dfunc,NULL,(char **)onames,dfp); + } else if (dumpFmt == 3) { + retval = Cudd_DumpDDcal(dd,2,dfunc,NULL,(char **)onames,dfp); + } else if (dumpFmt == 4) { + retval = Cudd_DumpFactoredForm(dd,2,dfunc,NULL, + (char **)onames,dfp); + } else if (dumpFmt == 5) { + retval = Cudd_DumpBlif(dd,2,dfunc,NULL,(char **)onames,NULL,dfp,1); + } else { + retval = Cudd_DumpDot(dd,2,dfunc,NULL,(char **)onames,dfp); + } + if (retval != 1) { + (void) fprintf(stderr,"abnormal termination\n"); + return(0); + } + fclose(dfp); + } + + /* Clean up. */ + Cudd_RecursiveDeref(dd,envelope); + + return(1); + +} /* end of Ntr_Envelope */ + + +/**Function******************************************************************** + + Synopsis [Maximum 0-1 flow between source and sink states.] + + Description [Maximum 0-1 flow between source and sink + states. Returns 1 in case of success; 0 otherwise.] + + SideEffects [Creates two new sets of variables.] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_maxflow( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + DdNode **x = NULL; + DdNode **y = NULL; + DdNode **z = NULL; + DdNode *E = NULL; + DdNode *F = NULL; + DdNode *cut = NULL; + DdNode *sx = NULL; + DdNode *ty = NULL; + DdNode *tx = NULL; + int n; + int pr; + int ylevel; + int i; + double flow; + int result = 0; + NtrPartTR *TR; + + n = net->nlatches; + pr = option->verb; + TR = Ntr_buildTR(dd,net,option,NTR_IMAGE_MONO); + if (TR == NULL) + goto endgame; + E = TR->part[0]; + x = TR->x; + y = TR->y; + /* Create array of auxiliary variables. */ + z = ALLOC(DdNode *,n); + if (z == NULL) + goto endgame; + for (i = 0; i < n; i++) { + ylevel = Cudd_ReadIndex(dd,y[i]->index); + z[i] = Cudd_bddNewVarAtLevel(dd,ylevel); + if (z[i] == NULL) + goto endgame; + Cudd_Ref(z[i]); + } + /* Create BDDs for source and sink. */ + sx = Ntr_initState(dd,net,option); + if (sx == NULL) + goto endgame; + if (pr > 0) (void) fprintf(stdout, "Sink(s): "); + tx = Ntr_getStateCube(dd,net,option->sinkfile,pr); + if (tx == NULL) + goto endgame; + ty = Cudd_bddSwapVariables(dd,tx,x,y,n); + if (ty == NULL) + goto endgame; + Cudd_Ref(ty); + Cudd_RecursiveDeref(dd,tx); + tx = NULL; + + flow = Ntr_maximum01Flow(dd, sx, ty, E, &F, &cut, x, y, z, n, pr); + if (flow >= 0.0) + result = 1; + if (pr >= 0) { + (void) fprintf(stdout,"Maximum flow = %g\n", flow); + (void) fprintf(stdout,"E"); Cudd_PrintDebug(dd,E,2*n,pr); + (void) fprintf(stdout,"F"); Cudd_PrintDebug(dd,F,2*n,pr); + (void) fprintf(stdout,"cut"); Cudd_PrintDebug(dd,cut,2*n,pr); + } +endgame: + /* Clean up. */ + if (TR != NULL) Ntr_freeTR(dd,TR); + for (i = 0; i < n; i++) { + if (z != NULL && z[i] != NULL) Cudd_RecursiveDeref(dd,z[i]); + } + if (z != NULL) FREE(z); + if (F != NULL) Cudd_RecursiveDeref(dd,F); + if (cut != NULL) Cudd_RecursiveDeref(dd,cut); + if (sx != NULL) Cudd_RecursiveDeref(dd,sx); + if (ty != NULL) Cudd_RecursiveDeref(dd,ty); + return(result); + +} /* end of Ntr_Maxflow */ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Builds a positive cube of all the variables in x.] + + Description [Builds a positive cube of all the variables in x. Returns + a BDD for the cube if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +makecube( + DdManager * dd, + DdNode ** x, + int n) +{ + DdNode *res, *w, *one; + int i; + + one = Cudd_ReadOne(dd); + Cudd_Ref(res = one); + + for (i = n-1; i >= 0; i--) { + w = Cudd_bddAnd(dd,res,x[i]); + if (w == NULL) { + Cudd_RecursiveDeref(dd,res); + return(NULL); + } + Cudd_Ref(w); + Cudd_RecursiveDeref(dd,res); + res = w; + } + Cudd_Deref(res); + return(res); + +} /* end of makecube */ + + +/**Function******************************************************************** + + Synopsis [Initializes the count fields used to drop DDs.] + + Description [Initializes the count fields used to drop DDs. + Before actually building the BDDs, we perform a DFS from the outputs + to initialize the count fields of the nodes. The initial value of the + count field will normally coincide with the fanout of the node. + However, if there are nodes with no path to any primary output or next + state variable, then the initial value of count for some nodes will be + less than the fanout. For primary outputs and next state functions we + add 1, so that we will never try to free their DDs. The count fields + of the nodes that are not reachable from the outputs are set to -1.] + + SideEffects [Changes the count fields of the network nodes. Uses the + visited fields.] + + SeeAlso [] + +******************************************************************************/ +static void +ntrInitializeCount( + BnetNetwork * net, + NtrOptions * option) +{ + BnetNode *node; + int i; + + if (option->node != NULL && + option->closestCube == FALSE && option->dontcares == FALSE) { + if (!st_lookup(net->hash,option->node,&node)) { + (void) fprintf(stdout, "Warning: node %s not found!\n", + option->node); + } else { + ntrCountDFS(net,node); + node->count++; + } + } else { + if (option->stateOnly == FALSE) { + for (i = 0; i < net->npos; i++) { + if (!st_lookup(net->hash,net->outputs[i],&node)) { + (void) fprintf(stdout, + "Warning: output %s is not driven!\n", + net->outputs[i]); + continue; + } + ntrCountDFS(net,node); + node->count++; + } + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][0],&node)) { + (void) fprintf(stdout, + "Warning: latch input %s is not driven!\n", + net->outputs[i]); + continue; + } + ntrCountDFS(net,node); + node->count++; + } + } + + /* Clear visited flags. */ + node = net->nodes; + while (node != NULL) { + if (node->visited == 0) { + node->count = -1; + } else { + node->visited = 0; + } + node = node->next; + } + +} /* end of ntrInitializeCount */ + + +/**Function******************************************************************** + + Synopsis [Does a DFS from a node setting the count field.] + + Description [] + + SideEffects [Changes the count and visited fields of the nodes it + visits.] + + SeeAlso [ntrLevelDFS] + +******************************************************************************/ +static void +ntrCountDFS( + BnetNetwork * net, + BnetNode * node) +{ + int i; + BnetNode *auxnd; + + node->count++; + + if (node->visited == 1) { + return; + } + + node->visited = 1; + + for (i = 0; i < node->ninp; i++) { + if (!st_lookup(net->hash, node->inputs[i], &auxnd)) { + exit(2); + } + ntrCountDFS(net,auxnd); + } + +} /* end of ntrCountDFS */ + + +/**Function******************************************************************** + + Synopsis [Computes the image of a set given a transition relation.] + + Description [Computes the image of a set given a transition relation. + Returns a pointer to the result if successful; NULL otherwise. The image is + returned in terms of the present state variables; its reference count is + already increased.] + + SideEffects [None] + + SeeAlso [Ntr_Trav] + +******************************************************************************/ +static DdNode * +ntrImage( + DdManager * dd, + NtrPartTR * TR, + DdNode * from, + NtrOptions * option) +{ + int i; + DdNode *image; + DdNode *to; + NtrPartTR *T; + int depth = 0; + + if (option->image == NTR_IMAGE_CLIP) { + depth = (int) ((double) Cudd_ReadSize(dd) * option->imageClip); + } + + /* Existentially quantify the present state variables that are not + ** in the support of any next state function. */ + image = Cudd_bddExistAbstract(dd,from,TR->preiabs); + if (image == NULL) return(NULL); + Cudd_Ref(image); + if (option->image == NTR_IMAGE_DEPEND) { + /* Simplify the transition relation based on dependencies + ** and build the conjuncts from the deltas. */ + T = ntrEliminateDependencies(dd,TR,&image,option); + } else { + T = TR; + } + if (T == NULL) return(NULL); + for (i = 0; i < T->nparts; i++) { +#if 0 + (void) printf(" Intermediate product[%d]: %d nodes\n", + i,Cudd_DagSize(image)); +#endif + if (option->image == NTR_IMAGE_CLIP) { + to = Cudd_bddClippingAndAbstract(dd,T->part[i],image,T->icube[i], + depth,option->approx); + } else { + to = Cudd_bddAndAbstract(dd,T->part[i],image,T->icube[i]); + } + if (to == NULL) return(NULL); + Cudd_Ref(to); + if (option->image == NTR_IMAGE_DEPEND) { + /* Extract dependencies from intermediate product. */ + DdNode *abs, *positive, *absabs, *phi, *exnor, *tmp; + abs = Cudd_bddExistAbstract(dd,to,T->xw); + if (abs == NULL) return(NULL); Cudd_Ref(abs); + if (Cudd_bddVarIsDependent(dd,abs,T->nscube[i]) && + Cudd_EstimateCofactor(dd,abs,T->nscube[i]->index,1) <= + T->nlatches) { + int retval, sizex; + positive = Cudd_Cofactor(dd,abs,T->nscube[i]); + if (positive == NULL) return(NULL); Cudd_Ref(positive); + absabs = Cudd_bddExistAbstract(dd,abs,T->nscube[i]); + if (absabs == NULL) return(NULL); Cudd_Ref(absabs); + Cudd_RecursiveDeref(dd,abs); + phi = Cudd_bddLICompaction(dd,positive,absabs); + if (phi == NULL) return(NULL); Cudd_Ref(phi); + Cudd_RecursiveDeref(dd,positive); + Cudd_RecursiveDeref(dd,absabs); + exnor = Cudd_bddXnor(dd,T->nscube[i],phi); + if (exnor == NULL) return(NULL); Cudd_Ref(exnor); + Cudd_RecursiveDeref(dd,phi); + sizex = Cudd_DagSize(exnor); + (void) printf("new factor of %d nodes\n", sizex); + retval = Ntr_HeapInsert(T->factors,exnor,sizex); + if (retval == 0) return(NULL); + tmp = Cudd_bddExistAbstract(dd,to,T->nscube[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,to); + to = tmp; + } else { + Cudd_RecursiveDeref(dd,abs); + } + } + Cudd_RecursiveDeref(dd,image); + image = to; + } + if (option->image == NTR_IMAGE_DEPEND) { + int size1, size2; + DdNode *factor1, *factor2, *tmp; + int retval; + size1 = Cudd_DagSize(image); + retval = Ntr_HeapInsert(T->factors,image,size1); + if (retval == 0) return(NULL); + (void) printf("Merging %d factors. Independent image: %d nodes\n", + Ntr_HeapCount(T->factors), size1); + while (Ntr_HeapCount(T->factors) > 1) { + retval = Ntr_HeapExtractMin(T->factors,&factor1,&size1); + if (retval == 0) return(NULL); + retval = Ntr_HeapExtractMin(T->factors,&factor2,&size2); + if (retval == 0) return(NULL); + tmp = Cudd_bddAnd(dd,factor1,factor2); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + size1 = Cudd_DagSize(tmp); + (void) printf("new factor %d nodes\n", size1); + Cudd_RecursiveDeref(dd,factor1); + Cudd_RecursiveDeref(dd,factor2); + retval = Ntr_HeapInsert(T->factors,tmp,size1); + if (retval == 0) return(NULL); + } + retval = Ntr_HeapExtractMin(T->factors,&image,&size1); + if (retval == 0) return(NULL); + Ntr_freeTR(dd,T); + } + + /* Express image in terms of x variables. */ + to = Cudd_bddVarMap(dd,image); + if (to == NULL) { + Cudd_RecursiveDeref(dd,image); + return(NULL); + } + Cudd_Ref(to); + Cudd_RecursiveDeref(dd,image); + return(to); + +} /* end of ntrImage */ + + +/**Function******************************************************************** + + Synopsis [Computes the preimage of a set given a transition relation.] + + Description [Computes the preimage of a set given a transition relation. + Returns a pointer to the result if successful; NULL otherwise. The preimage + is returned in terms of the next state variables; its reference count is + already increased.] + + SideEffects [None] + + SeeAlso [ntrImage Ntr_SCC] + +******************************************************************************/ +static DdNode * +ntrPreimage( + DdManager * dd, + NtrPartTR * T, + DdNode * from) +{ + int i; + DdNode *preimage; + DdNode *to; + + /* Existentially quantify the present state variables that are not + ** in the support of any next state function. */ + preimage = Cudd_bddExistAbstract(dd,from,T->prepabs); + if (preimage == NULL) return(NULL); + Cudd_Ref(preimage); + for (i = 0; i < T->nparts; i++) { +#if 0 + (void) printf(" Intermediate product[%d]: %d nodes\n", + i,Cudd_DagSize(preimage)); +#endif + to = Cudd_bddAndAbstract(dd,T->part[i],preimage,T->pcube[i]); + if (to == NULL) return(NULL); + Cudd_Ref(to); + Cudd_RecursiveDeref(dd,preimage); + preimage = to; + } + + /* Express preimage in terms of x variables. */ + to = Cudd_bddVarMap(dd,preimage); + if (to == NULL) { + Cudd_RecursiveDeref(dd,preimage); + return(NULL); + } + Cudd_Ref(to); + Cudd_RecursiveDeref(dd,preimage); + return(to); + +} /* end of ntrPreimage */ + + +/**Function******************************************************************** + + Synopsis [Chooses the initial states for a BFS step.] + + Description [Chooses the initial states for a BFS step. Returns a + pointer to the chose set if successful; NULL otherwise. The + reference count of the result is already incremented.] + + SideEffects [none] + + SeeAlso [Ntr_Trav] + +******************************************************************************/ +static DdNode * +ntrChooseFrom( + DdManager * dd, + DdNode * neW, + DdNode * reached, + NtrOptions * option) +{ + DdNode *min, *c; + int threshold; + + switch (option->from) { + case NTR_FROM_NEW: + Cudd_Ref(neW); + return(neW); + case NTR_FROM_REACHED: + Cudd_Ref(reached); + return(reached); + case NTR_FROM_RESTRICT: + c = Cudd_bddOr(dd, neW, Cudd_Not(reached)); + if (c == NULL) return(NULL); + Cudd_Ref(c); + min = Cudd_bddRestrict(dd,neW,c); + if (min == NULL) { + Cudd_RecursiveDeref(dd, c); + return(NULL); + } + Cudd_Ref(min); + Cudd_RecursiveDeref(dd, c); + return(min); + case NTR_FROM_COMPACT: + c = Cudd_bddOr(dd, neW, Cudd_Not(reached)); + if (c == NULL) return(NULL); + Cudd_Ref(c); + min = Cudd_bddLICompaction(dd,neW,c); + if (min == NULL) { + Cudd_RecursiveDeref(dd, c); + return(NULL); + } + Cudd_Ref(min); + Cudd_RecursiveDeref(dd, c); + return(min); + case NTR_FROM_SQUEEZE: + min = Cudd_bddSqueeze(dd,neW,reached); + if (min == NULL) return(NULL); + Cudd_Ref(min); + return(min); + case NTR_FROM_UNDERAPPROX: + threshold = (option->threshold < 0) ? 0 : option->threshold; + min = Cudd_RemapUnderApprox(dd,neW,Cudd_SupportSize(dd,neW), + threshold,option->quality); + if (min == NULL) return(NULL); + Cudd_Ref(min); + return(min); + case NTR_FROM_OVERAPPROX: + threshold = (option->threshold < 0) ? 0 : option->threshold; + min = Cudd_RemapOverApprox(dd,neW,Cudd_SupportSize(dd,neW), + threshold,option->quality); + if (min == NULL) return(NULL); + Cudd_Ref(min); + return(min); + default: + return(NULL); + } + +} /* end of ntrChooseFrom */ + + +/**Function******************************************************************** + + Synopsis [Updates the reached states after a traversal step.] + + Description [Updates the reached states after a traversal + step. Returns a pointer to the new reached set if successful; NULL + otherwise. The reference count of the result is already incremented.] + + SideEffects [The old reached set is dereferenced.] + + SeeAlso [Ntr_Trav] + +******************************************************************************/ +static DdNode * +ntrUpdateReached( + DdManager * dd /* manager */, + DdNode * oldreached /* old reached state set */, + DdNode * to /* result of last image computation */) +{ + DdNode *reached; + + reached = Cudd_bddOr(dd,oldreached,to); + if (reached == NULL) { + Cudd_RecursiveDeref(dd,oldreached); + return(NULL); + } + Cudd_Ref(reached); + Cudd_RecursiveDeref(dd,oldreached); + return(reached); + +} /* end of ntrUpdateReached */ + + +/**Function******************************************************************** + + Synopsis [Analyzes the reached states after traversal to find + dependent latches.] + + Description [Analyzes the reached states after traversal to find + dependent latches. Returns the number of latches that can be + eliminated because they are stuck at a constant value or are + dependent on others if successful; -1 otherwise. The algorithm is + greedy and determines a local optimum, not a global one.] + + SideEffects [] + + SeeAlso [Ntr_Trav] + +******************************************************************************/ +static int +ntrLatchDependencies( + DdManager *dd, + DdNode *reached, + BnetNetwork *net, + NtrOptions *option) +{ + int i; + int howMany; /* number of latches that can be eliminated */ + DdNode *var, *newreached, *abs, *positive, *phi; + char *name; + BnetNode *node; + int initVars, finalVars; + double initStates, finalStates; + DdNode **roots; + char **onames; + int howManySmall = 0; + int *candidates; + double minStates; + int totalVars; + + (void) printf("Analyzing latch dependencies\n"); + roots = ALLOC(DdNode *, net->nlatches); + if (roots == NULL) return(-1); + onames = ALLOC(char *, net->nlatches); + if (onames == NULL) return(-1); + + candidates = ALLOC(int,net->nlatches); + if (candidates == NULL) return(-1); + for (i = 0; i < net->nlatches; i++) { + candidates[i] = i; + } + /* The signatures of the variables in a function are the number + ** of minterms of the positive cofactors with respect to the + ** variables themselves. */ + newreached = reached; + Cudd_Ref(newreached); + signatures = Cudd_CofMinterm(dd,newreached); + if (signatures == NULL) return(-1); + /* We now extract a positive quantity which is higher for those + ** variables that are closer to being essential. */ + totalVars = Cudd_ReadSize(dd); + minStates = signatures[totalVars]; +#if 0 + (void) printf("Raw signatures (minStates = %g)\n", minStates); + for (i = 0; i < net->nlatches; i++) { + int j = candidates[i]; + if (!st_lookup(net->hash,net->latches[j][1],(char **) &node)) { + return(-1); + } + (void) printf("%s -> %g\n", node->name, signatures[node->dd->index]); + } +#endif + for (i = 0; i < totalVars; i++) { + double z = signatures[i] / minStates - 1.0; + signatures[i] = (z >= 0.0) ? z : -z; /* make positive */ + } + staticNet = net; + qsort((void *)candidates,net->nlatches,sizeof(int), + (DD_QSFP)ntrSignatureCompare2); +#if 0 + (void) printf("Cooked signatures\n"); + for (i = 0; i < net->nlatches; i++) { + int j = candidates[i]; + if (!st_lookup(net->hash,net->latches[j][1],(char **) &node)) { + return(-1); + } + (void) printf("%s -> %g\n", node->name, signatures[node->dd->index]); + } +#endif + FREE(signatures); + + /* Extract simple dependencies. */ + for (i = 0; i < net->nlatches; i++) { + int j = candidates[i]; + if (!st_lookup(net->hash,net->latches[j][1],&node)) { + return(-1); + } + var = node->dd; + name = node->name; + if (Cudd_bddVarIsDependent(dd,newreached,var)) { + positive = Cudd_Cofactor(dd,newreached,var); + if (positive == NULL) return(-1); Cudd_Ref(positive); + abs = Cudd_bddExistAbstract(dd,newreached,var); + if (abs == NULL) return(-1); Cudd_Ref(abs); + phi = Cudd_bddLICompaction(dd,positive,abs); + if (phi == NULL) return(-1); Cudd_Ref(phi); + Cudd_RecursiveDeref(dd,positive); + if (Cudd_DagSize(phi) < NTR_MAX_DEP_SIZE) { + if (Cudd_bddLeq(dd,newreached,var)) { + (void) printf("%s is stuck at 1\n",name); + } else if (Cudd_bddLeq(dd,newreached,Cudd_Not(var))) { + (void) printf("%s is stuck at 0\n",name); + } else { + (void) printf("%s depends on the other variables\n",name); + } + roots[howManySmall] = phi; + onames[howManySmall] = util_strsav(name); + Cudd_RecursiveDeref(dd,newreached); + newreached = abs; + howManySmall++; + candidates[i] = -1; /* do not reconsider */ + } else { + Cudd_RecursiveDeref(dd,abs); + Cudd_RecursiveDeref(dd,phi); + } + } else { + candidates[i] = -1; /* do not reconsider */ + } + } + /* Now remove remaining dependent variables. */ + howMany = howManySmall; + for (i = 0; i < net->nlatches; i++) { + int j = candidates[i]; + if (j == -1) continue; + if (!st_lookup(net->hash,net->latches[j][1],&node)) { + return(-1); + } + var = node->dd; + name = node->name; + if (Cudd_bddVarIsDependent(dd,newreached,var)) { + if (Cudd_bddLeq(dd,newreached,var)) { + (void) printf("%s is stuck at 1\n",name); + } else if (Cudd_bddLeq(dd,newreached,Cudd_Not(var))) { + (void) printf("%s is stuck at 0\n",name); + } else { + (void) printf("%s depends on the other variables\n",name); + } + abs = Cudd_bddExistAbstract(dd,newreached,var); + if (abs == NULL) return(-1); Cudd_Ref(abs); + Cudd_RecursiveDeref(dd,newreached); + newreached = abs; + howMany++; + } + } + FREE(candidates); + if (howManySmall > 0) { + if (!Bnet_bddArrayDump(dd,net,(char *)"-",roots,onames,howManySmall,1)) + return(-1); + } + for (i = 0; i < howManySmall; i++) { + Cudd_RecursiveDeref(dd,roots[i]); + FREE(onames[i]); + } + FREE(roots); + FREE(onames); + + initVars = net->nlatches; + initStates = Cudd_CountMinterm(dd,reached,initVars); + finalVars = initVars - howMany; + finalStates = Cudd_CountMinterm(dd,newreached,finalVars); + if (initStates != finalStates) { + (void) printf("Error: the number of states changed from %g to %g\n", + initStates, finalStates); + return(-1); + } + (void) printf("new reached"); + Cudd_PrintDebug(dd,newreached,finalVars,option->verb); + Cudd_RecursiveDeref(dd,newreached); + return(howMany); + +} /* end of ntrLatchDependencies */ + + +/**Function******************************************************************** + + Synopsis [Eliminates dependent variables from a transition relation.] + + Description [Eliminates dependent variables from a transition + relation. Returns a simplified copy of the given transition + relation if successful; NULL otherwise.] + + SideEffects [The modified set of states is returned as a side effect.] + + SeeAlso [ntrImage] + +******************************************************************************/ +static NtrPartTR * +ntrEliminateDependencies( + DdManager *dd, + NtrPartTR *TR, + DdNode **states, + NtrOptions *option) +{ + NtrPartTR *T; /* new TR without dependent vars */ + int pr = option->verb; + int i, j; + int howMany = 0; /* number of latches that can be eliminated */ + DdNode *var, *newstates, *abs, *positive, *phi; + DdNode *support, *scan, *tmp; + int finalSize; /* size of the TR after substitutions */ + int nvars; /* vars in the support of the state set */ + int *candidates; /* vars to be considered for elimination */ + int totalVars; + double minStates; + + /* Initialize the new transition relation by copying the old one. */ + T = Ntr_cloneTR(TR); + if (T == NULL) return(NULL); + newstates = *states; + Cudd_Ref(newstates); + + /* Find and rank the candidate variables. */ + support = Cudd_Support(dd,newstates); + if (support == NULL) { + Ntr_freeTR(dd,T); + return(NULL); + } + Cudd_Ref(support); + nvars = Cudd_DagSize(support) - 1; + candidates = ALLOC(int,nvars); + if (candidates == NULL) { + Cudd_RecursiveDeref(dd,support); + Ntr_freeTR(dd,T); + return(NULL); + } + scan = support; + for (i = 0; i < nvars; i++) { + candidates[i] = scan->index; + scan = Cudd_T(scan); + } + Cudd_RecursiveDeref(dd,support); + /* The signatures of the variables in a function are the number + ** of minterms of the positive cofactors with respect to the + ** variables themselves. */ + signatures = Cudd_CofMinterm(dd,newstates); + if (signatures == NULL) { + FREE(candidates); + Ntr_freeTR(dd,T); + return(NULL); + } + /* We now extract a positive quantity which is higher for those + ** variables that are closer to being essential. */ + totalVars = Cudd_ReadSize(dd); + minStates = signatures[totalVars]; + for (i = 0; i < totalVars; i++) { + double z = signatures[i] / minStates - 1.0; + signatures[i] = (z < 0.0) ? -z : z; /* make positive */ + } + /* Sort candidates in decreasing order of signature. */ + qsort((void *)candidates,nvars,sizeof(int), + (DD_QSFP)ntrSignatureCompare); + FREE(signatures); + + /* Now process the candidates in the given order. */ + for (i = 0; i < nvars; i++) { + var = Cudd_bddIthVar(dd,candidates[i]); + if (Cudd_bddVarIsDependent(dd,newstates,var)) { + abs = Cudd_bddExistAbstract(dd,newstates,var); + if (abs == NULL) return(NULL); Cudd_Ref(abs); + positive = Cudd_Cofactor(dd,newstates,var); + if (positive == NULL) return(NULL); Cudd_Ref(positive); + phi = Cudd_bddLICompaction(dd,positive,abs); + if (phi == NULL) return(NULL); Cudd_Ref(phi); + Cudd_RecursiveDeref(dd,positive); +#if 0 + if (pr > 0) { + (void) printf("Phi"); + Cudd_PrintDebug(dd,phi,T->nlatches,pr); + } +#endif + if (Cudd_DagSize(phi) < NTR_MAX_DEP_SIZE) { + howMany++; + for (j = 0; j < T->nparts; j++) { + tmp = Cudd_bddCompose(dd,T->part[j],phi,candidates[i]); + if (tmp == NULL) return(NULL); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,T->part[j]); + T->part[j] = tmp; + } + Cudd_RecursiveDeref(dd,newstates); + newstates = abs; + } else { + Cudd_RecursiveDeref(dd,abs); + } + Cudd_RecursiveDeref(dd,phi); + } + } + FREE(candidates); + + if (pr > 0) { + finalSize = Cudd_SharingSize(T->part,T->nparts); + (void) printf("Eliminated %d vars. Transition function %d nodes.\n", + howMany,finalSize); + } + + if (!ntrUpdateQuantificationSchedule(dd,T)) return(NULL); + + /* Quantify out of states variables that no longer appear in any part. */ + Cudd_RecursiveDeref(dd,*states); + *states = Cudd_bddExistAbstract(dd,newstates,T->preiabs); + if (*states == NULL) return(NULL); Cudd_Ref(*states); + Cudd_RecursiveDeref(dd,newstates); + return(T); + +} /* end of ntrEliminateDependencies */ + + +/**Function******************************************************************** + + Synopsis [Updates the quantification schedule of a transition relation.] + + Description [Updates the quantification schedule of a transition relation. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [ntrEliminateDependencies] + +******************************************************************************/ +static int +ntrUpdateQuantificationSchedule( + DdManager *dd, + NtrPartTR *T) +{ + int i, j, k; + int *schedule; + DdNode *one, *support, *scan, *var, *tmp; + char **matrix; + int *position, *row; + char *flags; + int nparts, nvars; + int extracted; +#if 0 + int schedcost; +#endif + + nparts = T->nparts; + nvars = Cudd_ReadSize(dd); + one = Cudd_ReadOne(dd); + + /* Reinitialize the abstraction cubes. */ + Cudd_RecursiveDeref(dd,T->preiabs); + T->preiabs = one; + Cudd_Ref(one); + for (i = 0; i < nparts; i++) { + Cudd_RecursiveDeref(dd,T->icube[i]); + T->icube[i] = one; + Cudd_Ref(one); + } + + /* Initialize row permutations to the identity. */ + position = ALLOC(int,nparts); + if (position == NULL) return(0); + for (i = 0; i < nparts; i++) { + position[i] = i; + } + /* Sort parts so that parts that differ only + ** in the index of the next state variable are contiguous. */ + staticPart = T->part; + qsort((void *)position,nparts,sizeof(int), (DD_QSFP)ntrPartCompare); + /* Extract repeated parts. */ + extracted = 0; + for (i = 0; i < nparts - 1; i += j) { + int pi, pij; + DdNode *eq; + j = 1; + pi = position[i]; + eq = one; + Cudd_Ref(eq); + pij = position[i+j]; + while (Cudd_Regular(staticPart[pij]) == Cudd_Regular(staticPart[pi])) { + int comple = staticPart[pij] != staticPart[pi]; + DdNode *xnor = Cudd_bddXnor(dd,T->nscube[pi], + Cudd_NotCond(T->nscube[pij],comple)); + if (xnor == NULL) return(0); Cudd_Ref(xnor); + tmp = Cudd_bddAnd(dd,xnor,eq); + if (tmp == NULL) return(0); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,xnor); + Cudd_RecursiveDeref(dd,eq); + eq = tmp; + Cudd_RecursiveDeref(dd,T->part[pij]); + Cudd_RecursiveDeref(dd,T->icube[pij]); + Cudd_RecursiveDeref(dd,T->nscube[pij]); + T->part[pij] = NULL; + j++; + if (i+j == nparts) break; + pij = position[i+j]; + } + if (eq != one) { + int retval = Ntr_HeapInsert(T->factors,eq,Cudd_DagSize(eq)); + if (retval == 0) return(0); + extracted += j - 1; + } else { + Cudd_RecursiveDeref(dd,eq); + } + } + /* Compact the part array by removing extracted parts. */ + for (i = 0, j = 0; i < nparts; i++) { + if (T->part[i] != NULL) { + T->part[j] = T->part[i]; + T->icube[j] = T->icube[i]; + T->nscube[j] = T->nscube[i]; + j++; + } + } + nparts = T->nparts -= extracted; + (void) printf("Extracted %d repeated parts in %d factors.\n", + extracted, Ntr_HeapCount(T->factors)); + + /* Build the support matrix. Each row corresponds to a part of the + ** transition relation; each column corresponds to a variable in + ** the manager. A 1 in position (i,j) means that Part i depends + ** on Variable j. */ + matrix = ntrAllocMatrix(nparts,nvars); + if (matrix == NULL) return(0); + + /* Allocate array for quantification schedule and initialize it. */ + schedule = ALLOC(int,nvars); + if (schedule == NULL) return(0); + for (i = 0; i < nvars; i++) { + schedule[i] = -1; + } + /* Collect scheduling info for this part. At the end of this loop + ** schedule[i] == j means that the variable of index i does not + ** appear in any part with index greater than j, unless j == -1, + ** in which case the variable appears in no part. + */ + for (i = 0; i < nparts; i++) { + support = Cudd_Support(dd,T->part[i]); + if (support == NULL) return(0); Cudd_Ref(support); + scan = support; + while (!Cudd_IsConstant(scan)) { + int index = scan->index; + schedule[index] = i; + matrix[i][index] = 1; + scan = Cudd_T(scan); + } + Cudd_RecursiveDeref(dd,support); + } +#if 0 + (void) printf("Initial schedule:"); + schedcost = 0; + for (i = 0; i < nvars; i++) { + (void) printf(" %d", schedule[i]); + if (schedule[i] != -1) schedcost += schedule[i]; + } + (void) printf("\nCost = %d\n", schedcost); +#endif + + /* Initialize direct and inverse row permutations to the identity + ** permutation. */ + row = ALLOC(int,nparts); + if (row == NULL) return(0); + for (i = 0; i < nparts; i++) { + position[i] = row[i] = i; + } + + /* Sift the matrix. */ + flags = ALLOC(char,nvars); + if (flags == NULL) return(0); + for (i = 0; i < nparts; i++) { + int cost = 0; /* cost of moving the row */ + int bestcost = 0; + int posn = position[i]; + int bestposn = posn; + /* Sift up. */ + /* Initialize the flags to one is for the variables that are + ** currently scheduled to be quantified after this part gets + ** multiplied. When we cross a row of a part that depends on + ** a variable whose flag is 1, we know that the row being sifted + ** is no longer responsible for that variable. */ + for (k = 0; k < nvars; k++) { + flags[k] = (char) (schedule[k] == i); + } + for (j = posn - 1; j >= 0; j--) { + for (k = 0; k < nvars; k++) { + if (schedule[k] == row[j]) { + cost++; + } else { + flags[k] &= matrix[row[j]][k] == 0; + cost -= flags[k]; + } + } + if (cost < bestcost) { + bestposn = j; + bestcost = cost; + } + } + /* Sift down. */ + /* Reinitialize the flags. (We are implicitly undoing the sift + ** down step.) */ + for (k = 0; k < nvars; k++) { + flags[k] = (char) (schedule[k] == i); + } + for (j = posn + 1; j < nparts; j++) { + for (k = 0; k < nvars; k++) { + if (schedule[k] == row[j]) { + flags[k] |= matrix[i][k] == 1; + cost -= flags[k] == 0; + } else { + cost += flags[k]; + } + } + if (cost < bestcost) { + bestposn = j; + bestcost = cost; + } + } + /* Move to best position. */ + if (bestposn < posn) { + for (j = posn; j >= bestposn; j--) { + k = row[j]; + if (j > 0) row[j] = row[j-1]; + position[k]++; + } + } else { + for (j = posn; j <= bestposn; j++) { + k = row[j]; + if (j < nparts - 1) row[j] = row[j+1]; + position[k]--; + } + } + position[i] = bestposn; + row[bestposn] = i; + /* Fix the schedule. */ + for (k = 0; k < nvars; k++) { + if (matrix[i][k] == 1) { + if (position[schedule[k]] < bestposn) { + schedule[k] = i; + } else { + for (j = nparts - 1; j >= position[i]; j--) { + if (matrix[row[j]][k] == 1) break; + } + schedule[k] = row[j]; + } + } + } + } + ntrFreeMatrix(matrix); + FREE(flags); + + /* Update schedule to account for the permutation. */ + for (i = 0; i < nvars; i++) { + if (schedule[i] >= 0) { + schedule[i] = position[schedule[i]]; + } + } + /* Sort parts. */ + ntrPermuteParts(T->part,T->nscube,row,position,nparts); + FREE(position); + FREE(row); +#if 0 + (void) printf("New schedule:"); + schedcost = 0; + for (i = 0; i < nvars; i++) { + (void) printf(" %d", schedule[i]); + if (schedule[i] != -1) schedcost += schedule[i]; + } + (void) printf("\nCost = %d\n", schedcost); +#endif + + /* Mark the next state varibles so that they do not go in the + ** abstraction cubes. */ + for (i = 0; i < T->nlatches; i++) { + schedule[T->y[i]->index] = -2; + } + + /* Rebuild the cubes from the schedule. */ + for (i = 0; i < nvars; i++) { + k = schedule[i]; + var = Cudd_bddIthVar(dd,i); + if (k >= 0) { + tmp = Cudd_bddAnd(dd,T->icube[k],var); + if (tmp == NULL) return(0); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,T->icube[k]); + T->icube[k] = tmp; + } else if (k != -2) { + tmp = Cudd_bddAnd(dd,T->preiabs,var); + if (tmp == NULL) return(0); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,T->preiabs); + T->preiabs = tmp; + } + } + FREE(schedule); + + /* Build the conjuncts. */ + for (i = 0; i < nparts; i++) { + tmp = Cudd_bddXnor(dd,T->nscube[i],T->part[i]); + if (tmp == NULL) return(0); Cudd_Ref(tmp); + Cudd_RecursiveDeref(dd,T->part[i]); + T->part[i] = tmp; + } + + return(1); + +} /* end of ntrUpdateQuantificationSchedule */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to their signatures.] + + SideEffects [None] + +******************************************************************************/ +static int +ntrSignatureCompare( + int * ptrX, + int * ptrY) +{ + if (signatures[*ptrY] > signatures[*ptrX]) return(1); + if (signatures[*ptrY] < signatures[*ptrX]) return(-1); + return(0); + +} /* end of ntrSignatureCompare */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to their signatures.] + + SideEffects [None] + +******************************************************************************/ +static int +ntrSignatureCompare2( + int * ptrX, + int * ptrY) +{ + BnetNode *node; + int x,y; + if (!st_lookup(staticNet->hash,staticNet->latches[*ptrX][1],&node)) { + return(0); + } + x = node->dd->index; + if (!st_lookup(staticNet->hash,staticNet->latches[*ptrY][1],&node)) { + return(0); + } + y = node->dd->index; + if (signatures[x] < signatures[y]) return(1); + if (signatures[x] > signatures[y]) return(-1); + return(0); + +} /* end of ntrSignatureCompare2 */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + parts according to the BDD addresses.] + + SideEffects [None] + +******************************************************************************/ +static int +ntrPartCompare( + int * ptrX, + int * ptrY) +{ + if (staticPart[*ptrY] > staticPart[*ptrX]) return(1); + if (staticPart[*ptrY] < staticPart[*ptrX]) return(-1); + return(0); + +} /* end of ntrPartCompare */ + + +/**Function******************************************************************** + + Synopsis [Allocates a matrix.] + + Description [Allocates a matrix of char's. Returns a pointer to the matrix + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static char ** +ntrAllocMatrix( + int nrows, + int ncols) +{ + int i; + char **matrix; + + matrix = ALLOC(char *,nrows); + if (matrix == NULL) return(NULL); + matrix[0] = ALLOC(char,nrows * ncols); + if (matrix[0] == NULL) { + FREE(matrix); + return(NULL); + } + for (i = 1; i < nrows; i++) { + matrix[i] = matrix[i-1] + ncols; + } + for (i = 0; i < nrows * ncols; i++) { + matrix[0][i] = 0; + } + return(matrix); + +} /* end of ntrAllocMatrix */ + + +/**Function******************************************************************** + + Synopsis [Frees a matrix of char's.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ntrFreeMatrix( + char **matrix) +{ + FREE(matrix[0]); + FREE(matrix); + return; + +} /* end of ntrFreeMatrix */ + + +/**Function******************************************************************** + + Synopsis [Sorts parts according to given permutation.] + + Description [] + + SideEffects [The permutation arrays are turned into the identity + permutations.] + + SeeAlso [] + +******************************************************************************/ +static void +ntrPermuteParts( + DdNode **a, + DdNode **b, + int *comesFrom, + int *goesTo, + int size) +{ + int i, j; + DdNode *tmp; + + for (i = 0; i < size; i++) { + if (comesFrom[i] == i) continue; + j = comesFrom[i]; + tmp = a[i]; a[i] = a[j]; a[j] = tmp; + tmp = b[i]; b[i] = b[j]; b[j] = tmp; + comesFrom[goesTo[i]] = j; + comesFrom[i] = i; + goesTo[j] = goesTo[i]; + goesTo[i] = i; + } + return; + +} /* end of ntrPermuteParts */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntr.h b/resources/3rdparty/cudd-2.5.0/nanotrav/ntr.h new file mode 100644 index 000000000..e70b42100 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntr.h @@ -0,0 +1,283 @@ +/**CHeaderFile***************************************************************** + + FileName [ntr.h] + + PackageName [ntr] + + Synopsis [Simple-minded package to do traversal.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: ntr.h,v 1.28 2012/02/05 01:53:01 fabio Exp fabio $] + +******************************************************************************/ + +#ifndef _NTR +#define _NTR + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include "dddmp.h" +#include "bnet.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define PI_PS_FROM_FILE 0 +#define PI_PS_DFS 1 +#define PI_PS_GIVEN 2 + +#define NTR_IMAGE_MONO 0 +#define NTR_IMAGE_PART 1 +#define NTR_IMAGE_CLIP 2 +#define NTR_IMAGE_DEPEND 3 + +#define NTR_UNDER_APPROX 0 +#define NTR_OVER_APPROX 1 + +#define NTR_FROM_NEW 0 +#define NTR_FROM_REACHED 1 +#define NTR_FROM_RESTRICT 2 +#define NTR_FROM_COMPACT 3 +#define NTR_FROM_SQUEEZE 4 +#define NTR_FROM_UNDERAPPROX 5 +#define NTR_FROM_OVERAPPROX 6 + +#define NTR_GROUP_NONE 0 +#define NTR_GROUP_DEFAULT 1 +#define NTR_GROUP_FIXED 2 + +#define NTR_SHORT_NONE 0 +#define NTR_SHORT_BELLMAN 1 +#define NTR_SHORT_FLOYD 2 +#define NTR_SHORT_SQUARE 3 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct NtrOptions { + long initialTime; /* this is here for convenience */ + int verify; /* read two networks and compare them */ + char *file1; /* first network file name */ + char *file2; /* second network file name */ + int second; /* a second network is given */ + int traverse; /* do reachability analysis */ + int depend; /* do latch dependence analysis */ + int image; /* monolithic, partitioned, or clip */ + double imageClip; /* clipping depth in image computation */ + int approx; /* under or over approximation */ + int threshold; /* approximation threshold */ + int from; /* method to compute from states */ + int groupnsps; /* group present state and next state vars */ + int closure; /* use transitive closure */ + double closureClip; /* clipping depth in closure computation */ + int envelope; /* compute outer envelope */ + int scc; /* compute strongly connected components */ + int zddtest; /* do zdd test */ + int printcover; /* print ISOP covers when testing ZDDs */ + int maxflow; /* compute maximum flow in network */ + int shortPath; /* compute shortest paths in network */ + int selectiveTrace; /* use selective trace in shortest paths */ + char *sinkfile; /* file for externally provided sink node */ + int partition; /* test McMillan conjunctive partitioning */ + int char2vect; /* test char-to-vect decomposition */ + int density; /* test density-related functions */ + double quality; /* quality parameter for density functions */ + int decomp; /* test decomposition functions */ + int cofest; /* test cofactor estimation */ + double clip; /* test clipping functions */ + int dontcares; /* test equivalence and containment with DCs */ + int closestCube; /* test Cudd_bddClosestCube */ + int clauses; /* test extraction of two-literal clauses */ + int noBuild; /* do not build BDDs; just echo order */ + int stateOnly; /* ignore primary outputs */ + char *node; /* only node for which to build BDD */ + int locGlob; /* build global or local BDDs */ + int progress; /* report output names while building BDDs */ + int cacheSize; /* computed table initial size */ + unsigned long maxMemory; /* target maximum memory */ + unsigned long maxMemHard; /* maximum allowed memory */ + unsigned int maxLive; /* maximum number of nodes */ + int slots; /* unique subtable initial slots */ + int ordering; /* FANIN DFS ... */ + char *orderPiPs; /* file for externally provided order */ + Cudd_ReorderingType reordering; /* NONE RANDOM PIVOT SIFTING ... */ + int autoDyn; /* ON OFF */ + Cudd_ReorderingType autoMethod; /* RANDOM PIVOT SIFTING CONVERGE ... */ + char *treefile; /* file name for variable tree */ + int firstReorder; /* when to do first reordering */ + int countDead; /* count dead nodes toward triggering + reordering */ + int maxGrowth; /* maximum growth during reordering (%) */ + Cudd_AggregationType groupcheck; /* grouping function */ + int arcviolation; /* percent violation of arcs in + extended symmetry check */ + int symmviolation; /* percent symm violation in + extended symmetry check */ + int recomb; /* recombination parameter for grouping */ + int nodrop; /* don't drop intermediate BDDs ASAP */ + int signatures; /* computation of signatures */ + int gaOnOff; /* whether to run GA at the end */ + int populationSize; /* population size for GA */ + int numberXovers; /* number of crossovers for GA */ + int bdddump; /* ON OFF */ + int dumpFmt; /* 0 -> dot 1 -> blif 2 ->daVinci 3 -> DDcal + ** 4 -> factored form */ + char *dumpfile; /* filename for dump */ + int store; /* iteration at which to store Reached */ + char *storefile; /* filename for storing Reached */ + int load; /* load initial states from file */ + char *loadfile; /* filename for loading states */ + int verb; /* level of verbosity */ +} NtrOptions; + +typedef struct NtrHeapSlot { + void *item; + int key; +} NtrHeapSlot; + +typedef struct NtrHeap { + int size; + int nslots; + NtrHeapSlot *slots; +} NtrHeap; + +typedef struct NtrPartTR { + int nparts; /* number of parts */ + DdNode **part; /* array of parts */ + DdNode **icube; /* quantification cubes for image */ + DdNode **pcube; /* quantification cubes for preimage */ + DdNode **nscube; /* next state variables in each part */ + DdNode *preiabs; /* present state vars and inputs in no part */ + DdNode *prepabs; /* inputs in no part */ + DdNode *xw; /* cube of all present states and PIs */ + NtrHeap *factors; /* factors extracted from the image */ + int nlatches; /* number of latches */ + DdNode **x; /* array of present state variables */ + DdNode **y; /* array of next state variables */ +} NtrPartTR; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef TRUE +# define TRUE 1 +#endif +#ifndef FALSE +# define FALSE 0 +#endif + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if the two arguments are identical strings.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define STRING_EQUAL(s1,s2) (strcmp((s1),(s2)) == 0) + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern int Ntr_buildDDs (BnetNetwork *net, DdManager *dd, NtrOptions *option, BnetNetwork *net2); +extern NtrPartTR * Ntr_buildTR (DdManager *dd, BnetNetwork *net, NtrOptions *option, int image); +extern DdNode * Ntr_TransitiveClosure (DdManager *dd, NtrPartTR *TR, NtrOptions *option); +extern int Ntr_Trav (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern int Ntr_SCC (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern int Ntr_ClosureTrav (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern void Ntr_freeTR (DdManager *dd, NtrPartTR *TR); +extern NtrPartTR * Ntr_cloneTR (NtrPartTR *TR); +extern DdNode * Ntr_initState (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern DdNode * Ntr_getStateCube (DdManager *dd, BnetNetwork *net, char *filename, int pr); +extern int Ntr_Envelope (DdManager *dd, NtrPartTR *TR, FILE *dfp, NtrOptions *option); +extern int Ntr_TestMinimization (DdManager *dd, BnetNetwork *net1, BnetNetwork *net2, NtrOptions *option); +extern int Ntr_TestDensity (DdManager *dd, BnetNetwork *net1, NtrOptions *option); +extern int Ntr_TestDecomp (DdManager *dd, BnetNetwork *net1, NtrOptions *option); +extern int Ntr_VerifyEquivalence (DdManager *dd, BnetNetwork *net1, BnetNetwork *net2, NtrOptions *option); +extern int Ntr_TestCofactorEstimate (DdManager * dd, BnetNetwork * net, NtrOptions * option); +extern int Ntr_TestClipping (DdManager *dd, BnetNetwork *net1, BnetNetwork *net2, NtrOptions *option); +extern int Ntr_TestEquivAndContain (DdManager *dd, BnetNetwork *net1, BnetNetwork *net2, NtrOptions *option); +extern int Ntr_TestClosestCube (DdManager * dd, BnetNetwork * net, NtrOptions * option); +extern int Ntr_TestTwoLiteralClauses (DdManager * dd, BnetNetwork * net1, NtrOptions * option); +extern int Ntr_TestCharToVect(DdManager * dd, BnetNetwork * net1, NtrOptions * option); +extern int Ntr_maxflow (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern double Ntr_maximum01Flow (DdManager *bdd, DdNode *sx, DdNode *ty, DdNode *E, DdNode **F, DdNode **cut, DdNode **x, DdNode **y, DdNode **z, int n, int pr); +extern int Ntr_testZDD (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern int Ntr_testISOP (DdManager *dd, BnetNetwork *net, NtrOptions *option); +extern NtrHeap * Ntr_InitHeap (int size); +extern void Ntr_FreeHeap (NtrHeap *heap); +extern int Ntr_HeapInsert (NtrHeap *heap, void *item, int key); +extern int Ntr_HeapExtractMin (NtrHeap *heap, void *item, int *key); +extern int Ntr_HeapCount (NtrHeap *heap); +extern NtrHeap * Ntr_HeapClone (NtrHeap *source); +extern int Ntr_TestHeap (NtrHeap *heap, int i); +extern int Ntr_ShortestPaths (DdManager *dd, BnetNetwork *net, NtrOptions *option); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* _NTR */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntrBddTest.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrBddTest.c new file mode 100644 index 000000000..a5e1ae190 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrBddTest.c @@ -0,0 +1,2315 @@ +/**CFile*********************************************************************** + + FileName [ntrBddTest.c] + + PackageName [ntr] + + Synopsis [BDD test functions for the nanotrav program.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: ntrBddTest.c,v 1.22 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ntrTestMinimizationAux (DdManager *dd, BnetNetwork *net1, DdNode *f, char *name, DdNode *c, char *cname, NtrOptions *option); +static int ntrTestDensityAux (DdManager *dd, BnetNetwork *net, DdNode *f, char *name, NtrOptions *option); +static int ntrTestDecompAux (DdManager *dd, BnetNetwork *net, DdNode *f, char *name, NtrOptions *option); +static int ntrTestCofEstAux (DdManager * dd, BnetNetwork * net, DdNode * f, char * name, NtrOptions * option); +static int ntrTestClippingAux (DdManager *dd, BnetNetwork *net1, DdNode *f, char *name, DdNode *g, char *gname, NtrOptions *option); +static int ntrTestEquivAndContainAux (DdManager *dd, BnetNetwork *net1, DdNode *f, char *fname, DdNode *g, char *gname, DdNode *d, char *dname, NtrOptions *option); +static int ntrTestClosestCubeAux (DdManager *dd, BnetNetwork *net, DdNode *f, char *fname, DdNode *g, char *gname, DdNode **vars, NtrOptions *option); +static int ntrTestCharToVect(DdManager * dd, DdNode * f, NtrOptions *option); +#if 0 +static DdNode * ntrCompress1 (DdManager *dd, DdNode *f, int nvars, int threshold); +#endif +static DdNode * ntrCompress2 (DdManager *dd, DdNode *f, int nvars, int threshold); +static BnetNode * ntrNodeIsBuffer (BnetNode *nd, st_table *hash); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Tests BDD minimization functions.] + + Description [Tests BDD minimization functions, including + leaf-identifying compaction, squeezing, and restrict. This function + uses as constraint the first output of net2 and computes positive + and negative cofactors of all the outputs of net1. For each + cofactor, it checks whether compaction was safe (cofactor not larger + than original function) and that the expansion based on each + minimization function (used as a generalized cofactor) equals the + original function. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestMinimization( + DdManager * dd, + BnetNetwork * net1, + BnetNetwork * net2, + NtrOptions * option) +{ + DdNode *f; + DdNode *c = NULL; + char *cname = NULL; + BnetNode *node; + int i; + int result; + int nsize, csize; + + if (option->second == FALSE) return(1); + + (void) printf("Testing BDD minimization algorithms\n"); + /* Use largest output of second network as constraint. */ + csize = -1; + for (i = 0; i < net2->noutputs; i++) { + if (!st_lookup(net2->hash,net2->outputs[i],&node)) { + return(0); + } + nsize = Cudd_DagSize(node->dd); + if (nsize > csize) { + c = node->dd; + cname = node->name; + csize = nsize; + } + } + if (c == NULL || cname == NULL) return(0); + (void) printf("TEST-MINI: Constrain (%s) %d nodes\n", + cname, Cudd_DagSize(c)); + + if (option->node == NULL) { + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestMinimizationAux(dd,net1,f,node->name,c,cname, + option); + if (result == 0) return(0); + } + } else { + if (!st_lookup(net1->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestMinimizationAux(dd,net1,f,option->node,c,cname,option); + if (result == 0) return(0); + } + + return(1); + +} /* end of Ntr_TestMinimization */ + + +/**Function******************************************************************** + + Synopsis [Tests BDD density-related functions.] + + Description [Tests BDD density-related functions. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestDensity( + DdManager * dd, + BnetNetwork * net1, + NtrOptions * option) +{ + DdNode *f; + BnetNode *node; + int i; + int result; + + if (option->density == FALSE) return(1); + + (void) printf("Testing BDD density-related algorithms\n"); + if (option->node == NULL) { + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestDensityAux(dd,net1,f,node->name,option); + if (result == 0) return(0); + } + } else { + if (!st_lookup(net1->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestDensityAux(dd,net1,f,option->node,option); + if (result == 0) return(0); + } + + return(1); + +} /* end of Ntr_TestDensity */ + + +/**Function******************************************************************** + + Synopsis [Tests BDD decomposition functions.] + + Description [Tests BDD decomposition functions. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestDecomp( + DdManager * dd, + BnetNetwork * net1, + NtrOptions * option) +{ + DdNode *f; + BnetNode *node; + int i; + int result; + + if (option->decomp == FALSE) return(1); + + (void) printf("Testing BDD decomposition algorithms\n"); + if (option->node == NULL) { + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestDecompAux(dd,net1,f,node->name,option); + if (result == 0) return(0); + } + } else { + if (!st_lookup(net1->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestDecompAux(dd,net1,f,option->node,option); + if (result == 0) return(0); + } + + return(1); + +} /* end of ntrTestDecomp */ + + +/**Function******************************************************************** + + Synopsis [Verify equivalence of combinational networks.] + + Description [Verify equivalence of combinational networks. + Returns 1 if successful and if the networks are equivalent; -1 if + successful, but the networks are not equivalent; 0 otherwise. + The two networks are supposed to have the same names for inputs and + outputs. The only exception is that the second network may miss + output buffers that are present in the first network. This function tries + to match both the output and the input of the buffer.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_VerifyEquivalence( + DdManager * dd, + BnetNetwork * net1, + BnetNetwork * net2, + NtrOptions * option) +{ + BnetNode *node; + char *oname; + DdNode *odd1, *odd2; + int i; + int pr; + + (void) printf("Testing equivalence\n"); + if (net2->noutputs != net1->noutputs) { + (void) printf("The two networks have different number of outputs\n"); + (void) printf(" %s has %d outputs\n %s has %d outputs\n", + net1->name, net1->noutputs, net2->name, net2->noutputs); + return(-1); + } + if (net2->nlatches != net1->nlatches) { + (void) printf("The two networks have different number of latches\n"); + (void) printf(" %s has %d latches\n %s has %d latches\n", + net1->name, net1->nlatches, net2->name, net2->nlatches); + return(-1); + } + + pr = option->verb; + for (i = 0; i < net1->noutputs; i++) { + oname = net1->outputs[i]; + if (!st_lookup(net1->hash,oname,&node)) { + return(0); + } + odd1 = node->dd; + (void) printf("%s", oname); + Cudd_PrintDebug(dd, node->dd, Cudd_ReadSize(dd), pr); + if (!st_lookup(net2->hash,oname,&node)) { + BnetNode *inpnd; + if ((inpnd = ntrNodeIsBuffer(node,net1->hash)) == NULL || + !st_lookup(net2->hash,inpnd->name,&node)) { + (void) printf("Output %s missing from network %s\n", + oname, net2->name); + return(-1); + } else { + odd2 = inpnd->dd; + } + } else { + odd2 = node->dd; + } + if (odd1 != odd2) { + (void) printf("Output %s is not equivalent\n", oname); + return(-1); + } + } + return(1); + +} /* end of Ntr_VerifyEquivalence */ + + +/**Function******************************************************************** + + Synopsis [Tests BDD cofactor estimate functions.] + + Description [Tests BDD cofactor estimate functions. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestCofactorEstimate( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + DdNode *f; + BnetNode *node; + int i; + int result; + + if (option->cofest == FALSE) return(1); + + (void) printf("Testing BDD cofactor estimation algorithms\n"); + if (option->node == NULL) { + for (i = 0; i < net->noutputs; i++) { + if (!st_lookup(net->hash,net->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestCofEstAux(dd,net,f,node->name,option); + if (result == 0) return(0); + } + } else { + if (!st_lookup(net->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestCofEstAux(dd,net,f,option->node,option); + if (result == 0) return(0); + } + + return(1); + +} /* end of Ntr_TestCofactorEstimate */ + + +/**Function******************************************************************** + + Synopsis [Tests BDD clipping functions.] + + Description [Tests BDD clipping functions. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestClipping( + DdManager * dd, + BnetNetwork * net1, + BnetNetwork * net2, + NtrOptions * option) +{ + DdNode *f; + DdNode *g = NULL; + char *gname = NULL; + BnetNode *node; + int i; + int result; + int nsize, gsize; + + if (option->clip < 0.0) return(1); + + (void) printf("Testing BDD clipping algorithms\n"); + /* Use largest output of second network as second operand. */ + gsize = -1; + for (i = 0; i < net2->noutputs; i++) { + if (!st_lookup(net2->hash,net2->outputs[i],&node)) { + return(0); + } + nsize = Cudd_DagSize(node->dd); + if (nsize > gsize) { + g = node->dd; + gname = node->name; + gsize = nsize; + } + } + if (g == NULL || gname == NULL) return(0); + (void) printf("TEST-CLIP: Second operand (%s) %d nodes\n", + gname, Cudd_DagSize(g)); + + if (option->node == NULL) { + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestClippingAux(dd,net1,f,node->name,g,gname,option); + if (result == 0) return(0); + } + } else { + if (!st_lookup(net1->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestClippingAux(dd,net1,f,option->node,g,gname,option); + if (result == 0) return(0); + } + + return(1); + +} /* end of Ntr_TestClipping */ + + +/**Function******************************************************************** + + Synopsis [Tests BDD equivalence and containment with don't cares.] + + Description [Tests functions for BDD equivalence and containment + with don't cares, including Cudd_EquivDC and Cudd_bddLeqUnless. This + function uses as care set the first output of net2 and checkes + equivalence and containment for of all the output pairs of net1. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestEquivAndContain( + DdManager *dd, + BnetNetwork *net1, + BnetNetwork *net2, + NtrOptions *option) +{ + DdNode *f, *g; + DdNode *d = NULL; + char *dname = NULL; + BnetNode *node1, *node2; + int i, j; + int result; + int nsize, dsize; + + if (option->dontcares == FALSE) return(1); + + (void) printf("Testing BDD equivalence and containment algorithms\n"); + /* Use largest output of second network as constraint. */ + dsize = -1; + for (i = 0; i < net2->noutputs; i++) { + if (!st_lookup(net2->hash,net2->outputs[i],&node1)) { + return(0); + } + nsize = Cudd_DagSize(node1->dd); + if (nsize > dsize) { + d = node1->dd; + dname = node1->name; + dsize = nsize; + } + } + if (d == NULL || dname == NULL) return(0); + (void) printf("TEST-DC: Don't care set (%s) %d nodes\n", + dname, Cudd_DagSize(d)); + + if (option->node == NULL) { + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node1)) { + return(0); + } + f = node1->dd; + if (f == NULL) return(0); + for (j = 0; j < net1->noutputs; j++) { + if (!st_lookup(net1->hash,net1->outputs[j],&node2)) { + return(0); + } + g = node2->dd; + if (g == NULL) return(0); + result = ntrTestEquivAndContainAux(dd,net1,f,node1->name,g, + node2->name,d,dname,option); + if (result == 0) return(0); + } + } + } else { + if (!st_lookup(net1->hash,option->node,&node1)) { + return(0); + } + f = node1->dd; + if (f == NULL) return(0); + for (j = 0; j < net1->noutputs; j++) { + if (!st_lookup(net1->hash,net1->outputs[j],&node2)) { + return(0); + } + g = node2->dd; + if (g == NULL) return(0); + result = ntrTestEquivAndContainAux(dd,net1,f,option->node, + g,node2->name,d,dname,option); + if (result == 0) return(0); + } + } + + return(1); + +} /* end of Ntr_TestEquivAndContain */ + + +/**Function******************************************************************** + + Synopsis [Tests the Cudd_bddClosestCube function.] + + Description [Tests the Cudd_bddClosestCube function. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestClosestCube( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + DdNode *f, *g; + BnetNode *node1, *node2; + int i, j, nvars; + int result; + DdNode **vars; + double calls; + + if (option->closestCube == FALSE) return(1); + + (void) printf("Testing Cudd_bddClosestCube\n"); + nvars = Cudd_ReadSize(dd); + vars = ALLOC(DdNode *, nvars); + if (vars == NULL) return(0); + for (i = 0; i < nvars; i++) { + vars[i] = Cudd_bddIthVar(dd,i); + } + calls = Cudd_ReadRecursiveCalls(dd); + if (option->node == NULL) { + for (i = 0; i < net->noutputs; i++) { + if (!st_lookup(net->hash,net->outputs[i],&node1)) { + FREE(vars); + return(0); + } + f = node1->dd; + if (f == NULL) { + FREE(vars); + return(0); + } + for (j = 0; j < net->noutputs; j++) { + if (!st_lookup(net->hash,net->outputs[j],&node2)) { + FREE(vars); + return(0); + } + g = node2->dd; + if (g == NULL) { + FREE(vars); + return(0); + } + result = ntrTestClosestCubeAux(dd,net,f,node1->name,g, + node2->name,vars,option); + if (result == 0) { + FREE(vars); + return(0); + } + } + } + } else { + if (!st_lookup(net->hash,option->node,&node1)) { + FREE(vars); + return(0); + } + f = node1->dd; + if (f == NULL) { + FREE(vars); + return(0); + } + for (j = 0; j < net->noutputs; j++) { + if (!st_lookup(net->hash,net->outputs[j],&node2)) { + FREE(vars); + return(0); + } + g = node2->dd; + if (g == NULL) { + FREE(vars); + return(0); + } + result = ntrTestClosestCubeAux(dd,net,f,option->node,g, + node2->name,vars,option); + if (result == 0) { + FREE(vars); + return(0); + } + } + } + (void) printf("End of test. Performed %.0f recursive calls.\n", + Cudd_ReadRecursiveCalls(dd) - calls); + FREE(vars); + return(1); + +} /* end of Ntr_TestClosestCube */ + + +/**Function******************************************************************** + + Synopsis [Tests extraction of two-literal clauses.] + + Description [Tests extraction of two-literal clauses. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestTwoLiteralClauses( + DdManager * dd, + BnetNetwork * net1, + NtrOptions * option) +{ + DdNode *f; + BnetNode *node; + int result; + char **inames = NULL; + int i; + + if (option->clauses == FALSE) return(1); + + /* Initialize data structures. */ + inames = ALLOC(char *,Cudd_ReadSize(dd)); + if (inames == NULL) return(0); + for (i = 0; i < Cudd_ReadSize(dd); i++) { + inames[i] = NULL; + } + + /* Find the input names. */ + for (i = 0; i < net1->ninputs; i++) { + if (!st_lookup(net1->hash,net1->inputs[i],&node)) { + FREE(inames); + return(0); + } + inames[node->var] = net1->inputs[i]; + } + for (i = 0; i < net1->nlatches; i++) { + if (!st_lookup(net1->hash,net1->latches[i][1],&node)) { + FREE(inames); + return(0); + } + inames[node->var] = net1->latches[i][1]; + } + + (void) printf("Testing extraction of two literal clauses\n"); + if (option->node == NULL) { + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) { + FREE(inames); + return(0); + } + (void) printf("*** %s ***\n", net1->outputs[i]); + result = Cudd_PrintTwoLiteralClauses(dd, f, inames, NULL); + if (result == 0) { + FREE(inames); + return(0); + } + } + } else { + if (!st_lookup(net1->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) { + FREE(inames); + return(0); + } + (void) printf("*** %s ***\n", option->node); + result = Cudd_PrintTwoLiteralClauses(dd, f, inames, NULL); + if (result == 0) { + FREE(inames); + return(0); + } + } + + FREE(inames); + return(1); + +} /* end of Ntr_TestTwoLiteralClauses */ + + +/**Function******************************************************************** + + Synopsis [Test char-to-vect conversion.] + + Description [Test char-to-vect conversion. Returns 1 if successful; + 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestCharToVect( + DdManager * dd, + BnetNetwork * net1, + NtrOptions * option) +{ + DdNode *f; + int result; + BnetNode *node; + int i; + + if (option->char2vect == FALSE) return(1); + + (void) printf("Testing char-to-vect\n"); + if (net1->nlatches > 0) { + NtrPartTR *T; + T = Ntr_buildTR(dd,net1,option,NTR_IMAGE_MONO); + result = ntrTestCharToVect(dd,T->part[0],option); + Ntr_freeTR(dd,T); + } else if (option->node == NULL) { + result = 1; + for (i = 0; i < net1->noutputs; i++) { + if (!st_lookup(net1->hash,net1->outputs[i],&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + (void) printf("*** %s ***\n", net1->outputs[i]); + result = ntrTestCharToVect(dd,f,option); + if (result == 0) return(0); + } + } else { + if (!st_lookup(net1->hash,option->node,&node)) { + return(0); + } + f = node->dd; + if (f == NULL) return(0); + result = ntrTestCharToVect(dd,f,option); + } + return(result); + +} /* end of Ntr_TestCharToVect */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Processes one BDD for Ntr_TestMinimization.] + + Description [Processes one BDD for Ntr_TestMinimization. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestMinimization] + +******************************************************************************/ +static int +ntrTestMinimizationAux( + DdManager * dd, + BnetNetwork * net1, + DdNode * f, + char * name, + DdNode * c, + char * cname, + NtrOptions * option) +{ + DdNode *com1, *com0, *min1, *min0, *sq1, *sq0; + DdNode *rs1, *rs0, *cs1, *cs0, *na1, *na0, *a1, *a0; + DdNode *g, *u1, *l1, *u0, *l0; + int pr, nvars; + int sizeF, sizeMin1, sizeMin0, sizeSq1, sizeSq0, sizeCom1, sizeCom0; + int sizeRs1, sizeRs0, sizeCs1, sizeCs0, sizeNa1, sizeNa0, sizeA1, sizeA0; + static char *onames[11]; + DdNode *outputs[11]; + DdNode *fc[2]; + + pr = option->verb; + fc[0] = f; fc[1] = c; + nvars = Cudd_VectorSupportSize(dd,fc,2); + if (nvars == CUDD_OUT_OF_MEM) return(0); + (void) printf("TEST-MINI:: %s\n", name); + (void) printf("T-M "); + Cudd_PrintDebug(dd, f, nvars, pr); + sizeF = Cudd_DagSize(f); + + /* Compute positive generalized cofactor. */ + com1 = Cudd_bddLICompaction(dd, f, c); + if (com1 == NULL) { + (void) printf("TEST-MINI: LI-compaction failed (1).\n"); + return(0); + } + Cudd_Ref(com1); + (void) printf("T-M L1 "); + Cudd_PrintDebug(dd, com1, nvars, pr); + sizeCom1 = Cudd_DagSize(com1); + if (sizeCom1 > sizeF) { + (void) printf("TEST-MINI: LI-compaction not safe (1).\n"); + return(0); + } + min1 = Cudd_bddMinimize(dd, f, c); + if (min1 == NULL) { + (void) printf("TEST-MINI: minimize failed (1).\n"); + return(0); + } + Cudd_Ref(min1); + (void) printf("T-M M1 "); + Cudd_PrintDebug(dd, min1, nvars, pr); + sizeMin1 = Cudd_DagSize(min1); + if (sizeMin1 > sizeF) { + (void) printf("TEST-MINI: minimize not safe (1).\n"); + return(0); + } + rs1 = Cudd_bddRestrict(dd, f, c); + if (rs1 == NULL) { + (void) printf("TEST-MINI: restrict failed (1).\n"); + return(0); + } + Cudd_Ref(rs1); + (void) printf("T-M R1 "); + Cudd_PrintDebug(dd, rs1, nvars, pr); + sizeRs1 = Cudd_DagSize(rs1); + cs1 = Cudd_bddConstrain(dd, f, c); + if (cs1 == NULL) { + (void) printf("TEST-MINI: constrain failed (1).\n"); + return(0); + } + Cudd_Ref(cs1); + (void) printf("T-M C1 "); + Cudd_PrintDebug(dd, cs1, nvars, pr); + sizeCs1 = Cudd_DagSize(cs1); + l1 = Cudd_bddAnd(dd, f, c); + if (l1 == NULL) { + (void) printf("TEST-MINI: lower bound failed (1).\n"); + return(0); + } + Cudd_Ref(l1); + u1 = Cudd_bddOr(dd, f, Cudd_Not(c)); + if (u1 == NULL) { + (void) printf("TEST-MINI: upper bound failed (1).\n"); + return(0); + } + Cudd_Ref(u1); + (void) printf("TEST-MINI: (lb,ub) : (%d,%d) nodes\n", + Cudd_DagSize(l1), Cudd_DagSize(u1)); + sq1 = Cudd_bddSqueeze(dd, l1, u1); + if (sq1 == NULL) { + (void) printf("TEST-MINI: squeezing failed (1).\n"); + return(0); + } + Cudd_Ref(sq1); + sizeSq1 = Cudd_DagSize(sq1); + if (sizeSq1 > sizeF) { + Cudd_RecursiveDeref(dd,sq1); + sq1 = f; + Cudd_Ref(sq1); + sizeSq1 = sizeF; + } + (void) printf("T-M S1 "); + Cudd_PrintDebug(dd, sq1, nvars, pr); + na1 = Cudd_bddNPAnd(dd, f, c); + if (na1 == NULL) { + (void) printf("TEST-MINI: NPand failed (1).\n"); + return(0); + } + Cudd_Ref(na1); + (void) printf("T-M N1 "); + Cudd_PrintDebug(dd, na1, nvars, pr); + sizeNa1 = Cudd_DagSize(na1); + a1 = Cudd_bddAnd(dd, f, c); + if (a1 == NULL) { + (void) printf("TEST-MINI: and failed (1).\n"); + return(0); + } + Cudd_Ref(a1); + (void) printf("T-M A1 "); + Cudd_PrintDebug(dd, a1, nvars, pr); + sizeA1 = Cudd_DagSize(a1); + (void) printf("TEST-MINI: f %d comp %d mini %d rest %d cons %d sque %d na %d and %d\n", + sizeF, sizeCom1, sizeMin1, sizeRs1, sizeCs1, sizeSq1, sizeNa1, sizeA1); + if (option->bdddump) { + onames[0] = name; outputs[0] = f; + onames[1] = cname; outputs[1] = c; + onames[2] = (char *) "cons"; outputs[2] = cs1; + onames[3] = (char *) "rest"; outputs[3] = rs1; + onames[4] = (char *) "comp"; outputs[4] = com1; + onames[5] = (char *) "mini"; outputs[5] = min1; + onames[6] = (char *) "sqee"; outputs[6] = sq1; + onames[7] = (char *) "lb"; outputs[7] = l1; + onames[8] = (char *) "ub"; outputs[8] = u1; + onames[9] = (char *) "na"; outputs[9] = na1; + onames[10] = (char *) "and"; outputs[10] = a1; + if (!Bnet_bddArrayDump(dd, net1, option->dumpfile, outputs, onames, + 11, option->dumpFmt)) + return(0); + } + Cudd_RecursiveDeref(dd,l1); + Cudd_RecursiveDeref(dd,u1); + + /* Compute negative generalized cofactor. */ + (void) printf("TEST-MINI:: %s\n", name); + (void) printf("T-M "); + Cudd_PrintDebug(dd, f, nvars, pr); + + com0 = Cudd_bddLICompaction(dd, f, Cudd_Not(c)); + if (com0 == NULL) { + (void) printf("TEST-MINI: LI-compaction failed (2).\n"); + return(0); + } + Cudd_Ref(com0); + (void) printf("T-M L0 "); + Cudd_PrintDebug(dd, com0, nvars, pr); + sizeCom0 = Cudd_DagSize(com0); + if (sizeCom0 > sizeF) { + (void) printf("TEST-MINI: LI-compaction not safe (2).\n"); + return(0); + } + min0 = Cudd_bddMinimize(dd, f, Cudd_Not(c)); + if (min0 == NULL) { + (void) printf("TEST-MINI: minimize failed (2).\n"); + return(0); + } + Cudd_Ref(min0); + (void) printf("T-M M0 "); + Cudd_PrintDebug(dd, min0, nvars, pr); + sizeMin0 = Cudd_DagSize(min0); + if (sizeMin0 > sizeF) { + (void) printf("TEST-MINI: minimize not safe (2).\n"); + return(0); + } + rs0 = Cudd_bddRestrict(dd, f, Cudd_Not(c)); + if (rs0 == NULL) { + (void) printf("TEST-MINI: restrict failed (2).\n"); + return(0); + } + Cudd_Ref(rs0); + (void) printf("T-M R0 "); + Cudd_PrintDebug(dd, rs0, nvars, pr); + sizeRs0 = Cudd_DagSize(rs0); + cs0 = Cudd_bddConstrain(dd, f, Cudd_Not(c)); + if (cs0 == NULL) { + (void) printf("TEST-MINI: constrain failed (2).\n"); + return(0); + } + Cudd_Ref(cs0); + (void) printf("T-M C0 "); + Cudd_PrintDebug(dd, cs0, nvars, pr); + sizeCs0 = Cudd_DagSize(cs0); + + l0 = Cudd_bddAnd(dd, f, Cudd_Not(c)); + if (l0 == NULL) { + (void) printf("TEST-MINI: lower bound failed (2).\n"); + return(0); + } + Cudd_Ref(l0); + u0 = Cudd_bddOr(dd, f, c); + if (u0 == NULL) { + (void) printf("TEST-MINI: upper bound failed (2).\n"); + return(0); + } + Cudd_Ref(u0); + (void) printf("TEST-MINI: (lb,ub) : (%d,%d) nodes\n", + Cudd_DagSize(l0), Cudd_DagSize(u0)); + sq0 = Cudd_bddSqueeze(dd, l0, u0); + if (sq0 == NULL) { + (void) printf("TEST-MINI: squeezing failed (2).\n"); + return(0); + } + Cudd_Ref(sq0); + Cudd_RecursiveDeref(dd,l0); + Cudd_RecursiveDeref(dd,u0); + sizeSq0 = Cudd_DagSize(sq0); + if (sizeSq0 > sizeF) { + Cudd_RecursiveDeref(dd,sq0); + sq0 = f; + Cudd_Ref(sq0); + sizeSq0 = sizeF; + } + (void) printf("T-M S0 "); + Cudd_PrintDebug(dd, sq0, nvars, pr); + na0 = Cudd_bddNPAnd(dd, f, Cudd_Not(c)); + if (na0 == NULL) { + (void) printf("TEST-MINI: NPand failed (2).\n"); + return(0); + } + Cudd_Ref(na0); + (void) printf("T-M N0 "); + Cudd_PrintDebug(dd, na0, nvars, pr); + sizeNa0 = Cudd_DagSize(na0); + a0 = Cudd_bddAnd(dd, f, Cudd_Not(c)); + if (a0 == NULL) { + (void) printf("TEST-MINI: and failed (2).\n"); + return(0); + } + Cudd_Ref(a0); + (void) printf("T-M A0 "); + Cudd_PrintDebug(dd, a0, nvars, pr); + sizeA0 = Cudd_DagSize(a0); + (void) printf("TEST-MINI: f %d comp %d mini %d rest %d cons %d sque %d na %d, and %d\n", + sizeF, sizeCom0, sizeMin0, sizeRs0, sizeCs0, sizeSq0, sizeNa0, sizeA0); + + /* Check fundamental identity. */ + g = Cudd_bddIte(dd,c,com1,com0); + if (g == NULL) { + (void) printf("TEST-MINI: LI-compaction failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: LI-compaction failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,com1); + Cudd_RecursiveDeref(dd,com0); + Cudd_RecursiveDeref(dd,g); + g = Cudd_bddIte(dd,c,min1,min0); + if (g == NULL) { + (void) printf("TEST-MINI: minimize failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: minimize failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,min1); + Cudd_RecursiveDeref(dd,min0); + Cudd_RecursiveDeref(dd,g); + g = Cudd_bddIte(dd,c,sq1,sq0); + if (g == NULL) { + (void) printf("TEST-MINI: squeezing failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: squeezing failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,sq1); + Cudd_RecursiveDeref(dd,sq0); + Cudd_RecursiveDeref(dd,g); + g = Cudd_bddIte(dd,c,rs1,rs0); + if (g == NULL) { + (void) printf("TEST-MINI: restrict failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: restrict failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,rs1); + Cudd_RecursiveDeref(dd,rs0); + Cudd_RecursiveDeref(dd,g); + g = Cudd_bddIte(dd,c,cs1,cs0); + if (g == NULL) { + (void) printf("TEST-MINI: constrain failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: constrain failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,cs1); + Cudd_RecursiveDeref(dd,cs0); + Cudd_RecursiveDeref(dd,g); + g = Cudd_bddIte(dd,c,na1,na0); + if (g == NULL) { + (void) printf("TEST-MINI: NPand failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: NPand failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,na1); + Cudd_RecursiveDeref(dd,na0); + Cudd_RecursiveDeref(dd,g); + g = Cudd_bddIte(dd,c,a1,a0); + if (g == NULL) { + (void) printf("TEST-MINI: and failed (3).\n"); + return(0); + } + Cudd_Ref(g); + if (g != f) { + (void) printf("TEST-MINI: and failed (4).\n"); + return(0); + } + Cudd_RecursiveDeref(dd,a1); + Cudd_RecursiveDeref(dd,a0); + Cudd_RecursiveDeref(dd,g); + + return(1); + +} /* end of ntrTestMinimizationAux */ + + +/**Function******************************************************************** + + Synopsis [Processes one BDD for Ntr_TestDensity.] + + Description [Processes one BDD for Ntr_TestDensity. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestDensity ntrCompress1] + +******************************************************************************/ +static int +ntrTestDensityAux( + DdManager * dd, + BnetNetwork * net, + DdNode * f, + char * name, + NtrOptions * option) +{ + DdNode *s, *b, *hb, *sp, *ua, *c1, *c2; + int pr; + int result; + int nvars; + int size, sizeS; + double densityF, densityB, densityS, densityHB, densitySP, densityUA; + double densityC1, densityC2; + char *onames[8]; + DdNode *outputs[8]; + + result = 1; + pr = option->verb; + nvars = Cudd_SupportSize(dd,f); + if (nvars == CUDD_OUT_OF_MEM) return(0); + densityF = Cudd_Density(dd,f,nvars); + (void) printf("TEST-DENSITY:: %s (%d variables)\n", name, nvars); + if (pr > 0) { + (void) printf("T-D (%g)", densityF); + Cudd_PrintDebug(dd, f, nvars, pr); + (void) printf("T-D APA "); + if (!Cudd_ApaPrintMinterm(stdout, dd, f, nvars)) + result = 0; + } + /* Test remapping underapproximation. */ + /* s = Cudd_SubsetRemap(dd,f); */ + s = Cudd_RemapUnderApprox(dd,f,nvars,0,option->quality); + if (s == NULL) { + (void) printf("TEST-DENSITY: computation failed\n"); + return(0); + } + Cudd_Ref(s); + sizeS = Cudd_DagSize(s); + densityS = Cudd_Density(dd,s,nvars); + if (pr > 0) { + (void) printf("T-D ID (%g)", densityS); + Cudd_PrintDebug(dd, s, nvars, pr); + } + if (!Cudd_bddLeq(dd,s,f)) { + (void) printf("TEST-DENSITY: result not a subset\n"); + result = 0; + } + if (densityF > densityS) { + (void) printf("TEST-DENSITY: result less dense\n"); + /* result = 0; */ + } + size = sizeS; + /* Test biased underapproximation. */ + b = Cudd_BiasedUnderApprox(dd,f,Cudd_Not(s),nvars,0, + option->quality*1.1,option->quality*0.5); + if (b == NULL) { + (void) printf("TEST-DENSITY: computation failed\n"); + return(0); + } + Cudd_Ref(b); + densityB = Cudd_Density(dd,b,nvars); + if (pr > 0) { + (void) printf("T-D BU (%g)", densityB); + Cudd_PrintDebug(dd, b, nvars, pr); + } + if (!Cudd_bddLeq(dd,b,f)) { + (void) printf("TEST-DENSITY: result not a subset\n"); + result = 0; + } + if (densityF > densityB) { + (void) printf("TEST-DENSITY: result less dense\n"); + /* result = 0; */ + } + /* Test heavy-branch subsetting. */ + hb = Cudd_SubsetHeavyBranch(dd, f, nvars, size); + if (hb == NULL) { + (void) printf("TEST-DENSITY: HB computation failed\n"); + Cudd_RecursiveDeref(dd,s); + return(0); + } + Cudd_Ref(hb); + densityHB = Cudd_Density(dd,hb,nvars); + if (pr > 0) { + (void) printf("T-D HB (%g)", densityHB); + Cudd_PrintDebug(dd, hb, nvars, pr); + } + if (!Cudd_bddLeq(dd,hb,f)) { + (void) printf("TEST-DENSITY: HB not a subset\n"); + result = 0; + } + /* Test short paths subsetting. */ + sp = Cudd_SubsetShortPaths(dd, f, nvars, size, 0); + if (sp == NULL) { + (void) printf("TEST-DENSITY: SP computation failed\n"); + Cudd_RecursiveDeref(dd,s); + Cudd_RecursiveDeref(dd,hb); + return(0); + } + Cudd_Ref(sp); + densitySP = Cudd_Density(dd,sp,nvars); + if (pr > 0) { + (void) printf("T-D SP (%g)", densitySP); + Cudd_PrintDebug(dd, sp, nvars, pr); + } + if (!Cudd_bddLeq(dd,sp,f)) { + (void) printf("TEST-DENSITY: SP not a subset\n"); + result = 0; + } + /* Test underapproximation. */ + ua = Cudd_UnderApprox(dd,f,nvars,0,FALSE,option->quality); + if (ua == NULL) { + (void) printf("TEST-DENSITY: computation failed\n"); + Cudd_RecursiveDeref(dd,s); + Cudd_RecursiveDeref(dd,hb); + Cudd_RecursiveDeref(dd,sp); + return(0); + } + Cudd_Ref(ua); + densityUA = Cudd_Density(dd,ua,nvars); + if (pr > 0) { + (void) printf("T-D UA (%g)", densityUA); + Cudd_PrintDebug(dd, ua, nvars, pr); + } + if (!Cudd_bddLeq(dd,ua,f)) { + (void) printf("TEST-DENSITY: result not a subset\n"); + result = 0; + } + if (densityF > densityUA) { + (void) printf("TEST-DENSITY: result less dense\n"); + } + /* Test compress 2 method. */ + c1 = ntrCompress2(dd, f, nvars, size); + if (c1 == NULL) { + (void) printf("TEST-DENSITY: C1 computation failed\n"); + Cudd_RecursiveDeref(dd,s); + Cudd_RecursiveDeref(dd,hb); + Cudd_RecursiveDeref(dd,sp); + Cudd_RecursiveDeref(dd,ua); + return(0); + } + densityC1 = Cudd_Density(dd,c1,nvars); + if (pr > 0) { + (void) printf("T-D C1 (%g)", densityC1); + Cudd_PrintDebug(dd, c1, nvars, pr); + } + if (!Cudd_bddLeq(dd,c1,f)) { + (void) printf("TEST-DENSITY: C1 not a subset\n"); + result = 0; + } + /* Test compress subsetting. */ + c2 = Cudd_SubsetCompress(dd, f, nvars, size); + if (c2 == NULL) { + (void) printf("TEST-DENSITY: C2 computation failed\n"); + Cudd_RecursiveDeref(dd,s); + Cudd_RecursiveDeref(dd,hb); + Cudd_RecursiveDeref(dd,sp); + Cudd_RecursiveDeref(dd,ua); + Cudd_RecursiveDeref(dd,c1); + return(0); + } + Cudd_Ref(c2); + densityC2 = Cudd_Density(dd,c2,nvars); + if (pr > 0) { + (void) printf("T-D C2 (%g)", densityC2); + Cudd_PrintDebug(dd, c2, nvars, pr); + } + if (!Cudd_bddLeq(dd,c2,f)) { + (void) printf("TEST-DENSITY: C2 not a subset\n"); + result = 0; + } + /* Dump results if so requested. */ + if (option->bdddump) { + onames[0] = name; outputs[0] = f; + onames[1] = (char *) "id"; outputs[1] = s; + onames[2] = (char *) "bu"; outputs[2] = b; + onames[3] = (char *) "hb"; outputs[3] = hb; + onames[4] = (char *) "sp"; outputs[4] = sp; + onames[5] = (char *) "ua"; outputs[5] = ua; + onames[6] = (char *) "c1"; outputs[6] = c1; + onames[7] = (char *) "c2"; outputs[7] = c2; + result &= Bnet_bddArrayDump(dd, net, option->dumpfile, outputs, + onames, 8, option->dumpFmt); + } + + Cudd_RecursiveDeref(dd,s); + Cudd_RecursiveDeref(dd,b); + Cudd_RecursiveDeref(dd,hb); + Cudd_RecursiveDeref(dd,sp); + Cudd_RecursiveDeref(dd,ua); + Cudd_RecursiveDeref(dd,c1); + Cudd_RecursiveDeref(dd,c2); + + return(result); + +} /* end of ntrTestDensityAux */ + + +/**Function******************************************************************** + + Synopsis [Processes one BDD for Ntr_TestDecomp.] + + Description [Processes one BDD for Ntr_TestDecomp. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestDecomp] + +******************************************************************************/ +static int +ntrTestDecompAux( + DdManager * dd, + BnetNetwork * net, + DdNode * f, + char * name, + NtrOptions * option) +{ + DdNode *one, *g, *h, *product; + DdNode **A, **I, **G, **V; + int pr; + int i, result; + int nA, nI, nG, nV; + int nvars; + int sizeSa; + int sizeSi, sizeSg, sizeSv; + char *onames[9]; + DdNode *outputs[9]; + + result = 1; + pr = option->verb; + nvars = Cudd_SupportSize(dd,f); + if (nvars == CUDD_OUT_OF_MEM) return(0); + (void) printf("TEST-DECOMP:: %s (%d variables)\n", name, nvars); + if (pr > 0) { + (void) printf("T-d "); + Cudd_PrintDebug(dd, f, nvars, pr); + } + one = Cudd_ReadOne(dd); + + /* Test Cudd_bddApproxConjDecomp */ + nA = Cudd_bddApproxConjDecomp(dd,f,&A); + if (nA == 0) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + g = A[0]; + h = (nA == 2) ? A[1] : one; + sizeSa = Cudd_SharingSize(A,nA); + if (pr > 0) { + (void) printf("T-d SS : %d nodes\n", sizeSa); + (void) printf("T-d GS "); + Cudd_PrintDebug(dd, g, nvars, pr); + (void) printf("T-d HS "); + Cudd_PrintDebug(dd, h, nvars, pr); + } + product = Cudd_bddAnd(dd,g,h); + if (product == NULL) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + Cudd_Ref(product); + if (product != f) { + (void) printf("TEST-DECOMP: result not a decomposition\n"); + result = 0; + } + Cudd_RecursiveDeref(dd,product); + + /* Test Cudd_bddIterConjDecomp */ + nI = Cudd_bddIterConjDecomp(dd,f,&I); + if (nI == 0) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + g = I[0]; + h = (nI == 2) ? I[1] : one; + sizeSi = Cudd_SharingSize(I,nI); + if (pr > 0) { + (void) printf("T-d SI : %d nodes\n", sizeSi); + (void) printf("T-d GI "); + Cudd_PrintDebug(dd, g, nvars, pr); + (void) printf("T-d HI "); + Cudd_PrintDebug(dd, h, nvars, pr); + } + product = Cudd_bddAnd(dd,g,h); + if (product == NULL) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + Cudd_Ref(product); + if (product != f) { + (void) printf("TEST-DECOMP: result not a decomposition\n"); + result = 0; + } + Cudd_RecursiveDeref(dd,product); + + /* Test Cudd_bddGenConjDecomp */ + nG = Cudd_bddGenConjDecomp(dd,f,&G); + if (nG == 0) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + g = G[0]; + h = (nG == 2) ? G[1] : one; + sizeSg = Cudd_SharingSize(G,nG); + if (pr > 0) { + (void) printf("T-d SD : %d nodes\n", sizeSg); + (void) printf("T-d GD "); + Cudd_PrintDebug(dd, g, nvars, pr); + (void) printf("T-d HD "); + Cudd_PrintDebug(dd, h, nvars, pr); + } + product = Cudd_bddAnd(dd,g,h); + if (product == NULL) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + Cudd_Ref(product); + if (product != f) { + (void) printf("TEST-DECOMP: result not a decomposition\n"); + result = 0; + } + Cudd_RecursiveDeref(dd,product); + + /* Test Cudd_bddVarConjDecomp */ + nV = Cudd_bddVarConjDecomp(dd,f,&V); + if (nV == 0) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + g = V[0]; + h = (nV == 2) ? V[1] : one; + sizeSv = Cudd_SharingSize(V,nV); + if (pr > 0) { + (void) printf("T-d SQ : %d nodes\n", sizeSv); + (void) printf("T-d GQ "); + Cudd_PrintDebug(dd, g, nvars, pr); + (void) printf("T-d HQ "); + Cudd_PrintDebug(dd, h, nvars, pr); + } + product = Cudd_bddAnd(dd,g,h); + if (product == NULL) { + (void) printf("TEST-DECOMP: computation failed\n"); + return(0); + } + Cudd_Ref(product); + if (product != f) { + (void) printf("TEST-DECOMP: result not a decomposition\n"); + result = 0; + } + Cudd_RecursiveDeref(dd,product); + + /* Dump to file if requested. */ + if (option->bdddump) { + onames[0] = name; outputs[0] = f; + onames[1] = (char *) "ga"; outputs[1] = A[0]; + onames[2] = (char *) "ha"; outputs[2] = (nA == 2) ? A[1] : one; + onames[3] = (char *) "gi"; outputs[3] = I[0]; + onames[4] = (char *) "hi"; outputs[4] = (nI == 2) ? I[1] : one; + onames[5] = (char *) "gg"; outputs[5] = G[0]; + onames[6] = (char *) "hg"; outputs[6] = (nG == 2) ? G[1] : one; + onames[7] = (char *) "gv"; outputs[7] = V[0]; + onames[8] = (char *) "hv"; outputs[8] = (nV == 2) ? V[1] : one; + result &= Bnet_bddArrayDump(dd, net, option->dumpfile, outputs, + onames, 9, option->dumpFmt); + } + + /* Clean up. */ + for (i = 0; i < nA; i++) { + Cudd_RecursiveDeref(dd,A[i]); + } + for (i = 0; i < nI; i++) { + Cudd_RecursiveDeref(dd,I[i]); + } + for (i = 0; i < nG; i++) { + Cudd_RecursiveDeref(dd,G[i]); + } + for (i = 0; i < nV; i++) { + Cudd_RecursiveDeref(dd,V[i]); + } + FREE(A); + FREE(I); + FREE(G); + FREE(V); + + return(result); + +} /* end of ntrTestDecompAux */ + + +/**Function******************************************************************** + + Synopsis [Processes one BDD for Ntr_TestCofactorEstimate.] + + Description [Processes one BDD for Ntr_TestCofactorEstimate. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ntrTestCofEstAux( + DdManager * dd, + BnetNetwork * net, + DdNode * f, + char * name, + NtrOptions * option) +{ + DdNode *support, *scan, *cof; + int pr; + int nvars; + int exactSize, estimate, estimateS; + int totalExactSize = 0; + int totalEstimate = 0; + int totalEstimateS = 0; + int largestError = -1; + int largestErrorS = -1; + DdNode *errorVar = NULL; + + pr = option->verb; + support = Cudd_Support(dd,f); + if (support == NULL) return(0); + Cudd_Ref(support); + nvars = Cudd_DagSize(support) - 1; + scan = support; + while (!Cudd_IsConstant(scan)) { + DdNode *var = Cudd_bddIthVar(dd,scan->index); + cof = Cudd_Cofactor(dd,f,var); + if (cof == NULL) return(0); + Cudd_Ref(cof); + exactSize = Cudd_DagSize(cof); + totalExactSize += exactSize; + estimate = Cudd_EstimateCofactor(dd,f,scan->index,1); + totalEstimate += estimate; + if (estimate < exactSize) + (void) printf("Optimistic estimate!\n"); + if (estimate - exactSize > largestError) { + largestError = estimate - exactSize; + errorVar = var; + } + estimateS = Cudd_EstimateCofactorSimple(f,scan->index); + totalEstimateS += estimateS; + if (estimateS < exactSize) + (void) printf("Optimistic estimateS!\n"); + if (estimateS - exactSize > largestErrorS) + largestErrorS = estimateS - exactSize; + Cudd_RecursiveDeref(dd,cof); + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + (void) printf("TEST-COF:: %s (%d vars)", name, nvars); + Cudd_PrintDebug(dd, f, nvars, pr); + (void) printf("T-c : %d\n", totalExactSize); + (void) printf("T-c E : %d %d\n", totalEstimate, largestError); + (void) printf("T-c S : %d %d\n", totalEstimateS, largestErrorS); + + /* Dump to file if requested. */ + if (option->bdddump) { + char *onames[3]; + DdNode *outputs[3]; + int result; + cof = Cudd_Cofactor(dd,f,errorVar); + if (cof == NULL) return(0); + Cudd_Ref(cof); + onames[0] = name; outputs[0] = f; + onames[1] = (char *) "var"; outputs[1] = errorVar; + onames[2] = (char *) "cof"; outputs[2] = cof; + result = Bnet_bddArrayDump(dd, net, option->dumpfile, outputs, + onames, 3, option->dumpFmt); + Cudd_RecursiveDeref(dd,cof); + if (result == 0) return(0); + } + + return(1); + +} /* end of ntrTestCofEstAux */ + + +/**Function******************************************************************** + + Synopsis [Processes one BDD for Ntr_TestClipping.] + + Description [Processes one BDD for Ntr_TestClipping. It checks whether + clipping was correct. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestClipping] + +******************************************************************************/ +static int +ntrTestClippingAux( + DdManager * dd, + BnetNetwork * net1, + DdNode * f, + char * name, + DdNode * g, + char * gname, + NtrOptions * option) +{ + DdNode *prod, *sub, *sup; + DdNode *subF, *subG, *psub; + DdNode *supF, *supG, *psup; + int pr, nvars, depth; + int sizeProd, sizeSub, sizeSup; + static char *onames[7]; + DdNode *outputs[7]; + DdNode *operands[2]; + int retval = 1; + int threshold = (option->threshold < 0) ? 0 : option->threshold; + + pr = option->verb; + operands[0] = f; operands[1] = g; + nvars = Cudd_VectorSupportSize(dd,operands,2); + if (nvars == CUDD_OUT_OF_MEM) return(0); + depth = (int) ((double) nvars * option->clip); + (void) printf("TEST-CLIP:: %s depth = %d\n", name, depth); + (void) printf("T-C "); + Cudd_PrintDebug(dd, f, nvars, pr); + + /* Compute product. */ + prod = Cudd_bddAnd(dd, f, g); + if (prod == NULL) { + (void) printf("TEST-CLIP: product failed.\n"); + return(0); + } + Cudd_Ref(prod); + (void) printf("T-C P= "); + Cudd_PrintDebug(dd, prod, nvars, pr); + sizeProd = Cudd_DagSize(prod); + + /* Compute subset of product. */ + sub = Cudd_bddClippingAnd(dd, f, g, depth, 0); + if (sub == NULL) { + (void) printf("TEST-CLIP: subsetting product failed.\n"); + return(0); + } + Cudd_Ref(sub); + (void) printf("T-C P- "); + Cudd_PrintDebug(dd, sub, nvars, pr); + sizeSub = Cudd_DagSize(sub); + if (sizeSub > sizeProd) { + (void) printf("TEST-CLIP: subsetting product not safe.\n"); + } + + /* Compute product of subsets. */ + subF = Cudd_RemapUnderApprox(dd,f,nvars,threshold,option->quality); + if (subF == NULL) { + (void) printf("TEST-CLIP: subsetting of f failed.\n"); + return(0); + } + Cudd_Ref(subF); + subG = Cudd_RemapUnderApprox(dd,g,nvars,threshold,option->quality); + if (subF == NULL) { + (void) printf("TEST-CLIP: subsetting of g failed.\n"); + return(0); + } + Cudd_Ref(subG); + psub = Cudd_bddAnd(dd,subF,subG); + if (psub == NULL) { + (void) printf("TEST-CLIP: product of subsets failed.\n"); + return(0); + } + Cudd_Ref(psub); + Cudd_RecursiveDeref(dd,subF); + Cudd_RecursiveDeref(dd,subG); + (void) printf("T-C P< "); + Cudd_PrintDebug(dd, psub, nvars, pr); + + /* Compute superset of product. */ + sup = Cudd_bddClippingAnd(dd, f, g, depth, 1); + if (sup == NULL) { + (void) printf("TEST-CLIP: supersetting product failed.\n"); + return(0); + } + Cudd_Ref(sup); + (void) printf("T-C P+ "); + Cudd_PrintDebug(dd, sup, nvars, pr); + sizeSup = Cudd_DagSize(sup); + if (sizeSup > sizeProd) { + (void) printf("TEST-CLIP: supersetting product not safe.\n"); + } + + /* Compute product of supersets. */ + supF = Cudd_RemapOverApprox(dd,f,nvars,threshold,option->quality); + if (supF == NULL) { + (void) printf("TEST-CLIP: supersetting of f failed.\n"); + return(0); + } + Cudd_Ref(supF); + supG = Cudd_RemapOverApprox(dd,g,nvars,threshold,option->quality); + if (supF == NULL) { + (void) printf("TEST-CLIP: supersetting of g failed.\n"); + return(0); + } + Cudd_Ref(supG); + psup = Cudd_bddAnd(dd,supF,supG); + if (psup == NULL) { + (void) printf("TEST-CLIP: product of supersets failed.\n"); + return(0); + } + Cudd_Ref(psup); + Cudd_RecursiveDeref(dd,supF); + Cudd_RecursiveDeref(dd,supG); + (void) printf("T-C P> "); + Cudd_PrintDebug(dd, psup, nvars, pr); + + if (option->bdddump) { + onames[0] = name; outputs[0] = f; + onames[1] = gname; outputs[1] = g; + onames[2] = (char *) "prod"; outputs[2] = prod; + onames[3] = (char *) "sub"; outputs[3] = sub; + onames[4] = (char *) "sup"; outputs[4] = sup; + onames[5] = (char *) "psub"; outputs[5] = psub; + onames[6] = (char *) "psup"; outputs[6] = psup; + retval &= Bnet_bddArrayDump(dd, net1, option->dumpfile, outputs, + onames, 7, option->dumpFmt); + } + + /* Check correctness. */ + if (!Cudd_bddLeq(dd,sub,prod)) { + (void) printf("TEST-CLIP: subsetting product not a subset.\n"); + return(0); + } + if (!Cudd_bddLeq(dd,prod,sup)) { + (void) printf("TEST-CLIP: supersetting product not a superset.\n"); + return(0); + } + if (!Cudd_bddLeq(dd,psub,prod)) { + (void) printf("TEST-CLIP: product of subsets not a subset.\n"); + return(0); + } + if (!Cudd_bddLeq(dd,prod,psup)) { + (void) printf("TEST-CLIP: product of supersets not a superset.\n"); + return(0); + } + + Cudd_RecursiveDeref(dd,prod); + Cudd_RecursiveDeref(dd,sub); + Cudd_RecursiveDeref(dd,sup); + Cudd_RecursiveDeref(dd,psub); + Cudd_RecursiveDeref(dd,psup); + + return(retval); + +} /* end of ntrTestClippingAux */ + + + +/**Function******************************************************************** + + Synopsis [Processes one triplet of BDDs for Ntr_TestEquivAndContain.] + + Description [Processes one triplet of BDDs for Ntr_TestEquivAndContain. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestEquivAndContain] + +******************************************************************************/ +static int +ntrTestEquivAndContainAux( + DdManager *dd, + BnetNetwork *net1, + DdNode *f, + char *fname, + DdNode *g, + char *gname, + DdNode *d, + char *dname, + NtrOptions *option) +{ + DdNode *xor_, *diff, *ndiff; + int pr, nvars; + int equiv, implies; + static char *onames[6]; + DdNode *outputs[6]; + DdNode *fgd[3]; + + pr = option->verb; + fgd[0] = f; fgd[1] = g; fgd[2] = d; + nvars = Cudd_VectorSupportSize(dd,fgd,3); + if (nvars == CUDD_OUT_OF_MEM) return(0); + (void) printf("TEST-DC:: %s [=<]= %s unless %s\n", fname, gname, dname); + (void) printf("T-F "); + Cudd_PrintDebug(dd, f, nvars, pr); + (void) printf("T-G "); + Cudd_PrintDebug(dd, g, nvars, pr); + (void) printf("T-D "); + Cudd_PrintDebug(dd, d, nvars, pr); + + /* Check equivalence unless don't cares. */ + xor_ = Cudd_bddXor(dd, f, g); + if (xor_ == NULL) { + (void) printf("TEST-DC: XOR computation failed (1).\n"); + return(0); + } + Cudd_Ref(xor_); + equiv = Cudd_EquivDC(dd, f, g, d); + if (equiv != Cudd_bddLeq(dd,xor_,d)) { + (void) printf("TEST-DC: EquivDC computation incorrect (1).\n"); + (void) printf(" EquivDC states that %s and %s are %s\n", + fname, gname, equiv ? "equivalent" : "not equivalent"); + (void) printf("T-X "); + Cudd_PrintDebug(dd, xor_, nvars, pr); + return(0); + } + equiv = Cudd_EquivDC(dd, f, g, Cudd_Not(d)); + if (equiv != Cudd_bddLeq(dd,xor_,Cudd_Not(d))) { + (void) printf("TEST-DC: EquivDC computation incorrect (2).\n"); + (void) printf(" EquivDC states that %s and %s are %s\n", + fname, gname, equiv ? "equivalent" : "not equivalent"); + (void) printf("T-X "); + Cudd_PrintDebug(dd, xor_, nvars, pr); + return(0); + } + equiv = Cudd_EquivDC(dd, f, Cudd_Not(g), d); + if (equiv != Cudd_bddLeq(dd,Cudd_Not(xor_),d)) { + (void) printf("TEST-DC: EquivDC computation incorrect (3).\n"); + (void) printf(" EquivDC states that %s and not %s are %s\n", + fname, gname, equiv ? "equivalent" : "not equivalent"); + (void) printf("T-X "); + Cudd_PrintDebug(dd, Cudd_Not(xor_), nvars, pr); + return(0); + } + equiv = Cudd_EquivDC(dd, f, Cudd_Not(g), Cudd_Not(d)); + if (equiv != Cudd_bddLeq(dd,d,xor_)) { + (void) printf("TEST-DC: EquivDC computation incorrect (4).\n"); + (void) printf(" EquivDC states that %s and not %s are %s\n", + fname, gname, equiv ? "equivalent" : "not equivalent"); + (void) printf("T-X "); + Cudd_PrintDebug(dd, Cudd_Not(xor_), nvars, pr); + return(0); + } + + /* Check containment unless don't cares. */ + diff = Cudd_bddAnd(dd, f, Cudd_Not(g)); + if (diff == NULL) { + (void) printf("TEST-DC: AND/NOT computation failed (1).\n"); + return(0); + } + Cudd_Ref(diff); + implies = Cudd_bddLeqUnless(dd, f, g, d); + if (implies != Cudd_bddLeq(dd,diff,d)) { + (void) printf("TEST-DC: LeqUnless computation incorrect (1).\n"); + (void) printf(" LeqUnless states that %s %s %s\n", + fname, implies ? "implies" : "does not imply", gname); + (void) printf("T-I "); + Cudd_PrintDebug(dd, diff, nvars, pr); + return(0); + } + implies = Cudd_bddLeqUnless(dd, f, g, Cudd_Not(d)); + if (implies != Cudd_bddLeq(dd,diff,Cudd_Not(d))) { + (void) printf("TEST-DC: LeqUnless computation incorrect (2).\n"); + (void) printf(" LeqUnless states that %s %s %s\n", + fname, implies ? "implies" : "does not imply", gname); + (void) printf("T-I "); + Cudd_PrintDebug(dd, diff, nvars, pr); + return(0); + } + ndiff = Cudd_bddAnd(dd, f, g); + if (ndiff == NULL) { + (void) printf("TEST-DC: AND computation failed (3).\n"); + return(0); + } + Cudd_Ref(ndiff); + implies = Cudd_bddLeqUnless(dd, f, Cudd_Not(g), d); + if (implies != Cudd_bddLeq(dd,ndiff,d)) { + (void) printf("TEST-DC: LeqUnless computation incorrect (3).\n"); + (void) printf(" LeqUnless states that %s %s not(%s)\n", + fname, implies ? "implies" : "does not imply", gname); + (void) printf("T-I "); + Cudd_PrintDebug(dd, ndiff, nvars, pr); + return(0); + } + implies = Cudd_bddLeqUnless(dd, f, Cudd_Not(g), Cudd_Not(d)); + if (implies != Cudd_bddLeq(dd,ndiff,Cudd_Not(d))) { + (void) printf("TEST-DC: LeqUnless computation incorrect (3).\n"); + (void) printf(" LeqUnless states that %s %s not(%s)\n", + fname, implies ? "implies" : "does not imply", gname); + (void) printf("T-I "); + Cudd_PrintDebug(dd, ndiff, nvars, pr); + return(0); + } + if (option->bdddump) { + onames[0] = fname; outputs[0] = f; + onames[1] = gname; outputs[1] = g; + onames[2] = dname; outputs[2] = d; + onames[3] = (char *) "xor"; outputs[3] = xor_; + onames[4] = (char *) "diff"; outputs[4] = diff; + onames[5] = (char *) "ndiff"; outputs[5] = ndiff; + if (!Bnet_bddArrayDump(dd, net1, option->dumpfile, outputs, onames, + 6, option->dumpFmt)) + return(0); + } + Cudd_RecursiveDeref(dd,xor_); + Cudd_RecursiveDeref(dd,diff); + Cudd_RecursiveDeref(dd,ndiff); + + return(1); + +} /* end of ntrTestEquivAndContainAux */ + + +/**Function******************************************************************** + + Synopsis [Processes one pair of BDDs for Ntr_TestClosestCube.] + + Description [Processes one pair of BDDs for Ntr_TestClosestCube. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestClosestCube] + +******************************************************************************/ +static int +ntrTestClosestCubeAux( + DdManager *dd, + BnetNetwork *net, + DdNode *f, + char *fname, + DdNode *g, + char *gname, + DdNode **vars, + NtrOptions *option) +{ + DdNode *cube, *cubeN; + int distance, pr, nvars; + DdNode *fg[2]; + static char *onames[4]; + DdNode *outputs[4]; + + pr = option->verb; + fg[0] = f; fg[1] = g; + nvars = Cudd_VectorSupportSize(dd,fg,2); + if (nvars == CUDD_OUT_OF_MEM) return(0); + (void) printf("TEST-CC:: H(%s, %s)\n", fname, gname); + (void) printf("T-F "); + Cudd_PrintDebug(dd, f, nvars, pr); + (void) printf("T-G "); + Cudd_PrintDebug(dd, g, nvars, pr); + + cube = Cudd_bddClosestCube(dd, f, g, &distance); + if (cube == NULL) { + (void) printf("TEST-CC: computation failed (1).\n"); + return(0); + } + Cudd_Ref(cube); + (void) printf("T-C (%d) ", distance); + Cudd_PrintDebug(dd, cube, nvars, pr); + if (distance == 0) { + if (!Cudd_bddLeq(dd,cube,g)) { + (void) printf("TEST-CC: distance-0 cube not in g (2).\n"); + return(0); + } + } + + (void) printf("T-GN "); + Cudd_PrintDebug(dd, Cudd_Not(g), nvars, pr); + cubeN = Cudd_bddClosestCube(dd, f, Cudd_Not(g), &distance); + if (cubeN == NULL) { + (void) printf("TEST-CC: computation failed (3).\n"); + return(0); + } + Cudd_Ref(cubeN); + (void) printf("T-N (%d) ", distance); + Cudd_PrintDebug(dd, cubeN, nvars, pr); + if (distance == 0) { + if (!Cudd_bddLeq(dd,cubeN,Cudd_Not(g))) { + (void) printf("TEST-CC: distance-0 cube not in not(g) (4).\n"); + return(0); + } + } else { + int d, *minterm; + int numvars = Cudd_ReadSize(dd); + DdNode *scan, *zero; + DdNode *minBdd = Cudd_bddPickOneMinterm(dd,cubeN,vars,numvars); + if (minBdd == NULL) { + (void) printf("TEST-CC: minterm selection failed (5).\n"); + return(0); + } + Cudd_Ref(minBdd); + minterm = ALLOC(int,numvars); + if (minterm == NULL) { + (void) printf("TEST-CC: allocation failed (6).\n"); + Cudd_RecursiveDeref(dd,minBdd); + return(0); + } + scan = minBdd; + zero = Cudd_Not(DD_ONE(dd)); + while (!Cudd_IsConstant(scan)) { + DdNode *R = Cudd_Regular(scan); + DdNode *T = Cudd_T(R); + DdNode *E = Cudd_E(R); + if (R != scan) { + T = Cudd_Not(T); + E = Cudd_Not(E); + } + if (T == zero) { + minterm[Cudd_NodeReadIndex(R)] = 0; + scan = E; + } else { + minterm[Cudd_NodeReadIndex(R)] = 1; + scan = T; + } + } + Cudd_RecursiveDeref(dd,minBdd); + d = Cudd_MinHammingDist(dd,Cudd_Not(g),minterm,numvars); + FREE(minterm); + if (d != distance) { + (void) printf("TEST-CC: distance disagreement (7).\n"); + return(0); + } + } + + if (option->bdddump) { + onames[0] = fname; outputs[0] = f; + onames[1] = gname; outputs[1] = g; + onames[2] = (char *) "cube"; outputs[2] = cube; + onames[3] = (char *) "cubeN"; outputs[3] = cubeN; + if (!Bnet_bddArrayDump(dd, net, option->dumpfile, outputs, onames, + 4, option->dumpFmt)) + return(0); + } + Cudd_RecursiveDeref(dd,cube); + Cudd_RecursiveDeref(dd,cubeN); + + return(1); + +} /* end of ntrTestClosestCubeAux */ + + +/**Function******************************************************************** + + Synopsis [Processes one BDDs for Ntr_TestCharToVect.] + + Description [Processes one BDD for Ntr_TestCharToVect. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_TestCharToVect] + +******************************************************************************/ +static int +ntrTestCharToVect( + DdManager * dd, + DdNode * f, + NtrOptions *option) +{ + DdNode **vector; + int sharingSize; + DdNode *verify; + int pr = option->verb; + int i; + + (void) fprintf(stdout,"f"); + Cudd_PrintDebug(dd, f, Cudd_ReadSize(dd), 1); + if (pr > 1) { + Cudd_bddPrintCover(dd, f, f); + } + vector = Cudd_bddCharToVect(dd,f); + if (vector == NULL) return(0); + sharingSize = Cudd_SharingSize(vector, Cudd_ReadSize(dd)); + (void) fprintf(stdout, "Vector Size: %d components %d nodes\n", + Cudd_ReadSize(dd), sharingSize); + for (i = 0; i < Cudd_ReadSize(dd); i++) { + (void) fprintf(stdout,"v[%d]",i); + Cudd_PrintDebug(dd, vector[i], Cudd_ReadSize(dd), 1); + if (pr > 1) { + Cudd_bddPrintCover(dd, vector[i], vector[i]); + } + } + verify = Cudd_bddVectorCompose(dd,f,vector); + if (verify != Cudd_ReadOne(dd)) { + (void) fprintf(stdout, "Verification failed!\n"); + return(0); + } + Cudd_Ref(verify); + Cudd_IterDerefBdd(dd, verify); + for (i = 0; i < Cudd_ReadSize(dd); i++) { + Cudd_IterDerefBdd(dd, vector[i]); + } + FREE(vector); + return(1); + +} /* end of ntrTestCharToVect */ + + +#if 0 +/**Function******************************************************************** + + Synopsis [Try hard to squeeze a BDD.] + + Description [Try hard to squeeze a BDD. + Returns a pointer to the squeezed BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [ntrTestDensityAux Cudd_SubsetCompress] + +******************************************************************************/ +static DdNode * +ntrCompress1( + DdManager * dd, + DdNode * f, + int nvars, + int threshold) +{ + DdNode *res, *tmp1, *tmp2; + int sizeI, size; + + tmp1 = Cudd_RemapUnderApprox(dd,f,nvars,0,1.0); + if (tmp1 == NULL) return(NULL); + Cudd_Ref(tmp1); + sizeI = Cudd_DagSize(tmp1); + size = (sizeI < threshold) ? sizeI : threshold; + tmp2 = Cudd_SubsetShortPaths(dd, tmp1, nvars, size, 0); + if (tmp2 == NULL) { + Cudd_RecursiveDeref(dd,tmp1); + return(NULL); + } + Cudd_Ref(tmp2); + Cudd_RecursiveDeref(dd,tmp1); + res = Cudd_bddSqueeze(dd,tmp2,f); + if (res == NULL) { + Cudd_RecursiveDeref(dd,tmp2); + return(NULL); + } + Cudd_Ref(res); + Cudd_RecursiveDeref(dd,tmp2); + return(res); + +} /* end of ntrCompress1 */ +#endif + + +/**Function******************************************************************** + + Synopsis [Try hard to squeeze a BDD.] + + Description [Try hard to squeeze a BDD. + Returns a pointer to the squeezed BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [ntrTestDensityAux Cudd_SubsetCompress] + +******************************************************************************/ +static DdNode * +ntrCompress2( + DdManager * dd, + DdNode * f, + int nvars, + int threshold) +{ + DdNode *res, *tmp1, *tmp2; + int sizeI; + + tmp1 = Cudd_RemapUnderApprox(dd,f,nvars,0,1.0); + if (tmp1 == NULL) return(NULL); + Cudd_Ref(tmp1); + sizeI = Cudd_DagSize(tmp1); + if (sizeI > threshold) { + tmp2 = Cudd_SubsetShortPaths(dd, tmp1, nvars, threshold, 0); + if (tmp2 == NULL) { + Cudd_RecursiveDeref(dd,tmp1); + return(NULL); + } + Cudd_Ref(tmp2); + Cudd_RecursiveDeref(dd,tmp1); + } else { + tmp2 = tmp1; + } + res = Cudd_bddSqueeze(dd,tmp2,f); + if (res == NULL) { + Cudd_RecursiveDeref(dd,tmp2); + return(NULL); + } + Cudd_Ref(res); + if (Cudd_Density(dd,res,nvars) < Cudd_Density(dd,tmp2,nvars)) { + Cudd_RecursiveDeref(dd,res); + return(tmp2); + } else { + Cudd_RecursiveDeref(dd,tmp2); + return(res); + } + +} /* end of ntrCompress2 */ + + +/**Function******************************************************************** + + Synopsis [Checks whether node is a buffer.] + + Description [Checks whether node is a buffer. Returns a pointer to the + input node if nd is a buffer; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static BnetNode * +ntrNodeIsBuffer( + BnetNode *nd, + st_table *hash) +{ + BnetNode *inpnd; + + if (nd->ninp != 1) return(0); + if (!st_lookup(hash, nd->inputs[0], &inpnd)) return(0); + + return(nd->dd == inpnd->dd ? inpnd : NULL); + +} /* end of ntrNodeIsBuffer */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntrHeap.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrHeap.c new file mode 100644 index 000000000..801b3f8d6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrHeap.c @@ -0,0 +1,390 @@ +/**CFile*********************************************************************** + + FileName [ntrHeap.c] + + PackageName [ntr] + + Synopsis [Functions for heap-based priority queue.] + + Description [The functions in this file manage a priority queue implemented + as a heap. The first element of the heap is the one with the smallest key. + Refer to Chapter 7 of Cormen, Leiserson, and Rivest for the theory.] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: ntrHeap.c,v 1.6 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define PARENT(i) (((i)-1)>>1) +#define RIGHT(i) (((i)+1)<<1) +#define LEFT(i) (((i)<<1)|1) +#define ITEM(p,i) ((p)[i].item) +#define KEY(p,i) ((p)[i].key) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void ntrHeapify (NtrHeap *heap, int i); +static int ntrHeapResize (NtrHeap *heap); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes a priority queue.] + + Description [Initializes a priority queue. Returns a pointer to the heap + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_FreeHeap] + +******************************************************************************/ +NtrHeap * +Ntr_InitHeap( + int size) +{ + NtrHeap *heap; + + heap = ALLOC(NtrHeap,1); + if (heap == NULL) return(NULL); + heap->size = size; + heap->nslots = 0; + heap->slots = ALLOC(NtrHeapSlot,size); + if (heap->slots == NULL) { + FREE(heap); + return(NULL); + } + return(heap); + +} /* end of Ntr_InitHeap */ + + +/**Function******************************************************************** + + Synopsis [Frees a priority queue.] + + Description [] + + SideEffects [None] + + SeeAlso [Ntr_InitHeap] + +******************************************************************************/ +void +Ntr_FreeHeap( + NtrHeap *heap) +{ + FREE(heap->slots); + FREE(heap); + return; + +} /* end of Ntr_FreeHeap */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a priority queue.] + + Description [Inserts an item in a priority queue. Returns 1 if successful; + 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_HeapExtractMin] + +******************************************************************************/ +int +Ntr_HeapInsert( + NtrHeap *heap, + void *item, + int key) +{ + NtrHeapSlot *slots; + int i = heap->nslots; + + if (i == heap->size && !ntrHeapResize(heap)) return(0); + slots = heap->slots; + heap->nslots++; + while (i > 0 && KEY(slots,PARENT(i)) > key) { + ITEM(slots,i) = ITEM(slots,PARENT(i)); + KEY(slots,i) = KEY(slots,PARENT(i)); + i = PARENT(i); + } + ITEM(slots,i) = item; + KEY(slots,i) = key; + return(1); + +} /* end of Ntr_HeapInsert */ + + +/**Function******************************************************************** + + Synopsis [Extracts the element with the minimum key from a priority + queue.] + + Description [Extracts the element with the minimum key from a priority + queue. Returns 1 if successful; 0 otherwise.] + + SideEffects [The minimum key and the associated item are returned as + side effects.] + + SeeAlso [Ntr_HeapInsert] + +******************************************************************************/ +int +Ntr_HeapExtractMin( + NtrHeap *heap, + void *item, + int *key) +{ + NtrHeapSlot *slots = heap->slots; + + if (heap->nslots == 0) return(0); + *(void **)item = ITEM(slots,0); + *key = KEY(slots,0); + heap->nslots--; + ITEM(slots,0) = ITEM(slots,heap->nslots); + KEY(slots,0) = KEY(slots,heap->nslots); + ntrHeapify(heap,0); + + return(1); + +} /* end of Ntr_HeapExtractMin */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of items in a priority queue.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_HeapCount( + NtrHeap *heap) +{ + return(heap->nslots); + +} /* end of Ntr_HeapCount */ + + +/**Function******************************************************************** + + Synopsis [Clones a priority queue.] + + Description [] + + SideEffects [None] + + SeeAlso [Ntr_InitHeap] + +******************************************************************************/ +NtrHeap * +Ntr_HeapClone( + NtrHeap *source) +{ + NtrHeap *dest; + int i; + int nslots = source->nslots; + NtrHeapSlot *sslots = source->slots; + NtrHeapSlot *dslots; + + dest = Ntr_InitHeap(source->size); + if (dest == NULL) return(NULL); + dest->nslots = nslots; + dslots = dest->slots; + for (i = 0; i < nslots; i++) { + KEY(dslots,i) = KEY(sslots,i); + ITEM(dslots,i) = ITEM(sslots,i); + } + return(dest); + +} /* end of Ntr_HeapClone */ + + +/**Function******************************************************************** + + Synopsis [Tests the heap property of a priority queue.] + + Description [Tests the heap property of a priority queue. Returns 1 if + Successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_TestHeap( + NtrHeap *heap, + int i) +{ + NtrHeapSlot *slots = heap->slots; + int nslots = heap->nslots; + + if (i > 0 && KEY(slots,i) < KEY(slots,PARENT(i))) + return(0); + if (LEFT(i) < nslots) { + if (!Ntr_TestHeap(heap,LEFT(i))) + return(0); + } + if (RIGHT(i) < nslots) { + if (!Ntr_TestHeap(heap,RIGHT(i))) + return(0); + } + return(1); + +} /* end of Ntr_TestHeap */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Maintains the heap property of a priority queue.] + + Description [] + + SideEffects [None] + + SeeAlso [Ntr_HeapExtractMin] + +******************************************************************************/ +static void +ntrHeapify( + NtrHeap *heap, + int i) +{ + int smallest; + int left = LEFT(i); + int right = RIGHT(i); + int nslots = heap->nslots; + NtrHeapSlot *slots = heap->slots; + int key = KEY(slots,i); + + if (left < nslots && KEY(slots,left) < key) { + smallest = left; + } else { + smallest = i; + } + if (right < nslots && KEY(slots,right) < KEY(slots,smallest)) { + smallest = right; + } + if (smallest != i) { + void *item = ITEM(slots,i); + KEY(slots,i) = KEY(slots,smallest); + ITEM(slots,i) = ITEM(slots,smallest); + KEY(slots,smallest) = key; + ITEM(slots,smallest) = item; + ntrHeapify(heap,smallest); + } + + return; + +} /* end of ntrHeapify */ + + +/**Function******************************************************************** + + Synopsis [Resizes a priority queue.] + + Description [Resizes a priority queue by doubling the number of + available slots. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Ntr_HeapInsert] + +******************************************************************************/ +static int +ntrHeapResize( + NtrHeap *heap) +{ + int oldlength = heap->size; + int newlength = 2 * oldlength; + NtrHeapSlot *oldslots = heap->slots; + NtrHeapSlot *newslots = REALLOC(NtrHeapSlot, oldslots, newlength); + if (newslots == NULL) return 0; + heap->size = newlength; + heap->slots = newslots; + assert(Ntr_TestHeap(heap, 0)); + return 1; + +} /* end of ntrHeapResize */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntrMflow.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrMflow.c new file mode 100644 index 000000000..a8893c927 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrMflow.c @@ -0,0 +1,1581 @@ +/**CFile*********************************************************************** + + FileName [ntrMflow.c] + + PackageName [ntr] + + Synopsis [Symbolic maxflow algorithm.] + + Description [This file contains the functions that implement the + symbolic version of Dinits's maxflow algorithm described in the + ICCAD93 paper. The present implementation differs from the algorithm + described in the paper in that more than one matching techniques is + used. The technique of the paper is the one applied to + hourglass-type bilayers here.] + + Author [Fabio Somenzi, Gary Hachtel] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define MAXPHASE 1000 +#define MAXLAYER 1000 +#define MAXFPIT 100000 +#define MANY_TIMES 3.0 + +#define PRUNE /* If defined, enables pruning of E */ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct flowStatsStruct { + int pr; /* level of verbosity */ + long start_time; /* cpu time when the covering started */ + int phases; /* number of phases */ + int layers; /* number of layers */ + int fpit; /* number of fixed point iterations */ +} flowStats; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: ntrMflow.c,v 1.8 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +static DdNode *xcube, *ycube, *zcube; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void maximal_pull (DdManager *bdd, int l, DdNode *ty, DdNode **neW, DdNode **U, DdNode *E, DdNode **F, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void propagate_maximal_flow (DdManager *bdd, int m, DdNode **neW, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void trellis (DdManager *bdd, int m, DdNode **neW, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void rhombus (DdManager *bdd, int m, DdNode **neW, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void hourglass (DdManager *bdd, int m, DdNode **neW, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void maximal_push (DdManager *bdd, int l, DdNode **U, DdNode **F, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void trellisPush (DdManager *bdd, int m, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void rhombusPush (DdManager *bdd, int m, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); +static void hourglassPush (DdManager *bdd, int m, DdNode **U, DdNode **x, DdNode **y, DdNode **z, int n, DdNode *pryz, DdNode *prxz, flowStats *stats); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [] + + Description [This function implements Dinits's algorithm for (0-1) + max flow, using BDDs and a symbolic technique to trace multiple + edge-disjoint augmenting paths to complete a phase. The outer + forever loop is over phases, and the inner forever loop is to + propagate a (not yet) maximal flow of edge-disjoint augmenting paths + from one layer to the previous. The subprocedure call implements a + least fixed point iteration to compute a (not yet) maximal flow + update between layers. At the end of each phase (except the last + one) the flow is actually pushed from the source to the sink. + + Data items: +
                    +
                  • sx(ty) BDD representations of s(t). +
                  • x(y) The variables encoding the from(to)-node u(v) of an + edge (u,v) in the given digraph. +
                  • z Another set of variables. +
                  • E(x,y) The edge relation. +
                  • F(x,y) BDD representation of the current flow, initialized to 0 + for each arc, and updated by +1, -1, or 0 at the + end of each phase. +
                  • Ms Mt The maximum flow, that is, the cardinality of a minimum cut, + measured at the source and at the sink, respectively. + The two values should be identical. +
                  • reached The set of nodes already visited in the BFS of the digraph. +
                  • fos fanout of the source node s. +
                  • fit fanin of the sink node t. +
                  + ] + + SideEffects [The flow realtion F and the cutset relation cut are returned + as side effects.] + + SeeAlso [] + +******************************************************************************/ +double +Ntr_maximum01Flow( + DdManager * bdd /* manager */, + DdNode * sx /* source node */, + DdNode * ty /* sink node */, + DdNode * E /* edge relation */, + DdNode ** F /* flow relation */, + DdNode ** cut /* cutset relation */, + DdNode ** x /* array of row variables */, + DdNode ** y /* array of column variables */, + DdNode ** z /* arrays of auxiliary variables */, + int n /* number of variables in each array */, + int pr /* verbosity level */) +{ + flowStats stats; + DdNode *one, *zero, +#ifdef PRUNE + *EDC, /* Edge don't care set */ +#endif + *reached, /* states reached through useful edges */ + *fos, *fit, /* fanout of source, fanin of sink */ + *rF, *rB, *tx, + *I, *P, + *w, *p, *q, *r,/* intemediate results */ + *pryz, *prxz, /* priority functions for disjoint path tracing */ + **neW, **U; /* arrays of BDDs for flow propagation */ + int i, j, l; + double Ms, Mt; + + /* Initialize debugging structure. */ + stats.pr = pr; + stats.start_time = util_cpu_time(); + stats.phases = 0; + stats.layers = 0; + stats.fpit = 0; + + /* Allocate arrays for new (just reached vertex sets) + ** and U (useful edge sets). + */ + U = ALLOC(DdNode *, ((unsigned) MAXLAYER)); + neW = ALLOC(DdNode *, ((unsigned) MAXLAYER)); + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /* Initialize xcube, ycube, and zcube (for abstractions). */ + Cudd_Ref(xcube = Cudd_bddComputeCube(bdd,x,NULL,n)); + Cudd_Ref(ycube = Cudd_bddComputeCube(bdd,y,NULL,n)); + Cudd_Ref(zcube = Cudd_bddComputeCube(bdd,z,NULL,n)); + + /* Build the BDD for the priority functions. */ + Cudd_Ref(pryz = Cudd_Dxygtdxz(bdd, n, x, y, z)); + Cudd_Ref(prxz = Cudd_Dxygtdyz(bdd, n, x, y, z)); + /* Now "randomize" by shuffling the x variables in pryz and the y + ** variables in prxz. + */ + Cudd_Ref(p = Cudd_bddAdjPermuteX(bdd,pryz,x,n)); + Cudd_RecursiveDeref(bdd,pryz); + pryz = p; + if(pr>2){(void) fprintf(stdout,"pryz");Cudd_PrintDebug(bdd,pryz,n*3,pr);} + Cudd_Ref(p = Cudd_bddAdjPermuteX(bdd,prxz,y,n)); + Cudd_RecursiveDeref(bdd,prxz); + prxz = p; + if(pr>2){(void) fprintf(stdout,"prxz");Cudd_PrintDebug(bdd,prxz,n*3,pr);} + +#ifdef PRUNE + /* Build the edge don't care set and prune E. The edge don't care + ** set consists of the edges into the source(s), the edges out of the + ** sink(s), and the self-loops. These edges cannot contribute to the + ** maximum flow. + */ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, sx, x, y, n)); + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, ty, x, y, n)); + Cudd_Ref(r = Cudd_bddOr(bdd, p, q)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,q); + Cudd_Ref(p = Cudd_Xeqy(bdd, n, x, y)); + Cudd_Ref(EDC = Cudd_bddOr(bdd, p, r)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,r); + if(pr>2){(void) fprintf(stdout,"EDC");Cudd_PrintDebug(bdd,EDC,n<<1,pr);} + Cudd_Ref(p = Cudd_bddAnd(bdd, E, Cudd_Not(EDC))); + Cudd_RecursiveDeref(bdd,EDC); + if(pr>0){(void) fprintf(stdout,"Given E");Cudd_PrintDebug(bdd,E,n<<1,pr);} + E = p; + if(pr>0){(void) fprintf(stdout,"Pruned E");Cudd_PrintDebug(bdd,E,n<<1,pr);} +#endif + + /* Compute fanin of sink node t: it is an upper bound for the flow. */ + Cudd_Ref(fit = Cudd_bddAnd(bdd, E, ty)); + if (pr>2) { + /* Compute fanout of source node s. */ + Cudd_Ref(fos = Cudd_bddAnd(bdd, E, sx)); + (void) fprintf(stdout,"fos");Cudd_PrintDebug(bdd,fos,n<<1,pr); + Cudd_RecursiveDeref(bdd,fos); + + (void) fprintf(stdout,"fit");Cudd_PrintDebug(bdd,fit,n<<1,pr); + } + /* t(x) is used to check for termination of forward traversal. */ + Cudd_Ref(tx = Cudd_bddSwapVariables(bdd, ty, x, y, n)); + + /* \KW{Procedure}\ \ \PC{maximum\_flow}$(s,t,E(x,y)) */ + Cudd_Ref(*F = zero); + + for (i = 1; i < MAXPHASE; i++) { + stats.phases++; + if(pr>0){(void) fprintf(stdout,"## Starting Phase %d at time = %s\n",i, + util_print_time(util_cpu_time() - stats.start_time));} + /* new[0](x) = s(x);U^0(x,y)=E(x,y)\cdot s(x) \cdot \overline{F(x,y)}; + ** reached=s; new[1](x)=\exists_xU^0(x,y); + */ + Cudd_Ref(neW[0] = sx); + Cudd_Ref(p = Cudd_bddAnd(bdd, sx, Cudd_Not(*F))); + Cudd_Ref(U[0] = Cudd_bddAnd(bdd, p, E)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(reached = sx); + Cudd_Ref(r = Cudd_bddExistAbstract(bdd, U[0], xcube)); + Cudd_RecursiveDeref(bdd,U[0]); + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, r, x, y, n)); + Cudd_RecursiveDeref(bdd,r); + Cudd_Ref(neW[1] = Cudd_bddAnd(bdd, q, Cudd_Not(reached))); + Cudd_RecursiveDeref(bdd,q); + if(pr>0) { + (void) fprintf(stdout,"neW[1]");Cudd_PrintDebug(bdd,neW[1],n,pr); + } + for (l = 1; l < MAXLAYER; l++) { + if (neW[l] == zero) { /* flow is maximum */ + /* cut=reached(x) \cdot E(x,y) \cdot \overline{reached(y)} */ + Cudd_Ref(p = Cudd_bddAnd(bdd, reached, E)); + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, reached, x, y, n)); + Cudd_Ref(*cut = Cudd_bddAnd(bdd, p, Cudd_Not(q))); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,q); + Cudd_RecursiveDeref(bdd,reached); + for (j = 0; j <= l; j++) + Cudd_RecursiveDeref(bdd,neW[j]); + goto endPhases; + } + /* As soon as we touch one sink node we stop traversal. + ** \KW{if} ($t\cdot new^{l} \neq 0$) + */ + if (!Cudd_bddLeq(bdd, tx, Cudd_Not(neW[l]))) { + Cudd_RecursiveDeref(bdd,reached); + maximal_pull(bdd,l-1,ty,neW,U,E,F,x,y,z,n,pryz,prxz,&stats); + goto endLayers; + } + stats.layers++; + if(pr>2){(void) fprintf(stdout,"===== Layer %d =====\n",l);} + /* reached(x) = reached(x) + new^l(x) */ + Cudd_Ref(w = Cudd_bddOr(bdd, reached, neW[l])); + Cudd_RecursiveDeref(bdd,reached); + reached = w; + /* I(y) = \exists_x((E(x,y) \cdot \overline{F(x,y)}) + ** \cdot new^l(x)) + */ + Cudd_Ref(p = Cudd_bddAnd(bdd, E, Cudd_Not(*F))); + Cudd_Ref(I = Cudd_bddAndAbstract(bdd, p, neW[l], xcube)); + if(pr>3){(void) fprintf(stdout,"I");Cudd_PrintDebug(bdd,I,n,pr);} + Cudd_RecursiveDeref(bdd,p); + /* rF(x)= I(x) \cdot \overline{reached(x)}) */ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, I, x, y, n)); + Cudd_RecursiveDeref(bdd,I); + Cudd_Ref(rF = Cudd_bddAnd(bdd, p, Cudd_Not(reached))); + Cudd_RecursiveDeref(bdd,p); + if(pr>2){(void) fprintf(stdout,"rF");Cudd_PrintDebug(bdd,rF,n,pr);} + /* P(x) = \exists_{y}(F(x,y) \cdot new^l(y)) */ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, neW[l], x, y, n)); + Cudd_Ref(P = Cudd_bddAndAbstract(bdd, *F, p, ycube)); + Cudd_RecursiveDeref(bdd,p); + /* rB(x) = P(x) \cdot \overline{reached(x)}) */ + Cudd_Ref(rB = Cudd_bddAnd(bdd, P, Cudd_Not(reached))); + Cudd_RecursiveDeref(bdd,P); + if(pr>2){(void) fprintf(stdout,"rB");Cudd_PrintDebug(bdd,rB,n,pr);} + /* new^{l+1}(x) = rF(x) + rB(x) */ + Cudd_Ref(neW[l+1] = Cudd_bddOr(bdd, rF, rB)); + Cudd_RecursiveDeref(bdd,rB); + Cudd_RecursiveDeref(bdd,rF); + if(pr>0) { + (void) fprintf(stdout,"new[%d]",l+1); + Cudd_PrintDebug(bdd,neW[l+1],n,pr); + } + } /* start next layer */ + if (l==MAXLAYER) (void) fprintf(stderr,"ERROR! MAXLAYER exceeded.\n"); + exit(3); +endLayers: + maximal_push(bdd, l-1, U, F, x, y, z, n, pryz, prxz, &stats); + for (j = 0; j < l; j++) { + Cudd_RecursiveDeref(bdd,U[j]); + Cudd_RecursiveDeref(bdd,neW[j]); + } + Cudd_RecursiveDeref(bdd,neW[l]); + if (pr > 0) { + Cudd_Ref(p = Cudd_bddAnd(bdd, sx, *F)); + Ms=Cudd_CountMinterm(bdd, p, n<<1); + (void) fprintf(stdout,"# Flow out of s: %g\n", Ms); + Cudd_RecursiveDeref(bdd,p); + } + if (Cudd_bddLeq(bdd, fit, *F)) { + Cudd_Ref(*cut = fit); + goto endPhases; + } + } /* start next phase */ + if (i == MAXPHASE) (void) fprintf(stderr,"ERROR! MAXPHASE exceeded.\n"); + + /* Last phase is completed --- print flow results. */ +endPhases: + Cudd_RecursiveDeref(bdd,tx); + + Cudd_Ref(q = Cudd_bddAnd(bdd, *F, sx)); + Ms = Cudd_CountMinterm(bdd, q, n<<1); + Cudd_RecursiveDeref(bdd,q); + + Cudd_Ref(q = Cudd_bddAnd(bdd, *F, ty)); + Mt = Cudd_CountMinterm(bdd, q, n<<1); + Cudd_RecursiveDeref(bdd,q); + + if (pr>1) (void) fprintf(stdout,"Mt= %g, Ms= %g \n", Mt, Ms); + + if (pr>3){(void) fprintf(stdout,"pryz");Cudd_PrintDebug(bdd,pryz,n*3,pr);} + if (pr>3){(void) fprintf(stdout,"prxz");Cudd_PrintDebug(bdd,prxz,n*3,pr);} + + if (pr>0) { + (void) fprintf(stdout,"#### Stats for maximum_flow ####\n"); + (void) fprintf(stdout,"%d variables %d of which x[i]\n", Cudd_ReadSize(bdd), n); + (void) fprintf(stdout,"time = %s\n", + util_print_time(util_cpu_time() - stats.start_time)); + (void) fprintf(stdout,"phases = %d\n", stats.phases); + (void) fprintf(stdout,"layers = %d\n", stats.layers); + (void) fprintf(stdout,"FP iter. = %d\n", stats.fpit); + } + + Cudd_RecursiveDeref(bdd,fit); + Cudd_RecursiveDeref(bdd,pryz); + Cudd_RecursiveDeref(bdd,prxz); + Cudd_RecursiveDeref(bdd,xcube); + Cudd_RecursiveDeref(bdd,ycube); + Cudd_RecursiveDeref(bdd,zcube); +#ifdef PRUNE + Cudd_RecursiveDeref(bdd,E); +#endif + + FREE(U); + FREE(neW); + + return(Ms); + +} /* end of Ntr_maximum01Flow */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Selects set of edge-disjoint paths from layered network.] + + Description [Selects set of edge-disjoint paths from layered + network. maximal_pull is called when the BFS constructing the + layered graph reaches a sink. At this point the new sets of the + BFS have been formed, and we know every vertex in these sets is + reachable from the source vertex (or vertices) s. The new sets are + used to compute the set of useful edges exiting each layer to the + right. In each layer, propagate_maximal_flow is called to select a + maximal subset of these useful edges. This subset is then used to + prune new and U.] + + SideEffects [None] + + SeeAlso [maximal_push] + +******************************************************************************/ +static void +maximal_pull( + DdManager * bdd /* manager */, + int l /* depth of layered network for current phase */, + DdNode * ty /* sink node */, + DdNode ** neW /* array of BFS layers */, + DdNode ** U /* array of useful edges */, + DdNode * E /* edge relation */, + DdNode ** F /* flow relation */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* arrays of variables for rows and columns */, + int n /* number of x variables */, + DdNode * pryz, + DdNode * prxz /* priority functions */, + flowStats * stats) +{ + DdNode *p, *q, *r, + *UF, *UB; + int m, + pr; /* Print control */ + + pr = stats->pr; + + /* The useful edges of the last layer are all the empty edges into + ** the sink(s) from new[l]. + ** U^{l}(x,y) = t(y)\cdot \overline{F(x,y)}\cdot E(x,y)\cdot new^{l}(x) + */ + Cudd_Ref(p = Cudd_bddAnd(bdd, E, Cudd_Not(*F))); + Cudd_Ref(q = Cudd_bddAnd(bdd, neW[l], p)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(U[l] = Cudd_bddAnd(bdd, ty, q)); + Cudd_RecursiveDeref(bdd,q); + if(pr>1){(void) fprintf(stdout,"U[%d]",l);Cudd_PrintDebug(bdd,U[l],n<<1,pr);} + /* Eliminate from new[l] the states with no paths to the sink(s). + ** new^{l}(x)=\exists_y U^{l}(x,y) + */ + Cudd_RecursiveDeref(bdd,neW[l]); + Cudd_Ref(neW[l] = Cudd_bddExistAbstract(bdd, U[l], ycube)); + + for (m = l; m >= 1; m--) { + /* Find usable backward edges from level m-1 to level m. + ** UB(x,y) = new^{m}(x) \cdot F(x,y) \cdot new^{m-1}(y) + */ + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, neW[m-1], x, y, n)); + Cudd_Ref(q = Cudd_bddAnd(bdd, r, *F)); + Cudd_RecursiveDeref(bdd,r); + Cudd_Ref(UB = Cudd_bddAnd(bdd, neW[m], q)); + Cudd_RecursiveDeref(bdd,q); + if(pr>2){(void) fprintf(stdout,"UB");Cudd_PrintDebug(bdd,UB,n<<1,pr);} + /* Find usable forward edges. + ** UF(x,y) = new^{m}(y) \cdot \overline{F(x,y)} \cdot E(x,y) + ** \cdot new^{m-1}(x) + */ + Cudd_Ref(p = Cudd_bddAnd(bdd, E, Cudd_Not(*F))); + Cudd_Ref(q = Cudd_bddAnd(bdd, neW[m-1], p)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, neW[m], x, y, n)); + Cudd_Ref(UF = Cudd_bddAnd(bdd, r, q)); + Cudd_RecursiveDeref(bdd,q); + Cudd_RecursiveDeref(bdd,r); + if(pr>2){(void) fprintf(stdout,"UF");Cudd_PrintDebug(bdd,UF,n<<1,pr);} + /* U^{m-1}(x,y) = UB(y,x) + UF(x,y) */ + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, UB, x, y, n)); + Cudd_RecursiveDeref(bdd,UB); + Cudd_Ref(U[m-1] = Cudd_bddOr(bdd, UF, r)); + Cudd_RecursiveDeref(bdd,UF); + Cudd_RecursiveDeref(bdd,r); + if(pr>2){(void)fprintf(stdout,"U[%d]",m-1); + Cudd_PrintDebug(bdd,U[m-1],n<<1,pr);} + /* new[m-1](x) = \exists_{y}U^{m-1}(x,y) */ + Cudd_RecursiveDeref(bdd,neW[m-1]); + Cudd_Ref(neW[m-1] = Cudd_bddExistAbstract(bdd, U[m-1], ycube)); + /* Compute maximal disjoint interlayer edge set. */ + propagate_maximal_flow(bdd, m, neW, U, x, y, z, n, pryz, prxz, stats); + if(pr>0) { + (void)fprintf(stdout,"U[%d]",m-1); + Cudd_PrintDebug(bdd,U[m-1],n<<1,pr); + } + } /* prune next layer */ + + return; + +} /* end of maximal_pull */ + + +/**Function******************************************************************** + + Synopsis [Pulls flow though a layer.] + + Description [Pulls flow though a layer. propagate_maximal_flow only + affects U[m-1] and new[m-1]. At the end of this function, the edges + in U[m] are guaranteed to drain all the flow supplied by the edges + in U[m-1]. This effect is obtained by pruning U[m-1]. After the + pruned U[m-1] is computed, new[m-1] is updated to keep track of what + nodes are still useful. + + The pruning is performed without actually measuring the in-potential + and the out-potential of each node. Instead, pairs of nodes from U[m-1] + and U[m] are matched. To avoid counting, the procedure computes sets of + paths that connect layer m-1 to layer m+1 and are edge-disjoint. + + Two paths from layer m-1 to layer m+1 are disjoint if they have distinct + end-point or if they have distinct middle points. What condition to + enforce depends on the "shape" of the layers.] + + SideEffects [Changes U[m-1] and new[m-1]] + + SeeAlso [trellis rhombus hourglass] + +******************************************************************************/ +static void +propagate_maximal_flow( + DdManager * bdd, + int m /* center of current bilayer */, + DdNode ** neW /* array of reachable or useful nodes */, + DdNode ** U /* array of usable or useful edges */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* arrays of variables for rows and columns */, + int n /* number of x variables */, + DdNode * pryz, + DdNode * prxz /* priority functions */, + flowStats * stats) +{ + DdNode *rN; + double mtl, mtc, mtr; /* minterms for left, center, right levels */ + int pr; /* print control */ + + pr = stats->pr; + + mtl = Cudd_CountMinterm(bdd, neW[m-1], n); + mtc = Cudd_CountMinterm(bdd, neW[m], n); + + /* rN(y) = \exists_x U^{m}(x,y) */ + Cudd_Ref(rN = Cudd_bddExistAbstract(bdd, U[m], xcube)); + mtr = Cudd_CountMinterm(bdd, rN, n); + Cudd_RecursiveDeref(bdd,rN); + + if (pr > 0) { + (void) fprintf(stdout, "layer = %d mtl = %g mtc = %g mtr = %g", + m, mtl, mtc, mtr); + } + + if ((mtc > MANY_TIMES * mtl) || (mtc > MANY_TIMES * mtr)) { + if (pr>0) (void) fprintf(stdout, " R\n"); + rhombus(bdd, m, neW, U, x, y, z, n, pryz, prxz, stats); + } else if (mtr > MANY_TIMES * mtc) { + if (pr>0) (void) fprintf(stdout, " H\n"); + hourglass(bdd, m, neW, U, x, y, z, n, pryz, prxz, stats); + } else { + if (pr>0) (void) fprintf(stdout, " T\n"); + trellis(bdd, m, neW, U, x, y, z, n, pryz, prxz, stats); + } + return; + +} /* end of propagate_maximal_flow */ + + +/**Function******************************************************************** + + Synopsis [Selects edges from a trellis-type bilayer.] + + Description [Selects edges from a trellis-type bilayer. Used to pull flow. + First a matching is found in the left layer. Then the paths are extended + (if possible) through the right layer. This process is repeated until a + maximal flow is found.] + + SideEffects [None] + + SeeAlso [rhombus hourglass trellisPush] + +******************************************************************************/ +static void +trellis( + DdManager * bdd, + int m /* center level of current bilayer */, + DdNode ** neW /* array of node levels */, + DdNode ** U /* array of edge layers */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* arrays of variables for rows and columns */, + int n /* number of x variables */, + DdNode * pryz, + DdNode * prxz /* priority functions */, + flowStats * stats) +{ + DdNode *one, *zero, + *p, *q, *r, + *Uin, /* edges to be matched from U[m-1] */ + *Uout, /* edges to be matched from U[m] */ + *P, + *LU, *RU, /* left-unique and right-unique sets of edges */ + *D, + *Ml, *Mr; /* nodes matched from left and right */ + int k, + pr; /* print control */ + + pr = stats->pr; + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /*Uout(x,y)=U^m(x,y)*/ + Cudd_Ref(Uout = U[m]); + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + /*Uin(x,y)=U^{m-1}(x,y)*/ + Cudd_Ref(Uin = U[m-1]); + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + for(k = 0; k < MAXFPIT; k++) { + stats->fpit++; + /*LU(x,y)=Uin(x,y)\cdot\overline{\exists_{z}(Uin(z,y)\cdot\Pi(x,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Uin, x, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, prxz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(LU = Cudd_bddAnd(bdd, Uin, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + if(pr>3){(void)fprintf(stdout,"LU");Cudd_PrintDebug(bdd,LU,n<<1,pr);} + /*D(x,y)= LU(x,y)\cdot \overline{\exists_{z}(LU(x,z)\cdot \Pi(y,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, LU, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, pryz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(D = Cudd_bddAnd(bdd, LU, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,LU); + if(pr>3){(void)fprintf(stdout,"D");Cudd_PrintDebug(bdd,D,n<<1,pr);} + /*Ml(y)=\exists_{x}D(x,y)*/ + Cudd_Ref(Ml = Cudd_bddExistAbstract(bdd, D, xcube)); + if(pr>3){(void)fprintf(stdout,"Ml");Cudd_PrintDebug(bdd,Ml,n,pr);} + /*P(x,y)=Ml(x)\cdot Uout(x,y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Ml, x, y, n)); + Cudd_Ref(P = Cudd_bddAnd(bdd, p, Uout)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Ml); + if(pr>3){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n<<1,pr);} + /*RU(x,y)= P(x,y)\cdot \overline{\exists_{z}(P(x,z)\cdot \Pi(y,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, P, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, pryz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(RU = Cudd_bddAnd(bdd, P, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,P); + if(pr>3){(void)fprintf(stdout,"RU");Cudd_PrintDebug(bdd,RU,n<<1,pr);} + /*Mr(x)=\exists_{y}RU(x,y)*/ + Cudd_Ref(Mr = Cudd_bddExistAbstract(bdd, RU, ycube)); + if(pr>3){(void)fprintf(stdout,"Mr");Cudd_PrintDebug(bdd,Mr,n,pr);} + /*D(x,y)=D(x,y)\cdot Mr(y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Mr, x, y, n)); + Cudd_RecursiveDeref(bdd,Mr); + Cudd_Ref(q = Cudd_bddAnd(bdd, D, p)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,D); + D = q; + if(pr>3){(void)fprintf(stdout,"D");Cudd_PrintDebug(bdd,D,n<<1,pr);} + /*Uin(x,y)=Uin(x,y)-D(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uin, Cudd_Not(D))); + Cudd_RecursiveDeref(bdd,Uin); + Uin = p; + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + /*Uout(x,y)=Uout(x,y)-RU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uout, Cudd_Not(RU))); + Cudd_RecursiveDeref(bdd,Uout); + Cudd_RecursiveDeref(bdd,RU); + Uout = p; + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + /*\KW{if}(($D(x,y)=zero$)~~\KW{or}~~($Uin(x,y)=zero$)~~\KW{or} + ($Uout(x,y)=zero$))~~KW{break}*/ + if ((D == zero)||(Uin == zero)||(Uout == zero)) { + Cudd_RecursiveDeref(bdd,D); + break; + } + Cudd_RecursiveDeref(bdd,D); + + } /* Next least fixed point iteration with smaller Uin and Uout */ + if (k == MAXFPIT) (void) fprintf(stderr, + "Trellis: WARNING! MAXFPIT (%d) exceeded processing Layer %d.\n", + MAXFPIT, m); + + if (Uin != zero) { + /* $U^{m-1}(x,y) = U^{m-1}(x,y)-Uin(x,y)$*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, U[m-1], Cudd_Not(Uin))); + Cudd_RecursiveDeref(bdd,U[m-1]); + U[m-1] = p; + /* $new^{m-1}(x,y) = \esists_yU^{m-1}(x,y)$*/ + Cudd_RecursiveDeref(bdd,neW[m-1]); + Cudd_Ref(neW[m-1] = Cudd_bddExistAbstract(bdd, U[m-1], ycube)); + } + if(pr>2){(void)fprintf(stdout,"U[%d]",m-1); Cudd_PrintDebug(bdd,U[m-1],n<<1,pr);} + if(pr>2){(void)fprintf(stdout,"new[%d]",m-1); + Cudd_PrintDebug(bdd,neW[m-1],n,pr);} + + Cudd_RecursiveDeref(bdd,Uin); + Cudd_RecursiveDeref(bdd,Uout); + + return; + +} /* end of trellis */ + + +/**Function******************************************************************** + + Synopsis [Selects edges from a rhombus-type bilayer.] + + Description [Selects edges from a rhombus-type bilayer. Used to pull flow. + Makes the left layer left-unique and the right layer right-unique. Prunes + and repeats until convergence to a maximal flow. It makes sure that all + intermediate points of the two-arc paths are disjoint at each iteration.] + + SideEffects [None] + + SeeAlso [trellis hourglass rhombusPush] + +******************************************************************************/ +static void +rhombus( + DdManager * bdd, + int m /* center of current bilayer */, + DdNode ** neW, + DdNode ** U /* arrays for flow propagation */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* arrays of variables for rows and columns */, + int n /* number of x variables */, + DdNode * pryz, + DdNode * prxz /* priority functions */, + flowStats * stats) +{ + DdNode *one, *zero, + *p, *q, *r, + *Uin, /* edges to be matched from U[m-1] */ + *Uout, /* edges to be matched from U[m] */ + *P, + *LU, *RU, /* left-unique and right-unique sets of edges */ + *Ml, *Mr; /* nodes matched from left and right */ + int k, + pr; /* print control */ + + pr = stats->pr; + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /*Uout(x,y)=U^m(x,y)*/ + Cudd_Ref(Uout = U[m]); + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*Uin(x,y)=U^{m-1}(x,y)*/ + Cudd_Ref(Uin = U[m-1]); + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + for(k = 0; k < MAXFPIT; k++) { + stats->fpit++; + /*LU(x,y)=Uin(x,y)\cdot\overline{\exists_{z}(Uin(z,y)\cdot\Pi(x,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Uin, x, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, prxz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(LU = Cudd_bddAnd(bdd, Uin, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + if(pr>3){(void)fprintf(stdout,"LU");Cudd_PrintDebug(bdd,LU,n<<1,pr);} + /*Ml(y)=\exists_{x}LU(x,y)*/ + Cudd_Ref(Ml = Cudd_bddExistAbstract(bdd, LU, xcube)); + if(pr>3){(void)fprintf(stdout,"Ml");Cudd_PrintDebug(bdd,Ml,n,pr);} + /*P(x,y)=Ml(x)\cdot Uout(x,y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Ml, x, y, n)); + Cudd_Ref(P = Cudd_bddAnd(bdd, p, Uout)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Ml); + if(pr>3){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n<<1,pr);} + /*RU(x,y)= P(x,y)\cdot \overline{\exists_{z}(P(x,z)\cdot \Pi(y,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, P, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, pryz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(RU = Cudd_bddAnd(bdd, P, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,P); + if(pr>3){(void)fprintf(stdout,"RU");Cudd_PrintDebug(bdd,RU,n<<1,pr);} + /*Mr(x)=\exists_{y}RU(x,y)*/ + Cudd_Ref(Mr = Cudd_bddExistAbstract(bdd, RU, ycube)); + if(pr>3){(void)fprintf(stdout,"Mr");Cudd_PrintDebug(bdd,Mr,n,pr);} + /*LU(x,y)=LU(x,y)\cdot Mr(y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Mr, x, y, n)); + Cudd_RecursiveDeref(bdd,Mr); + Cudd_Ref(q = Cudd_bddAnd(bdd, LU, p)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,LU); + LU = q; + if(pr>3){(void)fprintf(stdout,"LU");Cudd_PrintDebug(bdd,LU,n<<1,pr);} + /*Uin(x,y)=Uin(x,y)-LU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uin, Cudd_Not(LU))); + Cudd_RecursiveDeref(bdd,Uin); + Uin = p; + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + /*Uout(x,y)=Uout(x,y)-RU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uout, Cudd_Not(RU))); + Cudd_RecursiveDeref(bdd,Uout); + Cudd_RecursiveDeref(bdd,RU); + Uout = p; + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + /*\KW{if}(($LU(x,y)=zero$)~~\KW{or}~~($Uin(x,y)=zero$)~~\KW{or} + ($Uout(x,y)=zero$))~~KW{break}*/ + if((LU == zero)||(Uin == zero)||(Uout == zero)) { + Cudd_RecursiveDeref(bdd,LU); + break; + } + Cudd_RecursiveDeref(bdd,LU); + + } /* Next least fixed point iteration with smaller Uin and Uout */ + if (k == MAXFPIT) (void) fprintf(stderr, + "Rhombus: WARNING! MAXFPIT (%d) exceeded processing Layer %d.\n", + MAXFPIT, m); + + if (Uin != zero) { + /* $U^{m-1}(x,y) = U^{m-1}(x,y)-Uin(x,y)$*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, U[m-1], Cudd_Not(Uin))); + Cudd_RecursiveDeref(bdd,U[m-1]); + U[m-1] = p; + /* $new^{m-1}(x,y) = \esists_yU^{m-1}(x,y)$*/ + Cudd_RecursiveDeref(bdd,neW[m-1]); + Cudd_Ref(neW[m-1] = Cudd_bddExistAbstract(bdd, U[m-1], ycube)); + } + if(pr>2){(void)fprintf(stdout,"U[%d]",m-1); Cudd_PrintDebug(bdd,U[m-1],n<<1,pr);} + if(pr>2){ + (void)fprintf(stdout,"new[%d]",m-1); + Cudd_PrintDebug(bdd,neW[m-1],n,pr); + } + Cudd_RecursiveDeref(bdd,Uin); + Cudd_RecursiveDeref(bdd,Uout); + + return; + +} /* end of rhombus */ + + +/**Function******************************************************************** + + Synopsis [Selects edges from a hourglass-type bilayer.] + + Description [Selects edges from a hourglass-type bilayer. Used to + pull flow. Method described in paper. More general, but more + expensive than the others.] + + SideEffects [None] + + SeeAlso [trellis rhombus hourglassPush] + +******************************************************************************/ +static void +hourglass( + DdManager * bdd, + int m /* center level of current bilayer */, + DdNode ** neW, + DdNode ** U /* arrays for flow propagation */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* arrays of variables for rows and columns */, + int n /* number of x variables */, + DdNode * pryz, + DdNode * prxz /* priority functions */, + flowStats * stats) +{ + DdNode *one, *zero, + *przy, + *p, *q, *r, + *Uin, /* edges to be matched from U[m-1] */ + *Uout, /* edges to be matched from U[m] */ + *P, *Q, + *PA, *D; + int k, + pr; /* print control */ + + pr = stats->pr; + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /* Build priority function. */ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, pryz, y, z, n)); + Cudd_Ref(przy = Cudd_bddAdjPermuteX(bdd,p,x,n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>2){(void)fprintf(stdout,"przy");Cudd_PrintDebug(bdd,przy,n*3,pr);} + + /*Uout(x,y)=U^m(x,y)*/ + Cudd_Ref(Uout = U[m]); + if(pr>1){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*Uin(x,y)=U^{m-1}(x,y)*/ + Cudd_Ref(Uin = U[m-1]); + if(pr>1){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + for(k = 0; k < MAXFPIT; k++) { + stats->fpit++; + /*P(x,y,z)=Uin(x,y)\cdot Uout(y,z)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Uout, y, z, n)); + if(pr>2){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n<<1,pr);} + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, p, x, y, n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>2){(void)fprintf(stdout,"q");Cudd_PrintDebug(bdd,q,n<<1,pr);} + Cudd_Ref(P = Cudd_bddAnd(bdd, Uin, q)); + Cudd_RecursiveDeref(bdd,q); + if(pr>1){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n*3,pr);} + /*PA(x,z)=\exists_yP(x,y,z)*/ + Cudd_Ref(PA = Cudd_bddExistAbstract(bdd, P, ycube)); + if(pr>2){(void)fprintf(stdout,"PA");Cudd_PrintDebug(bdd,PA,n<<1,pr);} + if(pr>3) { + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, PA, xcube)); + (void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, PA, zcube)); + (void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr); + Cudd_RecursiveDeref(bdd,p); + } + /*Q(x,z)= PA(x,z)\cdot \overline{\exists_{y}(PA(x,y)\cdot \Pi(z,y))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, PA, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, przy, ycube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(Q = Cudd_bddAnd(bdd, PA, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,PA); + if(pr>2){(void)fprintf(stdout,"Q");Cudd_PrintDebug(bdd,Q,n<<1,pr);} + if(pr>3) { + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, Q, xcube)); + (void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr); + Cudd_RecursiveDeref(bdd,p); + } + /*D(x,z)= Q(x,z)\cdot \overline{\exists_{y}(Q(y,z)\cdot \Pi(x,y))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Q, x, y, n)); + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, prxz, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, q, ycube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,q); + Cudd_Ref(D = Cudd_bddAnd(bdd, Q, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,Q); + if(pr>1){(void)fprintf(stdout,"D");Cudd_PrintDebug(bdd,D,n<<1,pr);} + /*P(x,y,z)=P(x,y,z)\cdot D(x,z)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, P, D)); + Cudd_RecursiveDeref(bdd,D); + Cudd_RecursiveDeref(bdd,P); + P = p; + if(pr>2){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n*3,pr);} + /*Uin(x,y)=Uin(x,y)-\exists_zP(x,y,z)*/ + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, P, zcube)); + if(pr>3){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n<<1,pr);} + Cudd_Ref(q = Cudd_bddAnd(bdd, Uin, Cudd_Not(p))); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Uin); + Uin = q; + if(pr>1){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + /*Uout(x,y)=Uout(x,y)-\exists_zP(z,x,y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, P, x, y, n)); + if(pr>3){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n*3,pr);} + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, p, y, z, n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>3){(void)fprintf(stdout,"r");Cudd_PrintDebug(bdd,r,n*3,pr);} + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, r, zcube)); + Cudd_RecursiveDeref(bdd,r); + if(pr>3){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n<<1,pr);} + Cudd_Ref(q = Cudd_bddAnd(bdd, Uout, Cudd_Not(p))); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Uout); + Uout = q; + if(pr>1){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + /*\KW{if}(($P(x,y,z)=zero$)~~\KW{or}~~($Uin(x,y)=zero$)~~\KW{or} + ($Uout(x,y)=zero$))~~KW{break}*/ + if((P == zero)||(Uin == zero)||(Uout == zero)) { + Cudd_RecursiveDeref(bdd,P); + break; + } + Cudd_RecursiveDeref(bdd,P); + + } /* Next least fixed point iteration with smaller P */ + if (k == MAXFPIT) (void) fprintf(stderr, + "Hourglass: WARNING! MAXFPIT (%d) exceeded processing Layer %d.\n", + MAXFPIT, m); + + if (Uin != zero) { + /* $U^{m-1}(x,y) = U^{m-1}(x,y)-Uin(x,y)$*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, U[m-1], Cudd_Not(Uin))); + Cudd_RecursiveDeref(bdd,U[m-1]); + U[m-1] = p; + /* $new^{m-1}(x,y) = \esists_yU^{m-1}(x,y)$*/ + Cudd_RecursiveDeref(bdd,neW[m-1]); + Cudd_Ref(neW[m-1] = Cudd_bddExistAbstract(bdd, U[m-1], ycube)); + } + if(pr>1){(void)fprintf(stdout,"U[%d]",m-1); Cudd_PrintDebug(bdd,U[m-1],n<<1,pr);} + if(pr>1){(void)fprintf(stdout,"new[%d]",m-1); + Cudd_PrintDebug(bdd,neW[m-1],n,pr);} + + Cudd_RecursiveDeref(bdd,Uin); + Cudd_RecursiveDeref(bdd,Uout); + Cudd_RecursiveDeref(bdd,przy); + + return; + +} /* end of hourglass */ + + +/**Function******************************************************************** + + Synopsis [Pushes flow through useful edges.] + + Description [Pushes flow from the source(s) to the sink(s) through + useful edges.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +maximal_push( + DdManager * bdd, + int l /* Depth of layered network for current phase */, + DdNode ** U /* array of edge sets for flow propagation */, + DdNode ** F /* edge and flow relations */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* arrays of variables for rows and columns */, + int n /* number of x variables */, + DdNode * pryz, + DdNode * prxz /* priority functions */, + flowStats * stats) +{ + DdNode *p, *q, *r, + *UT, + *lN, *cN, *rN; /* left, center, right nodes of bilayer */ + double mtl, mtc, mtr; + int m, + pr; /* print control */ + + pr = stats->pr; + + if (l == 0) { + /* F(x,y) = F(x,y) + U^{0}(x,y) */ + Cudd_Ref(q = Cudd_bddOr(bdd, *F, U[0])); + Cudd_RecursiveDeref(bdd,*F); + *F = q; + if(pr>3){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + return; + } + + for (m = 1; m < l; m++) { + /* lN(x) = \exists_y U^{m-1}(x,y) */ + Cudd_Ref(lN = Cudd_bddExistAbstract(bdd, U[m-1], ycube)); + mtl = Cudd_CountMinterm(bdd, lN, n); + Cudd_RecursiveDeref(bdd,lN); + + /* cN(y) = \exists_x U^{m-1}(x,y) */ + Cudd_Ref(cN = Cudd_bddExistAbstract(bdd, U[m-1], xcube)); + mtc = Cudd_CountMinterm(bdd, cN, n); + Cudd_RecursiveDeref(bdd,cN); + + /* rN(y) = \exists_x U^{m}(x,y) */ + Cudd_Ref(rN = Cudd_bddExistAbstract(bdd, U[m], xcube)); + mtr = Cudd_CountMinterm(bdd, rN, n); + Cudd_RecursiveDeref(bdd,rN); + + if (pr > 0) { + (void) fprintf(stdout, "layer = %d mtl = %g mtc = %g mtr = %g", + m, mtl, mtc, mtr); + } + if ((mtc > MANY_TIMES * mtl) && !(mtr > MANY_TIMES * mtl)) { + if (pr>0) (void) fprintf(stdout, " R\n"); + rhombusPush(bdd, m, U, x, y, z, n, pryz, prxz, stats); + } else if (mtl > MANY_TIMES * mtc) { + if (pr>0) (void) fprintf(stdout, " H\n"); + hourglassPush(bdd, m, U, x, y, z, n, pryz, prxz, stats); + } else { + if (pr>0) (void) fprintf(stdout, " T\n"); + trellisPush(bdd, m, U, x, y, z, n, pryz, prxz, stats); + } + + /* F(x,y) = F(x,y) + U^{m-1}(x,y) \cdot \overline{F(y,x)} */ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, *F, x, y, n)); + Cudd_Ref(q = Cudd_bddAnd(bdd, Cudd_Not(p), U[m-1])); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(r = Cudd_bddOr(bdd, *F, q)); + Cudd_RecursiveDeref(bdd,q); + Cudd_RecursiveDeref(bdd,*F); + *F = r; + if(pr>3){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + + /* F(x,y) = F(x,y) - U^{m-1}(y,x) */ + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, U[m-1], x, y, n)); + Cudd_Ref(q = Cudd_bddAnd(bdd, *F, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,*F); + *F = q; + if(pr>3){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + + } /* Push maximal flow to next layer */ + + /*F(x,y)=F(x,y)+U^{l-1}(x,y)\cdot\overline{F(y,x)}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, *F, x, y, n)); + Cudd_Ref(q = Cudd_bddAnd(bdd, Cudd_Not(p), U[l-1])); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(r = Cudd_bddOr(bdd, *F, q)); + Cudd_RecursiveDeref(bdd,q); + Cudd_RecursiveDeref(bdd,*F); + *F = r; + if(pr>3){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + + /*F(y,x)=F(y,x)-U^{l-1}(x,y)*/ + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, U[l-1], x, y, n)); + Cudd_Ref(q = Cudd_bddAnd(bdd, *F, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,*F); + *F = q; + if(pr>1){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + + /*UT(x,y)=\exists_y(U^{l-1}(y,x))\cdot U^{l}(x,y)*/ + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, U[l-1], xcube)); + if(pr>4){(void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr);} + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, p, x, y, n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>4){(void) fprintf(stdout,"q");Cudd_PrintDebug(bdd,q,n,pr);} + Cudd_Ref(UT = Cudd_bddAnd(bdd, U[l], q)); + Cudd_RecursiveDeref(bdd,q); + if(pr>2){(void) fprintf(stdout,"UT");Cudd_PrintDebug(bdd,UT,n<<1,pr);} + + /*F(x,y)=F(x,y)+UT(x,y)\cdot\overline{F(y,x)}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, *F, x, y, n)); + Cudd_Ref(q = Cudd_bddAnd(bdd, Cudd_Not(p), UT)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(r = Cudd_bddOr(bdd, *F, q)); + Cudd_RecursiveDeref(bdd,q); + Cudd_RecursiveDeref(bdd,*F); + *F = r; + if(pr>3){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + + /*F(y,x)=F(y,x)-UT(x,y)*/ + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, UT, x, y, n)); + Cudd_RecursiveDeref(bdd,UT); + Cudd_Ref(q = Cudd_bddAnd(bdd, *F, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,*F); + *F = q; + if(pr>1){(void) fprintf(stdout,"F");Cudd_PrintDebug(bdd,*F,n<<1,pr);} + + return; + +} /* end of maximal_push */ + + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +trellisPush( + DdManager * bdd, + int m /* Current layer */, + DdNode ** U /* Array of edge sets for flow propagation */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* Arrays of variables for rows and columns */, + int n /* Number of x variables */, + DdNode * pryz, + DdNode * prxz /* Priority functions */, + flowStats * stats) +{ + DdNode *one, *zero, + *p, *r, + *Uin, /* Edges to be matched from U[m-1] */ + *Uout, /* Edges to be matched from U[m] */ + *RU, *LU, + *P, + *Ml; + + int i, + pr; /* Print control */ + + pr = stats->pr; + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /*Uout(x,y)=U^m(x,y)*/ + Cudd_Ref(Uout = U[m]); + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*Uin(x,y)=U^{m-1}(x,y)*/ + Cudd_Ref(Uin = U[m-1]); + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + for(i=0; ifpit++; + /*LU(x,y)=Uin(x,y)\cdot\overline{\exists_{z}(Uin(z,y)\cdot\Pi(x,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Uin, x, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, prxz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(LU = Cudd_bddAnd(bdd, Uin, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + if(pr>3){(void)fprintf(stdout,"LU");Cudd_PrintDebug(bdd,LU,n<<1,pr);} + + /*Ml(y)=\exists_{x}LU(x,y)*/ + Cudd_Ref(Ml = Cudd_bddExistAbstract(bdd, LU, xcube)); + if(pr>3){(void)fprintf(stdout,"Ml");Cudd_PrintDebug(bdd,Ml,n,pr);} + + /*P(x,y)=Ml(x)\cdot Uout(x,y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Ml, x, y, n)); + Cudd_Ref(P = Cudd_bddAnd(bdd, p, Uout)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Ml); + if(pr>3){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n<<1,pr);} + + /*RU(x,y)= P(x,y)\cdot \overline{\exists_{z}(P(x,z)\cdot \Pi(y,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, P, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, pryz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(RU = Cudd_bddAnd(bdd, P, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,P); + if(pr>3){(void)fprintf(stdout,"RU");Cudd_PrintDebug(bdd,RU,n<<1,pr);} + + /*Uin(x,y)=Uin(x,y)-LU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uin, Cudd_Not(LU))); + Cudd_RecursiveDeref(bdd,Uin); + Uin = p; + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + /*Uout(x,y)=Uout(x,y)-RU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uout, Cudd_Not(RU))); + Cudd_RecursiveDeref(bdd,Uout); + Cudd_RecursiveDeref(bdd,RU); + Uout = p; + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*\KW{if}(($LU(x,y)=zero$)~~\KW{or}~~($Uin(x,y)=zero$))~~KW{break}*/ + if((LU == zero)||(Uin == zero)) { + Cudd_RecursiveDeref(bdd,LU); + break; + } + + Cudd_RecursiveDeref(bdd,LU); + + } /* Next least fixed point iteration with smaller Uin and Uout */ + if (i == MAXFPIT) (void) fprintf(stderr, + "TrellisPush: ERROR! MAXFPIT (%d) exceeded at layer %d.\n", + MAXFPIT, m); + + /* $U^{m}(x,y) = U^{m}(x,y)-Uout(x,y)$*/ + if (Uout != zero) { + Cudd_Ref(p = Cudd_bddAnd(bdd, U[m], Cudd_Not(Uout))); + Cudd_RecursiveDeref(bdd,U[m]); + U[m] = p; + if(pr>3){(void)fprintf(stdout,"U[%d]",m); + Cudd_PrintDebug(bdd,U[m],n<<1,pr);} + } + + Cudd_RecursiveDeref(bdd,Uin); + Cudd_RecursiveDeref(bdd,Uout); + +} /* end of trellisPush */ + + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +rhombusPush( + DdManager * bdd, + int m /* Current layer */, + DdNode ** U /* Array of edge sets for flow propagation */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* Arrays of variables for rows and columns */, + int n /* Number of x variables */, + DdNode * pryz, + DdNode * prxz /* Priority functions */, + flowStats * stats) +{ + DdNode *one, *zero, + *p, *r, + *Uin, /* Edges to be matched from U[m-1] */ + *Uout, /* Edges to be matched from U[m] */ + *RU, *LU, + *P, + *Ml; + + int i, + pr; /* Print control */ + + pr = stats->pr; + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /*Uout(x,y)=U^m(x,y)*/ + Cudd_Ref(Uout = U[m]); + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*Uin(x,y)=U^{m-1}(x,y)*/ + Cudd_Ref(Uin = U[m-1]); + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + for(i = 0; i < MAXFPIT; i++) { + stats->fpit++; + /*RU(x,y)=Uin(x,y)\cdot\overline{\exists_{z}(Uin(x,z)\cdot\Pi(y,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Uin, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, pryz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(RU = Cudd_bddAnd(bdd, Uin, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + if(pr>3){(void)fprintf(stdout,"RU");Cudd_PrintDebug(bdd,RU,n<<1,pr);} + + /*Ml(y)=\exists_{x}RU(x,y)*/ + Cudd_Ref(Ml = Cudd_bddExistAbstract(bdd, RU, xcube)); + if(pr>3){(void)fprintf(stdout,"Ml");Cudd_PrintDebug(bdd,Ml,n,pr);} + + /*P(x,y)=Ml(x)\cdot Uout(x,y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Ml, x, y, n)); + Cudd_Ref(P = Cudd_bddAnd(bdd, p, Uout)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Ml); + if(pr>3){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n<<1,pr);} + + /*LU(x,y)= P(x,y)\cdot \overline{\exists_{z}(P(z,y)\cdot \Pi(x,z))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, P, x, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, prxz, zcube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(LU = Cudd_bddAnd(bdd, P, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,P); + if(pr>3){(void)fprintf(stdout,"LU");Cudd_PrintDebug(bdd,LU,n<<1,pr);} + + /*Uin(x,y)=Uin(x,y)-RU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uin, Cudd_Not(RU))); + Cudd_RecursiveDeref(bdd,Uin); + Uin = p; + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + /*Uout(x,y)=Uout(x,y)-LU(x,y)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, Uout, Cudd_Not(LU))); + Cudd_RecursiveDeref(bdd,Uout); + Cudd_RecursiveDeref(bdd,LU); + Uout = p; + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*\KW{if}(($RU(x,y)=zero$)~~\KW{or}~~($Uin(x,y)=zero$))~~KW{break}*/ + if((RU == zero)||(Uin == zero)) { + Cudd_RecursiveDeref(bdd,RU); + break; + } + + Cudd_RecursiveDeref(bdd,RU); + + } /* Next least fixed point iteration with smaller Uin and Uout */ + if (i == MAXFPIT) (void) fprintf(stderr, + "RhombusPush: ERROR! MAXFPIT (%d) exceeded at layer %d.\n", + MAXFPIT, m); + + /* $U^{m}(x,y) = U^{m}(x,y)-Uout(x,y)$*/ + if (Uout != zero) { + Cudd_Ref(p = Cudd_bddAnd(bdd, U[m], Cudd_Not(Uout))); + Cudd_RecursiveDeref(bdd,U[m]); + U[m] = p; + if(pr>3){(void)fprintf(stdout,"U[%d]",m); + Cudd_PrintDebug(bdd,U[m],n<<1,pr);} + } + + Cudd_RecursiveDeref(bdd,Uin); + Cudd_RecursiveDeref(bdd,Uout); + + return; + +} /* end of rhombusPush */ + + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +hourglassPush( + DdManager * bdd, + int m /* Current layer */, + DdNode ** U /* Array of edge sets for flow propagation */, + DdNode ** x, + DdNode ** y, + DdNode ** z /* Arrays of variables for rows and columns */, + int n /* Number of x variables */, + DdNode * pryz, + DdNode * prxz /* Priority functions */, + flowStats * stats) +{ + DdNode *one, *zero, + *przy, + *p, *q, *r, + *Uin, /* Edges to be matched from U[m-1] */ + *Uout, /* Edges to be matched from U[m] */ + *P, *Q, + *PA, *D; + + int i, + pr; /* Print control */ + + pr = stats->pr; + + one = Cudd_ReadOne(bdd); + zero = Cudd_Not(one); + + /* Build priority function. */ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, pryz, y, z, n)); + Cudd_Ref(przy = Cudd_bddAdjPermuteX(bdd,p,x,n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>2){(void)fprintf(stdout,"przy");Cudd_PrintDebug(bdd,przy,n*3,pr);} + + /*Uout(x,y)=U^m(x,y)*/ + Cudd_Ref(Uout = U[m]); + if(pr>3){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*Uin(x,y)=U^{m-1}(x,y)*/ + Cudd_Ref(Uin = U[m-1]); + if(pr>3){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + for(i = 0; i < MAXFPIT; i++) { + stats->fpit++; + /*P(x,y,z)=Uin(x,y)\cdot Uout(y,z)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Uout, y, z, n)); + if(pr>2){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n<<1,pr);} + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, p, x, y, n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>2){(void)fprintf(stdout,"q");Cudd_PrintDebug(bdd,q,n<<1,pr);} + Cudd_Ref(P = Cudd_bddAnd(bdd, Uin, q)); + Cudd_RecursiveDeref(bdd,q); + if(pr>1){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n*3,pr);} + + /*PA(x,z)=\exists_yP(x,y,z)*/ + Cudd_Ref(PA = Cudd_bddExistAbstract(bdd, P, ycube)); + if(pr>2){(void)fprintf(stdout,"PA");Cudd_PrintDebug(bdd,PA,n<<1,pr);} + if(pr>3) { + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, PA, xcube)); + (void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, PA, zcube)); + (void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr); + Cudd_RecursiveDeref(bdd,p); + } + + /*Q(x,z)= PA(x,z)\cdot \overline{\exists_{y}(PA(x,y)\cdot \Pi(z,y))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, PA, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, przy, ycube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_Ref(Q = Cudd_bddAnd(bdd, PA, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,PA); + if(pr>2){(void)fprintf(stdout,"Q");Cudd_PrintDebug(bdd,Q,n<<1,pr);} + if(pr>3) { + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, Q, xcube)); + (void) fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n,pr); + Cudd_RecursiveDeref(bdd,p); + } + + /*D(x,z)= Q(x,z)\cdot \overline{\exists_{y}(Q(y,z)\cdot \Pi(x,y))}*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, Q, x, y, n)); + Cudd_Ref(q = Cudd_bddSwapVariables(bdd, prxz, y, z, n)); + Cudd_Ref(r = Cudd_bddAndAbstract(bdd, p, q, ycube)); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,q); + Cudd_Ref(D = Cudd_bddAnd(bdd, Q, Cudd_Not(r))); + Cudd_RecursiveDeref(bdd,r); + Cudd_RecursiveDeref(bdd,Q); + if(pr>1){(void)fprintf(stdout,"D");Cudd_PrintDebug(bdd,D,n<<1,pr);} + + /*P(x,y,z)=P(x,y,z)\cdot D(x,z)*/ + Cudd_Ref(p = Cudd_bddAnd(bdd, P, D)); + Cudd_RecursiveDeref(bdd,D); + Cudd_RecursiveDeref(bdd,P); + P = p; + if(pr>2){(void)fprintf(stdout,"P");Cudd_PrintDebug(bdd,P,n*3,pr);} + + /*Uin(x,y)=Uin(x,y)-\exists_zP(x,y,z)*/ + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, P, zcube)); + if(pr>3){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n<<1,pr);} + Cudd_Ref(q = Cudd_bddAnd(bdd, Uin, Cudd_Not(p))); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Uin); + Uin = q; + if(pr>1){(void)fprintf(stdout,"Uin");Cudd_PrintDebug(bdd,Uin,n<<1,pr);} + + /*Uout(x,y)=Uout(x,y)-\exists_zP(z,x,y)*/ + Cudd_Ref(p = Cudd_bddSwapVariables(bdd, P, x, y, n)); + if(pr>3){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n*3,pr);} + Cudd_Ref(r = Cudd_bddSwapVariables(bdd, p, y, z, n)); + Cudd_RecursiveDeref(bdd,p); + if(pr>3){(void)fprintf(stdout,"r");Cudd_PrintDebug(bdd,r,n*3,pr);} + Cudd_Ref(p = Cudd_bddExistAbstract(bdd, r, zcube)); + Cudd_RecursiveDeref(bdd,r); + if(pr>3){(void)fprintf(stdout,"p");Cudd_PrintDebug(bdd,p,n<<1,pr);} + Cudd_Ref(q = Cudd_bddAnd(bdd, Uout, Cudd_Not(p))); + Cudd_RecursiveDeref(bdd,p); + Cudd_RecursiveDeref(bdd,Uout); + Uout = q; + if(pr>1){(void)fprintf(stdout,"Uout");Cudd_PrintDebug(bdd,Uout,n<<1,pr);} + + /*\KW{if}(($P(x,y,z)=zero$)~~\KW{or}~~($Uin(x,y)=zero$)~~\KW{or} + ($Uout(x,y)=zero$))~~KW{break}*/ + if((P == zero)||(Uin == zero)||(Uout == zero)) { + Cudd_RecursiveDeref(bdd,P); + break; + } + + Cudd_RecursiveDeref(bdd,P); + + } /* Next least fixed point iteration with smaller P */ + if (i == MAXFPIT) (void) fprintf(stderr, + "HourglassPush: ERROR! MAXFPIT (%d) exceeded at layer %d.\n", + MAXFPIT, m); + + /* $U^{m}(x,y) = U^{m}(x,y)-Uout(x,y)$*/ + if (Uout != zero) { + Cudd_Ref(p = Cudd_bddAnd(bdd, U[m], Cudd_Not(Uout))); + Cudd_RecursiveDeref(bdd,U[m]); + U[m] = p; + } + if(pr>1){(void)fprintf(stdout,"U[%d]",m); Cudd_PrintDebug(bdd,U[m],n<<1,pr);} + + Cudd_RecursiveDeref(bdd,Uin); + Cudd_RecursiveDeref(bdd,Uout); + Cudd_RecursiveDeref(bdd,przy); + + return; + +} /* end of hourglassPush */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntrShort.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrShort.c new file mode 100644 index 000000000..61ed980d3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrShort.c @@ -0,0 +1,578 @@ +/**CFile*********************************************************************** + + FileName [ntrShort.c] + + PackageName [ntr] + + Synopsis [Symbolic shortest paths algorithms.] + + Description [This file contains the functions that implement the + symbolic version of several shortest path algorithms described in the + JFM paper on ADDs.] + + Author [Fabio Somenzi, Iris Bahar] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: ntrShort.c,v 1.5 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * ntrBellman (DdManager *dd, DdNode *D, DdNode *source, DdNode **x, DdNode **y, int vars, int pr); +static DdNode * ntrWarshall (DdManager *dd, DdNode *D, DdNode **x, DdNode **y, int vars, int pr); +static DdNode * ntrSquare (DdManager *dd, DdNode *D, DdNode **x, DdNode **y, DdNode **z, int vars, int pr, int st); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Computes shortest paths in a state graph.] + + Description [Computes shortest paths in the state transition graph of + a network. Three methods are availabe: +
                    +
                  • Bellman-Ford algorithm for single-source shortest paths; the + algorithm computes the distance (number of transitions) from the initial + states to all states. +
                  • Floyd-Warshall algorithm for all-pair shortest paths. +
                  • Repeated squaring algorithm for all-pair shortest paths. +
                  + The function returns 1 in case of success; 0 otherwise. + ] + + SideEffects [ADD variables are created in the manager.] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_ShortestPaths( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + NtrPartTR *TR; + DdNode *edges, *source, *res, *r, *q, *bddSource; + DdNode **xadd, **yadd, **zadd; + int i; + int pr = option->verb; + int algorithm = option->shortPath; + int selectiveTrace = option->selectiveTrace; + int nvars = net->nlatches; + + /* Set background to infinity for shortest paths. */ + Cudd_SetBackground(dd,Cudd_ReadPlusInfinity(dd)); + + /* Build the monolithic TR. */ + TR = Ntr_buildTR(dd,net,option,NTR_IMAGE_MONO); + + /* Build the ADD variable vectors for x and y. */ + xadd = ALLOC(DdNode *, nvars); + yadd = ALLOC(DdNode *, nvars); + for(i = 0; i < nvars; i++) { + q = Cudd_addIthVar(dd,TR->x[i]->index); + Cudd_Ref(q); + xadd[i] = q; + q = Cudd_addIthVar(dd,TR->y[i]->index); + Cudd_Ref(q); + yadd[i] = q; + } + + /* Convert the transition relation BDD into an ADD... */ + q = Cudd_BddToAdd(dd,TR->part[0]); + Cudd_Ref(q); + /* ...replacing zeroes with infinities... */ + r = Cudd_addIte(dd,q,Cudd_ReadOne(dd),Cudd_ReadPlusInfinity(dd)); + Cudd_Ref(r); + Cudd_RecursiveDeref(dd,q); + /* ...and zeroing the diagonal. */ + q = Cudd_addXeqy(dd,nvars,xadd,yadd); + Cudd_Ref(q); + edges = Cudd_addIte(dd,q,Cudd_ReadZero(dd),r); + Cudd_Ref(edges); + Cudd_RecursiveDeref(dd,r); + Cudd_RecursiveDeref(dd,q); + + switch(algorithm) { + case NTR_SHORT_BELLMAN: + bddSource = Ntr_initState(dd,net,option); + source = Cudd_BddToAdd(dd,bddSource); + Cudd_Ref(source); + res = ntrBellman(dd,edges,source,xadd,yadd,nvars,pr); + if (res == NULL) return(0); + Cudd_Ref(res); + Cudd_RecursiveDeref(dd,source); + Cudd_RecursiveDeref(dd,bddSource); + if (pr >= 0) { + (void) fprintf(stdout,"Distance Matrix"); + Cudd_PrintDebug(dd,res,nvars,pr); + } + break; + case NTR_SHORT_FLOYD: + res = ntrWarshall(dd,edges,xadd,yadd,nvars,pr); + if (res == NULL) return(0); + Cudd_Ref(res); + if (pr >= 0) { + (void) fprintf(stdout,"Distance Matrix"); + Cudd_PrintDebug(dd,res,2*nvars,pr); + } + break; + case NTR_SHORT_SQUARE: + /* Create a third set of ADD variables. */ + zadd = ALLOC(DdNode *, nvars); + for(i = 0; i < nvars; i++) { + int level; + level = Cudd_ReadIndex(dd,TR->x[i]->index); + q = Cudd_addNewVarAtLevel(dd,level); + Cudd_Ref(q); + zadd[i] = q; + } + /* Compute the shortest paths. */ + res = ntrSquare(dd,edges,zadd,yadd,xadd,nvars,pr,selectiveTrace); + if (res == NULL) return(0); + Cudd_Ref(res); + /* Dispose of the extra variables. */ + for(i = 0; i < nvars; i++) { + Cudd_RecursiveDeref(dd,zadd[i]); + } + FREE(zadd); + if (pr >= 0) { + (void) fprintf(stdout,"Distance Matrix"); + Cudd_PrintDebug(dd,res,2*nvars,pr); + } + break; + default: + (void) printf("Unrecognized method. Try again.\n"); + return(0); + } + + /* Here we should compute the paths. */ + + /* Clean up. */ + Ntr_freeTR(dd,TR); + Cudd_RecursiveDeref(dd,edges); + Cudd_RecursiveDeref(dd,res); + for(i = 0; i < nvars; i++) { + Cudd_RecursiveDeref(dd,xadd[i]); + Cudd_RecursiveDeref(dd,yadd[i]); + } + FREE(xadd); + FREE(yadd); + + if (option->autoDyn & 1) { + (void) printf("Order after short path computation\n"); + if (!Bnet_PrintOrder(net,dd)) return(0); + } + + return(1); + +} /* end of Ntr_ShortestPaths */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Bellman-Ford algorithm for single-source shortest paths.] + + Description [Bellman-Ford algorithm for single-source shortest + paths. Returns the vector of the distances of all states from the + initial states. In case of multiple initial states the distance for + each state is from the nearest initial state. Negative-weight + cycles are detected, though only in the naive way. (Lack of + convergence after nodes-1 iterations.) In such a case, a constant + ADD with value minus infinity is returned. Bellman-Ford is based on + matrix-vector multiplication. The matrix is the distance matrix + D(x,y), such that D(a,b) is the length of the arc connecting state a + to state b. The vector V(x) stores the distances of all states from + the initial states. The actual vector used in the matrix-vector + multiplication is diff(x), that holds those distances that have + changed during the last update.] + + SideEffects [] + + SeeAlso [ntrWarshall ntrSquare] + +******************************************************************************/ +static DdNode * +ntrBellman( + DdManager *dd, + DdNode *D, + DdNode *source, + DdNode **x, + DdNode **y, + int vars, + int pr) +{ + DdNode *u, *w, *V, *min, *diff; + DdApaNumber i, nodes, one; + int digits = vars + 1; + + /* To avoid overflow when there are many variables, use APA. */ + nodes = Cudd_NewApaNumber(digits); + Cudd_ApaPowerOfTwo(digits,nodes,vars); + i = Cudd_NewApaNumber(digits); + one = Cudd_NewApaNumber(digits); + Cudd_ApaSetToLiteral(digits,one,1); + +#if 0 + /* Find the distances from the initial state along paths using one + ** arc. */ + w = Cudd_Cofactor(dd,D,source); /* works only if source is a cube */ + Cudd_Ref(w); + V = Cudd_addSwapVariables(dd,w,x,y,vars); + Cudd_Ref(V); + Cudd_RecursiveDeref(dd,w); +#endif + + /* The initial states are at distance 0. The other states are + ** initially at infinite distance. */ + V = Cudd_addIte(dd,source,Cudd_ReadZero(dd),Cudd_ReadPlusInfinity(dd)); + Cudd_Ref(V); + + /* Selective trace algorithm. For the next update, only consider the + ** nodes whose distance has changed in the last update. */ + diff = V; + Cudd_Ref(diff); + + for (Cudd_ApaSetToLiteral(digits,i,1); + Cudd_ApaCompare(digits,i,digits,nodes) < 0; + Cudd_ApaAdd(digits,i,one,i)) { + if (pr>2) {(void) printf("V"); Cudd_PrintDebug(dd,V,vars,pr);} + /* Compute the distances via triangulation as a function of x. */ + w = Cudd_addTriangle(dd,diff,D,x,vars); + Cudd_Ref(w); + Cudd_RecursiveDeref(dd,diff); + u = Cudd_addSwapVariables(dd,w,x,y,vars); + Cudd_Ref(u); + Cudd_RecursiveDeref(dd,w); + if (pr>2) {(void) printf("u"); Cudd_PrintDebug(dd,u,vars,pr);} + + /* Take the minimum of the previous distances and those just + ** computed. */ + min = Cudd_addApply(dd,Cudd_addMinimum,V,u); + Cudd_Ref(min); + Cudd_RecursiveDeref(dd,u); + if (pr>2) {(void) printf("min"); Cudd_PrintDebug(dd,min,vars,pr);} + + if (V == min) { /* convergence */ + Cudd_RecursiveDeref(dd,min); + if (pr>0) { + (void) printf("Terminating after "); + Cudd_ApaPrintDecimal(stdout,digits,i); + (void) printf(" iterations\n"); + } + break; + } + /* Find the distances that decreased. */ + diff = Cudd_addApply(dd,Cudd_addDiff,V,min); + Cudd_Ref(diff); + if (pr>2) {(void) printf("diff"); Cudd_PrintDebug(dd,diff,vars,pr);} + Cudd_RecursiveDeref(dd,V); + V = min; + } + /* Negative cycle detection. */ + if (Cudd_ApaCompare(digits,i,digits,nodes) == 0 && + diff != Cudd_ReadPlusInfinity(dd)) { + (void) printf("Negative cycle\n"); + Cudd_RecursiveDeref(dd,diff); + Cudd_RecursiveDeref(dd,V); + V = Cudd_ReadMinusInfinity(dd); + Cudd_Ref(V); + } + + Cudd_Deref(V); + FREE(i); + FREE(nodes); + FREE(one); + return(V); + +} /* end of ntrBellman */ + + +/**Function******************************************************************** + + Synopsis [Floyd-Warshall algorithm for all-pair shortest paths.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +ntrWarshall( + DdManager *dd, + DdNode *D, + DdNode **x, + DdNode **y, + int vars, + int pr) +{ + DdNode *one, *zero; + DdNode *xminterm, *w, *V, *V2; + DdNode *P, *R; + int i; + int nodes; + int k,u; + long start_time; + if (vars > 30) + nodes = 1000000000; + else + nodes = 1 << vars; + + one = DD_ONE(dd); + zero = DD_ZERO(dd); + Cudd_Ref(R = D); /* make copy of original matrix */ + + /* Extract pivot row and column from D */ + start_time = util_cpu_time(); + for (k = 0; k < nodes; k++) { + if (k % 10000 == 0) { + (void) printf("Starting iteration %d at time %s\n", + k,util_print_time(util_cpu_time() - start_time)); + } + Cudd_Ref(xminterm = one); + u = k; + for (i = vars-1; i >= 0; i--) { + if (u&1) { + Cudd_Ref(w = Cudd_addIte(dd,x[i],xminterm,zero)); + } else { + Cudd_Ref(w = Cudd_addIte(dd,x[i],zero,xminterm)); + } + Cudd_RecursiveDeref(dd,xminterm); + xminterm = w; + u >>= 1; + } + + Cudd_Ref(V = Cudd_Cofactor(dd,R,xminterm)); + Cudd_RecursiveDeref(dd,xminterm); + if (pr>2) {(void) printf("V"); Cudd_PrintDebug(dd,V,vars,pr);} + + + Cudd_Ref(xminterm = one); + u = k; + for (i = vars-1; i >= 0; i--) { + if (u&1) { + Cudd_Ref(w = Cudd_addIte(dd,y[i],xminterm,zero)); + } else { + Cudd_Ref(w = Cudd_addIte(dd,y[i],zero,xminterm)); + } + Cudd_RecursiveDeref(dd,xminterm); + xminterm = w; + u >>= 1; + } + + Cudd_Ref(V2 = Cudd_Cofactor(dd,R,xminterm)); + Cudd_RecursiveDeref(dd,xminterm); + if (pr>2) {(void) printf("V2"); Cudd_PrintDebug(dd,V2,vars,pr);} + + Cudd_Ref(P = Cudd_addOuterSum(dd,R,V,V2)); + + Cudd_RecursiveDeref(dd,V); + Cudd_RecursiveDeref(dd,V2); + Cudd_RecursiveDeref(dd,R); + R = P; + if (pr>2) {(void) printf("R"); Cudd_PrintDebug(dd,R,vars,pr);} + } + + Cudd_Deref(R); + return(R); + +} /* end of ntrWarshall */ + + +/**Function******************************************************************** + + Synopsis [Repeated squaring algorithm for all-pairs shortest paths.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +ntrSquare( + DdManager *dd /* manager */, + DdNode *D /* D(z,y): distance matrix */, + DdNode **x /* array of x variables */, + DdNode **y /* array of y variables */, + DdNode **z /* array of z variables */, + int vars /* number of variables in each of the three arrays */, + int pr /* verbosity level */, + int st /* use the selective trace algorithm */) +{ + DdNode *zero; + DdNode *I; /* identity matirix */ + DdNode *w, *V, *P, *M, *R, *RT; + DdNode *diff, *min, *minDiag; + int n; + int neg; + long start_time; + + zero = Cudd_ReadZero(dd); + /* Make a working copy of the original matrix. */ + R = D; + Cudd_Ref(R); + I = Cudd_addXeqy(dd,vars,z,y); /* identity matrix */ + Cudd_Ref(I); + + /* Make a copy of the matrix for the selective trace algorithm. */ + diff = R; + Cudd_Ref(diff); + + start_time = util_cpu_time(); + for (n = vars; n >= 0; n--) { + printf("Starting iteration %d at time %s\n",vars-n, + util_print_time(util_cpu_time() - start_time)); + + /* Check for negative cycles: They are identified by negative + ** elements on the diagonal. + */ + + /* Extract values from the diagonal. */ + Cudd_Ref(w = Cudd_addIte(dd,I,R,zero)); + minDiag = Cudd_addFindMin(dd,w); /* no need to ref */ + neg = Cudd_V(minDiag) < 0; + Cudd_RecursiveDeref(dd,w); + if (neg) { + Cudd_RecursiveDeref(dd,diff); + (void) printf("Negative cycle after %d iterations!\n",vars-n); + break; + } + + /* Prepare the first operand of matrix multiplication: + ** diff(z,y) -> RT(x,y) -> V(x,z) + */ + + /* RT(x,y) */ + Cudd_Ref(RT = Cudd_addSwapVariables(dd,diff,x,z,vars)); + Cudd_RecursiveDeref(dd,diff); + /* V(x,z) */ + Cudd_Ref(V = Cudd_addSwapVariables(dd,RT,y,z,vars)); + Cudd_RecursiveDeref(dd,RT); + if (pr > 0) { + double pathcount; + (void) printf("V"); Cudd_PrintDebug(dd,V,2*vars,pr); + pathcount = Cudd_CountPath(V); + (void) printf("Path count = %g\n", pathcount); + } + + /* V(x,z) * R(z,y) -> P(x,y) */ + Cudd_Ref(P = Cudd_addTriangle(dd,V,R,z,vars)); + Cudd_RecursiveDeref(dd,V); + /* P(x,y) => M(z,y) */ + Cudd_Ref(M = Cudd_addSwapVariables(dd,P,x,z,vars)); + Cudd_RecursiveDeref(dd,P); + if (pr>0) {(void) printf("M"); Cudd_PrintDebug(dd,M,2*vars,pr);} + + /* min(z,y) */ + Cudd_Ref(min = Cudd_addApply(dd,Cudd_addMinimum,R,M)); + Cudd_RecursiveDeref(dd,M); + + if (R == min) { + Cudd_RecursiveDeref(dd,min); + if (pr>0) {printf("Done after %d iterations\n",vars-n+1); } + break; + } + /* diff(z,y) */ + if (st) { + Cudd_Ref(diff = Cudd_addApply(dd,Cudd_addDiff,min,R)); + } else { + Cudd_Ref(diff = min); + } + Cudd_RecursiveDeref(dd,R); + R = min; /* keep a copy of matrix at current iter. */ + if (pr > 0) { + double pathcount; + (void) printf("R"); Cudd_PrintDebug(dd,R,2*vars,pr); + pathcount = Cudd_CountPath(R); + (void) printf("Path count = %g\n", pathcount); + } + + if (n == 0) { + (void) printf("Negative cycle!\n"); + break; + } + + } + Cudd_RecursiveDeref(dd,I); + Cudd_Deref(R); + return(R); + +} /* end of ntrSquare */ diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ntrZddTest.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrZddTest.c new file mode 100644 index 000000000..d1a8d83d3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ntrZddTest.c @@ -0,0 +1,468 @@ +/**CFile*********************************************************************** + + FileName [ntrZddTest.c] + + PackageName [ntr] + + Synopsis [ZDD test functions.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "ntr.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = "$Id: ntrZddTest.c,v 1.15 2012/02/05 01:53:01 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int reorderZdd (BnetNetwork *net, DdManager *dd, NtrOptions *option); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Tests ZDDs.] + + Description [Tests ZDDs. Returns 1 if successful; 0 otherwise.] + + SideEffects [Creates ZDD variables in the manager.] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_testZDD( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + DdNode **zdd; /* array of converted outputs */ + int nz; /* actual number of ZDDs */ + int result; + int i, j; + BnetNode *node; /* auxiliary pointer to network node */ + int pr = option->verb; + int level; /* aux. var. used to print variable orders */ + char **names; /* array used to print variable orders */ + int nvars; + + /* Build an array of ZDDs for the output functions or for the + ** specified node. */ + Cudd_AutodynDisable(dd); + Cudd_AutodynDisableZdd(dd); + zdd = ALLOC(DdNode *,net->noutputs); + result = Cudd_zddVarsFromBddVars(dd,1); + if (result == 0) return(0); + if (option->node == NULL) { + for (nz = 0; nz < net->noutputs; nz++) { + if (!st_lookup(net->hash,net->outputs[nz],&node)) { + return(0); + } + zdd[nz] = Cudd_zddPortFromBdd(dd, node->dd); + if (zdd[nz]) { + Cudd_Ref(zdd[nz]); + (void) printf("%s", node->name); + result = Cudd_zddPrintDebug(dd,zdd[nz],Cudd_ReadZddSize(dd),pr); + if (result == 0) return(0); + } else { + (void) printf("Conversion to ZDD failed.\n"); + } + } + } else { + if (!st_lookup(net->hash,option->node,&node)) { + return(0); + } + zdd[0] = Cudd_zddPortFromBdd(dd, node->dd); + if (zdd[0]) { + Cudd_Ref(zdd[0]); + (void) printf("%s", node->name); + result = Cudd_zddPrintDebug(dd,zdd[0],Cudd_ReadZddSize(dd),pr); + if (result == 0) return(0); + } else { + (void) printf("Conversion to ZDD failed.\n"); + } + nz = 1; + } + +#ifdef DD_DEBUG + result = Cudd_CheckKeys(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + return(0); + } +#endif + + if (option->autoDyn & 1) { + Cudd_AutodynEnable(dd,CUDD_REORDER_SAME); + } + if (option->autoDyn & 2) { + Cudd_AutodynEnableZdd(dd,CUDD_REORDER_SAME); + } + + /* Convert the ZDDs back to BDDs and check identity. */ + for (i = 0; i < nz; i++) { + DdNode *checkBdd; + checkBdd = Cudd_zddPortToBdd(dd,zdd[i]); + if (checkBdd) { + Cudd_Ref(checkBdd); + if (option->node == NULL) { + if (!st_lookup(net->hash,net->outputs[i],&node)) { + return(0); + } + } else { + if (!st_lookup(net->hash,option->node,&node)) { + return(0); + } + } + if (checkBdd != node->dd) { + (void) fprintf(stdout,"Equivalence failed at node %s", + node->name); + result = Cudd_PrintDebug(dd,checkBdd,Cudd_ReadZddSize(dd),pr); + if (result == 0) return(0); + } + Cudd_RecursiveDeref(dd,checkBdd); + } else { + (void) printf("Conversion to BDD failed.\n"); + } + } + +#ifdef DD_DEBUG + result = Cudd_CheckKeys(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + return(0); + } +#endif + + /* Play with the ZDDs a little. */ + if (nz > 2) { + DdNode *f; + DdNode *g1, *g2, *g; + f = Cudd_zddIte(dd,zdd[0],zdd[1],zdd[2]); + if (f == NULL) return(0); + cuddRef(f); + g1 = Cudd_zddIntersect(dd,zdd[0],zdd[1]); + if (g1 == NULL) { + Cudd_RecursiveDerefZdd(dd,f); + return(0); + } + cuddRef(g1); + g2 = Cudd_zddDiff(dd,zdd[2],zdd[0]); + if (g2 == NULL) { + Cudd_RecursiveDerefZdd(dd,f); + Cudd_RecursiveDerefZdd(dd,g1); + return(0); + } + cuddRef(g2); + g = Cudd_zddUnion(dd,g1,g2); + if (g == NULL) { + Cudd_RecursiveDerefZdd(dd,f); + Cudd_RecursiveDerefZdd(dd,g1); + Cudd_RecursiveDerefZdd(dd,g2); + return(0); + } + cuddRef(g); + Cudd_RecursiveDerefZdd(dd,g1); + Cudd_RecursiveDerefZdd(dd,g2); + if (g != f) { + (void) fprintf(stderr,"f != g!\n"); + } + Cudd_RecursiveDerefZdd(dd,g); + Cudd_RecursiveDerefZdd(dd,f); + } + +#ifdef DD_DEBUG + result = Cudd_CheckKeys(dd); + if (result != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + return(0); + } +#endif + + /* Perform ZDD reordering. */ + result = reorderZdd(net,dd,option); + if (result == 0) return(0); + + /* Print final ZDD order. */ + nvars = Cudd_ReadZddSize(dd); + names = ALLOC(char *, nvars); + if (names == NULL) return(0); + for (i = 0; i < nvars; i++) { + names[i] = NULL; + } + if (option->reordering != CUDD_REORDER_NONE) { + for (i = 0; i < net->npis; i++) { + if (!st_lookup(net->hash,net->inputs[i],&node)) { + FREE(names); + return(0); + } + level = Cudd_ReadPermZdd(dd,node->var); + names[level] = node->name; + } + for (i = 0; i < net->nlatches; i++) { + if (!st_lookup(net->hash,net->latches[i][1],&node)) { + FREE(names); + return(0); + } + level = Cudd_ReadPermZdd(dd,node->var); + names[level] = node->name; + } + (void) printf("New order\n"); + for (i = 0, j = 0; i < nvars; i++) { + if (names[i] == NULL) continue; + if((j%8 == 0)&&j) (void) printf("\n"); + (void) printf("%s ",names[i]); + j++; + } + (void) printf("\n"); + } + FREE(names); + + /* Dispose of ZDDs. */ + for (i = 0; i < nz; i++) { + Cudd_RecursiveDerefZdd(dd,zdd[i]); + } + FREE(zdd); + return(1); + +} /* end of Ntr_testZDD */ + + +/**Function******************************************************************** + + Synopsis [Builds ZDD covers.] + + Description [] + + SideEffects [Creates ZDD variables in the manager.] + + SeeAlso [] + +******************************************************************************/ +int +Ntr_testISOP( + DdManager * dd, + BnetNetwork * net, + NtrOptions * option) +{ + DdNode **zdd; /* array of converted outputs */ + DdNode *bdd; /* return value of Cudd_zddIsop */ + int nz; /* actual number of ZDDs */ + int result; + int i; + BnetNode *node; /* auxiliary pointer to network node */ + int pr = option->verb; + + /* Build an array of ZDDs for the output functions or the specified + ** node. */ + Cudd_zddRealignEnable(dd); + Cudd_AutodynDisableZdd(dd); + zdd = ALLOC(DdNode *,net->noutputs); + result = Cudd_zddVarsFromBddVars(dd,2); + if (result == 0) return(0); + if (option->node == NULL) { + nz = net->noutputs; + for (i = 0; i < nz; i++) { + if (!st_lookup(net->hash,net->outputs[i],&node)) { + return(0); + } + bdd = Cudd_zddIsop(dd, node->dd, node->dd, &zdd[i]); + if (bdd != node->dd) return(0); + Cudd_Ref(bdd); + Cudd_RecursiveDeref(dd,bdd); + if (zdd[i]) { + Cudd_Ref(zdd[i]); + (void) printf("%s", node->name); + result = Cudd_zddPrintDebug(dd,zdd[i],Cudd_ReadZddSize(dd),pr); + if (result == 0) return(0); + if (option->printcover) { + int *path; + DdGen *gen; + char *str = ALLOC(char,Cudd_ReadSize(dd)+1); + if (str == NULL) return(0); + (void) printf("Testing iterator on ZDD paths:\n"); + Cudd_zddForeachPath(dd,zdd[i],gen,path) { + str = Cudd_zddCoverPathToString(dd,path,str); + (void) printf("%s 1\n", str); + } + (void) printf("\n"); + FREE(str); + result = Cudd_zddPrintCover(dd,zdd[i]); + + if (result == 0) return(0); + } + } else { + (void) printf("Conversion to ISOP failed.\n"); + return(0); + } + } + } else { + nz = 1; + if (!st_lookup(net->hash,option->node,&node)) { + return(0); + } + bdd = Cudd_zddIsop(dd, node->dd, node->dd, &zdd[0]); + if (bdd != node->dd) return(0); + Cudd_Ref(bdd); + Cudd_RecursiveDeref(dd,bdd); + if (zdd[0]) { + Cudd_Ref(zdd[0]); + (void) printf("%s", node->name); + result = Cudd_zddPrintDebug(dd,zdd[0],Cudd_ReadZddSize(dd),pr); + if (result == 0) return(0); + if (option->printcover) { + int *path; + DdGen *gen; + char *str = ALLOC(char,Cudd_ReadSize(dd)+1); + if (str == NULL) return(0); + (void) printf("Testing iterator on ZDD paths:\n"); + Cudd_zddForeachPath(dd,zdd[0],gen,path) { + str = Cudd_zddCoverPathToString(dd,path,str); + (void) printf("%s 1\n", str); + } + (void) printf("\n"); + FREE(str); + + result = Cudd_zddPrintCover(dd,zdd[0]); + if (result == 0) return(0); + } + } else { + (void) printf("Conversion to ISOP failed.\n"); + return(0); + } + } + if (option->autoDyn) { + Cudd_AutodynEnableZdd(dd,CUDD_REORDER_SAME); + } + + /* Perform ZDD reordering. */ + result = reorderZdd(net,dd,option); + if (result == 0) return(0); + + /* Dispose of ZDDs. */ + for (i = 0; i < nz; i++) { + Cudd_RecursiveDerefZdd(dd,zdd[i]); + } + FREE(zdd); + + return(1); + +} /* end of Ntr_testISOP */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Applies reordering to the ZDDs.] + + Description [Explicitly applies reordering to the ZDDs. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +*****************************************************************************/ +static int +reorderZdd( + BnetNetwork * net, + DdManager * dd /* DD Manager */, + NtrOptions * option) +{ + int result; /* return value from functions */ + + /* Perform the final reordering. */ + if (option->reordering != CUDD_REORDER_NONE) { + (void) printf("Number of inputs = %d\n",net->ninputs); + + dd->siftMaxVar = 1000000; + result = Cudd_zddReduceHeap(dd,option->reordering,1); + if (result == 0) return(0); + + /* Print symmetry stats if pertinent */ + if (option->reordering == CUDD_REORDER_SYMM_SIFT || + option->reordering == CUDD_REORDER_SYMM_SIFT_CONV) + Cudd_zddSymmProfile(dd, 0, dd->sizeZ - 1); + } + + return(1); + +} /* end of reorderZdd */ + diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.blif b/resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.blif new file mode 100644 index 000000000..c11dbe070 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.blif @@ -0,0 +1,335 @@ +.model rcn25 +.outputs n0 n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 n13 n14 n15 n16 n17 \ +n18 n19 n20 n21 n22 n23 n24 + +.latch nn0 n0 2 +.latch nn1 n1 2 +.latch nn2 n2 2 +.latch nn3 n3 2 +.latch nn4 n4 2 +.latch nn5 n5 2 +.latch nn6 n6 2 +.latch nn7 n7 2 +.latch nn8 n8 2 +.latch nn9 n9 2 +.latch nn10 n10 2 +.latch nn11 n11 2 +.latch nn12 n12 2 +.latch nn13 n13 2 +.latch nn14 n14 2 +.latch nn15 n15 2 +.latch nn16 n16 2 +.latch nn17 n17 2 +.latch nn18 n18 2 +.latch nn19 n19 2 +.latch nn20 n20 2 +.latch nn21 n21 2 +.latch nn22 n22 2 +.latch nn23 n23 2 +.latch nn24 n24 2 + +.names n0 s0 +0 1 +.names n0 c1 +1 1 +.names n1 n0 c1 s1 +100 1 +010 1 +001 1 +111 1 +.names n1 n0 c1 c2 +11- 1 +1-1 1 +-11 1 +.names n2 n1 c2 s2 +100 1 +010 1 +001 1 +111 1 +.names n2 n1 c2 c3 +11- 1 +1-1 1 +-11 1 +.names n3 n2 c3 s3 +100 1 +010 1 +001 1 +111 1 +.names n3 n2 c3 c4 +11- 1 +1-1 1 +-11 1 +.names n4 n3 c4 s4 +100 1 +010 1 +001 1 +111 1 +.names n4 n3 c4 c5 +11- 1 +1-1 1 +-11 1 +.names n5 n4 c5 s5 +100 1 +010 1 +001 1 +111 1 +.names n5 n4 c5 c6 +11- 1 +1-1 1 +-11 1 +.names n6 n5 c6 s6 +100 1 +010 1 +001 1 +111 1 +.names n6 n5 c6 c7 +11- 1 +1-1 1 +-11 1 +.names n7 n6 c7 s7 +100 1 +010 1 +001 1 +111 1 +.names n7 n6 c7 c8 +11- 1 +1-1 1 +-11 1 +.names n8 n7 c8 s8 +100 1 +010 1 +001 1 +111 1 +.names n8 n7 c8 c9 +11- 1 +1-1 1 +-11 1 +.names n9 n8 c9 s9 +100 1 +010 1 +001 1 +111 1 +.names n9 n8 c9 c10 +11- 1 +1-1 1 +-11 1 +.names n10 n9 c10 s10 +100 1 +010 1 +001 1 +111 1 +.names n10 n9 c10 c11 +11- 1 +1-1 1 +-11 1 +.names n11 n10 c11 s11 +100 1 +010 1 +001 1 +111 1 +.names n11 n10 c11 c12 +11- 1 +1-1 1 +-11 1 +.names n12 n11 c12 s12 +100 1 +010 1 +001 1 +111 1 +.names n12 n11 c12 c13 +11- 1 +1-1 1 +-11 1 +.names n13 n12 c13 s13 +100 1 +010 1 +001 1 +111 1 +.names n13 n12 c13 c14 +11- 1 +1-1 1 +-11 1 +.names n14 n13 c14 s14 +100 1 +010 1 +001 1 +111 1 +.names n14 n13 c14 c15 +11- 1 +1-1 1 +-11 1 +.names n15 n14 c15 s15 +100 1 +010 1 +001 1 +111 1 +.names n15 n14 c15 c16 +11- 1 +1-1 1 +-11 1 +.names n16 n15 c16 s16 +100 1 +010 1 +001 1 +111 1 +.names n16 n15 c16 c17 +11- 1 +1-1 1 +-11 1 +.names n17 n16 c17 s17 +100 1 +010 1 +001 1 +111 1 +.names n17 n16 c17 c18 +11- 1 +1-1 1 +-11 1 +.names n18 n17 c18 s18 +100 1 +010 1 +001 1 +111 1 +.names n18 n17 c18 c19 +11- 1 +1-1 1 +-11 1 +.names n19 n18 c19 s19 +100 1 +010 1 +001 1 +111 1 +.names n19 n18 c19 c20 +11- 1 +1-1 1 +-11 1 +.names n20 n19 c20 s20 +100 1 +010 1 +001 1 +111 1 +.names n20 n19 c20 c21 +11- 1 +1-1 1 +-11 1 +.names n21 n20 c21 s21 +100 1 +010 1 +001 1 +111 1 +.names n21 n20 c21 c22 +11- 1 +1-1 1 +-11 1 +.names n22 n21 c22 s22 +100 1 +010 1 +001 1 +111 1 +.names n22 n21 c22 c23 +11- 1 +1-1 1 +-11 1 +.names n23 n22 c23 s23 +100 1 +010 1 +001 1 +111 1 +.names n23 n22 c23 c24 +11- 1 +1-1 1 +-11 1 +.names n24 n23 c24 s24 +100 1 +010 1 +001 1 +111 1 +.names n24 n23 c24 c25 +11- 1 +1-1 1 +-11 1 +.names n24 c25 s25 +10 1 +01 1 +.names n24 c25 s26 +11 1 + +.names s25 s26 of +00 0 + +.names n0 of s0 n1 nn0 +101- 1 +0--1 1 +.names n0 of s1 n2 nn1 +101- 1 +0--1 1 +.names n0 of s2 n3 nn2 +101- 1 +0--1 1 +.names n0 of s3 n4 nn3 +101- 1 +0--1 1 +.names n0 of s4 n5 nn4 +101- 1 +0--1 1 +.names n0 of s5 n6 nn5 +101- 1 +0--1 1 +.names n0 of s6 n7 nn6 +101- 1 +0--1 1 +.names n0 of s7 n8 nn7 +101- 1 +0--1 1 +.names n0 of s8 n9 nn8 +101- 1 +0--1 1 +.names n0 of s9 n10 nn9 +101- 1 +0--1 1 +.names n0 of s10 n11 nn10 +101- 1 +0--1 1 +.names n0 of s11 n12 nn11 +101- 1 +0--1 1 +.names n0 of s12 n13 nn12 +101- 1 +0--1 1 +.names n0 of s13 n14 nn13 +101- 1 +0--1 1 +.names n0 of s14 n15 nn14 +101- 1 +0--1 1 +.names n0 of s15 n16 nn15 +101- 1 +0--1 1 +.names n0 of s16 n17 nn16 +101- 1 +0--1 1 +.names n0 of s17 n18 nn17 +101- 1 +0--1 1 +.names n0 of s18 n19 nn18 +101- 1 +0--1 1 +.names n0 of s19 n20 nn19 +101- 1 +0--1 1 +.names n0 of s20 n21 nn20 +101- 1 +0--1 1 +.names n0 of s21 n22 nn21 +101- 1 +0--1 1 +.names n0 of s22 n23 nn22 +101- 1 +0--1 1 +.names n0 of s23 n24 nn23 +101- 1 +0--1 1 +.names n0 of s24 nn24 +101 1 + +.end diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.out b/resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.out new file mode 100644 index 000000000..a44f9703c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/rcn25.out @@ -0,0 +1,521 @@ +# Nanotrav Version #0.12, Release date 2003/12/31 +# ./nanotrav -p 1 -envelope rcn25.blif +# CUDD Version 2.4.2 +Order before final reordering +n0 n1 n2 n3 n4 n5 n6 n7 +n8 n9 n10 n11 n12 n13 n14 n15 +n16 n17 n18 n19 n20 n21 n22 n23 +n24 +Number of inputs = 25 +@@@@@@@@@@@@@@@@@@@@@@@@@ +S0: 1 nodes 1 leaves 3.35544e+07 minterms +Envelope[1]: 68 nodes 1 leaves 1.95734e+07 minterms +Envelope[2]: 131 nodes 1 leaves 1.53791e+07 minterms +Envelope[3]: 240 nodes 1 leaves 1.30489e+07 minterms +Envelope[4]: 351 nodes 1 leaves 1.07188e+07 minterms +Envelope[5]: 365 nodes 1 leaves 9.08766e+06 minterms +Envelope[6]: 672 nodes 1 leaves 7.88374e+06 minterms +Envelope[7]: 977 nodes 1 leaves 6.85458e+06 minterms +Envelope[8]: 1697 nodes 1 leaves 6.16039e+06 minterms +Envelope[9]: 2507 nodes 1 leaves 5.53173e+06 minterms +Envelope[10]: 2728 nodes 1 leaves 4.99328e+06 minterms +Envelope[11]: 4877 nodes 1 leaves 4.56022e+06 minterms +Envelope[12]: 7131 nodes 1 leaves 4.15173e+06 minterms +Envelope[13]: 10837 nodes 1 leaves 3.83181e+06 minterms +Envelope[14]: 16376 nodes 1 leaves 3.53694e+06 minterms +Envelope[15]: 18686 nodes 1 leaves 3.26485e+06 minterms +Envelope[16]: 27175 nodes 1 leaves 3.03016e+06 minterms +Envelope[17]: 37624 nodes 1 leaves 2.81134e+06 minterms +Envelope[18]: 42091 nodes 1 leaves 2.62598e+06 minterms +Envelope[19]: 64761 nodes 1 leaves 2.45532e+06 minterms +Envelope[20]: 88199 nodes 1 leaves 2.29512e+06 minterms +Envelope[21]: 112012 nodes 1 leaves 2.15501e+06 minterms +Envelope[22]: 148131 nodes 1 leaves 2.02284e+06 minterms +Envelope[23]: 178957 nodes 1 leaves 1.90343e+06 minterms +Envelope[24]: 213207 nodes 1 leaves 1.79426e+06 minterms +Envelope[25]: 251015 nodes 1 leaves 1.69064e+06 minterms +Envelope[26]: 278969 nodes 1 leaves 1.59836e+06 minterms +Envelope[27]: 298983 nodes 1 leaves 1.51117e+06 minterms +Envelope[28]: 310186 nodes 1 leaves 1.4295e+06 minterms +Envelope[29]: 314312 nodes 1 leaves 1.35474e+06 minterms +Envelope[30]: 312346 nodes 1 leaves 1.2838e+06 minterms +Envelope[31]: 308909 nodes 1 leaves 1.21948e+06 minterms +Envelope[32]: 304183 nodes 1 leaves 1.15867e+06 minterms +Envelope[33]: 298541 nodes 1 leaves 1.10083e+06 minterms +Envelope[34]: 292868 nodes 1 leaves 1.04754e+06 minterms +Envelope[35]: 286698 nodes 1 leaves 996946 minterms +Envelope[36]: 280610 nodes 1 leaves 949953 minterms +Envelope[37]: 274275 nodes 1 leaves 905778 minterms +Envelope[38]: 267711 nodes 1 leaves 863616 minterms +Envelope[39]: 261513 nodes 1 leaves 824606 minterms +Envelope[40]: 255196 nodes 1 leaves 787378 minterms +Envelope[41]: 248890 nodes 1 leaves 752197 minterms +Envelope[42]: 242617 nodes 1 leaves 719152 minterms +Envelope[43]: 236080 nodes 1 leaves 687560 minterms +Envelope[44]: 230130 nodes 1 leaves 658155 minterms +Envelope[45]: 224259 nodes 1 leaves 629967 minterms +Envelope[46]: 218166 nodes 1 leaves 603079 minterms +Envelope[47]: 212397 nodes 1 leaves 577815 minterms +Envelope[48]: 206597 nodes 1 leaves 553658 minterms +Envelope[49]: 201169 nodes 1 leaves 531033 minterms +Envelope[50]: 195784 nodes 1 leaves 509531 minterms +Envelope[51]: 190388 nodes 1 leaves 488904 minterms +Envelope[52]: 185402 nodes 1 leaves 469490 minterms +Envelope[53]: 180396 nodes 1 leaves 450891 minterms +Envelope[54]: 175724 nodes 1 leaves 433247 minterms +Envelope[55]: 171253 nodes 1 leaves 416458 minterms +Envelope[56]: 166524 nodes 1 leaves 400345 minterms +Envelope[57]: 162304 nodes 1 leaves 385129 minterms +Envelope[58]: 158158 nodes 1 leaves 370518 minterms +Envelope[59]: 154136 nodes 1 leaves 356541 minterms +Envelope[60]: 150218 nodes 1 leaves 343262 minterms +Envelope[61]: 146293 nodes 1 leaves 330504 minterms +Envelope[62]: 142731 nodes 1 leaves 318444 minterms +Envelope[63]: 139152 nodes 1 leaves 306873 minterms +Envelope[64]: 135570 nodes 1 leaves 295766 minterms +Envelope[65]: 132114 nodes 1 leaves 285183 minterms +Envelope[66]: 128777 nodes 1 leaves 275032 minterms +Envelope[67]: 125644 nodes 1 leaves 265348 minterms +Envelope[68]: 122532 nodes 1 leaves 256089 minterms +Envelope[69]: 119388 nodes 1 leaves 247191 minterms +Envelope[70]: 116557 nodes 1 leaves 238707 minterms +Envelope[71]: 113576 nodes 1 leaves 230531 minterms +Envelope[72]: 110737 nodes 1 leaves 222700 minterms +Envelope[73]: 107964 nodes 1 leaves 215170 minterms +Envelope[74]: 105272 nodes 1 leaves 207896 minterms +Envelope[75]: 102720 nodes 1 leaves 200935 minterms +Envelope[76]: 100098 nodes 1 leaves 194214 minterms +Envelope[77]: 97630 nodes 1 leaves 187719 minterms +Envelope[78]: 95248 nodes 1 leaves 181488 minterms +Envelope[79]: 92891 nodes 1 leaves 175479 minterms +Envelope[80]: 90738 nodes 1 leaves 169733 minterms +Envelope[81]: 88566 nodes 1 leaves 164201 minterms +Envelope[82]: 86372 nodes 1 leaves 158855 minterms +Envelope[83]: 84200 nodes 1 leaves 153722 minterms +Envelope[84]: 82108 nodes 1 leaves 148752 minterms +Envelope[85]: 80162 nodes 1 leaves 143977 minterms +Envelope[86]: 78254 nodes 1 leaves 139369 minterms +Envelope[87]: 76349 nodes 1 leaves 134921 minterms +Envelope[88]: 74645 nodes 1 leaves 130668 minterms +Envelope[89]: 72849 nodes 1 leaves 126558 minterms +Envelope[90]: 71140 nodes 1 leaves 122588 minterms +Envelope[91]: 69484 nodes 1 leaves 118779 minterms +Envelope[92]: 67898 nodes 1 leaves 115076 minterms +Envelope[93]: 66429 nodes 1 leaves 111539 minterms +Envelope[94]: 64879 nodes 1 leaves 108113 minterms +Envelope[95]: 63332 nodes 1 leaves 104807 minterms +Envelope[96]: 61892 nodes 1 leaves 101634 minterms +Envelope[97]: 60487 nodes 1 leaves 98554 minterms +Envelope[98]: 59076 nodes 1 leaves 95579 minterms +Envelope[99]: 57675 nodes 1 leaves 92712 minterms +Envelope[100]: 56346 nodes 1 leaves 89943 minterms +Envelope[101]: 55101 nodes 1 leaves 87270 minterms +Envelope[102]: 53857 nodes 1 leaves 84669 minterms +Envelope[103]: 52673 nodes 1 leaves 82155 minterms +Envelope[104]: 51498 nodes 1 leaves 79722 minterms +Envelope[105]: 50375 nodes 1 leaves 77355 minterms +Envelope[106]: 49253 nodes 1 leaves 75077 minterms +Envelope[107]: 48157 nodes 1 leaves 72867 minterms +Envelope[108]: 47096 nodes 1 leaves 70729 minterms +Envelope[109]: 46100 nodes 1 leaves 68652 minterms +Envelope[110]: 45047 nodes 1 leaves 66635 minterms +Envelope[111]: 44107 nodes 1 leaves 64689 minterms +Envelope[112]: 43198 nodes 1 leaves 62806 minterms +Envelope[113]: 42227 nodes 1 leaves 60981 minterms +Envelope[114]: 41297 nodes 1 leaves 59228 minterms +Envelope[115]: 40371 nodes 1 leaves 57524 minterms +Envelope[116]: 39479 nodes 1 leaves 55874 minterms +Envelope[117]: 38623 nodes 1 leaves 54279 minterms +Envelope[118]: 37792 nodes 1 leaves 52739 minterms +Envelope[119]: 37000 nodes 1 leaves 51264 minterms +Envelope[120]: 36185 nodes 1 leaves 49837 minterms +Envelope[121]: 35400 nodes 1 leaves 48443 minterms +Envelope[122]: 34580 nodes 1 leaves 47093 minterms +Envelope[123]: 33793 nodes 1 leaves 45782 minterms +Envelope[124]: 33084 nodes 1 leaves 44519 minterms +Envelope[125]: 32388 nodes 1 leaves 43292 minterms +Envelope[126]: 31710 nodes 1 leaves 42089 minterms +Envelope[127]: 31025 nodes 1 leaves 40920 minterms +Envelope[128]: 30350 nodes 1 leaves 39778 minterms +Envelope[129]: 29683 nodes 1 leaves 38664 minterms +Envelope[130]: 29050 nodes 1 leaves 37589 minterms +Envelope[131]: 28418 nodes 1 leaves 36551 minterms +Envelope[132]: 27804 nodes 1 leaves 35547 minterms +Envelope[133]: 27184 nodes 1 leaves 34573 minterms +Envelope[134]: 26621 nodes 1 leaves 33636 minterms +Envelope[135]: 26074 nodes 1 leaves 32724 minterms +Envelope[136]: 25528 nodes 1 leaves 31831 minterms +Envelope[137]: 24996 nodes 1 leaves 30967 minterms +Envelope[138]: 24472 nodes 1 leaves 30133 minterms +Envelope[139]: 23993 nodes 1 leaves 29324 minterms +Envelope[140]: 23514 nodes 1 leaves 28535 minterms +Envelope[141]: 23008 nodes 1 leaves 27769 minterms +Envelope[142]: 22525 nodes 1 leaves 27029 minterms +Envelope[143]: 22039 nodes 1 leaves 26318 minterms +Envelope[144]: 21561 nodes 1 leaves 25624 minterms +Envelope[145]: 21094 nodes 1 leaves 24950 minterms +Envelope[146]: 20685 nodes 1 leaves 24289 minterms +Envelope[147]: 20249 nodes 1 leaves 23651 minterms +Envelope[148]: 19794 nodes 1 leaves 23023 minterms +Envelope[149]: 19369 nodes 1 leaves 22418 minterms +Envelope[150]: 18976 nodes 1 leaves 21837 minterms +Envelope[151]: 18589 nodes 1 leaves 21272 minterms +Envelope[152]: 18201 nodes 1 leaves 20723 minterms +Envelope[153]: 17806 nodes 1 leaves 20198 minterms +Envelope[154]: 17419 nodes 1 leaves 19684 minterms +Envelope[155]: 17049 nodes 1 leaves 19180 minterms +Envelope[156]: 16672 nodes 1 leaves 18691 minterms +Envelope[157]: 16315 nodes 1 leaves 18214 minterms +Envelope[158]: 16005 nodes 1 leaves 17741 minterms +Envelope[159]: 15679 nodes 1 leaves 17284 minterms +Envelope[160]: 15341 nodes 1 leaves 16836 minterms +Envelope[161]: 14999 nodes 1 leaves 16397 minterms +Envelope[162]: 14667 nodes 1 leaves 15962 minterms +Envelope[163]: 14365 nodes 1 leaves 15544 minterms +Envelope[164]: 14066 nodes 1 leaves 15138 minterms +Envelope[165]: 13792 nodes 1 leaves 14743 minterms +Envelope[166]: 13539 nodes 1 leaves 14361 minterms +Envelope[167]: 13283 nodes 1 leaves 13992 minterms +Envelope[168]: 13022 nodes 1 leaves 13632 minterms +Envelope[169]: 12765 nodes 1 leaves 13280 minterms +Envelope[170]: 12497 nodes 1 leaves 12938 minterms +Envelope[171]: 12257 nodes 1 leaves 12605 minterms +Envelope[172]: 11990 nodes 1 leaves 12279 minterms +Envelope[173]: 11716 nodes 1 leaves 11958 minterms +Envelope[174]: 11436 nodes 1 leaves 11646 minterms +Envelope[175]: 11180 nodes 1 leaves 11345 minterms +Envelope[176]: 10939 nodes 1 leaves 11056 minterms +Envelope[177]: 10717 nodes 1 leaves 10771 minterms +Envelope[178]: 10488 nodes 1 leaves 10493 minterms +Envelope[179]: 10255 nodes 1 leaves 10221 minterms +Envelope[180]: 10013 nodes 1 leaves 9957 minterms +Envelope[181]: 9810 nodes 1 leaves 9699 minterms +Envelope[182]: 9568 nodes 1 leaves 9449 minterms +Envelope[183]: 9355 nodes 1 leaves 9206 minterms +Envelope[184]: 9176 nodes 1 leaves 8967 minterms +Envelope[185]: 8990 nodes 1 leaves 8733 minterms +Envelope[186]: 8810 nodes 1 leaves 8512 minterms +Envelope[187]: 8621 nodes 1 leaves 8297 minterms +Envelope[188]: 8421 nodes 1 leaves 8091 minterms +Envelope[189]: 8200 nodes 1 leaves 7895 minterms +Envelope[190]: 7992 nodes 1 leaves 7705 minterms +Envelope[191]: 7816 nodes 1 leaves 7519 minterms +Envelope[192]: 7641 nodes 1 leaves 7338 minterms +Envelope[193]: 7475 nodes 1 leaves 7161 minterms +Envelope[194]: 7307 nodes 1 leaves 6986 minterms +Envelope[195]: 7137 nodes 1 leaves 6814 minterms +Envelope[196]: 6956 nodes 1 leaves 6644 minterms +Envelope[197]: 6784 nodes 1 leaves 6477 minterms +Envelope[198]: 6642 nodes 1 leaves 6315 minterms +Envelope[199]: 6515 nodes 1 leaves 6157 minterms +Envelope[200]: 6377 nodes 1 leaves 6000 minterms +Envelope[201]: 6221 nodes 1 leaves 5847 minterms +Envelope[202]: 6069 nodes 1 leaves 5699 minterms +Envelope[203]: 5919 nodes 1 leaves 5555 minterms +Envelope[204]: 5797 nodes 1 leaves 5417 minterms +Envelope[205]: 5662 nodes 1 leaves 5282 minterms +Envelope[206]: 5535 nodes 1 leaves 5149 minterms +Envelope[207]: 5414 nodes 1 leaves 5018 minterms +Envelope[208]: 5293 nodes 1 leaves 4890 minterms +Envelope[209]: 5170 nodes 1 leaves 4765 minterms +Envelope[210]: 5057 nodes 1 leaves 4644 minterms +Envelope[211]: 4948 nodes 1 leaves 4526 minterms +Envelope[212]: 4856 nodes 1 leaves 4410 minterms +Envelope[213]: 4763 nodes 1 leaves 4296 minterms +Envelope[214]: 4651 nodes 1 leaves 4183 minterms +Envelope[215]: 4568 nodes 1 leaves 4076 minterms +Envelope[216]: 4488 nodes 1 leaves 3972 minterms +Envelope[217]: 4406 nodes 1 leaves 3869 minterms +Envelope[218]: 4322 nodes 1 leaves 3771 minterms +Envelope[219]: 4249 nodes 1 leaves 3677 minterms +Envelope[220]: 4177 nodes 1 leaves 3586 minterms +Envelope[221]: 4102 nodes 1 leaves 3496 minterms +Envelope[222]: 4021 nodes 1 leaves 3408 minterms +Envelope[223]: 3949 nodes 1 leaves 3322 minterms +Envelope[224]: 3871 nodes 1 leaves 3238 minterms +Envelope[225]: 3800 nodes 1 leaves 3158 minterms +Envelope[226]: 3740 nodes 1 leaves 3079 minterms +Envelope[227]: 3674 nodes 1 leaves 3002 minterms +Envelope[228]: 3618 nodes 1 leaves 2926 minterms +Envelope[229]: 3552 nodes 1 leaves 2852 minterms +Envelope[230]: 3485 nodes 1 leaves 2780 minterms +Envelope[231]: 3428 nodes 1 leaves 2711 minterms +Envelope[232]: 3370 nodes 1 leaves 2643 minterms +Envelope[233]: 3304 nodes 1 leaves 2575 minterms +Envelope[234]: 3244 nodes 1 leaves 2510 minterms +Envelope[235]: 3177 nodes 1 leaves 2447 minterms +Envelope[236]: 3112 nodes 1 leaves 2385 minterms +Envelope[237]: 3054 nodes 1 leaves 2324 minterms +Envelope[238]: 2999 nodes 1 leaves 2268 minterms +Envelope[239]: 2947 nodes 1 leaves 2212 minterms +Envelope[240]: 2892 nodes 1 leaves 2157 minterms +Envelope[241]: 2831 nodes 1 leaves 2104 minterms +Envelope[242]: 2769 nodes 1 leaves 2052 minterms +Envelope[243]: 2709 nodes 1 leaves 2001 minterms +Envelope[244]: 2644 nodes 1 leaves 1952 minterms +Envelope[245]: 2569 nodes 1 leaves 1903 minterms +Envelope[246]: 2505 nodes 1 leaves 1855 minterms +Envelope[247]: 2432 nodes 1 leaves 1807 minterms +Envelope[248]: 2361 nodes 1 leaves 1760 minterms +Envelope[249]: 2289 nodes 1 leaves 1715 minterms +Envelope[250]: 2215 nodes 1 leaves 1673 minterms +Envelope[251]: 2169 nodes 1 leaves 1632 minterms +Envelope[252]: 2114 nodes 1 leaves 1591 minterms +Envelope[253]: 2063 nodes 1 leaves 1551 minterms +Envelope[254]: 2011 nodes 1 leaves 1512 minterms +Envelope[255]: 1957 nodes 1 leaves 1473 minterms +Envelope[256]: 1902 nodes 1 leaves 1434 minterms +Envelope[257]: 1852 nodes 1 leaves 1396 minterms +Envelope[258]: 1805 nodes 1 leaves 1359 minterms +Envelope[259]: 1763 nodes 1 leaves 1322 minterms +Envelope[260]: 1711 nodes 1 leaves 1287 minterms +Envelope[261]: 1653 nodes 1 leaves 1255 minterms +Envelope[262]: 1604 nodes 1 leaves 1223 minterms +Envelope[263]: 1557 nodes 1 leaves 1193 minterms +Envelope[264]: 1515 nodes 1 leaves 1164 minterms +Envelope[265]: 1482 nodes 1 leaves 1136 minterms +Envelope[266]: 1447 nodes 1 leaves 1108 minterms +Envelope[267]: 1416 nodes 1 leaves 1081 minterms +Envelope[268]: 1383 nodes 1 leaves 1054 minterms +Envelope[269]: 1353 nodes 1 leaves 1028 minterms +Envelope[270]: 1323 nodes 1 leaves 1003 minterms +Envelope[271]: 1290 nodes 1 leaves 978 minterms +Envelope[272]: 1252 nodes 1 leaves 954 minterms +Envelope[273]: 1215 nodes 1 leaves 931 minterms +Envelope[274]: 1174 nodes 1 leaves 908 minterms +Envelope[275]: 1144 nodes 1 leaves 887 minterms +Envelope[276]: 1120 nodes 1 leaves 867 minterms +Envelope[277]: 1102 nodes 1 leaves 848 minterms +Envelope[278]: 1082 nodes 1 leaves 830 minterms +Envelope[279]: 1061 nodes 1 leaves 812 minterms +Envelope[280]: 1045 nodes 1 leaves 795 minterms +Envelope[281]: 1031 nodes 1 leaves 778 minterms +Envelope[282]: 1015 nodes 1 leaves 763 minterms +Envelope[283]: 1004 nodes 1 leaves 748 minterms +Envelope[284]: 996 nodes 1 leaves 733 minterms +Envelope[285]: 983 nodes 1 leaves 719 minterms +Envelope[286]: 964 nodes 1 leaves 705 minterms +Envelope[287]: 949 nodes 1 leaves 691 minterms +Envelope[288]: 938 nodes 1 leaves 677 minterms +Envelope[289]: 925 nodes 1 leaves 663 minterms +Envelope[290]: 913 nodes 1 leaves 650 minterms +Envelope[291]: 907 nodes 1 leaves 637 minterms +Envelope[292]: 901 nodes 1 leaves 624 minterms +Envelope[293]: 887 nodes 1 leaves 611 minterms +Envelope[294]: 878 nodes 1 leaves 598 minterms +Envelope[295]: 872 nodes 1 leaves 585 minterms +Envelope[296]: 860 nodes 1 leaves 573 minterms +Envelope[297]: 852 nodes 1 leaves 561 minterms +Envelope[298]: 842 nodes 1 leaves 549 minterms +Envelope[299]: 834 nodes 1 leaves 537 minterms +Envelope[300]: 826 nodes 1 leaves 526 minterms +Envelope[301]: 819 nodes 1 leaves 515 minterms +Envelope[302]: 808 nodes 1 leaves 505 minterms +Envelope[303]: 797 nodes 1 leaves 495 minterms +Envelope[304]: 789 nodes 1 leaves 485 minterms +Envelope[305]: 773 nodes 1 leaves 475 minterms +Envelope[306]: 758 nodes 1 leaves 465 minterms +Envelope[307]: 742 nodes 1 leaves 455 minterms +Envelope[308]: 727 nodes 1 leaves 445 minterms +Envelope[309]: 711 nodes 1 leaves 435 minterms +Envelope[310]: 698 nodes 1 leaves 425 minterms +Envelope[311]: 677 nodes 1 leaves 415 minterms +Envelope[312]: 662 nodes 1 leaves 405 minterms +Envelope[313]: 653 nodes 1 leaves 395 minterms +Envelope[314]: 638 nodes 1 leaves 386 minterms +Envelope[315]: 625 nodes 1 leaves 377 minterms +Envelope[316]: 611 nodes 1 leaves 368 minterms +Envelope[317]: 603 nodes 1 leaves 359 minterms +Envelope[318]: 598 nodes 1 leaves 350 minterms +Envelope[319]: 588 nodes 1 leaves 342 minterms +Envelope[320]: 581 nodes 1 leaves 334 minterms +Envelope[321]: 576 nodes 1 leaves 326 minterms +Envelope[322]: 566 nodes 1 leaves 318 minterms +Envelope[323]: 555 nodes 1 leaves 311 minterms +Envelope[324]: 546 nodes 1 leaves 305 minterms +Envelope[325]: 537 nodes 1 leaves 299 minterms +Envelope[326]: 526 nodes 1 leaves 293 minterms +Envelope[327]: 515 nodes 1 leaves 287 minterms +Envelope[328]: 505 nodes 1 leaves 281 minterms +Envelope[329]: 493 nodes 1 leaves 275 minterms +Envelope[330]: 481 nodes 1 leaves 270 minterms +Envelope[331]: 468 nodes 1 leaves 265 minterms +Envelope[332]: 455 nodes 1 leaves 260 minterms +Envelope[333]: 446 nodes 1 leaves 255 minterms +Envelope[334]: 438 nodes 1 leaves 250 minterms +Envelope[335]: 433 nodes 1 leaves 245 minterms +Envelope[336]: 430 nodes 1 leaves 240 minterms +Envelope[337]: 421 nodes 1 leaves 235 minterms +Envelope[338]: 415 nodes 1 leaves 230 minterms +Envelope[339]: 405 nodes 1 leaves 225 minterms +Envelope[340]: 397 nodes 1 leaves 220 minterms +Envelope[341]: 390 nodes 1 leaves 215 minterms +Envelope[342]: 382 nodes 1 leaves 210 minterms +Envelope[343]: 374 nodes 1 leaves 205 minterms +Envelope[344]: 368 nodes 1 leaves 200 minterms +Envelope[345]: 357 nodes 1 leaves 195 minterms +Envelope[346]: 349 nodes 1 leaves 190 minterms +Envelope[347]: 345 nodes 1 leaves 185 minterms +Envelope[348]: 343 nodes 1 leaves 180 minterms +Envelope[349]: 338 nodes 1 leaves 175 minterms +Envelope[350]: 329 nodes 1 leaves 170 minterms +Envelope[351]: 318 nodes 1 leaves 165 minterms +Envelope[352]: 312 nodes 1 leaves 160 minterms +Envelope[353]: 305 nodes 1 leaves 156 minterms +Envelope[354]: 298 nodes 1 leaves 152 minterms +Envelope[355]: 291 nodes 1 leaves 148 minterms +Envelope[356]: 284 nodes 1 leaves 144 minterms +Envelope[357]: 274 nodes 1 leaves 140 minterms +Envelope[358]: 267 nodes 1 leaves 136 minterms +Envelope[359]: 258 nodes 1 leaves 132 minterms +Envelope[360]: 250 nodes 1 leaves 129 minterms +Envelope[361]: 242 nodes 1 leaves 126 minterms +Envelope[362]: 239 nodes 1 leaves 123 minterms +Envelope[363]: 230 nodes 1 leaves 120 minterms +Envelope[364]: 224 nodes 1 leaves 117 minterms +Envelope[365]: 218 nodes 1 leaves 114 minterms +Envelope[366]: 217 nodes 1 leaves 111 minterms +Envelope[367]: 216 nodes 1 leaves 108 minterms +Envelope[368]: 214 nodes 1 leaves 105 minterms +Envelope[369]: 213 nodes 1 leaves 102 minterms +Envelope[370]: 213 nodes 1 leaves 99 minterms +Envelope[371]: 210 nodes 1 leaves 96 minterms +Envelope[372]: 206 nodes 1 leaves 93 minterms +Envelope[373]: 203 nodes 1 leaves 90 minterms +Envelope[374]: 199 nodes 1 leaves 87 minterms +Envelope[375]: 195 nodes 1 leaves 84 minterms +Envelope[376]: 191 nodes 1 leaves 81 minterms +Envelope[377]: 188 nodes 1 leaves 78 minterms +Envelope[378]: 186 nodes 1 leaves 75 minterms +Envelope[379]: 184 nodes 1 leaves 72 minterms +Envelope[380]: 183 nodes 1 leaves 70 minterms +Envelope[381]: 183 nodes 1 leaves 68 minterms +Envelope[382]: 182 nodes 1 leaves 66 minterms +Envelope[383]: 181 nodes 1 leaves 64 minterms +Envelope[384]: 179 nodes 1 leaves 62 minterms +Envelope[385]: 179 nodes 1 leaves 60 minterms +Envelope[386]: 178 nodes 1 leaves 58 minterms +Envelope[387]: 177 nodes 1 leaves 56 minterms +Envelope[388]: 175 nodes 1 leaves 54 minterms +Envelope[389]: 171 nodes 1 leaves 52 minterms +Envelope[390]: 168 nodes 1 leaves 50 minterms +Envelope[391]: 164 nodes 1 leaves 48 minterms +Envelope[392]: 159 nodes 1 leaves 46 minterms +Envelope[393]: 153 nodes 1 leaves 45 minterms +Envelope[394]: 148 nodes 1 leaves 44 minterms +Envelope[395]: 144 nodes 1 leaves 43 minterms +Envelope[396]: 140 nodes 1 leaves 42 minterms +Envelope[397]: 135 nodes 1 leaves 41 minterms +Envelope[398]: 132 nodes 1 leaves 40 minterms +Envelope[399]: 127 nodes 1 leaves 39 minterms +Envelope[400]: 122 nodes 1 leaves 38 minterms +Envelope[401]: 118 nodes 1 leaves 37 minterms +Envelope[402]: 114 nodes 1 leaves 36 minterms +Envelope[403]: 107 nodes 1 leaves 35 minterms +Envelope[404]: 100 nodes 1 leaves 34 minterms +Envelope[405]: 95 nodes 1 leaves 33 minterms +Envelope[406]: 92 nodes 1 leaves 32 minterms +Envelope[407]: 89 nodes 1 leaves 31 minterms +Envelope[408]: 84 nodes 1 leaves 30 minterms +Envelope[409]: 81 nodes 1 leaves 29 minterms +Envelope[410]: 78 nodes 1 leaves 28 minterms +Envelope[411]: 73 nodes 1 leaves 27 minterms +Envelope[412]: 70 nodes 1 leaves 26 minterms +Envelope[413]: 67 nodes 1 leaves 25 minterms +Envelope[414]: 63 nodes 1 leaves 24 minterms +Envelope[415]: 59 nodes 1 leaves 23 minterms +Envelope[416]: 56 nodes 1 leaves 22 minterms +Envelope[417]: 55 nodes 1 leaves 21 minterms +Envelope[418]: 54 nodes 1 leaves 20 minterms +Envelope[419]: 53 nodes 1 leaves 19 minterms +Envelope[420]: 52 nodes 1 leaves 18 minterms +Envelope[421]: 52 nodes 1 leaves 17 minterms +Envelope[422]: 50 nodes 1 leaves 16 minterms +Envelope[423]: 47 nodes 1 leaves 15 minterms +Envelope[424]: 44 nodes 1 leaves 14 minterms +Envelope[425]: 40 nodes 1 leaves 13 minterms +Envelope[426]: 36 nodes 1 leaves 12 minterms +Envelope[427]: 33 nodes 1 leaves 11 minterms +Envelope[428]: 31 nodes 1 leaves 10 minterms +Envelope[429]: 30 nodes 1 leaves 9 minterms +Envelope[430]: 29 nodes 1 leaves 8 minterms +Envelope[431]: 29 nodes 1 leaves 7 minterms +Envelope[432]: 29 nodes 1 leaves 6 minterms +Envelope[433]: 28 nodes 1 leaves 5 minterms +Envelope[434]: 27 nodes 1 leaves 4 minterms +depth = 434 +Envelope: 27 nodes 1 leaves 4 minterms +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000 +Maximum number of variable swaps per reordering: 2000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: no +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: no +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 10 +Arc violation threshold: 10 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 4004 +**** CUDD non-modifiable parameters **** +Memory in use: 240456716 +Peak number of nodes: 9643592 +Peak number of live nodes: 3171948 +Number of BDD variables: 50 +Number of ZDD variables: 0 +Number of cache entries: 4194304 +Number of cache look-ups: 53170021 +Number of cache hits: 30653976 +Number of cache insertions: 22515985 +Number of cache collisions: 15665382 +Number of cache deletions: 3483568 +Cache used slots = 97.84% (expected 98.41%) +Soft limit for cache size: 7645866 +Number of buckets in unique table: 3677184 +Used buckets in unique table: 71.16% (expected 71.15%) +Number of BDD and ADD nodes: 5843265 +Number of ZDD nodes: 0 +Number of dead BDD and ADD nodes: 4325974 +Number of dead ZDD nodes: 0 +Total number of nodes allocated: 15264438 +Total number of nodes reclaimed: 7806126 +Garbage collections so far: 2 +Time for garbage collection: 2.38 sec +Reorderings so far: 0 +Time for reordering: 0.00 sec +Final size: 869 +total time = 66.53 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 66.5 seconds +System time 0.6 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131815K +Virtual data size = 297K + data size initialized = 25K + data size uninitialized = 137K + data size sbrk = 135K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 5 +Minor page faults = 80223 +Swaps = 0 +Input blocks = 0 +Output blocks = 0 +Context switch (voluntary) = 6 +Context switch (involuntary) = 1991 diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/s27.blif b/resources/3rdparty/cudd-2.5.0/nanotrav/s27.blif new file mode 100644 index 000000000..42861a8ea --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/s27.blif @@ -0,0 +1,30 @@ +.model s27.bench +.inputs G0 G1 G2 G3 +.outputs G17 +.latch G10 G5 0 +.latch G11 G6 0 +.latch G13 G7 0 +.names G11 G17 +0 1 +.names G14 G11 G10 +00 1 +.names G5 G9 G11 +00 1 +.names G2 G12 G13 +00 1 +.names G0 G14 +0 1 +.names G14 G6 G8 +11 1 +.names G1 G7 G12 +00 1 +.names G12 G8 G15 +1- 1 +-1 1 +.names G3 G8 G16 +1- 1 +-1 1 +.names G16 G15 G9 +0- 1 +-0 1 +.end diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/s27.out b/resources/3rdparty/cudd-2.5.0/nanotrav/s27.out new file mode 100644 index 000000000..b9746f6c2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/s27.out @@ -0,0 +1,95 @@ +# Nanotrav Version #0.12, Release date 2003/12/31 +# ./nanotrav -p 1 -trav s27.blif +# CUDD Version 2.4.2 +Order before final reordering +G0 G1 G2 G3 G5 G6 G7 +Number of inputs = 7 +Building transition relation. Time = 0.00 sec +@@@ +Transition relation: 1 parts 3 latches 9 nodes +Traversing. Time = 0.00 sec +S0: 4 nodes 1 leaves 1 minterms +From[1]: 5 nodes 1 leaves 4 minterms +Reached[1]: 5 nodes 1 leaves 5 minterms +5 +5e+0 +From[2]: 4 nodes 1 leaves 1 minterms +Reached[2]: 3 nodes 1 leaves 6 minterms +6 +6e+0 +depth = 2 +R: 3 nodes 1 leaves 6 minterms +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000 +Maximum number of variable swaps per reordering: 2000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: no +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: no +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 10 +Arc violation threshold: 10 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 4004 +**** CUDD non-modifiable parameters **** +Memory in use: 4737772 +Peak number of nodes: 1022 +Peak number of live nodes: 95 +Number of BDD variables: 10 +Number of ZDD variables: 0 +Number of cache entries: 32768 +Number of cache look-ups: 180 +Number of cache hits: 26 +Number of cache insertions: 151 +Number of cache collisions: 1 +Number of cache deletions: 0 +Cache used slots = 0.46% (expected 0.46%) +Soft limit for cache size: 11264 +Number of buckets in unique table: 2816 +Used buckets in unique table: 4.97% (expected 5.15%) +Number of BDD and ADD nodes: 150 +Number of ZDD nodes: 0 +Number of dead BDD and ADD nodes: 75 +Number of dead ZDD nodes: 0 +Total number of nodes allocated: 150 +Total number of nodes reclaimed: 12 +Garbage collections so far: 0 +Time for garbage collection: 0.00 sec +Reorderings so far: 0 +Time for reordering: 0.00 sec +Final size: 16 +total time = 0.00 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 0.0 seconds +System time 0.0 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131815K +Virtual data size = 297K + data size initialized = 25K + data size uninitialized = 137K + data size sbrk = 135K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 0 +Minor page faults = 1424 +Swaps = 0 +Input blocks = 0 +Output blocks = 0 +Context switch (voluntary) = 1 +Context switch (involuntary) = 0 diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/tst.sh b/resources/3rdparty/cudd-2.5.0/nanotrav/tst.sh new file mode 100755 index 000000000..c51e67e29 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/tst.sh @@ -0,0 +1,9 @@ +#! /bin/sh +# +# $Id: tst.sh,v 1.2 1998/05/03 08:41:38 fabio Exp fabio $ +# +./nanotrav -p 1 -cover C17.blif > C17.tst +./nanotrav -p 1 -ordering dfs -autodyn -automethod sifting -reordering sifting -drop C880.blif > C880.tst +./nanotrav -p 1 -trav s27.blif > s27.tst +./nanotrav -p 1 -autodyn -reordering sifting -trav mult32a.blif > mult32a.tst +./nanotrav -p 1 -envelope rcn25.blif > rcn25.tst diff --git a/resources/3rdparty/cudd-2.5.0/nanotrav/ucbqsort.c b/resources/3rdparty/cudd-2.5.0/nanotrav/ucbqsort.c new file mode 100644 index 000000000..4a7348d5c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/nanotrav/ucbqsort.c @@ -0,0 +1,228 @@ +#if defined(__GNUC__) && (__GNUC__ >2 || __GNUC_MINOR__ >=7) +#define UNUSED __attribute__ ((unused)) +#else +#define UNUSED +#endif + +#ifndef lint +static char rcsid[] UNUSED = "$Id: ucbqsort.c,v 1.4 2004/01/01 07:06:06 fabio Exp $"; +#endif + +/* @(#)qsort.c 4.2 (Berkeley) 3/9/83 */ + +/* + * qsort.c: + * Our own version of the system qsort routine which is faster by an average + * of 25%, with lows and highs of 10% and 50%. + * The THRESHold below is the insertion sort threshold, and has been adjusted + * for records of size 48 bytes. + * The MTHREShold is where we stop finding a better median. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int (*QSFP)(const void *, const void *); +extern void qsort ( char *base, int n, int size, QSFP compar); + +#define THRESH 4 /* threshold for insertion */ +#define MTHRESH 6 /* threshold for median */ + +static QSFP qcmp; /* the comparison routine */ +static int qsz; /* size of each record */ +static int thresh; /* THRESHold in chars */ +static int mthresh; /* MTHRESHold in chars */ + +static void qst (char *base, char *max); + +#ifdef __cplusplus +} +#endif + +/* + * qsort: + * First, set up some global parameters for qst to share. Then, quicksort + * with qst(), and then a cleanup insertion sort ourselves. Sound simple? + * It's not... + */ +#undef min +#undef max +void +qsort( + char *base, + int n, + int size, + QSFP compar) +{ + register char c, *i, *j, *lo, *hi; + char *min, *max; + + if (n <= 1) + return; + qsz = size; + qcmp = compar; + thresh = qsz * THRESH; + mthresh = qsz * MTHRESH; + max = base + n * qsz; + if (n >= THRESH) { + qst(base, max); + hi = base + thresh; + } else { + hi = max; + } + /* + * First put smallest element, which must be in the first THRESH, in + * the first position as a sentinel. This is done just by searching + * the first THRESH elements (or the first n if n < THRESH), finding + * the min, and swapping it into the first position. + */ + for (j = lo = base; (lo += qsz) < hi; ) + if ((*qcmp)(j, lo) > 0) + j = lo; + if (j != base) { + /* swap j into place */ + for (i = base, hi = base + qsz; i < hi; ) { + c = *j; + *j++ = *i; + *i++ = c; + } + } + /* + * With our sentinel in place, we now run the following hyper-fast + * insertion sort. For each remaining element, min, from [1] to [n-1], + * set hi to the index of the element AFTER which this one goes. + * Then, do the standard insertion sort shift on a character at a time + * basis for each element in the frob. + */ + for (min = base; (hi = min += qsz) < max; ) { + while ((*qcmp)(hi -= qsz, min) > 0) + /* void */; + if ((hi += qsz) != min) { + for (lo = min + qsz; --lo >= min; ) { + c = *lo; + for (i = j = lo; (j -= qsz) >= hi; i = j) + *i = *j; + *i = c; + } + } + } +} + +/* + * qst: + * Do a quicksort + * First, find the median element, and put that one in the first place as the + * discriminator. (This "median" is just the median of the first, last and + * middle elements). (Using this median instead of the first element is a big + * win). Then, the usual partitioning/swapping, followed by moving the + * discriminator into the right place. Then, figure out the sizes of the two + * partions, do the smaller one recursively and the larger one via a repeat of + * this code. Stopping when there are less than THRESH elements in a partition + * and cleaning up with an insertion sort (in our caller) is a huge win. + * All data swaps are done in-line, which is space-losing but time-saving. + * (And there are only three places where this is done). + */ + +static void +qst(char *base, char *max) +{ + register char c, *i, *j, *jj; + register int ii; + char *mid, *tmp; + int lo, hi; + + /* + * At the top here, lo is the number of characters of elements in the + * current partition. (Which should be max - base). + * Find the median of the first, last, and middle element and make + * that the middle element. Set j to largest of first and middle. + * If max is larger than that guy, then it's that guy, else compare + * max with loser of first and take larger. Things are set up to + * prefer the middle, then the first in case of ties. + */ + lo = max - base; /* number of elements as chars */ + do { + mid = i = base + qsz * ((lo / qsz) >> 1); + if (lo >= mthresh) { + j = ((*qcmp)((jj = base), i) > 0 ? jj : i); + if ((*qcmp)(j, (tmp = max - qsz)) > 0) { + /* switch to first loser */ + j = (j == jj ? i : jj); + if ((*qcmp)(j, tmp) < 0) + j = tmp; + } + if (j != i) { + ii = qsz; + do { + c = *i; + *i++ = *j; + *j++ = c; + } while (--ii); + } + } + /* + * Semi-standard quicksort partitioning/swapping + */ + for (i = base, j = max - qsz; ; ) { + while (i < mid && (*qcmp)(i, mid) <= 0) + i += qsz; + while (j > mid) { + if ((*qcmp)(mid, j) <= 0) { + j -= qsz; + continue; + } + tmp = i + qsz; /* value of i after swap */ + if (i == mid) { + /* j <-> mid, new mid is j */ + mid = jj = j; + } else { + /* i <-> j */ + jj = j; + j -= qsz; + } + goto swap; + } + if (i == mid) { + break; + } else { + /* i <-> mid, new mid is i */ + jj = mid; + tmp = mid = i; /* value of i after swap */ + j -= qsz; + } + swap: + ii = qsz; + do { + c = *i; + *i++ = *jj; + *jj++ = c; + } while (--ii); + i = tmp; + } + /* + * Look at sizes of the two partitions, do the smaller + * one first by recursion, then do the larger one by + * making sure lo is its size, base and max are update + * correctly, and branching back. But only repeat + * (recursively or by branching) if the partition is + * of at least size THRESH. + */ + i = (j = mid) + qsz; + if ((lo = j - base) <= (hi = max - i)) { + if (lo >= thresh) + qst(base, j); + base = i; + lo = hi; + } else { + if (hi >= thresh) + qst(i, max); + max = j; + } + } while (lo >= thresh); +} + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/obj/Makefile b/resources/3rdparty/cudd-2.5.0/obj/Makefile new file mode 100644 index 000000000..ffc656452 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/obj/Makefile @@ -0,0 +1,114 @@ +# $Id: Makefile,v 1.3 2001/03/19 07:34:37 fabio Exp fabio $ +# +# obj: CUDD's C++ interface +#--------------------------------------------------------------------------- +.SUFFIXES: .o .cc .u + +#CXX = g++ +CXX = clang++ +RANLIB = ranlib +# Define EXE as .exe for MS-DOS and derivatives. +PURE = +EXE = +#EXE = .exe + +MFLAG = +#ICFLAGS = -g +ICFLAGS = +XCFLAGS = +#CXXFLAGS = +CXXFLAGS = -O3 -std=c++11 -stdlib=libc++ +#CXXFLAGS = -O3 -std=c++0x +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) $(CXXFLAGS) +DDDEBUG = + +LINTFLAGS = -u -n -DDD_STATS -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_DEBUG -DDD_UNIQUE_PROFILE + +# this is to create the lint library +LINTSWITCH = -o + +WHERE = .. + +INCLUDE = $(WHERE)/include + +LIBS = ./libobj.a $(WHERE)/cudd/libcudd.a $(WHERE)/mtr/libmtr.a \ + $(WHERE)/st/libst.a $(WHERE)/util/libutil.a $(WHERE)/epd/libepd.a + +MNEMLIB = + +BLIBS = -kL. -klobj -kL$(WHERE)/cudd -klcudd -kL$(WHERE)/mtr -klmtr \ + -kL$(WHERE)/st -klst -kL$(WHERE)/util -klutil -kL$(WHERE)/epd -klepd + +LINTLIBS = ./llib-lobj.ln $(WHERE)/cudd/llib-lcudd.ln \ + $(WHERE)/mtr/llib-lmtr.ln $(WHERE)/st/llib-lst.ln \ + $(WHERE)/util/llib-lutil.ln $(WHERE)/epd/llib-lepd.ln + +LDFLAGS = + +# files for the package +P = obj +PSRC = cuddObj.cc +PHDR = cuddObj.hh $(INCLUDE)/cudd.h +POBJ = $(PSRC:.cc=.o) +PUBJ = $(PSRC:.cc=.u) +TARGET = test$(P)$(EXE) +TARGETu = test$(P)-u + +# files for the test program +SRC = test$(P).cc +OBJ = $(SRC:.cc=.o) +UBJ = $(SRC:.cc=.u) + +#------------------------------------------------------ + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.cc.o: $(PHDR) + $(CXX) -c $< -I$(INCLUDE) $(CFLAGS) $(DDDEBUG) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.cc.u: $(PHDR) + cxx -j $< -I$(INCLUDE) $(CFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) +$(OBJ): $(PHDR) +$(UBJ): $(PHDR) + +$(TARGET): $(SRC) $(OBJ) $(HDR) $(LIBS) $(MNEMLIB) + $(PURE) $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +# optimize (DECstations and Alphas only: uses u-code) +$(TARGETu): $(SRC) $(UBJ) $(HDR) $(LIBS:.a=.b) + cxx -O3 -Olimit 1000 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +lintpgm: lint + lint $(LINTFLAGS) -I$(INCLUDE) $(SRC) $(LINTLIBS) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +programs: $(TARGET) $(TARGETu) lintpgm + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \ + *.bak *~ tags .gdb_history *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc b/resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc new file mode 100644 index 000000000..b8a7f2179 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/obj/cuddObj.cc @@ -0,0 +1,5759 @@ +/**CFile*********************************************************************** + + FileName [cuddObj.cc] + + PackageName [cuddObj] + + Synopsis [Functions for the C++ object-oriented encapsulation of CUDD.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ +#include +#include +#include +#include +#include +#include "cuddObj.hh" + +using std::cout; +using std::cerr; +using std::endl; +using std::hex; +using std::string; +using std::vector; +using std::sort; + +// --------------------------------------------------------------------------- +// Variable declarations +// --------------------------------------------------------------------------- + +#ifndef lint +static char rcsid[] UNUSED = "$Id: cuddObj.cc,v 1.15 2012/02/05 01:06:40 fabio Exp fabio $"; +#endif + +// --------------------------------------------------------------------------- +// Members of class DD +// --------------------------------------------------------------------------- + + +DD::DD() : p(0), node(0) {} + + +DD::DD(Capsule *cap, DdNode *ddNode) : p(cap), node(ddNode) { + if (node != 0) Cudd_Ref(node); + if (p->verbose) { + cout << "Standard DD constructor for node " << hex << long(node) << + " ref = " << Cudd_Regular(node)->ref << "\n"; + } + +} // DD::DD + + +DD::DD(Cudd const & manager, DdNode *ddNode) : p(manager.p), node(ddNode) { + checkReturnValue(ddNode); + if (node != 0) Cudd_Ref(node); + if (p->verbose) { + cout << "Standard DD constructor for node " << hex << long(node) << + " ref = " << Cudd_Regular(node)->ref << "\n"; + } + +} // DD::DD + + +DD::DD(const DD &from) { + p = from.p; + node = from.node; + if (node != 0) { + Cudd_Ref(node); + if (p->verbose) { + cout << "Copy DD constructor for node " << hex << long(node) << + " ref = " << Cudd_Regular(node)->ref << "\n"; + } + } + +} // DD::DD + + +DD::~DD() {} + + +inline DdManager * +DD::checkSameManager( + const DD &other) const +{ + DdManager *mgr = p->manager; + if (mgr != other.p->manager) { + p->errorHandler("Operands come from different manager."); + } + return mgr; + +} // DD::checkSameManager + + +inline void +DD::checkReturnValue( + const DdNode *result) const +{ + if (result == 0) { + DdManager *mgr = p->manager; + Cudd_ErrorType errType = Cudd_ReadErrorCode(mgr); + switch (errType) { + case CUDD_MEMORY_OUT: + p->errorHandler("Out of memory."); + break; + case CUDD_TOO_MANY_NODES: + break; + case CUDD_MAX_MEM_EXCEEDED: + p->errorHandler("Maximum memory exceeded."); + break; + case CUDD_TIMEOUT_EXPIRED: + { + std::ostringstream msg; + unsigned long lag = + Cudd_ReadElapsedTime(mgr) - Cudd_ReadTimeLimit(mgr); + msg << "Timeout expired. Lag = " << lag << " ms.\n"; + p->timeoutHandler(msg.str()); + } + break; + case CUDD_INVALID_ARG: + p->errorHandler("Invalid argument."); + break; + case CUDD_INTERNAL_ERROR: + p->errorHandler("Internal error."); + break; + case CUDD_NO_ERROR: + default: + p->errorHandler("Unexpected error."); + break; + } + } + +} // DD::checkReturnValue + + +inline void +DD::checkReturnValue( + const int result, + const int expected) const +{ + if (result != expected) { + DdManager *mgr = p->manager; + Cudd_ErrorType errType = Cudd_ReadErrorCode(mgr); + switch (errType) { + case CUDD_MEMORY_OUT: + p->errorHandler("Out of memory."); + break; + case CUDD_TOO_MANY_NODES: + break; + case CUDD_MAX_MEM_EXCEEDED: + p->errorHandler("Maximum memory exceeded."); + break; + case CUDD_TIMEOUT_EXPIRED: + { + std::ostringstream msg; + unsigned long lag = + Cudd_ReadElapsedTime(mgr) - Cudd_ReadTimeLimit(mgr); + msg << "Timeout expired. Lag = " << lag << " ms.\n"; + p->timeoutHandler(msg.str()); + } + break; + case CUDD_INVALID_ARG: + p->errorHandler("Invalid argument."); + break; + case CUDD_INTERNAL_ERROR: + p->errorHandler("Internal error."); + break; + case CUDD_NO_ERROR: + default: + p->errorHandler("Unexpected error."); + break; + } + } + +} // DD::checkReturnValue + + +DdManager * +DD::manager() const +{ + return p->manager; + +} // DD::manager + + +DdNode * +DD::getNode() const +{ + return node; + +} // DD::getNode + + +DdNode * +DD::getRegularNode() const +{ + return Cudd_Regular(node); + +} // DD::getRegularNode + + +int +DD::nodeCount() const +{ + return Cudd_DagSize(node); + +} // DD::nodeCount + + +unsigned int +DD::NodeReadIndex() const +{ + return Cudd_NodeReadIndex(node); + +} // DD::NodeReadIndex + + +// --------------------------------------------------------------------------- +// Members of class ABDD +// --------------------------------------------------------------------------- + + +ABDD::ABDD() : DD() {} +ABDD::ABDD(Capsule *cap, DdNode *bddNode) : DD(cap,bddNode) {} +ABDD::ABDD(Cudd const & manager, DdNode *bddNode) : DD(manager,bddNode) {} +ABDD::ABDD(const ABDD &from) : DD(from) {} + + +ABDD::~ABDD() { + if (node != 0) { + Cudd_RecursiveDeref(p->manager,node); + if (p->verbose) { + cout << "ADD/BDD destructor called for node " << hex << + long(node) << " ref = " << Cudd_Regular(node)->ref << "\n"; + } + } + +} // ABDD::~ABDD + + +bool +ABDD::operator==( + const ABDD& other) const +{ + checkSameManager(other); + return node == other.node; + +} // ABDD::operator== + + +bool +ABDD::operator!=( + const ABDD& other) const +{ + checkSameManager(other); + return node != other.node; + +} // ABDD::operator!= + + +bool +ABDD::IsOne() const +{ + return node == Cudd_ReadOne(p->manager); + +} // ABDD::IsOne + + +void +ABDD::print( + int nvars, + int verbosity) const +{ + cout.flush(); + int retval = Cudd_PrintDebug(p->manager,node,nvars,verbosity); + if (retval == 0) p->errorHandler("print failed"); + +} // ABDD::print + + +// --------------------------------------------------------------------------- +// Members of class BDD +// --------------------------------------------------------------------------- + +BDD::BDD() : ABDD() {} +BDD::BDD(Capsule *cap, DdNode *bddNode) : ABDD(cap,bddNode) {} +BDD::BDD(Cudd const & manager, DdNode *bddNode) : ABDD(manager,bddNode) {} +BDD::BDD(const BDD &from) : ABDD(from) {} + + +BDD +BDD::operator=( + const BDD& right) +{ + if (this == &right) return *this; + if (right.node != 0) Cudd_Ref(right.node); + if (node != 0) { + Cudd_RecursiveDeref(p->manager,node); + if (p->verbose) { + cout << "BDD dereferencing for node " << hex << long(node) << + " ref = " << Cudd_Regular(node)->ref << "\n"; + } + } + node = right.node; + p = right.p; + if (node != 0 && p->verbose) { + cout << "BDD assignment for node " << hex << long(node) << + " ref = " << Cudd_Regular(node)->ref << "\n"; + } + return *this; + +} // BDD::operator= + + +bool +BDD::operator<=( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return Cudd_bddLeq(mgr,node,other.node); + +} // BDD::operator<= + + +bool +BDD::operator>=( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return Cudd_bddLeq(mgr,other.node,node); + +} // BDD::operator>= + + +bool +BDD::operator<( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return node != other.node && Cudd_bddLeq(mgr,node,other.node); + +} // BDD::operator< + + +bool +BDD::operator>( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return node != other.node && Cudd_bddLeq(mgr,other.node,node); + +} // BDD::operator> + + +BDD +BDD::operator!() const +{ + return BDD(p, Cudd_Not(node)); + +} // BDD::operator! + + +BDD +BDD::operator~() const +{ + return BDD(p, Cudd_Not(node)); + +} // BDD::operator~ + + +BDD +BDD::operator*( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddAnd(mgr,node,other.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::operator* + + +BDD +BDD::operator*=( + const BDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddAnd(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // BDD::operator*= + + +BDD +BDD::operator&( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddAnd(mgr,node,other.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::operator& + + +BDD +BDD::operator&=( + const BDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddAnd(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // BDD::operator&= + + +BDD +BDD::operator+( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddOr(mgr,node,other.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::operator+ + + +BDD +BDD::operator+=( + const BDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddOr(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // BDD::operator+= + + +BDD +BDD::operator|( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddOr(mgr,node,other.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::operator| + + +BDD +BDD::operator|=( + const BDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddOr(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // BDD::operator|= + + +BDD +BDD::operator^( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddXor(mgr,node,other.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::operator^ + + +BDD +BDD::operator^=( + const BDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddXor(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // BDD::operator^= + + +BDD +BDD::operator-( + const BDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddAnd(mgr,node,Cudd_Not(other.node)); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::operator- + + +BDD +BDD::operator-=( + const BDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_bddAnd(mgr,node,Cudd_Not(other.node)); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // BDD::operator-= + + +bool +BDD::IsZero() const +{ + return node == Cudd_ReadLogicZero(p->manager); + +} // BDD::IsZero + + +// --------------------------------------------------------------------------- +// Members of class ADD +// --------------------------------------------------------------------------- + + +ADD::ADD() : ABDD() {} +ADD::ADD(Capsule *cap, DdNode *bddNode) : ABDD(cap,bddNode) {} +ADD::ADD(Cudd const & manager, DdNode *bddNode) : ABDD(manager,bddNode) {} +ADD::ADD(const ADD &from) : ABDD(from) {} + + +ADD +ADD::operator=( + const ADD& right) +{ + if (this == &right) return *this; + if (right.node != 0) Cudd_Ref(right.node); + if (node != 0) { + Cudd_RecursiveDeref(p->manager,node); + } + node = right.node; + p = right.p; + return *this; + +} // ADD::operator= + + +bool +ADD::operator<=( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + return Cudd_addLeq(mgr,node,other.node); + +} // ADD::operator<= + + +bool +ADD::operator>=( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + return Cudd_addLeq(mgr,other.node,node); + +} // ADD::operator>= + + +bool +ADD::operator<( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + return node != other.node && Cudd_addLeq(mgr,node,other.node); + +} // ADD::operator< + + +bool +ADD::operator>( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + return node != other.node && Cudd_addLeq(mgr,other.node,node); + +} // ADD::operator> + + +ADD +ADD::operator-() const +{ + return ADD(p, Cudd_addNegate(p->manager,node)); + +} // ADD::operator- + + +ADD +ADD::operator*( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addTimes,node,other.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::operator* + + +ADD +ADD::operator*=( + const ADD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addTimes,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // ADD::operator*= + + +ADD +ADD::operator+( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addPlus,node,other.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::operator+ + + +ADD +ADD::operator+=( + const ADD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addPlus,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // ADD::operator+= + + +ADD +ADD::operator-( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addMinus,node,other.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::operator- + + +ADD +ADD::operator-=( + const ADD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addMinus,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // ADD::operator-= + + +ADD +ADD::operator~() const +{ + return ADD(p, Cudd_addCmpl(p->manager,node)); + +} // ADD::operator~ + + +ADD +ADD::operator&( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addTimes,node,other.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::operator& + + +ADD +ADD::operator&=( + const ADD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addTimes,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // ADD::operator&= + + +ADD +ADD::operator|( + const ADD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addOr,node,other.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::operator| + + +ADD +ADD::operator|=( + const ADD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_addApply(mgr,Cudd_addOr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDeref(mgr,node); + node = result; + return *this; + +} // ADD::operator|= + + +bool +ADD::IsZero() const +{ + return node == Cudd_ReadZero(p->manager); + +} // ADD::IsZero + + +// --------------------------------------------------------------------------- +// Members of class ZDD +// --------------------------------------------------------------------------- + + +ZDD::ZDD(Capsule *cap, DdNode *bddNode) : DD(cap,bddNode) {} +ZDD::ZDD() : DD() {} +ZDD::ZDD(const ZDD &from) : DD(from) {} + + +ZDD::~ZDD() { + if (node != 0) { + Cudd_RecursiveDerefZdd(p->manager,node); + if (p->verbose) { + cout << "ZDD destructor called for node " << hex << long(node) << + " ref = " << Cudd_Regular(node)->ref << "\n"; + } + } + +} // ZDD::~ZDD + + +ZDD +ZDD::operator=( + const ZDD& right) +{ + if (this == &right) return *this; + if (right.node != 0) Cudd_Ref(right.node); + if (node != 0) { + Cudd_RecursiveDerefZdd(p->manager,node); + if (p->verbose) { + cout << "ZDD dereferencing for node " << hex << long(node) << + " ref = " << node->ref << "\n"; + } + } + node = right.node; + p = right.p; + if (node != 0 && p->verbose) { + cout << "ZDD assignment for node " << hex << long(node) << + " ref = " << node->ref << "\n"; + } + return *this; + +} // ZDD::operator= + + +bool +ZDD::operator==( + const ZDD& other) const +{ + checkSameManager(other); + return node == other.node; + +} // ZDD::operator== + + +bool +ZDD::operator!=( + const ZDD& other) const +{ + checkSameManager(other); + return node != other.node; + +} // ZDD::operator!= + + +bool +ZDD::operator<=( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return Cudd_zddDiffConst(mgr,node,other.node) == Cudd_ReadZero(mgr); + +} // ZDD::operator<= + + +bool +ZDD::operator>=( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return Cudd_zddDiffConst(mgr,other.node,node) == Cudd_ReadZero(mgr); + +} // ZDD::operator>= + + +bool +ZDD::operator<( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return node != other.node && + Cudd_zddDiffConst(mgr,node,other.node) == Cudd_ReadZero(mgr); + +} // ZDD::operator< + + +bool +ZDD::operator>( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + return node != other.node && + Cudd_zddDiffConst(mgr,other.node,node) == Cudd_ReadZero(mgr); + +} // ZDD::operator> + + +void +ZDD::print( + int nvars, + int verbosity) const +{ + cout.flush(); + int retval = Cudd_zddPrintDebug(p->manager,node,nvars,verbosity); + if (retval == 0) p->errorHandler("print failed"); + +} // ZDD::print + + +ZDD +ZDD::operator*( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddIntersect(mgr,node,other.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::operator* + + +ZDD +ZDD::operator*=( + const ZDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddIntersect(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDerefZdd(mgr,node); + node = result; + return *this; + +} // ZDD::operator*= + + +ZDD +ZDD::operator&( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddIntersect(mgr,node,other.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::operator& + + +ZDD +ZDD::operator&=( + const ZDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddIntersect(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDerefZdd(mgr,node); + node = result; + return *this; + +} // ZDD::operator&= + + +ZDD +ZDD::operator+( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddUnion(mgr,node,other.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::operator+ + + +ZDD +ZDD::operator+=( + const ZDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddUnion(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDerefZdd(mgr,node); + node = result; + return *this; + +} // ZDD::operator+= + + +ZDD +ZDD::operator|( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddUnion(mgr,node,other.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::operator| + + +ZDD +ZDD::operator|=( + const ZDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddUnion(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDerefZdd(mgr,node); + node = result; + return *this; + +} // ZDD::operator|= + + +ZDD +ZDD::operator-( + const ZDD& other) const +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddDiff(mgr,node,other.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::operator- + + +ZDD +ZDD::operator-=( + const ZDD& other) +{ + DdManager *mgr = checkSameManager(other); + DdNode *result = Cudd_zddDiff(mgr,node,other.node); + checkReturnValue(result); + Cudd_Ref(result); + Cudd_RecursiveDerefZdd(mgr,node); + node = result; + return *this; + +} // ZDD::operator-= + + +// --------------------------------------------------------------------------- +// Members of class Cudd +// --------------------------------------------------------------------------- + + +Cudd::Cudd( + unsigned int numVars, + unsigned int numVarsZ, + unsigned int numSlots, + unsigned int cacheSize, + unsigned long maxMemory) +{ + p = new Capsule; + p->manager = Cudd_Init(numVars,numVarsZ,numSlots,cacheSize,maxMemory); + p->errorHandler = defaultError; + p->timeoutHandler = defaultError; + p->verbose = 0; // initially terse + p->ref = 1; + +} // Cudd::Cudd + + +Cudd::Cudd( + const Cudd& x) +{ + p = x.p; + x.p->ref++; + if (p->verbose) + cout << "Cudd Copy Constructor" << endl; + +} // Cudd::Cudd + + +Cudd::~Cudd() +{ + if (--p->ref == 0) { +#ifdef DD_DEBUG + int retval = Cudd_CheckZeroRef(p->manager); + if (retval != 0) { + cerr << retval << " unexpected non-zero reference counts" << endl; + } else if (p->verbose) { + cerr << "All went well" << endl; + } +#endif + Cudd_Quit(p->manager); + delete p; + } + +} // Cudd::~Cudd + + +Cudd& +Cudd::operator=( + const Cudd& right) +{ + right.p->ref++; + if (--p->ref == 0) { // disconnect self + int retval = Cudd_CheckZeroRef(p->manager); + if (retval != 0) { + cerr << retval << " unexpected non-zero reference counts" << endl; + } else if (p->verbose) { + cerr << "All went well\n"; + } + Cudd_Quit(p->manager); + delete p; + } + p = right.p; + return *this; + +} // Cudd::operator= + + +PFC +Cudd::setHandler( + PFC newHandler) const +{ + PFC oldHandler = p->errorHandler; + p->errorHandler = newHandler; + return oldHandler; + +} // Cudd::setHandler + + +PFC +Cudd::getHandler() const +{ + return p->errorHandler; + +} // Cudd::getHandler + + +PFC +Cudd::setTimeoutHandler( + PFC newHandler) const +{ + PFC oldHandler = p->timeoutHandler; + p->timeoutHandler = newHandler; + return oldHandler; + +} // Cudd::setTimeoutHandler + + +PFC +Cudd::getTimeoutHandler() const +{ + return p->timeoutHandler; + +} // Cudd::getTimeourHandler + + +inline void +Cudd::checkReturnValue( + const DdNode *result) const +{ + if (result == 0) { + if (Cudd_ReadErrorCode(p->manager) == CUDD_MEMORY_OUT) { + p->errorHandler("Out of memory."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_TOO_MANY_NODES) { + p->errorHandler("Too many nodes."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_MAX_MEM_EXCEEDED) { + p->errorHandler("Maximum memory exceeded."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_TIMEOUT_EXPIRED) { + std::ostringstream msg; + DdManager *mgr = p->manager; + unsigned long lag = + Cudd_ReadElapsedTime(mgr) - Cudd_ReadTimeLimit(mgr); + msg << "Timeout expired. Lag = " << lag << " ms.\n"; + p->timeoutHandler(msg.str()); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_INVALID_ARG) { + p->errorHandler("Invalid argument."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_INTERNAL_ERROR) { + p->errorHandler("Internal error."); + } else { + p->errorHandler("Unexpected error."); + } + } + +} // Cudd::checkReturnValue + + +inline void +Cudd::checkReturnValue( + const int result) const +{ + if (result == 0) { + if (Cudd_ReadErrorCode(p->manager) == CUDD_MEMORY_OUT) { + p->errorHandler("Out of memory."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_TOO_MANY_NODES) { + p->errorHandler("Too many nodes."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_MAX_MEM_EXCEEDED) { + p->errorHandler("Maximum memory exceeded."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_TIMEOUT_EXPIRED) { + std::ostringstream msg; + DdManager *mgr = p->manager; + unsigned long lag = + Cudd_ReadElapsedTime(mgr) - Cudd_ReadTimeLimit(mgr); + msg << "Timeout expired. Lag = " << lag << " ms.\n"; + p->timeoutHandler(msg.str()); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_INVALID_ARG) { + p->errorHandler("Invalid argument."); + } else if (Cudd_ReadErrorCode(p->manager) == CUDD_INTERNAL_ERROR) { + p->errorHandler("Internal error."); + } else { + p->errorHandler("Unexpected error."); + } + } + +} // Cudd::checkReturnValue + + +void +Cudd::info() const +{ + cout.flush(); + int retval = Cudd_PrintInfo(p->manager,stdout); + checkReturnValue(retval); + +} // Cudd::info + + +BDD +Cudd::bddVar() const +{ + DdNode *result = Cudd_bddNewVar(p->manager); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::bddVar + + +BDD +Cudd::bddVar( + int index) const +{ + DdNode *result = Cudd_bddIthVar(p->manager,index); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::bddVar + + +BDD +Cudd::bddOne() const +{ + DdNode *result = Cudd_ReadOne(p->manager); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::bddOne + + +BDD +Cudd::bddZero() const +{ + DdNode *result = Cudd_ReadLogicZero(p->manager); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::bddZero + + +ADD +Cudd::addVar() const +{ + DdNode *result = Cudd_addNewVar(p->manager); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addVar + + +ADD +Cudd::addVar( + int index) const +{ + DdNode *result = Cudd_addIthVar(p->manager,index); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addVar + + +ADD +Cudd::addOne() const +{ + DdNode *result = Cudd_ReadOne(p->manager); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addOne + + +ADD +Cudd::addZero() const +{ + DdNode *result = Cudd_ReadZero(p->manager); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addZero + + +ADD +Cudd::constant( + CUDD_VALUE_TYPE c) const +{ + DdNode *result = Cudd_addConst(p->manager, c); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::constant + + +ADD +Cudd::plusInfinity() const +{ + DdNode *result = Cudd_ReadPlusInfinity(p->manager); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::plusInfinity + + +ADD +Cudd::minusInfinity() const +{ + DdNode *result = Cudd_ReadMinusInfinity(p->manager); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::minusInfinity + + +ZDD +Cudd::zddVar( + int index) const +{ + DdNode *result = Cudd_zddIthVar(p->manager,index); + checkReturnValue(result); + return ZDD(p, result); + +} // Cudd::zddVar + + +ZDD +Cudd::zddOne( + int i) const +{ + DdNode *result = Cudd_ReadZddOne(p->manager,i); + checkReturnValue(result); + return ZDD(p, result); + +} // Cudd::zddOne + + +ZDD +Cudd::zddZero() const +{ + DdNode *result = Cudd_ReadZero(p->manager); + checkReturnValue(result); + return ZDD(p, result); + +} // Cudd::zddZero + + +void +defaultError( + string message) +{ + cerr << message << endl; + assert(false); + +} // defaultError + + +// --------------------------------------------------------------------------- +// All the rest +// --------------------------------------------------------------------------- + + + +ADD +Cudd::addNewVarAtLevel( + int level) const +{ + DdNode *result = Cudd_addNewVarAtLevel(p->manager, level); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addNewVarAtLevel + + +BDD +Cudd::bddNewVarAtLevel( + int level) const +{ + DdNode *result = Cudd_bddNewVarAtLevel(p->manager, level); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::bddNewVarAtLevel + + +void +Cudd::zddVarsFromBddVars( + int multiplicity) const +{ + int result = Cudd_zddVarsFromBddVars(p->manager, multiplicity); + checkReturnValue(result); + +} // Cudd::zddVarsFromBddVars + + +unsigned long +Cudd::ReadStartTime() const +{ + return Cudd_ReadStartTime(p->manager); + +} // Cudd::ReadStartTime + + +unsigned long +Cudd::ReadElapsedTime() const +{ + return Cudd_ReadElapsedTime(p->manager); + +} // Cudd::ReadElapsedTime + + +void +Cudd::SetStartTime( + unsigned long st) const +{ + Cudd_SetStartTime(p->manager, st); + +} // Cudd::SetStartTime + + +void +Cudd::ResetStartTime() const +{ + Cudd_ResetStartTime(p->manager); + +} // Cudd::ResetStartTime + + +unsigned long +Cudd::ReadTimeLimit() const +{ + return Cudd_ReadTimeLimit(p->manager); + +} // Cudd::ReadTimeLimit + + +void +Cudd::SetTimeLimit( + unsigned long tl) const +{ + Cudd_SetTimeLimit(p->manager, tl); + +} // Cudd::SetTimeLimit + + +void +Cudd::UpdateTimeLimit() const +{ + Cudd_UpdateTimeLimit(p->manager); + +} // Cudd::UpdateTimeLimit + + +void +Cudd::IncreaseTimeLimit( + unsigned long increase) const +{ + Cudd_IncreaseTimeLimit(p->manager, increase); + +} // Cudd::IncreaseTimeLimit + + +void +Cudd::UnsetTimeLimit() const +{ + Cudd_UnsetTimeLimit(p->manager); + +} // Cudd::UnsetTimeLimit + + +bool +Cudd::TimeLimited() const +{ + return Cudd_TimeLimited(p->manager); + +} // Cudd::TimeLimited + + +void +Cudd::AutodynEnable( + Cudd_ReorderingType method) const +{ + Cudd_AutodynEnable(p->manager, method); + +} // Cudd::AutodynEnable + + +void +Cudd::AutodynDisable() const +{ + Cudd_AutodynDisable(p->manager); + +} // Cudd::AutodynDisable + + +bool +Cudd::ReorderingStatus( + Cudd_ReorderingType * method) const +{ + return Cudd_ReorderingStatus(p->manager, method); + +} // Cudd::ReorderingStatus + + +void +Cudd::AutodynEnableZdd( + Cudd_ReorderingType method) const +{ + Cudd_AutodynEnableZdd(p->manager, method); + +} // Cudd::AutodynEnableZdd + + +void +Cudd::AutodynDisableZdd() const +{ + Cudd_AutodynDisableZdd(p->manager); + +} // Cudd::AutodynDisableZdd + + +bool +Cudd::ReorderingStatusZdd( + Cudd_ReorderingType * method) const +{ + return Cudd_ReorderingStatusZdd(p->manager, method); + +} // Cudd::ReorderingStatusZdd + + +bool +Cudd::zddRealignmentEnabled() const +{ + return Cudd_zddRealignmentEnabled(p->manager); + +} // Cudd::zddRealignmentEnabled + + +void +Cudd::zddRealignEnable() const +{ + Cudd_zddRealignEnable(p->manager); + +} // Cudd::zddRealignEnable + + +void +Cudd::zddRealignDisable() const +{ + Cudd_zddRealignDisable(p->manager); + +} // Cudd::zddRealignDisable + + +bool +Cudd::bddRealignmentEnabled() const +{ + return Cudd_bddRealignmentEnabled(p->manager); + +} // Cudd::bddRealignmentEnabled + + +void +Cudd::bddRealignEnable() const +{ + Cudd_bddRealignEnable(p->manager); + +} // Cudd::bddRealignEnable + + +void +Cudd::bddRealignDisable() const +{ + Cudd_bddRealignDisable(p->manager); + +} // Cudd::bddRealignDisable + + +ADD +Cudd::background() const +{ + DdNode *result = Cudd_ReadBackground(p->manager); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::background + + +void +Cudd::SetBackground( + ADD bg) const +{ + DdManager *mgr = p->manager; + if (mgr != bg.manager()) { + p->errorHandler("Background comes from different manager."); + } + Cudd_SetBackground(mgr, bg.getNode()); + +} // Cudd::SetBackground + + +unsigned int +Cudd::ReadCacheSlots() const +{ + return Cudd_ReadCacheSlots(p->manager); + +} // Cudd::ReadCacheSlots + + +double +Cudd::ReadCacheLookUps() const +{ + return Cudd_ReadCacheLookUps(p->manager); + +} // Cudd::ReadCacheLookUps + + +double +Cudd::ReadCacheUsedSlots() const +{ + return Cudd_ReadCacheUsedSlots(p->manager); + +} // Cudd::ReadCacheUsedSlots + + +double +Cudd::ReadCacheHits() const +{ + return Cudd_ReadCacheHits(p->manager); + +} // Cudd::ReadCacheHits + + +unsigned int +Cudd::ReadMinHit() const +{ + return Cudd_ReadMinHit(p->manager); + +} // Cudd::ReadMinHit + + +void +Cudd::SetMinHit( + unsigned int hr) const +{ + Cudd_SetMinHit(p->manager, hr); + +} // Cudd::SetMinHit + + +unsigned int +Cudd::ReadLooseUpTo() const +{ + return Cudd_ReadLooseUpTo(p->manager); + +} // Cudd::ReadLooseUpTo + + +void +Cudd::SetLooseUpTo( + unsigned int lut) const +{ + Cudd_SetLooseUpTo(p->manager, lut); + +} // Cudd::SetLooseUpTo + + +unsigned int +Cudd::ReadMaxCache() const +{ + return Cudd_ReadMaxCache(p->manager); + +} // Cudd::ReadMaxCache + + +unsigned int +Cudd::ReadMaxCacheHard() const +{ + return Cudd_ReadMaxCacheHard(p->manager); + +} // Cudd::ReadMaxCacheHard + + +void +Cudd::SetMaxCacheHard( + unsigned int mc) const +{ + Cudd_SetMaxCacheHard(p->manager, mc); + +} // Cudd::SetMaxCacheHard + + +int +Cudd::ReadSize() const +{ + return Cudd_ReadSize(p->manager); + +} // Cudd::ReadSize + + +int +Cudd::ReadZddSize() const +{ + return Cudd_ReadZddSize(p->manager); + +} // Cudd::ReadZddSize + + +unsigned int +Cudd::ReadSlots() const +{ + return Cudd_ReadSlots(p->manager); + +} // Cudd::ReadSlots + + +unsigned int +Cudd::ReadKeys() const +{ + return Cudd_ReadKeys(p->manager); + +} // Cudd::ReadKeys + + +unsigned int +Cudd::ReadDead() const +{ + return Cudd_ReadDead(p->manager); + +} // Cudd::ReadDead + + +unsigned int +Cudd::ReadMinDead() const +{ + return Cudd_ReadMinDead(p->manager); + +} // Cudd::ReadMinDead + + +unsigned int +Cudd::ReadReorderings() const +{ + return Cudd_ReadReorderings(p->manager); + +} // Cudd::ReadReorderings + + +unsigned int +Cudd::ReadMaxReorderings() const +{ + return Cudd_ReadMaxReorderings(p->manager); + +} // Cudd::ReadMaxReorderings + +void +Cudd::SetMaxReorderings( + unsigned int mr) const +{ + Cudd_SetMaxReorderings(p->manager, mr); + +} // Cudd::SetMaxReorderings + +long +Cudd::ReadReorderingTime() const +{ + return Cudd_ReadReorderingTime(p->manager); + +} // Cudd::ReadReorderingTime + + +int +Cudd::ReadGarbageCollections() const +{ + return Cudd_ReadGarbageCollections(p->manager); + +} // Cudd::ReadGarbageCollections + + +long +Cudd::ReadGarbageCollectionTime() const +{ + return Cudd_ReadGarbageCollectionTime(p->manager); + +} // Cudd::ReadGarbageCollectionTime + + +int +Cudd::ReadSiftMaxVar() const +{ + return Cudd_ReadSiftMaxVar(p->manager); + +} // Cudd::ReadSiftMaxVar + + +void +Cudd::SetSiftMaxVar( + int smv) const +{ + Cudd_SetSiftMaxVar(p->manager, smv); + +} // Cudd::SetSiftMaxVar + + +int +Cudd::ReadSiftMaxSwap() const +{ + return Cudd_ReadSiftMaxSwap(p->manager); + +} // Cudd::ReadSiftMaxSwap + + +void +Cudd::SetSiftMaxSwap( + int sms) const +{ + Cudd_SetSiftMaxSwap(p->manager, sms); + +} // Cudd::SetSiftMaxSwap + + +double +Cudd::ReadMaxGrowth() const +{ + return Cudd_ReadMaxGrowth(p->manager); + +} // Cudd::ReadMaxGrowth + + +void +Cudd::SetMaxGrowth( + double mg) const +{ + Cudd_SetMaxGrowth(p->manager, mg); + +} // Cudd::SetMaxGrowth + + +MtrNode * +Cudd::ReadTree() const +{ + return Cudd_ReadTree(p->manager); + +} // Cudd::ReadTree + + +void +Cudd::SetTree( + MtrNode * tree) const +{ + Cudd_SetTree(p->manager, tree); + +} // Cudd::SetTree + + +void +Cudd::FreeTree() const +{ + Cudd_FreeTree(p->manager); + +} // Cudd::FreeTree + + +MtrNode * +Cudd::ReadZddTree() const +{ + return Cudd_ReadZddTree(p->manager); + +} // Cudd::ReadZddTree + + +void +Cudd::SetZddTree( + MtrNode * tree) const +{ + Cudd_SetZddTree(p->manager, tree); + +} // Cudd::SetZddTree + + +void +Cudd::FreeZddTree() const +{ + Cudd_FreeZddTree(p->manager); + +} // Cudd::FreeZddTree + + +int +Cudd::ReadPerm( + int i) const +{ + return Cudd_ReadPerm(p->manager, i); + +} // Cudd::ReadPerm + + +int +Cudd::ReadPermZdd( + int i) const +{ + return Cudd_ReadPermZdd(p->manager, i); + +} // Cudd::ReadPermZdd + + +int +Cudd::ReadInvPerm( + int i) const +{ + return Cudd_ReadInvPerm(p->manager, i); + +} // Cudd::ReadInvPerm + + +int +Cudd::ReadInvPermZdd( + int i) const +{ + return Cudd_ReadInvPermZdd(p->manager, i); + +} // Cudd::ReadInvPermZdd + + +BDD +Cudd::ReadVars( + int i) const +{ + DdNode *result = Cudd_ReadVars(p->manager, i); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::ReadVars + + +CUDD_VALUE_TYPE +Cudd::ReadEpsilon() const +{ + return Cudd_ReadEpsilon(p->manager); + +} // Cudd::ReadEpsilon + + +void +Cudd::SetEpsilon( + CUDD_VALUE_TYPE ep) const +{ + Cudd_SetEpsilon(p->manager, ep); + +} // Cudd::SetEpsilon + + +Cudd_AggregationType +Cudd::ReadGroupcheck() const +{ + return Cudd_ReadGroupcheck(p->manager); + +} // Cudd::ReadGroupcheck + + +void +Cudd::SetGroupcheck( + Cudd_AggregationType gc) const +{ + Cudd_SetGroupcheck(p->manager, gc); + +} // Cudd::SetGroupcheck + + +bool +Cudd::GarbageCollectionEnabled() const +{ + return Cudd_GarbageCollectionEnabled(p->manager); + +} // Cudd::GarbageCollectionEnabled + + +void +Cudd::EnableGarbageCollection() const +{ + Cudd_EnableGarbageCollection(p->manager); + +} // Cudd::EnableGarbageCollection + + +void +Cudd::DisableGarbageCollection() const +{ + Cudd_DisableGarbageCollection(p->manager); + +} // Cudd::DisableGarbageCollection + + +bool +Cudd::DeadAreCounted() const +{ + return Cudd_DeadAreCounted(p->manager); + +} // Cudd::DeadAreCounted + + +void +Cudd::TurnOnCountDead() const +{ + Cudd_TurnOnCountDead(p->manager); + +} // Cudd::TurnOnCountDead + + +void +Cudd::TurnOffCountDead() const +{ + Cudd_TurnOffCountDead(p->manager); + +} // Cudd::TurnOffCountDead + + +int +Cudd::ReadRecomb() const +{ + return Cudd_ReadRecomb(p->manager); + +} // Cudd::ReadRecomb + + +void +Cudd::SetRecomb( + int recomb) const +{ + Cudd_SetRecomb(p->manager, recomb); + +} // Cudd::SetRecomb + + +int +Cudd::ReadSymmviolation() const +{ + return Cudd_ReadSymmviolation(p->manager); + +} // Cudd::ReadSymmviolation + + +void +Cudd::SetSymmviolation( + int symmviolation) const +{ + Cudd_SetSymmviolation(p->manager, symmviolation); + +} // Cudd::SetSymmviolation + + +int +Cudd::ReadArcviolation() const +{ + return Cudd_ReadArcviolation(p->manager); + +} // Cudd::ReadArcviolation + + +void +Cudd::SetArcviolation( + int arcviolation) const +{ + Cudd_SetArcviolation(p->manager, arcviolation); + +} // Cudd::SetArcviolation + + +int +Cudd::ReadPopulationSize() const +{ + return Cudd_ReadPopulationSize(p->manager); + +} // Cudd::ReadPopulationSize + + +void +Cudd::SetPopulationSize( + int populationSize) const +{ + Cudd_SetPopulationSize(p->manager, populationSize); + +} // Cudd::SetPopulationSize + + +int +Cudd::ReadNumberXovers() const +{ + return Cudd_ReadNumberXovers(p->manager); + +} // Cudd::ReadNumberXovers + + +void +Cudd::SetNumberXovers( + int numberXovers) const +{ + Cudd_SetNumberXovers(p->manager, numberXovers); + +} // Cudd::SetNumberXovers + + +unsigned int +Cudd::ReadOrderRandomization() const +{ + return Cudd_ReadOrderRandomization(p->manager); + +} // Cudd::ReadOrderRandomization + + +void +Cudd::SetOrderRandomization( + unsigned int factor) const +{ + Cudd_SetOrderRandomization(p->manager, factor); + +} // Cudd::SetOrderRandomization + + +unsigned long +Cudd::ReadMemoryInUse() const +{ + return Cudd_ReadMemoryInUse(p->manager); + +} // Cudd::ReadMemoryInUse + + +long +Cudd::ReadPeakNodeCount() const +{ + return Cudd_ReadPeakNodeCount(p->manager); + +} // Cudd::ReadPeakNodeCount + + +long +Cudd::ReadNodeCount() const +{ + return Cudd_ReadNodeCount(p->manager); + +} // Cudd::ReadNodeCount + + +long +Cudd::zddReadNodeCount() const +{ + return Cudd_zddReadNodeCount(p->manager); + +} // Cudd::zddReadNodeCount + + +void +Cudd::AddHook( + DD_HFP f, + Cudd_HookType where) const +{ + int result = Cudd_AddHook(p->manager, f, where); + checkReturnValue(result); + +} // Cudd::AddHook + + +void +Cudd::RemoveHook( + DD_HFP f, + Cudd_HookType where) const +{ + int result = Cudd_RemoveHook(p->manager, f, where); + checkReturnValue(result); + +} // Cudd::RemoveHook + + +bool +Cudd::IsInHook( + DD_HFP f, + Cudd_HookType where) const +{ + return Cudd_IsInHook(p->manager, f, where); + +} // Cudd::IsInHook + + +void +Cudd::EnableReorderingReporting() const +{ + int result = Cudd_EnableReorderingReporting(p->manager); + checkReturnValue(result); + +} // Cudd::EnableReorderingReporting + + +void +Cudd::DisableReorderingReporting() const +{ + int result = Cudd_DisableReorderingReporting(p->manager); + checkReturnValue(result); + +} // Cudd::DisableReorderingReporting + + +bool +Cudd::ReorderingReporting() const +{ + return Cudd_ReorderingReporting(p->manager); + +} // Cudd::ReorderingReporting + + +int +Cudd::ReadErrorCode() const +{ + return Cudd_ReadErrorCode(p->manager); + +} // Cudd::ReadErrorCode + + +void +Cudd::ClearErrorCode() const +{ + Cudd_ClearErrorCode(p->manager); + +} // Cudd::ClearErrorCode + + +FILE * +Cudd::ReadStdout() const +{ + return Cudd_ReadStdout(p->manager); + +} // Cudd::ReadStdout + + +void +Cudd::SetStdout(FILE *fp) const +{ + Cudd_SetStdout(p->manager, fp); + +} // Cudd::SetStdout + + +FILE * +Cudd::ReadStderr() const +{ + return Cudd_ReadStderr(p->manager); + +} // Cudd::ReadStderr + + +void +Cudd::SetStderr(FILE *fp) const +{ + Cudd_SetStderr(p->manager, fp); + +} // Cudd::SetStderr + + +unsigned int +Cudd::ReadNextReordering() const +{ + return Cudd_ReadNextReordering(p->manager); + +} // Cudd::ReadNextReordering + + +void +Cudd::SetNextReordering( + unsigned int next) const +{ + Cudd_SetNextReordering(p->manager, next); + +} // Cudd::SetNextReordering + + +double +Cudd::ReadSwapSteps() const +{ + return Cudd_ReadSwapSteps(p->manager); + +} // Cudd::ReadSwapSteps + + +unsigned int +Cudd::ReadMaxLive() const +{ + return Cudd_ReadMaxLive(p->manager); + +} // Cudd::ReadMaxLive + + +void +Cudd::SetMaxLive(unsigned int maxLive) const +{ + Cudd_SetMaxLive(p->manager, maxLive); + +} // Cudd::SetMaxLive + + +unsigned long +Cudd::ReadMaxMemory() const +{ + return Cudd_ReadMaxMemory(p->manager); + +} // Cudd::ReadMaxMemory + + +void +Cudd::SetMaxMemory(unsigned long maxMem) const +{ + Cudd_SetMaxMemory(p->manager, maxMem); + +} // Cudd::SetMaxMemory + + +int +Cudd::bddBindVar(int index) const +{ + return Cudd_bddBindVar(p->manager, index); + +} // Cudd::bddBindVar + + +int +Cudd::bddUnbindVar(int index) const +{ + return Cudd_bddUnbindVar(p->manager, index); + +} // Cudd::bddUnbindVar + + +bool +Cudd::bddVarIsBound(int index) const +{ + return Cudd_bddVarIsBound(p->manager, index); + +} // Cudd::bddVarIsBound + + +ADD +ADD::ExistAbstract( + const ADD& cube) const +{ + DdManager *mgr = checkSameManager(cube); + DdNode *result = Cudd_addExistAbstract(mgr, node, cube.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::ExistAbstract + + +ADD +ADD::UnivAbstract( + const ADD& cube) const +{ + DdManager *mgr = checkSameManager(cube); + DdNode *result = Cudd_addUnivAbstract(mgr, node, cube.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::UnivAbstract + + +ADD +ADD::OrAbstract( + const ADD& cube) const +{ + DdManager *mgr = checkSameManager(cube); + DdNode *result = Cudd_addOrAbstract(mgr, node, cube.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::OrAbstract + + +ADD +ADD::Plus( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addPlus, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Plus + + +ADD +ADD::Times( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addTimes, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Times + + +ADD +ADD::Threshold( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addThreshold, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Threshold + + +ADD +ADD::SetNZ( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addSetNZ, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::SetNZ + + +ADD +ADD::Divide( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addDivide, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Divide + + +ADD +ADD::Minus( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addMinus, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Minus + + +ADD +ADD::Minimum( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addMinimum, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Minimum + + +ADD +ADD::Maximum( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addMaximum, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Maximum + + +ADD +ADD::OneZeroMaximum( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addOneZeroMaximum, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::OneZeroMaximum + + +ADD +ADD::Diff( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addDiff, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Diff + + +ADD +ADD::Agreement( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addAgreement, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Agreement + + +ADD +ADD::Or( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addOr, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Or + + +ADD +ADD::Nand( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addNand, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Nand + + +ADD +ADD::Nor( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addNor, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Nor + + +ADD +ADD::Xor( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addXor, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Xor + + +ADD +ADD::Xnor( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addXnor, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Xnor + + +ADD +ADD::Log() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addMonadicApply(mgr, Cudd_addLog, node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Log + + +ADD +ADD::FindMax() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addFindMax(mgr, node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::FindMax + + +ADD +ADD::FindMin() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addFindMin(mgr, node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::FindMin + + +ADD +ADD::IthBit( + int bit) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addIthBit(mgr, node, bit); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::IthBit + + +ADD +ADD::ScalarInverse( + const ADD& epsilon) const +{ + DdManager *mgr = checkSameManager(epsilon); + DdNode *result = Cudd_addScalarInverse(mgr, node, epsilon.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::ScalarInverse + + +ADD +ADD::Ite( + const ADD& g, + const ADD& h) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(h); + DdNode *result = Cudd_addIte(mgr, node, g.node, h.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Ite + + +ADD +ADD::IteConstant( + const ADD& g, + const ADD& h) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(h); + DdNode *result = Cudd_addIteConstant(mgr, node, g.node, h.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::IteConstant + + +ADD +ADD::EvalConst( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addEvalConst(mgr, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::EvalConst + + +bool +ADD::Leq( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + return Cudd_addLeq(mgr, node, g.node); + +} // ADD::Leq + + +ADD +ADD::Cmpl() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addCmpl(mgr, node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Cmpl + + +ADD +ADD::Negate() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addNegate(mgr, node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Negate + + +ADD +ADD::RoundOff( + int N) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addRoundOff(mgr, node, N); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::RoundOff + + +ADD +Cudd::Walsh( + vector x, + vector y) +{ + int n = x.size(); + DdNode **X = new DdNode *[n]; + DdNode **Y = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + } + DdNode *result = Cudd_addWalsh(p->manager, X, Y, n); + delete [] X; + delete [] Y; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Walsh + + +ADD +Cudd::addResidue( + int n, + int m, + int options, + int top) +{ + DdNode *result = Cudd_addResidue(p->manager, n, m, options, top); + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addResidue + +ADD +ADD::Equals(const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addEquals, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Equals + +ADD +ADD::NotEquals(const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addNotEquals, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::NotEquals + +ADD +ADD::LessThan(const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addLessThan, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::LessThan + +ADD +ADD::LessThanOrEqual(const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addLessThanEquals, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::LessThanOrEqual + +ADD +ADD::GreaterThan(const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addGreaterThan, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::GreaterThan + +ADD +ADD::GreaterThanOrEqual(const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addApply(mgr, Cudd_addGreaterThanEquals, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::GreaterThanOrEqual + + +BDD +BDD::AndAbstract( + const BDD& g, + const BDD& cube, + unsigned int limit) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(cube); + DdNode *result; + if (limit == 0) + result = Cudd_bddAndAbstract(mgr, node, g.node, cube.node); + else + result = Cudd_bddAndAbstractLimit(mgr, node, g.node, + cube.node, limit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::AndAbstract + + +int +Cudd::ApaNumberOfDigits( + int binaryDigits) const +{ + return Cudd_ApaNumberOfDigits(binaryDigits); + +} // Cudd::ApaNumberOfDigits + + +DdApaNumber +Cudd::NewApaNumber( + int digits) const +{ + return Cudd_NewApaNumber(digits); + +} // Cudd::NewApaNumber + + +void +Cudd::ApaCopy( + int digits, + DdApaNumber source, + DdApaNumber dest) const +{ + Cudd_ApaCopy(digits, source, dest); + +} // Cudd::ApaCopy + + +DdApaDigit +Cudd::ApaAdd( + int digits, + DdApaNumber a, + DdApaNumber b, + DdApaNumber sum) const +{ + return Cudd_ApaAdd(digits, a, b, sum); + +} // Cudd::ApaAdd + + +DdApaDigit +Cudd::ApaSubtract( + int digits, + DdApaNumber a, + DdApaNumber b, + DdApaNumber diff) const +{ + return Cudd_ApaSubtract(digits, a, b, diff); + +} // Cudd::ApaSubtract + + +DdApaDigit +Cudd::ApaShortDivision( + int digits, + DdApaNumber dividend, + DdApaDigit divisor, + DdApaNumber quotient) const +{ + return Cudd_ApaShortDivision(digits, dividend, divisor, quotient); + +} // Cudd::ApaShortDivision + + +void +Cudd::ApaShiftRight( + int digits, + DdApaDigit in, + DdApaNumber a, + DdApaNumber b) const +{ + Cudd_ApaShiftRight(digits, in, a, b); + +} // Cudd::ApaShiftRight + + +void +Cudd::ApaSetToLiteral( + int digits, + DdApaNumber number, + DdApaDigit literal) const +{ + Cudd_ApaSetToLiteral(digits, number, literal); + +} // Cudd::ApaSetToLiteral + + +void +Cudd::ApaPowerOfTwo( + int digits, + DdApaNumber number, + int power) const +{ + Cudd_ApaPowerOfTwo(digits, number, power); + +} // Cudd::ApaPowerOfTwo + + +void +Cudd::ApaPrintHex( + FILE * fp, + int digits, + DdApaNumber number) const +{ + cout.flush(); + int result = Cudd_ApaPrintHex(fp, digits, number); + checkReturnValue(result); + +} // Cudd::ApaPrintHex + + +void +Cudd::ApaPrintDecimal( + FILE * fp, + int digits, + DdApaNumber number) const +{ + cout.flush(); + int result = Cudd_ApaPrintDecimal(fp, digits, number); + checkReturnValue(result); + +} // Cudd::ApaPrintDecimal + + +DdApaNumber +ABDD::ApaCountMinterm( + int nvars, + int * digits) const +{ + DdManager *mgr = p->manager; + return Cudd_ApaCountMinterm(mgr, node, nvars, digits); + +} // ABDD::ApaCountMinterm + + +void +ABDD::ApaPrintMinterm( + int nvars, + FILE * fp) const +{ + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_ApaPrintMinterm(fp, mgr, node, nvars); + checkReturnValue(result); + +} // ABDD::ApaPrintMinterm + + +void +ABDD::EpdPrintMinterm( + int nvars, + FILE * fp) const +{ + EpDouble count; + char str[24]; + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_EpdCountMinterm(mgr, node, nvars, &count); + checkReturnValue(result,0); + EpdGetString(&count, str); + fprintf(fp, "%s\n", str); + +} // ABDD::ApaPrintMinterm + + +BDD +BDD::UnderApprox( + int numVars, + int threshold, + bool safe, + double quality) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_UnderApprox(mgr, node, numVars, threshold, safe, quality); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::UnderApprox + + +BDD +BDD::OverApprox( + int numVars, + int threshold, + bool safe, + double quality) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_OverApprox(mgr, node, numVars, threshold, safe, quality); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::OverApprox + + +BDD +BDD::RemapUnderApprox( + int numVars, + int threshold, + double quality) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_RemapUnderApprox(mgr, node, numVars, threshold, quality); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::RemapUnderApprox + + +BDD +BDD::RemapOverApprox( + int numVars, + int threshold, + double quality) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_RemapOverApprox(mgr, node, numVars, threshold, quality); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::RemapOverApprox + + +BDD +BDD::BiasedUnderApprox( + const BDD& bias, + int numVars, + int threshold, + double quality1, + double quality0) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_BiasedUnderApprox(mgr, node, bias.node, numVars, + threshold, quality1, quality0); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::BiasedUnderApprox + + +BDD +BDD::BiasedOverApprox( + const BDD& bias, + int numVars, + int threshold, + double quality1, + double quality0) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_BiasedOverApprox(mgr, node, bias.node, numVars, + threshold, quality1, quality0); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::BiasedOverApprox + + +BDD +BDD::ExistAbstract( + const BDD& cube, + unsigned int limit) const +{ + DdManager *mgr = checkSameManager(cube); + DdNode *result; + if (limit == 0) + result = Cudd_bddExistAbstract(mgr, node, cube.node); + else + result = Cudd_bddExistAbstractLimit(mgr, node, cube.node, limit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::ExistAbstract + + +BDD +BDD::XorExistAbstract( + const BDD& g, + const BDD& cube) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(cube); + DdNode *result = Cudd_bddXorExistAbstract(mgr, node, g.node, cube.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::XorExistAbstract + + +BDD +BDD::UnivAbstract( + const BDD& cube) const +{ + DdManager *mgr = checkSameManager(cube); + DdNode *result = Cudd_bddUnivAbstract(mgr, node, cube.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::UnivAbstract + + +BDD +BDD::BooleanDiff( + int x) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_bddBooleanDiff(mgr, node, x); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::BooleanDiff + + +bool +BDD::VarIsDependent( + const BDD& var) const +{ + DdManager *mgr = p->manager; + return Cudd_bddVarIsDependent(mgr, node, var.node); + +} // BDD::VarIsDependent + + +double +BDD::Correlation( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + return Cudd_bddCorrelation(mgr, node, g.node); + +} // BDD::Correlation + + +double +BDD::CorrelationWeights( + const BDD& g, + double * prob) const +{ + DdManager *mgr = checkSameManager(g); + return Cudd_bddCorrelationWeights(mgr, node, g.node, prob); + +} // BDD::CorrelationWeights + + +BDD +BDD::Ite( + const BDD& g, + const BDD& h, + unsigned int limit) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(h); + DdNode *result; + if (limit == 0) + result = Cudd_bddIte(mgr, node, g.node, h.node); + else + result = Cudd_bddIteLimit(mgr, node, g.node, h.node, limit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Ite + + +BDD +BDD::IteConstant( + const BDD& g, + const BDD& h) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(h); + DdNode *result = Cudd_bddIteConstant(mgr, node, g.node, h.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::IteConstant + + +BDD +BDD::Intersect( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddIntersect(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Intersect + + +BDD +BDD::And( + const BDD& g, + unsigned int limit) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result; + if (limit == 0) + result = Cudd_bddAnd(mgr, node, g.node); + else + result = Cudd_bddAndLimit(mgr, node, g.node, limit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::And + + +BDD +BDD::Or( + const BDD& g, + unsigned int limit) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result; + if (limit == 0) + result = Cudd_bddOr(mgr, node, g.node); + else + result = Cudd_bddOrLimit(mgr, node, g.node, limit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Or + + +BDD +BDD::Nand( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddNand(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Nand + + +BDD +BDD::Nor( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddNor(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Nor + + +BDD +BDD::Xor( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddXor(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Xor + + +BDD +BDD::Xnor( + const BDD& g, + unsigned int limit) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result; + if (limit == 0) + result = Cudd_bddXnor(mgr, node, g.node); + else + result = Cudd_bddXnorLimit(mgr, node, g.node, limit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Xnor + + +bool +BDD::Leq( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + return Cudd_bddLeq(mgr, node, g.node); + +} // BDD::Leq + + +BDD +ADD::BddThreshold( + CUDD_VALUE_TYPE value) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addBddThreshold(mgr, node, value); + checkReturnValue(result); + return BDD(p, result); + +} // ADD::BddThreshold + + +BDD +ADD::BddStrictThreshold( + CUDD_VALUE_TYPE value) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addBddStrictThreshold(mgr, node, value); + checkReturnValue(result); + return BDD(p, result); + +} // ADD::BddStrictThreshold + + +BDD +ADD::BddInterval( + CUDD_VALUE_TYPE lower, + CUDD_VALUE_TYPE upper) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addBddInterval(mgr, node, lower, upper); + checkReturnValue(result); + return BDD(p, result); + +} // ADD::BddInterval + + +BDD +ADD::BddIthBit( + int bit) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addBddIthBit(mgr, node, bit); + checkReturnValue(result); + return BDD(p, result); + +} // ADD::BddIthBit + + +ADD +BDD::Add() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_BddToAdd(mgr, node); + checkReturnValue(result); + return ADD(p, result); + +} // BDD::Add + + +BDD +ADD::BddPattern() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addBddPattern(mgr, node); + checkReturnValue(result); + return BDD(p, result); + +} // ADD::BddPattern + + +BDD +BDD::Transfer( + Cudd& destination) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_bddTransfer(mgr, destination.p->manager, node); + checkReturnValue(result); + return BDD(destination.p, result); + +} // BDD::Transfer + + +void +Cudd::DebugCheck() +{ + int result = Cudd_DebugCheck(p->manager); + checkReturnValue(result == 0); + +} // Cudd::DebugCheck + + +void +Cudd::CheckKeys() +{ + int result = Cudd_CheckKeys(p->manager); + checkReturnValue(result == 0); + +} // Cudd::CheckKeys + + +BDD +BDD::ClippingAnd( + const BDD& g, + int maxDepth, + int direction) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddClippingAnd(mgr, node, g.node, maxDepth, + direction); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::ClippingAnd + + +BDD +BDD::ClippingAndAbstract( + const BDD& g, + const BDD& cube, + int maxDepth, + int direction) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(cube); + DdNode *result = Cudd_bddClippingAndAbstract(mgr, node, g.node, cube.node, + maxDepth, direction); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::ClippingAndAbstract + + +ADD +ADD::Cofactor( + const ADD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_Cofactor(mgr, node, g.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Cofactor + + +BDD +BDD::Cofactor( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_Cofactor(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Cofactor + + +BDD +BDD::Compose( + const BDD& g, + int v) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddCompose(mgr, node, g.node, v); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Compose + + +ADD +ADD::Compose( + const ADD& g, + int v) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_addCompose(mgr, node, g.node, v); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Compose + + +ADD +ADD::Permute( + int * permut) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_addPermute(mgr, node, permut); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Permute + + +ADD +ADD::SwapVariables( + vector x, + vector y) const +{ + int n = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[n]; + DdNode **Y = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = x[i].node; + Y[i] = y[i].node; + } + DdNode *result = Cudd_addSwapVariables(mgr, node, X, Y, n); + delete [] X; + delete [] Y; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::SwapVariables + + +BDD +BDD::Permute( + int * permut) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_bddPermute(mgr, node, permut); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Permute + + +BDD +BDD::SwapVariables( + std::vector x, + std::vector y) const +{ + int n = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[n]; + DdNode **Y = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = x[i].node; + Y[i] = y[i].node; + } + DdNode *result = Cudd_bddSwapVariables(mgr, node, X, Y, n); + delete [] X; + delete [] Y; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SwapVariables + + +BDD +BDD::AdjPermuteX( + vector x) const +{ + int n = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = x[i].node; + } + DdNode *result = Cudd_bddAdjPermuteX(mgr, node, X, n); + delete [] X; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::AdjPermuteX + + +ADD +ADD::VectorCompose( + vector vector) const +{ + DdManager *mgr = p->manager; + int n = Cudd_ReadSize(mgr); + DdNode **X = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = vector[i].node; + } + DdNode *result = Cudd_addVectorCompose(mgr, node, X); + delete [] X; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::VectorCompose + + +ADD +ADD::NonSimCompose( + vector vector) const +{ + DdManager *mgr = p->manager; + int n = Cudd_ReadSize(mgr); + DdNode **X = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = vector[i].node; + } + DdNode *result = Cudd_addNonSimCompose(mgr, node, X); + delete [] X; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::NonSimCompose + + +BDD +BDD::VectorCompose( + vector vector) const +{ + DdManager *mgr = p->manager; + int n = Cudd_ReadSize(mgr); + DdNode **X = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = vector[i].node; + } + DdNode *result = Cudd_bddVectorCompose(mgr, node, X); + delete [] X; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::VectorCompose + + +void +BDD::ApproxConjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddApproxConjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::ApproxConjDecomp + + +void +BDD::ApproxDisjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddApproxDisjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::ApproxDisjDecomp + + +void +BDD::IterConjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddIterConjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::IterConjDecomp + + +void +BDD::IterDisjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddIterDisjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::IterDisjDecomp + + +void +BDD::GenConjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddGenConjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::GenConjDecomp + + +void +BDD::GenDisjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddGenDisjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::GenDisjDecomp + + +void +BDD::VarConjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddVarConjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::VarConjDecomp + + +void +BDD::VarDisjDecomp( + BDD* g, + BDD* h) const +{ + DdManager *mgr = p->manager; + DdNode **pieces; + int result = Cudd_bddVarDisjDecomp(mgr, node, &pieces); + checkReturnValue(result == 2); + *g = BDD(p, pieces[0]); + *h = BDD(p, pieces[1]); + Cudd_RecursiveDeref(mgr,pieces[0]); + Cudd_RecursiveDeref(mgr,pieces[1]); + free(pieces); + +} // BDD::VarDisjDecomp + + +bool +ABDD::IsCube() const +{ + DdManager *mgr = p->manager; + return Cudd_CheckCube(mgr, node); + +} // ABDD::IsCube + + +BDD +ABDD::FindEssential() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_FindEssential(mgr, node); + checkReturnValue(result); + return BDD(p, result); + +} // ABDD::FindEssential + + +bool +BDD::IsVarEssential( + int id, + int phase) const +{ + DdManager *mgr = p->manager; + return Cudd_bddIsVarEssential(mgr, node, id, phase); + +} // BDD::IsVarEssential + + +void +ABDD::PrintTwoLiteralClauses( + char **names, + FILE *fp) const +{ + DdManager *mgr = p->manager; + int result = Cudd_PrintTwoLiteralClauses(mgr, node, names, fp); + checkReturnValue(result); + +} // ABDD::PrintTwoLiteralClauses + + +void +Cudd::DumpBlif( + const vector& nodes, + char ** inames, + char ** onames, + char * mname, + FILE * fp, + int mv) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpBlif(mgr, n, F, inames, onames, mname, fp, mv); + delete [] F; + checkReturnValue(result); + +} // vector::DumpBlif + + +void +Cudd::DumpDot( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpDot(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpDot + + +void +Cudd::DumpDot( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpDot(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpDot + + +void +Cudd::DumpDaVinci( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpDaVinci(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpDaVinci + + +void +Cudd::DumpDaVinci( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpDaVinci(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpDaVinci + + +void +Cudd::DumpDDcal( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpDDcal(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpDDcal + + +void +Cudd::DumpFactoredForm( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i ++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_DumpFactoredForm(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpFactoredForm + + +BDD +BDD::Constrain( + const BDD& c) const +{ + DdManager *mgr = checkSameManager(c); + DdNode *result = Cudd_bddConstrain(mgr, node, c.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Constrain + + +BDD +BDD::Restrict( + const BDD& c) const +{ + DdManager *mgr = checkSameManager(c); + DdNode *result = Cudd_bddRestrict(mgr, node, c.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Restrict + + +BDD +BDD::NPAnd( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddNPAnd(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::NPAnd + + +ADD +ADD::Constrain( + const ADD& c) const +{ + DdManager *mgr = checkSameManager(c); + DdNode *result = Cudd_addConstrain(mgr, node, c.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Constrain + + +vector +BDD::ConstrainDecomp() const +{ + DdManager *mgr = p->manager; + DdNode **result = Cudd_bddConstrainDecomp(mgr, node); + checkReturnValue((DdNode *)result); + int size = Cudd_ReadSize(mgr); + vector vect; + for (int i = 0; i < size; i++) { + Cudd_Deref(result[i]); + vect.push_back(BDD(p, result[i])); + } + free(result); + return vect; + +} // BDD::ConstrainDecomp + + +ADD +ADD::Restrict( + const ADD& c) const +{ + DdManager *mgr = checkSameManager(c); + DdNode *result = Cudd_addRestrict(mgr, node, c.node); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Restrict + + +vector +BDD::CharToVect() const +{ + DdManager *mgr = p->manager; + DdNode **result = Cudd_bddCharToVect(mgr, node); + checkReturnValue((DdNode *)result); + int size = Cudd_ReadSize(mgr); + vector vect; + for (int i = 0; i < size; i++) { + Cudd_Deref(result[i]); + vect.push_back(BDD(p, result[i])); + } + free(result); + return vect; + +} // BDD::CharToVect + + +BDD +BDD::LICompaction( + const BDD& c) const +{ + DdManager *mgr = checkSameManager(c); + DdNode *result = Cudd_bddLICompaction(mgr, node, c.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::LICompaction + + +BDD +BDD::Squeeze( + const BDD& u) const +{ + DdManager *mgr = checkSameManager(u); + DdNode *result = Cudd_bddSqueeze(mgr, node, u.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Squeeze + + +BDD +BDD::Minimize( + const BDD& c) const +{ + DdManager *mgr = checkSameManager(c); + DdNode *result = Cudd_bddMinimize(mgr, node, c.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Minimize + + +BDD +BDD::SubsetCompress( + int nvars, + int threshold) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_SubsetCompress(mgr, node, nvars, threshold); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SubsetCompress + + +BDD +BDD::SupersetCompress( + int nvars, + int threshold) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_SupersetCompress(mgr, node, nvars, threshold); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SupersetCompress + + +MtrNode * +Cudd::MakeTreeNode( + unsigned int low, + unsigned int size, + unsigned int type) const +{ + return Cudd_MakeTreeNode(p->manager, low, size, type); + +} // Cudd::MakeTreeNode + + +/* This is incorrect, but we'll wait for this one. +void +Cudd::Harwell( + FILE * fp, + DdManager * dd, + ADD* E, + ADD** x, + ADD** y, + ADD** xn, + ADD** yn_, + int * nx, + int * ny, + int * m, + int * n, + int bx, + int sx, + int by, + int sy, + int pr) +{ + DdManager *mgr = p->manager; + int result = Cudd_addHarwell(fp, mgr, E, x, y, xn, yn_, nx, ny, m, n, bx, sx, by, sy, pr); + checkReturnValue(result); + +} // Cudd::Harwell +*/ + + +void +Cudd::PrintLinear() +{ + cout.flush(); + int result = Cudd_PrintLinear(p->manager); + checkReturnValue(result); + +} // Cudd::PrintLinear + + +int +Cudd::ReadLinear( + int x, + int y) +{ + return Cudd_ReadLinear(p->manager, x, y); + +} // Cudd::ReadLinear + + +BDD +BDD::LiteralSetIntersection( + const BDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_bddLiteralSetIntersection(mgr, node, g.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::LiteralSetIntersection + + +ADD +ADD::MatrixMultiply( + const ADD& B, + vector z) const +{ + int nz = z.size(); + DdManager *mgr = checkSameManager(B); + DdNode **Z = new DdNode *[nz]; + for (int i = 0; i < nz; i++) { + Z[i] = z[i].node; + } + DdNode *result = Cudd_addMatrixMultiply(mgr, node, B.node, Z, nz); + delete [] Z; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::MatrixMultiply + + +ADD +ADD::TimesPlus( + const ADD& B, + vector z) const +{ + int nz = z.size(); + DdManager *mgr = checkSameManager(B); + DdNode **Z = new DdNode *[nz]; + for (int i = 0; i < nz; i++) { + Z[i] = z[i].node; + } + DdNode *result = Cudd_addTimesPlus(mgr, node, B.node, Z, nz); + delete [] Z; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::TimesPlus + + +ADD +ADD::Triangle( + const ADD& g, + vector z) const +{ + int nz = z.size(); + DdManager *mgr = checkSameManager(g); + DdNode **Z = new DdNode *[nz]; + for (int i = 0; i < nz; i++) { + Z[i] = z[i].node; + } + DdNode *result = Cudd_addTriangle(mgr, node, g.node, Z, nz); + delete [] Z; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Triangle + + +BDD +BDD::PrioritySelect( + vector x, + vector y, + vector z, + const BDD& Pi, + DD_PRFP Pifunc) const +{ + int n = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[n]; + DdNode **Y = new DdNode *[n]; + DdNode **Z = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = x[i].node; + Y[i] = y[i].node; + Z[i] = z[i].node; + } + DdNode *result = Cudd_PrioritySelect(mgr, node, X, Y, Z, Pi.node, n, Pifunc); + delete [] X; + delete [] Y; + delete [] Z; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::PrioritySelect + + +BDD +Cudd::Xgty( + vector z, + vector x, + vector y) +{ + int N = z.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + DdNode **Z = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + Z[i] = z[i].getNode(); + } + DdNode *result = Cudd_Xgty(mgr, N, Z, X, Y); + delete [] X; + delete [] Y; + delete [] Z; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::Xgty + + +BDD +Cudd::Xeqy( + vector x, + vector y) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + } + DdNode *result = Cudd_Xeqy(mgr, N, X, Y); + delete [] X; + delete [] Y; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Xeqy + + +ADD +Cudd::Xeqy( + vector x, + vector y) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + } + DdNode *result = Cudd_addXeqy(mgr, N, X, X); + delete [] X; + delete [] Y; + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Xeqy + + +BDD +Cudd::Dxygtdxz( + vector x, + vector y, + vector z) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + DdNode **Z = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + Z[i] = z[i].getNode(); + } + DdNode *result = Cudd_Dxygtdxz(mgr, N, X, Y, Z); + delete [] X; + delete [] Y; + delete [] Z; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::Dxygtdxz + + +BDD +Cudd::Dxygtdyz( + vector x, + vector y, + vector z) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + DdNode **Z = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + Z[i] = z[i].getNode(); + } + DdNode *result = Cudd_Dxygtdyz(mgr, N, X, Y, Z); + delete [] X; + delete [] Y; + delete [] Z; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::Dxygtdyz + + +BDD +Cudd::Inequality( + int c, + vector x, + vector y) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + } + DdNode *result = Cudd_Inequality(mgr, N, c, X, Y); + delete [] X; + delete [] Y; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::Inequality + + +BDD +Cudd::Disequality( + int c, + vector x, + vector y) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + DdNode **Y = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + Y[i] = y[i].getNode(); + } + DdNode *result = Cudd_Disequality(mgr, N, c, X, Y); + delete [] X; + delete [] Y; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::Disequality + + +BDD +Cudd::Interval( + vector x, + unsigned int lowerB, + unsigned int upperB) +{ + int N = x.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[N]; + for (int i = 0; i < N; i++) { + X[i] = x[i].getNode(); + } + DdNode *result = Cudd_bddInterval(mgr, N, X, lowerB, upperB); + delete [] X; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::Interval + + +BDD +BDD::CProjection( + const BDD& Y) const +{ + DdManager *mgr = checkSameManager(Y); + DdNode *result = Cudd_CProjection(mgr, node, Y.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::CProjection + + +int +BDD::MinHammingDist( + int *minterm, + int upperBound) const +{ + DdManager *mgr = p->manager; + int result = Cudd_MinHammingDist(mgr, node, minterm, upperBound); + return result; + +} // BDD::MinHammingDist + + +ADD +Cudd::Hamming( + vector xVars, + vector yVars) +{ + int nVars = xVars.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[nVars]; + DdNode **Y = new DdNode *[nVars]; + for (int i = 0; i < nVars; i++) { + X[i] = xVars[i].getNode(); + Y[i] = yVars[i].getNode(); + } + DdNode *result = Cudd_addHamming(mgr, X, Y, nVars); + delete [] X; + delete [] Y; + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::Hamming + + +/* We'll leave these two out for the time being. +void +Cudd::Read( + FILE * fp, + ADD* E, + ADD** x, + ADD** y, + ADD** xn, + ADD** yn_, + int * nx, + int * ny, + int * m, + int * n, + int bx, + int sx, + int by, + int sy) +{ + DdManager *mgr = p->manager; + int result = Cudd_addRead(fp, mgr, E, x, y, xn, yn_, nx, ny, m, n, bx, sx, by, sy); + checkReturnValue(result); + +} // Cudd::Read + + +void +Cudd::Read( + FILE * fp, + BDD* E, + BDD** x, + BDD** y, + int * nx, + int * ny, + int * m, + int * n, + int bx, + int sx, + int by, + int sy) +{ + DdManager *mgr = p->manager; + int result = Cudd_bddRead(fp, mgr, E, x, y, nx, ny, m, n, bx, sx, by, sy); + checkReturnValue(result); + +} // Cudd::Read +*/ + + +void +Cudd::ReduceHeap( + Cudd_ReorderingType heuristic, + int minsize) +{ + int result = Cudd_ReduceHeap(p->manager, heuristic, minsize); + checkReturnValue(result); + +} // Cudd::ReduceHeap + + +void +Cudd::ShuffleHeap( + int * permutation) +{ + int result = Cudd_ShuffleHeap(p->manager, permutation); + checkReturnValue(result); + +} // Cudd::ShuffleHeap + + +ADD +ADD::Eval( + int * inputs) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_Eval(mgr, node, inputs); + checkReturnValue(result); + return ADD(p, result); + +} // ADD::Eval + + +BDD +BDD::Eval( + int * inputs) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_Eval(mgr, node, inputs); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Eval + + +BDD +ABDD::ShortestPath( + int * weight, + int * support, + int * length) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_ShortestPath(mgr, node, weight, support, length); + checkReturnValue(result); + return BDD(p, result); + +} // ABDD::ShortestPath + + +BDD +ABDD::LargestCube( + int * length) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_LargestCube(mgr, node, length); + checkReturnValue(result); + return BDD(p, result); + +} // ABDD::LargestCube + + +int +ABDD::ShortestLength( + int * weight) const +{ + DdManager *mgr = p->manager; + int result = Cudd_ShortestLength(mgr, node, weight); + checkReturnValue(result != CUDD_OUT_OF_MEM); + return result; + +} // ABDD::ShortestLength + + +BDD +BDD::Decreasing( + int i) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_Decreasing(mgr, node, i); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Decreasing + + +BDD +BDD::Increasing( + int i) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_Increasing(mgr, node, i); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Increasing + + +bool +ABDD::EquivDC( + const ABDD& G, + const ABDD& D) const +{ + DdManager *mgr = checkSameManager(G); + checkSameManager(D); + return Cudd_EquivDC(mgr, node, G.node, D.node); + +} // ABDD::EquivDC + +bool +BDD::LeqUnless( + const BDD& G, + const BDD& D) const +{ + DdManager *mgr = checkSameManager(G); + checkSameManager(D); + int res = Cudd_bddLeqUnless(mgr, node, G.node, D.node); + return res; + +} // BDD::LeqUnless + + +bool +ADD::EqualSupNorm( + const ADD& g, + CUDD_VALUE_TYPE tolerance, + int pr) const +{ + DdManager *mgr = checkSameManager(g); + return Cudd_EqualSupNorm(mgr, node, g.node, tolerance, pr); + +} // ADD::EqualSupNorm + + +BDD +BDD::MakePrime( + const BDD& F) const +{ + DdManager *mgr = checkSameManager(F); + if (!Cudd_CheckCube(mgr, node)) { + p->errorHandler("Invalid argument."); + } + DdNode *result = Cudd_bddMakePrime(mgr, node, F.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD:MakePrime + + +BDD +BDD::MaximallyExpand( + const BDD& ub, + const BDD& f) +{ + DdManager *mgr = checkSameManager(ub); + checkSameManager(f); + DdNode *result = Cudd_bddMaximallyExpand(mgr, node, ub.node, f.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::MaximallyExpand + + +BDD +BDD::LargestPrimeUnate( + const BDD& phases) +{ + DdManager *mgr = checkSameManager(phases); + DdNode *result = Cudd_bddLargestPrimeUnate(mgr, node, phases.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::LargestPrimeUnate + + +double * +ABDD::CofMinterm() const +{ + DdManager *mgr = p->manager; + double *result = Cudd_CofMinterm(mgr, node); + checkReturnValue((DdNode *)result); + return result; + +} // ABDD::CofMinterm + + +BDD +BDD::SolveEqn( + const BDD& Y, + BDD* G, + int ** yIndex, + int n) const +{ + DdManager *mgr = checkSameManager(Y); + DdNode **g = new DdNode *[n]; + DdNode *result = Cudd_SolveEqn(mgr, node, Y.node, g, yIndex, n); + checkReturnValue(result); + for (int i = 0; i < n; i++) { + G[i] = BDD(p, g[i]); + Cudd_RecursiveDeref(mgr,g[i]); + } + delete [] g; + return BDD(p, result); + +} // BDD::SolveEqn + + +BDD +BDD::VerifySol( + BDD* G, + int * yIndex, + int n) const +{ + DdManager *mgr = p->manager; + DdNode **g = new DdNode *[n]; + for (int i = 0; i < n; i++) { + g[i] = G[i].node; + } + DdNode *result = Cudd_VerifySol(mgr, node, g, yIndex, n); + delete [] g; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::VerifySol + + +BDD +BDD::SplitSet( + vector xVars, + double m) const +{ + int n = xVars.size(); + DdManager *mgr = p->manager; + DdNode **X = new DdNode *[n]; + for (int i = 0; i < n; i++) { + X[i] = xVars[i].node; + } + DdNode *result = Cudd_SplitSet(mgr, node, X, n, m); + delete [] X; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SplitSet + + +BDD +BDD::SubsetHeavyBranch( + int numVars, + int threshold) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_SubsetHeavyBranch(mgr, node, numVars, threshold); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SubsetHeavyBranch + + +BDD +BDD::SupersetHeavyBranch( + int numVars, + int threshold) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_SupersetHeavyBranch(mgr, node, numVars, threshold); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SupersetHeavyBranch + + +BDD +BDD::SubsetShortPaths( + int numVars, + int threshold, + bool hardlimit) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_SubsetShortPaths(mgr, node, numVars, threshold, hardlimit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SubsetShortPaths + + +BDD +BDD::SupersetShortPaths( + int numVars, + int threshold, + bool hardlimit) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_SupersetShortPaths(mgr, node, numVars, threshold, hardlimit); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::SupersetShortPaths + + +void +Cudd::SymmProfile( + int lower, + int upper) const +{ + Cudd_SymmProfile(p->manager, lower, upper); + +} // Cudd::SymmProfile + + +unsigned int +Cudd::Prime( + unsigned int pr) const +{ + return Cudd_Prime(pr); + +} // Cudd::Prime + + +void +Cudd::Reserve( + int amount) const +{ + int result = Cudd_Reserve(p->manager, amount); + checkReturnValue(result); + +} // Cudd::Reserve + + +void +ABDD::PrintMinterm() const +{ + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_PrintMinterm(mgr, node); + checkReturnValue(result); + +} // ABDD::PrintMinterm + + +void +BDD::PrintCover() const +{ + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_bddPrintCover(mgr, node, node); + checkReturnValue(result); + +} // BDD::PrintCover + + +void +BDD::PrintCover( + const BDD& u) const +{ + checkSameManager(u); + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_bddPrintCover(mgr, node, u.node); + checkReturnValue(result); + +} // BDD::PrintCover + + +int +BDD::EstimateCofactor( + int i, + int phase) const +{ + DdManager *mgr = p->manager; + int result = Cudd_EstimateCofactor(mgr, node, i, phase); + checkReturnValue(result != CUDD_OUT_OF_MEM); + return result; + +} // BDD::EstimateCofactor + + +int +BDD::EstimateCofactorSimple( + int i) const +{ + int result = Cudd_EstimateCofactorSimple(node, i); + return result; + +} // BDD::EstimateCofactorSimple + + +int +Cudd::SharingSize( + DD* nodes, + int n) const +{ + DdNode **nodeArray = new DdNode *[n]; + for (int i = 0; i < n; i++) { + nodeArray[i] = nodes[i].getNode(); + } + int result = Cudd_SharingSize(nodeArray, n); + delete [] nodeArray; + checkReturnValue(n == 0 || result > 0); + return result; + +} // Cudd::SharingSize + + +int +Cudd::SharingSize( + const vector& v) const +{ + vector::size_type n = v.size(); + DdNode **nodeArray = new DdNode *[n]; + for (vector::size_type i = 0; i != n; ++i) { + nodeArray[i] = v[i].getNode(); + } + int result = Cudd_SharingSize(nodeArray, n); + delete [] nodeArray; + checkReturnValue(n == 0 || result > 0); + return result; + +} // Cudd::SharingSize + + +double +ABDD::CountMinterm( + int nvars) const +{ + DdManager *mgr = p->manager; + double result = Cudd_CountMinterm(mgr, node, nvars); + checkReturnValue(result != (double) CUDD_OUT_OF_MEM); + return result; + +} // ABDD::CountMinterm + + +double +ABDD::CountPath() const +{ + double result = Cudd_CountPath(node); + checkReturnValue(result != (double) CUDD_OUT_OF_MEM); + return result; + +} // ABDD::CountPath + + +BDD +ABDD::Support() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_Support(mgr, node); + checkReturnValue(result); + return BDD(p, result); + +} // ABDD::Support + + +int +ABDD::SupportSize() const +{ + DdManager *mgr = p->manager; + int result = Cudd_SupportSize(mgr, node); + checkReturnValue(result != CUDD_OUT_OF_MEM); + return result; + +} // ABDD::SupportSize + + +BDD +Cudd::VectorSupport(const vector& roots) const +{ + int n = roots.size(); + DdManager *mgr = p->manager; + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i++) { + F[i] = roots[i].getNode(); + } + DdNode *result = Cudd_VectorSupport(mgr, F, n); + delete [] F; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::VectorSupport + + +vector +ABDD::SupportIndices() const +{ + unsigned int *support; + DdManager *mgr = p->manager; + int size = Cudd_SupportIndices(mgr, node, (int **)&support); + checkReturnValue(size >= 0); + // size could be 0, in which case support is 0 too! + vector indices(support, support+size); + if (support) free(support); + return indices; + +} // ABDD::SupportIndices + + +vector +Cudd::SupportIndices(const vector& roots) const +{ + unsigned int *support; + int n = roots.size(); + DdManager *mgr = p->manager; + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i++) { + F[i] = roots[i].getNode(); + } + int size = Cudd_VectorSupportIndices(mgr, F, n, (int **)&support); + delete [] F; + checkReturnValue(size >= 0); + // size could be 0, in which case support is 0 too! + vector indices(support, support+size); + if (support) free(support); + return indices; + +} // Cudd::SupportIndices + + +int +Cudd::nodeCount(const vector& roots) const +{ + int n = roots.size(); + DdNode **nodeArray = new DdNode *[n]; + for (int i = 0; i < n; i++) { + nodeArray[i] = roots[i].getNode(); + } + int result = Cudd_SharingSize(nodeArray, n); + delete [] nodeArray; + checkReturnValue(result > 0); + return result; + +} // vector::nodeCount + + +BDD +Cudd::VectorSupport(const vector& roots) const +{ + int n = roots.size(); + DdManager *mgr = p->manager; + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i++) { + F[i] = roots[i].getNode(); + } + DdNode *result = Cudd_VectorSupport(mgr, F, n); + delete [] F; + checkReturnValue(result); + return BDD(p, result); + +} // vector::VectorSupport + + +int +Cudd::VectorSupportSize(const vector& roots) const +{ + int n = roots.size(); + DdManager *mgr = p->manager; + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i++) { + F[i] = roots[i].getNode(); + } + int result = Cudd_VectorSupportSize(mgr, F, n); + delete [] F; + checkReturnValue(result != CUDD_OUT_OF_MEM); + return result; + +} // vector::VectorSupportSize + + +int +Cudd::VectorSupportSize(const vector& roots) const +{ + int n = roots.size(); + DdManager *mgr = p->manager; + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i++) { + F[i] = roots[i].getNode(); + } + int result = Cudd_VectorSupportSize(mgr, F, n); + delete [] F; + checkReturnValue(result != CUDD_OUT_OF_MEM); + return result; + +} // vector::VectorSupportSize + + +void +ABDD::ClassifySupport( + const ABDD& g, + BDD* common, + BDD* onlyF, + BDD* onlyG) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *C, *F, *G; + int result = Cudd_ClassifySupport(mgr, node, g.node, &C, &F, &G); + checkReturnValue(result); + *common = BDD(p, C); + *onlyF = BDD(p, F); + *onlyG = BDD(p, G); + +} // ABDD::ClassifySupport + + +int +ABDD::CountLeaves() const +{ + return Cudd_CountLeaves(node); + +} // ABDD::CountLeaves + + +void +BDD::PickOneCube( + char * string) const +{ + DdManager *mgr = p->manager; + int result = Cudd_bddPickOneCube(mgr, node, string); + checkReturnValue(result); + +} // BDD::PickOneCube + + +BDD +BDD::PickOneMinterm( + vector vars) const +{ + int n = vars.size(); + DdManager *mgr = p->manager; + DdNode **V = new DdNode *[n]; + for (int i = 0; i < n; i++) { + V[i] = vars[i].node; + } + DdNode *result = Cudd_bddPickOneMinterm(mgr, node, V, n); + delete [] V; + checkReturnValue(result); + return BDD(p, result); + +} // BDD::PickOneMinterm + + +DdGen * +ABDD::FirstCube( + int ** cube, + CUDD_VALUE_TYPE * value) const +{ + DdManager *mgr = p->manager; + DdGen *result = Cudd_FirstCube(mgr, node, cube, value); + checkReturnValue((DdNode *)result); + return result; + +} // ABDD::FirstCube + + +int +NextCube( + DdGen * gen, + int ** cube, + CUDD_VALUE_TYPE * value) +{ + return Cudd_NextCube(gen, cube, value); + +} // NextCube + + +BDD +Cudd::bddComputeCube( + BDD * vars, + int * phase, + int n) const +{ + DdManager *mgr = p->manager; + DdNode **V = new DdNode *[n]; + for (int i = 0; i < n; i++) { + V[i] = vars[i].getNode(); + } + DdNode *result = Cudd_bddComputeCube(mgr, V, phase, n); + delete [] V; + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::bddComputeCube + + +ADD +Cudd::addComputeCube( + ADD * vars, + int * phase, + int n) +{ + DdManager *mgr = p->manager; + DdNode **V = new DdNode *[n]; + for (int i = 0; i < n; i++) { + V[i] = vars[i].getNode(); + } + DdNode *result = Cudd_addComputeCube(mgr, V, phase, n); + delete [] V; + checkReturnValue(result); + return ADD(p, result); + +} // Cudd::addComputeCube + + +DdGen * +BDD::FirstNode( + BDD* fnode) const +{ + DdManager *mgr = p->manager; + DdNode *Fn; + DdGen *result = Cudd_FirstNode(mgr, node, &Fn); + checkReturnValue((DdNode *)result); + *fnode = BDD(p, Fn); + return result; + +} // DD::FirstNode + + +int +Cudd::NextNode( + DdGen * gen, + BDD * nnode) +{ + DdNode *nn; + int result = Cudd_NextNode(gen, &nn); + *nnode = BDD(p, nn); + return result; + +} // Cudd::NextNode + + +int +GenFree( + DdGen * gen) +{ + return Cudd_GenFree(gen); + +} // GenFree + + +int +IsGenEmpty( + DdGen * gen) +{ + return Cudd_IsGenEmpty(gen); + +} // IsGenEmpty + + +BDD +Cudd::IndicesToCube( + int * array, + int n) +{ + DdNode *result = Cudd_IndicesToCube(p->manager, array, n); + checkReturnValue(result); + return BDD(p, result); + +} // Cudd::IndicesToCube + + +void +Cudd::PrintVersion( + FILE * fp) const +{ + cout.flush(); + Cudd_PrintVersion(fp); + +} // Cudd::PrintVersion + + +double +Cudd::AverageDistance() const +{ + return Cudd_AverageDistance(p->manager); + +} // Cudd::AverageDistance + + +long +Cudd::Random() const +{ + return Cudd_Random(); + +} // Cudd::Random + + +void +Cudd::Srandom( + long seed) const +{ + Cudd_Srandom(seed); + +} // Cudd::Srandom + + +double +ABDD::Density( + int nvars) const +{ + DdManager *mgr = p->manager; + double result = Cudd_Density(mgr, node, nvars); + checkReturnValue(result != (double) CUDD_OUT_OF_MEM); + return result; + +} // ABDD::Density + + +int +ZDD::Count() const +{ + DdManager *mgr = p->manager; + int result = Cudd_zddCount(mgr, node); + checkReturnValue(result != CUDD_OUT_OF_MEM); + return result; + +} // ZDD::Count + + +double +ZDD::CountDouble() const +{ + DdManager *mgr = p->manager; + double result = Cudd_zddCountDouble(mgr, node); + checkReturnValue(result != (double) CUDD_OUT_OF_MEM); + return result; + +} // ZDD::CountDouble + + +ZDD +ZDD::Product( + const ZDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_zddProduct(mgr, node, g.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Product + + +ZDD +ZDD::UnateProduct( + const ZDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_zddUnateProduct(mgr, node, g.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::UnateProduct + + +ZDD +ZDD::WeakDiv( + const ZDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_zddWeakDiv(mgr, node, g.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::WeakDiv + + +ZDD +ZDD::Divide( + const ZDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_zddDivide(mgr, node, g.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Divide + + +ZDD +ZDD::WeakDivF( + const ZDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_zddWeakDivF(mgr, node, g.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::WeakDivF + + +ZDD +ZDD::DivideF( + const ZDD& g) const +{ + DdManager *mgr = checkSameManager(g); + DdNode *result = Cudd_zddDivideF(mgr, node, g.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::DivideF + + +MtrNode * +Cudd::MakeZddTreeNode( + unsigned int low, + unsigned int size, + unsigned int type) +{ + return Cudd_MakeZddTreeNode(p->manager, low, size, type); + +} // Cudd::MakeZddTreeNode + + +BDD +BDD::zddIsop( + const BDD& U, + ZDD* zdd_I) const +{ + DdManager *mgr = checkSameManager(U); + DdNode *Z; + DdNode *result = Cudd_zddIsop(mgr, node, U.node, &Z); + checkReturnValue(result); + *zdd_I = ZDD(p, Z); + return BDD(p, result); + +} // BDD::Isop + + +BDD +BDD::Isop( + const BDD& U) const +{ + DdManager *mgr = checkSameManager(U); + DdNode *result = Cudd_bddIsop(mgr, node, U.node); + checkReturnValue(result); + return BDD(p, result); + +} // BDD::Isop + + +double +ZDD::CountMinterm( + int path) const +{ + DdManager *mgr = p->manager; + double result = Cudd_zddCountMinterm(mgr, node, path); + checkReturnValue(result != (double) CUDD_OUT_OF_MEM); + return result; + +} // ZDD::CountMinterm + + +void +Cudd::zddPrintSubtable() const +{ + cout.flush(); + Cudd_zddPrintSubtable(p->manager); + +} // Cudd::zddPrintSubtable + + +ZDD +BDD::PortToZdd() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_zddPortFromBdd(mgr, node); + checkReturnValue(result); + return ZDD(p, result); + +} // BDD::PortToZdd + + +BDD +ZDD::PortToBdd() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_zddPortToBdd(mgr, node); + checkReturnValue(result); + return BDD(p, result); + +} // ZDD::PortToBdd + + +void +Cudd::zddReduceHeap( + Cudd_ReorderingType heuristic, + int minsize) +{ + int result = Cudd_zddReduceHeap(p->manager, heuristic, minsize); + checkReturnValue(result); + +} // Cudd::zddReduceHeap + + +void +Cudd::zddShuffleHeap( + int * permutation) +{ + int result = Cudd_zddShuffleHeap(p->manager, permutation); + checkReturnValue(result); + +} // Cudd::zddShuffleHeap + + +ZDD +ZDD::Ite( + const ZDD& g, + const ZDD& h) const +{ + DdManager *mgr = checkSameManager(g); + checkSameManager(h); + DdNode *result = Cudd_zddIte(mgr, node, g.node, h.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Ite + + +ZDD +ZDD::Union( + const ZDD& Q) const +{ + DdManager *mgr = checkSameManager(Q); + DdNode *result = Cudd_zddUnion(mgr, node, Q.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Union + + +ZDD +ZDD::Intersect( + const ZDD& Q) const +{ + DdManager *mgr = checkSameManager(Q); + DdNode *result = Cudd_zddIntersect(mgr, node, Q.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Intersect + + +ZDD +ZDD::Diff( + const ZDD& Q) const +{ + DdManager *mgr = checkSameManager(Q); + DdNode *result = Cudd_zddDiff(mgr, node, Q.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Diff + + +ZDD +ZDD::DiffConst( + const ZDD& Q) const +{ + DdManager *mgr = checkSameManager(Q); + DdNode *result = Cudd_zddDiffConst(mgr, node, Q.node); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::DiffConst + + +ZDD +ZDD::Subset1( + int var) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_zddSubset1(mgr, node, var); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Subset1 + + +ZDD +ZDD::Subset0( + int var) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_zddSubset0(mgr, node, var); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Subset0 + + +ZDD +ZDD::Change( + int var) const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_zddChange(mgr, node, var); + checkReturnValue(result); + return ZDD(p, result); + +} // ZDD::Change + + +void +Cudd::zddSymmProfile( + int lower, + int upper) const +{ + Cudd_zddSymmProfile(p->manager, lower, upper); + +} // Cudd::zddSymmProfile + + +void +ZDD::PrintMinterm() const +{ + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_zddPrintMinterm(mgr, node); + checkReturnValue(result); + +} // ZDD::PrintMinterm + + +void +ZDD::PrintCover() const +{ + cout.flush(); + DdManager *mgr = p->manager; + int result = Cudd_zddPrintCover(mgr, node); + checkReturnValue(result); + +} // ZDD::PrintCover + + +BDD +ZDD::Support() const +{ + DdManager *mgr = p->manager; + DdNode *result = Cudd_zddSupport(mgr, node); + checkReturnValue(result); + return BDD(p, result); + +} // ZDD::Support + + +void +Cudd::DumpDot( + const vector& nodes, + char ** inames, + char ** onames, + FILE * fp) const +{ + DdManager *mgr = p->manager; + int n = nodes.size(); + DdNode **F = new DdNode *[n]; + for (int i = 0; i < n; i++) { + F[i] = nodes[i].getNode(); + } + int result = Cudd_zddDumpDot(mgr, n, F, inames, onames, fp); + delete [] F; + checkReturnValue(result); + +} // vector::DumpDot diff --git a/resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh b/resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh new file mode 100644 index 000000000..726476448 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/obj/cuddObj.hh @@ -0,0 +1,768 @@ +/**CHeaderFile*************************************************************** + + FileName [cuddObj.hh] + + PackageName [cudd] + + Synopsis [Class definitions for C++ object-oriented encapsulation of + CUDD.] + + Description [Class definitions for C++ object-oriented encapsulation of + CUDD.] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: cuddObj.hh,v 1.13 2012/02/05 01:06:40 fabio Exp fabio $] + +******************************************************************************/ + +#ifndef _CPPCUDD +#define _CPPCUDD + +#if defined (__GNUC__) +#if (__GNUC__ >2 || __GNUC_MINOR__ >=7) && !defined(UNUSED) +#define UNUSED __attribute__ ((unused)) +#else +#define UNUSED +#endif +#else +#define UNUSED +#endif + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include +#include +#include +#include "cudd.h" + +/*---------------------------------------------------------------------------*/ +/* Type definitions */ +/*---------------------------------------------------------------------------*/ +class BDD; +class ADD; +class ZDD; +class Cudd; + +typedef void (*PFC)(std::string); // handler function type + +/*---------------------------------------------------------------------------*/ +/* Class definitions */ +/*---------------------------------------------------------------------------*/ + +/**Class*********************************************************************** + + Synopsis [Class for reference counting of CUDD managers.] + + Description [] + + SeeAlso [Cudd DD ABDD ADD BDD ZDD] + +******************************************************************************/ +class Capsule { + friend class DD; + friend class ABDD; + friend class BDD; + friend class ADD; + friend class ZDD; + friend class Cudd; +private: + DdManager *manager; + PFC errorHandler; + PFC timeoutHandler; + bool verbose; + int ref; +}; + + +/**Class*********************************************************************** + + Synopsis [Base class for all decision diagrams in CUDD.] + + Description [] + + SeeAlso [Cudd ABDD ADD BDD ZDD] + +******************************************************************************/ +class DD { + friend class ABDD; + friend class BDD; + friend class ADD; + friend class ZDD; +private: + Capsule *p; + DdNode *node; + inline DdManager * checkSameManager(const DD &other) const; + inline void checkReturnValue(const DdNode *result) const; + inline void checkReturnValue(const int result, const int expected = 1) + const; +public: + DD(); + DD(Capsule *cap, DdNode *ddNode); + DD(Cudd const & manager, DdNode *ddNode); + DD(const DD &from); + virtual ~DD(); + operator bool() const { return node; } + DdManager *manager() const; + DdNode * getNode() const; + DdNode * getRegularNode() const; + int nodeCount() const; + unsigned int NodeReadIndex() const; + +}; // DD + + +/**Class*********************************************************************** + + Synopsis [Class for ADDs and BDDs.] + + Description [] + + SeeAlso [Cudd ADD BDD] + +******************************************************************************/ +class ABDD : public DD { + friend class BDD; + friend class ADD; + friend class Cudd; +public: + ABDD(); + ABDD(Capsule *cap, DdNode *bddNode); + ABDD(Cudd const & manager, DdNode *ddNode); + ABDD(const ABDD &from); + virtual ~ABDD(); + bool operator==(const ABDD &other) const; + bool operator!=(const ABDD &other) const; + void print(int nvars, int verbosity = 1) const; + DdApaNumber ApaCountMinterm(int nvars, int * digits) const; + void ApaPrintMinterm(int nvars, FILE * fp = stdout) const; + void EpdPrintMinterm(int nvars, FILE * fp = stdout) const; + bool IsOne() const; + bool IsCube() const; + BDD FindEssential() const; + void PrintTwoLiteralClauses(char ** names, FILE * fp = stdout) const; + BDD ShortestPath(int * weight, int * support, int * length) const; + BDD LargestCube(int * length = 0) const; + int ShortestLength(int * weight) const; + bool EquivDC(const ABDD& G, const ABDD& D) const; + double * CofMinterm() const; + void PrintMinterm() const; + double CountMinterm(int nvars) const; + double CountPath() const; + BDD Support() const; + int SupportSize() const; + std::vector SupportIndices() const; + void ClassifySupport(const ABDD& g, BDD* common, BDD* onlyF, BDD* onlyG) + const; + int CountLeaves() const; + DdGen * FirstCube(int ** cube, CUDD_VALUE_TYPE * value) const; + double Density(int nvars) const; + +}; // ABDD + + +/**Class*********************************************************************** + + Synopsis [Class for BDDs.] + + Description [] + + SeeAlso [Cudd] + +******************************************************************************/ +class BDD : public ABDD { + friend class Cudd; +public: + BDD(); + BDD(Capsule *cap, DdNode *bddNode); + BDD(Cudd const & manager, DdNode *ddNode); + BDD(const BDD &from); + BDD operator=(const BDD& right); + bool operator<=(const BDD& other) const; + bool operator>=(const BDD& other) const; + bool operator<(const BDD& other) const; + bool operator>(const BDD& other) const; + BDD operator!() const; + BDD operator~() const; + BDD operator*(const BDD& other) const; + BDD operator*=(const BDD& other); + BDD operator&(const BDD& other) const; + BDD operator&=(const BDD& other); + BDD operator+(const BDD& other) const; + BDD operator+=(const BDD& other); + BDD operator|(const BDD& other) const; + BDD operator|=(const BDD& other); + BDD operator^(const BDD& other) const; + BDD operator^=(const BDD& other); + BDD operator-(const BDD& other) const; + BDD operator-=(const BDD& other); + bool IsZero() const; + BDD AndAbstract(const BDD& g, const BDD& cube, unsigned int limit = 0) + const; + BDD UnderApprox( + int numVars, + int threshold = 0, + bool safe = false, + double quality = 1.0) const; + BDD OverApprox( + int numVars, + int threshold = 0, + bool safe = false, + double quality = 1.0) const; + BDD RemapUnderApprox(int numVars, int threshold = 0, double quality = 1.0) + const; + BDD RemapOverApprox(int numVars, int threshold = 0, double quality = 1.0) + const; + BDD BiasedUnderApprox(const BDD& bias, int numVars, int threshold = 0, + double quality1 = 1.0, double quality0 = 1.0) const; + BDD BiasedOverApprox(const BDD& bias, int numVars, int threshold = 0, + double quality1 = 1.0, double quality0 = 1.0) const; + BDD ExistAbstract(const BDD& cube, unsigned int limit = 0) const; + BDD XorExistAbstract(const BDD& g, const BDD& cube) const; + BDD UnivAbstract(const BDD& cube) const; + BDD BooleanDiff(int x) const; + bool VarIsDependent(const BDD& var) const; + double Correlation(const BDD& g) const; + double CorrelationWeights(const BDD& g, double * prob) const; + BDD Ite(const BDD& g, const BDD& h, unsigned int limit = 0) const; + BDD IteConstant(const BDD& g, const BDD& h) const; + BDD Intersect(const BDD& g) const; + BDD And(const BDD& g, unsigned int limit = 0) const; + BDD Or(const BDD& g, unsigned int limit = 0) const; + BDD Nand(const BDD& g) const; + BDD Nor(const BDD& g) const; + BDD Xor(const BDD& g) const; + BDD Xnor(const BDD& g, unsigned int limit = 0) const; + bool Leq(const BDD& g) const; + ADD Add() const; + BDD Transfer(Cudd& destination) const; + BDD ClippingAnd(const BDD& g, int maxDepth, int direction) const; + BDD ClippingAndAbstract(const BDD& g, const BDD& cube, int maxDepth, + int direction) const; + BDD Cofactor(const BDD& g) const; + BDD Compose(const BDD& g, int v) const; + BDD Permute(int * permut) const; + BDD SwapVariables(std::vector x, std::vector y) const; + BDD AdjPermuteX(std::vector x) const; + BDD VectorCompose(std::vector vector) const; + void ApproxConjDecomp(BDD* g, BDD* h) const; + void ApproxDisjDecomp(BDD* g, BDD* h) const; + void IterConjDecomp(BDD* g, BDD* h) const; + void IterDisjDecomp(BDD* g, BDD* h) const; + void GenConjDecomp(BDD* g, BDD* h) const; + void GenDisjDecomp(BDD* g, BDD* h) const; + void VarConjDecomp(BDD* g, BDD* h) const; + void VarDisjDecomp(BDD* g, BDD* h) const; + bool IsVarEssential(int id, int phase) const; + BDD Constrain(const BDD& c) const; + BDD Restrict(const BDD& c) const; + BDD NPAnd(const BDD& g) const; + std::vector ConstrainDecomp() const; + std::vector CharToVect() const; + BDD LICompaction(const BDD& c) const; + BDD Squeeze(const BDD& u) const; + BDD Minimize(const BDD& c) const; + BDD SubsetCompress(int nvars, int threshold) const; + BDD SupersetCompress(int nvars, int threshold) const; + BDD LiteralSetIntersection(const BDD& g) const; + BDD PrioritySelect(std::vector x, std::vector y, + std::vector z, const BDD& Pi, DD_PRFP Pifunc) const; + BDD CProjection(const BDD& Y) const; + int MinHammingDist(int *minterm, int upperBound) const; + BDD Eval(int * inputs) const; + BDD Decreasing(int i) const; + BDD Increasing(int i) const; + bool LeqUnless(const BDD& G, const BDD& D) const; + BDD MakePrime(const BDD& F) const; + BDD MaximallyExpand(const BDD& ub, const BDD& f); + BDD LargestPrimeUnate(const BDD& phases); + BDD SolveEqn(const BDD& Y, BDD* G, int ** yIndex, int n) const; + BDD VerifySol(BDD* G, int * yIndex, int n) const; + BDD SplitSet(std::vector xVars, double m) const; + BDD SubsetHeavyBranch(int numVars, int threshold) const; + BDD SupersetHeavyBranch(int numVars, int threshold) const; + BDD SubsetShortPaths(int numVars, int threshold, bool hardlimit = false) const; + BDD SupersetShortPaths(int numVars, int threshold, bool hardlimit = false) const; + void PrintCover() const; + void PrintCover(const BDD& u) const; + int EstimateCofactor(int i, int phase) const; + int EstimateCofactorSimple(int i) const; + void PickOneCube(char * string) const; + BDD PickOneMinterm(std::vector vars) const; + DdGen * FirstNode(BDD* fnode) const; + BDD zddIsop(const BDD& U, ZDD* zdd_I) const; + BDD Isop(const BDD& U) const; + ZDD PortToZdd() const; + +}; // BDD + + +/**Class*********************************************************************** + + Synopsis [Class for ADDs.] + + Description [] + + SeeAlso [Cudd] + +******************************************************************************/ +class ADD : public ABDD { + friend class Cudd; +public: + ADD(); + ADD(Capsule *cap, DdNode *bddNode); + ADD(Cudd const & manager, DdNode *ddNode); + ADD(const ADD &from); + ADD operator=(const ADD& right); + // Relational operators + bool operator<=(const ADD& other) const; + bool operator>=(const ADD& other) const; + bool operator<(const ADD& other) const; + bool operator>(const ADD& other) const; + // Arithmetic operators + ADD operator-() const; + ADD operator*(const ADD& other) const; + ADD operator*=(const ADD& other); + ADD operator+(const ADD& other) const; + ADD operator+=(const ADD& other); + ADD operator-(const ADD& other) const; + ADD operator-=(const ADD& other); + // Logical operators + ADD operator~() const; + ADD operator&(const ADD& other) const; + ADD operator&=(const ADD& other); + ADD operator|(const ADD& other) const; + ADD operator|=(const ADD& other); + bool IsZero() const; + ADD ExistAbstract(const ADD& cube) const; + ADD UnivAbstract(const ADD& cube) const; + ADD OrAbstract(const ADD& cube) const; + ADD Plus(const ADD& g) const; + ADD Times(const ADD& g) const; + ADD Threshold(const ADD& g) const; + ADD SetNZ(const ADD& g) const; + ADD Divide(const ADD& g) const; + ADD Minus(const ADD& g) const; + ADD Minimum(const ADD& g) const; + ADD Maximum(const ADD& g) const; + ADD OneZeroMaximum(const ADD& g) const; + ADD Diff(const ADD& g) const; + ADD Agreement(const ADD& g) const; + ADD Or(const ADD& g) const; + ADD Nand(const ADD& g) const; + ADD Nor(const ADD& g) const; + ADD Xor(const ADD& g) const; + ADD Xnor(const ADD& g) const; + ADD Log() const; + ADD FindMax() const; + ADD FindMin() const; + ADD IthBit(int bit) const; + ADD ScalarInverse(const ADD& epsilon) const; + ADD Ite(const ADD& g, const ADD& h) const; + ADD IteConstant(const ADD& g, const ADD& h) const; + ADD EvalConst(const ADD& g) const; + bool Leq(const ADD& g) const; + ADD Cmpl() const; + ADD Negate() const; + ADD RoundOff(int N) const; + ADD Equals(const ADD& g) const; + ADD NotEquals(const ADD& g) const; + ADD LessThan(const ADD& g) const; + ADD LessThanOrEqual(const ADD& g) const; + ADD GreaterThan(const ADD& g) const; + ADD GreaterThanOrEqual(const ADD& g) const; + BDD BddThreshold(CUDD_VALUE_TYPE value) const; + BDD BddStrictThreshold(CUDD_VALUE_TYPE value) const; + BDD BddInterval(CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper) const; + BDD BddIthBit(int bit) const; + BDD BddPattern() const; + ADD Cofactor(const ADD& g) const; + ADD Compose(const ADD& g, int v) const; + ADD Permute(int * permut) const; + ADD SwapVariables(std::vector x, std::vector y) const; + ADD VectorCompose(std::vector vector) const; + ADD NonSimCompose(std::vector vector) const; + ADD Constrain(const ADD& c) const; + ADD Restrict(const ADD& c) const; + ADD MatrixMultiply(const ADD& B, std::vector z) const; + ADD TimesPlus(const ADD& B, std::vector z) const; + ADD Triangle(const ADD& g, std::vector z) const; + ADD Eval(int * inputs) const; + bool EqualSupNorm(const ADD& g, CUDD_VALUE_TYPE tolerance, int pr) const; + +}; // ADD + + +/**Class*********************************************************************** + + Synopsis [Class for ZDDs.] + + Description [] + + SeeAlso [Cudd] + +******************************************************************************/ +class ZDD : public DD { + friend class Cudd; +public: + ZDD(Capsule *cap, DdNode *bddNode); + ZDD(); + ZDD(const ZDD &from); + ~ZDD(); + ZDD operator=(const ZDD& right); + bool operator==(const ZDD& other) const; + bool operator!=(const ZDD& other) const; + bool operator<=(const ZDD& other) const; + bool operator>=(const ZDD& other) const; + bool operator<(const ZDD& other) const; + bool operator>(const ZDD& other) const; + void print(int nvars, int verbosity = 1) const; + ZDD operator*(const ZDD& other) const; + ZDD operator*=(const ZDD& other); + ZDD operator&(const ZDD& other) const; + ZDD operator&=(const ZDD& other); + ZDD operator+(const ZDD& other) const; + ZDD operator+=(const ZDD& other); + ZDD operator|(const ZDD& other) const; + ZDD operator|=(const ZDD& other); + ZDD operator-(const ZDD& other) const; + ZDD operator-=(const ZDD& other); + int Count() const; + double CountDouble() const; + ZDD Product(const ZDD& g) const; + ZDD UnateProduct(const ZDD& g) const; + ZDD WeakDiv(const ZDD& g) const; + ZDD Divide(const ZDD& g) const; + ZDD WeakDivF(const ZDD& g) const; + ZDD DivideF(const ZDD& g) const; + double CountMinterm(int path) const; + BDD PortToBdd() const; + ZDD Ite(const ZDD& g, const ZDD& h) const; + ZDD Union(const ZDD& Q) const; + ZDD Intersect(const ZDD& Q) const; + ZDD Diff(const ZDD& Q) const; + ZDD DiffConst(const ZDD& Q) const; + ZDD Subset1(int var) const; + ZDD Subset0(int var) const; + ZDD Change(int var) const; + void PrintMinterm() const; + void PrintCover() const; + BDD Support() const; + +}; // ZDD + + +/**Class*********************************************************************** + + Synopsis [Class for CUDD managers.] + + Description [] + + SeeAlso [DD] + +******************************************************************************/ +class Cudd { + friend class DD; + friend class ABDD; + friend class BDD; + friend class ADD; + friend class ZDD; +private: + Capsule *p; +public: + Cudd( + unsigned int numVars = 0, + unsigned int numVarsZ = 0, + unsigned int numSlots = CUDD_UNIQUE_SLOTS, + unsigned int cacheSize = CUDD_CACHE_SLOTS, + unsigned long maxMemory = 0); + Cudd(const Cudd& x); + ~Cudd(); + PFC setHandler(PFC newHandler) const; + PFC getHandler() const; + PFC setTimeoutHandler(PFC newHandler) const; + PFC getTimeoutHandler() const; + DdManager *getManager() const {return p->manager;} + inline void makeVerbose() const {p->verbose = 1;} + inline void makeTerse() {p->verbose = 0;} + inline bool isVerbose() const {return p->verbose;} + inline void checkReturnValue(const DdNode *result) const; + inline void checkReturnValue(const int result) const; + Cudd& operator=(const Cudd& right); + void info() const; + BDD bddVar() const; + BDD bddVar(int index) const; + BDD bddOne() const; + BDD bddZero() const; + ADD addVar() const; + ADD addVar(int index) const; + ADD addOne() const; + ADD addZero() const; + ADD constant(CUDD_VALUE_TYPE c) const; + ADD plusInfinity() const; + ADD minusInfinity() const; + ZDD zddVar(int index) const; + ZDD zddOne(int i) const; + ZDD zddZero() const; + ADD addNewVarAtLevel(int level) const; + BDD bddNewVarAtLevel(int level) const; + void zddVarsFromBddVars(int multiplicity) const; + unsigned long ReadStartTime() const; + unsigned long ReadElapsedTime() const; + void SetStartTime(unsigned long st) const; + void ResetStartTime() const; + unsigned long ReadTimeLimit() const; + void SetTimeLimit(unsigned long tl) const; + void UpdateTimeLimit() const; + void IncreaseTimeLimit(unsigned long increase) const; + void UnsetTimeLimit() const; + bool TimeLimited() const; + void AutodynEnable(Cudd_ReorderingType method) const; + void AutodynDisable() const; + bool ReorderingStatus(Cudd_ReorderingType * method) const; + void AutodynEnableZdd(Cudd_ReorderingType method) const; + void AutodynDisableZdd() const; + bool ReorderingStatusZdd(Cudd_ReorderingType * method) const; + bool zddRealignmentEnabled() const; + void zddRealignEnable() const; + void zddRealignDisable() const; + bool bddRealignmentEnabled() const; + void bddRealignEnable() const; + void bddRealignDisable() const; + ADD background() const; + void SetBackground(ADD bg) const; + unsigned int ReadCacheSlots() const; + double ReadCacheUsedSlots() const; + double ReadCacheLookUps() const; + double ReadCacheHits() const; + unsigned int ReadMinHit() const; + void SetMinHit(unsigned int hr) const; + unsigned int ReadLooseUpTo() const; + void SetLooseUpTo(unsigned int lut) const; + unsigned int ReadMaxCache() const; + unsigned int ReadMaxCacheHard() const; + void SetMaxCacheHard(unsigned int mc) const; + int ReadSize() const; + int ReadZddSize() const; + unsigned int ReadSlots() const; + unsigned int ReadKeys() const; + unsigned int ReadDead() const; + unsigned int ReadMinDead() const; + unsigned int ReadReorderings() const; + unsigned int ReadMaxReorderings() const; + void SetMaxReorderings(unsigned int mr) const; + long ReadReorderingTime() const; + int ReadGarbageCollections() const; + long ReadGarbageCollectionTime() const; + int ReadSiftMaxVar() const; + void SetSiftMaxVar(int smv) const; + int ReadSiftMaxSwap() const; + void SetSiftMaxSwap(int sms) const; + double ReadMaxGrowth() const; + void SetMaxGrowth(double mg) const; + MtrNode * ReadTree() const; + void SetTree(MtrNode * tree) const; + void FreeTree() const; + MtrNode * ReadZddTree() const; + void SetZddTree(MtrNode * tree) const; + void FreeZddTree() const; + int ReadPerm(int i) const; + int ReadPermZdd(int i) const; + int ReadInvPerm(int i) const; + int ReadInvPermZdd(int i) const; + BDD ReadVars(int i) const; + CUDD_VALUE_TYPE ReadEpsilon() const; + void SetEpsilon(CUDD_VALUE_TYPE ep) const; + Cudd_AggregationType ReadGroupcheck() const; + void SetGroupcheck(Cudd_AggregationType gc) const; + bool GarbageCollectionEnabled() const; + void EnableGarbageCollection() const; + void DisableGarbageCollection() const; + bool DeadAreCounted() const; + void TurnOnCountDead() const; + void TurnOffCountDead() const; + int ReadRecomb() const; + void SetRecomb(int recomb) const; + int ReadSymmviolation() const; + void SetSymmviolation(int symmviolation) const; + int ReadArcviolation() const; + void SetArcviolation(int arcviolation) const; + int ReadPopulationSize() const; + void SetPopulationSize(int populationSize) const; + int ReadNumberXovers() const; + void SetNumberXovers(int numberXovers) const; + unsigned int ReadOrderRandomization() const; + void SetOrderRandomization(unsigned int factor) const; + unsigned long ReadMemoryInUse() const; + long ReadPeakNodeCount() const; + long ReadNodeCount() const; + long zddReadNodeCount() const; + void AddHook(DD_HFP f, Cudd_HookType where) const; + void RemoveHook(DD_HFP f, Cudd_HookType where) const; + bool IsInHook(DD_HFP f, Cudd_HookType where) const; + void EnableReorderingReporting() const; + void DisableReorderingReporting() const; + bool ReorderingReporting() const; + int ReadErrorCode() const; + void ClearErrorCode() const; + FILE *ReadStdout() const; + void SetStdout(FILE *) const; + FILE *ReadStderr() const; + void SetStderr(FILE *) const; + unsigned int ReadNextReordering() const; + void SetNextReordering(unsigned int) const; + double ReadSwapSteps() const; + unsigned int ReadMaxLive() const; + void SetMaxLive(unsigned int) const; + unsigned long ReadMaxMemory() const; + void SetMaxMemory(unsigned long) const; + int bddBindVar(int) const; + int bddUnbindVar(int) const; + bool bddVarIsBound(int) const; + ADD Walsh(std::vector x, std::vector y); + ADD addResidue(int n, int m, int options, int top); + int ApaNumberOfDigits(int binaryDigits) const; + DdApaNumber NewApaNumber(int digits) const; + void ApaCopy(int digits, DdApaNumber source, DdApaNumber dest) const; + DdApaDigit ApaAdd(int digits, DdApaNumber a, DdApaNumber b, DdApaNumber + sum) const; + DdApaDigit ApaSubtract(int digits, DdApaNumber a, DdApaNumber b, + DdApaNumber diff) const; + DdApaDigit ApaShortDivision(int digits, DdApaNumber dividend, DdApaDigit + divisor, DdApaNumber quotient) const; + void ApaShiftRight(int digits, DdApaDigit in, DdApaNumber a, DdApaNumber + b) const; + void ApaSetToLiteral(int digits, DdApaNumber number, DdApaDigit literal) + const; + void ApaPowerOfTwo(int digits, DdApaNumber number, int power) const; + void ApaPrintHex(FILE * fp, int digits, DdApaNumber number) const; + void ApaPrintDecimal(FILE * fp, int digits, DdApaNumber number) const; + void DebugCheck(); + void CheckKeys(); + MtrNode * MakeTreeNode(unsigned int low, unsigned int size, unsigned int type) const; + // void Harwell(FILE * fp, ADD* E, ADD** x, ADD** y, ADD** xn, ADD** yn_, int * nx, int * ny, int * m, int * n, int bx, int sx, int by, int sy, int pr); + void PrintLinear(); + int ReadLinear(int x, int y); + BDD Xgty(std::vector z, std::vector x, std::vector y); + BDD Xeqy(std::vector x, std::vector y); + ADD Xeqy(std::vector x, std::vector y); + BDD Dxygtdxz(std::vector x, std::vector y, std::vector z); + BDD Dxygtdyz(std::vector x, std::vector y, std::vector z); + BDD Inequality(int c, std::vector x, std::vector y); + BDD Disequality(int c, std::vector x, std::vector y); + BDD Interval(std::vector x, unsigned int lowerB, unsigned int upperB); + ADD Hamming(std::vector xVars, std::vector yVars); + // void Read(FILE * fp, ADD* E, ADD** x, ADD** y, ADD** xn, ADD** yn_, int * nx, int * ny, int * m, int * n, int bx, int sx, int by, int sy); + // void Read(FILE * fp, BDD* E, BDD** x, BDD** y, int * nx, int * ny, int * m, int * n, int bx, int sx, int by, int sy); + void ReduceHeap(Cudd_ReorderingType heuristic, int minsize); + void ShuffleHeap(int * permutation); + void SymmProfile(int lower, int upper) const; + unsigned int Prime(unsigned int pr) const; + void Reserve(int amount) const; + int SharingSize(DD* nodes, int n) const; + int SharingSize(const std::vector& v) const; + BDD bddComputeCube(BDD * vars, int * phase, int n) const; + ADD addComputeCube(ADD * vars, int * phase, int n); + int NextNode(DdGen * gen, BDD * nnode); + BDD IndicesToCube(int * array, int n); + void PrintVersion(FILE * fp) const; + double AverageDistance() const; + long Random() const; + void Srandom(long seed) const; + MtrNode * MakeZddTreeNode(unsigned int low, unsigned int size, unsigned int type); + void zddPrintSubtable() const; + void zddReduceHeap(Cudd_ReorderingType heuristic, int minsize); + void zddShuffleHeap(int * permutation); + void zddSymmProfile(int lower, int upper) const; + void DumpDot( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + void DumpDaVinci( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + void DumpBlif( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + char * mname = 0, + FILE * fp = stdout, + int mv = 0) const; + void DumpDDcal( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + void DumpFactoredForm( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + BDD VectorSupport(const std::vector& roots) const; + std::vector + SupportIndices(const std::vector& roots) const; + int nodeCount(const std::vector& roots) const; + int VectorSupportSize(const std::vector& roots) const; + void DumpDot( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + void DumpDaVinci( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + BDD VectorSupport(const std::vector& roots) const; + int VectorSupportSize(const std::vector& roots) const; + void DumpDot( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + +}; // Cudd + + +extern void defaultError(std::string message); + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/obj/testobj.cc b/resources/3rdparty/cudd-2.5.0/obj/testobj.cc new file mode 100644 index 000000000..633e82337 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/obj/testobj.cc @@ -0,0 +1,607 @@ +/**CFile*********************************************************************** + + FileName [testobj.cc] + + PackageName [cuddObj] + + Synopsis [Test program for the C++ object-oriented encapsulation of CUDD.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "cuddObj.hh" +#include +#include +#include + +using namespace std; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UNUSED = "$Id: testobj.cc,v 1.7 2012/02/05 01:06:40 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void testBdd(Cudd& mgr, int verbosity); +static void testAdd(Cudd& mgr, int verbosity); +static void testAdd2(Cudd& mgr, int verbosity); +static void testZdd(Cudd& mgr, int verbosity); +static void testBdd2(Cudd& mgr, int verbosity); +static void testBdd3(Cudd& mgr, int verbosity); +static void testZdd2(Cudd& mgr, int verbosity); +static void testBdd4(Cudd& mgr, int verbosity); +static void testBdd5(Cudd& mgr, int verbosity); + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Main program for testobj.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +main(int argc, char **argv) +{ + int verbosity = 0; + + if (argc == 2) { + int retval = sscanf(argv[1], "%d", &verbosity); + if (retval != 1) + return 1; + } else if (argc != 1) { + return 1; + } + + Cudd mgr(0,2); + // mgr.makeVerbose(); // trace constructors and destructors + testBdd(mgr,verbosity); + testAdd(mgr,verbosity); + testAdd2(mgr,verbosity); + testZdd(mgr,verbosity); + testBdd2(mgr,verbosity); + testBdd3(mgr,verbosity); + testZdd2(mgr,verbosity); + testBdd4(mgr,verbosity); + testBdd5(mgr,verbosity); + if (verbosity) mgr.info(); + return 0; + +} // main + + +/**Function******************************************************************** + + Synopsis [Test basic operators on BDDs.] + + Description [Test basic operators on BDDs. The function returns void + because it relies on the error handling done by the interface. The + default error handler causes program termination.] + + SideEffects [Creates BDD variables in the manager.] + + SeeAlso [testBdd2 testBdd3 testBdd4 testBdd5] + +******************************************************************************/ +static void +testBdd( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testBdd\n"; + // Create two new variables in the manager. If testBdd is called before + // any variable is created in mgr, then x gets index 0 and y gets index 1. + BDD x = mgr.bddVar(); + BDD y = mgr.bddVar(); + + BDD f = x * y; + if (verbosity) cout << "f"; f.print(2,verbosity); + + BDD g = y + !x; + if (verbosity) cout << "g"; g.print(2,verbosity); + + if (verbosity) + cout << "f and g are" << (f == !g ? "" : " not") << " complementary\n"; + if (verbosity) + cout << "f is" << (f <= g ? "" : " not") << " less than or equal to g\n"; + + g = f | ~g; + if (verbosity) cout << "g"; g.print(2,verbosity); + + BDD h = f = y; + if (verbosity) cout << "h"; h.print(2,verbosity); + + if (verbosity) cout << "x + h has " << (x+h).nodeCount() << " nodes\n"; + + h += x; + if (verbosity) cout << "h"; h.print(2,verbosity); + +} // testBdd + + +/**Function******************************************************************** + + Synopsis [Test basic operators on ADDs.] + + Description [Test basic operators on ADDs. The function returns void + because it relies on the error handling done by the interface. The + default error handler causes program termination.] + + SideEffects [May create ADD variables in the manager.] + + SeeAlso [testAdd2] + +******************************************************************************/ +static void +testAdd( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testAdd\n"; + // Create two ADD variables. If we called method addVar without an + // argument, we would get two new indices. If testAdd is indeed called + // after testBdd, then those indices would be 2 and 3. By specifying the + // arguments, on the other hand, we avoid creating new unnecessary BDD + // variables. + ADD p = mgr.addVar(0); + ADD q = mgr.addVar(1); + + // Test arithmetic operators. + ADD r = p + q; + if (verbosity) cout << "r"; r.print(2,verbosity); + + // CUDD_VALUE_TYPE is double. + ADD s = mgr.constant(3.0); + s *= p * q; + if (verbosity) cout << "s"; s.print(2,verbosity); + + s += mgr.plusInfinity(); + if (verbosity) cout << "s"; s.print(2,verbosity); + + // Test relational operators. + if (verbosity) + cout << "p is" << (p <= r ? "" : " not") << " less than or equal to r\n"; + + // Test logical operators. + r = p | q; + if (verbosity) cout << "r"; r.print(2,verbosity); + +} // testAdd + + +/**Function******************************************************************** + + Synopsis [Test some more operators on ADDs.] + + Description [Test some more operators on ADDs. The function returns void + because it relies on the error handling done by the interface. The + default error handler causes program termination.] + + SideEffects [May create ADD variables in the manager.] + + SeeAlso [testAdd] + +******************************************************************************/ +static void +testAdd2( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testAdd2\n"; + // Create two ADD variables. If we called method addVar without an + // argument, we would get two new indices. + int i; + vector x(2); + for (i = 0; i < 2; i++) { + x[i] = mgr.addVar(i); + } + + // Build a probability density function: [0.1, 0.2, 0.3, 0.4]. + ADD f0 = x[1].Ite(mgr.constant(0.2), mgr.constant(0.1)); + ADD f1 = x[1].Ite(mgr.constant(0.4), mgr.constant(0.3)); + ADD f = x[0].Ite(f1, f0); + if (verbosity) cout << "f"; f.print(2,verbosity); + + // Compute the entropy. + ADD l = f.Log(); + if (verbosity) cout << "l"; l.print(2,verbosity); + ADD r = f * l; + if (verbosity) cout << "r"; r.print(2,verbosity); + + ADD e = r.MatrixMultiply(mgr.constant(-1.0/log(2.0)),x); + if (verbosity) cout << "e"; e.print(2,verbosity); + +} // testAdd2 + + +/**Function******************************************************************** + + Synopsis [Test basic operators on ZDDs.] + + Description [Test basic operators on ZDDs. The function returns void + because it relies on the error handling done by the interface. The + default error handler causes program termination.] + + SideEffects [May create ZDD variables in the manager.] + + SeeAlso [testZdd2] + +******************************************************************************/ +static void +testZdd( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testZdd\n"; + ZDD v = mgr.zddVar(0); + ZDD w = mgr.zddVar(1); + + ZDD s = v + w; + if (verbosity) cout << "s"; s.print(2,verbosity); + + if (verbosity) cout << "v is" << (v < s ? "" : " not") << " less than s\n"; + + s -= v; + if (verbosity) cout << "s"; s.print(2,verbosity); + +} // testZdd + + +/**Function******************************************************************** + + Synopsis [Test vector operators on BDDs.] + + Description [Test vector operators on BDDs. The function returns void + because it relies on the error handling done by the interface. The + default error handler causes program termination.] + + SideEffects [May create BDD variables in the manager.] + + SeeAlso [testBdd testBdd3 testBdd4 testBdd5] + +******************************************************************************/ +static void +testBdd2( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testBdd2\n"; + vector x(4); + for (int i = 0; i < 4; i++) { + x[i] = mgr.bddVar(i); + } + + // Create the BDD for the Achilles' Heel function. + BDD p1 = x[0] * x[2]; + BDD p2 = x[1] * x[3]; + BDD f = p1 + p2; + const char* inames[] = {"x0", "x1", "x2", "x3"}; + if (verbosity) { + cout << "f"; f.print(4,verbosity); + cout << "Irredundant cover of f:" << endl; f.PrintCover(); + cout << "Number of minterms (arbitrary precision): "; f.ApaPrintMinterm(4); + cout << "Number of minterms (extended precision): "; f.EpdPrintMinterm(4); + cout << "Two-literal clauses of f:" << endl; + f.PrintTwoLiteralClauses((char **)inames); cout << endl; + } + + vector vect = f.CharToVect(); + if (verbosity) { + for (size_t i = 0; i < vect.size(); i++) { + cout << "vect[" << i << "]" << endl; vect[i].PrintCover(); + } + } + + // v0,...,v3 suffice if testBdd2 is called before testBdd3. + if (verbosity) { + const char* onames[] = {"v0", "v1", "v2", "v3", "v4", "v5"}; + mgr.DumpDot(vect, (char **)inames,(char **)onames); + } + +} // testBdd2 + + +/**Function******************************************************************** + + Synopsis [Test additional operators on BDDs.] + + Description [Test additional operators on BDDs. The function returns + void because it relies on the error handling done by the + interface. The default error handler causes program termination.] + + SideEffects [May create BDD variables in the manager.] + + SeeAlso [testBdd testBdd2 testBdd4 testBdd5] + +******************************************************************************/ +static void +testBdd3( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testBdd3\n"; + vector x(6); + for (int i = 0; i < 6; i++) { + x[i] = mgr.bddVar(i); + } + + BDD G = x[4] + !x[5]; + BDD H = x[4] * x[5]; + BDD E = x[3].Ite(G,!x[5]); + BDD F = x[3] + !H; + BDD D = x[2].Ite(F,!H); + BDD C = x[2].Ite(E,!F); + BDD B = x[1].Ite(C,!F); + BDD A = x[0].Ite(B,!D); + BDD f = !A; + if (verbosity) cout << "f"; f.print(6,verbosity); + + BDD f1 = f.RemapUnderApprox(6); + if (verbosity) cout << "f1"; f1.print(6,verbosity); + if (verbosity) + cout << "f1 is" << (f1 <= f ? "" : " not") << " less than or equal to f\n"; + + BDD g; + BDD h; + f.GenConjDecomp(&g,&h); + if (verbosity) { + cout << "g"; g.print(6,verbosity); + cout << "h"; h.print(6,verbosity); + cout << "g * h " << (g * h == f ? "==" : "!=") << " f\n"; + } + +} // testBdd3 + + +/**Function******************************************************************** + + Synopsis [Test cover manipulation with BDDs and ZDDs.] + + Description [Test cover manipulation with BDDs and ZDDs. The + function returns void because it relies on the error handling done by + the interface. The default error handler causes program + termination. This function builds the BDDs for a transformed adder: + one in which the inputs are transformations of the original + inputs. It then creates ZDDs for the covers from the BDDs.] + + SideEffects [May create BDD and ZDD variables in the manager.] + + SeeAlso [testZdd] + +******************************************************************************/ +static void +testZdd2( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testZdd2\n"; + int N = 3; // number of bits + // Create variables. + vector a(N); + vector b(N); + vector c(N+1); + for (int i = 0; i < N; i++) { + a[N-1-i] = mgr.bddVar(2*i); + b[N-1-i] = mgr.bddVar(2*i+1); + } + c[0] = mgr.bddVar(2*N); + // Build functions. + vector s(N); + for (int i = 0; i < N; i++) { + s[i] = a[i].Xnor(c[i]); + c[i+1] = a[i].Ite(b[i],c[i]); + } + + // Create array of outputs and print it. + vector p(N+1); + for (int i = 0; i < N; i++) { + p[i] = s[i]; + } + p[N] = c[N]; + if (verbosity) { + for (size_t i = 0; i < p.size(); i++) { + cout << "p[" << i << "]"; p[i].print(2*N+1,verbosity); + } + } + const char* onames[] = {"s0", "s1", "s2", "c3"}; + if (verbosity) { + const char* inames[] = {"a2", "b2", "a1", "b1", "a0", "b0", "c0"}; + mgr.DumpDot(p, (char **)inames,(char **)onames); + } + + // Create ZDD variables and build ZDD covers from BDDs. + mgr.zddVarsFromBddVars(2); + vector z(N+1); + for (int i = 0; i < N+1; i++) { + ZDD temp; + BDD dummy = p[i].zddIsop(p[i],&temp); + z[i] = temp; + } + + // Print out covers. + if (verbosity) { + for (size_t i = 0; i < z.size(); i++) { + cout << "z[" << i << "]"; z[i].print(4*N+2,verbosity); + } + for (size_t i = 0; i < z.size(); i++) { + cout << "z[" << i << "]\n"; z[i].PrintCover(); + } + const char* znames[] = {"a2+", "a2-", "b2+", "b2-", "a1+", "a1-", "b1+", + "b1-", "a0+", "a0-", "b0+", "b0-", "c0+", "c0-"}; + mgr.DumpDot(z, (char **)znames,(char **)onames); + } + +} // testZdd2 + + +/**Function******************************************************************** + + Synopsis [Test transfer between BDD managers.] + + Description [Test transfer between BDD managers. The + function returns void because it relies on the error handling done by + the interface. The default error handler causes program + termination.] + + SideEffects [May create BDD variables in the manager.] + + SeeAlso [testBdd testBdd2 testBdd3 testBdd5] + +******************************************************************************/ +static void +testBdd4( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testBdd4\n"; + BDD x = mgr.bddVar(0); + BDD y = mgr.bddVar(1); + BDD z = mgr.bddVar(2); + + BDD f = !x * !y * !z + x * y; + if (verbosity) cout << "f"; f.print(3,verbosity); + + Cudd otherMgr(0,0); + BDD g = f.Transfer(otherMgr); + if (verbosity) cout << "g"; g.print(3,verbosity); + + BDD h = g.Transfer(mgr); + if (verbosity) + cout << "f and h are" << (f == h ? "" : " not") << " identical\n"; + +} // testBdd4 + + + +/**Function******************************************************************** + + Synopsis [Test maximal expansion of cubes.] + + Description [Test maximal expansion of cubes. The function returns + void because it relies on the error handling done by the interface. + The default error handler causes program termination.] + + SideEffects [May create BDD variables in the manager.] + + SeeAlso [testBdd testBdd2 testBdd3 testBdd4] + +******************************************************************************/ +static void +testBdd5( + Cudd& mgr, + int verbosity) +{ + if (verbosity) cout << "Entering testBdd5\n"; + vector x; + x.reserve(4); + for (int i = 0; i < 4; i++) { + x.push_back(mgr.bddVar(i)); + } + const char* inames[] = {"a", "b", "c", "d"}; + BDD f = (x[1] & x[3]) | (x[0] & !x[2] & x[3]) | (!x[0] & x[1] & !x[2]); + BDD lb = x[1] & !x[2] & x[3]; + BDD ub = x[3]; + BDD primes = lb.MaximallyExpand(ub,f); + assert(primes == (x[1] & x[3])); + BDD lprime = primes.LargestPrimeUnate(lb); + assert(lprime == primes); + if (verbosity) { + const char * onames[] = {"lb", "ub", "f", "primes", "lprime"}; + vector z; + z.reserve(5); + z.push_back(lb); + z.push_back(ub); + z.push_back(f); + z.push_back(primes); + z.push_back(lprime); + mgr.DumpDot(z, (char **)inames, (char **)onames); + cout << "primes(1)"; primes.print(4,verbosity); + } + + lb = !x[0] & x[2] & x[3]; + primes = lb.MaximallyExpand(ub,f); + assert(primes == mgr.bddZero()); + if (verbosity) { + cout << "primes(2)"; primes.print(4,verbosity); + } + + lb = x[0] & !x[2] & x[3]; + primes = lb.MaximallyExpand(ub,f); + assert(primes == lb); + lprime = primes.LargestPrimeUnate(lb); + assert(lprime == primes); + if (verbosity) { + cout << "primes(3)"; primes.print(4,verbosity); + } + + lb = !x[0] & x[1] & !x[2] & x[3]; + ub = mgr.bddOne(); + primes = lb.MaximallyExpand(ub,f); + assert(primes == ((x[1] & x[3]) | (!x[0] & x[1] & !x[2]))); + lprime = primes.LargestPrimeUnate(lb); + assert(lprime == (x[1] & x[3])); + if (verbosity) { + cout << "primes(4)"; primes.print(4,1); primes.PrintCover(); + } + + ub = !x[0] & x[3]; + primes = lb.MaximallyExpand(ub,f); + assert(primes == (!x[0] & x[1] & x[3])); + lprime = primes.LargestPrimeUnate(lb); + assert(lprime == primes); + if (verbosity) { + cout << "primes(5)"; primes.print(4,verbosity); + } + +} // testBdd5 diff --git a/resources/3rdparty/cudd-2.5.0/setup.sh b/resources/3rdparty/cudd-2.5.0/setup.sh new file mode 100755 index 000000000..cb4003236 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/setup.sh @@ -0,0 +1,18 @@ +#! /bin/sh +CREATE="ln -s" +if test -d include + then + : + else + mkdir include + cd include + $CREATE ../cudd/cudd.h . + $CREATE ../cudd/cuddInt.h . + $CREATE ../epd/epd.h . + $CREATE ../dddmp/dddmp.h . + $CREATE ../mtr/mtr.h . + $CREATE ../obj/cuddObj.hh . + $CREATE ../st/st.h . + $CREATE ../util/util.h . + $CREATE ../mnemosyne/mnemosyne.h . +fi diff --git a/resources/3rdparty/cudd-2.5.0/shutdown.sh b/resources/3rdparty/cudd-2.5.0/shutdown.sh new file mode 100755 index 000000000..724917d7c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/shutdown.sh @@ -0,0 +1,2 @@ +#! /bin/sh +rm -rf include *.bak *~ diff --git a/resources/3rdparty/cudd-2.5.0/sis/Makefile.sis b/resources/3rdparty/cudd-2.5.0/sis/Makefile.sis new file mode 100644 index 000000000..fb0c3e64d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/sis/Makefile.sis @@ -0,0 +1,97 @@ +# $Id$ +# +# Cudd - DD package +#--------------------------- +.SUFFIXES: .o .c .u + +RANLIB = ranlib + +CAD = /projects/octtools/octtools/$(MACHINE) +SIS = .. +LINTCREATEFLAG = -C + +# files for the package +P = bdd +PSRC = cuddAPI.c cuddAddAbs.c cuddAddApply.c cuddAddFind.c cuddAddIte.c \ + cuddAddInv.c cuddAddNeg.c cuddAddWalsh.c cuddAndAbs.c \ + cuddAnneal.c cuddApa.c cuddApprox.c cuddBddAbs.c cuddBddCorr.c \ + cuddBddIte.c cuddBddPort.c cuddBridge.c cuddCache.c cuddCheck.c \ + cuddClip.c cuddCof.c cuddCompose.c cuddDecomp.c cuddEssent.c \ + cuddExact.c cuddExport.c cuddGenCof.c \ + cuddGenetic.c cuddGroup.c cuddHarwell.c cuddInit.c cuddInteract.c \ + cuddLCache.c cuddLevelQ.c cuddLinear.c cuddLiteral.c \ + cuddMatMult.c cuddPriority.c cuddPwPt.c \ + cuddRead.c cuddRef.c cuddReorder.c cuddSat.c cuddSign.c \ + cuddSolve.c cuddSplit.c cuddSubsetHB.c cuddSubsetSP.c cuddSymmetry.c \ + cuddTable.c cuddUtil.c cuddWindow.c cuddZddCount.c cuddZddFuncs.c \ + cuddZddGroup.c cuddZddIsop.c cuddZddLin.c cuddZddMisc.c \ + cuddZddPort.c cuddZddReord.c cuddZddSetop.c cuddZddSymm.c \ + cuddZddUtil.c +POBJ = $(PSRC:.c=.o) +PHDR = cudd.h cuddInt.h cuddBdd.h + +# files for the test program +TARGET = testcudd +SRC = testcudd.c +OBJ = $(SRC:.c=.o) +HDR = + +LIBS = ../util/libutil.a ../st/libst.a +LINTLIBS= ../util/llib-lutil.ln ../st/llib-lst.ln +INCLUDE = -I$(CAD)/include -I$(SIS)/include + +CFLAGS = -g $(INCLUDE) +LDFLAGS = -g +LINTFLAGS = $(INCLUDE) ${LINTEXTRAS} + +#------------------------------------------------------ + +$(TARGET): $(PHDR) $(OBJ) $(POBJ) $(LIBS) + $(CC) $(LDFLAGS) -o $(TARGET) $(OBJ) $(POBJ) $(LIBS) + +lint: $(PSRC) $(PHDR) $(SRC) $(HDR) + lint $(LINTFLAGS) $(SRC) $(PSRC) $(LINTLIBS) + +install: lib$(P).a llib-l$(P).ln + +lib$(P).a: $(POBJ) + ar cr $@ $? + $(RANLIB) $@ + +unpack: lib$(P).a + @for i in $(POBJ); do \ + ln -s $(SIS)/$(P)/$$i $(SIS)/unpack; \ + done + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) ${LINTCREATEFLAG}$(P) -n $(PSRC) + +clean: + rm -f $(TARGET) *.a *.ln *.o \ + [Tt]ags [Mm]ake.out lint malloc.out gmon.out __.SYMDEF *~ + +tags: _force + @for i in $(PSRC) $(PHDR); do \ + cwd=`pwd`; ctags -a $$cwd/$$i; + done; + +strip_depend: + sed '/^#--DO NOT CHANGE ANYTHING AFTER THIS LINE/,$$d' Makefile >mktemp + mv mktemp Makefile + +depend: + sed '/^#--DO NOT CHANGE ANYTHING AFTER THIS LINE/,$$d' Makefile >mktemp + echo '#--DO NOT CHANGE ANYTHING AFTER THIS LINE' >>mktemp + $(CAD)/bin/cc-M $(CFLAGS) $(PSRC) | \ + sed 's|$(CAD)|$$(CAD)|g' | \ + grep -v '/usr/include' >>mktemp + mv mktemp Makefile + +#-------------------------- IBM 3090 support ----------------- +IBMHOST = opua +IBMDIST = /users2/sis +ibmdist: $(PSRC) $(PHDR) + rdist -Richw $(PSRC) $(PHDR) $(IBMHOST):$(IBMDIST) +#------------------------------------------------------------- +_force: + diff --git a/resources/3rdparty/cudd-2.5.0/sis/cuddBdd.h b/resources/3rdparty/cudd-2.5.0/sis/cuddBdd.h new file mode 100644 index 000000000..2a688d761 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/sis/cuddBdd.h @@ -0,0 +1,382 @@ +/**CHeaderFile***************************************************************** + + FileName [cuddBdd.h] + + PackageName [cudd] + + Synopsis [Defines interface for the CU package to work with the + ucb interface.] + + Description [] + + Author [Abelardo Pardo] + + Copyright [Copyright (c) 1994-1996 The Univ. of Colorado. + All rights reserved. + + Permission is hereby granted, without written agreement and without license + or royalty fees, to use, copy, modify, and distribute this software and its + documentation for any purpose, provided that the above copyright notice and + the following two paragraphs appear in all copies of this software. + + IN NO EVENT SHALL THE UNIVERSITY OF COLORADO BE LIABLE TO ANY PARTY FOR + DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + COLORADO HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + THE UNIVERSITY OF COLORADO SPECIFICALLY DISCLAIMS ANY WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN + "AS IS" BASIS, AND THE UNIVERSITY OF COLORADO HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.] + + Revision [$Id: cuddBdd.h,v 1.2 1996/07/30 20:42:04 bobbie Exp $] + +******************************************************************************/ + +#ifndef _BDD +#define _BDD + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include "var_set.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +#define boolean int +/* + * foreach macro in the most misesque tradition + * bdd_gen_free always returns 0 + * + * CAUTION: in the context of the port to the CUDD package, it is assumed that + * dynamic reordering will not occur while there are open generators. It is + * the user's responsibility to make sure dynamic reordering doesn't occur. + * As long as new nodes are not created during generation, and you don't + * explicitly call dynamic reordering, you should be okay. + */ + +/* + * foreach_bdd_cube(fn, gen, cube) + * bdd_t *fn; + * bdd_gen *gen; + * array_t *cube; - return + * + * foreach_bdd_cube(fn, gen, cube) { + * ... + * } + */ +#define foreach_bdd_cube(fn, gen, cube)\ + for((gen) = bdd_first_cube(fn, &cube);\ + bdd_is_gen_empty(gen) ? bdd_gen_free(gen) : TRUE;\ + (void) bdd_next_cube(gen, &cube)) + +/* + * foreach_bdd_node(fn, gen, node) + * bdd_t *fn; + * bdd_gen *gen; + * bdd_node *node; - return + */ +#define foreach_bdd_node(fn, gen, node)\ + for((gen) = bdd_first_node(fn, &node);\ + bdd_is_gen_empty(gen) ? bdd_gen_free(gen) : TRUE;\ + (void) bdd_next_node(gen, &node)) + +/* + * Default settings. + */ +#define BDD_NO_LIMIT ((1<<30)-2) +#define BDD_DFLT_ITE_ON TRUE +#define BDD_DFLT_ITE_RESIZE_AT 75 +#define BDD_DFLT_ITE_MAX_SIZE 1000000 +#define BDD_DFLT_ITE_CONST_ON TRUE +#define BDD_DFLT_ITE_CONST_RESIZE_AT 75 +#define BDD_DFLT_ITE_CONST_MAX_SIZE 1000000 +#define BDD_DFLT_ADHOC_ON TRUE +#define BDD_DFLT_ADHOC_RESIZE_AT 0 +#define BDD_DFLT_ADHOC_MAX_SIZE 10000000 +#define BDD_DFLT_GARB_COLLECT_ON TRUE +#define BDD_DFLT_DAEMON NIL(void) +#define BDD_DFLT_MEMORY_LIMIT BDD_NO_LIMIT +#define BDD_DFLT_NODE_RATIO 2.0 +#define BDD_DFLT_INIT_BLOCKS 10 + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct DdManager bdd_manager; /* referenced via a pointer only */ +typedef unsigned int bdd_variableId; /* the id of the variable in a bdd node */ +typedef struct DdNode bdd_node; /* referenced via a pointer only */ +typedef int bdd_literal; /* integers in the set { 0, 1, 2 } */ + +/* This is to avoid problems with the mnemosyne library, which redefines +** free. +*/ +#ifdef MNEMOSYNE +#undef free +#endif + +typedef struct bdd_t { + boolean free; /* TRUE if this is free, FALSE otherwise ... */ + bdd_node *node; /* ptr to the top node of the function */ + bdd_manager *mgr; /* the manager */ +} bdd_t; + +/* + * Initialization data structure. Not supported in CMU package. + */ +typedef struct bdd_mgr_init { + struct { + boolean on; /* TRUE/FALSE: is the cache on */ + unsigned int resize_at; /* percentage at which to resize (e.g. 85% is 85); doesn't apply to adhoc */ + unsigned int max_size; /* max allowable number of buckets; for adhoc, max allowable number of entries */ + } ITE_cache, + ITE_const_cache, + adhoc_cache; + struct { + boolean on; /* TRUE/FALSE: is the garbage collector on */ + } garbage_collector; + struct { + void (*daemon)(); /* used for callback when memory limit exceeded */ + unsigned int limit; /* upper bound on memory allocated by the manager; in megabytes */ + } memory; + struct { + float ratio; /* allocate new bdd_nodes to achieve ratio of used to unused nodes */ + unsigned int init_blocks; /* number of bdd_nodeBlocks initially allocated */ + } nodes; +} bdd_mgr_init; + +/* + * Match types for BDD minimization. + */ +typedef enum { + BDD_MIN_TSM, /* two-side match */ + BDD_MIN_OSM, /* one-side match */ + BDD_MIN_OSDM /* one-side DC match */ +} bdd_min_match_type_t; + +/* + * Statistics and Other Queries + */ +typedef struct bdd_cache_stats { + unsigned int hits; + unsigned int misses; + unsigned int collisions; + unsigned int inserts; +} bdd_cache_stats; + +typedef struct bdd_stats { + struct { + bdd_cache_stats hashtable; /* the unique table; collisions and inserts fields not used */ + bdd_cache_stats itetable; + bdd_cache_stats consttable; + bdd_cache_stats adhoc; + } cache; /* various cache statistics */ + struct { + unsigned int calls; + struct { + unsigned int trivial; + unsigned int cached; + unsigned int full; + } returns; + } ITE_ops, + ITE_constant_ops, + adhoc_ops; + struct { + unsigned int total; + } blocks; /* bdd_nodeBlock count */ + struct { + unsigned int used; + unsigned int unused; + unsigned int total; + unsigned int peak; + } nodes; /* bdd_node count */ + struct { + unsigned int used; + unsigned int unused; + unsigned int total; + unsigned int blocks; + } extptrs; /* bdd_t count */ + struct { + unsigned int times; /* the number of times the garbage-collector has run */ + unsigned int nodes_collected; /* cumulative number of nodes collected over life of manager */ + long runtime; /* cumulative CPU time spent garbage collecting */ + } gc; + struct { + int first_sbrk; /* value of sbrk at start of manager; used to analyze memory usage */ + int last_sbrk; /* value of last sbrk (see "man sbrk") fetched; used to analyze memory usage */ + unsigned int manager; + unsigned int nodes; + unsigned int hashtable; + unsigned int ext_ptrs; + unsigned int ITE_cache; + unsigned int ITE_const_cache; + unsigned int adhoc_cache; + unsigned int total; + } memory; /* memory usage */ +} bdd_stats; + +/* + * Traversal of BDD Formulas + */ + +typedef struct bdd_gen bdd_gen; + +/* + * These are the hooks for stuff that uses bdd's + * + * There are three hooks, and users may use them in whatever + * way they wish; these hooks are guaranteed to never be used + * by the bdd package. + */ +typedef struct bdd_external_hooks { + char *network; + char *mdd; + char *undef1; +} bdd_external_hooks; + +/* + * Dynamic reordering. + */ +typedef enum { + BDD_REORDER_SIFT, + BDD_REORDER_WINDOW, + BDD_REORDER_NONE, + BDD_REORDER_SAME, + BDD_REORDER_RANDOM, + BDD_REORDER_RANDOM_PIVOT, + BDD_REORDER_SIFT_CONVERGE, + BDD_REORDER_SYMM_SIFT, + BDD_REORDER_SYMM_SIFT_CONV, + BDD_REORDER_WINDOW2, + BDD_REORDER_WINDOW3, + BDD_REORDER_WINDOW4, + BDD_REORDER_WINDOW2_CONV, + BDD_REORDER_WINDOW3_CONV, + BDD_REORDER_WINDOW4_CONV, + BDD_REORDER_GROUP_SIFT, + BDD_REORDER_GROUP_SIFT_CONV, + BDD_REORDER_ANNEALING, + BDD_REORDER_GENETIC +} bdd_reorder_type_t; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/* + * BDD Manager Allocation And Destruction + */ +extern void bdd_end (bdd_manager *); +extern void bdd_register_daemon (bdd_manager *, void (*daemon)()); +extern void bdd_set_mgr_init_dflts (bdd_mgr_init *); +extern bdd_manager *bdd_start (int); +extern bdd_manager *bdd_start_with_params (int, bdd_mgr_init *); + +/* + * BDD Variable Allocation + */ +extern bdd_t *bdd_create_variable (bdd_manager *); +extern bdd_t *bdd_get_variable (bdd_manager *, bdd_variableId); + +/* + * BDD Formula Management + */ +extern bdd_t *bdd_dup (bdd_t *); +extern void bdd_free (bdd_t *); + +/* + * Operations on BDD Formulas + */ +extern bdd_t *bdd_and (bdd_t *, bdd_t *, boolean, boolean); +extern bdd_t *bdd_and_smooth (bdd_t *, bdd_t *, array_t *); +extern bdd_t *bdd_between (bdd_t *, bdd_t *); +extern bdd_t *bdd_cofactor (bdd_t *, bdd_t *); +extern bdd_t *bdd_compose (bdd_t *, bdd_t *, bdd_t *); +extern bdd_t *bdd_consensus (bdd_t *, array_t *); +extern bdd_t *bdd_cproject (bdd_t *, array_t *); +extern bdd_t *bdd_else (bdd_t *); +extern bdd_t *bdd_ite (bdd_t *, bdd_t *, bdd_t *, boolean, boolean, boolean); +extern bdd_t *bdd_minimize (bdd_t *, bdd_t *); +extern bdd_t *bdd_minimize_with_params (bdd_t *, bdd_t *, bdd_min_match_type_t, boolean, boolean, boolean); +extern bdd_t *bdd_not (bdd_t *); +extern bdd_t *bdd_one (bdd_manager *); +extern bdd_t *bdd_or (bdd_t *, bdd_t *, boolean, boolean); +extern bdd_t *bdd_smooth (bdd_t *, array_t *); +extern bdd_t *bdd_substitute (bdd_t *, array_t *, array_t *); +extern bdd_t *bdd_then (bdd_t *); +extern bdd_t *bdd_top_var (bdd_t *); +extern bdd_t *bdd_xnor (bdd_t *, bdd_t *); +extern bdd_t *bdd_xor (bdd_t *, bdd_t *); +extern bdd_t *bdd_zero (bdd_manager *); + +/* + * Queries about BDD Formulas + */ +extern boolean bdd_equal (bdd_t *, bdd_t *); +extern boolean bdd_is_cube (bdd_t *); +extern boolean bdd_is_tautology (bdd_t *, boolean); +extern boolean bdd_leq (bdd_t *, bdd_t *, boolean, boolean); + +extern double bdd_count_onset (bdd_t *, array_t *); +extern bdd_manager *bdd_get_manager (bdd_t *); +extern bdd_node *bdd_get_node (bdd_t *, boolean *); +extern void bdd_get_stats (bdd_manager *, bdd_stats *); +extern var_set_t *bdd_get_support (bdd_t *); +extern array_t *bdd_get_varids (array_t *); +extern unsigned int bdd_num_vars (bdd_manager *); +extern void bdd_print (bdd_t *); +extern void bdd_print_stats (bdd_stats, FILE *); +extern int bdd_size (bdd_t *); +extern bdd_variableId bdd_top_var_id (bdd_t *); +extern bdd_t *bdd_create_variable_after (bdd_manager *, bdd_variableId); +extern bdd_variableId bdd_get_id_from_level (bdd_manager *, long); +extern long bdd_top_var_level (bdd_manager *, bdd_t *); + +extern int bdd_gen_free (bdd_gen *); + +/* + * These are NOT to be used directly; only indirectly in the macros. + */ +extern bdd_gen *bdd_first_cube (bdd_t *, array_t **); +extern boolean bdd_next_cube (bdd_gen *, array_t **); +extern bdd_gen *bdd_first_node (bdd_t *, bdd_node **); +extern boolean bdd_next_node (bdd_gen *, bdd_node **); +extern boolean bdd_is_gen_empty (bdd_gen *); + +/* + * Miscellaneous + */ +extern void bdd_set_gc_mode (bdd_manager *, boolean); + +extern bdd_external_hooks *bdd_get_external_hooks (bdd_manager *); + +extern void bdd_dynamic_reordering (bdd_manager *, bdd_reorder_type_t); + +extern int bdd_read_reordering_flag (bdd_manager *); + +#ifdef __cplusplus +} +#endif + +#endif /* _BDD */ diff --git a/resources/3rdparty/cudd-2.5.0/sis/cuddBddPort.c b/resources/3rdparty/cudd-2.5.0/sis/cuddBddPort.c new file mode 100644 index 000000000..7b97956c6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/sis/cuddBddPort.c @@ -0,0 +1,1954 @@ +/**CFile*********************************************************************** + + FileName [cuddBddPort.c] + + PackageName [cudd] + + Synopsis [SIS interface to the Decision Diagram Package of the + University of Colorado.] + + Description [This file implements an interface between the functions in + the Berkeley BDD package and the functions provided by the CUDD (decision + diagram) package from the University of Colorado. The CUDD package is a + generic implementation of a decision diagram data structure. For the time + being, only Boole expansion is implemented and the leaves in the + in the nodes can be the constants zero, one or any arbitrary value.] + + Author [Abelardo Pardo] + + Copyright [Copyright (c) 1994-1996 The Univ. of Colorado. + All rights reserved. + + Permission is hereby granted, without written agreement and without license + or royalty fees, to use, copy, modify, and distribute this software and its + documentation for any purpose, provided that the above copyright notice and + the following two paragraphs appear in all copies of this software. + + IN NO EVENT SHALL THE UNIVERSITY OF COLORADO BE LIABLE TO ANY PARTY FOR + DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + COLORADO HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + THE UNIVERSITY OF COLORADO SPECIFICALLY DISCLAIMS ANY WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN + "AS IS" BASIS, AND THE UNIVERSITY OF COLORADO HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.] + +******************************************************************************/ + +#include "util.h" +#include "array.h" +#include "st.h" + +#ifdef EXTERN +#undef EXTERN +#endif +#define EXTERN +#include "cuddInt.h" +#include "cuddBdd.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +struct bdd_gen { + bdd_manager *manager; + DdGen *ddGen; + array_t *cube; +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBddPort.c,v 1.11 1996/05/08 06:13:08 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static bdd_t * bdd_construct_bdd_t (DdManager *mgr, DdNode * fn); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Terminates the bdd package.] + + SideEffects [] + +******************************************************************************/ +void +bdd_end(mgr) +bdd_manager *mgr; +{ + if (mgr->hooks != NULL) FREE(mgr->hooks); + Cudd_Quit(mgr); + +} /* end of bdd_end */ + + +/**Function******************************************************************** + + Synopsis [Initialize manager with the options given in mgr_init.] + + SideEffects [] + +******************************************************************************/ +void +bdd_set_mgr_init_dflts(mgr_init) +bdd_mgr_init *mgr_init; +{ + fprintf(stderr,"CU DD Package: bdd_set_mgr_init_dflts translated to no-op\n"); + return; + +} /* end of bdd_set_mgr_init_dflts */ + + +/**Function******************************************************************** + + Synopsis [Starts the manager with nvariables variables.] + + SideEffects [] + +******************************************************************************/ +bdd_manager * +bdd_start(nvariables) +int nvariables; +{ + DdManager *mgr; + bdd_external_hooks *hooks; + + mgr = Cudd_Init((unsigned int)nvariables,0,CUDD_UNIQUE_SLOTS, + CUDD_CACHE_SLOTS,0); + + hooks = ALLOC(bdd_external_hooks,1); + hooks->mdd = hooks->network = hooks->undef1 = (char *) 0; + mgr->hooks = (char *) hooks; + + return (bdd_manager *)mgr; + +} /* end of bdd_start */ + + +/**Function******************************************************************** + + Synopsis [Starts the manager with parameters.] + + SideEffects [] + +******************************************************************************/ +bdd_manager * +bdd_start_with_params(nvariables, mgr_init) +int nvariables; +bdd_mgr_init *mgr_init; +{ + fprintf(stderr,"CU DD Package: bdd_start_with_parameters bypassed\n"); + return (bdd_manager *)Cudd_Init((unsigned int)nvariables,0, + CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); + +} /* end of bdd_start_with_params */ + + +/**Function******************************************************************** + + Synopsis [Creates a new variable in the manager.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_create_variable(mgr) +bdd_manager *mgr; +{ + DdNode *var; + DdManager *dd = (DdManager *) mgr; + DdNode *one = DD_ONE(dd); + + if (dd->size >= CUDD_MAXINDEX -1) return(NULL); + do { + dd->reordered = 0; + var = cuddUniqueInter(dd,dd->size,one,Cudd_Not(one)); + } while (dd->reordered == 1); + + if (var == NULL) return(NULL); + cuddRef(var); + return(bdd_construct_bdd_t(dd,var)); + +} /* end of bdd_create_variable */ + + +/**Function******************************************************************** + + Synopsis [Creates a new variable and positions it after the + variable with the specified index.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_create_variable_after(mgr, after_id) +bdd_manager *mgr; +bdd_variableId after_id; +{ + DdNode *var; + DdManager *dd = (DdManager *) mgr; + int level; + + if (after_id >= dd->size) return(NULL); + level = 1 + dd->perm[after_id]; + var = Cudd_bddNewVarAtLevel(dd,level); + if (var == NULL) return(NULL); + cuddRef(var); + return(bdd_construct_bdd_t(dd,var)); + +} /* end of bdd_create_variable_after */ + + +/**Function******************************************************************** + + Synopsis [Returns the BDD representing the variable with given ID.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_get_variable(mgr, variable_ID) +bdd_manager *mgr; +bdd_variableId variable_ID; /* unsigned int */ +{ + DdNode *var; + DdManager *dd = (DdManager *) mgr; + DdNode *one = DD_ONE(dd); + + if (variable_ID >= CUDD_MAXINDEX -1) return(NULL); + do { + dd->reordered = 0; + var = cuddUniqueInter(dd,(int)variable_ID,one,Cudd_Not(one)); + } while (dd->reordered == 1); + + if (var == NULL) return(NULL); + cuddRef(var); + return(bdd_construct_bdd_t(dd,var)); + +} /* end of bdd_get_variable */ + + +/**Function******************************************************************** + + Synopsis [Creates a copy of the BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_dup(f) +bdd_t *f; +{ + cuddRef(f->node); + return(bdd_construct_bdd_t((DdManager *)f->mgr,f->node)); + +} /* end of bdd_dup */ + + +/**Function******************************************************************** + + Synopsis [Deletes the BDD of f.] + + SideEffects [] + +******************************************************************************/ +void +bdd_free(f) +bdd_t *f; +{ + if (f == NULL) { + fail("bdd_free: trying to free a NULL bdd_t"); + } + + if (f->free == TRUE) { + fail("bdd_free: trying to free a freed bdd_t"); + } + + Cudd_RecursiveDeref((DdManager *)f->mgr,f->node); + /* This is a bit overconservative. */ + f->node = 0; + f->mgr = 0; + f->free = 0; + FREE(f); + return; + +} /* end of bdd_free */ + + +/**Function******************************************************************** + + Synopsis [And of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_and(f, g, f_phase, g_phase) +bdd_t *f; +bdd_t *g; +boolean f_phase; +boolean g_phase; +{ + DdManager *dd; + DdNode *newf,*newg,*fandg; + bdd_t *result; + + /* Make sure both BDDs belong to the same manager. */ + assert(f->mgr == g->mgr); + + /* Modify the phases of the operands according to the parameters. */ + if (!f_phase) { + newf = Cudd_Not(f->node); + } else { + newf = f->node; + } + if (!g_phase) { + newg = Cudd_Not(g->node); + } else { + newg = g->node; + } + + /* Perform the AND operation */ + dd = (DdManager *)f->mgr; + fandg = Cudd_bddAnd((DdManager *)f->mgr,newf,newg); + if (fandg == NULL) return(NULL); + cuddRef(fandg); + result = bdd_construct_bdd_t(dd,fandg); + + return(result); + +} /* end of bdd_and */ + + +/**Function******************************************************************** + + Synopsis [Abstracts variables from the product of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_and_smooth(f, g, smoothing_vars) +bdd_t *f; +bdd_t *g; +array_t *smoothing_vars; /* of bdd_t *'s */ +{ + int i; + bdd_t *variable; + DdNode *cube,*tmpDd,*result; + DdManager *mgr; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + /* The Boulder package needs the smothing variables passed as a cube. + ** Therefore we must build that cube from the indices of variables + ** in the array before calling the procedure. + */ + mgr = (DdManager *)f->mgr; + Cudd_Ref(cube = DD_ONE(mgr)); + for (i = 0; i < array_n(smoothing_vars); i++) { + variable = array_fetch(bdd_t *,smoothing_vars,i); + + /* Make sure the variable belongs to the same manager. */ + assert(mgr == variable->mgr); + + tmpDd = Cudd_bddAnd(mgr,cube,variable->node); + if (tmpDd == NULL) { + Cudd_RecursiveDeref(mgr,cube); + return(NULL); + } + cuddRef(tmpDd); + Cudd_RecursiveDeref(mgr, cube); + cube = tmpDd; + } + + /* Perform the smoothing */ + result = Cudd_bddAndAbstract(mgr,f->node,g->node,cube); + if (result == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(result); + /* Get rid of temporary results. */ + Cudd_RecursiveDeref(mgr, cube); + + /* Build the bdd_t structure for the result */ + return(bdd_construct_bdd_t(mgr,result)); + +} /* end of bdd_and_smooth */ + + +/**Function******************************************************************** + + Synopsis [Return a minimum size BDD between bounds.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_between(f_min, f_max) +bdd_t *f_min; +bdd_t *f_max; +{ + bdd_t *temp, *ret; + + temp = bdd_or(f_min, f_max, 1, 0); + ret = bdd_minimize(f_min, temp); + bdd_free(temp); + return(ret); + +} /* end of bdd_between */ + + +/**Function******************************************************************** + + Synopsis [Computes the cofactor of f with respect to g.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_cofactor(f, g) +bdd_t *f; +bdd_t *g; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager */ + assert(f->mgr == g->mgr); + + /* We use Cudd_bddConstrain instead of Cudd_Cofactor for generality. */ + result = Cudd_bddConstrain((DdManager *)f->mgr,f->node,g->node); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t((DdManager *)f->mgr,result)); + +} /* end of bdd_cofactor */ + + +/**Function******************************************************************** + + Synopsis [Functional composition of a function by a variable.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_compose(f, v, g) +bdd_t *f; +bdd_t *v; +bdd_t *g; +{ + DdNode *result; + + /* Make sure all operands belong to the same manager. */ + assert(f->mgr == g->mgr); + assert(f->mgr == v->mgr); + + result = Cudd_bddCompose(f->mgr,f->node,g->node,(int)Cudd_Regular(v->node)->index); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_compose */ + + +/**Function******************************************************************** + + Synopsis [Universal Abstraction of Variables.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_consensus(f, quantifying_vars) +bdd_t *f; +array_t *quantifying_vars; /* of bdd_t *'s */ +{ + int i; + bdd_t *variable; + DdNode *cube,*tmpDd,*result; + bdd_manager *mgr; + + /* The Boulder package needs the smothing variables passed as a cube. + ** Therefore we must build that cube from the indices of the variables + ** in the array before calling the procedure. + */ + mgr = f->mgr; + Cudd_Ref(cube = DD_ONE(mgr)); + for (i = 0; i < array_n(quantifying_vars); i++) { + variable = array_fetch(bdd_t *,quantifying_vars,i); + + /* Make sure the variable belongs to the same manager */ + assert(mgr == variable->mgr); + + tmpDd = Cudd_bddAnd(mgr,cube,variable->node); + if (tmpDd == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(tmpDd); + Cudd_RecursiveDeref(mgr, cube); + cube = tmpDd; + } + + /* Perform the consensus */ + result = Cudd_bddUnivAbstract(mgr,f->node,cube); + if (result == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(result); + /* Get rid of temporary results */ + Cudd_RecursiveDeref(mgr, cube); + + /* Build the bdd_t structure for the result */ + return(bdd_construct_bdd_t(mgr,result)); + +} /* end of bdd_consensus */ + + +/**Function******************************************************************** + + Synopsis [The compatible projection function.] + + Description [The compatible projection function. The reference minterm + is chosen based on the phases of the quantifying variables. If all + variables are in positive phase, the minterm 111...111 is used as + reference.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_cproject(f, quantifying_vars) +bdd_t *f; +array_t *quantifying_vars; /* of bdd_t* */ +{ + DdManager *dd; + DdNode *cube; + DdNode *res; + bdd_t *fi; + int nvars, i; + + if (f == NULL) { + fail ("bdd_cproject: invalid BDD"); + } + + nvars = array_n(quantifying_vars); + if (nvars <= 0) { + fail("bdd_cproject: no projection variables"); + } + dd = f->mgr; + + cube = DD_ONE(dd); + cuddRef(cube); + for (i = nvars - 1; i >= 0; i--) { + DdNode *tmpp; + fi = array_fetch(bdd_t *, quantifying_vars, i); + tmpp = Cudd_bddAnd(dd,fi->node,cube); + if (tmpp == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(tmpp); + Cudd_RecursiveDeref(dd,cube); + cube = tmpp; + } + + res = Cudd_CProjection(dd,f->node,cube); + if (res == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,cube); + + return(bdd_construct_bdd_t(dd,res)); + +} /* end of bdd_cproject */ + + +/**Function******************************************************************** + + Synopsis [ITE.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_ite(i, t, e, i_phase, t_phase, e_phase) +bdd_t *i; +bdd_t *t; +bdd_t *e; +boolean i_phase; +boolean t_phase; +boolean e_phase; +{ + DdNode *newi,*newt,*newe,*ite; + + /* Make sure both bdds belong to the same mngr */ + assert(i->mgr == t->mgr); + assert(i->mgr == e->mgr); + + /* Modify the phases of the operands according to the parameters */ + if (!i_phase) { + newi = Cudd_Not(i->node); + } else { + newi = i->node; + } + if (!t_phase) { + newt = Cudd_Not(t->node); + } else { + newt = t->node; + } + if (!e_phase) { + newe = Cudd_Not(e->node); + } else { + newe = e->node; + } + + /* Perform the ITE operation */ + ite = Cudd_bddIte(i->mgr,newi,newt,newe); + if (ite == NULL) return(NULL); + cuddRef(ite); + return(bdd_construct_bdd_t(i->mgr,ite)); + +} /* end of bdd_ite */ + + +/**Function******************************************************************** + + Synopsis [Restric operator as described in Coudert et al. ICCAD90.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_minimize(f, c) +bdd_t *f; +bdd_t *c; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == c->mgr); + + result = Cudd_bddRestrict(f->mgr,f->node,c->node); + if (result == NULL) return(NULL); + cuddRef(result); + + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_minimize */ + + +/**Function******************************************************************** + + Synopsis [Parametrized version of the Restrict operator.] + + Description [Parametrized version of the Restrict operator. Currently + defaults to bdd_minimize.] + + SideEffects [] + +******************************************************************************/ +/*ARGSUSED*/ +bdd_t * +bdd_minimize_with_params(f, c, match_type, compl, no_new_vars, return_min) +bdd_t *f; +bdd_t *c; +bdd_min_match_type_t match_type; +boolean compl; +boolean no_new_vars; +boolean return_min; +{ + return(bdd_minimize(f,c)); + +} /* end of bdd_minimize_with_params */ + + +/**Function******************************************************************** + + Synopsis [Negation.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_not(f) +bdd_t *f; +{ + DdNode *result; + + Cudd_Ref(result = Cudd_Not(f->node)); + return(bdd_construct_bdd_t((DdManager *)f->mgr,result)); + +} /* end of bdd_not */ + + +/**Function******************************************************************** + + Synopsis [Returns the one BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_one(mgr) +bdd_manager *mgr; +{ + DdNode *result; + + Cudd_Ref(result = DD_ONE((DdManager *)mgr)); + return(bdd_construct_bdd_t((DdManager *)mgr,result)); + +} /* end of bdd_one */ + + +/**Function******************************************************************** + + Synopsis [Or of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_or(f, g, f_phase, g_phase) +bdd_t *f; +bdd_t *g; +boolean f_phase; +boolean g_phase; +{ + DdNode *newf,*newg,*forg; + bdd_t *result; + + /* Make sure both bdds belong to the same mngr */ + assert(f->mgr == g->mgr); + + /* Modify the phases of the operands according to the parameters */ + if (f_phase) { + newf = Cudd_Not(f->node); + } else { + newf = f->node; + } + if (g_phase) { + newg = Cudd_Not(g->node); + } else { + newg = g->node; + } + + /* Perform the OR operation */ + forg = Cudd_bddAnd(f->mgr,newf,newg); + if (forg == NULL) return(NULL); + forg = Cudd_Not(forg); + cuddRef(forg); + result = bdd_construct_bdd_t(f->mgr,forg); + + return(result); + +} /* end of bdd_or */ + + +/**Function******************************************************************** + + Synopsis [Existential abstraction of variables.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_smooth(f, smoothing_vars) +bdd_t *f; +array_t *smoothing_vars; /* of bdd_t *'s */ +{ + int i; + bdd_t *variable; + DdNode *cube,*tmpDd,*result; + bdd_manager *mgr; + + /* The Boulder package needs the smothing variables passed as a cube. + ** Therefore we must build that cube from the indices of the variables + ** in the array before calling the procedure. + */ + mgr = f->mgr; + Cudd_Ref(cube = DD_ONE(mgr)); + for (i = 0; i < array_n(smoothing_vars); i++) { + variable = array_fetch(bdd_t *,smoothing_vars,i); + + /* Make sure the variable belongs to the same manager. */ + assert(mgr == variable->mgr); + + tmpDd = Cudd_bddAnd(mgr,cube,variable->node); + if (tmpDd == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(tmpDd); + Cudd_RecursiveDeref(mgr, cube); + cube = tmpDd; + } + + /* Perform the smoothing */ + result = Cudd_bddExistAbstract(mgr,f->node,cube); + if (result == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(result); + + /* Get rid of temporary results */ + Cudd_RecursiveDeref(mgr, cube); + + /* Build the bdd_t structure for the result */ + return(bdd_construct_bdd_t(mgr,result)); + +} /* end of bdd_smooth */ + + +/**Function******************************************************************** + + Synopsis [Permutes the variables.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_substitute(f, old_array, new_array) +bdd_t *f; +array_t *old_array; /* of bdd_t *'s */ +array_t *new_array; /* of bdd_t *'s */ +{ + int maxOld; + int i,varIndex,from,to; + int *permut; + bdd_t *variable; + DdNode *result; + + /* Make sure both arrays have the same number of elements. */ + assert(array_n(old_array) == array_n(new_array)); + + /* Detect what is the highest index of variable to rename. */ + maxOld = 0; + for (i = 0; i < array_n(old_array); i++) { + variable = array_fetch(bdd_t *, old_array, i); + /* Make sure the variable belongs to this manager. */ + assert(f->mgr == variable->mgr); + + varIndex = Cudd_Regular(variable->node)->index; + if (varIndex > maxOld) { + maxOld = varIndex; + } + } + maxOld++; + + /* Allocate and fill the array with the trivial permutation. */ + permut = ALLOC(int, maxOld); + for (i = 0; i < maxOld; i++) permut[i] = i; + + /* Modify the permutation by looking at both arrays old and new. */ + for (i = 0; i < array_n(old_array); i++) { + variable = array_fetch(bdd_t *, old_array, i); + from = Cudd_Regular(variable->node)->index; + variable = array_fetch(bdd_t *, new_array, i); + /* Make sure the variable belongs to this manager. */ + assert(f->mgr == variable->mgr); + + to = Cudd_Regular(variable->node)->index; + permut[from] = to; + } + + result = Cudd_bddPermute(f->mgr,f->node,permut); + FREE(permut); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_substitute */ + + +/**Function******************************************************************** + + Synopsis [Returns the Then branch of the BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_then(f) +bdd_t *f; +{ + DdNode *result; + + result = Cudd_T(f->node); + result = Cudd_NotCond(result,Cudd_IsComplement(f->node)); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_then */ + + +/**Function******************************************************************** + + Synopsis [Returns the else branch of a BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_else(f) +bdd_t *f; +{ + DdNode *result; + + result = Cudd_E(f->node); + result = Cudd_NotCond(result,Cudd_IsComplement(f->node)); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_else */ + + +/**Function******************************************************************** + + Synopsis [Returns the BDD of the top variable.] + + Description [Returns the BDD of the top variable of the argument. If + the argument is constant, it returns the constant function itself.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_top_var(f) +bdd_t *f; +{ + DdNode *result; + + if (Cudd_IsConstant(f->node)) { + result = f->node; + } else { + result = f->mgr->vars[Cudd_Regular(f->node)->index]; + } + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_top_var */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive nor of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_xnor(f, g) +bdd_t *f; +bdd_t *g; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + result = Cudd_bddIte(f->mgr,f->node,g->node,Cudd_Not(g->node)); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_xnor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive or of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_xor(f, g) +bdd_t *f; +bdd_t *g; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + result = Cudd_bddIte(f->mgr,f->node,Cudd_Not(g->node),g->node); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_xor */ + + +/**Function******************************************************************** + + Synopsis [Returns the constant zero BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_zero(mgr) +bdd_manager *mgr; +{ + DdNode *result; + + Cudd_Ref(result = Cudd_Not(DD_ONE((mgr)))); + return(bdd_construct_bdd_t(mgr,result)); + +} /* end of bdd_zero */ + + +/**Function******************************************************************** + + Synopsis [Equality check.] + + SideEffects [] + +******************************************************************************/ +boolean +bdd_equal(f, g) +bdd_t *f; +bdd_t *g; +{ + return(f->node == g->node); + +} /* end of bdd_equal */ + + +/**Function******************************************************************** + + Synopsis [Returns a BDD included in the intersection of f and g.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_intersects(f, g) +bdd_t *f; +bdd_t *g; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + result = Cudd_bddIntersect(f->mgr,f->node,g->node); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_intersects */ + + +/**Function******************************************************************** + + Synopsis [Checks a BDD for tautology.] + + SideEffects [] + +******************************************************************************/ +boolean +bdd_is_tautology(f, phase) +bdd_t *f; +boolean phase; +{ + if (phase) { + return(f->node == DD_ONE(f->mgr)); + } else { + return(f->node == Cudd_Not(DD_ONE(f->mgr))); + } + +} /* end of bdd_is_tautology */ + + +/**Function******************************************************************** + + Synopsis [Tests for containment of f in g.] + + SideEffects [] + +******************************************************************************/ +boolean +bdd_leq(f, g, f_phase, g_phase) +bdd_t *f; +bdd_t *g; +boolean f_phase; +boolean g_phase; +{ + DdNode *newf, *newg; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + if (f_phase) { + newf = f->node; + } else { + newf = Cudd_Not(f->node); + } + if (g_phase) { + newg = g->node; + } else { + newg = Cudd_Not(g->node); + } + + return(Cudd_bddLeq(f->mgr,newf,newg)); + +} /* end of bdd_leq */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms in the on set.] + + SideEffects [] + +******************************************************************************/ +double +bdd_count_onset(f, var_array) +bdd_t *f; +array_t *var_array; /* of bdd_t *'s */ +{ + return(Cudd_CountMinterm(f->mgr,f->node,array_n(var_array))); + +} /* end of bdd_count_onset */ + + +/**Function******************************************************************** + + Synopsis [Obtains the manager of the BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_manager * +bdd_get_manager(f) +bdd_t *f; +{ + return(f->mgr); + +} /* end of bdd_get_manager */ + + +/**Function******************************************************************** + + Synopsis [Returns the node of the BDD.] + + SideEffects [Sets is_complemented.] + +******************************************************************************/ +bdd_node * +bdd_get_node(f, is_complemented) +bdd_t *f; +boolean *is_complemented; /* return */ +{ + if (Cudd_IsComplement(f->node)) { + *is_complemented = TRUE; + return(Cudd_Regular(f->node)); + } + *is_complemented = FALSE; + return(f->node); + +} /* end of bdd_get_node */ + + +/**Function******************************************************************** + + Synopsis [Returns the free field of the BDD.] + + SideEffects [] + +******************************************************************************/ +int +bdd_get_free(f) +bdd_t *f; +{ + return (f->free); + +} /* end of bdd_get_free */ + + +/**Function******************************************************************** + + Synopsis [Obtains some statistics of the BDD package.] + + SideEffects [Sets stats.] + +******************************************************************************/ +/*ARGSUSED*/ +void +bdd_get_stats(mgr, stats) +bdd_manager *mgr; +bdd_stats *stats; /* return */ +{ + stats->nodes.total = mgr->keys; + stats->nodes.used = mgr->keys - mgr->dead; + stats->nodes.unused = mgr->dead; + stats->cache.itetable.hits = (unsigned int) Cudd_ReadCacheHits(mgr); + stats->cache.itetable.misses = (unsigned int) + (Cudd_ReadCacheLookUps(mgr) - Cudd_ReadCacheHits(mgr)); + stats->cache.itetable.collisions = mgr->cachecollisions; + stats->cache.itetable.inserts = mgr->cacheinserts; + stats->gc.times = Cudd_ReadGarbageCollections(mgr); + return; + +} /* end of bdd_get_stats */ + + +/**Function******************************************************************** + + Synopsis [Obtains the support of the BDD.] + + SideEffects [] + +******************************************************************************/ +var_set_t * +bdd_get_support(f) +bdd_t *f; +{ + DdNode *support, *scan; + var_set_t *result; + + support = Cudd_Support(f->mgr,f->node); + if (support == NULL) return(NULL); + cuddRef(support); + + result = var_set_new((int) f->mgr->size); + scan = support; + while (!cuddIsConstant(scan)) { + var_set_set_elt(result, scan->index); + scan = cuddT(scan); + } + Cudd_RecursiveDeref(f->mgr,support); + + return(result); + +} /* end of bdd_get_support */ + + +/**Function******************************************************************** + + Synopsis [Obtains the array of indices of an array of variables.] + + SideEffects [] + +******************************************************************************/ +array_t * +bdd_get_varids(var_array) +array_t *var_array; +{ + int i; + int index; + bdd_t *var; + array_t *result = array_alloc(int,array_n(var_array)); + + for (i = 0; i < array_n(var_array); i++) { + var = array_fetch(bdd_t *, var_array, i); + index = Cudd_Regular(var->node)->index; + (void) array_insert_last(int, result, index); + } + return(result); + +} /* end of bdd_get_varids */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of variables in the manager.] + + SideEffects [] + +******************************************************************************/ +unsigned int +bdd_num_vars(mgr) +bdd_manager *mgr; +{ + return(mgr->size); + +} /* end of bdd_num_vars */ + + +/**Function******************************************************************** + + Synopsis [Prints the BDD.] + + SideEffects [] + +******************************************************************************/ +void +bdd_print(f) +bdd_t *f; +{ + (void) cuddP(f->mgr,f->node); + +} /* end of bdd_print */ + + +/**Function******************************************************************** + + Synopsis [Prints statistics about the package.] + + SideEffects [] + +******************************************************************************/ +void +bdd_print_stats(stats, file) +bdd_stats stats; +FILE *file; +{ +#ifndef DD_STATS + fprintf(stderr,"CU DD package: bdd_print_stats: Statistics turned off. No output\n"); +#else + fprintf(file,"CU DD Package Statistics\n"); + fprintf(file," Cache hits : %d\n",stats.cache.itetable.hits); + fprintf(file," Cache misses : %d\n",stats.cache.itetable.misses); + fprintf(file," Cache collisions : %d\n",stats.cache.itetable.collisions); + fprintf(file," Cache inserts: %d\n",stats.cache.itetable.inserts); +#endif + return; + +} /* end of bdd_print_stats */ + + +/**Function******************************************************************** + + Synopsis [Computes the number of nodes of a BDD.] + + SideEffects [] + +******************************************************************************/ +int +bdd_size(f) +bdd_t *f; +{ + return(Cudd_DagSize(f->node)); + +} /* end of bdd_size */ + + +/**Function******************************************************************** + + Synopsis [Accesses the id of the top variable.] + + SideEffects [] + +******************************************************************************/ +bdd_variableId +bdd_top_var_id(f) +bdd_t *f; +{ + return(Cudd_Regular(f->node)->index); + +} /* end of bdd_top_var_id */ + + +/**Function******************************************************************** + + Synopsis [Accesses the external_hooks field of the manager.] + + SideEffects [] + +******************************************************************************/ +bdd_external_hooks * +bdd_get_external_hooks(mgr) +bdd_manager *mgr; +{ + return((bdd_external_hooks *)(mgr->hooks)); + +} /* end of bdd_get_external_hooks */ + + +/**Function******************************************************************** + + Synopsis [Registers a new hook with the manager.] + + SideEffects [] + +******************************************************************************/ +/*ARGSUSED*/ +void +bdd_register_daemon(mgr, daemon) +bdd_manager *mgr; +void (*daemon)(); +{ + fprintf(stderr,"CU DD Package: bdd_register_daemon translated to no-op.\n"); + return; + +} /* end of bdd_register_daemon */ + + +/**Function******************************************************************** + + Synopsis [Turns on or off garbage collection.] + + SideEffects [] + +******************************************************************************/ +void +bdd_set_gc_mode(mgr, no_gc) +bdd_manager *mgr; +boolean no_gc; +{ + if (no_gc) { + Cudd_DisableGarbageCollection(mgr); + } else { + Cudd_EnableGarbageCollection(mgr); + } + return; + +} /* end of bdd_set_gc_mode */ + + +/**Function******************************************************************** + + Synopsis [Reorders the BDD pool.] + + SideEffects [] + +******************************************************************************/ +void +bdd_dynamic_reordering(mgr, algorithm_type) +bdd_manager *mgr; +bdd_reorder_type_t algorithm_type; +{ + switch (algorithm_type) { + case BDD_REORDER_SIFT: + mgr->autoMethod = CUDD_REORDER_SIFT; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW: + case BDD_REORDER_WINDOW4: + mgr->autoMethod = CUDD_REORDER_WINDOW4; + mgr->autoDyn = 1; + break; + case BDD_REORDER_NONE: + mgr->autoDyn = 0; + break; + case BDD_REORDER_SAME: + mgr->autoDyn = 1; + break; + case BDD_REORDER_RANDOM: + mgr->autoMethod = CUDD_REORDER_RANDOM; + mgr->autoDyn = 1; + break; + case BDD_REORDER_RANDOM_PIVOT: + mgr->autoMethod = CUDD_REORDER_RANDOM_PIVOT; + mgr->autoDyn = 1; + break; + case BDD_REORDER_SIFT_CONVERGE: + mgr->autoMethod = CUDD_REORDER_SIFT_CONVERGE; + mgr->autoDyn = 1; + break; + case BDD_REORDER_SYMM_SIFT: + mgr->autoMethod = CUDD_REORDER_SYMM_SIFT; + mgr->autoDyn = 1; + break; + case BDD_REORDER_SYMM_SIFT_CONV: + mgr->autoMethod = CUDD_REORDER_SYMM_SIFT_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW2: + mgr->autoMethod = CUDD_REORDER_WINDOW2; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW3: + mgr->autoMethod = CUDD_REORDER_WINDOW3; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW2_CONV: + mgr->autoMethod = CUDD_REORDER_WINDOW2_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW3_CONV: + mgr->autoMethod = CUDD_REORDER_WINDOW3_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW4_CONV: + mgr->autoMethod = CUDD_REORDER_WINDOW4_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_GROUP_SIFT: + mgr->autoMethod = CUDD_REORDER_GROUP_SIFT; + mgr->autoDyn = 1; + break; + case BDD_REORDER_GROUP_SIFT_CONV: + mgr->autoMethod = CUDD_REORDER_GROUP_SIFT_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_ANNEALING: + mgr->autoMethod = CUDD_REORDER_ANNEALING; + mgr->autoDyn = 1; + break; + case BDD_REORDER_GENETIC: + mgr->autoMethod = CUDD_REORDER_GENETIC; + mgr->autoDyn = 1; + break; + default: + fprintf(stderr,"CU DD Package: Reordering algorithm not considered\n"); + } + +} /* end of bdd_dynamic_reordering */ + + +/**Function******************************************************************** + + Synopsis [Calls reordering explicitly.] + + SideEffects [] + +******************************************************************************/ +void +bdd_reorder(mgr) +bdd_manager *mgr; +{ + (void) Cudd_ReduceHeap(mgr,mgr->autoMethod,10); /* 10 = whatever (Verbatim from file ddTable.c) */ + return; + +} /* end of bdd_reorder */ + + +/**Function******************************************************************** + + Synopsis [Read the number of reorderings the package has performed + so far.] + + SideEffects [] + +******************************************************************************/ +int +bdd_read_reorderings(mgr) +bdd_manager *mgr; +{ + return Cudd_ReadReorderings((DdManager *)mgr); + +} /* end of bdd_read_reorderings */ + + +/**Function******************************************************************** + + Synopsis [Gets the id variable for one level in the BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_variableId +bdd_get_id_from_level(mgr, level) +bdd_manager *mgr; +long level; +{ + return(mgr->invperm[level]); + +} /* end of bdd_get_id_from_level */ + + +/**Function******************************************************************** + + Synopsis [Gets the level of the top variable of the BDD.] + + SideEffects [] + +******************************************************************************/ +long +bdd_top_var_level(mgr, fn) +bdd_manager *mgr; +bdd_t *fn; +{ + return((long) cuddI(mgr,Cudd_Regular(fn->node)->index)); + +} /* end of bdd_top_var_level */ + + +/**Function******************************************************************** + + Synopsis [Returns TRUE if the argument BDD is a cube; FALSE + otherwise.] + + SideEffects [] + +******************************************************************************/ +boolean +bdd_is_cube(f) +bdd_t *f; +{ + struct DdManager *manager; + + if (f == NULL) { + fail("bdd_is_cube: invalid BDD"); + } + if (f->free) fail ("Freed BDD passed to bdd_is_cube"); + manager = (DdManager *) f->mgr; + return((boolean)cuddCheckCube(manager,f->node)); + +} /* end of bdd_is_cube */ + + +/**Function******************************************************************** + + Synopsis [Calls the garbage collector explicitly.] + + SideEffects [] + +******************************************************************************/ +void +bdd_gc(mgr) +bdd_manager *mgr; +{ + cuddGarbageCollect(mgr,1); + +} /* end of bdd_gc */ + + +/**Function******************************************************************** + + Synopsis [Computes the shared size of an array of BDDs.] + + Description [Computes the shared size of an array of BDDs. Returns + CUDD_OUT_OF_MEM in case of failure.] + + SideEffects [] + +******************************************************************************/ +long +bdd_size_multiple(bddArray) +array_t *bddArray; +{ + DdNode **nodeArray; + bdd_t *bddUnit; + long result; + int i; + + nodeArray = ALLOC(DdNode *, array_n(bddArray)); + if (nodeArray == NULL) return(CUDD_OUT_OF_MEM); + for (i = 0; i < array_n(bddArray); i++) { + bddUnit = array_fetch(bdd_t *, bddArray, i); + nodeArray[i] = bddUnit->node; + } + + result = Cudd_SharingSize(nodeArray,array_n(bddArray)); + + /* Clean up */ + FREE(nodeArray); + + return(result); + +} /* end of bdd_size_multiple */ + + +/**Function******************************************************************** + + Synopsis [Returns the first cube of the function. + A generator is also returned, which will iterate over the rest.] + + Description [Defines an iterator on the onset of a BDD. Two routines + are provided: bdd_first_cube, which extracts one cube from a BDD and + returns a bdd_gen structure containing the information necessary to + continue the enumeration; and bdd_next_cube, which returns 1 if + another cube was found, and 0 otherwise. A cube is represented as an + array of bdd_literal (which are integers in {0, 1, 2}), where 0 + represents negated literal, 1 for literal, and 2 for don't care. + Returns a disjoint cover. A third routine is there to clean up.] + + SideEffects [] + + SeeAlso [bdd_next_cube bdd_gen_free] + +******************************************************************************/ +bdd_gen * +bdd_first_cube(fn, cube) +bdd_t *fn; +array_t **cube; /* of bdd_literal */ +{ + bdd_manager *manager; + bdd_gen *gen; + int i; + int *icube; + CUDD_VALUE_TYPE value; + + /* Make sure we receive a valid bdd_t. (So to speak.) */ + assert(fn != 0); + + manager = fn->mgr; + + /* Initialize the generator. */ + gen = ALLOC(bdd_gen,1); + if (gen == NULL) return(NULL); + gen->manager = manager; + + gen->cube = array_alloc(bdd_literal, manager->size); + if (gen->cube == NULL) { + fail("Bdd Package: Out of memory in bdd_first_cube"); + } + + gen->ddGen = Cudd_FirstCube(manager,fn->node,&icube,&value); + if (gen->ddGen == NULL) { + fail("Cudd Package: Out of memory in bdd_first_cube"); + } + + if (!Cudd_IsGenEmpty(gen->ddGen)) { + /* Copy icube to the array_t cube. */ + for (i = 0; i < manager->size; i++) { + int myconst = icube[i]; + array_insert(bdd_literal, gen->cube, i, myconst); + } + *cube = gen->cube; + } + + return(gen); + +} /* end of bdd_first_cube */ + + +/**Function******************************************************************** + + Synopsis [Gets the next cube on the generator. Returns {TRUE, + FALSE} when {more, no more}.] + + SideEffects [] + + SeeAlso [bdd_first_cube bdd_gen_free] + +******************************************************************************/ +boolean +bdd_next_cube(gen, cube) +bdd_gen *gen; +array_t **cube; /* of bdd_literal */ +{ + int retval; + int *icube; + CUDD_VALUE_TYPE value; + int i; + + retval = Cudd_NextCube(gen->ddGen,&icube,&value); + if (!Cudd_IsGenEmpty(gen->ddGen)) { + /* Copy icube to the array_t cube. */ + for (i = 0; i < gen->manager->size; i++) { + int myconst = icube[i]; + array_insert(bdd_literal, gen->cube, i, myconst); + } + *cube = gen->cube; + } + + return(retval); + +} /* end of bdd_next_cube */ + + +/**Function******************************************************************** + + Synopsis [Gets the first node in the BDD and returns a generator.] + + SideEffects [] + + SeeAlso [bdd_next_node] + +******************************************************************************/ +bdd_gen * +bdd_first_node(fn, node) +bdd_t *fn; +bdd_node **node; /* return */ +{ + bdd_manager *manager; + bdd_gen *gen; + + /* Make sure we receive a valid bdd_t. (So to speak.) */ + assert(fn != 0); + + manager = fn->mgr; + + /* Initialize the generator. */ + gen = ALLOC(bdd_gen,1); + if (gen == NULL) return(NULL); + gen->manager = manager; + gen->cube = NULL; + + gen->ddGen = Cudd_FirstNode(manager,fn->node,node); + if (gen->ddGen == NULL) { + fail("Cudd Package: Out of memory in bdd_first_node"); + } + + return(gen); + +} /* end of bdd_first_node */ + + +/**Function******************************************************************** + + Synopsis [Gets the next node in the BDD. Returns {TRUE, FALSE} when + {more, no more}.] + + SideEffects [] + + SeeAlso [bdd_first_node] + +******************************************************************************/ +boolean +bdd_next_node(gen, node) +bdd_gen *gen; +bdd_node **node; /* return */ +{ + return(Cudd_NextNode(gen->ddGen,node)); + +} /* end of bdd_next_node */ + + +/**Function******************************************************************** + + Synopsis [Frees up the space used by the generator. Returns an int + so that it is easier to fit in a foreach macro. Returns 0 (to make it + easy to put in expressions).] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +bdd_gen_free(gen) +bdd_gen *gen; +{ + if (gen->cube != NULL) array_free(gen->cube); + Cudd_GenFree(gen->ddGen); + FREE(gen); + return(0); + +} /* end of bdd_gen_free */ + + +/**Function******************************************************************** + + Synopsis [Queries the status of a generator.] + + Description [Queries the status of a generator. Returns 1 if the + generator is empty or NULL; 0 otherswise.] + + SideEffects [] + + SeeAlso [bdd_first_cube bdd_next_cube bdd_first_node bdd_next_node + bdd_gen_free] + +******************************************************************************/ +boolean +bdd_is_gen_empty(gen) +bdd_gen *gen; +{ + return(Cudd_IsGenEmpty(gen->ddGen)); + +} /* end of bdd_is_gen_empty */ + + +/**Function******************************************************************** + + Synopsis [Function that creates a variable of a given index.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_var_with_index(manager, index) +bdd_manager *manager; +int index; +{ + DdNode *var; + + var = Cudd_bddIthVar(manager, index); + cuddRef(var); + return(bdd_construct_bdd_t(manager, var)); + +} /* end of bdd_var_with_index */ + + +/**Function******************************************************************** + + Synopsis [Temporary function that is empty.] + + SideEffects [] + +******************************************************************************/ +/*ARGSUSED*/ +void +bdd_new_var_block(f, n) +bdd_t *f; +long n; +{ + return; + +} /* end of bdd_new_var_block */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Builds the bdd_t structure.] + + Description [Builds the bdd_t structure from manager and node. + Assumes that the reference count of the node has already been + increased.] + + SideEffects [] + +******************************************************************************/ +static bdd_t * +bdd_construct_bdd_t(mgr,fn) +DdManager *mgr; +DdNode * fn; +{ + bdd_t *result; + + result = ALLOC(bdd_t, 1); + if (result == NULL) { + Cudd_RecursiveDeref(mgr,fn); + return(NULL); + } + result->mgr = mgr; + result->node = fn; + result->free = FALSE; + return(result); + +} /* end of bdd_construct_bdd_t */ diff --git a/resources/3rdparty/cudd-2.5.0/sis/cuddPwPt.c b/resources/3rdparty/cudd-2.5.0/sis/cuddPwPt.c new file mode 100644 index 000000000..823f7b966 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/sis/cuddPwPt.c @@ -0,0 +1,147 @@ +/**CFile*********************************************************************** + + FileName [cuddPwPt.c] + + PackageName [cudd] + + Synopsis [Emulation functions for the power package in SIS.] + + Description [This file contains functions that are necessary for the + power package in SIS. This package directly calls a few functions of + the CMU BDD package. Therefore, functions with identical names and + equivalent functionality are provided here. + External procedures included in this file: +
                    +
                  • cmu_bdd_zero() +
                  • cmu_bdd_one() +
                  • cmu_bdd_if_index() +
                  + Internal procedures included in this module: +
                    +
                  • +
                  ] + + Author [Fabio Somenzi] + + Copyright [This file was created at the University of Colorado at + Boulder. The University of Colorado at Boulder makes no warranty + about the suitability of this software for any purpose. It is + presented on an AS IS basis.] + +******************************************************************************/ + +#include "util.h" +#include "array.h" +#include "st.h" +#include "cuddInt.h" +#include "cuddBdd.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddPwPt.c,v 1.3 1997/01/18 19:43:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns a pointer to the one constant.] + + Description [Returns a pointer to the one constant. Used by the power + package in SIS. For new code, use Cudd_ReadOne instead.] + + SideEffects [None] + + SeeAlso [Cudd_ReadOne] + +******************************************************************************/ +bdd_node * +cmu_bdd_one(dd) +bdd_manager *dd; +{ + return((bdd_node *)((DdManager *)dd)->one); + +} /* end of cmu_bdd_one */ + + +/**Function******************************************************************** + + Synopsis [Returns a pointer to the zero constant.] + + Description [Returns a pointer to the zero constant. Used by the power + package in SIS. For new code, use Cudd_ReadZero instead.] + + SideEffects [None] + + SeeAlso [Cudd_ReadZero] + +******************************************************************************/ +bdd_node * +cmu_bdd_zero(dd) +bdd_manager *dd; +{ + return((bdd_node *)Cudd_Not(((DdManager *)dd)->one)); + +} /* end of cmu_bdd_zero */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the top variable in a BDD.] + + Description [Returns the index of the top variable in a BDD. Used by + the power package in SIS. For new code, use Cudd_ReadIndex instead.] + + SideEffects [None] + + SeeAlso [Cudd_ReadIndex] + +******************************************************************************/ +int +cmu_bdd_if_index(dd, node) +bdd_manager *dd; +bdd_node *node; +{ + return(Cudd_Regular(node)->index); + +} /* end of cmu_bdd_if_index */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/sis/st.c b/resources/3rdparty/cudd-2.5.0/sis/st.c new file mode 100644 index 000000000..426c79c5a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/sis/st.c @@ -0,0 +1,554 @@ +/* + * Revision Control Information + * + * /projects/hsis/CVS/utilities/st/st.c,v + * serdar + * 1.1 + * 1993/07/29 01:00:13 + * + */ +#include +#include "util.h" +#include "st.h" + +#define ST_NUMCMP(x,y) ((x) != (y)) +#define ST_NUMHASH(x,size) (ABS((long)x)%(size)) +#define ST_PTRHASH(x,size) ((int)((unsigned long)(x)>>2)%size) +#define EQUAL(func, x, y) \ + ((((func) == st_numcmp) || ((func) == st_ptrcmp)) ?\ + (ST_NUMCMP((x),(y)) == 0) : ((*func)((x), (y)) == 0)) + + +#define do_hash(key, table)\ + ((int)((table->hash == st_ptrhash) ? ST_PTRHASH((key),(table)->num_bins) :\ + (table->hash == st_numhash) ? ST_NUMHASH((key), (table)->num_bins) :\ + (*table->hash)((key), (table)->num_bins))) + +static int rehash (st_table *); + +st_table * +st_init_table_with_params( + ST_PFICPCP compare, + ST_PFICPI hash, + int size, + int density, + double grow_factor, + int reorder_flag) +{ + int i; + st_table *newt; + + newt = ALLOC(st_table, 1); + if (newt == NIL(st_table)) { + return NIL(st_table); + } + newt->compare = (int (*)(const char *, const char *)) compare; + newt->hash = (int (*)(char *, int)) hash; + newt->num_entries = 0; + newt->max_density = density; + newt->grow_factor = grow_factor; + newt->reorder_flag = reorder_flag; + if (size <= 0) { + size = 1; + } + newt->num_bins = size; + newt->bins = ALLOC(st_table_entry *, size); + if (newt->bins == NIL(st_table_entry *)) { + FREE(newt); + return NIL(st_table); + } + for(i = 0; i < size; i++) { + newt->bins[i] = 0; + } + return newt; +} + +st_table * +st_init_table(ST_PFICPCP compare, ST_PFICPI hash) +{ + return st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE, + ST_DEFAULT_MAX_DENSITY, + ST_DEFAULT_GROW_FACTOR, + ST_DEFAULT_REORDER_FLAG); +} + +void +st_free_table(st_table *table) +{ + register st_table_entry *ptr, *next; + int i; + + for(i = 0; i < table->num_bins ; i++) { + ptr = table->bins[i]; + while (ptr != NIL(st_table_entry)) { + next = ptr->next; + FREE(ptr); + ptr = next; + } + } + FREE(table->bins); + FREE(table); +} + +#define PTR_NOT_EQUAL(table, ptr, user_key)\ +(ptr != NULL && !EQUAL(table->compare, user_key, (ptr)->key)) + +#define FIND_ENTRY(table, hash_val, key, ptr, last) \ + (last) = &(table)->bins[hash_val];\ + (ptr) = *(last);\ + while (PTR_NOT_EQUAL((table), (ptr), (key))) {\ + (last) = &(ptr)->next; (ptr) = *(last);\ + }\ + if ((ptr) != NULL && (table)->reorder_flag) {\ + *(last) = (ptr)->next;\ + (ptr)->next = (table)->bins[hash_val];\ + (table)->bins[hash_val] = (ptr);\ + } + +int +st_lookup(st_table *table, char *key, char **value) +{ + int hash_val; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (value != NIL(char *)) { + *value = ptr->record; + } + return 1; + } +} + +int +st_lookup_int(st_table *table, char *key, int *value) +{ + int hash_val; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (value != NIL(int)) { + *value = (int) (util_ptrint) ptr->record; + } + return 1; + } +} + +/* This macro does not check if memory allocation fails. Use at you own risk */ +#define ADD_DIRECT(table, key, value, hash_val, newt)\ +{\ + if (table->num_entries/table->num_bins >= table->max_density) {\ + rehash(table);\ + hash_val = do_hash(key,table);\ + }\ + \ + newt = ALLOC(st_table_entry, 1);\ + \ + newt->key = key;\ + newt->record = value;\ + newt->next = table->bins[hash_val];\ + table->bins[hash_val] = newt;\ + table->num_entries++;\ +} + +int +st_insert(st_table *table, char *key, char *value) +{ + int hash_val; + st_table_entry *newt; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + if (table->num_entries/table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + hash_val = do_hash(key, table); + } + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = key; + newt->record = value; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + return 0; + } else { + ptr->record = value; + return 1; + } +} + +int +st_add_direct(st_table *table, char *key, char *value) +{ + int hash_val; + st_table_entry *newt; + + hash_val = do_hash(key, table); + if (table->num_entries / table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + } + hash_val = do_hash(key, table); + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = key; + newt->record = value; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + return 1; +} + +int +st_find_or_add(st_table *table, char *key, char ***slot) +{ + int hash_val; + st_table_entry *newt, *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + if (table->num_entries / table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + hash_val = do_hash(key, table); + } + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = key; + newt->record = (char *) 0; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + if (slot != NIL(char **)) *slot = &newt->record; + return 0; + } else { + if (slot != NIL(char **)) *slot = &ptr->record; + return 1; + } +} + +int +st_find(st_table *table, char *key, char ***slot) +{ + int hash_val; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (slot != NIL(char **)) { + *slot = &ptr->record; + } + return 1; + } +} + +static int +rehash(st_table *table) +{ + register st_table_entry *ptr, *next, **old_bins; + int i, old_num_bins, hash_val, old_num_entries; + + /* save old values */ + old_bins = table->bins; + old_num_bins = table->num_bins; + old_num_entries = table->num_entries; + + /* rehash */ + table->num_bins = (int) (table->grow_factor * old_num_bins); + if (table->num_bins % 2 == 0) { + table->num_bins += 1; + } + table->num_entries = 0; + table->bins = ALLOC(st_table_entry *, table->num_bins); + if (table->bins == NIL(st_table_entry *)) { + table->bins = old_bins; + table->num_bins = old_num_bins; + table->num_entries = old_num_entries; + return ST_OUT_OF_MEM; + } + /* initialize */ + for (i = 0; i < table->num_bins; i++) { + table->bins[i] = 0; + } + + /* copy data over */ + for (i = 0; i < old_num_bins; i++) { + ptr = old_bins[i]; + while (ptr != NIL(st_table_entry)) { + next = ptr->next; + hash_val = do_hash(ptr->key, table); + ptr->next = table->bins[hash_val]; + table->bins[hash_val] = ptr; + table->num_entries++; + ptr = next; + } + } + FREE(old_bins); + + return 1; +} + +st_table * +st_copy(st_table *old_table) +{ + st_table *new_table; + st_table_entry *ptr, *newptr, *next, *newt; + int i, j, num_bins = old_table->num_bins; + + new_table = ALLOC(st_table, 1); + if (new_table == NIL(st_table)) { + return NIL(st_table); + } + + *new_table = *old_table; + new_table->bins = ALLOC(st_table_entry *, num_bins); + if (new_table->bins == NIL(st_table_entry *)) { + FREE(new_table); + return NIL(st_table); + } + for(i = 0; i < num_bins ; i++) { + new_table->bins[i] = NIL(st_table_entry); + ptr = old_table->bins[i]; + while (ptr != NIL(st_table_entry)) { + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + for (j = 0; j <= i; j++) { + newptr = new_table->bins[j]; + while (newptr != NIL(st_table_entry)) { + next = newptr->next; + FREE(newptr); + newptr = next; + } + } + FREE(new_table->bins); + FREE(new_table); + return NIL(st_table); + } + *newt = *ptr; + newt->next = new_table->bins[i]; + new_table->bins[i] = newt; + ptr = ptr->next; + } + } + return new_table; +} + +int +st_delete(st_table *table, char **keyp, char **value) +{ + int hash_val; + char *key = *keyp; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr ,last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } + + *last = ptr->next; + if (value != NIL(char *)) *value = ptr->record; + *keyp = ptr->key; + FREE(ptr); + table->num_entries--; + return 1; +} + +int +st_delete_int(st_table *table, int *keyp, char **value) +{ + int hash_val; + char *key = (char *) (util_ptrint) *keyp; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr ,last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } + + *last = ptr->next; + if (value != NIL(char *)) *value = ptr->record; + *keyp = (int) (util_ptrint) ptr->key; + FREE(ptr); + table->num_entries--; + return 1; +} + +int +st_foreach(st_table *table, ST_PFSR func, char *arg) +{ + st_table_entry *ptr, **last; + enum st_retval retval; + int i; + + for(i = 0; i < table->num_bins; i++) { + last = &table->bins[i]; ptr = *last; + while (ptr != NIL(st_table_entry)) { + retval = (*func)(ptr->key, ptr->record, arg); + switch (retval) { + case ST_CONTINUE: + last = &ptr->next; ptr = *last; + break; + case ST_STOP: + return 0; + case ST_DELETE: + *last = ptr->next; + table->num_entries--; /* cstevens@ic */ + FREE(ptr); + ptr = *last; + } + } + } + return 1; +} + +int +st_strhash(char *string, int modulus) +{ + register int val = 0; + register int c; + + while ((c = *string++) != '\0') { + val = val*997 + c; + } + + return ((val < 0) ? -val : val)%modulus; +} + +int +st_numhash(char *x, int size) +{ + return ST_NUMHASH(x, size); +} + +int +st_ptrhash(char *x, int size) +{ + return ST_PTRHASH(x, size); +} + +int +st_numcmp(const char *x, const char *y) +{ + return ST_NUMCMP(x, y); +} + +int +st_ptrcmp(const char *x, const char *y) +{ + return ST_NUMCMP(x, y); +} + +st_generator * +st_init_gen(st_table *table) +{ + st_generator *gen; + + gen = ALLOC(st_generator, 1); + if (gen == NIL(st_generator)) { + return NIL(st_generator); + } + gen->table = table; + gen->entry = NIL(st_table_entry); + gen->index = 0; + return gen; +} + + +int +st_gen(st_generator *gen, char **key_p, char **value_p) +{ + register int i; + + if (gen->entry == NIL(st_table_entry)) { + /* try to find next entry */ + for(i = gen->index; i < gen->table->num_bins; i++) { + if (gen->table->bins[i] != NIL(st_table_entry)) { + gen->index = i+1; + gen->entry = gen->table->bins[i]; + break; + } + } + if (gen->entry == NIL(st_table_entry)) { + return 0; /* that's all folks ! */ + } + } + *key_p = gen->entry->key; + if (value_p != 0) { + *value_p = gen->entry->record; + } + gen->entry = gen->entry->next; + return 1; +} + + +int +st_gen_int(st_generator *gen, char **key_p, long *value_p) +{ + register int i; + + if (gen->entry == NIL(st_table_entry)) { + /* try to find next entry */ + for(i = gen->index; i < gen->table->num_bins; i++) { + if (gen->table->bins[i] != NIL(st_table_entry)) { + gen->index = i+1; + gen->entry = gen->table->bins[i]; + break; + } + } + if (gen->entry == NIL(st_table_entry)) { + return 0; /* that's all folks ! */ + } + } + *key_p = gen->entry->key; + if (value_p != NIL(long)) { + *value_p = (long) gen->entry->record; + } + gen->entry = gen->entry->next; + return 1; +} + + +void +st_free_gen(st_generator *gen) +{ + FREE(gen); +} diff --git a/resources/3rdparty/cudd-2.5.0/sis/st.h b/resources/3rdparty/cudd-2.5.0/sis/st.h new file mode 100644 index 000000000..a1d86192e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/sis/st.h @@ -0,0 +1,97 @@ +/* + * Revision Control Information + * + * /projects/hsis/CVS/utilities/st/st.h,v + * serdar + * 1.1 + * 1993/07/29 01:00:21 + * + */ +/* LINTLIBRARY */ + +/* /projects/hsis/CVS/utilities/st/st.h,v 1.1 1993/07/29 01:00:21 serdar Exp */ + +#ifndef ST_INCLUDED +#define ST_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct st_table_entry st_table_entry; +struct st_table_entry { + char *key; + char *record; + st_table_entry *next; +}; + +typedef struct st_table st_table; +struct st_table { + int (*compare)(const char *, const char *); + int (*hash)(char *, int); + int num_bins; + int num_entries; + int max_density; + int reorder_flag; + double grow_factor; + st_table_entry **bins; +}; + +typedef struct st_generator st_generator; +struct st_generator { + st_table *table; + st_table_entry *entry; + int index; +}; + +#define st_is_member(table,key) st_lookup(table,key,(char **) 0) +#define st_count(table) ((table)->num_entries) + +enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE}; + +typedef enum st_retval (*ST_PFSR)(char *, char *, char *); +typedef int (*ST_PFICPCP)(const char *, const char *); /* type for comparison function */ +typedef int (*ST_PFICPI)(char *, int); /* type for hash function */ + +extern st_table *st_init_table_with_params (ST_PFICPCP, ST_PFICPI, int, int, double, int); +extern st_table *st_init_table (ST_PFICPCP, ST_PFICPI); +extern void st_free_table (st_table *); +extern int st_lookup (st_table *, char *, char **); +extern int st_lookup_int (st_table *, char *, int *); +extern int st_insert (st_table *, char *, char *); +extern int st_add_direct (st_table *, char *, char *); +extern int st_find_or_add (st_table *, char *, char ***); +extern int st_find (st_table *, char *, char ***); +extern st_table *st_copy (st_table *); +extern int st_delete (st_table *, char **, char **); +extern int st_delete_int (st_table *, int *, char **); +extern int st_foreach (st_table *, ST_PFSR, char *); +extern int st_strhash (char *, int); +extern int st_numhash (char *, int); +extern int st_ptrhash (char *, int); +extern int st_numcmp (const char *, const char *); +extern int st_ptrcmp (const char *, const char *); +extern st_generator *st_init_gen (st_table *); +extern int st_gen (st_generator *, char **, char **); +extern int st_gen_int (st_generator *, char **, long *); +extern void st_free_gen (st_generator *); + + +#define ST_DEFAULT_MAX_DENSITY 5 +#define ST_DEFAULT_INIT_TABLE_SIZE 11 +#define ST_DEFAULT_GROW_FACTOR 2.0 +#define ST_DEFAULT_REORDER_FLAG 0 + +#define st_foreach_item(table, gen, key, value) \ + for(gen=st_init_gen(table); st_gen(gen,key,value) || (st_free_gen(gen),0);) + +#define st_foreach_item_int(table, gen, key, value) \ + for(gen=st_init_gen(table); st_gen_int(gen,key,value) || (st_free_gen(gen),0);) + +#define ST_OUT_OF_MEM -10000 + +#ifdef __cplusplus +} +#endif + +#endif /* ST_INCLUDED */ diff --git a/resources/3rdparty/cudd-2.5.0/st/Makefile b/resources/3rdparty/cudd-2.5.0/st/Makefile new file mode 100644 index 000000000..5fdc949c6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/Makefile @@ -0,0 +1,64 @@ +# $Id: Makefile,v 1.3 2004/01/01 06:53:06 fabio Exp fabio $ +# +# st -- hash table package +#--------------------------------------------------------------------------- +.SUFFIXES: .c .o .u + +CC = gcc +RANLIB = ranlib + +MFLAG = +ICFLAGS = -g -O6 -Wall +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) + +LINTFLAGS = -u -n + +# this is to create the lint library +LINTSWITCH = -o + +P = st +PSRC = st.c +PHDR = st.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) + +WHERE = .. +INCLUDE = $(WHERE)/include + +#--------------------------- + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +clean: + rm -f *.o *.u .pure *.warnings + +distclean: clean + rm -f lib*.a lib$(P).b llib-l$(P).ln tags *~ *.bak *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/st/doc/stAllAbs.html b/resources/3rdparty/cudd-2.5.0/st/doc/stAllAbs.html new file mode 100644 index 000000000..927c116bc --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/doc/stAllAbs.html @@ -0,0 +1,96 @@ + +st package abstract (Internal) + + +

                  st package abstract (Internal)

                  +

                  +
                  + + + +
                  +
                  st_add_direct() +
                  Place 'value' in 'table' under the key 'key'. + +
                  st_copy() +
                  Return a copy of old_table and all its members. + +
                  st_count() +
                  Returns the number of entries in the table `table'. + +
                  st_delete_int() +
                  Delete the entry with the key pointed to by `keyp'. + +
                  st_delete() +
                  Delete the entry with the key pointed to by `keyp'. + +
                  st_find_or_add() +
                  Lookup `key' in `table'. + +
                  st_find() +
                  Lookup `key' in `table'. + +
                  st_foreach_item_int() +
                  Iteration macro. + +
                  st_foreach_item() +
                  Iteration macro. + +
                  st_foreach() +
                  Iterates over the elements of a table. + +
                  st_free_gen() +
                  Reclaims the resources associated with `gen'. + +
                  st_free_table() +
                  Free a table. + +
                  st_gen_int() +
                  Returns the next (key, value) pair in the generation sequence. + +
                  st_gen() +
                  returns the next (key, value) pair in the generation sequence. + +
                  st_init_gen() +
                  Initializes a generator. + +
                  st_init_table_with_params() +
                  Create a table with given parameters. + +
                  st_init_table() +
                  Create and initialize a table. + +
                  st_insert() +
                  Insert value in table under the key 'key'. + +
                  st_is_member() +
                  Checks whethere `key' is in `table'. + +
                  st_lookup_int() +
                  Lookup up `key' in `table'. + +
                  st_lookup() +
                  Lookup up `key' in `table'. + +
                  st_numcmp() +
                  Number comparison function. + +
                  st_numhash() +
                  Number hash function. + +
                  st_ptrcmp() +
                  Pointer comparison function. + +
                  st_ptrhash() +
                  Pointer hash function. + +
                  st_strhash() +
                  String hash function. + +
                  + +
                  + +Generated automatically by extdoc on 20040102 + + diff --git a/resources/3rdparty/cudd-2.5.0/st/doc/stAllDet.html b/resources/3rdparty/cudd-2.5.0/st/doc/stAllDet.html new file mode 100644 index 000000000..e56d8834d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/doc/stAllDet.html @@ -0,0 +1,462 @@ + +The st package (Internal) + + +

                  The st package (Internal)

                  +

                  +

                  +
                  + + +
                  + + + + + +
                  + + +
                  + +
                  +int 
                  +st_add_direct(
                  +  st_table * table, 
                  +  void * key, 
                  +  void * value 
                  +)
                  +
                  +
                  Place 'value' in 'table' under the key 'key'. This is done without checking if 'key' is in 'table' already. This should only be used if you are sure there is not already an entry for 'key', since it is undefined which entry you would later get from st_lookup or st_find_or_add. Returns 1 if successful; ST_OUT_OF_MEM otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +st_table * 
                  +st_copy(
                  +  st_table * old_table 
                  +)
                  +
                  +
                  Return a copy of old_table and all its members. (st_table *) 0 is returned if there was insufficient memory to do the copy. +

                  + +

                  Side Effects None +

                  + +

                  + 
                  +st_count(
                  +   table 
                  +)
                  +
                  +
                  Returns the number of entries in the table `table'. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +st_delete_int(
                  +  st_table * table, 
                  +  void * keyp, 
                  +  int * value 
                  +)
                  +
                  +
                  Delete the entry with the key pointed to by `keyp'. `value' must be a pointer to an integer. If the entry is found, 1 is returned, the variable pointed by `keyp' is set to the actual key and the variable pointed by `value' is set to the corresponding entry. (This allows the freeing of the associated storage.) If the entry is not found, then 0 is returned and nothing is changed. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_delete + + +
                  +int 
                  +st_delete(
                  +  st_table * table, 
                  +  void * keyp, 
                  +  void * value 
                  +)
                  +
                  +
                  Delete the entry with the key pointed to by `keyp'. If the entry is found, 1 is returned, the variable pointed by `keyp' is set to the actual key and the variable pointed by `value' is set to the corresponding entry. (This allows the freeing of the associated storage.) If the entry is not found, then 0 is returned and nothing is changed. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_delete_int + + +
                  +int 
                  +st_find_or_add(
                  +  st_table * table, 
                  +  void * key, 
                  +  void * slot 
                  +)
                  +
                  +
                  Lookup `key' in `table'. If not found, create an entry. In either case set slot to point to the field in the entry where the value is stored. The value associated with `key' may then be changed by accessing directly through slot. Returns 1 if an entry already existed, 0 if it did not exist and creation was successful; ST_OUT_OF_MEM otherwise. As an example:
                   char **slot; 
                   char *key; 
                   char *value = (char *) item_ptr <-- ptr to a malloc'd structure 
                   if (st_find_or_add(table, key, &slot) == 1) { 
                   FREE(*slot); <-- free the old value of the record 
                   } 
                   *slot = value; <-- attach the new value to the record 
                  This replaces the equivelent code:
                   if (st_lookup(table, key, &ovalue) == 1) { 
                   FREE(ovalue); 
                   } 
                   st_insert(table, key, value); 
                  +

                  + +

                  Side Effects None +

                  + +

                  See Also st_find + + +
                  +int 
                  +st_find(
                  +  st_table * table, 
                  +  void * key, 
                  +  void * slot 
                  +)
                  +
                  +
                  Like st_find_or_add, but does not create an entry if one is not found. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_find_or_add + + +
                  + 
                  +st_foreach_item_int(
                  +   table, 
                  +   gen, 
                  +   key, 
                  +   value 
                  +)
                  +
                  +
                  An iteration macro which loops over all the entries in `table', setting `key' to point to the key and `value' to the associated value (if it is not nil). `value' is assumed to be a pointer to an integer. `gen' is a generator variable used internally. Sample usage:
                   char *key; 
                   int value; 
                   st_generator *gen; 
                   st_foreach_item_int(table, gen, &key, &value) { 
                   process_item(value); 
                   } 
                  +

                  + +

                  Side Effects None +

                  + +

                  See Also st_foreach_item +st_foreach + + +
                  + 
                  +st_foreach_item(
                  +   table, 
                  +   gen, 
                  +   key, 
                  +   value 
                  +)
                  +
                  +
                  An iteration macro which loops over all the entries in `table', setting `key' to point to the key and `value' to the associated value (if it is not nil). `gen' is a generator variable used internally. Sample usage:
                   char *key, *value; 
                   st_generator *gen; 
                   st_foreach_item(table, gen, &key, &value) { 
                   process_item(value); 
                   } 
                  +

                  + +

                  Side Effects None +

                  + +

                  See Also st_foreach_item_int +st_foreach + + +
                  +int 
                  +st_foreach(
                  +  st_table * table, 
                  +  ST_PFSR  func, 
                  +  char * arg 
                  +)
                  +
                  +
                  For each (key, value) record in `table', st_foreach call func with the arguments
                   (*func)(key, value, arg) 
                  If func returns ST_CONTINUE, st_foreach continues processing entries. If func returns ST_STOP, st_foreach stops processing and returns immediately. If func returns ST_DELETE, then the entry is deleted from the symbol table and st_foreach continues. In the case of ST_DELETE, it is func's responsibility to free the key and value, if necessary.

                  The routine returns 1 if all items in the table were generated and 0 if the generation sequence was aborted using ST_STOP. The order in which the records are visited will be seemingly random. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_foreach_item +st_foreach_item_int + + +
                  +void 
                  +st_free_gen(
                  +  st_generator * gen 
                  +)
                  +
                  +
                  After generating all items in a generation sequence, this routine must be called to reclaim the resources associated with `gen'. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_gen + + +
                  +void 
                  +st_free_table(
                  +  st_table * table 
                  +)
                  +
                  +
                  Any internal storage associated with table is freed. It is the user's responsibility to free any storage associated with the pointers he placed in the table (by perhaps using st_foreach). +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table +st_init_table_with_params + + +
                  +int 
                  +st_gen_int(
                  +  st_generator * gen, 
                  +  void * key_p, 
                  +  int * value_p 
                  +)
                  +
                  +
                  Given a generator returned by st_init_gen(), this routine returns the next (key, value) pair in the generation sequence. `value_p' must be a pointer to an integer. The pointer `value_p' can be zero which means no value will be returned. When there are no more items in the generation sequence, the routine returns 0. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_gen + + +
                  +int 
                  +st_gen(
                  +  st_generator * gen, 
                  +  void * key_p, 
                  +  void * value_p 
                  +)
                  +
                  +
                  Given a generator returned by st_init_gen(), this routine returns the next (key, value) pair in the generation sequence. The pointer `value_p' can be zero which means no value will be returned. When there are no more items in the generation sequence, the routine returns 0. While using a generation sequence, deleting any (key, value) pair other than the one just generated may cause a fatal error when st_gen() is called later in the sequence and is therefore not recommended. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_gen_int + + +
                  +st_generator * 
                  +st_init_gen(
                  +  st_table * table 
                  +)
                  +
                  +
                  Returns a generator handle which when used with st_gen() will progressively return each (key, value) record in `table'. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_free_gen + + +
                  +st_table * 
                  +st_init_table_with_params(
                  +  ST_PFICPCP  compare, 
                  +  ST_PFICPI  hash, 
                  +  int  size, 
                  +  int  density, 
                  +  double  grow_factor, 
                  +  int  reorder_flag 
                  +)
                  +
                  +
                  The full blown table initializer. compare and hash are the same as in st_init_table. density is the largest the average number of entries per hash bin there should be before the table is grown. grow_factor is the factor the table is grown by when it becomes too full. size is the initial number of bins to be allocated for the hash table. If reorder_flag is non-zero, then every time an entry is found, it is moved to the top of the chain.

                  st_init_table(compare, hash) is equivelent to

                   st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE, ST_DEFAULT_MAX_DENSITY, ST_DEFAULT_GROW_FACTOR, ST_DEFAULT_REORDER_FLAG); 
                  +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table +st_free_table + + +
                  +st_table * 
                  +st_init_table(
                  +  ST_PFICPCP  compare, 
                  +  ST_PFICPI  hash 
                  +)
                  +
                  +
                  Create and initialize a table with the comparison function compare_fn and hash function hash_fn. compare_fn is
                   int compare_fn(const char *key1, const char *key2) 
                  It returns <,=,> 0 depending on whether key1 <,=,> key2 by some measure.

                  hash_fn is

                   int hash_fn(char *key, int modulus) 
                  It returns a integer between 0 and modulus-1 such that if compare_fn(key1,key2) == 0 then hash_fn(key1) == hash_fn(key2).

                  There are five predefined hash and comparison functions in st. For keys as numbers:

                   st_numhash(key, modulus) { return (unsigned int) key % modulus; } 
                   st_numcmp(x,y) { return (int) x - (int) y; } 
                  For keys as pointers:
                   st_ptrhash(key, modulus) { return ((unsigned int) key/4) % modulus } 
                   st_ptrcmp(x,y) { return (int) x - (int) y; } 
                  For keys as strings:
                   st_strhash(x,y) - a reasonable hashing function for strings 
                   strcmp(x,y) - the standard library function 
                  It is recommended to use these particular functions if they fit your needs, since st will recognize certain of them and run more quickly because of it. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table_with_params +st_free_table + + +
                  +int 
                  +st_insert(
                  +  st_table * table, 
                  +  void * key, 
                  +  void * value 
                  +)
                  +
                  +
                  Insert value in table under the key 'key'. Returns 1 if there was an entry already under the key; 0 if there was no entry under the key and insertion was successful; ST_OUT_OF_MEM otherwise. In either of the first two cases the new value is added. +

                  + +

                  Side Effects None +

                  + +

                  + 
                  +st_is_member(
                  +   table, 
                  +   key 
                  +)
                  +
                  +
                  Returns 1 if there is an entry under `key' in `table', 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_lookup + + +
                  +int 
                  +st_lookup_int(
                  +  st_table * table, 
                  +  void * key, 
                  +  int * value 
                  +)
                  +
                  +
                  Lookup up `key' in `table'. If an entry is found, 1 is returned and if `value' is not nil, the variable it points to is set to the associated integer value. If an entry is not found, 0 is return and the variable pointed by `value' is unchanged. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_lookup + + +
                  +int 
                  +st_lookup(
                  +  st_table * table, 
                  +  void * key, 
                  +  void * value 
                  +)
                  +
                  +
                  Lookup up `key' in `table'. If an entry is found, 1 is returned and if `value' is not nil, the variable it points to is set to the associated value. If an entry is not found, 0 is returned and the variable pointed by value is unchanged. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_lookup_int + + +
                  +int 
                  +st_numcmp(
                  +  const char * x, 
                  +  const char * y 
                  +)
                  +
                  +
                  integer number comparison function. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table +st_numhash + + +
                  +int 
                  +st_numhash(
                  +  char * x, 
                  +  int  size 
                  +)
                  +
                  +
                  Integer number hash function. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table +st_numcmp + + +
                  +int 
                  +st_ptrcmp(
                  +  const char * x, 
                  +  const char * y 
                  +)
                  +
                  +
                  Pointer comparison function. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table +st_ptrhash + + +
                  +int 
                  +st_ptrhash(
                  +  char * x, 
                  +  int  size 
                  +)
                  +
                  +
                  Pointer hash function. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table +st_ptrcmp + + +
                  +int 
                  +st_strhash(
                  +  char * string, 
                  +  int  modulus 
                  +)
                  +
                  +
                  String hash function. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table + + + +
                  + +
                  + +Generated automatically by extdoc on 20040102 + + diff --git a/resources/3rdparty/cudd-2.5.0/st/doc/stExtAbs.html b/resources/3rdparty/cudd-2.5.0/st/doc/stExtAbs.html new file mode 100644 index 000000000..5302461fa --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/doc/stExtAbs.html @@ -0,0 +1,96 @@ + +st package abstract + + +

                  st package abstract

                  +

                  Symbol table package.

                  +
                  + + + +
                  +
                  st_add_direct() +
                  Place 'value' in 'table' under the key 'key'. + +
                  st_copy() +
                  Return a copy of old_table and all its members. + +
                  st_count() +
                  Returns the number of entries in the table `table'. + +
                  st_delete_int() +
                  Delete the entry with the key pointed to by `keyp'. + +
                  st_delete() +
                  Delete the entry with the key pointed to by `keyp'. + +
                  st_find_or_add() +
                  Lookup `key' in `table'. + +
                  st_find() +
                  Lookup `key' in `table'. + +
                  st_foreach_item_int() +
                  Iteration macro. + +
                  st_foreach_item() +
                  Iteration macro. + +
                  st_foreach() +
                  Iterates over the elements of a table. + +
                  st_free_gen() +
                  Reclaims the resources associated with `gen'. + +
                  st_free_table() +
                  Free a table. + +
                  st_gen_int() +
                  Returns the next (key, value) pair in the generation sequence. + +
                  st_gen() +
                  returns the next (key, value) pair in the generation sequence. + +
                  st_init_gen() +
                  Initializes a generator. + +
                  st_init_table_with_params() +
                  Create a table with given parameters. + +
                  st_init_table() +
                  Create and initialize a table. + +
                  st_insert() +
                  Insert value in table under the key 'key'. + +
                  st_is_member() +
                  Checks whethere `key' is in `table'. + +
                  st_lookup_int() +
                  Lookup up `key' in `table'. + +
                  st_lookup() +
                  Lookup up `key' in `table'. + +
                  st_numcmp() +
                  Number comparison function. + +
                  st_numhash() +
                  Number hash function. + +
                  st_ptrcmp() +
                  Pointer comparison function. + +
                  st_ptrhash() +
                  Pointer hash function. + +
                  st_strhash() +
                  String hash function. + +
                  + +
                  + +Generated automatically by extdoc on 20040102 + + diff --git a/resources/3rdparty/cudd-2.5.0/st/doc/stExtDet.html b/resources/3rdparty/cudd-2.5.0/st/doc/stExtDet.html new file mode 100644 index 000000000..43cb6f464 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/doc/stExtDet.html @@ -0,0 +1,463 @@ + +The st package + + +

                  The st package

                  +

                  Symbol table package.

                  +

                  +
                  + + +
                  + + +The st library provides functions to create, maintain, + and query symbol tables. + + +
                  + + +
                  + +
                  +int 
                  +st_add_direct(
                  +  st_table * table, 
                  +  void * key, 
                  +  void * value 
                  +)
                  +
                  +
                  Place 'value' in 'table' under the key 'key'. This is done without checking if 'key' is in 'table' already. This should only be used if you are sure there is not already an entry for 'key', since it is undefined which entry you would later get from st_lookup or st_find_or_add. Returns 1 if successful; ST_OUT_OF_MEM otherwise. +

                  + +

                  Side Effects None +

                  + +

                  +st_table * 
                  +st_copy(
                  +  st_table * old_table 
                  +)
                  +
                  +
                  Return a copy of old_table and all its members. (st_table *) 0 is returned if there was insufficient memory to do the copy. +

                  + +

                  Side Effects None +

                  + +

                  + 
                  +st_count(
                  +   table 
                  +)
                  +
                  +
                  Returns the number of entries in the table `table'. +

                  + +

                  Side Effects None +

                  + +

                  +int 
                  +st_delete_int(
                  +  st_table * table, 
                  +  void * keyp, 
                  +  int * value 
                  +)
                  +
                  +
                  Delete the entry with the key pointed to by `keyp'. `value' must be a pointer to an integer. If the entry is found, 1 is returned, the variable pointed by `keyp' is set to the actual key and the variable pointed by `value' is set to the corresponding entry. (This allows the freeing of the associated storage.) If the entry is not found, then 0 is returned and nothing is changed. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_delete + + +
                  +int 
                  +st_delete(
                  +  st_table * table, 
                  +  void * keyp, 
                  +  void * value 
                  +)
                  +
                  +
                  Delete the entry with the key pointed to by `keyp'. If the entry is found, 1 is returned, the variable pointed by `keyp' is set to the actual key and the variable pointed by `value' is set to the corresponding entry. (This allows the freeing of the associated storage.) If the entry is not found, then 0 is returned and nothing is changed. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_delete_int + + +
                  +int 
                  +st_find_or_add(
                  +  st_table * table, 
                  +  void * key, 
                  +  void * slot 
                  +)
                  +
                  +
                  Lookup `key' in `table'. If not found, create an entry. In either case set slot to point to the field in the entry where the value is stored. The value associated with `key' may then be changed by accessing directly through slot. Returns 1 if an entry already existed, 0 if it did not exist and creation was successful; ST_OUT_OF_MEM otherwise. As an example:
                   char **slot; 
                   char *key; 
                   char *value = (char *) item_ptr <-- ptr to a malloc'd structure 
                   if (st_find_or_add(table, key, &slot) == 1) { 
                   FREE(*slot); <-- free the old value of the record 
                   } 
                   *slot = value; <-- attach the new value to the record 
                  This replaces the equivelent code:
                   if (st_lookup(table, key, &ovalue) == 1) { 
                   FREE(ovalue); 
                   } 
                   st_insert(table, key, value); 
                  +

                  + +

                  Side Effects None +

                  + +

                  See Also st_find + + +
                  +int 
                  +st_find(
                  +  st_table * table, 
                  +  void * key, 
                  +  void * slot 
                  +)
                  +
                  +
                  Like st_find_or_add, but does not create an entry if one is not found. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_find_or_add + + +
                  + 
                  +st_foreach_item_int(
                  +   table, 
                  +   gen, 
                  +   key, 
                  +   value 
                  +)
                  +
                  +
                  An iteration macro which loops over all the entries in `table', setting `key' to point to the key and `value' to the associated value (if it is not nil). `value' is assumed to be a pointer to an integer. `gen' is a generator variable used internally. Sample usage:
                   char *key; 
                   int value; 
                   st_generator *gen; 
                   st_foreach_item_int(table, gen, &key, &value) { 
                   process_item(value); 
                   } 
                  +

                  + +

                  Side Effects None +

                  + +

                  See Also st_foreach_item +st_foreach + + +
                  + 
                  +st_foreach_item(
                  +   table, 
                  +   gen, 
                  +   key, 
                  +   value 
                  +)
                  +
                  +
                  An iteration macro which loops over all the entries in `table', setting `key' to point to the key and `value' to the associated value (if it is not nil). `gen' is a generator variable used internally. Sample usage:
                   char *key, *value; 
                   st_generator *gen; 
                   st_foreach_item(table, gen, &key, &value) { 
                   process_item(value); 
                   } 
                  +

                  + +

                  Side Effects None +

                  + +

                  See Also st_foreach_item_int +st_foreach + + +
                  +int 
                  +st_foreach(
                  +  st_table * table, 
                  +  ST_PFSR  func, 
                  +  char * arg 
                  +)
                  +
                  +
                  For each (key, value) record in `table', st_foreach call func with the arguments
                   (*func)(key, value, arg) 
                  If func returns ST_CONTINUE, st_foreach continues processing entries. If func returns ST_STOP, st_foreach stops processing and returns immediately. If func returns ST_DELETE, then the entry is deleted from the symbol table and st_foreach continues. In the case of ST_DELETE, it is func's responsibility to free the key and value, if necessary.

                  The routine returns 1 if all items in the table were generated and 0 if the generation sequence was aborted using ST_STOP. The order in which the records are visited will be seemingly random. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_foreach_item +st_foreach_item_int + + +
                  +void 
                  +st_free_gen(
                  +  st_generator * gen 
                  +)
                  +
                  +
                  After generating all items in a generation sequence, this routine must be called to reclaim the resources associated with `gen'. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_gen + + +
                  +void 
                  +st_free_table(
                  +  st_table * table 
                  +)
                  +
                  +
                  Any internal storage associated with table is freed. It is the user's responsibility to free any storage associated with the pointers he placed in the table (by perhaps using st_foreach). +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table +st_init_table_with_params + + +
                  +int 
                  +st_gen_int(
                  +  st_generator * gen, 
                  +  void * key_p, 
                  +  int * value_p 
                  +)
                  +
                  +
                  Given a generator returned by st_init_gen(), this routine returns the next (key, value) pair in the generation sequence. `value_p' must be a pointer to an integer. The pointer `value_p' can be zero which means no value will be returned. When there are no more items in the generation sequence, the routine returns 0. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_gen + + +
                  +int 
                  +st_gen(
                  +  st_generator * gen, 
                  +  void * key_p, 
                  +  void * value_p 
                  +)
                  +
                  +
                  Given a generator returned by st_init_gen(), this routine returns the next (key, value) pair in the generation sequence. The pointer `value_p' can be zero which means no value will be returned. When there are no more items in the generation sequence, the routine returns 0. While using a generation sequence, deleting any (key, value) pair other than the one just generated may cause a fatal error when st_gen() is called later in the sequence and is therefore not recommended. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_gen_int + + +
                  +st_generator * 
                  +st_init_gen(
                  +  st_table * table 
                  +)
                  +
                  +
                  Returns a generator handle which when used with st_gen() will progressively return each (key, value) record in `table'. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_free_gen + + +
                  +st_table * 
                  +st_init_table_with_params(
                  +  ST_PFICPCP  compare, 
                  +  ST_PFICPI  hash, 
                  +  int  size, 
                  +  int  density, 
                  +  double  grow_factor, 
                  +  int  reorder_flag 
                  +)
                  +
                  +
                  The full blown table initializer. compare and hash are the same as in st_init_table. density is the largest the average number of entries per hash bin there should be before the table is grown. grow_factor is the factor the table is grown by when it becomes too full. size is the initial number of bins to be allocated for the hash table. If reorder_flag is non-zero, then every time an entry is found, it is moved to the top of the chain.

                  st_init_table(compare, hash) is equivelent to

                   st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE, ST_DEFAULT_MAX_DENSITY, ST_DEFAULT_GROW_FACTOR, ST_DEFAULT_REORDER_FLAG); 
                  +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table +st_free_table + + +
                  +st_table * 
                  +st_init_table(
                  +  ST_PFICPCP  compare, 
                  +  ST_PFICPI  hash 
                  +)
                  +
                  +
                  Create and initialize a table with the comparison function compare_fn and hash function hash_fn. compare_fn is
                   int compare_fn(const char *key1, const char *key2) 
                  It returns <,=,> 0 depending on whether key1 <,=,> key2 by some measure.

                  hash_fn is

                   int hash_fn(char *key, int modulus) 
                  It returns a integer between 0 and modulus-1 such that if compare_fn(key1,key2) == 0 then hash_fn(key1) == hash_fn(key2).

                  There are five predefined hash and comparison functions in st. For keys as numbers:

                   st_numhash(key, modulus) { return (unsigned int) key % modulus; } 
                   st_numcmp(x,y) { return (int) x - (int) y; } 
                  For keys as pointers:
                   st_ptrhash(key, modulus) { return ((unsigned int) key/4) % modulus } 
                   st_ptrcmp(x,y) { return (int) x - (int) y; } 
                  For keys as strings:
                   st_strhash(x,y) - a reasonable hashing function for strings 
                   strcmp(x,y) - the standard library function 
                  It is recommended to use these particular functions if they fit your needs, since st will recognize certain of them and run more quickly because of it. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table_with_params +st_free_table + + +
                  +int 
                  +st_insert(
                  +  st_table * table, 
                  +  void * key, 
                  +  void * value 
                  +)
                  +
                  +
                  Insert value in table under the key 'key'. Returns 1 if there was an entry already under the key; 0 if there was no entry under the key and insertion was successful; ST_OUT_OF_MEM otherwise. In either of the first two cases the new value is added. +

                  + +

                  Side Effects None +

                  + +

                  + 
                  +st_is_member(
                  +   table, 
                  +   key 
                  +)
                  +
                  +
                  Returns 1 if there is an entry under `key' in `table', 0 otherwise. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_lookup + + +
                  +int 
                  +st_lookup_int(
                  +  st_table * table, 
                  +  void * key, 
                  +  int * value 
                  +)
                  +
                  +
                  Lookup up `key' in `table'. If an entry is found, 1 is returned and if `value' is not nil, the variable it points to is set to the associated integer value. If an entry is not found, 0 is return and the variable pointed by `value' is unchanged. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_lookup + + +
                  +int 
                  +st_lookup(
                  +  st_table * table, 
                  +  void * key, 
                  +  void * value 
                  +)
                  +
                  +
                  Lookup up `key' in `table'. If an entry is found, 1 is returned and if `value' is not nil, the variable it points to is set to the associated value. If an entry is not found, 0 is returned and the variable pointed by value is unchanged. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_lookup_int + + +
                  +int 
                  +st_numcmp(
                  +  const char * x, 
                  +  const char * y 
                  +)
                  +
                  +
                  integer number comparison function. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table +st_numhash + + +
                  +int 
                  +st_numhash(
                  +  char * x, 
                  +  int  size 
                  +)
                  +
                  +
                  Integer number hash function. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table +st_numcmp + + +
                  +int 
                  +st_ptrcmp(
                  +  const char * x, 
                  +  const char * y 
                  +)
                  +
                  +
                  Pointer comparison function. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table +st_ptrhash + + +
                  +int 
                  +st_ptrhash(
                  +  char * x, 
                  +  int  size 
                  +)
                  +
                  +
                  Pointer hash function. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table +st_ptrcmp + + +
                  +int 
                  +st_strhash(
                  +  char * string, 
                  +  int  modulus 
                  +)
                  +
                  +
                  String hash function. +

                  + +

                  Side Effects None +

                  + +

                  See Also st_init_table + + + +
                  + +
                  + +Generated automatically by extdoc on 20040102 + + diff --git a/resources/3rdparty/cudd-2.5.0/st/st.c b/resources/3rdparty/cudd-2.5.0/st/st.c new file mode 100644 index 000000000..dd76fa591 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/st.c @@ -0,0 +1,1065 @@ +/**CFile*********************************************************************** + + FileName [st.c] + + PackageName [st] + + Synopsis [Symbol table package.] + + Description [The st library provides functions to create, maintain, + and query symbol tables.] + + SeeAlso [] + + Author [] + + Copyright [] + +******************************************************************************/ + +#include "util.h" +#include "st.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = " $Id: st.c,v 1.12 2010/04/22 19:00:55 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define ST_NUMCMP(x,y) ((x) != (y)) + +#define ST_NUMHASH(x,size) ((unsigned long)(x)%(size)) + +#if SIZEOF_VOID_P == 8 +#define st_shift 3 +#else +#define st_shift 2 +#endif + +#define ST_PTRHASH(x,size) ((unsigned int)((unsigned long)(x)>>st_shift)%size) + +#define EQUAL(func, x, y) \ + ((((func) == st_numcmp) || ((func) == st_ptrcmp)) ?\ + (ST_NUMCMP((x),(y)) == 0) : ((*func)((x), (y)) == 0)) + +#define do_hash(key, table)\ + ((int)((table->hash == st_ptrhash) ? ST_PTRHASH((char *)(key),(table)->num_bins) :\ + (table->hash == st_numhash) ? ST_NUMHASH((char *)(key), (table)->num_bins) :\ + (*table->hash)((char *)(key), (table)->num_bins))) + +#define PTR_NOT_EQUAL(table, ptr, user_key)\ +(ptr != NIL(st_table_entry) && !EQUAL(table->compare, (char *)user_key, (ptr)->key)) + +#define FIND_ENTRY(table, hash_val, key, ptr, last) \ + (last) = &(table)->bins[hash_val];\ + (ptr) = *(last);\ + while (PTR_NOT_EQUAL((table), (ptr), (key))) {\ + (last) = &(ptr)->next; (ptr) = *(last);\ + }\ + if ((ptr) != NIL(st_table_entry) && (table)->reorder_flag) {\ + *(last) = (ptr)->next;\ + (ptr)->next = (table)->bins[hash_val];\ + (table)->bins[hash_val] = (ptr);\ + } + +/* This macro does not check if memory allocation fails. Use at you own risk */ +#define ADD_DIRECT(table, key, value, hash_val, newt)\ +{\ + if (table->num_entries/table->num_bins >= table->max_density) {\ + rehash(table);\ + hash_val = do_hash(key,table);\ + }\ + \ + newt = ALLOC(st_table_entry, 1);\ + \ + newt->key = (char *)key;\ + newt->record = value;\ + newt->next = table->bins[hash_val];\ + table->bins[hash_val] = newt;\ + table->num_entries++;\ +} + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int rehash (st_table *); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Create and initialize a table.] + + Description [Create and initialize a table with the comparison function + compare_fn and hash function hash_fn. compare_fn is +
                  +	int compare_fn(const char *key1, const char *key2)
                  +  
                  + It returns <,=,> 0 depending on whether key1 <,=,> key2 by some measure.

                  + hash_fn is +

                  +	int hash_fn(char *key, int modulus)
                  +  
                  + It returns a integer between 0 and modulus-1 such that if + compare_fn(key1,key2) == 0 then hash_fn(key1) == hash_fn(key2).

                  + There are five predefined hash and comparison functions in st. + For keys as numbers: +

                  +	 st_numhash(key, modulus) { return (unsigned int) key % modulus; }
                  +  
                  +
                  +	 st_numcmp(x,y) { return (int) x - (int) y; }
                  +  
                  + For keys as pointers: +
                  +	 st_ptrhash(key, modulus) { return ((unsigned int) key/4) % modulus }
                  +  
                  +
                  +	 st_ptrcmp(x,y) { return (int) x - (int) y; }
                  +  
                  + For keys as strings: +
                  +         st_strhash(x,y) - a reasonable hashing function for strings
                  +  
                  +
                  +	 strcmp(x,y) - the standard library function
                  +  
                  + It is recommended to use these particular functions if they fit your + needs, since st will recognize certain of them and run more quickly + because of it.] + + SideEffects [None] + + SeeAlso [st_init_table_with_params st_free_table] + +******************************************************************************/ +st_table * +st_init_table(ST_PFICPCP compare, ST_PFICPI hash) +{ + return st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE, + ST_DEFAULT_MAX_DENSITY, + ST_DEFAULT_GROW_FACTOR, + ST_DEFAULT_REORDER_FLAG); + +} /* st_init_table */ + + +/**Function******************************************************************** + + Synopsis [Create a table with given parameters.] + + Description [The full blown table initializer. compare and hash are + the same as in st_init_table. density is the largest the average + number of entries per hash bin there should be before the table is + grown. grow_factor is the factor the table is grown by when it + becomes too full. size is the initial number of bins to be allocated + for the hash table. If reorder_flag is non-zero, then every time an + entry is found, it is moved to the top of the chain.

                  + st_init_table(compare, hash) is equivelent to +

                  +  st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE,
                  +			    ST_DEFAULT_MAX_DENSITY,
                  +			    ST_DEFAULT_GROW_FACTOR,
                  +			    ST_DEFAULT_REORDER_FLAG);
                  +  
                  + ] + + SideEffects [None] + + SeeAlso [st_init_table st_free_table] + +******************************************************************************/ +st_table * +st_init_table_with_params( + ST_PFICPCP compare, + ST_PFICPI hash, + int size, + int density, + double grow_factor, + int reorder_flag) +{ + int i; + st_table *newt; + + newt = ALLOC(st_table, 1); + if (newt == NIL(st_table)) { + return NIL(st_table); + } + newt->compare = compare; + newt->hash = hash; + newt->num_entries = 0; + newt->max_density = density; + newt->grow_factor = grow_factor; + newt->reorder_flag = reorder_flag; + if (size <= 0) { + size = 1; + } + newt->num_bins = size; + newt->bins = ALLOC(st_table_entry *, size); + if (newt->bins == NIL(st_table_entry *)) { + FREE(newt); + return NIL(st_table); + } + for(i = 0; i < size; i++) { + newt->bins[i] = 0; + } + return newt; + +} /* st_init_table_with_params */ + + +/**Function******************************************************************** + + Synopsis [Free a table.] + + Description [Any internal storage associated with table is freed. + It is the user's responsibility to free any storage associated + with the pointers he placed in the table (by perhaps using + st_foreach).] + + SideEffects [None] + + SeeAlso [st_init_table st_init_table_with_params] + +******************************************************************************/ +void +st_free_table(st_table *table) +{ + st_table_entry *ptr, *next; + int i; + + for(i = 0; i < table->num_bins ; i++) { + ptr = table->bins[i]; + while (ptr != NIL(st_table_entry)) { + next = ptr->next; + FREE(ptr); + ptr = next; + } + } + FREE(table->bins); + FREE(table); + +} /* st_free_table */ + + +/**Function******************************************************************** + + Synopsis [Lookup up `key' in `table'.] + + Description [Lookup up `key' in `table'. If an entry is found, 1 is + returned and if `value' is not nil, the variable it points to is set + to the associated value. If an entry is not found, 0 is returned + and the variable pointed by value is unchanged.] + + SideEffects [None] + + SeeAlso [st_lookup_int] + +******************************************************************************/ +int +st_lookup(st_table *table, void *key, void *value) +{ + int hash_val; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (value != NIL(void)) { + *(char **)value = ptr->record; + } + return 1; + } + +} /* st_lookup */ + + +/**Function******************************************************************** + + Synopsis [Lookup up `key' in `table'.] + + Description [Lookup up `key' in `table'. If an entry is found, 1 is + returned and if `value' is not nil, the variable it points to is + set to the associated integer value. If an entry is not found, 0 is + return and the variable pointed by `value' is unchanged.] + + SideEffects [None] + + SeeAlso [st_lookup] + +******************************************************************************/ +int +st_lookup_int(st_table *table, void *key, int *value) +{ + int hash_val; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (value != NIL(int)) { + *value = (int) (long) ptr->record; + } + return 1; + } + +} /* st_lookup_int */ + + +/**Function******************************************************************** + + Synopsis [Insert value in table under the key 'key'.] + + Description [Insert value in table under the key 'key'. Returns 1 + if there was an entry already under the key; 0 if there was no entry + under the key and insertion was successful; ST_OUT_OF_MEM otherwise. + In either of the first two cases the new value is added.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +st_insert(st_table *table, void *key, void *value) +{ + int hash_val; + st_table_entry *newt; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + if (table->num_entries/table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + hash_val = do_hash(key, table); + } + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = (char *)key; + newt->record = (char *)value; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + return 0; + } else { + ptr->record = (char *)value; + return 1; + } + +} /* st_insert */ + + +/**Function******************************************************************** + + Synopsis [Place 'value' in 'table' under the key 'key'.] + + Description [Place 'value' in 'table' under the key 'key'. This is + done without checking if 'key' is in 'table' already. This should + only be used if you are sure there is not already an entry for + 'key', since it is undefined which entry you would later get from + st_lookup or st_find_or_add. Returns 1 if successful; ST_OUT_OF_MEM + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +st_add_direct(st_table *table, void *key, void *value) +{ + int hash_val; + st_table_entry *newt; + + hash_val = do_hash(key, table); + if (table->num_entries / table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + } + hash_val = do_hash(key, table); + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = (char *)key; + newt->record = (char *)value; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + return 1; + +} /* st_add_direct */ + + +/**Function******************************************************************** + + Synopsis [Lookup `key' in `table'.] + + Description [Lookup `key' in `table'. If not found, create an + entry. In either case set slot to point to the field in the entry + where the value is stored. The value associated with `key' may then + be changed by accessing directly through slot. Returns 1 if an + entry already existed, 0 if it did not exist and creation was + successful; ST_OUT_OF_MEM otherwise. As an example: +
                  +      char **slot;
                  +  
                  +
                  +      char *key;
                  +  
                  +
                  +      char *value = (char *) item_ptr <-- ptr to a malloc'd structure
                  +  
                  +
                  +      if (st_find_or_add(table, key, &slot) == 1) {
                  +  
                  +
                  +	 FREE(*slot); <-- free the old value of the record
                  +  
                  +
                  +      }
                  +  
                  +
                  +      *slot = value;  <-- attach the new value to the record
                  +  
                  + This replaces the equivelent code: +
                  +      if (st_lookup(table, key, &ovalue) == 1) {
                  +  
                  +
                  +         FREE(ovalue);
                  +  
                  +
                  +      }
                  +  
                  +
                  +      st_insert(table, key, value);
                  +  
                  + ] + + SideEffects [None] + + SeeAlso [st_find] + +******************************************************************************/ +int +st_find_or_add(st_table *table, void *key, void *slot) +{ + int hash_val; + st_table_entry *newt, *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + if (table->num_entries / table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + hash_val = do_hash(key, table); + } + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = (char *)key; + newt->record = (char *) 0; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + if (slot != NIL(void)) *(char ***)slot = &newt->record; + return 0; + } else { + if (slot != NIL(void)) *(char ***)slot = &ptr->record; + return 1; + } + +} /* st_find_or_add */ + + +/**Function******************************************************************** + + Synopsis [Lookup `key' in `table'.] + + Description [Like st_find_or_add, but does not create an entry if + one is not found.] + + SideEffects [None] + + SeeAlso [st_find_or_add] + +******************************************************************************/ +int +st_find(st_table *table, void *key, void *slot) +{ + int hash_val; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (slot != NIL(void)) { + *(char ***)slot = &ptr->record; + } + return 1; + } + +} /* st_find */ + + +/**Function******************************************************************** + + Synopsis [Return a copy of old_table and all its members.] + + Description [Return a copy of old_table and all its members. + (st_table *) 0 is returned if there was insufficient memory to do + the copy.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +st_table * +st_copy(st_table *old_table) +{ + st_table *new_table; + st_table_entry *ptr, *newptr, *next, *newt; + int i, j, num_bins = old_table->num_bins; + + new_table = ALLOC(st_table, 1); + if (new_table == NIL(st_table)) { + return NIL(st_table); + } + + *new_table = *old_table; + new_table->bins = ALLOC(st_table_entry *, num_bins); + if (new_table->bins == NIL(st_table_entry *)) { + FREE(new_table); + return NIL(st_table); + } + for(i = 0; i < num_bins ; i++) { + new_table->bins[i] = NIL(st_table_entry); + ptr = old_table->bins[i]; + while (ptr != NIL(st_table_entry)) { + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + for (j = 0; j <= i; j++) { + newptr = new_table->bins[j]; + while (newptr != NIL(st_table_entry)) { + next = newptr->next; + FREE(newptr); + newptr = next; + } + } + FREE(new_table->bins); + FREE(new_table); + return NIL(st_table); + } + *newt = *ptr; + newt->next = new_table->bins[i]; + new_table->bins[i] = newt; + ptr = ptr->next; + } + } + return new_table; + +} /* st_copy */ + + +/**Function******************************************************************** + + Synopsis [Delete the entry with the key pointed to by `keyp'.] + + Description [Delete the entry with the key pointed to by `keyp'. If + the entry is found, 1 is returned, the variable pointed by `keyp' is + set to the actual key and the variable pointed by `value' is set to + the corresponding entry. (This allows the freeing of the associated + storage.) If the entry is not found, then 0 is returned and nothing + is changed.] + + SideEffects [None] + + SeeAlso [st_delete_int] + +******************************************************************************/ +int +st_delete(st_table *table, void *keyp, void *value) +{ + int hash_val; + char *key = *(char **)keyp; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr ,last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } + + *last = ptr->next; + if (value != NIL(void)) *(char **)value = ptr->record; + *(char **)keyp = ptr->key; + FREE(ptr); + table->num_entries--; + return 1; + +} /* st_delete */ + + +/**Function******************************************************************** + + Synopsis [Delete the entry with the key pointed to by `keyp'.] + + Description [Delete the entry with the key pointed to by `keyp'. + `value' must be a pointer to an integer. If the entry is found, 1 + is returned, the variable pointed by `keyp' is set to the actual key + and the variable pointed by `value' is set to the corresponding + entry. (This allows the freeing of the associated storage.) If the + entry is not found, then 0 is returned and nothing is changed.] + + SideEffects [None] + + SeeAlso [st_delete] + +******************************************************************************/ +int +st_delete_int(st_table *table, void *keyp, int *value) +{ + int hash_val; + char *key = *(char **)keyp; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr ,last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } + + *last = ptr->next; + if (value != NIL(int)) *value = (int) (long) ptr->record; + *(char **)keyp = ptr->key; + FREE(ptr); + table->num_entries--; + return 1; + +} /* st_delete_int */ + + +/**Function******************************************************************** + + Synopsis [Iterates over the elements of a table.] + + Description [For each (key, value) record in `table', st_foreach + call func with the arguments +
                  +	  (*func)(key, value, arg)
                  +  
                  + If func returns ST_CONTINUE, st_foreach continues processing + entries. If func returns ST_STOP, st_foreach stops processing and + returns immediately. If func returns ST_DELETE, then the entry is + deleted from the symbol table and st_foreach continues. In the case + of ST_DELETE, it is func's responsibility to free the key and value, + if necessary.

                  + + The routine returns 1 if all items in the table were generated and 0 + if the generation sequence was aborted using ST_STOP. The order in + which the records are visited will be seemingly random.] + + SideEffects [None] + + SeeAlso [st_foreach_item st_foreach_item_int] + +******************************************************************************/ +int +st_foreach(st_table *table, ST_PFSR func, char *arg) +{ + st_table_entry *ptr, **last; + enum st_retval retval; + int i; + + for(i = 0; i < table->num_bins; i++) { + last = &table->bins[i]; ptr = *last; + while (ptr != NIL(st_table_entry)) { + retval = (*func)(ptr->key, ptr->record, arg); + switch (retval) { + case ST_CONTINUE: + last = &ptr->next; ptr = *last; + break; + case ST_STOP: + return 0; + case ST_DELETE: + *last = ptr->next; + table->num_entries--; /* cstevens@ic */ + FREE(ptr); + ptr = *last; + } + } + } + return 1; + +} /* st_foreach */ + + +/**Function******************************************************************** + + Synopsis [String hash function.] + + Description [String hash function.] + + SideEffects [None] + + SeeAlso [st_init_table] + +******************************************************************************/ +int +st_strhash(char *string, int modulus) +{ + int val = 0; + int c; + + while ((c = *string++) != '\0') { + val = val*997 + c; + } + + return ((val < 0) ? -val : val)%modulus; + +} /* st_strhash */ + + +/**Function******************************************************************** + + Synopsis [Number hash function.] + + Description [Integer number hash function.] + + SideEffects [None] + + SeeAlso [st_init_table st_numcmp] + +******************************************************************************/ +int +st_numhash(char *x, int size) +{ + return ST_NUMHASH(x, size); + +} /* st_numhash */ + + +/**Function******************************************************************** + + Synopsis [Pointer hash function.] + + Description [Pointer hash function.] + + SideEffects [None] + + SeeAlso [st_init_table st_ptrcmp] + +******************************************************************************/ +int +st_ptrhash(char *x, int size) +{ + return ST_PTRHASH(x, size); + +} /* st_ptrhash */ + + +/**Function******************************************************************** + + Synopsis [Number comparison function.] + + Description [integer number comparison function.] + + SideEffects [None] + + SeeAlso [st_init_table st_numhash] + +******************************************************************************/ +int +st_numcmp(const char *x, const char *y) +{ + return ST_NUMCMP(x, y); + +} /* st_numcmp */ + + +/**Function******************************************************************** + + Synopsis [Pointer comparison function.] + + Description [Pointer comparison function.] + + SideEffects [None] + + SeeAlso [st_init_table st_ptrhash] + +******************************************************************************/ +int +st_ptrcmp(const char *x, const char *y) +{ + return ST_NUMCMP(x, y); + +} /* st_ptrcmp */ + + +/**Function******************************************************************** + + Synopsis [Initializes a generator.] + + Description [Returns a generator handle which when used with + st_gen() will progressively return each (key, value) record in + `table'.] + + SideEffects [None] + + SeeAlso [st_free_gen] + +******************************************************************************/ +st_generator * +st_init_gen(st_table *table) +{ + st_generator *gen; + + gen = ALLOC(st_generator, 1); + if (gen == NIL(st_generator)) { + return NIL(st_generator); + } + gen->table = table; + gen->entry = NIL(st_table_entry); + gen->index = 0; + return gen; + +} /* st_init_gen */ + + +/**Function******************************************************************** + + Synopsis [returns the next (key, value) pair in the generation + sequence. ] + + Description [Given a generator returned by st_init_gen(), this + routine returns the next (key, value) pair in the generation + sequence. The pointer `value_p' can be zero which means no value + will be returned. When there are no more items in the generation + sequence, the routine returns 0. + + While using a generation sequence, deleting any (key, value) pair + other than the one just generated may cause a fatal error when + st_gen() is called later in the sequence and is therefore not + recommended.] + + SideEffects [None] + + SeeAlso [st_gen_int] + +******************************************************************************/ +int +st_gen(st_generator *gen, void *key_p, void *value_p) +{ + int i; + + if (gen->entry == NIL(st_table_entry)) { + /* try to find next entry */ + for(i = gen->index; i < gen->table->num_bins; i++) { + if (gen->table->bins[i] != NIL(st_table_entry)) { + gen->index = i+1; + gen->entry = gen->table->bins[i]; + break; + } + } + if (gen->entry == NIL(st_table_entry)) { + return 0; /* that's all folks ! */ + } + } + *(char **)key_p = gen->entry->key; + if (value_p != NIL(void)) { + *(char **)value_p = gen->entry->record; + } + gen->entry = gen->entry->next; + return 1; + +} /* st_gen */ + + +/**Function******************************************************************** + + Synopsis [Returns the next (key, value) pair in the generation + sequence.] + + Description [Given a generator returned by st_init_gen(), this + routine returns the next (key, value) pair in the generation + sequence. `value_p' must be a pointer to an integer. The pointer + `value_p' can be zero which means no value will be returned. When + there are no more items in the generation sequence, the routine + returns 0.] + + SideEffects [None] + + SeeAlso [st_gen] + +******************************************************************************/ +int +st_gen_int(st_generator *gen, void *key_p, int *value_p) +{ + int i; + + if (gen->entry == NIL(st_table_entry)) { + /* try to find next entry */ + for(i = gen->index; i < gen->table->num_bins; i++) { + if (gen->table->bins[i] != NIL(st_table_entry)) { + gen->index = i+1; + gen->entry = gen->table->bins[i]; + break; + } + } + if (gen->entry == NIL(st_table_entry)) { + return 0; /* that's all folks ! */ + } + } + *(char **)key_p = gen->entry->key; + if (value_p != NIL(int)) { + *value_p = (int) (long) gen->entry->record; + } + gen->entry = gen->entry->next; + return 1; + +} /* st_gen_int */ + + +/**Function******************************************************************** + + Synopsis [Reclaims the resources associated with `gen'.] + + Description [After generating all items in a generation sequence, + this routine must be called to reclaim the resources associated with + `gen'.] + + SideEffects [None] + + SeeAlso [st_init_gen] + +******************************************************************************/ +void +st_free_gen(st_generator *gen) +{ + FREE(gen); + +} /* st_free_gen */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Rehashes a symbol table.] + + Description [Rehashes a symbol table.] + + SideEffects [None] + + SeeAlso [st_insert] + +******************************************************************************/ +static int +rehash(st_table *table) +{ + st_table_entry *ptr, *next, **old_bins; + int i, old_num_bins, hash_val, old_num_entries; + + /* save old values */ + old_bins = table->bins; + old_num_bins = table->num_bins; + old_num_entries = table->num_entries; + + /* rehash */ + table->num_bins = (int) (table->grow_factor * old_num_bins); + if (table->num_bins % 2 == 0) { + table->num_bins += 1; + } + table->num_entries = 0; + table->bins = ALLOC(st_table_entry *, table->num_bins); + if (table->bins == NIL(st_table_entry *)) { + table->bins = old_bins; + table->num_bins = old_num_bins; + table->num_entries = old_num_entries; + return ST_OUT_OF_MEM; + } + /* initialize */ + for (i = 0; i < table->num_bins; i++) { + table->bins[i] = 0; + } + + /* copy data over */ + for (i = 0; i < old_num_bins; i++) { + ptr = old_bins[i]; + while (ptr != NIL(st_table_entry)) { + next = ptr->next; + hash_val = do_hash(ptr->key, table); + ptr->next = table->bins[hash_val]; + table->bins[hash_val] = ptr; + table->num_entries++; + ptr = next; + } + } + FREE(old_bins); + + return 1; + +} /* rehash */ diff --git a/resources/3rdparty/cudd-2.5.0/st/st.h b/resources/3rdparty/cudd-2.5.0/st/st.h new file mode 100644 index 000000000..dbb14bbeb --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/st/st.h @@ -0,0 +1,232 @@ +/**CHeaderFile***************************************************************** + + FileName [st.h] + + PackageName [st] + + Synopsis [Symbol table package.] + + Description [The st library provides functions to create, maintain, + and query symbol tables.] + + SeeAlso [] + + Author [] + + Copyright [] + + Revision [$Id: st.h,v 1.10 2004/01/02 07:40:31 fabio Exp fabio $] + +******************************************************************************/ + +#ifndef ST_INCLUDED +#define ST_INCLUDED + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define ST_DEFAULT_MAX_DENSITY 5 +#define ST_DEFAULT_INIT_TABLE_SIZE 11 +#define ST_DEFAULT_GROW_FACTOR 2.0 +#define ST_DEFAULT_REORDER_FLAG 0 +#define ST_OUT_OF_MEM -10000 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct st_table_entry st_table_entry; +struct st_table_entry { + char *key; + char *record; + st_table_entry *next; +}; + +typedef struct st_table st_table; +struct st_table { + int (*compare)(const char *, const char *); + int (*hash)(char *, int); + int num_bins; + int num_entries; + int max_density; + int reorder_flag; + double grow_factor; + st_table_entry **bins; +}; + +typedef struct st_generator st_generator; +struct st_generator { + st_table *table; + st_table_entry *entry; + int index; +}; + +enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE}; + +typedef enum st_retval (*ST_PFSR)(char *, char *, char *); + +typedef int (*ST_PFICPCP)(const char *, const char *); /* type for comparison function */ + +typedef int (*ST_PFICPI)(char *, int); /* type for hash function */ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Checks whethere `key' is in `table'.] + + Description [Returns 1 if there is an entry under `key' in `table', 0 + otherwise.] + + SideEffects [None] + + SeeAlso [st_lookup] + +******************************************************************************/ +#define st_is_member(table,key) st_lookup(table,key,(char **) 0) + + +/**Macro*********************************************************************** + + Synopsis [Returns the number of entries in the table `table'.] + + Description [Returns the number of entries in the table `table'.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +#define st_count(table) ((table)->num_entries) + + +/**Macro*********************************************************************** + + Synopsis [Iteration macro.] + + Description [An iteration macro which loops over all the entries in + `table', setting `key' to point to the key and `value' to the + associated value (if it is not nil). `gen' is a generator variable + used internally. Sample usage: +

                  +     	char *key, *value;
                  +  
                  +
                  +	st_generator *gen;
                  +  
                  +
                  +
                  +	st_foreach_item(table, gen, &key, &value) {
                  +  
                  +
                  +	    process_item(value);
                  +  
                  +
                  +	}
                  +  
                  + ] + + SideEffects [None] + + SeeAlso [st_foreach_item_int st_foreach] + +******************************************************************************/ +#define st_foreach_item(table, gen, key, value) \ + for(gen=st_init_gen(table); st_gen(gen,key,value) || (st_free_gen(gen),0);) + + +/**Macro*********************************************************************** + + Synopsis [Iteration macro.] + + Description [An iteration macro which loops over all the entries in + `table', setting `key' to point to the key and `value' to the + associated value (if it is not nil). `value' is assumed to be a + pointer to an integer. `gen' is a generator variable used + internally. Sample usage: +
                  +     	char *key;
                  +  
                  +
                  +	int value;
                  +  
                  +
                  +	st_generator *gen;
                  +  
                  +
                  +
                  +	st_foreach_item_int(table, gen, &key, &value) {
                  +  
                  +
                  +	    process_item(value);
                  +  
                  +
                  +	}
                  +  
                  + ] + + SideEffects [None] + + SeeAlso [st_foreach_item st_foreach] + +******************************************************************************/ +#define st_foreach_item_int(table, gen, key, value) \ + for(gen=st_init_gen(table); st_gen_int(gen,key,value) || (st_free_gen(gen),0);) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern st_table *st_init_table_with_params (ST_PFICPCP, ST_PFICPI, int, int, double, int); +extern st_table *st_init_table (ST_PFICPCP, ST_PFICPI); +extern void st_free_table (st_table *); +extern int st_lookup (st_table *, void *, void *); +extern int st_lookup_int (st_table *, void *, int *); +extern int st_insert (st_table *, void *, void *); +extern int st_add_direct (st_table *, void *, void *); +extern int st_find_or_add (st_table *, void *, void *); +extern int st_find (st_table *, void *, void *); +extern st_table *st_copy (st_table *); +extern int st_delete (st_table *, void *, void *); +extern int st_delete_int (st_table *, void *, int *); +extern int st_foreach (st_table *, ST_PFSR, char *); +extern int st_strhash (char *, int); +extern int st_numhash (char *, int); +extern int st_ptrhash (char *, int); +extern int st_numcmp (const char *, const char *); +extern int st_ptrcmp (const char *, const char *); +extern st_generator *st_init_gen (st_table *); +extern int st_gen (st_generator *, void *, void *); +extern int st_gen_int (st_generator *, void *, int *); +extern void st_free_gen (st_generator *); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* ST_INCLUDED */ diff --git a/resources/3rdparty/cudd-2.5.0/util/Makefile b/resources/3rdparty/cudd-2.5.0/util/Makefile new file mode 100644 index 000000000..61543baee --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/Makefile @@ -0,0 +1,64 @@ +# $Id$ +# +# util -- miscellaneous utility routines +#--------------------------------------------------------------------------- +.SUFFIXES: .c .o .u + +CC = gcc +RANLIB = ranlib + +FLAGS = -DUNIX +MFLAG = +ICFLAGS = -g +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) + +LINTFLAGS = -u -n + +# this is to create the lint library +LINTSWITCH = -o + +P = util +PSRC = cpu_time.c cpu_stats.c safe_mem.c strsav.c texpand.c \ + ptime.c prtime.c pipefork.c pathsearch.c stub.c datalimit.c +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +PHDR = util.h + +WHERE = .. +INCLUDE = $(WHERE)/include + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(FLAGS) $(CFLAGS) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PHDR) + cc -j $< -I$(INCLUDE) $(FLAGS) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +clean: + rm -f *.o *.u core *.warnings + +distclean: clean + rm -f lib$(P).a lib$(P).b llib-l$(P).ln tags *.bak *~ .pure diff --git a/resources/3rdparty/cudd-2.5.0/util/cpu_stats.c b/resources/3rdparty/cudd-2.5.0/util/cpu_stats.c new file mode 100644 index 000000000..40117d463 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/cpu_stats.c @@ -0,0 +1,89 @@ +/* LINTLIBRARY */ + +#include "util.h" + + +#ifdef BSD +#include +#include +#include + +#if defined(_IBMR2) +#define etext _etext +#define edata _edata +#define end _end +#endif + +extern int end, etext, edata; + +#endif + +void +util_print_cpu_stats(FILE *fp) +{ +#ifdef BSD + struct rusage rusage; + struct rlimit rlp; + long text, data, vm_limit, vm_soft_limit; + double user, system, scale; + char hostname[257]; + long vm_text, vm_init_data, vm_uninit_data, vm_sbrk_data; + + /* Get the hostname */ + (void) gethostname(hostname, 256); + hostname[256] = '\0'; /* just in case */ + + /* Get the virtual memory sizes */ + vm_text = (long) (((long) (&etext)) / 1024.0 + 0.5); + vm_init_data = (long) (((long) (&edata) - (long) (&etext)) / 1024.0 + 0.5); + vm_uninit_data = (long) (((long) (&end) - (long) (&edata)) / 1024.0 + 0.5); + vm_sbrk_data = (long) (((long) sbrk(0) - (long) (&end)) / 1024.0 + 0.5); + + /* Get virtual memory limits */ + (void) getrlimit(RLIMIT_DATA, &rlp); + vm_limit = (long) (rlp.rlim_max / 1024.0 + 0.5); + vm_soft_limit = (long) (rlp.rlim_cur / 1024.0 + 0.5); + + /* Get usage stats */ + (void) getrusage(RUSAGE_SELF, &rusage); + user = rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec/1.0e6; + system = rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec/1.0e6; + scale = (user + system)*100.0; + if (scale == 0.0) scale = 0.001; + + (void) fprintf(fp, "Runtime Statistics\n"); + (void) fprintf(fp, "------------------\n"); + (void) fprintf(fp, "Machine name: %s\n", hostname); + (void) fprintf(fp, "User time %6.1f seconds\n", user); + (void) fprintf(fp, "System time %6.1f seconds\n\n", system); + + text = (int) (rusage.ru_ixrss / scale + 0.5); + data = (int) ((rusage.ru_idrss + rusage.ru_isrss) / scale + 0.5); + (void) fprintf(fp, "Average resident text size = %5ldK\n", text); + (void) fprintf(fp, "Average resident data+stack size = %5ldK\n", data); + (void) fprintf(fp, "Maximum resident size = %5ldK\n\n", + rusage.ru_maxrss/2); + (void) fprintf(fp, "Virtual text size = %5ldK\n", + vm_text); + (void) fprintf(fp, "Virtual data size = %5ldK\n", + vm_init_data + vm_uninit_data + vm_sbrk_data); + (void) fprintf(fp, " data size initialized = %5ldK\n", + vm_init_data); + (void) fprintf(fp, " data size uninitialized = %5ldK\n", + vm_uninit_data); + (void) fprintf(fp, " data size sbrk = %5ldK\n", + vm_sbrk_data); + (void) fprintf(fp, "Virtual memory limit = %5ldK (%ldK)\n\n", + vm_soft_limit, vm_limit); + + (void) fprintf(fp, "Major page faults = %ld\n", rusage.ru_majflt); + (void) fprintf(fp, "Minor page faults = %ld\n", rusage.ru_minflt); + (void) fprintf(fp, "Swaps = %ld\n", rusage.ru_nswap); + (void) fprintf(fp, "Input blocks = %ld\n", rusage.ru_inblock); + (void) fprintf(fp, "Output blocks = %ld\n", rusage.ru_oublock); + (void) fprintf(fp, "Context switch (voluntary) = %ld\n", rusage.ru_nvcsw); + (void) fprintf(fp, "Context switch (involuntary) = %ld\n", rusage.ru_nivcsw); +#else + (void) fprintf(fp, "Usage statistics not available\n"); +#endif +} diff --git a/resources/3rdparty/cudd-2.5.0/util/cpu_time.c b/resources/3rdparty/cudd-2.5.0/util/cpu_time.c new file mode 100644 index 000000000..2a4be9240 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/cpu_time.c @@ -0,0 +1,76 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + +#ifdef IBM_WATC /* IBM Waterloo-C compiler (same as bsd 4.2) */ +#define void int +#define BSD +#endif + +#ifdef BSD +#include +#include +#include +#endif + +#if defined(UNIX60) || defined(UNIX100) || defined(__CYGWIN32__) +#include +#include +#endif + +#ifdef vms /* VAX/C compiler -- times() with 100 HZ clock */ +#include +#include +#endif + + + +/* + * util_cpu_time -- return a long which represents the elapsed processor + * time in milliseconds since some constant reference + */ +long +util_cpu_time() +{ + long t = 0; + +#ifdef BSD + struct rusage rusage; + (void) getrusage(RUSAGE_SELF, &rusage); + t = (long) rusage.ru_utime.tv_sec*1000 + rusage.ru_utime.tv_usec/1000; +#endif + +#ifdef IBMPC + long ltime; + (void) time(<ime); + t = ltime * 1000; +#endif + +#ifdef UNIX60 /* times() with 60 Hz resolution */ + struct tms buffer; + times(&buffer); + t = buffer.tms_utime * 16.6667; +#endif + +#ifdef UNIX100 + struct tms buffer; /* times() with 100 Hz resolution */ + times(&buffer); + t = buffer.tms_utime * 10; +#endif + +#ifdef __CYGWIN32__ + /* Works under Windows NT but not Windows 95. */ + struct tms buffer; /* times() with 1000 Hz resolution */ + times(&buffer); + t = buffer.tms_utime; +#endif + +#ifdef vms + tbuffer_t buffer; /* times() with 100 Hz resolution */ + times(&buffer); + t = buffer.proc_user_time * 10; +#endif + + return t; +} diff --git a/resources/3rdparty/cudd-2.5.0/util/datalimit.c b/resources/3rdparty/cudd-2.5.0/util/datalimit.c new file mode 100644 index 000000000..f140414d3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/datalimit.c @@ -0,0 +1,50 @@ +/* $Id: datalimit.c,v 1.5 2007/08/24 18:17:31 fabio Exp fabio $ */ + +#ifndef HAVE_SYS_RESOURCE_H +#define HAVE_SYS_RESOURCE_H 1 +#endif +#ifndef HAVE_SYS_TIME_H +#define HAVE_SYS_TIME_H 1 +#endif +#ifndef HAVE_GETRLIMIT +#define HAVE_GETRLIMIT 1 +#endif + +#if HAVE_SYS_RESOURCE_H == 1 +#if HAVE_SYS_TIME_H == 1 +#include +#endif +#include +#endif + +#ifndef RLIMIT_DATA_DEFAULT +#define RLIMIT_DATA_DEFAULT 67108864 /* assume 64MB by default */ +#endif + +#ifndef EXTERN +# ifdef __cplusplus +# define EXTERN extern "C" +# else +# define EXTERN extern +# endif +#endif + +EXTERN unsigned long getSoftDataLimit(void); + +unsigned long +getSoftDataLimit(void) +{ +#if HAVE_SYS_RESOURCE_H == 1 && HAVE_GETRLIMIT == 1 && defined(RLIMIT_DATA) + struct rlimit rl; + int result; + + result = getrlimit(RLIMIT_DATA, &rl); + if (result != 0 || rl.rlim_cur == RLIM_INFINITY) + return((unsigned long) RLIMIT_DATA_DEFAULT); + else + return((unsigned long) rl.rlim_cur); +#else + return((unsigned long) RLIMIT_DATA_DEFAULT); +#endif + +} /* end of getSoftDataLimit */ diff --git a/resources/3rdparty/cudd-2.5.0/util/pathsearch.c b/resources/3rdparty/cudd-2.5.0/util/pathsearch.c new file mode 100644 index 000000000..67c34b868 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/pathsearch.c @@ -0,0 +1,94 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + +static int check_file (char const *, char const *); + +char * +util_path_search(char const *prog) +{ +#ifdef UNIX + return util_file_search(prog, getenv("PATH"), (char *) "x"); +#else + return util_file_search(prog, NIL(char), (char *) "x"); +#endif +} + + +char * +util_file_search( + char const *file, /* file we're looking for */ + char *path, /* search path, colon separated */ + char const *mode /* "r", "w", or "x" */) +{ + int quit; + char *buffer, *filename, *save_path, *cp; + + if (path == 0 || strcmp(path, "") == 0) { + path = (char *) "."; /* just look in the current directory */ + } + + save_path = path = strsav(path); + quit = 0; + do { + cp = strchr(path, ':'); + if (cp != 0) { + *cp = '\0'; + } else { + quit = 1; + } + + /* cons up the filename out of the path and file name */ + if (strcmp(path, ".") == 0) { + buffer = strsav(file); + } else { + buffer = ALLOC(char, strlen(path) + strlen(file) + 4); + (void) sprintf(buffer, "%s/%s", path, file); + } + filename = util_tilde_expand(buffer); + FREE(buffer); + + /* see if we can access it */ + if (check_file(filename, mode)) { + FREE(save_path); + return filename; + } + FREE(filename); + path = ++cp; + } while (! quit); + + FREE(save_path); + return 0; +} + + +static int +check_file(char const *filename, char const *mode) +{ +#ifdef UNIX + int access_mode = /*F_OK*/ 0; + + if (strcmp(mode, "r") == 0) { + access_mode = /*R_OK*/ 4; + } else if (strcmp(mode, "w") == 0) { + access_mode = /*W_OK*/ 2; + } else if (strcmp(mode, "x") == 0) { + access_mode = /*X_OK*/ 1; + } + return access(filename, access_mode) == 0; +#else + FILE *fp; + int got_file; + + if (strcmp(mode, "x") == 0) { + mode = "r"; + } + fp = fopen(filename, mode); + got_file = (fp != 0); + if (fp != 0) { + (void) fclose(fp); + } + return got_file; +#endif +} diff --git a/resources/3rdparty/cudd-2.5.0/util/pipefork.c b/resources/3rdparty/cudd-2.5.0/util/pipefork.c new file mode 100644 index 000000000..ead02d43b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/pipefork.c @@ -0,0 +1,93 @@ +/* + * Revision Control Information + * + * $Id: pipefork.c,v 1.7 2012/02/05 05:34:04 fabio Exp fabio $ + * + */ +/* LINTLIBRARY */ + +#include "util.h" +#include + +/* + * util_pipefork - fork a command and set up pipes to and from + * + * Rick L Spickelmier, 3/23/86 + * Richard Rudell, 4/6/86 + * Rick L Spickelmier, 4/30/90, got rid of slimey vfork semantics + * + * Returns: + * 1 for success, with toCommand and fromCommand pointing to the streams + * 0 for failure + */ + +/* ARGSUSED */ +int +util_pipefork( + char * const *argv, /* normal argv argument list */ + FILE **toCommand, /* pointer to the sending stream */ + FILE **fromCommand, /* pointer to the reading stream */ + int *pid) +{ +#ifdef UNIX + int forkpid, waitPid; + int topipe[2], frompipe[2]; + char buffer[1024]; + int status; + + /* create the PIPES... + * fildes[0] for reading from command + * fildes[1] for writing to command + */ + if (pipe(topipe)) return(0); + if (pipe(frompipe)) return(0); + +#ifdef __CYGWIN32__ + if ((forkpid = fork()) == 0) { +#else + if ((forkpid = vfork()) == 0) { +#endif + /* child here, connect the pipes */ + (void) dup2(topipe[0], fileno(stdin)); + (void) dup2(frompipe[1], fileno(stdout)); + + (void) close(topipe[0]); + (void) close(topipe[1]); + (void) close(frompipe[0]); + (void) close(frompipe[1]); + + (void) execvp(argv[0], argv); + (void) sprintf(buffer, "util_pipefork: can not exec %s", argv[0]); + perror(buffer); + (void) _exit(1); + } + + if (pid) { + *pid = forkpid; + } + +#ifdef __CYGWIN32__ + waitPid = waitpid(-1, &status, WNOHANG); +#else + waitPid = wait3(&status, WNOHANG, NULL); +#endif + + /* parent here, use slimey vfork() semantics to get return status */ + if (waitPid == forkpid && WIFEXITED(status)) { + return 0; + } + if ((*toCommand = fdopen(topipe[1], "w")) == NULL) { + return 0; + } + if ((*fromCommand = fdopen(frompipe[0], "r")) == NULL) { + return 0; + } + (void) close(topipe[0]); + (void) close(frompipe[1]); + return 1; +#else + (void) fprintf(stderr, + "util_pipefork: not implemented on your operating system\n"); + return 0; +#endif +} diff --git a/resources/3rdparty/cudd-2.5.0/util/prtime.c b/resources/3rdparty/cudd-2.5.0/util/prtime.c new file mode 100644 index 000000000..236eafb75 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/prtime.c @@ -0,0 +1,21 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + + +/* + * util_print_time -- massage a long which represents a time interval in + * milliseconds, into a string suitable for output + * + * Hack for IBM/PC -- avoids using floating point + */ + +char * +util_print_time(unsigned long t) +{ + static char s[40]; + + (void) sprintf(s, "%lu.%02lu sec", t/1000, (t%1000)/10); + return s; +} diff --git a/resources/3rdparty/cudd-2.5.0/util/ptime.c b/resources/3rdparty/cudd-2.5.0/util/ptime.c new file mode 100644 index 000000000..4510857be --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/ptime.c @@ -0,0 +1,9 @@ +/* LINTLIBRARY */ +#include "util.h" + +/* backwards compatibility */ +long +ptime() +{ + return util_cpu_time(); +} diff --git a/resources/3rdparty/cudd-2.5.0/util/restart.c b/resources/3rdparty/cudd-2.5.0/util/restart.c new file mode 100644 index 000000000..b81dcb8c8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/restart.c @@ -0,0 +1,137 @@ +#include +#include "util.h" + +#if (defined(sun) && ! defined(sparc)) || defined(vax) + +#include +#include +#include + +static char *save_stack_base; +static char *stack_lo_addr; +static char *stack_hi_addr; +static int stack_size; + +static int restart_global_flag; +static char *old_file_name; +static char *new_file_name; + +char *util_save_sp; /* set by util_restart_save_state() */ +extern char *sbrk(); + +static void +grow_stack() +{ + int i, space[256]; + + for(i = 0; i < 256; i++) { + space[i] = 0; + } + if ((char *) &i > stack_lo_addr) { + grow_stack(); + } +} + + +/* ARGSUSED */ +static int +handle_sigquit(int sig, int code, struct sigcontext *scp) +{ + if (util_restart_save_state()) { + /* we are restarting ! -- return from signal */ + + } else { + /* copy stack to user data space */ + stack_lo_addr = util_save_sp; + stack_size = stack_hi_addr - stack_lo_addr + 1; + save_stack_base = sbrk(stack_size); + (void) memcpy(save_stack_base, stack_lo_addr, stack_size); + + /* write a new executable */ + (void) fprintf(stderr, "Writing executable %s ...\n", new_file_name); + (void) util_save_image(old_file_name, new_file_name); + + /* terminate if signal was a QUIT */ + if (sig == SIGQUIT) { + (void) _exit(1); + } + } +} + + +static void +restart_program() +{ + (void) fprintf(stderr, "Continuing execution ...\n"); + + /* create the stack */ + grow_stack(); + +#ifdef vax + asm("movl _util_save_sp,sp"); +#endif +#ifdef sun + asm("movl _util_save_sp,sp"); +#endif + + /* copy the stack back from user space */ + (void) memcpy(stack_lo_addr, save_stack_base, stack_size); + + /* remove the sbrk for the stack */ + if (sbrk(-stack_size) < 0) { + perror("sbrk"); + } + + util_restart_restore_state(); /* jump back into handle_sigquit() */ +} + +void +util_restart(char const *old, char const *neW, int interval) +{ + struct itimerval itimer; + +#ifdef vax +#ifdef ultrix + stack_hi_addr = (char *) 0x7fffe3ff; /* ultrix */ +#else + stack_hi_addr = (char *) 0x7fffebff; /* bsd 4.3 */ +#endif +#endif +#ifdef sun + stack_hi_addr = (char *) 0x0effffff; /* Sun OS 3.2, 3.4 */ +#endif + + old_file_name = old; + new_file_name = neW; + + (void) signal(SIGQUIT, handle_sigquit); + + if (interval > 0) { + (void) signal(SIGVTALRM, handle_sigquit); + itimer.it_interval.tv_sec = interval; + itimer.it_interval.tv_usec = 0; + itimer.it_value.tv_sec = interval; + itimer.it_value.tv_usec = 0; + if (setitimer(ITIMER_VIRTUAL, &itimer, (struct itimerval *) 0) < 0) { + perror("setitimer"); + exit(1); + } + } + + if (restart_global_flag) { + restart_program(); + } + restart_global_flag = 1; +} + +#else + +/* ARGSUSED */ +void +util_restart(char const *old, char const *neW, int interval) +{ + (void) fprintf(stderr, + "util_restart: not supported on your operating system/hardware\n"); +} + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/util/safe_mem.c b/resources/3rdparty/cudd-2.5.0/util/safe_mem.c new file mode 100644 index 000000000..597cc892b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/safe_mem.c @@ -0,0 +1,97 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + +/* + * These are interface routines to be placed between a program and the + * system memory allocator. + * + * It forces well-defined semantics for several 'borderline' cases: + * + * malloc() of a 0 size object is guaranteed to return something + * which is not 0, and can safely be freed (but not dereferenced) + * free() accepts (silently) an 0 pointer + * realloc of a 0 pointer is allowed, and is equiv. to malloc() + * For the IBM/PC it forces no object > 64K; note that the size argument + * to malloc/realloc is a 'long' to catch this condition + * + * The function pointer MMoutOfMemory() contains a vector to handle a + * 'out-of-memory' error (which, by default, points at a simple wrap-up + * and exit routine). + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern char *MMalloc(long); +extern void MMout_of_memory(long); +extern char *MMrealloc(char *, long); + +void (*MMoutOfMemory)(long) = MMout_of_memory; + +#ifdef __cplusplus +} +#endif + + +/* MMout_of_memory -- out of memory for lazy people, flush and exit */ +void +MMout_of_memory(long size) +{ + (void) fflush(stdout); + (void) fprintf(stderr, "\nout of memory allocating %lu bytes\n", + (unsigned long) size); + exit(1); +} + + +char * +MMalloc(long size) +{ + char *p; + +#ifdef IBMPC + if (size > 65000L) { + if (MMoutOfMemory != (void (*)(long)) 0 ) (*MMoutOfMemory)(size); + return NIL(char); + } +#endif + if (size == 0) size = sizeof(long); + if ((p = (char *) malloc((unsigned long) size)) == NIL(char)) { + if (MMoutOfMemory != 0 ) (*MMoutOfMemory)(size); + return NIL(char); + } + return p; +} + + +char * +MMrealloc(char *obj, long size) +{ + char *p; + +#ifdef IBMPC + if (size > 65000L) { + if (MMoutOfMemory != 0 ) (*MMoutOfMemory)(size); + return NIL(char); + } +#endif + if (obj == NIL(char)) return MMalloc(size); + if (size <= 0) size = sizeof(long); + if ((p = (char *) realloc(obj, (unsigned long) size)) == NIL(char)) { + if (MMoutOfMemory != 0 ) (*MMoutOfMemory)(size); + return NIL(char); + } + return p; +} + + +void +MMfree(char *obj) +{ + if (obj != 0) { + free(obj); + } +} diff --git a/resources/3rdparty/cudd-2.5.0/util/saveimage.c b/resources/3rdparty/cudd-2.5.0/util/saveimage.c new file mode 100644 index 000000000..32332ef40 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/saveimage.c @@ -0,0 +1,229 @@ +/* LINTLIBRARY */ + + +/* + * saveimage.c -- + * + * Function to save an executable copy of the current process's + * image in a file. + * + */ + +#include +#include "util.h" + +#ifdef BSD +#include +#include +#include +#include + +extern int errno; + +#define BUFSIZE 8192 + +extern long lseek(); /* For lint */ +extern int getpagesize(); +extern char *sbrk(); + +static int copy_file(); +static int pad_file(); + + +int +util_save_image(char const *orig_file_name, char const *save_file_name) +{ + int origFd = -1, saveFd = -1; + char *start_data, *end_data, *start_text, *end_round; + struct exec old_hdr, new_hdr; + struct stat old_stat; + int n, page_size, length_text, length_data; + + if ((origFd = open(orig_file_name, 0)) < 0) { + perror(orig_file_name); + (void) fprintf(stderr, "Cannot open original a.out file\n"); + goto bad; + } + + if (fstat(origFd, &old_stat) < 0) { + perror(orig_file_name); + (void) fprintf(stderr, "Cannot stat original a.out file\n"); + goto bad; + } + + /* + * Read the a.out header from the original file. + */ + if (read(origFd, (char *) &old_hdr, sizeof(old_hdr)) != sizeof(old_hdr)) { + perror(orig_file_name); + (void) fprintf(stderr, "Cannot read original a.out header\n"); + goto bad; + } + if (N_BADMAG(old_hdr)) { + (void) fprintf(stderr, "File %s has a bad magic number (%o)\n", + orig_file_name, old_hdr.a_magic); + goto bad; + } + if (old_hdr.a_magic != ZMAGIC) { + (void) fprintf(stderr, "File %s is not demand-paged\n", orig_file_name); + goto bad; + } + + /* + * Open the output file. + */ + if (access(save_file_name, /* F_OK */ 0) == 0) { + (void) unlink(save_file_name); + } + if ((saveFd = creat(save_file_name, 0777)) < 0) { + if (errno == ETXTBSY) { + (void) unlink(save_file_name); + saveFd = creat(save_file_name, 0777); + } + if (saveFd < 0) { + perror(save_file_name); + (void) fprintf(stderr, "Cannot create save file.\n"); + goto bad; + } + } + + /* + * Find out how far the data segment extends. + */ + new_hdr = old_hdr; + end_data = sbrk(0); + page_size = getpagesize(); + n = ((((int) end_data) + page_size - 1) / page_size) * page_size; + end_round = (char *) n; + if (end_round > end_data) { + end_data = sbrk(end_round - end_data); + } + +#ifdef vax + start_text = 0; + length_text = new_hdr.a_text; + start_data = (char *) old_hdr.a_text; + length_data = end_data - start_data; +#endif vax +#ifdef sun + start_text = (char *) N_TXTADDR(old_hdr) + sizeof(old_hdr); + length_text = old_hdr.a_text - sizeof(old_hdr); + start_data = (char *) N_DATADDR(old_hdr); + length_data = end_data - start_data; +#endif sun + new_hdr.a_data = end_data - start_data; + new_hdr.a_bss = 0; + + /* + * First, the header plus enough pad to extend up to N_TXTOFF. + */ + if (write(saveFd, (char *) &new_hdr, (int) sizeof(new_hdr)) != + sizeof(new_hdr)) { + perror("write"); + (void) fprintf(stderr, "Error while copying header.\n"); + goto bad; + } + if (! pad_file(saveFd, N_TXTOFF(old_hdr) - sizeof(new_hdr))) { + (void) fprintf(stderr, "Error while padding.\n"); + goto bad; + } + + + /* + * Copy our text segment + */ + if (write(saveFd, start_text, length_text) != length_text) { + perror("write"); + (void) fprintf(stderr, "Error while copying text segment.\n"); + goto bad; + } + + + /* + * Copy our data segment + */ + if (write(saveFd, start_data, length_data) != length_data) { + perror("write"); + (void) fprintf(stderr, "Error while copying data segment.\n"); + goto bad; + } + + /* + * Copy the symbol table and everything else. + * This takes us to the end of the original file. + */ + (void) lseek(origFd, (long) N_SYMOFF(old_hdr), 0); + if (! copy_file(origFd, saveFd, old_stat.st_size - N_SYMOFF(old_hdr))) { + (void) fprintf(stderr, "Error while copying symbol table.\n"); + goto bad; + } + (void) close(origFd); + (void) close(saveFd); + return 1; + +bad: + if (origFd >= 0) (void) close(origFd); + if (saveFd >= 0) (void) close(saveFd); + return 0; +} + + +static int +copy_file(inFd, outFd, nbytes) +int inFd, outFd; +unsigned long nbytes; +{ + char buf[BUFSIZE]; + int nread, ntoread; + + while (nbytes > 0) { + ntoread = nbytes; + if (ntoread > sizeof buf) ntoread = sizeof buf; + if ((nread = read(inFd, buf, ntoread)) != ntoread) { + perror("read"); + return (0); + } + if (write(outFd, buf, nread) != nread) { + perror("write"); + return (0); + } + nbytes -= nread; + } + + return (1); +} + + +static int +pad_file(outFd, nbytes) +int outFd; +int nbytes; +{ + char buf[BUFSIZE]; + int nzero; + + nzero = (nbytes > sizeof(buf)) ? sizeof(buf) : nbytes; + bzero(buf, nzero); + while (nbytes > 0) { + nzero = (nbytes > sizeof(buf)) ? sizeof(buf) : nbytes; + if (write(outFd, buf, nzero) != nzero) { + perror("write"); + return (0); + } + nbytes -= nzero; + } + + return (1); +} +#else + +/* ARGSUSED */ +int +util_save_image(char const *orig_file_name, char const *save_file_name) +{ + (void) fprintf(stderr, + "util_save_image: not implemented on your operating system\n"); + return 0; +} + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/util/state.c b/resources/3rdparty/cudd-2.5.0/util/state.c new file mode 100644 index 000000000..ef830aa74 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/state.c @@ -0,0 +1,82 @@ +#ifdef lint +util_restart_save_state() +{ + return 0; +} + + +util_restart_restore_state() +{ +} + +#else + +static char rcsid[] = "$Id: state.c,v 1.1 1997/11/04 22:38:50 fabio Exp $"; + +#ifdef vax +int util_restart_state[32]; + +util_restart_save_state() +{ + asm("movl sp,_util_save_sp"); + asm("movl r1,_util_restart_state"); + asm("movl r2,_util_restart_state+4"); + asm("movl r3,_util_restart_state+8"); + asm("movl r4,_util_restart_state+12"); + asm("movl r5,_util_restart_state+16"); + asm("movl r6,_util_restart_state+20"); + asm("movl r7,_util_restart_state+24"); + asm("movl r8,_util_restart_state+28"); + asm("movl r9,_util_restart_state+32"); + asm("movl r10,_util_restart_state+36"); + asm("movl r11,_util_restart_state+40"); + asm("movl 8(fp),_util_restart_state+44"); + asm("movl 12(fp),_util_restart_state+48"); + asm("movl 16(fp),_util_restart_state+52"); + asm("movl $0,r0"); +} + +util_restart_restore_state() +{ + asm("movl _util_restart_state,r1"); + asm("movl _util_restart_state+4,r2"); + asm("movl _util_restart_state+8,r3"); + asm("movl _util_restart_state+12,r4"); + asm("movl _util_restart_state+16,r5"); + asm("movl _util_restart_state+20,r6"); + asm("movl _util_restart_state+24,r7"); + asm("movl _util_restart_state+28,r8"); + asm("movl _util_restart_state+32,r9"); + asm("movl _util_restart_state+36,r10"); + asm("movl _util_restart_state+40,r11"); + asm("movl _util_restart_state+44,ap"); + asm("movl _util_restart_state+48,fp"); + asm("addl3 fp,$4,sp"); + asm("movl _util_restart_state+52,r0"); + asm("jmp (r0)"); +} +#endif + + +#if defined(sun) && ! defined(sparc) +int util_restart_state[32]; + +util_restart_save_state() +{ + asm("movel sp,_util_save_sp"); + asm("movel sp@,_util_restart_state"); + asm("movel sp@(0x4),_util_restart_state+4"); + asm("moveml #0xFFFF,_util_restart_state+8"); + return 0; +} + +util_restart_restore_state() +{ + asm("moveml _util_restart_state+8,#0xFFFF"); + asm("movel _util_restart_state+4,sp@(0x4)"); + asm("movel _util_restart_state,sp@"); + return 1; +} +#endif + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/util/strsav.c b/resources/3rdparty/cudd-2.5.0/util/strsav.c new file mode 100644 index 000000000..454e237c4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/strsav.c @@ -0,0 +1,14 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + + +/* + * util_strsav -- save a copy of a string + */ +char * +util_strsav(char const *s) +{ + return strcpy(ALLOC(char, strlen(s)+1), s); +} diff --git a/resources/3rdparty/cudd-2.5.0/util/stub.c b/resources/3rdparty/cudd-2.5.0/util/stub.c new file mode 100644 index 000000000..93f57e67f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/stub.c @@ -0,0 +1,82 @@ +/* LINTLIBRARY */ + +#ifdef LACK_SYS5 + +char * +memcpy(s1, s2, n) +char *s1, *s2; +int n; +{ + extern bcopy(); + bcopy(s2, s1, n); + return s1; +} + +char * +memset(s, c, n) +char *s; +int c; +int n; +{ + extern bzero(); + register int i; + + if (c == 0) { + bzero(s, n); + } else { + for(i = n-1; i >= 0; i--) { + *s++ = c; + } + } + return s; +} + +char * +strchr(s, c) +char *s; +int c; +{ + extern char *index(); + return index(s, c); +} + +char * +strrchr(s, c) +char *s; +int c; +{ + extern char *rindex(); + return rindex(s, c); +} + + +#endif + +#ifndef UNIX +#include + +FILE * +popen(string, mode) +const char *string; +const char *mode; +{ + (void) fprintf(stderr, "popen not supported on your operating system\n"); + return NULL; +} + + +int +pclose(fp) +FILE *fp; +{ + (void) fprintf(stderr, "pclose not supported on your operating system\n"); + return -1; +} +#endif + +/* put something here in case some compilers abort on empty files ... */ +int +util_do_nothing() +{ + return 1; +} diff --git a/resources/3rdparty/cudd-2.5.0/util/test-res.c b/resources/3rdparty/cudd-2.5.0/util/test-res.c new file mode 100644 index 000000000..e7af9c9fd --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/test-res.c @@ -0,0 +1,57 @@ +#include +#include "util.h" + + +main(argc, argv, environ) +int argc; +char **argv; +char **environ; +{ + int i; + char **ep, *prog; + + prog = util_path_search(argv[0]); + if (prog == NIL(char)) { + (void) fprintf(stderr, "Cannot find current executable\n"); + exit(1); + } + util_restart(prog, "a.out", 0); + + i = recur(10); + (void) fprintf(stderr, "terminated normally with i = %d\n", i); + + (void) printf("argc is %d\n", argc); + + for(i = 0, ep = argv; *ep != 0; i++, ep++) { + (void) printf("%08x (%08x-%08x)\targv[%d]:\t%s\n", + ep, *ep, *ep + strlen(*ep), i, *ep); + } + + i = 0; + for(i = 0, ep = environ; *ep != 0; ep++, i++) { + (void) printf("%08x (%08x-%08x)\tenviron[%d]:\t%s\n", + ep, *ep, *ep + strlen(*ep), i, *ep); + } + + (void) fprintf(stderr, "returning with status=4\n"); + return 4; +} + + +recur(cnt) +{ + int i, j, sum; + + if (cnt > 0) { + return recur(cnt-1); + } else { + sum = 0; + for(j = 0; j < 20; j++) { + for(i = 0; i < 100000; i++) { + sum += 1; + } + (void) printf("done loop %d\n", j); + } + return sum; + } +} diff --git a/resources/3rdparty/cudd-2.5.0/util/test-sav.c b/resources/3rdparty/cudd-2.5.0/util/test-sav.c new file mode 100644 index 000000000..3140671be --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/test-sav.c @@ -0,0 +1,39 @@ +#include +#include "util.h" + + +/* ARGSUSED */ +static int +saveit(prog, file2) +char *prog, *file2; +{ + char *file1; + + /* get current executable name by searching the path ... */ + file1 = util_path_search(prog); + if (file1 == 0) { + (void) fprintf(stderr, "cannot locate current executable\n"); + return 1; + } + + /* users name for the new executable -- perform tilde-expansion */ + if (! util_save_image(file1, file2)) { + (void) fprintf(stderr, "error occured during save ...\n"); + return 1; + } + FREE(file1); + return 0; +} + +int restart; + +main(argc, argv) +char **argv; +{ + if (restart) { + (void) printf("restarted ...\n"); + exit(0); + } + restart = 1; + exit(saveit(argv[0], "foobar")); +} diff --git a/resources/3rdparty/cudd-2.5.0/util/texpand.c b/resources/3rdparty/cudd-2.5.0/util/texpand.c new file mode 100644 index 000000000..c14defee8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/texpand.c @@ -0,0 +1,57 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + +#ifdef BSD +#include +#endif + + +char * +util_tilde_expand(char const *fname) +{ +#ifdef BSD + struct passwd *userRecord; + char username[256], *filename; + register int i, j; + + filename = ALLOC(char, strlen(fname) + 256); + + /* Clear the return string */ + i = 0; + filename[0] = '\0'; + + /* Tilde? */ + if (fname[0] == '~') { + j = 0; + i = 1; + while ((fname[i] != '\0') && (fname[i] != '/')) { + username[j++] = fname[i++]; + } + username[j] = '\0'; + + if (username[0] == '\0') { + /* ~/ resolves to home directory of current user */ + if ((userRecord = getpwuid(getuid())) != 0) { + (void) strcat(filename, userRecord->pw_dir); + } else { + i = 0; + } + } else { + /* ~user/ resolves to home directory of 'user' */ + if ((userRecord = getpwnam(username)) != 0) { + (void) strcat(filename, userRecord->pw_dir); + } else { + i = 0; + } + } + } + + /* Concantenate remaining portion of file name */ + (void) strcat(filename, fname + i); + return filename; +#else + return strsav(fname); +#endif +} diff --git a/resources/3rdparty/cudd-2.5.0/util/util.h b/resources/3rdparty/cudd-2.5.0/util/util.h new file mode 100644 index 000000000..410720379 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/util/util.h @@ -0,0 +1,204 @@ +/* $Id: util.h,v 1.10 2012/02/05 05:34:04 fabio Exp fabio $ */ + +#ifndef UTIL_H +#define UTIL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) +# define UTIL_INLINE __inline__ +# if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +# define UTIL_UNUSED __attribute__ ((unused)) +# else +# define UTIL_UNUSED +# endif +#else +# define UTIL_INLINE +# define UTIL_UNUSED +#endif + +#ifndef SIZEOF_VOID_P +#define SIZEOF_VOID_P 4 +#endif +#ifndef SIZEOF_INT +#define SIZEOF_INT 4 +#endif +#ifndef SIZEOF_LONG +#define SIZEOF_LONG 4 +#endif + +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +typedef long util_ptrint; +#else +typedef int util_ptrint; +#endif + +/* #define USE_MM */ /* choose libmm.a as the memory allocator */ + +/* these are too entrenched to get away with changing the name */ +#define strsav util_strsav +#include + +#define NIL(type) ((type *) 0) + +#if defined(USE_MM) || defined(MNEMOSYNE) +/* + * assumes the memory manager is either libmm.a or libmnem.a + * libmm.a: + * - allows malloc(0) or realloc(obj, 0) + * - catches out of memory (and calls MMout_of_memory()) + * - catch free(0) and realloc(0, size) in the macros + * libmnem.a: + * - reports memory leaks + * - is used in conjunction with the mnemalyse postprocessor + */ +#ifdef MNEMOSYNE +#include "mnemosyne.h" +#define ALLOC(type, num) \ + ((num) ? ((type *) malloc(sizeof(type) * (num))) : \ + ((type *) malloc(sizeof(long)))) +#else +#define ALLOC(type, num) \ + ((type *) malloc(sizeof(type) * (num))) +#endif +#define REALLOC(type, obj, num) \ + (obj) ? ((type *) realloc((char *) obj, sizeof(type) * (num))) : \ + ((type *) malloc(sizeof(type) * (num))) +#define FREE(obj) \ + ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) +#else +/* + * enforce strict semantics on the memory allocator + * - when in doubt, delete the '#define USE_MM' above + */ +#define ALLOC(type, num) \ + ((type *) MMalloc((long) sizeof(type) * (long) (num))) +#define REALLOC(type, obj, num) \ + ((type *) MMrealloc((char *) (obj), (long) sizeof(type) * (long) (num))) +#define FREE(obj) \ + ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) +#endif + + +/* Ultrix (and SABER) have 'fixed' certain functions which used to be int */ +#if defined(ultrix) || defined(SABER) || defined(aiws) || defined(hpux) || defined(apollo) || defined(__osf__) || defined(__SVR4) || defined(__GNUC__) +#define VOID_OR_INT void +#define VOID_OR_CHAR void +#else +#define VOID_OR_INT int +#define VOID_OR_CHAR char +#endif + + +/* No machines seem to have much of a problem with these */ +#include +#include + + +/* Some machines fail to define some functions in stdio.h */ +#if !defined(__STDC__) && !defined(__cplusplus) +extern FILE *popen(), *tmpfile(); +extern int pclose(); +#endif + + +/* most machines don't give us a header file for these */ +#if (defined(__STDC__) || defined(__cplusplus) || defined(ultrix)) && !defined(MNEMOSYNE) || defined(__SVR4) +# include +#else +# ifndef _IBMR2 + extern VOID_OR_INT abort(), exit(); +# endif +# if !defined(MNEMOSYNE) && !defined(_IBMR2) + extern VOID_OR_INT free (void *); + extern VOID_OR_CHAR *malloc(), *realloc(); +# endif + extern char *getenv(); + extern int system(); + extern double atof(); +#endif + + +/* some call it strings.h, some call it string.h; others, also have memory.h */ +#if defined(__STDC__) || defined(__cplusplus) || defined(_IBMR2) || defined(ultrix) +#include +#else +/* ANSI C string.h -- 1/11/88 Draft Standard */ +extern char *strcpy(), *strncpy(), *strcat(), *strncat(), *strerror(); +extern char *strpbrk(), *strtok(), *strchr(), *strrchr(), *strstr(); +extern int strcoll(), strxfrm(), strncmp(), strlen(), strspn(), strcspn(); +extern char *memmove(), *memccpy(), *memchr(), *memcpy(), *memset(); +extern int memcmp(), strcmp(); +#endif + + +#ifdef __STDC__ +#include +#else +#ifndef NDEBUG +#define assert(ex) {\ + if (! (ex)) {\ + (void) fprintf(stderr,\ + "Assertion failed: file %s, line %d\n\"%s\"\n",\ + __FILE__, __LINE__, "ex");\ + (void) fflush(stdout);\ + abort();\ + }\ +} +#else +#define assert(ex) ; +#endif +#endif + + +#define fail(why) {\ + (void) fprintf(stderr, "Fatal error: file %s, line %d\n%s\n",\ + __FILE__, __LINE__, why);\ + (void) fflush(stdout);\ + abort();\ +} + + +#ifdef lint +#undef putc /* correct lint '_flsbuf' bug */ +#undef ALLOC /* allow for lint -h flag */ +#undef REALLOC +#define ALLOC(type, num) (((type *) 0) + (num)) +#define REALLOC(type, obj, num) ((obj) + (num)) +#endif + + +/* These arguably do NOT belong in util.h */ +#define ABS(a) ((a) < 0 ? -(a) : (a)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + + +#ifndef USE_MM +extern char *MMalloc (long); +extern void MMout_of_memory (long); +extern void (*MMoutOfMemory) (long); +extern char *MMrealloc (char *, long); +#endif + +extern long util_cpu_time (void); +extern char *util_path_search (char const *); +extern char *util_file_search (char const *, char *, char const *); +extern int util_pipefork (char * const *, FILE **, FILE **, int *); +extern void util_print_cpu_stats (FILE *); +extern char *util_print_time (unsigned long); +extern int util_save_image (char const *, char const *); +extern char *util_strsav (char const *); +extern char *util_tilde_expand (char const *); +extern void util_restart (char const *, char const *, int); + + +extern unsigned long getSoftDataLimit (void); + +#ifdef __cplusplus +} +#endif + +#endif /* UTIL_H */ From 5f27a932a9746e60e7d21f2e34d4face5ceac7ef Mon Sep 17 00:00:00 2001 From: dehnert Date: Mon, 13 May 2013 18:53:34 +0200 Subject: [PATCH 119/152] Moved SCC decomposition to AbstractModel class, which was possible due to virtual iterator facilities in model classes. --- CMakeLists.txt | 4 +- src/models/AbstractDeterministicModel.h | 51 ++++++------------ src/models/AbstractModel.h | 51 +++++++++++++++++- src/models/AbstractNondeterministicModel.h | 63 +++++++--------------- 4 files changed, 88 insertions(+), 81 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a5a9a0bd..ae2c1fa2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ else() set (STORM_LIB_SUFFIX a) set (GTEST_LIBRARY ${PROJECT_SOURCE_DIR}/resources/3rdparty/gtest-1.6.0/libgtest.${STORM_LIB_SUFFIX}) set (GTEST_MAIN_LIBRARY ${PROJECT_SOURCE_DIR}/resources/3rdparty/gtest-1.6.0/libgtest_main.${STORM_LIB_SUFFIX}) - set (GTEST_LIBRARIES ${GTEST_LIBRARY}) # as we dont use FindGTest anymore + set (GTEST_LIBRARIES ${GTEST_LIBRARY} ${GTEST_MAIN_LIBRARY}) # as we dont use FindGTest anymore endif() message(STATUS "GTEST_INCLUDE_DIR is ${GTEST_INCLUDE_DIR}") message(STATUS "GTEST_LIBRARY is ${GTEST_LIBRARY}") @@ -126,6 +126,7 @@ file(GLOB_RECURSE STORM_MODELS_FILES ${PROJECT_SOURCE_DIR}/src/models/*.h ${PROJ file(GLOB_RECURSE STORM_PARSER_FILES ${PROJECT_SOURCE_DIR}/src/parser/*.h ${PROJECT_SOURCE_DIR}/src/parser/*.cpp) file(GLOB_RECURSE STORM_STORAGE_FILES ${PROJECT_SOURCE_DIR}/src/storage/*.h ${PROJECT_SOURCE_DIR}/src/storage/*.cpp) file(GLOB_RECURSE STORM_UTILITY_FILES ${PROJECT_SOURCE_DIR}/src/utility/*.h ${PROJECT_SOURCE_DIR}/src/utility/*.cpp) +file(GLOB_RECURSE STORM_IR_FILES ${PROJECT_SOURCE_DIR}/src/ir/*.h ${PROJECT_SOURCE_DIR}/src/ir/*.cpp) # Test Sources # Note that the tests also need the source files, except for the main file @@ -141,6 +142,7 @@ source_group(models FILES ${STORM_MODELS_FILES}) source_group(parser FILES ${STORM_PARSER_FILES}) source_group(storage FILES ${STORM_STORAGE_FILES}) source_group(utility FILES ${STORM_UTILITY_FILES}) +source_group(ir FILES ${STORM_IR_FILES}) source_group(test FILES ${STORM_TEST_FILES}) # Add base folder for better inclusion paths diff --git a/src/models/AbstractDeterministicModel.h b/src/models/AbstractDeterministicModel.h index f7594ba05..7048ab3ed 100644 --- a/src/models/AbstractDeterministicModel.h +++ b/src/models/AbstractDeterministicModel.h @@ -47,44 +47,23 @@ class AbstractDeterministicModel: public AbstractModel { } /*! - * Extracts the SCC dependency graph from the model according to the given SCC decomposition. + * Returns an iterator to the successors of the given state. * - * @param stronglyConnectedComponents A vector containing the SCCs of the system. - * @param stateToSccMap A mapping from state indices to + * @param state The state for which to return the iterator. + * @return An iterator to the successors of the given state. */ - virtual storm::storage::SparseMatrix extractSccDependencyGraph(std::vector> const& stronglyConnectedComponents, std::map const& stateToSccMap) { - // The resulting sparse matrix will have as many rows/columns as there are SCCs. - uint_fast64_t numberOfStates = stronglyConnectedComponents.size(); - storm::storage::SparseMatrix sccDependencyGraph(numberOfStates); - sccDependencyGraph.initialize(); - - for (uint_fast64_t currentSccIndex = 0; currentSccIndex < stronglyConnectedComponents.size(); ++currentSccIndex) { - // Get the actual SCC. - std::vector const& scc = stronglyConnectedComponents[currentSccIndex]; - - // Now, we determine the SCCs which are reachable (in one step) from the current SCC. - std::set allTargetSccs; - for (auto state : scc) { - for (typename storm::storage::SparseMatrix::ConstIndexIterator succIt = this->getTransitionMatrix()->constColumnIteratorBegin(state), succIte = this->getTransitionMatrix()->constColumnIteratorEnd(state); succIt != succIte; ++succIt) { - uint_fast64_t targetScc = stateToSccMap.find(*succIt)->second; - - // We only need to consider transitions that are actually leaving the SCC. - if (targetScc != currentSccIndex) { - allTargetSccs.insert(targetScc); - } - } - } - - // Now we can just enumerate all the target SCCs and insert the corresponding transitions. - for (auto targetScc : allTargetSccs) { - sccDependencyGraph.insertNextValue(currentSccIndex, targetScc, true); - } - } - - // Finalize the matrix. - sccDependencyGraph.finalize(true); - - return sccDependencyGraph; + virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorBegin(uint_fast64_t state) { + return this->getTransitionMatrix()->constColumnIteratorBegin(state); + } + + /*! + * Returns an iterator pointing to the element past the successors of the given state. + * + * @param state The state for which to return the iterator. + * @return An iterator pointing to the element past the successors of the given state. + */ + virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorEnd(uint_fast64_t state) { + return this->getTransitionMatrix()->constColumnIteratorEnd(state); } }; diff --git a/src/models/AbstractModel.h b/src/models/AbstractModel.h index 364e501b0..e50aa683f 100644 --- a/src/models/AbstractModel.h +++ b/src/models/AbstractModel.h @@ -91,7 +91,56 @@ class AbstractModel: public std::enable_shared_from_this> { * @param stronglyConnectedComponents A vector containing the SCCs of the system. * @param stateToSccMap A mapping from state indices to */ - virtual storm::storage::SparseMatrix extractSccDependencyGraph(std::vector> const& stronglyConnectedComponents, std::map const& stateToSccMap) = 0; + virtual storm::storage::SparseMatrix extractSccDependencyGraph(std::vector> const& stronglyConnectedComponents, std::map const& stateToSccMap) { + // The resulting sparse matrix will have as many rows/columns as there are SCCs. + uint_fast64_t numberOfStates = stronglyConnectedComponents.size(); + storm::storage::SparseMatrix sccDependencyGraph(numberOfStates); + sccDependencyGraph.initialize(); + + for (uint_fast64_t currentSccIndex = 0; currentSccIndex < stronglyConnectedComponents.size(); ++currentSccIndex) { + // Get the actual SCC. + std::vector const& scc = stronglyConnectedComponents[currentSccIndex]; + + // Now, we determine the SCCs which are reachable (in one step) from the current SCC. + std::set allTargetSccs; + for (auto state : scc) { + for (typename storm::storage::SparseMatrix::ConstIndexIterator succIt = this->constStateSuccessorIteratorBegin(state), succIte = this->constStateSuccessorIteratorEnd(state); succIt != succIte; ++succIt) { + uint_fast64_t targetScc = stateToSccMap.find(*succIt)->second; + + // We only need to consider transitions that are actually leaving the SCC. + if (targetScc != currentSccIndex) { + allTargetSccs.insert(targetScc); + } + } + } + + // Now we can just enumerate all the target SCCs and insert the corresponding transitions. + for (auto targetScc : allTargetSccs) { + sccDependencyGraph.insertNextValue(currentSccIndex, targetScc, true); + } + } + + // Finalize the matrix. + sccDependencyGraph.finalize(true); + + return sccDependencyGraph; + } + + /*! + * Returns an iterator to the successors of the given state. + * + * @param state The state for which to return the iterator. + * @return An iterator to the successors of the given state. + */ + virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorBegin(uint_fast64_t state) = 0; + + /*! + * Returns an iterator pointing to the element past the successors of the given state. + * + * @param state The state for which to return the iterator. + * @return An iterator pointing to the element past the successors of the given state. + */ + virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorEnd(uint_fast64_t state) = 0; /*! * Returns the state space size of the model. diff --git a/src/models/AbstractNondeterministicModel.h b/src/models/AbstractNondeterministicModel.h index 4c51f0863..cd2700a49 100644 --- a/src/models/AbstractNondeterministicModel.h +++ b/src/models/AbstractNondeterministicModel.h @@ -58,49 +58,6 @@ class AbstractNondeterministicModel: public AbstractModel { uint_fast64_t getNumberOfChoices() const { return this->getTransitionMatrix()->getRowCount(); } - - /*! - * Extracts the SCC dependency graph from the model according to the given SCC decomposition. - * - * @param stronglyConnectedComponents A vector containing the SCCs of the system. - * @param stateToSccMap A mapping from state indices to - */ - virtual storm::storage::SparseMatrix extractSccDependencyGraph(std::vector> const& stronglyConnectedComponents, std::map const& stateToSccMap) { - // The resulting sparse matrix will have as many rows/columns as there are SCCs. - uint_fast64_t numberOfStates = stronglyConnectedComponents.size(); - storm::storage::SparseMatrix sccDependencyGraph(numberOfStates); - sccDependencyGraph.initialize(); - - for (uint_fast64_t currentSccIndex = 0; currentSccIndex < stronglyConnectedComponents.size(); ++currentSccIndex) { - // Get the actual SCC. - std::vector const& scc = stronglyConnectedComponents[currentSccIndex]; - - // Now, we determine the SCCs which are reachable (in one step) from the current SCC. - std::set allTargetSccs; - for (auto state : scc) { - for (uint_fast64_t rowIndex = (*nondeterministicChoiceIndices)[state]; rowIndex < (*nondeterministicChoiceIndices)[state + 1]; ++rowIndex) { - for (typename storm::storage::SparseMatrix::ConstIndexIterator succIt = this->getTransitionMatrix()->constColumnIteratorBegin(rowIndex), succIte = this->getTransitionMatrix()->constColumnIteratorEnd(rowIndex); succIt != succIte; ++succIt) { - uint_fast64_t targetScc = stateToSccMap.find(*succIt)->second; - - // We only need to consider transitions that are actually leaving the SCC. - if (targetScc != currentSccIndex) { - allTargetSccs.insert(targetScc); - } - } - } - } - - // Now we can just enumerate all the target SCCs and insert the corresponding transitions. - for (auto targetScc : allTargetSccs) { - sccDependencyGraph.insertNextValue(currentSccIndex, targetScc, true); - } - } - - // Finalize the matrix. - sccDependencyGraph.finalize(true); - - return sccDependencyGraph; - } /*! * Retrieves the size of the internal representation of the model in memory. @@ -120,6 +77,26 @@ class AbstractNondeterministicModel: public AbstractModel { std::shared_ptr> getNondeterministicChoiceIndices() const { return nondeterministicChoiceIndices; } + + /*! + * Returns an iterator to the successors of the given state. + * + * @param state The state for which to return the iterator. + * @return An iterator to the successors of the given state. + */ + virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorBegin(uint_fast64_t state) { + return this->getTransitionMatrix()->constColumnIteratorBegin((*nondeterministicChoiceIndices)[state]); + } + + /*! + * Returns an iterator pointing to the element past the successors of the given state. + * + * @param state The state for which to return the iterator. + * @return An iterator pointing to the element past the successors of the given state. + */ + virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorEnd(uint_fast64_t state) { + return this->getTransitionMatrix()->constColumnIteratorEnd((*nondeterministicChoiceIndices)[state + 1] - 1); + } private: /*! A vector of indices mapping states to the choices (rows) in the transition matrix. */ From 27de566228cf9dbd537924c24b4f20ff6cc5e210 Mon Sep 17 00:00:00 2001 From: dehnert Date: Mon, 13 May 2013 20:03:26 +0200 Subject: [PATCH 120/152] Moved current tests to the functional test suite in an attempt to introduce performance tests. --- CMakeLists.txt | 5 +++-- resources/3rdparty/cudd-2.5.0/Makefile | 2 +- test/{ => functional}/eigen/EigenSparseMatrixTest.cpp | 0 .../{ => modelchecker}/EigenDtmcPrctModelCheckerTest.cpp | 6 +++--- .../{ => modelchecker}/GmmxxDtmcPrctModelCheckerTest.cpp | 6 +++--- .../{ => modelchecker}/GmmxxMdpPrctModelCheckerTest.cpp | 4 ++-- test/functional/{ => modelchecker}/die/testFormulas.prctl | 0 test/{ => functional}/parser/.gitignore | 0 test/{ => functional}/parser/CslParserTest.cpp | 0 test/{ => functional}/parser/LtlParserTest.cpp | 0 test/{ => functional}/parser/ParseMdpTest.cpp | 0 test/{ => functional}/parser/ParsePrismTest.cpp | 0 test/{ => functional}/parser/PrctlParserTest.cpp | 0 test/{ => functional}/parser/ReadLabFileTest.cpp | 0 test/{ => functional}/parser/ReadTraFileTest.cpp | 0 test/{ => functional}/parser/prctl_files/apOnly.prctl | 0 .../parser/prctl_files/complexFormula.prctl | 0 .../parser/prctl_files/probabilisticFormula.prctl | 0 .../parser/prctl_files/probabilisticNoBoundFormula.prctl | 0 .../parser/prctl_files/propositionalFormula.prctl | 0 .../{ => functional}/parser/prctl_files/rewardFormula.prctl | 0 .../parser/prctl_files/rewardNoBoundFormula.prctl | 0 test/{ => functional}/parser/readme.txt | 0 test/{ => functional}/storage/BitVectorTest.cpp | 0 test/{ => functional}/storage/SparseMatrixTest.cpp | 0 test/{ => functional}/storage/adapters/EigenAdapterTest.cpp | 0 test/{ => functional}/storage/adapters/GmmAdapterTest.cpp | 0 test/{ => functional}/storage/adapters/StormAdapterTest.cpp | 0 .../storm-functional-tests.cpp} | 0 29 files changed, 12 insertions(+), 11 deletions(-) rename test/{ => functional}/eigen/EigenSparseMatrixTest.cpp (100%) rename test/functional/{ => modelchecker}/EigenDtmcPrctModelCheckerTest.cpp (91%) rename test/functional/{ => modelchecker}/GmmxxDtmcPrctModelCheckerTest.cpp (92%) rename test/functional/{ => modelchecker}/GmmxxMdpPrctModelCheckerTest.cpp (95%) rename test/functional/{ => modelchecker}/die/testFormulas.prctl (100%) rename test/{ => functional}/parser/.gitignore (100%) rename test/{ => functional}/parser/CslParserTest.cpp (100%) rename test/{ => functional}/parser/LtlParserTest.cpp (100%) rename test/{ => functional}/parser/ParseMdpTest.cpp (100%) rename test/{ => functional}/parser/ParsePrismTest.cpp (100%) rename test/{ => functional}/parser/PrctlParserTest.cpp (100%) rename test/{ => functional}/parser/ReadLabFileTest.cpp (100%) rename test/{ => functional}/parser/ReadTraFileTest.cpp (100%) rename test/{ => functional}/parser/prctl_files/apOnly.prctl (100%) rename test/{ => functional}/parser/prctl_files/complexFormula.prctl (100%) rename test/{ => functional}/parser/prctl_files/probabilisticFormula.prctl (100%) rename test/{ => functional}/parser/prctl_files/probabilisticNoBoundFormula.prctl (100%) rename test/{ => functional}/parser/prctl_files/propositionalFormula.prctl (100%) rename test/{ => functional}/parser/prctl_files/rewardFormula.prctl (100%) rename test/{ => functional}/parser/prctl_files/rewardNoBoundFormula.prctl (100%) rename test/{ => functional}/parser/readme.txt (100%) rename test/{ => functional}/storage/BitVectorTest.cpp (100%) rename test/{ => functional}/storage/SparseMatrixTest.cpp (100%) rename test/{ => functional}/storage/adapters/EigenAdapterTest.cpp (100%) rename test/{ => functional}/storage/adapters/GmmAdapterTest.cpp (100%) rename test/{ => functional}/storage/adapters/StormAdapterTest.cpp (100%) rename test/{storm-tests.cpp => functional/storm-functional-tests.cpp} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae2c1fa2c..91df3d3f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,7 +130,7 @@ file(GLOB_RECURSE STORM_IR_FILES ${PROJECT_SOURCE_DIR}/src/ir/*.h ${PROJECT_SOUR # Test Sources # Note that the tests also need the source files, except for the main file -file(GLOB_RECURSE STORM_TEST_FILES ${PROJECT_SOURCE_DIR}/test/*.h ${PROJECT_SOURCE_DIR}/test/*.cpp) +file(GLOB_RECURSE STORM_FUNCTIONAL_TEST_FILES ${PROJECT_SOURCE_DIR}/test/functional/*.h ${PROJECT_SOURCE_DIR}/test/functional/*.cpp) # Group the headers and sources source_group(main FILES ${STORM_MAIN_FILE}) @@ -226,7 +226,8 @@ endif(CUDD_LIBRARY_DIRS) # Add the executables # Must be created *after* Boost was added because of LINK_DIRECTORIES add_executable(storm ${STORM_SOURCES} ${STORM_HEADERS}) -add_executable(storm-tests ${STORM_TEST_FILES} ${STORM_SOURCES_WITHOUT_MAIN} ${STORM_HEADERS}) +add_executable(storm-functional-tests ${STORM_FUNCTIONAL_TEST_FILES} ${STORM_SOURCES_WITHOUT_MAIN} ${STORM_HEADERS}) +add_executable(storm-performance-tests ${STORM_PERFORMANCE_TEST_FILES} ${STORM_SOURCES_WITHOUT_MAIN} ${STORM_HEADERS}) # Add target link deps for Boost program options target_link_libraries(storm ${Boost_LIBRARIES}) diff --git a/resources/3rdparty/cudd-2.5.0/Makefile b/resources/3rdparty/cudd-2.5.0/Makefile index 6c7fbb4d3..95a0a47d5 100644 --- a/resources/3rdparty/cudd-2.5.0/Makefile +++ b/resources/3rdparty/cudd-2.5.0/Makefile @@ -51,7 +51,7 @@ RANLIB = ranlib #ICFLAGS = # These two are typical settings for optimized code with gcc. #ICFLAGS = -g -O3 -Wall -ICFLAGS = -O3 +ICFLAGS = -O4 # Use XCFLAGS to specify machine-dependent compilation flags. # For some platforms no special flags are needed. diff --git a/test/eigen/EigenSparseMatrixTest.cpp b/test/functional/eigen/EigenSparseMatrixTest.cpp similarity index 100% rename from test/eigen/EigenSparseMatrixTest.cpp rename to test/functional/eigen/EigenSparseMatrixTest.cpp diff --git a/test/functional/EigenDtmcPrctModelCheckerTest.cpp b/test/functional/modelchecker/EigenDtmcPrctModelCheckerTest.cpp similarity index 91% rename from test/functional/EigenDtmcPrctModelCheckerTest.cpp rename to test/functional/modelchecker/EigenDtmcPrctModelCheckerTest.cpp index f2774c259..ced6139cb 100644 --- a/test/functional/EigenDtmcPrctModelCheckerTest.cpp +++ b/test/functional/modelchecker/EigenDtmcPrctModelCheckerTest.cpp @@ -9,7 +9,7 @@ TEST(EigenDtmcPrctModelCheckerTest, Die) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/die/die.tra", STORM_CPP_TESTS_BASE_PATH "/functional/die/die.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/die/die.coin_flips.trans.rew"); + storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/die/die.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/die/die.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/die/die.coin_flips.trans.rew"); ASSERT_EQ(parser.getType(), storm::models::DTMC); @@ -69,7 +69,7 @@ TEST(EigenDtmcPrctModelCheckerTest, Die) { TEST(EigenDtmcPrctModelCheckerTest, Crowds) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/crowds/crowds5_5.tra", STORM_CPP_TESTS_BASE_PATH "/functional/crowds/crowds5_5.lab", "", ""); + storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/crowds/crowds5_5.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/crowds/crowds5_5.lab", "", ""); ASSERT_EQ(parser.getType(), storm::models::DTMC); @@ -117,7 +117,7 @@ TEST(EigenDtmcPrctModelCheckerTest, Crowds) { TEST(EigenDtmcPrctModelCheckerTest, SynchronousLeader) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/synchronous_leader/leader4_8.tra", STORM_CPP_TESTS_BASE_PATH "/functional/synchronous_leader/leader4_8.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/synchronous_leader/leader4_8.pick.trans.rew"); + storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/synchronous_leader/leader4_8.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/synchronous_leader/leader4_8.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/synchronous_leader/leader4_8.pick.trans.rew"); ASSERT_EQ(parser.getType(), storm::models::DTMC); diff --git a/test/functional/GmmxxDtmcPrctModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp similarity index 92% rename from test/functional/GmmxxDtmcPrctModelCheckerTest.cpp rename to test/functional/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp index aa2a014fa..2286cd8d9 100644 --- a/test/functional/GmmxxDtmcPrctModelCheckerTest.cpp +++ b/test/functional/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp @@ -8,7 +8,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Die) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/die/die.tra", STORM_CPP_TESTS_BASE_PATH "/functional/die/die.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/die/die.coin_flips.trans.rew"); + storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/die/die.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/die/die.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/die/die.coin_flips.trans.rew"); ASSERT_EQ(parser.getType(), storm::models::DTMC); @@ -75,7 +75,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Die) { TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/crowds/crowds5_5.tra", STORM_CPP_TESTS_BASE_PATH "/functional/crowds/crowds5_5.lab", "", ""); + storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/crowds/crowds5_5.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/crowds/crowds5_5.lab", "", ""); ASSERT_EQ(parser.getType(), storm::models::DTMC); @@ -129,7 +129,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/synchronous_leader/leader4_8.tra", STORM_CPP_TESTS_BASE_PATH "/functional/synchronous_leader/leader4_8.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/synchronous_leader/leader4_8.pick.trans.rew"); + storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/synchronous_leader/leader4_8.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/synchronous_leader/leader4_8.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/synchronous_leader/leader4_8.pick.trans.rew"); ASSERT_EQ(parser.getType(), storm::models::DTMC); diff --git a/test/functional/GmmxxMdpPrctModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp similarity index 95% rename from test/functional/GmmxxMdpPrctModelCheckerTest.cpp rename to test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp index 13136cc69..43fbd9c35 100644 --- a/test/functional/GmmxxMdpPrctModelCheckerTest.cpp +++ b/test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp @@ -7,7 +7,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Dice) { storm::settings::Settings* s = storm::settings::instance(); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/two_dice/two_dice.tra", STORM_CPP_TESTS_BASE_PATH "/functional/two_dice/two_dice.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/two_dice/two_dice.flip.trans.rew"); + storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "functional/modelchecker/two_dice/two_dice.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.flip.trans.rew"); ASSERT_EQ(parser.getType(), storm::models::MDP); @@ -171,7 +171,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Dice) { TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { storm::settings::Settings* s = storm::settings::instance(); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/asynchronous_leader/leader4.tra", STORM_CPP_TESTS_BASE_PATH "/functional/asynchronous_leader/leader4.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/asynchronous_leader/leader4.trans.rew"); + storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/asynchronous_leader/leader4.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/asynchronous_leader/leader4.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/asynchronous_leader/leader4.trans.rew"); ASSERT_EQ(parser.getType(), storm::models::MDP); diff --git a/test/functional/die/testFormulas.prctl b/test/functional/modelchecker/die/testFormulas.prctl similarity index 100% rename from test/functional/die/testFormulas.prctl rename to test/functional/modelchecker/die/testFormulas.prctl diff --git a/test/parser/.gitignore b/test/functional/parser/.gitignore similarity index 100% rename from test/parser/.gitignore rename to test/functional/parser/.gitignore diff --git a/test/parser/CslParserTest.cpp b/test/functional/parser/CslParserTest.cpp similarity index 100% rename from test/parser/CslParserTest.cpp rename to test/functional/parser/CslParserTest.cpp diff --git a/test/parser/LtlParserTest.cpp b/test/functional/parser/LtlParserTest.cpp similarity index 100% rename from test/parser/LtlParserTest.cpp rename to test/functional/parser/LtlParserTest.cpp diff --git a/test/parser/ParseMdpTest.cpp b/test/functional/parser/ParseMdpTest.cpp similarity index 100% rename from test/parser/ParseMdpTest.cpp rename to test/functional/parser/ParseMdpTest.cpp diff --git a/test/parser/ParsePrismTest.cpp b/test/functional/parser/ParsePrismTest.cpp similarity index 100% rename from test/parser/ParsePrismTest.cpp rename to test/functional/parser/ParsePrismTest.cpp diff --git a/test/parser/PrctlParserTest.cpp b/test/functional/parser/PrctlParserTest.cpp similarity index 100% rename from test/parser/PrctlParserTest.cpp rename to test/functional/parser/PrctlParserTest.cpp diff --git a/test/parser/ReadLabFileTest.cpp b/test/functional/parser/ReadLabFileTest.cpp similarity index 100% rename from test/parser/ReadLabFileTest.cpp rename to test/functional/parser/ReadLabFileTest.cpp diff --git a/test/parser/ReadTraFileTest.cpp b/test/functional/parser/ReadTraFileTest.cpp similarity index 100% rename from test/parser/ReadTraFileTest.cpp rename to test/functional/parser/ReadTraFileTest.cpp diff --git a/test/parser/prctl_files/apOnly.prctl b/test/functional/parser/prctl_files/apOnly.prctl similarity index 100% rename from test/parser/prctl_files/apOnly.prctl rename to test/functional/parser/prctl_files/apOnly.prctl diff --git a/test/parser/prctl_files/complexFormula.prctl b/test/functional/parser/prctl_files/complexFormula.prctl similarity index 100% rename from test/parser/prctl_files/complexFormula.prctl rename to test/functional/parser/prctl_files/complexFormula.prctl diff --git a/test/parser/prctl_files/probabilisticFormula.prctl b/test/functional/parser/prctl_files/probabilisticFormula.prctl similarity index 100% rename from test/parser/prctl_files/probabilisticFormula.prctl rename to test/functional/parser/prctl_files/probabilisticFormula.prctl diff --git a/test/parser/prctl_files/probabilisticNoBoundFormula.prctl b/test/functional/parser/prctl_files/probabilisticNoBoundFormula.prctl similarity index 100% rename from test/parser/prctl_files/probabilisticNoBoundFormula.prctl rename to test/functional/parser/prctl_files/probabilisticNoBoundFormula.prctl diff --git a/test/parser/prctl_files/propositionalFormula.prctl b/test/functional/parser/prctl_files/propositionalFormula.prctl similarity index 100% rename from test/parser/prctl_files/propositionalFormula.prctl rename to test/functional/parser/prctl_files/propositionalFormula.prctl diff --git a/test/parser/prctl_files/rewardFormula.prctl b/test/functional/parser/prctl_files/rewardFormula.prctl similarity index 100% rename from test/parser/prctl_files/rewardFormula.prctl rename to test/functional/parser/prctl_files/rewardFormula.prctl diff --git a/test/parser/prctl_files/rewardNoBoundFormula.prctl b/test/functional/parser/prctl_files/rewardNoBoundFormula.prctl similarity index 100% rename from test/parser/prctl_files/rewardNoBoundFormula.prctl rename to test/functional/parser/prctl_files/rewardNoBoundFormula.prctl diff --git a/test/parser/readme.txt b/test/functional/parser/readme.txt similarity index 100% rename from test/parser/readme.txt rename to test/functional/parser/readme.txt diff --git a/test/storage/BitVectorTest.cpp b/test/functional/storage/BitVectorTest.cpp similarity index 100% rename from test/storage/BitVectorTest.cpp rename to test/functional/storage/BitVectorTest.cpp diff --git a/test/storage/SparseMatrixTest.cpp b/test/functional/storage/SparseMatrixTest.cpp similarity index 100% rename from test/storage/SparseMatrixTest.cpp rename to test/functional/storage/SparseMatrixTest.cpp diff --git a/test/storage/adapters/EigenAdapterTest.cpp b/test/functional/storage/adapters/EigenAdapterTest.cpp similarity index 100% rename from test/storage/adapters/EigenAdapterTest.cpp rename to test/functional/storage/adapters/EigenAdapterTest.cpp diff --git a/test/storage/adapters/GmmAdapterTest.cpp b/test/functional/storage/adapters/GmmAdapterTest.cpp similarity index 100% rename from test/storage/adapters/GmmAdapterTest.cpp rename to test/functional/storage/adapters/GmmAdapterTest.cpp diff --git a/test/storage/adapters/StormAdapterTest.cpp b/test/functional/storage/adapters/StormAdapterTest.cpp similarity index 100% rename from test/storage/adapters/StormAdapterTest.cpp rename to test/functional/storage/adapters/StormAdapterTest.cpp diff --git a/test/storm-tests.cpp b/test/functional/storm-functional-tests.cpp similarity index 100% rename from test/storm-tests.cpp rename to test/functional/storm-functional-tests.cpp From 3851377064408e28a6ca317592c051b2b7e7c231 Mon Sep 17 00:00:00 2001 From: dehnert Date: Mon, 13 May 2013 22:53:00 +0200 Subject: [PATCH 121/152] Introduced executable storm-functional-tests and storm-performance-tests. While the former contains the previous tests, the latter is currently empty, but will hold performance tests in the future. --- CMakeLists.txt | 45 +++--- .../SparseDtmcPrctlModelChecker.h | 8 +- .../eigen/EigenSparseMatrixTest.cpp | 2 +- .../GmmxxMdpPrctModelCheckerTest.cpp | 128 +++++++++--------- test/functional/parser/CslParserTest.cpp | 7 +- test/functional/parser/ParseMdpTest.cpp | 4 +- test/functional/parser/ReadLabFileTest.cpp | 8 +- test/functional/parser/ReadTraFileTest.cpp | 8 +- test/functional/storm-functional-tests.cpp | 4 +- 9 files changed, 109 insertions(+), 105 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 91df3d3f4..a99f224da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,7 +95,7 @@ else(CLANG) # As CLANG is not set as a variable, we need to set it in case we have not matched another compiler. set (CLANG ON) # Set standard flags for clang - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -funroll-loops -O4") + set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -funroll-loops -O4") set (CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Wall -Werror -pedantic -Wno-unused-variable -DBOOST_RESULT_OF_USE_TR1 -DBOOST_NO_DECLTYPE") set (CMAKE_CXX_FLAGS_DEBUG "-g") @@ -131,6 +131,7 @@ file(GLOB_RECURSE STORM_IR_FILES ${PROJECT_SOURCE_DIR}/src/ir/*.h ${PROJECT_SOUR # Test Sources # Note that the tests also need the source files, except for the main file file(GLOB_RECURSE STORM_FUNCTIONAL_TEST_FILES ${PROJECT_SOURCE_DIR}/test/functional/*.h ${PROJECT_SOURCE_DIR}/test/functional/*.cpp) +file(GLOB_RECURSE STORM_PERFORMANCE_TEST_FILES ${PROJECT_SOURCE_DIR}/test/performance/*.h ${PROJECT_SOURCE_DIR}/test/performance/*.cpp) # Group the headers and sources source_group(main FILES ${STORM_MAIN_FILE}) @@ -143,7 +144,8 @@ source_group(parser FILES ${STORM_PARSER_FILES}) source_group(storage FILES ${STORM_STORAGE_FILES}) source_group(utility FILES ${STORM_UTILITY_FILES}) source_group(ir FILES ${STORM_IR_FILES}) -source_group(test FILES ${STORM_TEST_FILES}) +source_group(functional-test FILES ${STORM_FUNCTIONAL_TEST_FILES}) +source_group(performance-test FILES ${STORM_PERFORMANCE_TEST_FILES}) # Add base folder for better inclusion paths include_directories("${PROJECT_SOURCE_DIR}") @@ -231,11 +233,13 @@ add_executable(storm-performance-tests ${STORM_PERFORMANCE_TEST_FILES} ${STORM_S # Add target link deps for Boost program options target_link_libraries(storm ${Boost_LIBRARIES}) -target_link_libraries(storm-tests ${Boost_LIBRARIES}) +target_link_libraries(storm-functional-tests ${Boost_LIBRARIES}) +target_link_libraries(storm-performance-tests ${Boost_LIBRARIES}) if (USE_INTELTBB) target_link_libraries(storm tbb tbbmalloc) - target_link_libraries(storm-tests tbb tbbmalloc) + target_link_libraries(storm-functional-tests tbb tbbmalloc) + target_link_libraries(storm-performance-tests tbb tbbmalloc) endif(USE_INTELTBB) if (APPLE) @@ -256,14 +260,16 @@ if (STORM_USE_COTIRE) cotire(storm) target_link_libraries(storm_unity ${Boost_LIBRARIES}) - #cotire(storm-tests) + #cotire(storm-functional-tests) + #cotire(storm-performance-tests) endif() # Link against libc++abi if requested. May be needed to build on Linux systems using clang. if (LINK_LIBCXXABI) message (STATUS "Linking against libc++abi.") target_link_libraries(storm "c++abi") - target_link_libraries(storm-tests "c++abi") + target_link_libraries(storm-functional-tests "c++abi") + target_link_libraries(storm-performance-tests "c++abi") endif(LINK_LIBCXXABI) # Add a target to generate API documentation with Doxygen @@ -282,9 +288,11 @@ if (GTEST_INCLUDE_DIR) enable_testing() include_directories(${GTEST_INCLUDE_DIR}) - target_link_libraries(storm-tests ${GTEST_LIBRARIES}) + target_link_libraries(storm-functional-tests ${GTEST_LIBRARIES}) + target_link_libraries(storm-performance-tests ${GTEST_LIBRARIES}) - add_test(NAME storm-tests COMMAND storm-tests) + add_test(NAME storm-functional-tests COMMAND storm-functional-tests) + add_test(NAME storm-performance-tests COMMAND storm-performance-tests) if(MSVC) # VS2012 doesn't support correctly the tuples yet add_definitions( /D _VARIADIC_MAX=10 ) endif() @@ -296,20 +304,23 @@ if (LOG4CPLUS_INCLUDE_DIR) if (STORM_USE_COTIRE) target_link_libraries(storm_unity ${LOG4CPLUS_LIBRARIES}) endif(STORM_USE_COTIRE) - target_link_libraries(storm-tests ${LOG4CPLUS_LIBRARIES}) + target_link_libraries(storm-functional-tests ${LOG4CPLUS_LIBRARIES}) + target_link_libraries(storm-performance-tests ${LOG4CPLUS_LIBRARIES}) # On Linux, we have to link against librt if (UNIX AND NOT APPLE) target_link_libraries(storm rt) if (STORM_USE_COTIRE) target_link_libraries(storm_unity rt) endif(STORM_USE_COTIRE) - target_link_libraries(storm-tests rt) + target_link_libraries(storm-functional-tests rt) + target_link_libraries(storm-performance-tests rt) endif(UNIX AND NOT APPLE) endif(LOG4CPLUS_INCLUDE_DIR) if (CUDD_LIBRARY_DIRS) target_link_libraries(storm "-lobj -lcudd -lmtr -lst -lutil -lepd") - target_link_libraries(storm-tests "-lobj -lcudd -lmtr -lst -lutil -lepd") + target_link_libraries(storm-functional-tests "-lobj -lcudd -lmtr -lst -lutil -lepd") + target_link_libraries(storm-performance-tests "-lobj -lcudd -lmtr -lst -lutil -lepd") endif(CUDD_LIBRARY_DIRS) if (THREADS_FOUND) @@ -318,7 +329,8 @@ if (THREADS_FOUND) if (STORM_USE_COTIRE) target_link_libraries(storm_unity ${CMAKE_THREAD_LIBS_INIT}) endif(STORM_USE_COTIRE) - target_link_libraries(storm-tests ${CMAKE_THREAD_LIBS_INIT}) + target_link_libraries(storm-functional-tests ${CMAKE_THREAD_LIBS_INIT}) + target_link_libraries(storm-performance-tests ${CMAKE_THREAD_LIBS_INIT}) endif(THREADS_FOUND) # Configure a header file to pass some of the CMake settings to the source code @@ -327,10 +339,9 @@ configure_file ( "${PROJECT_BINARY_DIR}/storm-config.h" ) -add_custom_target(memcheck valgrind --leak-check=full --show-reachable=yes ${PROJECT_BINARY_DIR}/storm -v --fix-deadlocks ${PROJECT_SOURCE_DIR}/examples/dtmc/crowds/crowds5_5.tra examples/dtmc/crowds/crowds5_5.lab - DEPENDS storm) -add_custom_target(memcheck-tests valgrind --leak-check=full --show-reachable=yes ${PROJECT_BINARY_DIR}/storm-tests -v --fix-deadlocks - DEPENDS storm-tests) - +add_custom_target(memcheck valgrind --leak-check=full --show-reachable=yes ${PROJECT_BINARY_DIR}/storm -v --fix-deadlocks ${PROJECT_SOURCE_DIR}/examples/dtmc/crowds/crowds5_5.tra examples/dtmc/crowds/crowds5_5.lab DEPENDS storm) +add_custom_target(memcheck-functional-tests valgrind --leak-check=full --show-reachable=yes ${PROJECT_BINARY_DIR}/storm-functional-tests -v --fix-deadlocks DEPENDS storm-functional-tests) +add_custom_target(memcheck-performance-tests valgrind --leak-check=full --show-reachable=yes ${PROJECT_BINARY_DIR}/storm-performance-tests -v --fix-deadlocks DEPENDS storm-performance-tests) + set (CPPLINT_ARGS --filter=-whitespace/tab,-whitespace/line_length,-legal/copyright,-readability/streams) add_custom_target(style python cpplint.py ${CPPLINT_ARGS} `find ./src/ -iname "*.h" -or -iname "*.cpp"`) diff --git a/src/modelchecker/SparseDtmcPrctlModelChecker.h b/src/modelchecker/SparseDtmcPrctlModelChecker.h index f55f79db5..56c7a9525 100644 --- a/src/modelchecker/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/SparseDtmcPrctlModelChecker.h @@ -94,10 +94,6 @@ public: // Make all rows absorbing that violate both sub-formulas or satisfy the second sub-formula. tmpMatrix.makeRowsAbsorbing(~(*leftStates | *rightStates) | *rightStates); - // Delete obsolete intermediates. - delete leftStates; - delete rightStates; - // Create the vector with which to multiply. std::vector* result = new std::vector(this->getModel().getNumberOfStates()); storm::utility::setVectorValues(result, *rightStates, storm::utility::constGetOne()); @@ -105,7 +101,9 @@ public: // Perform the matrix vector multiplication as often as required by the formula bound. this->performMatrixVectorMultiplication(tmpMatrix, *result, nullptr, formula.getBound()); - // Return result. + // Delete obsolete intermediates and return result. + delete leftStates; + delete rightStates; return result; } diff --git a/test/functional/eigen/EigenSparseMatrixTest.cpp b/test/functional/eigen/EigenSparseMatrixTest.cpp index 67b70f986..d050a6948 100644 --- a/test/functional/eigen/EigenSparseMatrixTest.cpp +++ b/test/functional/eigen/EigenSparseMatrixTest.cpp @@ -18,7 +18,7 @@ TEST(EigenSparseMatrixTest, BasicReadWriteTest) { int position_row[50] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, /* first row empty, one full row ��� 25 minus the diagonal entry */ + 2, 2, 2, 2, /* first row empty, one full row 25 minus the diagonal entry */ 4, 4, /* one empty row, then first and last column */ 13, 13, 13, 13, /* a few empty rows, middle columns */ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, diff --git a/test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp index 43fbd9c35..b440df38d 100644 --- a/test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp +++ b/test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp @@ -7,164 +7,164 @@ TEST(GmmxxMdpPrctModelCheckerTest, Dice) { storm::settings::Settings* s = storm::settings::instance(); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "functional/modelchecker/two_dice/two_dice.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.flip.trans.rew"); - + storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.flip.trans.rew"); + ASSERT_EQ(parser.getType(), storm::models::MDP); - + std::shared_ptr> mdp = parser.getModel>(); - + ASSERT_EQ(mdp->getNumberOfStates(), 169u); ASSERT_EQ(mdp->getNumberOfTransitions(), 436u); - + storm::modelchecker::GmmxxMdpPrctlModelChecker mc(*mdp); - + storm::property::prctl::Ap* apFormula = new storm::property::prctl::Ap("two"); storm::property::prctl::Eventually* eventuallyFormula = new storm::property::prctl::Eventually(apFormula); storm::property::prctl::ProbabilisticNoBoundOperator* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); - + std::vector* result = mc.checkNoBoundOperator(*probFormula); - + ASSERT_NE(nullptr, result); - + ASSERT_LT(std::abs((*result)[0] - 0.0277777612209320068), s->get("precision")); - + delete probFormula; delete result; - + apFormula = new storm::property::prctl::Ap("two"); eventuallyFormula = new storm::property::prctl::Eventually(apFormula); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); - + result = mc.checkNoBoundOperator(*probFormula); - + ASSERT_LT(std::abs((*result)[0] - 0.0277777612209320068), s->get("precision")); - + delete probFormula; delete result; - + apFormula = new storm::property::prctl::Ap("three"); eventuallyFormula = new storm::property::prctl::Eventually(apFormula); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); - + result = mc.checkNoBoundOperator(*probFormula); - + ASSERT_LT(std::abs((*result)[0] - 0.0555555224418640136), s->get("precision")); - + delete probFormula; delete result; - + apFormula = new storm::property::prctl::Ap("three"); eventuallyFormula = new storm::property::prctl::Eventually(apFormula); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); - + result = mc.checkNoBoundOperator(*probFormula); - + ASSERT_LT(std::abs((*result)[0] - 0.0555555224418640136), s->get("precision")); - + delete probFormula; delete result; - + apFormula = new storm::property::prctl::Ap("four"); eventuallyFormula = new storm::property::prctl::Eventually(apFormula); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); - + result = mc.checkNoBoundOperator(*probFormula); - + ASSERT_LT(std::abs((*result)[0] - 0.083333283662796020508), s->get("precision")); - + delete probFormula; delete result; - + apFormula = new storm::property::prctl::Ap("four"); eventuallyFormula = new storm::property::prctl::Eventually(apFormula); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); - + result = mc.checkNoBoundOperator(*probFormula); - + ASSERT_LT(std::abs((*result)[0] - 0.083333283662796020508), s->get("precision")); - + delete probFormula; delete result; - + apFormula = new storm::property::prctl::Ap("done"); storm::property::prctl::ReachabilityReward* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); storm::property::prctl::RewardNoBoundOperator* rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, true); - + result = mc.checkNoBoundOperator(*rewardFormula); - + ASSERT_LT(std::abs((*result)[0] - 7.3333294987678527832), s->get("precision")); - + delete rewardFormula; delete result; - + apFormula = new storm::property::prctl::Ap("done"); reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, false); - + result = mc.checkNoBoundOperator(*rewardFormula);; - + ASSERT_LT(std::abs((*result)[0] - 7.3333294987678527832), s->get("precision")); - + delete rewardFormula; delete result; - - storm::parser::AutoParser stateRewardParser(STORM_CPP_TESTS_BASE_PATH "/functional/two_dice/two_dice.tra", STORM_CPP_TESTS_BASE_PATH "/functional/two_dice/two_dice.lab", STORM_CPP_TESTS_BASE_PATH "/functional/two_dice/two_dice.flip.state.rew", ""); - + + storm::parser::AutoParser stateRewardParser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.lab", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.flip.state.rew", ""); + ASSERT_EQ(stateRewardParser.getType(), storm::models::MDP); - + std::shared_ptr> stateRewardMdp = stateRewardParser.getModel>(); - + storm::modelchecker::GmmxxMdpPrctlModelChecker stateRewardModelChecker(*stateRewardMdp); - + apFormula = new storm::property::prctl::Ap("done"); reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, true); - + result = stateRewardModelChecker.checkNoBoundOperator(*rewardFormula); - + ASSERT_LT(std::abs((*result)[0] - 7.3333294987678527832), s->get("precision")); - + delete rewardFormula; delete result; - + apFormula = new storm::property::prctl::Ap("done"); reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, false); - + result = stateRewardModelChecker.checkNoBoundOperator(*rewardFormula); - + ASSERT_LT(std::abs((*result)[0] - 7.3333294987678527832), s->get("precision")); - + delete rewardFormula; delete result; - - storm::parser::AutoParser stateAndTransitionRewardParser(STORM_CPP_TESTS_BASE_PATH "/functional/two_dice/two_dice.tra", STORM_CPP_TESTS_BASE_PATH "/functional/two_dice/two_dice.lab", STORM_CPP_TESTS_BASE_PATH "/functional/two_dice/two_dice.flip.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/two_dice/two_dice.flip.trans.rew"); - + + storm::parser::AutoParser stateAndTransitionRewardParser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.lab", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.flip.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.flip.trans.rew"); + ASSERT_EQ(stateAndTransitionRewardParser.getType(), storm::models::MDP); - + std::shared_ptr> stateAndTransitionRewardMdp = stateAndTransitionRewardParser.getModel>(); - + storm::modelchecker::GmmxxMdpPrctlModelChecker stateAndTransitionRewardModelChecker(*stateAndTransitionRewardMdp); - + apFormula = new storm::property::prctl::Ap("done"); reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, true); - + result = stateAndTransitionRewardModelChecker.checkNoBoundOperator(*rewardFormula); - + ASSERT_LT(std::abs((*result)[0] - (2 * 7.3333294987678527832)), s->get("precision")); - + delete rewardFormula; delete result; - + apFormula = new storm::property::prctl::Ap("done"); reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, false); - + result = stateAndTransitionRewardModelChecker.checkNoBoundOperator(*rewardFormula); - + ASSERT_LT(std::abs((*result)[0] - (2 * 7.3333294987678527832)), s->get("precision")); - + delete rewardFormula; delete result; } diff --git a/test/functional/parser/CslParserTest.cpp b/test/functional/parser/CslParserTest.cpp index 2ebd8ea16..ebf7250a9 100644 --- a/test/functional/parser/CslParserTest.cpp +++ b/test/functional/parser/CslParserTest.cpp @@ -127,14 +127,9 @@ TEST(CslParserTest, parseComplexFormulaTest) { } - - TEST(CslParserTest, wrongProbabilisticFormulaTest) { storm::parser::CslParser* cslParser = nullptr; - ASSERT_THROW( - cslParser = new storm::parser::CslParser("P > 0.5 [ a ]"), - storm::exceptions::WrongFormatException - ); + ASSERT_THROW(cslParser = new storm::parser::CslParser("P > 0.5 [ a ]"), storm::exceptions::WrongFormatException); delete cslParser; } diff --git a/test/functional/parser/ParseMdpTest.cpp b/test/functional/parser/ParseMdpTest.cpp index 55da2ae32..dfaa0ac15 100644 --- a/test/functional/parser/ParseMdpTest.cpp +++ b/test/functional/parser/ParseMdpTest.cpp @@ -13,8 +13,8 @@ TEST(ParseMdpTest, parseAndOutput) { storm::parser::NondeterministicModelParser* mdpParser = nullptr; ASSERT_NO_THROW(mdpParser = new storm::parser::NondeterministicModelParser( - STORM_CPP_TESTS_BASE_PATH "/parser/tra_files/mdp_general_input_01.tra", - STORM_CPP_TESTS_BASE_PATH "/parser/lab_files/pctl_general_input_01.lab")); + STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input_01.tra", + STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/pctl_general_input_01.lab")); std::shared_ptr> mdp = mdpParser->getMdp(); std::shared_ptr> matrix = mdp->getTransitionMatrix(); diff --git a/test/functional/parser/ReadLabFileTest.cpp b/test/functional/parser/ReadLabFileTest.cpp index b17f91738..2c3122209 100644 --- a/test/functional/parser/ReadLabFileTest.cpp +++ b/test/functional/parser/ReadLabFileTest.cpp @@ -25,7 +25,7 @@ TEST(ReadLabFileTest, ParseTest) { storm::parser::AtomicPropositionLabelingParser* parser = nullptr; //Parsing the file - ASSERT_NO_THROW(parser = new storm::parser::AtomicPropositionLabelingParser(12, STORM_CPP_TESTS_BASE_PATH "/parser/lab_files/pctl_general_input_01.lab")); + ASSERT_NO_THROW(parser = new storm::parser::AtomicPropositionLabelingParser(12, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/pctl_general_input_01.lab")); std::shared_ptr labeling(parser->getLabeling()); //Checking whether all propositions are in the labelling @@ -89,14 +89,14 @@ TEST(ReadLabFileTest, ParseTest) { } TEST(ReadLabFileTest, WrongHeaderTest1) { - ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(3, STORM_CPP_TESTS_BASE_PATH "/parser/lab_files/wrong_format_header1.lab"), storm::exceptions::WrongFormatException); + ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_header1.lab"), storm::exceptions::WrongFormatException); } TEST(ReadLabFileTest, WrongHeaderTest2) { - ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(3, STORM_CPP_TESTS_BASE_PATH "/parser/lab_files/wrong_format_header2.lab"), storm::exceptions::WrongFormatException); + ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_header2.lab"), storm::exceptions::WrongFormatException); } TEST(ReadLabFileTest, WrongPropositionTest) { - ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(3, STORM_CPP_TESTS_BASE_PATH "/parser/lab_files/wrong_format_proposition.lab"), storm::exceptions::WrongFormatException); + ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_proposition.lab"), storm::exceptions::WrongFormatException); } diff --git a/test/functional/parser/ReadTraFileTest.cpp b/test/functional/parser/ReadTraFileTest.cpp index 35ecfcbcc..fd86a8820 100644 --- a/test/functional/parser/ReadTraFileTest.cpp +++ b/test/functional/parser/ReadTraFileTest.cpp @@ -21,7 +21,7 @@ TEST(ReadTraFileTest, NonExistingFileTest) { */ TEST(ReadTraFileTest, ParseFileTest1) { storm::parser::DeterministicSparseTransitionParser* parser = nullptr; - ASSERT_NO_THROW(parser = new storm::parser::DeterministicSparseTransitionParser(STORM_CPP_TESTS_BASE_PATH "/parser/tra_files/csl_general_input_01.tra")); + ASSERT_NO_THROW(parser = new storm::parser::DeterministicSparseTransitionParser(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/csl_general_input_01.tra")); std::shared_ptr> result = parser->getMatrix(); if (result != nullptr) { @@ -73,13 +73,13 @@ TEST(ReadTraFileTest, ParseFileTest1) { } TEST(ReadTraFileTest, WrongFormatTestHeader1) { - ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser(STORM_CPP_TESTS_BASE_PATH "/parser/tra_files/wrong_format_header1.tra"), storm::exceptions::WrongFormatException); + ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/wrong_format_header1.tra"), storm::exceptions::WrongFormatException); } TEST(ReadTraFileTest, WrongFormatTestHeader2) { - ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser(STORM_CPP_TESTS_BASE_PATH "/parser/tra_files/wrong_format_header2.tra"), storm::exceptions::WrongFormatException); + ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/wrong_format_header2.tra"), storm::exceptions::WrongFormatException); } TEST(ReadTraFileTest, WrongFormatTestTransition) { - ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser(STORM_CPP_TESTS_BASE_PATH "/parser/tra_files/wrong_format_transition.tra"), storm::exceptions::WrongFormatException); + ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/wrong_format_transition.tra"), storm::exceptions::WrongFormatException); } diff --git a/test/functional/storm-functional-tests.cpp b/test/functional/storm-functional-tests.cpp index e5d78bb5e..7139bed3c 100644 --- a/test/functional/storm-functional-tests.cpp +++ b/test/functional/storm-functional-tests.cpp @@ -15,7 +15,7 @@ log4cplus::Logger logger; * Initializes the logging framework. */ void setUpLogging() { - log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender("storm-tests.log")); + log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender("storm-functional-tests.log")); fileLogAppender->setName("mainFileAppender"); fileLogAppender->setLayout(std::auto_ptr(new log4cplus::PatternLayout("%-5p - %D{%H:%M} (%r ms) - %F:%L : %m%n"))); logger = log4cplus::Logger::getInstance("mainLogger"); @@ -58,7 +58,7 @@ int main(int argc, char* argv[]) { if (!parseOptions(argc, argv)) { return 0; } - std::cout << "STORM Testing Suite" << std::endl; + std::cout << "StoRM (Functional) Testing Suite" << std::endl; testing::InitGoogleTest(&argc, argv); From 6ba1cf25c88577de6571219f1580da6661caf25c Mon Sep 17 00:00:00 2001 From: dehnert Date: Tue, 14 May 2013 13:28:19 +0200 Subject: [PATCH 122/152] Added new variable for base bath for project root. Changed test input files to the files from example folder. Added leader4.lab to asynchronous leader election example. --- CMakeLists.txt | 4 +- examples/mdp/two_dice/two_dice.nm | 2 +- src/modelchecker/SparseMdpPrctlModelChecker.h | 2 +- storm-config.h.in | 3 +- .../GmmxxDtmcPrctModelCheckerTest.cpp | 6 +- .../GmmxxMdpPrctModelCheckerTest.cpp | 8 +-- .../modelchecker/die/testFormulas.prctl | 4 -- test/performance/storm-performance-tests.cpp | 66 +++++++++++++++++++ 8 files changed, 79 insertions(+), 16 deletions(-) delete mode 100644 test/functional/modelchecker/die/testFormulas.prctl create mode 100644 test/performance/storm-performance-tests.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a99f224da..744e10d9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,8 +130,8 @@ file(GLOB_RECURSE STORM_IR_FILES ${PROJECT_SOURCE_DIR}/src/ir/*.h ${PROJECT_SOUR # Test Sources # Note that the tests also need the source files, except for the main file -file(GLOB_RECURSE STORM_FUNCTIONAL_TEST_FILES ${PROJECT_SOURCE_DIR}/test/functional/*.h ${PROJECT_SOURCE_DIR}/test/functional/*.cpp) -file(GLOB_RECURSE STORM_PERFORMANCE_TEST_FILES ${PROJECT_SOURCE_DIR}/test/performance/*.h ${PROJECT_SOURCE_DIR}/test/performance/*.cpp) +file(GLOB_RECURSE STORM_FUNCTIONAL_TEST_FILES ${STORM_CPP_TESTS_BASE_PATH}/functional/*.h ${STORM_CPP_TESTS_BASE_PATH}/functional/*.cpp) +file(GLOB_RECURSE STORM_PERFORMANCE_TEST_FILES ${STORM_CPP_TESTS_BASE_PATH}/performance/*.h ${STORM_CPP_TESTS_BASE_PATH}/performance/*.cpp) # Group the headers and sources source_group(main FILES ${STORM_MAIN_FILE}) diff --git a/examples/mdp/two_dice/two_dice.nm b/examples/mdp/two_dice/two_dice.nm index e1bf34aea..778153138 100644 --- a/examples/mdp/two_dice/two_dice.nm +++ b/examples/mdp/two_dice/two_dice.nm @@ -17,7 +17,7 @@ module die1 [] s1=4 -> 0.5 : (s1'=7) & (d1'=2) + 0.5 : (s1'=7) & (d1'=3); [] s1=5 -> 0.5 : (s1'=7) & (d1'=4) + 0.5 : (s1'=7) & (d1'=5); [] s1=6 -> 0.5 : (s1'=2) + 0.5 : (s1'=7) & (d1'=6); - [] s1=7 & s2=7 -> (s1'=7); + [] s1=7 & s2=7 -> 1: (s1'=7); endmodule module die2 = die1 [ s1=s2, s2=s1, d1=d2 ] endmodule diff --git a/src/modelchecker/SparseMdpPrctlModelChecker.h b/src/modelchecker/SparseMdpPrctlModelChecker.h index b9c80e24b..0c951ae8f 100644 --- a/src/modelchecker/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/SparseMdpPrctlModelChecker.h @@ -99,7 +99,7 @@ public: // Make all rows absorbing that violate both sub-formulas or satisfy the second sub-formula. tmpMatrix.makeRowsAbsorbing(~(*leftStates | *rightStates) | *rightStates, *this->getModel().getNondeterministicChoiceIndices()); - + // Create the vector with which to multiply. std::vector* result = new std::vector(this->getModel().getNumberOfStates()); storm::utility::setVectorValues(result, *rightStates, storm::utility::constGetOne()); diff --git a/storm-config.h.in b/storm-config.h.in index bb44dec25..0b1cd5134 100644 --- a/storm-config.h.in +++ b/storm-config.h.in @@ -1,4 +1,5 @@ // the configured options and settings for STORM #define STORM_CPP_VERSION_MAJOR @STORM_CPP_VERSION_MAJOR@ #define STORM_CPP_VERSION_MINOR @STORM_CPP_VERSION_MINOR@ -#define STORM_CPP_TESTS_BASE_PATH "@STORM_CPP_TESTS_BASE_PATH@" \ No newline at end of file +#define STORM_CPP_BASE_PATH "@PROJECT_SOURCE_DIR@" +#define STORM_CPP_TESTS_BASE_PATH "@STORM_CPP_TESTS_BASE_PATH@" diff --git a/test/functional/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp index 2286cd8d9..e3eb08b68 100644 --- a/test/functional/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp +++ b/test/functional/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp @@ -8,7 +8,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Die) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/die/die.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/die/die.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/die/die.coin_flips.trans.rew"); + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/die/die.tra", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.coin_flips.trans.rew"); ASSERT_EQ(parser.getType(), storm::models::DTMC); @@ -75,7 +75,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Die) { TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/crowds/crowds5_5.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/crowds/crowds5_5.lab", "", ""); + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.lab", "", ""); ASSERT_EQ(parser.getType(), storm::models::DTMC); @@ -129,7 +129,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/synchronous_leader/leader4_8.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/synchronous_leader/leader4_8.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/synchronous_leader/leader4_8.pick.trans.rew"); + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.pick.trans.rew"); ASSERT_EQ(parser.getType(), storm::models::DTMC); diff --git a/test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp index b440df38d..32cf5b9a4 100644 --- a/test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp +++ b/test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp @@ -7,7 +7,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Dice) { storm::settings::Settings* s = storm::settings::instance(); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.flip.trans.rew"); + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew"); ASSERT_EQ(parser.getType(), storm::models::MDP); @@ -108,7 +108,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Dice) { delete rewardFormula; delete result; - storm::parser::AutoParser stateRewardParser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.lab", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.flip.state.rew", ""); + storm::parser::AutoParser stateRewardParser(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", ""); ASSERT_EQ(stateRewardParser.getType(), storm::models::MDP); @@ -138,7 +138,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Dice) { delete rewardFormula; delete result; - storm::parser::AutoParser stateAndTransitionRewardParser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.lab", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.flip.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/two_dice/two_dice.flip.trans.rew"); + storm::parser::AutoParser stateAndTransitionRewardParser(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew"); ASSERT_EQ(stateAndTransitionRewardParser.getType(), storm::models::MDP); @@ -171,7 +171,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Dice) { TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { storm::settings::Settings* s = storm::settings::instance(); - storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/asynchronous_leader/leader4.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/asynchronous_leader/leader4.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/asynchronous_leader/leader4.trans.rew"); + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.trans.rew"); ASSERT_EQ(parser.getType(), storm::models::MDP); diff --git a/test/functional/modelchecker/die/testFormulas.prctl b/test/functional/modelchecker/die/testFormulas.prctl deleted file mode 100644 index 8deea6c43..000000000 --- a/test/functional/modelchecker/die/testFormulas.prctl +++ /dev/null @@ -1,4 +0,0 @@ -P=? [ F one ] -P=? [ F two ] -P=? [ F three ] -R=? [ F done ] diff --git a/test/performance/storm-performance-tests.cpp b/test/performance/storm-performance-tests.cpp new file mode 100644 index 000000000..1e1317a80 --- /dev/null +++ b/test/performance/storm-performance-tests.cpp @@ -0,0 +1,66 @@ +#include + +#include "gtest/gtest.h" +#include "log4cplus/logger.h" +#include "log4cplus/loggingmacros.h" +#include "log4cplus/consoleappender.h" +#include "log4cplus/fileappender.h" + +#include "src/utility/Settings.h" +#include "src/modelchecker/GmmxxDtmcPrctlModelChecker.h" + +log4cplus::Logger logger; + +/*! + * Initializes the logging framework. + */ +void setUpLogging() { + log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender("storm-functional-tests.log")); + fileLogAppender->setName("mainFileAppender"); + fileLogAppender->setLayout(std::auto_ptr(new log4cplus::PatternLayout("%-5p - %D{%H:%M} (%r ms) - %F:%L : %m%n"))); + logger = log4cplus::Logger::getInstance("mainLogger"); + logger.addAppender(fileLogAppender); + + // Uncomment these lines to enable console logging output + // log4cplus::SharedAppenderPtr consoleLogAppender(new log4cplus::ConsoleAppender()); + // consoleLogAppender->setName("mainConsoleAppender"); + // consoleLogAppender->setLayout(std::auto_ptr(new log4cplus::PatternLayout("%-5p - %D{%H:%M:%s} (%r ms) - %F:%L : %m%n"))); + // logger.addAppender(consoleLogAppender); +} + +/*! + * Function that parses the command line options. + * @param argc The argc argument of main(). + * @param argv The argv argument of main(). + * @return True iff the program should continue to run after parsing the options. + */ +bool parseOptions(int const argc, char const * const argv[]) { + storm::settings::Settings* s = nullptr; + try { + storm::settings::Settings::registerModule>(); + s = storm::settings::newInstance(argc, argv, nullptr, true); + } catch (storm::exceptions::InvalidSettingsException& e) { + std::cout << "Could not recover from settings error: " << e.what() << "." << std::endl; + std::cout << std::endl << storm::settings::help; + return false; + } + + if (s->isSet("help")) { + std::cout << storm::settings::help; + return false; + } + + return true; +} + +int main(int argc, char* argv[]) { + setUpLogging(); + if (!parseOptions(argc, argv)) { + return 0; + } + std::cout << "StoRM (Performance) Testing Suite" << std::endl; + + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} From 5149a7a9436387cd4fe9d9f0a5a9cc1d3d598de3 Mon Sep 17 00:00:00 2001 From: dehnert Date: Tue, 14 May 2013 15:01:01 +0200 Subject: [PATCH 123/152] Added lab files for asynch_leader and corrected pctl file a bit. Included first (incorrect) tests for performance test suite. --- examples/mdp/asynchronous_leader/leader.pctl | 6 +- .../GmmxxDtmcPrctModelCheckerTest.cpp | 116 ++++++++++ .../GmmxxMdpPrctModelCheckerTest.cpp | 217 ++++++++++++++++++ 3 files changed, 336 insertions(+), 3 deletions(-) create mode 100644 test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp create mode 100644 test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp diff --git a/examples/mdp/asynchronous_leader/leader.pctl b/examples/mdp/asynchronous_leader/leader.pctl index bb8fb1b82..2c87c7f27 100644 --- a/examples/mdp/asynchronous_leader/leader.pctl +++ b/examples/mdp/asynchronous_leader/leader.pctl @@ -1,8 +1,8 @@ Pmin=? [ F elected ] -const int K = 25; -Pmin=? [ F<=K elected ] -Pmax=? [ F<=K elected ] +// const int K = 25; +Pmin=? [ F<=25 elected ] +Pmax=? [ F<=25 elected ] Rmin=? [ F elected ] Rmax=? [ F elected ] diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp new file mode 100644 index 000000000..87bcf8ef6 --- /dev/null +++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp @@ -0,0 +1,116 @@ +#include "gtest/gtest.h" +#include "storm-config.h" + +#include "src/utility/Settings.h" +#include "src/modelchecker/GmmxxDtmcPrctlModelChecker.h" +#include "src/parser/AutoParser.h" + +TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { + storm::settings::Settings* s = storm::settings::instance(); + s->set("fix-deadlocks"); + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", ""); + + ASSERT_EQ(parser.getType(), storm::models::DTMC); + + std::shared_ptr> dtmc = parser.getModel>(); + + ASSERT_EQ(dtmc->getNumberOfStates(), 8607u); + ASSERT_EQ(dtmc->getNumberOfTransitions(), 22460u); + + storm::modelchecker::GmmxxDtmcPrctlModelChecker mc(*dtmc); + + storm::property::prctl::Ap* apFormula = new storm::property::prctl::Ap("observe0Greater1"); + storm::property::prctl::Eventually* eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + storm::property::prctl::ProbabilisticNoBoundOperator* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula); + + std::vector* result = probFormula->check(mc); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 0.3328800375801578281), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("observeIGreater1"); + eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula); + + result = probFormula->check(mc); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 0.1522173670950556501), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("observeOnlyTrueSender"); + eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula); + + result = probFormula->check(mc); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 0.32153724292835045), s->get("precision")); + + delete probFormula; + delete result; +} + +/* +TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { + storm::settings::Settings* s = storm::settings::instance(); + s->set("fix-deadlocks"); + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.pick.trans.rew"); + + ASSERT_EQ(parser.getType(), storm::models::DTMC); + + std::shared_ptr> dtmc = parser.getModel>(); + + ASSERT_EQ(dtmc->getNumberOfStates(), 12400u); + ASSERT_EQ(dtmc->getNumberOfTransitions(), 28894u); + + storm::modelchecker::GmmxxDtmcPrctlModelChecker mc(*dtmc); + + storm::property::prctl::Ap* apFormula = new storm::property::prctl::Ap("elected"); + storm::property::prctl::Eventually* eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + storm::property::prctl::ProbabilisticNoBoundOperator* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula); + + std::vector* result = probFormula->check(mc); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + storm::property::prctl::BoundedUntil* boundedUntilFormula = new storm::property::prctl::BoundedUntil(new storm::property::prctl::Ap("true"), apFormula, 20); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedUntilFormula); + + result = probFormula->check(mc); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 0.9999965911265462636), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + storm::property::prctl::ReachabilityReward* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + storm::property::prctl::RewardNoBoundOperator* rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula); + + result = rewardFormula->check(mc); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 1.0448979591835938496), s->get("precision")); + + delete rewardFormula; + delete result; +} +*/ \ No newline at end of file diff --git a/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp new file mode 100644 index 000000000..322dafe8e --- /dev/null +++ b/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp @@ -0,0 +1,217 @@ +#include "gtest/gtest.h" +#include "storm-config.h" + +#include "src/utility/Settings.h" +#include "src/modelchecker/GmmxxMdpPrctlModelChecker.h" +#include "src/parser/AutoParser.h" + +TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { + storm::settings::Settings* s = storm::settings::instance(); + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.trans.rew"); + + ASSERT_EQ(parser.getType(), storm::models::MDP); + + std::shared_ptr> mdp = parser.getModel>(); + + ASSERT_EQ(mdp->getNumberOfStates(), 3172u); + ASSERT_EQ(mdp->getNumberOfTransitions(), 7144u); + + storm::modelchecker::GmmxxMdpPrctlModelChecker mc(*mdp); + + storm::property::prctl::Ap* apFormula = new storm::property::prctl::Ap("elected"); + storm::property::prctl::Eventually* eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + storm::property::prctl::ProbabilisticNoBoundOperator* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + std::vector* result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + storm::property::prctl::BoundedEventually* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 25); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, true); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 0.0625), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 25); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, false); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 0.0625), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + storm::property::prctl::ReachabilityReward* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + storm::property::prctl::RewardNoBoundOperator* rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, true); + + result = mc.checkNoBoundOperator(*rewardFormula); + + ASSERT_LT(std::abs((*result)[0] - 4.28568908480604982), s->get("precision")); + + delete rewardFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, false); + + result = mc.checkNoBoundOperator(*rewardFormula);; + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 4.2856904354441400784), s->get("precision")); + + delete rewardFormula; + delete result; +} + +TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { + storm::settings::Settings* s = storm::settings::instance(); + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_6.steps.state.rew", ""); + + ASSERT_EQ(parser.getType(), storm::models::MDP); + + std::shared_ptr> mdp = parser.getModel>(); + + storm::modelchecker::GmmxxMdpPrctlModelChecker mc(*mdp); + + storm::property::prctl::Ap* apFormula = new storm::property::prctl::Ap("finished"); + storm::property::prctl::Eventually* eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + storm::property::prctl::ProbabilisticNoBoundOperator* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + std::vector* result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + storm::property::prctl::Ap* apFormula2 = new storm::property::prctl::Ap("all_coins_equal_0"); + storm::property::prctl::And* andFormula = new storm::property::prctl::And(apFormula, apFormula2); + eventuallyFormula = new storm::property::prctl::Eventually(andFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + apFormula2 = new storm::property::prctl::Ap("all_coins_equal_1"); + andFormula = new storm::property::prctl::And(apFormula, apFormula2); + eventuallyFormula = new storm::property::prctl::Eventually(andFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + apFormula2 = new storm::property::prctl::Ap("agree"); + storm::property::prctl::Not* notFormula = new storm::property::prctl::Not(apFormula2); + andFormula = new storm::property::prctl::And(apFormula, notFormula); + eventuallyFormula = new storm::property::prctl::Eventually(andFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + storm::property::prctl::BoundedEventually* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 50); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, true); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 0.0625), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 50); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, false); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 0.0625), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + storm::property::prctl::ReachabilityReward* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + storm::property::prctl::RewardNoBoundOperator* rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, true); + + result = mc.checkNoBoundOperator(*rewardFormula); + + ASSERT_LT(std::abs((*result)[0] - 4.28568908480604982), s->get("precision")); + + delete rewardFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, false); + + result = mc.checkNoBoundOperator(*rewardFormula);; + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 4.2856904354441400784), s->get("precision")); + + delete rewardFormula; + delete result; + +} \ No newline at end of file From c8e8e1502b5886b8fbe0b3e2d819b9308d4a71fc Mon Sep 17 00:00:00 2001 From: Lanchid Date: Tue, 14 May 2013 16:39:55 +0200 Subject: [PATCH 124/152] Added minimum/maximum support for probablistic no bound operators. --- src/parser/PrctlParser.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index c79485dc0..f1a8ad4ef 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -83,7 +83,15 @@ struct PrctlParser::PrctlGrammar : qi::grammar> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = + probabilisticNoBoundOperator = (probabilisticMinimumNoBoundOperator | probabilisticMaximumNoBoundOperator | probabilisticDeterministicNoBoundOperator); + + probabilisticMinimumNoBoundOperator = (qi::lit("P") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, true)]; + + probabilisticMaximumNoBoundOperator = (qi::lit("P") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, false)]; + + probabilisticDeterministicNoBoundOperator = (qi::lit("P") >> qi::lit("=") >> qi::lit("?") > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = phoenix::new_ >(qi::_1)]; probabilisticNoBoundOperator.name("no bound operator"); rewardNoBoundOperator = (qi::lit("R") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = @@ -141,6 +149,9 @@ struct PrctlParser::PrctlGrammar : qi::grammar*(), Skipper> noBoundOperator; qi::rule*(), Skipper> probabilisticNoBoundOperator; + qi::rule*(), Skipper> probabilisticMinimumNoBoundOperator; + qi::rule*(), Skipper> probabilisticMaximumNoBoundOperator; + qi::rule*(), Skipper> probabilisticDeterministicNoBoundOperator; qi::rule*(), Skipper> rewardNoBoundOperator; qi::rule*(), Skipper> pathFormula; From 6a1f6fbcee7a2a688161286995bc5f4a902fa4c6 Mon Sep 17 00:00:00 2001 From: Lanchid Date: Wed, 15 May 2013 14:26:43 +0200 Subject: [PATCH 125/152] Parser changed to support P and R operators annotated with min/max. --- src/formula/abstract/PathBoundOperator.h | 2 +- src/parser/PrctlFileParser.cpp | 7 ++ src/parser/PrctlParser.cpp | 84 +++++++++++++----------- 3 files changed, 55 insertions(+), 38 deletions(-) diff --git a/src/formula/abstract/PathBoundOperator.h b/src/formula/abstract/PathBoundOperator.h index 34a6f0732..03454b3c5 100644 --- a/src/formula/abstract/PathBoundOperator.h +++ b/src/formula/abstract/PathBoundOperator.h @@ -70,7 +70,7 @@ public: * @param minimumOperator Indicator, if operator should be minimum or maximum operator. */ PathBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, FormulaType* pathFormula, bool minimumOperator) - : comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula), OptimizingOperator(minimumOperator) { + : OptimizingOperator(minimumOperator), comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { // Intentionally left empty } diff --git a/src/parser/PrctlFileParser.cpp b/src/parser/PrctlFileParser.cpp index ed5f15a2b..0f7f877f1 100644 --- a/src/parser/PrctlFileParser.cpp +++ b/src/parser/PrctlFileParser.cpp @@ -13,6 +13,8 @@ #include "modelchecker/GmmxxDtmcPrctlModelChecker.h" #include "modelchecker/GmmxxMdpPrctlModelChecker.h" +#include + namespace storm { namespace parser { @@ -39,6 +41,11 @@ std::list*> PrctlFileParser std::string line; //The while loop reads the input file line by line while (std::getline(inputFileStream, line)) { + boost::algorithm::trim(line); + if ((line.length() == 0) || ((line[0] == '/') && (line[1] == '/'))) { + // ignore empty lines and lines starting with // + continue; + } PrctlParser parser(line); result.push_back(parser.getFormula()); } diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index f1a8ad4ef..07cf79b7a 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -35,7 +35,15 @@ namespace parser { template struct PrctlParser::PrctlGrammar : qi::grammar*(), Skipper > { PrctlGrammar() : PrctlGrammar::base_type(start) { + + //This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[+(qi::alpha | qi::char_('_'))]; + comparisonType = ( + (qi::lit(">="))[qi::_val = storm::property::GREATER_EQUAL] | + (qi::lit(">"))[qi::_val = storm::property::GREATER] | + (qi::lit("<="))[qi::_val = storm::property::LESS_EQUAL] | + (qi::lit("<"))[qi::_val = storm::property::LESS]); + comment = qi::lit("//") //This block defines rules for parsing state formulas stateFormula %= orFormula; @@ -58,44 +66,47 @@ struct PrctlParser::PrctlGrammar : qi::grammar>(qi::_1)]; atomicProposition.name("state formula"); probabilisticBoundOperator = ( - (qi::lit("P") >> qi::lit(">") >> qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::GREATER, qi::_1, qi::_2)] | - (qi::lit("P") >> qi::lit(">=") > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::GREATER_EQUAL, qi::_1, qi::_2)] | - (qi::lit("P") >> qi::lit("<") >> qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::LESS, qi::_1, qi::_2)] | - (qi::lit("P") >> qi::lit("<=") > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::LESS_EQUAL, qi::_1, qi::_2)] + (qi::lit("P") >> qi::lit("min") > comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, qi::_2, qi::_3, true)] | + (qi::lit("P") >> qi::lit("max") > comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, qi::_2, qi::_3, false)] | + (qi::lit("P") > comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, qi::_2, qi::_3)] ); + probabilisticBoundOperator.name("state formula"); rewardBoundOperator = ( - (qi::lit("R") >> qi::lit(">") >> qi::double_ >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::GREATER, qi::_1, qi::_2)] | - (qi::lit("R") >> qi::lit(">=") >> qi::double_ >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::GREATER_EQUAL, qi::_1, qi::_2)] | - (qi::lit("R") >> qi::lit("<") >> qi::double_ >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::LESS, qi::_1, qi::_2)] | - (qi::lit("R") >> qi::lit("<=")>> qi::double_ >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::LESS_EQUAL, qi::_1, qi::_2)] + (qi::lit("R") >> qi::lit("min") > comparisonType > qi::double_ > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, qi::_2, qi::_3, true)] | + (qi::lit("R") >> qi::lit("max") > comparisonType > qi::double_ > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, qi::_2, qi::_3, false)] | + (qi::lit("R") >> comparisonType > qi::double_ > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, qi::_2, qi::_3)] ); rewardBoundOperator.name("state formula"); //This block defines rules for parsing formulas with noBoundOperators noBoundOperator = (probabilisticNoBoundOperator | rewardNoBoundOperator); noBoundOperator.name("no bound operator"); - probabilisticNoBoundOperator = (probabilisticMinimumNoBoundOperator | probabilisticMaximumNoBoundOperator | probabilisticDeterministicNoBoundOperator); - - probabilisticMinimumNoBoundOperator = (qi::lit("P") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(qi::_1, true)]; + probabilisticNoBoundOperator = ( + (qi::lit("P") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, true)] | + (qi::lit("P") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, false)] | + (qi::lit("P") >> qi::lit("=") >> qi::lit("?") > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1)] + ); + probabilisticNoBoundOperator.name("no bound operator"); - probabilisticMaximumNoBoundOperator = (qi::lit("P") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(qi::_1, false)]; + rewardNoBoundOperator = ( + (qi::lit("R") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, true)] | + (qi::lit("R") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, false)] | + (qi::lit("R") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1)] - probabilisticDeterministicNoBoundOperator = (qi::lit("P") >> qi::lit("=") >> qi::lit("?") > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(qi::_1)]; - probabilisticNoBoundOperator.name("no bound operator"); - rewardNoBoundOperator = (qi::lit("R") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_ >(qi::_1)]; + ); rewardNoBoundOperator.name("no bound operator"); //This block defines rules for parsing probabilistic path formulas @@ -103,19 +114,19 @@ struct PrctlParser::PrctlGrammar : qi::grammar> qi::lit("<=") > qi::int_ > stateFormula)[qi::_val = phoenix::new_>(qi::_2, qi::_1)]; - boundedEventually.name("path formula (for probablistic operator)"); + boundedEventually.name("path formula (for probabilistic operator)"); eventually = (qi::lit("F") > stateFormula)[qi::_val = phoenix::new_ >(qi::_1)]; - eventually.name("path formula (for probablistic operator)"); + eventually.name("path formula (for probabilistic operator)"); globally = (qi::lit("G") > stateFormula)[qi::_val = phoenix::new_ >(qi::_1)]; - globally.name("path formula (for probablistic operator)"); + globally.name("path formula (for probabilistic operator)"); boundedUntil = (stateFormula[qi::_a = phoenix::construct>>(qi::_1)] >> qi::lit("U") >> qi::lit("<=") > qi::int_ > stateFormula) [qi::_val = phoenix::new_>(phoenix::bind(&storm::property::prctl::AbstractStateFormula::clone, phoenix::bind(&std::shared_ptr>::get, qi::_a)), qi::_3, qi::_2)]; - boundedUntil.name("path formula (for probablistic operator)"); + boundedUntil.name("path formula (for probabilistic operator)"); until = (stateFormula[qi::_a = phoenix::construct>>(qi::_1)] >> qi::lit("U") > stateFormula)[qi::_val = phoenix::new_>(phoenix::bind(&storm::property::prctl::AbstractStateFormula::clone, phoenix::bind(&std::shared_ptr>::get, qi::_a)), qi::_2)]; - until.name("path formula (for probablistic operator)"); + until.name("path formula (for probabilistic operator)"); //This block defines rules for parsing reward path formulas rewardPathFormula = (cumulativeReward | reachabilityReward | instantaneousReward | steadyStateReward); @@ -131,11 +142,12 @@ struct PrctlParser::PrctlGrammar : qi::grammar>()]; - start = (noBoundOperator | stateFormula); + start = (comment | noBoundOperator | stateFormula | qi::eps[qi::error()]); start.name("PRCTL formula"); } qi::rule*(), Skipper> start; + qi::rule*(), Skipper> comment; qi::rule*(), Skipper> stateFormula; qi::rule*(), Skipper> atomicStateFormula; @@ -149,9 +161,6 @@ struct PrctlParser::PrctlGrammar : qi::grammar*(), Skipper> noBoundOperator; qi::rule*(), Skipper> probabilisticNoBoundOperator; - qi::rule*(), Skipper> probabilisticMinimumNoBoundOperator; - qi::rule*(), Skipper> probabilisticMaximumNoBoundOperator; - qi::rule*(), Skipper> probabilisticDeterministicNoBoundOperator; qi::rule*(), Skipper> rewardNoBoundOperator; qi::rule*(), Skipper> pathFormula; @@ -169,6 +178,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar freeIdentifierName; + qi::rule comparisonType; }; @@ -221,7 +231,7 @@ storm::parser::PrctlParser::PrctlParser(std::string formulaString) { // The syntax can be so wrong that no rule can be matched at all // In that case, no expectation failure is thrown, but the parser just returns nullptr // Then, of course the result is not usable, hence we throw a WrongFormatException, too. - if (result_pointer == nullptr) { + if (positionIteratorBegin != formulaString.end()) { throw storm::exceptions::WrongFormatException() << "Syntax error in formula"; } From a956fc782acf82a9506331fcbb506a81f1aee7b9 Mon Sep 17 00:00:00 2001 From: Lanchid Date: Wed, 15 May 2013 16:25:38 +0200 Subject: [PATCH 126/152] Added support for atomic propositions containing numbers. --- src/parser/PrctlParser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index 07cf79b7a..18f470660 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -37,13 +37,13 @@ struct PrctlParser::PrctlGrammar : qi::grammar> *(qi::alnum | qi::char_('_'))]; comparisonType = ( (qi::lit(">="))[qi::_val = storm::property::GREATER_EQUAL] | (qi::lit(">"))[qi::_val = storm::property::GREATER] | (qi::lit("<="))[qi::_val = storm::property::LESS_EQUAL] | (qi::lit("<"))[qi::_val = storm::property::LESS]); - comment = qi::lit("//") + comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; //This block defines rules for parsing state formulas stateFormula %= orFormula; @@ -142,7 +142,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar>()]; - start = (comment | noBoundOperator | stateFormula | qi::eps[qi::error()]); + start = (comment | noBoundOperator | stateFormula) >> qi::eoi; start.name("PRCTL formula"); } @@ -231,7 +231,7 @@ storm::parser::PrctlParser::PrctlParser(std::string formulaString) { // The syntax can be so wrong that no rule can be matched at all // In that case, no expectation failure is thrown, but the parser just returns nullptr // Then, of course the result is not usable, hence we throw a WrongFormatException, too. - if (positionIteratorBegin != formulaString.end()) { + if (positionIteratorBegin != positionIteratorEnd) { throw storm::exceptions::WrongFormatException() << "Syntax error in formula"; } From b5baae58619b4839ac2124870ff2892f9b8f113e Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 15 May 2013 10:41:25 +0200 Subject: [PATCH 127/152] Added 3 missing example files for synchronous leader election protocol. Set release optimization level for clang to O3. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 744e10d9b..a78fb8925 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,7 +95,7 @@ else(CLANG) # As CLANG is not set as a variable, we need to set it in case we have not matched another compiler. set (CLANG ON) # Set standard flags for clang - set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -funroll-loops -O4") + set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -funroll-loops -O3") set (CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Wall -Werror -pedantic -Wno-unused-variable -DBOOST_RESULT_OF_USE_TR1 -DBOOST_NO_DECLTYPE") set (CMAKE_CXX_FLAGS_DEBUG "-g") From 9ed1fa19e20c74aaee1915b2db049849096c8e52 Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 15 May 2013 18:25:20 +0200 Subject: [PATCH 128/152] Added some example files. --- examples/dtmc/synchronous_leader/leader.pctl | 3 ++- examples/mdp/consensus/coin.pctl | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/dtmc/synchronous_leader/leader.pctl b/examples/dtmc/synchronous_leader/leader.pctl index b14536d80..c4eb53408 100644 --- a/examples/dtmc/synchronous_leader/leader.pctl +++ b/examples/dtmc/synchronous_leader/leader.pctl @@ -1,3 +1,4 @@ P=? [ F elected ] -P=? [ F<=(4*(N+1)) elected ] +// P=? [ F<=(4*(N+1)) elected ] +P=? [ F<=28 elected ] R=? [ F elected ] diff --git a/examples/mdp/consensus/coin.pctl b/examples/mdp/consensus/coin.pctl index aa371d50b..edd87a453 100644 --- a/examples/mdp/consensus/coin.pctl +++ b/examples/mdp/consensus/coin.pctl @@ -11,8 +11,8 @@ Pmin=? [ F finished & all_coins_equal_1 ] Pmax=? [ F finished & !agree ] // Min/max probability of finishing within k steps -Pmin=? [ F<=k finished ] -Pmax=? [ F<=k finished ] +Pmin=? [ F<=50 finished ] +Pmax=? [ F<=50 finished ] // Min/max expected steps to finish Rmin=? [ F finished ] From 8c329933ec7663d765526a9e7d22e960ec4355fd Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 15 May 2013 18:26:07 +0200 Subject: [PATCH 129/152] Began correcting performance tests. --- .../GmmxxDtmcPrctModelCheckerTest.cpp | 21 ++++++------ .../GmmxxMdpPrctModelCheckerTest.cpp | 33 ++++++++++--------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp index 87bcf8ef6..4ce527d7e 100644 --- a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp @@ -14,8 +14,8 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { std::shared_ptr> dtmc = parser.getModel>(); - ASSERT_EQ(dtmc->getNumberOfStates(), 8607u); - ASSERT_EQ(dtmc->getNumberOfTransitions(), 22460u); + ASSERT_EQ(dtmc->getNumberOfStates(), 2036647u); + ASSERT_EQ(dtmc->getNumberOfTransitions(), 8973900u); storm::modelchecker::GmmxxDtmcPrctlModelChecker mc(*dtmc); @@ -27,7 +27,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0.3328800375801578281), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 0.2296803699), s->get("precision")); delete probFormula; delete result; @@ -40,7 +40,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0.1522173670950556501), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 0.05072232915), s->get("precision")); delete probFormula; delete result; @@ -53,13 +53,13 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0.32153724292835045), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 0.2274230551), s->get("precision")); delete probFormula; delete result; } -/* + TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); @@ -69,8 +69,8 @@ TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { std::shared_ptr> dtmc = parser.getModel>(); - ASSERT_EQ(dtmc->getNumberOfStates(), 12400u); - ASSERT_EQ(dtmc->getNumberOfTransitions(), 28894u); + ASSERT_EQ(dtmc->getNumberOfStates(), 1312334u); + ASSERT_EQ(dtmc->getNumberOfTransitions(), 2886810u); storm::modelchecker::GmmxxDtmcPrctlModelChecker mc(*dtmc); @@ -95,7 +95,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0.9999965911265462636), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 0.9999996339), s->get("precision")); delete probFormula; delete result; @@ -108,9 +108,8 @@ TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 1.0448979591835938496), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 1.025217446), s->get("precision")); delete rewardFormula; delete result; } -*/ \ No newline at end of file diff --git a/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp index 322dafe8e..82c43a4fc 100644 --- a/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp @@ -13,8 +13,8 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { std::shared_ptr> mdp = parser.getModel>(); - ASSERT_EQ(mdp->getNumberOfStates(), 3172u); - ASSERT_EQ(mdp->getNumberOfTransitions(), 7144u); + ASSERT_EQ(mdp->getNumberOfStates(), 2095783u); + ASSERT_EQ(mdp->getNumberOfTransitions(), 7714385u); storm::modelchecker::GmmxxMdpPrctlModelChecker mc(*mdp); @@ -52,7 +52,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0.0625), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 0), s->get("precision")); delete probFormula; delete result; @@ -65,7 +65,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0.0625), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 0), s->get("precision")); delete probFormula; delete result; @@ -76,7 +76,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { result = mc.checkNoBoundOperator(*rewardFormula); - ASSERT_LT(std::abs((*result)[0] - 4.28568908480604982), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 6.172433512), s->get("precision")); delete rewardFormula; delete result; @@ -89,7 +89,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 4.2856904354441400784), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 6.1724344), s->get("precision")); delete rewardFormula; delete result; @@ -97,12 +97,15 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { storm::settings::Settings* s = storm::settings::instance(); - storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_6.steps.state.rew", ""); + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", ""); ASSERT_EQ(parser.getType(), storm::models::MDP); std::shared_ptr> mdp = parser.getModel>(); + ASSERT_EQ(mdp->getNumberOfStates(), 63616u); + ASSERT_EQ(mdp->getNumberOfTransitions(), 213472u); + storm::modelchecker::GmmxxMdpPrctlModelChecker mc(*mdp); storm::property::prctl::Ap* apFormula = new storm::property::prctl::Ap("finished"); @@ -128,7 +131,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 0.4370098592), s->get("precision")); delete probFormula; delete result; @@ -137,13 +140,13 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { apFormula2 = new storm::property::prctl::Ap("all_coins_equal_1"); andFormula = new storm::property::prctl::And(apFormula, apFormula2); eventuallyFormula = new storm::property::prctl::Eventually(andFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); result = mc.checkNoBoundOperator(*probFormula); ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 0.4370098592), s->get("precision")); delete probFormula; delete result; @@ -159,7 +162,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 0.1034345104), s->get("precision")); delete probFormula; delete result; @@ -172,7 +175,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0.0625), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 0), s->get("precision")); delete probFormula; delete result; @@ -185,7 +188,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0.0625), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 0), s->get("precision")); delete probFormula; delete result; @@ -196,7 +199,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { result = mc.checkNoBoundOperator(*rewardFormula); - ASSERT_LT(std::abs((*result)[0] - 4.28568908480604982), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 1725.593313), s->get("precision")); delete rewardFormula; delete result; @@ -209,7 +212,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 4.2856904354441400784), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 2179.014847), s->get("precision")); delete rewardFormula; delete result; From 2fcd6c95fb1ccea8d5fcc1dca08a96c141a1d8f1 Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 15 May 2013 20:00:25 +0200 Subject: [PATCH 130/152] Performance tests now run fine (and take about 3 minutes). --- .../GmmxxDtmcPrctModelCheckerTest.cpp | 4 ++-- .../GmmxxMdpPrctModelCheckerTest.cpp | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp index 4ce527d7e..2609ba0a1 100644 --- a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp @@ -95,7 +95,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0.9999996339), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 0.999394979327824395376467), s->get("precision")); delete probFormula; delete result; @@ -108,7 +108,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 1.025217446), s->get("precision")); + ASSERT_LT(std::abs((*result)[0] - 1.02521744572240791626427), s->get("precision")); delete rewardFormula; delete result; diff --git a/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp index 82c43a4fc..dc9bea32b 100644 --- a/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp @@ -116,7 +116,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + ASSERT_LT(std::abs((*result)[31168] - 1), s->get("precision")); delete probFormula; delete result; @@ -131,7 +131,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0.4370098592), s->get("precision")); + ASSERT_LT(std::abs((*result)[31168] - 0.4370098591707694546393), s->get("precision")); delete probFormula; delete result; @@ -146,7 +146,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0.4370098592), s->get("precision")); + ASSERT_LT(std::abs((*result)[31168] - 0.5282872761373342829216), s->get("precision")); delete probFormula; delete result; @@ -156,13 +156,13 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { storm::property::prctl::Not* notFormula = new storm::property::prctl::Not(apFormula2); andFormula = new storm::property::prctl::And(apFormula, notFormula); eventuallyFormula = new storm::property::prctl::Eventually(andFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); result = mc.checkNoBoundOperator(*probFormula); ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0.1034345104), s->get("precision")); + ASSERT_LT(std::abs((*result)[31168] - 0.10343451035775527713), s->get("precision")); delete probFormula; delete result; @@ -175,7 +175,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0), s->get("precision")); + ASSERT_LT(std::abs((*result)[31168] - 0), s->get("precision")); delete probFormula; delete result; @@ -188,7 +188,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 0), s->get("precision")); + ASSERT_LT(std::abs((*result)[31168] - 0), s->get("precision")); delete probFormula; delete result; @@ -199,7 +199,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { result = mc.checkNoBoundOperator(*rewardFormula); - ASSERT_LT(std::abs((*result)[0] - 1725.593313), s->get("precision")); + ASSERT_LT(std::abs((*result)[31168] - 1725.5933133943854045), s->get("precision")); delete rewardFormula; delete result; @@ -212,7 +212,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[0] - 2179.014847), s->get("precision")); + ASSERT_LT(std::abs((*result)[31168] - 2179.014847073392047605011), s->get("precision")); delete rewardFormula; delete result; From ed4c6c84293173d86ee7414b8f048dd8c838a0bf Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 15 May 2013 23:51:56 +0200 Subject: [PATCH 131/152] Fixed SCC decomposition functions. Added performance tests for GraphAnalyzer. --- src/models/AbstractDeterministicModel.h | 4 +- src/models/AbstractModel.h | 6 +- src/models/AbstractNondeterministicModel.h | 4 +- src/storage/SparseMatrix.h | 2 +- src/utility/GraphAnalyzer.h | 6 +- test/performance/graph/GraphTest.cpp | 117 ++++++++++++++++++ .../GmmxxDtmcPrctModelCheckerTest.cpp | 3 +- test/performance/storm-performance-tests.cpp | 6 +- 8 files changed, 133 insertions(+), 15 deletions(-) create mode 100644 test/performance/graph/GraphTest.cpp diff --git a/src/models/AbstractDeterministicModel.h b/src/models/AbstractDeterministicModel.h index 7048ab3ed..1986aa776 100644 --- a/src/models/AbstractDeterministicModel.h +++ b/src/models/AbstractDeterministicModel.h @@ -52,7 +52,7 @@ class AbstractDeterministicModel: public AbstractModel { * @param state The state for which to return the iterator. * @return An iterator to the successors of the given state. */ - virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorBegin(uint_fast64_t state) { + virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorBegin(uint_fast64_t state) const { return this->getTransitionMatrix()->constColumnIteratorBegin(state); } @@ -62,7 +62,7 @@ class AbstractDeterministicModel: public AbstractModel { * @param state The state for which to return the iterator. * @return An iterator pointing to the element past the successors of the given state. */ - virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorEnd(uint_fast64_t state) { + virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorEnd(uint_fast64_t state) const { return this->getTransitionMatrix()->constColumnIteratorEnd(state); } }; diff --git a/src/models/AbstractModel.h b/src/models/AbstractModel.h index e50aa683f..806cfed67 100644 --- a/src/models/AbstractModel.h +++ b/src/models/AbstractModel.h @@ -91,7 +91,7 @@ class AbstractModel: public std::enable_shared_from_this> { * @param stronglyConnectedComponents A vector containing the SCCs of the system. * @param stateToSccMap A mapping from state indices to */ - virtual storm::storage::SparseMatrix extractSccDependencyGraph(std::vector> const& stronglyConnectedComponents, std::map const& stateToSccMap) { + storm::storage::SparseMatrix extractSccDependencyGraph(std::vector> const& stronglyConnectedComponents, std::map const& stateToSccMap) const { // The resulting sparse matrix will have as many rows/columns as there are SCCs. uint_fast64_t numberOfStates = stronglyConnectedComponents.size(); storm::storage::SparseMatrix sccDependencyGraph(numberOfStates); @@ -132,7 +132,7 @@ class AbstractModel: public std::enable_shared_from_this> { * @param state The state for which to return the iterator. * @return An iterator to the successors of the given state. */ - virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorBegin(uint_fast64_t state) = 0; + virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorBegin(uint_fast64_t state) const = 0; /*! * Returns an iterator pointing to the element past the successors of the given state. @@ -140,7 +140,7 @@ class AbstractModel: public std::enable_shared_from_this> { * @param state The state for which to return the iterator. * @return An iterator pointing to the element past the successors of the given state. */ - virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorEnd(uint_fast64_t state) = 0; + virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorEnd(uint_fast64_t state) const = 0; /*! * Returns the state space size of the model. diff --git a/src/models/AbstractNondeterministicModel.h b/src/models/AbstractNondeterministicModel.h index cd2700a49..d3f0dcf25 100644 --- a/src/models/AbstractNondeterministicModel.h +++ b/src/models/AbstractNondeterministicModel.h @@ -84,7 +84,7 @@ class AbstractNondeterministicModel: public AbstractModel { * @param state The state for which to return the iterator. * @return An iterator to the successors of the given state. */ - virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorBegin(uint_fast64_t state) { + virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorBegin(uint_fast64_t state) const { return this->getTransitionMatrix()->constColumnIteratorBegin((*nondeterministicChoiceIndices)[state]); } @@ -94,7 +94,7 @@ class AbstractNondeterministicModel: public AbstractModel { * @param state The state for which to return the iterator. * @return An iterator pointing to the element past the successors of the given state. */ - virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorEnd(uint_fast64_t state) { + virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorEnd(uint_fast64_t state) const { return this->getTransitionMatrix()->constColumnIteratorEnd((*nondeterministicChoiceIndices)[state + 1] - 1); } diff --git a/src/storage/SparseMatrix.h b/src/storage/SparseMatrix.h index b0d2a1cc2..4ae474304 100644 --- a/src/storage/SparseMatrix.h +++ b/src/storage/SparseMatrix.h @@ -219,7 +219,7 @@ public: * * @param size The number of rows and columns of the matrix. */ - SparseMatrix(uint_fast64_t size) + SparseMatrix(uint_fast64_t size = 0) : rowCount(size), colCount(size), nonZeroEntryCount(0), internalStatus(MatrixStatus::UnInitialized), currentSize(0), lastRow(0) { diff --git a/src/utility/GraphAnalyzer.h b/src/utility/GraphAnalyzer.h index c8530e7ef..fb272fd99 100644 --- a/src/utility/GraphAnalyzer.h +++ b/src/utility/GraphAnalyzer.h @@ -428,10 +428,10 @@ public: * graph of the SCCs. */ template - static std::pair>, storm::models::GraphTransitions> performSccDecomposition(storm::models::AbstractNondeterministicModel const& model) { + static std::pair>, storm::storage::SparseMatrix> performSccDecomposition(storm::models::AbstractModel const& model) { LOG4CPLUS_INFO(logger, "Computing SCC decomposition."); - std::pair>, storm::models::GraphTransitions> sccDecomposition; + std::pair>, storm::storage::SparseMatrix> sccDecomposition; uint_fast64_t numberOfStates = model.getNumberOfStates(); // Set up the environment of Tarjan's algorithm. @@ -447,7 +447,7 @@ public: uint_fast64_t currentIndex = 0; for (uint_fast64_t state = 0; state < numberOfStates; ++state) { if (!visitedStates.get(state)) { - performSccDecompositionHelper(state, currentIndex, stateIndices, lowlinks, tarjanStack, tarjanStackStates, visitedStates, model.getTransitionMatrix(), sccDecomposition.first, stateToSccMap); + performSccDecompositionHelper(state, currentIndex, stateIndices, lowlinks, tarjanStack, tarjanStackStates, visitedStates, *model.getTransitionMatrix(), sccDecomposition.first, stateToSccMap); } } diff --git a/test/performance/graph/GraphTest.cpp b/test/performance/graph/GraphTest.cpp new file mode 100644 index 000000000..0d69d3d57 --- /dev/null +++ b/test/performance/graph/GraphTest.cpp @@ -0,0 +1,117 @@ +#include "gtest/gtest.h" +#include "storm-config.h" +#include "src/utility/Settings.h" +#include "src/parser/AutoParser.h" +#include "src/utility/GraphAnalyzer.h" + +TEST(GraphAnalyzerTest, PerformProb01) { + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", ""); + + std::shared_ptr> dtmc = parser.getModel>(); + + LOG4CPLUS_INFO(logger, "Computing prob01 (3 times) for crowds/crowds20_5."); + std::pair prob01 = storm::utility::GraphAnalyzer::performProb01(*dtmc, storm::storage::BitVector(dtmc->getNumberOfStates(), true), storm::storage::BitVector(dtmc->getLabeledStates("observe0Greater1"))); + + ASSERT_EQ(prob01.first.getNumberOfSetBits(), 1724414u); + ASSERT_EQ(prob01.second.getNumberOfSetBits(), 46046u); + + prob01 = storm::utility::GraphAnalyzer::performProb01(*dtmc, storm::storage::BitVector(dtmc->getNumberOfStates(), true), storm::storage::BitVector(dtmc->getLabeledStates("observeIGreater1"))); + + ASSERT_EQ(prob01.first.getNumberOfSetBits(), 574016u); + ASSERT_EQ(prob01.second.getNumberOfSetBits(), 825797u); + + prob01 = storm::utility::GraphAnalyzer::performProb01(*dtmc, storm::storage::BitVector(dtmc->getNumberOfStates(), true), storm::storage::BitVector(dtmc->getLabeledStates("observeOnlyTrueSender"))); + + ASSERT_EQ(prob01.first.getNumberOfSetBits(), 1785309u); + ASSERT_EQ(prob01.second.getNumberOfSetBits(), 40992u); + LOG4CPLUS_INFO(logger, "Done computing prob01 (3 times) for crowds/crowds20_5."); + + storm::parser::AutoParser parser2(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.pick.trans.rew"); + + std::shared_ptr> dtmc2 = parser2.getModel>(); + + LOG4CPLUS_INFO(logger, "Computing prob01 for synchronous_leader/leader6_8"); + prob01 = storm::utility::GraphAnalyzer::performProb01(*dtmc2, storm::storage::BitVector(dtmc2->getNumberOfStates(), true), storm::storage::BitVector(dtmc2->getLabeledStates("elected"))); + LOG4CPLUS_INFO(logger, "Done computing prob01 for synchronous_leader/leader6_8"); + + ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); + ASSERT_EQ(prob01.second.getNumberOfSetBits(), 1312334u); +} + +TEST(GraphAnalyzerTest, PerformProb01MinMax) { + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.trans.rew"); + std::shared_ptr> mdp = parser.getModel>(); + + LOG4CPLUS_INFO(logger, "Computing prob01min for asynchronous_leader/leader7"); + std::pair prob01 = storm::utility::GraphAnalyzer::performProb01Min(*mdp, storm::storage::BitVector(mdp->getNumberOfStates(), true), mdp->getLabeledStates("elected")); + LOG4CPLUS_INFO(logger, "Done computing prob01min for asynchronous_leader/leader7"); + + ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); + ASSERT_EQ(prob01.second.getNumberOfSetBits(), 2095783u); + + LOG4CPLUS_INFO(logger, "Computing prob01max for asynchronous_leader/leader7"); + prob01 = storm::utility::GraphAnalyzer::performProb01Max(*mdp, storm::storage::BitVector(mdp->getNumberOfStates(), true), mdp->getLabeledStates("elected")); + LOG4CPLUS_INFO(logger, "Done computing prob01max for asynchronous_leader/leader7"); + + ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); + ASSERT_EQ(prob01.second.getNumberOfSetBits(), 2095783u); + + storm::parser::AutoParser parser2(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", ""); + std::shared_ptr> mdp2 = parser2.getModel>(); + + LOG4CPLUS_INFO(logger, "Computing prob01min for consensus/coin4_6"); + prob01 = storm::utility::GraphAnalyzer::performProb01Min(*mdp2, storm::storage::BitVector(mdp2->getNumberOfStates(), true), mdp2->getLabeledStates("finished")); + LOG4CPLUS_INFO(logger, "Done computing prob01min for consensus/coin4_6"); + + ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); + ASSERT_EQ(prob01.second.getNumberOfSetBits(), 63616u); + + LOG4CPLUS_INFO(logger, "Computing prob01max for consensus/coin4_6"); + prob01 = storm::utility::GraphAnalyzer::performProb01Max(*mdp2, storm::storage::BitVector(mdp2->getNumberOfStates(), true), mdp2->getLabeledStates("finished")); + LOG4CPLUS_INFO(logger, "Done computing prob01max for consensus/coin4_6"); + + ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); + ASSERT_EQ(prob01.second.getNumberOfSetBits(), 63616u); +} + +TEST(GraphAnalyzerTest, PerformSCCDecomposition) { + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", ""); + std::shared_ptr> dtmc = parser.getModel>(); + + LOG4CPLUS_INFO(logger, "Computing SCC decomposition of crowds/crowds20_5."); + std::pair>, storm::storage::SparseMatrix> sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*dtmc); + LOG4CPLUS_INFO(logger, "Done computing SCC decomposition of crowds/crowds20_5."); + + ASSERT_EQ(sccDecomposition.first.size(), 1290297u); + ASSERT_EQ(sccDecomposition.second.getNonZeroEntryCount(), 1371253u); + + storm::parser::AutoParser parser2(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.pick.trans.rew"); + std::shared_ptr> dtmc2 = parser2.getModel>(); + + LOG4CPLUS_INFO(logger, "Computing SCC decomposition of synchronous_leader/leader6_8"); + sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*dtmc2); + LOG4CPLUS_INFO(logger, "Computing SCC decomposition of synchronous_leader/leader6_8."); + + ASSERT_EQ(sccDecomposition.first.size(), 1279673u); + ASSERT_EQ(sccDecomposition.second.getNonZeroEntryCount(), 1535367u); + + storm::parser::AutoParser parser3(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.trans.rew"); + std::shared_ptr> mdp = parser3.getModel>(); + + LOG4CPLUS_INFO(logger, "Computing SCC decomposition of asynchronous_leader/leader7"); + sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*mdp); + LOG4CPLUS_INFO(logger, "Done computing SCC decomposition of asynchronous_leader/leader7"); + + ASSERT_EQ(sccDecomposition.first.size(), 1914691u); + ASSERT_EQ(sccDecomposition.second.getNonZeroEntryCount(), 7023587u); + + storm::parser::AutoParser parser4(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", ""); + std::shared_ptr> mdp2 = parser4.getModel>(); + + LOG4CPLUS_INFO(logger, "Computing SCC decomposition of consensus/coin4_6"); + sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*mdp2); + LOG4CPLUS_INFO(logger, "Computing SCC decomposition of consensus/coin4_6"); + + ASSERT_EQ(sccDecomposition.first.size(), 63611u); + ASSERT_EQ(sccDecomposition.second.getNonZeroEntryCount(), 213400u); +} \ No newline at end of file diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp index 2609ba0a1..3e5aa39b8 100644 --- a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp @@ -1,6 +1,5 @@ #include "gtest/gtest.h" #include "storm-config.h" - #include "src/utility/Settings.h" #include "src/modelchecker/GmmxxDtmcPrctlModelChecker.h" #include "src/parser/AutoParser.h" @@ -112,4 +111,4 @@ TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { delete rewardFormula; delete result; -} +} \ No newline at end of file diff --git a/test/performance/storm-performance-tests.cpp b/test/performance/storm-performance-tests.cpp index 1e1317a80..1c52acc03 100644 --- a/test/performance/storm-performance-tests.cpp +++ b/test/performance/storm-performance-tests.cpp @@ -15,10 +15,12 @@ log4cplus::Logger logger; * Initializes the logging framework. */ void setUpLogging() { - log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender("storm-functional-tests.log")); + logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main")); + logger.setLogLevel(log4cplus::INFO_LOG_LEVEL); + log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender("storm-performance-tests.log")); fileLogAppender->setName("mainFileAppender"); + fileLogAppender->setThreshold(log4cplus::WARN_LOG_LEVEL); fileLogAppender->setLayout(std::auto_ptr(new log4cplus::PatternLayout("%-5p - %D{%H:%M} (%r ms) - %F:%L : %m%n"))); - logger = log4cplus::Logger::getInstance("mainLogger"); logger.addAppender(fileLogAppender); // Uncomment these lines to enable console logging output From a08db1b2cf158b20c19bde373e8c4e5fec5602c3 Mon Sep 17 00:00:00 2001 From: Lanchid Date: Thu, 16 May 2013 16:32:31 +0200 Subject: [PATCH 132/152] Changed prctl parser. Now, only complete lines will be matched (Before, the parser returned a result when a prefix could be matched); furthermore, comments are supported better. --- src/parser/PrctlFileParser.cpp | 13 +++++-------- src/parser/PrctlParser.cpp | 18 +++++++++--------- src/parser/PrctlParser.h | 10 ++++++++++ 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/parser/PrctlFileParser.cpp b/src/parser/PrctlFileParser.cpp index 0f7f877f1..4fa7a13d3 100644 --- a/src/parser/PrctlFileParser.cpp +++ b/src/parser/PrctlFileParser.cpp @@ -13,8 +13,6 @@ #include "modelchecker/GmmxxDtmcPrctlModelChecker.h" #include "modelchecker/GmmxxMdpPrctlModelChecker.h" -#include - namespace storm { namespace parser { @@ -41,13 +39,12 @@ std::list*> PrctlFileParser std::string line; //The while loop reads the input file line by line while (std::getline(inputFileStream, line)) { - boost::algorithm::trim(line); - if ((line.length() == 0) || ((line[0] == '/') && (line[1] == '/'))) { - // ignore empty lines and lines starting with // - continue; - } PrctlParser parser(line); - result.push_back(parser.getFormula()); + if (!parser.parsedComment()) { + //lines containing comments will be skipped. + LOG4CPLUS_INFO(logger, "Parsed formula \"" + line + "\" into \"" + parser.getFormula()->toString() + "\""); + result.push_back(parser.getFormula()); + } } } diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index 18f470660..446a6feb5 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -43,6 +43,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar"))[qi::_val = storm::property::GREATER] | (qi::lit("<="))[qi::_val = storm::property::LESS_EQUAL] | (qi::lit("<"))[qi::_val = storm::property::LESS]); + //Comment: Empty line or line starting with "//" comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; //This block defines rules for parsing state formulas @@ -70,7 +71,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar >(qi::_1, qi::_2, qi::_3, true)] | (qi::lit("P") >> qi::lit("max") > comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = phoenix::new_ >(qi::_1, qi::_2, qi::_3, false)] | - (qi::lit("P") > comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = + (qi::lit("P") >> comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = phoenix::new_ >(qi::_1, qi::_2, qi::_3)] ); @@ -142,11 +143,17 @@ struct PrctlParser::PrctlGrammar : qi::grammar>()]; - start = (comment | noBoundOperator | stateFormula) >> qi::eoi; + formula = (noBoundOperator | stateFormula); + formula.name("PRCTL formula"); + + start = (((formula) > (comment | qi::eps))[qi::_val = qi::_1] | + comment + ) > qi::eoi; start.name("PRCTL formula"); } qi::rule*(), Skipper> start; + qi::rule*(), Skipper> formula; qi::rule*(), Skipper> comment; qi::rule*(), Skipper> stateFormula; @@ -228,12 +235,5 @@ storm::parser::PrctlParser::PrctlParser(std::string formulaString) { throw storm::exceptions::WrongFormatException() << msg.str(); } - // The syntax can be so wrong that no rule can be matched at all - // In that case, no expectation failure is thrown, but the parser just returns nullptr - // Then, of course the result is not usable, hence we throw a WrongFormatException, too. - if (positionIteratorBegin != positionIteratorEnd) { - throw storm::exceptions::WrongFormatException() << "Syntax error in formula"; - } - formula = result_pointer; } diff --git a/src/parser/PrctlParser.h b/src/parser/PrctlParser.h index 3778b862a..7e2b3d13d 100644 --- a/src/parser/PrctlParser.h +++ b/src/parser/PrctlParser.h @@ -38,6 +38,16 @@ class PrctlParser : Parser { return this->formula; } + /*! + * Checks whether the line which was parsed was a comment line; also returns true if the line was empty (as the semantics are + * the same) + * + * @return True if the parsed line consisted completely of a (valid) comment, false otherwise. + */ + bool parsedComment() { + return (formula == nullptr); + } + private: storm::property::prctl::AbstractPrctlFormula* formula; From 00a7c50ad4c313d599adfb0ef463e069db173d7d Mon Sep 17 00:00:00 2001 From: Lanchid Date: Thu, 16 May 2013 17:09:04 +0200 Subject: [PATCH 133/152] Implemented the improvements from the PRCTL parser also in the CSL and LTL parsers. --- src/parser/CslParser.cpp | 40 +++++++++++++----------- src/parser/LtlParser.cpp | 30 ++++++------------ src/parser/PrctlParser.cpp | 1 - test/functional/parser/CslParserTest.cpp | 2 +- test/functional/parser/LtlParserTest.cpp | 4 +-- 5 files changed, 35 insertions(+), 42 deletions(-) diff --git a/src/parser/CslParser.cpp b/src/parser/CslParser.cpp index a246aacaf..8538c8d3f 100644 --- a/src/parser/CslParser.cpp +++ b/src/parser/CslParser.cpp @@ -40,7 +40,15 @@ namespace parser { template struct CslParser::CslGrammar : qi::grammar*(), Skipper > { CslGrammar() : CslGrammar::base_type(start) { - freeIdentifierName = qi::lexeme[+(qi::alpha | qi::char_('_'))]; + //This block contains helper rules that may be used several times + freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; + comparisonType = ( + (qi::lit(">="))[qi::_val = storm::property::GREATER_EQUAL] | + (qi::lit(">"))[qi::_val = storm::property::GREATER] | + (qi::lit("<="))[qi::_val = storm::property::LESS_EQUAL] | + (qi::lit("<"))[qi::_val = storm::property::LESS]); + //Comment: Empty line or line starting with "//" + comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; //This block defines rules for parsing state formulas stateFormula %= orFormula; @@ -63,25 +71,13 @@ struct CslParser::CslGrammar : qi::grammar>(qi::_1)]; atomicProposition.name("state formula"); probabilisticBoundOperator = ( - (qi::lit("P") >> qi::lit(">") >> qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::GREATER, qi::_1, qi::_2)] | - (qi::lit("P") >> qi::lit(">=") > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::GREATER_EQUAL, qi::_1, qi::_2)] | - (qi::lit("P") >> qi::lit("<") >> qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::LESS, qi::_1, qi::_2)] | - (qi::lit("P") > qi::lit("<=") > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::LESS_EQUAL, qi::_1, qi::_2)] + (qi::lit("P") >> comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, qi::_2, qi::_3)] ); probabilisticBoundOperator.name("state formula"); steadyStateBoundOperator = ( - (qi::lit("S") >> qi::lit(">") >> qi::double_ > qi::lit("[") > stateFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::GREATER, qi::_1, qi::_2)] | - (qi::lit("S") >> qi::lit(">=") >> qi::double_ > qi::lit("[") > stateFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::GREATER_EQUAL, qi::_1, qi::_2)] | - (qi::lit("S") >> qi::lit("<") >> qi::double_ > qi::lit("[") > stateFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::LESS, qi::_1, qi::_2)] | - (qi::lit("S") > qi::lit("<=") >> qi::double_ > qi::lit("[") > stateFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::LESS_EQUAL, qi::_1, qi::_2)] + (qi::lit("S") >> comparisonType > qi::double_ > qi::lit("[") > stateFormula > qi::lit("]"))[qi::_val = + phoenix::new_ >(qi::_1, qi::_2, qi::_3)] ); steadyStateBoundOperator.name("state formula"); @@ -126,11 +122,18 @@ struct CslParser::CslGrammar : qi::grammar>(phoenix::bind(&storm::property::csl::AbstractStateFormula::clone, phoenix::bind(&std::shared_ptr>::get, qi::_a)), qi::_2)]; until.name("path formula (for probabilistic operator)"); - start = (noBoundOperator | stateFormula); + formula = (noBoundOperator | stateFormula); + formula.name("CSL formula"); + + start = (((formula) > (comment | qi::eps))[qi::_val = qi::_1] | + comment + ) > qi::eoi; start.name("CSL formula"); } qi::rule*(), Skipper> start; + qi::rule*(), Skipper> formula; + qi::rule*(), Skipper> comment; qi::rule*(), Skipper> stateFormula; qi::rule*(), Skipper> atomicStateFormula; @@ -155,6 +158,7 @@ struct CslParser::CslGrammar : qi::grammar freeIdentifierName; + qi::rule comparisonType; }; diff --git a/src/parser/LtlParser.cpp b/src/parser/LtlParser.cpp index 060ad5e21..6060adedc 100644 --- a/src/parser/LtlParser.cpp +++ b/src/parser/LtlParser.cpp @@ -43,6 +43,11 @@ namespace parser { template struct LtlParser::LtlGrammar : qi::grammar*(), Skipper > { LtlGrammar() : LtlGrammar::base_type(start) { + //This block contains helper rules that may be used several times + freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; + //Comment: Empty line or line starting with "//" + comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; + freeIdentifierName = qi::lexeme[+(qi::alpha | qi::char_('_'))]; //This block defines rules for parsing state formulas @@ -68,27 +73,9 @@ struct LtlParser::LtlGrammar : qi::grammar>(qi::_1)]; atomicProposition.name("LTL formula"); - /*probabilisticBoundOperator = ( - (qi::lit("P") >> qi::lit(">") >> qi::double_ > qi::lit("[") > LtlFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::GREATER, qi::_1, qi::_2)] | - (qi::lit("P") >> qi::lit(">=") > qi::double_ > qi::lit("[") > LtlFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::GREATER_EQUAL, qi::_1, qi::_2)] | - (qi::lit("P") >> qi::lit("<") >> qi::double_ > qi::lit("[") > LtlFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::LESS, qi::_1, qi::_2)] | - (qi::lit("P") >> qi::lit("<=") > qi::double_ > qi::lit("[") > LtlFormula > qi::lit("]"))[qi::_val = - phoenix::new_ >(storm::property::LESS_EQUAL, qi::_1, qi::_2)] - ); - probabilisticBoundOperator.name("state formula");*/ - - //This block defines rules for parsing formulas with noBoundOperators - /*noBoundOperator = (probabilisticNoBoundOperator | rewardNoBoundOperator); - noBoundOperator.name("no bound operator"); - probabilisticNoBoundOperator = (qi::lit("P") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> LtlFormula >> qi::lit("]"))[qi::_val = - phoenix::new_ >(qi::_1)]; - probabilisticNoBoundOperator.name("no bound operator");*/ //This block defines rules for parsing probabilistic path formulas - pathFormula = (boundedEventually | eventually | globally);//(boundedEventually | eventually | globally | boundedUntil | until); + pathFormula = (boundedEventually | eventually | globally); pathFormula.name("LTL formula"); boundedEventually = (qi::lit("F") >> qi::lit("<=") > qi::int_ > ltlFormula)[qi::_val = phoenix::new_>(qi::_2, qi::_1)]; @@ -100,11 +87,14 @@ struct LtlParser::LtlGrammar : qi::grammar >(qi::_1)]; globally.name("LTL formula"); - start = ltlFormula; + start = (((ltlFormula) > (comment | qi::eps))[qi::_val = qi::_1] | + comment + ) > qi::eoi; start.name("LTL formula"); } qi::rule*(), Skipper> start; + qi::rule*(), Skipper> comment; qi::rule*(), Skipper> ltlFormula; qi::rule*(), Skipper> atomicLtlFormula; diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index 446a6feb5..88098561d 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -35,7 +35,6 @@ namespace parser { template struct PrctlParser::PrctlGrammar : qi::grammar*(), Skipper > { PrctlGrammar() : PrctlGrammar::base_type(start) { - //This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; comparisonType = ( diff --git a/test/functional/parser/CslParserTest.cpp b/test/functional/parser/CslParserTest.cpp index ebf7250a9..f6657289c 100644 --- a/test/functional/parser/CslParserTest.cpp +++ b/test/functional/parser/CslParserTest.cpp @@ -116,7 +116,7 @@ TEST(CslParserTest, parseProbabilisticNoBoundFormulaTest) { TEST(CslParserTest, parseComplexFormulaTest) { storm::parser::CslParser* cslParser = nullptr; ASSERT_NO_THROW( - cslParser = new storm::parser::CslParser("S<=0.5 [ P <= 0.5 [ a U c ] ] & (P > 0.5 [ G b] | !P < 0.4 [ G P>0.9 [F >=7 a & b] ])") + cslParser = new storm::parser::CslParser("S<=0.5 [ P <= 0.5 [ a U c ] ] & (P > 0.5 [ G b] | !P < 0.4 [ G P>0.9 [F >=7 a & b] ]) //and a comment") ); ASSERT_NE(cslParser->getFormula(), nullptr); diff --git a/test/functional/parser/LtlParserTest.cpp b/test/functional/parser/LtlParserTest.cpp index 1a50ddb28..c88885372 100644 --- a/test/functional/parser/LtlParserTest.cpp +++ b/test/functional/parser/LtlParserTest.cpp @@ -132,7 +132,7 @@ TEST(LtlParserTest, parseComplexUntilTest) { TEST(LtlParserTest, parseComplexFormulaTest) { storm::parser::LtlParser* ltlParser = nullptr; ASSERT_NO_THROW( - ltlParser = new storm::parser::LtlParser("a U F b | G a & F<=3 a U<=7 b") + ltlParser = new storm::parser::LtlParser("a U F b | G a & F<=3 a U<=7 b //and a comment :P") ); ASSERT_NE(ltlParser->getFormula(), nullptr); @@ -145,7 +145,7 @@ TEST(LtlParserTest, parseComplexFormulaTest) { TEST(LtlParserTest, wrongFormulaTest) { storm::parser::LtlParser* ltlParser = nullptr; ASSERT_THROW( - ltlParser = new storm::parser::LtlParser("(a | b) & +"), + ltlParser = new storm::parser::LtlParser("(a | c) & +"), storm::exceptions::WrongFormatException ); delete ltlParser; From fbe1f41213bef2799a9ec4ce5f3e9545786ddeb1 Mon Sep 17 00:00:00 2001 From: dehnert Date: Thu, 16 May 2013 16:19:00 +0200 Subject: [PATCH 134/152] Removed GraphTransition class, which is now replaced by SparseMatrix in the instances where it was used before. Changed GraphAnalyzer accordingly and adapted tests. --- src/modelchecker/GmmxxMdpPrctlModelChecker.h | 2 +- ...ogicalValueIterationMdpPrctlModelChecker.h | 6 +- src/models/AbstractDeterministicModel.h | 5 +- src/models/AbstractModel.h | 73 ++++- src/models/AbstractNondeterministicModel.h | 7 +- src/models/GraphTransitions.h | 258 ------------------ src/storage/SparseMatrix.h | 24 +- src/utility/GraphAnalyzer.h | 41 ++- test/functional/storm-functional-tests.cpp | 9 +- test/performance/graph/GraphTest.cpp | 98 +++++-- .../GmmxxDtmcPrctModelCheckerTest.cpp | 14 +- .../GmmxxMdpPrctModelCheckerTest.cpp | 40 ++- test/performance/storm-performance-tests.cpp | 12 +- 13 files changed, 244 insertions(+), 345 deletions(-) delete mode 100644 src/models/GraphTransitions.h diff --git a/src/modelchecker/GmmxxMdpPrctlModelChecker.h b/src/modelchecker/GmmxxMdpPrctlModelChecker.h index 48c4c6304..3b340dadf 100644 --- a/src/modelchecker/GmmxxMdpPrctlModelChecker.h +++ b/src/modelchecker/GmmxxMdpPrctlModelChecker.h @@ -151,7 +151,7 @@ private: if (converged) { LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iterations << " iterations."); } else { - LOG4CPLUS_WARN(logger, "Iterative solver did not converge."); + LOG4CPLUS_WARN(logger, "Iterative solver did not converge after " << iterations << " iterations."); } } }; diff --git a/src/modelchecker/TopologicalValueIterationMdpPrctlModelChecker.h b/src/modelchecker/TopologicalValueIterationMdpPrctlModelChecker.h index 1466c02ec..7368a91bf 100644 --- a/src/modelchecker/TopologicalValueIterationMdpPrctlModelChecker.h +++ b/src/modelchecker/TopologicalValueIterationMdpPrctlModelChecker.h @@ -67,10 +67,8 @@ private: bool relative = s->get("relative"); // Now, we need to determine the SCCs of the MDP and a topological sort. - std::pair>, storm::models::GraphTransitions> sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(this->getModel(), stronglyConnectedComponents, stronglyConnectedComponentsDependencyGraph); - std::vector> stronglyConnectedComponents = std::move(sccDecomposition.first); - storm::models::GraphTransitions stronglyConnectedComponentsDependencyGraph = std::move(sccDecomposition.second); - + std::vector> stronglyConnectedComponents = storm::utility::GraphAnalyzer::performSccDecomposition(this->getModel(), stronglyConnectedComponents, stronglyConnectedComponentsDependencyGraph); + storm::storage::SparseMatrix stronglyConnectedComponentsDependencyGraph = this->getModel().extractSccDependencyGraph(stronglyConnectedComponents); std::vector topologicalSort = storm::utility::GraphAnalyzer::getTopologicalSort(stronglyConnectedComponentsDependencyGraph); // Set up the environment for the power method. diff --git a/src/models/AbstractDeterministicModel.h b/src/models/AbstractDeterministicModel.h index 1986aa776..a45b5df77 100644 --- a/src/models/AbstractDeterministicModel.h +++ b/src/models/AbstractDeterministicModel.h @@ -2,7 +2,6 @@ #define STORM_MODELS_ABSTRACTDETERMINISTICMODEL_H_ #include "AbstractModel.h" -#include "GraphTransitions.h" #include @@ -53,7 +52,7 @@ class AbstractDeterministicModel: public AbstractModel { * @return An iterator to the successors of the given state. */ virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorBegin(uint_fast64_t state) const { - return this->getTransitionMatrix()->constColumnIteratorBegin(state); + return this->transitionMatrix->constColumnIteratorBegin(state); } /*! @@ -63,7 +62,7 @@ class AbstractDeterministicModel: public AbstractModel { * @return An iterator pointing to the element past the successors of the given state. */ virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorEnd(uint_fast64_t state) const { - return this->getTransitionMatrix()->constColumnIteratorEnd(state); + return this->transitionMatrix->constColumnIteratorEnd(state); } }; diff --git a/src/models/AbstractModel.h b/src/models/AbstractModel.h index 806cfed67..c4896a6c6 100644 --- a/src/models/AbstractModel.h +++ b/src/models/AbstractModel.h @@ -91,9 +91,20 @@ class AbstractModel: public std::enable_shared_from_this> { * @param stronglyConnectedComponents A vector containing the SCCs of the system. * @param stateToSccMap A mapping from state indices to */ - storm::storage::SparseMatrix extractSccDependencyGraph(std::vector> const& stronglyConnectedComponents, std::map const& stateToSccMap) const { - // The resulting sparse matrix will have as many rows/columns as there are SCCs. + storm::storage::SparseMatrix extractSccDependencyGraph(std::vector> const& stronglyConnectedComponents) const { uint_fast64_t numberOfStates = stronglyConnectedComponents.size(); + + // First, we need to create a mapping of states to their SCC index, to ease the computation + // of dependency transitions later. + std::vector stateToSccMap(this->getNumberOfStates()); + for (uint_fast64_t i = 0; i < numberOfStates; ++i) { + for (uint_fast64_t j = 0; j < stronglyConnectedComponents[i].size(); ++j) { + stateToSccMap[stronglyConnectedComponents[i][j]] = i; + } + } + + // The resulting sparse matrix will have as many rows/columns as there are SCCs. + storm::storage::SparseMatrix sccDependencyGraph(numberOfStates); sccDependencyGraph.initialize(); @@ -105,7 +116,7 @@ class AbstractModel: public std::enable_shared_from_this> { std::set allTargetSccs; for (auto state : scc) { for (typename storm::storage::SparseMatrix::ConstIndexIterator succIt = this->constStateSuccessorIteratorBegin(state), succIte = this->constStateSuccessorIteratorEnd(state); succIt != succIte; ++succIt) { - uint_fast64_t targetScc = stateToSccMap.find(*succIt)->second; + uint_fast64_t targetScc = stateToSccMap[*succIt]; // We only need to consider transitions that are actually leaving the SCC. if (targetScc != currentSccIndex) { @@ -125,6 +136,59 @@ class AbstractModel: public std::enable_shared_from_this> { return sccDependencyGraph; } + + /*! + * Retrieves the backward transition relation of the model, i.e. a set of transitions + * between states that correspond to the reversed transition relation of this model. + * + * @return A sparse matrix that represents the backward transitions of this model. + */ + virtual storm::storage::SparseMatrix getBackwardTransitions() const { + uint_fast64_t numberOfStates = this->getNumberOfStates(); + uint_fast64_t numberOfTransitions = this->getNumberOfTransitions(); + + std::vector rowIndications(numberOfStates + 1); + std::vector columnIndications(numberOfTransitions); + std::vector values(numberOfTransitions, true); + + // First, we need to count how many backward transitions each state has. + for (uint_fast64_t i = 0; i < numberOfStates; ++i) { + for (auto rowIt = this->constStateSuccessorIteratorBegin(i), rowIte = this->constStateSuccessorIteratorEnd(i); rowIt != rowIte; ++rowIt) { + rowIndications[*rowIt + 1]++; + } + } + + // Now compute the accumulated offsets. + for (uint_fast64_t i = 1; i < numberOfStates; ++i) { + rowIndications[i] = rowIndications[i - 1] + rowIndications[i]; + } + + // Put a sentinel element at the end of the indices list. This way, + // for each state i the range of indices can be read off between + // state_indices_list[i] and state_indices_list[i + 1]. + // FIXME: This should not be necessary and already be implied by the first steps. + rowIndications[numberOfStates] = numberOfTransitions; + + // Create an array that stores the next index for each state. Initially + // this corresponds to the previously computed accumulated offsets. + std::vector nextIndices = rowIndications; + + // Now we are ready to actually fill in the list of predecessors for + // every state. Again, we start by considering all but the last row. + for (uint_fast64_t i = 0; i < numberOfStates; ++i) { + for (auto rowIt = this->constStateSuccessorIteratorBegin(i), rowIte = this->constStateSuccessorIteratorEnd(i); rowIt != rowIte; ++rowIt) { + columnIndications[nextIndices[*rowIt]++] = i; + } + } + + storm::storage::SparseMatrix backwardTransitionMatrix(numberOfStates, numberOfStates, + numberOfTransitions, + std::move(rowIndications), + std::move(columnIndications), + std::move(values)); + + return backwardTransitionMatrix; + } /*! * Returns an iterator to the successors of the given state. @@ -269,10 +333,11 @@ class AbstractModel: public std::enable_shared_from_this> { << std::endl; } - private: + protected: /*! A matrix representing the likelihoods of moving between states. */ std::shared_ptr> transitionMatrix; +private: /*! The labeling of the states of the model. */ std::shared_ptr stateLabeling; diff --git a/src/models/AbstractNondeterministicModel.h b/src/models/AbstractNondeterministicModel.h index d3f0dcf25..b64359d2f 100644 --- a/src/models/AbstractNondeterministicModel.h +++ b/src/models/AbstractNondeterministicModel.h @@ -2,7 +2,6 @@ #define STORM_MODELS_ABSTRACTNONDETERMINISTICMODEL_H_ #include "AbstractModel.h" -#include "GraphTransitions.h" #include @@ -56,7 +55,7 @@ class AbstractNondeterministicModel: public AbstractModel { * @return The number of choices for all states of the MDP. */ uint_fast64_t getNumberOfChoices() const { - return this->getTransitionMatrix()->getRowCount(); + return this->transitionMatrix->getRowCount(); } /*! @@ -85,7 +84,7 @@ class AbstractNondeterministicModel: public AbstractModel { * @return An iterator to the successors of the given state. */ virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorBegin(uint_fast64_t state) const { - return this->getTransitionMatrix()->constColumnIteratorBegin((*nondeterministicChoiceIndices)[state]); + return this->transitionMatrix->constColumnIteratorBegin((*nondeterministicChoiceIndices)[state]); } /*! @@ -95,7 +94,7 @@ class AbstractNondeterministicModel: public AbstractModel { * @return An iterator pointing to the element past the successors of the given state. */ virtual typename storm::storage::SparseMatrix::ConstIndexIterator constStateSuccessorIteratorEnd(uint_fast64_t state) const { - return this->getTransitionMatrix()->constColumnIteratorEnd((*nondeterministicChoiceIndices)[state + 1] - 1); + return this->transitionMatrix->constColumnIteratorEnd((*nondeterministicChoiceIndices)[state + 1] - 1); } private: diff --git a/src/models/GraphTransitions.h b/src/models/GraphTransitions.h deleted file mode 100644 index de435a00b..000000000 --- a/src/models/GraphTransitions.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * GraphTransitions.h - * - * Created on: 17.11.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_MODELS_GRAPHTRANSITIONS_H_ -#define STORM_MODELS_GRAPHTRANSITIONS_H_ - -#include "src/storage/SparseMatrix.h" - -#include -#include - -namespace storm { - -namespace models { - -/*! - * This class stores the successors of all states in a state space of the - * given size. - */ -template -class GraphTransitions { - -public: - /*! - * Just typedef the iterator as a pointer to the index type. - */ - typedef const uint_fast64_t * stateSuccessorIterator; - - //! Constructor - /*! - * Constructs an object representing the graph structure of the given - * transition relation, which is given by a sparse matrix. - * @param transitionMatrix The (0-based) matrix representing the transition - * relation. - * @param forward If set to true, this objects will store the graph structure - * of the backwards transition relation. - */ - GraphTransitions(storm::storage::SparseMatrix const& transitionMatrix, bool forward) - : numberOfStates(transitionMatrix.getColumnCount()), numberOfTransitions(transitionMatrix.getNonZeroEntryCount()), successorList(numberOfTransitions), stateIndications(numberOfStates + 1) { - if (forward) { - this->initializeForward(transitionMatrix); - } else { - this->initializeBackward(transitionMatrix); - } - } - - GraphTransitions(storm::storage::SparseMatrix const& transitionMatrix, std::vector const& nondeterministicChoiceIndices, bool forward) - : numberOfStates(transitionMatrix.getColumnCount()), numberOfTransitions(transitionMatrix.getNonZeroEntryCount()), successorList(numberOfTransitions), stateIndications(numberOfStates + 1) { - if (forward) { - this->initializeForward(transitionMatrix, nondeterministicChoiceIndices); - } else { - this->initializeBackward(transitionMatrix, nondeterministicChoiceIndices); - } - } - - GraphTransitions(GraphTransitions const& transitions, std::vector> const& stronglyConnectedComponents, std::map const& stateToSccMap) - : numberOfStates(stronglyConnectedComponents.size()), numberOfTransitions(0), successorList(), stateIndications(numberOfStates + 1) { - this->initializeFromSccDecomposition(transitions, stronglyConnectedComponents, stateToSccMap); - } - - GraphTransitions() : numberOfStates(0), numberOfTransitions(0), successorList(), stateIndications() { - // Intentionally left empty. - } - - /*! - * Retrieves the size of the internal representation of the graph transitions in memory. - * @return the size of the internal representation of the graph transitions in memory - * measured in bytes. - */ - virtual uint_fast64_t getSizeInMemory() const { - uint_fast64_t result = sizeof(this) + (numberOfStates + numberOfTransitions + 1) * sizeof(uint_fast64_t); - return result; - } - - uint_fast64_t getNumberOfStates() const { - return numberOfStates; - } - - uint_fast64_t getNumberOfTransitions() const { - return numberOfTransitions; - } - - /*! - * Returns an iterator to the successors of the given state. - * @param state The state for which to get the successor iterator. - * @return An iterator to the predecessors of the given states. - */ - stateSuccessorIterator beginStateSuccessorsIterator(uint_fast64_t state) const { - return &(this->successorList[0]) + this->stateIndications[state]; - } - - /*! - * Returns an iterator referring to the element after the successors of - * the given state. - * @param state The state for which to get the iterator. - * @return An iterator referring to the element after the successors of - * the given state. - */ - stateSuccessorIterator endStateSuccessorsIterator(uint_fast64_t state) const { - return &(this->successorList[0]) + this->stateIndications[state + 1]; - } - - /*! - * Returns a (naive) string representation of the transitions in this object. - * @returns a (naive) string representation of the transitions in this object. - */ - std::string toString() const { - std::stringstream stream; - for (uint_fast64_t state = 0; state < numberOfStates; ++state) { - for (auto succIt = this->beginStateSuccessorsIterator(state), succIte = this->endStateSuccessorsIterator(state); succIt != succIte; ++succIt) { - stream << state << " -> " << *succIt << std::endl; - } - } - return stream.str(); - } - -private: - /*! - * Initializes this graph transitions object using the forward transition - * relation given by means of a sparse matrix. - */ - void initializeForward(storm::storage::SparseMatrix const& transitionMatrix) { - // First, we copy the index list from the sparse matrix as this will - // stay the same. - std::copy(transitionMatrix.constColumnIteratorBegin(), transitionMatrix.constColumnIteratorEnd(), this->stateIndications.begin()); - - // Now we can iterate over all rows of the transition matrix and record the target state. - for (uint_fast64_t i = 0, currentNonZeroElement = 0; i < numberOfStates; i++) { - for (auto rowIt = transitionMatrix.constColumnIteratorBegin(i); rowIt != transitionMatrix.constColumnIteratorEnd(i); ++rowIt) { - this->successorList[currentNonZeroElement++] = *rowIt; - } - } - } - - void initializeForward(storm::storage::SparseMatrix const& transitionMatrix, std::vector const& nondeterministicChoiceIndices) { - // We can directly copy the starting indices from the transition matrix as we do not - // eliminate duplicate transitions and therefore will have as many non-zero entries as this - // matrix. - typename storm::storage::SparseMatrix::ConstRowsIterator rowsIt(transitionMatrix); - for (uint_fast64_t i = 0; i < numberOfStates; ++i) { - rowsIt.moveToRow(nondeterministicChoiceIndices[i]); - this->stateIndications[i] = rowsIt.index(); - } - this->stateIndications[numberOfStates] = numberOfTransitions; - - // Now we can iterate over all rows of the transition matrix and record - // the target state. - for (uint_fast64_t i = 0, currentNonZeroElement = 0; i < numberOfStates; i++) { - for (uint_fast64_t j = nondeterministicChoiceIndices[i]; j < nondeterministicChoiceIndices[i + 1]; ++j) { - for (auto rowIt = transitionMatrix.constColumnIteratorBegin(j); rowIt != transitionMatrix.constColumnIteratorEnd(j); ++rowIt) { - this->successorList[currentNonZeroElement++] = *rowIt; - } - } - } - } - - /*! - * Initializes this graph transitions object using the backwards transition - * relation, whose forward transition relation is given by means of a sparse - * matrix. - */ - void initializeBackward(storm::storage::SparseMatrix const& transitionMatrix) { - // First, we need to count how many backward transitions each state has. - for (uint_fast64_t i = 0; i < numberOfStates; ++i) { - for (auto rowIt = transitionMatrix.constColumnIteratorBegin(i); rowIt != transitionMatrix.constColumnIteratorEnd(i); ++rowIt) { - this->stateIndications[*rowIt + 1]++; - } - } - - // Now compute the accumulated offsets. - for (uint_fast64_t i = 1; i < numberOfStates; ++i) { - this->stateIndications[i] = this->stateIndications[i - 1] + this->stateIndications[i]; - } - - // Put a sentinel element at the end of the indices list. This way, - // for each state i the range of indices can be read off between - // state_indices_list[i] and state_indices_list[i + 1]. - this->stateIndications[numberOfStates] = numberOfTransitions; - - // Create an array that stores the next index for each state. Initially - // this corresponds to the previously computed accumulated offsets. - std::vector nextIndices = stateIndications; - - // Now we are ready to actually fill in the list of predecessors for - // every state. Again, we start by considering all but the last row. - for (uint_fast64_t i = 0; i < numberOfStates; ++i) { - for (auto rowIt = transitionMatrix.constColumnIteratorBegin(i); rowIt != transitionMatrix.constColumnIteratorEnd(i); ++rowIt) { - this->successorList[nextIndices[*rowIt]++] = i; - } - } - } - - void initializeBackward(storm::storage::SparseMatrix const& transitionMatrix, std::vector const& nondeterministicChoiceIndices) { - // First, we need to count how many backward transitions each state has. - for (uint_fast64_t i = 0; i < numberOfStates; ++i) { - for (uint_fast64_t j = nondeterministicChoiceIndices[i]; j < nondeterministicChoiceIndices[i + 1]; ++j) { - for (auto rowIt = transitionMatrix.constColumnIteratorBegin(j); rowIt != transitionMatrix.constColumnIteratorEnd(j); ++rowIt) { - this->stateIndications[*rowIt + 1]++; - } - } - } - - // Now compute the accumulated offsets. - for (uint_fast64_t i = 1; i < numberOfStates; i++) { - this->stateIndications[i] = this->stateIndications[i - 1] + this->stateIndications[i]; - } - - // Put a sentinel element at the end of the indices list. This way, - // for each state i the range of indices can be read off between - // state_indices_list[i] and state_indices_list[i + 1]. - this->stateIndications[numberOfStates] = numberOfTransitions; - - // Create an array that stores the next index for each state. Initially - // this corresponds to the previously computed accumulated offsets. - std::vector nextIndices = stateIndications; - - // Now we are ready to actually fill in the list of predecessors for - // every state. Again, we start by considering all but the last row. - for (uint_fast64_t i = 0; i < numberOfStates; i++) { - for (uint_fast64_t j = nondeterministicChoiceIndices[i]; j < nondeterministicChoiceIndices[i + 1]; ++j) { - for (auto rowIt = transitionMatrix.constColumnIteratorBegin(j); rowIt != transitionMatrix.constColumnIteratorEnd(j); ++rowIt) { - this->successorList[nextIndices[*rowIt]++] = i; - } - } - } - } - - /*! - * Store the number of states to determine the highest index at which the - * state_indices_list may be accessed. - */ - uint_fast64_t numberOfStates; - - /*! - * Store the number of non-zero transition entries to determine the highest - * index at which the predecessor_list may be accessed. - */ - uint_fast64_t numberOfTransitions; - - /*! A list of successors for *all* states. */ - std::vector successorList; - - /*! - * A list of indices indicating at which position in the global array the - * successors of a state can be found. - */ - std::vector stateIndications; -}; - -} // namespace models - -} // namespace storm - -#endif /* STORM_MODELS_GRAPHTRANSITIONS_H_ */ diff --git a/src/storage/SparseMatrix.h b/src/storage/SparseMatrix.h index 4ae474304..a968f7ee5 100644 --- a/src/storage/SparseMatrix.h +++ b/src/storage/SparseMatrix.h @@ -211,7 +211,7 @@ public: */ SparseMatrix(uint_fast64_t rows, uint_fast64_t cols) : rowCount(rows), colCount(cols), nonZeroEntryCount(0), internalStatus(MatrixStatus::UnInitialized), currentSize(0), lastRow(0) { - + // Intentionally left empty. } /*! @@ -222,8 +222,28 @@ public: SparseMatrix(uint_fast64_t size = 0) : rowCount(size), colCount(size), nonZeroEntryCount(0), internalStatus(MatrixStatus::UnInitialized), currentSize(0), lastRow(0) { - + // Intentionally left empty. } + + /*! + * Constructs a sparse matrix object with the given (moved) contents. + * + * @param rowCount The number of rows. + * @param colCount The number of columns. + * @param nonZeroEntryCount The number of non-zero entries. + * @param rowIndications The vector indicating where the rows start. + * @param columnIndications The vector indicating the column for each non-zero element. + * @param values The vector containing the non-zero values. + */ + SparseMatrix(uint_fast64_t rowCount, uint_fast64_t colCount, uint_fast64_t nonZeroEntryCount, + std::vector&& rowIndications, + std::vector&& columnIndications, std::vector&& values) + : rowCount(rowCount), colCount(colCount), nonZeroEntryCount(nonZeroEntryCount), + valueStorage(values), columnIndications(columnIndications), + rowIndications(rowIndications), internalStatus(MatrixStatus::Initialized), + currentSize(0), lastRow(0) { + // Intentionally left empty. + } /*! * Initializes the sparse matrix with the given number of non-zero entries diff --git a/src/utility/GraphAnalyzer.h b/src/utility/GraphAnalyzer.h index fb272fd99..577bccf74 100644 --- a/src/utility/GraphAnalyzer.h +++ b/src/utility/GraphAnalyzer.h @@ -58,7 +58,7 @@ public: storm::storage::BitVector statesWithProbabilityGreater0(model.getNumberOfStates()); // Get the backwards transition relation from the model to ease the search. - storm::models::GraphTransitions backwardTransitions(*model.getTransitionMatrix(), false); + storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); // Add all psi states as the already satisfy the condition. statesWithProbabilityGreater0 |= psiStates; @@ -73,7 +73,7 @@ public: uint_fast64_t currentState = stack.back(); stack.pop_back(); - for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) { + for(auto it = backwardTransitions.constColumnIteratorBegin(currentState); it != backwardTransitions.constColumnIteratorEnd(currentState); ++it) { if (phiStates.get(*it) && !statesWithProbabilityGreater0.get(*it)) { statesWithProbabilityGreater0.set(*it, true); stack.push_back(*it); @@ -161,7 +161,7 @@ public: storm::storage::BitVector statesWithProbability0(model.getNumberOfStates()); // Get the backwards transition relation from the model to ease the search. - storm::models::GraphTransitions backwardTransitions(*model.getTransitionMatrix(), *model.getNondeterministicChoiceIndices(), false); + storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); // Add all psi states as the already satisfy the condition. statesWithProbability0 |= psiStates; @@ -176,7 +176,7 @@ public: uint_fast64_t currentState = stack.back(); stack.pop_back(); - for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) { + for(auto it = backwardTransitions.constColumnIteratorBegin(currentState), ite = backwardTransitions.constColumnIteratorEnd(currentState); it != ite; ++it) { if (phiStates.get(*it) && !statesWithProbability0.get(*it)) { statesWithProbability0.set(*it, true); stack.push_back(*it); @@ -207,7 +207,7 @@ public: std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); // Get the backwards transition relation from the model to ease the search. - storm::models::GraphTransitions backwardTransitions(*model.getTransitionMatrix(), *model.getNondeterministicChoiceIndices(), false); + storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); storm::storage::BitVector currentStates(model.getNumberOfStates(), true); @@ -225,7 +225,7 @@ public: uint_fast64_t currentState = stack.back(); stack.pop_back(); - for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) { + for(auto it = backwardTransitions.constColumnIteratorBegin(currentState), ite = backwardTransitions.constColumnIteratorEnd(currentState); it != ite; ++it) { if (phiStates.get(*it) && !nextStates.get(*it)) { // Check whether the predecessor has only successors in the current state set for one of the // nondeterminstic choices. @@ -300,7 +300,7 @@ public: std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); // Get the backwards transition relation from the model to ease the search. - storm::models::GraphTransitions backwardTransitions(*transitionMatrix, *nondeterministicChoiceIndices, false); + storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); // Add all psi states as the already satisfy the condition. statesWithProbability0 |= psiStates; @@ -315,7 +315,7 @@ public: uint_fast64_t currentState = stack.back(); stack.pop_back(); - for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) { + for(auto it = backwardTransitions.constColumnIteratorBegin(currentState), ite = backwardTransitions.constColumnIteratorEnd(currentState); it != ite; ++it) { if (phiStates.get(*it) && !statesWithProbability0.get(*it)) { // Check whether the predecessor has at least one successor in the current state // set for every nondeterministic choice. @@ -366,7 +366,7 @@ public: std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); // Get the backwards transition relation from the model to ease the search. - storm::models::GraphTransitions backwardTransitions(*model.getTransitionMatrix(), *model.getNondeterministicChoiceIndices(), false); + storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); storm::storage::BitVector currentStates(model.getNumberOfStates(), true); @@ -384,7 +384,7 @@ public: uint_fast64_t currentState = stack.back(); stack.pop_back(); - for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) { + for(auto it = backwardTransitions.constColumnIteratorBegin(currentState), ite = backwardTransitions.constColumnIteratorEnd(currentState); it != ite; ++it) { if (phiStates.get(*it) && !nextStates.get(*it)) { // Check whether the predecessor has only successors in the current state set for all of the // nondeterminstic choices. @@ -421,17 +421,16 @@ public: } /*! - * Performs a decomposition of the given nondeterministic model into its SCCs. + * Performs a decomposition of the given model into its SCCs. * * @param model The nondeterminstic model to decompose. - * @return A pair whose first component represents the SCCs and whose second component represents the dependency - * graph of the SCCs. + * @return A vector of SCCs of the model. */ template - static std::pair>, storm::storage::SparseMatrix> performSccDecomposition(storm::models::AbstractModel const& model) { + static std::vector> performSccDecomposition(storm::models::AbstractModel const& model) { LOG4CPLUS_INFO(logger, "Computing SCC decomposition."); - std::pair>, storm::storage::SparseMatrix> sccDecomposition; + std::vector> scc; uint_fast64_t numberOfStates = model.getNumberOfStates(); // Set up the environment of Tarjan's algorithm. @@ -441,21 +440,17 @@ public: std::vector stateIndices(numberOfStates); std::vector lowlinks(numberOfStates); storm::storage::BitVector visitedStates(numberOfStates); - std::map stateToSccMap; // Start the search for SCCs from every vertex in the graph structure, because there is. uint_fast64_t currentIndex = 0; for (uint_fast64_t state = 0; state < numberOfStates; ++state) { if (!visitedStates.get(state)) { - performSccDecompositionHelper(state, currentIndex, stateIndices, lowlinks, tarjanStack, tarjanStackStates, visitedStates, *model.getTransitionMatrix(), sccDecomposition.first, stateToSccMap); + performSccDecompositionHelper(state, currentIndex, stateIndices, lowlinks, tarjanStack, tarjanStackStates, visitedStates, *model.getTransitionMatrix(), scc); } } - - // Finally, determine the dependency graph over the SCCs and return result. - sccDecomposition.second = model.extractSccDependencyGraph(sccDecomposition.first, stateToSccMap); LOG4CPLUS_INFO(logger, "Done computing SCC decomposition."); - return sccDecomposition; + return scc; } /*! @@ -551,10 +546,9 @@ private: * @param visitedStates A bit vector that stores all states that have already been visited. * @param matrix The transition matrix representing the graph structure. * @param stronglyConnectedComponents A vector of strongly connected components to which newly found SCCs are added. - * @param stateToSccMap A mapping from state indices to SCC indices that maps each state to its SCC. */ template - static void performSccDecompositionHelper(uint_fast64_t startState, uint_fast64_t& currentIndex, std::vector& stateIndices, std::vector& lowlinks, std::vector& tarjanStack, storm::storage::BitVector& tarjanStackStates, storm::storage::BitVector& visitedStates, storm::storage::SparseMatrix const& matrix, std::vector>& stronglyConnectedComponents, std::map& stateToSccMap) { + static void performSccDecompositionHelper(uint_fast64_t startState, uint_fast64_t& currentIndex, std::vector& stateIndices, std::vector& lowlinks, std::vector& tarjanStack, storm::storage::BitVector& tarjanStackStates, storm::storage::BitVector& visitedStates, storm::storage::SparseMatrix const& matrix, std::vector>& stronglyConnectedComponents) { // Create the stacks needed for turning the recursive formulation of Tarjan's algorithm // into an iterative version. In particular, we keep one stack for states and one stack // for the iterators. The last one is not strictly needed, but reduces iteration work when @@ -623,7 +617,6 @@ private: // Add the state to the current SCC. stronglyConnectedComponents.back().push_back(lastState); - stateToSccMap[lastState] = stronglyConnectedComponents.size() - 1; } while (lastState != currentState); } diff --git a/test/functional/storm-functional-tests.cpp b/test/functional/storm-functional-tests.cpp index 7139bed3c..abfb5a125 100644 --- a/test/functional/storm-functional-tests.cpp +++ b/test/functional/storm-functional-tests.cpp @@ -15,10 +15,12 @@ log4cplus::Logger logger; * Initializes the logging framework. */ void setUpLogging() { + logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main")); + logger.setLogLevel(log4cplus::ERROR_LOG_LEVEL); log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender("storm-functional-tests.log")); fileLogAppender->setName("mainFileAppender"); + fileLogAppender->setThreshold(log4cplus::FATAL_LOG_LEVEL); fileLogAppender->setLayout(std::auto_ptr(new log4cplus::PatternLayout("%-5p - %D{%H:%M} (%r ms) - %F:%L : %m%n"))); - logger = log4cplus::Logger::getInstance("mainLogger"); logger.addAppender(fileLogAppender); // Uncomment these lines to enable console logging output @@ -62,5 +64,8 @@ int main(int argc, char* argv[]) { testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + int result = RUN_ALL_TESTS(); + + logger.closeNestedAppenders(); + return result; } diff --git a/test/performance/graph/GraphTest.cpp b/test/performance/graph/GraphTest.cpp index 0d69d3d57..84f264004 100644 --- a/test/performance/graph/GraphTest.cpp +++ b/test/performance/graph/GraphTest.cpp @@ -9,7 +9,7 @@ TEST(GraphAnalyzerTest, PerformProb01) { std::shared_ptr> dtmc = parser.getModel>(); - LOG4CPLUS_INFO(logger, "Computing prob01 (3 times) for crowds/crowds20_5."); + LOG4CPLUS_WARN(logger, "Computing prob01 (3 times) for crowds/crowds20_5..."); std::pair prob01 = storm::utility::GraphAnalyzer::performProb01(*dtmc, storm::storage::BitVector(dtmc->getNumberOfStates(), true), storm::storage::BitVector(dtmc->getLabeledStates("observe0Greater1"))); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 1724414u); @@ -24,94 +24,132 @@ TEST(GraphAnalyzerTest, PerformProb01) { ASSERT_EQ(prob01.first.getNumberOfSetBits(), 1785309u); ASSERT_EQ(prob01.second.getNumberOfSetBits(), 40992u); - LOG4CPLUS_INFO(logger, "Done computing prob01 (3 times) for crowds/crowds20_5."); + LOG4CPLUS_WARN(logger, "Done."); + + dtmc = nullptr; storm::parser::AutoParser parser2(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.pick.trans.rew"); std::shared_ptr> dtmc2 = parser2.getModel>(); - LOG4CPLUS_INFO(logger, "Computing prob01 for synchronous_leader/leader6_8"); + LOG4CPLUS_WARN(logger, "Computing prob01 for synchronous_leader/leader6_8..."); prob01 = storm::utility::GraphAnalyzer::performProb01(*dtmc2, storm::storage::BitVector(dtmc2->getNumberOfStates(), true), storm::storage::BitVector(dtmc2->getLabeledStates("elected"))); - LOG4CPLUS_INFO(logger, "Done computing prob01 for synchronous_leader/leader6_8"); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); ASSERT_EQ(prob01.second.getNumberOfSetBits(), 1312334u); + + dtmc2 = nullptr; } TEST(GraphAnalyzerTest, PerformProb01MinMax) { storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.trans.rew"); std::shared_ptr> mdp = parser.getModel>(); - LOG4CPLUS_INFO(logger, "Computing prob01min for asynchronous_leader/leader7"); + LOG4CPLUS_WARN(logger, "Computing prob01min for asynchronous_leader/leader7..."); std::pair prob01 = storm::utility::GraphAnalyzer::performProb01Min(*mdp, storm::storage::BitVector(mdp->getNumberOfStates(), true), mdp->getLabeledStates("elected")); - LOG4CPLUS_INFO(logger, "Done computing prob01min for asynchronous_leader/leader7"); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); ASSERT_EQ(prob01.second.getNumberOfSetBits(), 2095783u); - LOG4CPLUS_INFO(logger, "Computing prob01max for asynchronous_leader/leader7"); + LOG4CPLUS_WARN(logger, "Computing prob01max for asynchronous_leader/leader7..."); prob01 = storm::utility::GraphAnalyzer::performProb01Max(*mdp, storm::storage::BitVector(mdp->getNumberOfStates(), true), mdp->getLabeledStates("elected")); - LOG4CPLUS_INFO(logger, "Done computing prob01max for asynchronous_leader/leader7"); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); ASSERT_EQ(prob01.second.getNumberOfSetBits(), 2095783u); + + mdp = nullptr; storm::parser::AutoParser parser2(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", ""); std::shared_ptr> mdp2 = parser2.getModel>(); - LOG4CPLUS_INFO(logger, "Computing prob01min for consensus/coin4_6"); + LOG4CPLUS_WARN(logger, "Computing prob01min for consensus/coin4_6..."); prob01 = storm::utility::GraphAnalyzer::performProb01Min(*mdp2, storm::storage::BitVector(mdp2->getNumberOfStates(), true), mdp2->getLabeledStates("finished")); - LOG4CPLUS_INFO(logger, "Done computing prob01min for consensus/coin4_6"); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); ASSERT_EQ(prob01.second.getNumberOfSetBits(), 63616u); - LOG4CPLUS_INFO(logger, "Computing prob01max for consensus/coin4_6"); + LOG4CPLUS_WARN(logger, "Computing prob01max for consensus/coin4_6..."); prob01 = storm::utility::GraphAnalyzer::performProb01Max(*mdp2, storm::storage::BitVector(mdp2->getNumberOfStates(), true), mdp2->getLabeledStates("finished")); - LOG4CPLUS_INFO(logger, "Done computing prob01max for consensus/coin4_6"); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); ASSERT_EQ(prob01.second.getNumberOfSetBits(), 63616u); + + mdp2 = nullptr; } -TEST(GraphAnalyzerTest, PerformSCCDecomposition) { +TEST(GraphAnalyzerTest, PerformSCCDecompositionAndGetDependencyGraph) { storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", ""); std::shared_ptr> dtmc = parser.getModel>(); - LOG4CPLUS_INFO(logger, "Computing SCC decomposition of crowds/crowds20_5."); - std::pair>, storm::storage::SparseMatrix> sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*dtmc); - LOG4CPLUS_INFO(logger, "Done computing SCC decomposition of crowds/crowds20_5."); + LOG4CPLUS_WARN(logger, "Computing SCC decomposition of crowds/crowds20_5..."); + std::vector> sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*dtmc); + LOG4CPLUS_WARN(logger, "Done."); - ASSERT_EQ(sccDecomposition.first.size(), 1290297u); - ASSERT_EQ(sccDecomposition.second.getNonZeroEntryCount(), 1371253u); + ASSERT_EQ(sccDecomposition.size(), 1290297u); + + LOG4CPLUS_WARN(logger, "Extracting SCC dependency graph of crowds/crowds20_5..."); + storm::storage::SparseMatrix sccDependencyGraph = dtmc->extractSccDependencyGraph(sccDecomposition); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_EQ(sccDependencyGraph.getNonZeroEntryCount(), 1371253u); + + dtmc = nullptr; storm::parser::AutoParser parser2(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.pick.trans.rew"); std::shared_ptr> dtmc2 = parser2.getModel>(); - LOG4CPLUS_INFO(logger, "Computing SCC decomposition of synchronous_leader/leader6_8"); + LOG4CPLUS_WARN(logger, "Computing SCC decomposition of synchronous_leader/leader6_8..."); sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*dtmc2); - LOG4CPLUS_INFO(logger, "Computing SCC decomposition of synchronous_leader/leader6_8."); + LOG4CPLUS_WARN(logger, "Done."); - ASSERT_EQ(sccDecomposition.first.size(), 1279673u); - ASSERT_EQ(sccDecomposition.second.getNonZeroEntryCount(), 1535367u); + ASSERT_EQ(sccDecomposition.size(), 1279673u); + + LOG4CPLUS_WARN(logger, "Extracting SCC dependency graph of synchronous_leader/leader6_8..."); + sccDependencyGraph = dtmc2->extractSccDependencyGraph(sccDecomposition); + LOG4CPLUS_WARN(logger, "Done."); + ASSERT_EQ(sccDependencyGraph.getNonZeroEntryCount(), 1535367u); + + dtmc2 = nullptr; + + /* storm::parser::AutoParser parser3(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.trans.rew"); std::shared_ptr> mdp = parser3.getModel>(); - LOG4CPLUS_INFO(logger, "Computing SCC decomposition of asynchronous_leader/leader7"); + LOG4CPLUS_WARN(logger, "Computing SCC decomposition of asynchronous_leader/leader7..."); sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*mdp); - LOG4CPLUS_INFO(logger, "Done computing SCC decomposition of asynchronous_leader/leader7"); + LOG4CPLUS_WARN(logger, "Done."); - ASSERT_EQ(sccDecomposition.first.size(), 1914691u); - ASSERT_EQ(sccDecomposition.second.getNonZeroEntryCount(), 7023587u); + ASSERT_EQ(sccDecomposition.size(), 1914691u); + + LOG4CPLUS_WARN(logger, "Extracting SCC dependency graph of asynchronous_leader/leader7..."); + sccDependencyGraph = mdp->extractSccDependencyGraph(sccDecomposition); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_EQ(sccDependencyGraph.getNonZeroEntryCount(), 7023587u); + + mdp = nullptr; + */ storm::parser::AutoParser parser4(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", ""); std::shared_ptr> mdp2 = parser4.getModel>(); - LOG4CPLUS_INFO(logger, "Computing SCC decomposition of consensus/coin4_6"); + LOG4CPLUS_WARN(logger, "Computing SCC decomposition of consensus/coin4_6..."); sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*mdp2); - LOG4CPLUS_INFO(logger, "Computing SCC decomposition of consensus/coin4_6"); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_EQ(sccDecomposition.size(), 63611u); + + LOG4CPLUS_WARN(logger, "Extracting SCC dependency graph of consensus/coin4_6..."); + sccDependencyGraph = mdp2->extractSccDependencyGraph(sccDecomposition); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_EQ(sccDependencyGraph.getNonZeroEntryCount(), 213400u); - ASSERT_EQ(sccDecomposition.first.size(), 63611u); - ASSERT_EQ(sccDecomposition.second.getNonZeroEntryCount(), 213400u); + mdp2 = nullptr; } \ No newline at end of file diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp index 3e5aa39b8..bf0a72403 100644 --- a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp @@ -22,7 +22,9 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { storm::property::prctl::Eventually* eventuallyFormula = new storm::property::prctl::Eventually(apFormula); storm::property::prctl::ProbabilisticNoBoundOperator* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula); + LOG4CPLUS_WARN(logger, "Model Checking P=? [F observe0Greater1] on crowds/crowds20_5..."); std::vector* result = probFormula->check(mc); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); @@ -35,8 +37,10 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { eventuallyFormula = new storm::property::prctl::Eventually(apFormula); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula); + LOG4CPLUS_WARN(logger, "Model Checking P=? [F observeIGreater1] on crowds/crowds20_5..."); result = probFormula->check(mc); - + LOG4CPLUS_WARN(logger, "Done."); + ASSERT_NE(nullptr, result); ASSERT_LT(std::abs((*result)[0] - 0.05072232915), s->get("precision")); @@ -48,7 +52,9 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { eventuallyFormula = new storm::property::prctl::Eventually(apFormula); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula); + LOG4CPLUS_WARN(logger, "Model Checking P=? [F observeOnlyTrueSender] on crowds/crowds20_5..."); result = probFormula->check(mc); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); @@ -77,7 +83,9 @@ TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { storm::property::prctl::Eventually* eventuallyFormula = new storm::property::prctl::Eventually(apFormula); storm::property::prctl::ProbabilisticNoBoundOperator* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula); + LOG4CPLUS_WARN(logger, "Model Checking P=? [F elected] on synchronous_leader/leader6_8..."); std::vector* result = probFormula->check(mc); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); @@ -90,7 +98,9 @@ TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { storm::property::prctl::BoundedUntil* boundedUntilFormula = new storm::property::prctl::BoundedUntil(new storm::property::prctl::Ap("true"), apFormula, 20); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedUntilFormula); + LOG4CPLUS_WARN(logger, "Model Checking P=? [F<=20 elected] on synchronous_leader/leader6_8..."); result = probFormula->check(mc); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); @@ -103,7 +113,9 @@ TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { storm::property::prctl::ReachabilityReward* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); storm::property::prctl::RewardNoBoundOperator* rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula); + LOG4CPLUS_WARN(logger, "Model Checking R=? [F elected] on synchronous_leader/leader6_8..."); result = rewardFormula->check(mc); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); diff --git a/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp index dc9bea32b..cf8e91581 100644 --- a/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp @@ -22,7 +22,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { storm::property::prctl::Eventually* eventuallyFormula = new storm::property::prctl::Eventually(apFormula); storm::property::prctl::ProbabilisticNoBoundOperator* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F elected] on asynchronous_leader/leader7..."); std::vector* result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); @@ -35,7 +37,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { eventuallyFormula = new storm::property::prctl::Eventually(apFormula); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); + LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F elected] on asynchronous_leader/leader7..."); result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); @@ -48,7 +52,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { storm::property::prctl::BoundedEventually* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 25); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, true); + LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F<=25 elected] on asynchronous_leader/leader7..."); result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); @@ -61,7 +67,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 25); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, false); + LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F<=25 elected] on asynchronous_leader/leader7..."); result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); @@ -74,7 +82,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { storm::property::prctl::ReachabilityReward* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); storm::property::prctl::RewardNoBoundOperator* rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, true); + LOG4CPLUS_WARN(logger, "Model Checking Rmin=? [F elected] on asynchronous_leader/leader7..."); result = mc.checkNoBoundOperator(*rewardFormula); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs((*result)[0] - 6.172433512), s->get("precision")); @@ -85,7 +95,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, false); - result = mc.checkNoBoundOperator(*rewardFormula);; + LOG4CPLUS_WARN(logger, "Model Checking Rmax=? [F elected] on asynchronous_leader/leader7..."); + result = mc.checkNoBoundOperator(*rewardFormula); + LOG4CPLUS_WARN(logger, "Done"); ASSERT_NE(nullptr, result); @@ -97,6 +109,8 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { storm::settings::Settings* s = storm::settings::instance(); + s->set("maxiter", 20000); + std::cout << s->get("maxiter") << std::endl; storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", ""); ASSERT_EQ(parser.getType(), storm::models::MDP); @@ -112,7 +126,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { storm::property::prctl::Eventually* eventuallyFormula = new storm::property::prctl::Eventually(apFormula); storm::property::prctl::ProbabilisticNoBoundOperator* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F finished] on consensus/coin4_6..."); std::vector* result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); @@ -127,7 +143,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { eventuallyFormula = new storm::property::prctl::Eventually(andFormula); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F finished & all_coins_equal_0] on consensus/coin4_6..."); result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); @@ -142,10 +160,11 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { eventuallyFormula = new storm::property::prctl::Eventually(andFormula); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); + LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F finished & all_coins_equal_1] on consensus/coin4_6..."); result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[31168] - 0.5282872761373342829216), s->get("precision")); delete probFormula; @@ -158,10 +177,11 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { eventuallyFormula = new storm::property::prctl::Eventually(andFormula); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); + LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F finished & !agree] on consensus/coin4_6..."); result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[31168] - 0.10343451035775527713), s->get("precision")); delete probFormula; @@ -171,10 +191,11 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { storm::property::prctl::BoundedEventually* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 50); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, true); + LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F<=50 finished] on consensus/coin4_6..."); result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[31168] - 0), s->get("precision")); delete probFormula; @@ -184,10 +205,11 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 50); probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, false); + LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F<=50 finished] on consensus/coin4_6..."); result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[31168] - 0), s->get("precision")); delete probFormula; @@ -197,8 +219,11 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { storm::property::prctl::ReachabilityReward* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); storm::property::prctl::RewardNoBoundOperator* rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, true); + LOG4CPLUS_WARN(logger, "Model Checking Rmin=? [F finished] on consensus/coin4_6..."); result = mc.checkNoBoundOperator(*rewardFormula); + LOG4CPLUS_WARN(logger, "Done."); + ASSERT_NE(nullptr, result); ASSERT_LT(std::abs((*result)[31168] - 1725.5933133943854045), s->get("precision")); delete rewardFormula; @@ -208,10 +233,11 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, false); - result = mc.checkNoBoundOperator(*rewardFormula);; + LOG4CPLUS_WARN(logger, "Model Checking Rmax=? [F finished] on consensus/coin4_6..."); + result = mc.checkNoBoundOperator(*rewardFormula); + LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[31168] - 2179.014847073392047605011), s->get("precision")); delete rewardFormula; diff --git a/test/performance/storm-performance-tests.cpp b/test/performance/storm-performance-tests.cpp index 1c52acc03..49983a9e1 100644 --- a/test/performance/storm-performance-tests.cpp +++ b/test/performance/storm-performance-tests.cpp @@ -16,7 +16,7 @@ log4cplus::Logger logger; */ void setUpLogging() { logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main")); - logger.setLogLevel(log4cplus::INFO_LOG_LEVEL); + logger.setLogLevel(log4cplus::WARN_LOG_LEVEL); log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender("storm-performance-tests.log")); fileLogAppender->setName("mainFileAppender"); fileLogAppender->setThreshold(log4cplus::WARN_LOG_LEVEL); @@ -42,9 +42,8 @@ bool parseOptions(int const argc, char const * const argv[]) { storm::settings::Settings::registerModule>(); s = storm::settings::newInstance(argc, argv, nullptr, true); } catch (storm::exceptions::InvalidSettingsException& e) { - std::cout << "Could not recover from settings error: " << e.what() << "." << std::endl; - std::cout << std::endl << storm::settings::help; - return false; + // Ignore this case. + return true; } if (s->isSet("help")) { @@ -64,5 +63,8 @@ int main(int argc, char* argv[]) { testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + int result = RUN_ALL_TESTS(); + + logger.closeNestedAppenders(); + return result; } From 3c32eec8e10f3a3dc6c436828da9ecfd340d3f28 Mon Sep 17 00:00:00 2001 From: dehnert Date: Thu, 16 May 2013 16:32:56 +0200 Subject: [PATCH 135/152] Made the prob0/1 algorithms for MDPs share a common backward transition object. --- src/modelchecker/SparseMdpPrctlModelChecker.h | 4 +- src/utility/GraphAnalyzer.h | 40 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/modelchecker/SparseMdpPrctlModelChecker.h b/src/modelchecker/SparseMdpPrctlModelChecker.h index 0c951ae8f..f76092cd2 100644 --- a/src/modelchecker/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/SparseMdpPrctlModelChecker.h @@ -360,9 +360,9 @@ public: storm::storage::BitVector infinityStates; storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); if (this->minimumOperatorStack.top()) { - infinityStates = storm::utility::GraphAnalyzer::performProb1A(this->getModel(), trueStates, *targetStates); + infinityStates = storm::utility::GraphAnalyzer::performProb1A(this->getModel(), this->getModel().getBackwardTransitions(), trueStates, *targetStates); } else { - infinityStates = storm::utility::GraphAnalyzer::performProb1E(this->getModel(), trueStates, *targetStates); + infinityStates = storm::utility::GraphAnalyzer::performProb1E(this->getModel(), this->getModel().getBackwardTransitions(), trueStates, *targetStates); } infinityStates.complement(); diff --git a/src/utility/GraphAnalyzer.h b/src/utility/GraphAnalyzer.h index 577bccf74..b3eab9727 100644 --- a/src/utility/GraphAnalyzer.h +++ b/src/utility/GraphAnalyzer.h @@ -139,8 +139,12 @@ public: template static std::pair performProb01Max(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { std::pair result; - result.first = GraphAnalyzer::performProb0A(model, phiStates, psiStates); - result.second = GraphAnalyzer::performProb1E(model, phiStates, psiStates); + + // Get the backwards transition relation from the model to ease the search. + storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); + + result.first = GraphAnalyzer::performProb0A(model, backwardTransitions, phiStates, psiStates); + result.second = GraphAnalyzer::performProb1E(model, backwardTransitions, phiStates, psiStates); return result; } @@ -151,17 +155,15 @@ public: * scheduler tries to maximize this probability. * * @param model The model whose graph structure to search. + * @param backwardTransitions The reversed transition relation of the model. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. * @return A bit vector that represents all states with probability 0. */ template - static storm::storage::BitVector performProb0A(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + static storm::storage::BitVector performProb0A(storm::models::AbstractNondeterministicModel const& model, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { // Prepare the resulting bit vector. storm::storage::BitVector statesWithProbability0(model.getNumberOfStates()); - - // Get the backwards transition relation from the model to ease the search. - storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); // Add all psi states as the already satisfy the condition. statesWithProbability0 |= psiStates; @@ -196,19 +198,17 @@ public: * scheduler tries to maximize this probability. * * @param model The model whose graph structure to search. + * @param backwardTransitions The reversed transition relation of the model. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. * @return A bit vector that represents all states with probability 1. */ template - static storm::storage::BitVector performProb1E(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + static storm::storage::BitVector performProb1E(storm::models::AbstractNondeterministicModel const& model, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { // Get some temporaries for convenience. std::shared_ptr> transitionMatrix = model.getTransitionMatrix(); std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); - // Get the backwards transition relation from the model to ease the search. - storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); - storm::storage::BitVector currentStates(model.getNumberOfStates(), true); std::vector stack; @@ -274,8 +274,12 @@ public: template static std::pair performProb01Min(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { std::pair result; - result.first = GraphAnalyzer::performProb0E(model, phiStates, psiStates); - result.second = GraphAnalyzer::performProb1A(model, phiStates, psiStates); + + // Get the backwards transition relation from the model to ease the search. + storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); + + result.first = GraphAnalyzer::performProb0E(model, backwardTransitions, phiStates, psiStates); + result.second = GraphAnalyzer::performProb1A(model, backwardTransitions, phiStates, psiStates); return result; } @@ -286,12 +290,13 @@ public: * scheduler tries to minimize this probability. * * @param model The model whose graph structure to search. + * @param backwardTransitions The reversed transition relation of the model. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. * @return A bit vector that represents all states with probability 0. */ template - static storm::storage::BitVector performProb0E(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + static storm::storage::BitVector performProb0E(storm::models::AbstractNondeterministicModel const& model, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { // Prepare resulting bit vector. storm::storage::BitVector statesWithProbability0(model.getNumberOfStates()); @@ -299,9 +304,6 @@ public: std::shared_ptr> transitionMatrix = model.getTransitionMatrix(); std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); - // Get the backwards transition relation from the model to ease the search. - storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); - // Add all psi states as the already satisfy the condition. statesWithProbability0 |= psiStates; @@ -355,19 +357,17 @@ public: * scheduler tries to minimize this probability. * * @param model The model whose graph structure to search. + * @param backwardTransitions The reversed transition relation of the model. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. * @return A bit vector that represents all states with probability 0. */ template - static storm::storage::BitVector performProb1A(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + static storm::storage::BitVector performProb1A(storm::models::AbstractNondeterministicModel const& model, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { // Get some temporaries for convenience. std::shared_ptr> transitionMatrix = model.getTransitionMatrix(); std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); - // Get the backwards transition relation from the model to ease the search. - storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); - storm::storage::BitVector currentStates(model.getNumberOfStates(), true); std::vector stack; From 307911ca139a5581a47c0a1fa691dae95c83ea0e Mon Sep 17 00:00:00 2001 From: dehnert Date: Thu, 16 May 2013 17:41:41 +0200 Subject: [PATCH 136/152] Fixed performance tests, they now run fine. --- src/modelchecker/EigenDtmcPrctlModelChecker.h | 1 - .../SparseDtmcPrctlModelChecker.h | 6 +- src/modelchecker/SparseMdpPrctlModelChecker.h | 10 +- src/utility/Settings.h | 15 +- src/utility/{GraphAnalyzer.h => graph.h} | 323 +++++++++--------- test/performance/graph/GraphTest.cpp | 54 ++- .../GmmxxMdpPrctModelCheckerTest.cpp | 4 +- 7 files changed, 206 insertions(+), 207 deletions(-) rename src/utility/{GraphAnalyzer.h => graph.h} (87%) diff --git a/src/modelchecker/EigenDtmcPrctlModelChecker.h b/src/modelchecker/EigenDtmcPrctlModelChecker.h index 7c5b06ad0..c6e4840c7 100644 --- a/src/modelchecker/EigenDtmcPrctlModelChecker.h +++ b/src/modelchecker/EigenDtmcPrctlModelChecker.h @@ -12,7 +12,6 @@ #include "src/models/Dtmc.h" #include "src/modelchecker/SparseDtmcPrctlModelChecker.h" -#include "src/utility/GraphAnalyzer.h" #include "src/utility/ConstTemplates.h" #include "src/exceptions/NoConvergenceException.h" diff --git a/src/modelchecker/SparseDtmcPrctlModelChecker.h b/src/modelchecker/SparseDtmcPrctlModelChecker.h index 56c7a9525..c19cc471a 100644 --- a/src/modelchecker/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/SparseDtmcPrctlModelChecker.h @@ -11,7 +11,7 @@ #include "src/modelchecker/AbstractModelChecker.h" #include "src/models/Dtmc.h" #include "src/utility/Vector.h" -#include "src/utility/GraphAnalyzer.h" +#include "src/utility/graph.h" #include @@ -209,7 +209,7 @@ public: // Then, we need to identify the states which have to be taken out of the matrix, i.e. // all states that have probability 0 and 1 of satisfying the until-formula. - std::pair statesWithProbability01 = storm::utility::GraphAnalyzer::performProb01(this->getModel(), *leftStates, *rightStates); + std::pair statesWithProbability01 = storm::utility::graph::performProb01(this->getModel(), *leftStates, *rightStates); storm::storage::BitVector statesWithProbability0 = std::move(statesWithProbability01.first); storm::storage::BitVector statesWithProbability1 = std::move(statesWithProbability01.second); @@ -357,7 +357,7 @@ public: // Determine which states have a reward of infinity by definition. storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); - storm::storage::BitVector infinityStates = storm::utility::GraphAnalyzer::performProb1(this->getModel(), trueStates, *targetStates); + storm::storage::BitVector infinityStates = storm::utility::graph::performProb1(this->getModel(), trueStates, *targetStates); infinityStates.complement(); // Create resulting vector. diff --git a/src/modelchecker/SparseMdpPrctlModelChecker.h b/src/modelchecker/SparseMdpPrctlModelChecker.h index f76092cd2..8849cd222 100644 --- a/src/modelchecker/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/SparseMdpPrctlModelChecker.h @@ -11,7 +11,7 @@ #include "src/modelchecker/AbstractModelChecker.h" #include "src/models/Mdp.h" #include "src/utility/Vector.h" -#include "src/utility/GraphAnalyzer.h" +#include "src/utility/graph.h" #include #include @@ -215,9 +215,9 @@ public: // all states that have probability 0 and 1 of satisfying the until-formula. std::pair statesWithProbability01; if (this->minimumOperatorStack.top()) { - statesWithProbability01 = storm::utility::GraphAnalyzer::performProb01Min(this->getModel(), *leftStates, *rightStates); + statesWithProbability01 = storm::utility::graph::performProb01Min(this->getModel(), *leftStates, *rightStates); } else { - statesWithProbability01 = storm::utility::GraphAnalyzer::performProb01Max(this->getModel(), *leftStates, *rightStates); + statesWithProbability01 = storm::utility::graph::performProb01Max(this->getModel(), *leftStates, *rightStates); } storm::storage::BitVector statesWithProbability0 = std::move(statesWithProbability01.first); storm::storage::BitVector statesWithProbability1 = std::move(statesWithProbability01.second); @@ -360,9 +360,9 @@ public: storm::storage::BitVector infinityStates; storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); if (this->minimumOperatorStack.top()) { - infinityStates = storm::utility::GraphAnalyzer::performProb1A(this->getModel(), this->getModel().getBackwardTransitions(), trueStates, *targetStates); + infinityStates = storm::utility::graph::performProb1A(this->getModel(), this->getModel().getBackwardTransitions(), trueStates, *targetStates); } else { - infinityStates = storm::utility::GraphAnalyzer::performProb1E(this->getModel(), this->getModel().getBackwardTransitions(), trueStates, *targetStates); + infinityStates = storm::utility::graph::performProb1E(this->getModel(), this->getModel().getBackwardTransitions(), trueStates, *targetStates); } infinityStates.complement(); diff --git a/src/utility/Settings.h b/src/utility/Settings.h index 900b34673..b68aa4e6f 100644 --- a/src/utility/Settings.h +++ b/src/utility/Settings.h @@ -52,7 +52,7 @@ namespace settings { * @brief Get value of a generic option. */ template - inline const T& get( std::string const & name) const { + const T& get(std::string const& name) const { if (this->vm.count(name) == 0) throw storm::exceptions::InvalidSettingsException() << "Could not read option " << name << "."; return this->vm[name].as(); } @@ -60,32 +60,33 @@ namespace settings { /*! * @brief Get value of string option. */ - inline const std::string& getString(std::string const & name) const { + const std::string& getString(std::string const& name) const { return this->get(name); } /*! * @brief Check if an option is set. */ - inline const bool isSet(std::string const & name) const { + const bool isSet(std::string const& name) const { return this->vm.count(name) > 0; } /*! * @brief Set an option. */ - inline void set(std::string const & name) { + void set(std::string const& name) { bpo::variable_value val; - this->vm.insert( std::make_pair(name, val) ); + this->vm.insert(std::make_pair(name, val)); } /*! * @brief Set value for an option. */ template - inline void set(std::string const & name, T const & value) { + void set(std::string const& name, T const& value) { bpo::variable_value val(value, false); - this->vm.insert( std::make_pair(name, val) ); + this->vm.erase(name); + this->vm.insert(std::make_pair(name, val)); } /*! diff --git a/src/utility/GraphAnalyzer.h b/src/utility/graph.h similarity index 87% rename from src/utility/GraphAnalyzer.h rename to src/utility/graph.h index b3eab9727..d3494877d 100644 --- a/src/utility/GraphAnalyzer.h +++ b/src/utility/graph.h @@ -5,8 +5,8 @@ * Author: Christian Dehnert */ -#ifndef STORM_UTILITY_GRAPHANALYZER_H_ -#define STORM_UTILITY_GRAPHANALYZER_H_ +#ifndef STORM_UTILITY_GRAPH_H_ +#define STORM_UTILITY_GRAPH_H_ #include "src/models/AbstractDeterministicModel.h" #include "src/models/AbstractNondeterministicModel.h" @@ -20,27 +20,8 @@ extern log4cplus::Logger logger; namespace storm { namespace utility { - -class GraphAnalyzer { -public: - /*! - * Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi until psi in a - * deterministic model. - * - * @param model The model whose graph structure to search. - * @param phiStates The set of all states satisfying phi. - * @param psiStates The set of all states satisfying psi. - * @return A pair of bit vectors such that the first bit vector stores the indices of all states - * with probability 0 and the second stores all indices of states with probability 1. - */ - template - static std::pair performProb01(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { - std::pair result; - result.first = GraphAnalyzer::performProbGreater0(model, phiStates, psiStates); - result.second = GraphAnalyzer::performProb1(model, phiStates, psiStates, result.first); - result.first.complement(); - return result; - } + +namespace graph { /*! * Performs a backwards breadt-first search trough the underlying graph structure @@ -53,7 +34,7 @@ public: * @return A bit vector with all indices of states that have a probability greater than 0. */ template - static storm::storage::BitVector performProbGreater0(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + storm::storage::BitVector performProbGreater0(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { // Prepare the resulting bit vector. storm::storage::BitVector statesWithProbabilityGreater0(model.getNumberOfStates()); @@ -100,8 +81,8 @@ public: * @return A bit vector with all indices of states that have a probability greater than 1. */ template - static storm::storage::BitVector performProb1(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& statesWithProbabilityGreater0) { - storm::storage::BitVector statesWithProbability1 = GraphAnalyzer::performProbGreater0(model, ~psiStates, ~statesWithProbabilityGreater0); + storm::storage::BitVector performProb1(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& statesWithProbabilityGreater0) { + storm::storage::BitVector statesWithProbability1 = performProbGreater0(model, ~psiStates, ~statesWithProbabilityGreater0); statesWithProbability1.complement(); return statesWithProbability1; } @@ -119,32 +100,29 @@ public: * @return A bit vector with all indices of states that have a probability greater than 1. */ template - static storm::storage::BitVector performProb1(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { - storm::storage::BitVector statesWithProbabilityGreater0 = GraphAnalyzer::performProbGreater0(model, phiStates, psiStates); - storm::storage::BitVector statesWithProbability1 = GraphAnalyzer::performProbGreater0(model, ~psiStates, ~(statesWithProbabilityGreater0)); + storm::storage::BitVector performProb1(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + storm::storage::BitVector statesWithProbabilityGreater0 = performProbGreater0(model, phiStates, psiStates); + storm::storage::BitVector statesWithProbability1 = performProbGreater0(model, ~psiStates, ~(statesWithProbabilityGreater0)); statesWithProbability1.complement(); return statesWithProbability1; } - /*! - * Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi - * until psi in a non-deterministic model in which all non-deterministic choices are resolved - * such that the probability is maximized. + /*! + * Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi until psi in a + * deterministic model. * * @param model The model whose graph structure to search. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. - * @return A pair of bit vectors that represent all states with probability 0 and 1, respectively. + * @return A pair of bit vectors such that the first bit vector stores the indices of all states + * with probability 0 and the second stores all indices of states with probability 1. */ template - static std::pair performProb01Max(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { - std::pair result; - - // Get the backwards transition relation from the model to ease the search. - storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); - - result.first = GraphAnalyzer::performProb0A(model, backwardTransitions, phiStates, psiStates); - result.second = GraphAnalyzer::performProb1E(model, backwardTransitions, phiStates, psiStates); + static std::pair performProb01(storm::models::AbstractDeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + std::pair result; + result.first = performProbGreater0(model, phiStates, psiStates); + result.second = performProb1(model, phiStates, psiStates, result.first); + result.first.complement(); return result; } @@ -161,7 +139,7 @@ public: * @return A bit vector that represents all states with probability 0. */ template - static storm::storage::BitVector performProb0A(storm::models::AbstractNondeterministicModel const& model, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + storm::storage::BitVector performProb0A(storm::models::AbstractNondeterministicModel const& model, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { // Prepare the resulting bit vector. storm::storage::BitVector statesWithProbability0(model.getNumberOfStates()); @@ -204,7 +182,7 @@ public: * @return A bit vector that represents all states with probability 1. */ template - static storm::storage::BitVector performProb1E(storm::models::AbstractNondeterministicModel const& model, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + storm::storage::BitVector performProb1E(storm::models::AbstractNondeterministicModel const& model, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { // Get some temporaries for convenience. std::shared_ptr> transitionMatrix = model.getTransitionMatrix(); std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); @@ -261,25 +239,26 @@ public: return currentStates; } - /*! + + /*! * Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi * until psi in a non-deterministic model in which all non-deterministic choices are resolved - * such that the probability is minimized. + * such that the probability is maximized. * * @param model The model whose graph structure to search. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. * @return A pair of bit vectors that represent all states with probability 0 and 1, respectively. */ - template - static std::pair performProb01Min(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + template + std::pair performProb01Max(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { std::pair result; // Get the backwards transition relation from the model to ease the search. storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); - result.first = GraphAnalyzer::performProb0E(model, backwardTransitions, phiStates, psiStates); - result.second = GraphAnalyzer::performProb1A(model, backwardTransitions, phiStates, psiStates); + result.first = performProb0A(model, backwardTransitions, phiStates, psiStates); + result.second = performProb1E(model, backwardTransitions, phiStates, psiStates); return result; } @@ -296,7 +275,7 @@ public: * @return A bit vector that represents all states with probability 0. */ template - static storm::storage::BitVector performProb0E(storm::models::AbstractNondeterministicModel const& model, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + storm::storage::BitVector performProb0E(storm::models::AbstractNondeterministicModel const& model, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { // Prepare resulting bit vector. storm::storage::BitVector statesWithProbability0(model.getNumberOfStates()); @@ -363,7 +342,7 @@ public: * @return A bit vector that represents all states with probability 0. */ template - static storm::storage::BitVector performProb1A(storm::models::AbstractNondeterministicModel const& model, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + storm::storage::BitVector performProb1A(storm::models::AbstractNondeterministicModel const& model, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { // Get some temporaries for convenience. std::shared_ptr> transitionMatrix = model.getTransitionMatrix(); std::shared_ptr> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices(); @@ -420,6 +399,132 @@ public: return currentStates; } + /*! + * Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi + * until psi in a non-deterministic model in which all non-deterministic choices are resolved + * such that the probability is minimized. + * + * @param model The model whose graph structure to search. + * @param phiStates The set of all states satisfying phi. + * @param psiStates The set of all states satisfying psi. + * @return A pair of bit vectors that represent all states with probability 0 and 1, respectively. + */ + template + std::pair performProb01Min(storm::models::AbstractNondeterministicModel const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + std::pair result; + + // Get the backwards transition relation from the model to ease the search. + storm::storage::SparseMatrix backwardTransitions = model.getBackwardTransitions(); + + result.first = performProb0E(model, backwardTransitions, phiStates, psiStates); + result.second = performProb1A(model, backwardTransitions, phiStates, psiStates); + return result; + } + + /*! + * Performs an SCC decomposition using Tarjan's algorithm. + * + * @param startState The state at which the search is started. + * @param currentIndex The index that is to be used as the next free index. + * @param stateIndices The vector that stores the index for each state. + * @param lowlinks A vector that stores the lowlink of each state, i.e. the lowest index of a state reachable from + * a particular state. + * @param tarjanStack A stack used for Tarjan's algorithm. + * @param tarjanStackStates A bit vector that represents all states that are currently contained in tarjanStack. + * @param visitedStates A bit vector that stores all states that have already been visited. + * @param matrix The transition matrix representing the graph structure. + * @param stronglyConnectedComponents A vector of strongly connected components to which newly found SCCs are added. + */ + template + void performSccDecompositionHelper(uint_fast64_t startState, uint_fast64_t& currentIndex, std::vector& stateIndices, std::vector& lowlinks, std::vector& tarjanStack, storm::storage::BitVector& tarjanStackStates, storm::storage::BitVector& visitedStates, storm::storage::SparseMatrix const& matrix, std::vector>& stronglyConnectedComponents) { + // Create the stacks needed for turning the recursive formulation of Tarjan's algorithm + // into an iterative version. In particular, we keep one stack for states and one stack + // for the iterators. The last one is not strictly needed, but reduces iteration work when + // all successors of a particular state are considered. + std::vector recursionStateStack; + recursionStateStack.reserve(lowlinks.size()); + std::vector::ConstIndexIterator> recursionIteratorStack; + recursionIteratorStack.reserve(lowlinks.size()); + std::vector statesInStack(lowlinks.size()); + + // Initialize the recursion stacks with the given initial state (and its successor iterator). + recursionStateStack.push_back(startState); + recursionIteratorStack.push_back(matrix.constColumnIteratorBegin(startState)); + + recursionStepForward: + while (!recursionStateStack.empty()) { + uint_fast64_t currentState = recursionStateStack.back(); + typename storm::storage::SparseMatrix::ConstIndexIterator currentIt = recursionIteratorStack.back(); + + // Perform the treatment of newly discovered state as defined by Tarjan's algorithm + visitedStates.set(currentState, true); + stateIndices[currentState] = currentIndex; + lowlinks[currentState] = currentIndex; + ++currentIndex; + tarjanStack.push_back(currentState); + tarjanStackStates.set(currentState, true); + + // Now, traverse all successors of the current state. + for(; currentIt != matrix.constColumnIteratorEnd(currentState); ++currentIt) { + // If we have not visited the successor already, we need to perform the procedure + // recursively on the newly found state. + if (!visitedStates.get(*currentIt)) { + // Save current iterator position so we can continue where we left off later. + recursionIteratorStack.pop_back(); + recursionIteratorStack.push_back(currentIt); + + // Put unvisited successor on top of our recursion stack and remember that. + recursionStateStack.push_back(*currentIt); + statesInStack[*currentIt] = true; + + // Also, put initial value for iterator on corresponding recursion stack. + recursionIteratorStack.push_back(matrix.constColumnIteratorBegin(*currentIt)); + + // Perform the actual recursion step in an iterative way. + goto recursionStepForward; + + recursionStepBackward: + lowlinks[currentState] = std::min(lowlinks[currentState], lowlinks[*currentIt]); + } else if (tarjanStackStates.get(*currentIt)) { + // Update the lowlink of the current state. + lowlinks[currentState] = std::min(lowlinks[currentState], stateIndices[*currentIt]); + } + } + + // If the current state is the root of a SCC, we need to pop all states of the SCC from + // the algorithm's stack. + if (lowlinks[currentState] == stateIndices[currentState]) { + stronglyConnectedComponents.push_back(std::vector()); + + uint_fast64_t lastState = 0; + do { + // Pop topmost state from the algorithm's stack. + lastState = tarjanStack.back(); + tarjanStack.pop_back(); + tarjanStackStates.set(lastState, false); + + // Add the state to the current SCC. + stronglyConnectedComponents.back().push_back(lastState); + } while (lastState != currentState); + } + + // If we reach this point, we have completed the recursive descent for the current state. + // That is, we need to pop it from the recursion stacks. + recursionStateStack.pop_back(); + recursionIteratorStack.pop_back(); + + // If there is at least one state under the current one in our recursion stack, we need + // to restore the topmost state as the current state and jump to the part after the + // original recursive call. + if (recursionStateStack.size() > 0) { + currentState = recursionStateStack.back(); + currentIt = recursionIteratorStack.back(); + + goto recursionStepBackward; + } + } + } + /*! * Performs a decomposition of the given model into its SCCs. * @@ -427,7 +532,7 @@ public: * @return A vector of SCCs of the model. */ template - static std::vector> performSccDecomposition(storm::models::AbstractModel const& model) { + std::vector> performSccDecomposition(storm::models::AbstractModel const& model) { LOG4CPLUS_INFO(logger, "Computing SCC decomposition."); std::vector> scc; @@ -460,7 +565,7 @@ public: * @return A vector of indices that is a topological sort of the states. */ template - static std::vector getTopologicalSort(storm::storage::SparseMatrix const& matrix) { + std::vector getTopologicalSort(storm::storage::SparseMatrix const& matrix) { if (matrix.getRowCount() != matrix.getColumnCount()) { LOG4CPLUS_ERROR(logger, "Provided matrix is required to be square."); throw storm::exceptions::InvalidArgumentException() << "Provided matrix is required to be square."; @@ -531,115 +636,11 @@ public: return topologicalSort; } - -private: - /*! - * Performs an SCC decomposition using Tarjan's algorithm. - * - * @param startState The state at which the search is started. - * @param currentIndex The index that is to be used as the next free index. - * @param stateIndices The vector that stores the index for each state. - * @param lowlinks A vector that stores the lowlink of each state, i.e. the lowest index of a state reachable from - * a particular state. - * @param tarjanStack A stack used for Tarjan's algorithm. - * @param tarjanStackStates A bit vector that represents all states that are currently contained in tarjanStack. - * @param visitedStates A bit vector that stores all states that have already been visited. - * @param matrix The transition matrix representing the graph structure. - * @param stronglyConnectedComponents A vector of strongly connected components to which newly found SCCs are added. - */ - template - static void performSccDecompositionHelper(uint_fast64_t startState, uint_fast64_t& currentIndex, std::vector& stateIndices, std::vector& lowlinks, std::vector& tarjanStack, storm::storage::BitVector& tarjanStackStates, storm::storage::BitVector& visitedStates, storm::storage::SparseMatrix const& matrix, std::vector>& stronglyConnectedComponents) { - // Create the stacks needed for turning the recursive formulation of Tarjan's algorithm - // into an iterative version. In particular, we keep one stack for states and one stack - // for the iterators. The last one is not strictly needed, but reduces iteration work when - // all successors of a particular state are considered. - std::vector recursionStateStack; - recursionStateStack.reserve(lowlinks.size()); - std::vector::ConstIndexIterator> recursionIteratorStack; - recursionIteratorStack.reserve(lowlinks.size()); - std::vector statesInStack(lowlinks.size()); - - // Initialize the recursion stacks with the given initial state (and its successor iterator). - recursionStateStack.push_back(startState); - recursionIteratorStack.push_back(matrix.constColumnIteratorBegin(startState)); - - recursionStepForward: - while (!recursionStateStack.empty()) { - uint_fast64_t currentState = recursionStateStack.back(); - typename storm::storage::SparseMatrix::ConstIndexIterator currentIt = recursionIteratorStack.back(); - - // Perform the treatment of newly discovered state as defined by Tarjan's algorithm - visitedStates.set(currentState, true); - stateIndices[currentState] = currentIndex; - lowlinks[currentState] = currentIndex; - ++currentIndex; - tarjanStack.push_back(currentState); - tarjanStackStates.set(currentState, true); - - // Now, traverse all successors of the current state. - for(; currentIt != matrix.constColumnIteratorEnd(currentState); ++currentIt) { - // If we have not visited the successor already, we need to perform the procedure - // recursively on the newly found state. - if (!visitedStates.get(*currentIt)) { - // Save current iterator position so we can continue where we left off later. - recursionIteratorStack.pop_back(); - recursionIteratorStack.push_back(currentIt); - - // Put unvisited successor on top of our recursion stack and remember that. - recursionStateStack.push_back(*currentIt); - statesInStack[*currentIt] = true; - - // Also, put initial value for iterator on corresponding recursion stack. - recursionIteratorStack.push_back(matrix.constColumnIteratorBegin(*currentIt)); - - // Perform the actual recursion step in an iterative way. - goto recursionStepForward; - - recursionStepBackward: - lowlinks[currentState] = std::min(lowlinks[currentState], lowlinks[*currentIt]); - } else if (tarjanStackStates.get(*currentIt)) { - // Update the lowlink of the current state. - lowlinks[currentState] = std::min(lowlinks[currentState], stateIndices[*currentIt]); - } - } - - // If the current state is the root of a SCC, we need to pop all states of the SCC from - // the algorithm's stack. - if (lowlinks[currentState] == stateIndices[currentState]) { - stronglyConnectedComponents.push_back(std::vector()); - - uint_fast64_t lastState = 0; - do { - // Pop topmost state from the algorithm's stack. - lastState = tarjanStack.back(); - tarjanStack.pop_back(); - tarjanStackStates.set(lastState, false); - - // Add the state to the current SCC. - stronglyConnectedComponents.back().push_back(lastState); - } while (lastState != currentState); - } - - // If we reach this point, we have completed the recursive descent for the current state. - // That is, we need to pop it from the recursion stacks. - recursionStateStack.pop_back(); - recursionIteratorStack.pop_back(); - - // If there is at least one state under the current one in our recursion stack, we need - // to restore the topmost state as the current state and jump to the part after the - // original recursive call. - if (recursionStateStack.size() > 0) { - currentState = recursionStateStack.back(); - currentIt = recursionIteratorStack.back(); - - goto recursionStepBackward; - } - } - } -}; + +} // namespace graph } // namespace utility } // namespace storm -#endif /* STORM_UTILITY_GRAPHANALYZER_H_ */ +#endif /* STORM_UTILITY_GRAPH_H_ */ diff --git a/test/performance/graph/GraphTest.cpp b/test/performance/graph/GraphTest.cpp index 84f264004..4696ad8e5 100644 --- a/test/performance/graph/GraphTest.cpp +++ b/test/performance/graph/GraphTest.cpp @@ -2,25 +2,25 @@ #include "storm-config.h" #include "src/utility/Settings.h" #include "src/parser/AutoParser.h" -#include "src/utility/GraphAnalyzer.h" +#include "src/utility/graph.h" -TEST(GraphAnalyzerTest, PerformProb01) { +TEST(GraphTest, PerformProb01) { storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", ""); std::shared_ptr> dtmc = parser.getModel>(); LOG4CPLUS_WARN(logger, "Computing prob01 (3 times) for crowds/crowds20_5..."); - std::pair prob01 = storm::utility::GraphAnalyzer::performProb01(*dtmc, storm::storage::BitVector(dtmc->getNumberOfStates(), true), storm::storage::BitVector(dtmc->getLabeledStates("observe0Greater1"))); + std::pair prob01 = storm::utility::graph::performProb01(*dtmc, storm::storage::BitVector(dtmc->getNumberOfStates(), true), storm::storage::BitVector(dtmc->getLabeledStates("observe0Greater1"))); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 1724414u); ASSERT_EQ(prob01.second.getNumberOfSetBits(), 46046u); - prob01 = storm::utility::GraphAnalyzer::performProb01(*dtmc, storm::storage::BitVector(dtmc->getNumberOfStates(), true), storm::storage::BitVector(dtmc->getLabeledStates("observeIGreater1"))); + prob01 = storm::utility::graph::performProb01(*dtmc, storm::storage::BitVector(dtmc->getNumberOfStates(), true), storm::storage::BitVector(dtmc->getLabeledStates("observeIGreater1"))); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 574016u); ASSERT_EQ(prob01.second.getNumberOfSetBits(), 825797u); - prob01 = storm::utility::GraphAnalyzer::performProb01(*dtmc, storm::storage::BitVector(dtmc->getNumberOfStates(), true), storm::storage::BitVector(dtmc->getLabeledStates("observeOnlyTrueSender"))); + prob01 = storm::utility::graph::performProb01(*dtmc, storm::storage::BitVector(dtmc->getNumberOfStates(), true), storm::storage::BitVector(dtmc->getLabeledStates("observeOnlyTrueSender"))); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 1785309u); ASSERT_EQ(prob01.second.getNumberOfSetBits(), 40992u); @@ -28,12 +28,12 @@ TEST(GraphAnalyzerTest, PerformProb01) { dtmc = nullptr; - storm::parser::AutoParser parser2(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.pick.trans.rew"); + storm::parser::AutoParser parser2(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", ""); std::shared_ptr> dtmc2 = parser2.getModel>(); LOG4CPLUS_WARN(logger, "Computing prob01 for synchronous_leader/leader6_8..."); - prob01 = storm::utility::GraphAnalyzer::performProb01(*dtmc2, storm::storage::BitVector(dtmc2->getNumberOfStates(), true), storm::storage::BitVector(dtmc2->getLabeledStates("elected"))); + prob01 = storm::utility::graph::performProb01(*dtmc2, storm::storage::BitVector(dtmc2->getNumberOfStates(), true), storm::storage::BitVector(dtmc2->getLabeledStates("elected"))); LOG4CPLUS_WARN(logger, "Done."); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); @@ -42,19 +42,19 @@ TEST(GraphAnalyzerTest, PerformProb01) { dtmc2 = nullptr; } -TEST(GraphAnalyzerTest, PerformProb01MinMax) { - storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.trans.rew"); +TEST(GraphTest, PerformProb01MinMax) { + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", ""); std::shared_ptr> mdp = parser.getModel>(); LOG4CPLUS_WARN(logger, "Computing prob01min for asynchronous_leader/leader7..."); - std::pair prob01 = storm::utility::GraphAnalyzer::performProb01Min(*mdp, storm::storage::BitVector(mdp->getNumberOfStates(), true), mdp->getLabeledStates("elected")); + std::pair prob01 = storm::utility::graph::performProb01Min(*mdp, storm::storage::BitVector(mdp->getNumberOfStates(), true), mdp->getLabeledStates("elected")); LOG4CPLUS_WARN(logger, "Done."); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); ASSERT_EQ(prob01.second.getNumberOfSetBits(), 2095783u); LOG4CPLUS_WARN(logger, "Computing prob01max for asynchronous_leader/leader7..."); - prob01 = storm::utility::GraphAnalyzer::performProb01Max(*mdp, storm::storage::BitVector(mdp->getNumberOfStates(), true), mdp->getLabeledStates("elected")); + prob01 = storm::utility::graph::performProb01Max(*mdp, storm::storage::BitVector(mdp->getNumberOfStates(), true), mdp->getLabeledStates("elected")); LOG4CPLUS_WARN(logger, "Done."); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); @@ -62,18 +62,18 @@ TEST(GraphAnalyzerTest, PerformProb01MinMax) { mdp = nullptr; - storm::parser::AutoParser parser2(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", ""); + storm::parser::AutoParser parser2(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", "", ""); std::shared_ptr> mdp2 = parser2.getModel>(); LOG4CPLUS_WARN(logger, "Computing prob01min for consensus/coin4_6..."); - prob01 = storm::utility::GraphAnalyzer::performProb01Min(*mdp2, storm::storage::BitVector(mdp2->getNumberOfStates(), true), mdp2->getLabeledStates("finished")); + prob01 = storm::utility::graph::performProb01Min(*mdp2, storm::storage::BitVector(mdp2->getNumberOfStates(), true), mdp2->getLabeledStates("finished")); LOG4CPLUS_WARN(logger, "Done."); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); ASSERT_EQ(prob01.second.getNumberOfSetBits(), 63616u); LOG4CPLUS_WARN(logger, "Computing prob01max for consensus/coin4_6..."); - prob01 = storm::utility::GraphAnalyzer::performProb01Max(*mdp2, storm::storage::BitVector(mdp2->getNumberOfStates(), true), mdp2->getLabeledStates("finished")); + prob01 = storm::utility::graph::performProb01Max(*mdp2, storm::storage::BitVector(mdp2->getNumberOfStates(), true), mdp2->getLabeledStates("finished")); LOG4CPLUS_WARN(logger, "Done."); ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u); @@ -82,12 +82,12 @@ TEST(GraphAnalyzerTest, PerformProb01MinMax) { mdp2 = nullptr; } -TEST(GraphAnalyzerTest, PerformSCCDecompositionAndGetDependencyGraph) { +TEST(GraphTest, PerformSCCDecompositionAndGetDependencyGraph) { storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", ""); std::shared_ptr> dtmc = parser.getModel>(); LOG4CPLUS_WARN(logger, "Computing SCC decomposition of crowds/crowds20_5..."); - std::vector> sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*dtmc); + std::vector> sccDecomposition = storm::utility::graph::performSccDecomposition(*dtmc); LOG4CPLUS_WARN(logger, "Done."); ASSERT_EQ(sccDecomposition.size(), 1290297u); @@ -100,11 +100,11 @@ TEST(GraphAnalyzerTest, PerformSCCDecompositionAndGetDependencyGraph) { dtmc = nullptr; - storm::parser::AutoParser parser2(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.pick.trans.rew"); + storm::parser::AutoParser parser2(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", ""); std::shared_ptr> dtmc2 = parser2.getModel>(); LOG4CPLUS_WARN(logger, "Computing SCC decomposition of synchronous_leader/leader6_8..."); - sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*dtmc2); + sccDecomposition = storm::utility::graph::performSccDecomposition(*dtmc2); LOG4CPLUS_WARN(logger, "Done."); ASSERT_EQ(sccDecomposition.size(), 1279673u); @@ -117,30 +117,28 @@ TEST(GraphAnalyzerTest, PerformSCCDecompositionAndGetDependencyGraph) { dtmc2 = nullptr; - /* - storm::parser::AutoParser parser3(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.trans.rew"); + storm::parser::AutoParser parser3(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader6.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader6.lab", "", ""); std::shared_ptr> mdp = parser3.getModel>(); - LOG4CPLUS_WARN(logger, "Computing SCC decomposition of asynchronous_leader/leader7..."); - sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*mdp); + LOG4CPLUS_WARN(logger, "Computing SCC decomposition of asynchronous_leader/leader6..."); + sccDecomposition = storm::utility::graph::performSccDecomposition(*mdp); LOG4CPLUS_WARN(logger, "Done."); - ASSERT_EQ(sccDecomposition.size(), 1914691u); + ASSERT_EQ(sccDecomposition.size(), 214675); - LOG4CPLUS_WARN(logger, "Extracting SCC dependency graph of asynchronous_leader/leader7..."); + LOG4CPLUS_WARN(logger, "Extracting SCC dependency graph of asynchronous_leader/leader6..."); sccDependencyGraph = mdp->extractSccDependencyGraph(sccDecomposition); LOG4CPLUS_WARN(logger, "Done."); - ASSERT_EQ(sccDependencyGraph.getNonZeroEntryCount(), 7023587u); + ASSERT_EQ(sccDependencyGraph.getNonZeroEntryCount(), 684093u); mdp = nullptr; - */ - storm::parser::AutoParser parser4(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", ""); + storm::parser::AutoParser parser4(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", "", ""); std::shared_ptr> mdp2 = parser4.getModel>(); LOG4CPLUS_WARN(logger, "Computing SCC decomposition of consensus/coin4_6..."); - sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*mdp2); + sccDecomposition = storm::utility::graph::performSccDecomposition(*mdp2); LOG4CPLUS_WARN(logger, "Done."); ASSERT_EQ(sccDecomposition.size(), 63611u); diff --git a/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp index cf8e91581..971c7ec09 100644 --- a/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp @@ -110,7 +110,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { storm::settings::Settings* s = storm::settings::instance(); s->set("maxiter", 20000); - std::cout << s->get("maxiter") << std::endl; + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", ""); ASSERT_EQ(parser.getType(), storm::models::MDP); @@ -149,7 +149,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[31168] - 0.4370098591707694546393), s->get("precision")); + ASSERT_LT(std::abs((*result)[31168] - 0.43742828319177884388579), s->get("precision")); delete probFormula; delete result; From 16f33d8bcad2acc1c72ae1870ace9e4a0fe9dfcc Mon Sep 17 00:00:00 2001 From: gereon Date: Fri, 17 May 2013 17:01:09 +0200 Subject: [PATCH 137/152] Changed error messages for stat() and open() --- src/parser/Parser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp index 3a824dd58..cef51c7dd 100644 --- a/src/parser/Parser.cpp +++ b/src/parser/Parser.cpp @@ -76,14 +76,14 @@ storm::parser::MappedFile::MappedFile(const char* filename) { #else if (stat64(filename, &(this->st)) != 0) { #endif - LOG4CPLUS_ERROR(logger, "Error in stat(" << filename << "): " << std::strerror(errno)); - throw exceptions::FileIoException() << "storm::parser::MappedFile Error in stat(): " << std::strerror(errno); + LOG4CPLUS_ERROR(logger, "Error in stat(" << filename << "): Probably, this file does not exist."); + throw exceptions::FileIoException() << "storm::parser::MappedFile Error in stat(): Probably, this file does not exist."; } this->file = open(filename, O_RDONLY); if (this->file < 0) { - LOG4CPLUS_ERROR(logger, "Error in open(" << filename << "): " << std::strerror(errno)); - throw exceptions::FileIoException() << "storm::parser::MappedFile Error in open(): " << std::strerror(errno); + LOG4CPLUS_ERROR(logger, "Error in open(" << filename << "): Probably, we may not read this file."); + throw exceptions::FileIoException() << "storm::parser::MappedFile Error in open(): Probably, we may not read this file."; } this->data = reinterpret_cast(mmap(NULL, this->st.st_size, PROT_READ, MAP_PRIVATE, this->file, 0)); From 91f20b8bf22fb1642bddb296eb0d3eddefa4431e Mon Sep 17 00:00:00 2001 From: gereon Date: Fri, 17 May 2013 17:03:44 +0200 Subject: [PATCH 138/152] Also added messages for windows code. --- src/parser/Parser.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp index cef51c7dd..a58796982 100644 --- a/src/parser/Parser.cpp +++ b/src/parser/Parser.cpp @@ -99,21 +99,21 @@ storm::parser::MappedFile::MappedFile(const char* filename) { * _stat64(), CreateFile(), CreateFileMapping(), MapViewOfFile() */ if (_stat64(filename, &(this->st)) != 0) { - LOG4CPLUS_ERROR(logger, "Error in _stat(" << filename << ")."); - throw exceptions::FileIoException("storm::parser::MappedFile Error in stat()"); + LOG4CPLUS_ERROR(logger, "Error in _stat(" << filename << "): Probably, this file does not exist."); + throw exceptions::FileIoException("storm::parser::MappedFile Error in stat(): Probably, this file does not exist."); } this->file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (this->file == INVALID_HANDLE_VALUE) { - LOG4CPLUS_ERROR(logger, "Error in CreateFileA(" << filename << ")."); - throw exceptions::FileIoException("storm::parser::MappedFile Error in CreateFileA()"); + LOG4CPLUS_ERROR(logger, "Error in CreateFileA(" << filename << "): Probably, we may not read this file."); + throw exceptions::FileIoException("storm::parser::MappedFile Error in CreateFileA(): Probably, we may not read this file."); } this->mapping = CreateFileMappingA(this->file, NULL, PAGE_READONLY, (DWORD)(st.st_size >> 32), (DWORD)st.st_size, NULL); if (this->mapping == NULL) { CloseHandle(this->file); LOG4CPLUS_ERROR(logger, "Error in CreateFileMappingA(" << filename << ")."); - throw exceptions::FileIoException("storm::parser::MappedFile Error in CreateFileMappingA()"); + throw exceptions::FileIoException("storm::parser::MappedFile Error in CreateFileMappingA()."); } this->data = static_cast(MapViewOfFile(this->mapping, FILE_MAP_READ, 0, 0, this->st.st_size)); @@ -121,7 +121,7 @@ storm::parser::MappedFile::MappedFile(const char* filename) { CloseHandle(this->mapping); CloseHandle(this->file); LOG4CPLUS_ERROR(logger, "Error in MapViewOfFile(" << filename << ")."); - throw exceptions::FileIoException("storm::parser::MappedFile Error in MapViewOfFile()"); + throw exceptions::FileIoException("storm::parser::MappedFile Error in MapViewOfFile()."); } this->dataend = this->data + this->st.st_size; #endif From 02cc7065258fbd0eef547e886583ebf47ffbd15a Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 20 May 2013 21:30:47 +0200 Subject: [PATCH 139/152] Added cudd-2.5.0 patched for Win32/Win64 incl. static lib builds for MSVC2012 --- .../cudd-2.5.0/CUDD_Win32/CUDD_Win32.sln | 26 + .../CUDD_Win32/CUDD_Win32/CUDD_Win32.vcxproj | 256 + .../CUDD_Win32/CUDD_Win32.vcxproj.filters | 360 + .../CUDD_Win32/CUDD_Win32/ReadMe.txt | 29 + .../CUDD_Win32/CUDD_Win32/cudd/Makefile | 124 + .../CUDD_Win32/CUDD_Win32/cudd/cuddAPI.c | 4893 +++++ .../CUDD_Win32/CUDD_Win32/cudd/cuddAddAbs.c | 579 + .../CUDD_Win32/CUDD_Win32/cudd/cuddAddApply.c | 1121 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddAddFind.c | 316 + .../CUDD_Win32/CUDD_Win32/cudd/cuddAddInv.c | 201 + .../CUDD_Win32/CUDD_Win32/cudd/cuddAddIte.c | 639 + .../CUDD_Win32/CUDD_Win32/cudd/cuddAddNeg.c | 290 + .../CUDD_Win32/CUDD_Win32/cudd/cuddAddWalsh.c | 391 + .../CUDD_Win32/CUDD_Win32/cudd/cuddAndAbs.c | 373 + .../CUDD_Win32/CUDD_Win32/cudd/cuddAnneal.c | 814 + .../CUDD_Win32/CUDD_Win32/cudd/cuddApa.c | 979 + .../CUDD_Win32/CUDD_Win32/cudd/cuddApprox.c | 2204 +++ .../CUDD_Win32/CUDD_Win32/cudd/cuddBddAbs.c | 760 + .../CUDD_Win32/CUDD_Win32/cudd/cuddBddCorr.c | 515 + .../CUDD_Win32/CUDD_Win32/cudd/cuddBddIte.c | 1430 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddBridge.c | 1016 + .../CUDD_Win32/CUDD_Win32/cudd/cuddCache.c | 1053 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddCheck.c | 885 + .../CUDD_Win32/CUDD_Win32/cudd/cuddClip.c | 558 + .../CUDD_Win32/CUDD_Win32/cudd/cuddCof.c | 327 + .../CUDD_Win32/CUDD_Win32/cudd/cuddCompose.c | 1749 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddDecomp.c | 2177 +++ .../CUDD_Win32/CUDD_Win32/cudd/cuddEssent.c | 1467 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddExact.c | 1020 + .../CUDD_Win32/CUDD_Win32/cudd/cuddExport.c | 1389 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddGenCof.c | 2178 +++ .../CUDD_Win32/CUDD_Win32/cudd/cuddGenetic.c | 960 + .../CUDD_Win32/CUDD_Win32/cudd/cuddGroup.c | 2188 +++ .../CUDD_Win32/CUDD_Win32/cudd/cuddHarwell.c | 568 + .../CUDD_Win32/CUDD_Win32/cudd/cuddInit.c | 308 + .../CUDD_Win32/CUDD_Win32/cudd/cuddInteract.c | 432 + .../CUDD_Win32/CUDD_Win32/cudd/cuddLCache.c | 1557 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddLevelQ.c | 583 + .../CUDD_Win32/CUDD_Win32/cudd/cuddLinear.c | 1365 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddLiteral.c | 264 + .../CUDD_Win32/CUDD_Win32/cudd/cuddMatMult.c | 707 + .../CUDD_Win32/CUDD_Win32/cudd/cuddPriority.c | 2027 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddRead.c | 517 + .../CUDD_Win32/CUDD_Win32/cudd/cuddRef.c | 808 + .../CUDD_Win32/CUDD_Win32/cudd/cuddReorder.c | 2137 +++ .../CUDD_Win32/CUDD_Win32/cudd/cuddSat.c | 1774 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddSign.c | 318 + .../CUDD_Win32/CUDD_Win32/cudd/cuddSolve.c | 366 + .../CUDD_Win32/CUDD_Win32/cudd/cuddSplit.c | 686 + .../CUDD_Win32/CUDD_Win32/cudd/cuddSubsetHB.c | 1331 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddSubsetSP.c | 1660 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddSymmetry.c | 1707 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddTable.c | 3213 ++++ .../CUDD_Win32/CUDD_Win32/cudd/cuddUtil.c | 4032 ++++ .../CUDD_Win32/CUDD_Win32/cudd/cuddWindow.c | 1023 + .../CUDD_Win32/CUDD_Win32/cudd/cuddZddCount.c | 357 + .../CUDD_Win32/CUDD_Win32/cudd/cuddZddFuncs.c | 1630 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddZddGroup.c | 1340 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddZddIsop.c | 912 + .../CUDD_Win32/CUDD_Win32/cudd/cuddZddLin.c | 971 + .../CUDD_Win32/CUDD_Win32/cudd/cuddZddMisc.c | 278 + .../CUDD_Win32/CUDD_Win32/cudd/cuddZddPort.c | 381 + .../CUDD_Win32/CUDD_Win32/cudd/cuddZddReord.c | 1664 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddZddSetop.c | 1166 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddZddSymm.c | 1711 ++ .../CUDD_Win32/CUDD_Win32/cudd/cuddZddUtil.c | 1205 ++ .../CUDD_Win32/CUDD_Win32/cudd/doc/cudd.doc | 6776 +++++++ .../CUDD_Win32/CUDD_Win32/cudd/doc/cudd.ps | 5036 +++++ .../CUDD_Win32/cudd/doc/cuddAllAbs.html | 3114 +++ .../CUDD_Win32/cudd/doc/cuddAllByFile.html | 13 + .../CUDD_Win32/cudd/doc/cuddAllByFunc.html | 13 + .../CUDD_Win32/cudd/doc/cuddAllDet.html | 15754 ++++++++++++++++ .../CUDD_Win32/cudd/doc/cuddAllFile.html | 4876 +++++ .../CUDD_Win32/cudd/doc/cuddDesc.html | 33 + .../CUDD_Win32/cudd/doc/cuddExt.html | 14 + .../CUDD_Win32/cudd/doc/cuddExtAbs.html | 1415 ++ .../CUDD_Win32/cudd/doc/cuddExtDet.html | 4450 +++++ .../CUDD_Win32/cudd/doc/cuddIntro.css | 30 + .../CUDD_Win32/cudd/doc/cuddIntro.html | 219 + .../CUDD_Win32/cudd/doc/cuddTitle.html | 18 + .../CUDD_Win32/cudd/doc/footnode.html | 109 + .../CUDD_Win32/cudd/doc/icons/blueball.png | Bin 0 -> 333 bytes .../CUDD_Win32/cudd/doc/icons/ch_beg_r.png | Bin 0 -> 165 bytes .../CUDD_Win32/cudd/doc/icons/ch_begin.png | Bin 0 -> 174 bytes .../CUDD_Win32/cudd/doc/icons/ch_del_r.png | Bin 0 -> 288 bytes .../CUDD_Win32/cudd/doc/icons/ch_delet.png | Bin 0 -> 288 bytes .../CUDD_Win32/cudd/doc/icons/ch_end.png | Bin 0 -> 171 bytes .../CUDD_Win32/cudd/doc/icons/ch_end_r.png | Bin 0 -> 155 bytes .../CUDD_Win32/cudd/doc/icons/contents.png | Bin 0 -> 278 bytes .../CUDD_Win32/cudd/doc/icons/crossref.png | Bin 0 -> 147 bytes .../CUDD_Win32/cudd/doc/icons/footnote.png | Bin 0 -> 190 bytes .../CUDD_Win32/cudd/doc/icons/greenball.png | Bin 0 -> 333 bytes .../CUDD_Win32/cudd/doc/icons/image.png | Bin 0 -> 244 bytes .../CUDD_Win32/cudd/doc/icons/index.png | Bin 0 -> 246 bytes .../CUDD_Win32/cudd/doc/icons/next.png | Bin 0 -> 245 bytes .../CUDD_Win32/cudd/doc/icons/next_g.png | Bin 0 -> 272 bytes .../CUDD_Win32/cudd/doc/icons/nx_grp.png | Bin 0 -> 314 bytes .../CUDD_Win32/cudd/doc/icons/nx_grp_g.png | Bin 0 -> 386 bytes .../CUDD_Win32/cudd/doc/icons/orangeball.png | Bin 0 -> 333 bytes .../CUDD_Win32/cudd/doc/icons/pinkball.png | Bin 0 -> 332 bytes .../CUDD_Win32/cudd/doc/icons/prev.png | Bin 0 -> 279 bytes .../CUDD_Win32/cudd/doc/icons/prev_g.png | Bin 0 -> 327 bytes .../CUDD_Win32/cudd/doc/icons/purpleball.png | Bin 0 -> 332 bytes .../CUDD_Win32/cudd/doc/icons/pv_grp.png | Bin 0 -> 352 bytes .../CUDD_Win32/cudd/doc/icons/pv_grp_g.png | Bin 0 -> 430 bytes .../CUDD_Win32/cudd/doc/icons/redball.png | Bin 0 -> 332 bytes .../CUDD_Win32/cudd/doc/icons/up.png | Bin 0 -> 211 bytes .../CUDD_Win32/cudd/doc/icons/up_g.png | Bin 0 -> 231 bytes .../CUDD_Win32/cudd/doc/icons/whiteball.png | Bin 0 -> 229 bytes .../CUDD_Win32/cudd/doc/icons/yellowball.png | Bin 0 -> 333 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img1.png | Bin 0 -> 201 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img10.png | Bin 0 -> 211 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img11.png | Bin 0 -> 476 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img12.png | Bin 0 -> 555 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img13.png | Bin 0 -> 560 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img14.png | Bin 0 -> 675 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img15.png | Bin 0 -> 200 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img16.png | Bin 0 -> 223 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img17.png | Bin 0 -> 246 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img18.png | Bin 0 -> 298 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img19.png | Bin 0 -> 409 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img2.png | Bin 0 -> 197 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img20.png | Bin 0 -> 238 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img21.png | Bin 0 -> 614 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img22.png | Bin 0 -> 12605 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img3.png | Bin 0 -> 401 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img4.png | Bin 0 -> 204 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img5.png | Bin 0 -> 315 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img6.png | Bin 0 -> 185 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img7.png | Bin 0 -> 262 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img8.png | Bin 0 -> 220 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/img9.png | Bin 0 -> 215 bytes .../CUDD_Win32/CUDD_Win32/cudd/doc/index.html | 219 + .../CUDD_Win32/CUDD_Win32/cudd/doc/node1.html | 174 + .../CUDD_Win32/CUDD_Win32/cudd/doc/node2.html | 175 + .../CUDD_Win32/CUDD_Win32/cudd/doc/node3.html | 1637 ++ .../CUDD_Win32/CUDD_Win32/cudd/doc/node4.html | 1165 ++ .../CUDD_Win32/CUDD_Win32/cudd/doc/node5.html | 130 + .../CUDD_Win32/CUDD_Win32/cudd/doc/node6.html | 132 + .../CUDD_Win32/CUDD_Win32/cudd/doc/node7.html | 195 + .../CUDD_Win32/CUDD_Win32/cudd/doc/node8.html | 848 + .../CUDD_Win32/CUDD_Win32/cudd/r7x8.1.mat | 53 + .../CUDD_Win32/CUDD_Win32/cudd/r7x8.1.out | 396 + .../CUDD_Win32/CUDD_Win32/cudd/testcudd.c | 1178 ++ .../CUDD_Win32/CUDD_Win32/dddmp/Makefile | 243 + .../CUDD_Win32/CUDD_Win32/dddmp/README.dddmp | 64 + .../CUDD_Win32/dddmp/README.testdddmp | 79 + .../CUDD_Win32/CUDD_Win32/dddmp/RELEASE_NOTES | 60 + .../CUDD_Win32/CUDD_Win32/dddmp/dddmpBinary.c | 343 + .../CUDD_Win32/dddmp/dddmpConvert.c | 180 + .../CUDD_Win32/CUDD_Win32/dddmp/dddmpDbg.c | 166 + .../CUDD_Win32/dddmp/dddmpDdNodeBdd.c | 455 + .../CUDD_Win32/dddmp/dddmpDdNodeCnf.c | 944 + .../CUDD_Win32/CUDD_Win32/dddmp/dddmpLoad.c | 1486 ++ .../CUDD_Win32/dddmp/dddmpLoadCnf.c | 1072 ++ .../CUDD_Win32/dddmp/dddmpNodeAdd.c | 451 + .../CUDD_Win32/dddmp/dddmpNodeBdd.c | 452 + .../CUDD_Win32/dddmp/dddmpNodeCnf.c | 932 + .../CUDD_Win32/dddmp/dddmpStoreAdd.c | 957 + .../CUDD_Win32/dddmp/dddmpStoreBdd.c | 1114 ++ .../CUDD_Win32/dddmp/dddmpStoreCnf.c | 1583 ++ .../CUDD_Win32/dddmp/dddmpStoreMisc.c | 1641 ++ .../CUDD_Win32/CUDD_Win32/dddmp/dddmpUtil.c | 436 + .../CUDD_Win32/dddmp/doc/cmdIndex.html | 9 + .../CUDD_Win32/dddmp/doc/commands.html | 12 + .../CUDD_Win32/dddmp/doc/credit.html | 15 + .../CUDD_Win32/dddmp/doc/dddmp-2.0-A4.ps | 1261 ++ .../CUDD_Win32/dddmp/doc/dddmp-2.0-Letter.ps | 1260 ++ .../CUDD_Win32/dddmp/doc/dddmpAllAbs.html | 483 + .../CUDD_Win32/dddmp/doc/dddmpAllByFile.html | 13 + .../CUDD_Win32/dddmp/doc/dddmpAllByFunc.html | 13 + .../CUDD_Win32/dddmp/doc/dddmpAllDet.html | 3704 ++++ .../CUDD_Win32/dddmp/doc/dddmpAllFile.html | 679 + .../CUDD_Win32/dddmp/doc/dddmpDesc.html | 28 + .../CUDD_Win32/dddmp/doc/dddmpDoc.txt | Bin 0 -> 32768 bytes .../CUDD_Win32/dddmp/doc/dddmpExt.html | 13 + .../CUDD_Win32/dddmp/doc/dddmpExtAbs.html | 91 + .../CUDD_Win32/dddmp/doc/dddmpExtDet.html | 693 + .../CUDD_Win32/dddmp/doc/dddmpTitle.html | 17 + .../CUDD_Win32/dddmp/doc/packages.html | 12 + .../CUDD_Win32/dddmp/doc/pkgIndex.html | 13 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/0.add | 21 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/0.bdd | 19 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/0or1.bdd | 119 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/1.add | 28 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/1.bdd | 110 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/2.bdd | 118 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/2and3.bdd | 76 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/3.bdd | 304 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd | 50 + .../CUDD_Win32/dddmp/exp/4.bdd.bis1 | 50 + .../CUDD_Win32/dddmp/exp/4.bdd.bis2 | 50 + .../CUDD_Win32/dddmp/exp/4.bdd.bis3 | 50 + .../CUDD_Win32/dddmp/exp/4.bdd.bis4 | 50 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/4.cnf | 130 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/4.cnf.bis | 130 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/4.max1 | 125 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/4.max2 | 125 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/4bis.bdd | 47 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/4xor5.bdd | 120 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/5.bdd | 31 + .../CUDD_Win32/dddmp/exp/composeids.txt | 20 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/one.bdd | 13 + .../CUDD_Win32/dddmp/exp/runAllTest.out | 269 + .../CUDD_Win32/dddmp/exp/runAllTest.script | 11 + .../CUDD_Win32/dddmp/exp/s27RP1.bdd | 18 + .../CUDD_Win32/dddmp/exp/s27deltaDddmp1.bdd | 31 + .../dddmp/exp/s27deltaDddmp1.bdd.bis | 31 + .../CUDD_Win32/dddmp/exp/s27deltaDddmp2.bdd | 32 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/test1.out | 44 + .../CUDD_Win32/dddmp/exp/test1.script | 26 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/test2.out | 23 + .../CUDD_Win32/dddmp/exp/test2.script | 30 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/test3.out | 18 + .../CUDD_Win32/dddmp/exp/test3.script | 69 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/test4.out | 24 + .../CUDD_Win32/dddmp/exp/test4.script | 56 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/test5.out | 28 + .../CUDD_Win32/dddmp/exp/test5.script | 42 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/test6.out | 31 + .../CUDD_Win32/dddmp/exp/test6.script | 50 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/test7.out | 102 + .../CUDD_Win32/dddmp/exp/test7.script | 150 + .../CUDD_Win32/dddmp/exp/varauxids.ord | 50 + .../CUDD_Win32/dddmp/exp/varnames.ord | 50 + .../CUDD_Win32/CUDD_Win32/dddmp/exp/zero.bdd | 13 + .../CUDD_Win32/CUDD_Win32/dddmp/testdddmp.c | 2279 +++ .../CUDD_Win32/CUDD_Win32/epd/Makefile | 64 + .../CUDD_Win32/CUDD_Win32/epd/epd.c | 1344 ++ .../CUDD_Win32/CUDD_Win32/include/cudd.h | 1082 ++ .../CUDD_Win32/CUDD_Win32/include/cuddBdd.h | 382 + .../CUDD_Win32/CUDD_Win32/include/cuddInt.h | 1188 ++ .../CUDD_Win32/CUDD_Win32/include/cuddObj.h | 768 + .../CUDD_Win32/CUDD_Win32/include/dddmp.h | 330 + .../CUDD_Win32/CUDD_Win32/include/dddmpInt.h | 216 + .../CUDD_Win32/CUDD_Win32/include/epd.h | 200 + .../CUDD_Win32/CUDD_Win32/include/mnemosyne.h | 73 + .../CUDD_Win32/CUDD_Win32/include/mtr.h | 187 + .../CUDD_Win32/CUDD_Win32/include/mtrInt.h | 92 + .../CUDD_Win32/CUDD_Win32/include/st.h | 232 + .../CUDD_Win32/CUDD_Win32/include/util.h | 204 + .../CUDD_Win32/CUDD_Win32/mnemosyne/Makefile | 53 + .../CUDD_Win32/CUDD_Win32/mnemosyne/README | 39 + .../CUDD_Win32/mnemosyne/mnemalyse.c | 197 + .../CUDD_Win32/mnemosyne/mnemconf.h | 89 + .../CUDD_Win32/mnemosyne/mnemosyne.c | 674 + .../CUDD_Win32/CUDD_Win32/mnemosyne/mtest.c | 38 + .../CUDD_Win32/CUDD_Win32/mtr/Makefile | 96 + .../CUDD_Win32/CUDD_Win32/mtr/Makefile.sis | 83 + .../CUDD_Win32/CUDD_Win32/mtr/doc/mtr.doc | 252 + .../CUDD_Win32/mtr/doc/mtrAllAbs.html | 72 + .../CUDD_Win32/mtr/doc/mtrAllDet.html | 317 + .../CUDD_Win32/mtr/doc/mtrExtAbs.html | 72 + .../CUDD_Win32/mtr/doc/mtrExtDet.html | 324 + .../CUDD_Win32/CUDD_Win32/mtr/mtrBasic.c | 450 + .../CUDD_Win32/CUDD_Win32/mtr/mtrGroup.c | 877 + .../CUDD_Win32/CUDD_Win32/mtr/test.groups | 5 + .../CUDD_Win32/CUDD_Win32/mtr/testmtr.c | 270 + .../CUDD_Win32/CUDD_Win32/sis/Makefile.sis | 97 + .../CUDD_Win32/CUDD_Win32/sis/cuddBddPort.c | 1954 ++ .../CUDD_Win32/CUDD_Win32/sis/cuddPwPt.c | 147 + .../cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/st.c | 554 + .../cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/st.h | 97 + .../CUDD_Win32/CUDD_Win32/st/Makefile | 64 + .../CUDD_Win32/st/doc/stAllAbs.html | 96 + .../CUDD_Win32/st/doc/stAllDet.html | 462 + .../CUDD_Win32/st/doc/stExtAbs.html | 96 + .../CUDD_Win32/st/doc/stExtDet.html | 463 + .../cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/st.c | 1065 ++ .../CUDD_Win32/CUDD_Win32/util/Makefile | 64 + .../CUDD_Win32/CUDD_Win32/util/cpu_stats.c | 89 + .../CUDD_Win32/CUDD_Win32/util/cpu_time.c | 76 + .../CUDD_Win32/CUDD_Win32/util/datalimit.c | 50 + .../CUDD_Win32/CUDD_Win32/util/pathsearch.c | 94 + .../CUDD_Win32/CUDD_Win32/util/pipefork.c | 93 + .../CUDD_Win32/CUDD_Win32/util/prtime.c | 21 + .../CUDD_Win32/CUDD_Win32/util/ptime.c | 9 + .../CUDD_Win32/CUDD_Win32/util/restart.c | 137 + .../CUDD_Win32/CUDD_Win32/util/safe_mem.c | 97 + .../CUDD_Win32/CUDD_Win32/util/saveimage.c | 229 + .../CUDD_Win32/CUDD_Win32/util/state.c | 82 + .../CUDD_Win32/CUDD_Win32/util/strsav.c | 14 + .../CUDD_Win32/CUDD_Win32/util/stub.c | 82 + .../CUDD_Win32/CUDD_Win32/util/test-res.c | 57 + .../CUDD_Win32/CUDD_Win32/util/test-sav.c | 39 + .../CUDD_Win32/CUDD_Win32/util/texpand.c | 57 + 286 files changed, 163329 insertions(+) create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32.sln create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/CUDD_Win32.vcxproj create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/CUDD_Win32.vcxproj.filters create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/ReadMe.txt create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAPI.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddAbs.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddApply.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddFind.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddInv.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddIte.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddNeg.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddWalsh.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAndAbs.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAnneal.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddApa.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddApprox.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBddAbs.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBddCorr.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBddIte.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBridge.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCache.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCheck.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddClip.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCof.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCompose.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddDecomp.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddEssent.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddExact.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddExport.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddGenCof.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddGenetic.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddGroup.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddHarwell.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddInit.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddInteract.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLCache.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLevelQ.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLinear.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLiteral.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddMatMult.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddPriority.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddRead.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddRef.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddReorder.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSat.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSign.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSolve.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSplit.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSubsetHB.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSubsetSP.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSymmetry.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddTable.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddUtil.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddWindow.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddCount.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddFuncs.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddGroup.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddIsop.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddLin.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddMisc.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddPort.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddReord.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddSetop.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddSymm.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddUtil.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cudd.doc create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cudd.ps create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllByFile.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllByFunc.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllFile.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddDesc.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddExt.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddIntro.css create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddIntro.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddTitle.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/footnode.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/blueball.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/ch_beg_r.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/ch_begin.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/ch_del_r.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/ch_delet.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/ch_end.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/ch_end_r.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/contents.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/crossref.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/footnote.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/greenball.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/image.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/index.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/next.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/next_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/nx_grp.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/nx_grp_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/orangeball.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/pinkball.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/prev.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/prev_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/purpleball.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/pv_grp.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/pv_grp_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/redball.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/up.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/up_g.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/whiteball.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/yellowball.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img1.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img10.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img11.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img12.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img13.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img14.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img15.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img16.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img17.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img18.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img19.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img2.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img20.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img21.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img22.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img3.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img4.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img5.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img6.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img7.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img8.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img9.png create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/index.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node1.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node2.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node3.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node4.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node5.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node6.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node7.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node8.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/r7x8.1.mat create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/r7x8.1.out create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/testcudd.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/README.dddmp create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/README.testdddmp create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/RELEASE_NOTES create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpBinary.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpConvert.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpDbg.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpDdNodeBdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpDdNodeCnf.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpLoad.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpLoadCnf.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpNodeAdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpNodeBdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpNodeCnf.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpStoreAdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpStoreBdd.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpStoreCnf.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpStoreMisc.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpUtil.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/cmdIndex.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/commands.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/credit.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmp-2.0-A4.ps create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmp-2.0-Letter.ps create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllByFile.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllByFunc.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllFile.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpDesc.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpDoc.txt create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpExt.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpTitle.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/packages.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/pkgIndex.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/0.add create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/0.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/0or1.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/1.add create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/1.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/2.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/2and3.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/3.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis1 create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis2 create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis3 create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis4 create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.cnf create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.cnf.bis create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.max1 create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.max2 create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4bis.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4xor5.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/5.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/composeids.txt create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/one.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/runAllTest.out create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/runAllTest.script create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27RP1.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27deltaDddmp1.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27deltaDddmp1.bdd.bis create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27deltaDddmp2.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test1.out create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test1.script create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test2.out create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test2.script create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test3.out create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test3.script create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test4.out create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test4.script create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test5.out create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test5.script create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test6.out create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test6.script create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test7.out create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test7.script create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/varauxids.ord create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/varnames.ord create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/zero.bdd create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/testdddmp.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/epd/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/epd/epd.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cudd.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cuddBdd.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cuddInt.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cuddObj.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/dddmp.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/dddmpInt.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/epd.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/mnemosyne.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/mtr.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/mtrInt.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/st.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/util.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/README create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mnemalyse.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mnemconf.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mnemosyne.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mtest.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/Makefile.sis create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtr.doc create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/mtrBasic.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/mtrGroup.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/test.groups create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/testmtr.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/Makefile.sis create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/cuddBddPort.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/cuddPwPt.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/st.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/st.h create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stAllAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stAllDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stExtAbs.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stExtDet.html create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/st.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/Makefile create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/cpu_stats.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/cpu_time.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/datalimit.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/pathsearch.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/pipefork.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/prtime.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/ptime.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/restart.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/safe_mem.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/saveimage.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/state.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/strsav.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/stub.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/test-res.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/test-sav.c create mode 100644 resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/texpand.c diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32.sln b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32.sln new file mode 100644 index 000000000..077eeff78 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CUDD_Win32", "CUDD_Win32\CUDD_Win32.vcxproj", "{DE45D0D3-3A6C-4E62-937B-3447B836F649}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DE45D0D3-3A6C-4E62-937B-3447B836F649}.Debug|Win32.ActiveCfg = Debug|Win32 + {DE45D0D3-3A6C-4E62-937B-3447B836F649}.Debug|Win32.Build.0 = Debug|Win32 + {DE45D0D3-3A6C-4E62-937B-3447B836F649}.Debug|x64.ActiveCfg = Debug|x64 + {DE45D0D3-3A6C-4E62-937B-3447B836F649}.Debug|x64.Build.0 = Debug|x64 + {DE45D0D3-3A6C-4E62-937B-3447B836F649}.Release|Win32.ActiveCfg = Release|Win32 + {DE45D0D3-3A6C-4E62-937B-3447B836F649}.Release|Win32.Build.0 = Release|Win32 + {DE45D0D3-3A6C-4E62-937B-3447B836F649}.Release|x64.ActiveCfg = Release|x64 + {DE45D0D3-3A6C-4E62-937B-3447B836F649}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/CUDD_Win32.vcxproj b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/CUDD_Win32.vcxproj new file mode 100644 index 000000000..b823de3c8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/CUDD_Win32.vcxproj @@ -0,0 +1,256 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {DE45D0D3-3A6C-4E62-937B-3447B836F649} + Win32Proj + CUDD_Win32 + + + + StaticLibrary + true + v110 + Unicode + + + StaticLibrary + true + v110 + Unicode + + + StaticLibrary + false + v110 + true + Unicode + + + StaticLibrary + false + v110 + true + Unicode + + + + + + + + + + + + + + + + + + + C:\CppProjects\mrmc-cpp\resources\3rdparty\cudd-2.5.0\CUDD_Win32\CUDD_Win32\include;$(IncludePath) + + + C:\CppProjects\mrmc-cpp\resources\3rdparty\cudd-2.5.0\CUDD_Win32\CUDD_Win32\include;$(IncludePath) + + + C:\CppProjects\mrmc-cpp\resources\3rdparty\cudd-2.5.0\CUDD_Win32\CUDD_Win32\include;$(IncludePath) + + + C:\CppProjects\mrmc-cpp\resources\3rdparty\cudd-2.5.0\CUDD_Win32\CUDD_Win32\include;$(IncludePath) + + + + + + Level3 + Disabled + WIN32;__STDC__;_DEBUG;_LIB;%(PreprocessorDefinitions) + + + Windows + true + + + + + + + Level3 + Disabled + WIN32;__STDC__;_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions) + + + Windows + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;__STDC__;NDEBUG;_LIB;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;__STDC__;_CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/CUDD_Win32.vcxproj.filters b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/CUDD_Win32.vcxproj.filters new file mode 100644 index 000000000..b29db4168 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/CUDD_Win32.vcxproj.filters @@ -0,0 +1,360 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {20b2b4b8-676f-463a-9010-ab0ffe6cf355} + + + {e76895b6-4751-4c1b-8328-6a316780c71e} + + + {ef169b2b-eaea-43b1-b520-73e91071dc6d} + + + {188d4abd-935c-484d-98a5-18092114bd41} + + + {d1daf0ae-09b7-40c7-8cc5-9b8cd1c27964} + + + {498f6b79-fff1-4fc0-a620-b0cc35849067} + + + {85d6e913-53fd-406b-b270-55bde0faf286} + + + + + + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\CUDD + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\DDMP + + + Source Files\EPD + + + Source Files\MTR + + + Source Files\MTR + + + Source Files\OBJ + + + Source Files\UTIL + + + Source Files\UTIL + + + Source Files\UTIL + + + Source Files\UTIL + + + Source Files\UTIL + + + Source Files\UTIL + + + Source Files\UTIL + + + Source Files\UTIL + + + Source Files\UTIL + + + Source Files\UTIL + + + Source Files\UTIL + + + Source Files\UTIL + + + Source Files\UTIL + + + Source Files\ST + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/ReadMe.txt b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/ReadMe.txt new file mode 100644 index 000000000..e702721e3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/ReadMe.txt @@ -0,0 +1,29 @@ +======================================================================== + STATIC LIBRARY : CUDD_Win32 Project Overview +======================================================================== + +AppWizard has created this CUDD_Win32 library project for you. + +No source files were created as part of your project. + + +CUDD_Win32.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +CUDD_Win32.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/Makefile b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/Makefile new file mode 100644 index 000000000..d76954746 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/Makefile @@ -0,0 +1,124 @@ +# $Id$ +# +# Cudd - DD package +#--------------------------- +.SUFFIXES: .o .c .u + +CC = gcc +RANLIB = ranlib +PURE = +# Define EXE as .exe for MS-DOS and derivatives. +EXE = +#EXE = .exe + +MFLAG = +ICFLAGS = -g +XCFLAGS = -DDD_STATS +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) +#DDDEBUG = -DDD_DEBUG -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_UNIQUE_PROFILE +DDDEBUG = + +LINTFLAGS = -u -n -DDD_STATS -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_DEBUG -DDD_UNIQUE_PROFILE + +# this is to create the lint library +LINTSWITCH = -o + +WHERE = .. + +INCLUDE = $(WHERE)/include + +LIBS = ./libcudd.a $(WHERE)/mtr/libmtr.a \ + $(WHERE)/st/libst.a $(WHERE)/util/libutil.a $(WHERE)/epd/libepd.a + +MNEMLIB = + +BLIBS = -kL. -klcudd -kL$(WHERE)/mtr -klmtr \ + -kL$(WHERE)/st -klst -kL$(WHERE)/util -klutil -kL$(WHERE)/epd -klepd + +LINTLIBS = ./llib-lcudd.ln $(WHERE)/mtr/llib-lmtr.ln \ + $(WHERE)/st/llib-lst.ln $(WHERE)/util/llib-lutil.ln \ + $(WHERE)/epd/llib-lepd.ln + +LDFLAGS = + +# files for the package +P = cudd +PSRC = cuddAPI.c cuddAddAbs.c cuddAddApply.c cuddAddFind.c cuddAddIte.c \ + cuddAddInv.c cuddAddNeg.c cuddAddWalsh.c cuddAndAbs.c \ + cuddAnneal.c cuddApa.c cuddApprox.c cuddBddAbs.c cuddBddCorr.c \ + cuddBddIte.c cuddBridge.c cuddCache.c cuddCheck.c cuddClip.c \ + cuddCof.c cuddCompose.c cuddDecomp.c cuddEssent.c \ + cuddExact.c cuddExport.c cuddGenCof.c cuddGenetic.c \ + cuddGroup.c cuddHarwell.c cuddInit.c cuddInteract.c \ + cuddLCache.c cuddLevelQ.c \ + cuddLinear.c cuddLiteral.c cuddMatMult.c cuddPriority.c \ + cuddRead.c cuddRef.c cuddReorder.c cuddSat.c cuddSign.c \ + cuddSolve.c cuddSplit.c cuddSubsetHB.c cuddSubsetSP.c cuddSymmetry.c \ + cuddTable.c cuddUtil.c cuddWindow.c cuddZddCount.c cuddZddFuncs.c \ + cuddZddGroup.c cuddZddIsop.c cuddZddLin.c cuddZddMisc.c \ + cuddZddPort.c cuddZddReord.c cuddZddSetop.c cuddZddSymm.c \ + cuddZddUtil.c +PHDR = cudd.h cuddInt.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +TARGET = test$(P)$(EXE) +TARGETu = test$(P)-u + +# files for the test program +SRC = test$(P).c +OBJ = $(SRC:.c=.o) +UBJ = $(SRC:.c=.u) + +#------------------------------------------------------ + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PSRC) $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) $(DDDEBUG) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) +$(OBJ): $(PHDR) +$(UBJ): $(PHDR) + +$(TARGET): $(SRC) $(OBJ) $(HDR) $(LIBS) $(MNEMLIB) + $(PURE) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +# optimize (DECstations and Alphas only: uses u-code) +$(TARGETu): $(SRC) $(UBJ) $(HDR) $(LIBS:.a=.b) + $(CC) -O3 -Olimit 1000 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +lintpgm: lint + lint $(LINTFLAGS) -I$(INCLUDE) $(SRC) $(LINTLIBS) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +programs: $(TARGET) $(TARGETu) lintpgm + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \ + *.bak *~ tags .gdb_history *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAPI.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAPI.c new file mode 100644 index 000000000..0985cf13d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAPI.c @@ -0,0 +1,4893 @@ +/**CFile*********************************************************************** + + FileName [cuddAPI.c] + + PackageName [cudd] + + Synopsis [Application interface functions.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_addNewVar() +
                  • Cudd_addNewVarAtLevel() +
                  • Cudd_bddNewVar() +
                  • Cudd_bddNewVarAtLevel() +
                  • Cudd_addIthVar() +
                  • Cudd_bddIthVar() +
                  • Cudd_zddIthVar() +
                  • Cudd_zddVarsFromBddVars() +
                  • Cudd_addConst() +
                  • Cudd_IsNonConstant() +
                  • Cudd_ReadStartTime() +
                  • Cudd_ReadElapsedTime() +
                  • Cudd_SetStartTime() +
                  • Cudd_ResetStartTime() +
                  • Cudd_ReadTimeLimit() +
                  • Cudd_SetTimeLimit() +
                  • Cudd_UpdateTimeLimit() +
                  • Cudd_IncreaseTimeLimit() +
                  • Cudd_UnsetTimeLimit() +
                  • Cudd_TimeLimited() +
                  • Cudd_AutodynEnable() +
                  • Cudd_AutodynDisable() +
                  • Cudd_ReorderingStatus() +
                  • Cudd_AutodynEnableZdd() +
                  • Cudd_AutodynDisableZdd() +
                  • Cudd_ReorderingStatusZdd() +
                  • Cudd_zddRealignmentEnabled() +
                  • Cudd_zddRealignEnable() +
                  • Cudd_zddRealignDisable() +
                  • Cudd_bddRealignmentEnabled() +
                  • Cudd_bddRealignEnable() +
                  • Cudd_bddRealignDisable() +
                  • Cudd_ReadOne() +
                  • Cudd_ReadZddOne() +
                  • Cudd_ReadZero() +
                  • Cudd_ReadLogicZero() +
                  • Cudd_ReadPlusInfinity() +
                  • Cudd_ReadMinusInfinity() +
                  • Cudd_ReadBackground() +
                  • Cudd_SetBackground() +
                  • Cudd_ReadCacheSlots() +
                  • Cudd_ReadCacheUsedSlots() +
                  • Cudd_ReadCacheLookUps() +
                  • Cudd_ReadCacheHits() +
                  • Cudd_ReadMinHit() +
                  • Cudd_SetMinHit() +
                  • Cudd_ReadLooseUpTo() +
                  • Cudd_SetLooseUpTo() +
                  • Cudd_ReadMaxCache() +
                  • Cudd_ReadMaxCacheHard() +
                  • Cudd_SetMaxCacheHard() +
                  • Cudd_ReadSize() +
                  • Cudd_ReadSlots() +
                  • Cudd_ReadUsedSlots() +
                  • Cudd_ExpectedUsedSlots() +
                  • Cudd_ReadKeys() +
                  • Cudd_ReadDead() +
                  • Cudd_ReadMinDead() +
                  • Cudd_ReadReorderings() +
                  • Cudd_ReadMaxReorderings() +
                  • Cudd_SetMaxReorderings() +
                  • Cudd_ReadReorderingTime() +
                  • Cudd_ReadGarbageCollections() +
                  • Cudd_ReadGarbageCollectionTime() +
                  • Cudd_ReadNodesFreed() +
                  • Cudd_ReadNodesDropped() +
                  • Cudd_ReadUniqueLookUps() +
                  • Cudd_ReadUniqueLinks() +
                  • Cudd_ReadSiftMaxVar() +
                  • Cudd_SetSiftMaxVar() +
                  • Cudd_ReadMaxGrowth() +
                  • Cudd_SetMaxGrowth() +
                  • Cudd_ReadMaxGrowthAlternate() +
                  • Cudd_SetMaxGrowthAlternate() +
                  • Cudd_ReadReorderingCycle() +
                  • Cudd_SetReorderingCycle() +
                  • Cudd_ReadTree() +
                  • Cudd_SetTree() +
                  • Cudd_FreeTree() +
                  • Cudd_ReadZddTree() +
                  • Cudd_SetZddTree() +
                  • Cudd_FreeZddTree() +
                  • Cudd_NodeReadIndex() +
                  • Cudd_ReadPerm() +
                  • Cudd_ReadInvPerm() +
                  • Cudd_ReadVars() +
                  • Cudd_ReadEpsilon() +
                  • Cudd_SetEpsilon() +
                  • Cudd_ReadGroupCheck() +
                  • Cudd_SetGroupcheck() +
                  • Cudd_GarbageCollectionEnabled() +
                  • Cudd_EnableGarbageCollection() +
                  • Cudd_DisableGarbageCollection() +
                  • Cudd_DeadAreCounted() +
                  • Cudd_TurnOnCountDead() +
                  • Cudd_TurnOffCountDead() +
                  • Cudd_ReadRecomb() +
                  • Cudd_SetRecomb() +
                  • Cudd_ReadSymmviolation() +
                  • Cudd_SetSymmviolation() +
                  • Cudd_ReadArcviolation() +
                  • Cudd_SetArcviolation() +
                  • Cudd_ReadPopulationSize() +
                  • Cudd_SetPopulationSize() +
                  • Cudd_ReadNumberXovers() +
                  • Cudd_SetNumberXovers() +
                  • Cudd_ReadOrderRandomization() +
                  • Cudd_SetOrderRandomization() +
                  • Cudd_ReadMemoryInUse() +
                  • Cudd_PrintInfo() +
                  • Cudd_ReadPeakNodeCount() +
                  • Cudd_ReadPeakLiveNodeCount() +
                  • Cudd_ReadNodeCount() +
                  • Cudd_zddReadNodeCount() +
                  • Cudd_AddHook() +
                  • Cudd_RemoveHook() +
                  • Cudd_IsInHook() +
                  • Cudd_StdPreReordHook() +
                  • Cudd_StdPostReordHook() +
                  • Cudd_EnableReorderingReporting() +
                  • Cudd_DisableReorderingReporting() +
                  • Cudd_ReorderingReporting() +
                  • Cudd_PrintGroupedOrder() +
                  • Cudd_EnableOrderingMonitoring() +
                  • Cudd_DisableOrderingMonitoring() +
                  • Cudd_OrderingMonitoring() +
                  • Cudd_ReadErrorCode() +
                  • Cudd_ClearErrorCode() +
                  • Cudd_ReadStdout() +
                  • Cudd_SetStdout() +
                  • Cudd_ReadStderr() +
                  • Cudd_SetStderr() +
                  • Cudd_ReadNextReordering() +
                  • Cudd_SetNextReordering() +
                  • Cudd_ReadSwapSteps() +
                  • Cudd_ReadMaxLive() +
                  • Cudd_SetMaxLive() +
                  • Cudd_ReadMaxMemory() +
                  • Cudd_SetMaxMemory() +
                  • Cudd_bddBindVar() +
                  • Cudd_bddUnbindVar() +
                  • Cudd_bddVarIsBound() +
                  • Cudd_bddSetPiVar() +
                  • Cudd_bddSetPsVar() +
                  • Cudd_bddSetNsVar() +
                  • Cudd_bddIsPiVar() +
                  • Cudd_bddIsPsVar() +
                  • Cudd_bddIsNsVar() +
                  • Cudd_bddSetPairIndex() +
                  • Cudd_bddReadPairIndex() +
                  • Cudd_bddSetVarToBeGrouped() +
                  • Cudd_bddSetVarHardGroup() +
                  • Cudd_bddResetVarToBeGrouped() +
                  • Cudd_bddIsVarToBeGrouped() +
                  • Cudd_bddSetVarToBeUngrouped() +
                  • Cudd_bddIsVarToBeUngrouped() +
                  • Cudd_bddIsVarHardGroup() +
                  + Static procedures included in this module: +
                    +
                  • fixVarTree() +
                  ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAPI.c,v 1.64 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void fixVarTree (MtrNode *treenode, int *perm, int size); +static int addMultiplicityGroups (DdManager *dd, MtrNode *treenode, int multiplicity, char *vmask, char *lmask); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns a new ADD variable.] + + Description [Creates a new ADD variable. The new variable has an + index equal to the largest previous index plus 1. Returns a + pointer to the new variable if successful; NULL otherwise. + An ADD variable differs from a BDD variable because it points to the + arithmetic zero, instead of having a complement pointer to 1. ] + + SideEffects [None] + + SeeAlso [Cudd_bddNewVar Cudd_addIthVar Cudd_addConst + Cudd_addNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_addNewVar( + DdManager * dd) +{ + DdNode *res; + + if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); + do { + dd->reordered = 0; + res = cuddUniqueInter(dd,dd->size,DD_ONE(dd),DD_ZERO(dd)); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_addNewVar */ + + +/**Function******************************************************************** + + Synopsis [Returns a new ADD variable at a specified level.] + + Description [Creates a new ADD variable. The new variable has an + index equal to the largest previous index plus 1 and is positioned at + the specified level in the order. Returns a pointer to the new + variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_addNewVarAtLevel( + DdManager * dd, + int level) +{ + DdNode *res; + + if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); + if (level >= dd->size) return(Cudd_addIthVar(dd,level)); + if (!cuddInsertSubtables(dd,1,level)) return(NULL); + do { + dd->reordered = 0; + res = cuddUniqueInter(dd,dd->size - 1,DD_ONE(dd),DD_ZERO(dd)); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_addNewVarAtLevel */ + + +/**Function******************************************************************** + + Synopsis [Returns a new BDD variable.] + + Description [Creates a new BDD variable. The new variable has an + index equal to the largest previous index plus 1. Returns a + pointer to the new variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_bddNewVar( + DdManager * dd) +{ + DdNode *res; + + if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); + res = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); + + return(res); + +} /* end of Cudd_bddNewVar */ + + +/**Function******************************************************************** + + Synopsis [Returns a new BDD variable at a specified level.] + + Description [Creates a new BDD variable. The new variable has an + index equal to the largest previous index plus 1 and is positioned at + the specified level in the order. Returns a pointer to the new + variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNewVar Cudd_bddIthVar Cudd_addNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_bddNewVarAtLevel( + DdManager * dd, + int level) +{ + DdNode *res; + + if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); + if (level >= dd->size) return(Cudd_bddIthVar(dd,level)); + if (!cuddInsertSubtables(dd,1,level)) return(NULL); + res = dd->vars[dd->size - 1]; + + return(res); + +} /* end of Cudd_bddNewVarAtLevel */ + + +/**Function******************************************************************** + + Synopsis [Returns the ADD variable with index i.] + + Description [Retrieves the ADD variable with index i if it already + exists, or creates a new ADD variable. Returns a pointer to the + variable if successful; NULL otherwise. An ADD variable differs from + a BDD variable because it points to the arithmetic zero, instead of + having a complement pointer to 1. ] + + SideEffects [None] + + SeeAlso [Cudd_addNewVar Cudd_bddIthVar Cudd_addConst + Cudd_addNewVarAtLevel] + +******************************************************************************/ +DdNode * +Cudd_addIthVar( + DdManager * dd, + int i) +{ + DdNode *res; + + if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); + do { + dd->reordered = 0; + res = cuddUniqueInter(dd,i,DD_ONE(dd),DD_ZERO(dd)); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_addIthVar */ + + +/**Function******************************************************************** + + Synopsis [Returns the BDD variable with index i.] + + Description [Retrieves the BDD variable with index i if it already + exists, or creates a new BDD variable. Returns a pointer to the + variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel + Cudd_ReadVars] + +******************************************************************************/ +DdNode * +Cudd_bddIthVar( + DdManager * dd, + int i) +{ + DdNode *res; + + if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); + if (i < dd->size) { + res = dd->vars[i]; + } else { + res = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + } + + return(res); + +} /* end of Cudd_bddIthVar */ + + +/**Function******************************************************************** + + Synopsis [Returns the ZDD variable with index i.] + + Description [Retrieves the ZDD variable with index i if it already + exists, or creates a new ZDD variable. Returns a pointer to the + variable if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddIthVar Cudd_addIthVar] + +******************************************************************************/ +DdNode * +Cudd_zddIthVar( + DdManager * dd, + int i) +{ + DdNode *res; + DdNode *zvar; + DdNode *lower; + int j; + + if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); + + /* The i-th variable function has the following structure: + ** at the level corresponding to index i there is a node whose "then" + ** child points to the universe, and whose "else" child points to zero. + ** Above that level there are nodes with identical children. + */ + + /* First we build the node at the level of index i. */ + lower = (i < dd->sizeZ - 1) ? dd->univ[dd->permZ[i]+1] : DD_ONE(dd); + do { + dd->reordered = 0; + zvar = cuddUniqueInterZdd(dd, i, lower, DD_ZERO(dd)); + } while (dd->reordered == 1); + + if (zvar == NULL) + return(NULL); + cuddRef(zvar); + + /* Now we add the "filler" nodes above the level of index i. */ + for (j = dd->permZ[i] - 1; j >= 0; j--) { + do { + dd->reordered = 0; + res = cuddUniqueInterZdd(dd, dd->invpermZ[j], zvar, zvar); + } while (dd->reordered == 1); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd,zvar); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd,zvar); + zvar = res; + } + cuddDeref(zvar); + return(zvar); + +} /* end of Cudd_zddIthVar */ + + +/**Function******************************************************************** + + Synopsis [Creates one or more ZDD variables for each BDD variable.] + + Description [Creates one or more ZDD variables for each BDD + variable. If some ZDD variables already exist, only the missing + variables are created. Parameter multiplicity allows the caller to + control how many variables are created for each BDD variable in + existence. For instance, if ZDDs are used to represent covers, two + ZDD variables are required for each BDD variable. The order of the + BDD variables is transferred to the ZDD variables. If a variable + group tree exists for the BDD variables, a corresponding ZDD + variable group tree is created by expanding the BDD variable + tree. In any case, the ZDD variables derived from the same BDD + variable are merged in a ZDD variable group. If a ZDD variable group + tree exists, it is freed. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel] + +******************************************************************************/ +int +Cudd_zddVarsFromBddVars( + DdManager * dd /* DD manager */, + int multiplicity /* how many ZDD variables are created for each BDD variable */) +{ + int res; + int i, j; + int allnew; + int *permutation; + + if (multiplicity < 1) return(0); + allnew = dd->sizeZ == 0; + if (dd->size * multiplicity > dd->sizeZ) { + res = cuddResizeTableZdd(dd,dd->size * multiplicity - 1); + if (res == 0) return(0); + } + /* Impose the order of the BDD variables to the ZDD variables. */ + if (allnew) { + for (i = 0; i < dd->size; i++) { + for (j = 0; j < multiplicity; j++) { + dd->permZ[i * multiplicity + j] = + dd->perm[i] * multiplicity + j; + dd->invpermZ[dd->permZ[i * multiplicity + j]] = + i * multiplicity + j; + } + } + for (i = 0; i < dd->sizeZ; i++) { + dd->univ[i]->index = dd->invpermZ[i]; + } + } else { + permutation = ALLOC(int,dd->sizeZ); + if (permutation == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < dd->size; i++) { + for (j = 0; j < multiplicity; j++) { + permutation[i * multiplicity + j] = + dd->invperm[i] * multiplicity + j; + } + } + for (i = dd->size * multiplicity; i < dd->sizeZ; i++) { + permutation[i] = i; + } + res = Cudd_zddShuffleHeap(dd, permutation); + FREE(permutation); + if (res == 0) return(0); + } + /* Copy and expand the variable group tree if it exists. */ + if (dd->treeZ != NULL) { + Cudd_FreeZddTree(dd); + } + if (dd->tree != NULL) { + dd->treeZ = Mtr_CopyTree(dd->tree, multiplicity); + if (dd->treeZ == NULL) return(0); + } else if (multiplicity > 1) { + dd->treeZ = Mtr_InitGroupTree(0, dd->sizeZ); + if (dd->treeZ == NULL) return(0); + dd->treeZ->index = dd->invpermZ[0]; + } + /* Create groups for the ZDD variables derived from the same BDD variable. + */ + if (multiplicity > 1) { + char *vmask, *lmask; + + vmask = ALLOC(char, dd->size); + if (vmask == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + lmask = ALLOC(char, dd->size); + if (lmask == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < dd->size; i++) { + vmask[i] = lmask[i] = 0; + } + res = addMultiplicityGroups(dd,dd->treeZ,multiplicity,vmask,lmask); + FREE(vmask); + FREE(lmask); + if (res == 0) return(0); + } + return(1); + +} /* end of Cudd_zddVarsFromBddVars */ + + +/**Function******************************************************************** + + Synopsis [Returns the ADD for constant c.] + + Description [Retrieves the ADD for constant c if it already + exists, or creates a new ADD. Returns a pointer to the + ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNewVar Cudd_addIthVar] + +******************************************************************************/ +DdNode * +Cudd_addConst( + DdManager * dd, + CUDD_VALUE_TYPE c) +{ + return(cuddUniqueConst(dd,c)); + +} /* end of Cudd_addConst */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if a DD node is not constant.] + + Description [Returns 1 if a DD node is not constant. This function is + useful to test the results of Cudd_bddIteConstant, Cudd_addIteConstant, + Cudd_addEvalConst. These results may be a special value signifying + non-constant. In the other cases the macro Cudd_IsConstant can be used.] + + SideEffects [None] + + SeeAlso [Cudd_IsConstant Cudd_bddIteConstant Cudd_addIteConstant + Cudd_addEvalConst] + +******************************************************************************/ +int +Cudd_IsNonConstant( + DdNode *f) +{ + return(f == DD_NON_CONSTANT || !Cudd_IsConstant(f)); + +} /* end of Cudd_IsNonConstant */ + + +/**Function******************************************************************** + + Synopsis [Returns the start time of the manager.] + + Description [Returns the start time of the manager. This is initially set + to the number of milliseconds since the program started, but may be reset by + the application.] + + SideEffects [None] + + SeeAlso [Cudd_SetStartTime Cudd_ResetStartTime Cudd_ReadTimeLimit] + +******************************************************************************/ +unsigned long +Cudd_ReadStartTime( + DdManager * unique) +{ + return unique->startTime; + +} /* end of Cudd_ReadStartTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the time elapsed since the start time of the manager.] + + Description [Returns the time elapsed since the start time of the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadStartTime Cudd_SetStartTime] + +******************************************************************************/ +unsigned long +Cudd_ReadElapsedTime( + DdManager * unique) +{ + return util_cpu_time() - unique->startTime; + +} /* end of Cudd_ReadElapsedTime */ + + +/**Function******************************************************************** + + Synopsis [Sets the start time of the manager.] + + Description [Sets the start time of the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadStartTime Cudd_ResetStartTime Cudd_ReadElapsedTime + Cudd_SetTimeLimit] + +******************************************************************************/ +void +Cudd_SetStartTime( + DdManager * unique, + unsigned long st) +{ + unique->startTime = st; + +} /* end of Cudd_SetStartTime */ + + +/**Function******************************************************************** + + Synopsis [Resets the start time of the manager.] + + Description [Resets the start time of the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadStartTime Cudd_SetStartTime Cudd_SetTimeLimit] + +******************************************************************************/ +void +Cudd_ResetStartTime( + DdManager * unique) +{ + unique->startTime = util_cpu_time(); + +} /* end of Cudd_ResetStartTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the time limit for the manager.] + + Description [Returns the time limit for the manager. This is initially set + to a very large number, but may be reset by the application.] + + SideEffects [None] + + SeeAlso [Cudd_SetTimeLimit Cudd_UpdateTimeLimit Cudd_UnsetTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_ReadStartTime] + +******************************************************************************/ +unsigned long +Cudd_ReadTimeLimit( + DdManager * unique) +{ + return unique->timeLimit; + +} /* end of Cudd_ReadTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Sets the time limit for the manager.] + + Description [Sets the time limit for the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_UnsetTimeLimit Cudd_UpdateTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_SetTimeLimit( + DdManager * unique, + unsigned long tl) +{ + unique->timeLimit = tl; + +} /* end of Cudd_SetTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Updates the time limit for the manager.] + + Description [Updates the time limit for the manager by subtracting the + elapsed time from it.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UnsetTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_UpdateTimeLimit( + DdManager * unique) +{ + unsigned long elapsed; + if (unique->timeLimit == ~0UL) + return; + elapsed = util_cpu_time() - unique->startTime; + if (unique->timeLimit >= elapsed) { + unique->timeLimit -= elapsed; + } else { + unique->timeLimit = 0; + } + +} /* end of Cudd_UpdateTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Increases the time limit for the manager.] + + Description [Increases the time limit for the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UnsetTimeLimit + Cudd_UpdateTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_IncreaseTimeLimit( + DdManager * unique, + unsigned long increase) +{ + if (unique->timeLimit == ~0UL) + unique->timeLimit = increase; + else + unique->timeLimit += increase; + +} /* end of Cudd_IncreaseTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Unsets the time limit for the manager.] + + Description [Unsets the time limit for the manager. Actually, sets it to + a very large value.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UpdateTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_UnsetTimeLimit( + DdManager * unique) +{ + unique->timeLimit = ~0UL; + +} /* end of Cudd_UnsetTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Returns true if the time limit for the manager is set.] + + Description [Returns true if the time limit for the manager is set.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UpdateTimeLimit + Cudd_UnsetTimeLimit Cudd_IncreaseTimeLimit] + +******************************************************************************/ +int +Cudd_TimeLimited( + DdManager * unique) +{ + return unique->timeLimit != ~0UL; + +} /* end of Cudd_TimeLimited */ + + +/**Function******************************************************************** + + Synopsis [Enables automatic dynamic reordering of BDDs and ADDs.] + + Description [Enables automatic dynamic reordering of BDDs and + ADDs. Parameter method is used to determine the method used for + reordering. If CUDD_REORDER_SAME is passed, the method is + unchanged.] + + SideEffects [None] + + SeeAlso [Cudd_AutodynDisable Cudd_ReorderingStatus + Cudd_AutodynEnableZdd] + +******************************************************************************/ +void +Cudd_AutodynEnable( + DdManager * unique, + Cudd_ReorderingType method) +{ + unique->autoDyn = 1; + if (method != CUDD_REORDER_SAME) { + unique->autoMethod = method; + } +#ifndef DD_NO_DEATH_ROW + /* If reordering is enabled, using the death row causes too many + ** invocations. Hence, we shrink the death row to just one entry. + */ + cuddClearDeathRow(unique); + unique->deathRowDepth = 1; + unique->deadMask = unique->deathRowDepth - 1; + if ((unsigned) unique->nextDead > unique->deadMask) { + unique->nextDead = 0; + } + unique->deathRow = REALLOC(DdNodePtr, unique->deathRow, + unique->deathRowDepth); +#endif + return; + +} /* end of Cudd_AutodynEnable */ + + +/**Function******************************************************************** + + Synopsis [Disables automatic dynamic reordering.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_AutodynEnable Cudd_ReorderingStatus + Cudd_AutodynDisableZdd] + +******************************************************************************/ +void +Cudd_AutodynDisable( + DdManager * unique) +{ + unique->autoDyn = 0; + return; + +} /* end of Cudd_AutodynDisable */ + + +/**Function******************************************************************** + + Synopsis [Reports the status of automatic dynamic reordering of BDDs + and ADDs.] + + Description [Reports the status of automatic dynamic reordering of + BDDs and ADDs. Parameter method is set to the reordering method + currently selected. Returns 1 if automatic reordering is enabled; 0 + otherwise.] + + SideEffects [Parameter method is set to the reordering method currently + selected.] + + SeeAlso [Cudd_AutodynEnable Cudd_AutodynDisable + Cudd_ReorderingStatusZdd] + +******************************************************************************/ +int +Cudd_ReorderingStatus( + DdManager * unique, + Cudd_ReorderingType * method) +{ + *method = unique->autoMethod; + return(unique->autoDyn); + +} /* end of Cudd_ReorderingStatus */ + + +/**Function******************************************************************** + + Synopsis [Enables automatic dynamic reordering of ZDDs.] + + Description [Enables automatic dynamic reordering of ZDDs. Parameter + method is used to determine the method used for reordering ZDDs. If + CUDD_REORDER_SAME is passed, the method is unchanged.] + + SideEffects [None] + + SeeAlso [Cudd_AutodynDisableZdd Cudd_ReorderingStatusZdd + Cudd_AutodynEnable] + +******************************************************************************/ +void +Cudd_AutodynEnableZdd( + DdManager * unique, + Cudd_ReorderingType method) +{ + unique->autoDynZ = 1; + if (method != CUDD_REORDER_SAME) { + unique->autoMethodZ = method; + } + return; + +} /* end of Cudd_AutodynEnableZdd */ + + +/**Function******************************************************************** + + Synopsis [Disables automatic dynamic reordering of ZDDs.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_AutodynEnableZdd Cudd_ReorderingStatusZdd + Cudd_AutodynDisable] + +******************************************************************************/ +void +Cudd_AutodynDisableZdd( + DdManager * unique) +{ + unique->autoDynZ = 0; + return; + +} /* end of Cudd_AutodynDisableZdd */ + + +/**Function******************************************************************** + + Synopsis [Reports the status of automatic dynamic reordering of ZDDs.] + + Description [Reports the status of automatic dynamic reordering of + ZDDs. Parameter method is set to the ZDD reordering method currently + selected. Returns 1 if automatic reordering is enabled; 0 + otherwise.] + + SideEffects [Parameter method is set to the ZDD reordering method currently + selected.] + + SeeAlso [Cudd_AutodynEnableZdd Cudd_AutodynDisableZdd + Cudd_ReorderingStatus] + +******************************************************************************/ +int +Cudd_ReorderingStatusZdd( + DdManager * unique, + Cudd_ReorderingType * method) +{ + *method = unique->autoMethodZ; + return(unique->autoDynZ); + +} /* end of Cudd_ReorderingStatusZdd */ + + +/**Function******************************************************************** + + Synopsis [Tells whether the realignment of ZDD order to BDD order is + enabled.] + + Description [Returns 1 if the realignment of ZDD order to BDD order is + enabled; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddRealignEnable Cudd_zddRealignDisable + Cudd_bddRealignEnable Cudd_bddRealignDisable] + +******************************************************************************/ +int +Cudd_zddRealignmentEnabled( + DdManager * unique) +{ + return(unique->realign); + +} /* end of Cudd_zddRealignmentEnabled */ + + +/**Function******************************************************************** + + Synopsis [Enables realignment of ZDD order to BDD order.] + + Description [Enables realignment of the ZDD variable order to the + BDD variable order after the BDDs and ADDs have been reordered. The + number of ZDD variables must be a multiple of the number of BDD + variables for realignment to make sense. If this condition is not met, + Cudd_ReduceHeap will return 0. Let M be the + ratio of the two numbers. For the purpose of realignment, the ZDD + variables from M*i to (M+1)*i-1 are + reagarded as corresponding to BDD variable i. Realignment + is initially disabled.] + + SideEffects [None] + + SeeAlso [Cudd_ReduceHeap Cudd_zddRealignDisable + Cudd_zddRealignmentEnabled Cudd_bddRealignDisable + Cudd_bddRealignmentEnabled] + +******************************************************************************/ +void +Cudd_zddRealignEnable( + DdManager * unique) +{ + unique->realign = 1; + return; + +} /* end of Cudd_zddRealignEnable */ + + +/**Function******************************************************************** + + Synopsis [Disables realignment of ZDD order to BDD order.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddRealignEnable Cudd_zddRealignmentEnabled + Cudd_bddRealignEnable Cudd_bddRealignmentEnabled] + +******************************************************************************/ +void +Cudd_zddRealignDisable( + DdManager * unique) +{ + unique->realign = 0; + return; + +} /* end of Cudd_zddRealignDisable */ + + +/**Function******************************************************************** + + Synopsis [Tells whether the realignment of BDD order to ZDD order is + enabled.] + + Description [Returns 1 if the realignment of BDD order to ZDD order is + enabled; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddRealignEnable Cudd_bddRealignDisable + Cudd_zddRealignEnable Cudd_zddRealignDisable] + +******************************************************************************/ +int +Cudd_bddRealignmentEnabled( + DdManager * unique) +{ + return(unique->realignZ); + +} /* end of Cudd_bddRealignmentEnabled */ + + +/**Function******************************************************************** + + Synopsis [Enables realignment of BDD order to ZDD order.] + + Description [Enables realignment of the BDD variable order to the + ZDD variable order after the ZDDs have been reordered. The + number of ZDD variables must be a multiple of the number of BDD + variables for realignment to make sense. If this condition is not met, + Cudd_zddReduceHeap will return 0. Let M be the + ratio of the two numbers. For the purpose of realignment, the ZDD + variables from M*i to (M+1)*i-1 are + reagarded as corresponding to BDD variable i. Realignment + is initially disabled.] + + SideEffects [None] + + SeeAlso [Cudd_zddReduceHeap Cudd_bddRealignDisable + Cudd_bddRealignmentEnabled Cudd_zddRealignDisable + Cudd_zddRealignmentEnabled] + +******************************************************************************/ +void +Cudd_bddRealignEnable( + DdManager * unique) +{ + unique->realignZ = 1; + return; + +} /* end of Cudd_bddRealignEnable */ + + +/**Function******************************************************************** + + Synopsis [Disables realignment of ZDD order to BDD order.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_bddRealignEnable Cudd_bddRealignmentEnabled + Cudd_zddRealignEnable Cudd_zddRealignmentEnabled] + +******************************************************************************/ +void +Cudd_bddRealignDisable( + DdManager * unique) +{ + unique->realignZ = 0; + return; + +} /* end of Cudd_bddRealignDisable */ + + +/**Function******************************************************************** + + Synopsis [Returns the one constant of the manager.] + + Description [Returns the one constant of the manager. The one + constant is common to ADDs and BDDs.] + + SideEffects [None] + + SeeAlso [Cudd_ReadZero Cudd_ReadLogicZero Cudd_ReadZddOne] + +******************************************************************************/ +DdNode * +Cudd_ReadOne( + DdManager * dd) +{ + return(dd->one); + +} /* end of Cudd_ReadOne */ + + +/**Function******************************************************************** + + Synopsis [Returns the ZDD for the constant 1 function.] + + Description [Returns the ZDD for the constant 1 function. + The representation of the constant 1 function as a ZDD depends on + how many variables it (nominally) depends on. The index of the + topmost variable in the support is given as argument i.] + + SideEffects [None] + + SeeAlso [Cudd_ReadOne] + +******************************************************************************/ +DdNode * +Cudd_ReadZddOne( + DdManager * dd, + int i) +{ + if (i < 0) + return(NULL); + return(i < dd->sizeZ ? dd->univ[i] : DD_ONE(dd)); + +} /* end of Cudd_ReadZddOne */ + + + +/**Function******************************************************************** + + Synopsis [Returns the zero constant of the manager.] + + Description [Returns the zero constant of the manager. The zero + constant is the arithmetic zero, rather than the logic zero. The + latter is the complement of the one constant.] + + SideEffects [None] + + SeeAlso [Cudd_ReadOne Cudd_ReadLogicZero] + +******************************************************************************/ +DdNode * +Cudd_ReadZero( + DdManager * dd) +{ + return(DD_ZERO(dd)); + +} /* end of Cudd_ReadZero */ + + +/**Function******************************************************************** + + Synopsis [Returns the logic zero constant of the manager.] + + Description [Returns the zero constant of the manager. The logic zero + constant is the complement of the one constant, and is distinct from + the arithmetic zero.] + + SideEffects [None] + + SeeAlso [Cudd_ReadOne Cudd_ReadZero] + +******************************************************************************/ +DdNode * +Cudd_ReadLogicZero( + DdManager * dd) +{ + return(Cudd_Not(DD_ONE(dd))); + +} /* end of Cudd_ReadLogicZero */ + + +/**Function******************************************************************** + + Synopsis [Reads the plus-infinity constant from the manager.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_ReadPlusInfinity( + DdManager * dd) +{ + return(dd->plusinfinity); + +} /* end of Cudd_ReadPlusInfinity */ + + +/**Function******************************************************************** + + Synopsis [Reads the minus-infinity constant from the manager.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_ReadMinusInfinity( + DdManager * dd) +{ + return(dd->minusinfinity); + +} /* end of Cudd_ReadMinusInfinity */ + + +/**Function******************************************************************** + + Synopsis [Reads the background constant of the manager.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_ReadBackground( + DdManager * dd) +{ + return(dd->background); + +} /* end of Cudd_ReadBackground */ + + +/**Function******************************************************************** + + Synopsis [Sets the background constant of the manager.] + + Description [Sets the background constant of the manager. It assumes + that the DdNode pointer bck is already referenced.] + + SideEffects [None] + +******************************************************************************/ +void +Cudd_SetBackground( + DdManager * dd, + DdNode * bck) +{ + dd->background = bck; + +} /* end of Cudd_SetBackground */ + + +/**Function******************************************************************** + + Synopsis [Reads the number of slots in the cache.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadCacheUsedSlots] + +******************************************************************************/ +unsigned int +Cudd_ReadCacheSlots( + DdManager * dd) +{ + return(dd->cacheSlots); + +} /* end of Cudd_ReadCacheSlots */ + + +/**Function******************************************************************** + + Synopsis [Reads the fraction of used slots in the cache.] + + Description [Reads the fraction of used slots in the cache. The unused + slots are those in which no valid data is stored. Garbage collection, + variable reordering, and cache resizing may cause used slots to become + unused.] + + SideEffects [None] + + SeeAlso [Cudd_ReadCacheSlots] + +******************************************************************************/ +double +Cudd_ReadCacheUsedSlots( + DdManager * dd) +{ + unsigned long used = 0; + int slots = dd->cacheSlots; + DdCache *cache = dd->cache; + int i; + + for (i = 0; i < slots; i++) { + used += cache[i].h != 0; + } + + return((double)used / (double) dd->cacheSlots); + +} /* end of Cudd_ReadCacheUsedSlots */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of cache look-ups.] + + Description [Returns the number of cache look-ups.] + + SideEffects [None] + + SeeAlso [Cudd_ReadCacheHits] + +******************************************************************************/ +double +Cudd_ReadCacheLookUps( + DdManager * dd) +{ + return(dd->cacheHits + dd->cacheMisses + + dd->totCachehits + dd->totCacheMisses); + +} /* end of Cudd_ReadCacheLookUps */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of cache hits.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadCacheLookUps] + +******************************************************************************/ +double +Cudd_ReadCacheHits( + DdManager * dd) +{ + return(dd->cacheHits + dd->totCachehits); + +} /* end of Cudd_ReadCacheHits */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of recursive calls.] + + Description [Returns the number of recursive calls if the package is + compiled with DD_COUNT defined.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +double +Cudd_ReadRecursiveCalls( + DdManager * dd) +{ +#ifdef DD_COUNT + return(dd->recursiveCalls); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadRecursiveCalls */ + + + +/**Function******************************************************************** + + Synopsis [Reads the hit rate that causes resizinig of the computed + table.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetMinHit] + +******************************************************************************/ +unsigned int +Cudd_ReadMinHit( + DdManager * dd) +{ + /* Internally, the package manipulates the ratio of hits to + ** misses instead of the ratio of hits to accesses. */ + return((unsigned int) (0.5 + 100 * dd->minHit / (1 + dd->minHit))); + +} /* end of Cudd_ReadMinHit */ + + +/**Function******************************************************************** + + Synopsis [Sets the hit rate that causes resizinig of the computed + table.] + + Description [Sets the minHit parameter of the manager. This + parameter controls the resizing of the computed table. If the hit + rate is larger than the specified value, and the cache is not + already too large, then its size is doubled.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMinHit] + +******************************************************************************/ +void +Cudd_SetMinHit( + DdManager * dd, + unsigned int hr) +{ + /* Internally, the package manipulates the ratio of hits to + ** misses instead of the ratio of hits to accesses. */ + dd->minHit = (double) hr / (100.0 - (double) hr); + +} /* end of Cudd_SetMinHit */ + + +/**Function******************************************************************** + + Synopsis [Reads the looseUpTo parameter of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetLooseUpTo Cudd_ReadMinHit Cudd_ReadMinDead] + +******************************************************************************/ +unsigned int +Cudd_ReadLooseUpTo( + DdManager * dd) +{ + return(dd->looseUpTo); + +} /* end of Cudd_ReadLooseUpTo */ + + +/**Function******************************************************************** + + Synopsis [Sets the looseUpTo parameter of the manager.] + + Description [Sets the looseUpTo parameter of the manager. This + parameter of the manager controls the threshold beyond which no fast + growth of the unique table is allowed. The threshold is given as a + number of slots. If the value passed to this function is 0, the + function determines a suitable value based on the available memory.] + + SideEffects [None] + + SeeAlso [Cudd_ReadLooseUpTo Cudd_SetMinHit] + +******************************************************************************/ +void +Cudd_SetLooseUpTo( + DdManager * dd, + unsigned int lut) +{ + if (lut == 0) { + unsigned long datalimit = getSoftDataLimit(); + lut = (unsigned int) (datalimit / (sizeof(DdNode) * + DD_MAX_LOOSE_FRACTION)); + } + dd->looseUpTo = lut; + +} /* end of Cudd_SetLooseUpTo */ + + +/**Function******************************************************************** + + Synopsis [Returns the soft limit for the cache size.] + + Description [Returns the soft limit for the cache size.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxCacheHard] + +******************************************************************************/ +unsigned int +Cudd_ReadMaxCache( + DdManager * dd) +{ + return(2 * dd->cacheSlots + dd->cacheSlack); + +} /* end of Cudd_ReadMaxCache */ + + +/**Function******************************************************************** + + Synopsis [Reads the maxCacheHard parameter of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetMaxCacheHard Cudd_ReadMaxCache] + +******************************************************************************/ +unsigned int +Cudd_ReadMaxCacheHard( + DdManager * dd) +{ + return(dd->maxCacheHard); + +} /* end of Cudd_ReadMaxCache */ + + +/**Function******************************************************************** + + Synopsis [Sets the maxCacheHard parameter of the manager.] + + Description [Sets the maxCacheHard parameter of the manager. The + cache cannot grow larger than maxCacheHard entries. This parameter + allows an application to control the trade-off of memory versus + speed. If the value passed to this function is 0, the function + determines a suitable maximum cache size based on the available memory.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxCacheHard Cudd_SetMaxCache] + +******************************************************************************/ +void +Cudd_SetMaxCacheHard( + DdManager * dd, + unsigned int mc) +{ + if (mc == 0) { + unsigned long datalimit = getSoftDataLimit(); + mc = (unsigned int) (datalimit / (sizeof(DdCache) * + DD_MAX_CACHE_FRACTION)); + } + dd->maxCacheHard = mc; + +} /* end of Cudd_SetMaxCacheHard */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of BDD variables in existance.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadZddSize] + +******************************************************************************/ +int +Cudd_ReadSize( + DdManager * dd) +{ + return(dd->size); + +} /* end of Cudd_ReadSize */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of ZDD variables in existance.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadSize] + +******************************************************************************/ +int +Cudd_ReadZddSize( + DdManager * dd) +{ + return(dd->sizeZ); + +} /* end of Cudd_ReadZddSize */ + + +/**Function******************************************************************** + + Synopsis [Returns the total number of slots of the unique table.] + + Description [Returns the total number of slots of the unique table. + This number ismainly for diagnostic purposes.] + + SideEffects [None] + +******************************************************************************/ +unsigned int +Cudd_ReadSlots( + DdManager * dd) +{ + return(dd->slots); + +} /* end of Cudd_ReadSlots */ + + +/**Function******************************************************************** + + Synopsis [Reads the fraction of used slots in the unique table.] + + Description [Reads the fraction of used slots in the unique + table. The unused slots are those in which no valid data is + stored. Garbage collection, variable reordering, and subtable + resizing may cause used slots to become unused.] + + SideEffects [None] + + SeeAlso [Cudd_ReadSlots] + +******************************************************************************/ +double +Cudd_ReadUsedSlots( + DdManager * dd) +{ + unsigned long used = 0; + int i, j; + int size = dd->size; + DdNodePtr *nodelist; + DdSubtable *subtable; + DdNode *node; + DdNode *sentinel = &(dd->sentinel); + + /* Scan each BDD/ADD subtable. */ + for (i = 0; i < size; i++) { + subtable = &(dd->subtables[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != sentinel) { + used++; + } + } + } + + /* Scan the ZDD subtables. */ + size = dd->sizeZ; + + for (i = 0; i < size; i++) { + subtable = &(dd->subtableZ[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + used++; + } + } + } + + /* Constant table. */ + subtable = &(dd->constants); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + used++; + } + } + + return((double)used / (double) dd->slots); + +} /* end of Cudd_ReadUsedSlots */ + + +/**Function******************************************************************** + + Synopsis [Computes the expected fraction of used slots in the unique + table.] + + Description [Computes the fraction of slots in the unique table that + should be in use. This expected value is based on the assumption + that the hash function distributes the keys randomly; it can be + compared with the result of Cudd_ReadUsedSlots to monitor the + performance of the unique table hash function.] + + SideEffects [None] + + SeeAlso [Cudd_ReadSlots Cudd_ReadUsedSlots] + +******************************************************************************/ +double +Cudd_ExpectedUsedSlots( + DdManager * dd) +{ + int i; + int size = dd->size; + DdSubtable *subtable; + double empty = 0.0; + + /* To each subtable we apply the corollary to Theorem 8.5 (occupancy + ** distribution) from Sedgewick and Flajolet's Analysis of Algorithms. + ** The corollary says that for a table with M buckets and a load ratio + ** of r, the expected number of empty buckets is asymptotically given + ** by M * exp(-r). + */ + + /* Scan each BDD/ADD subtable. */ + for (i = 0; i < size; i++) { + subtable = &(dd->subtables[i]); + empty += (double) subtable->slots * + exp(-(double) subtable->keys / (double) subtable->slots); + } + + /* Scan the ZDD subtables. */ + size = dd->sizeZ; + + for (i = 0; i < size; i++) { + subtable = &(dd->subtableZ[i]); + empty += (double) subtable->slots * + exp(-(double) subtable->keys / (double) subtable->slots); + } + + /* Constant table. */ + subtable = &(dd->constants); + empty += (double) subtable->slots * + exp(-(double) subtable->keys / (double) subtable->slots); + + return(1.0 - empty / (double) dd->slots); + +} /* end of Cudd_ExpectedUsedSlots */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of nodes in the unique table.] + + Description [Returns the total number of nodes currently in the unique + table, including the dead nodes.] + + SideEffects [None] + + SeeAlso [Cudd_ReadDead] + +******************************************************************************/ +unsigned int +Cudd_ReadKeys( + DdManager * dd) +{ + return(dd->keys); + +} /* end of Cudd_ReadKeys */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of dead nodes in the unique table.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadKeys] + +******************************************************************************/ +unsigned int +Cudd_ReadDead( + DdManager * dd) +{ + return(dd->dead); + +} /* end of Cudd_ReadDead */ + + +/**Function******************************************************************** + + Synopsis [Reads the minDead parameter of the manager.] + + Description [Reads the minDead parameter of the manager. The minDead + parameter is used by the package to decide whether to collect garbage + or resize a subtable of the unique table when the subtable becomes + too full. The application can indirectly control the value of minDead + by setting the looseUpTo parameter.] + + SideEffects [None] + + SeeAlso [Cudd_ReadDead Cudd_ReadLooseUpTo Cudd_SetLooseUpTo] + +******************************************************************************/ +unsigned int +Cudd_ReadMinDead( + DdManager * dd) +{ + return(dd->minDead); + +} /* end of Cudd_ReadMinDead */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of times reordering has occurred.] + + Description [Returns the number of times reordering has occurred in the + manager. The number includes both the calls to Cudd_ReduceHeap from + the application program and those automatically performed by the + package. However, calls that do not even initiate reordering are not + counted. A call may not initiate reordering if there are fewer than + minsize live nodes in the manager, or if CUDD_REORDER_NONE is specified + as reordering method. The calls to Cudd_ShuffleHeap are not counted.] + + SideEffects [None] + + SeeAlso [Cudd_ReduceHeap Cudd_ReadReorderingTime] + +******************************************************************************/ +unsigned int +Cudd_ReadReorderings( + DdManager * dd) +{ + return(dd->reorderings); + +} /* end of Cudd_ReadReorderings */ + + +/**Function******************************************************************** + + Synopsis [Returns the maximum number of times reordering may be invoked.] + + Description [Returns the maximum number of times reordering may be invoked in + this manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadReorderings Cudd_SetMaxReorderings Cudd_ReduceHeap] + +******************************************************************************/ +unsigned int +Cudd_ReadMaxReorderings( + DdManager * dd) +{ + return(dd->maxReorderings); + +} /* end of Cudd_ReadMaxReorderings */ + + +/**Function******************************************************************** + + Synopsis [Sets the maximum number of times reordering may be invoked.] + + Description [Sets the maximum number of times reordering may be invoked in + this manager. The default value is (practically) infinite.] + + SideEffects [None] + + SeeAlso [Cudd_ReadReorderings Cudd_ReadMaxReorderings Cudd_ReduceHeap] + +******************************************************************************/ +void +Cudd_SetMaxReorderings( + DdManager * dd, unsigned int mr) +{ + dd->maxReorderings = mr; + +} /* end of Cudd_SetMaxReorderings */ + + +/**Function******************************************************************** + + Synopsis [Returns the time spent in reordering.] + + Description [Returns the number of milliseconds spent reordering + variables since the manager was initialized. The time spent in collecting + garbage before reordering is included.] + + SideEffects [None] + + SeeAlso [Cudd_ReadReorderings] + +******************************************************************************/ +long +Cudd_ReadReorderingTime( + DdManager * dd) +{ + return(dd->reordTime); + +} /* end of Cudd_ReadReorderingTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of times garbage collection has occurred.] + + Description [Returns the number of times garbage collection has + occurred in the manager. The number includes both the calls from + reordering procedures and those caused by requests to create new + nodes.] + + SideEffects [None] + + SeeAlso [Cudd_ReadGarbageCollectionTime] + +******************************************************************************/ +int +Cudd_ReadGarbageCollections( + DdManager * dd) +{ + return(dd->garbageCollections); + +} /* end of Cudd_ReadGarbageCollections */ + + +/**Function******************************************************************** + + Synopsis [Returns the time spent in garbage collection.] + + Description [Returns the number of milliseconds spent doing garbage + collection since the manager was initialized.] + + SideEffects [None] + + SeeAlso [Cudd_ReadGarbageCollections] + +******************************************************************************/ +long +Cudd_ReadGarbageCollectionTime( + DdManager * dd) +{ + return(dd->GCTime); + +} /* end of Cudd_ReadGarbageCollectionTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of nodes freed.] + + Description [Returns the number of nodes returned to the free list if the + keeping of this statistic is enabled; -1 otherwise. This statistic is + enabled only if the package is compiled with DD_STATS defined.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNodesDropped] + +******************************************************************************/ +double +Cudd_ReadNodesFreed( + DdManager * dd) +{ +#ifdef DD_STATS + return(dd->nodesFreed); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadNodesFreed */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of nodes dropped.] + + Description [Returns the number of nodes killed by dereferencing if the + keeping of this statistic is enabled; -1 otherwise. This statistic is + enabled only if the package is compiled with DD_STATS defined.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNodesFreed] + +******************************************************************************/ +double +Cudd_ReadNodesDropped( + DdManager * dd) +{ +#ifdef DD_STATS + return(dd->nodesDropped); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadNodesDropped */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of look-ups in the unique table.] + + Description [Returns the number of look-ups in the unique table if the + keeping of this statistic is enabled; -1 otherwise. This statistic is + enabled only if the package is compiled with DD_UNIQUE_PROFILE defined.] + + SideEffects [None] + + SeeAlso [Cudd_ReadUniqueLinks] + +******************************************************************************/ +double +Cudd_ReadUniqueLookUps( + DdManager * dd) +{ +#ifdef DD_UNIQUE_PROFILE + return(dd->uniqueLookUps); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadUniqueLookUps */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of links followed in the unique table.] + + Description [Returns the number of links followed during look-ups in the + unique table if the keeping of this statistic is enabled; -1 otherwise. + If an item is found in the first position of its collision list, the + number of links followed is taken to be 0. If it is in second position, + the number of links is 1, and so on. This statistic is enabled only if + the package is compiled with DD_UNIQUE_PROFILE defined.] + + SideEffects [None] + + SeeAlso [Cudd_ReadUniqueLookUps] + +******************************************************************************/ +double +Cudd_ReadUniqueLinks( + DdManager * dd) +{ +#ifdef DD_UNIQUE_PROFILE + return(dd->uniqueLinks); +#else + return(-1.0); +#endif + +} /* end of Cudd_ReadUniqueLinks */ + + +/**Function******************************************************************** + + Synopsis [Reads the siftMaxVar parameter of the manager.] + + Description [Reads the siftMaxVar parameter of the manager. This + parameter gives the maximum number of variables that will be sifted + for each invocation of sifting.] + + SideEffects [None] + + SeeAlso [Cudd_ReadSiftMaxSwap Cudd_SetSiftMaxVar] + +******************************************************************************/ +int +Cudd_ReadSiftMaxVar( + DdManager * dd) +{ + return(dd->siftMaxVar); + +} /* end of Cudd_ReadSiftMaxVar */ + + +/**Function******************************************************************** + + Synopsis [Sets the siftMaxVar parameter of the manager.] + + Description [Sets the siftMaxVar parameter of the manager. This + parameter gives the maximum number of variables that will be sifted + for each invocation of sifting.] + + SideEffects [None] + + SeeAlso [Cudd_SetSiftMaxSwap Cudd_ReadSiftMaxVar] + +******************************************************************************/ +void +Cudd_SetSiftMaxVar( + DdManager * dd, + int smv) +{ + dd->siftMaxVar = smv; + +} /* end of Cudd_SetSiftMaxVar */ + + +/**Function******************************************************************** + + Synopsis [Reads the siftMaxSwap parameter of the manager.] + + Description [Reads the siftMaxSwap parameter of the manager. This + parameter gives the maximum number of swaps that will be attempted + for each invocation of sifting. The real number of swaps may exceed + the set limit because the package will always complete the sifting + of the variable that causes the limit to be reached.] + + SideEffects [None] + + SeeAlso [Cudd_ReadSiftMaxVar Cudd_SetSiftMaxSwap] + +******************************************************************************/ +int +Cudd_ReadSiftMaxSwap( + DdManager * dd) +{ + return(dd->siftMaxSwap); + +} /* end of Cudd_ReadSiftMaxSwap */ + + +/**Function******************************************************************** + + Synopsis [Sets the siftMaxSwap parameter of the manager.] + + Description [Sets the siftMaxSwap parameter of the manager. This + parameter gives the maximum number of swaps that will be attempted + for each invocation of sifting. The real number of swaps may exceed + the set limit because the package will always complete the sifting + of the variable that causes the limit to be reached.] + + SideEffects [None] + + SeeAlso [Cudd_SetSiftMaxVar Cudd_ReadSiftMaxSwap] + +******************************************************************************/ +void +Cudd_SetSiftMaxSwap( + DdManager * dd, + int sms) +{ + dd->siftMaxSwap = sms; + +} /* end of Cudd_SetSiftMaxSwap */ + + +/**Function******************************************************************** + + Synopsis [Reads the maxGrowth parameter of the manager.] + + Description [Reads the maxGrowth parameter of the manager. This + parameter determines how much the number of nodes can grow during + sifting of a variable. Overall, sifting never increases the size of + the decision diagrams. This parameter only refers to intermediate + results. A lower value will speed up sifting, possibly at the + expense of quality.] + + SideEffects [None] + + SeeAlso [Cudd_SetMaxGrowth Cudd_ReadMaxGrowthAlternate] + +******************************************************************************/ +double +Cudd_ReadMaxGrowth( + DdManager * dd) +{ + return(dd->maxGrowth); + +} /* end of Cudd_ReadMaxGrowth */ + + +/**Function******************************************************************** + + Synopsis [Sets the maxGrowth parameter of the manager.] + + Description [Sets the maxGrowth parameter of the manager. This + parameter determines how much the number of nodes can grow during + sifting of a variable. Overall, sifting never increases the size of + the decision diagrams. This parameter only refers to intermediate + results. A lower value will speed up sifting, possibly at the + expense of quality.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate] + +******************************************************************************/ +void +Cudd_SetMaxGrowth( + DdManager * dd, + double mg) +{ + dd->maxGrowth = mg; + +} /* end of Cudd_SetMaxGrowth */ + + +/**Function******************************************************************** + + Synopsis [Reads the maxGrowthAlt parameter of the manager.] + + Description [Reads the maxGrowthAlt parameter of the manager. This + parameter is analogous to the maxGrowth paramter, and is used every + given number of reorderings instead of maxGrowth. The number of + reorderings is set with Cudd_SetReorderingCycle. If the number of + reorderings is 0 (default) maxGrowthAlt is never used.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate + Cudd_SetReorderingCycle Cudd_ReadReorderingCycle] + +******************************************************************************/ +double +Cudd_ReadMaxGrowthAlternate( + DdManager * dd) +{ + return(dd->maxGrowthAlt); + +} /* end of Cudd_ReadMaxGrowthAlternate */ + + +/**Function******************************************************************** + + Synopsis [Sets the maxGrowthAlt parameter of the manager.] + + Description [Sets the maxGrowthAlt parameter of the manager. This + parameter is analogous to the maxGrowth paramter, and is used every + given number of reorderings instead of maxGrowth. The number of + reorderings is set with Cudd_SetReorderingCycle. If the number of + reorderings is 0 (default) maxGrowthAlt is never used.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowth + Cudd_SetReorderingCycle Cudd_ReadReorderingCycle] + +******************************************************************************/ +void +Cudd_SetMaxGrowthAlternate( + DdManager * dd, + double mg) +{ + dd->maxGrowthAlt = mg; + +} /* end of Cudd_SetMaxGrowthAlternate */ + + +/**Function******************************************************************** + + Synopsis [Reads the reordCycle parameter of the manager.] + + Description [Reads the reordCycle parameter of the manager. This + parameter determines how often the alternate threshold on maximum + growth is used in reordering.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate + Cudd_SetReorderingCycle] + +******************************************************************************/ +int +Cudd_ReadReorderingCycle( + DdManager * dd) +{ + return(dd->reordCycle); + +} /* end of Cudd_ReadReorderingCycle */ + + +/**Function******************************************************************** + + Synopsis [Sets the reordCycle parameter of the manager.] + + Description [Sets the reordCycle parameter of the manager. This + parameter determines how often the alternate threshold on maximum + growth is used in reordering.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate + Cudd_ReadReorderingCycle] + +******************************************************************************/ +void +Cudd_SetReorderingCycle( + DdManager * dd, + int cycle) +{ + dd->reordCycle = cycle; + +} /* end of Cudd_SetReorderingCycle */ + + +/**Function******************************************************************** + + Synopsis [Returns the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetTree Cudd_FreeTree Cudd_ReadZddTree] + +******************************************************************************/ +MtrNode * +Cudd_ReadTree( + DdManager * dd) +{ + return(dd->tree); + +} /* end of Cudd_ReadTree */ + + +/**Function******************************************************************** + + Synopsis [Sets the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_FreeTree Cudd_ReadTree Cudd_SetZddTree] + +******************************************************************************/ +void +Cudd_SetTree( + DdManager * dd, + MtrNode * tree) +{ + if (dd->tree != NULL) { + Mtr_FreeTree(dd->tree); + } + dd->tree = tree; + if (tree == NULL) return; + + fixVarTree(tree, dd->perm, dd->size); + return; + +} /* end of Cudd_SetTree */ + + +/**Function******************************************************************** + + Synopsis [Frees the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetTree Cudd_ReadTree Cudd_FreeZddTree] + +******************************************************************************/ +void +Cudd_FreeTree( + DdManager * dd) +{ + if (dd->tree != NULL) { + Mtr_FreeTree(dd->tree); + dd->tree = NULL; + } + return; + +} /* end of Cudd_FreeTree */ + + +/**Function******************************************************************** + + Synopsis [Returns the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetZddTree Cudd_FreeZddTree Cudd_ReadTree] + +******************************************************************************/ +MtrNode * +Cudd_ReadZddTree( + DdManager * dd) +{ + return(dd->treeZ); + +} /* end of Cudd_ReadZddTree */ + + +/**Function******************************************************************** + + Synopsis [Sets the ZDD variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_FreeZddTree Cudd_ReadZddTree Cudd_SetTree] + +******************************************************************************/ +void +Cudd_SetZddTree( + DdManager * dd, + MtrNode * tree) +{ + if (dd->treeZ != NULL) { + Mtr_FreeTree(dd->treeZ); + } + dd->treeZ = tree; + if (tree == NULL) return; + + fixVarTree(tree, dd->permZ, dd->sizeZ); + return; + +} /* end of Cudd_SetZddTree */ + + +/**Function******************************************************************** + + Synopsis [Frees the variable group tree of the manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_SetZddTree Cudd_ReadZddTree Cudd_FreeTree] + +******************************************************************************/ +void +Cudd_FreeZddTree( + DdManager * dd) +{ + if (dd->treeZ != NULL) { + Mtr_FreeTree(dd->treeZ); + dd->treeZ = NULL; + } + return; + +} /* end of Cudd_FreeZddTree */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the node.] + + Description [Returns the index of the node. The node pointer can be + either regular or complemented.] + + SideEffects [None] + + SeeAlso [Cudd_ReadIndex] + +******************************************************************************/ +unsigned int +Cudd_NodeReadIndex( + DdNode * node) +{ + return((unsigned int) Cudd_Regular(node)->index); + +} /* end of Cudd_NodeReadIndex */ + + +/**Function******************************************************************** + + Synopsis [Returns the current position of the i-th variable in the + order.] + + Description [Returns the current position of the i-th variable in + the order. If the index is CUDD_CONST_INDEX, returns + CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns + -1.] + + SideEffects [None] + + SeeAlso [Cudd_ReadInvPerm Cudd_ReadPermZdd] + +******************************************************************************/ +int +Cudd_ReadPerm( + DdManager * dd, + int i) +{ + if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); + if (i < 0 || i >= dd->size) return(-1); + return(dd->perm[i]); + +} /* end of Cudd_ReadPerm */ + + +/**Function******************************************************************** + + Synopsis [Returns the current position of the i-th ZDD variable in the + order.] + + Description [Returns the current position of the i-th ZDD variable + in the order. If the index is CUDD_CONST_INDEX, returns + CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns + -1.] + + SideEffects [None] + + SeeAlso [Cudd_ReadInvPermZdd Cudd_ReadPerm] + +******************************************************************************/ +int +Cudd_ReadPermZdd( + DdManager * dd, + int i) +{ + if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); + if (i < 0 || i >= dd->sizeZ) return(-1); + return(dd->permZ[i]); + +} /* end of Cudd_ReadPermZdd */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the variable currently in the i-th + position of the order.] + + Description [Returns the index of the variable currently in the i-th + position of the order. If the index is CUDD_CONST_INDEX, returns + CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.] + + SideEffects [None] + + SeeAlso [Cudd_ReadPerm Cudd_ReadInvPermZdd] + +******************************************************************************/ +int +Cudd_ReadInvPerm( + DdManager * dd, + int i) +{ + if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); + if (i < 0 || i >= dd->size) return(-1); + return(dd->invperm[i]); + +} /* end of Cudd_ReadInvPerm */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the ZDD variable currently in the i-th + position of the order.] + + Description [Returns the index of the ZDD variable currently in the + i-th position of the order. If the index is CUDD_CONST_INDEX, returns + CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.] + + SideEffects [None] + + SeeAlso [Cudd_ReadPerm Cudd_ReadInvPermZdd] + +******************************************************************************/ +int +Cudd_ReadInvPermZdd( + DdManager * dd, + int i) +{ + if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); + if (i < 0 || i >= dd->sizeZ) return(-1); + return(dd->invpermZ[i]); + +} /* end of Cudd_ReadInvPermZdd */ + + +/**Function******************************************************************** + + Synopsis [Returns the i-th element of the vars array.] + + Description [Returns the i-th element of the vars array if it falls + within the array bounds; NULL otherwise. If i is the index of an + existing variable, this function produces the same result as + Cudd_bddIthVar. However, if the i-th var does not exist yet, + Cudd_bddIthVar will create it, whereas Cudd_ReadVars will not.] + + SideEffects [None] + + SeeAlso [Cudd_bddIthVar] + +******************************************************************************/ +DdNode * +Cudd_ReadVars( + DdManager * dd, + int i) +{ + if (i < 0 || i > dd->size) return(NULL); + return(dd->vars[i]); + +} /* end of Cudd_ReadVars */ + + +/**Function******************************************************************** + + Synopsis [Reads the epsilon parameter of the manager.] + + Description [Reads the epsilon parameter of the manager. The epsilon + parameter control the comparison between floating point numbers.] + + SideEffects [None] + + SeeAlso [Cudd_SetEpsilon] + +******************************************************************************/ +CUDD_VALUE_TYPE +Cudd_ReadEpsilon( + DdManager * dd) +{ + return(dd->epsilon); + +} /* end of Cudd_ReadEpsilon */ + + +/**Function******************************************************************** + + Synopsis [Sets the epsilon parameter of the manager to ep.] + + Description [Sets the epsilon parameter of the manager to ep. The epsilon + parameter control the comparison between floating point numbers.] + + SideEffects [None] + + SeeAlso [Cudd_ReadEpsilon] + +******************************************************************************/ +void +Cudd_SetEpsilon( + DdManager * dd, + CUDD_VALUE_TYPE ep) +{ + dd->epsilon = ep; + +} /* end of Cudd_SetEpsilon */ + + +/**Function******************************************************************** + + Synopsis [Reads the groupcheck parameter of the manager.] + + Description [Reads the groupcheck parameter of the manager. The + groupcheck parameter determines the aggregation criterion in group + sifting.] + + SideEffects [None] + + SeeAlso [Cudd_SetGroupcheck] + +******************************************************************************/ +Cudd_AggregationType +Cudd_ReadGroupcheck( + DdManager * dd) +{ + return(dd->groupcheck); + +} /* end of Cudd_ReadGroupCheck */ + + +/**Function******************************************************************** + + Synopsis [Sets the parameter groupcheck of the manager to gc.] + + Description [Sets the parameter groupcheck of the manager to gc. The + groupcheck parameter determines the aggregation criterion in group + sifting.] + + SideEffects [None] + + SeeAlso [Cudd_ReadGroupCheck] + +******************************************************************************/ +void +Cudd_SetGroupcheck( + DdManager * dd, + Cudd_AggregationType gc) +{ + dd->groupcheck = gc; + +} /* end of Cudd_SetGroupcheck */ + + +/**Function******************************************************************** + + Synopsis [Tells whether garbage collection is enabled.] + + Description [Returns 1 if garbage collection is enabled; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_EnableGarbageCollection Cudd_DisableGarbageCollection] + +******************************************************************************/ +int +Cudd_GarbageCollectionEnabled( + DdManager * dd) +{ + return(dd->gcEnabled); + +} /* end of Cudd_GarbageCollectionEnabled */ + + +/**Function******************************************************************** + + Synopsis [Enables garbage collection.] + + Description [Enables garbage collection. Garbage collection is + initially enabled. Therefore it is necessary to call this function + only if garbage collection has been explicitly disabled.] + + SideEffects [None] + + SeeAlso [Cudd_DisableGarbageCollection Cudd_GarbageCollectionEnabled] + +******************************************************************************/ +void +Cudd_EnableGarbageCollection( + DdManager * dd) +{ + dd->gcEnabled = 1; + +} /* end of Cudd_EnableGarbageCollection */ + + +/**Function******************************************************************** + + Synopsis [Disables garbage collection.] + + Description [Disables garbage collection. Garbage collection is + initially enabled. This function may be called to disable it. + However, garbage collection will still occur when a new node must be + created and no memory is left, or when garbage collection is required + for correctness. (E.g., before reordering.)] + + SideEffects [None] + + SeeAlso [Cudd_EnableGarbageCollection Cudd_GarbageCollectionEnabled] + +******************************************************************************/ +void +Cudd_DisableGarbageCollection( + DdManager * dd) +{ + dd->gcEnabled = 0; + +} /* end of Cudd_DisableGarbageCollection */ + + +/**Function******************************************************************** + + Synopsis [Tells whether dead nodes are counted towards triggering + reordering.] + + Description [Tells whether dead nodes are counted towards triggering + reordering. Returns 1 if dead nodes are counted; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_TurnOnCountDead Cudd_TurnOffCountDead] + +******************************************************************************/ +int +Cudd_DeadAreCounted( + DdManager * dd) +{ + return(dd->countDead == 0 ? 1 : 0); + +} /* end of Cudd_DeadAreCounted */ + + +/**Function******************************************************************** + + Synopsis [Causes the dead nodes to be counted towards triggering + reordering.] + + Description [Causes the dead nodes to be counted towards triggering + reordering. This causes more frequent reorderings. By default dead + nodes are not counted.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_TurnOffCountDead Cudd_DeadAreCounted] + +******************************************************************************/ +void +Cudd_TurnOnCountDead( + DdManager * dd) +{ + dd->countDead = 0; + +} /* end of Cudd_TurnOnCountDead */ + + +/**Function******************************************************************** + + Synopsis [Causes the dead nodes not to be counted towards triggering + reordering.] + + Description [Causes the dead nodes not to be counted towards + triggering reordering. This causes less frequent reorderings. By + default dead nodes are not counted. Therefore there is no need to + call this function unless Cudd_TurnOnCountDead has been previously + called.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_TurnOnCountDead Cudd_DeadAreCounted] + +******************************************************************************/ +void +Cudd_TurnOffCountDead( + DdManager * dd) +{ + dd->countDead = ~0; + +} /* end of Cudd_TurnOffCountDead */ + + +/**Function******************************************************************** + + Synopsis [Returns the current value of the recombination parameter used + in group sifting.] + + Description [Returns the current value of the recombination + parameter used in group sifting. A larger (positive) value makes the + aggregation of variables due to the second difference criterion more + likely. A smaller (negative) value makes aggregation less likely.] + + SideEffects [None] + + SeeAlso [Cudd_SetRecomb] + +******************************************************************************/ +int +Cudd_ReadRecomb( + DdManager * dd) +{ + return(dd->recomb); + +} /* end of Cudd_ReadRecomb */ + + +/**Function******************************************************************** + + Synopsis [Sets the value of the recombination parameter used in group + sifting.] + + Description [Sets the value of the recombination parameter used in + group sifting. A larger (positive) value makes the aggregation of + variables due to the second difference criterion more likely. A + smaller (negative) value makes aggregation less likely. The default + value is 0.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_ReadRecomb] + +******************************************************************************/ +void +Cudd_SetRecomb( + DdManager * dd, + int recomb) +{ + dd->recomb = recomb; + +} /* end of Cudd_SetRecomb */ + + +/**Function******************************************************************** + + Synopsis [Returns the current value of the symmviolation parameter used + in group sifting.] + + Description [Returns the current value of the symmviolation + parameter. This parameter is used in group sifting to decide how + many violations to the symmetry conditions f10 = f01 or + f11 = f00 are tolerable when checking for aggregation + due to extended symmetry. The value should be between 0 and 100. A + small value causes fewer variables to be aggregated. The default + value is 0.] + + SideEffects [None] + + SeeAlso [Cudd_SetSymmviolation] + +******************************************************************************/ +int +Cudd_ReadSymmviolation( + DdManager * dd) +{ + return(dd->symmviolation); + +} /* end of Cudd_ReadSymmviolation */ + + +/**Function******************************************************************** + + Synopsis [Sets the value of the symmviolation parameter used + in group sifting.] + + Description [Sets the value of the symmviolation + parameter. This parameter is used in group sifting to decide how + many violations to the symmetry conditions f10 = f01 or + f11 = f00 are tolerable when checking for aggregation + due to extended symmetry. The value should be between 0 and 100. A + small value causes fewer variables to be aggregated. The default + value is 0.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_ReadSymmviolation] + +******************************************************************************/ +void +Cudd_SetSymmviolation( + DdManager * dd, + int symmviolation) +{ + dd->symmviolation = symmviolation; + +} /* end of Cudd_SetSymmviolation */ + + +/**Function******************************************************************** + + Synopsis [Returns the current value of the arcviolation parameter used + in group sifting.] + + Description [Returns the current value of the arcviolation + parameter. This parameter is used in group sifting to decide how + many arcs into y not coming from x are + tolerable when checking for aggregation due to extended + symmetry. The value should be between 0 and 100. A small value + causes fewer variables to be aggregated. The default value is 0.] + + SideEffects [None] + + SeeAlso [Cudd_SetArcviolation] + +******************************************************************************/ +int +Cudd_ReadArcviolation( + DdManager * dd) +{ + return(dd->arcviolation); + +} /* end of Cudd_ReadArcviolation */ + + +/**Function******************************************************************** + + Synopsis [Sets the value of the arcviolation parameter used + in group sifting.] + + Description [Sets the value of the arcviolation + parameter. This parameter is used in group sifting to decide how + many arcs into y not coming from x are + tolerable when checking for aggregation due to extended + symmetry. The value should be between 0 and 100. A small value + causes fewer variables to be aggregated. The default value is 0.] + + SideEffects [None] + + SeeAlso [Cudd_ReadArcviolation] + +******************************************************************************/ +void +Cudd_SetArcviolation( + DdManager * dd, + int arcviolation) +{ + dd->arcviolation = arcviolation; + +} /* end of Cudd_SetArcviolation */ + + +/**Function******************************************************************** + + Synopsis [Reads the current size of the population used by the + genetic algorithm for reordering.] + + Description [Reads the current size of the population used by the + genetic algorithm for variable reordering. A larger population size will + cause the genetic algorithm to take more time, but will generally + produce better results. The default value is 0, in which case the + package uses three times the number of variables as population size, + with a maximum of 120.] + + SideEffects [None] + + SeeAlso [Cudd_SetPopulationSize] + +******************************************************************************/ +int +Cudd_ReadPopulationSize( + DdManager * dd) +{ + return(dd->populationSize); + +} /* end of Cudd_ReadPopulationSize */ + + +/**Function******************************************************************** + + Synopsis [Sets the size of the population used by the + genetic algorithm for reordering.] + + Description [Sets the size of the population used by the + genetic algorithm for variable reordering. A larger population size will + cause the genetic algorithm to take more time, but will generally + produce better results. The default value is 0, in which case the + package uses three times the number of variables as population size, + with a maximum of 120.] + + SideEffects [Changes the manager.] + + SeeAlso [Cudd_ReadPopulationSize] + +******************************************************************************/ +void +Cudd_SetPopulationSize( + DdManager * dd, + int populationSize) +{ + dd->populationSize = populationSize; + +} /* end of Cudd_SetPopulationSize */ + + +/**Function******************************************************************** + + Synopsis [Reads the current number of crossovers used by the + genetic algorithm for reordering.] + + Description [Reads the current number of crossovers used by the + genetic algorithm for variable reordering. A larger number of crossovers will + cause the genetic algorithm to take more time, but will generally + produce better results. The default value is 0, in which case the + package uses three times the number of variables as number of crossovers, + with a maximum of 60.] + + SideEffects [None] + + SeeAlso [Cudd_SetNumberXovers] + +******************************************************************************/ +int +Cudd_ReadNumberXovers( + DdManager * dd) +{ + return(dd->numberXovers); + +} /* end of Cudd_ReadNumberXovers */ + + +/**Function******************************************************************** + + Synopsis [Sets the number of crossovers used by the + genetic algorithm for reordering.] + + Description [Sets the number of crossovers used by the genetic + algorithm for variable reordering. A larger number of crossovers + will cause the genetic algorithm to take more time, but will + generally produce better results. The default value is 0, in which + case the package uses three times the number of variables as number + of crossovers, with a maximum of 60.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNumberXovers] + +******************************************************************************/ +void +Cudd_SetNumberXovers( + DdManager * dd, + int numberXovers) +{ + dd->numberXovers = numberXovers; + +} /* end of Cudd_SetNumberXovers */ + + +/**Function******************************************************************** + + Synopsis [Returns the order randomization factor.] + + Description [Returns the order randomization factor. If non-zero this + factor is used to determine a perturbation of the next reordering threshold. + Larger factors cause larger perturbations.] + + SideEffects [None] + + SeeAlso [Cudd_SetOrderRandomization] + +******************************************************************************/ +unsigned int +Cudd_ReadOrderRandomization( + DdManager * dd) +{ + return(dd->randomizeOrder); + +} /* end of Cudd_ReadOrderRandomization */ + + +/**Function******************************************************************** + + Synopsis [Sets the order randomization factor.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadOrderRandomization] + +******************************************************************************/ +void +Cudd_SetOrderRandomization( + DdManager * dd, + unsigned int factor) +{ + dd->randomizeOrder = factor; + +} /* end of Cudd_SetOrderRandomization */ + + +/**Function******************************************************************** + + Synopsis [Returns the memory in use by the manager measured in bytes.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +unsigned long +Cudd_ReadMemoryInUse( + DdManager * dd) +{ + return(dd->memused); + +} /* end of Cudd_ReadMemoryInUse */ + + +/**Function******************************************************************** + + Synopsis [Prints out statistics and settings for a CUDD manager.] + + Description [Prints out statistics and settings for a CUDD manager. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_PrintInfo( + DdManager * dd, + FILE * fp) +{ + int retval; + Cudd_ReorderingType autoMethod, autoMethodZ; + + /* Modifiable parameters. */ + retval = fprintf(fp,"**** CUDD modifiable parameters ****\n"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Hard limit for cache size: %u\n", + Cudd_ReadMaxCacheHard(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache hit threshold for resizing: %u%%\n", + Cudd_ReadMinHit(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Garbage collection enabled: %s\n", + Cudd_GarbageCollectionEnabled(dd) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Limit for fast unique table growth: %u\n", + Cudd_ReadLooseUpTo(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp, + "Maximum number of variables sifted per reordering: %d\n", + Cudd_ReadSiftMaxVar(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp, + "Maximum number of variable swaps per reordering: %d\n", + Cudd_ReadSiftMaxSwap(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Maximum growth while sifting a variable: %g\n", + Cudd_ReadMaxGrowth(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Dynamic reordering of BDDs enabled: %s\n", + Cudd_ReorderingStatus(dd,&autoMethod) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Default BDD reordering method: %d\n", + (int) autoMethod); + if (retval == EOF) return(0); + retval = fprintf(fp,"Dynamic reordering of ZDDs enabled: %s\n", + Cudd_ReorderingStatusZdd(dd,&autoMethodZ) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Default ZDD reordering method: %d\n", + (int) autoMethodZ); + if (retval == EOF) return(0); + retval = fprintf(fp,"Realignment of ZDDs to BDDs enabled: %s\n", + Cudd_zddRealignmentEnabled(dd) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Realignment of BDDs to ZDDs enabled: %s\n", + Cudd_bddRealignmentEnabled(dd) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Dead nodes counted in triggering reordering: %s\n", + Cudd_DeadAreCounted(dd) ? "yes" : "no"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Group checking criterion: %d\n", + (int) Cudd_ReadGroupcheck(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Recombination threshold: %d\n", Cudd_ReadRecomb(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Symmetry violation threshold: %d\n", + Cudd_ReadSymmviolation(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Arc violation threshold: %d\n", + Cudd_ReadArcviolation(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"GA population size: %d\n", + Cudd_ReadPopulationSize(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of crossovers for GA: %d\n", + Cudd_ReadNumberXovers(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Next reordering threshold: %u\n", + Cudd_ReadNextReordering(dd)); + if (retval == EOF) return(0); + + /* Non-modifiable parameters. */ + retval = fprintf(fp,"**** CUDD non-modifiable parameters ****\n"); + if (retval == EOF) return(0); + retval = fprintf(fp,"Memory in use: %lu\n", Cudd_ReadMemoryInUse(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Peak number of nodes: %ld\n", + Cudd_ReadPeakNodeCount(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Peak number of live nodes: %d\n", + Cudd_ReadPeakLiveNodeCount(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of BDD variables: %d\n", dd->size); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of ZDD variables: %d\n", dd->sizeZ); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache entries: %u\n", dd->cacheSlots); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache look-ups: %.0f\n", + Cudd_ReadCacheLookUps(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache hits: %.0f\n", + Cudd_ReadCacheHits(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache insertions: %.0f\n", + dd->cacheinserts); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache collisions: %.0f\n", + dd->cachecollisions); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of cache deletions: %.0f\n", + dd->cachedeletions); + if (retval == EOF) return(0); + retval = cuddCacheProfile(dd,fp); + if (retval == 0) return(0); + retval = fprintf(fp,"Soft limit for cache size: %u\n", + Cudd_ReadMaxCache(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of buckets in unique table: %u\n", dd->slots); + if (retval == EOF) return(0); + retval = fprintf(fp,"Used buckets in unique table: %.2f%% (expected %.2f%%)\n", + 100.0 * Cudd_ReadUsedSlots(dd), + 100.0 * Cudd_ExpectedUsedSlots(dd)); + if (retval == EOF) return(0); +#ifdef DD_UNIQUE_PROFILE + retval = fprintf(fp,"Unique lookups: %.0f\n", dd->uniqueLookUps); + if (retval == EOF) return(0); + retval = fprintf(fp,"Unique links: %.0f (%g per lookup)\n", + dd->uniqueLinks, dd->uniqueLinks / dd->uniqueLookUps); + if (retval == EOF) return(0); +#endif + retval = fprintf(fp,"Number of BDD and ADD nodes: %u\n", dd->keys); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of ZDD nodes: %u\n", dd->keysZ); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of dead BDD and ADD nodes: %u\n", dd->dead); + if (retval == EOF) return(0); + retval = fprintf(fp,"Number of dead ZDD nodes: %u\n", dd->deadZ); + if (retval == EOF) return(0); + retval = fprintf(fp,"Total number of nodes allocated: %.0f\n", + dd->allocated); + if (retval == EOF) return(0); + retval = fprintf(fp,"Total number of nodes reclaimed: %.0f\n", + dd->reclaimed); + if (retval == EOF) return(0); +#ifdef DD_STATS + retval = fprintf(fp,"Nodes freed: %.0f\n", dd->nodesFreed); + if (retval == EOF) return(0); + retval = fprintf(fp,"Nodes dropped: %.0f\n", dd->nodesDropped); + if (retval == EOF) return(0); +#endif +#ifdef DD_COUNT + retval = fprintf(fp,"Number of recursive calls: %.0f\n", + Cudd_ReadRecursiveCalls(dd)); + if (retval == EOF) return(0); +#endif + retval = fprintf(fp,"Garbage collections so far: %d\n", + Cudd_ReadGarbageCollections(dd)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Time for garbage collection: %.2f sec\n", + ((double)Cudd_ReadGarbageCollectionTime(dd)/1000.0)); + if (retval == EOF) return(0); + retval = fprintf(fp,"Reorderings so far: %d\n", dd->reorderings); + if (retval == EOF) return(0); + retval = fprintf(fp,"Time for reordering: %.2f sec\n", + ((double)Cudd_ReadReorderingTime(dd)/1000.0)); + if (retval == EOF) return(0); +#ifdef DD_COUNT + retval = fprintf(fp,"Node swaps in reordering: %.0f\n", + Cudd_ReadSwapSteps(dd)); + if (retval == EOF) return(0); +#endif + + return(1); + +} /* end of Cudd_PrintInfo */ + + +/**Function******************************************************************** + + Synopsis [Reports the peak number of nodes.] + + Description [Reports the peak number of nodes. This number includes + node on the free list. At the peak, the number of nodes on the free + list is guaranteed to be less than DD_MEM_CHUNK.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNodeCount Cudd_PrintInfo] + +******************************************************************************/ +long +Cudd_ReadPeakNodeCount( + DdManager * dd) +{ + long count = 0; + DdNodePtr *scan = dd->memoryList; + + while (scan != NULL) { + count += DD_MEM_CHUNK; + scan = (DdNodePtr *) *scan; + } + return(count); + +} /* end of Cudd_ReadPeakNodeCount */ + + +/**Function******************************************************************** + + Synopsis [Reports the peak number of live nodes.] + + Description [Reports the peak number of live nodes.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNodeCount Cudd_PrintInfo Cudd_ReadPeakNodeCount] + +******************************************************************************/ +int +Cudd_ReadPeakLiveNodeCount( + DdManager * dd) +{ + unsigned int live = dd->keys - dd->dead; + + if (live > dd->peakLiveNodes) { + dd->peakLiveNodes = live; + } + return((int)dd->peakLiveNodes); + +} /* end of Cudd_ReadPeakLiveNodeCount */ + + +/**Function******************************************************************** + + Synopsis [Reports the number of nodes in BDDs and ADDs.] + + Description [Reports the number of live nodes in BDDs and ADDs. This + number does not include the isolated projection functions and the + unused constants. These nodes that are not counted are not part of + the DDs manipulated by the application.] + + SideEffects [None] + + SeeAlso [Cudd_ReadPeakNodeCount Cudd_zddReadNodeCount] + +******************************************************************************/ +long +Cudd_ReadNodeCount( + DdManager * dd) +{ + long count; + int i; + +#ifndef DD_NO_DEATH_ROW + cuddClearDeathRow(dd); +#endif + + count = (long) (dd->keys - dd->dead); + + /* Count isolated projection functions. Their number is subtracted + ** from the node count because they are not part of the BDDs. + */ + for (i=0; i < dd->size; i++) { + if (dd->vars[i]->ref == 1) count--; + } + /* Subtract from the count the unused constants. */ + if (DD_ZERO(dd)->ref == 1) count--; + if (DD_PLUS_INFINITY(dd)->ref == 1) count--; + if (DD_MINUS_INFINITY(dd)->ref == 1) count--; + + return(count); + +} /* end of Cudd_ReadNodeCount */ + + + +/**Function******************************************************************** + + Synopsis [Reports the number of nodes in ZDDs.] + + Description [Reports the number of nodes in ZDDs. This + number always includes the two constants 1 and 0.] + + SideEffects [None] + + SeeAlso [Cudd_ReadPeakNodeCount Cudd_ReadNodeCount] + +******************************************************************************/ +long +Cudd_zddReadNodeCount( + DdManager * dd) +{ + return((long)(dd->keysZ - dd->deadZ + 2)); + +} /* end of Cudd_zddReadNodeCount */ + + +/**Function******************************************************************** + + Synopsis [Adds a function to a hook.] + + Description [Adds a function to a hook. A hook is a list of + application-provided functions called on certain occasions by the + package. Returns 1 if the function is successfully added; 2 if the + function was already in the list; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_RemoveHook] + +******************************************************************************/ +int +Cudd_AddHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where) +{ + DdHook **hook, *nextHook, *newHook; + + switch (where) { + case CUDD_PRE_GC_HOOK: + hook = &(dd->preGCHook); + break; + case CUDD_POST_GC_HOOK: + hook = &(dd->postGCHook); + break; + case CUDD_PRE_REORDERING_HOOK: + hook = &(dd->preReorderingHook); + break; + case CUDD_POST_REORDERING_HOOK: + hook = &(dd->postReorderingHook); + break; + default: + return(0); + } + /* Scan the list and find whether the function is already there. + ** If so, just return. */ + nextHook = *hook; + while (nextHook != NULL) { + if (nextHook->f == f) { + return(2); + } + hook = &(nextHook->next); + nextHook = nextHook->next; + } + /* The function was not in the list. Create a new item and append it + ** to the end of the list. */ + newHook = ALLOC(DdHook,1); + if (newHook == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newHook->next = NULL; + newHook->f = f; + *hook = newHook; + return(1); + +} /* end of Cudd_AddHook */ + + +/**Function******************************************************************** + + Synopsis [Removes a function from a hook.] + + Description [Removes a function from a hook. A hook is a list of + application-provided functions called on certain occasions by the + package. Returns 1 if successful; 0 the function was not in the list.] + + SideEffects [None] + + SeeAlso [Cudd_AddHook] + +******************************************************************************/ +int +Cudd_RemoveHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where) +{ + DdHook **hook, *nextHook; + + switch (where) { + case CUDD_PRE_GC_HOOK: + hook = &(dd->preGCHook); + break; + case CUDD_POST_GC_HOOK: + hook = &(dd->postGCHook); + break; + case CUDD_PRE_REORDERING_HOOK: + hook = &(dd->preReorderingHook); + break; + case CUDD_POST_REORDERING_HOOK: + hook = &(dd->postReorderingHook); + break; + default: + return(0); + } + nextHook = *hook; + while (nextHook != NULL) { + if (nextHook->f == f) { + *hook = nextHook->next; + FREE(nextHook); + return(1); + } + hook = &(nextHook->next); + nextHook = nextHook->next; + } + + return(0); + +} /* end of Cudd_RemoveHook */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a function is in a hook.] + + Description [Checks whether a function is in a hook. A hook is a list of + application-provided functions called on certain occasions by the + package. Returns 1 if the function is found; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_AddHook Cudd_RemoveHook] + +******************************************************************************/ +int +Cudd_IsInHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where) +{ + DdHook *hook; + + switch (where) { + case CUDD_PRE_GC_HOOK: + hook = dd->preGCHook; + break; + case CUDD_POST_GC_HOOK: + hook = dd->postGCHook; + break; + case CUDD_PRE_REORDERING_HOOK: + hook = dd->preReorderingHook; + break; + case CUDD_POST_REORDERING_HOOK: + hook = dd->postReorderingHook; + break; + default: + return(0); + } + /* Scan the list and find whether the function is already there. */ + while (hook != NULL) { + if (hook->f == f) { + return(1); + } + hook = hook->next; + } + return(0); + +} /* end of Cudd_IsInHook */ + + +/**Function******************************************************************** + + Synopsis [Sample hook function to call before reordering.] + + Description [Sample hook function to call before reordering. + Prints on the manager's stdout reordering method and initial size. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_StdPostReordHook] + +******************************************************************************/ +int +Cudd_StdPreReordHook( + DdManager *dd, + const char *str, + void *data) +{ + Cudd_ReorderingType method = (Cudd_ReorderingType) (ptruint) data; + int retval; + + retval = fprintf(dd->out,"%s reordering with ", str); + if (retval == EOF) return(0); + switch (method) { + case CUDD_REORDER_SIFT_CONVERGE: + case CUDD_REORDER_SYMM_SIFT_CONV: + case CUDD_REORDER_GROUP_SIFT_CONV: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + case CUDD_REORDER_LINEAR_CONVERGE: + retval = fprintf(dd->out,"converging "); + if (retval == EOF) return(0); + break; + default: + break; + } + switch (method) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + retval = fprintf(dd->out,"random"); + break; + case CUDD_REORDER_SIFT: + case CUDD_REORDER_SIFT_CONVERGE: + retval = fprintf(dd->out,"sifting"); + break; + case CUDD_REORDER_SYMM_SIFT: + case CUDD_REORDER_SYMM_SIFT_CONV: + retval = fprintf(dd->out,"symmetric sifting"); + break; + case CUDD_REORDER_LAZY_SIFT: + retval = fprintf(dd->out,"lazy sifting"); + break; + case CUDD_REORDER_GROUP_SIFT: + case CUDD_REORDER_GROUP_SIFT_CONV: + retval = fprintf(dd->out,"group sifting"); + break; + case CUDD_REORDER_WINDOW2: + case CUDD_REORDER_WINDOW3: + case CUDD_REORDER_WINDOW4: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + retval = fprintf(dd->out,"window"); + break; + case CUDD_REORDER_ANNEALING: + retval = fprintf(dd->out,"annealing"); + break; + case CUDD_REORDER_GENETIC: + retval = fprintf(dd->out,"genetic"); + break; + case CUDD_REORDER_LINEAR: + case CUDD_REORDER_LINEAR_CONVERGE: + retval = fprintf(dd->out,"linear sifting"); + break; + case CUDD_REORDER_EXACT: + retval = fprintf(dd->out,"exact"); + break; + default: + return(0); + } + if (retval == EOF) return(0); + + retval = fprintf(dd->out,": from %ld to ... ", strcmp(str, "BDD") == 0 ? + Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd)); + if (retval == EOF) return(0); + fflush(dd->out); + return(1); + +} /* end of Cudd_StdPreReordHook */ + + +/**Function******************************************************************** + + Synopsis [Sample hook function to call after reordering.] + + Description [Sample hook function to call after reordering. + Prints on the manager's stdout final size and reordering time. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_StdPreReordHook] + +******************************************************************************/ +int +Cudd_StdPostReordHook( + DdManager *dd, + const char *str, + void *data) +{ + unsigned long initialTime = (long) data; + int retval; + unsigned long finalTime = util_cpu_time(); + double totalTimeSec = (double)(finalTime - initialTime) / 1000.0; + + retval = fprintf(dd->out,"%ld nodes in %g sec\n", strcmp(str, "BDD") == 0 ? + Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd), + totalTimeSec); + if (retval == EOF) return(0); + retval = fflush(dd->out); + if (retval == EOF) return(0); + return(1); + +} /* end of Cudd_StdPostReordHook */ + + +/**Function******************************************************************** + + Synopsis [Enables reporting of reordering stats.] + + Description [Enables reporting of reordering stats. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Installs functions in the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_DisableReorderingReporting Cudd_ReorderingReporting] + +******************************************************************************/ +int +Cudd_EnableReorderingReporting( + DdManager *dd) +{ + if (!Cudd_AddHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_EnableReorderingReporting */ + + +/**Function******************************************************************** + + Synopsis [Disables reporting of reordering stats.] + + Description [Disables reporting of reordering stats. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Removes functions from the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_EnableReorderingReporting Cudd_ReorderingReporting] + +******************************************************************************/ +int +Cudd_DisableReorderingReporting( + DdManager *dd) +{ + if (!Cudd_RemoveHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_DisableReorderingReporting */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if reporting of reordering stats is enabled.] + + Description [Returns 1 if reporting of reordering stats is enabled; + 0 otherwise.] + + SideEffects [none] + + SeeAlso [Cudd_EnableReorderingReporting Cudd_DisableReorderingReporting] + +******************************************************************************/ +int +Cudd_ReorderingReporting( + DdManager *dd) +{ + return(Cudd_IsInHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)); + +} /* end of Cudd_ReorderingReporting */ + + +/**Function******************************************************************** + + Synopsis [Hook function to print the current variable order.] + + Description [Hook function to print the current variable order. It may be + called before or after reordering. Prints on the manager's stdout a + parenthesized list that describes the variable groups. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_StdPreReordHook] + +******************************************************************************/ +int +Cudd_PrintGroupedOrder( + DdManager * dd, + const char *str, + void *data) +{ + int isBdd = strcmp(str, "ZDD"); + MtrNode *tree = isBdd ? dd->tree : dd->treeZ; + int *invperm = isBdd ? dd->invperm : dd->invpermZ; + int size = isBdd ? dd->size : dd->sizeZ; + if (tree == NULL) { + int i, retval; + for (i=0; i < size; i++) { + retval = fprintf(dd->out, "%c%d", i==0 ? '(' : ',', invperm[i]); + if (retval == EOF) return(0); + } + retval = fprintf(dd->out,")\n"); + return (retval != EOF); + } else { + return Mtr_PrintGroupedOrder(tree,invperm,dd->out); + } + +} /* end of Cudd_PrintGroupedOrder */ + + +/**Function******************************************************************** + + Synopsis [Enables monitoring of ordering.] + + Description [Enables monitoring of ordering. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Installs functions in the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_EnableReorderingReporting] + +******************************************************************************/ +int +Cudd_EnableOrderingMonitoring( + DdManager *dd) +{ + if (!Cudd_AddHook(dd, Cudd_PrintGroupedOrder, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_PrintGroupedOrder, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_EnableOrderingMonitoring */ + + +/**Function******************************************************************** + + Synopsis [Disables monitoring of ordering.] + + Description [Disables monitoring of ordering. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Removes functions from the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_EnableOrderingMonitoring] + +******************************************************************************/ +int +Cudd_DisableOrderingMonitoring( + DdManager *dd) +{ + if (!Cudd_RemoveHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_PrintGroupedOrder, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_PrintGroupedOrder, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_DisableOrderingMonitoring */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if monitoring of ordering is enabled.] + + Description [Returns 1 if monitoring of ordering is enabled; + 0 otherwise.] + + SideEffects [none] + + SeeAlso [Cudd_EnableOrderingMonitoring Cudd_DisableOrderingMonitoring] + +******************************************************************************/ +int +Cudd_OrderingMonitoring( + DdManager *dd) +{ + return(Cudd_IsInHook(dd, Cudd_PrintGroupedOrder, CUDD_PRE_REORDERING_HOOK)); + +} /* end of Cudd_OrderingMonitoring */ + + +/**Function******************************************************************** + + Synopsis [Returns the code of the last error.] + + Description [Returns the code of the last error. The error codes are + defined in cudd.h.] + + SideEffects [None] + + SeeAlso [Cudd_ClearErrorCode] + +******************************************************************************/ +Cudd_ErrorType +Cudd_ReadErrorCode( + DdManager *dd) +{ + return(dd->errorCode); + +} /* end of Cudd_ReadErrorCode */ + + +/**Function******************************************************************** + + Synopsis [Clear the error code of a manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadErrorCode] + +******************************************************************************/ +void +Cudd_ClearErrorCode( + DdManager *dd) +{ + dd->errorCode = CUDD_NO_ERROR; + +} /* end of Cudd_ClearErrorCode */ + + +/**Function******************************************************************** + + Synopsis [Reads the stdout of a manager.] + + Description [Reads the stdout of a manager. This is the file pointer to + which messages normally going to stdout are written. It is initialized + to stdout. Cudd_SetStdout allows the application to redirect it.] + + SideEffects [None] + + SeeAlso [Cudd_SetStdout Cudd_ReadStderr] + +******************************************************************************/ +FILE * +Cudd_ReadStdout( + DdManager *dd) +{ + return(dd->out); + +} /* end of Cudd_ReadStdout */ + + +/**Function******************************************************************** + + Synopsis [Sets the stdout of a manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadStdout Cudd_SetStderr] + +******************************************************************************/ +void +Cudd_SetStdout( + DdManager *dd, + FILE *fp) +{ + dd->out = fp; + +} /* end of Cudd_SetStdout */ + + +/**Function******************************************************************** + + Synopsis [Reads the stderr of a manager.] + + Description [Reads the stderr of a manager. This is the file pointer to + which messages normally going to stderr are written. It is initialized + to stderr. Cudd_SetStderr allows the application to redirect it.] + + SideEffects [None] + + SeeAlso [Cudd_SetStderr Cudd_ReadStdout] + +******************************************************************************/ +FILE * +Cudd_ReadStderr( + DdManager *dd) +{ + return(dd->err); + +} /* end of Cudd_ReadStderr */ + + +/**Function******************************************************************** + + Synopsis [Sets the stderr of a manager.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadStderr Cudd_SetStdout] + +******************************************************************************/ +void +Cudd_SetStderr( + DdManager *dd, + FILE *fp) +{ + dd->err = fp; + +} /* end of Cudd_SetStderr */ + + +/**Function******************************************************************** + + Synopsis [Returns the threshold for the next dynamic reordering.] + + Description [Returns the threshold for the next dynamic reordering. + The threshold is in terms of number of nodes and is in effect only + if reordering is enabled. The count does not include the dead nodes, + unless the countDead parameter of the manager has been changed from + its default setting.] + + SideEffects [None] + + SeeAlso [Cudd_SetNextReordering] + +******************************************************************************/ +unsigned int +Cudd_ReadNextReordering( + DdManager *dd) +{ + return(dd->nextDyn); + +} /* end of Cudd_ReadNextReordering */ + + +/**Function******************************************************************** + + Synopsis [Sets the threshold for the next dynamic reordering.] + + Description [Sets the threshold for the next dynamic reordering. + The threshold is in terms of number of nodes and is in effect only + if reordering is enabled. The count does not include the dead nodes, + unless the countDead parameter of the manager has been changed from + its default setting.] + + SideEffects [None] + + SeeAlso [Cudd_ReadNextReordering] + +******************************************************************************/ +void +Cudd_SetNextReordering( + DdManager *dd, + unsigned int next) +{ + dd->nextDyn = next; + +} /* end of Cudd_SetNextReordering */ + + +/**Function******************************************************************** + + Synopsis [Reads the number of elementary reordering steps.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +double +Cudd_ReadSwapSteps( + DdManager *dd) +{ +#ifdef DD_COUNT + return(dd->swapSteps); +#else + return(-1); +#endif + +} /* end of Cudd_ReadSwapSteps */ + + +/**Function******************************************************************** + + Synopsis [Reads the maximum allowed number of live nodes.] + + Description [Reads the maximum allowed number of live nodes. When this + number is exceeded, the package returns NULL.] + + SideEffects [none] + + SeeAlso [Cudd_SetMaxLive] + +******************************************************************************/ +unsigned int +Cudd_ReadMaxLive( + DdManager *dd) +{ + return(dd->maxLive); + +} /* end of Cudd_ReadMaxLive */ + + +/**Function******************************************************************** + + Synopsis [Sets the maximum allowed number of live nodes.] + + Description [Sets the maximum allowed number of live nodes. When this + number is exceeded, the package returns NULL.] + + SideEffects [none] + + SeeAlso [Cudd_ReadMaxLive] + +******************************************************************************/ +void +Cudd_SetMaxLive( + DdManager *dd, + unsigned int maxLive) +{ + dd->maxLive = maxLive; + +} /* end of Cudd_SetMaxLive */ + + +/**Function******************************************************************** + + Synopsis [Reads the maximum allowed memory.] + + Description [Reads the maximum allowed memory. When this + number is exceeded, the package returns NULL.] + + SideEffects [none] + + SeeAlso [Cudd_SetMaxMemory] + +******************************************************************************/ +unsigned long +Cudd_ReadMaxMemory( + DdManager *dd) +{ + return(dd->maxmemhard); + +} /* end of Cudd_ReadMaxMemory */ + + +/**Function******************************************************************** + + Synopsis [Sets the maximum allowed memory.] + + Description [Sets the maximum allowed memory. When this + number is exceeded, the package returns NULL.] + + SideEffects [none] + + SeeAlso [Cudd_ReadMaxMemory] + +******************************************************************************/ +void +Cudd_SetMaxMemory( + DdManager *dd, + unsigned long maxMemory) +{ + dd->maxmemhard = maxMemory; + +} /* end of Cudd_SetMaxMemory */ + + +/**Function******************************************************************** + + Synopsis [Prevents sifting of a variable.] + + Description [This function sets a flag to prevent sifting of a + variable. Returns 1 if successful; 0 otherwise (i.e., invalid + variable index).] + + SideEffects [Changes the "bindVar" flag in DdSubtable.] + + SeeAlso [Cudd_bddUnbindVar] + +******************************************************************************/ +int +Cudd_bddBindVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].bindVar = 1; + return(1); + +} /* end of Cudd_bddBindVar */ + + +/**Function******************************************************************** + + Synopsis [Allows the sifting of a variable.] + + Description [This function resets the flag that prevents the sifting + of a variable. In successive variable reorderings, the variable will + NOT be skipped, that is, sifted. Initially all variables can be + sifted. It is necessary to call this function only to re-enable + sifting after a call to Cudd_bddBindVar. Returns 1 if successful; 0 + otherwise (i.e., invalid variable index).] + + SideEffects [Changes the "bindVar" flag in DdSubtable.] + + SeeAlso [Cudd_bddBindVar] + +******************************************************************************/ +int +Cudd_bddUnbindVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].bindVar = 0; + return(1); + +} /* end of Cudd_bddUnbindVar */ + + +/**Function******************************************************************** + + Synopsis [Tells whether a variable can be sifted.] + + Description [This function returns 1 if a variable is enabled for + sifting. Initially all variables can be sifted. This function returns + 0 only if there has been a previous call to Cudd_bddBindVar for that + variable not followed by a call to Cudd_bddUnbindVar. The function returns + 0 also in the case in which the index of the variable is out of bounds.] + + SideEffects [none] + + SeeAlso [Cudd_bddBindVar Cudd_bddUnbindVar] + +******************************************************************************/ +int +Cudd_bddVarIsBound( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return(0); + return(dd->subtables[dd->perm[index]].bindVar); + +} /* end of Cudd_bddVarIsBound */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable type to primary input.] + + Description [Sets a variable type to primary input. The variable type is + used by lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetPsVar Cudd_bddSetNsVar Cudd_bddIsPiVar] + +******************************************************************************/ +int +Cudd_bddSetPiVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return (0); + dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRIMARY_INPUT; + return(1); + +} /* end of Cudd_bddSetPiVar */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable type to present state.] + + Description [Sets a variable type to present state. The variable type is + used by lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetPiVar Cudd_bddSetNsVar Cudd_bddIsPsVar] + +******************************************************************************/ +int +Cudd_bddSetPsVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return (0); + dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRESENT_STATE; + return(1); + +} /* end of Cudd_bddSetPsVar */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable type to next state.] + + Description [Sets a variable type to next state. The variable type is + used by lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetPiVar Cudd_bddSetPsVar Cudd_bddIsNsVar] + +******************************************************************************/ +int +Cudd_bddSetNsVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return (0); + dd->subtables[dd->perm[index]].varType = CUDD_VAR_NEXT_STATE; + return(1); + +} /* end of Cudd_bddSetNsVar */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is primary input.] + + Description [Checks whether a variable is primary input. Returns 1 if + the variable's type is primary input; 0 if the variable exists but is + not a primary input; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetPiVar Cudd_bddIsPsVar Cudd_bddIsNsVar] + +******************************************************************************/ +int +Cudd_bddIsPiVar( + DdManager *dd /* manager */, + int index /* variable index */) +{ + if (index >= dd->size || index < 0) return -1; + return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRIMARY_INPUT); + +} /* end of Cudd_bddIsPiVar */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is present state.] + + Description [Checks whether a variable is present state. Returns 1 if + the variable's type is present state; 0 if the variable exists but is + not a present state; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetPsVar Cudd_bddIsPiVar Cudd_bddIsNsVar] + +******************************************************************************/ +int +Cudd_bddIsPsVar( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return -1; + return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRESENT_STATE); + +} /* end of Cudd_bddIsPsVar */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is next state.] + + Description [Checks whether a variable is next state. Returns 1 if + the variable's type is present state; 0 if the variable exists but is + not a present state; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetNsVar Cudd_bddIsPiVar Cudd_bddIsPsVar] + +******************************************************************************/ +int +Cudd_bddIsNsVar( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return -1; + return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_NEXT_STATE); + +} /* end of Cudd_bddIsNsVar */ + + +/**Function******************************************************************** + + Synopsis [Sets a corresponding pair index for a given index.] + + Description [Sets a corresponding pair index for a given index. + These pair indices are present and next state variable. Returns 1 if + successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddReadPairIndex] + +******************************************************************************/ +int +Cudd_bddSetPairIndex( + DdManager *dd /* manager */, + int index /* variable index */, + int pairIndex /* corresponding variable index */) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].pairIndex = pairIndex; + return(1); + +} /* end of Cudd_bddSetPairIndex */ + + +/**Function******************************************************************** + + Synopsis [Reads a corresponding pair index for a given index.] + + Description [Reads a corresponding pair index for a given index. + These pair indices are present and next state variable. Returns the + corresponding variable index if the variable exists; -1 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetPairIndex] + +******************************************************************************/ +int +Cudd_bddReadPairIndex( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return -1; + return dd->subtables[dd->perm[index]].pairIndex; + +} /* end of Cudd_bddReadPairIndex */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable to be grouped.] + + Description [Sets a variable to be grouped. This function is used for + lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetVarHardGroup Cudd_bddResetVarToBeGrouped] + +******************************************************************************/ +int +Cudd_bddSetVarToBeGrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + if (dd->subtables[dd->perm[index]].varToBeGrouped <= CUDD_LAZY_SOFT_GROUP) { + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_SOFT_GROUP; + } + return(1); + +} /* end of Cudd_bddSetVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable to be a hard group.] + + Description [Sets a variable to be a hard group. This function is used + for lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetVarToBeGrouped Cudd_bddResetVarToBeGrouped + Cudd_bddIsVarHardGroup] + +******************************************************************************/ +int +Cudd_bddSetVarHardGroup( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_HARD_GROUP; + return(1); + +} /* end of Cudd_bddSetVarHardGrouped */ + + +/**Function******************************************************************** + + Synopsis [Resets a variable not to be grouped.] + + Description [Resets a variable not to be grouped. This function is + used for lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddSetVarToBeGrouped Cudd_bddSetVarHardGroup] + +******************************************************************************/ +int +Cudd_bddResetVarToBeGrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + if (dd->subtables[dd->perm[index]].varToBeGrouped <= + CUDD_LAZY_SOFT_GROUP) { + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_NONE; + } + return(1); + +} /* end of Cudd_bddResetVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is set to be grouped.] + + Description [Checks whether a variable is set to be grouped. This + function is used for lazy sifting.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_bddIsVarToBeGrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(-1); + if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP) + return(0); + else + return(dd->subtables[dd->perm[index]].varToBeGrouped); + +} /* end of Cudd_bddIsVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable to be ungrouped.] + + Description [Sets a variable to be ungrouped. This function is used + for lazy sifting. Returns 1 if successful; 0 otherwise.] + + SideEffects [modifies the manager] + + SeeAlso [Cudd_bddIsVarToBeUngrouped] + +******************************************************************************/ +int +Cudd_bddSetVarToBeUngrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_UNGROUP; + return(1); + +} /* end of Cudd_bddSetVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is set to be ungrouped.] + + Description [Checks whether a variable is set to be ungrouped. This + function is used for lazy sifting. Returns 1 if the variable is marked + to be ungrouped; 0 if the variable exists, but it is not marked to be + ungrouped; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetVarToBeUngrouped] + +******************************************************************************/ +int +Cudd_bddIsVarToBeUngrouped( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(-1); + return dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP; + +} /* end of Cudd_bddIsVarToBeGrouped */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is set to be in a hard group.] + + Description [Checks whether a variable is set to be in a hard group. This + function is used for lazy sifting. Returns 1 if the variable is marked + to be in a hard group; 0 if the variable exists, but it is not marked to be + in a hard group; -1 if the variable does not exist.] + + SideEffects [none] + + SeeAlso [Cudd_bddSetVarHardGroup] + +******************************************************************************/ +int +Cudd_bddIsVarHardGroup( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(-1); + if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_HARD_GROUP) + return(1); + return(0); + +} /* end of Cudd_bddIsVarToBeGrouped */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Fixes a variable group tree.] + + Description [] + + SideEffects [Changes the variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static void +fixVarTree( + MtrNode * treenode, + int * perm, + int size) +{ + treenode->index = treenode->low; + treenode->low = ((int) treenode->index < size) ? + perm[treenode->index] : treenode->index; + if (treenode->child != NULL) + fixVarTree(treenode->child, perm, size); + if (treenode->younger != NULL) + fixVarTree(treenode->younger, perm, size); + return; + +} /* end of fixVarTree */ + + +/**Function******************************************************************** + + Synopsis [Adds multiplicity groups to a ZDD variable group tree.] + + Description [Adds multiplicity groups to a ZDD variable group tree. + Returns 1 if successful; 0 otherwise. This function creates the groups + for set of ZDD variables (whose cardinality is given by parameter + multiplicity) that are created for each BDD variable in + Cudd_zddVarsFromBddVars. The crux of the matter is to determine the index + each new group. (The index of the first variable in the group.) + We first build all the groups for the children of a node, and then deal + with the ZDD variables that are directly attached to the node. The problem + for these is that the tree itself does not provide information on their + position inside the group. While we deal with the children of the node, + therefore, we keep track of all the positions they occupy. The remaining + positions in the tree can be freely used. Also, we keep track of all the + variables placed in the children. All the remaining variables are directly + attached to the group. We can then place any pair of variables not yet + grouped in any pair of available positions in the node.] + + SideEffects [Changes the variable group tree.] + + SeeAlso [Cudd_zddVarsFromBddVars] + +******************************************************************************/ +static int +addMultiplicityGroups( + DdManager *dd /* manager */, + MtrNode *treenode /* current tree node */, + int multiplicity /* how many ZDD vars per BDD var */, + char *vmask /* variable pairs for which a group has been already built */, + char *lmask /* levels for which a group has already been built*/) +{ + int startV, stopV, startL; + int i, j; + MtrNode *auxnode = treenode; + + while (auxnode != NULL) { + if (auxnode->child != NULL) { + addMultiplicityGroups(dd,auxnode->child,multiplicity,vmask,lmask); + } + /* Build remaining groups. */ + startV = dd->permZ[auxnode->index] / multiplicity; + startL = auxnode->low / multiplicity; + stopV = startV + auxnode->size / multiplicity; + /* Walk down vmask starting at startV and build missing groups. */ + for (i = startV, j = startL; i < stopV; i++) { + if (vmask[i] == 0) { + MtrNode *node; + while (lmask[j] == 1) j++; + node = Mtr_MakeGroup(auxnode, j * multiplicity, multiplicity, + MTR_FIXED); + if (node == NULL) { + return(0); + } + node->index = dd->invpermZ[i * multiplicity]; + vmask[i] = 1; + lmask[j] = 1; + } + } + auxnode = auxnode->younger; + } + return(1); + +} /* end of addMultiplicityGroups */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddAbs.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddAbs.c new file mode 100644 index 000000000..5e809c134 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddAbs.c @@ -0,0 +1,579 @@ +/**CFile*********************************************************************** + + FileName [cuddAddAbs.c] + + PackageName [cudd] + + Synopsis [Quantification functions for ADDs.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_addExistAbstract() +
                  • Cudd_addUnivAbstract() +
                  • Cudd_addOrAbstract() +
                  + Internal procedures included in this module: +
                    +
                  • cuddAddExistAbstractRecur() +
                  • cuddAddUnivAbstractRecur() +
                  • cuddAddOrAbstractRecur() +
                  + Static procedures included in this module: +
                    +
                  • addCheckPositiveCube() +
                  ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddAbs.c,v 1.16 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static DdNode *two; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int addCheckPositiveCube (DdManager *manager, DdNode *cube); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Existentially Abstracts all the variables in cube from f.] + + Description [Abstracts all the variables in cube from f by summing + over all possible values taken by the variables. Returns the + abstracted ADD.] + + SideEffects [None] + + SeeAlso [Cudd_addUnivAbstract Cudd_bddExistAbstract + Cudd_addOrAbstract] + +******************************************************************************/ +DdNode * +Cudd_addExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + two = cuddUniqueConst(manager,(CUDD_VALUE_TYPE) 2); + if (two == NULL) return(NULL); + cuddRef(two); + + if (addCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err,"Error: Can only abstract cubes"); + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddAddExistAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(manager,two); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,two); + cuddDeref(res); + + return(res); + +} /* end of Cudd_addExistAbstract */ + + +/**Function******************************************************************** + + Synopsis [Universally Abstracts all the variables in cube from f.] + + Description [Abstracts all the variables in cube from f by taking + the product over all possible values taken by the variable. Returns + the abstracted ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addExistAbstract Cudd_bddUnivAbstract + Cudd_addOrAbstract] + +******************************************************************************/ +DdNode * +Cudd_addUnivAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (addCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err,"Error: Can only abstract cubes"); + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddAddUnivAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_addUnivAbstract */ + + +/**Function******************************************************************** + + Synopsis [Disjunctively abstracts all the variables in cube from the + 0-1 ADD f.] + + Description [Abstracts all the variables in cube from the 0-1 ADD f + by taking the disjunction over all possible values taken by the + variables. Returns the abstracted ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addUnivAbstract Cudd_addExistAbstract] + +******************************************************************************/ +DdNode * +Cudd_addOrAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (addCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err,"Error: Can only abstract cubes"); + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddAddOrAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + return(res); + +} /* end of Cudd_addOrAbstract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addExistAbstract.] + + Description [Performs the recursive step of Cudd_addExistAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddAddExistAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *T, *E, *res, *res1, *res2, *zero; + + statLine(manager); + zero = DD_ZERO(manager); + + /* Cube is guaranteed to be a cube at this point. */ + if (f == zero || cuddIsConstant(cube)) { + return(f); + } + + /* Abstract a variable that does not appear in f => multiply by 2. */ + if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { + res1 = cuddAddExistAbstractRecur(manager, f, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + /* Use the "internal" procedure to be alerted in case of + ** dynamic reordering. If dynamic reordering occurs, we + ** have to abort the entire abstraction. + */ + res = cuddAddApplyRecur(manager,Cudd_addTimes,res1,two); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + cuddDeref(res); + return(res); + } + + if ((res = cuddCacheLookup2(manager, Cudd_addExistAbstract, f, cube)) != NULL) { + return(res); + } + + T = cuddT(f); + E = cuddE(f); + + /* If the two indices are the same, so are their levels. */ + if (f->index == cube->index) { + res1 = cuddAddExistAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddExistAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddAddApplyRecur(manager, Cudd_addPlus, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); + cuddDeref(res); + return(res); + } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ + res1 = cuddAddExistAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddExistAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); + return(res); + } + +} /* end of cuddAddExistAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addUnivAbstract.] + + Description [Performs the recursive step of Cudd_addUnivAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddAddUnivAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *T, *E, *res, *res1, *res2, *one, *zero; + + statLine(manager); + one = DD_ONE(manager); + zero = DD_ZERO(manager); + + /* Cube is guaranteed to be a cube at this point. + ** zero and one are the only constatnts c such that c*c=c. + */ + if (f == zero || f == one || cube == one) { + return(f); + } + + /* Abstract a variable that does not appear in f. */ + if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { + res1 = cuddAddUnivAbstractRecur(manager, f, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + /* Use the "internal" procedure to be alerted in case of + ** dynamic reordering. If dynamic reordering occurs, we + ** have to abort the entire abstraction. + */ + res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res1); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + cuddDeref(res); + return(res); + } + + if ((res = cuddCacheLookup2(manager, Cudd_addUnivAbstract, f, cube)) != NULL) { + return(res); + } + + T = cuddT(f); + E = cuddE(f); + + /* If the two indices are the same, so are their levels. */ + if (f->index == cube->index) { + res1 = cuddAddUnivAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddUnivAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); + cuddDeref(res); + return(res); + } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ + res1 = cuddAddUnivAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddUnivAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); + return(res); + } + +} /* end of cuddAddUnivAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addOrAbstract.] + + Description [Performs the recursive step of Cudd_addOrAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddAddOrAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *T, *E, *res, *res1, *res2, *one; + + statLine(manager); + one = DD_ONE(manager); + + /* Cube is guaranteed to be a cube at this point. */ + if (cuddIsConstant(f) || cube == one) { + return(f); + } + + /* Abstract a variable that does not appear in f. */ + if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { + res = cuddAddOrAbstractRecur(manager, f, cuddT(cube)); + return(res); + } + + if ((res = cuddCacheLookup2(manager, Cudd_addOrAbstract, f, cube)) != NULL) { + return(res); + } + + T = cuddT(f); + E = cuddE(f); + + /* If the two indices are the same, so are their levels. */ + if (f->index == cube->index) { + res1 = cuddAddOrAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + if (res1 != one) { + res2 = cuddAddOrAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddAddApplyRecur(manager, Cudd_addOr, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + } else { + res = res1; + } + cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); + cuddDeref(res); + return(res); + } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ + res1 = cuddAddOrAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddAddOrAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); + return(res); + } + +} /* end of cuddAddOrAbstractRecur */ + + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Checks whether cube is an ADD representing the product + of positive literals.] + + Description [Checks whether cube is an ADD representing the product of + positive literals. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +addCheckPositiveCube( + DdManager * manager, + DdNode * cube) +{ + if (Cudd_IsComplement(cube)) return(0); + if (cube == DD_ONE(manager)) return(1); + if (cuddIsConstant(cube)) return(0); + if (cuddE(cube) == DD_ZERO(manager)) { + return(addCheckPositiveCube(manager, cuddT(cube))); + } + return(0); + +} /* end of addCheckPositiveCube */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddApply.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddApply.c new file mode 100644 index 000000000..9a4d2179d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddApply.c @@ -0,0 +1,1121 @@ +/**CFile*********************************************************************** + + FileName [cuddAddApply.c] + + PackageName [cudd] + + Synopsis [Apply functions for ADDs and their operators.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_addApply() +
                  • Cudd_addMonadicApply() +
                  • Cudd_addPlus() +
                  • Cudd_addTimes() +
                  • Cudd_addThreshold() +
                  • Cudd_addSetNZ() +
                  • Cudd_addDivide() +
                  • Cudd_addMinus() +
                  • Cudd_addMinimum() +
                  • Cudd_addMaximum() +
                  • Cudd_addOneZeroMaximum() +
                  • Cudd_addDiff() +
                  • Cudd_addAgreement() +
                  • Cudd_addOr() +
                  • Cudd_addNand() +
                  • Cudd_addNor() +
                  • Cudd_addXor() +
                  • Cudd_addXnor() +
                  + Internal procedures included in this module: +
                    +
                  • cuddAddApplyRecur() +
                  • cuddAddMonadicApplyRecur() +
                  ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.19 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Applies op to the corresponding discriminants of f and g.] + + Description [Applies op to the corresponding discriminants of f and g. + Returns a pointer to the result if succssful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addMonadicApply Cudd_addPlus Cudd_addTimes + Cudd_addThreshold Cudd_addSetNZ Cudd_addDivide Cudd_addMinus Cudd_addMinimum + Cudd_addMaximum Cudd_addOneZeroMaximum Cudd_addDiff Cudd_addAgreement + Cudd_addOr Cudd_addNand Cudd_addNor Cudd_addXor Cudd_addXnor] + +******************************************************************************/ +DdNode * +Cudd_addApply( + DdManager * dd, + DD_AOP op, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddApplyRecur(dd,op,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addApply */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point addition.] + + Description [Integer and floating point addition. Returns NULL if not + a terminal case; f+g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addPlus( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *res; + DdNode *F, *G; + CUDD_VALUE_TYPE value; + + F = *f; G = *g; + if (F == DD_ZERO(dd)) return(G); + if (G == DD_ZERO(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + value = cuddV(F)+cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); + } + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addPlus */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point multiplication.] + + Description [Integer and floating point multiplication. Returns NULL + if not a terminal case; f * g otherwise. This function can be used also + to take the AND of two 0-1 ADDs.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addTimes( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *res; + DdNode *F, *G; + CUDD_VALUE_TYPE value; + + F = *f; G = *g; + if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ZERO(dd)); + if (F == DD_ONE(dd)) return(G); + if (G == DD_ONE(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + value = cuddV(F)*cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); + } + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addTimes */ + + +/**Function******************************************************************** + + Synopsis [f if f>=g; 0 if f<g.] + + Description [Threshold operator for Apply (f if f >=g; 0 if f<g). + Returns NULL if not a terminal case; f op g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addThreshold( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G || F == DD_PLUS_INFINITY(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F) >= cuddV(G)) { + return(F); + } else { + return(DD_ZERO(dd)); + } + } + return(NULL); + +} /* end of Cudd_addThreshold */ + + +/**Function******************************************************************** + + Synopsis [This operator sets f to the value of g wherever g != 0.] + + Description [This operator sets f to the value of g wherever g != 0. + Returns NULL if not a terminal case; f op g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addSetNZ( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(F); + if (F == DD_ZERO(dd)) return(G); + if (G == DD_ZERO(dd)) return(F); + if (cuddIsConstant(G)) return(G); + return(NULL); + +} /* end of Cudd_addSetNZ */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point division.] + + Description [Integer and floating point division. Returns NULL if not + a terminal case; f / g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addDivide( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *res; + DdNode *F, *G; + CUDD_VALUE_TYPE value; + + F = *f; G = *g; + /* We would like to use F == G -> F/G == 1, but F and G may + ** contain zeroes. */ + if (F == DD_ZERO(dd)) return(DD_ZERO(dd)); + if (G == DD_ONE(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + value = cuddV(F)/cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); + } + return(NULL); + +} /* end of Cudd_addDivide */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point subtraction.] + + Description [Integer and floating point subtraction. Returns NULL if + not a terminal case; f - g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addMinus( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *res; + DdNode *F, *G; + CUDD_VALUE_TYPE value; + + F = *f; G = *g; + if (F == G) return(DD_ZERO(dd)); + if (F == DD_ZERO(dd)) return(cuddAddNegateRecur(dd,G)); + if (G == DD_ZERO(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + value = cuddV(F)-cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); + } + return(NULL); + +} /* end of Cudd_addMinus */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point min.] + + Description [Integer and floating point min for Cudd_addApply. + Returns NULL if not a terminal case; min(f,g) otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addMinimum( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == DD_PLUS_INFINITY(dd)) return(G); + if (G == DD_PLUS_INFINITY(dd)) return(F); + if (F == G) return(F); +#if 0 + /* These special cases probably do not pay off. */ + if (F == DD_MINUS_INFINITY(dd)) return(F); + if (G == DD_MINUS_INFINITY(dd)) return(G); +#endif + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F) <= cuddV(G)) { + return(F); + } else { + return(G); + } + } + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addMinimum */ + + +/**Function******************************************************************** + + Synopsis [Integer and floating point max.] + + Description [Integer and floating point max for Cudd_addApply. + Returns NULL if not a terminal case; max(f,g) otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addMaximum( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(F); + if (F == DD_MINUS_INFINITY(dd)) return(G); + if (G == DD_MINUS_INFINITY(dd)) return(F); +#if 0 + /* These special cases probably do not pay off. */ + if (F == DD_PLUS_INFINITY(dd)) return(F); + if (G == DD_PLUS_INFINITY(dd)) return(G); +#endif + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F) >= cuddV(G)) { + return(F); + } else { + return(G); + } + } + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addMaximum */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if f > g and 0 otherwise.] + + Description [Returns 1 if f > g and 0 otherwise. Used in + conjunction with Cudd_addApply. Returns NULL if not a terminal + case.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addOneZeroMaximum( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + + if (*f == *g) return(DD_ZERO(dd)); + if (*g == DD_PLUS_INFINITY(dd)) + return DD_ZERO(dd); + if (cuddIsConstant(*f) && cuddIsConstant(*g)) { + if (cuddV(*f) > cuddV(*g)) { + return(DD_ONE(dd)); + } else { + return(DD_ZERO(dd)); + } + } + + return(NULL); + +} /* end of Cudd_addOneZeroMaximum */ + + +/**Function******************************************************************** + + Synopsis [Returns plusinfinity if f=g; returns min(f,g) if f!=g.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is plusinfinity if f=g; min(f,g) if f!=g.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addDiff( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_PLUS_INFINITY(dd)); + if (F == DD_PLUS_INFINITY(dd)) return(G); + if (G == DD_PLUS_INFINITY(dd)) return(F); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F) != cuddV(G)) { + if (cuddV(F) < cuddV(G)) { + return(F); + } else { + return(G); + } + } else { + return(DD_PLUS_INFINITY(dd)); + } + } + return(NULL); + +} /* end of Cudd_addDiff */ + + +/**Function******************************************************************** + + Synopsis [f if f==g; background if f!=g.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is f if f==g; background if f!=g.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addAgreement( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(F); + if (F == dd->background) return(F); + if (G == dd->background) return(G); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(dd->background); + return(NULL); + +} /* end of Cudd_addAgreement */ + + +/**Function******************************************************************** + + Synopsis [Disjunction of two 0-1 ADDs.] + + Description [Disjunction of two 0-1 ADDs. Returns NULL + if not a terminal case; f OR g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addOr( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ONE(dd)); + if (cuddIsConstant(F)) return(G); + if (cuddIsConstant(G)) return(F); + if (F == G) return(F); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addOr */ + + +/**Function******************************************************************** + + Synopsis [NAND of two 0-1 ADDs.] + + Description [NAND of two 0-1 ADDs. Returns NULL + if not a terminal case; f NAND g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addNand( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addNand */ + + +/**Function******************************************************************** + + Synopsis [NOR of two 0-1 ADDs.] + + Description [NOR of two 0-1 ADDs. Returns NULL + if not a terminal case; f NOR g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addNor( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ZERO(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ONE(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addNor */ + + +/**Function******************************************************************** + + Synopsis [XOR of two 0-1 ADDs.] + + Description [XOR of two 0-1 ADDs. Returns NULL + if not a terminal case; f XOR g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addXor( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ZERO(dd)); + if (F == DD_ONE(dd) && G == DD_ZERO(dd)) return(DD_ONE(dd)); + if (G == DD_ONE(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addXor */ + + +/**Function******************************************************************** + + Synopsis [XNOR of two 0-1 ADDs.] + + Description [XNOR of two 0-1 ADDs. Returns NULL + if not a terminal case; f XNOR g otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addXnor( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ONE(dd)); + if (F == DD_ONE(dd) && G == DD_ONE(dd)) return(DD_ONE(dd)); + if (G == DD_ZERO(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addXnor */ + + +/**Function******************************************************************** + + Synopsis [Applies op to the discriminants of f.] + + Description [Applies op to the discriminants of f. + Returns a pointer to the result if succssful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply Cudd_addLog] + +******************************************************************************/ +DdNode * +Cudd_addMonadicApply( + DdManager * dd, + DD_MAOP op, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddMonadicApplyRecur(dd,op,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addMonadicApply */ + + +/**Function******************************************************************** + + Synopsis [Natural logarithm of an ADD.] + + Description [Natural logarithm of an ADDs. Returns NULL + if not a terminal case; log(f) otherwise. The discriminants of f must + be positive double's.] + + SideEffects [None] + + SeeAlso [Cudd_addMonadicApply] + +******************************************************************************/ +DdNode * +Cudd_addLog( + DdManager * dd, + DdNode * f) +{ + if (cuddIsConstant(f)) { + CUDD_VALUE_TYPE value = log(cuddV(f)); + DdNode *res = cuddUniqueConst(dd,value); + return(res); + } + return(NULL); + +} /* end of Cudd_addLog */ + +/**Function******************************************************************** + + Synopsis [1 if f==g; 0 otherwise.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is 1 if f==g; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addEquals( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addEquals */ + + +/**Function******************************************************************** + + Synopsis [1 if f!=g; 0 otherwise.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is 1 if f!=g; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addNotEquals( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ZERO(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ONE(dd)); + if (F > G) { /* swap f and g */ + *f = G; + *g = F; + } + return(NULL); + +} /* end of Cudd_addNotEquals */ + +/**Function******************************************************************** + + Synopsis [1 if f>g; 0 otherwise.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is 1 if f>g; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addGreaterThan( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ZERO(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F)>cuddV(G)) return (DD_ONE(dd)); else return (DD_ZERO(dd)); + } + return(NULL); + +} /* end of Cudd_addGreaterThan */ + + +/**Function******************************************************************** + + Synopsis [1 if f>=g; 0 otherwise.] + + Description [Returns NULL if not a terminal case; f op g otherwise, + where f op g is 1 if f>=g; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addGreaterThanEquals( + DdManager * dd, + DdNode ** f, + DdNode ** g) +{ + DdNode *F, *G; + + F = *f; G = *g; + if (F == G) return(DD_ONE(dd)); + if (cuddIsConstant(F) && cuddIsConstant(G)) { + if (cuddV(F)>=cuddV(G)) return (DD_ONE(dd)); else return (DD_ZERO(dd)); + } + return(NULL); + +} /* end of Cudd_addGreaterThanEquals */ + + +/**Function******************************************************************** + + Synopsis [1 if findex); + gord = cuddI(dd,g->index); + if (ford <= gord) { + index = f->index; + fv = cuddT(f); + fvn = cuddE(f); + } else { + index = g->index; + fv = fvn = f; + } + if (gord <= ford) { + gv = cuddT(g); + gvn = cuddE(g); + } else { + gv = gvn = g; + } + + T = cuddAddApplyRecur(dd,op,fv,gv); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddApplyRecur(dd,op,fvn,gvn); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + + res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,cacheOp,f,g,res); + + return(res); + +} /* end of cuddAddApplyRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addMonadicApply.] + + Description [Performs the recursive step of Cudd_addMonadicApply. Returns a + pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddAddApplyRecur] + +******************************************************************************/ +DdNode * +cuddAddMonadicApplyRecur( + DdManager * dd, + DD_MAOP op, + DdNode * f) +{ + DdNode *res, *ft, *fe, *T, *E; + unsigned int index; + + /* Check terminal cases. */ + statLine(dd); + res = (*op)(dd,f); + if (res != NULL) return(res); + + /* Check cache. */ + res = cuddCacheLookup1(dd,op,f); + if (res != NULL) return(res); + + /* Recursive step. */ + index = f->index; + ft = cuddT(f); + fe = cuddE(f); + + T = cuddAddMonadicApplyRecur(dd,op,ft); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddMonadicApplyRecur(dd,op,fe); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + + res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,op,f,res); + + return(res); + +} /* end of cuddAddMonadicApplyRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddFind.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddFind.c new file mode 100644 index 000000000..1352a87ff --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddFind.c @@ -0,0 +1,316 @@ +/**CFile*********************************************************************** + + FileName [cuddAddFind.c] + + PackageName [cudd] + + Synopsis [Functions to find maximum and minimum in an ADD and to + extract the i-th bit.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_addFindMax() +
                  • Cudd_addFindMin() +
                  • Cudd_addIthBit() +
                  + Static functions included in this module: +
                    +
                  • addDoIthBit() +
                  ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.9 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addDoIthBit (DdManager *dd, DdNode *f, DdNode *index); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Finds the maximum discriminant of f.] + + Description [Returns a pointer to a constant ADD.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addFindMax( + DdManager * dd, + DdNode * f) +{ + DdNode *t, *e, *res; + + statLine(dd); + if (cuddIsConstant(f)) { + return(f); + } + + res = cuddCacheLookup1(dd,Cudd_addFindMax,f); + if (res != NULL) { + return(res); + } + + t = Cudd_addFindMax(dd,cuddT(f)); + if (t == DD_PLUS_INFINITY(dd)) return(t); + + e = Cudd_addFindMax(dd,cuddE(f)); + + res = (cuddV(t) >= cuddV(e)) ? t : e; + + cuddCacheInsert1(dd,Cudd_addFindMax,f,res); + + return(res); + +} /* end of Cudd_addFindMax */ + + +/**Function******************************************************************** + + Synopsis [Finds the minimum discriminant of f.] + + Description [Returns a pointer to a constant ADD.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addFindMin( + DdManager * dd, + DdNode * f) +{ + DdNode *t, *e, *res; + + statLine(dd); + if (cuddIsConstant(f)) { + return(f); + } + + res = cuddCacheLookup1(dd,Cudd_addFindMin,f); + if (res != NULL) { + return(res); + } + + t = Cudd_addFindMin(dd,cuddT(f)); + if (t == DD_MINUS_INFINITY(dd)) return(t); + + e = Cudd_addFindMin(dd,cuddE(f)); + + res = (cuddV(t) <= cuddV(e)) ? t : e; + + cuddCacheInsert1(dd,Cudd_addFindMin,f,res); + + return(res); + +} /* end of Cudd_addFindMin */ + + +/**Function******************************************************************** + + Synopsis [Extracts the i-th bit from an ADD.] + + Description [Produces an ADD from another ADD by replacing all + discriminants whose i-th bit is equal to 1 with 1, and all other + discriminants with 0. The i-th bit refers to the integer + representation of the leaf value. If the value is has a fractional + part, it is ignored. Repeated calls to this procedure allow one to + transform an integer-valued ADD into an array of ADDs, one for each + bit of the leaf values. Returns a pointer to the resulting ADD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddIthBit] + +******************************************************************************/ +DdNode * +Cudd_addIthBit( + DdManager * dd, + DdNode * f, + int bit) +{ + DdNode *res; + DdNode *index; + + /* Use a constant node to remember the bit, so that we can use the + ** global cache. + */ + index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit); + if (index == NULL) return(NULL); + cuddRef(index); + + do { + dd->reordered = 0; + res = addDoIthBit(dd, f, index); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, index); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, index); + cuddDeref(res); + return(res); + +} /* end of Cudd_addIthBit */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addIthBit.] + + Description [Performs the recursive step for Cudd_addIthBit. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +addDoIthBit( + DdManager * dd, + DdNode * f, + DdNode * index) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int mask, value; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + mask = 1 << ((int) cuddV(index)); + value = (int) cuddV(f); + return((value & mask) == 0 ? DD_ZERO(dd) : DD_ONE(dd)); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addDoIthBit,f,index); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addDoIthBit(dd,fv,index); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addDoIthBit(dd,fvn,index); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addDoIthBit,f,index,res); + + return(res); + +} /* end of addDoIthBit */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddInv.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddInv.c new file mode 100644 index 000000000..454aa811d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddInv.c @@ -0,0 +1,201 @@ +/**CFile*********************************************************************** + + FileName [cuddAddInv.c] + + PackageName [cudd] + + Synopsis [Function to compute the scalar inverse of an ADD.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_addScalarInverse() +
                  + Internal procedures included in this module: +
                    +
                  • cuddAddScalarInverseRecur() +
                  ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddInv.c,v 1.10 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the scalar inverse of an ADD.] + + Description [Computes an n ADD where the discriminants are the + multiplicative inverses of the corresponding discriminants of the + argument ADD. Returns a pointer to the resulting ADD in case of + success. Returns NULL if any discriminants smaller than epsilon is + encountered.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addScalarInverse( + DdManager * dd, + DdNode * f, + DdNode * epsilon) +{ + DdNode *res; + + if (!cuddIsConstant(epsilon)) { + (void) fprintf(dd->err,"Invalid epsilon\n"); + return(NULL); + } + do { + dd->reordered = 0; + res = cuddAddScalarInverseRecur(dd,f,epsilon); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addScalarInverse */ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of addScalarInverse.] + + Description [Returns a pointer to the resulting ADD in case of + success. Returns NULL if any discriminants smaller than epsilon is + encountered.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddAddScalarInverseRecur( + DdManager * dd, + DdNode * f, + DdNode * epsilon) +{ + DdNode *t, *e, *res; + CUDD_VALUE_TYPE value; + + statLine(dd); + if (cuddIsConstant(f)) { + if (ddAbs(cuddV(f)) < cuddV(epsilon)) return(NULL); + value = 1.0 / cuddV(f); + res = cuddUniqueConst(dd,value); + return(res); + } + + res = cuddCacheLookup2(dd,Cudd_addScalarInverse,f,epsilon); + if (res != NULL) return(res); + + t = cuddAddScalarInverseRecur(dd,cuddT(f),epsilon); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddAddScalarInverseRecur(dd,cuddE(f),epsilon); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + res = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd,Cudd_addScalarInverse,f,epsilon,res); + + return(res); + +} /* end of cuddAddScalarInverseRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddIte.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddIte.c new file mode 100644 index 000000000..a6e84c54c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddIte.c @@ -0,0 +1,639 @@ +/**CFile*********************************************************************** + + FileName [cuddAddIte.c] + + PackageName [cudd] + + Synopsis [ADD ITE function and satellites.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_addIte() +
                  • Cudd_addIteConstant() +
                  • Cudd_addEvalConst() +
                  • Cudd_addCmpl() +
                  • Cudd_addLeq() +
                  + Internal procedures included in this module: +
                    +
                  • cuddAddIteRecur() +
                  • cuddAddCmplRecur() +
                  + Static procedures included in this module: +
                    +
                  • addVarToConst() +
                  ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.16 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void addVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements ITE(f,g,h).] + + Description [Implements ITE(f,g,h). This procedure assumes that f is + a 0-1 ADD. Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addIteConstant Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddIteRecur(dd,f,g,h); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addIte */ + + +/**Function******************************************************************** + + Synopsis [Implements ITEconstant for ADDs.] + + Description [Implements ITEconstant for ADDs. f must be a 0-1 ADD. + Returns a pointer to the resulting ADD (which may or may not be + constant) or DD_NON_CONSTANT. No new nodes are created. This function + can be used, for instance, to check that g has a constant value + (specified by h) whenever f is 1. If the constant value is unknown, + then one should use Cudd_addEvalConst.] + + SideEffects [None] + + SeeAlso [Cudd_addIte Cudd_addEvalConst Cudd_bddIteConstant] + +******************************************************************************/ +DdNode * +Cudd_addIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *one,*zero; + DdNode *Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*r,*t,*e; + unsigned int topf,topg,toph,v; + + statLine(dd); + /* Trivial cases. */ + if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ + return(g); + } + if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ + return(h); + } + + /* From now on, f is known not to be a constant. */ + addVarToConst(f,&g,&h,one,zero); + + /* Check remaining one variable cases. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } + if (cuddIsConstant(g) && cuddIsConstant(h)) { + return(DD_NON_CONSTANT); + } + + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + toph = cuddI(dd,h->index); + v = ddMin(topg,toph); + + /* ITE(F,G,H) = (x,G,H) (non constant) if F = (x,1,0), x < top(G,H). */ + if (topf < v && cuddIsConstant(cuddT(f)) && cuddIsConstant(cuddE(f))) { + return(DD_NON_CONSTANT); + } + + /* Check cache. */ + r = cuddConstantLookup(dd,DD_ADD_ITE_CONSTANT_TAG,f,g,h); + if (r != NULL) { + return(r); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf,v); /* v = top_var(F,G,H) */ + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg == v) { + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + if (toph == v) { + Hv = cuddT(h); Hnv = cuddE(h); + } else { + Hv = Hnv = h; + } + + /* Recursive step. */ + t = Cudd_addIteConstant(dd,Fv,Gv,Hv); + if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + e = Cudd_addIteConstant(dd,Fnv,Gnv,Hnv); + if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, t); + return(t); + +} /* end of Cudd_addIteConstant */ + + +/**Function******************************************************************** + + Synopsis [Checks whether ADD g is constant whenever ADD f is 1.] + + Description [Checks whether ADD g is constant whenever ADD f is 1. f + must be a 0-1 ADD. Returns a pointer to the resulting ADD (which may + or may not be constant) or DD_NON_CONSTANT. If f is identically 0, + the check is assumed to be successful, and the background value is + returned. No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_addIteConstant Cudd_addLeq] + +******************************************************************************/ +DdNode * +Cudd_addEvalConst( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *zero; + DdNode *Fv,*Fnv,*Gv,*Gnv,*r,*t,*e; + unsigned int topf,topg; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + statLine(dd); + /* Terminal cases. */ + if (f == DD_ONE(dd) || cuddIsConstant(g)) { + return(g); + } + if (f == (zero = DD_ZERO(dd))) { + return(dd->background); + } + +#ifdef DD_DEBUG + assert(!cuddIsConstant(f)); +#endif + /* From now on, f and g are known not to be constants. */ + + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + + /* Check cache. */ + r = cuddConstantLookup(dd,DD_ADD_EVAL_CONST_TAG,f,g,g); + if (r != NULL) { + return(r); + } + + /* Compute cofactors. */ + if (topf <= topg) { + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg <= topf) { + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + + /* Recursive step. */ + if (Fv != zero) { + t = Cudd_addEvalConst(dd,Fv,Gv); + if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + if (Fnv != zero) { + e = Cudd_addEvalConst(dd,Fnv,Gnv); + if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + } + cuddCacheInsert2(dd,Cudd_addEvalConst,f,g,t); + return(t); + } else { /* Fnv must be != zero */ + e = Cudd_addEvalConst(dd,Fnv,Gnv); + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e); + return(e); + } + +} /* end of Cudd_addEvalConst */ + + +/**Function******************************************************************** + + Synopsis [Computes the complement of an ADD a la C language.] + + Description [Computes the complement of an ADD a la C language: The + complement of 0 is 1 and the complement of everything else is 0. + Returns a pointer to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNegate] + +******************************************************************************/ +DdNode * +Cudd_addCmpl( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddCmplRecur(dd,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addCmpl */ + + +/**Function******************************************************************** + + Synopsis [Determines whether f is less than or equal to g.] + + Description [Returns 1 if f is less than or equal to g; 0 otherwise. + No new nodes are created. This procedure works for arbitrary ADDs. + For 0-1 ADDs Cudd_addEvalConst is more efficient.] + + SideEffects [None] + + SeeAlso [Cudd_addIteConstant Cudd_addEvalConst Cudd_bddLeq] + +******************************************************************************/ +int +Cudd_addLeq( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *tmp, *fv, *fvn, *gv, *gvn; + unsigned int topf, topg, res; + + /* Terminal cases. */ + if (f == g) return(1); + + statLine(dd); + if (cuddIsConstant(f)) { + if (cuddIsConstant(g)) return(cuddV(f) <= cuddV(g)); + if (f == DD_MINUS_INFINITY(dd)) return(1); + if (f == DD_PLUS_INFINITY(dd)) return(0); /* since f != g */ + } + if (g == DD_PLUS_INFINITY(dd)) return(1); + if (g == DD_MINUS_INFINITY(dd)) return(0); /* since f != g */ + + /* Check cache. */ + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq,f,g); + if (tmp != NULL) { + return(tmp == DD_ONE(dd)); + } + + /* Compute cofactors. One of f and g is not constant. */ + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + if (topf <= topg) { + fv = cuddT(f); fvn = cuddE(f); + } else { + fv = fvn = f; + } + if (topg <= topf) { + gv = cuddT(g); gvn = cuddE(g); + } else { + gv = gvn = g; + } + + res = Cudd_addLeq(dd,fvn,gvn) && Cudd_addLeq(dd,fv,gv); + + /* Store result in cache and return. */ + cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq,f,g, + Cudd_NotCond(DD_ONE(dd),res==0)); + return(res); + +} /* end of Cudd_addLeq */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addIte(f,g,h).] + + Description [Implements the recursive step of Cudd_addIte(f,g,h). + Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addIte] + +******************************************************************************/ +DdNode * +cuddAddIteRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *one,*zero; + DdNode *r,*Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*t,*e; + unsigned int topf,topg,toph,v; + int index; + + statLine(dd); + /* Trivial cases. */ + + /* One variable cases. */ + if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ + return(g); + } + if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ + return(h); + } + + /* From now on, f is known to not be a constant. */ + addVarToConst(f,&g,&h,one,zero); + + /* Check remaining one variable cases. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } + + if (g == one) { /* ITE(F,1,0) = F */ + if (h == zero) return(f); + } + + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + toph = cuddI(dd,h->index); + v = ddMin(topg,toph); + + /* A shortcut: ITE(F,G,H) = (x,G,H) if F=(x,1,0), x < top(G,H). */ + if (topf < v && cuddT(f) == one && cuddE(f) == zero) { + r = cuddUniqueInter(dd,(int)f->index,g,h); + return(r); + } + if (topf < v && cuddT(f) == zero && cuddE(f) == one) { + r = cuddUniqueInter(dd,(int)f->index,h,g); + return(r); + } + + /* Check cache. */ + r = cuddCacheLookup(dd,DD_ADD_ITE_TAG,f,g,h); + if (r != NULL) { + return(r); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf,v); /* v = top_var(F,G,H) */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg == v) { + index = g->index; + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + if (toph == v) { + index = h->index; + Hv = cuddT(h); Hnv = cuddE(h); + } else { + Hv = Hnv = h; + } + + /* Recursive step. */ + t = cuddAddIteRecur(dd,Fv,Gv,Hv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddAddIteRecur(dd,Fnv,Gnv,Hnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert(dd,DD_ADD_ITE_TAG,f,g,h,r); + + return(r); + +} /* end of cuddAddIteRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addCmpl.] + + Description [Performs the recursive step of Cudd_addCmpl. Returns a + pointer to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCmpl] + +******************************************************************************/ +DdNode * +cuddAddCmplRecur( + DdManager * dd, + DdNode * f) +{ + DdNode *one,*zero; + DdNode *r,*Fv,*Fnv,*t,*e; + + statLine(dd); + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + if (cuddIsConstant(f)) { + if (f == zero) { + return(one); + } else { + return(zero); + } + } + r = cuddCacheLookup1(dd,Cudd_addCmpl,f); + if (r != NULL) { + return(r); + } + Fv = cuddT(f); + Fnv = cuddE(f); + t = cuddAddCmplRecur(dd,Fv); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddAddCmplRecur(dd,Fnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + r = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + cuddCacheInsert1(dd,Cudd_addCmpl,f,r); + return(r); + +} /* end of cuddAddCmplRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Replaces variables with constants if possible (part of + canonical form).] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static void +addVarToConst( + DdNode * f, + DdNode ** gp, + DdNode ** hp, + DdNode * one, + DdNode * zero) +{ + DdNode *g = *gp; + DdNode *h = *hp; + + if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + *gp = one; + } + + if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + *hp = zero; + } + +} /* end of addVarToConst */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddNeg.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddNeg.c new file mode 100644 index 000000000..92c1cd71f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddNeg.c @@ -0,0 +1,290 @@ +/**CFile*********************************************************************** + + FileName [cuddAddNeg.c] + + PackageName [cudd] + + Synopsis [Function to compute the negation of an ADD.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_addNegate() +
                  • Cudd_addRoundOff() +
                  + Internal procedures included in this module: +
                    +
                  • cuddAddNegateRecur() +
                  • cuddAddRoundOffRecur() +
                  ] + + Author [Fabio Somenzi, Balakrishna Kumthekar] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddNeg.c,v 1.14 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Computes the additive inverse of an ADD.] + + Description [Computes the additive inverse of an ADD. Returns a pointer + to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCmpl] + +******************************************************************************/ +DdNode * +Cudd_addNegate( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddNegateRecur(dd,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addNegate */ + + +/**Function******************************************************************** + + Synopsis [Rounds off the discriminants of an ADD.] + + Description [Rounds off the discriminants of an ADD. The discriminants are + rounded off to N digits after the decimal. Returns a pointer to the result + ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addRoundOff( + DdManager * dd, + DdNode * f, + int N) +{ + DdNode *res; + double trunc = pow(10.0,(double)N); + + do { + dd->reordered = 0; + res = cuddAddRoundOffRecur(dd,f,trunc); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addRoundOff */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addNegate.] + + Description [Implements the recursive step of Cudd_addNegate. + Returns a pointer to the result.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddAddNegateRecur( + DdManager * dd, + DdNode * f) +{ + DdNode *res, + *fv, *fvn, + *T, *E; + + statLine(dd); + /* Check terminal cases. */ + if (cuddIsConstant(f)) { + res = cuddUniqueConst(dd,-cuddV(f)); + return(res); + } + + /* Check cache */ + res = cuddCacheLookup1(dd,Cudd_addNegate,f); + if (res != NULL) return(res); + + /* Recursive Step */ + fv = cuddT(f); + fvn = cuddE(f); + T = cuddAddNegateRecur(dd,fv); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddNegateRecur(dd,fvn); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,Cudd_addNegate,f,res); + + return(res); + +} /* end of cuddAddNegateRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addRoundOff.] + + Description [Implements the recursive step of Cudd_addRoundOff. + Returns a pointer to the result.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddAddRoundOffRecur( + DdManager * dd, + DdNode * f, + double trunc) +{ + + DdNode *res, *fv, *fvn, *T, *E; + double n; + DD_CTFP1 cacheOp; + + statLine(dd); + if (cuddIsConstant(f)) { + n = ceil(cuddV(f)*trunc)/trunc; + res = cuddUniqueConst(dd,n); + return(res); + } + cacheOp = (DD_CTFP1) Cudd_addRoundOff; + res = cuddCacheLookup1(dd,cacheOp,f); + if (res != NULL) { + return(res); + } + /* Recursive Step */ + fv = cuddT(f); + fvn = cuddE(f); + T = cuddAddRoundOffRecur(dd,fv,trunc); + if (T == NULL) { + return(NULL); + } + cuddRef(T); + E = cuddAddRoundOffRecur(dd,fvn,trunc); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,cacheOp,f,res); + return(res); + +} /* end of cuddAddRoundOffRecur */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddWalsh.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddWalsh.c new file mode 100644 index 000000000..146b1d313 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAddWalsh.c @@ -0,0 +1,391 @@ +/**CFile*********************************************************************** + + FileName [cuddAddWalsh.c] + + PackageName [cudd] + + Synopsis [Functions that generate Walsh matrices and residue + functions in ADD form.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_addWalsh() +
                  • Cudd_addResidue() +
                  + Static procedures included in this module: +
                    +
                  • addWalshInt() +
                  ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAddWalsh.c,v 1.11 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addWalshInt (DdManager *dd, DdNode **x, DdNode **y, int n); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Generates a Walsh matrix in ADD form.] + + Description [Generates a Walsh matrix in ADD form. Returns a pointer + to the matrixi if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addWalsh( + DdManager * dd, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = addWalshInt(dd, x, y, n); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addWalsh */ + + +/**Function******************************************************************** + + Synopsis [Builds an ADD for the residue modulo m of an n-bit + number.] + + Description [Builds an ADD for the residue modulo m of an n-bit + number. The modulus must be at least 2, and the number of bits at + least 1. Parameter options specifies whether the MSB should be on top + or the LSB; and whther the number whose residue is computed is in + two's complement notation or not. The macro CUDD_RESIDUE_DEFAULT + specifies LSB on top and unsigned number. The macro CUDD_RESIDUE_MSB + specifies MSB on top, and the macro CUDD_RESIDUE_TC specifies two's + complement residue. To request MSB on top and two's complement residue + simultaneously, one can OR the two macros: + CUDD_RESIDUE_MSB | CUDD_RESIDUE_TC. + Cudd_addResidue returns a pointer to the resulting ADD if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addResidue( + DdManager * dd /* manager */, + int n /* number of bits */, + int m /* modulus */, + int options /* options */, + int top /* index of top variable */) +{ + int msbLsb; /* MSB on top (1) or LSB on top (0) */ + int tc; /* two's complement (1) or unsigned (0) */ + int i, j, k, t, residue, thisOne, previous, index; + DdNode **array[2], *var, *tmp, *res; + + /* Sanity check. */ + if (n < 1 && m < 2) return(NULL); + + msbLsb = options & CUDD_RESIDUE_MSB; + tc = options & CUDD_RESIDUE_TC; + + /* Allocate and initialize working arrays. */ + array[0] = ALLOC(DdNode *,m); + if (array[0] == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + array[1] = ALLOC(DdNode *,m); + if (array[1] == NULL) { + FREE(array[0]); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < m; i++) { + array[0][i] = array[1][i] = NULL; + } + + /* Initialize residues. */ + for (i = 0; i < m; i++) { + tmp = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) i); + if (tmp == NULL) { + for (j = 0; j < i; j++) { + Cudd_RecursiveDeref(dd,array[1][j]); + } + FREE(array[0]); + FREE(array[1]); + return(NULL); + } + cuddRef(tmp); + array[1][i] = tmp; + } + + /* Main iteration. */ + residue = 1; /* residue of 2**0 */ + for (k = 0; k < n; k++) { + /* Choose current and previous arrays. */ + thisOne = k & 1; + previous = thisOne ^ 1; + /* Build an ADD projection function. */ + if (msbLsb) { + index = top+n-k-1; + } else { + index = top+k; + } + var = cuddUniqueInter(dd,index,DD_ONE(dd),DD_ZERO(dd)); + if (var == NULL) { + for (j = 0; j < m; j++) { + Cudd_RecursiveDeref(dd,array[previous][j]); + } + FREE(array[0]); + FREE(array[1]); + return(NULL); + } + cuddRef(var); + for (i = 0; i < m; i ++) { + t = (i + residue) % m; + tmp = Cudd_addIte(dd,var,array[previous][t],array[previous][i]); + if (tmp == NULL) { + for (j = 0; j < i; j++) { + Cudd_RecursiveDeref(dd,array[thisOne][j]); + } + for (j = 0; j < m; j++) { + Cudd_RecursiveDeref(dd,array[previous][j]); + } + FREE(array[0]); + FREE(array[1]); + return(NULL); + } + cuddRef(tmp); + array[thisOne][i] = tmp; + } + /* One layer completed. Free the other array for the next iteration. */ + for (i = 0; i < m; i++) { + Cudd_RecursiveDeref(dd,array[previous][i]); + } + Cudd_RecursiveDeref(dd,var); + /* Update residue of 2**k. */ + residue = (2 * residue) % m; + /* Adjust residue for MSB, if this is a two's complement number. */ + if (tc && (k == n - 1)) { + residue = (m - residue) % m; + } + } + + /* We are only interested in the 0-residue node of the top layer. */ + for (i = 1; i < m; i++) { + Cudd_RecursiveDeref(dd,array[(n - 1) & 1][i]); + } + res = array[(n - 1) & 1][0]; + + FREE(array[0]); + FREE(array[1]); + + cuddDeref(res); + return(res); + +} /* end of Cudd_addResidue */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addWalsh.] + + Description [Generates a Walsh matrix in ADD form. Returns a pointer + to the matrixi if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +addWalshInt( + DdManager * dd, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *one, *minusone; + DdNode *t, *u, *t1, *u1, *v, *w; + int i; + + one = DD_ONE(dd); + if (n == 0) return(one); + + /* Build bottom part of ADD outside loop */ + minusone = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) -1); + if (minusone == NULL) return(NULL); + cuddRef(minusone); + v = Cudd_addIte(dd, y[n-1], minusone, one); + if (v == NULL) { + Cudd_RecursiveDeref(dd, minusone); + return(NULL); + } + cuddRef(v); + u = Cudd_addIte(dd, x[n-1], v, one); + if (u == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + if (n>1) { + w = Cudd_addIte(dd, y[n-1], one, minusone); + if (w == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(w); + t = Cudd_addIte(dd, x[n-1], w, minusone); + if (t == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(t); + Cudd_RecursiveDeref(dd, w); + } + cuddDeref(minusone); /* minusone is in the result; it won't die */ + + /* Loop to build the rest of the ADD */ + for (i=n-2; i>=0; i--) { + t1 = t; u1 = u; + v = Cudd_addIte(dd, y[i], t1, u1); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + return(NULL); + } + cuddRef(v); + u = Cudd_addIte(dd, x[i], v, u1); + if (u == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + if (i>0) { + w = Cudd_addIte(dd, y[i], u1, t1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(w); + t = Cudd_addIte(dd, x[i], w, t1); + if (u == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(t); + Cudd_RecursiveDeref(dd, w); + } + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + } + + cuddDeref(u); + return(u); + +} /* end of addWalshInt */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAndAbs.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAndAbs.c new file mode 100644 index 000000000..a800830bf --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAndAbs.c @@ -0,0 +1,373 @@ +/**CFile*********************************************************************** + + FileName [cuddAndAbs.c] + + PackageName [cudd] + + Synopsis [Combined AND and existential abstraction for BDDs] + + Description [External procedures included in this module: +
                    +
                  • Cudd_bddAndAbstract() +
                  • Cudd_bddAndAbstractLimit() +
                  + Internal procedures included in this module: +
                    +
                  • cuddBddAndAbstractRecur() +
                  ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.20 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Takes the AND of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise. + Cudd_bddAndAbstract implements the semiring matrix multiplication + algorithm for the boolean semiring.] + + SideEffects [None] + + SeeAlso [Cudd_addMatrixMultiply Cudd_addTriangle Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddAndAbstract( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *res; + + do { + manager->reordered = 0; + res = cuddBddAndAbstractRecur(manager, f, g, cube); + } while (manager->reordered == 1); + return(res); + +} /* end of Cudd_bddAndAbstract */ + + +/**Function******************************************************************** + + Synopsis [Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. Returns NULL if too many nodes are required.] + + Description [Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise. + In particular, if the number of new nodes created exceeds + limit, this function returns NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddAndAbstractLimit( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = manager->maxLive; + + manager->maxLive = (manager->keys - manager->dead) + + (manager->keysZ - manager->deadZ) + limit; + do { + manager->reordered = 0; + res = cuddBddAndAbstractRecur(manager, f, g, cube); + } while (manager->reordered == 1); + manager->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddAndAbstractLimit */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Takes the AND of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +cuddBddAndAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *zero, *r, *t, *e; + unsigned int topf, topg, topcube, top, index; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == one && g == one) return(one); + + if (cube == one) { + return(cuddBddAndRecur(manager, f, g)); + } + if (f == one || f == g) { + return(cuddBddExistAbstractRecur(manager, g, cube)); + } + if (g == one) { + return(cuddBddExistAbstractRecur(manager, f, cube)); + } + /* At this point f, g, and cube are not constant. */ + + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; + g = tmp; + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + top = ddMin(topf, topg); + topcube = manager->perm[cube->index]; + + while (topcube < top) { + cube = cuddT(cube); + if (cube == one) { + return(cuddBddAndRecur(manager, f, g)); + } + topcube = manager->perm[cube->index]; + } + /* Now, topcube >= top. */ + + /* Check cache. */ + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube); + if (r != NULL) { + return(r); + } + } + + if (topf == top) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg == top) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + if (topcube == top) { /* quantify */ + DdNode *Cube = cuddT(cube); + t = cuddBddAndAbstractRecur(manager, ft, gt, Cube); + if (t == NULL) return(NULL); + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. Likewise t + t * anything == t. + ** Notice that t == fe implies that fe does not depend on the + ** variables in Cube. Likewise for t == ge. + */ + if (t == one || t == fe || t == ge) { + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, + f, g, cube, t); + return(t); + } + cuddRef(t); + /* Special case: t + !t * anything == t + anything. */ + if (t == Cudd_Not(fe)) { + e = cuddBddExistAbstractRecur(manager, ge, Cube); + } else if (t == Cudd_Not(ge)) { + e = cuddBddExistAbstractRecur(manager, fe, Cube); + } else { + e = cuddBddAndAbstractRecur(manager, fe, ge, Cube); + } + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + if (t == e) { + r = t; + cuddDeref(t); + } else { + cuddRef(e); + r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_DelayedDerefBdd(manager, t); + Cudd_DelayedDerefBdd(manager, e); + cuddDeref(r); + } + } else { + t = cuddBddAndAbstractRecur(manager, ft, gt, cube); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddAndAbstractRecur(manager, fe, ge, cube); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + if (t == e) { + r = t; + cuddDeref(t); + } else { + cuddRef(e); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager, (int) index, + Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + } + } + + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r); + return (r); + +} /* end of cuddBddAndAbstractRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAnneal.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAnneal.c new file mode 100644 index 000000000..622c3d14a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddAnneal.c @@ -0,0 +1,814 @@ +/**CFile*********************************************************************** + + FileName [cuddAnneal.c] + + PackageName [cudd] + + Synopsis [Reordering of DDs based on simulated annealing] + + Description [Internal procedures included in this file: +
                    +
                  • cuddAnnealing() +
                  + Static procedures included in this file: +
                    +
                  • stopping_criterion() +
                  • random_generator() +
                  • ddExchange() +
                  • ddJumpingAux() +
                  • ddJumpingUp() +
                  • ddJumpingDown() +
                  • siftBackwardProb() +
                  • copyOrder() +
                  • restoreOrder() +
                  + ] + + SeeAlso [] + + Author [Jae-Young Jang, Jorgen Sivesind] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Annealing parameters */ +#define BETA 0.6 +#define ALPHA 0.90 +#define EXC_PROB 0.4 +#define JUMP_UP_PROB 0.36 +#define MAXGEN_RATIO 15.0 +#define STOP_TEMP 1.0 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAnneal.c,v 1.15 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef DD_STATS +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +static int tosses; +static int acceptances; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int stopping_criterion (int c1, int c2, int c3, int c4, double temp); +static double random_generator (void); +static int ddExchange (DdManager *table, int x, int y, double temp); +static int ddJumpingAux (DdManager *table, int x, int x_low, int x_high, double temp); +static Move * ddJumpingUp (DdManager *table, int x, int x_low, int initial_size); +static Move * ddJumpingDown (DdManager *table, int x, int x_high, int initial_size); +static int siftBackwardProb (DdManager *table, Move *moves, int size, double temp); +static void copyOrder (DdManager *table, int *array, int lower, int upper); +static int restoreOrder (DdManager *table, int *array, int lower, int upper); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Get new variable-order by simulated annealing algorithm.] + + Description [Get x, y by random selection. Choose either + exchange or jump randomly. In case of jump, choose between jump_up + and jump_down randomly. Do exchange or jump and get optimal case. + Loop until there is no improvement or temperature reaches + minimum. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddAnnealing( + DdManager * table, + int lower, + int upper) +{ + int nvars; + int size; + int x,y; + int result; + int c1, c2, c3, c4; + int BestCost; + int *BestOrder; + double NewTemp, temp; + double rand1; + int innerloop, maxGen; + int ecount, ucount, dcount; + + nvars = upper - lower + 1; + + result = cuddSifting(table,lower,upper); +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + if (result == 0) return(0); + + size = table->keys - table->isolated; + + /* Keep track of the best order. */ + BestCost = size; + BestOrder = ALLOC(int,nvars); + if (BestOrder == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + copyOrder(table,BestOrder,lower,upper); + + temp = BETA * size; + maxGen = (int) (MAXGEN_RATIO * nvars); + + c1 = size + 10; + c2 = c1 + 10; + c3 = size; + c4 = c2 + 10; + ecount = ucount = dcount = 0; + + while (!stopping_criterion(c1, c2, c3, c4, temp)) { +#ifdef DD_STATS + (void) fprintf(table->out,"temp=%f\tsize=%d\tgen=%d\t", + temp,size,maxGen); + tosses = acceptances = 0; +#endif + for (innerloop = 0; innerloop < maxGen; innerloop++) { + /* Choose x, y randomly. */ + x = (int) Cudd_Random() % nvars; + do { + y = (int) Cudd_Random() % nvars; + } while (x == y); + x += lower; + y += lower; + if (x > y) { + int tmp = x; + x = y; + y = tmp; + } + + /* Choose move with roulette wheel. */ + rand1 = random_generator(); + if (rand1 < EXC_PROB) { + result = ddExchange(table,x,y,temp); /* exchange */ + ecount++; +#if 0 + (void) fprintf(table->out, + "Exchange of %d and %d: size = %d\n", + x,y,table->keys - table->isolated); +#endif + } else if (rand1 < EXC_PROB + JUMP_UP_PROB) { + result = ddJumpingAux(table,y,x,y,temp); /* jumping_up */ + ucount++; +#if 0 + (void) fprintf(table->out, + "Jump up of %d to %d: size = %d\n", + y,x,table->keys - table->isolated); +#endif + } else { + result = ddJumpingAux(table,x,x,y,temp); /* jumping_down */ + dcount++; +#if 0 + (void) fprintf(table->out, + "Jump down of %d to %d: size = %d\n", + x,y,table->keys - table->isolated); +#endif + } + + if (!result) { + FREE(BestOrder); + return(0); + } + + size = table->keys - table->isolated; /* keep current size */ + if (size < BestCost) { /* update best order */ + BestCost = size; + copyOrder(table,BestOrder,lower,upper); + } + } + c1 = c2; + c2 = c3; + c3 = c4; + c4 = size; + NewTemp = ALPHA * temp; + if (NewTemp >= 1.0) { + maxGen = (int)(log(NewTemp) / log(temp) * maxGen); + } + temp = NewTemp; /* control variable */ +#ifdef DD_STATS + (void) fprintf(table->out,"uphill = %d\taccepted = %d\n", + tosses,acceptances); + fflush(table->out); +#endif + } + + result = restoreOrder(table,BestOrder,lower,upper); + FREE(BestOrder); + if (!result) return(0); +#ifdef DD_STATS + fprintf(table->out,"#:N_EXCHANGE %8d : total exchanges\n",ecount); + fprintf(table->out,"#:N_JUMPUP %8d : total jumps up\n",ucount); + fprintf(table->out,"#:N_JUMPDOWN %8d : total jumps down",dcount); +#endif + return(1); + +} /* end of cuddAnnealing */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Checks termination condition.] + + Description [If temperature is STOP_TEMP or there is no improvement + then terminates. Returns 1 if the termination criterion is met; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +stopping_criterion( + int c1, + int c2, + int c3, + int c4, + double temp) +{ + if (STOP_TEMP < temp) { + return(0); + } else if ((c1 == c2) && (c1 == c3) && (c1 == c4)) { + return(1); + } else { + return(0); + } + +} /* end of stopping_criterion */ + + +/**Function******************************************************************** + + Synopsis [Random number generator.] + + Description [Returns a double precision value between 0.0 and 1.0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double +random_generator(void) +{ + return((double)(Cudd_Random() / 2147483561.0)); + +} /* end of random_generator */ + + +/**Function******************************************************************** + + Synopsis [This function is for exchanging two variables, x and y.] + + Description [This is the same funcion as ddSwapping except for + comparison expression. Use probability function, exp(-size_change/temp).] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddExchange( + DdManager * table, + int x, + int y, + double temp) +{ + Move *move,*moves; + int tmp; + int x_ref,y_ref; + int x_next,y_next; + int size, result; + int initial_size, limit_size; + + x_ref = x; + y_ref = y; + + x_next = cuddNextHigh(table,x); + y_next = cuddNextLow(table,y); + moves = NULL; + initial_size = limit_size = table->keys - table->isolated; + + for (;;) { + if (x_next == y_next) { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; + x = y; + y = tmp; + } else if (x == y_next) { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + tmp = x; + x = y; + y = tmp; + } else { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + x = x_next; + y = y_next; + } + + x_next = cuddNextHigh(table,x); + y_next = cuddNextLow(table,y); + if (x_next > y_ref) break; + + if ((double) size > DD_MAX_REORDER_GROWTH * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + } + + if (y_next>=x_ref) { + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + } + + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddExchangeOutOfMem; + + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(1); + +ddExchangeOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(0); + +} /* end of ddExchange */ + + +/**Function******************************************************************** + + Synopsis [Moves a variable to a specified position.] + + Description [If x==x_low, it executes jumping_down. If x==x_high, it + executes jumping_up. This funcion is similar to ddSiftingAux. Returns + 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddJumpingAux( + DdManager * table, + int x, + int x_low, + int x_high, + double temp) +{ + Move *move; + Move *moves; /* list of moves */ + int initial_size; + int result; + + initial_size = table->keys - table->isolated; + +#ifdef DD_DEBUG + assert(table->subtables[x].keys > 0); +#endif + + moves = NULL; + + if (cuddNextLow(table,x) < x_low) { + if (cuddNextHigh(table,x) > x_high) return(1); + moves = ddJumpingDown(table,x,x_high,initial_size); + /* after that point x --> x_high unless early termination */ + if (moves == NULL) goto ddJumpingAuxOutOfMem; + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddJumpingAuxOutOfMem; + } else if (cuddNextHigh(table,x) > x_high) { + moves = ddJumpingUp(table,x,x_low,initial_size); + /* after that point x --> x_low unless early termination */ + if (moves == NULL) goto ddJumpingAuxOutOfMem; + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddJumpingAuxOutOfMem; + } else { + (void) fprintf(table->err,"Unexpected condition in ddJumping\n"); + goto ddJumpingAuxOutOfMem; + } + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(1); + +ddJumpingAuxOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(0); + +} /* end of ddJumpingAux */ + + +/**Function******************************************************************** + + Synopsis [This function is for jumping up.] + + Description [This is a simplified version of ddSiftingUp. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +ddJumpingUp( + DdManager * table, + int x, + int x_low, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddNextLow(table,x); + while (y >= x_low) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) goto ddJumpingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddJumpingUpOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > table->maxGrowth * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + x = y; + y = cuddNextLow(table,x); + } + return(moves); + +ddJumpingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of ddJumpingUp */ + + +/**Function******************************************************************** + + Synopsis [This function is for jumping down.] + + Description [This is a simplified version of ddSiftingDown. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +ddJumpingDown( + DdManager * table, + int x, + int x_high, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddNextHigh(table,x); + while (y <= x_high) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddJumpingDownOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddJumpingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > table->maxGrowth * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + x = y; + y = cuddNextHigh(table,x); + } + return(moves); + +ddJumpingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of ddJumpingDown */ + + +/**Function******************************************************************** + + Synopsis [Returns the DD to the best position encountered during + sifting if there was improvement.] + + Description [Otherwise, "tosses a coin" to decide whether to keep + the current configuration or return the DD to the original + one. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +siftBackwardProb( + DdManager * table, + Move * moves, + int size, + double temp) +{ + Move *move; + int res; + int best_size = size; + double coin, threshold; + + /* Look for best size during the last sifting */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < best_size) { + best_size = move->size; + } + } + + /* If best_size equals size, the last sifting did not produce any + ** improvement. We now toss a coin to decide whether to retain + ** this change or not. + */ + if (best_size == size) { + coin = random_generator(); +#ifdef DD_STATS + tosses++; +#endif + threshold = exp(-((double)(table->keys - table->isolated - size))/temp); + if (coin < threshold) { +#ifdef DD_STATS + acceptances++; +#endif + return(1); + } + } + + /* Either there was improvement, or we have decided not to + ** accept the uphill move. Go to best position. + */ + res = table->keys - table->isolated; + for (move = moves; move != NULL; move = move->next) { + if (res == best_size) return(1); + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + + return(1); + +} /* end of sift_backward_prob */ + + +/**Function******************************************************************** + + Synopsis [Copies the current variable order to array.] + + Description [Copies the current variable order to array. + At the same time inverts the permutation.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +copyOrder( + DdManager * table, + int * array, + int lower, + int upper) +{ + int i; + int nvars; + + nvars = upper - lower + 1; + for (i = 0; i < nvars; i++) { + array[i] = table->invperm[i+lower]; + } + +} /* end of copyOrder */ + + +/**Function******************************************************************** + + Synopsis [Restores the variable order in array by a series of sifts up.] + + Description [Restores the variable order in array by a series of sifts up. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +restoreOrder( + DdManager * table, + int * array, + int lower, + int upper) +{ + int i, x, y, size; + int nvars = upper - lower + 1; + + for (i = 0; i < nvars; i++) { + x = table->perm[array[i]]; +#ifdef DD_DEBUG + assert(x >= lower && x <= upper); +#endif + y = cuddNextLow(table,x); + while (y >= i + lower) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) return(0); + x = y; + y = cuddNextLow(table,x); + } + } + + return(1); + +} /* end of restoreOrder */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddApa.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddApa.c new file mode 100644 index 000000000..7c4ff8ce6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddApa.c @@ -0,0 +1,979 @@ +/**CFile*********************************************************************** + + FileName [cuddApa.c] + + PackageName [cudd] + + Synopsis [Arbitrary precision arithmetic functions.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_ApaNumberOfDigits() +
                  • Cudd_NewApaNumber() +
                  • Cudd_ApaCopy() +
                  • Cudd_ApaAdd() +
                  • Cudd_ApaSubtract() +
                  • Cudd_ApaShortDivision() +
                  • Cudd_ApaIntDivision() +
                  • Cudd_ApaShiftRight() +
                  • Cudd_ApaSetToLiteral() +
                  • Cudd_ApaPowerOfTwo() +
                  • Cudd_ApaCompare() +
                  • Cudd_ApaCompareRatios() +
                  • Cudd_ApaPrintHex() +
                  • Cudd_ApaPrintDecimal() +
                  • Cudd_ApaPrintExponential() +
                  • Cudd_ApaCountMinterm() +
                  • Cudd_ApaPrintMinterm() +
                  • Cudd_ApaPrintMintermExp() +
                  • Cudd_ApaPrintDensity() +
                  + Static procedures included in this module: +
                    +
                  • cuddApaCountMintermAux() +
                  • cuddApaStCountfree() +
                  ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.20 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static DdNode *background, *zero; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdApaNumber cuddApaCountMintermAux (DdNode * node, int digits, DdApaNumber max, DdApaNumber min, st_table * table); +static enum st_retval cuddApaStCountfree (char * key, char * value, char * arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Finds the number of digits for an arbitrary precision + integer.] + + Description [Finds the number of digits for an arbitrary precision + integer given the maximum number of binary digits. The number of + binary digits should be positive. Returns the number of digits if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaNumberOfDigits( + int binaryDigits) +{ + int digits; + + digits = binaryDigits / DD_APA_BITS; + if ((digits * DD_APA_BITS) != binaryDigits) + digits++; + return(digits); + +} /* end of Cudd_ApaNumberOfDigits */ + + +/**Function******************************************************************** + + Synopsis [Allocates memory for an arbitrary precision integer.] + + Description [Allocates memory for an arbitrary precision + integer. Returns a pointer to the allocated memory if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdApaNumber +Cudd_NewApaNumber( + int digits) +{ + return(ALLOC(DdApaDigit, digits)); + +} /* end of Cudd_NewApaNumber */ + + +/**Function******************************************************************** + + Synopsis [Makes a copy of an arbitrary precision integer.] + + Description [Makes a copy of an arbitrary precision integer.] + + SideEffects [Changes parameter dest.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaCopy( + int digits, + DdApaNumber source, + DdApaNumber dest) +{ + int i; + + for (i = 0; i < digits; i++) { + dest[i] = source[i]; + } + +} /* end of Cudd_ApaCopy */ + + +/**Function******************************************************************** + + Synopsis [Adds two arbitrary precision integers.] + + Description [Adds two arbitrary precision integers. Returns the + carry out of the most significant digit.] + + SideEffects [The result of the sum is stored in parameter sum.] + + SeeAlso [] + +******************************************************************************/ +DdApaDigit +Cudd_ApaAdd( + int digits, + DdApaNumber a, + DdApaNumber b, + DdApaNumber sum) +{ + int i; + DdApaDoubleDigit partial = 0; + + for (i = digits - 1; i >= 0; i--) { + partial = a[i] + b[i] + DD_MSDIGIT(partial); + sum[i] = (DdApaDigit) DD_LSDIGIT(partial); + } + return((DdApaDigit) DD_MSDIGIT(partial)); + +} /* end of Cudd_ApaAdd */ + + +/**Function******************************************************************** + + Synopsis [Subtracts two arbitrary precision integers.] + + Description [Subtracts two arbitrary precision integers. Returns the + borrow out of the most significant digit.] + + SideEffects [The result of the subtraction is stored in parameter + diff.] + + SeeAlso [] + +******************************************************************************/ +DdApaDigit +Cudd_ApaSubtract( + int digits, + DdApaNumber a, + DdApaNumber b, + DdApaNumber diff) +{ + int i; + DdApaDoubleDigit partial = DD_APA_BASE; + + for (i = digits - 1; i >= 0; i--) { + partial = DD_MSDIGIT(partial) + DD_APA_MASK + a[i] - b[i]; + diff[i] = (DdApaDigit) DD_LSDIGIT(partial); + } + return((DdApaDigit) DD_MSDIGIT(partial) - 1); + +} /* end of Cudd_ApaSubtract */ + + +/**Function******************************************************************** + + Synopsis [Divides an arbitrary precision integer by a digit.] + + Description [Divides an arbitrary precision integer by a digit.] + + SideEffects [The quotient is returned in parameter quotient.] + + SeeAlso [] + +******************************************************************************/ +DdApaDigit +Cudd_ApaShortDivision( + int digits, + DdApaNumber dividend, + DdApaDigit divisor, + DdApaNumber quotient) +{ + int i; + DdApaDigit remainder; + DdApaDoubleDigit partial; + + remainder = 0; + for (i = 0; i < digits; i++) { + partial = remainder * DD_APA_BASE + dividend[i]; + quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor); + remainder = (DdApaDigit) (partial % divisor); + } + + return(remainder); + +} /* end of Cudd_ApaShortDivision */ + + +/**Function******************************************************************** + + Synopsis [Divides an arbitrary precision integer by an integer.] + + Description [Divides an arbitrary precision integer by a 32-bit + unsigned integer. Returns the remainder of the division. This + procedure relies on the assumption that the number of bits of a + DdApaDigit plus the number of bits of an unsigned int is less the + number of bits of the mantissa of a double. This guarantees that the + product of a DdApaDigit and an unsigned int can be represented + without loss of precision by a double. On machines where this + assumption is not satisfied, this procedure will malfunction.] + + SideEffects [The quotient is returned in parameter quotient.] + + SeeAlso [Cudd_ApaShortDivision] + +******************************************************************************/ +unsigned int +Cudd_ApaIntDivision( + int digits, + DdApaNumber dividend, + unsigned int divisor, + DdApaNumber quotient) +{ + int i; + double partial; + unsigned int remainder = 0; + double ddiv = (double) divisor; + + for (i = 0; i < digits; i++) { + partial = (double) remainder * DD_APA_BASE + dividend[i]; + quotient[i] = (DdApaDigit) (partial / ddiv); + remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv)); + } + + return(remainder); + +} /* end of Cudd_ApaIntDivision */ + + +/**Function******************************************************************** + + Synopsis [Shifts right an arbitrary precision integer by one binary + place.] + + Description [Shifts right an arbitrary precision integer by one + binary place. The most significant binary digit of the result is + taken from parameter in.] + + SideEffects [The result is returned in parameter b.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaShiftRight( + int digits, + DdApaDigit in, + DdApaNumber a, + DdApaNumber b) +{ + int i; + + for (i = digits - 1; i > 0; i--) { + b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1)); + } + b[0] = (a[0] >> 1) | (in << (DD_APA_BITS - 1)); + +} /* end of Cudd_ApaShiftRight */ + + +/**Function******************************************************************** + + Synopsis [Sets an arbitrary precision integer to a one-digit literal.] + + Description [Sets an arbitrary precision integer to a one-digit literal.] + + SideEffects [The result is returned in parameter number.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaSetToLiteral( + int digits, + DdApaNumber number, + DdApaDigit literal) +{ + int i; + + for (i = 0; i < digits - 1; i++) + number[i] = 0; + number[digits - 1] = literal; + +} /* end of Cudd_ApaSetToLiteral */ + + +/**Function******************************************************************** + + Synopsis [Sets an arbitrary precision integer to a power of two.] + + Description [Sets an arbitrary precision integer to a power of + two. If the power of two is too large to be represented, the number + is set to 0.] + + SideEffects [The result is returned in parameter number.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaPowerOfTwo( + int digits, + DdApaNumber number, + int power) +{ + int i; + int index; + + for (i = 0; i < digits; i++) + number[i] = 0; + i = digits - 1 - power / DD_APA_BITS; + if (i < 0) return; + index = power & (DD_APA_BITS - 1); + number[i] = 1 << index; + +} /* end of Cudd_ApaPowerOfTwo */ + + +/**Function******************************************************************** + + Synopsis [Compares two arbitrary precision integers.] + + Description [Compares two arbitrary precision integers. Returns 1 if + the first number is larger; 0 if they are equal; -1 if the second + number is larger.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaCompare( + int digitsFirst, + DdApaNumber first, + int digitsSecond, + DdApaNumber second) +{ + int i; + int firstNZ, secondNZ; + + /* Find first non-zero in both numbers. */ + for (firstNZ = 0; firstNZ < digitsFirst; firstNZ++) + if (first[firstNZ] != 0) break; + for (secondNZ = 0; secondNZ < digitsSecond; secondNZ++) + if (second[secondNZ] != 0) break; + if (digitsFirst - firstNZ > digitsSecond - secondNZ) return(1); + else if (digitsFirst - firstNZ < digitsSecond - secondNZ) return(-1); + for (i = 0; i < digitsFirst - firstNZ; i++) { + if (first[firstNZ + i] > second[secondNZ + i]) return(1); + else if (first[firstNZ + i] < second[secondNZ + i]) return(-1); + } + return(0); + +} /* end of Cudd_ApaCompare */ + + +/**Function******************************************************************** + + Synopsis [Compares the ratios of two arbitrary precision integers to two + unsigned ints.] + + Description [Compares the ratios of two arbitrary precision integers + to two unsigned ints. Returns 1 if the first number is larger; 0 if + they are equal; -1 if the second number is larger.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaCompareRatios( + int digitsFirst, + DdApaNumber firstNum, + unsigned int firstDen, + int digitsSecond, + DdApaNumber secondNum, + unsigned int secondDen) +{ + int result; + DdApaNumber first, second; + unsigned int firstRem, secondRem; + + first = Cudd_NewApaNumber(digitsFirst); + firstRem = Cudd_ApaIntDivision(digitsFirst,firstNum,firstDen,first); + second = Cudd_NewApaNumber(digitsSecond); + secondRem = Cudd_ApaIntDivision(digitsSecond,secondNum,secondDen,second); + result = Cudd_ApaCompare(digitsFirst,first,digitsSecond,second); + FREE(first); + FREE(second); + if (result == 0) { + if ((double)firstRem/firstDen > (double)secondRem/secondDen) + return(1); + else if ((double)firstRem/firstDen < (double)secondRem/secondDen) + return(-1); + } + return(result); + +} /* end of Cudd_ApaCompareRatios */ + + +/**Function******************************************************************** + + Synopsis [Prints an arbitrary precision integer in hexadecimal format.] + + Description [Prints an arbitrary precision integer in hexadecimal format. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintDecimal Cudd_ApaPrintExponential] + +******************************************************************************/ +int +Cudd_ApaPrintHex( + FILE * fp, + int digits, + DdApaNumber number) +{ + int i, result; + + for (i = 0; i < digits; i++) { + result = fprintf(fp,DD_APA_HEXPRINT,number[i]); + if (result == EOF) + return(0); + } + return(1); + +} /* end of Cudd_ApaPrintHex */ + + +/**Function******************************************************************** + + Synopsis [Prints an arbitrary precision integer in decimal format.] + + Description [Prints an arbitrary precision integer in decimal format. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintExponential] + +******************************************************************************/ +int +Cudd_ApaPrintDecimal( + FILE * fp, + int digits, + DdApaNumber number) +{ + int i, result; + DdApaDigit remainder; + DdApaNumber work; + unsigned char *decimal; + int leadingzero; + int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; + + work = Cudd_NewApaNumber(digits); + if (work == NULL) + return(0); + decimal = ALLOC(unsigned char, decimalDigits); + if (decimal == NULL) { + FREE(work); + return(0); + } + Cudd_ApaCopy(digits,number,work); + for (i = decimalDigits - 1; i >= 0; i--) { + remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); + decimal[i] = (unsigned char) remainder; + } + FREE(work); + + leadingzero = 1; + for (i = 0; i < decimalDigits; i++) { + leadingzero = leadingzero && (decimal[i] == 0); + if ((!leadingzero) || (i == (decimalDigits - 1))) { + result = fprintf(fp,"%1d",decimal[i]); + if (result == EOF) { + FREE(decimal); + return(0); + } + } + } + FREE(decimal); + return(1); + +} /* end of Cudd_ApaPrintDecimal */ + + +/**Function******************************************************************** + + Synopsis [Prints an arbitrary precision integer in exponential format.] + + Description [Prints an arbitrary precision integer in exponential format. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintDecimal] + +******************************************************************************/ +int +Cudd_ApaPrintExponential( + FILE * fp, + int digits, + DdApaNumber number, + int precision) +{ + int i, first, last, result; + DdApaDigit remainder; + DdApaNumber work; + unsigned char *decimal; + int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; + + work = Cudd_NewApaNumber(digits); + if (work == NULL) + return(0); + decimal = ALLOC(unsigned char, decimalDigits); + if (decimal == NULL) { + FREE(work); + return(0); + } + Cudd_ApaCopy(digits,number,work); + first = decimalDigits - 1; + for (i = decimalDigits - 1; i >= 0; i--) { + remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); + decimal[i] = (unsigned char) remainder; + if (remainder != 0) first = i; /* keep track of MS non-zero */ + } + FREE(work); + last = ddMin(first + precision, decimalDigits); + + for (i = first; i < last; i++) { + result = fprintf(fp,"%s%1d",i == first+1 ? "." : "", decimal[i]); + if (result == EOF) { + FREE(decimal); + return(0); + } + } + FREE(decimal); + result = fprintf(fp,"e+%d",decimalDigits - first - 1); + if (result == EOF) { + return(0); + } + return(1); + +} /* end of Cudd_ApaPrintExponential */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a DD.] + + Description [Counts the number of minterms of a DD. The function is + assumed to depend on nvars variables. The minterm count is + represented as an arbitrary precision unsigned integer, to allow for + any number of variables CUDD supports. Returns a pointer to the + array representing the number of minterms of the function rooted at + node if successful; NULL otherwise.] + + SideEffects [The number of digits of the result is returned in + parameter digits.] + + SeeAlso [Cudd_CountMinterm] + +******************************************************************************/ +DdApaNumber +Cudd_ApaCountMinterm( + DdManager * manager, + DdNode * node, + int nvars, + int * digits) +{ + DdApaNumber max, min; + st_table *table; + DdApaNumber i,count; + + background = manager->background; + zero = Cudd_Not(manager->one); + + *digits = Cudd_ApaNumberOfDigits(nvars+1); + max = Cudd_NewApaNumber(*digits); + if (max == NULL) { + return(NULL); + } + Cudd_ApaPowerOfTwo(*digits,max,nvars); + min = Cudd_NewApaNumber(*digits); + if (min == NULL) { + FREE(max); + return(NULL); + } + Cudd_ApaSetToLiteral(*digits,min,0); + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) { + FREE(max); + FREE(min); + return(NULL); + } + i = cuddApaCountMintermAux(Cudd_Regular(node),*digits,max,min,table); + if (i == NULL) { + FREE(max); + FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + return(NULL); + } + count = Cudd_NewApaNumber(*digits); + if (count == NULL) { + FREE(max); + FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + if (Cudd_Regular(node)->ref == 1) FREE(i); + return(NULL); + } + if (Cudd_IsComplement(node)) { + (void) Cudd_ApaSubtract(*digits,max,i,count); + } else { + Cudd_ApaCopy(*digits,i,count); + } + FREE(max); + FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + if (Cudd_Regular(node)->ref == 1) FREE(i); + return(count); + +} /* end of Cudd_ApaCountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic.] + + Description [Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintMintermExp] + +******************************************************************************/ +int +Cudd_ApaPrintMinterm( + FILE * fp, + DdManager * dd, + DdNode * node, + int nvars) +{ + int digits; + int result; + DdApaNumber count; + + count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); + if (count == NULL) + return(0); + result = Cudd_ApaPrintDecimal(fp,digits,count); + FREE(count); + if (fprintf(fp,"\n") == EOF) { + return(0); + } + return(result); + +} /* end of Cudd_ApaPrintMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints the number of minterms of a BDD or ADD in exponential + format using arbitrary precision arithmetic.] + + Description [Prints the number of minterms of a BDD or ADD in + exponential format using arbitrary precision arithmetic. Parameter + precision controls the number of signficant digits printed. Returns + 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintMinterm] + +******************************************************************************/ +int +Cudd_ApaPrintMintermExp( + FILE * fp, + DdManager * dd, + DdNode * node, + int nvars, + int precision) +{ + int digits; + int result; + DdApaNumber count; + + count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); + if (count == NULL) + return(0); + result = Cudd_ApaPrintExponential(fp,digits,count,precision); + FREE(count); + if (fprintf(fp,"\n") == EOF) { + return(0); + } + return(result); + +} /* end of Cudd_ApaPrintMintermExp */ + + +/**Function******************************************************************** + + Synopsis [Prints the density of a BDD or ADD using + arbitrary precision arithmetic.] + + Description [Prints the density of a BDD or ADD using + arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaPrintDensity( + FILE * fp, + DdManager * dd, + DdNode * node, + int nvars) +{ + int digits; + int result; + DdApaNumber count,density; + unsigned int size, remainder, fractional; + + count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); + if (count == NULL) + return(0); + size = Cudd_DagSize(node); + density = Cudd_NewApaNumber(digits); + remainder = Cudd_ApaIntDivision(digits,count,size,density); + result = Cudd_ApaPrintDecimal(fp,digits,density); + FREE(count); + FREE(density); + fractional = (unsigned int)((double)remainder / size * 1000000); + if (fprintf(fp,".%u\n", fractional) == EOF) { + return(0); + } + return(result); + +} /* end of Cudd_ApaPrintDensity */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_ApaCountMinterm.] + + Description [Performs the recursive step of Cudd_ApaCountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. + Uses the identity |f'| = max - |f|. + The procedure expects the argument "node" to be a regular pointer, and + guarantees this condition is met in the recursive calls. + For efficiency, the result of a call is cached only if the node has + a reference count greater than 1. + Returns the number of minterms of the function rooted at node.] + + SideEffects [None] + +******************************************************************************/ +static DdApaNumber +cuddApaCountMintermAux( + DdNode * node, + int digits, + DdApaNumber max, + DdApaNumber min, + st_table * table) +{ + DdNode *Nt, *Ne; + DdApaNumber mint, mint1, mint2; + DdApaDigit carryout; + + if (cuddIsConstant(node)) { + if (node == background || node == zero) { + return(min); + } else { + return(max); + } + } + if (node->ref > 1 && st_lookup(table, node, &mint)) { + return(mint); + } + + Nt = cuddT(node); Ne = cuddE(node); + + mint1 = cuddApaCountMintermAux(Nt, digits, max, min, table); + if (mint1 == NULL) return(NULL); + mint2 = cuddApaCountMintermAux(Cudd_Regular(Ne), digits, max, min, table); + if (mint2 == NULL) { + if (Nt->ref == 1) FREE(mint1); + return(NULL); + } + mint = Cudd_NewApaNumber(digits); + if (mint == NULL) { + if (Nt->ref == 1) FREE(mint1); + if (Cudd_Regular(Ne)->ref == 1) FREE(mint2); + return(NULL); + } + if (Cudd_IsComplement(Ne)) { + (void) Cudd_ApaSubtract(digits,max,mint2,mint); + carryout = Cudd_ApaAdd(digits,mint1,mint,mint); + } else { + carryout = Cudd_ApaAdd(digits,mint1,mint2,mint); + } + Cudd_ApaShiftRight(digits,carryout,mint,mint); + /* If the refernce count of a child is 1, its minterm count + ** hasn't been stored in table. Therefore, it must be explicitly + ** freed here. */ + if (Nt->ref == 1) FREE(mint1); + if (Cudd_Regular(Ne)->ref == 1) FREE(mint2); + + if (node->ref > 1) { + if (st_insert(table, (char *)node, (char *)mint) == ST_OUT_OF_MEM) { + FREE(mint); + return(NULL); + } + } + return(mint); + +} /* end of cuddApaCountMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory used to store the minterm counts recorded + in the visited table.] + + Description [Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +cuddApaStCountfree( + char * key, + char * value, + char * arg) +{ + DdApaNumber d; + + d = (DdApaNumber) value; + FREE(d); + return(ST_CONTINUE); + +} /* end of cuddApaStCountfree */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddApprox.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddApprox.c new file mode 100644 index 000000000..23f97415f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddApprox.c @@ -0,0 +1,2204 @@ +/**CFile*********************************************************************** + + FileName [cuddApprox.c] + + PackageName [cudd] + + Synopsis [Procedures to approximate a given BDD.] + + Description [External procedures provided by this module: +
                    +
                  • Cudd_UnderApprox() +
                  • Cudd_OverApprox() +
                  • Cudd_RemapUnderApprox() +
                  • Cudd_RemapOverApprox() +
                  • Cudd_BiasedUnderApprox() +
                  • Cudd_BiasedOverApprox() +
                  + Internal procedures included in this module: +
                    +
                  • cuddUnderApprox() +
                  • cuddRemapUnderApprox() +
                  • cuddBiasedUnderApprox() +
                  + Static procedures included in this module: +
                    +
                  • updateParity() +
                  • gatherInfoAux() +
                  • gatherInfo() +
                  • computeSavings() +
                  • updateRefs() +
                  • UAmarkNodes() +
                  • UAbuildSubset() +
                  • RAmarkNodes() +
                  • BAmarkNodes() +
                  • RAbuildSubset() +
                  • BAapplyBias() +
                  + ] + + SeeAlso [cuddSubsetHB.c cuddSubsetSP.c cuddGenCof.c] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#ifdef __STDC__ +#include +#else +#define DBL_MAX_EXP 1024 +#endif +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define NOTHING 0 +#define REPLACE_T 1 +#define REPLACE_E 2 +#define REPLACE_N 3 +#define REPLACE_TT 4 +#define REPLACE_TE 5 + +#define DONT_CARE 0 +#define CARE 1 +#define TOTAL_CARE 2 +#define CARE_ERROR 3 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/* Data structure to store the information on each node. It keeps the +** number of minterms of the function rooted at this node in terms of +** the number of variables specified by the user; the number of +** minterms of the complement; the impact of the number of minterms of +** this function on the number of minterms of the root function; the +** reference count of the node from within the root function; the +** flag that says whether the node intersects the care set; the flag +** that says whether the node should be replaced and how; the results +** of subsetting in both phases. */ +typedef struct NodeData { + double mintermsP; /* minterms for the regular node */ + double mintermsN; /* minterms for the complemented node */ + int functionRef; /* references from within this function */ + char care; /* node intersects care set */ + char replace; /* replacement decision */ + short int parity; /* 1: even; 2: odd; 3: both */ + DdNode *resultP; /* result for even parity */ + DdNode *resultN; /* result for odd parity */ +} NodeData; + +typedef struct ApproxInfo { + DdNode *one; /* one constant */ + DdNode *zero; /* BDD zero constant */ + NodeData *page; /* per-node information */ + DdHashTable *table; /* hash table to access the per-node info */ + int index; /* index of the current node */ + double max; /* max number of minterms */ + int size; /* how many nodes are left */ + double minterms; /* how many minterms are left */ +} ApproxInfo; + +/* Item of the queue used in the levelized traversal of the BDD. */ +typedef struct GlobalQueueItem { + struct GlobalQueueItem *next; + struct GlobalQueueItem *cnext; + DdNode *node; + double impactP; + double impactN; +} GlobalQueueItem; + +typedef struct LocalQueueItem { + struct LocalQueueItem *next; + struct LocalQueueItem *cnext; + DdNode *node; + int localRef; +} LocalQueueItem; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddApprox.c,v 1.31 2012/02/05 04:38:07 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void updateParity (DdNode *node, ApproxInfo *info, int newparity); +static NodeData * gatherInfoAux (DdNode *node, ApproxInfo *info, int parity); +static ApproxInfo * gatherInfo (DdManager *dd, DdNode *node, int numVars, int parity); +static int computeSavings (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue); +static int updateRefs (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue); +static int UAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, int safe, double quality); +static DdNode * UAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info); +static int RAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality); +static int BAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality1, double quality0); +static DdNode * RAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info); +static int BAapplyBias (DdManager *dd, DdNode *f, DdNode *b, ApproxInfo *info, DdHashTable *cache); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with Shiple's + underapproximation method.] + + Description [Extracts a dense subset from a BDD. This procedure uses + a variant of Tom Shiple's underapproximation method. The main + difference from the original method is that density is used as cost + function. Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value + returned by Cudd_ReadSize for numVars when the number of variables + is under 1023. If numVars is larger than 1023, it will cause + overflow. If a 0 parameter is passed then the procedure will compute + a value which will avoid overflow but will cause underflow with 2046 + variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_UnderApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddUnderApprox(dd, f, numVars, threshold, safe, quality); + } while (dd->reordered == 1); + + return(subset); + +} /* end of Cudd_UnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with Shiple's + underapproximation method.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the underapproximation procedure except for the fact that it + works on the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_OverApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddUnderApprox(dd, g, numVars, threshold, safe, quality); + } while (dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_OverApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the remapping + underapproximation method.] + + Description [Extracts a dense subset from a BDD. This procedure uses + a remapping technique and density as the cost function. + Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value + returned by Cudd_ReadSize for numVars when the number of variables + is under 1023. If numVars is larger than 1023, it will cause + overflow. If a 0 parameter is passed then the procedure will compute + a value which will avoid overflow but will cause underflow with 2046 + variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_RemapUnderApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddRemapUnderApprox(dd, f, numVars, threshold, quality); + } while (dd->reordered == 1); + + return(subset); + +} /* end of Cudd_RemapUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the remapping + underapproximation method.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the underapproximation procedure except for the fact that it + works on the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_RemapOverApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddRemapUnderApprox(dd, g, numVars, threshold, quality); + } while (dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_RemapOverApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the biased + underapproximation method.] + + Description [Extracts a dense subset from a BDD. This procedure uses + a biased remapping technique and density as the cost function. The bias + is a function. This procedure tries to approximate where the bias is 0 + and preserve the given function where the bias is 1. + Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value + returned by Cudd_ReadSize for numVars when the number of variables + is under 1023. If numVars is larger than 1023, it will cause + overflow. If a 0 parameter is passed then the procedure will compute + a value which will avoid overflow but will cause underflow with 2046 + variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox + Cudd_RemapUnderApprox Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_BiasedUnderApprox( + DdManager *dd /* manager */, + DdNode *f /* function to be subset */, + DdNode *b /* bias function */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality1 /* minimum improvement for accepted changes when b=1 */, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddBiasedUnderApprox(dd, f, b, numVars, threshold, quality1, + quality0); + } while (dd->reordered == 1); + + return(subset); + +} /* end of Cudd_BiasedUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the biased + underapproximation method.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the underapproximation procedure except for the fact that it + works on the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths + Cudd_RemapOverApprox Cudd_BiasedUnderApprox Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_BiasedOverApprox( + DdManager *dd /* manager */, + DdNode *f /* function to be superset */, + DdNode *b /* bias function */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality1 /* minimum improvement for accepted changes when b=1*/, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddBiasedUnderApprox(dd, g, b, numVars, threshold, quality1, + quality0); + } while (dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_BiasedOverApprox */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Applies Tom Shiple's underappoximation algorithm.] + + Description [Applies Tom Shiple's underappoximation algorithm. Proceeds + in three phases: +
                    +
                  • collect information on each node in the BDD; this is done via DFS. +
                  • traverse the BDD in top-down fashion and compute for each node + whether its elimination increases density. +
                  • traverse the BDD via DFS and actually perform the elimination. +
                  + Returns the approximated BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_UnderApprox] + +******************************************************************************/ +DdNode * +cuddUnderApprox( + DdManager * dd /* DD manager */, + DdNode * f /* current DD */, + int numVars /* maximum number of variables */, + int threshold /* threshold under which approximation stops */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + ApproxInfo *info; + DdNode *subset; + int result; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + return(NULL); + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + /* Create table where node data are accessible via a hash table. */ + info = gatherInfo(dd, f, numVars, safe); + if (info == NULL) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Mark nodes that should be replaced by zero. */ + result = UAmarkNodes(dd, f, info, threshold, safe, quality); + if (result == 0) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Build the result. */ + subset = UAbuildSubset(dd, f, info); +#if 1 + if (subset && info->size < Cudd_DagSize(subset)) + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); +#endif + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + +#ifdef DD_DEBUG + if (subset != NULL) { + cuddRef(subset); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + } + cuddDeref(subset); + } +#endif + return(subset); + +} /* end of cuddUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Applies the remapping underappoximation algorithm.] + + Description [Applies the remapping underappoximation algorithm. + Proceeds in three phases: +
                    +
                  • collect information on each node in the BDD; this is done via DFS. +
                  • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
                  • traverse the BDD via DFS and actually perform the elimination. +
                  + Returns the approximated BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_RemapUnderApprox] + +******************************************************************************/ +DdNode * +cuddRemapUnderApprox( + DdManager * dd /* DD manager */, + DdNode * f /* current DD */, + int numVars /* maximum number of variables */, + int threshold /* threshold under which approximation stops */, + double quality /* minimum improvement for accepted changes */) +{ + ApproxInfo *info; + DdNode *subset; + int result; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + /* Create table where node data are accessible via a hash table. */ + info = gatherInfo(dd, f, numVars, CUDD_TRUE); + if (info == NULL) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Mark nodes that should be replaced by zero. */ + result = RAmarkNodes(dd, f, info, threshold, quality); + if (result == 0) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Build the result. */ + subset = RAbuildSubset(dd, f, info); +#if 1 + if (subset && info->size < Cudd_DagSize(subset)) + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); +#endif + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + +#ifdef DD_DEBUG + if (subset != NULL) { + cuddRef(subset); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + } + cuddDeref(subset); + dd->errorCode = CUDD_INTERNAL_ERROR; + } +#endif + return(subset); + +} /* end of cuddRemapUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Applies the biased remapping underappoximation algorithm.] + + Description [Applies the biased remapping underappoximation algorithm. + Proceeds in three phases: +
                    +
                  • collect information on each node in the BDD; this is done via DFS. +
                  • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
                  • traverse the BDD via DFS and actually perform the elimination. +
                  + Returns the approximated BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_BiasedUnderApprox] + +******************************************************************************/ +DdNode * +cuddBiasedUnderApprox( + DdManager *dd /* DD manager */, + DdNode *f /* current DD */, + DdNode *b /* bias function */, + int numVars /* maximum number of variables */, + int threshold /* threshold under which approximation stops */, + double quality1 /* minimum improvement for accepted changes when b=1 */, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + ApproxInfo *info; + DdNode *subset; + int result; + DdHashTable *cache; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + /* Create table where node data are accessible via a hash table. */ + info = gatherInfo(dd, f, numVars, CUDD_TRUE); + if (info == NULL) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + cache = cuddHashTableInit(dd,2,2); + result = BAapplyBias(dd, Cudd_Regular(f), b, info, cache); + if (result == CARE_ERROR) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + cuddHashTableQuit(cache); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + cuddHashTableQuit(cache); + + /* Mark nodes that should be replaced by zero. */ + result = BAmarkNodes(dd, f, info, threshold, quality1, quality0); + if (result == 0) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Build the result. */ + subset = RAbuildSubset(dd, f, info); +#if 1 + if (subset && info->size < Cudd_DagSize(subset)) + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); +#endif + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + +#ifdef DD_DEBUG + if (subset != NULL) { + cuddRef(subset); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + } + cuddDeref(subset); + dd->errorCode = CUDD_INTERNAL_ERROR; + } +#endif + return(subset); + +} /* end of cuddBiasedUnderApprox */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Recursively update the parity of the paths reaching a node.] + + Description [Recursively update the parity of the paths reaching a node. + Assumes that node is regular and propagates the invariant.] + + SideEffects [None] + + SeeAlso [gatherInfoAux] + +******************************************************************************/ +static void +updateParity( + DdNode * node /* function to analyze */, + ApproxInfo * info /* info on BDD */, + int newparity /* new parity for node */) +{ + NodeData *infoN; + DdNode *E; + + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node)) == NULL) + return; + if ((infoN->parity & newparity) != 0) return; + infoN->parity |= (short) newparity; + if (Cudd_IsConstant(node)) return; + updateParity(cuddT(node),info,newparity); + E = cuddE(node); + if (Cudd_IsComplement(E)) { + updateParity(Cudd_Not(E),info,3-newparity); + } else { + updateParity(E,info,newparity); + } + return; + +} /* end of updateParity */ + + +/**Function******************************************************************** + + Synopsis [Recursively counts minterms and computes reference counts + of each node in the BDD.] + + Description [Recursively counts minterms and computes reference + counts of each node in the BDD. Similar to the cuddCountMintermAux + which recursively counts the number of minterms for the dag rooted + at each node in terms of the total number of variables (max). It assumes + that the node pointer passed to it is regular and it maintains the + invariant.] + + SideEffects [None] + + SeeAlso [gatherInfo] + +******************************************************************************/ +static NodeData * +gatherInfoAux( + DdNode * node /* function to analyze */, + ApproxInfo * info /* info on BDD */, + int parity /* gather parity information */) +{ + DdNode *N, *Nt, *Ne; + NodeData *infoN, *infoT, *infoE; + + N = Cudd_Regular(node); + + /* Check whether entry for this node exists. */ + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, N)) != NULL) { + if (parity) { + /* Update parity and propagate. */ + updateParity(N, info, 1 + (int) Cudd_IsComplement(node)); + } + return(infoN); + } + + /* Compute the cofactors. */ + Nt = Cudd_NotCond(cuddT(N), N != node); + Ne = Cudd_NotCond(cuddE(N), N != node); + + infoT = gatherInfoAux(Nt, info, parity); + if (infoT == NULL) return(NULL); + infoE = gatherInfoAux(Ne, info, parity); + if (infoE == NULL) return(NULL); + + infoT->functionRef++; + infoE->functionRef++; + + /* Point to the correct location in the page. */ + infoN = &(info->page[info->index++]); + infoN->parity |= (short) (1 + Cudd_IsComplement(node)); + + infoN->mintermsP = infoT->mintermsP/2; + infoN->mintermsN = infoT->mintermsN/2; + if (Cudd_IsComplement(Ne) ^ Cudd_IsComplement(node)) { + infoN->mintermsP += infoE->mintermsN/2; + infoN->mintermsN += infoE->mintermsP/2; + } else { + infoN->mintermsP += infoE->mintermsP/2; + infoN->mintermsN += infoE->mintermsN/2; + } + + /* Insert entry for the node in the table. */ + if (cuddHashTableGenericInsert(info->table, N, infoN) == 0) { + return(NULL); + } + return(infoN); + +} /* end of gatherInfoAux */ + + +/**Function******************************************************************** + + Synopsis [Gathers information about each node.] + + Description [Counts minterms and computes reference counts of each + node in the BDD. The minterm count is separately computed for the + node and its complement. This is to avoid cancellation + errors. Returns a pointer to the data structure holding the + information gathered if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddUnderApprox gatherInfoAux] + +******************************************************************************/ +static ApproxInfo * +gatherInfo( + DdManager * dd /* manager */, + DdNode * node /* function to be analyzed */, + int numVars /* number of variables node depends on */, + int parity /* gather parity information */) +{ + ApproxInfo * info; + NodeData * infoTop; + + /* If user did not give numVars value, set it to the maximum + ** exponent that the pow function can take. The -1 is due to the + ** discrepancy in the value that pow takes and the value that + ** log gives. + */ + if (numVars == 0) { + numVars = DBL_MAX_EXP - 1; + } + + info = ALLOC(ApproxInfo,1); + if (info == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + info->max = pow(2.0,(double) numVars); + info->one = DD_ONE(dd); + info->zero = Cudd_Not(info->one); + info->size = Cudd_DagSize(node); + /* All the information gathered will be stored in a contiguous + ** piece of memory, which is allocated here. This can be done + ** efficiently because we have counted the number of nodes of the + ** BDD. info->index points to the next available entry in the array + ** that stores the per-node information. */ + info->page = ALLOC(NodeData,info->size); + if (info->page == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(info); + return(NULL); + } + memset(info->page, 0, info->size * sizeof(NodeData)); /* clear all page */ + info->table = cuddHashTableInit(dd,1,info->size); + if (info->table == NULL) { + FREE(info->page); + FREE(info); + return(NULL); + } + /* We visit the DAG in post-order DFS. Hence, the constant node is + ** in first position, and the root of the DAG is in last position. */ + + /* Info for the constant node: Initialize only fields different from 0. */ + if (cuddHashTableGenericInsert(info->table, info->one, info->page) == 0) { + FREE(info->page); + FREE(info); + cuddHashTableGenericQuit(info->table); + return(NULL); + } + info->page[0].mintermsP = info->max; + info->index = 1; + + infoTop = gatherInfoAux(node,info,parity); + if (infoTop == NULL) { + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + return(NULL); + } + if (Cudd_IsComplement(node)) { + info->minterms = infoTop->mintermsN; + } else { + info->minterms = infoTop->mintermsP; + } + + infoTop->functionRef = 1; + return(info); + +} /* end of gatherInfo */ + + +/**Function******************************************************************** + + Synopsis [Counts the nodes that would be eliminated if a given node + were replaced by zero.] + + Description [Counts the nodes that would be eliminated if a given + node were replaced by zero. This procedure uses a queue passed by + the caller for efficiency: since the queue is left empty at the + endof the search, it can be reused as is by the next search. Returns + the count (always striclty positive) if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [UAmarkNodes RAmarkNodes BAmarkNodes] + +******************************************************************************/ +static int +computeSavings( + DdManager * dd, + DdNode * f, + DdNode * skip, + ApproxInfo * info, + DdLevelQueue * queue) +{ + NodeData *infoN; + LocalQueueItem *item; + DdNode *node; + int savings = 0; + + node = Cudd_Regular(f); + skip = Cudd_Regular(skip); + /* Insert the given node in the level queue. Its local reference + ** count is set equal to the function reference count so that the + ** search will continue from it when it is retrieved. */ + item = (LocalQueueItem *) + cuddLevelQueueFirst(queue,node,cuddI(dd,node->index)); + if (item == NULL) + return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node); + item->localRef = infoN->functionRef; + + /* Process the queue. */ + while ((item = (LocalQueueItem *) queue->first) != NULL) { + node = item->node; + if (node != skip) { + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,node); + if (item->localRef == infoN->functionRef) { + /* This node is not shared. */ + DdNode *nodeT, *nodeE; + savings++; + nodeT = cuddT(node); + if (!cuddIsConstant(nodeT)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeT,cuddI(dd,nodeT->index)); + if (item == NULL) return(0); + item->localRef++; + } + nodeE = Cudd_Regular(cuddE(node)); + if (!cuddIsConstant(nodeE)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeE,cuddI(dd,nodeE->index)); + if (item == NULL) return(0); + item->localRef++; + } + } + } + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + } + +#ifdef DD_DEBUG + /* At the end of a local search the queue should be empty. */ + assert(queue->size == 0); +#endif + return(savings); + +} /* end of computeSavings */ + + +/**Function******************************************************************** + + Synopsis [Update function reference counts.] + + Description [Update function reference counts to account for replacement. + Returns the number of nodes saved if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [UAmarkNodes RAmarkNodes BAmarkNodes] + +******************************************************************************/ +static int +updateRefs( + DdManager * dd, + DdNode * f, + DdNode * skip, + ApproxInfo * info, + DdLevelQueue * queue) +{ + NodeData *infoN; + LocalQueueItem *item; + DdNode *node; + int savings = 0; + + node = Cudd_Regular(f); + /* Insert the given node in the level queue. Its function reference + ** count is set equal to 0 so that the search will continue from it + ** when it is retrieved. */ + item = (LocalQueueItem *) cuddLevelQueueFirst(queue,node,cuddI(dd,node->index)); + if (item == NULL) + return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node); + infoN->functionRef = 0; + + if (skip != NULL) { + /* Increase the function reference count of the node to be skipped + ** by 1 to account for the node pointing to it that will be created. */ + skip = Cudd_Regular(skip); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, skip); + infoN->functionRef++; + } + + /* Process the queue. */ + while ((item = (LocalQueueItem *) queue->first) != NULL) { + node = item->node; + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,node); + if (infoN->functionRef == 0) { + /* This node is not shared or to be be skipped. */ + DdNode *nodeT, *nodeE; + savings++; + nodeT = cuddT(node); + if (!cuddIsConstant(nodeT)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeT,cuddI(dd,nodeT->index)); + if (item == NULL) return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,nodeT); + infoN->functionRef--; + } + nodeE = Cudd_Regular(cuddE(node)); + if (!cuddIsConstant(nodeE)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeE,cuddI(dd,nodeE->index)); + if (item == NULL) return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,nodeE); + infoN->functionRef--; + } + } + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + } + +#ifdef DD_DEBUG + /* At the end of a local search the queue should be empty. */ + assert(queue->size == 0); +#endif + return(savings); + +} /* end of updateRefs */ + + +/**Function******************************************************************** + + Synopsis [Marks nodes for replacement by zero.] + + Description [Marks nodes for replacement by zero. Returns 1 if successful; + 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddUnderApprox] + +******************************************************************************/ +static int +UAmarkNodes( + DdManager * dd /* manager */, + DdNode * f /* function to be analyzed */, + ApproxInfo * info /* info on BDD */, + int threshold /* when to stop approximating */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdLevelQueue *queue; + DdLevelQueue *localQueue; + NodeData *infoN; + GlobalQueueItem *item; + DdNode *node; + double numOnset; + double impactP, impactN; + int savings; + +#if 0 + (void) printf("initial size = %d initial minterms = %g\n", + info->size, info->minterms); +#endif + queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); + if (queue == NULL) { + return(0); + } + localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), + dd->initSlots); + if (localQueue == NULL) { + cuddLevelQueueQuit(queue); + return(0); + } + node = Cudd_Regular(f); + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + if (item == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + if (Cudd_IsComplement(f)) { + item->impactP = 0.0; + item->impactN = 1.0; + } else { + item->impactP = 1.0; + item->impactN = 0.0; + } + while (queue->first != NULL) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; + node = Cudd_Regular(node); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node); + if (safe && infoN->parity == 3) { + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + impactP = item->impactP; + impactN = item->impactN; + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,NULL,info,localQueue); + if (savings == 0) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); +#if 0 + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); +#endif + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = CUDD_TRUE; + info->size -= savings; + info->minterms -=numOnset; +#if 0 + (void) printf("replace: new size = %d new minterms = %g\n", + info->size, info->minterms); +#endif + savings -= updateRefs(dd,node,NULL,info,localQueue); + assert(savings == 0); + continue; + } + if (!cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + if (!Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(1); + +} /* end of UAmarkNodes */ + + +/**Function******************************************************************** + + Synopsis [Builds the subset BDD.] + + Description [Builds the subset BDD. Based on the info table, + replaces selected nodes by zero. Returns a pointer to the result if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddUnderApprox] + +******************************************************************************/ +static DdNode * +UAbuildSubset( + DdManager * dd /* DD manager */, + DdNode * node /* current node */, + ApproxInfo * info /* node info */) +{ + + DdNode *Nt, *Ne, *N, *t, *e, *r; + NodeData *infoN; + + if (Cudd_IsConstant(node)) + return(node); + + N = Cudd_Regular(node); + + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, N)) != NULL) { + if (infoN->replace == CUDD_TRUE) { + return(info->zero); + } + if (N == node ) { + if (infoN->resultP != NULL) { + return(infoN->resultP); + } + } else { + if (infoN->resultN != NULL) { + return(infoN->resultN); + } + } + } else { + (void) fprintf(dd->err, + "Something is wrong, ought to be in info table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node)); + Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node)); + + t = UAbuildSubset(dd, Nt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + + e = UAbuildSubset(dd, Ne, info); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + if (N == node) { + infoN->resultP = r; + } else { + infoN->resultN = r; + } + + return(r); + +} /* end of UAbuildSubset */ + + +/**Function******************************************************************** + + Synopsis [Marks nodes for remapping.] + + Description [Marks nodes for remapping. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddRemapUnderApprox] + +******************************************************************************/ +static int +RAmarkNodes( + DdManager * dd /* manager */, + DdNode * f /* function to be analyzed */, + ApproxInfo * info /* info on BDD */, + int threshold /* when to stop approximating */, + double quality /* minimum improvement for accepted changes */) +{ + DdLevelQueue *queue; + DdLevelQueue *localQueue; + NodeData *infoN, *infoT, *infoE; + GlobalQueueItem *item; + DdNode *node, *T, *E; + DdNode *shared; /* grandchild shared by the two children of node */ + double numOnset; + double impact, impactP, impactN; + double minterms; + int savings; + int replace; + +#if 0 + (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n", + info->size, info->minterms); +#endif + queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); + if (queue == NULL) { + return(0); + } + localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), + dd->initSlots); + if (localQueue == NULL) { + cuddLevelQueueQuit(queue); + return(0); + } + /* Enqueue regular pointer to root and initialize impact. */ + node = Cudd_Regular(f); + item = (GlobalQueueItem *) + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + if (item == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + if (Cudd_IsComplement(f)) { + item->impactP = 0.0; + item->impactN = 1.0; + } else { + item->impactP = 1.0; + item->impactN = 0.0; + } + /* The nodes retrieved here are guaranteed to be non-terminal. + ** The initial node is not terminal because constant nodes are + ** dealt with in the calling procedure. Subsequent nodes are inserted + ** only if they are not terminal. */ + while ((item = (GlobalQueueItem *) queue->first) != NULL) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + node = item->node; +#ifdef DD_DEBUG + assert(item->impactP >= 0 && item->impactP <= 1.0); + assert(item->impactN >= 0 && item->impactN <= 1.0); + assert(!Cudd_IsComplement(node)); + assert(!Cudd_IsConstant(node)); +#endif + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node)) == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } +#ifdef DD_DEBUG + assert(infoN->parity >= 1 && infoN->parity <= 3); +#endif + if (infoN->parity == 3) { + /* This node can be reached through paths of different parity. + ** It is not safe to replace it, because remapping will give + ** an incorrect result, while replacement by 0 may cause node + ** splitting. */ + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + T = cuddT(node); + E = cuddE(node); + shared = NULL; + impactP = item->impactP; + impactN = item->impactN; + if (Cudd_bddLeq(dd,T,E)) { + /* Here we know that E is regular. */ +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(E)); +#endif + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, E); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; + if (infoE->functionRef == 1 && !cuddIsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; + if (infoT->functionRef == 1 && !cuddIsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } + numOnset = impact * minterms; + } else if (Cudd_bddLeq(dd,E,T)) { + /* Here E may be complemented. */ + DdNode *Ereg = Cudd_Regular(E); + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, Ereg); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoT->mintermsP/2.0 - + ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; + if (infoT->functionRef == 1 && !cuddIsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = ((E == Ereg) ? infoE->mintermsN : + infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; + if (infoE->functionRef == 1 && !cuddIsConstant(Ereg)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } + numOnset = impact * minterms; + } else { + DdNode *Ereg = Cudd_Regular(E); + DdNode *TT = cuddT(T); + DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TT == ET) { + shared = TT; + replace = REPLACE_TT; + } else { + DdNode *TE = cuddE(T); + DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TE == EE) { + shared = TE; + replace = REPLACE_TE; + } else { + replace = REPLACE_N; + } + } + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,shared,info,localQueue); + if (shared != NULL) { + NodeData *infoS; + infoS = (NodeData *) cuddHashTableGenericLookup(info->table, Cudd_Regular(shared)); + if (Cudd_IsComplement(shared)) { + numOnset -= (infoS->mintermsN * impactP + + infoS->mintermsP * impactN)/2.0; + } else { + numOnset -= (infoS->mintermsP * impactP + + infoS->mintermsN * impactN)/2.0; + } + savings--; + } + } + + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); +#if 0 + if (replace == REPLACE_T || replace == REPLACE_E) + (void) printf("node %p: impact = %g numOnset = %g savings %d\n", + node, impact, numOnset, savings); + else + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); +#endif + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = (char) replace; + info->size -= savings; + info->minterms -=numOnset; +#if 0 + (void) printf("remap(%d): new size = %d new minterms = %g\n", + replace, info->size, info->minterms); +#endif + if (replace == REPLACE_N) { + savings -= updateRefs(dd,node,NULL,info,localQueue); + } else if (replace == REPLACE_T) { + savings -= updateRefs(dd,node,E,info,localQueue); + } else if (replace == REPLACE_E) { + savings -= updateRefs(dd,node,T,info,localQueue); + } else { +#ifdef DD_DEBUG + assert(replace == REPLACE_TT || replace == REPLACE_TE); +#endif + savings -= updateRefs(dd,node,shared,info,localQueue) - 1; + } + assert(savings == 0); + } else { + replace = NOTHING; + } + if (replace == REPLACE_N) continue; + if ((replace == REPLACE_E || replace == NOTHING) && + !cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (replace == REPLACE_E) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + if ((replace == REPLACE_T || replace == NOTHING) && + !Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + if ((replace == REPLACE_TT || replace == REPLACE_TE) && + !Cudd_IsConstant(shared)) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), + cuddI(dd,Cudd_Regular(shared)->index)); + if (Cudd_IsComplement(shared)) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactP; + item->impactN += impactN; + } + } + } + + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(1); + +} /* end of RAmarkNodes */ + + +/**Function******************************************************************** + + Synopsis [Marks nodes for remapping.] + + Description [Marks nodes for remapping. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddBiasedUnderApprox] + +******************************************************************************/ +static int +BAmarkNodes( + DdManager *dd /* manager */, + DdNode *f /* function to be analyzed */, + ApproxInfo *info /* info on BDD */, + int threshold /* when to stop approximating */, + double quality1 /* minimum improvement for accepted changes when b=1 */, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + DdLevelQueue *queue; + DdLevelQueue *localQueue; + NodeData *infoN, *infoT, *infoE; + GlobalQueueItem *item; + DdNode *node, *T, *E; + DdNode *shared; /* grandchild shared by the two children of node */ + double numOnset; + double impact, impactP, impactN; + double minterms; + double quality; + int savings; + int replace; + +#if 0 + (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n", + info->size, info->minterms); +#endif + queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); + if (queue == NULL) { + return(0); + } + localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), + dd->initSlots); + if (localQueue == NULL) { + cuddLevelQueueQuit(queue); + return(0); + } + /* Enqueue regular pointer to root and initialize impact. */ + node = Cudd_Regular(f); + item = (GlobalQueueItem *) + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + if (item == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + if (Cudd_IsComplement(f)) { + item->impactP = 0.0; + item->impactN = 1.0; + } else { + item->impactP = 1.0; + item->impactN = 0.0; + } + /* The nodes retrieved here are guaranteed to be non-terminal. + ** The initial node is not terminal because constant nodes are + ** dealt with in the calling procedure. Subsequent nodes are inserted + ** only if they are not terminal. */ + while (queue->first != NULL) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; +#ifdef DD_DEBUG + assert(item->impactP >= 0 && item->impactP <= 1.0); + assert(item->impactN >= 0 && item->impactN <= 1.0); + assert(!Cudd_IsComplement(node)); + assert(!Cudd_IsConstant(node)); +#endif + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node)) == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + quality = infoN->care ? quality1 : quality0; +#ifdef DD_DEBUG + assert(infoN->parity >= 1 && infoN->parity <= 3); +#endif + if (infoN->parity == 3) { + /* This node can be reached through paths of different parity. + ** It is not safe to replace it, because remapping will give + ** an incorrect result, while replacement by 0 may cause node + ** splitting. */ + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + T = cuddT(node); + E = cuddE(node); + shared = NULL; + impactP = item->impactP; + impactN = item->impactN; + if (Cudd_bddLeq(dd,T,E)) { + /* Here we know that E is regular. */ +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(E)); +#endif + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, E); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } + numOnset = impact * minterms; + } else if (Cudd_bddLeq(dd,E,T)) { + /* Here E may be complemented. */ + DdNode *Ereg = Cudd_Regular(E); + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, Ereg); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoT->mintermsP/2.0 - + ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = ((E == Ereg) ? infoE->mintermsN : + infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } + numOnset = impact * minterms; + } else { + DdNode *Ereg = Cudd_Regular(E); + DdNode *TT = cuddT(T); + DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TT == ET) { + shared = TT; + replace = REPLACE_TT; + } else { + DdNode *TE = cuddE(T); + DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TE == EE) { + shared = TE; + replace = REPLACE_TE; + } else { + replace = REPLACE_N; + } + } + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,shared,info,localQueue); + if (shared != NULL) { + NodeData *infoS; + infoS = (NodeData *) cuddHashTableGenericLookup(info->table, Cudd_Regular(shared)); + if (Cudd_IsComplement(shared)) { + numOnset -= (infoS->mintermsN * impactP + + infoS->mintermsP * impactN)/2.0; + } else { + numOnset -= (infoS->mintermsP * impactP + + infoS->mintermsN * impactN)/2.0; + } + savings--; + } + } + + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); +#if 0 + if (replace == REPLACE_T || replace == REPLACE_E) + (void) printf("node %p: impact = %g numOnset = %g savings %d\n", + node, impact, numOnset, savings); + else + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); +#endif + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = (char) replace; + info->size -= savings; + info->minterms -=numOnset; +#if 0 + (void) printf("remap(%d): new size = %d new minterms = %g\n", + replace, info->size, info->minterms); +#endif + if (replace == REPLACE_N) { + savings -= updateRefs(dd,node,NULL,info,localQueue); + } else if (replace == REPLACE_T) { + savings -= updateRefs(dd,node,E,info,localQueue); + } else if (replace == REPLACE_E) { + savings -= updateRefs(dd,node,T,info,localQueue); + } else { +#ifdef DD_DEBUG + assert(replace == REPLACE_TT || replace == REPLACE_TE); +#endif + savings -= updateRefs(dd,node,shared,info,localQueue) - 1; + } + assert(savings == 0); + } else { + replace = NOTHING; + } + if (replace == REPLACE_N) continue; + if ((replace == REPLACE_E || replace == NOTHING) && + !cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (replace == REPLACE_E) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + if ((replace == REPLACE_T || replace == NOTHING) && + !Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + if ((replace == REPLACE_TT || replace == REPLACE_TE) && + !Cudd_IsConstant(shared)) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), + cuddI(dd,Cudd_Regular(shared)->index)); + if (Cudd_IsComplement(shared)) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + } + + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(1); + +} /* end of BAmarkNodes */ + + +/**Function******************************************************************** + + Synopsis [Builds the subset BDD for cuddRemapUnderApprox.] + + Description [Builds the subset BDDfor cuddRemapUnderApprox. Based + on the info table, performs remapping or replacement at selected + nodes. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [cuddRemapUnderApprox] + +******************************************************************************/ +static DdNode * +RAbuildSubset( + DdManager * dd /* DD manager */, + DdNode * node /* current node */, + ApproxInfo * info /* node info */) +{ + DdNode *Nt, *Ne, *N, *t, *e, *r; + NodeData *infoN; + + if (Cudd_IsConstant(node)) + return(node); + + N = Cudd_Regular(node); + + Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node)); + Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node)); + + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, N)) != NULL) { + if (N == node ) { + if (infoN->resultP != NULL) { + return(infoN->resultP); + } + } else { + if (infoN->resultN != NULL) { + return(infoN->resultN); + } + } + if (infoN->replace == REPLACE_T) { + r = RAbuildSubset(dd, Ne, info); + return(r); + } else if (infoN->replace == REPLACE_E) { + r = RAbuildSubset(dd, Nt, info); + return(r); + } else if (infoN->replace == REPLACE_N) { + return(info->zero); + } else if (infoN->replace == REPLACE_TT) { + DdNode *Ntt = Cudd_NotCond(cuddT(cuddT(N)), + Cudd_IsComplement(node)); + int index = cuddT(N)->index; + e = info->zero; + t = RAbuildSubset(dd, Ntt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + return(r); + } else if (infoN->replace == REPLACE_TE) { + DdNode *Nte = Cudd_NotCond(cuddE(cuddT(N)), + Cudd_IsComplement(node)); + int index = cuddT(N)->index; + t = info->one; + e = RAbuildSubset(dd, Nte, info); + if (e == NULL) { + return(NULL); + } + cuddRef(e); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + r =Cudd_Not(r); + cuddDeref(e); + return(r); + } + } else { + (void) fprintf(dd->err, + "Something is wrong, ought to be in info table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + t = RAbuildSubset(dd, Nt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + + e = RAbuildSubset(dd, Ne, info); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + if (N == node) { + infoN->resultP = r; + } else { + infoN->resultN = r; + } + + return(r); + +} /* end of RAbuildSubset */ + + +/**Function******************************************************************** + + Synopsis [Finds don't care nodes.] + + Description [Finds don't care nodes by traversing f and b in parallel. + Returns the care status of the visited f node if successful; CARE_ERROR + otherwise.] + + SideEffects [None] + + SeeAlso [cuddBiasedUnderApprox] + +******************************************************************************/ +static int +BAapplyBias( + DdManager *dd, + DdNode *f, + DdNode *b, + ApproxInfo *info, + DdHashTable *cache) +{ + DdNode *one, *zero, *res; + DdNode *Ft, *Fe, *B, *Bt, *Be; + unsigned int topf, topb; + NodeData *infoF; + int careT, careE; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + if ((infoF = (NodeData *) cuddHashTableGenericLookup(info->table, f)) == NULL) + return(CARE_ERROR); + if (f == one) return(TOTAL_CARE); + if (b == zero) return(infoF->care); + if (infoF->care == TOTAL_CARE) return(TOTAL_CARE); + + if ((f->ref != 1 || Cudd_Regular(b)->ref != 1) && + (res = cuddHashTableLookup2(cache,f,b)) != NULL) { + if (res->ref == 0) { + cache->manager->dead++; + cache->manager->constants.dead++; + } + return(infoF->care); + } + + topf = dd->perm[f->index]; + B = Cudd_Regular(b); + topb = cuddI(dd,B->index); + if (topf <= topb) { + Ft = cuddT(f); Fe = cuddE(f); + } else { + Ft = Fe = f; + } + if (topb <= topf) { + /* We know that b is not constant because f is not. */ + Bt = cuddT(B); Be = cuddE(B); + if (Cudd_IsComplement(b)) { + Bt = Cudd_Not(Bt); + Be = Cudd_Not(Be); + } + } else { + Bt = Be = b; + } + + careT = BAapplyBias(dd, Ft, Bt, info, cache); + if (careT == CARE_ERROR) + return(CARE_ERROR); + careE = BAapplyBias(dd, Cudd_Regular(Fe), Be, info, cache); + if (careE == CARE_ERROR) + return(CARE_ERROR); + if (careT == TOTAL_CARE && careE == TOTAL_CARE) { + infoF->care = TOTAL_CARE; + } else { + infoF->care = CARE; + } + + if (f->ref != 1 || Cudd_Regular(b)->ref != 1) { + ptrint fanout = (ptrint) f->ref * Cudd_Regular(b)->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert2(cache,f,b,one,fanout)) { + return(CARE_ERROR); + } + } + return(infoF->care); + +} /* end of BAapplyBias */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBddAbs.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBddAbs.c new file mode 100644 index 000000000..a806078c5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBddAbs.c @@ -0,0 +1,760 @@ +/**CFile*********************************************************************** + + FileName [cuddBddAbs.c] + + PackageName [cudd] + + Synopsis [Quantification functions for BDDs.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_bddExistAbstract() +
                  • Cudd_bddExistAbstractLimit() +
                  • Cudd_bddXorExistAbstract() +
                  • Cudd_bddUnivAbstract() +
                  • Cudd_bddBooleanDiff() +
                  • Cudd_bddVarIsDependent() +
                  + Internal procedures included in this module: +
                    +
                  • cuddBddExistAbstractRecur() +
                  • cuddBddXorExistAbstractRecur() +
                  • cuddBddBooleanDiffRecur() +
                  + Static procedures included in this module: +
                    +
                  • bddCheckPositiveCube() +
                  + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.28 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int bddCheckPositiveCube (DdManager *manager, DdNode *cube); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Existentially abstracts all the variables in cube from f.] + + Description [Existentially abstracts all the variables in cube from f. + Returns the abstracted BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddUnivAbstract Cudd_addExistAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddExistAbstract */ + + +/**Function******************************************************************** + + Synopsis [Existentially abstracts all the variables in cube from f.] + + Description [Existentially abstracts all the variables in cube from f. + Returns the abstracted BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddExistAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddExistAbstractLimit( + DdManager * manager, + DdNode * f, + DdNode * cube, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = manager->maxLive; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + manager->maxLive = (manager->keys - manager->dead) + + (manager->keysZ - manager->deadZ) + limit; + do { + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + manager->maxLive = saveLimit; + + return(res); + +} /* end of Cudd_bddExistAbstractLimit */ + + +/**Function******************************************************************** + + Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the exclusive OR of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddUnivAbstract Cudd_bddExistAbstract Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddXorExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *res; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddBddXorExistAbstractRecur(manager, f, g, cube); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddXorExistAbstract */ + + +/**Function******************************************************************** + + Synopsis [Universally abstracts all the variables in cube from f.] + + Description [Universally abstracts all the variables in cube from f. + Returns the abstracted BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddExistAbstract Cudd_addUnivAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddUnivAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube); + } while (manager->reordered == 1); + if (res != NULL) res = Cudd_Not(res); + + return(res); + +} /* end of Cudd_bddUnivAbstract */ + + +/**Function******************************************************************** + + Synopsis [Computes the boolean difference of f with respect to x.] + + Description [Computes the boolean difference of f with respect to the + variable with index x. Returns the BDD of the boolean difference if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_bddBooleanDiff( + DdManager * manager, + DdNode * f, + int x) +{ + DdNode *res, *var; + + /* If the variable is not currently in the manager, f cannot + ** depend on it. + */ + if (x >= manager->size) return(Cudd_Not(DD_ONE(manager))); + var = manager->vars[x]; + + do { + manager->reordered = 0; + res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddBooleanDiff */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is dependent on others in a + function.] + + Description [Checks whether a variable is dependent on others in a + function. Returns 1 if the variable is dependent; 0 otherwise. No + new nodes are created.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_bddVarIsDependent( + DdManager *dd, /* manager */ + DdNode *f, /* function */ + DdNode *var /* variable */) +{ + DdNode *F, *res, *zero, *ft, *fe; + unsigned topf, level; + DD_CTFP cacheOp; + int retval; + + zero = Cudd_Not(DD_ONE(dd)); + if (Cudd_IsConstant(f)) return(f == zero); + + /* From now on f is not constant. */ + F = Cudd_Regular(f); + topf = (unsigned) dd->perm[F->index]; + level = (unsigned) dd->perm[var->index]; + + /* Check terminal case. If topf > index of var, f does not depend on var. + ** Therefore, var is not dependent in f. */ + if (topf > level) { + return(0); + } + + cacheOp = (DD_CTFP) Cudd_bddVarIsDependent; + res = cuddCacheLookup2(dd,cacheOp,f,var); + if (res != NULL) { + return(res != zero); + } + + /* Compute cofactors. */ + ft = Cudd_NotCond(cuddT(F), f != F); + fe = Cudd_NotCond(cuddE(F), f != F); + + if (topf == level) { + retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe)); + } else { + retval = Cudd_bddVarIsDependent(dd,ft,var) && + Cudd_bddVarIsDependent(dd,fe,var); + } + + cuddCacheInsert2(dd,cacheOp,f,var,Cudd_NotCond(zero,retval)); + + return(retval); + +} /* Cudd_bddVarIsDependent */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive steps of Cudd_bddExistAbstract.] + + Description [Performs the recursive steps of Cudd_bddExistAbstract. + Returns the BDD obtained by abstracting the variables + of cube from f if successful; NULL otherwise. It is also used by + Cudd_bddUnivAbstract.] + + SideEffects [None] + + SeeAlso [Cudd_bddExistAbstract Cudd_bddUnivAbstract] + +******************************************************************************/ +DdNode * +cuddBddExistAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *F, *T, *E, *res, *res1, *res2, *one; + + statLine(manager); + one = DD_ONE(manager); + F = Cudd_Regular(f); + + /* Cube is guaranteed to be a cube at this point. */ + if (cube == one || F == one) { + return(f); + } + /* From now on, f and cube are non-constant. */ + + /* Abstract a variable that does not appear in f. */ + while (manager->perm[F->index] > manager->perm[cube->index]) { + cube = cuddT(cube); + if (cube == one) return(f); + } + + /* Check the cache. */ + if (F->ref != 1 && (res = cuddCacheLookup2(manager, Cudd_bddExistAbstract, f, cube)) != NULL) { + return(res); + } + + /* Compute the cofactors of f. */ + T = cuddT(F); E = cuddE(F); + if (f != F) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + + /* If the two indices are the same, so are their levels. */ + if (F->index == cube->index) { + if (T == one || E == one || T == Cudd_Not(E)) { + return(one); + } + res1 = cuddBddExistAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + if (res1 == one) { + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, one); + return(one); + } + cuddRef(res1); + res2 = cuddBddExistAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddBddAndRecur(manager, Cudd_Not(res1), Cudd_Not(res2)); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + res = Cudd_Not(res); + cuddRef(res); + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); + cuddDeref(res); + return(res); + } else { /* if (cuddI(manager,F->index) < cuddI(manager,cube->index)) */ + res1 = cuddBddExistAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddBddExistAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager, res1); + return(NULL); + } + cuddRef(res2); + /* ITE takes care of possible complementation of res1 and of the + ** case in which res1 == res2. */ + res = cuddBddIteRecur(manager, manager->vars[F->index], res1, res2); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); + return(res); + } + +} /* end of cuddBddExistAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the exclusive OR of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +cuddBddXorExistAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *F, *fv, *fnv, *G, *gv, *gnv; + DdNode *one, *zero, *r, *t, *e, *Cube; + unsigned int topf, topg, topcube, top, index; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == g) { + return(zero); + } + if (f == Cudd_Not(g)) { + return(one); + } + if (cube == one) { + return(cuddBddXorRecur(manager, f, g)); + } + if (f == one) { + return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube)); + } + if (g == one) { + return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube)); + } + if (f == zero) { + return(cuddBddExistAbstractRecur(manager, g, cube)); + } + if (g == zero) { + return(cuddBddExistAbstractRecur(manager, f, cube)); + } + + /* At this point f, g, and cube are not constant. */ + + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; + g = tmp; + } + + /* Check cache. */ + r = cuddCacheLookup(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube); + if (r != NULL) { + return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + F = Cudd_Regular(f); + topf = manager->perm[F->index]; + G = Cudd_Regular(g); + topg = manager->perm[G->index]; + top = ddMin(topf, topg); + topcube = manager->perm[cube->index]; + + if (topcube < top) { + return(cuddBddXorExistAbstractRecur(manager, f, g, cuddT(cube))); + } + /* Now, topcube >= top. */ + + if (topf == top) { + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } + } else { + index = G->index; + fv = fnv = f; + } + + if (topg == top) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + if (topcube == top) { + Cube = cuddT(cube); + } else { + Cube = cube; + } + + t = cuddBddXorExistAbstractRecur(manager, fv, gv, Cube); + if (t == NULL) return(NULL); + + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. + */ + if (t == one && topcube == top) { + cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, one); + return(one); + } + cuddRef(t); + + e = cuddBddXorExistAbstractRecur(manager, fnv, gnv, Cube); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (topcube == top) { /* abstract */ + r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + cuddDeref(r); + } else if (t == e) { + r = t; + cuddDeref(t); + cuddDeref(e); + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + } + cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, r); + return (r); + +} /* end of cuddBddXorExistAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive steps of Cudd_bddBoleanDiff.] + + Description [Performs the recursive steps of Cudd_bddBoleanDiff. + Returns the BDD obtained by XORing the cofactors of f with respect to + var if successful; NULL otherwise. Exploits the fact that dF/dx = + dF'/dx.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddBddBooleanDiffRecur( + DdManager * manager, + DdNode * f, + DdNode * var) +{ + DdNode *T, *E, *res, *res1, *res2; + + statLine(manager); + if (cuddI(manager,f->index) > manager->perm[var->index]) { + /* f does not depend on var. */ + return(Cudd_Not(DD_ONE(manager))); + } + + /* From now on, f is non-constant. */ + + /* If the two indices are the same, so are their levels. */ + if (f->index == var->index) { + res = cuddBddXorRecur(manager, cuddT(f), cuddE(f)); + return(res); + } + + /* From now on, cuddI(manager,f->index) < cuddI(manager,cube->index). */ + + /* Check the cache. */ + res = cuddCacheLookup2(manager, cuddBddBooleanDiffRecur, f, var); + if (res != NULL) { + return(res); + } + + /* Compute the cofactors of f. */ + T = cuddT(f); E = cuddE(f); + + res1 = cuddBddBooleanDiffRecur(manager, T, var); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddBddBooleanDiffRecur(manager, Cudd_Regular(E), var); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager, res1); + return(NULL); + } + cuddRef(res2); + /* ITE takes care of possible complementation of res1 and of the + ** case in which res1 == res2. */ + res = cuddBddIteRecur(manager, manager->vars[f->index], res1, res2); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, cuddBddBooleanDiffRecur, f, var, res); + return(res); + +} /* end of cuddBddBooleanDiffRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Checks whether cube is an BDD representing the product of + positive literals.] + + Description [Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +bddCheckPositiveCube( + DdManager * manager, + DdNode * cube) +{ + if (Cudd_IsComplement(cube)) return(0); + if (cube == DD_ONE(manager)) return(1); + if (cuddIsConstant(cube)) return(0); + if (cuddE(cube) == Cudd_Not(DD_ONE(manager))) { + return(bddCheckPositiveCube(manager, cuddT(cube))); + } + return(0); + +} /* end of bddCheckPositiveCube */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBddCorr.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBddCorr.c new file mode 100644 index 000000000..e92d24ad6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBddCorr.c @@ -0,0 +1,515 @@ +/**CFile*********************************************************************** + + FileName [cuddBddCorr.c] + + PackageName [cudd] + + Synopsis [Correlation between BDDs.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_bddCorrelation() +
                  • Cudd_bddCorrelationWeights() +
                  + Static procedures included in this module: +
                    +
                  • bddCorrelationAux() +
                  • bddCorrelationWeightsAux() +
                  • CorrelCompare() +
                  • CorrelHash() +
                  • CorrelCleanUp() +
                  + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct hashEntry { + DdNode *f; + DdNode *g; +} HashEntry; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBddCorr.c,v 1.15 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef CORREL_STATS +static int num_calls; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static double bddCorrelationAux (DdManager *dd, DdNode *f, DdNode *g, st_table *table); +static double bddCorrelationWeightsAux (DdManager *dd, DdNode *f, DdNode *g, double *prob, st_table *table); +static int CorrelCompare (const char *key1, const char *key2); +static int CorrelHash (char *key, int modulus); +static enum st_retval CorrelCleanUp (char *key, char *value, char *arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the correlation of f and g.] + + Description [Computes the correlation of f and g. If f == g, their + correlation is 1. If f == g', their correlation is 0. Returns the + fraction of minterms in the ON-set of the EXNOR of f and g. If it + runs out of memory, returns (double)CUDD_OUT_OF_MEM.] + + SideEffects [None] + + SeeAlso [Cudd_bddCorrelationWeights] + +******************************************************************************/ +double +Cudd_bddCorrelation( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + + st_table *table; + double correlation; + +#ifdef CORREL_STATS + num_calls = 0; +#endif + + table = st_init_table(CorrelCompare,CorrelHash); + if (table == NULL) return((double)CUDD_OUT_OF_MEM); + correlation = bddCorrelationAux(manager,f,g,table); + st_foreach(table, CorrelCleanUp, NIL(char)); + st_free_table(table); + return(correlation); + +} /* end of Cudd_bddCorrelation */ + + +/**Function******************************************************************** + + Synopsis [Computes the correlation of f and g for given input + probabilities.] + + Description [Computes the correlation of f and g for given input + probabilities. On input, prob\[i\] is supposed to contain the + probability of the i-th input variable to be 1. + If f == g, their correlation is 1. If f == g', their + correlation is 0. Returns the probability that f and g have the same + value. If it runs out of memory, returns (double)CUDD_OUT_OF_MEM. The + correlation of f and the constant one gives the probability of f.] + + SideEffects [None] + + SeeAlso [Cudd_bddCorrelation] + +******************************************************************************/ +double +Cudd_bddCorrelationWeights( + DdManager * manager, + DdNode * f, + DdNode * g, + double * prob) +{ + + st_table *table; + double correlation; + +#ifdef CORREL_STATS + num_calls = 0; +#endif + + table = st_init_table(CorrelCompare,CorrelHash); + if (table == NULL) return((double)CUDD_OUT_OF_MEM); + correlation = bddCorrelationWeightsAux(manager,f,g,prob,table); + st_foreach(table, CorrelCleanUp, NIL(char)); + st_free_table(table); + return(correlation); + +} /* end of Cudd_bddCorrelationWeights */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCorrelation.] + + Description [Performs the recursive step of Cudd_bddCorrelation. + Returns the fraction of minterms in the ON-set of the EXNOR of f and + g.] + + SideEffects [None] + + SeeAlso [bddCorrelationWeightsAux] + +******************************************************************************/ +static double +bddCorrelationAux( + DdManager * dd, + DdNode * f, + DdNode * g, + st_table * table) +{ + DdNode *Fv, *Fnv, *G, *Gv, *Gnv; + double min, *pmin, min1, min2, *dummy; + HashEntry *entry; + unsigned int topF, topG; + + statLine(dd); +#ifdef CORREL_STATS + num_calls++; +#endif + + /* Terminal cases: only work for BDDs. */ + if (f == g) return(1.0); + if (f == Cudd_Not(g)) return(0.0); + + /* Standardize call using the following properties: + ** (f EXNOR g) = (g EXNOR f) + ** (f' EXNOR g') = (f EXNOR g). + */ + if (f > g) { + DdNode *tmp = f; + f = g; g = tmp; + } + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + g = Cudd_Not(g); + } + /* From now on, f is regular. */ + + entry = ALLOC(HashEntry,1); + if (entry == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + entry->f = f; entry->g = g; + + /* We do not use the fact that + ** correlation(f,g') = 1 - correlation(f,g) + ** to minimize the risk of cancellation. + */ + if (st_lookup(table, entry, &dummy)) { + min = *dummy; + FREE(entry); + return(min); + } + + G = Cudd_Regular(g); + topF = cuddI(dd,f->index); topG = cuddI(dd,G->index); + if (topF <= topG) { Fv = cuddT(f); Fnv = cuddE(f); } else { Fv = Fnv = f; } + if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; } + + if (g != G) { + Gv = Cudd_Not(Gv); + Gnv = Cudd_Not(Gnv); + } + + min1 = bddCorrelationAux(dd, Fv, Gv, table) / 2.0; + if (min1 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return(CUDD_OUT_OF_MEM); + } + min2 = bddCorrelationAux(dd, Fnv, Gnv, table) / 2.0; + if (min2 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return(CUDD_OUT_OF_MEM); + } + min = (min1+min2); + + pmin = ALLOC(double,1); + if (pmin == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + *pmin = min; + + if (st_insert(table,(char *)entry, (char *)pmin) == ST_OUT_OF_MEM) { + FREE(entry); + FREE(pmin); + return((double)CUDD_OUT_OF_MEM); + } + return(min); + +} /* end of bddCorrelationAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCorrelationWeigths.] + + Description [] + + SideEffects [None] + + SeeAlso [bddCorrelationAux] + +******************************************************************************/ +static double +bddCorrelationWeightsAux( + DdManager * dd, + DdNode * f, + DdNode * g, + double * prob, + st_table * table) +{ + DdNode *Fv, *Fnv, *G, *Gv, *Gnv; + double min, *pmin, min1, min2, *dummy; + HashEntry *entry; + int topF, topG, index; + + statLine(dd); +#ifdef CORREL_STATS + num_calls++; +#endif + + /* Terminal cases: only work for BDDs. */ + if (f == g) return(1.0); + if (f == Cudd_Not(g)) return(0.0); + + /* Standardize call using the following properties: + ** (f EXNOR g) = (g EXNOR f) + ** (f' EXNOR g') = (f EXNOR g). + */ + if (f > g) { + DdNode *tmp = f; + f = g; g = tmp; + } + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + g = Cudd_Not(g); + } + /* From now on, f is regular. */ + + entry = ALLOC(HashEntry,1); + if (entry == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + entry->f = f; entry->g = g; + + /* We do not use the fact that + ** correlation(f,g') = 1 - correlation(f,g) + ** to minimize the risk of cancellation. + */ + if (st_lookup(table, entry, &dummy)) { + min = *dummy; + FREE(entry); + return(min); + } + + G = Cudd_Regular(g); + topF = cuddI(dd,f->index); topG = cuddI(dd,G->index); + if (topF <= topG) { + Fv = cuddT(f); Fnv = cuddE(f); + index = f->index; + } else { + Fv = Fnv = f; + index = G->index; + } + if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; } + + if (g != G) { + Gv = Cudd_Not(Gv); + Gnv = Cudd_Not(Gnv); + } + + min1 = bddCorrelationWeightsAux(dd, Fv, Gv, prob, table) * prob[index]; + if (min1 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return((double)CUDD_OUT_OF_MEM); + } + min2 = bddCorrelationWeightsAux(dd, Fnv, Gnv, prob, table) * (1.0 - prob[index]); + if (min2 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return((double)CUDD_OUT_OF_MEM); + } + min = (min1+min2); + + pmin = ALLOC(double,1); + if (pmin == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + *pmin = min; + + if (st_insert(table,(char *)entry, (char *)pmin) == ST_OUT_OF_MEM) { + FREE(entry); + FREE(pmin); + return((double)CUDD_OUT_OF_MEM); + } + return(min); + +} /* end of bddCorrelationWeightsAux */ + + +/**Function******************************************************************** + + Synopsis [Compares two hash table entries.] + + Description [Compares two hash table entries. Returns 0 if they are + identical; 1 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +CorrelCompare( + const char * key1, + const char * key2) +{ + HashEntry *entry1; + HashEntry *entry2; + + entry1 = (HashEntry *) key1; + entry2 = (HashEntry *) key2; + if (entry1->f != entry2->f || entry1->g != entry2->g) return(1); + + return(0); + +} /* end of CorrelCompare */ + + +/**Function******************************************************************** + + Synopsis [Hashes a hash table entry.] + + Description [Hashes a hash table entry. It is patterned after + st_strhash. Returns a value between 0 and modulus.] + + SideEffects [None] + +******************************************************************************/ +static int +CorrelHash( + char * key, + int modulus) +{ + HashEntry *entry; + int val = 0; + + entry = (HashEntry *) key; +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + val = ((int) ((long)entry->f))*997 + ((int) ((long)entry->g)); +#else + val = ((int) entry->f)*997 + ((int) entry->g); +#endif + + return ((val < 0) ? -val : val) % modulus; + +} /* end of CorrelHash */ + + +/**Function******************************************************************** + + Synopsis [Frees memory associated with hash table.] + + Description [Frees memory associated with hash table. Returns + ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +CorrelCleanUp( + char * key, + char * value, + char * arg) +{ + double *d; + HashEntry *entry; + + entry = (HashEntry *) key; + FREE(entry); + d = (double *)value; + FREE(d); + return ST_CONTINUE; + +} /* end of CorrelCleanUp */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBddIte.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBddIte.c new file mode 100644 index 000000000..750a51c74 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBddIte.c @@ -0,0 +1,1430 @@ +/**CFile*********************************************************************** + + FileName [cuddBddIte.c] + + PackageName [cudd] + + Synopsis [BDD ITE function and satellites.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_bddIte() +
                  • Cudd_bddIteLimit() +
                  • Cudd_bddIteConstant() +
                  • Cudd_bddIntersect() +
                  • Cudd_bddAnd() +
                  • Cudd_bddAndLimit() +
                  • Cudd_bddOr() +
                  • Cudd_bddOrLimit() +
                  • Cudd_bddNand() +
                  • Cudd_bddNor() +
                  • Cudd_bddXor() +
                  • Cudd_bddXnor() +
                  • Cudd_bddXnorLimit() +
                  • Cudd_bddLeq() +
                  + Internal procedures included in this module: +
                    +
                  • cuddBddIteRecur() +
                  • cuddBddIntersectRecur() +
                  • cuddBddAndRecur() +
                  • cuddBddXorRecur() +
                  + Static procedures included in this module: +
                    +
                  • bddVarToConst() +
                  • bddVarToCanonical() +
                  • bddVarToCanonicalSimple() +
                  ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBddIte.c,v 1.26 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void bddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one); +static int bddVarToCanonical (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp); +static int bddVarToCanonicalSimple (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements ITE(f,g,h).] + + Description [Implements ITE(f,g,h). Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows + up.] + + SideEffects [None] + + SeeAlso [Cudd_addIte Cudd_bddIteConstant Cudd_bddIntersect] + +******************************************************************************/ +DdNode * +Cudd_bddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddIteRecur(dd,f,g,h); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddIte */ + + +/**Function******************************************************************** + + Synopsis [Implements ITE(f,g,h). Returns + NULL if too many nodes are required.] + + Description [Implements ITE(f,g,h). Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte] + +******************************************************************************/ +DdNode * +Cudd_bddIteLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddIteRecur(dd,f,g,h); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddIteLimit */ + + +/**Function******************************************************************** + + Synopsis [Implements ITEconstant(f,g,h).] + + Description [Implements ITEconstant(f,g,h). Returns a pointer to the + resulting BDD (which may or may not be constant) or DD_NON_CONSTANT. + No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_bddIntersect Cudd_bddLeq Cudd_addIteConstant] + +******************************************************************************/ +DdNode * +Cudd_bddIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + int comple; + unsigned int topf, topg, toph, v; + + statLine(dd); + /* Trivial cases. */ + if (f == one) /* ITE(1,G,H) => G */ + return(g); + + if (f == zero) /* ITE(0,G,H) => H */ + return(h); + + /* f now not a constant. */ + bddVarToConst(f, &g, &h, one); /* possibly convert g or h */ + /* to constants */ + + if (g == h) /* ITE(F,G,G) => G */ + return(g); + + if (Cudd_IsConstant(g) && Cudd_IsConstant(h)) + return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */ + /* => DD_NON_CONSTANT */ + + if (g == Cudd_Not(h)) + return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */ + /* if F != G and F != G' */ + + comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph); + + /* Cache lookup. */ + r = cuddConstantLookup(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h); + if (r != NULL) { + return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT)); + } + + v = ddMin(topg, toph); + + /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */ + if (topf < v && cuddT(f) == one && cuddE(f) == zero) { + return(DD_NON_CONSTANT); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf, v); /* v = top_var(F,G,H) */ + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + + if (topg == v) { + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + + if (toph == v) { + H = Cudd_Regular(h); + Hv = cuddT(H); Hnv = cuddE(H); + if (Cudd_IsComplement(h)) { + Hv = Cudd_Not(Hv); + Hnv = Cudd_Not(Hnv); + } + } else { + Hv = Hnv = h; + } + + /* Recursion. */ + t = Cudd_bddIteConstant(dd, Fv, Gv, Hv); + if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) { + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv); + if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) { + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t); + return(Cudd_NotCond(t,comple)); + +} /* end of Cudd_bddIteConstant */ + + +/**Function******************************************************************** + + Synopsis [Returns a function included in the intersection of f and g.] + + Description [Computes a function included in the intersection of f and + g. (That is, a witness that the intersection is not empty.) + Cudd_bddIntersect tries to build as few new nodes as possible. If the + only result of interest is whether f and g intersect, + Cudd_bddLeq should be used instead.] + + SideEffects [None] + + SeeAlso [Cudd_bddLeq Cudd_bddIteConstant] + +******************************************************************************/ +DdNode * +Cudd_bddIntersect( + DdManager * dd /* manager */, + DdNode * f /* first operand */, + DdNode * g /* second operand */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddIntersectRecur(dd,f,g); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_bddIntersect */ + + +/**Function******************************************************************** + + Synopsis [Computes the conjunction of two BDDs f and g.] + + Description [Computes the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAndAbstract Cudd_bddIntersect + Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddAnd( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddAnd */ + + +/**Function******************************************************************** + + Synopsis [Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required.] + + Description [Computes the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddAndLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddAndLimit */ + + +/**Function******************************************************************** + + Synopsis [Computes the disjunction of two BDDs f and g.] + + Description [Computes the disjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddNand Cudd_bddNor + Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddOr( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + } while (dd->reordered == 1); + res = Cudd_NotCond(res,res != NULL); + return(res); + +} /* end of Cudd_bddOr */ + + +/**Function******************************************************************** + + Synopsis [Computes the disjunction of two BDDs f and g. Returns + NULL if too many nodes are required.] + + Description [Computes the disjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddOr] + +******************************************************************************/ +DdNode * +Cudd_bddOrLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + res = Cudd_NotCond(res,res != NULL); + return(res); + +} /* end of Cudd_bddOrLimit */ + + +/**Function******************************************************************** + + Synopsis [Computes the NAND of two BDDs f and g.] + + Description [Computes the NAND of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNor + Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddNand( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + res = Cudd_NotCond(res,res != NULL); + return(res); + +} /* end of Cudd_bddNand */ + + +/**Function******************************************************************** + + Synopsis [Computes the NOR of two BDDs f and g.] + + Description [Computes the NOR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand + Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddNor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddNor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive OR of two BDDs f and g.] + + Description [Computes the exclusive OR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr + Cudd_bddNand Cudd_bddNor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddXor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddXor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive NOR of two BDDs f and g.] + + Description [Computes the exclusive NOR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr + Cudd_bddNand Cudd_bddNor Cudd_bddXor] + +******************************************************************************/ +DdNode * +Cudd_bddXnor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,Cudd_Not(g)); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddXnor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive NOR of two BDDs f and g. Returns + NULL if too many nodes are required.] + + Description [Computes the exclusive NOR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddXnorLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,Cudd_Not(g)); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddXnorLimit */ + + +/**Function******************************************************************** + + Synopsis [Determines whether f is less than or equal to g.] + + Description [Returns 1 if f is less than or equal to g; 0 otherwise. + No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_bddIteConstant Cudd_addEvalConst] + +******************************************************************************/ +int +Cudd_bddLeq( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *one, *zero, *tmp, *F, *fv, *fvn, *gv, *gvn; + unsigned int topf, topg, res; + + statLine(dd); + /* Terminal cases and normalization. */ + if (f == g) return(1); + + if (Cudd_IsComplement(g)) { + /* Special case: if f is regular and g is complemented, + ** f(1,...,1) = 1 > 0 = g(1,...,1). + */ + if (!Cudd_IsComplement(f)) return(0); + /* Both are complemented: Swap and complement because + ** f <= g <=> g' <= f' and we want the second argument to be regular. + */ + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } else if (Cudd_IsComplement(f) && g < f) { + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } + + /* Now g is regular and, if f is not regular, f < g. */ + one = DD_ONE(dd); + if (g == one) return(1); /* no need to test against zero */ + if (f == one) return(0); /* since at this point g != one */ + if (Cudd_Not(f) == g) return(0); /* because neither is constant */ + zero = Cudd_Not(one); + if (f == zero) return(1); + + /* Here neither f nor g is constant. */ + + /* Check cache. */ + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g); + if (tmp != NULL) { + return(tmp == one); + } + + /* Compute cofactors. */ + F = Cudd_Regular(f); + topf = dd->perm[F->index]; + topg = dd->perm[g->index]; + if (topf <= topg) { + fv = cuddT(F); fvn = cuddE(F); + if (f != F) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + } else { + fv = fvn = f; + } + if (topg <= topf) { + gv = cuddT(g); gvn = cuddE(g); + } else { + gv = gvn = g; + } + + /* Recursive calls. Since we want to maximize the probability of + ** the special case f(1,...,1) > g(1,...,1), we consider the negative + ** cofactors first. Indeed, the complementation parity of the positive + ** cofactors is the same as the one of the parent functions. + */ + res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv); + + /* Store result in cache and return. */ + cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero)); + return(res); + +} /* end of Cudd_bddLeq */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddIte.] + + Description [Implements the recursive step of Cudd_bddIte. Returns a + pointer to the resulting BDD. NULL if the intermediate result blows + up or if reordering occurs.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddBddIteRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *one, *zero, *res; + DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; + unsigned int topf, topg, toph, v; + int index; + int comple; + + statLine(dd); + /* Terminal cases. */ + + /* One variable cases. */ + if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */ + return(g); + + if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */ + return(h); + + /* From now on, f is known not to be a constant. */ + if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + if (h == zero) { /* ITE(F,1,0) = F */ + return(f); + } else { + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h)); + return(Cudd_NotCond(res,res != NULL)); + } + } else if (g == zero || f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ + if (h == one) { /* ITE(F,0,1) = !F */ + return(Cudd_Not(f)); + } else { + res = cuddBddAndRecur(dd,Cudd_Not(f),h); + return(res); + } + } + if (h == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + res = cuddBddAndRecur(dd,f,g); + return(res); + } else if (h == one || f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ + res = cuddBddAndRecur(dd,f,Cudd_Not(g)); + return(Cudd_NotCond(res,res != NULL)); + } + + /* Check remaining one variable case. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = F <-> G */ + res = cuddBddXorRecur(dd,f,h); + return(res); + } + + /* From here, there are no constants. */ + comple = bddVarToCanonicalSimple(dd, &f, &g, &h, &topf, &topg, &toph); + + /* f & g are now regular pointers */ + + v = ddMin(topg, toph); + + /* A shortcut: ITE(F,G,H) = (v,G,H) if F = (v,1,0), v < top(G,H). */ + if (topf < v && cuddT(f) == one && cuddE(f) == zero) { + r = cuddUniqueInter(dd, (int) f->index, g, h); + return(Cudd_NotCond(r,comple && r != NULL)); + } + + /* Check cache. */ + r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf, v); /* v = top_var(F,G,H) */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg == v) { + index = g->index; + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + if (toph == v) { + H = Cudd_Regular(h); + index = H->index; + Hv = cuddT(H); Hnv = cuddE(H); + if (Cudd_IsComplement(h)) { + Hv = Cudd_Not(Hv); + Hnv = Cudd_Not(Hnv); + } + } else { + Hv = Hnv = h; + } + + /* Recursive step. */ + t = cuddBddIteRecur(dd,Fv,Gv,Hv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert(dd, DD_BDD_ITE_TAG, f, g, h, r); + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddIteRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddIntersect.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_bddIntersect] + +******************************************************************************/ +DdNode * +cuddBddIntersectRecur( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + DdNode *F, *G, *t, *e; + DdNode *fv, *fnv, *gv, *gnv; + DdNode *one, *zero; + unsigned int index, topf, topg; + + statLine(dd); + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == g || g == one) return(f); + if (f == one) return(g); + + /* At this point f and g are not constant. */ + if (f > g) { DdNode *tmp = f; f = g; g = tmp; } + res = cuddCacheLookup2(dd,Cudd_bddIntersect,f,g); + if (res != NULL) return(res); + + /* Find splitting variable. Here we can skip the use of cuddI, + ** because the operands are known to be non-constant. + */ + F = Cudd_Regular(f); + topf = dd->perm[F->index]; + G = Cudd_Regular(g); + topg = dd->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } + } else { + index = G->index; + fv = fnv = f; + } + + if (topg <= topf) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + /* Compute partial results. */ + t = cuddBddIntersectRecur(dd,fv,gv); + if (t == NULL) return(NULL); + cuddRef(t); + if (t != zero) { + e = zero; + } else { + e = cuddBddIntersectRecur(dd,fnv,gnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddRef(e); + + if (t == e) { /* both equal zero */ + res = t; + } else if (Cudd_IsComplement(t)) { + res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (res == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = cuddUniqueInter(dd,(int)index,t,e); + if (res == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + + cuddCacheInsert2(dd,Cudd_bddIntersect,f,g,res); + + return(res); + +} /* end of cuddBddIntersectRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddAnd.] + + Description [Implements the recursive step of Cudd_bddAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +cuddBddAndRecur( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + DdNode *F, *fv, *fnv, *G, *gv, *gnv; + DdNode *one, *r, *t, *e; + unsigned int topf, topg, index; + + statLine(manager); + one = DD_ONE(manager); + + /* Terminal cases. */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + if (F == G) { + if (f == g) return(f); + else return(Cudd_Not(one)); + } + if (F == one) { + if (f == one) return(g); + else return(f); + } + if (G == one) { + if (g == one) return(f); + else return(g); + } + + /* At this point f and g are not constant. */ + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; + g = tmp; + F = Cudd_Regular(f); + G = Cudd_Regular(g); + } + + /* Check cache. */ + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g); + if (r != NULL) return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } + } else { + index = G->index; + fv = fnv = f; + } + + if (topg <= topf) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + t = cuddBddAndRecur(manager, fv, gv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddAndRecur(manager, fnv, gnv); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r); + return(r); + +} /* end of cuddBddAndRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddXor.] + + Description [Implements the recursive step of Cudd_bddXor by taking + the exclusive OR of two BDDs. Returns a pointer to the result is + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddXor] + +******************************************************************************/ +DdNode * +cuddBddXorRecur( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + DdNode *fv, *fnv, *G, *gv, *gnv; + DdNode *one, *zero, *r, *t, *e; + unsigned int topf, topg, index; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == g) return(zero); + if (f == Cudd_Not(g)) return(one); + if (f > g) { /* Try to increase cache efficiency and simplify tests. */ + DdNode *tmp = f; + f = g; + g = tmp; + } + if (g == zero) return(f); + if (g == one) return(Cudd_Not(f)); + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + g = Cudd_Not(g); + } + /* Now the first argument is regular. */ + if (f == one) return(Cudd_Not(g)); + + /* At this point f and g are not constant. */ + + /* Check cache. */ + r = cuddCacheLookup2(manager, Cudd_bddXor, f, g); + if (r != NULL) return(r); + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[f->index]; + G = Cudd_Regular(g); + topg = manager->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = f->index; + fv = cuddT(f); + fnv = cuddE(f); + } else { + index = G->index; + fv = fnv = f; + } + + if (topg <= topf) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + t = cuddBddXorRecur(manager, fv, gv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddXorRecur(manager, fnv, gnv); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + cuddCacheInsert2(manager, Cudd_bddXor, f, g, r); + return(r); + +} /* end of cuddBddXorRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Replaces variables with constants if possible.] + + Description [This function performs part of the transformation to + standard form by replacing variables with constants if possible.] + + SideEffects [None] + + SeeAlso [bddVarToCanonical bddVarToCanonicalSimple] + +******************************************************************************/ +static void +bddVarToConst( + DdNode * f, + DdNode ** gp, + DdNode ** hp, + DdNode * one) +{ + DdNode *g = *gp; + DdNode *h = *hp; + + if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + *gp = one; + } else if (f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ + *gp = Cudd_Not(one); + } + if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + *hp = Cudd_Not(one); + } else if (f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ + *hp = one; + } + +} /* end of bddVarToConst */ + + +/**Function******************************************************************** + + Synopsis [Picks unique member from equiv expressions.] + + Description [Reduces 2 variable expressions to canonical form.] + + SideEffects [None] + + SeeAlso [bddVarToConst bddVarToCanonicalSimple] + +******************************************************************************/ +static int +bddVarToCanonical( + DdManager * dd, + DdNode ** fp, + DdNode ** gp, + DdNode ** hp, + unsigned int * topfp, + unsigned int * topgp, + unsigned int * tophp) +{ + register DdNode *F, *G, *H, *r, *f, *g, *h; + register unsigned int topf, topg, toph; + DdNode *one = dd->one; + int comple, change; + + f = *fp; + g = *gp; + h = *hp; + F = Cudd_Regular(f); + G = Cudd_Regular(g); + H = Cudd_Regular(h); + topf = cuddI(dd,F->index); + topg = cuddI(dd,G->index); + toph = cuddI(dd,H->index); + + change = 0; + + if (G == one) { /* ITE(F,c,H) */ + if ((topf > toph) || (topf == toph && f > h)) { + r = h; + h = f; + f = r; /* ITE(F,1,H) = ITE(H,1,F) */ + if (g != one) { /* g == zero */ + f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */ + h = Cudd_Not(h); + } + change = 1; + } + } else if (H == one) { /* ITE(F,G,c) */ + if ((topf > topg) || (topf == topg && f > g)) { + r = g; + g = f; + f = r; /* ITE(F,G,0) = ITE(G,F,0) */ + if (h == one) { + f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */ + g = Cudd_Not(g); + } + change = 1; + } + } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */ + if ((topf > topg) || (topf == topg && f > g)) { + r = f; + f = g; + g = r; + h = Cudd_Not(r); + change = 1; + } + } + /* adjust pointers so that the first 2 arguments to ITE are regular */ + if (Cudd_IsComplement(f) != 0) { /* ITE(!F,G,H) = ITE(F,H,G) */ + f = Cudd_Not(f); + r = g; + g = h; + h = r; + change = 1; + } + comple = 0; + if (Cudd_IsComplement(g) != 0) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ + g = Cudd_Not(g); + h = Cudd_Not(h); + change = 1; + comple = 1; + } + if (change != 0) { + *fp = f; + *gp = g; + *hp = h; + } + *topfp = cuddI(dd,f->index); + *topgp = cuddI(dd,g->index); + *tophp = cuddI(dd,Cudd_Regular(h)->index); + + return(comple); + +} /* end of bddVarToCanonical */ + + +/**Function******************************************************************** + + Synopsis [Picks unique member from equiv expressions.] + + Description [Makes sure the first two pointers are regular. This + mat require the complementation of the result, which is signaled by + returning 1 instead of 0. This function is simpler than the general + case because it assumes that no two arguments are the same or + complementary, and no argument is constant.] + + SideEffects [None] + + SeeAlso [bddVarToConst bddVarToCanonical] + +******************************************************************************/ +static int +bddVarToCanonicalSimple( + DdManager * dd, + DdNode ** fp, + DdNode ** gp, + DdNode ** hp, + unsigned int * topfp, + unsigned int * topgp, + unsigned int * tophp) +{ + register DdNode *r, *f, *g, *h; + int comple, change; + + f = *fp; + g = *gp; + h = *hp; + + change = 0; + + /* adjust pointers so that the first 2 arguments to ITE are regular */ + if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */ + f = Cudd_Not(f); + r = g; + g = h; + h = r; + change = 1; + } + comple = 0; + if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ + g = Cudd_Not(g); + h = Cudd_Not(h); + change = 1; + comple = 1; + } + if (change) { + *fp = f; + *gp = g; + *hp = h; + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + *topfp = dd->perm[f->index]; + *topgp = dd->perm[g->index]; + *tophp = dd->perm[Cudd_Regular(h)->index]; + + return(comple); + +} /* end of bddVarToCanonicalSimple */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBridge.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBridge.c new file mode 100644 index 000000000..a6207b7f6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddBridge.c @@ -0,0 +1,1016 @@ +/**CFile*********************************************************************** + + FileName [cuddBridge.c] + + PackageName [cudd] + + Synopsis [Translation from BDD to ADD and vice versa and transfer between + different managers.] + + Description [External procedures included in this file: +
                    +
                  • Cudd_addBddThreshold() +
                  • Cudd_addBddStrictThreshold() +
                  • Cudd_addBddInterval() +
                  • Cudd_addBddIthBit() +
                  • Cudd_BddToAdd() +
                  • Cudd_addBddPattern() +
                  • Cudd_bddTransfer() +
                  + Internal procedures included in this file: +
                    +
                  • cuddBddTransfer() +
                  • cuddAddBddDoPattern() +
                  + Static procedures included in this file: +
                    +
                  • addBddDoThreshold() +
                  • addBddDoStrictThreshold() +
                  • addBddDoInterval() +
                  • addBddDoIthBit() +
                  • ddBddToAddRecur() +
                  • cuddBddTransferRecur() +
                  + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.20 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addBddDoThreshold (DdManager *dd, DdNode *f, DdNode *val); +static DdNode * addBddDoStrictThreshold (DdManager *dd, DdNode *f, DdNode *val); +static DdNode * addBddDoInterval (DdManager *dd, DdNode *f, DdNode *l, DdNode *u); +static DdNode * addBddDoIthBit (DdManager *dd, DdNode *f, DdNode *index); +static DdNode * ddBddToAddRecur (DdManager *dd, DdNode *B); +static DdNode * cuddBddTransferRecur (DdManager *ddS, DdManager *ddD, DdNode *f, st_table *table); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants greater than or equal to value with 1, and all other + discriminants with 0. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd + Cudd_addBddStrictThreshold] + +******************************************************************************/ +DdNode * +Cudd_addBddThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value) +{ + DdNode *res; + DdNode *val; + + val = cuddUniqueConst(dd,value); + if (val == NULL) return(NULL); + cuddRef(val); + + do { + dd->reordered = 0; + res = addBddDoThreshold(dd, f, val); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, val); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, val); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddThreshold */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants STRICTLY greater than value with 1, and all other + discriminants with 0. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd + Cudd_addBddThreshold] + +******************************************************************************/ +DdNode * +Cudd_addBddStrictThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value) +{ + DdNode *res; + DdNode *val; + + val = cuddUniqueConst(dd,value); + if (val == NULL) return(NULL); + cuddRef(val); + + do { + dd->reordered = 0; + res = addBddDoStrictThreshold(dd, f, val); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, val); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, val); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddStrictThreshold */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants greater than or equal to lower and less than or equal to + upper with 1, and all other discriminants with 0. Returns a pointer to + the resulting BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddThreshold Cudd_addBddStrictThreshold + Cudd_addBddPattern Cudd_BddToAdd] + +******************************************************************************/ +DdNode * +Cudd_addBddInterval( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE lower, + CUDD_VALUE_TYPE upper) +{ + DdNode *res; + DdNode *l; + DdNode *u; + + /* Create constant nodes for the interval bounds, so that we can use + ** the global cache. + */ + l = cuddUniqueConst(dd,lower); + if (l == NULL) return(NULL); + cuddRef(l); + u = cuddUniqueConst(dd,upper); + if (u == NULL) { + Cudd_RecursiveDeref(dd,l); + return(NULL); + } + cuddRef(u); + + do { + dd->reordered = 0; + res = addBddDoInterval(dd, f, l, u); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, l); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, l); + Cudd_RecursiveDeref(dd, u); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddInterval */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD by extracting the i-th bit from + the leaves.] + + Description [Converts an ADD to a BDD by replacing all + discriminants whose i-th bit is equal to 1 with 1, and all other + discriminants with 0. The i-th bit refers to the integer + representation of the leaf value. If the value is has a fractional + part, it is ignored. Repeated calls to this procedure allow one to + transform an integer-valued ADD into an array of BDDs, one for each + bit of the leaf values. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd] + +******************************************************************************/ +DdNode * +Cudd_addBddIthBit( + DdManager * dd, + DdNode * f, + int bit) +{ + DdNode *res; + DdNode *index; + + index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit); + if (index == NULL) return(NULL); + cuddRef(index); + + do { + dd->reordered = 0; + res = addBddDoIthBit(dd, f, index); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, index); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, index); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddIthBit */ + + +/**Function******************************************************************** + + Synopsis [Converts a BDD to a 0-1 ADD.] + + Description [Converts a BDD to a 0-1 ADD. Returns a pointer to the + resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddPattern Cudd_addBddThreshold Cudd_addBddInterval + Cudd_addBddStrictThreshold] + +******************************************************************************/ +DdNode * +Cudd_BddToAdd( + DdManager * dd, + DdNode * B) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = ddBddToAddRecur(dd, B); + } while (dd->reordered ==1); + return(res); + +} /* end of Cudd_BddToAdd */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants different from 0 with 1. Returns a pointer to the + resulting BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_BddToAdd Cudd_addBddThreshold Cudd_addBddInterval + Cudd_addBddStrictThreshold] + +******************************************************************************/ +DdNode * +Cudd_addBddPattern( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddBddDoPattern(dd, f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addBddPattern */ + + +/**Function******************************************************************** + + Synopsis [Convert a BDD from a manager to another one.] + + Description [Convert a BDD from a manager to another one. The orders of the + variables in the two managers may be different. Returns a + pointer to the BDD in the destination manager if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_bddTransfer( + DdManager * ddSource, + DdManager * ddDestination, + DdNode * f) +{ + DdNode *res; + do { + ddDestination->reordered = 0; + res = cuddBddTransfer(ddSource, ddDestination, f); + } while (ddDestination->reordered == 1); + return(res); + +} /* end of Cudd_bddTransfer */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Convert a BDD from a manager to another one.] + + Description [Convert a BDD from a manager to another one. Returns a + pointer to the BDD in the destination manager if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddTransfer] + +******************************************************************************/ +DdNode * +cuddBddTransfer( + DdManager * ddS, + DdManager * ddD, + DdNode * f) +{ + DdNode *res; + st_table *table = NULL; + st_generator *gen = NULL; + DdNode *key, *value; + + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) goto failure; + res = cuddBddTransferRecur(ddS, ddD, f, table); + if (res != NULL) cuddRef(res); + + /* Dereference all elements in the table and dispose of the table. + ** This must be done also if res is NULL to avoid leaks in case of + ** reordering. */ + gen = st_init_gen(table); + if (gen == NULL) goto failure; + while (st_gen(gen, &key, &value)) { + Cudd_RecursiveDeref(ddD, value); + } + st_free_gen(gen); gen = NULL; + st_free_table(table); table = NULL; + + if (res != NULL) cuddDeref(res); + return(res); + +failure: + /* No need to free gen because it is always NULL here. */ + if (table != NULL) st_free_table(table); + return(NULL); + +} /* end of cuddBddTransfer */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddPattern.] + + Description [Performs the recursive step for Cudd_addBddPattern. Returns a + pointer to the resulting BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddAddBddDoPattern( + DdManager * dd, + DdNode * f) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),f == DD_ZERO(dd))); + } + + /* Check cache. */ + res = cuddCacheLookup1(dd,Cudd_addBddPattern,f); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = cuddAddBddDoPattern(dd,fv); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddBddDoPattern(dd,fvn); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,Cudd_addBddPattern,f,res); + + return(res); + +} /* end of cuddAddBddDoPattern */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddThreshold.] + + Description [Performs the recursive step for Cudd_addBddThreshold. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [addBddDoStrictThreshold] + +******************************************************************************/ +static DdNode * +addBddDoThreshold( + DdManager * dd, + DdNode * f, + DdNode * val) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(val))); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addBddDoThreshold,f,val); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoThreshold(dd,fv,val); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoThreshold(dd,fvn,val); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addBddDoThreshold,f,val,res); + + return(res); + +} /* end of addBddDoThreshold */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddStrictThreshold.] + + Description [Performs the recursive step for Cudd_addBddStrictThreshold. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [addBddDoThreshold] + +******************************************************************************/ +static DdNode * +addBddDoStrictThreshold( + DdManager * dd, + DdNode * f, + DdNode * val) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) <= cuddV(val))); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addBddDoStrictThreshold,f,val); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoStrictThreshold(dd,fv,val); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoStrictThreshold(dd,fvn,val); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addBddDoStrictThreshold,f,val,res); + + return(res); + +} /* end of addBddDoStrictThreshold */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddInterval.] + + Description [Performs the recursive step for Cudd_addBddInterval. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [addBddDoThreshold addBddDoStrictThreshold] + +******************************************************************************/ +static DdNode * +addBddDoInterval( + DdManager * dd, + DdNode * f, + DdNode * l, + DdNode * u) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(l) || cuddV(f) > cuddV(u))); + } + + /* Check cache. */ + res = cuddCacheLookup(dd,DD_ADD_BDD_DO_INTERVAL_TAG,f,l,u); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoInterval(dd,fv,l,u); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoInterval(dd,fvn,l,u); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert(dd,DD_ADD_BDD_DO_INTERVAL_TAG,f,l,u,res); + + return(res); + +} /* end of addBddDoInterval */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddIthBit.] + + Description [Performs the recursive step for Cudd_addBddIthBit. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +addBddDoIthBit( + DdManager * dd, + DdNode * f, + DdNode * index) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int mask, value; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + mask = 1 << ((int) cuddV(index)); + value = (int) cuddV(f); + return(Cudd_NotCond(DD_ONE(dd),(value & mask) == 0)); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addBddDoIthBit,f,index); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoIthBit(dd,fv,index); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoIthBit(dd,fvn,index); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addBddDoIthBit,f,index,res); + + return(res); + +} /* end of addBddDoIthBit */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_BddToAdd.] + + Description [Performs the recursive step for Cudd_BddToAdd. Returns a + pointer to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +ddBddToAddRecur( + DdManager * dd, + DdNode * B) +{ + DdNode *one; + DdNode *res, *res1, *T, *E, *Bt, *Be; + int complement = 0; + + statLine(dd); + one = DD_ONE(dd); + + if (Cudd_IsConstant(B)) { + if (B == one) { + res = one; + } else { + res = DD_ZERO(dd); + } + return(res); + } + /* Check visited table */ + res = cuddCacheLookup1(dd,ddBddToAddRecur,B); + if (res != NULL) return(res); + + if (Cudd_IsComplement(B)) { + complement = 1; + Bt = cuddT(Cudd_Regular(B)); + Be = cuddE(Cudd_Regular(B)); + } else { + Bt = cuddT(B); + Be = cuddE(B); + } + + T = ddBddToAddRecur(dd, Bt); + if (T == NULL) return(NULL); + cuddRef(T); + + E = ddBddToAddRecur(dd, Be); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + /* No need to check for T == E, because it is guaranteed not to happen. */ + res = cuddUniqueInter(dd, (int) Cudd_Regular(B)->index, T, E); + if (res == NULL) { + Cudd_RecursiveDeref(dd ,T); + Cudd_RecursiveDeref(dd ,E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + if (complement) { + cuddRef(res); + res1 = cuddAddCmplRecur(dd, res); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(res1); + Cudd_RecursiveDeref(dd, res); + res = res1; + cuddDeref(res); + } + + /* Store result. */ + cuddCacheInsert1(dd,ddBddToAddRecur,B,res); + + return(res); + +} /* end of ddBddToAddRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddTransfer.] + + Description [Performs the recursive step of Cudd_bddTransfer. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddBddTransfer] + +******************************************************************************/ +static DdNode * +cuddBddTransferRecur( + DdManager * ddS, + DdManager * ddD, + DdNode * f, + st_table * table) +{ + DdNode *ft, *fe, *t, *e, *var, *res; + DdNode *one, *zero; + int index; + int comple = 0; + + statLine(ddD); + one = DD_ONE(ddD); + comple = Cudd_IsComplement(f); + + /* Trivial cases. */ + if (Cudd_IsConstant(f)) return(Cudd_NotCond(one, comple)); + + /* Make canonical to increase the utilization of the cache. */ + f = Cudd_NotCond(f,comple); + /* Now f is a regular pointer to a non-constant node. */ + + /* Check the cache. */ + if (st_lookup(table, f, &res)) + return(Cudd_NotCond(res,comple)); + + /* Recursive step. */ + index = f->index; + ft = cuddT(f); fe = cuddE(f); + + t = cuddBddTransferRecur(ddS, ddD, ft, table); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + + e = cuddBddTransferRecur(ddS, ddD, fe, table); + if (e == NULL) { + Cudd_RecursiveDeref(ddD, t); + return(NULL); + } + cuddRef(e); + + zero = Cudd_Not(one); + var = cuddUniqueInter(ddD,index,one,zero); + if (var == NULL) { + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + return(NULL); + } + res = cuddBddIteRecur(ddD,var,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + + if (st_add_direct(table, (char *) f, (char *) res) == ST_OUT_OF_MEM) { + Cudd_RecursiveDeref(ddD, res); + return(NULL); + } + return(Cudd_NotCond(res,comple)); + +} /* end of cuddBddTransferRecur */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCache.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCache.c new file mode 100644 index 000000000..bf98c69e4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCache.c @@ -0,0 +1,1053 @@ +/**CFile*********************************************************************** + + FileName [cuddCache.c] + + PackageName [cudd] + + Synopsis [Functions for cache insertion and lookup.] + + Description [Internal procedures included in this module: +
                    +
                  • cuddInitCache() +
                  • cuddCacheInsert() +
                  • cuddCacheInsert2() +
                  • cuddCacheLookup() +
                  • cuddCacheLookupZdd() +
                  • cuddCacheLookup2() +
                  • cuddCacheLookup2Zdd() +
                  • cuddConstantLookup() +
                  • cuddCacheProfile() +
                  • cuddCacheResize() +
                  • cuddCacheFlush() +
                  • cuddComputeFloorLog2() +
                  + Static procedures included in this module: +
                    +
                  ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef DD_CACHE_PROFILE +#define DD_HYSTO_BINS 8 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddCache.c,v 1.36 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes the computed table.] + + Description [Initializes the computed table. It is called by + Cudd_Init. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Init] + +******************************************************************************/ +int +cuddInitCache( + DdManager * unique /* unique table */, + unsigned int cacheSize /* initial size of the cache */, + unsigned int maxCacheSize /* cache size beyond which no resizing occurs */) +{ + int i; + unsigned int logSize; +#ifndef DD_CACHE_PROFILE + DdNodePtr *mem; + ptruint offset; +#endif + + /* Round cacheSize to largest power of 2 not greater than the requested + ** initial cache size. */ + logSize = cuddComputeFloorLog2(ddMax(cacheSize,unique->slots/2)); + cacheSize = 1 << logSize; + unique->acache = ALLOC(DdCache,cacheSize+1); + if (unique->acache == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + /* If the size of the cache entry is a power of 2, we want to + ** enforce alignment to that power of two. This happens when + ** DD_CACHE_PROFILE is not defined. */ +#ifdef DD_CACHE_PROFILE + unique->cache = unique->acache; + unique->memused += (cacheSize) * sizeof(DdCache); +#else + mem = (DdNodePtr *) unique->acache; + offset = (ptruint) mem & (sizeof(DdCache) - 1); + mem += (sizeof(DdCache) - offset) / sizeof(DdNodePtr); + unique->cache = (DdCache *) mem; + assert(((ptruint) unique->cache & (sizeof(DdCache) - 1)) == 0); + unique->memused += (cacheSize+1) * sizeof(DdCache); +#endif + unique->cacheSlots = cacheSize; + unique->cacheShift = sizeof(int) * 8 - logSize; + unique->maxCacheHard = maxCacheSize; + /* If cacheSlack is non-negative, we can resize. */ + unique->cacheSlack = (int) ddMin(maxCacheSize, + DD_MAX_CACHE_TO_SLOTS_RATIO*unique->slots) - + 2 * (int) cacheSize; + Cudd_SetMinHit(unique,DD_MIN_HIT); + /* Initialize to avoid division by 0 and immediate resizing. */ + unique->cacheMisses = (double) (int) (cacheSize * unique->minHit + 1); + unique->cacheHits = 0; + unique->totCachehits = 0; + /* The sum of cacheMisses and totCacheMisses is always correct, + ** even though cacheMisses is larger than it should for the reasons + ** explained above. */ + unique->totCacheMisses = -unique->cacheMisses; + unique->cachecollisions = 0; + unique->cacheinserts = 0; + unique->cacheLastInserts = 0; + unique->cachedeletions = 0; + + /* Initialize the cache */ + for (i = 0; (unsigned) i < cacheSize; i++) { + unique->cache[i].h = 0; /* unused slots */ + unique->cache[i].data = NULL; /* invalid entry */ +#ifdef DD_CACHE_PROFILE + unique->cache[i].count = 0; +#endif + } + + return(1); + +} /* end of cuddInitCache */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in the cache for a function with three + operands.] + + Description [Inserts a result in the cache for a function with three + operands. The operator tag (see cuddInt.h for details) is split and stored + into unused bits of the first two pointers.] + + SideEffects [None] + + SeeAlso [cuddCacheInsert2 cuddCacheInsert1] + +******************************************************************************/ +void +cuddCacheInsert( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h, + DdNode * data) +{ + int posn; + register DdCache *entry; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + posn = ddCHash2(uh,uf,ug,table->cacheShift); + entry = &table->cache[posn]; + + table->cachecollisions += entry->data != NULL; + table->cacheinserts++; + + entry->f = (DdNode *) uf; + entry->g = (DdNode *) ug; + entry->h = uh; + entry->data = data; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddCacheInsert */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in the cache for a function with two + operands.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddCacheInsert cuddCacheInsert1] + +******************************************************************************/ +void +cuddCacheInsert2( + DdManager * table, + DD_CTFP op, + DdNode * f, + DdNode * g, + DdNode * data) +{ + int posn; + register DdCache *entry; + + posn = ddCHash2(op,f,g,table->cacheShift); + entry = &table->cache[posn]; + + if (entry->data != NULL) { + table->cachecollisions++; + } + table->cacheinserts++; + + entry->f = f; + entry->g = g; + entry->h = (ptruint) op; + entry->data = data; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddCacheInsert2 */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in the cache for a function with two + operands.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddCacheInsert cuddCacheInsert2] + +******************************************************************************/ +void +cuddCacheInsert1( + DdManager * table, + DD_CTFP1 op, + DdNode * f, + DdNode * data) +{ + int posn; + register DdCache *entry; + + posn = ddCHash2(op,f,f,table->cacheShift); + entry = &table->cache[posn]; + + if (entry->data != NULL) { + table->cachecollisions++; + } + table->cacheinserts++; + + entry->f = f; + entry->g = f; + entry->h = (ptruint) op; + entry->data = data; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddCacheInsert1 */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f, + g, and h.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup2 cuddCacheLookup1] + +******************************************************************************/ +DdNode * +cuddCacheLookup( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(uh,uf,ug,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug && + en->h==uh) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f, + g, and h.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup2Zdd cuddCacheLookup1Zdd] + +******************************************************************************/ +DdNode * +cuddCacheLookupZdd( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(uh,uf,ug,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug && + en->h==uh) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookupZdd */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f + and g.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup cuddCacheLookup1] + +******************************************************************************/ +DdNode * +cuddCacheLookup2( + DdManager * table, + DD_CTFP op, + DdNode * f, + DdNode * g) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,g,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup2 */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup cuddCacheLookup2] + +******************************************************************************/ +DdNode * +cuddCacheLookup1( + DdManager * table, + DD_CTFP1 op, + DdNode * f) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,f,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup1 */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f + and g.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookupZdd cuddCacheLookup1Zdd] + +******************************************************************************/ +DdNode * +cuddCacheLookup2Zdd( + DdManager * table, + DD_CTFP op, + DdNode * f, + DdNode * g) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,g,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup2Zdd */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookupZdd cuddCacheLookup2Zdd] + +******************************************************************************/ +DdNode * +cuddCacheLookup1Zdd( + DdManager * table, + DD_CTFP1 op, + DdNode * f) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,f,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup1Zdd */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f, + g, and h.] + + Description [Looks up in the cache for the result of op applied to f, + g, and h. Assumes that the calling procedure (e.g., + Cudd_bddIteConstant) is only interested in whether the result is + constant or not. Returns the result if found (possibly + DD_NON_CONSTANT); otherwise it returns NULL.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup] + +******************************************************************************/ +DdNode * +cuddConstantLookup( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h) +{ + int posn; + DdCache *en,*cache; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + posn = ddCHash2(uh,uf,ug,table->cacheShift); + en = &cache[posn]; + + /* We do not reclaim here because the result should not be + * referenced, but only tested for being a constant. + */ + if (en->data != NULL && + en->f == (DdNodePtr)uf && en->g == (DdNodePtr)ug && en->h == uh) { + table->cacheHits++; + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddConstantLookup */ + + +/**Function******************************************************************** + + Synopsis [Computes and prints a profile of the cache usage.] + + Description [Computes and prints a profile of the cache usage. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddCacheProfile( + DdManager * table, + FILE * fp) +{ + DdCache *cache = table->cache; + int slots = table->cacheSlots; + int nzeroes = 0; + int i, retval; + double exUsed; + +#ifdef DD_CACHE_PROFILE + double count, mean, meansq, stddev, expected; + long max, min; + int imax, imin; + double *hystogramQ, *hystogramR; /* histograms by quotient and remainder */ + int nbins = DD_HYSTO_BINS; + int bin; + long thiscount; + double totalcount, exStddev; + + meansq = mean = expected = 0.0; + max = min = (long) cache[0].count; + imax = imin = 0; + totalcount = 0.0; + + hystogramQ = ALLOC(double, nbins); + if (hystogramQ == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + hystogramR = ALLOC(double, nbins); + if (hystogramR == NULL) { + FREE(hystogramQ); + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < nbins; i++) { + hystogramQ[i] = 0; + hystogramR[i] = 0; + } + + for (i = 0; i < slots; i++) { + thiscount = (long) cache[i].count; + if (thiscount > max) { + max = thiscount; + imax = i; + } + if (thiscount < min) { + min = thiscount; + imin = i; + } + if (thiscount == 0) { + nzeroes++; + } + count = (double) thiscount; + mean += count; + meansq += count * count; + totalcount += count; + expected += count * (double) i; + bin = (i * nbins) / slots; + hystogramQ[bin] += (double) thiscount; + bin = i % nbins; + hystogramR[bin] += (double) thiscount; + } + mean /= (double) slots; + meansq /= (double) slots; + + /* Compute the standard deviation from both the data and the + ** theoretical model for a random distribution. */ + stddev = sqrt(meansq - mean*mean); + exStddev = sqrt((1 - 1/(double) slots) * totalcount / (double) slots); + + retval = fprintf(fp,"Cache average accesses = %g\n", mean); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache access standard deviation = %g ", stddev); + if (retval == EOF) return(0); + retval = fprintf(fp,"(expected = %g)\n", exStddev); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache max accesses = %ld for slot %d\n", max, imax); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache min accesses = %ld for slot %d\n", min, imin); + if (retval == EOF) return(0); + exUsed = 100.0 * (1.0 - exp(-totalcount / (double) slots)); + retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n", + 100.0 - (double) nzeroes * 100.0 / (double) slots, + exUsed); + if (retval == EOF) return(0); + + if (totalcount > 0) { + expected /= totalcount; + retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); + if (retval == EOF) return(0); + retval = fprintf(fp," (expected bin value = %g)\nBy quotient:", + expected); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp," %.0f", hystogramQ[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\nBy residue: "); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp," %.0f", hystogramR[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\n"); + if (retval == EOF) return(0); + } + + FREE(hystogramQ); + FREE(hystogramR); +#else + for (i = 0; i < slots; i++) { + nzeroes += cache[i].h == 0; + } + exUsed = 100.0 * + (1.0 - exp(-(table->cacheinserts - table->cacheLastInserts) / + (double) slots)); + retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n", + 100.0 - (double) nzeroes * 100.0 / (double) slots, + exUsed); + if (retval == EOF) return(0); +#endif + return(1); + +} /* end of cuddCacheProfile */ + + +/**Function******************************************************************** + + Synopsis [Resizes the cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddCacheResize( + DdManager * table) +{ + DdCache *cache, *oldcache, *oldacache, *entry, *old; + int i; + int posn, shift; + unsigned int slots, oldslots; + double offset; + int moved = 0; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; +#ifndef DD_CACHE_PROFILE + ptruint misalignment; + DdNodePtr *mem; +#endif + + oldcache = table->cache; + oldacache = table->acache; + oldslots = table->cacheSlots; + slots = table->cacheSlots = oldslots << 1; + +#ifdef DD_VERBOSE + (void) fprintf(table->err,"Resizing the cache from %d to %d entries\n", + oldslots, slots); + (void) fprintf(table->err, + "\thits = %g\tmisses = %g\thit ratio = %5.3f\n", + table->cacheHits, table->cacheMisses, + table->cacheHits / (table->cacheHits + table->cacheMisses)); +#endif + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + table->acache = cache = ALLOC(DdCache,slots+1); + MMoutOfMemory = saveHandler; + /* If we fail to allocate the new table we just give up. */ + if (cache == NULL) { +#ifdef DD_VERBOSE + (void) fprintf(table->err,"Resizing failed. Giving up.\n"); +#endif + table->cacheSlots = oldslots; + table->acache = oldacache; + /* Do not try to resize again. */ + table->maxCacheHard = oldslots - 1; + table->cacheSlack = - (int) (oldslots + 1); + return; + } + /* If the size of the cache entry is a power of 2, we want to + ** enforce alignment to that power of two. This happens when + ** DD_CACHE_PROFILE is not defined. */ +#ifdef DD_CACHE_PROFILE + table->cache = cache; +#else + mem = (DdNodePtr *) cache; + misalignment = (ptruint) mem & (sizeof(DdCache) - 1); + mem += (sizeof(DdCache) - misalignment) / sizeof(DdNodePtr); + table->cache = cache = (DdCache *) mem; + assert(((ptruint) table->cache & (sizeof(DdCache) - 1)) == 0); +#endif + shift = --(table->cacheShift); + table->memused += (slots - oldslots) * sizeof(DdCache); + table->cacheSlack -= slots; /* need these many slots to double again */ + + /* Clear new cache. */ + for (i = 0; (unsigned) i < slots; i++) { + cache[i].data = NULL; + cache[i].h = 0; +#ifdef DD_CACHE_PROFILE + cache[i].count = 0; +#endif + } + + /* Copy from old cache to new one. */ + for (i = 0; (unsigned) i < oldslots; i++) { + old = &oldcache[i]; + if (old->data != NULL) { + posn = ddCHash2(old->h,old->f,old->g,shift); + entry = &cache[posn]; + entry->f = old->f; + entry->g = old->g; + entry->h = old->h; + entry->data = old->data; +#ifdef DD_CACHE_PROFILE + entry->count = 1; +#endif + moved++; + } + } + + FREE(oldacache); + + /* Reinitialize measurements so as to avoid division by 0 and + ** immediate resizing. + */ + offset = (double) (int) (slots * table->minHit + 1); + table->totCacheMisses += table->cacheMisses - offset; + table->cacheMisses = offset; + table->totCachehits += table->cacheHits; + table->cacheHits = 0; + table->cacheLastInserts = table->cacheinserts - (double) moved; + +} /* end of cuddCacheResize */ + + +/**Function******************************************************************** + + Synopsis [Flushes the cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddCacheFlush( + DdManager * table) +{ + int i, slots; + DdCache *cache; + + slots = table->cacheSlots; + cache = table->cache; + for (i = 0; i < slots; i++) { + table->cachedeletions += cache[i].data != NULL; + cache[i].data = NULL; + } + table->cacheLastInserts = table->cacheinserts; + + return; + +} /* end of cuddCacheFlush */ + + +/**Function******************************************************************** + + Synopsis [Returns the floor of the logarithm to the base 2.] + + Description [Returns the floor of the logarithm to the base 2. + The input value is assumed to be greater than 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddComputeFloorLog2( + unsigned int value) +{ + int floorLog = 0; +#ifdef DD_DEBUG + assert(value > 0); +#endif + while (value > 1) { + floorLog++; + value >>= 1; + } + return(floorLog); + +} /* end of cuddComputeFloorLog2 */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCheck.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCheck.c new file mode 100644 index 000000000..424aaba39 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCheck.c @@ -0,0 +1,885 @@ +/**CFile*********************************************************************** + + FileName [cuddCheck.c] + + PackageName [cudd] + + Synopsis [Functions to check consistency of data structures.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_DebugCheck() +
                  • Cudd_CheckKeys() +
                  + Internal procedures included in this module: +
                    +
                  • cuddHeapProfile() +
                  • cuddPrintNode() +
                  • cuddPrintVarGroups() +
                  + Static procedures included in this module: +
                    +
                  • debugFindParent() +
                  + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddCheck.c,v 1.37 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void debugFindParent (DdManager *table, DdNode *node); +#if 0 +static void debugCheckParent (DdManager *table, DdNode *node); +#endif + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Checks for inconsistencies in the DD heap.] + + Description [Checks for inconsistencies in the DD heap: +
                    +
                  • node has illegal index +
                  • live node has dead children +
                  • node has illegal Then or Else pointers +
                  • BDD/ADD node has identical children +
                  • ZDD node has zero then child +
                  • wrong number of total nodes +
                  • wrong number of dead nodes +
                  • ref count error at node +
                  + Returns 0 if no inconsistencies are found; DD_OUT_OF_MEM if there is + not enough memory; 1 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_CheckKeys] + +******************************************************************************/ +int +Cudd_DebugCheck( + DdManager * table) +{ + unsigned int i; + int j,count; + int slots; + DdNodePtr *nodelist; + DdNode *f; + DdNode *sentinel = &(table->sentinel); + st_table *edgeTable; /* stores internal ref count for each node */ + st_generator *gen; + int flag = 0; + int totalNode; + int deadNode; + int index; + int shift; + + edgeTable = st_init_table(st_ptrcmp,st_ptrhash); + if (edgeTable == NULL) return(CUDD_OUT_OF_MEM); + + /* Check the BDD/ADD subtables. */ + for (i = 0; i < (unsigned) table->size; i++) { + index = table->invperm[i]; + if (i != (unsigned) table->perm[index]) { + (void) fprintf(table->err, + "Permutation corrupted: invperm[%u] = %d\t perm[%d] = %d\n", + i, index, index, table->perm[index]); + } + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + shift = table->subtables[i].shift; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { /* for each subtable slot */ + f = nodelist[j]; + while (f != sentinel) { + totalNode++; + if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { + if ((int) f->index != index) { + (void) fprintf(table->err, + "Error: node has illegal index\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if ((unsigned) cuddI(table,cuddT(f)->index) <= i || + (unsigned) cuddI(table,Cudd_Regular(cuddE(f))->index) + <= i) { + (void) fprintf(table->err, + "Error: node has illegal children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (Cudd_Regular(cuddT(f)) != cuddT(f)) { + (void) fprintf(table->err, + "Error: node has illegal form\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f) == cuddE(f)) { + (void) fprintf(table->err, + "Error: node has identical children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f)->ref == 0 || Cudd_Regular(cuddE(f))->ref == 0) { + (void) fprintf(table->err, + "Error: live node has dead children\n"); + cuddPrintNode(f,table->err); + flag =1; + } + if (ddHash(cuddT(f),cuddE(f),shift) != j) { + (void) fprintf(table->err, "Error: misplaced node\n"); + cuddPrintNode(f,table->err); + flag =1; + } + /* Increment the internal reference count for the + ** then child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddT(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + + /* Increment the internal reference count for the + ** else child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)Cudd_Regular(cuddE(f)), + &count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)Cudd_Regular(cuddE(f)), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { + deadNode++; +#if 0 + debugCheckParent(table,f); +#endif + } else { + fprintf(table->err, + "Error: node has illegal Then or Else pointers\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + + f = f->next; + } /* for each element of the collision list */ + } /* for each subtable slot */ + + if ((unsigned) totalNode != table->subtables[i].keys) { + fprintf(table->err,"Error: wrong number of total nodes\n"); + flag = 1; + } + if ((unsigned) deadNode != table->subtables[i].dead) { + fprintf(table->err,"Error: wrong number of dead nodes\n"); + flag = 1; + } + } /* for each BDD/ADD subtable */ + + /* Check the ZDD subtables. */ + for (i = 0; i < (unsigned) table->sizeZ; i++) { + index = table->invpermZ[i]; + if (i != (unsigned) table->permZ[index]) { + (void) fprintf(table->err, + "Permutation corrupted: invpermZ[%u] = %d\t permZ[%d] = %d in ZDD\n", + i, index, index, table->permZ[index]); + } + nodelist = table->subtableZ[i].nodelist; + slots = table->subtableZ[i].slots; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { /* for each subtable slot */ + f = nodelist[j]; + while (f != NULL) { + totalNode++; + if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { + if ((int) f->index != index) { + (void) fprintf(table->err, + "Error: ZDD node has illegal index\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (Cudd_IsComplement(cuddT(f)) || + Cudd_IsComplement(cuddE(f))) { + (void) fprintf(table->err, + "Error: ZDD node has complemented children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if ((unsigned) cuddIZ(table,cuddT(f)->index) <= i || + (unsigned) cuddIZ(table,cuddE(f)->index) <= i) { + (void) fprintf(table->err, + "Error: ZDD node has illegal children\n"); + cuddPrintNode(f,table->err); + cuddPrintNode(cuddT(f),table->err); + cuddPrintNode(cuddE(f),table->err); + flag = 1; + } + if (cuddT(f) == DD_ZERO(table)) { + (void) fprintf(table->err, + "Error: ZDD node has zero then child\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f)->ref == 0 || cuddE(f)->ref == 0) { + (void) fprintf(table->err, + "Error: ZDD live node has dead children\n"); + cuddPrintNode(f,table->err); + flag =1; + } + /* Increment the internal reference count for the + ** then child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddT(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + + /* Increment the internal reference count for the + ** else child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddE(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddE(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + table->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { + deadNode++; +#if 0 + debugCheckParent(table,f); +#endif + } else { + fprintf(table->err, + "Error: ZDD node has illegal Then or Else pointers\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + + f = f->next; + } /* for each element of the collision list */ + } /* for each subtable slot */ + + if ((unsigned) totalNode != table->subtableZ[i].keys) { + fprintf(table->err, + "Error: wrong number of total nodes in ZDD\n"); + flag = 1; + } + if ((unsigned) deadNode != table->subtableZ[i].dead) { + fprintf(table->err, + "Error: wrong number of dead nodes in ZDD\n"); + flag = 1; + } + } /* for each ZDD subtable */ + + /* Check the constant table. */ + nodelist = table->constants.nodelist; + slots = table->constants.slots; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != NULL) { + totalNode++; + if (f->ref != 0) { + if (f->index != CUDD_CONST_INDEX) { + fprintf(table->err,"Error: node has illegal index\n"); +#if SIZEOF_VOID_P == 8 + fprintf(table->err, + " node 0x%lx, id = %u, ref = %u, value = %g\n", + (ptruint)f,f->index,f->ref,cuddV(f)); +#else + fprintf(table->err, + " node 0x%x, id = %hu, ref = %hu, value = %g\n", + (ptruint)f,f->index,f->ref,cuddV(f)); +#endif + flag = 1; + } + } else { + deadNode++; + } + f = f->next; + } + } + if ((unsigned) totalNode != table->constants.keys) { + (void) fprintf(table->err, + "Error: wrong number of total nodes in constants\n"); + flag = 1; + } + if ((unsigned) deadNode != table->constants.dead) { + (void) fprintf(table->err, + "Error: wrong number of dead nodes in constants\n"); + flag = 1; + } + gen = st_init_gen(edgeTable); + while (st_gen(gen, &f, &count)) { + if (count > (int)(f->ref) && f->ref != DD_MAXREF) { +#if SIZEOF_VOID_P == 8 + fprintf(table->err,"ref count error at node 0x%lx, count = %d, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#else + fprintf(table->err,"ref count error at node 0x%x, count = %d, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#endif + debugFindParent(table,f); + flag = 1; + } + } + st_free_gen(gen); + st_free_table(edgeTable); + + return (flag); + +} /* end of Cudd_DebugCheck */ + + +/**Function******************************************************************** + + Synopsis [Checks for several conditions that should not occur.] + + Description [Checks for the following conditions: +
                    +
                  • Wrong sizes of subtables. +
                  • Wrong number of keys found in unique subtable. +
                  • Wrong number of dead found in unique subtable. +
                  • Wrong number of keys found in the constant table +
                  • Wrong number of dead found in the constant table +
                  • Wrong number of total slots found +
                  • Wrong number of maximum keys found +
                  • Wrong number of total dead found +
                  + Reports the average length of non-empty lists. Returns the number of + subtables for which the number of keys is wrong.] + + SideEffects [None] + + SeeAlso [Cudd_DebugCheck] + +******************************************************************************/ +int +Cudd_CheckKeys( + DdManager * table) +{ + int size; + int i,j; + DdNodePtr *nodelist; + DdNode *node; + DdNode *sentinel = &(table->sentinel); + DdSubtable *subtable; + int keys; + int dead; + int count = 0; + int totalKeys = 0; + int totalSlots = 0; + int totalDead = 0; + int nonEmpty = 0; + unsigned int slots; + int logSlots; + int shift; + + size = table->size; + + for (i = 0; i < size; i++) { + subtable = &(table->subtables[i]); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + slots = subtable->slots; + shift = subtable->shift; + logSlots = sizeof(int) * 8 - shift; + if (((slots >> logSlots) << logSlots) != slots) { + (void) fprintf(table->err, + "Unique table %d is not the right power of 2\n", i); + (void) fprintf(table->err, + " slots = %u shift = %d\n", slots, shift); + } + totalSlots += slots; + totalDead += dead; + for (j = 0; (unsigned) j < slots; j++) { + node = nodelist[j]; + if (node != sentinel) { + nonEmpty++; + } + while (node != sentinel) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } + } + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ +in unique table %d (difference=%d)\n", i, keys); + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ +in unique table no. %d (difference=%d)\n", i, dead); + } + } /* for each BDD/ADD subtable */ + + /* Check the ZDD subtables. */ + size = table->sizeZ; + + for (i = 0; i < size; i++) { + subtable = &(table->subtableZ[i]); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + totalSlots += subtable->slots; + totalDead += dead; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + nonEmpty++; + } + while (node != NULL) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } + } + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ +in ZDD unique table no. %d (difference=%d)\n", i, keys); + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ +in ZDD unique table no. %d (difference=%d)\n", i, dead); + } + } /* for each ZDD subtable */ + + /* Check the constant table. */ + subtable = &(table->constants); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + totalSlots += subtable->slots; + totalDead += dead; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + nonEmpty++; + } + while (node != NULL) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } + } + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ +in the constant table (difference=%d)\n", keys); + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ +in the constant table (difference=%d)\n", dead); + } + if ((unsigned) totalKeys != table->keys + table->keysZ) { + (void) fprintf(table->err, "Wrong number of total keys found \ +(difference=%d)\n", (int) (totalKeys-table->keys)); + } + if ((unsigned) totalSlots != table->slots) { + (void) fprintf(table->err, "Wrong number of total slots found \ +(difference=%d)\n", (int) (totalSlots-table->slots)); + } + if (table->minDead != (unsigned) (table->gcFrac * table->slots)) { + (void) fprintf(table->err, "Wrong number of minimum dead found \ +(%u vs. %u)\n", table->minDead, + (unsigned) (table->gcFrac * (double) table->slots)); + } + if ((unsigned) totalDead != table->dead + table->deadZ) { + (void) fprintf(table->err, "Wrong number of total dead found \ +(difference=%d)\n", (int) (totalDead-table->dead)); + } + (void) fprintf(table->out,"Average length of non-empty lists = %g\n", + (double) table->keys / (double) nonEmpty); + + return(count); + +} /* end of Cudd_CheckKeys */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints information about the heap.] + + Description [Prints to the manager's stdout the number of live nodes for each + level of the DD heap that contains at least one live node. It also + prints a summary containing: +
                    +
                  • total number of tables; +
                  • number of tables with live nodes; +
                  • table with the largest number of live nodes; +
                  • number of nodes in that table. +
                  + If more than one table contains the maximum number of live nodes, + only the one of lowest index is reported. Returns 1 in case of success + and 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddHeapProfile( + DdManager * dd) +{ + int ntables = dd->size; + DdSubtable *subtables = dd->subtables; + int i, /* loop index */ + nodes, /* live nodes in i-th layer */ + retval, /* return value of fprintf */ + largest = -1, /* index of the table with most live nodes */ + maxnodes = -1, /* maximum number of live nodes in a table */ + nonempty = 0; /* number of tables with live nodes */ + + /* Print header. */ +#if SIZEOF_VOID_P == 8 + retval = fprintf(dd->out,"*** DD heap profile for 0x%lx ***\n", + (ptruint) dd); +#else + retval = fprintf(dd->out,"*** DD heap profile for 0x%x ***\n", + (ptruint) dd); +#endif + if (retval == EOF) return 0; + + /* Print number of live nodes for each nonempty table. */ + for (i=0; iout,"%5d: %5d nodes\n", i, nodes); + if (retval == EOF) return 0; + if (nodes > maxnodes) { + maxnodes = nodes; + largest = i; + } + } + } + + nodes = dd->constants.keys - dd->constants.dead; + if (nodes) { + nonempty++; + retval = fprintf(dd->out,"const: %5d nodes\n", nodes); + if (retval == EOF) return 0; + if (nodes > maxnodes) { + maxnodes = nodes; + largest = CUDD_CONST_INDEX; + } + } + + /* Print summary. */ + retval = fprintf(dd->out,"Summary: %d tables, %d non-empty, largest: %d ", + ntables+1, nonempty, largest); + if (retval == EOF) return 0; + retval = fprintf(dd->out,"(with %d nodes)\n", maxnodes); + if (retval == EOF) return 0; + + return(1); + +} /* end of cuddHeapProfile */ + + +/**Function******************************************************************** + + Synopsis [Prints out information on a node.] + + Description [Prints out information on a node.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddPrintNode( + DdNode * f, + FILE *fp) +{ + f = Cudd_Regular(f); +#if SIZEOF_VOID_P == 8 + (void) fprintf(fp," node 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#else + (void) fprintf(fp," node 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#endif + +} /* end of cuddPrintNode */ + + + +/**Function******************************************************************** + + Synopsis [Prints the variable groups as a parenthesized list.] + + Description [Prints the variable groups as a parenthesized list. + For each group the level range that it represents is printed. After + each group, the group's flags are printed, preceded by a `|'. For + each flag (except MTR_TERMINAL) a character is printed. +
                    +
                  • F: MTR_FIXED +
                  • N: MTR_NEWNODE +
                  • S: MTR_SOFT +
                  + The second argument, silent, if different from 0, causes + Cudd_PrintVarGroups to only check the syntax of the group tree.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddPrintVarGroups( + DdManager * dd /* manager */, + MtrNode * root /* root of the group tree */, + int zdd /* 0: BDD; 1: ZDD */, + int silent /* flag to check tree syntax only */) +{ + MtrNode *node; + int level; + + assert(root != NULL); + assert(root->younger == NULL || root->younger->elder == root); + assert(root->elder == NULL || root->elder->younger == root); + if (zdd) { + level = dd->permZ[root->index]; + } else { + level = dd->perm[root->index]; + } + if (!silent) (void) printf("(%d",level); + if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) { + if (!silent) (void) printf(","); + } else { + node = root->child; + while (node != NULL) { + assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size)); + assert(node->parent == root); + cuddPrintVarGroups(dd,node,zdd,silent); + node = node->younger; + } + } + if (!silent) { + (void) printf("%d", (int) (level + root->size - 1)); + if (root->flags != MTR_DEFAULT) { + (void) printf("|"); + if (MTR_TEST(root,MTR_FIXED)) (void) printf("F"); + if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N"); + if (MTR_TEST(root,MTR_SOFT)) (void) printf("S"); + } + (void) printf(")"); + if (root->parent == NULL) (void) printf("\n"); + } + assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0); + return; + +} /* end of cuddPrintVarGroups */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Searches the subtables above node for its parents.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +debugFindParent( + DdManager * table, + DdNode * node) +{ + int i,j; + int slots; + DdNodePtr *nodelist; + DdNode *f; + + for (i = 0; i < cuddI(table,node->index); i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + for (j=0;jout,"parent is at 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n", + (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#else + (void) fprintf(table->out,"parent is at 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n", + (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#endif + } + f = f->next; + } + } + } + +} /* end of debugFindParent */ + + +#if 0 +/**Function******************************************************************** + + Synopsis [Reports an error if a (dead) node has a non-dead parent.] + + Description [Searches all the subtables above node. Very expensive. + The same check is now implemented more efficiently in ddDebugCheck.] + + SideEffects [None] + + SeeAlso [debugFindParent] + +******************************************************************************/ +static void +debugCheckParent( + DdManager * table, + DdNode * node) +{ + int i,j; + int slots; + DdNode **nodelist,*f; + + for (i = 0; i < cuddI(table,node->index); i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + for (j=0;jref != 0) { + (void) fprintf(table->err, + "error with zero ref count\n"); + (void) fprintf(table->err,"parent is 0x%x, id = %u, ref = %u, then = 0x%x, else = 0x%x\n",f,f->index,f->ref,cuddT(f),cuddE(f)); + (void) fprintf(table->err,"child is 0x%x, id = %u, ref = %u, then = 0x%x, else = 0x%x\n",node,node->index,node->ref,cuddT(node),cuddE(node)); + } + f = f->next; + } + } + } +} +#endif diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddClip.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddClip.c new file mode 100644 index 000000000..2993254ff --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddClip.c @@ -0,0 +1,558 @@ +/**CFile*********************************************************************** + + FileName [cuddClip.c] + + PackageName [cudd] + + Synopsis [Clipping functions.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_bddClippingAnd() +
                  • Cudd_bddClippingAndAbstract() +
                  + Internal procedures included in this module: +
                    +
                  • cuddBddClippingAnd() +
                  • cuddBddClippingAndAbstract() +
                  + Static procedures included in this module: +
                    +
                  • cuddBddClippingAndRecur() +
                  • cuddBddClipAndAbsRecur() +
                  + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.9 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * cuddBddClippingAndRecur (DdManager *manager, DdNode *f, DdNode *g, int distance, int direction); +static DdNode * cuddBddClipAndAbsRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, int distance, int direction); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g.] + + Description [Approximates the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddClippingAnd( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddClippingAnd(dd,f,g,maxDepth,direction); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddClippingAnd */ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube.] + + Description [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. The variables are + existentially abstracted. Returns a pointer to the resulting BDD if + successful; NULL if the intermediate result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract Cudd_bddClippingAnd] + +******************************************************************************/ +DdNode * +Cudd_bddClippingAndAbstract( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + DdNode * cube /* cube of variables to be abstracted */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddClippingAndAbstract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g.] + + Description [Approximates the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddClippingAnd] + +******************************************************************************/ +DdNode * +cuddBddClippingAnd( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + res = cuddBddClippingAndRecur(dd,f,g,maxDepth,direction); + + return(res); + +} /* end of cuddBddClippingAnd */ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube.] + + Description [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddClippingAndAbstract] + +******************************************************************************/ +DdNode * +cuddBddClippingAndAbstract( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + DdNode * cube /* cube of variables to be abstracted */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + res = cuddBddClipAndAbsRecur(dd,f,g,cube,maxDepth,direction); + + return(res); + +} /* end of cuddBddClippingAndAbstract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddClippingAnd.] + + Description [Implements the recursive step of Cudd_bddClippingAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddBddClippingAnd] + +******************************************************************************/ +static DdNode * +cuddBddClippingAndRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + int distance, + int direction) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *zero, *r, *t, *e; + unsigned int topf, topg, index; + DD_CTFP cacheOp; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == g || g == one) return(f); + if (f == one) return(g); + if (distance == 0) { + /* One last attempt at returning the right result. We sort of + ** cheat by calling Cudd_bddLeq. */ + if (Cudd_bddLeq(manager,f,g)) return(f); + if (Cudd_bddLeq(manager,g,f)) return(g); + if (direction == 1) { + if (Cudd_bddLeq(manager,f,Cudd_Not(g)) || + Cudd_bddLeq(manager,g,Cudd_Not(f))) return(zero); + } + return(Cudd_NotCond(one,(direction == 0))); + } + + /* At this point f and g are not constant. */ + distance--; + + /* Check cache. Try to increase cache efficiency by sorting the + ** pointers. */ + if (f > g) { + DdNode *tmp = f; + f = g; g = tmp; + } + F = Cudd_Regular(f); + G = Cudd_Regular(g); + cacheOp = (DD_CTFP) + (direction ? Cudd_bddClippingAnd : cuddBddClippingAnd); + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup2(manager, cacheOp, f, g); + if (r != NULL) return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg <= topf) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + t = cuddBddClippingAndRecur(manager, ft, gt, distance, direction); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddClippingAndRecur(manager, fe, ge, distance, direction); + if (e == NULL) { + Cudd_RecursiveDeref(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert2(manager, cacheOp, f, g, r); + return(r); + +} /* end of cuddBddClippingAndRecur */ + + +/**Function******************************************************************** + + Synopsis [Approximates the AND of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Approximates the AND of two BDDs and simultaneously + abstracts the variables in cube. The variables are existentially + abstracted. Returns a pointer to the result is successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddClippingAndAbstract] + +******************************************************************************/ +static DdNode * +cuddBddClipAndAbsRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube, + int distance, + int direction) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *zero, *r, *t, *e, *Cube; + unsigned int topf, topg, topcube, top, index; + ptruint cacheTag; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == one && g == one) return(one); + if (cube == one) { + return(cuddBddClippingAndRecur(manager, f, g, distance, direction)); + } + if (f == one || f == g) { + return (cuddBddExistAbstractRecur(manager, g, cube)); + } + if (g == one) { + return (cuddBddExistAbstractRecur(manager, f, cube)); + } + if (distance == 0) return(Cudd_NotCond(one,(direction == 0))); + + /* At this point f, g, and cube are not constant. */ + distance--; + + /* Check cache. */ + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; g = tmp; + } + F = Cudd_Regular(f); + G = Cudd_Regular(g); + cacheTag = direction ? DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG : + DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG; + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup(manager, cacheTag, + f, g, cube); + if (r != NULL) { + return(r); + } + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + top = ddMin(topf, topg); + topcube = manager->perm[cube->index]; + + if (topcube < top) { + return(cuddBddClipAndAbsRecur(manager, f, g, cuddT(cube), + distance, direction)); + } + /* Now, topcube >= top. */ + + if (topf == top) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg == top) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + if (topcube == top) { + Cube = cuddT(cube); + } else { + Cube = cube; + } + + t = cuddBddClipAndAbsRecur(manager, ft, gt, Cube, distance, direction); + if (t == NULL) return(NULL); + + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. + */ + if (t == one && topcube == top) { + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, cacheTag, f, g, cube, one); + return(one); + } + cuddRef(t); + + e = cuddBddClipAndAbsRecur(manager, fe, ge, Cube, distance, direction); + if (e == NULL) { + Cudd_RecursiveDeref(manager, t); + return(NULL); + } + cuddRef(e); + + if (topcube == top) { /* abstract */ + r = cuddBddClippingAndRecur(manager, Cudd_Not(t), Cudd_Not(e), + distance, (direction == 0)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + cuddDeref(r); + } else if (t == e) { + r = t; + cuddDeref(t); + cuddDeref(e); + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + } + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, cacheTag, f, g, cube, r); + return (r); + +} /* end of cuddBddClipAndAbsRecur */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCof.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCof.c new file mode 100644 index 000000000..cff47b20a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCof.c @@ -0,0 +1,327 @@ +/**CFile*********************************************************************** + + FileName [cuddCof.c] + + PackageName [cudd] + + Synopsis [Cofactoring functions.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_Cofactor() +
                  • Cudd_CheckCube() +
                  + Internal procedures included in this module: +
                    +
                  • cuddGetBranches() +
                  • cuddCofactorRecur() +
                  + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddCof.c,v 1.11 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the cofactor of f with respect to g.] + + Description [Computes the cofactor of f with respect to g; g must be + the BDD or the ADD of a cube. Returns a pointer to the cofactor if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_Cofactor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res,*zero; + + zero = Cudd_Not(DD_ONE(dd)); + if (g == zero || g == DD_ZERO(dd)) { + (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + do { + dd->reordered = 0; + res = cuddCofactorRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_Cofactor */ + + +/**Function******************************************************************** + + Synopsis [Checks whether g is the BDD of a cube.] + + Description [Checks whether g is the BDD of a cube. Returns 1 in case + of success; 0 otherwise. The constant 1 is a valid cube, but all other + constant functions cause cuddCheckCube to return 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_CheckCube( + DdManager * dd, + DdNode * g) +{ + DdNode *g1,*g0,*one,*zero; + + one = DD_ONE(dd); + if (g == one) return(1); + if (Cudd_IsConstant(g)) return(0); + + zero = Cudd_Not(one); + cuddGetBranches(g,&g1,&g0); + + if (g0 == zero) { + return(Cudd_CheckCube(dd, g1)); + } + if (g1 == zero) { + return(Cudd_CheckCube(dd, g0)); + } + return(0); + +} /* end of Cudd_CheckCube */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the children of g.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddGetBranches( + DdNode * g, + DdNode ** g1, + DdNode ** g0) +{ + DdNode *G = Cudd_Regular(g); + + *g1 = cuddT(G); + *g0 = cuddE(G); + if (Cudd_IsComplement(g)) { + *g1 = Cudd_Not(*g1); + *g0 = Cudd_Not(*g0); + } + +} /* end of cuddGetBranches */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_Cofactor.] + + Description [Performs the recursive step of Cudd_Cofactor. Returns a + pointer to the cofactor if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Cofactor] + +******************************************************************************/ +DdNode * +cuddCofactorRecur( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *one,*zero,*F,*G,*g1,*g0,*f1,*f0,*t,*e,*r; + unsigned int topf,topg; + int comple; + + statLine(dd); + F = Cudd_Regular(f); + if (cuddIsConstant(F)) return(f); + + one = DD_ONE(dd); + + /* The invariant g != 0 is true on entry to this procedure and is + ** recursively maintained by it. Therefore it suffices to test g + ** against one to make sure it is not constant. + */ + if (g == one) return(f); + /* From now on, f and g are known not to be constants. */ + + comple = f != F; + r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + topf = dd->perm[F->index]; + G = Cudd_Regular(g); + topg = dd->perm[G->index]; + + /* We take the cofactors of F because we are going to rely on + ** the fact that the cofactors of the complement are the complements + ** of the cofactors to better utilize the cache. Variable comple + ** remembers whether we have to complement the result or not. + */ + if (topf <= topg) { + f1 = cuddT(F); f0 = cuddE(F); + } else { + f1 = f0 = F; + } + if (topg <= topf) { + g1 = cuddT(G); g0 = cuddE(G); + if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); } + } else { + g1 = g0 = g; + } + + zero = Cudd_Not(one); + if (topf >= topg) { + if (g0 == zero || g0 == DD_ZERO(dd)) { + r = cuddCofactorRecur(dd, f1, g1); + } else if (g1 == zero || g1 == DD_ZERO(dd)) { + r = cuddCofactorRecur(dd, f0, g0); + } else { + (void) fprintf(dd->out, + "Cudd_Cofactor: Invalid restriction 2\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + if (r == NULL) return(NULL); + } else /* if (topf < topg) */ { + t = cuddCofactorRecur(dd, f1, g); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddCofactorRecur(dd, f0, g); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e)); + if (r != NULL) + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(dd,(int)F->index,t,e); + } + if (r == NULL) { + Cudd_RecursiveDeref(dd ,e); + Cudd_RecursiveDeref(dd ,t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(dd,Cudd_Cofactor,F,g,r); + + return(Cudd_NotCond(r,comple)); + +} /* end of cuddCofactorRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCompose.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCompose.c new file mode 100644 index 000000000..eea044f59 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddCompose.c @@ -0,0 +1,1749 @@ +/**CFile*********************************************************************** + + FileName [cuddCompose.c] + + PackageName [cudd] + + Synopsis [Functional composition and variable permutation of DDs.] + + Description [External procedures included in this module: +
                    +
                  • Cudd_bddCompose() +
                  • Cudd_addCompose() +
                  • Cudd_addPermute() +
                  • Cudd_addSwapVariables() +
                  • Cudd_bddPermute() +
                  • Cudd_bddVarMap() +
                  • Cudd_SetVarMap() +
                  • Cudd_bddSwapVariables() +
                  • Cudd_bddAdjPermuteX() +
                  • Cudd_addVectorCompose() +
                  • Cudd_addGeneralVectorCompose() +
                  • Cudd_addNonSimCompose() +
                  • Cudd_bddVectorCompose() +
                  + Internal procedures included in this module: +
                    +
                  • cuddBddComposeRecur() +
                  • cuddAddComposeRecur() +
                  + Static procedures included in this module: +
                    +
                  • cuddAddPermuteRecur() +
                  • cuddBddPermuteRecur() +
                  • cuddBddVarMapRecur() +
                  • cuddAddVectorComposeRecur() +
                  • cuddAddGeneralVectorComposeRecur() +
                  • cuddAddNonSimComposeRecur() +
                  • cuddBddVectorComposeRecur() +
                  • ddIsIthAddVar() +
                  • ddIsIthAddVarPair() +
                  + The permutation functions use a local cache because the results to + be remembered depend on the permutation being applied. Since the + permutation is just an array, it cannot be stored in the global + cache. There are different procedured for BDDs and ADDs. This is + because bddPermuteRecur uses cuddBddIteRecur. If this were changed, + the procedures could be merged.] + + Author [Fabio Somenzi and Kavita Ravi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddCompose.c,v 1.46 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef DD_DEBUG +static int addPermuteRecurHits; +static int bddPermuteRecurHits; +static int bddVectorComposeHits; +static int addVectorComposeHits; + +static int addGeneralVectorComposeHits; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * cuddAddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut); +static DdNode * cuddBddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut); +static DdNode * cuddBddVarMapRecur (DdManager *manager, DdNode *f); +static DdNode * cuddAddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest); +static DdNode * cuddAddNonSimComposeRecur (DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub); +static DdNode * cuddBddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest); +DD_INLINE static int ddIsIthAddVar (DdManager *dd, DdNode *f, unsigned int i); + +static DdNode * cuddAddGeneralVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest); +DD_INLINE static int ddIsIthAddVarPair (DdManager *dd, DdNode *f, DdNode *g, unsigned int i); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Substitutes g for x_v in the BDD for f.] + + Description [Substitutes g for x_v in the BDD for f. v is the index of the + variable to be substituted. Cudd_bddCompose passes the corresponding + projection function to the recursive procedure, so that the cache may + be used. Returns the composed BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCompose] + +******************************************************************************/ +DdNode * +Cudd_bddCompose( + DdManager * dd, + DdNode * f, + DdNode * g, + int v) +{ + DdNode *proj, *res; + + /* Sanity check. */ + if (v < 0 || v >= dd->size) return(NULL); + + proj = dd->vars[v]; + do { + dd->reordered = 0; + res = cuddBddComposeRecur(dd,f,g,proj); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddCompose */ + + +/**Function******************************************************************** + + Synopsis [Substitutes g for x_v in the ADD for f.] + + Description [Substitutes g for x_v in the ADD for f. v is the index of the + variable to be substituted. g must be a 0-1 ADD. Cudd_bddCompose passes + the corresponding projection function to the recursive procedure, so + that the cache may be used. Returns the composed ADD if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddCompose] + +******************************************************************************/ +DdNode * +Cudd_addCompose( + DdManager * dd, + DdNode * f, + DdNode * g, + int v) +{ + DdNode *proj, *res; + + /* Sanity check. */ + if (v < 0 || v >= dd->size) return(NULL); + + proj = dd->vars[v]; + do { + dd->reordered = 0; + res = cuddAddComposeRecur(dd,f,g,proj); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addCompose */ + + +/**Function******************************************************************** + + Synopsis [Permutes the variables of an ADD.] + + Description [Given a permutation in array permut, creates a new ADD + with permuted variables. There should be an entry in array permut + for each variable in the manager. The i-th entry of permut holds the + index of the variable that is to substitute the i-th + variable. Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_addSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_addPermute( + DdManager * manager, + DdNode * node, + int * permut) +{ + DdHashTable *table; + DdNode *res; + + do { + manager->reordered = 0; + table = cuddHashTableInit(manager,1,2); + if (table == NULL) return(NULL); + /* Recursively solve the problem. */ + res = cuddAddPermuteRecur(manager,table,node,permut); + if (res != NULL) cuddRef(res); + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (manager->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addPermute */ + + +/**Function******************************************************************** + + Synopsis [Swaps two sets of variables of the same size (x and y) in + the ADD f.] + + Description [Swaps two sets of variables of the same size (x and y) in + the ADD f. The size is given by n. The two sets of variables are + assumed to be disjoint. Returns a pointer to the resulting ADD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addPermute Cudd_bddSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_addSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *swapped; + int i, j, k; + int *permut; + + permut = ALLOC(int,dd->size); + if (permut == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) permut[i] = i; + for (i = 0; i < n; i++) { + j = x[i]->index; + k = y[i]->index; + permut[j] = k; + permut[k] = j; + } + + swapped = Cudd_addPermute(dd,f,permut); + FREE(permut); + + return(swapped); + +} /* end of Cudd_addSwapVariables */ + + +/**Function******************************************************************** + + Synopsis [Permutes the variables of a BDD.] + + Description [Given a permutation in array permut, creates a new BDD + with permuted variables. There should be an entry in array permut + for each variable in the manager. The i-th entry of permut holds the + index of the variable that is to substitute the i-th variable. + Returns a pointer to the resulting BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addPermute Cudd_bddSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_bddPermute( + DdManager * manager, + DdNode * node, + int * permut) +{ + DdHashTable *table; + DdNode *res; + + do { + manager->reordered = 0; + table = cuddHashTableInit(manager,1,2); + if (table == NULL) return(NULL); + res = cuddBddPermuteRecur(manager,table,node,permut); + if (res != NULL) cuddRef(res); + /* Dispose of local cache. */ + cuddHashTableQuit(table); + + } while (manager->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_bddPermute */ + + +/**Function******************************************************************** + + Synopsis [Remaps the variables of a BDD using the default variable map.] + + Description [Remaps the variables of a BDD using the default + variable map. A typical use of this function is to swap two sets of + variables. The variable map must be registered with Cudd_SetVarMap. + Returns a pointer to the resulting BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables Cudd_SetVarMap] + +******************************************************************************/ +DdNode * +Cudd_bddVarMap( + DdManager * manager /* DD manager */, + DdNode * f /* function in which to remap variables */) +{ + DdNode *res; + + if (manager->map == NULL) return(NULL); + do { + manager->reordered = 0; + res = cuddBddVarMapRecur(manager, f); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddVarMap */ + + +/**Function******************************************************************** + + Synopsis [Registers a variable mapping with the manager.] + + Description [Registers with the manager a variable mapping described + by two sets of variables. This variable mapping is then used by + functions like Cudd_bddVarMap. This function is convenient for + those applications that perform the same mapping several times. + However, if several different permutations are used, it may be more + efficient not to rely on the registered mapping, because changing + mapping causes the cache to be cleared. (The initial setting, + however, does not clear the cache.) The two sets of variables (x and + y) must have the same size (x and y). The size is given by n. The + two sets of variables are normally disjoint, but this restriction is + not imposeded by the function. When new variables are created, the + map is automatically extended (each new variable maps to + itself). The typical use, however, is to wait until all variables + are created, and then create the map. Returns 1 if the mapping is + successfully registered with the manager; 0 otherwise.] + + SideEffects [Modifies the manager. May clear the cache.] + + SeeAlso [Cudd_bddVarMap Cudd_bddPermute Cudd_bddSwapVariables] + +******************************************************************************/ +int +Cudd_SetVarMap ( + DdManager *manager /* DD manager */, + DdNode **x /* first array of variables */, + DdNode **y /* second array of variables */, + int n /* length of both arrays */) +{ + int i; + + if (manager->map != NULL) { + cuddCacheFlush(manager); + } else { + manager->map = ALLOC(int,manager->maxSize); + if (manager->map == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(0); + } + manager->memused += sizeof(int) * manager->maxSize; + } + /* Initialize the map to the identity. */ + for (i = 0; i < manager->size; i++) { + manager->map[i] = i; + } + /* Create the map. */ + for (i = 0; i < n; i++) { + manager->map[x[i]->index] = y[i]->index; + manager->map[y[i]->index] = x[i]->index; + } + return(1); + +} /* end of Cudd_SetVarMap */ + + +/**Function******************************************************************** + + Synopsis [Swaps two sets of variables of the same size (x and y) in + the BDD f.] + + Description [Swaps two sets of variables of the same size (x and y) + in the BDD f. The size is given by n. The two sets of variables are + assumed to be disjoint. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_addSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_bddSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *swapped; + int i, j, k; + int *permut; + + permut = ALLOC(int,dd->size); + if (permut == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) permut[i] = i; + for (i = 0; i < n; i++) { + j = x[i]->index; + k = y[i]->index; + permut[j] = k; + permut[k] = j; + } + + swapped = Cudd_bddPermute(dd,f,permut); + FREE(permut); + + return(swapped); + +} /* end of Cudd_bddSwapVariables */ + + +/**Function******************************************************************** + + Synopsis [Rearranges a set of variables in the BDD B.] + + Description [Rearranges a set of variables in the BDD B. The size of + the set is given by n. This procedure is intended for the + `randomization' of the priority functions. Returns a pointer to the + BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables + Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_PrioritySelect] + +******************************************************************************/ +DdNode * +Cudd_bddAdjPermuteX( + DdManager * dd, + DdNode * B, + DdNode ** x, + int n) +{ + DdNode *swapped; + int i, j, k; + int *permut; + + permut = ALLOC(int,dd->size); + if (permut == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) permut[i] = i; + for (i = 0; i < n-2; i += 3) { + j = x[i]->index; + k = x[i+1]->index; + permut[j] = k; + permut[k] = j; + } + + swapped = Cudd_bddPermute(dd,B,permut); + FREE(permut); + + return(swapped); + +} /* end of Cudd_bddAdjPermuteX */ + + +/**Function******************************************************************** + + Synopsis [Composes an ADD with a vector of 0-1 ADDs.] + + Description [Given a vector of 0-1 ADDs, creates a new ADD by + substituting the 0-1 ADDs for the variables of the ADD f. There + should be an entry in vector for each variable in the manager. + If no substitution is sought for a given variable, the corresponding + projection function should be specified in the vector. + This function implements simultaneous composition. + Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNonSimCompose Cudd_addPermute Cudd_addCompose + Cudd_bddVectorCompose] + +******************************************************************************/ +DdNode * +Cudd_addVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector) +{ + DdHashTable *table; + DdNode *res; + int deepest; + int i; + + do { + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (!ddIsIthAddVar(dd,vector[i],i)) { + break; + } + } + + /* Recursively solve the problem. */ + res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest); + if (res != NULL) cuddRef(res); + + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (dd->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addVectorCompose */ + + +/**Function******************************************************************** + + Synopsis [Composes an ADD with a vector of ADDs.] + + Description [Given a vector of ADDs, creates a new ADD by substituting the + ADDs for the variables of the ADD f. vectorOn contains ADDs to be substituted + for the x_v and vectorOff the ADDs to be substituted for x_v'. There should + be an entry in vector for each variable in the manager. If no substitution + is sought for a given variable, the corresponding projection function should + be specified in the vector. This function implements simultaneous + composition. Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addVectorCompose Cudd_addNonSimCompose Cudd_addPermute + Cudd_addCompose Cudd_bddVectorCompose] + +******************************************************************************/ +DdNode * +Cudd_addGeneralVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vectorOn, + DdNode ** vectorOff) +{ + DdHashTable *table; + DdNode *res; + int deepest; + int i; + + do { + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) { + break; + } + } + + /* Recursively solve the problem. */ + res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn, + vectorOff,deepest); + if (res != NULL) cuddRef(res); + + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (dd->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addGeneralVectorCompose */ + + +/**Function******************************************************************** + + Synopsis [Composes an ADD with a vector of 0-1 ADDs.] + + Description [Given a vector of 0-1 ADDs, creates a new ADD by + substituting the 0-1 ADDs for the variables of the ADD f. There + should be an entry in vector for each variable in the manager. + This function implements non-simultaneous composition. If any of the + functions being composed depends on any of the variables being + substituted, then the result depends on the order of composition, + which in turn depends on the variable order: The variables farther from + the roots in the order are substituted first. + Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addVectorCompose Cudd_addPermute Cudd_addCompose] + +******************************************************************************/ +DdNode * +Cudd_addNonSimCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector) +{ + DdNode *cube, *key, *var, *tmp, *piece; + DdNode *res; + int i, lastsub; + + /* The cache entry for this function is composed of three parts: + ** f itself, the replacement relation, and the cube of the + ** variables being substituted. + ** The replacement relation is the product of the terms (yi EXNOR gi). + ** This apporach allows us to use the global cache for this function, + ** with great savings in memory with respect to using arrays for the + ** cache entries. + ** First we build replacement relation and cube of substituted + ** variables from the vector specifying the desired composition. + */ + key = DD_ONE(dd); + cuddRef(key); + cube = DD_ONE(dd); + cuddRef(cube); + for (i = (int) dd->size - 1; i >= 0; i--) { + if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) { + continue; + } + var = Cudd_addIthVar(dd,i); + if (var == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(var); + /* Update cube. */ + tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cube); + cube = tmp; + /* Update replacement relation. */ + piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]); + if (piece == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(piece); + Cudd_RecursiveDeref(dd,var); + tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,piece); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,piece); + key = tmp; + } + + /* Now try composition, until no reordering occurs. */ + do { + /* Find real substitution with largest index. */ + for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) { + if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) { + break; + } + } + + /* Recursively solve the problem. */ + dd->reordered = 0; + res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1); + if (res != NULL) cuddRef(res); + + } while (dd->reordered == 1); + + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addNonSimCompose */ + + +/**Function******************************************************************** + + Synopsis [Composes a BDD with a vector of BDDs.] + + Description [Given a vector of BDDs, creates a new BDD by + substituting the BDDs for the variables of the BDD f. There + should be an entry in vector for each variable in the manager. + If no substitution is sought for a given variable, the corresponding + projection function should be specified in the vector. + This function implements simultaneous composition. + Returns a pointer to the resulting BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_bddCompose Cudd_addVectorCompose] + +******************************************************************************/ +DdNode * +Cudd_bddVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector) +{ + DdHashTable *table; + DdNode *res; + int deepest; + int i; + + do { + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (vector[i] != dd->vars[i]) { + break; + } + } + + /* Recursively solve the problem. */ + res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest); + if (res != NULL) cuddRef(res); + + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (dd->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_bddVectorCompose */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCompose.] + + Description [Performs the recursive step of Cudd_bddCompose. + Exploits the fact that the composition of f' with g + produces the complement of the composition of f with g to better + utilize the cache. Returns the composed BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddCompose] + +******************************************************************************/ +DdNode * +cuddBddComposeRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * proj) +{ + DdNode *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e; + unsigned int v, topf, topg, topindex; + int comple; + + statLine(dd); + v = dd->perm[proj->index]; + F = Cudd_Regular(f); + topf = cuddI(dd,F->index); + + /* Terminal case. Subsumes the test for constant f. */ + if (topf > v) return(f); + + /* We solve the problem for a regular pointer, and then complement + ** the result if the pointer was originally complemented. + */ + comple = Cudd_IsComplement(f); + + /* Check cache. */ + r = cuddCacheLookup(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + if (topf == v) { + /* Compose. */ + f1 = cuddT(F); + f0 = cuddE(F); + r = cuddBddIteRecur(dd, g, f1, f0); + if (r == NULL) return(NULL); + } else { + /* Compute cofactors of f and g. Remember the index of the top + ** variable. + */ + G = Cudd_Regular(g); + topg = cuddI(dd,G->index); + if (topf > topg) { + topindex = G->index; + f1 = f0 = F; + } else { + topindex = F->index; + f1 = cuddT(F); + f0 = cuddE(F); + } + if (topg > topf) { + g1 = g0 = g; + } else { + g1 = cuddT(G); + g0 = cuddE(G); + if (g != G) { + g1 = Cudd_Not(g1); + g0 = Cudd_Not(g0); + } + } + /* Recursive step. */ + t = cuddBddComposeRecur(dd, f1, g1, proj); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddComposeRecur(dd, f0, g0, proj); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + cuddRef(e); + + r = cuddBddIteRecur(dd, dd->vars[topindex], t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, t); /* t & e not necessarily part of r */ + Cudd_IterDerefBdd(dd, e); + cuddDeref(r); + } + + cuddCacheInsert(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj,r); + + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addCompose.] + + Description [Performs the recursive step of Cudd_addCompose. + Returns the composed BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCompose] + +******************************************************************************/ +DdNode * +cuddAddComposeRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * proj) +{ + DdNode *f1, *f0, *g1, *g0, *r, *t, *e; + unsigned int v, topf, topg, topindex; + + statLine(dd); + v = dd->perm[proj->index]; + topf = cuddI(dd,f->index); + + /* Terminal case. Subsumes the test for constant f. */ + if (topf > v) return(f); + + /* Check cache. */ + r = cuddCacheLookup(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj); + if (r != NULL) { + return(r); + } + + if (topf == v) { + /* Compose. */ + f1 = cuddT(f); + f0 = cuddE(f); + r = cuddAddIteRecur(dd, g, f1, f0); + if (r == NULL) return(NULL); + } else { + /* Compute cofactors of f and g. Remember the index of the top + ** variable. + */ + topg = cuddI(dd,g->index); + if (topf > topg) { + topindex = g->index; + f1 = f0 = f; + } else { + topindex = f->index; + f1 = cuddT(f); + f0 = cuddE(f); + } + if (topg > topf) { + g1 = g0 = g; + } else { + g1 = cuddT(g); + g0 = cuddE(g); + } + /* Recursive step. */ + t = cuddAddComposeRecur(dd, f1, g1, proj); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddAddComposeRecur(dd, f0, g0, proj); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + r = cuddUniqueInter(dd, (int) topindex, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj,r); + + return(r); + +} /* end of cuddAddComposeRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addPermute.] + + Description [ Recursively puts the ADD in the order given in the + array permut. Checks for trivial cases to terminate recursion, then + splits on the children of this node. Once the solutions for the + children are obtained, it puts into the current position the node + from the rest of the ADD that should be here. Then returns this ADD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper + position is reached in the recursion tree.

                  + The DdNode * that is returned is the same ADD as passed in as node, + but in the new order.] + + SideEffects [None] + + SeeAlso [Cudd_addPermute cuddBddPermuteRecur] + +******************************************************************************/ +static DdNode * +cuddAddPermuteRecur( + DdManager * manager /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * node /* ADD to be reordered */, + int * permut /* permutation array */) +{ + DdNode *T,*E; + DdNode *res,*var; + int index; + + statLine(manager); + /* Check for terminal case of constant node. */ + if (cuddIsConstant(node)) { + return(node); + } + + /* If problem already solved, look up answer and return. */ + if (node->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) { +#ifdef DD_DEBUG + addPermuteRecurHits++; +#endif + return(res); + } + + /* Split and recur on children of this node. */ + T = cuddAddPermuteRecur(manager,table,cuddT(node),permut); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddAddPermuteRecur(manager,table,cuddE(node),permut); + if (E == NULL) { + Cudd_RecursiveDeref(manager, T); + return(NULL); + } + cuddRef(E); + + /* Move variable that should be in this position to this position + ** by creating a single var ADD for that variable, and calling + ** cuddAddIteRecur with the T and E we just created. + */ + index = permut[node->index]; + var = cuddUniqueInter(manager,index,DD_ONE(manager),DD_ZERO(manager)); + if (var == NULL) return(NULL); + cuddRef(var); + res = cuddAddIteRecur(manager,var,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(manager,var); + Cudd_RecursiveDeref(manager, T); + Cudd_RecursiveDeref(manager, E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,var); + Cudd_RecursiveDeref(manager, T); + Cudd_RecursiveDeref(manager, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (node->ref != 1) { + ptrint fanout = (ptrint) node->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,node,res,fanout)) { + Cudd_RecursiveDeref(manager, res); + return(NULL); + } + } + cuddDeref(res); + return(res); + +} /* end of cuddAddPermuteRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddPermute.] + + Description [ Recursively puts the BDD in the order given in the array permut. + Checks for trivial cases to terminate recursion, then splits on the + children of this node. Once the solutions for the children are + obtained, it puts into the current position the node from the rest of + the BDD that should be here. Then returns this BDD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper position + is reached in the recursion tree.

                  + The DdNode * that is returned is the same BDD as passed in as node, + but in the new order.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute cuddAddPermuteRecur] + +******************************************************************************/ +static DdNode * +cuddBddPermuteRecur( + DdManager * manager /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * node /* BDD to be reordered */, + int * permut /* permutation array */) +{ + DdNode *N,*T,*E; + DdNode *res; + int index; + + statLine(manager); + N = Cudd_Regular(node); + + /* Check for terminal case of constant node. */ + if (cuddIsConstant(N)) { + return(node); + } + + /* If problem already solved, look up answer and return. */ + if (N->ref != 1 && (res = cuddHashTableLookup1(table,N)) != NULL) { +#ifdef DD_DEBUG + bddPermuteRecurHits++; +#endif + return(Cudd_NotCond(res,N != node)); + } + + /* Split and recur on children of this node. */ + T = cuddBddPermuteRecur(manager,table,cuddT(N),permut); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddBddPermuteRecur(manager,table,cuddE(N),permut); + if (E == NULL) { + Cudd_IterDerefBdd(manager, T); + return(NULL); + } + cuddRef(E); + + /* Move variable that should be in this position to this position + ** by retrieving the single var BDD for that variable, and calling + ** cuddBddIteRecur with the T and E we just created. + */ + index = permut[N->index]; + res = cuddBddIteRecur(manager,manager->vars[index],T,E); + if (res == NULL) { + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (N->ref != 1) { + ptrint fanout = (ptrint) N->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,N,res,fanout)) { + Cudd_IterDerefBdd(manager, res); + return(NULL); + } + } + cuddDeref(res); + return(Cudd_NotCond(res,N != node)); + +} /* end of cuddBddPermuteRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddVarMap.] + + Description [Implements the recursive step of Cudd_bddVarMap. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddVarMap] + +******************************************************************************/ +static DdNode * +cuddBddVarMapRecur( + DdManager *manager /* DD manager */, + DdNode *f /* BDD to be remapped */) +{ + DdNode *F, *T, *E; + DdNode *res; + int index; + + statLine(manager); + F = Cudd_Regular(f); + + /* Check for terminal case of constant node. */ + if (cuddIsConstant(F)) { + return(f); + } + + /* If problem already solved, look up answer and return. */ + if (F->ref != 1 && + (res = cuddCacheLookup1(manager,Cudd_bddVarMap,F)) != NULL) { + return(Cudd_NotCond(res,F != f)); + } + + /* Split and recur on children of this node. */ + T = cuddBddVarMapRecur(manager,cuddT(F)); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddBddVarMapRecur(manager,cuddE(F)); + if (E == NULL) { + Cudd_IterDerefBdd(manager, T); + return(NULL); + } + cuddRef(E); + + /* Move variable that should be in this position to this position + ** by retrieving the single var BDD for that variable, and calling + ** cuddBddIteRecur with the T and E we just created. + */ + index = manager->map[F->index]; + res = cuddBddIteRecur(manager,manager->vars[index],T,E); + if (res == NULL) { + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (F->ref != 1) { + cuddCacheInsert1(manager,Cudd_bddVarMap,F,res); + } + cuddDeref(res); + return(Cudd_NotCond(res,F != f)); + +} /* end of cuddBddVarMapRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addVectorCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddVectorComposeRecur( + DdManager * dd /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * f /* ADD in which to compose */, + DdNode ** vector /* functions to substitute */, + int deepest /* depth of deepest substitution */) +{ + DdNode *T,*E; + DdNode *res; + + statLine(dd); + /* If we are past the deepest substitution, return f. */ + if (cuddI(dd,f->index) > deepest) { + return(f); + } + + if ((res = cuddHashTableLookup1(table,f)) != NULL) { +#ifdef DD_DEBUG + addVectorComposeHits++; +#endif + return(res); + } + + /* Split and recur on children of this node. */ + T = cuddAddVectorComposeRecur(dd,table,cuddT(f),vector,deepest); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddAddVectorComposeRecur(dd,table,cuddE(f),vector,deepest); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + /* Retrieve the 0-1 ADD for the current top variable and call + ** cuddAddIteRecur with the T and E we just created. + */ + res = cuddAddIteRecur(dd,vector[f->index],T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again + */ + if (f->ref != 1) { + ptrint fanout = (ptrint) f->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + } + cuddDeref(res); + return(res); + +} /* end of cuddAddVectorComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addGeneralVectorCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddGeneralVectorComposeRecur( + DdManager * dd /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * f /* ADD in which to compose */, + DdNode ** vectorOn /* functions to substitute for x_i */, + DdNode ** vectorOff /* functions to substitute for x_i' */, + int deepest /* depth of deepest substitution */) +{ + DdNode *T,*E,*t,*e; + DdNode *res; + + /* If we are past the deepest substitution, return f. */ + if (cuddI(dd,f->index) > deepest) { + return(f); + } + + if ((res = cuddHashTableLookup1(table,f)) != NULL) { +#ifdef DD_DEBUG + addGeneralVectorComposeHits++; +#endif + return(res); + } + + /* Split and recur on children of this node. */ + T = cuddAddGeneralVectorComposeRecur(dd,table,cuddT(f), + vectorOn,vectorOff,deepest); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddAddGeneralVectorComposeRecur(dd,table,cuddE(f), + vectorOn,vectorOff,deepest); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + /* Retrieve the compose ADDs for the current top variable and call + ** cuddAddApplyRecur with the T and E we just created. + */ + t = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOn[f->index],T); + if (t == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(t); + e = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOff[f->index],E); + if (e == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again + */ + if (f->ref != 1) { + ptrint fanout = (ptrint) f->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + } + cuddDeref(res); + return(res); + +} /* end of cuddAddGeneralVectorComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addNonSimCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddNonSimComposeRecur( + DdManager * dd, + DdNode * f, + DdNode ** vector, + DdNode * key, + DdNode * cube, + int lastsub) +{ + DdNode *f1, *f0, *key1, *key0, *cube1, *var; + DdNode *T,*E; + DdNode *r; + unsigned int top, topf, topk, topc; + unsigned int index; + int i; + DdNode **vect1; + DdNode **vect0; + + statLine(dd); + /* If we are past the deepest substitution, return f. */ + if (cube == DD_ONE(dd) || cuddIsConstant(f)) { + return(f); + } + + /* If problem already solved, look up answer and return. */ + r = cuddCacheLookup(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube); + if (r != NULL) { + return(r); + } + + /* Find top variable. we just need to look at f, key, and cube, + ** because all the varibles in the gi are in key. + */ + topf = cuddI(dd,f->index); + topk = cuddI(dd,key->index); + top = ddMin(topf,topk); + topc = cuddI(dd,cube->index); + top = ddMin(top,topc); + index = dd->invperm[top]; + + /* Compute the cofactors. */ + if (topf == top) { + f1 = cuddT(f); + f0 = cuddE(f); + } else { + f1 = f0 = f; + } + if (topc == top) { + cube1 = cuddT(cube); + /* We want to eliminate vector[index] from key. Otherwise + ** cache performance is severely affected. Hence we + ** existentially quantify the variable with index "index" from key. + */ + var = Cudd_addIthVar(dd, (int) index); + if (var == NULL) { + return(NULL); + } + cuddRef(var); + key1 = cuddAddExistAbstractRecur(dd, key, var); + if (key1 == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(key1); + Cudd_RecursiveDeref(dd,var); + key0 = key1; + } else { + cube1 = cube; + if (topk == top) { + key1 = cuddT(key); + key0 = cuddE(key); + } else { + key1 = key0 = key; + } + cuddRef(key1); + } + + /* Allocate two new vectors for the cofactors of vector. */ + vect1 = ALLOC(DdNode *,lastsub); + if (vect1 == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd,key1); + return(NULL); + } + vect0 = ALLOC(DdNode *,lastsub); + if (vect0 == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd,key1); + FREE(vect1); + return(NULL); + } + + /* Cofactor the gi. Eliminate vect1[index] and vect0[index], because + ** we do not need them. + */ + for (i = 0; i < lastsub; i++) { + DdNode *gi = vector[i]; + if (gi == NULL) { + vect1[i] = vect0[i] = NULL; + } else if (gi->index == index) { + vect1[i] = cuddT(gi); + vect0[i] = cuddE(gi); + } else { + vect1[i] = vect0[i] = gi; + } + } + vect1[index] = vect0[index] = NULL; + + /* Recur on children. */ + T = cuddAddNonSimComposeRecur(dd,f1,vect1,key1,cube1,lastsub); + FREE(vect1); + if (T == NULL) { + Cudd_RecursiveDeref(dd,key1); + FREE(vect0); + return(NULL); + } + cuddRef(T); + E = cuddAddNonSimComposeRecur(dd,f0,vect0,key0,cube1,lastsub); + FREE(vect0); + if (E == NULL) { + Cudd_RecursiveDeref(dd,key1); + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + Cudd_RecursiveDeref(dd,key1); + + /* Retrieve the 0-1 ADD for the current top variable from vector, + ** and call cuddAddIteRecur with the T and E we just created. + */ + r = cuddAddIteRecur(dd,vector[index],T,E); + if (r == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + cuddDeref(r); + + /* Store answer to trim recursion. */ + cuddCacheInsert(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube,r); + + return(r); + +} /* end of cuddAddNonSimComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddVectorCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddBddVectorComposeRecur( + DdManager * dd /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * f /* BDD in which to compose */, + DdNode ** vector /* functions to be composed */, + int deepest /* depth of the deepest substitution */) +{ + DdNode *F,*T,*E; + DdNode *res; + + statLine(dd); + F = Cudd_Regular(f); + + /* If we are past the deepest substitution, return f. */ + if (cuddI(dd,F->index) > deepest) { + return(f); + } + + /* If problem already solved, look up answer and return. */ + if ((res = cuddHashTableLookup1(table,F)) != NULL) { +#ifdef DD_DEBUG + bddVectorComposeHits++; +#endif + return(Cudd_NotCond(res,F != f)); + } + + /* Split and recur on children of this node. */ + T = cuddBddVectorComposeRecur(dd,table,cuddT(F),vector, deepest); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddBddVectorComposeRecur(dd,table,cuddE(F),vector, deepest); + if (E == NULL) { + Cudd_IterDerefBdd(dd, T); + return(NULL); + } + cuddRef(E); + + /* Call cuddBddIteRecur with the BDD that replaces the current top + ** variable and the T and E we just created. + */ + res = cuddBddIteRecur(dd,vector[F->index],T,E); + if (res == NULL) { + Cudd_IterDerefBdd(dd, T); + Cudd_IterDerefBdd(dd, E); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd, T); + Cudd_IterDerefBdd(dd, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (F->ref != 1) { + ptrint fanout = (ptrint) F->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,F,res,fanout)) { + Cudd_IterDerefBdd(dd, res); + return(NULL); + } + } + cuddDeref(res); + return(Cudd_NotCond(res,F != f)); + +} /* end of cuddBddVectorComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Comparison of a function to the i-th ADD variable.] + + Description [Comparison of a function to the i-th ADD variable. Returns 1 if + the function is the i-th ADD variable; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static int +ddIsIthAddVar( + DdManager * dd, + DdNode * f, + unsigned int i) +{ + return(f->index == i && cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd)); + +} /* end of ddIsIthAddVar */ + + +/**Function******************************************************************** + + Synopsis [Comparison of a pair of functions to the i-th ADD variable.] + + Description [Comparison of a pair of functions to the i-th ADD + variable. Returns 1 if the functions are the i-th ADD variable and its + complement; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static int +ddIsIthAddVarPair( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int i) +{ + return(f->index == i && g->index == i && + cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd) && + cuddT(g) == DD_ZERO(dd) && cuddE(g) == DD_ONE(dd)); + +} /* end of ddIsIthAddVarPair */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddDecomp.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddDecomp.c new file mode 100644 index 000000000..066027d95 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddDecomp.c @@ -0,0 +1,2177 @@ +/**CFile*********************************************************************** + + FileName [cuddDecomp.c] + + PackageName [cudd] + + Synopsis [Functions for BDD decomposition.] + + Description [External procedures included in this file: +

                    +
                  • Cudd_bddApproxConjDecomp() +
                  • Cudd_bddApproxDisjDecomp() +
                  • Cudd_bddIterConjDecomp() +
                  • Cudd_bddIterDisjDecomp() +
                  • Cudd_bddGenConjDecomp() +
                  • Cudd_bddGenDisjDecomp() +
                  • Cudd_bddVarConjDecomp() +
                  • Cudd_bddVarDisjDecomp() +
                  + Static procedures included in this module: +
                    +
                  • cuddConjunctsAux() +
                  • CreateBotDist() +
                  • BuildConjuncts() +
                  • ConjunctsFree() +
                  ] + + Author [Kavita Ravi, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ +#define DEPTH 5 +#define THRESHOLD 10 +#define NONE 0 +#define PAIR_ST 1 +#define PAIR_CR 2 +#define G_ST 3 +#define G_CR 4 +#define H_ST 5 +#define H_CR 6 +#define BOTH_G 7 +#define BOTH_H 8 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ +typedef struct Conjuncts { + DdNode *g; + DdNode *h; +} Conjuncts; + +typedef struct NodeStat { + int distance; + int localRef; +} NodeStat; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddDecomp.c,v 1.45 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static DdNode *one, *zero; +long lastTimeG; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +#define FactorsNotStored(factors) ((int)((long)(factors) & 01)) + +#define FactorsComplement(factors) ((Conjuncts *)((long)(factors) | 01)) + +#define FactorsUncomplement(factors) ((Conjuncts *)((long)(factors) ^ 01)) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static NodeStat * CreateBotDist (DdNode * node, st_table * distanceTable); +static double CountMinterms (DdNode * node, double max, st_table * mintermTable, FILE *fp); +static void ConjunctsFree (DdManager * dd, Conjuncts * factors); +static int PairInTables (DdNode * g, DdNode * h, st_table * ghTable); +static Conjuncts * CheckTablesCacheAndReturn (DdNode * node, DdNode * g, DdNode * h, st_table * ghTable, st_table * cacheTable); +static Conjuncts * PickOnePair (DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable); +static Conjuncts * CheckInTables (DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable, int * outOfMem); +static Conjuncts * ZeroCase (DdManager * dd, DdNode * node, Conjuncts * factorsNv, st_table * ghTable, st_table * cacheTable, int switched); +static Conjuncts * BuildConjuncts (DdManager * dd, DdNode * node, st_table * distanceTable, st_table * cacheTable, int approxDistance, int maxLocalRef, st_table * ghTable, st_table * mintermTable); +static int cuddConjunctsAux (DdManager * dd, DdNode * f, DdNode ** c1, DdNode ** c2); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Performs two-way conjunctive decomposition of a + BDD. This procedure owes its name to the use of supersetting to + obtain an initial factor of the given function. Returns the number + of conjuncts produced, that is, 2 if successful; 1 if no meaningful + decomposition was found; 0 otherwise. The conjuncts produced by this + procedure tend to be imbalanced.] + + SideEffects [The factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddApproxDisjDecomp Cudd_bddIterConjDecomp + Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox + Cudd_bddSqueeze Cudd_bddLICompaction] + +******************************************************************************/ +int +Cudd_bddApproxConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the first factor */) +{ + DdNode *superset1, *superset2, *glocal, *hlocal; + int nvars = Cudd_SupportSize(dd,f); + + /* Find a tentative first factor by overapproximation and minimization. */ + superset1 = Cudd_RemapOverApprox(dd,f,nvars,0,1.0); + if (superset1 == NULL) return(0); + cuddRef(superset1); + superset2 = Cudd_bddSqueeze(dd,f,superset1); + if (superset2 == NULL) { + Cudd_RecursiveDeref(dd,superset1); + return(0); + } + cuddRef(superset2); + Cudd_RecursiveDeref(dd,superset1); + + /* Compute the second factor by minimization. */ + hlocal = Cudd_bddLICompaction(dd,f,superset2); + if (hlocal == NULL) { + Cudd_RecursiveDeref(dd,superset2); + return(0); + } + cuddRef(hlocal); + + /* Refine the first factor by minimization. If h turns out to be f, this + ** step guarantees that g will be 1. */ + glocal = Cudd_bddLICompaction(dd,superset2,hlocal); + if (glocal == NULL) { + Cudd_RecursiveDeref(dd,superset2); + Cudd_RecursiveDeref(dd,hlocal); + return(0); + } + cuddRef(glocal); + Cudd_RecursiveDeref(dd,superset2); + + if (glocal != DD_ONE(dd)) { + if (hlocal != DD_ONE(dd)) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,glocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = hlocal; + return(1); + } + +} /* end of Cudd_bddApproxConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD. + Returns the number of disjuncts produced, that is, 2 if successful; + 1 if no meaningful decomposition was found; 0 otherwise. The + disjuncts produced by this procedure tend to be imbalanced.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddApproxConjDecomp Cudd_bddIterDisjDecomp + Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp] + +******************************************************************************/ +int +Cudd_bddApproxDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddApproxConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddApproxDisjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Performs two-way conjunctive decomposition of a + BDD. This procedure owes its name to the iterated use of + supersetting to obtain a factor of the given function. Returns the + number of conjuncts produced, that is, 2 if successful; 1 if no + meaningful decomposition was found; 0 otherwise. The conjuncts + produced by this procedure tend to be imbalanced.] + + SideEffects [The factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddIterDisjDecomp Cudd_bddApproxConjDecomp + Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox + Cudd_bddSqueeze Cudd_bddLICompaction] + +******************************************************************************/ +int +Cudd_bddIterConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the array of conjuncts */) +{ + DdNode *superset1, *superset2, *old[2], *res[2]; + int sizeOld, sizeNew; + int nvars = Cudd_SupportSize(dd,f); + + old[0] = DD_ONE(dd); + cuddRef(old[0]); + old[1] = f; + cuddRef(old[1]); + sizeOld = Cudd_SharingSize(old,2); + + do { + /* Find a tentative first factor by overapproximation and + ** minimization. */ + superset1 = Cudd_RemapOverApprox(dd,old[1],nvars,0,1.0); + if (superset1 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(superset1); + superset2 = Cudd_bddSqueeze(dd,old[1],superset1); + if (superset2 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + Cudd_RecursiveDeref(dd,superset1); + return(0); + } + cuddRef(superset2); + Cudd_RecursiveDeref(dd,superset1); + res[0] = Cudd_bddAnd(dd,old[0],superset2); + if (res[0] == NULL) { + Cudd_RecursiveDeref(dd,superset2); + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(res[0]); + Cudd_RecursiveDeref(dd,superset2); + if (res[0] == old[0]) { + Cudd_RecursiveDeref(dd,res[0]); + break; /* avoid infinite loop */ + } + + /* Compute the second factor by minimization. */ + res[1] = Cudd_bddLICompaction(dd,old[1],res[0]); + if (res[1] == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(res[1]); + + sizeNew = Cudd_SharingSize(res,2); + if (sizeNew <= sizeOld) { + Cudd_RecursiveDeref(dd,old[0]); + old[0] = res[0]; + Cudd_RecursiveDeref(dd,old[1]); + old[1] = res[1]; + sizeOld = sizeNew; + } else { + Cudd_RecursiveDeref(dd,res[0]); + Cudd_RecursiveDeref(dd,res[1]); + break; + } + + } while (1); + + /* Refine the first factor by minimization. If h turns out to + ** be f, this step guarantees that g will be 1. */ + superset1 = Cudd_bddLICompaction(dd,old[0],old[1]); + if (superset1 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(superset1); + Cudd_RecursiveDeref(dd,old[0]); + old[0] = superset1; + + if (old[0] != DD_ONE(dd)) { + if (old[1] != DD_ONE(dd)) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[0]; + (*conjuncts)[1] = old[1]; + return(2); + } else { + Cudd_RecursiveDeref(dd,old[1]); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[0]; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,old[0]); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[1]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[1]; + return(1); + } + +} /* end of Cudd_bddIterConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD. + Returns the number of disjuncts produced, that is, 2 if successful; + 1 if no meaningful decomposition was found; 0 otherwise. The + disjuncts produced by this procedure tend to be imbalanced.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddIterConjDecomp Cudd_bddApproxDisjDecomp + Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp] + +******************************************************************************/ +int +Cudd_bddIterDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddIterConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddIterDisjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Performs two-way conjunctive decomposition of a + BDD. This procedure owes its name to the fact tht it generalizes the + decomposition based on the cofactors with respect to one + variable. Returns the number of conjuncts produced, that is, 2 if + successful; 1 if no meaningful decomposition was found; 0 + otherwise. The conjuncts produced by this procedure tend to be + balanced.] + + SideEffects [The two factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddGenDisjDecomp Cudd_bddApproxConjDecomp + Cudd_bddIterConjDecomp Cudd_bddVarConjDecomp] + +******************************************************************************/ +int +Cudd_bddGenConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the array of conjuncts */) +{ + int result; + DdNode *glocal, *hlocal; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + do { + dd->reordered = 0; + result = cuddConjunctsAux(dd, f, &glocal, &hlocal); + } while (dd->reordered == 1); + + if (result == 0) { + return(0); + } + + if (glocal != one) { + if (hlocal != one) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,glocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = hlocal; + return(1); + } + +} /* end of Cudd_bddGenConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD. + Returns the number of disjuncts produced, that is, 2 if successful; + 1 if no meaningful decomposition was found; 0 otherwise. The + disjuncts produced by this procedure tend to be balanced.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddGenConjDecomp Cudd_bddApproxDisjDecomp + Cudd_bddIterDisjDecomp Cudd_bddVarDisjDecomp] + +******************************************************************************/ +int +Cudd_bddGenDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddGenConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddGenDisjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Conjunctively decomposes one BDD according to a + variable. If f is the function of the BDD and + x is the variable, the decomposition is + (f+x)(f+x'). The variable is chosen so as to balance + the sizes of the two conjuncts and to keep them small. Returns the + number of conjuncts produced, that is, 2 if successful; 1 if no + meaningful decomposition was found; 0 otherwise.] + + SideEffects [The two factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddVarDisjDecomp Cudd_bddGenConjDecomp + Cudd_bddApproxConjDecomp Cudd_bddIterConjDecomp] + +*****************************************************************************/ +int +Cudd_bddVarConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the array of conjuncts */) +{ + int best; + int min; + DdNode *support, *scan, *var, *glocal, *hlocal; + + /* Find best cofactoring variable. */ + support = Cudd_Support(dd,f); + if (support == NULL) return(0); + if (Cudd_IsConstant(support)) { + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = f; + cuddRef((*conjuncts)[0]); + return(1); + } + cuddRef(support); + min = 1000000000; + best = -1; + scan = support; + while (!Cudd_IsConstant(scan)) { + int i = scan->index; + int est1 = Cudd_EstimateCofactor(dd,f,i,1); + int est0 = Cudd_EstimateCofactor(dd,f,i,0); + /* Minimize the size of the larger of the two cofactors. */ + int est = (est1 > est0) ? est1 : est0; + if (est < min) { + min = est; + best = i; + } + scan = cuddT(scan); + } +#ifdef DD_DEBUG + assert(best >= 0 && best < dd->size); +#endif + Cudd_RecursiveDeref(dd,support); + + var = Cudd_bddIthVar(dd,best); + glocal = Cudd_bddOr(dd,f,var); + if (glocal == NULL) { + return(0); + } + cuddRef(glocal); + hlocal = Cudd_bddOr(dd,f,Cudd_Not(var)); + if (hlocal == NULL) { + Cudd_RecursiveDeref(dd,glocal); + return(0); + } + cuddRef(hlocal); + + if (glocal != DD_ONE(dd)) { + if (hlocal != DD_ONE(dd)) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,glocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = hlocal; + return(1); + } + +} /* end of Cudd_bddVarConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD + according to a variable. If f is the function of the + BDD and x is the variable, the decomposition is + f*x + f*x'. The variable is chosen so as to balance + the sizes of the two disjuncts and to keep them small. Returns the + number of disjuncts produced, that is, 2 if successful; 1 if no + meaningful decomposition was found; 0 otherwise.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddVarConjDecomp Cudd_bddApproxDisjDecomp + Cudd_bddIterDisjDecomp Cudd_bddGenDisjDecomp] + +******************************************************************************/ +int +Cudd_bddVarDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddVarConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddVarDisjDecomp */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Get longest distance of node from constant.] + + Description [Get longest distance of node from constant. Returns the + distance of the root from the constant if successful; CUDD_OUT_OF_MEM + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static NodeStat * +CreateBotDist( + DdNode * node, + st_table * distanceTable) +{ + DdNode *N, *Nv, *Nnv; + int distance, distanceNv, distanceNnv; + NodeStat *nodeStat, *nodeStatNv, *nodeStatNnv; + +#if 0 + if (Cudd_IsConstant(node)) { + return(0); + } +#endif + + /* Return the entry in the table if found. */ + N = Cudd_Regular(node); + if (st_lookup(distanceTable, N, &nodeStat)) { + nodeStat->localRef++; + return(nodeStat); + } + + Nv = cuddT(N); + Nnv = cuddE(N); + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* Recur on the children. */ + nodeStatNv = CreateBotDist(Nv, distanceTable); + if (nodeStatNv == NULL) return(NULL); + distanceNv = nodeStatNv->distance; + + nodeStatNnv = CreateBotDist(Nnv, distanceTable); + if (nodeStatNnv == NULL) return(NULL); + distanceNnv = nodeStatNnv->distance; + /* Store max distance from constant; note sometimes this distance + ** may be to 0. + */ + distance = (distanceNv > distanceNnv) ? (distanceNv+1) : (distanceNnv + 1); + + nodeStat = ALLOC(NodeStat, 1); + if (nodeStat == NULL) { + return(0); + } + nodeStat->distance = distance; + nodeStat->localRef = 1; + + if (st_insert(distanceTable, (char *)N, (char *)nodeStat) == + ST_OUT_OF_MEM) { + return(0); + + } + return(nodeStat); + +} /* end of CreateBotDist */ + + +/**Function******************************************************************** + + Synopsis [Count the number of minterms of each node ina a BDD and + store it in a hash table.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double +CountMinterms( + DdNode * node, + double max, + st_table * mintermTable, + FILE *fp) +{ + DdNode *N, *Nv, *Nnv; + double min, minNv, minNnv; + double *dummy; + + N = Cudd_Regular(node); + + if (cuddIsConstant(N)) { + if (node == zero) { + return(0); + } else { + return(max); + } + } + + /* Return the entry in the table if found. */ + if (st_lookup(mintermTable, node, &dummy)) { + min = *dummy; + return(min); + } + + Nv = cuddT(N); + Nnv = cuddE(N); + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* Recur on the children. */ + minNv = CountMinterms(Nv, max, mintermTable, fp); + if (minNv == -1.0) return(-1.0); + minNnv = CountMinterms(Nnv, max, mintermTable, fp); + if (minNnv == -1.0) return(-1.0); + min = minNv / 2.0 + minNnv / 2.0; + /* store + */ + + dummy = ALLOC(double, 1); + if (dummy == NULL) return(-1.0); + *dummy = min; + if (st_insert(mintermTable, (char *)node, (char *)dummy) == ST_OUT_OF_MEM) { + (void) fprintf(fp, "st table insert failed\n"); + } + return(min); + +} /* end of CountMinterms */ + + +/**Function******************************************************************** + + Synopsis [Free factors structure] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ConjunctsFree( + DdManager * dd, + Conjuncts * factors) +{ + Cudd_RecursiveDeref(dd, factors->g); + Cudd_RecursiveDeref(dd, factors->h); + FREE(factors); + return; + +} /* end of ConjunctsFree */ + + +/**Function******************************************************************** + + Synopsis [Check whether the given pair is in the tables.] + + Description [.Check whether the given pair is in the tables. gTable + and hTable are combined. + absence in both is indicated by 0, + presence in gTable is indicated by 1, + presence in hTable by 2 and + presence in both by 3. + The values returned by this function are PAIR_ST, + PAIR_CR, G_ST, G_CR, H_ST, H_CR, BOTH_G, BOTH_H, NONE. + PAIR_ST implies g in gTable and h in hTable + PAIR_CR implies g in hTable and h in gTable + G_ST implies g in gTable and h not in any table + G_CR implies g in hTable and h not in any table + H_ST implies h in hTable and g not in any table + H_CR implies h in gTable and g not in any table + BOTH_G implies both in gTable + BOTH_H implies both in hTable + NONE implies none in table; ] + + SideEffects [] + + SeeAlso [CheckTablesCacheAndReturn CheckInTables] + +******************************************************************************/ +static int +PairInTables( + DdNode * g, + DdNode * h, + st_table * ghTable) +{ + int valueG, valueH, gPresent, hPresent; + + valueG = valueH = gPresent = hPresent = 0; + + gPresent = st_lookup_int(ghTable, (char *)Cudd_Regular(g), &valueG); + hPresent = st_lookup_int(ghTable, (char *)Cudd_Regular(h), &valueH); + + if (!gPresent && !hPresent) return(NONE); + + if (!hPresent) { + if (valueG & 1) return(G_ST); + if (valueG & 2) return(G_CR); + } + if (!gPresent) { + if (valueH & 1) return(H_CR); + if (valueH & 2) return(H_ST); + } + /* both in tables */ + if ((valueG & 1) && (valueH & 2)) return(PAIR_ST); + if ((valueG & 2) && (valueH & 1)) return(PAIR_CR); + + if (valueG & 1) { + return(BOTH_G); + } else { + return(BOTH_H); + } + +} /* end of PairInTables */ + + +/**Function******************************************************************** + + Synopsis [Check the tables for the existence of pair and return one + combination, cache the result.] + + Description [Check the tables for the existence of pair and return + one combination, cache the result. The assumption is that one of the + conjuncts is already in the tables.] + + SideEffects [g and h referenced for the cache] + + SeeAlso [ZeroCase] + +******************************************************************************/ +static Conjuncts * +CheckTablesCacheAndReturn( + DdNode * node, + DdNode * g, + DdNode * h, + st_table * ghTable, + st_table * cacheTable) +{ + int pairValue; + int value; + Conjuncts *factors; + + value = 0; + /* check tables */ + pairValue = PairInTables(g, h, ghTable); + assert(pairValue != NONE); + /* if both dont exist in table, we know one exists(either g or h). + * Therefore store the other and proceed + */ + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) return(NULL); + if ((pairValue == BOTH_H) || (pairValue == H_ST)) { + if (g != one) { + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(g), &value)) { + value |= 1; + } else { + value = 1; + } + if (st_insert(ghTable, (char *)Cudd_Regular(g), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = g; + factors->h = h; + } else if ((pairValue == BOTH_G) || (pairValue == G_ST)) { + if (h != one) { + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(h), &value)) { + value |= 2; + } else { + value = 2; + } + if (st_insert(ghTable, (char *)Cudd_Regular(h), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = g; + factors->h = h; + } else if (pairValue == H_CR) { + if (g != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = h; + factors->h = g; + } else if (pairValue == G_CR) { + if (h != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = h; + factors->h = g; + } else if (pairValue == PAIR_CR) { + /* pair exists in table */ + factors->g = h; + factors->h = g; + } else if (pairValue == PAIR_ST) { + factors->g = g; + factors->h = h; + } + + /* cache the result for this node */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + + return(factors); + +} /* end of CheckTablesCacheAndReturn */ + +/**Function******************************************************************** + + Synopsis [Check the tables for the existence of pair and return one + combination, store in cache.] + + Description [Check the tables for the existence of pair and return + one combination, store in cache. The pair that has more pointers to + it is picked. An approximation of the number of local pointers is + made by taking the reference count of the pairs sent. ] + + SideEffects [] + + SeeAlso [ZeroCase BuildConjuncts] + +******************************************************************************/ +static Conjuncts * +PickOnePair( + DdNode * node, + DdNode * g1, + DdNode * h1, + DdNode * g2, + DdNode * h2, + st_table * ghTable, + st_table * cacheTable) +{ + int value; + Conjuncts *factors; + int oneRef, twoRef; + + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) return(NULL); + + /* count the number of pointers to pair 2 */ + if (h2 == one) { + twoRef = (Cudd_Regular(g2))->ref; + } else if (g2 == one) { + twoRef = (Cudd_Regular(h2))->ref; + } else { + twoRef = ((Cudd_Regular(g2))->ref + (Cudd_Regular(h2))->ref)/2; + } + + /* count the number of pointers to pair 1 */ + if (h1 == one) { + oneRef = (Cudd_Regular(g1))->ref; + } else if (g1 == one) { + oneRef = (Cudd_Regular(h1))->ref; + } else { + oneRef = ((Cudd_Regular(g1))->ref + (Cudd_Regular(h1))->ref)/2; + } + + /* pick the pair with higher reference count */ + if (oneRef >= twoRef) { + factors->g = g1; + factors->h = h1; + } else { + factors->g = g2; + factors->h = h2; + } + + /* + * Store computed factors in respective tables to encourage + * recombination. + */ + if (factors->g != one) { + /* insert g in htable */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->g), &value)) { + if (value == 2) { + value |= 1; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } else { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } + + if (factors->h != one) { + /* insert h in htable */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->h), &value)) { + if (value == 1) { + value |= 2; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } else { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } + + /* Store factors in cache table for later use. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == + ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + + return(factors); + +} /* end of PickOnePair */ + + +/**Function******************************************************************** + + Synopsis [Check if the two pairs exist in the table, If any of the + conjuncts do exist, store in the cache and return the corresponding pair.] + + Description [Check if the two pairs exist in the table. If any of + the conjuncts do exist, store in the cache and return the + corresponding pair.] + + SideEffects [] + + SeeAlso [ZeroCase BuildConjuncts] + +******************************************************************************/ +static Conjuncts * +CheckInTables( + DdNode * node, + DdNode * g1, + DdNode * h1, + DdNode * g2, + DdNode * h2, + st_table * ghTable, + st_table * cacheTable, + int * outOfMem) +{ + int pairValue1, pairValue2; + Conjuncts *factors; + int value; + + *outOfMem = 0; + + /* check existence of pair in table */ + pairValue1 = PairInTables(g1, h1, ghTable); + pairValue2 = PairInTables(g2, h2, ghTable); + + /* if none of the 4 exist in the gh tables, return NULL */ + if ((pairValue1 == NONE) && (pairValue2 == NONE)) { + return NULL; + } + + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + *outOfMem = 1; + return NULL; + } + + /* pairs that already exist in the table get preference. */ + if (pairValue1 == PAIR_ST) { + factors->g = g1; + factors->h = h1; + } else if (pairValue2 == PAIR_ST) { + factors->g = g2; + factors->h = h2; + } else if (pairValue1 == PAIR_CR) { + factors->g = h1; + factors->h = g1; + } else if (pairValue2 == PAIR_CR) { + factors->g = h2; + factors->h = g2; + } else if (pairValue1 == G_ST) { + /* g exists in the table, h is not found in either table */ + factors->g = g1; + factors->h = h1; + if (h1 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == BOTH_G) { + /* g and h are found in the g table */ + factors->g = g1; + factors->h = h1; + if (h1 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == H_ST) { + /* h exists in the table, g is not found in either table */ + factors->g = g1; + factors->h = h1; + if (g1 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == BOTH_H) { + /* g and h are found in the h table */ + factors->g = g1; + factors->h = h1; + if (g1 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == G_ST) { + /* g exists in the table, h is not found in either table */ + factors->g = g2; + factors->h = h2; + if (h2 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == BOTH_G) { + /* g and h are found in the g table */ + factors->g = g2; + factors->h = h2; + if (h2 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == H_ST) { + /* h exists in the table, g is not found in either table */ + factors->g = g2; + factors->h = h2; + if (g2 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == BOTH_H) { + /* g and h are found in the h table */ + factors->g = g2; + factors->h = h2; + if (g2 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == G_CR) { + /* g found in h table and h in none */ + factors->g = h1; + factors->h = g1; + if (h1 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == H_CR) { + /* h found in g table and g in none */ + factors->g = h1; + factors->h = g1; + if (g1 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == G_CR) { + /* g found in h table and h in none */ + factors->g = h2; + factors->h = g2; + if (h2 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == H_CR) { + /* h found in g table and g in none */ + factors->g = h2; + factors->h = g2; + if (g2 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } + + /* Store factors in cache table for later use. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == + ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + return factors; +} /* end of CheckInTables */ + + + +/**Function******************************************************************** + + Synopsis [If one child is zero, do explicitly what Restrict does or better] + + Description [If one child is zero, do explicitly what Restrict does or better. + First separate a variable and its child in the base case. In case of a cube + times a function, separate the cube and function. As a last resort, look in + tables.] + + SideEffects [Frees the BDDs in factorsNv. factorsNv itself is not freed + because it is freed above.] + + SeeAlso [BuildConjuncts] + +******************************************************************************/ +static Conjuncts * +ZeroCase( + DdManager * dd, + DdNode * node, + Conjuncts * factorsNv, + st_table * ghTable, + st_table * cacheTable, + int switched) +{ + int topid; + DdNode *g, *h, *g1, *g2, *h1, *h2, *x, *N, *G, *H, *Gv, *Gnv; + DdNode *Hv, *Hnv; + int value; + int outOfMem; + Conjuncts *factors; + + /* get var at this node */ + N = Cudd_Regular(node); + topid = N->index; + x = dd->vars[topid]; + x = (switched) ? Cudd_Not(x): x; + cuddRef(x); + + /* Seprate variable and child */ + if (factorsNv->g == one) { + Cudd_RecursiveDeref(dd, factorsNv->g); + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + factors->g = x; + factors->h = factorsNv->h; + /* cache the result*/ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + FREE(factors); + return NULL; + } + + /* store x in g table, the other node is already in the table */ + if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { + value |= 1; + } else { + value = 1; + } + if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + return(factors); + } + + /* Seprate variable and child */ + if (factorsNv->h == one) { + Cudd_RecursiveDeref(dd, factorsNv->h); + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + factors->g = factorsNv->g; + factors->h = x; + /* cache the result. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + FREE(factors); + return(NULL); + } + /* store x in h table, the other node is already in the table */ + if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { + value |= 2; + } else { + value = 2; + } + if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + return(factors); + } + + G = Cudd_Regular(factorsNv->g); + Gv = cuddT(G); + Gnv = cuddE(G); + Gv = Cudd_NotCond(Gv, Cudd_IsComplement(node)); + Gnv = Cudd_NotCond(Gnv, Cudd_IsComplement(node)); + /* if the child below is a variable */ + if ((Gv == zero) || (Gnv == zero)) { + h = factorsNv->h; + g = cuddBddAndRecur(dd, x, factorsNv->g); + if (g != NULL) cuddRef(g); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + if (g == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + return NULL; + } + /* CheckTablesCacheAndReturn responsible for allocating + * factors structure., g,h referenced for cache store the + */ + factors = CheckTablesCacheAndReturn(node, + g, + h, + ghTable, + cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g); + Cudd_RecursiveDeref(dd, h); + } + return(factors); + } + + H = Cudd_Regular(factorsNv->h); + Hv = cuddT(H); + Hnv = cuddE(H); + Hv = Cudd_NotCond(Hv, Cudd_IsComplement(node)); + Hnv = Cudd_NotCond(Hnv, Cudd_IsComplement(node)); + /* if the child below is a variable */ + if ((Hv == zero) || (Hnv == zero)) { + g = factorsNv->g; + h = cuddBddAndRecur(dd, x, factorsNv->h); + if (h!= NULL) cuddRef(h); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + if (h == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + return NULL; + } + /* CheckTablesCacheAndReturn responsible for allocating + * factors structure.g,h referenced for table store + */ + factors = CheckTablesCacheAndReturn(node, + g, + h, + ghTable, + cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g); + Cudd_RecursiveDeref(dd, h); + } + return(factors); + } + + /* build g1 = x*g; h1 = h */ + /* build g2 = g; h2 = x*h */ + Cudd_RecursiveDeref(dd, x); + h1 = factorsNv->h; + g1 = cuddBddAndRecur(dd, x, factorsNv->g); + if (g1 != NULL) cuddRef(g1); + if (g1 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + return NULL; + } + + g2 = factorsNv->g; + h2 = cuddBddAndRecur(dd, x, factorsNv->h); + if (h2 != NULL) cuddRef(h2); + if (h2 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNv->g); + return NULL; + } + + /* check whether any pair is in tables */ + factors = CheckInTables(node, g1, h1, g2, h2, ghTable, cacheTable, &outOfMem); + if (outOfMem) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + return NULL; + } + if (factors != NULL) { + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + return factors; + } + + /* check for each pair in tables and choose one */ + factors = PickOnePair(node,g1, h1, g2, h2, ghTable, cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + /* now free what was created and not used */ + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + } + + return(factors); +} /* end of ZeroCase */ + + +/**Function******************************************************************** + + Synopsis [Builds the conjuncts recursively, bottom up.] + + Description [Builds the conjuncts recursively, bottom up. Constants + are returned as (f, f). The cache is checked for previously computed + result. The decomposition points are determined by the local + reference count of this node and the longest distance from the + constant. At the decomposition point, the factors returned are (f, + 1). Recur on the two children. The order is determined by the + heavier branch. Combine the factors of the two children and pick the + one that already occurs in the gh table. Occurence in g is indicated + by value 1, occurence in h by 2, occurence in both 3.] + + SideEffects [] + + SeeAlso [cuddConjunctsAux] + +******************************************************************************/ +static Conjuncts * +BuildConjuncts( + DdManager * dd, + DdNode * node, + st_table * distanceTable, + st_table * cacheTable, + int approxDistance, + int maxLocalRef, + st_table * ghTable, + st_table * mintermTable) +{ + int topid, distance; + Conjuncts *factorsNv, *factorsNnv, *factors; + Conjuncts *dummy; + DdNode *N, *Nv, *Nnv, *temp, *g1, *g2, *h1, *h2, *topv; + double minNv = 0.0, minNnv = 0.0; + double *doubleDummy; + int switched =0; + int outOfMem; + int freeNv = 0, freeNnv = 0, freeTemp; + NodeStat *nodeStat; + int value; + + /* if f is constant, return (f,f) */ + if (Cudd_IsConstant(node)) { + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + factors->g = node; + factors->h = node; + return(FactorsComplement(factors)); + } + + /* If result (a pair of conjuncts) in cache, return the factors. */ + if (st_lookup(cacheTable, node, &dummy)) { + factors = dummy; + return(factors); + } + + /* check distance and local reference count of this node */ + N = Cudd_Regular(node); + if (!st_lookup(distanceTable, N, &nodeStat)) { + (void) fprintf(dd->err, "Not in table, Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + distance = nodeStat->distance; + + /* at or below decomposition point, return (f, 1) */ + if (((nodeStat->localRef > maxLocalRef*2/3) && + (distance < approxDistance*2/3)) || + (distance <= approxDistance/4)) { + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + /* alternate assigning (f,1) */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(node), &value)) { + if (value == 3) { + if (!lastTimeG) { + factors->g = node; + factors->h = one; + lastTimeG = 1; + } else { + factors->g = one; + factors->h = node; + lastTimeG = 0; + } + } else if (value == 1) { + factors->g = node; + factors->h = one; + } else { + factors->g = one; + factors->h = node; + } + } else if (!lastTimeG) { + factors->g = node; + factors->h = one; + lastTimeG = 1; + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(factors); + return NULL; + } + } else { + factors->g = one; + factors->h = node; + lastTimeG = 0; + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(factors); + return NULL; + } + } + return(FactorsComplement(factors)); + } + + /* get the children and recur */ + Nv = cuddT(N); + Nnv = cuddE(N); + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* Choose which subproblem to solve first based on the number of + * minterms. We go first where there are more minterms. + */ + if (!Cudd_IsConstant(Nv)) { + if (!st_lookup(mintermTable, Nv, &doubleDummy)) { + (void) fprintf(dd->err, "Not in table: Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + minNv = *doubleDummy; + } + + if (!Cudd_IsConstant(Nnv)) { + if (!st_lookup(mintermTable, Nnv, &doubleDummy)) { + (void) fprintf(dd->err, "Not in table: Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + minNnv = *doubleDummy; + } + + if (minNv < minNnv) { + temp = Nv; + Nv = Nnv; + Nnv = temp; + switched = 1; + } + + /* build gt, ht recursively */ + if (Nv != zero) { + factorsNv = BuildConjuncts(dd, Nv, distanceTable, + cacheTable, approxDistance, maxLocalRef, + ghTable, mintermTable); + if (factorsNv == NULL) return(NULL); + freeNv = FactorsNotStored(factorsNv); + factorsNv = (freeNv) ? FactorsUncomplement(factorsNv) : factorsNv; + cuddRef(factorsNv->g); + cuddRef(factorsNv->h); + + /* Deal with the zero case */ + if (Nnv == zero) { + /* is responsible for freeing factorsNv */ + factors = ZeroCase(dd, node, factorsNv, ghTable, + cacheTable, switched); + if (freeNv) FREE(factorsNv); + return(factors); + } + } + + /* build ge, he recursively */ + if (Nnv != zero) { + factorsNnv = BuildConjuncts(dd, Nnv, distanceTable, + cacheTable, approxDistance, maxLocalRef, + ghTable, mintermTable); + if (factorsNnv == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + if (freeNv) FREE(factorsNv); + return(NULL); + } + freeNnv = FactorsNotStored(factorsNnv); + factorsNnv = (freeNnv) ? FactorsUncomplement(factorsNnv) : factorsNnv; + cuddRef(factorsNnv->g); + cuddRef(factorsNnv->h); + + /* Deal with the zero case */ + if (Nv == zero) { + /* is responsible for freeing factorsNv */ + factors = ZeroCase(dd, node, factorsNnv, ghTable, + cacheTable, switched); + if (freeNnv) FREE(factorsNnv); + return(factors); + } + } + + /* construct the 2 pairs */ + /* g1 = x*gt + x'*ge; h1 = x*ht + x'*he; */ + /* g2 = x*gt + x'*he; h2 = x*ht + x'*ge */ + if (switched) { + factors = factorsNnv; + factorsNnv = factorsNv; + factorsNv = factors; + freeTemp = freeNv; + freeNv = freeNnv; + freeNnv = freeTemp; + } + + /* Build the factors for this node. */ + topid = N->index; + topv = dd->vars[topid]; + + g1 = cuddBddIteRecur(dd, topv, factorsNv->g, factorsNnv->g); + if (g1 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + + cuddRef(g1); + + h1 = cuddBddIteRecur(dd, topv, factorsNv->h, factorsNnv->h); + if (h1 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + + cuddRef(h1); + + g2 = cuddBddIteRecur(dd, topv, factorsNv->g, factorsNnv->h); + if (g2 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + cuddRef(g2); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + + h2 = cuddBddIteRecur(dd, topv, factorsNv->h, factorsNnv->g); + if (h2 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + cuddRef(h2); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + + /* check for each pair in tables and choose one */ + factors = CheckInTables(node, g1, h1, g2, h2, ghTable, cacheTable, &outOfMem); + if (outOfMem) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + return(NULL); + } + if (factors != NULL) { + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + return(factors); + } + + /* if not in tables, pick one pair */ + factors = PickOnePair(node,g1, h1, g2, h2, ghTable, cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + /* now free what was created and not used */ + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + } + + return(factors); + +} /* end of BuildConjuncts */ + + +/**Function******************************************************************** + + Synopsis [Procedure to compute two conjunctive factors of f and place in *c1 and *c2.] + + Description [Procedure to compute two conjunctive factors of f and + place in *c1 and *c2. Sets up the required data - table of distances + from the constant and local reference count. Also minterm table. ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +static int +cuddConjunctsAux( + DdManager * dd, + DdNode * f, + DdNode ** c1, + DdNode ** c2) +{ + st_table *distanceTable = NULL; + st_table *cacheTable = NULL; + st_table *mintermTable = NULL; + st_table *ghTable = NULL; + st_generator *stGen; + char *key, *value; + Conjuncts *factors; + int distance, approxDistance; + double max, minterms; + int freeFactors; + NodeStat *nodeStat; + int maxLocalRef; + + /* initialize */ + *c1 = NULL; + *c2 = NULL; + + /* initialize distances table */ + distanceTable = st_init_table(st_ptrcmp,st_ptrhash); + if (distanceTable == NULL) goto outOfMem; + + /* make the entry for the constant */ + nodeStat = ALLOC(NodeStat, 1); + if (nodeStat == NULL) goto outOfMem; + nodeStat->distance = 0; + nodeStat->localRef = 1; + if (st_insert(distanceTable, (char *)one, (char *)nodeStat) == ST_OUT_OF_MEM) { + goto outOfMem; + } + + /* Count node distances from constant. */ + nodeStat = CreateBotDist(f, distanceTable); + if (nodeStat == NULL) goto outOfMem; + + /* set the distance for the decomposition points */ + approxDistance = (DEPTH < nodeStat->distance) ? nodeStat->distance : DEPTH; + distance = nodeStat->distance; + + if (distance < approxDistance) { + /* Too small to bother. */ + *c1 = f; + *c2 = DD_ONE(dd); + cuddRef(*c1); cuddRef(*c2); + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); + return(1); + } + + /* record the maximum local reference count */ + maxLocalRef = 0; + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + nodeStat = (NodeStat *)value; + maxLocalRef = (nodeStat->localRef > maxLocalRef) ? + nodeStat->localRef : maxLocalRef; + } + st_free_gen(stGen); stGen = NULL; + + + /* Count minterms for each node. */ + max = pow(2.0, (double)Cudd_SupportSize(dd,f)); /* potential overflow */ + mintermTable = st_init_table(st_ptrcmp,st_ptrhash); + if (mintermTable == NULL) goto outOfMem; + minterms = CountMinterms(f, max, mintermTable, dd->err); + if (minterms == -1.0) goto outOfMem; + + lastTimeG = Cudd_Random() & 1; + cacheTable = st_init_table(st_ptrcmp, st_ptrhash); + if (cacheTable == NULL) goto outOfMem; + ghTable = st_init_table(st_ptrcmp, st_ptrhash); + if (ghTable == NULL) goto outOfMem; + + /* Build conjuncts. */ + factors = BuildConjuncts(dd, f, distanceTable, cacheTable, + approxDistance, maxLocalRef, ghTable, mintermTable); + if (factors == NULL) goto outOfMem; + + /* free up tables */ + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); distanceTable = NULL; + st_free_table(ghTable); ghTable = NULL; + + stGen = st_init_gen(mintermTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(mintermTable); mintermTable = NULL; + + freeFactors = FactorsNotStored(factors); + factors = (freeFactors) ? FactorsUncomplement(factors) : factors; + if (factors != NULL) { + *c1 = factors->g; + *c2 = factors->h; + cuddRef(*c1); + cuddRef(*c2); + if (freeFactors) FREE(factors); + +#if 0 + if ((*c1 == f) && (!Cudd_IsConstant(f))) { + assert(*c2 == one); + } + if ((*c2 == f) && (!Cudd_IsConstant(f))) { + assert(*c1 == one); + } + + if ((*c1 != one) && (!Cudd_IsConstant(f))) { + assert(!Cudd_bddLeq(dd, *c2, *c1)); + } + if ((*c2 != one) && (!Cudd_IsConstant(f))) { + assert(!Cudd_bddLeq(dd, *c1, *c2)); + } +#endif + } + + stGen = st_init_gen(cacheTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + ConjunctsFree(dd, (Conjuncts *)value); + } + st_free_gen(stGen); stGen = NULL; + + st_free_table(cacheTable); cacheTable = NULL; + + return(1); + +outOfMem: + if (distanceTable != NULL) { + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); distanceTable = NULL; + } + if (mintermTable != NULL) { + stGen = st_init_gen(mintermTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(mintermTable); mintermTable = NULL; + } + if (ghTable != NULL) st_free_table(ghTable); + if (cacheTable != NULL) { + stGen = st_init_gen(cacheTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + ConjunctsFree(dd, (Conjuncts *)value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(cacheTable); cacheTable = NULL; + } + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + +} /* end of cuddConjunctsAux */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddEssent.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddEssent.c new file mode 100644 index 000000000..7af6df651 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddEssent.c @@ -0,0 +1,1467 @@ +/**CFile*********************************************************************** + + FileName [cuddEssent.c] + + PackageName [cudd] + + Synopsis [Functions for the detection of essential variables.] + + Description [External procedures included in this file: +
                    +
                  • Cudd_FindEssential() +
                  • Cudd_bddIsVarEssential() +
                  • Cudd_FindTwoLiteralClauses() +
                  • Cudd_ReadIthClause() +
                  • Cudd_PrintTwoLiteralClauses() +
                  • Cudd_tlcInfoFree() +
                  + Static procedures included in this module: +
                    +
                  • ddFindEssentialRecur() +
                  • ddFindTwoLiteralClausesRecur() +
                  • computeClauses() +
                  • computeClausesWithUniverse() +
                  • emptyClauseSet() +
                  • sentinelp() +
                  • equalp() +
                  • beforep() +
                  • oneliteralp() +
                  • impliedp() +
                  • bitVectorAlloc() +
                  • bitVectorClear() +
                  • bitVectorFree() +
                  • bitVectorRead() +
                  • bitVectorSet() +
                  • tlcInfoAlloc() +
                  ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* These definitions are for the bit vectors. */ +#if SIZEOF_LONG == 8 +#define BPL 64 +#define LOGBPL 6 +#else +#define BPL 32 +#define LOGBPL 5 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/* This structure holds the set of clauses for a node. Each clause consists +** of two literals. For one-literal clauses, the second lietral is FALSE. +** Each literal is composed of a variable and a phase. A variable is a node +** index, and requires sizeof(DdHalfWord) bytes. The constant literals use +** CUDD_MAXINDEX as variable indicator. Each phase is a bit: 0 for positive +** phase, and 1 for negative phase. +** Variables and phases are stored separately for the sake of compactness. +** The variables are stored in an array of DdHalfWord's terminated by a +** sentinel (a pair of zeroes). The phases are stored in a bit vector. +** The cnt field holds, at the end, the number of clauses. +** The clauses of the set are kept sorted. For each clause, the first literal +** is the one of least index. So, the clause with literals +2 and -4 is stored +** as (+2,-4). A one-literal clause with literal +3 is stored as +** (+3,-CUDD_MAXINDEX). Clauses are sorted in decreasing order as follows: +** (+5,-7) +** (+5,+6) +** (-5,+7) +** (-4,FALSE) +** (-4,+8) +** ... +** That is, one first looks at the variable of the first literal, then at the +** phase of the first litral, then at the variable of the second literal, +** and finally at the phase of the second literal. +*/ +struct DdTlcInfo { + DdHalfWord *vars; + long *phases; + DdHalfWord cnt; +}; + +/* This structure is for temporary representation of sets of clauses. It is +** meant to be used in link lists, when the number of clauses is not yet +** known. The encoding of a clause is the same as in DdTlcInfo, though +** the phase information is not stored in a bit array. */ +struct TlClause { + DdHalfWord v1, v2; + short p1, p2; + struct TlClause *next; +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef long BitVector; +typedef struct TlClause TlClause; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddEssent.c,v 1.25 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static BitVector *Tolv; +static BitVector *Tolp; +static BitVector *Eolv; +static BitVector *Eolp; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * ddFindEssentialRecur (DdManager *dd, DdNode *f); +static DdTlcInfo * ddFindTwoLiteralClausesRecur (DdManager * dd, DdNode * f, st_table *table); +static DdTlcInfo * computeClauses (DdTlcInfo *Tres, DdTlcInfo *Eres, DdHalfWord label, int size); +static DdTlcInfo * computeClausesWithUniverse (DdTlcInfo *Cres, DdHalfWord label, short phase); +static DdTlcInfo * emptyClauseSet (void); +static int sentinelp (DdHalfWord var1, DdHalfWord var2); +static int equalp (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b); +static int beforep (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b); +static int oneliteralp (DdHalfWord var); +static int impliedp (DdHalfWord var1, short phase1, DdHalfWord var2, short phase2, BitVector *olv, BitVector *olp); +static BitVector * bitVectorAlloc (int size); +DD_INLINE static void bitVectorClear (BitVector *vector, int size); +static void bitVectorFree (BitVector *vector); +DD_INLINE static short bitVectorRead (BitVector *vector, int i); +DD_INLINE static void bitVectorSet (BitVector * vector, int i, short val); +static DdTlcInfo * tlcInfoAlloc (void); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Finds the essential variables of a DD.] + + Description [Returns the cube of the essential variables. A positive + literal means that the variable must be set to 1 for the function to be + 1. A negative literal means that the variable must be set to 0 for the + function to be 1. Returns a pointer to the cube BDD if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddIsVarEssential] + +******************************************************************************/ +DdNode * +Cudd_FindEssential( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = ddFindEssentialRecur(dd,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_FindEssential */ + + +/**Function******************************************************************** + + Synopsis [Determines whether a given variable is essential with a + given phase in a BDD.] + + Description [Determines whether a given variable is essential with a + given phase in a BDD. Uses Cudd_bddIteConstant. Returns 1 if phase == 1 + and f-->x_id, or if phase == 0 and f-->x_id'.] + + SideEffects [None] + + SeeAlso [Cudd_FindEssential] + +******************************************************************************/ +int +Cudd_bddIsVarEssential( + DdManager * manager, + DdNode * f, + int id, + int phase) +{ + DdNode *var; + int res; + + var = Cudd_bddIthVar(manager, id); + + var = Cudd_NotCond(var,phase == 0); + + res = Cudd_bddLeq(manager, f, var); + + return(res); + +} /* end of Cudd_bddIsVarEssential */ + + +/**Function******************************************************************** + + Synopsis [Finds the two literal clauses of a DD.] + + Description [Returns the one- and two-literal clauses of a DD. + Returns a pointer to the structure holding the clauses if + successful; NULL otherwise. For a constant DD, the empty set of clauses + is returned. This is obviously correct for a non-zero constant. For the + constant zero, it is based on the assumption that only those clauses + containing variables in the support of the function are considered. Since + the support of a constant function is empty, no clauses are returned.] + + SideEffects [None] + + SeeAlso [Cudd_FindEssential] + +******************************************************************************/ +DdTlcInfo * +Cudd_FindTwoLiteralClauses( + DdManager * dd, + DdNode * f) +{ + DdTlcInfo *res; + st_table *table; + st_generator *gen; + DdTlcInfo *tlc; + DdNode *node; + int size = dd->size; + + if (Cudd_IsConstant(f)) { + res = emptyClauseSet(); + return(res); + } + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) return(NULL); + Tolv = bitVectorAlloc(size); + if (Tolv == NULL) { + st_free_table(table); + return(NULL); + } + Tolp = bitVectorAlloc(size); + if (Tolp == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + return(NULL); + } + Eolv = bitVectorAlloc(size); + if (Eolv == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + return(NULL); + } + Eolp = bitVectorAlloc(size); + if (Eolp == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + bitVectorFree(Eolv); + return(NULL); + } + + res = ddFindTwoLiteralClausesRecur(dd,f,table); + /* Dispose of table contents and free table. */ + st_foreach_item(table, gen, &node, &tlc) { + if (node != f) { + Cudd_tlcInfoFree(tlc); + } + } + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + bitVectorFree(Eolv); + bitVectorFree(Eolp); + + if (res != NULL) { + int i; + for (i = 0; !sentinelp(res->vars[i], res->vars[i+1]); i += 2); + res->cnt = i >> 1; + } + + return(res); + +} /* end of Cudd_FindTwoLiteralClauses */ + + +/**Function******************************************************************** + + Synopsis [Accesses the i-th clause of a DD.] + + Description [Accesses the i-th clause of a DD given the clause set which + must be already computed. Returns 1 if successful; 0 if i is out of range, + or in case of error.] + + SideEffects [the four components of a clause are returned as side effects.] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +int +Cudd_ReadIthClause( + DdTlcInfo * tlc, + int i, + DdHalfWord *var1, + DdHalfWord *var2, + int *phase1, + int *phase2) +{ + if (tlc == NULL) return(0); + if (tlc->vars == NULL || tlc->phases == NULL) return(0); + if (i < 0 || (unsigned) i >= tlc->cnt) return(0); + *var1 = tlc->vars[2*i]; + *var2 = tlc->vars[2*i+1]; + *phase1 = (int) bitVectorRead(tlc->phases, 2*i); + *phase2 = (int) bitVectorRead(tlc->phases, 2*i+1); + return(1); + +} /* end of Cudd_ReadIthClause */ + + +/**Function******************************************************************** + + Synopsis [Prints the two literal clauses of a DD.] + + Description [Prints the one- and two-literal clauses. Returns 1 if + successful; 0 otherwise. The argument "names" can be NULL, in which case + the variable indices are printed.] + + SideEffects [None] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +int +Cudd_PrintTwoLiteralClauses( + DdManager * dd, + DdNode * f, + char **names, + FILE *fp) +{ + DdHalfWord *vars; + BitVector *phases; + int i; + DdTlcInfo *res = Cudd_FindTwoLiteralClauses(dd, f); + FILE *ifp = fp == NULL ? dd->out : fp; + + if (res == NULL) return(0); + vars = res->vars; + phases = res->phases; + for (i = 0; !sentinelp(vars[i], vars[i+1]); i += 2) { + if (names != NULL) { + if (vars[i+1] == CUDD_MAXINDEX) { + (void) fprintf(ifp, "%s%s\n", + bitVectorRead(phases, i) ? "~" : " ", + names[vars[i]]); + } else { + (void) fprintf(ifp, "%s%s | %s%s\n", + bitVectorRead(phases, i) ? "~" : " ", + names[vars[i]], + bitVectorRead(phases, i+1) ? "~" : " ", + names[vars[i+1]]); + } + } else { + if (vars[i+1] == CUDD_MAXINDEX) { + (void) fprintf(ifp, "%s%d\n", + bitVectorRead(phases, i) ? "~" : " ", + (int) vars[i]); + } else { + (void) fprintf(ifp, "%s%d | %s%d\n", + bitVectorRead(phases, i) ? "~" : " ", + (int) vars[i], + bitVectorRead(phases, i+1) ? "~" : " ", + (int) vars[i+1]); + } + } + } + Cudd_tlcInfoFree(res); + + return(1); + +} /* end of Cudd_PrintTwoLiteralClauses */ + + +/**Function******************************************************************** + + Synopsis [Frees a DdTlcInfo Structure.] + + Description [Frees a DdTlcInfo Structure as well as the memory pointed + by it.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_tlcInfoFree( + DdTlcInfo * t) +{ + if (t->vars != NULL) FREE(t->vars); + if (t->phases != NULL) FREE(t->phases); + FREE(t); + +} /* end of Cudd_tlcInfoFree */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_FindEssential.] + + Description [Implements the recursive step of Cudd_FindEssential. + Returns a pointer to the cube BDD if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +ddFindEssentialRecur( + DdManager * dd, + DdNode * f) +{ + DdNode *T, *E, *F; + DdNode *essT, *essE, *res; + int index; + DdNode *one, *lzero, *azero; + + one = DD_ONE(dd); + F = Cudd_Regular(f); + /* If f is constant the set of essential variables is empty. */ + if (cuddIsConstant(F)) return(one); + + res = cuddCacheLookup1(dd,Cudd_FindEssential,f); + if (res != NULL) { + return(res); + } + + lzero = Cudd_Not(one); + azero = DD_ZERO(dd); + /* Find cofactors: here f is non-constant. */ + T = cuddT(F); + E = cuddE(F); + if (Cudd_IsComplement(f)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + + index = F->index; + if (Cudd_IsConstant(T) && T != lzero && T != azero) { + /* if E is zero, index is essential, otherwise there are no + ** essentials, because index is not essential and no other variable + ** can be, since setting index = 1 makes the function constant and + ** different from 0. + */ + if (E == lzero || E == azero) { + res = dd->vars[index]; + } else { + res = one; + } + } else if (T == lzero || T == azero) { + if (Cudd_IsConstant(E)) { /* E cannot be zero here */ + res = Cudd_Not(dd->vars[index]); + } else { /* E == non-constant */ + /* find essentials in the else branch */ + essE = ddFindEssentialRecur(dd,E); + if (essE == NULL) { + return(NULL); + } + cuddRef(essE); + + /* add index to the set with negative phase */ + res = cuddUniqueInter(dd,index,one,Cudd_Not(essE)); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essE); + return(NULL); + } + res = Cudd_Not(res); + cuddDeref(essE); + } + } else { /* T == non-const */ + if (E == lzero || E == azero) { + /* find essentials in the then branch */ + essT = ddFindEssentialRecur(dd,T); + if (essT == NULL) { + return(NULL); + } + cuddRef(essT); + + /* add index to the set with positive phase */ + /* use And because essT may be complemented */ + res = cuddBddAndRecur(dd,dd->vars[index],essT); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essT); + return(NULL); + } + cuddDeref(essT); + } else if (!Cudd_IsConstant(E)) { + /* if E is a non-zero constant there are no essentials + ** because T is non-constant. + */ + essT = ddFindEssentialRecur(dd,T); + if (essT == NULL) { + return(NULL); + } + if (essT == one) { + res = one; + } else { + cuddRef(essT); + essE = ddFindEssentialRecur(dd,E); + if (essE == NULL) { + Cudd_RecursiveDeref(dd,essT); + return(NULL); + } + cuddRef(essE); + + /* res = intersection(essT, essE) */ + res = cuddBddLiteralSetIntersectionRecur(dd,essT,essE); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essT); + Cudd_RecursiveDeref(dd,essE); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,essT); + Cudd_RecursiveDeref(dd,essE); + cuddDeref(res); + } + } else { /* E is a non-zero constant */ + res = one; + } + } + + cuddCacheInsert1(dd,Cudd_FindEssential, f, res); + return(res); + +} /* end of ddFindEssentialRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_FindTwoLiteralClauses.] + + Description [Implements the recursive step of + Cudd_FindTwoLiteralClauses. The DD node is assumed to be not + constant. Returns a pointer to a set of clauses if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +static DdTlcInfo * +ddFindTwoLiteralClausesRecur( + DdManager * dd, + DdNode * f, + st_table *table) +{ + DdNode *T, *E, *F; + DdNode *one, *lzero, *azero; + DdTlcInfo *res, *Tres, *Eres; + DdHalfWord index; + + F = Cudd_Regular(f); + + assert(!cuddIsConstant(F)); + + /* Check computed table. Separate entries are necessary for + ** a node and its complement. We should update the counter here. */ + if (st_lookup(table, f, &res)) { + return(res); + } + + /* Easy access to the constants for BDDs and ADDs. */ + one = DD_ONE(dd); + lzero = Cudd_Not(one); + azero = DD_ZERO(dd); + + /* Find cofactors and variable labeling the top node. */ + T = cuddT(F); E = cuddE(F); + if (Cudd_IsComplement(f)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + index = F->index; + + if (Cudd_IsConstant(T) && T != lzero && T != azero) { + /* T is a non-zero constant. If E is zero, then this node's index + ** is a one-literal clause. Otherwise, if E is a non-zero + ** constant, there are no clauses for this node. Finally, + ** if E is not constant, we recursively compute its clauses, and then + ** merge using the empty set for T. */ + if (E == lzero || E == azero) { + /* Create the clause (index + 0). */ + res = tlcInfoAlloc(); + if (res == NULL) return(NULL); + res->vars = ALLOC(DdHalfWord,4); + if (res->vars == NULL) { + FREE(res); + return(NULL); + } + res->phases = bitVectorAlloc(2); + if (res->phases == NULL) { + FREE(res->vars); + FREE(res); + return(NULL); + } + res->vars[0] = index; + res->vars[1] = CUDD_MAXINDEX; + res->vars[2] = 0; + res->vars[3] = 0; + bitVectorSet(res->phases, 0, 0); /* positive phase */ + bitVectorSet(res->phases, 1, 1); /* negative phase */ + } else if (Cudd_IsConstant(E)) { + /* If E is a non-zero constant, no clauses. */ + res = emptyClauseSet(); + } else { + /* E is non-constant */ + Tres = emptyClauseSet(); + if (Tres == NULL) return(NULL); + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) { + Cudd_tlcInfoFree(Tres); + return(NULL); + } + res = computeClauses(Tres, Eres, index, dd->size); + Cudd_tlcInfoFree(Tres); + } + } else if (T == lzero || T == azero) { + /* T is zero. If E is a non-zero constant, then the + ** complement of this node's index is a one-literal clause. + ** Otherwise, if E is not constant, we recursively compute its + ** clauses, and then merge using the universal set for T. */ + if (Cudd_IsConstant(E)) { /* E cannot be zero here */ + /* Create the clause (!index + 0). */ + res = tlcInfoAlloc(); + if (res == NULL) return(NULL); + res->vars = ALLOC(DdHalfWord,4); + if (res->vars == NULL) { + FREE(res); + return(NULL); + } + res->phases = bitVectorAlloc(2); + if (res->phases == NULL) { + FREE(res->vars); + FREE(res); + return(NULL); + } + res->vars[0] = index; + res->vars[1] = CUDD_MAXINDEX; + res->vars[2] = 0; + res->vars[3] = 0; + bitVectorSet(res->phases, 0, 1); /* negative phase */ + bitVectorSet(res->phases, 1, 1); /* negative phase */ + } else { /* E == non-constant */ + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) return(NULL); + res = computeClausesWithUniverse(Eres, index, 1); + } + } else { /* T == non-const */ + Tres = ddFindTwoLiteralClausesRecur(dd, T, table); + if (Tres == NULL) return(NULL); + if (Cudd_IsConstant(E)) { + if (E == lzero || E == azero) { + res = computeClausesWithUniverse(Tres, index, 0); + } else { + Eres = emptyClauseSet(); + if (Eres == NULL) return(NULL); + res = computeClauses(Tres, Eres, index, dd->size); + Cudd_tlcInfoFree(Eres); + } + } else { + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) return(NULL); + res = computeClauses(Tres, Eres, index, dd->size); + } + } + + /* Cache results. */ + if (st_add_direct(table, (char *)f, (char *)res) == ST_OUT_OF_MEM) { + FREE(res); + return(NULL); + } + return(res); + +} /* end of ddFindTwoLiteralClausesRecur */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-literal clauses for a node.] + + Description [Computes the two-literal clauses for a node given the + clauses for its children and the label of the node. Returns a + pointer to a TclInfo structure if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [computeClausesWithUniverse] + +******************************************************************************/ +static DdTlcInfo * +computeClauses( + DdTlcInfo *Tres /* list of clauses for T child */, + DdTlcInfo *Eres /* list of clauses for E child */, + DdHalfWord label /* variable labeling the current node */, + int size /* number of variables in the manager */) +{ + DdHalfWord *Tcv = Tres->vars; /* variables of clauses for the T child */ + BitVector *Tcp = Tres->phases; /* phases of clauses for the T child */ + DdHalfWord *Ecv = Eres->vars; /* variables of clauses for the E child */ + BitVector *Ecp = Eres->phases; /* phases of clauses for the E child */ + DdHalfWord *Vcv = NULL; /* pointer to variables of the clauses for v */ + BitVector *Vcp = NULL; /* pointer to phases of the clauses for v */ + DdTlcInfo *res = NULL; /* the set of clauses to be returned */ + int pt = 0; /* index in the list of clauses of T */ + int pe = 0; /* index in the list of clauses of E */ + int cv = 0; /* counter of the clauses for this node */ + TlClause *iclauses = NULL; /* list of inherited clauses */ + TlClause *tclauses = NULL; /* list of 1-literal clauses of T */ + TlClause *eclauses = NULL; /* list of 1-literal clauses of E */ + TlClause *nclauses = NULL; /* list of new (non-inherited) clauses */ + TlClause *lnclause = NULL; /* pointer to last new clause */ + TlClause *newclause; /* temporary pointer to new clauses */ + + /* Initialize sets of one-literal clauses. The one-literal clauses + ** are stored redundantly. These sets allow constant-time lookup, which + ** we need when we check for implication of a two-literal clause by a + ** one-literal clause. The linked lists allow fast sequential + ** processing. */ + bitVectorClear(Tolv, size); + bitVectorClear(Tolp, size); + bitVectorClear(Eolv, size); + bitVectorClear(Eolp, size); + + /* Initialize result structure. */ + res = tlcInfoAlloc(); + if (res == NULL) goto cleanup; + + /* Scan the two input list. Extract inherited two-literal clauses + ** and set aside one-literal clauses from each list. The incoming lists + ** are sorted in the order defined by beforep. The three linked list + ** produced by this loop are sorted in the reverse order because we + ** always append to the front of the lists. + ** The inherited clauses are those clauses (both one- and two-literal) + ** that are common to both children; and the two-literal clauses of + ** one child that are implied by a one-literal clause of the other + ** child. */ + while (!sentinelp(Tcv[pt], Tcv[pt+1]) || !sentinelp(Ecv[pe], Ecv[pe+1])) { + if (equalp(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1))) { + /* Add clause to inherited list. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = Tcv[pt+1]; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = bitVectorRead(Tcp, pt+1); + newclause->next = iclauses; + iclauses = newclause; + pt += 2; pe += 2; cv++; + } else if (beforep(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1))) { + if (oneliteralp(Tcv[pt+1])) { + /* Add this one-literal clause to the T set. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = 1; + newclause->next = tclauses; + tclauses = newclause; + bitVectorSet(Tolv, Tcv[pt], 1); + bitVectorSet(Tolp, Tcv[pt], bitVectorRead(Tcp, pt)); + } else { + if (impliedp(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Eolv, Eolp)) { + /* Add clause to inherited list. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = Tcv[pt+1]; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = bitVectorRead(Tcp, pt+1); + newclause->next = iclauses; + iclauses = newclause; + cv++; + } + } + pt += 2; + } else { /* !beforep() */ + if (oneliteralp(Ecv[pe+1])) { + /* Add this one-literal clause to the E set. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Ecv[pe]; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = bitVectorRead(Ecp, pe); + newclause->p2 = 1; + newclause->next = eclauses; + eclauses = newclause; + bitVectorSet(Eolv, Ecv[pe], 1); + bitVectorSet(Eolp, Ecv[pe], bitVectorRead(Ecp, pe)); + } else { + if (impliedp(Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1), + Tolv, Tolp)) { + /* Add clause to inherited list. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Ecv[pe]; + newclause->v2 = Ecv[pe+1]; + newclause->p1 = bitVectorRead(Ecp, pe); + newclause->p2 = bitVectorRead(Ecp, pe+1); + newclause->next = iclauses; + iclauses = newclause; + cv++; + } + } + pe += 2; + } + } + + /* Add one-literal clauses for the label variable to the front of + ** the two lists. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = label; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = 0; + newclause->p2 = 1; + newclause->next = tclauses; + tclauses = newclause; + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = label; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = 1; + newclause->p2 = 1; + newclause->next = eclauses; + eclauses = newclause; + + /* Produce the non-inherited clauses. We preserve the "reverse" + ** order of the two input lists by appending to the end of the + ** list. In this way, iclauses and nclauses are consistent. */ + while (tclauses != NULL && eclauses != NULL) { + if (beforep(eclauses->v1, eclauses->p1, eclauses->v2, eclauses->p2, + tclauses->v1, tclauses->p1, tclauses->v2, tclauses->p2)) { + TlClause *nextclause = tclauses->next; + TlClause *otherclauses = eclauses; + while (otherclauses != NULL) { + if (tclauses->v1 != otherclauses->v1) { + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = tclauses->v1; + newclause->v2 = otherclauses->v1; + newclause->p1 = tclauses->p1; + newclause->p2 = otherclauses->p1; + newclause->next = NULL; + if (nclauses == NULL) { + nclauses = newclause; + lnclause = newclause; + } else { + lnclause->next = newclause; + lnclause = newclause; + } + cv++; + } + otherclauses = otherclauses->next; + } + FREE(tclauses); + tclauses = nextclause; + } else { + TlClause *nextclause = eclauses->next; + TlClause *otherclauses = tclauses; + while (otherclauses != NULL) { + if (eclauses->v1 != otherclauses->v1) { + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = eclauses->v1; + newclause->v2 = otherclauses->v1; + newclause->p1 = eclauses->p1; + newclause->p2 = otherclauses->p1; + newclause->next = NULL; + if (nclauses == NULL) { + nclauses = newclause; + lnclause = newclause; + } else { + lnclause->next = newclause; + lnclause = newclause; + } + cv++; + } + otherclauses = otherclauses->next; + } + FREE(eclauses); + eclauses = nextclause; + } + } + while (tclauses != NULL) { + TlClause *nextclause = tclauses->next; + FREE(tclauses); + tclauses = nextclause; + } + while (eclauses != NULL) { + TlClause *nextclause = eclauses->next; + FREE(eclauses); + eclauses = nextclause; + } + + /* Merge inherited and non-inherited clauses. Now that we know the + ** total number, we allocate the arrays, and we fill them bottom-up + ** to restore the proper ordering. */ + Vcv = ALLOC(DdHalfWord, 2*(cv+1)); + if (Vcv == NULL) goto cleanup; + if (cv > 0) { + Vcp = bitVectorAlloc(2*cv); + if (Vcp == NULL) goto cleanup; + } else { + Vcp = NULL; + } + res->vars = Vcv; + res->phases = Vcp; + /* Add sentinel. */ + Vcv[2*cv] = 0; + Vcv[2*cv+1] = 0; + while (iclauses != NULL || nclauses != NULL) { + TlClause *nextclause; + cv--; + if (nclauses == NULL || (iclauses != NULL && + beforep(nclauses->v1, nclauses->p1, nclauses->v2, nclauses->p2, + iclauses->v1, iclauses->p1, iclauses->v2, iclauses->p2))) { + Vcv[2*cv] = iclauses->v1; + Vcv[2*cv+1] = iclauses->v2; + bitVectorSet(Vcp, 2*cv, iclauses->p1); + bitVectorSet(Vcp, 2*cv+1, iclauses->p2); + nextclause = iclauses->next; + FREE(iclauses); + iclauses = nextclause; + } else { + Vcv[2*cv] = nclauses->v1; + Vcv[2*cv+1] = nclauses->v2; + bitVectorSet(Vcp, 2*cv, nclauses->p1); + bitVectorSet(Vcp, 2*cv+1, nclauses->p2); + nextclause = nclauses->next; + FREE(nclauses); + nclauses = nextclause; + } + } + assert(cv == 0); + + return(res); + + cleanup: + if (res != NULL) Cudd_tlcInfoFree(res); + while (iclauses != NULL) { + TlClause *nextclause = iclauses->next; + FREE(iclauses); + iclauses = nextclause; + } + while (nclauses != NULL) { + TlClause *nextclause = nclauses->next; + FREE(nclauses); + nclauses = nextclause; + } + while (tclauses != NULL) { + TlClause *nextclause = tclauses->next; + FREE(tclauses); + tclauses = nextclause; + } + while (eclauses != NULL) { + TlClause *nextclause = eclauses->next; + FREE(eclauses); + eclauses = nextclause; + } + + return(NULL); + +} /* end of computeClauses */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-literal clauses for a node.] + + Description [Computes the two-literal clauses for a node with a zero + child, given the clauses for its other child and the label of the + node. Returns a pointer to a TclInfo structure if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [computeClauses] + +******************************************************************************/ +static DdTlcInfo * +computeClausesWithUniverse( + DdTlcInfo *Cres /* list of clauses for child */, + DdHalfWord label /* variable labeling the current node */, + short phase /* 0 if E child is zero; 1 if T child is zero */) +{ + DdHalfWord *Ccv = Cres->vars; /* variables of clauses for child */ + BitVector *Ccp = Cres->phases; /* phases of clauses for child */ + DdHalfWord *Vcv = NULL; /* pointer to the variables of the clauses for v */ + BitVector *Vcp = NULL; /* pointer to the phases of the clauses for v */ + DdTlcInfo *res = NULL; /* the set of clauses to be returned */ + int i; + + /* Initialize result. */ + res = tlcInfoAlloc(); + if (res == NULL) goto cleanup; + /* Count entries for new list and allocate accordingly. */ + for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2); + /* At this point, i is twice the number of clauses in the child's + ** list. We need four more entries for this node: 2 for the one-literal + ** clause for the label, and 2 for the sentinel. */ + Vcv = ALLOC(DdHalfWord,i+4); + if (Vcv == NULL) goto cleanup; + Vcp = bitVectorAlloc(i+4); + if (Vcp == NULL) goto cleanup; + res->vars = Vcv; + res->phases = Vcp; + /* Copy old list into new. */ + for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2) { + Vcv[i] = Ccv[i]; + Vcv[i+1] = Ccv[i+1]; + bitVectorSet(Vcp, i, bitVectorRead(Ccp, i)); + bitVectorSet(Vcp, i+1, bitVectorRead(Ccp, i+1)); + } + /* Add clause corresponding to label. */ + Vcv[i] = label; + bitVectorSet(Vcp, i, phase); + i++; + Vcv[i] = CUDD_MAXINDEX; + bitVectorSet(Vcp, i, 1); + i++; + /* Add sentinel. */ + Vcv[i] = 0; + Vcv[i+1] = 0; + bitVectorSet(Vcp, i, 0); + bitVectorSet(Vcp, i+1, 0); + + return(res); + + cleanup: + /* Vcp is guaranteed to be NULL here. Hence, we do not try to free it. */ + if (Vcv != NULL) FREE(Vcv); + if (res != NULL) Cudd_tlcInfoFree(res); + + return(NULL); + +} /* end of computeClausesWithUniverse */ + + +/**Function******************************************************************** + + Synopsis [Returns an enpty set of clauses.] + + Description [Returns a pointer to an empty set of clauses if + successful; NULL otherwise. No bit vector for the phases is + allocated.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdTlcInfo * +emptyClauseSet(void) +{ + DdTlcInfo *eset; + + eset = ALLOC(DdTlcInfo,1); + if (eset == NULL) return(NULL); + eset->vars = ALLOC(DdHalfWord,2); + if (eset->vars == NULL) { + FREE(eset); + return(NULL); + } + /* Sentinel */ + eset->vars[0] = 0; + eset->vars[1] = 0; + eset->phases = NULL; /* does not matter */ + eset->cnt = 0; + return(eset); + +} /* end of emptyClauseSet */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the argument is the sentinel clause.] + + Description [Returns true iff the argument is the sentinel clause. + A sentinel clause has both variables equal to 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +sentinelp( + DdHalfWord var1, + DdHalfWord var2) +{ + return(var1 == 0 && var2 == 0); + +} /* end of sentinelp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the two arguments are identical clauses.] + + Description [Returns true iff the two arguments are identical + clauses. Since literals are sorted, we only need to compare + literals in the same position.] + + SideEffects [None] + + SeeAlso [beforep] + +******************************************************************************/ +static int +equalp( + DdHalfWord var1a, + short phase1a, + DdHalfWord var1b, + short phase1b, + DdHalfWord var2a, + short phase2a, + DdHalfWord var2b, + short phase2b) +{ + return(var1a == var2a && phase1a == phase2a && + var1b == var2b && phase1b == phase2b); + +} /* end of equalp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the first argument precedes the second in + the clause order.] + + Description [Returns true iff the first argument precedes the second + in the clause order. A clause precedes another if its first lieral + precedes the first literal of the other, or if the first literals + are the same, and its second literal precedes the second literal of + the other clause. A literal precedes another if it has a higher + index, of if it has the same index, but it has lower phase. Phase 0 + is the positive phase, and it is lower than Phase 1 (negative + phase).] + + SideEffects [None] + + SeeAlso [equalp] + +******************************************************************************/ +static int +beforep( + DdHalfWord var1a, + short phase1a, + DdHalfWord var1b, + short phase1b, + DdHalfWord var2a, + short phase2a, + DdHalfWord var2b, + short phase2b) +{ + return(var1a > var2a || (var1a == var2a && + (phase1a < phase2a || (phase1a == phase2a && + (var1b > var2b || (var1b == var2b && phase1b < phase2b)))))); + +} /* end of beforep */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the argument is a one-literal clause.] + + Description [Returns true iff the argument is a one-literal clause. + A one-litaral clause has the constant FALSE as second literal. + Since the constant TRUE is never used, it is sufficient to test for + a constant.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +oneliteralp( + DdHalfWord var) +{ + return(var == CUDD_MAXINDEX); + +} /* end of oneliteralp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff either literal of a clause is in a set of + literals.] + + Description [Returns true iff either literal of a clause is in a set + of literals. The first four arguments specify the clause. The + remaining two arguments specify the literal set.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +impliedp( + DdHalfWord var1, + short phase1, + DdHalfWord var2, + short phase2, + BitVector *olv, + BitVector *olp) +{ + return((bitVectorRead(olv, var1) && + bitVectorRead(olp, var1) == phase1) || + (bitVectorRead(olv, var2) && + bitVectorRead(olp, var2) == phase2)); + +} /* end of impliedp */ + + +/**Function******************************************************************** + + Synopsis [Allocates a bit vector.] + + Description [Allocates a bit vector. The parameter size gives the + number of bits. This procedure allocates enough long's to hold the + specified number of bits. Returns a pointer to the allocated vector + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [bitVectorClear bitVectorFree] + +******************************************************************************/ +static BitVector * +bitVectorAlloc( + int size) +{ + int allocSize; + BitVector *vector; + + /* Find out how many long's we need. + ** There are sizeof(long) * 8 bits in a long. + ** The ceiling of the ratio of two integers m and n is given + ** by ((n-1)/m)+1. Putting all this together, we get... */ + allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1; + vector = ALLOC(BitVector, allocSize); + if (vector == NULL) return(NULL); + /* Clear the whole array. */ + (void) memset(vector, 0, allocSize * sizeof(BitVector)); + return(vector); + +} /* end of bitVectorAlloc */ + + +/**Function******************************************************************** + + Synopsis [Clears a bit vector.] + + Description [Clears a bit vector. The parameter size gives the + number of bits.] + + SideEffects [None] + + SeeAlso [bitVectorAlloc] + +******************************************************************************/ +DD_INLINE +static void +bitVectorClear( + BitVector *vector, + int size) +{ + int allocSize; + + /* Find out how many long's we need. + ** There are sizeof(long) * 8 bits in a long. + ** The ceiling of the ratio of two integers m and n is given + ** by ((n-1)/m)+1. Putting all this together, we get... */ + allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1; + /* Clear the whole array. */ + (void) memset(vector, 0, allocSize * sizeof(BitVector)); + return; + +} /* end of bitVectorClear */ + + +/**Function******************************************************************** + + Synopsis [Frees a bit vector.] + + Description [Frees a bit vector.] + + SideEffects [None] + + SeeAlso [bitVectorAlloc] + +******************************************************************************/ +static void +bitVectorFree( + BitVector *vector) +{ + FREE(vector); + +} /* end of bitVectorFree */ + + +/**Function******************************************************************** + + Synopsis [Returns the i-th entry of a bit vector.] + + Description [Returns the i-th entry of a bit vector.] + + SideEffects [None] + + SeeAlso [bitVectorSet] + +******************************************************************************/ +DD_INLINE +static short +bitVectorRead( + BitVector *vector, + int i) +{ + int word, bit; + short result; + + if (vector == NULL) return((short) 0); + + word = i >> LOGBPL; + bit = i & (BPL - 1); + result = (short) ((vector[word] >> bit) & 1L); + return(result); + +} /* end of bitVectorRead */ + + +/**Function******************************************************************** + + Synopsis [Sets the i-th entry of a bit vector to a value.] + + Description [Sets the i-th entry of a bit vector to a value.] + + SideEffects [None] + + SeeAlso [bitVectorRead] + +******************************************************************************/ +DD_INLINE +static void +bitVectorSet( + BitVector * vector, + int i, + short val) +{ + int word, bit; + + word = i >> LOGBPL; + bit = i & (BPL - 1); + vector[word] &= ~(1L << bit); + vector[word] |= (((long) val) << bit); + +} /* end of bitVectorSet */ + + +/**Function******************************************************************** + + Synopsis [Allocates a DdTlcInfo Structure.] + + Description [Returns a pointer to a DdTlcInfo Structure if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_tlcInfoFree] + +******************************************************************************/ +static DdTlcInfo * +tlcInfoAlloc(void) +{ + DdTlcInfo *res = ALLOC(DdTlcInfo,1); + if (res == NULL) return(NULL); + res->vars = NULL; + res->phases = NULL; + res->cnt = 0; + return(res); + +} /* end of tlcInfoAlloc */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddExact.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddExact.c new file mode 100644 index 000000000..caffbba88 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddExact.c @@ -0,0 +1,1020 @@ +/**CFile*********************************************************************** + + FileName [cuddExact.c] + + PackageName [cudd] + + Synopsis [Functions for exact variable reordering.] + + Description [External procedures included in this file: +
                    +
                  + Internal procedures included in this module: +
                    +
                  • cuddExact() +
                  + Static procedures included in this module: +
                    +
                  • getMaxBinomial() +
                  • gcd() +
                  • getMatrix() +
                  • freeMatrix() +
                  • getLevelKeys() +
                  • ddShuffle() +
                  • ddSiftUp() +
                  • updateUB() +
                  • ddCountRoots() +
                  • ddClearGlobal() +
                  • computeLB() +
                  • updateEntry() +
                  • pushDown() +
                  • initSymmInfo() +
                  ] + + Author [Cheng Hua, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddExact.c,v 1.30 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef DD_STATS +static int ddTotalShuffles; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int getMaxBinomial (int n); +static DdHalfWord ** getMatrix (int rows, int cols); +static void freeMatrix (DdHalfWord **matrix); +static int getLevelKeys (DdManager *table, int l); +static int ddShuffle (DdManager *table, DdHalfWord *permutation, int lower, int upper); +static int ddSiftUp (DdManager *table, int x, int xLow); +static int updateUB (DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper); +static int ddCountRoots (DdManager *table, int lower, int upper); +static void ddClearGlobal (DdManager *table, int lower, int maxlevel); +static int computeLB (DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level); +static int updateEntry (DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper); +static void pushDown (DdHalfWord *order, int j, int level); +static DdHalfWord * initSymmInfo (DdManager *table, int lower, int upper); +static int checkSymmInfo (DdManager *table, DdHalfWord *symmInfo, int index, int level); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Exact variable ordering algorithm.] + + Description [Exact variable ordering algorithm. Finds an optimum + order for the variables between lower and upper. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddExact( + DdManager * table, + int lower, + int upper) +{ + int k, i, j; + int maxBinomial, oldSubsets, newSubsets; + int subsetCost; + int size; /* number of variables to be reordered */ + int unused, nvars, level, result; + int upperBound, lowerBound, cost; + int roots; + char *mask = NULL; + DdHalfWord *symmInfo = NULL; + DdHalfWord **newOrder = NULL; + DdHalfWord **oldOrder = NULL; + int *newCost = NULL; + int *oldCost = NULL; + DdHalfWord **tmpOrder; + int *tmpCost; + DdHalfWord *bestOrder = NULL; + DdHalfWord *order; +#ifdef DD_STATS + int ddTotalSubsets; +#endif + + /* Restrict the range to be reordered by excluding unused variables + ** at the two ends. */ + while (table->subtables[lower].keys == 1 && + table->vars[table->invperm[lower]]->ref == 1 && + lower < upper) + lower++; + while (table->subtables[upper].keys == 1 && + table->vars[table->invperm[upper]]->ref == 1 && + lower < upper) + upper--; + if (lower == upper) return(1); /* trivial problem */ + + /* Apply symmetric sifting to get a good upper bound and to extract + ** symmetry information. */ + result = cuddSymmSiftingConv(table,lower,upper); + if (result == 0) goto cuddExactOutOfMem; + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + ddTotalShuffles = 0; + ddTotalSubsets = 0; +#endif + + /* Initialization. */ + nvars = table->size; + size = upper - lower + 1; + /* Count unused variable among those to be reordered. This is only + ** used to compute maxBinomial. */ + unused = 0; + for (i = lower + 1; i < upper; i++) { + if (table->subtables[i].keys == 1 && + table->vars[table->invperm[i]]->ref == 1) + unused++; + } + + /* Find the maximum number of subsets we may have to store. */ + maxBinomial = getMaxBinomial(size - unused); + if (maxBinomial == -1) goto cuddExactOutOfMem; + + newOrder = getMatrix(maxBinomial, size); + if (newOrder == NULL) goto cuddExactOutOfMem; + + newCost = ALLOC(int, maxBinomial); + if (newCost == NULL) goto cuddExactOutOfMem; + + oldOrder = getMatrix(maxBinomial, size); + if (oldOrder == NULL) goto cuddExactOutOfMem; + + oldCost = ALLOC(int, maxBinomial); + if (oldCost == NULL) goto cuddExactOutOfMem; + + bestOrder = ALLOC(DdHalfWord, size); + if (bestOrder == NULL) goto cuddExactOutOfMem; + + mask = ALLOC(char, nvars); + if (mask == NULL) goto cuddExactOutOfMem; + + symmInfo = initSymmInfo(table, lower, upper); + if (symmInfo == NULL) goto cuddExactOutOfMem; + + roots = ddCountRoots(table, lower, upper); + + /* Initialize the old order matrix for the empty subset and the best + ** order to the current order. The cost for the empty subset includes + ** the cost of the levels between upper and the constants. These levels + ** are not going to change. Hence, we count them only once. + */ + oldSubsets = 1; + for (i = 0; i < size; i++) { + oldOrder[0][i] = bestOrder[i] = (DdHalfWord) table->invperm[i+lower]; + } + subsetCost = table->constants.keys; + for (i = upper + 1; i < nvars; i++) + subsetCost += getLevelKeys(table,i); + oldCost[0] = subsetCost; + /* The upper bound is initialized to the current size of the BDDs. */ + upperBound = table->keys - table->isolated; + + /* Now consider subsets of increasing size. */ + for (k = 1; k <= size; k++) { +#ifdef DD_STATS + (void) fprintf(table->out,"Processing subsets of size %d\n", k); + fflush(table->out); +#endif + newSubsets = 0; + level = size - k; /* offset of first bottom variable */ + + for (i = 0; i < oldSubsets; i++) { /* for each subset of size k-1 */ + order = oldOrder[i]; + cost = oldCost[i]; + lowerBound = computeLB(table, order, roots, cost, lower, upper, + level); + if (lowerBound >= upperBound) + continue; + /* Impose new order. */ + result = ddShuffle(table, order, lower, upper); + if (result == 0) goto cuddExactOutOfMem; + upperBound = updateUB(table,upperBound,bestOrder,lower,upper); + /* For each top bottom variable. */ + for (j = level; j >= 0; j--) { + /* Skip unused variables. */ + if (table->subtables[j+lower-1].keys == 1 && + table->vars[table->invperm[j+lower-1]]->ref == 1) continue; + /* Find cost under this order. */ + subsetCost = cost + getLevelKeys(table, lower + level); + newSubsets = updateEntry(table, order, level, subsetCost, + newOrder, newCost, newSubsets, mask, + lower, upper); + if (j == 0) + break; + if (checkSymmInfo(table, symmInfo, order[j-1], level) == 0) + continue; + pushDown(order,j-1,level); + /* Impose new order. */ + result = ddShuffle(table, order, lower, upper); + if (result == 0) goto cuddExactOutOfMem; + upperBound = updateUB(table,upperBound,bestOrder,lower,upper); + } /* for each bottom variable */ + } /* for each subset of size k */ + + /* New orders become old orders in preparation for next iteration. */ + tmpOrder = oldOrder; tmpCost = oldCost; + oldOrder = newOrder; oldCost = newCost; + newOrder = tmpOrder; newCost = tmpCost; +#ifdef DD_STATS + ddTotalSubsets += newSubsets; +#endif + oldSubsets = newSubsets; + } + result = ddShuffle(table, bestOrder, lower, upper); + if (result == 0) goto cuddExactOutOfMem; +#ifdef DD_STATS +#ifdef DD_VERBOSE + (void) fprintf(table->out,"\n"); +#endif + (void) fprintf(table->out,"#:S_EXACT %8d: total subsets\n", + ddTotalSubsets); + (void) fprintf(table->out,"#:H_EXACT %8d: total shuffles", + ddTotalShuffles); +#endif + + freeMatrix(newOrder); + freeMatrix(oldOrder); + FREE(bestOrder); + FREE(oldCost); + FREE(newCost); + FREE(symmInfo); + FREE(mask); + return(1); + +cuddExactOutOfMem: + + if (newOrder != NULL) freeMatrix(newOrder); + if (oldOrder != NULL) freeMatrix(oldOrder); + if (bestOrder != NULL) FREE(bestOrder); + if (oldCost != NULL) FREE(oldCost); + if (newCost != NULL) FREE(newCost); + if (symmInfo != NULL) FREE(symmInfo); + if (mask != NULL) FREE(mask); + table->errorCode = CUDD_MEMORY_OUT; + return(0); + +} /* end of cuddExact */ + + +/**Function******************************************************************** + + Synopsis [Returns the maximum value of (n choose k) for a given n.] + + Description [Computes the maximum value of (n choose k) for a given + n. The maximum value occurs for k = n/2 when n is even, or k = + (n-1)/2 when n is odd. The algorithm used in this procedure avoids + intermediate overflow problems. It is based on the identity +
                  +    binomial(n,k) = n/k * binomial(n-1,k-1).
                  +  
                  + Returns the computed value if successful; -1 if out of range.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +getMaxBinomial( + int n) +{ + double i, j, result; + + if (n < 0 || n > 33) return(-1); /* error */ + if (n < 2) return(1); + + for (result = (double)((n+3)/2), i = result+1, j=2; i <= n; i++, j++) { + result *= i; + result /= j; + } + + return((int)result); + +} /* end of getMaxBinomial */ + + +#if 0 +/**Function******************************************************************** + + Synopsis [Returns the gcd of two integers.] + + Description [Returns the gcd of two integers. Uses the binary GCD + algorithm described in Cormen, Leiserson, and Rivest.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +gcd( + int x, + int y) +{ + int a; + int b; + int lsbMask; + + /* GCD(n,0) = n. */ + if (x == 0) return(y); + if (y == 0) return(x); + + a = x; b = y; lsbMask = 1; + + /* Here both a and b are != 0. The iteration maintains this invariant. + ** Hence, we only need to check for when they become equal. + */ + while (a != b) { + if (a & lsbMask) { + if (b & lsbMask) { /* both odd */ + if (a < b) { + b = (b - a) >> 1; + } else { + a = (a - b) >> 1; + } + } else { /* a odd, b even */ + b >>= 1; + } + } else { + if (b & lsbMask) { /* a even, b odd */ + a >>= 1; + } else { /* both even */ + lsbMask <<= 1; + } + } + } + + return(a); + +} /* end of gcd */ +#endif + + +/**Function******************************************************************** + + Synopsis [Allocates a two-dimensional matrix of ints.] + + Description [Allocates a two-dimensional matrix of ints. + Returns the pointer to the matrix if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [freeMatrix] + +******************************************************************************/ +static DdHalfWord ** +getMatrix( + int rows /* number of rows */, + int cols /* number of columns */) +{ + DdHalfWord **matrix; + int i; + + if (cols*rows == 0) return(NULL); + matrix = ALLOC(DdHalfWord *, rows); + if (matrix == NULL) return(NULL); + matrix[0] = ALLOC(DdHalfWord, cols*rows); + if (matrix[0] == NULL) { + FREE(matrix); + return(NULL); + } + for (i = 1; i < rows; i++) { + matrix[i] = matrix[i-1] + cols; + } + return(matrix); + +} /* end of getMatrix */ + + +/**Function******************************************************************** + + Synopsis [Frees a two-dimensional matrix allocated by getMatrix.] + + Description [] + + SideEffects [None] + + SeeAlso [getMatrix] + +******************************************************************************/ +static void +freeMatrix( + DdHalfWord ** matrix) +{ + FREE(matrix[0]); + FREE(matrix); + return; + +} /* end of freeMatrix */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of nodes at one level of a unique table.] + + Description [Returns the number of nodes at one level of a unique table. + The projection function, if isolated, is not counted.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +getLevelKeys( + DdManager * table, + int l) +{ + int isolated; + int x; /* x is an index */ + + x = table->invperm[l]; + isolated = table->vars[x]->ref == 1; + + return(table->subtables[l].keys - isolated); + +} /* end of getLevelKeys */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables according to a given permutation.] + + Description [Reorders variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. ddShuffle assumes that no + dead nodes are present and that the interaction matrix is properly + initialized. The reordering is achieved by a series of upward sifts. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddShuffle( + DdManager * table, + DdHalfWord * permutation, + int lower, + int upper) +{ + DdHalfWord index; + int level; + int position; +#if 0 + int numvars; +#endif + int result; +#ifdef DD_STATS + unsigned long localTime; + int initialSize; +#ifdef DD_VERBOSE + int finalSize; +#endif + int previousSize; +#endif + +#ifdef DD_STATS + localTime = util_cpu_time(); + initialSize = table->keys - table->isolated; +#endif + +#if 0 + numvars = table->size; + + (void) fprintf(table->out,"%d:", ddTotalShuffles); + for (level = 0; level < numvars; level++) { + (void) fprintf(table->out," %d", table->invperm[level]); + } + (void) fprintf(table->out,"\n"); +#endif + + for (level = 0; level <= upper - lower; level++) { + index = permutation[level]; + position = table->perm[index]; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSiftUp(table,position,level+lower); + if (!result) return(0); + } + +#ifdef DD_STATS + ddTotalShuffles++; +#ifdef DD_VERBOSE + finalSize = table->keys - table->isolated; + if (finalSize < initialSize) { + (void) fprintf(table->out,"-"); + } else if (finalSize > initialSize) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + if ((ddTotalShuffles & 63) == 0) (void) fprintf(table->out,"\n"); + fflush(table->out); +#endif +#endif + + return(1); + +} /* end of ddShuffle */ + + +/**Function******************************************************************** + + Synopsis [Moves one variable up.] + + Description [Takes a variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddSiftUp( + DdManager * table, + int x, + int xLow) +{ + int y; + int size; + + y = cuddNextLow(table,x); + while (y >= xLow) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); + } + return(1); + +} /* end of ddSiftUp */ + + +/**Function******************************************************************** + + Synopsis [Updates the upper bound and saves the best order seen so far.] + + Description [Updates the upper bound and saves the best order seen so far. + Returns the current value of the upper bound.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +updateUB( + DdManager * table, + int oldBound, + DdHalfWord * bestOrder, + int lower, + int upper) +{ + int i; + int newBound = table->keys - table->isolated; + + if (newBound < oldBound) { +#ifdef DD_STATS + (void) fprintf(table->out,"New upper bound = %d\n", newBound); + fflush(table->out); +#endif + for (i = lower; i <= upper; i++) + bestOrder[i-lower] = (DdHalfWord) table->invperm[i]; + return(newBound); + } else { + return(oldBound); + } + +} /* end of updateUB */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of roots.] + + Description [Counts the number of roots at the levels between lower and + upper. The computation is based on breadth-first search. + A node is a root if it is not reachable from any previously visited node. + (All the nodes at level lower are therefore considered roots.) + The visited flag uses the LSB of the next pointer. Returns the root + count. The roots that are constant nodes are always ignored.] + + SideEffects [None] + + SeeAlso [ddClearGlobal] + +******************************************************************************/ +static int +ddCountRoots( + DdManager * table, + int lower, + int upper) +{ + int i,j; + DdNode *f; + DdNodePtr *nodelist; + DdNode *sentinel = &(table->sentinel); + int slots; + int roots = 0; + int maxlevel = lower; + + for (i = lower; i <= upper; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + /* A node is a root of the DAG if it cannot be + ** reached by nodes above it. If a node was never + ** reached during the previous depth-first searches, + ** then it is a root, and we start a new depth-first + ** search from it. + */ + if (!Cudd_IsComplement(f->next)) { + if (f != table->vars[f->index]) { + roots++; + } + } + if (!Cudd_IsConstant(cuddT(f))) { + cuddT(f)->next = Cudd_Complement(cuddT(f)->next); + if (table->perm[cuddT(f)->index] > maxlevel) + maxlevel = table->perm[cuddT(f)->index]; + } + if (!Cudd_IsConstant(cuddE(f))) { + Cudd_Regular(cuddE(f))->next = + Cudd_Complement(Cudd_Regular(cuddE(f))->next); + if (table->perm[Cudd_Regular(cuddE(f))->index] > maxlevel) + maxlevel = table->perm[Cudd_Regular(cuddE(f))->index]; + } + f = Cudd_Regular(f->next); + } + } + } + ddClearGlobal(table, lower, maxlevel); + + return(roots); + +} /* end of ddCountRoots */ + + +/**Function******************************************************************** + + Synopsis [Scans the DD and clears the LSB of the next pointers.] + + Description [Scans the DD and clears the LSB of the next pointers. + The LSB of the next pointers are used as markers to tell whether a + node was reached. Once the roots are counted, these flags are + reset.] + + SideEffects [None] + + SeeAlso [ddCountRoots] + +******************************************************************************/ +static void +ddClearGlobal( + DdManager * table, + int lower, + int maxlevel) +{ + int i,j; + DdNode *f; + DdNodePtr *nodelist; + DdNode *sentinel = &(table->sentinel); + int slots; + + for (i = lower; i <= maxlevel; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + f->next = Cudd_Regular(f->next); + f = f->next; + } + } + } + +} /* end of ddClearGlobal */ + + +/**Function******************************************************************** + + Synopsis [Computes a lower bound on the size of a BDD.] + + Description [Computes a lower bound on the size of a BDD from the + following factors: +
                    +
                  • size of the lower part of it; +
                  • size of the part of the upper part not subjected to reordering; +
                  • number of roots in the part of the BDD subjected to reordering; +
                  • variable in the support of the roots in the upper part of the + BDD subjected to reordering. +
                      ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +computeLB( + DdManager * table /* manager */, + DdHalfWord * order /* optimal order for the subset */, + int roots /* roots between lower and upper */, + int cost /* minimum cost for the subset */, + int lower /* lower level to be reordered */, + int upper /* upper level to be reordered */, + int level /* offset for the current top bottom var */ + ) +{ + int i; + int lb = cost; + int lb1 = 0; + int lb2; + int support; + DdHalfWord ref; + + /* The levels not involved in reordering are not going to change. + ** Add their sizes to the lower bound. + */ + for (i = 0; i < lower; i++) { + lb += getLevelKeys(table,i); + } + /* If a variable is in the support, then there is going + ** to be at least one node labeled by that variable. + */ + for (i = lower; i <= lower+level; i++) { + support = table->subtables[i].keys > 1 || + table->vars[order[i-lower]]->ref > 1; + lb1 += support; + } + + /* Estimate the number of nodes required to connect the roots to + ** the nodes in the bottom part. */ + if (lower+level+1 < table->size) { + if (lower+level < upper) + ref = table->vars[order[level+1]]->ref; + else + ref = table->vars[table->invperm[upper+1]]->ref; + lb2 = table->subtables[lower+level+1].keys - + (ref > (DdHalfWord) 1) - roots; + } else { + lb2 = 0; + } + + lb += lb1 > lb2 ? lb1 : lb2; + + return(lb); + +} /* end of computeLB */ + + +/**Function******************************************************************** + + Synopsis [Updates entry for a subset.] + + Description [Updates entry for a subset. Finds the subset, if it exists. + If the new order for the subset has lower cost, or if the subset did not + exist, it stores the new order and cost. Returns the number of subsets + currently in the table.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +updateEntry( + DdManager * table, + DdHalfWord * order, + int level, + int cost, + DdHalfWord ** orders, + int * costs, + int subsets, + char * mask, + int lower, + int upper) +{ + int i, j; + int size = upper - lower + 1; + + /* Build a mask that says what variables are in this subset. */ + for (i = lower; i <= upper; i++) + mask[table->invperm[i]] = 0; + for (i = level; i < size; i++) + mask[order[i]] = 1; + + /* Check each subset until a match is found or all subsets are examined. */ + for (i = 0; i < subsets; i++) { + DdHalfWord *subset = orders[i]; + for (j = level; j < size; j++) { + if (mask[subset[j]] == 0) + break; + } + if (j == size) /* no mismatches: success */ + break; + } + if (i == subsets || cost < costs[i]) { /* add or replace */ + for (j = 0; j < size; j++) + orders[i][j] = order[j]; + costs[i] = cost; + subsets += (i == subsets); + } + return(subsets); + +} /* end of updateEntry */ + + +/**Function******************************************************************** + + Synopsis [Pushes a variable in the order down to position "level."] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +pushDown( + DdHalfWord * order, + int j, + int level) +{ + int i; + DdHalfWord tmp; + + tmp = order[j]; + for (i = j; i < level; i++) { + order[i] = order[i+1]; + } + order[level] = tmp; + return; + +} /* end of pushDown */ + + +/**Function******************************************************************** + + Synopsis [Gathers symmetry information.] + + Description [Translates the symmetry information stored in the next + field of each subtable from level to indices. This procedure is called + immediately after symmetric sifting, so that the next fields are correct. + By translating this informaton in terms of indices, we make it independent + of subsequent reorderings. The format used is that of the next fields: + a circular list where each variable points to the next variable in the + same symmetry group. Only the entries between lower and upper are + considered. The procedure returns a pointer to an array + holding the symmetry information if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [checkSymmInfo] + +******************************************************************************/ +static DdHalfWord * +initSymmInfo( + DdManager * table, + int lower, + int upper) +{ + int level, index, next, nextindex; + DdHalfWord *symmInfo; + + symmInfo = ALLOC(DdHalfWord, table->size); + if (symmInfo == NULL) return(NULL); + + for (level = lower; level <= upper; level++) { + index = table->invperm[level]; + next = table->subtables[level].next; + nextindex = table->invperm[next]; + symmInfo[index] = nextindex; + } + return(symmInfo); + +} /* end of initSymmInfo */ + + +/**Function******************************************************************** + + Synopsis [Check symmetry condition.] + + Description [Returns 1 if a variable is the one with the highest index + among those belonging to a symmetry group that are in the top part of + the BDD. The top part is given by level.] + + SideEffects [None] + + SeeAlso [initSymmInfo] + +******************************************************************************/ +static int +checkSymmInfo( + DdManager * table, + DdHalfWord * symmInfo, + int index, + int level) +{ + int i; + + i = symmInfo[index]; + while (i != index) { + if (index < i && table->perm[i] <= level) + return(0); + i = symmInfo[i]; + } + return(1); + +} /* end of checkSymmInfo */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddExport.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddExport.c new file mode 100644 index 000000000..3d8da77ac --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddExport.c @@ -0,0 +1,1389 @@ +/**CFile*********************************************************************** + + FileName [cuddExport.c] + + PackageName [cudd] + + Synopsis [Export functions.] + + Description [External procedures included in this module: +
                        +
                      • Cudd_DumpBlif() +
                      • Cudd_DumpBlifBody() +
                      • Cudd_DumpDot() +
                      • Cudd_DumpDaVinci() +
                      • Cudd_DumpDDcal() +
                      • Cudd_DumpFactoredForm() +
                      + Internal procedures included in this module: +
                        +
                      + Static procedures included in this module: +
                        +
                      • ddDoDumpBlif() +
                      • ddDoDumpDaVinci() +
                      • ddDoDumpDDcal() +
                      • ddDoDumpFactoredForm() +
                      ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddExport.c,v 1.23 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddDoDumpBlif (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, int mv); +static int ddDoDumpDaVinci (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, ptruint mask); +static int ddDoDumpDDcal (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, ptruint mask); +static int ddDoDumpFactoredForm (DdManager *dd, DdNode *f, FILE *fp, char **names); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Writes a blif file representing the argument BDDs.] + + Description [Writes a blif file representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). Cudd_DumpBlif does not close the file: This is the + caller responsibility. Cudd_DumpBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for onames.] + + SideEffects [None] + + SeeAlso [Cudd_DumpBlifBody Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal + Cudd_DumpDaVinci Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpBlif( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + char * mname /* model name (or NULL) */, + FILE * fp /* pointer to the dump file */, + int mv /* 0: blif, 1: blif-MV */) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; + int retval; + int i; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int,nvars); + if (sorted == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; + } + for (i = 0; i < nvars; i++) sorted[i] = 0; + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(dd,f,n); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + support = NULL; /* so that we do not try to free it in case of failure */ + + /* Write the header (.model .inputs .outputs). */ + if (mname == NULL) { + retval = fprintf(fp,".model DD\n.inputs"); + } else { + retval = fprintf(fp,".model %s\n.inputs",mname); + } + if (retval == EOF) { + FREE(sorted); + return(0); + } + + /* Write the input list by scanning the support array. */ + for (i = 0; i < nvars; i++) { + if (sorted[i]) { + if (inames == NULL) { + retval = fprintf(fp," %d", i); + } else { + retval = fprintf(fp," %s", inames[i]); + } + if (retval == EOF) goto failure; + } + } + FREE(sorted); + sorted = NULL; + + /* Write the .output line. */ + retval = fprintf(fp,"\n.outputs"); + if (retval == EOF) goto failure; + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp," f%d", i); + } else { + retval = fprintf(fp," %s", onames[i]); + } + if (retval == EOF) goto failure; + } + retval = fprintf(fp,"\n"); + if (retval == EOF) goto failure; + + retval = Cudd_DumpBlifBody(dd, n, f, inames, onames, fp, mv); + if (retval == 0) goto failure; + + /* Write trailer and return. */ + retval = fprintf(fp,".end\n"); + if (retval == EOF) goto failure; + + return(1); + +failure: + if (sorted != NULL) FREE(sorted); + if (support != NULL) Cudd_RecursiveDeref(dd,support); + return(0); + +} /* end of Cudd_DumpBlif */ + + +/**Function******************************************************************** + + Synopsis [Writes a blif body representing the argument BDDs.] + + Description [Writes a blif body representing the argument BDDs as a + network of multiplexers. No header (.model, .inputs, and .outputs) and + footer (.end) are produced by this function. One multiplexer is written + for each BDD node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). Cudd_DumpBlifBody does not close the file: This is the + caller responsibility. Cudd_DumpBlifBody uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for onames. This function prints out only + .names part.] + + SideEffects [None] + + SeeAlso [Cudd_DumpBlif Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal + Cudd_DumpDaVinci Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpBlifBody( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */, + int mv /* 0: blif, 1: blif-MV */) +{ + st_table *visited = NULL; + int retval; + int i; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + retval = ddDoDumpBlif(dd,Cudd_Regular(f[i]),fp,visited,inames,mv); + if (retval == 0) goto failure; + } + + /* To account for the possible complement on the root, + ** we put either a buffer or an inverter at the output of + ** the multiplexer representing the top node. + */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp, +#if SIZEOF_VOID_P == 8 + ".names %lx f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); +#else + ".names %x f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); +#endif + } else { + retval = fprintf(fp, +#if SIZEOF_VOID_P == 8 + ".names %lx %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]); +#else + ".names %x %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]); +#endif + } + if (retval == EOF) goto failure; + if (Cudd_IsComplement(f[i])) { + retval = fprintf(fp,"%s0 1\n", mv ? ".def 0\n" : ""); + } else { + retval = fprintf(fp,"%s1 1\n", mv ? ".def 0\n" : ""); + } + if (retval == EOF) goto failure; + } + + st_free_table(visited); + return(1); + +failure: + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_DumpBlifBody */ + + +/**Function******************************************************************** + + Synopsis [Writes a dot file representing the argument DDs.] + + Description [Writes a file representing the argument DDs in a format + suitable for the graph drawing program dot. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, + file system full). + Cudd_DumpDot does not close the file: This is the caller + responsibility. Cudd_DumpDot uses a minimal unique subset of the + hexadecimal address of a node as name for it. + If the argument inames is non-null, it is assumed to hold the pointers + to the names of the inputs. Similarly for onames. + Cudd_DumpDot uses the following convention to draw arcs: +
                        +
                      • solid line: THEN arcs; +
                      • dotted line: complement arcs; +
                      • dashed line: regular ELSE arcs. +
                      + The dot options are chosen so that the drawing fits on a letter-size + sheet. + ] + + SideEffects [None] + + SeeAlso [Cudd_DumpBlif Cudd_PrintDebug Cudd_DumpDDcal + Cudd_DumpDaVinci Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpDot( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; + st_table *visited = NULL; + st_generator *gen = NULL; + int retval; + int i, j; + int slots; + DdNodePtr *nodelist; + long refAddr, diff, mask; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int,nvars); + if (sorted == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; + } + for (i = 0; i < nvars; i++) sorted[i] = 0; + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(dd,f,n); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + support = NULL; /* so that we do not try to free it in case of failure */ + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Collect all the nodes of this DD in the symbol table. */ + for (i = 0; i < n; i++) { + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; + } + + /* Find how many most significant hex digits are identical + ** in the addresses of all the nodes. Build a mask based + ** on this knowledge, so that digits that carry no information + ** will not be printed. This is done in two steps. + ** 1. We scan the symbol table to find the bits that differ + ** in at least 2 addresses. + ** 2. We choose one of the possible masks. There are 8 possible + ** masks for 32-bit integer, and 16 possible masks for 64-bit + ** integers. + */ + + /* Find the bits that are different. */ + refAddr = (long) Cudd_Regular(f[0]); + diff = 0; + gen = st_init_gen(visited); + if (gen == NULL) goto failure; + while (st_gen(gen, &scan, NULL)) { + diff |= refAddr ^ (long) scan; + } + st_free_gen(gen); gen = NULL; + + /* Choose the mask. */ + for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; + } + + /* Write the header and the global attributes. */ + retval = fprintf(fp,"digraph \"DD\" {\n"); + if (retval == EOF) return(0); + retval = fprintf(fp, + "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); + if (retval == EOF) return(0); + + /* Write the input name subgraph by scanning the support array. */ + retval = fprintf(fp,"{ node [shape = plaintext];\n"); + if (retval == EOF) goto failure; + retval = fprintf(fp," edge [style = invis];\n"); + if (retval == EOF) goto failure; + /* We use a name ("CONST NODES") with an embedded blank, because + ** it is unlikely to appear as an input name. + */ + retval = fprintf(fp," \"CONST NODES\" [style = invis];\n"); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if (sorted[dd->invperm[i]]) { + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"\" %d \" -> ", dd->invperm[i]); + } else { + retval = fprintf(fp,"\" %s \" -> ", inames[dd->invperm[i]]); + } + if (retval == EOF) goto failure; + } + } + retval = fprintf(fp,"\"CONST NODES\"; \n}\n"); + if (retval == EOF) goto failure; + + /* Write the output node subgraph. */ + retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); + if (retval == EOF) goto failure; + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + if (i == n - 1) { + retval = fprintf(fp,"; }\n"); + } else { + retval = fprintf(fp," -> "); + } + if (retval == EOF) goto failure; + } + + /* Write rank info: All nodes with the same index have the same rank. */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invperm[i]]) { + retval = fprintf(fp,"{ rank = same; "); + if (retval == EOF) goto failure; + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"\" %d \";\n", dd->invperm[i]); + } else { + retval = fprintf(fp,"\" %s \";\n", inames[dd->invperm[i]]); + } + if (retval == EOF) goto failure; + nodelist = dd->subtables[i].nodelist; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; + } + } + + /* All constants have the same rank. */ + retval = fprintf(fp, + "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); + if (retval == EOF) goto failure; + nodelist = dd->constants.nodelist; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", + (void *) ((mask & (ptrint) scan) / sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + retval = fprintf(fp,"}\n}\n"); + if (retval == EOF) goto failure; + + /* Write edge info. */ + /* Edges from the output nodes. */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + /* Account for the possible complement on the root. */ + if (Cudd_IsComplement(f[i])) { + retval = fprintf(fp," -> \"%p\" [style = dotted];\n", + (void *) ((mask & (ptrint) f[i]) / sizeof(DdNode))); + } else { + retval = fprintf(fp," -> \"%p\" [style = solid];\n", + (void *) ((mask & (ptrint) f[i]) / sizeof(DdNode))); + } + if (retval == EOF) goto failure; + } + + /* Edges from internal nodes. */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invperm[i]]) { + nodelist = dd->subtables[i].nodelist; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp, + "\"%p\" -> \"%p\";\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddT(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + if (Cudd_IsComplement(cuddE(scan))) { + retval = fprintf(fp, + "\"%p\" -> \"%p\" [style = dotted];\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddE(scan)) / + sizeof(DdNode))); + } else { + retval = fprintf(fp, + "\"%p\" -> \"%p\" [style = dashed];\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddE(scan)) / + sizeof(DdNode))); + } + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + } + } + + /* Write constant labels. */ + nodelist = dd->constants.nodelist; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n", + (void *) ((mask & (ptrint) scan) / sizeof(DdNode)), + cuddV(scan)); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + + /* Write trailer and return. */ + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; + + st_free_table(visited); + FREE(sorted); + return(1); + +failure: + if (sorted != NULL) FREE(sorted); + if (support != NULL) Cudd_RecursiveDeref(dd,support); + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_DumpDot */ + + +/**Function******************************************************************** + + Synopsis [Writes a daVinci file representing the argument BDDs.] + + Description [Writes a daVinci file representing the argument BDDs. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or + file system full). Cudd_DumpDaVinci does not close the file: This + is the caller responsibility. Cudd_DumpDaVinci uses a minimal unique + subset of the hexadecimal address of a node as name for it. If the + argument inames is non-null, it is assumed to hold the pointers to + the names of the inputs. Similarly for onames.] + + SideEffects [None] + + SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDDcal + Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpDaVinci( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + DdNode *support = NULL; + DdNode *scan; + st_table *visited = NULL; + int retval; + int i; + st_generator *gen; + ptruint refAddr, diff, mask; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Collect all the nodes of this DD in the symbol table. */ + for (i = 0; i < n; i++) { + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; + } + + /* Find how many most significant hex digits are identical + ** in the addresses of all the nodes. Build a mask based + ** on this knowledge, so that digits that carry no information + ** will not be printed. This is done in two steps. + ** 1. We scan the symbol table to find the bits that differ + ** in at least 2 addresses. + ** 2. We choose one of the possible masks. There are 8 possible + ** masks for 32-bit integer, and 16 possible masks for 64-bit + ** integers. + */ + + /* Find the bits that are different. */ + refAddr = (ptruint) Cudd_Regular(f[0]); + diff = 0; + gen = st_init_gen(visited); + while (st_gen(gen, &scan, NULL)) { + diff |= refAddr ^ (ptruint) scan; + } + st_free_gen(gen); + + /* Choose the mask. */ + for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; + } + st_free_table(visited); + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + retval = fprintf(fp, "["); + if (retval == EOF) goto failure; + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp, + "l(\"f%d\",n(\"root\",[a(\"OBJECT\",\"f%d\")],", + i,i); + } else { + retval = fprintf(fp, + "l(\"%s\",n(\"root\",[a(\"OBJECT\",\"%s\")],", + onames[i], onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp, "[e(\"edge\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],", + Cudd_IsComplement(f[i]) ? "red" : "blue"); + if (retval == EOF) goto failure; + retval = ddDoDumpDaVinci(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); + if (retval == 0) goto failure; + retval = fprintf(fp, ")]))%s", i == n-1 ? "" : ","); + if (retval == EOF) goto failure; + } + + /* Write trailer and return. */ + retval = fprintf(fp, "]\n"); + if (retval == EOF) goto failure; + + st_free_table(visited); + return(1); + +failure: + if (support != NULL) Cudd_RecursiveDeref(dd,support); + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_DumpDaVinci */ + + +/**Function******************************************************************** + + Synopsis [Writes a DDcal file representing the argument BDDs.] + + Description [Writes a DDcal file representing the argument BDDs. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or + file system full). Cudd_DumpDDcal does not close the file: This + is the caller responsibility. Cudd_DumpDDcal uses a minimal unique + subset of the hexadecimal address of a node as name for it. If the + argument inames is non-null, it is assumed to hold the pointers to + the names of the inputs. Similarly for onames.] + + SideEffects [None] + + SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci + Cudd_DumpFactoredForm] + +******************************************************************************/ +int +Cudd_DumpDDcal( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; + st_table *visited = NULL; + int retval; + int i; + st_generator *gen; + ptruint refAddr, diff, mask; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Collect all the nodes of this DD in the symbol table. */ + for (i = 0; i < n; i++) { + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; + } + + /* Find how many most significant hex digits are identical + ** in the addresses of all the nodes. Build a mask based + ** on this knowledge, so that digits that carry no information + ** will not be printed. This is done in two steps. + ** 1. We scan the symbol table to find the bits that differ + ** in at least 2 addresses. + ** 2. We choose one of the possible masks. There are 8 possible + ** masks for 32-bit integer, and 16 possible masks for 64-bit + ** integers. + */ + + /* Find the bits that are different. */ + refAddr = (ptruint) Cudd_Regular(f[0]); + diff = 0; + gen = st_init_gen(visited); + while (st_gen(gen, &scan, NULL)) { + diff |= refAddr ^ (ptruint) scan; + } + st_free_gen(gen); + + /* Choose the mask. */ + for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; + } + st_free_table(visited); + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int,nvars); + if (sorted == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; + } + for (i = 0; i < nvars; i++) sorted[i] = 0; + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(dd,f,n); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + support = NULL; /* so that we do not try to free it in case of failure */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invperm[i]]) { + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"v%d", dd->invperm[i]); + } else { + retval = fprintf(fp,"%s", inames[dd->invperm[i]]); + } + if (retval == EOF) goto failure; + } + retval = fprintf(fp,"%s", i == nvars - 1 ? "\n" : " * "); + if (retval == EOF) goto failure; + } + FREE(sorted); + sorted = NULL; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + retval = ddDoDumpDDcal(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); + if (retval == 0) goto failure; + if (onames == NULL) { + retval = fprintf(fp, "f%d = ", i); + } else { + retval = fprintf(fp, "%s = ", onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp, "n%p%s\n", + (void *) (((ptruint) f[i] & mask) / + (ptruint) sizeof(DdNode)), + Cudd_IsComplement(f[i]) ? "'" : ""); + if (retval == EOF) goto failure; + } + + /* Write trailer and return. */ + retval = fprintf(fp, "["); + if (retval == EOF) goto failure; + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp, "f%d", i); + } else { + retval = fprintf(fp, "%s", onames[i]); + } + retval = fprintf(fp, "%s", i == n-1 ? "" : " "); + if (retval == EOF) goto failure; + } + retval = fprintf(fp, "]\n"); + if (retval == EOF) goto failure; + + st_free_table(visited); + return(1); + +failure: + if (sorted != NULL) FREE(sorted); + if (support != NULL) Cudd_RecursiveDeref(dd,support); + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_DumpDDcal */ + + +/**Function******************************************************************** + + Synopsis [Writes factored forms representing the argument BDDs.] + + Description [Writes factored forms representing the argument BDDs. + The format of the factored form is the one used in the genlib files + for technology mapping in sis. It returns 1 in case of success; 0 + otherwise (e.g., file system full). Cudd_DumpFactoredForm does not + close the file: This is the caller responsibility. Caution must be + exercised because a factored form may be exponentially larger than + the argument BDD. If the argument inames is non-null, it is assumed + to hold the pointers to the names of the inputs. Similarly for + onames.] + + SideEffects [None] + + SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci + Cudd_DumpDDcal] + +******************************************************************************/ +int +Cudd_DumpFactoredForm( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + int retval; + int i; + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp, "f%d = ", i); + } else { + retval = fprintf(fp, "%s = ", onames[i]); + } + if (retval == EOF) return(0); + if (f[i] == DD_ONE(dd)) { + retval = fprintf(fp, "CONST1"); + if (retval == EOF) return(0); + } else if (f[i] == Cudd_Not(DD_ONE(dd)) || f[i] == DD_ZERO(dd)) { + retval = fprintf(fp, "CONST0"); + if (retval == EOF) return(0); + } else { + retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? "!(" : ""); + if (retval == EOF) return(0); + retval = ddDoDumpFactoredForm(dd,Cudd_Regular(f[i]),fp,inames); + if (retval == 0) return(0); + retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? ")" : ""); + if (retval == EOF) return(0); + } + retval = fprintf(fp, "%s", i == n-1 ? "" : "\n"); + if (retval == EOF) return(0); + } + + return(1); + +} /* end of Cudd_DumpFactoredForm */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DumpBlif.] + + Description [Performs the recursive step of Cudd_DumpBlif. Traverses + the BDD f and writes a multiplexer-network description to the file + pointed by fp in blif format. f is assumed to be a regular pointer + and ddDoDumpBlif guarantees this assumption in the recursive calls.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddDoDumpBlif( + DdManager * dd, + DdNode * f, + FILE * fp, + st_table * visited, + char ** names, + int mv) +{ + DdNode *T, *E; + int retval; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + /* If already visited, nothing to do. */ + if (st_is_member(visited, (char *) f) == 1) + return(1); + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Mark node as visited. */ + if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + + /* Check for special case: If constant node, generate constant 1. */ + if (f == DD_ONE(dd)) { +#if SIZEOF_VOID_P == 8 + retval = fprintf(fp, ".names %lx\n1\n",(ptruint) f / (ptruint) sizeof(DdNode)); +#else + retval = fprintf(fp, ".names %x\n1\n",(ptruint) f / (ptruint) sizeof(DdNode)); +#endif + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + + /* Check whether this is an ADD. We deal with 0-1 ADDs, but not + ** with the general case. + */ + if (f == DD_ZERO(dd)) { +#if SIZEOF_VOID_P == 8 + retval = fprintf(fp, ".names %lx\n%s", + (ptruint) f / (ptruint) sizeof(DdNode), + mv ? "0\n" : ""); +#else + retval = fprintf(fp, ".names %x\n%s", + (ptruint) f / (ptruint) sizeof(DdNode), + mv ? "0\n" : ""); +#endif + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + if (cuddIsConstant(f)) + return(0); + + /* Recursive calls. */ + T = cuddT(f); + retval = ddDoDumpBlif(dd,T,fp,visited,names,mv); + if (retval != 1) return(retval); + E = Cudd_Regular(cuddE(f)); + retval = ddDoDumpBlif(dd,E,fp,visited,names,mv); + if (retval != 1) return(retval); + + /* Write multiplexer taking complement arc into account. */ + if (names != NULL) { + retval = fprintf(fp,".names %s", names[f->index]); + } else { +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp,".names %u", f->index); +#else + retval = fprintf(fp,".names %hu", f->index); +#endif + } + if (retval == EOF) + return(0); + +#if SIZEOF_VOID_P == 8 + if (mv) { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %lx %lx %lx\n.def 0\n1 1 - 1\n0 - 0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %lx %lx %lx\n.def 0\n1 1 - 1\n0 - 1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } + } else { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } + } +#else + if (mv) { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %x %x %x\n.def 0\n1 1 - 1\n0 - 0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %x %x %x\n.def 0\n1 1 - 1\n0 - 1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } + } else { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %x %x %x\n11- 1\n0-0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %x %x %x\n11- 1\n0-1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } + } +#endif + if (retval == EOF) { + return(0); + } else { + return(1); + } + +} /* end of ddDoDumpBlif */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DumpDaVinci.] + + Description [Performs the recursive step of Cudd_DumpDaVinci. Traverses + the BDD f and writes a term expression to the file + pointed by fp in daVinci format. f is assumed to be a regular pointer + and ddDoDumpDaVinci guarantees this assumption in the recursive calls.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddDoDumpDaVinci( + DdManager * dd, + DdNode * f, + FILE * fp, + st_table * visited, + char ** names, + ptruint mask) +{ + DdNode *T, *E; + int retval; + ptruint id; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + id = ((ptruint) f & mask) / sizeof(DdNode); + + /* If already visited, insert a reference. */ + if (st_is_member(visited, (char *) f) == 1) { + retval = fprintf(fp,"r(\"%p\")", (void *) id); + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Mark node as visited. */ + if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + + /* Check for special case: If constant node, generate constant 1. */ + if (Cudd_IsConstant(f)) { + retval = fprintf(fp, + "l(\"%p\",n(\"constant\",[a(\"OBJECT\",\"%g\")],[]))", + (void *) id, cuddV(f)); + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + + /* Recursive calls. */ + if (names != NULL) { + retval = fprintf(fp, + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%s\"),", + (void *) id, names[f->index]); + } else { + retval = fprintf(fp, +#if SIZEOF_VOID_P == 8 + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%u\"),", +#else + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%hu\"),", +#endif + (void *) id, f->index); + } + retval = fprintf(fp, "a(\"_GO\",\"ellipse\")],[e(\"then\",[a(\"EDGECOLOR\",\"blue\"),a(\"_DIR\",\"none\")],"); + if (retval == EOF) return(0); + T = cuddT(f); + retval = ddDoDumpDaVinci(dd,T,fp,visited,names,mask); + if (retval != 1) return(retval); + retval = fprintf(fp, "),e(\"else\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],", + Cudd_IsComplement(cuddE(f)) ? "red" : "green"); + if (retval == EOF) return(0); + E = Cudd_Regular(cuddE(f)); + retval = ddDoDumpDaVinci(dd,E,fp,visited,names,mask); + if (retval != 1) return(retval); + + retval = fprintf(fp,")]))"); + if (retval == EOF) { + return(0); + } else { + return(1); + } + +} /* end of ddDoDumpDaVinci */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DumpDDcal.] + + Description [Performs the recursive step of Cudd_DumpDDcal. Traverses + the BDD f and writes a line for each node to the file + pointed by fp in DDcal format. f is assumed to be a regular pointer + and ddDoDumpDDcal guarantees this assumption in the recursive calls.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddDoDumpDDcal( + DdManager * dd, + DdNode * f, + FILE * fp, + st_table * visited, + char ** names, + ptruint mask) +{ + DdNode *T, *E; + int retval; + ptruint id, idT, idE; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + id = ((ptruint) f & mask) / sizeof(DdNode); + + /* If already visited, do nothing. */ + if (st_is_member(visited, (char *) f) == 1) { + return(1); + } + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Mark node as visited. */ + if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + + /* Check for special case: If constant node, assign constant. */ + if (Cudd_IsConstant(f)) { + if (f != DD_ONE(dd) && f != DD_ZERO(dd)) + return(0); + retval = fprintf(fp, "n%p = %g\n", (void *) id, cuddV(f)); + if (retval == EOF) { + return(0); + } else { + return(1); + } + } + + /* Recursive calls. */ + T = cuddT(f); + retval = ddDoDumpDDcal(dd,T,fp,visited,names,mask); + if (retval != 1) return(retval); + E = Cudd_Regular(cuddE(f)); + retval = ddDoDumpDDcal(dd,E,fp,visited,names,mask); + if (retval != 1) return(retval); + idT = ((ptruint) T & mask) / sizeof(DdNode); + idE = ((ptruint) E & mask) / sizeof(DdNode); + if (names != NULL) { + retval = fprintf(fp, "n%p = %s * n%p + %s' * n%p%s\n", + (void *) id, names[f->index], + (void *) idT, names[f->index], + (void *) idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); + } else { +#if SIZEOF_VOID_P == 8 + retval = fprintf(fp, "n%p = v%u * n%p + v%u' * n%p%s\n", +#else + retval = fprintf(fp, "n%p = v%hu * n%p + v%hu' * n%p%s\n", +#endif + (void *) id, f->index, + (void *) idT, f->index, + (void *) idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); + } + if (retval == EOF) { + return(0); + } else { + return(1); + } + +} /* end of ddDoDumpDDcal */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DumpFactoredForm.] + + Description [Performs the recursive step of + Cudd_DumpFactoredForm. Traverses the BDD f and writes a factored + form for each node to the file pointed by fp in terms of the + factored forms of the children. Constants are propagated, and + absorption is applied. f is assumed to be a regular pointer and + ddDoDumpFActoredForm guarantees this assumption in the recursive + calls.] + + SideEffects [None] + + SeeAlso [Cudd_DumpFactoredForm] + +******************************************************************************/ +static int +ddDoDumpFactoredForm( + DdManager * dd, + DdNode * f, + FILE * fp, + char ** names) +{ + DdNode *T, *E; + int retval; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); + assert(!Cudd_IsConstant(f)); +#endif + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Recursive calls. */ + T = cuddT(f); + E = cuddE(f); + if (T != DD_ZERO(dd)) { + if (E != DD_ONE(dd)) { + if (names != NULL) { + retval = fprintf(fp, "%s", names[f->index]); + } else { +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp, "x%u", f->index); +#else + retval = fprintf(fp, "x%hu", f->index); +#endif + } + if (retval == EOF) return(0); + } + if (T != DD_ONE(dd)) { + retval = fprintf(fp, "%s(", E != DD_ONE(dd) ? " * " : ""); + if (retval == EOF) return(0); + retval = ddDoDumpFactoredForm(dd,T,fp,names); + if (retval != 1) return(retval); + retval = fprintf(fp, ")"); + if (retval == EOF) return(0); + } + if (E == Cudd_Not(DD_ONE(dd)) || E == DD_ZERO(dd)) return(1); + retval = fprintf(fp, " + "); + if (retval == EOF) return(0); + } + E = Cudd_Regular(E); + if (T != DD_ONE(dd)) { + if (names != NULL) { + retval = fprintf(fp, "!%s", names[f->index]); + } else { +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp, "!x%u", f->index); +#else + retval = fprintf(fp, "!x%hu", f->index); +#endif + } + if (retval == EOF) return(0); + } + if (E != DD_ONE(dd)) { + retval = fprintf(fp, "%s%s(", T != DD_ONE(dd) ? " * " : "", + E != cuddE(f) ? "!" : ""); + if (retval == EOF) return(0); + retval = ddDoDumpFactoredForm(dd,E,fp,names); + if (retval != 1) return(retval); + retval = fprintf(fp, ")"); + if (retval == EOF) return(0); + } + return(1); + +} /* end of ddDoDumpFactoredForm */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddGenCof.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddGenCof.c new file mode 100644 index 000000000..e129aca44 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddGenCof.c @@ -0,0 +1,2178 @@ +/**CFile*********************************************************************** + + FileName [cuddGenCof.c] + + PackageName [cudd] + + Synopsis [Generalized cofactors for BDDs and ADDs.] + + Description [External procedures included in this module: +
                        +
                      • Cudd_bddConstrain() +
                      • Cudd_bddRestrict() +
                      • Cudd_bddNPAnd() +
                      • Cudd_addConstrain() +
                      • Cudd_bddConstrainDecomp() +
                      • Cudd_addRestrict() +
                      • Cudd_bddCharToVect() +
                      • Cudd_bddLICompaction() +
                      • Cudd_bddSqueeze() +
                      • Cudd_bddMinimize() +
                      • Cudd_SubsetCompress() +
                      • Cudd_SupersetCompress() +
                      + Internal procedures included in this module: +
                        +
                      • cuddBddConstrainRecur() +
                      • cuddBddRestrictRecur() +
                      • cuddBddNPAndRecur() +
                      • cuddAddConstrainRecur() +
                      • cuddAddRestrictRecur() +
                      • cuddBddLICompaction() +
                      + Static procedures included in this module: +
                        +
                      • cuddBddConstrainDecomp() +
                      • cuddBddCharToVect() +
                      • cuddBddLICMarkEdges() +
                      • cuddBddLICBuildResult() +
                      • MarkCacheHash() +
                      • MarkCacheCompare() +
                      • MarkCacheCleanUp() +
                      • cuddBddSqueeze() +
                      + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Codes for edge markings in Cudd_bddLICompaction. The codes are defined +** so that they can be bitwise ORed to implement the code priority scheme. +*/ +#define DD_LIC_DC 0 +#define DD_LIC_1 1 +#define DD_LIC_0 2 +#define DD_LIC_NL 3 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/* Key for the cache used in the edge marking phase. */ +typedef struct MarkCacheKey { + DdNode *f; + DdNode *c; +} MarkCacheKey; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddGenCof.c,v 1.40 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddBddConstrainDecomp (DdManager *dd, DdNode *f, DdNode **decomp); +static DdNode * cuddBddCharToVect (DdManager *dd, DdNode *f, DdNode *x); +static int cuddBddLICMarkEdges (DdManager *dd, DdNode *f, DdNode *c, st_table *table, st_table *cache); +static DdNode * cuddBddLICBuildResult (DdManager *dd, DdNode *f, st_table *cache, st_table *table); +static int MarkCacheHash (char *ptr, int modulus); +static int MarkCacheCompare (const char *ptr1, const char *ptr2); +static enum st_retval MarkCacheCleanUp (char *key, char *value, char *arg); +static DdNode * cuddBddSqueeze (DdManager *dd, DdNode *l, DdNode *u); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes f constrain c.] + + Description [Computes f constrain c (f @ c). + Uses a canonical form: (f' @ c) = (f @ c)'. (Note: this is not true + for c.) List of special cases: +
                        +
                      • f @ 0 = 0 +
                      • f @ 1 = f +
                      • 0 @ c = 0 +
                      • 1 @ c = 1 +
                      • f @ f = 1 +
                      • f @ f'= 0 +
                      + Returns a pointer to the result if successful; NULL otherwise. Note that if + F=(f1,...,fn) and reordering takes place while computing F @ c, then the + image restriction property (Img(F,c) = Img(F @ c)) is lost.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict Cudd_addConstrain] + +******************************************************************************/ +DdNode * +Cudd_bddConstrain( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddConstrainRecur(dd,f,c); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddConstrain */ + + +/**Function******************************************************************** + + Synopsis [BDD restrict according to Coudert and Madre's algorithm + (ICCAD90).] + + Description [BDD restrict according to Coudert and Madre's algorithm + (ICCAD90). Returns the restricted BDD if successful; otherwise NULL. + If application of restrict results in a BDD larger than the input + BDD, the input BDD is returned.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_addRestrict] + +******************************************************************************/ +DdNode * +Cudd_bddRestrict( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *suppF, *suppC, *commonSupport; + DdNode *cplus, *res; + int retval; + int sizeF, sizeRes; + + /* Check terminal cases here to avoid computing supports in trivial cases. + ** This also allows us notto check later for the case c == 0, in which + ** there is no common support. */ + if (c == Cudd_Not(DD_ONE(dd))) return(Cudd_Not(DD_ONE(dd))); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(DD_ONE(dd)); + if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd))); + + /* Check if supports intersect. */ + retval = Cudd_ClassifySupport(dd,f,c,&commonSupport,&suppF,&suppC); + if (retval == 0) { + return(NULL); + } + cuddRef(commonSupport); cuddRef(suppF); cuddRef(suppC); + Cudd_IterDerefBdd(dd,suppF); + + if (commonSupport == DD_ONE(dd)) { + Cudd_IterDerefBdd(dd,commonSupport); + Cudd_IterDerefBdd(dd,suppC); + return(f); + } + Cudd_IterDerefBdd(dd,commonSupport); + + /* Abstract from c the variables that do not appear in f. */ + cplus = Cudd_bddExistAbstract(dd, c, suppC); + if (cplus == NULL) { + Cudd_IterDerefBdd(dd,suppC); + return(NULL); + } + cuddRef(cplus); + Cudd_IterDerefBdd(dd,suppC); + + do { + dd->reordered = 0; + res = cuddBddRestrictRecur(dd, f, cplus); + } while (dd->reordered == 1); + if (res == NULL) { + Cudd_IterDerefBdd(dd,cplus); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd,cplus); + /* Make restric safe by returning the smaller of the input and the + ** result. */ + sizeF = Cudd_DagSize(f); + sizeRes = Cudd_DagSize(res); + if (sizeF <= sizeRes) { + Cudd_IterDerefBdd(dd, res); + return(f); + } else { + cuddDeref(res); + return(res); + } + +} /* end of Cudd_bddRestrict */ + + +/**Function******************************************************************** + + Synopsis [Computes f non-polluting-and g.] + + Description [Computes f non-polluting-and g. The non-polluting AND + of f and g is a hybrid of AND and Restrict. From Restrict, this + operation takes the idea of existentially quantifying the top + variable of the second operand if it does not appear in the first. + Therefore, the variables that appear in the result also appear in f. + For the rest, the function behaves like AND. Since the two operands + play different roles, non-polluting AND is not commutative. + + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_bddNPAnd( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddNPAndRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddNPAnd */ + + +/**Function******************************************************************** + + Synopsis [Computes f constrain c for ADDs.] + + Description [Computes f constrain c (f @ c), for f an ADD and c a 0-1 + ADD. List of special cases: +
                        +
                      • F @ 0 = 0 +
                      • F @ 1 = F +
                      • 0 @ c = 0 +
                      • 1 @ c = 1 +
                      • F @ F = 1 +
                      + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain] + +******************************************************************************/ +DdNode * +Cudd_addConstrain( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddConstrainRecur(dd,f,c); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addConstrain */ + + +/**Function******************************************************************** + + Synopsis [BDD conjunctive decomposition as in McMillan's CAV96 paper.] + + Description [BDD conjunctive decomposition as in McMillan's CAV96 + paper. The decomposition is canonical only for a given variable + order. If canonicity is required, variable ordering must be disabled + after the decomposition has been computed. Returns an array with one + entry for each BDD variable in the manager if successful; otherwise + NULL. The components of the solution have their reference counts + already incremented (unlike the results of most other functions in + the package).] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_bddExistAbstract] + +******************************************************************************/ +DdNode ** +Cudd_bddConstrainDecomp( + DdManager * dd, + DdNode * f) +{ + DdNode **decomp; + int res; + int i; + + /* Create an initialize decomposition array. */ + decomp = ALLOC(DdNode *,dd->size); + if (decomp == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) { + decomp[i] = NULL; + } + do { + dd->reordered = 0; + /* Clean up the decomposition array in case reordering took place. */ + for (i = 0; i < dd->size; i++) { + if (decomp[i] != NULL) { + Cudd_IterDerefBdd(dd, decomp[i]); + decomp[i] = NULL; + } + } + res = cuddBddConstrainDecomp(dd,f,decomp); + } while (dd->reordered == 1); + if (res == 0) { + FREE(decomp); + return(NULL); + } + /* Missing components are constant ones. */ + for (i = 0; i < dd->size; i++) { + if (decomp[i] == NULL) { + decomp[i] = DD_ONE(dd); + cuddRef(decomp[i]); + } + } + return(decomp); + +} /* end of Cudd_bddConstrainDecomp */ + + +/**Function******************************************************************** + + Synopsis [ADD restrict according to Coudert and Madre's algorithm + (ICCAD90).] + + Description [ADD restrict according to Coudert and Madre's algorithm + (ICCAD90). Returns the restricted ADD if successful; otherwise NULL. + If application of restrict results in an ADD larger than the input + ADD, the input ADD is returned.] + + SideEffects [None] + + SeeAlso [Cudd_addConstrain Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_addRestrict( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *supp_f, *supp_c; + DdNode *res, *commonSupport; + int intersection; + int sizeF, sizeRes; + + /* Check if supports intersect. */ + supp_f = Cudd_Support(dd, f); + if (supp_f == NULL) { + return(NULL); + } + cuddRef(supp_f); + supp_c = Cudd_Support(dd, c); + if (supp_c == NULL) { + Cudd_RecursiveDeref(dd,supp_f); + return(NULL); + } + cuddRef(supp_c); + commonSupport = Cudd_bddLiteralSetIntersection(dd, supp_f, supp_c); + if (commonSupport == NULL) { + Cudd_RecursiveDeref(dd,supp_f); + Cudd_RecursiveDeref(dd,supp_c); + return(NULL); + } + cuddRef(commonSupport); + Cudd_RecursiveDeref(dd,supp_f); + Cudd_RecursiveDeref(dd,supp_c); + intersection = commonSupport != DD_ONE(dd); + Cudd_RecursiveDeref(dd,commonSupport); + + if (intersection) { + do { + dd->reordered = 0; + res = cuddAddRestrictRecur(dd, f, c); + } while (dd->reordered == 1); + sizeF = Cudd_DagSize(f); + sizeRes = Cudd_DagSize(res); + if (sizeF <= sizeRes) { + cuddRef(res); + Cudd_RecursiveDeref(dd, res); + return(f); + } else { + return(res); + } + } else { + return(f); + } + +} /* end of Cudd_addRestrict */ + + +/**Function******************************************************************** + + Synopsis [Computes a vector whose image equals a non-zero function.] + + Description [Computes a vector of BDDs whose image equals a non-zero + function. + The result depends on the variable order. The i-th component of the vector + depends only on the first i variables in the order. Each BDD in the vector + is not larger than the BDD of the given characteristic function. This + function is based on the description of char-to-vect in "Verification of + Sequential Machines Using Boolean Functional Vectors" by O. Coudert, C. + Berthet and J. C. Madre. + Returns a pointer to an array containing the result if successful; NULL + otherwise. The size of the array equals the number of variables in the + manager. The components of the solution have their reference counts + already incremented (unlike the results of most other functions in + the package).] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain] + +******************************************************************************/ +DdNode ** +Cudd_bddCharToVect( + DdManager * dd, + DdNode * f) +{ + int i, j; + DdNode **vect; + DdNode *res = NULL; + + if (f == Cudd_Not(DD_ONE(dd))) return(NULL); + + vect = ALLOC(DdNode *, dd->size); + if (vect == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + do { + dd->reordered = 0; + for (i = 0; i < dd->size; i++) { + res = cuddBddCharToVect(dd,f,dd->vars[dd->invperm[i]]); + if (res == NULL) { + /* Clean up the vector array in case reordering took place. */ + for (j = 0; j < i; j++) { + Cudd_IterDerefBdd(dd, vect[dd->invperm[j]]); + } + break; + } + cuddRef(res); + vect[dd->invperm[i]] = res; + } + } while (dd->reordered == 1); + if (res == NULL) { + FREE(vect); + return(NULL); + } + return(vect); + +} /* end of Cudd_bddCharToVect */ + + +/**Function******************************************************************** + + Synopsis [Performs safe minimization of a BDD.] + + Description [Performs safe minimization of a BDD. Given the BDD + f of a function to be minimized and a BDD + c representing the care set, Cudd_bddLICompaction + produces the BDD of a function that agrees with f + wherever c is 1. Safe minimization means that the size + of the result is guaranteed not to exceed the size of + f. This function is based on the DAC97 paper by Hong et + al.. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_bddLICompaction( + DdManager * dd /* manager */, + DdNode * f /* function to be minimized */, + DdNode * c /* constraint (care set) */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddLICompaction(dd,f,c); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddLICompaction */ + + +/**Function******************************************************************** + + Synopsis [Finds a small BDD in a function interval.] + + Description [Finds a small BDD in a function interval. Given BDDs + l and u, representing the lower bound and + upper bound of a function interval, Cudd_bddSqueeze produces the BDD + of a function within the interval with a small BDD. Returns a + pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction] + +******************************************************************************/ +DdNode * +Cudd_bddSqueeze( + DdManager * dd /* manager */, + DdNode * l /* lower bound */, + DdNode * u /* upper bound */) +{ + DdNode *res; + int sizeRes, sizeL, sizeU; + + do { + dd->reordered = 0; + res = cuddBddSqueeze(dd,l,u); + } while (dd->reordered == 1); + if (res == NULL) return(NULL); + /* We now compare the result with the bounds and return the smallest. + ** We first compare to u, so that in case l == 0 and u == 1, we return + ** 0 as in other minimization algorithms. */ + sizeRes = Cudd_DagSize(res); + sizeU = Cudd_DagSize(u); + if (sizeU <= sizeRes) { + cuddRef(res); + Cudd_IterDerefBdd(dd,res); + res = u; + sizeRes = sizeU; + } + sizeL = Cudd_DagSize(l); + if (sizeL <= sizeRes) { + cuddRef(res); + Cudd_IterDerefBdd(dd,res); + res = l; + sizeRes = sizeL; + } + return(res); + +} /* end of Cudd_bddSqueeze */ + + +/**Function******************************************************************** + + Synopsis [Finds a small BDD that agrees with f over + c.] + + Description [Finds a small BDD that agrees with f over + c. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction Cudd_bddSqueeze] + +******************************************************************************/ +DdNode * +Cudd_bddMinimize( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *cplus, *res; + + if (c == Cudd_Not(DD_ONE(dd))) return(c); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(DD_ONE(dd)); + if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd))); + + cplus = Cudd_RemapOverApprox(dd,c,0,0,1.0); + if (cplus == NULL) return(NULL); + cuddRef(cplus); + res = Cudd_bddLICompaction(dd,f,cplus); + if (res == NULL) { + Cudd_IterDerefBdd(dd,cplus); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd,cplus); + cuddDeref(res); + return(res); + +} /* end of Cudd_bddMinimize */ + + +/**Function******************************************************************** + + Synopsis [Find a dense subset of BDD f.] + + Description [Finds a dense subset of BDD f. Density is + the ratio of number of minterms to number of nodes. Uses several + techniques in series. It is more expensive than other subsetting + procedures, but often produces better results. See + Cudd_SubsetShortPaths for a description of the threshold and nvars + parameters. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_RemapUnderApprox Cudd_SubsetShortPaths + Cudd_SubsetHeavyBranch Cudd_bddSqueeze] + +******************************************************************************/ +DdNode * +Cudd_SubsetCompress( + DdManager * dd /* manager */, + DdNode * f /* BDD whose subset is sought */, + int nvars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the subset */) +{ + DdNode *res, *tmp1, *tmp2; + + tmp1 = Cudd_SubsetShortPaths(dd, f, nvars, threshold, 0); + if (tmp1 == NULL) return(NULL); + cuddRef(tmp1); + tmp2 = Cudd_RemapUnderApprox(dd,tmp1,nvars,0,0.95); + if (tmp2 == NULL) { + Cudd_IterDerefBdd(dd,tmp1); + return(NULL); + } + cuddRef(tmp2); + Cudd_IterDerefBdd(dd,tmp1); + res = Cudd_bddSqueeze(dd,tmp2,f); + if (res == NULL) { + Cudd_IterDerefBdd(dd,tmp2); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd,tmp2); + cuddDeref(res); + return(res); + +} /* end of Cudd_SubsetCompress */ + + +/**Function******************************************************************** + + Synopsis [Find a dense superset of BDD f.] + + Description [Finds a dense superset of BDD f. Density is + the ratio of number of minterms to number of nodes. Uses several + techniques in series. It is more expensive than other supersetting + procedures, but often produces better results. See + Cudd_SupersetShortPaths for a description of the threshold and nvars + parameters. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetCompress Cudd_SupersetRemap Cudd_SupersetShortPaths + Cudd_SupersetHeavyBranch Cudd_bddSqueeze] + +******************************************************************************/ +DdNode * +Cudd_SupersetCompress( + DdManager * dd /* manager */, + DdNode * f /* BDD whose superset is sought */, + int nvars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the superset */) +{ + DdNode *subset; + + subset = Cudd_SubsetCompress(dd, Cudd_Not(f),nvars,threshold); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_SupersetCompress */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddConstrain.] + + Description [Performs the recursive step of Cudd_bddConstrain. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain] + +******************************************************************************/ +DdNode * +cuddBddConstrainRecur( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r; + DdNode *one, *zero; + unsigned int topf, topc; + int index; + int comple = 0; + + statLine(dd); + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Trivial cases. */ + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + if (f == Cudd_Not(c)) return(zero); + + /* Make canonical to increase the utilization of the cache. */ + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + comple = 1; + } + /* Now f is a regular pointer to a non-constant node; c is also + ** non-constant, but may be complemented. + */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_bddConstrain, f, c); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + /* Recursive step. */ + topf = dd->perm[f->index]; + topc = dd->perm[Cudd_Regular(c)->index]; + if (topf <= topc) { + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + index = Cudd_Regular(c)->index; + Fv = Fnv = f; + } + if (topc <= topf) { + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } + } else { + Cv = Cnv = c; + } + + if (!Cudd_IsConstant(Cv)) { + t = cuddBddConstrainRecur(dd, Fv, Cv); + if (t == NULL) + return(NULL); + } else if (Cv == one) { + t = Fv; + } else { /* Cv == zero: return Fnv @ Cnv */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddBddConstrainRecur(dd, Fnv, Cnv); + if (r == NULL) + return(NULL); + } + return(Cudd_NotCond(r,comple)); + } + cuddRef(t); + + if (!Cudd_IsConstant(Cnv)) { + e = cuddBddConstrainRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } else if (Cnv == one) { + e = Fnv; + } else { /* Cnv == zero: return Fv @ Cv previously computed */ + cuddDeref(t); + return(Cudd_NotCond(t,comple)); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd, Cudd_bddConstrain, f, c, r); + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddConstrainRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddRestrict.] + + Description [Performs the recursive step of Cudd_bddRestrict. + Returns the restricted BDD if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +cuddBddRestrictRecur( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; + unsigned int topf, topc; + int index; + int comple = 0; + + statLine(dd); + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Trivial cases */ + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + if (f == Cudd_Not(c)) return(zero); + + /* Make canonical to increase the utilization of the cache. */ + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + comple = 1; + } + /* Now f is a regular pointer to a non-constant node; c is also + ** non-constant, but may be complemented. + */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_bddRestrict, f, c); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + topf = dd->perm[f->index]; + topc = dd->perm[Cudd_Regular(c)->index]; + + if (topc < topf) { /* abstract top variable from c */ + DdNode *d, *s1, *s2; + + /* Find complements of cofactors of c. */ + if (Cudd_IsComplement(c)) { + s1 = cuddT(Cudd_Regular(c)); + s2 = cuddE(Cudd_Regular(c)); + } else { + s1 = Cudd_Not(cuddT(c)); + s2 = Cudd_Not(cuddE(c)); + } + /* Take the OR by applying DeMorgan. */ + d = cuddBddAndRecur(dd, s1, s2); + if (d == NULL) return(NULL); + d = Cudd_Not(d); + cuddRef(d); + r = cuddBddRestrictRecur(dd, f, d); + if (r == NULL) { + Cudd_IterDerefBdd(dd, d); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, d); + cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r); + cuddDeref(r); + return(Cudd_NotCond(r,comple)); + } + + /* Recursive step. Here topf <= topc. */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + if (topc == topf) { + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } + } else { + Cv = Cnv = c; + } + + if (!Cudd_IsConstant(Cv)) { + t = cuddBddRestrictRecur(dd, Fv, Cv); + if (t == NULL) return(NULL); + } else if (Cv == one) { + t = Fv; + } else { /* Cv == zero: return(Fnv @ Cnv) */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddBddRestrictRecur(dd, Fnv, Cnv); + if (r == NULL) return(NULL); + } + return(Cudd_NotCond(r,comple)); + } + cuddRef(t); + + if (!Cudd_IsConstant(Cnv)) { + e = cuddBddRestrictRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } else if (Cnv == one) { + e = Fnv; + } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ + cuddDeref(t); + return(Cudd_NotCond(t,comple)); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r); + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddRestrictRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddAnd.] + + Description [Implements the recursive step of Cudd_bddNPAnd. + Returns a pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNPAnd] + +******************************************************************************/ +DdNode * +cuddBddNPAndRecur( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *r, *t, *e; + unsigned int topf, topg, index; + + statLine(manager); + one = DD_ONE(manager); + + /* Terminal cases. */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + if (F == G) { + if (f == g) return(one); + else return(Cudd_Not(one)); + } + if (G == one) { + if (g == one) return(f); + else return(g); + } + if (F == one) { + return(f); + } + + /* At this point f and g are not constant. */ + /* Check cache. */ + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup2(manager, Cudd_bddNPAnd, f, g); + if (r != NULL) return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + + if (topg < topf) { /* abstract top variable from g */ + DdNode *d; + + /* Find complements of cofactors of g. */ + if (Cudd_IsComplement(g)) { + gt = cuddT(G); + ge = cuddE(G); + } else { + gt = Cudd_Not(cuddT(g)); + ge = Cudd_Not(cuddE(g)); + } + /* Take the OR by applying DeMorgan. */ + d = cuddBddAndRecur(manager, gt, ge); + if (d == NULL) return(NULL); + d = Cudd_Not(d); + cuddRef(d); + r = cuddBddNPAndRecur(manager, f, d); + if (r == NULL) { + Cudd_IterDerefBdd(manager, d); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(manager, d); + cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r); + cuddDeref(r); + return(r); + } + + /* Compute cofactors. */ + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + + if (topg == topf) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + t = cuddBddAndRecur(manager, ft, gt); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddAndRecur(manager, fe, ge); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r); + return(r); + +} /* end of cuddBddNPAndRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addConstrain.] + + Description [Performs the recursive step of Cudd_addConstrain. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addConstrain] + +******************************************************************************/ +DdNode * +cuddAddConstrainRecur( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r; + DdNode *one, *zero; + unsigned int topf, topc; + int index; + + statLine(dd); + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + /* Trivial cases. */ + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + + /* Now f and c are non-constant. */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_addConstrain, f, c); + if (r != NULL) { + return(r); + } + + /* Recursive step. */ + topf = dd->perm[f->index]; + topc = dd->perm[c->index]; + if (topf <= topc) { + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + index = c->index; + Fv = Fnv = f; + } + if (topc <= topf) { + Cv = cuddT(c); Cnv = cuddE(c); + } else { + Cv = Cnv = c; + } + + if (!Cudd_IsConstant(Cv)) { + t = cuddAddConstrainRecur(dd, Fv, Cv); + if (t == NULL) + return(NULL); + } else if (Cv == one) { + t = Fv; + } else { /* Cv == zero: return Fnv @ Cnv */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddAddConstrainRecur(dd, Fnv, Cnv); + if (r == NULL) + return(NULL); + } + return(r); + } + cuddRef(t); + + if (!Cudd_IsConstant(Cnv)) { + e = cuddAddConstrainRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } else if (Cnv == one) { + e = Fnv; + } else { /* Cnv == zero: return Fv @ Cv previously computed */ + cuddDeref(t); + return(t); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd, Cudd_addConstrain, f, c, r); + return(r); + +} /* end of cuddAddConstrainRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addRestrict.] + + Description [Performs the recursive step of Cudd_addRestrict. + Returns the restricted ADD if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_addRestrict] + +******************************************************************************/ +DdNode * +cuddAddRestrictRecur( + DdManager * dd, + DdNode * f, + DdNode * c) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; + unsigned int topf, topc; + int index; + + statLine(dd); + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + /* Trivial cases */ + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + + /* Now f and c are non-constant. */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_addRestrict, f, c); + if (r != NULL) { + return(r); + } + + topf = dd->perm[f->index]; + topc = dd->perm[c->index]; + + if (topc < topf) { /* abstract top variable from c */ + DdNode *d, *s1, *s2; + + /* Find cofactors of c. */ + s1 = cuddT(c); + s2 = cuddE(c); + /* Take the OR by applying DeMorgan. */ + d = cuddAddApplyRecur(dd, Cudd_addOr, s1, s2); + if (d == NULL) return(NULL); + cuddRef(d); + r = cuddAddRestrictRecur(dd, f, d); + if (r == NULL) { + Cudd_RecursiveDeref(dd, d); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDeref(dd, d); + cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r); + cuddDeref(r); + return(r); + } + + /* Recursive step. Here topf <= topc. */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + if (topc == topf) { + Cv = cuddT(c); Cnv = cuddE(c); + } else { + Cv = Cnv = c; + } + + if (!Cudd_IsConstant(Cv)) { + t = cuddAddRestrictRecur(dd, Fv, Cv); + if (t == NULL) return(NULL); + } else if (Cv == one) { + t = Fv; + } else { /* Cv == zero: return(Fnv @ Cnv) */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddAddRestrictRecur(dd, Fnv, Cnv); + if (r == NULL) return(NULL); + } + return(r); + } + cuddRef(t); + + if (!Cudd_IsConstant(Cnv)) { + e = cuddAddRestrictRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } else if (Cnv == one) { + e = Fnv; + } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ + cuddDeref(t); + return(t); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r); + return(r); + +} /* end of cuddAddRestrictRecur */ + + + +/**Function******************************************************************** + + Synopsis [Performs safe minimization of a BDD.] + + Description [Performs safe minimization of a BDD. Given the BDD + f of a function to be minimized and a BDD + c representing the care set, Cudd_bddLICompaction + produces the BDD of a function that agrees with f + wherever c is 1. Safe minimization means that the size + of the result is guaranteed not to exceed the size of + f. This function is based on the DAC97 paper by Hong et + al.. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction] + +******************************************************************************/ +DdNode * +cuddBddLICompaction( + DdManager * dd /* manager */, + DdNode * f /* function to be minimized */, + DdNode * c /* constraint (care set) */) +{ + st_table *marktable, *markcache, *buildcache; + DdNode *res, *zero; + + zero = Cudd_Not(DD_ONE(dd)); + if (c == zero) return(zero); + + /* We need to use local caches for both steps of this operation. + ** The results of the edge marking step are only valid as long as the + ** edge markings themselves are available. However, the edge markings + ** are lost at the end of one invocation of Cudd_bddLICompaction. + ** Hence, the cache entries for the edge marking step must be + ** invalidated at the end of this function. + ** For the result of the building step we argue as follows. The result + ** for a node and a given constrain depends on the BDD in which the node + ** appears. Hence, the same node and constrain may give different results + ** in successive invocations. + */ + marktable = st_init_table(st_ptrcmp,st_ptrhash); + if (marktable == NULL) { + return(NULL); + } + markcache = st_init_table(MarkCacheCompare,MarkCacheHash); + if (markcache == NULL) { + st_free_table(marktable); + return(NULL); + } + if (cuddBddLICMarkEdges(dd,f,c,marktable,markcache) == CUDD_OUT_OF_MEM) { + st_foreach(markcache, MarkCacheCleanUp, NULL); + st_free_table(marktable); + st_free_table(markcache); + return(NULL); + } + st_foreach(markcache, MarkCacheCleanUp, NULL); + st_free_table(markcache); + buildcache = st_init_table(st_ptrcmp,st_ptrhash); + if (buildcache == NULL) { + st_free_table(marktable); + return(NULL); + } + res = cuddBddLICBuildResult(dd,f,buildcache,marktable); + st_free_table(buildcache); + st_free_table(marktable); + return(res); + +} /* end of cuddBddLICompaction */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddConstrainDecomp.] + + Description [Performs the recursive step of Cudd_bddConstrainDecomp. + Returns f super (i) if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrainDecomp] + +******************************************************************************/ +static int +cuddBddConstrainDecomp( + DdManager * dd, + DdNode * f, + DdNode ** decomp) +{ + DdNode *F, *fv, *fvn; + DdNode *fAbs; + DdNode *result; + int ok; + + if (Cudd_IsConstant(f)) return(1); + /* Compute complements of cofactors. */ + F = Cudd_Regular(f); + fv = cuddT(F); + fvn = cuddE(F); + if (F == f) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + /* Compute abstraction of top variable. */ + fAbs = cuddBddAndRecur(dd, fv, fvn); + if (fAbs == NULL) { + return(0); + } + cuddRef(fAbs); + fAbs = Cudd_Not(fAbs); + /* Recursively find the next abstraction and the components of the + ** decomposition. */ + ok = cuddBddConstrainDecomp(dd, fAbs, decomp); + if (ok == 0) { + Cudd_IterDerefBdd(dd,fAbs); + return(0); + } + /* Compute the component of the decomposition corresponding to the + ** top variable and store it in the decomposition array. */ + result = cuddBddConstrainRecur(dd, f, fAbs); + if (result == NULL) { + Cudd_IterDerefBdd(dd,fAbs); + return(0); + } + cuddRef(result); + decomp[F->index] = result; + Cudd_IterDerefBdd(dd, fAbs); + return(1); + +} /* end of cuddBddConstrainDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCharToVect.] + + Description [Performs the recursive step of Cudd_bddCharToVect. + This function maintains the invariant that f is non-zero. + Returns the i-th component of the vector if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddCharToVect] + +******************************************************************************/ +static DdNode * +cuddBddCharToVect( + DdManager * dd, + DdNode * f, + DdNode * x) +{ + unsigned int topf; + unsigned int level; + int comple; + + DdNode *one, *zero, *res, *F, *fT, *fE, *T, *E; + + statLine(dd); + /* Check the cache. */ + res = cuddCacheLookup2(dd, cuddBddCharToVect, f, x); + if (res != NULL) { + return(res); + } + + F = Cudd_Regular(f); + + topf = cuddI(dd,F->index); + level = dd->perm[x->index]; + + if (topf > level) return(x); + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + comple = F != f; + fT = Cudd_NotCond(cuddT(F),comple); + fE = Cudd_NotCond(cuddE(F),comple); + + if (topf == level) { + if (fT == zero) return(zero); + if (fE == zero) return(one); + return(x); + } + + /* Here topf < level. */ + if (fT == zero) return(cuddBddCharToVect(dd, fE, x)); + if (fE == zero) return(cuddBddCharToVect(dd, fT, x)); + + T = cuddBddCharToVect(dd, fT, x); + if (T == NULL) { + return(NULL); + } + cuddRef(T); + E = cuddBddCharToVect(dd, fE, x); + if (E == NULL) { + Cudd_IterDerefBdd(dd,T); + return(NULL); + } + cuddRef(E); + res = cuddBddIteRecur(dd, dd->vars[F->index], T, E); + if (res == NULL) { + Cudd_IterDerefBdd(dd,T); + Cudd_IterDerefBdd(dd,E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + cuddCacheInsert2(dd, cuddBddCharToVect, f, x, res); + return(res); + +} /* end of cuddBddCharToVect */ + + +/**Function******************************************************************** + + Synopsis [Performs the edge marking step of Cudd_bddLICompaction.] + + Description [Performs the edge marking step of Cudd_bddLICompaction. + Returns the LUB of the markings of the two outgoing edges of f + if successful; otherwise CUDD_OUT_OF_MEM.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction cuddBddLICBuildResult] + +******************************************************************************/ +static int +cuddBddLICMarkEdges( + DdManager * dd, + DdNode * f, + DdNode * c, + st_table * table, + st_table * cache) +{ + DdNode *Fv, *Fnv, *Cv, *Cnv; + DdNode *one, *zero; + unsigned int topf, topc; + int comple; + int resT, resE, res, retval; + char **slot; + MarkCacheKey *key; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (c == zero) return(DD_LIC_DC); + if (f == one) return(DD_LIC_1); + if (f == zero) return(DD_LIC_0); + + /* Make canonical to increase the utilization of the cache. */ + comple = Cudd_IsComplement(f); + f = Cudd_Regular(f); + /* Now f is a regular pointer to a non-constant node; c may be + ** constant, or it may be complemented. + */ + + /* Check the cache. */ + key = ALLOC(MarkCacheKey, 1); + if (key == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + key->f = f; key->c = c; + if (st_lookup_int(cache, (char *)key, &res)) { + FREE(key); + if (comple) { + if (res == DD_LIC_0) res = DD_LIC_1; + else if (res == DD_LIC_1) res = DD_LIC_0; + } + return(res); + } + + /* Recursive step. */ + topf = dd->perm[f->index]; + topc = cuddI(dd,Cudd_Regular(c)->index); + if (topf <= topc) { + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topc <= topf) { + /* We know that c is not constant because f is not. */ + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } + } else { + Cv = Cnv = c; + } + + resT = cuddBddLICMarkEdges(dd, Fv, Cv, table, cache); + if (resT == CUDD_OUT_OF_MEM) { + FREE(key); + return(CUDD_OUT_OF_MEM); + } + resE = cuddBddLICMarkEdges(dd, Fnv, Cnv, table, cache); + if (resE == CUDD_OUT_OF_MEM) { + FREE(key); + return(CUDD_OUT_OF_MEM); + } + + /* Update edge markings. */ + if (topf <= topc) { + retval = st_find_or_add(table, (char *)f, (char ***)&slot); + if (retval == 0) { + *slot = (char *) (ptrint)((resT << 2) | resE); + } else if (retval == 1) { + *slot = (char *) (ptrint)((int)((ptrint) *slot) | (resT << 2) | resE); + } else { + FREE(key); + return(CUDD_OUT_OF_MEM); + } + } + + /* Cache result. */ + res = resT | resE; + if (st_insert(cache, (char *)key, (char *)(ptrint)res) == ST_OUT_OF_MEM) { + FREE(key); + return(CUDD_OUT_OF_MEM); + } + + /* Take into account possible complementation. */ + if (comple) { + if (res == DD_LIC_0) res = DD_LIC_1; + else if (res == DD_LIC_1) res = DD_LIC_0; + } + return(res); + +} /* end of cuddBddLICMarkEdges */ + + +/**Function******************************************************************** + + Synopsis [Builds the result of Cudd_bddLICompaction.] + + Description [Builds the results of Cudd_bddLICompaction. + Returns a pointer to the minimized BDD if successful; otherwise NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction cuddBddLICMarkEdges] + +******************************************************************************/ +static DdNode * +cuddBddLICBuildResult( + DdManager * dd, + DdNode * f, + st_table * cache, + st_table * table) +{ + DdNode *Fv, *Fnv, *r, *t, *e; + DdNode *one, *zero; + int index; + int comple; + int markT, markE, markings; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + if (Cudd_IsConstant(f)) return(f); + /* Make canonical to increase the utilization of the cache. */ + comple = Cudd_IsComplement(f); + f = Cudd_Regular(f); + + /* Check the cache. */ + if (st_lookup(cache, f, &r)) { + return(Cudd_NotCond(r,comple)); + } + + /* Retrieve the edge markings. */ + if (st_lookup_int(table, (char *)f, &markings) == 0) + return(NULL); + markT = markings >> 2; + markE = markings & 3; + + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + + if (markT == DD_LIC_NL) { + t = cuddBddLICBuildResult(dd,Fv,cache,table); + if (t == NULL) { + return(NULL); + } + } else if (markT == DD_LIC_1) { + t = one; + } else { + t = zero; + } + cuddRef(t); + if (markE == DD_LIC_NL) { + e = cuddBddLICBuildResult(dd,Fnv,cache,table); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } + } else if (markE == DD_LIC_1) { + e = one; + } else { + e = zero; + } + cuddRef(e); + + if (markT == DD_LIC_DC && markE != DD_LIC_DC) { + r = e; + } else if (markT != DD_LIC_DC && markE == DD_LIC_DC) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + } + cuddDeref(t); + cuddDeref(e); + + if (st_insert(cache, (char *)f, (char *)r) == ST_OUT_OF_MEM) { + cuddRef(r); + Cudd_IterDerefBdd(dd,r); + return(NULL); + } + + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddLICBuildResult */ + + +/**Function******************************************************************** + + Synopsis [Hash function for the computed table of cuddBddLICMarkEdges.] + + Description [Hash function for the computed table of + cuddBddLICMarkEdges. Returns the bucket number.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction] + +******************************************************************************/ +static int +MarkCacheHash( + char * ptr, + int modulus) +{ + int val = 0; + MarkCacheKey *entry; + + entry = (MarkCacheKey *) ptr; + + val = (int) (ptrint) entry->f; + val = val * 997 + (int) (ptrint) entry->c; + + return ((val < 0) ? -val : val) % modulus; + +} /* end of MarkCacheHash */ + + +/**Function******************************************************************** + + Synopsis [Comparison function for the computed table of + cuddBddLICMarkEdges.] + + Description [Comparison function for the computed table of + cuddBddLICMarkEdges. Returns 0 if the two nodes of the key are equal; 1 + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction] + +******************************************************************************/ +static int +MarkCacheCompare( + const char * ptr1, + const char * ptr2) +{ + MarkCacheKey *entry1, *entry2; + + entry1 = (MarkCacheKey *) ptr1; + entry2 = (MarkCacheKey *) ptr2; + + return((entry1->f != entry2->f) || (entry1->c != entry2->c)); + +} /* end of MarkCacheCompare */ + + +/**Function******************************************************************** + + Synopsis [Frees memory associated with computed table of + cuddBddLICMarkEdges.] + + Description [Frees memory associated with computed table of + cuddBddLICMarkEdges. Returns ST_CONTINUE.] + + SideEffects [None] + + SeeAlso [Cudd_bddLICompaction] + +******************************************************************************/ +static enum st_retval +MarkCacheCleanUp( + char * key, + char * value, + char * arg) +{ + MarkCacheKey *entry; + + entry = (MarkCacheKey *) key; + FREE(entry); + return ST_CONTINUE; + +} /* end of MarkCacheCleanUp */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddSqueeze.] + + Description [Performs the recursive step of Cudd_bddSqueeze. This + procedure exploits the fact that if we complement and swap the + bounds of the interval we obtain a valid solution by taking the + complement of the solution to the original problem. Therefore, we + can enforce the condition that the upper bound is always regular. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddSqueeze] + +******************************************************************************/ +static DdNode * +cuddBddSqueeze( + DdManager * dd, + DdNode * l, + DdNode * u) +{ + DdNode *one, *zero, *r, *lt, *le, *ut, *ue, *t, *e; +#if 0 + DdNode *ar; +#endif + int comple = 0; + unsigned int topu, topl; + int index; + + statLine(dd); + if (l == u) { + return(l); + } + one = DD_ONE(dd); + zero = Cudd_Not(one); + /* The only case when l == zero && u == one is at the top level, + ** where returning either one or zero is OK. In all other cases + ** the procedure will detect such a case and will perform + ** remapping. Therefore the order in which we test l and u at this + ** point is immaterial. */ + if (l == zero) return(l); + if (u == one) return(u); + + /* Make canonical to increase the utilization of the cache. */ + if (Cudd_IsComplement(u)) { + DdNode *temp; + temp = Cudd_Not(l); + l = Cudd_Not(u); + u = temp; + comple = 1; + } + /* At this point u is regular and non-constant; l is non-constant, but + ** may be complemented. */ + + /* Here we could check the relative sizes. */ + + /* Check the cache. */ + r = cuddCacheLookup2(dd, Cudd_bddSqueeze, l, u); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + /* Recursive step. */ + topu = dd->perm[u->index]; + topl = dd->perm[Cudd_Regular(l)->index]; + if (topu <= topl) { + index = u->index; + ut = cuddT(u); ue = cuddE(u); + } else { + index = Cudd_Regular(l)->index; + ut = ue = u; + } + if (topl <= topu) { + lt = cuddT(Cudd_Regular(l)); le = cuddE(Cudd_Regular(l)); + if (Cudd_IsComplement(l)) { + lt = Cudd_Not(lt); + le = Cudd_Not(le); + } + } else { + lt = le = l; + } + + /* If one interval is contained in the other, use the smaller + ** interval. This corresponds to one-sided matching. */ + if ((lt == zero || Cudd_bddLeq(dd,lt,le)) && + (ut == one || Cudd_bddLeq(dd,ue,ut))) { /* remap */ + r = cuddBddSqueeze(dd, le, ue); + if (r == NULL) + return(NULL); + return(Cudd_NotCond(r,comple)); + } else if ((le == zero || Cudd_bddLeq(dd,le,lt)) && + (ue == one || Cudd_bddLeq(dd,ut,ue))) { /* remap */ + r = cuddBddSqueeze(dd, lt, ut); + if (r == NULL) + return(NULL); + return(Cudd_NotCond(r,comple)); + } else if ((le == zero || Cudd_bddLeq(dd,le,Cudd_Not(ut))) && + (ue == one || Cudd_bddLeq(dd,Cudd_Not(lt),ue))) { /* c-remap */ + t = cuddBddSqueeze(dd, lt, ut); + cuddRef(t); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(dd, index, Cudd_Not(t), t); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(dd, index, t, Cudd_Not(t)); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddDeref(t); + if (r == NULL) + return(NULL); + cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); + return(Cudd_NotCond(r,comple)); + } else if ((lt == zero || Cudd_bddLeq(dd,lt,Cudd_Not(ue))) && + (ut == one || Cudd_bddLeq(dd,Cudd_Not(le),ut))) { /* c-remap */ + e = cuddBddSqueeze(dd, le, ue); + cuddRef(e); + if (Cudd_IsComplement(e)) { + r = cuddUniqueInter(dd, index, Cudd_Not(e), e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + } else { + r = cuddUniqueInter(dd, index, e, Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + r = Cudd_Not(r); + } + cuddDeref(e); + if (r == NULL) + return(NULL); + cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); + return(Cudd_NotCond(r,comple)); + } + +#if 0 + /* If the two intervals intersect, take a solution from + ** the intersection of the intervals. This guarantees that the + ** splitting variable will not appear in the result. + ** This approach corresponds to two-sided matching, and is very + ** expensive. */ + if (Cudd_bddLeq(dd,lt,ue) && Cudd_bddLeq(dd,le,ut)) { + DdNode *au, *al; + au = cuddBddAndRecur(dd,ut,ue); + if (au == NULL) + return(NULL); + cuddRef(au); + al = cuddBddAndRecur(dd,Cudd_Not(lt),Cudd_Not(le)); + if (al == NULL) { + Cudd_IterDerefBdd(dd,au); + return(NULL); + } + cuddRef(al); + al = Cudd_Not(al); + ar = cuddBddSqueeze(dd, al, au); + if (ar == NULL) { + Cudd_IterDerefBdd(dd,au); + Cudd_IterDerefBdd(dd,al); + return(NULL); + } + cuddRef(ar); + Cudd_IterDerefBdd(dd,au); + Cudd_IterDerefBdd(dd,al); + } else { + ar = NULL; + } +#endif + + t = cuddBddSqueeze(dd, lt, ut); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + e = cuddBddSqueeze(dd, le, ue); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + +#if 0 + /* Check whether there is a result obtained by abstraction and whether + ** it is better than the one obtained by recursion. */ + cuddRef(r); + if (ar != NULL) { + if (Cudd_DagSize(ar) <= Cudd_DagSize(r)) { + Cudd_IterDerefBdd(dd, r); + r = ar; + } else { + Cudd_IterDerefBdd(dd, ar); + } + } + cuddDeref(r); +#endif + + cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddSqueeze */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddGenetic.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddGenetic.c new file mode 100644 index 000000000..8b259fe70 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddGenetic.c @@ -0,0 +1,960 @@ +/**CFile*********************************************************************** + + FileName [cuddGenetic.c] + + PackageName [cudd] + + Synopsis [Genetic algorithm for variable reordering.] + + Description [Internal procedures included in this file: +
                        +
                      • cuddGa() +
                      + Static procedures included in this module: +
                        +
                      • make_random() +
                      • sift_up() +
                      • build_dd() +
                      • largest() +
                      • rand_int() +
                      • array_hash() +
                      • array_compare() +
                      • find_best() +
                      • find_average_fitness() +
                      • PMX() +
                      • roulette() +
                      + + The genetic algorithm implemented here is as follows. We start with + the current DD order. We sift this order and use this as the + reference DD. We only keep 1 DD around for the entire process and + simply rearrange the order of this DD, storing the various orders + and their corresponding DD sizes. We generate more random orders to + build an initial population. This initial population is 3 times the + number of variables, with a maximum of 120. Each random order is + built (from the reference DD) and its size stored. Each random + order is also sifted to keep the DD sizes fairly small. Then a + crossover is performed between two orders (picked randomly) and the + two resulting DDs are built and sifted. For each new order, if its + size is smaller than any DD in the population, it is inserted into + the population and the DD with the largest number of nodes is thrown + out. The crossover process happens up to 50 times, and at this point + the DD in the population with the smallest size is chosen as the + result. This DD must then be built from the reference DD.] + + SeeAlso [] + + Author [Curt Musfeldt, Alan Shuler, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddGenetic.c,v 1.30 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static int popsize; /* the size of the population */ +static int numvars; /* the number of input variables in the ckt. */ +/* storedd stores the population orders and sizes. This table has two +** extra rows and one extras column. The two extra rows are used for the +** offspring produced by a crossover. Each row stores one order and its +** size. The order is stored by storing the indices of variables in the +** order in which they appear in the order. The table is in reality a +** one-dimensional array which is accessed via a macro to give the illusion +** it is a two-dimensional structure. +*/ +static int *storedd; +static st_table *computed; /* hash table to identify existing orders */ +static int *repeat; /* how many times an order is present */ +static int large; /* stores the index of the population with + ** the largest number of nodes in the DD */ +static int result; +static int cross; /* the number of crossovers to perform */ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/* macro used to access the population table as if it were a +** two-dimensional structure. +*/ +#define STOREDD(i,j) storedd[(i)*(numvars+1)+(j)] + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int make_random (DdManager *table, int lower); +static int sift_up (DdManager *table, int x, int x_low); +static int build_dd (DdManager *table, int num, int lower, int upper); +static int largest (void); +static int rand_int (int a); +static int array_hash (char *array, int modulus); +static int array_compare (const char *array1, const char *array2); +static int find_best (void); +#ifdef DD_STATS +static double find_average_fitness (void); +#endif +static int PMX (int maxvar); +static int roulette (int *p1, int *p2); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Genetic algorithm for DD reordering.] + + Description [Genetic algorithm for DD reordering. + The two children of a crossover will be stored in + storedd[popsize] and storedd[popsize+1] --- the last two slots in the + storedd array. (This will make comparisons and replacement easy.) + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddGa( + DdManager * table /* manager */, + int lower /* lowest level to be reordered */, + int upper /* highest level to be reorderded */) +{ + int i,n,m; /* dummy/loop vars */ + int index; +#ifdef DD_STATS + double average_fitness; +#endif + int small; /* index of smallest DD in population */ + + /* Do an initial sifting to produce at least one reasonable individual. */ + if (!cuddSifting(table,lower,upper)) return(0); + + /* Get the initial values. */ + numvars = upper - lower + 1; /* number of variables to be reordered */ + if (table->populationSize == 0) { + popsize = 3 * numvars; /* population size is 3 times # of vars */ + if (popsize > 120) { + popsize = 120; /* Maximum population size is 120 */ + } + } else { + popsize = table->populationSize; /* user specified value */ + } + if (popsize < 4) popsize = 4; /* enforce minimum population size */ + + /* Allocate population table. */ + storedd = ALLOC(int,(popsize+2)*(numvars+1)); + if (storedd == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + + /* Initialize the computed table. This table is made up of two data + ** structures: A hash table with the key given by the order, which says + ** if a given order is present in the population; and the repeat + ** vector, which says how many copies of a given order are stored in + ** the population table. If there are multiple copies of an order, only + ** one has a repeat count greater than 1. This copy is the one pointed + ** by the computed table. + */ + repeat = ALLOC(int,popsize); + if (repeat == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + FREE(storedd); + return(0); + } + for (i = 0; i < popsize; i++) { + repeat[i] = 0; + } + computed = st_init_table(array_compare,array_hash); + if (computed == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + FREE(storedd); + FREE(repeat); + return(0); + } + + /* Copy the current DD and its size to the population table. */ + for (i = 0; i < numvars; i++) { + STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */ + } + STOREDD(0,numvars) = table->keys - table->isolated; /* size of initial DD */ + + /* Store the initial order in the computed table. */ + if (st_insert(computed,(char *)storedd,(char *) 0) == ST_OUT_OF_MEM) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[0]++; + + /* Insert the reverse order as second element of the population. */ + for (i = 0; i < numvars; i++) { + STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */ + } + + /* Now create the random orders. make_random fills the population + ** table with random permutations. The successive loop builds and sifts + ** the DDs for the reverse order and each random permutation, and stores + ** the results in the computed table. + */ + if (!make_random(table,lower)) { + table->errorCode = CUDD_MEMORY_OUT; + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + for (i = 1; i < popsize; i++) { + result = build_dd(table,i,lower,upper); /* build and sift order */ + if (!result) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + if (st_lookup_int(computed,(char *)&STOREDD(i,0),&index)) { + repeat[index]++; + } else { + if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) == + ST_OUT_OF_MEM) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[i]++; + } + } + +#if 0 +#ifdef DD_STATS + /* Print the initial population. */ + (void) fprintf(table->out,"Initial population after sifting\n"); + for (m = 0; m < popsize; m++) { + for (i = 0; i < numvars; i++) { + (void) fprintf(table->out," %2d",STOREDD(m,i)); + } + (void) fprintf(table->out," : %3d (%d)\n", + STOREDD(m,numvars),repeat[m]); + } +#endif +#endif + + small = find_best(); +#ifdef DD_STATS + average_fitness = find_average_fitness(); + (void) fprintf(table->out,"\nInitial population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness); +#endif + + /* Decide how many crossovers should be tried. */ + if (table->numberXovers == 0) { + cross = 3*numvars; + if (cross > 60) { /* do a maximum of 50 crossovers */ + cross = 60; + } + } else { + cross = table->numberXovers; /* use user specified value */ + } + if (cross >= popsize) { + cross = popsize; + } + + /* Perform the crossovers to get the best order. */ + for (m = 0; m < cross; m++) { + if (!PMX(table->size)) { /* perform one crossover */ + table->errorCode = CUDD_MEMORY_OUT; + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + /* The offsprings are left in the last two entries of the + ** population table. These are now considered in turn. + */ + for (i = popsize; i <= popsize+1; i++) { + result = build_dd(table,i,lower,upper); /* build and sift child */ + if (!result) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + large = largest(); /* find the largest DD in population */ + + /* If the new child is smaller than the largest DD in the current + ** population, enter it into the population in place of the + ** largest DD. + */ + if (STOREDD(i,numvars) < STOREDD(large,numvars)) { + /* Look up the largest DD in the computed table. + ** Decrease its repetition count. If the repetition count + ** goes to 0, remove the largest DD from the computed table. + */ + result = st_lookup_int(computed,(char *)&STOREDD(large,0), + &index); + if (!result) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[index]--; + if (repeat[index] == 0) { + int *pointer = &STOREDD(index,0); + result = st_delete(computed, &pointer, NULL); + if (!result) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + } + /* Copy the new individual to the entry of the + ** population table just made available and update the + ** computed table. + */ + for (n = 0; n <= numvars; n++) { + STOREDD(large,n) = STOREDD(i,n); + } + if (st_lookup_int(computed,(char *)&STOREDD(large,0), + &index)) { + repeat[index]++; + } else { + if (st_insert(computed,(char *)&STOREDD(large,0), + (char *)(long)large) == ST_OUT_OF_MEM) { + FREE(storedd); + FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[large]++; + } + } + } + } + + /* Find the smallest DD in the population and build it; + ** that will be the result. + */ + small = find_best(); + + /* Print stats on the final population. */ +#ifdef DD_STATS + average_fitness = find_average_fitness(); + (void) fprintf(table->out,"\nFinal population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness); +#endif + + /* Clean up, build the result DD, and return. */ + st_free_table(computed); + computed = NULL; + result = build_dd(table,small,lower,upper); + FREE(storedd); + FREE(repeat); + return(result); + +} /* end of cuddGa */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Generates the random sequences for the initial population.] + + Description [Generates the random sequences for the initial population. + The sequences are permutations of the indices between lower and + upper in the current order.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +make_random( + DdManager * table, + int lower) +{ + int i,j; /* loop variables */ + int *used; /* is a number already in a permutation */ + int next; /* next random number without repetitions */ + + used = ALLOC(int,numvars); + if (used == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } +#if 0 +#ifdef DD_STATS + (void) fprintf(table->out,"Initial population before sifting\n"); + for (i = 0; i < 2; i++) { + for (j = 0; j < numvars; j++) { + (void) fprintf(table->out," %2d",STOREDD(i,j)); + } + (void) fprintf(table->out,"\n"); + } +#endif +#endif + for (i = 2; i < popsize; i++) { + for (j = 0; j < numvars; j++) { + used[j] = 0; + } + /* Generate a permutation of {0...numvars-1} and use it to + ** permute the variables in the layesr from lower to upper. + */ + for (j = 0; j < numvars; j++) { + do { + next = rand_int(numvars-1); + } while (used[next] != 0); + used[next] = 1; + STOREDD(i,j) = table->invperm[next+lower]; + } +#if 0 +#ifdef DD_STATS + /* Print the order just generated. */ + for (j = 0; j < numvars; j++) { + (void) fprintf(table->out," %2d",STOREDD(i,j)); + } + (void) fprintf(table->out,"\n"); +#endif +#endif + } + FREE(used); + return(1); + +} /* end of make_random */ + + +/**Function******************************************************************** + + Synopsis [Moves one variable up.] + + Description [Takes a variable from position x and sifts it up to + position x_low; x_low should be less than x. Returns 1 if successful; + 0 otherwise] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +sift_up( + DdManager * table, + int x, + int x_low) +{ + int y; + int size; + + y = cuddNextLow(table,x); + while (y >= x_low) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); + } + return(1); + +} /* end of sift_up */ + + +/**Function******************************************************************** + + Synopsis [Builds a DD from a given order.] + + Description [Builds a DD from a given order. This procedure also + sifts the final order and inserts into the array the size in nodes + of the result. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +build_dd( + DdManager * table, + int num /* the index of the individual to be built */, + int lower, + int upper) +{ + int i,j; /* loop vars */ + int position; + int index; + int limit; /* how large the DD for this order can grow */ + int size; + + /* Check the computed table. If the order already exists, it + ** suffices to copy the size from the existing entry. + */ + if (computed && st_lookup_int(computed,(char *)&STOREDD(num,0),&index)) { + STOREDD(num,numvars) = STOREDD(index,numvars); +#ifdef DD_STATS + (void) fprintf(table->out,"\nCache hit for index %d", index); +#endif + return(1); + } + + /* Stop if the DD grows 20 times larges than the reference size. */ + limit = 20 * STOREDD(0,numvars); + + /* Sift up the variables so as to build the desired permutation. + ** First the variable that has to be on top is sifted to the top. + ** Then the variable that has to occupy the secon position is sifted + ** up to the second position, and so on. + */ + for (j = 0; j < numvars; j++) { + i = STOREDD(num,j); + position = table->perm[i]; + result = sift_up(table,position,j+lower); + if (!result) return(0); + size = table->keys - table->isolated; + if (size > limit) break; + } + + /* Sift the DD just built. */ +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + result = cuddSifting(table,lower,upper); + if (!result) return(0); + + /* Copy order and size to table. */ + for (j = 0; j < numvars; j++) { + STOREDD(num,j) = table->invperm[lower+j]; + } + STOREDD(num,numvars) = table->keys - table->isolated; /* size of new DD */ + return(1); + +} /* end of build_dd */ + + +/**Function******************************************************************** + + Synopsis [Finds the largest DD in the population.] + + Description [Finds the largest DD in the population. If an order is + repeated, it avoids choosing the copy that is in the computed table + (it has repeat[i] > 1).] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +largest(void) +{ + int i; /* loop var */ + int big; /* temporary holder to return result */ + + big = 0; + while (repeat[big] > 1) big++; + for (i = big + 1; i < popsize; i++) { + if (STOREDD(i,numvars) >= STOREDD(big,numvars) && repeat[i] <= 1) { + big = i; + } + } + return(big); + +} /* end of largest */ + + +/**Function******************************************************************** + + Synopsis [Generates a random number between 0 and the integer a.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +rand_int( + int a) +{ + return(Cudd_Random() % (a+1)); + +} /* end of rand_int */ + + +/**Function******************************************************************** + + Synopsis [Hash function for the computed table.] + + Description [Hash function for the computed table. Returns the bucket + number.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +array_hash( + char * array, + int modulus) +{ + int val = 0; + int i; + int *intarray; + + intarray = (int *) array; + + for (i = 0; i < numvars; i++) { + val = val * 997 + intarray[i]; + } + + return ((val < 0) ? -val : val) % modulus; + +} /* end of array_hash */ + + +/**Function******************************************************************** + + Synopsis [Comparison function for the computed table.] + + Description [Comparison function for the computed table. Returns 0 if + the two arrays are equal; 1 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +array_compare( + const char * array1, + const char * array2) +{ + int i; + int *intarray1, *intarray2; + + intarray1 = (int *) array1; + intarray2 = (int *) array2; + + for (i = 0; i < numvars; i++) { + if (intarray1[i] != intarray2[i]) return(1); + } + return(0); + +} /* end of array_compare */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the fittest individual.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +find_best(void) +{ + int i,small; + + small = 0; + for (i = 1; i < popsize; i++) { + if (STOREDD(i,numvars) < STOREDD(small,numvars)) { + small = i; + } + } + return(small); + +} /* end of find_best */ + + +/**Function******************************************************************** + + Synopsis [Returns the average fitness of the population.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +#ifdef DD_STATS +static double +find_average_fitness(void) +{ + int i; + int total_fitness = 0; + double average_fitness; + + for (i = 0; i < popsize; i++) { + total_fitness += STOREDD(i,numvars); + } + average_fitness = (double) total_fitness / (double) popsize; + return(average_fitness); + +} /* end of find_average_fitness */ +#endif + + +/**Function******************************************************************** + + Synopsis [Performs the crossover between two parents.] + + Description [Performs the crossover between two randomly chosen + parents, and creates two children, x1 and x2. Uses the Partially + Matched Crossover operator.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +PMX( + int maxvar) +{ + int cut1,cut2; /* the two cut positions (random) */ + int mom,dad; /* the two randomly chosen parents */ + int *inv1; /* inverse permutations for repair algo */ + int *inv2; + int i; /* loop vars */ + int u,v; /* aux vars */ + + inv1 = ALLOC(int,maxvar); + if (inv1 == NULL) { + return(0); + } + inv2 = ALLOC(int,maxvar); + if (inv2 == NULL) { + FREE(inv1); + return(0); + } + + /* Choose two orders from the population using roulette wheel. */ + if (!roulette(&mom,&dad)) { + FREE(inv1); + FREE(inv2); + return(0); + } + + /* Choose two random cut positions. A cut in position i means that + ** the cut immediately precedes position i. If cut1 < cut2, we + ** exchange the middle of the two orderings; otherwise, we + ** exchange the beginnings and the ends. + */ + cut1 = rand_int(numvars-1); + do { + cut2 = rand_int(numvars-1); + } while (cut1 == cut2); + +#if 0 + /* Print out the parents. */ + (void) fprintf(table->out, + "Crossover of %d (mom) and %d (dad) between %d and %d\n", + mom,dad,cut1,cut2); + for (i = 0; i < numvars; i++) { + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(mom,i)); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < numvars; i++) { + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(dad,i)); + } + (void) fprintf(table->out,"\n"); +#endif + + /* Initialize the inverse permutations: -1 means yet undetermined. */ + for (i = 0; i < maxvar; i++) { + inv1[i] = -1; + inv2[i] = -1; + } + + /* Copy the portions whithin the cuts. */ + for (i = cut1; i != cut2; i = (i == numvars-1) ? 0 : i+1) { + STOREDD(popsize,i) = STOREDD(dad,i); + inv1[STOREDD(popsize,i)] = i; + STOREDD(popsize+1,i) = STOREDD(mom,i); + inv2[STOREDD(popsize+1,i)] = i; + } + + /* Now apply the repair algorithm outside the cuts. */ + for (i = cut2; i != cut1; i = (i == numvars-1 ) ? 0 : i+1) { + v = i; + do { + u = STOREDD(mom,v); + v = inv1[u]; + } while (v != -1); + STOREDD(popsize,i) = u; + inv1[u] = i; + v = i; + do { + u = STOREDD(dad,v); + v = inv2[u]; + } while (v != -1); + STOREDD(popsize+1,i) = u; + inv2[u] = i; + } + +#if 0 + /* Print the results of crossover. */ + for (i = 0; i < numvars; i++) { + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(popsize,i)); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < numvars; i++) { + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(popsize+1,i)); + } + (void) fprintf(table->out,"\n"); +#endif + + FREE(inv1); + FREE(inv2); + return(1); + +} /* end of PMX */ + + +/**Function******************************************************************** + + Synopsis [Selects two parents with the roulette wheel method.] + + Description [Selects two distinct parents with the roulette wheel method.] + + SideEffects [The indices of the selected parents are returned as side + effects.] + + SeeAlso [] + +******************************************************************************/ +static int +roulette( + int * p1, + int * p2) +{ + double *wheel; + double spin; + int i; + + wheel = ALLOC(double,popsize); + if (wheel == NULL) { + return(0); + } + + /* The fitness of an individual is the reciprocal of its size. */ + wheel[0] = 1.0 / (double) STOREDD(0,numvars); + + for (i = 1; i < popsize; i++) { + wheel[i] = wheel[i-1] + 1.0 / (double) STOREDD(i,numvars); + } + + /* Get a random number between 0 and wheel[popsize-1] (that is, + ** the sum of all fitness values. 2147483561 is the largest number + ** returned by Cudd_Random. + */ + spin = wheel[numvars-1] * (double) Cudd_Random() / 2147483561.0; + + /* Find the lucky element by scanning the wheel. */ + for (i = 0; i < popsize; i++) { + if (spin <= wheel[i]) break; + } + *p1 = i; + + /* Repeat the process for the second parent, making sure it is + ** distinct from the first. + */ + do { + spin = wheel[popsize-1] * (double) Cudd_Random() / 2147483561.0; + for (i = 0; i < popsize; i++) { + if (spin <= wheel[i]) break; + } + } while (i == *p1); + *p2 = i; + + FREE(wheel); + return(1); + +} /* end of roulette */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddGroup.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddGroup.c new file mode 100644 index 000000000..03a1bb7aa --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddGroup.c @@ -0,0 +1,2188 @@ +/**CFile*********************************************************************** + + FileName [cuddGroup.c] + + PackageName [cudd] + + Synopsis [Functions for group sifting.] + + Description [External procedures included in this file: +
                        +
                      • Cudd_MakeTreeNode() +
                      + Internal procedures included in this file: +
                        +
                      • cuddTreeSifting() +
                      + Static procedures included in this module: +
                        +
                      • ddTreeSiftingAux() +
                      • ddCountInternalMtrNodes() +
                      • ddReorderChildren() +
                      • ddFindNodeHiLo() +
                      • ddUniqueCompareGroup() +
                      • ddGroupSifting() +
                      • ddCreateGroup() +
                      • ddGroupSiftingAux() +
                      • ddGroupSiftingUp() +
                      • ddGroupSiftingDown() +
                      • ddGroupMove() +
                      • ddGroupMoveBackward() +
                      • ddGroupSiftingBackward() +
                      • ddMergeGroups() +
                      • ddDissolveGroup() +
                      • ddNoCheck() +
                      • ddSecDiffCheck() +
                      • ddExtSymmCheck() +
                      • ddVarGroupCheck() +
                      • ddSetVarHandled() +
                      • ddResetVarHandled() +
                      • ddIsVarHandled() +
                      • ddFixTree() +
                      ] + + Author [Shipra Panda, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Constants for lazy sifting */ +#define DD_NORMAL_SIFT 0 +#define DD_LAZY_SIFT 1 + +/* Constants for sifting up and down */ +#define DD_SIFT_DOWN 0 +#define DD_SIFT_UP 1 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + typedef int (*DD_CHKFP)(DdManager *, int, int); +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddGroup.c,v 1.49 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static int *entry; +extern int ddTotalNumberSwapping; +#ifdef DD_STATS +extern int ddTotalNISwaps; +static int extsymmcalls; +static int extsymm; +static int secdiffcalls; +static int secdiff; +static int secdiffmisfire; +#endif +#ifdef DD_DEBUG +static int pr = 0; /* flag to enable printing while debugging */ + /* by depositing a 1 into it */ +#endif +static unsigned int originalSize; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +#ifdef DD_STATS +static int ddCountInternalMtrNodes (DdManager *table, MtrNode *treenode); +#endif +static int ddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +static void ddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper); +static int ddUniqueCompareGroup (int *ptrX, int *ptrY); +static int ddGroupSifting (DdManager *table, int lower, int upper, DD_CHKFP checkFunction, int lazyFlag); +static void ddCreateGroup (DdManager *table, int x, int y); +static int ddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh, DD_CHKFP checkFunction, int lazyFlag); +static int ddGroupSiftingUp (DdManager *table, int y, int xLow, DD_CHKFP checkFunction, Move **moves); +static int ddGroupSiftingDown (DdManager *table, int x, int xHigh, DD_CHKFP checkFunction, Move **moves); +static int ddGroupMove (DdManager *table, int x, int y, Move **moves); +static int ddGroupMoveBackward (DdManager *table, int x, int y); +static int ddGroupSiftingBackward (DdManager *table, Move *moves, int size, int upFlag, int lazyFlag); +static void ddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high); +static void ddDissolveGroup (DdManager *table, int x, int y); +static int ddNoCheck (DdManager *table, int x, int y); +static int ddSecDiffCheck (DdManager *table, int x, int y); +static int ddExtSymmCheck (DdManager *table, int x, int y); +static int ddVarGroupCheck (DdManager * table, int x, int y); +static int ddSetVarHandled (DdManager *dd, int index); +static int ddResetVarHandled (DdManager *dd, int index); +static int ddIsVarHandled (DdManager *dd, int index); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Creates a new variable group.] + + Description [Creates a new variable group. The group starts at + variable low and contains size variables. The parameter low is the index + of the first variable. If the variable already exists, its current + position in the order is known to the manager. If the variable does + not exist yet, the position is assumed to be the same as the index. + The group tree is created if it does not exist yet. + Returns a pointer to the group if successful; NULL otherwise.] + + SideEffects [The variable tree is changed.] + + SeeAlso [Cudd_MakeZddTreeNode] + +******************************************************************************/ +MtrNode * +Cudd_MakeTreeNode( + DdManager * dd /* manager */, + unsigned int low /* index of the first group variable */, + unsigned int size /* number of variables in the group */, + unsigned int type /* MTR_DEFAULT or MTR_FIXED */) +{ + MtrNode *group; + MtrNode *tree; + unsigned int level; + + /* If the variable does not exist yet, the position is assumed to be + ** the same as the index. Therefore, applications that rely on + ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new + ** variables have to create the variables before they group them. + */ + level = (low < (unsigned int) dd->size) ? dd->perm[low] : low; + + if (level + size - 1> (int) MTR_MAXHIGH) + return(NULL); + + /* If the tree does not exist yet, create it. */ + tree = dd->tree; + if (tree == NULL) { + dd->tree = tree = Mtr_InitGroupTree(0, dd->size); + if (tree == NULL) + return(NULL); + tree->index = dd->size == 0 ? 0 : dd->invperm[0]; + } + + /* Extend the upper bound of the tree if necessary. This allows the + ** application to create groups even before the variables are created. + */ + tree->size = ddMax(tree->size, ddMax(level + size, (unsigned) dd->size)); + + /* Create the group. */ + group = Mtr_MakeGroup(tree, level, size, type); + if (group == NULL) + return(NULL); + + /* Initialize the index field to the index of the variable currently + ** in position low. This field will be updated by the reordering + ** procedure to provide a handle to the group once it has been moved. + */ + group->index = (MtrHalfWord) low; + + return(group); + +} /* end of Cudd_MakeTreeNode */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Tree sifting algorithm.] + + Description [Tree sifting algorithm. Assumes that a tree representing + a group hierarchy is passed as a parameter. It then reorders each + group in postorder fashion by calling ddTreeSiftingAux. Assumes that + no dead nodes are present. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddTreeSifting( + DdManager * table /* DD table */, + Cudd_ReorderingType method /* reordering method for the groups of leaves */) +{ + int i; + int nvars; + int result; + int tempTree; + + /* If no tree is provided we create a temporary one in which all + ** variables are in a single group. After reordering this tree is + ** destroyed. + */ + tempTree = table->tree == NULL; + if (tempTree) { + table->tree = Mtr_InitGroupTree(0,table->size); + table->tree->index = table->invperm[0]; + } + nvars = table->size; + +#ifdef DD_DEBUG + if (pr > 0 && !tempTree) (void) fprintf(table->out,"cuddTreeSifting:"); + Mtr_PrintGroups(table->tree,pr <= 0); +#endif + +#ifdef DD_STATS + extsymmcalls = 0; + extsymm = 0; + secdiffcalls = 0; + secdiff = 0; + secdiffmisfire = 0; + + (void) fprintf(table->out,"\n"); + if (!tempTree) + (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", + ddCountInternalMtrNodes(table,table->tree)); +#endif + + /* Initialize the group of each subtable to itself. Initially + ** there are no groups. Groups are created according to the tree + ** structure in postorder fashion. + */ + for (i = 0; i < nvars; i++) + table->subtables[i].next = i; + + + /* Reorder. */ + result = ddTreeSiftingAux(table, table->tree, method); + +#ifdef DD_STATS /* print stats */ + if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && + (table->groupcheck == CUDD_GROUP_CHECK7 || + table->groupcheck == CUDD_GROUP_CHECK5)) { + (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); + (void) fprintf(table->out,"extsymm = %d",extsymm); + } + if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && + table->groupcheck == CUDD_GROUP_CHECK7) { + (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); + (void) fprintf(table->out,"secdiff = %d\n",secdiff); + (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); + } +#endif + + if (tempTree) + Cudd_FreeTree(table); + else + Mtr_ReorderGroups(table->tree, table->perm); + + return(result); + +} /* end of cuddTreeSifting */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Visits the group tree and reorders each group.] + + Description [Recursively visits the group tree and reorders each + group in postorder fashion. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddTreeSiftingAux( + DdManager * table, + MtrNode * treenode, + Cudd_ReorderingType method) +{ + MtrNode *auxnode; + int res; + Cudd_AggregationType saveCheck; + +#ifdef DD_DEBUG + Mtr_PrintGroups(treenode,1); +#endif + + auxnode = treenode; + while (auxnode != NULL) { + if (auxnode->child != NULL) { + if (!ddTreeSiftingAux(table, auxnode->child, method)) + return(0); + saveCheck = table->groupcheck; + table->groupcheck = CUDD_NO_CHECK; + if (method != CUDD_REORDER_LAZY_SIFT) + res = ddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT); + else + res = ddReorderChildren(table, auxnode, CUDD_REORDER_LAZY_SIFT); + table->groupcheck = saveCheck; + + if (res == 0) + return(0); + } else if (auxnode->size > 1) { + if (!ddReorderChildren(table, auxnode, method)) + return(0); + } + auxnode = auxnode->younger; + } + + return(1); + +} /* end of ddTreeSiftingAux */ + + +#ifdef DD_STATS +/**Function******************************************************************** + + Synopsis [Counts the number of internal nodes of the group tree.] + + Description [Counts the number of internal nodes of the group tree. + Returns the count.] + + SideEffects [None] + +******************************************************************************/ +static int +ddCountInternalMtrNodes( + DdManager * table, + MtrNode * treenode) +{ + MtrNode *auxnode; + int count,nodeCount; + + + nodeCount = 0; + auxnode = treenode; + while (auxnode != NULL) { + if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { + nodeCount++; + count = ddCountInternalMtrNodes(table,auxnode->child); + nodeCount += count; + } + auxnode = auxnode->younger; + } + + return(nodeCount); + +} /* end of ddCountInternalMtrNodes */ +#endif + + +/**Function******************************************************************** + + Synopsis [Reorders the children of a group tree node according to + the options.] + + Description [Reorders the children of a group tree node according to + the options. After reordering puts all the variables in the group + and/or its descendents in a single group. This allows hierarchical + reordering. If the variables in the group do not exist yet, simply + does nothing. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddReorderChildren( + DdManager * table, + MtrNode * treenode, + Cudd_ReorderingType method) +{ + int lower; + int upper; + int result; + unsigned int initialSize; + + ddFindNodeHiLo(table,treenode,&lower,&upper); + /* If upper == -1 these variables do not exist yet. */ + if (upper == -1) + return(1); + + if (treenode->flags == MTR_FIXED) { + result = 1; + } else { +#ifdef DD_STATS + (void) fprintf(table->out," "); +#endif + switch (method) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + result = cuddSwapping(table,lower,upper,method); + break; + case CUDD_REORDER_SIFT: + result = cuddSifting(table,lower,upper); + break; + case CUDD_REORDER_SIFT_CONVERGE: + do { + initialSize = table->keys - table->isolated; + result = cuddSifting(table,lower,upper); + if (initialSize <= table->keys - table->isolated) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + case CUDD_REORDER_SYMM_SIFT: + result = cuddSymmSifting(table,lower,upper); + break; + case CUDD_REORDER_SYMM_SIFT_CONV: + result = cuddSymmSiftingConv(table,lower,upper); + break; + case CUDD_REORDER_GROUP_SIFT: + if (table->groupcheck == CUDD_NO_CHECK) { + result = ddGroupSifting(table,lower,upper,ddNoCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK5) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK7) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else { + (void) fprintf(table->err, + "Unknown group ckecking method\n"); + result = 0; + } + break; + case CUDD_REORDER_GROUP_SIFT_CONV: + do { + initialSize = table->keys - table->isolated; + if (table->groupcheck == CUDD_NO_CHECK) { + result = ddGroupSifting(table,lower,upper,ddNoCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK5) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK7) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else { + (void) fprintf(table->err, + "Unknown group ckecking method\n"); + result = 0; + } +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + result = cuddWindowReorder(table,lower,upper, + CUDD_REORDER_WINDOW4); + if (initialSize <= table->keys - table->isolated) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + case CUDD_REORDER_WINDOW2: + case CUDD_REORDER_WINDOW3: + case CUDD_REORDER_WINDOW4: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + result = cuddWindowReorder(table,lower,upper,method); + break; + case CUDD_REORDER_ANNEALING: + result = cuddAnnealing(table,lower,upper); + break; + case CUDD_REORDER_GENETIC: + result = cuddGa(table,lower,upper); + break; + case CUDD_REORDER_LINEAR: + result = cuddLinearAndSifting(table,lower,upper); + break; + case CUDD_REORDER_LINEAR_CONVERGE: + do { + initialSize = table->keys - table->isolated; + result = cuddLinearAndSifting(table,lower,upper); + if (initialSize <= table->keys - table->isolated) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + case CUDD_REORDER_EXACT: + result = cuddExact(table,lower,upper); + break; + case CUDD_REORDER_LAZY_SIFT: + result = ddGroupSifting(table,lower,upper,ddVarGroupCheck, + DD_LAZY_SIFT); + break; + default: + return(0); + } + } + + /* Create a single group for all the variables that were sifted, + ** so that they will be treated as a single block by successive + ** invocations of ddGroupSifting. + */ + ddMergeGroups(table,treenode,lower,upper); + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddReorderChildren:"); +#endif + + return(result); + +} /* end of ddReorderChildren */ + + +/**Function******************************************************************** + + Synopsis [Finds the lower and upper bounds of the group represented + by treenode.] + + Description [Finds the lower and upper bounds of the group + represented by treenode. From the index and size fields we need to + derive the current positions, and find maximum and minimum.] + + SideEffects [The bounds are returned as side effects.] + + SeeAlso [] + +******************************************************************************/ +static void +ddFindNodeHiLo( + DdManager * table, + MtrNode * treenode, + int * lower, + int * upper) +{ + int low; + int high; + + /* Check whether no variables in this group already exist. + ** If so, return immediately. The calling procedure will know from + ** the values of upper that no reordering is needed. + */ + if ((int) treenode->low >= table->size) { + *lower = table->size; + *upper = -1; + return; + } + + *lower = low = (unsigned int) table->perm[treenode->index]; + high = (int) (low + treenode->size - 1); + + if (high >= table->size) { + /* This is the case of a partially existing group. The aim is to + ** reorder as many variables as safely possible. If the tree + ** node is terminal, we just reorder the subset of the group + ** that is currently in existence. If the group has + ** subgroups, then we only reorder those subgroups that are + ** fully instantiated. This way we avoid breaking up a group. + */ + MtrNode *auxnode = treenode->child; + if (auxnode == NULL) { + *upper = (unsigned int) table->size - 1; + } else { + /* Search the subgroup that strands the table->size line. + ** If the first group starts at 0 and goes past table->size + ** upper will get -1, thus correctly signaling that no reordering + ** should take place. + */ + while (auxnode != NULL) { + int thisLower = table->perm[auxnode->low]; + int thisUpper = thisLower + auxnode->size - 1; + if (thisUpper >= table->size && thisLower < table->size) + *upper = (unsigned int) thisLower - 1; + auxnode = auxnode->younger; + } + } + } else { + /* Normal case: All the variables of the group exist. */ + *upper = (unsigned int) high; + } + +#ifdef DD_DEBUG + /* Make sure that all variables in group are contiguous. */ + assert(treenode->size >= *upper - *lower + 1); +#endif + + return; + +} /* end of ddFindNodeHiLo */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the variables + according to the number of keys in the subtables. Returns the + difference in number of keys between the two variables being + compared.] + + SideEffects [None] + +******************************************************************************/ +static int +ddUniqueCompareGroup( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of ddUniqueCompareGroup */ + + +/**Function******************************************************************** + + Synopsis [Sifts from treenode->low to treenode->high.] + + Description [Sifts from treenode->low to treenode->high. If + croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the + end of the initial sifting. If a group is created, it is then sifted + again. After sifting one variable, the group that contains it is + dissolved. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSifting( + DdManager * table, + int lower, + int upper, + DD_CHKFP checkFunction, + int lazyFlag) +{ + int *var; + int i,j,x,xInit; + int nvars; + int classes; + int result; + int *sifted; + int merged; + int dissolve; +#ifdef DD_STATS + unsigned previousSize; +#endif + int xindex; + + nvars = table->size; + + /* Order variables to sift. */ + entry = NULL; + sifted = NULL; + var = ALLOC(int,nvars); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; + } + entry = ALLOC(int,nvars); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; + } + sifted = ALLOC(int,nvars); + if (sifted == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; + } + + /* Here we consider only one representative for each group. */ + for (i = 0, classes = 0; i < nvars; i++) { + sifted[i] = 0; + x = table->perm[i]; + if ((unsigned) x >= table->subtables[x].next) { + entry[i] = table->subtables[x].keys; + var[classes] = i; + classes++; + } + } + + qsort((void *)var,classes,sizeof(int), + (DD_QSFP) ddUniqueCompareGroup); + + if (lazyFlag) { + for (i = 0; i < nvars; i ++) { + ddResetVarHandled(table, i); + } + } + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime + table->reordTime + > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + xindex = var[i]; + if (sifted[xindex] == 1) /* variable already sifted as part of group */ + continue; + x = table->perm[xindex]; /* find current level of this variable */ + + if (x < lower || x > upper || table->subtables[x].bindVar == 1) + continue; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif +#ifdef DD_DEBUG + /* x is bottom of group */ + assert((unsigned) x >= table->subtables[x].next); +#endif + if ((unsigned) x == table->subtables[x].next) { + dissolve = 1; + result = ddGroupSiftingAux(table,x,lower,upper,checkFunction, + lazyFlag); + } else { + dissolve = 0; + result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); + } + if (!result) goto ddGroupSiftingOutOfMem; + + /* check for aggregation */ + merged = 0; + if (lazyFlag == 0 && table->groupcheck == CUDD_GROUP_CHECK7) { + x = table->perm[xindex]; /* find current level */ + if ((unsigned) x == table->subtables[x].next) { /* not part of a group */ + if (x != upper && sifted[table->invperm[x+1]] == 0 && + (unsigned) x+1 == table->subtables[x+1].next) { + if (ddSecDiffCheck(table,x,x+1)) { + merged =1; + ddCreateGroup(table,x,x+1); + } + } + if (x != lower && sifted[table->invperm[x-1]] == 0 && + (unsigned) x-1 == table->subtables[x-1].next) { + if (ddSecDiffCheck(table,x-1,x)) { + merged =1; + ddCreateGroup(table,x-1,x); + } + } + } + } + + if (merged) { /* a group was created */ + /* move x to bottom of group */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + /* sift */ + result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); + if (!result) goto ddGroupSiftingOutOfMem; +#ifdef DD_STATS + if (table->keys < previousSize + table->isolated) { + (void) fprintf(table->out,"_"); + } else if (table->keys > previousSize + table->isolated) { + (void) fprintf(table->out,"^"); + } else { + (void) fprintf(table->out,"*"); + } + fflush(table->out); + } else { + if (table->keys < previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > previousSize + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + /* Mark variables in the group just sifted. */ + x = table->perm[xindex]; + if ((unsigned) x != table->subtables[x].next) { + xInit = x; + do { + j = table->invperm[x]; + sifted[j] = 1; + x = table->subtables[x].next; + } while (x != xInit); + + /* Dissolve the group if it was created. */ + if (lazyFlag == 0 && dissolve) { + do { + j = table->subtables[x].next; + table->subtables[x].next = x; + x = j; + } while (x != xInit); + } + } + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddGroupSifting:"); +#endif + + if (lazyFlag) ddSetVarHandled(table, xindex); + } /* for */ + + FREE(sifted); + FREE(var); + FREE(entry); + + return(1); + +ddGroupSiftingOutOfMem: + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + if (sifted != NULL) FREE(sifted); + + return(0); + +} /* end of ddGroupSifting */ + + +/**Function******************************************************************** + + Synopsis [Creates a group encompassing variables from x to y in the + DD table.] + + Description [Creates a group encompassing variables from x to y in the + DD table. In the current implementation it must be y == x+1. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static void +ddCreateGroup( + DdManager * table, + int x, + int y) +{ + int gybot; + +#ifdef DD_DEBUG + assert(y == x+1); +#endif + + /* Find bottom of second group. */ + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + + /* Link groups. */ + table->subtables[x].next = y; + table->subtables[gybot].next = x; + + return; + +} /* ddCreateGroup */ + + +/**Function******************************************************************** + + Synopsis [Sifts one variable up and down until it has taken all + positions. Checks for aggregation.] + + Description [Sifts one variable up and down until it has taken all + positions. Checks for aggregation. There may be at most two sweeps, + even if the group grows. Assumes that x is either an isolated + variable, or it is the bottom of a group. All groups may not have + been found. The variable being moved is returned to the best position + seen during sifting. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh, + DD_CHKFP checkFunction, + int lazyFlag) +{ + Move *move; + Move *moves; /* list of moves */ + int initialSize; + int result; + int y; + int topbot; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out, + "ddGroupSiftingAux from %d to %d\n",xLow,xHigh); + assert((unsigned) x >= table->subtables[x].next); /* x is bottom of group */ +#endif + + initialSize = table->keys - table->isolated; + moves = NULL; + + originalSize = initialSize; /* for lazy sifting */ + + /* If we have a singleton, we check for aggregation in both + ** directions before we sift. + */ + if ((unsigned) x == table->subtables[x].next) { + /* Will go down first, unless x == xHigh: + ** Look for aggregation above x. + */ + for (y = x; y > xLow; y--) { + if (!checkFunction(table,y-1,y)) + break; + topbot = table->subtables[y-1].next; /* find top of y-1's group */ + table->subtables[y-1].next = y; + table->subtables[x].next = topbot; /* x is bottom of group so its */ + /* next is top of y-1's group */ + y = topbot + 1; /* add 1 for y--; new y is top of group */ + } + /* Will go up first unless x == xlow: + ** Look for aggregation below x. + */ + for (y = x; y < xHigh; y++) { + if (!checkFunction(table,y,y+1)) + break; + /* find bottom of y+1's group */ + topbot = y + 1; + while ((unsigned) topbot < table->subtables[topbot].next) { + topbot = table->subtables[topbot].next; + } + table->subtables[topbot].next = table->subtables[y].next; + table->subtables[y].next = y + 1; + y = topbot - 1; /* subtract 1 for y++; new y is bottom of group */ + } + } + + /* Now x may be in the middle of a group. + ** Find bottom of x's group. + */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + + if (x == xLow) { /* Sift down */ +#ifdef DD_DEBUG + /* x must be a singleton */ + assert((unsigned) x == table->subtables[x].next); +#endif + if (x == xHigh) return(1); /* just one variable */ + + if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_DOWN,lazyFlag); +#ifdef DD_DEBUG + assert(table->keys - table->isolated <= (unsigned) initialSize); +#endif + if (!result) goto ddGroupSiftingAuxOutOfMem; + + } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ +#ifdef DD_DEBUG + /* x is bottom of group */ + assert((unsigned) x >= table->subtables[x].next); +#endif + /* Find top of x's group */ + x = table->subtables[x].next; + + if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + /* at this point x == xLow, unless early term */ + + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_UP,lazyFlag); +#ifdef DD_DEBUG + assert(table->keys - table->isolated <= (unsigned) initialSize); +#endif + if (!result) goto ddGroupSiftingAuxOutOfMem; + + } else if (x - xLow > xHigh - x) { /* must go down first: shorter */ + if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + /* Find top of group */ + if (moves) { + x = moves->y; + } + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + x = table->subtables[x].next; +#ifdef DD_DEBUG + /* x should be the top of a group */ + assert((unsigned) x <= table->subtables[x].next); +#endif + + if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_UP,lazyFlag); +#ifdef DD_DEBUG + assert(table->keys - table->isolated <= (unsigned) initialSize); +#endif + if (!result) goto ddGroupSiftingAuxOutOfMem; + + } else { /* moving up first: shorter */ + /* Find top of x's group */ + x = table->subtables[x].next; + + if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + if (moves) { + x = moves->x; + } + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; +#ifdef DD_DEBUG + /* x is bottom of a group */ + assert((unsigned) x >= table->subtables[x].next); +#endif + + if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) + goto ddGroupSiftingAuxOutOfMem; + + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_DOWN,lazyFlag); +#ifdef DD_DEBUG + assert(table->keys - table->isolated <= (unsigned) initialSize); +#endif + if (!result) goto ddGroupSiftingAuxOutOfMem; + } + + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(1); + +ddGroupSiftingAuxOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(0); + +} /* end of ddGroupSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much.] + + Description [Sifts up a variable until either it reaches position + xLow or the size of the DD heap increases too much. Assumes that y is + the top of a group (or a singleton). Checks y for aggregation to the + adjacent variables. Records all the moves that are appended to the + list of moves received as input and returned as a side effect. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSiftingUp( + DdManager * table, + int y, + int xLow, + DD_CHKFP checkFunction, + Move ** moves) +{ + Move *move; + int x; + int size; + int i; + int gxtop,gybot; + int limitSize; + int xindex, yindex; + int zindex; + int z; + int isolated; + int L; /* lower bound on DD size */ +#ifdef DD_DEBUG + int checkL; +#endif + + yindex = table->invperm[y]; + + /* Initialize the lower bound. + ** The part of the DD below the bottom of y's group will not change. + ** The part of the DD above y that does not interact with any + ** variable of y's group will not change. + ** The rest may vanish in the best case, except for + ** the nodes at level xLow, which will not vanish, regardless. + ** What we use here is not really a lower bound, because we ignore + ** the interactions with all variables except y. + */ + limitSize = L = table->keys - table->isolated; + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L -= table->subtables[z].keys - isolated; + } + } + + x = cuddNextLow(table,y); + while (x >= xLow && L <= limitSize) { +#ifdef DD_DEBUG + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + if (pr > 0 && L != checkL) { + (void) fprintf(table->out, + "Inaccurate lower bound: L = %d checkL = %d\n", + L, checkL); + } +#endif + gxtop = table->subtables[x].next; + if (checkFunction(table,x,y)) { + /* Group found, attach groups */ + table->subtables[x].next = y; + i = table->subtables[y].next; + while (table->subtables[i].next != (unsigned) y) + i = table->subtables[i].next; + table->subtables[i].next = gxtop; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_NEWNODE; + move->size = table->keys - table->isolated; + move->next = *moves; + *moves = move; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y are self groups */ + xindex = table->invperm[x]; + size = cuddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); +#endif + if (size == 0) goto ddGroupSiftingUpOutOfMem; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_DEFAULT; + move->size = size; + move->next = *moves; + *moves = move; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out, + "ddGroupSiftingUp (2 single groups):\n"); +#endif + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } else { /* Group move */ + size = ddGroupMove(table,x,y,moves); + if (size == 0) goto ddGroupSiftingUpOutOfMem; + /* Update the lower bound. */ + z = (*moves)->y; + do { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L += table->subtables[z].keys - isolated; + } + z = table->subtables[z].next; + } while (z != (int) (*moves)->y); + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } + y = gxtop; + x = cuddNextLow(table,y); + } + + return(1); + +ddGroupSiftingUpOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of ddGroupSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts down a variable until it reaches position xHigh.] + + Description [Sifts down a variable until it reaches position xHigh. + Assumes that x is the bottom of a group (or a singleton). Records + all the moves. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSiftingDown( + DdManager * table, + int x, + int xHigh, + DD_CHKFP checkFunction, + Move ** moves) +{ + Move *move; + int y; + int size; + int limitSize; + int gxtop,gybot; + int R; /* upper bound on node decrease */ + int xindex, yindex; + int isolated, allVars; + int z; + int zindex; +#ifdef DD_DEBUG + int checkR; +#endif + + /* If the group consists of simple variables, there is no point in + ** sifting it down. This check is redundant if the projection functions + ** do not have external references, because the computation of the + ** lower bound takes care of the problem. It is necessary otherwise to + ** prevent the sifting down of simple variables. */ + y = x; + allVars = 1; + do { + if (table->subtables[y].keys != 1) { + allVars = 0; + break; + } + y = table->subtables[y].next; + } while (table->subtables[y].next != (unsigned) x); + if (allVars) + return(1); + + /* Initialize R. */ + xindex = table->invperm[x]; + gxtop = table->subtables[x].next; + limitSize = size = table->keys - table->isolated; + R = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } + + y = cuddNextHigh(table,x); + while (y <= xHigh && size - R < limitSize) { +#ifdef DD_DEBUG + gxtop = table->subtables[x].next; + checkR = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + assert(R >= checkR); +#endif + /* Find bottom of y group. */ + gybot = table->subtables[y].next; + while (table->subtables[gybot].next != (unsigned) y) + gybot = table->subtables[gybot].next; + + if (checkFunction(table,x,y)) { + /* Group found: attach groups and record move. */ + gxtop = table->subtables[x].next; + table->subtables[x].next = y; + table->subtables[gybot].next = gxtop; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_NEWNODE; + move->size = table->keys - table->isolated; + move->next = *moves; + *moves = move; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y are self groups */ + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); +#endif + if (size == 0) goto ddGroupSiftingDownOutOfMem; + + /* Record move. */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_DEFAULT; + move->size = size; + move->next = *moves; + *moves = move; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out, + "ddGroupSiftingDown (2 single groups):\n"); +#endif + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + + x = y; + y = cuddNextHigh(table,x); + } else { /* Group move */ + /* Update upper bound on node decrease: first phase. */ + gxtop = table->subtables[x].next; + z = gxtop + 1; + do { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R -= table->subtables[z].keys - isolated; + } + z++; + } while (z <= gybot); + size = ddGroupMove(table,x,y,moves); + if (size == 0) goto ddGroupSiftingDownOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + + /* Update upper bound on node decrease: second phase. */ + gxtop = table->subtables[gybot].next; + for (z = gxtop + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } + } + x = gybot; + y = cuddNextHigh(table,x); + } + + return(1); + +ddGroupSiftingDownOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + + return(0); + +} /* end of ddGroupSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Swaps two groups and records the move.] + + Description [Swaps two groups and records the move. Returns the + number of keys in the DD table in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupMove( + DdManager * table, + int x, + int y, + Move ** moves) +{ + Move *move; + int size; + int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + int swapx,swapy; +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + int initialSize,bestSize; +#endif + +#ifdef DD_DEBUG + /* We assume that x < y */ + assert(x < y); +#endif + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtables[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtables[ybot].next) + ybot = table->subtables[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + initialSize = bestSize = table->keys - table->isolated; +#endif + /* Sift the variables of the second group up through the first group */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddGroupMoveOutOfMem; +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (size < bestSize) + bestSize = size; +#endif + swapx = x; swapy = y; + y = x; + x = cuddNextLow(table,y); + } + y = ytop + i; + x = cuddNextLow(table,y); + } +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if ((bestSize < initialSize) && (bestSize < size)) + (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); +#endif + + /* fix groups */ + y = xtop; /* ytop is now where xtop used to be */ + for (i = 0; i < ysize - 1; i++) { + table->subtables[y].next = cuddNextHigh(table,y); + y = cuddNextHigh(table,y); + } + table->subtables[y].next = xtop; /* y is bottom of its group, join */ + /* it to top of its group */ + x = cuddNextHigh(table,y); + newxtop = x; + for (i = 0; i < xsize - 1; i++) { + table->subtables[x].next = cuddNextHigh(table,x); + x = cuddNextHigh(table,x); + } + table->subtables[x].next = newxtop; /* x is bottom of its group, join */ + /* it to top of its group */ +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddGroupMove:\n"); +#endif + + /* Store group move */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupMoveOutOfMem; + move->x = swapx; + move->y = swapy; + move->flags = MTR_DEFAULT; + move->size = table->keys - table->isolated; + move->next = *moves; + *moves = move; + + return(table->keys - table->isolated); + +ddGroupMoveOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of ddGroupMove */ + + +/**Function******************************************************************** + + Synopsis [Undoes the swap two groups.] + + Description [Undoes the swap two groups. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupMoveBackward( + DdManager * table, + int x, + int y) +{ + int size; + int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + + +#ifdef DD_DEBUG + /* We assume that x < y */ + assert(x < y); +#endif + + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtables[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtables[ybot].next) + ybot = table->subtables[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + + /* Sift the variables of the second group up through the first group */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) + return(0); + y = x; + x = cuddNextLow(table,y); + } + y = ytop + i; + x = cuddNextLow(table,y); + } + + /* fix groups */ + y = xtop; + for (i = 0; i < ysize - 1; i++) { + table->subtables[y].next = cuddNextHigh(table,y); + y = cuddNextHigh(table,y); + } + table->subtables[y].next = xtop; /* y is bottom of its group, join */ + /* to its top */ + x = cuddNextHigh(table,y); + newxtop = x; + for (i = 0; i < xsize - 1; i++) { + table->subtables[x].next = cuddNextHigh(table,x); + x = cuddNextHigh(table,x); + } + table->subtables[x].next = newxtop; /* x is bottom of its group, join */ + /* to its top */ +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddGroupMoveBackward:\n"); +#endif + + return(1); + +} /* end of ddGroupMoveBackward */ + + +/**Function******************************************************************** + + Synopsis [Determines the best position for a variables and returns + it there.] + + Description [Determines the best position for a variables and returns + it there. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddGroupSiftingBackward( + DdManager * table, + Move * moves, + int size, + int upFlag, + int lazyFlag) +{ + Move *move; + int res; + Move *end_move; + int diff, tmp_diff; + int index; + unsigned int pairlev; + + if (lazyFlag) { + end_move = NULL; + + /* Find the minimum size, and the earliest position at which it + ** was achieved. */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + end_move = move; + } else if (move->size == size) { + if (end_move == NULL) end_move = move; + } + } + + /* Find among the moves that give minimum size the one that + ** minimizes the distance from the corresponding variable. */ + if (moves != NULL) { + diff = Cudd_ReadSize(table) + 1; + index = (upFlag == 1) ? + table->invperm[moves->x] : table->invperm[moves->y]; + pairlev = + (unsigned) table->perm[Cudd_bddReadPairIndex(table, index)]; + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) { + if (upFlag == 1) { + tmp_diff = (move->x > pairlev) ? + move->x - pairlev : pairlev - move->x; + } else { + tmp_diff = (move->y > pairlev) ? + move->y - pairlev : pairlev - move->y; + } + if (tmp_diff < diff) { + diff = tmp_diff; + end_move = move; + } + } + } + } + } else { + /* Find the minimum size. */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + } + + /* In case of lazy sifting, end_move identifies the position at + ** which we want to stop. Otherwise, we stop as soon as we meet + ** the minimum size. */ + for (move = moves; move != NULL; move = move->next) { + if (lazyFlag) { + if (move == end_move) return(1); + } else { + if (move->size == size) return(1); + } + if ((table->subtables[move->x].next == move->x) && + (table->subtables[move->y].next == move->y)) { + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"ddGroupSiftingBackward:\n"); + assert(table->subtables[move->x].next == move->x); + assert(table->subtables[move->y].next == move->y); +#endif + } else { /* Group move necessary */ + if (move->flags == MTR_NEWNODE) { + ddDissolveGroup(table,(int)move->x,(int)move->y); + } else { + res = ddGroupMoveBackward(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + } + + } + + return(1); + +} /* end of ddGroupSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Merges groups in the DD table.] + + Description [Creates a single group from low to high and adjusts the + index field of the tree node.] + + SideEffects [None] + +******************************************************************************/ +static void +ddMergeGroups( + DdManager * table, + MtrNode * treenode, + int low, + int high) +{ + int i; + MtrNode *auxnode; + int saveindex; + int newindex; + + /* Merge all variables from low to high in one group, unless + ** this is the topmost group. In such a case we do not merge lest + ** we lose the symmetry information. */ + if (treenode != table->tree) { + for (i = low; i < high; i++) + table->subtables[i].next = i+1; + table->subtables[high].next = low; + } + + /* Adjust the index fields of the tree nodes. If a node is the + ** first child of its parent, then the parent may also need adjustment. */ + saveindex = treenode->index; + newindex = table->invperm[low]; + auxnode = treenode; + do { + auxnode->index = newindex; + if (auxnode->parent == NULL || + (int) auxnode->parent->index != saveindex) + break; + auxnode = auxnode->parent; + } while (1); + return; + +} /* end of ddMergeGroups */ + + +/**Function******************************************************************** + + Synopsis [Dissolves a group in the DD table.] + + Description [x and y are variables in a group to be cut in two. The cut + is to pass between x and y.] + + SideEffects [None] + +******************************************************************************/ +static void +ddDissolveGroup( + DdManager * table, + int x, + int y) +{ + int topx; + int boty; + + /* find top and bottom of the two groups */ + boty = y; + while ((unsigned) boty < table->subtables[boty].next) + boty = table->subtables[boty].next; + + topx = table->subtables[boty].next; + + table->subtables[boty].next = y; + table->subtables[x].next = topx; + + return; + +} /* end of ddDissolveGroup */ + + +/**Function******************************************************************** + + Synopsis [Pretends to check two variables for aggregation.] + + Description [Pretends to check two variables for aggregation. Always + returns 0.] + + SideEffects [None] + +******************************************************************************/ +static int +ddNoCheck( + DdManager * table, + int x, + int y) +{ + return(0); + +} /* end of ddNoCheck */ + + +/**Function******************************************************************** + + Synopsis [Checks two variables for aggregation.] + + Description [Checks two variables for aggregation. The check is based + on the second difference of the number of nodes as a function of the + layer. If the second difference is lower than a given threshold + (typically negative) then the two variables should be aggregated. + Returns 1 if the two variables pass the test; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSecDiffCheck( + DdManager * table, + int x, + int y) +{ + double Nx,Nx_1; + double Sx; + double threshold; + int xindex,yindex; + + if (x==0) return(0); + +#ifdef DD_STATS + secdiffcalls++; +#endif + Nx = (double) table->subtables[x].keys; + Nx_1 = (double) table->subtables[x-1].keys; + Sx = (table->subtables[y].keys/Nx) - (Nx/Nx_1); + + threshold = table->recomb / 100.0; + if (Sx < threshold) { + xindex = table->invperm[x]; + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + (void) fprintf(table->out, + "Second difference for %d = %g Pos(%d)\n", + table->invperm[x],Sx,x); +#endif +#ifdef DD_STATS + secdiff++; +#endif + return(1); + } else { +#ifdef DD_STATS + secdiffmisfire++; +#endif + return(0); + } + + } + return(0); + +} /* end of ddSecDiffCheck */ + + +/**Function******************************************************************** + + Synopsis [Checks for extended symmetry of x and y.] + + Description [Checks for extended symmetry of x and y. Returns 1 in + case of extended symmetry; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddExtSymmCheck( + DdManager * table, + int x, + int y) +{ + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10; + DdNode *one; + unsigned comple; /* f0 is complemented */ + int notproj; /* f is not a projection function */ + int arccount; /* number of arcs from layer x to layer y */ + int TotalRefCount; /* total reference count of layer y minus 1 */ + int counter; /* number of nodes of layer x that are allowed */ + /* to violate extended symmetry conditions */ + int arccounter; /* number of arcs into layer y that are allowed */ + /* to come from layers other than x */ + int i; + int xindex; + int yindex; + int res; + int slots; + DdNodePtr *list; + DdNode *sentinel = &(table->sentinel); + + xindex = table->invperm[x]; + yindex = table->invperm[y]; + + /* If the two variables do not interact, we do not want to merge them. */ + if (!cuddTestInteract(table,xindex,yindex)) + return(0); + +#ifdef DD_DEBUG + /* Checks that x and y do not contain just the projection functions. + ** With the test on interaction, these test become redundant, + ** because an isolated projection function does not interact with + ** any other variable. + */ + if (table->subtables[x].keys == 1) { + assert(table->vars[xindex]->ref != 1); + } + if (table->subtables[y].keys == 1) { + assert(table->vars[yindex]->ref != 1); + } +#endif + +#ifdef DD_STATS + extsymmcalls++; +#endif + + arccount = 0; + counter = (int) (table->subtables[x].keys * + (table->symmviolation/100.0) + 0.5); + one = DD_ONE(table); + + slots = table->subtables[x].slots; + list = table->subtables[x].nodelist; + for (i = 0; i < slots; i++) { + f = list[i]; + while (f != sentinel) { + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + f0 = Cudd_Regular(cuddE(f)); + comple = Cudd_IsComplement(cuddE(f)); + notproj = f1 != one || f0 != one || f->ref != (DdHalfWord) 1; + if (f1->index == (unsigned) yindex) { + arccount++; + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + if ((int) f0->index != yindex) { + /* If f is an isolated projection function it is + ** allowed to bypass layer y. + */ + if (notproj) { + if (counter == 0) + return(0); + counter--; /* f bypasses layer y */ + } + } + f11 = f10 = f1; + } + if ((int) f0->index == yindex) { + arccount++; + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + + /* Unless we are looking at a projection function + ** without external references except the one from the + ** table, we insist that f01 == f10 or f11 == f00 + */ + if (notproj) { + if (f01 != f10 && f11 != f00) { + if (counter == 0) + return(0); + counter--; + } + } + + f = f->next; + } /* while */ + } /* for */ + + /* Calculate the total reference counts of y */ + TotalRefCount = -1; /* -1 for projection function */ + slots = table->subtables[y].slots; + list = table->subtables[y].nodelist; + for (i = 0; i < slots; i++) { + f = list[i]; + while (f != sentinel) { + TotalRefCount += f->ref; + f = f->next; + } + } + + arccounter = (int) (table->subtables[y].keys * + (table->arcviolation/100.0) + 0.5); + res = arccount >= TotalRefCount - arccounter; + +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (res) { + (void) fprintf(table->out, + "Found extended symmetry! x = %d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); + } +#endif + +#ifdef DD_STATS + if (res) + extsymm++; +#endif + return(res); + +} /* end ddExtSymmCheck */ + + +/**Function******************************************************************** + + Synopsis [Checks for grouping of x and y.] + + Description [Checks for grouping of x and y. Returns 1 in + case of grouping; 0 otherwise. This function is used for lazy sifting.] + + SideEffects [None] + +******************************************************************************/ +static int +ddVarGroupCheck( + DdManager * table, + int x, + int y) +{ + int xindex = table->invperm[x]; + int yindex = table->invperm[y]; + + if (Cudd_bddIsVarToBeUngrouped(table, xindex)) return(0); + + if (Cudd_bddReadPairIndex(table, xindex) == yindex) { + if (ddIsVarHandled(table, xindex) || + ddIsVarHandled(table, yindex)) { + if (Cudd_bddIsVarToBeGrouped(table, xindex) || + Cudd_bddIsVarToBeGrouped(table, yindex) ) { + if (table->keys - table->isolated <= originalSize) { + return(1); + } + } + } + } + + return(0); + +} /* end of ddVarGroupCheck */ + + +/**Function******************************************************************** + + Synopsis [Sets a variable to already handled.] + + Description [Sets a variable to already handled. This function is used + for lazy sifting.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static int +ddSetVarHandled( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].varHandled = 1; + return(1); + +} /* end of ddSetVarHandled */ + + +/**Function******************************************************************** + + Synopsis [Resets a variable to be processed.] + + Description [Resets a variable to be processed. This function is used + for lazy sifting.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static int +ddResetVarHandled( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(0); + dd->subtables[dd->perm[index]].varHandled = 0; + return(1); + +} /* end of ddResetVarHandled */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variables is already handled.] + + Description [Checks whether a variables is already handled. This + function is used for lazy sifting.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static int +ddIsVarHandled( + DdManager *dd, + int index) +{ + if (index >= dd->size || index < 0) return(-1); + return dd->subtables[dd->perm[index]].varHandled; + +} /* end of ddIsVarHandled */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddHarwell.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddHarwell.c new file mode 100644 index 000000000..323db91d3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddHarwell.c @@ -0,0 +1,568 @@ +/**CFile*********************************************************************** + + FileName [cuddHarwell.c] + + PackageName [cudd] + + Synopsis [Function to read a matrix in Harwell format.] + + Description [External procedures included in this module: +
                        +
                      • Cudd_addHarwell() +
                      + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddHarwell.c,v 1.10 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads in a matrix in the format of the Harwell-Boeing + benchmark suite.] + + Description [Reads in a matrix in the format of the Harwell-Boeing + benchmark suite. The variables are ordered as follows: +
                      + x\[0\] y\[0\] x\[1\] y\[1\] ... +
                      + 0 is the most significant bit. On input, nx and ny hold the numbers + of row and column variables already in existence. On output, they + hold the numbers of row and column variables actually used by the + matrix. m and n are set to the numbers of rows and columns of the + matrix. Their values on input are immaterial. Returns 1 on + success; 0 otherwise. The ADD for the sparse matrix is returned in + E, and its reference count is > 0.] + + SideEffects [None] + + SeeAlso [Cudd_addRead Cudd_bddRead] + +******************************************************************************/ +int +Cudd_addHarwell( + FILE * fp /* pointer to the input file */, + DdManager * dd /* DD manager */, + DdNode ** E /* characteristic function of the graph */, + DdNode *** x /* array of row variables */, + DdNode *** y /* array of column variables */, + DdNode *** xn /* array of complemented row variables */, + DdNode *** yn_ /* array of complemented column variables */, + int * nx /* number or row variables */, + int * ny /* number or column variables */, + int * m /* number of rows */, + int * n /* number of columns */, + int bx /* first index of row variables */, + int sx /* step of row variables */, + int by /* first index of column variables */, + int sy /* step of column variables */, + int pr /* verbosity level */) +{ + DdNode *one, *zero; + DdNode *w; + DdNode *cubex, *cubey, *minterm1; + int u, v, err, i, j, nv; + double val; + DdNode **lx, **ly, **lxn, **lyn; /* local copies of x, y, xn, yn_ */ + int lnx, lny; /* local copies of nx and ny */ + char title[73], key[9], mxtype[4], rhstyp[4]; + int totcrd, ptrcrd, indcrd, valcrd, rhscrd, + nrow, ncol, nnzero, neltvl, + nrhs, nrhsix; + int *colptr, *rowind; +#if 0 + int nguess, nexact; + int *rhsptr, *rhsind; +#endif + + if (*nx < 0 || *ny < 0) return(0); + + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + /* Read the header */ + err = fscanf(fp, "%72c %8c", title, key); + if (err == EOF) { + return(0); + } else if (err != 2) { + return(0); + } + title[72] = (char) 0; + key[8] = (char) 0; + + err = fscanf(fp, "%d %d %d %d %d", &totcrd, &ptrcrd, &indcrd, + &valcrd, &rhscrd); + if (err == EOF) { + return(0); + } else if (err != 5) { + return(0); + } + + err = fscanf(fp, "%3s %d %d %d %d", mxtype, &nrow, &ncol, + &nnzero, &neltvl); + if (err == EOF) { + return(0); + } else if (err != 5) { + return(0); + } + + /* Skip FORTRAN formats */ + if (rhscrd == 0) { + err = fscanf(fp, "%*s %*s %*s \n"); + } else { + err = fscanf(fp, "%*s %*s %*s %*s \n"); + } + if (err == EOF) { + return(0); + } else if (err != 0) { + return(0); + } + + /* Print out some stuff if requested to be verbose */ + if (pr>0) { + (void) fprintf(dd->out,"%s: type %s, %d rows, %d columns, %d entries\n", key, + mxtype, nrow, ncol, nnzero); + if (pr>1) (void) fprintf(dd->out,"%s\n", title); + } + + /* Check matrix type */ + if (mxtype[0] != 'R' || mxtype[1] != 'U' || mxtype[2] != 'A') { + (void) fprintf(dd->err,"%s: Illegal matrix type: %s\n", + key, mxtype); + return(0); + } + if (neltvl != 0) return(0); + + /* Read optional 5-th line */ + if (rhscrd != 0) { + err = fscanf(fp, "%3c %d %d", rhstyp, &nrhs, &nrhsix); + if (err == EOF) { + return(0); + } else if (err != 3) { + return(0); + } + rhstyp[3] = (char) 0; + if (rhstyp[0] != 'F') { + (void) fprintf(dd->err, + "%s: Sparse right-hand side not yet supported\n", key); + return(0); + } + if (pr>0) (void) fprintf(dd->out,"%d right-hand side(s)\n", nrhs); + } else { + nrhs = 0; + } + + /* Compute the number of variables */ + + /* row and column numbers start from 0 */ + u = nrow - 1; + for (i=0; u > 0; i++) { + u >>= 1; + } + lnx = i; + if (nrhs == 0) { + v = ncol - 1; + } else { + v = 2* (ddMax(ncol, nrhs) - 1); + } + for (i=0; v > 0; i++) { + v >>= 1; + } + lny = i; + + /* Allocate or reallocate arrays for variables as needed */ + if (*nx == 0) { + if (lnx > 0) { + *x = lx = ALLOC(DdNode *,lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *xn = lxn = ALLOC(DdNode *,lnx); + if (lxn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + *x = *xn = NULL; + } + } else if (lnx > *nx) { + *x = lx = REALLOC(DdNode *, *x, lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *xn = lxn = REALLOC(DdNode *, *xn, lnx); + if (lxn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + lx = *x; + lxn = *xn; + } + if (*ny == 0) { + if (lny >0) { + *y = ly = ALLOC(DdNode *,lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *yn_ = lyn = ALLOC(DdNode *,lny); + if (lyn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + *y = *yn_ = NULL; + } + } else if (lny > *ny) { + *y = ly = REALLOC(DdNode *, *y, lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *yn_ = lyn = REALLOC(DdNode *, *yn_, lny); + if (lyn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + ly = *y; + lyn = *yn_; + } + + /* Create new variables as needed */ + for (i= *nx,nv=bx+(*nx)*sx; i < lnx; i++,nv+=sx) { + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); + cuddRef(lx[i]); + do { + dd->reordered = 0; + lxn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lxn[i] == NULL) return(0); + cuddRef(lxn[i]); + } + for (i= *ny,nv=by+(*ny)*sy; i < lny; i++,nv+=sy) { + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); + do { + dd->reordered = 0; + lyn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lyn[i] == NULL) return(0); + cuddRef(lyn[i]); + } + + /* Update matrix parameters */ + *nx = lnx; + *ny = lny; + *m = nrow; + if (nrhs == 0) { + *n = ncol; + } else { + *n = (1 << (lny - 1)) + nrhs; + } + + /* Read structure data */ + colptr = ALLOC(int, ncol+1); + if (colptr == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + rowind = ALLOC(int, nnzero); + if (rowind == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + + for (i=0; ierr,"%s: Unexpected colptr[0] (%d)\n", + key,colptr[0]); + FREE(colptr); + FREE(rowind); + return(0); + } + for (i=0; i=0; nv--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + FREE(colptr); + FREE(rowind); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubey); + cubey = w; + v >>= 1; + } + for (i=colptr[j]; i=0; nv--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + FREE(colptr); + FREE(rowind); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubex); + cubex = w; + u >>= 1; + } + minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); + if (minterm1 == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + FREE(colptr); + FREE(rowind); + return(0); + } + cuddRef(minterm1); + Cudd_RecursiveDeref(dd, cubex); + w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + FREE(colptr); + FREE(rowind); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, *E); + *E = w; + } + Cudd_RecursiveDeref(dd, cubey); + } + FREE(colptr); + FREE(rowind); + + /* Read right-hand sides */ + for (j=0; j=0; nv--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubey); + cubey = w; + v >>= 1; + } + for (i=0; i=0; nv--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubex); + cubex = w; + u >>= 1; + } + minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); + if (minterm1 == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + return(0); + } + cuddRef(minterm1); + Cudd_RecursiveDeref(dd, cubex); + w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, *E); + *E = w; + } + Cudd_RecursiveDeref(dd, cubey); + } + + return(1); + +} /* end of Cudd_addHarwell */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddInit.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddInit.c new file mode 100644 index 000000000..12830bdeb --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddInit.c @@ -0,0 +1,308 @@ +/**CFile*********************************************************************** + + FileName [cuddInit.c] + + PackageName [cudd] + + Synopsis [Functions to initialize and shut down the DD manager.] + + Description [External procedures included in this module: +
                        +
                      • Cudd_Init() +
                      • Cudd_Quit() +
                      + Internal procedures included in this module: +
                        +
                      • cuddZddInitUniv() +
                      • cuddZddFreeUniv() +
                      + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddInit.c,v 1.34 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Creates a new DD manager.] + + Description [Creates a new DD manager, initializes the table, the + basic constants and the projection functions. If maxMemory is 0, + Cudd_Init decides suitable values for the maximum size of the cache + and for the limit for fast unique table growth based on the available + memory. Returns a pointer to the manager if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Quit] + +******************************************************************************/ +DdManager * +Cudd_Init( + unsigned int numVars /* initial number of BDD variables (i.e., subtables) */, + unsigned int numVarsZ /* initial number of ZDD variables (i.e., subtables) */, + unsigned int numSlots /* initial size of the unique tables */, + unsigned int cacheSize /* initial size of the cache */, + unsigned long maxMemory /* target maximum memory occupation */) +{ + DdManager *unique; + int i,result; + DdNode *one, *zero; + unsigned int maxCacheSize; + unsigned int looseUpTo; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (maxMemory == 0) { + maxMemory = getSoftDataLimit(); + } + looseUpTo = (unsigned int) ((maxMemory / sizeof(DdNode)) / + DD_MAX_LOOSE_FRACTION); + unique = cuddInitTable(numVars,numVarsZ,numSlots,looseUpTo); + if (unique == NULL) return(NULL); + unique->maxmem = (unsigned long) maxMemory / 10 * 9; + maxCacheSize = (unsigned int) ((maxMemory / sizeof(DdCache)) / + DD_MAX_CACHE_FRACTION); + result = cuddInitCache(unique,cacheSize,maxCacheSize); + if (result == 0) return(NULL); + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + unique->stash = ALLOC(char,(maxMemory / DD_STASH_FRACTION) + 4); + MMoutOfMemory = saveHandler; + if (unique->stash == NULL) { + (void) fprintf(unique->err,"Unable to set aside memory\n"); + } + + /* Initialize constants. */ + unique->one = cuddUniqueConst(unique,1.0); + if (unique->one == NULL) return(0); + cuddRef(unique->one); + unique->zero = cuddUniqueConst(unique,0.0); + if (unique->zero == NULL) return(0); + cuddRef(unique->zero); +#ifdef HAVE_IEEE_754 + if (DD_PLUS_INF_VAL != DD_PLUS_INF_VAL * 3 || + DD_PLUS_INF_VAL != DD_PLUS_INF_VAL / 3) { + (void) fprintf(unique->err,"Warning: Crippled infinite values\n"); + (void) fprintf(unique->err,"Recompile without -DHAVE_IEEE_754\n"); + } +#endif + unique->plusinfinity = cuddUniqueConst(unique,DD_PLUS_INF_VAL); + if (unique->plusinfinity == NULL) return(0); + cuddRef(unique->plusinfinity); + unique->minusinfinity = cuddUniqueConst(unique,DD_MINUS_INF_VAL); + if (unique->minusinfinity == NULL) return(0); + cuddRef(unique->minusinfinity); + unique->background = unique->zero; + + /* The logical zero is different from the CUDD_VALUE_TYPE zero! */ + one = unique->one; + zero = Cudd_Not(one); + /* Create the projection functions. */ + unique->vars = ALLOC(DdNodePtr,unique->maxSize); + if (unique->vars == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < unique->size; i++) { + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) return(0); + cuddRef(unique->vars[i]); + } + + if (unique->sizeZ) + cuddZddInitUniv(unique); + + unique->memused += sizeof(DdNode *) * unique->maxSize; + + return(unique); + +} /* end of Cudd_Init */ + + +/**Function******************************************************************** + + Synopsis [Deletes resources associated with a DD manager.] + + Description [Deletes resources associated with a DD manager and + resets the global statistical counters. (Otherwise, another manaqger + subsequently created would inherit the stats of this one.)] + + SideEffects [None] + + SeeAlso [Cudd_Init] + +******************************************************************************/ +void +Cudd_Quit( + DdManager * unique) +{ + if (unique->stash != NULL) FREE(unique->stash); + cuddFreeTable(unique); + +} /* end of Cudd_Quit */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes the ZDD universe.] + + Description [Initializes the ZDD universe. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddZddFreeUniv] + +******************************************************************************/ +int +cuddZddInitUniv( + DdManager * zdd) +{ + DdNode *p, *res; + int i; + + zdd->univ = ALLOC(DdNodePtr, zdd->sizeZ); + if (zdd->univ == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + + res = DD_ONE(zdd); + cuddRef(res); + for (i = zdd->sizeZ - 1; i >= 0; i--) { + unsigned int index = zdd->invpermZ[i]; + p = res; + res = cuddUniqueInterZdd(zdd, index, p, p); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd,p); + FREE(zdd->univ); + return(0); + } + cuddRef(res); + cuddDeref(p); + zdd->univ[i] = res; + } + +#ifdef DD_VERBOSE + cuddZddP(zdd, zdd->univ[0]); +#endif + + return(1); + +} /* end of cuddZddInitUniv */ + + +/**Function******************************************************************** + + Synopsis [Frees the ZDD universe.] + + Description [Frees the ZDD universe.] + + SideEffects [None] + + SeeAlso [cuddZddInitUniv] + +******************************************************************************/ +void +cuddZddFreeUniv( + DdManager * zdd) +{ + if (zdd->univ) { + Cudd_RecursiveDerefZdd(zdd, zdd->univ[0]); + FREE(zdd->univ); + } + +} /* end of cuddZddFreeUniv */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddInteract.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddInteract.c new file mode 100644 index 000000000..42fc68046 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddInteract.c @@ -0,0 +1,432 @@ +/**CFile*********************************************************************** + + FileName [cuddInteract.c] + + PackageName [cudd] + + Synopsis [Functions to manipulate the variable interaction matrix.] + + Description [Internal procedures included in this file: +
                        +
                      • cuddSetInteract() +
                      • cuddTestInteract() +
                      • cuddInitInteract() +
                      + Static procedures included in this file: +
                        +
                      • ddSuppInteract() +
                      • ddClearLocal() +
                      • ddUpdateInteract() +
                      • ddClearGlobal() +
                      + The interaction matrix tells whether two variables are + both in the support of some function of the DD. The main use of the + interaction matrix is in the in-place swapping. Indeed, if two + variables do not interact, there is no arc connecting the two layers; + therefore, the swap can be performed in constant time, without + scanning the subtables. Another use of the interaction matrix is in + the computation of the lower bounds for sifting. Finally, the + interaction matrix can be used to speed up aggregation checks in + symmetric and group sifting.

                      + The computation of the interaction matrix is done with a series of + depth-first searches. The searches start from those nodes that have + only external references. The matrix is stored as a packed array of bits; + since it is symmetric, only the upper triangle is kept in memory. + As a final remark, we note that there may be variables that do + interact, but that for a given variable order have no arc connecting + their layers when they are adjacent. For instance, in ite(a,b,c) with + the order asize, + sets the corresponding bit of the interaction matrix to 1.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddSetInteract( + DdManager * table, + int x, + int y) +{ + int posn, word, bit; + +#ifdef DD_DEBUG + assert(x < y); + assert(y < table->size); + assert(x >= 0); +#endif + + posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1; + word = posn >> LOGBPL; + bit = posn & (BPL-1); + table->interact[word] |= 1L << bit; + +} /* end of cuddSetInteract */ + + +/**Function******************************************************************** + + Synopsis [Test interaction matrix entries.] + + Description [Given a pair of variables 0 <= x < y < table->size, + tests whether the corresponding bit of the interaction matrix is 1. + Returns the value of the bit.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddTestInteract( + DdManager * table, + int x, + int y) +{ + int posn, word, bit, result; + + if (x > y) { + int tmp = x; + x = y; + y = tmp; + } +#ifdef DD_DEBUG + assert(x < y); + assert(y < table->size); + assert(x >= 0); +#endif + + posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1; + word = posn >> LOGBPL; + bit = posn & (BPL-1); + result = (table->interact[word] >> bit) & 1L; + return(result); + +} /* end of cuddTestInteract */ + + +/**Function******************************************************************** + + Synopsis [Initializes the interaction matrix.] + + Description [Initializes the interaction matrix. The interaction + matrix is implemented as a bit vector storing the upper triangle of + the symmetric interaction matrix. The bit vector is kept in an array + of long integers. The computation is based on a series of depth-first + searches, one for each root of the DAG. Two flags are needed: The + local visited flag uses the LSB of the then pointer. The global + visited flag uses the LSB of the next pointer. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddInitInteract( + DdManager * table) +{ + int i,j; + unsigned long words; + long *interact; + char *support; + DdNode *f; + DdNode *sentinel = &(table->sentinel); + DdNodePtr *nodelist; + int slots; + unsigned long n = (unsigned long) table->size; + + words = ((n * (n-1)) >> (1 + LOGBPL)) + 1; + table->interact = interact = ALLOC(long,words); + if (interact == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < words; i++) { + interact[i] = 0; + } + + support = ALLOC(char,n); + if (support == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + FREE(interact); + return(0); + } + for (i = 0; i < n; i++) { + support[i] = 0; + } + + for (i = 0; i < n; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + /* A node is a root of the DAG if it cannot be + ** reached by nodes above it. If a node was never + ** reached during the previous depth-first searches, + ** then it is a root, and we start a new depth-first + ** search from it. + */ + if (!Cudd_IsComplement(f->next)) { + ddSuppInteract(f,support); + ddClearLocal(f); + ddUpdateInteract(table,support); + } + f = Cudd_Regular(f->next); + } + } + } + ddClearGlobal(table); + + FREE(support); + return(1); + +} /* end of cuddInitInteract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Find the support of f.] + + Description [Performs a DFS from f. Uses the LSB of the then pointer + as visited flag.] + + SideEffects [Accumulates in support the variables on which f depends.] + + SeeAlso [] + +******************************************************************************/ +static void +ddSuppInteract( + DdNode * f, + char * support) +{ + if (cuddIsConstant(f) || Cudd_IsComplement(cuddT(f))) { + return; + } + + support[f->index] = 1; + ddSuppInteract(cuddT(f),support); + ddSuppInteract(Cudd_Regular(cuddE(f)),support); + /* mark as visited */ + cuddT(f) = Cudd_Complement(cuddT(f)); + f->next = Cudd_Complement(f->next); + return; + +} /* end of ddSuppInteract */ + + +/**Function******************************************************************** + + Synopsis [Performs a DFS from f, clearing the LSB of the then pointers.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ddClearLocal( + DdNode * f) +{ + if (cuddIsConstant(f) || !Cudd_IsComplement(cuddT(f))) { + return; + } + /* clear visited flag */ + cuddT(f) = Cudd_Regular(cuddT(f)); + ddClearLocal(cuddT(f)); + ddClearLocal(Cudd_Regular(cuddE(f))); + return; + +} /* end of ddClearLocal */ + + +/**Function******************************************************************** + + Synopsis [Marks as interacting all pairs of variables that appear in + support.] + + Description [If support[i] == support[j] == 1, sets the (i,j) entry + of the interaction matrix to 1.] + + SideEffects [Clears support.] + + SeeAlso [] + +******************************************************************************/ +static void +ddUpdateInteract( + DdManager * table, + char * support) +{ + int i,j; + int n = table->size; + + for (i = 0; i < n-1; i++) { + if (support[i] == 1) { + support[i] = 0; + for (j = i+1; j < n; j++) { + if (support[j] == 1) { + cuddSetInteract(table,i,j); + } + } + } + } + support[n-1] = 0; + +} /* end of ddUpdateInteract */ + + +/**Function******************************************************************** + + Synopsis [Scans the DD and clears the LSB of the next pointers.] + + Description [The LSB of the next pointers are used as markers to tell + whether a node was reached by at least one DFS. Once the interaction + matrix is built, these flags are reset.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ddClearGlobal( + DdManager * table) +{ + int i,j; + DdNode *f; + DdNode *sentinel = &(table->sentinel); + DdNodePtr *nodelist; + int slots; + + for (i = 0; i < table->size; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + f->next = Cudd_Regular(f->next); + f = f->next; + } + } + } + +} /* end of ddClearGlobal */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLCache.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLCache.c new file mode 100644 index 000000000..63186e105 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLCache.c @@ -0,0 +1,1557 @@ +/**CFile*********************************************************************** + + FileName [cuddLCache.c] + + PackageName [cudd] + + Synopsis [Functions for local caches.] + + Description [Internal procedures included in this module: +

                        +
                      • cuddLocalCacheInit() +
                      • cuddLocalCacheQuit() +
                      • cuddLocalCacheInsert() +
                      • cuddLocalCacheLookup() +
                      • cuddLocalCacheClearDead() +
                      • cuddLocalCacheClearAll() +
                      • cuddLocalCacheProfile() +
                      • cuddHashTableInit() +
                      • cuddHashTableQuit() +
                      • cuddHashTableGenericQuit() +
                      • cuddHashTableInsert() +
                      • cuddHashTableLookup() +
                      • cuddHashTableGenericInsert() +
                      • cuddHashTableGenericLookup() +
                      • cuddHashTableInsert2() +
                      • cuddHashTableLookup2() +
                      • cuddHashTableInsert3() +
                      • cuddHashTableLookup3() +
                      + Static procedures included in this module: +
                        +
                      • cuddLocalCacheResize() +
                      • ddLCHash() +
                      • cuddLocalCacheAddToList() +
                      • cuddLocalCacheRemoveFromList() +
                      • cuddHashTableResize() +
                      • cuddHashTableAlloc() +
                      ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_MAX_HASHTABLE_DENSITY 2 /* tells when to resize a table */ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.27 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Computes hash function for keys of one operand.] + + Description [] + + SideEffects [None] + + SeeAlso [ddLCHash3 ddLCHash] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddLCHash1(f,shift) \ +(((unsigned)(ptruint)(f) * DD_P1) >> (shift)) +#else +#define ddLCHash1(f,shift) \ +(((unsigned)(f) * DD_P1) >> (shift)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Computes hash function for keys of two operands.] + + Description [] + + SideEffects [None] + + SeeAlso [ddLCHash3 ddLCHash] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddLCHash2(f,g,shift) \ +((((unsigned)(ptruint)(f) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (shift)) +#else +#define ddLCHash2(f,g,shift) \ +((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Computes hash function for keys of three operands.] + + Description [] + + SideEffects [None] + + SeeAlso [ddLCHash2 ddLCHash] + +******************************************************************************/ +#define ddLCHash3(f,g,h,shift) ddCHash2(f,g,h,shift) + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void cuddLocalCacheResize (DdLocalCache *cache); +DD_INLINE static unsigned int ddLCHash (DdNodePtr *key, unsigned int keysize, int shift); +static void cuddLocalCacheAddToList (DdLocalCache *cache); +static void cuddLocalCacheRemoveFromList (DdLocalCache *cache); +static int cuddHashTableResize (DdHashTable *hash); +DD_INLINE static DdHashItem * cuddHashTableAlloc (DdHashTable *hash); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes a local computed table.] + + Description [Initializes a computed table. Returns a pointer the + the new local cache in case of success; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddInitCache] + +******************************************************************************/ +DdLocalCache * +cuddLocalCacheInit( + DdManager * manager /* manager */, + unsigned int keySize /* size of the key (number of operands) */, + unsigned int cacheSize /* Initial size of the cache */, + unsigned int maxCacheSize /* Size of the cache beyond which no resizing occurs */) +{ + DdLocalCache *cache; + int logSize; + + cache = ALLOC(DdLocalCache,1); + if (cache == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + cache->manager = manager; + cache->keysize = keySize; + cache->itemsize = (keySize + 1) * sizeof(DdNode *); +#ifdef DD_CACHE_PROFILE + cache->itemsize += sizeof(ptrint); +#endif + logSize = cuddComputeFloorLog2(ddMax(cacheSize,manager->slots/2)); + cacheSize = 1 << logSize; + cache->item = (DdLocalCacheItem *) + ALLOC(char, cacheSize * cache->itemsize); + if (cache->item == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + FREE(cache); + return(NULL); + } + cache->slots = cacheSize; + cache->shift = sizeof(int) * 8 - logSize; + cache->maxslots = ddMin(maxCacheSize,manager->slots); + cache->minHit = manager->minHit; + /* Initialize to avoid division by 0 and immediate resizing. */ + cache->lookUps = (double) (int) (cacheSize * cache->minHit + 1); + cache->hits = 0; + manager->memused += cacheSize * cache->itemsize + sizeof(DdLocalCache); + + /* Initialize the cache. */ + memset(cache->item, 0, cacheSize * cache->itemsize); + + /* Add to manager's list of local caches for GC. */ + cuddLocalCacheAddToList(cache); + + return(cache); + +} /* end of cuddLocalCacheInit */ + + +/**Function******************************************************************** + + Synopsis [Shuts down a local computed table.] + + Description [Initializes the computed table. It is called by + Cudd_Init. Returns a pointer the the new local cache in case of + success; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddLocalCacheInit] + +******************************************************************************/ +void +cuddLocalCacheQuit( + DdLocalCache * cache /* cache to be shut down */) +{ + cache->manager->memused -= + cache->slots * cache->itemsize + sizeof(DdLocalCache); + cuddLocalCacheRemoveFromList(cache); + FREE(cache->item); + FREE(cache); + + return; + +} /* end of cuddLocalCacheQuit */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in a local cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddLocalCacheInsert( + DdLocalCache * cache, + DdNodePtr * key, + DdNode * value) +{ + unsigned int posn; + DdLocalCacheItem *entry; + + posn = ddLCHash(key,cache->keysize,cache->shift); + entry = (DdLocalCacheItem *) ((char *) cache->item + + posn * cache->itemsize); + memcpy(entry->key,key,cache->keysize * sizeof(DdNode *)); + entry->value = value; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddLocalCacheInsert */ + + +/**Function******************************************************************** + + Synopsis [Looks up in a local cache.] + + Description [Looks up in a local cache. Returns the result if found; + it returns NULL if no result is found.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddLocalCacheLookup( + DdLocalCache * cache, + DdNodePtr * key) +{ + unsigned int posn; + DdLocalCacheItem *entry; + DdNode *value; + + cache->lookUps++; + posn = ddLCHash(key,cache->keysize,cache->shift); + entry = (DdLocalCacheItem *) ((char *) cache->item + + posn * cache->itemsize); + if (entry->value != NULL && + memcmp(key,entry->key,cache->keysize*sizeof(DdNode *)) == 0) { + cache->hits++; + value = Cudd_Regular(entry->value); + if (value->ref == 0) { + cuddReclaim(cache->manager,value); + } + return(entry->value); + } + + /* Cache miss: decide whether to resize */ + + if (cache->slots < cache->maxslots && + cache->hits > cache->lookUps * cache->minHit) { + cuddLocalCacheResize(cache); + } + + return(NULL); + +} /* end of cuddLocalCacheLookup */ + + +/**Function******************************************************************** + + Synopsis [Clears the dead entries of the local caches of a manager.] + + Description [Clears the dead entries of the local caches of a manager. + Used during garbage collection.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddLocalCacheClearDead( + DdManager * manager) +{ + DdLocalCache *cache = manager->localCaches; + unsigned int keysize; + unsigned int itemsize; + unsigned int slots; + DdLocalCacheItem *item; + DdNodePtr *key; + unsigned int i, j; + + while (cache != NULL) { + keysize = cache->keysize; + itemsize = cache->itemsize; + slots = cache->slots; + item = cache->item; + for (i = 0; i < slots; i++) { + if (item->value != NULL) { + if (Cudd_Regular(item->value)->ref == 0) { + item->value = NULL; + } else { + key = item->key; + for (j = 0; j < keysize; j++) { + if (Cudd_Regular(key[j])->ref == 0) { + item->value = NULL; + break; + } + } + } + } + item = (DdLocalCacheItem *) ((char *) item + itemsize); + } + cache = cache->next; + } + return; + +} /* end of cuddLocalCacheClearDead */ + + +/**Function******************************************************************** + + Synopsis [Clears the local caches of a manager.] + + Description [Clears the local caches of a manager. + Used before reordering.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddLocalCacheClearAll( + DdManager * manager) +{ + DdLocalCache *cache = manager->localCaches; + + while (cache != NULL) { + memset(cache->item, 0, cache->slots * cache->itemsize); + cache = cache->next; + } + return; + +} /* end of cuddLocalCacheClearAll */ + + +#ifdef DD_CACHE_PROFILE + +#define DD_HYSTO_BINS 8 + +/**Function******************************************************************** + + Synopsis [Computes and prints a profile of a local cache usage.] + + Description [Computes and prints a profile of a local cache usage. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddLocalCacheProfile( + DdLocalCache * cache) +{ + double count, mean, meansq, stddev, expected; + long max, min; + int imax, imin; + int i, retval, slots; + long *hystogram; + int nbins = DD_HYSTO_BINS; + int bin; + long thiscount; + double totalcount; + int nzeroes; + DdLocalCacheItem *entry; + FILE *fp = cache->manager->out; + + slots = cache->slots; + + meansq = mean = expected = 0.0; + max = min = (long) cache->item[0].count; + imax = imin = nzeroes = 0; + totalcount = 0.0; + + hystogram = ALLOC(long, nbins); + if (hystogram == NULL) { + return(0); + } + for (i = 0; i < nbins; i++) { + hystogram[i] = 0; + } + + for (i = 0; i < slots; i++) { + entry = (DdLocalCacheItem *) ((char *) cache->item + + i * cache->itemsize); + thiscount = (long) entry->count; + if (thiscount > max) { + max = thiscount; + imax = i; + } + if (thiscount < min) { + min = thiscount; + imin = i; + } + if (thiscount == 0) { + nzeroes++; + } + count = (double) thiscount; + mean += count; + meansq += count * count; + totalcount += count; + expected += count * (double) i; + bin = (i * nbins) / slots; + hystogram[bin] += thiscount; + } + mean /= (double) slots; + meansq /= (double) slots; + stddev = sqrt(meansq - mean*mean); + + retval = fprintf(fp,"Cache stats: slots = %d average = %g ", slots, mean); + if (retval == EOF) return(0); + retval = fprintf(fp,"standard deviation = %g\n", stddev); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache max accesses = %ld for slot %d\n", max, imax); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache min accesses = %ld for slot %d\n", min, imin); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache unused slots = %d\n", nzeroes); + if (retval == EOF) return(0); + + if (totalcount) { + expected /= totalcount; + retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); + if (retval == EOF) return(0); + retval = fprintf(fp," (expected bin value = %g)\n# ", expected); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp,"%ld ", hystogram[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\n"); + if (retval == EOF) return(0); + } + + FREE(hystogram); + return(1); + +} /* end of cuddLocalCacheProfile */ +#endif + + +/**Function******************************************************************** + + Synopsis [Initializes a hash table.] + + Description [Initializes a hash table. Returns a pointer to the new + table if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableQuit] + +******************************************************************************/ +DdHashTable * +cuddHashTableInit( + DdManager * manager, + unsigned int keySize, + unsigned int initSize) +{ + DdHashTable *hash; + int logSize; + + hash = ALLOC(DdHashTable, 1); + if (hash == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + hash->keysize = keySize; + hash->manager = manager; + hash->memoryList = NULL; + hash->nextFree = NULL; + hash->itemsize = (keySize + 1) * sizeof(DdNode *) + + sizeof(ptrint) + sizeof(DdHashItem *); + /* We have to guarantee that the shift be < 32. */ + if (initSize < 2) initSize = 2; + logSize = cuddComputeFloorLog2(initSize); + hash->numBuckets = 1 << logSize; + hash->shift = sizeof(int) * 8 - logSize; + hash->bucket = ALLOC(DdHashItem *, hash->numBuckets); + if (hash->bucket == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + FREE(hash); + return(NULL); + } + memset(hash->bucket, 0, hash->numBuckets * sizeof(DdHashItem *)); + hash->size = 0; + hash->maxsize = hash->numBuckets * DD_MAX_HASHTABLE_DENSITY; + return(hash); + +} /* end of cuddHashTableInit */ + + +/**Function******************************************************************** + + Synopsis [Shuts down a hash table.] + + Description [Shuts down a hash table, dereferencing all the values.] + + SideEffects [None] + + SeeAlso [cuddHashTableInit] + +******************************************************************************/ +void +cuddHashTableQuit( + DdHashTable * hash) +{ + unsigned int i; + DdManager *dd = hash->manager; + DdHashItem *bucket; + DdHashItem **memlist, **nextmem; + unsigned int numBuckets = hash->numBuckets; + + for (i = 0; i < numBuckets; i++) { + bucket = hash->bucket[i]; + while (bucket != NULL) { + Cudd_RecursiveDeref(dd, bucket->value); + bucket = bucket->next; + } + } + + memlist = hash->memoryList; + while (memlist != NULL) { + nextmem = (DdHashItem **) memlist[0]; + FREE(memlist); + memlist = nextmem; + } + + FREE(hash->bucket); + FREE(hash); + + return; + +} /* end of cuddHashTableQuit */ + + +/**Function******************************************************************** + + Synopsis [Shuts down a hash table.] + + Description [Shuts down a hash table, when the values are not DdNode + pointers.] + + SideEffects [None] + + SeeAlso [cuddHashTableInit] + +******************************************************************************/ +void +cuddHashTableGenericQuit( + DdHashTable * hash) +{ +#ifdef __osf__ +#pragma pointer_size save +#pragma pointer_size short +#endif + DdHashItem **memlist, **nextmem; + + memlist = hash->memoryList; + while (memlist != NULL) { + nextmem = (DdHashItem **) memlist[0]; + FREE(memlist); + memlist = nextmem; + } + + FREE(hash->bucket); + FREE(hash); +#ifdef __osf__ +#pragma pointer_size restore +#endif + + return; + +} /* end of cuddHashTableGenericQuit */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key has more than + three pointers. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [[cuddHashTableInsert1 cuddHashTableInsert2 cuddHashTableInsert3 + cuddHashTableLookup] + +******************************************************************************/ +int +cuddHashTableInsert( + DdHashTable * hash, + DdNodePtr * key, + DdNode * value, + ptrint count) +{ + int result; + unsigned int posn; + DdHashItem *item; + unsigned int i; + +#ifdef DD_DEBUG + assert(hash->keysize > 3); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = value; + cuddRef(value); + item->count = count; + for (i = 0; i < hash->keysize; i++) { + item->key[i] = key[i]; + } + posn = ddLCHash(key,hash->keysize,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableInsert */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key in a hash table.] + + Description [Looks up a key consisting of more than three pointers + in a hash table. Returns the value associated to the key if there + is an entry for the given key in the table; NULL otherwise. If the + entry is present, its reference counter is decremented if not + saturated. If the counter reaches 0, the value of the entry is + dereferenced, and the entry is returned to the free list.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup1 cuddHashTableLookup2 cuddHashTableLookup3 + cuddHashTableInsert] + +******************************************************************************/ +DdNode * +cuddHashTableLookup( + DdHashTable * hash, + DdNodePtr * key) +{ + unsigned int posn; + DdHashItem *item, *prev; + unsigned int i, keysize; + +#ifdef DD_DEBUG + assert(hash->keysize > 3); +#endif + + posn = ddLCHash(key,hash->keysize,hash->shift); + item = hash->bucket[posn]; + prev = NULL; + + keysize = hash->keysize; + while (item != NULL) { + DdNodePtr *key2 = item->key; + int equal = 1; + for (i = 0; i < keysize; i++) { + if (key[i] != key2[i]) { + equal = 0; + break; + } + } + if (equal) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); + } + prev = item; + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableLookup */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key is one pointer. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert cuddHashTableInsert2 cuddHashTableInsert3 + cuddHashTableLookup1] + +******************************************************************************/ +int +cuddHashTableInsert1( + DdHashTable * hash, + DdNode * f, + DdNode * value, + ptrint count) +{ + int result; + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 1); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = value; + cuddRef(value); + item->count = count; + item->key[0] = f; + posn = ddLCHash1(f,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableInsert1 */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key consisting of one pointer in a hash table.] + + Description [Looks up a key consisting of one pointer in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup cuddHashTableLookup2 cuddHashTableLookup3 + cuddHashTableInsert1] + +******************************************************************************/ +DdNode * +cuddHashTableLookup1( + DdHashTable * hash, + DdNode * f) +{ + unsigned int posn; + DdHashItem *item, *prev; + +#ifdef DD_DEBUG + assert(hash->keysize == 1); +#endif + + posn = ddLCHash1(f,hash->shift); + item = hash->bucket[posn]; + prev = NULL; + + while (item != NULL) { + DdNodePtr *key = item->key; + if (f == key[0]) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); + } + prev = item; + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableLookup1 */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key is one + pointer and the value is not a DdNode pointer. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert1 cuddHashTableGenericLookup] + +******************************************************************************/ +int +cuddHashTableGenericInsert( + DdHashTable * hash, + DdNode * f, + void * value) +{ + int result; + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 1); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = (DdNode *) value; + item->count = 0; + item->key[0] = f; + posn = ddLCHash1(f,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableGenericInsert */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key consisting of one pointer in a hash table.] + + Description [Looks up a key consisting of one pointer in a hash + table when the value is not a DdNode pointer. Returns the value + associated to the key if there is an entry for the given key in the + table; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup1 cuddHashTableGenericInsert] + +******************************************************************************/ +void * +cuddHashTableGenericLookup( + DdHashTable * hash, + DdNode * f) +{ + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 1); +#endif + + posn = ddLCHash1(f,hash->shift); + item = hash->bucket[posn]; + + while (item != NULL) { + if (f == item->key[0]) { + return ((void *) item->value); + } + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableGenericLookup */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key is + composed of two pointers. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert3 + cuddHashTableLookup2] + +******************************************************************************/ +int +cuddHashTableInsert2( + DdHashTable * hash, + DdNode * f, + DdNode * g, + DdNode * value, + ptrint count) +{ + int result; + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 2); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = value; + cuddRef(value); + item->count = count; + item->key[0] = f; + item->key[1] = g; + posn = ddLCHash2(f,g,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableInsert2 */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key consisting of two pointers in a hash table.] + + Description [Looks up a key consisting of two pointer in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup3 + cuddHashTableInsert2] + +******************************************************************************/ +DdNode * +cuddHashTableLookup2( + DdHashTable * hash, + DdNode * f, + DdNode * g) +{ + unsigned int posn; + DdHashItem *item, *prev; + +#ifdef DD_DEBUG + assert(hash->keysize == 2); +#endif + + posn = ddLCHash2(f,g,hash->shift); + item = hash->bucket[posn]; + prev = NULL; + + while (item != NULL) { + DdNodePtr *key = item->key; + if ((f == key[0]) && (g == key[1])) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); + } + prev = item; + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableLookup2 */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in a hash table.] + + Description [Inserts an item in a hash table when the key is + composed of three pointers. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert2 + cuddHashTableLookup3] + +******************************************************************************/ +int +cuddHashTableInsert3( + DdHashTable * hash, + DdNode * f, + DdNode * g, + DdNode * h, + DdNode * value, + ptrint count) +{ + int result; + unsigned int posn; + DdHashItem *item; + +#ifdef DD_DEBUG + assert(hash->keysize == 3); +#endif + + if (hash->size > hash->maxsize) { + result = cuddHashTableResize(hash); + if (result == 0) return(0); + } + item = cuddHashTableAlloc(hash); + if (item == NULL) return(0); + hash->size++; + item->value = value; + cuddRef(value); + item->count = count; + item->key[0] = f; + item->key[1] = g; + item->key[2] = h; + posn = ddLCHash3(f,g,h,hash->shift); + item->next = hash->bucket[posn]; + hash->bucket[posn] = item; + + return(1); + +} /* end of cuddHashTableInsert3 */ + + +/**Function******************************************************************** + + Synopsis [Looks up a key consisting of three pointers in a hash table.] + + Description [Looks up a key consisting of three pointers in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list.] + + SideEffects [None] + + SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup2 + cuddHashTableInsert3] + +******************************************************************************/ +DdNode * +cuddHashTableLookup3( + DdHashTable * hash, + DdNode * f, + DdNode * g, + DdNode * h) +{ + unsigned int posn; + DdHashItem *item, *prev; + +#ifdef DD_DEBUG + assert(hash->keysize == 3); +#endif + + posn = ddLCHash3(f,g,h,hash->shift); + item = hash->bucket[posn]; + prev = NULL; + + while (item != NULL) { + DdNodePtr *key = item->key; + if ((f == key[0]) && (g == key[1]) && (h == key[2])) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); + } + prev = item; + item = item->next; + } + return(NULL); + +} /* end of cuddHashTableLookup3 */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Resizes a local cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +cuddLocalCacheResize( + DdLocalCache * cache) +{ + DdLocalCacheItem *item, *olditem, *entry, *old; + int i, shift; + unsigned int posn; + unsigned int slots, oldslots; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + olditem = cache->item; + oldslots = cache->slots; + slots = cache->slots = oldslots << 1; + +#ifdef DD_VERBOSE + (void) fprintf(cache->manager->err, + "Resizing local cache from %d to %d entries\n", + oldslots, slots); + (void) fprintf(cache->manager->err, + "\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n", + cache->hits, cache->lookUps, cache->hits / cache->lookUps); +#endif + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + cache->item = item = + (DdLocalCacheItem *) ALLOC(char, slots * cache->itemsize); + MMoutOfMemory = saveHandler; + /* If we fail to allocate the new table we just give up. */ + if (item == NULL) { +#ifdef DD_VERBOSE + (void) fprintf(cache->manager->err,"Resizing failed. Giving up.\n"); +#endif + cache->slots = oldslots; + cache->item = olditem; + /* Do not try to resize again. */ + cache->maxslots = oldslots - 1; + return; + } + shift = --(cache->shift); + cache->manager->memused += (slots - oldslots) * cache->itemsize; + + /* Clear new cache. */ + memset(item, 0, slots * cache->itemsize); + + /* Copy from old cache to new one. */ + for (i = 0; (unsigned) i < oldslots; i++) { + old = (DdLocalCacheItem *) ((char *) olditem + i * cache->itemsize); + if (old->value != NULL) { + posn = ddLCHash(old->key,cache->keysize,shift); + entry = (DdLocalCacheItem *) ((char *) item + + posn * cache->itemsize); + memcpy(entry->key,old->key,cache->keysize*sizeof(DdNode *)); + entry->value = old->value; + } + } + + FREE(olditem); + + /* Reinitialize measurements so as to avoid division by 0 and + ** immediate resizing. + */ + cache->lookUps = (double) (int) (slots * cache->minHit + 1); + cache->hits = 0; + +} /* end of cuddLocalCacheResize */ + + +/**Function******************************************************************** + + Synopsis [Computes the hash value for a local cache.] + + Description [Computes the hash value for a local cache. Returns the + bucket index.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static unsigned int +ddLCHash( + DdNodePtr * key, + unsigned int keysize, + int shift) +{ + unsigned int val = (unsigned int) (ptrint) key[0] * DD_P2; + unsigned int i; + + for (i = 1; i < keysize; i++) { + val = val * DD_P1 + (int) (ptrint) key[i]; + } + + return(val >> shift); + +} /* end of ddLCHash */ + + +/**Function******************************************************************** + + Synopsis [Inserts a local cache in the manager list.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +cuddLocalCacheAddToList( + DdLocalCache * cache) +{ + DdManager *manager = cache->manager; + + cache->next = manager->localCaches; + manager->localCaches = cache; + return; + +} /* end of cuddLocalCacheAddToList */ + + +/**Function******************************************************************** + + Synopsis [Removes a local cache from the manager list.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +cuddLocalCacheRemoveFromList( + DdLocalCache * cache) +{ + DdManager *manager = cache->manager; + DdLocalCache **prevCache, *nextCache; + + prevCache = &(manager->localCaches); + nextCache = manager->localCaches; + + while (nextCache != NULL) { + if (nextCache == cache) { + *prevCache = nextCache->next; + return; + } + prevCache = &(nextCache->next); + nextCache = nextCache->next; + } + return; /* should never get here */ + +} /* end of cuddLocalCacheRemoveFromList */ + + +/**Function******************************************************************** + + Synopsis [Resizes a hash table.] + + Description [Resizes a hash table. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddHashTableInsert] + +******************************************************************************/ +static int +cuddHashTableResize( + DdHashTable * hash) +{ + int j; + unsigned int posn; + DdHashItem *item; + DdHashItem *next; + DdNode **key; + int numBuckets; + DdHashItem **buckets; + DdHashItem **oldBuckets = hash->bucket; + int shift; + int oldNumBuckets = hash->numBuckets; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + /* Compute the new size of the table. */ + numBuckets = oldNumBuckets << 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + buckets = ALLOC(DdHashItem *, numBuckets); + MMoutOfMemory = saveHandler; + if (buckets == NULL) { + hash->maxsize <<= 1; + return(1); + } + + hash->bucket = buckets; + hash->numBuckets = numBuckets; + shift = --(hash->shift); + hash->maxsize <<= 1; + memset(buckets, 0, numBuckets * sizeof(DdHashItem *)); + if (hash->keysize == 1) { + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash2(key[0], key[0], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + } else if (hash->keysize == 2) { + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash2(key[0], key[1], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + } else if (hash->keysize == 3) { + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash3(key[0], key[1], key[2], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + } else { + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + posn = ddLCHash(item->key, hash->keysize, shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + } + FREE(oldBuckets); + return(1); + +} /* end of cuddHashTableResize */ + + +/**Function******************************************************************** + + Synopsis [Fast storage allocation for items in a hash table.] + + Description [Fast storage allocation for items in a hash table. The + first 4 bytes of a chunk contain a pointer to the next block; the + rest contains DD_MEM_CHUNK spaces for hash items. Returns a pointer to + a new item if successful; NULL is memory is full.] + + SideEffects [None] + + SeeAlso [cuddAllocNode cuddDynamicAllocNode] + +******************************************************************************/ +DD_INLINE +static DdHashItem * +cuddHashTableAlloc( + DdHashTable * hash) +{ + int i; + unsigned int itemsize = hash->itemsize; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + DdHashItem **mem, *thisOne, *next, *item; + + if (hash->nextFree == NULL) { + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdHashItem **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); + MMoutOfMemory = saveHandler; + if (mem == NULL) { + if (hash->manager->stash != NULL) { + FREE(hash->manager->stash); + hash->manager->stash = NULL; + /* Inhibit resizing of tables. */ + hash->manager->maxCacheHard = hash->manager->cacheSlots - 1; + hash->manager->cacheSlack = - (int) (hash->manager->cacheSlots + 1); + for (i = 0; i < hash->manager->size; i++) { + hash->manager->subtables[i].maxKeys <<= 2; + } + hash->manager->gcFrac = 0.2; + hash->manager->minDead = + (unsigned) (0.2 * (double) hash->manager->slots); + mem = (DdHashItem **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); + } + if (mem == NULL) { + (*MMoutOfMemory)((long)((DD_MEM_CHUNK + 1) * itemsize)); + hash->manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + } + + mem[0] = (DdHashItem *) hash->memoryList; + hash->memoryList = mem; + + thisOne = (DdHashItem *) ((char *) mem + itemsize); + hash->nextFree = thisOne; + for (i = 1; i < DD_MEM_CHUNK; i++) { + next = (DdHashItem *) ((char *) thisOne + itemsize); + thisOne->next = next; + thisOne = next; + } + + thisOne->next = NULL; + + } + item = hash->nextFree; + hash->nextFree = item->next; + return(item); + +} /* end of cuddHashTableAlloc */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLevelQ.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLevelQ.c new file mode 100644 index 000000000..34f32c5b8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLevelQ.c @@ -0,0 +1,583 @@ +/**CFile*********************************************************************** + + FileName [cuddLevelQ.c] + + PackageName [cudd] + + Synopsis [Procedure to manage level queues.] + + Description [The functions in this file allow an application to + easily manipulate a queue where nodes are prioritized by level. The + emphasis is on efficiency. Therefore, the queue items can have + variable size. If the application does not need to attach + information to the nodes, it can declare the queue items to be of + type DdQueueItem. Otherwise, it can declare them to be of a + structure type such that the first three fields are data + pointers. The third pointer points to the node. The first two + pointers are used by the level queue functions. The remaining fields + are initialized to 0 when a new item is created, and are then left + to the exclusive use of the application. On the DEC Alphas the three + pointers must be 32-bit pointers when CUDD is compiled with 32-bit + pointers. The level queue functions make sure that each node + appears at most once in the queue. They do so by keeping a hash + table where the node is used as key. Queue items are recycled via a + free list for efficiency. + + Internal procedures provided by this module: +
                        +
                      • cuddLevelQueueInit() +
                      • cuddLevelQueueQuit() +
                      • cuddLevelQueueEnqueue() +
                      • cuddLevelQueueDequeue() +
                      + Static procedures included in this module: +
                        +
                      • hashLookup() +
                      • hashInsert() +
                      • hashDelete() +
                      • hashResize() +
                      + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.16 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**Macro*********************************************************************** + + Synopsis [Hash function for the table of a level queue.] + + Description [Hash function for the table of a level queue.] + + SideEffects [None] + + SeeAlso [hashInsert hashLookup hashDelete] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define lqHash(key,shift) \ +(((unsigned)(ptruint)(key) * DD_P1) >> (shift)) +#else +#define lqHash(key,shift) \ +(((unsigned)(key) * DD_P1) >> (shift)) +#endif + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdQueueItem * hashLookup(DdLevelQueue *queue, void *key); +static int hashInsert(DdLevelQueue *queue, DdQueueItem *item); +static void hashDelete(DdLevelQueue *queue, DdQueueItem *item); +static int hashResize(DdLevelQueue *queue); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes a level queue.] + + Description [Initializes a level queue. A level queue is a queue + where inserts are based on the levels of the nodes. Within each + level the policy is FIFO. Level queues are useful in traversing a + BDD top-down. Queue items are kept in a free list when dequeued for + efficiency. Returns a pointer to the new queue if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueQuit cuddLevelQueueEnqueue cuddLevelQueueDequeue] + +******************************************************************************/ +DdLevelQueue * +cuddLevelQueueInit( + int levels /* number of levels */, + int itemSize /* size of the item */, + int numBuckets /* initial number of hash buckets */) +{ + DdLevelQueue *queue; + int logSize; + + queue = ALLOC(DdLevelQueue,1); + if (queue == NULL) + return(NULL); + /* Keep pointers to the insertion points for all levels. */ + queue->last = ALLOC(DdQueueItem *, levels); + if (queue->last == NULL) { + FREE(queue); + return(NULL); + } + /* Use a hash table to test for uniqueness. */ + if (numBuckets < 2) numBuckets = 2; + logSize = cuddComputeFloorLog2(numBuckets); + queue->numBuckets = 1 << logSize; + queue->shift = sizeof(int) * 8 - logSize; + queue->buckets = ALLOC(DdQueueItem *, queue->numBuckets); + if (queue->buckets == NULL) { + FREE(queue->last); + FREE(queue); + return(NULL); + } + memset(queue->last, 0, levels * sizeof(DdQueueItem *)); + memset(queue->buckets, 0, queue->numBuckets * sizeof(DdQueueItem *)); + queue->first = NULL; + queue->freelist = NULL; + queue->levels = levels; + queue->itemsize = itemSize; + queue->size = 0; + queue->maxsize = queue->numBuckets * DD_MAX_SUBTABLE_DENSITY; + return(queue); + +} /* end of cuddLevelQueueInit */ + + +/**Function******************************************************************** + + Synopsis [Shuts down a level queue.] + + Description [Shuts down a level queue and releases all the + associated memory.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueInit] + +******************************************************************************/ +void +cuddLevelQueueQuit( + DdLevelQueue * queue) +{ + DdQueueItem *item; + + while (queue->freelist != NULL) { + item = queue->freelist; + queue->freelist = item->next; + FREE(item); + } + while (queue->first != NULL) { + item = (DdQueueItem *) queue->first; + queue->first = item->next; + FREE(item); + } + FREE(queue->buckets); + FREE(queue->last); + FREE(queue); + return; + +} /* end of cuddLevelQueueQuit */ + + +/**Function******************************************************************** + + Synopsis [Inserts a new key in a level queue.] + + Description [Inserts a new key in a level queue. A new entry is + created in the queue only if the node is not already + enqueued. Returns a pointer to the queue item if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueInit cuddLevelQueueDequeue] + +******************************************************************************/ +void * +cuddLevelQueueEnqueue( + DdLevelQueue * queue /* level queue */, + void * key /* key to be enqueued */, + int level /* level at which to insert */) +{ + DdQueueItem *item; + +#ifdef DD_DEBUG + assert(level < queue->levels); +#endif + /* Check whether entry for this node exists. */ + item = hashLookup(queue,key); + if (item != NULL) return(item); + + /* Get a free item from either the free list or the memory manager. */ + if (queue->freelist == NULL) { + item = (DdQueueItem *) ALLOC(char, queue->itemsize); + if (item == NULL) + return(NULL); + } else { + item = queue->freelist; + queue->freelist = item->next; + } + /* Initialize. */ + memset(item, 0, queue->itemsize); + item->key = key; + /* Update stats. */ + queue->size++; + + if (queue->last[level]) { + /* There are already items for this level in the queue. */ + item->next = queue->last[level]->next; + queue->last[level]->next = item; + } else { + /* There are no items at the current level. Look for the first + ** non-empty level preceeding this one. */ + int plevel = level; + while (plevel != 0 && queue->last[plevel] == NULL) + plevel--; + if (queue->last[plevel] == NULL) { + /* No element precedes this one in the queue. */ + item->next = (DdQueueItem *) queue->first; + queue->first = item; + } else { + item->next = queue->last[plevel]->next; + queue->last[plevel]->next = item; + } + } + queue->last[level] = item; + + /* Insert entry for the key in the hash table. */ + if (hashInsert(queue,item) == 0) { + return(NULL); + } + return(item); + +} /* end of cuddLevelQueueEnqueue */ + + +/**Function******************************************************************** + + Synopsis [Inserts the first key in a level queue.] + + Description [Inserts the first key in a level queue. Returns a + pointer to the queue item if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueEnqueue] + +******************************************************************************/ +void * +cuddLevelQueueFirst( + DdLevelQueue * queue /* level queue */, + void * key /* key to be enqueued */, + int level /* level at which to insert */) +{ + DdQueueItem *item; + +#ifdef DD_DEBUG + assert(level < queue->levels); + /* Check whether entry for this node exists. */ + item = hashLookup(queue,key); + assert(item == NULL); +#endif + + /* Get a free item from either the free list or the memory manager. */ + if (queue->freelist == NULL) { + item = (DdQueueItem *) ALLOC(char, queue->itemsize); + if (item == NULL) + return(NULL); + } else { + item = queue->freelist; + queue->freelist = item->next; + } + /* Initialize. */ + memset(item, 0, queue->itemsize); + item->key = key; + /* Update stats. */ + queue->size = 1; + + /* No element precedes this one in the queue. */ + queue->first = item; + queue->last[level] = item; + + /* Insert entry for the key in the hash table. */ + if (hashInsert(queue,item) == 0) { + return(NULL); + } + return(item); + +} /* end of cuddLevelQueueFirst */ + + +/**Function******************************************************************** + + Synopsis [Remove an item from the front of a level queue.] + + Description [Remove an item from the front of a level queue.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueEnqueue] + +******************************************************************************/ +void +cuddLevelQueueDequeue( + DdLevelQueue * queue, + int level) +{ + DdQueueItem *item = (DdQueueItem *) queue->first; + + /* Delete from the hash table. */ + hashDelete(queue,item); + + /* Since we delete from the front, if this is the last item for + ** its level, there are no other items for the same level. */ + if (queue->last[level] == item) { + queue->last[level] = NULL; + } + + queue->first = item->next; + /* Put item on the free list. */ + item->next = queue->freelist; + queue->freelist = item; + /* Update stats. */ + queue->size--; + return; + +} /* end of cuddLevelQueueDequeue */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Looks up a key in the hash table of a level queue.] + + Description [Looks up a key in the hash table of a level queue. Returns + a pointer to the item with the given key if the key is found; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueEnqueue hashInsert] + +******************************************************************************/ +static DdQueueItem * +hashLookup( + DdLevelQueue * queue, + void * key) +{ + int posn; + DdQueueItem *item; + + posn = lqHash(key,queue->shift); + item = queue->buckets[posn]; + + while (item != NULL) { + if (item->key == key) { + return(item); + } + item = item->cnext; + } + return(NULL); + +} /* end of hashLookup */ + + +/**Function******************************************************************** + + Synopsis [Inserts an item in the hash table of a level queue.] + + Description [Inserts an item in the hash table of a level queue. Returns + 1 if successful; 0 otherwise. No check is performed to see if an item with + the same key is already in the hash table.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueEnqueue] + +******************************************************************************/ +static int +hashInsert( + DdLevelQueue * queue, + DdQueueItem * item) +{ + int result; + int posn; + + if (queue->size > queue->maxsize) { + result = hashResize(queue); + if (result == 0) return(0); + } + + posn = lqHash(item->key,queue->shift); + item->cnext = queue->buckets[posn]; + queue->buckets[posn] = item; + + return(1); + +} /* end of hashInsert */ + + +/**Function******************************************************************** + + Synopsis [Removes an item from the hash table of a level queue.] + + Description [Removes an item from the hash table of a level queue. + Nothing is done if the item is not in the table.] + + SideEffects [None] + + SeeAlso [cuddLevelQueueDequeue hashInsert] + +******************************************************************************/ +static void +hashDelete( + DdLevelQueue * queue, + DdQueueItem * item) +{ + int posn; + DdQueueItem *prevItem; + + posn = lqHash(item->key,queue->shift); + prevItem = queue->buckets[posn]; + + if (prevItem == NULL) return; + if (prevItem == item) { + queue->buckets[posn] = prevItem->cnext; + return; + } + + while (prevItem->cnext != NULL) { + if (prevItem->cnext == item) { + prevItem->cnext = item->cnext; + return; + } + prevItem = prevItem->cnext; + } + return; + +} /* end of hashDelete */ + + +/**Function******************************************************************** + + Synopsis [Resizes the hash table of a level queue.] + + Description [Resizes the hash table of a level queue. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [hashInsert] + +******************************************************************************/ +static int +hashResize( + DdLevelQueue * queue) +{ + int j; + int posn; + DdQueueItem *item; + DdQueueItem *next; + int numBuckets; + DdQueueItem **buckets; + DdQueueItem **oldBuckets = queue->buckets; + int shift; + int oldNumBuckets = queue->numBuckets; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + /* Compute the new size of the subtable. */ + numBuckets = oldNumBuckets << 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + buckets = queue->buckets = ALLOC(DdQueueItem *, numBuckets); + MMoutOfMemory = saveHandler; + if (buckets == NULL) { + queue->maxsize <<= 1; + return(1); + } + + queue->numBuckets = numBuckets; + shift = --(queue->shift); + queue->maxsize <<= 1; + memset(buckets, 0, numBuckets * sizeof(DdQueueItem *)); + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->cnext; + posn = lqHash(item->key, shift); + item->cnext = buckets[posn]; + buckets[posn] = item; + item = next; + } + } + FREE(oldBuckets); + return(1); + +} /* end of hashResize */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLinear.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLinear.c new file mode 100644 index 000000000..387989004 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLinear.c @@ -0,0 +1,1365 @@ +/**CFile*********************************************************************** + + FileName [cuddLinear.c] + + PackageName [cudd] + + Synopsis [Functions for DD reduction by linear transformations.] + + Description [ Internal procedures included in this module: +
                        +
                      • cuddLinearAndSifting() +
                      • cuddLinearInPlace() +
                      • cuddUpdateInteractionMatrix() +
                      • cuddInitLinear() +
                      • cuddResizeLinear() +
                      + Static procedures included in this module: +
                        +
                      • ddLinearUniqueCompare() +
                      • ddLinearAndSiftingAux() +
                      • ddLinearAndSiftingUp() +
                      • ddLinearAndSiftingDown() +
                      • ddLinearAndSiftingBackward() +
                      • ddUndoMoves() +
                      • cuddXorLinear() +
                      ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define CUDD_SWAP_MOVE 0 +#define CUDD_LINEAR_TRANSFORM_MOVE 1 +#define CUDD_INVERSE_TRANSFORM_MOVE 2 +#if SIZEOF_LONG == 8 +#define BPL 64 +#define LOGBPL 6 +#else +#define BPL 32 +#define LOGBPL 5 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddLinear.c,v 1.29 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int *entry; + +#ifdef DD_STATS +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +static int ddTotalNumberLinearTr; +#endif + +#ifdef DD_DEBUG +static int zero = 0; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddLinearUniqueCompare (int *ptrX, int *ptrY); +static int ddLinearAndSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddLinearAndSiftingUp (DdManager *table, int y, int xLow, Move *prevMoves); +static Move * ddLinearAndSiftingDown (DdManager *table, int x, int xHigh, Move *prevMoves); +static int ddLinearAndSiftingBackward (DdManager *table, int size, Move *moves); +static Move* ddUndoMoves (DdManager *table, Move *moves); +static void cuddXorLinear (DdManager *table, int x, int y); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints the linear transform matrix.] + + Description [Prints the linear transform matrix. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_PrintLinear( + DdManager * table) +{ + int i,j,k; + int retval; + int nvars = table->linearSize; + int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + long word; + + for (i = 0; i < nvars; i++) { + for (j = 0; j < wordsPerRow; j++) { + word = table->linear[i*wordsPerRow + j]; + for (k = 0; k < BPL; k++) { + retval = fprintf(table->out,"%ld",word & 1); + if (retval == 0) return(0); + word >>= 1; + } + } + retval = fprintf(table->out,"\n"); + if (retval == 0) return(0); + } + return(1); + +} /* end of Cudd_PrintLinear */ + + +/**Function******************************************************************** + + Synopsis [Reads an entry of the linear transform matrix.] + + Description [Reads an entry of the linear transform matrix.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ReadLinear( + DdManager * table /* CUDD manager */, + int x /* row index */, + int y /* column index */) +{ + int nvars = table->size; + int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + long word; + int bit; + int result; + + assert(table->size == table->linearSize); + + word = wordsPerRow * x + (y >> LOGBPL); + bit = y & (BPL-1); + result = (int) ((table->linear[word] >> bit) & 1); + return(result); + +} /* end of Cudd_ReadLinear */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [BDD reduction based on combination of sifting and linear + transformations.] + + Description [BDD reduction based on combination of sifting and linear + transformations. Assumes that no dead nodes are present. +
                        +
                      1. Order all the variables according to the number of entries + in each unique table. +
                      2. Sift the variable up and down, remembering each time the + total size of the DD heap. At each position, linear transformation + of the two adjacent variables is tried and is accepted if it reduces + the size of the DD. +
                      3. Select the best permutation. +
                      4. Repeat 3 and 4 for all variables. +
                      + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddLinearAndSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; +#ifdef DD_STATS + int previousSize; +#endif + +#ifdef DD_STATS + ddTotalNumberLinearTr = 0; +#endif + + size = table->size; + + var = NULL; + entry = NULL; + if (table->linear == NULL) { + result = cuddInitLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; +#if 0 + (void) fprintf(table->out,"\n"); + result = Cudd_PrintLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; +#endif + } else if (table->size != table->linearSize) { + result = cuddResizeLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; +#if 0 + (void) fprintf(table->out,"\n"); + result = Cudd_PrintLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; +#endif + } + + /* Find order in which to sift variables. */ + entry = ALLOC(int,size); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddLinearAndSiftingOutOfMem; + } + var = ALLOC(int,size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddLinearAndSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; + } + + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddLinearUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { + x = table->perm[var[i]]; + if (x < lower || x > upper) continue; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddLinearAndSiftingAux(table,x,lower,upper); + if (!result) goto cuddLinearAndSiftingOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif +#ifdef DD_DEBUG + (void) Cudd_DebugCheck(table); +#endif + } + + FREE(var); + FREE(entry); + +#ifdef DD_STATS + (void) fprintf(table->out,"\n#:L_LINSIFT %8d: linear trans.", + ddTotalNumberLinearTr); +#endif + + return(1); + +cuddLinearAndSiftingOutOfMem: + + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddLinearAndSifting */ + + +/**Function******************************************************************** + + Synopsis [Linearly combines two adjacent variables.] + + Description [Linearly combines two adjacent variables. Specifically, + replaces the top variable with the exclusive nor of the two variables. + It assumes that no dead nodes are present on entry to this + procedure. The procedure then guarantees that no dead nodes will be + present when it terminates. cuddLinearInPlace assumes that x < + y. Returns the number of keys in the table if successful; 0 + otherwise.] + + SideEffects [The two subtables corrresponding to variables x and y are + modified. The global counters of the unique table are also affected.] + + SeeAlso [cuddSwapInPlace] + +******************************************************************************/ +int +cuddLinearInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int comple, newcomplement; + int i; + int posn; + int isolated; + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0; + DdNode *g,*next,*last; + DdNodePtr *previousP; + DdNode *tmp; + DdNode *sentinel = &(table->sentinel); +#ifdef DD_DEBUG + int count, idcheck; +#endif + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddNextHigh(table,x) == y); + assert(table->subtables[x].keys != 0); + assert(table->subtables[y].keys != 0); + assert(table->subtables[x].dead == 0); + assert(table->subtables[y].dead == 0); +#endif + + xindex = table->invperm[x]; + yindex = table->invperm[y]; + + if (cuddTestInteract(table,xindex,yindex)) { +#ifdef DD_STATS + ddTotalNumberLinearTr++; +#endif + /* Get parameters of x subtable. */ + xlist = table->subtables[x].nodelist; + oldxkeys = table->subtables[x].keys; + xslots = table->subtables[x].slots; + xshift = table->subtables[x].shift; + + /* Get parameters of y subtable. */ + ylist = table->subtables[y].nodelist; + oldykeys = table->subtables[y].keys; + yslots = table->subtables[y].slots; + yshift = table->subtables[y].shift; + + newxkeys = 0; + newykeys = oldykeys; + + /* Check whether the two projection functions involved in this + ** swap are isolated. At the end, we'll be able to tell how many + ** isolated projection functions are there by checking only these + ** two functions again. This is done to eliminate the isolated + ** projection functions from the node count. + */ + isolated = - ((table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1)); + + /* The nodes in the x layer are put in a chain. + ** The chain is handled as a FIFO; g points to the beginning and + ** last points to the end. + */ + g = NULL; +#ifdef DD_DEBUG + last = NULL; +#endif + for (i = 0; i < xslots; i++) { + f = xlist[i]; + if (f == sentinel) continue; + xlist[i] = sentinel; + if (g == NULL) { + g = f; + } else { + last->next = f; + } + while ((next = f->next) != sentinel) { + f = next; + } /* while there are elements in the collision chain */ + last = f; + } /* for each slot of the x subtable */ +#ifdef DD_DEBUG + /* last is always assigned in the for loop because there is at + ** least one key */ + assert(last != NULL); +#endif + last->next = NULL; + +#ifdef DD_COUNT + table->swapSteps += oldxkeys; +#endif + /* Take care of the x nodes that must be re-expressed. + ** They form a linked list pointed by g. + */ + f = g; + while (f != NULL) { + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f1))); +#endif + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = f10 = f1; + } +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f11))); +#endif + f0 = cuddE(f); + comple = Cudd_IsComplement(f0); + f0 = Cudd_Regular(f0); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == f00) { + newf1 = f11; + cuddSatInc(newf1->ref); + } else { + /* Check ylist for triple (yindex,f11,f00). */ + posn = ddHash(f11, f00, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + previousP = &(ylist[posn]); + newf1 = *previousP; + while (f11 < cuddT(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + while (f11 == cuddT(newf1) && f00 < cuddE(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + if (cuddT(newf1) == f11 && cuddE(newf1) == f00) { + cuddSatInc(newf1->ref); + } else { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto cuddLinearOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f00; + /* Insert newf1 in the collision list ylist[posn]; + ** increase the ref counts of f11 and f00. + */ + newykeys++; + newf1->next = *previousP; + *previousP = newf1; + cuddSatInc(f11->ref); + tmp = Cudd_Regular(f00); + cuddSatInc(tmp->ref); + } + } + cuddT(f) = newf1; +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(newf1))); +#endif + + /* Do the same for f0, keeping complement dots into account. */ + /* decrease ref count of f0 */ + tmp = Cudd_Regular(f0); + cuddSatDec(tmp->ref); + /* create the new E child */ + if (f01 == f10) { + newf0 = f01; + tmp = Cudd_Regular(newf0); + cuddSatInc(tmp->ref); + } else { + /* make sure f01 is regular */ + newcomplement = Cudd_IsComplement(f01); + if (newcomplement) { + f01 = Cudd_Not(f01); + f10 = Cudd_Not(f10); + } + /* Check ylist for triple (yindex,f01,f10). */ + posn = ddHash(f01, f10, yshift); + /* For each element newf0 in collision list ylist[posn]. */ + previousP = &(ylist[posn]); + newf0 = *previousP; + while (f01 < cuddT(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + while (f01 == cuddT(newf0) && f10 < cuddE(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + if (cuddT(newf0) == f01 && cuddE(newf0) == f10) { + cuddSatInc(newf0->ref); + } else { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto cuddLinearOutOfMem; + newf0->index = yindex; newf0->ref = 1; + cuddT(newf0) = f01; + cuddE(newf0) = f10; + /* Insert newf0 in the collision list ylist[posn]; + ** increase the ref counts of f01 and f10. + */ + newykeys++; + newf0->next = *previousP; + *previousP = newf0; + cuddSatInc(f01->ref); + tmp = Cudd_Regular(f10); + cuddSatInc(tmp->ref); + } + if (newcomplement) { + newf0 = Cudd_Not(newf0); + } + } + cuddE(f) = newf0; + + /* Re-insert the modified f in xlist. + ** The modified f does not already exists in xlist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, xshift); + newxkeys++; + previousP = &(xlist[posn]); + tmp = *previousP; + while (newf1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; + *previousP = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previousP = &(ylist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + if (f->ref == 0) { + tmp = cuddT(f); + cuddSatDec(tmp->ref); + tmp = Cudd_Regular(cuddE(f)); + cuddSatDec(tmp->ref); + cuddDeallocNode(table,f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = sentinel; + } /* for every collision list */ + +#ifdef DD_DEBUG +#if 0 + (void) fprintf(table->out,"Linearly combining %d and %d\n",x,y); +#endif + count = 0; + idcheck = 0; + for (i = 0; i < yslots; i++) { + f = ylist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) yindex) + idcheck++; + f = f->next; + } + } + if (count != newykeys) { + fprintf(table->err,"Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",oldykeys,newykeys,count); + } + if (idcheck != 0) + fprintf(table->err,"Error in id's of ylist\twrong id's = %d\n",idcheck); + count = 0; + idcheck = 0; + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) xindex) + idcheck++; + f = f->next; + } + } + if (count != newxkeys || newxkeys != oldxkeys) { + fprintf(table->err,"Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",oldxkeys,newxkeys,count); + } + if (idcheck != 0) + fprintf(table->err,"Error in id's of xlist\twrong id's = %d\n",idcheck); +#endif + + isolated += (table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1); + table->isolated += isolated; + + /* Set the appropriate fields in table. */ + table->subtables[y].keys = newykeys; + + /* Here we should update the linear combination table + ** to record that x <- x EXNOR y. This is done by complementing + ** the (x,y) entry of the table. + */ + + table->keys += newykeys - oldykeys; + + cuddXorLinear(table,xindex,yindex); + } + +#ifdef DD_DEBUG + if (zero) { + (void) Cudd_DebugCheck(table); + } +#endif + + return(table->keys - table->isolated); + +cuddLinearOutOfMem: + (void) fprintf(table->err,"Error: cuddLinearInPlace out of memory\n"); + + return (0); + +} /* end of cuddLinearInPlace */ + + +/**Function******************************************************************** + + Synopsis [Updates the interaction matrix.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +void +cuddUpdateInteractionMatrix( + DdManager * table, + int xindex, + int yindex) +{ + int i; + for (i = 0; i < yindex; i++) { + if (i != xindex && cuddTestInteract(table,i,yindex)) { + if (i < xindex) { + cuddSetInteract(table,i,xindex); + } else { + cuddSetInteract(table,xindex,i); + } + } + } + for (i = yindex+1; i < table->size; i++) { + if (i != xindex && cuddTestInteract(table,yindex,i)) { + if (i < xindex) { + cuddSetInteract(table,i,xindex); + } else { + cuddSetInteract(table,xindex,i); + } + } + } + +} /* end of cuddUpdateInteractionMatrix */ + + +/**Function******************************************************************** + + Synopsis [Initializes the linear transform matrix.] + + Description [Initializes the linear transform matrix. Returns 1 if + successful; 0 otherwise.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +cuddInitLinear( + DdManager * table) +{ + int words; + int wordsPerRow; + int nvars; + int word; + int bit; + int i; + long *linear; + + nvars = table->size; + wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + words = wordsPerRow * nvars; + table->linear = linear = ALLOC(long,words); + if (linear == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + table->memused += words * sizeof(long); + table->linearSize = nvars; + for (i = 0; i < words; i++) linear[i] = 0; + for (i = 0; i < nvars; i++) { + word = wordsPerRow * i + (i >> LOGBPL); + bit = i & (BPL-1); + linear[word] = 1 << bit; + } + return(1); + +} /* end of cuddInitLinear */ + + +/**Function******************************************************************** + + Synopsis [Resizes the linear transform matrix.] + + Description [Resizes the linear transform matrix. Returns 1 if + successful; 0 otherwise.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +cuddResizeLinear( + DdManager * table) +{ + int words,oldWords; + int wordsPerRow,oldWordsPerRow; + int nvars,oldNvars; + int word,oldWord; + int bit; + int i,j; + long *linear,*oldLinear; + + oldNvars = table->linearSize; + oldWordsPerRow = ((oldNvars - 1) >> LOGBPL) + 1; + oldWords = oldWordsPerRow * oldNvars; + oldLinear = table->linear; + + nvars = table->size; + wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + words = wordsPerRow * nvars; + table->linear = linear = ALLOC(long,words); + if (linear == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + table->memused += (words - oldWords) * sizeof(long); + for (i = 0; i < words; i++) linear[i] = 0; + + /* Copy old matrix. */ + for (i = 0; i < oldNvars; i++) { + for (j = 0; j < oldWordsPerRow; j++) { + oldWord = oldWordsPerRow * i + j; + word = wordsPerRow * i + j; + linear[word] = oldLinear[oldWord]; + } + } + FREE(oldLinear); + + /* Add elements to the diagonal. */ + for (i = oldNvars; i < nvars; i++) { + word = wordsPerRow * i + (i >> LOGBPL); + bit = i & (BPL-1); + linear[word] = 1 << bit; + } + table->linearSize = nvars; + + return(1); + +} /* end of cuddResizeLinear */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + +******************************************************************************/ +static int +ddLinearUniqueCompare( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of ddLinearUniqueCompare */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. At each step a linear transformation is tried, and, if it + decreases the size of the DD, it is accepted. Finds the best position + and does the required changes. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddLinearAndSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; + + initialSize = table->keys - table->isolated; + + moveDown = NULL; + moveUp = NULL; + + if (x == xLow) { + moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; + + } else if (x == xHigh) { + moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + moveUp = ddUndoMoves(table,moveDown); +#ifdef DD_DEBUG + assert(moveUp == NULL || moveUp->x == x); +#endif + moveUp = ddLinearAndSiftingUp(table,x,xLow,moveUp); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; + + } else { /* must go up first: shorter */ + moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + moveDown = ddUndoMoves(table,moveUp); +#ifdef DD_DEBUG + assert(moveDown == NULL || moveDown->y == x); +#endif + moveDown = ddLinearAndSiftingDown(table,x,xHigh,moveDown); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +ddLinearAndSiftingAuxOutOfMem: + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(0); + +} /* end of ddLinearAndSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable up and applies linear transformations.] + + Description [Sifts a variable up and applies linear transformations. + Moves y up until either it reaches the bound (xLow) or the size of + the DD heap increases too much. Returns the set of moves in case of + success; NULL if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddLinearAndSiftingUp( + DdManager * table, + int y, + int xLow, + Move * prevMoves) +{ + Move *moves; + Move *move; + int x; + int size, newsize; + int limitSize; + int xindex, yindex; + int isolated; + int L; /* lower bound on DD size */ +#ifdef DD_DEBUG + int checkL; + int z; + int zindex; +#endif + + moves = prevMoves; + yindex = table->invperm[y]; + + /* Initialize the lower bound. + ** The part of the DD below y will not change. + ** The part of the DD above y that does not interact with y will not + ** change. The rest may vanish in the best case, except for + ** the nodes at level xLow, which will not vanish, regardless. + */ + limitSize = L = table->keys - table->isolated; + for (x = xLow + 1; x < y; x++) { + xindex = table->invperm[x]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L -= table->subtables[x].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + L -= table->subtables[y].keys - isolated; + + x = cuddNextLow(table,y); + while (x >= xLow && L <= limitSize) { + xindex = table->invperm[x]; +#ifdef DD_DEBUG + checkL = table->keys - table->isolated; + for (z = xLow + 1; z < y; z++) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + checkL -= table->subtables[y].keys - isolated; + if (L != checkL) { + (void) fprintf(table->out, "checkL(%d) != L(%d)\n",checkL,L); + } +#endif + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddLinearAndSiftingUpOutOfMem; + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddLinearAndSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize >= size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem; +#ifdef DD_DEBUG + if (newsize != size) { + (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } +#endif + } else if (cuddTestInteract(table,xindex,yindex)) { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + cuddUpdateInteractionMatrix(table,xindex,yindex); + } + move->size = size; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + y = x; + x = cuddNextLow(table,y); + } + return(moves); + +ddLinearAndSiftingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddLinearAndSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable down and applies linear transformations.] + + Description [Sifts a variable down and applies linear + transformations. Moves x down until either it reaches the bound + (xHigh) or the size of the DD heap increases too much. Returns the + set of moves in case of success; NULL if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddLinearAndSiftingDown( + DdManager * table, + int x, + int xHigh, + Move * prevMoves) +{ + Move *moves; + Move *move; + int y; + int size, newsize; + int R; /* upper bound on node decrease */ + int limitSize; + int xindex, yindex; + int isolated; +#ifdef DD_DEBUG + int checkR; + int z; + int zindex; +#endif + + moves = prevMoves; + /* Initialize R */ + xindex = table->invperm[x]; + limitSize = size = table->keys - table->isolated; + R = 0; + for (y = xHigh; y > x; y--) { + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R += table->subtables[y].keys - isolated; + } + } + + y = cuddNextHigh(table,x); + while (y <= xHigh && size - R < limitSize) { +#ifdef DD_DEBUG + checkR = 0; + for (z = xHigh; z > x; z--) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + if (R != checkR) { + (void) fprintf(table->out, "checkR(%d) != R(%d)\n",checkR,R); + } +#endif + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddLinearAndSiftingDownOutOfMem; + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddLinearAndSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize >= size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem; + if (newsize != size) { + (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } + } else if (cuddTestInteract(table,xindex,yindex)) { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + cuddUpdateInteractionMatrix(table,xindex,yindex); + } + move->size = size; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + x = y; + y = cuddNextHigh(table,x); + } + return(moves); + +ddLinearAndSiftingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddLinearAndSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the DD heap to the order + giving the minimum size.] + + Description [Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddLinearAndSiftingBackward( + DdManager * table, + int size, + Move * moves) +{ + Move *move; + int res; + + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + res = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { + res = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + } + + return(1); + +} /* end of ddLinearAndSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the DD heap to the order + in effect before the moves.] + + Description [Given a set of moves, returns the DD heap to the + order in effect before the moves. Returns 1 in case of success; + 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static Move* +ddUndoMoves( + DdManager * table, + Move * moves) +{ + Move *invmoves = NULL; + Move *move; + Move *invmove; + int size; + + for (move = moves; move != NULL; move = move->next) { + invmove = (Move *) cuddDynamicAllocNode(table); + if (invmove == NULL) goto ddUndoMovesOutOfMem; + invmove->x = move->x; + invmove->y = move->y; + invmove->next = invmoves; + invmoves = invmove; + if (move->flags == CUDD_SWAP_MOVE) { + invmove->flags = CUDD_SWAP_MOVE; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; + size = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ +#ifdef DD_DEBUG + (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); +#endif + invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + size = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } + invmove->size = size; + } + + return(invmoves); + +ddUndoMovesOutOfMem: + while (invmoves != NULL) { + move = invmoves->next; + cuddDeallocMove(table, invmoves); + invmoves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddUndoMoves */ + + +/**Function******************************************************************** + + Synopsis [XORs two rows of the linear transform matrix.] + + Description [XORs two rows of the linear transform matrix and replaces + the first row with the result.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static void +cuddXorLinear( + DdManager * table, + int x, + int y) +{ + int i; + int nvars = table->size; + int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + int xstart = wordsPerRow * x; + int ystart = wordsPerRow * y; + long *linear = table->linear; + + for (i = 0; i < wordsPerRow; i++) { + linear[xstart+i] ^= linear[ystart+i]; + } + +} /* end of cuddXorLinear */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLiteral.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLiteral.c new file mode 100644 index 000000000..b81697028 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddLiteral.c @@ -0,0 +1,264 @@ +/**CFile*********************************************************************** + + FileName [cuddLiteral.c] + + PackageName [cudd] + + Synopsis [Functions for manipulation of literal sets represented by + BDDs.] + + Description [External procedures included in this file: +
                        +
                      • Cudd_bddLiteralSetIntersection() +
                      + Internal procedures included in this file: +
                        +
                      • cuddBddLiteralSetIntersectionRecur() +
                      ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddLiteral.c,v 1.9 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the intesection of two sets of literals + represented as BDDs.] + + Description [Computes the intesection of two sets of literals + represented as BDDs. Each set is represented as a cube of the + literals in the set. The empty set is represented by the constant 1. + No variable can be simultaneously present in both phases in a set. + Returns a pointer to the BDD representing the intersected sets, if + successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_bddLiteralSetIntersection( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddLiteralSetIntersectionRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddLiteralSetIntersection */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of + Cudd_bddLiteralSetIntersection.] + + Description [Performs the recursive step of + Cudd_bddLiteralSetIntersection. Scans the cubes for common variables, + and checks whether they agree in phase. Returns a pointer to the + resulting cube if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddBddLiteralSetIntersectionRecur( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res, *tmp; + DdNode *F, *G; + DdNode *fc, *gc; + DdNode *one; + DdNode *zero; + unsigned int topf, topg, comple; + int phasef, phaseg; + + statLine(dd); + if (f == g) return(f); + + F = Cudd_Regular(f); + G = Cudd_Regular(g); + one = DD_ONE(dd); + + /* Here f != g. If F == G, then f and g are complementary. + ** Since they are two cubes, this case only occurs when f == v, + ** g == v', and v is a variable or its complement. + */ + if (F == G) return(one); + + zero = Cudd_Not(one); + topf = cuddI(dd,F->index); + topg = cuddI(dd,G->index); + /* Look for a variable common to both cubes. If there are none, this + ** loop will stop when the constant node is reached in both cubes. + */ + while (topf != topg) { + if (topf < topg) { /* move down on f */ + comple = f != F; + f = cuddT(F); + if (comple) f = Cudd_Not(f); + if (f == zero) { + f = cuddE(F); + if (comple) f = Cudd_Not(f); + } + F = Cudd_Regular(f); + topf = cuddI(dd,F->index); + } else if (topg < topf) { + comple = g != G; + g = cuddT(G); + if (comple) g = Cudd_Not(g); + if (g == zero) { + g = cuddE(G); + if (comple) g = Cudd_Not(g); + } + G = Cudd_Regular(g); + topg = cuddI(dd,G->index); + } + } + + /* At this point, f == one <=> g == 1. It suffices to test one of them. */ + if (f == one) return(one); + + res = cuddCacheLookup2(dd,Cudd_bddLiteralSetIntersection,f,g); + if (res != NULL) { + return(res); + } + + /* Here f and g are both non constant and have the same top variable. */ + comple = f != F; + fc = cuddT(F); + phasef = 1; + if (comple) fc = Cudd_Not(fc); + if (fc == zero) { + fc = cuddE(F); + phasef = 0; + if (comple) fc = Cudd_Not(fc); + } + comple = g != G; + gc = cuddT(G); + phaseg = 1; + if (comple) gc = Cudd_Not(gc); + if (gc == zero) { + gc = cuddE(G); + phaseg = 0; + if (comple) gc = Cudd_Not(gc); + } + + tmp = cuddBddLiteralSetIntersectionRecur(dd,fc,gc); + if (tmp == NULL) { + return(NULL); + } + + if (phasef != phaseg) { + res = tmp; + } else { + cuddRef(tmp); + if (phasef == 0) { + res = cuddBddAndRecur(dd,Cudd_Not(dd->vars[F->index]),tmp); + } else { + res = cuddBddAndRecur(dd,dd->vars[F->index],tmp); + } + if (res == NULL) { + Cudd_RecursiveDeref(dd,tmp); + return(NULL); + } + cuddDeref(tmp); /* Just cuddDeref, because it is included in result */ + } + + cuddCacheInsert2(dd,Cudd_bddLiteralSetIntersection,f,g,res); + + return(res); + +} /* end of cuddBddLiteralSetIntersectionRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddMatMult.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddMatMult.c new file mode 100644 index 000000000..adcbdc79f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddMatMult.c @@ -0,0 +1,707 @@ +/**CFile*********************************************************************** + + FileName [cuddMatMult.c] + + PackageName [cudd] + + Synopsis [Matrix multiplication functions.] + + Description [External procedures included in this module: +
                        +
                      • Cudd_addMatrixMultiply() +
                      • Cudd_addTimesPlus() +
                      • Cudd_addTriangle() +
                      • Cudd_addOuterSum() +
                      + Static procedures included in this module: +
                        +
                      • addMMRecur() +
                      • addTriangleRecur() +
                      • cuddAddOuterSumRecur() +
                      ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.18 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addMMRecur (DdManager *dd, DdNode *A, DdNode *B, int topP, int *vars); +static DdNode * addTriangleRecur (DdManager *dd, DdNode *f, DdNode *g, int *vars, DdNode *cube); +static DdNode * cuddAddOuterSumRecur (DdManager *dd, DdNode *M, DdNode *r, DdNode *c); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Calculates the product of two matrices represented as + ADDs.] + + Description [Calculates the product of two matrices, A and B, + represented as ADDs. This procedure implements the quasiring multiplication + algorithm. A is assumed to depend on variables x (rows) and z + (columns). B is assumed to depend on variables z (rows) and y + (columns). The product of A and B then depends on x (rows) and y + (columns). Only the z variables have to be explicitly identified; + they are the "summation" variables. Returns a pointer to the + result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addTimesPlus Cudd_addTriangle Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_addMatrixMultiply( + DdManager * dd, + DdNode * A, + DdNode * B, + DdNode ** z, + int nz) +{ + int i, nvars, *vars; + DdNode *res; + + /* Array vars says what variables are "summation" variables. */ + nvars = dd->size; + vars = ALLOC(int,nvars); + if (vars == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < nvars; i++) { + vars[i] = 0; + } + for (i = 0; i < nz; i++) { + vars[z[i]->index] = 1; + } + + do { + dd->reordered = 0; + res = addMMRecur(dd,A,B,-1,vars); + } while (dd->reordered == 1); + FREE(vars); + return(res); + +} /* end of Cudd_addMatrixMultiply */ + + +/**Function******************************************************************** + + Synopsis [Calculates the product of two matrices represented as + ADDs.] + + Description [Calculates the product of two matrices, A and B, + represented as ADDs, using the CMU matrix by matrix multiplication + procedure by Clarke et al.. Matrix A has x's as row variables and z's + as column variables, while matrix B has z's as row variables and y's + as column variables. Returns the pointer to the result if successful; + NULL otherwise. The resulting matrix has x's as row variables and y's + as column variables.] + + SideEffects [None] + + SeeAlso [Cudd_addMatrixMultiply] + +******************************************************************************/ +DdNode * +Cudd_addTimesPlus( + DdManager * dd, + DdNode * A, + DdNode * B, + DdNode ** z, + int nz) +{ + DdNode *w, *cube, *tmp, *res; + int i; + tmp = Cudd_addApply(dd,Cudd_addTimes,A,B); + if (tmp == NULL) return(NULL); + Cudd_Ref(tmp); + Cudd_Ref(cube = DD_ONE(dd)); + for (i = nz-1; i >= 0; i--) { + w = Cudd_addIte(dd,z[i],cube,DD_ZERO(dd)); + if (w == NULL) { + Cudd_RecursiveDeref(dd,tmp); + return(NULL); + } + Cudd_Ref(w); + Cudd_RecursiveDeref(dd,cube); + cube = w; + } + res = Cudd_addExistAbstract(dd,tmp,cube); + if (res == NULL) { + Cudd_RecursiveDeref(dd,tmp); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + Cudd_Ref(res); + Cudd_RecursiveDeref(dd,cube); + Cudd_RecursiveDeref(dd,tmp); + Cudd_Deref(res); + return(res); + +} /* end of Cudd_addTimesPlus */ + + +/**Function******************************************************************** + + Synopsis [Performs the triangulation step for the shortest path + computation.] + + Description [Implements the semiring multiplication algorithm used in + the triangulation step for the shortest path computation. f + is assumed to depend on variables x (rows) and z (columns). g is + assumed to depend on variables z (rows) and y (columns). The product + of f and g then depends on x (rows) and y (columns). Only the z + variables have to be explicitly identified; they are the + "abstraction" variables. Returns a pointer to the result if + successful; NULL otherwise. ] + + SideEffects [None] + + SeeAlso [Cudd_addMatrixMultiply Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_addTriangle( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode ** z, + int nz) +{ + int i, nvars, *vars; + DdNode *res, *cube; + + nvars = dd->size; + vars = ALLOC(int, nvars); + if (vars == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < nvars; i++) vars[i] = -1; + for (i = 0; i < nz; i++) vars[z[i]->index] = i; + cube = Cudd_addComputeCube(dd, z, NULL, nz); + if (cube == NULL) { + FREE(vars); + return(NULL); + } + cuddRef(cube); + + do { + dd->reordered = 0; + res = addTriangleRecur(dd, f, g, vars, cube); + } while (dd->reordered == 1); + if (res != NULL) cuddRef(res); + Cudd_RecursiveDeref(dd,cube); + if (res != NULL) cuddDeref(res); + FREE(vars); + return(res); + +} /* end of Cudd_addTriangle */ + + +/**Function******************************************************************** + + Synopsis [Takes the minimum of a matrix and the outer sum of two vectors.] + + Description [Takes the pointwise minimum of a matrix and the outer + sum of two vectors. This procedure is used in the Floyd-Warshall + all-pair shortest path algorithm. Returns a pointer to the result if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addOuterSum( + DdManager *dd, + DdNode *M, + DdNode *r, + DdNode *c) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddOuterSumRecur(dd, M, r, c); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addOuterSum */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addMatrixMultiply.] + + Description [Performs the recursive step of Cudd_addMatrixMultiply. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +addMMRecur( + DdManager * dd, + DdNode * A, + DdNode * B, + int topP, + int * vars) +{ + DdNode *zero, + *At, /* positive cofactor of first operand */ + *Ae, /* negative cofactor of first operand */ + *Bt, /* positive cofactor of second operand */ + *Be, /* negative cofactor of second operand */ + *t, /* positive cofactor of result */ + *e, /* negative cofactor of result */ + *scaled, /* scaled result */ + *add_scale, /* ADD representing the scaling factor */ + *res; + int i; /* loop index */ + double scale; /* scaling factor */ + int index; /* index of the top variable */ + CUDD_VALUE_TYPE value; + unsigned int topA, topB, topV; + DD_CTFP cacheOp; + + statLine(dd); + zero = DD_ZERO(dd); + + if (A == zero || B == zero) { + return(zero); + } + + if (cuddIsConstant(A) && cuddIsConstant(B)) { + /* Compute the scaling factor. It is 2^k, where k is the + ** number of summation variables below the current variable. + ** Indeed, these constants represent blocks of 2^k identical + ** constant values in both A and B. + */ + value = cuddV(A) * cuddV(B); + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP) { + value *= (CUDD_VALUE_TYPE) 2; + } + } + } + res = cuddUniqueConst(dd, value); + return(res); + } + + /* Standardize to increase cache efficiency. Clearly, A*B != B*A + ** in matrix multiplication. However, which matrix is which is + ** determined by the variables appearing in the ADDs and not by + ** which one is passed as first argument. + */ + if (A > B) { + DdNode *tmp = A; + A = B; + B = tmp; + } + + topA = cuddI(dd,A->index); topB = cuddI(dd,B->index); + topV = ddMin(topA,topB); + + cacheOp = (DD_CTFP) addMMRecur; + res = cuddCacheLookup2(dd,cacheOp,A,B); + if (res != NULL) { + /* If the result is 0, there is no need to normalize. + ** Otherwise we count the number of z variables between + ** the current depth and the top of the ADDs. These are + ** the missing variables that determine the size of the + ** constant blocks. + */ + if (res == zero) return(res); + scale = 1.0; + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { + scale *= 2; + } + } + } + if (scale > 1.0) { + cuddRef(res); + add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); + if (add_scale == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(add_scale); + scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); + if (scaled == NULL) { + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(scaled); + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + res = scaled; + cuddDeref(res); + } + return(res); + } + + /* compute the cofactors */ + if (topV == topA) { + At = cuddT(A); + Ae = cuddE(A); + } else { + At = Ae = A; + } + if (topV == topB) { + Bt = cuddT(B); + Be = cuddE(B); + } else { + Bt = Be = B; + } + + t = addMMRecur(dd, At, Bt, (int)topV, vars); + if (t == NULL) return(NULL); + cuddRef(t); + e = addMMRecur(dd, Ae, Be, (int)topV, vars); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + index = dd->invperm[topV]; + if (vars[index] == 0) { + /* We have split on either the rows of A or the columns + ** of B. We just need to connect the two subresults, + ** which correspond to two submatrices of the result. + */ + res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); + cuddDeref(t); + cuddDeref(e); + } else { + /* we have simultaneously split on the columns of A and + ** the rows of B. The two subresults must be added. + */ + res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + } + + cuddCacheInsert2(dd,cacheOp,A,B,res); + + /* We have computed (and stored in the computed table) a minimal + ** result; that is, a result that assumes no summation variables + ** between the current depth of the recursion and its top + ** variable. We now take into account the z variables by properly + ** scaling the result. + */ + if (res != zero) { + scale = 1.0; + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { + scale *= 2; + } + } + } + if (scale > 1.0) { + add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); + if (add_scale == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(add_scale); + scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); + if (scaled == NULL) { + Cudd_RecursiveDeref(dd, res); + Cudd_RecursiveDeref(dd, add_scale); + return(NULL); + } + cuddRef(scaled); + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + res = scaled; + } + } + cuddDeref(res); + return(res); + +} /* end of addMMRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addTriangle.] + + Description [Performs the recursive step of Cudd_addTriangle. Returns + a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +addTriangleRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + int * vars, + DdNode *cube) +{ + DdNode *fv, *fvn, *gv, *gvn, *t, *e, *res; + CUDD_VALUE_TYPE value; + int top, topf, topg, index; + + statLine(dd); + if (f == DD_PLUS_INFINITY(dd) || g == DD_PLUS_INFINITY(dd)) { + return(DD_PLUS_INFINITY(dd)); + } + + if (cuddIsConstant(f) && cuddIsConstant(g)) { + value = cuddV(f) + cuddV(g); + res = cuddUniqueConst(dd, value); + return(res); + } + if (f < g) { + DdNode *tmp = f; + f = g; + g = tmp; + } + + if (f->ref != 1 || g->ref != 1) { + res = cuddCacheLookup(dd, DD_ADD_TRIANGLE_TAG, f, g, cube); + if (res != NULL) { + return(res); + } + } + + topf = cuddI(dd,f->index); topg = cuddI(dd,g->index); + top = ddMin(topf,topg); + + if (top == topf) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;} + if (top == topg) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;} + + t = addTriangleRecur(dd, fv, gv, vars, cube); + if (t == NULL) return(NULL); + cuddRef(t); + e = addTriangleRecur(dd, fvn, gvn, vars, cube); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + index = dd->invperm[top]; + if (vars[index] < 0) { + res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } else { + res = cuddAddApplyRecur(dd,Cudd_addMinimum,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + cuddDeref(res); + } + + if (f->ref != 1 || g->ref != 1) { + cuddCacheInsert(dd, DD_ADD_TRIANGLE_TAG, f, g, cube, res); + } + + return(res); + +} /* end of addTriangleRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addOuterSum.] + + Description [Performs the recursive step of Cudd_addOuterSum. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddOuterSumRecur( + DdManager *dd, + DdNode *M, + DdNode *r, + DdNode *c) +{ + DdNode *P, *R, *Mt, *Me, *rt, *re, *ct, *ce, *Rt, *Re; + int topM, topc, topr; + int v, index; + + statLine(dd); + /* Check special cases. */ + if (r == DD_PLUS_INFINITY(dd) || c == DD_PLUS_INFINITY(dd)) return(M); + + if (cuddIsConstant(c) && cuddIsConstant(r)) { + R = cuddUniqueConst(dd,Cudd_V(c)+Cudd_V(r)); + cuddRef(R); + if (cuddIsConstant(M)) { + if (cuddV(R) <= cuddV(M)) { + cuddDeref(R); + return(R); + } else { + Cudd_RecursiveDeref(dd,R); + return(M); + } + } else { + P = Cudd_addApply(dd,Cudd_addMinimum,R,M); + cuddRef(P); + Cudd_RecursiveDeref(dd,R); + cuddDeref(P); + return(P); + } + } + + /* Check the cache. */ + R = cuddCacheLookup(dd,DD_ADD_OUT_SUM_TAG,M,r,c); + if (R != NULL) return(R); + + topM = cuddI(dd,M->index); topr = cuddI(dd,r->index); + topc = cuddI(dd,c->index); + v = ddMin(topM,ddMin(topr,topc)); + + /* Compute cofactors. */ + if (topM == v) { Mt = cuddT(M); Me = cuddE(M); } else { Mt = Me = M; } + if (topr == v) { rt = cuddT(r); re = cuddE(r); } else { rt = re = r; } + if (topc == v) { ct = cuddT(c); ce = cuddE(c); } else { ct = ce = c; } + + /* Recursively solve. */ + Rt = cuddAddOuterSumRecur(dd,Mt,rt,ct); + if (Rt == NULL) return(NULL); + cuddRef(Rt); + Re = cuddAddOuterSumRecur(dd,Me,re,ce); + if (Re == NULL) { + Cudd_RecursiveDeref(dd, Rt); + return(NULL); + } + cuddRef(Re); + index = dd->invperm[v]; + R = (Rt == Re) ? Rt : cuddUniqueInter(dd,index,Rt,Re); + if (R == NULL) { + Cudd_RecursiveDeref(dd, Rt); + Cudd_RecursiveDeref(dd, Re); + return(NULL); + } + cuddDeref(Rt); + cuddDeref(Re); + + /* Store the result in the cache. */ + cuddCacheInsert(dd,DD_ADD_OUT_SUM_TAG,M,r,c,R); + + return(R); + +} /* end of cuddAddOuterSumRecur */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddPriority.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddPriority.c new file mode 100644 index 000000000..2b59adca2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddPriority.c @@ -0,0 +1,2027 @@ +/**CFile*********************************************************************** + + FileName [cuddPriority.c] + + PackageName [cudd] + + Synopsis [Priority functions.] + + Description [External procedures included in this file: +
                        +
                      • Cudd_PrioritySelect() +
                      • Cudd_Xgty() +
                      • Cudd_Xeqy() +
                      • Cudd_addXeqy() +
                      • Cudd_Dxygtdxz() +
                      • Cudd_Dxygtdyz() +
                      • Cudd_Inequality() +
                      • Cudd_Disequality() +
                      • Cudd_bddInterval() +
                      • Cudd_CProjection() +
                      • Cudd_addHamming() +
                      • Cudd_MinHammingDist() +
                      • Cudd_bddClosestCube() +
                      + Internal procedures included in this module: +
                        +
                      • cuddCProjectionRecur() +
                      • cuddBddClosestCube() +
                      + Static procedures included in this module: +
                        +
                      • cuddMinHammingDistRecur() +
                      • separateCube() +
                      • createResult() +
                      + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_DEBUG 1 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddPriority.c,v 1.36 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ +static int cuddMinHammingDistRecur (DdNode * f, int *minterm, DdHashTable * table, int upperBound); +static DdNode * separateCube (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE *distance); +static DdNode * createResult (DdManager *dd, unsigned int index, unsigned int phase, DdNode *cube, CUDD_VALUE_TYPE distance); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Selects pairs from R using a priority function.] + + Description [Selects pairs from a relation R(x,y) (given as a BDD) + in such a way that a given x appears in one pair only. Uses a + priority function to determine which y should be paired to a given x. + Cudd_PrioritySelect returns a pointer to + the selected function if successful; NULL otherwise. + Three of the arguments--x, y, and z--are vectors of BDD variables. + The first two are the variables on which R depends. The third vector + is a vector of auxiliary variables, used during the computation. This + vector is optional. If a NULL value is passed instead, + Cudd_PrioritySelect will create the working variables on the fly. + The sizes of x and y (and z if it is not NULL) should equal n. + The priority function Pi can be passed as a BDD, or can be built by + Cudd_PrioritySelect. If NULL is passed instead of a DdNode *, + parameter Pifunc is used by Cudd_PrioritySelect to build a BDD for the + priority function. (Pifunc is a pointer to a C function.) If Pi is not + NULL, then Pifunc is ignored. Pifunc should have the same interface as + the standard priority functions (e.g., Cudd_Dxygtdxz). + Cudd_PrioritySelect and Cudd_CProjection can sometimes be used + interchangeably. Specifically, calling Cudd_PrioritySelect with + Cudd_Xgty as Pifunc produces the same result as calling + Cudd_CProjection with the all-zero minterm as reference minterm. + However, depending on the application, one or the other may be + preferable: +
                        +
                      • When extracting representatives from an equivalence relation, + Cudd_CProjection has the advantage of nor requiring the auxiliary + variables. +
                      • When computing matchings in general bipartite graphs, + Cudd_PrioritySelect normally obtains better results because it can use + more powerful matching schemes (e.g., Cudd_Dxygtdxz). +
                      + ] + + SideEffects [If called with z == NULL, will create new variables in + the manager.] + + SeeAlso [Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_Xgty + Cudd_bddAdjPermuteX Cudd_CProjection] + +******************************************************************************/ +DdNode * +Cudd_PrioritySelect( + DdManager * dd /* manager */, + DdNode * R /* BDD of the relation */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */, + DdNode ** z /* array of z variables (optional: may be NULL) */, + DdNode * Pi /* BDD of the priority function (optional: may be NULL) */, + int n /* size of x, y, and z */, + DD_PRFP Pifunc /* function used to build Pi if it is NULL */) +{ + DdNode *res = NULL; + DdNode *zcube = NULL; + DdNode *Rxz, *Q; + int createdZ = 0; + int createdPi = 0; + int i; + + /* Create z variables if needed. */ + if (z == NULL) { + if (Pi != NULL) return(NULL); + z = ALLOC(DdNode *,n); + if (z == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + createdZ = 1; + for (i = 0; i < n; i++) { + if (dd->size >= (int) CUDD_MAXINDEX - 1) goto endgame; + z[i] = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); + if (z[i] == NULL) goto endgame; + } + } + + /* Create priority function BDD if needed. */ + if (Pi == NULL) { + Pi = Pifunc(dd,n,x,y,z); + if (Pi == NULL) goto endgame; + createdPi = 1; + cuddRef(Pi); + } + + /* Initialize abstraction cube. */ + zcube = DD_ONE(dd); + cuddRef(zcube); + for (i = n - 1; i >= 0; i--) { + DdNode *tmpp; + tmpp = Cudd_bddAnd(dd,z[i],zcube); + if (tmpp == NULL) goto endgame; + cuddRef(tmpp); + Cudd_RecursiveDeref(dd,zcube); + zcube = tmpp; + } + + /* Compute subset of (x,y) pairs. */ + Rxz = Cudd_bddSwapVariables(dd,R,y,z,n); + if (Rxz == NULL) goto endgame; + cuddRef(Rxz); + Q = Cudd_bddAndAbstract(dd,Rxz,Pi,zcube); + if (Q == NULL) { + Cudd_RecursiveDeref(dd,Rxz); + goto endgame; + } + cuddRef(Q); + Cudd_RecursiveDeref(dd,Rxz); + res = Cudd_bddAnd(dd,R,Cudd_Not(Q)); + if (res == NULL) { + Cudd_RecursiveDeref(dd,Q); + goto endgame; + } + cuddRef(res); + Cudd_RecursiveDeref(dd,Q); + +endgame: + if (zcube != NULL) Cudd_RecursiveDeref(dd,zcube); + if (createdZ) { + FREE(z); + } + if (createdPi) { + Cudd_RecursiveDeref(dd,Pi); + } + if (res != NULL) cuddDeref(res); + return(res); + +} /* Cudd_PrioritySelect */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function x > y.] + + Description [This function generates a BDD for the function x > y. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has 3*N-1 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. + Argument z is not used by Cudd_Xgty: it is included to make it + call-compatible to Cudd_Dxygtdxz and Cudd_Dxygtdyz.] + + SideEffects [None] + + SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Dxygtdyz] + +******************************************************************************/ +DdNode * +Cudd_Xgty( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + DdNode ** z /* array of z variables: unused */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + DdNode *u, *v, *w; + int i; + + /* Build bottom part of BDD outside loop. */ + u = Cudd_bddAnd(dd, x[N-1], Cudd_Not(y[N-1])); + if (u == NULL) return(NULL); + cuddRef(u); + + /* Loop to build the rest of the BDD. */ + for (i = N-2; i >= 0; i--) { + v = Cudd_bddAnd(dd, y[i], Cudd_Not(u)); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, u); + u = Cudd_bddIte(dd, x[i], Cudd_Not(v), w); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + + } + cuddDeref(u); + return(u); + +} /* end of Cudd_Xgty */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function x==y.] + + Description [This function generates a BDD for the function x==y. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has 3*N-1 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ] + + SideEffects [None] + + SeeAlso [Cudd_addXeqy] + +******************************************************************************/ +DdNode * +Cudd_Xeqy( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + DdNode *u, *v, *w; + int i; + + /* Build bottom part of BDD outside loop. */ + u = Cudd_bddIte(dd, x[N-1], y[N-1], Cudd_Not(y[N-1])); + if (u == NULL) return(NULL); + cuddRef(u); + + /* Loop to build the rest of the BDD. */ + for (i = N-2; i >= 0; i--) { + v = Cudd_bddAnd(dd, y[i], u); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, u); + u = Cudd_bddIte(dd, x[i], v, w); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + } + cuddDeref(u); + return(u); + +} /* end of Cudd_Xeqy */ + + +/**Function******************************************************************** + + Synopsis [Generates an ADD for the function x==y.] + + Description [This function generates an ADD for the function x==y. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The ADD is built bottom-up. + It has 3*N-1 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ] + + SideEffects [None] + + SeeAlso [Cudd_Xeqy] + +******************************************************************************/ +DdNode * +Cudd_addXeqy( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + DdNode *one, *zero; + DdNode *u, *v, *w; + int i; + + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + /* Build bottom part of ADD outside loop. */ + v = Cudd_addIte(dd, y[N-1], one, zero); + if (v == NULL) return(NULL); + cuddRef(v); + w = Cudd_addIte(dd, y[N-1], zero, one); + if (w == NULL) { + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); + u = Cudd_addIte(dd, x[N-1], v, w); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + + /* Loop to build the rest of the ADD. */ + for (i = N-2; i >= 0; i--) { + v = Cudd_addIte(dd, y[i], u, zero); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_addIte(dd, y[i], zero, u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, u); + u = Cudd_addIte(dd, x[i], v, w); + if (w == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + } + cuddDeref(u); + return(u); + +} /* end of Cudd_addXeqy */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function d(x,y) > d(x,z).] + + Description [This function generates a BDD for the function d(x,y) + > d(x,z); + x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\], + y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\], + with 0 the most significant bit. + The distance d(x,y) is defined as: + \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). + The BDD is built bottom-up. + It has 7*N-3 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ] + + SideEffects [None] + + SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdyz Cudd_Xgty Cudd_bddAdjPermuteX] + +******************************************************************************/ +DdNode * +Cudd_Dxygtdxz( + DdManager * dd /* DD manager */, + int N /* number of x, y, and z variables */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */, + DdNode ** z /* array of z variables */) +{ + DdNode *one, *zero; + DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1; + int i; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Build bottom part of BDD outside loop. */ + y1_ = Cudd_bddIte(dd, y[N-1], one, Cudd_Not(z[N-1])); + if (y1_ == NULL) return(NULL); + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[N-1], z[N-1], one); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); + x1 = Cudd_bddIte(dd, x[N-1], y1_, y2); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + + /* Loop to build the rest of the BDD. */ + for (i = N-2; i >= 0; i--) { + z1 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); + if (z1 == NULL) { + Cudd_RecursiveDeref(dd, x1); + return(NULL); + } + cuddRef(z1); + z2 = Cudd_bddIte(dd, z[i], x1, one); + if (z2 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + return(NULL); + } + cuddRef(z2); + z3 = Cudd_bddIte(dd, z[i], one, x1); + if (z3 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + return(NULL); + } + cuddRef(z3); + z4 = Cudd_bddIte(dd, z[i], x1, zero); + if (z4 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + return(NULL); + } + cuddRef(z4); + Cudd_RecursiveDeref(dd, x1); + y1_ = Cudd_bddIte(dd, y[i], z2, Cudd_Not(z1)); + if (y1_ == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + return(NULL); + } + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[i], z4, z3); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + x1 = Cudd_bddIte(dd, x[i], y1_, y2); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + } + cuddDeref(x1); + return(Cudd_Not(x1)); + +} /* end of Cudd_Dxygtdxz */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function d(x,y) > d(y,z).] + + Description [This function generates a BDD for the function d(x,y) + > d(y,z); + x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\], + y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\], + with 0 the most significant bit. + The distance d(x,y) is defined as: + \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). + The BDD is built bottom-up. + It has 7*N-3 internal nodes, if the variables are ordered as follows: + x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ] + + SideEffects [None] + + SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Xgty Cudd_bddAdjPermuteX] + +******************************************************************************/ +DdNode * +Cudd_Dxygtdyz( + DdManager * dd /* DD manager */, + int N /* number of x, y, and z variables */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */, + DdNode ** z /* array of z variables */) +{ + DdNode *one, *zero; + DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1; + int i; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Build bottom part of BDD outside loop. */ + y1_ = Cudd_bddIte(dd, y[N-1], one, z[N-1]); + if (y1_ == NULL) return(NULL); + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[N-1], z[N-1], zero); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); + x1 = Cudd_bddIte(dd, x[N-1], y1_, Cudd_Not(y2)); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + + /* Loop to build the rest of the BDD. */ + for (i = N-2; i >= 0; i--) { + z1 = Cudd_bddIte(dd, z[i], x1, zero); + if (z1 == NULL) { + Cudd_RecursiveDeref(dd, x1); + return(NULL); + } + cuddRef(z1); + z2 = Cudd_bddIte(dd, z[i], x1, one); + if (z2 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + return(NULL); + } + cuddRef(z2); + z3 = Cudd_bddIte(dd, z[i], one, x1); + if (z3 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + return(NULL); + } + cuddRef(z3); + z4 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); + if (z4 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + return(NULL); + } + cuddRef(z4); + Cudd_RecursiveDeref(dd, x1); + y1_ = Cudd_bddIte(dd, y[i], z2, z1); + if (y1_ == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + return(NULL); + } + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[i], z4, Cudd_Not(z3)); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + x1 = Cudd_bddIte(dd, x[i], y1_, Cudd_Not(y2)); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + } + cuddDeref(x1); + return(Cudd_Not(x1)); + +} /* end of Cudd_Dxygtdyz */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function x - y ≥ c.] + + Description [This function generates a BDD for the function x -y ≥ c. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has a linear number of nodes if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].] + + SideEffects [None] + + SeeAlso [Cudd_Xgty] + +******************************************************************************/ +DdNode * +Cudd_Inequality( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + int c /* right-hand side constant */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + /* The nodes at level i represent values of the difference that are + ** multiples of 2^i. We use variables with names starting with k + ** to denote the multipliers of 2^i in such multiples. */ + int kTrue = c; + int kFalse = c - 1; + /* Mask used to compute the ceiling function. Since we divide by 2^i, + ** we want to know whether the dividend is a multiple of 2^i. If it is, + ** then ceiling and floor coincide; otherwise, they differ by one. */ + int mask = 1; + int i; + + DdNode *f = NULL; /* the eventual result */ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + + /* Two x-labeled nodes are created at most at each iteration. They are + ** stored, along with their k values, in these variables. At each level, + ** the old nodes are freed and the new nodes are copied into the old map. + */ + DdNode *map[2]; + int invalidIndex = 1 << (N-1); + int index[2] = {invalidIndex, invalidIndex}; + + /* This should never happen. */ + if (N < 0) return(NULL); + + /* If there are no bits, both operands are 0. The result depends on c. */ + if (N == 0) { + if (c >= 0) return(one); + else return(zero); + } + + /* The maximum or the minimum difference comparing to c can generate the terminal case */ + if ((1 << N) - 1 < c) return(zero); + else if ((-(1 << N) + 1) >= c) return(one); + + /* Build the result bottom up. */ + for (i = 1; i <= N; i++) { + int kTrueLower, kFalseLower; + int leftChild, middleChild, rightChild; + DdNode *g0, *g1, *fplus, *fequal, *fminus; + int j; + DdNode *newMap[2]; + int newIndex[2]; + + kTrueLower = kTrue; + kFalseLower = kFalse; + /* kTrue = ceiling((c-1)/2^i) + 1 */ + kTrue = ((c-1) >> i) + ((c & mask) != 1) + 1; + mask = (mask << 1) | 1; + /* kFalse = floor(c/2^i) - 1 */ + kFalse = (c >> i) - 1; + newIndex[0] = invalidIndex; + newIndex[1] = invalidIndex; + + for (j = kFalse + 1; j < kTrue; j++) { + /* Skip if node is not reachable from top of BDD. */ + if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue; + + /* Find f- */ + leftChild = (j << 1) - 1; + if (leftChild >= kTrueLower) { + fminus = one; + } else if (leftChild <= kFalseLower) { + fminus = zero; + } else { + assert(leftChild == index[0] || leftChild == index[1]); + if (leftChild == index[0]) { + fminus = map[0]; + } else { + fminus = map[1]; + } + } + + /* Find f= */ + middleChild = j << 1; + if (middleChild >= kTrueLower) { + fequal = one; + } else if (middleChild <= kFalseLower) { + fequal = zero; + } else { + assert(middleChild == index[0] || middleChild == index[1]); + if (middleChild == index[0]) { + fequal = map[0]; + } else { + fequal = map[1]; + } + } + + /* Find f+ */ + rightChild = (j << 1) + 1; + if (rightChild >= kTrueLower) { + fplus = one; + } else if (rightChild <= kFalseLower) { + fplus = zero; + } else { + assert(rightChild == index[0] || rightChild == index[1]); + if (rightChild == index[0]) { + fplus = map[0]; + } else { + fplus = map[1]; + } + } + + /* Build new nodes. */ + g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus); + if (g1 == NULL) { + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g1); + g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal); + if (g0 == NULL) { + Cudd_IterDerefBdd(dd, g1); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g0); + f = Cudd_bddIte(dd, x[N - i], g1, g0); + if (f == NULL) { + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(f); + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + + /* Save newly computed node in map. */ + assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex); + if (newIndex[0] == invalidIndex) { + newIndex[0] = j; + newMap[0] = f; + } else { + newIndex[1] = j; + newMap[1] = f; + } + } + + /* Copy new map to map. */ + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + map[0] = newMap[0]; + map[1] = newMap[1]; + index[0] = newIndex[0]; + index[1] = newIndex[1]; + } + + cuddDeref(f); + return(f); + +} /* end of Cudd_Inequality */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function x - y != c.] + + Description [This function generates a BDD for the function x -y != c. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has a linear number of nodes if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].] + + SideEffects [None] + + SeeAlso [Cudd_Xgty] + +******************************************************************************/ +DdNode * +Cudd_Disequality( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + int c /* right-hand side constant */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + /* The nodes at level i represent values of the difference that are + ** multiples of 2^i. We use variables with names starting with k + ** to denote the multipliers of 2^i in such multiples. */ + int kTrueLb = c + 1; + int kTrueUb = c - 1; + int kFalse = c; + /* Mask used to compute the ceiling function. Since we divide by 2^i, + ** we want to know whether the dividend is a multiple of 2^i. If it is, + ** then ceiling and floor coincide; otherwise, they differ by one. */ + int mask = 1; + int i; + + DdNode *f = NULL; /* the eventual result */ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + + /* Two x-labeled nodes are created at most at each iteration. They are + ** stored, along with their k values, in these variables. At each level, + ** the old nodes are freed and the new nodes are copied into the old map. + */ + DdNode *map[2]; + int invalidIndex = 1 << (N-1); + int index[2] = {invalidIndex, invalidIndex}; + + /* This should never happen. */ + if (N < 0) return(NULL); + + /* If there are no bits, both operands are 0. The result depends on c. */ + if (N == 0) { + if (c != 0) return(one); + else return(zero); + } + + /* The maximum or the minimum difference comparing to c can generate the terminal case */ + if ((1 << N) - 1 < c || (-(1 << N) + 1) > c) return(one); + + /* Build the result bottom up. */ + for (i = 1; i <= N; i++) { + int kTrueLbLower, kTrueUbLower; + int leftChild, middleChild, rightChild; + DdNode *g0, *g1, *fplus, *fequal, *fminus; + int j; + DdNode *newMap[2]; + int newIndex[2]; + + kTrueLbLower = kTrueLb; + kTrueUbLower = kTrueUb; + /* kTrueLb = floor((c-1)/2^i) + 2 */ + kTrueLb = ((c-1) >> i) + 2; + /* kTrueUb = ceiling((c+1)/2^i) - 2 */ + kTrueUb = ((c+1) >> i) + (((c+2) & mask) != 1) - 2; + mask = (mask << 1) | 1; + newIndex[0] = invalidIndex; + newIndex[1] = invalidIndex; + + for (j = kTrueUb + 1; j < kTrueLb; j++) { + /* Skip if node is not reachable from top of BDD. */ + if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue; + + /* Find f- */ + leftChild = (j << 1) - 1; + if (leftChild >= kTrueLbLower || leftChild <= kTrueUbLower) { + fminus = one; + } else if (i == 1 && leftChild == kFalse) { + fminus = zero; + } else { + assert(leftChild == index[0] || leftChild == index[1]); + if (leftChild == index[0]) { + fminus = map[0]; + } else { + fminus = map[1]; + } + } + + /* Find f= */ + middleChild = j << 1; + if (middleChild >= kTrueLbLower || middleChild <= kTrueUbLower) { + fequal = one; + } else if (i == 1 && middleChild == kFalse) { + fequal = zero; + } else { + assert(middleChild == index[0] || middleChild == index[1]); + if (middleChild == index[0]) { + fequal = map[0]; + } else { + fequal = map[1]; + } + } + + /* Find f+ */ + rightChild = (j << 1) + 1; + if (rightChild >= kTrueLbLower || rightChild <= kTrueUbLower) { + fplus = one; + } else if (i == 1 && rightChild == kFalse) { + fplus = zero; + } else { + assert(rightChild == index[0] || rightChild == index[1]); + if (rightChild == index[0]) { + fplus = map[0]; + } else { + fplus = map[1]; + } + } + + /* Build new nodes. */ + g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus); + if (g1 == NULL) { + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g1); + g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal); + if (g0 == NULL) { + Cudd_IterDerefBdd(dd, g1); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g0); + f = Cudd_bddIte(dd, x[N - i], g1, g0); + if (f == NULL) { + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(f); + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + + /* Save newly computed node in map. */ + assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex); + if (newIndex[0] == invalidIndex) { + newIndex[0] = j; + newMap[0] = f; + } else { + newIndex[1] = j; + newMap[1] = f; + } + } + + /* Copy new map to map. */ + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + map[0] = newMap[0]; + map[1] = newMap[1]; + index[0] = newIndex[0]; + index[1] = newIndex[1]; + } + + cuddDeref(f); + return(f); + +} /* end of Cudd_Disequality */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function lowerB ≤ x ≤ upperB.] + + Description [This function generates a BDD for the function + lowerB ≤ x ≤ upperB, where x is an N-bit number, + x\[0\] x\[1\] ... x\[N-1\], with 0 the most significant bit (important!). + The number of variables N should be sufficient to represent the bounds; + otherwise, the bounds are truncated to their N least significant bits. + Two BDDs are built bottom-up for lowerB ≤ x and x ≤ upperB, and they + are finally conjoined.] + + SideEffects [None] + + SeeAlso [Cudd_Xgty] + +******************************************************************************/ +DdNode * +Cudd_bddInterval( + DdManager * dd /* DD manager */, + int N /* number of x variables */, + DdNode ** x /* array of x variables */, + unsigned int lowerB /* lower bound */, + unsigned int upperB /* upper bound */) +{ + DdNode *one, *zero; + DdNode *r, *rl, *ru; + int i; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + rl = one; + cuddRef(rl); + ru = one; + cuddRef(ru); + + /* Loop to build the rest of the BDDs. */ + for (i = N-1; i >= 0; i--) { + DdNode *vl, *vu; + vl = Cudd_bddIte(dd, x[i], + lowerB&1 ? rl : one, + lowerB&1 ? zero : rl); + if (vl == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(vl); + Cudd_IterDerefBdd(dd, rl); + rl = vl; + lowerB >>= 1; + vu = Cudd_bddIte(dd, x[i], + upperB&1 ? ru : zero, + upperB&1 ? one : ru); + if (vu == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(vu); + Cudd_IterDerefBdd(dd, ru); + ru = vu; + upperB >>= 1; + } + + /* Conjoin the two bounds. */ + r = Cudd_bddAnd(dd, rl, ru); + if (r == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + cuddDeref(r); + return(r); + +} /* end of Cudd_bddInterval */ + + +/**Function******************************************************************** + + Synopsis [Computes the compatible projection of R w.r.t. cube Y.] + + Description [Computes the compatible projection of relation R with + respect to cube Y. Returns a pointer to the c-projection if + successful; NULL otherwise. For a comparison between Cudd_CProjection + and Cudd_PrioritySelect, see the documentation of the latter.] + + SideEffects [None] + + SeeAlso [Cudd_PrioritySelect] + +******************************************************************************/ +DdNode * +Cudd_CProjection( + DdManager * dd, + DdNode * R, + DdNode * Y) +{ + DdNode *res; + DdNode *support; + + if (Cudd_CheckCube(dd,Y) == 0) { + (void) fprintf(dd->err, + "Error: The third argument of Cudd_CProjection should be a cube\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + /* Compute the support of Y, which is used by the abstraction step + ** in cuddCProjectionRecur. + */ + support = Cudd_Support(dd,Y); + if (support == NULL) return(NULL); + cuddRef(support); + + do { + dd->reordered = 0; + res = cuddCProjectionRecur(dd,R,Y,support); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd,support); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,support); + cuddDeref(res); + + return(res); + +} /* end of Cudd_CProjection */ + + +/**Function******************************************************************** + + Synopsis [Computes the Hamming distance ADD.] + + Description [Computes the Hamming distance ADD. Returns an ADD that + gives the Hamming distance between its two arguments if successful; + NULL otherwise. The two vectors xVars and yVars identify the variables + that form the two arguments.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addHamming( + DdManager * dd, + DdNode ** xVars, + DdNode ** yVars, + int nVars) +{ + DdNode *result,*tempBdd; + DdNode *tempAdd,*temp; + int i; + + result = DD_ZERO(dd); + cuddRef(result); + + for (i = 0; i < nVars; i++) { + tempBdd = Cudd_bddIte(dd,xVars[i],Cudd_Not(yVars[i]),yVars[i]); + if (tempBdd == NULL) { + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(tempBdd); + tempAdd = Cudd_BddToAdd(dd,tempBdd); + if (tempAdd == NULL) { + Cudd_RecursiveDeref(dd,tempBdd); + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(tempAdd); + Cudd_RecursiveDeref(dd,tempBdd); + temp = Cudd_addApply(dd,Cudd_addPlus,tempAdd,result); + if (temp == NULL) { + Cudd_RecursiveDeref(dd,tempAdd); + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(temp); + Cudd_RecursiveDeref(dd,tempAdd); + Cudd_RecursiveDeref(dd,result); + result = temp; + } + + cuddDeref(result); + return(result); + +} /* end of Cudd_addHamming */ + + +/**Function******************************************************************** + + Synopsis [Returns the minimum Hamming distance between f and minterm.] + + Description [Returns the minimum Hamming distance between the + minterms of a function f and a reference minterm. The function is + given as a BDD; the minterm is given as an array of integers, one + for each variable in the manager. Returns the minimum distance if + it is less than the upper bound; the upper bound if the minimum + distance is at least as large; CUDD_OUT_OF_MEM in case of failure.] + + SideEffects [None] + + SeeAlso [Cudd_addHamming Cudd_bddClosestCube] + +******************************************************************************/ +int +Cudd_MinHammingDist( + DdManager *dd /* DD manager */, + DdNode *f /* function to examine */, + int *minterm /* reference minterm */, + int upperBound /* distance above which an approximate answer is OK */) +{ + DdHashTable *table; + CUDD_VALUE_TYPE epsilon; + int res; + + table = cuddHashTableInit(dd,1,2); + if (table == NULL) { + return(CUDD_OUT_OF_MEM); + } + epsilon = Cudd_ReadEpsilon(dd); + Cudd_SetEpsilon(dd,(CUDD_VALUE_TYPE)0.0); + res = cuddMinHammingDistRecur(f,minterm,table,upperBound); + cuddHashTableQuit(table); + Cudd_SetEpsilon(dd,epsilon); + + return(res); + +} /* end of Cudd_MinHammingDist */ + + +/**Function******************************************************************** + + Synopsis [Finds a cube of f at minimum Hamming distance from g.] + + Description [Finds a cube of f at minimum Hamming distance from the + minterms of g. All the minterms of the cube are at the minimum + distance. If the distance is 0, the cube belongs to the + intersection of f and g. Returns the cube if successful; NULL + otherwise.] + + SideEffects [The distance is returned as a side effect.] + + SeeAlso [Cudd_MinHammingDist] + +******************************************************************************/ +DdNode * +Cudd_bddClosestCube( + DdManager *dd, + DdNode * f, + DdNode *g, + int *distance) +{ + DdNode *res, *acube; + CUDD_VALUE_TYPE rdist; + + /* Compute the cube and distance as a single ADD. */ + do { + dd->reordered = 0; + res = cuddBddClosestCube(dd,f,g,CUDD_CONST_INDEX + 1.0); + } while (dd->reordered == 1); + if (res == NULL) return(NULL); + cuddRef(res); + + /* Unpack distance and cube. */ + do { + dd->reordered = 0; + acube = separateCube(dd, res, &rdist); + } while (dd->reordered == 1); + if (acube == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(acube); + Cudd_RecursiveDeref(dd, res); + + /* Convert cube from ADD to BDD. */ + do { + dd->reordered = 0; + res = cuddAddBddDoPattern(dd, acube); + } while (dd->reordered == 1); + if (res == NULL) { + Cudd_RecursiveDeref(dd, acube); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, acube); + + *distance = (int) rdist; + cuddDeref(res); + return(res); + +} /* end of Cudd_bddClosestCube */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CProjection.] + + Description [Performs the recursive step of Cudd_CProjection. Returns + the projection if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_CProjection] + +******************************************************************************/ +DdNode * +cuddCProjectionRecur( + DdManager * dd, + DdNode * R, + DdNode * Y, + DdNode * Ysupp) +{ + DdNode *res, *res1, *res2, *resA; + DdNode *r, *y, *RT, *RE, *YT, *YE, *Yrest, *Ra, *Ran, *Gamma, *Alpha; + unsigned int topR, topY, top, index; + DdNode *one = DD_ONE(dd); + + statLine(dd); + if (Y == one) return(R); + +#ifdef DD_DEBUG + assert(!Cudd_IsConstant(Y)); +#endif + + if (R == Cudd_Not(one)) return(R); + + res = cuddCacheLookup2(dd, Cudd_CProjection, R, Y); + if (res != NULL) return(res); + + r = Cudd_Regular(R); + topR = cuddI(dd,r->index); + y = Cudd_Regular(Y); + topY = cuddI(dd,y->index); + + top = ddMin(topR, topY); + + /* Compute the cofactors of R */ + if (topR == top) { + index = r->index; + RT = cuddT(r); + RE = cuddE(r); + if (r != R) { + RT = Cudd_Not(RT); RE = Cudd_Not(RE); + } + } else { + RT = RE = R; + } + + if (topY > top) { + /* Y does not depend on the current top variable. + ** We just need to compute the results on the two cofactors of R + ** and make them the children of a node labeled r->index. + */ + res1 = cuddCProjectionRecur(dd,RT,Y,Ysupp); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddCProjectionRecur(dd,RE,Y,Ysupp); + if (res2 == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); + } + cuddRef(res2); + res = cuddBddIteRecur(dd, dd->vars[index], res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(NULL); + } + /* If we have reached this point, res1 and res2 are now + ** incorporated in res. cuddDeref is therefore sufficient. + */ + cuddDeref(res1); + cuddDeref(res2); + } else { + /* Compute the cofactors of Y */ + index = y->index; + YT = cuddT(y); + YE = cuddE(y); + if (y != Y) { + YT = Cudd_Not(YT); YE = Cudd_Not(YE); + } + if (YT == Cudd_Not(one)) { + Alpha = Cudd_Not(dd->vars[index]); + Yrest = YE; + Ra = RE; + Ran = RT; + } else { + Alpha = dd->vars[index]; + Yrest = YT; + Ra = RT; + Ran = RE; + } + Gamma = cuddBddExistAbstractRecur(dd,Ra,cuddT(Ysupp)); + if (Gamma == NULL) return(NULL); + if (Gamma == one) { + res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res = cuddBddAndRecur(dd, Alpha, res1); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); + } + cuddDeref(res1); + } else if (Gamma == Cudd_Not(one)) { + res1 = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res = cuddBddAndRecur(dd, Cudd_Not(Alpha), res1); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); + } + cuddDeref(res1); + } else { + cuddRef(Gamma); + resA = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); + if (resA == NULL) { + Cudd_RecursiveDeref(dd,Gamma); + return(NULL); + } + cuddRef(resA); + res2 = cuddBddAndRecur(dd, Cudd_Not(Gamma), resA); + if (res2 == NULL) { + Cudd_RecursiveDeref(dd,Gamma); + Cudd_RecursiveDeref(dd,resA); + return(NULL); + } + cuddRef(res2); + Cudd_RecursiveDeref(dd,Gamma); + Cudd_RecursiveDeref(dd,resA); + res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd,res2); + return(NULL); + } + cuddRef(res1); + res = cuddBddIteRecur(dd, Alpha, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + } + } + + cuddCacheInsert2(dd,Cudd_CProjection,R,Y,res); + + return(res); + +} /* end of cuddCProjectionRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddClosestCube.] + + Description [Performs the recursive step of Cudd_bddClosestCube. + Returns the cube if succesful; NULL otherwise. The procedure uses a + four-way recursion to examine all four combinations of cofactors of + f and g according to the following formula. +
                      +    H(f,g) = min(H(ft,gt), H(fe,ge), H(ft,ge)+1, H(fe,gt)+1)
                      +  
                      + Bounding is based on the following observations. +
                        +
                      • If we already found two points at distance 0, there is no point in + continuing. Furthermore, +
                      • If F == not(G) then the best we can hope for is a minimum distance + of 1. If we have already found two points at distance 1, there is + no point in continuing. (Indeed, H(F,G) == 1 in this case. We + have to continue, though, to find the cube.) +
                      + The variable bound is set at the largest value of the distance + that we are still interested in. Therefore, we desist when +
                      +    (bound == -1) and (F != not(G)) or (bound == 0) and (F == not(G)).
                      +  
                      + If we were maximally aggressive in using the bound, we would always + set the bound to the minimum distance seen thus far minus one. That + is, we would maintain the invariant +
                      +    bound < minD,
                      +  
                      + except at the very beginning, when we have no value for + minD.

                      + + However, we do not use bound < minD when examining the + two negative cofactors, because we try to find a large cube at + minimum distance. To do so, we try to find a cube in the negative + cofactors at the same or smaller distance from the cube found in the + positive cofactors.

                      + + When we compute H(ft,ge) and H(fe,gt) we + know that we are going to add 1 to the result of the recursive call + to account for the difference in the splitting variable. Therefore, + we decrease the bound correspondingly.

                      + + Another important observation concerns the need of examining all + four pairs of cofators only when both f and + g depend on the top variable.

                      + + Suppose gt == ge == g. (That is, g does + not depend on the top variable.) Then +

                      +    H(f,g) = min(H(ft,g), H(fe,g), H(ft,g)+1, H(fe,g)+1)
                      +	   = min(H(ft,g), H(fe,g)) .
                      +  
                      + Therefore, under these circumstances, we skip the two "cross" cases.

                      + + An interesting feature of this function is the scheme used for + caching the results in the global computed table. Since we have a + cube and a distance, we combine them to form an ADD. The + combination replaces the zero child of the top node of the cube with + the negative of the distance. (The use of the negative is to avoid + ambiguity with 1.) The degenerate cases (zero and one) are treated + specially because the distance is known (0 for one, and infinity for + zero).] + + SideEffects [None] + + SeeAlso [Cudd_bddClosestCube] + +******************************************************************************/ +DdNode * +cuddBddClosestCube( + DdManager *dd, + DdNode *f, + DdNode *g, + CUDD_VALUE_TYPE bound) +{ + DdNode *res, *F, *G, *ft, *fe, *gt, *ge, *tt, *ee; + DdNode *ctt, *cee, *cte, *cet; + CUDD_VALUE_TYPE minD, dtt, dee, dte, det; + DdNode *one = DD_ONE(dd); + DdNode *lzero = Cudd_Not(one); + DdNode *azero = DD_ZERO(dd); + unsigned int topf, topg, index; + + statLine(dd); + if (bound < (f == Cudd_Not(g))) return(azero); + /* Terminal cases. */ + if (g == lzero || f == lzero) return(azero); + if (f == one && g == one) return(one); + + /* Check cache. */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + if (F->ref != 1 || G->ref != 1) { + res = cuddCacheLookup2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g); + if (res != NULL) return(res); + } + + topf = cuddI(dd,F->index); + topg = cuddI(dd,G->index); + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg <= topf) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + tt = cuddBddClosestCube(dd,ft,gt,bound); + if (tt == NULL) return(NULL); + cuddRef(tt); + ctt = separateCube(dd,tt,&dtt); + if (ctt == NULL) { + Cudd_RecursiveDeref(dd, tt); + return(NULL); + } + cuddRef(ctt); + Cudd_RecursiveDeref(dd, tt); + minD = dtt; + bound = ddMin(bound,minD); + + ee = cuddBddClosestCube(dd,fe,ge,bound); + if (ee == NULL) { + Cudd_RecursiveDeref(dd, ctt); + return(NULL); + } + cuddRef(ee); + cee = separateCube(dd,ee,&dee); + if (cee == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, ee); + return(NULL); + } + cuddRef(cee); + Cudd_RecursiveDeref(dd, ee); + minD = ddMin(dtt, dee); + if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1); + + if (minD > 0 && topf == topg) { + DdNode *te = cuddBddClosestCube(dd,ft,ge,bound-1); + if (te == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + return(NULL); + } + cuddRef(te); + cte = separateCube(dd,te,&dte); + if (cte == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, te); + return(NULL); + } + cuddRef(cte); + Cudd_RecursiveDeref(dd, te); + dte += 1.0; + minD = ddMin(minD, dte); + } else { + cte = azero; + cuddRef(cte); + dte = CUDD_CONST_INDEX + 1.0; + } + if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1); + + if (minD > 0 && topf == topg) { + DdNode *et = cuddBddClosestCube(dd,fe,gt,bound-1); + if (et == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + return(NULL); + } + cuddRef(et); + cet = separateCube(dd,et,&det); + if (cet == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + Cudd_RecursiveDeref(dd, et); + return(NULL); + } + cuddRef(cet); + Cudd_RecursiveDeref(dd, et); + det += 1.0; + minD = ddMin(minD, det); + } else { + cet = azero; + cuddRef(cet); + det = CUDD_CONST_INDEX + 1.0; + } + + if (minD == dtt) { + if (dtt == dee && ctt == cee) { + res = createResult(dd,CUDD_CONST_INDEX,1,ctt,dtt); + } else { + res = createResult(dd,index,1,ctt,dtt); + } + } else if (minD == dee) { + res = createResult(dd,index,0,cee,dee); + } else if (minD == dte) { +#ifdef DD_DEBUG + assert(topf == topg); +#endif + res = createResult(dd,index,1,cte,dte); + } else { +#ifdef DD_DEBUG + assert(topf == topg); +#endif + res = createResult(dd,index,0,cet,det); + } + if (res == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + Cudd_RecursiveDeref(dd, cet); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + Cudd_RecursiveDeref(dd, cet); + + /* Only cache results that are different from azero to avoid + ** storing results that depend on the value of the bound. */ + if ((F->ref != 1 || G->ref != 1) && res != azero) + cuddCacheInsert2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g, res); + + cuddDeref(res); + return(res); + +} /* end of cuddBddClosestCube */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_MinHammingDist.] + + Description [Performs the recursive step of Cudd_MinHammingDist. + It is based on the following identity. Let H(f) be the + minimum Hamming distance of the minterms of f from the reference + minterm. Then: +

                      + H(f) = min(H(f0)+h0,H(f1)+h1) + + where f0 and f1 are the two cofactors of f with respect to its top + variable; h0 is 1 if the minterm assigns 1 to the top variable of f; + h1 is 1 if the minterm assigns 0 to the top variable of f. + The upper bound on the distance is used to bound the depth of the + recursion. + Returns the minimum distance unless it exceeds the upper bound or + computation fails.] + + SideEffects [None] + + SeeAlso [Cudd_MinHammingDist] + +******************************************************************************/ +static int +cuddMinHammingDistRecur( + DdNode * f, + int *minterm, + DdHashTable * table, + int upperBound) +{ + DdNode *F, *Ft, *Fe; + double h, hT, hE; + DdNode *zero, *res; + DdManager *dd = table->manager; + + statLine(dd); + if (upperBound == 0) return(0); + + F = Cudd_Regular(f); + + if (cuddIsConstant(F)) { + zero = Cudd_Not(DD_ONE(dd)); + if (f == dd->background || f == zero) { + return(upperBound); + } else { + return(0); + } + } + if ((res = cuddHashTableLookup1(table,f)) != NULL) { + h = cuddV(res); + if (res->ref == 0) { + dd->dead++; + dd->constants.dead++; + } + return((int) h); + } + + Ft = cuddT(F); Fe = cuddE(F); + if (Cudd_IsComplement(f)) { + Ft = Cudd_Not(Ft); Fe = Cudd_Not(Fe); + } + if (minterm[F->index] == 0) { + DdNode *temp = Ft; + Ft = Fe; Fe = temp; + } + + hT = cuddMinHammingDistRecur(Ft,minterm,table,upperBound); + if (hT == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + if (hT == 0) { + hE = upperBound; + } else { + hE = cuddMinHammingDistRecur(Fe,minterm,table,upperBound - 1); + if (hE == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + } + h = ddMin(hT, hE + 1); + + if (F->ref != 1) { + ptrint fanout = (ptrint) F->ref; + cuddSatDec(fanout); + res = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) h); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + cuddRef(res); Cudd_RecursiveDeref(dd, res); + return(CUDD_OUT_OF_MEM); + } + } + + return((int) h); + +} /* end of cuddMinHammingDistRecur */ + + +/**Function******************************************************************** + + Synopsis [Separates cube from distance.] + + Description [Separates cube from distance. Returns the cube if + successful; NULL otherwise.] + + SideEffects [The distance is returned as a side effect.] + + SeeAlso [cuddBddClosestCube createResult] + +******************************************************************************/ +static DdNode * +separateCube( + DdManager *dd, + DdNode *f, + CUDD_VALUE_TYPE *distance) +{ + DdNode *cube, *t; + + /* One and zero are special cases because the distance is implied. */ + if (Cudd_IsConstant(f)) { + *distance = (f == DD_ONE(dd)) ? 0.0 : + (1.0 + (CUDD_VALUE_TYPE) CUDD_CONST_INDEX); + return(f); + } + + /* Find out which branch points to the distance and replace the top + ** node with one pointing to zero instead. */ + t = cuddT(f); + if (Cudd_IsConstant(t) && cuddV(t) <= 0) { +#ifdef DD_DEBUG + assert(!Cudd_IsConstant(cuddE(f)) || cuddE(f) == DD_ONE(dd)); +#endif + *distance = -cuddV(t); + cube = cuddUniqueInter(dd, f->index, DD_ZERO(dd), cuddE(f)); + } else { +#ifdef DD_DEBUG + assert(!Cudd_IsConstant(t) || t == DD_ONE(dd)); +#endif + *distance = -cuddV(cuddE(f)); + cube = cuddUniqueInter(dd, f->index, t, DD_ZERO(dd)); + } + + return(cube); + +} /* end of separateCube */ + + +/**Function******************************************************************** + + Synopsis [Builds a result for cache storage.] + + Description [Builds a result for cache storage. Returns a pointer + to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddBddClosestCube separateCube] + +******************************************************************************/ +static DdNode * +createResult( + DdManager *dd, + unsigned int index, + unsigned int phase, + DdNode *cube, + CUDD_VALUE_TYPE distance) +{ + DdNode *res, *constant; + + /* Special case. The cube is either one or zero, and we do not + ** add any variables. Hence, the result is also one or zero, + ** and the distance remains implied by the value of the constant. */ + if (index == CUDD_CONST_INDEX && Cudd_IsConstant(cube)) return(cube); + + constant = cuddUniqueConst(dd,-distance); + if (constant == NULL) return(NULL); + cuddRef(constant); + + if (index == CUDD_CONST_INDEX) { + /* Replace the top node. */ + if (cuddT(cube) == DD_ZERO(dd)) { + res = cuddUniqueInter(dd,cube->index,constant,cuddE(cube)); + } else { + res = cuddUniqueInter(dd,cube->index,cuddT(cube),constant); + } + } else { + /* Add a new top node. */ +#ifdef DD_DEBUG + assert(cuddI(dd,index) < cuddI(dd,cube->index)); +#endif + if (phase) { + res = cuddUniqueInter(dd,index,cube,constant); + } else { + res = cuddUniqueInter(dd,index,constant,cube); + } + } + if (res == NULL) { + Cudd_RecursiveDeref(dd, constant); + return(NULL); + } + cuddDeref(constant); /* safe because constant is part of res */ + + return(res); + +} /* end of createResult */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddRead.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddRead.c new file mode 100644 index 000000000..713668fe2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddRead.c @@ -0,0 +1,517 @@ +/**CFile*********************************************************************** + + FileName [cuddRead.c] + + PackageName [cudd] + + Synopsis [Functions to read in a matrix] + + Description [External procedures included in this module: +
                        +
                      • Cudd_addRead() +
                      • Cudd_bddRead() +
                      ] + + SeeAlso [cudd_addHarwell.c] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddRead.c,v 1.7 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Reads in a sparse matrix.] + + Description [Reads in a sparse matrix specified in a simple format. + The first line of the input contains the numbers of rows and columns. + The remaining lines contain the elements of the matrix, one per line. + Given a background value + (specified by the background field of the manager), only the values + different from it are explicitly listed. Each foreground element is + described by two integers, i.e., the row and column number, and a + real number, i.e., the value.

                      + Cudd_addRead produces an ADD that depends on two sets of variables: x + and y. The x variables (x\[0\] ... x\[nx-1\]) encode the row index and + the y variables (y\[0\] ... y\[ny-1\]) encode the column index. + x\[0\] and y\[0\] are the most significant bits in the indices. + The variables may already exist or may be created by the function. + The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.

                      + On input, nx and ny hold the numbers + of row and column variables already in existence. On output, they + hold the numbers of row and column variables actually used by the + matrix. When Cudd_addRead creates the variable arrays, + the index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy. + When some variables already exist Cudd_addRead expects the indices + of the existing x variables to be bx+i*sx, and the indices of the + existing y variables to be by+i*sy.

                      + m and n are set to the numbers of rows and columns of the + matrix. Their values on input are immaterial. + The ADD for the + sparse matrix is returned in E, and its reference count is > 0. + Cudd_addRead returns 1 in case of success; 0 otherwise.] + + SideEffects [nx and ny are set to the numbers of row and column + variables. m and n are set to the numbers of rows and columns. x and y + are possibly extended to represent the array of row and column + variables. Similarly for xn and yn_, which hold on return from + Cudd_addRead the complements of the row and column variables.] + + SeeAlso [Cudd_addHarwell Cudd_bddRead] + +******************************************************************************/ +int +Cudd_addRead( + FILE * fp /* input file pointer */, + DdManager * dd /* DD manager */, + DdNode ** E /* characteristic function of the graph */, + DdNode *** x /* array of row variables */, + DdNode *** y /* array of column variables */, + DdNode *** xn /* array of complemented row variables */, + DdNode *** yn_ /* array of complemented column variables */, + int * nx /* number or row variables */, + int * ny /* number or column variables */, + int * m /* number of rows */, + int * n /* number of columns */, + int bx /* first index of row variables */, + int sx /* step of row variables */, + int by /* first index of column variables */, + int sy /* step of column variables */) +{ + DdNode *one, *zero; + DdNode *w, *neW; + DdNode *minterm1; + int u, v, err, i, nv; + int lnx, lny; + CUDD_VALUE_TYPE val; + DdNode **lx, **ly, **lxn, **lyn; + + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + err = fscanf(fp, "%d %d", &u, &v); + if (err == EOF) { + return(0); + } else if (err != 2) { + return(0); + } + + *m = u; + /* Compute the number of x variables. */ + lx = *x; lxn = *xn; + u--; /* row and column numbers start from 0 */ + for (lnx=0; u > 0; lnx++) { + u >>= 1; + } + /* Here we rely on the fact that REALLOC of a null pointer is + ** translates to an ALLOC. + */ + if (lnx > *nx) { + *x = lx = REALLOC(DdNode *, *x, lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *xn = lxn = REALLOC(DdNode *, *xn, lnx); + if (lxn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } + + *n = v; + /* Compute the number of y variables. */ + ly = *y; lyn = *yn_; + v--; /* row and column numbers start from 0 */ + for (lny=0; v > 0; lny++) { + v >>= 1; + } + /* Here we rely on the fact that REALLOC of a null pointer is + ** translates to an ALLOC. + */ + if (lny > *ny) { + *y = ly = REALLOC(DdNode *, *y, lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *yn_ = lyn = REALLOC(DdNode *, *yn_, lny); + if (lyn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } + + /* Create all new variables. */ + for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) { + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); + cuddRef(lx[i]); + do { + dd->reordered = 0; + lxn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lxn[i] == NULL) return(0); + cuddRef(lxn[i]); + } + for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) { + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); + do { + dd->reordered = 0; + lyn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lyn[i] == NULL) return(0); + cuddRef(lyn[i]); + } + *nx = lnx; + *ny = lny; + + *E = dd->background; /* this call will never cause reordering */ + cuddRef(*E); + + while (! feof(fp)) { + err = fscanf(fp, "%d %d %lf", &u, &v, &val); + if (err == EOF) { + break; + } else if (err != 3) { + return(0); + } else if (u >= *m || v >= *n || u < 0 || v < 0) { + return(0); + } + + minterm1 = one; cuddRef(minterm1); + + /* Build minterm1 corresponding to this arc */ + for (i = lnx - 1; i>=0; i--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lx[i]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lxn[i]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + u >>= 1; + } + for (i = lny - 1; i>=0; i--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, ly[i]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lyn[i]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + v >>= 1; + } + /* Create new constant node if necessary. + ** This call will never cause reordering. + */ + neW = cuddUniqueConst(dd, val); + if (neW == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(neW); + + w = Cudd_addIte(dd, minterm1, neW, *E); + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, neW); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, neW); + Cudd_RecursiveDeref(dd, *E); + *E = w; + } + return(1); + +} /* end of Cudd_addRead */ + + +/**Function******************************************************************** + + Synopsis [Reads in a graph (without labels) given as a list of arcs.] + + Description [Reads in a graph (without labels) given as an adjacency + matrix. The first line of the input contains the numbers of rows and + columns of the adjacency matrix. The remaining lines contain the arcs + of the graph, one per line. Each arc is described by two integers, + i.e., the row and column number, or the indices of the two endpoints. + Cudd_bddRead produces a BDD that depends on two sets of variables: x + and y. The x variables (x\[0\] ... x\[nx-1\]) encode + the row index and the y variables (y\[0\] ... y\[ny-1\]) encode the + column index. x\[0\] and y\[0\] are the most significant bits in the + indices. + The variables may already exist or may be created by the function. + The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.

                      + On input, nx and ny hold the numbers of row and column variables already + in existence. On output, they hold the numbers of row and column + variables actually used by the matrix. When Cudd_bddRead creates the + variable arrays, the index of x\[i\] is bx+i*sx, and the index of + y\[i\] is by+i*sy. When some variables already exist, Cudd_bddRead + expects the indices of the existing x variables to be bx+i*sx, and the + indices of the existing y variables to be by+i*sy.

                      + m and n are set to the numbers of rows and columns of the + matrix. Their values on input are immaterial. The BDD for the graph + is returned in E, and its reference count is > 0. Cudd_bddRead returns + 1 in case of success; 0 otherwise.] + + SideEffects [nx and ny are set to the numbers of row and column + variables. m and n are set to the numbers of rows and columns. x and y + are possibly extended to represent the array of row and column + variables.] + + SeeAlso [Cudd_addHarwell Cudd_addRead] + +******************************************************************************/ +int +Cudd_bddRead( + FILE * fp /* input file pointer */, + DdManager * dd /* DD manager */, + DdNode ** E /* characteristic function of the graph */, + DdNode *** x /* array of row variables */, + DdNode *** y /* array of column variables */, + int * nx /* number or row variables */, + int * ny /* number or column variables */, + int * m /* number of rows */, + int * n /* number of columns */, + int bx /* first index of row variables */, + int sx /* step of row variables */, + int by /* first index of column variables */, + int sy /* step of column variables */) +{ + DdNode *one, *zero; + DdNode *w; + DdNode *minterm1; + int u, v, err, i, nv; + int lnx, lny; + DdNode **lx, **ly; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + err = fscanf(fp, "%d %d", &u, &v); + if (err == EOF) { + return(0); + } else if (err != 2) { + return(0); + } + + *m = u; + /* Compute the number of x variables. */ + lx = *x; + u--; /* row and column numbers start from 0 */ + for (lnx=0; u > 0; lnx++) { + u >>= 1; + } + if (lnx > *nx) { + *x = lx = REALLOC(DdNode *, *x, lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } + + *n = v; + /* Compute the number of y variables. */ + ly = *y; + v--; /* row and column numbers start from 0 */ + for (lny=0; v > 0; lny++) { + v >>= 1; + } + if (lny > *ny) { + *y = ly = REALLOC(DdNode *, *y, lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } + + /* Create all new variables. */ + for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) { + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); + cuddRef(lx[i]); + } + for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) { + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); + } + *nx = lnx; + *ny = lny; + + *E = zero; /* this call will never cause reordering */ + cuddRef(*E); + + while (! feof(fp)) { + err = fscanf(fp, "%d %d", &u, &v); + if (err == EOF) { + break; + } else if (err != 2) { + return(0); + } else if (u >= *m || v >= *n || u < 0 || v < 0) { + return(0); + } + + minterm1 = one; cuddRef(minterm1); + + /* Build minterm1 corresponding to this arc. */ + for (i = lnx - 1; i>=0; i--) { + if (u & 1) { + w = Cudd_bddAnd(dd, minterm1, lx[i]); + } else { + w = Cudd_bddAnd(dd, minterm1, Cudd_Not(lx[i])); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd,minterm1); + minterm1 = w; + u >>= 1; + } + for (i = lny - 1; i>=0; i--) { + if (v & 1) { + w = Cudd_bddAnd(dd, minterm1, ly[i]); + } else { + w = Cudd_bddAnd(dd, minterm1, Cudd_Not(ly[i])); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + v >>= 1; + } + + w = Cudd_bddAnd(dd, Cudd_Not(minterm1), Cudd_Not(*E)); + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + w = Cudd_Not(w); + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, *E); + *E = w; + } + return(1); + +} /* end of Cudd_bddRead */ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddRef.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddRef.c new file mode 100644 index 000000000..457d71442 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddRef.c @@ -0,0 +1,808 @@ +/**CFile*********************************************************************** + + FileName [cuddRef.c] + + PackageName [cudd] + + Synopsis [Functions that manipulate the reference counts.] + + Description [External procedures included in this module: +

                        +
                      • Cudd_Ref() +
                      • Cudd_RecursiveDeref() +
                      • Cudd_IterDerefBdd() +
                      • Cudd_DelayedDerefBdd() +
                      • Cudd_RecursiveDerefZdd() +
                      • Cudd_Deref() +
                      • Cudd_CheckZeroRef() +
                      + Internal procedures included in this module: +
                        +
                      • cuddReclaim() +
                      • cuddReclaimZdd() +
                      • cuddClearDeathRow() +
                      • cuddShrinkDeathRow() +
                      • cuddIsInDeathRow() +
                      • cuddTimesInDeathRow() +
                      + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddRef.c,v 1.29 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Increases the reference count of a node, if it is not + saturated.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_RecursiveDeref Cudd_Deref] + +******************************************************************************/ +void +Cudd_Ref( + DdNode * n) +{ + + n = Cudd_Regular(n); + + cuddSatInc(n->ref); + +} /* end of Cudd_Ref */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of node n.] + + Description [Decreases the reference count of node n. If n dies, + recursively decreases the reference counts of its children. It is + used to dispose of a DD that is no longer needed.] + + SideEffects [None] + + SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDerefZdd] + +******************************************************************************/ +void +Cudd_RecursiveDeref( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + + unsigned int live = table->keys - table->dead; + if (live > table->peakLiveNodes) { + table->peakLiveNodes = live; + } + + N = Cudd_Regular(n); + + do { +#ifdef DD_DEBUG + assert(N->ref != 0); +#endif + + if (N->ref == 1) { + N->ref = 0; + table->dead++; +#ifdef DD_STATS + table->nodesDropped++; +#endif + if (cuddIsConstant(N)) { + table->constants.dead++; + N = stack[--SP]; + } else { + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } + } else { + cuddSatDec(N->ref); + N = stack[--SP]; + } + } while (SP != 0); + +} /* end of Cudd_RecursiveDeref */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of BDD node n.] + + Description [Decreases the reference count of node n. If n dies, + recursively decreases the reference counts of its children. It is + used to dispose of a BDD that is no longer needed. It is more + efficient than Cudd_RecursiveDeref, but it cannot be used on + ADDs. The greater efficiency comes from being able to assume that no + constant node will ever die as a result of a call to this + procedure.] + + SideEffects [None] + + SeeAlso [Cudd_RecursiveDeref Cudd_DelayedDerefBdd] + +******************************************************************************/ +void +Cudd_IterDerefBdd( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + + unsigned int live = table->keys - table->dead; + if (live > table->peakLiveNodes) { + table->peakLiveNodes = live; + } + + N = Cudd_Regular(n); + + do { +#ifdef DD_DEBUG + assert(N->ref != 0); +#endif + + if (N->ref == 1) { + N->ref = 0; + table->dead++; +#ifdef DD_STATS + table->nodesDropped++; +#endif + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } else { + cuddSatDec(N->ref); + N = stack[--SP]; + } + } while (SP != 0); + +} /* end of Cudd_IterDerefBdd */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of BDD node n.] + + Description [Enqueues node n for later dereferencing. If the queue + is full decreases the reference count of the oldest node N to make + room for n. If N dies, recursively decreases the reference counts of + its children. It is used to dispose of a BDD that is currently not + needed, but may be useful again in the near future. The dereferencing + proper is done as in Cudd_IterDerefBdd.] + + SideEffects [None] + + SeeAlso [Cudd_RecursiveDeref Cudd_IterDerefBdd] + +******************************************************************************/ +void +Cudd_DelayedDerefBdd( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack; + int SP; + + unsigned int live = table->keys - table->dead; + if (live > table->peakLiveNodes) { + table->peakLiveNodes = live; + } + + n = Cudd_Regular(n); +#ifdef DD_DEBUG + assert(n->ref != 0); +#endif + +#ifdef DD_NO_DEATH_ROW + N = n; +#else + if (cuddIsConstant(n) || n->ref > 1) { +#ifdef DD_DEBUG + assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table))); +#endif + cuddSatDec(n->ref); + return; + } + + N = table->deathRow[table->nextDead]; + + if (N != NULL) { +#endif +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(N)); +#endif + stack = table->stack; + SP = 1; + do { +#ifdef DD_DEBUG + assert(N->ref != 0); +#endif + if (N->ref == 1) { + N->ref = 0; + table->dead++; +#ifdef DD_STATS + table->nodesDropped++; +#endif + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } else { + cuddSatDec(N->ref); + N = stack[--SP]; + } + } while (SP != 0); +#ifndef DD_NO_DEATH_ROW + } + table->deathRow[table->nextDead] = n; + + /* Udate insertion point. */ + table->nextDead++; + table->nextDead &= table->deadMask; +#if 0 + if (table->nextDead == table->deathRowDepth) { + if (table->deathRowDepth < table->looseUpTo / 2) { + extern void (*MMoutOfMemory)(long); + void (*saveHandler)(long) = MMoutOfMemory; + DdNodePtr *newRow; + MMoutOfMemory = Cudd_OutOfMem; + newRow = REALLOC(DdNodePtr,table->deathRow,2*table->deathRowDepth); + MMoutOfMemory = saveHandler; + if (newRow == NULL) { + table->nextDead = 0; + } else { + int i; + table->memused += table->deathRowDepth; + i = table->deathRowDepth; + table->deathRowDepth <<= 1; + for (; i < table->deathRowDepth; i++) { + newRow[i] = NULL; + } + table->deadMask = table->deathRowDepth - 1; + table->deathRow = newRow; + } + } else { + table->nextDead = 0; + } + } +#endif +#endif + +} /* end of Cudd_DelayedDerefBdd */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of ZDD node n.] + + Description [Decreases the reference count of ZDD node n. If n dies, + recursively decreases the reference counts of its children. It is + used to dispose of a ZDD that is no longer needed.] + + SideEffects [None] + + SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDeref] + +******************************************************************************/ +void +Cudd_RecursiveDerefZdd( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + + N = n; + + do { +#ifdef DD_DEBUG + assert(N->ref != 0); +#endif + + cuddSatDec(N->ref); + + if (N->ref == 0) { + table->deadZ++; +#ifdef DD_STATS + table->nodesDropped++; +#endif +#ifdef DD_DEBUG + assert(!cuddIsConstant(N)); +#endif + ord = table->permZ[N->index]; + stack[SP++] = cuddE(N); + table->subtableZ[ord].dead++; + N = cuddT(N); + } else { + N = stack[--SP]; + } + } while (SP != 0); + +} /* end of Cudd_RecursiveDerefZdd */ + + +/**Function******************************************************************** + + Synopsis [Decreases the reference count of node.] + + Description [Decreases the reference count of node. It is primarily + used in recursive procedures to decrease the ref count of a result + node before returning it. This accomplishes the goal of removing the + protection applied by a previous Cudd_Ref.] + + SideEffects [None] + + SeeAlso [Cudd_RecursiveDeref Cudd_RecursiveDerefZdd Cudd_Ref] + +******************************************************************************/ +void +Cudd_Deref( + DdNode * node) +{ + node = Cudd_Regular(node); + cuddSatDec(node->ref); + +} /* end of Cudd_Deref */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for nodes with non-zero reference + counts.] + + Description [Checks the unique table for nodes with non-zero + reference counts. It is normally called before Cudd_Quit to make sure + that there are no memory leaks due to missing Cudd_RecursiveDeref's. + Takes into account that reference counts may saturate and that the + basic constants and the projection functions are referenced by the + manager. Returns the number of nodes with non-zero reference count. + (Except for the cases mentioned above.)] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_CheckZeroRef( + DdManager * manager) +{ + int size; + int i, j; + int remain; /* the expected number of remaining references to one */ + DdNodePtr *nodelist; + DdNode *node; + DdNode *sentinel = &(manager->sentinel); + DdSubtable *subtable; + int count = 0; + int index; + +#ifndef DD_NO_DEATH_ROW + cuddClearDeathRow(manager); +#endif + + /* First look at the BDD/ADD subtables. */ + remain = 1; /* reference from the manager */ + size = manager->size; + remain += 2 * size; /* reference from the BDD projection functions */ + + for (i = 0; i < size; i++) { + subtable = &(manager->subtables[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + while (node != sentinel) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + index = (int) node->index; + if (node != manager->vars[index]) { + count++; + } else { + if (node->ref != 1) { + count++; + } + } + } + node = node->next; + } + } + } + + /* Then look at the ZDD subtables. */ + size = manager->sizeZ; + if (size) /* references from ZDD universe */ + remain += 2; + + for (i = 0; i < size; i++) { + subtable = &(manager->subtableZ[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + while (node != NULL) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + index = (int) node->index; + if (node == manager->univ[manager->permZ[index]]) { + if (node->ref > 2) { + count++; + } + } else { + count++; + } + } + node = node->next; + } + } + } + + /* Now examine the constant table. Plusinfinity, minusinfinity, and + ** zero are referenced by the manager. One is referenced by the + ** manager, by the ZDD universe, and by all projection functions. + ** All other nodes should have no references. + */ + nodelist = manager->constants.nodelist; + for (j = 0; (unsigned) j < manager->constants.slots; j++) { + node = nodelist[j]; + while (node != NULL) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + if (node == manager->one) { + if ((int) node->ref != remain) { + count++; + } + } else if (node == manager->zero || + node == manager->plusinfinity || + node == manager->minusinfinity) { + if (node->ref != 1) { + count++; + } + } else { + count++; + } + } + node = node->next; + } + } + return(count); + +} /* end of Cudd_CheckZeroRef */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Brings children of a dead node back.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddReclaimZdd] + +******************************************************************************/ +void +cuddReclaim( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + double initialDead = table->dead; + + N = Cudd_Regular(n); + +#ifdef DD_DEBUG + assert(N->ref == 0); +#endif + + do { + if (N->ref == 0) { + N->ref = 1; + table->dead--; + if (cuddIsConstant(N)) { + table->constants.dead--; + N = stack[--SP]; + } else { + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead--; + N = cuddT(N); + } + } else { + cuddSatInc(N->ref); + N = stack[--SP]; + } + } while (SP != 0); + + N = Cudd_Regular(n); + cuddSatDec(N->ref); + table->reclaimed += initialDead - table->dead; + +} /* end of cuddReclaim */ + + +/**Function******************************************************************** + + Synopsis [Brings children of a dead ZDD node back.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddReclaim] + +******************************************************************************/ +void +cuddReclaimZdd( + DdManager * table, + DdNode * n) +{ + DdNode *N; + int ord; + DdNodePtr *stack = table->stack; + int SP = 1; + + N = n; + +#ifdef DD_DEBUG + assert(N->ref == 0); +#endif + + do { + cuddSatInc(N->ref); + + if (N->ref == 1) { + table->deadZ--; + table->reclaimed++; +#ifdef DD_DEBUG + assert(!cuddIsConstant(N)); +#endif + ord = table->permZ[N->index]; + stack[SP++] = cuddE(N); + table->subtableZ[ord].dead--; + N = cuddT(N); + } else { + N = stack[--SP]; + } + } while (SP != 0); + + cuddSatDec(n->ref); + +} /* end of cuddReclaimZdd */ + + +/**Function******************************************************************** + + Synopsis [Shrinks the death row.] + + Description [Shrinks the death row by a factor of four.] + + SideEffects [None] + + SeeAlso [cuddClearDeathRow] + +******************************************************************************/ +void +cuddShrinkDeathRow( + DdManager *table) +{ +#ifndef DD_NO_DEATH_ROW + int i; + + if (table->deathRowDepth > 3) { + for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) { + if (table->deathRow[i] == NULL) break; + Cudd_IterDerefBdd(table,table->deathRow[i]); + table->deathRow[i] = NULL; + } + table->deathRowDepth /= 4; + table->deadMask = table->deathRowDepth - 1; + if ((unsigned) table->nextDead > table->deadMask) { + table->nextDead = 0; + } + table->deathRow = REALLOC(DdNodePtr, table->deathRow, + table->deathRowDepth); + } +#endif + +} /* end of cuddShrinkDeathRow */ + + +/**Function******************************************************************** + + Synopsis [Clears the death row.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_DelayedDerefBdd Cudd_IterDerefBdd Cudd_CheckZeroRef + cuddGarbageCollect] + +******************************************************************************/ +void +cuddClearDeathRow( + DdManager *table) +{ +#ifndef DD_NO_DEATH_ROW + int i; + + for (i = 0; i < table->deathRowDepth; i++) { + if (table->deathRow[i] == NULL) break; + Cudd_IterDerefBdd(table,table->deathRow[i]); + table->deathRow[i] = NULL; + } +#ifdef DD_DEBUG + for (; i < table->deathRowDepth; i++) { + assert(table->deathRow[i] == NULL); + } +#endif + table->nextDead = 0; +#endif + +} /* end of cuddClearDeathRow */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a node is in the death row.] + + Description [Checks whether a node is in the death row. Returns the + position of the first occurrence if the node is present; -1 + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_DelayedDerefBdd cuddClearDeathRow] + +******************************************************************************/ +int +cuddIsInDeathRow( + DdManager *dd, + DdNode *f) +{ +#ifndef DD_NO_DEATH_ROW + int i; + + for (i = 0; i < dd->deathRowDepth; i++) { + if (f == dd->deathRow[i]) { + return(i); + } + } +#endif + + return(-1); + +} /* end of cuddIsInDeathRow */ + + +/**Function******************************************************************** + + Synopsis [Counts how many times a node is in the death row.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_DelayedDerefBdd cuddClearDeathRow cuddIsInDeathRow] + +******************************************************************************/ +int +cuddTimesInDeathRow( + DdManager *dd, + DdNode *f) +{ + int count = 0; +#ifndef DD_NO_DEATH_ROW + int i; + + for (i = 0; i < dd->deathRowDepth; i++) { + count += f == dd->deathRow[i]; + } +#endif + + return(count); + +} /* end of cuddTimesInDeathRow */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddReorder.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddReorder.c new file mode 100644 index 000000000..11ce2f528 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddReorder.c @@ -0,0 +1,2137 @@ +/**CFile*********************************************************************** + + FileName [cuddReorder.c] + + PackageName [cudd] + + Synopsis [Functions for dynamic variable reordering.] + + Description [External procedures included in this file: +
                        +
                      • Cudd_ReduceHeap() +
                      • Cudd_ShuffleHeap() +
                      + Internal procedures included in this module: +
                        +
                      • cuddDynamicAllocNode() +
                      • cuddSifting() +
                      • cuddSwapping() +
                      • cuddNextHigh() +
                      • cuddNextLow() +
                      • cuddSwapInPlace() +
                      • cuddBddAlignToZdd() +
                      + Static procedures included in this module: +
                        +
                      • ddUniqueCompare() +
                      • ddSwapAny() +
                      • ddSiftingAux() +
                      • ddSiftingUp() +
                      • ddSiftingDown() +
                      • ddSiftingBackward() +
                      • ddReorderPreprocess() +
                      • ddReorderPostprocess() +
                      • ddShuffle() +
                      • ddSiftUp() +
                      • bddFixTree() +
                      ] + + Author [Shipra Panda, Bernard Plessier, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_MAX_SUBTABLE_SPARSITY 8 +#define DD_SHRINK_FACTOR 2 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddReorder.c,v 1.71 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int *entry; + +int ddTotalNumberSwapping; +#ifdef DD_STATS +int ddTotalNISwaps; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddUniqueCompare (int *ptrX, int *ptrY); +static Move * ddSwapAny (DdManager *table, int x, int y); +static int ddSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddSiftingUp (DdManager *table, int y, int xLow); +static Move * ddSiftingDown (DdManager *table, int x, int xHigh); +static int ddSiftingBackward (DdManager *table, int size, Move *moves); +static int ddReorderPreprocess (DdManager *table); +static int ddReorderPostprocess (DdManager *table); +static int ddShuffle (DdManager *table, int *permutation); +static int ddSiftUp (DdManager *table, int x, int xLow); +static void bddFixTree (DdManager *table, MtrNode *treenode); +static int ddUpdateMtrTree (DdManager *table, MtrNode *treenode, int *perm, int *invperm); +static int ddCheckPermuation (DdManager *table, MtrNode *treenode, int *perm, int *invperm); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Main dynamic reordering routine.] + + Description [Main dynamic reordering routine. + Calls one of the possible reordering procedures: +
                        +
                      • Swapping +
                      • Sifting +
                      • Symmetric Sifting +
                      • Group Sifting +
                      • Window Permutation +
                      • Simulated Annealing +
                      • Genetic Algorithm +
                      • Dynamic Programming (exact) +
                      + + For sifting, symmetric sifting, group sifting, and window + permutation it is possible to request reordering to convergence.

                      + + The core of all methods is the reordering procedure + cuddSwapInPlace() which swaps two adjacent variables and is based + on Rudell's paper. + Returns 1 in case of success; 0 otherwise. In the case of symmetric + sifting (with and without convergence) returns 1 plus the number of + symmetric variables, in case of success.] + + SideEffects [Changes the variable order for all diagrams and clears + the cache.] + +******************************************************************************/ +int +Cudd_ReduceHeap( + DdManager * table /* DD manager */, + Cudd_ReorderingType heuristic /* method used for reordering */, + int minsize /* bound below which no reordering occurs */) +{ + DdHook *hook; + int result; + unsigned int nextDyn; +#ifdef DD_STATS + unsigned int initialSize; + unsigned int finalSize; +#endif + unsigned long localTime; + + /* Don't reorder if there are too many dead nodes. */ + if (table->keys - table->dead < (unsigned) minsize) + return(1); + + if (heuristic == CUDD_REORDER_SAME) { + heuristic = table->autoMethod; + } + if (heuristic == CUDD_REORDER_NONE) { + return(1); + } + + /* This call to Cudd_ReduceHeap does initiate reordering. Therefore + ** we count it. + */ + table->reorderings++; + + localTime = util_cpu_time(); + + /* Run the hook functions. */ + hook = table->preReorderingHook; + while (hook != NULL) { + int res = (hook->f)(table, "BDD", (void *)heuristic); + if (res == 0) return(0); + hook = hook->next; + } + + if (!ddReorderPreprocess(table)) return(0); + ddTotalNumberSwapping = 0; + + if (table->keys > table->peakLiveNodes) { + table->peakLiveNodes = table->keys; + } +#ifdef DD_STATS + initialSize = table->keys - table->isolated; + ddTotalNISwaps = 0; + + switch(heuristic) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + (void) fprintf(table->out,"#:I_RANDOM "); + break; + case CUDD_REORDER_SIFT: + case CUDD_REORDER_SIFT_CONVERGE: + case CUDD_REORDER_SYMM_SIFT: + case CUDD_REORDER_SYMM_SIFT_CONV: + case CUDD_REORDER_GROUP_SIFT: + case CUDD_REORDER_GROUP_SIFT_CONV: + (void) fprintf(table->out,"#:I_SIFTING "); + break; + case CUDD_REORDER_WINDOW2: + case CUDD_REORDER_WINDOW3: + case CUDD_REORDER_WINDOW4: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + (void) fprintf(table->out,"#:I_WINDOW "); + break; + case CUDD_REORDER_ANNEALING: + (void) fprintf(table->out,"#:I_ANNEAL "); + break; + case CUDD_REORDER_GENETIC: + (void) fprintf(table->out,"#:I_GENETIC "); + break; + case CUDD_REORDER_LINEAR: + case CUDD_REORDER_LINEAR_CONVERGE: + (void) fprintf(table->out,"#:I_LINSIFT "); + break; + case CUDD_REORDER_EXACT: + (void) fprintf(table->out,"#:I_EXACT "); + break; + default: + return(0); + } + (void) fprintf(table->out,"%8d: initial size",initialSize); +#endif + + /* See if we should use alternate threshold for maximum growth. */ + if (table->reordCycle && table->reorderings % table->reordCycle == 0) { + double saveGrowth = table->maxGrowth; + table->maxGrowth = table->maxGrowthAlt; + result = cuddTreeSifting(table,heuristic); + table->maxGrowth = saveGrowth; + } else { + result = cuddTreeSifting(table,heuristic); + } + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + finalSize = table->keys - table->isolated; + (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n", + ((double)(util_cpu_time() - localTime)/1000.0)); + (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n", + ddTotalNumberSwapping); + (void) fprintf(table->out,"#:M_REORDER %8d: NI swaps\n",ddTotalNISwaps); +#endif + + if (result == 0) + return(0); + + if (!ddReorderPostprocess(table)) + return(0); + + if (table->realign) { + if (!cuddZddAlignToBdd(table)) + return(0); + } + + nextDyn = (table->keys - table->constants.keys + 1) * + DD_DYN_RATIO + table->constants.keys; + if (table->reorderings < 20 || nextDyn > table->nextDyn) + table->nextDyn = nextDyn; + else + table->nextDyn += 20; + if (table->randomizeOrder != 0) { + table->nextDyn += Cudd_Random() & table->randomizeOrder; + } + table->reordered = 1; + + /* Run hook functions. */ + hook = table->postReorderingHook; + while (hook != NULL) { + int res = (hook->f)(table, "BDD", (void *)localTime); + if (res == 0) return(0); + hook = hook->next; + } + /* Update cumulative reordering time. */ + table->reordTime += util_cpu_time() - localTime; + + return(result); + +} /* end of Cudd_ReduceHeap */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables according to given permutation.] + + Description [Reorders variables according to given permutation. + The i-th entry of the permutation array contains the index of the variable + that should be brought to the i-th level. The size of the array should be + equal or greater to the number of variables currently in use. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [Changes the variable order for all diagrams and clears + the cache.] + + SeeAlso [Cudd_ReduceHeap] + +******************************************************************************/ +int +Cudd_ShuffleHeap( + DdManager * table /* DD manager */, + int * permutation /* required variable permutation */) +{ + + int result; + int i; + int identity = 1; + int *perm; + + /* Don't waste time in case of identity permutation. */ + for (i = 0; i < table->size; i++) { + if (permutation[i] != table->invperm[i]) { + identity = 0; + break; + } + } + if (identity == 1) { + return(1); + } + if (!ddReorderPreprocess(table)) return(0); + if (table->keys > table->peakLiveNodes) { + table->peakLiveNodes = table->keys; + } + + perm = ALLOC(int, table->size); + for (i = 0; i < table->size; i++) + perm[permutation[i]] = i; + if (!ddCheckPermuation(table,table->tree,perm,permutation)) { + FREE(perm); + return(0); + } + if (!ddUpdateMtrTree(table,table->tree,perm,permutation)) { + FREE(perm); + return(0); + } + FREE(perm); + + result = ddShuffle(table,permutation); + + if (!ddReorderPostprocess(table)) return(0); + + return(result); + +} /* end of Cudd_ShuffleHeap */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Dynamically allocates a Node.] + + Description [Dynamically allocates a Node. This procedure is similar + to cuddAllocNode in Cudd_Table.c, but it does not attempt garbage + collection, because during reordering there are no dead nodes. + Returns a pointer to a new node if successful; NULL is memory is + full.] + + SideEffects [None] + + SeeAlso [cuddAllocNode] + +******************************************************************************/ +DdNode * +cuddDynamicAllocNode( + DdManager * table) +{ + int i; + DdNodePtr *mem; + DdNode *list, *node; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (table->nextFree == NULL) { /* free list is empty */ + /* Try to allocate a new block. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdNodePtr *) ALLOC(DdNode, DD_MEM_CHUNK + 1); + MMoutOfMemory = saveHandler; + if (mem == NULL && table->stash != NULL) { + FREE(table->stash); + table->stash = NULL; + /* Inhibit resizing of tables. */ + table->maxCacheHard = table->cacheSlots - 1; + table->cacheSlack = - (int) (table->cacheSlots + 1); + for (i = 0; i < table->size; i++) { + table->subtables[i].maxKeys <<= 2; + } + mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1); + } + if (mem == NULL) { + /* Out of luck. Call the default handler to do + ** whatever it specifies for a failed malloc. If this + ** handler returns, then set error code, print + ** warning, and return. */ + (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); + table->errorCode = CUDD_MEMORY_OUT; +#ifdef DD_VERBOSE + (void) fprintf(table->err, + "cuddDynamicAllocNode: out of memory"); + (void) fprintf(table->err,"Memory in use = %lu\n", + table->memused); +#endif + return(NULL); + } else { /* successful allocation; slice memory */ + unsigned long offset; + table->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); + mem[0] = (DdNode *) table->memoryList; + table->memoryList = mem; + + /* Here we rely on the fact that the size of a DdNode is a + ** power of 2 and a multiple of the size of a pointer. + ** If we align one node, all the others will be aligned + ** as well. */ + offset = (unsigned long) mem & (sizeof(DdNode) - 1); + mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); +#ifdef DD_DEBUG + assert(((unsigned long) mem & (sizeof(DdNode) - 1)) == 0); +#endif + list = (DdNode *) mem; + + i = 1; + do { + list[i - 1].ref = 0; + list[i - 1].next = &list[i]; + } while (++i < DD_MEM_CHUNK); + + list[DD_MEM_CHUNK-1].ref = 0; + list[DD_MEM_CHUNK - 1].next = NULL; + + table->nextFree = &list[0]; + } + } /* if free list empty */ + + node = table->nextFree; + table->nextFree = node->next; + return (node); + +} /* end of cuddDynamicAllocNode */ + + +/**Function******************************************************************** + + Synopsis [Implementation of Rudell's sifting algorithm.] + + Description [Implementation of Rudell's sifting algorithm. + Assumes that no dead nodes are present. +

                        +
                      1. Order all the variables according to the number of entries + in each unique table. +
                      2. Sift the variable up and down, remembering each time the + total size of the DD heap. +
                      3. Select the best permutation. +
                      4. Repeat 3 and 4 for all variables. +
                      + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; +#ifdef DD_STATS + int previousSize; +#endif + + size = table->size; + + /* Find order in which to sift variables. */ + var = NULL; + entry = ALLOC(int,size); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddSiftingOutOfMem; + } + var = ALLOC(int,size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; + } + + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime + table->reordTime + > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + x = table->perm[var[i]]; + + if (x < lower || x > upper || table->subtables[x].bindVar == 1) + continue; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSiftingAux(table, x, lower, upper); + if (!result) goto cuddSiftingOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->err,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + FREE(var); + FREE(entry); + + return(1); + +cuddSiftingOutOfMem: + + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddSifting */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables by a sequence of (non-adjacent) swaps.] + + Description [Implementation of Plessier's algorithm that reorders + variables by a sequence of (non-adjacent) swaps. +
                        +
                      1. Select two variables (RANDOM or HEURISTIC). +
                      2. Permute these variables. +
                      3. If the nodes have decreased accept the permutation. +
                      4. Otherwise reconstruct the original heap. +
                      5. Loop. +
                      + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddSwapping( + DdManager * table, + int lower, + int upper, + Cudd_ReorderingType heuristic) +{ + int i, j; + int max, keys; + int nvars; + int x, y; + int iterate; + int previousSize; + Move *moves, *move; + int pivot; + int modulo; + int result; + +#ifdef DD_DEBUG + /* Sanity check */ + assert(lower >= 0 && upper < table->size && lower <= upper); +#endif + + nvars = upper - lower + 1; + iterate = nvars; + + for (i = 0; i < iterate; i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { + max = -1; + for (j = lower; j <= upper; j++) { + if ((keys = table->subtables[j].keys) > max) { + max = keys; + pivot = j; + } + } + + modulo = upper - pivot; + if (modulo == 0) { + y = pivot; + } else{ + y = pivot + 1 + ((int) Cudd_Random() % modulo); + } + + modulo = pivot - lower - 1; + if (modulo < 1) { + x = lower; + } else{ + do { + x = (int) Cudd_Random() % modulo; + } while (x == y); + } + } else { + x = ((int) Cudd_Random() % nvars) + lower; + do { + y = ((int) Cudd_Random() % nvars) + lower; + } while (x == y); + } + previousSize = table->keys - table->isolated; + moves = ddSwapAny(table,x,y); + if (moves == NULL) goto cuddSwappingOutOfMem; + result = ddSiftingBackward(table,previousSize,moves); + if (!result) goto cuddSwappingOutOfMem; + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif +#if 0 + (void) fprintf(table->out,"#:t_SWAPPING %8d: tmp size\n", + table->keys - table->isolated); +#endif + } + + return(1); + +cuddSwappingOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(0); + +} /* end of cuddSwapping */ + + +/**Function******************************************************************** + + Synopsis [Finds the next subtable with a larger index.] + + Description [Finds the next subtable with a larger index. Returns the + index.] + + SideEffects [None] + + SeeAlso [cuddNextLow] + +******************************************************************************/ +int +cuddNextHigh( + DdManager * table, + int x) +{ + return(x+1); + +} /* end of cuddNextHigh */ + + +/**Function******************************************************************** + + Synopsis [Finds the next subtable with a smaller index.] + + Description [Finds the next subtable with a smaller index. Returns the + index.] + + SideEffects [None] + + SeeAlso [cuddNextHigh] + +******************************************************************************/ +int +cuddNextLow( + DdManager * table, + int x) +{ + return(x-1); + +} /* end of cuddNextLow */ + + +/**Function******************************************************************** + + Synopsis [Swaps two adjacent variables.] + + Description [Swaps two adjacent variables. It assumes that no dead + nodes are present on entry to this procedure. The procedure then + guarantees that no dead nodes will be present when it terminates. + cuddSwapInPlace assumes that x < y. Returns the number of keys in + the table if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddSwapInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int comple, newcomplement; + int i; + Cudd_VariableType varType; + Cudd_LazyGroupType groupType; + int posn; + int isolated; + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0; + DdNode *g,*next; + DdNodePtr *previousP; + DdNode *tmp; + DdNode *sentinel = &(table->sentinel); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + +#ifdef DD_DEBUG + int count,idcheck; +#endif + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddNextHigh(table,x) == y); + assert(table->subtables[x].keys != 0); + assert(table->subtables[y].keys != 0); + assert(table->subtables[x].dead == 0); + assert(table->subtables[y].dead == 0); +#endif + + ddTotalNumberSwapping++; + + /* Get parameters of x subtable. */ + xindex = table->invperm[x]; + xlist = table->subtables[x].nodelist; + oldxkeys = table->subtables[x].keys; + xslots = table->subtables[x].slots; + xshift = table->subtables[x].shift; + + /* Get parameters of y subtable. */ + yindex = table->invperm[y]; + ylist = table->subtables[y].nodelist; + oldykeys = table->subtables[y].keys; + yslots = table->subtables[y].slots; + yshift = table->subtables[y].shift; + + if (!cuddTestInteract(table,xindex,yindex)) { +#ifdef DD_STATS + ddTotalNISwaps++; +#endif + newxkeys = oldxkeys; + newykeys = oldykeys; + } else { + newxkeys = 0; + newykeys = oldykeys; + + /* Check whether the two projection functions involved in this + ** swap are isolated. At the end, we'll be able to tell how many + ** isolated projection functions are there by checking only these + ** two functions again. This is done to eliminate the isolated + ** projection functions from the node count. + */ + isolated = - ((table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1)); + + /* The nodes in the x layer that do not depend on + ** y will stay there; the others are put in a chain. + ** The chain is handled as a LIFO; g points to the beginning. + */ + g = NULL; + if ((oldxkeys >= xslots || (unsigned) xslots == table->initSlots) && + oldxkeys <= DD_MAX_SUBTABLE_DENSITY * xslots) { + for (i = 0; i < xslots; i++) { + previousP = &(xlist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if (f1->index != (DdHalfWord) yindex && + Cudd_Regular(f0)->index != (DdHalfWord) yindex) { + /* stays */ + newxkeys++; + *previousP = f; + previousP = &(f->next); + } else { + f->index = yindex; + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ + *previousP = sentinel; + } /* for each slot of the x subtable */ + } else { /* resize xlist */ + DdNode *h = NULL; + DdNodePtr *newxlist; + unsigned int newxslots; + int newxshift; + /* Empty current xlist. Nodes that stay go to list h; + ** nodes that move go to list g. */ + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if (f1->index != (DdHalfWord) yindex && + Cudd_Regular(f0)->index != (DdHalfWord) yindex) { + /* stays */ + f->next = h; + h = f; + newxkeys++; + } else { + f->index = yindex; + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ + } /* for each slot of the x subtable */ + /* Decide size of new subtable. */ + newxshift = xshift; + newxslots = xslots; + while ((unsigned) oldxkeys > DD_MAX_SUBTABLE_DENSITY * newxslots) { + newxshift--; + newxslots <<= 1; + } + while ((unsigned) oldxkeys < newxslots && + newxslots > table->initSlots) { + newxshift++; + newxslots >>= 1; + } + /* Try to allocate new table. Be ready to back off. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + newxlist = ALLOC(DdNodePtr, newxslots); + MMoutOfMemory = saveHandler; + if (newxlist == NULL) { + (void) fprintf(table->err, "Unable to resize subtable %d for lack of memory\n", i); + newxlist = xlist; + newxslots = xslots; + newxshift = xshift; + } else { + table->slots += ((int) newxslots - xslots); + table->minDead = (unsigned) + (table->gcFrac * (double) table->slots); + table->cacheSlack = (int) + ddMin(table->maxCacheHard, DD_MAX_CACHE_TO_SLOTS_RATIO + * table->slots) - 2 * (int) table->cacheSlots; + table->memused += + ((int) newxslots - xslots) * sizeof(DdNodePtr); + FREE(xlist); + xslots = newxslots; + xshift = newxshift; + xlist = newxlist; + } + /* Initialize new subtable. */ + for (i = 0; i < xslots; i++) { + xlist[i] = sentinel; + } + /* Move nodes that were parked in list h to their new home. */ + f = h; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); + f0 = cuddE(f); + /* Check xlist for pair (f11,f01). */ + posn = ddHash(f1, f0, xshift); + /* For each element tmp in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + tmp = *previousP; + while (f1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (f1 == cuddT(tmp) && f0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; + *previousP = f; + f = next; + } + } + +#ifdef DD_COUNT + table->swapSteps += oldxkeys - newxkeys; +#endif + /* Take care of the x nodes that must be re-expressed. + ** They form a linked list pointed by g. Their index has been + ** already changed to yindex. + */ + f = g; + while (f != NULL) { + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f1))); +#endif + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = f10 = f1; + } +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f11))); +#endif + f0 = cuddE(f); + comple = Cudd_IsComplement(f0); + f0 = Cudd_Regular(f0); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == f01) { + newf1 = f11; + cuddSatInc(newf1->ref); + } else { + /* Check xlist for triple (xindex,f11,f01). */ + posn = ddHash(f11, f01, xshift); + /* For each element newf1 in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + newf1 = *previousP; + while (f11 < cuddT(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + while (f11 == cuddT(newf1) && f01 < cuddE(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { + cuddSatInc(newf1->ref); + } else { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto cuddSwapOutOfMem; + newf1->index = xindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f01; + /* Insert newf1 in the collision list xlist[posn]; + ** increase the ref counts of f11 and f01. + */ + newxkeys++; + newf1->next = *previousP; + *previousP = newf1; + cuddSatInc(f11->ref); + tmp = Cudd_Regular(f01); + cuddSatInc(tmp->ref); + } + } + cuddT(f) = newf1; +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(newf1))); +#endif + + /* Do the same for f0, keeping complement dots into account. */ + /* Decrease ref count of f0. */ + tmp = Cudd_Regular(f0); + cuddSatDec(tmp->ref); + /* Create the new E child. */ + if (f10 == f00) { + newf0 = f00; + tmp = Cudd_Regular(newf0); + cuddSatInc(tmp->ref); + } else { + /* make sure f10 is regular */ + newcomplement = Cudd_IsComplement(f10); + if (newcomplement) { + f10 = Cudd_Not(f10); + f00 = Cudd_Not(f00); + } + /* Check xlist for triple (xindex,f10,f00). */ + posn = ddHash(f10, f00, xshift); + /* For each element newf0 in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + newf0 = *previousP; + while (f10 < cuddT(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + while (f10 == cuddT(newf0) && f00 < cuddE(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { + cuddSatInc(newf0->ref); + } else { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto cuddSwapOutOfMem; + newf0->index = xindex; newf0->ref = 1; + cuddT(newf0) = f10; + cuddE(newf0) = f00; + /* Insert newf0 in the collision list xlist[posn]; + ** increase the ref counts of f10 and f00. + */ + newxkeys++; + newf0->next = *previousP; + *previousP = newf0; + cuddSatInc(f10->ref); + tmp = Cudd_Regular(f00); + cuddSatInc(tmp->ref); + } + if (newcomplement) { + newf0 = Cudd_Not(newf0); + } + } + cuddE(f) = newf0; + + /* Insert the modified f in ylist. + ** The modified f does not already exists in ylist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, yshift); + newykeys++; + previousP = &(ylist[posn]); + tmp = *previousP; + while (newf1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; + *previousP = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previousP = &(ylist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + if (f->ref == 0) { + tmp = cuddT(f); + cuddSatDec(tmp->ref); + tmp = Cudd_Regular(cuddE(f)); + cuddSatDec(tmp->ref); + cuddDeallocNode(table,f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = sentinel; + } /* for i */ + +#ifdef DD_DEBUG +#if 0 + (void) fprintf(table->out,"Swapping %d and %d\n",x,y); +#endif + count = 0; + idcheck = 0; + for (i = 0; i < yslots; i++) { + f = ylist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) yindex) + idcheck++; + f = f->next; + } + } + if (count != newykeys) { + (void) fprintf(table->out, + "Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n", + oldykeys,newykeys,count); + } + if (idcheck != 0) + (void) fprintf(table->out, + "Error in id's of ylist\twrong id's = %d\n", + idcheck); + count = 0; + idcheck = 0; + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) xindex) + idcheck++; + f = f->next; + } + } + if (count != newxkeys) { + (void) fprintf(table->out, + "Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n", + oldxkeys,newxkeys,count); + } + if (idcheck != 0) + (void) fprintf(table->out, + "Error in id's of xlist\twrong id's = %d\n", + idcheck); +#endif + + isolated += (table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1); + table->isolated += isolated; + } + + /* Set the appropriate fields in table. */ + table->subtables[x].nodelist = ylist; + table->subtables[x].slots = yslots; + table->subtables[x].shift = yshift; + table->subtables[x].keys = newykeys; + table->subtables[x].maxKeys = yslots * DD_MAX_SUBTABLE_DENSITY; + i = table->subtables[x].bindVar; + table->subtables[x].bindVar = table->subtables[y].bindVar; + table->subtables[y].bindVar = i; + /* Adjust filds for lazy sifting. */ + varType = table->subtables[x].varType; + table->subtables[x].varType = table->subtables[y].varType; + table->subtables[y].varType = varType; + i = table->subtables[x].pairIndex; + table->subtables[x].pairIndex = table->subtables[y].pairIndex; + table->subtables[y].pairIndex = i; + i = table->subtables[x].varHandled; + table->subtables[x].varHandled = table->subtables[y].varHandled; + table->subtables[y].varHandled = i; + groupType = table->subtables[x].varToBeGrouped; + table->subtables[x].varToBeGrouped = table->subtables[y].varToBeGrouped; + table->subtables[y].varToBeGrouped = groupType; + + table->subtables[y].nodelist = xlist; + table->subtables[y].slots = xslots; + table->subtables[y].shift = xshift; + table->subtables[y].keys = newxkeys; + table->subtables[y].maxKeys = xslots * DD_MAX_SUBTABLE_DENSITY; + + table->perm[xindex] = y; table->perm[yindex] = x; + table->invperm[x] = yindex; table->invperm[y] = xindex; + + table->keys += newxkeys + newykeys - oldxkeys - oldykeys; + + return(table->keys - table->isolated); + +cuddSwapOutOfMem: + (void) fprintf(table->err,"Error: cuddSwapInPlace out of memory\n"); + + return (0); + +} /* end of cuddSwapInPlace */ + + +/**Function******************************************************************** + + Synopsis [Reorders BDD variables according to the order of the ZDD + variables.] + + Description [Reorders BDD variables according to the order of the + ZDD variables. This function can be called at the end of ZDD + reordering to insure that the order of the BDD variables is + consistent with the order of the ZDD variables. The number of ZDD + variables must be a multiple of the number of BDD variables. Let + M be the ratio of the two numbers. cuddBddAlignToZdd + then considers the ZDD variables from M*i to + (M+1)*i-1 as corresponding to BDD variable + i. This function should be normally called from + Cudd_zddReduceHeap, which clears the cache. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [Changes the BDD variable order for all diagrams and performs + garbage collection of the BDD unique table.] + + SeeAlso [Cudd_ShuffleHeap Cudd_zddReduceHeap] + +******************************************************************************/ +int +cuddBddAlignToZdd( + DdManager * table /* DD manager */) +{ + int *invperm; /* permutation array */ + int M; /* ratio of ZDD variables to BDD variables */ + int i; /* loop index */ + int result; /* return value */ + + /* We assume that a ratio of 0 is OK. */ + if (table->size == 0) + return(1); + + M = table->sizeZ / table->size; + /* Check whether the number of ZDD variables is a multiple of the + ** number of BDD variables. + */ + if (M * table->size != table->sizeZ) + return(0); + /* Create and initialize the inverse permutation array. */ + invperm = ALLOC(int,table->size); + if (invperm == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < table->sizeZ; i += M) { + int indexZ = table->invpermZ[i]; + int index = indexZ / M; + invperm[i / M] = index; + } + /* Eliminate dead nodes. Do not scan the cache again, because we + ** assume that Cudd_zddReduceHeap has already cleared it. + */ + cuddGarbageCollect(table,0); + + /* Initialize number of isolated projection functions. */ + table->isolated = 0; + for (i = 0; i < table->size; i++) { + if (table->vars[i]->ref == 1) table->isolated++; + } + + /* Initialize the interaction matrix. */ + result = cuddInitInteract(table); + if (result == 0) return(0); + + result = ddShuffle(table, invperm); + FREE(invperm); + /* Free interaction matrix. */ + FREE(table->interact); + /* Fix the BDD variable group tree. */ + bddFixTree(table,table->tree); + return(result); + +} /* end of cuddBddAlignToZdd */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + +******************************************************************************/ +static int +ddUniqueCompare( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of ddUniqueCompare */ + + +/**Function******************************************************************** + + Synopsis [Swaps any two variables.] + + Description [Swaps any two variables. Returns the set of moves.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSwapAny( + DdManager * table, + int x, + int y) +{ + Move *move, *moves; + int xRef,yRef; + int xNext,yNext; + int size; + int limitSize; + int tmp; + + if (x >y) { + tmp = x; x = y; y = tmp; + } + + xRef = x; yRef = y; + + xNext = cuddNextHigh(table,x); + yNext = cuddNextLow(table,y); + moves = NULL; + limitSize = table->keys - table->isolated; + + for (;;) { + if ( xNext == yNext) { + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,yNext,y); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = yNext; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + + } else if (x == yNext) { + + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + + } else { + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,yNext,y); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = yNext; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + x = xNext; + y = yNext; + } + + xNext = cuddNextHigh(table,x); + yNext = cuddNextLow(table,y); + if (xNext > yRef) break; + + if ((double) size > table->maxGrowth * (double) limitSize) break; + if (size < limitSize) limitSize = size; + } + if (yNext>=xRef) { + size = cuddSwapInPlace(table,yNext,y); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = yNext; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + } + + return(moves); + +ddSwapAnyOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of ddSwapAny */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; + + initialSize = table->keys - table->isolated; + + moveDown = NULL; + moveUp = NULL; + + if (x == xLow) { + moveDown = ddSiftingDown(table,x,xHigh); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddSiftingAuxOutOfMem; + + } else if (x == xHigh) { + moveUp = ddSiftingUp(table,x,xLow); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddSiftingAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + moveDown = ddSiftingDown(table,x,xHigh); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + if (moveDown != NULL) { + x = moveDown->y; + } + moveUp = ddSiftingUp(table,x,xLow); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position */ + result = ddSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddSiftingAuxOutOfMem; + + } else { /* must go up first: shorter */ + moveUp = ddSiftingUp(table,x,xLow); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + if (moveUp != NULL) { + x = moveUp->x; + } + moveDown = ddSiftingDown(table,x,xHigh); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddSiftingAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +ddSiftingAuxOutOfMem: + if (moveDown != (Move *) CUDD_OUT_OF_MEM) { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + } + if (moveUp != (Move *) CUDD_OUT_OF_MEM) { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + } + + return(0); + +} /* end of ddSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable up.] + + Description [Sifts a variable up. Moves y up until either it reaches + the bound (xLow) or the size of the DD heap increases too much. + Returns the set of moves in case of success; NULL if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSiftingUp( + DdManager * table, + int y, + int xLow) +{ + Move *moves; + Move *move; + int x; + int size; + int limitSize; + int xindex, yindex; + int isolated; + int L; /* lower bound on DD size */ +#ifdef DD_DEBUG + int checkL; + int z; + int zindex; +#endif + + moves = NULL; + yindex = table->invperm[y]; + + /* Initialize the lower bound. + ** The part of the DD below y will not change. + ** The part of the DD above y that does not interact with y will not + ** change. The rest may vanish in the best case, except for + ** the nodes at level xLow, which will not vanish, regardless. + */ + limitSize = L = table->keys - table->isolated; + for (x = xLow + 1; x < y; x++) { + xindex = table->invperm[x]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L -= table->subtables[x].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + L -= table->subtables[y].keys - isolated; + + x = cuddNextLow(table,y); + while (x >= xLow && L <= limitSize) { + xindex = table->invperm[x]; +#ifdef DD_DEBUG + checkL = table->keys - table->isolated; + for (z = xLow + 1; z < y; z++) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + checkL -= table->subtables[y].keys - isolated; + assert(L == checkL); +#endif + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddSiftingUpOutOfMem; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + y = x; + x = cuddNextLow(table,y); + } + return(moves); + +ddSiftingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable down.] + + Description [Sifts a variable down. Moves x down until either it + reaches the bound (xHigh) or the size of the DD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSiftingDown( + DdManager * table, + int x, + int xHigh) +{ + Move *moves; + Move *move; + int y; + int size; + int R; /* upper bound on node decrease */ + int limitSize; + int xindex, yindex; + int isolated; +#ifdef DD_DEBUG + int checkR; + int z; + int zindex; +#endif + + moves = NULL; + /* Initialize R */ + xindex = table->invperm[x]; + limitSize = size = table->keys - table->isolated; + R = 0; + for (y = xHigh; y > x; y--) { + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R += table->subtables[y].keys - isolated; + } + } + + y = cuddNextHigh(table,x); + while (y <= xHigh && size - R < limitSize) { +#ifdef DD_DEBUG + checkR = 0; + for (z = xHigh; z > x; z--) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + assert(R == checkR); +#endif + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddSiftingDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + x = y; + y = cuddNextHigh(table,x); + } + return(moves); + +ddSiftingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of ddSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the DD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSiftingBackward( + DdManager * table, + int size, + Move * moves) +{ + Move *move; + int res; + + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + + return(1); + +} /* end of ddSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Prepares the DD heap for dynamic reordering.] + + Description [Prepares the DD heap for dynamic reordering. Does + garbage collection, to guarantee that there are no dead nodes; + clears the cache, which is invalidated by dynamic reordering; initializes + the number of isolated projection functions; and initializes the + interaction matrix. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddReorderPreprocess( + DdManager * table) +{ + int i; + int res; + + /* Clear the cache. */ + cuddCacheFlush(table); + cuddLocalCacheClearAll(table); + + /* Eliminate dead nodes. Do not scan the cache again. */ + cuddGarbageCollect(table,0); + + /* Initialize number of isolated projection functions. */ + table->isolated = 0; + for (i = 0; i < table->size; i++) { + if (table->vars[i]->ref == 1) table->isolated++; + } + + /* Initialize the interaction matrix. */ + res = cuddInitInteract(table); + if (res == 0) return(0); + + return(1); + +} /* end of ddReorderPreprocess */ + + +/**Function******************************************************************** + + Synopsis [Cleans up at the end of reordering.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static int +ddReorderPostprocess( + DdManager * table) +{ + +#ifdef DD_VERBOSE + (void) fflush(table->out); +#endif + + /* Free interaction matrix. */ + FREE(table->interact); + + return(1); + +} /* end of ddReorderPostprocess */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables according to a given permutation.] + + Description [Reorders variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. ddShuffle assumes that no + dead nodes are present and that the interaction matrix is properly + initialized. The reordering is achieved by a series of upward sifts. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddShuffle( + DdManager * table, + int * permutation) +{ + int index; + int level; + int position; + int numvars; + int result; +#ifdef DD_STATS + unsigned long localTime; + int initialSize; + int finalSize; + int previousSize; +#endif + + ddTotalNumberSwapping = 0; +#ifdef DD_STATS + localTime = util_cpu_time(); + initialSize = table->keys - table->isolated; + (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n", + initialSize); + ddTotalNISwaps = 0; +#endif + + numvars = table->size; + + for (level = 0; level < numvars; level++) { + index = permutation[level]; + position = table->perm[index]; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSiftUp(table,position,level); + if (!result) return(0); +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + finalSize = table->keys - table->isolated; + (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:T_SHUFFLE %8g: total time (sec)\n", + ((double)(util_cpu_time() - localTime)/1000.0)); + (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n", + ddTotalNumberSwapping); + (void) fprintf(table->out,"#:M_SHUFFLE %8d: NI swaps\n",ddTotalNISwaps); +#endif + + return(1); + +} /* end of ddShuffle */ + + +/**Function******************************************************************** + + Synopsis [Moves one variable up.] + + Description [Takes a variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddSiftUp( + DdManager * table, + int x, + int xLow) +{ + int y; + int size; + + y = cuddNextLow(table,x); + while (y >= xLow) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); + } + return(1); + +} /* end of ddSiftUp */ + + +/**Function******************************************************************** + + Synopsis [Fixes the BDD variable group tree after a shuffle.] + + Description [Fixes the BDD variable group tree after a + shuffle. Assumes that the order of the variables in a terminal node + has not been changed.] + + SideEffects [Changes the BDD variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static void +bddFixTree( + DdManager * table, + MtrNode * treenode) +{ + if (treenode == NULL) return; + treenode->low = ((int) treenode->index < table->size) ? + table->perm[treenode->index] : treenode->index; + if (treenode->child != NULL) { + bddFixTree(table, treenode->child); + } + if (treenode->younger != NULL) + bddFixTree(table, treenode->younger); + if (treenode->parent != NULL && treenode->low < treenode->parent->low) { + treenode->parent->low = treenode->low; + treenode->parent->index = treenode->index; + } + return; + +} /* end of bddFixTree */ + + +/**Function******************************************************************** + + Synopsis [Updates the BDD variable group tree before a shuffle.] + + Description [Updates the BDD variable group tree before a shuffle. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Changes the BDD variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static int +ddUpdateMtrTree( + DdManager * table, + MtrNode * treenode, + int * perm, + int * invperm) +{ + unsigned int i, size; + int index, level, minLevel, maxLevel, minIndex; + + if (treenode == NULL) return(1); + + minLevel = CUDD_MAXINDEX; + maxLevel = 0; + minIndex = -1; + /* i : level */ + for (i = treenode->low; i < treenode->low + treenode->size; i++) { + index = table->invperm[i]; + level = perm[index]; + if (level < minLevel) { + minLevel = level; + minIndex = index; + } + if (level > maxLevel) + maxLevel = level; + } + size = maxLevel - minLevel + 1; + if (minIndex == -1) return(0); + if (size == treenode->size) { + treenode->low = minLevel; + treenode->index = minIndex; + } else { + return(0); + } + + if (treenode->child != NULL) { + if (!ddUpdateMtrTree(table, treenode->child, perm, invperm)) + return(0); + } + if (treenode->younger != NULL) { + if (!ddUpdateMtrTree(table, treenode->younger, perm, invperm)) + return(0); + } + return(1); +} + + +/**Function******************************************************************** + + Synopsis [Checks the BDD variable group tree before a shuffle.] + + Description [Checks the BDD variable group tree before a shuffle. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Changes the BDD variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static int +ddCheckPermuation( + DdManager * table, + MtrNode * treenode, + int * perm, + int * invperm) +{ + unsigned int i, size; + int index, level, minLevel, maxLevel; + + if (treenode == NULL) return(1); + + minLevel = table->size; + maxLevel = 0; + /* i : level */ + for (i = treenode->low; i < treenode->low + treenode->size; i++) { + index = table->invperm[i]; + level = perm[index]; + if (level < minLevel) + minLevel = level; + if (level > maxLevel) + maxLevel = level; + } + size = maxLevel - minLevel + 1; + if (size != treenode->size) + return(0); + + if (treenode->child != NULL) { + if (!ddCheckPermuation(table, treenode->child, perm, invperm)) + return(0); + } + if (treenode->younger != NULL) { + if (!ddCheckPermuation(table, treenode->younger, perm, invperm)) + return(0); + } + return(1); +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSat.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSat.c new file mode 100644 index 000000000..80d8c2bea --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSat.c @@ -0,0 +1,1774 @@ +/**CFile*********************************************************************** + + FileName [cuddSat.c] + + PackageName [cudd] + + Synopsis [Functions for the solution of satisfiability related problems.] + + Description [External procedures included in this file: +
                        +
                      • Cudd_Eval() +
                      • Cudd_ShortestPath() +
                      • Cudd_LargestCube() +
                      • Cudd_ShortestLength() +
                      • Cudd_Decreasing() +
                      • Cudd_Increasing() +
                      • Cudd_EquivDC() +
                      • Cudd_bddLeqUnless() +
                      • Cudd_EqualSupNorm() +
                      • Cudd_bddMakePrime() +
                      • Cudd_bddMaximallyExpand() +
                      • Cudd_bddLargestPrimeUnate() +
                      + Internal procedures included in this module: +
                        +
                      • cuddBddMakePrime() +
                      + Static procedures included in this module: +
                        +
                      • freePathPair() +
                      • getShortest() +
                      • getPath() +
                      • getLargest() +
                      • getCube() +
                      • ddBddMaximallyExpand() +
                      • ddShortestPathUnate() +
                      ] + + Author [Seh-Woong Jeong, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_BIGGY 100000000 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct cuddPathPair { + int pos; + int neg; +} cuddPathPair; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSat.c,v 1.39 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static DdNode *one, *zero; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define WEIGHT(weight, col) ((weight) == NULL ? 1 : weight[col]) + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static enum st_retval freePathPair (char *key, char *value, char *arg); +static cuddPathPair getShortest (DdNode *root, int *cost, int *support, st_table *visited); +static DdNode * getPath (DdManager *manager, st_table *visited, DdNode *f, int *weight, int cost); +static cuddPathPair getLargest (DdNode *root, st_table *visited); +static DdNode * getCube (DdManager *manager, st_table *visited, DdNode *f, int cost); +static DdNode * ddBddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f); +static int ddBddShortestPathUnate(DdManager *dd, DdNode *f, int *phases, st_table *table); +static DdNode * ddGetLargestCubeUnate(DdManager *dd, DdNode *f, int *phases, st_table *table); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns the value of a DD for a given variable assignment.] + + Description [Finds the value of a DD for a given variable + assignment. The variable assignment is passed in an array of int's, + that should specify a zero or a one for each variable in the support + of the function. Returns a pointer to a constant node. No new nodes + are produced.] + + SideEffects [None] + + SeeAlso [Cudd_bddLeq Cudd_addEvalConst] + +******************************************************************************/ +DdNode * +Cudd_Eval( + DdManager * dd, + DdNode * f, + int * inputs) +{ + int comple; + DdNode *ptr; + + comple = Cudd_IsComplement(f); + ptr = Cudd_Regular(f); + + while (!cuddIsConstant(ptr)) { + if (inputs[ptr->index] == 1) { + ptr = cuddT(ptr); + } else { + comple ^= Cudd_IsComplement(cuddE(ptr)); + ptr = Cudd_Regular(cuddE(ptr)); + } + } + return(Cudd_NotCond(ptr,comple)); + +} /* end of Cudd_Eval */ + + +/**Function******************************************************************** + + Synopsis [Finds a shortest path in a DD.] + + Description [Finds a shortest path in a DD. f is the DD we want to + get the shortest path for; weight\[i\] is the weight of the THEN arc + coming from the node whose index is i. If weight is NULL, then unit + weights are assumed for all THEN arcs. All ELSE arcs have 0 weight. + If non-NULL, both weight and support should point to arrays with at + least as many entries as there are variables in the manager. + Returns the shortest path as the BDD of a cube.] + + SideEffects [support contains on return the true support of f. + If support is NULL on entry, then Cudd_ShortestPath does not compute + the true support info. length contains the length of the path.] + + SeeAlso [Cudd_ShortestLength Cudd_LargestCube] + +******************************************************************************/ +DdNode * +Cudd_ShortestPath( + DdManager * manager, + DdNode * f, + int * weight, + int * support, + int * length) +{ + DdNode *F; + st_table *visited; + DdNode *sol; + cuddPathPair *rootPair; + int complement, cost; + int i; + + one = DD_ONE(manager); + zero = DD_ZERO(manager); + + /* Initialize support. Support does not depend on variable order. + ** Hence, it does not need to be reinitialized if reordering occurs. + */ + if (support) { + for (i = 0; i < manager->size; i++) { + support[i] = 0; + } + } + + if (f == Cudd_Not(one) || f == zero) { + *length = DD_BIGGY; + return(Cudd_Not(one)); + } + /* From this point on, a path exists. */ + + do { + manager->reordered = 0; + + /* Initialize visited table. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + + /* Now get the length of the shortest path(s) from f to 1. */ + (void) getShortest(f, weight, support, visited); + + complement = Cudd_IsComplement(f); + + F = Cudd_Regular(f); + + if (!st_lookup(visited, F, &rootPair)) return(NULL); + + if (complement) { + cost = rootPair->neg; + } else { + cost = rootPair->pos; + } + + /* Recover an actual shortest path. */ + sol = getPath(manager,visited,f,weight,cost); + + st_foreach(visited, freePathPair, NULL); + st_free_table(visited); + + } while (manager->reordered == 1); + + *length = cost; + return(sol); + +} /* end of Cudd_ShortestPath */ + + +/**Function******************************************************************** + + Synopsis [Finds a largest cube in a DD.] + + Description [Finds a largest cube in a DD. f is the DD we want to + get the largest cube for. The problem is translated into the one of + finding a shortest path in f, when both THEN and ELSE arcs are assumed to + have unit length. This yields a largest cube in the disjoint cover + corresponding to the DD. Therefore, it is not necessarily the largest + implicant of f. Returns the largest cube as a BDD.] + + SideEffects [The number of literals of the cube is returned in the location + pointed by length if it is non-null.] + + SeeAlso [Cudd_ShortestPath] + +******************************************************************************/ +DdNode * +Cudd_LargestCube( + DdManager * manager, + DdNode * f, + int * length) +{ + register DdNode *F; + st_table *visited; + DdNode *sol; + cuddPathPair *rootPair; + int complement, cost; + + one = DD_ONE(manager); + zero = DD_ZERO(manager); + + if (f == Cudd_Not(one) || f == zero) { + if (length != NULL) { + *length = DD_BIGGY; + } + return(Cudd_Not(one)); + } + /* From this point on, a path exists. */ + + do { + manager->reordered = 0; + + /* Initialize visited table. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + + /* Now get the length of the shortest path(s) from f to 1. */ + (void) getLargest(f, visited); + + complement = Cudd_IsComplement(f); + + F = Cudd_Regular(f); + + if (!st_lookup(visited, F, &rootPair)) return(NULL); + + if (complement) { + cost = rootPair->neg; + } else { + cost = rootPair->pos; + } + + /* Recover an actual shortest path. */ + sol = getCube(manager,visited,f,cost); + + st_foreach(visited, freePathPair, NULL); + st_free_table(visited); + + } while (manager->reordered == 1); + + if (length != NULL) { + *length = cost; + } + return(sol); + +} /* end of Cudd_LargestCube */ + + +/**Function******************************************************************** + + Synopsis [Find the length of the shortest path(s) in a DD.] + + Description [Find the length of the shortest path(s) in a DD. f is + the DD we want to get the shortest path for; weight\[i\] is the + weight of the THEN edge coming from the node whose index is i. All + ELSE edges have 0 weight. Returns the length of the shortest + path(s) if such a path is found; a large number if the function is + identically 0, and CUDD_OUT_OF_MEM in case of failure.] + + SideEffects [None] + + SeeAlso [Cudd_ShortestPath] + +******************************************************************************/ +int +Cudd_ShortestLength( + DdManager * manager, + DdNode * f, + int * weight) +{ + register DdNode *F; + st_table *visited; + cuddPathPair *my_pair; + int complement, cost; + + one = DD_ONE(manager); + zero = DD_ZERO(manager); + + if (f == Cudd_Not(one) || f == zero) { + return(DD_BIGGY); + } + + /* From this point on, a path exists. */ + /* Initialize visited table and support. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + + /* Now get the length of the shortest path(s) from f to 1. */ + (void) getShortest(f, weight, NULL, visited); + + complement = Cudd_IsComplement(f); + + F = Cudd_Regular(f); + + if (!st_lookup(visited, F, &my_pair)) return(CUDD_OUT_OF_MEM); + + if (complement) { + cost = my_pair->neg; + } else { + cost = my_pair->pos; + } + + st_foreach(visited, freePathPair, NULL); + st_free_table(visited); + + return(cost); + +} /* end of Cudd_ShortestLength */ + + +/**Function******************************************************************** + + Synopsis [Determines whether a BDD is negative unate in a + variable.] + + Description [Determines whether the function represented by BDD f is + negative unate (monotonic decreasing) in variable i. Returns the + constant one is f is unate and the (logical) constant zero if it is not. + This function does not generate any new nodes.] + + SideEffects [None] + + SeeAlso [Cudd_Increasing] + +******************************************************************************/ +DdNode * +Cudd_Decreasing( + DdManager * dd, + DdNode * f, + int i) +{ + unsigned int topf, level; + DdNode *F, *fv, *fvn, *res; + DD_CTFP cacheOp; + + statLine(dd); +#ifdef DD_DEBUG + assert(0 <= i && i < dd->size); +#endif + + F = Cudd_Regular(f); + topf = cuddI(dd,F->index); + + /* Check terminal case. If topf > i, f does not depend on var. + ** Therefore, f is unate in i. + */ + level = (unsigned) dd->perm[i]; + if (topf > level) { + return(DD_ONE(dd)); + } + + /* From now on, f is not constant. */ + + /* Check cache. */ + cacheOp = (DD_CTFP) Cudd_Decreasing; + res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]); + if (res != NULL) { + return(res); + } + + /* Compute cofactors. */ + fv = cuddT(F); fvn = cuddE(F); + if (F != f) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + + if (topf == (unsigned) level) { + /* Special case: if fv is regular, fv(1,...,1) = 1; + ** If in addition fvn is complemented, fvn(1,...,1) = 0. + ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not + ** monotonic decreasing in i. + */ + if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) { + return(Cudd_Not(DD_ONE(dd))); + } + res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd)); + } else { + res = Cudd_Decreasing(dd,fv,i); + if (res == DD_ONE(dd)) { + res = Cudd_Decreasing(dd,fvn,i); + } + } + + cuddCacheInsert2(dd,cacheOp,f,dd->vars[i],res); + return(res); + +} /* end of Cudd_Decreasing */ + + +/**Function******************************************************************** + + Synopsis [Determines whether a BDD is positive unate in a + variable.] + + Description [Determines whether the function represented by BDD f is + positive unate (monotonic increasing) in variable i. It is based on + Cudd_Decreasing and the fact that f is monotonic increasing in i if + and only if its complement is monotonic decreasing in i.] + + SideEffects [None] + + SeeAlso [Cudd_Decreasing] + +******************************************************************************/ +DdNode * +Cudd_Increasing( + DdManager * dd, + DdNode * f, + int i) +{ + return(Cudd_Decreasing(dd,Cudd_Not(f),i)); + +} /* end of Cudd_Increasing */ + + +/**Function******************************************************************** + + Synopsis [Tells whether F and G are identical wherever D is 0.] + + Description [Tells whether F and G are identical wherever D is 0. F + and G are either two ADDs or two BDDs. D is either a 0-1 ADD or a + BDD. The function returns 1 if F and G are equivalent, and 0 + otherwise. No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_bddLeqUnless] + +******************************************************************************/ +int +Cudd_EquivDC( + DdManager * dd, + DdNode * F, + DdNode * G, + DdNode * D) +{ + DdNode *tmp, *One, *Gr, *Dr; + DdNode *Fv, *Fvn, *Gv, *Gvn, *Dv, *Dvn; + int res; + unsigned int flevel, glevel, dlevel, top; + + One = DD_ONE(dd); + + statLine(dd); + /* Check terminal cases. */ + if (D == One || F == G) return(1); + if (D == Cudd_Not(One) || D == DD_ZERO(dd) || F == Cudd_Not(G)) return(0); + + /* From now on, D is non-constant. */ + + /* Normalize call to increase cache efficiency. */ + if (F > G) { + tmp = F; + F = G; + G = tmp; + } + if (Cudd_IsComplement(F)) { + F = Cudd_Not(F); + G = Cudd_Not(G); + } + + /* From now on, F is regular. */ + + /* Check cache. */ + tmp = cuddCacheLookup(dd,DD_EQUIV_DC_TAG,F,G,D); + if (tmp != NULL) return(tmp == One); + + /* Find splitting variable. */ + flevel = cuddI(dd,F->index); + Gr = Cudd_Regular(G); + glevel = cuddI(dd,Gr->index); + top = ddMin(flevel,glevel); + Dr = Cudd_Regular(D); + dlevel = dd->perm[Dr->index]; + top = ddMin(top,dlevel); + + /* Compute cofactors. */ + if (top == flevel) { + Fv = cuddT(F); + Fvn = cuddE(F); + } else { + Fv = Fvn = F; + } + if (top == glevel) { + Gv = cuddT(Gr); + Gvn = cuddE(Gr); + if (G != Gr) { + Gv = Cudd_Not(Gv); + Gvn = Cudd_Not(Gvn); + } + } else { + Gv = Gvn = G; + } + if (top == dlevel) { + Dv = cuddT(Dr); + Dvn = cuddE(Dr); + if (D != Dr) { + Dv = Cudd_Not(Dv); + Dvn = Cudd_Not(Dvn); + } + } else { + Dv = Dvn = D; + } + + /* Solve recursively. */ + res = Cudd_EquivDC(dd,Fv,Gv,Dv); + if (res != 0) { + res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn); + } + cuddCacheInsert(dd,DD_EQUIV_DC_TAG,F,G,D,(res) ? One : Cudd_Not(One)); + + return(res); + +} /* end of Cudd_EquivDC */ + + +/**Function******************************************************************** + + Synopsis [Tells whether f is less than of equal to G unless D is 1.] + + Description [Tells whether f is less than of equal to G unless D is + 1. f, g, and D are BDDs. The function returns 1 if f is less than + of equal to G, and 0 otherwise. No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_EquivDC Cudd_bddLeq Cudd_bddIteConstant] + +******************************************************************************/ +int +Cudd_bddLeqUnless( + DdManager *dd, + DdNode *f, + DdNode *g, + DdNode *D) +{ + DdNode *tmp, *One, *F, *G; + DdNode *Ft, *Fe, *Gt, *Ge, *Dt, *De; + int res; + unsigned int flevel, glevel, dlevel, top; + + statLine(dd); + + One = DD_ONE(dd); + + /* Check terminal cases. */ + if (f == g || g == One || f == Cudd_Not(One) || D == One || + D == f || D == Cudd_Not(g)) return(1); + /* Check for two-operand cases. */ + if (D == Cudd_Not(One) || D == g || D == Cudd_Not(f)) + return(Cudd_bddLeq(dd,f,g)); + if (g == Cudd_Not(One) || g == Cudd_Not(f)) return(Cudd_bddLeq(dd,f,D)); + if (f == One) return(Cudd_bddLeq(dd,Cudd_Not(g),D)); + + /* From now on, f, g, and D are non-constant, distinct, and + ** non-complementary. */ + + /* Normalize call to increase cache efficiency. We rely on the + ** fact that f <= g unless D is equivalent to not(g) <= not(f) + ** unless D and to f <= D unless g. We make sure that D is + ** regular, and that at most one of f and g is complemented. We also + ** ensure that when two operands can be swapped, the one with the + ** lowest address comes first. */ + + if (Cudd_IsComplement(D)) { + if (Cudd_IsComplement(g)) { + /* Special case: if f is regular and g is complemented, + ** f(1,...,1) = 1 > 0 = g(1,...,1). If D(1,...,1) = 0, return 0. + */ + if (!Cudd_IsComplement(f)) return(0); + /* !g <= D unless !f or !D <= g unless !f */ + tmp = D; + D = Cudd_Not(f); + if (g < tmp) { + f = Cudd_Not(g); + g = tmp; + } else { + f = Cudd_Not(tmp); + } + } else { + if (Cudd_IsComplement(f)) { + /* !D <= !f unless g or !D <= g unless !f */ + tmp = f; + f = Cudd_Not(D); + if (tmp < g) { + D = g; + g = Cudd_Not(tmp); + } else { + D = Cudd_Not(tmp); + } + } else { + /* f <= D unless g or !D <= !f unless g */ + tmp = D; + D = g; + if (tmp < f) { + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } else { + g = tmp; + } + } + } + } else { + if (Cudd_IsComplement(g)) { + if (Cudd_IsComplement(f)) { + /* !g <= !f unless D or !g <= D unless !f */ + tmp = f; + f = Cudd_Not(g); + if (D < tmp) { + g = D; + D = Cudd_Not(tmp); + } else { + g = Cudd_Not(tmp); + } + } else { + /* f <= g unless D or !g <= !f unless D */ + if (g < f) { + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } + } + } else { + /* f <= g unless D or f <= D unless g */ + if (D < g) { + tmp = D; + D = g; + g = tmp; + } + } + } + + /* From now on, D is regular. */ + + /* Check cache. */ + tmp = cuddCacheLookup(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D); + if (tmp != NULL) return(tmp == One); + + /* Find splitting variable. */ + F = Cudd_Regular(f); + flevel = dd->perm[F->index]; + G = Cudd_Regular(g); + glevel = dd->perm[G->index]; + top = ddMin(flevel,glevel); + dlevel = dd->perm[D->index]; + top = ddMin(top,dlevel); + + /* Compute cofactors. */ + if (top == flevel) { + Ft = cuddT(F); + Fe = cuddE(F); + if (F != f) { + Ft = Cudd_Not(Ft); + Fe = Cudd_Not(Fe); + } + } else { + Ft = Fe = f; + } + if (top == glevel) { + Gt = cuddT(G); + Ge = cuddE(G); + if (G != g) { + Gt = Cudd_Not(Gt); + Ge = Cudd_Not(Ge); + } + } else { + Gt = Ge = g; + } + if (top == dlevel) { + Dt = cuddT(D); + De = cuddE(D); + } else { + Dt = De = D; + } + + /* Solve recursively. */ + res = Cudd_bddLeqUnless(dd,Ft,Gt,Dt); + if (res != 0) { + res = Cudd_bddLeqUnless(dd,Fe,Ge,De); + } + cuddCacheInsert(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D,Cudd_NotCond(One,!res)); + + return(res); + +} /* end of Cudd_bddLeqUnless */ + + +/**Function******************************************************************** + + Synopsis [Compares two ADDs for equality within tolerance.] + + Description [Compares two ADDs for equality within tolerance. Two + ADDs are reported to be equal if the maximum difference between them + (the sup norm of their difference) is less than or equal to the + tolerance parameter. Returns 1 if the two ADDs are equal (within + tolerance); 0 otherwise. If parameter pr is positive + the first failure is reported to the standard output.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_EqualSupNorm( + DdManager * dd /* manager */, + DdNode * f /* first ADD */, + DdNode * g /* second ADD */, + CUDD_VALUE_TYPE tolerance /* maximum allowed difference */, + int pr /* verbosity level */) +{ + DdNode *fv, *fvn, *gv, *gvn, *r; + unsigned int topf, topg; + + statLine(dd); + /* Check terminal cases. */ + if (f == g) return(1); + if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) { + if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) { + return(1); + } else { + if (pr>0) { + (void) fprintf(dd->out,"Offending nodes:\n"); + (void) fprintf(dd->out, + "f: address = %p\t value = %40.30f\n", + (void *) f, cuddV(f)); + (void) fprintf(dd->out, + "g: address = %p\t value = %40.30f\n", + (void *) g, cuddV(g)); + } + return(0); + } + } + + /* We only insert the result in the cache if the comparison is + ** successful. Therefore, if we hit we return 1. */ + r = cuddCacheLookup2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g); + if (r != NULL) { + return(1); + } + + /* Compute the cofactors and solve the recursive subproblems. */ + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + + if (topf <= topg) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;} + if (topg <= topf) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;} + + if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0); + if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0); + + cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g,DD_ONE(dd)); + + return(1); + +} /* end of Cudd_EqualSupNorm */ + + +/**Function******************************************************************** + + Synopsis [Expands cube to a prime implicant of f.] + + Description [Expands cube to a prime implicant of f. Returns the prime + if successful; NULL otherwise. In particular, NULL is returned if cube + is not a real cube or is not an implicant of f.] + + SideEffects [None] + + SeeAlso [Cudd_bddMaximallyExpand] + +******************************************************************************/ +DdNode * +Cudd_bddMakePrime( + DdManager *dd /* manager */, + DdNode *cube /* cube to be expanded */, + DdNode *f /* function of which the cube is to be made a prime */) +{ + DdNode *res; + + if (!Cudd_bddLeq(dd,cube,f)) return(NULL); + + do { + dd->reordered = 0; + res = cuddBddMakePrime(dd,cube,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddMakePrime */ + + +/**Function******************************************************************** + + Synopsis [Expands lb to prime implicants of (f and ub).] + + Description [Expands lb to all prime implicants of (f and ub) that contain lb. + Assumes that lb is contained in ub. Returns the disjunction of the primes if + lb is contained in f; returns the zero BDD if lb is not contained in f; + returns NULL in case of failure. In particular, NULL is returned if cube is + not a real cube or is not an implicant of f. Returning the disjunction of + all prime implicants works because the resulting function is unate.] + + SideEffects [None] + + SeeAlso [Cudd_bddMakePrime] + +******************************************************************************/ +DdNode * +Cudd_bddMaximallyExpand( + DdManager *dd /* manager */, + DdNode *lb /* cube to be expanded */, + DdNode *ub /* upper bound cube */, + DdNode *f /* function against which to expand */) +{ + DdNode *res; + + if (!Cudd_bddLeq(dd,lb,ub)) return(NULL); + + do { + dd->reordered = 0; + res = ddBddMaximallyExpand(dd,lb,ub,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddMaximallyExpand */ + + +/**Function******************************************************************** + + Synopsis [Find a largest prime of a unate function.] + + Description [Find a largest prime implicant of a unate function. + Returns the BDD for the prime if succesful; NULL otherwise. The behavior + is undefined if f is not unate. The third argument is used to determine + whether f is unate positive (increasing) or negative (decreasing) + in each of the variables in its support.] + + SideEffects [None] + + SeeAlso [Cudd_bddMaximallyExpand] + +******************************************************************************/ +DdNode * +Cudd_bddLargestPrimeUnate( + DdManager *dd /* manager */, + DdNode *f /* unate function */, + DdNode *phaseBdd /* cube of the phases */) +{ + DdNode *res; + int *phases; + int retval; + st_table *table; + + /* Extract phase vector for quick access. */ + phases = ALLOC(int, dd->size); + if (phases == NULL) return(NULL); + retval = Cudd_BddToCubeArray(dd, phaseBdd, phases); + if (retval == 0) { + FREE(phases); + return(NULL); + } + do { + dd->reordered = 0; + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) { + FREE(phases); + return(NULL); + } + (void) ddBddShortestPathUnate(dd, f, phases, table); + res = ddGetLargestCubeUnate(dd, f, phases, table); + st_free_table(table); + } while (dd->reordered == 1); + + FREE(phases); + return(res); + +} /* end of Cudd_bddLargestPrimeUnate */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddMakePrime.] + + Description [Performs the recursive step of Cudd_bddMakePrime. + Returns the prime if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddBddMakePrime( + DdManager *dd /* manager */, + DdNode *cube /* cube to be expanded */, + DdNode *f /* function of which the cube is to be made a prime */) +{ + DdNode *scan; + DdNode *t, *e; + DdNode *res = cube; + DdNode *zero = Cudd_Not(DD_ONE(dd)); + + Cudd_Ref(res); + scan = cube; + while (!Cudd_IsConstant(scan)) { + DdNode *reg = Cudd_Regular(scan); + DdNode *var = dd->vars[reg->index]; + DdNode *expanded = Cudd_bddExistAbstract(dd,res,var); + if (expanded == NULL) { + Cudd_RecursiveDeref(dd,res); + return(NULL); + } + Cudd_Ref(expanded); + if (Cudd_bddLeq(dd,expanded,f)) { + Cudd_RecursiveDeref(dd,res); + res = expanded; + } else { + Cudd_RecursiveDeref(dd,expanded); + } + cuddGetBranches(scan,&t,&e); + if (t == zero) { + scan = e; + } else if (e == zero) { + scan = t; + } else { + Cudd_RecursiveDeref(dd,res); + return(NULL); /* cube is not a cube */ + } + } + + if (scan == DD_ONE(dd)) { + Cudd_Deref(res); + return(res); + } else { + Cudd_RecursiveDeref(dd,res); + return(NULL); + } + +} /* end of cuddBddMakePrime */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Frees the entries of the visited symbol table.] + + Description [Frees the entries of the visited symbol table. Returns + ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +freePathPair( + char * key, + char * value, + char * arg) +{ + cuddPathPair *pair; + + pair = (cuddPathPair *) value; + FREE(pair); + return(ST_CONTINUE); + +} /* end of freePathPair */ + + +/**Function******************************************************************** + + Synopsis [Finds the length of the shortest path(s) in a DD.] + + Description [Finds the length of the shortest path(s) in a DD. + Uses a local symbol table to store the lengths for each + node. Only the lengths for the regular nodes are entered in the table, + because those for the complement nodes are simply obtained by swapping + the two lenghts. + Returns a pair of lengths: the length of the shortest path to 1; + and the length of the shortest path to 0. This is done so as to take + complement arcs into account.] + + SideEffects [Accumulates the support of the DD in support.] + + SeeAlso [] + +******************************************************************************/ +static cuddPathPair +getShortest( + DdNode * root, + int * cost, + int * support, + st_table * visited) +{ + cuddPathPair *my_pair, res_pair, pair_T, pair_E; + DdNode *my_root, *T, *E; + int weight; + + my_root = Cudd_Regular(root); + + if (st_lookup(visited, my_root, &my_pair)) { + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); + } + + /* In the case of a BDD the following test is equivalent to + ** testing whether the BDD is the constant 1. This formulation, + ** however, works for ADDs as well, by assuming the usual + ** dichotomy of 0 and != 0. + */ + if (cuddIsConstant(my_root)) { + if (my_root != zero) { + res_pair.pos = 0; + res_pair.neg = DD_BIGGY; + } else { + res_pair.pos = DD_BIGGY; + res_pair.neg = 0; + } + } else { + T = cuddT(my_root); + E = cuddE(my_root); + + pair_T = getShortest(T, cost, support, visited); + pair_E = getShortest(E, cost, support, visited); + weight = WEIGHT(cost, my_root->index); + res_pair.pos = ddMin(pair_T.pos+weight, pair_E.pos); + res_pair.neg = ddMin(pair_T.neg+weight, pair_E.neg); + + /* Update support. */ + if (support != NULL) { + support[my_root->index] = 1; + } + } + + my_pair = ALLOC(cuddPathPair, 1); + if (my_pair == NULL) { + if (Cudd_IsComplement(root)) { + int tmp = res_pair.pos; + res_pair.pos = res_pair.neg; + res_pair.neg = tmp; + } + return(res_pair); + } + my_pair->pos = res_pair.pos; + my_pair->neg = res_pair.neg; + + st_insert(visited, (char *)my_root, (char *)my_pair); + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); + +} /* end of getShortest */ + + +/**Function******************************************************************** + + Synopsis [Build a BDD for a shortest path of f.] + + Description [Build a BDD for a shortest path of f. + Given the minimum length from the root, and the minimum + lengths for each node (in visited), apply triangulation at each node. + Of the two children of each node on a shortest path, at least one is + on a shortest path. In case of ties the procedure chooses the THEN + children. + Returns a pointer to the cube BDD representing the path if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +getPath( + DdManager * manager, + st_table * visited, + DdNode * f, + int * weight, + int cost) +{ + DdNode *sol, *tmp; + DdNode *my_dd, *T, *E; + cuddPathPair *T_pair, *E_pair; + int Tcost, Ecost; + int complement; + + my_dd = Cudd_Regular(f); + complement = Cudd_IsComplement(f); + + sol = one; + cuddRef(sol); + + while (!cuddIsConstant(my_dd)) { + Tcost = cost - WEIGHT(weight, my_dd->index); + Ecost = cost; + + T = cuddT(my_dd); + E = cuddE(my_dd); + + if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} + + st_lookup(visited, Cudd_Regular(T), &T_pair); + if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || + (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { + tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + + complement = Cudd_IsComplement(T); + my_dd = Cudd_Regular(T); + cost = Tcost; + continue; + } + st_lookup(visited, Cudd_Regular(E), &E_pair); + if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || + (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { + tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + complement = Cudd_IsComplement(E); + my_dd = Cudd_Regular(E); + cost = Ecost; + continue; + } + (void) fprintf(manager->err,"We shouldn't be here!!\n"); + manager->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + cuddDeref(sol); + return(sol); + +} /* end of getPath */ + + +/**Function******************************************************************** + + Synopsis [Finds the size of the largest cube(s) in a DD.] + + Description [Finds the size of the largest cube(s) in a DD. + This problem is translated into finding the shortest paths from a node + when both THEN and ELSE arcs have unit lengths. + Uses a local symbol table to store the lengths for each + node. Only the lengths for the regular nodes are entered in the table, + because those for the complement nodes are simply obtained by swapping + the two lenghts. + Returns a pair of lengths: the length of the shortest path to 1; + and the length of the shortest path to 0. This is done so as to take + complement arcs into account.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static cuddPathPair +getLargest( + DdNode * root, + st_table * visited) +{ + cuddPathPair *my_pair, res_pair, pair_T, pair_E; + DdNode *my_root, *T, *E; + + my_root = Cudd_Regular(root); + + if (st_lookup(visited, my_root, &my_pair)) { + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); + } + + /* In the case of a BDD the following test is equivalent to + ** testing whether the BDD is the constant 1. This formulation, + ** however, works for ADDs as well, by assuming the usual + ** dichotomy of 0 and != 0. + */ + if (cuddIsConstant(my_root)) { + if (my_root != zero) { + res_pair.pos = 0; + res_pair.neg = DD_BIGGY; + } else { + res_pair.pos = DD_BIGGY; + res_pair.neg = 0; + } + } else { + T = cuddT(my_root); + E = cuddE(my_root); + + pair_T = getLargest(T, visited); + pair_E = getLargest(E, visited); + res_pair.pos = ddMin(pair_T.pos, pair_E.pos) + 1; + res_pair.neg = ddMin(pair_T.neg, pair_E.neg) + 1; + } + + my_pair = ALLOC(cuddPathPair, 1); + if (my_pair == NULL) { /* simply do not cache this result */ + if (Cudd_IsComplement(root)) { + int tmp = res_pair.pos; + res_pair.pos = res_pair.neg; + res_pair.neg = tmp; + } + return(res_pair); + } + my_pair->pos = res_pair.pos; + my_pair->neg = res_pair.neg; + + /* Caching may fail without affecting correctness. */ + st_insert(visited, (char *)my_root, (char *)my_pair); + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); + +} /* end of getLargest */ + + +/**Function******************************************************************** + + Synopsis [Build a BDD for a largest cube of f.] + + Description [Build a BDD for a largest cube of f. + Given the minimum length from the root, and the minimum + lengths for each node (in visited), apply triangulation at each node. + Of the two children of each node on a shortest path, at least one is + on a shortest path. In case of ties the procedure chooses the THEN + children. + Returns a pointer to the cube BDD representing the path if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +getCube( + DdManager * manager, + st_table * visited, + DdNode * f, + int cost) +{ + DdNode *sol, *tmp; + DdNode *my_dd, *T, *E; + cuddPathPair *T_pair, *E_pair; + int Tcost, Ecost; + int complement; + + my_dd = Cudd_Regular(f); + complement = Cudd_IsComplement(f); + + sol = one; + cuddRef(sol); + + while (!cuddIsConstant(my_dd)) { + Tcost = cost - 1; + Ecost = cost - 1; + + T = cuddT(my_dd); + E = cuddE(my_dd); + + if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} + + if (!st_lookup(visited, Cudd_Regular(T), &T_pair)) return(NULL); + if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || + (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { + tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + + complement = Cudd_IsComplement(T); + my_dd = Cudd_Regular(T); + cost = Tcost; + continue; + } + if (!st_lookup(visited, Cudd_Regular(E), &E_pair)) return(NULL); + if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || + (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { + tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + complement = Cudd_IsComplement(E); + my_dd = Cudd_Regular(E); + cost = Ecost; + continue; + } + (void) fprintf(manager->err,"We shouldn't be here!\n"); + manager->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + cuddDeref(sol); + return(sol); + +} /* end of getCube */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddMaximallyExpand.] + + Description [Performs the recursive step of Cudd_bddMaximallyExpand. + Returns set of primes or zero BDD if successful; NULL otherwise. On entry + to this function, ub and lb should be different from the zero BDD. The + function then maintains this invariant.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +ddBddMaximallyExpand( + DdManager *dd /* manager */, + DdNode *lb /* cube to be expanded */, + DdNode *ub /* upper bound cube */, + DdNode *f /* function against which to expand */) +{ + DdNode *one, *zero, *lbv, *lbvn, *lbnx, *ubv, *ubvn, *fv, *fvn, *res; + DdNode *F, *UB, *LB, *t, *e; + unsigned int top, toplb, topub, topf, index; + + statLine(dd); + /* Terminal cases. */ + one = DD_ONE(dd); + zero = Cudd_Not(one); + assert(ub != zero && lb != zero); + /** There are three major terminal cases in theory: + ** ub -> f : return ub + ** lb == f : return lb + ** not(lb -> f): return zero + ** Only the second case can be checked exactly in constant time. + ** For the others, we check for sufficient conditions. + */ + if (ub == f || f == one) return(ub); + if (lb == f) return(lb); + if (f == zero || ub == Cudd_Not(f) || lb == one || lb == Cudd_Not(f)) + return(zero); + if (!Cudd_IsComplement(lb) && Cudd_IsComplement(f)) return(zero); + + /* Here lb and f are not constant. */ + + /* Check cache. Since lb and ub are cubes, their local reference counts + ** are always 1. Hence, we only check the reference count of f. + */ + F = Cudd_Regular(f); + if (F->ref != 1) { + DdNode *tmp = cuddCacheLookup(dd, DD_BDD_MAX_EXP_TAG, lb, ub, f); + if (tmp != NULL) { + return(tmp); + } + } + + /* Compute cofactors. For lb we use the non-zero one in + ** both branches of the recursion. + */ + LB = Cudd_Regular(lb); + UB = Cudd_Regular(ub); + topf = dd->perm[F->index]; + toplb = dd->perm[LB->index]; + topub = (ub == one) ? CUDD_CONST_INDEX : dd->perm[UB->index]; + assert(toplb <= topub); + top = ddMin(topf,toplb); + if (toplb == top) { + index = LB->index; + lbv = cuddT(LB); + lbvn = cuddE(LB); + if (lb != LB) { + lbv = Cudd_Not(lbv); + lbvn = Cudd_Not(lbvn); + } + if (lbv == zero) { + lbnx = lbvn; + } else { + lbnx = lbv; + } + } else { + index = F->index; + lbnx = lbv = lbvn = lb; + } + if (topub == top) { + ubv = cuddT(UB); + ubvn = cuddE(UB); + if (ub != UB) { + ubv = Cudd_Not(ubv); + ubvn = Cudd_Not(ubvn); + } + } else { + ubv = ubvn = ub; + } + if (topf == top) { + fv = cuddT(F); + fvn = cuddE(F); + if (f != F) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + } else { + fv = fvn = f; + } + + /* Recursive calls. */ + if (ubv != zero) { + t = ddBddMaximallyExpand(dd, lbnx, ubv, fv); + if (t == NULL) return(NULL); + } else { + assert(topub == toplb && topub == top && lbv == zero); + t = zero; + } + cuddRef(t); + + /* If the top variable appears only in lb, the positive and negative + ** cofactors of each operand are the same. We want to avoid a + ** needless recursive call, which would force us to give up the + ** cache optimization trick based on reference counts. + */ + if (ubv == ubvn && fv == fvn) { + res = t; + } else { + if (ubvn != zero) { + e = ddBddMaximallyExpand(dd, lbnx, ubvn, fvn); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } + } else { + assert(topub == toplb && topub == top && lbvn == zero); + e = zero; + } + + if (t == e) { + res = t; + } else { + cuddRef(e); + + if (toplb == top) { + if (lbv == zero) { + /* Top variable appears in negative phase. */ + if (t != one) { + DdNode *newT; + if (Cudd_IsComplement(t)) { + newT = cuddUniqueInter(dd, index, Cudd_Not(t), zero); + if (newT == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + newT = Cudd_Not(newT); + } else { + newT = cuddUniqueInter(dd, index, t, one); + if (newT == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + } + cuddRef(newT); + cuddDeref(t); + t = newT; + } + } else if (lbvn == zero) { + /* Top variable appears in positive phase. */ + if (e != one) { + DdNode *newE; + newE = cuddUniqueInter(dd, index, one, e); + if (newE == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + cuddRef(newE); + cuddDeref(e); + e = newE; + } + } else { + /* Not a cube. */ + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + } + + /* Combine results. */ + res = cuddBddAndRecur(dd, t, e); + if (res == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + } + } + + /* Cache result and return. */ + if (F->ref != 1) { + cuddCacheInsert(dd, DD_BDD_MAX_EXP_TAG, lb, ub, f, res); + } + cuddDeref(res); + return(res); + +} /* end of ddBddMaximallyExpand */ + + +/**Function******************************************************************** + + Synopsis [Performs shortest path computation on a unate function.] + + Description [Performs shortest path computation on a unate function. + Returns the length of the shortest path to one if successful; + CUDD_OUT_OF_MEM otherwise. This function is based on the observation + that in the BDD of a unate function no node except the constant is + reachable from the root via paths of different parity.] + + SideEffects [None] + + SeeAlso [getShortest] + +******************************************************************************/ +static int +ddBddShortestPathUnate( + DdManager *dd, + DdNode *f, + int *phases, + st_table *table) +{ + int positive, l, lT, lE; + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + DdNode *F, *fv, *fvn; + + if (st_lookup_int(table, f, &l)) { + return(l); + } + if (f == one) { + l = 0; + } else if (f == zero) { + l = DD_BIGGY; + } else { + F = Cudd_Regular(f); + fv = cuddT(F); + fvn = cuddE(F); + if (f != F) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + lT = ddBddShortestPathUnate(dd, fv, phases, table); + lE = ddBddShortestPathUnate(dd, fvn, phases, table); + positive = phases[F->index]; + l = positive ? ddMin(lT+1, lE) : ddMin(lT, lE+1); + } + if (st_insert(table, f, (void *)(ptrint) l) == ST_OUT_OF_MEM) { + return(CUDD_OUT_OF_MEM); + } + return(l); + +} /* end of ddShortestPathUnate */ + + +/**Function******************************************************************** + + Synopsis [Extracts largest prime of a unate function.] + + Description [Extracts largest prime of a unate function. Returns the BDD of + the prime if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [getPath] + +******************************************************************************/ +static DdNode * +ddGetLargestCubeUnate( + DdManager *dd, + DdNode *f, + int *phases, + st_table *table) +{ + DdNode *res, *scan; + DdNode *one = DD_ONE(dd); + int cost; + + res = one; + cuddRef(res); + scan = f; + st_lookup_int(table, scan, &cost); + + while (!Cudd_IsConstant(scan)) { + int Pcost, Ncost, Tcost; + DdNode *tmp, *T, *E; + DdNode *rscan = Cudd_Regular(scan); + int index = rscan->index; + //assert(phases[index] == 0 || phases[index] == 1); + int positive = phases[index] == 1; + Pcost = positive ? cost - 1 : cost; + Ncost = positive ? cost : cost - 1; + T = cuddT(rscan); + E = cuddE(rscan); + if (rscan != scan) { + T = Cudd_Not(T); + E = Cudd_Not(E); + } + tmp = res; + st_lookup_int(table, T, &Tcost); + if (Tcost == Pcost) { + cost = Pcost; + scan = T; + if (positive) { + tmp = cuddBddAndRecur(dd, dd->vars[index], res); + } + } else { + cost = Ncost; + scan = E; + if (!positive) { + tmp = cuddBddAndRecur(dd, Cudd_Not(dd->vars[index]), res); + } + } + if (tmp == NULL) { + Cudd_IterDerefBdd(dd, res); + return(NULL); + } + cuddRef(tmp); + Cudd_IterDerefBdd(dd, res); + res = tmp; + } + + cuddDeref(res); + return(res); + +} /* end of ddGetLargestCubeUnate */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSign.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSign.c new file mode 100644 index 000000000..60520697a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSign.c @@ -0,0 +1,318 @@ +/**CFile*********************************************************************** + + FileName [cuddSign.c] + + PackageName [cudd] + + Synopsis [Computation of signatures.] + + Description [External procedures included in this module: +
                        +
                      • Cudd_CofMinterm(); +
                      + Static procedures included in this module: +
                        +
                      • ddCofMintermAux() +
                      + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSign.c,v 1.24 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int size; + +#ifdef DD_STATS +static int num_calls; /* should equal 2n-1 (n is the # of nodes) */ +static int table_mem; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static double * ddCofMintermAux (DdManager *dd, DdNode *node, st_table *table); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Computes the fraction of minterms in the on-set of all the + positive cofactors of a BDD or ADD.] + + Description [Computes the fraction of minterms in the on-set of all + the positive cofactors of DD. Returns the pointer to an array of + doubles if successful; NULL otherwise. The array has as many + positions as there are BDD variables in the manager plus one. The + last position of the array contains the fraction of the minterms in + the ON-set of the function represented by the BDD or ADD. The other + positions of the array hold the variable signatures.] + + SideEffects [None] + +******************************************************************************/ +double * +Cudd_CofMinterm( + DdManager * dd, + DdNode * node) +{ + st_table *table; + double *values; + double *result = NULL; + int i, firstLevel; + +#ifdef DD_STATS + unsigned long startTime; + startTime = util_cpu_time(); + num_calls = 0; + table_mem = sizeof(st_table); +#endif + + table = st_init_table(st_ptrcmp, st_ptrhash); + if (table == NULL) { + (void) fprintf(dd->err, + "out-of-memory, couldn't measure DD cofactors.\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + size = dd->size; + values = ddCofMintermAux(dd, node, table); + if (values != NULL) { + result = ALLOC(double,size + 1); + if (result != NULL) { +#ifdef DD_STATS + table_mem += (size + 1) * sizeof(double); +#endif + if (Cudd_IsConstant(node)) + firstLevel = 1; + else + firstLevel = cuddI(dd,Cudd_Regular(node)->index); + for (i = 0; i < size; i++) { + if (i >= cuddI(dd,Cudd_Regular(node)->index)) { + result[dd->invperm[i]] = values[i - firstLevel]; + } else { + result[dd->invperm[i]] = values[size - firstLevel]; + } + } + result[size] = values[size - firstLevel]; + } else { + dd->errorCode = CUDD_MEMORY_OUT; + } + } + +#ifdef DD_STATS + table_mem += table->num_bins * sizeof(st_table_entry *); +#endif + if (Cudd_Regular(node)->ref == 1) FREE(values); + st_foreach(table, cuddStCountfree, NULL); + st_free_table(table); +#ifdef DD_STATS + (void) fprintf(dd->out,"Number of calls: %d\tTable memory: %d bytes\n", + num_calls, table_mem); + (void) fprintf(dd->out,"Time to compute measures: %s\n", + util_print_time(util_cpu_time() - startTime)); +#endif + if (result == NULL) { + (void) fprintf(dd->out, + "out-of-memory, couldn't measure DD cofactors.\n"); + dd->errorCode = CUDD_MEMORY_OUT; + } + return(result); + +} /* end of Cudd_CofMinterm */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Recursive Step for Cudd_CofMinterm function.] + + Description [Traverses the DD node and computes the fraction of + minterms in the on-set of all positive cofactors simultaneously. + It allocates an array with two more entries than there are + variables below the one labeling the node. One extra entry (the + first in the array) is for the variable labeling the node. The other + entry (the last one in the array) holds the fraction of minterms of + the function rooted at node. Each other entry holds the value for + one cofactor. The array is put in a symbol table, to avoid repeated + computation, and its address is returned by the procedure, for use + by the caller. Returns a pointer to the array of cofactor measures.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double * +ddCofMintermAux( + DdManager * dd, + DdNode * node, + st_table * table) +{ + DdNode *N; /* regular version of node */ + DdNode *Nv, *Nnv; + double *values; + double *valuesT, *valuesE; + int i; + int localSize, localSizeT, localSizeE; + double vT, vE; + + statLine(dd); +#ifdef DD_STATS + num_calls++; +#endif + + if (st_lookup(table, node, &values)) { + return(values); + } + + N = Cudd_Regular(node); + if (cuddIsConstant(N)) { + localSize = 1; + } else { + localSize = size - cuddI(dd,N->index) + 1; + } + values = ALLOC(double, localSize); + if (values == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + if (cuddIsConstant(N)) { + if (node == DD_ZERO(dd) || node == Cudd_Not(DD_ONE(dd))) { + values[0] = 0.0; + } else { + values[0] = 1.0; + } + } else { + Nv = Cudd_NotCond(cuddT(N),N!=node); + Nnv = Cudd_NotCond(cuddE(N),N!=node); + + valuesT = ddCofMintermAux(dd, Nv, table); + if (valuesT == NULL) return(NULL); + valuesE = ddCofMintermAux(dd, Nnv, table); + if (valuesE == NULL) return(NULL); + + if (Cudd_IsConstant(Nv)) { + localSizeT = 1; + } else { + localSizeT = size - cuddI(dd,Cudd_Regular(Nv)->index) + 1; + } + if (Cudd_IsConstant(Nnv)) { + localSizeE = 1; + } else { + localSizeE = size - cuddI(dd,Cudd_Regular(Nnv)->index) + 1; + } + values[0] = valuesT[localSizeT - 1]; + for (i = 1; i < localSize; i++) { + if (i >= cuddI(dd,Cudd_Regular(Nv)->index) - cuddI(dd,N->index)) { + vT = valuesT[i - cuddI(dd,Cudd_Regular(Nv)->index) + + cuddI(dd,N->index)]; + } else { + vT = valuesT[localSizeT - 1]; + } + if (i >= cuddI(dd,Cudd_Regular(Nnv)->index) - cuddI(dd,N->index)) { + vE = valuesE[i - cuddI(dd,Cudd_Regular(Nnv)->index) + + cuddI(dd,N->index)]; + } else { + vE = valuesE[localSizeE - 1]; + } + values[i] = (vT + vE) / 2.0; + } + if (Cudd_Regular(Nv)->ref == 1) FREE(valuesT); + if (Cudd_Regular(Nnv)->ref == 1) FREE(valuesE); + } + + if (N->ref > 1) { + if (st_add_direct(table, (char *) node, (char *) values) == ST_OUT_OF_MEM) { + FREE(values); + return(NULL); + } +#ifdef DD_STATS + table_mem += localSize * sizeof(double) + sizeof(st_table_entry); +#endif + } + return(values); + +} /* end of ddCofMintermAux */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSolve.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSolve.c new file mode 100644 index 000000000..e97779d8e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSolve.c @@ -0,0 +1,366 @@ +/**CFile*********************************************************************** + + FileName [cuddSolve.c] + + PackageName [cudd] + + Synopsis [Boolean equation solver and related functions.] + + Description [External functions included in this modoule: +
                        +
                      • Cudd_SolveEqn() +
                      • Cudd_VerifySol() +
                      + Internal functions included in this module: +
                        +
                      • cuddSolveEqnRecur() +
                      • cuddVerifySol() +
                      ] + + SeeAlso [] + + Author [Balakrishna Kumthekar] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSolve.c,v 1.13 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the solution of F(x,y) = 0.] + + Description [Implements the solution for F(x,y) = 0. The return + value is the consistency condition. The y variables are the unknowns + and the remaining variables are the parameters. Returns the + consistency condition if successful; NULL otherwise. Cudd_SolveEqn + allocates an array and fills it with the indices of the + unknowns. This array is used by Cudd_VerifySol.] + + SideEffects [The solution is returned in G; the indices of the y + variables are returned in yIndex.] + + SeeAlso [Cudd_VerifySol] + +******************************************************************************/ +DdNode * +Cudd_SolveEqn( + DdManager * bdd, + DdNode * F /* the left-hand side of the equation */, + DdNode * Y /* the cube of the y variables */, + DdNode ** G /* the array of solutions (return parameter) */, + int ** yIndex /* index of y variables */, + int n /* numbers of unknowns */) +{ + DdNode *res; + int *temp; + + *yIndex = temp = ALLOC(int, n); + if (temp == NULL) { + bdd->errorCode = CUDD_MEMORY_OUT; + (void) fprintf(bdd->out, + "Cudd_SolveEqn: Out of memory for yIndex\n"); + return(NULL); + } + + do { + bdd->reordered = 0; + res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0); + } while (bdd->reordered == 1); + + return(res); + +} /* end of Cudd_SolveEqn */ + + +/**Function******************************************************************** + + Synopsis [Checks the solution of F(x,y) = 0.] + + Description [Checks the solution of F(x,y) = 0. This procedure + substitutes the solution components for the unknowns of F and returns + the resulting BDD for F.] + + SideEffects [Frees the memory pointed by yIndex.] + + SeeAlso [Cudd_SolveEqn] + +******************************************************************************/ +DdNode * +Cudd_VerifySol( + DdManager * bdd, + DdNode * F /* the left-hand side of the equation */, + DdNode ** G /* the array of solutions */, + int * yIndex /* index of y variables */, + int n /* numbers of unknowns */) +{ + DdNode *res; + + do { + bdd->reordered = 0; + res = cuddVerifySol(bdd, F, G, yIndex, n); + } while (bdd->reordered == 1); + + FREE(yIndex); + + return(res); + +} /* end of Cudd_VerifySol */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_SolveEqn.] + + Description [Implements the recursive step of Cudd_SolveEqn. + Returns NULL if the intermediate solution blows up + or reordering occurs. The parametric solutions are + stored in the array G.] + + SideEffects [none] + + SeeAlso [Cudd_SolveEqn, Cudd_VerifySol] + +******************************************************************************/ +DdNode * +cuddSolveEqnRecur( + DdManager * bdd, + DdNode * F /* the left-hand side of the equation */, + DdNode * Y /* the cube of remaining y variables */, + DdNode ** G /* the array of solutions */, + int n /* number of unknowns */, + int * yIndex /* array holding the y variable indices */, + int i /* level of recursion */) +{ + DdNode *Fn, *Fm1, *Fv, *Fvbar, *T, *w, *nextY, *one; + DdNodePtr *variables; + + int j; + + statLine(bdd); + variables = bdd->vars; + one = DD_ONE(bdd); + + /* Base condition. */ + if (Y == one) { + return F; + } + + /* Cofactor of Y. */ + yIndex[i] = Y->index; + nextY = Cudd_T(Y); + + /* Universal abstraction of F with respect to the top variable index. */ + Fm1 = cuddBddExistAbstractRecur(bdd, Cudd_Not(F), variables[yIndex[i]]); + if (Fm1) { + Fm1 = Cudd_Not(Fm1); + cuddRef(Fm1); + } else { + return(NULL); + } + + Fn = cuddSolveEqnRecur(bdd, Fm1, nextY, G, n, yIndex, i+1); + if (Fn) { + cuddRef(Fn); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + return(NULL); + } + + Fv = cuddCofactorRecur(bdd, F, variables[yIndex[i]]); + if (Fv) { + cuddRef(Fv); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + return(NULL); + } + + Fvbar = cuddCofactorRecur(bdd, F, Cudd_Not(variables[yIndex[i]])); + if (Fvbar) { + cuddRef(Fvbar); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + return(NULL); + } + + /* Build i-th component of the solution. */ + w = cuddBddIteRecur(bdd, variables[yIndex[i]], Cudd_Not(Fv), Fvbar); + if (w) { + cuddRef(w); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + Cudd_RecursiveDeref(bdd, Fvbar); + return(NULL); + } + + T = cuddBddRestrictRecur(bdd, w, Cudd_Not(Fm1)); + if(T) { + cuddRef(T); + } else { + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + Cudd_RecursiveDeref(bdd, Fvbar); + Cudd_RecursiveDeref(bdd, w); + return(NULL); + } + + Cudd_RecursiveDeref(bdd,Fm1); + Cudd_RecursiveDeref(bdd,w); + Cudd_RecursiveDeref(bdd,Fv); + Cudd_RecursiveDeref(bdd,Fvbar); + + /* Substitute components of solution already found into solution. */ + for (j = n-1; j > i; j--) { + w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]); + if(w) { + cuddRef(w); + } else { + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, T); + return(NULL); + } + Cudd_RecursiveDeref(bdd,T); + T = w; + } + G[i] = T; + + Cudd_Deref(Fn); + + return(Fn); + +} /* end of cuddSolveEqnRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_VerifySol. ] + + Description [] + + SideEffects [none] + + SeeAlso [Cudd_VerifySol] + +******************************************************************************/ +DdNode * +cuddVerifySol( + DdManager * bdd, + DdNode * F /* the left-hand side of the equation */, + DdNode ** G /* the array of solutions */, + int * yIndex /* array holding the y variable indices */, + int n /* number of unknowns */) +{ + DdNode *w, *R; + + int j; + + R = F; + cuddRef(R); + for(j = n - 1; j >= 0; j--) { + w = Cudd_bddCompose(bdd, R, G[j], yIndex[j]); + if (w) { + cuddRef(w); + } else { + return(NULL); + } + Cudd_RecursiveDeref(bdd,R); + R = w; + } + + cuddDeref(R); + + return(R); + +} /* end of cuddVerifySol */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSplit.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSplit.c new file mode 100644 index 000000000..11fe86267 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSplit.c @@ -0,0 +1,686 @@ +/**CFile*********************************************************************** + + FileName [cuddSplit.c] + + PackageName [cudd] + + Synopsis [Returns a subset of minterms from a boolean function.] + + Description [External functions included in this modoule: +
                        +
                      • Cudd_SplitSet() +
                      + Internal functions included in this module: +
                        +
                      • cuddSplitSetRecur() + + Static functions included in this module: +
                          +
                        • selectMintermsFromUniverse() +
                        • mintermsFromUniverse() +
                        • bddAnnotateMintermCount() +
                        ] + + SeeAlso [] + + Author [Balakrishna Kumthekar] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * selectMintermsFromUniverse (DdManager *manager, int *varSeen, double n); +static DdNode * mintermsFromUniverse (DdManager *manager, DdNode **vars, int numVars, double n, int index); +static double bddAnnotateMintermCount (DdManager *manager, DdNode *node, double max, st_table *table); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns m minterms from a BDD.] + + Description [Returns m minterms from a BDD whose + support has n variables at most. The procedure tries + to create as few extra nodes as possible. The function represented + by S depends on at most n of the variables + in xVars. Returns a BDD with m minterms + of the on-set of S if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_SplitSet( + DdManager * manager, + DdNode * S, + DdNode ** xVars, + int n, + double m) +{ + DdNode *result; + DdNode *zero, *one; + double max, num; + st_table *mtable; + int *varSeen; + int i,index, size; + + size = manager->size; + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Trivial cases. */ + if (m == 0.0) { + return(zero); + } + if (S == zero) { + return(NULL); + } + + max = pow(2.0,(double)n); + if (m > max) + return(NULL); + + do { + manager->reordered = 0; + /* varSeen is used to mark the variables that are encountered + ** while traversing the BDD S. + */ + varSeen = ALLOC(int, size); + if (varSeen == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + varSeen[i] = -1; + } + for (i = 0; i < n; i++) { + index = (xVars[i])->index; + varSeen[manager->invperm[index]] = 0; + } + + if (S == one) { + if (m == max) { + FREE(varSeen); + return(S); + } + result = selectMintermsFromUniverse(manager,varSeen,m); + if (result) + cuddRef(result); + FREE(varSeen); + } else { + mtable = st_init_table(st_ptrcmp,st_ptrhash); + if (mtable == NULL) { + (void) fprintf(manager->out, + "Cudd_SplitSet: out-of-memory.\n"); + FREE(varSeen); + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + /* The nodes of BDD S are annotated by the number of minterms + ** in their onset. The node and the number of minterms in its + ** onset are stored in mtable. + */ + num = bddAnnotateMintermCount(manager,S,max,mtable); + if (m == num) { + st_foreach(mtable,cuddStCountfree,NIL(char)); + st_free_table(mtable); + FREE(varSeen); + return(S); + } + + result = cuddSplitSetRecur(manager,mtable,varSeen,S,m,max,0); + if (result) + cuddRef(result); + st_foreach(mtable,cuddStCountfree,NULL); + st_free_table(mtable); + FREE(varSeen); + } + } while (manager->reordered == 1); + + cuddDeref(result); + return(result); + +} /* end of Cudd_SplitSet */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_SplitSet.] + + Description [Implements the recursive step of Cudd_SplitSet. The + procedure recursively traverses the BDD and checks to see if any + node satisfies the minterm requirements as specified by 'n'. At any + node X, n is compared to the number of minterms in the onset of X's + children. If either of the child nodes have exactly n minterms, then + that node is returned; else, if n is greater than the onset of one + of the child nodes, that node is retained and the difference in the + number of minterms is extracted from the other child. In case n + minterms can be extracted from constant 1, the algorithm returns the + result with at most log(n) nodes.] + + SideEffects [The array 'varSeen' is updated at every recursive call + to set the variables traversed by the procedure.] + + SeeAlso [] + +******************************************************************************/ +DdNode* +cuddSplitSetRecur( + DdManager * manager, + st_table * mtable, + int * varSeen, + DdNode * p, + double n, + double max, + int index) +{ + DdNode *one, *zero, *N, *Nv; + DdNode *Nnv, *q, *r, *v; + DdNode *result; + double *dummy, numT, numE; + int variable, positive; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* If p is constant, extract n minterms from constant 1. The procedure by + ** construction guarantees that minterms will not be extracted from + ** constant 0. + */ + if (Cudd_IsConstant(p)) { + q = selectMintermsFromUniverse(manager,varSeen,n); + return(q); + } + + N = Cudd_Regular(p); + + /* Set variable as seen. */ + variable = N->index; + varSeen[manager->invperm[variable]] = -1; + + Nv = cuddT(N); + Nnv = cuddE(N); + if (Cudd_IsComplement(p)) { + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); + } + + /* If both the children of 'p' are constants, extract n minterms from a + ** constant node. + */ + if (Cudd_IsConstant(Nv) && Cudd_IsConstant(Nnv)) { + q = selectMintermsFromUniverse(manager,varSeen,n); + if (q == NULL) { + return(NULL); + } + cuddRef(q); + r = cuddBddAndRecur(manager,p,q); + if (r == NULL) { + Cudd_RecursiveDeref(manager,q); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDeref(manager,q); + cuddDeref(r); + return(r); + } + + /* Lookup the # of minterms in the onset of the node from the table. */ + if (!Cudd_IsConstant(Nv)) { + if (!st_lookup(mtable, Nv, &dummy)) return(NULL); + numT = *dummy/(2*(1<size; + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Count the number of variables not encountered so far in procedure + ** cuddSplitSetRecur. + */ + for (i = size-1; i >= 0; i--) { + if(varSeen[i] == 0) + numVars++; + } + vars = ALLOC(DdNode *, numVars); + if (!vars) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + j = 0; + for (i = size-1; i >= 0; i--) { + if(varSeen[i] == 0) { + vars[j] = cuddUniqueInter(manager,manager->perm[i],one,zero); + cuddRef(vars[j]); + j++; + } + } + + /* Compute a function which has n minterms and depends on at most + ** numVars variables. + */ + result = mintermsFromUniverse(manager,vars,numVars,n, 0); + if (result) + cuddRef(result); + + for (i = 0; i < numVars; i++) + Cudd_RecursiveDeref(manager,vars[i]); + FREE(vars); + + return(result); + +} /* end of selectMintermsFromUniverse */ + + +/**Function******************************************************************** + + Synopsis [Recursive procedure to extract n mintems from constant 1.] + + Description [Recursive procedure to extract n mintems from constant 1.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +mintermsFromUniverse( + DdManager * manager, + DdNode ** vars, + int numVars, + double n, + int index) +{ + DdNode *one, *zero; + DdNode *q, *result; + double max, max2; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + max = pow(2.0, (double)numVars); + max2 = max / 2.0; + + if (n == max) + return(one); + if (n == 0.0) + return(zero); + /* if n == 2^(numVars-1), return a single variable */ + if (n == max2) + return vars[index]; + else if (n > max2) { + /* When n > 2^(numVars-1), a single variable vars[index] + ** contains 2^(numVars-1) minterms. The rest are extracted + ** from a constant with 1 less variable. + */ + q = mintermsFromUniverse(manager,vars,numVars-1,(n-max2),index+1); + if (q == NULL) + return(NULL); + cuddRef(q); + result = cuddBddIteRecur(manager,vars[index],one,q); + } else { + /* When n < 2^(numVars-1), a literal of variable vars[index] + ** is selected. The required n minterms are extracted from a + ** constant with 1 less variable. + */ + q = mintermsFromUniverse(manager,vars,numVars-1,n,index+1); + if (q == NULL) + return(NULL); + cuddRef(q); + result = cuddBddAndRecur(manager,vars[index],q); + } + + if (result == NULL) { + Cudd_RecursiveDeref(manager,q); + return(NULL); + } + cuddRef(result); + Cudd_RecursiveDeref(manager,q); + cuddDeref(result); + return(result); + +} /* end of mintermsFromUniverse */ + + +/**Function******************************************************************** + + Synopsis [Annotates every node in the BDD node with its minterm count.] + + Description [Annotates every node in the BDD node with its minterm count. + In this function, every node and the minterm count represented by it are + stored in a hash table.] + + SideEffects [Fills up 'table' with the pair .] + +******************************************************************************/ +static double +bddAnnotateMintermCount( + DdManager * manager, + DdNode * node, + double max, + st_table * table) +{ + + DdNode *N,*Nv,*Nnv; + register double min_v,min_nv; + register double min_N; + double *pmin; + double *dummy; + + statLine(manager); + N = Cudd_Regular(node); + if (cuddIsConstant(N)) { + if (node == DD_ONE(manager)) { + return(max); + } else { + return(0.0); + } + } + + if (st_lookup(table, node, &dummy)) { + return(*dummy); + } + + Nv = cuddT(N); + Nnv = cuddE(N); + if (N != node) { + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); + } + + /* Recur on the two branches. */ + min_v = bddAnnotateMintermCount(manager,Nv,max,table) / 2.0; + if (min_v == (double)CUDD_OUT_OF_MEM) + return ((double)CUDD_OUT_OF_MEM); + min_nv = bddAnnotateMintermCount(manager,Nnv,max,table) / 2.0; + if (min_nv == (double)CUDD_OUT_OF_MEM) + return ((double)CUDD_OUT_OF_MEM); + min_N = min_v + min_nv; + + pmin = ALLOC(double,1); + if (pmin == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + *pmin = min_N; + + if (st_insert(table,(char *)node, (char *)pmin) == ST_OUT_OF_MEM) { + FREE(pmin); + return((double)CUDD_OUT_OF_MEM); + } + + return(min_N); + +} /* end of bddAnnotateMintermCount */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSubsetHB.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSubsetHB.c new file mode 100644 index 000000000..bb0f847b2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSubsetHB.c @@ -0,0 +1,1331 @@ +/**CFile*********************************************************************** + + FileName [cuddSubsetHB.c] + + PackageName [cudd] + + Synopsis [Procedure to subset the given BDD by choosing the heavier + branches.] + + + Description [External procedures provided by this module: +
                          +
                        • Cudd_SubsetHeavyBranch() +
                        • Cudd_SupersetHeavyBranch() +
                        + Internal procedures included in this module: +
                          +
                        • cuddSubsetHeavyBranch() +
                        + Static procedures included in this module: +
                          +
                        • ResizeCountMintermPages(); +
                        • ResizeNodeDataPages() +
                        • ResizeCountNodePages() +
                        • SubsetCountMintermAux() +
                        • SubsetCountMinterm() +
                        • SubsetCountNodesAux() +
                        • SubsetCountNodes() +
                        • BuildSubsetBdd() +
                        + ] + + SeeAlso [cuddSubsetSP.c] + + Author [Kavita Ravi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#ifdef __STDC__ +#include +#else +#define DBL_MAX_EXP 1024 +#endif +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DEFAULT_PAGE_SIZE 2048 +#define DEFAULT_NODE_DATA_PAGE_SIZE 1024 +#define INITIAL_PAGES 128 + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/* data structure to store the information on each node. It keeps + * the number of minterms represented by the DAG rooted at this node + * in terms of the number of variables specified by the user, number + * of nodes in this DAG and the number of nodes of its child with + * lesser number of minterms that are not shared by the child with + * more minterms + */ +struct NodeData { + double *mintermPointer; + int *nodesPointer; + int *lightChildNodesPointer; +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct NodeData NodeData_t; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSubsetHB.c,v 1.39 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int memOut; +#ifdef DEBUG +static int num_calls; +#endif + +static DdNode *zero, *one; /* constant functions */ +static double **mintermPages; /* pointers to the pages */ +static int **nodePages; /* pointers to the pages */ +static int **lightNodePages; /* pointers to the pages */ +static double *currentMintermPage; /* pointer to the current + page */ +static double max; /* to store the 2^n value of the number + * of variables */ + +static int *currentNodePage; /* pointer to the current + page */ +static int *currentLightNodePage; /* pointer to the + * current page */ +static int pageIndex; /* index to next element */ +static int page; /* index to current page */ +static int pageSize = DEFAULT_PAGE_SIZE; /* page size */ +static int maxPages; /* number of page pointers */ + +static NodeData_t *currentNodeDataPage; /* pointer to the current + page */ +static int nodeDataPage; /* index to next element */ +static int nodeDataPageIndex; /* index to next element */ +static NodeData_t **nodeDataPages; /* index to current page */ +static int nodeDataPageSize = DEFAULT_NODE_DATA_PAGE_SIZE; + /* page size */ +static int maxNodeDataPages; /* number of page pointers */ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void ResizeNodeDataPages (void); +static void ResizeCountMintermPages (void); +static void ResizeCountNodePages (void); +static double SubsetCountMintermAux (DdNode *node, double max, st_table *table); +static st_table * SubsetCountMinterm (DdNode *node, int nvars); +static int SubsetCountNodesAux (DdNode *node, st_table *table, double max); +static int SubsetCountNodes (DdNode *node, st_table *table, int nvars); +static void StoreNodes (st_table *storeTable, DdManager *dd, DdNode *node); +static DdNode * BuildSubsetBdd (DdManager *dd, DdNode *node, int *size, st_table *visitedTable, int threshold, st_table *storeTable, st_table *approxTable); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the heavy branch + heuristic.] + + Description [Extracts a dense subset from a BDD. This procedure + builds a subset by throwing away one of the children of each node, + starting from the root, until the result is small enough. The child + that is eliminated from the result is the one that contributes the + fewer minterms. Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation and node count calculation. The optimal number should + be as close as possible to the size of the support of f. However, + it is safe to pass the value returned by Cudd_ReadSize for numVars + when the number of variables is under 1023. If numVars is larger + than 1023, it will overflow. If a 0 parameter is passed then the + procedure will compute a value which will avoid overflow but will + cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SupersetHeavyBranch Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_SubsetHeavyBranch( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the subset */) +{ + DdNode *subset; + + memOut = 0; + do { + dd->reordered = 0; + subset = cuddSubsetHeavyBranch(dd, f, numVars, threshold); + } while ((dd->reordered == 1) && (!memOut)); + + return(subset); + +} /* end of Cudd_SubsetHeavyBranch */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the heavy branch + heuristic.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the subset procedure except for the fact that it + receives the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. This procedure builds a superset by throwing away + one of the children of each node starting from the root of the + complement function, until the result is small enough. The child + that is eliminated from the result is the one that contributes the + fewer minterms. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation and node count calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_SupersetHeavyBranch( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the superset */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + memOut = 0; + do { + dd->reordered = 0; + subset = cuddSubsetHeavyBranch(dd, g, numVars, threshold); + } while ((dd->reordered == 1) && (!memOut)); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_SupersetHeavyBranch */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [The main procedure that returns a subset by choosing the heavier + branch in the BDD.] + + Description [Here a subset BDD is built by throwing away one of the + children. Starting at root, annotate each node with the number of + minterms (in terms of the total number of variables specified - + numVars), number of nodes taken by the DAG rooted at this node and + number of additional nodes taken by the child that has the lesser + minterms. The child with the lower number of minterms is thrown away + and a dyanmic count of the nodes of the subset is kept. Once the + threshold is reached the subset is returned to the calling + procedure.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetHeavyBranch] + +******************************************************************************/ +DdNode * +cuddSubsetHeavyBranch( + DdManager * dd /* DD manager */, + DdNode * f /* current DD */, + int numVars /* maximum number of variables */, + int threshold /* threshold size for the subset */) +{ + + int i, *size; + st_table *visitedTable; + int numNodes; + NodeData_t *currNodeQual; + DdNode *subset; + st_table *storeTable, *approxTable; + DdNode *key, *value; + st_generator *stGen; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + one = Cudd_ReadOne(dd); + zero = Cudd_Not(one); + + /* If user does not know numVars value, set it to the maximum + * exponent that the pow function can take. The -1 is due to the + * discrepancy in the value that pow takes and the value that + * log gives. + */ + if (numVars == 0) { + /* set default value */ + numVars = DBL_MAX_EXP - 1; + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + max = pow(2.0, (double)numVars); + + /* Create visited table where structures for node data are allocated and + stored in a st_table */ + visitedTable = SubsetCountMinterm(f, numVars); + if ((visitedTable == NULL) || memOut) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + numNodes = SubsetCountNodes(f, visitedTable, numVars); + if (memOut) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + + if (st_lookup(visitedTable, f, &currNodeQual) == 0) { + fprintf(dd->err, + "Something is wrong, ought to be node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + } + + size = ALLOC(int, 1); + if (size == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + *size = numNodes; + +#ifdef DEBUG + num_calls = 0; +#endif + /* table to store nodes being created. */ + storeTable = st_init_table(st_ptrcmp, st_ptrhash); + /* insert the constant */ + cuddRef(one); + if (st_insert(storeTable, Cudd_ReadOne(dd), NULL) == + ST_OUT_OF_MEM) { + fprintf(dd->out, "Something wrong, st_table insert failed\n"); + } + /* table to store approximations of nodes */ + approxTable = st_init_table(st_ptrcmp, st_ptrhash); + subset = (DdNode *)BuildSubsetBdd(dd, f, size, visitedTable, threshold, + storeTable, approxTable); + if (subset != NULL) { + cuddRef(subset); + } + + stGen = st_init_gen(approxTable); + if (stGen == NULL) { + st_free_table(approxTable); + return(NULL); + } + while(st_gen(stGen, &key, &value)) { + Cudd_RecursiveDeref(dd, value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(approxTable); + + stGen = st_init_gen(storeTable); + if (stGen == NULL) { + st_free_table(storeTable); + return(NULL); + } + while(st_gen(stGen, &key, &value)) { + Cudd_RecursiveDeref(dd, key); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(storeTable); + + for (i = 0; i <= page; i++) { + FREE(mintermPages[i]); + } + FREE(mintermPages); + for (i = 0; i <= page; i++) { + FREE(nodePages[i]); + } + FREE(nodePages); + for (i = 0; i <= page; i++) { + FREE(lightNodePages[i]); + } + FREE(lightNodePages); + for (i = 0; i <= nodeDataPage; i++) { + FREE(nodeDataPages[i]); + } + FREE(nodeDataPages); + st_free_table(visitedTable); + FREE(size); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + + if (subset != NULL) { +#ifdef DD_DEBUG + if (!Cudd_bddLeq(dd, subset, f)) { + fprintf(dd->err, "Wrong subset\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } +#endif + cuddDeref(subset); + return(subset); + } else { + return(NULL); + } +} /* end of cuddSubsetHeavyBranch */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store the node data.] + + Description [Resize the number of pages allocated to store the node data + The procedure moves the counter to the next page when the end of + the page is reached and allocates new pages when necessary.] + + SideEffects [Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. ] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeNodeDataPages(void) +{ + int i; + NodeData_t **newNodeDataPages; + + nodeDataPage++; + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. Page numbers are incremented by + * INITIAL_PAGES + */ + if (nodeDataPage == maxNodeDataPages) { + newNodeDataPages = ALLOC(NodeData_t *,maxNodeDataPages + INITIAL_PAGES); + if (newNodeDataPages == NULL) { + for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + memOut = 1; + return; + } else { + for (i = 0; i < maxNodeDataPages; i++) { + newNodeDataPages[i] = nodeDataPages[i]; + } + /* Increase total page count */ + maxNodeDataPages += INITIAL_PAGES; + FREE(nodeDataPages); + nodeDataPages = newNodeDataPages; + } + } + /* Allocate a new page */ + currentNodeDataPage = nodeDataPages[nodeDataPage] = + ALLOC(NodeData_t ,nodeDataPageSize); + if (currentNodeDataPage == NULL) { + for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + memOut = 1; + return; + } + /* reset page index */ + nodeDataPageIndex = 0; + return; + +} /* end of ResizeNodeDataPages */ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store the minterm + counts. ] + + Description [Resize the number of pages allocated to store the minterm + counts. The procedure moves the counter to the next page when the + end of the page is reached and allocates new pages when necessary.] + + SideEffects [Changes the size of minterm pages, page, page index, maximum + number of pages freeing stuff in case of memory out. ] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeCountMintermPages(void) +{ + int i; + double **newMintermPages; + + page++; + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. Page numbers are incremented by + * INITIAL_PAGES + */ + if (page == maxPages) { + newMintermPages = ALLOC(double *,maxPages + INITIAL_PAGES); + if (newMintermPages == NULL) { + for (i = 0; i < page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newMintermPages[i] = mintermPages[i]; + } + /* Increase total page count */ + maxPages += INITIAL_PAGES; + FREE(mintermPages); + mintermPages = newMintermPages; + } + } + /* Allocate a new page */ + currentMintermPage = mintermPages[page] = ALLOC(double,pageSize); + if (currentMintermPage == NULL) { + for (i = 0; i < page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + memOut = 1; + return; + } + /* reset page index */ + pageIndex = 0; + return; + +} /* end of ResizeCountMintermPages */ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store the node counts.] + + Description [Resize the number of pages allocated to store the node counts. + The procedure moves the counter to the next page when the end of + the page is reached and allocates new pages when necessary.] + + SideEffects [Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out.] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeCountNodePages(void) +{ + int i; + int **newNodePages; + + page++; + + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. The number of pages is incremented + * by INITIAL_PAGES. + */ + if (page == maxPages) { + newNodePages = ALLOC(int *,maxPages + INITIAL_PAGES); + if (newNodePages == NULL) { + for (i = 0; i < page; i++) FREE(nodePages[i]); + FREE(nodePages); + for (i = 0; i < page; i++) FREE(lightNodePages[i]); + FREE(lightNodePages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newNodePages[i] = nodePages[i]; + } + FREE(nodePages); + nodePages = newNodePages; + } + + newNodePages = ALLOC(int *,maxPages + INITIAL_PAGES); + if (newNodePages == NULL) { + for (i = 0; i < page; i++) FREE(nodePages[i]); + FREE(nodePages); + for (i = 0; i < page; i++) FREE(lightNodePages[i]); + FREE(lightNodePages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newNodePages[i] = lightNodePages[i]; + } + FREE(lightNodePages); + lightNodePages = newNodePages; + } + /* Increase total page count */ + maxPages += INITIAL_PAGES; + } + /* Allocate a new page */ + currentNodePage = nodePages[page] = ALLOC(int,pageSize); + if (currentNodePage == NULL) { + for (i = 0; i < page; i++) FREE(nodePages[i]); + FREE(nodePages); + for (i = 0; i < page; i++) FREE(lightNodePages[i]); + FREE(lightNodePages); + memOut = 1; + return; + } + /* Allocate a new page */ + currentLightNodePage = lightNodePages[page] = ALLOC(int,pageSize); + if (currentLightNodePage == NULL) { + for (i = 0; i <= page; i++) FREE(nodePages[i]); + FREE(nodePages); + for (i = 0; i < page; i++) FREE(lightNodePages[i]); + FREE(lightNodePages); + memOut = 1; + return; + } + /* reset page index */ + pageIndex = 0; + return; + +} /* end of ResizeCountNodePages */ + + +/**Function******************************************************************** + + Synopsis [Recursively counts minterms of each node in the DAG.] + + Description [Recursively counts minterms of each node in the DAG. + Similar to the cuddCountMintermAux which recursively counts the + number of minterms for the dag rooted at each node in terms of the + total number of variables (max). This procedure creates the node + data structure and stores the minterm count as part of the node + data structure. ] + + SideEffects [Creates structures of type node quality and fills the st_table] + + SeeAlso [SubsetCountMinterm] + +******************************************************************************/ +static double +SubsetCountMintermAux( + DdNode * node /* function to analyze */, + double max /* number of minterms of constant 1 */, + st_table * table /* visitedTable table */) +{ + + DdNode *N,*Nv,*Nnv; /* nodes to store cofactors */ + double min,*pmin; /* minterm count */ + double min1, min2; /* minterm count */ + NodeData_t *dummy; + NodeData_t *newEntry; + int i; + +#ifdef DEBUG + num_calls++; +#endif + + /* Constant case */ + if (Cudd_IsConstant(node)) { + if (node == zero) { + return(0.0); + } else { + return(max); + } + } else { + + /* check if entry for this node exists */ + if (st_lookup(table, node, &dummy)) { + min = *(dummy->mintermPointer); + return(min); + } + + /* Make the node regular to extract cofactors */ + N = Cudd_Regular(node); + + /* store the cofactors */ + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + min1 = SubsetCountMintermAux(Nv, max,table)/2.0; + if (memOut) return(0.0); + min2 = SubsetCountMintermAux(Nnv,max,table)/2.0; + if (memOut) return(0.0); + min = (min1+min2); + + /* if page index is at the bottom, then create a new page */ + if (pageIndex == pageSize) ResizeCountMintermPages(); + if (memOut) { + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0.0); + } + + /* point to the correct location in the page */ + pmin = currentMintermPage+pageIndex; + pageIndex++; + + /* store the minterm count of this node in the page */ + *pmin = min; + + /* Note I allocate the struct here. Freeing taken care of later */ + if (nodeDataPageIndex == nodeDataPageSize) ResizeNodeDataPages(); + if (memOut) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + st_free_table(table); + return(0.0); + } + + newEntry = currentNodeDataPage + nodeDataPageIndex; + nodeDataPageIndex++; + + /* points to the correct location in the page */ + newEntry->mintermPointer = pmin; + /* initialize this field of the Node Quality structure */ + newEntry->nodesPointer = NULL; + + /* insert entry for the node in the table */ + if (st_insert(table,node, newEntry) == ST_OUT_OF_MEM) { + memOut = 1; + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0.0); + } + return(min); + } + +} /* end of SubsetCountMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Counts minterms of each node in the DAG] + + Description [Counts minterms of each node in the DAG. Similar to the + Cudd_CountMinterm procedure except this returns the minterm count for + all the nodes in the bdd in an st_table.] + + SideEffects [none] + + SeeAlso [SubsetCountMintermAux] + +******************************************************************************/ +static st_table * +SubsetCountMinterm( + DdNode * node /* function to be analyzed */, + int nvars /* number of variables node depends on */) +{ + st_table *table; + int i; + + +#ifdef DEBUG + num_calls = 0; +#endif + + max = pow(2.0,(double) nvars); + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) goto OUT_OF_MEM; + maxPages = INITIAL_PAGES; + mintermPages = ALLOC(double *,maxPages); + if (mintermPages == NULL) { + st_free_table(table); + goto OUT_OF_MEM; + } + page = 0; + currentMintermPage = ALLOC(double,pageSize); + mintermPages[page] = currentMintermPage; + if (currentMintermPage == NULL) { + FREE(mintermPages); + st_free_table(table); + goto OUT_OF_MEM; + } + pageIndex = 0; + maxNodeDataPages = INITIAL_PAGES; + nodeDataPages = ALLOC(NodeData_t *, maxNodeDataPages); + if (nodeDataPages == NULL) { + for (i = 0; i <= page ; i++) FREE(mintermPages[i]); + FREE(mintermPages); + st_free_table(table); + goto OUT_OF_MEM; + } + nodeDataPage = 0; + currentNodeDataPage = ALLOC(NodeData_t ,nodeDataPageSize); + nodeDataPages[nodeDataPage] = currentNodeDataPage; + if (currentNodeDataPage == NULL) { + for (i = 0; i <= page ; i++) FREE(mintermPages[i]); + FREE(mintermPages); + FREE(nodeDataPages); + st_free_table(table); + goto OUT_OF_MEM; + } + nodeDataPageIndex = 0; + + (void) SubsetCountMintermAux(node,max,table); + if (memOut) goto OUT_OF_MEM; + return(table); + +OUT_OF_MEM: + memOut = 1; + return(NULL); + +} /* end of SubsetCountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node.] + + Description [Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node. . Note that the same dag may be the lighter child of two + different nodes and have different counts. As with the minterm counts, + the node counts are stored in pages to be space efficient and the + address for these node counts are stored in an st_table associated + to each node. ] + + SideEffects [Updates the node data table with node counts] + + SeeAlso [SubsetCountNodes] + +******************************************************************************/ +static int +SubsetCountNodesAux( + DdNode * node /* current node */, + st_table * table /* table to update node count, also serves as visited table. */, + double max /* maximum number of variables */) +{ + int tval, eval, i; + DdNode *N, *Nv, *Nnv; + double minNv, minNnv; + NodeData_t *dummyN, *dummyNv, *dummyNnv, *dummyNBar; + int *pmin, *pminBar, *val; + + if ((node == NULL) || Cudd_IsConstant(node)) + return(0); + + /* if this node has been processed do nothing */ + if (st_lookup(table, node, &dummyN) == 1) { + val = dummyN->nodesPointer; + if (val != NULL) + return(0); + } else { + return(0); + } + + N = Cudd_Regular(node); + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* find the minterm counts for the THEN and ELSE branches */ + if (Cudd_IsConstant(Nv)) { + if (Nv == zero) { + minNv = 0.0; + } else { + minNv = max; + } + } else { + if (st_lookup(table, Nv, &dummyNv) == 1) + minNv = *(dummyNv->mintermPointer); + else { + return(0); + } + } + if (Cudd_IsConstant(Nnv)) { + if (Nnv == zero) { + minNnv = 0.0; + } else { + minNnv = max; + } + } else { + if (st_lookup(table, Nnv, &dummyNnv) == 1) { + minNnv = *(dummyNnv->mintermPointer); + } + else { + return(0); + } + } + + + /* recur based on which has larger minterm, */ + if (minNv >= minNnv) { + tval = SubsetCountNodesAux(Nv, table, max); + if (memOut) return(0); + eval = SubsetCountNodesAux(Nnv, table, max); + if (memOut) return(0); + + /* store the node count of the lighter child. */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pmin = currentLightNodePage + pageIndex; + *pmin = eval; /* Here the ELSE child is lighter */ + dummyN->lightChildNodesPointer = pmin; + + } else { + eval = SubsetCountNodesAux(Nnv, table, max); + if (memOut) return(0); + tval = SubsetCountNodesAux(Nv, table, max); + if (memOut) return(0); + + /* store the node count of the lighter child. */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pmin = currentLightNodePage + pageIndex; + *pmin = tval; /* Here the THEN child is lighter */ + dummyN->lightChildNodesPointer = pmin; + + } + /* updating the page index for node count storage. */ + pmin = currentNodePage + pageIndex; + *pmin = tval + eval + 1; + dummyN->nodesPointer = pmin; + + /* pageIndex is parallel page index for count_nodes and count_lightNodes */ + pageIndex++; + + /* if this node has been reached first, it belongs to a heavier + branch. Its complement will be reached later on a lighter branch. + Hence the complement has zero node count. */ + + if (st_lookup(table, Cudd_Not(node), &dummyNBar) == 1) { + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i < page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pminBar = currentLightNodePage + pageIndex; + *pminBar = 0; + dummyNBar->lightChildNodesPointer = pminBar; + /* The lighter child has less nodes than the parent. + * So if parent 0 then lighter child zero + */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i < page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pminBar = currentNodePage + pageIndex; + *pminBar = 0; + dummyNBar->nodesPointer = pminBar ; /* maybe should point to zero */ + + pageIndex++; + } + return(*pmin); +} /*end of SubsetCountNodesAux */ + + +/**Function******************************************************************** + + Synopsis [Counts the nodes under the current node and its lighter child] + + Description [Counts the nodes under the current node and its lighter + child. Calls a recursive procedure to count the number of nodes of + a DAG rooted at a particular node and the number of nodes taken by its + lighter child.] + + SideEffects [None] + + SeeAlso [SubsetCountNodesAux] + +******************************************************************************/ +static int +SubsetCountNodes( + DdNode * node /* function to be analyzed */, + st_table * table /* node quality table */, + int nvars /* number of variables node depends on */) +{ + int num; + int i; + +#ifdef DEBUG + num_calls = 0; +#endif + + max = pow(2.0,(double) nvars); + maxPages = INITIAL_PAGES; + nodePages = ALLOC(int *,maxPages); + if (nodePages == NULL) { + goto OUT_OF_MEM; + } + + lightNodePages = ALLOC(int *,maxPages); + if (lightNodePages == NULL) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + FREE(nodePages); + goto OUT_OF_MEM; + } + + page = 0; + currentNodePage = nodePages[page] = ALLOC(int,pageSize); + if (currentNodePage == NULL) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + FREE(lightNodePages); + FREE(nodePages); + goto OUT_OF_MEM; + } + + currentLightNodePage = lightNodePages[page] = ALLOC(int,pageSize); + if (currentLightNodePage == NULL) { + for (i = 0; i <= page; i++) FREE(mintermPages[i]); + FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]); + FREE(nodeDataPages); + FREE(currentNodePage); + FREE(lightNodePages); + FREE(nodePages); + goto OUT_OF_MEM; + } + + pageIndex = 0; + num = SubsetCountNodesAux(node,table,max); + if (memOut) goto OUT_OF_MEM; + return(num); + +OUT_OF_MEM: + memOut = 1; + return(0); + +} /* end of SubsetCountNodes */ + + +/**Function******************************************************************** + + Synopsis [Procedure to recursively store nodes that are retained in the subset.] + + Description [rocedure to recursively store nodes that are retained in the subset.] + + SideEffects [None] + + SeeAlso [StoreNodes] + +******************************************************************************/ +static void +StoreNodes( + st_table * storeTable, + DdManager * dd, + DdNode * node) +{ + DdNode *N, *Nt, *Ne; + if (Cudd_IsConstant(dd)) { + return; + } + N = Cudd_Regular(node); + if (st_lookup(storeTable, N, NULL)) { + return; + } + cuddRef(N); + if (st_insert(storeTable, N, NULL) == ST_OUT_OF_MEM) { + fprintf(dd->err,"Something wrong, st_table insert failed\n"); + } + + Nt = Cudd_T(N); + Ne = Cudd_E(N); + + StoreNodes(storeTable, dd, Nt); + StoreNodes(storeTable, dd, Ne); + return; + +} + + +/**Function******************************************************************** + + Synopsis [Builds the subset BDD using the heavy branch method.] + + Description [The procedure carries out the building of the subset BDD + starting at the root. Using the three different counts labelling each node, + the procedure chooses the heavier branch starting from the root and keeps + track of the number of nodes it discards at each step, thus keeping count + of the size of the subset BDD dynamically. Once the threshold is satisfied, + the procedure then calls ITE to build the BDD.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +BuildSubsetBdd( + DdManager * dd /* DD manager */, + DdNode * node /* current node */, + int * size /* current size of the subset */, + st_table * visitedTable /* visited table storing all node data */, + int threshold, + st_table * storeTable, + st_table * approxTable) +{ + + DdNode *Nv, *Nnv, *N, *topv, *neW; + double minNv, minNnv; + NodeData_t *currNodeQual; + NodeData_t *currNodeQualT; + NodeData_t *currNodeQualE; + DdNode *ThenBranch, *ElseBranch; + unsigned int topid; + char *dummy; + +#ifdef DEBUG + num_calls++; +#endif + /*If the size of the subset is below the threshold, dont do + anything. */ + if ((*size) <= threshold) { + /* store nodes below this, so we can recombine if possible */ + StoreNodes(storeTable, dd, node); + return(node); + } + + if (Cudd_IsConstant(node)) + return(node); + + /* Look up minterm count for this node. */ + if (!st_lookup(visitedTable, node, &currNodeQual)) { + fprintf(dd->err, + "Something is wrong, ought to be in node quality table\n"); + } + + /* Get children. */ + N = Cudd_Regular(node); + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + /* complement if necessary */ + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + if (!Cudd_IsConstant(Nv)) { + /* find out minterms and nodes contributed by then child */ + if (!st_lookup(visitedTable, Nv, &currNodeQualT)) { + fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + else { + minNv = *(((NodeData_t *)currNodeQualT)->mintermPointer); + } + } else { + if (Nv == zero) { + minNv = 0; + } else { + minNv = max; + } + } + if (!Cudd_IsConstant(Nnv)) { + /* find out minterms and nodes contributed by else child */ + if (!st_lookup(visitedTable, Nnv, &currNodeQualE)) { + fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } else { + minNnv = *(((NodeData_t *)currNodeQualE)->mintermPointer); + } + } else { + if (Nnv == zero) { + minNnv = 0; + } else { + minNnv = max; + } + } + + /* keep track of size of subset by subtracting the number of + * differential nodes contributed by lighter child + */ + *size = (*(size)) - (int)*(currNodeQual->lightChildNodesPointer); + if (minNv >= minNnv) { /*SubsetCountNodesAux procedure takes + the Then branch in case of a tie */ + + /* recur with the Then branch */ + ThenBranch = (DdNode *)BuildSubsetBdd(dd, Nv, size, + visitedTable, threshold, storeTable, approxTable); + if (ThenBranch == NULL) { + return(NULL); + } + cuddRef(ThenBranch); + /* The Else branch is either a node that already exists in the + * subset, or one whose approximation has been computed, or + * Zero. + */ + if (st_lookup(storeTable, Cudd_Regular(Nnv), &dummy)) { + ElseBranch = Nnv; + cuddRef(ElseBranch); + } else { + if (st_lookup(approxTable, Nnv, &dummy)) { + ElseBranch = (DdNode *)dummy; + cuddRef(ElseBranch); + } else { + ElseBranch = zero; + cuddRef(ElseBranch); + } + } + + } + else { + /* recur with the Else branch */ + ElseBranch = (DdNode *)BuildSubsetBdd(dd, Nnv, size, + visitedTable, threshold, storeTable, approxTable); + if (ElseBranch == NULL) { + return(NULL); + } + cuddRef(ElseBranch); + /* The Then branch is either a node that already exists in the + * subset, or one whose approximation has been computed, or + * Zero. + */ + if (st_lookup(storeTable, Cudd_Regular(Nv), &dummy)) { + ThenBranch = Nv; + cuddRef(ThenBranch); + } else { + if (st_lookup(approxTable, Nv, &dummy)) { + ThenBranch = (DdNode *)dummy; + cuddRef(ThenBranch); + } else { + ThenBranch = zero; + cuddRef(ThenBranch); + } + } + } + + /* construct the Bdd with the top variable and the two children */ + topid = Cudd_NodeReadIndex(N); + topv = Cudd_ReadVars(dd, topid); + cuddRef(topv); + neW = cuddBddIteRecur(dd, topv, ThenBranch, ElseBranch); + if (neW != NULL) { + cuddRef(neW); + } + Cudd_RecursiveDeref(dd, topv); + Cudd_RecursiveDeref(dd, ThenBranch); + Cudd_RecursiveDeref(dd, ElseBranch); + + + if (neW == NULL) + return(NULL); + else { + /* store this node in the store table */ + if (!st_lookup(storeTable, Cudd_Regular(neW), &dummy)) { + cuddRef(neW); + if (st_insert(storeTable, Cudd_Regular(neW), NULL) == + ST_OUT_OF_MEM) + return (NULL); + } + /* store the approximation for this node */ + if (N != Cudd_Regular(neW)) { + if (st_lookup(approxTable, node, &dummy)) { + fprintf(dd->err, "This node should not be in the approximated table\n"); + } else { + cuddRef(neW); + if (st_insert(approxTable, node, neW) == + ST_OUT_OF_MEM) + return(NULL); + } + } + cuddDeref(neW); + return(neW); + } +} /* end of BuildSubsetBdd */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSubsetSP.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSubsetSP.c new file mode 100644 index 000000000..fa89f167f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSubsetSP.c @@ -0,0 +1,1660 @@ +/**CFile*********************************************************************** + + FileName [cuddSubsetSP.c] + + PackageName [cudd] + + Synopsis [Procedure to subset the given BDD choosing the shortest paths + (largest cubes) in the BDD.] + + + Description [External procedures included in this module: +
                          +
                        • Cudd_SubsetShortPaths() +
                        • Cudd_SupersetShortPaths() +
                        + Internal procedures included in this module: +
                          +
                        • cuddSubsetShortPaths() +
                        + Static procedures included in this module: +
                          +
                        • BuildSubsetBdd() +
                        • CreatePathTable() +
                        • AssessPathLength() +
                        • CreateTopDist() +
                        • CreateBotDist() +
                        • ResizeNodeDistPages() +
                        • ResizeQueuePages() +
                        • stPathTableDdFree() +
                        + ] + + SeeAlso [cuddSubsetHB.c] + + Author [Kavita Ravi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DEFAULT_PAGE_SIZE 2048 /* page size to store the BFS queue element type */ +#define DEFAULT_NODE_DIST_PAGE_SIZE 2048 /* page size to store NodeDist_t type */ +#define MAXSHORTINT ((DdHalfWord) ~0) /* constant defined to store + * maximum distance of a node + * from the root or the constant + */ +#define INITIAL_PAGES 128 /* number of initial pages for the + * queue/NodeDist_t type */ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/* structure created to store subset results for each node and distances with + * odd and even parity of the node from the root and sink. Main data structure + * in this procedure. + */ +struct NodeDist { + DdHalfWord oddTopDist; + DdHalfWord evenTopDist; + DdHalfWord oddBotDist; + DdHalfWord evenBotDist; + DdNode *regResult; + DdNode *compResult; +}; + +/* assorted information needed by the BuildSubsetBdd procedure. */ +struct AssortedInfo { + unsigned int maxpath; + int findShortestPath; + int thresholdReached; + st_table *maxpathTable; + int threshold; +}; + +struct GlobalInfo { + struct NodeDist **nodeDistPages; /* pointers to the pages */ + int nodeDistPageIndex; /* index to next element */ + int nodeDistPage; /* index to current page */ + int nodeDistPageSize; /* page size */ + int maxNodeDistPages; /* number of page pointers */ + struct NodeDist *currentNodeDistPage; /* current page */ + DdNode ***queuePages; /* pointers to the pages */ + int queuePageIndex; /* index to next element */ + int queuePage; /* index to current page */ + int queuePageSize; /* page size */ + int maxQueuePages; /* number of page pointers */ + DdNode **currentQueuePage; /* current page */ +#ifdef DD_DEBUG + int numCalls; + int hits; + int thishit; +#endif +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct NodeDist NodeDist_t; +typedef struct GlobalInfo GlobalInfo_t; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSubsetSP.c,v 1.36 2012/02/05 01:07:19 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void ResizeNodeDistPages (DdManager *dd, GlobalInfo_t *gInfo); +static void ResizeQueuePages (DdManager *dd, GlobalInfo_t *gInfo); +static void CreateTopDist (DdManager *dd, GlobalInfo_t *gInfo, st_table *pathTable, int parentPage, int parentQueueIndex, int topLen, DdNode **childPage, int childQueueIndex, int numParents, FILE *fp); +static int CreateBotDist (DdNode *node, st_table *pathTable, unsigned int *pathLengthArray, FILE *fp); +static st_table * CreatePathTable (DdManager *dd, GlobalInfo_t *gInfo, DdNode *node, unsigned int *pathLengthArray, FILE *fp); +static unsigned int AssessPathLength (unsigned int *pathLengthArray, int threshold, int numVars, unsigned int *excess, FILE *fp); +static DdNode * BuildSubsetBdd (DdManager *dd, GlobalInfo_t *gInfo, st_table *pathTable, DdNode *node, struct AssortedInfo *info, st_table *subsetNodeTable); +static enum st_retval stPathTableDdFree (char *key, char *value, char *arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of Exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the shortest paths + heuristic.] + + Description [Extracts a dense subset from a BDD. This procedure + tries to preserve the shortest paths of the input BDD, because they + give many minterms and contribute few nodes. This procedure may + increase the number of nodes in trying to create the subset or + reduce the number of nodes due to recombination as compared to the + original BDD. Hence the threshold may not be strictly adhered to. In + practice, recombination overshadows the increase in the number of + nodes and results in small BDDs as compared to the threshold. The + hardlimit specifies whether threshold needs to be strictly adhered + to. If it is set to 1, the procedure ensures that result is never + larger than the specified limit but may be considerably less than + the threshold. Returns a pointer to the BDD for the subset if + successful; NULL otherwise. The value for numVars should be as + close as possible to the size of the support of f for better + efficiency. However, it is safe to pass the value returned by + Cudd_ReadSize for numVars. If 0 is passed, then the value returned + by Cudd_ReadSize is used.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_SubsetShortPaths( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the subset */, + int hardlimit /* flag: 1 if threshold is a hard limit */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddSubsetShortPaths(dd, f, numVars, threshold, hardlimit); + } while(dd->reordered == 1); + + return(subset); + +} /* end of Cudd_SubsetShortPaths */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the shortest paths + heuristic.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the subset procedure except for the fact that it + receives the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. This procedure tries to preserve the shortest + paths of the complement BDD, because they give many minterms and + contribute few nodes. This procedure may increase the number of + nodes in trying to create the superset or reduce the number of nodes + due to recombination as compared to the original BDD. Hence the + threshold may not be strictly adhered to. In practice, recombination + overshadows the increase in the number of nodes and results in small + BDDs as compared to the threshold. The hardlimit specifies whether + threshold needs to be strictly adhered to. If it is set to 1, the + procedure ensures that result is never larger than the specified + limit but may be considerably less than the threshold. Returns a + pointer to the BDD for the superset if successful; NULL + otherwise. The value for numVars should be as close as possible to + the size of the support of f for better efficiency. However, it is + safe to pass the value returned by Cudd_ReadSize for numVar. If 0 + is passed, then the value returned by Cudd_ReadSize is used.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SupersetHeavyBranch Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_SupersetShortPaths( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* maximum number of nodes in the subset */, + int hardlimit /* flag: 1 if threshold is a hard limit */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddSubsetShortPaths(dd, g, numVars, threshold, hardlimit); + } while(dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_SupersetShortPaths */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [The outermost procedure to return a subset of the given BDD + with the shortest path lengths.] + + Description [The outermost procedure to return a subset of the given + BDD with the largest cubes. The path lengths are calculated, the maximum + allowable path length is determined and the number of nodes of this + path length that can be used to build a subset. If the threshold is + larger than the size of the original BDD, the original BDD is + returned. ] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths] + +******************************************************************************/ +DdNode * +cuddSubsetShortPaths( + DdManager * dd /* DD manager */, + DdNode * f /* function to be subset */, + int numVars /* total number of variables in consideration */, + int threshold /* maximum number of nodes allowed in the subset */, + int hardlimit /* flag determining whether threshold should be respected strictly */) +{ + GlobalInfo_t gInfo; + st_table *pathTable; + DdNode *N, *subset; + + unsigned int *pathLengthArray; + unsigned int maxpath, oddLen, evenLen, pathLength, *excess; + int i; + NodeDist_t *nodeStat; + struct AssortedInfo *info; + st_table *subsetNodeTable; + + gInfo.nodeDistPageSize = DEFAULT_NODE_DIST_PAGE_SIZE; + gInfo.queuePageSize = DEFAULT_PAGE_SIZE; + + if (numVars == 0) { + /* set default value */ + numVars = Cudd_ReadSize(dd); + } + + if (threshold > numVars) { + threshold = threshold - numVars; + } + if (f == NULL) { + fprintf(dd->err, "Cannot partition, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + if (Cudd_IsConstant(f)) + return (f); + + pathLengthArray = ALLOC(unsigned int, numVars+1); + for (i = 0; i < numVars+1; i++) pathLengthArray[i] = 0; + + +#ifdef DD_DEBUG + gInfo.numCalls = 0; +#endif + + pathTable = CreatePathTable(dd, &gInfo, f, pathLengthArray, dd->err); + + if ((pathTable == NULL) || (dd->errorCode == CUDD_MEMORY_OUT)) { + if (pathTable != NULL) + st_free_table(pathTable); + FREE(pathLengthArray); + return (NIL(DdNode)); + } + + excess = ALLOC(unsigned int, 1); + *excess = 0; + maxpath = AssessPathLength(pathLengthArray, threshold, numVars, excess, + dd->err); + + if (maxpath != (unsigned) (numVars + 1)) { + + info = ALLOC(struct AssortedInfo, 1); + info->maxpath = maxpath; + info->findShortestPath = 0; + info->thresholdReached = *excess; + info->maxpathTable = st_init_table(st_ptrcmp, st_ptrhash); + info->threshold = threshold; + +#ifdef DD_DEBUG + (void) fprintf(dd->out, "Path length array\n"); + for (i = 0; i < (numVars+1); i++) { + if (pathLengthArray[i]) + (void) fprintf(dd->out, "%d ",i); + } + (void) fprintf(dd->out, "\n"); + for (i = 0; i < (numVars+1); i++) { + if (pathLengthArray[i]) + (void) fprintf(dd->out, "%d ",pathLengthArray[i]); + } + (void) fprintf(dd->out, "\n"); + (void) fprintf(dd->out, "Maxpath = %d, Thresholdreached = %d\n", + maxpath, info->thresholdReached); +#endif + + N = Cudd_Regular(f); + if (!st_lookup(pathTable, N, &nodeStat)) { + fprintf(dd->err, "Something wrong, root node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + FREE(excess); + FREE(info); + return(NULL); + } else { + if ((nodeStat->oddTopDist != MAXSHORTINT) && + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + else + oddLen = MAXSHORTINT; + + if ((nodeStat->evenTopDist != MAXSHORTINT) && + (nodeStat->evenBotDist != MAXSHORTINT)) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + else + evenLen = MAXSHORTINT; + + pathLength = (oddLen <= evenLen) ? oddLen : evenLen; + if (pathLength > maxpath) { + (void) fprintf(dd->err, "All computations are bogus, since root has path length greater than max path length within threshold %u, %u\n", maxpath, pathLength); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + } + +#ifdef DD_DEBUG + gInfo.numCalls = 0; + gInfo.hits = 0; + gInfo.thishit = 0; +#endif + /* initialize a table to store computed nodes */ + if (hardlimit) { + subsetNodeTable = st_init_table(st_ptrcmp, st_ptrhash); + } else { + subsetNodeTable = NIL(st_table); + } + subset = BuildSubsetBdd(dd, &gInfo, pathTable, f, info, subsetNodeTable); + if (subset != NULL) { + cuddRef(subset); + } + /* record the number of times a computed result for a node is hit */ + +#ifdef DD_DEBUG + (void) fprintf(dd->out, "Hits = %d, New==Node = %d, NumCalls = %d\n", + gInfo.hits, gInfo.thishit, gInfo.numCalls); +#endif + + if (subsetNodeTable != NIL(st_table)) { + st_free_table(subsetNodeTable); + } + st_free_table(info->maxpathTable); + st_foreach(pathTable, stPathTableDdFree, (char *)dd); + + FREE(info); + + } else {/* if threshold larger than size of dd */ + subset = f; + cuddRef(subset); + } + FREE(excess); + st_free_table(pathTable); + FREE(pathLengthArray); + for (i = 0; i <= gInfo.nodeDistPage; i++) FREE(gInfo.nodeDistPages[i]); + FREE(gInfo.nodeDistPages); + +#ifdef DD_DEBUG + /* check containment of subset in f */ + if (subset != NULL) { + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong partition\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + } +#endif + + if (subset != NULL) { + cuddDeref(subset); + return(subset); + } else { + return(NULL); + } + +} /* end of cuddSubsetShortPaths */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store the distances + related to each node.] + + Description [Resize the number of pages allocated to store the distances + related to each node. The procedure moves the counter to the + next page when the end of the page is reached and allocates new + pages when necessary. ] + + SideEffects [Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. ] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeNodeDistPages( + DdManager *dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */) +{ + int i; + NodeDist_t **newNodeDistPages; + + /* move to next page */ + gInfo->nodeDistPage++; + + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. Page numbers are incremented by + * INITIAL_PAGES + */ + if (gInfo->nodeDistPage == gInfo->maxNodeDistPages) { + newNodeDistPages = ALLOC(NodeDist_t *,gInfo->maxNodeDistPages + INITIAL_PAGES); + if (newNodeDistPages == NULL) { + for (i = 0; i < gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + dd->errorCode = CUDD_MEMORY_OUT; + return; + } else { + for (i = 0; i < gInfo->maxNodeDistPages; i++) { + newNodeDistPages[i] = gInfo->nodeDistPages[i]; + } + /* Increase total page count */ + gInfo->maxNodeDistPages += INITIAL_PAGES; + FREE(gInfo->nodeDistPages); + gInfo->nodeDistPages = newNodeDistPages; + } + } + /* Allocate a new page */ + gInfo->currentNodeDistPage = gInfo->nodeDistPages[gInfo->nodeDistPage] = + ALLOC(NodeDist_t, gInfo->nodeDistPageSize); + if (gInfo->currentNodeDistPage == NULL) { + for (i = 0; i < gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + dd->errorCode = CUDD_MEMORY_OUT; + return; + } + /* reset page index */ + gInfo->nodeDistPageIndex = 0; + return; + +} /* end of ResizeNodeDistPages */ + + +/**Function******************************************************************** + + Synopsis [Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd .] + + Description [Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd. The procedure moves the counter to the + next page when the end of the page is reached and allocates new + pages when necessary.] + + SideEffects [Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. ] + + SeeAlso [] + +******************************************************************************/ +static void +ResizeQueuePages( + DdManager *dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */) +{ + int i; + DdNode ***newQueuePages; + + gInfo->queuePage++; + /* If the current page index is larger than the number of pages + * allocated, allocate a new page array. Page numbers are incremented by + * INITIAL_PAGES + */ + if (gInfo->queuePage == gInfo->maxQueuePages) { + newQueuePages = ALLOC(DdNode **,gInfo->maxQueuePages + INITIAL_PAGES); + if (newQueuePages == NULL) { + for (i = 0; i < gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + dd->errorCode = CUDD_MEMORY_OUT; + return; + } else { + for (i = 0; i < gInfo->maxQueuePages; i++) { + newQueuePages[i] = gInfo->queuePages[i]; + } + /* Increase total page count */ + gInfo->maxQueuePages += INITIAL_PAGES; + FREE(gInfo->queuePages); + gInfo->queuePages = newQueuePages; + } + } + /* Allocate a new page */ + gInfo->currentQueuePage = gInfo->queuePages[gInfo->queuePage] = + ALLOC(DdNode *,gInfo->queuePageSize); + if (gInfo->currentQueuePage == NULL) { + for (i = 0; i < gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + dd->errorCode = CUDD_MEMORY_OUT; + return; + } + /* reset page index */ + gInfo->queuePageIndex = 0; + return; + +} /* end of ResizeQueuePages */ + + +/**Function******************************************************************** + + Synopsis [ Labels each node with its shortest distance from the root] + + Description [ Labels each node with its shortest distance from the root. + This is done in a BFS search of the BDD. The nodes are processed + in a queue implemented as pages(array) to reduce memory fragmentation. + An entry is created for each node visited. The distance from the root + to the node with the corresponding parity is updated. The procedure + is called recursively each recusion level handling nodes at a given + level from the root.] + + + SideEffects [Creates entries in the pathTable] + + SeeAlso [CreatePathTable CreateBotDist] + +******************************************************************************/ +static void +CreateTopDist( + DdManager *dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */, + st_table * pathTable /* hast table to store path lengths */, + int parentPage /* the pointer to the page on which the first parent in the queue is to be found. */, + int parentQueueIndex /* pointer to the first parent on the page */, + int topLen /* current distance from the root */, + DdNode ** childPage /* pointer to the page on which the first child is to be added. */, + int childQueueIndex /* pointer to the first child */, + int numParents /* number of parents to process in this recursive call */, + FILE *fp /* where to write messages */) +{ + NodeDist_t *nodeStat; + DdNode *N, *Nv, *Nnv, *node, *child, *regChild; + int i; + int processingDone, childrenCount; + +#ifdef DD_DEBUG + gInfo->numCalls++; + + /* assume this procedure comes in with only the root node*/ + /* set queue index to the next available entry for addition */ + /* set queue page to page of addition */ + if ((gInfo->queuePages[parentPage] == childPage) && (parentQueueIndex == + childQueueIndex)) { + fprintf(fp, "Should not happen that they are equal\n"); + } + assert(gInfo->queuePageIndex == childQueueIndex); + assert(gInfo->currentQueuePage == childPage); +#endif + /* number children added to queue is initialized , needed for + * numParents in the next call + */ + childrenCount = 0; + /* process all the nodes in this level */ + while (numParents) { + numParents--; + if (parentQueueIndex == gInfo->queuePageSize) { + parentPage++; + parentQueueIndex = 0; + } + /* a parent to process */ + node = *(gInfo->queuePages[parentPage] + parentQueueIndex); + parentQueueIndex++; + /* get its children */ + N = Cudd_Regular(node); + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + processingDone = 2; + while (processingDone) { + /* processing the THEN and the ELSE children, the THEN + * child first + */ + if (processingDone == 2) { + child = Nv; + } else { + child = Nnv; + } + + regChild = Cudd_Regular(child); + /* dont process if the child is a constant */ + if (!Cudd_IsConstant(child)) { + /* check is already visited, if not add a new entry in + * the path Table + */ + if (!st_lookup(pathTable, regChild, &nodeStat)) { + /* if not in table, has never been visited */ + /* create entry for table */ + if (gInfo->nodeDistPageIndex == gInfo->nodeDistPageSize) + ResizeNodeDistPages(dd, gInfo); + if (dd->errorCode == CUDD_MEMORY_OUT) { + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + st_free_table(pathTable); + return; + } + /* New entry for child in path Table is created here */ + nodeStat = gInfo->currentNodeDistPage + gInfo->nodeDistPageIndex; + gInfo->nodeDistPageIndex++; + + /* Initialize fields of the node data */ + nodeStat->oddTopDist = MAXSHORTINT; + nodeStat->evenTopDist = MAXSHORTINT; + nodeStat->evenBotDist = MAXSHORTINT; + nodeStat->oddBotDist = MAXSHORTINT; + nodeStat->regResult = NULL; + nodeStat->compResult = NULL; + /* update the table entry element, the distance keeps + * track of the parity of the path from the root + */ + if (Cudd_IsComplement(child)) { + nodeStat->oddTopDist = (DdHalfWord) topLen + 1; + } else { + nodeStat->evenTopDist = (DdHalfWord) topLen + 1; + } + + /* insert entry element for child in the table */ + if (st_insert(pathTable, regChild, + nodeStat) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i <= gInfo->nodeDistPage; i++) + FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + st_free_table(pathTable); + return; + } + + /* Create list element for this child to process its children. + * If this node has been processed already, then it appears + * in the path table and hence is never added to the list + * again. + */ + + if (gInfo->queuePageIndex == gInfo->queuePageSize) ResizeQueuePages(dd, gInfo); + if (dd->errorCode == CUDD_MEMORY_OUT) { + for (i = 0; i <= gInfo->nodeDistPage; i++) + FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + st_free_table(pathTable); + return; + } + *(gInfo->currentQueuePage + gInfo->queuePageIndex) = child; + gInfo->queuePageIndex++; + + childrenCount++; + } else { + /* if not been met in a path with this parity before */ + /* put in list */ + if (((Cudd_IsComplement(child)) && (nodeStat->oddTopDist == + MAXSHORTINT)) || ((!Cudd_IsComplement(child)) && + (nodeStat->evenTopDist == MAXSHORTINT))) { + + if (gInfo->queuePageIndex == gInfo->queuePageSize) ResizeQueuePages(dd, gInfo); + if (dd->errorCode == CUDD_MEMORY_OUT) { + for (i = 0; i <= gInfo->nodeDistPage; i++) + FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + st_free_table(pathTable); + return; + + } + *(gInfo->currentQueuePage + gInfo->queuePageIndex) = child; + gInfo->queuePageIndex++; + + /* update the distance with the appropriate parity */ + if (Cudd_IsComplement(child)) { + nodeStat->oddTopDist = (DdHalfWord) topLen + 1; + } else { + nodeStat->evenTopDist = (DdHalfWord) topLen + 1; + } + childrenCount++; + } + + } /* end of else (not found in st_table) */ + } /*end of if Not constant child */ + processingDone--; + } /*end of while processing Nv, Nnv */ + } /*end of while numParents */ + +#ifdef DD_DEBUG + assert(gInfo->queuePages[parentPage] == childPage); + assert(parentQueueIndex == childQueueIndex); +#endif + + if (childrenCount != 0) { + topLen++; + childPage = gInfo->currentQueuePage; + childQueueIndex = gInfo->queuePageIndex; + CreateTopDist(dd, gInfo, pathTable, parentPage, parentQueueIndex, topLen, + childPage, childQueueIndex, childrenCount, fp); + } + + return; + +} /* end of CreateTopDist */ + + +/**Function******************************************************************** + + Synopsis [ Labels each node with the shortest distance from the constant.] + + Description [Labels each node with the shortest distance from the constant. + This is done in a DFS search of the BDD. Each node has an odd + and even parity distance from the sink (since there exists paths to both + zero and one) which is less than MAXSHORTINT. At each node these distances + are updated using the minimum distance of its children from the constant. + SInce now both the length from the root and child is known, the minimum path + length(length of the shortest path between the root and the constant that + this node lies on) of this node can be calculated and used to update the + pathLengthArray] + + SideEffects [Updates Path Table and path length array] + + SeeAlso [CreatePathTable CreateTopDist AssessPathLength] + +******************************************************************************/ +static int +CreateBotDist( + DdNode * node /* current node */, + st_table * pathTable /* path table with path lengths */, + unsigned int * pathLengthArray /* array that stores number of nodes belonging to a particular path length. */, + FILE *fp /* where to write messages */) +{ + DdNode *N, *Nv, *Nnv; + DdNode *realChild; + DdNode *child, *regChild; + NodeDist_t *nodeStat, *nodeStatChild; + unsigned int oddLen, evenLen, pathLength; + DdHalfWord botDist; + int processingDone; + + if (Cudd_IsConstant(node)) + return(1); + N = Cudd_Regular(node); + /* each node has one table entry */ + /* update as you go down the min dist of each node from + the root in each (odd and even) parity */ + if (!st_lookup(pathTable, N, &nodeStat)) { + fprintf(fp, "Something wrong, the entry doesn't exist\n"); + return(0); + } + + /* compute length of odd parity distances */ + if ((nodeStat->oddTopDist != MAXSHORTINT) && + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + else + oddLen = MAXSHORTINT; + + /* compute length of even parity distances */ + if (!((nodeStat->evenTopDist == MAXSHORTINT) || + (nodeStat->evenBotDist == MAXSHORTINT))) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + else + evenLen = MAXSHORTINT; + + /* assign pathlength to minimum of the two */ + pathLength = (oddLen <= evenLen) ? oddLen : evenLen; + + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + /* process each child */ + processingDone = 0; + while (processingDone != 2) { + if (!processingDone) { + child = Nv; + } else { + child = Nnv; + } + + realChild = Cudd_NotCond(child, Cudd_IsComplement(node)); + regChild = Cudd_Regular(child); + if (Cudd_IsConstant(realChild)) { + /* Found a minterm; count parity and shortest distance + ** from the constant. + */ + if (Cudd_IsComplement(child)) + nodeStat->oddBotDist = 1; + else + nodeStat->evenBotDist = 1; + } else { + /* If node not in table, recur. */ + if (!st_lookup(pathTable, regChild, &nodeStatChild)) { + fprintf(fp, "Something wrong, node in table should have been created in top dist proc.\n"); + return(0); + } + + if (nodeStatChild->oddBotDist == MAXSHORTINT) { + if (nodeStatChild->evenBotDist == MAXSHORTINT) { + if (!CreateBotDist(realChild, pathTable, pathLengthArray, fp)) + return(0); + } else { + fprintf(fp, "Something wrong, both bot nodeStats should be there\n"); + return(0); + } + } + + /* Update shortest distance from the constant depending on + ** parity. */ + + if (Cudd_IsComplement(child)) { + /* If parity on the edge then add 1 to even distance + ** of child to get odd parity distance and add 1 to + ** odd distance of child to get even parity + ** distance. Change distance of current node only if + ** the calculated distance is less than existing + ** distance. */ + if (nodeStatChild->oddBotDist != MAXSHORTINT) + botDist = nodeStatChild->oddBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->evenBotDist > botDist ) + nodeStat->evenBotDist = botDist; + + if (nodeStatChild->evenBotDist != MAXSHORTINT) + botDist = nodeStatChild->evenBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->oddBotDist > botDist) + nodeStat->oddBotDist = botDist; + + } else { + /* If parity on the edge then add 1 to even distance + ** of child to get even parity distance and add 1 to + ** odd distance of child to get odd parity distance. + ** Change distance of current node only if the + ** calculated distance is lesser than existing + ** distance. */ + if (nodeStatChild->evenBotDist != MAXSHORTINT) + botDist = nodeStatChild->evenBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->evenBotDist > botDist) + nodeStat->evenBotDist = botDist; + + if (nodeStatChild->oddBotDist != MAXSHORTINT) + botDist = nodeStatChild->oddBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->oddBotDist > botDist) + nodeStat->oddBotDist = botDist; + } + } /* end of else (if not constant child ) */ + processingDone++; + } /* end of while processing Nv, Nnv */ + + /* Compute shortest path length on the fly. */ + if ((nodeStat->oddTopDist != MAXSHORTINT) && + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + else + oddLen = MAXSHORTINT; + + if ((nodeStat->evenTopDist != MAXSHORTINT) && + (nodeStat->evenBotDist != MAXSHORTINT)) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + else + evenLen = MAXSHORTINT; + + /* Update path length array that has number of nodes of a particular + ** path length. */ + if (oddLen < pathLength ) { + if (pathLength != MAXSHORTINT) + pathLengthArray[pathLength]--; + if (oddLen != MAXSHORTINT) + pathLengthArray[oddLen]++; + pathLength = oddLen; + } + if (evenLen < pathLength ) { + if (pathLength != MAXSHORTINT) + pathLengthArray[pathLength]--; + if (evenLen != MAXSHORTINT) + pathLengthArray[evenLen]++; + } + + return(1); + +} /*end of CreateBotDist */ + + +/**Function******************************************************************** + + Synopsis [ The outer procedure to label each node with its shortest + distance from the root and constant] + + Description [ The outer procedure to label each node with its shortest + distance from the root and constant. Calls CreateTopDist and CreateBotDist. + The basis for computing the distance between root and constant is that + the distance may be the sum of even distances from the node to the root + and constant or the sum of odd distances from the node to the root and + constant. Both CreateTopDist and CreateBotDist create the odd and + even parity distances from the root and constant respectively.] + + SideEffects [None] + + SeeAlso [CreateTopDist CreateBotDist] + +******************************************************************************/ +static st_table * +CreatePathTable( + DdManager *dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */, + DdNode * node /* root of function */, + unsigned int * pathLengthArray /* array of path lengths to store nodes labeled with the various path lengths */, + FILE *fp /* where to write messages */) +{ + + st_table *pathTable; + NodeDist_t *nodeStat; + DdHalfWord topLen; + DdNode *N; + int i, numParents; + int insertValue; + DdNode **childPage; + int parentPage; + int childQueueIndex, parentQueueIndex; + + /* Creating path Table for storing data about nodes */ + pathTable = st_init_table(st_ptrcmp,st_ptrhash); + + /* initializing pages for info about each node */ + gInfo->maxNodeDistPages = INITIAL_PAGES; + gInfo->nodeDistPages = ALLOC(NodeDist_t *, gInfo->maxNodeDistPages); + if (gInfo->nodeDistPages == NULL) { + goto OUT_OF_MEM; + } + gInfo->nodeDistPage = 0; + gInfo->currentNodeDistPage = gInfo->nodeDistPages[gInfo->nodeDistPage] = + ALLOC(NodeDist_t, gInfo->nodeDistPageSize); + if (gInfo->currentNodeDistPage == NULL) { + for (i = 0; i <= gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + goto OUT_OF_MEM; + } + gInfo->nodeDistPageIndex = 0; + + /* Initializing pages for the BFS search queue, implemented as an array. */ + gInfo->maxQueuePages = INITIAL_PAGES; + gInfo->queuePages = ALLOC(DdNode **, gInfo->maxQueuePages); + if (gInfo->queuePages == NULL) { + goto OUT_OF_MEM; + } + gInfo->queuePage = 0; + gInfo->currentQueuePage = gInfo->queuePages[gInfo->queuePage] = + ALLOC(DdNode *, gInfo->queuePageSize); + if (gInfo->currentQueuePage == NULL) { + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + goto OUT_OF_MEM; + } + gInfo->queuePageIndex = 0; + + /* Enter the root node into the queue to start with. */ + parentPage = gInfo->queuePage; + parentQueueIndex = gInfo->queuePageIndex; + topLen = 0; + *(gInfo->currentQueuePage + gInfo->queuePageIndex) = node; + gInfo->queuePageIndex++; + childPage = gInfo->currentQueuePage; + childQueueIndex = gInfo->queuePageIndex; + + N = Cudd_Regular(node); + + if (gInfo->nodeDistPageIndex == gInfo->nodeDistPageSize) ResizeNodeDistPages(dd, gInfo); + if (dd->errorCode == CUDD_MEMORY_OUT) { + for (i = 0; i <= gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + st_free_table(pathTable); + goto OUT_OF_MEM; + } + + nodeStat = gInfo->currentNodeDistPage + gInfo->nodeDistPageIndex; + gInfo->nodeDistPageIndex++; + + nodeStat->oddTopDist = MAXSHORTINT; + nodeStat->evenTopDist = MAXSHORTINT; + nodeStat->evenBotDist = MAXSHORTINT; + nodeStat->oddBotDist = MAXSHORTINT; + nodeStat->regResult = NULL; + nodeStat->compResult = NULL; + + insertValue = st_insert(pathTable, N, nodeStat); + if (insertValue == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i <= gInfo->nodeDistPage; i++) FREE(gInfo->nodeDistPages[i]); + FREE(gInfo->nodeDistPages); + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + st_free_table(pathTable); + goto OUT_OF_MEM; + } else if (insertValue == 1) { + fprintf(fp, "Something wrong, the entry exists but didnt show up in st_lookup\n"); + return(NULL); + } + + if (Cudd_IsComplement(node)) { + nodeStat->oddTopDist = 0; + } else { + nodeStat->evenTopDist = 0; + } + numParents = 1; + /* call the function that counts the distance of each node from the + * root + */ +#ifdef DD_DEBUG + gInfo->numCalls = 0; +#endif + CreateTopDist(dd, gInfo, pathTable, parentPage, parentQueueIndex, (int) topLen, + childPage, childQueueIndex, numParents, fp); + if (dd->errorCode == CUDD_MEMORY_OUT) { + fprintf(fp, "Out of Memory and cant count path lengths\n"); + goto OUT_OF_MEM; + } + +#ifdef DD_DEBUG + gInfo->numCalls = 0; +#endif + /* call the function that counts the distance of each node from the + * constant + */ + if (!CreateBotDist(node, pathTable, pathLengthArray, fp)) return(NULL); + + /* free BFS queue pages as no longer required */ + for (i = 0; i <= gInfo->queuePage; i++) FREE(gInfo->queuePages[i]); + FREE(gInfo->queuePages); + return(pathTable); + +OUT_OF_MEM: + (void) fprintf(fp, "Out of Memory, cannot allocate pages\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + +} /*end of CreatePathTable */ + + +/**Function******************************************************************** + + Synopsis [Chooses the maximum allowable path length of nodes under the + threshold.] + + Description [Chooses the maximum allowable path length under each node. + The corner cases are when the threshold is larger than the number + of nodes in the BDD iself, in which case 'numVars + 1' is returned. + If all nodes of a particular path length are needed, then the + maxpath returned is the next one with excess nodes = 0;] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static unsigned int +AssessPathLength( + unsigned int * pathLengthArray /* array determining number of nodes belonging to the different path lengths */, + int threshold /* threshold to determine maximum allowable nodes in the subset */, + int numVars /* maximum number of variables */, + unsigned int * excess /* number of nodes labeled maxpath required in the subset */, + FILE *fp /* where to write messages */) +{ + unsigned int i, maxpath; + int temp; + + temp = threshold; + i = 0; + maxpath = 0; + /* quit loop if i reaches max number of variables or if temp reaches + * below zero + */ + while ((i < (unsigned) numVars+1) && (temp > 0)) { + if (pathLengthArray[i] > 0) { + maxpath = i; + temp = temp - pathLengthArray[i]; + } + i++; + } + /* if all nodes of max path are needed */ + if (temp >= 0) { + maxpath++; /* now maxpath becomes the next maxppath or max number + of variables */ + *excess = 0; + } else { /* normal case when subset required is less than size of + original BDD */ + *excess = temp + pathLengthArray[maxpath]; + } + + if (maxpath == 0) { + fprintf(fp, "Path Length array seems to be all zeroes, check\n"); + } + return(maxpath); + +} /* end of AssessPathLength */ + + +/**Function******************************************************************** + + Synopsis [Builds the BDD with nodes labeled with path length less than or equal to maxpath] + + Description [Builds the BDD with nodes labeled with path length + under maxpath and as many nodes labeled maxpath as determined by the + threshold. The procedure uses the path table to determine which nodes + in the original bdd need to be retained. This procedure picks a + shortest path (tie break decided by taking the child with the shortest + distance to the constant) and recurs down the path till it reaches the + constant. the procedure then starts building the subset upward from + the constant. All nodes labeled by path lengths less than the given + maxpath are used to build the subset. However, in the case of nodes + that have label equal to maxpath, as many are chosen as required by + the threshold. This number is stored in the info structure in the + field thresholdReached. This field is decremented whenever a node + labeled maxpath is encountered and the nodes labeled maxpath are + aggregated in a maxpath table. As soon as the thresholdReached count + goes to 0, the shortest path from this node to the constant is found. + The extraction of nodes with the above labeling is based on the fact + that each node, labeled with a path length, P, has at least one child + labeled P or less. So extracting all nodes labeled a given path length + P ensures complete paths between the root and the constant. Extraction + of a partial number of nodes with a given path length may result in + incomplete paths and hence the additional number of nodes are grabbed + to complete the path. Since the Bdd is built bottom-up, other nodes + labeled maxpath do lie on complete paths. The procedure may cause the + subset to have a larger or smaller number of nodes than the specified + threshold. The increase in the number of nodes is caused by the + building of a subset and the reduction by recombination. However in + most cases, the recombination overshadows the increase and the + procedure returns a result with lower number of nodes than specified. + The subsetNodeTable is NIL when there is no hard limit on the number + of nodes. Further efforts towards keeping the subset closer to the + threshold number were abandoned in favour of keeping the procedure + simple and fast.] + + SideEffects [SubsetNodeTable is changed if it is not NIL.] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +BuildSubsetBdd( + DdManager * dd /* DD manager */, + GlobalInfo_t *gInfo /* global information */, + st_table * pathTable /* path table with path lengths and computed results */, + DdNode * node /* current node */, + struct AssortedInfo * info /* assorted information structure */, + st_table * subsetNodeTable /* table storing computed results */) +{ + DdNode *N, *Nv, *Nnv; + DdNode *ThenBranch, *ElseBranch, *childBranch; + DdNode *child, *regChild, *regNnv, *regNv; + NodeDist_t *nodeStatNv, *nodeStat, *nodeStatNnv; + DdNode *neW, *topv, *regNew; + char *entry; + unsigned int topid; + unsigned int childPathLength, oddLen, evenLen, NnvPathLength, NvPathLength; + unsigned int NvBotDist, NnvBotDist; + int tiebreakChild; + int processingDone, thenDone, elseDone; + + DdNode *zero = Cudd_Not(DD_ONE(dd)); +#ifdef DD_DEBUG + gInfo->numCalls++; +#endif + if (Cudd_IsConstant(node)) + return(node); + + N = Cudd_Regular(node); + /* Find node in table. */ + if (!st_lookup(pathTable, N, &nodeStat)) { + (void) fprintf(dd->err, "Something wrong, node must be in table \n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + /* If the node in the table has been visited, then return the corresponding + ** Dd. Since a node can become a subset of itself, its + ** complement (that is te same node reached by a different parity) will + ** become a superset of the original node and result in some minterms + ** that were not in the original set. Hence two different results are + ** maintained, corresponding to the odd and even parities. + */ + + /* If this node is reached with an odd parity, get odd parity results. */ + if (Cudd_IsComplement(node)) { + if (nodeStat->compResult != NULL) { +#ifdef DD_DEBUG + gInfo->hits++; +#endif + return(nodeStat->compResult); + } + } else { + /* if this node is reached with an even parity, get even parity + * results + */ + if (nodeStat->regResult != NULL) { +#ifdef DD_DEBUG + gInfo->hits++; +#endif + return(nodeStat->regResult); + } + } + + + /* get children */ + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* no child processed */ + processingDone = 0; + /* then child not processed */ + thenDone = 0; + ThenBranch = NULL; + /* else child not processed */ + elseDone = 0; + ElseBranch = NULL; + /* if then child constant, branch is the child */ + if (Cudd_IsConstant(Nv)) { + /*shortest path found */ + if ((Nv == DD_ONE(dd)) && (info->findShortestPath)) { + info->findShortestPath = 0; + } + + ThenBranch = Nv; + cuddRef(ThenBranch); + if (ThenBranch == NULL) { + return(NULL); + } + + thenDone++; + processingDone++; + NvBotDist = MAXSHORTINT; + } else { + /* Derive regular child for table lookup. */ + regNv = Cudd_Regular(Nv); + /* Get node data for shortest path length. */ + if (!st_lookup(pathTable, regNv, &nodeStatNv) ) { + (void) fprintf(dd->err, "Something wrong, node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + /* Derive shortest path length for child. */ + if ((nodeStatNv->oddTopDist != MAXSHORTINT) && + (nodeStatNv->oddBotDist != MAXSHORTINT)) { + oddLen = (nodeStatNv->oddTopDist + nodeStatNv->oddBotDist); + } else { + oddLen = MAXSHORTINT; + } + + if ((nodeStatNv->evenTopDist != MAXSHORTINT) && + (nodeStatNv->evenBotDist != MAXSHORTINT)) { + evenLen = (nodeStatNv->evenTopDist +nodeStatNv->evenBotDist); + } else { + evenLen = MAXSHORTINT; + } + + NvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; + NvBotDist = (oddLen <= evenLen) ? nodeStatNv->oddBotDist: + nodeStatNv->evenBotDist; + } + /* if else child constant, branch is the child */ + if (Cudd_IsConstant(Nnv)) { + /*shortest path found */ + if ((Nnv == DD_ONE(dd)) && (info->findShortestPath)) { + info->findShortestPath = 0; + } + + ElseBranch = Nnv; + cuddRef(ElseBranch); + if (ElseBranch == NULL) { + return(NULL); + } + + elseDone++; + processingDone++; + NnvBotDist = MAXSHORTINT; + } else { + /* Derive regular child for table lookup. */ + regNnv = Cudd_Regular(Nnv); + /* Get node data for shortest path length. */ + if (!st_lookup(pathTable, regNnv, &nodeStatNnv) ) { + (void) fprintf(dd->err, "Something wrong, node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + /* Derive shortest path length for child. */ + if ((nodeStatNnv->oddTopDist != MAXSHORTINT) && + (nodeStatNnv->oddBotDist != MAXSHORTINT)) { + oddLen = (nodeStatNnv->oddTopDist + nodeStatNnv->oddBotDist); + } else { + oddLen = MAXSHORTINT; + } + + if ((nodeStatNnv->evenTopDist != MAXSHORTINT) && + (nodeStatNnv->evenBotDist != MAXSHORTINT)) { + evenLen = (nodeStatNnv->evenTopDist +nodeStatNnv->evenBotDist); + } else { + evenLen = MAXSHORTINT; + } + + NnvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; + NnvBotDist = (oddLen <= evenLen) ? nodeStatNnv->oddBotDist : + nodeStatNnv->evenBotDist; + } + + tiebreakChild = (NvBotDist <= NnvBotDist) ? 1 : 0; + /* while both children not processed */ + while (processingDone != 2) { + if (!processingDone) { + /* if no child processed */ + /* pick the child with shortest path length and record which one + * picked + */ + if ((NvPathLength < NnvPathLength) || + ((NvPathLength == NnvPathLength) && (tiebreakChild == 1))) { + child = Nv; + regChild = regNv; + thenDone = 1; + childPathLength = NvPathLength; + } else { + child = Nnv; + regChild = regNnv; + elseDone = 1; + childPathLength = NnvPathLength; + } /* then path length less than else path length */ + } else { + /* if one child processed, process the other */ + if (thenDone) { + child = Nnv; + regChild = regNnv; + elseDone = 1; + childPathLength = NnvPathLength; + } else { + child = Nv; + regChild = regNv; + thenDone = 1; + childPathLength = NvPathLength; + } /* end of else pick the Then child if ELSE child processed */ + } /* end of else one child has been processed */ + + /* ignore (replace with constant 0) all nodes which lie on paths larger + * than the maximum length of the path required + */ + if (childPathLength > info->maxpath) { + /* record nodes visited */ + childBranch = zero; + } else { + if (childPathLength < info->maxpath) { + if (info->findShortestPath) { + info->findShortestPath = 0; + } + childBranch = BuildSubsetBdd(dd, gInfo, pathTable, child, info, + subsetNodeTable); + + } else { /* Case: path length of node = maxpath */ + /* If the node labeled with maxpath is found in the + ** maxpathTable, use it to build the subset BDD. */ + if (st_lookup(info->maxpathTable, regChild, &entry)) { + /* When a node that is already been chosen is hit, + ** the quest for a complete path is over. */ + if (info->findShortestPath) { + info->findShortestPath = 0; + } + childBranch = BuildSubsetBdd(dd, gInfo, pathTable, child, info, + subsetNodeTable); + } else { + /* If node is not found in the maxpathTable and + ** the threshold has been reached, then if the + ** path needs to be completed, continue. Else + ** replace the node with a zero. */ + if (info->thresholdReached <= 0) { + if (info->findShortestPath) { + if (st_insert(info->maxpathTable, regChild, + NULL) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + (void) fprintf(dd->err, "OUT of memory\n"); + info->thresholdReached = 0; + childBranch = zero; + } else { + info->thresholdReached--; + childBranch = BuildSubsetBdd(dd, gInfo, pathTable, + child, info,subsetNodeTable); + } + } else { /* not find shortest path, we dont need this + node */ + childBranch = zero; + } + } else { /* Threshold hasn't been reached, + ** need the node. */ + if (st_insert(info->maxpathTable, regChild, + NULL) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + (void) fprintf(dd->err, "OUT of memory\n"); + info->thresholdReached = 0; + childBranch = zero; + } else { + info->thresholdReached--; + if (info->thresholdReached <= 0) { + info->findShortestPath = 1; + } + childBranch = BuildSubsetBdd(dd, gInfo, pathTable, + child, info, subsetNodeTable); + + } /* end of st_insert successful */ + } /* end of threshold hasnt been reached yet */ + } /* end of else node not found in maxpath table */ + } /* end of if (path length of node = maxpath) */ + } /* end if !(childPathLength > maxpath) */ + if (childBranch == NULL) { + /* deref other stuff incase reordering has taken place */ + if (ThenBranch != NULL) { + Cudd_RecursiveDeref(dd, ThenBranch); + ThenBranch = NULL; + } + if (ElseBranch != NULL) { + Cudd_RecursiveDeref(dd, ElseBranch); + ElseBranch = NULL; + } + return(NULL); + } + + cuddRef(childBranch); + + if (child == Nv) { + ThenBranch = childBranch; + } else { + ElseBranch = childBranch; + } + processingDone++; + + } /*end of while processing Nv, Nnv */ + + info->findShortestPath = 0; + topid = Cudd_NodeReadIndex(N); + topv = Cudd_ReadVars(dd, topid); + cuddRef(topv); + neW = cuddBddIteRecur(dd, topv, ThenBranch, ElseBranch); + if (neW != NULL) { + cuddRef(neW); + } + Cudd_RecursiveDeref(dd, topv); + Cudd_RecursiveDeref(dd, ThenBranch); + Cudd_RecursiveDeref(dd, ElseBranch); + + + /* Hard Limit of threshold has been imposed */ + if (subsetNodeTable != NIL(st_table)) { + /* check if a new node is created */ + regNew = Cudd_Regular(neW); + /* subset node table keeps all new nodes that have been created to keep + * a running count of how many nodes have been built in the subset. + */ + if (!st_lookup(subsetNodeTable, regNew, &entry)) { + if (!Cudd_IsConstant(regNew)) { + if (st_insert(subsetNodeTable, regNew, + NULL) == ST_OUT_OF_MEM) { + (void) fprintf(dd->err, "Out of memory\n"); + return (NULL); + } + if (st_count(subsetNodeTable) > info->threshold) { + info->thresholdReached = 0; + } + } + } + } + + + if (neW == NULL) { + return(NULL); + } else { + /*store computed result in regular form*/ + if (Cudd_IsComplement(node)) { + nodeStat->compResult = neW; + cuddRef(nodeStat->compResult); + /* if the new node is the same as the corresponding node in the + * original bdd then its complement need not be computed as it + * cannot be larger than the node itself + */ + if (neW == node) { +#ifdef DD_DEBUG + gInfo->thishit++; +#endif + /* if a result for the node has already been computed, then + * it can only be smaller than teh node itself. hence store + * the node result in order not to break recombination + */ + if (nodeStat->regResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->regResult); + } + nodeStat->regResult = Cudd_Not(neW); + cuddRef(nodeStat->regResult); + } + + } else { + nodeStat->regResult = neW; + cuddRef(nodeStat->regResult); + if (neW == node) { +#ifdef DD_DEBUG + gInfo->thishit++; +#endif + if (nodeStat->compResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->compResult); + } + nodeStat->compResult = Cudd_Not(neW); + cuddRef(nodeStat->compResult); + } + } + + cuddDeref(neW); + return(neW); + } /* end of else i.e. Subset != NULL */ +} /* end of BuildSubsetBdd */ + + +/**Function******************************************************************** + + Synopsis [Procedure to free te result dds stored in the NodeDist pages.] + + Description [None] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static enum st_retval +stPathTableDdFree( + char * key, + char * value, + char * arg) +{ + NodeDist_t *nodeStat; + DdManager *dd; + + nodeStat = (NodeDist_t *)value; + dd = (DdManager *)arg; + if (nodeStat->regResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->regResult); + } + if (nodeStat->compResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->compResult); + } + return(ST_CONTINUE); + +} /* end of stPathTableFree */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSymmetry.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSymmetry.c new file mode 100644 index 000000000..7761949ee --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddSymmetry.c @@ -0,0 +1,1707 @@ +/**CFile*********************************************************************** + + FileName [cuddSymmetry.c] + + PackageName [cudd] + + Synopsis [Functions for symmetry-based variable reordering.] + + Description [External procedures included in this file: +
                          +
                        • Cudd_SymmProfile() +
                        + Internal procedures included in this module: +
                          +
                        • cuddSymmCheck() +
                        • cuddSymmSifting() +
                        • cuddSymmSiftingConv() +
                        + Static procedures included in this module: +
                          +
                        • ddSymmUniqueCompare() +
                        • ddSymmSiftingAux() +
                        • ddSymmSiftingConvAux() +
                        • ddSymmSiftingUp() +
                        • ddSymmSiftingDown() +
                        • ddSymmGroupMove() +
                        • ddSymmGroupMoveBackward() +
                        • ddSymmSiftingBackward() +
                        • ddSymmSummary() +
                        ] + + Author [Shipra Panda, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define MV_OOM (Move *)1 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddSymmetry.c,v 1.28 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int *entry; + +extern int ddTotalNumberSwapping; +#ifdef DD_STATS +extern int ddTotalNISwaps; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddSymmUniqueCompare (int *ptrX, int *ptrY); +static int ddSymmSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static int ddSymmSiftingConvAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddSymmSiftingUp (DdManager *table, int y, int xLow); +static Move * ddSymmSiftingDown (DdManager *table, int x, int xHigh); +static int ddSymmGroupMove (DdManager *table, int x, int y, Move **moves); +static int ddSymmGroupMoveBackward (DdManager *table, int x, int y); +static int ddSymmSiftingBackward (DdManager *table, Move *moves, int size); +static void ddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints statistics on symmetric variables.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +void +Cudd_SymmProfile( + DdManager * table, + int lower, + int upper) +{ + int i,x,gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; + + for (i = lower; i <= upper; i++) { + if (table->subtables[i].next != (unsigned) i) { + x = i; + (void) fprintf(table->out,"Group:"); + do { + (void) fprintf(table->out," %d",table->invperm[x]); + TotalSymm++; + gbot = x; + x = table->subtables[x].next; + } while (x != i); + TotalSymmGroups++; +#ifdef DD_DEBUG + assert(table->subtables[gbot].next == (unsigned) i); +#endif + i = gbot; + (void) fprintf(table->out,"\n"); + } + } + (void) fprintf(table->out,"Total Symmetric = %d\n",TotalSymm); + (void) fprintf(table->out,"Total Groups = %d\n",TotalSymmGroups); + +} /* end of Cudd_SymmProfile */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Checks for symmetry of x and y.] + + Description [Checks for symmetry of x and y. Ignores projection + functions, unless they are isolated. Returns 1 in case of symmetry; 0 + otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddSymmCheck( + DdManager * table, + int x, + int y) +{ + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10; + int comple; /* f0 is complemented */ + int xsymmy; /* x and y may be positively symmetric */ + int xsymmyp; /* x and y may be negatively symmetric */ + int arccount; /* number of arcs from layer x to layer y */ + int TotalRefCount; /* total reference count of layer y minus 1 */ + int yindex; + int i; + DdNodePtr *list; + int slots; + DdNode *sentinel = &(table->sentinel); +#ifdef DD_DEBUG + int xindex; +#endif + + /* Checks that x and y are not the projection functions. + ** For x it is sufficient to check whether there is only one + ** node; indeed, if there is one node, it is the projection function + ** and it cannot point to y. Hence, if y isn't just the projection + ** function, it has one arc coming from a layer different from x. + */ + if (table->subtables[x].keys == 1) { + return(0); + } + yindex = table->invperm[y]; + if (table->subtables[y].keys == 1) { + if (table->vars[yindex]->ref == 1) + return(0); + } + + xsymmy = xsymmyp = 1; + arccount = 0; + slots = table->subtables[x].slots; + list = table->subtables[x].nodelist; + for (i = 0; i < slots; i++) { + f = list[i]; + while (f != sentinel) { + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + f0 = Cudd_Regular(cuddE(f)); + comple = Cudd_IsComplement(cuddE(f)); + if ((int) f1->index == yindex) { + arccount++; + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + if ((int) f0->index != yindex) { + /* If f is an isolated projection function it is + ** allowed to bypass layer y. + */ + if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) + return(0); /* f bypasses layer y */ + } + f11 = f10 = f1; + } + if ((int) f0->index == yindex) { + arccount++; + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + + if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) { + xsymmy &= f01 == f10; + xsymmyp &= f11 == f00; + if ((xsymmy == 0) && (xsymmyp == 0)) + return(0); + } + + f = f->next; + } /* while */ + } /* for */ + + /* Calculate the total reference counts of y */ + TotalRefCount = -1; /* -1 for projection function */ + slots = table->subtables[y].slots; + list = table->subtables[y].nodelist; + for (i = 0; i < slots; i++) { + f = list[i]; + while (f != sentinel) { + TotalRefCount += f->ref; + f = f->next; + } + } + +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (arccount == TotalRefCount) { + xindex = table->invperm[x]; + (void) fprintf(table->out, + "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); + } +#endif + + return(arccount == TotalRefCount); + +} /* end of cuddSymmCheck */ + + +/**Function******************************************************************** + + Synopsis [Symmetric sifting algorithm.] + + Description [Symmetric sifting algorithm. + Assumes that no dead nodes are present. +
                          +
                        1. Order all the variables according to the number of entries in + each unique subtable. +
                        2. Sift the variable up and down, remembering each time the total + size of the DD heap and grouping variables that are symmetric. +
                        3. Select the best permutation. +
                        4. Repeat 3 and 4 for all variables. +
                        + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddSymmSiftingConv] + +******************************************************************************/ +int +cuddSymmSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; + int symvars; + int symgroups; +#ifdef DD_STATS + int previousSize; +#endif + + size = table->size; + + /* Find order in which to sift variables. */ + var = NULL; + entry = ALLOC(int,size); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingOutOfMem; + } + var = ALLOC(int,size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; + } + + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); + + /* Initialize the symmetry of each subtable to itself. */ + for (i = lower; i <= upper; i++) { + table->subtables[i].next = i; + } + + for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + x = table->perm[var[i]]; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + if (x < lower || x > upper) continue; + if (table->subtables[x].next == (unsigned) x) { + result = ddSymmSiftingAux(table,x,lower,upper); + if (!result) goto ddSymmSiftingOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } + + FREE(var); + FREE(entry); + + ddSymmSummary(table, lower, upper, &symvars, &symgroups); + +#ifdef DD_STATS + (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n", + symvars); + (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups", + symgroups); +#endif + + return(1+symvars); + +ddSymmSiftingOutOfMem: + + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddSymmSifting */ + + +/**Function******************************************************************** + + Synopsis [Symmetric sifting to convergence algorithm.] + + Description [Symmetric sifting to convergence algorithm. + Assumes that no dead nodes are present. +
                          +
                        1. Order all the variables according to the number of entries in + each unique subtable. +
                        2. Sift the variable up and down, remembering each time the total + size of the DD heap and grouping variables that are symmetric. +
                        3. Select the best permutation. +
                        4. Repeat 3 and 4 for all variables. +
                        5. Repeat 1-4 until no further improvement. +
                        + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddSymmSifting] + +******************************************************************************/ +int +cuddSymmSiftingConv( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; + int symvars; + int symgroups; + int classes; + int initialSize; +#ifdef DD_STATS + int previousSize; +#endif + + initialSize = table->keys - table->isolated; + + size = table->size; + + /* Find order in which to sift variables. */ + var = NULL; + entry = ALLOC(int,size); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingConvOutOfMem; + } + var = ALLOC(int,size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingConvOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; + } + + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); + + /* Initialize the symmetry of each subtable to itself + ** for first pass of converging symmetric sifting. + */ + for (i = lower; i <= upper; i++) { + table->subtables[i].next = i; + } + + for (i = 0; i < ddMin(table->siftMaxVar, table->size); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + x = table->perm[var[i]]; + if (x < lower || x > upper) continue; + /* Only sift if not in symmetry group already. */ + if (table->subtables[x].next == (unsigned) x) { +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSymmSiftingAux(table,x,lower,upper); + if (!result) goto ddSymmSiftingConvOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } + + /* Sifting now until convergence. */ + while ((unsigned) initialSize > table->keys - table->isolated) { + initialSize = table->keys - table->isolated; +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + /* Here we consider only one representative for each symmetry class. */ + for (x = lower, classes = 0; x <= upper; x++, classes++) { + while ((unsigned) x < table->subtables[x].next) { + x = table->subtables[x].next; + } + /* Here x is the largest index in a group. + ** Groups consist of adjacent variables. + ** Hence, the next increment of x will move it to a new group. + */ + i = table->invperm[x]; + entry[i] = table->subtables[x].keys; + var[classes] = i; + } + + qsort((void *)var,classes,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDyn = 0; /* prevent further reordering */ + break; + } + x = table->perm[var[i]]; + if ((unsigned) x >= table->subtables[x].next) { +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSymmSiftingConvAux(table,x,lower,upper); + if (!result ) goto ddSymmSiftingConvOutOfMem; +#ifdef DD_STATS + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } /* for */ + } + + ddSymmSummary(table, lower, upper, &symvars, &symgroups); + +#ifdef DD_STATS + (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n", + symvars); + (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups", + symgroups); +#endif + + FREE(var); + FREE(entry); + + return(1+symvars); + +ddSymmSiftingConvOutOfMem: + + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddSymmSiftingConv */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the variables + according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmUniqueCompare( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of ddSymmUniqueCompare */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is not part of a symmetry group. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; + int i; + int topbot; /* index to either top or bottom of symmetry group */ + int initGroupSize, finalGroupSize; + + +#ifdef DD_DEBUG + /* check for previously detected symmetry */ + assert(table->subtables[x].next == (unsigned) x); +#endif + + initialSize = table->keys - table->isolated; + + moveDown = NULL; + moveUp = NULL; + + if ((x - xLow) > (xHigh - x)) { + /* Will go down first, unless x == xHigh: + ** Look for consecutive symmetries above x. + */ + for (i = x; i > xLow; i--) { + if (!cuddSymmCheck(table,i-1,i)) + break; + topbot = table->subtables[i-1].next; /* find top of i-1's group */ + table->subtables[i-1].next = i; + table->subtables[x].next = topbot; /* x is bottom of group so its */ + /* next is top of i-1's group */ + i = topbot + 1; /* add 1 for i--; new i is top of symm group */ + } + } else { + /* Will go up first unless x == xlow: + ** Look for consecutive symmetries below x. + */ + for (i = x; i < xHigh; i++) { + if (!cuddSymmCheck(table,i,i+1)) + break; + /* find bottom of i+1's symm group */ + topbot = i + 1; + while ((unsigned) topbot < table->subtables[topbot].next) { + topbot = table->subtables[topbot].next; + } + table->subtables[topbot].next = table->subtables[i].next; + table->subtables[i].next = i + 1; + i = topbot - 1; /* subtract 1 for i++; new i is bottom of group */ + } + } + + /* Now x may be in the middle of a symmetry group. + ** Find bottom of x's symm group. + */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + + if (x == xLow) { /* Sift down */ + +#ifdef DD_DEBUG + /* x must be a singleton */ + assert((unsigned) x == table->subtables[x].next); +#endif + if (x == xHigh) return(1); /* just one variable */ + + initGroupSize = 1; + + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* after this point x --> xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + if (moveDown == NULL) return(1); + + x = moveDown->y; + /* Find bottom of x's group */ + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + finalGroupSize = i - x + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; + + } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ + /* Find top of x's symm group */ + i = x; /* bottom */ + x = table->subtables[x].next; /* top */ + + if (x == xLow) return(1); /* just one big group */ + + initGroupSize = i - x + 1; + + moveUp = ddSymmSiftingUp(table,x,xLow); + /* after this point x --> xLow, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + if (moveUp == NULL) return(1); + + x = moveUp->x; + /* Find top of x's group */ + i = table->subtables[x].next; +#ifdef DD_DEBUG + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + finalGroupSize = x - i + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; /* x is top here */ + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + x = table->subtables[i].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + initGroupSize = i - x + 1; + + moveUp = ddSymmSiftingUp(table,x,xLow); + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + finalGroupSize = x - i + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; + + } else { /* moving up first: shorter */ + /* Find top of x's symmetry group */ + x = table->subtables[x].next; + + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xHigh, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x is bottom of the symmetry group and i is top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + initGroupSize = x - i + 1; + + moveDown = ddSymmSiftingDown(table,x,xHigh); + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + finalGroupSize = i - x + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +ddSymmSiftingAuxOutOfMem: + if (moveDown != MV_OOM) { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + } + if (moveUp != MV_OOM) { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + } + + return(0); + +} /* end of ddSymmSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is either an isolated variable, or it is the bottom of + a symmetry group. All symmetries may not have been found, because of + exceeded growth limit. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmSiftingConvAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; + int i; + int initGroupSize, finalGroupSize; + + + initialSize = table->keys - table->isolated; + + moveDown = NULL; + moveUp = NULL; + + if (x == xLow) { /* Sift down */ +#ifdef DD_DEBUG + /* x is bottom of symmetry group */ + assert((unsigned) x >= table->subtables[x].next); +#endif + i = table->subtables[x].next; + initGroupSize = x - i + 1; + + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + if (moveDown == NULL) return(1); + + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetric group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + finalGroupSize = i - x + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingConvAuxOutOfMem; + + } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ + /* Find top of x's symm group */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = x; /* bottom */ + x = table->subtables[x].next; /* top */ + + if (x == xLow) return(1); + + initGroupSize = i - x + 1; + + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xLow, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + if (moveUp == NULL) return(1); + + x = moveUp->x; + i = table->subtables[x].next; +#ifdef DD_DEBUG + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + finalGroupSize = x - i + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) + goto ddSymmSiftingConvAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = x; + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + initGroupSize = i - x + 1; + + moveUp = ddSymmSiftingUp(table,x,xLow); + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + finalGroupSize = x - i + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) goto ddSymmSiftingConvAuxOutOfMem; + + } else { /* moving up first: shorter */ + /* Find top of x's symmetry group */ + x = table->subtables[x].next; + + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xHigh, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x is bottom of the symmetry group and i is top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); +#endif + initGroupSize = x - i + 1; + + moveDown = ddSymmSiftingDown(table,x,xHigh); + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + x = table->subtables[x].next; + } +#ifdef DD_DEBUG + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); +#endif + finalGroupSize = i - x + 1; + + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingConvAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +ddSymmSiftingConvAuxOutOfMem: + if (moveDown != MV_OOM) { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + } + if (moveUp != MV_OOM) { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + } + + return(0); + +} /* end of ddSymmSiftingConvAux */ + + +/**Function******************************************************************** + + Synopsis [Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much.] + + Description [Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much. Assumes that x is the top + of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; MV_OOM if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSymmSiftingUp( + DdManager * table, + int y, + int xLow) +{ + Move *moves; + Move *move; + int x; + int size; + int i; + int gxtop,gybot; + int limitSize; + int xindex, yindex; + int zindex; + int z; + int isolated; + int L; /* lower bound on DD size */ +#ifdef DD_DEBUG + int checkL; +#endif + + + moves = NULL; + yindex = table->invperm[y]; + + /* Initialize the lower bound. + ** The part of the DD below the bottom of y' group will not change. + ** The part of the DD above y that does not interact with y will not + ** change. The rest may vanish in the best case, except for + ** the nodes at level xLow, which will not vanish, regardless. + */ + limitSize = L = table->keys - table->isolated; + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L -= table->subtables[z].keys - isolated; + } + } + + x = cuddNextLow(table,y); + while (x >= xLow && L <= limitSize) { +#ifdef DD_DEBUG + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + assert(L == checkL); +#endif + gxtop = table->subtables[x].next; + if (cuddSymmCheck(table,x,y)) { + /* Symmetry found, attach symm groups */ + table->subtables[x].next = y; + i = table->subtables[y].next; + while (table->subtables[i].next != (unsigned) y) + i = table->subtables[i].next; + table->subtables[i].next = gxtop; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y have self symmetry */ + xindex = table->invperm[x]; + size = cuddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); +#endif + if (size == 0) goto ddSymmSiftingUpOutOfMem; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSymmSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + } else { /* Group move */ + size = ddSymmGroupMove(table,x,y,&moves); + if (size == 0) goto ddSymmSiftingUpOutOfMem; + /* Update the lower bound. */ + z = moves->y; + do { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L += table->subtables[z].keys - isolated; + } + z = table->subtables[z].next; + } while (z != (int) moves->y); + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + } + y = gxtop; + x = cuddNextLow(table,y); + } + + return(moves); + +ddSymmSiftingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(MV_OOM); + +} /* end of ddSymmSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Moves x down until either it reaches the bound (xHigh) or + the size of the DD heap increases too much.] + + Description [Moves x down until either it reaches the bound (xHigh) + or the size of the DD heap increases too much. Assumes that x is the + bottom of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; MV_OOM if memory is full.] + + SideEffects [None] + +******************************************************************************/ +static Move * +ddSymmSiftingDown( + DdManager * table, + int x, + int xHigh) +{ + Move *moves; + Move *move; + int y; + int size; + int limitSize; + int gxtop,gybot; + int R; /* upper bound on node decrease */ + int xindex, yindex; + int isolated; + int z; + int zindex; +#ifdef DD_DEBUG + int checkR; +#endif + + moves = NULL; + /* Initialize R */ + xindex = table->invperm[x]; + gxtop = table->subtables[x].next; + limitSize = size = table->keys - table->isolated; + R = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } + + y = cuddNextHigh(table,x); + while (y <= xHigh && size - R < limitSize) { +#ifdef DD_DEBUG + gxtop = table->subtables[x].next; + checkR = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + assert(R == checkR); +#endif + gybot = table->subtables[y].next; + while (table->subtables[gybot].next != (unsigned) y) + gybot = table->subtables[gybot].next; + if (cuddSymmCheck(table,x,y)) { + /* Symmetry found, attach symm groups */ + gxtop = table->subtables[x].next; + table->subtables[x].next = y; + table->subtables[gybot].next = gxtop; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y have self symmetry */ + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); +#endif + if (size == 0) goto ddSymmSiftingDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSymmSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + } else { /* Group move */ + /* Update upper bound on node decrease: first phase. */ + gxtop = table->subtables[x].next; + z = gxtop + 1; + do { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R -= table->subtables[z].keys - isolated; + } + z++; + } while (z <= gybot); + size = ddSymmGroupMove(table,x,y,&moves); + if (size == 0) goto ddSymmSiftingDownOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + /* Update upper bound on node decrease: second phase. */ + gxtop = table->subtables[gybot].next; + for (z = gxtop + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } + } + x = gybot; + y = cuddNextHigh(table,x); + } + + return(moves); + +ddSymmSiftingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(MV_OOM); + +} /* end of ddSymmSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Swaps two groups.] + + Description [Swaps two groups. x is assumed to be the bottom variable + of the first group. y is assumed to be the top variable of the second + group. Updates the list of moves. Returns the number of keys in the + table if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmGroupMove( + DdManager * table, + int x, + int y, + Move ** moves) +{ + Move *move; + int size; + int i,j; + int xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + int swapx,swapy; + +#ifdef DD_DEBUG + assert(x < y); /* we assume that x < y */ +#endif + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtables[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtables[ybot].next) + ybot = table->subtables[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + + /* Sift the variables of the second group up through the first group. */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) return(0); + swapx = x; swapy = y; + y = x; + x = y - 1; + } + y = ytop + i; + x = y - 1; + } + + /* fix symmetries */ + y = xtop; /* ytop is now where xtop used to be */ + for (i = 0; i < ysize-1 ; i++) { + table->subtables[y].next = y + 1; + y = y + 1; + } + table->subtables[y].next = xtop; /* y is bottom of its group, join */ + /* its symmetry to top of its group */ + x = y + 1; + newxtop = x; + for (i = 0; i < xsize - 1 ; i++) { + table->subtables[x].next = x + 1; + x = x + 1; + } + table->subtables[x].next = newxtop; /* x is bottom of its group, join */ + /* its symmetry to top of its group */ + /* Store group move */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) return(0); + move->x = swapx; + move->y = swapy; + move->size = size; + move->next = *moves; + *moves = move; + + return(size); + +} /* end of ddSymmGroupMove */ + + +/**Function******************************************************************** + + Synopsis [Undoes the swap of two groups.] + + Description [Undoes the swap of two groups. x is assumed to be the + bottom variable of the first group. y is assumed to be the top + variable of the second group. Returns the number of keys in the table + if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmGroupMoveBackward( + DdManager * table, + int x, + int y) +{ + int size; + int i,j; + int xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + +#ifdef DD_DEBUG + assert(x < y); /* We assume that x < y */ +#endif + + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtables[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtables[ybot].next) + ybot = table->subtables[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + + /* Sift the variables of the second group up through the first group. */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) return(0); + y = x; + x = cuddNextLow(table,y); + } + y = ytop + i; + x = y - 1; + } + + /* Fix symmetries. */ + y = xtop; + for (i = 0; i < ysize-1 ; i++) { + table->subtables[y].next = y + 1; + y = y + 1; + } + table->subtables[y].next = xtop; /* y is bottom of its group, join */ + /* its symmetry to top of its group */ + x = y + 1; + newxtop = x; + for (i = 0; i < xsize-1 ; i++) { + table->subtables[x].next = x + 1; + x = x + 1; + } + table->subtables[x].next = newxtop; /* x is bottom of its group, join */ + /* its symmetry to top of its group */ + + return(size); + +} /* end of ddSymmGroupMoveBackward */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the DD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddSymmSiftingBackward( + DdManager * table, + Move * moves, + int size) +{ + Move *move; + int res; + + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + if (table->subtables[move->x].next == move->x && table->subtables[move->y].next == move->y) { + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); +#ifdef DD_DEBUG + assert(table->subtables[move->x].next == move->x); + assert(table->subtables[move->y].next == move->y); +#endif + } else { /* Group move necessary */ + res = ddSymmGroupMoveBackward(table,(int)move->x,(int)move->y); + } + if (!res) return(0); + } + + return(1); + +} /* end of ddSymmSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Counts numbers of symmetric variables and symmetry + groups.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static void +ddSymmSummary( + DdManager * table, + int lower, + int upper, + int * symvars, + int * symgroups) +{ + int i,x,gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; + + for (i = lower; i <= upper; i++) { + if (table->subtables[i].next != (unsigned) i) { + TotalSymmGroups++; + x = i; + do { + TotalSymm++; + gbot = x; + x = table->subtables[x].next; + } while (x != i); +#ifdef DD_DEBUG + assert(table->subtables[gbot].next == (unsigned) i); +#endif + i = gbot; + } + } + *symvars = TotalSymm; + *symgroups = TotalSymmGroups; + + return; + +} /* end of ddSymmSummary */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddTable.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddTable.c new file mode 100644 index 000000000..b8e989375 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddTable.c @@ -0,0 +1,3213 @@ +/**CFile*********************************************************************** + + FileName [cuddTable.c] + + PackageName [cudd] + + Synopsis [Unique table management functions.] + + Description [External procedures included in this module: +
                          +
                        • Cudd_Prime() +
                        • Cudd_Reserve() +
                        + Internal procedures included in this module: +
                          +
                        • cuddAllocNode() +
                        • cuddInitTable() +
                        • cuddFreeTable() +
                        • cuddGarbageCollect() +
                        • cuddZddGetNode() +
                        • cuddZddGetNodeIVO() +
                        • cuddUniqueInter() +
                        • cuddUniqueInterIVO() +
                        • cuddUniqueInterZdd() +
                        • cuddUniqueConst() +
                        • cuddRehash() +
                        • cuddShrinkSubtable() +
                        • cuddInsertSubtables() +
                        • cuddDestroySubtables() +
                        • cuddResizeTableZdd() +
                        • cuddSlowTableGrowth() +
                        + Static procedures included in this module: +
                          +
                        • ddRehashZdd() +
                        • ddResizeTable() +
                        • cuddFindParent() +
                        • cuddOrderedInsert() +
                        • cuddOrderedThread() +
                        • cuddRotateLeft() +
                        • cuddRotateRight() +
                        • cuddDoRebalance() +
                        • cuddCheckCollisionOrdering() +
                        ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST +/* Constants for red/black trees. */ +#define DD_STACK_SIZE 128 +#define DD_RED 0 +#define DD_BLACK 1 +#define DD_PAGE_SIZE 8192 +#define DD_PAGE_MASK ~(DD_PAGE_SIZE - 1) +#endif +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/* This is a hack for when CUDD_VALUE_TYPE is double */ +typedef union hack { + CUDD_VALUE_TYPE value; + unsigned int bits[2]; +} hack; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.126 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST +/* Macros for red/black trees. */ +#define DD_INSERT_COMPARE(x,y) \ + (((ptruint) (x) & DD_PAGE_MASK) - ((ptruint) (y) & DD_PAGE_MASK)) +#define DD_COLOR(p) ((p)->index) +#define DD_IS_BLACK(p) ((p)->index == DD_BLACK) +#define DD_IS_RED(p) ((p)->index == DD_RED) +#define DD_LEFT(p) cuddT(p) +#define DD_RIGHT(p) cuddE(p) +#define DD_NEXT(p) ((p)->next) +#endif +#endif + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void ddRehashZdd (DdManager *unique, int i); +static int ddResizeTable (DdManager *unique, int index, int amount); +static int cuddFindParent (DdManager *table, DdNode *node); +DD_INLINE static void ddFixLimits (DdManager *unique); +#ifdef DD_RED_BLACK_FREE_LIST +static void cuddOrderedInsert (DdNodePtr *root, DdNodePtr node); +static DdNode * cuddOrderedThread (DdNode *root, DdNode *list); +static void cuddRotateLeft (DdNodePtr *nodeP); +static void cuddRotateRight (DdNodePtr *nodeP); +static void cuddDoRebalance (DdNodePtr **stack, int stackN); +#endif +static void ddPatchTree (DdManager *dd, MtrNode *treenode); +#ifdef DD_DEBUG +static int cuddCheckCollisionOrdering (DdManager *unique, int i, int j); +#endif +static void ddReportRefMess (DdManager *unique, int i, const char *caller); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns the next prime >= p.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +unsigned int +Cudd_Prime( + unsigned int p) +{ + int i,pn; + + p--; + do { + p++; + if (p&1) { + pn = 1; + i = 3; + while ((unsigned) (i * i) <= p) { + if (p % i == 0) { + pn = 0; + break; + } + i += 2; + } + } else { + pn = 0; + } + } while (!pn); + return(p); + +} /* end of Cudd_Prime */ + + +/**Function******************************************************************** + + Synopsis [Expand manager without creating variables.] + + Description [Expand a manager by a specified number of subtables without + actually creating new variables. This function can be used to reduce the + frequency of resizing when an estimate of the number of variables is + available. One would call this function instead of passing the number + of variables to Cudd_Init if variables should not be created right away + of if the estimate on their number became available only after the manager + has been created. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Init] + +******************************************************************************/ +int +Cudd_Reserve( + DdManager *manager, + int amount) +{ + int currentSize = manager->size; + if (amount < 0) + return(0); + if (currentSize + amount < currentSize) /* overflow */ + return(0); + if (amount <= manager->maxSize - manager->size) + return(1); + return ddResizeTable(manager, -1, amount); + +} /* end of Cudd_Reserve */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Fast storage allocation for DdNodes in the table.] + + Description [Fast storage allocation for DdNodes in the table. The + first 4 bytes of a chunk contain a pointer to the next block; the + rest contains DD_MEM_CHUNK spaces for DdNodes. Returns a pointer to + a new node if successful; NULL is memory is full.] + + SideEffects [None] + + SeeAlso [cuddDynamicAllocNode] + +******************************************************************************/ +DdNode * +cuddAllocNode( + DdManager * unique) +{ + int i; + DdNodePtr *mem; + DdNode *list, *node; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (unique->nextFree == NULL) { /* free list is empty */ + /* Check for exceeded limits. */ + if ((unique->keys - unique->dead) + (unique->keysZ - unique->deadZ) > + unique->maxLive) { + unique->errorCode = CUDD_TOO_MANY_NODES; + return(NULL); + } + if (util_cpu_time() - unique->startTime > unique->timeLimit) { + unique->errorCode = CUDD_TIMEOUT_EXPIRED; + return(NULL); + } + if (unique->stash == NULL || unique->memused > unique->maxmemhard) { + (void) cuddGarbageCollect(unique,1); + mem = NULL; + } + if (unique->nextFree == NULL) { + if (unique->memused > unique->maxmemhard) { + unique->errorCode = CUDD_MAX_MEM_EXCEEDED; + return(NULL); + } + /* Try to allocate a new block. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1); + MMoutOfMemory = saveHandler; + if (mem == NULL) { + /* No more memory: Try collecting garbage. If this succeeds, + ** we end up with mem still NULL, but unique->nextFree != + ** NULL. */ + if (cuddGarbageCollect(unique,1) == 0) { + /* Last resort: Free the memory stashed away, if there + ** any. If this succeeeds, mem != NULL and + ** unique->nextFree still NULL. */ + if (unique->stash != NULL) { + FREE(unique->stash); + unique->stash = NULL; + /* Inhibit resizing of tables. */ + cuddSlowTableGrowth(unique); + /* Now try again. */ + mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1); + } + if (mem == NULL) { + /* Out of luck. Call the default handler to do + ** whatever it specifies for a failed malloc. + ** If this handler returns, then set error code, + ** print warning, and return. */ + (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); + unique->errorCode = CUDD_MEMORY_OUT; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "cuddAllocNode: out of memory"); + (void) fprintf(unique->err, "Memory in use = %lu\n", + unique->memused); +#endif + return(NULL); + } + } + } + if (mem != NULL) { /* successful allocation; slice memory */ + ptruint offset; + unique->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); + mem[0] = (DdNodePtr) unique->memoryList; + unique->memoryList = mem; + + /* Here we rely on the fact that a DdNode is as large + ** as 4 pointers. */ + offset = (ptruint) mem & (sizeof(DdNode) - 1); + mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); + assert(((ptruint) mem & (sizeof(DdNode) - 1)) == 0); + list = (DdNode *) mem; + + i = 1; + do { + list[i - 1].ref = 0; + list[i - 1].next = &list[i]; + } while (++i < DD_MEM_CHUNK); + + list[DD_MEM_CHUNK-1].ref = 0; + list[DD_MEM_CHUNK-1].next = NULL; + + unique->nextFree = &list[0]; + } + } + } + unique->allocated++; + node = unique->nextFree; + unique->nextFree = node->next; + return(node); + +} /* end of cuddAllocNode */ + + +/**Function******************************************************************** + + Synopsis [Creates and initializes the unique table.] + + Description [Creates and initializes the unique table. Returns a pointer + to the table if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Init cuddFreeTable] + +******************************************************************************/ +DdManager * +cuddInitTable( + unsigned int numVars /* Initial number of BDD variables (and subtables) */, + unsigned int numVarsZ /* Initial number of ZDD variables (and subtables) */, + unsigned int numSlots /* Initial size of the BDD subtables */, + unsigned int looseUpTo /* Limit for fast table growth */) +{ + DdManager *unique = ALLOC(DdManager,1); + int i, j; + DdNodePtr *nodelist; + DdNode *sentinel; + unsigned int slots; + int shift; + + if (unique == NULL) { + return(NULL); + } + sentinel = &(unique->sentinel); + sentinel->ref = 0; + sentinel->index = 0; + cuddT(sentinel) = NULL; + cuddE(sentinel) = NULL; + sentinel->next = NULL; + unique->epsilon = DD_EPSILON; + unique->size = numVars; + unique->sizeZ = numVarsZ; + unique->maxSize = ddMax(DD_DEFAULT_RESIZE, numVars); + unique->maxSizeZ = ddMax(DD_DEFAULT_RESIZE, numVarsZ); + + /* Adjust the requested number of slots to a power of 2. */ + slots = 8; + while (slots < numSlots) { + slots <<= 1; + } + unique->initSlots = slots; + shift = sizeof(int) * 8 - cuddComputeFloorLog2(slots); + + unique->slots = (numVars + numVarsZ + 1) * slots; + unique->keys = 0; + unique->maxLive = ~0; /* very large number */ + unique->keysZ = 0; + unique->dead = 0; + unique->deadZ = 0; + unique->gcFrac = DD_GC_FRAC_HI; + unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots); + unique->looseUpTo = looseUpTo; + unique->gcEnabled = 1; + unique->allocated = 0; + unique->reclaimed = 0; + unique->subtables = ALLOC(DdSubtable,unique->maxSize); + if (unique->subtables == NULL) { + FREE(unique); + return(NULL); + } + unique->subtableZ = ALLOC(DdSubtable,unique->maxSizeZ); + if (unique->subtableZ == NULL) { + FREE(unique->subtables); + FREE(unique); + return(NULL); + } + unique->perm = ALLOC(int,unique->maxSize); + if (unique->perm == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique); + return(NULL); + } + unique->invperm = ALLOC(int,unique->maxSize); + if (unique->invperm == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique); + return(NULL); + } + unique->permZ = ALLOC(int,unique->maxSizeZ); + if (unique->permZ == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique); + return(NULL); + } + unique->invpermZ = ALLOC(int,unique->maxSizeZ); + if (unique->invpermZ == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique); + return(NULL); + } + unique->map = NULL; + unique->stack = ALLOC(DdNodePtr,ddMax(unique->maxSize,unique->maxSizeZ)+1); + if (unique->stack == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique); + return(NULL); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + +#ifndef DD_NO_DEATH_ROW + unique->deathRowDepth = 1 << cuddComputeFloorLog2(unique->looseUpTo >> 2); + unique->deathRow = ALLOC(DdNodePtr,unique->deathRowDepth); + if (unique->deathRow == NULL) { + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique->stack); + FREE(unique); + return(NULL); + } + for (i = 0; i < unique->deathRowDepth; i++) { + unique->deathRow[i] = NULL; + } + unique->nextDead = 0; + unique->deadMask = unique->deathRowDepth - 1; +#endif + + for (i = 0; (unsigned) i < numVars; i++) { + unique->subtables[i].slots = slots; + unique->subtables[i].shift = shift; + unique->subtables[i].keys = 0; + unique->subtables[i].dead = 0; + unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[i].bindVar = 0; + unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[i].pairIndex = 0; + unique->subtables[i].varHandled = 0; + unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + nodelist = unique->subtables[i].nodelist = ALLOC(DdNodePtr,slots); + if (nodelist == NULL) { + for (j = 0; j < i; j++) { + FREE(unique->subtables[j].nodelist); + } + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique->stack); + FREE(unique); + return(NULL); + } + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = sentinel; + } + unique->perm[i] = i; + unique->invperm[i] = i; + } + for (i = 0; (unsigned) i < numVarsZ; i++) { + unique->subtableZ[i].slots = slots; + unique->subtableZ[i].shift = shift; + unique->subtableZ[i].keys = 0; + unique->subtableZ[i].dead = 0; + unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + nodelist = unique->subtableZ[i].nodelist = ALLOC(DdNodePtr,slots); + if (nodelist == NULL) { + for (j = 0; (unsigned) j < numVars; j++) { + FREE(unique->subtables[j].nodelist); + } + FREE(unique->subtables); + for (j = 0; j < i; j++) { + FREE(unique->subtableZ[j].nodelist); + } + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique->stack); + FREE(unique); + return(NULL); + } + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + unique->permZ[i] = i; + unique->invpermZ[i] = i; + } + unique->constants.slots = slots; + unique->constants.shift = shift; + unique->constants.keys = 0; + unique->constants.dead = 0; + unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + nodelist = unique->constants.nodelist = ALLOC(DdNodePtr,slots); + if (nodelist == NULL) { + for (j = 0; (unsigned) j < numVars; j++) { + FREE(unique->subtables[j].nodelist); + } + FREE(unique->subtables); + for (j = 0; (unsigned) j < numVarsZ; j++) { + FREE(unique->subtableZ[j].nodelist); + } + FREE(unique->subtableZ); + FREE(unique->perm); + FREE(unique->invperm); + FREE(unique->permZ); + FREE(unique->invpermZ); + FREE(unique->stack); + FREE(unique); + return(NULL); + } + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + + unique->memoryList = NULL; + unique->nextFree = NULL; + + unique->memused = sizeof(DdManager) + (unique->maxSize + unique->maxSizeZ) + * (sizeof(DdSubtable) + 2 * sizeof(int)) + (numVars + 1) * + slots * sizeof(DdNodePtr) + + (ddMax(unique->maxSize,unique->maxSizeZ) + 1) * sizeof(DdNodePtr); +#ifndef DD_NO_DEATH_ROW + unique->memused += unique->deathRowDepth * sizeof(DdNodePtr); +#endif + + /* Initialize fields concerned with automatic dynamic reordering. */ + unique->reordered = 0; + unique->reorderings = 0; + unique->maxReorderings = ~0; + unique->siftMaxVar = DD_SIFT_MAX_VAR; + unique->siftMaxSwap = DD_SIFT_MAX_SWAPS; + unique->maxGrowth = DD_MAX_REORDER_GROWTH; + unique->maxGrowthAlt = 2.0 * DD_MAX_REORDER_GROWTH; + unique->reordCycle = 0; /* do not use alternate threshold */ + unique->autoDyn = 0; /* initially disabled */ + unique->autoDynZ = 0; /* initially disabled */ + unique->autoMethod = CUDD_REORDER_SIFT; + unique->autoMethodZ = CUDD_REORDER_SIFT; + unique->realign = 0; /* initially disabled */ + unique->realignZ = 0; /* initially disabled */ + unique->nextDyn = DD_FIRST_REORDER; + unique->countDead = ~0; + unique->tree = NULL; + unique->treeZ = NULL; + unique->groupcheck = CUDD_GROUP_CHECK7; + unique->recomb = DD_DEFAULT_RECOMB; + unique->symmviolation = 0; + unique->arcviolation = 0; + unique->populationSize = 0; + unique->numberXovers = 0; + unique->randomizeOrder = 0; + unique->linear = NULL; + unique->linearSize = 0; + + /* Initialize ZDD universe. */ + unique->univ = (DdNodePtr *)NULL; + + /* Initialize auxiliary fields. */ + unique->localCaches = NULL; + unique->preGCHook = NULL; + unique->postGCHook = NULL; + unique->preReorderingHook = NULL; + unique->postReorderingHook = NULL; + unique->out = stdout; + unique->err = stderr; + unique->errorCode = CUDD_NO_ERROR; + unique->startTime = util_cpu_time(); + unique->timeLimit = ~0UL; + + /* Initialize statistical counters. */ + unique->maxmemhard = ~ 0UL; + unique->garbageCollections = 0; + unique->GCTime = 0; + unique->reordTime = 0; +#ifdef DD_STATS + unique->nodesDropped = 0; + unique->nodesFreed = 0; +#endif + unique->peakLiveNodes = 0; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLookUps = 0; + unique->uniqueLinks = 0; +#endif +#ifdef DD_COUNT + unique->recursiveCalls = 0; + unique->swapSteps = 0; +#ifdef DD_STATS + unique->nextSample = 250000; +#endif +#endif + + return(unique); + +} /* end of cuddInitTable */ + + +/**Function******************************************************************** + + Synopsis [Frees the resources associated to a unique table.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddInitTable] + +******************************************************************************/ +void +cuddFreeTable( + DdManager * unique) +{ + DdNodePtr *next; + DdNodePtr *memlist = unique->memoryList; + int i; + + if (unique->univ != NULL) cuddZddFreeUniv(unique); + while (memlist != NULL) { + next = (DdNodePtr *) memlist[0]; /* link to next block */ + FREE(memlist); + memlist = next; + } + unique->nextFree = NULL; + unique->memoryList = NULL; + + for (i = 0; i < unique->size; i++) { + FREE(unique->subtables[i].nodelist); + } + for (i = 0; i < unique->sizeZ; i++) { + FREE(unique->subtableZ[i].nodelist); + } + FREE(unique->constants.nodelist); + FREE(unique->subtables); + FREE(unique->subtableZ); + FREE(unique->acache); + FREE(unique->perm); + FREE(unique->permZ); + FREE(unique->invperm); + FREE(unique->invpermZ); + FREE(unique->vars); + if (unique->map != NULL) FREE(unique->map); + FREE(unique->stack); +#ifndef DD_NO_DEATH_ROW + FREE(unique->deathRow); +#endif + if (unique->tree != NULL) Mtr_FreeTree(unique->tree); + if (unique->treeZ != NULL) Mtr_FreeTree(unique->treeZ); + if (unique->linear != NULL) FREE(unique->linear); + while (unique->preGCHook != NULL) + Cudd_RemoveHook(unique,unique->preGCHook->f,CUDD_PRE_GC_HOOK); + while (unique->postGCHook != NULL) + Cudd_RemoveHook(unique,unique->postGCHook->f,CUDD_POST_GC_HOOK); + while (unique->preReorderingHook != NULL) + Cudd_RemoveHook(unique,unique->preReorderingHook->f, + CUDD_PRE_REORDERING_HOOK); + while (unique->postReorderingHook != NULL) + Cudd_RemoveHook(unique,unique->postReorderingHook->f, + CUDD_POST_REORDERING_HOOK); + FREE(unique); + +} /* end of cuddFreeTable */ + + +/**Function******************************************************************** + + Synopsis [Performs garbage collection on the unique tables.] + + Description [Performs garbage collection on the BDD and ZDD unique tables. + If clearCache is 0, the cache is not cleared. This should only be + specified if the cache has been cleared right before calling + cuddGarbageCollect. (As in the case of dynamic reordering.) + Returns the total number of deleted nodes.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddGarbageCollect( + DdManager * unique, + int clearCache) +{ + DdHook *hook; + DdCache *cache = unique->cache; + DdNode *sentinel = &(unique->sentinel); + DdNodePtr *nodelist; + int i, j, deleted, totalDeleted, totalDeletedZ; + DdCache *c; + DdNode *node,*next; + DdNodePtr *lastP; + int slots; + unsigned long localTime; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + DdNodePtr tree; +#else + DdNodePtr *memListTrav, *nxtNode; + DdNode *downTrav, *sentry; + int k; +#endif +#endif + +#ifndef DD_NO_DEATH_ROW + cuddClearDeathRow(unique); +#endif + + hook = unique->preGCHook; + while (hook != NULL) { + int res = (hook->f)(unique,"DD",NULL); + if (res == 0) return(0); + hook = hook->next; + } + + if (unique->dead + unique->deadZ == 0) { + hook = unique->postGCHook; + while (hook != NULL) { + int res = (hook->f)(unique,"DD",NULL); + if (res == 0) return(0); + hook = hook->next; + } + return(0); + } + + /* If many nodes are being reclaimed, we want to resize the tables + ** more aggressively, to reduce the frequency of garbage collection. + */ + if (clearCache && unique->gcFrac == DD_GC_FRAC_LO && + unique->slots <= unique->looseUpTo && unique->stash != NULL) { + unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots); +#ifdef DD_VERBOSE + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_HI); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); +#endif + unique->gcFrac = DD_GC_FRAC_HI; + return(0); + } + + localTime = util_cpu_time(); + + unique->garbageCollections++; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "garbage collecting (%d dead BDD nodes out of %d, min %d)...", + unique->dead, unique->keys, unique->minDead); + (void) fprintf(unique->err, + " (%d dead ZDD nodes out of %d)...", + unique->deadZ, unique->keysZ); +#endif + + /* Remove references to garbage collected nodes from the cache. */ + if (clearCache) { + slots = unique->cacheSlots; + for (i = 0; i < slots; i++) { + c = &cache[i]; + if (c->data != NULL) { + if (cuddClean(c->f)->ref == 0 || + cuddClean(c->g)->ref == 0 || + (((ptruint)c->f & 0x2) && Cudd_Regular(c->h)->ref == 0) || + (c->data != DD_NON_CONSTANT && + Cudd_Regular(c->data)->ref == 0)) { + c->data = NULL; + unique->cachedeletions++; + } + } + } + cuddLocalCacheClearDead(unique); + } + + /* Now return dead nodes to free list. Count them for sanity check. */ + totalDeleted = 0; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + tree = NULL; +#endif +#endif + + for (i = 0; i < unique->size; i++) { + if (unique->subtables[i].dead == 0) continue; + nodelist = unique->subtables[i].nodelist; + + deleted = 0; + slots = unique->subtables[i].slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != sentinel) { + next = node->next; + if (node->ref == 0) { + deleted++; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + cuddOrderedInsert(&tree,node); +#endif +#else + cuddDeallocNode(unique,node); +#endif + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = sentinel; + } + if ((unsigned) deleted != unique->subtables[i].dead) { + ddReportRefMess(unique, i, "cuddGarbageCollect"); + } + totalDeleted += deleted; + unique->subtables[i].keys -= deleted; + unique->subtables[i].dead = 0; + } + if (unique->constants.dead != 0) { + nodelist = unique->constants.nodelist; + deleted = 0; + slots = unique->constants.slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != NULL) { + next = node->next; + if (node->ref == 0) { + deleted++; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + cuddOrderedInsert(&tree,node); +#endif +#else + cuddDeallocNode(unique,node); +#endif + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = NULL; + } + if ((unsigned) deleted != unique->constants.dead) { + ddReportRefMess(unique, CUDD_CONST_INDEX, "cuddGarbageCollect"); + } + totalDeleted += deleted; + unique->constants.keys -= deleted; + unique->constants.dead = 0; + } + if ((unsigned) totalDeleted != unique->dead) { + ddReportRefMess(unique, -1, "cuddGarbageCollect"); + } + unique->keys -= totalDeleted; + unique->dead = 0; +#ifdef DD_STATS + unique->nodesFreed += (double) totalDeleted; +#endif + + totalDeletedZ = 0; + + for (i = 0; i < unique->sizeZ; i++) { + if (unique->subtableZ[i].dead == 0) continue; + nodelist = unique->subtableZ[i].nodelist; + + deleted = 0; + slots = unique->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != NULL) { + next = node->next; + if (node->ref == 0) { + deleted++; +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + cuddOrderedInsert(&tree,node); +#endif +#else + cuddDeallocNode(unique,node); +#endif + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = NULL; + } + if ((unsigned) deleted != unique->subtableZ[i].dead) { + ddReportRefMess(unique, i, "cuddGarbageCollect"); + } + totalDeletedZ += deleted; + unique->subtableZ[i].keys -= deleted; + unique->subtableZ[i].dead = 0; + } + + /* No need to examine the constant table for ZDDs. + ** If we did we should be careful not to count whatever dead + ** nodes we found there among the dead ZDD nodes. */ + if ((unsigned) totalDeletedZ != unique->deadZ) { + ddReportRefMess(unique, -1, "cuddGarbageCollect"); + } + unique->keysZ -= totalDeletedZ; + unique->deadZ = 0; +#ifdef DD_STATS + unique->nodesFreed += (double) totalDeletedZ; +#endif + + +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST + unique->nextFree = cuddOrderedThread(tree,unique->nextFree); +#else + memListTrav = unique->memoryList; + sentry = NULL; + while (memListTrav != NULL) { + ptruint offset; + nxtNode = (DdNodePtr *)memListTrav[0]; + offset = (ptruint) memListTrav & (sizeof(DdNode) - 1); + memListTrav += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); + downTrav = (DdNode *)memListTrav; + k = 0; + do { + if (downTrav[k].ref == 0) { + if (sentry == NULL) { + unique->nextFree = sentry = &downTrav[k]; + } else { + /* First hook sentry->next to the dead node and then + ** reassign sentry to the dead node. */ + sentry = (sentry->next = &downTrav[k]); + } + } + } while (++k < DD_MEM_CHUNK); + memListTrav = nxtNode; + } + sentry->next = NULL; +#endif +#endif + + unique->GCTime += util_cpu_time() - localTime; + + hook = unique->postGCHook; + while (hook != NULL) { + int res = (hook->f)(unique,"DD",NULL); + if (res == 0) return(0); + hook = hook->next; + } + +#ifdef DD_VERBOSE + (void) fprintf(unique->err," done\n"); +#endif + + return(totalDeleted+totalDeletedZ); + +} /* end of cuddGarbageCollect */ + + +/**Function******************************************************************** + + Synopsis [Wrapper for cuddUniqueInterZdd.] + + Description [Wrapper for cuddUniqueInterZdd, which applies the ZDD + reduction rule. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted.] + + SideEffects [None] + + SeeAlso [cuddUniqueInterZdd] + +******************************************************************************/ +DdNode * +cuddZddGetNode( + DdManager * zdd, + int id, + DdNode * T, + DdNode * E) +{ + DdNode *node; + + if (T == DD_ZERO(zdd)) + return(E); + node = cuddUniqueInterZdd(zdd, id, T, E); + return(node); + +} /* end of cuddZddGetNode */ + + +/**Function******************************************************************** + + Synopsis [Wrapper for cuddUniqueInterZdd that is independent of variable + ordering.] + + Description [Wrapper for cuddUniqueInterZdd that is independent of + variable ordering (IVO). This function does not require parameter + index to precede the indices of the top nodes of g and h in the + variable order. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted.] + + SideEffects [None] + + SeeAlso [cuddZddGetNode cuddZddIsop] + +******************************************************************************/ +DdNode * +cuddZddGetNodeIVO( + DdManager * dd, + int index, + DdNode * g, + DdNode * h) +{ + DdNode *f, *r, *t; + DdNode *zdd_one = DD_ONE(dd); + DdNode *zdd_zero = DD_ZERO(dd); + + f = cuddUniqueInterZdd(dd, index, zdd_one, zdd_zero); + if (f == NULL) { + return(NULL); + } + cuddRef(f); + t = cuddZddProduct(dd, f, g); + if (t == NULL) { + Cudd_RecursiveDerefZdd(dd, f); + return(NULL); + } + cuddRef(t); + Cudd_RecursiveDerefZdd(dd, f); + r = cuddZddUnion(dd, t, h); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, t); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDerefZdd(dd, t); + + cuddDeref(r); + return(r); + +} /* end of cuddZddGetNodeIVO */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for the existence of an internal node.] + + Description [Checks the unique table for the existence of an internal + node. If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. For a newly + created node, increments the reference counts of what T and E point + to. Returns a pointer to the new node if successful; NULL if memory + is exhausted or if reordering took place.] + + SideEffects [None] + + SeeAlso [cuddUniqueInterZdd] + +******************************************************************************/ +DdNode * +cuddUniqueInter( + DdManager * unique, + int index, + DdNode * T, + DdNode * E) +{ + int pos; + unsigned int level; + int retval; + DdNodePtr *nodelist; + DdNode *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int gcNumber; + +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLookUps++; +#endif + + if ((0x1ffffUL & (unsigned long) unique->cacheMisses) == 0) { + if (util_cpu_time() - unique->startTime > unique->timeLimit) { + unique->errorCode = CUDD_TIMEOUT_EXPIRED; + return(NULL); + } + } + if (index >= unique->size) { + int amount = ddMax(DD_DEFAULT_RESIZE,unique->size/20); + if (!ddResizeTable(unique,index,amount)) return(NULL); + } + + level = unique->perm[index]; + subtable = &(unique->subtables[level]); + +#ifdef DD_DEBUG + assert(level < (unsigned) cuddI(unique,T->index)); + assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index)); +#endif + + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + while (T == cuddT(looking) && E < cuddE(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + if (T == cuddT(looking) && E == cuddE(looking)) { + if (looking->ref == 0) { + cuddReclaim(unique,looking); + } + return(looking); + } + + /* countDead is 0 if deads should be counted and ~0 if they should not. */ + if (unique->autoDyn && + unique->keys - (unique->dead & unique->countDead) >= unique->nextDyn && + unique->maxReorderings > 0) { + unsigned long cpuTime; +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(unique); + if (retval != 0) return(NULL); + retval = Cudd_CheckKeys(unique); + if (retval != 0) return(NULL); +#endif + retval = Cudd_ReduceHeap(unique,unique->autoMethod,10); /* 10 = whatever */ + unique->maxReorderings--; + if (retval == 0) { + unique->reordered = 2; + } else if ((cpuTime = util_cpu_time()) - unique->startTime > unique->timeLimit) { + unique->errorCode = CUDD_TIMEOUT_EXPIRED; + unique->reordered = 0; + } else if (unique->timeLimit - (cpuTime - unique->startTime) + < unique->reordTime) { + unique->autoDyn = 0; + } +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(unique); + if (retval != 0) unique->reordered = 2; + retval = Cudd_CheckKeys(unique); + if (retval != 0) unique->reordered = 2; +#endif + return(NULL); + } + + if (subtable->keys > subtable->maxKeys) { + if (unique->gcEnabled && + ((unique->dead > unique->minDead) || + ((unique->dead > unique->minDead / 2) && + (subtable->dead > subtable->keys * 0.95)))) { /* too many dead */ + if (util_cpu_time() - unique->startTime > unique->timeLimit) { + unique->errorCode = CUDD_TIMEOUT_EXPIRED; + return(NULL); + } + (void) cuddGarbageCollect(unique,1); + } else { + cuddRehash(unique,(int)level); + } + /* Update pointer to insertion point. In the case of rehashing, + ** the slot may have changed. In the case of garbage collection, + ** the predecessor may have been dead. */ + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + while (T == cuddT(looking) && E < cuddE(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + } + + gcNumber = unique->garbageCollections; + looking = cuddAllocNode(unique); + if (looking == NULL) { + return(NULL); + } + unique->keys++; + subtable->keys++; + + if (gcNumber != unique->garbageCollections) { + DdNode *looking2; + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + previousP = &(nodelist[pos]); + looking2 = *previousP; + + while (T < cuddT(looking2)) { + previousP = &(looking2->next); + looking2 = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + while (T == cuddT(looking2) && E < cuddE(looking2)) { + previousP = &(looking2->next); + looking2 = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + } + looking->index = index; + cuddT(looking) = T; + cuddE(looking) = E; + looking->next = *previousP; + *previousP = looking; + cuddSatInc(T->ref); /* we know T is a regular pointer */ + cuddRef(E); + +#ifdef DD_DEBUG + cuddCheckCollisionOrdering(unique,level,pos); +#endif + + return(looking); + +} /* end of cuddUniqueInter */ + + +/**Function******************************************************************** + + Synopsis [Wrapper for cuddUniqueInter that is independent of variable + ordering.] + + Description [Wrapper for cuddUniqueInter that is independent of + variable ordering (IVO). This function does not require parameter + index to precede the indices of the top nodes of T and E in the + variable order. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted.] + + SideEffects [None] + + SeeAlso [cuddUniqueInter Cudd_MakeBddFromZddCover] + +******************************************************************************/ +DdNode * +cuddUniqueInterIVO( + DdManager * unique, + int index, + DdNode * T, + DdNode * E) +{ + DdNode *result; + DdNode *v; + + v = cuddUniqueInter(unique, index, DD_ONE(unique), + Cudd_Not(DD_ONE(unique))); + if (v == NULL) + return(NULL); + /* Since v is a projection function, we can skip the call to cuddRef. */ + result = cuddBddIteRecur(unique, v, T, E); + return(result); + +} /* end of cuddUniqueInterIVO */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for the existence of an internal + ZDD node.] + + Description [Checks the unique table for the existence of an internal + ZDD node. If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. For a newly + created node, increments the reference counts of what T and E point + to. Returns a pointer to the new node if successful; NULL if memory + is exhausted or if reordering took place.] + + SideEffects [None] + + SeeAlso [cuddUniqueInter] + +******************************************************************************/ +DdNode * +cuddUniqueInterZdd( + DdManager * unique, + int index, + DdNode * T, + DdNode * E) +{ + int pos; + unsigned int level; + int retval; + DdNodePtr *nodelist; + DdNode *looking; + DdSubtable *subtable; + +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLookUps++; +#endif + + if (index >= unique->sizeZ) { + if (!cuddResizeTableZdd(unique,index)) return(NULL); + } + + level = unique->permZ[index]; + subtable = &(unique->subtableZ[level]); + +#ifdef DD_DEBUG + assert(level < (unsigned) cuddIZ(unique,T->index)); + assert(level < (unsigned) cuddIZ(unique,Cudd_Regular(E)->index)); +#endif + + if (subtable->keys > subtable->maxKeys) { + if (unique->gcEnabled && ((unique->deadZ > unique->minDead) || + (10 * subtable->dead > 9 * subtable->keys))) { /* too many dead */ + (void) cuddGarbageCollect(unique,1); + } else { + ddRehashZdd(unique,(int)level); + } + } + + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + looking = nodelist[pos]; + + while (looking != NULL) { + if (cuddT(looking) == T && cuddE(looking) == E) { + if (looking->ref == 0) { + cuddReclaimZdd(unique,looking); + } + return(looking); + } + looking = looking->next; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + + /* countDead is 0 if deads should be counted and ~0 if they should not. */ + if (unique->autoDynZ && + unique->keysZ - (unique->deadZ & unique->countDead) >= unique->nextDyn) { +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(unique); + if (retval != 0) return(NULL); + retval = Cudd_CheckKeys(unique); + if (retval != 0) return(NULL); +#endif + retval = Cudd_zddReduceHeap(unique,unique->autoMethodZ,10); /* 10 = whatever */ + if (retval == 0) unique->reordered = 2; +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(unique); + if (retval != 0) unique->reordered = 2; + retval = Cudd_CheckKeys(unique); + if (retval != 0) unique->reordered = 2; +#endif + return(NULL); + } + + unique->keysZ++; + subtable->keys++; + + looking = cuddAllocNode(unique); + if (looking == NULL) return(NULL); + looking->index = index; + cuddT(looking) = T; + cuddE(looking) = E; + looking->next = nodelist[pos]; + nodelist[pos] = looking; + cuddRef(T); + cuddRef(E); + + return(looking); + +} /* end of cuddUniqueInterZdd */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for the existence of a constant node.] + + Description [Checks the unique table for the existence of a constant node. + If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. Returns a + pointer to the new node.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddUniqueConst( + DdManager * unique, + CUDD_VALUE_TYPE value) +{ + int pos; + DdNodePtr *nodelist; + DdNode *looking; + hack split; + +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLookUps++; +#endif + + if (unique->constants.keys > unique->constants.maxKeys) { + if (unique->gcEnabled && ((unique->dead > unique->minDead) || + (10 * unique->constants.dead > 9 * unique->constants.keys))) { /* too many dead */ + (void) cuddGarbageCollect(unique,1); + } else { + cuddRehash(unique,CUDD_CONST_INDEX); + } + } + + cuddAdjust(value); /* for the case of crippled infinities */ + + if (ddAbs(value) < unique->epsilon) { + value = 0.0; + } + split.value = value; + + pos = ddHash(split.bits[0], split.bits[1], unique->constants.shift); + nodelist = unique->constants.nodelist; + looking = nodelist[pos]; + + /* Here we compare values both for equality and for difference less + * than epsilon. The first comparison is required when values are + * infinite, since Infinity - Infinity is NaN and NaN < X is 0 for + * every X. + */ + while (looking != NULL) { + if (looking->type.value == value || + ddEqualVal(looking->type.value,value,unique->epsilon)) { + if (looking->ref == 0) { + cuddReclaim(unique,looking); + } + return(looking); + } + looking = looking->next; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + + unique->keys++; + unique->constants.keys++; + + looking = cuddAllocNode(unique); + if (looking == NULL) return(NULL); + looking->index = CUDD_CONST_INDEX; + looking->type.value = value; + looking->next = nodelist[pos]; + nodelist[pos] = looking; + + return(looking); + +} /* end of cuddUniqueConst */ + + +/**Function******************************************************************** + + Synopsis [Rehashes a unique subtable.] + + Description [Doubles the size of a unique subtable and rehashes its + contents.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddRehash( + DdManager * unique, + int i) +{ + unsigned int slots, oldslots; + int shift, oldshift; + int j, pos; + DdNodePtr *nodelist, *oldnodelist; + DdNode *node, *next; + DdNode *sentinel = &(unique->sentinel); + hack split; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (unique->gcFrac == DD_GC_FRAC_HI && unique->slots > unique->looseUpTo) { + unique->gcFrac = DD_GC_FRAC_LO; + unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); +#ifdef DD_VERBOSE + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_LO); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); +#endif + } + + if (unique->gcFrac != DD_GC_FRAC_MIN && unique->memused > unique->maxmem) { + unique->gcFrac = DD_GC_FRAC_MIN; + unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots); +#ifdef DD_VERBOSE + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_MIN); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); +#endif + cuddShrinkDeathRow(unique); + if (cuddGarbageCollect(unique,1) > 0) return; + } + + if (i != CUDD_CONST_INDEX) { + oldslots = unique->subtables[i].slots; + oldshift = unique->subtables[i].shift; + oldnodelist = unique->subtables[i].nodelist; + + /* Compute the new size of the subtable. */ + slots = oldslots << 1; + shift = oldshift - 1; + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + (void) fprintf(unique->err, + "Unable to resize subtable %d for lack of memory\n", + i); + /* Prevent frequent resizing attempts. */ + (void) cuddGarbageCollect(unique,1); + if (unique->stash != NULL) { + FREE(unique->stash); + unique->stash = NULL; + /* Inhibit resizing of tables. */ + cuddSlowTableGrowth(unique); + } + return; + } + unique->subtables[i].nodelist = nodelist; + unique->subtables[i].slots = slots; + unique->subtables[i].shift = shift; + unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + + /* Move the nodes from the old table to the new table. + ** This code depends on the type of hash function. + ** It assumes that the effect of doubling the size of the table + ** is to retain one more bit of the 32-bit hash value. + ** The additional bit is the LSB. */ + for (j = 0; (unsigned) j < oldslots; j++) { + DdNodePtr *evenP, *oddP; + node = oldnodelist[j]; + evenP = &(nodelist[j<<1]); + oddP = &(nodelist[(j<<1)+1]); + while (node != sentinel) { + next = node->next; + pos = ddHash(cuddT(node), cuddE(node), shift); + if (pos & 1) { + *oddP = node; + oddP = &(node->next); + } else { + *evenP = node; + evenP = &(node->next); + } + node = next; + } + *evenP = *oddP = sentinel; + } + FREE(oldnodelist); + +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "rehashing layer %d: keys %d dead %d new size %d\n", + i, unique->subtables[i].keys, + unique->subtables[i].dead, slots); +#endif + } else { + oldslots = unique->constants.slots; + oldshift = unique->constants.shift; + oldnodelist = unique->constants.nodelist; + + /* The constant subtable is never subjected to reordering. + ** Therefore, when it is resized, it is because it has just + ** reached the maximum load. We can safely just double the size, + ** with no need for the loop we use for the other tables. + */ + slots = oldslots << 1; + shift = oldshift - 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + (void) fprintf(unique->err, + "Unable to resize constant subtable for lack of memory\n"); + (void) cuddGarbageCollect(unique,1); + for (j = 0; j < unique->size; j++) { + unique->subtables[j].maxKeys <<= 1; + } + unique->constants.maxKeys <<= 1; + return; + } + unique->constants.slots = slots; + unique->constants.shift = shift; + unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + unique->constants.nodelist = nodelist; + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + split.value = cuddV(node); + pos = ddHash(split.bits[0], split.bits[1], shift); + node->next = nodelist[pos]; + nodelist[pos] = node; + node = next; + } + } + FREE(oldnodelist); + +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "rehashing constants: keys %d dead %d new size %d\n", + unique->constants.keys,unique->constants.dead,slots); +#endif + } + + /* Update global data */ + + unique->memused += (slots - oldslots) * sizeof(DdNodePtr); + unique->slots += (slots - oldslots); + ddFixLimits(unique); + +} /* end of cuddRehash */ + + +/**Function******************************************************************** + + Synopsis [Shrinks a subtable.] + + Description [Shrinks a subtable.] + + SideEffects [None] + + SeeAlso [cuddRehash] + +******************************************************************************/ +void +cuddShrinkSubtable( + DdManager *unique, + int i) +{ + int j; + int shift, posn; + DdNodePtr *nodelist, *oldnodelist; + DdNode *node, *next; + DdNode *sentinel = &(unique->sentinel); + unsigned int slots, oldslots; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + oldnodelist = unique->subtables[i].nodelist; + oldslots = unique->subtables[i].slots; + slots = oldslots >> 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + return; + } + unique->subtables[i].nodelist = nodelist; + unique->subtables[i].slots = slots; + unique->subtables[i].shift++; + unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "shrunk layer %d (%d keys) from %d to %d slots\n", + i, unique->subtables[i].keys, oldslots, slots); +#endif + + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = sentinel; + } + shift = unique->subtables[i].shift; + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != sentinel) { + DdNode *looking, *T, *E; + DdNodePtr *previousP; + next = node->next; + posn = ddHash(cuddT(node), cuddE(node), shift); + previousP = &(nodelist[posn]); + looking = *previousP; + T = cuddT(node); + E = cuddE(node); + while (T < cuddT(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + while (T == cuddT(looking) && E < cuddE(looking)) { + previousP = &(looking->next); + looking = *previousP; +#ifdef DD_UNIQUE_PROFILE + unique->uniqueLinks++; +#endif + } + node->next = *previousP; + *previousP = node; + node = next; + } + } + FREE(oldnodelist); + + unique->memused += ((long) slots - (long) oldslots) * sizeof(DdNode *); + unique->slots += slots - oldslots; + unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); + unique->cacheSlack = (int) + ddMin(unique->maxCacheHard,DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) + - 2 * (int) unique->cacheSlots; + +} /* end of cuddShrinkSubtable */ + + +/**Function******************************************************************** + + Synopsis [Inserts n new subtables in a unique table at level.] + + Description [Inserts n new subtables in a unique table at level. + The number n should be positive, and level should be an existing level. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddDestroySubtables] + +******************************************************************************/ +int +cuddInsertSubtables( + DdManager * unique, + int n, + int level) +{ + DdSubtable *newsubtables; + DdNodePtr *newnodelist; + DdNodePtr *newvars; + DdNode *sentinel = &(unique->sentinel); + int oldsize,newsize; + int i,j,index,reorderSave; + unsigned int numSlots = unique->initSlots; + int *newperm, *newinvperm, *newmap; + DdNode *one, *zero; + +#ifdef DD_DEBUG + assert(n > 0 && level < unique->size); +#endif + + oldsize = unique->size; + /* Easy case: there is still room in the current table. */ + if (oldsize + n <= unique->maxSize) { + /* Shift the tables at and below level. */ + for (i = oldsize - 1; i >= level; i--) { + unique->subtables[i+n].slots = unique->subtables[i].slots; + unique->subtables[i+n].shift = unique->subtables[i].shift; + unique->subtables[i+n].keys = unique->subtables[i].keys; + unique->subtables[i+n].maxKeys = unique->subtables[i].maxKeys; + unique->subtables[i+n].dead = unique->subtables[i].dead; + unique->subtables[i+n].nodelist = unique->subtables[i].nodelist; + unique->subtables[i+n].bindVar = unique->subtables[i].bindVar; + unique->subtables[i+n].varType = unique->subtables[i].varType; + unique->subtables[i+n].pairIndex = unique->subtables[i].pairIndex; + unique->subtables[i+n].varHandled = unique->subtables[i].varHandled; + unique->subtables[i+n].varToBeGrouped = + unique->subtables[i].varToBeGrouped; + + index = unique->invperm[i]; + unique->invperm[i+n] = index; + unique->perm[index] += n; + } + /* Create new subtables. */ + for (i = 0; i < n; i++) { + unique->subtables[level+i].slots = numSlots; + unique->subtables[level+i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtables[level+i].keys = 0; + unique->subtables[level+i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[level+i].dead = 0; + unique->subtables[level+i].bindVar = 0; + unique->subtables[level+i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[level+i].pairIndex = 0; + unique->subtables[level+i].varHandled = 0; + unique->subtables[level+i].varToBeGrouped = CUDD_LAZY_NONE; + + unique->perm[oldsize+i] = level + i; + unique->invperm[level+i] = oldsize + i; + newnodelist = unique->subtables[level+i].nodelist = + ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + if (unique->map != NULL) { + for (i = 0; i < n; i++) { + unique->map[oldsize+i] = oldsize + i; + } + } + } else { + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables. + */ + newsize = oldsize + n + DD_DEFAULT_RESIZE; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "Increasing the table size from %d to %d\n", + unique->maxSize, newsize); +#endif + /* Allocate memory for new arrays (except nodelists). */ + newsubtables = ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newvars = ALLOC(DdNodePtr,newsize); + if (newvars == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + FREE(newsubtables); + return(0); + } + newperm = ALLOC(int,newsize); + if (newperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + FREE(newsubtables); + FREE(newvars); + return(0); + } + newinvperm = ALLOC(int,newsize); + if (newinvperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + return(0); + } + if (unique->map != NULL) { + newmap = ALLOC(int,newsize); + if (newmap == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + FREE(newinvperm); + return(0); + } + unique->memused += (newsize - unique->maxSize) * sizeof(int); + } + unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + /* Copy levels before insertion points from old tables. */ + for (i = 0; i < level; i++) { + newsubtables[i].slots = unique->subtables[i].slots; + newsubtables[i].shift = unique->subtables[i].shift; + newsubtables[i].keys = unique->subtables[i].keys; + newsubtables[i].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i].dead = unique->subtables[i].dead; + newsubtables[i].nodelist = unique->subtables[i].nodelist; + newsubtables[i].bindVar = unique->subtables[i].bindVar; + newsubtables[i].varType = unique->subtables[i].varType; + newsubtables[i].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i].varHandled = unique->subtables[i].varHandled; + newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + newperm[i] = unique->perm[i]; + newinvperm[i] = unique->invperm[i]; + } + /* Finish initializing permutation for new table to old one. */ + for (i = level; i < oldsize; i++) { + newperm[i] = unique->perm[i]; + } + /* Initialize new levels. */ + for (i = level; i < level + n; i++) { + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newsubtables[i].bindVar = 0; + newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + newsubtables[i].pairIndex = 0; + newsubtables[i].varHandled = 0; + newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + newperm[oldsize + i - level] = i; + newinvperm[i] = oldsize + i - level; + newnodelist = newsubtables[i].nodelist = ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + /* We are going to leak some memory. We should clean up. */ + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + /* Copy the old tables for levels past the insertion point. */ + for (i = level; i < oldsize; i++) { + newsubtables[i+n].slots = unique->subtables[i].slots; + newsubtables[i+n].shift = unique->subtables[i].shift; + newsubtables[i+n].keys = unique->subtables[i].keys; + newsubtables[i+n].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i+n].dead = unique->subtables[i].dead; + newsubtables[i+n].nodelist = unique->subtables[i].nodelist; + newsubtables[i+n].bindVar = unique->subtables[i].bindVar; + newsubtables[i+n].varType = unique->subtables[i].varType; + newsubtables[i+n].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i+n].varHandled = unique->subtables[i].varHandled; + newsubtables[i+n].varToBeGrouped = + unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + index = unique->invperm[i]; + newinvperm[i+n] = index; + newperm[index] += n; + } + /* Update the map. */ + if (unique->map != NULL) { + for (i = 0; i < oldsize; i++) { + newmap[i] = unique->map[i]; + } + for (i = oldsize; i < oldsize + n; i++) { + newmap[i] = i; + } + FREE(unique->map); + unique->map = newmap; + } + /* Install the new tables and free the old ones. */ + FREE(unique->subtables); + unique->subtables = newsubtables; + unique->maxSize = newsize; + FREE(unique->vars); + unique->vars = newvars; + FREE(unique->perm); + unique->perm = newperm; + FREE(unique->invperm); + unique->invperm = newinvperm; + /* Update the stack for iterative procedures. */ + if (newsize > unique->maxSizeZ) { + FREE(unique->stack); + unique->stack = ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); + } + } + /* Update manager parameters to account for the new subtables. */ + unique->slots += n * numSlots; + ddFixLimits(unique); + unique->size += n; + + /* Now that the table is in a coherent state, create the new + ** projection functions. We need to temporarily disable reordering, + ** because we cannot reorder without projection functions in place. + **/ + one = unique->one; + zero = Cudd_Not(one); + + reorderSave = unique->autoDyn; + unique->autoDyn = 0; + for (i = oldsize; i < oldsize + n; i++) { + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) { + unique->autoDyn = reorderSave; + /* Shift everything back so table remains coherent. */ + for (j = oldsize; j < i; j++) { + Cudd_IterDerefBdd(unique,unique->vars[j]); + cuddDeallocNode(unique,unique->vars[j]); + unique->vars[j] = NULL; + } + for (j = level; j < oldsize; j++) { + unique->subtables[j].slots = unique->subtables[j+n].slots; + unique->subtables[j].slots = unique->subtables[j+n].slots; + unique->subtables[j].shift = unique->subtables[j+n].shift; + unique->subtables[j].keys = unique->subtables[j+n].keys; + unique->subtables[j].maxKeys = + unique->subtables[j+n].maxKeys; + unique->subtables[j].dead = unique->subtables[j+n].dead; + FREE(unique->subtables[j].nodelist); + unique->subtables[j].nodelist = + unique->subtables[j+n].nodelist; + unique->subtables[j+n].nodelist = NULL; + unique->subtables[j].bindVar = + unique->subtables[j+n].bindVar; + unique->subtables[j].varType = + unique->subtables[j+n].varType; + unique->subtables[j].pairIndex = + unique->subtables[j+n].pairIndex; + unique->subtables[j].varHandled = + unique->subtables[j+n].varHandled; + unique->subtables[j].varToBeGrouped = + unique->subtables[j+n].varToBeGrouped; + index = unique->invperm[j+n]; + unique->invperm[j] = index; + unique->perm[index] -= n; + } + unique->size = oldsize; + unique->slots -= n * numSlots; + ddFixLimits(unique); + (void) Cudd_DebugCheck(unique); + return(0); + } + cuddRef(unique->vars[i]); + } + if (unique->tree != NULL) { + unique->tree->size += n; + unique->tree->index = unique->invperm[0]; + ddPatchTree(unique,unique->tree); + } + unique->autoDyn = reorderSave; + + return(1); + +} /* end of cuddInsertSubtables */ + + +/**Function******************************************************************** + + Synopsis [Destroys the n most recently created subtables in a unique table.] + + Description [Destroys the n most recently created subtables in a unique + table. n should be positive. The subtables should not contain any live + nodes, except the (isolated) projection function. The projection + functions are freed. Returns 1 if successful; 0 otherwise.] + + SideEffects [The variable map used for fast variable substitution is + destroyed if it exists. In this case the cache is also cleared.] + + SeeAlso [cuddInsertSubtables Cudd_SetVarMap] + +******************************************************************************/ +int +cuddDestroySubtables( + DdManager * unique, + int n) +{ + DdSubtable *subtables; + DdNodePtr *nodelist; + DdNodePtr *vars; + int firstIndex, lastIndex; + int index, level, newlevel; + int lowestLevel; + int shift; + int found; + + /* Sanity check and set up. */ + if (n <= 0) return(0); + if (n > unique->size) n = unique->size; + + subtables = unique->subtables; + vars = unique->vars; + firstIndex = unique->size - n; + lastIndex = unique->size; + + /* Check for nodes labeled by the variables being destroyed + ** that may still be in use. It is allowed to destroy a variable + ** only if there are no such nodes. Also, find the lowest level + ** among the variables being destroyed. This will make further + ** processing more efficient. + */ + lowestLevel = unique->size; + for (index = firstIndex; index < lastIndex; index++) { + level = unique->perm[index]; + if (level < lowestLevel) lowestLevel = level; + nodelist = subtables[level].nodelist; + if (subtables[level].keys - subtables[level].dead != 1) return(0); + /* The projection function should be isolated. If the ref count + ** is 1, everything is OK. If the ref count is saturated, then + ** we need to make sure that there are no nodes pointing to it. + ** As for the external references, we assume the application is + ** responsible for them. + */ + if (vars[index]->ref != 1) { + if (vars[index]->ref != DD_MAXREF) return(0); + found = cuddFindParent(unique,vars[index]); + if (found) { + return(0); + } else { + vars[index]->ref = 1; + } + } + Cudd_RecursiveDeref(unique,vars[index]); + } + + /* Collect garbage, because we cannot afford having dead nodes pointing + ** to the dead nodes in the subtables being destroyed. + */ + (void) cuddGarbageCollect(unique,1); + + /* Here we know we can destroy our subtables. */ + for (index = firstIndex; index < lastIndex; index++) { + level = unique->perm[index]; + nodelist = subtables[level].nodelist; +#ifdef DD_DEBUG + assert(subtables[level].keys == 0); +#endif + FREE(nodelist); + unique->memused -= sizeof(DdNodePtr) * subtables[level].slots; + unique->slots -= subtables[level].slots; + unique->dead -= subtables[level].dead; + } + + /* Here all subtables to be destroyed have their keys field == 0 and + ** their hash tables have been freed. + ** We now scan the subtables from level lowestLevel + 1 to level size - 1, + ** shifting the subtables as required. We keep a running count of + ** how many subtables have been moved, so that we know by how many + ** positions each subtable should be shifted. + */ + shift = 1; + for (level = lowestLevel + 1; level < unique->size; level++) { + if (subtables[level].keys == 0) { + shift++; + continue; + } + newlevel = level - shift; + subtables[newlevel].slots = subtables[level].slots; + subtables[newlevel].shift = subtables[level].shift; + subtables[newlevel].keys = subtables[level].keys; + subtables[newlevel].maxKeys = subtables[level].maxKeys; + subtables[newlevel].dead = subtables[level].dead; + subtables[newlevel].nodelist = subtables[level].nodelist; + index = unique->invperm[level]; + unique->perm[index] = newlevel; + unique->invperm[newlevel] = index; + subtables[newlevel].bindVar = subtables[level].bindVar; + subtables[newlevel].varType = subtables[level].varType; + subtables[newlevel].pairIndex = subtables[level].pairIndex; + subtables[newlevel].varHandled = subtables[level].varHandled; + subtables[newlevel].varToBeGrouped = subtables[level].varToBeGrouped; + } + /* Destroy the map. If a surviving variable is + ** mapped to a dying variable, and the map were used again, + ** an out-of-bounds access to unique->vars would result. */ + if (unique->map != NULL) { + cuddCacheFlush(unique); + FREE(unique->map); + unique->map = NULL; + } + + unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); + unique->size -= n; + + return(1); + +} /* end of cuddDestroySubtables */ + + +/**Function******************************************************************** + + Synopsis [Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index.] + + Description [Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index. When new ZDD variables are created, it + is possible to preserve the functions unchanged, or it is possible to + preserve the covers unchanged, but not both. cuddResizeTableZdd preserves + the covers. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [ddResizeTable] + +******************************************************************************/ +int +cuddResizeTableZdd( + DdManager * unique, + int index) +{ + DdSubtable *newsubtables; + DdNodePtr *newnodelist; + int oldsize,newsize; + int i,j,reorderSave; + unsigned int numSlots = unique->initSlots; + int *newperm, *newinvperm; + + oldsize = unique->sizeZ; + /* Easy case: there is still room in the current table. */ + if (index < unique->maxSizeZ) { + for (i = oldsize; i <= index; i++) { + unique->subtableZ[i].slots = numSlots; + unique->subtableZ[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtableZ[i].keys = 0; + unique->subtableZ[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtableZ[i].dead = 0; + unique->permZ[i] = i; + unique->invpermZ[i] = i; + newnodelist = unique->subtableZ[i].nodelist = + ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = NULL; + } + } + } else { + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables up to index included. + */ + newsize = index + DD_DEFAULT_RESIZE; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "Increasing the ZDD table size from %d to %d\n", + unique->maxSizeZ, newsize); +#endif + newsubtables = ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newperm = ALLOC(int,newsize); + if (newperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newinvperm = ALLOC(int,newsize); + if (newinvperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->memused += (newsize - unique->maxSizeZ) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + if (newsize > unique->maxSize) { + FREE(unique->stack); + unique->stack = ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); + } + for (i = 0; i < oldsize; i++) { + newsubtables[i].slots = unique->subtableZ[i].slots; + newsubtables[i].shift = unique->subtableZ[i].shift; + newsubtables[i].keys = unique->subtableZ[i].keys; + newsubtables[i].maxKeys = unique->subtableZ[i].maxKeys; + newsubtables[i].dead = unique->subtableZ[i].dead; + newsubtables[i].nodelist = unique->subtableZ[i].nodelist; + newperm[i] = unique->permZ[i]; + newinvperm[i] = unique->invpermZ[i]; + } + for (i = oldsize; i <= index; i++) { + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newperm[i] = i; + newinvperm[i] = i; + newnodelist = newsubtables[i].nodelist = ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = NULL; + } + } + FREE(unique->subtableZ); + unique->subtableZ = newsubtables; + unique->maxSizeZ = newsize; + FREE(unique->permZ); + unique->permZ = newperm; + FREE(unique->invpermZ); + unique->invpermZ = newinvperm; + } + unique->slots += (index + 1 - unique->sizeZ) * numSlots; + ddFixLimits(unique); + unique->sizeZ = index + 1; + + /* Now that the table is in a coherent state, update the ZDD + ** universe. We need to temporarily disable reordering, + ** because we cannot reorder without universe in place. + */ + + reorderSave = unique->autoDynZ; + unique->autoDynZ = 0; + cuddZddFreeUniv(unique); + if (!cuddZddInitUniv(unique)) { + unique->autoDynZ = reorderSave; + return(0); + } + unique->autoDynZ = reorderSave; + + return(1); + +} /* end of cuddResizeTableZdd */ + + +/**Function******************************************************************** + + Synopsis [Adjusts parameters of a table to slow down its growth.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddSlowTableGrowth( + DdManager *unique) +{ + int i; + + unique->maxCacheHard = unique->cacheSlots - 1; + unique->cacheSlack = - (int) (unique->cacheSlots + 1); + for (i = 0; i < unique->size; i++) { + unique->subtables[i].maxKeys <<= 2; + } + unique->gcFrac = DD_GC_FRAC_MIN; + unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots); + cuddShrinkDeathRow(unique); + (void) fprintf(unique->err,"Slowing down table growth: "); + (void) fprintf(unique->err,"GC fraction = %.2f\t", unique->gcFrac); + (void) fprintf(unique->err,"minDead = %u\n", unique->minDead); + +} /* end of cuddSlowTableGrowth */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Rehashes a ZDD unique subtable.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddRehash] + +******************************************************************************/ +static void +ddRehashZdd( + DdManager * unique, + int i) +{ + unsigned int slots, oldslots; + int shift, oldshift; + int j, pos; + DdNodePtr *nodelist, *oldnodelist; + DdNode *node, *next; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (unique->slots > unique->looseUpTo) { + unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); +#ifdef DD_VERBOSE + if (unique->gcFrac == DD_GC_FRAC_HI) { + (void) fprintf(unique->err,"GC fraction = %.2f\t", + DD_GC_FRAC_LO); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); + } +#endif + unique->gcFrac = DD_GC_FRAC_LO; + } + + assert(i != CUDD_MAXINDEX); + oldslots = unique->subtableZ[i].slots; + oldshift = unique->subtableZ[i].shift; + oldnodelist = unique->subtableZ[i].nodelist; + + /* Compute the new size of the subtable. Normally, we just + ** double. However, after reordering, a table may be severely + ** overloaded. Therefore, we iterate. */ + slots = oldslots; + shift = oldshift; + do { + slots <<= 1; + shift--; + } while (slots * DD_MAX_SUBTABLE_DENSITY < unique->subtableZ[i].keys); + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + (void) fprintf(unique->err, + "Unable to resize ZDD subtable %d for lack of memory.\n", + i); + (void) cuddGarbageCollect(unique,1); + for (j = 0; j < unique->sizeZ; j++) { + unique->subtableZ[j].maxKeys <<= 1; + } + return; + } + unique->subtableZ[i].nodelist = nodelist; + unique->subtableZ[i].slots = slots; + unique->subtableZ[i].shift = shift; + unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + pos = ddHash(cuddT(node), cuddE(node), shift); + node->next = nodelist[pos]; + nodelist[pos] = node; + node = next; + } + } + FREE(oldnodelist); + +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "rehashing layer %d: keys %d dead %d new size %d\n", + i, unique->subtableZ[i].keys, + unique->subtableZ[i].dead, slots); +#endif + + /* Update global data. */ + unique->memused += (slots - oldslots) * sizeof(DdNode *); + unique->slots += (slots - oldslots); + ddFixLimits(unique); + +} /* end of ddRehashZdd */ + + +/**Function******************************************************************** + + Synopsis [Increases the number of subtables in a unique table so + that it meets or exceeds index.] + + Description [Increases the number of subtables in a unique table so + that it meets or exceeds index. The parameter amount determines how + much spare space is allocated to prevent too frequent resizing. If + index is negative, the table is resized, but no new variables are + created. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Reserve cuddResizeTableZdd] + +******************************************************************************/ +static int +ddResizeTable( + DdManager * unique, + int index, + int amount) +{ + DdSubtable *newsubtables; + DdNodePtr *newnodelist; + DdNodePtr *newvars; + DdNode *sentinel = &(unique->sentinel); + int oldsize,newsize; + int i,j,reorderSave; + int numSlots = unique->initSlots; + int *newperm, *newinvperm, *newmap; + DdNode *one, *zero; + + oldsize = unique->size; + /* Easy case: there is still room in the current table. */ + if (index >= 0 && index < unique->maxSize) { + for (i = oldsize; i <= index; i++) { + unique->subtables[i].slots = numSlots; + unique->subtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtables[i].keys = 0; + unique->subtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[i].dead = 0; + unique->subtables[i].bindVar = 0; + unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[i].pairIndex = 0; + unique->subtables[i].varHandled = 0; + unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + unique->perm[i] = i; + unique->invperm[i] = i; + newnodelist = unique->subtables[i].nodelist = + ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + for (j = oldsize; j < i; j++) { + FREE(unique->subtables[j].nodelist); + } + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + if (unique->map != NULL) { + for (i = oldsize; i <= index; i++) { + unique->map[i] = i; + } + } + } else { + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables up to index included. + */ + newsize = (index < 0) ? amount : index + amount; +#ifdef DD_VERBOSE + (void) fprintf(unique->err, + "Increasing the table size from %d to %d\n", + unique->maxSize, newsize); +#endif + newsubtables = ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newvars = ALLOC(DdNodePtr,newsize); + if (newvars == NULL) { + FREE(newsubtables); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newperm = ALLOC(int,newsize); + if (newperm == NULL) { + FREE(newsubtables); + FREE(newvars); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + newinvperm = ALLOC(int,newsize); + if (newinvperm == NULL) { + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + if (unique->map != NULL) { + newmap = ALLOC(int,newsize); + if (newmap == NULL) { + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + FREE(newinvperm); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->memused += (newsize - unique->maxSize) * sizeof(int); + } + unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + if (newsize > unique->maxSizeZ) { + FREE(unique->stack); + unique->stack = ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + FREE(newsubtables); + FREE(newvars); + FREE(newperm); + FREE(newinvperm); + if (unique->map != NULL) { + FREE(newmap); + } + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); + } + for (i = 0; i < oldsize; i++) { + newsubtables[i].slots = unique->subtables[i].slots; + newsubtables[i].shift = unique->subtables[i].shift; + newsubtables[i].keys = unique->subtables[i].keys; + newsubtables[i].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i].dead = unique->subtables[i].dead; + newsubtables[i].nodelist = unique->subtables[i].nodelist; + newsubtables[i].bindVar = unique->subtables[i].bindVar; + newsubtables[i].varType = unique->subtables[i].varType; + newsubtables[i].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i].varHandled = unique->subtables[i].varHandled; + newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + newperm[i] = unique->perm[i]; + newinvperm[i] = unique->invperm[i]; + } + for (i = oldsize; i <= index; i++) { + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newsubtables[i].bindVar = 0; + newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + newsubtables[i].pairIndex = 0; + newsubtables[i].varHandled = 0; + newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + newperm[i] = i; + newinvperm[i] = i; + newnodelist = newsubtables[i].nodelist = ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + if (unique->map != NULL) { + for (i = 0; i < oldsize; i++) { + newmap[i] = unique->map[i]; + } + for (i = oldsize; i <= index; i++) { + newmap[i] = i; + } + FREE(unique->map); + unique->map = newmap; + } + FREE(unique->subtables); + unique->subtables = newsubtables; + unique->maxSize = newsize; + FREE(unique->vars); + unique->vars = newvars; + FREE(unique->perm); + unique->perm = newperm; + FREE(unique->invperm); + unique->invperm = newinvperm; + } + + /* Now that the table is in a coherent state, create the new + ** projection functions. We need to temporarily disable reordering, + ** because we cannot reorder without projection functions in place. + **/ + if (index >= 0) { + one = unique->one; + zero = Cudd_Not(one); + + unique->size = index + 1; + if (unique->tree != NULL) { + unique->tree->size = ddMax(unique->tree->size, unique->size); + } + unique->slots += (index + 1 - oldsize) * numSlots; + ddFixLimits(unique); + + reorderSave = unique->autoDyn; + unique->autoDyn = 0; + for (i = oldsize; i <= index; i++) { + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) { + unique->autoDyn = reorderSave; + for (j = oldsize; j < i; j++) { + Cudd_IterDerefBdd(unique,unique->vars[j]); + cuddDeallocNode(unique,unique->vars[j]); + unique->vars[j] = NULL; + } + for (j = oldsize; j <= index; j++) { + FREE(unique->subtables[j].nodelist); + unique->subtables[j].nodelist = NULL; + } + unique->size = oldsize; + unique->slots -= (index + 1 - oldsize) * numSlots; + ddFixLimits(unique); + return(0); + } + cuddRef(unique->vars[i]); + } + unique->autoDyn = reorderSave; + } + + return(1); + +} /* end of ddResizeTable */ + + +/**Function******************************************************************** + + Synopsis [Searches the subtables above node for a parent.] + + Description [Searches the subtables above node for a parent. Returns 1 + as soon as one parent is found. Returns 0 is the search is fruitless.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddFindParent( + DdManager * table, + DdNode * node) +{ + int i,j; + int slots; + DdNodePtr *nodelist; + DdNode *f; + + for (i = cuddI(table,node->index) - 1; i >= 0; i--) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (cuddT(f) > node) { + f = f->next; + } + while (cuddT(f) == node && Cudd_Regular(cuddE(f)) > node) { + f = f->next; + } + if (cuddT(f) == node && Cudd_Regular(cuddE(f)) == node) { + return(1); + } + } + } + + return(0); + +} /* end of cuddFindParent */ + + +/**Function******************************************************************** + + Synopsis [Adjusts the values of table limits.] + + Description [Adjusts the values of table fields controlling the. + sizes of subtables and computed table. If the computed table is too small + according to the new values, it is resized.] + + SideEffects [Modifies manager fields. May resize computed table.] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static void +ddFixLimits( + DdManager *unique) +{ + unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); + unique->cacheSlack = (int) ddMin(unique->maxCacheHard, + DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) - + 2 * (int) unique->cacheSlots; + if (unique->cacheSlots < unique->slots/2 && unique->cacheSlack >= 0) + cuddCacheResize(unique); + return; + +} /* end of ddFixLimits */ + + +#ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST +/**Function******************************************************************** + + Synopsis [Inserts a DdNode in a red/black search tree.] + + Description [Inserts a DdNode in a red/black search tree. Nodes from + the same "page" (defined by DD_PAGE_MASK) are linked in a LIFO list.] + + SideEffects [None] + + SeeAlso [cuddOrderedThread] + +******************************************************************************/ +static void +cuddOrderedInsert( + DdNodePtr * root, + DdNodePtr node) +{ + DdNode *scan; + DdNodePtr *scanP; + DdNodePtr *stack[DD_STACK_SIZE]; + int stackN = 0; + + scanP = root; + while ((scan = *scanP) != NULL) { + stack[stackN++] = scanP; + if (DD_INSERT_COMPARE(node, scan) == 0) { /* add to page list */ + DD_NEXT(node) = DD_NEXT(scan); + DD_NEXT(scan) = node; + return; + } + scanP = (node < scan) ? &DD_LEFT(scan) : &DD_RIGHT(scan); + } + DD_RIGHT(node) = DD_LEFT(node) = DD_NEXT(node) = NULL; + DD_COLOR(node) = DD_RED; + *scanP = node; + stack[stackN] = &node; + cuddDoRebalance(stack,stackN); + +} /* end of cuddOrderedInsert */ + + +/**Function******************************************************************** + + Synopsis [Threads all the nodes of a search tree into a linear list.] + + Description [Threads all the nodes of a search tree into a linear + list. For each node of the search tree, the "left" child, if non-null, has + a lower address than its parent, and the "right" child, if non-null, has a + higher address than its parent. + The list is sorted in order of increasing addresses. The search + tree is destroyed as a result of this operation. The last element of + the linear list is made to point to the address passed in list. Each + node if the search tree is a linearly-linked list of nodes from the + same memory page (as defined in DD_PAGE_MASK). When a node is added to + the linear list, all the elements of the linked list are added.] + + SideEffects [The search tree is destroyed as a result of this operation.] + + SeeAlso [cuddOrderedInsert] + +******************************************************************************/ +static DdNode * +cuddOrderedThread( + DdNode * root, + DdNode * list) +{ + DdNode *current, *next, *prev, *end; + + current = root; + /* The first word in the node is used to implement a stack that holds + ** the nodes from the root of the tree to the current node. Here we + ** put the root of the tree at the bottom of the stack. + */ + *((DdNodePtr *) current) = NULL; + + while (current != NULL) { + if (DD_RIGHT(current) != NULL) { + /* If possible, we follow the "right" link. Eventually we'll + ** find the node with the largest address in the current tree. + ** In this phase we use the first word of a node to implemen + ** a stack of the nodes on the path from the root to "current". + ** Also, we disconnect the "right" pointers to indicate that + ** we have already followed them. + */ + next = DD_RIGHT(current); + DD_RIGHT(current) = NULL; + *((DdNodePtr *)next) = current; + current = next; + } else { + /* We can't proceed along the "right" links any further. + ** Hence "current" is the largest element in the current tree. + ** We make this node the new head of "list". (Repeating this + ** operation until the tree is empty yields the desired linear + ** threading of all nodes.) + */ + prev = *((DdNodePtr *) current); /* save prev node on stack in prev */ + /* Traverse the linked list of current until the end. */ + for (end = current; DD_NEXT(end) != NULL; end = DD_NEXT(end)); + DD_NEXT(end) = list; /* attach "list" at end and make */ + list = current; /* "current" the new head of "list" */ + /* Now, if current has a "left" child, we push it on the stack. + ** Otherwise, we just continue with the parent of "current". + */ + if (DD_LEFT(current) != NULL) { + next = DD_LEFT(current); + *((DdNodePtr *) next) = prev; + current = next; + } else { + current = prev; + } + } + } + + return(list); + +} /* end of cuddOrderedThread */ + + +/**Function******************************************************************** + + Synopsis [Performs the left rotation for red/black trees.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddRotateRight] + +******************************************************************************/ +DD_INLINE +static void +cuddRotateLeft( + DdNodePtr * nodeP) +{ + DdNode *newRoot; + DdNode *oldRoot = *nodeP; + + *nodeP = newRoot = DD_RIGHT(oldRoot); + DD_RIGHT(oldRoot) = DD_LEFT(newRoot); + DD_LEFT(newRoot) = oldRoot; + +} /* end of cuddRotateLeft */ + + +/**Function******************************************************************** + + Synopsis [Performs the right rotation for red/black trees.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddRotateLeft] + +******************************************************************************/ +DD_INLINE +static void +cuddRotateRight( + DdNodePtr * nodeP) +{ + DdNode *newRoot; + DdNode *oldRoot = *nodeP; + + *nodeP = newRoot = DD_LEFT(oldRoot); + DD_LEFT(oldRoot) = DD_RIGHT(newRoot); + DD_RIGHT(newRoot) = oldRoot; + +} /* end of cuddRotateRight */ + + +/**Function******************************************************************** + + Synopsis [Rebalances a red/black tree.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +cuddDoRebalance( + DdNodePtr ** stack, + int stackN) +{ + DdNodePtr *xP, *parentP, *grandpaP; + DdNode *x, *y, *parent, *grandpa; + + xP = stack[stackN]; + x = *xP; + /* Work our way back up, re-balancing the tree. */ + while (--stackN >= 0) { + parentP = stack[stackN]; + parent = *parentP; + if (DD_IS_BLACK(parent)) break; + /* Since the root is black, here a non-null grandparent exists. */ + grandpaP = stack[stackN-1]; + grandpa = *grandpaP; + if (parent == DD_LEFT(grandpa)) { + y = DD_RIGHT(grandpa); + if (y != NULL && DD_IS_RED(y)) { + DD_COLOR(parent) = DD_BLACK; + DD_COLOR(y) = DD_BLACK; + DD_COLOR(grandpa) = DD_RED; + x = grandpa; + stackN--; + } else { + if (x == DD_RIGHT(parent)) { + cuddRotateLeft(parentP); + DD_COLOR(x) = DD_BLACK; + } else { + DD_COLOR(parent) = DD_BLACK; + } + DD_COLOR(grandpa) = DD_RED; + cuddRotateRight(grandpaP); + break; + } + } else { + y = DD_LEFT(grandpa); + if (y != NULL && DD_IS_RED(y)) { + DD_COLOR(parent) = DD_BLACK; + DD_COLOR(y) = DD_BLACK; + DD_COLOR(grandpa) = DD_RED; + x = grandpa; + stackN--; + } else { + if (x == DD_LEFT(parent)) { + cuddRotateRight(parentP); + DD_COLOR(x) = DD_BLACK; + } else { + DD_COLOR(parent) = DD_BLACK; + } + DD_COLOR(grandpa) = DD_RED; + cuddRotateLeft(grandpaP); + } + } + } + DD_COLOR(*(stack[0])) = DD_BLACK; + +} /* end of cuddDoRebalance */ +#endif +#endif + + +/**Function******************************************************************** + + Synopsis [Fixes a variable tree after the insertion of new subtables.] + + Description [Fixes a variable tree after the insertion of new subtables. + After such an insertion, the low fields of the tree below the insertion + point are inconsistent.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ddPatchTree( + DdManager *dd, + MtrNode *treenode) +{ + MtrNode *auxnode = treenode; + + while (auxnode != NULL) { + auxnode->low = dd->perm[auxnode->index]; + if (auxnode->child != NULL) { + ddPatchTree(dd, auxnode->child); + } + auxnode = auxnode->younger; + } + + return; + +} /* end of ddPatchTree */ + + +#ifdef DD_DEBUG +/**Function******************************************************************** + + Synopsis [Checks whether a collision list is ordered.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddCheckCollisionOrdering( + DdManager *unique, + int i, + int j) +{ + int slots; + DdNode *node, *next; + DdNodePtr *nodelist; + DdNode *sentinel = &(unique->sentinel); + + nodelist = unique->subtables[i].nodelist; + slots = unique->subtables[i].slots; + node = nodelist[j]; + if (node == sentinel) return(1); + next = node->next; + while (next != sentinel) { + if (cuddT(node) < cuddT(next) || + (cuddT(node) == cuddT(next) && cuddE(node) < cuddE(next))) { + (void) fprintf(unique->err, + "Unordered list: index %u, position %d\n", i, j); + return(0); + } + node = next; + next = node->next; + } + return(1); + +} /* end of cuddCheckCollisionOrdering */ +#endif + + + + +/**Function******************************************************************** + + Synopsis [Reports problem in garbage collection.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddGarbageCollect cuddGarbageCollectZdd] + +******************************************************************************/ +static void +ddReportRefMess( + DdManager *unique /* manager */, + int i /* table in which the problem occurred */, + const char *caller /* procedure that detected the problem */) +{ + if (i == CUDD_CONST_INDEX) { + (void) fprintf(unique->err, + "%s: problem in constants\n", caller); + } else if (i != -1) { + (void) fprintf(unique->err, + "%s: problem in table %d\n", caller, i); + } + (void) fprintf(unique->err, " dead count != deleted\n"); + (void) fprintf(unique->err, " This problem is often due to a missing \ +call to Cudd_Ref\n or to an extra call to Cudd_RecursiveDeref.\n \ +See the CUDD Programmer's Guide for additional details."); + abort(); + +} /* end of ddReportRefMess */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddUtil.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddUtil.c new file mode 100644 index 000000000..1a1a47a03 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddUtil.c @@ -0,0 +1,4032 @@ +/**CFile*********************************************************************** + + FileName [cuddUtil.c] + + PackageName [cudd] + + Synopsis [Utility functions.] + + Description [External procedures included in this module: +
                          +
                        • Cudd_PrintMinterm() +
                        • Cudd_bddPrintCover() +
                        • Cudd_PrintDebug() +
                        • Cudd_DagSize() +
                        • Cudd_EstimateCofactor() +
                        • Cudd_EstimateCofactorSimple() +
                        • Cudd_SharingSize() +
                        • Cudd_CountMinterm() +
                        • Cudd_EpdCountMinterm() +
                        • Cudd_CountPath() +
                        • Cudd_CountPathsToNonZero() +
                        • Cudd_SupportIndices() +
                        • Cudd_Support() +
                        • Cudd_SupportIndex() +
                        • Cudd_SupportSize() +
                        • Cudd_VectorSupportIndices() +
                        • Cudd_VectorSupport() +
                        • Cudd_VectorSupportIndex() +
                        • Cudd_VectorSupportSize() +
                        • Cudd_ClassifySupport() +
                        • Cudd_CountLeaves() +
                        • Cudd_bddPickOneCube() +
                        • Cudd_bddPickOneMinterm() +
                        • Cudd_bddPickArbitraryMinterms() +
                        • Cudd_SubsetWithMaskVars() +
                        • Cudd_FirstCube() +
                        • Cudd_NextCube() +
                        • Cudd_bddComputeCube() +
                        • Cudd_addComputeCube() +
                        • Cudd_FirstNode() +
                        • Cudd_NextNode() +
                        • Cudd_GenFree() +
                        • Cudd_IsGenEmpty() +
                        • Cudd_IndicesToCube() +
                        • Cudd_PrintVersion() +
                        • Cudd_AverageDistance() +
                        • Cudd_Random() +
                        • Cudd_Srandom() +
                        • Cudd_Density() +
                        + Internal procedures included in this module: +
                          +
                        • cuddP() +
                        • cuddStCountfree() +
                        • cuddCollectNodes() +
                        • cuddNodeArray() +
                        + Static procedures included in this module: +
                          +
                        • dp2() +
                        • ddPrintMintermAux() +
                        • ddDagInt() +
                        • ddCountMintermAux() +
                        • ddEpdCountMintermAux() +
                        • ddCountPathAux() +
                        • ddSupportStep() +
                        • ddClearFlag() +
                        • ddLeavesInt() +
                        • ddPickArbitraryMinterms() +
                        • ddPickRepresentativeCube() +
                        • ddEpdFree() +
                        • ddFindSupport() +
                        • ddClearVars() +
                        • indexCompare() +
                        ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* Random generator constants. */ +#define MODULUS1 2147483563 +#define LEQA1 40014 +#define LEQQ1 53668 +#define LEQR1 12211 +#define MODULUS2 2147483399 +#define LEQA2 40692 +#define LEQQ2 52774 +#define LEQR2 3791 +#define STAB_SIZE 64 +#define STAB_DIV (1 + (MODULUS1 - 1) / STAB_SIZE) + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddUtil.c,v 1.83 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static DdNode *background, *zero; + +static long cuddRand = 0; +static long cuddRand2; +static long shuffleSelect; +static long shuffleTable[STAB_SIZE]; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define bang(f) ((Cudd_IsComplement(f)) ? '!' : ' ') + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int dp2 (DdManager *dd, DdNode *f, st_table *t); +static void ddPrintMintermAux (DdManager *dd, DdNode *node, int *list); +static int ddDagInt (DdNode *n); +static int cuddNodeArrayRecur (DdNode *f, DdNodePtr *table, int index); +static int cuddEstimateCofactor (DdManager *dd, st_table *table, DdNode * node, int i, int phase, DdNode ** ptr); +static DdNode * cuddUniqueLookup (DdManager * unique, int index, DdNode * T, DdNode * E); +static int cuddEstimateCofactorSimple (DdNode * node, int i); +static double ddCountMintermAux (DdNode *node, double max, DdHashTable *table); +static int ddEpdCountMintermAux (DdNode *node, EpDouble *max, EpDouble *epd, st_table *table); +static double ddCountPathAux (DdNode *node, st_table *table); +static double ddCountPathsToNonZero (DdNode * N, st_table * table); +static void ddSupportStep (DdNode *f, int *support); +static void ddClearFlag (DdNode *f); +static int ddLeavesInt (DdNode *n); +static int ddPickArbitraryMinterms (DdManager *dd, DdNode *node, int nvars, int nminterms, char **string); +static int ddPickRepresentativeCube (DdManager *dd, DdNode *node, double *weight, char *string); +static enum st_retval ddEpdFree (char * key, char * value, char * arg); +static void ddFindSupport(DdManager *dd, DdNode *f, int *SP); +static void ddClearVars(DdManager *dd, int SP); +static int indexCompare(const void *a, const void *b); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints a disjoint sum of products.] + + Description [Prints a disjoint sum of product cover for the function + rooted at node. Each product corresponds to a path from node to a + leaf node different from the logical zero, and different from the + background value. Uses the package default output file. Returns 1 + if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug Cudd_bddPrintCover] + +******************************************************************************/ +int +Cudd_PrintMinterm( + DdManager * manager, + DdNode * node) +{ + int i, *list; + + background = manager->background; + zero = Cudd_Not(manager->one); + list = ALLOC(int,manager->size); + if (list == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < manager->size; i++) list[i] = 2; + ddPrintMintermAux(manager,node,list); + FREE(list); + return(1); + +} /* end of Cudd_PrintMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints a sum of prime implicants of a BDD.] + + Description [Prints a sum of product cover for an incompletely + specified function given by a lower bound and an upper bound. Each + product is a prime implicant obtained by expanding the product + corresponding to a path from node to the constant one. Uses the + package default output file. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintMinterm] + +******************************************************************************/ +int +Cudd_bddPrintCover( + DdManager *dd, + DdNode *l, + DdNode *u) +{ + int *array; + int q, result; + DdNode *lb; +#ifdef DD_DEBUG + DdNode *cover; +#endif + + array = ALLOC(int, Cudd_ReadSize(dd)); + if (array == NULL) return(0); + lb = l; + cuddRef(lb); +#ifdef DD_DEBUG + cover = Cudd_ReadLogicZero(dd); + cuddRef(cover); +#endif + while (lb != Cudd_ReadLogicZero(dd)) { + DdNode *implicant, *prime, *tmp; + int length; + implicant = Cudd_LargestCube(dd,lb,&length); + if (implicant == NULL) { + Cudd_RecursiveDeref(dd,lb); + FREE(array); + return(0); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,u); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,implicant); + FREE(array); + return(0); + } + cuddRef(prime); + Cudd_RecursiveDeref(dd,implicant); + tmp = Cudd_bddAnd(dd,lb,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + FREE(array); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,lb); + lb = tmp; + result = Cudd_BddToCubeArray(dd,prime,array); + if (result == 0) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + FREE(array); + return(0); + } + for (q = 0; q < dd->size; q++) { + switch (array[q]) { + case 0: + (void) fprintf(dd->out, "0"); + break; + case 1: + (void) fprintf(dd->out, "1"); + break; + case 2: + (void) fprintf(dd->out, "-"); + break; + default: + (void) fprintf(dd->out, "?"); + } + } + (void) fprintf(dd->out, " 1\n"); +#ifdef DD_DEBUG + tmp = Cudd_bddOr(dd,prime,cover); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cover); + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + FREE(array); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cover); + cover = tmp; +#endif + Cudd_RecursiveDeref(dd,prime); + } + (void) fprintf(dd->out, "\n"); + Cudd_RecursiveDeref(dd,lb); + FREE(array); +#ifdef DD_DEBUG + if (!Cudd_bddLeq(dd,cover,u) || !Cudd_bddLeq(dd,l,cover)) { + Cudd_RecursiveDeref(dd,cover); + return(0); + } + Cudd_RecursiveDeref(dd,cover); +#endif + return(1); + +} /* end of Cudd_bddPrintCover */ + + +/**Function******************************************************************** + + Synopsis [Prints to the standard output a DD and its statistics.] + + Description [Prints to the standard output a DD and its statistics. + The statistics include the number of nodes, the number of leaves, and + the number of minterms. (The number of minterms is the number of + assignments to the variables that cause the function to be different + from the logical zero (for BDDs) and from the background value (for + ADDs.) The statistics are printed if pr > 0. Specifically: +
                          +
                        • pr = 0 : prints nothing +
                        • pr = 1 : prints counts of nodes and minterms +
                        • pr = 2 : prints counts + disjoint sum of product +
                        • pr = 3 : prints counts + list of nodes +
                        • pr > 3 : prints counts + disjoint sum of product + list of nodes +
                        + For the purpose of counting the number of minterms, the function is + supposed to depend on n variables. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize Cudd_CountLeaves Cudd_CountMinterm + Cudd_PrintMinterm] + +******************************************************************************/ +int +Cudd_PrintDebug( + DdManager * dd, + DdNode * f, + int n, + int pr) +{ + DdNode *azero, *bzero; + int nodes; + int leaves; + double minterms; + int retval = 1; + + if (f == NULL) { + (void) fprintf(dd->out,": is the NULL DD\n"); + (void) fflush(dd->out); + return(0); + } + azero = DD_ZERO(dd); + bzero = Cudd_Not(DD_ONE(dd)); + if ((f == azero || f == bzero) && pr > 0){ + (void) fprintf(dd->out,": is the zero DD\n"); + (void) fflush(dd->out); + return(1); + } + if (pr > 0) { + nodes = Cudd_DagSize(f); + if (nodes == CUDD_OUT_OF_MEM) retval = 0; + leaves = Cudd_CountLeaves(f); + if (leaves == CUDD_OUT_OF_MEM) retval = 0; + minterms = Cudd_CountMinterm(dd, f, n); + if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; + (void) fprintf(dd->out,": %d nodes %d leaves %g minterms\n", + nodes, leaves, minterms); + if (pr > 2) { + if (!cuddP(dd, f)) retval = 0; + } + if (pr == 2 || pr > 3) { + if (!Cudd_PrintMinterm(dd,f)) retval = 0; + (void) fprintf(dd->out,"\n"); + } + (void) fflush(dd->out); + } + return(retval); + +} /* end of Cudd_PrintDebug */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of nodes in a DD.] + + Description [Counts the number of nodes in a DD. Returns the number + of nodes in the graph rooted at node.] + + SideEffects [None] + + SeeAlso [Cudd_SharingSize Cudd_PrintDebug] + +******************************************************************************/ +int +Cudd_DagSize( + DdNode * node) +{ + int i; + + i = ddDagInt(Cudd_Regular(node)); + ddClearFlag(Cudd_Regular(node)); + + return(i); + +} /* end of Cudd_DagSize */ + + +/**Function******************************************************************** + + Synopsis [Estimates the number of nodes in a cofactor of a DD.] + + Description [Estimates the number of nodes in a cofactor of a DD. + Returns an estimate of the number of nodes in a cofactor of + the graph rooted at node with respect to the variable whose index is i. + In case of failure, returns CUDD_OUT_OF_MEM. + This function uses a refinement of the algorithm of Cabodi et al. + (ICCAD96). The refinement allows the procedure to account for part + of the recombination that may occur in the part of the cofactor above + the cofactoring variable. This procedure does not create any new node. + It does keep a small table of results; therefore it may run out of memory. + If this is a concern, one should use Cudd_EstimateCofactorSimple, which + is faster, does not allocate any memory, but is less accurate.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize Cudd_EstimateCofactorSimple] + +******************************************************************************/ +int +Cudd_EstimateCofactor( + DdManager *dd /* manager */, + DdNode * f /* function */, + int i /* index of variable */, + int phase /* 1: positive; 0: negative */ + ) +{ + int val; + DdNode *ptr; + st_table *table; + + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) return(CUDD_OUT_OF_MEM); + val = cuddEstimateCofactor(dd,table,Cudd_Regular(f),i,phase,&ptr); + ddClearFlag(Cudd_Regular(f)); + st_free_table(table); + + return(val); + +} /* end of Cudd_EstimateCofactor */ + + +/**Function******************************************************************** + + Synopsis [Estimates the number of nodes in a cofactor of a DD.] + + Description [Estimates the number of nodes in a cofactor of a DD. + Returns an estimate of the number of nodes in the positive cofactor of + the graph rooted at node with respect to the variable whose index is i. + This procedure implements with minor changes the algorithm of Cabodi et al. + (ICCAD96). It does not allocate any memory, it does not change the + state of the manager, and it is fast. However, it has been observed to + overestimate the size of the cofactor by as much as a factor of 2.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize] + +******************************************************************************/ +int +Cudd_EstimateCofactorSimple( + DdNode * node, + int i) +{ + int val; + + val = cuddEstimateCofactorSimple(Cudd_Regular(node),i); + ddClearFlag(Cudd_Regular(node)); + + return(val); + +} /* end of Cudd_EstimateCofactorSimple */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of nodes in an array of DDs.] + + Description [Counts the number of nodes in an array of DDs. Shared + nodes are counted only once. Returns the total number of nodes.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize] + +******************************************************************************/ +int +Cudd_SharingSize( + DdNode ** nodeArray, + int n) +{ + int i,j; + + i = 0; + for (j = 0; j < n; j++) { + i += ddDagInt(Cudd_Regular(nodeArray[j])); + } + for (j = 0; j < n; j++) { + ddClearFlag(Cudd_Regular(nodeArray[j])); + } + return(i); + +} /* end of Cudd_SharingSize */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a DD.] + + Description [Counts the number of minterms of a DD. The function is + assumed to depend on nvars variables. The minterm count is + represented as a double, to allow for a larger number of variables. + Returns the number of minterms of the function rooted at node if + successful; (double) CUDD_OUT_OF_MEM otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug Cudd_CountPath] + +******************************************************************************/ +double +Cudd_CountMinterm( + DdManager * manager, + DdNode * node, + int nvars) +{ + double max; + DdHashTable *table; + double res; + CUDD_VALUE_TYPE epsilon; + + background = manager->background; + zero = Cudd_Not(manager->one); + + max = pow(2.0,(double)nvars); + table = cuddHashTableInit(manager,1,2); + if (table == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + epsilon = Cudd_ReadEpsilon(manager); + Cudd_SetEpsilon(manager,(CUDD_VALUE_TYPE)0.0); + res = ddCountMintermAux(node,max,table); + cuddHashTableQuit(table); + Cudd_SetEpsilon(manager,epsilon); + + return(res); + +} /* end of Cudd_CountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of paths of a DD.] + + Description [Counts the number of paths of a DD. Paths to all + terminal nodes are counted. The path count is represented as a + double, to allow for a larger number of variables. Returns the + number of paths of the function rooted at node if successful; + (double) CUDD_OUT_OF_MEM otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_CountMinterm] + +******************************************************************************/ +double +Cudd_CountPath( + DdNode * node) +{ + + st_table *table; + double i; + + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + i = ddCountPathAux(Cudd_Regular(node),table); + st_foreach(table, cuddStCountfree, NULL); + st_free_table(table); + return(i); + +} /* end of Cudd_CountPath */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a DD with extended precision.] + + Description [Counts the number of minterms of a DD with extended precision. + The function is assumed to depend on nvars variables. The minterm count is + represented as an EpDouble, to allow any number of variables. + Returns 0 if successful; CUDD_OUT_OF_MEM otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug Cudd_CountPath] + +******************************************************************************/ +int +Cudd_EpdCountMinterm( + DdManager * manager, + DdNode * node, + int nvars, + EpDouble * epd) +{ + EpDouble max, tmp; + st_table *table; + int status; + + background = manager->background; + zero = Cudd_Not(manager->one); + + EpdPow2(nvars, &max); + table = st_init_table(EpdCmp, st_ptrhash); + if (table == NULL) { + EpdMakeZero(epd, 0); + return(CUDD_OUT_OF_MEM); + } + status = ddEpdCountMintermAux(Cudd_Regular(node),&max,epd,table); + st_foreach(table, ddEpdFree, NULL); + st_free_table(table); + if (status == CUDD_OUT_OF_MEM) { + EpdMakeZero(epd, 0); + return(CUDD_OUT_OF_MEM); + } + if (Cudd_IsComplement(node)) { + EpdSubtract3(&max, epd, &tmp); + EpdCopy(&tmp, epd); + } + return(0); + +} /* end of Cudd_EpdCountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of paths to a non-zero terminal of a DD.] + + Description [Counts the number of paths to a non-zero terminal of a + DD. The path count is + represented as a double, to allow for a larger number of variables. + Returns the number of paths of the function rooted at node.] + + SideEffects [None] + + SeeAlso [Cudd_CountMinterm Cudd_CountPath] + +******************************************************************************/ +double +Cudd_CountPathsToNonZero( + DdNode * node) +{ + + st_table *table; + double i; + + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + i = ddCountPathsToNonZero(node,table); + st_foreach(table, cuddStCountfree, NULL); + st_free_table(table); + return(i); + +} /* end of Cudd_CountPathsToNonZero */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a DD depends.] + + Description [Finds the variables on which a DD depends. Returns the + number of variables if successful; CUDD_OUT_OF_MEM otherwise.] + + SideEffects [The indices of the support variables are returned as + side effects. If the function is constant, no array is allocated.] + + SeeAlso [Cudd_Support Cudd_SupportIndex Cudd_VectorSupportIndices] + +******************************************************************************/ +int +Cudd_SupportIndices( + DdManager * dd /* manager */, + DdNode * f /* DD whose support is sought */, + int **indices /* array containing (on return) the indices */) +{ + int SP = 0; + + ddFindSupport(dd, Cudd_Regular(f), &SP); + ddClearFlag(Cudd_Regular(f)); + ddClearVars(dd, SP); + if (SP > 0) { + int i; + *indices = ALLOC(int, SP); + if (*indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + + for (i = 0; i < SP; i++) + (*indices)[i] = (int) (ptrint) dd->stack[i]; + + qsort(*indices, SP, sizeof(int), indexCompare); + } else { + *indices = NULL; + } + + return(SP); + +} /* end of Cudd_SupportIndices */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a DD depends.] + + Description [Finds the variables on which a DD depends. + Returns a BDD consisting of the product of the variables if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_VectorSupport Cudd_ClassifySupport] + +******************************************************************************/ +DdNode * +Cudd_Support( + DdManager * dd /* manager */, + DdNode * f /* DD whose support is sought */) +{ + int *support; + DdNode *res; + int j; + + int size = Cudd_SupportIndices(dd, f, &support); + if (size == CUDD_OUT_OF_MEM) + return(NULL); + + /* Transform support from array of indices to cube. */ + res = DD_ONE(dd); + cuddRef(res); + + for (j = size - 1; j >= 0; j--) { /* for each index bottom-up (almost) */ + int index = support[j]; + DdNode *var = dd->vars[index]; + DdNode *tmp = Cudd_bddAnd(dd,res,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,res); + FREE(support); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,res); + res = tmp; + } + + FREE(support); + cuddDeref(res); + return(res); + +} /* end of Cudd_Support */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a DD depends.] + + Description [Finds the variables on which a DD depends. Returns an + index array of the variables if successful; NULL otherwise. The + size of the array equals the number of variables in the manager. + Each entry of the array is 1 if the corresponding variable is in the + support of the DD and 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Support Cudd_SupportIndices Cudd_ClassifySupport] + +******************************************************************************/ +int * +Cudd_SupportIndex( + DdManager * dd /* manager */, + DdNode * f /* DD whose support is sought */) +{ + int *support; + int i; + int size; + + /* Allocate and initialize support array for ddSupportStep. */ + size = ddMax(dd->size, dd->sizeZ); + support = ALLOC(int,size); + if (support == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + support[i] = 0; + } + + /* Compute support and clean up markers. */ + ddSupportStep(Cudd_Regular(f),support); + ddClearFlag(Cudd_Regular(f)); + + return(support); + +} /* end of Cudd_SupportIndex */ + + +/**Function******************************************************************** + + Synopsis [Counts the variables on which a DD depends.] + + Description [Returns the variables on which a DD depends.] + + SideEffects [None] + + SeeAlso [Cudd_Support Cudd_SupportIndices] + +******************************************************************************/ +int +Cudd_SupportSize( + DdManager * dd /* manager */, + DdNode * f /* DD whose support size is sought */) +{ + int SP = 0; + + ddFindSupport(dd, Cudd_Regular(f), &SP); + ddClearFlag(Cudd_Regular(f)); + ddClearVars(dd, SP); + + return(SP); + +} /* end of Cudd_SupportSize */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a set of DDs depends.] + + Description [Finds the variables on which a set of DDs depends. The + set must contain either BDDs and ADDs, or ZDDs. Returns the number + of variables if successful; CUDD_OUT_OF_MEM otherwise.] + + SideEffects [The indices of the support variables are returned as + side effects. If the function is constant, no array is allocated.] + + SeeAlso [Cudd_Support Cudd_SupportIndex Cudd_VectorSupportIndices] + +******************************************************************************/ +int +Cudd_VectorSupportIndices( + DdManager * dd /* manager */, + DdNode ** F /* DD whose support is sought */, + int n /* size of the array */, + int **indices /* array containing (on return) the indices */) +{ + int i; + int SP = 0; + + /* Compute support and clean up markers. */ + for (i = 0; i < n; i++) { + ddFindSupport(dd, Cudd_Regular(F[i]), &SP); + } + for (i = 0; i < n; i++) { + ddClearFlag(Cudd_Regular(F[i])); + } + ddClearVars(dd, SP); + + if (SP > 0) { + int i; + *indices = ALLOC(int, SP); + if (*indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + + for (i = 0; i < SP; i++) + (*indices)[i] = (int) (ptrint) dd->stack[i]; + + qsort(*indices, SP, sizeof(int), indexCompare); + } else { + *indices = NULL; + } + + return(SP); + +} /* end of Cudd_VectorSupportIndices */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a set of DDs depends.] + + Description [Finds the variables on which a set of DDs depends. + The set must contain either BDDs and ADDs, or ZDDs. + Returns a BDD consisting of the product of the variables if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Support Cudd_ClassifySupport] + +******************************************************************************/ +DdNode * +Cudd_VectorSupport( + DdManager * dd /* manager */, + DdNode ** F /* array of DDs whose support is sought */, + int n /* size of the array */) +{ + int *support; + DdNode *res; + int j; + int size = Cudd_VectorSupportIndices(dd, F, n, &support); + if (size == CUDD_OUT_OF_MEM) + return(NULL); + + /* Transform support from array of indices to cube. */ + res = DD_ONE(dd); + cuddRef(res); + + for (j = size - 1; j >= 0; j--) { /* for each index bottom-up (almost) */ + int index = support[j]; + DdNode *var = dd->vars[index]; + DdNode *tmp = Cudd_bddAnd(dd,res,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,res); + FREE(support); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,res); + res = tmp; + } + + FREE(support); + cuddDeref(res); + return(res); + +} /* end of Cudd_VectorSupport */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a set of DDs depends.] + + Description [Finds the variables on which a set of DDs depends. + The set must contain either BDDs and ADDs, or ZDDs. + Returns an index array of the variables if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_SupportIndex Cudd_VectorSupport Cudd_VectorSupportIndices] + +******************************************************************************/ +int * +Cudd_VectorSupportIndex( + DdManager * dd /* manager */, + DdNode ** F /* array of DDs whose support is sought */, + int n /* size of the array */) +{ + int *support; + int i; + int size; + + /* Allocate and initialize support array for ddSupportStep. */ + size = ddMax(dd->size, dd->sizeZ); + support = ALLOC(int,size); + if (support == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + support[i] = 0; + } + + /* Compute support and clean up markers. */ + for (i = 0; i < n; i++) { + ddSupportStep(Cudd_Regular(F[i]),support); + } + for (i = 0; i < n; i++) { + ddClearFlag(Cudd_Regular(F[i])); + } + + return(support); + +} /* end of Cudd_VectorSupportIndex */ + + +/**Function******************************************************************** + + Synopsis [Counts the variables on which a set of DDs depends.] + + Description [Returns the variables on which a set of DDs depends. + The set must contain either BDDs and ADDs, or ZDDs.] + + SideEffects [None] + + SeeAlso [Cudd_VectorSupport Cudd_SupportSize] + +******************************************************************************/ +int +Cudd_VectorSupportSize( + DdManager * dd /* manager */, + DdNode ** F /* array of DDs whose support is sought */, + int n /* size of the array */) +{ + int i; + int SP = 0; + + /* Compute support and clean up markers. */ + for (i = 0; i < n; i++) { + ddFindSupport(dd, Cudd_Regular(F[i]), &SP); + } + for (i = 0; i < n; i++) { + ddClearFlag(Cudd_Regular(F[i])); + } + ddClearVars(dd, SP); + + return(SP); + +} /* end of Cudd_VectorSupportSize */ + + +/**Function******************************************************************** + + Synopsis [Classifies the variables in the support of two DDs.] + + Description [Classifies the variables in the support of two DDs + f and g, depending on whther they appear + in both DDs, only in f, or only in g. + Returns 1 if successful; 0 otherwise.] + + SideEffects [The cubes of the three classes of variables are + returned as side effects.] + + SeeAlso [Cudd_Support Cudd_VectorSupport] + +******************************************************************************/ +int +Cudd_ClassifySupport( + DdManager * dd /* manager */, + DdNode * f /* first DD */, + DdNode * g /* second DD */, + DdNode ** common /* cube of shared variables */, + DdNode ** onlyF /* cube of variables only in f */, + DdNode ** onlyG /* cube of variables only in g */) +{ + int *supportF, *supportG; + int fi, gi; + int sizeF, sizeG; + + sizeF = Cudd_SupportIndices(dd, f, &supportF); + if (sizeF == CUDD_OUT_OF_MEM) + return(0); + + sizeG = Cudd_SupportIndices(dd, g, &supportG); + if (sizeG == CUDD_OUT_OF_MEM) { + FREE(supportF); + return(0); + } + + /* Classify variables and create cubes. This part of the procedure + ** relies on the sorting of the indices in the two support arrays. + */ + *common = *onlyF = *onlyG = DD_ONE(dd); + cuddRef(*common); cuddRef(*onlyF); cuddRef(*onlyG); + fi = sizeF - 1; + gi = sizeG - 1; + while (fi >= 0 || gi >= 0) { + int indexF = fi >= 0 ? supportF[fi] : -1; + int indexG = gi >= 0 ? supportG[gi] : -1; + int index = ddMax(indexF, indexG); + DdNode *var = dd->vars[index]; +#ifdef DD_DEBUG + assert(index >= 0); +#endif + if (indexF == indexG) { + DdNode *tmp = Cudd_bddAnd(dd,*common,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + FREE(supportF); FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*common); + *common = tmp; + fi--; + gi--; + } else if (index == indexF) { + DdNode *tmp = Cudd_bddAnd(dd,*onlyF,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + FREE(supportF); FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*onlyF); + *onlyF = tmp; + fi--; + } else { /* index == indexG */ + DdNode *tmp = Cudd_bddAnd(dd,*onlyG,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + FREE(supportF); FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*onlyG); + *onlyG = tmp; + gi--; + } + } + + FREE(supportF); FREE(supportG); + cuddDeref(*common); cuddDeref(*onlyF); cuddDeref(*onlyG); + return(1); + +} /* end of Cudd_ClassifySupport */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of leaves in a DD.] + + Description [Counts the number of leaves in a DD. Returns the number + of leaves in the DD rooted at node if successful; CUDD_OUT_OF_MEM + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug] + +******************************************************************************/ +int +Cudd_CountLeaves( + DdNode * node) +{ + int i; + + i = ddLeavesInt(Cudd_Regular(node)); + ddClearFlag(Cudd_Regular(node)); + return(i); + +} /* end of Cudd_CountLeaves */ + + +/**Function******************************************************************** + + Synopsis [Picks one on-set cube randomly from the given DD.] + + Description [Picks one on-set cube randomly from the given DD. The + cube is written into an array of characters. The array must have at + least as many entries as there are variables. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPickOneMinterm] + +******************************************************************************/ +int +Cudd_bddPickOneCube( + DdManager * ddm, + DdNode * node, + char * string) +{ + DdNode *N, *T, *E; + DdNode *one, *bzero; + char dir; + int i; + + if (string == NULL || node == NULL) return(0); + + /* The constant 0 function has no on-set cubes. */ + one = DD_ONE(ddm); + bzero = Cudd_Not(one); + if (node == bzero) return(0); + + for (i = 0; i < ddm->size; i++) string[i] = 2; + + for (;;) { + + if (node == one) break; + + N = Cudd_Regular(node); + + T = cuddT(N); E = cuddE(N); + if (Cudd_IsComplement(node)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + if (T == bzero) { + string[N->index] = 0; + node = E; + } else if (E == bzero) { + string[N->index] = 1; + node = T; + } else { + dir = (char) ((Cudd_Random() & 0x2000) >> 13); + string[N->index] = dir; + node = dir ? T : E; + } + } + return(1); + +} /* end of Cudd_bddPickOneCube */ + + +/**Function******************************************************************** + + Synopsis [Picks one on-set minterm randomly from the given DD.] + + Description [Picks one on-set minterm randomly from the given + DD. The minterm is in terms of vars. The array + vars should contain at least all variables in the + support of f; if this condition is not met the minterm + built by this procedure may not be contained in + f. Builds a BDD for the minterm and returns a pointer + to it if successful; NULL otherwise. There are three reasons why the + procedure may fail: +
                          +
                        • It may run out of memory; +
                        • the function f may be the constant 0; +
                        • the minterm may not be contained in f. +
                        ] + + SideEffects [None] + + SeeAlso [Cudd_bddPickOneCube] + +******************************************************************************/ +DdNode * +Cudd_bddPickOneMinterm( + DdManager * dd /* manager */, + DdNode * f /* function from which to pick one minterm */, + DdNode ** vars /* array of variables */, + int n /* size of vars */) +{ + char *string; + int i, size; + int *indices; + int result; + DdNode *old, *neW; + + size = dd->size; + string = ALLOC(char, size); + if (string == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + indices = ALLOC(int,n); + if (indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(string); + return(NULL); + } + + for (i = 0; i < n; i++) { + indices[i] = vars[i]->index; + } + + result = Cudd_bddPickOneCube(dd,f,string); + if (result == 0) { + FREE(string); + FREE(indices); + return(NULL); + } + + /* Randomize choice for don't cares. */ + for (i = 0; i < n; i++) { + if (string[indices[i]] == 2) + string[indices[i]] = (char) ((Cudd_Random() & 0x20) >> 5); + } + + /* Build result BDD. */ + old = Cudd_ReadOne(dd); + cuddRef(old); + + for (i = n-1; i >= 0; i--) { + neW = Cudd_bddAnd(dd,old,Cudd_NotCond(vars[i],string[indices[i]]==0)); + if (neW == NULL) { + FREE(string); + FREE(indices); + Cudd_RecursiveDeref(dd,old); + return(NULL); + } + cuddRef(neW); + Cudd_RecursiveDeref(dd,old); + old = neW; + } + +#ifdef DD_DEBUG + /* Test. */ + if (Cudd_bddLeq(dd,old,f)) { + cuddDeref(old); + } else { + Cudd_RecursiveDeref(dd,old); + old = NULL; + } +#else + cuddDeref(old); +#endif + + FREE(string); + FREE(indices); + return(old); + +} /* end of Cudd_bddPickOneMinterm */ + + +/**Function******************************************************************** + + Synopsis [Picks k on-set minterms evenly distributed from given DD.] + + Description [Picks k on-set minterms evenly distributed from given DD. + The minterms are in terms of vars. The array + vars should contain at least all variables in the + support of f; if this condition is not met the minterms + built by this procedure may not be contained in + f. Builds an array of BDDs for the minterms and returns a + pointer to it if successful; NULL otherwise. There are three reasons + why the procedure may fail: +
                          +
                        • It may run out of memory; +
                        • the function f may be the constant 0; +
                        • the minterms may not be contained in f. +
                        ] + + SideEffects [None] + + SeeAlso [Cudd_bddPickOneMinterm Cudd_bddPickOneCube] + +******************************************************************************/ +DdNode ** +Cudd_bddPickArbitraryMinterms( + DdManager * dd /* manager */, + DdNode * f /* function from which to pick k minterms */, + DdNode ** vars /* array of variables */, + int n /* size of vars */, + int k /* number of minterms to find */) +{ + char **string; + int i, j, l, size; + int *indices; + int result; + DdNode **old, *neW; + double minterms; + char *saveString; + int saveFlag, savePoint, isSame; + + minterms = Cudd_CountMinterm(dd,f,n); + if ((double)k > minterms) { + return(NULL); + } + + size = dd->size; + string = ALLOC(char *, k); + if (string == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < k; i++) { + string[i] = ALLOC(char, size + 1); + if (string[i] == NULL) { + for (j = 0; j < i; j++) + FREE(string[i]); + FREE(string); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (j = 0; j < size; j++) string[i][j] = '2'; + string[i][size] = '\0'; + } + indices = ALLOC(int,n); + if (indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + FREE(string[i]); + FREE(string); + return(NULL); + } + + for (i = 0; i < n; i++) { + indices[i] = vars[i]->index; + } + + result = ddPickArbitraryMinterms(dd,f,n,k,string); + if (result == 0) { + for (i = 0; i < k; i++) + FREE(string[i]); + FREE(string); + FREE(indices); + return(NULL); + } + + old = ALLOC(DdNode *, k); + if (old == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + FREE(string[i]); + FREE(string); + FREE(indices); + return(NULL); + } + saveString = ALLOC(char, size + 1); + if (saveString == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + FREE(string[i]); + FREE(string); + FREE(indices); + FREE(old); + return(NULL); + } + saveFlag = 0; + + /* Build result BDD array. */ + for (i = 0; i < k; i++) { + isSame = 0; + if (!saveFlag) { + for (j = i + 1; j < k; j++) { + if (strcmp(string[i], string[j]) == 0) { + savePoint = i; + strcpy(saveString, string[i]); + saveFlag = 1; + break; + } + } + } else { + if (strcmp(string[i], saveString) == 0) { + isSame = 1; + } else { + saveFlag = 0; + for (j = i + 1; j < k; j++) { + if (strcmp(string[i], string[j]) == 0) { + savePoint = i; + strcpy(saveString, string[i]); + saveFlag = 1; + break; + } + } + } + } + /* Randomize choice for don't cares. */ + for (j = 0; j < n; j++) { + if (string[i][indices[j]] == '2') + string[i][indices[j]] = + (char) ((Cudd_Random() & 0x20) ? '1' : '0'); + } + + while (isSame) { + isSame = 0; + for (j = savePoint; j < i; j++) { + if (strcmp(string[i], string[j]) == 0) { + isSame = 1; + break; + } + } + if (isSame) { + strcpy(string[i], saveString); + /* Randomize choice for don't cares. */ + for (j = 0; j < n; j++) { + if (string[i][indices[j]] == '2') + string[i][indices[j]] = + (char) ((Cudd_Random() & 0x20) ? '1' : '0'); + } + } + } + + old[i] = Cudd_ReadOne(dd); + cuddRef(old[i]); + + for (j = 0; j < n; j++) { + if (string[i][indices[j]] == '0') { + neW = Cudd_bddAnd(dd,old[i],Cudd_Not(vars[j])); + } else { + neW = Cudd_bddAnd(dd,old[i],vars[j]); + } + if (neW == NULL) { + FREE(saveString); + for (l = 0; l < k; l++) + FREE(string[l]); + FREE(string); + FREE(indices); + for (l = 0; l <= i; l++) + Cudd_RecursiveDeref(dd,old[l]); + FREE(old); + return(NULL); + } + cuddRef(neW); + Cudd_RecursiveDeref(dd,old[i]); + old[i] = neW; + } + + /* Test. */ + if (!Cudd_bddLeq(dd,old[i],f)) { + FREE(saveString); + for (l = 0; l < k; l++) + FREE(string[l]); + FREE(string); + FREE(indices); + for (l = 0; l <= i; l++) + Cudd_RecursiveDeref(dd,old[l]); + FREE(old); + return(NULL); + } + } + + FREE(saveString); + for (i = 0; i < k; i++) { + cuddDeref(old[i]); + FREE(string[i]); + } + FREE(string); + FREE(indices); + return(old); + +} /* end of Cudd_bddPickArbitraryMinterms */ + + +/**Function******************************************************************** + + Synopsis [Extracts a subset from a BDD.] + + Description [Extracts a subset from a BDD in the following procedure. + 1. Compute the weight for each mask variable by counting the number of + minterms for both positive and negative cofactors of the BDD with + respect to each mask variable. (weight = #positive - #negative) + 2. Find a representative cube of the BDD by using the weight. From the + top variable of the BDD, for each variable, if the weight is greater + than 0.0, choose THEN branch, othereise ELSE branch, until meeting + the constant 1. + 3. Quantify out the variables not in maskVars from the representative + cube and if a variable in maskVars is don't care, replace the + variable with a constant(1 or 0) depending on the weight. + 4. Make a subset of the BDD by multiplying with the modified cube.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_SubsetWithMaskVars( + DdManager * dd /* manager */, + DdNode * f /* function from which to pick a cube */, + DdNode ** vars /* array of variables */, + int nvars /* size of vars */, + DdNode ** maskVars /* array of variables */, + int mvars /* size of maskVars */) +{ + double *weight; + char *string; + int i, size; + int *indices, *mask; + int result; + DdNode *zero, *cube, *newCube, *subset; + DdNode *cof; + + DdNode *support; + support = Cudd_Support(dd,f); + cuddRef(support); + Cudd_RecursiveDeref(dd,support); + + zero = Cudd_Not(dd->one); + size = dd->size; + + weight = ALLOC(double,size); + if (weight == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + weight[i] = 0.0; + } + for (i = 0; i < mvars; i++) { + cof = Cudd_Cofactor(dd, f, maskVars[i]); + cuddRef(cof); + weight[i] = Cudd_CountMinterm(dd, cof, nvars); + Cudd_RecursiveDeref(dd,cof); + + cof = Cudd_Cofactor(dd, f, Cudd_Not(maskVars[i])); + cuddRef(cof); + weight[i] -= Cudd_CountMinterm(dd, cof, nvars); + Cudd_RecursiveDeref(dd,cof); + } + + string = ALLOC(char, size + 1); + if (string == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(weight); + return(NULL); + } + mask = ALLOC(int, size); + if (mask == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(weight); + FREE(string); + return(NULL); + } + for (i = 0; i < size; i++) { + string[i] = '2'; + mask[i] = 0; + } + string[size] = '\0'; + indices = ALLOC(int,nvars); + if (indices == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(weight); + FREE(string); + FREE(mask); + return(NULL); + } + for (i = 0; i < nvars; i++) { + indices[i] = vars[i]->index; + } + + result = ddPickRepresentativeCube(dd,f,weight,string); + if (result == 0) { + FREE(weight); + FREE(string); + FREE(mask); + FREE(indices); + return(NULL); + } + + cube = Cudd_ReadOne(dd); + cuddRef(cube); + zero = Cudd_Not(Cudd_ReadOne(dd)); + for (i = 0; i < nvars; i++) { + if (string[indices[i]] == '0') { + newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); + } else if (string[indices[i]] == '1') { + newCube = Cudd_bddIte(dd,cube,vars[i],zero); + } else + continue; + if (newCube == NULL) { + FREE(weight); + FREE(string); + FREE(mask); + FREE(indices); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(newCube); + Cudd_RecursiveDeref(dd,cube); + cube = newCube; + } + Cudd_RecursiveDeref(dd,cube); + + for (i = 0; i < mvars; i++) { + mask[maskVars[i]->index] = 1; + } + for (i = 0; i < nvars; i++) { + if (mask[indices[i]]) { + if (string[indices[i]] == '2') { + if (weight[indices[i]] >= 0.0) + string[indices[i]] = '1'; + else + string[indices[i]] = '0'; + } + } else { + string[indices[i]] = '2'; + } + } + + cube = Cudd_ReadOne(dd); + cuddRef(cube); + zero = Cudd_Not(Cudd_ReadOne(dd)); + + /* Build result BDD. */ + for (i = 0; i < nvars; i++) { + if (string[indices[i]] == '0') { + newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); + } else if (string[indices[i]] == '1') { + newCube = Cudd_bddIte(dd,cube,vars[i],zero); + } else + continue; + if (newCube == NULL) { + FREE(weight); + FREE(string); + FREE(mask); + FREE(indices); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(newCube); + Cudd_RecursiveDeref(dd,cube); + cube = newCube; + } + + subset = Cudd_bddAnd(dd,f,cube); + cuddRef(subset); + Cudd_RecursiveDeref(dd,cube); + + /* Test. */ + if (Cudd_bddLeq(dd,subset,f)) { + cuddDeref(subset); + } else { + Cudd_RecursiveDeref(dd,subset); + subset = NULL; + } + + FREE(weight); + FREE(string); + FREE(mask); + FREE(indices); + return(subset); + +} /* end of Cudd_SubsetWithMaskVars */ + + +/**Function******************************************************************** + + Synopsis [Finds the first cube of a decision diagram.] + + Description [Defines an iterator on the onset of a decision diagram + and finds its first cube. Returns a generator that contains the + information necessary to continue the enumeration if successful; NULL + otherwise.

                        + A cube is represented as an array of literals, which are integers in + {0, 1, 2}; 0 represents a complemented literal, 1 represents an + uncomplemented literal, and 2 stands for don't care. The enumeration + produces a disjoint cover of the function associated with the diagram. + The size of the array equals the number of variables in the manager at + the time Cudd_FirstCube is called.

                        + For each cube, a value is also returned. This value is always 1 for a + BDD, while it may be different from 1 for an ADD. + For BDDs, the offset is the set of cubes whose value is the logical zero. + For ADDs, the offset is the set of cubes whose value is the + background value. The cubes of the offset are not enumerated.] + + SideEffects [The first cube and its value are returned as side effects.] + + SeeAlso [Cudd_ForeachCube Cudd_NextCube Cudd_GenFree Cudd_IsGenEmpty + Cudd_FirstNode] + +******************************************************************************/ +DdGen * +Cudd_FirstCube( + DdManager * dd, + DdNode * f, + int ** cube, + CUDD_VALUE_TYPE * value) +{ + DdGen *gen; + DdNode *top, *treg, *next, *nreg, *prev, *preg; + int i; + int nvars; + + /* Sanity Check. */ + if (dd == NULL || f == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ALLOC(DdGen,1); + if (gen == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = dd; + gen->type = CUDD_GEN_CUBES; + gen->status = CUDD_GEN_EMPTY; + gen->gen.cubes.cube = NULL; + gen->gen.cubes.value = DD_ZERO_VAL; + gen->stack.sp = 0; + gen->stack.stack = NULL; + gen->node = NULL; + + nvars = dd->size; + gen->gen.cubes.cube = ALLOC(int,nvars); + if (gen->gen.cubes.cube == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(gen); + return(NULL); + } + for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; + + /* The maximum stack depth is one plus the number of variables. + ** because a path may have nodes at all levels, including the + ** constant level. + */ + gen->stack.stack = ALLOC(DdNodePtr, nvars+1); + if (gen->stack.stack == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(gen->gen.cubes.cube); + FREE(gen); + return(NULL); + } + for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; + + /* Find the first cube of the onset. */ + gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; + + while (1) { + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + if (!cuddIsConstant(treg)) { + /* Take the else branch first. */ + gen->gen.cubes.cube[treg->index] = 0; + next = cuddE(treg); + if (top != treg) next = Cudd_Not(next); + gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; + } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { + /* Backtrack */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = gen->stack.stack[gen->stack.sp-2]; + preg = Cudd_Regular(prev); + nreg = cuddT(preg); + if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[preg->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[preg->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(top); + goto done; + } + } + +done: + *cube = gen->gen.cubes.cube; + *value = gen->gen.cubes.value; + return(gen); + +} /* end of Cudd_FirstCube */ + + +/**Function******************************************************************** + + Synopsis [Generates the next cube of a decision diagram onset.] + + Description [Generates the next cube of a decision diagram onset, + using generator gen. Returns 0 if the enumeration is completed; 1 + otherwise.] + + SideEffects [The cube and its value are returned as side effects. The + generator is modified.] + + SeeAlso [Cudd_ForeachCube Cudd_FirstCube Cudd_GenFree Cudd_IsGenEmpty + Cudd_NextNode] + +******************************************************************************/ +int +Cudd_NextCube( + DdGen * gen, + int ** cube, + CUDD_VALUE_TYPE * value) +{ + DdNode *top, *treg, *next, *nreg, *prev, *preg; + DdManager *dd = gen->manager; + + /* Backtrack from previously reached terminal node. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + prev = gen->stack.stack[gen->stack.sp-2]; + preg = Cudd_Regular(prev); + nreg = cuddT(preg); + if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[preg->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[preg->index] = 2; + gen->stack.sp--; + } + + while (1) { + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + if (!cuddIsConstant(treg)) { + /* Take the else branch first. */ + gen->gen.cubes.cube[treg->index] = 0; + next = cuddE(treg); + if (top != treg) next = Cudd_Not(next); + gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; + } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { + /* Backtrack */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = gen->stack.stack[gen->stack.sp-2]; + preg = Cudd_Regular(prev); + nreg = cuddT(preg); + if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[preg->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[preg->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(top); + goto done; + } + } + +done: + if (gen->status == CUDD_GEN_EMPTY) return(0); + *cube = gen->gen.cubes.cube; + *value = gen->gen.cubes.value; + return(1); + +} /* end of Cudd_NextCube */ + + +/**Function******************************************************************** + + Synopsis [Finds the first prime of a Boolean function.] + + Description [Defines an iterator on a pair of BDDs describing a + (possibly incompletely specified) Boolean functions and finds the + first cube of a cover of the function. Returns a generator + that contains the information necessary to continue the enumeration + if successful; NULL otherwise.

                        + + The two argument BDDs are the lower and upper bounds of an interval. + It is a mistake to call this function with a lower bound that is not + less than or equal to the upper bound.

                        + + A cube is represented as an array of literals, which are integers in + {0, 1, 2}; 0 represents a complemented literal, 1 represents an + uncomplemented literal, and 2 stands for don't care. The enumeration + produces a prime and irredundant cover of the function associated + with the two BDDs. The size of the array equals the number of + variables in the manager at the time Cudd_FirstCube is called.

                        + + This iterator can only be used on BDDs.] + + SideEffects [The first cube is returned as side effect.] + + SeeAlso [Cudd_ForeachPrime Cudd_NextPrime Cudd_GenFree Cudd_IsGenEmpty + Cudd_FirstCube Cudd_FirstNode] + +******************************************************************************/ +DdGen * +Cudd_FirstPrime( + DdManager *dd, + DdNode *l, + DdNode *u, + int **cube) +{ + DdGen *gen; + DdNode *implicant, *prime, *tmp; + int length, result; + + /* Sanity Check. */ + if (dd == NULL || l == NULL || u == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ALLOC(DdGen,1); + if (gen == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = dd; + gen->type = CUDD_GEN_PRIMES; + gen->status = CUDD_GEN_EMPTY; + gen->gen.primes.cube = NULL; + gen->gen.primes.ub = u; + gen->stack.sp = 0; + gen->stack.stack = NULL; + gen->node = l; + cuddRef(l); + + gen->gen.primes.cube = ALLOC(int,dd->size); + if (gen->gen.primes.cube == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(gen); + return(NULL); + } + + if (gen->node == Cudd_ReadLogicZero(dd)) { + gen->status = CUDD_GEN_EMPTY; + } else { + implicant = Cudd_LargestCube(dd,gen->node,&length); + if (implicant == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + FREE(gen->gen.primes.cube); + FREE(gen); + return(NULL); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,implicant); + FREE(gen->gen.primes.cube); + FREE(gen); + return(NULL); + } + cuddRef(prime); + Cudd_RecursiveDeref(dd,implicant); + tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,prime); + FREE(gen->gen.primes.cube); + FREE(gen); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,gen->node); + gen->node = tmp; + result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); + if (result == 0) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,prime); + FREE(gen->gen.primes.cube); + FREE(gen); + return(NULL); + } + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_NONEMPTY; + } + *cube = gen->gen.primes.cube; + return(gen); + +} /* end of Cudd_FirstPrime */ + + +/**Function******************************************************************** + + Synopsis [Generates the next prime of a Boolean function.] + + Description [Generates the next cube of a Boolean function, + using generator gen. Returns 0 if the enumeration is completed; 1 + otherwise.] + + SideEffects [The cube and is returned as side effects. The + generator is modified.] + + SeeAlso [Cudd_ForeachPrime Cudd_FirstPrime Cudd_GenFree Cudd_IsGenEmpty + Cudd_NextCube Cudd_NextNode] + +******************************************************************************/ +int +Cudd_NextPrime( + DdGen *gen, + int **cube) +{ + DdNode *implicant, *prime, *tmp; + DdManager *dd = gen->manager; + int length, result; + + if (gen->node == Cudd_ReadLogicZero(dd)) { + gen->status = CUDD_GEN_EMPTY; + } else { + implicant = Cudd_LargestCube(dd,gen->node,&length); + if (implicant == NULL) { + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,implicant); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(prime); + Cudd_RecursiveDeref(dd,implicant); + tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,gen->node); + gen->node = tmp; + result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); + if (result == 0) { + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_NONEMPTY; + } + if (gen->status == CUDD_GEN_EMPTY) return(0); + *cube = gen->gen.primes.cube; + return(1); + +} /* end of Cudd_NextPrime */ + + +/**Function******************************************************************** + + Synopsis [Computes the cube of an array of BDD variables.] + + Description [Computes the cube of an array of BDD variables. If + non-null, the phase argument indicates which literal of each + variable should appear in the cube. If phase\[i\] is nonzero, then the + positive literal is used. If phase is NULL, the cube is positive unate. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addComputeCube Cudd_IndicesToCube Cudd_CubeArrayToBdd] + +******************************************************************************/ +DdNode * +Cudd_bddComputeCube( + DdManager * dd, + DdNode ** vars, + int * phase, + int n) +{ + DdNode *cube; + DdNode *fn; + int i; + + cube = DD_ONE(dd); + cuddRef(cube); + + for (i = n - 1; i >= 0; i--) { + if (phase == NULL || phase[i] != 0) { + fn = Cudd_bddAnd(dd,vars[i],cube); + } else { + fn = Cudd_bddAnd(dd,Cudd_Not(vars[i]),cube); + } + if (fn == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(fn); + Cudd_RecursiveDeref(dd,cube); + cube = fn; + } + cuddDeref(cube); + + return(cube); + +} /* end of Cudd_bddComputeCube */ + + +/**Function******************************************************************** + + Synopsis [Computes the cube of an array of ADD variables.] + + Description [Computes the cube of an array of ADD variables. If + non-null, the phase argument indicates which literal of each + variable should appear in the cube. If phase\[i\] is nonzero, then the + positive literal is used. If phase is NULL, the cube is positive unate. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [none] + + SeeAlso [Cudd_bddComputeCube] + +******************************************************************************/ +DdNode * +Cudd_addComputeCube( + DdManager * dd, + DdNode ** vars, + int * phase, + int n) +{ + DdNode *cube, *zero; + DdNode *fn; + int i; + + cube = DD_ONE(dd); + cuddRef(cube); + zero = DD_ZERO(dd); + + for (i = n - 1; i >= 0; i--) { + if (phase == NULL || phase[i] != 0) { + fn = Cudd_addIte(dd,vars[i],cube,zero); + } else { + fn = Cudd_addIte(dd,vars[i],zero,cube); + } + if (fn == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(fn); + Cudd_RecursiveDeref(dd,cube); + cube = fn; + } + cuddDeref(cube); + + return(cube); + +} /* end of Cudd_addComputeCube */ + + +/**Function******************************************************************** + + Synopsis [Builds the BDD of a cube from a positional array.] + + Description [Builds a cube from a positional array. The array must + have one integer entry for each BDD variable. If the i-th entry is + 1, the variable of index i appears in true form in the cube; If the + i-th entry is 0, the variable of index i appears complemented in the + cube; otherwise the variable does not appear in the cube. Returns a + pointer to the BDD for the cube if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddComputeCube Cudd_IndicesToCube Cudd_BddToCubeArray] + +******************************************************************************/ +DdNode * +Cudd_CubeArrayToBdd( + DdManager *dd, + int *array) +{ + DdNode *cube, *var, *tmp; + int i; + int size = Cudd_ReadSize(dd); + + cube = DD_ONE(dd); + cuddRef(cube); + for (i = size - 1; i >= 0; i--) { + if ((array[i] & ~1) == 0) { + var = Cudd_bddIthVar(dd,i); + tmp = Cudd_bddAnd(dd,cube,Cudd_NotCond(var,array[i]==0)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cube); + cube = tmp; + } + } + cuddDeref(cube); + return(cube); + +} /* end of Cudd_CubeArrayToBdd */ + + +/**Function******************************************************************** + + Synopsis [Builds a positional array from the BDD of a cube.] + + Description [Builds a positional array from the BDD of a cube. + Array must have one entry for each BDD variable. The positional + array has 1 in i-th position if the variable of index i appears in + true form in the cube; it has 0 in i-th position if the variable of + index i appears in complemented form in the cube; finally, it has 2 + in i-th position if the variable of index i does not appear in the + cube. Returns 1 if successful (the BDD is indeed a cube); 0 + otherwise.] + + SideEffects [The result is in the array passed by reference.] + + SeeAlso [Cudd_CubeArrayToBdd] + +******************************************************************************/ +int +Cudd_BddToCubeArray( + DdManager *dd, + DdNode *cube, + int *array) +{ + DdNode *scan, *t, *e; + int i; + int size = Cudd_ReadSize(dd); + DdNode *zero = Cudd_Not(DD_ONE(dd)); + + for (i = size-1; i >= 0; i--) { + array[i] = 2; + } + scan = cube; + while (!Cudd_IsConstant(scan)) { + int index = Cudd_Regular(scan)->index; + cuddGetBranches(scan,&t,&e); + if (t == zero) { + array[index] = 0; + scan = e; + } else if (e == zero) { + array[index] = 1; + scan = t; + } else { + return(0); /* cube is not a cube */ + } + } + if (scan == zero) { + return(0); + } else { + return(1); + } + +} /* end of Cudd_BddToCubeArray */ + + +/**Function******************************************************************** + + Synopsis [Finds the first node of a decision diagram.] + + Description [Defines an iterator on the nodes of a decision diagram + and finds its first node. Returns a generator that contains the + information necessary to continue the enumeration if successful; + NULL otherwise. The nodes are enumerated in a reverse topological + order, so that a node is always preceded in the enumeration by its + descendants.] + + SideEffects [The first node is returned as a side effect.] + + SeeAlso [Cudd_ForeachNode Cudd_NextNode Cudd_GenFree Cudd_IsGenEmpty + Cudd_FirstCube] + +******************************************************************************/ +DdGen * +Cudd_FirstNode( + DdManager * dd, + DdNode * f, + DdNode ** node) +{ + DdGen *gen; + int size; + + /* Sanity Check. */ + if (dd == NULL || f == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ALLOC(DdGen,1); + if (gen == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = dd; + gen->type = CUDD_GEN_NODES; + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp = 0; + gen->node = NULL; + + /* Collect all the nodes on the generator stack for later perusal. */ + gen->stack.stack = cuddNodeArray(Cudd_Regular(f), &size); + if (gen->stack.stack == NULL) { + FREE(gen); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + gen->gen.nodes.size = size; + + /* Find the first node. */ + if (gen->stack.sp < gen->gen.nodes.size) { + gen->status = CUDD_GEN_NONEMPTY; + gen->node = gen->stack.stack[gen->stack.sp]; + *node = gen->node; + } + + return(gen); + +} /* end of Cudd_FirstNode */ + + +/**Function******************************************************************** + + Synopsis [Finds the next node of a decision diagram.] + + Description [Finds the node of a decision diagram, using generator + gen. Returns 0 if the enumeration is completed; 1 otherwise.] + + SideEffects [The next node is returned as a side effect.] + + SeeAlso [Cudd_ForeachNode Cudd_FirstNode Cudd_GenFree Cudd_IsGenEmpty + Cudd_NextCube] + +******************************************************************************/ +int +Cudd_NextNode( + DdGen * gen, + DdNode ** node) +{ + /* Find the next node. */ + gen->stack.sp++; + if (gen->stack.sp < gen->gen.nodes.size) { + gen->node = gen->stack.stack[gen->stack.sp]; + *node = gen->node; + return(1); + } else { + gen->status = CUDD_GEN_EMPTY; + return(0); + } + +} /* end of Cudd_NextNode */ + + +/**Function******************************************************************** + + Synopsis [Frees a CUDD generator.] + + Description [Frees a CUDD generator. Always returns 0, so that it can + be used in mis-like foreach constructs.] + + SideEffects [None] + + SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube + Cudd_FirstNode Cudd_NextNode Cudd_IsGenEmpty] + +******************************************************************************/ +int +Cudd_GenFree( + DdGen * gen) +{ + if (gen == NULL) return(0); + switch (gen->type) { + case CUDD_GEN_CUBES: + case CUDD_GEN_ZDD_PATHS: + FREE(gen->gen.cubes.cube); + FREE(gen->stack.stack); + break; + case CUDD_GEN_PRIMES: + FREE(gen->gen.primes.cube); + Cudd_RecursiveDeref(gen->manager,gen->node); + break; + case CUDD_GEN_NODES: + FREE(gen->stack.stack); + break; + default: + return(0); + } + FREE(gen); + return(0); + +} /* end of Cudd_GenFree */ + + +/**Function******************************************************************** + + Synopsis [Queries the status of a generator.] + + Description [Queries the status of a generator. Returns 1 if the + generator is empty or NULL; 0 otherswise.] + + SideEffects [None] + + SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube + Cudd_FirstNode Cudd_NextNode Cudd_GenFree] + +******************************************************************************/ +int +Cudd_IsGenEmpty( + DdGen * gen) +{ + if (gen == NULL) return(1); + return(gen->status == CUDD_GEN_EMPTY); + +} /* end of Cudd_IsGenEmpty */ + + +/**Function******************************************************************** + + Synopsis [Builds a cube of BDD variables from an array of indices.] + + Description [Builds a cube of BDD variables from an array of indices. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddComputeCube Cudd_CubeArrayToBdd] + +******************************************************************************/ +DdNode * +Cudd_IndicesToCube( + DdManager * dd, + int * array, + int n) +{ + DdNode *cube, *tmp; + int i; + + cube = DD_ONE(dd); + cuddRef(cube); + for (i = n - 1; i >= 0; i--) { + tmp = Cudd_bddAnd(dd,Cudd_bddIthVar(dd,array[i]),cube); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cube); + cube = tmp; + } + + cuddDeref(cube); + return(cube); + +} /* end of Cudd_IndicesToCube */ + + +/**Function******************************************************************** + + Synopsis [Prints the package version number.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_PrintVersion( + FILE * fp) +{ + (void) fprintf(fp, "%s\n", CUDD_VERSION); + +} /* end of Cudd_PrintVersion */ + + +/**Function******************************************************************** + + Synopsis [Computes the average distance between adjacent nodes.] + + Description [Computes the average distance between adjacent nodes in + the manager. Adjacent nodes are node pairs such that the second node + is the then child, else child, or next node in the collision list.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +double +Cudd_AverageDistance( + DdManager * dd) +{ + double tetotal, nexttotal; + double tesubtotal, nextsubtotal; + double temeasured, nextmeasured; + int i, j; + int slots, nvars; + long diff; + DdNode *scan; + DdNodePtr *nodelist; + DdNode *sentinel = &(dd->sentinel); + + nvars = dd->size; + if (nvars == 0) return(0.0); + + /* Initialize totals. */ + tetotal = 0.0; + nexttotal = 0.0; + temeasured = 0.0; + nextmeasured = 0.0; + + /* Scan the variable subtables. */ + for (i = 0; i < nvars; i++) { + nodelist = dd->subtables[i].nodelist; + tesubtotal = 0.0; + nextsubtotal = 0.0; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != sentinel) { + diff = (long) scan - (long) cuddT(scan); + tesubtotal += (double) ddAbs(diff); + diff = (long) scan - (long) Cudd_Regular(cuddE(scan)); + tesubtotal += (double) ddAbs(diff); + temeasured += 2.0; + if (scan->next != sentinel) { + diff = (long) scan - (long) scan->next; + nextsubtotal += (double) ddAbs(diff); + nextmeasured += 1.0; + } + scan = scan->next; + } + } + tetotal += tesubtotal; + nexttotal += nextsubtotal; + } + + /* Scan the constant table. */ + nodelist = dd->constants.nodelist; + nextsubtotal = 0.0; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (scan->next != NULL) { + diff = (long) scan - (long) scan->next; + nextsubtotal += (double) ddAbs(diff); + nextmeasured += 1.0; + } + scan = scan->next; + } + } + nexttotal += nextsubtotal; + + return((tetotal + nexttotal) / (temeasured + nextmeasured)); + +} /* end of Cudd_AverageDistance */ + + +/**Function******************************************************************** + + Synopsis [Portable random number generator.] + + Description [Portable number generator based on ran2 from "Numerical + Recipes in C." It is a long period (> 2 * 10^18) random number generator + of L'Ecuyer with Bays-Durham shuffle. Returns a long integer uniformly + distributed between 0 and 2147483561 (inclusive of the endpoint values). + The random generator can be explicitly initialized by calling + Cudd_Srandom. If no explicit initialization is performed, then the + seed 1 is assumed.] + + SideEffects [None] + + SeeAlso [Cudd_Srandom] + +******************************************************************************/ +long +Cudd_Random(void) +{ + int i; /* index in the shuffle table */ + long int w; /* work variable */ + + /* cuddRand == 0 if the geneartor has not been initialized yet. */ + if (cuddRand == 0) Cudd_Srandom(1); + + /* Compute cuddRand = (cuddRand * LEQA1) % MODULUS1 avoiding + ** overflows by Schrage's method. + */ + w = cuddRand / LEQQ1; + cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; + cuddRand += (cuddRand < 0) * MODULUS1; + + /* Compute cuddRand2 = (cuddRand2 * LEQA2) % MODULUS2 avoiding + ** overflows by Schrage's method. + */ + w = cuddRand2 / LEQQ2; + cuddRand2 = LEQA2 * (cuddRand2 - w * LEQQ2) - w * LEQR2; + cuddRand2 += (cuddRand2 < 0) * MODULUS2; + + /* cuddRand is shuffled with the Bays-Durham algorithm. + ** shuffleSelect and cuddRand2 are combined to generate the output. + */ + + /* Pick one element from the shuffle table; "i" will be in the range + ** from 0 to STAB_SIZE-1. + */ + i = (int) (shuffleSelect / STAB_DIV); + /* Mix the element of the shuffle table with the current iterate of + ** the second sub-generator, and replace the chosen element of the + ** shuffle table with the current iterate of the first sub-generator. + */ + shuffleSelect = shuffleTable[i] - cuddRand2; + shuffleTable[i] = cuddRand; + shuffleSelect += (shuffleSelect < 1) * (MODULUS1 - 1); + /* Since shuffleSelect != 0, and we want to be able to return 0, + ** here we subtract 1 before returning. + */ + return(shuffleSelect - 1); + +} /* end of Cudd_Random */ + + +/**Function******************************************************************** + + Synopsis [Initializer for the portable random number generator.] + + Description [Initializer for the portable number generator based on + ran2 in "Numerical Recipes in C." The input is the seed for the + generator. If it is negative, its absolute value is taken as seed. + If it is 0, then 1 is taken as seed. The initialized sets up the two + recurrences used to generate a long-period stream, and sets up the + shuffle table.] + + SideEffects [None] + + SeeAlso [Cudd_Random] + +******************************************************************************/ +void +Cudd_Srandom( + long seed) +{ + int i; + + if (seed < 0) cuddRand = -seed; + else if (seed == 0) cuddRand = 1; + else cuddRand = seed; + cuddRand2 = cuddRand; + /* Load the shuffle table (after 11 warm-ups). */ + for (i = 0; i < STAB_SIZE + 11; i++) { + long int w; + w = cuddRand / LEQQ1; + cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; + cuddRand += (cuddRand < 0) * MODULUS1; + shuffleTable[i % STAB_SIZE] = cuddRand; + } + shuffleSelect = shuffleTable[1 % STAB_SIZE]; + +} /* end of Cudd_Srandom */ + + +/**Function******************************************************************** + + Synopsis [Computes the density of a BDD or ADD.] + + Description [Computes the density of a BDD or ADD. The density is + the ratio of the number of minterms to the number of nodes. If 0 is + passed as number of variables, the number of variables existing in + the manager is used. Returns the density if successful; (double) + CUDD_OUT_OF_MEM otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_CountMinterm Cudd_DagSize] + +******************************************************************************/ +double +Cudd_Density( + DdManager * dd /* manager */, + DdNode * f /* function whose density is sought */, + int nvars /* size of the support of f */) +{ + double minterms; + int nodes; + double density; + + if (nvars == 0) nvars = dd->size; + minterms = Cudd_CountMinterm(dd,f,nvars); + if (minterms == (double) CUDD_OUT_OF_MEM) return(minterms); + nodes = Cudd_DagSize(f); + density = minterms / (double) nodes; + return(density); + +} /* end of Cudd_Density */ + + +/**Function******************************************************************** + + Synopsis [Warns that a memory allocation failed.] + + Description [Warns that a memory allocation failed. + This function can be used as replacement of MMout_of_memory to prevent + the safe_mem functions of the util package from exiting when malloc + returns NULL. One possible use is in case of discretionary allocations; + for instance, the allocation of memory to enlarge the computed table.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_OutOfMem( + long size /* size of the allocation that failed */) +{ + (void) fflush(stdout); + (void) fprintf(stderr, "\nunable to allocate %ld bytes\n", size); + return; + +} /* end of Cudd_OutOfMem */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints a DD to the standard output. One line per node is + printed.] + + Description [Prints a DD to the standard output. One line per node is + printed. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_PrintDebug] + +******************************************************************************/ +int +cuddP( + DdManager * dd, + DdNode * f) +{ + int retval; + st_table *table = st_init_table(st_ptrcmp,st_ptrhash); + + if (table == NULL) return(0); + + retval = dp2(dd,f,table); + st_free_table(table); + (void) fputc('\n',dd->out); + return(retval); + +} /* end of cuddP */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory used to store the minterm counts recorded + in the visited table.] + + Description [Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +enum st_retval +cuddStCountfree( + char * key, + char * value, + char * arg) +{ + double *d; + + d = (double *)value; + FREE(d); + return(ST_CONTINUE); + +} /* end of cuddStCountfree */ + + +/**Function******************************************************************** + + Synopsis [Recursively collects all the nodes of a DD in a symbol + table.] + + Description [Traverses the DD f and collects all its nodes in a + symbol table. f is assumed to be a regular pointer and + cuddCollectNodes guarantees this assumption in the recursive calls. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddCollectNodes( + DdNode * f, + st_table * visited) +{ + DdNode *T, *E; + int retval; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + /* If already visited, nothing to do. */ + if (st_is_member(visited, (char *) f) == 1) + return(1); + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) + return(0); + + /* Mark node as visited. */ + if (st_add_direct(visited, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + + /* Check terminal case. */ + if (cuddIsConstant(f)) + return(1); + + /* Recursive calls. */ + T = cuddT(f); + retval = cuddCollectNodes(T,visited); + if (retval != 1) return(retval); + E = Cudd_Regular(cuddE(f)); + retval = cuddCollectNodes(E,visited); + return(retval); + +} /* end of cuddCollectNodes */ + + +/**Function******************************************************************** + + Synopsis [Recursively collects all the nodes of a DD in an array.] + + Description [Traverses the DD f and collects all its nodes in an array. + The caller should free the array returned by cuddNodeArray. + Returns a pointer to the array of nodes in case of success; NULL + otherwise. The nodes are collected in reverse topological order, so + that a node is always preceded in the array by all its descendants.] + + SideEffects [The number of nodes is returned as a side effect.] + + SeeAlso [Cudd_FirstNode] + +******************************************************************************/ +DdNodePtr * +cuddNodeArray( + DdNode *f, + int *n) +{ + DdNodePtr *table; + int size, retval; + + size = ddDagInt(Cudd_Regular(f)); + table = ALLOC(DdNodePtr, size); + if (table == NULL) { + ddClearFlag(Cudd_Regular(f)); + return(NULL); + } + + retval = cuddNodeArrayRecur(f, table, 0); + assert(retval == size); + + *n = size; + return(table); + +} /* cuddNodeArray */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of cuddP.] + + Description [Performs the recursive step of cuddP. Returns 1 in case + of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +dp2( + DdManager *dd, + DdNode * f, + st_table * t) +{ + DdNode *g, *n, *N; + int T,E; + + if (f == NULL) { + return(0); + } + g = Cudd_Regular(f); + if (cuddIsConstant(g)) { +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"ID = %c0x%lx\tvalue = %-9g\n", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g)); +#else + (void) fprintf(dd->out,"ID = %c0x%x\tvalue = %-9g\n", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g)); +#endif + return(1); + } + if (st_is_member(t,(char *) g) == 1) { + return(1); + } + if (st_add_direct(t,(char *) g,NULL) == ST_OUT_OF_MEM) + return(0); +#ifdef DD_STATS +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %d\tr = %d\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode), g->index, g->ref); +#else + (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\tr = %d\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),g->index,g->ref); +#endif +#else +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %u\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),g->index); +#else + (void) fprintf(dd->out,"ID = %c0x%x\tindex = %hu\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),g->index); +#endif +#endif + n = cuddT(g); + if (cuddIsConstant(n)) { + (void) fprintf(dd->out,"T = %-9g\t",cuddV(n)); + T = 1; + } else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"T = 0x%lx\t",(ptruint) n / (ptruint) sizeof(DdNode)); +#else + (void) fprintf(dd->out,"T = 0x%x\t",(ptruint) n / (ptruint) sizeof(DdNode)); +#endif + T = 0; + } + + n = cuddE(g); + N = Cudd_Regular(n); + if (cuddIsConstant(N)) { + (void) fprintf(dd->out,"E = %c%-9g\n",bang(n),cuddV(N)); + E = 1; + } else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(dd->out,"E = %c0x%lx\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode)); +#else + (void) fprintf(dd->out,"E = %c0x%x\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode)); +#endif + E = 0; + } + if (E == 0) { + if (dp2(dd,N,t) == 0) + return(0); + } + if (T == 0) { + if (dp2(dd,cuddT(g),t) == 0) + return(0); + } + return(1); + +} /* end of dp2 */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_PrintMinterm.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static void +ddPrintMintermAux( + DdManager * dd /* manager */, + DdNode * node /* current node */, + int * list /* current recursion path */) +{ + DdNode *N,*Nv,*Nnv; + int i,v,index; + + N = Cudd_Regular(node); + + if (cuddIsConstant(N)) { + /* Terminal case: Print one cube based on the current recursion + ** path, unless we have reached the background value (ADDs) or + ** the logical zero (BDDs). + */ + if (node != background && node != zero) { + for (i = 0; i < dd->size; i++) { + v = list[i]; + if (v == 0) (void) fprintf(dd->out,"0"); + else if (v == 1) (void) fprintf(dd->out,"1"); + else (void) fprintf(dd->out,"-"); + } + (void) fprintf(dd->out," % g\n", cuddV(node)); + } + } else { + Nv = cuddT(N); + Nnv = cuddE(N); + if (Cudd_IsComplement(node)) { + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); + } + index = N->index; + list[index] = 0; + ddPrintMintermAux(dd,Nnv,list); + list[index] = 1; + ddPrintMintermAux(dd,Nv,list); + list[index] = 2; + } + return; + +} /* end of ddPrintMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_DagSize.] + + Description [Performs the recursive step of Cudd_DagSize. Returns the + number of nodes in the graph rooted at n.] + + SideEffects [None] + +******************************************************************************/ +static int +ddDagInt( + DdNode * n) +{ + int tval, eval; + + if (Cudd_IsComplement(n->next)) { + return(0); + } + n->next = Cudd_Not(n->next); + if (cuddIsConstant(n)) { + return(1); + } + tval = ddDagInt(cuddT(n)); + eval = ddDagInt(Cudd_Regular(cuddE(n))); + return(1 + tval + eval); + +} /* end of ddDagInt */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of cuddNodeArray.] + + Description [Performs the recursive step of cuddNodeArray. Returns + an the number of nodes in the DD. Clear the least significant bit + of the next field that was used as visited flag by + cuddNodeArrayRecur when counting the nodes. node is supposed to be + regular; the invariant is maintained by this procedure.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddNodeArrayRecur( + DdNode *f, + DdNodePtr *table, + int index) +{ + int tindex, eindex; + + if (!Cudd_IsComplement(f->next)) { + return(index); + } + /* Clear visited flag. */ + f->next = Cudd_Regular(f->next); + if (cuddIsConstant(f)) { + table[index] = f; + return(index + 1); + } + tindex = cuddNodeArrayRecur(cuddT(f), table, index); + eindex = cuddNodeArrayRecur(Cudd_Regular(cuddE(f)), table, tindex); + table[eindex] = f; + return(eindex + 1); + +} /* end of cuddNodeArrayRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CofactorEstimate.] + + Description [Performs the recursive step of Cudd_CofactorEstimate. + Returns an estimate of the number of nodes in the DD of a + cofactor of node. Uses the least significant bit of the next field as + visited flag. node is supposed to be regular; the invariant is maintained + by this procedure.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddEstimateCofactor( + DdManager *dd, + st_table *table, + DdNode * node, + int i, + int phase, + DdNode ** ptr) +{ + int tval, eval, val; + DdNode *ptrT, *ptrE; + + if (Cudd_IsComplement(node->next)) { + if (!st_lookup(table,(char *)node,(char **)ptr)) { + if (st_add_direct(table,(char *)node,(char *)node) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + *ptr = node; + } + return(0); + } + node->next = Cudd_Not(node->next); + if (cuddIsConstant(node)) { + *ptr = node; + if (st_add_direct(table,(char *)node,(char *)node) == ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + return(1); + } + if ((int) node->index == i) { + if (phase == 1) { + *ptr = cuddT(node); + val = ddDagInt(cuddT(node)); + } else { + *ptr = cuddE(node); + val = ddDagInt(Cudd_Regular(cuddE(node))); + } + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + return(val); + } + if (dd->perm[node->index] > dd->perm[i]) { + *ptr = node; + tval = ddDagInt(cuddT(node)); + eval = ddDagInt(Cudd_Regular(cuddE(node))); + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)node) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + val = 1 + tval + eval; + return(val); + } + tval = cuddEstimateCofactor(dd,table,cuddT(node),i,phase,&ptrT); + eval = cuddEstimateCofactor(dd,table,Cudd_Regular(cuddE(node)),i, + phase,&ptrE); + ptrE = Cudd_NotCond(ptrE,Cudd_IsComplement(cuddE(node))); + if (ptrT == ptrE) { /* recombination */ + *ptr = ptrT; + val = tval; + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + } else if ((ptrT != cuddT(node) || ptrE != cuddE(node)) && + (*ptr = cuddUniqueLookup(dd,node->index,ptrT,ptrE)) != NULL) { + if (Cudd_IsComplement((*ptr)->next)) { + val = 0; + } else { + val = 1 + tval + eval; + } + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + } else { + *ptr = node; + val = 1 + tval + eval; + } + return(val); + +} /* end of cuddEstimateCofactor */ + + +/**Function******************************************************************** + + Synopsis [Checks the unique table for the existence of an internal node.] + + Description [Checks the unique table for the existence of an internal + node. Returns a pointer to the node if it is in the table; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddUniqueInter] + +******************************************************************************/ +static DdNode * +cuddUniqueLookup( + DdManager * unique, + int index, + DdNode * T, + DdNode * E) +{ + int posn; + unsigned int level; + DdNodePtr *nodelist; + DdNode *looking; + DdSubtable *subtable; + + if (index >= unique->size) { + return(NULL); + } + + level = unique->perm[index]; + subtable = &(unique->subtables[level]); + +#ifdef DD_DEBUG + assert(level < (unsigned) cuddI(unique,T->index)); + assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index)); +#endif + + posn = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + looking = nodelist[posn]; + + while (T < cuddT(looking)) { + looking = Cudd_Regular(looking->next); + } + while (T == cuddT(looking) && E < cuddE(looking)) { + looking = Cudd_Regular(looking->next); + } + if (cuddT(looking) == T && cuddE(looking) == E) { + return(looking); + } + + return(NULL); + +} /* end of cuddUniqueLookup */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CofactorEstimateSimple.] + + Description [Performs the recursive step of Cudd_CofactorEstimateSimple. + Returns an estimate of the number of nodes in the DD of the positive + cofactor of node. Uses the least significant bit of the next field as + visited flag. node is supposed to be regular; the invariant is maintained + by this procedure.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddEstimateCofactorSimple( + DdNode * node, + int i) +{ + int tval, eval; + + if (Cudd_IsComplement(node->next)) { + return(0); + } + node->next = Cudd_Not(node->next); + if (cuddIsConstant(node)) { + return(1); + } + tval = cuddEstimateCofactorSimple(cuddT(node),i); + if ((int) node->index == i) return(tval); + eval = cuddEstimateCofactorSimple(Cudd_Regular(cuddE(node)),i); + return(1 + tval + eval); + +} /* end of cuddEstimateCofactorSimple */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CountMinterm.] + + Description [Performs the recursive step of Cudd_CountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: +

                        + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. Does not use the + identity |f'| = max - |f|, to minimize loss of accuracy due to + roundoff. Returns the number of minterms of the function rooted at + node.] + + SideEffects [None] + +******************************************************************************/ +static double +ddCountMintermAux( + DdNode * node, + double max, + DdHashTable * table) +{ + DdNode *N, *Nt, *Ne; + double min, minT, minE; + DdNode *res; + + N = Cudd_Regular(node); + + if (cuddIsConstant(N)) { + if (node == background || node == zero) { + return(0.0); + } else { + return(max); + } + } + if (N->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) { + min = cuddV(res); + if (res->ref == 0) { + table->manager->dead++; + table->manager->constants.dead++; + } + return(min); + } + + Nt = cuddT(N); Ne = cuddE(N); + if (Cudd_IsComplement(node)) { + Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); + } + + minT = ddCountMintermAux(Nt,max,table); + if (minT == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + minT *= 0.5; + minE = ddCountMintermAux(Ne,max,table); + if (minE == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + minE *= 0.5; + min = minT + minE; + + if (N->ref != 1) { + ptrint fanout = (ptrint) N->ref; + cuddSatDec(fanout); + res = cuddUniqueConst(table->manager,min); + if (!cuddHashTableInsert1(table,node,res,fanout)) { + cuddRef(res); Cudd_RecursiveDeref(table->manager, res); + return((double)CUDD_OUT_OF_MEM); + } + } + + return(min); + +} /* end of ddCountMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CountPath.] + + Description [Performs the recursive step of Cudd_CountPath. + It is based on the following identity. Let |f| be the + number of paths of f. Then: + + |f| = |f0|+|f1| + + where f0 and f1 are the two cofactors of f. Uses the + identity |f'| = |f|, to improve the utilization of the (local) cache. + Returns the number of paths of the function rooted at node.] + + SideEffects [None] + +******************************************************************************/ +static double +ddCountPathAux( + DdNode * node, + st_table * table) +{ + + DdNode *Nv, *Nnv; + double paths, *ppaths, paths1, paths2; + double *dummy; + + + if (cuddIsConstant(node)) { + return(1.0); + } + if (st_lookup(table, node, &dummy)) { + paths = *dummy; + return(paths); + } + + Nv = cuddT(node); Nnv = cuddE(node); + + paths1 = ddCountPathAux(Nv,table); + if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + paths2 = ddCountPathAux(Cudd_Regular(Nnv),table); + if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + paths = paths1 + paths2; + + ppaths = ALLOC(double,1); + if (ppaths == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + + *ppaths = paths; + + if (st_add_direct(table,(char *)node, (char *)ppaths) == ST_OUT_OF_MEM) { + FREE(ppaths); + return((double)CUDD_OUT_OF_MEM); + } + return(paths); + +} /* end of ddCountPathAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_EpdCountMinterm.] + + Description [Performs the recursive step of Cudd_EpdCountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. Does not use the + identity |f'| = max - |f|, to minimize loss of accuracy due to + roundoff. Returns the number of minterms of the function rooted at + node.] + + SideEffects [None] + +******************************************************************************/ +static int +ddEpdCountMintermAux( + DdNode * node, + EpDouble * max, + EpDouble * epd, + st_table * table) +{ + DdNode *Nt, *Ne; + EpDouble *min, minT, minE; + EpDouble *res; + int status; + + /* node is assumed to be regular */ + if (cuddIsConstant(node)) { + if (node == background || node == zero) { + EpdMakeZero(epd, 0); + } else { + EpdCopy(max, epd); + } + return(0); + } + if (node->ref != 1 && st_lookup(table, node, &res)) { + EpdCopy(res, epd); + return(0); + } + + Nt = cuddT(node); Ne = cuddE(node); + + status = ddEpdCountMintermAux(Nt,max,&minT,table); + if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + EpdMultiply(&minT, (double)0.5); + status = ddEpdCountMintermAux(Cudd_Regular(Ne),max,&minE,table); + if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + if (Cudd_IsComplement(Ne)) { + EpdSubtract3(max, &minE, epd); + EpdCopy(epd, &minE); + } + EpdMultiply(&minE, (double)0.5); + EpdAdd3(&minT, &minE, epd); + + if (node->ref > 1) { + min = EpdAlloc(); + if (!min) + return(CUDD_OUT_OF_MEM); + EpdCopy(epd, min); + if (st_insert(table, (char *)node, (char *)min) == ST_OUT_OF_MEM) { + EpdFree(min); + return(CUDD_OUT_OF_MEM); + } + } + + return(0); + +} /* end of ddEpdCountMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CountPathsToNonZero.] + + Description [Performs the recursive step of Cudd_CountPathsToNonZero. + It is based on the following identity. Let |f| be the + number of paths of f. Then: + + |f| = |f0|+|f1| + + where f0 and f1 are the two cofactors of f. Returns the number of + paths of the function rooted at node.] + + SideEffects [None] + +******************************************************************************/ +static double +ddCountPathsToNonZero( + DdNode * N, + st_table * table) +{ + + DdNode *node, *Nt, *Ne; + double paths, *ppaths, paths1, paths2; + double *dummy; + + node = Cudd_Regular(N); + if (cuddIsConstant(node)) { + return((double) !(Cudd_IsComplement(N) || cuddV(node)==DD_ZERO_VAL)); + } + if (st_lookup(table, N, &dummy)) { + paths = *dummy; + return(paths); + } + + Nt = cuddT(node); Ne = cuddE(node); + if (node != N) { + Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); + } + + paths1 = ddCountPathsToNonZero(Nt,table); + if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + paths2 = ddCountPathsToNonZero(Ne,table); + if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); + paths = paths1 + paths2; + + ppaths = ALLOC(double,1); + if (ppaths == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + + *ppaths = paths; + + if (st_add_direct(table,(char *)N, (char *)ppaths) == ST_OUT_OF_MEM) { + FREE(ppaths); + return((double)CUDD_OUT_OF_MEM); + } + return(paths); + +} /* end of ddCountPathsToNonZero */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_Support.] + + Description [Performs the recursive step of Cudd_Support. Performs a + DFS from f. The support is accumulated in supp as a side effect. Uses + the LSB of the then pointer as visited flag.] + + SideEffects [None] + + SeeAlso [ddClearFlag] + +******************************************************************************/ +static void +ddSupportStep( + DdNode * f, + int * support) +{ + if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) + return; + + support[f->index] = 1; + ddSupportStep(cuddT(f),support); + ddSupportStep(Cudd_Regular(cuddE(f)),support); + /* Mark as visited. */ + f->next = Cudd_Complement(f->next); + +} /* end of ddSupportStep */ + + +/**Function******************************************************************** + + Synopsis [Performs a DFS from f, clearing the LSB of the next + pointers.] + + Description [] + + SideEffects [None] + + SeeAlso [ddSupportStep ddFindSupport ddLeavesInt ddDagInt] + +******************************************************************************/ +static void +ddClearFlag( + DdNode * f) +{ + if (!Cudd_IsComplement(f->next)) { + return; + } + /* Clear visited flag. */ + f->next = Cudd_Regular(f->next); + if (cuddIsConstant(f)) { + return; + } + ddClearFlag(cuddT(f)); + ddClearFlag(Cudd_Regular(cuddE(f))); + return; + +} /* end of ddClearFlag */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_CountLeaves.] + + Description [Performs the recursive step of Cudd_CountLeaves. Returns + the number of leaves in the DD rooted at n.] + + SideEffects [None] + + SeeAlso [Cudd_CountLeaves] + +******************************************************************************/ +static int +ddLeavesInt( + DdNode * n) +{ + int tval, eval; + + if (Cudd_IsComplement(n->next)) { + return(0); + } + n->next = Cudd_Not(n->next); + if (cuddIsConstant(n)) { + return(1); + } + tval = ddLeavesInt(cuddT(n)); + eval = ddLeavesInt(Cudd_Regular(cuddE(n))); + return(tval + eval); + +} /* end of ddLeavesInt */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddPickArbitraryMinterms.] + + Description [Performs the recursive step of Cudd_bddPickArbitraryMinterms. + Returns 1 if successful; 0 otherwise.] + + SideEffects [none] + + SeeAlso [Cudd_bddPickArbitraryMinterms] + +******************************************************************************/ +static int +ddPickArbitraryMinterms( + DdManager *dd, + DdNode *node, + int nvars, + int nminterms, + char **string) +{ + DdNode *N, *T, *E; + DdNode *one, *bzero; + int i, t, result; + double min1, min2; + + if (string == NULL || node == NULL) return(0); + + /* The constant 0 function has no on-set cubes. */ + one = DD_ONE(dd); + bzero = Cudd_Not(one); + if (nminterms == 0 || node == bzero) return(1); + if (node == one) { + return(1); + } + + N = Cudd_Regular(node); + T = cuddT(N); E = cuddE(N); + if (Cudd_IsComplement(node)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + + min1 = Cudd_CountMinterm(dd, T, nvars) / 2.0; + if (min1 == (double)CUDD_OUT_OF_MEM) return(0); + min2 = Cudd_CountMinterm(dd, E, nvars) / 2.0; + if (min2 == (double)CUDD_OUT_OF_MEM) return(0); + + t = (int)((double)nminterms * min1 / (min1 + min2) + 0.5); + for (i = 0; i < t; i++) + string[i][N->index] = '1'; + for (i = t; i < nminterms; i++) + string[i][N->index] = '0'; + + result = ddPickArbitraryMinterms(dd,T,nvars,t,&string[0]); + if (result == 0) + return(0); + result = ddPickArbitraryMinterms(dd,E,nvars,nminterms-t,&string[t]); + return(result); + +} /* end of ddPickArbitraryMinterms */ + + +/**Function******************************************************************** + + Synopsis [Finds a representative cube of a BDD.] + + Description [Finds a representative cube of a BDD with the weight of + each variable. From the top variable, if the weight is greater than or + equal to 0.0, choose THEN branch unless the child is the constant 0. + Otherwise, choose ELSE branch unless the child is the constant 0.] + + SideEffects [Cudd_SubsetWithMaskVars Cudd_bddPickOneCube] + +******************************************************************************/ +static int +ddPickRepresentativeCube( + DdManager *dd, + DdNode *node, + double *weight, + char *string) +{ + DdNode *N, *T, *E; + DdNode *one, *bzero; + + if (string == NULL || node == NULL) return(0); + + /* The constant 0 function has no on-set cubes. */ + one = DD_ONE(dd); + bzero = Cudd_Not(one); + if (node == bzero) return(0); + + if (node == DD_ONE(dd)) return(1); + + for (;;) { + N = Cudd_Regular(node); + if (N == one) + break; + T = cuddT(N); + E = cuddE(N); + if (Cudd_IsComplement(node)) { + T = Cudd_Not(T); + E = Cudd_Not(E); + } + if (weight[N->index] >= 0.0) { + if (T == bzero) { + node = E; + string[N->index] = '0'; + } else { + node = T; + string[N->index] = '1'; + } + } else { + if (E == bzero) { + node = T; + string[N->index] = '1'; + } else { + node = E; + string[N->index] = '0'; + } + } + } + return(1); + +} /* end of ddPickRepresentativeCube */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory used to store the minterm counts recorded + in the visited table.] + + Description [Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +ddEpdFree( + char * key, + char * value, + char * arg) +{ + EpDouble *epd; + + epd = (EpDouble *) value; + EpdFree(epd); + return(ST_CONTINUE); + +} /* end of ddEpdFree */ + + +/**Function******************************************************************** + + Synopsis [Recursively find the support of f.] + + Description [Recursively find the support of f. This function uses the + LSB of the next field of the nodes of f as visited flag. It also uses the + LSB of the next field of the variables as flag to remember whether a + certain index has already been seen. Finally, it uses the manager stack + to record all seen indices.] + + SideEffects [The stack pointer SP is modified by side-effect. The next + fields are changed and need to be reset.] + +******************************************************************************/ +static void +ddFindSupport( + DdManager *dd, + DdNode *f, + int *SP) +{ + int index; + DdNode *var; + + if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) { + return; + } + + index = f->index; + var = dd->vars[index]; + /* It is possible that var is embedded in f. That causes no problem, + ** though, because if we see it after encountering another node with + ** the same index, nothing is supposed to happen. + */ + if (!Cudd_IsComplement(var->next)) { + var->next = Cudd_Complement(var->next); + dd->stack[*SP] = (DdNode *)(ptrint) index; + (*SP)++; + } + ddFindSupport(dd, cuddT(f), SP); + ddFindSupport(dd, Cudd_Regular(cuddE(f)), SP); + /* Mark as visited. */ + f->next = Cudd_Complement(f->next); + +} /* end of ddFindSupport */ + + +/**Function******************************************************************** + + Synopsis [Clears visited flags for variables.] + + Description [Clears visited flags for variables.] + + SideEffects [None] + +******************************************************************************/ +static void +ddClearVars( + DdManager *dd, + int SP) +{ + int i; + + for (i = 0; i < SP; i++) { + int index = (int) (ptrint) dd->stack[i]; + DdNode *var = dd->vars[index]; + var->next = Cudd_Regular(var->next); + } + +} /* end of ddClearVars */ + + +/**Function******************************************************************** + + Synopsis [Compares indices for qsort.] + + Description [Compares indices for qsort. Subtracting these integers + cannot produce overflow, because they are non-negative.] + + SideEffects [None] + +******************************************************************************/ +static int +indexCompare( + const void *a, + const void *b) +{ + int ia = *((int *) a); + int ib = *((int *) b); + return(ia - ib); + +} /* end of indexCompare */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddWindow.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddWindow.c new file mode 100644 index 000000000..2f80beb16 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddWindow.c @@ -0,0 +1,1023 @@ +/**CFile*********************************************************************** + + FileName [cuddWindow.c] + + PackageName [cudd] + + Synopsis [Functions for variable reordering by window permutation.] + + Description [Internal procedures included in this module: +
                          +
                        • cuddWindowReorder() +
                        + Static procedures included in this module: +
                          +
                        • ddWindow2() +
                        • ddWindowConv2() +
                        • ddPermuteWindow3() +
                        • ddWindow3() +
                        • ddWindowConv3() +
                        • ddPermuteWindow4() +
                        • ddWindow4() +
                        • ddWindowConv4() +
                        ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddWindow.c,v 1.15 2012/02/05 01:07:19 fabio Exp $"; +#endif + +#ifdef DD_STATS +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int ddWindow2 (DdManager *table, int low, int high); +static int ddWindowConv2 (DdManager *table, int low, int high); +static int ddPermuteWindow3 (DdManager *table, int x); +static int ddWindow3 (DdManager *table, int low, int high); +static int ddWindowConv3 (DdManager *table, int low, int high); +static int ddPermuteWindow4 (DdManager *table, int w); +static int ddWindow4 (DdManager *table, int low, int high); +static int ddWindowConv4 (DdManager *table, int low, int high); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Reorders by applying the method of the sliding window.] + + Description [Reorders by applying the method of the sliding window. + Tries all possible permutations to the variables in a window that + slides from low to high. The size of the window is determined by + submethod. Assumes that no dead nodes are present. Returns 1 in + case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddWindowReorder( + DdManager * table /* DD table */, + int low /* lowest index to reorder */, + int high /* highest index to reorder */, + Cudd_ReorderingType submethod /* window reordering option */) +{ + + int res; +#ifdef DD_DEBUG + int supposedOpt; +#endif + + switch (submethod) { + case CUDD_REORDER_WINDOW2: + res = ddWindow2(table,low,high); + break; + case CUDD_REORDER_WINDOW3: + res = ddWindow3(table,low,high); + break; + case CUDD_REORDER_WINDOW4: + res = ddWindow4(table,low,high); + break; + case CUDD_REORDER_WINDOW2_CONV: + res = ddWindowConv2(table,low,high); + break; + case CUDD_REORDER_WINDOW3_CONV: + res = ddWindowConv3(table,low,high); +#ifdef DD_DEBUG + supposedOpt = table->keys - table->isolated; + res = ddWindow3(table,low,high); + if (table->keys - table->isolated != (unsigned) supposedOpt) { + (void) fprintf(table->err, "Convergence failed! (%d != %d)\n", + table->keys - table->isolated, supposedOpt); + } +#endif + break; + case CUDD_REORDER_WINDOW4_CONV: + res = ddWindowConv4(table,low,high); +#ifdef DD_DEBUG + supposedOpt = table->keys - table->isolated; + res = ddWindow4(table,low,high); + if (table->keys - table->isolated != (unsigned) supposedOpt) { + (void) fprintf(table->err,"Convergence failed! (%d != %d)\n", + table->keys - table->isolated, supposedOpt); + } +#endif + break; + default: return(0); + } + + return(res); + +} /* end of cuddWindowReorder */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reorders by applying a sliding window of width 2.] + + Description [Reorders by applying a sliding window of width 2. + Tries both permutations of the variables in a window + that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindow2( + DdManager * table, + int low, + int high) +{ + + int x; + int res; + int size; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 1) return(0); + + res = table->keys - table->isolated; + for (x = low; x < high; x++) { + size = res; + res = cuddSwapInPlace(table,x,x+1); + if (res == 0) return(0); + if (res >= size) { /* no improvement: undo permutation */ + res = cuddSwapInPlace(table,x,x+1); + if (res == 0) return(0); + } +#ifdef DD_STATS + if (res < size) { + (void) fprintf(table->out,"-"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + return(1); + +} /* end of ddWindow2 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by repeatedly applying a sliding window of width 2.] + + Description [Reorders by repeatedly applying a sliding window of width + 2. Tries both permutations of the variables in a window + that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindowConv2( + DdManager * table, + int low, + int high) +{ + int x; + int res; + int nwin; + int newevent; + int *events; + int size; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 1) return(ddWindowConv2(table,low,high)); + + nwin = high-low; + events = ALLOC(int,nwin); + if (events == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (x=0; xkeys - table->isolated; + do { + newevent = 0; + for (x=0; x= size) { /* no improvement: undo permutation */ + res = cuddSwapInPlace(table,x+low,x+low+1); + if (res == 0) { + FREE(events); + return(0); + } + } + if (res < size) { + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + } + events[x] = 0; +#ifdef DD_STATS + if (res < size) { + (void) fprintf(table->out,"-"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } +#ifdef DD_STATS + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } +#endif + } while (newevent); + + FREE(events); + + return(1); + +} /* end of ddWindowConv3 */ + + +/**Function******************************************************************** + + Synopsis [Tries all the permutations of the three variables between + x and x+2 and retains the best.] + + Description [Tries all the permutations of the three variables between + x and x+2 and retains the best. Assumes that no dead nodes are + present. Returns the index of the best permutation (1-6) in case of + success; 0 otherwise.Assumes that no dead nodes are present. Returns + the index of the best permutation (1-6) in case of success; 0 + otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddPermuteWindow3( + DdManager * table, + int x) +{ + int y,z; + int size,sizeNew; + int best; + +#ifdef DD_DEBUG + assert(table->dead == 0); + assert(x+2 < table->size); +#endif + + size = table->keys - table->isolated; + y = x+1; z = y+1; + + /* The permutation pattern is: + ** (x,y)(y,z) + ** repeated three times to get all 3! = 6 permutations. + */ +#define ABC 1 + best = ABC; + +#define BAC 2 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = BAC; + size = sizeNew; + } +#define BCA 3 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = BCA; + size = sizeNew; + } +#define CBA 4 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = CBA; + size = sizeNew; + } +#define CAB 5 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = CAB; + size = sizeNew; + } +#define ACB 6 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = ACB; + size = sizeNew; + } + + /* Now take the shortest route to the best permuytation. + ** The initial permutation is ACB. + */ + switch(best) { + case BCA: if (!cuddSwapInPlace(table,y,z)) return(0); + case CBA: if (!cuddSwapInPlace(table,x,y)) return(0); + case ABC: if (!cuddSwapInPlace(table,y,z)) return(0); + case ACB: break; + case BAC: if (!cuddSwapInPlace(table,y,z)) return(0); + case CAB: if (!cuddSwapInPlace(table,x,y)) return(0); + break; + default: return(0); + } + +#ifdef DD_DEBUG + assert(table->keys - table->isolated == (unsigned) size); +#endif + + return(best); + +} /* end of ddPermuteWindow3 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by applying a sliding window of width 3.] + + Description [Reorders by applying a sliding window of width 3. + Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindow3( + DdManager * table, + int low, + int high) +{ + + int x; + int res; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 2) return(ddWindow2(table,low,high)); + + for (x = low; x+1 < high; x++) { + res = ddPermuteWindow3(table,x); + if (res == 0) return(0); +#ifdef DD_STATS + if (res == ABC) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); +#endif + } + + return(1); + +} /* end of ddWindow3 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by repeatedly applying a sliding window of width 3.] + + Description [Reorders by repeatedly applying a sliding window of width + 3. Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindowConv3( + DdManager * table, + int low, + int high) +{ + int x; + int res; + int nwin; + int newevent; + int *events; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 2) return(ddWindowConv2(table,low,high)); + + nwin = high-low-1; + events = ALLOC(int,nwin); + if (events == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (x=0; x 1) events[x-2] = 1; + newevent = 1; + break; + case BCA: + case CBA: + case CAB: + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + case ACB: + if (x < nwin-2) events[x+2] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + break; + default: + FREE(events); + return(0); + } + events[x] = 0; +#ifdef DD_STATS + if (res == ABC) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); +#endif + } + } +#ifdef DD_STATS + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } +#endif + } while (newevent); + + FREE(events); + + return(1); + +} /* end of ddWindowConv3 */ + + +/**Function******************************************************************** + + Synopsis [Tries all the permutations of the four variables between w + and w+3 and retains the best.] + + Description [Tries all the permutations of the four variables between + w and w+3 and retains the best. Assumes that no dead nodes are + present. Returns the index of the best permutation (1-24) in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddPermuteWindow4( + DdManager * table, + int w) +{ + int x,y,z; + int size,sizeNew; + int best; + +#ifdef DD_DEBUG + assert(table->dead == 0); + assert(w+3 < table->size); +#endif + + size = table->keys - table->isolated; + x = w+1; y = x+1; z = y+1; + + /* The permutation pattern is: + * (w,x)(y,z)(w,x)(x,y) + * (y,z)(w,x)(y,z)(x,y) + * repeated three times to get all 4! = 24 permutations. + * This gives a hamiltonian circuit of Cayley's graph. + * The codes to the permutation are assigned in topological order. + * The permutations at lower distance from the final permutation are + * assigned lower codes. This way we can choose, between + * permutations that give the same size, one that requires the minimum + * number of swaps from the final permutation of the hamiltonian circuit. + * There is an exception to this rule: ABCD is given Code 1, to + * avoid oscillation when convergence is sought. + */ +#define ABCD 1 + best = ABCD; + +#define BACD 7 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = BACD; + size = sizeNew; + } +#define BADC 13 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = BADC; + size = sizeNew; + } +#define ABDC 8 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && ABDC < best)) { + if (sizeNew == 0) return(0); + best = ABDC; + size = sizeNew; + } +#define ADBC 14 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = ADBC; + size = sizeNew; + } +#define ADCB 9 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && ADCB < best)) { + if (sizeNew == 0) return(0); + best = ADCB; + size = sizeNew; + } +#define DACB 15 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = DACB; + size = sizeNew; + } +#define DABC 20 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = DABC; + size = sizeNew; + } +#define DBAC 23 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = DBAC; + size = sizeNew; + } +#define BDAC 19 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && BDAC < best)) { + if (sizeNew == 0) return(0); + best = BDAC; + size = sizeNew; + } +#define BDCA 21 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && BDCA < best)) { + if (sizeNew == 0) return(0); + best = BDCA; + size = sizeNew; + } +#define DBCA 24 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size) { + if (sizeNew == 0) return(0); + best = DBCA; + size = sizeNew; + } +#define DCBA 22 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size || (sizeNew == size && DCBA < best)) { + if (sizeNew == 0) return(0); + best = DCBA; + size = sizeNew; + } +#define DCAB 18 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && DCAB < best)) { + if (sizeNew == 0) return(0); + best = DCAB; + size = sizeNew; + } +#define CDAB 12 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && CDAB < best)) { + if (sizeNew == 0) return(0); + best = CDAB; + size = sizeNew; + } +#define CDBA 17 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && CDBA < best)) { + if (sizeNew == 0) return(0); + best = CDBA; + size = sizeNew; + } +#define CBDA 11 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size || (sizeNew == size && CBDA < best)) { + if (sizeNew == 0) return(0); + best = CBDA; + size = sizeNew; + } +#define BCDA 16 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && BCDA < best)) { + if (sizeNew == 0) return(0); + best = BCDA; + size = sizeNew; + } +#define BCAD 10 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && BCAD < best)) { + if (sizeNew == 0) return(0); + best = BCAD; + size = sizeNew; + } +#define CBAD 5 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && CBAD < best)) { + if (sizeNew == 0) return(0); + best = CBAD; + size = sizeNew; + } +#define CABD 3 + sizeNew = cuddSwapInPlace(table,x,y); + if (sizeNew < size || (sizeNew == size && CABD < best)) { + if (sizeNew == 0) return(0); + best = CABD; + size = sizeNew; + } +#define CADB 6 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && CADB < best)) { + if (sizeNew == 0) return(0); + best = CADB; + size = sizeNew; + } +#define ACDB 4 + sizeNew = cuddSwapInPlace(table,w,x); + if (sizeNew < size || (sizeNew == size && ACDB < best)) { + if (sizeNew == 0) return(0); + best = ACDB; + size = sizeNew; + } +#define ACBD 2 + sizeNew = cuddSwapInPlace(table,y,z); + if (sizeNew < size || (sizeNew == size && ACBD < best)) { + if (sizeNew == 0) return(0); + best = ACBD; + size = sizeNew; + } + + /* Now take the shortest route to the best permutation. + ** The initial permutation is ACBD. + */ + switch(best) { + case DBCA: if (!cuddSwapInPlace(table,y,z)) return(0); + case BDCA: if (!cuddSwapInPlace(table,x,y)) return(0); + case CDBA: if (!cuddSwapInPlace(table,w,x)) return(0); + case ADBC: if (!cuddSwapInPlace(table,y,z)) return(0); + case ABDC: if (!cuddSwapInPlace(table,x,y)) return(0); + case ACDB: if (!cuddSwapInPlace(table,y,z)) return(0); + case ACBD: break; + case DCBA: if (!cuddSwapInPlace(table,y,z)) return(0); + case BCDA: if (!cuddSwapInPlace(table,x,y)) return(0); + case CBDA: if (!cuddSwapInPlace(table,w,x)) return(0); + if (!cuddSwapInPlace(table,x,y)) return(0); + if (!cuddSwapInPlace(table,y,z)) return(0); + break; + case DBAC: if (!cuddSwapInPlace(table,x,y)) return(0); + case DCAB: if (!cuddSwapInPlace(table,w,x)) return(0); + case DACB: if (!cuddSwapInPlace(table,y,z)) return(0); + case BACD: if (!cuddSwapInPlace(table,x,y)) return(0); + case CABD: if (!cuddSwapInPlace(table,w,x)) return(0); + break; + case DABC: if (!cuddSwapInPlace(table,y,z)) return(0); + case BADC: if (!cuddSwapInPlace(table,x,y)) return(0); + case CADB: if (!cuddSwapInPlace(table,w,x)) return(0); + if (!cuddSwapInPlace(table,y,z)) return(0); + break; + case BDAC: if (!cuddSwapInPlace(table,x,y)) return(0); + case CDAB: if (!cuddSwapInPlace(table,w,x)) return(0); + case ADCB: if (!cuddSwapInPlace(table,y,z)) return(0); + case ABCD: if (!cuddSwapInPlace(table,x,y)) return(0); + break; + case BCAD: if (!cuddSwapInPlace(table,x,y)) return(0); + case CBAD: if (!cuddSwapInPlace(table,w,x)) return(0); + if (!cuddSwapInPlace(table,x,y)) return(0); + break; + default: return(0); + } + +#ifdef DD_DEBUG + assert(table->keys - table->isolated == (unsigned) size); +#endif + + return(best); + +} /* end of ddPermuteWindow4 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by applying a sliding window of width 4.] + + Description [Reorders by applying a sliding window of width 4. + Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindow4( + DdManager * table, + int low, + int high) +{ + + int w; + int res; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 3) return(ddWindow3(table,low,high)); + + for (w = low; w+2 < high; w++) { + res = ddPermuteWindow4(table,w); + if (res == 0) return(0); +#ifdef DD_STATS + if (res == ABCD) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); +#endif + } + + return(1); + +} /* end of ddWindow4 */ + + +/**Function******************************************************************** + + Synopsis [Reorders by repeatedly applying a sliding window of width 4.] + + Description [Reorders by repeatedly applying a sliding window of width + 4. Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +ddWindowConv4( + DdManager * table, + int low, + int high) +{ + int x; + int res; + int nwin; + int newevent; + int *events; + +#ifdef DD_DEBUG + assert(low >= 0 && high < table->size); +#endif + + if (high-low < 3) return(ddWindowConv3(table,low,high)); + + nwin = high-low-2; + events = ALLOC(int,nwin); + if (events == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (x=0; x 2) events[x-3] = 1; + newevent = 1; + break; + case BADC: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case ABDC: + if (x < nwin-3) events[x+3] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + break; + case ADBC: + case ADCB: + case ACDB: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-2) events[x+2] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + case DACB: + case DABC: + case DBAC: + case BDAC: + case BDCA: + case DBCA: + case DCBA: + case DCAB: + case CDAB: + case CDBA: + case CBDA: + case BCDA: + case CADB: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case BCAD: + case CBAD: + case CABD: + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 1) events[x-2] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case ACBD: + if (x < nwin-2) events[x+2] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + default: + FREE(events); + return(0); + } + events[x] = 0; +#ifdef DD_STATS + if (res == ABCD) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); +#endif + } + } +#ifdef DD_STATS + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } +#endif + } while (newevent); + + FREE(events); + + return(1); + +} /* end of ddWindowConv4 */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddCount.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddCount.c new file mode 100644 index 000000000..b65d1022f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddCount.c @@ -0,0 +1,357 @@ +/**CFile*********************************************************************** + + FileName [cuddZddCount.c] + + PackageName [cudd] + + Synopsis [Procedures to count the number of minterms of a ZDD.] + + Description [External procedures included in this module: +
                          +
                        • Cudd_zddCount(); +
                        • Cudd_zddCountDouble(); +
                        + Internal procedures included in this module: +
                          +
                        + Static procedures included in this module: +
                          +
                        • cuddZddCountStep(); +
                        • cuddZddCountDoubleStep(); +
                        • st_zdd_count_dbl_free() +
                        • st_zdd_countfree() +
                        + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.15 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddZddCountStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty); +static double cuddZddCountDoubleStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty); +static enum st_retval st_zdd_countfree (char *key, char *value, char *arg); +static enum st_retval st_zdd_count_dbl_free (char *key, char *value, char *arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms in a ZDD.] + + Description [Returns an integer representing the number of minterms + in a ZDD.] + + SideEffects [None] + + SeeAlso [Cudd_zddCountDouble] + +******************************************************************************/ +int +Cudd_zddCount( + DdManager * zdd, + DdNode * P) +{ + st_table *table; + int res; + DdNode *base, *empty; + + base = DD_ONE(zdd); + empty = DD_ZERO(zdd); + table = st_init_table(st_ptrcmp, st_ptrhash); + if (table == NULL) return(CUDD_OUT_OF_MEM); + res = cuddZddCountStep(P, table, base, empty); + if (res == CUDD_OUT_OF_MEM) { + zdd->errorCode = CUDD_MEMORY_OUT; + } + st_foreach(table, st_zdd_countfree, NIL(char)); + st_free_table(table); + + return(res); + +} /* end of Cudd_zddCount */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a ZDD.] + + Description [Counts the number of minterms of a ZDD. The result is + returned as a double. If the procedure runs out of memory, it + returns (double) CUDD_OUT_OF_MEM. This procedure is used in + Cudd_zddCountMinterm.] + + SideEffects [None] + + SeeAlso [Cudd_zddCountMinterm Cudd_zddCount] + +******************************************************************************/ +double +Cudd_zddCountDouble( + DdManager * zdd, + DdNode * P) +{ + st_table *table; + double res; + DdNode *base, *empty; + + base = DD_ONE(zdd); + empty = DD_ZERO(zdd); + table = st_init_table(st_ptrcmp, st_ptrhash); + if (table == NULL) return((double)CUDD_OUT_OF_MEM); + res = cuddZddCountDoubleStep(P, table, base, empty); + if (res == (double)CUDD_OUT_OF_MEM) { + zdd->errorCode = CUDD_MEMORY_OUT; + } + st_foreach(table, st_zdd_count_dbl_free, NIL(char)); + st_free_table(table); + + return(res); + +} /* end of Cudd_zddCountDouble */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddCount.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddCountStep( + DdNode * P, + st_table * table, + DdNode * base, + DdNode * empty) +{ + int res; + int *dummy; + + if (P == empty) + return(0); + if (P == base) + return(1); + + /* Check cache. */ + if (st_lookup(table, P, &dummy)) { + res = *dummy; + return(res); + } + + res = cuddZddCountStep(cuddE(P), table, base, empty) + + cuddZddCountStep(cuddT(P), table, base, empty); + + dummy = ALLOC(int, 1); + if (dummy == NULL) { + return(CUDD_OUT_OF_MEM); + } + *dummy = res; + if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) { + FREE(dummy); + return(CUDD_OUT_OF_MEM); + } + + return(res); + +} /* end of cuddZddCountStep */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddCountDouble.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double +cuddZddCountDoubleStep( + DdNode * P, + st_table * table, + DdNode * base, + DdNode * empty) +{ + double res; + double *dummy; + + if (P == empty) + return((double)0.0); + if (P == base) + return((double)1.0); + + /* Check cache */ + if (st_lookup(table, P, &dummy)) { + res = *dummy; + return(res); + } + + res = cuddZddCountDoubleStep(cuddE(P), table, base, empty) + + cuddZddCountDoubleStep(cuddT(P), table, base, empty); + + dummy = ALLOC(double, 1); + if (dummy == NULL) { + return((double)CUDD_OUT_OF_MEM); + } + *dummy = res; + if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) { + FREE(dummy); + return((double)CUDD_OUT_OF_MEM); + } + + return(res); + +} /* end of cuddZddCountDoubleStep */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory associated with the computed table of + Cudd_zddCount.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static enum st_retval +st_zdd_countfree( + char * key, + char * value, + char * arg) +{ + int *d; + + d = (int *)value; + FREE(d); + return(ST_CONTINUE); + +} /* end of st_zdd_countfree */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory associated with the computed table of + Cudd_zddCountDouble.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static enum st_retval +st_zdd_count_dbl_free( + char * key, + char * value, + char * arg) +{ + double *d; + + d = (double *)value; + FREE(d); + return(ST_CONTINUE); + +} /* end of st_zdd_count_dbl_free */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddFuncs.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddFuncs.c new file mode 100644 index 000000000..9d818212b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddFuncs.c @@ -0,0 +1,1630 @@ +/**CFile*********************************************************************** + + FileName [cuddZddFuncs.c] + + PackageName [cudd] + + Synopsis [Functions to manipulate covers represented as ZDDs.] + + Description [External procedures included in this module: +
                          +
                        • Cudd_zddProduct(); +
                        • Cudd_zddUnateProduct(); +
                        • Cudd_zddWeakDiv(); +
                        • Cudd_zddWeakDivF(); +
                        • Cudd_zddDivide(); +
                        • Cudd_zddDivideF(); +
                        • Cudd_zddComplement(); +
                        + Internal procedures included in this module: +
                          +
                        • cuddZddProduct(); +
                        • cuddZddUnateProduct(); +
                        • cuddZddWeakDiv(); +
                        • cuddZddWeakDivF(); +
                        • cuddZddDivide(); +
                        • cuddZddDivideF(); +
                        • cuddZddGetCofactors3() +
                        • cuddZddGetCofactors2() +
                        • cuddZddComplement(); +
                        • cuddZddGetPosVarIndex(); +
                        • cuddZddGetNegVarIndex(); +
                        • cuddZddGetPosVarLevel(); +
                        • cuddZddGetNegVarLevel(); +
                        + Static procedures included in this module: +
                          +
                        + ] + + SeeAlso [] + + Author [In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddFuncs.c,v 1.17 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the product of two covers represented by ZDDs.] + + Description [Computes the product of two covers represented by + ZDDs. The result is also a ZDD. Returns a pointer to the result if + successful; NULL otherwise. The covers on which Cudd_zddProduct + operates use two ZDD variables for each function variable (one ZDD + variable for each literal of the variable). Those two ZDD variables + should be adjacent in the order.] + + SideEffects [None] + + SeeAlso [Cudd_zddUnateProduct] + +******************************************************************************/ +DdNode * +Cudd_zddProduct( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddProduct(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddProduct */ + + +/**Function******************************************************************** + + Synopsis [Computes the product of two unate covers.] + + Description [Computes the product of two unate covers represented as + ZDDs. Unate covers use one ZDD variable for each BDD + variable. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddProduct] + +******************************************************************************/ +DdNode * +Cudd_zddUnateProduct( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddUnateProduct(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddUnateProduct */ + + +/**Function******************************************************************** + + Synopsis [Applies weak division to two covers.] + + Description [Applies weak division to two ZDDs representing two + covers. Returns a pointer to the ZDD representing the result if + successful; NULL otherwise. The result of weak division depends on + the variable order. The covers on which Cudd_zddWeakDiv operates use + two ZDD variables for each function variable (one ZDD variable for + each literal of the variable). Those two ZDD variables should be + adjacent in the order.] + + SideEffects [None] + + SeeAlso [Cudd_zddDivide] + +******************************************************************************/ +DdNode * +Cudd_zddWeakDiv( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddWeakDiv(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddWeakDiv */ + + +/**Function******************************************************************** + + Synopsis [Computes the quotient of two unate covers.] + + Description [Computes the quotient of two unate covers represented + by ZDDs. Unate covers use one ZDD variable for each BDD + variable. Returns a pointer to the resulting ZDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddWeakDiv] + +******************************************************************************/ +DdNode * +Cudd_zddDivide( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddDivide(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddDivide */ + + +/**Function******************************************************************** + + Synopsis [Modified version of Cudd_zddWeakDiv.] + + Description [Modified version of Cudd_zddWeakDiv. This function may + disappear in future releases.] + + SideEffects [None] + + SeeAlso [Cudd_zddWeakDiv] + +******************************************************************************/ +DdNode * +Cudd_zddWeakDivF( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddWeakDivF(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddWeakDivF */ + + +/**Function******************************************************************** + + Synopsis [Modified version of Cudd_zddDivide.] + + Description [Modified version of Cudd_zddDivide. This function may + disappear in future releases.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddDivideF( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddDivideF(dd, f, g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddDivideF */ + + +/**Function******************************************************************** + + Synopsis [Computes a complement cover for a ZDD node.] + + Description [Computes a complement cover for a ZDD node. For lack of a + better method, we first extract the function BDD from the ZDD cover, + then make the complement of the ZDD cover from the complement of the + BDD node by using ISOP. Returns a pointer to the resulting cover if + successful; NULL otherwise. The result depends on current variable + order.] + + SideEffects [The result depends on current variable order.] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddComplement( + DdManager *dd, + DdNode *node) +{ + DdNode *b, *isop, *zdd_I; + + /* Check cache */ + zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node); + if (zdd_I) + return(zdd_I); + + b = Cudd_MakeBddFromZddCover(dd, node); + if (!b) + return(NULL); + Cudd_Ref(b); + isop = Cudd_zddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I); + if (!isop) { + Cudd_RecursiveDeref(dd, b); + return(NULL); + } + Cudd_Ref(isop); + Cudd_Ref(zdd_I); + Cudd_RecursiveDeref(dd, b); + Cudd_RecursiveDeref(dd, isop); + + cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I); + Cudd_Deref(zdd_I); + return(zdd_I); +} /* end of Cudd_zddComplement */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddProduct.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddProduct] + +******************************************************************************/ +DdNode * +cuddZddProduct( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v, top_f, top_g; + DdNode *tmp, *term1, *term2, *term3; + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *R0, *R1, *Rd, *N0, *N1; + DdNode *r; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + int flag; + int pv, nv; + + statLine(dd); + if (f == zero || g == zero) + return(zero); + if (f == one) + return(g); + if (g == one) + return(f); + + top_f = dd->permZ[f->index]; + top_g = dd->permZ[g->index]; + + if (top_f > top_g) + return(cuddZddProduct(dd, g, f)); + + /* Check cache */ + r = cuddCacheLookup2Zdd(dd, cuddZddProduct, f, g); + if (r) + return(r); + + v = f->index; /* either yi or zi */ + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + Cudd_Ref(gd); + pv = cuddZddGetPosVarIndex(dd, v); + nv = cuddZddGetNegVarIndex(dd, v); + + Rd = cuddZddProduct(dd, fd, gd); + if (Rd == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(Rd); + + term1 = cuddZddProduct(dd, f0, g0); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + return(NULL); + } + Cudd_Ref(term1); + term2 = cuddZddProduct(dd, f0, gd); + if (term2 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term2); + term3 = cuddZddProduct(dd, fd, g0); + if (term3 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); + } + Cudd_Ref(term3); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g0); + tmp = cuddZddUnion(dd, term1, term2); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + R0 = cuddZddUnion(dd, tmp, term3); + if (R0 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(R0); + Cudd_RecursiveDerefZdd(dd, tmp); + Cudd_RecursiveDerefZdd(dd, term3); + N0 = cuddZddGetNode(dd, nv, R0, Rd); /* nv = zi */ + if (N0 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, R0); + return(NULL); + } + Cudd_Ref(N0); + Cudd_RecursiveDerefZdd(dd, R0); + Cudd_RecursiveDerefZdd(dd, Rd); + + term1 = cuddZddProduct(dd, f1, g1); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + return(NULL); + } + Cudd_Ref(term1); + term2 = cuddZddProduct(dd, f1, gd); + if (term2 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term2); + term3 = cuddZddProduct(dd, fd, g1); + if (term3 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); + } + Cudd_Ref(term3); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + tmp = cuddZddUnion(dd, term1, term2); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + R1 = cuddZddUnion(dd, tmp, term3); + if (R1 == NULL) { + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(R1); + Cudd_RecursiveDerefZdd(dd, tmp); + Cudd_RecursiveDerefZdd(dd, term3); + N1 = cuddZddGetNode(dd, pv, R1, N0); /* pv = yi */ + if (N1 == NULL) { + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, R1); + return(NULL); + } + Cudd_Ref(N1); + Cudd_RecursiveDerefZdd(dd, R1); + Cudd_RecursiveDerefZdd(dd, N0); + + cuddCacheInsert2(dd, cuddZddProduct, f, g, N1); + Cudd_Deref(N1); + return(N1); + +} /* end of cuddZddProduct */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddUnateProduct.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddUnateProduct] + +******************************************************************************/ +DdNode * +cuddZddUnateProduct( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v, top_f, top_g; + DdNode *term1, *term2, *term3, *term4; + DdNode *sum1, *sum2; + DdNode *f0, *f1, *g0, *g1; + DdNode *r; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + int flag; + + statLine(dd); + if (f == zero || g == zero) + return(zero); + if (f == one) + return(g); + if (g == one) + return(f); + + top_f = dd->permZ[f->index]; + top_g = dd->permZ[g->index]; + + if (top_f > top_g) + return(cuddZddUnateProduct(dd, g, f)); + + /* Check cache */ + r = cuddCacheLookup2Zdd(dd, cuddZddUnateProduct, f, g); + if (r) + return(r); + + v = f->index; /* either yi or zi */ + flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + + term1 = cuddZddUnateProduct(dd, f1, g1); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(term1); + term2 = cuddZddUnateProduct(dd, f1, g0); + if (term2 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term2); + term3 = cuddZddUnateProduct(dd, f0, g1); + if (term3 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); + } + Cudd_Ref(term3); + term4 = cuddZddUnateProduct(dd, f0, g0); + if (term4 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); + } + Cudd_Ref(term4); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + sum1 = cuddZddUnion(dd, term1, term2); + if (sum1 == NULL) { + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, term4); + return(NULL); + } + Cudd_Ref(sum1); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + sum2 = cuddZddUnion(dd, sum1, term3); + if (sum2 == NULL) { + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, term4); + Cudd_RecursiveDerefZdd(dd, sum1); + return(NULL); + } + Cudd_Ref(sum2); + Cudd_RecursiveDerefZdd(dd, sum1); + Cudd_RecursiveDerefZdd(dd, term3); + r = cuddZddGetNode(dd, v, sum2, term4); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, term4); + Cudd_RecursiveDerefZdd(dd, sum2); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDerefZdd(dd, sum2); + Cudd_RecursiveDerefZdd(dd, term4); + + cuddCacheInsert2(dd, cuddZddUnateProduct, f, g, r); + Cudd_Deref(r); + return(r); + +} /* end of cuddZddUnateProduct */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddWeakDiv.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddWeakDiv] + +******************************************************************************/ +DdNode * +cuddZddWeakDiv( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *q, *tmp; + DdNode *r; + int flag; + + statLine(dd); + if (g == one) + return(f); + if (f == zero || f == one) + return(zero); + if (f == g) + return(one); + + /* Check cache. */ + r = cuddCacheLookup2Zdd(dd, cuddZddWeakDiv, f, g); + if (r) + return(r); + + v = g->index; + + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + Cudd_Ref(gd); + + q = g; + + if (g0 != zero) { + q = cuddZddWeakDiv(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + } + else + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g0); + + if (q == zero) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); + Cudd_Deref(q); + return(zero); + } + + if (g1 != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDiv(dd, f1, g1); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + } + else { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + } + + if (q == zero) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); + Cudd_Deref(q); + return(zero); + } + + if (gd != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDiv(dd, fd, gd); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + } + else { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + } + + cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, q); + Cudd_Deref(q); + return(q); + +} /* end of cuddZddWeakDiv */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddWeakDivF.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddWeakDivF] + +******************************************************************************/ +DdNode * +cuddZddWeakDivF( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v, top_f, top_g, vf, vg; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *q, *tmp; + DdNode *r; + DdNode *term1, *term0, *termd; + int flag; + int pv, nv; + + statLine(dd); + if (g == one) + return(f); + if (f == zero || f == one) + return(zero); + if (f == g) + return(one); + + /* Check cache. */ + r = cuddCacheLookup2Zdd(dd, cuddZddWeakDivF, f, g); + if (r) + return(r); + + top_f = dd->permZ[f->index]; + top_g = dd->permZ[g->index]; + vf = top_f >> 1; + vg = top_g >> 1; + v = ddMin(top_f, top_g); + + if (v == top_f && vf < vg) { + v = f->index; + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + + pv = cuddZddGetPosVarIndex(dd, v); + nv = cuddZddGetNegVarIndex(dd, v); + + term1 = cuddZddWeakDivF(dd, f1, g); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(term1); + Cudd_RecursiveDerefZdd(dd, f1); + term0 = cuddZddWeakDivF(dd, f0, g); + if (term0 == NULL) { + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term0); + Cudd_RecursiveDerefZdd(dd, f0); + termd = cuddZddWeakDivF(dd, fd, g); + if (termd == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term0); + return(NULL); + } + Cudd_Ref(termd); + Cudd_RecursiveDerefZdd(dd, fd); + + tmp = cuddZddGetNode(dd, nv, term0, termd); /* nv = zi */ + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term0); + Cudd_RecursiveDerefZdd(dd, termd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, term0); + Cudd_RecursiveDerefZdd(dd, termd); + q = cuddZddGetNode(dd, pv, term1, tmp); /* pv = yi */ + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, tmp); + + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q); + Cudd_Deref(q); + return(q); + } + + if (v == top_f) + v = f->index; + else + v = g->index; + + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + Cudd_Ref(gd); + + q = g; + + if (g0 != zero) { + q = cuddZddWeakDivF(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + } + else + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g0); + + if (q == zero) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); + Cudd_Deref(q); + return(zero); + } + + if (g1 != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDivF(dd, f1, g1); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + } + else { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + } + + if (q == zero) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); + Cudd_Deref(q); + return(zero); + } + + if (gd != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDivF(dd, fd, gd); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + } + else { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + } + + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q); + Cudd_Deref(q); + return(q); + +} /* end of cuddZddWeakDivF */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddDivide.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddDivide] + +******************************************************************************/ +DdNode * +cuddZddDivide( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *g0, *g1; + DdNode *q, *r, *tmp; + int flag; + + statLine(dd); + if (g == one) + return(f); + if (f == zero || f == one) + return(zero); + if (f == g) + return(one); + + /* Check cache. */ + r = cuddCacheLookup2Zdd(dd, cuddZddDivide, f, g); + if (r) + return(r); + + v = g->index; + + flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */ + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + + r = cuddZddDivide(dd, f1, g1); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(r); + + if (r != zero && g0 != zero) { + tmp = r; + q = cuddZddDivide(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(q); + r = cuddZddIntersect(dd, r, q); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, q); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDerefZdd(dd, q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + + cuddCacheInsert2(dd, cuddZddDivide, f, g, r); + Cudd_Deref(r); + return(r); + +} /* end of cuddZddDivide */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddDivideF.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddDivideF] + +******************************************************************************/ +DdNode * +cuddZddDivideF( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *g0, *g1; + DdNode *q, *r, *tmp; + int flag; + + statLine(dd); + if (g == one) + return(f); + if (f == zero || f == one) + return(zero); + if (f == g) + return(one); + + /* Check cache. */ + r = cuddCacheLookup2Zdd(dd, cuddZddDivideF, f, g); + if (r) + return(r); + + v = g->index; + + flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */ + if (flag == 1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); + } + Cudd_Ref(g1); + Cudd_Ref(g0); + + r = cuddZddDivideF(dd, f1, g1); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(r); + + if (r != zero && g0 != zero) { + tmp = r; + q = cuddZddDivideF(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(q); + r = cuddZddIntersect(dd, r, q); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, q); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDerefZdd(dd, q); + Cudd_RecursiveDerefZdd(dd, tmp); + } + + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + + cuddCacheInsert2(dd, cuddZddDivideF, f, g, r); + Cudd_Deref(r); + return(r); + +} /* end of cuddZddDivideF */ + + +/**Function******************************************************************** + + Synopsis [Computes the three-way decomposition of f w.r.t. v.] + + Description [Computes the three-way decomposition of function f (represented + by a ZDD) wit respect to variable v. Returns 0 if successful; 1 otherwise.] + + SideEffects [The results are returned in f1, f0, and fd.] + + SeeAlso [cuddZddGetCofactors2] + +******************************************************************************/ +int +cuddZddGetCofactors3( + DdManager * dd, + DdNode * f, + int v, + DdNode ** f1, + DdNode ** f0, + DdNode ** fd) +{ + DdNode *pc, *nc; + DdNode *zero = DD_ZERO(dd); + int top, hv, ht, pv, nv; + int level; + + top = dd->permZ[f->index]; + level = dd->permZ[v]; + hv = level >> 1; + ht = top >> 1; + + if (hv < ht) { + *f1 = zero; + *f0 = zero; + *fd = f; + } + else { + pv = cuddZddGetPosVarIndex(dd, v); + nv = cuddZddGetNegVarIndex(dd, v); + + /* not to create intermediate ZDD node */ + if (cuddZddGetPosVarLevel(dd, v) < cuddZddGetNegVarLevel(dd, v)) { + pc = cuddZddSubset1(dd, f, pv); + if (pc == NULL) + return(1); + Cudd_Ref(pc); + nc = cuddZddSubset0(dd, f, pv); + if (nc == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + return(1); + } + Cudd_Ref(nc); + + *f1 = cuddZddSubset0(dd, pc, nv); + if (*f1 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + return(1); + } + Cudd_Ref(*f1); + *f0 = cuddZddSubset1(dd, nc, nv); + if (*f0 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + return(1); + } + Cudd_Ref(*f0); + + *fd = cuddZddSubset0(dd, nc, nv); + if (*fd == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*fd); + } else { + pc = cuddZddSubset1(dd, f, nv); + if (pc == NULL) + return(1); + Cudd_Ref(pc); + nc = cuddZddSubset0(dd, f, nv); + if (nc == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + return(1); + } + Cudd_Ref(nc); + + *f0 = cuddZddSubset0(dd, pc, pv); + if (*f0 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + return(1); + } + Cudd_Ref(*f0); + *f1 = cuddZddSubset1(dd, nc, pv); + if (*f1 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*f1); + + *fd = cuddZddSubset0(dd, nc, pv); + if (*fd == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*fd); + } + + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_Deref(*f1); + Cudd_Deref(*f0); + Cudd_Deref(*fd); + } + return(0); + +} /* end of cuddZddGetCofactors3 */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-way decomposition of f w.r.t. v.] + + Description [] + + SideEffects [The results are returned in f1 and f0.] + + SeeAlso [cuddZddGetCofactors3] + +******************************************************************************/ +int +cuddZddGetCofactors2( + DdManager * dd, + DdNode * f, + int v, + DdNode ** f1, + DdNode ** f0) +{ + *f1 = cuddZddSubset1(dd, f, v); + if (*f1 == NULL) + return(1); + *f0 = cuddZddSubset0(dd, f, v); + if (*f0 == NULL) { + Cudd_RecursiveDerefZdd(dd, *f1); + return(1); + } + return(0); + +} /* end of cuddZddGetCofactors2 */ + + +/**Function******************************************************************** + + Synopsis [Computes a complement of a ZDD node.] + + Description [Computes the complement of a ZDD node. So far, since we + couldn't find a direct way to get the complement of a ZDD cover, we first + convert a ZDD cover to a BDD, then make the complement of the ZDD cover + from the complement of the BDD node by using ISOP.] + + SideEffects [The result depends on current variable order.] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddComplement( + DdManager * dd, + DdNode *node) +{ + DdNode *b, *isop, *zdd_I; + + /* Check cache */ + zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node); + if (zdd_I) + return(zdd_I); + + b = cuddMakeBddFromZddCover(dd, node); + if (!b) + return(NULL); + cuddRef(b); + isop = cuddZddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I); + if (!isop) { + Cudd_RecursiveDeref(dd, b); + return(NULL); + } + cuddRef(isop); + cuddRef(zdd_I); + Cudd_RecursiveDeref(dd, b); + Cudd_RecursiveDeref(dd, isop); + + cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I); + cuddDeref(zdd_I); + return(zdd_I); +} /* end of cuddZddComplement */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of positive ZDD variable.] + + Description [Returns the index of positive ZDD variable.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddGetPosVarIndex( + DdManager * dd, + int index) +{ + int pv = (index >> 1) << 1; + return(pv); +} /* end of cuddZddGetPosVarIndex */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of negative ZDD variable.] + + Description [Returns the index of negative ZDD variable.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddGetNegVarIndex( + DdManager * dd, + int index) +{ + int nv = index | 0x1; + return(nv); +} /* end of cuddZddGetPosVarIndex */ + + +/**Function******************************************************************** + + Synopsis [Returns the level of positive ZDD variable.] + + Description [Returns the level of positive ZDD variable.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddGetPosVarLevel( + DdManager * dd, + int index) +{ + int pv = cuddZddGetPosVarIndex(dd, index); + return(dd->permZ[pv]); +} /* end of cuddZddGetPosVarLevel */ + + +/**Function******************************************************************** + + Synopsis [Returns the level of negative ZDD variable.] + + Description [Returns the level of negative ZDD variable.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddGetNegVarLevel( + DdManager * dd, + int index) +{ + int nv = cuddZddGetNegVarIndex(dd, index); + return(dd->permZ[nv]); +} /* end of cuddZddGetNegVarLevel */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddGroup.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddGroup.c new file mode 100644 index 000000000..11b31734d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddGroup.c @@ -0,0 +1,1340 @@ +/**CFile*********************************************************************** + + FileName [cuddZddGroup.c] + + PackageName [cudd] + + Synopsis [Functions for ZDD group sifting.] + + Description [External procedures included in this file: +
                          +
                        • Cudd_MakeZddTreeNode() +
                        + Internal procedures included in this file: +
                          +
                        • cuddZddTreeSifting() +
                        + Static procedures included in this module: +
                          +
                        • zddTreeSiftingAux() +
                        • zddCountInternalMtrNodes() +
                        • zddReorderChildren() +
                        • zddFindNodeHiLo() +
                        • zddUniqueCompareGroup() +
                        • zddGroupSifting() +
                        • zddGroupSiftingAux() +
                        • zddGroupSiftingUp() +
                        • zddGroupSiftingDown() +
                        • zddGroupMove() +
                        • zddGroupMoveBackward() +
                        • zddGroupSiftingBackward() +
                        • zddMergeGroups() +
                        ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddGroup.c,v 1.22 2012/02/05 01:07:19 fabio Exp $"; +#endif + +static int *entry; +extern int zddTotalNumberSwapping; +#ifdef DD_STATS +static int extsymmcalls; +static int extsymm; +static int secdiffcalls; +static int secdiff; +static int secdiffmisfire; +#endif +#ifdef DD_DEBUG +static int pr = 0; /* flag to enable printing while debugging */ + /* by depositing a 1 into it */ +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int zddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +#ifdef DD_STATS +static int zddCountInternalMtrNodes (DdManager *table, MtrNode *treenode); +#endif +static int zddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +static void zddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper); +static int zddUniqueCompareGroup (int *ptrX, int *ptrY); +static int zddGroupSifting (DdManager *table, int lower, int upper); +static int zddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static int zddGroupSiftingUp (DdManager *table, int y, int xLow, Move **moves); +static int zddGroupSiftingDown (DdManager *table, int x, int xHigh, Move **moves); +static int zddGroupMove (DdManager *table, int x, int y, Move **moves); +static int zddGroupMoveBackward (DdManager *table, int x, int y); +static int zddGroupSiftingBackward (DdManager *table, Move *moves, int size); +static void zddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Creates a new ZDD variable group.] + + Description [Creates a new ZDD variable group. The group starts at + variable and contains size variables. The parameter low is the index + of the first variable. If the variable already exists, its current + position in the order is known to the manager. If the variable does + not exist yet, the position is assumed to be the same as the index. + The group tree is created if it does not exist yet. + Returns a pointer to the group if successful; NULL otherwise.] + + SideEffects [The ZDD variable tree is changed.] + + SeeAlso [Cudd_MakeTreeNode] + +******************************************************************************/ +MtrNode * +Cudd_MakeZddTreeNode( + DdManager * dd /* manager */, + unsigned int low /* index of the first group variable */, + unsigned int size /* number of variables in the group */, + unsigned int type /* MTR_DEFAULT or MTR_FIXED */) +{ + MtrNode *group; + MtrNode *tree; + unsigned int level; + + /* If the variable does not exist yet, the position is assumed to be + ** the same as the index. Therefore, applications that rely on + ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new + ** variables have to create the variables before they group them. + */ + level = (low < (unsigned int) dd->sizeZ) ? dd->permZ[low] : low; + + if (level + size - 1> (int) MTR_MAXHIGH) + return(NULL); + + /* If the tree does not exist yet, create it. */ + tree = dd->treeZ; + if (tree == NULL) { + dd->treeZ = tree = Mtr_InitGroupTree(0, dd->sizeZ); + if (tree == NULL) + return(NULL); + tree->index = dd->invpermZ[0]; + } + + /* Extend the upper bound of the tree if necessary. This allows the + ** application to create groups even before the variables are created. + */ + tree->size = ddMax(tree->size, level + size); + + /* Create the group. */ + group = Mtr_MakeGroup(tree, level, size, type); + if (group == NULL) + return(NULL); + + /* Initialize the index field to the index of the variable currently + ** in position low. This field will be updated by the reordering + ** procedure to provide a handle to the group once it has been moved. + */ + group->index = (MtrHalfWord) low; + + return(group); + +} /* end of Cudd_MakeZddTreeNode */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Tree sifting algorithm for ZDDs.] + + Description [Tree sifting algorithm for ZDDs. Assumes that a tree + representing a group hierarchy is passed as a parameter. It then + reorders each group in postorder fashion by calling + zddTreeSiftingAux. Assumes that no dead nodes are present. Returns + 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +int +cuddZddTreeSifting( + DdManager * table /* DD table */, + Cudd_ReorderingType method /* reordering method for the groups of leaves */) +{ + int i; + int nvars; + int result; + int tempTree; + + /* If no tree is provided we create a temporary one in which all + ** variables are in a single group. After reordering this tree is + ** destroyed. + */ + tempTree = table->treeZ == NULL; + if (tempTree) { + table->treeZ = Mtr_InitGroupTree(0,table->sizeZ); + table->treeZ->index = table->invpermZ[0]; + } + nvars = table->sizeZ; + +#ifdef DD_DEBUG + if (pr > 0 && !tempTree) + (void) fprintf(table->out,"cuddZddTreeSifting:"); + Mtr_PrintGroups(table->treeZ,pr <= 0); +#endif +#if 0 + /* Debugging code. */ + if (table->tree && table->treeZ) { + (void) fprintf(table->out,"\n"); + Mtr_PrintGroups(table->tree, 0); + cuddPrintVarGroups(table,table->tree,0,0); + for (i = 0; i < table->size; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->invperm[i]); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < table->size; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->perm[i]); + } + (void) fprintf(table->out,"\n\n"); + Mtr_PrintGroups(table->treeZ,0); + cuddPrintVarGroups(table,table->treeZ,1,0); + for (i = 0; i < table->sizeZ; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->invpermZ[i]); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < table->sizeZ; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->permZ[i]); + } + (void) fprintf(table->out,"\n"); + } + /* End of debugging code. */ +#endif +#ifdef DD_STATS + extsymmcalls = 0; + extsymm = 0; + secdiffcalls = 0; + secdiff = 0; + secdiffmisfire = 0; + + (void) fprintf(table->out,"\n"); + if (!tempTree) + (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", + zddCountInternalMtrNodes(table,table->treeZ)); +#endif + + /* Initialize the group of each subtable to itself. Initially + ** there are no groups. Groups are created according to the tree + ** structure in postorder fashion. + */ + for (i = 0; i < nvars; i++) + table->subtableZ[i].next = i; + + /* Reorder. */ + result = zddTreeSiftingAux(table, table->treeZ, method); + +#ifdef DD_STATS /* print stats */ + if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && + (table->groupcheck == CUDD_GROUP_CHECK7 || + table->groupcheck == CUDD_GROUP_CHECK5)) { + (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); + (void) fprintf(table->out,"extsymm = %d",extsymm); + } + if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && + table->groupcheck == CUDD_GROUP_CHECK7) { + (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); + (void) fprintf(table->out,"secdiff = %d\n",secdiff); + (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); + } +#endif + + if (tempTree) + Cudd_FreeZddTree(table); + return(result); + +} /* end of cuddZddTreeSifting */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Visits the group tree and reorders each group.] + + Description [Recursively visits the group tree and reorders each + group in postorder fashion. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddTreeSiftingAux( + DdManager * table, + MtrNode * treenode, + Cudd_ReorderingType method) +{ + MtrNode *auxnode; + int res; + +#ifdef DD_DEBUG + Mtr_PrintGroups(treenode,1); +#endif + + auxnode = treenode; + while (auxnode != NULL) { + if (auxnode->child != NULL) { + if (!zddTreeSiftingAux(table, auxnode->child, method)) + return(0); + res = zddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT); + if (res == 0) + return(0); + } else if (auxnode->size > 1) { + if (!zddReorderChildren(table, auxnode, method)) + return(0); + } + auxnode = auxnode->younger; + } + + return(1); + +} /* end of zddTreeSiftingAux */ + + +#ifdef DD_STATS +/**Function******************************************************************** + + Synopsis [Counts the number of internal nodes of the group tree.] + + Description [Counts the number of internal nodes of the group tree. + Returns the count.] + + SideEffects [None] + +******************************************************************************/ +static int +zddCountInternalMtrNodes( + DdManager * table, + MtrNode * treenode) +{ + MtrNode *auxnode; + int count,nodeCount; + + + nodeCount = 0; + auxnode = treenode; + while (auxnode != NULL) { + if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { + nodeCount++; + count = zddCountInternalMtrNodes(table,auxnode->child); + nodeCount += count; + } + auxnode = auxnode->younger; + } + + return(nodeCount); + +} /* end of zddCountInternalMtrNodes */ +#endif + + +/**Function******************************************************************** + + Synopsis [Reorders the children of a group tree node according to + the options.] + + Description [Reorders the children of a group tree node according to + the options. After reordering puts all the variables in the group + and/or its descendents in a single group. This allows hierarchical + reordering. If the variables in the group do not exist yet, simply + does nothing. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddReorderChildren( + DdManager * table, + MtrNode * treenode, + Cudd_ReorderingType method) +{ + int lower; + int upper; + int result; + unsigned int initialSize; + + zddFindNodeHiLo(table,treenode,&lower,&upper); + /* If upper == -1 these variables do not exist yet. */ + if (upper == -1) + return(1); + + if (treenode->flags == MTR_FIXED) { + result = 1; + } else { +#ifdef DD_STATS + (void) fprintf(table->out," "); +#endif + switch (method) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + result = cuddZddSwapping(table,lower,upper,method); + break; + case CUDD_REORDER_SIFT: + result = cuddZddSifting(table,lower,upper); + break; + case CUDD_REORDER_SIFT_CONVERGE: + do { + initialSize = table->keysZ; + result = cuddZddSifting(table,lower,upper); + if (initialSize <= table->keysZ) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + case CUDD_REORDER_SYMM_SIFT: + result = cuddZddSymmSifting(table,lower,upper); + break; + case CUDD_REORDER_SYMM_SIFT_CONV: + result = cuddZddSymmSiftingConv(table,lower,upper); + break; + case CUDD_REORDER_GROUP_SIFT: + result = zddGroupSifting(table,lower,upper); + break; + case CUDD_REORDER_LINEAR: + result = cuddZddLinearSifting(table,lower,upper); + break; + case CUDD_REORDER_LINEAR_CONVERGE: + do { + initialSize = table->keysZ; + result = cuddZddLinearSifting(table,lower,upper); + if (initialSize <= table->keysZ) + break; +#ifdef DD_STATS + else + (void) fprintf(table->out,"\n"); +#endif + } while (result != 0); + break; + default: + return(0); + } + } + + /* Create a single group for all the variables that were sifted, + ** so that they will be treated as a single block by successive + ** invocations of zddGroupSifting. + */ + zddMergeGroups(table,treenode,lower,upper); + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddReorderChildren:"); +#endif + + return(result); + +} /* end of zddReorderChildren */ + + +/**Function******************************************************************** + + Synopsis [Finds the lower and upper bounds of the group represented + by treenode.] + + Description [Finds the lower and upper bounds of the group represented + by treenode. The high and low fields of treenode are indices. From + those we need to derive the current positions, and find maximum and + minimum.] + + SideEffects [The bounds are returned as side effects.] + + SeeAlso [] + +******************************************************************************/ +static void +zddFindNodeHiLo( + DdManager * table, + MtrNode * treenode, + int * lower, + int * upper) +{ + int low; + int high; + + /* Check whether no variables in this group already exist. + ** If so, return immediately. The calling procedure will know from + ** the values of upper that no reordering is needed. + */ + if ((int) treenode->low >= table->sizeZ) { + *lower = table->sizeZ; + *upper = -1; + return; + } + + *lower = low = (unsigned int) table->permZ[treenode->index]; + high = (int) (low + treenode->size - 1); + + if (high >= table->sizeZ) { + /* This is the case of a partially existing group. The aim is to + ** reorder as many variables as safely possible. If the tree + ** node is terminal, we just reorder the subset of the group + ** that is currently in existence. If the group has + ** subgroups, then we only reorder those subgroups that are + ** fully instantiated. This way we avoid breaking up a group. + */ + MtrNode *auxnode = treenode->child; + if (auxnode == NULL) { + *upper = (unsigned int) table->sizeZ - 1; + } else { + /* Search the subgroup that strands the table->sizeZ line. + ** If the first group starts at 0 and goes past table->sizeZ + ** upper will get -1, thus correctly signaling that no reordering + ** should take place. + */ + while (auxnode != NULL) { + int thisLower = table->permZ[auxnode->low]; + int thisUpper = thisLower + auxnode->size - 1; + if (thisUpper >= table->sizeZ && thisLower < table->sizeZ) + *upper = (unsigned int) thisLower - 1; + auxnode = auxnode->younger; + } + } + } else { + /* Normal case: All the variables of the group exist. */ + *upper = (unsigned int) high; + } + +#ifdef DD_DEBUG + /* Make sure that all variables in group are contiguous. */ + assert(treenode->size >= *upper - *lower + 1); +#endif + + return; + +} /* end of zddFindNodeHiLo */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the variables + according to the number of keys in the subtables. Returns the + difference in number of keys between the two variables being + compared.] + + SideEffects [None] + +******************************************************************************/ +static int +zddUniqueCompareGroup( + int * ptrX, + int * ptrY) +{ +#if 0 + if (entry[*ptrY] == entry[*ptrX]) { + return((*ptrX) - (*ptrY)); + } +#endif + return(entry[*ptrY] - entry[*ptrX]); + +} /* end of zddUniqueCompareGroup */ + + +/**Function******************************************************************** + + Synopsis [Sifts from treenode->low to treenode->high.] + + Description [Sifts from treenode->low to treenode->high. If + croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the + end of the initial sifting. If a group is created, it is then sifted + again. After sifting one variable, the group that contains it is + dissolved. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSifting( + DdManager * table, + int lower, + int upper) +{ + int *var; + int i,j,x,xInit; + int nvars; + int classes; + int result; + int *sifted; +#ifdef DD_STATS + unsigned previousSize; +#endif + int xindex; + + nvars = table->sizeZ; + + /* Order variables to sift. */ + entry = NULL; + sifted = NULL; + var = ALLOC(int,nvars); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; + } + entry = ALLOC(int,nvars); + if (entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; + } + sifted = ALLOC(int,nvars); + if (sifted == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; + } + + /* Here we consider only one representative for each group. */ + for (i = 0, classes = 0; i < nvars; i++) { + sifted[i] = 0; + x = table->permZ[i]; + if ((unsigned) x >= table->subtableZ[x].next) { + entry[i] = table->subtableZ[x].keys; + var[classes] = i; + classes++; + } + } + + qsort((void *)var,classes,sizeof(int),(DD_QSFP)zddUniqueCompareGroup); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + xindex = var[i]; + if (sifted[xindex] == 1) /* variable already sifted as part of group */ + continue; + x = table->permZ[xindex]; /* find current level of this variable */ + if (x < lower || x > upper) + continue; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif +#ifdef DD_DEBUG + /* x is bottom of group */ + assert((unsigned) x >= table->subtableZ[x].next); +#endif + result = zddGroupSiftingAux(table,x,lower,upper); + if (!result) goto zddGroupSiftingOutOfMem; + +#ifdef DD_STATS + if (table->keysZ < previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > previousSize) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + + /* Mark variables in the group just sifted. */ + x = table->permZ[xindex]; + if ((unsigned) x != table->subtableZ[x].next) { + xInit = x; + do { + j = table->invpermZ[x]; + sifted[j] = 1; + x = table->subtableZ[x].next; + } while (x != xInit); + } + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSifting:"); +#endif + } /* for */ + + FREE(sifted); + FREE(var); + FREE(entry); + + return(1); + +zddGroupSiftingOutOfMem: + if (entry != NULL) FREE(entry); + if (var != NULL) FREE(var); + if (sifted != NULL) FREE(sifted); + + return(0); + +} /* end of zddGroupSifting */ + + +/**Function******************************************************************** + + Synopsis [Sifts one variable up and down until it has taken all + positions. Checks for aggregation.] + + Description [Sifts one variable up and down until it has taken all + positions. Checks for aggregation. There may be at most two sweeps, + even if the group grows. Assumes that x is either an isolated + variable, or it is the bottom of a group. All groups may not have + been found. The variable being moved is returned to the best position + seen during sifting. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSiftingAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + Move *move; + Move *moves; /* list of moves */ + int initialSize; + int result; + + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingAux from %d to %d\n",xLow,xHigh); + assert((unsigned) x >= table->subtableZ[x].next); /* x is bottom of group */ +#endif + + initialSize = table->keysZ; + moves = NULL; + + if (x == xLow) { /* Sift down */ +#ifdef DD_DEBUG + /* x must be a singleton */ + assert((unsigned) x == table->subtableZ[x].next); +#endif + if (x == xHigh) return(1); /* just one variable */ + + if (!zddGroupSiftingDown(table,x,xHigh,&moves)) + goto zddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); +#ifdef DD_DEBUG + assert(table->keysZ <= (unsigned) initialSize); +#endif + if (!result) goto zddGroupSiftingAuxOutOfMem; + + } else if (cuddZddNextHigh(table,x) > xHigh) { /* Sift up */ +#ifdef DD_DEBUG + /* x is bottom of group */ + assert((unsigned) x >= table->subtableZ[x].next); +#endif + /* Find top of x's group */ + x = table->subtableZ[x].next; + + if (!zddGroupSiftingUp(table,x,xLow,&moves)) + goto zddGroupSiftingAuxOutOfMem; + /* at this point x == xLow, unless early term */ + + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); +#ifdef DD_DEBUG + assert(table->keysZ <= (unsigned) initialSize); +#endif + if (!result) goto zddGroupSiftingAuxOutOfMem; + + } else if (x - xLow > xHigh - x) { /* must go down first: shorter */ + if (!zddGroupSiftingDown(table,x,xHigh,&moves)) + goto zddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + /* Find top of group */ + if (moves) { + x = moves->y; + } + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; +#ifdef DD_DEBUG + /* x should be the top of a group */ + assert((unsigned) x <= table->subtableZ[x].next); +#endif + + if (!zddGroupSiftingUp(table,x,xLow,&moves)) + goto zddGroupSiftingAuxOutOfMem; + + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); +#ifdef DD_DEBUG + assert(table->keysZ <= (unsigned) initialSize); +#endif + if (!result) goto zddGroupSiftingAuxOutOfMem; + + } else { /* moving up first: shorter */ + /* Find top of x's group */ + x = table->subtableZ[x].next; + + if (!zddGroupSiftingUp(table,x,xLow,&moves)) + goto zddGroupSiftingAuxOutOfMem; + /* at this point x == xHigh, unless early term */ + + if (moves) { + x = moves->x; + } + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; +#ifdef DD_DEBUG + /* x is bottom of a group */ + assert((unsigned) x >= table->subtableZ[x].next); +#endif + + if (!zddGroupSiftingDown(table,x,xHigh,&moves)) + goto zddGroupSiftingAuxOutOfMem; + + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); +#ifdef DD_DEBUG + assert(table->keysZ <= (unsigned) initialSize); +#endif + if (!result) goto zddGroupSiftingAuxOutOfMem; + } + + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(1); + +zddGroupSiftingAuxOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + + return(0); + +} /* end of zddGroupSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much.] + + Description [Sifts up a variable until either it reaches position + xLow or the size of the DD heap increases too much. Assumes that y is + the top of a group (or a singleton). Checks y for aggregation to the + adjacent variables. Records all the moves that are appended to the + list of moves received as input and returned as a side effect. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSiftingUp( + DdManager * table, + int y, + int xLow, + Move ** moves) +{ + Move *move; + int x; + int size; + int gxtop; + int limitSize; + + limitSize = table->keysZ; + + x = cuddZddNextLow(table,y); + while (x >= xLow) { + gxtop = table->subtableZ[x].next; + if (table->subtableZ[x].next == (unsigned) x && + table->subtableZ[y].next == (unsigned) y) { + /* x and y are self groups */ + size = cuddZddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtableZ[x].next == (unsigned) x); + assert(table->subtableZ[y].next == (unsigned) y); +#endif + if (size == 0) goto zddGroupSiftingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto zddGroupSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_DEFAULT; + move->size = size; + move->next = *moves; + *moves = move; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingUp (2 single groups):\n"); +#endif + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } else { /* group move */ + size = zddGroupMove(table,x,y,moves); + if (size == 0) goto zddGroupSiftingUpOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } + y = gxtop; + x = cuddZddNextLow(table,y); + } + + return(1); + +zddGroupSiftingUpOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of zddGroupSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts down a variable until it reaches position xHigh.] + + Description [Sifts down a variable until it reaches position xHigh. + Assumes that x is the bottom of a group (or a singleton). Records + all the moves. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSiftingDown( + DdManager * table, + int x, + int xHigh, + Move ** moves) +{ + Move *move; + int y; + int size; + int limitSize; + int gybot; + + + /* Initialize R */ + limitSize = size = table->keysZ; + y = cuddZddNextHigh(table,x); + while (y <= xHigh) { + /* Find bottom of y group. */ + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + + if (table->subtableZ[x].next == (unsigned) x && + table->subtableZ[y].next == (unsigned) y) { + /* x and y are self groups */ + size = cuddZddSwapInPlace(table,x,y); +#ifdef DD_DEBUG + assert(table->subtableZ[x].next == (unsigned) x); + assert(table->subtableZ[y].next == (unsigned) y); +#endif + if (size == 0) goto zddGroupSiftingDownOutOfMem; + + /* Record move. */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto zddGroupSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_DEFAULT; + move->size = size; + move->next = *moves; + *moves = move; + +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingDown (2 single groups):\n"); +#endif + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + x = y; + y = cuddZddNextHigh(table,x); + } else { /* Group move */ + size = zddGroupMove(table,x,y,moves); + if (size == 0) goto zddGroupSiftingDownOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(1); + if (size < limitSize) limitSize = size; + } + x = gybot; + y = cuddZddNextHigh(table,x); + } + + return(1); + +zddGroupSiftingDownOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + + return(0); + +} /* end of zddGroupSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Swaps two groups and records the move.] + + Description [Swaps two groups and records the move. Returns the + number of keys in the DD table in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupMove( + DdManager * table, + int x, + int y, + Move ** moves) +{ + Move *move; + int size; + int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + int swapx,swapy; +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + int initialSize,bestSize; +#endif + +#ifdef DD_DEBUG + /* We assume that x < y */ + assert(x < y); +#endif + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtableZ[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtableZ[ybot].next) + ybot = table->subtableZ[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + initialSize = bestSize = table->keysZ; +#endif + /* Sift the variables of the second group up through the first group */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddZddSwapInPlace(table,x,y); + if (size == 0) goto zddGroupMoveOutOfMem; +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (size < bestSize) + bestSize = size; +#endif + swapx = x; swapy = y; + y = x; + x = cuddZddNextLow(table,y); + } + y = ytop + i; + x = cuddZddNextLow(table,y); + } +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if ((bestSize < initialSize) && (bestSize < size)) + (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); +#endif + + /* fix groups */ + y = xtop; /* ytop is now where xtop used to be */ + for (i = 0; i < ysize - 1; i++) { + table->subtableZ[y].next = cuddZddNextHigh(table,y); + y = cuddZddNextHigh(table,y); + } + table->subtableZ[y].next = xtop; /* y is bottom of its group, join */ + /* it to top of its group */ + x = cuddZddNextHigh(table,y); + newxtop = x; + for (i = 0; i < xsize - 1; i++) { + table->subtableZ[x].next = cuddZddNextHigh(table,x); + x = cuddZddNextHigh(table,x); + } + table->subtableZ[x].next = newxtop; /* x is bottom of its group, join */ + /* it to top of its group */ +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupMove:\n"); +#endif + + /* Store group move */ + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto zddGroupMoveOutOfMem; + move->x = swapx; + move->y = swapy; + move->flags = MTR_DEFAULT; + move->size = table->keysZ; + move->next = *moves; + *moves = move; + + return(table->keysZ); + +zddGroupMoveOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of zddGroupMove */ + + +/**Function******************************************************************** + + Synopsis [Undoes the swap two groups.] + + Description [Undoes the swap two groups. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupMoveBackward( + DdManager * table, + int x, + int y) +{ + int size; + int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + + +#ifdef DD_DEBUG + /* We assume that x < y */ + assert(x < y); +#endif + + /* Find top, bottom, and size for the two groups. */ + xbot = x; + xtop = table->subtableZ[x].next; + xsize = xbot - xtop + 1; + ybot = y; + while ((unsigned) ybot < table->subtableZ[ybot].next) + ybot = table->subtableZ[ybot].next; + ytop = y; + ysize = ybot - ytop + 1; + + /* Sift the variables of the second group up through the first group */ + for (i = 1; i <= ysize; i++) { + for (j = 1; j <= xsize; j++) { + size = cuddZddSwapInPlace(table,x,y); + if (size == 0) + return(0); + y = x; + x = cuddZddNextLow(table,y); + } + y = ytop + i; + x = cuddZddNextLow(table,y); + } + + /* fix groups */ + y = xtop; + for (i = 0; i < ysize - 1; i++) { + table->subtableZ[y].next = cuddZddNextHigh(table,y); + y = cuddZddNextHigh(table,y); + } + table->subtableZ[y].next = xtop; /* y is bottom of its group, join */ + /* to its top */ + x = cuddZddNextHigh(table,y); + newxtop = x; + for (i = 0; i < xsize - 1; i++) { + table->subtableZ[x].next = cuddZddNextHigh(table,x); + x = cuddZddNextHigh(table,x); + } + table->subtableZ[x].next = newxtop; /* x is bottom of its group, join */ + /* to its top */ +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupMoveBackward:\n"); +#endif + + return(1); + +} /* end of zddGroupMoveBackward */ + + +/**Function******************************************************************** + + Synopsis [Determines the best position for a variables and returns + it there.] + + Description [Determines the best position for a variables and returns + it there. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddGroupSiftingBackward( + DdManager * table, + Move * moves, + int size) +{ + Move *move; + int res; + + + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + if ((table->subtableZ[move->x].next == move->x) && + (table->subtableZ[move->y].next == move->y)) { + res = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); +#ifdef DD_DEBUG + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingBackward:\n"); + assert(table->subtableZ[move->x].next == move->x); + assert(table->subtableZ[move->y].next == move->y); +#endif + } else { /* Group move necessary */ + res = zddGroupMoveBackward(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + } + + return(1); + +} /* end of zddGroupSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Merges groups in the DD table.] + + Description [Creates a single group from low to high and adjusts the + idex field of the tree node.] + + SideEffects [None] + +******************************************************************************/ +static void +zddMergeGroups( + DdManager * table, + MtrNode * treenode, + int low, + int high) +{ + int i; + MtrNode *auxnode; + int saveindex; + int newindex; + + /* Merge all variables from low to high in one group, unless + ** this is the topmost group. In such a case we do not merge lest + ** we lose the symmetry information. */ + if (treenode != table->treeZ) { + for (i = low; i < high; i++) + table->subtableZ[i].next = i+1; + table->subtableZ[high].next = low; + } + + /* Adjust the index fields of the tree nodes. If a node is the + ** first child of its parent, then the parent may also need adjustment. */ + saveindex = treenode->index; + newindex = table->invpermZ[low]; + auxnode = treenode; + do { + auxnode->index = newindex; + if (auxnode->parent == NULL || + (int) auxnode->parent->index != saveindex) + break; + auxnode = auxnode->parent; + } while (1); + return; + +} /* end of zddMergeGroups */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddIsop.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddIsop.c new file mode 100644 index 000000000..c1eaea3d6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddIsop.c @@ -0,0 +1,912 @@ +/**CFile*********************************************************************** + + FileName [cuddZddIsop.c] + + PackageName [cudd] + + Synopsis [Functions to find irredundant SOP covers as ZDDs from BDDs.] + + Description [External procedures included in this module: +
                          +
                        • Cudd_bddIsop() +
                        • Cudd_zddIsop() +
                        • Cudd_MakeBddFromZddCover() +
                        + Internal procedures included in this module: +
                          +
                        • cuddBddIsop() +
                        • cuddZddIsop() +
                        • cuddMakeBddFromZddCover() +
                        + Static procedures included in this module: +
                          +
                        + ] + + SeeAlso [] + + Author [In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddIsop.c,v 1.22 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Computes an ISOP in ZDD form from BDDs.] + + Description [Computes an irredundant sum of products (ISOP) in ZDD + form from BDDs. The two BDDs L and U represent the lower bound and + the upper bound, respectively, of the function. The ISOP uses two + ZDD variables for each BDD variable: One for the positive literal, + and one for the negative literal. These two variables should be + adjacent in the ZDD order. The two ZDD variables corresponding to + BDD variable i should have indices 2i and + 2i+1. The result of this procedure depends on the + variable order. If successful, Cudd_zddIsop returns the BDD for + the function chosen from the interval. The ZDD representing the + irredundant cover is returned as a side effect in zdd_I. In case of + failure, NULL is returned.] + + SideEffects [zdd_I holds the pointer to the ZDD for the ISOP on + successful return.] + + SeeAlso [Cudd_bddIsop Cudd_zddVarsFromBddVars] + +******************************************************************************/ +DdNode * +Cudd_zddIsop( + DdManager * dd, + DdNode * L, + DdNode * U, + DdNode ** zdd_I) +{ + DdNode *res; + int autoDynZ; + + autoDynZ = dd->autoDynZ; + dd->autoDynZ = 0; + + do { + dd->reordered = 0; + res = cuddZddIsop(dd, L, U, zdd_I); + } while (dd->reordered == 1); + dd->autoDynZ = autoDynZ; + return(res); + +} /* end of Cudd_zddIsop */ + + +/**Function******************************************************************** + + Synopsis [Computes a BDD in the interval between L and U with a + simple sum-of-product cover.] + + Description [Computes a BDD in the interval between L and U with a + simple sum-of-product cover. This procedure is similar to + Cudd_zddIsop, but it does not return the ZDD for the cover. Returns + a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddIsop] + +******************************************************************************/ +DdNode * +Cudd_bddIsop( + DdManager * dd, + DdNode * L, + DdNode * U) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddIsop(dd, L, U); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddIsop */ + + +/**Function******************************************************************** + + Synopsis [Converts a ZDD cover to a BDD.] + + Description [Converts a ZDD cover to a BDD for the function represented + by the cover. If successful, it returns a BDD node, otherwise it returns + NULL.] + + SideEffects [] + + SeeAlso [Cudd_zddIsop] + +******************************************************************************/ +DdNode * +Cudd_MakeBddFromZddCover( + DdManager * dd, + DdNode * node) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddMakeBddFromZddCover(dd, node); + } while (dd->reordered == 1); + return(res); +} /* end of Cudd_MakeBddFromZddCover */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddIsop.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_zddIsop] + +******************************************************************************/ +DdNode * +cuddZddIsop( + DdManager * dd, + DdNode * L, + DdNode * U, + DdNode ** zdd_I) +{ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + DdNode *zdd_one = DD_ONE(dd); + DdNode *zdd_zero = DD_ZERO(dd); + int v, top_l, top_u; + DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; + DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; + DdNode *Isub0, *Isub1, *Id; + DdNode *zdd_Isub0, *zdd_Isub1, *zdd_Id; + DdNode *x; + DdNode *term0, *term1, *sum; + DdNode *Lv, *Uv, *Lnv, *Unv; + DdNode *r, *y, *z; + int index; + DD_CTFP cacheOp; + + statLine(dd); + if (L == zero) { + *zdd_I = zdd_zero; + return(zero); + } + if (U == one) { + *zdd_I = zdd_one; + return(one); + } + + if (U == zero || L == one) { + printf("*** ERROR : illegal condition for ISOP (U < L).\n"); + exit(1); + } + + /* Check the cache. We store two results for each recursive call. + ** One is the BDD, and the other is the ZDD. Both are needed. + ** Hence we need a double hit in the cache to terminate the + ** recursion. Clearly, collisions may evict only one of the two + ** results. */ + cacheOp = (DD_CTFP) cuddZddIsop; + r = cuddCacheLookup2(dd, cuddBddIsop, L, U); + if (r) { + *zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U); + if (*zdd_I) + return(r); + else { + /* The BDD result may have been dead. In that case + ** cuddCacheLookup2 would have called cuddReclaim, + ** whose effects we now have to undo. */ + cuddRef(r); + Cudd_RecursiveDeref(dd, r); + } + } + + top_l = dd->perm[Cudd_Regular(L)->index]; + top_u = dd->perm[Cudd_Regular(U)->index]; + v = ddMin(top_l, top_u); + + /* Compute cofactors. */ + if (top_l == v) { + index = Cudd_Regular(L)->index; + Lv = Cudd_T(L); + Lnv = Cudd_E(L); + if (Cudd_IsComplement(L)) { + Lv = Cudd_Not(Lv); + Lnv = Cudd_Not(Lnv); + } + } + else { + index = Cudd_Regular(U)->index; + Lv = Lnv = L; + } + + if (top_u == v) { + Uv = Cudd_T(U); + Unv = Cudd_E(U); + if (Cudd_IsComplement(U)) { + Uv = Cudd_Not(Uv); + Unv = Cudd_Not(Unv); + } + } + else { + Uv = Unv = U; + } + + Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv)); + if (Lsub0 == NULL) + return(NULL); + Cudd_Ref(Lsub0); + Usub0 = Unv; + Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv)); + if (Lsub1 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + return(NULL); + } + Cudd_Ref(Lsub1); + Usub1 = Uv; + + Isub0 = cuddZddIsop(dd, Lsub0, Usub0, &zdd_Isub0); + if (Isub0 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + return(NULL); + } + /* + if ((!cuddIsConstant(Cudd_Regular(Isub0))) && + (Cudd_Regular(Isub0)->index != zdd_Isub0->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Isub0->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); + } + */ + Cudd_Ref(Isub0); + Cudd_Ref(zdd_Isub0); + Isub1 = cuddZddIsop(dd, Lsub1, Usub1, &zdd_Isub1); + if (Isub1 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + return(NULL); + } + /* + if ((!cuddIsConstant(Cudd_Regular(Isub1))) && + (Cudd_Regular(Isub1)->index != zdd_Isub1->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Isub1->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); + } + */ + Cudd_Ref(Isub1); + Cudd_Ref(zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + + Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0)); + if (Lsuper0 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + return(NULL); + } + Cudd_Ref(Lsuper0); + Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1)); + if (Lsuper1 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + return(NULL); + } + Cudd_Ref(Lsuper1); + Usuper0 = Unv; + Usuper1 = Uv; + + /* Ld = Lsuper0 + Lsuper1 */ + Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1)); + if (Ld == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + return(NULL); + } + Ld = Cudd_Not(Ld); + Cudd_Ref(Ld); + /* Ud = Usuper0 * Usuper1 */ + Ud = cuddBddAndRecur(dd, Usuper0, Usuper1); + if (Ud == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + Cudd_RecursiveDeref(dd, Ld); + return(NULL); + } + Cudd_Ref(Ud); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + + Id = cuddZddIsop(dd, Ld, Ud, &zdd_Id); + if (Id == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + return(NULL); + } + /* + if ((!cuddIsConstant(Cudd_Regular(Id))) && + (Cudd_Regular(Id)->index != zdd_Id->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Id->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); + } + */ + Cudd_Ref(Id); + Cudd_Ref(zdd_Id); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + + x = cuddUniqueInter(dd, index, one, zero); + if (x == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + return(NULL); + } + Cudd_Ref(x); + /* term0 = x * Isub0 */ + term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0); + if (term0 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + Cudd_Ref(term0); + Cudd_RecursiveDeref(dd, Isub0); + /* term1 = x * Isub1 */ + term1 = cuddBddAndRecur(dd, x, Isub1); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, term0); + return(NULL); + } + Cudd_Ref(term1); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, Isub1); + /* sum = term0 + term1 */ + sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1)); + if (sum == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + return(NULL); + } + sum = Cudd_Not(sum); + Cudd_Ref(sum); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + /* r = sum + Id */ + r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id)); + r = Cudd_NotCond(r, r != NULL); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, sum); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDeref(dd, sum); + Cudd_RecursiveDeref(dd, Id); + + if (zdd_Isub0 != zdd_zero) { + z = cuddZddGetNodeIVO(dd, index * 2 + 1, zdd_Isub0, zdd_Id); + if (z == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, r); + return(NULL); + } + } + else { + z = zdd_Id; + } + Cudd_Ref(z); + if (zdd_Isub1 != zdd_zero) { + y = cuddZddGetNodeIVO(dd, index * 2, zdd_Isub1, z); + if (y == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, r); + Cudd_RecursiveDerefZdd(dd, z); + return(NULL); + } + } + else + y = z; + Cudd_Ref(y); + + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDerefZdd(dd, z); + + cuddCacheInsert2(dd, cuddBddIsop, L, U, r); + cuddCacheInsert2(dd, cacheOp, L, U, y); + + Cudd_Deref(r); + Cudd_Deref(y); + *zdd_I = y; + /* + if (Cudd_Regular(r)->index != y->index / 2) { + printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n"); + } + */ + return(r); + +} /* end of cuddZddIsop */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddIsop.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_bddIsop] + +******************************************************************************/ +DdNode * +cuddBddIsop( + DdManager * dd, + DdNode * L, + DdNode * U) +{ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + int v, top_l, top_u; + DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; + DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; + DdNode *Isub0, *Isub1, *Id; + DdNode *x; + DdNode *term0, *term1, *sum; + DdNode *Lv, *Uv, *Lnv, *Unv; + DdNode *r; + int index; + + statLine(dd); + if (L == zero) + return(zero); + if (U == one) + return(one); + + /* Check cache */ + r = cuddCacheLookup2(dd, cuddBddIsop, L, U); + if (r) + return(r); + + top_l = dd->perm[Cudd_Regular(L)->index]; + top_u = dd->perm[Cudd_Regular(U)->index]; + v = ddMin(top_l, top_u); + + /* Compute cofactors */ + if (top_l == v) { + index = Cudd_Regular(L)->index; + Lv = Cudd_T(L); + Lnv = Cudd_E(L); + if (Cudd_IsComplement(L)) { + Lv = Cudd_Not(Lv); + Lnv = Cudd_Not(Lnv); + } + } + else { + index = Cudd_Regular(U)->index; + Lv = Lnv = L; + } + + if (top_u == v) { + Uv = Cudd_T(U); + Unv = Cudd_E(U); + if (Cudd_IsComplement(U)) { + Uv = Cudd_Not(Uv); + Unv = Cudd_Not(Unv); + } + } + else { + Uv = Unv = U; + } + + Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv)); + if (Lsub0 == NULL) + return(NULL); + Cudd_Ref(Lsub0); + Usub0 = Unv; + Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv)); + if (Lsub1 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + return(NULL); + } + Cudd_Ref(Lsub1); + Usub1 = Uv; + + Isub0 = cuddBddIsop(dd, Lsub0, Usub0); + if (Isub0 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + return(NULL); + } + Cudd_Ref(Isub0); + Isub1 = cuddBddIsop(dd, Lsub1, Usub1); + if (Isub1 == NULL) { + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + Cudd_RecursiveDeref(dd, Isub0); + return(NULL); + } + Cudd_Ref(Isub1); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + + Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0)); + if (Lsuper0 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + return(NULL); + } + Cudd_Ref(Lsuper0); + Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1)); + if (Lsuper1 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + return(NULL); + } + Cudd_Ref(Lsuper1); + Usuper0 = Unv; + Usuper1 = Uv; + + /* Ld = Lsuper0 + Lsuper1 */ + Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1)); + Ld = Cudd_NotCond(Ld, Ld != NULL); + if (Ld == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + return(NULL); + } + Cudd_Ref(Ld); + Ud = cuddBddAndRecur(dd, Usuper0, Usuper1); + if (Ud == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + Cudd_RecursiveDeref(dd, Ld); + return(NULL); + } + Cudd_Ref(Ud); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + + Id = cuddBddIsop(dd, Ld, Ud); + if (Id == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + return(NULL); + } + Cudd_Ref(Id); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + + x = cuddUniqueInter(dd, index, one, zero); + if (x == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + return(NULL); + } + Cudd_Ref(x); + term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0); + if (term0 == NULL) { + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + Cudd_Ref(term0); + Cudd_RecursiveDeref(dd, Isub0); + term1 = cuddBddAndRecur(dd, x, Isub1); + if (term1 == NULL) { + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, term0); + return(NULL); + } + Cudd_Ref(term1); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, Isub1); + /* sum = term0 + term1 */ + sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1)); + sum = Cudd_NotCond(sum, sum != NULL); + if (sum == NULL) { + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + return(NULL); + } + Cudd_Ref(sum); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + /* r = sum + Id */ + r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id)); + r = Cudd_NotCond(r, r != NULL); + if (r == NULL) { + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, sum); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDeref(dd, sum); + Cudd_RecursiveDeref(dd, Id); + + cuddCacheInsert2(dd, cuddBddIsop, L, U, r); + + Cudd_Deref(r); + return(r); + +} /* end of cuddBddIsop */ + + +/**Function******************************************************************** + + Synopsis [Converts a ZDD cover to a BDD.] + + Description [Converts a ZDD cover to a BDD. If successful, it returns + a BDD node, otherwise it returns NULL. It is a recursive algorithm + that works as follows. First it computes 3 cofactors of a ZDD cover: + f1, f0 and fd. Second, it compute BDDs (b1, b0 and bd) of f1, f0 and fd. + Third, it computes T=b1+bd and E=b0+bd. Fourth, it computes ITE(v,T,E) where + v is the variable which has the index of the top node of the ZDD cover. + In this case, since the index of v can be larger than either the one of T + or the one of E, cuddUniqueInterIVO is called, where IVO stands for + independent from variable ordering.] + + SideEffects [] + + SeeAlso [Cudd_MakeBddFromZddCover] + +******************************************************************************/ +DdNode * +cuddMakeBddFromZddCover( + DdManager * dd, + DdNode * node) +{ + DdNode *neW; + int v; + DdNode *f1, *f0, *fd; + DdNode *b1, *b0, *bd; + DdNode *T, *E; + + statLine(dd); + if (node == dd->one) + return(dd->one); + if (node == dd->zero) + return(Cudd_Not(dd->one)); + + /* Check cache */ + neW = cuddCacheLookup1(dd, cuddMakeBddFromZddCover, node); + if (neW) + return(neW); + + v = Cudd_Regular(node)->index; /* either yi or zi */ + if (cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd)) return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + + b1 = cuddMakeBddFromZddCover(dd, f1); + if (!b1) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(b1); + b0 = cuddMakeBddFromZddCover(dd, f0); + if (!b0) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDeref(dd, b1); + return(NULL); + } + Cudd_Ref(b0); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + if (fd != dd->zero) { + bd = cuddMakeBddFromZddCover(dd, fd); + if (!bd) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDeref(dd, b1); + Cudd_RecursiveDeref(dd, b0); + return(NULL); + } + Cudd_Ref(bd); + Cudd_RecursiveDerefZdd(dd, fd); + + T = cuddBddAndRecur(dd, Cudd_Not(b1), Cudd_Not(bd)); + if (!T) { + Cudd_RecursiveDeref(dd, b1); + Cudd_RecursiveDeref(dd, b0); + Cudd_RecursiveDeref(dd, bd); + return(NULL); + } + T = Cudd_NotCond(T, T != NULL); + Cudd_Ref(T); + Cudd_RecursiveDeref(dd, b1); + E = cuddBddAndRecur(dd, Cudd_Not(b0), Cudd_Not(bd)); + if (!E) { + Cudd_RecursiveDeref(dd, b0); + Cudd_RecursiveDeref(dd, bd); + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + E = Cudd_NotCond(E, E != NULL); + Cudd_Ref(E); + Cudd_RecursiveDeref(dd, b0); + Cudd_RecursiveDeref(dd, bd); + } + else { + Cudd_RecursiveDerefZdd(dd, fd); + T = b1; + E = b0; + } + + if (Cudd_IsComplement(T)) { + neW = cuddUniqueInterIVO(dd, v / 2, Cudd_Not(T), Cudd_Not(E)); + if (!neW) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + neW = Cudd_Not(neW); + } + else { + neW = cuddUniqueInterIVO(dd, v / 2, T, E); + if (!neW) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + Cudd_Ref(neW); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + + cuddCacheInsert1(dd, cuddMakeBddFromZddCover, node, neW); + Cudd_Deref(neW); + return(neW); + +} /* end of cuddMakeBddFromZddCover */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddLin.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddLin.c new file mode 100644 index 000000000..3fc989d5b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddLin.c @@ -0,0 +1,971 @@ +/**CFile*********************************************************************** + + FileName [cuddZddLin.c] + + PackageName [cudd] + + Synopsis [Procedures for dynamic variable ordering of ZDDs.] + + Description [Internal procedures included in this module: +
                          +
                        • cuddZddLinearSifting() +
                        + Static procedures included in this module: +
                          +
                        • cuddZddLinearInPlace() +
                        • cuddZddLinerAux() +
                        • cuddZddLinearUp() +
                        • cuddZddLinearDown() +
                        • cuddZddLinearBackward() +
                        • cuddZddUndoMoves() +
                        + ] + + SeeAlso [cuddLinear.c cuddZddReord.c] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define CUDD_SWAP_MOVE 0 +#define CUDD_LINEAR_TRANSFORM_MOVE 1 +#define CUDD_INVERSE_TRANSFORM_MOVE 2 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddLin.c,v 1.16 2012/02/05 01:07:19 fabio Exp $"; +#endif + +extern int *zdd_entry; +extern int zddTotalNumberSwapping; +static int zddTotalNumberLinearTr; +static DdNode *empty; + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddZddLinearInPlace (DdManager * table, int x, int y); +static int cuddZddLinearAux (DdManager *table, int x, int xLow, int xHigh); +static Move * cuddZddLinearUp (DdManager *table, int y, int xLow, Move *prevMoves); +static Move * cuddZddLinearDown (DdManager *table, int x, int xHigh, Move *prevMoves); +static int cuddZddLinearBackward (DdManager *table, int size, Move *moves); +static Move* cuddZddUndoMoves (DdManager *table, Move *moves); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + + + +/**Function******************************************************************** + + Synopsis [Implementation of the linear sifting algorithm for ZDDs.] + + Description [Implementation of the linear sifting algorithm for ZDDs. + Assumes that no dead nodes are present. +
                          +
                        1. Order all the variables according to the number of entries + in each unique table. +
                        2. Sift the variable up and down and applies the XOR transformation, + remembering each time the total size of the DD heap. +
                        3. Select the best permutation. +
                        4. Repeat 3 and 4 for all variables. +
                        + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddLinearSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; +#ifdef DD_STATS + int previousSize; +#endif + + size = table->sizeZ; + empty = table->zero; + + /* Find order in which to sift variables. */ + var = NULL; + zdd_entry = ALLOC(int, size); + if (zdd_entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; + } + var = ALLOC(int, size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; + } + + qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar, size); i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = cuddZddLinearAux(table, x, lower, upper); + if (!result) + goto cuddZddSiftingOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + FREE(var); + FREE(zdd_entry); + + return(1); + +cuddZddSiftingOutOfMem: + + if (zdd_entry != NULL) FREE(zdd_entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddZddLinearSifting */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Linearly combines two adjacent variables.] + + Description [Linearly combines two adjacent variables. It assumes + that no dead nodes are present on entry to this procedure. The + procedure then guarantees that no dead nodes will be present when it + terminates. cuddZddLinearInPlace assumes that x < y. Returns the + number of keys in the table if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddZddSwapInPlace cuddLinearInPlace] + +******************************************************************************/ +static int +cuddZddLinearInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int i; + int posn; + DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; + DdNode *newf1, *newf0, *g, *next, *previous; + DdNode *special; + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddZddNextHigh(table,x) == y); + assert(table->subtableZ[x].keys != 0); + assert(table->subtableZ[y].keys != 0); + assert(table->subtableZ[x].dead == 0); + assert(table->subtableZ[y].dead == 0); +#endif + + zddTotalNumberLinearTr++; + + /* Get parameters of x subtable. */ + xindex = table->invpermZ[x]; + xlist = table->subtableZ[x].nodelist; + oldxkeys = table->subtableZ[x].keys; + xslots = table->subtableZ[x].slots; + xshift = table->subtableZ[x].shift; + newxkeys = 0; + + /* Get parameters of y subtable. */ + yindex = table->invpermZ[y]; + ylist = table->subtableZ[y].nodelist; + oldykeys = table->subtableZ[y].keys; + yslots = table->subtableZ[y].slots; + yshift = table->subtableZ[y].shift; + newykeys = oldykeys; + + /* The nodes in the x layer are put in two chains. The chain + ** pointed by g holds the normal nodes. When re-expressed they stay + ** in the x list. The chain pointed by special holds the elements + ** that will move to the y list. + */ + g = special = NULL; + for (i = 0; i < xslots; i++) { + f = xlist[i]; + if (f == NULL) continue; + xlist[i] = NULL; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); + /* if (f1->index == yindex) */ cuddSatDec(f1->ref); + f0 = cuddE(f); + /* if (f0->index == yindex) */ cuddSatDec(f0->ref); + if ((int) f1->index == yindex && cuddE(f1) == empty && + (int) f0->index != yindex) { + f->next = special; + special = f; + } else { + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ + } /* for each slot of the x subtable */ + + /* Mark y nodes with pointers from above x. We mark them by + ** changing their index to x. + */ + for (i = 0; i < yslots; i++) { + f = ylist[i]; + while (f != NULL) { + if (f->ref != 0) { + f->index = xindex; + } + f = f->next; + } /* while there are elements in the collision chain */ + } /* for each slot of the y subtable */ + + /* Move special nodes to the y list. */ + f = special; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); + f11 = cuddT(f1); + cuddT(f) = f11; + cuddSatInc(f11->ref); + f0 = cuddE(f); + cuddSatInc(f0->ref); + f->index = yindex; + /* Insert at the beginning of the list so that it will be + ** found first if there is a duplicate. The duplicate will + ** eventually be moved or garbage collected. No node + ** re-expression will add a pointer to it. + */ + posn = ddHash(f11, f0, yshift); + f->next = ylist[posn]; + ylist[posn] = f; + newykeys++; + f = next; + } + + /* Take care of the remaining x nodes that must be re-expressed. + ** They form a linked list pointed by g. + */ + f = g; + while (f != NULL) { +#ifdef DD_COUNT + table->swapSteps++; +#endif + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + if ((int) f1->index == yindex || (int) f1->index == xindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = empty; f10 = f1; + } + f0 = cuddE(f); + if ((int) f0->index == yindex || (int) f0->index == xindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = empty; f00 = f0; + } + /* Create the new T child. */ + if (f01 == empty) { + newf1 = f10; + cuddSatInc(newf1->ref); + } else { + /* Check ylist for triple (yindex, f01, f10). */ + posn = ddHash(f01, f10, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + newf1 = ylist[posn]; + /* Search the collision chain skipping the marked nodes. */ + while (newf1 != NULL) { + if (cuddT(newf1) == f01 && cuddE(newf1) == f10 && + (int) newf1->index == yindex) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f01; + cuddE(newf1) = f10; + /* Insert newf1 in the collision list ylist[pos]; + ** increase the ref counts of f01 and f10 + */ + newykeys++; + newf1->next = ylist[posn]; + ylist[posn] = newf1; + cuddSatInc(f01->ref); + cuddSatInc(f10->ref); + } + } + cuddT(f) = newf1; + + /* Do the same for f0. */ + /* Create the new E child. */ + if (f11 == empty) { + newf0 = f00; + cuddSatInc(newf0->ref); + } else { + /* Check ylist for triple (yindex, f11, f00). */ + posn = ddHash(f11, f00, yshift); + /* For each element newf0 in collision list ylist[posn]. */ + newf0 = ylist[posn]; + while (newf0 != NULL) { + if (cuddT(newf0) == f11 && cuddE(newf0) == f00 && + (int) newf0->index == yindex) { + cuddSatInc(newf0->ref); + break; /* match */ + } + newf0 = newf0->next; + } /* while newf0 */ + if (newf0 == NULL) { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto zddSwapOutOfMem; + newf0->index = yindex; newf0->ref = 1; + cuddT(newf0) = f11; cuddE(newf0) = f00; + /* Insert newf0 in the collision list ylist[posn]; + ** increase the ref counts of f11 and f00. + */ + newykeys++; + newf0->next = ylist[posn]; + ylist[posn] = newf0; + cuddSatInc(f11->ref); + cuddSatInc(f00->ref); + } + } + cuddE(f) = newf0; + + /* Re-insert the modified f in xlist. + ** The modified f does not already exists in xlist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, xshift); + newxkeys++; + f->next = xlist[posn]; + xlist[posn] = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer and move the marked nodes to the x list. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previous = NULL; + f = ylist[i]; + while (f != NULL) { + next = f->next; + if (f->ref == 0) { + cuddSatDec(cuddT(f)->ref); + cuddSatDec(cuddE(f)->ref); + cuddDeallocNode(table, f); + newykeys--; + if (previous == NULL) + ylist[i] = next; + else + previous->next = next; + } else if ((int) f->index == xindex) { /* move marked node */ + if (previous == NULL) + ylist[i] = next; + else + previous->next = next; + f1 = cuddT(f); + cuddSatDec(f1->ref); + /* Check ylist for triple (yindex, f1, empty). */ + posn = ddHash(f1, empty, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + newf1 = ylist[posn]; + while (newf1 != NULL) { + if (cuddT(newf1) == f1 && cuddE(newf1) == empty && + (int) newf1->index == yindex) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f1; cuddE(newf1) = empty; + /* Insert newf1 in the collision list ylist[posn]; + ** increase the ref counts of f1 and empty. + */ + newykeys++; + newf1->next = ylist[posn]; + ylist[posn] = newf1; + if (posn == i && previous == NULL) + previous = newf1; + cuddSatInc(f1->ref); + cuddSatInc(empty->ref); + } + cuddT(f) = newf1; + f0 = cuddE(f); + /* Insert f in x list. */ + posn = ddHash(newf1, f0, xshift); + newxkeys++; + newykeys--; + f->next = xlist[posn]; + xlist[posn] = f; + } else { + previous = f; + } + f = next; + } /* while f */ + } /* for i */ + + /* Set the appropriate fields in table. */ + table->subtableZ[x].keys = newxkeys; + table->subtableZ[y].keys = newykeys; + + table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys; + + /* Update univ section; univ[x] remains the same. */ + table->univ[y] = cuddT(table->univ[x]); + +#if 0 + (void) fprintf(table->out,"x = %d y = %d\n", x, y); + (void) Cudd_DebugCheck(table); + (void) Cudd_CheckKeys(table); +#endif + + return (table->keysZ); + +zddSwapOutOfMem: + (void) fprintf(table->err, "Error: cuddZddSwapInPlace out of memory\n"); + + return (0); + +} /* end of cuddZddLinearInPlace */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddLinearAux( + DdManager * table, + int x, + int xLow, + int xHigh) +{ + Move *move; + Move *moveUp; /* list of up move */ + Move *moveDown; /* list of down move */ + + int initial_size; + int result; + + initial_size = table->keysZ; + +#ifdef DD_DEBUG + assert(table->subtableZ[x].keys > 0); +#endif + + moveDown = NULL; + moveUp = NULL; + + if (x == xLow) { + moveDown = cuddZddLinearDown(table, x, xHigh, NULL); + /* At this point x --> xHigh. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveDown); + if (!result) + goto cuddZddLinearAuxOutOfMem; + + } else if (x == xHigh) { + moveUp = cuddZddLinearUp(table, x, xLow, NULL); + /* At this point x --> xLow. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveUp); + if (!result) + goto cuddZddLinearAuxOutOfMem; + + } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ + moveDown = cuddZddLinearDown(table, x, xHigh, NULL); + /* At this point x --> xHigh. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + moveUp = cuddZddUndoMoves(table,moveDown); +#ifdef DD_DEBUG + assert(moveUp == NULL || moveUp->x == x); +#endif + moveUp = cuddZddLinearUp(table, x, xLow, moveUp); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveUp); + if (!result) + goto cuddZddLinearAuxOutOfMem; + + } else { + moveUp = cuddZddLinearUp(table, x, xLow, NULL); + /* At this point x --> xHigh. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Then move up. */ + moveDown = cuddZddUndoMoves(table,moveUp); +#ifdef DD_DEBUG + assert(moveDown == NULL || moveDown->y == x); +#endif + moveDown = cuddZddLinearDown(table, x, xHigh, moveDown); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveDown); + if (!result) + goto cuddZddLinearAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +cuddZddLinearAuxOutOfMem: + if (moveDown != (Move *) CUDD_OUT_OF_MEM) { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + } + if (moveUp != (Move *) CUDD_OUT_OF_MEM) { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + } + + return(0); + +} /* end of cuddZddLinearAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable up applying the XOR transformation.] + + Description [Sifts a variable up applying the XOR + transformation. Moves y up until either it reaches the bound (xLow) + or the size of the ZDD heap increases too much. Returns the set of + moves in case of success; NULL if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddLinearUp( + DdManager * table, + int y, + int xLow, + Move * prevMoves) +{ + Move *moves; + Move *move; + int x; + int size, newsize; + int limitSize; + + moves = prevMoves; + limitSize = table->keysZ; + + x = cuddZddNextLow(table, y); + while (x >= xLow) { + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddLinearUpOutOfMem; + newsize = cuddZddLinearInPlace(table, x, y); + if (newsize == 0) + goto cuddZddLinearUpOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddLinearUpOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize > size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddZddLinearInPlace(table,x,y); + if (newsize == 0) goto cuddZddLinearUpOutOfMem; +#ifdef DD_DEBUG + if (newsize != size) { + (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } +#endif + } else { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + } + move->size = size; + + if ((double)size > (double)limitSize * table->maxGrowth) + break; + if (size < limitSize) + limitSize = size; + + y = x; + x = cuddZddNextLow(table, y); + } + return(moves); + +cuddZddLinearUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of cuddZddLinearUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable down and applies the XOR transformation.] + + Description [Sifts a variable down. Moves x down until either it + reaches the bound (xHigh) or the size of the ZDD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddLinearDown( + DdManager * table, + int x, + int xHigh, + Move * prevMoves) +{ + Move *moves; + Move *move; + int y; + int size, newsize; + int limitSize; + + moves = prevMoves; + limitSize = table->keysZ; + + y = cuddZddNextHigh(table, x); + while (y <= xHigh) { + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddLinearDownOutOfMem; + newsize = cuddZddLinearInPlace(table, x, y); + if (newsize == 0) + goto cuddZddLinearDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddLinearDownOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize > size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddZddLinearInPlace(table,x,y); + if (newsize == 0) goto cuddZddLinearDownOutOfMem; + if (newsize != size) { + (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } + } else { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + } + move->size = size; + + if ((double)size > (double)limitSize * table->maxGrowth) + break; + if (size < limitSize) + limitSize = size; + + x = y; + y = cuddZddNextHigh(table, x); + } + return(moves); + +cuddZddLinearDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of cuddZddLinearDown */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the ZDD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddLinearBackward( + DdManager * table, + int size, + Move * moves) +{ + Move *move; + int res; + + /* Find the minimum size among moves. */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) return(1); + if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) + return(0); + if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { + res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + } + + return(1); + +} /* end of cuddZddLinearBackward */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the ZDD heap to the order + in effect before the moves.] + + Description [Given a set of moves, returns the ZDD heap to the + order in effect before the moves. Returns 1 in case of success; + 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static Move* +cuddZddUndoMoves( + DdManager * table, + Move * moves) +{ + Move *invmoves = NULL; + Move *move; + Move *invmove; + int size; + + for (move = moves; move != NULL; move = move->next) { + invmove = (Move *) cuddDynamicAllocNode(table); + if (invmove == NULL) goto cuddZddUndoMovesOutOfMem; + invmove->x = move->x; + invmove->y = move->y; + invmove->next = invmoves; + invmoves = invmove; + if (move->flags == CUDD_SWAP_MOVE) { + invmove->flags = CUDD_SWAP_MOVE; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; + size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ +#ifdef DD_DEBUG + (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); +#endif + invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } + invmove->size = size; + } + + return(invmoves); + +cuddZddUndoMovesOutOfMem: + while (invmoves != NULL) { + move = invmoves->next; + cuddDeallocMove(table, invmoves); + invmoves = move; + } + return((Move *) CUDD_OUT_OF_MEM); + +} /* end of cuddZddUndoMoves */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddMisc.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddMisc.c new file mode 100644 index 000000000..ec7686276 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddMisc.c @@ -0,0 +1,278 @@ +/**CFile*********************************************************************** + + FileName [cuddZddMisc.c] + + PackageName [cudd] + + Synopsis [Miscellaneous utility functions for ZDDs.] + + Description [External procedures included in this module: +
                          +
                        • Cudd_zddDagSize() +
                        • Cudd_zddCountMinterm() +
                        • Cudd_zddPrintSubtable() +
                        + Internal procedures included in this module: +
                          +
                        + Static procedures included in this module: +
                          +
                        • cuddZddDagInt() +
                        + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddMisc.c,v 1.18 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddZddDagInt (DdNode *n, st_table *tab); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Counts the number of nodes in a ZDD.] + + Description [Counts the number of nodes in a ZDD. This function + duplicates Cudd_DagSize and is only retained for compatibility.] + + SideEffects [None] + + SeeAlso [Cudd_DagSize] + +******************************************************************************/ +int +Cudd_zddDagSize( + DdNode * p_node) +{ + + int i; + st_table *table; + + table = st_init_table(st_ptrcmp, st_ptrhash); + i = cuddZddDagInt(p_node, table); + st_free_table(table); + return(i); + +} /* end of Cudd_zddDagSize */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a ZDD.] + + Description [Counts the number of minterms of the ZDD rooted at + node. This procedure takes a parameter + path that specifies how many variables are in the + support of the function. If the procedure runs out of memory, it + returns (double) CUDD_OUT_OF_MEM.] + + SideEffects [None] + + SeeAlso [Cudd_zddCountDouble] + +******************************************************************************/ +double +Cudd_zddCountMinterm( + DdManager * zdd, + DdNode * node, + int path) +{ + double dc_var, minterms; + + dc_var = (double)((double)(zdd->sizeZ) - (double)path); + minterms = Cudd_zddCountDouble(zdd, node) / pow(2.0, dc_var); + return(minterms); + +} /* end of Cudd_zddCountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints the ZDD table.] + + Description [Prints the ZDD table for debugging purposes.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_zddPrintSubtable( + DdManager * table) +{ + int i, j; + DdNode *z1, *z1_next, *base; + DdSubtable *ZSubTable; + + base = table->one; + for (i = table->sizeZ - 1; i >= 0; i--) { + ZSubTable = &(table->subtableZ[i]); + printf("subtable[%d]:\n", i); + for (j = ZSubTable->slots - 1; j >= 0; j--) { + z1 = ZSubTable->nodelist[j]; + while (z1 != NIL(DdNode)) { + (void) fprintf(table->out, +#if SIZEOF_VOID_P == 8 + "ID = 0x%lx\tindex = %u\tr = %u\t", + (ptruint) z1 / (ptruint) sizeof(DdNode), + z1->index, z1->ref); +#else + "ID = 0x%x\tindex = %hu\tr = %hu\t", + (ptruint) z1 / (ptruint) sizeof(DdNode), + z1->index, z1->ref); +#endif + z1_next = cuddT(z1); + if (Cudd_IsConstant(z1_next)) { + (void) fprintf(table->out, "T = %d\t\t", + (z1_next == base)); + } + else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(table->out, "T = 0x%lx\t", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); +#else + (void) fprintf(table->out, "T = 0x%x\t", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); +#endif + } + z1_next = cuddE(z1); + if (Cudd_IsConstant(z1_next)) { + (void) fprintf(table->out, "E = %d\n", + (z1_next == base)); + } + else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(table->out, "E = 0x%lx\n", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); +#else + (void) fprintf(table->out, "E = 0x%x\n", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); +#endif + } + + z1_next = z1->next; + z1 = z1_next; + } + } + } + putchar('\n'); + +} /* Cudd_zddPrintSubtable */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddDagSize.] + + Description [Performs the recursive step of Cudd_zddDagSize. Does + not check for out-of-memory conditions.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddDagInt( + DdNode * n, + st_table * tab) +{ + if (n == NIL(DdNode)) + return(0); + + if (st_is_member(tab, (char *)n) == 1) + return(0); + + if (Cudd_IsConstant(n)) + return(0); + + (void)st_insert(tab, (char *)n, NIL(char)); + return(1 + cuddZddDagInt(cuddT(n), tab) + + cuddZddDagInt(cuddE(n), tab)); + +} /* cuddZddDagInt */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddPort.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddPort.c new file mode 100644 index 000000000..c661c6a88 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddPort.c @@ -0,0 +1,381 @@ +/**CFile*********************************************************************** + + FileName [cuddZddPort.c] + + PackageName [cudd] + + Synopsis [Functions that translate BDDs to ZDDs.] + + Description [External procedures included in this module: +
                          +
                        • Cudd_zddPortFromBdd() +
                        • Cudd_zddPortToBdd() +
                        + Internal procedures included in this module: +
                          +
                        + Static procedures included in this module: +
                          +
                        • zddPortFromBddStep() +
                        • zddPortToBddStep() +
                        + ] + + SeeAlso [] + + Author [Hyong-kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddPort.c,v 1.14 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * zddPortFromBddStep (DdManager *dd, DdNode *B, int expected); +static DdNode * zddPortToBddStep (DdManager *dd, DdNode *f, int depth); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Converts a BDD into a ZDD.] + + Description [Converts a BDD into a ZDD. This function assumes that + there is a one-to-one correspondence between the BDD variables and the + ZDD variables, and that the variable order is the same for both types + of variables. These conditions are established if the ZDD variables + are created by one call to Cudd_zddVarsFromBddVars with multiplicity = + 1. Returns a pointer to the resulting ZDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddVarsFromBddVars] + +******************************************************************************/ +DdNode * +Cudd_zddPortFromBdd( + DdManager * dd, + DdNode * B) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = zddPortFromBddStep(dd,B,0); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_zddPortFromBdd */ + + +/**Function******************************************************************** + + Synopsis [Converts a ZDD into a BDD.] + + Description [Converts a ZDD into a BDD. Returns a pointer to the resulting + ZDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddPortFromBdd] + +******************************************************************************/ +DdNode * +Cudd_zddPortToBdd( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = zddPortToBddStep(dd,f,0); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_zddPortToBdd */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddPortFromBdd.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +zddPortFromBddStep( + DdManager * dd, + DdNode * B, + int expected) +{ + DdNode *res, *prevZdd, *t, *e; + DdNode *Breg, *Bt, *Be; + int id, level; + + statLine(dd); + /* Terminal cases. */ + if (B == Cudd_Not(DD_ONE(dd))) + return(DD_ZERO(dd)); + if (B == DD_ONE(dd)) { + if (expected >= dd->sizeZ) { + return(DD_ONE(dd)); + } else { + return(dd->univ[expected]); + } + } + + Breg = Cudd_Regular(B); + + /* Computed table look-up. */ + res = cuddCacheLookup1Zdd(dd,Cudd_zddPortFromBdd,B); + if (res != NULL) { + level = cuddI(dd,Breg->index); + /* Adding DC vars. */ + if (expected < level) { + /* Add suppressed variables. */ + cuddRef(res); + for (level--; level >= expected; level--) { + prevZdd = res; + id = dd->invperm[level]; + res = cuddZddGetNode(dd, id, prevZdd, prevZdd); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd, prevZdd); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd, prevZdd); + } + cuddDeref(res); + } + return(res); + } /* end of cache look-up */ + + if (Cudd_IsComplement(B)) { + Bt = Cudd_Not(cuddT(Breg)); + Be = Cudd_Not(cuddE(Breg)); + } else { + Bt = cuddT(Breg); + Be = cuddE(Breg); + } + + id = Breg->index; + level = cuddI(dd,id); + t = zddPortFromBddStep(dd, Bt, level+1); + if (t == NULL) return(NULL); + cuddRef(t); + e = zddPortFromBddStep(dd, Be, level+1); + if (e == NULL) { + Cudd_RecursiveDerefZdd(dd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(dd, id, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd, t); + Cudd_RecursiveDerefZdd(dd, e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd, t); + Cudd_RecursiveDerefZdd(dd, e); + + cuddCacheInsert1(dd,Cudd_zddPortFromBdd,B,res); + + for (level--; level >= expected; level--) { + prevZdd = res; + id = dd->invperm[level]; + res = cuddZddGetNode(dd, id, prevZdd, prevZdd); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd, prevZdd); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd, prevZdd); + } + + cuddDeref(res); + return(res); + +} /* end of zddPortFromBddStep */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddPortToBdd.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +zddPortToBddStep( + DdManager * dd /* manager */, + DdNode * f /* ZDD to be converted */, + int depth /* recursion depth */) +{ + DdNode *one, *zero, *T, *E, *res, *var; + unsigned int index; + unsigned int level; + + statLine(dd); + one = DD_ONE(dd); + zero = DD_ZERO(dd); + if (f == zero) return(Cudd_Not(one)); + + if (depth == dd->sizeZ) return(one); + + index = dd->invpermZ[depth]; + level = cuddIZ(dd,f->index); + var = cuddUniqueInter(dd,index,one,Cudd_Not(one)); + if (var == NULL) return(NULL); + cuddRef(var); + + if (level > (unsigned) depth) { + E = zddPortToBddStep(dd,f,depth+1); + if (E == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(E); + res = cuddBddIteRecur(dd,var,Cudd_Not(one),E); + if (res == NULL) { + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,E); + cuddDeref(res); + return(res); + } + + res = cuddCacheLookup1(dd,Cudd_zddPortToBdd,f); + if (res != NULL) { + Cudd_RecursiveDeref(dd,var); + return(res); + } + + T = zddPortToBddStep(dd,cuddT(f),depth+1); + if (T == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(T); + E = zddPortToBddStep(dd,cuddE(f),depth+1); + if (E == NULL) { + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + + res = cuddBddIteRecur(dd,var,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + cuddDeref(res); + + cuddCacheInsert1(dd,Cudd_zddPortToBdd,f,res); + + return(res); + +} /* end of zddPortToBddStep */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddReord.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddReord.c new file mode 100644 index 000000000..c4b67bf84 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddReord.c @@ -0,0 +1,1664 @@ +/**CFile*********************************************************************** + + FileName [cuddZddReord.c] + + PackageName [cudd] + + Synopsis [Procedures for dynamic variable ordering of ZDDs.] + + Description [External procedures included in this module: +
                          +
                        • Cudd_zddReduceHeap() +
                        • Cudd_zddShuffleHeap() +
                        + Internal procedures included in this module: +
                          +
                        • cuddZddAlignToBdd() +
                        • cuddZddNextHigh() +
                        • cuddZddNextLow() +
                        • cuddZddUniqueCompare() +
                        • cuddZddSwapInPlace() +
                        • cuddZddSwapping() +
                        • cuddZddSifting() +
                        + Static procedures included in this module: +
                          +
                        • zddSwapAny() +
                        • cuddZddSiftingAux() +
                        • cuddZddSiftingUp() +
                        • cuddZddSiftingDown() +
                        • cuddZddSiftingBackward() +
                        • zddReorderPreprocess() +
                        • zddReorderPostprocess() +
                        • zddShuffle() +
                        • zddSiftUp() +
                        + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_MAX_SUBTABLE_SPARSITY 8 +#define DD_SHRINK_FACTOR 2 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddReord.c,v 1.49 2012/02/05 01:07:19 fabio Exp $"; +#endif + +int *zdd_entry; + +int zddTotalNumberSwapping; + +static DdNode *empty; + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static Move * zddSwapAny (DdManager *table, int x, int y); +static int cuddZddSiftingAux (DdManager *table, int x, int x_low, int x_high); +static Move * cuddZddSiftingUp (DdManager *table, int x, int x_low, int initial_size); +static Move * cuddZddSiftingDown (DdManager *table, int x, int x_high, int initial_size); +static int cuddZddSiftingBackward (DdManager *table, Move *moves, int size); +static void zddReorderPreprocess (DdManager *table); +static int zddReorderPostprocess (DdManager *table); +static int zddShuffle (DdManager *table, int *permutation); +static int zddSiftUp (DdManager *table, int x, int xLow); +static void zddFixTree (DdManager *table, MtrNode *treenode); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Main dynamic reordering routine for ZDDs.] + + Description [Main dynamic reordering routine for ZDDs. + Calls one of the possible reordering procedures: +
                          +
                        • Swapping +
                        • Sifting +
                        • Symmetric Sifting +
                        + + For sifting and symmetric sifting it is possible to request reordering + to convergence.

                        + + The core of all methods is the reordering procedure + cuddZddSwapInPlace() which swaps two adjacent variables. + Returns 1 in case of success; 0 otherwise. In the case of symmetric + sifting (with and without convergence) returns 1 plus the number of + symmetric variables, in case of success.] + + SideEffects [Changes the variable order for all ZDDs and clears + the cache.] + +******************************************************************************/ +int +Cudd_zddReduceHeap( + DdManager * table /* DD manager */, + Cudd_ReorderingType heuristic /* method used for reordering */, + int minsize /* bound below which no reordering occurs */) +{ + DdHook *hook; + int result; + unsigned int nextDyn; +#ifdef DD_STATS + unsigned int initialSize; + unsigned int finalSize; +#endif + unsigned long localTime; + + /* Don't reorder if there are too many dead nodes. */ + if (table->keysZ - table->deadZ < (unsigned) minsize) + return(1); + + if (heuristic == CUDD_REORDER_SAME) { + heuristic = table->autoMethodZ; + } + if (heuristic == CUDD_REORDER_NONE) { + return(1); + } + + /* This call to Cudd_zddReduceHeap does initiate reordering. Therefore + ** we count it. + */ + table->reorderings++; + empty = table->zero; + + localTime = util_cpu_time(); + + /* Run the hook functions. */ + hook = table->preReorderingHook; + while (hook != NULL) { + int res = (hook->f)(table, "ZDD", (void *)heuristic); + if (res == 0) return(0); + hook = hook->next; + } + + /* Clear the cache and collect garbage. */ + zddReorderPreprocess(table); + zddTotalNumberSwapping = 0; + +#ifdef DD_STATS + initialSize = table->keysZ; + + switch(heuristic) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + (void) fprintf(table->out,"#:I_RANDOM "); + break; + case CUDD_REORDER_SIFT: + case CUDD_REORDER_SIFT_CONVERGE: + case CUDD_REORDER_SYMM_SIFT: + case CUDD_REORDER_SYMM_SIFT_CONV: + (void) fprintf(table->out,"#:I_SIFTING "); + break; + case CUDD_REORDER_LINEAR: + case CUDD_REORDER_LINEAR_CONVERGE: + (void) fprintf(table->out,"#:I_LINSIFT "); + break; + default: + (void) fprintf(table->err,"Unsupported ZDD reordering method\n"); + return(0); + } + (void) fprintf(table->out,"%8d: initial size",initialSize); +#endif + + result = cuddZddTreeSifting(table,heuristic); + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + finalSize = table->keysZ; + (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n", + ((double)(util_cpu_time() - localTime)/1000.0)); + (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n", + zddTotalNumberSwapping); +#endif + + if (result == 0) + return(0); + + if (!zddReorderPostprocess(table)) + return(0); + + if (table->realignZ) { + if (!cuddBddAlignToZdd(table)) + return(0); + } + + nextDyn = table->keysZ * DD_DYN_RATIO; + if (table->reorderings < 20 || nextDyn > table->nextDyn) + table->nextDyn = nextDyn; + else + table->nextDyn += 20; + + table->reordered = 1; + + /* Run hook functions. */ + hook = table->postReorderingHook; + while (hook != NULL) { + int res = (hook->f)(table, "ZDD", (void *)localTime); + if (res == 0) return(0); + hook = hook->next; + } + /* Update cumulative reordering time. */ + table->reordTime += util_cpu_time() - localTime; + + return(result); + +} /* end of Cudd_zddReduceHeap */ + + +/**Function******************************************************************** + + Synopsis [Reorders ZDD variables according to given permutation.] + + Description [Reorders ZDD variables according to given permutation. + The i-th entry of the permutation array contains the index of the variable + that should be brought to the i-th level. The size of the array should be + equal or greater to the number of variables currently in use. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [Changes the ZDD variable order for all diagrams and clears + the cache.] + + SeeAlso [Cudd_zddReduceHeap] + +******************************************************************************/ +int +Cudd_zddShuffleHeap( + DdManager * table /* DD manager */, + int * permutation /* required variable permutation */) +{ + + int result; + + empty = table->zero; + zddReorderPreprocess(table); + + result = zddShuffle(table,permutation); + + if (!zddReorderPostprocess(table)) return(0); + + return(result); + +} /* end of Cudd_zddShuffleHeap */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Reorders ZDD variables according to the order of the BDD + variables.] + + Description [Reorders ZDD variables according to the order of the + BDD variables. This function can be called at the end of BDD + reordering to insure that the order of the ZDD variables is + consistent with the order of the BDD variables. The number of ZDD + variables must be a multiple of the number of BDD variables. Let + M be the ratio of the two numbers. cuddZddAlignToBdd + then considers the ZDD variables from M*i to + (M+1)*i-1 as corresponding to BDD variable + i. This function should be normally called from + Cudd_ReduceHeap, which clears the cache. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [Changes the ZDD variable order for all diagrams and performs + garbage collection of the ZDD unique table.] + + SeeAlso [Cudd_zddShuffleHeap Cudd_ReduceHeap] + +******************************************************************************/ +int +cuddZddAlignToBdd( + DdManager * table /* DD manager */) +{ + int *invpermZ; /* permutation array */ + int M; /* ratio of ZDD variables to BDD variables */ + int i,j; /* loop indices */ + int result; /* return value */ + + /* We assume that a ratio of 0 is OK. */ + if (table->sizeZ == 0) + return(1); + + empty = table->zero; + M = table->sizeZ / table->size; + /* Check whether the number of ZDD variables is a multiple of the + ** number of BDD variables. + */ + if (M * table->size != table->sizeZ) + return(0); + /* Create and initialize the inverse permutation array. */ + invpermZ = ALLOC(int,table->sizeZ); + if (invpermZ == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < table->size; i++) { + int index = table->invperm[i]; + int indexZ = index * M; + int levelZ = table->permZ[indexZ]; + levelZ = (levelZ / M) * M; + for (j = 0; j < M; j++) { + invpermZ[M * i + j] = table->invpermZ[levelZ + j]; + } + } + /* Eliminate dead nodes. Do not scan the cache again, because we + ** assume that Cudd_ReduceHeap has already cleared it. + */ + cuddGarbageCollect(table,0); + + result = zddShuffle(table, invpermZ); + FREE(invpermZ); + /* Fix the ZDD variable group tree. */ + zddFixTree(table,table->treeZ); + return(result); + +} /* end of cuddZddAlignToBdd */ + + +/**Function******************************************************************** + + Synopsis [Finds the next subtable with a larger index.] + + Description [Finds the next subtable with a larger index. Returns the + index.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddNextHigh( + DdManager * table, + int x) +{ + return(x + 1); + +} /* end of cuddZddNextHigh */ + + +/**Function******************************************************************** + + Synopsis [Finds the next subtable with a smaller index.] + + Description [Finds the next subtable with a smaller index. Returns the + index.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddNextLow( + DdManager * table, + int x) +{ + return(x - 1); + +} /* end of cuddZddNextLow */ + + +/**Function******************************************************************** + + Synopsis [Comparison function used by qsort.] + + Description [Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddUniqueCompare( + int * ptr_x, + int * ptr_y) +{ + return(zdd_entry[*ptr_y] - zdd_entry[*ptr_x]); + +} /* end of cuddZddUniqueCompare */ + + +/**Function******************************************************************** + + Synopsis [Swaps two adjacent variables.] + + Description [Swaps two adjacent variables. It assumes that no dead + nodes are present on entry to this procedure. The procedure then + guarantees that no dead nodes will be present when it terminates. + cuddZddSwapInPlace assumes that x < y. Returns the number of keys in + the table if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddSwapInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int i; + int posn; + DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; + DdNode *newf1, *newf0, *next; + DdNodePtr g, *lastP, *previousP; + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddZddNextHigh(table,x) == y); + assert(table->subtableZ[x].keys != 0); + assert(table->subtableZ[y].keys != 0); + assert(table->subtableZ[x].dead == 0); + assert(table->subtableZ[y].dead == 0); +#endif + + zddTotalNumberSwapping++; + + /* Get parameters of x subtable. */ + xindex = table->invpermZ[x]; + xlist = table->subtableZ[x].nodelist; + oldxkeys = table->subtableZ[x].keys; + xslots = table->subtableZ[x].slots; + xshift = table->subtableZ[x].shift; + newxkeys = 0; + + yindex = table->invpermZ[y]; + ylist = table->subtableZ[y].nodelist; + oldykeys = table->subtableZ[y].keys; + yslots = table->subtableZ[y].slots; + yshift = table->subtableZ[y].shift; + newykeys = oldykeys; + + /* The nodes in the x layer that don't depend on y directly + ** will stay there; the others are put in a chain. + ** The chain is handled as a FIFO; g points to the beginning and + ** last points to the end. + */ + + g = NULL; + lastP = &g; + for (i = 0; i < xslots; i++) { + previousP = &(xlist[i]); + f = *previousP; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if ((f1->index != (DdHalfWord) yindex) && + (f0->index != (DdHalfWord) yindex)) { /* stays */ + newxkeys++; + *previousP = f; + previousP = &(f->next); + } else { + f->index = yindex; + *lastP = f; + lastP = &(f->next); + } + f = next; + } /* while there are elements in the collision chain */ + *previousP = NULL; + } /* for each slot of the x subtable */ + *lastP = NULL; + + +#ifdef DD_COUNT + table->swapSteps += oldxkeys - newxkeys; +#endif + /* Take care of the x nodes that must be re-expressed. + ** They form a linked list pointed by g. Their index has been + ** changed to yindex already. + */ + f = g; + while (f != NULL) { + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = empty; f10 = f1; + } + f0 = cuddE(f); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = empty; f00 = f0; + } + + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == empty) { + if (f01 != empty) { + newf1 = f01; + cuddSatInc(newf1->ref); + } + /* else case was already handled when finding nodes + ** with both children below level y + */ + } else { + /* Check xlist for triple (xindex, f11, f01). */ + posn = ddHash(f11, f01, xshift); + /* For each element newf1 in collision list xlist[posn]. */ + newf1 = xlist[posn]; + while (newf1 != NULL) { + if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = xindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f01; + /* Insert newf1 in the collision list xlist[pos]; + ** increase the ref counts of f11 and f01 + */ + newxkeys++; + newf1->next = xlist[posn]; + xlist[posn] = newf1; + cuddSatInc(f11->ref); + cuddSatInc(f01->ref); + } + } + cuddT(f) = newf1; + + /* Do the same for f0. */ + /* Decrease ref count of f0. */ + cuddSatDec(f0->ref); + /* Create the new E child. */ + if (f10 == empty) { + newf0 = f00; + cuddSatInc(newf0->ref); + } else { + /* Check xlist for triple (xindex, f10, f00). */ + posn = ddHash(f10, f00, xshift); + /* For each element newf0 in collision list xlist[posn]. */ + newf0 = xlist[posn]; + while (newf0 != NULL) { + if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { + cuddSatInc(newf0->ref); + break; /* match */ + } + newf0 = newf0->next; + } /* while newf0 */ + if (newf0 == NULL) { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto zddSwapOutOfMem; + newf0->index = xindex; newf0->ref = 1; + cuddT(newf0) = f10; cuddE(newf0) = f00; + /* Insert newf0 in the collision list xlist[posn]; + ** increase the ref counts of f10 and f00. + */ + newxkeys++; + newf0->next = xlist[posn]; + xlist[posn] = newf0; + cuddSatInc(f10->ref); + cuddSatInc(f00->ref); + } + } + cuddE(f) = newf0; + + /* Insert the modified f in ylist. + ** The modified f does not already exists in ylist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, yshift); + newykeys++; + f->next = ylist[posn]; + ylist[posn] = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previousP = &(ylist[i]); + f = *previousP; + while (f != NULL) { + next = f->next; + if (f->ref == 0) { + cuddSatDec(cuddT(f)->ref); + cuddSatDec(cuddE(f)->ref); + cuddDeallocNode(table, f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = NULL; + } /* for i */ + + /* Set the appropriate fields in table. */ + table->subtableZ[x].nodelist = ylist; + table->subtableZ[x].slots = yslots; + table->subtableZ[x].shift = yshift; + table->subtableZ[x].keys = newykeys; + table->subtableZ[x].maxKeys = yslots * DD_MAX_SUBTABLE_DENSITY; + + table->subtableZ[y].nodelist = xlist; + table->subtableZ[y].slots = xslots; + table->subtableZ[y].shift = xshift; + table->subtableZ[y].keys = newxkeys; + table->subtableZ[y].maxKeys = xslots * DD_MAX_SUBTABLE_DENSITY; + + table->permZ[xindex] = y; table->permZ[yindex] = x; + table->invpermZ[x] = yindex; table->invpermZ[y] = xindex; + + table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys; + + /* Update univ section; univ[x] remains the same. */ + table->univ[y] = cuddT(table->univ[x]); + + return (table->keysZ); + +zddSwapOutOfMem: + (void) fprintf(table->err, "Error: cuddZddSwapInPlace out of memory\n"); + + return (0); + +} /* end of cuddZddSwapInPlace */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables by a sequence of (non-adjacent) swaps.] + + Description [Implementation of Plessier's algorithm that reorders + variables by a sequence of (non-adjacent) swaps. +

                          +
                        1. Select two variables (RANDOM or HEURISTIC). +
                        2. Permute these variables. +
                        3. If the nodes have decreased accept the permutation. +
                        4. Otherwise reconstruct the original heap. +
                        5. Loop. +
                        + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddSwapping( + DdManager * table, + int lower, + int upper, + Cudd_ReorderingType heuristic) +{ + int i, j; + int max, keys; + int nvars; + int x, y; + int iterate; + int previousSize; + Move *moves, *move; + int pivot; + int modulo; + int result; + +#ifdef DD_DEBUG + /* Sanity check */ + assert(lower >= 0 && upper < table->sizeZ && lower <= upper); +#endif + + nvars = upper - lower + 1; + iterate = nvars; + + for (i = 0; i < iterate; i++) { + if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { + /* Find pivot <= id with maximum keys. */ + for (max = -1, j = lower; j <= upper; j++) { + if ((keys = table->subtableZ[j].keys) > max) { + max = keys; + pivot = j; + } + } + + modulo = upper - pivot; + if (modulo == 0) { + y = pivot; /* y = nvars-1 */ + } else { + /* y = random # from {pivot+1 .. nvars-1} */ + y = pivot + 1 + (int) (Cudd_Random() % modulo); + } + + modulo = pivot - lower - 1; + if (modulo < 1) { /* if pivot = 1 or 0 */ + x = lower; + } else { + do { /* x = random # from {0 .. pivot-2} */ + x = (int) Cudd_Random() % modulo; + } while (x == y); + /* Is this condition really needed, since x and y + are in regions separated by pivot? */ + } + } else { + x = (int) (Cudd_Random() % nvars) + lower; + do { + y = (int) (Cudd_Random() % nvars) + lower; + } while (x == y); + } + + previousSize = table->keysZ; + moves = zddSwapAny(table, x, y); + if (moves == NULL) + goto cuddZddSwappingOutOfMem; + + result = cuddZddSiftingBackward(table, moves, previousSize); + if (!result) + goto cuddZddSwappingOutOfMem; + + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + return(1); + +cuddZddSwappingOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(0); + +} /* end of cuddZddSwapping */ + + +/**Function******************************************************************** + + Synopsis [Implementation of Rudell's sifting algorithm.] + + Description [Implementation of Rudell's sifting algorithm. + Assumes that no dead nodes are present. +
                          +
                        1. Order all the variables according to the number of entries + in each unique table. +
                        2. Sift the variable up and down, remembering each time the + total size of the DD heap. +
                        3. Select the best permutation. +
                        4. Repeat 3 and 4 for all variables. +
                        + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int size; + int x; + int result; +#ifdef DD_STATS + int previousSize; +#endif + + size = table->sizeZ; + + /* Find order in which to sift variables. */ + var = NULL; + zdd_entry = ALLOC(int, size); + if (zdd_entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; + } + var = ALLOC(int, size); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; + } + + for (i = 0; i < size; i++) { + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; + } + + qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); + + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar, size); i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = cuddZddSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSiftingOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + + FREE(var); + FREE(zdd_entry); + + return(1); + +cuddZddSiftingOutOfMem: + + if (zdd_entry != NULL) FREE(zdd_entry); + if (var != NULL) FREE(var); + + return(0); + +} /* end of cuddZddSifting */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Swaps any two variables.] + + Description [Swaps any two variables. Returns the set of moves.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +zddSwapAny( + DdManager * table, + int x, + int y) +{ + Move *move, *moves; + int tmp, size; + int x_ref, y_ref; + int x_next, y_next; + int limit_size; + + if (x > y) { /* make x precede y */ + tmp = x; x = y; y = tmp; + } + + x_ref = x; y_ref = y; + + x_next = cuddZddNextHigh(table, x); + y_next = cuddZddNextLow(table, y); + moves = NULL; + limit_size = table->keysZ; + + for (;;) { + if (x_next == y_next) { /* x < x_next = y_next < y */ + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, y_next, y); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + + } else if (x == y_next) { /* x = y_next < y = x_next */ + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + } else { + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, y_next, y); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + x = x_next; y = y_next; + } + + x_next = cuddZddNextHigh(table, x); + y_next = cuddZddNextLow(table, y); + if (x_next > y_ref) + break; /* if x == y_ref */ + + if ((double) size > table->maxGrowth * (double) limit_size) + break; + if (size < limit_size) + limit_size = size; + } + if (y_next >= x_ref) { + size = cuddZddSwapInPlace(table, y_next, y); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + } + + return(moves); + +zddSwapAnyOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of zddSwapAny */ + + +/**Function******************************************************************** + + Synopsis [Given xLow <= x <= xHigh moves x up and down between the + boundaries.] + + Description [Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSiftingAux( + DdManager * table, + int x, + int x_low, + int x_high) +{ + Move *move; + Move *moveUp; /* list of up move */ + Move *moveDown; /* list of down move */ + + int initial_size; + int result; + + initial_size = table->keysZ; + +#ifdef DD_DEBUG + assert(table->subtableZ[x].keys > 0); +#endif + + moveDown = NULL; + moveUp = NULL; + + if (x == x_low) { + moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); + /* after that point x --> x_high */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveDown, + initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; + + } + else if (x == x_high) { + moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); + /* after that point x --> x_low */ + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveUp, initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; + } + else if ((x - x_low) > (x_high - x)) { + /* must go down first:shorter */ + moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); + /* after that point x --> x_high */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + moveUp = cuddZddSiftingUp(table, moveDown->y, x_low, + initial_size); + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveUp, initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; + } + else { + moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); + /* after that point x --> x_high */ + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + moveDown = cuddZddSiftingDown(table, moveUp->x, x_high, + initial_size); + /* then move up */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveDown, + initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; + } + + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(1); + +cuddZddSiftingAuxOutOfMem: + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + + return(0); + +} /* end of cuddZddSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable up.] + + Description [Sifts a variable up. Moves y up until either it reaches + the bound (x_low) or the size of the ZDD heap increases too much. + Returns the set of moves in case of success; NULL if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddSiftingUp( + DdManager * table, + int x, + int x_low, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddZddNextLow(table, x); + while (y >= x_low) { + size = cuddZddSwapInPlace(table, y, x); + if (size == 0) + goto cuddZddSiftingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSiftingUpOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + + if ((double)size > (double)limit_size * table->maxGrowth) + break; + if (size < limit_size) + limit_size = size; + + x = y; + y = cuddZddNextLow(table, x); + } + return(moves); + +cuddZddSiftingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of cuddZddSiftingUp */ + + +/**Function******************************************************************** + + Synopsis [Sifts a variable down.] + + Description [Sifts a variable down. Moves x down until either it + reaches the bound (x_high) or the size of the ZDD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddSiftingDown( + DdManager * table, + int x, + int x_high, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddZddNextHigh(table, x); + while (y <= x_high) { + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddSiftingDownOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + if ((double)size > (double)limit_size * table->maxGrowth) + break; + if (size < limit_size) + limit_size = size; + + x = y; + y = cuddZddNextHigh(table, x); + } + return(moves); + +cuddZddSiftingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of cuddZddSiftingDown */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the ZDD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSiftingBackward( + DdManager * table, + Move * moves, + int size) +{ + int i; + int i_best; + Move *move; + int res; + + /* Find the minimum size among moves. */ + i_best = -1; + for (move = moves, i = 0; move != NULL; move = move->next, i++) { + if (move->size < size) { + i_best = i; + size = move->size; + } + } + + for (move = moves, i = 0; move != NULL; move = move->next, i++) { + if (i == i_best) + break; + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) + return(0); + if (i_best == -1 && res == size) + break; + } + + return(1); + +} /* end of cuddZddSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Prepares the ZDD heap for dynamic reordering.] + + Description [Prepares the ZDD heap for dynamic reordering. Does + garbage collection, to guarantee that there are no dead nodes; + and clears the cache, which is invalidated by dynamic reordering.] + + SideEffects [None] + +******************************************************************************/ +static void +zddReorderPreprocess( + DdManager * table) +{ + + /* Clear the cache. */ + cuddCacheFlush(table); + + /* Eliminate dead nodes. Do not scan the cache again. */ + cuddGarbageCollect(table,0); + + return; + +} /* end of ddReorderPreprocess */ + + +/**Function******************************************************************** + + Synopsis [Shrinks almost empty ZDD subtables at the end of reordering + to guarantee that they have a reasonable load factor.] + + Description [Shrinks almost empty subtables at the end of reordering to + guarantee that they have a reasonable load factor. However, if there many + nodes are being reclaimed, then no resizing occurs. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +zddReorderPostprocess( + DdManager * table) +{ + int i, j, posn; + DdNodePtr *nodelist, *oldnodelist; + DdNode *node, *next; + unsigned int slots, oldslots; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + +#ifdef DD_VERBOSE + (void) fflush(table->out); +#endif + + /* If we have very many reclaimed nodes, we do not want to shrink + ** the subtables, because this will lead to more garbage + ** collections. More garbage collections mean shorter mean life for + ** nodes with zero reference count; hence lower probability of finding + ** a result in the cache. + */ + if (table->reclaimed > table->allocated * 0.5) return(1); + + /* Resize subtables. */ + for (i = 0; i < table->sizeZ; i++) { + int shift; + oldslots = table->subtableZ[i].slots; + if (oldslots < table->subtableZ[i].keys * DD_MAX_SUBTABLE_SPARSITY || + oldslots <= table->initSlots) continue; + oldnodelist = table->subtableZ[i].nodelist; + slots = oldslots >> 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + return(1); + } + table->subtableZ[i].nodelist = nodelist; + table->subtableZ[i].slots = slots; + table->subtableZ[i].shift++; + table->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; +#ifdef DD_VERBOSE + (void) fprintf(table->err, + "shrunk layer %d (%d keys) from %d to %d slots\n", + i, table->subtableZ[i].keys, oldslots, slots); +#endif + + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + shift = table->subtableZ[i].shift; + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + posn = ddHash(cuddT(node), cuddE(node), shift); + node->next = nodelist[posn]; + nodelist[posn] = node; + node = next; + } + } + FREE(oldnodelist); + + table->memused += (slots - oldslots) * sizeof(DdNode *); + table->slots += slots - oldslots; + table->minDead = (unsigned) (table->gcFrac * (double) table->slots); + table->cacheSlack = (int) ddMin(table->maxCacheHard, + DD_MAX_CACHE_TO_SLOTS_RATIO*table->slots) - + 2 * (int) table->cacheSlots; + } + /* We don't look at the constant subtable, because it is not + ** affected by reordering. + */ + + return(1); + +} /* end of zddReorderPostprocess */ + + +/**Function******************************************************************** + + Synopsis [Reorders ZDD variables according to a given permutation.] + + Description [Reorders ZDD variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. zddShuffle assumes that no + dead nodes are present. The reordering is achieved by a series of + upward sifts. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zddShuffle( + DdManager * table, + int * permutation) +{ + int index; + int level; + int position; + int numvars; + int result; +#ifdef DD_STATS + unsigned long localTime; + int initialSize; + int finalSize; + int previousSize; +#endif + + zddTotalNumberSwapping = 0; +#ifdef DD_STATS + localTime = util_cpu_time(); + initialSize = table->keysZ; + (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n", + initialSize); +#endif + + numvars = table->sizeZ; + + for (level = 0; level < numvars; level++) { + index = permutation[level]; + position = table->permZ[index]; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = zddSiftUp(table,position,level); + if (!result) return(0); +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + finalSize = table->keysZ; + (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:T_SHUFFLE %8g: total time (sec)\n", + ((double)(util_cpu_time() - localTime)/1000.0)); + (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n", + zddTotalNumberSwapping); +#endif + + return(1); + +} /* end of zddShuffle */ + + +/**Function******************************************************************** + + Synopsis [Moves one ZDD variable up.] + + Description [Takes a ZDD variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zddSiftUp( + DdManager * table, + int x, + int xLow) +{ + int y; + int size; + + y = cuddZddNextLow(table,x); + while (y >= xLow) { + size = cuddZddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddZddNextLow(table,x); + } + return(1); + +} /* end of zddSiftUp */ + + +/**Function******************************************************************** + + Synopsis [Fixes the ZDD variable group tree after a shuffle.] + + Description [Fixes the ZDD variable group tree after a + shuffle. Assumes that the order of the variables in a terminal node + has not been changed.] + + SideEffects [Changes the ZDD variable group tree.] + + SeeAlso [] + +******************************************************************************/ +static void +zddFixTree( + DdManager * table, + MtrNode * treenode) +{ + if (treenode == NULL) return; + treenode->low = ((int) treenode->index < table->sizeZ) ? + table->permZ[treenode->index] : treenode->index; + if (treenode->child != NULL) { + zddFixTree(table, treenode->child); + } + if (treenode->younger != NULL) + zddFixTree(table, treenode->younger); + if (treenode->parent != NULL && treenode->low < treenode->parent->low) { + treenode->parent->low = treenode->low; + treenode->parent->index = treenode->index; + } + return; + +} /* end of zddFixTree */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddSetop.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddSetop.c new file mode 100644 index 000000000..18cce2c92 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddSetop.c @@ -0,0 +1,1166 @@ +/**CFile*********************************************************************** + + FileName [cuddZddSetop.c] + + PackageName [cudd] + + Synopsis [Set operations on ZDDs.] + + Description [External procedures included in this module: +
                          +
                        • Cudd_zddIte() +
                        • Cudd_zddUnion() +
                        • Cudd_zddIntersect() +
                        • Cudd_zddDiff() +
                        • Cudd_zddDiffConst() +
                        • Cudd_zddSubset1() +
                        • Cudd_zddSubset0() +
                        • Cudd_zddChange() +
                        + Internal procedures included in this module: +
                          +
                        • cuddZddIte() +
                        • cuddZddUnion() +
                        • cuddZddIntersect() +
                        • cuddZddDiff() +
                        • cuddZddChangeAux() +
                        • cuddZddSubset1() +
                        • cuddZddSubset0() +
                        + Static procedures included in this module: +
                          +
                        • zdd_subset1_aux() +
                        • zdd_subset0_aux() +
                        • zddVarToConst() +
                        + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddSetop.c,v 1.26 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * zdd_subset1_aux (DdManager *zdd, DdNode *P, DdNode *zvar); +static DdNode * zdd_subset0_aux (DdManager *zdd, DdNode *P, DdNode *zvar); +static void zddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *base, DdNode *empty); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the ITE of three ZDDs.] + + Description [Computes the ITE of three ZDDs. Returns a pointer to the + result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddIte(dd, f, g, h); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddIte */ + + +/**Function******************************************************************** + + Synopsis [Computes the union of two ZDDs.] + + Description [Computes the union of two ZDDs. Returns a pointer to the + result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddUnion( + DdManager * dd, + DdNode * P, + DdNode * Q) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddUnion(dd, P, Q); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddUnion */ + + +/**Function******************************************************************** + + Synopsis [Computes the intersection of two ZDDs.] + + Description [Computes the intersection of two ZDDs. Returns a pointer to + the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddIntersect( + DdManager * dd, + DdNode * P, + DdNode * Q) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddIntersect(dd, P, Q); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddIntersect */ + + +/**Function******************************************************************** + + Synopsis [Computes the difference of two ZDDs.] + + Description [Computes the difference of two ZDDs. Returns a pointer to the + result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddDiffConst] + +******************************************************************************/ +DdNode * +Cudd_zddDiff( + DdManager * dd, + DdNode * P, + DdNode * Q) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddZddDiff(dd, P, Q); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddDiff */ + + +/**Function******************************************************************** + + Synopsis [Performs the inclusion test for ZDDs (P implies Q).] + + Description [Inclusion test for ZDDs (P implies Q). No new nodes are + generated by this procedure. Returns empty if true; + a valid pointer different from empty or DD_NON_CONSTANT otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddDiff] + +******************************************************************************/ +DdNode * +Cudd_zddDiffConst( + DdManager * zdd, + DdNode * P, + DdNode * Q) +{ + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *res; + DdManager *table = zdd; + + statLine(zdd); + if (P == empty) + return(empty); + if (Q == empty) + return(P); + if (P == Q) + return(empty); + + /* Check cache. The cache is shared by cuddZddDiff(). */ + res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) + p_top = P->index; + else + p_top = zdd->permZ[P->index]; + if (cuddIsConstant(Q)) + q_top = Q->index; + else + q_top = zdd->permZ[Q->index]; + if (p_top < q_top) { + res = DD_NON_CONSTANT; + } else if (p_top > q_top) { + res = Cudd_zddDiffConst(zdd, P, cuddE(Q)); + } else { + t = Cudd_zddDiffConst(zdd, cuddT(P), cuddT(Q)); + if (t != empty) + res = DD_NON_CONSTANT; + else + res = Cudd_zddDiffConst(zdd, cuddE(P), cuddE(Q)); + } + + cuddCacheInsert2(table, cuddZddDiff, P, Q, res); + + return(res); + +} /* end of Cudd_zddDiffConst */ + + +/**Function******************************************************************** + + Synopsis [Computes the positive cofactor of a ZDD w.r.t. a variable.] + + Description [Computes the positive cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is asserted. Returns a pointer to + the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddSubset0] + +******************************************************************************/ +DdNode * +Cudd_zddSubset1( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *r; + + do { + dd->reordered = 0; + r = cuddZddSubset1(dd, P, var); + } while (dd->reordered == 1); + + return(r); + +} /* end of Cudd_zddSubset1 */ + + +/**Function******************************************************************** + + Synopsis [Computes the negative cofactor of a ZDD w.r.t. a variable.] + + Description [Computes the negative cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is negated. Returns a pointer to + the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddSubset1] + +******************************************************************************/ +DdNode * +Cudd_zddSubset0( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *r; + + do { + dd->reordered = 0; + r = cuddZddSubset0(dd, P, var); + } while (dd->reordered == 1); + + return(r); + +} /* end of Cudd_zddSubset0 */ + + +/**Function******************************************************************** + + Synopsis [Substitutes a variable with its complement in a ZDD.] + + Description [Substitutes a variable with its complement in a ZDD. + returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_zddChange( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *res; + + if ((unsigned int) var >= CUDD_MAXINDEX - 1) return(NULL); + + do { + dd->reordered = 0; + res = cuddZddChange(dd, P, var); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_zddChange */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddIte.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *tautology, *empty; + DdNode *r,*Gv,*Gvn,*Hv,*Hvn,*t,*e; + unsigned int topf,topg,toph,v,top; + int index; + + statLine(dd); + /* Trivial cases. */ + /* One variable cases. */ + if (f == (empty = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ + return(h); + } + topf = cuddIZ(dd,f->index); + topg = cuddIZ(dd,g->index); + toph = cuddIZ(dd,h->index); + v = ddMin(topg,toph); + top = ddMin(topf,v); + + tautology = (top == CUDD_MAXINDEX) ? DD_ONE(dd) : dd->univ[top]; + if (f == tautology) { /* ITE(1,G,H) = G */ + return(g); + } + + /* From now on, f is known to not be a constant. */ + zddVarToConst(f,&g,&h,tautology,empty); + + /* Check remaining one variable cases. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } + + if (g == tautology) { /* ITE(F,1,0) = F */ + if (h == empty) return(f); + } + + /* Check cache. */ + r = cuddCacheLookupZdd(dd,DD_ZDD_ITE_TAG,f,g,h); + if (r != NULL) { + return(r); + } + + /* Recompute these because they may have changed in zddVarToConst. */ + topg = cuddIZ(dd,g->index); + toph = cuddIZ(dd,h->index); + v = ddMin(topg,toph); + + if (topf < v) { + r = cuddZddIte(dd,cuddE(f),g,h); + if (r == NULL) return(NULL); + } else if (topf > v) { + if (topg > v) { + Gvn = g; + index = h->index; + } else { + Gvn = cuddE(g); + index = g->index; + } + if (toph > v) { + Hv = empty; Hvn = h; + } else { + Hv = cuddT(h); Hvn = cuddE(h); + } + e = cuddZddIte(dd,f,Gvn,Hvn); + if (e == NULL) return(NULL); + cuddRef(e); + r = cuddZddGetNode(dd,index,Hv,e); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + return(NULL); + } + cuddDeref(e); + } else { + index = f->index; + if (topg > v) { + Gv = empty; Gvn = g; + } else { + Gv = cuddT(g); Gvn = cuddE(g); + } + if (toph > v) { + Hv = empty; Hvn = h; + } else { + Hv = cuddT(h); Hvn = cuddE(h); + } + e = cuddZddIte(dd,cuddE(f),Gvn,Hvn); + if (e == NULL) return(NULL); + cuddRef(e); + t = cuddZddIte(dd,cuddT(f),Gv,Hv); + if (t == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + return(NULL); + } + cuddRef(t); + r = cuddZddGetNode(dd,index,t,e); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + Cudd_RecursiveDerefZdd(dd,t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert(dd,DD_ZDD_ITE_TAG,f,g,h,r); + + return(r); + +} /* end of cuddZddIte */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddUnion.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddUnion( + DdManager * zdd, + DdNode * P, + DdNode * Q) +{ + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; + + statLine(zdd); + if (P == empty) + return(Q); + if (Q == empty) + return(P); + if (P == Q) + return(P); + + /* Check cache */ + res = cuddCacheLookup2Zdd(table, cuddZddUnion, P, Q); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) + p_top = P->index; + else + p_top = zdd->permZ[P->index]; + if (cuddIsConstant(Q)) + q_top = Q->index; + else + q_top = zdd->permZ[Q->index]; + if (p_top < q_top) { + e = cuddZddUnion(zdd, cuddE(P), Q); + if (e == NULL) return (NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, cuddT(P), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); + } else if (p_top > q_top) { + e = cuddZddUnion(zdd, P, cuddE(Q)); + if (e == NULL) return(NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, Q->index, cuddT(Q), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); + } else { + t = cuddZddUnion(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddUnion(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(table, cuddZddUnion, P, Q, res); + + return(res); + +} /* end of cuddZddUnion */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddIntersect.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddIntersect( + DdManager * zdd, + DdNode * P, + DdNode * Q) +{ + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; + + statLine(zdd); + if (P == empty) + return(empty); + if (Q == empty) + return(empty); + if (P == Q) + return(P); + + /* Check cache. */ + res = cuddCacheLookup2Zdd(table, cuddZddIntersect, P, Q); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) + p_top = P->index; + else + p_top = zdd->permZ[P->index]; + if (cuddIsConstant(Q)) + q_top = Q->index; + else + q_top = zdd->permZ[Q->index]; + if (p_top < q_top) { + res = cuddZddIntersect(zdd, cuddE(P), Q); + if (res == NULL) return(NULL); + } else if (p_top > q_top) { + res = cuddZddIntersect(zdd, P, cuddE(Q)); + if (res == NULL) return(NULL); + } else { + t = cuddZddIntersect(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddIntersect(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(table, cuddZddIntersect, P, Q, res); + + return(res); + +} /* end of cuddZddIntersect */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddDiff.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddDiff( + DdManager * zdd, + DdNode * P, + DdNode * Q) +{ + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; + + statLine(zdd); + if (P == empty) + return(empty); + if (Q == empty) + return(P); + if (P == Q) + return(empty); + + /* Check cache. The cache is shared by Cudd_zddDiffConst(). */ + res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q); + if (res != NULL && res != DD_NON_CONSTANT) + return(res); + + if (cuddIsConstant(P)) + p_top = P->index; + else + p_top = zdd->permZ[P->index]; + if (cuddIsConstant(Q)) + q_top = Q->index; + else + q_top = zdd->permZ[Q->index]; + if (p_top < q_top) { + e = cuddZddDiff(zdd, cuddE(P), Q); + if (e == NULL) return(NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, cuddT(P), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); + } else if (p_top > q_top) { + res = cuddZddDiff(zdd, P, cuddE(Q)); + if (res == NULL) return(NULL); + } else { + t = cuddZddDiff(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddDiff(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(table, cuddZddDiff, P, Q, res); + + return(res); + +} /* end of cuddZddDiff */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddChange.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddZddChangeAux( + DdManager * zdd, + DdNode * P, + DdNode * zvar) +{ + int top_var, level; + DdNode *res, *t, *e; + DdNode *base = DD_ONE(zdd); + DdNode *empty = DD_ZERO(zdd); + + statLine(zdd); + if (P == empty) + return(empty); + if (P == base) + return(zvar); + + /* Check cache. */ + res = cuddCacheLookup2Zdd(zdd, cuddZddChangeAux, P, zvar); + if (res != NULL) + return(res); + + top_var = zdd->permZ[P->index]; + level = zdd->permZ[zvar->index]; + + if (top_var > level) { + res = cuddZddGetNode(zdd, zvar->index, P, DD_ZERO(zdd)); + if (res == NULL) return(NULL); + } else if (top_var == level) { + res = cuddZddGetNode(zdd, zvar->index, cuddE(P), cuddT(P)); + if (res == NULL) return(NULL); + } else { + t = cuddZddChangeAux(zdd, cuddT(P), zvar); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddChangeAux(zdd, cuddE(P), zvar); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(zdd, cuddZddChangeAux, P, zvar, res); + + return(res); + +} /* end of cuddZddChangeAux */ + + +/**Function******************************************************************** + + Synopsis [Computes the positive cofactor of a ZDD w.r.t. a variable.] + + Description [Computes the positive cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is asserted. Returns a pointer to + the result if successful; NULL otherwise. cuddZddSubset1 performs + the same function as Cudd_zddSubset1, but does not restart if + reordering has taken place. Therefore it can be called from within a + recursive procedure.] + + SideEffects [None] + + SeeAlso [cuddZddSubset0 Cudd_zddSubset1] + +******************************************************************************/ +DdNode * +cuddZddSubset1( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *zvar, *r; + DdNode *base, *empty; + + base = DD_ONE(dd); + empty = DD_ZERO(dd); + + zvar = cuddUniqueInterZdd(dd, var, base, empty); + if (zvar == NULL) { + return(NULL); + } else { + cuddRef(zvar); + r = zdd_subset1_aux(dd, P, zvar); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, zvar); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDerefZdd(dd, zvar); + } + + cuddDeref(r); + return(r); + +} /* end of cuddZddSubset1 */ + + +/**Function******************************************************************** + + Synopsis [Computes the negative cofactor of a ZDD w.r.t. a variable.] + + Description [Computes the negative cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is negated. Returns a pointer to + the result if successful; NULL otherwise. cuddZddSubset0 performs + the same function as Cudd_zddSubset0, but does not restart if + reordering has taken place. Therefore it can be called from within a + recursive procedure.] + + SideEffects [None] + + SeeAlso [cuddZddSubset1 Cudd_zddSubset0] + +******************************************************************************/ +DdNode * +cuddZddSubset0( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *zvar, *r; + DdNode *base, *empty; + + base = DD_ONE(dd); + empty = DD_ZERO(dd); + + zvar = cuddUniqueInterZdd(dd, var, base, empty); + if (zvar == NULL) { + return(NULL); + } else { + cuddRef(zvar); + r = zdd_subset0_aux(dd, P, zvar); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, zvar); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDerefZdd(dd, zvar); + } + + cuddDeref(r); + return(r); + +} /* end of cuddZddSubset0 */ + + +/**Function******************************************************************** + + Synopsis [Substitutes a variable with its complement in a ZDD.] + + Description [Substitutes a variable with its complement in a ZDD. + returns a pointer to the result if successful; NULL + otherwise. cuddZddChange performs the same function as + Cudd_zddChange, but does not restart if reordering has taken + place. Therefore it can be called from within a recursive + procedure.] + + SideEffects [None] + + SeeAlso [Cudd_zddChange] + +******************************************************************************/ +DdNode * +cuddZddChange( + DdManager * dd, + DdNode * P, + int var) +{ + DdNode *zvar, *res; + + zvar = cuddUniqueInterZdd(dd, var, DD_ONE(dd), DD_ZERO(dd)); + if (zvar == NULL) return(NULL); + cuddRef(zvar); + + res = cuddZddChangeAux(dd, P, zvar); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd,zvar); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd,zvar); + cuddDeref(res); + return(res); + +} /* end of cuddZddChange */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddSubset1.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +zdd_subset1_aux( + DdManager * zdd, + DdNode * P, + DdNode * zvar) +{ + int top_var, level; + DdNode *res, *t, *e; + DdNode *empty; + + statLine(zdd); + empty = DD_ZERO(zdd); + + /* Check cache. */ + res = cuddCacheLookup2Zdd(zdd, zdd_subset1_aux, P, zvar); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) { + res = empty; + cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res); + return(res); + } + + top_var = zdd->permZ[P->index]; + level = zdd->permZ[zvar->index]; + + if (top_var > level) { + res = empty; + } else if (top_var == level) { + res = cuddT(P); + } else { + t = zdd_subset1_aux(zdd, cuddT(P), zvar); + if (t == NULL) return(NULL); + cuddRef(t); + e = zdd_subset1_aux(zdd, cuddE(P), zvar); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res); + + return(res); + +} /* end of zdd_subset1_aux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddSubset0.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +zdd_subset0_aux( + DdManager * zdd, + DdNode * P, + DdNode * zvar) +{ + int top_var, level; + DdNode *res, *t, *e; + + statLine(zdd); + + /* Check cache. */ + res = cuddCacheLookup2Zdd(zdd, zdd_subset0_aux, P, zvar); + if (res != NULL) + return(res); + + if (cuddIsConstant(P)) { + res = P; + cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res); + return(res); + } + + top_var = zdd->permZ[P->index]; + level = zdd->permZ[zvar->index]; + + if (top_var > level) { + res = P; + } + else if (top_var == level) { + res = cuddE(P); + } + else { + t = zdd_subset0_aux(zdd, cuddT(P), zvar); + if (t == NULL) return(NULL); + cuddRef(t); + e = zdd_subset0_aux(zdd, cuddE(P), zvar); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res); + + return(res); + +} /* end of zdd_subset0_aux */ + + +/**Function******************************************************************** + + Synopsis [Replaces variables with constants if possible (part of + canonical form).] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +zddVarToConst( + DdNode * f, + DdNode ** gp, + DdNode ** hp, + DdNode * base, + DdNode * empty) +{ + DdNode *g = *gp; + DdNode *h = *hp; + + if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + *gp = base; + } + + if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + *hp = empty; + } + +} /* end of zddVarToConst */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddSymm.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddSymm.c new file mode 100644 index 000000000..559d1a2a5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddSymm.c @@ -0,0 +1,1711 @@ +/**CFile*********************************************************************** + + FileName [cuddZddSymm.c] + + PackageName [cudd] + + Synopsis [Functions for symmetry-based ZDD variable reordering.] + + Description [External procedures included in this module: +
                          +
                        • Cudd_zddSymmProfile() +
                        + Internal procedures included in this module: +
                          +
                        • cuddZddSymmCheck() +
                        • cuddZddSymmSifting() +
                        • cuddZddSymmSiftingConv() +
                        + Static procedures included in this module: +
                          +
                        • cuddZddUniqueCompare() +
                        • cuddZddSymmSiftingAux() +
                        • cuddZddSymmSiftingConvAux() +
                        • cuddZddSymmSifting_up() +
                        • cuddZddSymmSifting_down() +
                        • zdd_group_move() +
                        • cuddZddSymmSiftingBackward() +
                        • zdd_group_move_backward() +
                        + ] + + SeeAlso [cuddSymmetry.c] + + Author [Hyong-Kyoon Shin, In-Ho Moon] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define ZDD_MV_OOM (Move *)1 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddSymm.c,v 1.31 2012/02/05 01:07:19 fabio Exp $"; +#endif + +extern int *zdd_entry; + +extern int zddTotalNumberSwapping; + +static DdNode *empty; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int cuddZddSymmSiftingAux (DdManager *table, int x, int x_low, int x_high); +static int cuddZddSymmSiftingConvAux (DdManager *table, int x, int x_low, int x_high); +static Move * cuddZddSymmSifting_up (DdManager *table, int x, int x_low, int initial_size); +static Move * cuddZddSymmSifting_down (DdManager *table, int x, int x_high, int initial_size); +static int cuddZddSymmSiftingBackward (DdManager *table, Move *moves, int size); +static int zdd_group_move (DdManager *table, int x, int y, Move **moves); +static int zdd_group_move_backward (DdManager *table, int x, int y); +static void cuddZddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints statistics on symmetric ZDD variables.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_zddSymmProfile( + DdManager * table, + int lower, + int upper) +{ + int i, x, gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; + + for (i = lower; i < upper; i++) { + if (table->subtableZ[i].next != (unsigned) i) { + x = i; + (void) fprintf(table->out,"Group:"); + do { + (void) fprintf(table->out," %d", table->invpermZ[x]); + TotalSymm++; + gbot = x; + x = table->subtableZ[x].next; + } while (x != i); + TotalSymmGroups++; +#ifdef DD_DEBUG + assert(table->subtableZ[gbot].next == (unsigned) i); +#endif + i = gbot; + (void) fprintf(table->out,"\n"); + } + } + (void) fprintf(table->out,"Total Symmetric = %d\n", TotalSymm); + (void) fprintf(table->out,"Total Groups = %d\n", TotalSymmGroups); + +} /* end of Cudd_zddSymmProfile */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Checks for symmetry of x and y.] + + Description [Checks for symmetry of x and y. Ignores projection + functions, unless they are isolated. Returns 1 in case of + symmetry; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddZddSymmCheck( + DdManager * table, + int x, + int y) +{ + int i; + DdNode *f, *f0, *f1, *f01, *f00, *f11, *f10; + int yindex; + int xsymmy = 1; + int xsymmyp = 1; + int arccount = 0; + int TotalRefCount = 0; + int symm_found; + + empty = table->zero; + + yindex = table->invpermZ[y]; + for (i = table->subtableZ[x].slots - 1; i >= 0; i--) { + f = table->subtableZ[x].nodelist[i]; + while (f != NULL) { + /* Find f1, f0, f11, f10, f01, f00 */ + f1 = cuddT(f); + f0 = cuddE(f); + if ((int) f1->index == yindex) { + f11 = cuddT(f1); + f10 = cuddE(f1); + if (f10 != empty) + arccount++; + } else { + if ((int) f0->index != yindex) { + return(0); /* f bypasses layer y */ + } + f11 = empty; + f10 = f1; + } + if ((int) f0->index == yindex) { + f01 = cuddT(f0); + f00 = cuddE(f0); + if (f00 != empty) + arccount++; + } else { + f01 = empty; + f00 = f0; + } + if (f01 != f10) + xsymmy = 0; + if (f11 != f00) + xsymmyp = 0; + if ((xsymmy == 0) && (xsymmyp == 0)) + return(0); + + f = f->next; + } /* for each element of the collision list */ + } /* for each slot of the subtable */ + + /* Calculate the total reference counts of y + ** whose else arc is not empty. + */ + for (i = table->subtableZ[y].slots - 1; i >= 0; i--) { + f = table->subtableZ[y].nodelist[i]; + while (f != NIL(DdNode)) { + if (cuddE(f) != empty) + TotalRefCount += f->ref; + f = f->next; + } + } + + symm_found = (arccount == TotalRefCount); +#if defined(DD_DEBUG) && defined(DD_VERBOSE) + if (symm_found) { + int xindex = table->invpermZ[x]; + (void) fprintf(table->out, + "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); + } +#endif + + return(symm_found); + +} /* end cuddZddSymmCheck */ + + +/**Function******************************************************************** + + Synopsis [Symmetric sifting algorithm for ZDDs.] + + Description [Symmetric sifting algorithm. + Assumes that no dead nodes are present. +
                          +
                        1. Order all the variables according to the number of entries in + each unique subtable. +
                        2. Sift the variable up and down, remembering each time the total + size of the ZDD heap and grouping variables that are symmetric. +
                        3. Select the best permutation. +
                        4. Repeat 3 and 4 for all variables. +
                        + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddZddSymmSiftingConv] + +******************************************************************************/ +int +cuddZddSymmSifting( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int nvars; + int x; + int result; + int symvars; + int symgroups; + int iteration; +#ifdef DD_STATS + int previousSize; +#endif + + nvars = table->sizeZ; + + /* Find order in which to sift variables. */ + var = NULL; + zdd_entry = ALLOC(int, nvars); + if (zdd_entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingOutOfMem; + } + var = ALLOC(int, nvars); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingOutOfMem; + } + + for (i = 0; i < nvars; i++) { + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; + } + + qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); + + /* Initialize the symmetry of each subtable to itself. */ + for (i = lower; i <= upper; i++) + table->subtableZ[i].next = i; + + iteration = ddMin(table->siftMaxVar, nvars); + for (i = 0; i < iteration; i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + if (x < lower || x > upper) continue; + if (table->subtableZ[x].next == (unsigned) x) { + result = cuddZddSymmSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); +#ifdef DD_VERBOSE + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); +#endif + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } + + FREE(var); + FREE(zdd_entry); + + cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups); + +#ifdef DD_STATS + (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n",symvars); + (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n",symgroups); +#endif + + return(1+symvars); + +cuddZddSymmSiftingOutOfMem: + + if (zdd_entry != NULL) + FREE(zdd_entry); + if (var != NULL) + FREE(var); + + return(0); + +} /* end of cuddZddSymmSifting */ + + +/**Function******************************************************************** + + Synopsis [Symmetric sifting to convergence algorithm for ZDDs.] + + Description [Symmetric sifting to convergence algorithm for ZDDs. + Assumes that no dead nodes are present. +
                          +
                        1. Order all the variables according to the number of entries in + each unique subtable. +
                        2. Sift the variable up and down, remembering each time the total + size of the ZDD heap and grouping variables that are symmetric. +
                        3. Select the best permutation. +
                        4. Repeat 3 and 4 for all variables. +
                        5. Repeat 1-4 until no further improvement. +
                        + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddZddSymmSifting] + +******************************************************************************/ +int +cuddZddSymmSiftingConv( + DdManager * table, + int lower, + int upper) +{ + int i; + int *var; + int nvars; + int initialSize; + int x; + int result; + int symvars; + int symgroups; + int classes; + int iteration; +#ifdef DD_STATS + int previousSize; +#endif + + initialSize = table->keysZ; + + nvars = table->sizeZ; + + /* Find order in which to sift variables. */ + var = NULL; + zdd_entry = ALLOC(int, nvars); + if (zdd_entry == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingConvOutOfMem; + } + var = ALLOC(int, nvars); + if (var == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingConvOutOfMem; + } + + for (i = 0; i < nvars; i++) { + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; + } + + qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); + + /* Initialize the symmetry of each subtable to itself + ** for first pass of converging symmetric sifting. + */ + for (i = lower; i <= upper; i++) + table->subtableZ[i].next = i; + + iteration = ddMin(table->siftMaxVar, table->sizeZ); + for (i = 0; i < iteration; i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; + /* Only sift if not in symmetry group already. */ + if (table->subtableZ[x].next == (unsigned) x) { +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = cuddZddSymmSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingConvOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); +#ifdef DD_VERBOSE + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); +#endif + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } + + /* Sifting now until convergence. */ + while ((unsigned) initialSize > table->keysZ) { + initialSize = table->keysZ; +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + /* Here we consider only one representative for each symmetry class. */ + for (x = lower, classes = 0; x <= upper; x++, classes++) { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + /* Here x is the largest index in a group. + ** Groups consists of adjacent variables. + ** Hence, the next increment of x will move it to a new group. + */ + i = table->invpermZ[x]; + zdd_entry[i] = table->subtableZ[x].keys; + var[classes] = i; + } + + qsort((void *)var,classes,sizeof(int),(DD_QSFP)cuddZddUniqueCompare); + + /* Now sift. */ + iteration = ddMin(table->siftMaxVar, nvars); + for (i = 0; i < iteration; i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (util_cpu_time() - table->startTime > table->timeLimit) { + table->autoDynZ = 0; /* prevent further reordering */ + break; + } + x = table->permZ[var[i]]; + if ((unsigned) x >= table->subtableZ[x].next) { +#ifdef DD_STATS + previousSize = table->keysZ; +#endif + result = cuddZddSymmSiftingConvAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingConvOutOfMem; +#ifdef DD_STATS + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); +#ifdef DD_VERBOSE + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); +#endif + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); +#endif + } + } /* for */ + } + + cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups); + +#ifdef DD_STATS + (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n", + symvars); + (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n", + symgroups); +#endif + + FREE(var); + FREE(zdd_entry); + + return(1+symvars); + +cuddZddSymmSiftingConvOutOfMem: + + if (zdd_entry != NULL) + FREE(zdd_entry); + if (var != NULL) + FREE(var); + + return(0); + +} /* end of cuddZddSymmSiftingConv */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Given x_low <= x <= x_high moves x up and down between the + boundaries.] + + Description [Given x_low <= x <= x_high moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is not part of a symmetry group. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSymmSiftingAux( + DdManager * table, + int x, + int x_low, + int x_high) +{ + Move *move; + Move *move_up; /* list of up move */ + Move *move_down; /* list of down move */ + int initial_size; + int result; + int i; + int topbot; /* index to either top or bottom of symmetry group */ + int init_group_size, final_group_size; + + initial_size = table->keysZ; + + move_down = NULL; + move_up = NULL; + + /* Look for consecutive symmetries above x. */ + for (i = x; i > x_low; i--) { + if (!cuddZddSymmCheck(table, i - 1, i)) + break; + /* find top of i-1's symmetry */ + topbot = table->subtableZ[i - 1].next; + table->subtableZ[i - 1].next = i; + table->subtableZ[x].next = topbot; + /* x is bottom of group so its symmetry is top of i-1's + group */ + i = topbot + 1; /* add 1 for i--, new i is top of symm group */ + } + /* Look for consecutive symmetries below x. */ + for (i = x; i < x_high; i++) { + if (!cuddZddSymmCheck(table, i, i + 1)) + break; + /* find bottom of i+1's symm group */ + topbot = i + 1; + while ((unsigned) topbot < table->subtableZ[topbot].next) + topbot = table->subtableZ[topbot].next; + + table->subtableZ[topbot].next = table->subtableZ[i].next; + table->subtableZ[i].next = i + 1; + i = topbot - 1; /* add 1 for i++, + new i is bottom of symm group */ + } + + /* Now x maybe in the middle of a symmetry group. */ + if (x == x_low) { /* Sift down */ + /* Find bottom of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + + i = table->subtableZ[x].next; + init_group_size = x - i + 1; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) + x = move_down->y; + else + x = table->subtableZ[x].next; + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, + move_down, initial_size); + } + else { + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; + } + else if (x == x_high) { /* Sift up */ + /* Find top of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_low, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) + x = move_up->x; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; + } + else if ((x - x_low) > (x_high - x)) { /* must go down first: + shorter */ + /* Find bottom of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_down != NULL) { + x = move_down->y; + } + else { + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; + } + else { /* moving up first:shorter */ + /* Find top of x's symmetry group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_high, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + init_group_size = x - i + 1; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) { + x = move_down->y; + } + else { + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetries detected, + go back to best position */ + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + else { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; + } + + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + + return(1); + +cuddZddSymmSiftingAuxOutOfMem: + if (move_down != ZDD_MV_OOM) { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + } + if (move_up != ZDD_MV_OOM) { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + } + + return(0); + +} /* end of cuddZddSymmSiftingAux */ + + +/**Function******************************************************************** + + Synopsis [Given x_low <= x <= x_high moves x up and down between the + boundaries.] + + Description [Given x_low <= x <= x_high moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is either an isolated variable, or it is the bottom of + a symmetry group. All symmetries may not have been found, because of + exceeded growth limit. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSymmSiftingConvAux( + DdManager * table, + int x, + int x_low, + int x_high) +{ + Move *move; + Move *move_up; /* list of up move */ + Move *move_down; /* list of down move */ + int initial_size; + int result; + int i; + int init_group_size, final_group_size; + + initial_size = table->keysZ; + + move_down = NULL; + move_up = NULL; + + if (x == x_low) { /* Sift down */ + i = table->subtableZ[x].next; + init_group_size = x - i + 1; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) + x = move_down->y; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetries detected, + go back to best position */ + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + else { + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; + } + else if (x == x_high) { /* Sift up */ + /* Find top of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_low, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) + x = move_up->x; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; + } + else if ((x - x_low) > (x_high - x)) { /* must go down first: + shorter */ + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_down != NULL) { + x = move_down->y; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; + + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; + } + else { /* moving up first:shorter */ + /* Find top of x's symmetry group */ + x = table->subtableZ[x].next; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_high, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + init_group_size = x - i + 1; + + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) { + x = move_down->y; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetries detected, + go back to best position */ + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + else { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + } + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ + } + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; + } + + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + + return(1); + +cuddZddSymmSiftingConvAuxOutOfMem: + if (move_down != ZDD_MV_OOM) { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + } + if (move_up != ZDD_MV_OOM) { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + } + + return(0); + +} /* end of cuddZddSymmSiftingConvAux */ + + +/**Function******************************************************************** + + Synopsis [Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much.] + + Description [Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much. Assumes that x is the top + of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; ZDD_MV_OOM if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddSymmSifting_up( + DdManager * table, + int x, + int x_low, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + int i, gytop; + + moves = NULL; + y = cuddZddNextLow(table, x); + while (y >= x_low) { + gytop = table->subtableZ[y].next; + if (cuddZddSymmCheck(table, y, x)) { + /* Symmetry found, attach symm groups */ + table->subtableZ[y].next = x; + i = table->subtableZ[x].next; + while (table->subtableZ[i].next != (unsigned) x) + i = table->subtableZ[i].next; + table->subtableZ[i].next = gytop; + } + else if ((table->subtableZ[x].next == (unsigned) x) && + (table->subtableZ[y].next == (unsigned) y)) { + /* x and y have self symmetry */ + size = cuddZddSwapInPlace(table, y, x); + if (size == 0) + goto cuddZddSymmSifting_upOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSymmSifting_upOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + else { /* Group move */ + size = zdd_group_move(table, y, x, &moves); + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + x = gytop; + y = cuddZddNextLow(table, x); + } + + return(moves); + +cuddZddSymmSifting_upOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(ZDD_MV_OOM); + +} /* end of cuddZddSymmSifting_up */ + + +/**Function******************************************************************** + + Synopsis [Moves x down until either it reaches the bound (x_high) or + the size of the ZDD heap increases too much.] + + Description [Moves x down until either it reaches the bound (x_high) + or the size of the ZDD heap increases too much. Assumes that x is the + bottom of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; ZDD_MV_OOM if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +cuddZddSymmSifting_down( + DdManager * table, + int x, + int x_high, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + int i, gxtop, gybot; + + moves = NULL; + y = cuddZddNextHigh(table, x); + while (y <= x_high) { + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + if (cuddZddSymmCheck(table, x, y)) { + /* Symmetry found, attach symm groups */ + gxtop = table->subtableZ[x].next; + table->subtableZ[x].next = y; + i = table->subtableZ[y].next; + while (table->subtableZ[i].next != (unsigned) y) + i = table->subtableZ[i].next; + table->subtableZ[i].next = gxtop; + } + else if ((table->subtableZ[x].next == (unsigned) x) && + (table->subtableZ[y].next == (unsigned) y)) { + /* x and y have self symmetry */ + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddSymmSifting_downOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSymmSifting_downOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + x = y; + y = cuddZddNextHigh(table, x); + } + else { /* Group move */ + size = zdd_group_move(table, x, y, &moves); + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + x = gybot; + y = cuddZddNextHigh(table, x); + } + + return(moves); + +cuddZddSymmSifting_downOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(ZDD_MV_OOM); + +} /* end of cuddZddSymmSifting_down */ + + +/**Function******************************************************************** + + Synopsis [Given a set of moves, returns the ZDD heap to the position + giving the minimum size.] + + Description [Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddZddSymmSiftingBackward( + DdManager * table, + Move * moves, + int size) +{ + int i; + int i_best; + Move *move; + int res; + + i_best = -1; + for (move = moves, i = 0; move != NULL; move = move->next, i++) { + if (move->size < size) { + i_best = i; + size = move->size; + } + } + + for (move = moves, i = 0; move != NULL; move = move->next, i++) { + if (i == i_best) break; + if ((table->subtableZ[move->x].next == move->x) && + (table->subtableZ[move->y].next == move->y)) { + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) return(0); + } + else { /* Group move necessary */ + res = zdd_group_move_backward(table, move->x, move->y); + } + if (i_best == -1 && res == size) + break; + } + + return(1); + +} /* end of cuddZddSymmSiftingBackward */ + + +/**Function******************************************************************** + + Synopsis [Swaps two groups.] + + Description [Swaps two groups. x is assumed to be the bottom variable + of the first group. y is assumed to be the top variable of the second + group. Updates the list of moves. Returns the number of keys in the + table if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zdd_group_move( + DdManager * table, + int x, + int y, + Move ** moves) +{ + Move *move; + int size; + int i, temp, gxtop, gxbot, gybot, yprev; + int swapx, swapy; + +#ifdef DD_DEBUG + assert(x < y); /* we assume that x < y */ +#endif + /* Find top and bottom for the two groups. */ + gxtop = table->subtableZ[x].next; + gxbot = x; + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + yprev = gybot; + + while (x <= y) { + while (y > gxtop) { + /* Set correct symmetries. */ + temp = table->subtableZ[x].next; + if (temp == x) + temp = y; + i = gxtop; + for (;;) { + if (table->subtableZ[i].next == (unsigned) x) { + table->subtableZ[i].next = y; + break; + } else { + i = table->subtableZ[i].next; + } + } + if (table->subtableZ[y].next != (unsigned) y) { + table->subtableZ[x].next = table->subtableZ[y].next; + } else { + table->subtableZ[x].next = x; + } + + if (yprev != y) { + table->subtableZ[yprev].next = x; + } else { + yprev = x; + } + table->subtableZ[y].next = temp; + + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto zdd_group_moveOutOfMem; + swapx = x; + swapy = y; + y = x; + x--; + } /* while y > gxtop */ + + /* Trying to find the next y. */ + if (table->subtableZ[y].next <= (unsigned) y) { + gybot = y; + } else { + y = table->subtableZ[y].next; + } + + yprev = gxtop; + gxtop++; + gxbot++; + x = gxbot; + } /* while x <= y, end of group movement */ + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zdd_group_moveOutOfMem; + move->x = swapx; + move->y = swapy; + move->size = table->keysZ; + move->next = *moves; + *moves = move; + + return(table->keysZ); + +zdd_group_moveOutOfMem: + while (*moves != NULL) { + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; + } + return(0); + +} /* end of zdd_group_move */ + + +/**Function******************************************************************** + + Synopsis [Undoes the swap of two groups.] + + Description [Undoes the swap of two groups. x is assumed to be the + bottom variable of the first group. y is assumed to be the top + variable of the second group. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zdd_group_move_backward( + DdManager * table, + int x, + int y) +{ + int size; + int i, temp, gxtop, gxbot, gybot, yprev; + +#ifdef DD_DEBUG + assert(x < y); /* we assume that x < y */ +#endif + /* Find top and bottom of the two groups. */ + gxtop = table->subtableZ[x].next; + gxbot = x; + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + yprev = gybot; + + while (x <= y) { + while (y > gxtop) { + /* Set correct symmetries. */ + temp = table->subtableZ[x].next; + if (temp == x) + temp = y; + i = gxtop; + for (;;) { + if (table->subtableZ[i].next == (unsigned) x) { + table->subtableZ[i].next = y; + break; + } else { + i = table->subtableZ[i].next; + } + } + if (table->subtableZ[y].next != (unsigned) y) { + table->subtableZ[x].next = table->subtableZ[y].next; + } else { + table->subtableZ[x].next = x; + } + + if (yprev != y) { + table->subtableZ[yprev].next = x; + } else { + yprev = x; + } + table->subtableZ[y].next = temp; + + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + return(0); + y = x; + x--; + } /* while y > gxtop */ + + /* Trying to find the next y. */ + if (table->subtableZ[y].next <= (unsigned) y) { + gybot = y; + } else { + y = table->subtableZ[y].next; + } + + yprev = gxtop; + gxtop++; + gxbot++; + x = gxbot; + } /* while x <= y, end of group movement backward */ + + return(size); + +} /* end of zdd_group_move_backward */ + + +/**Function******************************************************************** + + Synopsis [Counts numbers of symmetric variables and symmetry + groups.] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static void +cuddZddSymmSummary( + DdManager * table, + int lower, + int upper, + int * symvars, + int * symgroups) +{ + int i,x,gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; + + for (i = lower; i <= upper; i++) { + if (table->subtableZ[i].next != (unsigned) i) { + TotalSymmGroups++; + x = i; + do { + TotalSymm++; + gbot = x; + x = table->subtableZ[x].next; + } while (x != i); +#ifdef DD_DEBUG + assert(table->subtableZ[gbot].next == (unsigned) i); +#endif + i = gbot; + } + } + *symvars = TotalSymm; + *symgroups = TotalSymmGroups; + + return; + +} /* end of cuddZddSymmSummary */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddUtil.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddUtil.c new file mode 100644 index 000000000..aecb93ee4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/cuddZddUtil.c @@ -0,0 +1,1205 @@ +/**CFile*********************************************************************** + + FileName [cuddZddUtil.c] + + PackageName [cudd] + + Synopsis [Utility functions for ZDDs.] + + Description [External procedures included in this module: +
                          +
                        • Cudd_zddPrintMinterm() +
                        • Cudd_zddPrintCover() +
                        • Cudd_zddPrintDebug() +
                        • Cudd_zddFirstPath() +
                        • Cudd_zddNextPath() +
                        • Cudd_zddCoverPathToString() +
                        • Cudd_zddSupport() +
                        • Cudd_zddDumpDot() +
                        + Internal procedures included in this module: +
                          +
                        • cuddZddP() +
                        + Static procedures included in this module: +
                          +
                        • zp2() +
                        • zdd_print_minterm_aux() +
                        • zddPrintCoverAux() +
                        • zddSupportStep() +
                        • zddClearFlag() +
                        + ] + + SeeAlso [] + + Author [Hyong-Kyoon Shin, In-Ho Moon, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.29 2012/02/05 01:07:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int zp2 (DdManager *zdd, DdNode *f, st_table *t); +static void zdd_print_minterm_aux (DdManager *zdd, DdNode *node, int level, int *list); +static void zddPrintCoverAux (DdManager *zdd, DdNode *node, int level, int *list); +static void zddSupportStep(DdNode * f, int * support); +static void zddClearFlag(DdNode * f); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints a disjoint sum of product form for a ZDD.] + + Description [Prints a disjoint sum of product form for a ZDD. Returns 1 + if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddPrintDebug Cudd_zddPrintCover] + +******************************************************************************/ +int +Cudd_zddPrintMinterm( + DdManager * zdd, + DdNode * node) +{ + int i, size; + int *list; + + size = (int)zdd->sizeZ; + list = ALLOC(int, size); + if (list == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ + zdd_print_minterm_aux(zdd, node, 0, list); + FREE(list); + return(1); + +} /* end of Cudd_zddPrintMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints a sum of products from a ZDD representing a cover.] + + Description [Prints a sum of products from a ZDD representing a cover. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddPrintMinterm] + +******************************************************************************/ +int +Cudd_zddPrintCover( + DdManager * zdd, + DdNode * node) +{ + int i, size; + int *list; + + size = (int)zdd->sizeZ; + if (size % 2 != 0) return(0); /* number of variables should be even */ + list = ALLOC(int, size); + if (list == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ + zddPrintCoverAux(zdd, node, 0, list); + FREE(list); + return(1); + +} /* end of Cudd_zddPrintCover */ + + +/**Function******************************************************************** + + Synopsis [Prints to the standard output a ZDD and its statistics.] + + Description [Prints to the standard output a DD and its statistics. + The statistics include the number of nodes and the number of minterms. + (The number of minterms is also the number of combinations in the set.) + The statistics are printed if pr > 0. Specifically: +
                          +
                        • pr = 0 : prints nothing +
                        • pr = 1 : prints counts of nodes and minterms +
                        • pr = 2 : prints counts + disjoint sum of products +
                        • pr = 3 : prints counts + list of nodes +
                        • pr > 3 : prints counts + disjoint sum of products + list of nodes +
                        + Returns 1 if successful; 0 otherwise. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_zddPrintDebug( + DdManager * zdd, + DdNode * f, + int n, + int pr) +{ + DdNode *empty = DD_ZERO(zdd); + int nodes; + double minterms; + int retval = 1; + + if (f == empty && pr > 0) { + (void) fprintf(zdd->out,": is the empty ZDD\n"); + (void) fflush(zdd->out); + return(1); + } + + if (pr > 0) { + nodes = Cudd_zddDagSize(f); + if (nodes == CUDD_OUT_OF_MEM) retval = 0; + minterms = Cudd_zddCountMinterm(zdd, f, n); + if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; + (void) fprintf(zdd->out,": %d nodes %g minterms\n", + nodes, minterms); + if (pr > 2) + if (!cuddZddP(zdd, f)) retval = 0; + if (pr == 2 || pr > 3) { + if (!Cudd_zddPrintMinterm(zdd, f)) retval = 0; + (void) fprintf(zdd->out,"\n"); + } + (void) fflush(zdd->out); + } + return(retval); + +} /* end of Cudd_zddPrintDebug */ + + + +/**Function******************************************************************** + + Synopsis [Finds the first path of a ZDD.] + + Description [Defines an iterator on the paths of a ZDD + and finds its first path. Returns a generator that contains the + information necessary to continue the enumeration if successful; NULL + otherwise.

                        + A path is represented as an array of literals, which are integers in + {0, 1, 2}; 0 represents an else arc out of a node, 1 represents a then arc + out of a node, and 2 stands for the absence of a node. + The size of the array equals the number of variables in the manager at + the time Cudd_zddFirstCube is called.

                        + The paths that end in the empty terminal are not enumerated.] + + SideEffects [The first path is returned as a side effect.] + + SeeAlso [Cudd_zddForeachPath Cudd_zddNextPath Cudd_GenFree + Cudd_IsGenEmpty] + +******************************************************************************/ +DdGen * +Cudd_zddFirstPath( + DdManager * zdd, + DdNode * f, + int ** path) +{ + DdGen *gen; + DdNode *top, *next, *prev; + int i; + int nvars; + + /* Sanity Check. */ + if (zdd == NULL || f == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ALLOC(DdGen,1); + if (gen == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = zdd; + gen->type = CUDD_GEN_ZDD_PATHS; + gen->status = CUDD_GEN_EMPTY; + gen->gen.cubes.cube = NULL; + gen->gen.cubes.value = DD_ZERO_VAL; + gen->stack.sp = 0; + gen->stack.stack = NULL; + gen->node = NULL; + + nvars = zdd->sizeZ; + gen->gen.cubes.cube = ALLOC(int,nvars); + if (gen->gen.cubes.cube == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + FREE(gen); + return(NULL); + } + for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; + + /* The maximum stack depth is one plus the number of variables. + ** because a path may have nodes at all levels, including the + ** constant level. + */ + gen->stack.stack = ALLOC(DdNodePtr, nvars+1); + if (gen->stack.stack == NULL) { + zdd->errorCode = CUDD_MEMORY_OUT; + FREE(gen->gen.cubes.cube); + FREE(gen); + return(NULL); + } + for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; + + /* Find the first path of the ZDD. */ + gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; + + while (1) { + top = gen->stack.stack[gen->stack.sp-1]; + if (!cuddIsConstant(Cudd_Regular(top))) { + /* Take the else branch first. */ + gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; + next = cuddE(Cudd_Regular(top)); + gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; + } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { + /* Backtrack. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); + next = cuddT(prev); + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[prev->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[prev->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(Cudd_Regular(top)); + goto done; + } + } + +done: + *path = gen->gen.cubes.cube; + return(gen); + +} /* end of Cudd_zddFirstPath */ + + +/**Function******************************************************************** + + Synopsis [Generates the next path of a ZDD.] + + Description [Generates the next path of a ZDD onset, + using generator gen. Returns 0 if the enumeration is completed; 1 + otherwise.] + + SideEffects [The path is returned as a side effect. The + generator is modified.] + + SeeAlso [Cudd_zddForeachPath Cudd_zddFirstPath Cudd_GenFree + Cudd_IsGenEmpty] + +******************************************************************************/ +int +Cudd_zddNextPath( + DdGen * gen, + int ** path) +{ + DdNode *top, *next, *prev; + DdManager *zdd = gen->manager; + + /* Backtrack from previously reached terminal node. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + top = gen->stack.stack[gen->stack.sp-1]; + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); + next = cuddT(prev); + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[prev->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[prev->index] = 2; + gen->stack.sp--; + } + + while (1) { + top = gen->stack.stack[gen->stack.sp-1]; + if (!cuddIsConstant(Cudd_Regular(top))) { + /* Take the else branch first. */ + gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; + next = cuddE(Cudd_Regular(top)); + gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; + } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { + /* Backtrack. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); + next = cuddT(prev); + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[prev->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[prev->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(Cudd_Regular(top)); + goto done; + } + } + +done: + if (gen->status == CUDD_GEN_EMPTY) return(0); + *path = gen->gen.cubes.cube; + return(1); + +} /* end of Cudd_zddNextPath */ + + +/**Function******************************************************************** + + Synopsis [Converts a path of a ZDD representing a cover to a string.] + + Description [Converts a path of a ZDD representing a cover to a + string. The string represents an implicant of the cover. The path + is typically produced by Cudd_zddForeachPath. Returns a pointer to + the string if successful; NULL otherwise. If the str input is NULL, + it allocates a new string. The string passed to this function must + have enough room for all variables and for the terminator.] + + SideEffects [None] + + SeeAlso [Cudd_zddForeachPath] + +******************************************************************************/ +char * +Cudd_zddCoverPathToString( + DdManager *zdd /* DD manager */, + int *path /* path of ZDD representing a cover */, + char *str /* pointer to string to use if != NULL */ + ) +{ + int nvars = zdd->sizeZ; + int i; + char *res; + + if (nvars & 1) return(NULL); + nvars >>= 1; + if (str == NULL) { + res = ALLOC(char, nvars+1); + if (res == NULL) return(NULL); + } else { + res = str; + } + for (i = 0; i < nvars; i++) { + int v = (path[2*i] << 2) | path[2*i+1]; + switch (v) { + case 0: + case 2: + case 8: + case 10: + res[i] = '-'; + break; + case 1: + case 9: + res[i] = '0'; + break; + case 4: + case 6: + res[i] = '1'; + break; + default: + res[i] = '?'; + } + } + res[nvars] = 0; + + return(res); + +} /* end of Cudd_zddCoverPathToString */ + + +/**Function******************************************************************** + + Synopsis [Finds the variables on which a ZDD depends.] + + Description [Finds the variables on which a ZDD depends. + Returns a BDD consisting of the product of the variables if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Support] + +******************************************************************************/ +DdNode * +Cudd_zddSupport( + DdManager * dd /* manager */, + DdNode * f /* ZDD whose support is sought */) +{ + int *support; + DdNode *res, *tmp, *var; + int i,j; + int size; + + /* Allocate and initialize support array for ddSupportStep. */ + size = ddMax(dd->size, dd->sizeZ); + support = ALLOC(int,size); + if (support == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + support[i] = 0; + } + + /* Compute support and clean up markers. */ + zddSupportStep(Cudd_Regular(f),support); + zddClearFlag(Cudd_Regular(f)); + + /* Transform support from array to cube. */ + do { + dd->reordered = 0; + res = DD_ONE(dd); + cuddRef(res); + for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ + i = (j >= dd->size) ? j : dd->invperm[j]; + if (support[i] == 1) { + /* The following call to cuddUniqueInter is guaranteed + ** not to trigger reordering because the node we look up + ** already exists. */ + var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + cuddRef(var); + tmp = cuddBddAndRecur(dd,res,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + res = NULL; + break; + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + res = tmp; + } + } + } while (dd->reordered == 1); + + FREE(support); + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_zddSupport */ + + +/**Function******************************************************************** + + Synopsis [Writes a dot file representing the argument ZDDs.] + + Description [Writes a file representing the argument ZDDs in a format + suitable for the graph drawing program dot. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, + file system full). + Cudd_zddDumpDot does not close the file: This is the caller + responsibility. Cudd_zddDumpDot uses a minimal unique subset of the + hexadecimal address of a node as name for it. + If the argument inames is non-null, it is assumed to hold the pointers + to the names of the inputs. Similarly for onames. + Cudd_zddDumpDot uses the following convention to draw arcs: +

                          +
                        • solid line: THEN arcs; +
                        • dashed line: ELSE arcs. +
                        + The dot options are chosen so that the drawing fits on a letter-size + sheet. + ] + + SideEffects [None] + + SeeAlso [Cudd_DumpDot Cudd_zddPrintDebug] + +******************************************************************************/ +int +Cudd_zddDumpDot( + DdManager * dd /* manager */, + int n /* number of output nodes to be dumped */, + DdNode ** f /* array of output nodes to be dumped */, + char ** inames /* array of input names (or NULL) */, + char ** onames /* array of output names (or NULL) */, + FILE * fp /* pointer to the dump file */) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->sizeZ; + st_table *visited = NULL; + st_generator *gen; + int retval; + int i, j; + int slots; + DdNodePtr *nodelist; + long refAddr, diff, mask; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int,nvars); + if (sorted == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; + } + for (i = 0; i < nvars; i++) sorted[i] = 0; + + /* Take the union of the supports of each output function. */ + for (i = 0; i < n; i++) { + support = Cudd_zddSupport(dd,f[i]); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); + } + support = NULL; /* so that we do not try to free it in case of failure */ + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + if (visited == NULL) goto failure; + + /* Collect all the nodes of this DD in the symbol table. */ + for (i = 0; i < n; i++) { + retval = cuddCollectNodes(f[i],visited); + if (retval == 0) goto failure; + } + + /* Find how many most significant hex digits are identical + ** in the addresses of all the nodes. Build a mask based + ** on this knowledge, so that digits that carry no information + ** will not be printed. This is done in two steps. + ** 1. We scan the symbol table to find the bits that differ + ** in at least 2 addresses. + ** 2. We choose one of the possible masks. There are 8 possible + ** masks for 32-bit integer, and 16 possible masks for 64-bit + ** integers. + */ + + /* Find the bits that are different. */ + refAddr = (long) f[0]; + diff = 0; + gen = st_init_gen(visited); + while (st_gen(gen, &scan, NULL)) { + diff |= refAddr ^ (long) scan; + } + st_free_gen(gen); + + /* Choose the mask. */ + for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; + } + + /* Write the header and the global attributes. */ + retval = fprintf(fp,"digraph \"ZDD\" {\n"); + if (retval == EOF) return(0); + retval = fprintf(fp, + "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); + if (retval == EOF) return(0); + + /* Write the input name subgraph by scanning the support array. */ + retval = fprintf(fp,"{ node [shape = plaintext];\n"); + if (retval == EOF) goto failure; + retval = fprintf(fp," edge [style = invis];\n"); + if (retval == EOF) goto failure; + /* We use a name ("CONST NODES") with an embedded blank, because + ** it is unlikely to appear as an input name. + */ + retval = fprintf(fp," \"CONST NODES\" [style = invis];\n"); + if (retval == EOF) goto failure; + for (i = 0; i < nvars; i++) { + if (sorted[dd->invpermZ[i]]) { + if (inames == NULL) { + retval = fprintf(fp,"\" %d \" -> ", dd->invpermZ[i]); + } else { + retval = fprintf(fp,"\" %s \" -> ", inames[dd->invpermZ[i]]); + } + if (retval == EOF) goto failure; + } + } + retval = fprintf(fp,"\"CONST NODES\"; \n}\n"); + if (retval == EOF) goto failure; + + /* Write the output node subgraph. */ + retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); + if (retval == EOF) goto failure; + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + if (i == n - 1) { + retval = fprintf(fp,"; }\n"); + } else { + retval = fprintf(fp," -> "); + } + if (retval == EOF) goto failure; + } + + /* Write rank info: All nodes with the same index have the same rank. */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invpermZ[i]]) { + retval = fprintf(fp,"{ rank = same; "); + if (retval == EOF) goto failure; + if (inames == NULL) { + retval = fprintf(fp,"\" %d \";\n", dd->invpermZ[i]); + } else { + retval = fprintf(fp,"\" %s \";\n", inames[dd->invpermZ[i]]); + } + if (retval == EOF) goto failure; + nodelist = dd->subtableZ[i].nodelist; + slots = dd->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", (void *) + ((mask & (ptrint) scan) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; + } + } + + /* All constants have the same rank. */ + retval = fprintf(fp, + "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); + if (retval == EOF) goto failure; + nodelist = dd->constants.nodelist; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", (void *) + ((mask & (ptrint) scan) / sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + retval = fprintf(fp,"}\n}\n"); + if (retval == EOF) goto failure; + + /* Write edge info. */ + /* Edges from the output nodes. */ + for (i = 0; i < n; i++) { + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp," -> \"%p\" [style = solid];\n", + (void *) ((mask & (ptrint) f[i]) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + + /* Edges from internal nodes. */ + for (i = 0; i < nvars; i++) { + if (sorted[dd->invpermZ[i]]) { + nodelist = dd->subtableZ[i].nodelist; + slots = dd->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp, + "\"%p\" -> \"%p\";\n", + (void *) ((mask & (ptrint) scan) / sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddT(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + retval = fprintf(fp, + "\"%p\" -> \"%p\" [style = dashed];\n", + (void *) ((mask & (ptrint) scan) + / sizeof(DdNode)), + (void *) ((mask & (ptrint) + cuddE(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + } + } + + /* Write constant labels. */ + nodelist = dd->constants.nodelist; + slots = dd->constants.slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + cuddV(scan)); + if (retval == EOF) goto failure; + } + scan = scan->next; + } + } + + /* Write trailer and return. */ + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; + + st_free_table(visited); + FREE(sorted); + return(1); + +failure: + if (sorted != NULL) FREE(sorted); + if (visited != NULL) st_free_table(visited); + return(0); + +} /* end of Cudd_zddDumpBlif */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints a ZDD to the standard output. One line per node is + printed.] + + Description [Prints a ZDD to the standard output. One line per node is + printed. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_zddPrintDebug] + +******************************************************************************/ +int +cuddZddP( + DdManager * zdd, + DdNode * f) +{ + int retval; + st_table *table = st_init_table(st_ptrcmp, st_ptrhash); + + if (table == NULL) return(0); + + retval = zp2(zdd, f, table); + st_free_table(table); + (void) fputc('\n', zdd->out); + return(retval); + +} /* end of cuddZddP */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of cuddZddP.] + + Description [Performs the recursive step of cuddZddP. Returns 1 in + case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +zp2( + DdManager * zdd, + DdNode * f, + st_table * t) +{ + DdNode *n; + int T, E; + DdNode *base = DD_ONE(zdd); + + if (f == NULL) + return(0); + + if (Cudd_IsConstant(f)) { + (void)fprintf(zdd->out, "ID = %d\n", (f == base)); + return(1); + } + if (st_is_member(t, (char *)f) == 1) + return(1); + + if (st_insert(t, (char *) f, NULL) == ST_OUT_OF_MEM) + return(0); + +#if SIZEOF_VOID_P == 8 + (void) fprintf(zdd->out, "ID = 0x%lx\tindex = %u\tr = %u\t", + (ptruint)f / (ptruint) sizeof(DdNode), f->index, f->ref); +#else + (void) fprintf(zdd->out, "ID = 0x%x\tindex = %hu\tr = %hu\t", + (ptruint)f / (ptruint) sizeof(DdNode), f->index, f->ref); +#endif + + n = cuddT(f); + if (Cudd_IsConstant(n)) { + (void) fprintf(zdd->out, "T = %d\t\t", (n == base)); + T = 1; + } else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(zdd->out, "T = 0x%lx\t", (ptruint) n / + (ptruint) sizeof(DdNode)); +#else + (void) fprintf(zdd->out, "T = 0x%x\t", (ptruint) n / + (ptruint) sizeof(DdNode)); +#endif + T = 0; + } + + n = cuddE(f); + if (Cudd_IsConstant(n)) { + (void) fprintf(zdd->out, "E = %d\n", (n == base)); + E = 1; + } else { +#if SIZEOF_VOID_P == 8 + (void) fprintf(zdd->out, "E = 0x%lx\n", (ptruint) n / + (ptruint) sizeof(DdNode)); +#else + (void) fprintf(zdd->out, "E = 0x%x\n", (ptruint) n / + (ptruint) sizeof(DdNode)); +#endif + E = 0; + } + + if (E == 0) + if (zp2(zdd, cuddE(f), t) == 0) return(0); + if (T == 0) + if (zp2(zdd, cuddT(f), t) == 0) return(0); + return(1); + +} /* end of zp2 */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddPrintMinterm.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +zdd_print_minterm_aux( + DdManager * zdd /* manager */, + DdNode * node /* current node */, + int level /* depth in the recursion */, + int * list /* current recursion path */) +{ + DdNode *Nv, *Nnv; + int i, v; + DdNode *base = DD_ONE(zdd); + + if (Cudd_IsConstant(node)) { + if (node == base) { + /* Check for missing variable. */ + if (level != zdd->sizeZ) { + list[zdd->invpermZ[level]] = 0; + zdd_print_minterm_aux(zdd, node, level + 1, list); + return; + } + /* Terminal case: Print one cube based on the current recursion + ** path. + */ + for (i = 0; i < zdd->sizeZ; i++) { + v = list[i]; + if (v == 0) + (void) fprintf(zdd->out,"0"); + else if (v == 1) + (void) fprintf(zdd->out,"1"); + else if (v == 3) + (void) fprintf(zdd->out,"@"); /* should never happen */ + else + (void) fprintf(zdd->out,"-"); + } + (void) fprintf(zdd->out," 1\n"); + } + } else { + /* Check for missing variable. */ + if (level != cuddIZ(zdd,node->index)) { + list[zdd->invpermZ[level]] = 0; + zdd_print_minterm_aux(zdd, node, level + 1, list); + return; + } + + Nnv = cuddE(node); + Nv = cuddT(node); + if (Nv == Nnv) { + list[node->index] = 2; + zdd_print_minterm_aux(zdd, Nnv, level + 1, list); + return; + } + + list[node->index] = 1; + zdd_print_minterm_aux(zdd, Nv, level + 1, list); + list[node->index] = 0; + zdd_print_minterm_aux(zdd, Nnv, level + 1, list); + } + return; + +} /* end of zdd_print_minterm_aux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddPrintCover.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +zddPrintCoverAux( + DdManager * zdd /* manager */, + DdNode * node /* current node */, + int level /* depth in the recursion */, + int * list /* current recursion path */) +{ + DdNode *Nv, *Nnv; + int i, v; + DdNode *base = DD_ONE(zdd); + + if (Cudd_IsConstant(node)) { + if (node == base) { + /* Check for missing variable. */ + if (level != zdd->sizeZ) { + list[zdd->invpermZ[level]] = 0; + zddPrintCoverAux(zdd, node, level + 1, list); + return; + } + /* Terminal case: Print one cube based on the current recursion + ** path. + */ + for (i = 0; i < zdd->sizeZ; i += 2) { + v = list[i] * 4 + list[i+1]; + if (v == 0) + (void) putc('-',zdd->out); + else if (v == 4) + (void) putc('1',zdd->out); + else if (v == 1) + (void) putc('0',zdd->out); + else + (void) putc('@',zdd->out); /* should never happen */ + } + (void) fprintf(zdd->out," 1\n"); + } + } else { + /* Check for missing variable. */ + if (level != cuddIZ(zdd,node->index)) { + list[zdd->invpermZ[level]] = 0; + zddPrintCoverAux(zdd, node, level + 1, list); + return; + } + + Nnv = cuddE(node); + Nv = cuddT(node); + if (Nv == Nnv) { + list[node->index] = 2; + zddPrintCoverAux(zdd, Nnv, level + 1, list); + return; + } + + list[node->index] = 1; + zddPrintCoverAux(zdd, Nv, level + 1, list); + list[node->index] = 0; + zddPrintCoverAux(zdd, Nnv, level + 1, list); + } + return; + +} /* end of zddPrintCoverAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_zddSupport.] + + Description [Performs the recursive step of Cudd_zddSupport. Performs a + DFS from f. The support is accumulated in supp as a side effect. Uses + the LSB of the then pointer as visited flag.] + + SideEffects [None] + + SeeAlso [zddClearFlag] + +******************************************************************************/ +static void +zddSupportStep( + DdNode * f, + int * support) +{ + if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) { + return; + } + + support[f->index] = 1; + zddSupportStep(cuddT(f),support); + zddSupportStep(Cudd_Regular(cuddE(f)),support); + /* Mark as visited. */ + f->next = Cudd_Not(f->next); + return; + +} /* end of zddSupportStep */ + + +/**Function******************************************************************** + + Synopsis [Performs a DFS from f, clearing the LSB of the next + pointers.] + + Description [] + + SideEffects [None] + + SeeAlso [zddSupportStep] + +******************************************************************************/ +static void +zddClearFlag( + DdNode * f) +{ + if (!Cudd_IsComplement(f->next)) { + return; + } + /* Clear visited flag. */ + f->next = Cudd_Regular(f->next); + if (cuddIsConstant(f)) { + return; + } + zddClearFlag(cuddT(f)); + zddClearFlag(Cudd_Regular(cuddE(f))); + return; + +} /* end of zddClearFlag */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cudd.doc b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cudd.doc new file mode 100644 index 000000000..7a9169b19 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cudd.doc @@ -0,0 +1,6776 @@ +The cudd package + +The University of Colorado decision diagram package. + +Fabio Somenzi + +********************************************************************** + +Cudd_AddHook() Adds a function to a hook. + +Cudd_ApaAdd() Adds two arbitrary precision integers. + +Cudd_ApaCompareRatios() Compares the ratios of two arbitrary precision + integers to two unsigned ints. + +Cudd_ApaCompare() Compares two arbitrary precision integers. + +Cudd_ApaCopy() Makes a copy of an arbitrary precision integer. + +Cudd_ApaCountMinterm() Counts the number of minterms of a DD. + +Cudd_ApaIntDivision() Divides an arbitrary precision integer by an + integer. + +Cudd_ApaNumberOfDigits() Finds the number of digits for an arbitrary + precision integer. + +Cudd_ApaPowerOfTwo() Sets an arbitrary precision integer to a power + of two. + +Cudd_ApaPrintDecimal() Prints an arbitrary precision integer in + decimal format. + +Cudd_ApaPrintDensity() Prints the density of a BDD or ADD using + arbitrary precision arithmetic. + +Cudd_ApaPrintExponential() Prints an arbitrary precision integer in + exponential format. + +Cudd_ApaPrintHex() Prints an arbitrary precision integer in + hexadecimal format. + +Cudd_ApaPrintMintermExp() Prints the number of minterms of a BDD or ADD + in exponential format using arbitrary + precision arithmetic. + +Cudd_ApaPrintMinterm() Prints the number of minterms of a BDD or ADD + using arbitrary precision arithmetic. + +Cudd_ApaSetToLiteral() Sets an arbitrary precision integer to a one- + digit literal. + +Cudd_ApaShiftRight() Shifts right an arbitrary precision integer by + one binary place. + +Cudd_ApaShortDivision() Divides an arbitrary precision integer by a + digit. + +Cudd_ApaSubtract() Subtracts two arbitrary precision integers. + +Cudd_AutodynDisableZdd() Disables automatic dynamic reordering of ZDDs. + +Cudd_AutodynDisable() Disables automatic dynamic reordering. + +Cudd_AutodynEnableZdd() Enables automatic dynamic reordering of ZDDs. + +Cudd_AutodynEnable() Enables automatic dynamic reordering of BDDs + and ADDs. + +Cudd_AverageDistance() Computes the average distance between adjacent + nodes. + +Cudd_BddToAdd() Converts a BDD to a 0-1 ADD. + +Cudd_BddToCubeArray() Builds a positional array from the BDD of a + cube. + +Cudd_BiasedOverApprox() Extracts a dense superset from a BDD with the + biased underapproximation method. + +Cudd_BiasedUnderApprox() Extracts a dense subset from a BDD with the + biased underapproximation method. + +Cudd_CProjection() Computes the compatible projection of R w.r.t. + cube Y. + +Cudd_CheckCube() Checks whether g is the BDD of a cube. + +Cudd_CheckKeys() Checks for several conditions that should not + occur. + +Cudd_CheckZeroRef() Checks the unique table for nodes with non-zero + reference counts. + +Cudd_ClassifySupport() Classifies the variables in the support of two + DDs. + +Cudd_ClearErrorCode() Clear the error code of a manager. + +Cudd_CofMinterm() Computes the fraction of minterms in the on-set + of all the positive cofactors of a BDD or + ADD. + +Cudd_Cofactor() Computes the cofactor of f with respect to g. + +Cudd_CountLeaves() Counts the number of leaves in a DD. + +Cudd_CountMinterm() Counts the number of minterms of a DD. + +Cudd_CountPathsToNonZero() Counts the number of paths to a non-zero + terminal of a DD. + +Cudd_CountPath() Counts the number of paths of a DD. + +Cudd_CubeArrayToBdd() Builds the BDD of a cube from a positional + array. + +Cudd_DagSize() Counts the number of nodes in a DD. + +Cudd_DeadAreCounted() Tells whether dead nodes are counted towards + triggering reordering. + +Cudd_DebugCheck() Checks for inconsistencies in the DD heap. + +Cudd_Decreasing() Determines whether a BDD is negative unate in a + variable. + +Cudd_DelayedDerefBdd() Decreases the reference count of BDD node n. + +Cudd_Density() Computes the density of a BDD or ADD. + +Cudd_Deref() Decreases the reference count of node. + +Cudd_DisableGarbageCollection() + Disables garbage collection. + +Cudd_DisableOrderingMonitoring() + Disables monitoring of ordering. + +Cudd_DisableReorderingReporting() + Disables reporting of reordering stats. + +Cudd_Disequality() Generates a BDD for the function x - y != c. + +Cudd_DumpBlifBody() Writes a blif body representing the argument + BDDs. + +Cudd_DumpBlif() Writes a blif file representing the argument + BDDs. + +Cudd_DumpDDcal() Writes a DDcal file representing the argument + BDDs. + +Cudd_DumpDaVinci() Writes a daVinci file representing the argument + BDDs. + +Cudd_DumpDot() Writes a dot file representing the argument + DDs. + +Cudd_DumpFactoredForm() Writes factored forms representing the argument + BDDs. + +Cudd_Dxygtdxz() Generates a BDD for the function d(x,y) > + d(x,z). + +Cudd_Dxygtdyz() Generates a BDD for the function d(x,y) > + d(y,z). + +Cudd_EnableGarbageCollection() Enables garbage collection. + +Cudd_EnableOrderingMonitoring() + Enables monitoring of ordering. + +Cudd_EnableReorderingReporting() + Enables reporting of reordering stats. + +Cudd_EpdCountMinterm() Counts the number of minterms of a DD with + extended precision. + +Cudd_EqualSupNorm() Compares two ADDs for equality within + tolerance. + +Cudd_EquivDC() Tells whether F and G are identical wherever D + is 0. + +Cudd_EstimateCofactorSimple() Estimates the number of nodes in a cofactor of + a DD. + +Cudd_EstimateCofactor() Estimates the number of nodes in a cofactor of + a DD. + +Cudd_Eval() Returns the value of a DD for a given variable + assignment. + +Cudd_ExpectedUsedSlots() Computes the expected fraction of used slots in + the unique table. + +Cudd_FindEssential() Finds the essential variables of a DD. + +Cudd_FindTwoLiteralClauses() Finds the two literal clauses of a DD. + +Cudd_FirstCube() Finds the first cube of a decision diagram. + +Cudd_FirstNode() Finds the first node of a decision diagram. + +Cudd_FirstPrime() Finds the first prime of a Boolean function. + +Cudd_FreeTree() Frees the variable group tree of the manager. + +Cudd_FreeZddTree() Frees the variable group tree of the manager. + +Cudd_GarbageCollectionEnabled() + Tells whether garbage collection is enabled. + +Cudd_GenFree() Frees a CUDD generator. + +Cudd_IncreaseTimeLimit() Increases the time limit for the manager. + +Cudd_Increasing() Determines whether a BDD is positive unate in a + variable. + +Cudd_IndicesToCube() Builds a cube of BDD variables from an array of + indices. + +Cudd_Inequality() Generates a BDD for the function x - y ≥ c. + +Cudd_Init() Creates a new DD manager. + +Cudd_IsGenEmpty() Queries the status of a generator. + +Cudd_IsInHook() Checks whether a function is in a hook. + +Cudd_IsNonConstant() Returns 1 if a DD node is not constant. + +Cudd_IterDerefBdd() Decreases the reference count of BDD node n. + +Cudd_LargestCube() Finds a largest cube in a DD. + +Cudd_MakeBddFromZddCover() Converts a ZDD cover to a BDD. + +Cudd_MakeTreeNode() Creates a new variable group. + +Cudd_MakeZddTreeNode() Creates a new ZDD variable group. + +Cudd_MinHammingDist() Returns the minimum Hamming distance between f + and minterm. + +Cudd_NewApaNumber() Allocates memory for an arbitrary precision + integer. + +Cudd_NextCube() Generates the next cube of a decision diagram + onset. + +Cudd_NextNode() Finds the next node of a decision diagram. + +Cudd_NextPrime() Generates the next prime of a Boolean function. + +Cudd_NodeReadIndex() Returns the index of the node. + +Cudd_OrderingMonitoring() Returns 1 if monitoring of ordering is enabled. + +Cudd_OutOfMem() Warns that a memory allocation failed. + +Cudd_OverApprox() Extracts a dense superset from a BDD with + Shiple's underapproximation method. + +Cudd_Prime() Returns the next prime >= p. + +Cudd_PrintDebug() Prints to the standard output a DD and its + statistics. + +Cudd_PrintGroupedOrder() Hook function to print the current variable + order. + +Cudd_PrintInfo() Prints out statistics and settings for a CUDD + manager. + +Cudd_PrintLinear() Prints the linear transform matrix. + +Cudd_PrintMinterm() Prints a disjoint sum of products. + +Cudd_PrintTwoLiteralClauses() Prints the two literal clauses of a DD. + +Cudd_PrintVersion() Prints the package version number. + +Cudd_PrioritySelect() Selects pairs from R using a priority function. + +Cudd_Quit() Deletes resources associated with a DD manager. + +Cudd_Random() Portable random number generator. + +Cudd_ReadArcviolation() Returns the current value of the arcviolation + parameter used in group sifting. + +Cudd_ReadBackground() Reads the background constant of the manager. + +Cudd_ReadCacheHits() Returns the number of cache hits. + +Cudd_ReadCacheLookUps() Returns the number of cache look-ups. + +Cudd_ReadCacheSlots() Reads the number of slots in the cache. + +Cudd_ReadCacheUsedSlots() Reads the fraction of used slots in the cache. + +Cudd_ReadDead() Returns the number of dead nodes in the unique + table. + +Cudd_ReadElapsedTime() Returns the time elapsed since the start time + of the manager. + +Cudd_ReadEpsilon() Reads the epsilon parameter of the manager. + +Cudd_ReadErrorCode() Returns the code of the last error. + +Cudd_ReadGarbageCollectionTime() + Returns the time spent in garbage collection. + +Cudd_ReadGarbageCollections() Returns the number of times garbage collection + has occurred. + +Cudd_ReadGroupcheck() Reads the groupcheck parameter of the manager. + +Cudd_ReadInvPermZdd() Returns the index of the ZDD variable currently + in the i-th position of the order. + +Cudd_ReadInvPerm() Returns the index of the variable currently in + the i-th position of the order. + +Cudd_ReadIthClause() Accesses the i-th clause of a DD. + +Cudd_ReadKeys() Returns the number of nodes in the unique + table. + +Cudd_ReadLinear() Reads an entry of the linear transform matrix. + +Cudd_ReadLogicZero() Returns the logic zero constant of the manager. + +Cudd_ReadLooseUpTo() Reads the looseUpTo parameter of the manager. + +Cudd_ReadMaxCacheHard() Reads the maxCacheHard parameter of the + manager. + +Cudd_ReadMaxCache() Returns the soft limit for the cache size. + +Cudd_ReadMaxGrowthAlternate() Reads the maxGrowthAlt parameter of the + manager. + +Cudd_ReadMaxGrowth() Reads the maxGrowth parameter of the manager. + +Cudd_ReadMaxLive() Reads the maximum allowed number of live nodes. + +Cudd_ReadMaxMemory() Reads the maximum allowed memory. + +Cudd_ReadMaxReorderings() Returns the maximum number of times reordering + may be invoked. + +Cudd_ReadMemoryInUse() Returns the memory in use by the manager + measured in bytes. + +Cudd_ReadMinDead() Reads the minDead parameter of the manager. + +Cudd_ReadMinHit() Reads the hit rate that causes resizinig of the + computed table. + +Cudd_ReadMinusInfinity() Reads the minus-infinity constant from the + manager. + +Cudd_ReadNextReordering() Returns the threshold for the next dynamic + reordering. + +Cudd_ReadNodeCount() Reports the number of nodes in BDDs and ADDs. + +Cudd_ReadNodesDropped() Returns the number of nodes dropped. + +Cudd_ReadNodesFreed() Returns the number of nodes freed. + +Cudd_ReadNumberXovers() Reads the current number of crossovers used by + the genetic algorithm for reordering. + +Cudd_ReadOne() Returns the one constant of the manager. + +Cudd_ReadOrderRandomization() Returns the order randomization factor. + +Cudd_ReadPeakLiveNodeCount() Reports the peak number of live nodes. + +Cudd_ReadPeakNodeCount() Reports the peak number of nodes. + +Cudd_ReadPermZdd() Returns the current position of the i-th ZDD + variable in the order. + +Cudd_ReadPerm() Returns the current position of the i-th + variable in the order. + +Cudd_ReadPlusInfinity() Reads the plus-infinity constant from the + manager. + +Cudd_ReadPopulationSize() Reads the current size of the population used + by the genetic algorithm for reordering. + +Cudd_ReadRecomb() Returns the current value of the recombination + parameter used in group sifting. + +Cudd_ReadRecursiveCalls() Returns the number of recursive calls. + +Cudd_ReadReorderingCycle() Reads the reordCycle parameter of the manager. + +Cudd_ReadReorderingTime() Returns the time spent in reordering. + +Cudd_ReadReorderings() Returns the number of times reordering has + occurred. + +Cudd_ReadSiftMaxSwap() Reads the siftMaxSwap parameter of the manager. + +Cudd_ReadSiftMaxVar() Reads the siftMaxVar parameter of the manager. + +Cudd_ReadSize() Returns the number of BDD variables in + existance. + +Cudd_ReadSlots() Returns the total number of slots of the unique + table. + +Cudd_ReadStartTime() Returns the start time of the manager. + +Cudd_ReadStderr() Reads the stderr of a manager. + +Cudd_ReadStdout() Reads the stdout of a manager. + +Cudd_ReadSwapSteps() Reads the number of elementary reordering + steps. + +Cudd_ReadSymmviolation() Returns the current value of the symmviolation + parameter used in group sifting. + +Cudd_ReadTimeLimit() Returns the time limit for the manager. + +Cudd_ReadTree() Returns the variable group tree of the manager. + +Cudd_ReadUniqueLinks() Returns the number of links followed in the + unique table. + +Cudd_ReadUniqueLookUps() Returns the number of look-ups in the unique + table. + +Cudd_ReadUsedSlots() Reads the fraction of used slots in the unique + table. + +Cudd_ReadVars() Returns the i-th element of the vars array. + +Cudd_ReadZddOne() Returns the ZDD for the constant 1 function. + +Cudd_ReadZddSize() Returns the number of ZDD variables in + existance. + +Cudd_ReadZddTree() Returns the variable group tree of the manager. + +Cudd_ReadZero() Returns the zero constant of the manager. + +Cudd_RecursiveDerefZdd() Decreases the reference count of ZDD node n. + +Cudd_RecursiveDeref() Decreases the reference count of node n. + +Cudd_ReduceHeap() Main dynamic reordering routine. + +Cudd_Ref() Increases the reference count of a node, if it + is not saturated. + +Cudd_RemapOverApprox() Extracts a dense superset from a BDD with the + remapping underapproximation method. + +Cudd_RemapUnderApprox() Extracts a dense subset from a BDD with the + remapping underapproximation method. + +Cudd_RemoveHook() Removes a function from a hook. + +Cudd_ReorderingReporting() Returns 1 if reporting of reordering stats is + enabled. + +Cudd_ReorderingStatusZdd() Reports the status of automatic dynamic + reordering of ZDDs. + +Cudd_ReorderingStatus() Reports the status of automatic dynamic + reordering of BDDs and ADDs. + +Cudd_Reserve() Expand manager without creating variables. + +Cudd_ResetStartTime() Resets the start time of the manager. + +Cudd_SetArcviolation() Sets the value of the arcviolation parameter + used in group sifting. + +Cudd_SetBackground() Sets the background constant of the manager. + +Cudd_SetEpsilon() Sets the epsilon parameter of the manager to + ep. + +Cudd_SetGroupcheck() Sets the parameter groupcheck of the manager to + gc. + +Cudd_SetLooseUpTo() Sets the looseUpTo parameter of the manager. + +Cudd_SetMaxCacheHard() Sets the maxCacheHard parameter of the manager. + +Cudd_SetMaxGrowthAlternate() Sets the maxGrowthAlt parameter of the manager. + +Cudd_SetMaxGrowth() Sets the maxGrowth parameter of the manager. + +Cudd_SetMaxLive() Sets the maximum allowed number of live nodes. + +Cudd_SetMaxMemory() Sets the maximum allowed memory. + +Cudd_SetMaxReorderings() Sets the maximum number of times reordering may + be invoked. + +Cudd_SetMinHit() Sets the hit rate that causes resizinig of the + computed table. + +Cudd_SetNextReordering() Sets the threshold for the next dynamic + reordering. + +Cudd_SetNumberXovers() Sets the number of crossovers used by the + genetic algorithm for reordering. + +Cudd_SetOrderRandomization() Sets the order randomization factor. + +Cudd_SetPopulationSize() Sets the size of the population used by the + genetic algorithm for reordering. + +Cudd_SetRecomb() Sets the value of the recombination parameter + used in group sifting. + +Cudd_SetReorderingCycle() Sets the reordCycle parameter of the manager. + +Cudd_SetSiftMaxSwap() Sets the siftMaxSwap parameter of the manager. + +Cudd_SetSiftMaxVar() Sets the siftMaxVar parameter of the manager. + +Cudd_SetStartTime() Sets the start time of the manager. + +Cudd_SetStderr() Sets the stderr of a manager. + +Cudd_SetStdout() Sets the stdout of a manager. + +Cudd_SetSymmviolation() Sets the value of the symmviolation parameter + used in group sifting. + +Cudd_SetTimeLimit() Sets the time limit for the manager. + +Cudd_SetTree() Sets the variable group tree of the manager. + +Cudd_SetVarMap() Registers a variable mapping with the manager. + +Cudd_SetZddTree() Sets the ZDD variable group tree of the + manager. + +Cudd_SharingSize() Counts the number of nodes in an array of DDs. + +Cudd_ShortestLength() Find the length of the shortest path(s) in a + DD. + +Cudd_ShortestPath() Finds a shortest path in a DD. + +Cudd_ShuffleHeap() Reorders variables according to given + permutation. + +Cudd_SolveEqn() Implements the solution of F(x,y) = 0. + +Cudd_SplitSet() Returns m minterms from a BDD. + +Cudd_Srandom() Initializer for the portable random number + generator. + +Cudd_StdPostReordHook() Sample hook function to call after reordering. + +Cudd_StdPreReordHook() Sample hook function to call before reordering. + +Cudd_SubsetCompress() Find a dense subset of BDD f. + +Cudd_SubsetHeavyBranch() Extracts a dense subset from a BDD with the + heavy branch heuristic. + +Cudd_SubsetShortPaths() Extracts a dense subset from a BDD with the + shortest paths heuristic. + +Cudd_SubsetWithMaskVars() Extracts a subset from a BDD. + +Cudd_SupersetCompress() Find a dense superset of BDD f. + +Cudd_SupersetHeavyBranch() Extracts a dense superset from a BDD with the + heavy branch heuristic. + +Cudd_SupersetShortPaths() Extracts a dense superset from a BDD with the + shortest paths heuristic. + +Cudd_SupportIndex() Finds the variables on which a DD depends. + +Cudd_SupportIndices() Finds the variables on which a DD depends. + +Cudd_SupportSize() Counts the variables on which a DD depends. + +Cudd_Support() Finds the variables on which a DD depends. + +Cudd_SymmProfile() Prints statistics on symmetric variables. + +Cudd_TimeLimited() Returns true if the time limit for the manager + is set. + +Cudd_TurnOffCountDead() Causes the dead nodes not to be counted towards + triggering reordering. + +Cudd_TurnOnCountDead() Causes the dead nodes to be counted towards + triggering reordering. + +Cudd_UnderApprox() Extracts a dense subset from a BDD with + Shiple's underapproximation method. + +Cudd_UnsetTimeLimit() Unsets the time limit for the manager. + +Cudd_UpdateTimeLimit() Updates the time limit for the manager. + +Cudd_VectorSupportIndex() Finds the variables on which a set of DDs + depends. + +Cudd_VectorSupportIndices() Finds the variables on which a set of DDs + depends. + +Cudd_VectorSupportSize() Counts the variables on which a set of DDs + depends. + +Cudd_VectorSupport() Finds the variables on which a set of DDs + depends. + +Cudd_VerifySol() Checks the solution of F(x,y) = 0. + +Cudd_Xeqy() Generates a BDD for the function x==y. + +Cudd_Xgty() Generates a BDD for the function x > y. + +Cudd_addAgreement() f if f==g; background if f!=g. + +Cudd_addApply() Applies op to the corresponding discriminants + of f and g. + +Cudd_addBddInterval() Converts an ADD to a BDD. + +Cudd_addBddIthBit() Converts an ADD to a BDD by extracting the i-th + bit from the leaves. + +Cudd_addBddPattern() Converts an ADD to a BDD. + +Cudd_addBddStrictThreshold() Converts an ADD to a BDD. + +Cudd_addBddThreshold() Converts an ADD to a BDD. + +Cudd_addCmpl() Computes the complement of an ADD a la C + language. + +Cudd_addCompose() Substitutes g for x_v in the ADD for f. + +Cudd_addComputeCube() Computes the cube of an array of ADD variables. + +Cudd_addConstrain() Computes f constrain c for ADDs. + +Cudd_addConst() Returns the ADD for constant c. + +Cudd_addDiff() Returns plusinfinity if f=g; returns min(f,g) + if f!=g. + +Cudd_addDivide() Integer and floating point division. + +Cudd_addEvalConst() Checks whether ADD g is constant whenever ADD f + is 1. + +Cudd_addExistAbstract() Existentially Abstracts all the variables in + cube from f. + +Cudd_addFindMax() Finds the maximum discriminant of f. + +Cudd_addFindMin() Finds the minimum discriminant of f. + +Cudd_addGeneralVectorCompose() Composes an ADD with a vector of ADDs. + +Cudd_addHamming() Computes the Hamming distance ADD. + +Cudd_addHarwell() Reads in a matrix in the format of the Harwell- + Boeing benchmark suite. + +Cudd_addIteConstant() Implements ITEconstant for ADDs. + +Cudd_addIte() Implements ITE(f,g,h). + +Cudd_addIthBit() Extracts the i-th bit from an ADD. + +Cudd_addIthVar() Returns the ADD variable with index i. + +Cudd_addLeq() Determines whether f is less than or equal to + g. + +Cudd_addLog() Natural logarithm of an ADD. + +Cudd_addMatrixMultiply() Calculates the product of two matrices + represented as ADDs. + +Cudd_addMaximum() Integer and floating point max. + +Cudd_addMinimum() Integer and floating point min. + +Cudd_addMinus() Integer and floating point subtraction. + +Cudd_addMonadicApply() Applies op to the discriminants of f. + +Cudd_addNand() NAND of two 0-1 ADDs. + +Cudd_addNegate() Computes the additive inverse of an ADD. + +Cudd_addNewVarAtLevel() Returns a new ADD variable at a specified + level. + +Cudd_addNewVar() Returns a new ADD variable. + +Cudd_addNonSimCompose() Composes an ADD with a vector of 0-1 ADDs. + +Cudd_addNor() NOR of two 0-1 ADDs. + +Cudd_addOneZeroMaximum() Returns 1 if f > g and 0 otherwise. + +Cudd_addOrAbstract() Disjunctively abstracts all the variables in + cube from the 0-1 ADD f. + +Cudd_addOr() Disjunction of two 0-1 ADDs. + +Cudd_addOuterSum() Takes the minimum of a matrix and the outer sum + of two vectors. + +Cudd_addPermute() Permutes the variables of an ADD. + +Cudd_addPlus() Integer and floating point addition. + +Cudd_addRead() Reads in a sparse matrix. + +Cudd_addResidue() Builds an ADD for the residue modulo m of an n- + bit number. + +Cudd_addRestrict() ADD restrict according to Coudert and Madre's + algorithm (ICCAD90). + +Cudd_addRoundOff() Rounds off the discriminants of an ADD. + +Cudd_addScalarInverse() Computes the scalar inverse of an ADD. + +Cudd_addSetNZ() This operator sets f to the value of g wherever + g != 0. + +Cudd_addSwapVariables() Swaps two sets of variables of the same size (x + and y) in the ADD f. + +Cudd_addThreshold() f if f>=g; 0 if f d(x,z); x, y, and + z are N-bit numbers, x[0] x[1] ... x[N-1], y[0] y[1] ... y[N-1], and z[0] + z[1] ... z[N-1], with 0 the most significant bit. The distance d(x,y) is + defined as: sum_{i=0}^{N-1}(|x_i - y_i| cdot 2^{N-i-1}). The BDD is built + bottom-up. It has 7*N-3 internal nodes, if the variables are ordered as + follows: x[0] y[0] z[0] x[1] y[1] z[1] ... x[N-1] y[N-1] z[N-1]. + + Side Effects: None + +DdNode * +Cudd_Dxygtdyz( + DdManager * dd, DD manager + int N, number of x, y, and z variables + DdNode ** x, array of x variables + DdNode ** y, array of y variables + DdNode ** z array of z variables +) + This function generates a BDD for the function d(x,y) > d(y,z); x, y, and + z are N-bit numbers, x[0] x[1] ... x[N-1], y[0] y[1] ... y[N-1], and z[0] + z[1] ... z[N-1], with 0 the most significant bit. The distance d(x,y) is + defined as: sum_{i=0}^{N-1}(|x_i - y_i| cdot 2^{N-i-1}). The BDD is built + bottom-up. It has 7*N-3 internal nodes, if the variables are ordered as + follows: x[0] y[0] z[0] x[1] y[1] z[1] ... x[N-1] y[N-1] z[N-1]. + + Side Effects: None + +void +Cudd_EnableGarbageCollection( + DdManager * dd +) + Enables garbage collection. Garbage collection is initially enabled. + Therefore it is necessary to call this function only if garbage collection + has been explicitly disabled. + + Side Effects: None + +int +Cudd_EnableOrderingMonitoring( + DdManager * dd +) + Enables monitoring of ordering. Returns 1 if successful; 0 otherwise. + + Side Effects: Installs functions in the pre-reordering and post-reordering + hooks. + +int +Cudd_EnableReorderingReporting( + DdManager * dd +) + Enables reporting of reordering stats. Returns 1 if successful; 0 otherwise. + + Side Effects: Installs functions in the pre-reordering and post-reordering + hooks. + +int +Cudd_EpdCountMinterm( + DdManager * manager, + DdNode * node, + int nvars, + EpDouble * epd +) + Counts the number of minterms of a DD with extended precision. The function + is assumed to depend on nvars variables. The minterm count is represented as + an EpDouble, to allow any number of variables. Returns 0 if successful; + CUDD_OUT_OF_MEM otherwise. + + Side Effects: None + +int +Cudd_EqualSupNorm( + DdManager * dd, manager + DdNode * f, first ADD + DdNode * g, second ADD + CUDD_VALUE_TYPE tolerance, maximum allowed difference + int pr verbosity level +) + Compares two ADDs for equality within tolerance. Two ADDs are reported to be + equal if the maximum difference between them (the sup norm of their + difference) is less than or equal to the tolerance parameter. Returns 1 if + the two ADDs are equal (within tolerance); 0 otherwise. If parameter + pr is positive the first failure is reported to the standard + output. + + Side Effects: None + +int +Cudd_EquivDC( + DdManager * dd, + DdNode * F, + DdNode * G, + DdNode * D +) + Tells whether F and G are identical wherever D is 0. F and G are either two + ADDs or two BDDs. D is either a 0-1 ADD or a BDD. The function returns 1 if + F and G are equivalent, and 0 otherwise. No new nodes are created. + + Side Effects: None + +int +Cudd_EstimateCofactorSimple( + DdNode * node, + int i +) + Estimates the number of nodes in a cofactor of a DD. Returns an estimate of + the number of nodes in the positive cofactor of the graph rooted at node + with respect to the variable whose index is i. This procedure implements + with minor changes the algorithm of Cabodi et al. (ICCAD96). It does not + allocate any memory, it does not change the state of the manager, and it is + fast. However, it has been observed to overestimate the size of the cofactor + by as much as a factor of 2. + + Side Effects: None + +int +Cudd_EstimateCofactor( + DdManager * dd, manager + DdNode * f, function + int i, index of variable + int phase 1: positive; 0: negative +) + Estimates the number of nodes in a cofactor of a DD. Returns an estimate of + the number of nodes in a cofactor of the graph rooted at node with respect + to the variable whose index is i. In case of failure, returns + CUDD_OUT_OF_MEM. This function uses a refinement of the algorithm of Cabodi + et al. (ICCAD96). The refinement allows the procedure to account for part of + the recombination that may occur in the part of the cofactor above the + cofactoring variable. This procedure does not create any new node. It does + keep a small table of results; therefore it may run out of memory. If this + is a concern, one should use Cudd_EstimateCofactorSimple, which is faster, + does not allocate any memory, but is less accurate. + + Side Effects: None + +DdNode * +Cudd_Eval( + DdManager * dd, + DdNode * f, + int * inputs +) + Finds the value of a DD for a given variable assignment. The variable + assignment is passed in an array of int's, that should specify a zero or a + one for each variable in the support of the function. Returns a pointer to a + constant node. No new nodes are produced. + + Side Effects: None + +double +Cudd_ExpectedUsedSlots( + DdManager * dd +) + Computes the fraction of slots in the unique table that should be in use. + This expected value is based on the assumption that the hash function + distributes the keys randomly; it can be compared with the result of + Cudd_ReadUsedSlots to monitor the performance of the unique table hash + function. + + Side Effects: None + +DdNode * +Cudd_FindEssential( + DdManager * dd, + DdNode * f +) + Returns the cube of the essential variables. A positive literal means that + the variable must be set to 1 for the function to be 1. A negative literal + means that the variable must be set to 0 for the function to be 1. Returns a + pointer to the cube BDD if successful; NULL otherwise. + + Side Effects: None + +DdTlcInfo * +Cudd_FindTwoLiteralClauses( + DdManager * dd, + DdNode * f +) + Returns the one- and two-literal clauses of a DD. Returns a pointer to the + structure holding the clauses if successful; NULL otherwise. For a constant + DD, the empty set of clauses is returned. This is obviously correct for a + non-zero constant. For the constant zero, it is based on the assumption that + only those clauses containing variables in the support of the function are + considered. Since the support of a constant function is empty, no clauses + are returned. + + Side Effects: None + +DdGen * +Cudd_FirstCube( + DdManager * dd, + DdNode * f, + int ** cube, + CUDD_VALUE_TYPE * value +) + Defines an iterator on the onset of a decision diagram and finds its first + cube. Returns a generator that contains the information necessary to + continue the enumeration if successful; NULL otherwise. A cube is + represented as an array of literals, which are integers in {0, 1, 2}; 0 + represents a complemented literal, 1 represents an uncomplemented literal, + and 2 stands for don't care. The enumeration produces a disjoint cover of + the function associated with the diagram. The size of the array equals the + number of variables in the manager at the time Cudd_FirstCube is called. + For each cube, a value is also returned. This value is always 1 for a BDD, + while it may be different from 1 for an ADD. For BDDs, the offset is the set + of cubes whose value is the logical zero. For ADDs, the offset is the set of + cubes whose value is the background value. The cubes of the offset are not + enumerated. + + Side Effects: The first cube and its value are returned as side effects. + +DdGen * +Cudd_FirstNode( + DdManager * dd, + DdNode * f, + DdNode ** node +) + Defines an iterator on the nodes of a decision diagram and finds its first + node. Returns a generator that contains the information necessary to + continue the enumeration if successful; NULL otherwise. The nodes are + enumerated in a reverse topological order, so that a node is always preceded + in the enumeration by its descendants. + + Side Effects: The first node is returned as a side effect. + +DdGen * +Cudd_FirstPrime( + DdManager * dd, + DdNode * l, + DdNode * u, + int ** cube +) + Defines an iterator on a pair of BDDs describing a (possibly incompletely + specified) Boolean functions and finds the first cube of a cover of the + function. Returns a generator that contains the information necessary to + continue the enumeration if successful; NULL otherwise. The two argument + BDDs are the lower and upper bounds of an interval. It is a mistake to call + this function with a lower bound that is not less than or equal to the upper + bound. A cube is represented as an array of literals, which are integers + in {0, 1, 2}; 0 represents a complemented literal, 1 represents an + uncomplemented literal, and 2 stands for don't care. The enumeration + produces a prime and irredundant cover of the function associated with the + two BDDs. The size of the array equals the number of variables in the + manager at the time Cudd_FirstCube is called. This iterator can only be + used on BDDs. + + Side Effects: The first cube is returned as side effect. + +void +Cudd_FreeTree( + DdManager * dd +) + Frees the variable group tree of the manager. + + Side Effects: None + +void +Cudd_FreeZddTree( + DdManager * dd +) + Frees the variable group tree of the manager. + + Side Effects: None + +int +Cudd_GarbageCollectionEnabled( + DdManager * dd +) + Returns 1 if garbage collection is enabled; 0 otherwise. + + Side Effects: None + +int +Cudd_GenFree( + DdGen * gen +) + Frees a CUDD generator. Always returns 0, so that it can be used in mis-like + foreach constructs. + + Side Effects: None + +void +Cudd_IncreaseTimeLimit( + DdManager * unique, + unsigned long increase +) + Increases the time limit for the manager. + + Side Effects: None + +DdNode * +Cudd_Increasing( + DdManager * dd, + DdNode * f, + int i +) + Determines whether the function represented by BDD f is positive unate + (monotonic increasing) in variable i. It is based on Cudd_Decreasing and the + fact that f is monotonic increasing in i if and only if its complement is + monotonic decreasing in i. + + Side Effects: None + +DdNode * +Cudd_IndicesToCube( + DdManager * dd, + int * array, + int n +) + Builds a cube of BDD variables from an array of indices. Returns a pointer + to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_Inequality( + DdManager * dd, DD manager + int N, number of x and y variables + int c, right-hand side constant + DdNode ** x, array of x variables + DdNode ** y array of y variables +) + This function generates a BDD for the function x -y ≥ c. Both x and y are + N-bit numbers, x[0] x[1] ... x[N-1] and y[0] y[1] ... y[N-1], with 0 the + most significant bit. The BDD is built bottom-up. It has a linear number of + nodes if the variables are ordered as follows: x[0] y[0] x[1] y[1] ... x[N- + 1] y[N-1]. + + Side Effects: None + +DdManager * +Cudd_Init( + unsigned int numVars, initial number of BDD variables (i.e., + subtables) + unsigned int numVarsZ, initial number of ZDD variables (i.e., + subtables) + unsigned int numSlots, initial size of the unique tables + unsigned int cacheSize, initial size of the cache + unsigned long maxMemory target maximum memory occupation +) + Creates a new DD manager, initializes the table, the basic constants and the + projection functions. If maxMemory is 0, Cudd_Init decides suitable values + for the maximum size of the cache and for the limit for fast unique table + growth based on the available memory. Returns a pointer to the manager if + successful; NULL otherwise. + + Side Effects: None + +int +Cudd_IsGenEmpty( + DdGen * gen +) + Queries the status of a generator. Returns 1 if the generator is empty or + NULL; 0 otherswise. + + Side Effects: None + +int +Cudd_IsInHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where +) + Checks whether a function is in a hook. A hook is a list of application- + provided functions called on certain occasions by the package. Returns 1 if + the function is found; 0 otherwise. + + Side Effects: None + +int +Cudd_IsNonConstant( + DdNode * f +) + Returns 1 if a DD node is not constant. This function is useful to test the + results of Cudd_bddIteConstant, Cudd_addIteConstant, Cudd_addEvalConst. + These results may be a special value signifying non-constant. In the other + cases the macro Cudd_IsConstant can be used. + + Side Effects: None + +void +Cudd_IterDerefBdd( + DdManager * table, + DdNode * n +) + Decreases the reference count of node n. If n dies, recursively decreases + the reference counts of its children. It is used to dispose of a BDD that is + no longer needed. It is more efficient than Cudd_RecursiveDeref, but it + cannot be used on ADDs. The greater efficiency comes from being able to + assume that no constant node will ever die as a result of a call to this + procedure. + + Side Effects: None + +DdNode * +Cudd_LargestCube( + DdManager * manager, + DdNode * f, + int * length +) + Finds a largest cube in a DD. f is the DD we want to get the largest cube + for. The problem is translated into the one of finding a shortest path in f, + when both THEN and ELSE arcs are assumed to have unit length. This yields a + largest cube in the disjoint cover corresponding to the DD. Therefore, it is + not necessarily the largest implicant of f. Returns the largest cube as a + BDD. + + Side Effects: The number of literals of the cube is returned in the location + pointed by length if it is non-null. + +DdNode * +Cudd_MakeBddFromZddCover( + DdManager * dd, + DdNode * node +) + Converts a ZDD cover to a BDD for the function represented by the cover. If + successful, it returns a BDD node, otherwise it returns NULL. + + +MtrNode * +Cudd_MakeTreeNode( + DdManager * dd, manager + unsigned int low, index of the first group variable + unsigned int size, number of variables in the group + unsigned int type MTR_DEFAULT or MTR_FIXED +) + Creates a new variable group. The group starts at variable low and contains + size variables. The parameter low is the index of the first variable. If the + variable already exists, its current position in the order is known to the + manager. If the variable does not exist yet, the position is assumed to be + the same as the index. The group tree is created if it does not exist yet. + Returns a pointer to the group if successful; NULL otherwise. + + Side Effects: The variable tree is changed. + +MtrNode * +Cudd_MakeZddTreeNode( + DdManager * dd, manager + unsigned int low, index of the first group variable + unsigned int size, number of variables in the group + unsigned int type MTR_DEFAULT or MTR_FIXED +) + Creates a new ZDD variable group. The group starts at variable and contains + size variables. The parameter low is the index of the first variable. If the + variable already exists, its current position in the order is known to the + manager. If the variable does not exist yet, the position is assumed to be + the same as the index. The group tree is created if it does not exist yet. + Returns a pointer to the group if successful; NULL otherwise. + + Side Effects: The ZDD variable tree is changed. + +int +Cudd_MinHammingDist( + DdManager * dd, DD manager + DdNode * f, function to examine + int * minterm, reference minterm + int upperBound distance above which an approximate + answer is OK +) + Returns the minimum Hamming distance between the minterms of a function f + and a reference minterm. The function is given as a BDD; the minterm is + given as an array of integers, one for each variable in the manager. Returns + the minimum distance if it is less than the upper bound; the upper bound if + the minimum distance is at least as large; CUDD_OUT_OF_MEM in case of + failure. + + Side Effects: None + +DdApaNumber +Cudd_NewApaNumber( + int digits +) + Allocates memory for an arbitrary precision integer. Returns a pointer to + the allocated memory if successful; NULL otherwise. + + Side Effects: None + +int +Cudd_NextCube( + DdGen * gen, + int ** cube, + CUDD_VALUE_TYPE * value +) + Generates the next cube of a decision diagram onset, using generator gen. + Returns 0 if the enumeration is completed; 1 otherwise. + + Side Effects: The cube and its value are returned as side effects. The + generator is modified. + +int +Cudd_NextNode( + DdGen * gen, + DdNode ** node +) + Finds the node of a decision diagram, using generator gen. Returns 0 if the + enumeration is completed; 1 otherwise. + + Side Effects: The next node is returned as a side effect. + +int +Cudd_NextPrime( + DdGen * gen, + int ** cube +) + Generates the next cube of a Boolean function, using generator gen. Returns + 0 if the enumeration is completed; 1 otherwise. + + Side Effects: The cube and is returned as side effects. The generator is + modified. + +unsigned int +Cudd_NodeReadIndex( + DdNode * node +) + Returns the index of the node. The node pointer can be either regular or + complemented. + + Side Effects: None + +int +Cudd_OrderingMonitoring( + DdManager * dd +) + Returns 1 if monitoring of ordering is enabled; 0 otherwise. + + Side Effects: none + +void +Cudd_OutOfMem( + long size size of the allocation that failed +) + Warns that a memory allocation failed. This function can be used as + replacement of MMout_of_memory to prevent the safe_mem functions of the util + package from exiting when malloc returns NULL. One possible use is in case + of discretionary allocations; for instance, the allocation of memory to + enlarge the computed table. + + Side Effects: None + +DdNode * +Cudd_OverApprox( + DdManager * dd, manager + DdNode * f, function to be superset + int numVars, number of variables in the support of f + int threshold, when to stop approximation + int safe, enforce safe approximation + double quality minimum improvement for accepted changes +) + Extracts a dense superset from a BDD. The procedure is identical to the + underapproximation procedure except for the fact that it works on the + complement of the given function. Extracting the subset of the complement + function is equivalent to extracting the superset of the function. Returns a + pointer to the BDD of the superset if successful. NULL if intermediate + result causes the procedure to run out of memory. The parameter numVars is + the maximum number of variables to be used in minterm calculation. The + optimal number should be as close as possible to the size of the support of + f. However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is larger + than 1023, it will overflow. If a 0 parameter is passed then the procedure + will compute a value which will avoid overflow but will cause underflow with + 2046 variables or more. + + Side Effects: None + +unsigned int +Cudd_Prime( + unsigned int p +) + Returns the next prime >= p. + + Side Effects: None + +int +Cudd_PrintDebug( + DdManager * dd, + DdNode * f, + int n, + int pr +) + Prints to the standard output a DD and its statistics. The statistics + include the number of nodes, the number of leaves, and the number of + minterms. (The number of minterms is the number of assignments to the + variables that cause the function to be different from the logical zero (for + BDDs) and from the background value (for ADDs.) The statistics are printed + if pr > 0. Specifically: pr = 0 : prints nothing pr = 1 : + prints counts of nodes and minterms pr = 2 : prints counts + disjoint + sum of product pr = 3 : prints counts + list of nodes pr > 3 : + prints counts + disjoint sum of product + list of nodes For the + purpose of counting the number of minterms, the function is supposed to + depend on n variables. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_PrintGroupedOrder( + DdManager * dd, + const char * str, + void * data +) + Hook function to print the current variable order. It may be called before + or after reordering. Prints on the manager's stdout a parenthesized list + that describes the variable groups. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_PrintInfo( + DdManager * dd, + FILE * fp +) + Prints out statistics and settings for a CUDD manager. Returns 1 if + successful; 0 otherwise. + + Side Effects: None + +int +Cudd_PrintLinear( + DdManager * table +) + Prints the linear transform matrix. Returns 1 in case of success; 0 + otherwise. + + Side Effects: none + +int +Cudd_PrintMinterm( + DdManager * manager, + DdNode * node +) + Prints a disjoint sum of product cover for the function rooted at node. Each + product corresponds to a path from node to a leaf node different from the + logical zero, and different from the background value. Uses the package + default output file. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_PrintTwoLiteralClauses( + DdManager * dd, + DdNode * f, + char ** names, + FILE * fp +) + Prints the one- and two-literal clauses. Returns 1 if successful; 0 + otherwise. The argument "names" can be NULL, in which case the variable + indices are printed. + + Side Effects: None + +void +Cudd_PrintVersion( + FILE * fp +) + Prints the package version number. + + Side Effects: None + +DdNode * +Cudd_PrioritySelect( + DdManager * dd, manager + DdNode * R, BDD of the relation + DdNode ** x, array of x variables + DdNode ** y, array of y variables + DdNode ** z, array of z variables (optional: may be + NULL) + DdNode * Pi, BDD of the priority function (optional: + may be NULL) + int n, size of x, y, and z + DD_PRFP Pifunc function used to build Pi if it is NULL +) + Selects pairs from a relation R(x,y) (given as a BDD) in such a way that a + given x appears in one pair only. Uses a priority function to determine + which y should be paired to a given x. Cudd_PrioritySelect returns a pointer + to the selected function if successful; NULL otherwise. Three of the + arguments--x, y, and z--are vectors of BDD variables. The first two are the + variables on which R depends. The third vector is a vector of auxiliary + variables, used during the computation. This vector is optional. If a NULL + value is passed instead, Cudd_PrioritySelect will create the working + variables on the fly. The sizes of x and y (and z if it is not NULL) should + equal n. The priority function Pi can be passed as a BDD, or can be built by + Cudd_PrioritySelect. If NULL is passed instead of a DdNode *, parameter + Pifunc is used by Cudd_PrioritySelect to build a BDD for the priority + function. (Pifunc is a pointer to a C function.) If Pi is not NULL, then + Pifunc is ignored. Pifunc should have the same interface as the standard + priority functions (e.g., Cudd_Dxygtdxz). Cudd_PrioritySelect and + Cudd_CProjection can sometimes be used interchangeably. Specifically, + calling Cudd_PrioritySelect with Cudd_Xgty as Pifunc produces the same + result as calling Cudd_CProjection with the all-zero minterm as reference + minterm. However, depending on the application, one or the other may be + preferable: When extracting representatives from an equivalence + relation, Cudd_CProjection has the advantage of nor requiring the auxiliary + variables. When computing matchings in general bipartite graphs, + Cudd_PrioritySelect normally obtains better results because it can use more + powerful matching schemes (e.g., Cudd_Dxygtdxz). + + Side Effects: If called with z == NULL, will create new variables in the + manager. + +void +Cudd_Quit( + DdManager * unique +) + Deletes resources associated with a DD manager and resets the global + statistical counters. (Otherwise, another manaqger subsequently created + would inherit the stats of this one.) + + Side Effects: None + +long +Cudd_Random( + +) + Portable number generator based on ran2 from "Numerical Recipes in C." It is + a long period (> 2 * 10^18) random number generator of L'Ecuyer with Bays- + Durham shuffle. Returns a long integer uniformly distributed between 0 and + 2147483561 (inclusive of the endpoint values). The random generator can be + explicitly initialized by calling Cudd_Srandom. If no explicit + initialization is performed, then the seed 1 is assumed. + + Side Effects: None + +int +Cudd_ReadArcviolation( + DdManager * dd +) + Returns the current value of the arcviolation parameter. This parameter is + used in group sifting to decide how many arcs into y not coming + from x are tolerable when checking for aggregation due to + extended symmetry. The value should be between 0 and 100. A small value + causes fewer variables to be aggregated. The default value is 0. + + Side Effects: None + +DdNode * +Cudd_ReadBackground( + DdManager * dd +) + Reads the background constant of the manager. + + Side Effects: None + +double +Cudd_ReadCacheHits( + DdManager * dd +) + Returns the number of cache hits. + + Side Effects: None + +double +Cudd_ReadCacheLookUps( + DdManager * dd +) + Returns the number of cache look-ups. + + Side Effects: None + +unsigned int +Cudd_ReadCacheSlots( + DdManager * dd +) + Reads the number of slots in the cache. + + Side Effects: None + +double +Cudd_ReadCacheUsedSlots( + DdManager * dd +) + Reads the fraction of used slots in the cache. The unused slots are those in + which no valid data is stored. Garbage collection, variable reordering, and + cache resizing may cause used slots to become unused. + + Side Effects: None + +unsigned int +Cudd_ReadDead( + DdManager * dd +) + Returns the number of dead nodes in the unique table. + + Side Effects: None + +unsigned long +Cudd_ReadElapsedTime( + DdManager * unique +) + Returns the time elapsed since the start time of the manager. + + Side Effects: None + +CUDD_VALUE_TYPE +Cudd_ReadEpsilon( + DdManager * dd +) + Reads the epsilon parameter of the manager. The epsilon parameter control + the comparison between floating point numbers. + + Side Effects: None + +Cudd_ErrorType +Cudd_ReadErrorCode( + DdManager * dd +) + Returns the code of the last error. The error codes are defined in cudd.h. + + Side Effects: None + +long +Cudd_ReadGarbageCollectionTime( + DdManager * dd +) + Returns the number of milliseconds spent doing garbage collection since the + manager was initialized. + + Side Effects: None + +int +Cudd_ReadGarbageCollections( + DdManager * dd +) + Returns the number of times garbage collection has occurred in the manager. + The number includes both the calls from reordering procedures and those + caused by requests to create new nodes. + + Side Effects: None + +Cudd_AggregationType +Cudd_ReadGroupcheck( + DdManager * dd +) + Reads the groupcheck parameter of the manager. The groupcheck parameter + determines the aggregation criterion in group sifting. + + Side Effects: None + +int +Cudd_ReadInvPermZdd( + DdManager * dd, + int i +) + Returns the index of the ZDD variable currently in the i-th position of the + order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; + otherwise, if the index is out of bounds returns -1. + + Side Effects: None + +int +Cudd_ReadInvPerm( + DdManager * dd, + int i +) + Returns the index of the variable currently in the i-th position of the + order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; + otherwise, if the index is out of bounds returns -1. + + Side Effects: None + +int +Cudd_ReadIthClause( + DdTlcInfo * tlc, + int i, + DdHalfWord * var1, + DdHalfWord * var2, + int * phase1, + int * phase2 +) + Accesses the i-th clause of a DD given the clause set which must be already + computed. Returns 1 if successful; 0 if i is out of range, or in case of + error. + + Side Effects: the four components of a clause are returned as side effects. + +unsigned int +Cudd_ReadKeys( + DdManager * dd +) + Returns the total number of nodes currently in the unique table, including + the dead nodes. + + Side Effects: None + +int +Cudd_ReadLinear( + DdManager * table, CUDD manager + int x, row index + int y column index +) + Reads an entry of the linear transform matrix. + + Side Effects: none + +DdNode * +Cudd_ReadLogicZero( + DdManager * dd +) + Returns the zero constant of the manager. The logic zero constant is the + complement of the one constant, and is distinct from the arithmetic zero. + + Side Effects: None + +unsigned int +Cudd_ReadLooseUpTo( + DdManager * dd +) + Reads the looseUpTo parameter of the manager. + + Side Effects: None + +unsigned int +Cudd_ReadMaxCacheHard( + DdManager * dd +) + Reads the maxCacheHard parameter of the manager. + + Side Effects: None + +unsigned int +Cudd_ReadMaxCache( + DdManager * dd +) + Returns the soft limit for the cache size. + + Side Effects: None + +double +Cudd_ReadMaxGrowthAlternate( + DdManager * dd +) + Reads the maxGrowthAlt parameter of the manager. This parameter is analogous + to the maxGrowth paramter, and is used every given number of reorderings + instead of maxGrowth. The number of reorderings is set with + Cudd_SetReorderingCycle. If the number of reorderings is 0 (default) + maxGrowthAlt is never used. + + Side Effects: None + +double +Cudd_ReadMaxGrowth( + DdManager * dd +) + Reads the maxGrowth parameter of the manager. This parameter determines how + much the number of nodes can grow during sifting of a variable. Overall, + sifting never increases the size of the decision diagrams. This parameter + only refers to intermediate results. A lower value will speed up sifting, + possibly at the expense of quality. + + Side Effects: None + +unsigned int +Cudd_ReadMaxLive( + DdManager * dd +) + Reads the maximum allowed number of live nodes. When this number is + exceeded, the package returns NULL. + + Side Effects: none + +unsigned long +Cudd_ReadMaxMemory( + DdManager * dd +) + Reads the maximum allowed memory. When this number is exceeded, the package + returns NULL. + + Side Effects: none + +unsigned int +Cudd_ReadMaxReorderings( + DdManager * dd +) + Returns the maximum number of times reordering may be invoked in this + manager. + + Side Effects: None + +unsigned long +Cudd_ReadMemoryInUse( + DdManager * dd +) + Returns the memory in use by the manager measured in bytes. + + Side Effects: None + +unsigned int +Cudd_ReadMinDead( + DdManager * dd +) + Reads the minDead parameter of the manager. The minDead parameter is used by + the package to decide whether to collect garbage or resize a subtable of the + unique table when the subtable becomes too full. The application can + indirectly control the value of minDead by setting the looseUpTo parameter. + + Side Effects: None + +unsigned int +Cudd_ReadMinHit( + DdManager * dd +) + Reads the hit rate that causes resizinig of the computed table. + + Side Effects: None + +DdNode * +Cudd_ReadMinusInfinity( + DdManager * dd +) + Reads the minus-infinity constant from the manager. + + Side Effects: None + +unsigned int +Cudd_ReadNextReordering( + DdManager * dd +) + Returns the threshold for the next dynamic reordering. The threshold is in + terms of number of nodes and is in effect only if reordering is enabled. The + count does not include the dead nodes, unless the countDead parameter of the + manager has been changed from its default setting. + + Side Effects: None + +long +Cudd_ReadNodeCount( + DdManager * dd +) + Reports the number of live nodes in BDDs and ADDs. This number does not + include the isolated projection functions and the unused constants. These + nodes that are not counted are not part of the DDs manipulated by the + application. + + Side Effects: None + +double +Cudd_ReadNodesDropped( + DdManager * dd +) + Returns the number of nodes killed by dereferencing if the keeping of this + statistic is enabled; -1 otherwise. This statistic is enabled only if the + package is compiled with DD_STATS defined. + + Side Effects: None + +double +Cudd_ReadNodesFreed( + DdManager * dd +) + Returns the number of nodes returned to the free list if the keeping of this + statistic is enabled; -1 otherwise. This statistic is enabled only if the + package is compiled with DD_STATS defined. + + Side Effects: None + +int +Cudd_ReadNumberXovers( + DdManager * dd +) + Reads the current number of crossovers used by the genetic algorithm for + variable reordering. A larger number of crossovers will cause the genetic + algorithm to take more time, but will generally produce better results. The + default value is 0, in which case the package uses three times the number of + variables as number of crossovers, with a maximum of 60. + + Side Effects: None + +DdNode * +Cudd_ReadOne( + DdManager * dd +) + Returns the one constant of the manager. The one constant is common to ADDs + and BDDs. + + Side Effects: None + +unsigned int +Cudd_ReadOrderRandomization( + DdManager * dd +) + Returns the order randomization factor. If non-zero this factor is used to + determine a perturbation of the next reordering threshold. Larger factors + cause larger perturbations. + + Side Effects: None + +int +Cudd_ReadPeakLiveNodeCount( + DdManager * dd +) + Reports the peak number of live nodes. + + Side Effects: None + +long +Cudd_ReadPeakNodeCount( + DdManager * dd +) + Reports the peak number of nodes. This number includes node on the free + list. At the peak, the number of nodes on the free list is guaranteed to be + less than DD_MEM_CHUNK. + + Side Effects: None + +int +Cudd_ReadPermZdd( + DdManager * dd, + int i +) + Returns the current position of the i-th ZDD variable in the order. If the + index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index + is out of bounds returns -1. + + Side Effects: None + +int +Cudd_ReadPerm( + DdManager * dd, + int i +) + Returns the current position of the i-th variable in the order. If the index + is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index is + out of bounds returns -1. + + Side Effects: None + +DdNode * +Cudd_ReadPlusInfinity( + DdManager * dd +) + Reads the plus-infinity constant from the manager. + + Side Effects: None + +int +Cudd_ReadPopulationSize( + DdManager * dd +) + Reads the current size of the population used by the genetic algorithm for + variable reordering. A larger population size will cause the genetic + algorithm to take more time, but will generally produce better results. The + default value is 0, in which case the package uses three times the number of + variables as population size, with a maximum of 120. + + Side Effects: None + +int +Cudd_ReadRecomb( + DdManager * dd +) + Returns the current value of the recombination parameter used in group + sifting. A larger (positive) value makes the aggregation of variables due to + the second difference criterion more likely. A smaller (negative) value + makes aggregation less likely. + + Side Effects: None + +double +Cudd_ReadRecursiveCalls( + DdManager * dd +) + Returns the number of recursive calls if the package is compiled with + DD_COUNT defined. + + Side Effects: None + +int +Cudd_ReadReorderingCycle( + DdManager * dd +) + Reads the reordCycle parameter of the manager. This parameter determines how + often the alternate threshold on maximum growth is used in reordering. + + Side Effects: None + +long +Cudd_ReadReorderingTime( + DdManager * dd +) + Returns the number of milliseconds spent reordering variables since the + manager was initialized. The time spent in collecting garbage before + reordering is included. + + Side Effects: None + +unsigned int +Cudd_ReadReorderings( + DdManager * dd +) + Returns the number of times reordering has occurred in the manager. The + number includes both the calls to Cudd_ReduceHeap from the application + program and those automatically performed by the package. However, calls + that do not even initiate reordering are not counted. A call may not + initiate reordering if there are fewer than minsize live nodes in the + manager, or if CUDD_REORDER_NONE is specified as reordering method. The + calls to Cudd_ShuffleHeap are not counted. + + Side Effects: None + +int +Cudd_ReadSiftMaxSwap( + DdManager * dd +) + Reads the siftMaxSwap parameter of the manager. This parameter gives the + maximum number of swaps that will be attempted for each invocation of + sifting. The real number of swaps may exceed the set limit because the + package will always complete the sifting of the variable that causes the + limit to be reached. + + Side Effects: None + +int +Cudd_ReadSiftMaxVar( + DdManager * dd +) + Reads the siftMaxVar parameter of the manager. This parameter gives the + maximum number of variables that will be sifted for each invocation of + sifting. + + Side Effects: None + +int +Cudd_ReadSize( + DdManager * dd +) + Returns the number of BDD variables in existance. + + Side Effects: None + +unsigned int +Cudd_ReadSlots( + DdManager * dd +) + Returns the total number of slots of the unique table. This number ismainly + for diagnostic purposes. + + Side Effects: None + +unsigned long +Cudd_ReadStartTime( + DdManager * unique +) + Returns the start time of the manager. This is initially set to the number + of milliseconds since the program started, but may be reset by the + application. + + Side Effects: None + +FILE * +Cudd_ReadStderr( + DdManager * dd +) + Reads the stderr of a manager. This is the file pointer to which messages + normally going to stderr are written. It is initialized to stderr. + Cudd_SetStderr allows the application to redirect it. + + Side Effects: None + +FILE * +Cudd_ReadStdout( + DdManager * dd +) + Reads the stdout of a manager. This is the file pointer to which messages + normally going to stdout are written. It is initialized to stdout. + Cudd_SetStdout allows the application to redirect it. + + Side Effects: None + +double +Cudd_ReadSwapSteps( + DdManager * dd +) + Reads the number of elementary reordering steps. + + Side Effects: none + +int +Cudd_ReadSymmviolation( + DdManager * dd +) + Returns the current value of the symmviolation parameter. This parameter is + used in group sifting to decide how many violations to the symmetry + conditions f10 = f01 or f11 = f00 are tolerable + when checking for aggregation due to extended symmetry. The value should be + between 0 and 100. A small value causes fewer variables to be aggregated. + The default value is 0. + + Side Effects: None + +unsigned long +Cudd_ReadTimeLimit( + DdManager * unique +) + Returns the time limit for the manager. This is initially set to a very + large number, but may be reset by the application. + + Side Effects: None + +MtrNode * +Cudd_ReadTree( + DdManager * dd +) + Returns the variable group tree of the manager. + + Side Effects: None + +double +Cudd_ReadUniqueLinks( + DdManager * dd +) + Returns the number of links followed during look-ups in the unique table if + the keeping of this statistic is enabled; -1 otherwise. If an item is found + in the first position of its collision list, the number of links followed is + taken to be 0. If it is in second position, the number of links is 1, and so + on. This statistic is enabled only if the package is compiled with + DD_UNIQUE_PROFILE defined. + + Side Effects: None + +double +Cudd_ReadUniqueLookUps( + DdManager * dd +) + Returns the number of look-ups in the unique table if the keeping of this + statistic is enabled; -1 otherwise. This statistic is enabled only if the + package is compiled with DD_UNIQUE_PROFILE defined. + + Side Effects: None + +double +Cudd_ReadUsedSlots( + DdManager * dd +) + Reads the fraction of used slots in the unique table. The unused slots are + those in which no valid data is stored. Garbage collection, variable + reordering, and subtable resizing may cause used slots to become unused. + + Side Effects: None + +DdNode * +Cudd_ReadVars( + DdManager * dd, + int i +) + Returns the i-th element of the vars array if it falls within the array + bounds; NULL otherwise. If i is the index of an existing variable, this + function produces the same result as Cudd_bddIthVar. However, if the i-th + var does not exist yet, Cudd_bddIthVar will create it, whereas Cudd_ReadVars + will not. + + Side Effects: None + +DdNode * +Cudd_ReadZddOne( + DdManager * dd, + int i +) + Returns the ZDD for the constant 1 function. The representation of the + constant 1 function as a ZDD depends on how many variables it (nominally) + depends on. The index of the topmost variable in the support is given as + argument i. + + Side Effects: None + +int +Cudd_ReadZddSize( + DdManager * dd +) + Returns the number of ZDD variables in existance. + + Side Effects: None + +MtrNode * +Cudd_ReadZddTree( + DdManager * dd +) + Returns the variable group tree of the manager. + + Side Effects: None + +DdNode * +Cudd_ReadZero( + DdManager * dd +) + Returns the zero constant of the manager. The zero constant is the + arithmetic zero, rather than the logic zero. The latter is the complement of + the one constant. + + Side Effects: None + +void +Cudd_RecursiveDerefZdd( + DdManager * table, + DdNode * n +) + Decreases the reference count of ZDD node n. If n dies, recursively + decreases the reference counts of its children. It is used to dispose of a + ZDD that is no longer needed. + + Side Effects: None + +void +Cudd_RecursiveDeref( + DdManager * table, + DdNode * n +) + Decreases the reference count of node n. If n dies, recursively decreases + the reference counts of its children. It is used to dispose of a DD that is + no longer needed. + + Side Effects: None + +int +Cudd_ReduceHeap( + DdManager * table, DD manager + Cudd_ReorderingTy heuristic, method used for reordering + int minsize bound below which no reordering occurs +) + Main dynamic reordering routine. Calls one of the possible reordering + procedures: Swapping Sifting Symmetric Sifting Group + Sifting Window Permutation Simulated Annealing Genetic Algorithm + Dynamic Programming (exact) For sifting, symmetric sifting, group + sifting, and window permutation it is possible to request reordering to + convergence. The core of all methods is the reordering procedure + cuddSwapInPlace() which swaps two adjacent variables and is based on + Rudell's paper. Returns 1 in case of success; 0 otherwise. In the case of + symmetric sifting (with and without convergence) returns 1 plus the number + of symmetric variables, in case of success. + + Side Effects: Changes the variable order for all diagrams and clears the + cache. + +void +Cudd_Ref( + DdNode * n +) + Increases the reference count of a node, if it is not saturated. + + Side Effects: None + +DdNode * +Cudd_RemapOverApprox( + DdManager * dd, manager + DdNode * f, function to be superset + int numVars, number of variables in the support of f + int threshold, when to stop approximation + double quality minimum improvement for accepted changes +) + Extracts a dense superset from a BDD. The procedure is identical to the + underapproximation procedure except for the fact that it works on the + complement of the given function. Extracting the subset of the complement + function is equivalent to extracting the superset of the function. Returns a + pointer to the BDD of the superset if successful. NULL if intermediate + result causes the procedure to run out of memory. The parameter numVars is + the maximum number of variables to be used in minterm calculation. The + optimal number should be as close as possible to the size of the support of + f. However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is larger + than 1023, it will overflow. If a 0 parameter is passed then the procedure + will compute a value which will avoid overflow but will cause underflow with + 2046 variables or more. + + Side Effects: None + +DdNode * +Cudd_RemapUnderApprox( + DdManager * dd, manager + DdNode * f, function to be subset + int numVars, number of variables in the support of f + int threshold, when to stop approximation + double quality minimum improvement for accepted changes +) + Extracts a dense subset from a BDD. This procedure uses a remapping + technique and density as the cost function. Returns a pointer to the BDD of + the subset if successful. NULL if the procedure runs out of memory. The + parameter numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to the size + of the support of f. However, it is safe to pass the value returned by + Cudd_ReadSize for numVars when the number of variables is under 1023. If + numVars is larger than 1023, it will cause overflow. If a 0 parameter is + passed then the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more. + + Side Effects: None + +int +Cudd_RemoveHook( + DdManager * dd, + DD_HFP f, + Cudd_HookType where +) + Removes a function from a hook. A hook is a list of application-provided + functions called on certain occasions by the package. Returns 1 if + successful; 0 the function was not in the list. + + Side Effects: None + +int +Cudd_ReorderingReporting( + DdManager * dd +) + Returns 1 if reporting of reordering stats is enabled; 0 otherwise. + + Side Effects: none + +int +Cudd_ReorderingStatusZdd( + DdManager * unique, + Cudd_ReorderingTy method +) + Reports the status of automatic dynamic reordering of ZDDs. Parameter method + is set to the ZDD reordering method currently selected. Returns 1 if + automatic reordering is enabled; 0 otherwise. + + Side Effects: Parameter method is set to the ZDD reordering method currently + selected. + +int +Cudd_ReorderingStatus( + DdManager * unique, + Cudd_ReorderingTy method +) + Reports the status of automatic dynamic reordering of BDDs and ADDs. + Parameter method is set to the reordering method currently selected. Returns + 1 if automatic reordering is enabled; 0 otherwise. + + Side Effects: Parameter method is set to the reordering method currently + selected. + +int +Cudd_Reserve( + DdManager * manager, + int amount +) + Expand a manager by a specified number of subtables without actually + creating new variables. This function can be used to reduce the frequency of + resizing when an estimate of the number of variables is available. One would + call this function instead of passing the number of variables to Cudd_Init + if variables should not be created right away of if the estimate on their + number became available only after the manager has been created. Returns 1 + if successful; 0 otherwise. + + Side Effects: None + +void +Cudd_ResetStartTime( + DdManager * unique +) + Resets the start time of the manager. + + Side Effects: None + +void +Cudd_SetArcviolation( + DdManager * dd, + int arcviolation +) + Sets the value of the arcviolation parameter. This parameter is used in + group sifting to decide how many arcs into y not coming from + x are tolerable when checking for aggregation due to extended + symmetry. The value should be between 0 and 100. A small value causes fewer + variables to be aggregated. The default value is 0. + + Side Effects: None + +void +Cudd_SetBackground( + DdManager * dd, + DdNode * bck +) + Sets the background constant of the manager. It assumes that the DdNode + pointer bck is already referenced. + + Side Effects: None + +void +Cudd_SetEpsilon( + DdManager * dd, + CUDD_VALUE_TYPE ep +) + Sets the epsilon parameter of the manager to ep. The epsilon parameter + control the comparison between floating point numbers. + + Side Effects: None + +void +Cudd_SetGroupcheck( + DdManager * dd, + Cudd_AggregationT gc +) + Sets the parameter groupcheck of the manager to gc. The groupcheck parameter + determines the aggregation criterion in group sifting. + + Side Effects: None + +void +Cudd_SetLooseUpTo( + DdManager * dd, + unsigned int lut +) + Sets the looseUpTo parameter of the manager. This parameter of the manager + controls the threshold beyond which no fast growth of the unique table is + allowed. The threshold is given as a number of slots. If the value passed to + this function is 0, the function determines a suitable value based on the + available memory. + + Side Effects: None + +void +Cudd_SetMaxCacheHard( + DdManager * dd, + unsigned int mc +) + Sets the maxCacheHard parameter of the manager. The cache cannot grow larger + than maxCacheHard entries. This parameter allows an application to control + the trade-off of memory versus speed. If the value passed to this function + is 0, the function determines a suitable maximum cache size based on the + available memory. + + Side Effects: None + +void +Cudd_SetMaxGrowthAlternate( + DdManager * dd, + double mg +) + Sets the maxGrowthAlt parameter of the manager. This parameter is analogous + to the maxGrowth paramter, and is used every given number of reorderings + instead of maxGrowth. The number of reorderings is set with + Cudd_SetReorderingCycle. If the number of reorderings is 0 (default) + maxGrowthAlt is never used. + + Side Effects: None + +void +Cudd_SetMaxGrowth( + DdManager * dd, + double mg +) + Sets the maxGrowth parameter of the manager. This parameter determines how + much the number of nodes can grow during sifting of a variable. Overall, + sifting never increases the size of the decision diagrams. This parameter + only refers to intermediate results. A lower value will speed up sifting, + possibly at the expense of quality. + + Side Effects: None + +void +Cudd_SetMaxLive( + DdManager * dd, + unsigned int maxLive +) + Sets the maximum allowed number of live nodes. When this number is exceeded, + the package returns NULL. + + Side Effects: none + +void +Cudd_SetMaxMemory( + DdManager * dd, + unsigned long maxMemory +) + Sets the maximum allowed memory. When this number is exceeded, the package + returns NULL. + + Side Effects: none + +void +Cudd_SetMaxReorderings( + DdManager * dd, + unsigned int mr +) + Sets the maximum number of times reordering may be invoked in this manager. + The default value is (practically) infinite. + + Side Effects: None + +void +Cudd_SetMinHit( + DdManager * dd, + unsigned int hr +) + Sets the minHit parameter of the manager. This parameter controls the + resizing of the computed table. If the hit rate is larger than the specified + value, and the cache is not already too large, then its size is doubled. + + Side Effects: None + +void +Cudd_SetNextReordering( + DdManager * dd, + unsigned int next +) + Sets the threshold for the next dynamic reordering. The threshold is in + terms of number of nodes and is in effect only if reordering is enabled. The + count does not include the dead nodes, unless the countDead parameter of the + manager has been changed from its default setting. + + Side Effects: None + +void +Cudd_SetNumberXovers( + DdManager * dd, + int numberXovers +) + Sets the number of crossovers used by the genetic algorithm for variable + reordering. A larger number of crossovers will cause the genetic algorithm + to take more time, but will generally produce better results. The default + value is 0, in which case the package uses three times the number of + variables as number of crossovers, with a maximum of 60. + + Side Effects: None + +void +Cudd_SetOrderRandomization( + DdManager * dd, + unsigned int factor +) + Sets the order randomization factor. + + Side Effects: None + +void +Cudd_SetPopulationSize( + DdManager * dd, + int populationSize +) + Sets the size of the population used by the genetic algorithm for variable + reordering. A larger population size will cause the genetic algorithm to + take more time, but will generally produce better results. The default value + is 0, in which case the package uses three times the number of variables as + population size, with a maximum of 120. + + Side Effects: Changes the manager. + +void +Cudd_SetRecomb( + DdManager * dd, + int recomb +) + Sets the value of the recombination parameter used in group sifting. A + larger (positive) value makes the aggregation of variables due to the second + difference criterion more likely. A smaller (negative) value makes + aggregation less likely. The default value is 0. + + Side Effects: Changes the manager. + +void +Cudd_SetReorderingCycle( + DdManager * dd, + int cycle +) + Sets the reordCycle parameter of the manager. This parameter determines how + often the alternate threshold on maximum growth is used in reordering. + + Side Effects: None + +void +Cudd_SetSiftMaxSwap( + DdManager * dd, + int sms +) + Sets the siftMaxSwap parameter of the manager. This parameter gives the + maximum number of swaps that will be attempted for each invocation of + sifting. The real number of swaps may exceed the set limit because the + package will always complete the sifting of the variable that causes the + limit to be reached. + + Side Effects: None + +void +Cudd_SetSiftMaxVar( + DdManager * dd, + int smv +) + Sets the siftMaxVar parameter of the manager. This parameter gives the + maximum number of variables that will be sifted for each invocation of + sifting. + + Side Effects: None + +void +Cudd_SetStartTime( + DdManager * unique, + unsigned long st +) + Sets the start time of the manager. + + Side Effects: None + +void +Cudd_SetStderr( + DdManager * dd, + FILE * fp +) + Sets the stderr of a manager. + + Side Effects: None + +void +Cudd_SetStdout( + DdManager * dd, + FILE * fp +) + Sets the stdout of a manager. + + Side Effects: None + +void +Cudd_SetSymmviolation( + DdManager * dd, + int symmviolation +) + Sets the value of the symmviolation parameter. This parameter is used in + group sifting to decide how many violations to the symmetry conditions + f10 = f01 or f11 = f00 are tolerable when checking + for aggregation due to extended symmetry. The value should be between 0 and + 100. A small value causes fewer variables to be aggregated. The default + value is 0. + + Side Effects: Changes the manager. + +void +Cudd_SetTimeLimit( + DdManager * unique, + unsigned long tl +) + Sets the time limit for the manager. + + Side Effects: None + +void +Cudd_SetTree( + DdManager * dd, + MtrNode * tree +) + Sets the variable group tree of the manager. + + Side Effects: None + +int +Cudd_SetVarMap( + DdManager * manager, DD manager + DdNode ** x, first array of variables + DdNode ** y, second array of variables + int n length of both arrays +) + Registers with the manager a variable mapping described by two sets of + variables. This variable mapping is then used by functions like + Cudd_bddVarMap. This function is convenient for those applications that + perform the same mapping several times. However, if several different + permutations are used, it may be more efficient not to rely on the + registered mapping, because changing mapping causes the cache to be cleared. + (The initial setting, however, does not clear the cache.) The two sets of + variables (x and y) must have the same size (x and y). The size is given by + n. The two sets of variables are normally disjoint, but this restriction is + not imposeded by the function. When new variables are created, the map is + automatically extended (each new variable maps to itself). The typical use, + however, is to wait until all variables are created, and then create the + map. Returns 1 if the mapping is successfully registered with the manager; 0 + otherwise. + + Side Effects: Modifies the manager. May clear the cache. + +void +Cudd_SetZddTree( + DdManager * dd, + MtrNode * tree +) + Sets the ZDD variable group tree of the manager. + + Side Effects: None + +int +Cudd_SharingSize( + DdNode ** nodeArray, + int n +) + Counts the number of nodes in an array of DDs. Shared nodes are counted only + once. Returns the total number of nodes. + + Side Effects: None + +int +Cudd_ShortestLength( + DdManager * manager, + DdNode * f, + int * weight +) + Find the length of the shortest path(s) in a DD. f is the DD we want to get + the shortest path for; weight[i] is the weight of the THEN edge coming from + the node whose index is i. All ELSE edges have 0 weight. Returns the length + of the shortest path(s) if such a path is found; a large number if the + function is identically 0, and CUDD_OUT_OF_MEM in case of failure. + + Side Effects: None + +DdNode * +Cudd_ShortestPath( + DdManager * manager, + DdNode * f, + int * weight, + int * support, + int * length +) + Finds a shortest path in a DD. f is the DD we want to get the shortest path + for; weight[i] is the weight of the THEN arc coming from the node whose + index is i. If weight is NULL, then unit weights are assumed for all THEN + arcs. All ELSE arcs have 0 weight. If non-NULL, both weight and support + should point to arrays with at least as many entries as there are variables + in the manager. Returns the shortest path as the BDD of a cube. + + Side Effects: support contains on return the true support of f. If support + is NULL on entry, then Cudd_ShortestPath does not compute the true support + info. length contains the length of the path. + +int +Cudd_ShuffleHeap( + DdManager * table, DD manager + int * permutation required variable permutation +) + Reorders variables according to given permutation. The i-th entry of the + permutation array contains the index of the variable that should be brought + to the i-th level. The size of the array should be equal or greater to the + number of variables currently in use. Returns 1 in case of success; 0 + otherwise. + + Side Effects: Changes the variable order for all diagrams and clears the + cache. + +DdNode * +Cudd_SolveEqn( + DdManager * bdd, + DdNode * F, the left-hand side of the equation + DdNode * Y, the cube of the y variables + DdNode ** G, the array of solutions (return parameter) + int ** yIndex, index of y variables + int n numbers of unknowns +) + Implements the solution for F(x,y) = 0. The return value is the consistency + condition. The y variables are the unknowns and the remaining variables are + the parameters. Returns the consistency condition if successful; NULL + otherwise. Cudd_SolveEqn allocates an array and fills it with the indices of + the unknowns. This array is used by Cudd_VerifySol. + + Side Effects: The solution is returned in G; the indices of the y variables + are returned in yIndex. + +DdNode * +Cudd_SplitSet( + DdManager * manager, + DdNode * S, + DdNode ** xVars, + int n, + double m +) + Returns m minterms from a BDD whose support has n + variables at most. The procedure tries to create as few extra nodes as + possible. The function represented by S depends on at most + n of the variables in xVars. Returns a BDD with + m minterms of the on-set of S if successful; NULL otherwise. + + Side Effects: None + +void +Cudd_Srandom( + long seed +) + Initializer for the portable number generator based on ran2 in "Numerical + Recipes in C." The input is the seed for the generator. If it is negative, + its absolute value is taken as seed. If it is 0, then 1 is taken as seed. + The initialized sets up the two recurrences used to generate a long-period + stream, and sets up the shuffle table. + + Side Effects: None + +int +Cudd_StdPostReordHook( + DdManager * dd, + const char * str, + void * data +) + Sample hook function to call after reordering. Prints on the manager's + stdout final size and reordering time. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_StdPreReordHook( + DdManager * dd, + const char * str, + void * data +) + Sample hook function to call before reordering. Prints on the manager's + stdout reordering method and initial size. Returns 1 if successful; 0 + otherwise. + + Side Effects: None + +DdNode * +Cudd_SubsetCompress( + DdManager * dd, manager + DdNode * f, BDD whose subset is sought + int nvars, number of variables in the support of f + int threshold maximum number of nodes in the subset +) + Finds a dense subset of BDD f. Density is the ratio of number + of minterms to number of nodes. Uses several techniques in series. It is + more expensive than other subsetting procedures, but often produces better + results. See Cudd_SubsetShortPaths for a description of the threshold and + nvars parameters. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_SubsetHeavyBranch( + DdManager * dd, manager + DdNode * f, function to be subset + int numVars, number of variables in the support of f + int threshold maximum number of nodes in the subset +) + Extracts a dense subset from a BDD. This procedure builds a subset by + throwing away one of the children of each node, starting from the root, + until the result is small enough. The child that is eliminated from the + result is the one that contributes the fewer minterms. Returns a pointer to + the BDD of the subset if successful. NULL if the procedure runs out of + memory. The parameter numVars is the maximum number of variables to be used + in minterm calculation and node count calculation. The optimal number should + be as close as possible to the size of the support of f. However, it is safe + to pass the value returned by Cudd_ReadSize for numVars when the number of + variables is under 1023. If numVars is larger than 1023, it will overflow. + If a 0 parameter is passed then the procedure will compute a value which + will avoid overflow but will cause underflow with 2046 variables or more. + + Side Effects: None + +DdNode * +Cudd_SubsetShortPaths( + DdManager * dd, manager + DdNode * f, function to be subset + int numVars, number of variables in the support of f + int threshold, maximum number of nodes in the subset + int hardlimit flag: 1 if threshold is a hard limit +) + Extracts a dense subset from a BDD. This procedure tries to preserve the + shortest paths of the input BDD, because they give many minterms and + contribute few nodes. This procedure may increase the number of nodes in + trying to create the subset or reduce the number of nodes due to + recombination as compared to the original BDD. Hence the threshold may not + be strictly adhered to. In practice, recombination overshadows the increase + in the number of nodes and results in small BDDs as compared to the + threshold. The hardlimit specifies whether threshold needs to be strictly + adhered to. If it is set to 1, the procedure ensures that result is never + larger than the specified limit but may be considerably less than the + threshold. Returns a pointer to the BDD for the subset if successful; NULL + otherwise. The value for numVars should be as close as possible to the size + of the support of f for better efficiency. However, it is safe to pass the + value returned by Cudd_ReadSize for numVars. If 0 is passed, then the value + returned by Cudd_ReadSize is used. + + Side Effects: None + +DdNode * +Cudd_SubsetWithMaskVars( + DdManager * dd, manager + DdNode * f, function from which to pick a cube + DdNode ** vars, array of variables + int nvars, size of vars + DdNode ** maskVars, array of variables + int mvars size of maskVars +) + Extracts a subset from a BDD in the following procedure. 1. Compute the + weight for each mask variable by counting the number of minterms for both + positive and negative cofactors of the BDD with respect to each mask + variable. (weight = #positive - #negative) 2. Find a representative cube of + the BDD by using the weight. From the top variable of the BDD, for each + variable, if the weight is greater than 0.0, choose THEN branch, othereise + ELSE branch, until meeting the constant 1. 3. Quantify out the variables not + in maskVars from the representative cube and if a variable in maskVars is + don't care, replace the variable with a constant(1 or 0) depending on the + weight. 4. Make a subset of the BDD by multiplying with the modified cube. + + Side Effects: None + +DdNode * +Cudd_SupersetCompress( + DdManager * dd, manager + DdNode * f, BDD whose superset is sought + int nvars, number of variables in the support of f + int threshold maximum number of nodes in the superset +) + Finds a dense superset of BDD f. Density is the ratio of number + of minterms to number of nodes. Uses several techniques in series. It is + more expensive than other supersetting procedures, but often produces better + results. See Cudd_SupersetShortPaths for a description of the threshold and + nvars parameters. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_SupersetHeavyBranch( + DdManager * dd, manager + DdNode * f, function to be superset + int numVars, number of variables in the support of f + int threshold maximum number of nodes in the superset +) + Extracts a dense superset from a BDD. The procedure is identical to the + subset procedure except for the fact that it receives the complement of the + given function. Extracting the subset of the complement function is + equivalent to extracting the superset of the function. This procedure builds + a superset by throwing away one of the children of each node starting from + the root of the complement function, until the result is small enough. The + child that is eliminated from the result is the one that contributes the + fewer minterms. Returns a pointer to the BDD of the superset if successful. + NULL if intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in minterm + calculation and node count calculation. The optimal number should be as + close as possible to the size of the support of f. However, it is safe to + pass the value returned by Cudd_ReadSize for numVars when the number of + variables is under 1023. If numVars is larger than 1023, it will overflow. + If a 0 parameter is passed then the procedure will compute a value which + will avoid overflow but will cause underflow with 2046 variables or more. + + Side Effects: None + +DdNode * +Cudd_SupersetShortPaths( + DdManager * dd, manager + DdNode * f, function to be superset + int numVars, number of variables in the support of f + int threshold, maximum number of nodes in the subset + int hardlimit flag: 1 if threshold is a hard limit +) + Extracts a dense superset from a BDD. The procedure is identical to the + subset procedure except for the fact that it receives the complement of the + given function. Extracting the subset of the complement function is + equivalent to extracting the superset of the function. This procedure tries + to preserve the shortest paths of the complement BDD, because they give many + minterms and contribute few nodes. This procedure may increase the number of + nodes in trying to create the superset or reduce the number of nodes due to + recombination as compared to the original BDD. Hence the threshold may not + be strictly adhered to. In practice, recombination overshadows the increase + in the number of nodes and results in small BDDs as compared to the + threshold. The hardlimit specifies whether threshold needs to be strictly + adhered to. If it is set to 1, the procedure ensures that result is never + larger than the specified limit but may be considerably less than the + threshold. Returns a pointer to the BDD for the superset if successful; NULL + otherwise. The value for numVars should be as close as possible to the size + of the support of f for better efficiency. However, it is safe to pass the + value returned by Cudd_ReadSize for numVar. If 0 is passed, then the value + returned by Cudd_ReadSize is used. + + Side Effects: None + +int * +Cudd_SupportIndex( + DdManager * dd, manager + DdNode * f DD whose support is sought +) + Finds the variables on which a DD depends. Returns an index array of the + variables if successful; NULL otherwise. The size of the array equals the + number of variables in the manager. Each entry of the array is 1 if the + corresponding variable is in the support of the DD and 0 otherwise. + + Side Effects: None + +int +Cudd_SupportIndices( + DdManager * dd, manager + DdNode * f, DD whose support is sought + int ** indices array containing (on return) the indices +) + Finds the variables on which a DD depends. Returns the number of variables + if successful; CUDD_OUT_OF_MEM otherwise. + + Side Effects: The indices of the support variables are returned as side + effects. If the function is constant, no array is allocated. + +int +Cudd_SupportSize( + DdManager * dd, manager + DdNode * f DD whose support size is sought +) + Returns the variables on which a DD depends. + + Side Effects: None + +DdNode * +Cudd_Support( + DdManager * dd, manager + DdNode * f DD whose support is sought +) + Finds the variables on which a DD depends. Returns a BDD consisting of the + product of the variables if successful; NULL otherwise. + + Side Effects: None + +void +Cudd_SymmProfile( + DdManager * table, + int lower, + int upper +) + Prints statistics on symmetric variables. + + Side Effects: None + +int +Cudd_TimeLimited( + DdManager * unique +) + Returns true if the time limit for the manager is set. + + Side Effects: None + +void +Cudd_TurnOffCountDead( + DdManager * dd +) + Causes the dead nodes not to be counted towards triggering reordering. This + causes less frequent reorderings. By default dead nodes are not counted. + Therefore there is no need to call this function unless Cudd_TurnOnCountDead + has been previously called. + + Side Effects: Changes the manager. + +void +Cudd_TurnOnCountDead( + DdManager * dd +) + Causes the dead nodes to be counted towards triggering reordering. This + causes more frequent reorderings. By default dead nodes are not counted. + + Side Effects: Changes the manager. + +DdNode * +Cudd_UnderApprox( + DdManager * dd, manager + DdNode * f, function to be subset + int numVars, number of variables in the support of f + int threshold, when to stop approximation + int safe, enforce safe approximation + double quality minimum improvement for accepted changes +) + Extracts a dense subset from a BDD. This procedure uses a variant of Tom + Shiple's underapproximation method. The main difference from the original + method is that density is used as cost function. Returns a pointer to the + BDD of the subset if successful. NULL if the procedure runs out of memory. + The parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value returned + by Cudd_ReadSize for numVars when the number of variables is under 1023. If + numVars is larger than 1023, it will cause overflow. If a 0 parameter is + passed then the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more. + + Side Effects: None + +void +Cudd_UnsetTimeLimit( + DdManager * unique +) + Unsets the time limit for the manager. Actually, sets it to a very large + value. + + Side Effects: None + +void +Cudd_UpdateTimeLimit( + DdManager * unique +) + Updates the time limit for the manager by subtracting the elapsed time from + it. + + Side Effects: None + +int * +Cudd_VectorSupportIndex( + DdManager * dd, manager + DdNode ** F, array of DDs whose support is sought + int n size of the array +) + Finds the variables on which a set of DDs depends. The set must contain + either BDDs and ADDs, or ZDDs. Returns an index array of the variables if + successful; NULL otherwise. + + Side Effects: None + +int +Cudd_VectorSupportIndices( + DdManager * dd, manager + DdNode ** F, DD whose support is sought + int n, size of the array + int ** indices array containing (on return) the indices +) + Finds the variables on which a set of DDs depends. The set must contain + either BDDs and ADDs, or ZDDs. Returns the number of variables if + successful; CUDD_OUT_OF_MEM otherwise. + + Side Effects: The indices of the support variables are returned as side + effects. If the function is constant, no array is allocated. + +int +Cudd_VectorSupportSize( + DdManager * dd, manager + DdNode ** F, array of DDs whose support is sought + int n size of the array +) + Returns the variables on which a set of DDs depends. The set must contain + either BDDs and ADDs, or ZDDs. + + Side Effects: None + +DdNode * +Cudd_VectorSupport( + DdManager * dd, manager + DdNode ** F, array of DDs whose support is sought + int n size of the array +) + Finds the variables on which a set of DDs depends. The set must contain + either BDDs and ADDs, or ZDDs. Returns a BDD consisting of the product of + the variables if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_VerifySol( + DdManager * bdd, + DdNode * F, the left-hand side of the equation + DdNode ** G, the array of solutions + int * yIndex, index of y variables + int n numbers of unknowns +) + Checks the solution of F(x,y) = 0. This procedure substitutes the solution + components for the unknowns of F and returns the resulting BDD for F. + + Side Effects: Frees the memory pointed by yIndex. + +DdNode * +Cudd_Xeqy( + DdManager * dd, DD manager + int N, number of x and y variables + DdNode ** x, array of x variables + DdNode ** y array of y variables +) + This function generates a BDD for the function x==y. Both x and y are N-bit + numbers, x[0] x[1] ... x[N-1] and y[0] y[1] ... y[N-1], with 0 the most + significant bit. The BDD is built bottom-up. It has 3*N-1 internal nodes, if + the variables are ordered as follows: x[0] y[0] x[1] y[1] ... x[N-1] y[N-1]. + + Side Effects: None + +DdNode * +Cudd_Xgty( + DdManager * dd, DD manager + int N, number of x and y variables + DdNode ** z, array of z variables: unused + DdNode ** x, array of x variables + DdNode ** y array of y variables +) + This function generates a BDD for the function x > y. Both x and y are N- + bit numbers, x[0] x[1] ... x[N-1] and y[0] y[1] ... y[N-1], with 0 the most + significant bit. The BDD is built bottom-up. It has 3*N-1 internal nodes, if + the variables are ordered as follows: x[0] y[0] x[1] y[1] ... x[N-1] y[N-1]. + Argument z is not used by Cudd_Xgty: it is included to make it call- + compatible to Cudd_Dxygtdxz and Cudd_Dxygtdyz. + + Side Effects: None + +DdNode * +Cudd_addAgreement( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Returns NULL if not a terminal case; f op g otherwise, where f op g is f if + f==g; background if f!=g. + + Side Effects: None + +DdNode * +Cudd_addApply( + DdManager * dd, + DD_AOP op, + DdNode * f, + DdNode * g +) + Applies op to the corresponding discriminants of f and g. Returns a pointer + to the result if succssful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddInterval( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE lower, + CUDD_VALUE_TYPE upper +) + Converts an ADD to a BDD by replacing all discriminants greater than or + equal to lower and less than or equal to upper with 1, and all other + discriminants with 0. Returns a pointer to the resulting BDD if successful; + NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddIthBit( + DdManager * dd, + DdNode * f, + int bit +) + Converts an ADD to a BDD by replacing all discriminants whose i-th bit is + equal to 1 with 1, and all other discriminants with 0. The i-th bit refers + to the integer representation of the leaf value. If the value is has a + fractional part, it is ignored. Repeated calls to this procedure allow one + to transform an integer-valued ADD into an array of BDDs, one for each bit + of the leaf values. Returns a pointer to the resulting BDD if successful; + NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddPattern( + DdManager * dd, + DdNode * f +) + Converts an ADD to a BDD by replacing all discriminants different from 0 + with 1. Returns a pointer to the resulting BDD if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddStrictThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value +) + Converts an ADD to a BDD by replacing all discriminants STRICTLY greater + than value with 1, and all other discriminants with 0. Returns a pointer to + the resulting BDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addBddThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value +) + Converts an ADD to a BDD by replacing all discriminants greater than or + equal to value with 1, and all other discriminants with 0. Returns a pointer + to the resulting BDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addCmpl( + DdManager * dd, + DdNode * f +) + Computes the complement of an ADD a la C language: The complement of 0 is 1 + and the complement of everything else is 0. Returns a pointer to the + resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addCompose( + DdManager * dd, + DdNode * f, + DdNode * g, + int v +) + Substitutes g for x_v in the ADD for f. v is the index of the variable to be + substituted. g must be a 0-1 ADD. Cudd_bddCompose passes the corresponding + projection function to the recursive procedure, so that the cache may be + used. Returns the composed ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addComputeCube( + DdManager * dd, + DdNode ** vars, + int * phase, + int n +) + Computes the cube of an array of ADD variables. If non-null, the phase + argument indicates which literal of each variable should appear in the cube. + If phase[i] is nonzero, then the positive literal is used. If phase is NULL, + the cube is positive unate. Returns a pointer to the result if successful; + NULL otherwise. + + Side Effects: none + +DdNode * +Cudd_addConstrain( + DdManager * dd, + DdNode * f, + DdNode * c +) + Computes f constrain c (f @ c), for f an ADD and c a 0-1 ADD. List of + special cases: F @ 0 = 0 F @ 1 = F 0 @ c = 0 1 @ c + = 1 F @ F = 1 Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_addConst( + DdManager * dd, + CUDD_VALUE_TYPE c +) + Retrieves the ADD for constant c if it already exists, or creates a new ADD. + Returns a pointer to the ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addDiff( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Returns NULL if not a terminal case; f op g otherwise, where f op g is + plusinfinity if f=g; min(f,g) if f!=g. + + Side Effects: None + +DdNode * +Cudd_addDivide( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point division. Returns NULL if not a terminal case; f + / g otherwise. + + Side Effects: None + +DdNode * +Cudd_addEvalConst( + DdManager * dd, + DdNode * f, + DdNode * g +) + Checks whether ADD g is constant whenever ADD f is 1. f must be a 0-1 ADD. + Returns a pointer to the resulting ADD (which may or may not be constant) or + DD_NON_CONSTANT. If f is identically 0, the check is assumed to be + successful, and the background value is returned. No new nodes are created. + + Side Effects: None + +DdNode * +Cudd_addExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube +) + Abstracts all the variables in cube from f by summing over all possible + values taken by the variables. Returns the abstracted ADD. + + Side Effects: None + +DdNode * +Cudd_addFindMax( + DdManager * dd, + DdNode * f +) + Returns a pointer to a constant ADD. + + Side Effects: None + +DdNode * +Cudd_addFindMin( + DdManager * dd, + DdNode * f +) + Returns a pointer to a constant ADD. + + Side Effects: None + +DdNode * +Cudd_addGeneralVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vectorOn, + DdNode ** vectorOff +) + Given a vector of ADDs, creates a new ADD by substituting the ADDs for the + variables of the ADD f. vectorOn contains ADDs to be substituted for the x_v + and vectorOff the ADDs to be substituted for x_v'. There should be an entry + in vector for each variable in the manager. If no substitution is sought for + a given variable, the corresponding projection function should be specified + in the vector. This function implements simultaneous composition. Returns a + pointer to the resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addHamming( + DdManager * dd, + DdNode ** xVars, + DdNode ** yVars, + int nVars +) + Computes the Hamming distance ADD. Returns an ADD that gives the Hamming + distance between its two arguments if successful; NULL otherwise. The two + vectors xVars and yVars identify the variables that form the two arguments. + + Side Effects: None + +int +Cudd_addHarwell( + FILE * fp, pointer to the input file + DdManager * dd, DD manager + DdNode ** E, characteristic function of the graph + DdNode *** x, array of row variables + DdNode *** y, array of column variables + DdNode *** xn, array of complemented row variables + DdNode *** yn_, array of complemented column variables + int * nx, number or row variables + int * ny, number or column variables + int * m, number of rows + int * n, number of columns + int bx, first index of row variables + int sx, step of row variables + int by, first index of column variables + int sy, step of column variables + int pr verbosity level +) + Reads in a matrix in the format of the Harwell-Boeing benchmark suite. The + variables are ordered as follows: x[0] y[0] x[1] y[1] ... + 0 is the most significant bit. On input, nx and ny hold the + numbers of row and column variables already in existence. On output, they + hold the numbers of row and column variables actually used by the matrix. m + and n are set to the numbers of rows and columns of the matrix. Their values + on input are immaterial. Returns 1 on success; 0 otherwise. The ADD for the + sparse matrix is returned in E, and its reference count is > 0. + + Side Effects: None + +DdNode * +Cudd_addIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Implements ITEconstant for ADDs. f must be a 0-1 ADD. Returns a pointer to + the resulting ADD (which may or may not be constant) or DD_NON_CONSTANT. No + new nodes are created. This function can be used, for instance, to check + that g has a constant value (specified by h) whenever f is 1. If the + constant value is unknown, then one should use Cudd_addEvalConst. + + Side Effects: None + +DdNode * +Cudd_addIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Implements ITE(f,g,h). This procedure assumes that f is a 0-1 ADD. Returns a + pointer to the resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addIthBit( + DdManager * dd, + DdNode * f, + int bit +) + Produces an ADD from another ADD by replacing all discriminants whose i-th + bit is equal to 1 with 1, and all other discriminants with 0. The i-th bit + refers to the integer representation of the leaf value. If the value is has + a fractional part, it is ignored. Repeated calls to this procedure allow one + to transform an integer-valued ADD into an array of ADDs, one for each bit + of the leaf values. Returns a pointer to the resulting ADD if successful; + NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addIthVar( + DdManager * dd, + int i +) + Retrieves the ADD variable with index i if it already exists, or creates a + new ADD variable. Returns a pointer to the variable if successful; NULL + otherwise. An ADD variable differs from a BDD variable because it points to + the arithmetic zero, instead of having a complement pointer to 1. + + Side Effects: None + +int +Cudd_addLeq( + DdManager * dd, + DdNode * f, + DdNode * g +) + Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are + created. This procedure works for arbitrary ADDs. For 0-1 ADDs + Cudd_addEvalConst is more efficient. + + Side Effects: None + +DdNode * +Cudd_addLog( + DdManager * dd, + DdNode * f +) + Natural logarithm of an ADDs. Returns NULL if not a terminal case; log(f) + otherwise. The discriminants of f must be positive double's. + + Side Effects: None + +DdNode * +Cudd_addMatrixMultiply( + DdManager * dd, + DdNode * A, + DdNode * B, + DdNode ** z, + int nz +) + Calculates the product of two matrices, A and B, represented as ADDs. This + procedure implements the quasiring multiplication algorithm. A is assumed to + depend on variables x (rows) and z (columns). B is assumed to depend on + variables z (rows) and y (columns). The product of A and B then depends on x + (rows) and y (columns). Only the z variables have to be explicitly + identified; they are the "summation" variables. Returns a pointer to the + result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addMaximum( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point max for Cudd_addApply. Returns NULL if not a + terminal case; max(f,g) otherwise. + + Side Effects: None + +DdNode * +Cudd_addMinimum( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point min for Cudd_addApply. Returns NULL if not a + terminal case; min(f,g) otherwise. + + Side Effects: None + +DdNode * +Cudd_addMinus( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point subtraction. Returns NULL if not a terminal case; + f - g otherwise. + + Side Effects: None + +DdNode * +Cudd_addMonadicApply( + DdManager * dd, + DD_MAOP op, + DdNode * f +) + Applies op to the discriminants of f. Returns a pointer to the result if + succssful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addNand( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + NAND of two 0-1 ADDs. Returns NULL if not a terminal case; f NAND g + otherwise. + + Side Effects: None + +DdNode * +Cudd_addNegate( + DdManager * dd, + DdNode * f +) + Computes the additive inverse of an ADD. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addNewVarAtLevel( + DdManager * dd, + int level +) + Creates a new ADD variable. The new variable has an index equal to the + largest previous index plus 1 and is positioned at the specified level in + the order. Returns a pointer to the new variable if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_addNewVar( + DdManager * dd +) + Creates a new ADD variable. The new variable has an index equal to the + largest previous index plus 1. Returns a pointer to the new variable if + successful; NULL otherwise. An ADD variable differs from a BDD variable + because it points to the arithmetic zero, instead of having a complement + pointer to 1. + + Side Effects: None + +DdNode * +Cudd_addNonSimCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector +) + Given a vector of 0-1 ADDs, creates a new ADD by substituting the 0-1 ADDs + for the variables of the ADD f. There should be an entry in vector for each + variable in the manager. This function implements non-simultaneous + composition. If any of the functions being composed depends on any of the + variables being substituted, then the result depends on the order of + composition, which in turn depends on the variable order: The variables + farther from the roots in the order are substituted first. Returns a pointer + to the resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addNor( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + NOR of two 0-1 ADDs. Returns NULL if not a terminal case; f NOR g otherwise. + + Side Effects: None + +DdNode * +Cudd_addOneZeroMaximum( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Returns 1 if f > g and 0 otherwise. Used in conjunction with + Cudd_addApply. Returns NULL if not a terminal case. + + Side Effects: None + +DdNode * +Cudd_addOrAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube +) + Abstracts all the variables in cube from the 0-1 ADD f by taking the + disjunction over all possible values taken by the variables. Returns the + abstracted ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addOr( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Disjunction of two 0-1 ADDs. Returns NULL if not a terminal case; f OR g + otherwise. + + Side Effects: None + +DdNode * +Cudd_addOuterSum( + DdManager * dd, + DdNode * M, + DdNode * r, + DdNode * c +) + Takes the pointwise minimum of a matrix and the outer sum of two vectors. + This procedure is used in the Floyd-Warshall all-pair shortest path + algorithm. Returns a pointer to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addPermute( + DdManager * manager, + DdNode * node, + int * permut +) + Given a permutation in array permut, creates a new ADD with permuted + variables. There should be an entry in array permut for each variable in the + manager. The i-th entry of permut holds the index of the variable that is to + substitute the i-th variable. Returns a pointer to the resulting ADD if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addPlus( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Integer and floating point addition. Returns NULL if not a terminal case; + f+g otherwise. + + Side Effects: None + +int +Cudd_addRead( + FILE * fp, input file pointer + DdManager * dd, DD manager + DdNode ** E, characteristic function of the graph + DdNode *** x, array of row variables + DdNode *** y, array of column variables + DdNode *** xn, array of complemented row variables + DdNode *** yn_, array of complemented column variables + int * nx, number or row variables + int * ny, number or column variables + int * m, number of rows + int * n, number of columns + int bx, first index of row variables + int sx, step of row variables + int by, first index of column variables + int sy step of column variables +) + Reads in a sparse matrix specified in a simple format. The first line of the + input contains the numbers of rows and columns. The remaining lines contain + the elements of the matrix, one per line. Given a background value + (specified by the background field of the manager), only the values + different from it are explicitly listed. Each foreground element is + described by two integers, i.e., the row and column number, and a real + number, i.e., the value. Cudd_addRead produces an ADD that depends on two + sets of variables: x and y. The x variables (x[0] ... x[nx-1]) encode the + row index and the y variables (y[0] ... y[ny-1]) encode the column index. + x[0] and y[0] are the most significant bits in the indices. The variables + may already exist or may be created by the function. The index of x[i] is + bx+i*sx, and the index of y[i] is by+i*sy. On input, nx and ny hold the + numbers of row and column variables already in existence. On output, they + hold the numbers of row and column variables actually used by the matrix. + When Cudd_addRead creates the variable arrays, the index of x[i] is bx+i*sx, + and the index of y[i] is by+i*sy. When some variables already exist + Cudd_addRead expects the indices of the existing x variables to be bx+i*sx, + and the indices of the existing y variables to be by+i*sy. m and n are + set to the numbers of rows and columns of the matrix. Their values on input + are immaterial. The ADD for the sparse matrix is returned in E, and its + reference count is > 0. Cudd_addRead returns 1 in case of success; 0 + otherwise. + + Side Effects: nx and ny are set to the numbers of row and column variables. + m and n are set to the numbers of rows and columns. x and y are possibly + extended to represent the array of row and column variables. Similarly for + xn and yn_, which hold on return from Cudd_addRead the complements of the + row and column variables. + +DdNode * +Cudd_addResidue( + DdManager * dd, manager + int n, number of bits + int m, modulus + int options, options + int top index of top variable +) + Builds an ADD for the residue modulo m of an n-bit number. The modulus must + be at least 2, and the number of bits at least 1. Parameter options + specifies whether the MSB should be on top or the LSB; and whther the number + whose residue is computed is in two's complement notation or not. The macro + CUDD_RESIDUE_DEFAULT specifies LSB on top and unsigned number. The macro + CUDD_RESIDUE_MSB specifies MSB on top, and the macro CUDD_RESIDUE_TC + specifies two's complement residue. To request MSB on top and two's + complement residue simultaneously, one can OR the two macros: + CUDD_RESIDUE_MSB | CUDD_RESIDUE_TC. Cudd_addResidue returns a pointer to the + resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addRestrict( + DdManager * dd, + DdNode * f, + DdNode * c +) + ADD restrict according to Coudert and Madre's algorithm (ICCAD90). Returns + the restricted ADD if successful; otherwise NULL. If application of restrict + results in an ADD larger than the input ADD, the input ADD is returned. + + Side Effects: None + +DdNode * +Cudd_addRoundOff( + DdManager * dd, + DdNode * f, + int N +) + Rounds off the discriminants of an ADD. The discriminants are rounded off to + N digits after the decimal. Returns a pointer to the result ADD if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addScalarInverse( + DdManager * dd, + DdNode * f, + DdNode * epsilon +) + Computes an n ADD where the discriminants are the multiplicative inverses of + the corresponding discriminants of the argument ADD. Returns a pointer to + the resulting ADD in case of success. Returns NULL if any discriminants + smaller than epsilon is encountered. + + Side Effects: None + +DdNode * +Cudd_addSetNZ( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + This operator sets f to the value of g wherever g != 0. Returns NULL if not + a terminal case; f op g otherwise. + + Side Effects: None + +DdNode * +Cudd_addSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n +) + Swaps two sets of variables of the same size (x and y) in the ADD f. The + size is given by n. The two sets of variables are assumed to be disjoint. + Returns a pointer to the resulting ADD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_addThreshold( + DdManager * dd, + DdNode ** f, + DdNode ** g +) + Threshold operator for Apply (f if f >=g; 0 if fx_id, or if + phase == 0 and f-->x_id'. + + Side Effects: None + +int +Cudd_bddIsVarHardGroup( + DdManager * dd, + int index +) + Checks whether a variable is set to be in a hard group. This function is + used for lazy sifting. Returns 1 if the variable is marked to be in a hard + group; 0 if the variable exists, but it is not marked to be in a hard group; + -1 if the variable does not exist. + + Side Effects: none + +int +Cudd_bddIsVarToBeGrouped( + DdManager * dd, + int index +) + Checks whether a variable is set to be grouped. This function is used for + lazy sifting. + + Side Effects: none + +int +Cudd_bddIsVarToBeUngrouped( + DdManager * dd, + int index +) + Checks whether a variable is set to be ungrouped. This function is used for + lazy sifting. Returns 1 if the variable is marked to be ungrouped; 0 if the + variable exists, but it is not marked to be ungrouped; -1 if the variable + does not exist. + + Side Effects: none + +DdNode * +Cudd_bddIsop( + DdManager * dd, + DdNode * L, + DdNode * U +) + Computes a BDD in the interval between L and U with a simple sum-of-product + cover. This procedure is similar to Cudd_zddIsop, but it does not return the + ZDD for the cover. Returns a pointer to the BDD if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_bddIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Implements ITEconstant(f,g,h). Returns a pointer to the resulting BDD (which + may or may not be constant) or DD_NON_CONSTANT. No new nodes are created. + + Side Effects: None + +DdNode * +Cudd_bddIteLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h, + unsigned int limit +) + Implements ITE(f,g,h). Returns a pointer to the resulting BDD if successful; + NULL if the intermediate result blows up or more new nodes than + limit are required. + + Side Effects: None + +int +Cudd_bddIterConjDecomp( + DdManager * dd, manager + DdNode * f, function to be decomposed + DdNode *** conjuncts address of the array of conjuncts +) + Performs two-way conjunctive decomposition of a BDD. This procedure owes its + name to the iterated use of supersetting to obtain a factor of the given + function. Returns the number of conjuncts produced, that is, 2 if + successful; 1 if no meaningful decomposition was found; 0 otherwise. The + conjuncts produced by this procedure tend to be imbalanced. + + Side Effects: The factors are returned in an array as side effects. The + array is allocated by this function. It is the caller's responsibility to + free it. On successful completion, the conjuncts are already referenced. If + the function returns 0, the array for the conjuncts is not allocated. If the + function returns 1, the only factor equals the function to be decomposed. + +int +Cudd_bddIterDisjDecomp( + DdManager * dd, manager + DdNode * f, function to be decomposed + DdNode *** disjuncts address of the array of the disjuncts +) + Performs two-way disjunctive decomposition of a BDD. Returns the number of + disjuncts produced, that is, 2 if successful; 1 if no meaningful + decomposition was found; 0 otherwise. The disjuncts produced by this + procedure tend to be imbalanced. + + Side Effects: The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already referenced. + If the function returns 0, the array for the disjuncts is not allocated. If + the function returns 1, the only factor equals the function to be + decomposed. + +DdNode * +Cudd_bddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Implements ITE(f,g,h). Returns a pointer to the resulting BDD if successful; + NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddIthVar( + DdManager * dd, + int i +) + Retrieves the BDD variable with index i if it already exists, or creates a + new BDD variable. Returns a pointer to the variable if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_bddLICompaction( + DdManager * dd, manager + DdNode * f, function to be minimized + DdNode * c constraint (care set) +) + Performs safe minimization of a BDD. Given the BDD f of a + function to be minimized and a BDD c representing the care set, + Cudd_bddLICompaction produces the BDD of a function that agrees with + f wherever c is 1. Safe minimization means that + the size of the result is guaranteed not to exceed the size of + f. This function is based on the DAC97 paper by Hong et al.. + Returns a pointer to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddLargestPrimeUnate( + DdManager * dd, manager + DdNode * f, unate function + DdNode * phaseBdd cube of the phases +) + Find a largest prime implicant of a unate function. Returns the BDD for the + prime if succesful; NULL otherwise. The behavior is undefined if f is not + unate. The third argument is used to determine whether f is unate positive + (increasing) or negative (decreasing) in each of the variables in its + support. + + Side Effects: None + +int +Cudd_bddLeqUnless( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * D +) + Tells whether f is less than of equal to G unless D is 1. f, g, and D are + BDDs. The function returns 1 if f is less than of equal to G, and 0 + otherwise. No new nodes are created. + + Side Effects: None + +int +Cudd_bddLeq( + DdManager * dd, + DdNode * f, + DdNode * g +) + Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are + created. + + Side Effects: None + +DdNode * +Cudd_bddLiteralSetIntersection( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the intesection of two sets of literals represented as BDDs. Each + set is represented as a cube of the literals in the set. The empty set is + represented by the constant 1. No variable can be simultaneously present in + both phases in a set. Returns a pointer to the BDD representing the + intersected sets, if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddMakePrime( + DdManager * dd, manager + DdNode * cube, cube to be expanded + DdNode * f function of which the cube is to be made + a prime +) + Expands cube to a prime implicant of f. Returns the prime if successful; + NULL otherwise. In particular, NULL is returned if cube is not a real cube + or is not an implicant of f. + + Side Effects: None + +DdNode * +Cudd_bddMaximallyExpand( + DdManager * dd, manager + DdNode * lb, cube to be expanded + DdNode * ub, upper bound cube + DdNode * f function against which to expand +) + Expands lb to all prime implicants of (f and ub) that contain lb. Assumes + that lb is contained in ub. Returns the disjunction of the primes if lb is + contained in f; returns the zero BDD if lb is not contained in f; returns + NULL in case of failure. In particular, NULL is returned if cube is not a + real cube or is not an implicant of f. Returning the disjunction of all + prime implicants works because the resulting function is unate. + + Side Effects: None + +DdNode * +Cudd_bddMinimize( + DdManager * dd, + DdNode * f, + DdNode * c +) + Finds a small BDD that agrees with f over c. + Returns a pointer to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddNPAnd( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes f non-polluting-and g. The non-polluting AND of f and g is a hybrid + of AND and Restrict. From Restrict, this operation takes the idea of + existentially quantifying the top variable of the second operand if it does + not appear in the first. Therefore, the variables that appear in the result + also appear in f. For the rest, the function behaves like AND. Since the two + operands play different roles, non-polluting AND is not commutative. Returns + a pointer to the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddNand( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the NAND of two BDDs f and g. Returns a pointer to the resulting + BDD if successful; NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddNewVarAtLevel( + DdManager * dd, + int level +) + Creates a new BDD variable. The new variable has an index equal to the + largest previous index plus 1 and is positioned at the specified level in + the order. Returns a pointer to the new variable if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_bddNewVar( + DdManager * dd +) + Creates a new BDD variable. The new variable has an index equal to the + largest previous index plus 1. Returns a pointer to the new variable if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddNor( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the NOR of two BDDs f and g. Returns a pointer to the resulting BDD + if successful; NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddOrLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit +) + Computes the disjunction of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up or + more new nodes than limit are required. + + Side Effects: None + +DdNode * +Cudd_bddOr( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the disjunction of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddPermute( + DdManager * manager, + DdNode * node, + int * permut +) + Given a permutation in array permut, creates a new BDD with permuted + variables. There should be an entry in array permut for each variable in the + manager. The i-th entry of permut holds the index of the variable that is to + substitute the i-th variable. Returns a pointer to the resulting BDD if + successful; NULL otherwise. + + Side Effects: None + +DdNode ** +Cudd_bddPickArbitraryMinterms( + DdManager * dd, manager + DdNode * f, function from which to pick k minterms + DdNode ** vars, array of variables + int n, size of vars + int k number of minterms to find +) + Picks k on-set minterms evenly distributed from given DD. The minterms are + in terms of vars. The array vars should contain at + least all variables in the support of f; if this condition is + not met the minterms built by this procedure may not be contained in + f. Builds an array of BDDs for the minterms and returns a + pointer to it if successful; NULL otherwise. There are three reasons why the + procedure may fail: It may run out of memory; the function + f may be the constant 0; the minterms may not be contained + in f. + + Side Effects: None + +int +Cudd_bddPickOneCube( + DdManager * ddm, + DdNode * node, + char * string +) + Picks one on-set cube randomly from the given DD. The cube is written into + an array of characters. The array must have at least as many entries as + there are variables. Returns 1 if successful; 0 otherwise. + + Side Effects: None + +DdNode * +Cudd_bddPickOneMinterm( + DdManager * dd, manager + DdNode * f, function from which to pick one minterm + DdNode ** vars, array of variables + int n size of vars +) + Picks one on-set minterm randomly from the given DD. The minterm is in terms + of vars. The array vars should contain at least + all variables in the support of f; if this condition is not met + the minterm built by this procedure may not be contained in f. + Builds a BDD for the minterm and returns a pointer to it if successful; NULL + otherwise. There are three reasons why the procedure may fail: It + may run out of memory; the function f may be the constant + 0; the minterm may not be contained in f. + + Side Effects: None + +int +Cudd_bddPrintCover( + DdManager * dd, + DdNode * l, + DdNode * u +) + Prints a sum of product cover for an incompletely specified function given + by a lower bound and an upper bound. Each product is a prime implicant + obtained by expanding the product corresponding to a path from node to the + constant one. Uses the package default output file. Returns 1 if successful; + 0 otherwise. + + Side Effects: None + +int +Cudd_bddReadPairIndex( + DdManager * dd, + int index +) + Reads a corresponding pair index for a given index. These pair indices are + present and next state variable. Returns the corresponding variable index if + the variable exists; -1 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddRead( + FILE * fp, input file pointer + DdManager * dd, DD manager + DdNode ** E, characteristic function of the graph + DdNode *** x, array of row variables + DdNode *** y, array of column variables + int * nx, number or row variables + int * ny, number or column variables + int * m, number of rows + int * n, number of columns + int bx, first index of row variables + int sx, step of row variables + int by, first index of column variables + int sy step of column variables +) + Reads in a graph (without labels) given as an adjacency matrix. The first + line of the input contains the numbers of rows and columns of the adjacency + matrix. The remaining lines contain the arcs of the graph, one per line. + Each arc is described by two integers, i.e., the row and column number, or + the indices of the two endpoints. Cudd_bddRead produces a BDD that depends + on two sets of variables: x and y. The x variables (x[0] ... x[nx-1]) encode + the row index and the y variables (y[0] ... y[ny-1]) encode the column + index. x[0] and y[0] are the most significant bits in the indices. The + variables may already exist or may be created by the function. The index of + x[i] is bx+i*sx, and the index of y[i] is by+i*sy. On input, nx and ny + hold the numbers of row and column variables already in existence. On + output, they hold the numbers of row and column variables actually used by + the matrix. When Cudd_bddRead creates the variable arrays, the index of x[i] + is bx+i*sx, and the index of y[i] is by+i*sy. When some variables already + exist, Cudd_bddRead expects the indices of the existing x variables to be + bx+i*sx, and the indices of the existing y variables to be by+i*sy. m and + n are set to the numbers of rows and columns of the matrix. Their values on + input are immaterial. The BDD for the graph is returned in E, and its + reference count is > 0. Cudd_bddRead returns 1 in case of success; 0 + otherwise. + + Side Effects: nx and ny are set to the numbers of row and column variables. + m and n are set to the numbers of rows and columns. x and y are possibly + extended to represent the array of row and column variables. + +void +Cudd_bddRealignDisable( + DdManager * unique +) + Disables realignment of ZDD order to BDD order. + + Side Effects: None + +void +Cudd_bddRealignEnable( + DdManager * unique +) + Enables realignment of the BDD variable order to the ZDD variable order + after the ZDDs have been reordered. The number of ZDD variables must be a + multiple of the number of BDD variables for realignment to make sense. If + this condition is not met, Cudd_zddReduceHeap will return 0. Let + M be the ratio of the two numbers. For the purpose of + realignment, the ZDD variables from M*i to (M+1)*i- + 1 are reagarded as corresponding to BDD variable i. + Realignment is initially disabled. + + Side Effects: None + +int +Cudd_bddRealignmentEnabled( + DdManager * unique +) + Returns 1 if the realignment of BDD order to ZDD order is enabled; 0 + otherwise. + + Side Effects: None + +int +Cudd_bddResetVarToBeGrouped( + DdManager * dd, + int index +) + Resets a variable not to be grouped. This function is used for lazy sifting. + Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +DdNode * +Cudd_bddRestrict( + DdManager * dd, + DdNode * f, + DdNode * c +) + BDD restrict according to Coudert and Madre's algorithm (ICCAD90). Returns + the restricted BDD if successful; otherwise NULL. If application of restrict + results in a BDD larger than the input BDD, the input BDD is returned. + + Side Effects: None + +int +Cudd_bddSetNsVar( + DdManager * dd, manager + int index variable index +) + Sets a variable type to next state. The variable type is used by lazy + sifting. Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetPairIndex( + DdManager * dd, manager + int index, variable index + int pairIndex corresponding variable index +) + Sets a corresponding pair index for a given index. These pair indices are + present and next state variable. Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetPiVar( + DdManager * dd, manager + int index variable index +) + Sets a variable type to primary input. The variable type is used by lazy + sifting. Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetPsVar( + DdManager * dd, manager + int index variable index +) + Sets a variable type to present state. The variable type is used by lazy + sifting. Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetVarHardGroup( + DdManager * dd, + int index +) + Sets a variable to be a hard group. This function is used for lazy sifting. + Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetVarToBeGrouped( + DdManager * dd, + int index +) + Sets a variable to be grouped. This function is used for lazy sifting. + Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +int +Cudd_bddSetVarToBeUngrouped( + DdManager * dd, + int index +) + Sets a variable to be ungrouped. This function is used for lazy sifting. + Returns 1 if successful; 0 otherwise. + + Side Effects: modifies the manager + +DdNode * +Cudd_bddSqueeze( + DdManager * dd, manager + DdNode * l, lower bound + DdNode * u upper bound +) + Finds a small BDD in a function interval. Given BDDs l and + u, representing the lower bound and upper bound of a function + interval, Cudd_bddSqueeze produces the BDD of a function within the interval + with a small BDD. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_bddSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n +) + Swaps two sets of variables of the same size (x and y) in the BDD f. The + size is given by n. The two sets of variables are assumed to be disjoint. + Returns a pointer to the resulting BDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddTransfer( + DdManager * ddSource, + DdManager * ddDestination, + DdNode * f +) + Convert a BDD from a manager to another one. The orders of the variables in + the two managers may be different. Returns a pointer to the BDD in the + destination manager if successful; NULL otherwise. + + Side Effects: None + +int +Cudd_bddUnbindVar( + DdManager * dd, manager + int index variable index +) + This function resets the flag that prevents the sifting of a variable. In + successive variable reorderings, the variable will NOT be skipped, that is, + sifted. Initially all variables can be sifted. It is necessary to call this + function only to re-enable sifting after a call to Cudd_bddBindVar. Returns + 1 if successful; 0 otherwise (i.e., invalid variable index). + + Side Effects: Changes the "bindVar" flag in DdSubtable. + +DdNode * +Cudd_bddUnivAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube +) + Universally abstracts all the variables in cube from f. Returns the + abstracted BDD if successful; NULL otherwise. + + Side Effects: None + +int +Cudd_bddVarConjDecomp( + DdManager * dd, manager + DdNode * f, function to be decomposed + DdNode *** conjuncts address of the array of conjuncts +) + Conjunctively decomposes one BDD according to a variable. If f + is the function of the BDD and x is the variable, the + decomposition is (f+x)(f+x'). The variable is chosen so as to + balance the sizes of the two conjuncts and to keep them small. Returns the + number of conjuncts produced, that is, 2 if successful; 1 if no meaningful + decomposition was found; 0 otherwise. + + Side Effects: The two factors are returned in an array as side effects. The + array is allocated by this function. It is the caller's responsibility to + free it. On successful completion, the conjuncts are already referenced. If + the function returns 0, the array for the conjuncts is not allocated. If the + function returns 1, the only factor equals the function to be decomposed. + +int +Cudd_bddVarDisjDecomp( + DdManager * dd, manager + DdNode * f, function to be decomposed + DdNode *** disjuncts address of the array of the disjuncts +) + Performs two-way disjunctive decomposition of a BDD according to a variable. + If f is the function of the BDD and x is the + variable, the decomposition is f*x + f*x'. The variable is + chosen so as to balance the sizes of the two disjuncts and to keep them + small. Returns the number of disjuncts produced, that is, 2 if successful; 1 + if no meaningful decomposition was found; 0 otherwise. + + Side Effects: The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already referenced. + If the function returns 0, the array for the disjuncts is not allocated. If + the function returns 1, the only factor equals the function to be + decomposed. + +int +Cudd_bddVarIsBound( + DdManager * dd, manager + int index variable index +) + This function returns 1 if a variable is enabled for sifting. Initially all + variables can be sifted. This function returns 0 only if there has been a + previous call to Cudd_bddBindVar for that variable not followed by a call to + Cudd_bddUnbindVar. The function returns 0 also in the case in which the + index of the variable is out of bounds. + + Side Effects: none + +int +Cudd_bddVarIsDependent( + DdManager * dd, + DdNode * f, + DdNode * var variable +) + Checks whether a variable is dependent on others in a function. Returns 1 if + the variable is dependent; 0 otherwise. No new nodes are created. + + Side Effects: None + +DdNode * +Cudd_bddVarMap( + DdManager * manager, DD manager + DdNode * f function in which to remap variables +) + Remaps the variables of a BDD using the default variable map. A typical use + of this function is to swap two sets of variables. The variable map must be + registered with Cudd_SetVarMap. Returns a pointer to the resulting BDD if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector +) + Given a vector of BDDs, creates a new BDD by substituting the BDDs for the + variables of the BDD f. There should be an entry in vector for each variable + in the manager. If no substitution is sought for a given variable, the + corresponding projection function should be specified in the vector. This + function implements simultaneous composition. Returns a pointer to the + resulting BDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddXnorLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit +) + Computes the exclusive NOR of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up or + more new nodes than limit are required. + + Side Effects: None + +DdNode * +Cudd_bddXnor( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the exclusive NOR of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up. + + Side Effects: None + +DdNode * +Cudd_bddXorExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube +) + Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_bddXor( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the exclusive OR of two BDDs f and g. Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows up. + + Side Effects: None + +void +Cudd_tlcInfoFree( + DdTlcInfo * t +) + Frees a DdTlcInfo Structure as well as the memory pointed by it. + + Side Effects: None + +DdNode * +Cudd_zddChange( + DdManager * dd, + DdNode * P, + int var +) + Substitutes a variable with its complement in a ZDD. returns a pointer to + the result if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddComplement( + DdManager * dd, + DdNode * node +) + Computes a complement cover for a ZDD node. For lack of a better method, we + first extract the function BDD from the ZDD cover, then make the complement + of the ZDD cover from the complement of the BDD node by using ISOP. Returns + a pointer to the resulting cover if successful; NULL otherwise. The result + depends on current variable order. + + Side Effects: The result depends on current variable order. + +double +Cudd_zddCountDouble( + DdManager * zdd, + DdNode * P +) + Counts the number of minterms of a ZDD. The result is returned as a double. + If the procedure runs out of memory, it returns (double) CUDD_OUT_OF_MEM. + This procedure is used in Cudd_zddCountMinterm. + + Side Effects: None + +double +Cudd_zddCountMinterm( + DdManager * zdd, + DdNode * node, + int path +) + Counts the number of minterms of the ZDD rooted at node. This + procedure takes a parameter path that specifies how many + variables are in the support of the function. If the procedure runs out of + memory, it returns (double) CUDD_OUT_OF_MEM. + + Side Effects: None + +int +Cudd_zddCount( + DdManager * zdd, + DdNode * P +) + Returns an integer representing the number of minterms in a ZDD. + + Side Effects: None + +char * +Cudd_zddCoverPathToString( + DdManager * zdd, DD manager + int * path, path of ZDD representing a cover + char * str pointer to string to use if != NULL +) + Converts a path of a ZDD representing a cover to a string. The string + represents an implicant of the cover. The path is typically produced by + Cudd_zddForeachPath. Returns a pointer to the string if successful; NULL + otherwise. If the str input is NULL, it allocates a new string. The string + passed to this function must have enough room for all variables and for the + terminator. + + Side Effects: None + +int +Cudd_zddDagSize( + DdNode * p_node +) + Counts the number of nodes in a ZDD. This function duplicates Cudd_DagSize + and is only retained for compatibility. + + Side Effects: None + +DdNode * +Cudd_zddDiffConst( + DdManager * zdd, + DdNode * P, + DdNode * Q +) + Inclusion test for ZDDs (P implies Q). No new nodes are generated by this + procedure. Returns empty if true; a valid pointer different from empty or + DD_NON_CONSTANT otherwise. + + Side Effects: None + +DdNode * +Cudd_zddDiff( + DdManager * dd, + DdNode * P, + DdNode * Q +) + Computes the difference of two ZDDs. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddDivideF( + DdManager * dd, + DdNode * f, + DdNode * g +) + Modified version of Cudd_zddDivide. This function may disappear in future + releases. + + Side Effects: None + +DdNode * +Cudd_zddDivide( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the quotient of two unate covers represented by ZDDs. Unate covers + use one ZDD variable for each BDD variable. Returns a pointer to the + resulting ZDD if successful; NULL otherwise. + + Side Effects: None + +int +Cudd_zddDumpDot( + DdManager * dd, manager + int n, number of output nodes to be dumped + DdNode ** f, array of output nodes to be dumped + char ** inames, array of input names (or NULL) + char ** onames, array of output names (or NULL) + FILE * fp pointer to the dump file +) + Writes a file representing the argument ZDDs in a format suitable for the + graph drawing program dot. It returns 1 in case of success; 0 otherwise + (e.g., out-of-memory, file system full). Cudd_zddDumpDot does not close the + file: This is the caller responsibility. Cudd_zddDumpDot uses a minimal + unique subset of the hexadecimal address of a node as name for it. If the + argument inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for onames. Cudd_zddDumpDot uses the following + convention to draw arcs: solid line: THEN arcs; dashed line: + ELSE arcs. The dot options are chosen so that the drawing fits on a + letter-size sheet. + + Side Effects: None + +DdGen * +Cudd_zddFirstPath( + DdManager * zdd, + DdNode * f, + int ** path +) + Defines an iterator on the paths of a ZDD and finds its first path. Returns + a generator that contains the information necessary to continue the + enumeration if successful; NULL otherwise. A path is represented as an + array of literals, which are integers in {0, 1, 2}; 0 represents an else arc + out of a node, 1 represents a then arc out of a node, and 2 stands for the + absence of a node. The size of the array equals the number of variables in + the manager at the time Cudd_zddFirstCube is called. The paths that end + in the empty terminal are not enumerated. + + Side Effects: The first path is returned as a side effect. + +DdNode * +Cudd_zddIntersect( + DdManager * dd, + DdNode * P, + DdNode * Q +) + Computes the intersection of two ZDDs. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddIsop( + DdManager * dd, + DdNode * L, + DdNode * U, + DdNode ** zdd_I +) + Computes an irredundant sum of products (ISOP) in ZDD form from BDDs. The + two BDDs L and U represent the lower bound and the upper bound, + respectively, of the function. The ISOP uses two ZDD variables for each BDD + variable: One for the positive literal, and one for the negative literal. + These two variables should be adjacent in the ZDD order. The two ZDD + variables corresponding to BDD variable i should have indices + 2i and 2i+1. The result of this procedure depends + on the variable order. If successful, Cudd_zddIsop returns the BDD for the + function chosen from the interval. The ZDD representing the irredundant + cover is returned as a side effect in zdd_I. In case of failure, NULL is + returned. + + Side Effects: zdd_I holds the pointer to the ZDD for the ISOP on successful + return. + +DdNode * +Cudd_zddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h +) + Computes the ITE of three ZDDs. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddIthVar( + DdManager * dd, + int i +) + Retrieves the ZDD variable with index i if it already exists, or creates a + new ZDD variable. Returns a pointer to the variable if successful; NULL + otherwise. + + Side Effects: None + +int +Cudd_zddNextPath( + DdGen * gen, + int ** path +) + Generates the next path of a ZDD onset, using generator gen. Returns 0 if + the enumeration is completed; 1 otherwise. + + Side Effects: The path is returned as a side effect. The generator is + modified. + +DdNode * +Cudd_zddPortFromBdd( + DdManager * dd, + DdNode * B +) + Converts a BDD into a ZDD. This function assumes that there is a one-to-one + correspondence between the BDD variables and the ZDD variables, and that the + variable order is the same for both types of variables. These conditions are + established if the ZDD variables are created by one call to + Cudd_zddVarsFromBddVars with multiplicity = 1. Returns a pointer to the + resulting ZDD if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddPortToBdd( + DdManager * dd, + DdNode * f +) + Converts a ZDD into a BDD. Returns a pointer to the resulting ZDD if + successful; NULL otherwise. + + Side Effects: None + +int +Cudd_zddPrintCover( + DdManager * zdd, + DdNode * node +) + Prints a sum of products from a ZDD representing a cover. Returns 1 if + successful; 0 otherwise. + + Side Effects: None + +int +Cudd_zddPrintDebug( + DdManager * zdd, + DdNode * f, + int n, + int pr +) + Prints to the standard output a DD and its statistics. The statistics + include the number of nodes and the number of minterms. (The number of + minterms is also the number of combinations in the set.) The statistics are + printed if pr > 0. Specifically: pr = 0 : prints nothing + pr = 1 : prints counts of nodes and minterms pr = 2 : prints counts + + disjoint sum of products pr = 3 : prints counts + list of nodes pr + > 3 : prints counts + disjoint sum of products + list of nodes + Returns 1 if successful; 0 otherwise. + + Side Effects: None + +int +Cudd_zddPrintMinterm( + DdManager * zdd, + DdNode * node +) + Prints a disjoint sum of product form for a ZDD. Returns 1 if successful; 0 + otherwise. + + Side Effects: None + +void +Cudd_zddPrintSubtable( + DdManager * table +) + Prints the ZDD table for debugging purposes. + + Side Effects: None + +DdNode * +Cudd_zddProduct( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the product of two covers represented by ZDDs. The result is also a + ZDD. Returns a pointer to the result if successful; NULL otherwise. The + covers on which Cudd_zddProduct operates use two ZDD variables for each + function variable (one ZDD variable for each literal of the variable). Those + two ZDD variables should be adjacent in the order. + + Side Effects: None + +long +Cudd_zddReadNodeCount( + DdManager * dd +) + Reports the number of nodes in ZDDs. This number always includes the two + constants 1 and 0. + + Side Effects: None + +void +Cudd_zddRealignDisable( + DdManager * unique +) + Disables realignment of ZDD order to BDD order. + + Side Effects: None + +void +Cudd_zddRealignEnable( + DdManager * unique +) + Enables realignment of the ZDD variable order to the BDD variable order + after the BDDs and ADDs have been reordered. The number of ZDD variables + must be a multiple of the number of BDD variables for realignment to make + sense. If this condition is not met, Cudd_ReduceHeap will return 0. Let + M be the ratio of the two numbers. For the purpose of + realignment, the ZDD variables from M*i to (M+1)*i- + 1 are reagarded as corresponding to BDD variable i. + Realignment is initially disabled. + + Side Effects: None + +int +Cudd_zddRealignmentEnabled( + DdManager * unique +) + Returns 1 if the realignment of ZDD order to BDD order is enabled; 0 + otherwise. + + Side Effects: None + +int +Cudd_zddReduceHeap( + DdManager * table, DD manager + Cudd_ReorderingTy heuristic, method used for reordering + int minsize bound below which no reordering occurs +) + Main dynamic reordering routine for ZDDs. Calls one of the possible + reordering procedures: Swapping Sifting Symmetric Sifting + For sifting and symmetric sifting it is possible to request reordering + to convergence. The core of all methods is the reordering procedure + cuddZddSwapInPlace() which swaps two adjacent variables. Returns 1 in case + of success; 0 otherwise. In the case of symmetric sifting (with and without + convergence) returns 1 plus the number of symmetric variables, in case of + success. + + Side Effects: Changes the variable order for all ZDDs and clears the cache. + +int +Cudd_zddShuffleHeap( + DdManager * table, DD manager + int * permutation required variable permutation +) + Reorders ZDD variables according to given permutation. The i-th entry of the + permutation array contains the index of the variable that should be brought + to the i-th level. The size of the array should be equal or greater to the + number of variables currently in use. Returns 1 in case of success; 0 + otherwise. + + Side Effects: Changes the ZDD variable order for all diagrams and clears the + cache. + +DdNode * +Cudd_zddSubset0( + DdManager * dd, + DdNode * P, + int var +) + Computes the negative cofactor of a ZDD w.r.t. a variable. In terms of + combinations, the result is the set of all combinations in which the + variable is negated. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_zddSubset1( + DdManager * dd, + DdNode * P, + int var +) + Computes the positive cofactor of a ZDD w.r.t. a variable. In terms of + combinations, the result is the set of all combinations in which the + variable is asserted. Returns a pointer to the result if successful; NULL + otherwise. + + Side Effects: None + +DdNode * +Cudd_zddSupport( + DdManager * dd, manager + DdNode * f ZDD whose support is sought +) + Finds the variables on which a ZDD depends. Returns a BDD consisting of the + product of the variables if successful; NULL otherwise. + + Side Effects: None + +void +Cudd_zddSymmProfile( + DdManager * table, + int lower, + int upper +) + Prints statistics on symmetric ZDD variables. + + Side Effects: None + +DdNode * +Cudd_zddUnateProduct( + DdManager * dd, + DdNode * f, + DdNode * g +) + Computes the product of two unate covers represented as ZDDs. Unate covers + use one ZDD variable for each BDD variable. Returns a pointer to the result + if successful; NULL otherwise. + + Side Effects: None + +DdNode * +Cudd_zddUnion( + DdManager * dd, + DdNode * P, + DdNode * Q +) + Computes the union of two ZDDs. Returns a pointer to the result if + successful; NULL otherwise. + + Side Effects: None + +int +Cudd_zddVarsFromBddVars( + DdManager * dd, DD manager + int multiplicity how many ZDD variables are created for + each BDD variable +) + Creates one or more ZDD variables for each BDD variable. If some ZDD + variables already exist, only the missing variables are created. Parameter + multiplicity allows the caller to control how many variables are created for + each BDD variable in existence. For instance, if ZDDs are used to represent + covers, two ZDD variables are required for each BDD variable. The order of + the BDD variables is transferred to the ZDD variables. If a variable group + tree exists for the BDD variables, a corresponding ZDD variable group tree + is created by expanding the BDD variable tree. In any case, the ZDD + variables derived from the same BDD variable are merged in a ZDD variable + group. If a ZDD variable group tree exists, it is freed. Returns 1 if + successful; 0 otherwise. + + Side Effects: None + +DdNode * +Cudd_zddWeakDivF( + DdManager * dd, + DdNode * f, + DdNode * g +) + Modified version of Cudd_zddWeakDiv. This function may disappear in future + releases. + + Side Effects: None + +DdNode * +Cudd_zddWeakDiv( + DdManager * dd, + DdNode * f, + DdNode * g +) + Applies weak division to two ZDDs representing two covers. Returns a pointer + to the ZDD representing the result if successful; NULL otherwise. The result + of weak division depends on the variable order. The covers on which + Cudd_zddWeakDiv operates use two ZDD variables for each function variable + (one ZDD variable for each literal of the variable). Those two ZDD variables + should be adjacent in the order. + + Side Effects: None + +writing ./cuddTitle.html diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cudd.ps b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cudd.ps new file mode 100644 index 000000000..0a12057cc --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cudd.ps @@ -0,0 +1,5036 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.92b Copyright 2002 Radical Eye Software +%%Title: cudd.dvi +%%Pages: 48 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%DocumentFonts: Times-Roman CMMI12 Times-Bold Times-Italic CMSY10 CMR10 +%%+ CMMI10 CMMI8 Courier CMSY8 CMR8 Times-BoldItalic +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -o cudd.ps cudd +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2012.02.04:1929 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% File 8r.enc as of 2002-03-12 for PSNFSS 9 +% +% This is the encoding vector for Type1 and TrueType fonts to be used +% with TeX. This file is part of the PSNFSS bundle, version 9 +% +% Authors: S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry, W. Schmidt +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida + Euro. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both ASCII and Windows. +% +% (6) /Euro is assigned to 128, as in Windows ANSI +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there down to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /Euro /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0 +ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{ +pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get +div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type +/nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end +definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup +sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll +mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[ +exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if} +forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def +end + +%%EndProcSet +%%BeginProcSet: special.pro +%! +TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N +/vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N +/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N +/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ +/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho +X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B +/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ +/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known +{userdict/md get type/dicttype eq{userdict begin md length 10 add md +maxlength ge{/md md dup length 20 add dict copy def}if end md begin +/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S +atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ +itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll +transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll +curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf +pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} +if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 +-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 +get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip +yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub +neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ +noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop +90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get +neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr +1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr +2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 +-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S +TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ +Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale +}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState +save N userdict maxlength dict begin/magscale true def normalscale +currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts +/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x +psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx +psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub +TR/showpage{}N/erasepage{}N/setpagedevice{pop}N/copypage{}N/p 3 def +@MacSetUp}N/doclip{psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll +newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto +closepath clip newpath moveto}N/endTexFig{end psf$SavedState restore}N +/@beginspecial{SDict begin/SpecialSave save N gsave normalscale +currentpoint TR @SpecialDefaults count/ocount X/dcount countdictstack N} +N/@setspecial{CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs +neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate +rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse +scale llx neg lly neg TR}{rhiSeen{rhi ury lly sub div dup scale llx neg +lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx +ury lineto llx ury lineto closepath clip}if/showpage{}N/erasepage{}N +/setpagedevice{pop}N/copypage{}N newpath}N/@endspecial{count ocount sub{ +pop}repeat countdictstack dcount sub{end}repeat grestore SpecialSave +restore end}N/@defspecial{SDict begin}N/@fedspecial{end}B/li{lineto}B +/rl{rlineto}B/rc{rcurveto}B/np{/SaveX currentpoint/SaveY X N 1 +setlinecap newpath}N/st{stroke SaveX SaveY moveto}N/fil{fill SaveX SaveY +moveto}N/ellipse{/endangle X/startangle X/yrad X/xrad X/savematrix +matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc +savematrix setmatrix}N end + +%%EndProcSet +%%BeginProcSet: color.pro +%! +TeXDict begin/setcmykcolor where{pop}{/setcmykcolor{dup 10 eq{pop +setrgbcolor}{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll +}repeat setrgbcolor pop}ifelse}B}ifelse/TeXcolorcmyk{setcmykcolor}def +/TeXcolorrgb{setrgbcolor}def/TeXcolorgrey{setgray}def/TeXcolorgray{ +setgray}def/TeXcolorhsb{sethsbcolor}def/currentcmykcolor where{pop}{ +/currentcmykcolor{currentrgbcolor 10}B}ifelse/DC{exch dup userdict exch +known{pop pop}{X}ifelse}B/GreenYellow{0.15 0 0.69 0 setcmykcolor}DC +/Yellow{0 0 1 0 setcmykcolor}DC/Goldenrod{0 0.10 0.84 0 setcmykcolor}DC +/Dandelion{0 0.29 0.84 0 setcmykcolor}DC/Apricot{0 0.32 0.52 0 +setcmykcolor}DC/Peach{0 0.50 0.70 0 setcmykcolor}DC/Melon{0 0.46 0.50 0 +setcmykcolor}DC/YellowOrange{0 0.42 1 0 setcmykcolor}DC/Orange{0 0.61 +0.87 0 setcmykcolor}DC/BurntOrange{0 0.51 1 0 setcmykcolor}DC +/Bittersweet{0 0.75 1 0.24 setcmykcolor}DC/RedOrange{0 0.77 0.87 0 +setcmykcolor}DC/Mahogany{0 0.85 0.87 0.35 setcmykcolor}DC/Maroon{0 0.87 +0.68 0.32 setcmykcolor}DC/BrickRed{0 0.89 0.94 0.28 setcmykcolor}DC/Red{ +0 1 1 0 setcmykcolor}DC/OrangeRed{0 1 0.50 0 setcmykcolor}DC/RubineRed{ +0 1 0.13 0 setcmykcolor}DC/WildStrawberry{0 0.96 0.39 0 setcmykcolor}DC +/Salmon{0 0.53 0.38 0 setcmykcolor}DC/CarnationPink{0 0.63 0 0 +setcmykcolor}DC/Magenta{0 1 0 0 setcmykcolor}DC/VioletRed{0 0.81 0 0 +setcmykcolor}DC/Rhodamine{0 0.82 0 0 setcmykcolor}DC/Mulberry{0.34 0.90 +0 0.02 setcmykcolor}DC/RedViolet{0.07 0.90 0 0.34 setcmykcolor}DC +/Fuchsia{0.47 0.91 0 0.08 setcmykcolor}DC/Lavender{0 0.48 0 0 +setcmykcolor}DC/Thistle{0.12 0.59 0 0 setcmykcolor}DC/Orchid{0.32 0.64 0 +0 setcmykcolor}DC/DarkOrchid{0.40 0.80 0.20 0 setcmykcolor}DC/Purple{ +0.45 0.86 0 0 setcmykcolor}DC/Plum{0.50 1 0 0 setcmykcolor}DC/Violet{ +0.79 0.88 0 0 setcmykcolor}DC/RoyalPurple{0.75 0.90 0 0 setcmykcolor}DC +/BlueViolet{0.86 0.91 0 0.04 setcmykcolor}DC/Periwinkle{0.57 0.55 0 0 +setcmykcolor}DC/CadetBlue{0.62 0.57 0.23 0 setcmykcolor}DC +/CornflowerBlue{0.65 0.13 0 0 setcmykcolor}DC/MidnightBlue{0.98 0.13 0 +0.43 setcmykcolor}DC/NavyBlue{0.94 0.54 0 0 setcmykcolor}DC/RoyalBlue{1 +0.50 0 0 setcmykcolor}DC/Blue{1 1 0 0 setcmykcolor}DC/Cerulean{0.94 0.11 +0 0 setcmykcolor}DC/Cyan{1 0 0 0 setcmykcolor}DC/ProcessBlue{0.96 0 0 0 +setcmykcolor}DC/SkyBlue{0.62 0 0.12 0 setcmykcolor}DC/Turquoise{0.85 0 +0.20 0 setcmykcolor}DC/TealBlue{0.86 0 0.34 0.02 setcmykcolor}DC +/Aquamarine{0.82 0 0.30 0 setcmykcolor}DC/BlueGreen{0.85 0 0.33 0 +setcmykcolor}DC/Emerald{1 0 0.50 0 setcmykcolor}DC/JungleGreen{0.99 0 +0.52 0 setcmykcolor}DC/SeaGreen{0.69 0 0.50 0 setcmykcolor}DC/Green{1 0 +1 0 setcmykcolor}DC/ForestGreen{0.91 0 0.88 0.12 setcmykcolor}DC +/PineGreen{0.92 0 0.59 0.25 setcmykcolor}DC/LimeGreen{0.50 0 1 0 +setcmykcolor}DC/YellowGreen{0.44 0 0.74 0 setcmykcolor}DC/SpringGreen{ +0.26 0 0.76 0 setcmykcolor}DC/OliveGreen{0.64 0 0.95 0.40 setcmykcolor} +DC/RawSienna{0 0.72 1 0.45 setcmykcolor}DC/Sepia{0 0.83 1 0.70 +setcmykcolor}DC/Brown{0 0.81 1 0.60 setcmykcolor}DC/Tan{0.14 0.42 0.56 0 +setcmykcolor}DC/Gray{0 0 0 0.50 setcmykcolor}DC/Black{0 0 0 1 +setcmykcolor}DC/White{0 0 0 0 setcmykcolor}DC end + +%%EndProcSet +%%BeginFont: CMR8 +%!PS-AdobeFont-1.1: CMR8 1.0 +%%CreationDate: 1991 Aug 20 16:39:40 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.0) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMR8) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle 0 def +/isFixedPitch false def +end readonly def +/FontName /CMR8 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 48 /zero put +dup 49 /one put +dup 50 /two put +dup 51 /three put +readonly def +/FontBBox{-36 -250 1070 750}readonly def +/UniqueID 5000791 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 +016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 +9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F +D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 +469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 +2BDBF16FBC7512FAA308A093FE5CF4E9D2405B169CD5365D6ECED5D768D66D6C +68618B8C482B341F8CA38E9BB9BAFCFAAD9C2F3FD033B62690986ED43D9C9361 +3645B82392D5CAE11A7CB49D7E2E82DCD485CBA1772CE422BB1D7283AD675B65 +48A7EA0069A883EC1DAA3E1F9ECE7586D6CF0A128CD557C7E5D7AA3EA97EBAD3 +9619D1BFCF4A6D64768741EDEA0A5B0EFBBF347CDCBE2E03D756967A16B613DB +0FC45FA2A3312E0C46A5FD0466AB097C58FFEEC40601B8395E52775D0AFCD7DB +8AB317333110531E5C44A4CB4B5ACD571A1A60960B15E450948A5EEA14DD330F +EA209265DB8E1A1FC80DCD3860323FD26C113B041A88C88A21655878680A4466 +FA10403D24BB97152A49B842C180E4D258C9D48F21D057782D90623116830BA3 +9902B3C5F2F2DD01433B0D7099C07DBDE268D0FFED5169BCD03D48B2F058AD62 +D8678C626DC7A3F352152C99BA963EF95F8AD11DB8B0D351210A17E4C2C55AD8 +9EB64172935D3C20A398F3EEEEC31551966A7438EF3FEE422C6D4E05337620D5 +ACC7B52BED984BFAAD36EF9D20748B05D07BE4414A63975125D272FAD83F76E6 +10FFF8363014BE526D580873C5A42B70FA911EC7B86905F13AFE55EB0273F582 +83158793B8CC296B8DE1DCCF1250FD57CB0E035C7EDA3B0092ED940D37A05493 +2EC54E09B984FCA4AB7D2EA182BCF1263AA244B07EC0EA901C077A059F709F30 +4384CB5FA748F2054FAD9A7A43D4EA427918BD414F766531136B60C3477C6632 +BEFE3897B58C19276A301926C2AEF2756B367319772C9B201C49B4D935A8267B +041D6F1783B6AEA4DAC4F5B3507D7032AA640AAB12E343A4E9BDCF419C04A721 +3888B25AF4E293AACED9A6BDC78E61DA1C424C6503CC1885F762BE0618B16C14 +7386EB4C4B9B3142B9662F48CF5B55DC44261F9F0F975611120F7B9846423136 +B3A568B97F5822B76CF10ECD4CD0C64DC55413CC2E843FB37053EAFE985A98CF +9E408707AB2BBD2F036B622F74397BE4BEFA06A0CC51A30C326C3654B5E548B5 +FD5BE6BFFD05A02E81F12A94892139862012A6776D80F0B7C3E90F8E34918601 +8A6B25676CDD71F0DBD7CF514F0363B15B6C7E62EF9BE227EB164481CC0EF812 +8B8B5FDD0FA1815E629760FDEAA026094F96B05BE963194E99D2E5444F62C26B +1BBAD76672EEC98948B7D9C81CAEBBB7C9CBA16CBDFC595D7AD3F92651B63D50 +CC7E92F4E96C4DE2721AFEE94FBFE5843979D30068BC1F11E5374F6F6EF4586C +AB699727770D97A8681D2E75E907027302832D0834FD7BB48EE89D7F0A39E263 +C34F09602BDEF782A7BCF182CB6D8603E31EF82E669B294BBE9B5AD29CD12FA9 +DD1CAAC8AB4DBB663F8C50472C9D7CF3CFB9AE712D83B306991B89F75A87A6C8 +CF7901236E9EE16204F26C79404A6EB87AC532A29C47C9455D0F3DCCA48E2B26 +1240EB3CD115047EC6C4E3F5B3680127DF7509CD26BEF7C542D0332B2A2F680F +ECAC3A2C958DC3F17576DEBDB9478343EE622DF8C8F7C488ED049690697A6B1D +BAFF45A781099100DD7B0A0598A4A93E088E8B44198EB0DE3761F141AEF45C92 +1A71F32189FEFCC7978570BEBD53305BFB9B68829998196345770721ABAE7410 +50A99976446ABBBF31130CE1A85B4F37B85BBCCD2E31C072B96F005E7506BA7B +6AF46E32CEAB608411DACC4D93ECE77BC4C4282DE8FC4189C8661A93F0A3C0CC +B09077804522B3675B87F45E9E0AB99AFC3F6A979FB2030642DB80CBB4A92BA9 +8FEADF534577FE567839008FEB0F6CD811ACB7CEDCEFC98807636A24B6EDAD43 +83CE013C9E660F3F3DB842554D04B5D8277640A931ED4CC700F8BCFF901775C6 +DBE1A76EE8ADC5601FF1DC4EC663E3E960064875BBCA81F5B82118A055D48C9D +C2DC4C00BB1B42B6C3D00354040080ACAD10EE6A464E5F62E5AC4236FF2D2A6A +BBFE55CD6E55990D15C6A13229F0AB706D61C746EF99E2AF9365 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMSY8 +%!PS-AdobeFont-1.1: CMSY8 1.0 +%%CreationDate: 1991 Aug 15 07:22:10 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.0) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMSY8) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.035 def +/isFixedPitch false def +end readonly def +/FontName /CMSY8 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 0 /minus put +dup 48 /prime put +readonly def +/FontBBox{-30 -955 1185 779}readonly def +/UniqueID 5000818 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964 +7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4 +A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85 +E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A +221A37D9A807DD01161779DDE7D5FC1B2109839E5B52DFBB2A7C1B5D8E7E8AA0 +5B10EA43D6A8ED61AF5B23D49920D8F79DAB6A59062134D84AC0100187A6CD1F +80F5DDD9D222ACB1C23326A7656A635C4A241CCD32CBFDF8363206B8AA36E107 +1477F5496111E055C7491002AFF272E46ECC46422F0380D093284870022523FB +DA1716CC4F2E2CCAD5F173FCBE6EDDB874AD255CD5E5C0F86214393FCB5F5C20 +9C3C2BB5886E36FC3CCC21483C3AC193485A46E9D22BD7201894E4D45ADD9BF1 +CC5CF6A5010B5654AC0BE0DA903DB563B13840BA3015F72E51E3BC80156388BA +F83C7D393392BCBC227771CDCB976E93302530FA3F4BEF341997D4302A48384A +CEFFC1559462EA5F60DC05245E8499D8E61397B2C094CEED1AF26EE15A837209 +ECE64FEF41ABE8DDA7BE1F351CF14E07BA8FD40CEFBFC3CE7B9D4912D6FE752D +9CF163084E688DDCC4B5AAEDEB6E94DDDE34330BA35394A8B485E767F0F94A71 +4532F3B89C51AC3FD1C082EF41EA489B9595B4120FDCA2F599C88F5058126CD1 +4C7F96B4FE22BAB1A5E16F215DECBCE4186C68B6263BD5331CDC1FF9F30332A7 +7B831255A41A642C5719272C6B5993171CA395A0D11B6376457EC30E1CDE47A4 +9B9EE95D112C64084901B6357E881C0DEB6836B80F21E57B660388BA4F7B89EB +9AF7DE8AEA702FC5B765552F78058A20E424277F667A4E9955A797593CE44E19 +A98F149CA17D6379040A1C836CA18234278DFDA205EFD55D527C7F38766D4C97 + +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMMI8 +%!PS-AdobeFont-1.1: CMMI8 1.100 +%%CreationDate: 1996 Jul 23 07:53:54 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.100) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMMI8) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.04 def +/isFixedPitch false def +end readonly def +/FontName /CMMI8 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 110 /n put +readonly def +/FontBBox{-24 -250 1110 750}readonly def +/UniqueID 5087383 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE +3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B +532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 +B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B +986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE +D919C2DDD26BDC0D99398B9F4D03D6A8F05B47AF95EF28A9C561DBDC98C47CF5 +5250011D19E9366EB6FD153D3A100CAA6212E3D5D93990737F8D326D347B7EDC +4391C9DF440285B8FC159D0E98D4258FC57892DDF753642CD526A96ACEDA4120 +788F22B1D09F149794E66DD1AC2C2B3BC6FEC59D626F427CD5AE9C54C7F78F62 +C36F49B3C2E5E62AFB56DCEE87445A12A942C14AE618D1FE1B11A9CF9FAA1F32 +617B598CE5058715EF3051E228F72F651040AD99A741F247C68007E68C84E9D1 +D0BF99AA5D777D88A7D3CED2EA67F4AE61E8BC0495E7DA382E82DDB2B009DD63 +532C74E3BE5EC555A014BCBB6AB31B8286D7712E0E926F8696830672B8214E9B +5D0740C16ADF0AFD47C4938F373575C6CA91E46D88DE24E682DEC44B57EA8AF8 +4E57D45646073250D82C4B50CBBB0B369932618301F3D4186277103B53B3C9E6 +DB42D6B30115F67B9D078220D5752644930643BDF9FACF684EBE13E39B65055E +B1BD054C324962025EC79E1D155936FE32D9F2224353F2A46C3558EF216F6BB2 +A304BAF752BEEC36C4440B556AEFECF454BA7CBBA7537BCB10EBC21047333A89 +8936419D857CD9F59EBA20B0A3D9BA4A0D3395336B4CDA4BA6451B6E4D1370FA +D9BDABB7F271BC1C6C48D9DF1E5A6FAE788F5609DE3C48D47A67097C547D9817 +AD3A7CCE2B771843D69F860DA4059A71494281C0AD8D4BAB3F67BB6739723C04 +AE05F9E35B2B2CB9C7874C114F57A185C8563C0DCCA93F8096384D71A2994748 +A3C7C8B8AF54961A8838AD279441D9A5EB6C1FE26C98BD025F353124DA68A827 +AE2AF8D25CA48031C242AA433EEEBB8ABA4B96821786C38BACB5F58C3D5DA011 +85B385124C2B6534F3CD1866AF92009D93B97F763AA3CF46C60636D7FC1564CF +1DDFBC12CA37D27A79B11F2AFF2D70DBEE03CF1DFA5B864A2DC22266E4FA43DC +3F2CC229231F1F72874E6A74A90E8003B9AF1BFAA55C071FDDE5C94E4AE3C5BF +936EDFD4164624881410AB9EF0593F823D40BA7D059992104D08E41EBAD8F276 +A84EE2C9AEBC7CCB72AA6B6E6FE52293DC7BC34C2D1B69418392608FC5920291 +733654FA401E05F3E647B1C6AF4BECC3E802F9963344B05EC3DE8C774293CDB4 +3F057D6F258BD341848FA7FDCFD4D1923FCAB51FA8ADAE6D9F19C1FFA6EB5E9F +ECF844CEC6C1320D3F00C7259EF5812526F58248C61F89A42D9C9288CA8076FA +77E1C950940D8D6A7D852A0D0ABEBF2EDEDCDF6DDE0C8CCAC8DA9B28207D9CF8 +46446E1153D8D8795EE914B12349137D4BE461BCF5A6A3CF15FA5B9E91EB9B90 +0483916D0CD40EDC29EB0B996B16462A64F3B19B57802D9AFE3F1D91D9A8553C +531EB8B4E975037ED620EED3020388BFE705958B1E3AD4638B9CC8644C2F4024 +5DACD97151C3DF7A448CC3 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMMI10 +%!PS-AdobeFont-1.1: CMMI10 1.100 +%%CreationDate: 1996 Jul 23 07:53:57 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.100) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMMI10) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.04 def +/isFixedPitch false def +end readonly def +/FontName /CMMI10 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 59 /comma put +dup 76 /L put +dup 85 /U put +dup 102 /f put +dup 103 /g put +dup 104 /h put +dup 105 /i put +dup 110 /n put +dup 120 /x put +readonly def +/FontBBox{-32 -250 1048 750}readonly def +/UniqueID 5087385 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE +3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B +532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 +B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B +986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE +D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958 +9E394A533A081C36D456A09920001A3D2199583EB9B84B4DEE08E3D12939E321 +990CD249827D9648574955F61BAAA11263A91B6C3D47A5190165B0C25ABF6D3E +6EC187E4B05182126BB0D0323D943170B795255260F9FD25F2248D04F45DFBFB +DEF7FF8B19BFEF637B210018AE02572B389B3F76282BEB29CC301905D388C721 +59616893E774413F48DE0B408BC66DCE3FE17CB9F84D205839D58014D6A88823 +D9320AE93AF96D97A02C4D5A2BB2B8C7925C4578003959C46E3CE1A2F0EAC4BF +8B9B325E46435BDE60BC54D72BC8ACB5C0A34413AC87045DC7B84646A324B808 +6FD8E34217213E131C3B1510415CE45420688ED9C1D27890EC68BD7C1235FAF9 +1DAB3A369DD2FC3BE5CF9655C7B7EDA7361D7E05E5831B6B8E2EEC542A7B38EE +03BE4BAC6079D038ACB3C7C916279764547C2D51976BABA94BA9866D79F13909 +95AA39B0F03103A07CBDF441B8C5669F729020AF284B7FF52A29C6255FCAACF1 +74109050FBA2602E72593FBCBFC26E726EE4AEF97B7632BC4F5F353B5C67FED2 +3EA752A4A57B8F7FEFF1D7341D895F0A3A0BE1D8E3391970457A967EFF84F6D8 +47750B1145B8CC5BD96EE7AA99DDC9E06939E383BDA41175233D58AD263EBF19 +AFC0E2F840512D321166547B306C592B8A01E1FA2564B9A26DAC14256414E4C8 +42616728D918C74D13C349F4186EC7B9708B86467425A6FDB3A396562F7EE4D8 +40B43621744CF8A23A6E532649B66C2A0002DD04F8F39618E4F572819DD34837 +B5A08E643FDCA1505AF6A1FA3DDFD1FA758013CAED8ACDDBBB334D664DFF5B53 +95601766758C197F327101A9C9BF396ED625E27A7791ADF7474135C50F2F927A +5B5E332A003F858399565E4C02931D19AC2866CEFAB2288ACA215F2B7BE37156 +89009B14D623E0A872AC17AA52D29EA6E8D725A05A300AAD937745F61803544E +978846734C4C8FEA576A5D77903920CF4531C051776BBDF99ABD8C09849E586C +ED0E1D51A0047D2FF9097EA10DE0E397D69BC302D7A949CC435EE46C508FB6D6 +DAA66F2EDD3A6881D50A440A702018A99102DE5039F7CA1EF9F4C36D5C66AA4C +97C81079C961F48C6EC9E1C26E3740945443C9A262373410B96043CF52CA074A +D18DAFCE0ADE27C2C4A109C21C1B2A8E2F9DF1F14ED57195984F76A5B4213F69 +53C017777402DB63066D528BD2C690959CFE72FAE34C98CA3E797C3CE2B8544E +143B2BB6D7ED137528BC8BB4AB4BB49A295C43C96E92D2D4AA0157DD37CFE2DA +921259A6876045871A994E1316BD39142279BEED0AFCAE7F8D847650D409C934 +D8D16486AC153C8C6F5849270F71DBB5A744A258D5EF64F8819025F49B5A3D29 +889F9CE6CAFB1A44F503559B63B9BEB727C9FD6F99F1E618DEC55C349E1D24BA +3E4599AC645E89E2852D0E152DC94465071B3835EDC93C2924778DFAC1664734 +98F5583DDF83315203AAF78897CE1768F22083276F6D29D07C72CE4B3FF6F293 +28DC673F80626F8654E4FCF6A0263C1DB7AC8F63790729256F9B969908F3A176 +05D7AD6ED5F8E8AF79890282AE7B4C55AEE6526920983A72C5876DE620CF4E3A +7D1376FEF0B296F62C5C29D8D9BEE6B622AAFB66335001F92DAA1E119CFD5101 +08FCB0F238A64FCF56A62C7C08C0871C8D15DB0374C53D39CCD8B1058BAA3FAF +F9785E2D17FCE278B5179EB8AE77B6F1ADBDA6284B0658A07D91B044ABD82EE8 +C9F1763A966496728615DD1EBAB159D7CF6168DBB2582815DA6733785828DF75 +D6848392D3E479E5527DFC967F36D3D66CA6FE01FC6FA9BF6AD401051013DE6A +C69971B1271DFE6ED6A8B53B394CE11FEE75CB1F9AB278A74FD2765FFA3773F9 +F61B5B11C462CE38287536B946E7BD1F8AE0C8F5804B04AFDBB624A2489DAE07 +903F90656C96D1E1C2101FBB9B48C66BFED1B572CEEA04A16AAFE734E754251F +EC12CAF4D56AA5A936D40CBB44E76FF4780B8594967138A1E3092254DB2D4C2C +CDECE9AF76FAF9B3DED9847C79C1723CDD328E4B0B15566C6CD8490ADFEB9169 +418B34C36EF4FB43EF7FB5F1BFE7F795E85FEBA443DCABD076418BA94DAE6505 +D4E6075D792C0C1A6BDFF56326FBA965DFB9519F072BBB8CA486D4C9AA6FCF62 +3CDACB91B41C69837DB4E6DACD0AC582A044D526E340343720AED1742DC4E52F +67579B3A625C4B5E508BCFF3DA667DAE69B25F9D50996033797C42D7CBD85F99 +AB2CDCF739E3B2C6AEA3C315AC2D0F0D48B293B1397A9C1E304260CD8D0C3497 +27385284419D6B3BFCD701C367149332FA1A58EAA22A193C24375D40482129C0 +55BD4147CF597B64FD1F3F3545A03235B6918790D39B7473FE8AE5ED218500D2 +1F6B8EE7632762D06578544C16D9D3866B4A8295904C95CE224E15044770C7B8 +F7408C215A0FA286CAE554D3C51D6BF20B33F4890784816A1AD1B202C381DA82 +01CBEFC0B043181DCD849BCCF035C87708B6E3A9CE4D68B61E35B9CF54123A30 +0939400BA136E6CD4D30F42259ADDAAC17D613E6998BBE4F37C414F397D802AF +83EB5B4247C648B834C3F59C566F252EACE08706E410299F72BEAB9A49274E5E +74F834B4A5983F4C00932124B5D9DFA54E5EF7C1CB9A97C29B49BBCE6F00AE13 +E9CB172D2033E719841728DAB47C858BA8C0687B844B7FC5C2513F5A88A9E5DF +436A28193F1C9A42F840634CCB6681EFC5249080769728E330520A5D6D50164C +0C9A8456535BC89E45BDA70C62CC42C5E750470EFAE512202D95E5BAF604352E +8001E29161B7D6FB6CAD331E42E636021B2854923894715B496038F4AEDBD1E9 +12CC6F15B440C87B8633C43B5D696AFE0C8ACDDC98503A6B3F8685987D178FD6 +E3E8DC9763CCB10ED3D8E065CF3354496D648053B2F0B7B5596528AA91EB6F7D +F7E856ECB8DDB8523CAB5CB6349827450C58A3B007CB9928AF1E98DF77D84B4A +A97B85CEC023289C82A2189AB947C56BAA64911653C2FFFB4D546F3A08821136 +14E904163C9F1CBC64BCC368CBE5764423BB308364B8CA907F38687A153BB01F +6BAE773B21DB3FFE55F9523A52C6286FA2C090F4B8EA11A7C793AC55AAEDDF0C +5E9219B11A940F1ACDE2E124F42F040C9B29D8A56099B0592E1FC33C42B5BAF5 +5CD5E0997B66D81132C4DEE5A9B34AB0761164E23B1418D9AF2EF466EE648BF7 +B550A0559B37AA4EEFE096D5B7B65A891FBB0364CDB8FAC49A7011152CA04B0C +4A91E982CF0E718DBDCAE97F90BC2D22EEA14CDE4003702563D5E02D758A3839 +4A4DDC3DF05069E1F23CB5B5ED68DBFDD1E26FF41967D5158056D86DE8BFAE94 +407645A693988C796417224C91661505FA3983863E2563E4228A5E76BA5E72B9 +10C08AF95D0C4C29E812EF8B3E2CD401562C1C7A35E49054D492DE9712D89C49 +FCB524E3D479A05DABA3D774E30F247A9287407468809AB93E53C3F9B5F5A6D7 +74F447C46BDA6AC95BBFF5A39268259C1E4A4C16FBE30C2DAD58C1D3F9DF5887 +CFE667D2E29DDBA05CE796355F0E1EC3A10FA0421074651E0B584FBD4A04D4C1 +3B4E8E729EB0F7676958F4A3677504132AEAF0DF00F781E4CC4E055917D0F363 +327C3C8E48E75675D425B02D4387269FC8487A325155B0335D +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMR10 +%!PS-AdobeFont-1.1: CMR10 1.00B +%%CreationDate: 1992 Feb 19 19:54:52 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.00B) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMR10) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle 0 def +/isFixedPitch false def +end readonly def +/FontName /CMR10 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 40 /parenleft put +dup 41 /parenright put +dup 43 /plus put +dup 48 /zero put +dup 49 /one put +dup 50 /two put +dup 53 /five put +dup 61 /equal put +readonly def +/FontBBox{-251 -250 1009 969}readonly def +/UniqueID 5000793 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 +016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 +9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F +D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 +469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 +2BDBF16FBC7512FAA308A093FE5CF7158F1163BC1F3352E22A1452E73FECA8A4 +87100FB1FFC4C8AF409B2067537220E605DA0852CA49839E1386AF9D7A1A455F +D1F017CE45884D76EF2CB9BC5821FD25365DDEA6E45F332B5F68A44AD8A530F0 +92A36FAC8D27F9087AFEEA2096F839A2BC4B937F24E080EF7C0F9374A18D565C +295A05210DB96A23175AC59A9BD0147A310EF49C551A417E0A22703F94FF7B75 +409A5D417DA6730A69E310FA6A4229FC7E4F620B0FC4C63C50E99E179EB51E4C +4BC45217722F1E8E40F1E1428E792EAFE05C5A50D38C52114DFCD24D54027CBF +2512DD116F0463DE4052A7AD53B641A27E81E481947884CE35661B49153FA19E +0A2A860C7B61558671303DE6AE06A80E4E450E17067676E6BBB42A9A24ACBC3E +B0CA7B7A3BFEA84FED39CCFB6D545BB2BCC49E5E16976407AB9D94556CD4F008 +24EF579B6800B6DC3AAF840B3FC6822872368E3B4274DD06CA36AF8F6346C11B +43C772CC242F3B212C4BD7018D71A1A74C9A94ED0093A5FB6557F4E0751047AF +D72098ECA301B8AE68110F983796E581F106144951DF5B750432A230FDA3B575 +5A38B5E7972AABC12306A01A99FCF8189D71B8DBF49550BAEA9CF1B97CBFC7CC +96498ECC938B1A1710B670657DE923A659DB8757147B140A48067328E7E3F9C3 +7D1888B284904301450CE0BC15EEEA00E48CCD6388F3FC390E75D51F36C3E61E +E84B5AD036ADADEBD4F8D399AA559B34270D370DEDF077D1D49253F313C333CB +F22FD740EDE076FE3383503F159888E77132A06528CEBA5BB0E57C07D36B73D7 +C81B71200D95D73A1AD33BBA5CA3E34B94447EAB8D27625CBFF13B56F87A9B74 +4B52A09BAB0AABD5E398B1E5E9868BC080EFC7ECBDA4D6817C3255A51A814A04 +0839172E2CCECB4F6E7B5B6B3B61D5858256AD27D93969EBB34C7EE68BF805D0 +39CA6AC7DECCD1A395E7BA297AB0E97B3290EDAED775EAB0D7D553F222A3B014 +FFA358EE448BBB24E1B44CE0BB474DFA01B0F4C4964248444FCA4DDEA8FDA9B8 +82F96DCBEF94CAC9C8F48922899CB1E7D70F650E6471E5408C44554E72599D97 +BC1D32360ECFB378192605E726A3DDA7E5B02736CEB7BE8A5C27AE952F4946D0 +1DD1D65C1D50D0317984B781D64B6075D35EC1E3507FD4FE2E7097A0EE116EEC +3497D2D84B19F68EBF7125FB02920466AE4FE25A3C3068A83A513556D05359A3 +93B6C6929BA47044787EEBA3A38E8266CF1D13DB69779644DF8AFE2C2C5C81F9 +75CBC9CA07E6CB70211CA62FD7CF596132333970E5233AAFBF984EC110664810 +AEFBADCE663CADF91D36D1587C5D7E7F63E3A674856AD7CDB99CD276D3659ED0 +CA0FDC17251E69BA7F2F3AC57257831C31AFBB0DADF44F7E6EF84D63C03E75FF +886FFDAF8153EA8E0779E46935AB0AEFC84AC2061291D39E5F67FB75BEA48EDA +030512CDB14B16D466CFBC58D3764B83AF5C00D05A3F052F53BBE4E1417773CA +BDBEAC50BB7BFF981255BDA6650870E4D67BCB80A63BA050F2650934CB6E742B +B2B2A115C1F9827C979E8F2E92C0A1F428288643C8A27B7105587366E1BFF1FB +056DE92CAD4A7F391A483DE4E9930E8C5BA9B215F1E3FA4798A1740A9B72810A +44CD1D1ECAC8ED7BA3655C4EEF6BF28A2B0B23B0BF783A4FBDDB1246B5EEA601 +6440F98C0A3B6ED360561479EA83990A78A0F4608698B30FE6476AED9349D11F +FB467D3C19D7A3539B8A2DA0C54454A231B87FB441A1BE6893E0F67081E8FF09 +FC20412C452D8227D4BA7665EA8F14A1987845CF8570EDD926F4EF5F2D85DB99 +736D7A939D4313F589033FA135D6366EB8B63C026357360A9E8717656ADABA76 +11B9D672B7D57F1422CAEA295A774CB1F6BEAE51A7A9F7EACF6F22CC6412F1D6 +9DDF884EB94F91B5F301039EE962C51F7FCEF8319CE80F46A7E3187EE60342DB +4057C2374CF68AAD30B5979B24D41ED8A803A1E6EA845D7E7675031A2D4257D8 +4BE91A75006673CE3C24AA4C4138EED6DE5147FD16049BC523D54F26BF951AAC +85157DB39E8B38798267AE2E5266331CFAA0E4D18D2F5C50277BE056498E569E +90AB0A7127F94F0EEC3FC2DC7BF421A2A855318646BACC78EC03D14CC41AB9CA +61649659F81614F8FA9E052F37445DBAF2B0873A06015E16A268544FB047AD0A +E9EF324844E8CA272D00944D54B691CA137E1CF59B69F59D5F9A40EEA081C9EC +6AD88DB832E588F5AACA900198105A8D59C215DCD387B32FE34E9B8476AB5C7A +B739EEE6840ACBFDC79501A04FFB2A57D3A4D3D181D68F074DFB0E828C41FBE3 +E7D0F2A7CE0AC1C7ED09FD9C6E085C89E8BC46BA83A8CED54EDB6EDE1B55B349 +84C37F33BB71994A8EF29050A902448E21CA0B2B5E9DDCF43ACBB79CC841E7EA +5D8BA0D8C18DDFB3B72559BF6251A5F026FAEB035509D20058FEC5FDB1B7E329 +3E299B4FBDF2BD3A5D27035BB8732C3688C3C203D1664522CEBC8BCAC7D4E643 +6490E8CAE79FB51F9285A64099719EA841CD4710392D94660920608397214CEA +588A9CFC233DA75C7C8F381ECEA4065F431122D472D333B2E260DB32F5CCCB15 +56BB953DEC3B6E451B212ABBE079888B73C48744CF5A9C1DCB47C423C647A94F +2B4358B020B2C5FDF1D4B7BE081BC0F4EA86359DFE9BDCC1CBDA475618A71ED4 +F61834FCC9DAA616C7C8D2407333ECE57AD5F5F43FD077EB12C2310BF7EB1EFC +1EAEE06F0891DEFD32AF69082D203207524CA6DC8005C22C1C1CE2C6CBED42B3 +122148A0A6BAFC0DEEEC37594B68494BB5EF16E510C1CD4BF3F6597F98E5362C +544F51DC368425AD6A867D1E6E9AB208C77982536D56581A539597DC172F1D09 +BF027427518C4CCD96BD4321DD8FF54C8D034F66F32F3A2DDFA05E33E5C5408B +8C8511FE0E8F52F38475B84E2A2F5F7B09F8F92D8E1DE2754E683A39EE71BD78 +EFFA9E0804386F6B98CB37112C4A8844C8E2F26C8920CD18089BE16D20922DD4 +AF2EFCE40BCFFB79A001E1DFF89AC67B02FFB09FD38354B57A5FAD9BA3640064 +E4CB7CFC355B5384699A57E86513CA2F89B938688A3F42A6FDBC6E92D50C050E +B96AFCE7691A96AEC83213FC00BD81EA3895 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMSY10 +%!PS-AdobeFont-1.1: CMSY10 1.0 +%%CreationDate: 1991 Aug 15 07:20:57 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.0) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMSY10) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.035 def +/isFixedPitch false def +end readonly def +/FontName /CMSY10 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /periodcentered put +dup 15 /bullet put +dup 102 /braceleft put +dup 103 /braceright put +readonly def +/FontBBox{-29 -960 1116 775}readonly def +/UniqueID 5000820 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964 +7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4 +A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85 +E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A +221A37D9A807DD01161779DDE7D31FF2B87F97C73D63EECDDA4C49501773468A +27D1663E0B62F461F6E40A5D6676D1D12B51E641C1D4E8E2771864FC104F8CBF +5B78EC1D88228725F1C453A678F58A7E1B7BD7CA700717D288EB8DA1F57C4F09 +0ABF1D42C5DDD0C384C7E22F8F8047BE1D4C1CC8E33368FB1AC82B4E96146730 +DE3302B2E6B819CB6AE455B1AF3187FFE8071AA57EF8A6616B9CB7941D44EC7A +71A7BB3DF755178D7D2E4BB69859EFA4BBC30BD6BB1531133FD4D9438FF99F09 +4ECC068A324D75B5F696B8688EEB2F17E5ED34CCD6D047A4E3806D000C199D7C +515DB70A8D4F6146FE068DC1E5DE8BC57030ACE57A0A31C99BEDB251A0ECAD78 +253AB3339E847FBB1AF693606A973F6ECD887C325CA59C6A4A9AC48AF5551D10 +EE26B8C4DA13F670D3F0C09187B9AB37F2BA6A32F8D363393D22215650EEE7F8 +DFB1378390C44F36098EA2DA6CB943DACFB8AECD62E46F120BE7A15C19200094 +7975CA278BAF5E155531F90FCBFE67D2AC15BA6E3B15FEF09F697956F198D111 +16292151DECACDAF2B2CF42B82DE6D4515735744887745770F8D8656BAEEFC04 +2F6A832F466D4244F1F9998BF49A413F094108FC90F586AEB324888BD885F2A1 +C749504E6DCB10F6A2B797826939AFA46BD208A268FB4C6635264B2B39F6E11E +34ED5B3D02E6C9178BFE61AE0A0B6B789E394F8A33730EC5E4484F2D962268F5 +8FD36EAD6CF68C7120E82FD8B2EA91095227CFF985054557361FD9B1E8FACB8C +A17AD35513D4D69B5D52470A6B4796299442430E66AAB39A574CF4C4D0838C52 +B675FB04C646FE52C599EA039302B200CEA102986E6549225D22F30455B7947B +5DCF0190B5296E12FA026272B1D2076B630CABB8F71589ECB69B95486A650A09 +05D11C00F0909A7228A107C7D27074FC6B5380FB3534816E122D65369D70C68E +98E1951DA9756B3CD665F378B661506661175A89D37889CDB07D1692988875EE +878DC0771EF29DDB382287584FE12E47FD7CEE6C130E2D2B3028C8C54B83C977 +26845C0960D62A50B290605368BE2568340524244ABCEE470B683E92456DEE76 +228DCCBDBC688458DF63F2C1E4D8BA46657CB79B9E28179AD2459603874FC200 +CAB2ABDBD725DB89EB7E7C5DFE03826FC7EA65F57CF87E382A976D70F44596B5 +53C6DC34FE7F2B295D67AA8A550F1DF1D040237352D42F14D1D0E7A23318E53B +BA0958CC11E47508EE8D9DCAB8116452978F0963222D14739F8E890A39AB41BC +B66B92570A18 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +%%BeginFont: CMMI12 +%!PS-AdobeFont-1.1: CMMI12 1.100 +%%CreationDate: 1996 Jul 27 08:57:55 +% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. +11 dict begin +/FontInfo 7 dict dup begin +/version (1.100) readonly def +/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def +/FullName (CMMI12) readonly def +/FamilyName (Computer Modern) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.04 def +/isFixedPitch false def +end readonly def +/FontName /CMMI12 def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 60 /less put +dup 62 /greater put +readonly def +/FontBBox{-30 -250 1026 750}readonly def +/UniqueID 5087386 def +currentdict end +currentfile eexec +D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE +3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B +532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 +B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B +986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE +D919C2DDD26BDC0D99398B9F4D03D6A8F05B47AF95EF28A9C561DBDC98C47CF5 +5250011D19E9366EB6FD153D3A100CAA6212E3D5D93990737F8D326D347B7EDC +4391C9DF440285B8FC159D0E98D4258FC57892DCC57F7903449E07914FBE9E67 +3C15C2153C061EB541F66C11E7EE77D5D77C0B11E1AC55101DA976CCACAB6993 +EED1406FBB7FF30EAC9E90B90B2AF4EC7C273CA32F11A5C1426FF641B4A2FB2F +4E68635C93DB835737567FAF8471CBC05078DCD4E40E25A2F4E5AF46C234CF59 +2A1CE8F39E1BA1B2A594355637E474167EAD4D97D51AF0A899B44387E1FD933A +323AFDA6BA740534A510B4705C0A15647AFBF3E53A82BF320DD96753639BE49C +2F79A1988863EF977B800C9DB5B42039C23EB86953713F730E03EA22FF7BB2C1 +D97D33FD77B1BDCC2A60B12CF7805CFC90C5B914C0F30A673DF9587F93E47CEA +5932DD1930560C4F0D97547BCD805D6D854455B13A4D7382A22F562D7C55041F +0FD294BDAA1834820F894265A667E5C97D95FF152531EF97258F56374502865D +A1E7C0C5FB7C6FB7D3C43FEB3431095A59FBF6F61CEC6D6DEE09F4EB0FD70D77 +2A8B0A4984C6120293F6B947944BE23259F6EB64303D627353163B6505FC8A60 +00681F7A3968B6CBB49E0420A691258F5E7B07B417157803FCBE9B9FB1F80FD8 +CA0DA1186446DD565542BCCC7D339A1EB34C7F49246E8D72E987EB477C6DB757 +99AF86CEBCD7605C487A00CD2CD093098182DC57B20D78ECE0BECF3A0BF88EBA +C866DB19F34BBBED6634AFC0F08D2AFB2A92578A6F8B4ADCD6594737FF6EED7D +5B536DA9E3E2CADB40DB7C600EA4D100D33C3B92B1CF857E012C4EB370BA8295 +55B50047CD58E912E67E22C1B92F41D0BEE742201DF198F3766AE35EA71D8195 +A8C94D661C40D718CB09497485FAA34204229AECFE644C93FFDA54C789E4F751 +3D2519F7CB9E79B2ABE3101DF2EBFAD375469CDC687FB3DC2833EDC0F946B41F +F28D72FFF2A9B8B0D76DC542537612E2BE0F3FB9601C897386359C55E867A547 +F872005F5C56C6EC5E9685E03D7A82653BE8B69741C4DF332AEEB2AA450B23F3 +EABD5ED060606CC7DB1762632EC3C6C4A66ADAF61A97D949DEA5156B4CF34765 +67AC3F10AE17199A710A882D47979F9D41AA2CB794648BE47479F0B00E18BF04 +923F54CEC1214BAFA39BB65ECB013875899E9901B7882D16D2E2C97AD3353668 +A6070081E4DC627AF9192599F5876369908FBDFA11E8D6CB2E83896E9C897CEC +FD1D25651D66A333AF531FF74E1B0DEB1E3D1B5B7D3FB9D1C8BF60517B31C8D2 +1C264F44BC9AF3D9BA5280D1618EED96C11ED24F789FAA263394C658DFCA8DE9 +D47D9E188E212F9EC1DCF449DFDAB8437FAB9EA9AF01AE1714E8F932855182 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndFont +TeXDict begin 40258431 52099146 1000 600 600 (cudd.dvi) +@start /Fa 137[40 51 1[35 35 8[25 2[30 40 45 40 16[61 +13[66 61 67[{ TeXBase1Encoding ReEncodeFont }12 90.9091 +/Times-BoldItalic rf /Fb 136[50 7[37 2[21 108[{ + TeXBase1Encoding ReEncodeFont }3 74.7198 /Times-Italic +rf /Fc 204[35 35 35 35 48[{}4 66.4176 /CMR8 rf /Fd 207[19 +47[55{}2 66.4176 /CMSY8 rf /Fe 133[33 37 37 54 37 37 +21 29 25 1[37 37 37 58 21 37 1[21 37 37 25 33 37 33 37 +33 9[71 54 54 46 11[54 2[46 54 50 7[21 21 10[21 19 25 +19 41[42 2[{ TeXBase1Encoding ReEncodeFont }39 74.7198 +/Times-Roman rf /Ff 201[25 25 25 25 25 25 49[{ + TeXBase1Encoding ReEncodeFont }6 49.8132 /Times-Roman +rf /Fg 201[33 33 33 33 33 33 49[{ TeXBase1Encoding ReEncodeFont }6 +66.4176 /Times-Roman rf /Fh 130[55 55 55 55 55 55 55 +55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 +55 55 55 55 1[55 1[55 55 55 55 1[55 1[55 55 55 55 55 +55 55 55 55 55 55 2[55 55 55 55 55 55 55 55 55 55 55 +55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 +55 55 55 55 55 2[55 1[55 55 55 33[{ TeXBase1Encoding ReEncodeFont }84 +90.9091 /Courier rf /Fi 133[44 50 1[72 50 55 33 39 44 +55 55 50 55 83 28 55 1[28 55 50 33 44 55 44 55 50 6[66 +2[100 72 72 66 55 72 1[61 78 1[94 66 78 1[39 78 78 61 +1[72 72 66 72 7[50 50 50 50 50 50 50 50 50 50 28 25 46[{ + TeXBase1Encoding ReEncodeFont }56 99.6264 /Times-Bold +rf /Fj 145[43 110[{}1 66.4176 /CMMI8 rf /Fk 135[52 9[55 +4[31 52 43 45 16[62 8[62 16[25 59[{}9 90.9091 /CMMI10 +rf /Fl 194[71 7[45 2[45 45 45 4[71 1[35 35 40[{}8 90.9091 +/CMR10 rf /Fm 152[45 45 86[45 13[25 1[{}4 90.9091 /CMSY10 +rf /Fn 133[35 40 40 61 40 45 25 35 35 45 45 45 45 66 +25 40 25 25 45 45 25 40 45 40 45 45 6[51 1[56 76 56 66 +51 45 56 66 56 66 61 76 51 61 40 30 66 66 56 56 66 61 +56 56 7[45 1[45 3[45 45 45 2[23 30 3[30 30 30 35[45 45 +2[{ TeXBase1Encoding ReEncodeFont }63 90.9091 /Times-Italic +rf /Fo 87[30 16[91 45 1[40 40 24[40 45 45 66 45 45 25 +35 30 45 45 45 45 71 25 45 25 25 45 45 30 40 45 40 45 +40 3[30 1[30 56 66 66 86 66 66 56 51 61 66 51 66 66 81 +56 66 35 30 66 66 51 56 66 61 61 66 5[25 25 45 45 45 +45 45 45 45 45 45 45 25 23 30 23 51 1[30 30 30 1[76 33[51 +51 2[{ TeXBase1Encoding ReEncodeFont }82 90.9091 /Times-Roman +rf /Fp 105[45 27[40 45 45 66 45 51 30 35 40 1[51 45 51 +76 25 51 1[25 51 45 30 40 51 40 51 45 6[61 66 66 91 66 +66 61 51 66 1[56 71 66 86 61 2[35 71 71 56 61 66 66 61 +66 5[30 30 1[45 1[45 45 45 45 45 45 45 1[23 1[23 52 3[30 +36[51 2[{ TeXBase1Encoding ReEncodeFont }63 90.9091 /Times-Bold +rf /Fq 135[60 86 1[66 40 47 53 2[60 66 100 33 66 1[33 +66 60 40 53 66 53 1[60 11[86 80 1[86 1[73 2[113 3[47 +93 93 2[86 86 1[86 10[60 60 60 60 60 60 5[68 3[40 39[{ + TeXBase1Encoding ReEncodeFont }38 119.552 /Times-Bold +rf /Fr 193[76 1[76 60[{}2 99.6264 /CMMI12 rf /Fs 133[44 +50 2[50 50 28 39 33 1[50 50 50 78 28 2[28 1[50 33 44 +50 44 50 44 11[72 1[55 12[55 61 72 66 66 1[92 11[50 1[50 +50 50 1[25 1[25 44[{ TeXBase1Encoding ReEncodeFont }34 +99.6264 /Times-Roman rf /Ft 140[56 48 2[72 72 112 40 +72 1[40 1[72 1[64 1[64 1[64 11[104 2[96 1[80 11[104 96 +8[40 4[72 2[72 1[72 1[36 46[{ TeXBase1Encoding ReEncodeFont }22 +143.462 /Times-Roman rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin + end +%%EndSetup +%%Page: 1 1 +TeXDict begin 1 0 bop Black Black Black Black 804 937 +a Ft(CUDD:)34 b(CU)i(Decision)d(Diagram)h(P)n(ackage)1558 +1120 y(Release)g(2.5.0)1643 1373 y Fs(F)o(abio)25 b(Somenzi)720 +1489 y(Department)f(of)h(Electrical,)g(Computer)l(,)f(and)h(Ener)n(gy)g +(Engineering)1261 1605 y(Uni)n(v)o(ersity)e(of)i(Colorado)f(at)h +(Boulder)1408 1721 y Fr(<)p Fs(F)o(abio@Colorado.EDU)p +Fr(>)1601 1923 y Fs(February)h(4,)e(2012)448 2316 y Fq(Contents)448 +2523 y Fp(1)92 b(Intr)n(oduction)2315 b(4)448 2726 y(2)92 +b(Ho)o(w)22 b(to)i(Get)f(CUDD)2077 b(5)585 2839 y Fo(2.1)96 +b(The)23 b(CUDD)e(P)o(ackage)92 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 171 w(5)p Black 585 2952 a(2.2)96 b(CUDD)21 b(Friends)81 +b(.)45 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(5)p +Black 448 3156 a Fp(3)92 b(User')m(s)23 b(Manual)2238 +b(5)585 3269 y Fo(3.1)96 b(Compiling)24 b(and)g(Linking)53 +b(.)45 b(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(6)p Black 585 3382 +a(3.2)96 b(Basic)23 b(Data)h(Structures)51 b(.)45 b(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +p Black 171 w(6)p Black 794 3495 a(3.2.1)110 b(Nodes)41 +b(.)46 b(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 +w(6)p Black 794 3608 a(3.2.2)110 b(The)23 b(Manager)60 +b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(7)p Black 794 +3721 a(3.2.3)110 b(Cache)46 b(.)g(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +p Black 171 w(8)p Black 585 3833 a(3.3)96 b(Initializing)26 +b(and)e(Shutting)h(Do)n(wn)e(a)g(DdManager)78 b(.)46 +b(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(8)p +Black 585 3946 a(3.4)96 b(Setting)24 b(P)o(arameters)87 +b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(9)p Black +585 4059 a(3.5)96 b(Constant)25 b(Functions)66 b(.)45 +b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 171 w(9)p Black 794 +4172 a(3.5.1)110 b(One,)23 b(Logic)g(Zero,)g(and)h(Arithmetic)h(Zero)41 +b(.)46 b(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +171 w(9)p Black 794 4285 a(3.5.2)110 b(Prede\002ned)24 +b(Constants)51 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(10)p Black 794 +4398 a(3.5.3)110 b(Background)36 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(10)p Black 794 4511 a(3.5.4)110 b(Ne)n(w)22 +b(Constants)65 b(.)45 b(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(11)p +Black 585 4624 a(3.6)96 b(Creating)25 b(V)-10 b(ariables)28 +b(.)45 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(11)p +Black 794 4737 a(3.6.1)110 b(Ne)n(w)22 b(BDD)f(and)j(ADD)e(V)-10 +b(ariables)43 b(.)i(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)p Black 125 w(11)p Black 794 4850 a(3.6.2)110 b(Ne)n(w)22 +b(ZDD)f(V)-10 b(ariables)81 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(12)p +Black 585 4963 a(3.7)96 b(Basic)23 b(BDD)f(Manipulation)47 +b(.)f(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)p Black 125 w(12)p Black Black 1920 +5225 a(1)p Black eop end +%%Page: 2 2 +TeXDict begin 2 1 bop Black Black 585 573 a Fo(3.8)96 +b(Basic)23 b(ADD)f(Manipulation)42 b(.)k(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(13)p Black 585 686 a(3.9)96 b(Basic)23 b(ZDD)f +(Manipulation)52 b(.)46 b(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(14)p +Black 585 799 a(3.10)51 b(Con)l(v)o(erting)26 b(ADDs)c(to)h(BDDs)f(and) +i(V)-5 b(ice)23 b(V)-10 b(ersa)85 b(.)45 b(.)h(.)f(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)p Black 125 w(15)p Black 585 912 a(3.11)51 +b(Con)l(v)o(erting)26 b(BDDs)c(to)h(ZDDs)f(and)i(V)-5 +b(ice)23 b(V)-10 b(ersa)27 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)p Black 125 w(15)p Black 585 1024 a(3.12)51 +b(V)-10 b(ariable)24 b(Reordering)i(for)e(BDDs)e(and)i(ADDs)63 +b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(16)p Black 585 1137 a(3.13)51 b(Grouping)25 +b(V)-10 b(ariables)61 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(19)p Black 585 1250 a(3.14)51 b(V)-10 b(ariable)24 +b(Reordering)i(for)e(ZDDs)68 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(20)p +Black 585 1363 a(3.15)51 b(K)n(eeping)24 b(Consistent)i(V)-10 +b(ariable)24 b(Orders)h(for)e(BDDs)f(and)i(ZDDs)46 b(.)f(.)g(.)g(.)g(.) +p Black 125 w(21)p Black 585 1476 a(3.16)51 b(Hooks)k(.)45 +b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(21)p Black 585 1589 a(3.17)51 b(T)m(imeouts)24 +b(and)g(Limits)82 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(22)p Black 585 1702 a(3.18)51 b(The)23 b(SIS/VIS)f(Interf)o(ace) +27 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(22)p Black +794 1815 a(3.18.1)65 b(Using)24 b(the)f(CUDD)f(P)o(ackage)i(in)f(SIS)h +(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(22)p Black 585 1928 a(3.19)51 b(Writing)24 +b(Decision)h(Diagrams)f(to)g(a)f(File)57 b(.)45 b(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(24)p +Black 585 2041 a(3.20)51 b(Sa)n(ving)24 b(and)g(Restoring)h(BDDs)78 +b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)p Black 125 w(24)p Black 448 2245 a Fp(4)92 +b(Pr)n(ogrammer')m(s)25 b(Manual)1870 b(24)585 2357 y +Fo(4.1)96 b(Compiling)24 b(and)g(Linking)53 b(.)45 b(.)h(.)f(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(24)p Black 585 2470 a(4.2)96 b(Reference)25 +b(Counts)53 b(.)45 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(26)p Black 794 2583 a(4.2.1)110 b(NULL)21 b(Return)j(V)-10 +b(alues)42 b(.)j(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)p Black 125 w(27)p Black 794 2696 +a(4.2.2)110 b Fn(Cudd)p 1286 2696 28 4 v 33 w(Recur)o(siveDer)m(ef)40 +b Fo(vs.)23 b Fn(Cudd)p 2239 2696 V 34 w(Der)m(ef)45 +b Fo(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(27)p Black 794 2809 a(4.2.3)110 b(When)23 b(Increasing)k(the)d +(Reference)h(Count)f(is)f(Unnecessary)90 b(.)45 b(.)p +Black 125 w(27)p Black 794 2922 a(4.2.4)110 b(Saturating)25 +b(Increments)h(and)e(Decrements)91 b(.)45 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)p Black 125 w(28)p Black 585 3035 a(4.3)96 b(Complement)24 +b(Arcs)37 b(.)45 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(28)p Black 585 3148 a(4.4)96 b(The)23 b(Cache)37 +b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(29)p Black 794 3261 a(4.4.1)110 b(Cache)24 +b(Sizing)64 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(29)p +Black 794 3374 a(4.4.2)110 b(Local)23 b(Caches)55 b(.)45 +b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(30)p Black 585 3487 +a(4.5)96 b(The)23 b(Unique)h(T)-7 b(able)47 b(.)e(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)p Black 125 w(31)p Black 585 3599 a(4.6)96 b(Allo)n(wing)24 +b(Asynchronous)j(Reordering)64 b(.)45 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(32)p Black 585 +3712 a(4.7)96 b(Deb)n(ugging)28 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)p Black 125 w(33)p Black 585 3825 a(4.8)96 +b(Gathering)25 b(and)f(Interpreting)j(Statistics)64 b(.)45 +b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p +Black 125 w(34)p Black 794 3938 a(4.8.1)110 b(Non)23 +b(Modi\002able)i(P)o(arameters)89 b(.)45 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(34)p Black +794 4051 a(4.8.2)110 b(Modi\002able)24 b(P)o(arameters)64 +b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)p Black 125 w(37)p Black 794 4164 a(4.8.3)110 +b(Extended)25 b(Statistics)g(and)f(Reporting)63 b(.)45 +b(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black +125 w(39)p Black 585 4277 a(4.9)96 b(Guidelines)25 b(for)f +(Documentation)75 b(.)45 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)p Black 125 w(39)p Black 448 +4481 a Fp(5)92 b(The)22 b(C++)g(Interface)2044 b(40)585 +4594 y Fo(5.1)96 b(Compiling)24 b(and)g(Linking)53 b(.)45 +b(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)p Black 125 w(40)p Black 585 4707 +a(5.2)96 b(Basic)23 b(Manipulation)58 b(.)45 b(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +p Black 125 w(40)p Black 448 4910 a Fp(6)92 b(Ackno)o(wledgments)2050 +b(41)p Black 1920 5225 a Fo(2)p Black eop end +%%Page: 3 3 +TeXDict begin 3 2 bop Black Black 585 573 a Fp(Refer)n(ences)2341 +b(41)585 777 y(Index)2539 b(43)p Black 1920 5225 a Fo(3)p +Black eop end +%%Page: 4 4 +TeXDict begin 4 3 bop Black Black 448 573 a Fq(1)120 +b(Intr)n(oduction)448 780 y Fo(The)28 b(CUDD)d(package)30 +b(pro)o(vides)g(functions)g(to)e(manipulate)i(Binary)e(Decision)i +(Diagrams)448 893 y(\(BDDs\))35 b([5,)f(3)q(],)j(Algebraic)g(Decision)g +(Diagrams)e(\(ADDs\))g([1],)j(and)d(Zero-suppressed)448 +1006 y(Binary)f(Decision)g(Diagrams)g(\(ZDDs\))e([12)q(].)56 +b(BDDs)32 b(are)h(used)g(to)g(represent)j(switching)448 +1119 y(functions;)i(ADDs)30 b(are)h(used)h(to)g(represent)h(function)h +(from)d Fm(f)p Fl(0)p Fk(;)15 b Fl(1)p Fm(g)2673 1086 +y Fj(n)2753 1119 y Fo(to)31 b(an)g(arbitrary)i(set.)448 +1231 y(ZDDs)20 b(represent)j(switching)g(functions)g(lik)o(e)f(BDDs;)e +(ho)n(we)n(v)o(er)l(,)i(the)o(y)g(are)f(much)g(more)g(ef)n(\002-)448 +1344 y(cient)27 b(than)f(BDDs)e(when)i(the)g(functions)i(to)d(be)h +(represented)j(are)c(characteristic)30 b(functions)448 +1457 y(of)h(cube)g(sets,)i(or)d(in)h(general,)i(when)e(the)g(ON-set)f +(of)g(the)h(function)i(to)d(be)h(represented)i(is)448 +1570 y(v)o(ery)24 b(sparse.)30 b(The)o(y)23 b(are)h(inferior)i(to)d +(BDDs)f(in)h(other)i(cases.)589 1683 y(The)30 b(package)h(pro)o(vides)h +(a)d(lar)n(ge)i(set)f(of)f(operations)k(on)c(BDDs,)h(ADDs,)f(and)h +(ZDDs,)448 1796 y(functions)d(to)d(con)l(v)o(ert)h(BDDs)e(into)h(ADDs)f +(or)g(ZDDs)g(and)h(vice)g(v)o(ersa,)h(and)f(a)g(lar)n(ge)h(assort-)448 +1909 y(ment)f(of)f(v)n(ariable)j(reordering)g(methods.)589 +2022 y(The)e(CUDD)d(package)k(can)f(be)g(used)g(in)g(three)g(w)o(ays:)p +Black 585 2190 a Fm(\017)p Black 46 w Fo(As)17 b(a)h(black)h(box.)28 +b(In)18 b(this)h(case,)g(the)g(application)i(program)f(that)f(needs)g +(to)f(manipulate)676 2303 y(decision)25 b(diagrams)f(only)g(uses)g(the) +g(e)o(xported)h(functions)g(of)e(the)h(package.)30 b(The)23 +b(rich)676 2416 y(set)g(of)h(functions)i(included)g(in)d(the)h(CUDD)d +(package)26 b(allo)n(ws)e(man)o(y)f(applications)k(to)676 +2529 y(be)21 b(written)i(in)f(this)g(w)o(ay)-6 b(.)28 +b(Section)23 b(3)e(describes)k(ho)n(w)c(to)h(use)g(the)g(e)o(xported)i +(functions)676 2642 y(of)g(the)h(package.)33 b(An)24 +b(application)k(written)d(in)f(terms)h(of)f(the)h(e)o(xported)h +(functions)h(of)676 2755 y(the)f(package)j(needs)e(not)g(concern)i +(itself)e(with)f(the)h(details)h(of)f(v)n(ariable)h(reordering,)676 +2868 y(which)23 b(may)h(tak)o(e)g(place)h(behind)g(the)f(scenes.)p +Black 585 3047 a Fm(\017)p Black 46 w Fo(As)h(a)g(clear)i(box.)36 +b(When)26 b(writing)g(a)g(sophisticated)j(application)g(based)e(on)f +(decision)676 3160 y(diagrams,)35 b(ef)n(\002cienc)o(y)e(often)g +(dictates)h(that)f(some)f(functions)i(be)e(implemented)i(as)676 +3273 y(direct)h(recursi)n(v)o(e)h(manipulation)i(of)c(the)h(diagrams,)j +(instead)e(of)f(being)g(written)g(in)676 3386 y(terms)e(of)g(e)o +(xisting)i(primiti)n(v)o(e)f(functions.)60 b(Section)35 +b(4)d(e)o(xplains)j(ho)n(w)e(to)g(add)h(ne)n(w)676 3499 +y(functions)j(to)f(the)f(CUDD)e(package.)66 b(It)35 b(also)h(details)h +(ho)n(w)d(to)i(write)f(a)g(recursi)n(v)o(e)676 3612 y(function)25 +b(that)f(can)g(be)g(interrupted)i(by)e(dynamic)h(v)n(ariable)g +(reordering.)p Black 585 3792 a Fm(\017)p Black 46 w +Fo(Through)c(an)f(interf)o(ace.)30 b(Object-oriented)23 +b(languages)g(lik)o(e)e(C++)e(and)h(Perl5)g(can)h(free)676 +3905 y(the)k(programmer)h(from)f(the)h(b)n(urden)h(of)e(memory)g +(management.)35 b(A)24 b(C++)g(interf)o(ace)676 4018 +y(is)k(included)i(in)e(the)h(distrib)n(ution)j(of)c(CUDD.)d(It)j +(automatically)k(frees)d(decision)h(di-)676 4131 y(agrams)g(that)f(are) +h(no)f(longer)i(used)f(by)f(the)h(application)i(and)e(o)o(v)o(erloads)h +(operators.)676 4244 y(Almost)i(all)h(the)g(functionality)k(pro)o +(vided)e(by)e(the)g(CUDD)d(e)o(xported)36 b(functions)g(is)676 +4356 y(a)n(v)n(ailable)d(through)g(the)e(C++)f(interf)o(ace,)35 +b(which)c(is)g(especially)j(recommended)f(for)676 4469 +y(f)o(ast)e(prototyping.)56 b(Section)32 b(5)f(e)o(xplains)j(ho)n(w)c +(to)i(use)f(the)h(interf)o(ace.)54 b(A)31 b(Perl5)g(in-)676 +4582 y(terf)o(ace)38 b(also)g(e)o(xists)g(and)f(is)g(ditrib)n(uted)j +(separately)-6 b(.)71 b(\(See)37 b(Section)h(2.2.\))69 +b(Some)676 4695 y(applications)27 b(de\002ne)d(their)g(o)n(wn)f(interf) +o(aces.)31 b(See)23 b(for)h(e)o(xample)g(Section)h(3.18.)448 +4863 y(In)k(the)h(follo)n(wing,)i(the)d(reader)i(is)e(supposed)j(to)d +(be)g(f)o(amiliar)h(with)f(the)h(basic)g(ideas)g(about)448 +4976 y(decision)c(diagrams,)f(as)e(found,)i(for)e(instance,)j(in)d([3)q +(].)p Black 1920 5225 a(4)p Black eop end +%%Page: 5 5 +TeXDict begin 5 4 bop Black Black 448 573 a Fq(2)120 +b(Ho)o(w)29 b(to)h(Get)g(CUDD)448 783 y Fi(2.1)99 b(The)26 +b(CUDD)f(P)o(ackage)448 957 y Fo(The)36 b(CUDD)e(package)39 +b(is)d(a)n(v)n(ailable)j(via)d(anon)o(ymous)j(FTP)34 +b(from)i(vlsi.Colorado.EDU.)448 1070 y(A)29 b(compressed)j(tar)e +(\002le)f(named)h Fh(cudd-2.5.0.tar.)o(gz)22 b Fo(can)31 +b(be)e(found)i(in)f(directory)448 1183 y Fh(pub)p Fo(.)d(Once)c(you)h +(ha)n(v)o(e)h(this)f(\002le,)p Black Black 676 1371 a +Fh(gzip)52 b(-dc)i(cudd-2.5.0.tar)o(.g)o(z)48 b(|)54 +b(tar)g(xvf)f(-)448 1559 y Fo(will)27 b(create)g(directory)j +Fh(cudd-2.5.0)21 b Fo(and)27 b(its)g(subdirectories.)42 +b(These)27 b(directories)j(con-)448 1671 y(tain)h(the)g(decision)i +(diagram)f(package,)i(a)c(fe)n(w)g(support)j(libraries,)h(and)d(a)f(to) +o(y)h(application)448 1784 y(based)23 b(on)f(the)h(decision)h(diagram)f +(package.)30 b(There)22 b(is)g(a)f(README)e(\002le)i(with)h +(instructions)448 1897 y(on)33 b(con\002guration)j(and)d(installation)j +(in)d Fh(cudd-2.5.0)p Fo(.)51 b(Y)-10 b(ou)32 b(can)i(use)f(a)f +(compiler)i(for)448 2010 y(either)25 b(ANSI)d(C)g(or)i(C++.)589 +2123 y(Once)g(you)g(ha)n(v)o(e)g(made)g(the)g(libraries)h(and)f +(program,)h(you)f(can)g(type:)p Black Black 676 2311 +a Fh(cd)53 b(nanotrav)676 2424 y(nanotrav)e(-p)i(1)h(-autodyn)d +(-reordering)f(sifting)h(-trav)676 2537 y(mult32a.blif)448 +2724 y Fo(This)26 b(will)g(run)h(a)e(simple-minded)k(FSM)c(tra)n(v)o +(ersal)j(program.)38 b(\(On)25 b(a)h(2.4)g(GHz)f(Pentium)i(4)448 +2837 y(\(TM\),)g(it)h(tak)o(es)h(about)h(0.5)e(s.\))42 +b(The)28 b(output)i(produced)g(by)f(the)f(program)h(can)g(be)f(check)o +(ed)448 2950 y(against)35 b Fh(cudd-2.5.0/nano)o(tra)o(v/)o(mu)o(lt)o +(32)o(a.o)o(ut)o Fo(.)52 b(More)34 b(information)i(on)e(the)448 +3063 y Fh(nanotrav)19 b Fo(program)25 b(can)f(be)g(found)g(in)g +Fh(cudd-2.5.0/nan)o(otr)o(av)o(/R)o(EA)o(DM)o(E)p Fo(.)589 +3176 y(If)i(you)h(w)o(ant)f(to)g(be)g(noti\002ed)h(of)f(ne)n(w)f +(releases)j(of)e(the)h(CUDD)c(package,)29 b(send)e(a)e(mes-)448 +3289 y(sage)g(to)e Fh(Fabio@Colorado.)o(ED)o(U)p Fo(.)448 +3538 y Fi(2.2)99 b(CUDD)25 b(Friends)448 3712 y Fo(T)-7 +b(w)o(o)18 b(CUDD)g(e)o(xtensions)k(are)e(a)n(v)n(ailable)h(via)f(anon) +o(ymous)i(FTP)17 b(from)i(vlsi.Colorado.EDU.)p Black +585 3900 a Fm(\017)p Black 46 w Fn(P)-7 b(erlDD)27 b +Fo(is)i(an)f(object-oriented)34 b(Perl5)29 b(interf)o(ace)i(to)d(CUDD.) +f(It)h(is)h(or)n(ganized)i(as)e(a)676 4013 y(standard)f(Perl)e(e)o +(xtension)j(module.)39 b(The)26 b(Perl)g(interf)o(ace)j(is)d(at)h(a)f +(some)n(what)h(higher)676 4126 y(le)n(v)o(el)c(than)i(the)e(C++)g +(interf)o(ace,)j(b)n(ut)e(it)f(is)h(not)g(as)f(complete.)p +Black 585 4313 a Fm(\017)p Black 46 w Fn(DDcal)g Fo(is)h(a)g(graphic)h +(BDD)e(calculator)j(based)f(on)f(CUDD,)e(Perl-Tk,)i(and)g(dot.)31 +b(\(See)676 4426 y(Section)24 b(3.19)g(for)g(information)i(on)d +Fn(dot)p Fo(.\))448 4719 y Fq(3)120 b(User')l(s)28 b(Manual)448 +4926 y Fo(This)c(section)h(describes)h(the)e(use)g(of)f(the)h(CUDD)d +(package)26 b(as)d(a)g(black)i(box.)p Black 1920 5225 +a(5)p Black eop end +%%Page: 6 6 +TeXDict begin 6 5 bop Black Black 448 573 a Fi(3.1)99 +b(Compiling)25 b(and)g(Linking)448 747 y Fo(T)-7 b(o)23 +b(b)n(uild)i(an)e(application)k(that)d(uses)g(the)g(CUDD)d(package,)26 +b(you)e(should)h(add)p Black Black 448 935 a Fh(#include)51 +b("util.h")448 1048 y(#include)g("cudd.h")448 1235 y +Fo(to)32 b(your)g(source)h(\002les,)g(and)g(should)g(link)f +Fh(libcudd.a)p Fo(,)d Fh(libmtr.a)p Fo(,)f Fh(libst.a)p +Fo(,)i(and)448 1348 y Fh(libutil.a)23 b Fo(to)28 b(your)h(e)o(x)o +(ecutable.)43 b(\(All)28 b(these)h(libraries)g(are)f(part)h(of)f(the)g +(distrib)n(ution.\))448 1461 y(Some)20 b(platforms)h(require)h +(speci\002c)e(compiler)i(and)e(link)o(er)h(\003ags.)28 +b(Refer)20 b(to)g(the)g Fh(Makefile)448 1574 y Fo(in)k(the)g(top)f(le)n +(v)o(el)h(directory)i(of)e(the)f(distrib)n(ution.)589 +1687 y(K)n(eep)d(in)g(mind)g(that)h(whate)n(v)o(er)g(\003ags)e(af)n +(fect)i(the)g(size)f(of)g(data)h(structures\227for)i(instance)448 +1800 y(the)e(\003ags)f(used)g(to)g(use)h(64-bit)g(pointers)h(where)f(a) +n(v)n(ailable\227must)i(be)d(speci\002ed)h(when)f(com-)448 +1913 y(piling)25 b(both)g(CUDD)c(and)j(the)g(\002les)f(that)h(include)h +(its)f(header)h(\002les.)448 2162 y Fi(3.2)99 b(Basic)25 +b(Data)g(Structur)n(es)448 2336 y Fp(3.2.1)92 b(Nodes)448 +2510 y Fo(BDDs,)24 b(ADDs,)h(and)h(ZDDs)d(are)j(made)g(of)f(DdNode')-5 +b(s.)35 b(A)25 b(DdNode)g(\(node)i(for)f(short\))g(is)g(a)448 +2623 y(structure)j(with)d(se)n(v)o(eral)i(\002elds.)37 +b(Those)27 b(that)g(are)f(of)h(interest)h(to)e(the)h(application)j +(that)d(uses)448 2736 y(the)e(CUDD)d(package)27 b(as)d(a)g(black)i(box) +f(are)f(the)h(v)n(ariable)h(inde)o(x,)g(the)e(reference)j(count,)f(and) +448 2849 y(the)f(v)n(alue.)33 b(The)24 b(remaining)i(\002elds)f(are)f +(pointers)j(that)e(connect)i(nodes)e(among)g(themselv)o(es)448 +2962 y(and)f(that)g(are)g(used)g(to)g(implement)h(the)e(unique)j +(table.)j(\(See)23 b(Section)i(3.2.2.\))589 3075 y(The)h +Fn(inde)n(x)i Fo(\002eld)e(holds)h(the)g(name)f(of)g(the)h(v)n(ariable) +h(that)e(labels)i(the)e(node.)38 b(The)25 b(inde)o(x)448 +3188 y(of)37 b(a)f(v)n(ariable)i(is)f(a)f(permanent)j(attrib)n(ute)g +(that)e(re\003ects)g(the)g(order)h(of)e(creation.)70 +b(Inde)o(x)448 3301 y(0)26 b(corresponds)k(to)c(the)g(v)n(ariable)i +(created)g(\002rst.)36 b(On)25 b(a)h(machine)h(with)f(32-bit)h +(pointers,)i(the)448 3414 y(maximum)21 b(number)h(of)e(v)n(ariables)j +(is)d(the)h(lar)n(gest)i(v)n(alue)e(that)h(can)f(be)f(stored)j(in)d(an) +h(unsigned)448 3527 y(short)27 b(inte)o(ger)g(minus)f(1.)35 +b(The)25 b(lar)n(gest)j(inde)o(x)f(is)e(reserv)o(ed)j(for)e(the)g +(constant)h(nodes.)37 b(When)448 3640 y(64-bit)24 b(pointers)g(are)e +(used,)h(the)f(maximum)g(number)h(of)f(v)n(ariables)i(is)e(the)g(lar)n +(gest)i(v)n(alue)f(that)448 3752 y(can)h(be)g(stored)h(in)e(an)h +(unsigned)i(inte)o(ger)e(minus)g(1.)589 3865 y(When)k(v)n(ariables)i +(are)e(reordered)i(to)e(reduce)h(the)f(size)g(of)f(the)h(decision)i +(diagrams,)g(the)448 3978 y(v)n(ariables)h(may)e(shift)h(in)f(the)g +(order)l(,)i(b)n(ut)f(the)o(y)f(retain)h(their)g(indices.)47 +b(The)28 b(package)j(k)o(eeps)448 4091 y(track)d(of)e(the)h(v)n +(ariable)h(permutation)h(\(and)e(its)g(in)l(v)o(erse\).)40 +b(The)26 b(application)j(is)e(not)g(af)n(fected)448 4204 +y(by)d(v)n(ariable)h(reordering,)h(e)o(xcept)f(in)e(the)h(follo)n(wing) +h(cases.)p Black 585 4392 a Fm(\017)p Black 46 w Fo(If)17 +b(the)i(application)i(uses)e(generators)i(\()p Fn(Cudd)p +2104 4392 28 4 v 34 w(F)-10 b(or)m(eac)o(hCube)20 b Fo(and)e +Fn(Cudd)p 2985 4392 V 34 w(F)-10 b(or)m(eac)o(hNode)p +Fo(\))676 4505 y(and)20 b(reordering)j(is)d(enabled,)j(then)e(it)f +(must)g(tak)o(e)h(care)f(not)h(to)f(call)h(an)o(y)f(operation)j(that) +676 4618 y(may)29 b(create)i(ne)n(w)e(nodes)j(\(and)e(hence)h(possibly) +h(trigger)g(reordering\).)51 b(This)29 b(is)h(be-)676 +4730 y(cause)j(the)g(cubes)h(\(i.e.,)g(paths\))g(and)f(nodes)h(of)e(a)g +(diagram)i(change)g(as)f(a)f(result)h(of)676 4843 y(reordering.)p +Black 1920 5225 a(6)p Black eop end +%%Page: 7 7 +TeXDict begin 7 6 bop Black Black Black 585 573 a Fm(\017)p +Black 46 w Fo(If)26 b(the)h(application)j(uses)d Fn(Cudd)p +1712 573 28 4 v 34 w(bddConstr)o(ain)j Fo(and)d(reordering)i(tak)o(es)f +(place,)h(then)676 686 y(the)23 b(property)j(of)e Fn(Cudd)p +1440 686 V 33 w(bddConstr)o(ain)j Fo(of)c(being)i(an)e(image)h +(restrictor)i(is)e(lost.)589 873 y(The)j(CUDD)f(package)j(relies)g(on)e +(garbage)i(collection)h(to)e(reclaim)g(the)g(memory)f(used)448 +986 y(by)35 b(diagrams)i(that)e(are)h(no)f(longer)h(in)f(use.)64 +b(The)34 b(scheme)i(emplo)o(yed)h(for)e(garbage)i(col-)448 +1099 y(lection)32 b(is)d(based)i(on)f(k)o(eeping)h(a)e(reference)j +(count)f(for)f(each)g(node.)48 b(The)29 b(references)k(that)448 +1212 y(are)26 b(counted)i(are)e(both)h(the)f(internal)h(references)i +(\(references)f(from)e(other)h(nodes\))g(and)f(e)o(x-)448 +1325 y(ternal)37 b(references)h(\(typically)g(references)g(from)d(the)g +(calling)i(en)l(vironment\).)68 b(When)35 b(an)448 1438 +y(application)25 b(creates)f(a)d(ne)n(w)g(BDD,)f(ADD,)f(or)j(ZDD,)d(it) +j(must)f(increase)j(its)e(reference)i(count)448 1551 +y(e)o(xplicitly)-6 b(,)40 b(through)d(a)e(call)g(to)g +Fn(Cudd)p 1707 1551 V 34 w(Ref)13 b Fo(.)62 b(Similarly)-6 +b(,)38 b(when)e(a)e(diagram)i(is)f(no)g(longer)448 1664 +y(needed,)28 b(the)e(application)i(must)e(call)g Fn(Cudd)p +1877 1664 V 34 w(Recur)o(siveDer)m(ef)41 b Fo(\(for)26 +b(BDDs)e(and)i(ADDs\))e(or)448 1777 y Fn(Cudd)p 649 1777 +V 34 w(Recur)o(siveDer)m(efZdd)29 b Fo(\(for)24 b(ZDDs\))e(to)h +(\223rec)o(ycle\224)j(the)e(nodes)h(of)e(the)h(diagram.)589 +1890 y(T)-6 b(erminal)37 b(nodes)h(carry)g(a)e(v)n(alue.)69 +b(This)36 b(is)h(especially)i(important)g(for)d(ADDs.)67 +b(By)448 2002 y(def)o(ault,)29 b(the)f(v)n(alue)f(is)g(a)f(double.)41 +b(T)-7 b(o)25 b(change)k(to)d(something)j(dif)n(ferent)g(\(e.g.,)e(an)g +(inte)o(ger\),)448 2115 y(the)21 b(package)i(must)d(be)h(modi\002ed)g +(and)g(recompiled.)30 b(Support)21 b(for)g(this)g(process)i(is)d +(currently)448 2228 y(v)o(ery)k(rudimentary)-6 b(.)448 +2474 y Fp(3.2.2)92 b(The)22 b(Manager)448 2648 y Fo(All)27 +b(nodes)i(used)g(in)f(BDDs,)f(ADDs,)g(and)h(ZDDs)e(are)i(k)o(ept)g(in)g +(special)h(hash)g(tables)g(called)448 2761 y(the)36 b +Fn(unique)i(tables)p Fo(.)66 b(Speci\002cally)-6 b(,)40 +b(BDDs)35 b(and)h(ADDs)e(share)j(the)f(same)f(unique)j(table,)448 +2874 y(whereas)24 b(ZDDs)d(ha)n(v)o(e)j(their)f(o)n(wn)f(table.)30 +b(As)22 b(the)h(name)f(implies,)i(the)f(main)g(purpose)h(of)f(the)448 +2987 y(unique)i(table)e(is)g(to)f(guarantee)k(that)d(each)g(node)h(is)e +(unique;)j(that)e(is,)g(there)g(is)g(no)g(other)g(node)448 +3100 y(labeled)h(by)e(the)h(same)f(v)n(ariable)i(and)e(with)g(the)g +(same)h(children.)30 b(This)22 b(uniqueness)j(property)448 +3213 y(mak)o(es)34 b(decision)i(diagrams)f(canonical.)61 +b(The)33 b(unique)i(tables)f(and)g(some)g(auxiliary)i(data)448 +3326 y(structures)e(mak)o(e)d(up)g(the)g(DdManager)h(\(manager)h(for)e +(short\).)52 b(Though)32 b(the)f(application)448 3439 +y(that)c(uses)h(only)f(the)g(e)o(xported)h(functions)h(needs)f(not)f +(be)f(concerned)j(with)e(most)f(details)i(of)448 3552 +y(the)20 b(manager)l(,)h(it)e(has)h(to)f(deal)h(with)f(the)h(manager)g +(in)g(the)f(follo)n(wing)i(sense.)28 b(The)19 b(application)448 +3665 y(must)28 b(initialize)h(the)f(manager)h(by)e(calling)i(an)e +(appropriate)k(function.)42 b(\(See)27 b(Section)h(3.3.\))448 +3778 y(Subsequently)-6 b(,)25 b(it)c(must)h(pass)g(a)f(pointer)j(to)d +(the)h(manager)h(to)e(all)h(the)f(functions)j(that)f(operate)448 +3890 y(on)h(decision)i(diagrams.)589 4003 y(W)l(ith)k(the)g(e)o +(xception)i(of)d(a)g(fe)n(w)g(statistical)j(counters,)h(there)d(are)g +(no)f(global)i(v)n(ariables)448 4116 y(in)f(the)g(CUDD)d(package.)50 +b(Therefore,)32 b(it)e(is)f(quite)i(possible)h(to)d(ha)n(v)o(e)i +(multiple)g(managers)448 4229 y(simultaneously)h(acti)n(v)o(e)d(in)f +(the)g(same)g(application.)2140 4196 y Fg(1)2223 4229 +y Fo(It)g(is)g(the)g(pointers)i(to)e(the)h(managers)448 +4342 y(that)24 b(tell)g(the)g(functions)i(on)e(what)f(data)h(the)o(y)g +(should)i(operate.)p Black 448 4423 1196 4 v 554 4479 +a Ff(1)583 4511 y Fe(The)18 b(global)h(statistical)e(counters)i(are)f +(used)h(locally;)g(hence)g(the)o(y)f(are)h(compatible)g(with)e(the)i +(use)f(of)g(multi-)448 4602 y(ple)h(managers.)p Black +Black 1920 5225 a Fo(7)p Black eop end +%%Page: 8 8 +TeXDict begin 8 7 bop Black Black 448 573 a Fp(3.2.3)92 +b(Cache)448 747 y Fo(Ef)n(\002cient)23 b(recursi)n(v)o(e)i +(manipulation)h(of)e(decision)h(diagrams)f(requires)i(the)d(use)h(of)f +(a)f(table)i(to)448 860 y(store)i(computed)g(results.)34 +b(This)24 b(table)i(is)e(called)i(here)g(the)e Fn(cac)o(he)i +Fo(because)g(it)f(is)f(ef)n(fecti)n(v)o(ely)448 973 y(handled)g(lik)o +(e)f(a)e(cache)i(of)f(v)n(ariable)i(b)n(ut)e(limited)h(capacity)-6 +b(.)30 b(The)22 b(CUDD)d(package)24 b(starts)f(by)448 +1086 y(def)o(ault)31 b(with)e(a)g(small)g(cache,)i(and)f(increases)h +(its)e(size)h(until)g(either)g(no)f(further)i(bene\002t)e(is)448 +1199 y(achie)n(v)o(ed,)c(or)f(a)f(limit)g(size)h(is)f(reached.)31 +b(The)23 b(user)h(can)g(in\003uence)h(this)f(polic)o(y)g(by)g(choosing) +448 1312 y(initial)h(and)f(limit)g(v)n(alues)g(for)g(the)g(cache)h +(size.)589 1425 y(T)-7 b(oo)22 b(small)g(a)f(cache)i(will)e(cause)i +(frequent)h(o)o(v)o(erwriting)f(of)f(useful)h(results.)30 +b(T)-7 b(oo)21 b(lar)n(ge)i(a)448 1537 y(cache)h(will)d(cause)j(o)o(v)o +(erhead,)g(because)g(the)e(whole)h(cache)g(is)f(scanned)i(e)n(v)o(ery)f +(time)f(garbage)448 1650 y(collection)27 b(tak)o(es)f(place.)32 +b(The)24 b(optimal)h(parameters)i(depend)f(on)e(the)h(speci\002c)g +(application.)448 1763 y(The)e(def)o(ault)j(parameters)f(w)o(ork)f +(reasonably)i(well)e(for)f(a)g(lar)n(ge)i(spectrum)g(of)f +(applications.)589 1876 y(The)32 b(cache)h(of)f(the)h(CUDD)d(package)k +(is)e(used)h(by)f(most)g(recursi)n(v)o(e)i(functions)h(of)d(the)448 +1989 y(package,)26 b(and)e(can)f(be)h(used)g(by)g(user)n(-supplied)k +(functions)e(as)d(well.)29 b(\(See)23 b(Section)h(4.4.\))448 +2236 y Fi(3.3)99 b(Initializing)24 b(and)i(Shutting)g(Do)o(wn)f(a)g +(DdManager)448 2411 y Fo(T)-7 b(o)27 b(use)g(the)h(functions)i(in)d +(the)h(CUDD)d(package,)30 b(one)e(has)g(\002rst)f(to)g(initialize)j +(the)d(package)448 2524 y(itself)e(by)e(calling)j Fn(Cudd)p +1238 2524 28 4 v 33 w(Init)r Fo(.)j(This)24 b(function)h(tak)o(es)g +(four)f(parameters:)p Black 585 2702 a Fm(\017)p Black +46 w Fo(numV)-10 b(ars:)28 b(It)21 b(is)h(the)f(initial)i(number)f(of)g +(v)n(ariables)h(for)f(BDDs)e(and)i(ADDs.)k(If)21 b(the)h(to-)676 +2815 y(tal)e(number)i(of)f(v)n(ariables)h(needed)h(by)d(the)h +(application)j(is)d(kno)n(wn,)g(then)g(it)g(is)f(slightly)676 +2928 y(more)h(ef)n(\002cient)h(to)f(create)i(a)e(manager)i(with)e(that) +h(number)g(of)f(v)n(ariables.)30 b(If)22 b(the)f(num-)676 +3041 y(ber)g(is)g(unkno)n(wn,)i(it)e(can)h(be)f(set)g(to)g(0,)h(or)f +(to)g(an)o(y)g(other)i(lo)n(wer)e(bound)h(on)g(the)f(number)676 +3154 y(of)28 b(v)n(ariables.)47 b(Requesting)31 b(more)e(v)n(ariables)i +(than)f(are)f(actually)i(needed)f(is)f(not)g(in-)676 +3267 y(correct,)24 b(b)n(ut)g(is)g(not)g(ef)n(\002cient.)p +Black 585 3450 a Fm(\017)p Black 46 w Fo(numV)-10 b(arsZ:)27 +b(It)h(is)f(the)h(initial)h(number)f(of)g(v)n(ariables)i(for)d(ZDDs.)40 +b(See)27 b(Sections)h(3.9)676 3563 y(and)c(3.11)f(for)h(a)f(discussion) +k(of)c(the)h(v)n(alue)g(of)g(this)g(ar)n(gument.)p Black +585 3747 a Fm(\017)p Black 46 w Fo(numSlots:)42 b(Determines)31 +b(the)f(initial)h(size)f(of)g(each)h(subtable)h(of)d(the)h(unique)i +(table.)676 3860 y(There)c(is)g(a)f(subtable)j(for)f(each)f(v)n +(ariable.)44 b(The)28 b(size)g(of)g(each)h(subtable)h(is)e(dynami-)676 +3973 y(cally)e(adjusted)i(to)e(re\003ect)g(the)g(number)h(of)f(nodes.) +37 b(It)25 b(is)h(normally)h(O.K.)d(to)i(use)g(the)676 +4086 y(def)o(ault)f(v)n(alue)f(for)g(this)g(parameter)l(,)h(which)f(is) +g(CUDD)p 2448 4086 V 31 w(UNIQ)o(UE)p 2828 4086 V 31 +w(SLO)l(TS.)p Black 585 4270 a Fm(\017)p Black 46 w Fo(cacheSize:)39 +b(It)28 b(is)g(the)g(initial)h(size)g(\(number)g(of)f(entries\))h(of)f +(the)h(cache.)43 b(Its)28 b(def)o(ault)676 4383 y(v)n(alue)c(is)f(CUDD) +p 1240 4383 V 32 w(CA)l(CHE)p 1578 4383 V 31 w(SLO)l(TS.)p +Black 585 4567 a Fm(\017)p Black 46 w Fo(maxMemory:)29 +b(It)23 b(is)g(the)h(tar)n(get)g(v)n(alue)g(for)f(the)h(maximum)f +(memory)g(occupation)j(\(in)676 4680 y(bytes\).)k(The)23 +b(package)i(uses)g(this)f(v)n(alue)g(to)f(decide)i(tw)o(o)f +(parameters.)p Black 785 4863 a Fp(\226)p Black 46 w +Fo(the)29 b(maximum)f(size)i(to)e(which)i(the)f(cache)h(will)e(gro)n(w) +-6 b(,)30 b(re)o(gardless)g(of)f(the)g(hit)876 4976 y(rate)24 +b(or)f(the)h(size)g(of)f(the)h(unique)h(table.)p Black +1920 5225 a(8)p Black eop end +%%Page: 9 9 +TeXDict begin 9 8 bop Black Black Black 785 573 a Fp(\226)p +Black 46 w Fo(the)19 b(maximum)g(size)h(to)f(which)h(gro)n(wth)f(of)g +(the)h(unique)h(table)f(will)f(be)g(preferred)876 686 +y(to)k(garbage)i(collection.)676 873 y(If)j(maxMemory)h(is)g(set)g(to)f +(0,)h(CUDD)e(tries)i(to)g(guess)g(a)f(good)i(v)n(alue)g(based)f(on)g +(the)676 986 y(a)n(v)n(ailable)c(memory)-6 b(.)448 1174 +y(A)23 b(typical)i(call)f(to)f Fn(Cudd)p 1255 1174 28 +4 v 34 w(Init)j Fo(may)d(look)h(lik)o(e)g(this:)p Black +Black 557 1362 a Fh(manager)52 b(=)i(Cudd_Init\(0,0,)o(CUD)o(D_)o(UN)o +(IQ)o(UE)o(_SL)o(OT)o(S,)o(CU)o(DD)o(_CA)o(CH)o(E_)o(SL)o(OT)o(S,0)o +(\);)448 1549 y Fo(T)-7 b(o)34 b(reclaim)i(all)f(the)g(memory)g +(associated)j(with)d(a)f(manager)l(,)39 b(an)c(application)j(must)d +(call)448 1662 y Fn(Cudd)p 649 1662 V 34 w(Quit)r Fo(.)28 +b(This)c(is)f(normally)i(done)f(before)h(e)o(xiting.)448 +1911 y Fi(3.4)99 b(Setting)26 b(P)o(arameters)448 2086 +y Fo(The)i(package)j(pro)o(vides)f(se)n(v)o(eral)g(functions)h(to)d +(set)h(the)g(parameters)h(that)f(control)i(v)n(arious)448 +2198 y(functions.)g(F)o(or)22 b(instance,)j(the)e(package)i(has)f(an)f +(automatic)h(w)o(ay)f(of)g(determining)i(whether)448 +2311 y(a)f(lar)n(ger)i(unique)f(table)g(w)o(ould)g(mak)o(e)f(the)g +(application)k(run)c(f)o(aster)-5 b(.)32 b(In)24 b(that)g(case,)h(the)f +(pack-)448 2424 y(age)19 b(enters)h(a)e(\223f)o(ast)i(gro)n(wth\224)f +(mode)g(in)g(which)g(resizing)i(of)d(the)h(unique)h(subtables)i(is)c(f) +o(a)n(v)n(ored)448 2537 y(o)o(v)o(er)25 b(garbage)h(collection.)36 +b(When)25 b(the)g(unique)h(table)g(reaches)g(a)f(gi)n(v)o(en)g(size,)h +(ho)n(we)n(v)o(er)l(,)f(the)448 2650 y(package)d(returns)e(to)g(the)f +(normal)h(\223slo)n(w)f(gro)n(wth\224)i(mode,)f(e)n(v)o(en)f(though)i +(the)e(conditions)k(that)448 2763 y(caused)k(the)f(transition)i(to)d(f) +o(ast)h(gro)n(wth)f(still)h(pre)n(v)n(ail.)35 b(The)25 +b(limit)g(size)h(for)f(f)o(ast)h(gro)n(wth)g(can)448 +2876 y(be)k(read)h(by)f Fn(Cudd)p 1070 2876 V 33 w(ReadLooseUpT)-8 +b(o)31 b Fo(and)g(changed)h(by)e Fn(Cudd)p 2544 2876 +V 33 w(SetLooseUpT)-8 b(o)p Fo(.)49 b(Similar)448 2989 +y(pairs)25 b(of)e(functions)j(e)o(xist)e(for)g(se)n(v)o(eral)h(other)f +(parameters.)31 b(See)23 b(also)h(Section)h(4.8.)448 +3238 y Fi(3.5)99 b(Constant)26 b(Functions)448 3412 y +Fo(The)18 b(CUDD)e(P)o(ackage)j(de\002nes)g(se)n(v)o(eral)h(constant)g +(functions.)30 b(These)18 b(functions)j(are)e(created)448 +3525 y(when)24 b(the)g(manager)g(is)g(initialized,)i(and)e(are)g +(accessible)i(through)f(the)f(manager)h(itself.)448 3771 +y Fp(3.5.1)92 b(One,)22 b(Logic)i(Zer)n(o,)g(and)e(Arithmetic)i(Zer)n +(o)448 3945 y Fo(The)36 b(constant)i(1)d(\(returned)j(by)e +Fn(Cudd)p 1738 3945 V 34 w(ReadOne)p Fo(\))g(is)g(common)g(to)g(BDDs,)h +(ADDs,)g(and)448 4058 y(ZDDs.)42 b(Ho)n(we)n(v)o(er)l(,)29 +b(its)f(meaning)i(is)e(dif)n(ferent)i(for)f(ADDs)d(and)j(BDDs,)f(on)g +(the)h(one)g(hand,)448 4171 y(and)c(ZDDs,)f(on)g(the)h(other)h(hand.)33 +b(The)25 b(diagram)g(consisting)j(of)d(the)g(constant)h(1)f(node)g +(only)448 4284 y(represents)33 b(the)d(constant)i(1)e(function)i(for)e +(ADDs)f(and)h(BDDs.)46 b(F)o(or)29 b(ZDDs,)h(its)g(meaning)448 +4397 y(depends)i(on)d(the)g(number)i(of)e(v)n(ariables:)42 +b(It)29 b(is)g(the)h(conjunction)j(of)c(the)g(complements)i(of)448 +4510 y(all)j(v)n(ariables.)63 b(Con)l(v)o(ersely)-6 b(,)38 +b(the)d(representation)j(of)c(the)g(constant)i(1)e(function)i(depends) +448 4623 y(on)28 b(the)f(number)h(of)f(v)n(ariables.)42 +b(The)26 b(constant)k(1)c(function)k(of)d Fk(n)f Fo(v)n(ariables)j(is)e +(returned)i(by)448 4736 y Fn(Cudd)p 649 4736 V 34 w(ReadZddOne)p +Fo(.)p Black 1920 5225 a(9)p Black eop end +%%Page: 10 10 +TeXDict begin 10 9 bop Black Black 589 573 a Fo(The)29 +b(constant)j(0)c(is)h(common)h(to)f(ADDs)f(and)h(ZDDs,)g(b)n(ut)h(not)f +(to)g(BDDs.)44 b(The)29 b(BDD)448 686 y(logic)21 b(0)f(is)g +Fp(not)g Fo(associated)i(with)e(the)h(constant)h(0)e(function:)29 +b(It)20 b(is)g(obtained)i(by)f(complemen-)448 799 y(tation)26 +b(\()p Fn(Cudd)p 910 799 28 4 v 34 w(Not)r Fo(\))e(of)h(the)g(constant) +i(1.)32 b(\(It)24 b(is)h(also)g(returned)i(by)e Fn(Cudd)p +2795 799 V 33 w(ReadLo)o(gicZer)l(o)p Fo(.\))448 912 +y(All)e(other)i(constants)h(are)e(speci\002c)g(to)f(ADDs.)448 +1157 y Fp(3.5.2)92 b(Pr)n(ede\002ned)22 b(Constants)448 +1332 y Fo(Besides)34 b(0)e(\(returned)j(by)d Fn(Cudd)p +1528 1332 V 34 w(ReadZer)l(o)p Fo(\))h(and)g(1,)h(the)f(follo)n(wing)h +(constant)h(functions)448 1445 y(are)24 b(created)h(at)f +(initialization)j(time.)p Black 562 1632 a(1.)p Black +46 w(PlusIn\002nity)f(and)g(MinusIn\002nity:)34 b(On)25 +b(computers)i(implementing)g(the)e(IEEE)e(stan-)676 1745 +y(dard)39 b(754)g(for)f(\003oating-point)k(arithmetic,)h(these)d(tw)o +(o)e(constants)j(are)d(set)h(to)f(the)676 1858 y(signed)19 +b(in\002nities.)29 b(On)17 b(the)h(DEC)e(Alphas,)k(the)e(option)i +Fh(-ieee_with_no_i)o(ne)o(xa)o(ct)676 1971 y Fo(or)33 +b Fh(-ieee_with_inexa)o(ct)26 b Fo(must)34 b(be)g(passed)h(to)f(the)g +(DEC)e(compiler)j(to)f(get)676 2084 y(support)26 b(of)e(the)h(IEEE)d +(standard.)34 b(\(The)24 b(compiler)i(still)f(produces)h(a)e(w)o +(arning,)i(b)n(ut)f(it)676 2197 y(can)30 b(be)h(ignored.\))52 +b(Compiling)32 b(with)e(those)i(options)g(may)e(cause)i(substantial)i +(per)n(-)676 2310 y(formance)39 b(de)o(gradation)j(on)c(the)g(Ev)n +(olution)j(IV)c(CPUs.)71 b(\(Especially)41 b(if)d(the)g(ap-)676 +2423 y(plication)d(does)f(use)f(the)g(in\002nities.\))58 +b(The)33 b(problem)h(is)e(reportedly)k(solv)o(ed)e(in)f(the)676 +2536 y(Ev)n(olution)h(V)d(CPUs.)55 b(If)32 b Fh(gcc)e +Fo(is)j(used)g(to)f(compile)i(CUDD)c(on)j(the)g(Alphas,)i(the)676 +2648 y(symbol)26 b Fh(HAVE)p 1193 2648 V 31 w(IEEE)p +1444 2648 V 31 w(754)d Fo(must)j(be)f(unde\002ned.)37 +b(\(See)25 b(the)h(Mak)o(e\002le)g(for)f(the)h(de-)676 +2761 y(tails.\))39 b(The)26 b(v)n(alues)i(of)e(these)i(constants)h(are) +e(returned)i(by)d Fn(Cudd)p 2802 2761 V 34 w(ReadPlusIn\002nity)676 +2874 y Fo(and)e Fn(Cudd)p 1031 2874 V 33 w(ReadMinusIn\002nity)p +Fo(.)p Black 562 3062 a(2.)p Black 46 w(Epsilon:)38 b(This)28 +b(constant,)j(initially)f(set)e(to)f Fl(10)2183 3029 +y Fd(\000)p Fc(12)2314 3062 y Fo(,)h(is)f(used)i(in)f(comparing)h +(\003oating)676 3175 y(point)e(v)n(alues)g(for)f(equality)-6 +b(.)39 b(Its)26 b(v)n(alue)h(is)f(returned)j(by)d Fn(Cudd)p +2688 3175 V 34 w(ReadEpsilon)p Fo(,)i(and)f(it)676 3288 +y(can)h(be)g(modi\002ed)h(by)g(calling)g Fn(Cudd)p 1887 +3288 V 34 w(SetEpsilon)p Fo(.)45 b(Unlik)o(e)29 b(the)g(other)g +(constants,)j(it)676 3401 y(does)24 b(not)g(correspond)i(to)e(a)f +(node.)448 3646 y Fp(3.5.3)92 b(Backgr)n(ound)448 3821 +y Fo(The)22 b(background)k(v)n(alue)e(is)e(a)g(constant)j(typically)g +(used)e(to)g(represent)h(non-e)o(xisting)i(arcs)d(in)448 +3934 y(graphs.)31 b(Consider)26 b(a)d(shortest)j(path)e(problem.)31 +b(T)-7 b(w)o(o)22 b(nodes)j(that)g(are)f(not)g(connected)i(by)e(an)448 +4047 y(arc)31 b(can)f(be)g(re)o(garded)i(as)e(being)h(joined)h(by)e(an) +g(arc)g(of)g(in\002nite)h(length.)50 b(In)30 b(shortest)j(path)448 +4159 y(problems,)27 b(it)d(is)g(therefore)j(con)l(v)o(enient)h(to)d +(set)g(the)g(background)j(v)n(alue)d(to)g(PlusIn\002nity.)33 +b(In)448 4272 y(netw)o(ork)26 b(\003o)n(w)e(problems,)i(on)f(the)g +(other)h(hand,)g(tw)o(o)e(nodes)i(not)g(connected)h(by)e(an)g(arc)g +(can)448 4385 y(be)j(re)o(garded)h(as)f(joined)h(by)f(an)g(arc)g(of)f +(0)h(capacity)-6 b(.)43 b(F)o(or)27 b(these)i(problems,)h(therefore,)h +(it)c(is)448 4498 y(more)i(con)l(v)o(enient)j(to)c(set)h(the)g +(background)j(v)n(alue)d(to)g(0.)43 b(In)29 b(general,)i(when)e +(representing)448 4611 y(sparse)c(matrices,)g(the)e(background)k(v)n +(alue)e(is)e(the)h(v)n(alue)g(that)g(is)g(assumed)h(implicitly)-6 +b(.)589 4724 y(At)18 b(initialization,)k(the)d(background)i(v)n(alue)e +(is)f(set)g(to)g(0.)27 b(It)18 b(can)g(be)g(read)h(with)f +Fn(Cudd)p 3237 4724 V 34 w(ReadBac)n(kgr)l(ound)r Fo(,)448 +4837 y(and)k(modi\002ed)f(with)f Fn(Cudd)p 1325 4837 +V 34 w(SetBac)n(kgr)l(ound)p Fo(.)31 b(The)21 b(background)j(v)n(alue)d +(af)n(fects)h(procedures)p Black 1897 5225 a(10)p Black +eop end +%%Page: 11 11 +TeXDict begin 11 10 bop Black Black 448 573 a Fo(that)34 +b(read)f(sparse)i(matrices/graphs)h(\()p Fn(Cudd)p 1903 +573 28 4 v 34 w(addRead)h Fo(and)c Fn(Cudd)p 2654 573 +V 34 w(addHarwell)p Fo(\),)k(proce-)448 686 y(dures)31 +b(that)f(print)g(out)f(sum-of-product)34 b(e)o(xpressions)e(for)d(ADDs) +f(\()p Fn(Cudd)p 2855 686 V 34 w(PrintMinterm)p Fo(\),)448 +799 y(generators)43 b(of)d(cubes)h(\()p Fn(Cudd)p 1458 +799 V 34 w(F)-10 b(or)m(eac)o(hCube)p Fo(\),)46 b(and)40 +b(procedures)j(that)e(count)g(minterms)448 912 y(\()p +Fn(Cudd)p 679 912 V 34 w(CountMinterm)p Fo(\).)448 1157 +y Fp(3.5.4)92 b(New)22 b(Constants)448 1332 y Fo(Ne)n(w)d(constant)j +(can)f(be)f(created)i(by)e(calling)i Fn(Cudd)p 2070 1332 +V 34 w(addConst)r Fo(.)29 b(This)20 b(function)i(will)e(retrie)n(v)o(e) +448 1445 y(the)31 b(ADD)e(for)i(the)g(desired)h(constant,)i(if)d(it)f +(already)i(e)o(xist,)h(or)e(it)f(will)g(create)i(a)e(ne)n(w)g(one.)448 +1558 y(Ob)o(viously)-6 b(,)25 b(ne)n(w)e(constants)j(should)f(only)g +(be)e(used)i(when)e(manipulating)k(ADDs.)448 1807 y Fi(3.6)99 +b(Cr)n(eating)26 b(V)-9 b(ariables)448 1981 y Fo(Decision)28 +b(diagrams)g(are)e(typically)j(created)f(by)e(combining)i(simpler)g +(decision)g(diagrams.)448 2094 y(The)22 b(simplest)h(decision)h +(diagrams,)g(of)e(course,)h(cannot)h(be)e(created)h(in)f(that)h(w)o(ay) +-6 b(.)28 b(Constant)448 2207 y(functions)e(ha)n(v)o(e)e(been)g +(discussed)h(in)e(Section)h(3.5.)29 b(In)23 b(this)g(section)i(we)d +(discuss)j(the)f(simple)448 2320 y(v)n(ariable)i(functions,)f(also)g +(kno)n(wn)e(as)h Fn(pr)l(ojection)i(functions)p Fo(.)448 +2566 y Fp(3.6.1)92 b(New)22 b(BDD)g(and)g(ADD)g(V)-8 +b(ariables)448 2740 y Fo(The)27 b(projection)j(functions)g(are)e +(distinct)h(for)f(BDDs)d(and)j(ADDs.)39 b(A)26 b(projection)k(function) +448 2853 y(for)24 b(BDDs)d(consists)k(of)e(an)h(internal)h(node)f(with) +f(both)h(outgoing)h(arcs)f(pointing)h(to)e(the)h(con-)448 +2966 y(stant)h(1.)j(The)23 b Fn(else)h Fo(arc)g(is)f(complemented.)589 +3079 y(An)e(ADD)e(projection)k(function,)h(on)d(the)g(other)h(hand,)g +(has)f(the)g Fn(else)h Fo(pointer)g(directed)h(to)448 +3192 y(the)35 b(arithmetic)h(zero)f(function.)64 b(One)34 +b(should)i(ne)n(v)o(er)f(mix)f(the)h(tw)o(o)f(types)h(of)f(v)n +(ariables.)448 3304 y(BDD)k(v)n(ariables)k(should)g(be)e(used)h(when)f +(manipulating)j(BDDs,)f(and)e(ADD)e(v)n(ariables)448 +3417 y(should)c(be)e(used)h(when)f(manipulating)j(ADDs.)53 +b(Three)33 b(functions)h(are)f(pro)o(vided)h(to)e(cre-)448 +3530 y(ate)24 b(BDD)e(v)n(ariables:)p Black 585 3718 +a Fm(\017)p Black 46 w Fn(Cudd)p 877 3718 V 33 w(bddIthV)-10 +b(ar)r Fo(:)40 b(Returns)29 b(the)f(projection)j(function)f(with)e +(inde)o(x)h Fk(i)p Fo(.)41 b(If)28 b(the)g(func-)676 +3831 y(tion)c(does)g(not)g(e)o(xist,)g(it)f(is)g(created.)p +Black 585 4018 a Fm(\017)p Black 46 w Fn(Cudd)p 877 4018 +V 33 w(bddNe)o(wV)-10 b(ar)r Fo(:)49 b(Returns)35 b(a)d(ne)n(w)h +(projection)j(function,)i(whose)c(inde)o(x)g(is)f(the)676 +4131 y(lar)n(gest)25 b(inde)o(x)f(in)g(use)g(at)f(the)h(time)f(of)h +(the)g(call,)f(plus)i(1.)p Black 585 4319 a Fm(\017)p +Black 46 w Fn(Cudd)p 877 4319 V 33 w(bddNe)o(wV)-10 b(arAtLe)o(vel)p +Fo(:)50 b(Similar)34 b(to)f Fn(Cudd)p 2283 4319 V 34 +w(bddNe)o(wV)-10 b(ar)r Fo(.)59 b(In)34 b(addition)i(it)d(al-)676 +4432 y(lo)n(ws)27 b(to)h(specify)i(the)e(position)i(in)e(the)g(v)n +(ariable)h(order)g(at)f(which)g(the)g(ne)n(w)g(v)n(ariable)676 +4545 y(should)i(be)f(inserted.)47 b(In)29 b(contrast,)j +Fn(Cudd)p 2060 4545 V 33 w(bddNe)o(wV)-10 b(ar)32 b Fo(adds)d(the)h(ne) +n(w)e(v)n(ariable)i(at)676 4658 y(the)23 b(end)h(of)g(the)g(order)-5 +b(.)448 4845 y(The)33 b(analogous)j(functions)g(for)d(ADDs)f(are)i +Fn(Cudd)p 2142 4845 V 33 w(addIthV)-10 b(ar)r Fo(,)38 +b Fn(Cudd)p 2795 4845 V 33 w(addNe)o(wV)-10 b(ar)r Fo(,)36 +b(and)448 4958 y Fn(Cudd)p 649 4958 V 34 w(addNe)o(wV)-10 +b(arAtLe)o(vel)p Fo(.)p Black 1897 5225 a(11)p Black +eop end +%%Page: 12 12 +TeXDict begin 12 11 bop Black Black 448 573 a Fp(3.6.2)92 +b(New)22 b(ZDD)g(V)-8 b(ariables)448 747 y Fo(Unlik)o(e)33 +b(the)f(projection)i(functions)g(of)e(BDDs)e(and)i(ADDs,)g(the)g +(projection)i(functions)g(of)448 860 y(ZDDs)20 b(ha)n(v)o(e)j(diagrams) +g(with)e Fk(n)13 b Fl(+)g(1)22 b Fo(nodes,)h(where)f +Fk(n)e Fo(is)i(the)f(number)i(of)f(v)n(ariables.)30 b(There-)448 +973 y(fore)g(the)f(ZDDs)e(of)h(the)h(projection)j(functions)f(change)g +(when)d(ne)n(w)h(v)n(ariables)h(are)f(added.)448 1086 +y(This)21 b(will)g(be)h(discussed)i(in)d(Section)h(3.9.)28 +b(Here)21 b(we)g(assume)h(that)g(the)g(number)g(of)f(v)n(ariables)448 +1199 y(is)j(\002x)o(ed.)k(The)23 b(ZDD)f(of)h(the)h Fk(i)p +Fo(-th)g(projection)i(function)g(is)d(returned)j(by)e +Fn(Cudd)p 2965 1199 28 4 v 33 w(zddIthV)-10 b(ar)r Fo(.)448 +1448 y Fi(3.7)99 b(Basic)25 b(BDD)h(Manipulation)448 +1622 y Fo(Common)34 b(manipulations)j(of)d(BDDs)e(can)i(be)g +(accomplished)j(by)d(calling)h Fn(Cudd)p 3153 1622 V +34 w(bddIte)p Fo(.)448 1735 y(This)19 b(function)i(tak)o(es)e(three)h +(BDDs,)d Fk(f)10 b Fo(,)18 b Fk(g)s Fo(,)h(and)g Fk(h)p +Fo(,)g(as)g(ar)n(guments)i(and)e(computes)h Fk(f)12 b +Fm(\001)r Fk(g)5 b Fl(+)r Fk(f)3311 1702 y Fd(0)3335 +1735 y Fm(\001)r Fk(h)p Fo(.)448 1848 y(Lik)o(e)29 b(all)g(the)g +(functions)j(that)d(create)h(ne)n(w)f(BDDs)e(or)i(ADDs,)f +Fn(Cudd)p 2698 1848 V 34 w(bddIte)i Fo(returns)h(a)d(re-)448 +1961 y(sult)j(that)g(must)f(be)g(e)o(xplicitly)i(referenced)h(by)d(the) +h(caller)-5 b(.)49 b Fn(Cudd)p 2609 1961 V 34 w(bddIte)32 +b Fo(can)e(be)g(used)h(to)448 2074 y(implement)i(all)e(tw)o(o-ar)n +(gument)k(boolean)e(functions.)55 b(Ho)n(we)n(v)o(er)l(,)33 +b(the)f(package)i(also)e(pro-)448 2187 y(vides)24 b Fn(Cudd)p +863 2187 V 33 w(bddAnd)i Fo(as)c(well)g(as)g(the)h(other)g(tw)o +(o-operand)i(boolean)f(functions,)h(which)d(are)448 2300 +y(slightly)32 b(more)f(ef)n(\002cient)f(when)h(a)e(tw)o(o-operand)k +(function)f(is)e(called)i(for)-5 b(.)48 b(The)30 b(follo)n(wing)448 +2413 y(fragment)24 b(of)f(code)h(illustrates)h(ho)n(w)d(to)h(b)n(uild)h +(the)f(BDD)e(for)h(the)h(function)i Fk(f)35 b Fl(=)25 +b Fk(x)3101 2380 y Fd(0)3101 2436 y Fc(0)3140 2413 y +Fk(x)3192 2380 y Fd(0)3192 2436 y Fc(1)3232 2413 y Fk(x)3284 +2380 y Fd(0)3284 2436 y Fc(2)3323 2413 y Fk(x)3375 2380 +y Fd(0)3375 2436 y Fc(3)3414 2413 y Fo(.)p Black Black +448 2600 a Fh(DdManager)51 b(*manager;)448 2713 y(DdNode)h(*f,)h(*var,) +g(*tmp;)448 2826 y(int)h(i;)448 3052 y(...)448 3278 y(f)g(=)h +(Cudd_ReadOne\(m)o(an)o(ag)o(er)o(\);)448 3391 y(Cudd_Ref\(f\);)448 +3504 y(for)f(\(i)f(=)h(3;)g(i)g(>=)g(0;)f(i--\))g({)667 +3616 y(var)g(=)h(Cudd_bddIthVar)o(\(m)o(ana)o(ge)o(r,)o(i\))o(;)667 +3729 y(tmp)f(=)h(Cudd_bddAnd\(ma)o(na)o(ger)o(,C)o(ud)o(d_)o(No)o(t\(v) +o(ar)o(\),)o(f\))o(;)667 3842 y(Cudd_Ref\(tmp\);)667 +3955 y(Cudd_Recursive)o(De)o(re)o(f\()o(ma)o(nag)o(er)o(,f)o(\);)667 +4068 y(f)g(=)g(tmp;)448 4181 y(})448 4369 y Fo(This)24 +b(e)o(xample)g(illustrates)i(the)e(follo)n(wing)h(points:)p +Black 585 4556 a Fm(\017)p Black 46 w Fo(Intermediate)40 +b(results)g(must)d(be)h(\223referenced\224)k(and)c(\223dereferenced.)-6 +b(\224)76 b(Ho)n(we)n(v)o(er)l(,)676 4669 y Fh(var)25 +b Fo(is)j(a)f(projection)k(function,)g(and)d(its)g(reference)i(count)f +(is)f(al)o(w)o(ays)g(greater)i(than)676 4782 y(0.)e(Therefore,)d(there) +f(is)g(no)f(call)h(to)g Fn(Cudd)p 2026 4782 V 33 w(Ref)13 +b Fo(.)p Black 1897 5225 a(12)p Black eop end +%%Page: 13 13 +TeXDict begin 13 12 bop Black Black Black 585 573 a Fm(\017)p +Black 46 w Fo(The)24 b(ne)n(w)g Fh(f)f Fo(must)i(be)f(assigned)j(to)e +(a)f(temporary)j(v)n(ariable)f(\()p Fh(tmp)d Fo(in)h(this)h(e)o +(xample\).)676 686 y(If)c(the)g(result)i(of)e Fn(Cudd)p +1408 686 28 4 v 34 w(bddAnd)k Fo(were)c(assigned)i(directly)h(to)d +Fh(f)p Fo(,)f(the)i(old)f Fh(f)f Fo(w)o(ould)i(be)676 +799 y(lost,)h(and)h(there)h(w)o(ould)f(be)f(no)h(w)o(ay)f(to)h(free)g +(its)f(nodes.)p Black 585 983 a Fm(\017)p Black 46 w +Fo(The)g(statement)i Fh(f)54 b(=)g(tmp)21 b Fo(has)j(the)g(same)g(ef)n +(fect)g(as:)p Black Black 894 1197 a Fh(f)54 b(=)g(tmp;)894 +1310 y(Cudd_Ref\(f\);)894 1423 y(Cudd_Recursive)o(De)o(ref)o(\(m)o(an)o +(ag)o(er)o(,tm)o(p\))o(;)676 1637 y Fo(b)n(ut)27 b(is)f(more)h(ef)n +(\002cient.)39 b(The)26 b(reference)j(is)d(\223passed\224)j(from)e +Fh(tmp)d Fo(to)j Fh(f)p Fo(,)f(and)h Fh(tmp)d Fo(is)676 +1750 y(no)n(w)f(ready)h(to)g(be)f(reutilized.)p Black +585 1934 a Fm(\017)p Black 46 w Fo(It)31 b(is)g(normally)h(more)g(ef)n +(\002cient)g(to)f(b)n(uild)h(BDDs)e(\223bottom-up.)-6 +b(\224)54 b(This)31 b(is)g(why)g(the)676 2047 y(loop)22 +b(goes)g(from)f(3)g(to)g(0.)28 b(Notice,)22 b(ho)n(we)n(v)o(er)l(,)g +(that)g(after)g(v)n(ariable)h(reordering,)h(higher)676 +2160 y(inde)o(x)30 b(does)h(not)f(necessarily)i(mean)e(\223closer)h(to) +f(the)g(bottom.)-6 b(\224)48 b(Of)29 b(course,)j(in)e(this)676 +2273 y(simple)24 b(e)o(xample,)g(ef)n(\002cienc)o(y)g(is)g(not)g(a)f +(concern.)p Black 585 2457 a Fm(\017)p Black 46 w Fo(Had)31 +b(we)g(w)o(anted)h(to)g(conjoin)i(the)e(v)n(ariables)h(in)f(a)f +(bottom-up)j(f)o(ashion)g(e)n(v)o(en)e(after)676 2569 +y(reordering,)26 b(we)c(should)j(ha)n(v)o(e)f(used)g +Fn(Cudd)p 2074 2569 V 34 w(ReadIn)l(vP)-7 b(erm)p Fo(.)30 +b(One)23 b(has)g(to)h(be)f(careful,)676 2682 y(though,)28 +b(to)e(\002x)f(the)i(order)g(of)f(conjunction)j(before)f(entering)g +(the)e(loop.)38 b(Otherwise,)676 2795 y(if)33 b(reordering)j(tak)o(es)e +(place,)i(it)d(is)h(possible)h(to)e(use)h(one)f(v)n(ariable)i(twice)f +(and)g(skip)676 2908 y(another)25 b(v)n(ariable.)448 +3156 y Fi(3.8)99 b(Basic)25 b(ADD)g(Manipulation)448 +3330 y Fo(The)f(most)f(common)h(w)o(ay)g(to)f(manipulate)j(ADDs)c(is)i +(via)g Fn(Cudd)p 2521 3330 V 34 w(addApply)p Fo(.)31 +b(This)23 b(function)448 3443 y(can)35 b(apply)g(a)e(wide)h(v)n(ariety) +h(of)f(operators)i(to)e(a)f(pair)h(of)g(ADDs.)58 b(Among)34 +b(the)g(a)n(v)n(ailable)448 3556 y(operators)27 b(are)d(addition,)i +(multiplication,)h(di)n(vision,)f(minimum,)d(maximum,)h(and)g(boolean) +448 3669 y(operators)i(that)e(w)o(ork)g(on)g(ADDs)e(whose)i(lea)n(v)o +(es)g(are)g(restricted)i(to)e(0)f(and)h(1)f(\(0-1)h(ADDs\).)589 +3782 y(The)g(follo)n(wing)h(fragment)g(of)f(code)h(illustrates)h(ho)n +(w)d(to)h(b)n(uild)h(the)f(ADD)e(for)i(the)g(func-)448 +3894 y(tion)g Fk(f)35 b Fl(=)25 b(5)p Fk(x)885 3908 y +Fc(0)925 3894 y Fk(x)977 3908 y Fc(1)1016 3894 y Fk(x)1068 +3908 y Fc(2)1108 3894 y Fk(x)1160 3908 y Fc(3)1199 3894 +y Fo(.)p Black Black 448 4073 a Fh(DdManager)51 b(*manager;)448 +4186 y(DdNode)h(*f,)h(*var,)g(*tmp;)448 4299 y(int)h(i;)448 +4525 y(...)448 4751 y(f)g(=)h(Cudd_addConst\()o(ma)o(na)o(ge)o(r,)o +(5\);)448 4863 y(Cudd_Ref\(f\);)448 4976 y(for)f(\(i)f(=)h(3;)g(i)g(>=) +g(0;)f(i--\))g({)p Black 1897 5225 a Fo(13)p Black eop +end +%%Page: 14 14 +TeXDict begin 14 13 bop Black Black 667 573 a Fh(var)53 +b(=)h(Cudd_addIthVar)o(\(m)o(ana)o(ge)o(r,)o(i\))o(;)667 +686 y(Cudd_Ref\(var\);)667 799 y(tmp)f(=)h(Cudd_addApply\()o(ma)o(nag)o +(er)o(,C)o(ud)o(d_)o(add)o(Ti)o(me)o(s,)o(va)o(r,f)o(\);)667 +912 y(Cudd_Ref\(tmp\);)667 1024 y(Cudd_Recursive)o(De)o(re)o(f\()o(ma)o +(nag)o(er)o(,f)o(\);)667 1137 y(Cudd_Recursive)o(De)o(re)o(f\()o(ma)o +(nag)o(er)o(,v)o(ar)o(\);)667 1250 y(f)g(=)g(tmp;)448 +1363 y(})448 1538 y Fo(This)25 b(e)o(xample,)i(contrasted)h(to)d(the)g +(e)o(xample)h(of)g(BDD)d(manipulation,)28 b(illustrates)g(the)e(fol-) +448 1651 y(lo)n(wing)e(points:)p Black 585 1826 a Fm(\017)p +Black 46 w Fo(The)d(ADD)f(projection)25 b(function)f(are)e(not)g +(maintained)i(by)e(the)g(manager)-5 b(.)30 b(It)21 b(is)h(there-)676 +1939 y(fore)i(necessary)i(to)d(reference)j(and)e(dereference)j(them.)p +Black 585 2122 a Fm(\017)p Black 46 w Fo(The)17 b(product)j(of)e(tw)o +(o)g(ADDs)e(is)i(computed)i(by)e(calling)i Fn(Cudd)p +2652 2122 28 4 v 34 w(addApply)g Fo(with)d Fn(Cudd)p +3426 2122 V 34 w(addT)-5 b(imes)676 2235 y Fo(as)19 b(parameter)-5 +b(.)29 b(There)20 b(is)f(no)h(\223apply\224)i(function)f(for)f(BDDs,)f +(because)i Fn(Cudd)p 3123 2235 V 34 w(bddAnd)676 2348 +y Fo(and)g Fn(Cudd)p 1028 2348 V 34 w(bddXor)i Fo(plus)f +(complementation)i(are)d(suf)n(\002cient)h(to)f(implement)h(all)e(tw)o +(o-)676 2461 y(ar)n(gument)25 b(boolean)h(functions.)448 +2707 y Fi(3.9)99 b(Basic)25 b(ZDD)h(Manipulation)448 +2882 y Fo(ZDDs)21 b(are)i(often)h(generated)h(by)e(con)l(v)o(erting)j +(e)o(xisting)e(BDDs.)j(\(See)c(Section)g(3.11.\))29 b(Ho)n(w-)448 +2995 y(e)n(v)o(er)l(,)20 b(it)e(is)g(also)h(possible)h(to)e(b)n(uild)i +(ZDDs)d(by)h(applying)j(boolean)f(operators)h(to)d(other)h(ZDDs,)448 +3108 y(starting)29 b(from)e(constants)i(and)e(projection)j(functions.) +41 b(The)26 b(follo)n(wing)j(fragment)f(of)e(code)448 +3220 y(illustrates)34 b(ho)n(w)d(to)h(b)n(uild)g(the)g(ZDD)d(for)j(the) +g(function)h Fk(f)49 b Fl(=)40 b Fk(x)2562 3187 y Fd(0)2562 +3244 y Fc(0)2627 3220 y Fl(+)26 b Fk(x)2776 3187 y Fd(0)2776 +3244 y Fc(1)2841 3220 y Fl(+)g Fk(x)2990 3187 y Fd(0)2990 +3244 y Fc(2)3056 3220 y Fl(+)f Fk(x)3204 3187 y Fd(0)3204 +3244 y Fc(3)3244 3220 y Fo(.)51 b(W)-7 b(e)448 3333 y(assume)25 +b(that)g(the)f(four)h(v)n(ariables)h(already)f(e)o(xist)g(in)f(the)g +(manager)h(when)g(the)f(ZDD)e(for)i Fk(f)32 b Fo(is)448 +3446 y(b)n(uilt.)e(Note)24 b(the)f(use)h(of)g(De)e(Mor)n(gan')-5 +b(s)26 b(la)o(w)-6 b(.)p Black Black 448 3621 a Fh(DdManager)51 +b(*manager;)448 3734 y(DdNode)h(*f,)h(*var,)g(*tmp;)448 +3847 y(int)h(i;)448 4073 y(manager)e(=)i(Cudd_Init\(0,4,)o(CU)o(DD_)o +(UN)o(IQ)o(UE)o(_S)o(LOT)o(S,)667 4186 y(CUDD_CACHE_SLO)o(TS)o(,0)o +(\);)448 4299 y(...)448 4525 y(tmp)g(=)g(Cudd_ReadZddOn)o(e\()o(ma)o +(na)o(ger)o(,0)o(\);)448 4638 y(Cudd_Ref\(tmp\);)448 +4751 y(for)g(\(i)f(=)h(3;)g(i)g(>=)g(0;)f(i--\))g({)667 +4863 y(var)g(=)h(Cudd_zddIthVar)o(\(m)o(ana)o(ge)o(r,)o(i\))o(;)667 +4976 y(Cudd_Ref\(var\);)p Black 1897 5225 a Fo(14)p Black +eop end +%%Page: 15 15 +TeXDict begin 15 14 bop Black Black 667 573 a Fh(f)54 +b(=)g(Cudd_zddInters)o(ec)o(t\()o(man)o(ag)o(er)o(,v)o(ar)o(,tm)o(p\))o +(;)667 686 y(Cudd_Ref\(f\);)667 799 y(Cudd_Recursive)o(De)o(re)o(fZ)o +(dd)o(\(ma)o(na)o(ge)o(r,)o(tm)o(p\);)667 912 y(Cudd_Recursive)o(De)o +(re)o(fZ)o(dd)o(\(ma)o(na)o(ge)o(r,)o(va)o(r\);)667 1024 +y(tmp)f(=)h(f;)448 1137 y(})448 1250 y(f)g(=)h(Cudd_zddDiff\(m)o(an)o +(ag)o(er)o(,C)o(udd)o(_R)o(ea)o(dZ)o(dd)o(One)o(\(m)o(an)o(ag)o(er)o +(,0\))o(,t)o(mp)o(\);)448 1363 y(Cudd_Ref\(f\);)448 1476 +y(Cudd_RecursiveD)o(ere)o(fZ)o(dd)o(\(m)o(an)o(age)o(r,)o(tm)o(p\))o(;) +448 1664 y Fo(This)24 b(e)o(xample)g(illustrates)i(the)e(follo)n(wing)h +(points:)p Black 585 1851 a Fm(\017)p Black 46 w Fo(The)e(projection)k +(functions)f(are)e(referenced,)j(because)f(the)o(y)e(are)g(not)g +(maintained)i(by)676 1964 y(the)d(manager)-5 b(.)p Black +585 2152 a Fm(\017)p Black 46 w Fo(Complementation)26 +b(is)d(obtained)j(by)e(subtracting)i(from)e(the)g(constant)h(1)f +(function.)p Black 585 2340 a Fm(\017)p Black 46 w Fo(The)f(result)h +(of)g Fn(Cudd)p 1364 2340 28 4 v 34 w(ReadZddOne)g Fo(does)g(not)g +(require)h(referencing.)448 2527 y(CUDD)31 b(pro)o(vides)j(functions)i +(for)d(the)g(manipulation)i(of)e(co)o(v)o(ers)g(represented)j(by)d +(ZDDs.)448 2640 y(F)o(or)40 b(instance,)47 b Fn(Cudd)p +1179 2640 V 33 w(zddIsop)c Fo(b)n(uilds)f(a)e(ZDD)f(representing)44 +b(an)c(irredundant)k(sum)c(of)448 2753 y(products)31 +b(for)e(the)g(incompletely)i(speci\002ed)f(function)h(de\002ned)e(by)f +(the)h(tw)o(o)f(BDDs)f Fk(L)h Fo(and)448 2866 y Fk(U)10 +b Fo(.)45 b Fn(Cudd)p 789 2866 V 33 w(zddW)-8 b(eakDiv)31 +b Fo(performs)f(the)f(weak)g(di)n(vision)i(of)e(tw)o(o)g(co)o(v)o(ers)h +(gi)n(v)o(en)f(as)g(ZDDs.)448 2979 y(These)c(functions)h(e)o(xpect)f +(the)f(tw)o(o)g(ZDD)e(v)n(ariables)k(corresponding)i(to)c(the)g(tw)o(o) +g(literals)h(of)448 3092 y(the)30 b(function)j(v)n(ariable)e(to)f(be)g +(adjacent.)50 b(One)29 b(has)h(to)g(create)h(v)n(ariable)h(groups)f +(\(see)g(Sec-)448 3205 y(tion)23 b(3.14\))g(for)g(reordering)i(of)d +(the)h(ZDD)e(v)n(ariables)j(to)e(w)o(ork.)29 b(BDD)20 +b(automatic)k(reordering)448 3318 y(is)31 b(safe)h(e)n(v)o(en)f +(without)h(groups:)45 b(If)31 b(realignment)i(of)e(ZDD)e(and)i(ADD/BDD) +d(v)n(ariables)33 b(is)448 3430 y(requested)26 b(\(see)e(Section)h +(3.15\))f(groups)h(will)e(be)h(k)o(ept)g(adjacent.)448 +3680 y Fi(3.10)99 b(Con)l(v)o(erting)26 b(ADDs)e(to)h(BDDs)g(and)h(V)l +(ice)f(V)-10 b(ersa)448 3854 y Fo(Se)n(v)o(eral)25 b(procedures)i(are)d +(pro)o(vided)i(to)e(con)l(v)o(ert)i(ADDs)d(to)h(BDDs,)f(according)j(to) +e(dif)n(ferent)448 3967 y(criteria.)29 b(\()p Fn(Cudd)p +986 3967 V 34 w(addBddP)-7 b(attern)p Fo(,)21 b Fn(Cudd)p +1805 3967 V 34 w(addBddInterval)p Fo(,)i(and)18 b Fn(Cudd)p +2795 3967 V 34 w(addBddThr)m(eshold)r Fo(.\))448 4080 +y(The)34 b(con)l(v)o(ersion)i(from)e(BDDs)e(to)h(ADDs)g(\()p +Fn(Cudd)p 2119 4080 V 34 w(BddT)-8 b(oAdd)r Fo(\))34 +b(is)f(based)i(on)f(the)g(simple)448 4193 y(principle)26 +b(of)e(mapping)h(the)f(logical)i(0)d(and)h(1)g(on)f(the)h(arithmetic)i +(0)d(and)i(1.)k(It)23 b(is)h(also)g(possi-)448 4306 y(ble)g(to)g(con)l +(v)o(ert)h(an)f(ADD)e(with)h(inte)o(ger)i(v)n(alues)g(\(more)f +(precisely)-6 b(,)26 b(\003oating)e(point)h(numbers)448 +4418 y(with)f(0)f(fractional)j(part\))e(to)g(an)f(array)i(of)e(BDDs)f +(by)i(repeatedly)i(calling)f Fn(Cudd)p 3012 4418 V 34 +w(addIthBit)r Fo(.)448 4668 y Fi(3.11)99 b(Con)l(v)o(erting)26 +b(BDDs)f(to)g(ZDDs)g(and)g(V)l(ice)g(V)-10 b(ersa)448 +4842 y Fo(Man)o(y)22 b(applications)k(\002rst)21 b(b)n(uild)j(a)d(set)h +(of)g(BDDs)f(and)h(then)h(deri)n(v)o(e)g(ZDDs)d(from)i(the)g(BDDs.)448 +4955 y(These)i(applications)j(should)e(create)f(the)g(manager)g(with)f +(0)g(ZDD)e(v)n(ariables)26 b(and)e(create)g(the)p Black +1897 5225 a(15)p Black eop end +%%Page: 16 16 +TeXDict begin 16 15 bop Black Black 448 573 a Fo(BDDs.)40 +b(Then)27 b(the)o(y)h(should)h(call)f Fn(Cudd)p 1762 +573 28 4 v 34 w(zddV)-10 b(ar)o(sF)-5 b(r)l(omBddV)-10 +b(ar)o(s)30 b Fo(to)d(create)i(the)f(necessary)448 686 +y(ZDD)j(v)n(ariables\227whose)36 b(number)e(is)e(lik)o(ely)i(to)f(be)g +(kno)n(wn)g(once)g(the)g(BDDs)e(are)i(a)n(v)n(ail-)448 +799 y(able.)g(This)24 b(approach)j(eliminates)f(the)f(dif)n +(\002culties)i(that)e(arise)g(when)g(the)f(number)i(of)e(ZDD)448 +912 y(v)n(ariables)i(changes)f(while)f(ZDDs)e(are)i(being)h(b)n(uilt.) +589 1024 y(The)h(simplest)h(con)l(v)o(ersion)h(from)e(BDDs)e(to)h(ZDDs) +f(is)i(a)f(simple)h(change)h(of)f(represen-)448 1137 +y(tation,)39 b(which)c(preserv)o(es)i(the)f(functions.)65 +b(Simply)35 b(put,)j(gi)n(v)o(en)d(a)g(BDD)e(for)i Fk(f)10 +b Fo(,)36 b(a)e(ZDD)448 1250 y(for)g Fk(f)42 b Fo(is)34 +b(requested.)61 b(In)34 b(this)g(case)h(the)e(correspondence)39 +b(between)c(the)e(BDD)f(v)n(ariables)448 1363 y(and)g(ZDD)e(v)n +(ariables)j(is)e(one-to-one.)55 b(Hence,)34 b Fn(Cudd)p +2232 1363 V 34 w(zddV)-10 b(ar)o(sF)-5 b(r)l(omBddV)-10 +b(ar)o(s)33 b Fo(should)g(be)448 1476 y(called)c(with)e(the)g +Fn(multiplicity)j Fo(parameter)f(equal)f(to)g(1.)39 b(The)27 +b(con)l(v)o(ersion)j(proper)f(can)f(then)448 1589 y(be)37 +b(performed)h(by)f(calling)h Fn(Cudd)p 1595 1589 V 33 +w(zddP)-7 b(ortF)i(r)l(omBdd)r Fo(.)69 b(The)36 b(in)l(v)o(erse)j +(transformation)g(is)448 1702 y(performed)26 b(by)d Fn(Cudd)p +1164 1702 V 34 w(zddP)-7 b(ortT)f(oBdd)r Fo(.)589 1815 +y(ZDDs)28 b(are)i(quite)h(often)f(used)h(for)e(the)h(representation)k +(of)c Fn(co)o(ver)o(s)p Fo(.)48 b(This)29 b(is)h(normally)448 +1928 y(done)36 b(by)g(associating)i(tw)o(o)d(ZDD)e(v)n(ariables)38 +b(to)d(each)h(v)n(ariable)h(of)e(the)g(function.)66 b(\(And)448 +2041 y(hence,)28 b(typically)-6 b(,)28 b(to)e(each)g(BDD)e(v)n +(ariable.\))38 b(One)25 b(ZDD)f(v)n(ariable)j(is)f(associated)i(with)e +(the)448 2154 y(positi)n(v)o(e)35 b(literal)f(of)f(the)g(BDD)e(v)n +(ariable,)37 b(while)d(the)f(other)h(ZDD)d(v)n(ariable)k(is)d +(associated)448 2267 y(with)i(the)f(ne)o(gati)n(v)o(e)h(literal.)60 +b(A)32 b(call)i(to)f Fn(Cudd)p 1980 2267 V 34 w(zddV)-10 +b(ar)o(sF)-5 b(r)l(omBddV)-10 b(ar)o(s)36 b Fo(with)d +Fn(multiplicity)448 2379 y Fo(equal)25 b(to)e(2)h(will)f(associate)j +(to)d(BDD)f(v)n(ariable)j Fk(i)e Fo(the)h(tw)o(o)f(ZDD)f(v)n(ariables)j +Fl(2)p Fk(i)f Fo(and)g Fl(2)p Fk(i)d Fl(+)f(1)p Fo(.)589 +2492 y(If)j(a)f(BDD)f(v)n(ariable)j(group)g(tree)f(e)o(xists)h(when)f +Fn(Cudd)p 2300 2492 V 34 w(zddV)-10 b(ar)o(sF)-5 b(r)l(omBddV)-10 +b(ar)o(s)25 b Fo(is)d(called)448 2605 y(\(see)29 b(Section)f(3.13\))g +(the)g(function)i(generates)g(a)e(ZDD)d(v)n(ariable)30 +b(group)f(tree)f(consistent)i(to)448 2718 y(it.)57 b(In)33 +b(an)o(y)h(case,)h(all)f(the)f(ZDD)e(v)n(ariables)k(deri)n(v)o(ed)g +(from)e(the)g(same)g(BDD)e(v)n(ariable)k(are)448 2831 +y(clustered)26 b(into)e(a)f(group.)589 2944 y(If)i(the)f(ZDD)e(for)j +Fk(f)33 b Fo(is)24 b(created)i(and)f(later)g(a)f(ne)n(w)f(ZDD)g(v)n +(ariable)j(is)e(added)h(to)g(the)f(man-)448 3057 y(ager)l(,)f(the)e +(function)i(represented)i(by)c(the)h(e)o(xisting)g(ZDD)e(changes.)29 +b(Suppose,)23 b(for)e(instance,)448 3170 y(that)26 b(tw)o(o)f(v)n +(ariables)i(are)e(initially)i(created,)g(and)e(that)h(the)f(ZDD)e(for)i +Fk(f)38 b Fl(=)27 b Fk(x)2896 3184 y Fc(0)2957 3170 y +Fl(+)21 b Fk(x)3101 3184 y Fc(1)3165 3170 y Fo(is)j(b)n(uilt.)448 +3283 y(If)33 b(a)g(third)h(v)n(ariable)h(is)e(added,)k(say)c +Fk(x)1714 3297 y Fc(2)1753 3283 y Fo(,)i(then)f(the)f(ZDD)e(represents) +36 b Fk(g)47 b Fl(=)c(\()p Fk(x)3054 3297 y Fc(0)3121 +3283 y Fl(+)27 b Fk(x)3271 3297 y Fc(1)3310 3283 y Fl(\))p +Fk(x)3397 3250 y Fd(0)3397 3306 y Fc(2)448 3396 y Fo(instead.)36 +b(This)25 b(change)i(in)e(function)j(ob)o(viously)g(applies)f(re)o +(gardless)g(of)e(what)g(use)h(is)f(made)448 3509 y(of)j(the)g(ZDD.)39 +b(Ho)n(we)n(v)o(er)l(,)29 b(if)e(the)h(ZDD)e(is)h(used)i(to)e +(represent)k(a)c(co)o(v)o(er,)i(the)f(co)o(v)o(er)g(itself)g(is)448 +3621 y(not)i(changed)h(by)e(the)g(addition)j(of)c(ne)n(w)h(v)n +(ariable.)47 b(\(What)29 b(changes)i(is)e(the)g(characteristic)448 +3734 y(function)d(of)d(the)h(co)o(v)o(er)-5 b(.\))448 +3984 y Fi(3.12)99 b(V)-9 b(ariable)25 b(Reordering)h(f)n(or)e(BDDs)h +(and)h(ADDs)448 4158 y Fo(The)20 b(CUDD)d(package)22 +b(pro)o(vides)g(a)d(rich)h(set)g(of)g(dynamic)h(reordering)i +(algorithms.)29 b(Some)19 b(of)448 4271 y(them)24 b(are)g(slight)g(v)n +(ariations)i(of)e(e)o(xisting)h(techniques)i([16)q(,)22 +b(6)q(,)g(2)q(,)g(10)q(,)h(15)q(,)f(11)q(];)h(some)h(others)448 +4384 y(ha)n(v)o(e)h(been)f(de)n(v)o(eloped)i(speci\002cally)f(for)f +(this)g(package)i([14)q(,)c(13)q(].)589 4497 y(Reordering)33 +b(af)n(fects)e(a)f(unique)i(table.)50 b(This)30 b(means)h(that)g(BDDs)e +(and)i(ADDs,)f(which)448 4609 y(share)36 b(the)g(same)f(unique)i(table) +f(are)f(simultaneously)k(reordered.)66 b(ZDDs,)36 b(on)f(the)g(other) +448 4722 y(hand,)22 b(are)f(reordered)i(separately)-6 +b(.)31 b(In)20 b(the)h(follo)n(wing)h(we)e(discuss)i(the)f(reordering)i +(of)e(BDDs)448 4835 y(and)j(ADDs.)j(Reordering)f(for)e(ZDDs)e(is)h(the) +h(subject)h(of)f(Section)g(3.14.)p Black 1897 5225 a(16)p +Black eop end +%%Page: 17 17 +TeXDict begin 17 16 bop Black Black 589 573 a Fo(Reordering)28 +b(of)d(the)g(v)n(ariables)i(can)f(be)f(in)l(v)n(ok)o(ed)j(directly)f +(by)e(the)g(application)j(by)e(call-)448 686 y(ing)g +Fn(Cudd)p 790 686 28 4 v 34 w(ReduceHeap)p Fo(.)35 b(Or)24 +b(it)h(can)h(be)f(automatically)k(triggered)e(by)e(the)h(package)h +(when)448 799 y(the)k(number)g(of)g(nodes)g(has)g(reached)h(a)e(gi)n(v) +o(en)h(threshold.)52 b(\(The)30 b(threshold)j(is)d(initialized)448 +912 y(and)h(automatically)j(adjusted)f(after)e(each)h(reordering)h(by)e +(the)g(package.\))52 b(T)-7 b(o)30 b(enable)i(au-)448 +1024 y(tomatic)c(dynamic)h(reordering)h(\(also)e(called)g +Fn(async)o(hr)l(onous)j Fo(dynamic)e(reordering)h(in)d(this)448 +1137 y(document\))37 b(the)f(application)i(must)d(call)h +Fn(Cudd)p 2033 1137 V 34 w(A)n(utodynEnable)p Fo(.)66 +b(Automatic)36 b(dynamic)448 1250 y(reordering)27 b(can)d(subsequently) +j(be)d(disabled)h(by)f(calling)h Fn(Cudd)p 2515 1250 +V 34 w(A)n(utodynDisable)p Fo(.)589 1363 y(All)18 b(reordering)j +(methods)e(are)f(a)n(v)n(ailable)j(in)d(both)h(the)f(case)h(of)f +(direct)h(call)g(to)f Fn(Cudd)p 3238 1363 V 33 w(ReduceHeap)448 +1476 y Fo(and)23 b(the)g(case)g(of)g(automatic)h(in)l(v)n(ocation.)32 +b(F)o(or)21 b(man)o(y)i(methods,)h(the)e(reordering)k(procedure)448 +1589 y(is)34 b(iterated)h(until)f(no)f(further)i(impro)o(v)o(ement)g +(is)e(obtained.)61 b(W)-7 b(e)32 b(call)i(these)g(methods)h(the)448 +1702 y Fn(con)l(ver)m(ging)40 b Fo(methods.)68 b(When)37 +b(constraints)i(are)e(imposed)g(on)g(the)f(relati)n(v)o(e)i(position)g +(of)448 1815 y(v)n(ariables)31 b(\(see)d(Section)h(3.13\))g(the)f +(reordering)j(methods)f(apply)f(inside)g(the)g(groups.)44 +b(The)448 1928 y(groups)33 b(themselv)o(es)g(are)e(reordered)i(by)e +(sifting.)53 b(Each)31 b(method)h(is)e(identi\002ed)j(by)e(a)g(con-)448 +2041 y(stant)24 b(of)f(the)h(enumerated)h(type)f Fn(Cudd)p +1700 2041 V 34 w(Reor)m(deringT)-7 b(ype)26 b Fo(de\002ned)e(in)f +Fn(cudd.h)h Fo(\(the)g(e)o(xternal)448 2154 y(header)h(\002le)e(of)h +(the)f(CUDD)f(package\):)p Black 448 2366 a Fp(CUDD)p +717 2366 V 32 w(REORDER)p 1206 2366 V 30 w(NONE:)p Black +44 w Fo(This)i(method)g(causes)h(no)f(reordering.)p Black +448 2554 a Fp(CUDD)p 717 2554 V 32 w(REORDER)p 1206 2554 +V 30 w(SAME:)p Black 44 w Fo(If)18 b(passed)i(to)e Fn(Cudd)p +2196 2554 V 33 w(A)n(utodynEnable)p Fo(,)k(this)d(method)g(lea)n(v)o +(es)676 2667 y(the)f(current)i(method)f(for)f(automatic)i(reordering)h +(unchanged.)30 b(If)17 b(passed)j(to)e Fn(Cudd)p 3333 +2667 V 34 w(ReduceHeap)p Fo(,)676 2780 y(this)24 b(method)g(causes)h +(the)f(current)h(method)g(for)e(automatic)j(reordering)g(to)d(be)h +(used.)p Black 448 2967 a Fp(CUDD)p 717 2967 V 32 w(REORDER)p +1206 2967 V 30 w(RANDOM:)p Black 44 w Fo(P)o(airs)17 +b(of)h(v)n(ariables)j(are)d(randomly)i(chosen,)g(and)f(sw)o(apped)676 +3080 y(in)29 b(the)h(order)-5 b(.)48 b(The)29 b(sw)o(ap)h(is)f +(performed)i(by)f(a)f(series)i(of)f(sw)o(aps)g(of)f(adjacent)j(v)n +(ari-)676 3193 y(ables.)c(The)18 b(best)h(order)g(among)g(those)h +(obtained)g(by)f(the)g(series)g(of)f(sw)o(aps)h(is)g(retained.)676 +3306 y(The)24 b(number)i(of)f(pairs)h(chosen)h(for)e(sw)o(apping)i +(equals)f(the)f(number)h(of)f(v)n(ariables)i(in)676 3419 +y(the)c(diagram.)p Black 448 3606 a Fp(CUDD)p 717 3606 +V 32 w(REORDER)p 1206 3606 V 30 w(RANDOM)p 1657 3606 +V 31 w(PIV)l(O)l(T:)p Black 45 w Fo(Same)17 b(as)h(CUDD)p +2615 3606 V 31 w(REORDER)p 3073 3606 V 30 w(RANDOM,)676 +3719 y(b)n(ut)30 b(the)g(tw)o(o)f(v)n(ariables)j(are)d(chosen)j(so)d +(that)h(the)g(\002rst)g(is)f(abo)o(v)o(e)h(the)g(v)n(ariable)h(with)676 +3832 y(the)d(lar)n(gest)h(number)g(of)e(nodes,)j(and)e(the)g(second)i +(is)d(belo)n(w)h(that)g(v)n(ariable.)43 b(In)28 b(case)676 +3945 y(there)h(are)g(se)n(v)o(eral)h(v)n(ariables)h(tied)e(for)g(the)g +(maximum)g(number)g(of)g(nodes,)i(the)e(one)676 4058 +y(closest)c(to)e(the)h(root)g(is)g(used.)p Black 448 +4246 a Fp(CUDD)p 717 4246 V 32 w(REORDER)p 1206 4246 +V 30 w(SIFT:)p Black 45 w Fo(This)g(method)h(is)g(an)f(implementation)k +(of)c(Rudell')-5 b(s)26 b(sifting)676 4359 y(algorithm)i([16)q(].)39 +b(A)26 b(simpli\002ed)i(description)i(of)d(sifting)h(is)f(as)g(follo)n +(ws:)37 b(Each)27 b(v)n(ari-)676 4472 y(able)32 b(is)g(considered)j(in) +d(turn.)55 b(A)30 b(v)n(ariable)k(is)e(mo)o(v)o(ed)g(up)g(and)g(do)n +(wn)g(in)g(the)g(order)676 4584 y(so)26 b(that)h(it)e(tak)o(es)j(all)e +(possible)i(positions.)40 b(The)25 b(best)i(position)i(is)d +(identi\002ed)h(and)g(the)676 4697 y(v)n(ariable)e(is)e(returned)j(to)d +(that)h(position.)676 4848 y(In)30 b(reality)-6 b(,)34 +b(things)e(are)f(a)g(bit)g(more)f(complicated.)53 b(F)o(or)30 +b(instance,)35 b(there)c(is)g(a)f(limit)676 4961 y(on)g(the)g(number)h +(of)f(v)n(ariables)i(that)f(will)f(be)g(sifted.)49 b(This)30 +b(limit)g(can)h(be)f(read)g(with)p Black 1897 5225 a(17)p +Black eop end +%%Page: 18 18 +TeXDict begin 18 17 bop Black Black 676 573 a Fn(Cudd)p +877 573 28 4 v 33 w(ReadSiftMaxV)-10 b(ar)29 b Fo(and)d(set)f(with)g +Fn(Cudd)p 2195 573 V 34 w(SetSiftMaxV)-10 b(ar)r Fo(.)35 +b(In)25 b(addition,)i(if)e(the)676 686 y(diagram)31 b(gro)n(ws)g(too)g +(much)g(while)g(mo)o(ving)h(a)e(v)n(ariable)j(up)d(or)h(do)n(wn,)h +(that)g(mo)o(v)o(e-)676 799 y(ment)37 b(is)f(terminated)j(before)g(the) +e(v)n(ariable)i(has)e(reached)i(one)e(end)g(of)g(the)h(order)-5 +b(.)676 912 y(The)27 b(maximum)g(ratio)i(by)f(which)g(the)g(diagram)h +(is)e(allo)n(wed)i(to)e(gro)n(w)h(while)f(a)h(v)n(ari-)676 +1024 y(able)35 b(is)f(being)h(sifted)h(can)f(be)f(read)h(with)g +Fn(Cudd)p 2292 1024 V 33 w(ReadMaxGr)l(owth)h Fo(and)f(set)f(with)676 +1137 y Fn(Cudd)p 877 1137 V 33 w(SetMaxGr)l(owth)p Fo(.)p +Black 448 1318 a Fp(CUDD)p 717 1318 V 32 w(REORDER)p +1206 1318 V 30 w(SIFT)p 1439 1318 V 32 w(CONVERGE:)p +Black 43 w Fo(This)18 b(is)f(the)i(con)l(v)o(er)n(ging)i(v)n(ariant)f +(of)e(CUDD-)p 676 1431 V 703 1431 a(REORDER)p 1135 1431 +V 30 w(SIFT)-7 b(.)p Black 448 1612 a Fp(CUDD)p 717 1612 +V 32 w(REORDER)p 1206 1612 V 30 w(SYMM)p 1525 1612 V +31 w(SIFT:)p Black 45 w Fo(This)34 b(method)h(is)f(an)g(implementation) +i(of)e(sym-)676 1725 y(metric)27 b(sifting)i([14)q(].)39 +b(It)26 b(is)h(similar)h(to)f(sifting,)i(with)e(one)h(addition:)38 +b(V)-10 b(ariables)29 b(that)676 1837 y(become)23 b(adjacent)i(during)f +(sifting)g(are)f(tested)h(for)f(symmetry.)29 b(If)22 +b(the)o(y)h(are)g(symmet-)676 1950 y(ric,)34 b(the)o(y)f(are)f(link)o +(ed)i(in)f(a)f(group.)56 b(Sifting)33 b(then)g(continues)i(with)e(a)e +(group)j(being)676 2063 y(mo)o(v)o(ed,)d(instead)h(of)f(a)e(single)j(v) +n(ariable.)51 b(After)30 b(symmetric)i(sifting)f(has)g(been)g(run,)676 +2176 y Fn(Cudd)p 877 2176 V 33 w(SymmPr)l(o\002le)h Fo(can)g(be)g +(called)g(to)g(report)h(on)e(the)h(symmetry)g(groups)h(found.)676 +2289 y(\(Both)23 b(positi)n(v)o(e)i(and)f(ne)o(gati)n(v)o(e)h +(symmetries)g(are)e(reported.\))p Black 448 2470 a Fp(CUDD)p +717 2470 V 32 w(REORDER)p 1206 2470 V 30 w(SYMM)p 1525 +2470 V 31 w(SIFT)p 1759 2470 V 32 w(CONV:)p Black 45 +w Fo(This)17 b(is)h(the)h(con)l(v)o(er)n(ging)i(v)n(ariant)f(of)e +(CUDD-)p 676 2583 V 703 2583 a(REORDER)p 1135 2583 V +30 w(SYMM)p 1444 2583 V 31 w(SIFT)-7 b(.)p Black 448 +2763 a Fp(CUDD)p 717 2763 V 32 w(REORDER)p 1206 2763 +V 30 w(GR)m(OUP)p 1563 2763 V 31 w(SIFT:)p Black 45 w +Fo(This)22 b(method)i(is)e(an)h(implementation)i(of)e(group)676 +2876 y(sifting)c([13)r(].)26 b(It)18 b(is)g(similar)h(to)f(symmetric)i +(sifting,)g(b)n(ut)f(aggre)o(gation)i(is)d(not)h(restricted)676 +2989 y(to)k(symmetric)i(v)n(ariables.)p Black 448 3170 +a Fp(CUDD)p 717 3170 V 32 w(REORDER)p 1206 3170 V 30 +w(GR)m(OUP)p 1563 3170 V 31 w(SIFT)p 1797 3170 V 32 w(CONV:)p +Black 44 w Fo(This)36 b(method)h(repeats)g(until)g(con)l(v)o(er)n(-)676 +3283 y(gence)h(the)f(combination)j(of)d(CUDD)p 1938 3283 +V 31 w(REORDER)p 2396 3283 V 30 w(GR)l(OUP)p 2732 3283 +V 32 w(SIFT)e(and)i(CUDD-)p 676 3396 V 703 3396 a(REORDER)p +1135 3396 V 30 w(WINDO)m(W4.)p Black 448 3576 a Fp(CUDD)p +717 3576 V 32 w(REORDER)p 1206 3576 V 30 w(WINDO)-5 b(W2:)p +Black 46 w Fo(This)30 b(method)h(implements)h(the)e(windo)n(w)h(permu-) +676 3689 y(tation)j(approach)i(of)d(Fujita)h([8)q(])f(and)g(Ishiura)j +([10)q(].)57 b(The)33 b(size)h(of)g(the)f(windo)n(w)g(is)676 +3802 y(2.)p Black 448 3983 a Fp(CUDD)p 717 3983 V 32 +w(REORDER)p 1206 3983 V 30 w(WINDO)-5 b(W3:)p Black 46 +w Fo(Similar)18 b(to)g(CUDD)p 2404 3983 V 31 w(REORDER)p +2862 3983 V 30 w(WINDO)m(W2,)f(b)n(ut)676 4096 y(with)23 +b(a)g(windo)n(w)g(of)h(size)g(3.)p Black 448 4276 a Fp(CUDD)p +717 4276 V 32 w(REORDER)p 1206 4276 V 30 w(WINDO)-5 b(W4:)p +Black 46 w Fo(Similar)18 b(to)g(CUDD)p 2404 4276 V 31 +w(REORDER)p 2862 4276 V 30 w(WINDO)m(W2,)f(b)n(ut)676 +4389 y(with)23 b(a)g(windo)n(w)g(of)h(size)g(4.)p Black +448 4570 a Fp(CUDD)p 717 4570 V 32 w(REORDER)p 1206 4570 +V 30 w(WINDO)-5 b(W2)p 1696 4570 V 33 w(CONV:)p Black +44 w Fo(This)18 b(is)g(the)g(con)l(v)o(er)n(ging)k(v)n(ariant)d(of)f +(CUDD-)p 676 4683 V 703 4683 a(REORDER)p 1135 4683 V +30 w(WINDO)m(W2.)p Black 448 4863 a Fp(CUDD)p 717 4863 +V 32 w(REORDER)p 1206 4863 V 30 w(WINDO)-5 b(W3)p 1696 +4863 V 33 w(CONV:)p Black 44 w Fo(This)18 b(is)g(the)g(con)l(v)o(er)n +(ging)k(v)n(ariant)d(of)f(CUDD-)p 676 4976 V 703 4976 +a(REORDER)p 1135 4976 V 30 w(WINDO)m(W3.)p Black 1897 +5225 a(18)p Black eop end +%%Page: 19 19 +TeXDict begin 19 18 bop Black Black Black 448 573 a Fp(CUDD)p +717 573 28 4 v 32 w(REORDER)p 1206 573 V 30 w(WINDO)-5 +b(W4)p 1696 573 V 33 w(CONV:)p Black 44 w Fo(This)18 +b(is)g(the)g(con)l(v)o(er)n(ging)k(v)n(ariant)d(of)f(CUDD-)p +676 686 V 703 686 a(REORDER)p 1135 686 V 30 w(WINDO)m(W4.)p +Black 448 867 a Fp(CUDD)p 717 867 V 32 w(REORDER)p 1206 +867 V 30 w(ANNEALING:)p Black 43 w Fo(This)24 b(method)h(is)f(an)h +(implementation)i(of)d(simu-)676 980 y(lated)e(annealing)h(for)f(v)n +(ariable)h(ordering,)g(v)n(aguely)g(resemblant)g(of)e(the)h(algorithm)g +(of)676 1093 y([2].)28 b(This)c(method)g(is)g(potentially)i(v)o(ery)e +(slo)n(w)-6 b(.)p Black 448 1275 a Fp(CUDD)p 717 1275 +V 32 w(REORDER)p 1206 1275 V 30 w(GENETIC:)p Black 44 +w Fo(This)26 b(method)i(is)e(an)h(implementation)j(of)c(a)h(genetic)676 +1388 y(algorithm)g(for)e(v)n(ariable)j(ordering,)f(inspired)h(by)d(the) +h(w)o(ork)g(of)f(Drechsler)i([6)q(].)33 b(This)676 1501 +y(method)24 b(is)f(potentially)k(v)o(ery)d(slo)n(w)-6 +b(.)p Black 448 1682 a Fp(CUDD)p 717 1682 V 32 w(REORDER)p +1206 1682 V 30 w(EXA)h(CT:)p Black 44 w Fo(This)22 b(method)i +(implements)h(a)d(dynamic)i(programming)676 1795 y(approach)d(to)f(e)o +(xact)g(reordering)i([9)q(,)c(7)q(,)g(10)q(],)h(with)h(impro)o(v)o +(ements)h(described)h(in)d([11)q(].)676 1908 y(It)33 +b(only)h(stores)g(one)g(BDD)d(at)j(the)f(time.)58 b(Therefore,)37 +b(it)c(is)g(relati)n(v)o(ely)i(ef)n(\002cient)f(in)676 +2021 y(terms)29 b(of)g(memory)-6 b(.)45 b(Compared)29 +b(to)g(other)h(reordering)i(strate)o(gies,)g(it)d(is)g(v)o(ery)g(slo)n +(w)-6 b(,)676 2134 y(and)24 b(is)f(not)h(recommended)i(for)d(more)h +(than)g(16)g(v)n(ariables.)448 2329 y(So)f(f)o(ar)h(we)e(ha)n(v)o(e)i +(described)i(methods)f(whereby)g(the)e(package)j(selects)f(an)e(order)i +(automati-)448 2442 y(cally)-6 b(.)28 b(A)17 b(gi)n(v)o(en)i(order)g +(of)f(the)g(v)n(ariables)i(can)f(also)g(be)f(imposed)h(by)f(calling)i +Fn(Cudd)p 3050 2442 V 34 w(Shuf)n(\003eHeap)p Fo(.)448 +2688 y Fi(3.13)99 b(Gr)n(ouping)26 b(V)-9 b(ariables)448 +2862 y Fo(CUDD)29 b(allo)n(ws)i(the)g(application)j(to)d(specify)h +(constraints)i(on)d(the)g(positions)j(of)c(group)i(of)448 +2975 y(v)n(ariables.)63 b(It)34 b(is)g(possible)j(to)d(request)i(that)f +(a)f(group)h(of)f(contiguous)k(v)n(ariables)e(be)e(k)o(ept)448 +3088 y(contiguous)39 b(by)d(the)g(reordering)i(procedures.)68 +b(It)35 b(is)g(also)h(possible)i(to)e(request)h(that)f(the)448 +3201 y(relati)n(v)o(e)31 b(order)f(of)g(some)f(groups)j(of)d(v)n +(ariables)j(be)d(left)h(unchanged.)50 b(The)29 b(constraints)j(on)448 +3314 y(the)24 b(order)h(are)e(speci\002ed)i(by)f(means)g(of)f(a)g +(tree,)h(which)g(is)f(created)j(in)d(one)h(of)g(tw)o(o)f(w)o(ays:)p +Black 585 3486 a Fm(\017)p Black 46 w Fo(By)f(calling)k +Fn(Cudd)p 1276 3486 V 33 w(Mak)o(eT)-5 b(r)m(eeNode)p +Fo(.)p Black 585 3668 a Fm(\017)p Black 46 w Fo(By)21 +b(calling)j(the)f(functions)i(of)d(the)h(MTR)e(library)j(\(part)f(of)f +(the)h(distrib)n(ution\),)j(and)d(by)676 3781 y(re)o(gistering)i(the)d +(result)i(with)e(the)g(manager)i(using)f Fn(Cudd)p 2510 +3781 V 34 w(SetT)-5 b(r)m(ee)p Fo(.)29 b(The)22 b(current)i(tree)676 +3894 y(re)o(gistered)h(with)f(the)g(manager)g(can)g(be)g(read)g(with)f +Fn(Cudd)p 2531 3894 V 34 w(ReadT)-5 b(r)m(ee)p Fo(.)589 +4067 y(Each)36 b(node)h(in)f(the)g(tree)h(represents)h(a)e(range)h(of)f +(v)n(ariables.)68 b(The)35 b(lo)n(wer)h(bound)h(of)448 +4180 y(the)29 b(range)g(is)f(gi)n(v)o(en)h(by)f(the)h +Fn(low)e Fo(\002eld)h(of)g(the)h(node,)h(and)f(the)f(size)h(of)f(the)g +(group)i(is)e(gi)n(v)o(en)448 4293 y(by)33 b(the)g Fn(size)g +Fo(\002eld)g(of)g(the)g(node.)1525 4260 y Fg(2)1619 4293 +y Fo(The)f(v)n(ariables)j(in)e(each)g(range)h(are)f(k)o(ept)g +(contiguous.)448 4405 y(Furthermore,)22 b(if)e(a)f(node)i(is)f(mark)o +(ed)g(with)g(the)g(MTR)p 2159 4405 V 32 w(FIXED)e(\003ag,)i(then)g(the) +g(relati)n(v)o(e)h(order)448 4518 y(of)32 b(the)g(v)n(ariable)i(ranges) +g(associated)g(to)e(its)g(children)i(is)e(not)h(changed.)56 +b(As)31 b(an)h(e)o(xample,)448 4631 y(suppose)26 b(the)e(initial)h(v)n +(ariable)g(order)f(is:)p Black 448 4706 1196 4 v 554 +4762 a Ff(2)583 4794 y Fe(When)18 b(the)g(v)n(ariables)h(in)f(a)g +(group)h(are)f(reordered,)h(the)g(association)g(between)f(the)h +Fb(low)e Fe(\002eld)h(and)h(the)f(inde)o(x)448 4885 y(of)k(the)h +(\002rst)e(v)n(ariable)h(in)g(the)h(group)g(is)f(lost.)32 +b(The)22 b(package)i(updates)f(the)f(tree)g(to)g(k)o(eep)h(track)f(of)h +(the)f(changes.)448 4976 y(Ho)n(we)n(v)o(er)m(,)e(the)f(application)g +(cannot)h(rely)f(on)h Fb(low)e Fe(to)h(determine)g(the)g(position)h(of) +f(v)n(ariables.)p Black Black 1897 5225 a Fo(19)p Black +eop end +%%Page: 20 20 +TeXDict begin 20 19 bop Black Black Black Black 448 573 +a Fh(x0,)54 b(y0,)f(z0,)g(x1,)g(y1,)g(z1,)g(...)h(,)g(x9,)f(y9,)g(z9.) +448 748 y Fo(Suppose)27 b(we)f(w)o(ant)f(to)h(k)o(eep)h(each)g(group)g +(of)f(three)g(v)n(ariables)i(with)e(the)g(same)g(inde)o(x)h(\(e.g.,)448 +861 y Fh(x3,)54 b(y3,)f(z3)p Fo(\))21 b(contiguous,)27 +b(while)c(allo)n(wing)h(the)g(package)h(to)e(change)i(the)f(order)g(of) +f(the)448 974 y(groups.)31 b(W)-7 b(e)22 b(can)i(accomplish)i(this)e +(with)f(the)h(follo)n(wing)h(code:)p Black Black 448 +1150 a Fh(for)54 b(\(i)f(=)h(0;)g(i)g(<)g(10;)f(i++\))g({)667 +1262 y(\(void\))e(Cudd_MakeTreeNo)o(de\()o(ma)o(na)o(ge)o(r,)o(i*3)o +(,3)o(,M)o(TR)o(_D)o(EFA)o(UL)o(T\))o(;)448 1375 y(})448 +1551 y Fo(If)26 b(we)f(w)o(ant)h(to)g(k)o(eep)h(the)f(order)h(within)g +(each)g(group)g(of)f(v)n(ariables)i(\002x)o(ed)e(\(i.e.,)f +Fh(x)g Fo(before)j Fh(y)448 1664 y Fo(before)d Fh(z)p +Fo(\))e(we)f(need)j(to)e(change)i(MTR)p 1710 1664 28 +4 v 32 w(DEF)-7 b(A)i(UL)d(T)20 b(into)k(MTR)p 2521 1664 +V 32 w(FIXED.)589 1777 y(The)32 b Fn(low)f Fo(parameter)i(passed)g(to)f +Fn(Cudd)p 1894 1777 V 33 w(Mak)o(eT)-5 b(r)m(eeNode)33 +b Fo(is)f(the)g(inde)o(x)g(of)f(a)h(v)n(ariable)448 1890 +y(\(as)27 b(opposed)i(to)e(its)f(le)n(v)o(el)h(or)g(position)i(in)d +(the)h(order\).)39 b(The)27 b(group)g(tree)h(can)f(be)f(created)i(at) +448 2003 y(an)o(y)g(time.)40 b(The)27 b(result)h(ob)o(viously)i +(depends)f(on)f(the)f(v)n(ariable)i(order)g(in)e(ef)n(fect)h(at)f +(creation)448 2115 y(time.)589 2228 y(It)20 b(is)g(possible)i(to)e +(create)h(a)e(v)n(ariable)j(group)f(tree)f(also)h(before)g(the)f(v)n +(ariables)i(themselv)o(es)448 2341 y(are)f(created.)29 +b(The)21 b(package)h(assumes)g(in)e(this)i(case)f(that)g(the)g(inde)o +(x)g(of)g(the)f(v)n(ariables)j(not)e(yet)448 2454 y(in)h(e)o(xistence)i +(will)e(equal)g(their)h(position)h(in)e(the)g(order)h(when)f(the)o(y)g +(are)g(created.)30 b(Therefore,)448 2567 y(applications)g(that)c(rely)h +(on)f Fn(Cudd)p 1558 2567 V 34 w(bddNe)o(wV)-10 b(arAtLe)o(vel)26 +b Fo(or)g Fn(Cudd)p 2613 2567 V 34 w(addNe)o(wV)-10 b(arAtLe)o(vel)26 +b Fo(to)448 2680 y(create)f(ne)n(w)e(v)n(ariables)j(ha)n(v)o(e)e(to)f +(create)i(the)f(v)n(ariables)h(before)g(the)o(y)f(group)h(them.)589 +2793 y(The)31 b(reordering)j(procedure)g(will)d(skip)h(all)g(groups)h +(whose)e(v)n(ariables)j(are)d(not)h(yet)f(in)448 2906 +y(e)o(xistence.)h(F)o(or)24 b(groups)h(that)g(are)f(only)h(partially)h +(in)e(e)o(xistence,)i(the)e(reordering)j(procedure)448 +3019 y(will)18 b(try)h(to)f(reorder)i(the)e(v)n(ariables)i(already)g +(instantiated,)j(without)c(violating)i(the)d(adjacenc)o(y)448 +3132 y(constraints.)448 3378 y Fi(3.14)99 b(V)-9 b(ariable)25 +b(Reordering)h(f)n(or)e(ZDDs)448 3553 y Fo(Reordering)h(of)d(ZDDs)f(is) +h(done)h(in)g(much)f(the)h(same)f(w)o(ay)h(as)f(the)g(reordering)k(of)c +(BDDs)f(and)448 3666 y(ADDs.)28 b(The)23 b(functions)j(corresponding)i +(to)c Fn(Cudd)p 2095 3666 V 33 w(ReduceHeap)i Fo(and)e +Fn(Cudd)p 2966 3666 V 33 w(Shuf)n(\003eHeap)448 3778 +y Fo(are)h Fn(Cudd)p 784 3778 V 33 w(zddReduceHeap)i +Fo(and)e Fn(Cudd)p 1782 3778 V 34 w(zddShuf)n(\003eHeap)p +Fo(.)34 b(T)-7 b(o)23 b(enable)j(dynamic)f(reorder)n(-)448 +3891 y(ing,)36 b(the)e(application)j(must)c(call)h Fn(Cudd)p +1777 3891 V 34 w(A)n(utodynEnableZdd)r Fo(,)39 b(and)34 +b(to)g(disable)h(dynamic)448 4004 y(reordering,)29 b(it)d(must)g(call)g +Fn(Cudd)p 1510 4004 V 34 w(A)n(utodynDisableZdd)r Fo(.)39 +b(In)26 b(the)g(current)i(implementation,)448 4117 y(ho)n(we)n(v)o(er)l +(,)c(the)f(choice)h(of)f(reordering)j(methods)e(for)g(ZDDs)d(is)i(more) +g(limited.)29 b(Speci\002cally)-6 b(,)448 4230 y(these)25 +b(methods)g(are)e(a)n(v)n(ailable:)p Black 448 4428 a +Fp(CUDD)p 717 4428 V 32 w(REORDER)p 1206 4428 V 30 w(NONE;)p +Black Black 448 4611 a(CUDD)p 717 4611 V 32 w(REORDER)p +1206 4611 V 30 w(SAME;)p Black Black 448 4794 a(CUDD)p +717 4794 V 32 w(REORDER)p 1206 4794 V 30 w(RANDOM;)p +Black Black 448 4976 a(CUDD)p 717 4976 V 32 w(REORDER)p +1206 4976 V 30 w(RANDOM)p 1657 4976 V 31 w(PIV)l(O)l(T;)p +Black Black 1897 5225 a Fo(20)p Black eop end +%%Page: 21 21 +TeXDict begin 21 20 bop Black Black Black 448 573 a Fp(CUDD)p +717 573 28 4 v 32 w(REORDER)p 1206 573 V 30 w(SIFT;)p +Black Black 448 760 a(CUDD)p 717 760 V 32 w(REORDER)p +1206 760 V 30 w(SIFT)p 1439 760 V 32 w(CONVERGE;)p Black +Black 448 948 a(CUDD)p 717 948 V 32 w(REORDER)p 1206 +948 V 30 w(SYMM)p 1525 948 V 31 w(SIFT;)p Black Black +448 1136 a(CUDD)p 717 1136 V 32 w(REORDER)p 1206 1136 +V 30 w(SYMM)p 1525 1136 V 31 w(SIFT)p 1759 1136 V 32 +w(CONV.)p Black 589 1348 a Fo(T)-7 b(o)20 b(create)j(ZDD)c(v)n(ariable) +k(groups,)g(the)e(application)j(calls)e Fn(Cudd)p 2693 +1348 V 34 w(Mak)o(eZddT)-5 b(r)m(eeNode)p Fo(.)448 1597 +y Fi(3.15)99 b(K)n(eeping)25 b(Consistent)g(V)-9 b(ariable)25 +b(Orders)g(f)n(or)g(BDDs)g(and)g(ZDDs)448 1772 y Fo(Se)n(v)o(eral)f +(applications)i(that)e(manipulate)i(both)e(BDDs)d(and)j(ZDDs)d +(bene\002t)j(from)f(k)o(eeping)j(a)448 1885 y(\002x)o(ed)e +(correspondence)29 b(between)d(the)f(order)g(of)f(the)h(BDD)d(v)n +(ariables)27 b(and)e(the)f(order)i(of)e(the)448 1998 +y(ZDD)k(v)n(ariables.)51 b(If)30 b(each)h(BDD)d(v)n(ariable)k +(corresponds)h(to)d(a)g(group)h(of)f(ZDD)e(v)n(ariables,)448 +2110 y(then)34 b(it)e(is)g(often)i(desirable)h(that)e(the)g(groups)h +(of)f(ZDD)d(v)n(ariables)35 b(be)d(in)h(the)g(same)f(order)448 +2223 y(as)g(the)g(corresponding)37 b(BDD)30 b(v)n(ariables.)55 +b(CUDD)30 b(allo)n(ws)i(the)h(ZDD)c(order)k(to)f(track)h(the)448 +2336 y(BDD)27 b(order)j(and)f(vice)g(v)o(ersa.)45 b(T)-7 +b(o)27 b(ha)n(v)o(e)j(the)f(ZDD)d(order)k(track)f(the)g(BDD)e(order)l +(,)k(the)e(ap-)448 2449 y(plication)g(calls)e Fn(Cudd)p +1185 2449 V 34 w(zddRealignEnable)p Fo(.)41 b(The)26 +b(ef)n(fect)i(of)e(this)h(call)g(can)g(be)f(re)n(v)o(ersed)i(by)448 +2562 y(calling)j Fn(Cudd)p 925 2562 V 34 w(zddRealignDisable)p +Fo(.)48 b(When)29 b(ZDD)e(realignment)k(is)e(in)g(ef)n(fect,)i +(automatic)448 2675 y(reordering)c(of)c(ZDDs)f(should)j(be)f(disabled.) +448 2924 y Fi(3.16)99 b(Hooks)448 3098 y Fo(Hooks)22 +b(in)f(CUDD)d(are)k(lists)f(of)g(application-speci\002ed)27 +b(functions)c(to)e(be)g(run)g(on)h(certain)g(oc-)448 +3211 y(casions.)29 b(Each)18 b(hook)h(is)f(identi\002ed)i(by)e(a)g +(constant)i(of)e(the)g(enumerated)j(type)d Fn(Cudd)p +3125 3211 V 34 w(HookT)-7 b(ype)p Fo(.)448 3324 y(In)24 +b(V)-10 b(ersion)24 b(2.5.0)g(hooks)h(are)e(de\002ned)i(for)e(these)i +(occasions:)p Black 585 3512 a Fm(\017)p Black 46 w Fo(before)f +(garbage)h(collection)i(\(CUDD)p 1916 3512 V 31 w(PRE)p +2115 3512 V 32 w(GC)p 2274 3512 V 32 w(HOOK\);)p Black +585 3700 a Fm(\017)p Black 46 w Fo(after)d(garbage)h(collection)h +(\(CUDD)p 1850 3700 V 32 w(POST)p 2106 3700 V 31 w(GC)p +2264 3700 V 32 w(HOOK\);)p Black 585 3887 a Fm(\017)p +Black 46 w Fo(before)e(v)n(ariable)i(reordering)g(\(CUDD)p +1939 3887 V 32 w(PRE)p 2139 3887 V 31 w(REORDERING)p +2759 3887 V 30 w(HOOK\);)p Black 585 4075 a Fm(\017)p +Black 46 w Fo(after)e(v)n(ariable)h(reordering)h(\(CUDD)p +1873 4075 V 32 w(POST)p 2129 4075 V 31 w(REORDERING)p +2749 4075 V 30 w(HOOK\).)448 4262 y(The)e(current)i(implementation)i +(of)c(hooks)i(is)e(e)o(xperimental.)34 b(A)24 b(function)i(added)g(to)e +(a)g(hook)448 4375 y(recei)n(v)o(es)c(a)e(pointer)i(to)e(the)g(manager) +l(,)j(a)d(pointer)i(to)e(a)g(constant)i(string,)h(and)d(a)g(pointer)i +(to)e(v)n(oid)448 4488 y(as)27 b(ar)n(guments;)j(it)d(must)f(return)i +(1)e(if)g(successful;)31 b(0)c(otherwise.)39 b(The)26 +b(second)i(ar)n(gument)g(is)448 4601 y(one)21 b(of)f(\223DD,)-6 +b(\224)19 b(\223BDD,)-6 b(\224)18 b(and)j(\223ZDD.)-6 +b(\224)18 b(This)i(allo)n(ws)h(the)f(hook)h(functions)i(to)d(tell)h +(the)f(type)h(of)448 4714 y(diagram)f(for)f(which)h(reordering)h(or)e +(garbage)h(collection)i(tak)o(es)e(place.)28 b(The)19 +b(third)g(ar)n(gument)448 4827 y(v)n(aries)30 b(depending)h(on)e(the)g +(hook.)45 b(The)28 b(hook)h(functions)i(called)f(before)g(or)f(after)g +(garbage)448 4940 y(collection)d(do)d(not)g(use)g(it.)28 +b(The)23 b(hook)h(functions)h(called)f(before)g(reordering)i(are)d +(passed,)h(in)p Black 1897 5225 a(21)p Black eop end +%%Page: 22 22 +TeXDict begin 22 21 bop Black Black 448 573 a Fo(addition)32 +b(to)d(the)h(pointer)h(to)f(the)g(manager)l(,)i(also)e(the)g(method)g +(used)h(for)e(reordering.)50 b(The)448 686 y(hook)27 +b(functions)h(called)f(after)f(reordering)j(are)d(passed)h(the)f(start) +g(time.)35 b(T)-7 b(o)25 b(add)h(a)f(function)448 799 +y(to)e(a)g(hook,)g(one)h(uses)f Fn(Cudd)p 1363 799 28 +4 v 34 w(AddHook)r Fo(.)29 b(The)22 b(function)j(of)e(a)g(gi)n(v)o(en)g +(hook)h(are)f(called)h(in)f(the)448 912 y(order)k(in)e(which)h(the)o(y) +g(were)f(added)i(to)f(the)f(hook.)36 b(F)o(or)25 b(sample)h(hook)g +(functions,)j(one)d(may)448 1024 y(look)f(at)e Fn(Cudd)p +922 1024 V 34 w(StdPr)m(eReor)m(dHook)k Fo(and)d Fn(Cudd)p +1990 1024 V 34 w(StdP)-7 b(ostReor)m(dHook)r Fo(.)448 +1274 y Fi(3.17)99 b(T)n(imeouts)26 b(and)f(Limits)448 +1448 y Fo(It)19 b(is)h(possible)h(to)f(set)f(a)g(time)g(limit)h(for)f +(a)g(manger)h(with)g Fn(Cudd)p 2413 1448 V 33 w(SetT)-5 +b(imeLimit)r Fo(.)27 b(Once)20 b(set,)g(the)448 1561 +y(time)g(a)n(v)n(ailable)i(to)e(the)h(manager)g(can)f(be)g(modi\002ed)h +(through)h(other)f(API)d(functions.)31 b(CUDD)448 1674 +y(checks)e(for)e(e)o(xpiration)i(periodically)-6 b(.)43 +b(When)27 b(time)g(has)g(e)o(xpired,)j(it)c(returns)j(NULL)24 +b(from)448 1787 y(the)29 b(call)h(in)e(progress,)k(b)n(ut)e(it)e(lea)n +(v)o(es)i(the)f(manager)h(in)f(a)f(consistent)k(state.)45 +b(The)28 b(in)l(v)n(oking)448 1900 y(application)f(must)d(be)f +(designed)j(to)d(handle)j(the)d(NULL)e(v)n(alues)k(returned.)589 +2013 y(When)35 b(reordering,)k(if)34 b(a)g(timout)h(is)f(approaching,) +41 b(CUDD)31 b(will)j(quit)h(reordering)i(to)448 2125 +y(gi)n(v)o(e)24 b(the)g(application)i(a)e(chance)h(to)e(\002nish)h +(some)g(computation.)589 2238 y(It)31 b(is)h(also)f(possible)j(to)d(in) +l(v)n(ok)o(e)j(some)d(functions)j(that)e(return)g(NULL)d(if)i(the)o(y)h +(cannot)448 2351 y(complete)k(without)f(creating)i(more)d(than)h(a)f +(set)g(number)h(of)g(nodes.)62 b(See,)36 b(for)e(instance,)448 +2464 y Fn(Cudd)p 649 2464 V 34 w(bddAndLimit)r Fo(.)448 +2713 y Fi(3.18)99 b(The)26 b(SIS/VIS)f(Interface)448 +2888 y Fo(The)j(CUDD)d(package)30 b(contains)f(interf)o(ace)h +(functions)h(that)d(emulate)g(the)g(beha)n(vior)i(of)e(the)448 +3001 y(original)i(BDD)c(package)k(used)f(in)f(SIS)e([17)q(])i(and)g(in) +g(the)g(ne)n(wer)g(VIS)2719 2968 y Fg(3)2783 3001 y Fo([4].)42 +b(Ho)n(w)26 b(to)i(b)n(uild)448 3113 y(VIS)i(with)i(CUDD)d(is)i +(described)j(in)e(the)f(installation)k(documents)f(of)d(VIS.)f(\(V)-10 +b(ersion)32 b(1.1)448 3226 y(and)24 b(later)-5 b(.\))448 +3472 y Fp(3.18.1)93 b(Using)22 b(the)h(CUDD)f(P)o(ackage)i(in)e(SIS)448 +3646 y Fo(This)32 b(section)h(describes)h(ho)n(w)d(to)h(b)n(uild)g(SIS) +f(with)g(the)h(CUDD)d(package.)55 b(Let)31 b Fh(SISDIR)448 +3759 y Fo(designate)41 b(the)d(root)h(of)f(the)g(directory)j(hierarchy) +f(where)e(the)h(sources)g(for)g(SIS)d(reside.)448 3872 +y(Let)27 b Fh(CUDDDIR)d Fo(be)j(the)h(root)g(of)g(the)f(directory)j +(hierarchy)g(where)e(the)f(distrib)n(ution)32 b(of)27 +b(the)448 3985 y(CUDD)21 b(package)k(resides.)30 b(T)-7 +b(o)22 b(b)n(uild)i(SIS)d(with)i(the)g(CUDD)e(package,)k(follo)n(w)e +(these)h(steps.)p Black 562 4173 a(1.)p Black 46 w(Create)g +(directories)i Fh(SISDIR/sis/cudd)16 b Fo(and)24 b Fh(SISDIR/sis/mtr)p +Fo(.)p Black 562 4360 a(2.)p Black 46 w(Cop)o(y)18 b(all)g(\002les)g +(from)g Fh(CUDDDIR/cudd)12 b Fo(and)18 b Fh(CUDDDIR/sis)13 +b Fo(to)18 b Fh(SISDIR/sis/cud)o(d)676 4473 y Fo(and)24 +b(all)f(\002les)g(from)h Fh(CUDDDIR/mtr)18 b Fo(to)23 +b Fh(SISDIR/sis/mtr)p Fo(.)p Black 562 4661 a(3.)p Black +46 w(Cop)o(y)35 b Fh(CUDDDIR/cudd/d)o(oc)o(/c)o(ud)o(d.d)o(oc)27 +b Fo(to)35 b Fh(SISDIR/sis/cud)o(d)p Fo(;)f(also)676 +4774 y(cop)o(y)24 b Fh(CUDDDIR/mtr/doc)o(/m)o(tr)o(.do)o(c)16 +b Fo(to)24 b Fh(SISDIR/sis/mtr)o Fo(.)p Black 448 4855 +1196 4 v 554 4911 a Ff(3)583 4942 y Fe(http://vlsi.Colorado.EDU/)18 +b(vis/)p Black Black 1897 5225 a Fo(22)p Black eop end +%%Page: 23 23 +TeXDict begin 23 22 bop Black Black Black 562 573 a Fo(4.)p +Black 46 w(In)38 b Fh(SISDIR/sis/cud)o(d)31 b Fo(mak)o(e)39 +b Fh(bdd.h)c Fo(a)j(symbolic)h(link)g(to)f Fh(cuddBdd.h)p +Fo(.)676 686 y(\(That)23 b(is:)29 b Fh(ln)54 b(-s)g(cuddBdd.h)c(bdd.h)p +Fo(.\))p Black 562 873 a(5.)p Black 46 w(In)27 b Fh(SISDIR/sis/cudd)20 +b Fo(delete)29 b Fh(Makefile)23 b Fo(and)28 b(rename)h +Fh(Makefile.sis)676 986 y Fo(as)23 b Fh(Makefile)p Fo(.)h(Do)f(the)h +(same)f(in)h Fh(SISDIR/sis/mtr)p Fo(.)p Black 562 1174 +a(6.)p Black 46 w(Cop)o(y)18 b Fh(CUDDDIR/sis/st.)o([c)o(h])11 +b Fo(and)18 b Fh(CUDDDIR/st/doc/)o(st)o(.d)o(oc)11 b +Fo(to)18 b Fh(SISDIR/sis/st)p Fo(.)676 1287 y(\(This)29 +b(will)h(o)o(v)o(erwrite)h(the)f(original)h(\002les:)42 +b(Y)-10 b(ou)29 b(may)h(w)o(ant)g(to)g(sa)n(v)o(e)g(them)g(before-)676 +1400 y(hand.\))p Black 562 1587 a(7.)p Black 46 w(From)17 +b Fh(CUDDDIR/util)12 b Fo(cop)o(y)19 b Fh(datalimit.c)12 +b Fo(to)18 b Fh(SISDIR/sis/util)o Fo(.)i(Up-)676 1700 +y(date)30 b Fh(util.h)d Fo(and)k Fh(Makefile)26 b Fo(in)k +Fh(SISDIR/sis/uti)o(l)p Fo(.)42 b(Speci\002cally)-6 b(,)33 +b(add)676 1813 y(the)38 b(declaration)k Fh(EXTERN)52 +b(long)g(getSoftDataLimi)o(t\(\))o(;)39 b Fo(to)f Fh(util.h)676 +1926 y Fo(and)24 b(add)g Fh(datalimit.c)17 b Fo(to)24 +b(the)g(list)f(of)h(source)h(\002les)e(\(PSRC\))f(in)h +Fh(Makefile)p Fo(.)p Black 562 2114 a(8.)p Black 46 w(In)g +Fh(SISDIR/sis)17 b Fo(remo)o(v)o(e)23 b(the)h(link)f(from)g +Fh(bdd)e Fo(to)i Fh(bdd)p 2578 2114 28 4 v 31 w(cmu)e +Fo(or)i Fh(bdd)p 3058 2114 V 32 w(ucb)d Fo(\(that)676 +2227 y(is,)36 b Fh(rm)54 b(bdd)p Fo(\))32 b(and)j(mak)o(e)f +Fh(bdd)e Fo(a)i(symbolic)i(link)f(to)f Fh(cudd)p Fo(.)58 +b(\(That)35 b(is:)50 b Fh(ln)k(-s)676 2340 y(cudd)e(bdd)p +Fo(.\))p Black 562 2527 a(9.)p Black 46 w(Still)17 b(in)h +Fh(SISDIR/sis)p Fo(,)c(edit)19 b Fh(Makefile)p Fo(,)14 +b Fh(Makefile.oct)p Fo(,)f(and)18 b Fh(Makefile.nooct)p +Fo(.)676 2640 y(In)23 b(all)h(three)g(\002les)f(add)h(mtr)f(to)h(the)g +(list)g(of)f(directories)j(to)e(be)f(made)h(\(DIRS\).)p +Black 517 2828 a(10.)p Black 46 w(In)18 b Fh(SISDIR/sis/inc)o(lu)o(de) +11 b Fo(mak)o(e)18 b Fh(mtr.h)d Fo(a)j(symbolic)h(link)g(to)f +Fh(../mtr/mtr.h)p Fo(.)p Black 517 3015 a(11.)p Black +46 w(In)g Fh(SISDIR/sis/doc)10 b Fo(mak)o(e)19 b Fh(cudd.doc)13 +b Fo(a)18 b(symbolic)i(link)e(to)g Fh(../cudd/cudd.doc)676 +3128 y Fo(and)32 b Fh(mtr.doc)d Fo(a)j(symbolic)h(link)g(to)g +Fh(../mtr/mtr.doc)o Fo(.)48 b(\(That)33 b(is:)46 b Fh(ln)54 +b(-s)676 3241 y(../cudd/cudd.d)o(oc)48 b(.;)53 b(ln)h(-s)g +(../mtr/mtr.doc)48 b(.)p Fo(.\))p Black 517 3429 a(12.)p +Black 46 w(From)25 b Fh(SISDIR)e Fo(do)j Fh(make)53 b(clean)23 +b Fo(follo)n(wed)k(by)f Fh(make)53 b(-i)p Fo(.)35 b(This)26 +b(should)i(cre-)676 3542 y(ate)23 b(a)g(w)o(orking)i(cop)o(y)g(of)e +(SIS)f(that)i(uses)h(the)e(CUDD)f(package.)589 3729 y(The)35 +b(replacement)j(for)d(the)h Fh(st)d Fo(library)k(is)e(because)i(the)e +(v)o(ersion)i(shipped)g(with)e(the)448 3842 y(CUDD)22 +b(package)27 b(tests)e(for)f(out-of-memory)j(conditions.)35 +b(Notice)24 b(that)h(the)g(v)o(ersion)h(of)e(the)448 +3955 y Fh(st)32 b Fo(library)k(to)e(be)f(used)i(for)f(replacement)j(is) +c(not)h(the)h(one)f(used)h(for)f(the)g(normal)g(b)n(uild,)448 +4068 y(because)26 b(the)e(latter)g(has)g(been)h(modi\002ed)f(for)g(C++) +f(compatibility)-6 b(.)32 b(The)23 b(abo)o(v)o(e)h(installation)448 +4181 y(procedure)34 b(has)e(been)h(tested)f(on)g(SIS)e(1.3.)52 +b(SIS)30 b(can)i(be)g(obtained)h(via)f(anon)o(ymous)h(FTP)448 +4294 y(from)18 b Fh(ic.eecs.berkele)o(y.e)o(du)o Fo(.)i(T)-7 +b(o)17 b(b)n(uild)j(SIS)c(1.3,)j(you)g(need)g Fh(sis-1.2.tar.Z)448 +4407 y Fo(and)g Fh(sis-1.2.patch1.Z)o Fo(.)12 b(When)19 +b(compiling)h(on)f(a)f(DEC)f(Alpha,)i(you)h(should)g(add)f(the)448 +4520 y Fh(-ieee)p 728 4520 V 31 w(with)p 979 4520 V 31 +w(no)p 1120 4520 V 31 w(inexact)e Fo(\003ag.)27 b(\(See)20 +b(Section)h(3.5.2.\))28 b(Refer)20 b(to)g(the)h Fh(Makefile)15 +b Fo(in)448 4633 y(the)24 b(top)g(le)n(v)o(el)g(directory)i(of)d(the)h +(distrib)n(ution)j(for)d(ho)n(w)f(to)g(compile)i(with)e(32-bit)i +(pointers.)p Black 1897 5225 a(23)p Black eop end +%%Page: 24 24 +TeXDict begin 24 23 bop Black Black 448 573 a Fi(3.19)99 +b(Writing)25 b(Decision)f(Diagrams)g(to)h(a)g(File)448 +747 y Fo(The)c(CUDD)e(package)k(pro)o(vides)g(se)n(v)o(eral)f +(functions)i(to)d(write)g(decision)j(diagrams)e(to)f(a)g(\002le.)448 +860 y Fn(Cudd)p 649 860 28 4 v 34 w(DumpBlif)35 b Fo(writes)23 +b(a)f(\002le)g(in)g Fn(blif)37 b Fo(format.)28 b(It)23 +b(is)f(restricted)j(to)d(BDDs.)27 b(The)22 b(diagrams)448 +973 y(are)j(written)g(as)f(a)g(netw)o(ork)i(of)e(multiple)o(x)o(ers,)i +(one)f(multiple)o(x)o(er)h(for)f(each)g(internal)h(node)f(of)448 +1086 y(the)f(BDD.)589 1199 y Fn(Cudd)p 790 1199 V 34 +w(DumpDot)37 b Fo(produces)i(input)e(suitable)h(to)e(the)g(graph-dra)o +(wing)j(program)e Fn(dot)3399 1166 y Fg(4)448 1312 y +Fo(written)29 b(by)g(Eleftherios)h(K)m(outso\002os)g(and)f(Stephen)g +(C.)e(North.)43 b(An)28 b(e)o(xample)h(of)g(dra)o(wing)448 +1425 y(produced)f(by)d(dot)g(from)g(the)g(output)h(of)f +Fn(Cudd)p 1959 1425 V 34 w(DumpDot)h Fo(is)e(sho)n(wn)i(in)e(Figure)i +(1.)32 b(It)25 b(is)f(re-)448 1537 y(stricted)j(to)d(BDDs)f(and)h +(ADDs.)30 b Fn(Cudd)p 1726 1537 V 34 w(zddDumpDot)d Fo(is)d(the)h +(analog)h(of)e Fn(Cudd)p 3050 1537 V 34 w(DumpDot)448 +1650 y Fo(for)g(ZDDs.)589 1763 y Fn(Cudd)p 790 1763 V +34 w(DumpDaV)-7 b(inci)41 b Fo(produces)i(input)f(suitable)g(to)f(the)g +(graph-dra)o(wing)i(program)448 1876 y Fn(daV)-7 b(inci)722 +1843 y Fg(5)799 1876 y Fo(de)n(v)o(eloped)40 b(at)d(the)i(Uni)n(v)o +(ersity)g(of)f(Bremen.)71 b(It)38 b(is)f(restricted)k(to)d(BDDs)e(and) +448 1989 y(ADDs.)589 2102 y(Functions)f(are)d(also)h(a)n(v)n(ailable)h +(to)f(produce)h(the)e(input)i(format)f(of)f Fn(DDcal)g +Fo(\(see)h(Sec-)448 2215 y(tion)24 b(2.2\))g(and)g(f)o(actored)i +(forms.)448 2464 y Fi(3.20)99 b(Sa)n(ving)25 b(and)g(Restoring)g(BDDs) +448 2638 y Fo(The)e Fn(dddmp)858 2605 y Fg(6)919 2638 +y Fo(library)i(by)e(Gianpiero)i(Cabodi)f(and)g(Stef)o(ano)g(Quer)f +(allo)n(ws)g(a)g(CUDD)e(appli-)448 2751 y(cation)30 b(to)e(sa)n(v)o(e)h +(BDDs)d(to)j(disk)g(in)f(compact)h(form)f(for)h(later)g(retrie)n(v)n +(al.)44 b(See)28 b(the)g(library')-5 b(s)448 2864 y(o)n(wn)23 +b(documentation)k(for)d(the)g(details.)448 3157 y Fq(4)120 +b(Pr)n(ogrammer')l(s)27 b(Manual)448 3364 y Fo(This)g(section)i(pro)o +(vides)g(additional)h(detail)e(on)f(the)g(w)o(orking)i(of)e(the)g(CUDD) +e(package)k(and)448 3477 y(on)37 b(the)g(programming)h(con)l(v)o +(entions)i(follo)n(wed)e(in)e(its)h(writing.)68 b(The)36 +b(additional)j(detail)448 3590 y(should)21 b(help)f(those)h(who)e(w)o +(ant)g(to)h(write)f(procedures)j(that)e(directly)h(manipulate)h(the)e +(CUDD)448 3703 y(data)k(structures.)448 3952 y Fi(4.1)99 +b(Compiling)25 b(and)g(Linking)448 4126 y Fo(If)32 b(you)h(plan)h(to)e +(use)h(the)f(CUDD)f(package)j(as)e(a)g(clear)i(box)f(\(for)f(instance,) +37 b(you)c(w)o(ant)f(to)448 4239 y(write)24 b(a)f(procedure)j(that)e +(tra)n(v)o(erses)i(a)d(decision)j(diagram\))f(you)f(need)g(to)f(add)p +Black Black 448 4427 a Fh(#include)51 b("cuddInt.h")p +Black 448 4491 1196 4 v 554 4546 a Ff(4)583 4578 y Fe(http://www)-5 +b(.research.att.com/sw/tools/graphviz)554 4640 y Ff(5)583 +4671 y Fe(ftp://ftp.uni-bremen.de/pub/graphics/daV)l(inci)554 +4733 y Ff(6)583 4764 y Fe(ftp://ftp.polito.it/pub/research/dddmp/)p +Black Black 1897 5225 a Fo(24)p Black eop end +%%Page: 25 25 +TeXDict begin 25 24 bop Black Black Black 721 4226 a +@beginspecial 66 @llx 36 @lly 547 @urx 757 @ury 4393 +@rhi @setspecial +%%BeginDocument: phase.ps +%!PS-Adobe-2.0 +%%Creator: dot version 95 (4-10-95) +%%For: (fabio) Fabio Somenzi,OT4-11,2-3466,ECE faculty +%%Title: DD +%%Pages: (atend) +%%BoundingBox: 66 36 547 757 +%%EndComments +%%BeginProlog +save +/DotDict 200 dict def +DotDict begin + +%%BeginResource: procset +/coord-font-family /Times-Roman def +/default-font-family /Times-Roman def +/coordfont coord-font-family findfont 8 scalefont def + +/InvScaleFactor 1.0 def +/set_scale { + dup 1 exch div /InvScaleFactor exch def + dup scale +} bind def + +% styles +/solid { } bind def +/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def +/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def +/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def +/bold { 2 setlinewidth } bind def +/filled { } bind def +/unfilled { } bind def +/rounded { } bind def +/diagonals { } bind def + +% hooks for setting color +/nodecolor { sethsbcolor } bind def +/edgecolor { sethsbcolor } bind def +/graphcolor { sethsbcolor } bind def +/nopcolor {pop pop pop} bind def + +/beginpage { % i j npages + /npages exch def + /j exch def + /i exch def + /str 10 string def + npages 1 gt { + gsave + coordfont setfont + 0 0 moveto + (() show i str cvs show (,) show j str cvs show ()) show + grestore + } if +} bind def + +/set_font { + findfont exch + scalefont setfont +} def + +/arrowhead { + /arrowwidth exch def + /arrowlength exch def + gsave + 3 1 roll + translate + rotate + newpath + arrowlength arrowwidth 2 div moveto + 0 0 lineto + arrowlength arrowwidth -2 div lineto + closepath fill + stroke + grestore +} def + +% draw aligned label in bounding box aligned to current point +% alignfactor tells what fraction to place on the left. +% -.5 is centered. +/alignedtext { % text labelwidth fontsz alignfactor + /alignfactor exch def + /fontsz exch def + /width exch def + /text exch def + gsave + % even if node or edge is dashed, don't paint text with dashes + [] 0 setdash + currentpoint newpath moveto + text stringwidth pop + alignfactor mul fontsz -.3 mul rmoveto + text show + grestore +} def + +/boxprim { % xcorner ycorner xsize ysize + 4 2 roll + moveto + 2 copy + exch 0 rlineto + 0 exch rlineto + pop neg 0 rlineto + closepath +} bind def + +/ellipse_path { + /ry exch def + /rx exch def + /y exch def + /x exch def + matrix currentmatrix + newpath + x y translate + rx ry scale + 0 0 1 0 360 arc + setmatrix +} bind def + +/endpage { showpage } bind def + +/layercolorseq + [ % layer color sequence - darkest to lightest + [0 0 0] + [.2 .8 .8] + [.4 .8 .8] + [.6 .8 .8] + [.8 .8 .8] + ] +def + +/setlayer {/maxlayer exch def /curlayer exch def + layercolorseq curlayer get + aload pop sethsbcolor + /nodecolor {nopcolor} def + /edgecolor {nopcolor} def + /graphcolor {nopcolor} def +} bind def + +/onlayer { curlayer ne {invis} if } def + +/onlayers { + /myupper exch def + /mylower exch def + curlayer mylower lt + curlayer myupper gt + or + {invis} if +} def + +/curlayer 0 def + +%%EndResource +%%EndProlog +%%BeginSetup +14 default-font-family set_font +% /arrowlength 10 def +% /arrowwidth 5 def +%%EndSetup +%%Page: 1 (atend) +%%PageBoundingBox: 66 36 547 757 +gsave +65 35 482 722 boxprim clip newpath +66 36 translate +0 0 1 beginpage +0.7407 set_scale +0 0 translate 0 rotate +0.000 0.000 0.000 graphcolor +14.00 /Times-Roman set_font + +% CONST NODES +gsave 10 dict begin +invis +gsave 10 dict begin +55 19 moveto (CONST NODES) 96 14.00 -0.50 alignedtext +end grestore +end grestore + +% a110 +gsave 10 dict begin +gsave 10 dict begin +55 883 moveto (a110) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a111 +gsave 10 dict begin +gsave 10 dict begin +55 811 moveto (a111) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a110 -> a111 +gsave 10 dict begin +invis +newpath 55 864 moveto +55 853 55 839 55 828 curveto +stroke +end grestore + +% a210 +gsave 10 dict begin +gsave 10 dict begin +55 739 moveto (a210) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a111 -> a210 +gsave 10 dict begin +invis +newpath 55 792 moveto +55 781 55 767 55 756 curveto +stroke +end grestore + +% a211 +gsave 10 dict begin +gsave 10 dict begin +55 667 moveto (a211) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a210 -> a211 +gsave 10 dict begin +invis +newpath 55 720 moveto +55 709 55 695 55 684 curveto +stroke +end grestore + +% a310 +gsave 10 dict begin +gsave 10 dict begin +55 595 moveto (a310) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a211 -> a310 +gsave 10 dict begin +invis +newpath 55 648 moveto +55 637 55 623 55 612 curveto +stroke +end grestore + +% a311 +gsave 10 dict begin +gsave 10 dict begin +55 523 moveto (a311) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a310 -> a311 +gsave 10 dict begin +invis +newpath 55 576 moveto +55 565 55 551 55 540 curveto +stroke +end grestore + +% a410 +gsave 10 dict begin +gsave 10 dict begin +55 451 moveto (a410) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a311 -> a410 +gsave 10 dict begin +invis +newpath 55 504 moveto +55 493 55 479 55 468 curveto +stroke +end grestore + +% a411 +gsave 10 dict begin +gsave 10 dict begin +55 379 moveto (a411) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a410 -> a411 +gsave 10 dict begin +invis +newpath 55 432 moveto +55 421 55 407 55 396 curveto +stroke +end grestore + +% a510 +gsave 10 dict begin +gsave 10 dict begin +55 307 moveto (a510) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a411 -> a510 +gsave 10 dict begin +invis +newpath 55 360 moveto +55 349 55 335 55 324 curveto +stroke +end grestore + +% a511 +gsave 10 dict begin +gsave 10 dict begin +55 235 moveto (a511) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a510 -> a511 +gsave 10 dict begin +invis +newpath 55 288 moveto +55 277 55 263 55 252 curveto +stroke +end grestore + +% a610 +gsave 10 dict begin +gsave 10 dict begin +55 163 moveto (a610) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a511 -> a610 +gsave 10 dict begin +invis +newpath 55 216 moveto +55 205 55 191 55 180 curveto +stroke +end grestore + +% a611 +gsave 10 dict begin +gsave 10 dict begin +55 91 moveto (a611) 27 14.00 -0.50 alignedtext +end grestore +end grestore + +% a610 -> a611 +gsave 10 dict begin +invis +newpath 55 144 moveto +55 133 55 119 55 108 curveto +stroke +end grestore + +% a611 -> CONST NODES +gsave 10 dict begin +invis +newpath 55 72 moveto +55 61 55 47 55 36 curveto +stroke +end grestore + +% o +gsave 10 dict begin +newpath 511 972 moveto +457 972 lineto +457 936 lineto +511 936 lineto +closepath +stroke +gsave 10 dict begin +484 955 moveto (o) 7 14.00 -0.50 alignedtext +end grestore +end grestore + +% a00 +gsave 10 dict begin +484 882 27 18 ellipse_path +stroke +gsave 10 dict begin +484 883 moveto (a00) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% o -> a00 +gsave 10 dict begin +solid +newpath 484 936 moveto +484 925 484 911 484 900 curveto +stroke +end grestore + +% 9fc +gsave 10 dict begin +448 810 27 18 ellipse_path +stroke +gsave 10 dict begin +448 811 moveto (9fc) 17 14.00 -0.50 alignedtext +end grestore +end grestore + +% a00 -> 9fc +newpath 475 865 moveto +470 853 462 839 457 827 curveto +stroke + +% 9ff +gsave 10 dict begin +520 810 27 18 ellipse_path +stroke +gsave 10 dict begin +520 811 moveto (9ff) 16 14.00 -0.50 alignedtext +end grestore +end grestore + +% a00 -> 9ff +gsave 10 dict begin +dashed +newpath 493 865 moveto +498 853 506 839 511 827 curveto +stroke +end grestore + +% 995 +gsave 10 dict begin +453 738 27 18 ellipse_path +stroke +gsave 10 dict begin +453 739 moveto (995) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fc -> 995 +gsave 10 dict begin +dashed +newpath 449 792 moveto +450 781 451 767 452 756 curveto +stroke +end grestore + +% 9fb +gsave 10 dict begin +381 738 27 18 ellipse_path +stroke +gsave 10 dict begin +381 739 moveto (9fb) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fc -> 9fb +newpath 433 794 moveto +422 782 407 765 396 753 curveto +stroke + +% 9fe +gsave 10 dict begin +584 738 27 18 ellipse_path +stroke +gsave 10 dict begin +584 739 moveto (9fe) 17 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ff -> 9fe +gsave 10 dict begin +dashed +newpath 534 794 moveto +545 782 560 765 570 753 curveto +stroke +end grestore + +% 95f +gsave 10 dict begin +512 666 27 18 ellipse_path +stroke +gsave 10 dict begin +512 667 moveto (95f) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ff -> 95f +newpath 519 792 moveto +518 764 515 712 513 684 curveto +stroke + +% 994 +gsave 10 dict begin +347 594 27 18 ellipse_path +stroke +gsave 10 dict begin +347 595 moveto (994) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 995 -> 994 +newpath 432 727 moveto +407 714 370 693 363 684 curveto +356 675 351 636 349 612 curveto +stroke + +% 946 +gsave 10 dict begin +newpath 401 36 moveto +347 36 lineto +347 0 lineto +401 0 lineto +closepath +stroke +gsave 10 dict begin +374 19 moveto (1) 7 14.00 -0.50 alignedtext +end grestore +end grestore + +% 995 -> 946 +gsave 10 dict begin +dotted +newpath 584 594 moveto +589 570 587 545 584 522 curveto +stroke +newpath 453 720 moveto +454 698 458 662 473 648 curveto +498 621 544 628 577 612 curveto +582 609 582 600 584 594 curveto +stroke +end grestore + +% 9f7 +gsave 10 dict begin +292 666 27 18 ellipse_path +stroke +gsave 10 dict begin +292 667 moveto (9f7) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fb -> 9f7 +newpath 363 724 moveto +347 711 325 693 309 680 curveto +stroke + +% 9fa +gsave 10 dict begin +402 666 27 18 ellipse_path +stroke +gsave 10 dict begin +402 667 moveto (9fa) 17 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fb -> 9fa +gsave 10 dict begin +dashed +newpath 386 720 moveto +389 709 393 695 397 684 curveto +stroke +end grestore + +% 9fd +gsave 10 dict begin +584 666 27 18 ellipse_path +stroke +gsave 10 dict begin +584 667 moveto (9fd) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fe -> 9fd +newpath 584 720 moveto +584 709 584 695 584 684 curveto +stroke + +% 9fe -> 946 +gsave 10 dict begin +dotted +newpath 600 723 moveto +611 711 625 696 632 684 curveto +637 673 637 658 632 648 curveto +632 648 584 594 584 594 curveto +stroke +end grestore + +% 9f7 -> 994 +gsave 10 dict begin +dashed +newpath 304 650 moveto +313 638 326 622 335 610 curveto +stroke +end grestore + +% 9f6 +gsave 10 dict begin +275 594 27 18 ellipse_path +stroke +gsave 10 dict begin +275 595 moveto (9f6) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f7 -> 9f6 +newpath 288 648 moveto +285 637 282 623 279 612 curveto +stroke + +% 9f9 +gsave 10 dict begin +529 594 27 18 ellipse_path +stroke +gsave 10 dict begin +529 595 moveto (9f9) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fa -> 9f9 +gsave 10 dict begin +dashed +newpath 423 654 moveto +447 641 485 619 508 606 curveto +stroke +end grestore + +% 95e +gsave 10 dict begin +457 522 27 18 ellipse_path +stroke +gsave 10 dict begin +457 523 moveto (95e) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9fa -> 95e +newpath 465 594 moveto +464 579 462 556 460 540 curveto +stroke +newpath 420 652 moveto +439 638 464 614 465 594 curveto +stroke + +% 95f -> 95e +newpath 497 651 moveto +483 636 464 612 465 594 curveto +stroke + +% 95f -> 946 +gsave 10 dict begin +dotted +newpath 531 653 moveto +551 639 579 615 584 594 curveto +stroke +end grestore + +% 9fd -> 9f9 +newpath 572 650 moveto +563 638 550 622 541 610 curveto +stroke + +% 9fd -> 946 +gsave 10 dict begin +dotted +newpath 582 648 moveto +581 631 580 608 584 594 curveto +stroke +end grestore + +% 993 +gsave 10 dict begin +292 450 27 18 ellipse_path +stroke +gsave 10 dict begin +292 451 moveto (993) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 994 -> 993 +newpath 333 578 moveto +323 566 312 551 308 540 curveto +301 521 296 489 294 468 curveto +stroke + +% 994 -> 946 +gsave 10 dict begin +dotted +newpath 357 577 moveto +371 556 396 519 418 504 curveto +447 482 489 484 522 468 curveto +527 465 527 456 529 450 curveto +stroke +newpath 529 450 moveto +534 426 532 401 529 378 curveto +stroke +end grestore + +% 9f5 +gsave 10 dict begin +347 522 27 18 ellipse_path +stroke +gsave 10 dict begin +347 523 moveto (9f5) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f6 -> 9f5 +gsave 10 dict begin +dashed +newpath 290 579 moveto +302 567 319 550 332 537 curveto +stroke +end grestore + +% 9f2 +gsave 10 dict begin +237 522 27 18 ellipse_path +stroke +gsave 10 dict begin +237 523 moveto (9f2) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f6 -> 9f2 +newpath 266 577 moveto +260 566 252 551 246 539 curveto +stroke + +% 9f8 +gsave 10 dict begin +529 522 27 18 ellipse_path +stroke +gsave 10 dict begin +529 523 moveto (9f8) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f9 -> 9f8 +newpath 529 576 moveto +529 565 529 551 529 540 curveto +stroke + +% 9f9 -> 946 +gsave 10 dict begin +dotted +newpath 546 580 moveto +563 565 587 541 584 522 curveto +stroke +newpath 584 522 moveto +579 492 522 479 529 450 curveto +stroke +end grestore + +% 9f4 +gsave 10 dict begin +474 450 27 18 ellipse_path +stroke +gsave 10 dict begin +474 451 moveto (9f4) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f5 -> 9f4 +gsave 10 dict begin +dashed +newpath 368 510 moveto +392 497 430 475 453 462 curveto +stroke +end grestore + +% 95d +gsave 10 dict begin +402 378 27 18 ellipse_path +stroke +gsave 10 dict begin +402 379 moveto (95d) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f5 -> 95d +newpath 365 508 moveto +384 494 409 470 410 450 curveto +stroke +newpath 410 450 moveto +409 435 407 412 405 396 curveto +stroke + +% 9f2 -> 993 +gsave 10 dict begin +dashed +newpath 249 506 moveto +258 494 271 478 280 466 curveto +stroke +end grestore + +% 9f1 +gsave 10 dict begin +220 450 27 18 ellipse_path +stroke +gsave 10 dict begin +220 451 moveto (9f1) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f2 -> 9f1 +newpath 233 504 moveto +230 493 227 479 224 468 curveto +stroke + +% 95e -> 95d +newpath 442 507 moveto +428 492 409 468 410 450 curveto +stroke + +% 95e -> 946 +gsave 10 dict begin +dotted +newpath 476 509 moveto +496 495 524 471 529 450 curveto +stroke +end grestore + +% 9f8 -> 9f4 +newpath 517 506 moveto +508 494 495 478 486 466 curveto +stroke + +% 9f8 -> 946 +gsave 10 dict begin +dotted +newpath 527 504 moveto +526 487 525 464 529 450 curveto +stroke +end grestore + +% 992 +gsave 10 dict begin +237 306 27 18 ellipse_path +stroke +gsave 10 dict begin +237 307 moveto (992) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 993 -> 992 +newpath 278 434 moveto +268 422 257 407 253 396 curveto +246 377 241 345 239 324 curveto +stroke + +% 993 -> 946 +gsave 10 dict begin +dotted +newpath 474 306 moveto +474 306 474 234 474 234 curveto +stroke +newpath 302 433 moveto +316 412 341 375 363 360 curveto +392 338 434 340 467 324 curveto +472 321 472 312 474 306 curveto +stroke +end grestore + +% 9ed +gsave 10 dict begin +182 378 27 18 ellipse_path +stroke +gsave 10 dict begin +182 379 moveto (9ed) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f1 -> 9ed +newpath 211 433 moveto +205 422 197 407 191 395 curveto +stroke + +% 9f0 +gsave 10 dict begin +292 378 27 18 ellipse_path +stroke +gsave 10 dict begin +292 379 moveto (9f0) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f1 -> 9f0 +gsave 10 dict begin +dashed +newpath 235 435 moveto +247 423 264 406 277 393 curveto +stroke +end grestore + +% 9f3 +gsave 10 dict begin +474 378 27 18 ellipse_path +stroke +gsave 10 dict begin +474 379 moveto (9f3) 18 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f4 -> 9f3 +newpath 474 432 moveto +474 421 474 407 474 396 curveto +stroke + +% 9f4 -> 946 +gsave 10 dict begin +dotted +newpath 491 436 moveto +508 421 532 397 529 378 curveto +stroke +newpath 529 378 moveto +528 371 525 365 522 360 curveto +522 360 474 306 474 306 curveto +stroke +end grestore + +% 9ed -> 992 +gsave 10 dict begin +dashed +newpath 194 362 moveto +203 350 216 334 225 322 curveto +stroke +end grestore + +% 9ec +gsave 10 dict begin +165 306 27 18 ellipse_path +stroke +gsave 10 dict begin +165 307 moveto (9ec) 19 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ed -> 9ec +newpath 178 360 moveto +175 349 172 335 169 324 curveto +stroke + +% 9ef +gsave 10 dict begin +419 306 27 18 ellipse_path +stroke +gsave 10 dict begin +419 307 moveto (9ef) 17 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f0 -> 9ef +gsave 10 dict begin +dashed +newpath 313 366 moveto +337 353 375 331 398 318 curveto +stroke +end grestore + +% 95c +gsave 10 dict begin +347 234 27 18 ellipse_path +stroke +gsave 10 dict begin +347 235 moveto (95c) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9f0 -> 95c +newpath 310 364 moveto +329 350 354 326 355 306 curveto +stroke +newpath 355 306 moveto +354 291 352 268 350 252 curveto +stroke + +% 95d -> 95c +newpath 387 363 moveto +373 348 354 324 355 306 curveto +stroke + +% 95d -> 946 +gsave 10 dict begin +dotted +newpath 421 365 moveto +441 351 469 327 474 306 curveto +stroke +end grestore + +% 9f3 -> 9ef +newpath 462 362 moveto +453 350 440 334 431 322 curveto +stroke + +% 9f3 -> 946 +gsave 10 dict begin +dotted +newpath 472 360 moveto +471 343 470 320 474 306 curveto +stroke +end grestore + +% 954 +gsave 10 dict begin +165 162 27 18 ellipse_path +stroke +gsave 10 dict begin +165 163 moveto (954) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 992 -> 954 +newpath 220 234 moveto +214 216 194 192 180 177 curveto +stroke +newpath 233 288 moveto +230 272 224 248 220 234 curveto +stroke + +% 992 -> 946 +gsave 10 dict begin +dotted +newpath 220 234 moveto +220 234 213 144 213 144 curveto +213 144 193 90 193 90 curveto +stroke +end grestore + +% 987 +gsave 10 dict begin +165 234 27 18 ellipse_path +stroke +gsave 10 dict begin +165 235 moveto (987) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ec -> 987 +newpath 165 288 moveto +165 277 165 263 165 252 curveto +stroke + +% 9eb +gsave 10 dict begin +275 234 27 18 ellipse_path +stroke +gsave 10 dict begin +275 235 moveto (9eb) 20 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ec -> 9eb +gsave 10 dict begin +dashed +newpath 184 293 moveto +204 280 236 260 256 247 curveto +stroke +end grestore + +% 9ee +gsave 10 dict begin +419 234 27 18 ellipse_path +stroke +gsave 10 dict begin +419 235 moveto (9ee) 19 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9ef -> 9ee +newpath 419 288 moveto +419 277 419 263 419 252 curveto +stroke + +% 9ef -> 946 +gsave 10 dict begin +dotted +newpath 474 234 moveto +477 210 461 184 469 162 curveto +stroke +newpath 435 291 moveto +450 276 471 252 474 234 curveto +stroke +end grestore + +% 987 -> 954 +gsave 10 dict begin +dashed +newpath 165 216 moveto +165 205 165 191 165 180 curveto +stroke +end grestore + +% 987 -> 946 +newpath 193 90 moveto +225 56 305 34 347 24 curveto +stroke +newpath 152 218 moveto +136 197 113 162 126 144 curveto +144 120 173 110 193 90 curveto +stroke + +% 9ea +gsave 10 dict begin +410 162 27 18 ellipse_path +stroke +gsave 10 dict begin +410 163 moveto (9ea) 19 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9eb -> 9ea +gsave 10 dict begin +dashed +newpath 296 223 moveto +321 210 363 187 389 174 curveto +stroke +end grestore + +% 955 +gsave 10 dict begin +374 90 27 18 ellipse_path +stroke +gsave 10 dict begin +374 91 moveto (955) 21 14.00 -0.50 alignedtext +end grestore +end grestore + +% 9eb -> 955 +newpath 293 220 moveto +311 206 338 182 347 162 curveto +stroke +newpath 347 162 moveto +353 147 362 124 368 108 curveto +stroke + +% 95c -> 955 +newpath 344 216 moveto +342 199 341 175 347 162 curveto +stroke + +% 95c -> 946 +gsave 10 dict begin +dotted +newpath 368 222 moveto +372 220 376 217 380 216 curveto +407 203 436 195 462 180 curveto +467 176 466 168 469 162 curveto +stroke +newpath 469 162 moveto +476 139 475 113 469 90 curveto +stroke +end grestore + +% 9ee -> 9ea +newpath 417 216 moveto +415 205 414 191 412 180 curveto +stroke + +% 9ee -> 946 +gsave 10 dict begin +dotted +newpath 432 218 moveto +442 206 454 190 462 180 curveto +465 174 466 168 469 162 curveto +stroke +end grestore + +% 954 -> 946 +newpath 169 144 moveto +174 127 182 101 193 90 curveto +stroke + +% 954 -> 946 +gsave 10 dict begin +dotted +end grestore + +% 9ea -> 955 +newpath 401 145 moveto +396 133 388 119 383 107 curveto +stroke + +% 9ea -> 946 +gsave 10 dict begin +dotted +newpath 429 149 moveto +448 133 474 109 469 90 curveto +stroke +newpath 469 90 moveto +462 66 427 44 401 30 curveto +stroke +end grestore + +% 955 -> 946 +newpath 374 72 moveto +374 61 374 47 374 36 curveto +stroke + +% 955 -> 946 +gsave 10 dict begin +dotted +end grestore +endpage +grestore +%%PageTrailer +%%Trailer +%%Pages: 1 +end +restore +%%EOF + +%%EndDocument + @endspecial 448 4422 a Fo(Figure)34 b(1:)49 b(A)32 b(BDD)f +(representing)37 b(a)c(phase)h(constraint)i(for)e(the)f(optimization)j +(of)d(\002x)o(ed-)448 4535 y(polarity)27 b(Reed-Muller)g(forms.)33 +b(The)24 b(label)i(of)f(each)h(node)f(is)g(the)g(unique)i(part)e(of)g +(the)g(node)448 4648 y(address.)31 b(All)21 b(nodes)j(on)f(the)g(same)f +(le)n(v)o(el)h(correspond)i(to)e(the)g(same)f(v)n(ariable,)i(whose)f +(name)448 4761 y(is)f(sho)n(wn)h(at)f(the)g(left)g(of)g(the)h(diagram.) +29 b(Dotted)23 b(lines)g(indicate)h(complement)g(arcs.)k(Dashed)448 +4874 y(lines)d(indicate)g(re)o(gular)g(\223else\224)g(arcs.)p +Black Black 1897 5225 a(25)p Black eop end +%%Page: 26 26 +TeXDict begin 26 25 bop Black Black 448 573 a Fo(to)24 +b(your)h(source)h(\002les.)k(In)24 b(addition,)i(you)f(should)h(link)e +Fh(libcudd.a)19 b Fo(to)24 b(your)h(e)o(x)o(ecutable.)448 +686 y(Some)20 b(platforms)h(require)h(speci\002c)e(compiler)i(and)e +(link)o(er)h(\003ags.)28 b(Refer)20 b(to)g(the)g Fh(Makefile)448 +799 y Fo(in)k(the)g(top)f(le)n(v)o(el)h(directory)i(of)e(the)f(distrib) +n(ution.)448 1040 y Fi(4.2)99 b(Refer)n(ence)27 b(Counts)448 +1214 y Fo(Garbage)d(collection)i(in)d(the)g(CUDD)d(package)25 +b(is)e(based)h(on)f(reference)i(counts.)30 b(Each)22 +b(node)448 1327 y(stores)j(the)f(sum)f(of)g(the)h(e)o(xternal)h +(references)h(and)e(internal)h(references.)31 b(An)23 +b(internal)i(BDD)448 1440 y(or)33 b(ADD)e(node)i(is)g(created)h(by)f(a) +g(call)g(to)f Fn(cuddUniqueInter)r Fo(,)40 b(an)32 b(internal)j(ZDD)c +(node)i(is)448 1553 y(created)c(by)e(a)g(call)g(to)g +Fn(cuddUniqueInterZdd)r Fo(,)33 b(and)28 b(a)e(terminal)j(node)e(is)g +(created)i(by)e(a)g(call)448 1666 y(to)g Fn(cuddUniqueConst)r +Fo(.)40 b(If)27 b(the)f(node)i(returned)g(by)f(these)g(functions)i(is)d +(ne)n(w)-6 b(,)27 b(its)f(reference)448 1779 y(count)32 +b(is)e(zero.)51 b(The)30 b(function)i(that)g(calls)f +Fn(cuddUniqueInter)r Fo(,)36 b Fn(cuddUniqueInterZdd)r +Fo(,)h(or)448 1892 y Fn(cuddUniqueConst)j Fo(is)35 b(responsible)j(for) +d(increasing)i(the)e(reference)i(count)f(of)f(the)g(node.)448 +2005 y(This)24 b(is)f(accomplished)k(by)c(calling)i Fn(Cudd)p +1823 2005 28 4 v 34 w(Ref)13 b Fo(.)589 2118 y(When)22 +b(a)f(function)i(is)e(no)g(longer)i(needed)f(by)g(an)f(application,)j +(the)e(memory)f(used)h(by)f(its)448 2231 y(diagram)32 +b(can)g(be)f(rec)o(ycled)i(by)e(calling)i Fn(Cudd)p 1986 +2231 V 33 w(Recur)o(siveDer)m(ef)47 b Fo(\(BDDs)30 b(and)i(ADDs\))d(or) +448 2344 y Fn(Cudd)p 649 2344 V 34 w(Recur)o(siveDer)m(efZdd)36 +b Fo(\(ZDDs\).)49 b(These)31 b(functions)i(decrease)g(the)e(reference)i +(count)448 2456 y(of)h(the)h(node)g(passed)g(to)f(them.)61 +b(If)34 b(the)g(reference)i(count)g(becomes)f(0,)h(then)f(tw)o(o)f +(things)448 2569 y(happen:)p Black 562 2718 a(1.)p Black +46 w(The)23 b(node)i(is)f(declared)i(\223dead;\224)g(this)e(entails)h +(increasing)i(the)d(counters)i(of)e(the)g(dead)676 2831 +y(nodes.)56 b(\(One)32 b(counter)i(for)f(the)f(subtable)j(to)d(which)h +(the)g(node)g(belongs,)j(and)d(one)676 2944 y(global)f(counter)h(for)f +(the)f(unique)i(table)f(to)f(which)h(the)f(node)i(belongs.\))54 +b(The)30 b(node)676 3057 y(itself)24 b(is)f(not)h(af)n(fected.)p +Black 562 3229 a(2.)p Black 46 w(The)f(function)i(is)f(recursi)n(v)o +(ely)i(called)f(on)e(the)h(tw)o(o)f(children)j(of)d(the)h(node.)448 +3378 y(F)o(or)35 b(instance,)41 b(if)36 b(the)g(diagram)h(of)f(a)f +(function)j(does)f(not)f(share)h(an)o(y)f(nodes)i(with)d(other)448 +3491 y(diagrams,)k(then)c(calling)h Fn(Cudd)p 1513 3491 +V 33 w(Recur)o(siveDer)m(ef)50 b Fo(or)34 b Fn(Cudd)p +2459 3491 V 34 w(Recur)o(siveDer)m(efZdd)40 b Fo(on)34 +b(its)448 3603 y(root)24 b(will)g(cause)g(all)g(the)g(nodes)h(of)e(the) +h(diagram)g(to)g(become)g(dead.)589 3716 y(When)d(the)f(number)g(of)g +(dead)h(nodes)g(reaches)g(a)f(gi)n(v)o(en)g(le)n(v)o(el)g +(\(dynamically)j(determined)448 3829 y(by)33 b(the)f(package\))j +(garbage)e(collection)i(tak)o(es)f(place.)56 b(During)33 +b(garbage)g(collection)i(dead)448 3942 y(nodes)25 b(are)f(returned)h +(to)f(the)g(node)g(free)g(list.)589 4055 y(When)37 b(a)e(ne)n(w)g(node) +i(is)f(created,)k(it)c(is)g(important)h(to)f(increase)i(its)e +(reference)i(count)448 4168 y(before)25 b(one)f(of)g(the)f(tw)o(o)h +(follo)n(wing)h(e)n(v)o(ents)f(occurs:)p Black 562 4317 +a(1.)p Black 46 w(A)19 b(call)j(to)e Fn(cuddUniqueInter)r +Fo(,)26 b(to)21 b Fn(cuddUniqueInterZdd)r Fo(,)26 b(to)21 +b Fn(cuddUniqueConst)r Fo(,)j(or)676 4430 y(to)f(a)g(function)j(that)e +(may)f(e)n(v)o(entually)j(cause)f(a)e(call)h(to)f(them.)p +Black 562 4602 a(2.)p Black 46 w(A)28 b(call)i(to)f Fn(Cudd)p +1230 4602 V 34 w(Recur)o(siveDer)m(ef)13 b Fo(,)33 b(to)c +Fn(Cudd)p 2186 4602 V 34 w(Recur)o(siveDer)m(efZdd)r +Fo(,)34 b(or)29 b(to)g(a)g(func-)676 4715 y(tion)24 b(that)g(may)f(e)n +(v)o(entually)j(cause)f(a)e(call)h(to)f(them.)448 4863 +y(In)31 b(practice,)j(it)d(is)f(recommended)j(to)e(increase)i(the)e +(reference)i(count)f(as)f(soon)g(as)g(the)g(re-)448 4976 +y(turned)25 b(pointer)h(has)d(been)i(tested)g(for)e(not)h(being)h +(NULL.)p Black 1897 5225 a(26)p Black eop end +%%Page: 27 27 +TeXDict begin 27 26 bop Black Black 448 573 a Fp(4.2.1)92 +b(NULL)21 b(Retur)o(n)h(V)-8 b(alues)448 747 y Fo(The)25 +b(interf)o(ace)i(to)e(the)g(memory)g(management)i(functions)g(\(e.g.,)e +(malloc\))h(used)g(by)f(CUDD)448 860 y(intercepts)k(NULL)c(return)i(v)n +(alues)h(and)f(calls)g(a)f(handler)-5 b(.)40 b(The)26 +b(def)o(ault)i(handler)g(e)o(xits)f(with)448 973 y(an)i(error)h +(message.)47 b(If)29 b(the)g(application)k(does)d(not)f(install)i +(another)g(handler)l(,)h(therefore,)h(a)448 1086 y(NULL)21 +b(return)k(v)n(alue)g(from)e(an)h(e)o(xported)h(function)h(of)d(CUDD)e +(signals)26 b(an)d(internal)j(error)-5 b(.)589 1199 y(If)23 +b(the)f(aplication,)j(ho)n(we)n(v)o(er)l(,)e(installs)i(another)f +(handler)g(that)f(lets)g(e)o(x)o(ecution)h(continue,)448 +1312 y(a)i(NULL)f(pointer)j(returned)g(by)f(an)g(e)o(xported)h +(function)h(typically)g(indicates)g(that)e(the)g(pro-)448 +1425 y(cess)32 b(has)g(run)g(out)g(of)f(memory)-6 b(.)53 +b Fn(Cudd)p 1760 1425 28 4 v 33 w(ReadErr)l(orCode)34 +b Fo(can)d(be)h(used)g(to)f(ascertain)j(the)448 1537 +y(nature)25 b(of)f(the)f(problem.)589 1650 y(An)37 b(application)j +(that)d(tests)h(for)f(the)h(result)g(being)g(NULL)c(can)k(try)f(some)g +(remedial)448 1763 y(action,)25 b(if)e(it)g(runs)h(out)g(of)g(memory)-6 +b(.)28 b(F)o(or)23 b(instance,)i(it)e(may)h(free)g(some)f(memory)h +(that)g(is)f(not)448 1876 y(strictly)29 b(necessary)-6 +b(,)31 b(or)c(try)g(a)g(slo)n(wer)g(algorithm)i(that)f(tak)o(es)g(less) +g(space.)40 b(As)27 b(an)g(e)o(xample,)448 1989 y(CUDD)e(o)o(v)o +(errides)k(the)f(def)o(ault)h(handler)g(when)f(trying)g(to)g(enlar)n +(ge)h(the)f(cache)g(or)f(increase)448 2102 y(the)i(number)g(of)f(slots) +h(of)f(the)h(unique)h(table.)43 b(If)28 b(the)h(allocation)h(f)o(ails,) +g(the)f(package)h(prints)448 2215 y(out)24 b(a)f(message)i(and)f +(continues)i(without)f(resizing)g(the)f(cache.)448 2461 +y Fp(4.2.2)92 b Fa(Cudd)p 928 2461 V 33 w(Recursiv)o(eDeref)35 +b Fp(vs.)23 b Fa(Cudd)p 1901 2461 V 33 w(Deref)448 2635 +y Fo(It)36 b(is)f(often)i(the)f(case)g(that)h(a)e(recursi)n(v)o(e)i +(procedure)i(has)d(to)g(protect)h(the)f(result)h(it)e(is)h(go-)448 +2748 y(ing)j(to)g(return,)k(while)c(it)f(disposes)j(of)d(intermediate)j +(results.)75 b(\(See)38 b(the)h(pre)n(vious)i(dis-)448 +2861 y(cussion)i(on)d(when)h(to)f(increase)j(reference)g(counts.\))81 +b(Once)41 b(the)g(intermediate)i(results)448 2974 y(ha)n(v)o(e)37 +b(been)f(properly)i(disposed)f(of,)i(the)c(\002nal)h(result)h(must)e +(be)h(returned)h(to)f(its)f(pristine)448 3087 y(state,)h(in)d(which)g +(the)g(root)h(node)g(may)e(ha)n(v)o(e)i(a)e(reference)k(count)e(of)e +(0.)57 b(One)32 b(cannot)j(use)448 3200 y Fn(Cudd)p 649 +3200 V 34 w(Recur)o(siveDer)m(ef)49 b Fo(\(or)33 b Fn(Cudd)p +1624 3200 V 34 w(Recur)o(siveDer)m(efZdd)r Fo(\))j(for)d(this)h +(purpose,)j(because)e(it)448 3313 y(may)22 b(erroneously)j(mak)o(e)d +(some)g(nodes)h(dead.)29 b(Therefore,)24 b(the)e(package)i(pro)o(vides) +g(a)d(dif)n(fer)n(-)448 3425 y(ent)k(function:)35 b Fn(Cudd)p +1144 3425 V 33 w(Der)m(ef)13 b Fo(.)33 b(This)25 b(function)i(is)d(not) +i(recursi)n(v)o(e,)g(and)g(does)f(not)h(change)g(the)448 +3538 y(dead)g(node)f(counts.)34 b(Its)25 b(use)g(is)f(almost)h(e)o +(xclusi)n(v)o(ely)i(the)e(one)g(just)g(described:)34 +b(Decreasing)448 3651 y(the)26 b(reference)h(count)g(of)e(the)g(root)h +(of)f(the)h(\002nal)f(result)h(before)h(returning)h(from)d(a)g(recursi) +n(v)o(e)448 3764 y(procedure.)448 4010 y Fp(4.2.3)92 +b(When)22 b(Incr)n(easing)j(the)e(Refer)n(ence)i(Count)d(is)h +(Unnecessary)448 4184 y Fo(When)29 b(a)f(cop)o(y)h(of)f(a)g +(prede\002ned)i(constant)h(or)d(of)g(a)g(simple)h(BDD)d(v)n(ariable)k +(is)e(needed)i(for)448 4297 y(comparison)g(purposes,)g(then)f(calling)g +Fn(Cudd)p 1931 4297 V 33 w(Ref)40 b Fo(is)27 b(not)h(necessary)-6 +b(,)31 b(because)e(these)f(sim-)448 4410 y(ple)j(functions)i(are)d +(guaranteed)k(to)c(ha)n(v)o(e)h(reference)i(counts)f(greater)g(than)f +(0)f(at)g(all)g(times.)448 4523 y(If)35 b(no)g(call)g(to)f +Fn(Cudd)p 1138 4523 V 34 w(Ref)47 b Fo(is)35 b(made,)i(then)f(no)f +(attempt)g(to)g(free)g(the)g(diagram)h(by)f(calling)448 +4636 y Fn(Cudd)p 649 4636 V 34 w(Recur)o(siveDer)m(ef)k +Fo(or)24 b Fn(Cudd)p 1575 4636 V 33 w(Recur)o(siveDer)m(efZdd)29 +b Fo(should)c(be)f(made.)p Black 1897 5225 a(27)p Black +eop end +%%Page: 28 28 +TeXDict begin 28 27 bop Black Black 448 573 a Fp(4.2.4)92 +b(Saturating)24 b(Incr)n(ements)g(and)f(Decr)n(ements)448 +747 y Fo(On)30 b(32-bit)i(machines,)i(the)d(CUDD)d(package)33 +b(stores)f(the)f(reference)i(counts)f(in)f(unsigned)448 +860 y(short)38 b(int')-5 b(s.)68 b(F)o(or)36 b(lar)n(ge)i(diagrams,)j +(it)36 b(is)g(possible)j(for)e(some)f(reference)j(counts)f(to)e(e)o(x-) +448 973 y(ceed)27 b(the)g(capacity)h(of)f(an)f(unsigned)j(short)e(int.) +38 b(Therefore,)28 b(increments)g(and)f(decrements)448 +1086 y(of)34 b(reference)j(counts)f(are)e Fn(satur)o(ating)p +Fo(.)64 b(This)34 b(means)g(that)h(once)g(a)f(reference)j(count)e(has) +448 1199 y(reached)24 b(the)e(maximum)f(possible)j(v)n(alue,)f(it)e(is) +h(no)g(longer)h(changed)h(by)d(calls)i(to)e Fn(Cudd)p +3264 1199 28 4 v 34 w(Ref)p Fo(,)448 1312 y Fn(Cudd)p +649 1312 V 34 w(Recur)o(siveDer)m(ef)13 b Fo(,)46 b Fn(Cudd)p +1519 1312 V 34 w(Recur)o(siveDer)m(efZdd)r Fo(,)h(or)40 +b Fn(Cudd)p 2635 1312 V 34 w(Der)m(ef)13 b Fo(.)77 b(As)39 +b(a)h(conse-)448 1425 y(quence,)30 b(some)d(nodes)i(that)e(ha)n(v)o(e)h +(no)f(references)j(may)d(not)h(be)f(declared)i(dead.)41 +b(This)27 b(may)448 1537 y(result)j(in)e(a)g(small)h(w)o(aste)f(of)h +(memory)-6 b(,)29 b(which)g(is)f(normally)i(more)f(than)g(of)n(fset)g +(by)g(the)f(re-)448 1650 y(duction)e(in)d(size)h(of)g(the)g(node)g +(structure.)589 1763 y(When)j(using)h(64-bit)f(pointers,)i(there)f(is)e +(normally)i(no)e(memory)h(adv)n(antage)i(from)d(us-)448 +1876 y(ing)e(short)h(int')-5 b(s)24 b(instead)h(of)e(int')-5 +b(s)25 b(in)e(a)g(DdNode.)29 b(Therefore,)c(increments)g(and)f +(decrements)448 1989 y(are)31 b(not)h(saturating)h(in)e(that)h(case.)51 +b(What)31 b(option)i(is)e(in)f(ef)n(fect)i(depends)h(on)e(tw)o(o)g +(macros,)448 2102 y(SIZEOF)p 763 2102 V 31 w(V)l(OID)p +1018 2102 V 32 w(P)f(and)h(SIZEOF)p 1602 2102 V 30 w(INT,)e(de\002ned)j +(in)e(the)h(e)o(xternal)h(header)g(\002le)e(\()p Fn(cudd.h)p +Fo(\).)448 2215 y(The)g(increments)i(and)e(decrements)i(of)e(the)g +(reference)i(counts)f(are)f(performed)i(using)f(tw)o(o)448 +2328 y(macros:)d Fn(cuddSatInc)21 b Fo(and)d Fn(cuddSatDec)p +Fo(,)k(whose)c(de\002nitions)i(depend)g(on)e(SIZEOF)p +3170 2328 V 31 w(V)l(OID)p 3425 2328 V 33 w(P)448 2441 +y(and)24 b(SIZEOF)p 917 2441 V 31 w(INT.)448 2690 y Fi(4.3)99 +b(Complement)26 b(Ar)n(cs)448 2864 y Fo(If)j(ADDs)f(are)h(restricted)j +(to)d(use)g(only)h(the)g(constants)i(0)c(and)i(1,)g(the)o(y)f(beha)n(v) +o(e)i(lik)o(e)f(BDDs)448 2977 y(without)d(complement)h(arcs.)36 +b(It)25 b(is)h(normally)h(easier)g(to)f(write)g(code)g(that)h +(manipulates)h(0-1)448 3090 y(ADDs,)33 b(than)h(to)e(write)h(code)g +(for)g(BDDs.)54 b(Ho)n(we)n(v)o(er)l(,)34 b(complementation)i(is)d(tri) +n(vial)g(with)448 3203 y(complement)c(arcs,)g(and)f(is)f(not)h(tri)n +(vial)g(without.)41 b(As)27 b(a)g(consequence,)k(with)d(complement)448 +3316 y(arcs)h(it)g(is)f(possible)j(to)d(check)i(for)f(more)f(terminal)i +(cases)g(and)f(it)f(is)g(possible)j(to)d(apply)i(De)448 +3429 y(Mor)n(gan')-5 b(s)25 b(la)o(ws)d(to)g(reduce)j(problems)f(that)f +(are)g(essentially)j(identical)f(to)d(a)h(standard)i(form.)448 +3542 y(This)f(in)f(turn)h(increases)i(the)e(utilization)i(of)e(the)g +(cache.)589 3655 y(The)38 b(complement)h(attrib)n(ute)h(is)d(stored)i +(in)e(the)h(least)h(signi\002cant)g(bit)f(of)f(the)h(\223else\224)448 +3768 y(pointer)25 b(of)f(each)g(node.)29 b(An)23 b(e)o(xternal)i +(pointer)g(to)e(a)g(function)j(can)e(also)g(be)f(complemented.)448 +3880 y(The)d(\223then\224)j(pointer)f(to)e(a)h(node,)g(on)g(the)g +(other)g(hand,)h(is)f(al)o(w)o(ays)g Fn(r)m(e)l(gular)p +Fo(.)30 b(It)20 b(is)h(a)f(mistak)o(e)h(to)448 3993 y(use)f(a)f +(complement)i(pointer)g(as)f(it)f(is)g(to)g(address)j(memory)-6 +b(.)27 b(Instead,)22 b(it)d(is)g(al)o(w)o(ays)i(necessary)448 +4106 y(to)28 b(obtain)i(a)e(re)o(gular)h(v)o(ersion)h(of)e(it.)42 +b(This)28 b(is)g(normally)h(done)g(by)g(calling)g Fn(Cudd)p +3094 4106 V 34 w(Re)l(gular)r Fo(.)448 4219 y(It)f(is)f(also)h(a)f +(mistak)o(e)i(to)e(call)h Fn(cuddUniqueInter)34 b Fo(with)27 +b(a)g(complemented)j(\223then\224)f(child)f(as)448 4332 +y(ar)n(gument.)i(The)22 b(calling)i(procedure)h(must)d(apply)h(De)e +(Mor)n(gan')-5 b(s)24 b(la)o(ws)d(by)h(complementing)448 +4445 y(both)32 b(pointers)i(passed)f(to)e Fn(cuddUniqueInter)38 +b Fo(and)31 b(then)h(taking)h(the)f(complement)h(of)e(the)448 +4558 y(result.)p Black 1897 5225 a(28)p Black eop end +%%Page: 29 29 +TeXDict begin 29 28 bop Black Black 448 573 a Fi(4.4)99 +b(The)26 b(Cache)448 747 y Fo(Each)38 b(entry)g(of)g(the)f(cache)i +(consists)g(of)f(\002)n(v)o(e)e(\002elds:)57 b(The)37 +b(operator)l(,)43 b(three)c(pointers)g(to)448 860 y(operands)d(and)e(a) +f(pointer)i(to)e(the)h(result.)60 b(The)33 b(operator)i(and)f(the)g +(three)g(pointers)i(to)d(the)448 973 y(operands)26 b(are)e(combined)h +(to)f(form)f(three)i(w)o(ords.)k(The)23 b(combination)j(relies)f(on)e +(tw)o(o)h(f)o(acts:)p Black 585 1155 a Fm(\017)p Black +46 w Fo(Most)i(operations)k(ha)n(v)o(e)d(one)h(or)e(tw)o(o)h(operands.) +40 b(A)26 b(fe)n(w)g(bits)h(are)g(suf)n(\002cient)h(to)f(dis-)676 +1268 y(criminate)e(all)e(three-operands)28 b(operations.)p +Black 585 1454 a Fm(\017)p Black 46 w Fo(All)h(nodes)h(are)g(aligned)h +(to)f(16-byte)h(boundaries.)50 b(\(32-byte)32 b(boundaries)h(if)c +(64-bit)676 1567 y(pointers)j(are)f(used.\))51 b(Hence,)33 +b(there)e(are)g(a)g(fe)n(w)e(bits)j(a)n(v)n(ailable)h(to)d(distinguish) +k(the)676 1679 y(three-operand)27 b(operations)g(from)c(te)g(others)i +(and)f(to)g(assign)h(unique)g(codes)g(to)e(them.)589 +1862 y(The)30 b(cache)h(does)f(not)g(contrib)n(ute)j(to)d(the)g +(reference)i(counts)f(of)f(the)g(nodes.)48 b(The)30 b(f)o(act)448 +1975 y(that)h(the)g(cache)g(contains)h(a)e(pointer)i(to)e(a)g(node)h +(does)g(not)f(imply)h(that)g(the)f(node)h(is)f(ali)n(v)o(e.)448 +2088 y(Instead,)k(when)d(garbage)h(collection)h(tak)o(es)e(place,)i +(all)e(entries)h(of)e(the)h(cache)h(pointing)g(to)448 +2201 y(dead)25 b(nodes)f(are)g(cleared.)589 2313 y(The)f(cache)i(is)e +(also)h(cleared)h(\(of)f(all)f(entries\))j(when)d(dynamic)i(reordering) +h(tak)o(es)f(place.)448 2426 y(In)f(both)g(cases,)g(the)g(entries)h +(remo)o(v)o(ed)f(from)g(the)g(cache)g(are)g(about)h(to)e(become)i(in)l +(v)n(alid.)589 2539 y(All)30 b(operands)j(and)e(results)i(in)d(a)g +(cache)i(entry)g(must)e(be)h(pointers)h(to)f(DdNodes.)50 +b(If)31 b(a)448 2652 y(function)f(produces)f(more)f(than)g(one)f +(result,)j(or)d(uses)h(more)f(than)h(three)g(ar)n(guments,)i(there)448 +2765 y(are)24 b(currently)i(tw)o(o)d(solutions:)p Black +585 2947 a Fm(\017)p Black 46 w Fo(Build)g(a)g(separate,)j(local,)e +(cache.)30 b(\(Using,)24 b(for)f(instance,)j(the)e Fn(st)h +Fo(library.\))p Black 585 3133 a Fm(\017)p Black 46 w +Fo(Combine)33 b(multiple)h(results,)i(or)c(multiple)i(operands,)j(into) +c(a)g(single)h(diagram,)h(by)676 3246 y(b)n(uilding)26 +b(a)d(\223multiple)o(xing)j(structure\224)g(with)e(reserv)o(ed)h(v)n +(ariables.)448 3428 y(Support)35 b(of)f(the)h(former)f(solution)j(is)c +(under)j(de)n(v)o(elopment.)62 b(\(See)34 b Fh(cuddLCache.c)p +Fo(..\))448 3541 y(Support)25 b(for)f(the)f(latter)i(solution)h(may)d +(be)h(pro)o(vided)h(in)f(future)g(v)o(ersions)i(of)d(the)h(package.)589 +3654 y(There)e(are)g(three)h(sets)g(of)e(interf)o(ace)j(functions)h(to) +c(the)i(cache.)29 b(The)21 b(\002rst)h(set)g(is)f(for)h(func-)448 +3767 y(tions)31 b(with)f(three)i(operands:)44 b Fn(cuddCac)o(heInsert) +36 b Fo(and)31 b Fn(cuddCac)o(heLookup)p Fo(.)52 b(The)30 +b(second)448 3880 y(set)21 b(is)g(for)g(functions)j(with)c(tw)o(o)h +(operands:)30 b Fn(cuddCac)o(heInsert2)25 b Fo(and)d +Fn(cuddCac)o(heLookup2)p Fo(.)448 3993 y(The)33 b(second)i(set)f(is)f +(for)h(functions)i(with)d(one)h(operand:)51 b Fn(cuddCac)o(heInsert1)38 +b Fo(and)c Fn(cudd-)448 4106 y(Cac)o(heLookup1)p Fo(.)42 +b(The)26 b(second)j(set)e(is)g(slightly)i(f)o(aster)f(than)g(the)f +(\002rst,)h(and)f(the)g(third)h(set)f(is)448 4219 y(slightly)f(f)o +(aster)f(than)f(the)g(second.)448 4463 y Fp(4.4.1)92 +b(Cache)23 b(Sizing)448 4638 y Fo(The)e(size)i(of)e(the)h(cache)h(can)f +(increase)h(during)h(the)d(e)o(x)o(ecution)j(of)e(an)f(application.)31 +b(\(There)22 b(is)448 4751 y(currently)27 b(no)d(w)o(ay)g(to)g +(decrease)i(the)e(size)h(of)f(the)g(cache,)i(though)f(it)f(w)o(ould)h +(not)f(be)g(dif)n(\002cult)448 4863 y(to)33 b(do)g(it.\))57 +b(When)33 b(a)g(cache)h(miss)f(occurs,)j(the)e(package)g(uses)g(the)f +(follo)n(wing)i(criteria)f(to)448 4976 y(decide)25 b(whether)g(to)e +(resize)i(the)f(cache:)p Black 1897 5225 a(29)p Black +eop end +%%Page: 30 30 +TeXDict begin 30 29 bop Black Black Black 562 573 a Fo(1.)p +Black 46 w(If)28 b(the)h(cache)g(already)i(e)o(xceeds)f(the)f(limit)f +(gi)n(v)o(en)h(by)g(the)g Fh(maxCache)24 b Fo(\002eld)29 +b(of)f(the)676 686 y(manager)l(,)i(no)f(resizing)h(tak)o(es)f(place.)44 +b(The)28 b(limit)g(is)g(the)h(minimum)f(of)g(tw)o(o)g(v)n(alues:)676 +799 y(a)k(v)n(alue)i(set)f(at)f(initialization)37 b(time)c(and)g +(possibly)i(modi\002ed)e(by)g(the)g(application,)676 +912 y(which)g(constitutes)i(the)e(hard)h(limit)e(be)o(yond)i(which)f +(the)g(cache)h(will)e(ne)n(v)o(er)h(gro)n(w;)676 1024 +y(and)23 b(a)f(number)i(that)f(depends)i(on)e(the)g(current)h(total)g +(number)g(of)e(slots)i(in)f(the)g(unique)676 1137 y(table.)p +Black 562 1325 a(2.)p Black 46 w(If)f(the)h(cache)h(is)f(not)g(too)g +(lar)n(ge)h(already)-6 b(,)25 b(resizing)g(is)d(decided)j(based)f(on)f +(the)g(hit)g(rate.)676 1438 y(The)28 b(polic)o(y)i(adopted)h(by)e(the)h +(CUDD)c(package)31 b(is)e(\223re)n(w)o(ard-based.)-6 +b(\224)48 b(If)29 b(the)g(cache)676 1551 y(hit)23 b(rate)h(is)g(high,)g +(then)g(it)f(is)h(w)o(orthwhile)h(to)e(increase)j(the)d(size)h(of)g +(the)g(cache.)448 1738 y(When)i(resizing)h(tak)o(es)f(place,)g(the)g +(statistical)h(counters)h(used)e(to)f(compute)h(the)f(hit)h(rate)f(are) +448 1851 y(reinitialized)g(so)c(as)g(to)g(pre)n(v)o(ent)h(immediate)g +(resizing.)30 b(The)21 b(number)h(of)f(entries)i(is)d(doubled.)589 +1964 y(The)k(rationale)i(for)e(the)g(\223re)n(w)o(ard-based\224)j +(polic)o(y)e(is)e(as)h(follo)n(ws.)30 b(In)23 b(man)o(y)h(BDD/ADD)448 +2077 y(applications)j(the)c(hit)g(rate)g(is)g(not)g(v)o(ery)g(sensiti)n +(v)o(e)i(to)d(the)h(size)h(of)e(the)i(cache:)30 b(It)22 +b(is)h(primarily)448 2190 y(a)i(function)j(of)e(the)g(problem)g +(instance)i(at)d(hand.)36 b(If)25 b(a)h(lar)n(ge)g(hit)g(rate)g(is)g +(observ)o(ed,)h(chances)448 2303 y(are)c(that)g(by)g(using)g(a)f(lar)n +(ge)i(cache,)g(the)e(results)i(of)f(lar)n(ge)h(problems)g(\(those)f +(that)h(w)o(ould)f(tak)o(e)448 2416 y(longer)31 b(to)f(solv)o(e\))g +(will)g(survi)n(v)o(e)g(in)g(the)g(cache)h(without)f(being)h(o)o(v)o +(erwritten)g(long)f(enough)448 2529 y(to)i(cause)i(a)d(v)n(aluable)k +(cache)e(hit.)55 b(Notice)32 b(that)h(when)f(a)g(lar)n(ge)i(problem)f +(is)f(solv)o(ed)h(more)448 2642 y(than)c(once,)g(so)f(are)g(its)g +(recursi)n(v)o(ely)i(generated)g(subproblems.)44 b(If)28 +b(the)g(hit)f(rate)i(is)e(lo)n(w)-6 b(,)28 b(the)448 +2755 y(probability)f(of)c(lar)n(ge)i(problems)g(being)g(solv)o(ed)g +(more)e(than)i(once)f(is)f(lo)n(w)-6 b(.)589 2868 y(The)20 +b(other)h(observ)n(ation)j(about)d(the)f(cache)i(sizing)f(polic)o(y)g +(is)f(that)h(there)g(is)f(little)h(point)g(in)448 2980 +y(k)o(eeping)k(a)d(cache)h(which)g(is)f(much)h(lar)n(ger)h(than)f(the)g +(unique)h(table.)29 b(Ev)o(ery)23 b(time)f(the)h(unique)448 +3093 y(table)29 b(\223\002lls)g(up,)-6 b(\224)29 b(garbage)g +(collection)i(is)d(in)l(v)n(ok)o(ed)j(and)e(the)f(cache)h(is)f(cleared) +i(of)e(all)g(dead)448 3206 y(entries.)h(A)19 b(cache)i(that)g(is)f +(much)g(lar)n(ger)i(than)f(the)f(unique)i(table)f(is)f(therefore)i +(less)f(than)f(fully)448 3319 y(utilized.)448 3565 y +Fp(4.4.2)92 b(Local)24 b(Caches)448 3739 y Fo(Sometimes)k(it)f(may)f +(be)i(necessary)h(or)e(con)l(v)o(enient)j(to)d(use)h(a)f(local)h +(cache.)40 b(A)26 b(local)i(cache)448 3852 y(can)f(be)g(lossless)i +(\(no)e(results)h(are)e(e)n(v)o(er)h(o)o(v)o(erwritten\),)i(or)e(it)f +(may)g(store)i(objects)g(for)f(which)448 3965 y(canonical)36 +b(representations)h(are)c(not)g(a)n(v)n(ailable.)59 b(One)33 +b(important)h(f)o(act)g(to)f(k)o(eep)g(in)g(mind)448 +4078 y(when)d(using)g(a)f(local)h(cache)h(is)e(that)h(local)g(caches)h +(are)e(not)h(cleared)h(during)g(garbage)g(col-)448 4191 +y(lection)e(or)e(before)i(reordering.)42 b(Therefore,)29 +b(it)e(is)g(necessary)j(to)d(increment)i(the)e(reference)448 +4304 y(count)22 b(of)d(all)i(nodes)g(pointed)h(by)e(a)g(local)h(cache.) +28 b(\(Unless)21 b(their)g(reference)h(counts)g(are)e(guar)n(-)448 +4417 y(anteed)25 b(positi)n(v)o(e)h(in)d(some)h(other)h(w)o(ay)-6 +b(.)29 b(One)23 b(such)i(w)o(ay)e(is)h(by)f(including)k(all)d(partial)h +(results)448 4530 y(in)i(the)g(global)i(result.\))40 +b(Before)27 b(disposing)j(of)d(the)g(local)h(cache,)g(all)f(elements)i +(stored)f(in)f(it)448 4643 y(must)20 b(be)g(passed)h(to)e +Fn(Cudd)p 1300 4643 28 4 v 34 w(Recur)o(siveDer)m(ef)13 +b Fo(.)30 b(As)19 b(consequence)k(of)d(the)g(f)o(act)g(that)g(all)g +(results)448 4756 y(in)i(a)g(local)h(cache)g(are)g(referenced,)i(it)d +(is)g(generally)i(con)l(v)o(enient)h(to)e(store)g(in)f(the)g(local)h +(cache)448 4868 y(also)h(the)e(result)i(of)f(tri)n(vial)g(problems,)h +(which)f(are)g(not)g(usually)h(stored)g(in)f(the)f(global)i(cache.)p +Black 1897 5225 a(30)p Black eop end +%%Page: 31 31 +TeXDict begin 31 30 bop Black Black 448 573 a Fo(Otherwise,)35 +b(after)d(a)g(recursi)n(v)o(e)h(call,)i(it)c(is)h(dif)n(\002cult)g(to)g +(tell)h(whether)f(the)h(result)g(is)e(in)h(the)448 686 +y(cache,)25 b(and)f(therefore)h(referenced,)h(or)e(not)g(in)f(the)h +(cache,)g(and)g(therefore)i(not)e(referenced.)589 799 +y(An)19 b(alternati)n(v)o(e)i(approach)g(to)e(referencing)j(the)d +(results)i(in)e(the)g(local)h(caches)g(is)f(to)g(install)448 +912 y(hook)25 b(functions)h(\(see)e(Section)g(3.16\))h(to)e(be)h(e)o(x) +o(ecuted)h(before)g(garbage)g(collection.)448 1158 y +Fi(4.5)99 b(The)26 b(Unique)g(T)-9 b(able)448 1333 y +Fo(A)29 b(recursi)n(v)o(e)j(procedure)h(typically)f(splits)g(the)e +(operands)j(by)d(e)o(xpanding)j(with)d(respect)h(to)448 +1445 y(the)d(topmost)h(v)n(ariable.)43 b(T)-7 b(opmost)28 +b(in)g(this)g(conte)o(xt)h(refers)g(to)e(the)h(v)n(ariable)i(that)e(is) +g(closest)448 1558 y(to)i(the)f(roots)i(in)e(the)h(current)h(v)n +(ariable)g(order)-5 b(.)47 b(The)29 b(nodes,)j(on)d(the)h(other)g +(hand,)i(hold)e(the)448 1671 y(inde)o(x,)c(which)f(is)g(in)l(v)n +(ariant)i(with)e(reordering.)36 b(Therefore,)26 b(when)f(splitting,)j +(one)d(must)g(use)448 1784 y(the)j(permutation)i(array)e(maintained)i +(by)d(the)h(package)i(to)d(get)h(the)f(right)i(le)n(v)o(el.)40 +b(Access)28 b(to)448 1897 y(the)22 b(permutation)i(array)e(is)f(pro)o +(vided)i(by)f(the)f(macro)h Fn(cuddI)27 b Fo(for)21 b(BDDs)f(and)i +(ADDs,)d(and)j(by)448 2010 y(the)i(macro)g Fn(cuddIZ)29 +b Fo(for)24 b(ZDDs.)589 2123 y(The)i(unique)i(table)f(consists)h(of)e +(as)g(man)o(y)g(hash)h(tables)h(as)e(there)h(are)f(v)n(ariables)i(in)e +(use.)448 2236 y(These)e(has)f(tables)h(are)g(called)g +Fn(unique)h(subtables)p Fo(.)31 b(The)23 b(sizes)g(of)g(the)h(unique)h +(subtables)g(are)448 2349 y(determined)h(by)e(tw)o(o)f(criteria:)p +Black 562 2524 a(1.)p Black 46 w(The)g(collision)j(lists)e(should)h(be) +f(short)g(to)g(k)o(eep)g(access)h(time)e(do)n(wn.)p Black +562 2707 a(2.)p Black 46 w(There)18 b(should)i(be)e(enough)i(room)e +(for)g(dead)h(nodes,)h(to)e(pre)n(v)o(ent)h(too)g(frequent)h(garbage) +676 2819 y(collections.)448 2995 y(While)30 b(the)g(\002rst)g +(criterion)i(is)d(f)o(airly)i(straightforw)o(ard)j(to)c(implement,)i +(the)e(second)h(lea)n(v)o(es)448 3108 y(more)22 b(room)g(to)f(creati)n +(vity)-6 b(.)31 b(The)21 b(CUDD)e(package)24 b(tries)f(to)e(\002gure)h +(out)g(whether)h(more)e(dead)448 3220 y(node)j(should)h(be)e(allo)n +(wed)g(to)g(increase)i(performance.)31 b(\(See)23 b(also)h(Section)f +(3.4.\))29 b(There)23 b(are)448 3333 y(tw)o(o)k(reasons)h(for)f(not)g +(doing)h(garbage)g(collection)h(too)e(often.)39 b(The)26 +b(ob)o(vious)j(one)e(is)f(that)i(it)448 3446 y(is)21 +b(e)o(xpensi)n(v)o(e.)30 b(The)21 b(second)i(is)e(that)h(dead)g(nodes)g +(may)f(be)g(reclaimed,)j(if)d(the)o(y)g(are)h(the)f(result)448 +3559 y(of)k(a)g(successful)j(cache)f(lookup.)35 b(Hence)26 +b(dead)g(nodes)g(may)f(pro)o(vide)i(a)e(substantial)j(speed-)448 +3672 y(up)35 b(if)f(the)o(y)g(are)h(k)o(ept)g(around)g(long)h(enough.) +62 b(The)34 b(usefulness)j(of)d(k)o(eeping)i(man)o(y)e(dead)448 +3785 y(nodes)g(around)h(v)n(aries)f(from)e(application)k(to)d +(application,)38 b(and)33 b(from)g(problem)h(instance)448 +3898 y(to)d(problem)g(instance.)51 b(As)30 b(in)g(the)h(sizing)g(of)f +(the)h(cache,)i(the)e(CUDD)d(package)k(adopts)g(a)448 +4011 y(\223re)n(w)o(ard-based\224)k(polic)o(y)e(to)e(decide)i(ho)n(w)e +(much)h(room)f(should)i(be)f(used)g(for)g(the)g(unique)448 +4124 y(table.)62 b(If)35 b(the)f(number)h(of)g(dead)g(nodes)h +(reclaimed)g(is)e(lar)n(ge)h(compared)h(to)f(the)f(number)448 +4237 y(of)d(nodes)h(directly)g(requested)h(from)e(the)g(memory)f +(manager)l(,)k(then)d(the)g(CUDD)d(package)448 4350 y(assumes)34 +b(that)g(it)e(will)h(be)f(bene\002cial)j(to)e(allo)n(w)f(more)h(room)g +(for)g(the)g(subtables,)k(thereby)448 4462 y(reducing)31 +b(the)e(frequenc)o(y)i(of)e(garbage)h(collection.)47 +b(The)28 b(package)j(does)e(so)g(by)g(switching)448 4575 +y(between)c(tw)o(o)e(modes)h(of)g(operation:)p Black +562 4751 a(1.)p Black 46 w(F)o(ast)d(gro)n(wth:)30 b(In)22 +b(this)h(mode,)f(the)h(ratio)g(of)g(dead)g(nodes)g(to)g(total)g(nodes)h +(required)g(for)676 4863 y(garbage)k(collection)h(is)e(higher)h(than)g +(in)f(the)g(slo)n(w)f(gro)n(wth)h(mode)g(to)g(f)o(a)n(v)n(or)h +(resizing)676 4976 y(of)23 b(the)h(subtables.)p Black +1897 5225 a(31)p Black eop end +%%Page: 32 32 +TeXDict begin 32 31 bop Black Black Black 562 573 a Fo(2.)p +Black 46 w(Slo)n(w)28 b(gro)n(wth:)42 b(In)29 b(this)h(mode)g(k)o +(eeping)h(man)o(y)f(dead)g(nodes)h(around)g(is)f(not)f(as)h(im-)676 +686 y(portant)25 b(as)e(k)o(eeping)j(memory)e(requirements)i(lo)n(w)-6 +b(.)448 873 y(Switching)25 b(from)e(one)h(mode)g(to)f(the)h(other)h(is) +e(based)i(on)e(the)h(follo)n(wing)h(criteria:)p Black +562 1061 a(1.)p Black 46 w(If)e(the)h(unique)h(table)f(is)g(already)h +(lar)n(ge,)f(only)h(slo)n(w)e(gro)n(wth)h(is)f(possible.)p +Black 562 1249 a(2.)p Black 46 w(If)35 b(the)h(table)h(is)f(small)g +(and)g(man)o(y)g(dead)h(nodes)g(are)f(being)h(reclaimed,)j(then)d(f)o +(ast)676 1362 y(gro)n(wth)24 b(is)f(selected.)448 1549 +y(This)j(polic)o(y)g(is)g(especially)i(ef)n(fecti)n(v)o(e)f(when)f(the) +g(diagrams)h(being)f(manipulated)j(ha)n(v)o(e)d(lots)448 +1662 y(of)f(recombination.)37 b(Notice)25 b(the)h(interplay)h(of)e(the) +h(cache)g(sizing)g(and)g(unique)g(sizing:)34 b(F)o(ast)448 +1775 y(gro)n(wth)24 b(normally)h(occurs)f(when)g(the)f(cache)h(hit)g +(rate)g(is)f(lar)n(ge.)29 b(The)23 b(cache)h(and)g(the)g(unique)448 +1888 y(table)h(then)f(gro)n(w)f(in)h(concert,)h(preserving)h(a)d +(healthy)i(balance)h(between)e(their)h(sizes.)448 2137 +y Fi(4.6)99 b(Allo)o(wing)24 b(Asynchr)n(onous)i(Reordering)448 +2311 y Fo(Asynchronous)36 b(reordering)f(is)d(the)g(reordering)j(that)d +(is)g(triggered)j(automatically)g(by)d(the)448 2424 y(increase)37 +b(of)d(the)h(number)g(of)g(nodes.)62 b(Asynchronous)38 +b(reordering)f(tak)o(es)f(place)f(when)g(a)448 2537 y(ne)n(w)28 +b(internal)i(node)g(must)e(be)g(created,)j(and)e(the)g(number)g(of)f +(nodes)i(has)f(reached)h(a)e(gi)n(v)o(en)448 2650 y(threshold.)49 +b(\(The)29 b(threshold)j(is)d(adjusted)i(by)f(the)f(package)i(e)n(v)o +(ery)f(time)f(reordering)j(tak)o(es)448 2763 y(place.\))589 +2876 y(Those)24 b(procedures)j(that)d(do)g(not)f(create)i(ne)n(w)e +(nodes)i(\(e.g.,)e(procedures)j(that)e(count)h(the)448 +2989 y(number)g(of)e(nodes)h(or)g(minterms\))g(need)g(not)g(w)o(orry)f +(about)i(asynchronous)i(reordering:)32 b(No)448 3102 +y(special)25 b(precaution)i(is)c(necessary)j(in)e(writing)g(them.)589 +3215 y(Procedures)i(that)e(only)g(manipulate)i(decision)f(diagrams)g +(through)g(the)f(e)o(xported)h(func-)448 3328 y(tions)j(of)e(the)h +(CUDD)e(package)j(also)f(need)h(not)f(concern)h(themselv)o(es)h(with)d +(asynchronous)448 3440 y(reordering.)32 b(\(See)23 b(Section)i(3.2.1)e +(for)h(the)g(e)o(xceptions.\))589 3553 y(The)i(remaining)h(class)g(of)e +(procedures)k(is)c(composed)j(of)d(functions)j(that)e(visit)h(the)f +(dia-)448 3666 y(grams)h(and)h(may)e(create)i(ne)n(w)e(nodes.)39 +b(All)26 b(such)i(procedures)h(in)e(the)g(CUDD)d(package)29 +b(are)448 3779 y(written)35 b(so)e(that)h(the)o(y)g(can)g(be)f +(interrupted)k(by)d(dynamic)g(reordering.)62 b(The)33 +b(general)i(ap-)448 3892 y(proach)26 b(follo)n(wed)g(goes)f(under)g +(the)g(name)f(of)h(\223abort)g(and)g(retry.)-6 b(\224)32 +b(As)24 b(the)g(name)h(implies,)g(a)448 4005 y(computation)i(that)d(is) +f(interrupted)k(by)c(dynamic)i(reordering)h(is)e(aborted)h(and)f(tried) +h(again.)589 4118 y(A)e(recursi)n(v)o(e)i(procedure)h(that)e(can)f(be)h +(interrupted)i(by)e(dynamic)g(reordering)i(\(an)e(inter)n(-)448 +4231 y(ruptible)g(procedure)h(from)d(no)n(w)g(on\))h(is)f(composed)i +(of)e(tw)o(o)f(functions.)31 b(One)22 b(is)g(responsible)448 +4344 y(for)30 b(the)f(real)h(computation.)49 b(The)29 +b(other)h(is)f(a)g(simple)h(wrapper,)h(which)f(tests)g(whether)g(re-) +448 4457 y(ordering)c(occurred)g(and)e(restarts)h(the)f(computation)i +(if)d(it)h(did.)589 4570 y(Asynchronous)f(reordering)e(of)e(BDDs)e(and) +i(ADDs)e(can)i(only)h(be)e(triggered)k(inside)e Fn(cud-)448 +4682 y(dUniqueInter)r Fo(,)36 b(when)31 b(a)f(ne)n(w)g(node)i(is)f +(about)h(to)e(be)h(created.)53 b(Lik)o(e)n(wise,)32 b(asynchronous)448 +4795 y(reordering)f(of)d(ZDDs)f(can)h(only)h(be)f(triggered)j(inside)e +Fn(cuddUniqueInterZdd)r Fo(.)48 b(When)28 b(re-)448 4908 +y(ordering)e(is)d(triggered,)j(three)e(things)h(happen:)p +Black 1897 5225 a(32)p Black eop end +%%Page: 33 33 +TeXDict begin 33 32 bop Black Black Black 562 573 a Fo(1.)p +Black 46 w Fn(cuddUniqueInter)29 b Fo(returns)d(a)d(NULL)e(v)n(alue;)p +Black 562 760 a(2.)p Black 46 w(The)i(\003ag)g Fn(r)m(eor)m(der)m(ed)28 +b Fo(of)23 b(the)h(manager)h(is)e(set)h(to)g(1.)29 b(\(0)23 +b(means)h(no)g(reordering,)i(while)676 873 y(2)d(indicates)j(an)d +(error)i(occurred)g(during)g(reordering.\))p Black 562 +1061 a(3.)p Black 46 w(The)g(counter)k Fn(r)m(eor)m(derings)g +Fo(of)d(the)g(manager)i(is)e(incremented.)40 b(The)26 +b(counter)i(is)e(ini-)676 1174 y(tialized)37 b(to)f(0)f(when)h(the)g +(manager)h(is)f(started)h(and)f(can)g(be)g(accessed)i(by)e(calling)676 +1287 y Fn(Cudd)p 877 1287 28 4 v 33 w(ReadReor)m(derings)p +Fo(.)41 b(By)25 b(taking)j(tw)o(o)e(readings)j(of)d(the)h(counter)l(,)i +(an)d(applica-)676 1400 y(tion)32 b(can)g(determine)i(if)d(v)n(ariable) +j(reordering)h(has)d(tak)o(en)h(place)g(between)g(the)f(\002rst)676 +1513 y(and)27 b(the)g(second)h(reading.)41 b(The)26 b(package)j +(itself,)f(ho)n(we)n(v)o(er)l(,)g(does)g(not)f(mak)o(e)g(use)g(of)676 +1626 y(the)c(counter:)31 b(It)24 b(is)f(mentioned)j(here)e(for)g +(completeness.)589 1813 y(The)35 b(recursi)n(v)o(e)h(procedure)i(that)d +(recei)n(v)o(es)h(a)e(NULL)f(v)n(alue)i(from)g Fn(cuddUniqueInter)448 +1926 y Fo(must)g(free)h(all)f(intermediate)j(results)f(that)e(it)g(may) +g(ha)n(v)o(e)h(computed)g(before,)j(and)d(return)448 +2039 y(NULL)21 b(in)j(its)f(turn.)589 2152 y(The)31 b(wrapper)g +(function)i(does)e(not)g(decide)i(whether)e(reordering)j(occurred)e +(based)g(on)448 2265 y(the)37 b(NULL)e(return)j(v)n(alue,)i(because)f +(the)e(NULL)d(v)n(alue)k(may)e(be)h(the)g(result)h(of)f(lack)g(of)448 +2378 y(memory)-6 b(.)29 b(Instead,)c(it)f(checks)h(the)e +Fn(r)m(eor)m(der)m(ed)28 b Fo(\003ag.)589 2491 y(When)h(a)e(recursi)n +(v)o(e)i(procedure)i(calls)e(another)g(recursi)n(v)o(e)h(procedure)g +(that)f(may)e(cause)448 2604 y(reordering,)i(it)d(should)i(bypass)f +(the)f(wrapper)h(and)g(call)f(the)g(recursi)n(v)o(e)i(procedure)h +(directly)-6 b(.)448 2716 y(Otherwise,)29 b(the)f(calling)i(procedure)g +(will)d(not)h(kno)n(w)f(whether)i(reordering)h(occurred,)h(and)448 +2829 y(will)26 b(not)g(be)g(able)g(to)g(restart.)37 b(This)25 +b(is)h(the)g(main)g(reason)h(why)e(most)h(recursi)n(v)o(e)h(procedures) +448 2942 y(are)k(internal,)i(rather)e(than)g(static.)50 +b(\(The)30 b(wrappers,)j(on)d(the)h(other)g(hand,)h(are)e(mostly)h(e)o +(x-)448 3055 y(ported.\))448 3304 y Fi(4.7)99 b(Deb)n(ugging)448 +3479 y Fo(By)35 b(de\002ning)i(the)g(symbol)f(DD)p 1508 +3479 V 32 w(DEB)o(UG)e(during)j(compilation,)k(numerous)d(checks)f(are) +448 3592 y(added)20 b(to)e(the)g(code.)28 b(In)18 b(addition,)j(the)d +(procedures)j Fn(Cudd)p 2297 3592 V 34 w(Deb)n(ugChec)n(k)r +Fo(,)g Fn(Cudd)p 3036 3592 V 33 w(Chec)n(kK)m(e)m(ys)p +Fo(,)448 3704 y(and)g Fn(cuddHeapPr)l(o\002le)i Fo(can)e(be)f(called)h +(at)f(an)o(y)g(point)i(to)e(v)o(erify)h(the)f(consistenc)o(y)j(of)d +(the)h(data)448 3817 y(structure.)44 b(\()p Fn(cuddHeapPr)l(o\002le)31 +b Fo(is)d(an)f(internal)j(procedure.)44 b(It)27 b(is)h(declared)i(in)d +Fn(cuddInt.h)p Fo(.\))448 3930 y(Procedures)37 b Fn(Cudd)p +1087 3930 V 34 w(Deb)n(ugChec)n(k)h Fo(and)d Fn(Cudd)p +1983 3930 V 34 w(Chec)n(kK)m(e)m(ys)h Fo(are)f(especially)i(useful)f +(when)448 4043 y(CUDD)20 b(reports)k(that)e(during)i(garbage)f +(collection)i(the)d(number)h(of)e(nodes)j(actually)g(deleted)448 +4156 y(from)k(the)h(unique)h(table)f(is)f(dif)n(ferent)i(from)f(the)f +(count)i(of)e(dead)h(nodes)g(k)o(ept)g(by)g(the)f(man-)448 +4269 y(ager)-5 b(.)36 b(The)25 b(error)h(causing)h(the)f(discrepanc)o +(y)j(may)c(ha)n(v)o(e)h(occurred)i(much)d(earlier)i(than)f(it)f(is)448 +4382 y(disco)o(v)o(ered.)42 b(A)26 b(fe)n(w)h(strate)o(gicaly)j(placed) +f(calls)f(to)f(the)g(deb)n(ugging)k(procedures)f(can)e(con-)448 +4495 y(siderably)j(narro)n(w)e(do)n(wn)f(the)h(search)g(for)g(the)g +(source)g(of)g(the)f(problem.)45 b(\(F)o(or)27 b(instance,)32 +b(a)448 4608 y(call)23 b(to)g Fn(Cudd)p 895 4608 V 34 +w(Recur)o(siveDer)m(ef)38 b Fo(where)23 b(one)g(to)f +Fn(Cudd)p 2210 4608 V 34 w(Der)m(ef)36 b Fo(w)o(as)22 +b(required)i(may)f(be)f(iden-)448 4721 y(ti\002ed)i(in)f(this)h(w)o(ay) +-6 b(.\))589 4834 y(One)29 b(of)g(the)g(most)g(common)g(problems)i +(encountered)h(in)d(deb)n(ugging)j(code)e(based)g(on)448 +4946 y(the)j(CUDD)e(package)k(is)e(a)f(missing)i(call)f(to)g +Fn(Cudd)p 2158 4946 V 34 w(Recur)o(siveDer)m(ef)13 b +Fo(.)59 b(T)-7 b(o)32 b(help)h(identify)p Black 1897 +5225 a(33)p Black eop end +%%Page: 34 34 +TeXDict begin 34 33 bop Black Black 448 573 a Fo(this)22 +b(type)g(of)f(problems,)i(the)e(package)i(pro)o(vides)g(a)e(function)i +(called)f Fn(Cudd)p 2858 573 28 4 v 34 w(Chec)n(kZer)l(oRef)13 +b Fo(.)448 686 y(This)37 b(function)h(should)h(be)d(called)i +(immediately)g(before)g(shutting)h(do)n(wn)e(the)f(manager)-5 +b(.)448 799 y Fn(Cudd)p 649 799 V 34 w(Chec)n(kZer)l(oRef)34 +b Fo(checks)20 b(that)g(the)f(only)h(nodes)g(left)f(with)g(non-zero)i +(reference)h(counts)448 912 y(are)27 b(the)f(prede\002ned)j(constants,) +g(the)e(BDD)d(projection)29 b(functions,)h(and)c(nodes)i(whose)f(ref-) +448 1024 y(erence)e(counts)g(are)f(saturated.)589 1137 +y(F)o(or)29 b(this)h(function)i(to)e(be)g(ef)n(fecti)n(v)o(e)h(the)f +(application)i(must)e(e)o(xplicitly)i(dispose)g(of)d(all)448 +1250 y(diagrams)c(to)f(which)g(it)f(has)h(pointers)h(before)g(calling)h +(it.)448 1498 y Fi(4.8)99 b(Gathering)26 b(and)f(Inter)o(pr)n(eting)i +(Statistics)448 1673 y Fo(Function)33 b Fn(Cudd)p 1003 +1673 V 34 w(PrintInfo)g Fo(can)f(be)f(called)i(to)e(print)i(out)f(the)f +(v)n(alues)i(of)e(parameters)j(and)448 1786 y(statistics)c(for)e(a)f +(manager)-5 b(.)41 b(The)27 b(output)j(of)d Fn(Cudd)p +2089 1786 V 34 w(PrintInfo)i Fo(is)e(di)n(vided)i(in)e(tw)o(o)g +(sections.)448 1899 y(The)19 b(\002rst)g(reports)i(the)e(v)n(alues)h +(of)f(parameters)j(that)d(are)h(under)g(the)f(application)k(control.)29 +b(The)448 2011 y(second)e(reports)g(the)f(v)n(alues)g(of)f(statistical) +j(counters)f(and)f(other)g(non-modi\002able)i(parame-)448 +2124 y(ters.)j(A)22 b(quick)k(guide)f(to)f(the)g(interpretation)k(of)c +(all)g(these)h(quantities)h(follo)n(ws.)31 b(F)o(or)23 +b(ease)h(of)448 2237 y(e)o(xposition,)30 b(we)25 b(re)n(v)o(erse)j(the) +f(order)g(and)g(describe)i(the)d(non-modi\002able)j(parameters)g +(\002rst.)448 2350 y(W)-7 b(e')o(ll)24 b(use)g(a)f(sample)h(run)g(as)f +(e)o(xample.)30 b(There)24 b(is)f(nothing)j(special)f(about)g(this)f +(run.)448 2595 y Fp(4.8.1)92 b(Non)22 b(Modi\002able)h(P)o(arameters) +448 2769 y Fo(The)g(list)h(of)g(non-modi\002able)i(parameters)g(starts) +e(with:)p Black Black 667 2952 a Fh(****)52 b(CUDD)h(non-modifiable)48 +b(parameters)i(****)667 3065 y(Memory)h(in)j(use:)f(32544220)448 +3247 y Fo(This)25 b(is)f(the)h(memory)g(used)h(by)f(CUDD)d(for)j(three) +h(things)g(mainly:)32 b(Unique)26 b(table)f(\(includ-)448 +3360 y(ing)i(all)g(DD)d(nodes)k(in)e(use\),)i(node)f(free)g(list,)g +(and)g(computed)h(table.)38 b(This)26 b(number)i(almost)448 +3473 y(ne)n(v)o(er)g(decreases)h(in)f(the)f(lifetime)h(of)f(a)g(CUDD)e +(manager)l(,)k(because)g(CUDD)c(does)j(not)f(re-)448 +3586 y(lease)k(memory)f(when)g(it)f(frees)h(nodes.)49 +b(Rather)l(,)32 b(it)d(puts)h(the)g(nodes)h(on)f(its)g(o)n(wn)f(free)h +(list.)448 3699 y(This)h(number)g(is)g(in)f(bytes.)51 +b(It)30 b(does)i(not)f(represent)i(the)e(peak)g(memory)g(occupation,)k +(be-)448 3812 y(cause)d(it)e(does)h(not)g(include)h(the)e(size)h(of)f +(data)h(structures)i(created)f(temporarily)h(by)d(some)448 +3925 y(functions)c(\(e.g.,)d(local)i(look-up)g(tables\).)p +Black Black 667 4131 a Fh(Peak)52 b(number)g(of)i(nodes:)d(837018)448 +4338 y Fo(This)31 b(number)h(is)f(the)g(number)g(of)g(nodes)h(that)g +(the)f(manager)h(has)f(allocated.)54 b(This)30 b(is)h(not)448 +4451 y(the)d(lar)n(gest)h(size)f(of)f(the)h(BDDs,)e(because)j(the)f +(manager)g(will)f(normally)i(ha)n(v)o(e)f(some)f(dead)448 +4563 y(nodes)e(and)f(some)g(nodes)h(on)e(the)h(free)g(list.)p +Black Black 667 4770 a Fh(Peak)52 b(number)g(of)i(live)e(nodes:)g +(836894)448 4976 y Fo(This)20 b(is)g(the)h(lar)n(gest)h(number)f(of)f +(li)n(v)o(e)g(nodes)h(that)g(the)f(manager)i(has)e(held)h(since)g(its)g +(creation.)p Black 1897 5225 a(34)p Black eop end +%%Page: 35 35 +TeXDict begin 35 34 bop Black Black Black Black 667 573 +a Fh(Number)51 b(of)j(BDD)f(variables:)d(198)667 686 +y(Number)h(of)j(ZDD)f(variables:)d(0)448 892 y Fo(These)24 +b(numbers)h(tell)f(us)f(this)h(run)g(w)o(as)g(not)f(using)i(ZDDs.)p +Black Black 667 1099 a Fh(Number)51 b(of)j(cache)e(entries:)f(1048576) +448 1306 y Fo(Current)25 b(number)g(of)f(slots)h(of)f(the)g(computed)i +(table.)31 b(If)24 b(one)g(has)g(a)g(performance)i(problem,)448 +1419 y(this)e(is)g(one)g(of)f(the)h(numbers)h(to)e(look)i(at.)j(The)23 +b(cache)i(size)f(is)f(al)o(w)o(ays)i(a)e(po)n(wer)g(of)h(2.)p +Black Black 667 1625 a Fh(Number)51 b(of)j(cache)e(look-ups:)f(2996536) +667 1738 y(Number)g(of)j(cache)e(hits:)g(1187087)448 +1945 y Fo(These)22 b(numbers)i(gi)n(v)o(e)e(an)g(indication)i(of)e(the) +g(hit)g(rate)h(in)e(the)i(computed)g(table.)29 b(It)22 +b(is)g(not)g(un-)448 2058 y(lik)o(ely)j(for)f(model)g(checking)i(runs)e +(to)g(get)f(hit)h(rates)g(e)n(v)o(en)g(higher)h(than)f(this)h(one)f +(\(39.62\045\).)p Black Black 667 2265 a Fh(Number)51 +b(of)j(cache)e(insertions:)e(1809473)667 2377 y(Number)h(of)j(cache)e +(collisions:)e(961208)667 2490 y(Number)h(of)j(cache)e(deletions:)e(0) +448 2697 y Fo(A)30 b(collision)j(occurs)f(when)f(a)f(cache)i(entry)g +(is)e(o)o(v)o(erwritten.)52 b(A)30 b(deletion)j(occurs)f(when)f(a)448 +2810 y(cache)c(entry)g(is)e(in)l(v)n(alidated)k(\(e.g.,)d(during)h +(garbage)g(collection\).)39 b(If)25 b(the)h(number)h(of)e(dele-)448 +2923 y(tions)d(is)f(high)g(compared)i(to)d(the)h(number)h(of)f +(collisions,)i(it)e(means)g(that)g(garbage)i(collection)448 +3036 y(occurs)32 b(too)e(often.)48 b(In)30 b(this)g(case)h(there)f +(were)g(no)g(garbage)h(collections;)36 b(hence,)d(no)c(dele-)448 +3149 y(tions.)p Black Black 667 3355 a Fh(Cache)52 b(used)g(slots)h(=)h +(80.90\045)e(\(expected)e(82.19\045\))448 3562 y Fo(Percentage)26 +b(of)e(cache)i(slots)f(that)f(contain)i(a)e(v)n(alid)h(entry)-6 +b(.)31 b(If)24 b(this)h(number)g(is)f(small,)g(it)g(may)448 +3675 y(signal)h(one)f(of)g(three)g(conditions:)p Black +562 3858 a(1.)p Black 46 w(The)f(cache)h(may)g(ha)n(v)o(e)g(been)g +(recently)i(resized)f(and)f(it)f(is)g(still)i(\002lling)f(up.)p +Black 562 4043 a(2.)p Black 46 w(The)j(cache)i(is)f(too)h(lar)n(ge)g +(for)f(the)g(BDDs.)41 b(This)28 b(should)i(not)e(happen)i(if)d(the)i +(size)f(of)676 4156 y(the)23 b(cache)i(is)e(determined)j(by)e(CUDD.)p +Black 562 4342 a(3.)p Black 46 w(The)f(hash)i(function)h(is)d(not)i(w)o +(orking)g(properly)-6 b(.)32 b(This)24 b(is)f(accompanied)k(by)d(a)f +(de)o(gra-)676 4455 y(dation)34 b(in)f(performance.)59 +b(Con)l(v)o(ersely)-6 b(,)37 b(a)c(de)o(gradation)j(in)c(performance)k +(may)c(be)676 4568 y(due)24 b(to)f(bad)h(hash)g(function)i(beha)n(vior) +-5 b(.)448 4751 y(The)26 b(e)o(xpected)j(v)n(alue)e(is)f(computed)j +(assuming)f(a)e(uniformly)i(random)f(distrib)n(ution)k(of)26 +b(the)448 4863 y(accesses.)45 b(If)28 b(the)h(dif)n(ference)h(between)g +(the)e(measured)i(v)n(alue)f(and)g(the)f(e)o(xpected)i(v)n(alue)f(is) +448 4976 y(lar)n(ge)c(\(unlik)o(e)g(this)g(case\),)f(the)g(cache)g(is)g +(not)f(w)o(orking)i(properly)-6 b(.)p Black 1897 5225 +a(35)p Black eop end +%%Page: 36 36 +TeXDict begin 36 35 bop Black Black Black Black 667 573 +a Fh(Soft)52 b(limit)g(for)i(cache)e(size:)g(1318912)448 +781 y Fo(This)25 b(number)h(says)f(ho)n(w)g(lar)n(ge)h(the)f(cache)h +(can)f(gro)n(w)-6 b(.)33 b(This)24 b(limit)h(is)g(based)h(on)f(the)g +(size)g(of)448 894 y(the)k(unique)g(table.)43 b(CUDD)26 +b(uses)j(a)e(re)n(w)o(ard-based)k(polic)o(y)e(for)f(gro)n(wing)h(the)f +(cache.)44 b(\(See)448 1007 y(Section)32 b(4.4.1.\))49 +b(The)30 b(def)o(ault)i(hit)e(rate)h(for)g(resizing)h(is)e(30\045)g +(and)h(the)g(v)n(alue)g(in)f(ef)n(fect)h(is)448 1120 +y(reported)26 b(among)e(the)g(modi\002able)h(parameters.)p +Black Black 667 1328 a Fh(Number)51 b(of)j(buckets)d(in)j(unique)e +(table:)g(329728)448 1537 y Fo(This)28 b(number)g(is)g(e)o(xactly)h +(one)f(quarter)i(of)d(the)h(one)g(abo)o(v)o(e.)42 b(This)28 +b(is)f(indeed)j(ho)n(w)d(the)h(soft)448 1650 y(limit)37 +b(is)g(determined)i(currently)-6 b(,)43 b(unless)38 b(the)g(computed)g +(table)g(hits)g(the)f(speci\002ed)i(hard)448 1763 y(limit.)29 +b(\(See)23 b(belo)n(w)-6 b(.\))p Black Black 667 1971 +a Fh(Used)52 b(buckets)g(in)h(unique)f(table:)g(87.96\045)g(\(expected) +e(87.93\045\))448 2180 y Fo(Percentage)27 b(of)e(unique)i(table)f(b)n +(uck)o(ets)h(that)e(contain)i(at)e(least)g(one)h(node.)34 +b(Remarks)25 b(analo-)448 2293 y(gous)g(to)e(those)i(made)e(about)i +(the)f(used)g(cache)h(slots)f(apply)-6 b(.)p Black Black +667 2501 a Fh(Number)51 b(of)j(BDD)f(and)g(ADD)g(nodes:)f(836894)667 +2614 y(Number)f(of)j(ZDD)f(nodes:)f(0)448 2822 y Fo(Ho)n(w)22 +b(man)o(y)i(nodes)h(are)e(currently)j(in)e(the)g(unique)h(table,)f +(either)h(ali)n(v)o(e)e(or)h(dead.)p Black Black 667 +3031 a Fh(Number)51 b(of)j(dead)f(BDD)g(and)g(ADD)g(nodes:)f(0)667 +3144 y(Number)f(of)j(dead)f(ZDD)g(nodes:)f(0)448 3352 +y Fo(Subtract)29 b(these)f(numbers)g(from)f(those)i(abo)o(v)o(e)e(to)h +(get)f(the)g(number)i(of)e(li)n(v)o(e)g(nodes.)41 b(In)27 +b(this)448 3465 y(case)k(there)g(are)g(no)f(dead)h(nodes)g(because)i +(the)d(application)j(uses)e(delayed)h(dereferencing)448 +3578 y Fn(Cudd)p 649 3578 28 4 v 34 w(DelayedDer)m(efBdd)r +Fo(.)p Black Black 667 3786 a Fh(Total)52 b(number)g(of)h(nodes)f +(allocated:)e(836894)448 3995 y Fo(This)29 b(is)g(the)g(total)h(number) +g(of)e(nodes)j(that)e(were)g(requested)i(and)f(obtained)h(from)e(the)g +(free)448 4108 y(list.)52 b(It)31 b(ne)n(v)o(er)h(decreases,)j(and)d +(is)f(not)g(an)g(indication)j(of)e(memory)f(occupation)j(after)e(the) +448 4221 y(\002rst)23 b(garbage)i(collection.)32 b(Rather)l(,)24 +b(it)f(is)h(a)f(measure)h(of)g(the)g(package)h(acti)n(vity)-6 +b(.)p Black Black 667 4429 a Fh(Total)52 b(number)g(of)h(nodes)f +(reclaimed:)e(0)448 4638 y Fo(These)29 b(are)f(the)h(nodes)g(that)g +(were)f(resuscitated)k(from)c(the)h(dead.)43 b(If)28 +b(the)o(y)h(are)f(man)o(y)g(more)448 4751 y(than)23 b(the)e(allocated)j +(nodes,)f(and)f(the)g(total)g(number)h(of)e(slots)h(is)g(lo)n(w)f +(relati)n(v)o(e)h(to)g(the)f(number)448 4863 y(of)26 +b(nodes,)i(then)f(one)g(may)f(w)o(ant)g(to)g(increase)i(the)f(limit)f +(for)g(f)o(ast)h(unique)h(table)f(gro)n(wth.)37 b(In)448 +4976 y(this)24 b(case,)g(the)g(number)h(is)e(0)g(because)j(of)d +(delayed)i(dereferencing.)p Black 1897 5225 a(36)p Black +eop end +%%Page: 37 37 +TeXDict begin 37 36 bop Black Black Black Black 667 573 +a Fh(Garbage)51 b(collections)e(so)54 b(far:)f(0)667 +686 y(Time)f(for)h(garbage)f(collections:)d(0.00)k(sec)667 +799 y(Reorderings)c(so)54 b(far:)e(0)667 912 y(Time)g(for)h +(reordering:)d(0.00)j(sec)448 1124 y Fo(There)26 b(is)f(a)g(GC)f(for)i +(each)g(reordering.)37 b(Hence)26 b(the)f(\002rst)h(count)g(will)f(al)o +(w)o(ays)h(be)g(at)f(least)h(as)448 1237 y(lar)n(ge)f(as)f(the)f +(second.)p Black Black 667 1450 a Fh(Node)52 b(swaps)g(in)i +(reordering:)c(0)448 1662 y Fo(This)31 b(is)g(the)g(number)h(of)e +(elementary)j(reordering)h(steps.)52 b(Each)31 b(step)g(consists)i(of)e +(the)g(re-)448 1775 y(e)o(xpression)g(of)d(one)g(node)h(while)f(sw)o +(apping)i(tw)o(o)e(adjacent)i(v)n(ariables.)44 b(This)28 +b(number)h(is)f(a)448 1888 y(good)d(measure)f(of)g(the)g(amount)g(of)g +(w)o(ork)f(done)i(in)e(reordering.)448 2134 y Fp(4.8.2)92 +b(Modi\002able)23 b(P)o(arameters)448 2308 y Fo(Let)g(us)g(no)n(w)f +(consider)k(the)d(modi\002able)h(parameters,)h(that)f(is,)e(those)i +(settings)h(on)f(which)f(the)448 2421 y(application)k(or)c(the)h(user)g +(has)g(control.)p Black Black 667 2634 a Fh(****)52 b(CUDD)h +(modifiable)d(parameters)g(****)667 2746 y(Hard)i(limit)g(for)i(cache)e +(size:)g(8388608)448 2959 y Fo(This)30 b(number)i(counts)f(entries.)51 +b(Each)30 b(entry)h(is)f(16)h(bytes)g(if)f(CUDD)e(is)i(compiled)i(to)e +(use)448 3072 y(32-bit)25 b(pointers.)31 b(T)-7 b(w)o(o)22 +b(important)j(observ)n(ations)i(are)d(in)g(order:)p Black +562 3259 a(1.)p Black 46 w(If)29 b(the)i(datasize)h(limit)e(is)g(set,)h +(CUDD)d(will)i(use)g(it)g(to)g(determine)h(this)g(number)g(au-)676 +3372 y(tomatically)-6 b(.)39 b(On)26 b(a)g(Unix)g(system,)i(one)f(can)g +(type)g(\223limit\224)g(or)f(\223ulimit\224)i(to)e(v)o(erify)i(if)676 +3485 y(this)e(v)n(alue)h(is)e(set.)36 b(If)26 b(the)g(datasize)i(limit) +e(is)f(not)h(set,)h(CUDD)c(uses)k(a)e(def)o(ault)j(which)676 +3598 y(is)21 b(rather)i(small.)28 b(If)22 b(you)g(ha)n(v)o(e)g(enough)i +(memory)d(\(say)i(64MB)e(or)h(more\))f(you)i(should)676 +3711 y(seriously)29 b(consider)g Fn(not)f Fo(using)g(the)f(def)o(ault.) +40 b(So,)27 b(either)h(set)e(the)h(datasize)i(limit,)e(or)676 +3824 y(o)o(v)o(erride)d(the)g(def)o(ault)i(with)d Fn(Cudd)p +1792 3824 28 4 v 34 w(SetMaxCac)o(heHar)m(d)r Fo(.)p +Black 562 4012 a(2.)p Black 46 w(If)d(a)g(process)j(seems)e(to)g(be)f +(going)i(no)n(where,)g(a)f(small)f(v)n(alue)i(for)f(this)g(parameter)i +(may)676 4125 y(be)29 b(the)h(culprit.)47 b(One)29 b(cannot)i(o)o(v)o +(eremphasize)h(the)e(importance)i(of)d(the)h(computed)676 +4237 y(table)24 b(in)f(BDD)f(algorithms.)448 4425 y(In)i(this)g(case)g +(the)g(limit)f(w)o(as)g(automatically)k(set)d(for)f(a)g(tar)n(get)i +(maximum)f(memory)f(occupa-)448 4538 y(tion)h(of)g(104)g(MB.)p +Black Black 667 4751 a Fh(Cache)52 b(hit)h(threshold)d(for)k(resizing:) +c(15\045)p Black 1897 5225 a Fo(37)p Black eop end +%%Page: 38 38 +TeXDict begin 38 37 bop Black Black 448 573 a Fo(This)25 +b(number)g(can)g(be)f(changed)j(if)d(one)h(suspects)i(performance)g(is) +d(hindered)j(by)d(the)h(small)448 686 y(size)30 b(of)e(the)i(cache,)g +(and)g(the)f(cache)h(is)e(not)i(gro)n(wing)f(to)n(w)o(ards)h(the)f +(soft)g(limit)g(suf)n(\002ciently)448 799 y(f)o(ast.)g(In)21 +b(such)h(a)f(case)h(one)g(can)g(change)h(the)e(def)o(ault)i(30\045)f +(to)f(15\045)g(\(as)g(in)h(this)g(case\))g(or)f(e)n(v)o(en)448 +912 y(1\045.)p Black Black 667 1124 a Fh(Garbage)51 b(collection)f +(enabled:)h(yes)448 1337 y Fo(One)34 b(can)g(disable)i(it,)f(b)n(ut)g +(there)f(are)g(fe)n(w)f(good)i(reasons)h(for)e(doing)h(so.)60 +b(It)33 b(is)h(normally)448 1450 y(preferable)26 b(to)e(raise)g(the)g +(limit)g(for)f(f)o(ast)h(unique)i(table)e(gro)n(wth.)29 +b(\(See)24 b(belo)n(w)-6 b(.\))p Black Black 667 1662 +a Fh(Limit)52 b(for)h(fast)g(unique)e(table)i(growth:)e(1363148)448 +1875 y Fo(See)23 b(Section)i(4.5)f(and)g(the)g(comments)g(abo)o(v)o(e)h +(about)g(reclaimed)g(nodes)g(and)f(hard)g(limit)g(for)448 +1988 y(the)g(cache)h(size.)30 b(This)23 b(v)n(alue)i(w)o(as)e(chosen)i +(automatically)i(by)d(CUDD)d(for)j(a)g(datasize)h(limit)448 +2100 y(of)f(1)f(GB.)p Black Black 667 2313 a Fh(Maximum)51 +b(number)h(of)h(variables)e(sifted)h(per)h(reordering:)c(1000)667 +2426 y(Maximum)i(number)h(of)h(variable)e(swaps)h(per)i(reordering:)49 +b(2000000)667 2539 y(Maximum)i(growth)h(while)g(sifting)f(a)j +(variable:)d(1.2)448 2751 y Fo(Lo)n(wering)29 b(these)f(numbers)i(will) +d(cause)i(reordering)i(to)c(be)h(less)h(accurate)h(and)e(f)o(aster)-5 +b(.)43 b(Re-)448 2864 y(sults)22 b(are)f(some)n(what)g(unpredictable,)k +(because)d(lar)n(ger)g(BDDs)d(after)j(one)f(reordering)i(do)e(not)448 +2977 y(necessarily)27 b(mean)d(the)f(process)j(will)d(go)h(f)o(aster)g +(or)g(slo)n(wer)-5 b(.)p Black Black 667 3190 a Fh(Dynamic)51 +b(reordering)f(of)j(BDDs)g(enabled:)e(yes)667 3303 y(Default)g(BDD)i +(reordering)d(method:)h(4)667 3416 y(Dynamic)g(reordering)f(of)j(ZDDs)g +(enabled:)e(no)667 3528 y(Default)g(ZDD)i(reordering)d(method:)h(4)448 +3741 y Fo(These)38 b(lines)h(tell)f(whether)g(automatic)i(reordering)g +(can)e(tak)o(e)g(place)h(and)f(what)f(method)448 3854 +y(w)o(ould)28 b(be)f(used.)41 b(The)27 b(mapping)i(from)e(numbers)h(to) +f(methods)i(is)e(in)g Fh(cudd.h)p Fo(.)37 b(One)27 b(may)448 +3967 y(w)o(ant)i(to)f(try)g(dif)n(ferent)i(BDD)d(reordering)k(methods.) +44 b(If)28 b(v)n(ariable)i(groups)g(are)f(used,)h(ho)n(w-)448 +4080 y(e)n(v)o(er)l(,)21 b(one)f(should)i(not)e(e)o(xpect)h(to)e(see)h +(big)g(dif)n(ferences,)j(because)f(CUDD)c(uses)i(the)g(reported)448 +4193 y(method)31 b(only)f(to)f(reorder)i(each)f(leaf)g(v)n(ariable)h +(group)f(\(typically)i(corresponding)i(present)448 4306 +y(and)d(ne)o(xt)g(state)g(v)n(ariables\).)51 b(F)o(or)30 +b(the)h(relati)n(v)o(e)g(order)g(of)g(the)f(groups,)k(it)c(al)o(w)o +(ays)h(uses)g(the)448 4418 y(same)24 b(algorithm,)h(which)f(is)f(ef)n +(fecti)n(v)o(ely)j(sifting.)589 4531 y(As)i(for)h(enabling)h(dynamic)g +(reordering)h(or)e(not,)h(a)e(sensible)i(recommendation)i(is)c(the)448 +4644 y(follo)n(wing:)36 b(Unless)27 b(the)f(circuit)h(is)f(rather)h +(small)f(or)g(one)h(has)f(a)g(pretty)h(good)g(idea)f(of)g(what)448 +4757 y(the)e(order)h(should)g(be,)e(reordering)j(should)g(be)d +(enabled.)p Black 1897 5225 a(38)p Black eop end +%%Page: 39 39 +TeXDict begin 39 38 bop Black Black Black Black 667 573 +a Fh(Realignment)49 b(of)54 b(ZDDs)e(to)i(BDDs)f(enabled:)e(no)667 +686 y(Realignment)e(of)54 b(BDDs)e(to)i(ZDDs)f(enabled:)e(no)667 +799 y(Dead)h(nodes)g(counted)g(in)h(triggering)d(reordering:)g(no)667 +912 y(Group)i(checking)f(criterion:)f(7)667 1024 y(Recombination)e +(threshold:)i(0)667 1137 y(Symmetry)g(violation)h(threshold:)f(0)667 +1250 y(Arc)j(violation)d(threshold:)g(0)667 1363 y(GA)j(population)d +(size:)i(0)667 1476 y(Number)f(of)j(crossovers)c(for)j(GA:)g(0)448 +1681 y Fo(P)o(arameters)26 b(for)f(reordering.)37 b(See)24 +b(the)i(documentation)i(of)d(the)h(functions)i(used)e(to)f(control)448 +1794 y(these)g(parameters)g(for)f(the)g(details.)p Black +Black 667 1998 a Fh(Next)52 b(reordering)e(threshold:)g(100000)448 +2203 y Fo(When)25 b(the)g(number)g(of)g(nodes)h(crosses)g(this)f +(threshold,)i(reordering)g(will)e(be)f(triggered.)34 +b(\(If)448 2315 y(enabled;)26 b(in)d(this)h(case)f(it)g(is)g(not.\))30 +b(This)23 b(parameter)h(is)f(updated)j(by)d(the)g(package)i(whene)n(v)o +(er)448 2428 y(reordering)i(tak)o(es)f(place.)32 b(The)24 +b(application)j(can)e(change)h(it,)e(for)g(instance)j(at)d(start-up.)33 +b(An-)448 2541 y(other)24 b(possibility)h(is)e(to)f(use)h(a)f(hook)h +(function)i(\(see)e(Section)h(3.16\))f(to)f(o)o(v)o(erride)i(the)f(def) +o(ault)448 2654 y(updating)j(polic)o(y)-6 b(.)448 2899 +y Fp(4.8.3)92 b(Extended)22 b(Statistics)k(and)c(Reporting)448 +3073 y Fo(The)27 b(follo)n(wing)i(symbols)f(can)f(be)h(de\002ned)g +(during)g(compilation)i(to)d(increase)i(the)e(amount)448 +3186 y(of)d(statistics)i(gathered)f(and)f(the)g(number)g(of)g(messages) +h(produced)h(by)d(the)h(package:)p Black 585 3367 a Fm(\017)p +Black 46 w Fo(DD)p 813 3367 28 4 v 32 w(ST)-8 b(A)e(TS;)p +Black 585 3552 a Fm(\017)p Black 46 w Fo(DD)p 813 3552 +V 32 w(CA)l(CHE)p 1151 3552 V 31 w(PR)l(OFILE;)p Black +585 3737 a Fm(\017)p Black 46 w Fo(DD)p 813 3737 V 32 +w(UNIQ)o(UE)p 1194 3737 V 31 w(PR)l(OFILE.)p Black 585 +3922 a Fm(\017)p Black 46 w Fo(DD)p 813 3922 V 32 w(VERBOSE;)448 +4103 y(De\002ning)27 b(DD)p 929 4103 V 32 w(CA)l(CHE)p +1267 4103 V 32 w(PR)l(OFILE)d(causes)k(each)f(entry)h(of)e(the)h(cache) +h(to)f(include)h(an)f(ac-)448 4215 y(cess)i(counter)l(,)h(which)e(is)g +(used)g(to)g(compute)h(simple)f(statistics)i(on)e(the)g(distrib)n +(ution)j(of)d(the)448 4328 y(k)o(e)o(ys.)448 4576 y Fi(4.9)99 +b(Guidelines)25 b(f)n(or)g(Documentation)448 4751 y Fo(The)36 +b(documentation)j(of)d(the)g(CUDD)d(functions)38 b(is)e(e)o(xtracted)i +(automatically)g(from)e(the)448 4863 y(sources)23 b(by)e(Stephen)h(Edw) +o(ards')-5 b(s)21 b(e)o(xtdoc.)29 b(\(The)21 b(Ext)f(system)i(is)e(a)n +(v)n(ailable)j(via)e(anon)o(ymous)448 4976 y(FTP)27 b(from)i +Fh(ic.eecs.berkele)o(y.)o(ed)o(u)p Fo(.\))38 b(The)29 +b(follo)n(wing)h(guidelines)i(are)d(follo)n(wed)p Black +1897 5225 a(39)p Black eop end +%%Page: 40 40 +TeXDict begin 40 39 bop Black Black 448 573 a Fo(in)28 +b(CUDD)d(to)j(insure)h(consistent)h(and)f(ef)n(fecti)n(v)o(e)f(use)h +(of)e(automatic)i(e)o(xtraction.)44 b(It)27 b(is)h(rec-)448 +686 y(ommended)d(that)f(e)o(xtensions)i(to)e(CUDD)d(follo)n(w)j(the)g +(same)f(documentation)k(guidelines.)p Black 585 873 a +Fm(\017)p Black 46 w Fo(The)j(documentation)35 b(of)c(an)g(e)o(xported) +i(procedure)h(should)f(be)e(suf)n(\002cient)h(to)f(allo)n(w)676 +986 y(one)23 b(to)h(use)f(it)h(without)g(reading)h(the)f(code.)29 +b(It)23 b(is)g(not)h(necessary)i(to)d(e)o(xplain)i(ho)n(w)e(the)676 +1099 y(procedure)j(w)o(orks;)e(only)g(what)g(it)f(does.)p +Black 585 1287 a Fm(\017)p Black 46 w Fo(The)29 b Fn(SeeAlso)i +Fo(\002elds)f(should)i(be)e(space-separated)k(lists)d(of)f(function)i +(names.)49 b(The)676 1400 y Fn(SeeAlso)24 b Fo(\002eld)f(of)g(an)g(e)o +(xported)j(procedure)g(should)e(only)h(reference)g(other)f(e)o(xported) +676 1513 y(procedures.)39 b(The)26 b Fn(SeeAlso)h Fo(\002eld)f(of)h(an) +f(internal)i(procedure)h(may)d(reference)i(other)676 +1626 y(internal)c(procedures)i(as)d(well)f(as)h(e)o(xported)i +(procedures,)g(b)n(ut)f(no)f(static)h(procedures.)p Black +585 1813 a Fm(\017)p Black 46 w Fo(The)30 b(return)i(v)n(alues)g(are)f +(detailed)i(in)e(the)g Fn(Description)i Fo(\002eld,)g(not)e(in)g(the)g +Fn(Synopsis)676 1926 y Fo(\002eld.)p Black 585 2114 a +Fm(\017)p Black 46 w Fo(The)c(parameters)k(are)d(documented)j +(alongside)g(their)e(declarations.)46 b(Further)29 b(com-)676 +2227 y(ments)23 b(may)h(appear)h(in)e(the)h Fn(Description)i +Fo(\002eld.)p Black 585 2414 a Fm(\017)p Black 46 w Fo(If)i(the)i +Fn(Description)h Fo(\002eld)e(is)g(non-empty\227which)j(is)d(the)h +(normal)f(case)h(for)f(an)g(e)o(x-)676 2527 y(ported)19 +b(procedure\227then)j(the)d(synopsis)h(is)e(repeated\227possibly)23 +b(slightly)d(changed\227)676 2640 y(at)25 b(the)h(be)o(ginning)i(of)e +(the)g Fn(Description)i Fo(\002eld.)35 b(This)25 b(is)h(so)f(because)j +(e)o(xtdoc)f(will)e(not)676 2753 y(put)e(the)h(synopsis)i(in)e(the)f +(same)h(HTML)d(\002le)i(as)h(the)f(description.)p Black +585 2941 a Fm(\017)p Black 46 w Fo(The)g Fn(Synopsis)j +Fo(\002eld)d(should)i(be)f(about)g(one)g(line)g(long.)448 +3233 y Fq(5)120 b(The)30 b(C++)g(Interface)448 3444 y +Fi(5.1)99 b(Compiling)25 b(and)g(Linking)448 3618 y Fo(T)-7 +b(o)23 b(b)n(uild)i(an)e(application)k(that)d(uses)g(the)g(CUDD)d(C++)i +(interf)o(ace,)j(you)e(should)h(add)p Black Black 448 +3805 a Fh(#include)51 b("cuddObj.hh")448 3993 y Fo(to)31 +b(your)g(source)i(\002les.)50 b(In)30 b(addition)j(to)e(the)g(normal)g +(CUDD)e(libraries)j(\(see)g(Section)f(3.1\))448 4106 +y(you)22 b(should)g(link)g Fh(libobj.a)16 b Fo(to)21 +b(your)h(e)o(x)o(ecutable.)30 b(Refer)21 b(to)f(the)i +Fh(Makefile)16 b Fo(in)21 b(the)g(top)448 4219 y(le)n(v)o(el)j +(directory)i(of)d(the)h(distrib)n(ution)j(for)d(further)h(details.)448 +4468 y Fi(5.2)99 b(Basic)25 b(Manipulation)448 4642 y +Fo(The)d(follo)n(wing)i(fragment)g(of)f(code)g(illustrates)i(some)e +(simple)g(operations)j(on)c(BDDs)f(using)448 4755 y(the)j(C++)f(interf) +o(ace.)p Black 1897 5225 a(40)p Black eop end +%%Page: 41 41 +TeXDict begin 41 40 bop Black Black Black Black 448 573 +a Fh(Cudd)53 b(mgr\(0,0\);)448 686 y(BDD)h(x)g(=)g(mgr.bddVar\(\);)448 +799 y(BDD)g(y)g(=)g(mgr.bddVar\(\);)448 912 y(BDD)g(f)g(=)g(x)g(*)g(y;) +448 1024 y(BDD)g(g)g(=)g(y)g(+)g(!x;)448 1137 y(cout)f(<<)h("f)f(is")g +(<<)h(\(f)g(<=)f(g)h(?)h("")e(:)h(")g(not"\))721 1250 +y(<<)g(")g(less)e(than)h(or)h(equal)e(to)i(g\\n";)448 +1438 y Fo(This)22 b(code)h(creates)h(a)e(manager)h(called)h +Fh(mgr)c Fo(and)j(tw)o(o)e(v)n(ariables)k(in)d(it.)28 +b(It)22 b(then)h(de\002nes)g(tw)o(o)448 1551 y(functions)31 +b Fh(f)c Fo(and)h Fh(g)f Fo(in)h(terms)g(of)g(the)g(v)n(ariables.)44 +b(Finally)-6 b(,)30 b(it)e(prints)h(a)f(message)h(based)g(on)448 +1664 y(the)h(comparison)j(of)c(the)i(tw)o(o)e(functions.)50 +b(No)30 b(e)o(xplicit)h(referencing)i(or)d(dereferencing)j(is)448 +1777 y(required.)h(The)25 b(operators)i(are)d(o)o(v)o(erloaded)j(in)e +(the)g(intuiti)n(v)o(e)h(w)o(ay)-6 b(.)32 b(BDDs)23 b(are)i(freed)g +(when)448 1890 y(e)o(x)o(ecution)d(lea)n(v)o(es)e(the)g(scope)g(in)g +(which)g(the)o(y)f(are)h(de\002ned)g(or)f(when)h(the)g(v)n(ariables)h +(referring)448 2002 y(to)j(them)f(are)h(o)o(v)o(erwritten.)448 +2295 y Fq(6)120 b(Ackno)o(wledgments)448 2502 y Fo(The)27 +b(contrib)n(utors:)40 b(Iris)27 b(Bahar)l(,)h(Hyunw)o(oo)g(Cho,)f +(Erica)g(Frohm,)g(Charlie)h(Gaona,)g(Cheng)448 2615 y(Hua,)k(Jae-Y)-10 +b(oung)32 b(Jang,)g(Seh-W)-7 b(oong)31 b(Jeong,)i(Balakrishna)g(K)o +(umthekar)l(,)g(Enrico)d(Macii,)448 2728 y(Bobbie)19 +b(Manne,)h(In-Ho)e(Moon,)h(Curt)f(Musfeldt,)j(Shipra)d(P)o(anda,)h +(Abelardo)h(P)o(ardo,)f(Bernard)448 2841 y(Plessier)l(,)28 +b(Ka)n(vita)f(Ra)n(vi,)g(Hyongk)o(yoon)i(Shin,)d(Alan)h(Shuler)l(,)g +(Arun)f(Si)n(v)n(akumaran,)i(Jor)n(gen)448 2954 y(Si)n(v)o(esind.)448 +3067 y(The)k(early)h(adopters:)49 b(Gianpiero)34 b(Cabodi,)h(Jordi)e +(Cortadella,)j(Mario)d(Escobar)l(,)j(Gayani)448 3180 +y(Gamage,)28 b(Gary)f(Hachtel,)i(Mariano)g(Hermida,)f(W)-7 +b(oohyuk)28 b(Lee,)f(Enric)g(P)o(astor)l(,)i(Massimo)448 +3292 y(Poncino,)c(Ellen)e(Sento)o(vich,)i(the)f(students)i(of)d +(ECEN5139.)589 3405 y(I)36 b(am)f(also)h(particularly)k(indebted)e(to)e +(the)g(follo)n(wing)h(people)g(for)g(in-depth)h(discus-)448 +3518 y(sions)23 b(on)f(BDDs:)27 b(Armin)22 b(Biere,)g(Oli)n(vier)g +(Coudert,)h(Arie)f(Gur\002nk)o(el,)h(Geert)f(Janssen,)i(Don)448 +3631 y(Knuth,)39 b(Da)n(vid)d(Long,)i(Jean)f(Christophe)g(Madre,)i(K)n +(en)c(McMillan,)k(Shin-Ichi)e(Minato,)448 3744 y(Jaehong)24 +b(P)o(ark,)c(Rajee)n(v)i(Ranjan,)g(Rick)f(Rudell,)h(Ellen)f(Sento)o +(vich,)i(T)-7 b(om)20 b(Shiple,)i(Christian)448 3857 +y(Stangier)l(,)j(and)f(Bw)o(olen)g(Y)-9 b(ang.)589 3970 +y(Special)28 b(thanks)h(to)e(Norris)h(Ip)f(for)g(guiding)j(my)c(f)o +(altering)k(steps)e(in)f(the)g(design)i(of)e(the)448 +4083 y(C++)h(interf)o(ace.)46 b(Gianpiero)30 b(Cabodi)f(and)g(Stef)o +(ano)g(Quer)g(ha)n(v)o(e)g(graciously)i(agreed)f(to)e(let)448 +4196 y(me)23 b(distrib)n(ute)j(their)f(dddmp)f(library)h(with)f(CUDD.) +589 4309 y(Masahiro)j(Fujita,)e(Gary)g(Hachtel,)h(and)f(Carl)g(Pixle)o +(y)g(ha)n(v)o(e)h(pro)o(vided)h(encouragement)448 4422 +y(and)d(advice.)589 4534 y(The)31 b(National)i(Science)f(F)o(oundation) +h(and)f(the)f(Semiconductor)j(Research)f(Corpora-)448 +4647 y(tion)24 b(ha)n(v)o(e)h(supported)h(in)d(part)h(the)g(de)n(v)o +(elopment)i(of)d(this)i(package.)p Black 1897 5225 a(41)p +Black eop end +%%Page: 42 42 +TeXDict begin 42 41 bop Black Black 448 573 a Fq(Refer)n(ences)p +Black 494 780 a Fo([1])p Black 46 w(R.)27 b(I.)h(Bahar)l(,)i(E.)e(A.)f +(Frohm,)i(C.)e(M.)h(Gaona,)i(G.)d(D.)g(Hachtel,)j(E.)e(Macii,)h(A.)f(P) +o(ardo,)645 893 y(and)d(F)-7 b(.)23 b(Somenzi.)36 b(Algebraic)27 +b(decision)f(diagrams)g(and)f(their)g(applications.)40 +b(In)25 b Fn(Pr)l(o-)645 1006 y(ceedings)30 b(of)d(the)h(International) +k(Confer)m(ence)d(on)e(Computer)n(-Aided)j(Design)p Fo(,)f(pages)645 +1119 y(188\226191,)d(Santa)e(Clara,)f(CA,)f(No)o(v)o(ember)h(1993.)p +Black 494 1306 a([2])p Black 46 w(B.)36 b(Bollig,)41 +b(M.)35 b(L)8 b(\250)-38 b(obbing,)42 b(and)c(I.)e(W)-7 +b(e)o(gener)i(.)77 b(Simulated)38 b(annealing)i(to)d(impro)o(v)o(e)645 +1419 y(v)n(ariable)31 b(orderings)h(for)e(OBDDs.)50 b(Presented)30 +b(at)g(the)f(International)k(W)-7 b(orkshop)31 b(on)645 +1532 y(Logic)24 b(Synthesis,)h(Granlibakk)o(en,)h(CA,)c(May)h(1995.)p +Black 494 1720 a([3])p Black 46 w(K.)29 b(S.)f(Brace,)k(R.)d(L.)f +(Rudell,)k(and)f(R.)d(E.)h(Bryant.)55 b(Ef)n(\002cient)30 +b(implementation)j(of)d(a)645 1833 y(BDD)f(package.)57 +b(In)30 b Fn(Pr)l(oceedings)j(of)e(the)f(27th)h(Design)h(A)n(utomation) +g(Confer)m(ence)p Fo(,)645 1945 y(pages)25 b(40\22645,)g(Orlando,)f +(FL,)e(June)i(1990.)p Black 494 2133 a([4])p Black 46 +w(R.)g(K.)g(Brayton)j(et)e(al.)40 b(VIS:)24 b(A)h(system)h(for)f(v)o +(eri\002cation)j(and)e(synthesis.)42 b(T)-6 b(echnical)645 +2246 y(Report)31 b(UCB/ERL)26 b(M95/104,)33 b(Electronics)f(Research)f +(Lab,)g(Uni)n(v)-6 b(.)29 b(of)h(California,)645 2359 +y(December)24 b(1995.)p Black 494 2547 a([5])p Black +46 w(R.)32 b(E.)g(Bryant.)65 b(Graph-based)36 b(algorithms)g(for)d +(Boolean)i(function)h(manipulation.)645 2659 y Fn(IEEE)22 +b(T)-5 b(r)o(ansactions)26 b(on)e(Computer)o(s)p Fo(,)g +(C-35\(8\):677\226691,)k(August)c(1986.)p Black 494 2847 +a([6])p Black 46 w(R.)32 b(Drechsler)l(,)38 b(B.)32 b(Beck)o(er)l(,)k +(and)e(N.)e(G)8 b(\250)-38 b(ock)o(el.)66 b(A)32 b(genetic)j(algorithm) +g(for)f(v)n(ariable)645 2960 y(ordering)27 b(of)e(OBDDs.)35 +b(Presented)26 b(at)f(the)g(International)j(W)-7 b(orkshop)27 +b(on)d(Logic)h(Syn-)645 3073 y(thesis,)g(Granlibakk)o(en,)h(CA,)c(May)h +(1995.)p Black 494 3261 a([7])p Black 46 w(S.)j(J.)g(Friedman)i(and)g +(K.)e(J.)g(Supo)n(wit.)45 b(Finding)28 b(the)g(optimal)g(v)n(ariable)h +(ordering)g(for)645 3373 y(binary)24 b(decision)h(diagrams.)32 +b Fn(IEEE)21 b(T)-5 b(r)o(ansactions)25 b(on)d(Computer)o(s)p +Fo(,)i(39\(5\):710\226713,)645 3486 y(May)g(1990.)p Black +494 3674 a([8])p Black 46 w(M.)35 b(Fujita,)k(Y)-12 b(.)35 +b(Matsunaga,)40 b(and)d(T)-7 b(.)34 b(Kakuda.)74 b(On)35 +b(v)n(ariable)j(ordering)g(of)e(binary)645 3787 y(decision)30 +b(diagrams)f(for)f(the)g(application)j(of)c(multi-le)n(v)o(el)i(logic)g +(synthesis.)49 b(In)28 b Fn(Pr)l(o-)645 3900 y(ceedings)33 +b(of)e(the)g(Eur)l(opean)h(Confer)m(ence)h(on)e(Design)g(A)n(utomation) +p Fo(,)j(pages)e(50\22654,)645 4013 y(Amsterdam,)24 b(February)h(1991.) +p Black 494 4200 a([9])p Black 46 w(M.)h(Held)g(and)i(R.)d(M.)g(Karp.) +44 b(A)25 b(dynamic)j(programming)h(approach)g(to)e(sequencing)645 +4313 y(problems.)35 b Fn(J)n(.)23 b(SIAM)p Fo(,)f(10\(1\):196\226210,) +28 b(1962.)p Black 448 4501 a([10])p Black 47 w(N.)e(Ishiura,)i(H.)e +(Sa)o(w)o(ada,)h(and)g(S.)e(Y)-9 b(ajima.)43 b(Minimization)29 +b(of)e(binary)h(decision)h(dia-)645 4614 y(grams)f(based)g(on)g(e)o +(xchanges)h(of)e(v)n(ariables.)48 b(In)27 b Fn(Pr)l(oceedings)j(of)d +(the)g(International)645 4727 y(Confer)m(ence)37 b(on)e(Computer)n +(-Aided)j(Design)p Fo(,)g(pages)e(472\226475,)k(Santa)35 +b(Clara,)j(CA,)645 4840 y(No)o(v)o(ember)24 b(1991.)p +Black 1897 5225 a(42)p Black eop end +%%Page: 43 43 +TeXDict begin 43 42 bop Black Black Black 448 573 a Fo([11])p +Black 47 w(S.-W)-8 b(.)31 b(Jeong,)37 b(T)-7 b(.-S.)31 +b(Kim,)k(and)e(F)-7 b(.)32 b(Somenzi.)64 b(An)33 b(ef)n(\002cient)h +(method)g(for)f(optimal)645 686 y(BDD)25 b(ordering)k(computation.)47 +b(In)27 b Fn(International)k(Confer)m(ence)e(on)e(VLSI)f(and)h(CAD)645 +799 y(\(ICVC'93\))p Fo(,)c(T)-7 b(aejon,)24 b(K)m(orea,)f(No)o(v)o +(ember)h(1993.)p Black 448 986 a([12])p Black 47 w(S.-I.)29 +b(Minato.)55 b(Zero-suppressed)35 b(BDDs)28 b(for)j(set)f(manipulation) +j(in)d(combinatorial)645 1099 y(problems.)35 b(In)24 +b Fn(Pr)l(oceedings)i(of)e(the)g(Design)g(A)n(utomation)h(Confer)m +(ence)p Fo(,)g(pages)g(272\226)645 1212 y(277,)f(Dallas,)g(TX,)d(June)k +(1993.)p Black 448 1400 a([13])p Black 47 w(S.)38 b(P)o(anda)i(and)f(F) +-7 b(.)38 b(Somenzi.)85 b(Who)39 b(are)h(the)f(v)n(ariables)j(in)d +(your)h(neighborhood.)645 1513 y(In)28 b Fn(Pr)l(oceedings)i(of)d(the)h +(International)j(Confer)m(ence)e(on)f(Computer)n(-Aided)i(Design)p +Fo(,)645 1626 y(pages)25 b(74\22677,)g(San)e(Jose,)h(CA,)d(No)o(v)o +(ember)j(1995.)p Black 448 1813 a([14])p Black 47 w(S.)41 +b(P)o(anda,)48 b(F)-7 b(.)40 b(Somenzi,)48 b(and)43 b(B.)e(F)-7 +b(.)41 b(Plessier)-5 b(.)96 b(Symmetry)43 b(detection)i(and)e(dy-)645 +1926 y(namic)31 b(v)n(ariable)i(ordering)f(of)f(decision)i(diagrams.)57 +b(In)30 b Fn(Pr)l(oceedings)k(of)c(the)h(Inter)n(-)645 +2039 y(national)h(Confer)m(ence)g(on)e(Computer)n(-Aided)i(Design)p +Fo(,)f(pages)g(628\226631,)j(San)29 b(Jose,)645 2152 +y(CA,)22 b(No)o(v)o(ember)i(1994.)p Black 448 2340 a([15])p +Black 47 w(B.)i(F)-7 b(.)25 b(Plessier)-5 b(.)46 b Fn(A)26 +b(Gener)o(al)i(F)-5 b(r)o(ame)o(work)27 b(for)g(V)-10 +b(eri\002cation)30 b(of)d(Sequential)j(Cir)m(cuits)p +Fo(.)645 2452 y(PhD)24 b(thesis,)i(Uni)n(v)o(ersity)h(of)e(Colorado)h +(at)f(Boulder)l(,)i(Dept.)d(of)h(Electrical)i(and)e(Com-)645 +2565 y(puter)g(Engineering,)h(1993.)p Black 448 2753 +a([16])p Black 47 w(R.)e(Rudell.)41 b(Dynamic)25 b(v)n(ariable)j +(ordering)f(for)f(ordered)h(binary)g(decision)h(diagrams.)645 +2866 y(In)g Fn(Pr)l(oceedings)i(of)d(the)h(International)j(Confer)m +(ence)e(on)f(Computer)n(-Aided)i(Design)p Fo(,)645 2979 +y(pages)25 b(42\22647,)g(Santa)e(Clara,)h(CA,)d(No)o(v)o(ember)j(1993.) +p Black 448 3166 a([17])p Black 47 w(E.)43 b(M.)f(Sento)o(vich,)51 +b(K.)42 b(J.)i(Singh,)49 b(C.)42 b(Moon,)50 b(H.)42 b(Sa)n(v)n(oj,)50 +b(R.)42 b(K.)h(Brayton,)50 b(and)645 3279 y(A.)35 b(Sangio)o(v)n +(anni-V)-5 b(incentelli.)79 b(Sequential)38 b(circuit)g(design)g(using) +f(synthesis)i(and)645 3392 y(optimization.)55 b(In)29 +b Fn(Pr)l(oceedings)j(of)e(the)f(International)34 b(Confer)m(ence)d(on) +e(Computer)645 3505 y(Design)p Fo(,)24 b(pages)h(328\226333,)h +(Cambridge,)e(MA,)e(October)i(1992.)p Black 1897 5225 +a(43)p Black eop end +%%Page: 44 44 +TeXDict begin 44 43 bop Black Black Black 448 705 a Fq(Index)p +Black 448 892 a Fo(ADD,)22 b(4,)h(7,)f(11,)i(13)448 1005 +y(aggre)o(gation,)i(18)448 1118 y(Algebraic)f(Decision)g(Diagram,)f +Fn(see)g Fo(ADD)448 1231 y(arc)614 1344 y(complement,)h(11,)f(25,)f(28) +614 1457 y(re)o(gular)l(,)i(25,)f(28)448 1653 y(background)j(v)n(alue,) +d(10)448 1766 y(BDD,)e(4,)h(7,)f(10,)i(12)448 1878 y(Binary)g(Decision) +h(Diagram,)f Fn(see)g Fo(BDD)448 1991 y(box)614 2104 +y(black,)h(4)614 2217 y(clear)l(,)g(4,)e(24)448 2413 +y(cache,)i(8,)e(28,)g(29)614 2526 y(collision,)j(35)614 +2639 y(collision)g(list,)e(31)614 2752 y(deletion,)i(35)614 +2865 y(local,)f(29,)e(30)614 2978 y(lossless,)j(30)614 +3091 y(re)n(w)o(ard-based)h(resizing,)e(30)614 3204 y(sizing,)g(29)448 +3316 y(cacheSize,)g(8)448 3429 y(canonical,)h(7,)d(30)448 +3542 y(compiling,)i(6,)e(10,)h(24)448 3655 y(con\002guration,)j(5)448 +3768 y(con)l(v)o(ersion)614 3881 y(of)d(ADDs)e(to)h(BDDs,)f(15)614 +3994 y(of)i(BDDs)e(to)h(ADDs,)f(15)614 4107 y(of)i(BDDs)e(to)h(ZDDs,)f +(14,)h(15)614 4220 y(of)h(ZDDs)e(to)h(BDDs,)f(15)448 +4333 y(cube)j(sets,)e(4)448 4446 y(cudd.h,)i(6,)e(17,)g(28)448 +4558 y Fn(Cudd)p 649 4558 28 4 v 34 w(addApply)p Fo(,)i(13,)e(14)448 +4671 y Fn(Cudd)p 649 4671 V 34 w(addBddInterval)p Fo(,)k(15)448 +4784 y Fn(Cudd)p 649 4784 V 34 w(addBddP)-7 b(attern)p +Fo(,)26 b(15)448 4897 y Fn(Cudd)p 649 4897 V 34 w(addBddThr)m(eshold)p +Fo(,)h(15)p Black Black 1984 892 a Fn(Cudd)p 2185 892 +V 34 w(addConst)p Fo(,)e(11)1984 1005 y Fn(Cudd)p 2185 +1005 V 34 w(addHarwell)p Fo(,)g(11)1984 1118 y Fn(Cudd)p +2185 1118 V 34 w(AddHook)p Fo(,)f(22)1984 1231 y Fn(Cudd)p +2185 1231 V 34 w(addIthBit)p Fo(,)h(15)1984 1344 y Fn(Cudd)p +2185 1344 V 34 w(addIthV)-10 b(ar)p Fo(,)25 b(11)1984 +1457 y Fn(Cudd)p 2185 1457 V 34 w(addNe)o(wV)-10 b(ar)p +Fo(,)23 b(11)1984 1570 y Fn(Cudd)p 2185 1570 V 34 w(addNe)o(wV)-10 +b(arAtLe)o(vel)p Fo(,)24 b(11,)f(20)1984 1683 y Fn(Cudd)p +2185 1683 V 34 w(addRead)p Fo(,)i(11)1984 1795 y Fn(Cudd)p +2185 1795 V 34 w(addT)-5 b(imes)p Fo(,)24 b(14)1984 1908 +y Fn(Cudd)p 2185 1908 V 34 w(A)n(utodynDisable)p Fo(,)i(17)1984 +2021 y Fn(Cudd)p 2185 2021 V 34 w(A)n(utodynDisableZdd)p +Fo(,)h(20)1984 2134 y Fn(Cudd)p 2185 2134 V 34 w(A)n(utodynEnable)p +Fo(,)f(17)1984 2247 y Fn(Cudd)p 2185 2247 V 34 w(A)n(utodynEnableZdd)p +Fo(,)h(20)1984 2360 y Fn(Cudd)p 2185 2360 V 34 w(bddAnd)p +Fo(,)d(12\22614)1984 2473 y Fn(Cudd)p 2185 2473 V 34 +w(bddAndLimit)p Fo(,)g(22)1984 2586 y Fn(Cudd)p 2185 +2586 V 34 w(bddConstr)o(ain)p Fo(,)i(7)1984 2699 y Fn(Cudd)p +2185 2699 V 34 w(bddIte)p Fo(,)f(12)1984 2812 y Fn(Cudd)p +2185 2812 V 34 w(bddIthV)-10 b(ar)p Fo(,)25 b(11)1984 +2925 y Fn(Cudd)p 2185 2925 V 34 w(bddNe)o(wV)-10 b(ar)p +Fo(,)23 b(11)1984 3037 y Fn(Cudd)p 2185 3037 V 34 w(bddNe)o(wV)-10 +b(arAtLe)o(vel)p Fo(,)24 b(11,)f(20)1984 3150 y Fn(Cudd)p +2185 3150 V 34 w(BddT)-8 b(oAdd)p Fo(,)23 b(15)1984 3263 +y Fn(Cudd)p 2185 3263 V 34 w(bddXor)p Fo(,)h(14)1984 +3376 y(CUDD)p 2248 3376 V 31 w(CA)l(CHE)p 2585 3376 V +32 w(SLO)l(TS,)c(8)1984 3489 y Fn(Cudd)p 2185 3489 V +34 w(Chec)n(kK)m(e)m(ys)p Fo(,)25 b(33)1984 3602 y Fn(Cudd)p +2185 3602 V 34 w(Chec)n(kZer)l(oRef)p Fo(,)g(34)1984 +3715 y Fn(Cudd)p 2185 3715 V 34 w(CountMinterm)p Fo(,)g(11)1984 +3828 y Fn(Cudd)p 2185 3828 V 34 w(Deb)n(ugChec)n(k)p +Fo(,)g(33)1984 3941 y Fn(Cudd)p 2185 3941 V 34 w(DelayedDer)m(efBdd)p +Fo(,)g(36)1984 4054 y Fn(Cudd)p 2185 4054 V 34 w(Der)m(ef)p +Fo(,)e(27,)g(28)1984 4167 y Fn(Cudd)p 2185 4167 V 34 +w(DumpBlif)p Fo(,)g(24)1984 4279 y Fn(Cudd)p 2185 4279 +V 34 w(DumpDaV)-7 b(inci)p Fo(,)24 b(24)1984 4392 y Fn(Cudd)p +2185 4392 V 34 w(DumpDot)p Fo(,)f(24)1984 4505 y Fn(Cudd)p +2185 4505 V 34 w(F)-10 b(or)m(eac)o(hCube)p Fo(,)25 b(6,)e(11)1984 +4618 y Fn(Cudd)p 2185 4618 V 34 w(F)-10 b(or)m(eac)o(hNode)p +Fo(,)25 b(6)1984 4731 y Fn(Cudd)p 2185 4731 V 34 w(HookT)-7 +b(ype)p Fo(,)24 b(21)1984 4844 y Fn(Cudd)p 2185 4844 +V 34 w(Init)p Fo(,)g(8,)f(9)1984 4957 y Fn(Cudd)p 2185 +4957 V 34 w(Mak)o(eT)-5 b(r)m(eeNode)p Fo(,)25 b(19,)e(20)p +Black 1897 5225 a(44)p Black eop end +%%Page: 45 45 +TeXDict begin 45 44 bop Black Black 448 573 a Fn(Cudd)p +649 573 28 4 v 34 w(Mak)o(eZddT)-5 b(r)m(eeNode)p Fo(,)25 +b(21)448 686 y Fn(Cudd)p 649 686 V 34 w(Not)p Fo(,)e(10)448 +799 y Fn(Cudd)p 649 799 V 34 w(PrintInfo)p Fo(,)i(34)448 +912 y Fn(Cudd)p 649 912 V 34 w(PrintMinterm)p Fo(,)f(11)448 +1024 y Fn(Cudd)p 649 1024 V 34 w(Quit)p Fo(,)f(9)448 +1137 y Fn(Cudd)p 649 1137 V 34 w(ReadBac)n(kgr)l(ound)p +Fo(,)k(10)448 1250 y Fn(Cudd)p 649 1250 V 34 w(ReadEpsilon)p +Fo(,)e(10)448 1363 y Fn(Cudd)p 649 1363 V 34 w(ReadErr)l(orCode)p +Fo(,)g(27)448 1476 y Fn(Cudd)p 649 1476 V 34 w(ReadIn)l(vP)-7 +b(erm)p Fo(,)24 b(13)448 1589 y Fn(Cudd)p 649 1589 V +34 w(ReadLo)o(gicZer)l(o)p Fo(,)h(10)448 1702 y Fn(Cudd)p +649 1702 V 34 w(ReadLooseUpto)p Fo(,)g(9)448 1815 y Fn(Cudd)p +649 1815 V 34 w(ReadMaxGr)l(owth)p Fo(,)g(18)448 1928 +y Fn(Cudd)p 649 1928 V 34 w(ReadMinusIn\002nity)p Fo(,)i(10)448 +2041 y Fn(Cudd)p 649 2041 V 34 w(ReadOne)p Fo(,)d(9)448 +2154 y Fn(Cudd)p 649 2154 V 34 w(ReadPlusIn\002nity)p +Fo(,)i(10)448 2267 y Fn(Cudd)p 649 2267 V 34 w(ReadReor)m(derings)p +Fo(,)g(33)448 2379 y Fn(Cudd)p 649 2379 V 34 w(ReadSiftMaxV)-10 +b(ar)p Fo(,)25 b(18)448 2492 y Fn(Cudd)p 649 2492 V 34 +w(ReadT)-5 b(r)m(ee)p Fo(,)24 b(19)448 2605 y Fn(Cudd)p +649 2605 V 34 w(ReadZddOne)p Fo(,)g(9,)f(15)448 2718 +y Fn(Cudd)p 649 2718 V 34 w(ReadZer)l(o)p Fo(,)h(10)448 +2831 y Fn(Cudd)p 649 2831 V 34 w(Recur)o(siveDer)m(ef)p +Fo(,)i(7,)d(26\22628,)h(30,)g(33)448 2944 y Fn(Cudd)p +649 2944 V 34 w(Recur)o(siveDer)m(efZdd)p Fo(,)i(7,)d(26\22628)448 +3057 y Fn(Cudd)p 649 3057 V 34 w(ReduceHeap)p Fo(,)i(17)448 +3170 y Fn(Cudd)p 649 3170 V 34 w(Ref)p Fo(,)e(7,)g(12,)g(26,)g(27)448 +3283 y Fn(Cudd)p 649 3283 V 34 w(Re)l(gular)p Fo(,)i(28)448 +3396 y(CUDD)p 712 3396 V 32 w(REORDER)p 1171 3396 V 30 +w(ANNEALING,)19 b(19)448 3509 y(CUDD)p 712 3509 V 32 +w(REORDER)p 1171 3509 V 30 w(EXA)l(CT)-7 b(,)21 b(19)448 +3621 y(CUDD)p 712 3621 V 32 w(REORDER)p 1171 3621 V 30 +w(GENETIC,)f(19)448 3734 y(CUDD)p 712 3734 V 32 w(REORDER)p +1171 3734 V 30 w(GR)l(OUP)p 1507 3734 V 31 w(SIFT)-7 +b(,)21 b(18)448 3847 y(CUDD)p 712 3847 V 32 w(REORDER)p +1171 3847 V 30 w(GR)l(OUP)p 1507 3847 V 31 w(SIFT)p 1726 +3847 V 31 w(CONV)-12 b(,)780 3960 y(18)448 4073 y(CUDD)p +712 4073 V 32 w(REORDER)p 1171 4073 V 30 w(NONE,)20 b(17,)k(20)448 +4186 y(CUDD)p 712 4186 V 32 w(REORDER)p 1171 4186 V 30 +w(RANDOM,)c(17,)j(20)448 4299 y(CUDD)p 712 4299 V 32 +w(REORDER)p 1171 4299 V 30 w(RANDOM)p 1607 4299 V 30 +w(PIV)l(O)l(T)-7 b(,)780 4412 y(17,)24 b(20)448 4525 +y(CUDD)p 712 4525 V 32 w(REORDER)p 1171 4525 V 30 w(SAME,)d(17,)i(20) +448 4638 y(CUDD)p 712 4638 V 32 w(REORDER)p 1171 4638 +V 30 w(SIFT)-7 b(,)21 b(17,)j(21)448 4751 y(CUDD)p 712 +4751 V 32 w(REORDER)p 1171 4751 V 30 w(SIFT)p 1389 4751 +V 31 w(CONVERGE,)780 4863 y(18,)g(21)448 4976 y(CUDD)p +712 4976 V 32 w(REORDER)p 1171 4976 V 30 w(SYMM)p 1480 +4976 V 31 w(SIFT)-7 b(,)16 b(18,)j(21)p Black Black 1984 +573 a(CUDD)p 2248 573 V 31 w(REORDER)p 2706 573 V 30 +w(SYMM)p 3015 573 V 32 w(SIFT)p 3235 573 V 32 w(CONV)-12 +b(,)2316 686 y(18,)24 b(21)1984 799 y(CUDD)p 2248 799 +V 31 w(REORDER)p 2706 799 V 30 w(WINDO)m(W2,)e(18)1984 +912 y(CUDD)p 2248 912 V 31 w(REORDER)p 2706 912 V 30 +w(WINDO)m(W2)p 3178 912 V 32 w(CONV)-12 b(,)2316 1024 +y(18)1984 1137 y(CUDD)p 2248 1137 V 31 w(REORDER)p 2706 +1137 V 30 w(WINDO)m(W3,)22 b(18)1984 1250 y(CUDD)p 2248 +1250 V 31 w(REORDER)p 2706 1250 V 30 w(WINDO)m(W3)p 3178 +1250 V 32 w(CONV)-12 b(,)2316 1363 y(18)1984 1476 y(CUDD)p +2248 1476 V 31 w(REORDER)p 2706 1476 V 30 w(WINDO)m(W4,)22 +b(18)1984 1589 y(CUDD)p 2248 1589 V 31 w(REORDER)p 2706 +1589 V 30 w(WINDO)m(W4)p 3178 1589 V 32 w(CONV)-12 b(,)2316 +1702 y(19)1984 1815 y Fn(Cudd)p 2185 1815 V 34 w(SetEpsilon)p +Fo(,)25 b(10)1984 1928 y Fn(Cudd)p 2185 1928 V 34 w(SetLooseUpT)-8 +b(o)p Fo(,)24 b(9)1984 2041 y Fn(Cudd)p 2185 2041 V 34 +w(SetMaxCac)o(heHar)m(d)p Fo(,)h(37)1984 2154 y Fn(Cudd)p +2185 2154 V 34 w(SetMaxGr)l(owth)p Fo(,)g(18)1984 2267 +y Fn(Cudd)p 2185 2267 V 34 w(SetSiftMaxV)-10 b(ar)p Fo(,)26 +b(18)1984 2379 y Fn(Cudd)p 2185 2379 V 34 w(SetT)-5 b(imeLimit)p +Fo(,)23 b(22)1984 2492 y Fn(Cudd)p 2185 2492 V 34 w(SetT)-5 +b(r)m(ee)p Fo(,)24 b(19)1984 2605 y Fn(Cudd)p 2185 2605 +V 34 w(Shuf)n(\003eHeap)p Fo(,)i(19)1984 2718 y Fn(Cudd)p +2185 2718 V 34 w(StdP)-7 b(ostReor)m(dHook)p Fo(,)26 +b(22)1984 2831 y Fn(Cudd)p 2185 2831 V 34 w(StdPr)m(eReor)m(dHook)p +Fo(,)f(22)1984 2944 y Fn(Cudd)p 2185 2944 V 34 w(SymmPr)l(o\002le)p +Fo(,)f(18)1984 3057 y(CUDD)p 2248 3057 V 31 w(UNIQ)o(UE)p +2628 3057 V 32 w(SLO)l(TS,)c(8)1984 3170 y Fn(Cudd)p +2185 3170 V 34 w(zddDumpDot)p Fo(,)k(24)1984 3283 y Fn(Cudd)p +2185 3283 V 34 w(zddIsop)p Fo(,)h(15)1984 3396 y Fn(Cudd)p +2185 3396 V 34 w(zddIthV)-10 b(ar)p Fo(,)25 b(12)1984 +3509 y Fn(Cudd)p 2185 3509 V 34 w(zddP)-7 b(ortF)i(r)l(omBdd)p +Fo(,)24 b(16)1984 3621 y Fn(Cudd)p 2185 3621 V 34 w(zddP)-7 +b(ortT)f(oBdd)p Fo(,)24 b(16)1984 3734 y Fn(Cudd)p 2185 +3734 V 34 w(zddRealignDisable)p Fo(,)j(21)1984 3847 y +Fn(Cudd)p 2185 3847 V 34 w(zddRealignEnable)p Fo(,)g(21)1984 +3960 y Fn(Cudd)p 2185 3960 V 34 w(zddReduceHeap)p Fo(,)f(20)1984 +4073 y Fn(Cudd)p 2185 4073 V 34 w(zddShuf)n(\003eHeap)p +Fo(,)h(20)1984 4186 y Fn(Cudd)p 2185 4186 V 34 w(zddV)-10 +b(ar)o(sF)-5 b(r)l(omBddV)-10 b(ar)o(s)p Fo(,)25 b(16)1984 +4299 y Fn(Cudd)p 2185 4299 V 34 w(zddW)-8 b(eakDiv)p +Fo(,)24 b(15)1984 4412 y Fn(cuddCac)o(heInsert)p Fo(,)j(29)1984 +4525 y Fn(cuddCac)o(heInsert1)p Fo(,)h(29)1984 4638 y +Fn(cuddCac)o(heInsert2)p Fo(,)g(29)1984 4751 y Fn(cuddCac)o(heLookup)p +Fo(,)f(29)1984 4863 y Fn(cuddCac)o(heLookup1)p Fo(,)g(29)1984 +4976 y Fn(cuddCac)o(heLookup2)p Fo(,)g(29)p Black 1897 +5225 a(45)p Black eop end +%%Page: 46 46 +TeXDict begin 46 45 bop Black Black 448 573 a Fo(CUDDDIR,)21 +b(22)448 686 y Fn(cuddHeapPr)l(o\002le)p Fo(,)27 b(33)448 +799 y Fn(cuddI)p Fo(,)e(31)448 912 y(cuddInt.h,)h(33)448 +1024 y Fn(cuddIZ)p Fo(,)e(31)448 1137 y Fn(cuddSatDec)p +Fo(,)i(28)448 1250 y Fn(cuddSatInc)p Fo(,)h(28)448 1363 +y Fn(cuddUniqueConst)p Fo(,)g(26)448 1476 y Fn(cuddUniqueInter)p +Fo(,)h(26,)23 b(28,)h(32,)f(33)448 1589 y Fn(cuddUniqueInterZdd)p +Fo(,)28 b(26,)c(32)448 1777 y(DD)p 585 1777 28 4 v 32 +w(CA)l(CHE)p 923 1777 V 31 w(PR)l(OFILE,)d(39)448 1890 +y(DD)p 585 1890 V 32 w(DEB)o(UG,)g(33)448 2003 y(DD)p +585 2003 V 32 w(ST)-8 b(A)e(TS,)20 b(39)448 2116 y(DD)p +585 2116 V 32 w(UNIQ)o(UE)p 966 2116 V 31 w(PR)l(OFILE,)h(39)448 +2229 y(DD)p 585 2229 V 32 w(VERBOSE,)f(39)448 2342 y(DdManager)l(,)25 +b(7,)e(8)448 2455 y(DdNode,)h(6,)f(29)448 2568 y(deb)n(ugging,)k(33)448 +2681 y(DEC)22 b(Alpha,)h(23)448 2793 y(DEC)f(Alpha,)h(10)448 +2906 y(documentation,)k(39)614 3019 y Fn(Description)p +Fo(,)f(40)614 3132 y(HTML)c(\002les,)h(40)614 3245 y +Fn(SeeAlso)p Fo(,)i(40)614 3358 y Fn(Synopsis)p Fo(,)h(40)448 +3471 y(dot,)e Fn(see)g Fo(graph,)g(dra)o(wing)448 3659 +y(Epsilon,)h(10)448 3772 y(e)o(xtdoc,)g Fn(see)f Fo(documentation)448 +3960 y(\003oating)h(point,)f(10)614 4073 y(double)i(\(C)c(type\),)i(7) +614 4186 y(IEEE)e(Standard)j(754,)f(10)448 4299 y(free)g(list,)g(26)448 +4412 y(FTP)-10 b(,)21 b(5,)i(23,)h(39)448 4525 y(function)614 +4638 y(characteristic,)j(4,)c(16)614 4751 y(co)o(v)o(er)l(,)h(15,)g(16) +697 4863 y(irredundant,)j(15)614 4976 y(minterms,)d(11,)g(32)p +Black Black 2150 573 a(ON-set,)f(4)2150 686 y(sum)h(of)f(products,)j +(11)2150 799 y(switching,)f(4)1984 995 y(garbage)g(collection,)h +(7\2269,)e(26,)f(29\22631)2150 1108 y(hooks,)i(21)1984 +1220 y(gcc,)f(10)1984 1333 y(generator)l(,)i(6)1984 1446 +y(global)f(v)n(ariables,)h(7)1984 1559 y(graph)2150 1672 +y(arc)e(capacity)-6 b(,)25 b(10)2150 1785 y(arc)f(length,)h(10)2150 +1898 y(dra)o(wing,)f(24)1984 2011 y(gro)n(wth,)g(9)1984 +2124 y(gzip,)g(5)1984 2320 y(HA)-12 b(VE)p 2231 2320 +V 31 w(IEEE)p 2460 2320 V 32 w(754,)24 b(10)1984 2433 +y(header)h(\002les,)e(17,)h(28)1984 2545 y(hook,)g(21)1984 +2741 y(in\002nities,)h(10)1984 2854 y(installation,)i(5)1984 +2967 y(Intel)e(Pentium)e(4,)g(5)1984 3080 y(interf)o(ace)2150 +3193 y(cache,)i(29)2150 3306 y(SIS,)d(22)2150 3419 y(VIS,)g(22)1984 +3615 y(libraries,)k(5)2150 3728 y(cudd,)e(6)2150 3841 +y(dddmp,)g(24)2150 3954 y(mtr)l(,)f(6,)g(19)2150 4066 +y(obj,)h(40)2150 4179 y(st,)f(6,)g(29)2150 4292 y(util,)h(6)1984 +4488 y(Mak)o(e\002le,)g(6,)f(10,)g(40)1984 4601 y(manager)l(,)i(7,)e(9) +1984 4714 y(matrix)2150 4827 y(sparse,)i(10)1984 4940 +y(maxCache,)f(30)p Black 1897 5225 a(46)p Black eop end +%%Page: 47 47 +TeXDict begin 47 46 bop Black Black 448 573 a Fo(maxMemory)-6 +b(,)24 b(8)448 686 y(MinusIn\002nity)-6 b(,)26 b(10)448 +799 y(MTR)p 651 799 28 4 v 32 w(DEF)-7 b(A)i(UL)d(T)h(,)20 +b(20)448 912 y(MTR)p 651 912 V 32 w(FIXED,)h(19)448 1100 +y(nanotra)n(v)-6 b(,)26 b(5)448 1213 y(node,)e(6)614 +1326 y(constant,)i(6,)d(9\22611,)h(26,)f(27)697 1438 +y(v)n(alue,)h(7)614 1551 y(dead,)g(26,)g(29,)f(31)614 +1664 y(dereference,)k(14)614 1777 y(reclaimed,)e(31)614 +1890 y(rec)o(ycling,)h(7)614 2003 y(reference,)g(14)614 +2116 y(reference)g(count,)f(26)614 2229 y(reference)c(count,)f(6,)f(7,) +g(12,)g(13,)g(26\22630,)780 2342 y(34)697 2455 y(saturated,)26 +b(34)614 2568 y(terminal,)f Fn(see)f Fo(node,)g(constant)614 +2681 y(v)n(ariable)i(inde)o(x,)e(6)448 2793 y(numSlots,)g(8)448 +2906 y(numV)-10 b(ars,)24 b(8)448 3019 y(numV)-10 b(arsZ,)23 +b(8)448 3207 y(PlusIn\002nity)-6 b(,)25 b(10)448 3320 +y(projection)i(functions,)e(11,)f(12,)f(14,)h(15,)f(34)448 +3509 y(README)e(\002le,)h(5)448 3621 y(reordering,)k(4,)d(6,)g(29)614 +3734 y(abort)i(and)f(retry)-6 b(,)24 b(32)614 3847 y(asynchronous,)k +(17,)23 b(32)614 3960 y(con)l(v)o(er)n(ging,)k(17,)d(18)614 +4073 y(Cudd)p 815 4073 V 34 w(ReorderingT)-7 b(ype,)26 +b(17)614 4186 y(dynamic,)f(4,)e(16,)g(20)614 4299 y(e)o(xact,)h(19)614 +4412 y(function)i(wrapper)l(,)f(32,)e(33)614 4525 y(genetic,)i(19)614 +4638 y(group,)g(17,)e(18)614 4751 y(hooks,)i(21)614 4863 +y(interruptible)j(procedure,)d(32)614 4976 y(of)f(BDDs)e(and)i(ADDs,)e +(16)p Black Black 2150 573 a(of)i(ZDDs,)d(15,)j(20)2150 +686 y(random,)g(17)2150 799 y(sifting,)h(17)2150 912 +y(simulated)h(annealing,)f(19)2150 1024 y(symmetric,)g(18)2150 +1137 y(threshold,)h(17,)d(32)2150 1250 y(windo)n(w)-6 +b(,)23 b(18)1984 1446 y(saturating)2150 1559 y(decrements,)j(28)2150 +1672 y(increments,)g(28)1984 1785 y(SISDIR,)c(22)1984 +1898 y(SIZEOF)p 2299 1898 V 31 w(INT)-7 b(,)22 b(28)1984 +2011 y(SIZEOF)p 2299 2011 V 31 w(V)l(OID)p 2554 2011 +V 32 w(P)-10 b(,)22 b(28)1984 2124 y(statistical)k(counters,)g(7,)d(30) +1984 2237 y(statistical)j(counters,)g(26)1984 2350 y(statistics,)g(34) +1984 2462 y(subtable,)g(8,)d(26)1984 2575 y(symmetry)-6 +b(,)24 b(18)1984 2771 y(table)2150 2884 y(computed,)h(8)2150 +2997 y(gro)n(wth,)f(9)2150 3110 y(hash,)g(7,)f(31)2150 +3223 y(unique,)i(6\2269,)f(16,)f(26,)h(30,)f(31)2233 +3336 y(f)o(ast)h(gro)n(wth,)g(31)2233 3449 y(re)n(w)o(ard-based)i +(resizing,)g(31)2233 3562 y(slo)n(w)d(gro)n(wth,)h(32)1984 +3675 y(timeout,)g(22)1984 3870 y(v)n(ariable)2150 3983 +y(groups,)h(19)2150 4096 y(order)l(,)g(6,)e(11)2150 4209 +y(permutation,)j(6,)d(31)2150 4322 y(tree,)h(19,)f(20)1984 +4518 y(ZDD,)e(4,)i(7,)g(12,)h(14,)f(15)1984 4631 y(zero)2150 +4744 y(arithmetic,)i(9,)e(11,)h(15)2150 4857 y(logical,)h(9,)e(15)p +Black 1897 5225 a(47)p Black eop end +%%Page: 48 48 +TeXDict begin 48 47 bop Black Black 448 573 a Fo(Zero-suppressed)22 +b(Binary)d(Decision)h(Diagram,)780 686 y Fn(see)k Fo(ZDD)p +Black Black Black 1897 5225 a(48)p Black eop end +%%Trailer + +userdict /end-hook known{end-hook}if +%%EOF diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllAbs.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllAbs.html new file mode 100644 index 000000000..969b6e6cc --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllAbs.html @@ -0,0 +1,3114 @@ + +cudd package abstract + + + + + +
                        +
                        AssessPathLength() +
                        Chooses the maximum allowable path length of nodes under the + threshold. + +
                        BAapplyBias() +
                        Finds don't care nodes. + +
                        BAmarkNodes() +
                        Marks nodes for remapping. + +
                        BuildConjuncts() +
                        Builds the conjuncts recursively, bottom up. + +
                        BuildSubsetBdd() +
                        Builds the BDD with nodes labeled with path length less than or equal to maxpath + +
                        BuildSubsetBdd() +
                        Builds the subset BDD using the heavy branch method. + +
                        CheckInTables() +
                        Check if the two pairs exist in the table, If any of the + conjuncts do exist, store in the cache and return the corresponding pair. + +
                        CheckTablesCacheAndReturn() +
                        Check the tables for the existence of pair and return one + combination, cache the result. + +
                        ConjunctsFree() +
                        Free factors structure + +
                        CorrelCleanUp() +
                        Frees memory associated with hash table. + +
                        CorrelCompare() +
                        Compares two hash table entries. + +
                        CorrelHash() +
                        Hashes a hash table entry. + +
                        CountMinterms() +
                        Count the number of minterms of each node ina a BDD and + store it in a hash table. + +
                        CreateBotDist() +
                        Get longest distance of node from constant. + +
                        CreateBotDist() +
                        Labels each node with the shortest distance from the constant. + +
                        CreatePathTable() +
                        The outer procedure to label each node with its shortest + distance from the root and constant + +
                        CreateTopDist() +
                        Labels each node with its shortest distance from the root + +
                        Cudd_AddHook() +
                        Adds a function to a hook. + +
                        Cudd_ApaAdd() +
                        Adds two arbitrary precision integers. + +
                        Cudd_ApaCompareRatios() +
                        Compares the ratios of two arbitrary precision integers to two + unsigned ints. + +
                        Cudd_ApaCompare() +
                        Compares two arbitrary precision integers. + +
                        Cudd_ApaCopy() +
                        Makes a copy of an arbitrary precision integer. + +
                        Cudd_ApaCountMinterm() +
                        Counts the number of minterms of a DD. + +
                        Cudd_ApaIntDivision() +
                        Divides an arbitrary precision integer by an integer. + +
                        Cudd_ApaNumberOfDigits() +
                        Finds the number of digits for an arbitrary precision + integer. + +
                        Cudd_ApaPowerOfTwo() +
                        Sets an arbitrary precision integer to a power of two. + +
                        Cudd_ApaPrintDecimal() +
                        Prints an arbitrary precision integer in decimal format. + +
                        Cudd_ApaPrintDensity() +
                        Prints the density of a BDD or ADD using + arbitrary precision arithmetic. + +
                        Cudd_ApaPrintExponential() +
                        Prints an arbitrary precision integer in exponential format. + +
                        Cudd_ApaPrintHex() +
                        Prints an arbitrary precision integer in hexadecimal format. + +
                        Cudd_ApaPrintMintermExp() +
                        Prints the number of minterms of a BDD or ADD in exponential + format using arbitrary precision arithmetic. + +
                        Cudd_ApaPrintMinterm() +
                        Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic. + +
                        Cudd_ApaSetToLiteral() +
                        Sets an arbitrary precision integer to a one-digit literal. + +
                        Cudd_ApaShiftRight() +
                        Shifts right an arbitrary precision integer by one binary + place. + +
                        Cudd_ApaShortDivision() +
                        Divides an arbitrary precision integer by a digit. + +
                        Cudd_ApaSubtract() +
                        Subtracts two arbitrary precision integers. + +
                        Cudd_AutodynDisableZdd() +
                        Disables automatic dynamic reordering of ZDDs. + +
                        Cudd_AutodynDisable() +
                        Disables automatic dynamic reordering. + +
                        Cudd_AutodynEnableZdd() +
                        Enables automatic dynamic reordering of ZDDs. + +
                        Cudd_AutodynEnable() +
                        Enables automatic dynamic reordering of BDDs and ADDs. + +
                        Cudd_AverageDistance() +
                        Computes the average distance between adjacent nodes. + +
                        Cudd_BddToAdd() +
                        Converts a BDD to a 0-1 ADD. + +
                        Cudd_BddToCubeArray() +
                        Builds a positional array from the BDD of a cube. + +
                        Cudd_BiasedOverApprox() +
                        Extracts a dense superset from a BDD with the biased + underapproximation method. + +
                        Cudd_BiasedUnderApprox() +
                        Extracts a dense subset from a BDD with the biased + underapproximation method. + +
                        Cudd_CProjection() +
                        Computes the compatible projection of R w.r.t. cube Y. + +
                        Cudd_CheckCube() +
                        Checks whether g is the BDD of a cube. + +
                        Cudd_CheckKeys() +
                        Checks for several conditions that should not occur. + +
                        Cudd_CheckZeroRef() +
                        Checks the unique table for nodes with non-zero reference + counts. + +
                        Cudd_ClassifySupport() +
                        Classifies the variables in the support of two DDs. + +
                        Cudd_ClearErrorCode() +
                        Clear the error code of a manager. + +
                        Cudd_CofMinterm() +
                        Computes the fraction of minterms in the on-set of all the + positive cofactors of a BDD or ADD. + +
                        Cudd_Cofactor() +
                        Computes the cofactor of f with respect to g. + +
                        Cudd_CountLeaves() +
                        Counts the number of leaves in a DD. + +
                        Cudd_CountMinterm() +
                        Counts the number of minterms of a DD. + +
                        Cudd_CountPathsToNonZero() +
                        Counts the number of paths to a non-zero terminal of a DD. + +
                        Cudd_CountPath() +
                        Counts the number of paths of a DD. + +
                        Cudd_CubeArrayToBdd() +
                        Builds the BDD of a cube from a positional array. + +
                        Cudd_DagSize() +
                        Counts the number of nodes in a DD. + +
                        Cudd_DeadAreCounted() +
                        Tells whether dead nodes are counted towards triggering + reordering. + +
                        Cudd_DebugCheck() +
                        Checks for inconsistencies in the DD heap. + +
                        Cudd_Decreasing() +
                        Determines whether a BDD is negative unate in a + variable. + +
                        Cudd_DelayedDerefBdd() +
                        Decreases the reference count of BDD node n. + +
                        Cudd_Density() +
                        Computes the density of a BDD or ADD. + +
                        Cudd_Deref() +
                        Decreases the reference count of node. + +
                        Cudd_DisableGarbageCollection() +
                        Disables garbage collection. + +
                        Cudd_DisableOrderingMonitoring() +
                        Disables monitoring of ordering. + +
                        Cudd_DisableReorderingReporting() +
                        Disables reporting of reordering stats. + +
                        Cudd_Disequality() +
                        Generates a BDD for the function x - y != c. + +
                        Cudd_DumpBlifBody() +
                        Writes a blif body representing the argument BDDs. + +
                        Cudd_DumpBlif() +
                        Writes a blif file representing the argument BDDs. + +
                        Cudd_DumpDDcal() +
                        Writes a DDcal file representing the argument BDDs. + +
                        Cudd_DumpDaVinci() +
                        Writes a daVinci file representing the argument BDDs. + +
                        Cudd_DumpDot() +
                        Writes a dot file representing the argument DDs. + +
                        Cudd_DumpFactoredForm() +
                        Writes factored forms representing the argument BDDs. + +
                        Cudd_Dxygtdxz() +
                        Generates a BDD for the function d(x,y) > d(x,z). + +
                        Cudd_Dxygtdyz() +
                        Generates a BDD for the function d(x,y) > d(y,z). + +
                        Cudd_EnableGarbageCollection() +
                        Enables garbage collection. + +
                        Cudd_EnableOrderingMonitoring() +
                        Enables monitoring of ordering. + +
                        Cudd_EnableReorderingReporting() +
                        Enables reporting of reordering stats. + +
                        Cudd_EpdCountMinterm() +
                        Counts the number of minterms of a DD with extended precision. + +
                        Cudd_EqualSupNorm() +
                        Compares two ADDs for equality within tolerance. + +
                        Cudd_EquivDC() +
                        Tells whether F and G are identical wherever D is 0. + +
                        Cudd_EstimateCofactorSimple() +
                        Estimates the number of nodes in a cofactor of a DD. + +
                        Cudd_EstimateCofactor() +
                        Estimates the number of nodes in a cofactor of a DD. + +
                        Cudd_Eval() +
                        Returns the value of a DD for a given variable assignment. + +
                        Cudd_ExpectedUsedSlots() +
                        Computes the expected fraction of used slots in the unique + table. + +
                        Cudd_FindEssential() +
                        Finds the essential variables of a DD. + +
                        Cudd_FindTwoLiteralClauses() +
                        Finds the two literal clauses of a DD. + +
                        Cudd_FirstCube() +
                        Finds the first cube of a decision diagram. + +
                        Cudd_FirstNode() +
                        Finds the first node of a decision diagram. + +
                        Cudd_FirstPrime() +
                        Finds the first prime of a Boolean function. + +
                        Cudd_FreeTree() +
                        Frees the variable group tree of the manager. + +
                        Cudd_FreeZddTree() +
                        Frees the variable group tree of the manager. + +
                        Cudd_GarbageCollectionEnabled() +
                        Tells whether garbage collection is enabled. + +
                        Cudd_GenFree() +
                        Frees a CUDD generator. + +
                        Cudd_IncreaseTimeLimit() +
                        Increases the time limit for the manager. + +
                        Cudd_Increasing() +
                        Determines whether a BDD is positive unate in a + variable. + +
                        Cudd_IndicesToCube() +
                        Builds a cube of BDD variables from an array of indices. + +
                        Cudd_Inequality() +
                        Generates a BDD for the function x - y ≥ c. + +
                        Cudd_Init() +
                        Creates a new DD manager. + +
                        Cudd_IsGenEmpty() +
                        Queries the status of a generator. + +
                        Cudd_IsInHook() +
                        Checks whether a function is in a hook. + +
                        Cudd_IsNonConstant() +
                        Returns 1 if a DD node is not constant. + +
                        Cudd_IterDerefBdd() +
                        Decreases the reference count of BDD node n. + +
                        Cudd_LargestCube() +
                        Finds a largest cube in a DD. + +
                        Cudd_MakeBddFromZddCover() +
                        Converts a ZDD cover to a BDD. + +
                        Cudd_MakeTreeNode() +
                        Creates a new variable group. + +
                        Cudd_MakeZddTreeNode() +
                        Creates a new ZDD variable group. + +
                        Cudd_MinHammingDist() +
                        Returns the minimum Hamming distance between f and minterm. + +
                        Cudd_NewApaNumber() +
                        Allocates memory for an arbitrary precision integer. + +
                        Cudd_NextCube() +
                        Generates the next cube of a decision diagram onset. + +
                        Cudd_NextNode() +
                        Finds the next node of a decision diagram. + +
                        Cudd_NextPrime() +
                        Generates the next prime of a Boolean function. + +
                        Cudd_NodeReadIndex() +
                        Returns the index of the node. + +
                        Cudd_OrderingMonitoring() +
                        Returns 1 if monitoring of ordering is enabled. + +
                        Cudd_OutOfMem() +
                        Warns that a memory allocation failed. + +
                        Cudd_OverApprox() +
                        Extracts a dense superset from a BDD with Shiple's + underapproximation method. + +
                        Cudd_Prime() +
                        Returns the next prime >= p. + +
                        Cudd_PrintDebug() +
                        Prints to the standard output a DD and its statistics. + +
                        Cudd_PrintGroupedOrder() +
                        Hook function to print the current variable order. + +
                        Cudd_PrintInfo() +
                        Prints out statistics and settings for a CUDD manager. + +
                        Cudd_PrintLinear() +
                        Prints the linear transform matrix. + +
                        Cudd_PrintMinterm() +
                        Prints a disjoint sum of products. + +
                        Cudd_PrintTwoLiteralClauses() +
                        Prints the two literal clauses of a DD. + +
                        Cudd_PrintVersion() +
                        Prints the package version number. + +
                        Cudd_PrioritySelect() +
                        Selects pairs from R using a priority function. + +
                        Cudd_Quit() +
                        Deletes resources associated with a DD manager. + +
                        Cudd_Random() +
                        Portable random number generator. + +
                        Cudd_ReadArcviolation() +
                        Returns the current value of the arcviolation parameter used + in group sifting. + +
                        Cudd_ReadBackground() +
                        Reads the background constant of the manager. + +
                        Cudd_ReadCacheHits() +
                        Returns the number of cache hits. + +
                        Cudd_ReadCacheLookUps() +
                        Returns the number of cache look-ups. + +
                        Cudd_ReadCacheSlots() +
                        Reads the number of slots in the cache. + +
                        Cudd_ReadCacheUsedSlots() +
                        Reads the fraction of used slots in the cache. + +
                        Cudd_ReadDead() +
                        Returns the number of dead nodes in the unique table. + +
                        Cudd_ReadElapsedTime() +
                        Returns the time elapsed since the start time of the manager. + +
                        Cudd_ReadEpsilon() +
                        Reads the epsilon parameter of the manager. + +
                        Cudd_ReadErrorCode() +
                        Returns the code of the last error. + +
                        Cudd_ReadGarbageCollectionTime() +
                        Returns the time spent in garbage collection. + +
                        Cudd_ReadGarbageCollections() +
                        Returns the number of times garbage collection has occurred. + +
                        Cudd_ReadGroupcheck() +
                        Reads the groupcheck parameter of the manager. + +
                        Cudd_ReadInvPermZdd() +
                        Returns the index of the ZDD variable currently in the i-th + position of the order. + +
                        Cudd_ReadInvPerm() +
                        Returns the index of the variable currently in the i-th + position of the order. + +
                        Cudd_ReadIthClause() +
                        Accesses the i-th clause of a DD. + +
                        Cudd_ReadKeys() +
                        Returns the number of nodes in the unique table. + +
                        Cudd_ReadLinear() +
                        Reads an entry of the linear transform matrix. + +
                        Cudd_ReadLogicZero() +
                        Returns the logic zero constant of the manager. + +
                        Cudd_ReadLooseUpTo() +
                        Reads the looseUpTo parameter of the manager. + +
                        Cudd_ReadMaxCacheHard() +
                        Reads the maxCacheHard parameter of the manager. + +
                        Cudd_ReadMaxCache() +
                        Returns the soft limit for the cache size. + +
                        Cudd_ReadMaxGrowthAlternate() +
                        Reads the maxGrowthAlt parameter of the manager. + +
                        Cudd_ReadMaxGrowth() +
                        Reads the maxGrowth parameter of the manager. + +
                        Cudd_ReadMaxLive() +
                        Reads the maximum allowed number of live nodes. + +
                        Cudd_ReadMaxMemory() +
                        Reads the maximum allowed memory. + +
                        Cudd_ReadMaxReorderings() +
                        Returns the maximum number of times reordering may be invoked. + +
                        Cudd_ReadMemoryInUse() +
                        Returns the memory in use by the manager measured in bytes. + +
                        Cudd_ReadMinDead() +
                        Reads the minDead parameter of the manager. + +
                        Cudd_ReadMinHit() +
                        Reads the hit rate that causes resizinig of the computed + table. + +
                        Cudd_ReadMinusInfinity() +
                        Reads the minus-infinity constant from the manager. + +
                        Cudd_ReadNextReordering() +
                        Returns the threshold for the next dynamic reordering. + +
                        Cudd_ReadNodeCount() +
                        Reports the number of nodes in BDDs and ADDs. + +
                        Cudd_ReadNodesDropped() +
                        Returns the number of nodes dropped. + +
                        Cudd_ReadNodesFreed() +
                        Returns the number of nodes freed. + +
                        Cudd_ReadNumberXovers() +
                        Reads the current number of crossovers used by the + genetic algorithm for reordering. + +
                        Cudd_ReadOne() +
                        Returns the one constant of the manager. + +
                        Cudd_ReadOrderRandomization() +
                        Returns the order randomization factor. + +
                        Cudd_ReadPeakLiveNodeCount() +
                        Reports the peak number of live nodes. + +
                        Cudd_ReadPeakNodeCount() +
                        Reports the peak number of nodes. + +
                        Cudd_ReadPermZdd() +
                        Returns the current position of the i-th ZDD variable in the + order. + +
                        Cudd_ReadPerm() +
                        Returns the current position of the i-th variable in the + order. + +
                        Cudd_ReadPlusInfinity() +
                        Reads the plus-infinity constant from the manager. + +
                        Cudd_ReadPopulationSize() +
                        Reads the current size of the population used by the + genetic algorithm for reordering. + +
                        Cudd_ReadRecomb() +
                        Returns the current value of the recombination parameter used + in group sifting. + +
                        Cudd_ReadRecursiveCalls() +
                        Returns the number of recursive calls. + +
                        Cudd_ReadReorderingCycle() +
                        Reads the reordCycle parameter of the manager. + +
                        Cudd_ReadReorderingTime() +
                        Returns the time spent in reordering. + +
                        Cudd_ReadReorderings() +
                        Returns the number of times reordering has occurred. + +
                        Cudd_ReadSiftMaxSwap() +
                        Reads the siftMaxSwap parameter of the manager. + +
                        Cudd_ReadSiftMaxVar() +
                        Reads the siftMaxVar parameter of the manager. + +
                        Cudd_ReadSize() +
                        Returns the number of BDD variables in existance. + +
                        Cudd_ReadSlots() +
                        Returns the total number of slots of the unique table. + +
                        Cudd_ReadStartTime() +
                        Returns the start time of the manager. + +
                        Cudd_ReadStderr() +
                        Reads the stderr of a manager. + +
                        Cudd_ReadStdout() +
                        Reads the stdout of a manager. + +
                        Cudd_ReadSwapSteps() +
                        Reads the number of elementary reordering steps. + +
                        Cudd_ReadSymmviolation() +
                        Returns the current value of the symmviolation parameter used + in group sifting. + +
                        Cudd_ReadTimeLimit() +
                        Returns the time limit for the manager. + +
                        Cudd_ReadTree() +
                        Returns the variable group tree of the manager. + +
                        Cudd_ReadUniqueLinks() +
                        Returns the number of links followed in the unique table. + +
                        Cudd_ReadUniqueLookUps() +
                        Returns the number of look-ups in the unique table. + +
                        Cudd_ReadUsedSlots() +
                        Reads the fraction of used slots in the unique table. + +
                        Cudd_ReadVars() +
                        Returns the i-th element of the vars array. + +
                        Cudd_ReadZddOne() +
                        Returns the ZDD for the constant 1 function. + +
                        Cudd_ReadZddSize() +
                        Returns the number of ZDD variables in existance. + +
                        Cudd_ReadZddTree() +
                        Returns the variable group tree of the manager. + +
                        Cudd_ReadZero() +
                        Returns the zero constant of the manager. + +
                        Cudd_RecursiveDerefZdd() +
                        Decreases the reference count of ZDD node n. + +
                        Cudd_RecursiveDeref() +
                        Decreases the reference count of node n. + +
                        Cudd_ReduceHeap() +
                        Main dynamic reordering routine. + +
                        Cudd_Ref() +
                        Increases the reference count of a node, if it is not + saturated. + +
                        Cudd_RemapOverApprox() +
                        Extracts a dense superset from a BDD with the remapping + underapproximation method. + +
                        Cudd_RemapUnderApprox() +
                        Extracts a dense subset from a BDD with the remapping + underapproximation method. + +
                        Cudd_RemoveHook() +
                        Removes a function from a hook. + +
                        Cudd_ReorderingReporting() +
                        Returns 1 if reporting of reordering stats is enabled. + +
                        Cudd_ReorderingStatusZdd() +
                        Reports the status of automatic dynamic reordering of ZDDs. + +
                        Cudd_ReorderingStatus() +
                        Reports the status of automatic dynamic reordering of BDDs + and ADDs. + +
                        Cudd_Reserve() +
                        Expand manager without creating variables. + +
                        Cudd_ResetStartTime() +
                        Resets the start time of the manager. + +
                        Cudd_SetArcviolation() +
                        Sets the value of the arcviolation parameter used + in group sifting. + +
                        Cudd_SetBackground() +
                        Sets the background constant of the manager. + +
                        Cudd_SetEpsilon() +
                        Sets the epsilon parameter of the manager to ep. + +
                        Cudd_SetGroupcheck() +
                        Sets the parameter groupcheck of the manager to gc. + +
                        Cudd_SetLooseUpTo() +
                        Sets the looseUpTo parameter of the manager. + +
                        Cudd_SetMaxCacheHard() +
                        Sets the maxCacheHard parameter of the manager. + +
                        Cudd_SetMaxGrowthAlternate() +
                        Sets the maxGrowthAlt parameter of the manager. + +
                        Cudd_SetMaxGrowth() +
                        Sets the maxGrowth parameter of the manager. + +
                        Cudd_SetMaxLive() +
                        Sets the maximum allowed number of live nodes. + +
                        Cudd_SetMaxMemory() +
                        Sets the maximum allowed memory. + +
                        Cudd_SetMaxReorderings() +
                        Sets the maximum number of times reordering may be invoked. + +
                        Cudd_SetMinHit() +
                        Sets the hit rate that causes resizinig of the computed + table. + +
                        Cudd_SetNextReordering() +
                        Sets the threshold for the next dynamic reordering. + +
                        Cudd_SetNumberXovers() +
                        Sets the number of crossovers used by the + genetic algorithm for reordering. + +
                        Cudd_SetOrderRandomization() +
                        Sets the order randomization factor. + +
                        Cudd_SetPopulationSize() +
                        Sets the size of the population used by the + genetic algorithm for reordering. + +
                        Cudd_SetRecomb() +
                        Sets the value of the recombination parameter used in group + sifting. + +
                        Cudd_SetReorderingCycle() +
                        Sets the reordCycle parameter of the manager. + +
                        Cudd_SetSiftMaxSwap() +
                        Sets the siftMaxSwap parameter of the manager. + +
                        Cudd_SetSiftMaxVar() +
                        Sets the siftMaxVar parameter of the manager. + +
                        Cudd_SetStartTime() +
                        Sets the start time of the manager. + +
                        Cudd_SetStderr() +
                        Sets the stderr of a manager. + +
                        Cudd_SetStdout() +
                        Sets the stdout of a manager. + +
                        Cudd_SetSymmviolation() +
                        Sets the value of the symmviolation parameter used + in group sifting. + +
                        Cudd_SetTimeLimit() +
                        Sets the time limit for the manager. + +
                        Cudd_SetTree() +
                        Sets the variable group tree of the manager. + +
                        Cudd_SetVarMap() +
                        Registers a variable mapping with the manager. + +
                        Cudd_SetZddTree() +
                        Sets the ZDD variable group tree of the manager. + +
                        Cudd_SharingSize() +
                        Counts the number of nodes in an array of DDs. + +
                        Cudd_ShortestLength() +
                        Find the length of the shortest path(s) in a DD. + +
                        Cudd_ShortestPath() +
                        Finds a shortest path in a DD. + +
                        Cudd_ShuffleHeap() +
                        Reorders variables according to given permutation. + +
                        Cudd_SolveEqn() +
                        Implements the solution of F(x,y) = 0. + +
                        Cudd_SplitSet() +
                        Returns m minterms from a BDD. + +
                        Cudd_Srandom() +
                        Initializer for the portable random number generator. + +
                        Cudd_StdPostReordHook() +
                        Sample hook function to call after reordering. + +
                        Cudd_StdPreReordHook() +
                        Sample hook function to call before reordering. + +
                        Cudd_SubsetCompress() +
                        Find a dense subset of BDD f. + +
                        Cudd_SubsetHeavyBranch() +
                        Extracts a dense subset from a BDD with the heavy branch + heuristic. + +
                        Cudd_SubsetShortPaths() +
                        Extracts a dense subset from a BDD with the shortest paths + heuristic. + +
                        Cudd_SubsetWithMaskVars() +
                        Extracts a subset from a BDD. + +
                        Cudd_SupersetCompress() +
                        Find a dense superset of BDD f. + +
                        Cudd_SupersetHeavyBranch() +
                        Extracts a dense superset from a BDD with the heavy branch + heuristic. + +
                        Cudd_SupersetShortPaths() +
                        Extracts a dense superset from a BDD with the shortest paths + heuristic. + +
                        Cudd_SupportIndex() +
                        Finds the variables on which a DD depends. + +
                        Cudd_SupportIndices() +
                        Finds the variables on which a DD depends. + +
                        Cudd_SupportSize() +
                        Counts the variables on which a DD depends. + +
                        Cudd_Support() +
                        Finds the variables on which a DD depends. + +
                        Cudd_SymmProfile() +
                        Prints statistics on symmetric variables. + +
                        Cudd_TimeLimited() +
                        Returns true if the time limit for the manager is set. + +
                        Cudd_TurnOffCountDead() +
                        Causes the dead nodes not to be counted towards triggering + reordering. + +
                        Cudd_TurnOnCountDead() +
                        Causes the dead nodes to be counted towards triggering + reordering. + +
                        Cudd_UnderApprox() +
                        Extracts a dense subset from a BDD with Shiple's + underapproximation method. + +
                        Cudd_UnsetTimeLimit() +
                        Unsets the time limit for the manager. + +
                        Cudd_UpdateTimeLimit() +
                        Updates the time limit for the manager. + +
                        Cudd_VectorSupportIndex() +
                        Finds the variables on which a set of DDs depends. + +
                        Cudd_VectorSupportIndices() +
                        Finds the variables on which a set of DDs depends. + +
                        Cudd_VectorSupportSize() +
                        Counts the variables on which a set of DDs depends. + +
                        Cudd_VectorSupport() +
                        Finds the variables on which a set of DDs depends. + +
                        Cudd_VerifySol() +
                        Checks the solution of F(x,y) = 0. + +
                        Cudd_Xeqy() +
                        Generates a BDD for the function x==y. + +
                        Cudd_Xgty() +
                        Generates a BDD for the function x > y. + +
                        Cudd_addAgreement() +
                        f if f==g; background if f!=g. + +
                        Cudd_addApply() +
                        Applies op to the corresponding discriminants of f and g. + +
                        Cudd_addBddInterval() +
                        Converts an ADD to a BDD. + +
                        Cudd_addBddIthBit() +
                        Converts an ADD to a BDD by extracting the i-th bit from + the leaves. + +
                        Cudd_addBddPattern() +
                        Converts an ADD to a BDD. + +
                        Cudd_addBddStrictThreshold() +
                        Converts an ADD to a BDD. + +
                        Cudd_addBddThreshold() +
                        Converts an ADD to a BDD. + +
                        Cudd_addCmpl() +
                        Computes the complement of an ADD a la C language. + +
                        Cudd_addCompose() +
                        Substitutes g for x_v in the ADD for f. + +
                        Cudd_addComputeCube() +
                        Computes the cube of an array of ADD variables. + +
                        Cudd_addConstrain() +
                        Computes f constrain c for ADDs. + +
                        Cudd_addConst() +
                        Returns the ADD for constant c. + +
                        Cudd_addDiff() +
                        Returns plusinfinity if f=g; returns min(f,g) if f!=g. + +
                        Cudd_addDivide() +
                        Integer and floating point division. + +
                        Cudd_addEvalConst() +
                        Checks whether ADD g is constant whenever ADD f is 1. + +
                        Cudd_addExistAbstract() +
                        Existentially Abstracts all the variables in cube from f. + +
                        Cudd_addFindMax() +
                        Finds the maximum discriminant of f. + +
                        Cudd_addFindMin() +
                        Finds the minimum discriminant of f. + +
                        Cudd_addGeneralVectorCompose() +
                        Composes an ADD with a vector of ADDs. + +
                        Cudd_addHamming() +
                        Computes the Hamming distance ADD. + +
                        Cudd_addHarwell() +
                        Reads in a matrix in the format of the Harwell-Boeing + benchmark suite. + +
                        Cudd_addIteConstant() +
                        Implements ITEconstant for ADDs. + +
                        Cudd_addIte() +
                        Implements ITE(f,g,h). + +
                        Cudd_addIthBit() +
                        Extracts the i-th bit from an ADD. + +
                        Cudd_addIthVar() +
                        Returns the ADD variable with index i. + +
                        Cudd_addLeq() +
                        Determines whether f is less than or equal to g. + +
                        Cudd_addLog() +
                        Natural logarithm of an ADD. + +
                        Cudd_addMatrixMultiply() +
                        Calculates the product of two matrices represented as + ADDs. + +
                        Cudd_addMaximum() +
                        Integer and floating point max. + +
                        Cudd_addMinimum() +
                        Integer and floating point min. + +
                        Cudd_addMinus() +
                        Integer and floating point subtraction. + +
                        Cudd_addMonadicApply() +
                        Applies op to the discriminants of f. + +
                        Cudd_addNand() +
                        NAND of two 0-1 ADDs. + +
                        Cudd_addNegate() +
                        Computes the additive inverse of an ADD. + +
                        Cudd_addNewVarAtLevel() +
                        Returns a new ADD variable at a specified level. + +
                        Cudd_addNewVar() +
                        Returns a new ADD variable. + +
                        Cudd_addNonSimCompose() +
                        Composes an ADD with a vector of 0-1 ADDs. + +
                        Cudd_addNor() +
                        NOR of two 0-1 ADDs. + +
                        Cudd_addOneZeroMaximum() +
                        Returns 1 if f > g and 0 otherwise. + +
                        Cudd_addOrAbstract() +
                        Disjunctively abstracts all the variables in cube from the + 0-1 ADD f. + +
                        Cudd_addOr() +
                        Disjunction of two 0-1 ADDs. + +
                        Cudd_addOuterSum() +
                        Takes the minimum of a matrix and the outer sum of two vectors. + +
                        Cudd_addPermute() +
                        Permutes the variables of an ADD. + +
                        Cudd_addPlus() +
                        Integer and floating point addition. + +
                        Cudd_addRead() +
                        Reads in a sparse matrix. + +
                        Cudd_addResidue() +
                        Builds an ADD for the residue modulo m of an n-bit + number. + +
                        Cudd_addRestrict() +
                        ADD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
                        Cudd_addRoundOff() +
                        Rounds off the discriminants of an ADD. + +
                        Cudd_addScalarInverse() +
                        Computes the scalar inverse of an ADD. + +
                        Cudd_addSetNZ() +
                        This operator sets f to the value of g wherever g != 0. + +
                        Cudd_addSwapVariables() +
                        Swaps two sets of variables of the same size (x and y) in + the ADD f. + +
                        Cudd_addThreshold() +
                        f if f>=g; 0 if f<g. + +
                        Cudd_addTimesPlus() +
                        Calculates the product of two matrices represented as + ADDs. + +
                        Cudd_addTimes() +
                        Integer and floating point multiplication. + +
                        Cudd_addTriangle() +
                        Performs the triangulation step for the shortest path + computation. + +
                        Cudd_addUnivAbstract() +
                        Universally Abstracts all the variables in cube from f. + +
                        Cudd_addVectorCompose() +
                        Composes an ADD with a vector of 0-1 ADDs. + +
                        Cudd_addWalsh() +
                        Generates a Walsh matrix in ADD form. + +
                        Cudd_addXeqy() +
                        Generates an ADD for the function x==y. + +
                        Cudd_addXnor() +
                        XNOR of two 0-1 ADDs. + +
                        Cudd_addXor() +
                        XOR of two 0-1 ADDs. + +
                        Cudd_bddAdjPermuteX() +
                        Rearranges a set of variables in the BDD B. + +
                        Cudd_bddAndAbstractLimit() +
                        Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. Returns NULL if too many nodes are required. + +
                        Cudd_bddAndAbstract() +
                        Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                        Cudd_bddAndLimit() +
                        Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                        Cudd_bddAnd() +
                        Computes the conjunction of two BDDs f and g. + +
                        Cudd_bddApproxConjDecomp() +
                        Performs two-way conjunctive decomposition of a BDD. + +
                        Cudd_bddApproxDisjDecomp() +
                        Performs two-way disjunctive decomposition of a BDD. + +
                        Cudd_bddBindVar() +
                        Prevents sifting of a variable. + +
                        Cudd_bddBooleanDiff() +
                        Computes the boolean difference of f with respect to x. + +
                        Cudd_bddCharToVect() +
                        Computes a vector whose image equals a non-zero function. + +
                        Cudd_bddClippingAndAbstract() +
                        Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
                        Cudd_bddClippingAnd() +
                        Approximates the conjunction of two BDDs f and g. + +
                        Cudd_bddClosestCube() +
                        Finds a cube of f at minimum Hamming distance from g. + +
                        Cudd_bddCompose() +
                        Substitutes g for x_v in the BDD for f. + +
                        Cudd_bddComputeCube() +
                        Computes the cube of an array of BDD variables. + +
                        Cudd_bddConstrainDecomp() +
                        BDD conjunctive decomposition as in McMillan's CAV96 paper. + +
                        Cudd_bddConstrain() +
                        Computes f constrain c. + +
                        Cudd_bddCorrelationWeights() +
                        Computes the correlation of f and g for given input + probabilities. + +
                        Cudd_bddCorrelation() +
                        Computes the correlation of f and g. + +
                        Cudd_bddExistAbstractLimit() +
                        Existentially abstracts all the variables in cube from f. + +
                        Cudd_bddExistAbstract() +
                        Existentially abstracts all the variables in cube from f. + +
                        Cudd_bddGenConjDecomp() +
                        Performs two-way conjunctive decomposition of a BDD. + +
                        Cudd_bddGenDisjDecomp() +
                        Performs two-way disjunctive decomposition of a BDD. + +
                        Cudd_bddIntersect() +
                        Returns a function included in the intersection of f and g. + +
                        Cudd_bddInterval() +
                        Generates a BDD for the function lowerB ≤ x ≤ upperB. + +
                        Cudd_bddIsNsVar() +
                        Checks whether a variable is next state. + +
                        Cudd_bddIsPiVar() +
                        Checks whether a variable is primary input. + +
                        Cudd_bddIsPsVar() +
                        Checks whether a variable is present state. + +
                        Cudd_bddIsVarEssential() +
                        Determines whether a given variable is essential with a + given phase in a BDD. + +
                        Cudd_bddIsVarHardGroup() +
                        Checks whether a variable is set to be in a hard group. + +
                        Cudd_bddIsVarToBeGrouped() +
                        Checks whether a variable is set to be grouped. + +
                        Cudd_bddIsVarToBeUngrouped() +
                        Checks whether a variable is set to be ungrouped. + +
                        Cudd_bddIsop() +
                        Computes a BDD in the interval between L and U with a + simple sum-of-product cover. + +
                        Cudd_bddIteConstant() +
                        Implements ITEconstant(f,g,h). + +
                        Cudd_bddIteLimit() +
                        Implements ITE(f,g,h). Returns + NULL if too many nodes are required. + +
                        Cudd_bddIterConjDecomp() +
                        Performs two-way conjunctive decomposition of a BDD. + +
                        Cudd_bddIterDisjDecomp() +
                        Performs two-way disjunctive decomposition of a BDD. + +
                        Cudd_bddIte() +
                        Implements ITE(f,g,h). + +
                        Cudd_bddIthVar() +
                        Returns the BDD variable with index i. + +
                        Cudd_bddLICompaction() +
                        Performs safe minimization of a BDD. + +
                        Cudd_bddLargestPrimeUnate() +
                        Find a largest prime of a unate function. + +
                        Cudd_bddLeqUnless() +
                        Tells whether f is less than of equal to G unless D is 1. + +
                        Cudd_bddLeq() +
                        Determines whether f is less than or equal to g. + +
                        Cudd_bddLiteralSetIntersection() +
                        Computes the intesection of two sets of literals + represented as BDDs. + +
                        Cudd_bddMakePrime() +
                        Expands cube to a prime implicant of f. + +
                        Cudd_bddMaximallyExpand() +
                        Expands lb to prime implicants of (f and ub). + +
                        Cudd_bddMinimize() +
                        Finds a small BDD that agrees with f over + c. + +
                        Cudd_bddNPAnd() +
                        Computes f non-polluting-and g. + +
                        Cudd_bddNand() +
                        Computes the NAND of two BDDs f and g. + +
                        Cudd_bddNewVarAtLevel() +
                        Returns a new BDD variable at a specified level. + +
                        Cudd_bddNewVar() +
                        Returns a new BDD variable. + +
                        Cudd_bddNor() +
                        Computes the NOR of two BDDs f and g. + +
                        Cudd_bddOrLimit() +
                        Computes the disjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                        Cudd_bddOr() +
                        Computes the disjunction of two BDDs f and g. + +
                        Cudd_bddPermute() +
                        Permutes the variables of a BDD. + +
                        Cudd_bddPickArbitraryMinterms() +
                        Picks k on-set minterms evenly distributed from given DD. + +
                        Cudd_bddPickOneCube() +
                        Picks one on-set cube randomly from the given DD. + +
                        Cudd_bddPickOneMinterm() +
                        Picks one on-set minterm randomly from the given DD. + +
                        Cudd_bddPrintCover() +
                        Prints a sum of prime implicants of a BDD. + +
                        Cudd_bddReadPairIndex() +
                        Reads a corresponding pair index for a given index. + +
                        Cudd_bddRead() +
                        Reads in a graph (without labels) given as a list of arcs. + +
                        Cudd_bddRealignDisable() +
                        Disables realignment of ZDD order to BDD order. + +
                        Cudd_bddRealignEnable() +
                        Enables realignment of BDD order to ZDD order. + +
                        Cudd_bddRealignmentEnabled() +
                        Tells whether the realignment of BDD order to ZDD order is + enabled. + +
                        Cudd_bddResetVarToBeGrouped() +
                        Resets a variable not to be grouped. + +
                        Cudd_bddRestrict() +
                        BDD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
                        Cudd_bddSetNsVar() +
                        Sets a variable type to next state. + +
                        Cudd_bddSetPairIndex() +
                        Sets a corresponding pair index for a given index. + +
                        Cudd_bddSetPiVar() +
                        Sets a variable type to primary input. + +
                        Cudd_bddSetPsVar() +
                        Sets a variable type to present state. + +
                        Cudd_bddSetVarHardGroup() +
                        Sets a variable to be a hard group. + +
                        Cudd_bddSetVarToBeGrouped() +
                        Sets a variable to be grouped. + +
                        Cudd_bddSetVarToBeUngrouped() +
                        Sets a variable to be ungrouped. + +
                        Cudd_bddSqueeze() +
                        Finds a small BDD in a function interval. + +
                        Cudd_bddSwapVariables() +
                        Swaps two sets of variables of the same size (x and y) in + the BDD f. + +
                        Cudd_bddTransfer() +
                        Convert a BDD from a manager to another one. + +
                        Cudd_bddUnbindVar() +
                        Allows the sifting of a variable. + +
                        Cudd_bddUnivAbstract() +
                        Universally abstracts all the variables in cube from f. + +
                        Cudd_bddVarConjDecomp() +
                        Performs two-way conjunctive decomposition of a BDD. + +
                        Cudd_bddVarDisjDecomp() +
                        Performs two-way disjunctive decomposition of a BDD. + +
                        Cudd_bddVarIsBound() +
                        Tells whether a variable can be sifted. + +
                        Cudd_bddVarIsDependent() +
                        Checks whether a variable is dependent on others in a + function. + +
                        Cudd_bddVarMap() +
                        Remaps the variables of a BDD using the default variable map. + +
                        Cudd_bddVectorCompose() +
                        Composes a BDD with a vector of BDDs. + +
                        Cudd_bddXnorLimit() +
                        Computes the exclusive NOR of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                        Cudd_bddXnor() +
                        Computes the exclusive NOR of two BDDs f and g. + +
                        Cudd_bddXorExistAbstract() +
                        Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
                        Cudd_bddXor() +
                        Computes the exclusive OR of two BDDs f and g. + +
                        Cudd_tlcInfoFree() +
                        Frees a DdTlcInfo Structure. + +
                        Cudd_zddChange() +
                        Substitutes a variable with its complement in a ZDD. + +
                        Cudd_zddComplement() +
                        Computes a complement cover for a ZDD node. + +
                        Cudd_zddCountDouble() +
                        Counts the number of minterms of a ZDD. + +
                        Cudd_zddCountMinterm() +
                        Counts the number of minterms of a ZDD. + +
                        Cudd_zddCount() +
                        Counts the number of minterms in a ZDD. + +
                        Cudd_zddCoverPathToString() +
                        Converts a path of a ZDD representing a cover to a string. + +
                        Cudd_zddDagSize() +
                        Counts the number of nodes in a ZDD. + +
                        Cudd_zddDiffConst() +
                        Performs the inclusion test for ZDDs (P implies Q). + +
                        Cudd_zddDiff() +
                        Computes the difference of two ZDDs. + +
                        Cudd_zddDivideF() +
                        Modified version of Cudd_zddDivide. + +
                        Cudd_zddDivide() +
                        Computes the quotient of two unate covers. + +
                        Cudd_zddDumpDot() +
                        Writes a dot file representing the argument ZDDs. + +
                        Cudd_zddFirstPath() +
                        Finds the first path of a ZDD. + +
                        Cudd_zddIntersect() +
                        Computes the intersection of two ZDDs. + +
                        Cudd_zddIsop() +
                        Computes an ISOP in ZDD form from BDDs. + +
                        Cudd_zddIte() +
                        Computes the ITE of three ZDDs. + +
                        Cudd_zddIthVar() +
                        Returns the ZDD variable with index i. + +
                        Cudd_zddNextPath() +
                        Generates the next path of a ZDD. + +
                        Cudd_zddPortFromBdd() +
                        Converts a BDD into a ZDD. + +
                        Cudd_zddPortToBdd() +
                        Converts a ZDD into a BDD. + +
                        Cudd_zddPrintCover() +
                        Prints a sum of products from a ZDD representing a cover. + +
                        Cudd_zddPrintDebug() +
                        Prints to the standard output a ZDD and its statistics. + +
                        Cudd_zddPrintMinterm() +
                        Prints a disjoint sum of product form for a ZDD. + +
                        Cudd_zddPrintSubtable() +
                        Prints the ZDD table. + +
                        Cudd_zddProduct() +
                        Computes the product of two covers represented by ZDDs. + +
                        Cudd_zddReadNodeCount() +
                        Reports the number of nodes in ZDDs. + +
                        Cudd_zddRealignDisable() +
                        Disables realignment of ZDD order to BDD order. + +
                        Cudd_zddRealignEnable() +
                        Enables realignment of ZDD order to BDD order. + +
                        Cudd_zddRealignmentEnabled() +
                        Tells whether the realignment of ZDD order to BDD order is + enabled. + +
                        Cudd_zddReduceHeap() +
                        Main dynamic reordering routine for ZDDs. + +
                        Cudd_zddShuffleHeap() +
                        Reorders ZDD variables according to given permutation. + +
                        Cudd_zddSubset0() +
                        Computes the negative cofactor of a ZDD w.r.t. a variable. + +
                        Cudd_zddSubset1() +
                        Computes the positive cofactor of a ZDD w.r.t. a variable. + +
                        Cudd_zddSupport() +
                        Finds the variables on which a ZDD depends. + +
                        Cudd_zddSymmProfile() +
                        Prints statistics on symmetric ZDD variables. + +
                        Cudd_zddUnateProduct() +
                        Computes the product of two unate covers. + +
                        Cudd_zddUnion() +
                        Computes the union of two ZDDs. + +
                        Cudd_zddVarsFromBddVars() +
                        Creates one or more ZDD variables for each BDD variable. + +
                        Cudd_zddWeakDivF() +
                        Modified version of Cudd_zddWeakDiv. + +
                        Cudd_zddWeakDiv() +
                        Applies weak division to two covers. + +
                        MarkCacheCleanUp() +
                        Frees memory associated with computed table of + cuddBddLICMarkEdges. + +
                        MarkCacheCompare() +
                        Comparison function for the computed table of + cuddBddLICMarkEdges. + +
                        MarkCacheHash() +
                        Hash function for the computed table of cuddBddLICMarkEdges. + +
                        PMX() +
                        Performs the crossover between two parents. + +
                        PairInTables() +
                        Check whether the given pair is in the tables. + +
                        PickOnePair() +
                        Check the tables for the existence of pair and return one + combination, store in cache. + +
                        RAbuildSubset() +
                        Builds the subset BDD for cuddRemapUnderApprox. + +
                        RAmarkNodes() +
                        Marks nodes for remapping. + +
                        ResizeCountMintermPages() +
                        Resize the number of pages allocated to store the minterm + counts. + +
                        ResizeCountNodePages() +
                        Resize the number of pages allocated to store the node counts. + +
                        ResizeNodeDataPages() +
                        Resize the number of pages allocated to store the node data. + +
                        ResizeNodeDistPages() +
                        Resize the number of pages allocated to store the distances + related to each node. + +
                        ResizeQueuePages() +
                        Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd . + +
                        StoreNodes() +
                        Procedure to recursively store nodes that are retained in the subset. + +
                        SubsetCountMintermAux() +
                        Recursively counts minterms of each node in the DAG. + +
                        SubsetCountMinterm() +
                        Counts minterms of each node in the DAG + +
                        SubsetCountNodesAux() +
                        Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node. + +
                        SubsetCountNodes() +
                        Counts the nodes under the current node and its lighter child + +
                        UAbuildSubset() +
                        Builds the subset BDD. + +
                        UAmarkNodes() +
                        Marks nodes for replacement by zero. + +
                        ZeroCase() +
                        If one child is zero, do explicitly what Restrict does or better + +
                        addBddDoInterval() +
                        Performs the recursive step for Cudd_addBddInterval. + +
                        addBddDoIthBit() +
                        Performs the recursive step for Cudd_addBddIthBit. + +
                        addBddDoStrictThreshold() +
                        Performs the recursive step for Cudd_addBddStrictThreshold. + +
                        addBddDoThreshold() +
                        Performs the recursive step for Cudd_addBddThreshold. + +
                        addCheckPositiveCube() +
                        Checks whether cube is an ADD representing the product + of positive literals. + +
                        addDoIthBit() +
                        Performs the recursive step for Cudd_addIthBit. + +
                        addMMRecur() +
                        Performs the recursive step of Cudd_addMatrixMultiply. + +
                        addMultiplicityGroups() +
                        Adds multiplicity groups to a ZDD variable group tree. + +
                        addTriangleRecur() +
                        Performs the recursive step of Cudd_addTriangle. + +
                        addVarToConst() +
                        Replaces variables with constants if possible (part of + canonical form). + +
                        addWalshInt() +
                        Implements the recursive step of Cudd_addWalsh. + +
                        array_compare() +
                        Comparison function for the computed table. + +
                        array_hash() +
                        Hash function for the computed table. + +
                        bddAnnotateMintermCount() +
                        Annotates every node in the BDD node with its minterm count. + +
                        bddCheckPositiveCube() +
                        Checks whether cube is an BDD representing the product of + positive literals. + +
                        bddCorrelationAux() +
                        Performs the recursive step of Cudd_bddCorrelation. + +
                        bddCorrelationWeightsAux() +
                        Performs the recursive step of Cudd_bddCorrelationWeigths. + +
                        bddFixTree() +
                        Fixes the BDD variable group tree after a shuffle. + +
                        bddVarToCanonicalSimple() +
                        Picks unique member from equiv expressions. + +
                        bddVarToCanonical() +
                        Picks unique member from equiv expressions. + +
                        bddVarToConst() +
                        Replaces variables with constants if possible. + +
                        beforep() +
                        Returns true iff the first argument precedes the second in + the clause order. + +
                        bitVectorAlloc() +
                        Allocates a bit vector. + +
                        bitVectorFree() +
                        Frees a bit vector. + +
                        build_dd() +
                        Builds a DD from a given order. + +
                        checkSymmInfo() +
                        Check symmetry condition. + +
                        computeClausesWithUniverse() +
                        Computes the two-literal clauses for a node. + +
                        computeClauses() +
                        Computes the two-literal clauses for a node. + +
                        computeLB() +
                        Computes a lower bound on the size of a BDD. + +
                        computeSavings() +
                        Counts the nodes that would be eliminated if a given node + were replaced by zero. + +
                        copyOrder() +
                        Copies the current variable order to array. + +
                        createResult() +
                        Builds a result for cache storage. + +
                        cuddAddApplyRecur() +
                        Performs the recursive step of Cudd_addApply. + +
                        cuddAddBddDoPattern() +
                        Performs the recursive step for Cudd_addBddPattern. + +
                        cuddAddCmplRecur() +
                        Performs the recursive step of Cudd_addCmpl. + +
                        cuddAddComposeRecur() +
                        Performs the recursive step of Cudd_addCompose. + +
                        cuddAddConstrainRecur() +
                        Performs the recursive step of Cudd_addConstrain. + +
                        cuddAddExistAbstractRecur() +
                        Performs the recursive step of Cudd_addExistAbstract. + +
                        cuddAddGeneralVectorComposeRecur() +
                        Performs the recursive step of Cudd_addGeneralVectorCompose. + +
                        cuddAddIteRecur() +
                        Implements the recursive step of Cudd_addIte(f,g,h). + +
                        cuddAddMonadicApplyRecur() +
                        Performs the recursive step of Cudd_addMonadicApply. + +
                        cuddAddNegateRecur() +
                        Implements the recursive step of Cudd_addNegate. + +
                        cuddAddNonSimComposeRecur() +
                        Performs the recursive step of Cudd_addNonSimCompose. + +
                        cuddAddOrAbstractRecur() +
                        Performs the recursive step of Cudd_addOrAbstract. + +
                        cuddAddOuterSumRecur() +
                        Performs the recursive step of Cudd_addOuterSum. + +
                        cuddAddPermuteRecur() +
                        Implements the recursive step of Cudd_addPermute. + +
                        cuddAddRestrictRecur() +
                        Performs the recursive step of Cudd_addRestrict. + +
                        cuddAddRoundOffRecur() +
                        Implements the recursive step of Cudd_addRoundOff. + +
                        cuddAddScalarInverseRecur() +
                        Performs the recursive step of addScalarInverse. + +
                        cuddAddUnivAbstractRecur() +
                        Performs the recursive step of Cudd_addUnivAbstract. + +
                        cuddAddVectorComposeRecur() +
                        Performs the recursive step of Cudd_addVectorCompose. + +
                        cuddAllocNode() +
                        Fast storage allocation for DdNodes in the table. + +
                        cuddAnnealing() +
                        Get new variable-order by simulated annealing algorithm. + +
                        cuddApaCountMintermAux() +
                        Performs the recursive step of Cudd_ApaCountMinterm. + +
                        cuddApaStCountfree() +
                        Frees the memory used to store the minterm counts recorded + in the visited table. + +
                        cuddBddAlignToZdd() +
                        Reorders BDD variables according to the order of the ZDD + variables. + +
                        cuddBddAndAbstractRecur() +
                        Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                        cuddBddAndRecur() +
                        Implements the recursive step of Cudd_bddAnd. + +
                        cuddBddBooleanDiffRecur() +
                        Performs the recursive steps of Cudd_bddBoleanDiff. + +
                        cuddBddCharToVect() +
                        Performs the recursive step of Cudd_bddCharToVect. + +
                        cuddBddClipAndAbsRecur() +
                        Approximates the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                        cuddBddClippingAndAbstract() +
                        Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
                        cuddBddClippingAndRecur() +
                        Implements the recursive step of Cudd_bddClippingAnd. + +
                        cuddBddClippingAnd() +
                        Approximates the conjunction of two BDDs f and g. + +
                        cuddBddClosestCube() +
                        Performs the recursive step of Cudd_bddClosestCube. + +
                        cuddBddComposeRecur() +
                        Performs the recursive step of Cudd_bddCompose. + +
                        cuddBddConstrainDecomp() +
                        Performs the recursive step of Cudd_bddConstrainDecomp. + +
                        cuddBddConstrainRecur() +
                        Performs the recursive step of Cudd_bddConstrain. + +
                        cuddBddExistAbstractRecur() +
                        Performs the recursive steps of Cudd_bddExistAbstract. + +
                        cuddBddIntersectRecur() +
                        Implements the recursive step of Cudd_bddIntersect. + +
                        cuddBddIsop() +
                        Performs the recursive step of Cudd_bddIsop. + +
                        cuddBddIteRecur() +
                        Implements the recursive step of Cudd_bddIte. + +
                        cuddBddLICBuildResult() +
                        Builds the result of Cudd_bddLICompaction. + +
                        cuddBddLICMarkEdges() +
                        Performs the edge marking step of Cudd_bddLICompaction. + +
                        cuddBddLICompaction() +
                        Performs safe minimization of a BDD. + +
                        cuddBddLiteralSetIntersectionRecur() +
                        Performs the recursive step of + Cudd_bddLiteralSetIntersection. + +
                        cuddBddMakePrime() +
                        Performs the recursive step of Cudd_bddMakePrime. + +
                        cuddBddNPAndRecur() +
                        Implements the recursive step of Cudd_bddAnd. + +
                        cuddBddPermuteRecur() +
                        Implements the recursive step of Cudd_bddPermute. + +
                        cuddBddRestrictRecur() +
                        Performs the recursive step of Cudd_bddRestrict. + +
                        cuddBddSqueeze() +
                        Performs the recursive step of Cudd_bddSqueeze. + +
                        cuddBddTransferRecur() +
                        Performs the recursive step of Cudd_bddTransfer. + +
                        cuddBddTransfer() +
                        Convert a BDD from a manager to another one. + +
                        cuddBddVarMapRecur() +
                        Implements the recursive step of Cudd_bddVarMap. + +
                        cuddBddVectorComposeRecur() +
                        Performs the recursive step of Cudd_bddVectorCompose. + +
                        cuddBddXorExistAbstractRecur() +
                        Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
                        cuddBddXorRecur() +
                        Implements the recursive step of Cudd_bddXor. + +
                        cuddBiasedUnderApprox() +
                        Applies the biased remapping underappoximation algorithm. + +
                        cuddCProjectionRecur() +
                        Performs the recursive step of Cudd_CProjection. + +
                        cuddCacheFlush() +
                        Flushes the cache. + +
                        cuddCacheInsert1() +
                        Inserts a result in the cache for a function with two + operands. + +
                        cuddCacheInsert2() +
                        Inserts a result in the cache for a function with two + operands. + +
                        cuddCacheInsert() +
                        Inserts a result in the cache for a function with three + operands. + +
                        cuddCacheLookup1Zdd() +
                        Looks up in the cache for the result of op applied to f. + +
                        cuddCacheLookup1() +
                        Looks up in the cache for the result of op applied to f. + +
                        cuddCacheLookup2Zdd() +
                        Looks up in the cache for the result of op applied to f + and g. + +
                        cuddCacheLookup2() +
                        Looks up in the cache for the result of op applied to f + and g. + +
                        cuddCacheLookupZdd() +
                        Looks up in the cache for the result of op applied to f, + g, and h. + +
                        cuddCacheLookup() +
                        Looks up in the cache for the result of op applied to f, + g, and h. + +
                        cuddCacheProfile() +
                        Computes and prints a profile of the cache usage. + +
                        cuddCacheResize() +
                        Resizes the cache. + +
                        cuddCheckCollisionOrdering() +
                        Checks whether a collision list is ordered. + +
                        cuddClearDeathRow() +
                        Clears the death row. + +
                        cuddCofactorRecur() +
                        Performs the recursive step of Cudd_Cofactor. + +
                        cuddCollectNodes() +
                        Recursively collects all the nodes of a DD in a symbol + table. + +
                        cuddComputeFloorLog2() +
                        Returns the floor of the logarithm to the base 2. + +
                        cuddConjunctsAux() +
                        Procedure to compute two conjunctive factors of f and place in *c1 and *c2. + +
                        cuddConstantLookup() +
                        Looks up in the cache for the result of op applied to f, + g, and h. + +
                        cuddDestroySubtables() +
                        Destroys the n most recently created subtables in a unique table. + +
                        cuddDoRebalance() +
                        Rebalances a red/black tree. + +
                        cuddDynamicAllocNode() +
                        Dynamically allocates a Node. + +
                        cuddEstimateCofactorSimple() +
                        Performs the recursive step of Cudd_CofactorEstimateSimple. + +
                        cuddEstimateCofactor() +
                        Performs the recursive step of Cudd_CofactorEstimate. + +
                        cuddExact() +
                        Exact variable ordering algorithm. + +
                        cuddFindParent() +
                        Searches the subtables above node for a parent. + +
                        cuddFreeTable() +
                        Frees the resources associated to a unique table. + +
                        cuddGarbageCollect() +
                        Performs garbage collection on the unique tables. + +
                        cuddGa() +
                        Genetic algorithm for DD reordering. + +
                        cuddGetBranches() +
                        Computes the children of g. + +
                        cuddHashTableGenericInsert() +
                        Inserts an item in a hash table. + +
                        cuddHashTableGenericLookup() +
                        Looks up a key consisting of one pointer in a hash table. + +
                        cuddHashTableGenericQuit() +
                        Shuts down a hash table. + +
                        cuddHashTableInit() +
                        Initializes a hash table. + +
                        cuddHashTableInsert1() +
                        Inserts an item in a hash table. + +
                        cuddHashTableInsert2() +
                        Inserts an item in a hash table. + +
                        cuddHashTableInsert3() +
                        Inserts an item in a hash table. + +
                        cuddHashTableInsert() +
                        Inserts an item in a hash table. + +
                        cuddHashTableLookup1() +
                        Looks up a key consisting of one pointer in a hash table. + +
                        cuddHashTableLookup2() +
                        Looks up a key consisting of two pointers in a hash table. + +
                        cuddHashTableLookup3() +
                        Looks up a key consisting of three pointers in a hash table. + +
                        cuddHashTableLookup() +
                        Looks up a key in a hash table. + +
                        cuddHashTableQuit() +
                        Shuts down a hash table. + +
                        cuddHashTableResize() +
                        Resizes a hash table. + +
                        cuddHeapProfile() +
                        Prints information about the heap. + +
                        cuddInitCache() +
                        Initializes the computed table. + +
                        cuddInitInteract() +
                        Initializes the interaction matrix. + +
                        cuddInitLinear() +
                        Initializes the linear transform matrix. + +
                        cuddInitTable() +
                        Creates and initializes the unique table. + +
                        cuddInsertSubtables() +
                        Inserts n new subtables in a unique table at level. + +
                        cuddIsInDeathRow() +
                        Checks whether a node is in the death row. + +
                        cuddLevelQueueDequeue() +
                        Remove an item from the front of a level queue. + +
                        cuddLevelQueueEnqueue() +
                        Inserts a new key in a level queue. + +
                        cuddLevelQueueFirst() +
                        Inserts the first key in a level queue. + +
                        cuddLevelQueueInit() +
                        Initializes a level queue. + +
                        cuddLevelQueueQuit() +
                        Shuts down a level queue. + +
                        cuddLinearAndSifting() +
                        BDD reduction based on combination of sifting and linear + transformations. + +
                        cuddLinearInPlace() +
                        Linearly combines two adjacent variables. + +
                        cuddLocalCacheAddToList() +
                        Inserts a local cache in the manager list. + +
                        cuddLocalCacheClearAll() +
                        Clears the local caches of a manager. + +
                        cuddLocalCacheClearDead() +
                        Clears the dead entries of the local caches of a manager. + +
                        cuddLocalCacheInit() +
                        Initializes a local computed table. + +
                        cuddLocalCacheInsert() +
                        Inserts a result in a local cache. + +
                        cuddLocalCacheLookup() +
                        Looks up in a local cache. + +
                        cuddLocalCacheProfile() +
                        Computes and prints a profile of a local cache usage. + +
                        cuddLocalCacheQuit() +
                        Shuts down a local computed table. + +
                        cuddLocalCacheRemoveFromList() +
                        Removes a local cache from the manager list. + +
                        cuddLocalCacheResize() +
                        Resizes a local cache. + +
                        cuddMakeBddFromZddCover() +
                        Converts a ZDD cover to a BDD. + +
                        cuddMinHammingDistRecur() +
                        Performs the recursive step of Cudd_MinHammingDist. + +
                        cuddNextHigh() +
                        Finds the next subtable with a larger index. + +
                        cuddNextLow() +
                        Finds the next subtable with a smaller index. + +
                        cuddNodeArrayRecur() +
                        Performs the recursive step of cuddNodeArray. + +
                        cuddNodeArray() +
                        Recursively collects all the nodes of a DD in an array. + +
                        cuddOrderedInsert() +
                        Inserts a DdNode in a red/black search tree. + +
                        cuddOrderedThread() +
                        Threads all the nodes of a search tree into a linear list. + +
                        cuddPrintNode() +
                        Prints out information on a node. + +
                        cuddPrintVarGroups() +
                        Prints the variable groups as a parenthesized list. + +
                        cuddP() +
                        Prints a DD to the standard output. One line per node is + printed. + +
                        cuddReclaimZdd() +
                        Brings children of a dead ZDD node back. + +
                        cuddReclaim() +
                        Brings children of a dead node back. + +
                        cuddRehash() +
                        Rehashes a unique subtable. + +
                        cuddRemapUnderApprox() +
                        Applies the remapping underappoximation algorithm. + +
                        cuddResizeLinear() +
                        Resizes the linear transform matrix. + +
                        cuddResizeTableZdd() +
                        Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index. + +
                        cuddSetInteract() +
                        Set interaction matrix entries. + +
                        cuddShrinkDeathRow() +
                        Shrinks the death row. + +
                        cuddShrinkSubtable() +
                        Shrinks a subtable. + +
                        cuddSifting() +
                        Implementation of Rudell's sifting algorithm. + +
                        cuddSlowTableGrowth() +
                        Adjusts parameters of a table to slow down its growth. + +
                        cuddSolveEqnRecur() +
                        Implements the recursive step of Cudd_SolveEqn. + +
                        cuddSplitSetRecur() +
                        Implements the recursive step of Cudd_SplitSet. + +
                        cuddStCountfree() +
                        Frees the memory used to store the minterm counts recorded + in the visited table. + +
                        cuddSubsetHeavyBranch() +
                        The main procedure that returns a subset by choosing the heavier + branch in the BDD. + +
                        cuddSubsetShortPaths() +
                        The outermost procedure to return a subset of the given BDD + with the shortest path lengths. + +
                        cuddSwapInPlace() +
                        Swaps two adjacent variables. + +
                        cuddSwapping() +
                        Reorders variables by a sequence of (non-adjacent) swaps. + +
                        cuddSymmCheck() +
                        Checks for symmetry of x and y. + +
                        cuddSymmSiftingConv() +
                        Symmetric sifting to convergence algorithm. + +
                        cuddSymmSifting() +
                        Symmetric sifting algorithm. + +
                        cuddTestInteract() +
                        Test interaction matrix entries. + +
                        cuddTimesInDeathRow() +
                        Counts how many times a node is in the death row. + +
                        cuddTreeSifting() +
                        Tree sifting algorithm. + +
                        cuddUnderApprox() +
                        Applies Tom Shiple's underappoximation algorithm. + +
                        cuddUniqueConst() +
                        Checks the unique table for the existence of a constant node. + +
                        cuddUniqueInterIVO() +
                        Wrapper for cuddUniqueInter that is independent of variable + ordering. + +
                        cuddUniqueInterZdd() +
                        Checks the unique table for the existence of an internal + ZDD node. + +
                        cuddUniqueInter() +
                        Checks the unique table for the existence of an internal node. + +
                        cuddUniqueLookup() +
                        Checks the unique table for the existence of an internal node. + +
                        cuddUpdateInteractionMatrix() +
                        Updates the interaction matrix. + +
                        cuddVerifySol() +
                        Implements the recursive step of Cudd_VerifySol. + +
                        cuddWindowReorder() +
                        Reorders by applying the method of the sliding window. + +
                        cuddXorLinear() +
                        XORs two rows of the linear transform matrix. + +
                        cuddZddAlignToBdd() +
                        Reorders ZDD variables according to the order of the BDD + variables. + +
                        cuddZddChangeAux() +
                        Performs the recursive step of Cudd_zddChange. + +
                        cuddZddChange() +
                        Substitutes a variable with its complement in a ZDD. + +
                        cuddZddComplement() +
                        Computes a complement of a ZDD node. + +
                        cuddZddCountDoubleStep() +
                        Performs the recursive step of Cudd_zddCountDouble. + +
                        cuddZddCountStep() +
                        Performs the recursive step of Cudd_zddCount. + +
                        cuddZddDagInt() +
                        Performs the recursive step of Cudd_zddDagSize. + +
                        cuddZddDiff() +
                        Performs the recursive step of Cudd_zddDiff. + +
                        cuddZddDivideF() +
                        Performs the recursive step of Cudd_zddDivideF. + +
                        cuddZddDivide() +
                        Performs the recursive step of Cudd_zddDivide. + +
                        cuddZddFreeUniv() +
                        Frees the ZDD universe. + +
                        cuddZddGetCofactors2() +
                        Computes the two-way decomposition of f w.r.t. v. + +
                        cuddZddGetCofactors3() +
                        Computes the three-way decomposition of f w.r.t. v. + +
                        cuddZddGetNegVarIndex() +
                        Returns the index of negative ZDD variable. + +
                        cuddZddGetNegVarLevel() +
                        Returns the level of negative ZDD variable. + +
                        cuddZddGetNodeIVO() +
                        Wrapper for cuddUniqueInterZdd that is independent of variable + ordering. + +
                        cuddZddGetNode() +
                        Wrapper for cuddUniqueInterZdd. + +
                        cuddZddGetPosVarIndex() +
                        Returns the index of positive ZDD variable. + +
                        cuddZddGetPosVarLevel() +
                        Returns the level of positive ZDD variable. + +
                        cuddZddInitUniv() +
                        Initializes the ZDD universe. + +
                        cuddZddIntersect() +
                        Performs the recursive step of Cudd_zddIntersect. + +
                        cuddZddIsop() +
                        Performs the recursive step of Cudd_zddIsop. + +
                        cuddZddIte() +
                        Performs the recursive step of Cudd_zddIte. + +
                        cuddZddLinearAux() +
                        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                        cuddZddLinearBackward() +
                        Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
                        cuddZddLinearDown() +
                        Sifts a variable down and applies the XOR transformation. + +
                        cuddZddLinearInPlace() +
                        Linearly combines two adjacent variables. + +
                        cuddZddLinearSifting() +
                        Implementation of the linear sifting algorithm for ZDDs. + +
                        cuddZddLinearUp() +
                        Sifts a variable up applying the XOR transformation. + +
                        cuddZddNextHigh() +
                        Finds the next subtable with a larger index. + +
                        cuddZddNextLow() +
                        Finds the next subtable with a smaller index. + +
                        cuddZddProduct() +
                        Performs the recursive step of Cudd_zddProduct. + +
                        cuddZddP() +
                        Prints a ZDD to the standard output. One line per node is + printed. + +
                        cuddZddSiftingAux() +
                        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                        cuddZddSiftingBackward() +
                        Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
                        cuddZddSiftingDown() +
                        Sifts a variable down. + +
                        cuddZddSiftingUp() +
                        Sifts a variable up. + +
                        cuddZddSifting() +
                        Implementation of Rudell's sifting algorithm. + +
                        cuddZddSubset0() +
                        Computes the negative cofactor of a ZDD w.r.t. a variable. + +
                        cuddZddSubset1() +
                        Computes the positive cofactor of a ZDD w.r.t. a variable. + +
                        cuddZddSwapInPlace() +
                        Swaps two adjacent variables. + +
                        cuddZddSwapping() +
                        Reorders variables by a sequence of (non-adjacent) swaps. + +
                        cuddZddSymmCheck() +
                        Checks for symmetry of x and y. + +
                        cuddZddSymmSiftingAux() +
                        Given x_low <= x <= x_high moves x up and down between the + boundaries. + +
                        cuddZddSymmSiftingBackward() +
                        Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
                        cuddZddSymmSiftingConvAux() +
                        Given x_low <= x <= x_high moves x up and down between the + boundaries. + +
                        cuddZddSymmSiftingConv() +
                        Symmetric sifting to convergence algorithm for ZDDs. + +
                        cuddZddSymmSifting_down() +
                        Moves x down until either it reaches the bound (x_high) or + the size of the ZDD heap increases too much. + +
                        cuddZddSymmSifting_up() +
                        Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much. + +
                        cuddZddSymmSifting() +
                        Symmetric sifting algorithm for ZDDs. + +
                        cuddZddSymmSummary() +
                        Counts numbers of symmetric variables and symmetry + groups. + +
                        cuddZddTreeSifting() +
                        Tree sifting algorithm for ZDDs. + +
                        cuddZddUnateProduct() +
                        Performs the recursive step of Cudd_zddUnateProduct. + +
                        cuddZddUndoMoves() +
                        Given a set of moves, returns the ZDD heap to the order + in effect before the moves. + +
                        cuddZddUnion() +
                        Performs the recursive step of Cudd_zddUnion. + +
                        cuddZddUniqueCompare() +
                        Comparison function used by qsort. + +
                        cuddZddWeakDivF() +
                        Performs the recursive step of Cudd_zddWeakDivF. + +
                        cuddZddWeakDiv() +
                        Performs the recursive step of Cudd_zddWeakDiv. + +
                        ddBddMaximallyExpand() +
                        Performs the recursive step of Cudd_bddMaximallyExpand. + +
                        ddBddShortestPathUnate() +
                        Performs shortest path computation on a unate function. + +
                        ddBddToAddRecur() +
                        Performs the recursive step for Cudd_BddToAdd. + +
                        ddCheckPermuation() +
                        Checks the BDD variable group tree before a shuffle. + +
                        ddClearFlag() +
                        Performs a DFS from f, clearing the LSB of the next + pointers. + +
                        ddClearGlobal() +
                        Scans the DD and clears the LSB of the next pointers. + +
                        ddClearGlobal() +
                        Scans the DD and clears the LSB of the next pointers. + +
                        ddClearLocal() +
                        Performs a DFS from f, clearing the LSB of the then pointers. + +
                        ddClearVars() +
                        Clears visited flags for variables. + +
                        ddCofMintermAux() +
                        Recursive Step for Cudd_CofMinterm function. + +
                        ddCountInternalMtrNodes() +
                        Counts the number of internal nodes of the group tree. + +
                        ddCountMintermAux() +
                        Performs the recursive step of Cudd_CountMinterm. + +
                        ddCountPathAux() +
                        Performs the recursive step of Cudd_CountPath. + +
                        ddCountPathsToNonZero() +
                        Performs the recursive step of Cudd_CountPathsToNonZero. + +
                        ddCountRoots() +
                        Counts the number of roots. + +
                        ddCreateGroup() +
                        Creates a group encompassing variables from x to y in the + DD table. + +
                        ddDagInt() +
                        Performs the recursive step of Cudd_DagSize. + +
                        ddDissolveGroup() +
                        Dissolves a group in the DD table. + +
                        ddDoDumpBlif() +
                        Performs the recursive step of Cudd_DumpBlif. + +
                        ddDoDumpDDcal() +
                        Performs the recursive step of Cudd_DumpDDcal. + +
                        ddDoDumpDaVinci() +
                        Performs the recursive step of Cudd_DumpDaVinci. + +
                        ddDoDumpFactoredForm() +
                        Performs the recursive step of Cudd_DumpFactoredForm. + +
                        ddEpdCountMintermAux() +
                        Performs the recursive step of Cudd_EpdCountMinterm. + +
                        ddEpdFree() +
                        Frees the memory used to store the minterm counts recorded + in the visited table. + +
                        ddExchange() +
                        This function is for exchanging two variables, x and y. + +
                        ddExtSymmCheck() +
                        Checks for extended symmetry of x and y. + +
                        ddFindEssentialRecur() +
                        Implements the recursive step of Cudd_FindEssential. + +
                        ddFindNodeHiLo() +
                        Finds the lower and upper bounds of the group represented + by treenode. + +
                        ddFindSupport() +
                        Recursively find the support of f. + +
                        ddFindTwoLiteralClausesRecur() +
                        Implements the recursive step of Cudd_FindTwoLiteralClauses. + +
                        ddGetLargestCubeUnate() +
                        Extracts largest prime of a unate function. + +
                        ddGroupMoveBackward() +
                        Undoes the swap two groups. + +
                        ddGroupMove() +
                        Swaps two groups and records the move. + +
                        ddGroupSiftingAux() +
                        Sifts one variable up and down until it has taken all + positions. Checks for aggregation. + +
                        ddGroupSiftingBackward() +
                        Determines the best position for a variables and returns + it there. + +
                        ddGroupSiftingDown() +
                        Sifts down a variable until it reaches position xHigh. + +
                        ddGroupSiftingUp() +
                        Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much. + +
                        ddGroupSifting() +
                        Sifts from treenode->low to treenode->high. + +
                        ddIsVarHandled() +
                        Checks whether a variables is already handled. + +
                        ddJumpingAux() +
                        Moves a variable to a specified position. + +
                        ddJumpingDown() +
                        This function is for jumping down. + +
                        ddJumpingUp() +
                        This function is for jumping up. + +
                        ddLeavesInt() +
                        Performs the recursive step of Cudd_CountLeaves. + +
                        ddLinearAndSiftingAux() +
                        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                        ddLinearAndSiftingBackward() +
                        Given a set of moves, returns the DD heap to the order + giving the minimum size. + +
                        ddLinearAndSiftingDown() +
                        Sifts a variable down and applies linear transformations. + +
                        ddLinearAndSiftingUp() +
                        Sifts a variable up and applies linear transformations. + +
                        ddLinearUniqueCompare() +
                        Comparison function used by qsort. + +
                        ddMergeGroups() +
                        Merges groups in the DD table. + +
                        ddNoCheck() +
                        Pretends to check two variables for aggregation. + +
                        ddPatchTree() +
                        Fixes a variable tree after the insertion of new subtables. + +
                        ddPermuteWindow3() +
                        Tries all the permutations of the three variables between + x and x+2 and retains the best. + +
                        ddPermuteWindow4() +
                        Tries all the permutations of the four variables between w + and w+3 and retains the best. + +
                        ddPickArbitraryMinterms() +
                        Performs the recursive step of Cudd_bddPickArbitraryMinterms. + +
                        ddPickRepresentativeCube() +
                        Finds a representative cube of a BDD. + +
                        ddPrintMintermAux() +
                        Performs the recursive step of Cudd_PrintMinterm. + +
                        ddRehashZdd() +
                        Rehashes a ZDD unique subtable. + +
                        ddReorderChildren() +
                        Reorders the children of a group tree node according to + the options. + +
                        ddReorderPostprocess() +
                        Cleans up at the end of reordering. + +
                        ddReorderPreprocess() +
                        Prepares the DD heap for dynamic reordering. + +
                        ddReportRefMess() +
                        Reports problem in garbage collection. + +
                        ddResetVarHandled() +
                        Resets a variable to be processed. + +
                        ddResizeTable() +
                        Increases the number of subtables in a unique table so + that it meets or exceeds index. + +
                        ddSecDiffCheck() +
                        Checks two variables for aggregation. + +
                        ddSetVarHandled() +
                        Sets a variable to already handled. + +
                        ddShuffle() +
                        Reorders variables according to a given permutation. + +
                        ddShuffle() +
                        Reorders variables according to a given permutation. + +
                        ddSiftUp() +
                        Moves one variable up. + +
                        ddSiftUp() +
                        Moves one variable up. + +
                        ddSiftingAux() +
                        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                        ddSiftingBackward() +
                        Given a set of moves, returns the DD heap to the position + giving the minimum size. + +
                        ddSiftingDown() +
                        Sifts a variable down. + +
                        ddSiftingUp() +
                        Sifts a variable up. + +
                        ddSuppInteract() +
                        Find the support of f. + +
                        ddSupportStep() +
                        Performs the recursive step of Cudd_Support. + +
                        ddSwapAny() +
                        Swaps any two variables. + +
                        ddSymmGroupMoveBackward() +
                        Undoes the swap of two groups. + +
                        ddSymmGroupMove() +
                        Swaps two groups. + +
                        ddSymmSiftingAux() +
                        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                        ddSymmSiftingBackward() +
                        Given a set of moves, returns the DD heap to the position + giving the minimum size. + +
                        ddSymmSiftingConvAux() +
                        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                        ddSymmSiftingDown() +
                        Moves x down until either it reaches the bound (xHigh) or + the size of the DD heap increases too much. + +
                        ddSymmSiftingUp() +
                        Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much. + +
                        ddSymmSummary() +
                        Counts numbers of symmetric variables and symmetry + groups. + +
                        ddSymmUniqueCompare() +
                        Comparison function used by qsort. + +
                        ddTreeSiftingAux() +
                        Visits the group tree and reorders each group. + +
                        ddUndoMoves() +
                        Given a set of moves, returns the DD heap to the order + in effect before the moves. + +
                        ddUniqueCompareGroup() +
                        Comparison function used by qsort. + +
                        ddUniqueCompare() +
                        Comparison function used by qsort. + +
                        ddUpdateInteract() +
                        Marks as interacting all pairs of variables that appear in + support. + +
                        ddUpdateMtrTree() +
                        Updates the BDD variable group tree before a shuffle. + +
                        ddVarGroupCheck() +
                        Checks for grouping of x and y. + +
                        ddWindow2() +
                        Reorders by applying a sliding window of width 2. + +
                        ddWindow3() +
                        Reorders by applying a sliding window of width 3. + +
                        ddWindow4() +
                        Reorders by applying a sliding window of width 4. + +
                        ddWindowConv2() +
                        Reorders by repeatedly applying a sliding window of width 2. + +
                        ddWindowConv3() +
                        Reorders by repeatedly applying a sliding window of width 3. + +
                        ddWindowConv4() +
                        Reorders by repeatedly applying a sliding window of width 4. + +
                        debugCheckParent() +
                        Reports an error if a (dead) node has a non-dead parent. + +
                        debugFindParent() +
                        Searches the subtables above node for its parents. + +
                        dp2() +
                        Performs the recursive step of cuddP. + +
                        emptyClauseSet() +
                        Returns an enpty set of clauses. + +
                        equalp() +
                        Returns true iff the two arguments are identical clauses. + +
                        find_best() +
                        Returns the index of the fittest individual. + +
                        fixVarTree() +
                        Fixes a variable group tree. + +
                        freeMatrix() +
                        Frees a two-dimensional matrix allocated by getMatrix. + +
                        freePathPair() +
                        Frees the entries of the visited symbol table. + +
                        gatherInfoAux() +
                        Recursively counts minterms and computes reference counts + of each node in the BDD. + +
                        gatherInfo() +
                        Gathers information about each node. + +
                        gcd() +
                        Returns the gcd of two integers. + +
                        getCube() +
                        Build a BDD for a largest cube of f. + +
                        getLargest() +
                        Finds the size of the largest cube(s) in a DD. + +
                        getLevelKeys() +
                        Returns the number of nodes at one level of a unique table. + +
                        getMatrix() +
                        Allocates a two-dimensional matrix of ints. + +
                        getMaxBinomial() +
                        Returns the maximum value of (n choose k) for a given n. + +
                        getPath() +
                        Build a BDD for a shortest path of f. + +
                        getShortest() +
                        Finds the length of the shortest path(s) in a DD. + +
                        hashDelete() +
                        Removes an item from the hash table of a level queue. + +
                        hashInsert() +
                        Inserts an item in the hash table of a level queue. + +
                        hashLookup() +
                        Looks up a key in the hash table of a level queue. + +
                        hashResize() +
                        Resizes the hash table of a level queue. + +
                        impliedp() +
                        Returns true iff either literal of a clause is in a set of + literals. + +
                        indexCompare() +
                        Compares indices for qsort. + +
                        initSymmInfo() +
                        Gathers symmetry information. + +
                        largest() +
                        Finds the largest DD in the population. + +
                        make_random() +
                        Generates the random sequences for the initial population. + +
                        mintermsFromUniverse() +
                        Recursive procedure to extract n mintems from constant 1. + +
                        oneliteralp() +
                        Returns true iff the argument is a one-literal clause. + +
                        pushDown() +
                        Pushes a variable in the order down to position "level." + +
                        rand_int() +
                        Generates a random number between 0 and the integer a. + +
                        random_generator() +
                        Random number generator. + +
                        restoreOrder() +
                        Restores the variable order in array by a series of sifts up. + +
                        roulette() +
                        Selects two parents with the roulette wheel method. + +
                        selectMintermsFromUniverse() +
                        This function prepares an array of variables which have not been + encountered so far when traversing the procedure cuddSplitSetRecur. + +
                        sentinelp() +
                        Returns true iff the argument is the sentinel clause. + +
                        separateCube() +
                        Separates cube from distance. + +
                        siftBackwardProb() +
                        Returns the DD to the best position encountered during + sifting if there was improvement. + +
                        sift_up() +
                        Moves one variable up. + +
                        stPathTableDdFree() +
                        Procedure to free te result dds stored in the NodeDist pages. + +
                        st_zdd_count_dbl_free() +
                        Frees the memory associated with the computed table of + Cudd_zddCountDouble. + +
                        st_zdd_countfree() +
                        Frees the memory associated with the computed table of + Cudd_zddCount. + +
                        stopping_criterion() +
                        Checks termination condition. + +
                        tlcInfoAlloc() +
                        Allocates a DdTlcInfo Structure. + +
                        updateEntry() +
                        Updates entry for a subset. + +
                        updateParity() +
                        Recursively update the parity of the paths reaching a node. + +
                        updateRefs() +
                        Update function reference counts. + +
                        updateUB() +
                        Updates the upper bound and saves the best order seen so far. + +
                        zddClearFlag() +
                        Performs a DFS from f, clearing the LSB of the next + pointers. + +
                        zddCountInternalMtrNodes() +
                        Counts the number of internal nodes of the group tree. + +
                        zddFindNodeHiLo() +
                        Finds the lower and upper bounds of the group represented + by treenode. + +
                        zddFixTree() +
                        Fixes the ZDD variable group tree after a shuffle. + +
                        zddGroupMoveBackward() +
                        Undoes the swap two groups. + +
                        zddGroupMove() +
                        Swaps two groups and records the move. + +
                        zddGroupSiftingAux() +
                        Sifts one variable up and down until it has taken all + positions. Checks for aggregation. + +
                        zddGroupSiftingBackward() +
                        Determines the best position for a variables and returns + it there. + +
                        zddGroupSiftingDown() +
                        Sifts down a variable until it reaches position xHigh. + +
                        zddGroupSiftingUp() +
                        Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much. + +
                        zddGroupSifting() +
                        Sifts from treenode->low to treenode->high. + +
                        zddMergeGroups() +
                        Merges groups in the DD table. + +
                        zddPortFromBddStep() +
                        Performs the recursive step of Cudd_zddPortFromBdd. + +
                        zddPortToBddStep() +
                        Performs the recursive step of Cudd_zddPortToBdd. + +
                        zddPrintCoverAux() +
                        Performs the recursive step of Cudd_zddPrintCover. + +
                        zddReorderChildren() +
                        Reorders the children of a group tree node according to + the options. + +
                        zddReorderPostprocess() +
                        Shrinks almost empty ZDD subtables at the end of reordering + to guarantee that they have a reasonable load factor. + +
                        zddReorderPreprocess() +
                        Prepares the ZDD heap for dynamic reordering. + +
                        zddShuffle() +
                        Reorders ZDD variables according to a given permutation. + +
                        zddSiftUp() +
                        Moves one ZDD variable up. + +
                        zddSupportStep() +
                        Performs the recursive step of Cudd_zddSupport. + +
                        zddSwapAny() +
                        Swaps any two variables. + +
                        zddTreeSiftingAux() +
                        Visits the group tree and reorders each group. + +
                        zddUniqueCompareGroup() +
                        Comparison function used by qsort. + +
                        zddVarToConst() +
                        Replaces variables with constants if possible (part of + canonical form). + +
                        zdd_group_move_backward() +
                        Undoes the swap of two groups. + +
                        zdd_group_move() +
                        Swaps two groups. + +
                        zdd_print_minterm_aux() +
                        Performs the recursive step of Cudd_zddPrintMinterm. + +
                        zdd_subset0_aux() +
                        Performs the recursive step of Cudd_zddSubset0. + +
                        zdd_subset1_aux() +
                        Performs the recursive step of Cudd_zddSubset1. + +
                        zp2() +
                        Performs the recursive step of cuddZddP. + +
                        () +
                        Adds node to the head of the free list. + +
                        () +
                        Adds node to the head of the free list. + +
                        () +
                        Adjusts the values of table limits. + +
                        () +
                        Clears a bit vector. + +
                        () +
                        Clears the 4 least significant bits of a pointer. + +
                        () +
                        Comparison of a function to the i-th ADD variable. + +
                        () +
                        Comparison of a pair of functions to the i-th ADD variable. + +
                        () +
                        Complements a DD if a condition is true. + +
                        () +
                        Complements a DD. + +
                        () +
                        Computes hash function for keys of one operand. + +
                        () +
                        Computes hash function for keys of three operands. + +
                        () +
                        Computes hash function for keys of two operands. + +
                        () +
                        Computes the absolute value of a number. + +
                        () +
                        Computes the hash value for a local cache. + +
                        () +
                        Computes the maximum of two numbers. + +
                        () +
                        Computes the minimum of two numbers. + +
                        () +
                        Decreases the reference count of a node, if it is not + saturated. + +
                        () +
                        Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL. + +
                        () +
                        Extract the least significant digit of a double digit. + +
                        () +
                        Extract the most significant digit of a double digit. + +
                        () +
                        Fast storage allocation for items in a hash table. + +
                        () +
                        Finds the current position of ZDD variable index in the + order. + +
                        () +
                        Finds the current position of variable index in the + order. + +
                        () +
                        Hash function for the cache for functions with two + operands. + +
                        () +
                        Hash function for the cache. + +
                        () +
                        Hash function for the table of a level queue. + +
                        () +
                        Hash function for the unique table. + +
                        () +
                        Increases the reference count of a node, if it is not + saturated. + +
                        () +
                        Iterates over the cubes of a decision diagram. + +
                        () +
                        Iterates over the nodes of a decision diagram. + +
                        () +
                        Iterates over the paths of a ZDD. + +
                        () +
                        Iterates over the primes of a Boolean function. + +
                        () +
                        Outputs a line of stats. + +
                        () +
                        Performs the left rotation for red/black trees. + +
                        () +
                        Performs the right rotation for red/black trees. + +
                        () +
                        Returns 1 if a pointer is complemented. + +
                        () +
                        Returns 1 if the absolute value of the difference of the two + arguments x and y is less than e. + +
                        () +
                        Returns 1 if the node is a constant node. + +
                        () +
                        Returns 1 if the node is a constant node. + +
                        () +
                        Returns the arithmetic 0 constant node. + +
                        () +
                        Returns the average fitness of the population. + +
                        () +
                        Returns the complemented version of a pointer. + +
                        () +
                        Returns the constant 1 node. + +
                        () +
                        Returns the current position in the order of variable + index. + +
                        () +
                        Returns the else child of an internal node. + +
                        () +
                        Returns the else child of an internal node. + +
                        () +
                        Returns the i-th entry of a bit vector. + +
                        () +
                        Returns the minus infinity constant node. + +
                        () +
                        Returns the plus infinity constant node. + +
                        () +
                        Returns the regular version of a pointer. + +
                        () +
                        Returns the then child of an internal node. + +
                        () +
                        Returns the then child of an internal node. + +
                        () +
                        Returns the value of a constant node. + +
                        () +
                        Returns the value of a constant node. + +
                        () +
                        Saturating decrement operator. + +
                        () +
                        Saturating increment operator. + +
                        () +
                        Sets the i-th entry of a bit vector to a value. + +
                        + +
                        + +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllByFile.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllByFile.html new file mode 100644 index 000000000..4076ddeae --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllByFile.html @@ -0,0 +1,13 @@ + +The cudd package for maintainers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllByFunc.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllByFunc.html new file mode 100644 index 000000000..76ec3ae05 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllByFunc.html @@ -0,0 +1,13 @@ + +The cudd package for maintainers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllDet.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllDet.html new file mode 100644 index 000000000..b700560e8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllDet.html @@ -0,0 +1,15754 @@ + +The cudd package: all functions + + + +
                        +
                        +
                        +
                        +static unsigned int 
                        +AssessPathLength(
                        +  unsigned int * pathLengthArray, array determining number of nodes belonging to the different path lengths
                        +  int  threshold, threshold to determine maximum allowable nodes in the subset
                        +  int  numVars, maximum number of variables
                        +  unsigned int * excess, number of nodes labeled maxpath required in the subset
                        +  FILE * fp where to write messages
                        +)
                        +
                        +
                        Chooses the maximum allowable path length under each node. + The corner cases are when the threshold is larger than the number + of nodes in the BDD iself, in which case 'numVars + 1' is returned. + If all nodes of a particular path length are needed, then the + maxpath returned is the next one with excess nodes = 0; +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddSubsetSP.c + +
                        +
                        +static int 
                        +BAapplyBias(
                        +  DdManager * dd, 
                        +  DdNode * f, 
                        +  DdNode * b, 
                        +  ApproxInfo * info, 
                        +  DdHashTable * cache 
                        +)
                        +
                        +
                        Finds don't care nodes by traversing f and b in parallel. + Returns the care status of the visited f node if successful; CARE_ERROR + otherwise. +

                        + +

                        Side Effects None +

                        + +

                        See Also cuddBiasedUnderApprox + + +
                        Defined in cuddApprox.c + +
                        +
                        +static int 
                        +BAmarkNodes(
                        +  DdManager * dd, manager
                        +  DdNode * f, function to be analyzed
                        +  ApproxInfo * info, info on BDD
                        +  int  threshold, when to stop approximating
                        +  double  quality1, minimum improvement for accepted changes when b=1
                        +  double  quality0 minimum improvement for accepted changes when b=0
                        +)
                        +
                        +
                        Marks nodes for remapping. Returns 1 if successful; 0 + otherwise. +

                        + +

                        Side Effects None +

                        + +

                        See Also cuddBiasedUnderApprox + + +
                        Defined in cuddApprox.c + +
                        +
                        +static Conjuncts * 
                        +BuildConjuncts(
                        +  DdManager * dd, 
                        +  DdNode * node, 
                        +  st_table * distanceTable, 
                        +  st_table * cacheTable, 
                        +  int  approxDistance, 
                        +  int  maxLocalRef, 
                        +  st_table * ghTable, 
                        +  st_table * mintermTable 
                        +)
                        +
                        +
                        Builds the conjuncts recursively, bottom up. Constants + are returned as (f, f). The cache is checked for previously computed + result. The decomposition points are determined by the local + reference count of this node and the longest distance from the + constant. At the decomposition point, the factors returned are (f, + 1). Recur on the two children. The order is determined by the + heavier branch. Combine the factors of the two children and pick the + one that already occurs in the gh table. Occurence in g is indicated + by value 1, occurence in h by 2, occurence in both 3. +

                        + +

                        See Also cuddConjunctsAux + + +
                        Defined in cuddDecomp.c + +
                        +
                        +static DdNode * 
                        +BuildSubsetBdd(
                        +  DdManager * dd, DD manager
                        +  GlobalInfo_t * gInfo, global information
                        +  st_table * pathTable, path table with path lengths and computed results
                        +  DdNode * node, current node
                        +  struct AssortedInfo * info, assorted information structure
                        +  st_table * subsetNodeTable table storing computed results
                        +)
                        +
                        +
                        Builds the BDD with nodes labeled with path length + under maxpath and as many nodes labeled maxpath as determined by the + threshold. The procedure uses the path table to determine which nodes + in the original bdd need to be retained. This procedure picks a + shortest path (tie break decided by taking the child with the shortest + distance to the constant) and recurs down the path till it reaches the + constant. the procedure then starts building the subset upward from + the constant. All nodes labeled by path lengths less than the given + maxpath are used to build the subset. However, in the case of nodes + that have label equal to maxpath, as many are chosen as required by + the threshold. This number is stored in the info structure in the + field thresholdReached. This field is decremented whenever a node + labeled maxpath is encountered and the nodes labeled maxpath are + aggregated in a maxpath table. As soon as the thresholdReached count + goes to 0, the shortest path from this node to the constant is found. + The extraction of nodes with the above labeling is based on the fact + that each node, labeled with a path length, P, has at least one child + labeled P or less. So extracting all nodes labeled a given path length + P ensures complete paths between the root and the constant. Extraction + of a partial number of nodes with a given path length may result in + incomplete paths and hence the additional number of nodes are grabbed + to complete the path. Since the Bdd is built bottom-up, other nodes + labeled maxpath do lie on complete paths. The procedure may cause the + subset to have a larger or smaller number of nodes than the specified + threshold. The increase in the number of nodes is caused by the + building of a subset and the reduction by recombination. However in + most cases, the recombination overshadows the increase and the + procedure returns a result with lower number of nodes than specified. + The subsetNodeTable is NIL when there is no hard limit on the number + of nodes. Further efforts towards keeping the subset closer to the + threshold number were abandoned in favour of keeping the procedure + simple and fast. +

                        + +

                        Side Effects SubsetNodeTable is changed if it is not NIL. +

                        + +

                        Defined in cuddSubsetSP.c + +
                        +
                        +static DdNode * 
                        +BuildSubsetBdd(
                        +  DdManager * dd, DD manager
                        +  DdNode * node, current node
                        +  int * size, current size of the subset
                        +  st_table * visitedTable, visited table storing all node data
                        +  int  threshold, 
                        +  st_table * storeTable, 
                        +  st_table * approxTable 
                        +)
                        +
                        +
                        The procedure carries out the building of the subset BDD + starting at the root. Using the three different counts labelling each node, + the procedure chooses the heavier branch starting from the root and keeps + track of the number of nodes it discards at each step, thus keeping count + of the size of the subset BDD dynamically. Once the threshold is satisfied, + the procedure then calls ITE to build the BDD. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddSubsetHB.c + +
                        +
                        + 
                        +CUDD_VALUE_TYPE *þvalueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +CUDD_VALUE_TYPE *þvalueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +CUDD_VALUE_TYPE þcþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +CUDD_VALUE_TYPE þepþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +CUDD_VALUE_TYPE þupperþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +CUDD_VALUE_TYPE þvalueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +CUDD_VALUE_TYPE þvalueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        +static Conjuncts * 
                        +CheckInTables(
                        +  DdNode * node, 
                        +  DdNode * g1, 
                        +  DdNode * h1, 
                        +  DdNode * g2, 
                        +  DdNode * h2, 
                        +  st_table * ghTable, 
                        +  st_table * cacheTable, 
                        +  int * outOfMem 
                        +)
                        +
                        +
                        Check if the two pairs exist in the table. If any of + the conjuncts do exist, store in the cache and return the + corresponding pair. +

                        + +

                        See Also ZeroCase +BuildConjuncts + + +
                        Defined in cuddDecomp.c + +
                        +
                        +static Conjuncts * 
                        +CheckTablesCacheAndReturn(
                        +  DdNode * node, 
                        +  DdNode * g, 
                        +  DdNode * h, 
                        +  st_table * ghTable, 
                        +  st_table * cacheTable 
                        +)
                        +
                        +
                        Check the tables for the existence of pair and return + one combination, cache the result. The assumption is that one of the + conjuncts is already in the tables. +

                        + +

                        Side Effects g and h referenced for the cache +

                        + +

                        See Also ZeroCase + + +
                        Defined in cuddDecomp.c + +
                        +
                        +static void 
                        +ConjunctsFree(
                        +  DdManager * dd, 
                        +  Conjuncts * factors 
                        +)
                        +
                        +
                        Free factors structure +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddDecomp.c + +
                        +
                        +static enum st_retval 
                        +CorrelCleanUp(
                        +  char * key, 
                        +  char * value, 
                        +  char * arg 
                        +)
                        +
                        +
                        Frees memory associated with hash table. Returns + ST_CONTINUE. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddBddCorr.c + +
                        +
                        +static int 
                        +CorrelCompare(
                        +  const char * key1, 
                        +  const char * key2 
                        +)
                        +
                        +
                        Compares two hash table entries. Returns 0 if they are + identical; 1 otherwise. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddBddCorr.c + +
                        +
                        +static int 
                        +CorrelHash(
                        +  char * key, 
                        +  int  modulus 
                        +)
                        +
                        +
                        Hashes a hash table entry. It is patterned after + st_strhash. Returns a value between 0 and modulus. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddBddCorr.c + +
                        +
                        +static double 
                        +CountMinterms(
                        +  DdNode * node, 
                        +  double  max, 
                        +  st_table * mintermTable, 
                        +  FILE * fp 
                        +)
                        +
                        +
                        Count the number of minterms of each node ina a BDD and + store it in a hash table. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddDecomp.c + +
                        +
                        +static NodeStat * 
                        +CreateBotDist(
                        +  DdNode * node, 
                        +  st_table * distanceTable 
                        +)
                        +
                        +
                        Get longest distance of node from constant. Returns the + distance of the root from the constant if successful; CUDD_OUT_OF_MEM + otherwise. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddDecomp.c + +
                        +
                        +static int 
                        +CreateBotDist(
                        +  DdNode * node, current node
                        +  st_table * pathTable, path table with path lengths
                        +  unsigned int * pathLengthArray, array that stores number of nodes belonging to a particular path length.
                        +  FILE * fp where to write messages
                        +)
                        +
                        +
                        Labels each node with the shortest distance from the constant. + This is done in a DFS search of the BDD. Each node has an odd + and even parity distance from the sink (since there exists paths to both + zero and one) which is less than MAXSHORTINT. At each node these distances + are updated using the minimum distance of its children from the constant. + SInce now both the length from the root and child is known, the minimum path + length(length of the shortest path between the root and the constant that + this node lies on) of this node can be calculated and used to update the + pathLengthArray +

                        + +

                        Side Effects Updates Path Table and path length array +

                        + +

                        See Also CreatePathTable +CreateTopDist +AssessPathLength + + +
                        Defined in cuddSubsetSP.c + +
                        +
                        +static st_table * 
                        +CreatePathTable(
                        +  DdManager * dd, DD manager
                        +  GlobalInfo_t * gInfo, global information
                        +  DdNode * node, root of function
                        +  unsigned int * pathLengthArray, array of path lengths to store nodes labeled with the various path lengths
                        +  FILE * fp where to write messages
                        +)
                        +
                        +
                        The outer procedure to label each node with its shortest + distance from the root and constant. Calls CreateTopDist and CreateBotDist. + The basis for computing the distance between root and constant is that + the distance may be the sum of even distances from the node to the root + and constant or the sum of odd distances from the node to the root and + constant. Both CreateTopDist and CreateBotDist create the odd and + even parity distances from the root and constant respectively. +

                        + +

                        Side Effects None +

                        + +

                        See Also CreateTopDist +CreateBotDist + + +
                        Defined in cuddSubsetSP.c + +
                        +
                        +static void 
                        +CreateTopDist(
                        +  DdManager * dd, DD manager
                        +  GlobalInfo_t * gInfo, global information
                        +  st_table * pathTable, hast table to store path lengths
                        +  int  parentPage, the pointer to the page on which the first parent in the queue is to be found.
                        +  int  parentQueueIndex, pointer to the first parent on the page
                        +  int  topLen, current distance from the root
                        +  DdNode ** childPage, pointer to the page on which the first child is to be added.
                        +  int  childQueueIndex, pointer to the first child
                        +  int  numParents, number of parents to process in this recursive call
                        +  FILE * fp where to write messages
                        +)
                        +
                        +
                        Labels each node with its shortest distance from the root. + This is done in a BFS search of the BDD. The nodes are processed + in a queue implemented as pages(array) to reduce memory fragmentation. + An entry is created for each node visited. The distance from the root + to the node with the corresponding parity is updated. The procedure + is called recursively each recusion level handling nodes at a given + level from the root. +

                        + +

                        Side Effects Creates entries in the pathTable +

                        + +

                        See Also CreatePathTable +CreateBotDist + + +
                        Defined in cuddSubsetSP.c + +
                        +
                        + 
                        +Cudd_AggregationType þgcþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +Cudd_HookType þwhereþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +Cudd_HookType þwhereþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +Cudd_HookType þwhereþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +Cudd_ReorderingType *þmethodþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +Cudd_ReorderingType *þmethodþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +Cudd_ReorderingType þmethodþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +Cudd_ReorderingType þmethodþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DD_PRFP þPifuncþfunction used to build Pi if it is NULL(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdApaDigit þliteralþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdApaNumber þbþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdApaNumber þdestþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdApaNumber þdiffþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdApaNumber þnumberþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdApaNumber þnumberþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdApaNumber þquotientþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdApaNumber þquotientþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdApaNumber þsecondþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdApaNumber þsumþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdGen *þgenþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdGen *þgenþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þddþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þmanagerþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þtableþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þtableþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þtableþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þtableþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdManager *þuniqueþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode ***þconjunctsþaddress of the array of conjuncts(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode ***þconjunctsþaddress of the array of conjuncts(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode ***þconjunctsþaddress of the array of conjuncts(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode ***þconjunctsþaddress of the first factor(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þonlyGþcube of variables only in g(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þvectorOffþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þvectorþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þvectorþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þvectorþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þyþarray of y variables(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þyþarray of y variables(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þyþarray of y variables(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þyþarray of y variables(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þyþarray of y variables(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þzdd_Iþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þzþarray of z variables(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode **þzþarray of z variables(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þBþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þBþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þDþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þDþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þPþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þPþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þQþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þQþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þQþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þQþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þUþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þYþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þbckþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcubeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcubeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcubeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcubeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcubeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcubeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcubeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þcþconstraint (care set)(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þepsilonþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþDD whose support is sought(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþDD whose support is sought(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþDD whose support size is sought(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþZDD whose support is sought(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþfunction against which to expand(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþfunction in which to remap variables(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þfþfunction of which the cube is to be made a prime(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þgþsecond operand(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þhþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þhþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þhþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þhþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þhþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þnþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þp_nodeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þphaseBddþcube of the phases(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þuþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þuþupper bound(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdNode *þvarþvariable(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +DdTlcInfo *þtþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +EpDouble *þepdþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +FILE *þfpþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +FILE *þfpþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +FILE *þfpþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +FILE *þfpþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +FILE *þfpþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +FILE *þfpþpointer to the dump file(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +FILE *þfpþpointer to the dump file(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +FILE *þfpþpointer to the dump file(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +FILE *þfpþpointer to the dump file(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +FILE *þfpþpointer to the dump file(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        +static enum st_retval 
                        +MarkCacheCleanUp(
                        +  char * key, 
                        +  char * value, 
                        +  char * arg 
                        +)
                        +
                        +
                        Frees memory associated with computed table of + cuddBddLICMarkEdges. Returns ST_CONTINUE. +

                        + +

                        Side Effects None +

                        + +

                        See Also Cudd_bddLICompaction + + +
                        Defined in cuddGenCof.c + +
                        +
                        +static int 
                        +MarkCacheCompare(
                        +  const char * ptr1, 
                        +  const char * ptr2 
                        +)
                        +
                        +
                        Comparison function for the computed table of + cuddBddLICMarkEdges. Returns 0 if the two nodes of the key are equal; 1 + otherwise. +

                        + +

                        Side Effects None +

                        + +

                        See Also Cudd_bddLICompaction + + +
                        Defined in cuddGenCof.c + +
                        +
                        +static int 
                        +MarkCacheHash(
                        +  char * ptr, 
                        +  int  modulus 
                        +)
                        +
                        +
                        Hash function for the computed table of + cuddBddLICMarkEdges. Returns the bucket number. +

                        + +

                        Side Effects None +

                        + +

                        See Also Cudd_bddLICompaction + + +
                        Defined in cuddGenCof.c + +
                        +
                        + 
                        +MtrNode *þtreeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +MtrNode *þtreeþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        +static int 
                        +PMX(
                        +  int  maxvar 
                        +)
                        +
                        +
                        Performs the crossover between two randomly chosen + parents, and creates two children, x1 and x2. Uses the Partially + Matched Crossover operator. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddGenetic.c + +
                        +
                        +static int 
                        +PairInTables(
                        +  DdNode * g, 
                        +  DdNode * h, 
                        +  st_table * ghTable 
                        +)
                        +
                        +
                        .Check whether the given pair is in the tables. gTable + and hTable are combined. + absence in both is indicated by 0, + presence in gTable is indicated by 1, + presence in hTable by 2 and + presence in both by 3. + The values returned by this function are PAIR_ST, + PAIR_CR, G_ST, G_CR, H_ST, H_CR, BOTH_G, BOTH_H, NONE. + PAIR_ST implies g in gTable and h in hTable + PAIR_CR implies g in hTable and h in gTable + G_ST implies g in gTable and h not in any table + G_CR implies g in hTable and h not in any table + H_ST implies h in hTable and g not in any table + H_CR implies h in gTable and g not in any table + BOTH_G implies both in gTable + BOTH_H implies both in hTable + NONE implies none in table; +

                        + +

                        See Also CheckTablesCacheAndReturn +CheckInTables + + +
                        Defined in cuddDecomp.c + +
                        +
                        +static Conjuncts * 
                        +PickOnePair(
                        +  DdNode * node, 
                        +  DdNode * g1, 
                        +  DdNode * h1, 
                        +  DdNode * g2, 
                        +  DdNode * h2, 
                        +  st_table * ghTable, 
                        +  st_table * cacheTable 
                        +)
                        +
                        +
                        Check the tables for the existence of pair and return + one combination, store in cache. The pair that has more pointers to + it is picked. An approximation of the number of local pointers is + made by taking the reference count of the pairs sent. +

                        + +

                        See Also ZeroCase +BuildConjuncts + + +
                        Defined in cuddDecomp.c + +
                        +
                        +static DdNode * 
                        +RAbuildSubset(
                        +  DdManager * dd, DD manager
                        +  DdNode * node, current node
                        +  ApproxInfo * info node info
                        +)
                        +
                        +
                        Builds the subset BDDfor cuddRemapUnderApprox. Based + on the info table, performs remapping or replacement at selected + nodes. Returns a pointer to the result if successful; NULL + otherwise. +

                        + +

                        Side Effects None +

                        + +

                        See Also cuddRemapUnderApprox + + +
                        Defined in cuddApprox.c + +
                        +
                        +static int 
                        +RAmarkNodes(
                        +  DdManager * dd, manager
                        +  DdNode * f, function to be analyzed
                        +  ApproxInfo * info, info on BDD
                        +  int  threshold, when to stop approximating
                        +  double  quality minimum improvement for accepted changes
                        +)
                        +
                        +
                        Marks nodes for remapping. Returns 1 if successful; 0 + otherwise. +

                        + +

                        Side Effects None +

                        + +

                        See Also cuddRemapUnderApprox + + +
                        Defined in cuddApprox.c + +
                        +
                        +static void 
                        +ResizeCountMintermPages(
                        +    
                        +)
                        +
                        +
                        Resize the number of pages allocated to store the minterm + counts. The procedure moves the counter to the next page when the + end of the page is reached and allocates new pages when necessary. +

                        + +

                        Side Effects Changes the size of minterm pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

                        + +

                        Defined in cuddSubsetHB.c + +
                        +
                        +static void 
                        +ResizeCountNodePages(
                        +    
                        +)
                        +
                        +
                        Resize the number of pages allocated to store the node counts. + The procedure moves the counter to the next page when the end of + the page is reached and allocates new pages when necessary. +

                        + +

                        Side Effects Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

                        + +

                        Defined in cuddSubsetHB.c + +
                        +
                        +static void 
                        +ResizeNodeDataPages(
                        +    
                        +)
                        +
                        +
                        Resize the number of pages allocated to store the node data + The procedure moves the counter to the next page when the end of + the page is reached and allocates new pages when necessary. +

                        + +

                        Side Effects Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

                        + +

                        Defined in cuddSubsetHB.c + +
                        +
                        +static void 
                        +ResizeNodeDistPages(
                        +  DdManager * dd, DD manager
                        +  GlobalInfo_t * gInfo global information
                        +)
                        +
                        +
                        Resize the number of pages allocated to store the distances + related to each node. The procedure moves the counter to the + next page when the end of the page is reached and allocates new + pages when necessary. +

                        + +

                        Side Effects Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

                        + +

                        Defined in cuddSubsetSP.c + +
                        +
                        +static void 
                        +ResizeQueuePages(
                        +  DdManager * dd, DD manager
                        +  GlobalInfo_t * gInfo global information
                        +)
                        +
                        +
                        Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd. The procedure moves the counter to the + next page when the end of the page is reached and allocates new + pages when necessary. +

                        + +

                        Side Effects Changes the size of pages, page, page index, maximum + number of pages freeing stuff in case of memory out. +

                        + +

                        Defined in cuddSubsetSP.c + +
                        +
                        +static void 
                        +StoreNodes(
                        +  st_table * storeTable, 
                        +  DdManager * dd, 
                        +  DdNode * node 
                        +)
                        +
                        +
                        rocedure to recursively store nodes that are retained in the subset. +

                        + +

                        Side Effects None +

                        + +

                        See Also StoreNodes + + +
                        Defined in cuddSubsetHB.c + +
                        +
                        +static double 
                        +SubsetCountMintermAux(
                        +  DdNode * node, function to analyze
                        +  double  max, number of minterms of constant 1
                        +  st_table * table visitedTable table
                        +)
                        +
                        +
                        Recursively counts minterms of each node in the DAG. + Similar to the cuddCountMintermAux which recursively counts the + number of minterms for the dag rooted at each node in terms of the + total number of variables (max). This procedure creates the node + data structure and stores the minterm count as part of the node + data structure. +

                        + +

                        Side Effects Creates structures of type node quality and fills the st_table +

                        + +

                        See Also SubsetCountMinterm + + +
                        Defined in cuddSubsetHB.c + +
                        +
                        +static st_table * 
                        +SubsetCountMinterm(
                        +  DdNode * node, function to be analyzed
                        +  int  nvars number of variables node depends on
                        +)
                        +
                        +
                        Counts minterms of each node in the DAG. Similar to the + Cudd_CountMinterm procedure except this returns the minterm count for + all the nodes in the bdd in an st_table. +

                        + +

                        Side Effects none +

                        + +

                        See Also SubsetCountMintermAux + + +
                        Defined in cuddSubsetHB.c + +
                        +
                        +static int 
                        +SubsetCountNodesAux(
                        +  DdNode * node, current node
                        +  st_table * table, table to update node count, also serves as visited table.
                        +  double  max maximum number of variables
                        +)
                        +
                        +
                        Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node. . Note that the same dag may be the lighter child of two + different nodes and have different counts. As with the minterm counts, + the node counts are stored in pages to be space efficient and the + address for these node counts are stored in an st_table associated + to each node. +

                        + +

                        Side Effects Updates the node data table with node counts +

                        + +

                        See Also SubsetCountNodes + + +
                        Defined in cuddSubsetHB.c + +
                        +
                        +static int 
                        +SubsetCountNodes(
                        +  DdNode * node, function to be analyzed
                        +  st_table * table, node quality table
                        +  int  nvars number of variables node depends on
                        +)
                        +
                        +
                        Counts the nodes under the current node and its lighter + child. Calls a recursive procedure to count the number of nodes of + a DAG rooted at a particular node and the number of nodes taken by its + lighter child. +

                        + +

                        Side Effects None +

                        + +

                        See Also SubsetCountNodesAux + + +
                        Defined in cuddSubsetHB.c + +
                        +
                        +static DdNode * 
                        +UAbuildSubset(
                        +  DdManager * dd, DD manager
                        +  DdNode * node, current node
                        +  ApproxInfo * info node info
                        +)
                        +
                        +
                        Builds the subset BDD. Based on the info table, + replaces selected nodes by zero. Returns a pointer to the result if + successful; NULL otherwise. +

                        + +

                        Side Effects None +

                        + +

                        See Also cuddUnderApprox + + +
                        Defined in cuddApprox.c + +
                        +
                        +static int 
                        +UAmarkNodes(
                        +  DdManager * dd, manager
                        +  DdNode * f, function to be analyzed
                        +  ApproxInfo * info, info on BDD
                        +  int  threshold, when to stop approximating
                        +  int  safe, enforce safe approximation
                        +  double  quality minimum improvement for accepted changes
                        +)
                        +
                        +
                        Marks nodes for replacement by zero. Returns 1 if successful; + 0 otherwise. +

                        + +

                        Side Effects None +

                        + +

                        See Also cuddUnderApprox + + +
                        Defined in cuddApprox.c + +
                        +
                        +static Conjuncts * 
                        +ZeroCase(
                        +  DdManager * dd, 
                        +  DdNode * node, 
                        +  Conjuncts * factorsNv, 
                        +  st_table * ghTable, 
                        +  st_table * cacheTable, 
                        +  int  switched 
                        +)
                        +
                        +
                        If one child is zero, do explicitly what Restrict does or better. + First separate a variable and its child in the base case. In case of a cube + times a function, separate the cube and function. As a last resort, look in + tables. +

                        + +

                        Side Effects Frees the BDDs in factorsNv. factorsNv itself is not freed + because it is freed above. +

                        + +

                        See Also BuildConjuncts + + +
                        Defined in cuddDecomp.c + +
                        +
                        +static DdNode * 
                        +addBddDoInterval(
                        +  DdManager * dd, 
                        +  DdNode * f, 
                        +  DdNode * l, 
                        +  DdNode * u 
                        +)
                        +
                        +
                        Performs the recursive step for Cudd_addBddInterval. + Returns a pointer to the BDD if successful; NULL otherwise. +

                        + +

                        Side Effects None +

                        + +

                        See Also addBddDoThreshold +addBddDoStrictThreshold + + +
                        Defined in cuddBridge.c + +
                        +
                        +static DdNode * 
                        +addBddDoIthBit(
                        +  DdManager * dd, 
                        +  DdNode * f, 
                        +  DdNode * index 
                        +)
                        +
                        +
                        Performs the recursive step for Cudd_addBddIthBit. + Returns a pointer to the BDD if successful; NULL otherwise. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddBridge.c + +
                        +
                        +static DdNode * 
                        +addBddDoStrictThreshold(
                        +  DdManager * dd, 
                        +  DdNode * f, 
                        +  DdNode * val 
                        +)
                        +
                        +
                        Performs the recursive step for Cudd_addBddStrictThreshold. + Returns a pointer to the BDD if successful; NULL otherwise. +

                        + +

                        Side Effects None +

                        + +

                        See Also addBddDoThreshold + + +
                        Defined in cuddBridge.c + +
                        +
                        +static DdNode * 
                        +addBddDoThreshold(
                        +  DdManager * dd, 
                        +  DdNode * f, 
                        +  DdNode * val 
                        +)
                        +
                        +
                        Performs the recursive step for Cudd_addBddThreshold. + Returns a pointer to the BDD if successful; NULL otherwise. +

                        + +

                        Side Effects None +

                        + +

                        See Also addBddDoStrictThreshold + + +
                        Defined in cuddBridge.c + +
                        +
                        +static int 
                        +addCheckPositiveCube(
                        +  DdManager * manager, 
                        +  DdNode * cube 
                        +)
                        +
                        +
                        Checks whether cube is an ADD representing the product of + positive literals. Returns 1 in case of success; 0 otherwise. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddAddAbs.c + +
                        +
                        +static DdNode * 
                        +addDoIthBit(
                        +  DdManager * dd, 
                        +  DdNode * f, 
                        +  DdNode * index 
                        +)
                        +
                        +
                        Performs the recursive step for Cudd_addIthBit. + Returns a pointer to the BDD if successful; NULL otherwise. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddAddFind.c + +
                        +
                        +static DdNode * 
                        +addMMRecur(
                        +  DdManager * dd, 
                        +  DdNode * A, 
                        +  DdNode * B, 
                        +  int  topP, 
                        +  int * vars 
                        +)
                        +
                        +
                        Performs the recursive step of Cudd_addMatrixMultiply. + Returns a pointer to the result if successful; NULL otherwise. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddMatMult.c + +
                        +
                        +static int 
                        +addMultiplicityGroups(
                        +  DdManager * dd, manager
                        +  MtrNode * treenode, current tree node
                        +  int  multiplicity, how many ZDD vars per BDD var
                        +  char * vmask, variable pairs for which a group has been already built
                        +  char * lmask levels for which a group has already been built
                        +)
                        +
                        +
                        Adds multiplicity groups to a ZDD variable group tree. + Returns 1 if successful; 0 otherwise. This function creates the groups + for set of ZDD variables (whose cardinality is given by parameter + multiplicity) that are created for each BDD variable in + Cudd_zddVarsFromBddVars. The crux of the matter is to determine the index + each new group. (The index of the first variable in the group.) + We first build all the groups for the children of a node, and then deal + with the ZDD variables that are directly attached to the node. The problem + for these is that the tree itself does not provide information on their + position inside the group. While we deal with the children of the node, + therefore, we keep track of all the positions they occupy. The remaining + positions in the tree can be freely used. Also, we keep track of all the + variables placed in the children. All the remaining variables are directly + attached to the group. We can then place any pair of variables not yet + grouped in any pair of available positions in the node. +

                        + +

                        Side Effects Changes the variable group tree. +

                        + +

                        See Also Cudd_zddVarsFromBddVars + + +
                        Defined in cuddAPI.c + +
                        +
                        +static DdNode * 
                        +addTriangleRecur(
                        +  DdManager * dd, 
                        +  DdNode * f, 
                        +  DdNode * g, 
                        +  int * vars, 
                        +  DdNode * cube 
                        +)
                        +
                        +
                        Performs the recursive step of Cudd_addTriangle. Returns + a pointer to the result if successful; NULL otherwise. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddMatMult.c + +
                        +
                        +static void 
                        +addVarToConst(
                        +  DdNode * f, 
                        +  DdNode ** gp, 
                        +  DdNode ** hp, 
                        +  DdNode * one, 
                        +  DdNode * zero 
                        +)
                        +
                        +
                        Replaces variables with constants if possible (part of + canonical form). +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddAddIte.c + +
                        +
                        +static DdNode * 
                        +addWalshInt(
                        +  DdManager * dd, 
                        +  DdNode ** x, 
                        +  DdNode ** y, 
                        +  int  n 
                        +)
                        +
                        +
                        Generates a Walsh matrix in ADD form. Returns a pointer + to the matrixi if successful; NULL otherwise. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddAddWalsh.c + +
                        +
                        +static int 
                        +array_compare(
                        +  const char * array1, 
                        +  const char * array2 
                        +)
                        +
                        +
                        Comparison function for the computed table. Returns 0 if + the two arrays are equal; 1 otherwise. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddGenetic.c + +
                        +
                        +static int 
                        +array_hash(
                        +  char * array, 
                        +  int  modulus 
                        +)
                        +
                        +
                        Hash function for the computed table. Returns the bucket + number. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddGenetic.c + +
                        +
                        +static double 
                        +bddAnnotateMintermCount(
                        +  DdManager * manager, 
                        +  DdNode * node, 
                        +  double  max, 
                        +  st_table * table 
                        +)
                        +
                        +
                        Annotates every node in the BDD node with its minterm count. + In this function, every node and the minterm count represented by it are + stored in a hash table. +

                        + +

                        Side Effects Fills up 'table' with the pair . +

                        + +

                        Defined in cuddSplit.c + +
                        +
                        +static int 
                        +bddCheckPositiveCube(
                        +  DdManager * manager, 
                        +  DdNode * cube 
                        +)
                        +
                        +
                        Returns 1 in case of success; 0 otherwise. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddBddAbs.c + +
                        +
                        +static double 
                        +bddCorrelationAux(
                        +  DdManager * dd, 
                        +  DdNode * f, 
                        +  DdNode * g, 
                        +  st_table * table 
                        +)
                        +
                        +
                        Performs the recursive step of Cudd_bddCorrelation. + Returns the fraction of minterms in the ON-set of the EXNOR of f and + g. +

                        + +

                        Side Effects None +

                        + +

                        See Also bddCorrelationWeightsAux + + +
                        Defined in cuddBddCorr.c + +
                        +
                        +static double 
                        +bddCorrelationWeightsAux(
                        +  DdManager * dd, 
                        +  DdNode * f, 
                        +  DdNode * g, 
                        +  double * prob, 
                        +  st_table * table 
                        +)
                        +
                        +
                        Performs the recursive step of Cudd_bddCorrelationWeigths. +

                        + +

                        Side Effects None +

                        + +

                        See Also bddCorrelationAux + + +
                        Defined in cuddBddCorr.c + +
                        +
                        +static void 
                        +bddFixTree(
                        +  DdManager * table, 
                        +  MtrNode * treenode 
                        +)
                        +
                        +
                        Fixes the BDD variable group tree after a + shuffle. Assumes that the order of the variables in a terminal node + has not been changed. +

                        + +

                        Side Effects Changes the BDD variable group tree. +

                        + +

                        Defined in cuddReorder.c + +
                        +
                        +static int 
                        +bddVarToCanonicalSimple(
                        +  DdManager * dd, 
                        +  DdNode ** fp, 
                        +  DdNode ** gp, 
                        +  DdNode ** hp, 
                        +  unsigned int * topfp, 
                        +  unsigned int * topgp, 
                        +  unsigned int * tophp 
                        +)
                        +
                        +
                        Makes sure the first two pointers are regular. This + mat require the complementation of the result, which is signaled by + returning 1 instead of 0. This function is simpler than the general + case because it assumes that no two arguments are the same or + complementary, and no argument is constant. +

                        + +

                        Side Effects None +

                        + +

                        See Also bddVarToConst +bddVarToCanonical + + +
                        Defined in cuddBddIte.c + +
                        +
                        +static int 
                        +bddVarToCanonical(
                        +  DdManager * dd, 
                        +  DdNode ** fp, 
                        +  DdNode ** gp, 
                        +  DdNode ** hp, 
                        +  unsigned int * topfp, 
                        +  unsigned int * topgp, 
                        +  unsigned int * tophp 
                        +)
                        +
                        +
                        Reduces 2 variable expressions to canonical form. +

                        + +

                        Side Effects None +

                        + +

                        See Also bddVarToConst +bddVarToCanonicalSimple + + +
                        Defined in cuddBddIte.c + +
                        +
                        +static void 
                        +bddVarToConst(
                        +  DdNode * f, 
                        +  DdNode ** gp, 
                        +  DdNode ** hp, 
                        +  DdNode * one 
                        +)
                        +
                        +
                        This function performs part of the transformation to + standard form by replacing variables with constants if possible. +

                        + +

                        Side Effects None +

                        + +

                        See Also bddVarToCanonical +bddVarToCanonicalSimple + + +
                        Defined in cuddBddIte.c + +
                        +
                        +static int 
                        +beforep(
                        +  DdHalfWord  var1a, 
                        +  short  phase1a, 
                        +  DdHalfWord  var1b, 
                        +  short  phase1b, 
                        +  DdHalfWord  var2a, 
                        +  short  phase2a, 
                        +  DdHalfWord  var2b, 
                        +  short  phase2b 
                        +)
                        +
                        +
                        Returns true iff the first argument precedes the second + in the clause order. A clause precedes another if its first lieral + precedes the first literal of the other, or if the first literals + are the same, and its second literal precedes the second literal of + the other clause. A literal precedes another if it has a higher + index, of if it has the same index, but it has lower phase. Phase 0 + is the positive phase, and it is lower than Phase 1 (negative + phase). +

                        + +

                        Side Effects None +

                        + +

                        See Also equalp + + +
                        Defined in cuddEssent.c + +
                        +
                        +static BitVector * 
                        +bitVectorAlloc(
                        +  int  size 
                        +)
                        +
                        +
                        Allocates a bit vector. The parameter size gives the + number of bits. This procedure allocates enough long's to hold the + specified number of bits. Returns a pointer to the allocated vector + if successful; NULL otherwise. +

                        + +

                        Side Effects None +

                        + +

                        See Also bitVectorClear +bitVectorFree + + +
                        Defined in cuddEssent.c + +
                        +
                        +static void 
                        +bitVectorFree(
                        +  BitVector * vector 
                        +)
                        +
                        +
                        Frees a bit vector. +

                        + +

                        Side Effects None +

                        + +

                        See Also bitVectorAlloc + + +
                        Defined in cuddEssent.c + +
                        +
                        +static int 
                        +build_dd(
                        +  DdManager * table, 
                        +  int  num, the index of the individual to be built
                        +  int  lower, 
                        +  int  upper 
                        +)
                        +
                        +
                        Builds a DD from a given order. This procedure also + sifts the final order and inserts into the array the size in nodes + of the result. Returns 1 if successful; 0 otherwise. +

                        + +

                        Side Effects None +

                        + +

                        Defined in cuddGenetic.c + +
                        +
                        + 
                        +char *þstringþ(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        + 
                        +char *þstrþpointer to string to use if != NULL(
                        +    
                        +)
                        +
                        +
                        +

                        + +

                        +
                        +static int 
                        +checkSymmInfo(
                        +  DdManager * table, 
                        +  DdHalfWord * symmInfo, 
                        +  int  index, 
                        +  int  level 
                        +)
                        +
                        +
                        Returns 1 if a variable is the one with the highest index + among those belonging to a symmetry group that are in the top part of + the BDD. The top part is given by level. +

                        + +

                        Side Effects None +

                        + +

                        See Also initSymmInfo + + +
                        Defined in cuddExact.c + +
                        +
                        +static DdTlcInfo * 
                        +computeClausesWithUniverse(
                        +  DdTlcInfo * Cres, list of clauses for child
                        +  DdHalfWord  label, variable labeling the current node
                        +  short  phase 0 if E child is zero; 1 if T child is zero
                        +)
                        +
                        +
                        Computes the two-literal clauses for a node with a zero + child, given the clauses for its other child and the label of the + node. Returns a pointer to a TclInfo structure if successful; NULL + otherwise. +

                        + +

                        Side Effects None +

                        + +

                        See Also computeClauses + + +
                        Defined in cuddEssent.c + +
                        +
                        +static DdTlcInfo * 
                        +computeClauses(
                        +  DdTlcInfo * Tres, list of clauses for T child
                        +  DdTlcInfo * Eres, list of clauses for E child
                        +  DdHalfWord  label, variable labeling the current node
                        +  int  size number of variables in the manager
                        +)
                        +
                        +
                        Computes the two-literal clauses for a node given the + clauses for its children and the label of the node. Returns a + pointer to a TclInfo structure if successful; NULL otherwise. +

                        + +

                        Side Effects None +

                        + +

                        See Also computeClausesWithUniverse + + +
                        Defined in cuddEssent.c + +
                        +
                        +static int 
                        +computeLB(
                        +  DdManager * table, manager
                        +  DdHalfWord * order, optimal order for the subset
                        +  int  roots, roots between lower and upper
                        +  int  cost, minimum cost for the subset
                        +  int  lower, lower level to be reordered
                        +  int  upper, upper level to be reordered
                        +  int  level offset for the current top bottom var
                        +)
                        +
                        +
                        Computes a lower bound on the size of a BDD from the + following factors: +
                          +
                        • size of the lower part of it; +
                        • size of the part of the upper part not subjected to reordering; +
                        • number of roots in the part of the BDD subjected to reordering; +
                        • variable in the support of the roots in the upper part of the + BDD subjected to reordering. +
                            +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddExact.c + +
                            +
                            +static int 
                            +computeSavings(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * skip, 
                            +  ApproxInfo * info, 
                            +  DdLevelQueue * queue 
                            +)
                            +
                            +
                            Counts the nodes that would be eliminated if a given + node were replaced by zero. This procedure uses a queue passed by + the caller for efficiency: since the queue is left empty at the + endof the search, it can be reused as is by the next search. Returns + the count (always striclty positive) if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also UAmarkNodes +RAmarkNodes +BAmarkNodes + + +
                            Defined in cuddApprox.c + +
                            +
                            +static void 
                            +copyOrder(
                            +  DdManager * table, 
                            +  int * array, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Copies the current variable order to array. + At the same time inverts the permutation. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAnneal.c + +
                            +
                            +static DdNode * 
                            +createResult(
                            +  DdManager * dd, 
                            +  unsigned int  index, 
                            +  unsigned int  phase, 
                            +  DdNode * cube, 
                            +  CUDD_VALUE_TYPE  distance 
                            +)
                            +
                            +
                            Builds a result for cache storage. Returns a pointer + to the resulting ADD if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddBddClosestCube +separateCube + + +
                            Defined in cuddPriority.c + +
                            +
                            +DdNode * 
                            +cuddAddApplyRecur(
                            +  DdManager * dd, 
                            +  DD_AOP  op, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_addApply. Returns a + pointer to the result if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddAddMonadicApplyRecur + + +
                            Defined in cuddAddApply.c + +
                            +
                            +DdNode * 
                            +cuddAddBddDoPattern(
                            +  DdManager * dd, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Performs the recursive step for Cudd_addBddPattern. Returns a + pointer to the resulting BDD if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddBridge.c + +
                            +
                            +DdNode * 
                            +cuddAddCmplRecur(
                            +  DdManager * dd, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_addCmpl. Returns a + pointer to the resulting ADD if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_addCmpl + + +
                            Defined in cuddAddIte.c + +
                            +
                            +DdNode * 
                            +cuddAddComposeRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * proj 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_addCompose. + Returns the composed BDD if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_addCompose + + +
                            Defined in cuddCompose.c + +
                            +
                            +DdNode * 
                            +cuddAddConstrainRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * c 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_addConstrain. + Returns a pointer to the result if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_addConstrain + + +
                            Defined in cuddGenCof.c + +
                            +
                            +DdNode * 
                            +cuddAddExistAbstractRecur(
                            +  DdManager * manager, 
                            +  DdNode * f, 
                            +  DdNode * cube 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_addExistAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAddAbs.c + +
                            +
                            +static DdNode * 
                            +cuddAddGeneralVectorComposeRecur(
                            +  DdManager * dd, DD manager
                            +  DdHashTable * table, computed table
                            +  DdNode * f, ADD in which to compose
                            +  DdNode ** vectorOn, functions to substitute for x_i
                            +  DdNode ** vectorOff, functions to substitute for x_i'
                            +  int  deepest depth of deepest substitution
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_addGeneralVectorCompose. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCompose.c + +
                            +
                            +DdNode * 
                            +cuddAddIteRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * h 
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_addIte(f,g,h). + Returns a pointer to the resulting ADD if successful; NULL + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_addIte + + +
                            Defined in cuddAddIte.c + +
                            +
                            +DdNode * 
                            +cuddAddMonadicApplyRecur(
                            +  DdManager * dd, 
                            +  DD_MAOP  op, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_addMonadicApply. Returns a + pointer to the result if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddAddApplyRecur + + +
                            Defined in cuddAddApply.c + +
                            +
                            +DdNode * 
                            +cuddAddNegateRecur(
                            +  DdManager * dd, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_addNegate. + Returns a pointer to the result. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAddNeg.c + +
                            +
                            +static DdNode * 
                            +cuddAddNonSimComposeRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode ** vector, 
                            +  DdNode * key, 
                            +  DdNode * cube, 
                            +  int  lastsub 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_addNonSimCompose. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCompose.c + +
                            +
                            +DdNode * 
                            +cuddAddOrAbstractRecur(
                            +  DdManager * manager, 
                            +  DdNode * f, 
                            +  DdNode * cube 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_addOrAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAddAbs.c + +
                            +
                            +static DdNode * 
                            +cuddAddOuterSumRecur(
                            +  DdManager * dd, 
                            +  DdNode * M, 
                            +  DdNode * r, 
                            +  DdNode * c 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_addOuterSum. + Returns a pointer to the result if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddMatMult.c + +
                            +
                            +static DdNode * 
                            +cuddAddPermuteRecur(
                            +  DdManager * manager, DD manager
                            +  DdHashTable * table, computed table
                            +  DdNode * node, ADD to be reordered
                            +  int * permut permutation array
                            +)
                            +
                            +
                            Recursively puts the ADD in the order given in the + array permut. Checks for trivial cases to terminate recursion, then + splits on the children of this node. Once the solutions for the + children are obtained, it puts into the current position the node + from the rest of the ADD that should be here. Then returns this ADD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper + position is reached in the recursion tree.

                            + The DdNode * that is returned is the same ADD as passed in as node, + but in the new order. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_addPermute +cuddBddPermuteRecur + + +
                            Defined in cuddCompose.c + +
                            +
                            +DdNode * 
                            +cuddAddRestrictRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * c 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_addRestrict. + Returns the restricted ADD if successful; otherwise NULL. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_addRestrict + + +
                            Defined in cuddGenCof.c + +
                            +
                            +DdNode * 
                            +cuddAddRoundOffRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  double  trunc 
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_addRoundOff. + Returns a pointer to the result. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAddNeg.c + +
                            +
                            +DdNode * 
                            +cuddAddScalarInverseRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * epsilon 
                            +)
                            +
                            +
                            Returns a pointer to the resulting ADD in case of + success. Returns NULL if any discriminants smaller than epsilon is + encountered. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAddInv.c + +
                            +
                            +DdNode * 
                            +cuddAddUnivAbstractRecur(
                            +  DdManager * manager, 
                            +  DdNode * f, 
                            +  DdNode * cube 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_addUnivAbstract. + Returns the ADD obtained by abstracting the variables of cube from f, + if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAddAbs.c + +
                            +
                            +static DdNode * 
                            +cuddAddVectorComposeRecur(
                            +  DdManager * dd, DD manager
                            +  DdHashTable * table, computed table
                            +  DdNode * f, ADD in which to compose
                            +  DdNode ** vector, functions to substitute
                            +  int  deepest depth of deepest substitution
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_addVectorCompose. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCompose.c + +
                            +
                            +DdNode * 
                            +cuddAllocNode(
                            +  DdManager * unique 
                            +)
                            +
                            +
                            Fast storage allocation for DdNodes in the table. The + first 4 bytes of a chunk contain a pointer to the next block; the + rest contains DD_MEM_CHUNK spaces for DdNodes. Returns a pointer to + a new node if successful; NULL is memory is full. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddDynamicAllocNode + + +
                            Defined in cuddTable.c + +
                            +
                            +int 
                            +cuddAnnealing(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Get x, y by random selection. Choose either + exchange or jump randomly. In case of jump, choose between jump_up + and jump_down randomly. Do exchange or jump and get optimal case. + Loop until there is no improvement or temperature reaches + minimum. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAnneal.c + +
                            +
                            +static DdApaNumber 
                            +cuddApaCountMintermAux(
                            +  DdNode * node, 
                            +  int  digits, 
                            +  DdApaNumber  max, 
                            +  DdApaNumber  min, 
                            +  st_table * table 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_ApaCountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. + Uses the identity |f'| = max - |f|. + The procedure expects the argument "node" to be a regular pointer, and + guarantees this condition is met in the recursive calls. + For efficiency, the result of a call is cached only if the node has + a reference count greater than 1. + Returns the number of minterms of the function rooted at node. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddApa.c + +
                            +
                            +static enum st_retval 
                            +cuddApaStCountfree(
                            +  char * key, 
                            +  char * value, 
                            +  char * arg 
                            +)
                            +
                            +
                            Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddApa.c + +
                            +
                            +int 
                            +cuddBddAlignToZdd(
                            +  DdManager * table DD manager
                            +)
                            +
                            +
                            Reorders BDD variables according to the order of the + ZDD variables. This function can be called at the end of ZDD + reordering to insure that the order of the BDD variables is + consistent with the order of the ZDD variables. The number of ZDD + variables must be a multiple of the number of BDD variables. Let + M be the ratio of the two numbers. cuddBddAlignToZdd + then considers the ZDD variables from M*i to + (M+1)*i-1 as corresponding to BDD variable + i. This function should be normally called from + Cudd_zddReduceHeap, which clears the cache. Returns 1 in case of + success; 0 otherwise. +

                            + +

                            Side Effects Changes the BDD variable order for all diagrams and performs + garbage collection of the BDD unique table. +

                            + +

                            See Also Cudd_ShuffleHeap +Cudd_zddReduceHeap + + +
                            Defined in cuddReorder.c + +
                            +
                            +DdNode * 
                            +cuddBddAndAbstractRecur(
                            +  DdManager * manager, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * cube 
                            +)
                            +
                            +
                            Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddAndAbstract + + +
                            Defined in cuddAndAbs.c + +
                            +
                            +DdNode * 
                            +cuddBddAndRecur(
                            +  DdManager * manager, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_bddAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddAnd + + +
                            Defined in cuddBddIte.c + +
                            +
                            +DdNode * 
                            +cuddBddBooleanDiffRecur(
                            +  DdManager * manager, 
                            +  DdNode * f, 
                            +  DdNode * var 
                            +)
                            +
                            +
                            Performs the recursive steps of Cudd_bddBoleanDiff. + Returns the BDD obtained by XORing the cofactors of f with respect to + var if successful; NULL otherwise. Exploits the fact that dF/dx = + dF'/dx. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddBddAbs.c + +
                            +
                            +static DdNode * 
                            +cuddBddCharToVect(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * x 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_bddCharToVect. + This function maintains the invariant that f is non-zero. + Returns the i-th component of the vector if successful; otherwise NULL. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddCharToVect + + +
                            Defined in cuddGenCof.c + +
                            +
                            +static DdNode * 
                            +cuddBddClipAndAbsRecur(
                            +  DdManager * manager, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * cube, 
                            +  int  distance, 
                            +  int  direction 
                            +)
                            +
                            +
                            Approximates the AND of two BDDs and simultaneously + abstracts the variables in cube. The variables are existentially + abstracted. Returns a pointer to the result is successful; NULL + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddClippingAndAbstract + + +
                            Defined in cuddClip.c + +
                            +
                            +DdNode * 
                            +cuddBddClippingAndAbstract(
                            +  DdManager * dd, manager
                            +  DdNode * f, first conjunct
                            +  DdNode * g, second conjunct
                            +  DdNode * cube, cube of variables to be abstracted
                            +  int  maxDepth, maximum recursion depth
                            +  int  direction under (0) or over (1) approximation
                            +)
                            +
                            +
                            Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddClippingAndAbstract + + +
                            Defined in cuddClip.c + +
                            +
                            +static DdNode * 
                            +cuddBddClippingAndRecur(
                            +  DdManager * manager, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  int  distance, 
                            +  int  direction 
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_bddClippingAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddBddClippingAnd + + +
                            Defined in cuddClip.c + +
                            +
                            +DdNode * 
                            +cuddBddClippingAnd(
                            +  DdManager * dd, manager
                            +  DdNode * f, first conjunct
                            +  DdNode * g, second conjunct
                            +  int  maxDepth, maximum recursion depth
                            +  int  direction under (0) or over (1) approximation
                            +)
                            +
                            +
                            Approximates the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddClippingAnd + + +
                            Defined in cuddClip.c + +
                            +
                            +DdNode * 
                            +cuddBddClosestCube(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  CUDD_VALUE_TYPE  bound 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_bddClosestCube. + Returns the cube if succesful; NULL otherwise. The procedure uses a + four-way recursion to examine all four combinations of cofactors of + f and g according to the following formula. +
                            +    H(f,g) = min(H(ft,gt), H(fe,ge), H(ft,ge)+1, H(fe,gt)+1)
                            +  
                            + Bounding is based on the following observations. +
                              +
                            • If we already found two points at distance 0, there is no point in + continuing. Furthermore, +
                            • If F == not(G) then the best we can hope for is a minimum distance + of 1. If we have already found two points at distance 1, there is + no point in continuing. (Indeed, H(F,G) == 1 in this case. We + have to continue, though, to find the cube.) +
                            + The variable bound is set at the largest value of the distance + that we are still interested in. Therefore, we desist when +
                            +    (bound == -1) and (F != not(G)) or (bound == 0) and (F == not(G)).
                            +  
                            + If we were maximally aggressive in using the bound, we would always + set the bound to the minimum distance seen thus far minus one. That + is, we would maintain the invariant +
                            +    bound < minD,
                            +  
                            + except at the very beginning, when we have no value for + minD.

                            + + However, we do not use bound < minD when examining the + two negative cofactors, because we try to find a large cube at + minimum distance. To do so, we try to find a cube in the negative + cofactors at the same or smaller distance from the cube found in the + positive cofactors.

                            + + When we compute H(ft,ge) and H(fe,gt) we + know that we are going to add 1 to the result of the recursive call + to account for the difference in the splitting variable. Therefore, + we decrease the bound correspondingly.

                            + + Another important observation concerns the need of examining all + four pairs of cofators only when both f and + g depend on the top variable.

                            + + Suppose gt == ge == g. (That is, g does + not depend on the top variable.) Then +

                            +    H(f,g) = min(H(ft,g), H(fe,g), H(ft,g)+1, H(fe,g)+1)
                            +	   = min(H(ft,g), H(fe,g)) .
                            +  
                            + Therefore, under these circumstances, we skip the two "cross" cases.

                            + + An interesting feature of this function is the scheme used for + caching the results in the global computed table. Since we have a + cube and a distance, we combine them to form an ADD. The + combination replaces the zero child of the top node of the cube with + the negative of the distance. (The use of the negative is to avoid + ambiguity with 1.) The degenerate cases (zero and one) are treated + specially because the distance is known (0 for one, and infinity for + zero). +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddClosestCube + + +
                            Defined in cuddPriority.c + +
                            +
                            +DdNode * 
                            +cuddBddComposeRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * proj 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_bddCompose. + Exploits the fact that the composition of f' with g + produces the complement of the composition of f with g to better + utilize the cache. Returns the composed BDD if successful; NULL + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddCompose + + +
                            Defined in cuddCompose.c + +
                            +
                            +static int 
                            +cuddBddConstrainDecomp(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode ** decomp 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_bddConstrainDecomp. + Returns f super (i) if successful; otherwise NULL. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddConstrainDecomp + + +
                            Defined in cuddGenCof.c + +
                            +
                            +DdNode * 
                            +cuddBddConstrainRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * c 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_bddConstrain. + Returns a pointer to the result if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddConstrain + + +
                            Defined in cuddGenCof.c + +
                            +
                            +DdNode * 
                            +cuddBddExistAbstractRecur(
                            +  DdManager * manager, 
                            +  DdNode * f, 
                            +  DdNode * cube 
                            +)
                            +
                            +
                            Performs the recursive steps of Cudd_bddExistAbstract. + Returns the BDD obtained by abstracting the variables + of cube from f if successful; NULL otherwise. It is also used by + Cudd_bddUnivAbstract. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddExistAbstract +Cudd_bddUnivAbstract + + +
                            Defined in cuddBddAbs.c + +
                            +
                            +DdNode * 
                            +cuddBddIntersectRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_bddIntersect. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddIntersect + + +
                            Defined in cuddBddIte.c + +
                            +
                            +DdNode	* 
                            +cuddBddIsop(
                            +  DdManager * dd, 
                            +  DdNode * L, 
                            +  DdNode * U 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_bddIsop. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddIsop + + +
                            Defined in cuddZddIsop.c + +
                            +
                            +DdNode * 
                            +cuddBddIteRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * h 
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_bddIte. Returns a + pointer to the resulting BDD. NULL if the intermediate result blows + up or if reordering occurs. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddBddIte.c + +
                            +
                            +static DdNode * 
                            +cuddBddLICBuildResult(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  st_table * cache, 
                            +  st_table * table 
                            +)
                            +
                            +
                            Builds the results of Cudd_bddLICompaction. + Returns a pointer to the minimized BDD if successful; otherwise NULL. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddLICompaction +cuddBddLICMarkEdges + + +
                            Defined in cuddGenCof.c + +
                            +
                            +static int 
                            +cuddBddLICMarkEdges(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * c, 
                            +  st_table * table, 
                            +  st_table * cache 
                            +)
                            +
                            +
                            Performs the edge marking step of Cudd_bddLICompaction. + Returns the LUB of the markings of the two outgoing edges of f + if successful; otherwise CUDD_OUT_OF_MEM. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddLICompaction +cuddBddLICBuildResult + + +
                            Defined in cuddGenCof.c + +
                            +
                            +DdNode * 
                            +cuddBddLICompaction(
                            +  DdManager * dd, manager
                            +  DdNode * f, function to be minimized
                            +  DdNode * c constraint (care set)
                            +)
                            +
                            +
                            Performs safe minimization of a BDD. Given the BDD + f of a function to be minimized and a BDD + c representing the care set, Cudd_bddLICompaction + produces the BDD of a function that agrees with f + wherever c is 1. Safe minimization means that the size + of the result is guaranteed not to exceed the size of + f. This function is based on the DAC97 paper by Hong et + al.. Returns a pointer to the result if successful; NULL + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddLICompaction + + +
                            Defined in cuddGenCof.c + +
                            +
                            +DdNode * 
                            +cuddBddLiteralSetIntersectionRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Performs the recursive step of + Cudd_bddLiteralSetIntersection. Scans the cubes for common variables, + and checks whether they agree in phase. Returns a pointer to the + resulting cube if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLiteral.c + +
                            +
                            +DdNode * 
                            +cuddBddMakePrime(
                            +  DdManager * dd, manager
                            +  DdNode * cube, cube to be expanded
                            +  DdNode * f function of which the cube is to be made a prime
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_bddMakePrime. + Returns the prime if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSat.c + +
                            +
                            +DdNode * 
                            +cuddBddNPAndRecur(
                            +  DdManager * manager, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_bddNPAnd. + Returns a pointer to the result is successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddNPAnd + + +
                            Defined in cuddGenCof.c + +
                            +
                            +static DdNode * 
                            +cuddBddPermuteRecur(
                            +  DdManager * manager, DD manager
                            +  DdHashTable * table, computed table
                            +  DdNode * node, BDD to be reordered
                            +  int * permut permutation array
                            +)
                            +
                            +
                            Recursively puts the BDD in the order given in the array permut. + Checks for trivial cases to terminate recursion, then splits on the + children of this node. Once the solutions for the children are + obtained, it puts into the current position the node from the rest of + the BDD that should be here. Then returns this BDD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper position + is reached in the recursion tree.

                            + The DdNode * that is returned is the same BDD as passed in as node, + but in the new order. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddPermute +cuddAddPermuteRecur + + +
                            Defined in cuddCompose.c + +
                            +
                            +DdNode * 
                            +cuddBddRestrictRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * c 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_bddRestrict. + Returns the restricted BDD if successful; otherwise NULL. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddRestrict + + +
                            Defined in cuddGenCof.c + +
                            +
                            +static DdNode * 
                            +cuddBddSqueeze(
                            +  DdManager * dd, 
                            +  DdNode * l, 
                            +  DdNode * u 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_bddSqueeze. This + procedure exploits the fact that if we complement and swap the + bounds of the interval we obtain a valid solution by taking the + complement of the solution to the original problem. Therefore, we + can enforce the condition that the upper bound is always regular. + Returns a pointer to the result if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddSqueeze + + +
                            Defined in cuddGenCof.c + +
                            +
                            +static DdNode * 
                            +cuddBddTransferRecur(
                            +  DdManager * ddS, 
                            +  DdManager * ddD, 
                            +  DdNode * f, 
                            +  st_table * table 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_bddTransfer. + Returns a pointer to the result if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddBddTransfer + + +
                            Defined in cuddBridge.c + +
                            +
                            +DdNode * 
                            +cuddBddTransfer(
                            +  DdManager * ddS, 
                            +  DdManager * ddD, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Convert a BDD from a manager to another one. Returns a + pointer to the BDD in the destination manager if successful; NULL + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddTransfer + + +
                            Defined in cuddBridge.c + +
                            +
                            +static DdNode * 
                            +cuddBddVarMapRecur(
                            +  DdManager * manager, DD manager
                            +  DdNode * f BDD to be remapped
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_bddVarMap. + Returns a pointer to the result if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddVarMap + + +
                            Defined in cuddCompose.c + +
                            +
                            +static DdNode * 
                            +cuddBddVectorComposeRecur(
                            +  DdManager * dd, DD manager
                            +  DdHashTable * table, computed table
                            +  DdNode * f, BDD in which to compose
                            +  DdNode ** vector, functions to be composed
                            +  int  deepest depth of the deepest substitution
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_bddVectorCompose. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCompose.c + +
                            +
                            +DdNode * 
                            +cuddBddXorExistAbstractRecur(
                            +  DdManager * manager, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * cube 
                            +)
                            +
                            +
                            Takes the exclusive OR of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddAndAbstract + + +
                            Defined in cuddBddAbs.c + +
                            +
                            +DdNode * 
                            +cuddBddXorRecur(
                            +  DdManager * manager, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_bddXor by taking + the exclusive OR of two BDDs. Returns a pointer to the result is + successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_bddXor + + +
                            Defined in cuddBddIte.c + +
                            +
                            +DdNode * 
                            +cuddBiasedUnderApprox(
                            +  DdManager * dd, DD manager
                            +  DdNode * f, current DD
                            +  DdNode * b, bias function
                            +  int  numVars, maximum number of variables
                            +  int  threshold, threshold under which approximation stops
                            +  double  quality1, minimum improvement for accepted changes when b=1
                            +  double  quality0 minimum improvement for accepted changes when b=0
                            +)
                            +
                            +
                            Applies the biased remapping underappoximation algorithm. + Proceeds in three phases: +
                              +
                            • collect information on each node in the BDD; this is done via DFS. +
                            • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
                            • traverse the BDD via DFS and actually perform the elimination. +
                            + Returns the approximated BDD if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_BiasedUnderApprox + + +
                            Defined in cuddApprox.c + +
                            +
                            +DdNode * 
                            +cuddCProjectionRecur(
                            +  DdManager * dd, 
                            +  DdNode * R, 
                            +  DdNode * Y, 
                            +  DdNode * Ysupp 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_CProjection. Returns + the projection if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_CProjection + + +
                            Defined in cuddPriority.c + +
                            +
                            +void 
                            +cuddCacheFlush(
                            +  DdManager * table 
                            +)
                            +
                            +
                            Flushes the cache. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCache.c + +
                            +
                            +void 
                            +cuddCacheInsert1(
                            +  DdManager * table, 
                            +  DD_CTFP1  op, 
                            +  DdNode * f, 
                            +  DdNode * data 
                            +)
                            +
                            +
                            Inserts a result in the cache for a function with two + operands. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddCacheInsert +cuddCacheInsert2 + + +
                            Defined in cuddCache.c + +
                            +
                            +void 
                            +cuddCacheInsert2(
                            +  DdManager * table, 
                            +  DD_CTFP  op, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * data 
                            +)
                            +
                            +
                            Inserts a result in the cache for a function with two + operands. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddCacheInsert +cuddCacheInsert1 + + +
                            Defined in cuddCache.c + +
                            +
                            +void 
                            +cuddCacheInsert(
                            +  DdManager * table, 
                            +  ptruint  op, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * h, 
                            +  DdNode * data 
                            +)
                            +
                            +
                            Inserts a result in the cache for a function with three + operands. The operator tag (see cuddInt.h for details) is split and stored + into unused bits of the first two pointers. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddCacheInsert2 +cuddCacheInsert1 + + +
                            Defined in cuddCache.c + +
                            +
                            +DdNode * 
                            +cuddCacheLookup1Zdd(
                            +  DdManager * table, 
                            +  DD_CTFP1  op, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Returns the result if found; it returns NULL if no + result is found. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddCacheLookupZdd +cuddCacheLookup2Zdd + + +
                            Defined in cuddCache.c + +
                            +
                            +DdNode * 
                            +cuddCacheLookup1(
                            +  DdManager * table, 
                            +  DD_CTFP1  op, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Returns the result if found; it returns NULL if no + result is found. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddCacheLookup +cuddCacheLookup2 + + +
                            Defined in cuddCache.c + +
                            +
                            +DdNode * 
                            +cuddCacheLookup2Zdd(
                            +  DdManager * table, 
                            +  DD_CTFP  op, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Returns the result if found; it returns NULL if no + result is found. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddCacheLookupZdd +cuddCacheLookup1Zdd + + +
                            Defined in cuddCache.c + +
                            +
                            +DdNode * 
                            +cuddCacheLookup2(
                            +  DdManager * table, 
                            +  DD_CTFP  op, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Returns the result if found; it returns NULL if no + result is found. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddCacheLookup +cuddCacheLookup1 + + +
                            Defined in cuddCache.c + +
                            +
                            +DdNode * 
                            +cuddCacheLookupZdd(
                            +  DdManager * table, 
                            +  ptruint  op, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * h 
                            +)
                            +
                            +
                            Returns the result if found; it returns NULL if no + result is found. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddCacheLookup2Zdd +cuddCacheLookup1Zdd + + +
                            Defined in cuddCache.c + +
                            +
                            +DdNode * 
                            +cuddCacheLookup(
                            +  DdManager * table, 
                            +  ptruint  op, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * h 
                            +)
                            +
                            +
                            Returns the result if found; it returns NULL if no + result is found. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddCacheLookup2 +cuddCacheLookup1 + + +
                            Defined in cuddCache.c + +
                            +
                            +int 
                            +cuddCacheProfile(
                            +  DdManager * table, 
                            +  FILE * fp 
                            +)
                            +
                            +
                            Computes and prints a profile of the cache usage. + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCache.c + +
                            +
                            +void 
                            +cuddCacheResize(
                            +  DdManager * table 
                            +)
                            +
                            +
                            Resizes the cache. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCache.c + +
                            +
                            +static int 
                            +cuddCheckCollisionOrdering(
                            +  DdManager * unique, 
                            +  int  i, 
                            +  int  j 
                            +)
                            +
                            +
                            Checks whether a collision list is ordered. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddTable.c + +
                            +
                            +void 
                            +cuddClearDeathRow(
                            +  DdManager * table 
                            +)
                            +
                            +
                            Clears the death row. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_DelayedDerefBdd +Cudd_IterDerefBdd +Cudd_CheckZeroRef +cuddGarbageCollect + + +
                            Defined in cuddRef.c + +
                            +
                            +DdNode * 
                            +cuddCofactorRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_Cofactor. Returns a + pointer to the cofactor if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_Cofactor + + +
                            Defined in cuddCof.c + +
                            +
                            +int 
                            +cuddCollectNodes(
                            +  DdNode * f, 
                            +  st_table * visited 
                            +)
                            +
                            +
                            Traverses the DD f and collects all its nodes in a + symbol table. f is assumed to be a regular pointer and + cuddCollectNodes guarantees this assumption in the recursive calls. + Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +int 
                            +cuddComputeFloorLog2(
                            +  unsigned int  value 
                            +)
                            +
                            +
                            Returns the floor of the logarithm to the base 2. + The input value is assumed to be greater than 0. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCache.c + +
                            +
                            +static int 
                            +cuddConjunctsAux(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode ** c1, 
                            +  DdNode ** c2 
                            +)
                            +
                            +
                            Procedure to compute two conjunctive factors of f and + place in *c1 and *c2. Sets up the required data - table of distances + from the constant and local reference count. Also minterm table. +

                            + +

                            Defined in cuddDecomp.c + +
                            +
                            +DdNode * 
                            +cuddConstantLookup(
                            +  DdManager * table, 
                            +  ptruint  op, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * h 
                            +)
                            +
                            +
                            Looks up in the cache for the result of op applied to f, + g, and h. Assumes that the calling procedure (e.g., + Cudd_bddIteConstant) is only interested in whether the result is + constant or not. Returns the result if found (possibly + DD_NON_CONSTANT); otherwise it returns NULL. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddCacheLookup + + +
                            Defined in cuddCache.c + +
                            +
                            +int 
                            +cuddDestroySubtables(
                            +  DdManager * unique, 
                            +  int  n 
                            +)
                            +
                            +
                            Destroys the n most recently created subtables in a unique + table. n should be positive. The subtables should not contain any live + nodes, except the (isolated) projection function. The projection + functions are freed. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects The variable map used for fast variable substitution is + destroyed if it exists. In this case the cache is also cleared. +

                            + +

                            See Also cuddInsertSubtables +Cudd_SetVarMap + + +
                            Defined in cuddTable.c + +
                            +
                            +static void 
                            +cuddDoRebalance(
                            +  DdNodePtr ** stack, 
                            +  int  stackN 
                            +)
                            +
                            +
                            Rebalances a red/black tree. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddTable.c + +
                            +
                            +DdNode * 
                            +cuddDynamicAllocNode(
                            +  DdManager * table 
                            +)
                            +
                            +
                            Dynamically allocates a Node. This procedure is similar + to cuddAllocNode in Cudd_Table.c, but it does not attempt garbage + collection, because during reordering there are no dead nodes. + Returns a pointer to a new node if successful; NULL is memory is + full. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddAllocNode + + +
                            Defined in cuddReorder.c + +
                            +
                            +static int 
                            +cuddEstimateCofactorSimple(
                            +  DdNode * node, 
                            +  int  i 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_CofactorEstimateSimple. + Returns an estimate of the number of nodes in the DD of the positive + cofactor of node. Uses the least significant bit of the next field as + visited flag. node is supposed to be regular; the invariant is maintained + by this procedure. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +static int 
                            +cuddEstimateCofactor(
                            +  DdManager * dd, 
                            +  st_table * table, 
                            +  DdNode * node, 
                            +  int  i, 
                            +  int  phase, 
                            +  DdNode ** ptr 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_CofactorEstimate. + Returns an estimate of the number of nodes in the DD of a + cofactor of node. Uses the least significant bit of the next field as + visited flag. node is supposed to be regular; the invariant is maintained + by this procedure. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +int 
                            +cuddExact(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Exact variable ordering algorithm. Finds an optimum + order for the variables between lower and upper. Returns 1 if + successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddExact.c + +
                            +
                            +static int 
                            +cuddFindParent(
                            +  DdManager * table, 
                            +  DdNode * node 
                            +)
                            +
                            +
                            Searches the subtables above node for a parent. Returns 1 + as soon as one parent is found. Returns 0 is the search is fruitless. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddTable.c + +
                            +
                            +void 
                            +cuddFreeTable(
                            +  DdManager * unique 
                            +)
                            +
                            +
                            Frees the resources associated to a unique table. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddInitTable + + +
                            Defined in cuddTable.c + +
                            +
                            +int 
                            +cuddGarbageCollect(
                            +  DdManager * unique, 
                            +  int  clearCache 
                            +)
                            +
                            +
                            Performs garbage collection on the BDD and ZDD unique tables. + If clearCache is 0, the cache is not cleared. This should only be + specified if the cache has been cleared right before calling + cuddGarbageCollect. (As in the case of dynamic reordering.) + Returns the total number of deleted nodes. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddTable.c + +
                            +
                            +int 
                            +cuddGa(
                            +  DdManager * table, manager
                            +  int  lower, lowest level to be reordered
                            +  int  upper highest level to be reorderded
                            +)
                            +
                            +
                            Genetic algorithm for DD reordering. + The two children of a crossover will be stored in + storedd[popsize +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGenetic.c + +
                            +
                            +void 
                            +cuddGetBranches(
                            +  DdNode * g, 
                            +  DdNode ** g1, 
                            +  DdNode ** g0 
                            +)
                            +
                            +
                            Computes the children of g. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCof.c + +
                            +
                            +int 
                            +cuddHashTableGenericInsert(
                            +  DdHashTable * hash, 
                            +  DdNode * f, 
                            +  void * value 
                            +)
                            +
                            +
                            Inserts an item in a hash table when the key is one + pointer and the value is not a DdNode pointer. Returns 1 if + successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddHashTableInsert1 +cuddHashTableGenericLookup + + +
                            Defined in cuddLCache.c + +
                            +
                            +void * 
                            +cuddHashTableGenericLookup(
                            +  DdHashTable * hash, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Looks up a key consisting of one pointer in a hash + table when the value is not a DdNode pointer. Returns the value + associated to the key if there is an entry for the given key in the + table; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddHashTableLookup1 +cuddHashTableGenericInsert + + +
                            Defined in cuddLCache.c + +
                            +
                            +void 
                            +cuddHashTableGenericQuit(
                            +  DdHashTable * hash 
                            +)
                            +
                            +
                            Shuts down a hash table, when the values are not DdNode + pointers. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddHashTableInit + + +
                            Defined in cuddLCache.c + +
                            +
                            +DdHashTable * 
                            +cuddHashTableInit(
                            +  DdManager * manager, 
                            +  unsigned int  keySize, 
                            +  unsigned int  initSize 
                            +)
                            +
                            +
                            Initializes a hash table. Returns a pointer to the new + table if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddHashTableQuit + + +
                            Defined in cuddLCache.c + +
                            +
                            +int 
                            +cuddHashTableInsert1(
                            +  DdHashTable * hash, 
                            +  DdNode * f, 
                            +  DdNode * value, 
                            +  ptrint  count 
                            +)
                            +
                            +
                            Inserts an item in a hash table when the key is one pointer. + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddHashTableInsert +cuddHashTableInsert2 +cuddHashTableInsert3 +cuddHashTableLookup1 + + +
                            Defined in cuddLCache.c + +
                            +
                            +int 
                            +cuddHashTableInsert2(
                            +  DdHashTable * hash, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * value, 
                            +  ptrint  count 
                            +)
                            +
                            +
                            Inserts an item in a hash table when the key is + composed of two pointers. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddHashTableInsert +cuddHashTableInsert1 +cuddHashTableInsert3 +cuddHashTableLookup2 + + +
                            Defined in cuddLCache.c + +
                            +
                            +int 
                            +cuddHashTableInsert3(
                            +  DdHashTable * hash, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * h, 
                            +  DdNode * value, 
                            +  ptrint  count 
                            +)
                            +
                            +
                            Inserts an item in a hash table when the key is + composed of three pointers. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddHashTableInsert +cuddHashTableInsert1 +cuddHashTableInsert2 +cuddHashTableLookup3 + + +
                            Defined in cuddLCache.c + +
                            +
                            +int 
                            +cuddHashTableInsert(
                            +  DdHashTable * hash, 
                            +  DdNodePtr * key, 
                            +  DdNode * value, 
                            +  ptrint  count 
                            +)
                            +
                            +
                            Inserts an item in a hash table when the key has more than + three pointers. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also [cuddHashTableInsert1 +cuddHashTableInsert2 +cuddHashTableInsert3 +cuddHashTableLookup + + +
                            Defined in cuddLCache.c + +
                            +
                            +DdNode * 
                            +cuddHashTableLookup1(
                            +  DdHashTable * hash, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Looks up a key consisting of one pointer in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddHashTableLookup +cuddHashTableLookup2 +cuddHashTableLookup3 +cuddHashTableInsert1 + + +
                            Defined in cuddLCache.c + +
                            +
                            +DdNode * 
                            +cuddHashTableLookup2(
                            +  DdHashTable * hash, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Looks up a key consisting of two pointer in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddHashTableLookup +cuddHashTableLookup1 +cuddHashTableLookup3 +cuddHashTableInsert2 + + +
                            Defined in cuddLCache.c + +
                            +
                            +DdNode * 
                            +cuddHashTableLookup3(
                            +  DdHashTable * hash, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * h 
                            +)
                            +
                            +
                            Looks up a key consisting of three pointers in a hash table. + Returns the value associated to the key if there is an entry for the given + key in the table; NULL otherwise. If the entry is present, its reference + counter is decremented if not saturated. If the counter reaches 0, the + value of the entry is dereferenced, and the entry is returned to the free + list. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddHashTableLookup +cuddHashTableLookup1 +cuddHashTableLookup2 +cuddHashTableInsert3 + + +
                            Defined in cuddLCache.c + +
                            +
                            +DdNode * 
                            +cuddHashTableLookup(
                            +  DdHashTable * hash, 
                            +  DdNodePtr * key 
                            +)
                            +
                            +
                            Looks up a key consisting of more than three pointers + in a hash table. Returns the value associated to the key if there + is an entry for the given key in the table; NULL otherwise. If the + entry is present, its reference counter is decremented if not + saturated. If the counter reaches 0, the value of the entry is + dereferenced, and the entry is returned to the free list. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddHashTableLookup1 +cuddHashTableLookup2 +cuddHashTableLookup3 +cuddHashTableInsert + + +
                            Defined in cuddLCache.c + +
                            +
                            +void 
                            +cuddHashTableQuit(
                            +  DdHashTable * hash 
                            +)
                            +
                            +
                            Shuts down a hash table, dereferencing all the values. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddHashTableInit + + +
                            Defined in cuddLCache.c + +
                            +
                            +static int 
                            +cuddHashTableResize(
                            +  DdHashTable * hash 
                            +)
                            +
                            +
                            Resizes a hash table. Returns 1 if successful; 0 + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddHashTableInsert + + +
                            Defined in cuddLCache.c + +
                            +
                            +int 
                            +cuddHeapProfile(
                            +  DdManager * dd 
                            +)
                            +
                            +
                            Prints to the manager's stdout the number of live nodes for each + level of the DD heap that contains at least one live node. It also + prints a summary containing: +
                              +
                            • total number of tables; +
                            • number of tables with live nodes; +
                            • table with the largest number of live nodes; +
                            • number of nodes in that table. +
                            + If more than one table contains the maximum number of live nodes, + only the one of lowest index is reported. Returns 1 in case of success + and 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCheck.c + +
                            +
                            +int 
                            +cuddInitCache(
                            +  DdManager * unique, unique table
                            +  unsigned int  cacheSize, initial size of the cache
                            +  unsigned int  maxCacheSize cache size beyond which no resizing occurs
                            +)
                            +
                            +
                            Initializes the computed table. It is called by + Cudd_Init. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_Init + + +
                            Defined in cuddCache.c + +
                            +
                            +int 
                            +cuddInitInteract(
                            +  DdManager * table 
                            +)
                            +
                            +
                            Initializes the interaction matrix. The interaction + matrix is implemented as a bit vector storing the upper triangle of + the symmetric interaction matrix. The bit vector is kept in an array + of long integers. The computation is based on a series of depth-first + searches, one for each root of the DAG. Two flags are needed: The + local visited flag uses the LSB of the then pointer. The global + visited flag uses the LSB of the next pointer. + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddInteract.c + +
                            +
                            +int 
                            +cuddInitLinear(
                            +  DdManager * table 
                            +)
                            +
                            +
                            Initializes the linear transform matrix. Returns 1 if + successful; 0 otherwise. +

                            + +

                            Side Effects none +

                            + +

                            Defined in cuddLinear.c + +
                            +
                            +DdManager * 
                            +cuddInitTable(
                            +  unsigned int  numVars, Initial number of BDD variables (and subtables)
                            +  unsigned int  numVarsZ, Initial number of ZDD variables (and subtables)
                            +  unsigned int  numSlots, Initial size of the BDD subtables
                            +  unsigned int  looseUpTo Limit for fast table growth
                            +)
                            +
                            +
                            Creates and initializes the unique table. Returns a pointer + to the table if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_Init +cuddFreeTable + + +
                            Defined in cuddTable.c + +
                            +
                            +int 
                            +cuddInsertSubtables(
                            +  DdManager * unique, 
                            +  int  n, 
                            +  int  level 
                            +)
                            +
                            +
                            Inserts n new subtables in a unique table at level. + The number n should be positive, and level should be an existing level. + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddDestroySubtables + + +
                            Defined in cuddTable.c + +
                            +
                            +int 
                            +cuddIsInDeathRow(
                            +  DdManager * dd, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Checks whether a node is in the death row. Returns the + position of the first occurrence if the node is present; -1 + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_DelayedDerefBdd +cuddClearDeathRow + + +
                            Defined in cuddRef.c + +
                            +
                            +void 
                            +cuddLevelQueueDequeue(
                            +  DdLevelQueue * queue, 
                            +  int  level 
                            +)
                            +
                            +
                            Remove an item from the front of a level queue. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddLevelQueueEnqueue + + +
                            Defined in cuddLevelQ.c + +
                            +
                            +void * 
                            +cuddLevelQueueEnqueue(
                            +  DdLevelQueue * queue, level queue
                            +  void * key, key to be enqueued
                            +  int  level level at which to insert
                            +)
                            +
                            +
                            Inserts a new key in a level queue. A new entry is + created in the queue only if the node is not already + enqueued. Returns a pointer to the queue item if successful; NULL + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddLevelQueueInit +cuddLevelQueueDequeue + + +
                            Defined in cuddLevelQ.c + +
                            +
                            +void * 
                            +cuddLevelQueueFirst(
                            +  DdLevelQueue * queue, level queue
                            +  void * key, key to be enqueued
                            +  int  level level at which to insert
                            +)
                            +
                            +
                            Inserts the first key in a level queue. Returns a + pointer to the queue item if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddLevelQueueEnqueue + + +
                            Defined in cuddLevelQ.c + +
                            +
                            +DdLevelQueue * 
                            +cuddLevelQueueInit(
                            +  int  levels, number of levels
                            +  int  itemSize, size of the item
                            +  int  numBuckets initial number of hash buckets
                            +)
                            +
                            +
                            Initializes a level queue. A level queue is a queue + where inserts are based on the levels of the nodes. Within each + level the policy is FIFO. Level queues are useful in traversing a + BDD top-down. Queue items are kept in a free list when dequeued for + efficiency. Returns a pointer to the new queue if successful; NULL + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddLevelQueueQuit +cuddLevelQueueEnqueue +cuddLevelQueueDequeue + + +
                            Defined in cuddLevelQ.c + +
                            +
                            +void 
                            +cuddLevelQueueQuit(
                            +  DdLevelQueue * queue 
                            +)
                            +
                            +
                            Shuts down a level queue and releases all the + associated memory. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddLevelQueueInit + + +
                            Defined in cuddLevelQ.c + +
                            +
                            +int 
                            +cuddLinearAndSifting(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            BDD reduction based on combination of sifting and linear + transformations. Assumes that no dead nodes are present. +
                              +
                            1. Order all the variables according to the number of entries + in each unique table. +
                            2. Sift the variable up and down, remembering each time the + total size of the DD heap. At each position, linear transformation + of the two adjacent variables is tried and is accepted if it reduces + the size of the DD. +
                            3. Select the best permutation. +
                            4. Repeat 3 and 4 for all variables. +
                            + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLinear.c + +
                            +
                            +int 
                            +cuddLinearInPlace(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Linearly combines two adjacent variables. Specifically, + replaces the top variable with the exclusive nor of the two variables. + It assumes that no dead nodes are present on entry to this + procedure. The procedure then guarantees that no dead nodes will be + present when it terminates. cuddLinearInPlace assumes that x < + y. Returns the number of keys in the table if successful; 0 + otherwise. +

                            + +

                            Side Effects The two subtables corrresponding to variables x and y are + modified. The global counters of the unique table are also affected. +

                            + +

                            See Also cuddSwapInPlace + + +
                            Defined in cuddLinear.c + +
                            +
                            +static void 
                            +cuddLocalCacheAddToList(
                            +  DdLocalCache * cache 
                            +)
                            +
                            +
                            Inserts a local cache in the manager list. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLCache.c + +
                            +
                            +void 
                            +cuddLocalCacheClearAll(
                            +  DdManager * manager 
                            +)
                            +
                            +
                            Clears the local caches of a manager. + Used before reordering. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLCache.c + +
                            +
                            +void 
                            +cuddLocalCacheClearDead(
                            +  DdManager * manager 
                            +)
                            +
                            +
                            Clears the dead entries of the local caches of a manager. + Used during garbage collection. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLCache.c + +
                            +
                            +DdLocalCache * 
                            +cuddLocalCacheInit(
                            +  DdManager * manager, manager
                            +  unsigned int  keySize, size of the key (number of operands)
                            +  unsigned int  cacheSize, Initial size of the cache
                            +  unsigned int  maxCacheSize Size of the cache beyond which no resizing occurs
                            +)
                            +
                            +
                            Initializes a computed table. Returns a pointer the + the new local cache in case of success; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddInitCache + + +
                            Defined in cuddLCache.c + +
                            +
                            +void 
                            +cuddLocalCacheInsert(
                            +  DdLocalCache * cache, 
                            +  DdNodePtr * key, 
                            +  DdNode * value 
                            +)
                            +
                            +
                            Inserts a result in a local cache. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLCache.c + +
                            +
                            +DdNode * 
                            +cuddLocalCacheLookup(
                            +  DdLocalCache * cache, 
                            +  DdNodePtr * key 
                            +)
                            +
                            +
                            Looks up in a local cache. Returns the result if found; + it returns NULL if no result is found. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLCache.c + +
                            +
                            +int 
                            +cuddLocalCacheProfile(
                            +  DdLocalCache * cache 
                            +)
                            +
                            +
                            Computes and prints a profile of a local cache usage. + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLCache.c + +
                            +
                            +void 
                            +cuddLocalCacheQuit(
                            +  DdLocalCache * cache cache to be shut down
                            +)
                            +
                            +
                            Initializes the computed table. It is called by + Cudd_Init. Returns a pointer the the new local cache in case of + success; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddLocalCacheInit + + +
                            Defined in cuddLCache.c + +
                            +
                            +static void 
                            +cuddLocalCacheRemoveFromList(
                            +  DdLocalCache * cache 
                            +)
                            +
                            +
                            Removes a local cache from the manager list. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLCache.c + +
                            +
                            +static void 
                            +cuddLocalCacheResize(
                            +  DdLocalCache * cache 
                            +)
                            +
                            +
                            Resizes a local cache. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLCache.c + +
                            +
                            +DdNode	* 
                            +cuddMakeBddFromZddCover(
                            +  DdManager * dd, 
                            +  DdNode * node 
                            +)
                            +
                            +
                            Converts a ZDD cover to a BDD. If successful, it returns + a BDD node, otherwise it returns NULL. It is a recursive algorithm + that works as follows. First it computes 3 cofactors of a ZDD cover: + f1, f0 and fd. Second, it compute BDDs (b1, b0 and bd) of f1, f0 and fd. + Third, it computes T=b1+bd and E=b0+bd. Fourth, it computes ITE(v,T,E) where + v is the variable which has the index of the top node of the ZDD cover. + In this case, since the index of v can be larger than either the one of T + or the one of E, cuddUniqueInterIVO is called, where IVO stands for + independent from variable ordering. +

                            + +

                            See Also Cudd_MakeBddFromZddCover + + +
                            Defined in cuddZddIsop.c + +
                            +
                            +static int 
                            +cuddMinHammingDistRecur(
                            +  DdNode * f, 
                            +  int * minterm, 
                            +  DdHashTable * table, 
                            +  int  upperBound 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_MinHammingDist. + It is based on the following identity. Let H(f) be the + minimum Hamming distance of the minterms of f from the reference + minterm. Then: + + H(f) = min(H(f0)+h0,H(f1)+h1) + + where f0 and f1 are the two cofactors of f with respect to its top + variable; h0 is 1 if the minterm assigns 1 to the top variable of f; + h1 is 1 if the minterm assigns 0 to the top variable of f. + The upper bound on the distance is used to bound the depth of the + recursion. + Returns the minimum distance unless it exceeds the upper bound or + computation fails. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_MinHammingDist + + +
                            Defined in cuddPriority.c + +
                            +
                            +int 
                            +cuddNextHigh(
                            +  DdManager * table, 
                            +  int  x 
                            +)
                            +
                            +
                            Finds the next subtable with a larger index. Returns the + index. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddNextLow + + +
                            Defined in cuddReorder.c + +
                            +
                            +int 
                            +cuddNextLow(
                            +  DdManager * table, 
                            +  int  x 
                            +)
                            +
                            +
                            Finds the next subtable with a smaller index. Returns the + index. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddNextHigh + + +
                            Defined in cuddReorder.c + +
                            +
                            +static int 
                            +cuddNodeArrayRecur(
                            +  DdNode * f, 
                            +  DdNodePtr * table, 
                            +  int  index 
                            +)
                            +
                            +
                            Performs the recursive step of cuddNodeArray. Returns + an the number of nodes in the DD. Clear the least significant bit + of the next field that was used as visited flag by + cuddNodeArrayRecur when counting the nodes. node is supposed to be + regular; the invariant is maintained by this procedure. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +DdNodePtr * 
                            +cuddNodeArray(
                            +  DdNode * f, 
                            +  int * n 
                            +)
                            +
                            +
                            Traverses the DD f and collects all its nodes in an array. + The caller should free the array returned by cuddNodeArray. + Returns a pointer to the array of nodes in case of success; NULL + otherwise. The nodes are collected in reverse topological order, so + that a node is always preceded in the array by all its descendants. +

                            + +

                            Side Effects The number of nodes is returned as a side effect. +

                            + +

                            See Also Cudd_FirstNode + + +
                            Defined in cuddUtil.c + +
                            +
                            +static void 
                            +cuddOrderedInsert(
                            +  DdNodePtr * root, 
                            +  DdNodePtr  node 
                            +)
                            +
                            +
                            Inserts a DdNode in a red/black search tree. Nodes from + the same "page" (defined by DD_PAGE_MASK) are linked in a LIFO list. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddOrderedThread + + +
                            Defined in cuddTable.c + +
                            +
                            +static DdNode * 
                            +cuddOrderedThread(
                            +  DdNode * root, 
                            +  DdNode * list 
                            +)
                            +
                            +
                            Threads all the nodes of a search tree into a linear + list. For each node of the search tree, the "left" child, if non-null, has + a lower address than its parent, and the "right" child, if non-null, has a + higher address than its parent. + The list is sorted in order of increasing addresses. The search + tree is destroyed as a result of this operation. The last element of + the linear list is made to point to the address passed in list. Each + node if the search tree is a linearly-linked list of nodes from the + same memory page (as defined in DD_PAGE_MASK). When a node is added to + the linear list, all the elements of the linked list are added. +

                            + +

                            Side Effects The search tree is destroyed as a result of this operation. +

                            + +

                            See Also cuddOrderedInsert + + +
                            Defined in cuddTable.c + +
                            +
                            +void 
                            +cuddPrintNode(
                            +  DdNode * f, 
                            +  FILE * fp 
                            +)
                            +
                            +
                            Prints out information on a node. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCheck.c + +
                            +
                            +void 
                            +cuddPrintVarGroups(
                            +  DdManager * dd, manager
                            +  MtrNode * root, root of the group tree
                            +  int  zdd, 0: BDD; 1: ZDD
                            +  int  silent flag to check tree syntax only
                            +)
                            +
                            +
                            Prints the variable groups as a parenthesized list. + For each group the level range that it represents is printed. After + each group, the group's flags are printed, preceded by a `|'. For + each flag (except MTR_TERMINAL) a character is printed. +
                              +
                            • F: MTR_FIXED +
                            • N: MTR_NEWNODE +
                            • S: MTR_SOFT +
                            + The second argument, silent, if different from 0, causes + Cudd_PrintVarGroups to only check the syntax of the group tree. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCheck.c + +
                            +
                            +int 
                            +cuddP(
                            +  DdManager * dd, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Prints a DD to the standard output. One line per node is + printed. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_PrintDebug + + +
                            Defined in cuddUtil.c + +
                            +
                            +void 
                            +cuddReclaimZdd(
                            +  DdManager * table, 
                            +  DdNode * n 
                            +)
                            +
                            +
                            Brings children of a dead ZDD node back. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddReclaim + + +
                            Defined in cuddRef.c + +
                            +
                            +void 
                            +cuddReclaim(
                            +  DdManager * table, 
                            +  DdNode * n 
                            +)
                            +
                            +
                            Brings children of a dead node back. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddReclaimZdd + + +
                            Defined in cuddRef.c + +
                            +
                            +void 
                            +cuddRehash(
                            +  DdManager * unique, 
                            +  int  i 
                            +)
                            +
                            +
                            Doubles the size of a unique subtable and rehashes its + contents. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddTable.c + +
                            +
                            +DdNode * 
                            +cuddRemapUnderApprox(
                            +  DdManager * dd, DD manager
                            +  DdNode * f, current DD
                            +  int  numVars, maximum number of variables
                            +  int  threshold, threshold under which approximation stops
                            +  double  quality minimum improvement for accepted changes
                            +)
                            +
                            +
                            Applies the remapping underappoximation algorithm. + Proceeds in three phases: +
                              +
                            • collect information on each node in the BDD; this is done via DFS. +
                            • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
                            • traverse the BDD via DFS and actually perform the elimination. +
                            + Returns the approximated BDD if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_RemapUnderApprox + + +
                            Defined in cuddApprox.c + +
                            +
                            +int 
                            +cuddResizeLinear(
                            +  DdManager * table 
                            +)
                            +
                            +
                            Resizes the linear transform matrix. Returns 1 if + successful; 0 otherwise. +

                            + +

                            Side Effects none +

                            + +

                            Defined in cuddLinear.c + +
                            +
                            +int 
                            +cuddResizeTableZdd(
                            +  DdManager * unique, 
                            +  int  index 
                            +)
                            +
                            +
                            Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index. When new ZDD variables are created, it + is possible to preserve the functions unchanged, or it is possible to + preserve the covers unchanged, but not both. cuddResizeTableZdd preserves + the covers. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also ddResizeTable + + +
                            Defined in cuddTable.c + +
                            +
                            +void 
                            +cuddSetInteract(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Given a pair of variables 0 <= x < y < table->size, + sets the corresponding bit of the interaction matrix to 1. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddInteract.c + +
                            +
                            +void 
                            +cuddShrinkDeathRow(
                            +  DdManager * table 
                            +)
                            +
                            +
                            Shrinks the death row by a factor of four. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddClearDeathRow + + +
                            Defined in cuddRef.c + +
                            +
                            +void 
                            +cuddShrinkSubtable(
                            +  DdManager * unique, 
                            +  int  i 
                            +)
                            +
                            +
                            Shrinks a subtable. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddRehash + + +
                            Defined in cuddTable.c + +
                            +
                            +int 
                            +cuddSifting(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Implementation of Rudell's sifting algorithm. + Assumes that no dead nodes are present. +
                              +
                            1. Order all the variables according to the number of entries + in each unique table. +
                            2. Sift the variable up and down, remembering each time the + total size of the DD heap. +
                            3. Select the best permutation. +
                            4. Repeat 3 and 4 for all variables. +
                            + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +void 
                            +cuddSlowTableGrowth(
                            +  DdManager * unique 
                            +)
                            +
                            +
                            Adjusts parameters of a table to slow down its growth. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddTable.c + +
                            +
                            +DdNode * 
                            +cuddSolveEqnRecur(
                            +  DdManager * bdd, 
                            +  DdNode * F, the left-hand side of the equation
                            +  DdNode * Y, the cube of remaining y variables
                            +  DdNode ** G, the array of solutions
                            +  int  n, number of unknowns
                            +  int * yIndex, array holding the y variable indices
                            +  int  i level of recursion
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_SolveEqn. + Returns NULL if the intermediate solution blows up + or reordering occurs. The parametric solutions are + stored in the array G. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_SolveEqn +Cudd_VerifySol + + +
                            Defined in cuddSolve.c + +
                            +
                            +DdNode* 
                            +cuddSplitSetRecur(
                            +  DdManager * manager, 
                            +  st_table * mtable, 
                            +  int * varSeen, 
                            +  DdNode * p, 
                            +  double  n, 
                            +  double  max, 
                            +  int  index 
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_SplitSet. The + procedure recursively traverses the BDD and checks to see if any + node satisfies the minterm requirements as specified by 'n'. At any + node X, n is compared to the number of minterms in the onset of X's + children. If either of the child nodes have exactly n minterms, then + that node is returned; else, if n is greater than the onset of one + of the child nodes, that node is retained and the difference in the + number of minterms is extracted from the other child. In case n + minterms can be extracted from constant 1, the algorithm returns the + result with at most log(n) nodes. +

                            + +

                            Side Effects The array 'varSeen' is updated at every recursive call + to set the variables traversed by the procedure. +

                            + +

                            Defined in cuddSplit.c + +
                            +
                            +enum st_retval 
                            +cuddStCountfree(
                            +  char * key, 
                            +  char * value, 
                            +  char * arg 
                            +)
                            +
                            +
                            Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +DdNode * 
                            +cuddSubsetHeavyBranch(
                            +  DdManager * dd, DD manager
                            +  DdNode * f, current DD
                            +  int  numVars, maximum number of variables
                            +  int  threshold threshold size for the subset
                            +)
                            +
                            +
                            Here a subset BDD is built by throwing away one of the + children. Starting at root, annotate each node with the number of + minterms (in terms of the total number of variables specified - + numVars), number of nodes taken by the DAG rooted at this node and + number of additional nodes taken by the child that has the lesser + minterms. The child with the lower number of minterms is thrown away + and a dyanmic count of the nodes of the subset is kept. Once the + threshold is reached the subset is returned to the calling + procedure. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_SubsetHeavyBranch + + +
                            Defined in cuddSubsetHB.c + +
                            +
                            +DdNode * 
                            +cuddSubsetShortPaths(
                            +  DdManager * dd, DD manager
                            +  DdNode * f, function to be subset
                            +  int  numVars, total number of variables in consideration
                            +  int  threshold, maximum number of nodes allowed in the subset
                            +  int  hardlimit flag determining whether threshold should be respected strictly
                            +)
                            +
                            +
                            The outermost procedure to return a subset of the given + BDD with the largest cubes. The path lengths are calculated, the maximum + allowable path length is determined and the number of nodes of this + path length that can be used to build a subset. If the threshold is + larger than the size of the original BDD, the original BDD is + returned. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_SubsetShortPaths + + +
                            Defined in cuddSubsetSP.c + +
                            +
                            +int 
                            +cuddSwapInPlace(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Swaps two adjacent variables. It assumes that no dead + nodes are present on entry to this procedure. The procedure then + guarantees that no dead nodes will be present when it terminates. + cuddSwapInPlace assumes that x < y. Returns the number of keys in + the table if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +int 
                            +cuddSwapping(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper, 
                            +  Cudd_ReorderingType  heuristic 
                            +)
                            +
                            +
                            Implementation of Plessier's algorithm that reorders + variables by a sequence of (non-adjacent) swaps. +
                              +
                            1. Select two variables (RANDOM or HEURISTIC). +
                            2. Permute these variables. +
                            3. If the nodes have decreased accept the permutation. +
                            4. Otherwise reconstruct the original heap. +
                            5. Loop. +
                            + Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +int 
                            +cuddSymmCheck(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Checks for symmetry of x and y. Ignores projection + functions, unless they are isolated. Returns 1 in case of symmetry; 0 + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSymmetry.c + +
                            +
                            +int 
                            +cuddSymmSiftingConv(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Symmetric sifting to convergence algorithm. + Assumes that no dead nodes are present. +
                              +
                            1. Order all the variables according to the number of entries in + each unique subtable. +
                            2. Sift the variable up and down, remembering each time the total + size of the DD heap and grouping variables that are symmetric. +
                            3. Select the best permutation. +
                            4. Repeat 3 and 4 for all variables. +
                            5. Repeat 1-4 until no further improvement. +
                            + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddSymmSifting + + +
                            Defined in cuddSymmetry.c + +
                            +
                            +int 
                            +cuddSymmSifting(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Symmetric sifting algorithm. + Assumes that no dead nodes are present. +
                              +
                            1. Order all the variables according to the number of entries in + each unique subtable. +
                            2. Sift the variable up and down, remembering each time the total + size of the DD heap and grouping variables that are symmetric. +
                            3. Select the best permutation. +
                            4. Repeat 3 and 4 for all variables. +
                            + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddSymmSiftingConv + + +
                            Defined in cuddSymmetry.c + +
                            +
                            +int 
                            +cuddTestInteract(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Given a pair of variables 0 <= x < y < table->size, + tests whether the corresponding bit of the interaction matrix is 1. + Returns the value of the bit. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddInteract.c + +
                            +
                            +int 
                            +cuddTimesInDeathRow(
                            +  DdManager * dd, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Counts how many times a node is in the death row. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_DelayedDerefBdd +cuddClearDeathRow +cuddIsInDeathRow + + +
                            Defined in cuddRef.c + +
                            +
                            +int 
                            +cuddTreeSifting(
                            +  DdManager * table, DD table
                            +  Cudd_ReorderingType  method reordering method for the groups of leaves
                            +)
                            +
                            +
                            Tree sifting algorithm. Assumes that a tree representing + a group hierarchy is passed as a parameter. It then reorders each + group in postorder fashion by calling ddTreeSiftingAux. Assumes that + no dead nodes are present. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +DdNode * 
                            +cuddUnderApprox(
                            +  DdManager * dd, DD manager
                            +  DdNode * f, current DD
                            +  int  numVars, maximum number of variables
                            +  int  threshold, threshold under which approximation stops
                            +  int  safe, enforce safe approximation
                            +  double  quality minimum improvement for accepted changes
                            +)
                            +
                            +
                            Applies Tom Shiple's underappoximation algorithm. Proceeds + in three phases: +
                              +
                            • collect information on each node in the BDD; this is done via DFS. +
                            • traverse the BDD in top-down fashion and compute for each node + whether its elimination increases density. +
                            • traverse the BDD via DFS and actually perform the elimination. +
                            + Returns the approximated BDD if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_UnderApprox + + +
                            Defined in cuddApprox.c + +
                            +
                            +DdNode * 
                            +cuddUniqueConst(
                            +  DdManager * unique, 
                            +  CUDD_VALUE_TYPE  value 
                            +)
                            +
                            +
                            Checks the unique table for the existence of a constant node. + If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. Returns a + pointer to the new node. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddTable.c + +
                            +
                            +DdNode * 
                            +cuddUniqueInterIVO(
                            +  DdManager * unique, 
                            +  int  index, 
                            +  DdNode * T, 
                            +  DdNode * E 
                            +)
                            +
                            +
                            Wrapper for cuddUniqueInter that is independent of + variable ordering (IVO). This function does not require parameter + index to precede the indices of the top nodes of T and E in the + variable order. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddUniqueInter +Cudd_MakeBddFromZddCover + + +
                            Defined in cuddTable.c + +
                            +
                            +DdNode * 
                            +cuddUniqueInterZdd(
                            +  DdManager * unique, 
                            +  int  index, 
                            +  DdNode * T, 
                            +  DdNode * E 
                            +)
                            +
                            +
                            Checks the unique table for the existence of an internal + ZDD node. If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. For a newly + created node, increments the reference counts of what T and E point + to. Returns a pointer to the new node if successful; NULL if memory + is exhausted or if reordering took place. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddUniqueInter + + +
                            Defined in cuddTable.c + +
                            +
                            +DdNode * 
                            +cuddUniqueInter(
                            +  DdManager * unique, 
                            +  int  index, 
                            +  DdNode * T, 
                            +  DdNode * E 
                            +)
                            +
                            +
                            Checks the unique table for the existence of an internal + node. If it does not exist, it creates a new one. Does not + modify the reference count of whatever is returned. A newly created + internal node comes back with a reference count 0. For a newly + created node, increments the reference counts of what T and E point + to. Returns a pointer to the new node if successful; NULL if memory + is exhausted or if reordering took place. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddUniqueInterZdd + + +
                            Defined in cuddTable.c + +
                            +
                            +static DdNode * 
                            +cuddUniqueLookup(
                            +  DdManager * unique, 
                            +  int  index, 
                            +  DdNode * T, 
                            +  DdNode * E 
                            +)
                            +
                            +
                            Checks the unique table for the existence of an internal + node. Returns a pointer to the node if it is in the table; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddUniqueInter + + +
                            Defined in cuddUtil.c + +
                            +
                            +void 
                            +cuddUpdateInteractionMatrix(
                            +  DdManager * table, 
                            +  int  xindex, 
                            +  int  yindex 
                            +)
                            +
                            +
                            Updates the interaction matrix. +

                            + +

                            Side Effects none +

                            + +

                            Defined in cuddLinear.c + +
                            +
                            +DdNode * 
                            +cuddVerifySol(
                            +  DdManager * bdd, 
                            +  DdNode * F, the left-hand side of the equation
                            +  DdNode ** G, the array of solutions
                            +  int * yIndex, array holding the y variable indices
                            +  int  n number of unknowns
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_VerifySol. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_VerifySol + + +
                            Defined in cuddSolve.c + +
                            +
                            +int 
                            +cuddWindowReorder(
                            +  DdManager * table, DD table
                            +  int  low, lowest index to reorder
                            +  int  high, highest index to reorder
                            +  Cudd_ReorderingType  submethod window reordering option
                            +)
                            +
                            +
                            Reorders by applying the method of the sliding window. + Tries all possible permutations to the variables in a window that + slides from low to high. The size of the window is determined by + submethod. Assumes that no dead nodes are present. Returns 1 in + case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddWindow.c + +
                            +
                            +static void 
                            +cuddXorLinear(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            XORs two rows of the linear transform matrix and replaces + the first row with the result. +

                            + +

                            Side Effects none +

                            + +

                            Defined in cuddLinear.c + +
                            +
                            +int 
                            +cuddZddAlignToBdd(
                            +  DdManager * table DD manager
                            +)
                            +
                            +
                            Reorders ZDD variables according to the order of the + BDD variables. This function can be called at the end of BDD + reordering to insure that the order of the ZDD variables is + consistent with the order of the BDD variables. The number of ZDD + variables must be a multiple of the number of BDD variables. Let + M be the ratio of the two numbers. cuddZddAlignToBdd + then considers the ZDD variables from M*i to + (M+1)*i-1 as corresponding to BDD variable + i. This function should be normally called from + Cudd_ReduceHeap, which clears the cache. Returns 1 in case of + success; 0 otherwise. +

                            + +

                            Side Effects Changes the ZDD variable order for all diagrams and performs + garbage collection of the ZDD unique table. +

                            + +

                            See Also Cudd_zddShuffleHeap +Cudd_ReduceHeap + + +
                            Defined in cuddZddReord.c + +
                            +
                            +DdNode * 
                            +cuddZddChangeAux(
                            +  DdManager * zdd, 
                            +  DdNode * P, 
                            +  DdNode * zvar 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddChange. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSetop.c + +
                            +
                            +DdNode * 
                            +cuddZddChange(
                            +  DdManager * dd, 
                            +  DdNode * P, 
                            +  int  var 
                            +)
                            +
                            +
                            Substitutes a variable with its complement in a ZDD. + returns a pointer to the result if successful; NULL + otherwise. cuddZddChange performs the same function as + Cudd_zddChange, but does not restart if reordering has taken + place. Therefore it can be called from within a recursive + procedure. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_zddChange + + +
                            Defined in cuddZddSetop.c + +
                            +
                            +DdNode	* 
                            +cuddZddComplement(
                            +  DdManager * dd, 
                            +  DdNode * node 
                            +)
                            +
                            +
                            Computes the complement of a ZDD node. So far, since we + couldn't find a direct way to get the complement of a ZDD cover, we first + convert a ZDD cover to a BDD, then make the complement of the ZDD cover + from the complement of the BDD node by using ISOP. +

                            + +

                            Side Effects The result depends on current variable order. +

                            + +

                            Defined in cuddZddFuncs.c + +
                            +
                            +static double 
                            +cuddZddCountDoubleStep(
                            +  DdNode * P, 
                            +  st_table * table, 
                            +  DdNode * base, 
                            +  DdNode * empty 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddCountDouble. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddCount.c + +
                            +
                            +static int 
                            +cuddZddCountStep(
                            +  DdNode * P, 
                            +  st_table * table, 
                            +  DdNode * base, 
                            +  DdNode * empty 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddCount. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddCount.c + +
                            +
                            +static int 
                            +cuddZddDagInt(
                            +  DdNode * n, 
                            +  st_table * tab 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddDagSize. Does + not check for out-of-memory conditions. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddMisc.c + +
                            +
                            +DdNode * 
                            +cuddZddDiff(
                            +  DdManager * zdd, 
                            +  DdNode * P, 
                            +  DdNode * Q 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddDiff. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSetop.c + +
                            +
                            +DdNode	* 
                            +cuddZddDivideF(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddDivideF. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_zddDivideF + + +
                            Defined in cuddZddFuncs.c + +
                            +
                            +DdNode	* 
                            +cuddZddDivide(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddDivide. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_zddDivide + + +
                            Defined in cuddZddFuncs.c + +
                            +
                            +void 
                            +cuddZddFreeUniv(
                            +  DdManager * zdd 
                            +)
                            +
                            +
                            Frees the ZDD universe. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddZddInitUniv + + +
                            Defined in cuddInit.c + +
                            +
                            +int 
                            +cuddZddGetCofactors2(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  int  v, 
                            +  DdNode ** f1, 
                            +  DdNode ** f0 
                            +)
                            +
                            +
                            Computes the two-way decomposition of f w.r.t. v. +

                            + +

                            Side Effects The results are returned in f1 and f0. +

                            + +

                            See Also cuddZddGetCofactors3 + + +
                            Defined in cuddZddFuncs.c + +
                            +
                            +int 
                            +cuddZddGetCofactors3(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  int  v, 
                            +  DdNode ** f1, 
                            +  DdNode ** f0, 
                            +  DdNode ** fd 
                            +)
                            +
                            +
                            Computes the three-way decomposition of function f (represented + by a ZDD) wit respect to variable v. Returns 0 if successful; 1 otherwise. +

                            + +

                            Side Effects The results are returned in f1, f0, and fd. +

                            + +

                            See Also cuddZddGetCofactors2 + + +
                            Defined in cuddZddFuncs.c + +
                            +
                            +int 
                            +cuddZddGetNegVarIndex(
                            +  DdManager * dd, 
                            +  int  index 
                            +)
                            +
                            +
                            Returns the index of negative ZDD variable. +

                            + +

                            Defined in cuddZddFuncs.c + +
                            +
                            +int 
                            +cuddZddGetNegVarLevel(
                            +  DdManager * dd, 
                            +  int  index 
                            +)
                            +
                            +
                            Returns the level of negative ZDD variable. +

                            + +

                            Defined in cuddZddFuncs.c + +
                            +
                            +DdNode * 
                            +cuddZddGetNodeIVO(
                            +  DdManager * dd, 
                            +  int  index, 
                            +  DdNode * g, 
                            +  DdNode * h 
                            +)
                            +
                            +
                            Wrapper for cuddUniqueInterZdd that is independent of + variable ordering (IVO). This function does not require parameter + index to precede the indices of the top nodes of g and h in the + variable order. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddZddGetNode +cuddZddIsop + + +
                            Defined in cuddTable.c + +
                            +
                            +DdNode * 
                            +cuddZddGetNode(
                            +  DdManager * zdd, 
                            +  int  id, 
                            +  DdNode * T, 
                            +  DdNode * E 
                            +)
                            +
                            +
                            Wrapper for cuddUniqueInterZdd, which applies the ZDD + reduction rule. Returns a pointer to the result node under normal + conditions; NULL if reordering occurred or memory was exhausted. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddUniqueInterZdd + + +
                            Defined in cuddTable.c + +
                            +
                            +int 
                            +cuddZddGetPosVarIndex(
                            +  DdManager * dd, 
                            +  int  index 
                            +)
                            +
                            +
                            Returns the index of positive ZDD variable. +

                            + +

                            Defined in cuddZddFuncs.c + +
                            +
                            +int 
                            +cuddZddGetPosVarLevel(
                            +  DdManager * dd, 
                            +  int  index 
                            +)
                            +
                            +
                            Returns the level of positive ZDD variable. +

                            + +

                            Defined in cuddZddFuncs.c + +
                            +
                            +int 
                            +cuddZddInitUniv(
                            +  DdManager * zdd 
                            +)
                            +
                            +
                            Initializes the ZDD universe. Returns 1 if successful; 0 + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddZddFreeUniv + + +
                            Defined in cuddInit.c + +
                            +
                            +DdNode * 
                            +cuddZddIntersect(
                            +  DdManager * zdd, 
                            +  DdNode * P, 
                            +  DdNode * Q 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddIntersect. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSetop.c + +
                            +
                            +DdNode	* 
                            +cuddZddIsop(
                            +  DdManager * dd, 
                            +  DdNode * L, 
                            +  DdNode * U, 
                            +  DdNode ** zdd_I 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddIsop. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_zddIsop + + +
                            Defined in cuddZddIsop.c + +
                            +
                            +DdNode * 
                            +cuddZddIte(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g, 
                            +  DdNode * h 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddIte. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSetop.c + +
                            +
                            +static int 
                            +cuddZddLinearAux(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xLow, 
                            +  int  xHigh 
                            +)
                            +
                            +
                            Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddLin.c + +
                            +
                            +static int 
                            +cuddZddLinearBackward(
                            +  DdManager * table, 
                            +  int  size, 
                            +  Move * moves 
                            +)
                            +
                            +
                            Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddLin.c + +
                            +
                            +static Move * 
                            +cuddZddLinearDown(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xHigh, 
                            +  Move * prevMoves 
                            +)
                            +
                            +
                            Sifts a variable down. Moves x down until either it + reaches the bound (xHigh) or the size of the ZDD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddLin.c + +
                            +
                            +static int 
                            +cuddZddLinearInPlace(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Linearly combines two adjacent variables. It assumes + that no dead nodes are present on entry to this procedure. The + procedure then guarantees that no dead nodes will be present when it + terminates. cuddZddLinearInPlace assumes that x < y. Returns the + number of keys in the table if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddZddSwapInPlace +cuddLinearInPlace + + +
                            Defined in cuddZddLin.c + +
                            +
                            +int 
                            +cuddZddLinearSifting(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Implementation of the linear sifting algorithm for ZDDs. + Assumes that no dead nodes are present. +
                              +
                            1. Order all the variables according to the number of entries + in each unique table. +
                            2. Sift the variable up and down and applies the XOR transformation, + remembering each time the total size of the DD heap. +
                            3. Select the best permutation. +
                            4. Repeat 3 and 4 for all variables. +
                            + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddLin.c + +
                            +
                            +static Move * 
                            +cuddZddLinearUp(
                            +  DdManager * table, 
                            +  int  y, 
                            +  int  xLow, 
                            +  Move * prevMoves 
                            +)
                            +
                            +
                            Sifts a variable up applying the XOR + transformation. Moves y up until either it reaches the bound (xLow) + or the size of the ZDD heap increases too much. Returns the set of + moves in case of success; NULL if memory is full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddLin.c + +
                            +
                            +int 
                            +cuddZddNextHigh(
                            +  DdManager * table, 
                            +  int  x 
                            +)
                            +
                            +
                            Finds the next subtable with a larger index. Returns the + index. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +int 
                            +cuddZddNextLow(
                            +  DdManager * table, 
                            +  int  x 
                            +)
                            +
                            +
                            Finds the next subtable with a smaller index. Returns the + index. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +DdNode	* 
                            +cuddZddProduct(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddProduct. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_zddProduct + + +
                            Defined in cuddZddFuncs.c + +
                            +
                            +int 
                            +cuddZddP(
                            +  DdManager * zdd, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Prints a ZDD to the standard output. One line per node is + printed. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_zddPrintDebug + + +
                            Defined in cuddZddUtil.c + +
                            +
                            +static int 
                            +cuddZddSiftingAux(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  x_low, 
                            +  int  x_high 
                            +)
                            +
                            +
                            Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +static int 
                            +cuddZddSiftingBackward(
                            +  DdManager * table, 
                            +  Move * moves, 
                            +  int  size 
                            +)
                            +
                            +
                            Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +static Move * 
                            +cuddZddSiftingDown(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  x_high, 
                            +  int  initial_size 
                            +)
                            +
                            +
                            Sifts a variable down. Moves x down until either it + reaches the bound (x_high) or the size of the ZDD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +static Move * 
                            +cuddZddSiftingUp(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  x_low, 
                            +  int  initial_size 
                            +)
                            +
                            +
                            Sifts a variable up. Moves y up until either it reaches + the bound (x_low) or the size of the ZDD heap increases too much. + Returns the set of moves in case of success; NULL if memory is full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +int 
                            +cuddZddSifting(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Implementation of Rudell's sifting algorithm. + Assumes that no dead nodes are present. +
                              +
                            1. Order all the variables according to the number of entries + in each unique table. +
                            2. Sift the variable up and down, remembering each time the + total size of the DD heap. +
                            3. Select the best permutation. +
                            4. Repeat 3 and 4 for all variables. +
                            + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +DdNode * 
                            +cuddZddSubset0(
                            +  DdManager * dd, 
                            +  DdNode * P, 
                            +  int  var 
                            +)
                            +
                            +
                            Computes the negative cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is negated. Returns a pointer to + the result if successful; NULL otherwise. cuddZddSubset0 performs + the same function as Cudd_zddSubset0, but does not restart if + reordering has taken place. Therefore it can be called from within a + recursive procedure. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddZddSubset1 +Cudd_zddSubset0 + + +
                            Defined in cuddZddSetop.c + +
                            +
                            +DdNode * 
                            +cuddZddSubset1(
                            +  DdManager * dd, 
                            +  DdNode * P, 
                            +  int  var 
                            +)
                            +
                            +
                            Computes the positive cofactor of a ZDD w.r.t. a + variable. In terms of combinations, the result is the set of all + combinations in which the variable is asserted. Returns a pointer to + the result if successful; NULL otherwise. cuddZddSubset1 performs + the same function as Cudd_zddSubset1, but does not restart if + reordering has taken place. Therefore it can be called from within a + recursive procedure. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddZddSubset0 +Cudd_zddSubset1 + + +
                            Defined in cuddZddSetop.c + +
                            +
                            +int 
                            +cuddZddSwapInPlace(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Swaps two adjacent variables. It assumes that no dead + nodes are present on entry to this procedure. The procedure then + guarantees that no dead nodes will be present when it terminates. + cuddZddSwapInPlace assumes that x < y. Returns the number of keys in + the table if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +int 
                            +cuddZddSwapping(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper, 
                            +  Cudd_ReorderingType  heuristic 
                            +)
                            +
                            +
                            Implementation of Plessier's algorithm that reorders + variables by a sequence of (non-adjacent) swaps. +
                              +
                            1. Select two variables (RANDOM or HEURISTIC). +
                            2. Permute these variables. +
                            3. If the nodes have decreased accept the permutation. +
                            4. Otherwise reconstruct the original heap. +
                            5. Loop. +
                            + Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +int 
                            +cuddZddSymmCheck(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Checks for symmetry of x and y. Ignores projection + functions, unless they are isolated. Returns 1 in case of + symmetry; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSymm.c + +
                            +
                            +static int 
                            +cuddZddSymmSiftingAux(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  x_low, 
                            +  int  x_high 
                            +)
                            +
                            +
                            Given x_low <= x <= x_high moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is not part of a symmetry group. Returns 1 if + successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSymm.c + +
                            +
                            +static int 
                            +cuddZddSymmSiftingBackward(
                            +  DdManager * table, 
                            +  Move * moves, 
                            +  int  size 
                            +)
                            +
                            +
                            Given a set of moves, returns the ZDD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSymm.c + +
                            +
                            +static int 
                            +cuddZddSymmSiftingConvAux(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  x_low, 
                            +  int  x_high 
                            +)
                            +
                            +
                            Given x_low <= x <= x_high moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is either an isolated variable, or it is the bottom of + a symmetry group. All symmetries may not have been found, because of + exceeded growth limit. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSymm.c + +
                            +
                            +int 
                            +cuddZddSymmSiftingConv(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Symmetric sifting to convergence algorithm for ZDDs. + Assumes that no dead nodes are present. +
                              +
                            1. Order all the variables according to the number of entries in + each unique subtable. +
                            2. Sift the variable up and down, remembering each time the total + size of the ZDD heap and grouping variables that are symmetric. +
                            3. Select the best permutation. +
                            4. Repeat 3 and 4 for all variables. +
                            5. Repeat 1-4 until no further improvement. +
                            + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddZddSymmSifting + + +
                            Defined in cuddZddSymm.c + +
                            +
                            +static Move * 
                            +cuddZddSymmSifting_down(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  x_high, 
                            +  int  initial_size 
                            +)
                            +
                            +
                            Moves x down until either it reaches the bound (x_high) + or the size of the ZDD heap increases too much. Assumes that x is the + bottom of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; ZDD_MV_OOM if memory is full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSymm.c + +
                            +
                            +static Move * 
                            +cuddZddSymmSifting_up(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  x_low, 
                            +  int  initial_size 
                            +)
                            +
                            +
                            Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much. Assumes that x is the top + of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; ZDD_MV_OOM if memory is full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSymm.c + +
                            +
                            +int 
                            +cuddZddSymmSifting(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Symmetric sifting algorithm. + Assumes that no dead nodes are present. +
                              +
                            1. Order all the variables according to the number of entries in + each unique subtable. +
                            2. Sift the variable up and down, remembering each time the total + size of the ZDD heap and grouping variables that are symmetric. +
                            3. Select the best permutation. +
                            4. Repeat 3 and 4 for all variables. +
                            + Returns 1 plus the number of symmetric variables if successful; 0 + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddZddSymmSiftingConv + + +
                            Defined in cuddZddSymm.c + +
                            +
                            +static void 
                            +cuddZddSymmSummary(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper, 
                            +  int * symvars, 
                            +  int * symgroups 
                            +)
                            +
                            +
                            Counts numbers of symmetric variables and symmetry + groups. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSymm.c + +
                            +
                            +int 
                            +cuddZddTreeSifting(
                            +  DdManager * table, DD table
                            +  Cudd_ReorderingType  method reordering method for the groups of leaves
                            +)
                            +
                            +
                            Tree sifting algorithm for ZDDs. Assumes that a tree + representing a group hierarchy is passed as a parameter. It then + reorders each group in postorder fashion by calling + zddTreeSiftingAux. Assumes that no dead nodes are present. Returns + 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +DdNode	* 
                            +cuddZddUnateProduct(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddUnateProduct. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_zddUnateProduct + + +
                            Defined in cuddZddFuncs.c + +
                            +
                            +static Move* 
                            +cuddZddUndoMoves(
                            +  DdManager * table, 
                            +  Move * moves 
                            +)
                            +
                            +
                            Given a set of moves, returns the ZDD heap to the + order in effect before the moves. Returns 1 in case of success; + 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddLin.c + +
                            +
                            +DdNode * 
                            +cuddZddUnion(
                            +  DdManager * zdd, 
                            +  DdNode * P, 
                            +  DdNode * Q 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddUnion. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSetop.c + +
                            +
                            +int 
                            +cuddZddUniqueCompare(
                            +  int * ptr_x, 
                            +  int * ptr_y 
                            +)
                            +
                            +
                            Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +DdNode	* 
                            +cuddZddWeakDivF(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddWeakDivF. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_zddWeakDivF + + +
                            Defined in cuddZddFuncs.c + +
                            +
                            +DdNode	* 
                            +cuddZddWeakDiv(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * g 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddWeakDiv. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_zddWeakDiv + + +
                            Defined in cuddZddFuncs.c + +
                            +
                            +static DdNode * 
                            +ddBddMaximallyExpand(
                            +  DdManager * dd, manager
                            +  DdNode * lb, cube to be expanded
                            +  DdNode * ub, upper bound cube
                            +  DdNode * f function against which to expand
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_bddMaximallyExpand. + Returns set of primes or zero BDD if successful; NULL otherwise. On entry + to this function, ub and lb should be different from the zero BDD. The + function then maintains this invariant. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSat.c + +
                            +
                            +static int 
                            +ddBddShortestPathUnate(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  int * phases, 
                            +  st_table * table 
                            +)
                            +
                            +
                            Performs shortest path computation on a unate function. + Returns the length of the shortest path to one if successful; + CUDD_OUT_OF_MEM otherwise. This function is based on the observation + that in the BDD of a unate function no node except the constant is + reachable from the root via paths of different parity. +

                            + +

                            Side Effects None +

                            + +

                            See Also getShortest + + +
                            Defined in cuddSat.c + +
                            +
                            +static DdNode * 
                            +ddBddToAddRecur(
                            +  DdManager * dd, 
                            +  DdNode * B 
                            +)
                            +
                            +
                            Performs the recursive step for Cudd_BddToAdd. Returns a + pointer to the resulting ADD if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddBridge.c + +
                            +
                            +static int 
                            +ddCheckPermuation(
                            +  DdManager * table, 
                            +  MtrNode * treenode, 
                            +  int * perm, 
                            +  int * invperm 
                            +)
                            +
                            +
                            Checks the BDD variable group tree before a shuffle. + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects Changes the BDD variable group tree. +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +static void 
                            +ddClearFlag(
                            +  DdNode * f 
                            +)
                            +
                            +
                            Performs a DFS from f, clearing the LSB of the next + pointers. +

                            + +

                            Side Effects None +

                            + +

                            See Also ddSupportStep +ddFindSupport +ddLeavesInt +ddDagInt + + +
                            Defined in cuddUtil.c + +
                            +
                            +static void 
                            +ddClearGlobal(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  maxlevel 
                            +)
                            +
                            +
                            Scans the DD and clears the LSB of the next pointers. + The LSB of the next pointers are used as markers to tell whether a + node was reached. Once the roots are counted, these flags are + reset. +

                            + +

                            Side Effects None +

                            + +

                            See Also ddCountRoots + + +
                            Defined in cuddExact.c + +
                            +
                            +static void 
                            +ddClearGlobal(
                            +  DdManager * table 
                            +)
                            +
                            +
                            The LSB of the next pointers are used as markers to tell + whether a node was reached by at least one DFS. Once the interaction + matrix is built, these flags are reset. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddInteract.c + +
                            +
                            +static void 
                            +ddClearLocal(
                            +  DdNode * f 
                            +)
                            +
                            +
                            Performs a DFS from f, clearing the LSB of the then pointers. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddInteract.c + +
                            +
                            +static void 
                            +ddClearVars(
                            +  DdManager * dd, 
                            +  int  SP 
                            +)
                            +
                            +
                            Clears visited flags for variables. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +static double * 
                            +ddCofMintermAux(
                            +  DdManager * dd, 
                            +  DdNode * node, 
                            +  st_table * table 
                            +)
                            +
                            +
                            Traverses the DD node and computes the fraction of + minterms in the on-set of all positive cofactors simultaneously. + It allocates an array with two more entries than there are + variables below the one labeling the node. One extra entry (the + first in the array) is for the variable labeling the node. The other + entry (the last one in the array) holds the fraction of minterms of + the function rooted at node. Each other entry holds the value for + one cofactor. The array is put in a symbol table, to avoid repeated + computation, and its address is returned by the procedure, for use + by the caller. Returns a pointer to the array of cofactor measures. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSign.c + +
                            +
                            +static int 
                            +ddCountInternalMtrNodes(
                            +  DdManager * table, 
                            +  MtrNode * treenode 
                            +)
                            +
                            +
                            Counts the number of internal nodes of the group tree. + Returns the count. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static double 
                            +ddCountMintermAux(
                            +  DdNode * node, 
                            +  double  max, 
                            +  DdHashTable * table 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_CountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. Does not use the + identity |f'| = max - |f|, to minimize loss of accuracy due to + roundoff. Returns the number of minterms of the function rooted at + node. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +static double 
                            +ddCountPathAux(
                            +  DdNode * node, 
                            +  st_table * table 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_CountPath. + It is based on the following identity. Let |f| be the + number of paths of f. Then: + + |f| = |f0|+|f1| + + where f0 and f1 are the two cofactors of f. Uses the + identity |f'| = |f|, to improve the utilization of the (local) cache. + Returns the number of paths of the function rooted at node. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +static double 
                            +ddCountPathsToNonZero(
                            +  DdNode * N, 
                            +  st_table * table 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_CountPathsToNonZero. + It is based on the following identity. Let |f| be the + number of paths of f. Then: + + |f| = |f0|+|f1| + + where f0 and f1 are the two cofactors of f. Returns the number of + paths of the function rooted at node. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +static int 
                            +ddCountRoots(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Counts the number of roots at the levels between lower and + upper. The computation is based on breadth-first search. + A node is a root if it is not reachable from any previously visited node. + (All the nodes at level lower are therefore considered roots.) + The visited flag uses the LSB of the next pointer. Returns the root + count. The roots that are constant nodes are always ignored. +

                            + +

                            Side Effects None +

                            + +

                            See Also ddClearGlobal + + +
                            Defined in cuddExact.c + +
                            +
                            +static void 
                            +ddCreateGroup(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Creates a group encompassing variables from x to y in the + DD table. In the current implementation it must be y == x+1. + Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddDagInt(
                            +  DdNode * n 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_DagSize. Returns the + number of nodes in the graph rooted at n. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +static void 
                            +ddDissolveGroup(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            x and y are variables in a group to be cut in two. The cut + is to pass between x and y. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddDoDumpBlif(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  FILE * fp, 
                            +  st_table * visited, 
                            +  char ** names, 
                            +  int  mv 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_DumpBlif. Traverses + the BDD f and writes a multiplexer-network description to the file + pointed by fp in blif format. f is assumed to be a regular pointer + and ddDoDumpBlif guarantees this assumption in the recursive calls. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddExport.c + +
                            +
                            +static int 
                            +ddDoDumpDDcal(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  FILE * fp, 
                            +  st_table * visited, 
                            +  char ** names, 
                            +  ptruint  mask 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_DumpDDcal. Traverses + the BDD f and writes a line for each node to the file + pointed by fp in DDcal format. f is assumed to be a regular pointer + and ddDoDumpDDcal guarantees this assumption in the recursive calls. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddExport.c + +
                            +
                            +static int 
                            +ddDoDumpDaVinci(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  FILE * fp, 
                            +  st_table * visited, 
                            +  char ** names, 
                            +  ptruint  mask 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_DumpDaVinci. Traverses + the BDD f and writes a term expression to the file + pointed by fp in daVinci format. f is assumed to be a regular pointer + and ddDoDumpDaVinci guarantees this assumption in the recursive calls. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddExport.c + +
                            +
                            +static int 
                            +ddDoDumpFactoredForm(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  FILE * fp, 
                            +  char ** names 
                            +)
                            +
                            +
                            Performs the recursive step of + Cudd_DumpFactoredForm. Traverses the BDD f and writes a factored + form for each node to the file pointed by fp in terms of the + factored forms of the children. Constants are propagated, and + absorption is applied. f is assumed to be a regular pointer and + ddDoDumpFActoredForm guarantees this assumption in the recursive + calls. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_DumpFactoredForm + + +
                            Defined in cuddExport.c + +
                            +
                            +static int 
                            +ddEpdCountMintermAux(
                            +  DdNode * node, 
                            +  EpDouble * max, 
                            +  EpDouble * epd, 
                            +  st_table * table 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_EpdCountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. Does not use the + identity |f'| = max - |f|, to minimize loss of accuracy due to + roundoff. Returns the number of minterms of the function rooted at + node. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +static enum st_retval 
                            +ddEpdFree(
                            +  char * key, 
                            +  char * value, 
                            +  char * arg 
                            +)
                            +
                            +
                            Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +static int 
                            +ddExchange(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y, 
                            +  double  temp 
                            +)
                            +
                            +
                            This is the same funcion as ddSwapping except for + comparison expression. Use probability function, exp(-size_change/temp). +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAnneal.c + +
                            +
                            +static int 
                            +ddExtSymmCheck(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Checks for extended symmetry of x and y. Returns 1 in + case of extended symmetry; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static DdNode * 
                            +ddFindEssentialRecur(
                            +  DdManager * dd, 
                            +  DdNode * f 
                            +)
                            +
                            +
                            Implements the recursive step of Cudd_FindEssential. + Returns a pointer to the cube BDD if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddEssent.c + +
                            +
                            +static void 
                            +ddFindNodeHiLo(
                            +  DdManager * table, 
                            +  MtrNode * treenode, 
                            +  int * lower, 
                            +  int * upper 
                            +)
                            +
                            +
                            Finds the lower and upper bounds of the group + represented by treenode. From the index and size fields we need to + derive the current positions, and find maximum and minimum. +

                            + +

                            Side Effects The bounds are returned as side effects. +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static void 
                            +ddFindSupport(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  int * SP 
                            +)
                            +
                            +
                            Recursively find the support of f. This function uses the + LSB of the next field of the nodes of f as visited flag. It also uses the + LSB of the next field of the variables as flag to remember whether a + certain index has already been seen. Finally, it uses the manager stack + to record all seen indices. +

                            + +

                            Side Effects The stack pointer SP is modified by side-effect. The next + fields are changed and need to be reset. +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +static DdTlcInfo * 
                            +ddFindTwoLiteralClausesRecur(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  st_table * table 
                            +)
                            +
                            +
                            Implements the recursive step of + Cudd_FindTwoLiteralClauses. The DD node is assumed to be not + constant. Returns a pointer to a set of clauses if successful; NULL + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_FindTwoLiteralClauses + + +
                            Defined in cuddEssent.c + +
                            +
                            +static DdNode * 
                            +ddGetLargestCubeUnate(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  int * phases, 
                            +  st_table * table 
                            +)
                            +
                            +
                            Extracts largest prime of a unate function. Returns the BDD of + the prime if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also getPath + + +
                            Defined in cuddSat.c + +
                            +
                            +static int 
                            +ddGroupMoveBackward(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Undoes the swap two groups. Returns 1 in case of + success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddGroupMove(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y, 
                            +  Move ** moves 
                            +)
                            +
                            +
                            Swaps two groups and records the move. Returns the + number of keys in the DD table in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddGroupSiftingAux(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xLow, 
                            +  int  xHigh, 
                            +  DD_CHKFP  checkFunction, 
                            +  int  lazyFlag 
                            +)
                            +
                            +
                            Sifts one variable up and down until it has taken all + positions. Checks for aggregation. There may be at most two sweeps, + even if the group grows. Assumes that x is either an isolated + variable, or it is the bottom of a group. All groups may not have + been found. The variable being moved is returned to the best position + seen during sifting. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddGroupSiftingBackward(
                            +  DdManager * table, 
                            +  Move * moves, 
                            +  int  size, 
                            +  int  upFlag, 
                            +  int  lazyFlag 
                            +)
                            +
                            +
                            Determines the best position for a variables and returns + it there. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddGroupSiftingDown(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xHigh, 
                            +  DD_CHKFP  checkFunction, 
                            +  Move ** moves 
                            +)
                            +
                            +
                            Sifts down a variable until it reaches position xHigh. + Assumes that x is the bottom of a group (or a singleton). Records + all the moves. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddGroupSiftingUp(
                            +  DdManager * table, 
                            +  int  y, 
                            +  int  xLow, 
                            +  DD_CHKFP  checkFunction, 
                            +  Move ** moves 
                            +)
                            +
                            +
                            Sifts up a variable until either it reaches position + xLow or the size of the DD heap increases too much. Assumes that y is + the top of a group (or a singleton). Checks y for aggregation to the + adjacent variables. Records all the moves that are appended to the + list of moves received as input and returned as a side effect. + Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddGroupSifting(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper, 
                            +  DD_CHKFP  checkFunction, 
                            +  int  lazyFlag 
                            +)
                            +
                            +
                            Sifts from treenode->low to treenode->high. If + croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the + end of the initial sifting. If a group is created, it is then sifted + again. After sifting one variable, the group that contains it is + dissolved. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddIsVarHandled(
                            +  DdManager * dd, 
                            +  int  index 
                            +)
                            +
                            +
                            Checks whether a variables is already handled. This + function is used for lazy sifting. +

                            + +

                            Side Effects none +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddJumpingAux(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  x_low, 
                            +  int  x_high, 
                            +  double  temp 
                            +)
                            +
                            +
                            If x==x_low, it executes jumping_down. If x==x_high, it + executes jumping_up. This funcion is similar to ddSiftingAux. Returns + 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAnneal.c + +
                            +
                            +static Move * 
                            +ddJumpingDown(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  x_high, 
                            +  int  initial_size 
                            +)
                            +
                            +
                            This is a simplified version of ddSiftingDown. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAnneal.c + +
                            +
                            +static Move * 
                            +ddJumpingUp(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  x_low, 
                            +  int  initial_size 
                            +)
                            +
                            +
                            This is a simplified version of ddSiftingUp. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAnneal.c + +
                            +
                            +static int 
                            +ddLeavesInt(
                            +  DdNode * n 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_CountLeaves. Returns + the number of leaves in the DD rooted at n. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_CountLeaves + + +
                            Defined in cuddUtil.c + +
                            +
                            +static int 
                            +ddLinearAndSiftingAux(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xLow, 
                            +  int  xHigh 
                            +)
                            +
                            +
                            Given xLow <= x <= xHigh moves x up and down between the + boundaries. At each step a linear transformation is tried, and, if it + decreases the size of the DD, it is accepted. Finds the best position + and does the required changes. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLinear.c + +
                            +
                            +static int 
                            +ddLinearAndSiftingBackward(
                            +  DdManager * table, 
                            +  int  size, 
                            +  Move * moves 
                            +)
                            +
                            +
                            Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLinear.c + +
                            +
                            +static Move * 
                            +ddLinearAndSiftingDown(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xHigh, 
                            +  Move * prevMoves 
                            +)
                            +
                            +
                            Sifts a variable down and applies linear + transformations. Moves x down until either it reaches the bound + (xHigh) or the size of the DD heap increases too much. Returns the + set of moves in case of success; NULL if memory is full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLinear.c + +
                            +
                            +static Move * 
                            +ddLinearAndSiftingUp(
                            +  DdManager * table, 
                            +  int  y, 
                            +  int  xLow, 
                            +  Move * prevMoves 
                            +)
                            +
                            +
                            Sifts a variable up and applies linear transformations. + Moves y up until either it reaches the bound (xLow) or the size of + the DD heap increases too much. Returns the set of moves in case of + success; NULL if memory is full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLinear.c + +
                            +
                            +static int 
                            +ddLinearUniqueCompare(
                            +  int * ptrX, 
                            +  int * ptrY 
                            +)
                            +
                            +
                            Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLinear.c + +
                            +
                            +static void 
                            +ddMergeGroups(
                            +  DdManager * table, 
                            +  MtrNode * treenode, 
                            +  int  low, 
                            +  int  high 
                            +)
                            +
                            +
                            Creates a single group from low to high and adjusts the + index field of the tree node. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddNoCheck(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Pretends to check two variables for aggregation. Always + returns 0. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static void 
                            +ddPatchTree(
                            +  DdManager * dd, 
                            +  MtrNode * treenode 
                            +)
                            +
                            +
                            Fixes a variable tree after the insertion of new subtables. + After such an insertion, the low fields of the tree below the insertion + point are inconsistent. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddTable.c + +
                            +
                            +static int 
                            +ddPermuteWindow3(
                            +  DdManager * table, 
                            +  int  x 
                            +)
                            +
                            +
                            Tries all the permutations of the three variables between + x and x+2 and retains the best. Assumes that no dead nodes are + present. Returns the index of the best permutation (1-6) in case of + success; 0 otherwise.Assumes that no dead nodes are present. Returns + the index of the best permutation (1-6) in case of success; 0 + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddWindow.c + +
                            +
                            +static int 
                            +ddPermuteWindow4(
                            +  DdManager * table, 
                            +  int  w 
                            +)
                            +
                            +
                            Tries all the permutations of the four variables between + w and w+3 and retains the best. Assumes that no dead nodes are + present. Returns the index of the best permutation (1-24) in case of + success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddWindow.c + +
                            +
                            +static int 
                            +ddPickArbitraryMinterms(
                            +  DdManager * dd, 
                            +  DdNode * node, 
                            +  int  nvars, 
                            +  int  nminterms, 
                            +  char ** string 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_bddPickArbitraryMinterms. + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_bddPickArbitraryMinterms + + +
                            Defined in cuddUtil.c + +
                            +
                            +static int 
                            +ddPickRepresentativeCube(
                            +  DdManager * dd, 
                            +  DdNode * node, 
                            +  double * weight, 
                            +  char * string 
                            +)
                            +
                            +
                            Finds a representative cube of a BDD with the weight of + each variable. From the top variable, if the weight is greater than or + equal to 0.0, choose THEN branch unless the child is the constant 0. + Otherwise, choose ELSE branch unless the child is the constant 0. +

                            + +

                            Side Effects Cudd_SubsetWithMaskVars Cudd_bddPickOneCube +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +static void 
                            +ddPrintMintermAux(
                            +  DdManager * dd, manager
                            +  DdNode * node, current node
                            +  int * list current recursion path
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_PrintMinterm. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +static void 
                            +ddRehashZdd(
                            +  DdManager * unique, 
                            +  int  i 
                            +)
                            +
                            +
                            Rehashes a ZDD unique subtable. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddRehash + + +
                            Defined in cuddTable.c + +
                            +
                            +static int 
                            +ddReorderChildren(
                            +  DdManager * table, 
                            +  MtrNode * treenode, 
                            +  Cudd_ReorderingType  method 
                            +)
                            +
                            +
                            Reorders the children of a group tree node according to + the options. After reordering puts all the variables in the group + and/or its descendents in a single group. This allows hierarchical + reordering. If the variables in the group do not exist yet, simply + does nothing. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddReorderPostprocess(
                            +  DdManager * table 
                            +)
                            +
                            +
                            Cleans up at the end of reordering. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +static int 
                            +ddReorderPreprocess(
                            +  DdManager * table 
                            +)
                            +
                            +
                            Prepares the DD heap for dynamic reordering. Does + garbage collection, to guarantee that there are no dead nodes; + clears the cache, which is invalidated by dynamic reordering; initializes + the number of isolated projection functions; and initializes the + interaction matrix. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +static void 
                            +ddReportRefMess(
                            +  DdManager * unique, manager
                            +  int  i, table in which the problem occurred
                            +  const char * caller procedure that detected the problem
                            +)
                            +
                            +
                            Reports problem in garbage collection. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddGarbageCollect +cuddGarbageCollectZdd + + +
                            Defined in cuddTable.c + +
                            +
                            +static int 
                            +ddResetVarHandled(
                            +  DdManager * dd, 
                            +  int  index 
                            +)
                            +
                            +
                            Resets a variable to be processed. This function is used + for lazy sifting. +

                            + +

                            Side Effects none +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddResizeTable(
                            +  DdManager * unique, 
                            +  int  index, 
                            +  int  amount 
                            +)
                            +
                            +
                            Increases the number of subtables in a unique table so + that it meets or exceeds index. The parameter amount determines how + much spare space is allocated to prevent too frequent resizing. If + index is negative, the table is resized, but no new variables are + created. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_Reserve +cuddResizeTableZdd + + +
                            Defined in cuddTable.c + +
                            +
                            +static int 
                            +ddSecDiffCheck(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Checks two variables for aggregation. The check is based + on the second difference of the number of nodes as a function of the + layer. If the second difference is lower than a given threshold + (typically negative) then the two variables should be aggregated. + Returns 1 if the two variables pass the test; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddSetVarHandled(
                            +  DdManager * dd, 
                            +  int  index 
                            +)
                            +
                            +
                            Sets a variable to already handled. This function is used + for lazy sifting. +

                            + +

                            Side Effects none +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddShuffle(
                            +  DdManager * table, 
                            +  DdHalfWord * permutation, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Reorders variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. ddShuffle assumes that no + dead nodes are present and that the interaction matrix is properly + initialized. The reordering is achieved by a series of upward sifts. + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddExact.c + +
                            +
                            +static int 
                            +ddShuffle(
                            +  DdManager * table, 
                            +  int * permutation 
                            +)
                            +
                            +
                            Reorders variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. ddShuffle assumes that no + dead nodes are present and that the interaction matrix is properly + initialized. The reordering is achieved by a series of upward sifts. + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +static int 
                            +ddSiftUp(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xLow 
                            +)
                            +
                            +
                            Takes a variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddExact.c + +
                            +
                            +static int 
                            +ddSiftUp(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xLow 
                            +)
                            +
                            +
                            Takes a variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +static int 
                            +ddSiftingAux(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xLow, 
                            +  int  xHigh 
                            +)
                            +
                            +
                            Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +static int 
                            +ddSiftingBackward(
                            +  DdManager * table, 
                            +  int  size, 
                            +  Move * moves 
                            +)
                            +
                            +
                            Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +static Move * 
                            +ddSiftingDown(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xHigh 
                            +)
                            +
                            +
                            Sifts a variable down. Moves x down until either it + reaches the bound (xHigh) or the size of the DD heap increases too + much. Returns the set of moves in case of success; NULL if memory is + full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +static Move * 
                            +ddSiftingUp(
                            +  DdManager * table, 
                            +  int  y, 
                            +  int  xLow 
                            +)
                            +
                            +
                            Sifts a variable up. Moves y up until either it reaches + the bound (xLow) or the size of the DD heap increases too much. + Returns the set of moves in case of success; NULL if memory is full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +static void 
                            +ddSuppInteract(
                            +  DdNode * f, 
                            +  char * support 
                            +)
                            +
                            +
                            Performs a DFS from f. Uses the LSB of the then pointer + as visited flag. +

                            + +

                            Side Effects Accumulates in support the variables on which f depends. +

                            + +

                            Defined in cuddInteract.c + +
                            +
                            +static void 
                            +ddSupportStep(
                            +  DdNode * f, 
                            +  int * support 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_Support. Performs a + DFS from f. The support is accumulated in supp as a side effect. Uses + the LSB of the then pointer as visited flag. +

                            + +

                            Side Effects None +

                            + +

                            See Also ddClearFlag + + +
                            Defined in cuddUtil.c + +
                            +
                            +static Move * 
                            +ddSwapAny(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Swaps any two variables. Returns the set of moves. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +static int 
                            +ddSymmGroupMoveBackward(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Undoes the swap of two groups. x is assumed to be the + bottom variable of the first group. y is assumed to be the top + variable of the second group. Returns the number of keys in the table + if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSymmetry.c + +
                            +
                            +static int 
                            +ddSymmGroupMove(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y, 
                            +  Move ** moves 
                            +)
                            +
                            +
                            Swaps two groups. x is assumed to be the bottom variable + of the first group. y is assumed to be the top variable of the second + group. Updates the list of moves. Returns the number of keys in the + table if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSymmetry.c + +
                            +
                            +static int 
                            +ddSymmSiftingAux(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xLow, 
                            +  int  xHigh 
                            +)
                            +
                            +
                            Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is not part of a symmetry group. Returns 1 if + successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSymmetry.c + +
                            +
                            +static int 
                            +ddSymmSiftingBackward(
                            +  DdManager * table, 
                            +  Move * moves, 
                            +  int  size 
                            +)
                            +
                            +
                            Given a set of moves, returns the DD heap to the + position giving the minimum size. In case of ties, returns to the + closest position giving the minimum size. Returns 1 in case of + success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSymmetry.c + +
                            +
                            +static int 
                            +ddSymmSiftingConvAux(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xLow, 
                            +  int  xHigh 
                            +)
                            +
                            +
                            Given xLow <= x <= xHigh moves x up and down between the + boundaries. Finds the best position and does the required changes. + Assumes that x is either an isolated variable, or it is the bottom of + a symmetry group. All symmetries may not have been found, because of + exceeded growth limit. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSymmetry.c + +
                            +
                            +static Move * 
                            +ddSymmSiftingDown(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xHigh 
                            +)
                            +
                            +
                            Moves x down until either it reaches the bound (xHigh) + or the size of the DD heap increases too much. Assumes that x is the + bottom of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; MV_OOM if memory is full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSymmetry.c + +
                            +
                            +static Move * 
                            +ddSymmSiftingUp(
                            +  DdManager * table, 
                            +  int  y, 
                            +  int  xLow 
                            +)
                            +
                            +
                            Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much. Assumes that x is the top + of a symmetry group. Checks x for symmetry to the adjacent + variables. If symmetry is found, the symmetry group of x is merged + with the symmetry group of the other variable. Returns the set of + moves in case of success; MV_OOM if memory is full. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSymmetry.c + +
                            +
                            +static void 
                            +ddSymmSummary(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper, 
                            +  int * symvars, 
                            +  int * symgroups 
                            +)
                            +
                            +
                            Counts numbers of symmetric variables and symmetry + groups. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSymmetry.c + +
                            +
                            +static int 
                            +ddSymmUniqueCompare(
                            +  int * ptrX, 
                            +  int * ptrY 
                            +)
                            +
                            +
                            Comparison function used by qsort to order the variables + according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSymmetry.c + +
                            +
                            +static int 
                            +ddTreeSiftingAux(
                            +  DdManager * table, 
                            +  MtrNode * treenode, 
                            +  Cudd_ReorderingType  method 
                            +)
                            +
                            +
                            Recursively visits the group tree and reorders each + group in postorder fashion. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static Move* 
                            +ddUndoMoves(
                            +  DdManager * table, 
                            +  Move * moves 
                            +)
                            +
                            +
                            Given a set of moves, returns the DD heap to the + order in effect before the moves. Returns 1 in case of success; + 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLinear.c + +
                            +
                            +static int 
                            +ddUniqueCompareGroup(
                            +  int * ptrX, 
                            +  int * ptrY 
                            +)
                            +
                            +
                            Comparison function used by qsort to order the variables + according to the number of keys in the subtables. Returns the + difference in number of keys between the two variables being + compared. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddUniqueCompare(
                            +  int * ptrX, 
                            +  int * ptrY 
                            +)
                            +
                            +
                            Comparison function used by qsort to order the + variables according to the number of keys in the subtables. + Returns the difference in number of keys between the two + variables being compared. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +static void 
                            +ddUpdateInteract(
                            +  DdManager * table, 
                            +  char * support 
                            +)
                            +
                            +
                            If support[i +

                            + +

                            Side Effects Clears support. +

                            + +

                            Defined in cuddInteract.c + +
                            +
                            +static int 
                            +ddUpdateMtrTree(
                            +  DdManager * table, 
                            +  MtrNode * treenode, 
                            +  int * perm, 
                            +  int * invperm 
                            +)
                            +
                            +
                            Updates the BDD variable group tree before a shuffle. + Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects Changes the BDD variable group tree. +

                            + +

                            Defined in cuddReorder.c + +
                            +
                            +static int 
                            +ddVarGroupCheck(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Checks for grouping of x and y. Returns 1 in + case of grouping; 0 otherwise. This function is used for lazy sifting. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGroup.c + +
                            +
                            +static int 
                            +ddWindow2(
                            +  DdManager * table, 
                            +  int  low, 
                            +  int  high 
                            +)
                            +
                            +
                            Reorders by applying a sliding window of width 2. + Tries both permutations of the variables in a window + that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddWindow.c + +
                            +
                            +static int 
                            +ddWindow3(
                            +  DdManager * table, 
                            +  int  low, 
                            +  int  high 
                            +)
                            +
                            +
                            Reorders by applying a sliding window of width 3. + Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddWindow.c + +
                            +
                            +static int 
                            +ddWindow4(
                            +  DdManager * table, 
                            +  int  low, 
                            +  int  high 
                            +)
                            +
                            +
                            Reorders by applying a sliding window of width 4. + Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddWindow.c + +
                            +
                            +static int 
                            +ddWindowConv2(
                            +  DdManager * table, 
                            +  int  low, 
                            +  int  high 
                            +)
                            +
                            +
                            Reorders by repeatedly applying a sliding window of width + 2. Tries both permutations of the variables in a window + that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddWindow.c + +
                            +
                            +static int 
                            +ddWindowConv3(
                            +  DdManager * table, 
                            +  int  low, 
                            +  int  high 
                            +)
                            +
                            +
                            Reorders by repeatedly applying a sliding window of width + 3. Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddWindow.c + +
                            +
                            +static int 
                            +ddWindowConv4(
                            +  DdManager * table, 
                            +  int  low, 
                            +  int  high 
                            +)
                            +
                            +
                            Reorders by repeatedly applying a sliding window of width + 4. Tries all possible permutations to the variables in a + window that slides from low to high. Assumes that no dead nodes are + present. Uses an event-driven approach to determine convergence. + Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddWindow.c + +
                            +
                            +static void 
                            +debugCheckParent(
                            +  DdManager * table, 
                            +  DdNode * node 
                            +)
                            +
                            +
                            Searches all the subtables above node. Very expensive. + The same check is now implemented more efficiently in ddDebugCheck. +

                            + +

                            Side Effects None +

                            + +

                            See Also debugFindParent + + +
                            Defined in cuddCheck.c + +
                            +
                            +static void 
                            +debugFindParent(
                            +  DdManager * table, 
                            +  DdNode * node 
                            +)
                            +
                            +
                            Searches the subtables above node for its parents. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCheck.c + +
                            +
                            + 
                            +double *þprobþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +double þmgþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +double þmgþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +double þmþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +double þquality0þminimum improvement for accepted changes when b=0(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +double þquality0þminimum improvement for accepted changes when b=0(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +double þqualityþminimum improvement for accepted changes(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +double þqualityþminimum improvement for accepted changes(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +double þqualityþminimum improvement for accepted changes(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +double þqualityþminimum improvement for accepted changes(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            +static int 
                            +dp2(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  st_table * t 
                            +)
                            +
                            +
                            Performs the recursive step of cuddP. Returns 1 in case + of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +static DdTlcInfo * 
                            +emptyClauseSet(
                            +    
                            +)
                            +
                            +
                            Returns a pointer to an empty set of clauses if + successful; NULL otherwise. No bit vector for the phases is + allocated. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddEssent.c + +
                            +
                            +static int 
                            +equalp(
                            +  DdHalfWord  var1a, 
                            +  short  phase1a, 
                            +  DdHalfWord  var1b, 
                            +  short  phase1b, 
                            +  DdHalfWord  var2a, 
                            +  short  phase2a, 
                            +  DdHalfWord  var2b, 
                            +  short  phase2b 
                            +)
                            +
                            +
                            Returns true iff the two arguments are identical + clauses. Since literals are sorted, we only need to compare + literals in the same position. +

                            + +

                            Side Effects None +

                            + +

                            See Also beforep + + +
                            Defined in cuddEssent.c + +
                            +
                            +static int 
                            +find_best(
                            +    
                            +)
                            +
                            +
                            Returns the index of the fittest individual. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGenetic.c + +
                            +
                            +static void 
                            +fixVarTree(
                            +  MtrNode * treenode, 
                            +  int * perm, 
                            +  int  size 
                            +)
                            +
                            +
                            Fixes a variable group tree. +

                            + +

                            Side Effects Changes the variable group tree. +

                            + +

                            Defined in cuddAPI.c + +
                            +
                            +static void 
                            +freeMatrix(
                            +  DdHalfWord ** matrix 
                            +)
                            +
                            +
                            Frees a two-dimensional matrix allocated by getMatrix. +

                            + +

                            Side Effects None +

                            + +

                            See Also getMatrix + + +
                            Defined in cuddExact.c + +
                            +
                            +static enum st_retval 
                            +freePathPair(
                            +  char * key, 
                            +  char * value, 
                            +  char * arg 
                            +)
                            +
                            +
                            Frees the entries of the visited symbol table. Returns + ST_CONTINUE. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSat.c + +
                            +
                            +static NodeData * 
                            +gatherInfoAux(
                            +  DdNode * node, function to analyze
                            +  ApproxInfo * info, info on BDD
                            +  int  parity gather parity information
                            +)
                            +
                            +
                            Recursively counts minterms and computes reference + counts of each node in the BDD. Similar to the cuddCountMintermAux + which recursively counts the number of minterms for the dag rooted + at each node in terms of the total number of variables (max). It assumes + that the node pointer passed to it is regular and it maintains the + invariant. +

                            + +

                            Side Effects None +

                            + +

                            See Also gatherInfo + + +
                            Defined in cuddApprox.c + +
                            +
                            +static ApproxInfo * 
                            +gatherInfo(
                            +  DdManager * dd, manager
                            +  DdNode * node, function to be analyzed
                            +  int  numVars, number of variables node depends on
                            +  int  parity gather parity information
                            +)
                            +
                            +
                            Counts minterms and computes reference counts of each + node in the BDD. The minterm count is separately computed for the + node and its complement. This is to avoid cancellation + errors. Returns a pointer to the data structure holding the + information gathered if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddUnderApprox +gatherInfoAux + + +
                            Defined in cuddApprox.c + +
                            +
                            +static int 
                            +gcd(
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Returns the gcd of two integers. Uses the binary GCD + algorithm described in Cormen, Leiserson, and Rivest. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddExact.c + +
                            +
                            +static DdNode * 
                            +getCube(
                            +  DdManager * manager, 
                            +  st_table * visited, 
                            +  DdNode * f, 
                            +  int  cost 
                            +)
                            +
                            +
                            Build a BDD for a largest cube of f. + Given the minimum length from the root, and the minimum + lengths for each node (in visited), apply triangulation at each node. + Of the two children of each node on a shortest path, at least one is + on a shortest path. In case of ties the procedure chooses the THEN + children. + Returns a pointer to the cube BDD representing the path if + successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSat.c + +
                            +
                            +static cuddPathPair 
                            +getLargest(
                            +  DdNode * root, 
                            +  st_table * visited 
                            +)
                            +
                            +
                            Finds the size of the largest cube(s) in a DD. + This problem is translated into finding the shortest paths from a node + when both THEN and ELSE arcs have unit lengths. + Uses a local symbol table to store the lengths for each + node. Only the lengths for the regular nodes are entered in the table, + because those for the complement nodes are simply obtained by swapping + the two lenghts. + Returns a pair of lengths: the length of the shortest path to 1; + and the length of the shortest path to 0. This is done so as to take + complement arcs into account. +

                            + +

                            Side Effects none +

                            + +

                            Defined in cuddSat.c + +
                            +
                            +static int 
                            +getLevelKeys(
                            +  DdManager * table, 
                            +  int  l 
                            +)
                            +
                            +
                            Returns the number of nodes at one level of a unique table. + The projection function, if isolated, is not counted. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddExact.c + +
                            +
                            +static DdHalfWord ** 
                            +getMatrix(
                            +  int  rows, number of rows
                            +  int  cols number of columns
                            +)
                            +
                            +
                            Allocates a two-dimensional matrix of ints. + Returns the pointer to the matrix if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also freeMatrix + + +
                            Defined in cuddExact.c + +
                            +
                            +static int 
                            +getMaxBinomial(
                            +  int  n 
                            +)
                            +
                            +
                            Computes the maximum value of (n choose k) for a given + n. The maximum value occurs for k = n/2 when n is even, or k = + (n-1)/2 when n is odd. The algorithm used in this procedure avoids + intermediate overflow problems. It is based on the identity +
                            +    binomial(n,k) = n/k * binomial(n-1,k-1).
                            +  
                            + Returns the computed value if successful; -1 if out of range. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddExact.c + +
                            +
                            +static DdNode * 
                            +getPath(
                            +  DdManager * manager, 
                            +  st_table * visited, 
                            +  DdNode * f, 
                            +  int * weight, 
                            +  int  cost 
                            +)
                            +
                            +
                            Build a BDD for a shortest path of f. + Given the minimum length from the root, and the minimum + lengths for each node (in visited), apply triangulation at each node. + Of the two children of each node on a shortest path, at least one is + on a shortest path. In case of ties the procedure chooses the THEN + children. + Returns a pointer to the cube BDD representing the path if + successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSat.c + +
                            +
                            +static cuddPathPair 
                            +getShortest(
                            +  DdNode * root, 
                            +  int * cost, 
                            +  int * support, 
                            +  st_table * visited 
                            +)
                            +
                            +
                            Finds the length of the shortest path(s) in a DD. + Uses a local symbol table to store the lengths for each + node. Only the lengths for the regular nodes are entered in the table, + because those for the complement nodes are simply obtained by swapping + the two lenghts. + Returns a pair of lengths: the length of the shortest path to 1; + and the length of the shortest path to 0. This is done so as to take + complement arcs into account. +

                            + +

                            Side Effects Accumulates the support of the DD in support. +

                            + +

                            Defined in cuddSat.c + +
                            +
                            +static void 
                            +hashDelete(
                            +  DdLevelQueue * queue, 
                            +  DdQueueItem * item 
                            +)
                            +
                            +
                            Removes an item from the hash table of a level queue. + Nothing is done if the item is not in the table. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddLevelQueueDequeue +hashInsert + + +
                            Defined in cuddLevelQ.c + +
                            +
                            +static int 
                            +hashInsert(
                            +  DdLevelQueue * queue, 
                            +  DdQueueItem * item 
                            +)
                            +
                            +
                            Inserts an item in the hash table of a level queue. Returns + 1 if successful; 0 otherwise. No check is performed to see if an item with + the same key is already in the hash table. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddLevelQueueEnqueue + + +
                            Defined in cuddLevelQ.c + +
                            +
                            +static DdQueueItem * 
                            +hashLookup(
                            +  DdLevelQueue * queue, 
                            +  void * key 
                            +)
                            +
                            +
                            Looks up a key in the hash table of a level queue. Returns + a pointer to the item with the given key if the key is found; NULL + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddLevelQueueEnqueue +hashInsert + + +
                            Defined in cuddLevelQ.c + +
                            +
                            +static int 
                            +hashResize(
                            +  DdLevelQueue * queue 
                            +)
                            +
                            +
                            Resizes the hash table of a level queue. Returns 1 if + successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also hashInsert + + +
                            Defined in cuddLevelQ.c + +
                            +
                            +static int 
                            +impliedp(
                            +  DdHalfWord  var1, 
                            +  short  phase1, 
                            +  DdHalfWord  var2, 
                            +  short  phase2, 
                            +  BitVector * olv, 
                            +  BitVector * olp 
                            +)
                            +
                            +
                            Returns true iff either literal of a clause is in a set + of literals. The first four arguments specify the clause. The + remaining two arguments specify the literal set. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddEssent.c + +
                            +
                            +static int 
                            +indexCompare(
                            +  const void * a, 
                            +  const void * b 
                            +)
                            +
                            +
                            Compares indices for qsort. Subtracting these integers + cannot produce overflow, because they are non-negative. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddUtil.c + +
                            +
                            +static DdHalfWord * 
                            +initSymmInfo(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Translates the symmetry information stored in the next + field of each subtable from level to indices. This procedure is called + immediately after symmetric sifting, so that the next fields are correct. + By translating this informaton in terms of indices, we make it independent + of subsequent reorderings. The format used is that of the next fields: + a circular list where each variable points to the next variable in the + same symmetry group. Only the entries between lower and upper are + considered. The procedure returns a pointer to an array + holding the symmetry information if successful; NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also checkSymmInfo + + +
                            Defined in cuddExact.c + +
                            +
                            + 
                            +int **þcubeþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int **þcubeþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int **þindicesþarray containing (on return) the indices(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int **þindicesþarray containing (on return) the indices(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int **þpathþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int **þpathþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int *þarrayþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int *þarrayþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int *þdigitsþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int *þdistanceþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int *þinputsþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int *þlengthþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int *þlengthþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int *þpermutationþrequired variable permutation(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int *þpermutationþrequired variable permutation(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int *þpermutþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int *þpermutþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int *þphase2þ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int *þweightþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þNþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þamountþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þarcviolationþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þbinaryDigitsþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þbitþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þbitþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þcycleþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þdigitsþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þdirectionþunder (0) or over (1) approximation(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þdirectionþunder (0) or over (1) approximation(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þhardlimitþflag: 1 if threshold is a hard limit(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þhardlimitþflag: 1 if threshold is a hard limit(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþvariable index(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþvariable index(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþvariable index(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþvariable index(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþvariable index(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþvariable index(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þindexþvariable index(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þiþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þiþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þiþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þiþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þiþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þiþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þiþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þiþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þiþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þiþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þiþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þiþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þkþnumber of minterms to find(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þlevelþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þlevelþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þminsizeþbound below which no reordering occurs(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þminsizeþbound below which no reordering occurs(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þmultiplicityþhow many ZDD variables are created for each BDD variable(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þmvarsþsize of maskVars(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þmvþ0: blif, 1: blif-MV(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þmvþ0: blif, 1: blif-MV(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnVarsþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnumberXoversþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnvarsþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnvarsþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnvarsþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnvarsþsize of the support of f(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnzþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnzþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnzþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþlength of both arrays(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþnumbers of unknowns(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþnumbers of unknowns(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþsize of vars(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþsize of the array(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþsize of the array(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þnþsize of the array(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þpairIndexþcorresponding variable index(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þpathþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þphaseþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þphaseþ1: positive; 0: negative(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þpopulationSizeþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þpowerþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þprecisionþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þprecisionþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þprþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þprþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þprþverbosity level(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þprþverbosity level(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þrecombþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þsmsþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þsmvþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þsymmviolationþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þsyþstep of column variables(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þsyþstep of column variables(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þthresholdþmaximum number of nodes in the subset(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þthresholdþmaximum number of nodes in the subset(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þthresholdþmaximum number of nodes in the superset(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þthresholdþmaximum number of nodes in the superset(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þtopþindex of top variable(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þupperBoundþdistance above which an approximate answer is OK(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þupperþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þupperþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þvarþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þvarþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þvarþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þvþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þvþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þxþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +int þyþcolumn index(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            +static int 
                            +largest(
                            +    
                            +)
                            +
                            +
                            Finds the largest DD in the population. If an order is + repeated, it avoids choosing the copy that is in the computed table + (it has repeat[i +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGenetic.c + +
                            +
                            + 
                            +long þseedþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +long þsizeþsize of the allocation that failed(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            +static int 
                            +make_random(
                            +  DdManager * table, 
                            +  int  lower 
                            +)
                            +
                            +
                            Generates the random sequences for the initial population. + The sequences are permutations of the indices between lower and + upper in the current order. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGenetic.c + +
                            +
                            +static DdNode * 
                            +mintermsFromUniverse(
                            +  DdManager * manager, 
                            +  DdNode ** vars, 
                            +  int  numVars, 
                            +  double  n, 
                            +  int  index 
                            +)
                            +
                            +
                            Recursive procedure to extract n mintems from constant 1. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSplit.c + +
                            +
                            +static int 
                            +oneliteralp(
                            +  DdHalfWord  var 
                            +)
                            +
                            +
                            Returns true iff the argument is a one-literal clause. + A one-litaral clause has the constant FALSE as second literal. + Since the constant TRUE is never used, it is sufficient to test for + a constant. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddEssent.c + +
                            +
                            +static void 
                            +pushDown(
                            +  DdHalfWord * order, 
                            +  int  j, 
                            +  int  level 
                            +)
                            +
                            +
                            Pushes a variable in the order down to position "level." +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddExact.c + +
                            +
                            +static int 
                            +rand_int(
                            +  int  a 
                            +)
                            +
                            +
                            Generates a random number between 0 and the integer a. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGenetic.c + +
                            +
                            +static double 
                            +random_generator(
                            +    
                            +)
                            +
                            +
                            Returns a double precision value between 0.0 and 1.0. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAnneal.c + +
                            +
                            +static int 
                            +restoreOrder(
                            +  DdManager * table, 
                            +  int * array, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Restores the variable order in array by a series of sifts up. + Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAnneal.c + +
                            +
                            +static int 
                            +roulette(
                            +  int * p1, 
                            +  int * p2 
                            +)
                            +
                            +
                            Selects two distinct parents with the roulette wheel method. +

                            + +

                            Side Effects The indices of the selected parents are returned as side + effects. +

                            + +

                            Defined in cuddGenetic.c + +
                            +
                            +static DdNode * 
                            +selectMintermsFromUniverse(
                            +  DdManager * manager, 
                            +  int * varSeen, 
                            +  double  n 
                            +)
                            +
                            +
                            This function prepares an array of variables which have not been + encountered so far when traversing the procedure cuddSplitSetRecur. This + array is then used to extract the required number of minterms from a constant + 1. The algorithm guarantees that the size of BDD will be utmost log(n). +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSplit.c + +
                            +
                            +static int 
                            +sentinelp(
                            +  DdHalfWord  var1, 
                            +  DdHalfWord  var2 
                            +)
                            +
                            +
                            Returns true iff the argument is the sentinel clause. + A sentinel clause has both variables equal to 0. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddEssent.c + +
                            +
                            +static DdNode * 
                            +separateCube(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  CUDD_VALUE_TYPE * distance 
                            +)
                            +
                            +
                            Separates cube from distance. Returns the cube if + successful; NULL otherwise. +

                            + +

                            Side Effects The distance is returned as a side effect. +

                            + +

                            See Also cuddBddClosestCube +createResult + + +
                            Defined in cuddPriority.c + +
                            +
                            +static int 
                            +siftBackwardProb(
                            +  DdManager * table, 
                            +  Move * moves, 
                            +  int  size, 
                            +  double  temp 
                            +)
                            +
                            +
                            Otherwise, "tosses a coin" to decide whether to keep + the current configuration or return the DD to the original + one. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAnneal.c + +
                            +
                            +static int 
                            +sift_up(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  x_low 
                            +)
                            +
                            +
                            Takes a variable from position x and sifts it up to + position x_low; x_low should be less than x. Returns 1 if successful; + 0 otherwise +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGenetic.c + +
                            +
                            +static enum st_retval 
                            +stPathTableDdFree(
                            +  char * key, 
                            +  char * value, 
                            +  char * arg 
                            +)
                            +
                            +
                            None +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddSubsetSP.c + +
                            +
                            +static enum st_retval 
                            +st_zdd_count_dbl_free(
                            +  char * key, 
                            +  char * value, 
                            +  char * arg 
                            +)
                            +
                            +
                            Frees the memory associated with the computed table of + Cudd_zddCountDouble. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddCount.c + +
                            +
                            +static enum st_retval 
                            +st_zdd_countfree(
                            +  char * key, 
                            +  char * value, 
                            +  char * arg 
                            +)
                            +
                            +
                            Frees the memory associated with the computed table of + Cudd_zddCount. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddCount.c + +
                            +
                            +static int 
                            +stopping_criterion(
                            +  int  c1, 
                            +  int  c2, 
                            +  int  c3, 
                            +  int  c4, 
                            +  double  temp 
                            +)
                            +
                            +
                            If temperature is STOP_TEMP or there is no improvement + then terminates. Returns 1 if the termination criterion is met; 0 + otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddAnneal.c + +
                            +
                            +static DdTlcInfo * 
                            +tlcInfoAlloc(
                            +    
                            +)
                            +
                            +
                            Returns a pointer to a DdTlcInfo Structure if successful; + NULL otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also Cudd_tlcInfoFree + + +
                            Defined in cuddEssent.c + +
                            +
                            + 
                            +unsigned int þfactorþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þhrþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þlimitþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þlimitþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þlimitþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þlimitþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þlimitþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þlimitþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þlutþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þmaxLiveþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þmcþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þmrþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þnextþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þpþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þsecondDenþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þtypeþMTR_DEFAULT or MTR_FIXED(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þtypeþMTR_DEFAULT or MTR_FIXED(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned int þupperBþupper bound(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned long þincreaseþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned long þmaxMemoryþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned long þmaxMemoryþtarget maximum memory occupation(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned long þstþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +unsigned long þtlþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            +static int 
                            +updateEntry(
                            +  DdManager * table, 
                            +  DdHalfWord * order, 
                            +  int  level, 
                            +  int  cost, 
                            +  DdHalfWord ** orders, 
                            +  int * costs, 
                            +  int  subsets, 
                            +  char * mask, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Updates entry for a subset. Finds the subset, if it exists. + If the new order for the subset has lower cost, or if the subset did not + exist, it stores the new order and cost. Returns the number of subsets + currently in the table. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddExact.c + +
                            +
                            +static void 
                            +updateParity(
                            +  DdNode * node, function to analyze
                            +  ApproxInfo * info, info on BDD
                            +  int  newparity new parity for node
                            +)
                            +
                            +
                            Recursively update the parity of the paths reaching a node. + Assumes that node is regular and propagates the invariant. +

                            + +

                            Side Effects None +

                            + +

                            See Also gatherInfoAux + + +
                            Defined in cuddApprox.c + +
                            +
                            +static int 
                            +updateRefs(
                            +  DdManager * dd, 
                            +  DdNode * f, 
                            +  DdNode * skip, 
                            +  ApproxInfo * info, 
                            +  DdLevelQueue * queue 
                            +)
                            +
                            +
                            Update function reference counts to account for replacement. + Returns the number of nodes saved if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            See Also UAmarkNodes +RAmarkNodes +BAmarkNodes + + +
                            Defined in cuddApprox.c + +
                            +
                            +static int 
                            +updateUB(
                            +  DdManager * table, 
                            +  int  oldBound, 
                            +  DdHalfWord * bestOrder, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Updates the upper bound and saves the best order seen so far. + Returns the current value of the upper bound. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddExact.c + +
                            +
                            + 
                            +void *þdataþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +void *þdataþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +void *þdataþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            +static void 
                            +zddClearFlag(
                            +  DdNode * f 
                            +)
                            +
                            +
                            Performs a DFS from f, clearing the LSB of the next + pointers. +

                            + +

                            Side Effects None +

                            + +

                            See Also zddSupportStep + + +
                            Defined in cuddZddUtil.c + +
                            +
                            +static int 
                            +zddCountInternalMtrNodes(
                            +  DdManager * table, 
                            +  MtrNode * treenode 
                            +)
                            +
                            +
                            Counts the number of internal nodes of the group tree. + Returns the count. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +static void 
                            +zddFindNodeHiLo(
                            +  DdManager * table, 
                            +  MtrNode * treenode, 
                            +  int * lower, 
                            +  int * upper 
                            +)
                            +
                            +
                            Finds the lower and upper bounds of the group represented + by treenode. The high and low fields of treenode are indices. From + those we need to derive the current positions, and find maximum and + minimum. +

                            + +

                            Side Effects The bounds are returned as side effects. +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +static void 
                            +zddFixTree(
                            +  DdManager * table, 
                            +  MtrNode * treenode 
                            +)
                            +
                            +
                            Fixes the ZDD variable group tree after a + shuffle. Assumes that the order of the variables in a terminal node + has not been changed. +

                            + +

                            Side Effects Changes the ZDD variable group tree. +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +static int 
                            +zddGroupMoveBackward(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Undoes the swap two groups. Returns 1 in case of + success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +static int 
                            +zddGroupMove(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y, 
                            +  Move ** moves 
                            +)
                            +
                            +
                            Swaps two groups and records the move. Returns the + number of keys in the DD table in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +static int 
                            +zddGroupSiftingAux(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xLow, 
                            +  int  xHigh 
                            +)
                            +
                            +
                            Sifts one variable up and down until it has taken all + positions. Checks for aggregation. There may be at most two sweeps, + even if the group grows. Assumes that x is either an isolated + variable, or it is the bottom of a group. All groups may not have + been found. The variable being moved is returned to the best position + seen during sifting. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +static int 
                            +zddGroupSiftingBackward(
                            +  DdManager * table, 
                            +  Move * moves, 
                            +  int  size 
                            +)
                            +
                            +
                            Determines the best position for a variables and returns + it there. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +static int 
                            +zddGroupSiftingDown(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xHigh, 
                            +  Move ** moves 
                            +)
                            +
                            +
                            Sifts down a variable until it reaches position xHigh. + Assumes that x is the bottom of a group (or a singleton). Records + all the moves. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +static int 
                            +zddGroupSiftingUp(
                            +  DdManager * table, 
                            +  int  y, 
                            +  int  xLow, 
                            +  Move ** moves 
                            +)
                            +
                            +
                            Sifts up a variable until either it reaches position + xLow or the size of the DD heap increases too much. Assumes that y is + the top of a group (or a singleton). Checks y for aggregation to the + adjacent variables. Records all the moves that are appended to the + list of moves received as input and returned as a side effect. + Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +static int 
                            +zddGroupSifting(
                            +  DdManager * table, 
                            +  int  lower, 
                            +  int  upper 
                            +)
                            +
                            +
                            Sifts from treenode->low to treenode->high. If + croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the + end of the initial sifting. If a group is created, it is then sifted + again. After sifting one variable, the group that contains it is + dissolved. Returns 1 in case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +static void 
                            +zddMergeGroups(
                            +  DdManager * table, 
                            +  MtrNode * treenode, 
                            +  int  low, 
                            +  int  high 
                            +)
                            +
                            +
                            Creates a single group from low to high and adjusts the + idex field of the tree node. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +static DdNode * 
                            +zddPortFromBddStep(
                            +  DdManager * dd, 
                            +  DdNode * B, 
                            +  int  expected 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddPortFromBdd. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddPort.c + +
                            +
                            +static DdNode * 
                            +zddPortToBddStep(
                            +  DdManager * dd, manager
                            +  DdNode * f, ZDD to be converted
                            +  int  depth recursion depth
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddPortToBdd. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddPort.c + +
                            +
                            +static void 
                            +zddPrintCoverAux(
                            +  DdManager * zdd, manager
                            +  DdNode * node, current node
                            +  int  level, depth in the recursion
                            +  int * list current recursion path
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddPrintCover. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddUtil.c + +
                            +
                            +static int 
                            +zddReorderChildren(
                            +  DdManager * table, 
                            +  MtrNode * treenode, 
                            +  Cudd_ReorderingType  method 
                            +)
                            +
                            +
                            Reorders the children of a group tree node according to + the options. After reordering puts all the variables in the group + and/or its descendents in a single group. This allows hierarchical + reordering. If the variables in the group do not exist yet, simply + does nothing. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +static int 
                            +zddReorderPostprocess(
                            +  DdManager * table 
                            +)
                            +
                            +
                            Shrinks almost empty subtables at the end of reordering to + guarantee that they have a reasonable load factor. However, if there many + nodes are being reclaimed, then no resizing occurs. Returns 1 in case of + success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +static void 
                            +zddReorderPreprocess(
                            +  DdManager * table 
                            +)
                            +
                            +
                            Prepares the ZDD heap for dynamic reordering. Does + garbage collection, to guarantee that there are no dead nodes; + and clears the cache, which is invalidated by dynamic reordering. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +static int 
                            +zddShuffle(
                            +  DdManager * table, 
                            +  int * permutation 
                            +)
                            +
                            +
                            Reorders ZDD variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. zddShuffle assumes that no + dead nodes are present. The reordering is achieved by a series of + upward sifts. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +static int 
                            +zddSiftUp(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  xLow 
                            +)
                            +
                            +
                            Takes a ZDD variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +static void 
                            +zddSupportStep(
                            +  DdNode * f, 
                            +  int * support 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddSupport. Performs a + DFS from f. The support is accumulated in supp as a side effect. Uses + the LSB of the then pointer as visited flag. +

                            + +

                            Side Effects None +

                            + +

                            See Also zddClearFlag + + +
                            Defined in cuddZddUtil.c + +
                            +
                            +static Move * 
                            +zddSwapAny(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Swaps any two variables. Returns the set of moves. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddReord.c + +
                            +
                            +static int 
                            +zddTreeSiftingAux(
                            +  DdManager * table, 
                            +  MtrNode * treenode, 
                            +  Cudd_ReorderingType  method 
                            +)
                            +
                            +
                            Recursively visits the group tree and reorders each + group in postorder fashion. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +static int 
                            +zddUniqueCompareGroup(
                            +  int * ptrX, 
                            +  int * ptrY 
                            +)
                            +
                            +
                            Comparison function used by qsort to order the variables + according to the number of keys in the subtables. Returns the + difference in number of keys between the two variables being + compared. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddGroup.c + +
                            +
                            +static void 
                            +zddVarToConst(
                            +  DdNode * f, 
                            +  DdNode ** gp, 
                            +  DdNode ** hp, 
                            +  DdNode * base, 
                            +  DdNode * empty 
                            +)
                            +
                            +
                            Replaces variables with constants if possible (part of + canonical form). +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSetop.c + +
                            +
                            +static int 
                            +zdd_group_move_backward(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y 
                            +)
                            +
                            +
                            Undoes the swap of two groups. x is assumed to be the + bottom variable of the first group. y is assumed to be the top + variable of the second group. Returns 1 if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSymm.c + +
                            +
                            +static int 
                            +zdd_group_move(
                            +  DdManager * table, 
                            +  int  x, 
                            +  int  y, 
                            +  Move ** moves 
                            +)
                            +
                            +
                            Swaps two groups. x is assumed to be the bottom variable + of the first group. y is assumed to be the top variable of the second + group. Updates the list of moves. Returns the number of keys in the + table if successful; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSymm.c + +
                            +
                            +static void 
                            +zdd_print_minterm_aux(
                            +  DdManager * zdd, manager
                            +  DdNode * node, current node
                            +  int  level, depth in the recursion
                            +  int * list current recursion path
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddPrintMinterm. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddUtil.c + +
                            +
                            +static DdNode * 
                            +zdd_subset0_aux(
                            +  DdManager * zdd, 
                            +  DdNode * P, 
                            +  DdNode * zvar 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddSubset0. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSetop.c + +
                            +
                            +static DdNode * 
                            +zdd_subset1_aux(
                            +  DdManager * zdd, 
                            +  DdNode * P, 
                            +  DdNode * zvar 
                            +)
                            +
                            +
                            Performs the recursive step of Cudd_zddSubset1. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddSetop.c + +
                            +
                            +static int 
                            +zp2(
                            +  DdManager * zdd, 
                            +  DdNode * f, 
                            +  st_table * t 
                            +)
                            +
                            +
                            Performs the recursive step of cuddZddP. Returns 1 in + case of success; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddZddUtil.c + +
                            +
                            + 
                            +þþ(
                            +    
                            +)
                            +
                            +
                            +

                            + +

                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddAllocNode +cuddDynamicAllocNode +cuddDeallocMove + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddDeallocNode +cuddDynamicAllocNode + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Adjusts the values of table fields controlling the. + sizes of subtables and computed table. If the computed table is too small + according to the new values, it is resized. +

                            + +

                            Side Effects Modifies manager fields. May resize computed table. +

                            + +

                            Defined in cuddTable.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Clears a bit vector. The parameter size gives the + number of bits. +

                            + +

                            Side Effects None +

                            + +

                            See Also bitVectorAlloc + + +
                            Defined in cuddEssent.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Clears the 4 least significant bits of a pointer. +

                            + +

                            Side Effects none +

                            + +

                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Comparison of a function to the i-th ADD variable. Returns 1 if + the function is the i-th ADD variable; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCompose.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Comparison of a pair of functions to the i-th ADD + variable. Returns 1 if the functions are the i-th ADD variable and its + complement; 0 otherwise. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddCompose.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Complements a DD if condition c is true; c should be + either 0 or 1, because it is used directly (for efficiency). If in + doubt on the values c may take, use "(c) ? Cudd_Not(node) : node". +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_Not + + +
                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Complements a DD by flipping the complement attribute of + the pointer (the least significant bit). +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_NotCond + + +
                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Computes hash function for keys of one operand. +

                            + +

                            Side Effects None +

                            + +

                            See Also ddLCHash3 +ddLCHash + + +
                            Defined in cuddLCache.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Computes hash function for keys of three operands. +

                            + +

                            Side Effects None +

                            + +

                            See Also ddLCHash2 +ddLCHash + + +
                            Defined in cuddLCache.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Computes hash function for keys of two operands. +

                            + +

                            Side Effects None +

                            + +

                            See Also ddLCHash3 +ddLCHash + + +
                            Defined in cuddLCache.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Computes the absolute value of a number. +

                            + +

                            Side Effects none +

                            + +

                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Computes the hash value for a local cache. Returns the + bucket index. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddLCache.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Computes the maximum of two numbers. +

                            + +

                            Side Effects none +

                            + +

                            See Also ddMin + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Computes the minimum of two numbers. +

                            + +

                            Side Effects none +

                            + +

                            See Also ddMax + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Decreases the reference count of node. It is primarily + used in recursive procedures to decrease the ref count of a result + node before returning it. This accomplishes the goal of removing the + protection applied by a previous cuddRef. This being a macro, it is + faster than Cudd_Deref, but it cannot be used in constructs like + cuddDeref(a = b()). +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_Deref + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL. + Furthermore, if x <= DD_MINUS_INF_VAL/2, x is set to + DD_MINUS_INF_VAL. Similarly, if DD_PLUS_INF_VAL/2 <= x, x is set to + DD_PLUS_INF_VAL. Normally this macro is a NOOP. However, if + HAVE_IEEE_754 is not defined, it makes sure that a value does not + get larger than infinity in absolute value, and once it gets to + infinity, stays there. If the value overflows before this macro is + applied, no recovery is possible. +

                            + +

                            Side Effects none +

                            + +

                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Extract the least significant digit of a double digit. Used + in the manipulation of arbitrary precision integers. +

                            + +

                            Side Effects None +

                            + +

                            See Also DD_MSDIGIT + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Extract the most significant digit of a double digit. Used + in the manipulation of arbitrary precision integers. +

                            + +

                            Side Effects None +

                            + +

                            See Also DD_LSDIGIT + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Fast storage allocation for items in a hash table. The + first 4 bytes of a chunk contain a pointer to the next block; the + rest contains DD_MEM_CHUNK spaces for hash items. Returns a pointer to + a new item if successful; NULL is memory is full. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddAllocNode +cuddDynamicAllocNode + + +
                            Defined in cuddLCache.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Finds the current position of ZDD variable index in the + order. This macro duplicates the functionality of Cudd_ReadPermZdd, + but it does not check for out-of-bounds indices and it is more + efficient. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_ReadPermZdd + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Finds the current position of variable index in the + order. This macro duplicates the functionality of Cudd_ReadPerm, + but it does not check for out-of-bounds indices and it is more + efficient. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_ReadPerm + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Hash function for the cache for functions with two + operands. +

                            + +

                            Side Effects none +

                            + +

                            See Also ddHash +ddCHash + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Hash function for the cache. +

                            + +

                            Side Effects none +

                            + +

                            See Also ddHash +ddCHash2 + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Hash function for the table of a level queue. +

                            + +

                            Side Effects None +

                            + +

                            See Also hashInsert +hashLookup +hashDelete + + +
                            Defined in cuddLevelQ.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Hash function for the unique table. +

                            + +

                            Side Effects none +

                            + +

                            See Also ddCHash +ddCHash2 + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Increases the reference count of a node, if it is not + saturated. This being a macro, it is faster than Cudd_Ref, but it + cannot be used in constructs like cuddRef(a = b()). +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_Ref + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Iterates over the cubes of a decision diagram f. +
                              +
                            • DdManager *manager; +
                            • DdNode *f; +
                            • DdGen *gen; +
                            • int *cube; +
                            • CUDD_VALUE_TYPE value; +
                            + Cudd_ForeachCube allocates and frees the generator. Therefore the + application should not try to do that. Also, the cube is freed at the + end of Cudd_ForeachCube and hence is not available outside of the loop.

                            + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_ForeachNode +Cudd_FirstCube +Cudd_NextCube +Cudd_GenFree +Cudd_IsGenEmpty +Cudd_AutodynDisable + + +
                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Iterates over the nodes of a decision diagram f. +
                              +
                            • DdManager *manager; +
                            • DdNode *f; +
                            • DdGen *gen; +
                            • DdNode *node; +
                            + The nodes are returned in a seemingly random order. + Cudd_ForeachNode allocates and frees the generator. Therefore the + application should not try to do that.

                            + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_ForeachCube +Cudd_FirstNode +Cudd_NextNode +Cudd_GenFree +Cudd_IsGenEmpty +Cudd_AutodynDisable + + +
                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Iterates over the paths of a ZDD f. +
                              +
                            • DdManager *manager; +
                            • DdNode *f; +
                            • DdGen *gen; +
                            • int *path; +
                            + Cudd_zddForeachPath allocates and frees the generator. Therefore the + application should not try to do that. Also, the path is freed at the + end of Cudd_zddForeachPath and hence is not available outside of the loop.

                            + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_zddFirstPath +Cudd_zddNextPath +Cudd_GenFree +Cudd_IsGenEmpty +Cudd_AutodynDisable + + +
                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Iterates over the primes of a Boolean function producing + a prime and irredundant cover. +
                              +
                            • DdManager *manager; +
                            • DdNode *l; +
                            • DdNode *u; +
                            • DdGen *gen; +
                            • int *cube; +
                            + The Boolean function is described by an upper bound and a lower bound. If + the function is completely specified, the two bounds coincide. + Cudd_ForeachPrime allocates and frees the generator. Therefore the + application should not try to do that. Also, the cube is freed at the + end of Cudd_ForeachPrime and hence is not available outside of the loop.

                            + CAUTION: It is a mistake to change a diagram on which generation is ongoing. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_ForeachCube +Cudd_FirstPrime +Cudd_NextPrime +Cudd_GenFree +Cudd_IsGenEmpty + + +
                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Outputs a line of stats if DD_COUNT and DD_STATS are + defined. Increments the number of recursive calls if DD_COUNT is + defined. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Performs the left rotation for red/black trees. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddRotateRight + + +
                            Defined in cuddTable.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Performs the right rotation for red/black trees. +

                            + +

                            Side Effects None +

                            + +

                            See Also cuddRotateLeft + + +
                            Defined in cuddTable.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns 1 if a pointer is complemented. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_Regular +Cudd_Complement + + +
                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns 1 if the absolute value of the difference of the two + arguments x and y is less than e. +

                            + +

                            Side Effects none +

                            + +

                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns 1 if the node is a constant node (rather than an + internal node). All constant nodes have the same index + (CUDD_CONST_INDEX). The pointer passed to Cudd_IsConstant may be either + regular or complemented. +

                            + +

                            Side Effects none +

                            + +

                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns 1 if the node is a constant node (rather than an + internal node). All constant nodes have the same index + (CUDD_CONST_INDEX). The pointer passed to cuddIsConstant must be regular. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_IsConstant + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the arithmetic 0 constant node. This is different + from the logical zero. The latter is obtained by + Cudd_Not(DD_ONE(dd)). +

                            + +

                            Side Effects none +

                            + +

                            See Also DD_ONE +Cudd_Not +DD_PLUS_INFINITY +DD_MINUS_INFINITY + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the average fitness of the population. +

                            + +

                            Side Effects None +

                            + +

                            Defined in cuddGenetic.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the complemented version of a pointer. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_Regular +Cudd_IsComplement + + +
                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the constant 1 node. +

                            + +

                            Side Effects none +

                            + +

                            See Also DD_ZERO +DD_PLUS_INFINITY +DD_MINUS_INFINITY + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the current position in the order of variable + index. This macro is obsolete and is kept for compatibility. New + applications should use Cudd_ReadPerm instead. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_ReadPerm + + +
                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the else child of an internal node. If + node is a constant node, the result is unpredictable. + The pointer passed to cuddE must be regular. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_E + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the else child of an internal node. If + node is a constant node, the result is unpredictable. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_T +Cudd_V + + +
                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the i-th entry of a bit vector. +

                            + +

                            Side Effects None +

                            + +

                            See Also bitVectorSet + + +
                            Defined in cuddEssent.c + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the minus infinity constant node. +

                            + +

                            Side Effects none +

                            + +

                            See Also DD_ONE +DD_ZERO +DD_PLUS_INFINITY + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the plus infinity constant node. +

                            + +

                            Side Effects none +

                            + +

                            See Also DD_ONE +DD_ZERO +DD_MINUS_INFINITY + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the regular version of a pointer. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_Complement +Cudd_IsComplement + + +
                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the then child of an internal node. If + node is a constant node, the result is unpredictable. + The pointer passed to cuddT must be regular. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_T + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the then child of an internal node. If + node is a constant node, the result is unpredictable. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_E +Cudd_V + + +
                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the value of a constant node. If + node is an internal node, the result is unpredictable. + The pointer passed to cuddV must be regular. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_V + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Returns the value of a constant node. If + node is an internal node, the result is unpredictable. +

                            + +

                            Side Effects none +

                            + +

                            See Also Cudd_T +Cudd_E + + +
                            Defined in cudd.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Saturating decrement operator. +

                            + +

                            Side Effects none +

                            + +

                            See Also cuddSatInc + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Saturating increment operator. +

                            + +

                            Side Effects none +

                            + +

                            See Also cuddSatDec + + +
                            Defined in cuddInt.h + +
                            +
                            + 
                            +(
                            +    
                            +)
                            +
                            +
                            Sets the i-th entry of a bit vector to a value. +

                            + +

                            Side Effects None +

                            + +

                            See Also bitVectorRead + + +
                            Defined in cuddEssent.c + + +
                        +
                        +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllFile.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllFile.html new file mode 100644 index 000000000..9293943d3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddAllFile.html @@ -0,0 +1,4876 @@ + +The cudd package: files + + +
                        +
                        cuddAddAbs.c +
                        Quantification functions for ADDs. +
                        cuddAddApply.c +
                        Apply functions for ADDs and their operators. +
                        cuddAddFind.c +
                        Functions to find maximum and minimum in an ADD and to + extract the i-th bit. +
                        cuddAddInv.c +
                        Function to compute the scalar inverse of an ADD. +
                        cuddAddIte.c +
                        ADD ITE function and satellites. +
                        cuddAddNeg.c +
                        Function to compute the negation of an ADD. +
                        cuddAddWalsh.c +
                        Functions that generate Walsh matrices and residue + functions in ADD form. +
                        cuddAndAbs.c +
                        Combined AND and existential abstraction for BDDs +
                        cuddAnneal.c +
                        Reordering of DDs based on simulated annealing +
                        cuddApa.c +
                        Arbitrary precision arithmetic functions. +
                        cuddAPI.c +
                        Application interface functions. +
                        cuddApprox.c +
                        Procedures to approximate a given BDD. +
                        cuddBddAbs.c +
                        Quantification functions for BDDs. +
                        cuddBddCorr.c +
                        Correlation between BDDs. +
                        cuddBddIte.c +
                        BDD ITE function and satellites. +
                        cuddBridge.c +
                        Translation from BDD to ADD and vice versa and transfer between + different managers. +
                        cuddCache.c +
                        Functions for cache insertion and lookup. +
                        cuddCheck.c +
                        Functions to check consistency of data structures. +
                        cuddClip.c +
                        Clipping functions. +
                        cuddCof.c +
                        Cofactoring functions. +
                        cuddCompose.c +
                        Functional composition and variable permutation of DDs. +
                        cuddDecomp.c +
                        Functions for BDD decomposition. +
                        cuddEssent.c +
                        Functions for the detection of essential variables. +
                        cuddExact.c +
                        Functions for exact variable reordering. +
                        cuddExport.c +
                        Export functions. +
                        cuddGenCof.c +
                        Generalized cofactors for BDDs and ADDs. +
                        cuddGenetic.c +
                        Genetic algorithm for variable reordering. +
                        cuddGroup.c +
                        Functions for group sifting. +
                        cuddHarwell.c +
                        Function to read a matrix in Harwell format. +
                        cuddInit.c +
                        Functions to initialize and shut down the DD manager. +
                        cuddInteract.c +
                        Functions to manipulate the variable interaction matrix. +
                        cuddLCache.c +
                        Functions for local caches. +
                        cuddLevelQ.c +
                        Procedure to manage level queues. +
                        cuddLinear.c +
                        Functions for DD reduction by linear transformations. +
                        cuddLiteral.c +
                        Functions for manipulation of literal sets represented by + BDDs. +
                        cuddMatMult.c +
                        Matrix multiplication functions. +
                        cuddPriority.c +
                        Priority functions. +
                        cuddRead.c +
                        Functions to read in a matrix +
                        cuddRef.c +
                        Functions that manipulate the reference counts. +
                        cuddReorder.c +
                        Functions for dynamic variable reordering. +
                        cuddSat.c +
                        Functions for the solution of satisfiability related problems. +
                        cuddSign.c +
                        Computation of signatures. +
                        cuddSolve.c +
                        Boolean equation solver and related functions. +
                        cuddSplit.c +
                        Returns a subset of minterms from a boolean function. +
                        cuddSubsetHB.c +
                        Procedure to subset the given BDD by choosing the heavier + branches. +
                        cuddSubsetSP.c +
                        Procedure to subset the given BDD choosing the shortest paths + (largest cubes) in the BDD. +
                        cuddSymmetry.c +
                        Functions for symmetry-based variable reordering. +
                        cuddTable.c +
                        Unique table management functions. +
                        cuddUtil.c +
                        Utility functions. +
                        cuddWindow.c +
                        Functions for variable reordering by window permutation. +
                        cuddZddCount.c +
                        Procedures to count the number of minterms of a ZDD. +
                        cuddZddFuncs.c +
                        Functions to manipulate covers represented as ZDDs. +
                        cuddZddGroup.c +
                        Functions for ZDD group sifting. +
                        cuddZddIsop.c +
                        Functions to find irredundant SOP covers as ZDDs from BDDs. +
                        cuddZddLin.c +
                        Procedures for dynamic variable ordering of ZDDs. +
                        cuddZddMisc.c +
                        Miscellaneous utility functions for ZDDs. +
                        cuddZddPort.c +
                        Functions that translate BDDs to ZDDs. +
                        cuddZddReord.c +
                        Procedures for dynamic variable ordering of ZDDs. +
                        cuddZddSetop.c +
                        Set operations on ZDDs. +
                        cuddZddSymm.c +
                        Functions for symmetry-based ZDD variable reordering. +
                        cuddZddUtil.c +
                        Utility functions for ZDDs. +

                        +

                        cuddAddAbs.c

                        +Quantification functions for ADDs.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_addExistAbstract() +
                        • Cudd_addUnivAbstract() +
                        • Cudd_addOrAbstract() +
                        + Internal procedures included in this module: +
                          +
                        • cuddAddExistAbstractRecur() +
                        • cuddAddUnivAbstractRecur() +
                        • cuddAddOrAbstractRecur() +
                        + Static procedures included in this module: +
                          +
                        • addCheckPositiveCube() +

                        +

                        +
                        Cudd_addExistAbstract() +
                        Existentially Abstracts all the variables in cube from f. + +
                        Cudd_addUnivAbstract() +
                        Universally Abstracts all the variables in cube from f. + +
                        Cudd_addOrAbstract() +
                        Disjunctively abstracts all the variables in cube from the + 0-1 ADD f. + +
                        cuddAddExistAbstractRecur() +
                        Performs the recursive step of Cudd_addExistAbstract. + +
                        cuddAddUnivAbstractRecur() +
                        Performs the recursive step of Cudd_addUnivAbstract. + +
                        cuddAddOrAbstractRecur() +
                        Performs the recursive step of Cudd_addOrAbstract. + +
                        addCheckPositiveCube() +
                        Checks whether cube is an ADD representing the product + of positive literals. + +
                        +
                        +

                        cuddAddApply.c

                        +Apply functions for ADDs and their operators.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_addApply() +
                        • Cudd_addMonadicApply() +
                        • Cudd_addPlus() +
                        • Cudd_addTimes() +
                        • Cudd_addThreshold() +
                        • Cudd_addSetNZ() +
                        • Cudd_addDivide() +
                        • Cudd_addMinus() +
                        • Cudd_addMinimum() +
                        • Cudd_addMaximum() +
                        • Cudd_addOneZeroMaximum() +
                        • Cudd_addDiff() +
                        • Cudd_addAgreement() +
                        • Cudd_addOr() +
                        • Cudd_addNand() +
                        • Cudd_addNor() +
                        • Cudd_addXor() +
                        • Cudd_addXnor() +
                        + Internal procedures included in this module: +
                          +
                        • cuddAddApplyRecur() +
                        • cuddAddMonadicApplyRecur() +

                        +

                        +
                        Cudd_addApply() +
                        Applies op to the corresponding discriminants of f and g. + +
                        Cudd_addPlus() +
                        Integer and floating point addition. + +
                        Cudd_addTimes() +
                        Integer and floating point multiplication. + +
                        Cudd_addThreshold() +
                        f if f>=g; 0 if f<g. + +
                        Cudd_addSetNZ() +
                        This operator sets f to the value of g wherever g != 0. + +
                        Cudd_addDivide() +
                        Integer and floating point division. + +
                        Cudd_addMinus() +
                        Integer and floating point subtraction. + +
                        Cudd_addMinimum() +
                        Integer and floating point min. + +
                        Cudd_addMaximum() +
                        Integer and floating point max. + +
                        Cudd_addOneZeroMaximum() +
                        Returns 1 if f > g and 0 otherwise. + +
                        Cudd_addDiff() +
                        Returns plusinfinity if f=g; returns min(f,g) if f!=g. + +
                        Cudd_addAgreement() +
                        f if f==g; background if f!=g. + +
                        Cudd_addOr() +
                        Disjunction of two 0-1 ADDs. + +
                        Cudd_addNand() +
                        NAND of two 0-1 ADDs. + +
                        Cudd_addNor() +
                        NOR of two 0-1 ADDs. + +
                        Cudd_addXor() +
                        XOR of two 0-1 ADDs. + +
                        Cudd_addXnor() +
                        XNOR of two 0-1 ADDs. + +
                        Cudd_addMonadicApply() +
                        Applies op to the discriminants of f. + +
                        Cudd_addLog() +
                        Natural logarithm of an ADD. + +
                        cuddAddApplyRecur() +
                        Performs the recursive step of Cudd_addApply. + +
                        cuddAddMonadicApplyRecur() +
                        Performs the recursive step of Cudd_addMonadicApply. + +
                        +
                        +

                        cuddAddFind.c

                        +Functions to find maximum and minimum in an ADD and to + extract the i-th bit.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_addFindMax() +
                        • Cudd_addFindMin() +
                        • Cudd_addIthBit() +
                        + Static functions included in this module: +
                          +
                        • addDoIthBit() +

                        +

                        +
                        Cudd_addFindMax() +
                        Finds the maximum discriminant of f. + +
                        Cudd_addFindMin() +
                        Finds the minimum discriminant of f. + +
                        Cudd_addIthBit() +
                        Extracts the i-th bit from an ADD. + +
                        addDoIthBit() +
                        Performs the recursive step for Cudd_addIthBit. + +
                        +
                        +

                        cuddAddInv.c

                        +Function to compute the scalar inverse of an ADD.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_addScalarInverse() +
                        + Internal procedures included in this module: +
                          +
                        • cuddAddScalarInverseRecur() +

                        +

                        +
                        Cudd_addScalarInverse() +
                        Computes the scalar inverse of an ADD. + +
                        cuddAddScalarInverseRecur() +
                        Performs the recursive step of addScalarInverse. + +
                        +
                        +

                        cuddAddIte.c

                        +ADD ITE function and satellites.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_addIte() +
                        • Cudd_addIteConstant() +
                        • Cudd_addEvalConst() +
                        • Cudd_addCmpl() +
                        • Cudd_addLeq() +
                        + Internal procedures included in this module: +
                          +
                        • cuddAddIteRecur() +
                        • cuddAddCmplRecur() +
                        + Static procedures included in this module: +
                          +
                        • addVarToConst() +

                        +

                        +
                        Cudd_addIte() +
                        Implements ITE(f,g,h). + +
                        Cudd_addIteConstant() +
                        Implements ITEconstant for ADDs. + +
                        Cudd_addEvalConst() +
                        Checks whether ADD g is constant whenever ADD f is 1. + +
                        Cudd_addCmpl() +
                        Computes the complement of an ADD a la C language. + +
                        Cudd_addLeq() +
                        Determines whether f is less than or equal to g. + +
                        cuddAddIteRecur() +
                        Implements the recursive step of Cudd_addIte(f,g,h). + +
                        cuddAddCmplRecur() +
                        Performs the recursive step of Cudd_addCmpl. + +
                        addVarToConst() +
                        Replaces variables with constants if possible (part of + canonical form). + +
                        +
                        +

                        cuddAddNeg.c

                        +Function to compute the negation of an ADD.

                        +By: Fabio Somenzi, Balakrishna Kumthekar

                        +External procedures included in this module: +

                          +
                        • Cudd_addNegate() +
                        • Cudd_addRoundOff() +
                        + Internal procedures included in this module: +
                          +
                        • cuddAddNegateRecur() +
                        • cuddAddRoundOffRecur() +

                        +

                        +
                        Cudd_addNegate() +
                        Computes the additive inverse of an ADD. + +
                        Cudd_addRoundOff() +
                        Rounds off the discriminants of an ADD. + +
                        cuddAddNegateRecur() +
                        Implements the recursive step of Cudd_addNegate. + +
                        cuddAddRoundOffRecur() +
                        Implements the recursive step of Cudd_addRoundOff. + +
                        +
                        +

                        cuddAddWalsh.c

                        +Functions that generate Walsh matrices and residue + functions in ADD form.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_addWalsh() +
                        • Cudd_addResidue() +
                        + Static procedures included in this module: +
                          +
                        • addWalshInt() +

                        +

                        +
                        Cudd_addWalsh() +
                        Generates a Walsh matrix in ADD form. + +
                        Cudd_addResidue() +
                        Builds an ADD for the residue modulo m of an n-bit + number. + +
                        addWalshInt() +
                        Implements the recursive step of Cudd_addWalsh. + +
                        +
                        +

                        cuddAndAbs.c

                        +Combined AND and existential abstraction for BDDs

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_bddAndAbstract() +
                        • Cudd_bddAndAbstractLimit() +
                        + Internal procedures included in this module: +
                          +
                        • cuddBddAndAbstractRecur() +

                        +

                        +
                        Cudd_bddAndAbstract() +
                        Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                        Cudd_bddAndAbstractLimit() +
                        Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. Returns NULL if too many nodes are required. + +
                        cuddBddAndAbstractRecur() +
                        Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                        +
                        +

                        cuddAnneal.c

                        +Reordering of DDs based on simulated annealing

                        +By: Jae-Young Jang, Jorgen Sivesind

                        +Internal procedures included in this file: +

                          +
                        • cuddAnnealing() +
                        + Static procedures included in this file: +
                          +
                        • stopping_criterion() +
                        • random_generator() +
                        • ddExchange() +
                        • ddJumpingAux() +
                        • ddJumpingUp() +
                        • ddJumpingDown() +
                        • siftBackwardProb() +
                        • copyOrder() +
                        • restoreOrder() +

                        +

                        +
                        cuddAnnealing() +
                        Get new variable-order by simulated annealing algorithm. + +
                        stopping_criterion() +
                        Checks termination condition. + +
                        random_generator() +
                        Random number generator. + +
                        ddExchange() +
                        This function is for exchanging two variables, x and y. + +
                        ddJumpingAux() +
                        Moves a variable to a specified position. + +
                        ddJumpingUp() +
                        This function is for jumping up. + +
                        ddJumpingDown() +
                        This function is for jumping down. + +
                        siftBackwardProb() +
                        Returns the DD to the best position encountered during + sifting if there was improvement. + +
                        copyOrder() +
                        Copies the current variable order to array. + +
                        restoreOrder() +
                        Restores the variable order in array by a series of sifts up. + +
                        +
                        +

                        cuddApa.c

                        +Arbitrary precision arithmetic functions.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_ApaNumberOfDigits() +
                        • Cudd_NewApaNumber() +
                        • Cudd_ApaCopy() +
                        • Cudd_ApaAdd() +
                        • Cudd_ApaSubtract() +
                        • Cudd_ApaShortDivision() +
                        • Cudd_ApaIntDivision() +
                        • Cudd_ApaShiftRight() +
                        • Cudd_ApaSetToLiteral() +
                        • Cudd_ApaPowerOfTwo() +
                        • Cudd_ApaCompare() +
                        • Cudd_ApaCompareRatios() +
                        • Cudd_ApaPrintHex() +
                        • Cudd_ApaPrintDecimal() +
                        • Cudd_ApaPrintExponential() +
                        • Cudd_ApaCountMinterm() +
                        • Cudd_ApaPrintMinterm() +
                        • Cudd_ApaPrintMintermExp() +
                        • Cudd_ApaPrintDensity() +
                        + Static procedures included in this module: +
                          +
                        • cuddApaCountMintermAux() +
                        • cuddApaStCountfree() +

                        +

                        +
                        Cudd_ApaNumberOfDigits() +
                        Finds the number of digits for an arbitrary precision + integer. + +
                        Cudd_NewApaNumber() +
                        Allocates memory for an arbitrary precision integer. + +
                        Cudd_ApaCopy() +
                        Makes a copy of an arbitrary precision integer. + +
                        Cudd_ApaAdd() +
                        Adds two arbitrary precision integers. + +
                        Cudd_ApaSubtract() +
                        Subtracts two arbitrary precision integers. + +
                        Cudd_ApaShortDivision() +
                        Divides an arbitrary precision integer by a digit. + +
                        Cudd_ApaIntDivision() +
                        Divides an arbitrary precision integer by an integer. + +
                        Cudd_ApaShiftRight() +
                        Shifts right an arbitrary precision integer by one binary + place. + +
                        Cudd_ApaSetToLiteral() +
                        Sets an arbitrary precision integer to a one-digit literal. + +
                        Cudd_ApaPowerOfTwo() +
                        Sets an arbitrary precision integer to a power of two. + +
                        Cudd_ApaCompare() +
                        Compares two arbitrary precision integers. + +
                        Cudd_ApaCompareRatios() +
                        Compares the ratios of two arbitrary precision integers to two + unsigned ints. + +
                        Cudd_ApaPrintHex() +
                        Prints an arbitrary precision integer in hexadecimal format. + +
                        Cudd_ApaPrintDecimal() +
                        Prints an arbitrary precision integer in decimal format. + +
                        Cudd_ApaPrintExponential() +
                        Prints an arbitrary precision integer in exponential format. + +
                        Cudd_ApaCountMinterm() +
                        Counts the number of minterms of a DD. + +
                        Cudd_ApaPrintMinterm() +
                        Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic. + +
                        Cudd_ApaPrintMintermExp() +
                        Prints the number of minterms of a BDD or ADD in exponential + format using arbitrary precision arithmetic. + +
                        Cudd_ApaPrintDensity() +
                        Prints the density of a BDD or ADD using + arbitrary precision arithmetic. + +
                        cuddApaCountMintermAux() +
                        Performs the recursive step of Cudd_ApaCountMinterm. + +
                        cuddApaStCountfree() +
                        Frees the memory used to store the minterm counts recorded + in the visited table. + +
                        +
                        +

                        cuddAPI.c

                        +Application interface functions.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_addNewVar() +
                        • Cudd_addNewVarAtLevel() +
                        • Cudd_bddNewVar() +
                        • Cudd_bddNewVarAtLevel() +
                        • Cudd_addIthVar() +
                        • Cudd_bddIthVar() +
                        • Cudd_zddIthVar() +
                        • Cudd_zddVarsFromBddVars() +
                        • Cudd_addConst() +
                        • Cudd_IsNonConstant() +
                        • Cudd_ReadStartTime() +
                        • Cudd_ReadElapsedTime() +
                        • Cudd_SetStartTime() +
                        • Cudd_ResetStartTime() +
                        • Cudd_ReadTimeLimit() +
                        • Cudd_SetTimeLimit() +
                        • Cudd_UpdateTimeLimit() +
                        • Cudd_IncreaseTimeLimit() +
                        • Cudd_UnsetTimeLimit() +
                        • Cudd_TimeLimited() +
                        • Cudd_AutodynEnable() +
                        • Cudd_AutodynDisable() +
                        • Cudd_ReorderingStatus() +
                        • Cudd_AutodynEnableZdd() +
                        • Cudd_AutodynDisableZdd() +
                        • Cudd_ReorderingStatusZdd() +
                        • Cudd_zddRealignmentEnabled() +
                        • Cudd_zddRealignEnable() +
                        • Cudd_zddRealignDisable() +
                        • Cudd_bddRealignmentEnabled() +
                        • Cudd_bddRealignEnable() +
                        • Cudd_bddRealignDisable() +
                        • Cudd_ReadOne() +
                        • Cudd_ReadZddOne() +
                        • Cudd_ReadZero() +
                        • Cudd_ReadLogicZero() +
                        • Cudd_ReadPlusInfinity() +
                        • Cudd_ReadMinusInfinity() +
                        • Cudd_ReadBackground() +
                        • Cudd_SetBackground() +
                        • Cudd_ReadCacheSlots() +
                        • Cudd_ReadCacheUsedSlots() +
                        • Cudd_ReadCacheLookUps() +
                        • Cudd_ReadCacheHits() +
                        • Cudd_ReadMinHit() +
                        • Cudd_SetMinHit() +
                        • Cudd_ReadLooseUpTo() +
                        • Cudd_SetLooseUpTo() +
                        • Cudd_ReadMaxCache() +
                        • Cudd_ReadMaxCacheHard() +
                        • Cudd_SetMaxCacheHard() +
                        • Cudd_ReadSize() +
                        • Cudd_ReadSlots() +
                        • Cudd_ReadUsedSlots() +
                        • Cudd_ExpectedUsedSlots() +
                        • Cudd_ReadKeys() +
                        • Cudd_ReadDead() +
                        • Cudd_ReadMinDead() +
                        • Cudd_ReadReorderings() +
                        • Cudd_ReadMaxReorderings() +
                        • Cudd_SetMaxReorderings() +
                        • Cudd_ReadReorderingTime() +
                        • Cudd_ReadGarbageCollections() +
                        • Cudd_ReadGarbageCollectionTime() +
                        • Cudd_ReadNodesFreed() +
                        • Cudd_ReadNodesDropped() +
                        • Cudd_ReadUniqueLookUps() +
                        • Cudd_ReadUniqueLinks() +
                        • Cudd_ReadSiftMaxVar() +
                        • Cudd_SetSiftMaxVar() +
                        • Cudd_ReadMaxGrowth() +
                        • Cudd_SetMaxGrowth() +
                        • Cudd_ReadMaxGrowthAlternate() +
                        • Cudd_SetMaxGrowthAlternate() +
                        • Cudd_ReadReorderingCycle() +
                        • Cudd_SetReorderingCycle() +
                        • Cudd_ReadTree() +
                        • Cudd_SetTree() +
                        • Cudd_FreeTree() +
                        • Cudd_ReadZddTree() +
                        • Cudd_SetZddTree() +
                        • Cudd_FreeZddTree() +
                        • Cudd_NodeReadIndex() +
                        • Cudd_ReadPerm() +
                        • Cudd_ReadInvPerm() +
                        • Cudd_ReadVars() +
                        • Cudd_ReadEpsilon() +
                        • Cudd_SetEpsilon() +
                        • Cudd_ReadGroupCheck() +
                        • Cudd_SetGroupcheck() +
                        • Cudd_GarbageCollectionEnabled() +
                        • Cudd_EnableGarbageCollection() +
                        • Cudd_DisableGarbageCollection() +
                        • Cudd_DeadAreCounted() +
                        • Cudd_TurnOnCountDead() +
                        • Cudd_TurnOffCountDead() +
                        • Cudd_ReadRecomb() +
                        • Cudd_SetRecomb() +
                        • Cudd_ReadSymmviolation() +
                        • Cudd_SetSymmviolation() +
                        • Cudd_ReadArcviolation() +
                        • Cudd_SetArcviolation() +
                        • Cudd_ReadPopulationSize() +
                        • Cudd_SetPopulationSize() +
                        • Cudd_ReadNumberXovers() +
                        • Cudd_SetNumberXovers() +
                        • Cudd_ReadOrderRandomization() +
                        • Cudd_SetOrderRandomization() +
                        • Cudd_ReadMemoryInUse() +
                        • Cudd_PrintInfo() +
                        • Cudd_ReadPeakNodeCount() +
                        • Cudd_ReadPeakLiveNodeCount() +
                        • Cudd_ReadNodeCount() +
                        • Cudd_zddReadNodeCount() +
                        • Cudd_AddHook() +
                        • Cudd_RemoveHook() +
                        • Cudd_IsInHook() +
                        • Cudd_StdPreReordHook() +
                        • Cudd_StdPostReordHook() +
                        • Cudd_EnableReorderingReporting() +
                        • Cudd_DisableReorderingReporting() +
                        • Cudd_ReorderingReporting() +
                        • Cudd_PrintGroupedOrder() +
                        • Cudd_EnableOrderingMonitoring() +
                        • Cudd_DisableOrderingMonitoring() +
                        • Cudd_OrderingMonitoring() +
                        • Cudd_ReadErrorCode() +
                        • Cudd_ClearErrorCode() +
                        • Cudd_ReadStdout() +
                        • Cudd_SetStdout() +
                        • Cudd_ReadStderr() +
                        • Cudd_SetStderr() +
                        • Cudd_ReadNextReordering() +
                        • Cudd_SetNextReordering() +
                        • Cudd_ReadSwapSteps() +
                        • Cudd_ReadMaxLive() +
                        • Cudd_SetMaxLive() +
                        • Cudd_ReadMaxMemory() +
                        • Cudd_SetMaxMemory() +
                        • Cudd_bddBindVar() +
                        • Cudd_bddUnbindVar() +
                        • Cudd_bddVarIsBound() +
                        • Cudd_bddSetPiVar() +
                        • Cudd_bddSetPsVar() +
                        • Cudd_bddSetNsVar() +
                        • Cudd_bddIsPiVar() +
                        • Cudd_bddIsPsVar() +
                        • Cudd_bddIsNsVar() +
                        • Cudd_bddSetPairIndex() +
                        • Cudd_bddReadPairIndex() +
                        • Cudd_bddSetVarToBeGrouped() +
                        • Cudd_bddSetVarHardGroup() +
                        • Cudd_bddResetVarToBeGrouped() +
                        • Cudd_bddIsVarToBeGrouped() +
                        • Cudd_bddSetVarToBeUngrouped() +
                        • Cudd_bddIsVarToBeUngrouped() +
                        • Cudd_bddIsVarHardGroup() +
                        + Static procedures included in this module: +
                          +
                        • fixVarTree() +

                        +

                        +
                        Cudd_addNewVar() +
                        Returns a new ADD variable. + +
                        Cudd_addNewVarAtLevel() +
                        Returns a new ADD variable at a specified level. + +
                        Cudd_bddNewVar() +
                        Returns a new BDD variable. + +
                        Cudd_bddNewVarAtLevel() +
                        Returns a new BDD variable at a specified level. + +
                        Cudd_addIthVar() +
                        Returns the ADD variable with index i. + +
                        Cudd_bddIthVar() +
                        Returns the BDD variable with index i. + +
                        Cudd_zddIthVar() +
                        Returns the ZDD variable with index i. + +
                        Cudd_zddVarsFromBddVars() +
                        Creates one or more ZDD variables for each BDD variable. + +
                        Cudd_addConst() +
                        Returns the ADD for constant c. + +
                        Cudd_IsNonConstant() +
                        Returns 1 if a DD node is not constant. + +
                        Cudd_ReadStartTime() +
                        Returns the start time of the manager. + +
                        Cudd_ReadElapsedTime() +
                        Returns the time elapsed since the start time of the manager. + +
                        Cudd_SetStartTime() +
                        Sets the start time of the manager. + +
                        Cudd_ResetStartTime() +
                        Resets the start time of the manager. + +
                        Cudd_ReadTimeLimit() +
                        Returns the time limit for the manager. + +
                        Cudd_SetTimeLimit() +
                        Sets the time limit for the manager. + +
                        Cudd_UpdateTimeLimit() +
                        Updates the time limit for the manager. + +
                        Cudd_IncreaseTimeLimit() +
                        Increases the time limit for the manager. + +
                        Cudd_UnsetTimeLimit() +
                        Unsets the time limit for the manager. + +
                        Cudd_TimeLimited() +
                        Returns true if the time limit for the manager is set. + +
                        Cudd_AutodynEnable() +
                        Enables automatic dynamic reordering of BDDs and ADDs. + +
                        Cudd_AutodynDisable() +
                        Disables automatic dynamic reordering. + +
                        Cudd_ReorderingStatus() +
                        Reports the status of automatic dynamic reordering of BDDs + and ADDs. + +
                        Cudd_AutodynEnableZdd() +
                        Enables automatic dynamic reordering of ZDDs. + +
                        Cudd_AutodynDisableZdd() +
                        Disables automatic dynamic reordering of ZDDs. + +
                        Cudd_ReorderingStatusZdd() +
                        Reports the status of automatic dynamic reordering of ZDDs. + +
                        Cudd_zddRealignmentEnabled() +
                        Tells whether the realignment of ZDD order to BDD order is + enabled. + +
                        Cudd_zddRealignEnable() +
                        Enables realignment of ZDD order to BDD order. + +
                        Cudd_zddRealignDisable() +
                        Disables realignment of ZDD order to BDD order. + +
                        Cudd_bddRealignmentEnabled() +
                        Tells whether the realignment of BDD order to ZDD order is + enabled. + +
                        Cudd_bddRealignEnable() +
                        Enables realignment of BDD order to ZDD order. + +
                        Cudd_bddRealignDisable() +
                        Disables realignment of ZDD order to BDD order. + +
                        Cudd_ReadOne() +
                        Returns the one constant of the manager. + +
                        Cudd_ReadZddOne() +
                        Returns the ZDD for the constant 1 function. + +
                        Cudd_ReadZero() +
                        Returns the zero constant of the manager. + +
                        Cudd_ReadLogicZero() +
                        Returns the logic zero constant of the manager. + +
                        Cudd_ReadPlusInfinity() +
                        Reads the plus-infinity constant from the manager. + +
                        Cudd_ReadMinusInfinity() +
                        Reads the minus-infinity constant from the manager. + +
                        Cudd_ReadBackground() +
                        Reads the background constant of the manager. + +
                        Cudd_SetBackground() +
                        Sets the background constant of the manager. + +
                        Cudd_ReadCacheSlots() +
                        Reads the number of slots in the cache. + +
                        Cudd_ReadCacheUsedSlots() +
                        Reads the fraction of used slots in the cache. + +
                        Cudd_ReadCacheLookUps() +
                        Returns the number of cache look-ups. + +
                        Cudd_ReadCacheHits() +
                        Returns the number of cache hits. + +
                        Cudd_ReadRecursiveCalls() +
                        Returns the number of recursive calls. + +
                        Cudd_ReadMinHit() +
                        Reads the hit rate that causes resizinig of the computed + table. + +
                        Cudd_SetMinHit() +
                        Sets the hit rate that causes resizinig of the computed + table. + +
                        Cudd_ReadLooseUpTo() +
                        Reads the looseUpTo parameter of the manager. + +
                        Cudd_SetLooseUpTo() +
                        Sets the looseUpTo parameter of the manager. + +
                        Cudd_ReadMaxCache() +
                        Returns the soft limit for the cache size. + +
                        Cudd_ReadMaxCacheHard() +
                        Reads the maxCacheHard parameter of the manager. + +
                        Cudd_SetMaxCacheHard() +
                        Sets the maxCacheHard parameter of the manager. + +
                        Cudd_ReadSize() +
                        Returns the number of BDD variables in existance. + +
                        Cudd_ReadZddSize() +
                        Returns the number of ZDD variables in existance. + +
                        Cudd_ReadSlots() +
                        Returns the total number of slots of the unique table. + +
                        Cudd_ReadUsedSlots() +
                        Reads the fraction of used slots in the unique table. + +
                        Cudd_ExpectedUsedSlots() +
                        Computes the expected fraction of used slots in the unique + table. + +
                        Cudd_ReadKeys() +
                        Returns the number of nodes in the unique table. + +
                        Cudd_ReadDead() +
                        Returns the number of dead nodes in the unique table. + +
                        Cudd_ReadMinDead() +
                        Reads the minDead parameter of the manager. + +
                        Cudd_ReadReorderings() +
                        Returns the number of times reordering has occurred. + +
                        Cudd_ReadMaxReorderings() +
                        Returns the maximum number of times reordering may be invoked. + +
                        Cudd_SetMaxReorderings() +
                        Sets the maximum number of times reordering may be invoked. + +
                        Cudd_ReadReorderingTime() +
                        Returns the time spent in reordering. + +
                        Cudd_ReadGarbageCollections() +
                        Returns the number of times garbage collection has occurred. + +
                        Cudd_ReadGarbageCollectionTime() +
                        Returns the time spent in garbage collection. + +
                        Cudd_ReadNodesFreed() +
                        Returns the number of nodes freed. + +
                        Cudd_ReadNodesDropped() +
                        Returns the number of nodes dropped. + +
                        Cudd_ReadUniqueLookUps() +
                        Returns the number of look-ups in the unique table. + +
                        Cudd_ReadUniqueLinks() +
                        Returns the number of links followed in the unique table. + +
                        Cudd_ReadSiftMaxVar() +
                        Reads the siftMaxVar parameter of the manager. + +
                        Cudd_SetSiftMaxVar() +
                        Sets the siftMaxVar parameter of the manager. + +
                        Cudd_ReadSiftMaxSwap() +
                        Reads the siftMaxSwap parameter of the manager. + +
                        Cudd_SetSiftMaxSwap() +
                        Sets the siftMaxSwap parameter of the manager. + +
                        Cudd_ReadMaxGrowth() +
                        Reads the maxGrowth parameter of the manager. + +
                        Cudd_SetMaxGrowth() +
                        Sets the maxGrowth parameter of the manager. + +
                        Cudd_ReadMaxGrowthAlternate() +
                        Reads the maxGrowthAlt parameter of the manager. + +
                        Cudd_SetMaxGrowthAlternate() +
                        Sets the maxGrowthAlt parameter of the manager. + +
                        Cudd_ReadReorderingCycle() +
                        Reads the reordCycle parameter of the manager. + +
                        Cudd_SetReorderingCycle() +
                        Sets the reordCycle parameter of the manager. + +
                        Cudd_ReadTree() +
                        Returns the variable group tree of the manager. + +
                        Cudd_SetTree() +
                        Sets the variable group tree of the manager. + +
                        Cudd_FreeTree() +
                        Frees the variable group tree of the manager. + +
                        Cudd_ReadZddTree() +
                        Returns the variable group tree of the manager. + +
                        Cudd_SetZddTree() +
                        Sets the ZDD variable group tree of the manager. + +
                        Cudd_FreeZddTree() +
                        Frees the variable group tree of the manager. + +
                        Cudd_NodeReadIndex() +
                        Returns the index of the node. + +
                        Cudd_ReadPerm() +
                        Returns the current position of the i-th variable in the + order. + +
                        Cudd_ReadPermZdd() +
                        Returns the current position of the i-th ZDD variable in the + order. + +
                        Cudd_ReadInvPerm() +
                        Returns the index of the variable currently in the i-th + position of the order. + +
                        Cudd_ReadInvPermZdd() +
                        Returns the index of the ZDD variable currently in the i-th + position of the order. + +
                        Cudd_ReadVars() +
                        Returns the i-th element of the vars array. + +
                        Cudd_ReadEpsilon() +
                        Reads the epsilon parameter of the manager. + +
                        Cudd_SetEpsilon() +
                        Sets the epsilon parameter of the manager to ep. + +
                        Cudd_ReadGroupcheck() +
                        Reads the groupcheck parameter of the manager. + +
                        Cudd_SetGroupcheck() +
                        Sets the parameter groupcheck of the manager to gc. + +
                        Cudd_GarbageCollectionEnabled() +
                        Tells whether garbage collection is enabled. + +
                        Cudd_EnableGarbageCollection() +
                        Enables garbage collection. + +
                        Cudd_DisableGarbageCollection() +
                        Disables garbage collection. + +
                        Cudd_DeadAreCounted() +
                        Tells whether dead nodes are counted towards triggering + reordering. + +
                        Cudd_TurnOnCountDead() +
                        Causes the dead nodes to be counted towards triggering + reordering. + +
                        Cudd_TurnOffCountDead() +
                        Causes the dead nodes not to be counted towards triggering + reordering. + +
                        Cudd_ReadRecomb() +
                        Returns the current value of the recombination parameter used + in group sifting. + +
                        Cudd_SetRecomb() +
                        Sets the value of the recombination parameter used in group + sifting. + +
                        Cudd_ReadSymmviolation() +
                        Returns the current value of the symmviolation parameter used + in group sifting. + +
                        Cudd_SetSymmviolation() +
                        Sets the value of the symmviolation parameter used + in group sifting. + +
                        Cudd_ReadArcviolation() +
                        Returns the current value of the arcviolation parameter used + in group sifting. + +
                        Cudd_SetArcviolation() +
                        Sets the value of the arcviolation parameter used + in group sifting. + +
                        Cudd_ReadPopulationSize() +
                        Reads the current size of the population used by the + genetic algorithm for reordering. + +
                        Cudd_SetPopulationSize() +
                        Sets the size of the population used by the + genetic algorithm for reordering. + +
                        Cudd_ReadNumberXovers() +
                        Reads the current number of crossovers used by the + genetic algorithm for reordering. + +
                        Cudd_SetNumberXovers() +
                        Sets the number of crossovers used by the + genetic algorithm for reordering. + +
                        Cudd_ReadOrderRandomization() +
                        Returns the order randomization factor. + +
                        Cudd_SetOrderRandomization() +
                        Sets the order randomization factor. + +
                        Cudd_ReadMemoryInUse() +
                        Returns the memory in use by the manager measured in bytes. + +
                        Cudd_PrintInfo() +
                        Prints out statistics and settings for a CUDD manager. + +
                        Cudd_ReadPeakNodeCount() +
                        Reports the peak number of nodes. + +
                        Cudd_ReadPeakLiveNodeCount() +
                        Reports the peak number of live nodes. + +
                        Cudd_ReadNodeCount() +
                        Reports the number of nodes in BDDs and ADDs. + +
                        Cudd_zddReadNodeCount() +
                        Reports the number of nodes in ZDDs. + +
                        Cudd_AddHook() +
                        Adds a function to a hook. + +
                        Cudd_RemoveHook() +
                        Removes a function from a hook. + +
                        Cudd_IsInHook() +
                        Checks whether a function is in a hook. + +
                        Cudd_StdPreReordHook() +
                        Sample hook function to call before reordering. + +
                        Cudd_StdPostReordHook() +
                        Sample hook function to call after reordering. + +
                        Cudd_EnableReorderingReporting() +
                        Enables reporting of reordering stats. + +
                        Cudd_DisableReorderingReporting() +
                        Disables reporting of reordering stats. + +
                        Cudd_ReorderingReporting() +
                        Returns 1 if reporting of reordering stats is enabled. + +
                        Cudd_PrintGroupedOrder() +
                        Hook function to print the current variable order. + +
                        Cudd_EnableOrderingMonitoring() +
                        Enables monitoring of ordering. + +
                        Cudd_DisableOrderingMonitoring() +
                        Disables monitoring of ordering. + +
                        Cudd_OrderingMonitoring() +
                        Returns 1 if monitoring of ordering is enabled. + +
                        Cudd_ReadErrorCode() +
                        Returns the code of the last error. + +
                        Cudd_ClearErrorCode() +
                        Clear the error code of a manager. + +
                        Cudd_ReadStdout() +
                        Reads the stdout of a manager. + +
                        Cudd_SetStdout() +
                        Sets the stdout of a manager. + +
                        Cudd_ReadStderr() +
                        Reads the stderr of a manager. + +
                        Cudd_SetStderr() +
                        Sets the stderr of a manager. + +
                        Cudd_ReadNextReordering() +
                        Returns the threshold for the next dynamic reordering. + +
                        Cudd_SetNextReordering() +
                        Sets the threshold for the next dynamic reordering. + +
                        Cudd_ReadSwapSteps() +
                        Reads the number of elementary reordering steps. + +
                        Cudd_ReadMaxLive() +
                        Reads the maximum allowed number of live nodes. + +
                        Cudd_SetMaxLive() +
                        Sets the maximum allowed number of live nodes. + +
                        Cudd_ReadMaxMemory() +
                        Reads the maximum allowed memory. + +
                        Cudd_SetMaxMemory() +
                        Sets the maximum allowed memory. + +
                        Cudd_bddBindVar() +
                        Prevents sifting of a variable. + +
                        Cudd_bddUnbindVar() +
                        Allows the sifting of a variable. + +
                        Cudd_bddVarIsBound() +
                        Tells whether a variable can be sifted. + +
                        Cudd_bddSetPiVar() +
                        Sets a variable type to primary input. + +
                        Cudd_bddSetPsVar() +
                        Sets a variable type to present state. + +
                        Cudd_bddSetNsVar() +
                        Sets a variable type to next state. + +
                        Cudd_bddIsPiVar() +
                        Checks whether a variable is primary input. + +
                        Cudd_bddIsPsVar() +
                        Checks whether a variable is present state. + +
                        Cudd_bddIsNsVar() +
                        Checks whether a variable is next state. + +
                        Cudd_bddSetPairIndex() +
                        Sets a corresponding pair index for a given index. + +
                        Cudd_bddReadPairIndex() +
                        Reads a corresponding pair index for a given index. + +
                        Cudd_bddSetVarToBeGrouped() +
                        Sets a variable to be grouped. + +
                        Cudd_bddSetVarHardGroup() +
                        Sets a variable to be a hard group. + +
                        Cudd_bddResetVarToBeGrouped() +
                        Resets a variable not to be grouped. + +
                        Cudd_bddIsVarToBeGrouped() +
                        Checks whether a variable is set to be grouped. + +
                        Cudd_bddSetVarToBeUngrouped() +
                        Sets a variable to be ungrouped. + +
                        Cudd_bddIsVarToBeUngrouped() +
                        Checks whether a variable is set to be ungrouped. + +
                        Cudd_bddIsVarHardGroup() +
                        Checks whether a variable is set to be in a hard group. + +
                        fixVarTree() +
                        Fixes a variable group tree. + +
                        addMultiplicityGroups() +
                        Adds multiplicity groups to a ZDD variable group tree. + +
                        +
                        +

                        cuddApprox.c

                        +Procedures to approximate a given BDD.

                        +By: Fabio Somenzi

                        +External procedures provided by this module: +

                          +
                        • Cudd_UnderApprox() +
                        • Cudd_OverApprox() +
                        • Cudd_RemapUnderApprox() +
                        • Cudd_RemapOverApprox() +
                        • Cudd_BiasedUnderApprox() +
                        • Cudd_BiasedOverApprox() +
                        + Internal procedures included in this module: +
                          +
                        • cuddUnderApprox() +
                        • cuddRemapUnderApprox() +
                        • cuddBiasedUnderApprox() +
                        + Static procedures included in this module: +
                          +
                        • updateParity() +
                        • gatherInfoAux() +
                        • gatherInfo() +
                        • computeSavings() +
                        • updateRefs() +
                        • UAmarkNodes() +
                        • UAbuildSubset() +
                        • RAmarkNodes() +
                        • BAmarkNodes() +
                        • RAbuildSubset() +
                        • BAapplyBias() +

                        +

                        See AlsocuddSubsetHB.c +cuddSubsetSP.c +cuddGenCof.c +

                        +
                        Cudd_UnderApprox() +
                        Extracts a dense subset from a BDD with Shiple's + underapproximation method. + +
                        Cudd_OverApprox() +
                        Extracts a dense superset from a BDD with Shiple's + underapproximation method. + +
                        Cudd_RemapUnderApprox() +
                        Extracts a dense subset from a BDD with the remapping + underapproximation method. + +
                        Cudd_RemapOverApprox() +
                        Extracts a dense superset from a BDD with the remapping + underapproximation method. + +
                        Cudd_BiasedUnderApprox() +
                        Extracts a dense subset from a BDD with the biased + underapproximation method. + +
                        Cudd_BiasedOverApprox() +
                        Extracts a dense superset from a BDD with the biased + underapproximation method. + +
                        cuddUnderApprox() +
                        Applies Tom Shiple's underappoximation algorithm. + +
                        cuddRemapUnderApprox() +
                        Applies the remapping underappoximation algorithm. + +
                        cuddBiasedUnderApprox() +
                        Applies the biased remapping underappoximation algorithm. + +
                        updateParity() +
                        Recursively update the parity of the paths reaching a node. + +
                        gatherInfoAux() +
                        Recursively counts minterms and computes reference counts + of each node in the BDD. + +
                        gatherInfo() +
                        Gathers information about each node. + +
                        computeSavings() +
                        Counts the nodes that would be eliminated if a given node + were replaced by zero. + +
                        updateRefs() +
                        Update function reference counts. + +
                        UAmarkNodes() +
                        Marks nodes for replacement by zero. + +
                        UAbuildSubset() +
                        Builds the subset BDD. + +
                        RAmarkNodes() +
                        Marks nodes for remapping. + +
                        BAmarkNodes() +
                        Marks nodes for remapping. + +
                        RAbuildSubset() +
                        Builds the subset BDD for cuddRemapUnderApprox. + +
                        BAapplyBias() +
                        Finds don't care nodes. + +
                        +
                        +

                        cuddBddAbs.c

                        +Quantification functions for BDDs.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_bddExistAbstract() +
                        • Cudd_bddExistAbstractLimit() +
                        • Cudd_bddXorExistAbstract() +
                        • Cudd_bddUnivAbstract() +
                        • Cudd_bddBooleanDiff() +
                        • Cudd_bddVarIsDependent() +
                        + Internal procedures included in this module: +
                          +
                        • cuddBddExistAbstractRecur() +
                        • cuddBddXorExistAbstractRecur() +
                        • cuddBddBooleanDiffRecur() +
                        + Static procedures included in this module: +
                          +
                        • bddCheckPositiveCube() +

                        +

                        +
                        Cudd_bddExistAbstract() +
                        Existentially abstracts all the variables in cube from f. + +
                        Cudd_bddExistAbstractLimit() +
                        Existentially abstracts all the variables in cube from f. + +
                        Cudd_bddXorExistAbstract() +
                        Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
                        Cudd_bddUnivAbstract() +
                        Universally abstracts all the variables in cube from f. + +
                        Cudd_bddBooleanDiff() +
                        Computes the boolean difference of f with respect to x. + +
                        Cudd_bddVarIsDependent() +
                        Checks whether a variable is dependent on others in a + function. + +
                        cuddBddExistAbstractRecur() +
                        Performs the recursive steps of Cudd_bddExistAbstract. + +
                        cuddBddXorExistAbstractRecur() +
                        Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
                        cuddBddBooleanDiffRecur() +
                        Performs the recursive steps of Cudd_bddBoleanDiff. + +
                        bddCheckPositiveCube() +
                        Checks whether cube is an BDD representing the product of + positive literals. + +
                        +
                        +

                        cuddBddCorr.c

                        +Correlation between BDDs.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_bddCorrelation() +
                        • Cudd_bddCorrelationWeights() +
                        + Static procedures included in this module: +
                          +
                        • bddCorrelationAux() +
                        • bddCorrelationWeightsAux() +
                        • CorrelCompare() +
                        • CorrelHash() +
                        • CorrelCleanUp() +

                        +

                        +
                        Cudd_bddCorrelation() +
                        Computes the correlation of f and g. + +
                        Cudd_bddCorrelationWeights() +
                        Computes the correlation of f and g for given input + probabilities. + +
                        bddCorrelationAux() +
                        Performs the recursive step of Cudd_bddCorrelation. + +
                        bddCorrelationWeightsAux() +
                        Performs the recursive step of Cudd_bddCorrelationWeigths. + +
                        CorrelCompare() +
                        Compares two hash table entries. + +
                        CorrelHash() +
                        Hashes a hash table entry. + +
                        CorrelCleanUp() +
                        Frees memory associated with hash table. + +
                        +
                        +

                        cuddBddIte.c

                        +BDD ITE function and satellites.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_bddIte() +
                        • Cudd_bddIteLimit() +
                        • Cudd_bddIteConstant() +
                        • Cudd_bddIntersect() +
                        • Cudd_bddAnd() +
                        • Cudd_bddAndLimit() +
                        • Cudd_bddOr() +
                        • Cudd_bddOrLimit() +
                        • Cudd_bddNand() +
                        • Cudd_bddNor() +
                        • Cudd_bddXor() +
                        • Cudd_bddXnor() +
                        • Cudd_bddXnorLimit() +
                        • Cudd_bddLeq() +
                        + Internal procedures included in this module: +
                          +
                        • cuddBddIteRecur() +
                        • cuddBddIntersectRecur() +
                        • cuddBddAndRecur() +
                        • cuddBddXorRecur() +
                        + Static procedures included in this module: +
                          +
                        • bddVarToConst() +
                        • bddVarToCanonical() +
                        • bddVarToCanonicalSimple() +

                        +

                        +
                        Cudd_bddIte() +
                        Implements ITE(f,g,h). + +
                        Cudd_bddIteLimit() +
                        Implements ITE(f,g,h). Returns + NULL if too many nodes are required. + +
                        Cudd_bddIteConstant() +
                        Implements ITEconstant(f,g,h). + +
                        Cudd_bddIntersect() +
                        Returns a function included in the intersection of f and g. + +
                        Cudd_bddAnd() +
                        Computes the conjunction of two BDDs f and g. + +
                        Cudd_bddAndLimit() +
                        Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                        Cudd_bddOr() +
                        Computes the disjunction of two BDDs f and g. + +
                        Cudd_bddOrLimit() +
                        Computes the disjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                        Cudd_bddNand() +
                        Computes the NAND of two BDDs f and g. + +
                        Cudd_bddNor() +
                        Computes the NOR of two BDDs f and g. + +
                        Cudd_bddXor() +
                        Computes the exclusive OR of two BDDs f and g. + +
                        Cudd_bddXnor() +
                        Computes the exclusive NOR of two BDDs f and g. + +
                        Cudd_bddXnorLimit() +
                        Computes the exclusive NOR of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                        Cudd_bddLeq() +
                        Determines whether f is less than or equal to g. + +
                        cuddBddIteRecur() +
                        Implements the recursive step of Cudd_bddIte. + +
                        cuddBddIntersectRecur() +
                        Implements the recursive step of Cudd_bddIntersect. + +
                        cuddBddAndRecur() +
                        Implements the recursive step of Cudd_bddAnd. + +
                        cuddBddXorRecur() +
                        Implements the recursive step of Cudd_bddXor. + +
                        bddVarToConst() +
                        Replaces variables with constants if possible. + +
                        bddVarToCanonical() +
                        Picks unique member from equiv expressions. + +
                        bddVarToCanonicalSimple() +
                        Picks unique member from equiv expressions. + +
                        +
                        +

                        cuddBridge.c

                        +Translation from BDD to ADD and vice versa and transfer between + different managers.

                        +By: Fabio Somenzi

                        +External procedures included in this file: +

                          +
                        • Cudd_addBddThreshold() +
                        • Cudd_addBddStrictThreshold() +
                        • Cudd_addBddInterval() +
                        • Cudd_addBddIthBit() +
                        • Cudd_BddToAdd() +
                        • Cudd_addBddPattern() +
                        • Cudd_bddTransfer() +
                        + Internal procedures included in this file: +
                          +
                        • cuddBddTransfer() +
                        • cuddAddBddDoPattern() +
                        + Static procedures included in this file: +
                          +
                        • addBddDoThreshold() +
                        • addBddDoStrictThreshold() +
                        • addBddDoInterval() +
                        • addBddDoIthBit() +
                        • ddBddToAddRecur() +
                        • cuddBddTransferRecur() +

                        +

                        +
                        Cudd_addBddThreshold() +
                        Converts an ADD to a BDD. + +
                        Cudd_addBddStrictThreshold() +
                        Converts an ADD to a BDD. + +
                        Cudd_addBddInterval() +
                        Converts an ADD to a BDD. + +
                        Cudd_addBddIthBit() +
                        Converts an ADD to a BDD by extracting the i-th bit from + the leaves. + +
                        Cudd_BddToAdd() +
                        Converts a BDD to a 0-1 ADD. + +
                        Cudd_addBddPattern() +
                        Converts an ADD to a BDD. + +
                        Cudd_bddTransfer() +
                        Convert a BDD from a manager to another one. + +
                        cuddBddTransfer() +
                        Convert a BDD from a manager to another one. + +
                        cuddAddBddDoPattern() +
                        Performs the recursive step for Cudd_addBddPattern. + +
                        addBddDoThreshold() +
                        Performs the recursive step for Cudd_addBddThreshold. + +
                        addBddDoStrictThreshold() +
                        Performs the recursive step for Cudd_addBddStrictThreshold. + +
                        addBddDoInterval() +
                        Performs the recursive step for Cudd_addBddInterval. + +
                        addBddDoIthBit() +
                        Performs the recursive step for Cudd_addBddIthBit. + +
                        ddBddToAddRecur() +
                        Performs the recursive step for Cudd_BddToAdd. + +
                        cuddBddTransferRecur() +
                        Performs the recursive step of Cudd_bddTransfer. + +
                        +
                        +

                        cuddCache.c

                        +Functions for cache insertion and lookup.

                        +By: Fabio Somenzi

                        +Internal procedures included in this module: +

                          +
                        • cuddInitCache() +
                        • cuddCacheInsert() +
                        • cuddCacheInsert2() +
                        • cuddCacheLookup() +
                        • cuddCacheLookupZdd() +
                        • cuddCacheLookup2() +
                        • cuddCacheLookup2Zdd() +
                        • cuddConstantLookup() +
                        • cuddCacheProfile() +
                        • cuddCacheResize() +
                        • cuddCacheFlush() +
                        • cuddComputeFloorLog2() +
                        + Static procedures included in this module: +
                          +

                        +

                        +
                        cuddInitCache() +
                        Initializes the computed table. + +
                        cuddCacheInsert() +
                        Inserts a result in the cache for a function with three + operands. + +
                        cuddCacheInsert2() +
                        Inserts a result in the cache for a function with two + operands. + +
                        cuddCacheInsert1() +
                        Inserts a result in the cache for a function with two + operands. + +
                        cuddCacheLookup() +
                        Looks up in the cache for the result of op applied to f, + g, and h. + +
                        cuddCacheLookupZdd() +
                        Looks up in the cache for the result of op applied to f, + g, and h. + +
                        cuddCacheLookup2() +
                        Looks up in the cache for the result of op applied to f + and g. + +
                        cuddCacheLookup1() +
                        Looks up in the cache for the result of op applied to f. + +
                        cuddCacheLookup2Zdd() +
                        Looks up in the cache for the result of op applied to f + and g. + +
                        cuddCacheLookup1Zdd() +
                        Looks up in the cache for the result of op applied to f. + +
                        cuddConstantLookup() +
                        Looks up in the cache for the result of op applied to f, + g, and h. + +
                        cuddCacheProfile() +
                        Computes and prints a profile of the cache usage. + +
                        cuddCacheResize() +
                        Resizes the cache. + +
                        cuddCacheFlush() +
                        Flushes the cache. + +
                        cuddComputeFloorLog2() +
                        Returns the floor of the logarithm to the base 2. + +
                        +
                        +

                        cuddCheck.c

                        +Functions to check consistency of data structures.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_DebugCheck() +
                        • Cudd_CheckKeys() +
                        + Internal procedures included in this module: +
                          +
                        • cuddHeapProfile() +
                        • cuddPrintNode() +
                        • cuddPrintVarGroups() +
                        + Static procedures included in this module: +
                          +
                        • debugFindParent() +

                        +

                        +
                        Cudd_DebugCheck() +
                        Checks for inconsistencies in the DD heap. + +
                        Cudd_CheckKeys() +
                        Checks for several conditions that should not occur. + +
                        cuddHeapProfile() +
                        Prints information about the heap. + +
                        cuddPrintNode() +
                        Prints out information on a node. + +
                        cuddPrintVarGroups() +
                        Prints the variable groups as a parenthesized list. + +
                        debugFindParent() +
                        Searches the subtables above node for its parents. + +
                        debugCheckParent() +
                        Reports an error if a (dead) node has a non-dead parent. + +
                        +
                        +

                        cuddClip.c

                        +Clipping functions.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_bddClippingAnd() +
                        • Cudd_bddClippingAndAbstract() +
                        + Internal procedures included in this module: +
                          +
                        • cuddBddClippingAnd() +
                        • cuddBddClippingAndAbstract() +
                        + Static procedures included in this module: +
                          +
                        • cuddBddClippingAndRecur() +
                        • cuddBddClipAndAbsRecur() +
                        + + SeeAlso [

                        +

                        +
                        Cudd_bddClippingAnd() +
                        Approximates the conjunction of two BDDs f and g. + +
                        Cudd_bddClippingAndAbstract() +
                        Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
                        cuddBddClippingAnd() +
                        Approximates the conjunction of two BDDs f and g. + +
                        cuddBddClippingAndAbstract() +
                        Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
                        cuddBddClippingAndRecur() +
                        Implements the recursive step of Cudd_bddClippingAnd. + +
                        cuddBddClipAndAbsRecur() +
                        Approximates the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                        +
                        +

                        cuddCof.c

                        +Cofactoring functions.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_Cofactor() +
                        • Cudd_CheckCube() +
                        + Internal procedures included in this module: +
                          +
                        • cuddGetBranches() +
                        • cuddCofactorRecur() +

                        +

                        +
                        Cudd_Cofactor() +
                        Computes the cofactor of f with respect to g. + +
                        Cudd_CheckCube() +
                        Checks whether g is the BDD of a cube. + +
                        cuddGetBranches() +
                        Computes the children of g. + +
                        cuddCofactorRecur() +
                        Performs the recursive step of Cudd_Cofactor. + +
                        +
                        +

                        cuddCompose.c

                        +Functional composition and variable permutation of DDs.

                        +By: Fabio Somenzi and Kavita Ravi

                        +External procedures included in this module: +

                          +
                        • Cudd_bddCompose() +
                        • Cudd_addCompose() +
                        • Cudd_addPermute() +
                        • Cudd_addSwapVariables() +
                        • Cudd_bddPermute() +
                        • Cudd_bddVarMap() +
                        • Cudd_SetVarMap() +
                        • Cudd_bddSwapVariables() +
                        • Cudd_bddAdjPermuteX() +
                        • Cudd_addVectorCompose() +
                        • Cudd_addGeneralVectorCompose() +
                        • Cudd_addNonSimCompose() +
                        • Cudd_bddVectorCompose() +
                        + Internal procedures included in this module: +
                          +
                        • cuddBddComposeRecur() +
                        • cuddAddComposeRecur() +
                        + Static procedures included in this module: +
                          +
                        • cuddAddPermuteRecur() +
                        • cuddBddPermuteRecur() +
                        • cuddBddVarMapRecur() +
                        • cuddAddVectorComposeRecur() +
                        • cuddAddGeneralVectorComposeRecur() +
                        • cuddAddNonSimComposeRecur() +
                        • cuddBddVectorComposeRecur() +
                        • ddIsIthAddVar() +
                        • ddIsIthAddVarPair() +
                        + The permutation functions use a local cache because the results to + be remembered depend on the permutation being applied. Since the + permutation is just an array, it cannot be stored in the global + cache. There are different procedured for BDDs and ADDs. This is + because bddPermuteRecur uses cuddBddIteRecur. If this were changed, + the procedures could be merged.

                        +

                        +
                        Cudd_bddCompose() +
                        Substitutes g for x_v in the BDD for f. + +
                        Cudd_addCompose() +
                        Substitutes g for x_v in the ADD for f. + +
                        Cudd_addPermute() +
                        Permutes the variables of an ADD. + +
                        Cudd_addSwapVariables() +
                        Swaps two sets of variables of the same size (x and y) in + the ADD f. + +
                        Cudd_bddPermute() +
                        Permutes the variables of a BDD. + +
                        Cudd_bddVarMap() +
                        Remaps the variables of a BDD using the default variable map. + +
                        Cudd_SetVarMap() +
                        Registers a variable mapping with the manager. + +
                        Cudd_bddSwapVariables() +
                        Swaps two sets of variables of the same size (x and y) in + the BDD f. + +
                        Cudd_bddAdjPermuteX() +
                        Rearranges a set of variables in the BDD B. + +
                        Cudd_addVectorCompose() +
                        Composes an ADD with a vector of 0-1 ADDs. + +
                        Cudd_addGeneralVectorCompose() +
                        Composes an ADD with a vector of ADDs. + +
                        Cudd_addNonSimCompose() +
                        Composes an ADD with a vector of 0-1 ADDs. + +
                        Cudd_bddVectorCompose() +
                        Composes a BDD with a vector of BDDs. + +
                        cuddBddComposeRecur() +
                        Performs the recursive step of Cudd_bddCompose. + +
                        cuddAddComposeRecur() +
                        Performs the recursive step of Cudd_addCompose. + +
                        cuddAddPermuteRecur() +
                        Implements the recursive step of Cudd_addPermute. + +
                        cuddBddPermuteRecur() +
                        Implements the recursive step of Cudd_bddPermute. + +
                        cuddBddVarMapRecur() +
                        Implements the recursive step of Cudd_bddVarMap. + +
                        cuddAddVectorComposeRecur() +
                        Performs the recursive step of Cudd_addVectorCompose. + +
                        cuddAddGeneralVectorComposeRecur() +
                        Performs the recursive step of Cudd_addGeneralVectorCompose. + +
                        cuddAddNonSimComposeRecur() +
                        Performs the recursive step of Cudd_addNonSimCompose. + +
                        cuddBddVectorComposeRecur() +
                        Performs the recursive step of Cudd_bddVectorCompose. + +
                        () +
                        Comparison of a function to the i-th ADD variable. + +
                        () +
                        Comparison of a pair of functions to the i-th ADD variable. + +
                        +
                        +

                        cuddDecomp.c

                        +Functions for BDD decomposition.

                        +By: Kavita Ravi, Fabio Somenzi

                        +External procedures included in this file: +

                          +
                        • Cudd_bddApproxConjDecomp() +
                        • Cudd_bddApproxDisjDecomp() +
                        • Cudd_bddIterConjDecomp() +
                        • Cudd_bddIterDisjDecomp() +
                        • Cudd_bddGenConjDecomp() +
                        • Cudd_bddGenDisjDecomp() +
                        • Cudd_bddVarConjDecomp() +
                        • Cudd_bddVarDisjDecomp() +
                        + Static procedures included in this module: +
                          +
                        • cuddConjunctsAux() +
                        • CreateBotDist() +
                        • BuildConjuncts() +
                        • ConjunctsFree() +

                        +

                        +
                        Cudd_bddApproxConjDecomp() +
                        Performs two-way conjunctive decomposition of a BDD. + +
                        Cudd_bddApproxDisjDecomp() +
                        Performs two-way disjunctive decomposition of a BDD. + +
                        Cudd_bddIterConjDecomp() +
                        Performs two-way conjunctive decomposition of a BDD. + +
                        Cudd_bddIterDisjDecomp() +
                        Performs two-way disjunctive decomposition of a BDD. + +
                        Cudd_bddGenConjDecomp() +
                        Performs two-way conjunctive decomposition of a BDD. + +
                        Cudd_bddGenDisjDecomp() +
                        Performs two-way disjunctive decomposition of a BDD. + +
                        Cudd_bddVarConjDecomp() +
                        Performs two-way conjunctive decomposition of a BDD. + +
                        Cudd_bddVarDisjDecomp() +
                        Performs two-way disjunctive decomposition of a BDD. + +
                        CreateBotDist() +
                        Get longest distance of node from constant. + +
                        CountMinterms() +
                        Count the number of minterms of each node ina a BDD and + store it in a hash table. + +
                        ConjunctsFree() +
                        Free factors structure + +
                        PairInTables() +
                        Check whether the given pair is in the tables. + +
                        CheckTablesCacheAndReturn() +
                        Check the tables for the existence of pair and return one + combination, cache the result. + +
                        PickOnePair() +
                        Check the tables for the existence of pair and return one + combination, store in cache. + +
                        CheckInTables() +
                        Check if the two pairs exist in the table, If any of the + conjuncts do exist, store in the cache and return the corresponding pair. + +
                        ZeroCase() +
                        If one child is zero, do explicitly what Restrict does or better + +
                        BuildConjuncts() +
                        Builds the conjuncts recursively, bottom up. + +
                        cuddConjunctsAux() +
                        Procedure to compute two conjunctive factors of f and place in *c1 and *c2. + +
                        +
                        +

                        cuddEssent.c

                        +Functions for the detection of essential variables.

                        +By: Fabio Somenzi

                        +External procedures included in this file: +

                          +
                        • Cudd_FindEssential() +
                        • Cudd_bddIsVarEssential() +
                        • Cudd_FindTwoLiteralClauses() +
                        • Cudd_ReadIthClause() +
                        • Cudd_PrintTwoLiteralClauses() +
                        • Cudd_tlcInfoFree() +
                        + Static procedures included in this module: +
                          +
                        • ddFindEssentialRecur() +
                        • ddFindTwoLiteralClausesRecur() +
                        • computeClauses() +
                        • computeClausesWithUniverse() +
                        • emptyClauseSet() +
                        • sentinelp() +
                        • equalp() +
                        • beforep() +
                        • oneliteralp() +
                        • impliedp() +
                        • bitVectorAlloc() +
                        • bitVectorClear() +
                        • bitVectorFree() +
                        • bitVectorRead() +
                        • bitVectorSet() +
                        • tlcInfoAlloc() +

                        +

                        +
                        Cudd_FindEssential() +
                        Finds the essential variables of a DD. + +
                        Cudd_bddIsVarEssential() +
                        Determines whether a given variable is essential with a + given phase in a BDD. + +
                        Cudd_FindTwoLiteralClauses() +
                        Finds the two literal clauses of a DD. + +
                        Cudd_ReadIthClause() +
                        Accesses the i-th clause of a DD. + +
                        Cudd_PrintTwoLiteralClauses() +
                        Prints the two literal clauses of a DD. + +
                        Cudd_tlcInfoFree() +
                        Frees a DdTlcInfo Structure. + +
                        ddFindEssentialRecur() +
                        Implements the recursive step of Cudd_FindEssential. + +
                        ddFindTwoLiteralClausesRecur() +
                        Implements the recursive step of Cudd_FindTwoLiteralClauses. + +
                        computeClauses() +
                        Computes the two-literal clauses for a node. + +
                        computeClausesWithUniverse() +
                        Computes the two-literal clauses for a node. + +
                        emptyClauseSet() +
                        Returns an enpty set of clauses. + +
                        sentinelp() +
                        Returns true iff the argument is the sentinel clause. + +
                        equalp() +
                        Returns true iff the two arguments are identical clauses. + +
                        beforep() +
                        Returns true iff the first argument precedes the second in + the clause order. + +
                        oneliteralp() +
                        Returns true iff the argument is a one-literal clause. + +
                        impliedp() +
                        Returns true iff either literal of a clause is in a set of + literals. + +
                        bitVectorAlloc() +
                        Allocates a bit vector. + +
                        () +
                        Clears a bit vector. + +
                        bitVectorFree() +
                        Frees a bit vector. + +
                        () +
                        Returns the i-th entry of a bit vector. + +
                        () +
                        Sets the i-th entry of a bit vector to a value. + +
                        tlcInfoAlloc() +
                        Allocates a DdTlcInfo Structure. + +
                        +
                        +

                        cuddExact.c

                        +Functions for exact variable reordering.

                        +By: Cheng Hua, Fabio Somenzi

                        +External procedures included in this file: +

                          +
                        + Internal procedures included in this module: +
                          +
                        • cuddExact() +
                        + Static procedures included in this module: +
                          +
                        • getMaxBinomial() +
                        • gcd() +
                        • getMatrix() +
                        • freeMatrix() +
                        • getLevelKeys() +
                        • ddShuffle() +
                        • ddSiftUp() +
                        • updateUB() +
                        • ddCountRoots() +
                        • ddClearGlobal() +
                        • computeLB() +
                        • updateEntry() +
                        • pushDown() +
                        • initSymmInfo() +

                        +

                        +
                        cuddExact() +
                        Exact variable ordering algorithm. + +
                        getMaxBinomial() +
                        Returns the maximum value of (n choose k) for a given n. + +
                        gcd() +
                        Returns the gcd of two integers. + +
                        getMatrix() +
                        Allocates a two-dimensional matrix of ints. + +
                        freeMatrix() +
                        Frees a two-dimensional matrix allocated by getMatrix. + +
                        getLevelKeys() +
                        Returns the number of nodes at one level of a unique table. + +
                        ddShuffle() +
                        Reorders variables according to a given permutation. + +
                        ddSiftUp() +
                        Moves one variable up. + +
                        updateUB() +
                        Updates the upper bound and saves the best order seen so far. + +
                        ddCountRoots() +
                        Counts the number of roots. + +
                        ddClearGlobal() +
                        Scans the DD and clears the LSB of the next pointers. + +
                        computeLB() +
                        Computes a lower bound on the size of a BDD. + +
                        updateEntry() +
                        Updates entry for a subset. + +
                        pushDown() +
                        Pushes a variable in the order down to position "level." + +
                        initSymmInfo() +
                        Gathers symmetry information. + +
                        checkSymmInfo() +
                        Check symmetry condition. + +
                        +
                        +

                        cuddExport.c

                        +Export functions.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_DumpBlif() +
                        • Cudd_DumpBlifBody() +
                        • Cudd_DumpDot() +
                        • Cudd_DumpDaVinci() +
                        • Cudd_DumpDDcal() +
                        • Cudd_DumpFactoredForm() +
                        + Internal procedures included in this module: +
                          +
                        + Static procedures included in this module: +
                          +
                        • ddDoDumpBlif() +
                        • ddDoDumpDaVinci() +
                        • ddDoDumpDDcal() +
                        • ddDoDumpFactoredForm() +

                        +

                        +
                        Cudd_DumpBlif() +
                        Writes a blif file representing the argument BDDs. + +
                        Cudd_DumpBlifBody() +
                        Writes a blif body representing the argument BDDs. + +
                        Cudd_DumpDot() +
                        Writes a dot file representing the argument DDs. + +
                        Cudd_DumpDaVinci() +
                        Writes a daVinci file representing the argument BDDs. + +
                        Cudd_DumpDDcal() +
                        Writes a DDcal file representing the argument BDDs. + +
                        Cudd_DumpFactoredForm() +
                        Writes factored forms representing the argument BDDs. + +
                        ddDoDumpBlif() +
                        Performs the recursive step of Cudd_DumpBlif. + +
                        ddDoDumpDaVinci() +
                        Performs the recursive step of Cudd_DumpDaVinci. + +
                        ddDoDumpDDcal() +
                        Performs the recursive step of Cudd_DumpDDcal. + +
                        ddDoDumpFactoredForm() +
                        Performs the recursive step of Cudd_DumpFactoredForm. + +
                        +
                        +

                        cuddGenCof.c

                        +Generalized cofactors for BDDs and ADDs.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_bddConstrain() +
                        • Cudd_bddRestrict() +
                        • Cudd_bddNPAnd() +
                        • Cudd_addConstrain() +
                        • Cudd_bddConstrainDecomp() +
                        • Cudd_addRestrict() +
                        • Cudd_bddCharToVect() +
                        • Cudd_bddLICompaction() +
                        • Cudd_bddSqueeze() +
                        • Cudd_bddMinimize() +
                        • Cudd_SubsetCompress() +
                        • Cudd_SupersetCompress() +
                        + Internal procedures included in this module: +
                          +
                        • cuddBddConstrainRecur() +
                        • cuddBddRestrictRecur() +
                        • cuddBddNPAndRecur() +
                        • cuddAddConstrainRecur() +
                        • cuddAddRestrictRecur() +
                        • cuddBddLICompaction() +
                        + Static procedures included in this module: +
                          +
                        • cuddBddConstrainDecomp() +
                        • cuddBddCharToVect() +
                        • cuddBddLICMarkEdges() +
                        • cuddBddLICBuildResult() +
                        • MarkCacheHash() +
                        • MarkCacheCompare() +
                        • MarkCacheCleanUp() +
                        • cuddBddSqueeze() +

                        +

                        +
                        Cudd_bddConstrain() +
                        Computes f constrain c. + +
                        Cudd_bddRestrict() +
                        BDD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
                        Cudd_bddNPAnd() +
                        Computes f non-polluting-and g. + +
                        Cudd_addConstrain() +
                        Computes f constrain c for ADDs. + +
                        Cudd_bddConstrainDecomp() +
                        BDD conjunctive decomposition as in McMillan's CAV96 paper. + +
                        Cudd_addRestrict() +
                        ADD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
                        Cudd_bddCharToVect() +
                        Computes a vector whose image equals a non-zero function. + +
                        Cudd_bddLICompaction() +
                        Performs safe minimization of a BDD. + +
                        Cudd_bddSqueeze() +
                        Finds a small BDD in a function interval. + +
                        Cudd_bddMinimize() +
                        Finds a small BDD that agrees with f over + c. + +
                        Cudd_SubsetCompress() +
                        Find a dense subset of BDD f. + +
                        Cudd_SupersetCompress() +
                        Find a dense superset of BDD f. + +
                        cuddBddConstrainRecur() +
                        Performs the recursive step of Cudd_bddConstrain. + +
                        cuddBddRestrictRecur() +
                        Performs the recursive step of Cudd_bddRestrict. + +
                        cuddBddNPAndRecur() +
                        Implements the recursive step of Cudd_bddAnd. + +
                        cuddAddConstrainRecur() +
                        Performs the recursive step of Cudd_addConstrain. + +
                        cuddAddRestrictRecur() +
                        Performs the recursive step of Cudd_addRestrict. + +
                        cuddBddLICompaction() +
                        Performs safe minimization of a BDD. + +
                        cuddBddConstrainDecomp() +
                        Performs the recursive step of Cudd_bddConstrainDecomp. + +
                        cuddBddCharToVect() +
                        Performs the recursive step of Cudd_bddCharToVect. + +
                        cuddBddLICMarkEdges() +
                        Performs the edge marking step of Cudd_bddLICompaction. + +
                        cuddBddLICBuildResult() +
                        Builds the result of Cudd_bddLICompaction. + +
                        MarkCacheHash() +
                        Hash function for the computed table of cuddBddLICMarkEdges. + +
                        MarkCacheCompare() +
                        Comparison function for the computed table of + cuddBddLICMarkEdges. + +
                        MarkCacheCleanUp() +
                        Frees memory associated with computed table of + cuddBddLICMarkEdges. + +
                        cuddBddSqueeze() +
                        Performs the recursive step of Cudd_bddSqueeze. + +
                        +
                        +

                        cuddGenetic.c

                        +Genetic algorithm for variable reordering.

                        +By: Curt Musfeldt, Alan Shuler, Fabio Somenzi

                        +Internal procedures included in this file: +

                          +
                        • cuddGa() +
                        + Static procedures included in this module: +
                          +
                        • make_random() +
                        • sift_up() +
                        • build_dd() +
                        • largest() +
                        • rand_int() +
                        • array_hash() +
                        • array_compare() +
                        • find_best() +
                        • find_average_fitness() +
                        • PMX() +
                        • roulette() +
                        + + The genetic algorithm implemented here is as follows. We start with + the current DD order. We sift this order and use this as the + reference DD. We only keep 1 DD around for the entire process and + simply rearrange the order of this DD, storing the various orders + and their corresponding DD sizes. We generate more random orders to + build an initial population. This initial population is 3 times the + number of variables, with a maximum of 120. Each random order is + built (from the reference DD) and its size stored. Each random + order is also sifted to keep the DD sizes fairly small. Then a + crossover is performed between two orders (picked randomly) and the + two resulting DDs are built and sifted. For each new order, if its + size is smaller than any DD in the population, it is inserted into + the population and the DD with the largest number of nodes is thrown + out. The crossover process happens up to 50 times, and at this point + the DD in the population with the smallest size is chosen as the + result. This DD must then be built from the reference DD.

                        +

                        +
                        cuddGa() +
                        Genetic algorithm for DD reordering. + +
                        make_random() +
                        Generates the random sequences for the initial population. + +
                        sift_up() +
                        Moves one variable up. + +
                        build_dd() +
                        Builds a DD from a given order. + +
                        largest() +
                        Finds the largest DD in the population. + +
                        rand_int() +
                        Generates a random number between 0 and the integer a. + +
                        array_hash() +
                        Hash function for the computed table. + +
                        array_compare() +
                        Comparison function for the computed table. + +
                        find_best() +
                        Returns the index of the fittest individual. + +
                        () +
                        Returns the average fitness of the population. + +
                        PMX() +
                        Performs the crossover between two parents. + +
                        roulette() +
                        Selects two parents with the roulette wheel method. + +
                        +
                        +

                        cuddGroup.c

                        +Functions for group sifting.

                        +By: Shipra Panda, Fabio Somenzi

                        +External procedures included in this file: +

                          +
                        • Cudd_MakeTreeNode() +
                        + Internal procedures included in this file: +
                          +
                        • cuddTreeSifting() +
                        + Static procedures included in this module: +
                          +
                        • ddTreeSiftingAux() +
                        • ddCountInternalMtrNodes() +
                        • ddReorderChildren() +
                        • ddFindNodeHiLo() +
                        • ddUniqueCompareGroup() +
                        • ddGroupSifting() +
                        • ddCreateGroup() +
                        • ddGroupSiftingAux() +
                        • ddGroupSiftingUp() +
                        • ddGroupSiftingDown() +
                        • ddGroupMove() +
                        • ddGroupMoveBackward() +
                        • ddGroupSiftingBackward() +
                        • ddMergeGroups() +
                        • ddDissolveGroup() +
                        • ddNoCheck() +
                        • ddSecDiffCheck() +
                        • ddExtSymmCheck() +
                        • ddVarGroupCheck() +
                        • ddSetVarHandled() +
                        • ddResetVarHandled() +
                        • ddIsVarHandled() +
                        • ddFixTree() +

                        +

                        +
                        Cudd_MakeTreeNode() +
                        Creates a new variable group. + +
                        cuddTreeSifting() +
                        Tree sifting algorithm. + +
                        ddTreeSiftingAux() +
                        Visits the group tree and reorders each group. + +
                        ddCountInternalMtrNodes() +
                        Counts the number of internal nodes of the group tree. + +
                        ddReorderChildren() +
                        Reorders the children of a group tree node according to + the options. + +
                        ddFindNodeHiLo() +
                        Finds the lower and upper bounds of the group represented + by treenode. + +
                        ddUniqueCompareGroup() +
                        Comparison function used by qsort. + +
                        ddGroupSifting() +
                        Sifts from treenode->low to treenode->high. + +
                        ddCreateGroup() +
                        Creates a group encompassing variables from x to y in the + DD table. + +
                        ddGroupSiftingAux() +
                        Sifts one variable up and down until it has taken all + positions. Checks for aggregation. + +
                        ddGroupSiftingUp() +
                        Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much. + +
                        ddGroupSiftingDown() +
                        Sifts down a variable until it reaches position xHigh. + +
                        ddGroupMove() +
                        Swaps two groups and records the move. + +
                        ddGroupMoveBackward() +
                        Undoes the swap two groups. + +
                        ddGroupSiftingBackward() +
                        Determines the best position for a variables and returns + it there. + +
                        ddMergeGroups() +
                        Merges groups in the DD table. + +
                        ddDissolveGroup() +
                        Dissolves a group in the DD table. + +
                        ddNoCheck() +
                        Pretends to check two variables for aggregation. + +
                        ddSecDiffCheck() +
                        Checks two variables for aggregation. + +
                        ddExtSymmCheck() +
                        Checks for extended symmetry of x and y. + +
                        ddVarGroupCheck() +
                        Checks for grouping of x and y. + +
                        ddSetVarHandled() +
                        Sets a variable to already handled. + +
                        ddResetVarHandled() +
                        Resets a variable to be processed. + +
                        ddIsVarHandled() +
                        Checks whether a variables is already handled. + +
                        +
                        +

                        cuddHarwell.c

                        +Function to read a matrix in Harwell format.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_addHarwell() +

                        +

                        +
                        Cudd_addHarwell() +
                        Reads in a matrix in the format of the Harwell-Boeing + benchmark suite. + +
                        +
                        +

                        cuddInit.c

                        +Functions to initialize and shut down the DD manager.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_Init() +
                        • Cudd_Quit() +
                        + Internal procedures included in this module: +
                          +
                        • cuddZddInitUniv() +
                        • cuddZddFreeUniv() +

                        +

                        +
                        Cudd_Init() +
                        Creates a new DD manager. + +
                        Cudd_Quit() +
                        Deletes resources associated with a DD manager. + +
                        cuddZddInitUniv() +
                        Initializes the ZDD universe. + +
                        cuddZddFreeUniv() +
                        Frees the ZDD universe. + +
                        +
                        +

                        cuddInteract.c

                        +Functions to manipulate the variable interaction matrix.

                        +By: Fabio Somenzi

                        +Internal procedures included in this file: +

                          +
                        • cuddSetInteract() +
                        • cuddTestInteract() +
                        • cuddInitInteract() +
                        + Static procedures included in this file: +
                          +
                        • ddSuppInteract() +
                        • ddClearLocal() +
                        • ddUpdateInteract() +
                        • ddClearGlobal() +
                        + The interaction matrix tells whether two variables are + both in the support of some function of the DD. The main use of the + interaction matrix is in the in-place swapping. Indeed, if two + variables do not interact, there is no arc connecting the two layers; + therefore, the swap can be performed in constant time, without + scanning the subtables. Another use of the interaction matrix is in + the computation of the lower bounds for sifting. Finally, the + interaction matrix can be used to speed up aggregation checks in + symmetric and group sifting.

                        + The computation of the interaction matrix is done with a series of + depth-first searches. The searches start from those nodes that have + only external references. The matrix is stored as a packed array of bits; + since it is symmetric, only the upper triangle is kept in memory. + As a final remark, we note that there may be variables that do + interact, but that for a given variable order have no arc connecting + their layers when they are adjacent. For instance, in ite(a,b,c) with + the order a +

                        +
                        cuddSetInteract() +
                        Set interaction matrix entries. + +
                        cuddTestInteract() +
                        Test interaction matrix entries. + +
                        cuddInitInteract() +
                        Initializes the interaction matrix. + +
                        ddSuppInteract() +
                        Find the support of f. + +
                        ddClearLocal() +
                        Performs a DFS from f, clearing the LSB of the then pointers. + +
                        ddUpdateInteract() +
                        Marks as interacting all pairs of variables that appear in + support. + +
                        ddClearGlobal() +
                        Scans the DD and clears the LSB of the next pointers. + +
                        +
                        +

                        cuddLCache.c

                        +Functions for local caches.

                        +By: Fabio Somenzi

                        +Internal procedures included in this module: +

                          +
                        • cuddLocalCacheInit() +
                        • cuddLocalCacheQuit() +
                        • cuddLocalCacheInsert() +
                        • cuddLocalCacheLookup() +
                        • cuddLocalCacheClearDead() +
                        • cuddLocalCacheClearAll() +
                        • cuddLocalCacheProfile() +
                        • cuddHashTableInit() +
                        • cuddHashTableQuit() +
                        • cuddHashTableGenericQuit() +
                        • cuddHashTableInsert() +
                        • cuddHashTableLookup() +
                        • cuddHashTableGenericInsert() +
                        • cuddHashTableGenericLookup() +
                        • cuddHashTableInsert2() +
                        • cuddHashTableLookup2() +
                        • cuddHashTableInsert3() +
                        • cuddHashTableLookup3() +
                        + Static procedures included in this module: +
                          +
                        • cuddLocalCacheResize() +
                        • ddLCHash() +
                        • cuddLocalCacheAddToList() +
                        • cuddLocalCacheRemoveFromList() +
                        • cuddHashTableResize() +
                        • cuddHashTableAlloc() +

                        +

                        +
                        cuddLocalCacheInit() +
                        Initializes a local computed table. + +
                        cuddLocalCacheQuit() +
                        Shuts down a local computed table. + +
                        cuddLocalCacheInsert() +
                        Inserts a result in a local cache. + +
                        cuddLocalCacheLookup() +
                        Looks up in a local cache. + +
                        cuddLocalCacheClearDead() +
                        Clears the dead entries of the local caches of a manager. + +
                        cuddLocalCacheClearAll() +
                        Clears the local caches of a manager. + +
                        cuddLocalCacheProfile() +
                        Computes and prints a profile of a local cache usage. + +
                        cuddHashTableInit() +
                        Initializes a hash table. + +
                        cuddHashTableQuit() +
                        Shuts down a hash table. + +
                        cuddHashTableGenericQuit() +
                        Shuts down a hash table. + +
                        cuddHashTableInsert() +
                        Inserts an item in a hash table. + +
                        cuddHashTableLookup() +
                        Looks up a key in a hash table. + +
                        cuddHashTableInsert1() +
                        Inserts an item in a hash table. + +
                        cuddHashTableLookup1() +
                        Looks up a key consisting of one pointer in a hash table. + +
                        cuddHashTableGenericInsert() +
                        Inserts an item in a hash table. + +
                        cuddHashTableGenericLookup() +
                        Looks up a key consisting of one pointer in a hash table. + +
                        cuddHashTableInsert2() +
                        Inserts an item in a hash table. + +
                        cuddHashTableLookup2() +
                        Looks up a key consisting of two pointers in a hash table. + +
                        cuddHashTableInsert3() +
                        Inserts an item in a hash table. + +
                        cuddHashTableLookup3() +
                        Looks up a key consisting of three pointers in a hash table. + +
                        cuddLocalCacheResize() +
                        Resizes a local cache. + +
                        () +
                        Computes the hash value for a local cache. + +
                        cuddLocalCacheAddToList() +
                        Inserts a local cache in the manager list. + +
                        cuddLocalCacheRemoveFromList() +
                        Removes a local cache from the manager list. + +
                        cuddHashTableResize() +
                        Resizes a hash table. + +
                        () +
                        Fast storage allocation for items in a hash table. + +
                        +
                        +

                        cuddLevelQ.c

                        +Procedure to manage level queues.

                        +By: Fabio Somenzi

                        +The functions in this file allow an application to + easily manipulate a queue where nodes are prioritized by level. The + emphasis is on efficiency. Therefore, the queue items can have + variable size. If the application does not need to attach + information to the nodes, it can declare the queue items to be of + type DdQueueItem. Otherwise, it can declare them to be of a + structure type such that the first three fields are data + pointers. The third pointer points to the node. The first two + pointers are used by the level queue functions. The remaining fields + are initialized to 0 when a new item is created, and are then left + to the exclusive use of the application. On the DEC Alphas the three + pointers must be 32-bit pointers when CUDD is compiled with 32-bit + pointers. The level queue functions make sure that each node + appears at most once in the queue. They do so by keeping a hash + table where the node is used as key. Queue items are recycled via a + free list for efficiency. + + Internal procedures provided by this module: +

                          +
                        • cuddLevelQueueInit() +
                        • cuddLevelQueueQuit() +
                        • cuddLevelQueueEnqueue() +
                        • cuddLevelQueueDequeue() +
                        + Static procedures included in this module: +
                          +
                        • hashLookup() +
                        • hashInsert() +
                        • hashDelete() +
                        • hashResize() +

                        +

                        +
                        cuddLevelQueueInit() +
                        Initializes a level queue. + +
                        cuddLevelQueueQuit() +
                        Shuts down a level queue. + +
                        cuddLevelQueueEnqueue() +
                        Inserts a new key in a level queue. + +
                        cuddLevelQueueFirst() +
                        Inserts the first key in a level queue. + +
                        cuddLevelQueueDequeue() +
                        Remove an item from the front of a level queue. + +
                        hashLookup() +
                        Looks up a key in the hash table of a level queue. + +
                        hashInsert() +
                        Inserts an item in the hash table of a level queue. + +
                        hashDelete() +
                        Removes an item from the hash table of a level queue. + +
                        hashResize() +
                        Resizes the hash table of a level queue. + +
                        +
                        +

                        cuddLinear.c

                        +Functions for DD reduction by linear transformations.

                        +By: Fabio Somenzi

                        +Internal procedures included in this module: +

                          +
                        • cuddLinearAndSifting() +
                        • cuddLinearInPlace() +
                        • cuddUpdateInteractionMatrix() +
                        • cuddInitLinear() +
                        • cuddResizeLinear() +
                        + Static procedures included in this module: +
                          +
                        • ddLinearUniqueCompare() +
                        • ddLinearAndSiftingAux() +
                        • ddLinearAndSiftingUp() +
                        • ddLinearAndSiftingDown() +
                        • ddLinearAndSiftingBackward() +
                        • ddUndoMoves() +
                        • cuddXorLinear() +

                        +

                        +
                        Cudd_PrintLinear() +
                        Prints the linear transform matrix. + +
                        Cudd_ReadLinear() +
                        Reads an entry of the linear transform matrix. + +
                        cuddLinearAndSifting() +
                        BDD reduction based on combination of sifting and linear + transformations. + +
                        cuddLinearInPlace() +
                        Linearly combines two adjacent variables. + +
                        cuddUpdateInteractionMatrix() +
                        Updates the interaction matrix. + +
                        cuddInitLinear() +
                        Initializes the linear transform matrix. + +
                        cuddResizeLinear() +
                        Resizes the linear transform matrix. + +
                        ddLinearUniqueCompare() +
                        Comparison function used by qsort. + +
                        ddLinearAndSiftingAux() +
                        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                        ddLinearAndSiftingUp() +
                        Sifts a variable up and applies linear transformations. + +
                        ddLinearAndSiftingDown() +
                        Sifts a variable down and applies linear transformations. + +
                        ddLinearAndSiftingBackward() +
                        Given a set of moves, returns the DD heap to the order + giving the minimum size. + +
                        ddUndoMoves() +
                        Given a set of moves, returns the DD heap to the order + in effect before the moves. + +
                        cuddXorLinear() +
                        XORs two rows of the linear transform matrix. + +
                        +
                        +

                        cuddLiteral.c

                        +Functions for manipulation of literal sets represented by + BDDs.

                        +By: Fabio Somenzi

                        +External procedures included in this file: +

                          +
                        • Cudd_bddLiteralSetIntersection() +
                        + Internal procedures included in this file: +
                          +
                        • cuddBddLiteralSetIntersectionRecur() +

                        +

                        +
                        Cudd_bddLiteralSetIntersection() +
                        Computes the intesection of two sets of literals + represented as BDDs. + +
                        cuddBddLiteralSetIntersectionRecur() +
                        Performs the recursive step of + Cudd_bddLiteralSetIntersection. + +
                        +
                        +

                        cuddMatMult.c

                        +Matrix multiplication functions.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_addMatrixMultiply() +
                        • Cudd_addTimesPlus() +
                        • Cudd_addTriangle() +
                        • Cudd_addOuterSum() +
                        + Static procedures included in this module: +
                          +
                        • addMMRecur() +
                        • addTriangleRecur() +
                        • cuddAddOuterSumRecur() +

                        +

                        +
                        Cudd_addMatrixMultiply() +
                        Calculates the product of two matrices represented as + ADDs. + +
                        Cudd_addTimesPlus() +
                        Calculates the product of two matrices represented as + ADDs. + +
                        Cudd_addTriangle() +
                        Performs the triangulation step for the shortest path + computation. + +
                        Cudd_addOuterSum() +
                        Takes the minimum of a matrix and the outer sum of two vectors. + +
                        addMMRecur() +
                        Performs the recursive step of Cudd_addMatrixMultiply. + +
                        addTriangleRecur() +
                        Performs the recursive step of Cudd_addTriangle. + +
                        cuddAddOuterSumRecur() +
                        Performs the recursive step of Cudd_addOuterSum. + +
                        +
                        +

                        cuddPriority.c

                        +Priority functions.

                        +By: Fabio Somenzi

                        +External procedures included in this file: +

                          +
                        • Cudd_PrioritySelect() +
                        • Cudd_Xgty() +
                        • Cudd_Xeqy() +
                        • Cudd_addXeqy() +
                        • Cudd_Dxygtdxz() +
                        • Cudd_Dxygtdyz() +
                        • Cudd_Inequality() +
                        • Cudd_Disequality() +
                        • Cudd_bddInterval() +
                        • Cudd_CProjection() +
                        • Cudd_addHamming() +
                        • Cudd_MinHammingDist() +
                        • Cudd_bddClosestCube() +
                        + Internal procedures included in this module: +
                          +
                        • cuddCProjectionRecur() +
                        • cuddBddClosestCube() +
                        + Static procedures included in this module: +
                          +
                        • cuddMinHammingDistRecur() +
                        • separateCube() +
                        • createResult() +

                        +

                        +
                        Cudd_PrioritySelect() +
                        Selects pairs from R using a priority function. + +
                        Cudd_Xgty() +
                        Generates a BDD for the function x > y. + +
                        Cudd_Xeqy() +
                        Generates a BDD for the function x==y. + +
                        Cudd_addXeqy() +
                        Generates an ADD for the function x==y. + +
                        Cudd_Dxygtdxz() +
                        Generates a BDD for the function d(x,y) > d(x,z). + +
                        Cudd_Dxygtdyz() +
                        Generates a BDD for the function d(x,y) > d(y,z). + +
                        Cudd_Inequality() +
                        Generates a BDD for the function x - y ≥ c. + +
                        Cudd_Disequality() +
                        Generates a BDD for the function x - y != c. + +
                        Cudd_bddInterval() +
                        Generates a BDD for the function lowerB ≤ x ≤ upperB. + +
                        Cudd_CProjection() +
                        Computes the compatible projection of R w.r.t. cube Y. + +
                        Cudd_addHamming() +
                        Computes the Hamming distance ADD. + +
                        Cudd_MinHammingDist() +
                        Returns the minimum Hamming distance between f and minterm. + +
                        Cudd_bddClosestCube() +
                        Finds a cube of f at minimum Hamming distance from g. + +
                        cuddCProjectionRecur() +
                        Performs the recursive step of Cudd_CProjection. + +
                        cuddBddClosestCube() +
                        Performs the recursive step of Cudd_bddClosestCube. + +
                        cuddMinHammingDistRecur() +
                        Performs the recursive step of Cudd_MinHammingDist. + +
                        separateCube() +
                        Separates cube from distance. + +
                        createResult() +
                        Builds a result for cache storage. + +
                        +
                        +

                        cuddRead.c

                        +Functions to read in a matrix

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_addRead() +
                        • Cudd_bddRead() +

                        +

                        See Alsocudd_addHarwell.c +

                        +
                        Cudd_addRead() +
                        Reads in a sparse matrix. + +
                        Cudd_bddRead() +
                        Reads in a graph (without labels) given as a list of arcs. + +
                        +
                        +

                        cuddRef.c

                        +Functions that manipulate the reference counts.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_Ref() +
                        • Cudd_RecursiveDeref() +
                        • Cudd_IterDerefBdd() +
                        • Cudd_DelayedDerefBdd() +
                        • Cudd_RecursiveDerefZdd() +
                        • Cudd_Deref() +
                        • Cudd_CheckZeroRef() +
                        + Internal procedures included in this module: +
                          +
                        • cuddReclaim() +
                        • cuddReclaimZdd() +
                        • cuddClearDeathRow() +
                        • cuddShrinkDeathRow() +
                        • cuddIsInDeathRow() +
                        • cuddTimesInDeathRow() +

                        +

                        +
                        Cudd_Ref() +
                        Increases the reference count of a node, if it is not + saturated. + +
                        Cudd_RecursiveDeref() +
                        Decreases the reference count of node n. + +
                        Cudd_IterDerefBdd() +
                        Decreases the reference count of BDD node n. + +
                        Cudd_DelayedDerefBdd() +
                        Decreases the reference count of BDD node n. + +
                        Cudd_RecursiveDerefZdd() +
                        Decreases the reference count of ZDD node n. + +
                        Cudd_Deref() +
                        Decreases the reference count of node. + +
                        Cudd_CheckZeroRef() +
                        Checks the unique table for nodes with non-zero reference + counts. + +
                        cuddReclaim() +
                        Brings children of a dead node back. + +
                        cuddReclaimZdd() +
                        Brings children of a dead ZDD node back. + +
                        cuddShrinkDeathRow() +
                        Shrinks the death row. + +
                        cuddClearDeathRow() +
                        Clears the death row. + +
                        cuddIsInDeathRow() +
                        Checks whether a node is in the death row. + +
                        cuddTimesInDeathRow() +
                        Counts how many times a node is in the death row. + +
                        +
                        +

                        cuddReorder.c

                        +Functions for dynamic variable reordering.

                        +By: Shipra Panda, Bernard Plessier, Fabio Somenzi

                        +External procedures included in this file: +

                          +
                        • Cudd_ReduceHeap() +
                        • Cudd_ShuffleHeap() +
                        + Internal procedures included in this module: +
                          +
                        • cuddDynamicAllocNode() +
                        • cuddSifting() +
                        • cuddSwapping() +
                        • cuddNextHigh() +
                        • cuddNextLow() +
                        • cuddSwapInPlace() +
                        • cuddBddAlignToZdd() +
                        + Static procedures included in this module: +
                          +
                        • ddUniqueCompare() +
                        • ddSwapAny() +
                        • ddSiftingAux() +
                        • ddSiftingUp() +
                        • ddSiftingDown() +
                        • ddSiftingBackward() +
                        • ddReorderPreprocess() +
                        • ddReorderPostprocess() +
                        • ddShuffle() +
                        • ddSiftUp() +
                        • bddFixTree() +

                        +

                        +
                        Cudd_ReduceHeap() +
                        Main dynamic reordering routine. + +
                        Cudd_ShuffleHeap() +
                        Reorders variables according to given permutation. + +
                        cuddDynamicAllocNode() +
                        Dynamically allocates a Node. + +
                        cuddSifting() +
                        Implementation of Rudell's sifting algorithm. + +
                        cuddSwapping() +
                        Reorders variables by a sequence of (non-adjacent) swaps. + +
                        cuddNextHigh() +
                        Finds the next subtable with a larger index. + +
                        cuddNextLow() +
                        Finds the next subtable with a smaller index. + +
                        cuddSwapInPlace() +
                        Swaps two adjacent variables. + +
                        cuddBddAlignToZdd() +
                        Reorders BDD variables according to the order of the ZDD + variables. + +
                        ddUniqueCompare() +
                        Comparison function used by qsort. + +
                        ddSwapAny() +
                        Swaps any two variables. + +
                        ddSiftingAux() +
                        Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                        ddSiftingUp() +
                        Sifts a variable up. + +
                        ddSiftingDown() +
                        Sifts a variable down. + +
                        ddSiftingBackward() +
                        Given a set of moves, returns the DD heap to the position + giving the minimum size. + +
                        ddReorderPreprocess() +
                        Prepares the DD heap for dynamic reordering. + +
                        ddReorderPostprocess() +
                        Cleans up at the end of reordering. + +
                        ddShuffle() +
                        Reorders variables according to a given permutation. + +
                        ddSiftUp() +
                        Moves one variable up. + +
                        bddFixTree() +
                        Fixes the BDD variable group tree after a shuffle. + +
                        ddUpdateMtrTree() +
                        Updates the BDD variable group tree before a shuffle. + +
                        ddCheckPermuation() +
                        Checks the BDD variable group tree before a shuffle. + +
                        +
                        +

                        cuddSat.c

                        +Functions for the solution of satisfiability related problems.

                        +By: Seh-Woong Jeong, Fabio Somenzi

                        +External procedures included in this file: +

                          +
                        • Cudd_Eval() +
                        • Cudd_ShortestPath() +
                        • Cudd_LargestCube() +
                        • Cudd_ShortestLength() +
                        • Cudd_Decreasing() +
                        • Cudd_Increasing() +
                        • Cudd_EquivDC() +
                        • Cudd_bddLeqUnless() +
                        • Cudd_EqualSupNorm() +
                        • Cudd_bddMakePrime() +
                        • Cudd_bddMaximallyExpand() +
                        • Cudd_bddLargestPrimeUnate() +
                        + Internal procedures included in this module: +
                          +
                        • cuddBddMakePrime() +
                        + Static procedures included in this module: +
                          +
                        • freePathPair() +
                        • getShortest() +
                        • getPath() +
                        • getLargest() +
                        • getCube() +
                        • ddBddMaximallyExpand() +
                        • ddShortestPathUnate() +

                        +

                        +
                        Cudd_Eval() +
                        Returns the value of a DD for a given variable assignment. + +
                        Cudd_ShortestPath() +
                        Finds a shortest path in a DD. + +
                        Cudd_LargestCube() +
                        Finds a largest cube in a DD. + +
                        Cudd_ShortestLength() +
                        Find the length of the shortest path(s) in a DD. + +
                        Cudd_Decreasing() +
                        Determines whether a BDD is negative unate in a + variable. + +
                        Cudd_Increasing() +
                        Determines whether a BDD is positive unate in a + variable. + +
                        Cudd_EquivDC() +
                        Tells whether F and G are identical wherever D is 0. + +
                        Cudd_bddLeqUnless() +
                        Tells whether f is less than of equal to G unless D is 1. + +
                        Cudd_EqualSupNorm() +
                        Compares two ADDs for equality within tolerance. + +
                        Cudd_bddMakePrime() +
                        Expands cube to a prime implicant of f. + +
                        Cudd_bddMaximallyExpand() +
                        Expands lb to prime implicants of (f and ub). + +
                        Cudd_bddLargestPrimeUnate() +
                        Find a largest prime of a unate function. + +
                        cuddBddMakePrime() +
                        Performs the recursive step of Cudd_bddMakePrime. + +
                        freePathPair() +
                        Frees the entries of the visited symbol table. + +
                        getShortest() +
                        Finds the length of the shortest path(s) in a DD. + +
                        getPath() +
                        Build a BDD for a shortest path of f. + +
                        getLargest() +
                        Finds the size of the largest cube(s) in a DD. + +
                        getCube() +
                        Build a BDD for a largest cube of f. + +
                        ddBddMaximallyExpand() +
                        Performs the recursive step of Cudd_bddMaximallyExpand. + +
                        ddBddShortestPathUnate() +
                        Performs shortest path computation on a unate function. + +
                        ddGetLargestCubeUnate() +
                        Extracts largest prime of a unate function. + +
                        +
                        +

                        cuddSign.c

                        +Computation of signatures.

                        +By: Fabio Somenzi

                        +External procedures included in this module: +

                          +
                        • Cudd_CofMinterm(); +
                        + Static procedures included in this module: +
                          +
                        • ddCofMintermAux() +

                        +

                        +
                        Cudd_CofMinterm() +
                        Computes the fraction of minterms in the on-set of all the + positive cofactors of a BDD or ADD. + +
                        ddCofMintermAux() +
                        Recursive Step for Cudd_CofMinterm function. + +
                        +
                        +

                        cuddSolve.c

                        +Boolean equation solver and related functions.

                        +By: Balakrishna Kumthekar

                        +External functions included in this modoule: +

                          +
                        • Cudd_SolveEqn() +
                        • Cudd_VerifySol() +
                        + Internal functions included in this module: +
                          +
                        • cuddSolveEqnRecur() +
                        • cuddVerifySol() +

                        +

                        +
                        Cudd_SolveEqn() +
                        Implements the solution of F(x,y) = 0. + +
                        Cudd_VerifySol() +
                        Checks the solution of F(x,y) = 0. + +
                        cuddSolveEqnRecur() +
                        Implements the recursive step of Cudd_SolveEqn. + +
                        cuddVerifySol() +
                        Implements the recursive step of Cudd_VerifySol. + +
                        +
                        +

                        cuddSplit.c

                        +Returns a subset of minterms from a boolean function.

                        +By: Balakrishna Kumthekar

                        +External functions included in this modoule: +

                          +
                        • Cudd_SplitSet() +
                        + Internal functions included in this module: +
                          +
                        • cuddSplitSetRecur() + + Static functions included in this module: +
                            +
                          • selectMintermsFromUniverse() +
                          • mintermsFromUniverse() +
                          • bddAnnotateMintermCount() +

                          +

                          +
                          Cudd_SplitSet() +
                          Returns m minterms from a BDD. + +
                          cuddSplitSetRecur() +
                          Implements the recursive step of Cudd_SplitSet. + +
                          selectMintermsFromUniverse() +
                          This function prepares an array of variables which have not been + encountered so far when traversing the procedure cuddSplitSetRecur. + +
                          mintermsFromUniverse() +
                          Recursive procedure to extract n mintems from constant 1. + +
                          bddAnnotateMintermCount() +
                          Annotates every node in the BDD node with its minterm count. + +
                          +
                          +

                          cuddSubsetHB.c

                          +Procedure to subset the given BDD by choosing the heavier + branches.

                          +By: Kavita Ravi

                          +External procedures provided by this module: +

                            +
                          • Cudd_SubsetHeavyBranch() +
                          • Cudd_SupersetHeavyBranch() +
                          + Internal procedures included in this module: +
                            +
                          • cuddSubsetHeavyBranch() +
                          + Static procedures included in this module: +
                            +
                          • ResizeCountMintermPages(); +
                          • ResizeNodeDataPages() +
                          • ResizeCountNodePages() +
                          • SubsetCountMintermAux() +
                          • SubsetCountMinterm() +
                          • SubsetCountNodesAux() +
                          • SubsetCountNodes() +
                          • BuildSubsetBdd() +

                          +

                          See AlsocuddSubsetSP.c +

                          +
                          Cudd_SubsetHeavyBranch() +
                          Extracts a dense subset from a BDD with the heavy branch + heuristic. + +
                          Cudd_SupersetHeavyBranch() +
                          Extracts a dense superset from a BDD with the heavy branch + heuristic. + +
                          cuddSubsetHeavyBranch() +
                          The main procedure that returns a subset by choosing the heavier + branch in the BDD. + +
                          ResizeNodeDataPages() +
                          Resize the number of pages allocated to store the node data. + +
                          ResizeCountMintermPages() +
                          Resize the number of pages allocated to store the minterm + counts. + +
                          ResizeCountNodePages() +
                          Resize the number of pages allocated to store the node counts. + +
                          SubsetCountMintermAux() +
                          Recursively counts minterms of each node in the DAG. + +
                          SubsetCountMinterm() +
                          Counts minterms of each node in the DAG + +
                          SubsetCountNodesAux() +
                          Recursively counts the number of nodes under the dag. + Also counts the number of nodes under the lighter child of + this node. + +
                          SubsetCountNodes() +
                          Counts the nodes under the current node and its lighter child + +
                          StoreNodes() +
                          Procedure to recursively store nodes that are retained in the subset. + +
                          BuildSubsetBdd() +
                          Builds the subset BDD using the heavy branch method. + +
                          +
                          +

                          cuddSubsetSP.c

                          +Procedure to subset the given BDD choosing the shortest paths + (largest cubes) in the BDD.

                          +By: Kavita Ravi

                          +External procedures included in this module: +

                            +
                          • Cudd_SubsetShortPaths() +
                          • Cudd_SupersetShortPaths() +
                          + Internal procedures included in this module: +
                            +
                          • cuddSubsetShortPaths() +
                          + Static procedures included in this module: +
                            +
                          • BuildSubsetBdd() +
                          • CreatePathTable() +
                          • AssessPathLength() +
                          • CreateTopDist() +
                          • CreateBotDist() +
                          • ResizeNodeDistPages() +
                          • ResizeQueuePages() +
                          • stPathTableDdFree() +

                          +

                          See AlsocuddSubsetHB.c +

                          +
                          Cudd_SubsetShortPaths() +
                          Extracts a dense subset from a BDD with the shortest paths + heuristic. + +
                          Cudd_SupersetShortPaths() +
                          Extracts a dense superset from a BDD with the shortest paths + heuristic. + +
                          cuddSubsetShortPaths() +
                          The outermost procedure to return a subset of the given BDD + with the shortest path lengths. + +
                          ResizeNodeDistPages() +
                          Resize the number of pages allocated to store the distances + related to each node. + +
                          ResizeQueuePages() +
                          Resize the number of pages allocated to store nodes in the BFS + traversal of the Bdd . + +
                          CreateTopDist() +
                          Labels each node with its shortest distance from the root + +
                          CreateBotDist() +
                          Labels each node with the shortest distance from the constant. + +
                          CreatePathTable() +
                          The outer procedure to label each node with its shortest + distance from the root and constant + +
                          AssessPathLength() +
                          Chooses the maximum allowable path length of nodes under the + threshold. + +
                          BuildSubsetBdd() +
                          Builds the BDD with nodes labeled with path length less than or equal to maxpath + +
                          stPathTableDdFree() +
                          Procedure to free te result dds stored in the NodeDist pages. + +
                          +
                          +

                          cuddSymmetry.c

                          +Functions for symmetry-based variable reordering.

                          +By: Shipra Panda, Fabio Somenzi

                          +External procedures included in this file: +

                            +
                          • Cudd_SymmProfile() +
                          + Internal procedures included in this module: +
                            +
                          • cuddSymmCheck() +
                          • cuddSymmSifting() +
                          • cuddSymmSiftingConv() +
                          + Static procedures included in this module: +
                            +
                          • ddSymmUniqueCompare() +
                          • ddSymmSiftingAux() +
                          • ddSymmSiftingConvAux() +
                          • ddSymmSiftingUp() +
                          • ddSymmSiftingDown() +
                          • ddSymmGroupMove() +
                          • ddSymmGroupMoveBackward() +
                          • ddSymmSiftingBackward() +
                          • ddSymmSummary() +

                          +

                          +
                          Cudd_SymmProfile() +
                          Prints statistics on symmetric variables. + +
                          cuddSymmCheck() +
                          Checks for symmetry of x and y. + +
                          cuddSymmSifting() +
                          Symmetric sifting algorithm. + +
                          cuddSymmSiftingConv() +
                          Symmetric sifting to convergence algorithm. + +
                          ddSymmUniqueCompare() +
                          Comparison function used by qsort. + +
                          ddSymmSiftingAux() +
                          Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                          ddSymmSiftingConvAux() +
                          Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                          ddSymmSiftingUp() +
                          Moves x up until either it reaches the bound (xLow) or + the size of the DD heap increases too much. + +
                          ddSymmSiftingDown() +
                          Moves x down until either it reaches the bound (xHigh) or + the size of the DD heap increases too much. + +
                          ddSymmGroupMove() +
                          Swaps two groups. + +
                          ddSymmGroupMoveBackward() +
                          Undoes the swap of two groups. + +
                          ddSymmSiftingBackward() +
                          Given a set of moves, returns the DD heap to the position + giving the minimum size. + +
                          ddSymmSummary() +
                          Counts numbers of symmetric variables and symmetry + groups. + +
                          +
                          +

                          cuddTable.c

                          +Unique table management functions.

                          +By: Fabio Somenzi

                          +External procedures included in this module: +

                            +
                          • Cudd_Prime() +
                          • Cudd_Reserve() +
                          + Internal procedures included in this module: +
                            +
                          • cuddAllocNode() +
                          • cuddInitTable() +
                          • cuddFreeTable() +
                          • cuddGarbageCollect() +
                          • cuddZddGetNode() +
                          • cuddZddGetNodeIVO() +
                          • cuddUniqueInter() +
                          • cuddUniqueInterIVO() +
                          • cuddUniqueInterZdd() +
                          • cuddUniqueConst() +
                          • cuddRehash() +
                          • cuddShrinkSubtable() +
                          • cuddInsertSubtables() +
                          • cuddDestroySubtables() +
                          • cuddResizeTableZdd() +
                          • cuddSlowTableGrowth() +
                          + Static procedures included in this module: +
                            +
                          • ddRehashZdd() +
                          • ddResizeTable() +
                          • cuddFindParent() +
                          • cuddOrderedInsert() +
                          • cuddOrderedThread() +
                          • cuddRotateLeft() +
                          • cuddRotateRight() +
                          • cuddDoRebalance() +
                          • cuddCheckCollisionOrdering() +

                          +

                          +
                          Cudd_Prime() +
                          Returns the next prime >= p. + +
                          Cudd_Reserve() +
                          Expand manager without creating variables. + +
                          cuddAllocNode() +
                          Fast storage allocation for DdNodes in the table. + +
                          cuddInitTable() +
                          Creates and initializes the unique table. + +
                          cuddFreeTable() +
                          Frees the resources associated to a unique table. + +
                          cuddGarbageCollect() +
                          Performs garbage collection on the unique tables. + +
                          cuddZddGetNode() +
                          Wrapper for cuddUniqueInterZdd. + +
                          cuddZddGetNodeIVO() +
                          Wrapper for cuddUniqueInterZdd that is independent of variable + ordering. + +
                          cuddUniqueInter() +
                          Checks the unique table for the existence of an internal node. + +
                          cuddUniqueInterIVO() +
                          Wrapper for cuddUniqueInter that is independent of variable + ordering. + +
                          cuddUniqueInterZdd() +
                          Checks the unique table for the existence of an internal + ZDD node. + +
                          cuddUniqueConst() +
                          Checks the unique table for the existence of a constant node. + +
                          cuddRehash() +
                          Rehashes a unique subtable. + +
                          cuddShrinkSubtable() +
                          Shrinks a subtable. + +
                          cuddInsertSubtables() +
                          Inserts n new subtables in a unique table at level. + +
                          cuddDestroySubtables() +
                          Destroys the n most recently created subtables in a unique table. + +
                          cuddResizeTableZdd() +
                          Increases the number of ZDD subtables in a unique table so + that it meets or exceeds index. + +
                          cuddSlowTableGrowth() +
                          Adjusts parameters of a table to slow down its growth. + +
                          ddRehashZdd() +
                          Rehashes a ZDD unique subtable. + +
                          ddResizeTable() +
                          Increases the number of subtables in a unique table so + that it meets or exceeds index. + +
                          cuddFindParent() +
                          Searches the subtables above node for a parent. + +
                          () +
                          Adjusts the values of table limits. + +
                          cuddOrderedInsert() +
                          Inserts a DdNode in a red/black search tree. + +
                          cuddOrderedThread() +
                          Threads all the nodes of a search tree into a linear list. + +
                          () +
                          Performs the left rotation for red/black trees. + +
                          () +
                          Performs the right rotation for red/black trees. + +
                          cuddDoRebalance() +
                          Rebalances a red/black tree. + +
                          ddPatchTree() +
                          Fixes a variable tree after the insertion of new subtables. + +
                          cuddCheckCollisionOrdering() +
                          Checks whether a collision list is ordered. + +
                          ddReportRefMess() +
                          Reports problem in garbage collection. + +
                          +
                          +

                          cuddUtil.c

                          +Utility functions.

                          +By: Fabio Somenzi

                          +External procedures included in this module: +

                            +
                          • Cudd_PrintMinterm() +
                          • Cudd_bddPrintCover() +
                          • Cudd_PrintDebug() +
                          • Cudd_DagSize() +
                          • Cudd_EstimateCofactor() +
                          • Cudd_EstimateCofactorSimple() +
                          • Cudd_SharingSize() +
                          • Cudd_CountMinterm() +
                          • Cudd_EpdCountMinterm() +
                          • Cudd_CountPath() +
                          • Cudd_CountPathsToNonZero() +
                          • Cudd_SupportIndices() +
                          • Cudd_Support() +
                          • Cudd_SupportIndex() +
                          • Cudd_SupportSize() +
                          • Cudd_VectorSupportIndices() +
                          • Cudd_VectorSupport() +
                          • Cudd_VectorSupportIndex() +
                          • Cudd_VectorSupportSize() +
                          • Cudd_ClassifySupport() +
                          • Cudd_CountLeaves() +
                          • Cudd_bddPickOneCube() +
                          • Cudd_bddPickOneMinterm() +
                          • Cudd_bddPickArbitraryMinterms() +
                          • Cudd_SubsetWithMaskVars() +
                          • Cudd_FirstCube() +
                          • Cudd_NextCube() +
                          • Cudd_bddComputeCube() +
                          • Cudd_addComputeCube() +
                          • Cudd_FirstNode() +
                          • Cudd_NextNode() +
                          • Cudd_GenFree() +
                          • Cudd_IsGenEmpty() +
                          • Cudd_IndicesToCube() +
                          • Cudd_PrintVersion() +
                          • Cudd_AverageDistance() +
                          • Cudd_Random() +
                          • Cudd_Srandom() +
                          • Cudd_Density() +
                          + Internal procedures included in this module: +
                            +
                          • cuddP() +
                          • cuddStCountfree() +
                          • cuddCollectNodes() +
                          • cuddNodeArray() +
                          + Static procedures included in this module: +
                            +
                          • dp2() +
                          • ddPrintMintermAux() +
                          • ddDagInt() +
                          • ddCountMintermAux() +
                          • ddEpdCountMintermAux() +
                          • ddCountPathAux() +
                          • ddSupportStep() +
                          • ddClearFlag() +
                          • ddLeavesInt() +
                          • ddPickArbitraryMinterms() +
                          • ddPickRepresentativeCube() +
                          • ddEpdFree() +
                          • ddFindSupport() +
                          • ddClearVars() +
                          • indexCompare() +

                          +

                          +
                          Cudd_PrintMinterm() +
                          Prints a disjoint sum of products. + +
                          Cudd_bddPrintCover() +
                          Prints a sum of prime implicants of a BDD. + +
                          Cudd_PrintDebug() +
                          Prints to the standard output a DD and its statistics. + +
                          Cudd_DagSize() +
                          Counts the number of nodes in a DD. + +
                          Cudd_EstimateCofactor() +
                          Estimates the number of nodes in a cofactor of a DD. + +
                          Cudd_EstimateCofactorSimple() +
                          Estimates the number of nodes in a cofactor of a DD. + +
                          Cudd_SharingSize() +
                          Counts the number of nodes in an array of DDs. + +
                          Cudd_CountMinterm() +
                          Counts the number of minterms of a DD. + +
                          Cudd_CountPath() +
                          Counts the number of paths of a DD. + +
                          Cudd_EpdCountMinterm() +
                          Counts the number of minterms of a DD with extended precision. + +
                          Cudd_CountPathsToNonZero() +
                          Counts the number of paths to a non-zero terminal of a DD. + +
                          Cudd_SupportIndices() +
                          Finds the variables on which a DD depends. + +
                          Cudd_Support() +
                          Finds the variables on which a DD depends. + +
                          Cudd_SupportIndex() +
                          Finds the variables on which a DD depends. + +
                          Cudd_SupportSize() +
                          Counts the variables on which a DD depends. + +
                          Cudd_VectorSupportIndices() +
                          Finds the variables on which a set of DDs depends. + +
                          Cudd_VectorSupport() +
                          Finds the variables on which a set of DDs depends. + +
                          Cudd_VectorSupportIndex() +
                          Finds the variables on which a set of DDs depends. + +
                          Cudd_VectorSupportSize() +
                          Counts the variables on which a set of DDs depends. + +
                          Cudd_ClassifySupport() +
                          Classifies the variables in the support of two DDs. + +
                          Cudd_CountLeaves() +
                          Counts the number of leaves in a DD. + +
                          Cudd_bddPickOneCube() +
                          Picks one on-set cube randomly from the given DD. + +
                          Cudd_bddPickOneMinterm() +
                          Picks one on-set minterm randomly from the given DD. + +
                          Cudd_bddPickArbitraryMinterms() +
                          Picks k on-set minterms evenly distributed from given DD. + +
                          Cudd_SubsetWithMaskVars() +
                          Extracts a subset from a BDD. + +
                          Cudd_FirstCube() +
                          Finds the first cube of a decision diagram. + +
                          Cudd_NextCube() +
                          Generates the next cube of a decision diagram onset. + +
                          Cudd_FirstPrime() +
                          Finds the first prime of a Boolean function. + +
                          Cudd_NextPrime() +
                          Generates the next prime of a Boolean function. + +
                          Cudd_bddComputeCube() +
                          Computes the cube of an array of BDD variables. + +
                          Cudd_addComputeCube() +
                          Computes the cube of an array of ADD variables. + +
                          Cudd_CubeArrayToBdd() +
                          Builds the BDD of a cube from a positional array. + +
                          Cudd_BddToCubeArray() +
                          Builds a positional array from the BDD of a cube. + +
                          Cudd_FirstNode() +
                          Finds the first node of a decision diagram. + +
                          Cudd_NextNode() +
                          Finds the next node of a decision diagram. + +
                          Cudd_GenFree() +
                          Frees a CUDD generator. + +
                          Cudd_IsGenEmpty() +
                          Queries the status of a generator. + +
                          Cudd_IndicesToCube() +
                          Builds a cube of BDD variables from an array of indices. + +
                          Cudd_PrintVersion() +
                          Prints the package version number. + +
                          Cudd_AverageDistance() +
                          Computes the average distance between adjacent nodes. + +
                          Cudd_Random() +
                          Portable random number generator. + +
                          Cudd_Srandom() +
                          Initializer for the portable random number generator. + +
                          Cudd_Density() +
                          Computes the density of a BDD or ADD. + +
                          Cudd_OutOfMem() +
                          Warns that a memory allocation failed. + +
                          cuddP() +
                          Prints a DD to the standard output. One line per node is + printed. + +
                          cuddStCountfree() +
                          Frees the memory used to store the minterm counts recorded + in the visited table. + +
                          cuddCollectNodes() +
                          Recursively collects all the nodes of a DD in a symbol + table. + +
                          cuddNodeArray() +
                          Recursively collects all the nodes of a DD in an array. + +
                          dp2() +
                          Performs the recursive step of cuddP. + +
                          ddPrintMintermAux() +
                          Performs the recursive step of Cudd_PrintMinterm. + +
                          ddDagInt() +
                          Performs the recursive step of Cudd_DagSize. + +
                          cuddNodeArrayRecur() +
                          Performs the recursive step of cuddNodeArray. + +
                          cuddEstimateCofactor() +
                          Performs the recursive step of Cudd_CofactorEstimate. + +
                          cuddUniqueLookup() +
                          Checks the unique table for the existence of an internal node. + +
                          cuddEstimateCofactorSimple() +
                          Performs the recursive step of Cudd_CofactorEstimateSimple. + +
                          ddCountMintermAux() +
                          Performs the recursive step of Cudd_CountMinterm. + +
                          ddCountPathAux() +
                          Performs the recursive step of Cudd_CountPath. + +
                          ddEpdCountMintermAux() +
                          Performs the recursive step of Cudd_EpdCountMinterm. + +
                          ddCountPathsToNonZero() +
                          Performs the recursive step of Cudd_CountPathsToNonZero. + +
                          ddSupportStep() +
                          Performs the recursive step of Cudd_Support. + +
                          ddClearFlag() +
                          Performs a DFS from f, clearing the LSB of the next + pointers. + +
                          ddLeavesInt() +
                          Performs the recursive step of Cudd_CountLeaves. + +
                          ddPickArbitraryMinterms() +
                          Performs the recursive step of Cudd_bddPickArbitraryMinterms. + +
                          ddPickRepresentativeCube() +
                          Finds a representative cube of a BDD. + +
                          ddEpdFree() +
                          Frees the memory used to store the minterm counts recorded + in the visited table. + +
                          ddFindSupport() +
                          Recursively find the support of f. + +
                          ddClearVars() +
                          Clears visited flags for variables. + +
                          indexCompare() +
                          Compares indices for qsort. + +
                          +
                          +

                          cuddWindow.c

                          +Functions for variable reordering by window permutation.

                          +By: Fabio Somenzi

                          +Internal procedures included in this module: +

                            +
                          • cuddWindowReorder() +
                          + Static procedures included in this module: +
                            +
                          • ddWindow2() +
                          • ddWindowConv2() +
                          • ddPermuteWindow3() +
                          • ddWindow3() +
                          • ddWindowConv3() +
                          • ddPermuteWindow4() +
                          • ddWindow4() +
                          • ddWindowConv4() +

                          +

                          +
                          cuddWindowReorder() +
                          Reorders by applying the method of the sliding window. + +
                          ddWindow2() +
                          Reorders by applying a sliding window of width 2. + +
                          ddWindowConv2() +
                          Reorders by repeatedly applying a sliding window of width 2. + +
                          ddPermuteWindow3() +
                          Tries all the permutations of the three variables between + x and x+2 and retains the best. + +
                          ddWindow3() +
                          Reorders by applying a sliding window of width 3. + +
                          ddWindowConv3() +
                          Reorders by repeatedly applying a sliding window of width 3. + +
                          ddPermuteWindow4() +
                          Tries all the permutations of the four variables between w + and w+3 and retains the best. + +
                          ddWindow4() +
                          Reorders by applying a sliding window of width 4. + +
                          ddWindowConv4() +
                          Reorders by repeatedly applying a sliding window of width 4. + +
                          +
                          +

                          cuddZddCount.c

                          +Procedures to count the number of minterms of a ZDD.

                          +By: Hyong-Kyoon Shin, In-Ho Moon

                          +External procedures included in this module: +

                            +
                          • Cudd_zddCount(); +
                          • Cudd_zddCountDouble(); +
                          + Internal procedures included in this module: +
                            +
                          + Static procedures included in this module: +
                            +
                          • cuddZddCountStep(); +
                          • cuddZddCountDoubleStep(); +
                          • st_zdd_count_dbl_free() +
                          • st_zdd_countfree() +

                          +

                          +
                          Cudd_zddCount() +
                          Counts the number of minterms in a ZDD. + +
                          Cudd_zddCountDouble() +
                          Counts the number of minterms of a ZDD. + +
                          cuddZddCountStep() +
                          Performs the recursive step of Cudd_zddCount. + +
                          cuddZddCountDoubleStep() +
                          Performs the recursive step of Cudd_zddCountDouble. + +
                          st_zdd_countfree() +
                          Frees the memory associated with the computed table of + Cudd_zddCount. + +
                          st_zdd_count_dbl_free() +
                          Frees the memory associated with the computed table of + Cudd_zddCountDouble. + +
                          +
                          +

                          cuddZddFuncs.c

                          +Functions to manipulate covers represented as ZDDs.

                          +By: In-Ho Moon

                          +External procedures included in this module: +

                            +
                          • Cudd_zddProduct(); +
                          • Cudd_zddUnateProduct(); +
                          • Cudd_zddWeakDiv(); +
                          • Cudd_zddWeakDivF(); +
                          • Cudd_zddDivide(); +
                          • Cudd_zddDivideF(); +
                          • Cudd_zddComplement(); +
                          + Internal procedures included in this module: +
                            +
                          • cuddZddProduct(); +
                          • cuddZddUnateProduct(); +
                          • cuddZddWeakDiv(); +
                          • cuddZddWeakDivF(); +
                          • cuddZddDivide(); +
                          • cuddZddDivideF(); +
                          • cuddZddGetCofactors3() +
                          • cuddZddGetCofactors2() +
                          • cuddZddComplement(); +
                          • cuddZddGetPosVarIndex(); +
                          • cuddZddGetNegVarIndex(); +
                          • cuddZddGetPosVarLevel(); +
                          • cuddZddGetNegVarLevel(); +
                          + Static procedures included in this module: +
                            +

                          +

                          +
                          Cudd_zddProduct() +
                          Computes the product of two covers represented by ZDDs. + +
                          Cudd_zddUnateProduct() +
                          Computes the product of two unate covers. + +
                          Cudd_zddWeakDiv() +
                          Applies weak division to two covers. + +
                          Cudd_zddDivide() +
                          Computes the quotient of two unate covers. + +
                          Cudd_zddWeakDivF() +
                          Modified version of Cudd_zddWeakDiv. + +
                          Cudd_zddDivideF() +
                          Modified version of Cudd_zddDivide. + +
                          Cudd_zddComplement() +
                          Computes a complement cover for a ZDD node. + +
                          cuddZddProduct() +
                          Performs the recursive step of Cudd_zddProduct. + +
                          cuddZddUnateProduct() +
                          Performs the recursive step of Cudd_zddUnateProduct. + +
                          cuddZddWeakDiv() +
                          Performs the recursive step of Cudd_zddWeakDiv. + +
                          cuddZddWeakDivF() +
                          Performs the recursive step of Cudd_zddWeakDivF. + +
                          cuddZddDivide() +
                          Performs the recursive step of Cudd_zddDivide. + +
                          cuddZddDivideF() +
                          Performs the recursive step of Cudd_zddDivideF. + +
                          cuddZddGetCofactors3() +
                          Computes the three-way decomposition of f w.r.t. v. + +
                          cuddZddGetCofactors2() +
                          Computes the two-way decomposition of f w.r.t. v. + +
                          cuddZddComplement() +
                          Computes a complement of a ZDD node. + +
                          cuddZddGetPosVarIndex() +
                          Returns the index of positive ZDD variable. + +
                          cuddZddGetNegVarIndex() +
                          Returns the index of negative ZDD variable. + +
                          cuddZddGetPosVarLevel() +
                          Returns the level of positive ZDD variable. + +
                          cuddZddGetNegVarLevel() +
                          Returns the level of negative ZDD variable. + +
                          +
                          +

                          cuddZddGroup.c

                          +Functions for ZDD group sifting.

                          +By: Fabio Somenzi

                          +External procedures included in this file: +

                            +
                          • Cudd_MakeZddTreeNode() +
                          + Internal procedures included in this file: +
                            +
                          • cuddZddTreeSifting() +
                          + Static procedures included in this module: +
                            +
                          • zddTreeSiftingAux() +
                          • zddCountInternalMtrNodes() +
                          • zddReorderChildren() +
                          • zddFindNodeHiLo() +
                          • zddUniqueCompareGroup() +
                          • zddGroupSifting() +
                          • zddGroupSiftingAux() +
                          • zddGroupSiftingUp() +
                          • zddGroupSiftingDown() +
                          • zddGroupMove() +
                          • zddGroupMoveBackward() +
                          • zddGroupSiftingBackward() +
                          • zddMergeGroups() +

                          +

                          +
                          Cudd_MakeZddTreeNode() +
                          Creates a new ZDD variable group. + +
                          cuddZddTreeSifting() +
                          Tree sifting algorithm for ZDDs. + +
                          zddTreeSiftingAux() +
                          Visits the group tree and reorders each group. + +
                          zddCountInternalMtrNodes() +
                          Counts the number of internal nodes of the group tree. + +
                          zddReorderChildren() +
                          Reorders the children of a group tree node according to + the options. + +
                          zddFindNodeHiLo() +
                          Finds the lower and upper bounds of the group represented + by treenode. + +
                          zddUniqueCompareGroup() +
                          Comparison function used by qsort. + +
                          zddGroupSifting() +
                          Sifts from treenode->low to treenode->high. + +
                          zddGroupSiftingAux() +
                          Sifts one variable up and down until it has taken all + positions. Checks for aggregation. + +
                          zddGroupSiftingUp() +
                          Sifts up a variable until either it reaches position xLow + or the size of the DD heap increases too much. + +
                          zddGroupSiftingDown() +
                          Sifts down a variable until it reaches position xHigh. + +
                          zddGroupMove() +
                          Swaps two groups and records the move. + +
                          zddGroupMoveBackward() +
                          Undoes the swap two groups. + +
                          zddGroupSiftingBackward() +
                          Determines the best position for a variables and returns + it there. + +
                          zddMergeGroups() +
                          Merges groups in the DD table. + +
                          +
                          +

                          cuddZddIsop.c

                          +Functions to find irredundant SOP covers as ZDDs from BDDs.

                          +By: In-Ho Moon

                          +External procedures included in this module: +

                            +
                          • Cudd_bddIsop() +
                          • Cudd_zddIsop() +
                          • Cudd_MakeBddFromZddCover() +
                          + Internal procedures included in this module: +
                            +
                          • cuddBddIsop() +
                          • cuddZddIsop() +
                          • cuddMakeBddFromZddCover() +
                          + Static procedures included in this module: +
                            +

                          +

                          +
                          Cudd_zddIsop() +
                          Computes an ISOP in ZDD form from BDDs. + +
                          Cudd_bddIsop() +
                          Computes a BDD in the interval between L and U with a + simple sum-of-product cover. + +
                          Cudd_MakeBddFromZddCover() +
                          Converts a ZDD cover to a BDD. + +
                          cuddZddIsop() +
                          Performs the recursive step of Cudd_zddIsop. + +
                          cuddBddIsop() +
                          Performs the recursive step of Cudd_bddIsop. + +
                          cuddMakeBddFromZddCover() +
                          Converts a ZDD cover to a BDD. + +
                          +
                          +

                          cuddZddLin.c

                          +Procedures for dynamic variable ordering of ZDDs.

                          +By: Fabio Somenzi

                          +Internal procedures included in this module: +

                            +
                          • cuddZddLinearSifting() +
                          + Static procedures included in this module: +
                            +
                          • cuddZddLinearInPlace() +
                          • cuddZddLinerAux() +
                          • cuddZddLinearUp() +
                          • cuddZddLinearDown() +
                          • cuddZddLinearBackward() +
                          • cuddZddUndoMoves() +

                          +

                          See AlsocuddLinear.c +cuddZddReord.c +

                          +
                          cuddZddLinearSifting() +
                          Implementation of the linear sifting algorithm for ZDDs. + +
                          cuddZddLinearInPlace() +
                          Linearly combines two adjacent variables. + +
                          cuddZddLinearAux() +
                          Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                          cuddZddLinearUp() +
                          Sifts a variable up applying the XOR transformation. + +
                          cuddZddLinearDown() +
                          Sifts a variable down and applies the XOR transformation. + +
                          cuddZddLinearBackward() +
                          Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
                          cuddZddUndoMoves() +
                          Given a set of moves, returns the ZDD heap to the order + in effect before the moves. + +
                          +
                          +

                          cuddZddMisc.c

                          +Miscellaneous utility functions for ZDDs.

                          +By: Hyong-Kyoon Shin, In-Ho Moon

                          +External procedures included in this module: +

                            +
                          • Cudd_zddDagSize() +
                          • Cudd_zddCountMinterm() +
                          • Cudd_zddPrintSubtable() +
                          + Internal procedures included in this module: +
                            +
                          + Static procedures included in this module: +
                            +
                          • cuddZddDagInt() +

                          +

                          +
                          Cudd_zddDagSize() +
                          Counts the number of nodes in a ZDD. + +
                          Cudd_zddCountMinterm() +
                          Counts the number of minterms of a ZDD. + +
                          Cudd_zddPrintSubtable() +
                          Prints the ZDD table. + +
                          cuddZddDagInt() +
                          Performs the recursive step of Cudd_zddDagSize. + +
                          +
                          +

                          cuddZddPort.c

                          +Functions that translate BDDs to ZDDs.

                          +By: Hyong-kyoon Shin, In-Ho Moon

                          +External procedures included in this module: +

                            +
                          • Cudd_zddPortFromBdd() +
                          • Cudd_zddPortToBdd() +
                          + Internal procedures included in this module: +
                            +
                          + Static procedures included in this module: +
                            +
                          • zddPortFromBddStep() +
                          • zddPortToBddStep() +

                          +

                          +
                          Cudd_zddPortFromBdd() +
                          Converts a BDD into a ZDD. + +
                          Cudd_zddPortToBdd() +
                          Converts a ZDD into a BDD. + +
                          zddPortFromBddStep() +
                          Performs the recursive step of Cudd_zddPortFromBdd. + +
                          zddPortToBddStep() +
                          Performs the recursive step of Cudd_zddPortToBdd. + +
                          +
                          +

                          cuddZddReord.c

                          +Procedures for dynamic variable ordering of ZDDs.

                          +By: Hyong-Kyoon Shin, In-Ho Moon

                          +External procedures included in this module: +

                            +
                          • Cudd_zddReduceHeap() +
                          • Cudd_zddShuffleHeap() +
                          + Internal procedures included in this module: +
                            +
                          • cuddZddAlignToBdd() +
                          • cuddZddNextHigh() +
                          • cuddZddNextLow() +
                          • cuddZddUniqueCompare() +
                          • cuddZddSwapInPlace() +
                          • cuddZddSwapping() +
                          • cuddZddSifting() +
                          + Static procedures included in this module: +
                            +
                          • zddSwapAny() +
                          • cuddZddSiftingAux() +
                          • cuddZddSiftingUp() +
                          • cuddZddSiftingDown() +
                          • cuddZddSiftingBackward() +
                          • zddReorderPreprocess() +
                          • zddReorderPostprocess() +
                          • zddShuffle() +
                          • zddSiftUp() +

                          +

                          +
                          Cudd_zddReduceHeap() +
                          Main dynamic reordering routine for ZDDs. + +
                          Cudd_zddShuffleHeap() +
                          Reorders ZDD variables according to given permutation. + +
                          cuddZddAlignToBdd() +
                          Reorders ZDD variables according to the order of the BDD + variables. + +
                          cuddZddNextHigh() +
                          Finds the next subtable with a larger index. + +
                          cuddZddNextLow() +
                          Finds the next subtable with a smaller index. + +
                          cuddZddUniqueCompare() +
                          Comparison function used by qsort. + +
                          cuddZddSwapInPlace() +
                          Swaps two adjacent variables. + +
                          cuddZddSwapping() +
                          Reorders variables by a sequence of (non-adjacent) swaps. + +
                          cuddZddSifting() +
                          Implementation of Rudell's sifting algorithm. + +
                          zddSwapAny() +
                          Swaps any two variables. + +
                          cuddZddSiftingAux() +
                          Given xLow <= x <= xHigh moves x up and down between the + boundaries. + +
                          cuddZddSiftingUp() +
                          Sifts a variable up. + +
                          cuddZddSiftingDown() +
                          Sifts a variable down. + +
                          cuddZddSiftingBackward() +
                          Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
                          zddReorderPreprocess() +
                          Prepares the ZDD heap for dynamic reordering. + +
                          zddReorderPostprocess() +
                          Shrinks almost empty ZDD subtables at the end of reordering + to guarantee that they have a reasonable load factor. + +
                          zddShuffle() +
                          Reorders ZDD variables according to a given permutation. + +
                          zddSiftUp() +
                          Moves one ZDD variable up. + +
                          zddFixTree() +
                          Fixes the ZDD variable group tree after a shuffle. + +
                          +
                          +

                          cuddZddSetop.c

                          +Set operations on ZDDs.

                          +By: Hyong-Kyoon Shin, In-Ho Moon

                          +External procedures included in this module: +

                            +
                          • Cudd_zddIte() +
                          • Cudd_zddUnion() +
                          • Cudd_zddIntersect() +
                          • Cudd_zddDiff() +
                          • Cudd_zddDiffConst() +
                          • Cudd_zddSubset1() +
                          • Cudd_zddSubset0() +
                          • Cudd_zddChange() +
                          + Internal procedures included in this module: +
                            +
                          • cuddZddIte() +
                          • cuddZddUnion() +
                          • cuddZddIntersect() +
                          • cuddZddDiff() +
                          • cuddZddChangeAux() +
                          • cuddZddSubset1() +
                          • cuddZddSubset0() +
                          + Static procedures included in this module: +
                            +
                          • zdd_subset1_aux() +
                          • zdd_subset0_aux() +
                          • zddVarToConst() +

                          +

                          +
                          Cudd_zddIte() +
                          Computes the ITE of three ZDDs. + +
                          Cudd_zddUnion() +
                          Computes the union of two ZDDs. + +
                          Cudd_zddIntersect() +
                          Computes the intersection of two ZDDs. + +
                          Cudd_zddDiff() +
                          Computes the difference of two ZDDs. + +
                          Cudd_zddDiffConst() +
                          Performs the inclusion test for ZDDs (P implies Q). + +
                          Cudd_zddSubset1() +
                          Computes the positive cofactor of a ZDD w.r.t. a variable. + +
                          Cudd_zddSubset0() +
                          Computes the negative cofactor of a ZDD w.r.t. a variable. + +
                          Cudd_zddChange() +
                          Substitutes a variable with its complement in a ZDD. + +
                          cuddZddIte() +
                          Performs the recursive step of Cudd_zddIte. + +
                          cuddZddUnion() +
                          Performs the recursive step of Cudd_zddUnion. + +
                          cuddZddIntersect() +
                          Performs the recursive step of Cudd_zddIntersect. + +
                          cuddZddDiff() +
                          Performs the recursive step of Cudd_zddDiff. + +
                          cuddZddChangeAux() +
                          Performs the recursive step of Cudd_zddChange. + +
                          cuddZddSubset1() +
                          Computes the positive cofactor of a ZDD w.r.t. a variable. + +
                          cuddZddSubset0() +
                          Computes the negative cofactor of a ZDD w.r.t. a variable. + +
                          cuddZddChange() +
                          Substitutes a variable with its complement in a ZDD. + +
                          zdd_subset1_aux() +
                          Performs the recursive step of Cudd_zddSubset1. + +
                          zdd_subset0_aux() +
                          Performs the recursive step of Cudd_zddSubset0. + +
                          zddVarToConst() +
                          Replaces variables with constants if possible (part of + canonical form). + +
                          +
                          +

                          cuddZddSymm.c

                          +Functions for symmetry-based ZDD variable reordering.

                          +By: Hyong-Kyoon Shin, In-Ho Moon

                          +External procedures included in this module: +

                            +
                          • Cudd_zddSymmProfile() +
                          + Internal procedures included in this module: +
                            +
                          • cuddZddSymmCheck() +
                          • cuddZddSymmSifting() +
                          • cuddZddSymmSiftingConv() +
                          + Static procedures included in this module: +
                            +
                          • cuddZddUniqueCompare() +
                          • cuddZddSymmSiftingAux() +
                          • cuddZddSymmSiftingConvAux() +
                          • cuddZddSymmSifting_up() +
                          • cuddZddSymmSifting_down() +
                          • zdd_group_move() +
                          • cuddZddSymmSiftingBackward() +
                          • zdd_group_move_backward() +

                          +

                          See AlsocuddSymmetry.c +

                          +
                          Cudd_zddSymmProfile() +
                          Prints statistics on symmetric ZDD variables. + +
                          cuddZddSymmCheck() +
                          Checks for symmetry of x and y. + +
                          cuddZddSymmSifting() +
                          Symmetric sifting algorithm for ZDDs. + +
                          cuddZddSymmSiftingConv() +
                          Symmetric sifting to convergence algorithm for ZDDs. + +
                          cuddZddSymmSiftingAux() +
                          Given x_low <= x <= x_high moves x up and down between the + boundaries. + +
                          cuddZddSymmSiftingConvAux() +
                          Given x_low <= x <= x_high moves x up and down between the + boundaries. + +
                          cuddZddSymmSifting_up() +
                          Moves x up until either it reaches the bound (x_low) or + the size of the ZDD heap increases too much. + +
                          cuddZddSymmSifting_down() +
                          Moves x down until either it reaches the bound (x_high) or + the size of the ZDD heap increases too much. + +
                          cuddZddSymmSiftingBackward() +
                          Given a set of moves, returns the ZDD heap to the position + giving the minimum size. + +
                          zdd_group_move() +
                          Swaps two groups. + +
                          zdd_group_move_backward() +
                          Undoes the swap of two groups. + +
                          cuddZddSymmSummary() +
                          Counts numbers of symmetric variables and symmetry + groups. + +
                          +
                          +

                          cuddZddUtil.c

                          +Utility functions for ZDDs.

                          +By: Hyong-Kyoon Shin, In-Ho Moon, Fabio Somenzi

                          +External procedures included in this module: +

                            +
                          • Cudd_zddPrintMinterm() +
                          • Cudd_zddPrintCover() +
                          • Cudd_zddPrintDebug() +
                          • Cudd_zddFirstPath() +
                          • Cudd_zddNextPath() +
                          • Cudd_zddCoverPathToString() +
                          • Cudd_zddSupport() +
                          • Cudd_zddDumpDot() +
                          + Internal procedures included in this module: +
                            +
                          • cuddZddP() +
                          + Static procedures included in this module: +
                            +
                          • zp2() +
                          • zdd_print_minterm_aux() +
                          • zddPrintCoverAux() +
                          • zddSupportStep() +
                          • zddClearFlag() +

                          +

                          +
                          Cudd_zddPrintMinterm() +
                          Prints a disjoint sum of product form for a ZDD. + +
                          Cudd_zddPrintCover() +
                          Prints a sum of products from a ZDD representing a cover. + +
                          Cudd_zddPrintDebug() +
                          Prints to the standard output a ZDD and its statistics. + +
                          Cudd_zddFirstPath() +
                          Finds the first path of a ZDD. + +
                          Cudd_zddNextPath() +
                          Generates the next path of a ZDD. + +
                          Cudd_zddCoverPathToString() +
                          Converts a path of a ZDD representing a cover to a string. + +
                          Cudd_zddSupport() +
                          Finds the variables on which a ZDD depends. + +
                          Cudd_zddDumpDot() +
                          Writes a dot file representing the argument ZDDs. + +
                          cuddZddP() +
                          Prints a ZDD to the standard output. One line per node is + printed. + +
                          zp2() +
                          Performs the recursive step of cuddZddP. + +
                          zdd_print_minterm_aux() +
                          Performs the recursive step of Cudd_zddPrintMinterm. + +
                          zddPrintCoverAux() +
                          Performs the recursive step of Cudd_zddPrintCover. + +
                          zddSupportStep() +
                          Performs the recursive step of Cudd_zddSupport. + +
                          zddClearFlag() +
                          Performs a DFS from f, clearing the LSB of the next + pointers. + +
                          +
                          +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddDesc.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddDesc.html new file mode 100644 index 000000000..5f27bf530 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddDesc.html @@ -0,0 +1,33 @@ + +The cudd package: Overview + + +

                          The cudd package

                          +

                          The University of Colorado decision diagram package.

                          +

                          By Fabio Somenzi

                          + + + +
                          + +External functions and data strucures of the CUDD package. +
                            +
                          • To turn on the gathering of statistics, define DD_STATS. +
                          • To link with mis, define DD_MIS. +
                          + Modified by Abelardo Pardo to interface it to VIS. + +
                          + +Last updated on 20120204 17h33 + + + +writing ./cuddExt.html diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddExt.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddExt.html new file mode 100644 index 000000000..24b63634a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddExt.html @@ -0,0 +1,14 @@ + +The cudd Package for Programmers + + + + + + + + + + + +writing ./cuddAllByFunc.html diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddExtAbs.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddExtAbs.html new file mode 100644 index 000000000..a476db7b1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddExtAbs.html @@ -0,0 +1,1415 @@ + +cudd package abstract + + + + + +
                          +
                          Cudd_AddHook() +
                          Adds a function to a hook. + +
                          Cudd_ApaAdd() +
                          Adds two arbitrary precision integers. + +
                          Cudd_ApaCompareRatios() +
                          Compares the ratios of two arbitrary precision integers to two + unsigned ints. + +
                          Cudd_ApaCompare() +
                          Compares two arbitrary precision integers. + +
                          Cudd_ApaCopy() +
                          Makes a copy of an arbitrary precision integer. + +
                          Cudd_ApaCountMinterm() +
                          Counts the number of minterms of a DD. + +
                          Cudd_ApaIntDivision() +
                          Divides an arbitrary precision integer by an integer. + +
                          Cudd_ApaNumberOfDigits() +
                          Finds the number of digits for an arbitrary precision + integer. + +
                          Cudd_ApaPowerOfTwo() +
                          Sets an arbitrary precision integer to a power of two. + +
                          Cudd_ApaPrintDecimal() +
                          Prints an arbitrary precision integer in decimal format. + +
                          Cudd_ApaPrintDensity() +
                          Prints the density of a BDD or ADD using + arbitrary precision arithmetic. + +
                          Cudd_ApaPrintExponential() +
                          Prints an arbitrary precision integer in exponential format. + +
                          Cudd_ApaPrintHex() +
                          Prints an arbitrary precision integer in hexadecimal format. + +
                          Cudd_ApaPrintMintermExp() +
                          Prints the number of minterms of a BDD or ADD in exponential + format using arbitrary precision arithmetic. + +
                          Cudd_ApaPrintMinterm() +
                          Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic. + +
                          Cudd_ApaSetToLiteral() +
                          Sets an arbitrary precision integer to a one-digit literal. + +
                          Cudd_ApaShiftRight() +
                          Shifts right an arbitrary precision integer by one binary + place. + +
                          Cudd_ApaShortDivision() +
                          Divides an arbitrary precision integer by a digit. + +
                          Cudd_ApaSubtract() +
                          Subtracts two arbitrary precision integers. + +
                          Cudd_AutodynDisableZdd() +
                          Disables automatic dynamic reordering of ZDDs. + +
                          Cudd_AutodynDisable() +
                          Disables automatic dynamic reordering. + +
                          Cudd_AutodynEnableZdd() +
                          Enables automatic dynamic reordering of ZDDs. + +
                          Cudd_AutodynEnable() +
                          Enables automatic dynamic reordering of BDDs and ADDs. + +
                          Cudd_AverageDistance() +
                          Computes the average distance between adjacent nodes. + +
                          Cudd_BddToAdd() +
                          Converts a BDD to a 0-1 ADD. + +
                          Cudd_BddToCubeArray() +
                          Builds a positional array from the BDD of a cube. + +
                          Cudd_BiasedOverApprox() +
                          Extracts a dense superset from a BDD with the biased + underapproximation method. + +
                          Cudd_BiasedUnderApprox() +
                          Extracts a dense subset from a BDD with the biased + underapproximation method. + +
                          Cudd_CProjection() +
                          Computes the compatible projection of R w.r.t. cube Y. + +
                          Cudd_CheckCube() +
                          Checks whether g is the BDD of a cube. + +
                          Cudd_CheckKeys() +
                          Checks for several conditions that should not occur. + +
                          Cudd_CheckZeroRef() +
                          Checks the unique table for nodes with non-zero reference + counts. + +
                          Cudd_ClassifySupport() +
                          Classifies the variables in the support of two DDs. + +
                          Cudd_ClearErrorCode() +
                          Clear the error code of a manager. + +
                          Cudd_CofMinterm() +
                          Computes the fraction of minterms in the on-set of all the + positive cofactors of a BDD or ADD. + +
                          Cudd_Cofactor() +
                          Computes the cofactor of f with respect to g. + +
                          Cudd_CountLeaves() +
                          Counts the number of leaves in a DD. + +
                          Cudd_CountMinterm() +
                          Counts the number of minterms of a DD. + +
                          Cudd_CountPathsToNonZero() +
                          Counts the number of paths to a non-zero terminal of a DD. + +
                          Cudd_CountPath() +
                          Counts the number of paths of a DD. + +
                          Cudd_CubeArrayToBdd() +
                          Builds the BDD of a cube from a positional array. + +
                          Cudd_DagSize() +
                          Counts the number of nodes in a DD. + +
                          Cudd_DeadAreCounted() +
                          Tells whether dead nodes are counted towards triggering + reordering. + +
                          Cudd_DebugCheck() +
                          Checks for inconsistencies in the DD heap. + +
                          Cudd_Decreasing() +
                          Determines whether a BDD is negative unate in a + variable. + +
                          Cudd_DelayedDerefBdd() +
                          Decreases the reference count of BDD node n. + +
                          Cudd_Density() +
                          Computes the density of a BDD or ADD. + +
                          Cudd_Deref() +
                          Decreases the reference count of node. + +
                          Cudd_DisableGarbageCollection() +
                          Disables garbage collection. + +
                          Cudd_DisableOrderingMonitoring() +
                          Disables monitoring of ordering. + +
                          Cudd_DisableReorderingReporting() +
                          Disables reporting of reordering stats. + +
                          Cudd_Disequality() +
                          Generates a BDD for the function x - y != c. + +
                          Cudd_DumpBlifBody() +
                          Writes a blif body representing the argument BDDs. + +
                          Cudd_DumpBlif() +
                          Writes a blif file representing the argument BDDs. + +
                          Cudd_DumpDDcal() +
                          Writes a DDcal file representing the argument BDDs. + +
                          Cudd_DumpDaVinci() +
                          Writes a daVinci file representing the argument BDDs. + +
                          Cudd_DumpDot() +
                          Writes a dot file representing the argument DDs. + +
                          Cudd_DumpFactoredForm() +
                          Writes factored forms representing the argument BDDs. + +
                          Cudd_Dxygtdxz() +
                          Generates a BDD for the function d(x,y) > d(x,z). + +
                          Cudd_Dxygtdyz() +
                          Generates a BDD for the function d(x,y) > d(y,z). + +
                          Cudd_EnableGarbageCollection() +
                          Enables garbage collection. + +
                          Cudd_EnableOrderingMonitoring() +
                          Enables monitoring of ordering. + +
                          Cudd_EnableReorderingReporting() +
                          Enables reporting of reordering stats. + +
                          Cudd_EpdCountMinterm() +
                          Counts the number of minterms of a DD with extended precision. + +
                          Cudd_EqualSupNorm() +
                          Compares two ADDs for equality within tolerance. + +
                          Cudd_EquivDC() +
                          Tells whether F and G are identical wherever D is 0. + +
                          Cudd_EstimateCofactorSimple() +
                          Estimates the number of nodes in a cofactor of a DD. + +
                          Cudd_EstimateCofactor() +
                          Estimates the number of nodes in a cofactor of a DD. + +
                          Cudd_Eval() +
                          Returns the value of a DD for a given variable assignment. + +
                          Cudd_ExpectedUsedSlots() +
                          Computes the expected fraction of used slots in the unique + table. + +
                          Cudd_FindEssential() +
                          Finds the essential variables of a DD. + +
                          Cudd_FindTwoLiteralClauses() +
                          Finds the two literal clauses of a DD. + +
                          Cudd_FirstCube() +
                          Finds the first cube of a decision diagram. + +
                          Cudd_FirstNode() +
                          Finds the first node of a decision diagram. + +
                          Cudd_FirstPrime() +
                          Finds the first prime of a Boolean function. + +
                          Cudd_FreeTree() +
                          Frees the variable group tree of the manager. + +
                          Cudd_FreeZddTree() +
                          Frees the variable group tree of the manager. + +
                          Cudd_GarbageCollectionEnabled() +
                          Tells whether garbage collection is enabled. + +
                          Cudd_GenFree() +
                          Frees a CUDD generator. + +
                          Cudd_IncreaseTimeLimit() +
                          Increases the time limit for the manager. + +
                          Cudd_Increasing() +
                          Determines whether a BDD is positive unate in a + variable. + +
                          Cudd_IndicesToCube() +
                          Builds a cube of BDD variables from an array of indices. + +
                          Cudd_Inequality() +
                          Generates a BDD for the function x - y ≥ c. + +
                          Cudd_Init() +
                          Creates a new DD manager. + +
                          Cudd_IsGenEmpty() +
                          Queries the status of a generator. + +
                          Cudd_IsInHook() +
                          Checks whether a function is in a hook. + +
                          Cudd_IsNonConstant() +
                          Returns 1 if a DD node is not constant. + +
                          Cudd_IterDerefBdd() +
                          Decreases the reference count of BDD node n. + +
                          Cudd_LargestCube() +
                          Finds a largest cube in a DD. + +
                          Cudd_MakeBddFromZddCover() +
                          Converts a ZDD cover to a BDD. + +
                          Cudd_MakeTreeNode() +
                          Creates a new variable group. + +
                          Cudd_MakeZddTreeNode() +
                          Creates a new ZDD variable group. + +
                          Cudd_MinHammingDist() +
                          Returns the minimum Hamming distance between f and minterm. + +
                          Cudd_NewApaNumber() +
                          Allocates memory for an arbitrary precision integer. + +
                          Cudd_NextCube() +
                          Generates the next cube of a decision diagram onset. + +
                          Cudd_NextNode() +
                          Finds the next node of a decision diagram. + +
                          Cudd_NextPrime() +
                          Generates the next prime of a Boolean function. + +
                          Cudd_NodeReadIndex() +
                          Returns the index of the node. + +
                          Cudd_OrderingMonitoring() +
                          Returns 1 if monitoring of ordering is enabled. + +
                          Cudd_OutOfMem() +
                          Warns that a memory allocation failed. + +
                          Cudd_OverApprox() +
                          Extracts a dense superset from a BDD with Shiple's + underapproximation method. + +
                          Cudd_Prime() +
                          Returns the next prime >= p. + +
                          Cudd_PrintDebug() +
                          Prints to the standard output a DD and its statistics. + +
                          Cudd_PrintGroupedOrder() +
                          Hook function to print the current variable order. + +
                          Cudd_PrintInfo() +
                          Prints out statistics and settings for a CUDD manager. + +
                          Cudd_PrintLinear() +
                          Prints the linear transform matrix. + +
                          Cudd_PrintMinterm() +
                          Prints a disjoint sum of products. + +
                          Cudd_PrintTwoLiteralClauses() +
                          Prints the two literal clauses of a DD. + +
                          Cudd_PrintVersion() +
                          Prints the package version number. + +
                          Cudd_PrioritySelect() +
                          Selects pairs from R using a priority function. + +
                          Cudd_Quit() +
                          Deletes resources associated with a DD manager. + +
                          Cudd_Random() +
                          Portable random number generator. + +
                          Cudd_ReadArcviolation() +
                          Returns the current value of the arcviolation parameter used + in group sifting. + +
                          Cudd_ReadBackground() +
                          Reads the background constant of the manager. + +
                          Cudd_ReadCacheHits() +
                          Returns the number of cache hits. + +
                          Cudd_ReadCacheLookUps() +
                          Returns the number of cache look-ups. + +
                          Cudd_ReadCacheSlots() +
                          Reads the number of slots in the cache. + +
                          Cudd_ReadCacheUsedSlots() +
                          Reads the fraction of used slots in the cache. + +
                          Cudd_ReadDead() +
                          Returns the number of dead nodes in the unique table. + +
                          Cudd_ReadElapsedTime() +
                          Returns the time elapsed since the start time of the manager. + +
                          Cudd_ReadEpsilon() +
                          Reads the epsilon parameter of the manager. + +
                          Cudd_ReadErrorCode() +
                          Returns the code of the last error. + +
                          Cudd_ReadGarbageCollectionTime() +
                          Returns the time spent in garbage collection. + +
                          Cudd_ReadGarbageCollections() +
                          Returns the number of times garbage collection has occurred. + +
                          Cudd_ReadGroupcheck() +
                          Reads the groupcheck parameter of the manager. + +
                          Cudd_ReadInvPermZdd() +
                          Returns the index of the ZDD variable currently in the i-th + position of the order. + +
                          Cudd_ReadInvPerm() +
                          Returns the index of the variable currently in the i-th + position of the order. + +
                          Cudd_ReadIthClause() +
                          Accesses the i-th clause of a DD. + +
                          Cudd_ReadKeys() +
                          Returns the number of nodes in the unique table. + +
                          Cudd_ReadLinear() +
                          Reads an entry of the linear transform matrix. + +
                          Cudd_ReadLogicZero() +
                          Returns the logic zero constant of the manager. + +
                          Cudd_ReadLooseUpTo() +
                          Reads the looseUpTo parameter of the manager. + +
                          Cudd_ReadMaxCacheHard() +
                          Reads the maxCacheHard parameter of the manager. + +
                          Cudd_ReadMaxCache() +
                          Returns the soft limit for the cache size. + +
                          Cudd_ReadMaxGrowthAlternate() +
                          Reads the maxGrowthAlt parameter of the manager. + +
                          Cudd_ReadMaxGrowth() +
                          Reads the maxGrowth parameter of the manager. + +
                          Cudd_ReadMaxLive() +
                          Reads the maximum allowed number of live nodes. + +
                          Cudd_ReadMaxMemory() +
                          Reads the maximum allowed memory. + +
                          Cudd_ReadMaxReorderings() +
                          Returns the maximum number of times reordering may be invoked. + +
                          Cudd_ReadMemoryInUse() +
                          Returns the memory in use by the manager measured in bytes. + +
                          Cudd_ReadMinDead() +
                          Reads the minDead parameter of the manager. + +
                          Cudd_ReadMinHit() +
                          Reads the hit rate that causes resizinig of the computed + table. + +
                          Cudd_ReadMinusInfinity() +
                          Reads the minus-infinity constant from the manager. + +
                          Cudd_ReadNextReordering() +
                          Returns the threshold for the next dynamic reordering. + +
                          Cudd_ReadNodeCount() +
                          Reports the number of nodes in BDDs and ADDs. + +
                          Cudd_ReadNodesDropped() +
                          Returns the number of nodes dropped. + +
                          Cudd_ReadNodesFreed() +
                          Returns the number of nodes freed. + +
                          Cudd_ReadNumberXovers() +
                          Reads the current number of crossovers used by the + genetic algorithm for reordering. + +
                          Cudd_ReadOne() +
                          Returns the one constant of the manager. + +
                          Cudd_ReadOrderRandomization() +
                          Returns the order randomization factor. + +
                          Cudd_ReadPeakLiveNodeCount() +
                          Reports the peak number of live nodes. + +
                          Cudd_ReadPeakNodeCount() +
                          Reports the peak number of nodes. + +
                          Cudd_ReadPermZdd() +
                          Returns the current position of the i-th ZDD variable in the + order. + +
                          Cudd_ReadPerm() +
                          Returns the current position of the i-th variable in the + order. + +
                          Cudd_ReadPlusInfinity() +
                          Reads the plus-infinity constant from the manager. + +
                          Cudd_ReadPopulationSize() +
                          Reads the current size of the population used by the + genetic algorithm for reordering. + +
                          Cudd_ReadRecomb() +
                          Returns the current value of the recombination parameter used + in group sifting. + +
                          Cudd_ReadRecursiveCalls() +
                          Returns the number of recursive calls. + +
                          Cudd_ReadReorderingCycle() +
                          Reads the reordCycle parameter of the manager. + +
                          Cudd_ReadReorderingTime() +
                          Returns the time spent in reordering. + +
                          Cudd_ReadReorderings() +
                          Returns the number of times reordering has occurred. + +
                          Cudd_ReadSiftMaxSwap() +
                          Reads the siftMaxSwap parameter of the manager. + +
                          Cudd_ReadSiftMaxVar() +
                          Reads the siftMaxVar parameter of the manager. + +
                          Cudd_ReadSize() +
                          Returns the number of BDD variables in existance. + +
                          Cudd_ReadSlots() +
                          Returns the total number of slots of the unique table. + +
                          Cudd_ReadStartTime() +
                          Returns the start time of the manager. + +
                          Cudd_ReadStderr() +
                          Reads the stderr of a manager. + +
                          Cudd_ReadStdout() +
                          Reads the stdout of a manager. + +
                          Cudd_ReadSwapSteps() +
                          Reads the number of elementary reordering steps. + +
                          Cudd_ReadSymmviolation() +
                          Returns the current value of the symmviolation parameter used + in group sifting. + +
                          Cudd_ReadTimeLimit() +
                          Returns the time limit for the manager. + +
                          Cudd_ReadTree() +
                          Returns the variable group tree of the manager. + +
                          Cudd_ReadUniqueLinks() +
                          Returns the number of links followed in the unique table. + +
                          Cudd_ReadUniqueLookUps() +
                          Returns the number of look-ups in the unique table. + +
                          Cudd_ReadUsedSlots() +
                          Reads the fraction of used slots in the unique table. + +
                          Cudd_ReadVars() +
                          Returns the i-th element of the vars array. + +
                          Cudd_ReadZddOne() +
                          Returns the ZDD for the constant 1 function. + +
                          Cudd_ReadZddSize() +
                          Returns the number of ZDD variables in existance. + +
                          Cudd_ReadZddTree() +
                          Returns the variable group tree of the manager. + +
                          Cudd_ReadZero() +
                          Returns the zero constant of the manager. + +
                          Cudd_RecursiveDerefZdd() +
                          Decreases the reference count of ZDD node n. + +
                          Cudd_RecursiveDeref() +
                          Decreases the reference count of node n. + +
                          Cudd_ReduceHeap() +
                          Main dynamic reordering routine. + +
                          Cudd_Ref() +
                          Increases the reference count of a node, if it is not + saturated. + +
                          Cudd_RemapOverApprox() +
                          Extracts a dense superset from a BDD with the remapping + underapproximation method. + +
                          Cudd_RemapUnderApprox() +
                          Extracts a dense subset from a BDD with the remapping + underapproximation method. + +
                          Cudd_RemoveHook() +
                          Removes a function from a hook. + +
                          Cudd_ReorderingReporting() +
                          Returns 1 if reporting of reordering stats is enabled. + +
                          Cudd_ReorderingStatusZdd() +
                          Reports the status of automatic dynamic reordering of ZDDs. + +
                          Cudd_ReorderingStatus() +
                          Reports the status of automatic dynamic reordering of BDDs + and ADDs. + +
                          Cudd_Reserve() +
                          Expand manager without creating variables. + +
                          Cudd_ResetStartTime() +
                          Resets the start time of the manager. + +
                          Cudd_SetArcviolation() +
                          Sets the value of the arcviolation parameter used + in group sifting. + +
                          Cudd_SetBackground() +
                          Sets the background constant of the manager. + +
                          Cudd_SetEpsilon() +
                          Sets the epsilon parameter of the manager to ep. + +
                          Cudd_SetGroupcheck() +
                          Sets the parameter groupcheck of the manager to gc. + +
                          Cudd_SetLooseUpTo() +
                          Sets the looseUpTo parameter of the manager. + +
                          Cudd_SetMaxCacheHard() +
                          Sets the maxCacheHard parameter of the manager. + +
                          Cudd_SetMaxGrowthAlternate() +
                          Sets the maxGrowthAlt parameter of the manager. + +
                          Cudd_SetMaxGrowth() +
                          Sets the maxGrowth parameter of the manager. + +
                          Cudd_SetMaxLive() +
                          Sets the maximum allowed number of live nodes. + +
                          Cudd_SetMaxMemory() +
                          Sets the maximum allowed memory. + +
                          Cudd_SetMaxReorderings() +
                          Sets the maximum number of times reordering may be invoked. + +
                          Cudd_SetMinHit() +
                          Sets the hit rate that causes resizinig of the computed + table. + +
                          Cudd_SetNextReordering() +
                          Sets the threshold for the next dynamic reordering. + +
                          Cudd_SetNumberXovers() +
                          Sets the number of crossovers used by the + genetic algorithm for reordering. + +
                          Cudd_SetOrderRandomization() +
                          Sets the order randomization factor. + +
                          Cudd_SetPopulationSize() +
                          Sets the size of the population used by the + genetic algorithm for reordering. + +
                          Cudd_SetRecomb() +
                          Sets the value of the recombination parameter used in group + sifting. + +
                          Cudd_SetReorderingCycle() +
                          Sets the reordCycle parameter of the manager. + +
                          Cudd_SetSiftMaxSwap() +
                          Sets the siftMaxSwap parameter of the manager. + +
                          Cudd_SetSiftMaxVar() +
                          Sets the siftMaxVar parameter of the manager. + +
                          Cudd_SetStartTime() +
                          Sets the start time of the manager. + +
                          Cudd_SetStderr() +
                          Sets the stderr of a manager. + +
                          Cudd_SetStdout() +
                          Sets the stdout of a manager. + +
                          Cudd_SetSymmviolation() +
                          Sets the value of the symmviolation parameter used + in group sifting. + +
                          Cudd_SetTimeLimit() +
                          Sets the time limit for the manager. + +
                          Cudd_SetTree() +
                          Sets the variable group tree of the manager. + +
                          Cudd_SetVarMap() +
                          Registers a variable mapping with the manager. + +
                          Cudd_SetZddTree() +
                          Sets the ZDD variable group tree of the manager. + +
                          Cudd_SharingSize() +
                          Counts the number of nodes in an array of DDs. + +
                          Cudd_ShortestLength() +
                          Find the length of the shortest path(s) in a DD. + +
                          Cudd_ShortestPath() +
                          Finds a shortest path in a DD. + +
                          Cudd_ShuffleHeap() +
                          Reorders variables according to given permutation. + +
                          Cudd_SolveEqn() +
                          Implements the solution of F(x,y) = 0. + +
                          Cudd_SplitSet() +
                          Returns m minterms from a BDD. + +
                          Cudd_Srandom() +
                          Initializer for the portable random number generator. + +
                          Cudd_StdPostReordHook() +
                          Sample hook function to call after reordering. + +
                          Cudd_StdPreReordHook() +
                          Sample hook function to call before reordering. + +
                          Cudd_SubsetCompress() +
                          Find a dense subset of BDD f. + +
                          Cudd_SubsetHeavyBranch() +
                          Extracts a dense subset from a BDD with the heavy branch + heuristic. + +
                          Cudd_SubsetShortPaths() +
                          Extracts a dense subset from a BDD with the shortest paths + heuristic. + +
                          Cudd_SubsetWithMaskVars() +
                          Extracts a subset from a BDD. + +
                          Cudd_SupersetCompress() +
                          Find a dense superset of BDD f. + +
                          Cudd_SupersetHeavyBranch() +
                          Extracts a dense superset from a BDD with the heavy branch + heuristic. + +
                          Cudd_SupersetShortPaths() +
                          Extracts a dense superset from a BDD with the shortest paths + heuristic. + +
                          Cudd_SupportIndex() +
                          Finds the variables on which a DD depends. + +
                          Cudd_SupportIndices() +
                          Finds the variables on which a DD depends. + +
                          Cudd_SupportSize() +
                          Counts the variables on which a DD depends. + +
                          Cudd_Support() +
                          Finds the variables on which a DD depends. + +
                          Cudd_SymmProfile() +
                          Prints statistics on symmetric variables. + +
                          Cudd_TimeLimited() +
                          Returns true if the time limit for the manager is set. + +
                          Cudd_TurnOffCountDead() +
                          Causes the dead nodes not to be counted towards triggering + reordering. + +
                          Cudd_TurnOnCountDead() +
                          Causes the dead nodes to be counted towards triggering + reordering. + +
                          Cudd_UnderApprox() +
                          Extracts a dense subset from a BDD with Shiple's + underapproximation method. + +
                          Cudd_UnsetTimeLimit() +
                          Unsets the time limit for the manager. + +
                          Cudd_UpdateTimeLimit() +
                          Updates the time limit for the manager. + +
                          Cudd_VectorSupportIndex() +
                          Finds the variables on which a set of DDs depends. + +
                          Cudd_VectorSupportIndices() +
                          Finds the variables on which a set of DDs depends. + +
                          Cudd_VectorSupportSize() +
                          Counts the variables on which a set of DDs depends. + +
                          Cudd_VectorSupport() +
                          Finds the variables on which a set of DDs depends. + +
                          Cudd_VerifySol() +
                          Checks the solution of F(x,y) = 0. + +
                          Cudd_Xeqy() +
                          Generates a BDD for the function x==y. + +
                          Cudd_Xgty() +
                          Generates a BDD for the function x > y. + +
                          Cudd_addAgreement() +
                          f if f==g; background if f!=g. + +
                          Cudd_addApply() +
                          Applies op to the corresponding discriminants of f and g. + +
                          Cudd_addBddInterval() +
                          Converts an ADD to a BDD. + +
                          Cudd_addBddIthBit() +
                          Converts an ADD to a BDD by extracting the i-th bit from + the leaves. + +
                          Cudd_addBddPattern() +
                          Converts an ADD to a BDD. + +
                          Cudd_addBddStrictThreshold() +
                          Converts an ADD to a BDD. + +
                          Cudd_addBddThreshold() +
                          Converts an ADD to a BDD. + +
                          Cudd_addCmpl() +
                          Computes the complement of an ADD a la C language. + +
                          Cudd_addCompose() +
                          Substitutes g for x_v in the ADD for f. + +
                          Cudd_addComputeCube() +
                          Computes the cube of an array of ADD variables. + +
                          Cudd_addConstrain() +
                          Computes f constrain c for ADDs. + +
                          Cudd_addConst() +
                          Returns the ADD for constant c. + +
                          Cudd_addDiff() +
                          Returns plusinfinity if f=g; returns min(f,g) if f!=g. + +
                          Cudd_addDivide() +
                          Integer and floating point division. + +
                          Cudd_addEvalConst() +
                          Checks whether ADD g is constant whenever ADD f is 1. + +
                          Cudd_addExistAbstract() +
                          Existentially Abstracts all the variables in cube from f. + +
                          Cudd_addFindMax() +
                          Finds the maximum discriminant of f. + +
                          Cudd_addFindMin() +
                          Finds the minimum discriminant of f. + +
                          Cudd_addGeneralVectorCompose() +
                          Composes an ADD with a vector of ADDs. + +
                          Cudd_addHamming() +
                          Computes the Hamming distance ADD. + +
                          Cudd_addHarwell() +
                          Reads in a matrix in the format of the Harwell-Boeing + benchmark suite. + +
                          Cudd_addIteConstant() +
                          Implements ITEconstant for ADDs. + +
                          Cudd_addIte() +
                          Implements ITE(f,g,h). + +
                          Cudd_addIthBit() +
                          Extracts the i-th bit from an ADD. + +
                          Cudd_addIthVar() +
                          Returns the ADD variable with index i. + +
                          Cudd_addLeq() +
                          Determines whether f is less than or equal to g. + +
                          Cudd_addLog() +
                          Natural logarithm of an ADD. + +
                          Cudd_addMatrixMultiply() +
                          Calculates the product of two matrices represented as + ADDs. + +
                          Cudd_addMaximum() +
                          Integer and floating point max. + +
                          Cudd_addMinimum() +
                          Integer and floating point min. + +
                          Cudd_addMinus() +
                          Integer and floating point subtraction. + +
                          Cudd_addMonadicApply() +
                          Applies op to the discriminants of f. + +
                          Cudd_addNand() +
                          NAND of two 0-1 ADDs. + +
                          Cudd_addNegate() +
                          Computes the additive inverse of an ADD. + +
                          Cudd_addNewVarAtLevel() +
                          Returns a new ADD variable at a specified level. + +
                          Cudd_addNewVar() +
                          Returns a new ADD variable. + +
                          Cudd_addNonSimCompose() +
                          Composes an ADD with a vector of 0-1 ADDs. + +
                          Cudd_addNor() +
                          NOR of two 0-1 ADDs. + +
                          Cudd_addOneZeroMaximum() +
                          Returns 1 if f > g and 0 otherwise. + +
                          Cudd_addOrAbstract() +
                          Disjunctively abstracts all the variables in cube from the + 0-1 ADD f. + +
                          Cudd_addOr() +
                          Disjunction of two 0-1 ADDs. + +
                          Cudd_addOuterSum() +
                          Takes the minimum of a matrix and the outer sum of two vectors. + +
                          Cudd_addPermute() +
                          Permutes the variables of an ADD. + +
                          Cudd_addPlus() +
                          Integer and floating point addition. + +
                          Cudd_addRead() +
                          Reads in a sparse matrix. + +
                          Cudd_addResidue() +
                          Builds an ADD for the residue modulo m of an n-bit + number. + +
                          Cudd_addRestrict() +
                          ADD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
                          Cudd_addRoundOff() +
                          Rounds off the discriminants of an ADD. + +
                          Cudd_addScalarInverse() +
                          Computes the scalar inverse of an ADD. + +
                          Cudd_addSetNZ() +
                          This operator sets f to the value of g wherever g != 0. + +
                          Cudd_addSwapVariables() +
                          Swaps two sets of variables of the same size (x and y) in + the ADD f. + +
                          Cudd_addThreshold() +
                          f if f>=g; 0 if f<g. + +
                          Cudd_addTimesPlus() +
                          Calculates the product of two matrices represented as + ADDs. + +
                          Cudd_addTimes() +
                          Integer and floating point multiplication. + +
                          Cudd_addTriangle() +
                          Performs the triangulation step for the shortest path + computation. + +
                          Cudd_addUnivAbstract() +
                          Universally Abstracts all the variables in cube from f. + +
                          Cudd_addVectorCompose() +
                          Composes an ADD with a vector of 0-1 ADDs. + +
                          Cudd_addWalsh() +
                          Generates a Walsh matrix in ADD form. + +
                          Cudd_addXeqy() +
                          Generates an ADD for the function x==y. + +
                          Cudd_addXnor() +
                          XNOR of two 0-1 ADDs. + +
                          Cudd_addXor() +
                          XOR of two 0-1 ADDs. + +
                          Cudd_bddAdjPermuteX() +
                          Rearranges a set of variables in the BDD B. + +
                          Cudd_bddAndAbstractLimit() +
                          Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. Returns NULL if too many nodes are required. + +
                          Cudd_bddAndAbstract() +
                          Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. + +
                          Cudd_bddAndLimit() +
                          Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                          Cudd_bddAnd() +
                          Computes the conjunction of two BDDs f and g. + +
                          Cudd_bddApproxConjDecomp() +
                          Performs two-way conjunctive decomposition of a BDD. + +
                          Cudd_bddApproxDisjDecomp() +
                          Performs two-way disjunctive decomposition of a BDD. + +
                          Cudd_bddBindVar() +
                          Prevents sifting of a variable. + +
                          Cudd_bddBooleanDiff() +
                          Computes the boolean difference of f with respect to x. + +
                          Cudd_bddCharToVect() +
                          Computes a vector whose image equals a non-zero function. + +
                          Cudd_bddClippingAndAbstract() +
                          Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. + +
                          Cudd_bddClippingAnd() +
                          Approximates the conjunction of two BDDs f and g. + +
                          Cudd_bddClosestCube() +
                          Finds a cube of f at minimum Hamming distance from g. + +
                          Cudd_bddCompose() +
                          Substitutes g for x_v in the BDD for f. + +
                          Cudd_bddComputeCube() +
                          Computes the cube of an array of BDD variables. + +
                          Cudd_bddConstrainDecomp() +
                          BDD conjunctive decomposition as in McMillan's CAV96 paper. + +
                          Cudd_bddConstrain() +
                          Computes f constrain c. + +
                          Cudd_bddCorrelationWeights() +
                          Computes the correlation of f and g for given input + probabilities. + +
                          Cudd_bddCorrelation() +
                          Computes the correlation of f and g. + +
                          Cudd_bddExistAbstractLimit() +
                          Existentially abstracts all the variables in cube from f. + +
                          Cudd_bddExistAbstract() +
                          Existentially abstracts all the variables in cube from f. + +
                          Cudd_bddGenConjDecomp() +
                          Performs two-way conjunctive decomposition of a BDD. + +
                          Cudd_bddGenDisjDecomp() +
                          Performs two-way disjunctive decomposition of a BDD. + +
                          Cudd_bddIntersect() +
                          Returns a function included in the intersection of f and g. + +
                          Cudd_bddInterval() +
                          Generates a BDD for the function lowerB ≤ x ≤ upperB. + +
                          Cudd_bddIsNsVar() +
                          Checks whether a variable is next state. + +
                          Cudd_bddIsPiVar() +
                          Checks whether a variable is primary input. + +
                          Cudd_bddIsPsVar() +
                          Checks whether a variable is present state. + +
                          Cudd_bddIsVarEssential() +
                          Determines whether a given variable is essential with a + given phase in a BDD. + +
                          Cudd_bddIsVarHardGroup() +
                          Checks whether a variable is set to be in a hard group. + +
                          Cudd_bddIsVarToBeGrouped() +
                          Checks whether a variable is set to be grouped. + +
                          Cudd_bddIsVarToBeUngrouped() +
                          Checks whether a variable is set to be ungrouped. + +
                          Cudd_bddIsop() +
                          Computes a BDD in the interval between L and U with a + simple sum-of-product cover. + +
                          Cudd_bddIteConstant() +
                          Implements ITEconstant(f,g,h). + +
                          Cudd_bddIteLimit() +
                          Implements ITE(f,g,h). Returns + NULL if too many nodes are required. + +
                          Cudd_bddIterConjDecomp() +
                          Performs two-way conjunctive decomposition of a BDD. + +
                          Cudd_bddIterDisjDecomp() +
                          Performs two-way disjunctive decomposition of a BDD. + +
                          Cudd_bddIte() +
                          Implements ITE(f,g,h). + +
                          Cudd_bddIthVar() +
                          Returns the BDD variable with index i. + +
                          Cudd_bddLICompaction() +
                          Performs safe minimization of a BDD. + +
                          Cudd_bddLargestPrimeUnate() +
                          Find a largest prime of a unate function. + +
                          Cudd_bddLeqUnless() +
                          Tells whether f is less than of equal to G unless D is 1. + +
                          Cudd_bddLeq() +
                          Determines whether f is less than or equal to g. + +
                          Cudd_bddLiteralSetIntersection() +
                          Computes the intesection of two sets of literals + represented as BDDs. + +
                          Cudd_bddMakePrime() +
                          Expands cube to a prime implicant of f. + +
                          Cudd_bddMaximallyExpand() +
                          Expands lb to prime implicants of (f and ub). + +
                          Cudd_bddMinimize() +
                          Finds a small BDD that agrees with f over + c. + +
                          Cudd_bddNPAnd() +
                          Computes f non-polluting-and g. + +
                          Cudd_bddNand() +
                          Computes the NAND of two BDDs f and g. + +
                          Cudd_bddNewVarAtLevel() +
                          Returns a new BDD variable at a specified level. + +
                          Cudd_bddNewVar() +
                          Returns a new BDD variable. + +
                          Cudd_bddNor() +
                          Computes the NOR of two BDDs f and g. + +
                          Cudd_bddOrLimit() +
                          Computes the disjunction of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                          Cudd_bddOr() +
                          Computes the disjunction of two BDDs f and g. + +
                          Cudd_bddPermute() +
                          Permutes the variables of a BDD. + +
                          Cudd_bddPickArbitraryMinterms() +
                          Picks k on-set minterms evenly distributed from given DD. + +
                          Cudd_bddPickOneCube() +
                          Picks one on-set cube randomly from the given DD. + +
                          Cudd_bddPickOneMinterm() +
                          Picks one on-set minterm randomly from the given DD. + +
                          Cudd_bddPrintCover() +
                          Prints a sum of prime implicants of a BDD. + +
                          Cudd_bddReadPairIndex() +
                          Reads a corresponding pair index for a given index. + +
                          Cudd_bddRead() +
                          Reads in a graph (without labels) given as a list of arcs. + +
                          Cudd_bddRealignDisable() +
                          Disables realignment of ZDD order to BDD order. + +
                          Cudd_bddRealignEnable() +
                          Enables realignment of BDD order to ZDD order. + +
                          Cudd_bddRealignmentEnabled() +
                          Tells whether the realignment of BDD order to ZDD order is + enabled. + +
                          Cudd_bddResetVarToBeGrouped() +
                          Resets a variable not to be grouped. + +
                          Cudd_bddRestrict() +
                          BDD restrict according to Coudert and Madre's algorithm + (ICCAD90). + +
                          Cudd_bddSetNsVar() +
                          Sets a variable type to next state. + +
                          Cudd_bddSetPairIndex() +
                          Sets a corresponding pair index for a given index. + +
                          Cudd_bddSetPiVar() +
                          Sets a variable type to primary input. + +
                          Cudd_bddSetPsVar() +
                          Sets a variable type to present state. + +
                          Cudd_bddSetVarHardGroup() +
                          Sets a variable to be a hard group. + +
                          Cudd_bddSetVarToBeGrouped() +
                          Sets a variable to be grouped. + +
                          Cudd_bddSetVarToBeUngrouped() +
                          Sets a variable to be ungrouped. + +
                          Cudd_bddSqueeze() +
                          Finds a small BDD in a function interval. + +
                          Cudd_bddSwapVariables() +
                          Swaps two sets of variables of the same size (x and y) in + the BDD f. + +
                          Cudd_bddTransfer() +
                          Convert a BDD from a manager to another one. + +
                          Cudd_bddUnbindVar() +
                          Allows the sifting of a variable. + +
                          Cudd_bddUnivAbstract() +
                          Universally abstracts all the variables in cube from f. + +
                          Cudd_bddVarConjDecomp() +
                          Performs two-way conjunctive decomposition of a BDD. + +
                          Cudd_bddVarDisjDecomp() +
                          Performs two-way disjunctive decomposition of a BDD. + +
                          Cudd_bddVarIsBound() +
                          Tells whether a variable can be sifted. + +
                          Cudd_bddVarIsDependent() +
                          Checks whether a variable is dependent on others in a + function. + +
                          Cudd_bddVarMap() +
                          Remaps the variables of a BDD using the default variable map. + +
                          Cudd_bddVectorCompose() +
                          Composes a BDD with a vector of BDDs. + +
                          Cudd_bddXnorLimit() +
                          Computes the exclusive NOR of two BDDs f and g. Returns + NULL if too many nodes are required. + +
                          Cudd_bddXnor() +
                          Computes the exclusive NOR of two BDDs f and g. + +
                          Cudd_bddXorExistAbstract() +
                          Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube. + +
                          Cudd_bddXor() +
                          Computes the exclusive OR of two BDDs f and g. + +
                          Cudd_tlcInfoFree() +
                          Frees a DdTlcInfo Structure. + +
                          Cudd_zddChange() +
                          Substitutes a variable with its complement in a ZDD. + +
                          Cudd_zddComplement() +
                          Computes a complement cover for a ZDD node. + +
                          Cudd_zddCountDouble() +
                          Counts the number of minterms of a ZDD. + +
                          Cudd_zddCountMinterm() +
                          Counts the number of minterms of a ZDD. + +
                          Cudd_zddCount() +
                          Counts the number of minterms in a ZDD. + +
                          Cudd_zddCoverPathToString() +
                          Converts a path of a ZDD representing a cover to a string. + +
                          Cudd_zddDagSize() +
                          Counts the number of nodes in a ZDD. + +
                          Cudd_zddDiffConst() +
                          Performs the inclusion test for ZDDs (P implies Q). + +
                          Cudd_zddDiff() +
                          Computes the difference of two ZDDs. + +
                          Cudd_zddDivideF() +
                          Modified version of Cudd_zddDivide. + +
                          Cudd_zddDivide() +
                          Computes the quotient of two unate covers. + +
                          Cudd_zddDumpDot() +
                          Writes a dot file representing the argument ZDDs. + +
                          Cudd_zddFirstPath() +
                          Finds the first path of a ZDD. + +
                          Cudd_zddIntersect() +
                          Computes the intersection of two ZDDs. + +
                          Cudd_zddIsop() +
                          Computes an ISOP in ZDD form from BDDs. + +
                          Cudd_zddIte() +
                          Computes the ITE of three ZDDs. + +
                          Cudd_zddIthVar() +
                          Returns the ZDD variable with index i. + +
                          Cudd_zddNextPath() +
                          Generates the next path of a ZDD. + +
                          Cudd_zddPortFromBdd() +
                          Converts a BDD into a ZDD. + +
                          Cudd_zddPortToBdd() +
                          Converts a ZDD into a BDD. + +
                          Cudd_zddPrintCover() +
                          Prints a sum of products from a ZDD representing a cover. + +
                          Cudd_zddPrintDebug() +
                          Prints to the standard output a ZDD and its statistics. + +
                          Cudd_zddPrintMinterm() +
                          Prints a disjoint sum of product form for a ZDD. + +
                          Cudd_zddPrintSubtable() +
                          Prints the ZDD table. + +
                          Cudd_zddProduct() +
                          Computes the product of two covers represented by ZDDs. + +
                          Cudd_zddReadNodeCount() +
                          Reports the number of nodes in ZDDs. + +
                          Cudd_zddRealignDisable() +
                          Disables realignment of ZDD order to BDD order. + +
                          Cudd_zddRealignEnable() +
                          Enables realignment of ZDD order to BDD order. + +
                          Cudd_zddRealignmentEnabled() +
                          Tells whether the realignment of ZDD order to BDD order is + enabled. + +
                          Cudd_zddReduceHeap() +
                          Main dynamic reordering routine for ZDDs. + +
                          Cudd_zddShuffleHeap() +
                          Reorders ZDD variables according to given permutation. + +
                          Cudd_zddSubset0() +
                          Computes the negative cofactor of a ZDD w.r.t. a variable. + +
                          Cudd_zddSubset1() +
                          Computes the positive cofactor of a ZDD w.r.t. a variable. + +
                          Cudd_zddSupport() +
                          Finds the variables on which a ZDD depends. + +
                          Cudd_zddSymmProfile() +
                          Prints statistics on symmetric ZDD variables. + +
                          Cudd_zddUnateProduct() +
                          Computes the product of two unate covers. + +
                          Cudd_zddUnion() +
                          Computes the union of two ZDDs. + +
                          Cudd_zddVarsFromBddVars() +
                          Creates one or more ZDD variables for each BDD variable. + +
                          Cudd_zddWeakDivF() +
                          Modified version of Cudd_zddWeakDiv. + +
                          Cudd_zddWeakDiv() +
                          Applies weak division to two covers. + +
                          + +
                          + +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddExtDet.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddExtDet.html new file mode 100644 index 000000000..f23e11e4f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddExtDet.html @@ -0,0 +1,4450 @@ + +The cudd package + + +
                          +
                          +
                          + 
                          +CUDD_VALUE_TYPE *þvalueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +CUDD_VALUE_TYPE *þvalueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +CUDD_VALUE_TYPE þcþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +CUDD_VALUE_TYPE þepþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +CUDD_VALUE_TYPE þupperþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +CUDD_VALUE_TYPE þvalueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +CUDD_VALUE_TYPE þvalueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +Cudd_AggregationType þgcþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +Cudd_HookType þwhereþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +Cudd_HookType þwhereþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +Cudd_HookType þwhereþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +Cudd_ReorderingType *þmethodþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +Cudd_ReorderingType *þmethodþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +Cudd_ReorderingType þmethodþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +Cudd_ReorderingType þmethodþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DD_PRFP þPifuncþfunction used to build Pi if it is NULL(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdApaDigit þliteralþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdApaNumber þbþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdApaNumber þdestþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdApaNumber þdiffþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdApaNumber þnumberþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdApaNumber þnumberþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdApaNumber þquotientþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdApaNumber þquotientþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdApaNumber þsecondþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdApaNumber þsumþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdGen *þgenþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdGen *þgenþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þddþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þmanagerþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þtableþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þtableþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þtableþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þtableþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdManager *þuniqueþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode ***þconjunctsþaddress of the array of conjuncts(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode ***þconjunctsþaddress of the array of conjuncts(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode ***þconjunctsþaddress of the array of conjuncts(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode ***þconjunctsþaddress of the first factor(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode ***þdisjunctsþaddress of the array of the disjuncts(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þonlyGþcube of variables only in g(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þvectorOffþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þvectorþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þvectorþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þvectorþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þyþarray of y variables(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þyþarray of y variables(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þyþarray of y variables(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þyþarray of y variables(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þyþarray of y variables(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þzdd_Iþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þzþarray of z variables(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode **þzþarray of z variables(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þBþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þBþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þDþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þDþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þPþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þPþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þQþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þQþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þQþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þQþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þUþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þYþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þbckþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcubeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcubeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcubeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcubeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcubeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcubeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcubeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þcþconstraint (care set)(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þepsilonþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþDD whose support is sought(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþDD whose support is sought(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþDD whose support size is sought(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþZDD whose support is sought(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþfunction against which to expand(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþfunction in which to remap variables(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þfþfunction of which the cube is to be made a prime(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þgþsecond operand(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þhþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þhþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þhþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þhþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þhþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þnþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þp_nodeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þphaseBddþcube of the phases(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þuþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þuþupper bound(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdNode *þvarþvariable(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +DdTlcInfo *þtþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +EpDouble *þepdþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +FILE *þfpþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +FILE *þfpþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +FILE *þfpþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +FILE *þfpþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +FILE *þfpþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +FILE *þfpþpointer to the dump file(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +FILE *þfpþpointer to the dump file(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +FILE *þfpþpointer to the dump file(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +FILE *þfpþpointer to the dump file(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +FILE *þfpþpointer to the dump file(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +MtrNode *þtreeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +MtrNode *þtreeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +char *þstringþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +char *þstrþpointer to string to use if != NULL(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +double *þprobþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +double þmgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +double þmgþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +double þmþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +double þquality0þminimum improvement for accepted changes when b=0(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +double þquality0þminimum improvement for accepted changes when b=0(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +double þqualityþminimum improvement for accepted changes(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +double þqualityþminimum improvement for accepted changes(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +double þqualityþminimum improvement for accepted changes(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +double þqualityþminimum improvement for accepted changes(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int **þcubeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int **þcubeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int **þindicesþarray containing (on return) the indices(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int **þindicesþarray containing (on return) the indices(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int **þpathþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int **þpathþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int *þarrayþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int *þarrayþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int *þdigitsþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int *þdistanceþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int *þinputsþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int *þlengthþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int *þlengthþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int *þpermutationþrequired variable permutation(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int *þpermutationþrequired variable permutation(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int *þpermutþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int *þpermutþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int *þphase2þ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int *þweightþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þNþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þamountþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þarcviolationþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þbinaryDigitsþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þbitþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þbitþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þcycleþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þdigitsþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þdirectionþunder (0) or over (1) approximation(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þdirectionþunder (0) or over (1) approximation(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þhardlimitþflag: 1 if threshold is a hard limit(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þhardlimitþflag: 1 if threshold is a hard limit(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþvariable index(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþvariable index(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþvariable index(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþvariable index(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþvariable index(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþvariable index(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þindexþvariable index(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þiþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þiþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þiþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þiþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þiþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þiþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þiþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þiþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þiþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þiþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þiþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þiþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þkþnumber of minterms to find(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þlevelþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þlevelþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þminsizeþbound below which no reordering occurs(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þminsizeþbound below which no reordering occurs(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þmultiplicityþhow many ZDD variables are created for each BDD variable(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þmvarsþsize of maskVars(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þmvþ0: blif, 1: blif-MV(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þmvþ0: blif, 1: blif-MV(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnVarsþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnumberXoversþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnvarsþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnvarsþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnvarsþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnvarsþsize of the support of f(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnzþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnzþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnzþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþlength of both arrays(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþnumbers of unknowns(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþnumbers of unknowns(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþsize of vars(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþsize of the array(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþsize of the array(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þnþsize of the array(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þpairIndexþcorresponding variable index(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þpathþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þphaseþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þphaseþ1: positive; 0: negative(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þpopulationSizeþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þpowerþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þprecisionþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þprecisionþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þprþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þprþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þprþverbosity level(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þprþverbosity level(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þrecombþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þsmsþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þsmvþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þsymmviolationþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þsyþstep of column variables(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þsyþstep of column variables(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þthresholdþmaximum number of nodes in the subset(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þthresholdþmaximum number of nodes in the subset(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þthresholdþmaximum number of nodes in the superset(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þthresholdþmaximum number of nodes in the superset(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þtopþindex of top variable(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þupperBoundþdistance above which an approximate answer is OK(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þupperþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þupperþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þvarþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þvarþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þvarþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þvþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þvþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þxþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +int þyþcolumn index(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +long þseedþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +long þsizeþsize of the allocation that failed(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þfactorþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þhrþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þlimitþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þlimitþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þlimitþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þlimitþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þlimitþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þlimitþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þlutþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þmaxLiveþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þmcþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þmrþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þnextþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þpþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þsecondDenþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þtypeþMTR_DEFAULT or MTR_FIXED(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þtypeþMTR_DEFAULT or MTR_FIXED(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned int þupperBþupper bound(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned long þincreaseþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned long þmaxMemoryþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned long þmaxMemoryþtarget maximum memory occupation(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned long þstþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +unsigned long þtlþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +void *þdataþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +void *þdataþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +void *þdataþ(
                          +    
                          +)
                          +
                          +
                          +

                          + +

                          +
                          + 
                          +þþ(
                          +    
                          +)
                          +
                          +
                          +

                          + + +

                          +
                          +Last updated on 20120204 17h33 + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddIntro.css b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddIntro.css new file mode 100644 index 000000000..d1824aff4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddIntro.css @@ -0,0 +1,30 @@ +/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */ +.MATH { font-family: "Century Schoolbook", serif; } +.MATH I { font-family: "Century Schoolbook", serif; font-style: italic } +.BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold } + +/* implement both fixed-size and relative sizes */ +SMALL.XTINY { font-size : xx-small } +SMALL.TINY { font-size : x-small } +SMALL.SCRIPTSIZE { font-size : smaller } +SMALL.FOOTNOTESIZE { font-size : small } +SMALL.SMALL { } +BIG.LARGE { } +BIG.XLARGE { font-size : large } +BIG.XXLARGE { font-size : x-large } +BIG.HUGE { font-size : larger } +BIG.XHUGE { font-size : xx-large } + +/* heading styles */ +H1 { } +H2 { } +H3 { } +H4 { } +H5 { } + +/* mathematics styles */ +DIV.displaymath { } /* math displays */ +TD.eqno { } /* equation-number cells */ + + +/* document-specific styles come next */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddIntro.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddIntro.html new file mode 100644 index 000000000..e74c4fff5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddIntro.html @@ -0,0 +1,219 @@ + + + + + +CUDD: CU Decision Diagram Package +Release 2.5.0 + + + + + + + + + + + + + + + + +next +up +previous + +index +
                          + Next: Introduction +   Index +
                          +
                          + + +

                          CUDD: CU Decision Diagram Package +
                          +Release 2.5.0

                          +
                          + +

                          Fabio Somenzi

                          +

                          Department of Electrical, Computer, and Energy Engineering

                          +

                          University of Colorado at Boulder

                          +
                          + +

                          +


                          + + + + + +

                          +
                          +Fabio Somenzi +2012-02-04 +
                          + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddTitle.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddTitle.html new file mode 100644 index 000000000..de29df000 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/cuddTitle.html @@ -0,0 +1,18 @@ + +The cudd package: Title + + + + + + + + +
                          + Programmer view + Maintainer by function + Maintainer by file
                          + + + +writing ./cuddDesc.html diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/footnode.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/footnode.html new file mode 100644 index 000000000..985c42271 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/footnode.html @@ -0,0 +1,109 @@ + + + + + +Footnotes + + + + + + + + + + + + + + + + +
                          +
                          ... application.1
                          +
                          The + global statistical counters are used locally; hence they are + compatible with the use of multiple managers. + +
                          .
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +
                          +
                          +
                          ... +node.2
                          +
                          When the variables in a group are reordered, the + association between the low field and the index of the first + variable in the group is lost. The package updates the tree to keep + track of the changes. However, the application cannot rely on + low to determine the position of variables. + +
                          .
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +.
                          +
                          +
                          +
                          + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/blueball.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/blueball.png new file mode 100644 index 0000000000000000000000000000000000000000..9720c29504ba579244bfbd203fd05240cc94a536 GIT binary patch literal 333 zcmV-T0kZyyP)g#RC9xF*N@U2-YVd{{{fg2mrhj5B~=M<^TXndV0kN0Q~>~TBXMS zYhuj;0K5+mat8pM1^~uFF=$Bu0004WQchC fp6U^O_M`O)E)54>ni*oc00000NkvXXu0mjfsOawM_w&SE@R)n5>xJ5B z1F;(h|BF_wQV4l;JD~8s(vhjgCGtV$Ds2t(5_qDSm6|w|UPxb;>}t1HkZ N22WQ%mvv4FO#oUfIV%7F literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/ch_begin.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/ch_begin.png new file mode 100644 index 0000000000000000000000000000000000000000..0b3a6e230df75ccef0955e1b346f3f5a94bc1a73 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^89*$-0VEh*g05=;X{M4OzhH*_y1vP(Kwi41i(^Q| zoVQaP`4|*An7cnV{yC!lYwO-a3y*wxkhkeenwPBWB3%~WiiqBfgF#DkMW*sCI@ojR z)Qg$b($DLkNv4UkZM&BfndB5)l8PiRLd~xnWZklNF;pM8tvX0WqPPyO z;)-K=4#W4F4}GJq1>p=*HTH~8Bx4Uw@L9auPP7>(8MU{?ml;f$b($DLkNv4UkZM&BfndB5)l8PiRLd~xnWZklNF;pM8tvX0WqPPyO z;)-K=4#W4F4}GJq1>p=*HTH~8Bx4Uw@L9auPP7>(8MU{?ml;fUD+8 zX^gy=OnEK3Q}m;lhza8yZV|7cVql)yXw0 z;)F+4%2HdS18kr6xbR7A&A75Cu)A%7Ys%EgTe~DWM4f D4qP>Q literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/contents.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/contents.png new file mode 100644 index 0000000000000000000000000000000000000000..0c752c66c876acaa2131d43788a7406f5979f746 GIT binary patch literal 278 zcmV+x0qOpUP)n_8B^;cn$O_g|3BG{!1Fj&^JiWpJWLeA$WK=+#U`gfB`ZJpvc?v;;IiS zWN}RlBW%jSmz3^2R|i?JM0KMv+9z;7ee@a!R<*>X0K7&N_)1@@}28%Z6=9 t-O~MHw|5t0`TuI#<-T9Me##YR_J!+(UN4n;@(5@ygQu&X%Q~loCIFb&G|K=0 literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/footnote.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/footnote.png new file mode 100644 index 0000000000000000000000000000000000000000..4591c0eca1231a8dd51f936b46363bcb9c35cefd GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^{2FS zrsoVLnH6~&F0zL+P8GD|SkqyVU@2Hw;H_Hnf}ux6|G)cetK3(c&T7OiHM_`p-Fn|I zk6S7tu`7hSPeski&6e)S+V5Vl<++E- m`l!8MrB+YxvAz2@`46M@GoAfWMa#rMF7kBsb6Mw<&;$UT-9{4t literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/greenball.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/greenball.png new file mode 100644 index 0000000000000000000000000000000000000000..a4d714533a8c5e836f167a2118108d4f68bcf2f6 GIT binary patch literal 333 zcmV-T0kZyyP)&2#{24FFmV07?x2oE8Aa z832?P0IV5GoK*nU90=AYkN=AR&L1KFKLAl@PcFG!4j{1mTA&&;ze)eFnmrpph=4*Wd1;<76Q uRfVXn4m>Ir2oglLH2I2lWqskW{Rg3J}7qSOsCi?q75nH?M zE^{77+Z<+1r-r1Nch|4lthS=d{J1PfXUU1#ym22LZu_2=vAt}Pd}!6<{pzf1?Y4jM u^4(GWO*wx3{4#&$%6k3J$8QJwOy|GN;;5Q**1ZVmMg~t;KbLh*2~7aKlwD!~ literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/next.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/next.png new file mode 100644 index 0000000000000000000000000000000000000000..1628652aac7cff4b24228abd9908c320c6026a7c GIT binary patch literal 245 zcmVQ2aP`rsfsL)H8>rF50IrEKQ7U2mrM!9=R9*Dw1X+@W9RTx^a-#5T6$bi^4|h!q3s vo9V3RdqZP$JTTh9!JZ)`voZLAB<&|;0_>J~#QNZkD16SAR=O4@7anKqmC5&ngT;#rH1+qK z20S~FlZynq-MY=T{~%>KNs884sExd44P^%bf!zNDPxW#x21^f><@$FgzM-=J5cLN5 WGDyh~oC>l40000tyuK1_JOFF_cfRLygYKXs-cjquE z6qZUgCnOS-qR#wjl*#Yu6x>pYvGz*5sgT3Ky$sw{E$HaO|9>UJNF+j;OnPJjVj%;{m_nqs0ZqV}||YZyJu#*Jw}23cUX_af%9 z{uS~*k`LH^Qb$R+lmwPEN^IYqTH-Vq0YzE^cOwaMk&itdVwtMByf}E>Y3%dwD5Z9*>tJ(L)x+ zsQ6o00>F0uiF$f}|EHc` gW14v)`Zh=L1v(Lj=i40@mjD0&07*qoM6N<$f}?G$umAu6 literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/orangeball.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/orangeball.png new file mode 100644 index 0000000000000000000000000000000000000000..10249c668abb037b32a1d537d66e9e2999bbc30e GIT binary patch literal 333 zcmV-T0kZyyP)AS^$Jp5VUCk#in}ymj~{O09rHvS~38OWibEI zrMztboOepzfdEP?07@wUtYiSqpJM--5C4`Aaz_u&dk|_o0L7(x)_4H_#*6==A;xn6 zazX&SY5-z60RN>ilvV(>R1Y8k0004WQchCd@h{G;iGOwP-k9UVO50Hcelh_;^S8s zlr19Cn;yHsWZodf)(Q_M@X|8FKV`iT$$re%Hlc^|+B?5ptZnip-JzW5walZJkLkqq fd#WKa^^evk#2W_K-Vq6^00000NkvXXu0mjf&K`=A literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/pinkball.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/pinkball.png new file mode 100644 index 0000000000000000000000000000000000000000..5b92325708e4bec4699d8b15e7ed285b55e9d6b6 GIT binary patch literal 332 zcmV-S0ki&zP)2P*}kMa>gUTJl$kP*V4^b)U_hOaP4 z(MBY9-{*nl_&|=WXFRCDeMJQS)O6OCS>LQ})^E1QPP=rmVxHz?hoKhgB esft+@KU$ytO$Rt^R9;{J0000fWJ4@hJr9=)Yx5|PDs2VC9?nk002ovPDHLkV1i^Ya=-up literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/prev_g.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/prev_g.png new file mode 100644 index 0000000000000000000000000000000000000000..476d9568c900e2ada6c2019b67eeee166a5f1288 GIT binary patch literal 327 zcmV-N0l5B&P)18~ zIpil5yY|hg&aw;rvXQ~olHp&x|G5Aw{ug* Z|8M28X+2RX!WaMm002ovPDHLkV1gF^iYx#C literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/purpleball.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/purpleball.png new file mode 100644 index 0000000000000000000000000000000000000000..d6d63fb822774678fbdd5da91b990f7b2be62997 GIT binary patch literal 332 zcmV-S0ki&zP)cTL6T*5C5-v#ny}en+VpE0M1bWa-{&~l>pYN0PeN`{l6jq+ok_+0GxpU zv@`%ph5)>_5C4q-#zp{QJ^)&S0K8%lgso!Df=ZlJ4{~V$lyNYNvH<;i0IaZj#WMg( zr9#fQ2meX{YCr&5ln~C}Z~OcJ0004WQchCK~#90#g)sEgfI+5A5%`N^P6zUU=N+dWI!5wkbi)oX1q1EeE{2PAz43` zjUI_tURl5+mNtM{cI5QxcaO3##>=)7a%RRi!C3=ixYOHP-y>bCt&dAl_~Pn=2Yv!r zIRI2Yf3EG_-QgN*3JYpS)}FGLc3w*194)5Q2wO$$?irWMpHpxZimD#{vRQw!W>{2Hx>KfrC3+}RpurNIMf0(44muQU=B5BoHh7m+`5KXsClX!R|pfonPY z@$RA_h4!9T%^dHQNzNCPkzC41E>31^)OKcj5cr=xaE@2f8U}+F0fQ(8 z@xKg#XOpV_8&*XzDC}XdxW?hQg~8w&gJTkdcngEZIj5{{1JAQb&3_p@_b?dT0~)*Z z-7^NqECvN5<(>$jGZ;&P{DK)Ap4~_Ta_T)@978JR)b{1_HyQA>>~8XV&C*`>K*a3H z*Z=>W%#XZaf2{g;vbWxJW{#qdHw)65`X_ZAm|s{r^NV26`?o^#C2y}csF>;cM0&1T zV{EB%-&)()&bP0l+XkKm7#uU literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/up.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/up.png new file mode 100644 index 0000000000000000000000000000000000000000..3937e168f44bc997766dbe3b9383bd1db44f094d GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)h#LU3J`0lmo0U(Dbz$e6Y|Ni~?`T5VEKaXZ$ zILr2UCs3TRB*-tA!Qt7BG$5zc)5S5QVoq$YAz!lrkL&!DV=`*aVJGv=2TrrsUKR?`=XF~0x$5q(BOL&qeQ?X^G$FnGH9 KxvX2RVNRAoooEaAn8>@(e1sRI!V#<^f)p#-WVQt^!{}{R!<_yH~7!&%|GmpxjXG& eckJV{U(78Bbom$-1qlM(%HZkh=d#Wzp$Pz8Iac=o literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/whiteball.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/icons/whiteball.png new file mode 100644 index 0000000000000000000000000000000000000000..9d3056253edcd186983168a96518bf84b7dfee94 GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^d?3sLBp7{FoMr=Qrjj7PV21s=zR9XU-aJni$B>FS zsb?1Q9Wsz`eRz4<$*!ykmsgzhGIFk9xyN|?aY7}F+Qi?6n?06!q!zxu(#FVQ(7fx} z9e>VQZk)e3KXoNpGz(q0`D$5is3xOo$~3v&=wIs&UUDHlX>5E z9S;zGC3EdoszqA)r|Kp{Ii!hv< zN=iup;^qMT{Q&>|5BmK8&COz_tN?Iw0M5-2`~L@zlmPqxAw^06#l?EAv;cyH5SN?) z|NAk|)(C`y0JgjU$Ibv2|F}*70004WQchC))ZYaU)ksQTISgKb3Rb} fo+=PU`=j*<1)c{R%U83*00000NkvXXu0mjfomZ1* literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img1.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img1.png new file mode 100644 index 0000000000000000000000000000000000000000..6082d1b9ad58139a0f3364a2754c623968379213 GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^LO`s*!py+HI4hJj1jx|}@Ck9kPs3Q;^E<8V`F1rV4$L+!o$O}V#SJ8`5V1~x)@7>{DK)Ap4~_Ta(q2q z9780gCMP&BuHksb%2qPrzyV$rOM@el5)lnE?lPQtB62{;$GVEUQ?}r0_?Id56g9l9u^1tybh2Gc(A~U@v?V{pT~#UB9LPc;1lAydGqEKD^|>zGiSnt z2`w!x6%`dZIXMXl2_YdN9v&VxHZ}$Z1}Z8l5)u+TJUl>6uOd&+15%77L4Lsu4$p3+ z0Xc!5E{-7_Gm{e>82G{rP98Y$y`fQ&LF)v+(u~T6BkXo;DF;}mF$m@|DMYd>Y<$2p z!62e-P0wfjDH~;-Hrni+&ah~ww1izlhCN#!r$A;MCo97-W8O3CLO8Ah4QKFl^>bP0 Hl+XkKMA<<` literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img11.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img11.png new file mode 100644 index 0000000000000000000000000000000000000000..9509b94b974ebceda7307b1464cff41d092dd978 GIT binary patch literal 476 zcmV<20VDp2P)RHR400001 zbW%=J06^y0W&i*IT1iAfR5*?8Qol>XKotIB65E(GNjEq1C-ff>`WKYWg3v*9G`mYc zaIUjUKyVYf6`Y)0z12av#Z`jfqUhOscNb401agtq6#GM((*ZSG0@&w*5zR?Vp&JFjHZYw)R1{_DDabix!g7 zN(IK0TlhoZj7&cRCMN4YA+4=D+ufyUsPT{OK+%!xlHHfY^?EQz@`3E<$=wK0#zIu; z?Kmo#9LSUeJ>819WYEjzJZg=MxOW2cC~DL6s2BJ#{L{wJ26OMV89dkC&AB{oS}{a@ zS|*E0000RHR400001 zbW%=J06^y0W&i*IsYygZR5*?8QoBw9K@>d;>@MIw(8|J?>1`-&jC=wywj?wfE3vYb z+5{gzKuD~O)K;1pTeq+^*-i@s8xkypWSu+vU>~4RnsAakb7t?HduPuK;3Ln2@yH-= zXxPW^uxQXtWmewiA%(2TqY%k5F&3>qnxu=-@q+F?qP2}zzC74`36mur+jDlA7po!b z@F>EwPMm`d=DH)ON8iBdWe4m*LPitEpbf4&2AoP8X08BCYkDLY7# zU6v%ZbS15lBu_|?hTDxvjvp^h4x>c*Tz^;UQ9_Ugh@RHR400001 zbW%=J06^y0W&i*Iu1Q2eR5*?8Rl82YP#FH&LR+A47@TXJT>A*jPP~9g-7q1hkHBV} zSO&QRoIk9)L%Y+im3u$m-yS?=LkV7l0n`^iWLJ`qUav>_=ie|0PP1MJE{ z+nQ?aDeF`tQ;eA%vrGG1KcrQ=r1xXtk=hxZ!_qqy^fYx9Yy29nn^K2wmF0bp((0nu zEQK516^9)B&APDr*fzWJUXKJltT&RBAdrcF1{(l&6WIR@gphBk>Wr&fDbxn);m9?3 zUlMsEI&~d<0GnPW6Y=s%5C>6vK}CZr1>`HzmwBnATIno*Vi2eYmB=2N)F|G*c2cWO%q0|3YX0000RHR400001 zbW%=J06^y0W&i*JAxT6*R7i>KR=-OeK@|RWz1utQ_Q%C4MF`v5Sfvy1PdGwa!Aer) zQiW8>)&Ud!2Sl(ItSv-AY;#50z;>|^9fU+kgvq?wnc110lW^F@`{3Ta_vV|AH$NV; zfQ7F3G3AFMVjRf;uP_5bU?QCuC=vaOUXmF!GX*k^ZDhB?zh?DV4y!=)CbJagBPA24 zAS9C@^H{P7&bnk4^~`U=L?gkb9m7{cHY;gAth9&ViShQd(>1A{@d`3x2RZ+P&gjLEJmR8tzuyAn&n?o3&zf7E2h9fFrk}Ln!rr6>qym%+Y|k zMX5;z#w*EO>FC~*mDnR=b~`co+<0_svZ3Vt#}EnUOx*%P^A-rMx-2a%LHa4plC@lO z4#+;?{8rbps2D*W{i-HqE!|5?SQ}L}u;CV9I`I5wtlSIT=ka(nC?z-DlIyKkpZbl9 z1?a2Saq@BEb5{!GM4>-8$Nz}-ftOmi@o8)MY_xTMEFLPStaE36O4I7DuW4g`=t#af z{rq-Q2i1!hT|WI0Z8#~1raHu-1~p)_=LD_-n@CmiWPI_%$YD@ zLQ6|aPEJljLPAJLh=GBDii(Pagai){4^XXaSl_!@p7{W0# z8K@zhp_!S7=L}E50p@hZqm5oOBqYwwi9FE2!zHnxs#2kasU!Npftp7=T}EwZjF&6& uOj8aJ>|@h7e4O#riv}sy5T#u+85vZgc_!?AeDx;KXa-MLKbLh*2~7aK8$K2Q literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img16.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img16.png new file mode 100644 index 0000000000000000000000000000000000000000..2a761cec18c990da32810254f9db52ffe85ad543 GIT binary patch literal 223 zcmeAS@N?(olHy`uVBq!ia0vp^LO{&V!py+Hn6rMEP z6IxnYDk>^+a&i(95<)^kJUl!M3=C9MR3s!MczAe#I-D8z?*>wgB|(0{3=Yq3qyaez zo-U3d95a&>8kh_XPO?7yu+dYS{A9%ziqp)c` zqwmi(<>w{8-3?;c6d`YD&~VkDz&{}&fPM2L5eW$et1u%21J#Dexm;@|H;OR)tmVHj TKVXU#&@Ki~S3j3^P6nbtJynBUmAxRH^~?nCoR&KQSBf4|4Eg#`R) zWcRT9!SJkxMNpnZMM)6 qi?$LrwtEZ)r<)qLKI~#)W@eB+CE3%V^>i=Leg;ohKbLh*2~7Y~L{>Ba literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img18.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img18.png new file mode 100644 index 0000000000000000000000000000000000000000..c08507b88acb3cffbe165f81eed7aedf44e8d0e2 GIT binary patch literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^hCr;q!py+HXlK8-9mp{V@Ck93?s|A38I*di0fMz(B`cdWH4eT>Il zHM|=_k~^9HvfUA26Yu!JaHPiJ4F3^fJDUarhZ%{pn3@isD_}gB$??G<=vc!UiIfF% zKJH;WER{0x-)Dhe^34C)R|wckot<#s;vsXGWFKdb40pqq-~Syx$a=PIZCrS8I_qq? u1(%xsd7n`F_y5230?Wy>P2zc-7#R39RlZ6w8GQh{nZeW5&t;ucLK6TQ_Gl;o literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img19.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img19.png new file mode 100644 index 0000000000000000000000000000000000000000..1b152d483a1e0fd81ba2349625b9a79bfd9b65a1 GIT binary patch literal 409 zcmV;K0cQS*P)RHR400001 zbW%=J06^y0W&i*I7fD1xR5*=eV1NLA1|EhF0$}C`eg+(X9hU?e*Z{-_fCe!nd>~Q> z1H%F&HXG0Ywgw=B?*UYV3F0&cW}?j_9R#589w3-7PXsK0@h(6F5?~4xpc2 z1g3c5wsE7TyNhrZ+hZ7ukNEU7l7O5XVKvC06OSCW5WWH;c>jX{FlRCq0XxoBs^R-~*dc0Az7YU|?7YHHEW*0WNm{$YT7&;NZi+kK!JA1r|7)UjfB* zo@f168Te4upUe0g0Ap`hfyGNa3bGK!1_FK`1rz}Qzxzn9e2?1q00000NkvXXu0mjf DYgU%k literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img2.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img2.png new file mode 100644 index 0000000000000000000000000000000000000000..022cc6a0bc1d2a79493d179c99d8c4c4924471d7 GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^LO`s*!py+HI4hJj1jtbd@Ck9eSqp2OM?7@862M7NCR^GJzX3_B&H?< zH9SagU}803vu2h`Xi4IEz_4(Kdc%pl9IXOo#*SFFgf8A3A>$LAI-DMA!Q3mvm2M=R s<@mOZRbbXm-bXUiR!XnPHe_L7NXcUVTK#DnJJ4tbPgg&ebxsLQ05*3!p8x;= literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img20.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img20.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd4c942bfc89fcf1ca31cd3bc57a7ec99ad4eda GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^VnD3G!py+HICEP z6IxnYDk>^+a&i(95<)^kJUl#XY-|h+3{+H9BqStwczA%CUPYds2c#HFg8YIR9G=}s z19EaaT^vIsrX~ZmC8Qi+6*6f3A=gmC!1;`A&Mk)rOrOIQD(6l;$gtk%kHT_UpN&Ny zV;F*LczBo`y5@H#GP%rPn(WE&Do6dtLm9pWSEX;rH{AThrNhJXhF9U)&Yt~@JZCtW j3{rdE|Ic60nat3>S8&(gLtWfJdl@`k{an^LB{Ts5Hv3VJ literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img21.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img21.png new file mode 100644 index 0000000000000000000000000000000000000000..49c39a27762847710af4a4887c3abb0f11b5fdb7 GIT binary patch literal 614 zcmV-s0-61ZP)RHR400001 zbW%=J06^y0W&i*IKRl82yKomXp`hj;HdzFfU!Zm63574QH_*5UDtW}!7y35+HIUSefL zMlO9m4YT(6BO0A2KgIt;>ntu8dCg(A@)O7o(AZa+RdGRC|A6D7AiwGBc$ATj+>Kw{ zP7}@Zuoa^yZfLD8Qx$+d!<6%LdLJ1Rd?O;+r?>Qj;zw!|iN7__(|5NuweWAwfVupvuZfs6jwL);01Oz#Rtc0kBSMH@@jOlp|s-@CKne1`O(>s|*AG{f4aw0^T=wDOz!UV!ujRB6< zc6T}THck|5sTFv&MO^}OORg_{!Rv;-eWi$ zY6qJUHCJIh2aa8D0E1UFO5$@dXX>%)1<&Z;XaF8riE+YcnaNlKdKjb-M03h(ZVuSJ zQK*LM@o+;h+DTsu3k-*cV#Z29%5n95Dp}bG@2_#Zpf8P&KX%M$thBzEY*vvFrYbSf8`Kt)>05d&Fuo_USeAM&=-q-j-<99mbn~dm^)lfE_+tWv5IUC2gt~S7;)I-Myni25rhdc%8FAy_;P1xQ zie8+Y$N^sVU$bWl?|dcST8yJIizf;53vvc&^ya2tPQDDJ(n$S6P&_P^gd2Oy3Dg3` znTi?5k)o&Do)0x^C&N-@ZK5>OK`0X}7J*eB;!Gpt=Zj+RQM?%uxUUobkYs&NU5%AD z#(BjlR?gE($ehOIRaOZ=Y63s6AhzwSNY$@Cb-ylLEJI=tQd{HD3`&q~`kp`epVXFL z{h0pXeT3H2Ge<2{%#3Qo9A}2-`r8~3+(GK5z>pG-K-Onp9Gwg*W#-90mcg=YJ8YUG7F3ve82K}jA2~g}(bARxMz&p|(e}Geq_n?{ zeIeC({iaR8BXB@50r871KuiqOG?2O+Xgde>L+N8QcD2odd$83*(Q=)PFFmP^Z>}zf zVset^iiJjg0Q*P8JTP{hCKO0d-XR)z7@re4eVJE&Kh(Q2{D8;|Nx-i*;AytHj@v_i zc!U_%t%^pk3r8PKrPjvBWCEmW?Ihh`L|Y4MzZITKy-?^^S~rtHv=yka@Y^l_(Z*)E z5KW6>8MIwD#LOL~hT;9@DG|3!}cQU4AY6kBb*DieI zf-OeQ%IoJ9?Vro8FN`Tv!};qF$X^xvN$S>C813CQE70$Je~q>!vUzl$FezxYkgW#2 z=G3RH`!v5d5wC3oIxqOup7MF{BGt3H#5X}PdR6W}@?E}RH_p{G*x3bmWFYG9BO8^c z&SHgy|1fOY1aC&6$53Gjy#a9yNHJ*o4eqeng`_XWY&~(YBFp%`B)2_jD7svFcYmfn zyh$f-l1BQ&dQ1>}bDvZ@Sp#aBV~nVZ9A*hwhyPG6HG9vWDO>1hR#9%@XM!bS(U5lHxF|#GV}tOjjgApvYCucQZvS@Yw7A{KDTjh zF7TIAUBUm*=TtDy?N~(#KE8S#9CR}ex&Os$0qzy533{=yvmf{ABm3z=2G>1z+ZW7; zTrczZfL~A$ShwxN;!nJgL>D7r)N5$@h#ak1ZCK{oklci#q7Auh`V`H*l>8jTi0bht z???~YVDt3)q%WWr{pu*Jv%SF1v$kHOEdC08ZSFgEu91tu(g?)~D;7W75pcDpGviK( z3b&%hvwvS7Oe&4{7pm19@vx64^b67H$BMbGjK5gVD0FJ^;uY68&w0sn2aihiy?;>w ze+H*U4QODdcQt~$I)8PHf=}66&2lQ+xdoGY(LdcKiC5u?r!vHa08$H2nKp}`!LSKU z@*8ztMi&!y=M@i)G+_^W0qNyNK}p4a+wA7iEf;1W` zsP;GXcPyMDQ}g2}-?*HG-jLR2kCtv4@_}Egg*Q2}4~UALn}qGC;pY^xzsKW#V_nt% zJjNWM;M|a$#FErd70q8>lZ?K^vOt99cl^tUB)-Cud(tuQsF1ES`_f_bMF5I>QlcjZ z{9^rRBH8_VP|u8Imdw9b}FF1XP?AfJ=0k zfruGQ2Fd&BM*h`MN*6yxwM=YMI1qxz@}O3|Af4Xrn>O~Pz(bmR*qaps_wwYR8{@9} zGCkB5bTl?j@^@fg-OqzRNf(buCf}i`BsyjZoTeCGkh?mbv%zaW=1M-RE7SSTQmLus z!S^;U-Mgn+;_2B{a4+h&E7^PLlAgEAy*cP7tZ5l|&yuJ1deJi=!2F~|mL+iu+ z(MVIhbKKyAi!9&AYetPV>j%%VrbzQO=`bebH36bs-drZ^F2Y0U6x`kfRJZ+}IWuiK zyhDnKiF2!(9K>5LH?V~R^N6Pd_@l2tvFI=M3jDib`l4X}Gg7q+nEFmG=0hF>`z^9u zy=0G)M41DIL8^v*VQ|#EAkmQ#Sl?);nZSz&7 zv=;A=;nLKRVzI^SSARE~-bLx=wKAVL->WjkoWnrw)d$#(`{hk{2i}b0E!&_#;*lH< zJ@YW(C2IKJ+#A%Yn;L0`oW&j#sY0cO^n$iw*KedYdT2L#OU4<$(74xHLxa>TF0f*p zdZ&@s(y*k$a-3?2(ebA;uefh#_nhbp2J-d{LMSHBOSb$kpbtmeH%%jb6<7SOm|j7j zH(OGTi^Be1ughBnb;aNa#lp9qZf4s|-UjGJ2Yk{9*xl=psG)XW!$ngwZn_62$L@io zvO)=?ZU~zuq|#D}WD7XfQ^ZMX8SZd>TM)TDrXkkzhyskoE-sx@2BPxr?jVU;7$(iC z@G#cGfXWtQ&FIeqtiKtb-5mo{^vC4g^f(|EPpz$PdFUK&Fz)1|o(r>Oj5C?I6Kjs= zPv1bGM;zjxZK#4kkW4;^eP88R0H5Giv~t^H*C*;M%9rHnXVmaLMqajI-#pfjDK?nj zLF+?98fX_7+9~5$P4{`WZ1fPZf~oA7QgR;N>qlp!MDK?@;*Ks{$KIdOVTOxuiWeuW z6Ga=(Y!4(NNx8EGKZU;i_PfFu2mRR9CgpnXtuM{LFx#S*K_3kfpL-SO~asd$tM_Q`0T5!WxA55 zf>Er7oEfwoGcma*`W{lMdR0XE`XWzjhf>8z$BBkigcsQQ!x)mGrc|2X!@p>Xk{<#q~8 zKPNx26n0&WSha^fzCce*Xnqkcr zN(*EOJv3e+%VDe{w(uVF#0@p`4m`CcAHe0dC^-$+8iMIQaOJ`Qp}^UM1t?uhYFMIe zwfVaLhb?=5cQ# zF@y9RXI=UwYo!V8nHwzGk{ggc>UlfccVHJ0Qx>ts@^lz4=HkS)(=F9C`&#?n#Om-x z2a}yLoz$(HRptTXktMj3fj4UG232z839T-!HbBM3}x7oKZ|!b8(HW+-m;W z*8+GS4I(5)P9d<$*G~jdWisMM7!;SQ^9@)t4aPt2T8H;at6VuFqEU0L`MkvM9PC5A zpN@M3%kf?m-7f+^rl;T5GN7=EVxX@82T@qhqb8(m4+To(U!udu84mJzi+@6$Aw+1b zkD~JS;b4`F9LRXcBA8p`otVl9N@ODZoiiJi_P_n*@^LuMxX*fUvhy*|#ep5#EiPf& zgSm%s0vWpn6HC8rr8D*OcD)z;ct{s2^7>lVErfc9+WwxW|A?A*{qF=KR3C|@%f

                          lnIoJ6UeWfl!#R{L6t(hB)q|}^BP`SG} zZHsc1FwMvt^SW)Amg5fF?-Ddn$l&+VtQq@19QEm!DV0am@_-6mN#|^8k#y7wT`2SQ z{|n*YR(UFBZ_(sK>LzA>_=9no#rr08wlk`!XKr)Zy;e)fOl*i*dJcDOBtA zrsZl1>sM;PwO_It&Dui zU+ZxTOjar!6|huubj`4!6b@dlMB*gV(BRKxL8fog{AEVeyD0MOgIh&&+04*Be*bR?v4^Ds~2iL&U?(}lnq7$ zY+gP;Gv7(@Ke+y8E|Xl28v!<3%I)godA5^R{2@J!V=p}s7byS&e!4bodfU2-R(Adk zR|Y>4C<0?hoyCc~3UDuvM{=IWe*j*W4fMTscOpJNyZ?>b5^&qjNh{95$Xwr?^DEe? zDP46r6v2max4U(G^hIsacg(^!c;%-O$qwuWxM^um)nv_Pw!R~Boq#U;{047O1B*S!&O)#c zGMCdHRx(?AXF1xict24t6}D>F=Y3&kO$nlXH(8HO;}7}x5Kf2kvwpfsf|%O+7C4L8 zfK0vL&vfCreqtCC&8^JQj0ih(FaO=&Bsj zS?EsVfEe?Y9L-ZNp)#QzG?3szY318B3kf{2*(O8`6VH5pjEsm@im@u8=8N)5YCOG^ z*7W^dX_^eCRI0WnQ-!A@>LPcPSZUN?kjWX7jJGBMK~zE6JAOj+tmlzwZIC zR?gQJy?$%Ixif(SlPJ^Qyy1%i^=Or!qI{}oFy53S9u&AQ<*Du5M+KQR4!yV)0~6eG zFBVYE;2t4Mmmjttd`bEpjS96q_qJQg{T*4D?J7%J(KiJ-#j#8^dYQZ&Q znX?W-0;{Y0>kl+39S&^f&c_Ttx*_LU3RwDoa2%h_Y()q%pVWduJIFSuE}MTqKR(2~ zk>`IUz<@!AqWaFc+7k+yK^DVkf#QVGLMFWAPyHFI9A^@>q-u^<_&d%n zdE)bH3VTYPPY~Nd3-tyaNIV17D+JeaAeRJbD0ec=f!{gFH)qip$0oCb#&{4m$RqA< zni;!yLY@~rM=4F+Cedp2|Tg3Juqg;T!I(pcj^PD+~Uo^l*B z{aHgt9Oqu=cpld~QiP!NdkMnW%sH4hZD|F9Kh*P9f{v7y&z5ipg{6o|PQ(^sS%fHB zeqx0xP`=#927!xWk97U)FpM;VXUC__?qHw}-e`^nu)w6i_PIQr7jf~gGf&mCFHspwW-gYYP zMlDZ1tKSe^ite4w!%WR1tkP!3mcA2>e(5>@fl0`l7PlYh?wzvGt}m`FdAe(&d}^+C z?iGtJ6v1YOU?(6saX&HYQC!eg>fZ4XCnF*u5cjQZQd&e?jc3AA4xx604-KV=V4;)_ z+8N!yEZUh0vpx{edhWFI!=)%~z{mxCl3c#umx8~GaQYo5*?WB zE1|*rb$ZUCZjn!JoROf?jFE9h={NctaWt_26K1eC>a4$HsLGtKCMvLoX}o5b*2^Ye z5JU4XnPrRMPUtMO;FI6s@5~j2{S~MKk_pBcg^^~|8Sye#f$|7S^bRB z;CO6rOt6fj0?WKrxzjBHR;e)idadD@U9N!VlhW*$5=O|QM{a*J{gw=H28B3LC1QSn zuSb1>{A$a?^u5w!kJI=R@U`NTY$_4fjeQO408c^Ys>M2c2lUE3S8ns|cEd=oa&re9 zc)JRUiWL*Y<~#2$>4)%CJec|A$E?Pma^%gBoLUP^|eA5@(?+bx&wE#W|kw_b)n2(6;=_eNYXY;9xEN@&|N;= zNJY&rq#XHcErV?G!58QjkSG&)gg|`%eIW6l(!oZROo6A2qf%x3K^}kfRSbpjYezgH z8eB%R##cz5WRi5u>wX;El%-G4bC&l&70A-w+Dwl68L7}p_&eja{9EFM{MwyW!0Y`m z_e1Neara4p=gZxN(duzBJx&Y<%aLcLP{7dafHnL&QfQk^-wLtc$8MCSDKQQ&x+7wr zDE|o$M_x6bAv-St$IaaZkb3B;NHY2kC04y%58*jEHtF}`Ux31q`>2Ru39=kLa+NeI zy+UGQDL#!As4x4-uNmBiWUKwmD!u&Gdj6#6>8_MpqnoMCT zlDjxgms>I7j?!-KS_d6Lc64V|u|sJX!&VQjG)&sBTDA0dm(x*6S)oaN!pBBL1E(at z?eD685VkZfr8YPYr*yX!IN!6!E9?^@lCn1lG%V$9n z@~&`Ej%#xgTHo?@4ydTf9lV&EQzg*2s$ag(UAlK^X>L$=%~!$~Bz*xpIf{>$O(b*IV& zeZx|6B0;QZkB{$p_w->z{fEL9^`-y!WdDcwztWHmpTHO<5^tZF=mD~|(@)9rwjgxz z(*D%$+dDkiNRZm)T-NjOl(3_4rTD`KjYmF#@8l_mqGuMk-J6+X>h9{f$GhP)vuI}o zXh+Guogh@>Tto_J~`7B`z`3aW>G&4Vo|^Ad<7Azc)M(~ zprSnz!6VbdDIZh}{So?3+*z@xuVBvS1c{L?JvI6pM%Xgh2P(p_{qS^jQJ)y1*Q1ZU z3a`xP@(vGr_}f2Aa`0`xKeY^Rm5?86|H z`2t$r%m(Z~DCVtCT%e#zC_M|}Gp1$>Kp~hXW=genD!l*TK-8P7#&td@Su~%)s9nqR z<+|PEQN;I@Gy&Y|cg(dm^3FGpBB9@Pm+x-pK3n0i2|4TQNoebOwX@G#=c^~mC4bnQ z@v9_T9pLLTc^Onr(l`6=epMH&1rZnBu14rb%46v2QX$fS8}lo8QQy~@!S(h(%Y_U? z?l%7y{PvD1`#d_oOUKWRHaKJeE$Ry?d>^DA+n&z_sY$tBki`D&4o6Jh&4 zFPfJOX2#3~Z3HJ7;}_8l-;E`nB`)f}B%Y(8S8zdAwA-6|(HBttxm)>??2oydMt*d+ z0<})LW$f!wQ2@#&Hw*pK{jb-fSgVaKSlU0lQrfWx5E`}lsrP%Ng92RdGJ*`(s zA96J)7{$NGfb=jL4`=<<0J5gm_DH02syGcEy9m(>$mC+t9ZS$BGDvK#qu>f_-ByZl zXZrrW@%U_mSQO z*(D{m^K~AXQBp8WQs*jN7lFjG${tbwwd>!3PPvF$LAOv_cMU4bC)cV0%4aqw6B^$4 z-#$Lb&^{jEJ1q+1CQlKqC`!>DinIguo?%5Fz*?ZsB#`A(*07fH0_*o~gdzdixPE?@ zuHyh&Bl0a0ZByZazXBuWv}zCTTnZ;0e|Qtc1B%DbY->U9k6@|uJCIQYcHxn zg-LL#t7lS%<`zrXR*2oL^8ak7d}0x-=0l7$1_lX*@jt`cWKTe>PLGVsTpT?G?Xmsx zX;Js`ESiKA5o+XFF%ikDiNbyn!`IWSr${EA(Vx(zBGtvC@Z*OSHP~N=`$M*g(kGXq zfwqLe`g?%ahHXsts7_uTMNp=TzVW9-?OI+8K`0z_FRyTH$Y znGV@`Om(q2%zZi!%h7OXUc&&zK1^k?6F=D$gQlLeNN4`N8jfENpOZD1yWu*0vDh+o zOX;SVFC*&m+l_<^lhb@!8rSS?B!*fv=zTz1>aRtwg=d=^G%cLody{#GYv_Z61zubO zQBGi?{*0tNeB4P3#{pds^=b15h6dzknC1nulB-e&96la#JlcuvzS)Rv@31#^@!i9a zi75KvkVfT-zDugCDJ_0UMc9#gvmIyZfacGC)qU5Sdg*xn;vgJPg>Cp~2E`Rs9S*Lw zo%MksEbQghsxk`rbU!yU`taVgZop~o3+Q^SZ(lxIl;Oai@p$fmt?tG7D_3cp&ak|$ z=$`wp8@b2?eXp_yD26PhImjaQ$Mm&yuS=y9q1{Hc;O$#GtoA~FK3f7cdjQfC&BL_I zFjCCzs1d&)YudRqDwp(^rT$h4P+s|`IxhRf@J6b`3qi$dL}w!5`r1KM2;mFaY06L> za6$m`Y9tOpXXOsz`cu(fVfI9_U+H_SBd(EKaEP?e2x^tSL1ZH_H%m%Lh!_aWi1;0rx%jvYL$ zzzDIg&1Z{0hHGM!DTRvQNT9MK9J#L9jJjiAc5CtOcXoXdmA5z#9K{a!9tUK)K({NZ z(f6F1gwZ`dgj)}05WEWb9_7>7+C^B<7FYNf+_@UjuNfH{v3+?;i+BychT0QQhaU)A zEgk-P4t9_X)d%QL=-XMG{{+^zrxid?)y0r9$F4f=-oGvzvh-OtARPhhN;r8Q)){`q zS+7902S_{5?4Y)ory|Q&lFMetE^+hEY0^_-uN_8l$WbtZBEHJ)D^Irj>U{ zUcPViYm6WoByPn}yq1c@AHjCe?9ckho8d_$k?>|Th9nwCV>guj@kAH$m~w+h#Il8; z@QxvuNtA!~U97cpy)!2P6Eek8>VNBM^TE#F8e2csEszxG9 zoJ4St_je*E;G)W8`BxMG`A++DuVlhXvjR^n?_}ny9I`!)@qxD*N|n7ClbTfv3dI}H zkcd@wQ_nH zW;oBv2l&^Xt*Rb^a+A|vcPmV!bNYe#6TWqIX0twjnO5|3Ze7Kv7u=Dzz6^iubw6>R z#Phtnbv@LKEC$k#_8O7oE*vgT;9%L|+Vq-0{zC>RJOV4mJ zu|4ZK-(Lb}bHF9Wz0p2#Sf#2Zq?%~WD;nb+2I3mFB$PAKRU3B&QI^}b;FjIM=etoT z(uuhR)9?+BsCV`vAbHErXsf~Hg0PaaC8fEYNCLL2=X8&o)94meh$=#uqynKc)0%^1 zQj~>dov2-BhU7&}+l1zC)2W(}sU5_YTV(L>X?rxQnw6Z&qDufHyi$_sewnGO`u0}K z>7FlZR(9_j92=h9oemkZcmgJu8aC#IbcyaPW8DPZ7uj&3Oy*<6f+yK_z}`88fxa5HtR)M}VjH^~ z9OshFXX`tXnodEkvDLv~l;!s;OLay+doz%2K-m@VJ7GDbMdN{utPGhkbT~T8O+iMCq^i?AX9!~Q>7J6` zWZsvqiMdYXv#*%Lgy=f0Bmi<3tK73nv3Ah$QmKlaP-Js@gBcNJ}#=KKVhEGT}bnH>39dF zE*v|0>o?3XiKwX2Rk>V*`RHtNh{YrSKAJ9?;(Y3 zSUTfr&dEGJb41lUce~nN-m#VDeDC1d9^QiAKHcvKGwxZqN|LXN(2eI}3bv6u}Rk%3>wxLHt>P`z&2GFd0Tf3uvh&#-9DrpyH z3sY^FRgXhv-2lOptf^9^R^G_uYQRF|BUY8$%0+Qg3-)eu@nNj>Hp02Vb5@s4(SwUa znE0+g@gsTWFha67UOcqCn%_n1Xf(4P%#m7d=(Y3eNa*gL z+1B~N`3PQNh45^Mi&&a;d~>MrzFWMsmMQ@@UCcU(y1YkEhxOOnd3wKhvk)~bIo~wL zdB1hXk7mME3n$@EYg{~e`Foc88|_IYBBiK$x;?hK3Mq!b@ec-KqD~6BmcMq@DJ5U8 z+&|lrwO^eB0_6gsmJ5Po1Uw7{mSxG&`}3@S+2t@?=Cw>$Bv~geeq%TJo?=qJk?`F2 z=?nU0VtqvRljk9#-gj|U@925k5d5Jv*?KZYvUYE{F8p=&QUmwoIoOix>_JRe|LZ)t zRVuFP>l!=7FLV>BJ^RHL>oe~bIe-`n&Y&V6*QnS!0_gAia8^Fw9+Xu^Io$kqV*w!} zQv6a37B~Fn5mKdaUA801kko>rBni zq-x~0J9(E4eP)}8j1IZ@951*z(co1V%_6PmE-A8);|j4_e0_p0yg1D2%kNsD6Uo1j zGpWmQ6j`%`it1wkemBAejzMD0UQL9Xb7`6=_PUFoR%u1AD1^&vGYk4Wq25?b2`!d4 zbLgeR!xUL=Jo;kMm7*e|enQf{yjW(ye`3gQgHzgyV7L8R9oUWeIJ-5;&#lYx4S7s9 zo732%zsJc!rv8LdQ`~;zyP0wrRv!T{I;oQ4ZNXIgKD(1FlH>73N(Wy&`{x!5?PVS! zG7Zr0y$)rIG2{C!N8+7UgKzS|T=1HMrVc-ec(Ph)5dW)v=C_Ky&~1Aii56QMIuz_s6}G@5s2N-pT6TW0}eW zqe^WRdQJP3Ua5cwT)ZfzLTgt_-=J`P`Q~!_i%rpwTCw%UzqmAGPzMjD%nO(4z(a&k zS8rgWR=bVjr#-4g*SphN)?Bx3ZFmzn?m~-lyA|iu!_2DiWRhHztm*5+wa^bfEF0g5 zja=#@Woy55` zGEWP!jiBnmUzi-#2Z6zop>Hp4Q|^o-6==dVcB-H8k&81ZK zF(}1UPum9>PO}Cez9IZaIJ-LqYd5z}N>%W`XA7*+_>HwA=w`R=k9)|&$I^#K6BHKer@iC{OxYrkl= zrApV1)~>DzD{y99hbLmAZ$ynI`)5~c*OZ(4^$k~6L|HBMkUWVCVV;_bhex&8ic7Ah z)Uux#W-{7AjWXz{h>B!fn;L)0J{es*>0DaY-_0XEhw#7xN#6HycAVA08H+)s&sZgp zYpKX@guf9jG^RHR400001 zbW%=J06^y0W&i*I4@pEpR49>SV1R%RZ~_Hz!3ivYAE-kBNQ1Bg4mDtqz`($0z`zMI zzW~T(@`s9ZVjOy&j}U(zy?&pAi)m}@(W;6j9USscp_Bqh6~}K(ER}ALNF4S z1;K?H!N5xsUr`A#w=1CVEhZvyfF80{r~xxM{(Jxnu)Xhn2a{y_!oaZr!huLKL^8BN z`0@7&bASH2`tvH!$#j0LjB88Fx9r?UZ9+!!Q=vL6ZNEGO+#w2K4{` vUoa%WAPQXo?EXa%?@oa7Sx#UHjKL28#KSt56Ur~300000NkvXXu0mjfprn~E literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img4.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img4.png new file mode 100644 index 0000000000000000000000000000000000000000..a709c3fd21312df2b667fcf4fe306de3cad16c5b GIT binary patch literal 204 zcmeAS@N?(olHy`uVBq!ia0vp^{2`Pl)U0&6`)OSTSeLoCy;q zw6wHTR8-{T5)u*<5;Pc+*wh5LS$4=uNQfIKFqWB3kcwku%W1gSEbU=Zz%Wx>$l;aMMlI)t ySx0uxb~KrN!;LMnqm_{-`aq8kTi$XeHU^7#TpRHR400001 zbW%=J06^y0W&i*Hxk*GpR2Y?GU;qO)21W>jfeVUZfS&;k{C)r=5*R)R0I3gP5he$8 zH4H%Gcqf2$bAY)Y_<+RzeZL_bUQG44K>^r7@d9uTKSRO-5Stn7JWhrUKn< zg@I!MT!$$`15ASV0|Va&1`NQ@!2baxhed)7$tVQy|Nq}X^8ZmZQ2<3vEJklyxX%Cp N002ovPDHLkV1iYGbMOEF literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img6.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img6.png new file mode 100644 index 0000000000000000000000000000000000000000..732c334023cbfffcb41fb9ca5d7c46ee1e6b1404 GIT binary patch literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^AT~b>GXn!-#I@qpK#p#JPl)U0&6`)OSTSeLoR*fB zii(PyoScM&gpiOB4-XF;8yf=y0~Hk&2?+@v9v+~M%!7WqK#H*>$S;_|;n|HeAjitn z#W93qW^w{UGn>Fc9wiIO9}*K7)CI09eB7xhqRb)A(0SP54~M56_rV_4lbf|{88%kR fI6O%#WMlXLmz$e6Y^XAPfR;-vaXU>EP z6IxnYDk>^+a&i(95<)^kJUl#XY-|h+3{+H9BqStwczA%CUPYds2c#HFg8YIR9G=}s z19DnCT^vI+CMG8^Fy*m@TsYuh^dKoAVfTRp2hJZjz_rkWJ;8TVkH;LAX>2U*Vh#*m zpB-Pe&wn^=qv|JRoqY$I66ANVBs$A_SsxE%Eco-YL5-zGiSnt z2`w!x6%`dZIXMXl2_YdN9v&VxHZ}$Z1}Z8l5)u+TJUl>6uOd&+15%77L4Lsu4$p3+ z0Xb2gE{-7*Q&GgH_oZm^+o=b4C5wuTOV1trFg{G?E3_KgaUm;^pIml$X< zaF$IF;O}_ADk%O@xIZFy7rfdU8wI%-n7Vjk%e{lv Q0BvFLboFyt=akR{0OjmNw*UYD literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img9.png b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/img9.png new file mode 100644 index 0000000000000000000000000000000000000000..1a46e4c82bbd694875097987add2292668562096 GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp@K&-&R%)r3t^WnZBkfR&m6XLpg^X3&RR?L|*XTpRD zEiEk-6%{!-ISB~~At50i9v(I}HU^GJUl=hf3lAN^)oP*1o;IsI6S+N2INF| zx;Tb#%uG&5c#!-c&4F>xikNFmY;8bP0l+XkKcWg(T literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/index.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/index.html new file mode 100644 index 000000000..e74c4fff5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/index.html @@ -0,0 +1,219 @@ + + + + + +CUDD: CU Decision Diagram Package +Release 2.5.0 + + + + + + + + + + + + + + + + +next +up +previous + +index +
                          + Next: Introduction +   Index +
                          +
                          + + +

                          CUDD: CU Decision Diagram Package +
                          +Release 2.5.0

                          +
                          + +

                          Fabio Somenzi

                          +

                          Department of Electrical, Computer, and Energy Engineering

                          +

                          University of Colorado at Boulder

                          +
                          + +

                          +


                          + + + + + +

                          +
                          +Fabio Somenzi +2012-02-04 +
                          + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node1.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node1.html new file mode 100644 index 000000000..2398d3652 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node1.html @@ -0,0 +1,174 @@ + + + + + +Introduction + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                          + Next: How to Get CUDD + Up: CUDD: CU Decision Diagram + Previous: CUDD: CU Decision Diagram +   Index +
                          +
                          + + +

                          + +
                          +Introduction +

                          + +

                          +The CUDD package provides functions to manipulate Binary Decision +Diagrams (BDDs) [5,3], +Algebraic Decision Diagrams (ADDs) +[1], and Zero-suppressed Binary Decision +Diagrams (ZDDs) +[12]. BDDs are used to represent +switching functions; ADDs are used to +represent function from $\{0,1\}^n$ to an arbitrary set. ZDDs +represent switching functions like BDDs; +however, they are much more efficient than BDDs when the functions to +be represented are characteristic +functions of cube sets, or in general, when the +ON-set of the function to be represented is +very sparse. They are inferior to BDDs in other cases. + +

                          +The package provides a large set of operations on BDDs, ADDs, and +ZDDs, functions to convert BDDs into ADDs or ZDDs and vice versa, and +a large assortment of variable reordering methods. + +

                          +The CUDD package can be used in three ways: + +

                            +
                          • As a black box. In this case, the application + program that needs to manipulate decision diagrams only uses the + exported functions of the package. The rich set of functions + included in the CUDD package allows many applications to be written + in this way. Section 3 describes how to use the + exported functions of the package. An application written in terms + of the exported functions of the package needs not concern itself + with the details of variable reordering, which may + take place behind the scenes. +Click here +for a list of the + exported functions. +
                          • +
                          • As a clear box. When writing a sophisticated + application based on decision diagrams, efficiency often dictates + that some functions be implemented as direct recursive manipulation + of the diagrams, instead of being written in terms of existing + primitive functions. Section 4 explains how to add new + functions to the CUDD package. It also details how to write a + recursive function that can be interrupted by + dynamic variable reordering. +Click here +for a list of the + exported and internal functions. +
                          • +
                          • Through an interface. Object-oriented languages like C++ and + Perl5 can free the programmer from the burden of memory management. + A C++ interface is included in the distribution of CUDD. It + automatically frees decision diagrams that are no longer used by the + application and overloads operators. Almost all the functionality + provided by the CUDD exported functions is available through the C++ + interface, which is especially recommended for fast prototyping. + Section 5 explains how to use the interface. A Perl5 + interface also exists and is ditributed separately. (See + Section 2.2.) Some applications define their own + interfaces. See for example Section 3.18. +
                          • +
                          +In the following, the reader is supposed to be familiar with the basic +ideas about decision diagrams, as found, for instance, in [3]. + +

                          +


                          + + +next + +up + +previous + +index +
                          + Next: How to Get CUDD + Up: CUDD: CU Decision Diagram + Previous: CUDD: CU Decision Diagram +   Index + +
                          +Fabio Somenzi +2012-02-04 +
                          + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node2.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node2.html new file mode 100644 index 000000000..f36d7ec2a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node2.html @@ -0,0 +1,175 @@ + + + + + +How to Get CUDD + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                          + Next: User's Manual + Up: CUDD: CU Decision Diagram + Previous: Introduction +   Index +
                          +
                          + + +Subsections + + + +
                          + +

                          + +
                          +How to Get CUDD +

                          + +

                          + +

                          + +
                          +The CUDD Package +

                          + +

                          +The CUDD package is available via anonymous FTP from +vlsi.Colorado.EDU. A compressed tar file named +cudd-2.5.0.tar.gz can be found in directory pub. +Once you have this file, +

                          +gzip -dc cudd-2.5.0.tar.gz | tar xvf - + +
                          +will create directory cudd-2.5.0 and its subdirectories. +These directories contain the decision diagram package, a few support +libraries, and a toy application based on the +decision diagram package. There is a README file +with instructions on configuration and +installation in cudd-2.5.0. You can use +a compiler for either ANSI C or C++. + +

                          +Once you have made the libraries and program, you can type: +

                          +cd nanotrav +
                          +nanotrav -p 1 -autodyn -reordering sifting -trav mult32a.blif + +
                          +This will run a simple-minded FSM traversal program. (On a 2.4 GHz +Pentium 4 (TM), it takes about 0.5 s.) The +output produced by the program can be checked against +cudd-2.5.0/nanotrav/mult32a.out. More information on the +nanotrav program can be found in +cudd-2.5.0/nanotrav/README. + +

                          +If you want to be notified of new releases of the CUDD package, send a +message to Fabio@Colorado.EDU. + +

                          + +

                          + +
                          +CUDD Friends +

                          + +

                          +Two CUDD extensions are available via anonymous FTP from +vlsi.Colorado.EDU. + +

                            +
                          • PerlDD is an object-oriented Perl5 interface to CUDD. It + is organized as a standard Perl extension module. The Perl interface + is at a somewhat higher level than the C++ interface, but it is not + as complete. +
                          • +
                          • DDcal is a graphic BDD calculator based on CUDD, Perl-Tk, + and dot. (See Section 3.19 for information on dot.) + +

                            +

                          • +

                          + + +next + +up + +previous + +index +
                          + Next: User's Manual + Up: CUDD: CU Decision Diagram + Previous: Introduction +   Index + +
                          +Fabio Somenzi +2012-02-04 +
                          + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node3.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node3.html new file mode 100644 index 000000000..d91378b2e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node3.html @@ -0,0 +1,1637 @@ + + + + + +User's Manual + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                          + Next: Programmer's Manual + Up: CUDD: CU Decision Diagram + Previous: How to Get CUDD +   Index +
                          +
                          + + +Subsections + + + +
                          + +

                          + +
                          +User's Manual +

                          + +

                          +This section describes the use of the CUDD package as a black box. + +

                          + +

                          + +
                          +Compiling and Linking +

                          + +

                          +To build an application that uses the CUDD package, you should add +

                          +#include "util.h"
                          +#include "cudd.h"
                          +
                          + +to your source files, and should link +libcudd.a, +libmtr.a, +libst.a, and +libutil.a to your executable. (All these +libraries are part of the distribution.) Some +platforms require specific compiler and linker flags. Refer to the +Makefile in the top level directory of the +distribution. + +

                          +Keep in mind that whatever flags affect the size of data +structures--for instance the flags used to use 64-bit pointers where +available--must be specified when compiling both CUDD and the files +that include its header files. + +

                          + +

                          + +
                          +Basic Data Structures +

                          + +

                          + +

                          + +
                          +Nodes +

                          + +

                          +BDDs, ADDs, and ZDDs are made of DdNode's. A DdNode +(node for short) is a structure with several fields. Those +that are of interest to the application that uses the CUDD package as +a black box are the variable index, the +reference count, and the value. The +remaining fields are pointers that connect nodes among themselves and +that are used to implement the unique table. (See +Section 3.2.2.) + +

                          +The index field holds the name of the variable that labels the +node. The index of a variable is a permanent attribute that reflects +the order of creation. Index 0 corresponds to +the variable created first. On a machine with 32-bit pointers, the +maximum number of variables is the largest value that can be stored in +an unsigned short integer minus 1. The largest index is reserved for +the constant nodes. When 64-bit pointers are +used, the maximum number of variables is the largest value that can be +stored in an unsigned integer minus 1. + +

                          +When variables are reordered to reduce the size of the decision +diagrams, the variables may shift in the order, but they retain their +indices. The package keeps track of the variable +permutation (and its inverse). The +application is not affected by variable reordering, +except in the following cases. + +

                            +
                          • If the application uses generators + (Cudd_ForeachCube and + Cudd_ForeachNode) and reordering is + enabled, then it must take care not to call any operation that may + create new nodes (and hence possibly trigger reordering). This is + because the cubes (i.e., paths) and nodes of a diagram change as a + result of reordering. +
                          • +
                          • If the application uses + Cudd_bddConstrain and reordering + takes place, then the property of Cudd_bddConstrain of + being an image restrictor is lost. +
                          • +
                          + +

                          +The CUDD package relies on garbage +collection to reclaim the memory used by diagrams that are no longer +in use. The scheme employed for garbage collection is based on keeping +a reference count for each node. The +references that are counted are both the internal references +(references from other nodes) and external references (typically +references from the calling environment). When an application creates +a new BDD, ADD, or ZDD, it must +increase its reference count explicitly, through a call to +Cudd_Ref. Similarly, when a diagram is no +longer needed, the application must call +Cudd_RecursiveDeref (for BDDs and +ADDs) or Cudd_RecursiveDerefZdd +(for ZDDs) to ``recycle'' the nodes of the +diagram. + +

                          +Terminal nodes carry a value. This is especially +important for ADDs. By default, the value is a double. +To change to something different (e.g., an integer), the +package must be modified and recompiled. Support for this process is +currently very rudimentary. + +

                          + +

                          + +
                          +The Manager +

                          + +

                          +All nodes used in BDDs, ADDs, and ZDDs are kept in special +hash tables called the +unique tables. Specifically, BDDs and ADDs +share the same unique table, whereas ZDDs have their own table. As +the name implies, the main purpose of the unique table is to guarantee +that each node is unique; that is, there is no other node labeled by +the same variable and with the same children. This uniqueness +property makes decision diagrams canonical. The +unique tables and some auxiliary data structures +make up the DdManager (manager for +short). Though the application that uses only the exported functions +needs not be concerned with most details of the manager, it has to +deal with the manager in the following sense. The application must +initialize the manager by calling an appropriate function. (See +Section 3.3.) Subsequently, it must pass a pointer to the +manager to all the functions that operate on decision diagrams. + +

                          +With the exception of a few statistical counters, there are no global variables in +the CUDD package. Therefore, it is quite possible to have multiple +managers simultaneously active in the same application.1 It is the pointers to +the managers that tell the functions on what data they should operate. + +

                          + +

                          + +
                          +Cache +

                          + +

                          +Efficient recursive manipulation of decision diagrams requires the use +of a table to store computed results. This table +is called here the cache because it is +effectively handled like a cache of variable but limited capacity. The +CUDD package starts by default with a small cache, and increases its +size until either no further benefit is achieved, or a limit size is +reached. The user can influence this policy by choosing initial and +limit values for the cache size. + +

                          +Too small a cache will cause frequent overwriting of useful results. +Too large a cache will cause overhead, because the whole cache is +scanned every time garbage collection takes +place. The optimal parameters depend on the specific application. The +default parameters work reasonably well for a large spectrum of +applications. + +

                          +The cache of the CUDD package is used by most recursive +functions of the package, and can be used by user-supplied functions +as well. (See Section 4.4.) + +

                          + +

                          + +
                          +Initializing and Shutting Down a DdManager +

                          + +

                          +To use the functions in the CUDD package, one has first to initialize +the package itself by calling Cudd_Init. +This function takes four parameters: + +

                            +
                          • numVars: It is the initial number of variables + for BDDs and ADDs. If the total number of variables needed by the + application is known, then it is slightly more efficient to create a + manager with that number of variables. If the number is unknown, it + can be set to 0, or to any other lower bound on the number of + variables. Requesting more variables than are actually needed is + not incorrect, but is not efficient. +
                          • +
                          • numVarsZ: It is the initial number of variables + for ZDDs. See Sections 3.9 and 3.11 for + a discussion of the value of this argument. +
                          • +
                          • numSlots: Determines the initial size of each + subtable of the unique table. + There is a subtable for each variable. The size of each subtable is + dynamically adjusted to reflect the number of nodes. It is normally + O.K. to use the default value for this parameter, which is + CUDD_UNIQUE_SLOTS. +
                          • +
                          • cacheSize: It is the initial size (number of + entries) of the cache. Its default value is + CUDD_CACHE_SLOTS. +
                          • +
                          • maxMemory: It is the target value for the + maximum memory occupation (in bytes). The package uses this value to + decide two parameters. + +
                              +
                            • the maximum size to which the cache will grow, regardless of + the hit rate or the size of the unique table. +
                            • +
                            • the maximum size to which growth of the unique table will be + preferred to garbage collection. + +
                            • +
                            + If maxMemory is set to 0, CUDD tries to guess a good value based on + the available memory. +
                          • +
                          +A typical call to Cudd_Init may look +like this: +
                          +  manager = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0);
                          +
                          +To reclaim all the memory associated with a manager, an application +must call Cudd_Quit. This is normally +done before exiting. + +

                          + +

                          + +
                          +Setting Parameters +

                          + +

                          +The package provides several functions to set the parameters that +control various functions. For instance, the package has an automatic +way of determining whether a larger unique table +would make the application run faster. In that case, the package +enters a ``fast growth'' mode in which resizing of +the unique subtables is favored over garbage +collection. When the unique table reaches a given size, however, the +package returns to the normal ``slow growth'' mode, even though the +conditions that caused the transition to fast growth still prevail. +The limit size for fast growth can be read by +Cudd_ReadLooseUpTo and changed by +Cudd_SetLooseUpTo. Similar pairs of +functions exist for several other parameters. See also +Section 4.8. + +

                          + +

                          + +
                          +Constant Functions +

                          + +

                          +The CUDD Package defines several constant functions. These functions +are created when the manager is initialized, and are accessible +through the manager itself. + +

                          + +

                          + +
                          +One, Logic Zero, and Arithmetic Zero +

                          + +

                          +The constant 1 (returned by +Cudd_ReadOne) is common to BDDs, ADDs, and +ZDDs. However, its meaning is different for ADDs and BDDs, on the one +hand, and ZDDs, on the other hand. The diagram consisting of the +constant 1 node only represents the constant 1 function for ADDs and +BDDs. For ZDDs, its meaning depends on the number of variables: It is +the conjunction of the complements of all variables. Conversely, the +representation of the constant 1 function depends on the number of +variables. The constant 1 function of $n$ variables is returned by +Cudd_ReadZddOne. + +

                          +The constant 0 is common to ADDs and ZDDs, but not to BDDs. The +BDD logic 0 is not associated with the constant 0 +function: It is obtained by complementation +(Cudd_Not) of the constant 1. (It is also +returned by Cudd_ReadLogicZero.) +All other constants are specific to ADDs. + +

                          + +

                          + +
                          +Predefined Constants +

                          + +

                          +Besides 0 (returned by Cudd_ReadZero) +and 1, the following constant functions are +created at initialization time. + +

                            +
                          1. PlusInfinity and + MinusInfinity: On computers implementing the + IEEE standard 754 for + floating-point arithmetic, these two constants + are set to the signed infinities. On the DEC + Alphas, the option -ieee_with_no_inexact or + -ieee_with_inexact must be passed to the DEC compiler to get + support of the IEEE standard. (The compiler still produces a + warning, but it can be ignored.) Compiling with + those options may cause substantial performance degradation on the + Evolution IV CPUs. (Especially if the application does use the + infinities.) The problem is reportedly solved in the Evolution V + CPUs. If gcc is used to compile CUDD on the + Alphas, the symbol HAVE_IEEE_754 + must be undefined. (See the Makefile for the + details.) The values of these constants are returned by + Cudd_ReadPlusInfinity and + Cudd_ReadMinusInfinity. +
                          2. +
                          3. Epsilon: This constant, initially set to + $10^{-12}$, is used in comparing floating point values for equality. + Its value is returned by + Cudd_ReadEpsilon, and it can be + modified by calling Cudd_SetEpsilon. + Unlike the other constants, it does not correspond to a node. +
                          4. +
                          + +

                          + +

                          + +
                          +Background +

                          + +

                          +The background value is a constant typically used +to represent non-existing arcs in graphs. Consider a shortest path +problem. Two nodes that are not connected by an arc can be regarded as +being joined by an arc of infinite length. In +shortest path problems, it is therefore convenient to set the +background value to PlusInfinity. In network flow +problems, on the other hand, two nodes not connected by an arc can be +regarded as joined by an arc of 0 capacity. +For these problems, therefore, it is more convenient to set the +background value to 0. In general, when representing +sparse matrices, the background value is the value that +is assumed implicitly. + +

                          +At initialization, the background value is set to 0. It can be read +with Cudd_ReadBackground, and +modified with Cudd_SetBackground. The background value +affects procedures that read sparse matrices/graphs +(Cudd_addRead and +Cudd_addHarwell), procedures that print +out sum-of-product expressions for +ADDs (Cudd_PrintMinterm), generators +of cubes (Cudd_ForeachCube), and +procedures that count minterms +(Cudd_CountMinterm). + +

                          + +

                          + +
                          +New Constants +

                          + +

                          +New constant can be created by calling +Cudd_addConst. This function will +retrieve the ADD for the desired constant, if it already +exist, or it will create a new one. Obviously, new constants should +only be used when manipulating ADDs. + +

                          + +

                          + +
                          +Creating Variables +

                          + +

                          +Decision diagrams are typically created by combining simpler decision +diagrams. The simplest decision diagrams, of course, cannot be +created in that way. Constant functions have been discussed in +Section 3.5. In this section we discuss the simple +variable functions, also known as projection functions. + +

                          + +

                          + +
                          +New BDD and ADD Variables +

                          + +

                          +The projection functions are distinct for +BDDs and ADDs. A projection function for BDDs consists of an internal +node with both outgoing arcs pointing to the constant 1. The +else arc is complemented. + +

                          +An ADD projection function, on the other hand, has the else +pointer directed to the arithmetic zero +function. One should never mix the two types of variables. BDD +variables should be used when manipulating BDDs, and ADD variables +should be used when manipulating ADDs. Three functions are provided +to create BDD variables: + +

                            +
                          • Cudd_bddIthVar: Returns + the projection function with index $i$. + If the function does not exist, it is created. +
                          • +
                          • Cudd_bddNewVar: Returns a + new projection function, whose index is + the largest index in use at the time of the call, plus 1. +
                          • +
                          • Cudd_bddNewVarAtLevel: + Similar to Cudd_bddNewVar. In + addition it allows to specify the position in the variable + order at which the new variable should be + inserted. In contrast, Cudd_bddNewVar + adds the new variable at the end of the order. +
                          • +
                          +The analogous functions for ADDs are +Cudd_addIthVar, +Cudd_addNewVar, and +Cudd_addNewVarAtLevel. + +

                          + +

                          + +
                          +New ZDD Variables +

                          + +

                          +Unlike the projection functions of BDDs and ADDs, the +projection functions of ZDDs have diagrams +with $n+1$ nodes, where $n$ is the number of variables. Therefore the +ZDDs of the projection functions change when new variables are added. +This will be discussed in Section 3.9. Here we assume +that the number of variables is fixed. The ZDD of the $i$-th +projection function is returned by +Cudd_zddIthVar. + +

                          + +

                          + +
                          +Basic BDD Manipulation +

                          + +

                          +Common manipulations of BDDs can be accomplished by calling +Cudd_bddIte. This function takes three BDDs, $f$, $g$, and +$h$, as arguments and computes +$f\cdot g + f'\cdot h$. Like all the +functions that create new BDDs or ADDs, Cudd_bddIte returns a result that must be +explicitly referenced by the caller. Cudd_bddIte can be used +to implement all two-argument boolean functions. However, the package +also provides Cudd_bddAnd as well as the +other two-operand boolean functions, which are slightly more efficient +when a two-operand function is called for. The following fragment of +code illustrates how to build the BDD for the function +$f =
+x_0'x_1'x_2'x_3'$. +

                          +	DdManager *manager;
                          +	DdNode *f, *var, *tmp;
                          +	int i;
                          +
                          +	...
                          +
                          +	f = Cudd_ReadOne(manager);
                          +	Cudd_Ref(f);
                          +	for (i = 3; i >= 0; i--) {
                          +	    var = Cudd_bddIthVar(manager,i);
                          +	    tmp = Cudd_bddAnd(manager,Cudd_Not(var),f);
                          +	    Cudd_Ref(tmp);
                          +	    Cudd_RecursiveDeref(manager,f);
                          +	    f = tmp;
                          +	}
                          +
                          +This example illustrates the following points: + +
                            +
                          • Intermediate results must be ``referenced'' and + ``dereferenced.'' However, var is a + projection function, and its + reference count is always greater than + 0. Therefore, there is no call to Cudd_Ref. +
                          • +
                          • The new f must be assigned to a temporary variable + (tmp in this example). If the result of + Cudd_bddAnd were assigned directly to + f, the old f would be lost, and there would be no + way to free its nodes. +
                          • +
                          • The statement f = tmp has the same effect as: +
                            +	    f = tmp;
                            +	    Cudd_Ref(f);
                            +	    Cudd_RecursiveDeref(manager,tmp);
                            +
                            + but is more efficient. The reference is + ``passed'' from tmp to f, and tmp is now + ready to be reutilized. +
                          • +
                          • It is normally more efficient to build BDDs ``bottom-up.'' This + is why the loop goes from 3 to 0. Notice, however, that after + variable reordering, higher index does not necessarily mean ``closer + to the bottom.'' Of course, in this simple example, efficiency is + not a concern. +
                          • +
                          • Had we wanted to conjoin the variables in a bottom-up fashion + even after reordering, we should have used + Cudd_ReadInvPerm. One has to be + careful, though, to fix the order of conjunction before entering the + loop. Otherwise, if reordering takes place, it is possible to use + one variable twice and skip another variable. +
                          • +
                          + +

                          + +

                          + +
                          +Basic ADD Manipulation +

                          + +

                          +The most common way to manipulate ADDs is via +Cudd_addApply. This function can apply a +wide variety of operators to a pair of ADDs. Among the available +operators are addition, multiplication, division, minimum, maximum, +and boolean operators that work on ADDs whose leaves are restricted to +0 and 1 (0-1 ADDs). + +

                          +The following fragment of code illustrates how to build the ADD for +the function +$f = 5x_0x_1x_2x_3$. +

                          +	DdManager *manager;
                          +	DdNode *f, *var, *tmp;
                          +	int i;
                          +
                          +	...
                          +
                          +	f = Cudd_addConst(manager,5);
                          +	Cudd_Ref(f);
                          +	for (i = 3; i >= 0; i--) {
                          +	    var = Cudd_addIthVar(manager,i);
                          +	    Cudd_Ref(var);
                          +	    tmp = Cudd_addApply(manager,Cudd_addTimes,var,f);
                          +	    Cudd_Ref(tmp);
                          +	    Cudd_RecursiveDeref(manager,f);
                          +	    Cudd_RecursiveDeref(manager,var);
                          +	    f = tmp;
                          +	}
                          +
                          +This example, contrasted to the example of BDD manipulation, +illustrates the following points: + +
                            +
                          • The ADD projection function are not + maintained by the manager. It is therefore necessary to + reference and + dereference them. +
                          • +
                          • The product of two ADDs is computed by calling + Cudd_addApply with + Cudd_addTimes as parameter. There is + no ``apply'' function for BDDs, because + Cudd_bddAnd and + Cudd_bddXor plus complementation are + sufficient to implement all two-argument boolean functions. +
                          • +
                          + +

                          + +

                          + +
                          +Basic ZDD Manipulation +

                          + +

                          +ZDDs are often generated by converting +existing BDDs. (See Section 3.11.) However, it is also +possible to build ZDDs by applying boolean operators to other ZDDs, +starting from constants and projection +functions. The following fragment of code illustrates how to build +the ZDD for the function +$f = x_0'+x_1'+x_2'+x_3'$. We assume that the +four variables already exist in the manager when the ZDD for $f$ is +built. Note the use of De Morgan's law. +

                          +	DdManager *manager;
                          +	DdNode *f, *var, *tmp;
                          +	int i;
                          +
                          +	manager = Cudd_Init(0,4,CUDD_UNIQUE_SLOTS,
                          +			    CUDD_CACHE_SLOTS,0);
                          +	...
                          +
                          +	tmp = Cudd_ReadZddOne(manager,0);
                          +	Cudd_Ref(tmp);
                          +	for (i = 3; i >= 0; i--) {
                          +	    var = Cudd_zddIthVar(manager,i);
                          +	    Cudd_Ref(var);
                          +	    f = Cudd_zddIntersect(manager,var,tmp);
                          +	    Cudd_Ref(f);
                          +	    Cudd_RecursiveDerefZdd(manager,tmp);
                          +	    Cudd_RecursiveDerefZdd(manager,var);
                          +	    tmp = f;
                          +	}
                          +	f = Cudd_zddDiff(manager,Cudd_ReadZddOne(manager,0),tmp);
                          +	Cudd_Ref(f);
                          +	Cudd_RecursiveDerefZdd(manager,tmp);
                          +
                          +This example illustrates the following points: + +
                            +
                          • The projection functions are + referenced, because they are not maintained by the manager. +
                          • +
                          • Complementation is obtained by subtracting from the constant 1 + function. +
                          • +
                          • The result of Cudd_ReadZddOne + does not require referencing. +
                          • +
                          +CUDD provides functions for the manipulation of +covers represented by ZDDs. For instance, +Cudd_zddIsop builds a ZDD representing an +irredundant sum of products for the +incompletely specified function defined by the two BDDs $L$ and $U$. +Cudd_zddWeakDiv performs the weak +division of two covers given as ZDDs. These functions expect the two +ZDD variables corresponding to the two literals of the function +variable to be adjacent. One has to create variable groups (see +Section 3.14) for reordering of +the ZDD variables to work. BDD automatic reordering is safe even +without groups: If realignment of ZDD and ADD/BDD variables is +requested (see Section 3.15) groups will be kept +adjacent. + +

                          + +

                          + + +
                          +Converting ADDs to BDDs and Vice Versa +

                          + +

                          +Several procedures are provided to convert ADDs to BDDs, according to +different criteria. +(Cudd_addBddPattern, +Cudd_addBddInterval, and +Cudd_addBddThreshold.) The +conversion from BDDs to ADDs +(Cudd_BddToAdd) is based on the simple +principle of mapping the logical 0 and 1 on the +arithmetic 0 and 1. It is also possible to +convert an ADD with integer values (more precisely, floating point +numbers with 0 fractional part) to an array of BDDs by repeatedly +calling Cudd_addIthBit. + +

                          + +

                          + + +
                          +Converting BDDs to ZDDs and Vice Versa +

                          + +

                          +Many applications first build a set of BDDs and then derive ZDDs from +the BDDs. These applications should create the manager with 0 +ZDD variables and create the BDDs. Then they should call +Cudd_zddVarsFromBddVars to +create the necessary ZDD variables--whose number is likely to be +known once the BDDs are available. This approach eliminates the +difficulties that arise when the number of ZDD variables changes while +ZDDs are being built. + +

                          +The simplest conversion from BDDs to ZDDs is a simple change of +representation, which preserves the functions. Simply put, given a BDD +for $f$, a ZDD for $f$ is requested. In this case the correspondence +between the BDD variables and ZDD variables is one-to-one. Hence, +Cudd_zddVarsFromBddVars should be called with the +multiplicity parameter equal to 1. The conversion proper can +then be performed by calling +Cudd_zddPortFromBdd. The inverse +transformation is performed by +Cudd_zddPortToBdd. + +

                          +ZDDs are quite often used for the representation of +covers. This is normally done by +associating two ZDD variables to each variable of the function. (And +hence, typically, to each BDD variable.) One ZDD variable is +associated with the positive literal of the BDD variable, while the +other ZDD variable is associated with the negative literal. A call to +Cudd_zddVarsFromBddVars with +multiplicity equal to 2 will associate to BDD variable $i$ the +two ZDD variables $2i$ and $2i+1$. + +

                          +If a BDD variable group tree exists when +Cudd_zddVarsFromBddVars is called (see +Section 3.13) the function generates a ZDD variable group +tree consistent to it. In any case, all the ZDD variables derived +from the same BDD variable are clustered into a group. + +

                          +If the ZDD for $f$ is created and later a new ZDD variable is added to +the manager, the function represented by the existing ZDD changes. +Suppose, for instance, that two variables are initially created, and +that the ZDD for $f = x_0 + x_1$ is built. If a third variable is +added, say $x_2$, then the ZDD represents +$g = (x_0 + x_1) x_2'$ +instead. This change in function obviously applies regardless of what +use is made of the ZDD. However, if the ZDD is used to represent a +cover, the cover itself is not changed by the +addition of new variable. (What changes is the +characteristic function of the cover.) + +

                          + +

                          + +
                          +Variable Reordering for BDDs and ADDs +

                          + +

                          +The CUDD package provides a rich set of +dynamic reordering algorithms. Some of them +are slight variations of existing techniques +[16,6,2,10,15,11]; some +others have been developed specifically for this package +[14,13]. + +

                          +Reordering affects a unique table. This means that +BDDs and ADDs, which share the same unique table are simultaneously +reordered. ZDDs, on the other hand, are reordered separately. In the +following we discuss the reordering of BDDs and ADDs. Reordering for +ZDDs is the subject of Section 3.14. + +

                          +Reordering of the variables can be invoked directly by the application +by calling Cudd_ReduceHeap. Or it can +be automatically triggered by the package when the number of nodes has +reached a given threshold. (The threshold +is initialized and automatically adjusted after each reordering by the +package.) To enable automatic dynamic reordering (also called +asynchronous dynamic reordering +in this document) the application must call +Cudd_AutodynEnable. Automatic +dynamic reordering can subsequently be disabled by calling +Cudd_AutodynDisable. + +

                          +All reordering methods are available in both the case of direct call +to Cudd_ReduceHeap and the case of +automatic invocation. For many methods, the reordering procedure is +iterated until no further improvement is obtained. We call these +methods the converging methods. +When constraints are imposed on the relative position of variables +(see Section 3.13) the reordering methods apply inside the +groups. The groups themselves are reordered +by sifting. Each method is identified by a +constant of the enumerated type +Cudd_ReorderingType +defined in cudd.h (the external +header file of the CUDD package): + +

                          +

                          +
                          CUDD_REORDER_NONE:
                          +
                          This method + causes no reordering. +
                          +
                          CUDD_REORDER_SAME:
                          +
                          If passed to + Cudd_AutodynEnable, this + method leaves the current method for automatic reordering unchanged. + If passed to Cudd_ReduceHeap, + this method causes the current method for automatic reordering to be + used. +
                          +
                          CUDD_REORDER_RANDOM:
                          +
                          Pairs of + variables are randomly chosen, and swapped in the order. The swap is + performed by a series of swaps of adjacent variables. The best order + among those obtained by the series of swaps is retained. The number + of pairs chosen for swapping equals the + number of variables in the diagram. +
                          +
                          CUDD_REORDER_RANDOM_PIVOT:
                          +
                          Same as CUDD_REORDER_RANDOM, but the two variables are chosen so + that the first is above the variable with the largest number of + nodes, and the second is below that variable. In case there are + several variables tied for the maximum number of nodes, the one + closest to the root is used. +
                          +
                          CUDD_REORDER_SIFT:
                          +
                          This method is + an implementation of Rudell's sifting + algorithm [16]. A simplified description of sifting is as + follows: Each variable is considered in turn. A variable is moved up + and down in the order so that it takes all possible positions. The + best position is identified and the variable is returned to that + position. + +

                          +In reality, things are a bit more complicated. For instance, there + is a limit on the number of variables that will be sifted. This + limit can be read with + Cudd_ReadSiftMaxVar and set with + Cudd_SetSiftMaxVar. In addition, + if the diagram grows too much while moving a variable up or down, + that movement is terminated before the variable has reached one end + of the order. The maximum ratio by which the diagram is allowed to + grow while a variable is being sifted can be read with + Cudd_ReadMaxGrowth and set with + Cudd_SetMaxGrowth. +

                          +
                          CUDD_REORDER_SIFT_CONVERGE:
                          +
                          This is the converging variant of + CUDD_REORDER_SIFT. +
                          +
                          CUDD_REORDER_SYMM_SIFT:
                          +
                          This method is an implementation of + symmetric sifting [14]. It is + similar to sifting, with one addition: Variables that become + adjacent during sifting are tested for symmetry. If + they are symmetric, they are linked in a group. Sifting then + continues with a group being moved, instead of a single variable. + After symmetric sifting has been run, + Cudd_SymmProfile can be called to + report on the symmetry groups found. (Both positive and negative + symmetries are reported.) +
                          +
                          CUDD_REORDER_SYMM_SIFT_CONV:
                          +
                          This is the converging variant of + CUDD_REORDER_SYMM_SIFT. +
                          +
                          CUDD_REORDER_GROUP_SIFT:
                          +
                          This method is an implementation of group + sifting [13]. It is similar to symmetric sifting, but + aggregation is not restricted to symmetric + variables. +
                          +
                          CUDD_REORDER_GROUP_SIFT_CONV:
                          +
                          This method repeats until convergence the combination of + CUDD_REORDER_GROUP_SIFT and CUDD_REORDER_WINDOW4. +
                          +
                          CUDD_REORDER_WINDOW2:
                          +
                          This + method implements the window permutation + approach of Fujita [8] and Ishiura [10]. + The size of the window is 2. +
                          +
                          CUDD_REORDER_WINDOW3:
                          +
                          Similar + to CUDD_REORDER_WINDOW2, but with a window of size 3. +
                          +
                          CUDD_REORDER_WINDOW4:
                          +
                          Similar + to CUDD_REORDER_WINDOW2, but with a window of size 4. +
                          +
                          CUDD_REORDER_WINDOW2_CONV:
                          +
                          This is the converging variant of + CUDD_REORDER_WINDOW2. +
                          +
                          CUDD_REORDER_WINDOW3_CONV:
                          +
                          This is the converging variant of CUDD_REORDER_WINDOW3. +
                          +
                          CUDD_REORDER_WINDOW4_CONV:
                          +
                          This is the converging variant of CUDD_REORDER_WINDOW4. +
                          +
                          CUDD_REORDER_ANNEALING:
                          +
                          This + method is an implementation of simulated + annealing for variable + ordering, vaguely resemblant of the algorithm of [2]. + This method is potentially very slow. +
                          +
                          CUDD_REORDER_GENETIC:
                          +
                          This + method is an implementation of a genetic + algorithm for variable ordering, inspired by the work of Drechsler + [6]. This method is potentially very slow. +
                          +
                          CUDD_REORDER_EXACT:
                          +
                          This method + implements a dynamic programming approach to + exact reordering + [9,7,10], with improvements described in + [11]. It only stores one BDD at the time. Therefore, it is + relatively efficient in terms of memory. Compared to other + reordering strategies, it is very slow, and is not recommended for + more than 16 variables. +
                          +
                          +So far we have described methods whereby the package selects an order +automatically. A given order of the variables can also be imposed by +calling Cudd_ShuffleHeap. + +

                          + +

                          + +
                          +Grouping Variables +

                          + +

                          +CUDD allows the application to specify constraints on the positions of +group of variables. It is possible to request that a group of +contiguous variables be kept contiguous by the reordering procedures. +It is also possible to request that the relative order of some groups +of variables be left unchanged. The constraints on the order are +specified by means of a tree, which is created in +one of two ways: + +

                            +
                          • By calling Cudd_MakeTreeNode. +
                          • +
                          • By calling the functions of the MTR library + (part of the distribution), and by registering the result with the + manager using Cudd_SetTree. The current + tree registered with the manager can be read with + Cudd_ReadTree. +
                          • +
                          + +

                          +Each node in the tree represents a range of variables. The lower bound +of the range is given by the low field of the node, and the +size of the group is given by the size field of the +node.2 The variables +in each range are kept contiguous. Furthermore, if a node is marked +with the MTR_FIXED flag, then the relative order of +the variable ranges associated to its children is not changed. As an +example, suppose the initial variable order is: +

                          +	x0, y0, z0, x1, y1, z1, ... , x9, y9, z9.
                          +
                          +Suppose we want to keep each group of three variables with the same +index (e.g., x3, y3, z3) contiguous, while allowing the package +to change the order of the groups. We can accomplish this with the +following code: +
                          +	for (i = 0; i < 10; i++) {
                          +	    (void) Cudd_MakeTreeNode(manager,i*3,3,MTR_DEFAULT);
                          +	}
                          +
                          +If we want to keep the order within each group of variables +fixed (i.e., x before y before z) we need to +change MTR_DEFAULT into MTR_FIXED. + +

                          +The low parameter passed to +Cudd_MakeTreeNode is the index of a +variable (as opposed to its level or position in the order). The +group tree can be created at any time. The +result obviously depends on the variable order in effect at creation +time. + +

                          +It is possible to create a variable group tree also before the +variables themselves are created. The package assumes in this case +that the index of the variables not yet in existence will equal their +position in the order when they are created. Therefore, applications +that rely on +Cudd_bddNewVarAtLevel or +Cudd_addNewVarAtLevel to create +new variables have to create the variables before they group them. + +

                          +The reordering procedure will skip all groups whose variables are not +yet in existence. For groups that are only partially in existence, the +reordering procedure will try to reorder the variables already +instantiated, without violating the adjacency constraints. + +

                          + +

                          + +
                          +Variable Reordering for ZDDs +

                          + +

                          +Reordering of ZDDs is done in much the same way as the reordering of +BDDs and ADDs. The functions corresponding to Cudd_ReduceHeap +and Cudd_ShuffleHeap are +Cudd_zddReduceHeap and +Cudd_zddShuffleHeap. To enable +dynamic reordering, the application must +call Cudd_AutodynEnableZdd, and +to disable dynamic reordering, it must call +Cudd_AutodynDisableZdd. In the +current implementation, however, the choice of reordering methods for +ZDDs is more limited. Specifically, these methods are available: + +

                          +

                          +
                          CUDD_REORDER_NONE;
                          +
                          +
                          +
                          CUDD_REORDER_SAME;
                          +
                          +
                          +
                          CUDD_REORDER_RANDOM;
                          +
                          +
                          +
                          CUDD_REORDER_RANDOM_PIVOT;
                          +
                          +
                          +
                          CUDD_REORDER_SIFT;
                          +
                          +
                          +
                          CUDD_REORDER_SIFT_CONVERGE;
                          +
                          +
                          +
                          CUDD_REORDER_SYMM_SIFT;
                          +
                          +
                          +
                          CUDD_REORDER_SYMM_SIFT_CONV.
                          +
                          +
                          +
                          + +

                          +To create ZDD variable groups, the application calls +Cudd_MakeZddTreeNode. + +

                          + +

                          + +
                          +Keeping Consistent Variable Orders for BDDs and ZDDs +

                          + +

                          +Several applications that manipulate both BDDs and ZDDs benefit from +keeping a fixed correspondence between the order of the BDD variables +and the order of the ZDD variables. If each BDD variable corresponds +to a group of ZDD variables, then it is often desirable that the +groups of ZDD variables be in the same order as the corresponding BDD +variables. CUDD allows the ZDD order to track the BDD order and vice +versa. To have the ZDD order track the BDD order, the application +calls Cudd_zddRealignEnable. The +effect of this call can be reversed by calling +Cudd_zddRealignDisable. When +ZDD realignment is in effect, automatic reordering of ZDDs should be +disabled. + +

                          + +

                          + +
                          +Hooks +

                          + +

                          +Hooks in CUDD are lists of application-specified functions to be run on +certain occasions. Each hook is identified by a constant of the +enumerated type Cudd_HookType. In Version +2.5.0 hooks are defined for these occasions: + +

                            +
                          • before garbage collection (CUDD_PRE_GC_HOOK); +
                          • +
                          • after garbage collection (CUDD_POST_GC_HOOK); +
                          • +
                          • before variable reordering (CUDD_PRE_REORDERING_HOOK); +
                          • +
                          • after variable reordering (CUDD_POST_REORDERING_HOOK). +
                          • +
                          +The current implementation of hooks is experimental. A function added +to a hook receives a pointer to the manager, a pointer to a constant +string, and a pointer to void as arguments; it must return 1 if +successful; 0 otherwise. The second argument is one of ``DD,'' +``BDD,'' and ``ZDD.'' This allows the hook functions to tell the type +of diagram for which reordering or garbage collection takes place. The +third argument varies depending on the hook. The hook functions called +before or after garbage collection do +not use it. The hook functions called before +reordering are passed, in addition to the +pointer to the manager, also the method used for reordering. The hook +functions called after reordering are passed the start time. To add a +function to a hook, one uses Cudd_AddHook. +The function of a given hook +are called in the order in which they were added to the hook. For +sample hook functions, one may look at +Cudd_StdPreReordHook and +Cudd_StdPostReordHook. + +

                          + +

                          + +
                          +Timeouts and Limits +

                          + +

                          +It is possible to set a time limit for a manger with +Cudd_SetTimeLimit. Once set, the +time available to the manager can be modified through other API +functions. CUDD checks for expiration periodically. When time has +expired, it returns NULL from the call in progress, but it leaves the +manager in a consistent state. The invoking application must be +designed to handle the NULL values returned. + +

                          +When reordering, if a timout is approaching, CUDD will quit reordering +to give the application a chance to finish some computation. + +

                          +It is also possible to invoke some functions that return NULL if they +cannot complete without creating more than a set number of nodes. +See, for instance, Cudd_bddAndLimit. + +

                          + +

                          + +
                          +The SIS/VIS Interface +

                          + +

                          +The CUDD package contains interface functions that emulate the +behavior of the original BDD package used in SIS [17] and +in the newer +VIS +[4]. How to build VIS with CUDD is described +in the installation documents of VIS. (Version 1.1 and later.) + +

                          + +

                          + +
                          +Using the CUDD Package in SIS +

                          + +

                          +This section describes how to build SIS with the CUDD package. Let +SISDIR designate the root of the directory +hierarchy where the sources for SIS reside. Let +CUDDDIR be the root of the directory hierarchy +where the distribution of the CUDD package resides. To build SIS with +the CUDD package, follow these steps. + +

                            +
                          1. Create directories SISDIR/sis/cudd and + SISDIR/sis/mtr. +
                          2. +
                          3. Copy all files from CUDDDIR/cudd and + CUDDDIR/sis to SISDIR/sis/cudd and all files from + CUDDDIR/mtr to SISDIR/sis/mtr. +
                          4. +
                          5. Copy CUDDDIR/cudd/doc/cudd.doc to + SISDIR/sis/cudd; also copy CUDDDIR/mtr/doc/mtr.doc + to SISDIR/sis/mtr. +
                          6. +
                          7. In SISDIR/sis/cudd make bdd.h a symbolic link + to cuddBdd.h. (That is: ln -s cuddBdd.h bdd.h.) +
                          8. +
                          9. In SISDIR/sis/cudd delete Makefile and rename + Makefile.sis as Makefile. Do the same in + SISDIR/sis/mtr. +
                          10. +
                          11. Copy CUDDDIR/sis/st.[ch] and CUDDDIR/st/doc/st.doc + to SISDIR/sis/st. (This will overwrite the original files: You + may want to save them beforehand.) +
                          12. +
                          13. From CUDDDIR/util copy datalimit.c to + SISDIR/sis/util. Update util.h and + Makefile in SISDIR/sis/util. Specifically, add the + declaration EXTERN long getSoftDataLimit(); to + util.h and add datalimit.c to the list of source + files (PSRC) in Makefile. +
                          14. +
                          15. In SISDIR/sis remove the link from bdd to + bdd_cmu or bdd_ucb (that is, rm bdd) + and make bdd a symbolic link to cudd. (That is: + ln -s cudd bdd.) +
                          16. +
                          17. Still in SISDIR/sis, edit Makefile, Makefile.oct, and Makefile.nooct. In all three files add + mtr to the list of directories to be made (DIRS). +
                          18. +
                          19. In SISDIR/sis/include make mtr.h a symbolic + link to ../mtr/mtr.h. +
                          20. +
                          21. In SISDIR/sis/doc make cudd.doc a symbolic + link to ../cudd/cudd.doc and mtr.doc a symbolic + link to ../mtr/mtr.doc. (That is: ln -s + ../cudd/cudd.doc .; ln -s ../mtr/mtr.doc ..) +
                          22. +
                          23. From SISDIR do make clean followed by + make -i. This should create a working copy of SIS that + uses the CUDD package. +
                          24. +
                          + +

                          +The replacement for the st library is because the version +shipped with the CUDD package tests for out-of-memory conditions. +Notice that the version of the st library to be used for +replacement is not the one used for the normal build, because the +latter has been modified for C++ compatibility. The above installation +procedure has been tested on SIS 1.3. SIS can be obtained via +anonymous FTP from +ic.eecs.berkeley.edu. +To build SIS 1.3, you need sis-1.2.tar.Z and +sis-1.2.patch1.Z. When compiling on a DEC Alpha, you should add the -ieee_with_no_inexact flag. +(See Section 3.5.2.) Refer to the Makefile +in the top level directory of the distribution for how to compile with +32-bit pointers. + +

                          + +

                          + +
                          +Writing Decision Diagrams to a File +

                          + +

                          +The CUDD package provides several functions to write decision diagrams +to a file. Cudd_DumpBlif writes a +file in blif format. It is restricted to BDDs. The diagrams +are written as a network of multiplexers, one multiplexer for each +internal node of the BDD. + +

                          +Cudd_DumpDot produces input suitable to +the graph-drawing program +dot +written by Eleftherios Koutsofios and Stephen C. North. An example of +drawing produced by dot from the output of Cudd_DumpDot is +shown in Figure 1. It is restricted to BDDs and ADDs. + +

                          + + + +
                          Figure 1: +A BDD representing a phase constraint for the optimization of + fixed-polarity Reed-Muller forms. The label of each node is the + unique part of the node address. All nodes on the same level + correspond to the same variable, whose name is shown at the left of + the diagram. Dotted lines indicate complement + arcs. Dashed lines indicate regular ``else'' + arcs.
                          +
                          +\includegraphics[height=15.5cm]{phase.ps}
                          +
                          + +Cudd_zddDumpDot is the analog of +Cudd_DumpDot for ZDDs. + +

                          +Cudd_DumpDaVinci produces input +suitable to the graph-drawing program +daVinci +developed at the University of Bremen. It is restricted to BDDs and +ADDs. + +

                          +Functions are also available to produce the input format of +DDcal (see Section 2.2) and factored forms. + +

                          + +

                          + +
                          +Saving and Restoring BDDs +

                          + +

                          +The +dddmp +library by Gianpiero Cabodi and Stefano Quer +allows a CUDD application to save BDDs to disk in compact form for +later retrieval. See the library's own documentation for the details. + +

                          +


                          + + +next + +up + +previous + +index +
                          + Next: Programmer's Manual + Up: CUDD: CU Decision Diagram + Previous: How to Get CUDD +   Index + +
                          +Fabio Somenzi +2012-02-04 +
                          + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node4.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node4.html new file mode 100644 index 000000000..e1697b331 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node4.html @@ -0,0 +1,1165 @@ + + + + + +Programmer's Manual + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                          + Next: The C++ Interface + Up: CUDD: CU Decision Diagram + Previous: User's Manual +   Index +
                          +
                          + + +Subsections + + + +
                          + +

                          + +
                          +Programmer's Manual +

                          + +

                          +This section provides additional detail on the working of the CUDD +package and on the programming conventions followed in its writing. +The additional detail should help those who want to write procedures +that directly manipulate the CUDD data structures. + +

                          + +

                          + +
                          +Compiling and Linking +

                          + +

                          +If you plan to use the CUDD package as a clear box +(for instance, you want to write a procedure that traverses a decision +diagram) you need to add +

                          +#include "cuddInt.h"
                          +
                          +to your source files. In addition, you should link libcudd.a to +your executable. Some platforms require specific compiler and linker +flags. Refer to the Makefile in the top level directory of +the distribution. + +

                          + +

                          + +
                          +Reference Counts +

                          + +

                          +Garbage collection in the CUDD package is +based on reference counts. Each node stores the sum of the external +references and internal references. An internal BDD or ADD node is +created by a call to cuddUniqueInter, an +internal ZDD node is created by a call to +cuddUniqueInterZdd, and a +terminal node is created by a call to +cuddUniqueConst. If the node returned by +these functions is new, its reference count is zero. The function +that calls cuddUniqueInter, +cuddUniqueInterZdd, or +cuddUniqueConst is responsible for +increasing the reference count of the node. This is accomplished by +calling Cudd_Ref. + +

                          +When a function is no longer needed by an application, the memory used +by its diagram can be recycled by calling +Cudd_RecursiveDeref (BDDs and ADDs) +or Cudd_RecursiveDerefZdd +(ZDDs). These functions decrease the reference count of the node passed to them. If the reference count +becomes 0, then two things happen: + +

                            +
                          1. The node is declared ``dead;'' this entails + increasing the counters of the dead + nodes. (One counter for the subtable to which the + node belongs, and one global counter for the + unique table to which the node belongs.) The + node itself is not affected. +
                          2. +
                          3. The function is recursively called on the two children of the + node. +
                          4. +
                          +For instance, if the diagram of a function does not share any nodes +with other diagrams, then calling +Cudd_RecursiveDeref or +Cudd_RecursiveDerefZdd on its +root will cause all the nodes of the diagram to become dead. + +

                          +When the number of dead nodes reaches a given level (dynamically +determined by the package) garbage collection takes place. During +garbage collection dead nodes are returned +to the node free list. + +

                          +When a new node is created, it is important to increase its +reference count before one of the two +following events occurs: + +

                            +
                          1. A call to cuddUniqueInter, + to cuddUniqueInterZdd, to + cuddUniqueConst, or to a + function that may eventually cause a call to them. +
                          2. +
                          3. A call to + Cudd_RecursiveDeref, to + Cudd_RecursiveDerefZdd, or to + a function that may eventually cause a call to them. +
                          4. +
                          +In practice, it is recommended to increase the reference count as soon +as the returned pointer has been tested for not being NULL. + +

                          + +

                          + +
                          +NULL Return Values +

                          + +

                          +The interface to the memory management functions (e.g., malloc) used +by CUDD intercepts NULL return values and calls a handler. The +default handler exits with an error message. If the application does +not install another handler, therefore, a NULL return value from an +exported function of CUDD signals an internal error. + +

                          +If the aplication, however, installs another handler that lets +execution continue, a NULL pointer returned by an exported function +typically indicates that the process has run out of memory. +Cudd_ReadErrorCode can be used to +ascertain the nature of the problem. + +

                          +An application that tests for the result being NULL can try some +remedial action, if it runs out of memory. For instance, it may free +some memory that is not strictly necessary, or try a slower algorithm +that takes less space. As an example, CUDD overrides the default +handler when trying to enlarge the cache or increase the number of +slots of the unique table. If the allocation fails, the package prints +out a message and continues without resizing the cache. + +

                          + +

                          + +
                          +Cudd_RecursiveDeref vs. Cudd_Deref +

                          + +

                          +It is often the case that a recursive procedure has to protect the +result it is going to return, while it disposes of intermediate +results. (See the previous discussion on when to increase reference +counts.) Once the intermediate results have been properly disposed +of, the final result must be returned to its pristine state, in which +the root node may have a reference count of 0. One cannot use +Cudd_RecursiveDeref (or +Cudd_RecursiveDerefZdd) for this purpose, because it may +erroneously make some nodes dead. Therefore, the package provides a +different function: Cudd_Deref. This +function is not recursive, and does not change the dead node counts. +Its use is almost exclusively the one just described: Decreasing the +reference count of the root of the final result before returning from +a recursive procedure. + +

                          + +

                          + +
                          +When Increasing the Reference Count is Unnecessary +

                          + +

                          +When a copy of a predefined constant or of a +simple BDD variable is needed for comparison purposes, then calling +Cudd_Ref is not necessary, because these +simple functions are guaranteed to have reference counts greater than +0 at all times. If no call to Cudd_Ref is made, then no +attempt to free the diagram by calling +Cudd_RecursiveDeref or +Cudd_RecursiveDerefZdd should be +made. + +

                          + +

                          + +
                          +Saturating Increments and Decrements +

                          + +

                          +On 32-bit machines, the CUDD package stores the +reference counts in unsigned short int's. +For large diagrams, it is possible for some reference counts to exceed +the capacity of an unsigned short int. Therefore, increments and +decrements of reference counts are saturating. This means that +once a reference count has reached the maximum possible value, it is +no longer changed by calls to Cudd_Ref, +Cudd_RecursiveDeref, +Cudd_RecursiveDerefZdd, or +Cudd_Deref. As a consequence, some nodes +that have no references may not be declared dead. This may result in a +small waste of memory, which is normally more than offset by the +reduction in size of the node structure. + +

                          +When using 64-bit pointers, there is normally no memory advantage from +using short int's instead of int's in a DdNode. Therefore, increments +and decrements are not saturating in that case. What option is in +effect depends on two macros, SIZEOF_VOID_P +and SIZEOF_INT, defined in the external +header file (cudd.h). The +increments and decrements of the reference counts are performed using +two macros: cuddSatInc and +cuddSatDec, whose definitions depend on +SIZEOF_VOID_P and +SIZEOF_INT. + +

                          + +

                          + +
                          +Complement Arcs +

                          + +

                          +If ADDs are restricted to use only the constants 0 and 1, they behave +like BDDs without complement arcs. It is normally easier to write code +that manipulates 0-1 ADDs, than to write code for BDDs. However, +complementation is trivial with complement arcs, and is not trivial +without. As a consequence, with complement arcs it is possible to +check for more terminal cases and it is possible to apply De Morgan's +laws to reduce problems that are essentially identical to a standard +form. This in turn increases the utilization of the cache. + +

                          +The complement attribute is stored in the least significant bit of the +``else'' pointer of each node. An external pointer to a function can +also be complemented. The ``then'' pointer to a node, on the other +hand, is always regular. It is a mistake to +use a complement pointer as it is to address +memory. Instead, it is always necessary to obtain a regular version +of it. This is normally done by calling +Cudd_Regular. It is also a mistake to +call cuddUniqueInter with a complemented +``then'' child as argument. The calling procedure must apply De +Morgan's laws by complementing both pointers passed to +cuddUniqueInter and then taking the +complement of the result. + +

                          + +

                          + +
                          +The Cache +

                          + +

                          +Each entry of the cache consists of five fields: The operator, three +pointers to operands and a pointer to the result. The operator and the +three pointers to the operands are combined to form three words. The +combination relies on two facts: + +

                            +
                          • Most operations have one or two operands. A few bits are + sufficient to discriminate all three-operands operations. +
                          • +
                          • All nodes are aligned to 16-byte boundaries. (32-byte boundaries + if 64-bit pointers are used.) Hence, there are a few bits available + to distinguish the three-operand operations from te others and to + assign unique codes to them. +
                          • +
                          + +

                          +The cache does not contribute to the reference + +counts of the nodes. The fact that the cache contains a +pointer to a node does not imply that the node is alive. Instead, when +garbage collection takes place, all entries +of the cache pointing to dead nodes are cleared. + +

                          +The cache is also cleared (of all entries) when dynamic +reordering takes place. In both cases, the entries +removed from the cache are about to become invalid. + +

                          +All operands and results in a cache entry must be pointers to +DdNodes. If a function produces more than one result, +or uses more than three arguments, there are currently two solutions: + +

                            +
                          • Build a separate, local, cache. (Using, for + instance, the st library.) +
                          • +
                          • Combine multiple results, or multiple operands, into a single + diagram, by building a ``multiplexing structure'' with reserved + variables. +
                          • +
                          +Support of the former solution is under development. (See +cuddLCache.c..) Support for the latter solution may be +provided in future versions of the package. + +

                          +There are three sets of interface functions to +the cache. The first set is for functions with three operands: +cuddCacheInsert and +cuddCacheLookup. The second set is for +functions with two operands: +cuddCacheInsert2 and +cuddCacheLookup2. The second set is for +functions with one operand: +cuddCacheInsert1 and +cuddCacheLookup1. The second set is +slightly faster than the first, and the third set is slightly faster +than the second. + +

                          + +

                          + +
                          +Cache Sizing +

                          + +

                          +The size of the cache can increase during the execution of an +application. (There is currently no way to decrease the size of the +cache, though it would not be difficult to do it.) When a cache miss +occurs, the package uses the following criteria to decide whether to +resize the cache: + +

                            +
                          1. If the cache already exceeds the limit given by the + maxCache field of the manager, no resizing + takes place. The limit is the minimum of two values: a value set at + initialization time and possibly modified by the application, which + constitutes the hard limit beyond which the cache will never grow; + and a number that depends on the current total number of slots in + the unique table. +
                          2. +
                          3. If the cache is not too large already, resizing is decided based + on the hit rate. The policy adopted by the CUDD package is + ``reward-based.'' If the cache hit + rate is high, then it is worthwhile to increase the size of the + cache. +
                          4. +
                          +When resizing takes place, the statistical counters used to compute the hit rate are reinitialized so as to +prevent immediate resizing. The number of entries is doubled. + +

                          +The rationale for the ``reward-based'' +policy is as follows. In many BDD/ADD applications the hit rate is +not very sensitive to the size of the cache: It is primarily a +function of the problem instance at hand. If a large hit rate is +observed, chances are that by using a large cache, the results of +large problems (those that would take longer to solve) will survive in +the cache without being overwritten long enough to cause a valuable +cache hit. Notice that when a large problem is solved more than once, +so are its recursively generated subproblems. If the hit rate is +low, the probability of large problems being solved more than once is +low. + +

                          +The other observation about the cache sizing policy is that there is +little point in keeping a cache which is much larger than the unique +table. Every time the unique table ``fills up,'' garbage collection is +invoked and the cache is cleared of all dead entries. A cache that is +much larger than the unique table is therefore +less than fully utilized. + +

                          + +

                          + +
                          +Local Caches +

                          + +

                          +Sometimes it may be necessary or convenient to use a local cache. A +local cache can be lossless (no results are ever +overwritten), or it may store objects for which +canonical representations are not available. One +important fact to keep in mind when using a local cache is that local +caches are not cleared during garbage +collection or before reordering. Therefore, it is necessary to +increment the reference count of all nodes +pointed by a local cache. (Unless their reference counts are +guaranteed positive in some other way. One such way is by including +all partial results in the global result.) Before disposing of the +local cache, all elements stored in it must be passed to +Cudd_RecursiveDeref. As consequence +of the fact that all results in a local cache are referenced, it is +generally convenient to store in the local cache also the result of +trivial problems, which are not usually stored in the global cache. +Otherwise, after a recursive call, it is difficult to tell whether the +result is in the cache, and therefore referenced, or not in the cache, +and therefore not referenced. + +

                          +An alternative approach to referencing the results in the local caches +is to install hook functions (see Section 3.16) to be +executed before garbage collection. + +

                          + +

                          + +
                          +The Unique Table +

                          + +

                          +A recursive procedure typically splits the operands by expanding with +respect to the topmost variable. Topmost in this context refers to the +variable that is closest to the roots in the current variable order. +The nodes, on the other hand, hold the index, which is invariant with +reordering. Therefore, when splitting, one must use the +permutation array maintained by the +package to get the right level. Access to the permutation array is +provided by the macro cuddI for BDDs and ADDs, +and by the macro cuddIZ for ZDDs. + +

                          +The unique table consists of as many hash tables as +there are variables in use. These has tables are called unique + subtables. The sizes of the unique subtables are determined by two +criteria: + +

                            +
                          1. The collision lists should be short + to keep access time down. +
                          2. +
                          3. There should be enough room for dead nodes, to + prevent too frequent garbage collections. +
                          4. +
                          +While the first criterion is fairly straightforward to implement, the +second leaves more room to creativity. The CUDD package tries to +figure out whether more dead node should be allowed to increase +performance. (See also Section 3.4.) There are two +reasons for not doing garbage collection too often. The obvious one is +that it is expensive. The second is that dead nodes may be +reclaimed, if they are the result of a +successful cache lookup. Hence dead nodes may provide a substantial +speed-up if they are kept around long enough. The usefulness of +keeping many dead nodes around varies from application to application, +and from problem instance to problem instance. As in the sizing of the +cache, the CUDD package adopts a +``reward-based'' policy to +decide how much room should be used for the unique table. If the +number of dead nodes reclaimed is large compared to the number of +nodes directly requested from the memory manager, then the CUDD +package assumes that it will be beneficial to allow more room for the +subtables, thereby reducing the frequency of garbage collection. The +package does so by switching between two modes of operation: + +
                            +
                          1. Fast growth: In this mode, the + ratio of dead nodes to total nodes required for garbage collection + is higher than in the slow growth mode to favor resizing + of the subtables. +
                          2. +
                          3. Slow growth: In this + mode keeping many dead nodes around is not as important as + keeping memory requirements low. +
                          4. +
                          +Switching from one mode to the other is based on the following +criteria: + +
                            +
                          1. If the unique table is already large, only slow growth is + possible. +
                          2. +
                          3. If the table is small and many dead nodes are being reclaimed, + then fast growth is selected. +
                          4. +
                          +This policy is especially effective when the diagrams being +manipulated have lots of recombination. Notice the interplay of the +cache sizing and unique sizing: Fast growth normally occurs when the +cache hit rate is large. The cache and the unique table then grow in +concert, preserving a healthy balance between their sizes. + +

                          + +

                          + +
                          +Allowing Asynchronous Reordering +

                          + +

                          +Asynchronous reordering is the reordering that is triggered +automatically by the increase of the number of nodes. Asynchronous +reordering takes place when a new internal node must be created, and +the number of nodes has reached a given +threshold. (The threshold is adjusted by +the package every time reordering takes place.) + +

                          +Those procedures that do not create new nodes (e.g., procedures that +count the number of nodes or minterms) need +not worry about asynchronous reordering: No special precaution is +necessary in writing them. + +

                          +Procedures that only manipulate decision diagrams through the exported +functions of the CUDD package also need not concern themselves with +asynchronous reordering. (See Section 3.2.1 for the +exceptions.) + +

                          +The remaining class of procedures is composed of functions that visit +the diagrams and may create new nodes. All such procedures in the CUDD +package are written so that they can be interrupted by dynamic +reordering. The general approach followed goes under the name of +``abort and retry.'' As the name +implies, a computation that is interrupted by dynamic reordering is +aborted and tried again. + +

                          +A recursive procedure that can be interrupted by dynamic reordering +(an interruptible procedure +from now on) is composed of two functions. One is responsible for the +real computation. The other is a simple +wrapper, which tests whether +reordering occurred and restarts the computation if it did. + +

                          +Asynchronous reordering of BDDs and ADDs can only be triggered inside +cuddUniqueInter, when a new node is about +to be created. Likewise, asynchronous reordering of ZDDs can only be +triggered inside cuddUniqueInterZdd. +When reordering is triggered, three things happen: + +

                            +
                          1. cuddUniqueInter returns a NULL + value; +
                          2. +
                          3. The flag reordered of the manager is set to 1. (0 means + no reordering, while 2 indicates an error occurred during + reordering.) +
                          4. +
                          5. The counter reorderings of the manager is incremented. + The counter is initialized to 0 when the manager is started and can + be accessed by calling + Cudd_ReadReorderings. By taking + two readings of the counter, an application can determine if + variable reordering has taken place between the first and the second + reading. The package itself, however, does not make use of the + counter: It is mentioned here for completeness. +
                          6. +
                          + +

                          +The recursive procedure that receives a NULL value from +cuddUniqueInter must free all +intermediate results that it may have computed before, and return NULL +in its turn. + +

                          +The wrapper function does not +decide whether reordering occurred based on the NULL return value, +because the NULL value may be the result of lack of memory. Instead, +it checks the reordered flag. + +

                          +When a recursive procedure calls another recursive procedure that may +cause reordering, it should bypass the wrapper and call the recursive +procedure directly. Otherwise, the calling procedure will not know +whether reordering occurred, and will not be able to restart. This is +the main reason why most recursive procedures are internal, rather +than static. (The wrappers, on the other hand, are mostly exported.) + +

                          + +

                          + +
                          +Debugging +

                          + +

                          +By defining the symbol DD_DEBUG during compilation, +numerous checks are added to the code. In addition, the procedures +Cudd_DebugCheck, +Cudd_CheckKeys, and +cuddHeapProfile can be called at any +point to verify the consistency of the data structure. +(cuddHeapProfile is an internal procedure. It is declared in +cuddInt.h.) Procedures +Cudd_DebugCheck and Cudd_CheckKeys are especially +useful when CUDD reports that during garbage collection the number of +nodes actually deleted from the unique table is different from the +count of dead nodes kept by the manager. The error causing the +discrepancy may have occurred much earlier than it is discovered. A +few strategicaly placed calls to the debugging procedures can +considerably narrow down the search for the source of the problem. +(For instance, a call to Cudd_RecursiveDeref where one to +Cudd_Deref was required may be identified in this way.) + +

                          +One of the most common problems encountered in debugging code based on +the CUDD package is a missing call to +Cudd_RecursiveDeref. To help +identify this type of problems, the package provides a function called +Cudd_CheckZeroRef. This function +should be called immediately before shutting down the manager. +Cudd_CheckZeroRef checks that the only nodes left with +non-zero reference counts are the +predefined constants, the BDD projection +functions, and nodes whose reference counts are +saturated. + +

                          +For this function to be effective the application must explicitly +dispose of all diagrams to which it has pointers before calling it. + +

                          + +

                          + +
                          +Gathering and Interpreting Statistics +

                          + +

                          +Function Cudd_PrintInfo can be called to +print out the values of parameters and statistics for a manager. The +output of Cudd_PrintInfo is divided in two sections. The +first reports the values of parameters that are under the application +control. The second reports the values of statistical counters and +other non-modifiable parameters. A quick guide to the interpretation +of all these quantities follows. For ease of exposition, we reverse +the order and describe the non-modifiable parameters first. We'll use +a sample run as example. There is nothing special about this run. + +

                          + +

                          + +
                          +Non Modifiable Parameters +

                          + +

                          +The list of non-modifiable parameters starts with: +

                          +    **** CUDD non-modifiable parameters ****
                          +    Memory in use: 32544220
                          +
                          +This is the memory used by CUDD for three things mainly: Unique table +(including all DD nodes in use), node free list, and computed table. +This number almost never decreases in the lifetime of a CUDD manager, +because CUDD does not release memory when it frees nodes. Rather, it +puts the nodes on its own free list. This number is in bytes. It does +not represent the peak memory occupation, because it does not include +the size of data structures created temporarily by some functions (e.g., +local look-up tables). + +

                          +

                          +    Peak number of nodes: 837018
                          +
                          +This number is the number of nodes that the manager has allocated. +This is not the largest size of the BDDs, because the manager will +normally have some dead nodes and some nodes on the free list. + +

                          +

                          +    Peak number of live nodes: 836894
                          +
                          +This is the largest number of live nodes that the manager has held +since its creation. + +

                          +

                          +    Number of BDD variables: 198
                          +    Number of ZDD variables: 0
                          +
                          +These numbers tell us this run was not using ZDDs. + +

                          +

                          +    Number of cache entries: 1048576
                          +
                          +Current number of slots of the computed table. If one has a +performance problem, this is one of the numbers to look at. The cache +size is always a power of 2. + +

                          +

                          +    Number of cache look-ups: 2996536
                          +    Number of cache hits: 1187087
                          +
                          +These numbers give an indication of the hit rate in the computed +table. It is not unlikely for model checking runs to get +hit rates even higher than this one (39.62%). + +

                          +

                          +    Number of cache insertions: 1809473
                          +    Number of cache collisions: 961208
                          +    Number of cache deletions: 0
                          +
                          +A collision occurs when a cache entry is +overwritten. A deletion +occurs when a cache entry is invalidated (e.g., during garbage +collection). If the number of deletions is high compared to the +number of collisions, it means that garbage collection occurs too +often. In this case there were no garbage collections; hence, no +deletions. + +

                          +

                          +    Cache used slots = 80.90% (expected 82.19%)
                          +
                          +Percentage of cache slots that contain a valid entry. If this +number is small, it may signal one of three conditions: + +
                            +
                          1. The cache may have been recently resized and it is still filling + up. +
                          2. +
                          3. The cache is too large for the BDDs. This should not happen if + the size of the cache is determined by CUDD. +
                          4. +
                          5. The hash function is not working properly. This is accompanied + by a degradation in performance. Conversely, a degradation in + performance may be due to bad hash function behavior. +
                          6. +
                          +The expected value is computed assuming a uniformly random +distribution of the accesses. If the difference between the measured +value and the expected value is large (unlike this case), the cache is +not working properly. + +

                          +

                          +    Soft limit for cache size: 1318912
                          +
                          +This number says how large the cache can grow. This limit is based on +the size of the unique table. CUDD uses a reward-based policy for +growing the cache. (See Section 4.4.1.) The default +hit rate for resizing is 30% and the value in effect is reported +among the modifiable parameters. + +

                          +

                          +    Number of buckets in unique table: 329728
                          +
                          +This number is exactly one quarter of the one above. This is indeed +how the soft limit is determined currently, unless the computed table +hits the specified hard limit. (See below.) + +

                          +

                          +    Used buckets in unique table: 87.96% (expected 87.93%)
                          +
                          +Percentage of unique table buckets that contain at least one +node. Remarks analogous to those made about the used cache slots apply. + +

                          +

                          +    Number of BDD and ADD nodes: 836894
                          +    Number of ZDD nodes: 0
                          +
                          +How many nodes are currently in the unique table, either alive or dead. + +

                          +

                          +    Number of dead BDD and ADD nodes: 0
                          +    Number of dead ZDD nodes: 0
                          +
                          +Subtract these numbers from those above to get the number of live +nodes. In this case there are no dead nodes because the application +uses delayed dereferencing +Cudd_DelayedDerefBdd. + +

                          +

                          +    Total number of nodes allocated: 836894
                          +
                          +This is the total number of nodes that were requested and obtained +from the free list. It never decreases, and is not an indication of +memory occupation after the first garbage collection. Rather, it is a +measure of the package activity. + +

                          +

                          +    Total number of nodes reclaimed: 0
                          +
                          +These are the nodes that were resuscitated from the dead. If they are +many more than the allocated nodes, and the total +number of slots is low relative to the number of nodes, then one may +want to increase the limit for fast unique table growth. In this case, +the number is 0 because of delayed dereferencing. + +

                          +

                          +    Garbage collections so far: 0
                          +    Time for garbage collections: 0.00 sec
                          +    Reorderings so far: 0
                          +    Time for reordering: 0.00 sec
                          +
                          +There is a GC for each reordering. Hence the first count will always be +at least as large as the second. + +

                          +

                          +    Node swaps in reordering: 0
                          +
                          +This is the number of elementary reordering steps. Each step consists +of the re-expression of one node while swapping two adjacent +variables. This number is a good measure of the amount of work done in +reordering. + +

                          + +

                          + +
                          +Modifiable Parameters +

                          + +

                          +Let us now consider the modifiable parameters, that is, those settings on +which the application or the user has control. + +

                          +

                          +    **** CUDD modifiable parameters ****
                          +    Hard limit for cache size: 8388608
                          +
                          +This number counts entries. Each entry is 16 bytes if CUDD is compiled +to use 32-bit pointers. Two important observations are in order: + +
                            +
                          1. If the datasize limit is set, CUDD will use it to determine this + number automatically. On a Unix system, one can type ``limit'' or + ``ulimit'' to verify if this value is set. If the datasize limit is + not set, CUDD uses a default which is rather small. If you have + enough memory (say 64MB or more) you should seriously consider + not using the default. So, either set the datasize limit, or + override the default with + Cudd_SetMaxCacheHard. +
                          2. +
                          3. If a process seems to be going nowhere, a small value for + this parameter may be the culprit. One cannot overemphasize the + importance of the computed table in BDD algorithms. +
                          4. +
                          +In this case the limit was automatically set for a target maximum +memory occupation of 104 MB. + +

                          +

                          +    Cache hit threshold for resizing: 15%
                          +
                          +This number can be changed if one suspects performance is hindered by +the small size of the cache, and the cache is not growing towards the +soft limit sufficiently fast. In such a case one can change the +default 30% to 15% (as in this case) or even 1%. + +

                          +

                          +    Garbage collection enabled: yes
                          +
                          +One can disable it, but there are few good reasons for doing +so. It is normally preferable to raise the limit for fast unique table +growth. (See below.) + +

                          +

                          +    Limit for fast unique table growth: 1363148
                          +
                          +See Section 4.5 and the comments above about reclaimed +nodes and hard limit for the cache size. This value was chosen +automatically by CUDD for a datasize limit of 1 GB. + +

                          +

                          +    Maximum number of variables sifted per reordering: 1000
                          +    Maximum number of variable swaps per reordering: 2000000
                          +    Maximum growth while sifting a variable: 1.2
                          +
                          +Lowering these numbers will cause reordering to be less accurate and +faster. Results are somewhat unpredictable, because larger BDDs after one +reordering do not necessarily mean the process will go faster or slower. + +

                          +

                          +    Dynamic reordering of BDDs enabled: yes
                          +    Default BDD reordering method: 4
                          +    Dynamic reordering of ZDDs enabled: no
                          +    Default ZDD reordering method: 4
                          +
                          +These lines tell whether automatic reordering can take place and what +method would be used. The mapping from numbers to methods is in +cudd.h. One may want to try different BDD reordering +methods. If variable groups are used, however, one should not expect +to see big differences, because CUDD uses the reported method only to +reorder each leaf variable group (typically corresponding present and +next state variables). For the relative order of the groups, it +always uses the same algorithm, which is effectively sifting. + +

                          +As for enabling dynamic reordering or not, a sensible recommendation is the +following: Unless the circuit is rather small or one has a pretty good +idea of what the order should be, reordering should be enabled. + +

                          +

                          +    Realignment of ZDDs to BDDs enabled: no
                          +    Realignment of BDDs to ZDDs enabled: no
                          +    Dead nodes counted in triggering reordering: no
                          +    Group checking criterion: 7
                          +    Recombination threshold: 0
                          +    Symmetry violation threshold: 0
                          +    Arc violation threshold: 0
                          +    GA population size: 0
                          +    Number of crossovers for GA: 0
                          +
                          +Parameters for reordering. See the documentation of the functions used +to control these parameters for the details. + +

                          +

                          +    Next reordering threshold: 100000
                          +
                          +When the number of nodes crosses this threshold, reordering will be +triggered. (If enabled; in this case it is not.) This parameter is +updated by the package whenever reordering takes place. The +application can change it, for instance at start-up. Another +possibility is to use a hook function (see Section 3.16) to +override the default updating policy. + +

                          + +

                          + +
                          +Extended Statistics and Reporting +

                          + +

                          +The following symbols can be defined during compilation to increase +the amount of statistics gathered and the number of messages produced +by the package: + +

                            +
                          • DD_STATS; +
                          • +
                          • DD_CACHE_PROFILE; +
                          • +
                          • DD_UNIQUE_PROFILE. +
                          • +
                          • DD_VERBOSE; +
                          • +
                          +Defining DD_CACHE_PROFILE causes each entry of the cache to include +an access counter, which is used to compute simple statistics on the +distribution of the keys. + +

                          + +

                          + +
                          +Guidelines for Documentation +

                          + +

                          +The documentation of the CUDD functions is extracted automatically +from the sources by Stephen Edwards's extdoc. (The Ext system is +available via anonymous FTP from +ic.eecs.berkeley.edu.) +The following guidelines are followed in CUDD to insure consistent and +effective use of automatic extraction. It is recommended that +extensions to CUDD follow the same documentation guidelines. + +

                            +
                          • The documentation of an exported procedure should be sufficient + to allow one to use it without reading the code. It is not necessary + to explain how the procedure works; only what it does. +
                          • +
                          • The SeeAlso + fields should be space-separated lists of function names. The + SeeAlso field of an exported procedure should only reference + other exported procedures. The SeeAlso field of an internal + procedure may reference other internal procedures as well as + exported procedures, but no static procedures. +
                          • +
                          • The return values are detailed in the + Description + field, not in the + Synopsis field. +
                          • +
                          • The parameters are documented alongside their declarations. + Further comments may appear in the Description field. +
                          • +
                          • If the Description field is non-empty--which is the + normal case for an exported procedure--then the synopsis is + repeated--possibly slightly changed--at the beginning of the + Description field. This is so because extdoc will not put the + synopsis in the same HTML file as + the description. +
                          • +
                          • The Synopsis field should be about one line long. +
                          • +
                          + +

                          +


                          + + +next + +up + +previous + +index +
                          + Next: The C++ Interface + Up: CUDD: CU Decision Diagram + Previous: User's Manual +   Index + +
                          +Fabio Somenzi +2012-02-04 +
                          + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node5.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node5.html new file mode 100644 index 000000000..b519a2f97 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node5.html @@ -0,0 +1,130 @@ + + + + + +The C++ Interface + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                          + Next: Acknowledgments + Up: CUDD: CU Decision Diagram + Previous: Programmer's Manual +   Index +
                          +
                          + + +Subsections + + + +
                          + +

                          + +
                          +The C++ Interface +

                          + +

                          + +

                          + +
                          +Compiling and Linking +

                          + +

                          +To build an application that uses the CUDD C++ interface, you should +add +

                          +#include "cuddObj.hh"
                          +
                          +to your source files. In addition to the normal CUDD libraries (see +Section 3.1) you should link +libobj.a to your executable. Refer to the +Makefile in the top level directory of the +distribution for further details. + +

                          + +

                          + +
                          +Basic Manipulation +

                          + +

                          +The following fragment of code illustrates some simple operations on +BDDs using the C++ interface. +

                          +	Cudd mgr(0,0);
                          +	BDD x = mgr.bddVar();
                          +	BDD y = mgr.bddVar();
                          +	BDD f = x * y;
                          +	BDD g = y + !x;
                          +	cout << "f is" << (f <= g ? "" : " not")
                          +	     << " less than or equal to g\n";
                          +
                          +This code creates a manager called mgr and two variables in it. +It then defines two functions f and g in terms of the +variables. Finally, it prints a message based on the comparison of the +two functions. No explicit referencing or dereferencing is required. +The operators are overloaded in the intuitive way. BDDs are freed when +execution leaves the scope in which they are defined or when the +variables referring to them are overwritten. + +

                          +


                          +
                          +Fabio Somenzi +2012-02-04 +
                          + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node6.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node6.html new file mode 100644 index 000000000..1f42c860e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node6.html @@ -0,0 +1,132 @@ + + + + + +Acknowledgments + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                          + Next: Bibliography + Up: CUDD: CU Decision Diagram + Previous: The C++ Interface +   Index +
                          +
                          + + +

                          + +
                          +Acknowledgments +

                          + +

                          +The contributors: Iris Bahar, Hyunwoo Cho, Erica Frohm, Charlie Gaona, +Cheng Hua, Jae-Young Jang, Seh-Woong Jeong, Balakrishna Kumthekar, +Enrico Macii, Bobbie Manne, In-Ho Moon, Curt Musfeldt, Shipra Panda, +Abelardo Pardo, Bernard Plessier, Kavita Ravi, Hyongkyoon Shin, Alan +Shuler, Arun Sivakumaran, Jorgen Sivesind. + +

                          +The early adopters: Gianpiero Cabodi, Jordi Cortadella, Mario Escobar, +Gayani Gamage, Gary Hachtel, Mariano Hermida, Woohyuk Lee, Enric +Pastor, Massimo Poncino, Ellen Sentovich, the students of ECEN5139. + +

                          +I am also particularly indebted to the following people for in-depth +discussions on BDDs: Armin Biere, Olivier Coudert, Arie Gurfinkel, +Geert Janssen, Don Knuth, David Long, Jean Christophe Madre, Ken +McMillan, Shin-Ichi Minato, Jaehong Park, Rajeev Ranjan, Rick Rudell, +Ellen Sentovich, Tom Shiple, Christian Stangier, and Bwolen Yang. + +

                          +Special thanks to Norris Ip for guiding my faltering steps +in the design of the C++ interface. +Gianpiero Cabodi and Stefano Quer have graciously agreed to let me +distribute their dddmp library with CUDD. + +

                          +Masahiro Fujita, Gary Hachtel, and Carl Pixley have provided +encouragement and advice. + +

                          +The National Science Foundation and the Semiconductor Research +Corporation have supported in part the development of this package. + +

                          + +


                          + + +next + +up + +previous + +index +
                          + Next: Bibliography + Up: CUDD: CU Decision Diagram + Previous: The C++ Interface +   Index + +
                          +Fabio Somenzi +2012-02-04 +
                          + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node7.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node7.html new file mode 100644 index 000000000..d7e967ef5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node7.html @@ -0,0 +1,195 @@ + + + + + +Bibliography + + + + + + + + + + + + + + + + + + + +next + +up + +previous + +index +
                          + Next: Index + Up: CUDD: CU Decision Diagram + Previous: Acknowledgments +   Index +

                          + + +

                          +Bibliography +

                          1 +
                          +R. I. Bahar, E. A. Frohm, C. M. Gaona, G. D. Hachtel, E. Macii, A. Pardo, and + F. Somenzi. +
                          Algebraic decision diagrams and their applications. +
                          In Proceedings of the International Conference on Computer-Aided + Design, pages 188-191, Santa Clara, CA, November 1993. + +

                          2 +
                          +B. Bollig, M. Löbbing, and I. Wegener. +
                          Simulated annealing to improve variable orderings for OBDDs. +
                          Presented at the International Workshop on Logic Synthesis, + Granlibakken, CA, May 1995. + +

                          3 +
                          +K. S. Brace, R. L. Rudell, and R. E. Bryant. +
                          Efficient implementation of a BDD package. +
                          In Proceedings of the 27th Design Automation Conference, pages + 40-45, Orlando, FL, June 1990. + +

                          4 +
                          +R. K. Brayton et al. +
                          VIS: A system for verification and synthesis. +
                          Technical Report UCB/ERL M95/104, Electronics Research Lab, Univ. of + California, December 1995. + +

                          5 +
                          +R. E. Bryant. +
                          Graph-based algorithms for Boolean function manipulation. +
                          IEEE Transactions on Computers, C-35(8):677-691, August 1986. + +

                          6 +
                          +R. Drechsler, B. Becker, and N. Göckel. +
                          A genetic algorithm for variable ordering of OBDDs. +
                          Presented at the International Workshop on Logic Synthesis, + Granlibakken, CA, May 1995. + +

                          7 +
                          +S. J. Friedman and K. J. Supowit. +
                          Finding the optimal variable ordering for binary decision diagrams. +
                          IEEE Transactions on Computers, 39(5):710-713, May 1990. + +

                          8 +
                          +M. Fujita, Y. Matsunaga, and T. Kakuda. +
                          On variable ordering of binary decision diagrams for the application + of multi-level logic synthesis. +
                          In Proceedings of the European Conference on Design Automation, + pages 50-54, Amsterdam, February 1991. + +

                          9 +
                          +M. Held and R. M. Karp. +
                          A dynamic programming approach to sequencing problems. +
                          J. SIAM, 10(1):196-210, 1962. + +

                          10 +
                          +N. Ishiura, H. Sawada, and S. Yajima. +
                          Minimization of binary decision diagrams based on exchanges of + variables. +
                          In Proceedings of the International Conference on Computer-Aided + Design, pages 472-475, Santa Clara, CA, November 1991. + +

                          11 +
                          +S.-W. Jeong, T.-S. Kim, and F. Somenzi. +
                          An efficient method for optimal BDD ordering computation. +
                          In International Conference on VLSI and CAD (ICVC'93), Taejon, + Korea, November 1993. + +

                          12 +
                          +S.-I. Minato. +
                          Zero-suppressed BDDs for set manipulation in combinatorial + problems. +
                          In Proceedings of the Design Automation Conference, pages + 272-277, Dallas, TX, June 1993. + +

                          13 +
                          +S. Panda and F. Somenzi. +
                          Who are the variables in your neighborhood. +
                          In Proceedings of the International Conference on Computer-Aided + Design, pages 74-77, San Jose, CA, November 1995. + +

                          14 +
                          +S. Panda, F. Somenzi, and B. F. Plessier. +
                          Symmetry detection and dynamic variable ordering of decision + diagrams. +
                          In Proceedings of the International Conference on Computer-Aided + Design, pages 628-631, San Jose, CA, November 1994. + +

                          15 +
                          +B. F. Plessier. +
                          A General Framework for Verification of Sequential Circuits. +
                          PhD thesis, University of Colorado at Boulder, Dept. of Electrical + and Computer Engineering, 1993. + +

                          16 +
                          +R. Rudell. +
                          Dynamic variable ordering for ordered binary decision diagrams. +
                          In Proceedings of the International Conference on Computer-Aided + Design, pages 42-47, Santa Clara, CA, November 1993. + +

                          17 +
                          +E. M. Sentovich, K. J. Singh, C. Moon, H. Savoj, R. K. Brayton, and + A. Sangiovanni-Vincentelli. +
                          Sequential circuit design using synthesis and optimization. +
                          In Proceedings of the International Conference on Computer + Design, pages 328-333, Cambridge, MA, October 1992. +
                          + + + + + + + +

                          +


                          +
                          +Fabio Somenzi +2012-02-04 +
                          + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node8.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node8.html new file mode 100644 index 000000000..a723fa181 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/doc/node8.html @@ -0,0 +1,848 @@ + + + + + +Index + + + + + + + + + + + + + + + + +next + +up + +previous +
                          + Up: CUDD: CU Decision Diagram + Previous: Bibliography +
                          +
                          + +
                          + +

                          +Index +

                          +
                          ADD +
                          Introduction + | Nodes + | New Constants + | Basic ADD Manipulation +
                          aggregation +
                          Variable Reordering for BDDs +
                          Algebraic Decision Diagram +
                          see ADD +
                          arc +
                          +
                          complement +
                          New BDD and ADD + | Writing Decision Diagrams to + | Writing Decision Diagrams to + | Complement Arcs + | Complement Arcs +
                          regular +
                          Writing Decision Diagrams to + | Writing Decision Diagrams to + | Complement Arcs +
                          +
                          background value +
                          Background +
                          BDD +
                          Introduction + | Nodes + | One, Logic Zero, and + | Basic BDD Manipulation +
                          Binary Decision Diagram +
                          see BDD +
                          box +
                          +
                          black +
                          Introduction +
                          clear +
                          Introduction + | Compiling and Linking +
                          +
                          cache +
                          Cache + | Cache + | Cache + | Initializing and Shutting Down + | Complement Arcs + | The Cache +
                          +
                          collision +
                          Non Modifiable Parameters +
                          collision list +
                          The Unique Table +
                          deletion +
                          Non Modifiable Parameters +
                          local +
                          The Cache + | Local Caches +
                          lossless +
                          Local Caches +
                          reward-based resizing +
                          Cache Sizing + | Cache Sizing +
                          sizing +
                          Cache Sizing +
                          +
                          cacheSize +
                          Initializing and Shutting Down +
                          canonical +
                          The Manager + | Local Caches +
                          compiling +
                          Compiling and Linking + | Predefined Constants + | Compiling and Linking +
                          configuration +
                          The CUDD Package +
                          conversion +
                          +
                          of ADDs to BDDs +
                          Converting ADDs to BDDs +
                          of BDDs to ADDs +
                          Converting ADDs to BDDs +
                          of BDDs to ZDDs +
                          Basic ZDD Manipulation + | Converting BDDs to ZDDs +
                          of ZDDs to BDDs +
                          Converting BDDs to ZDDs +
                          +
                          cube sets +
                          Introduction +
                          cudd.h +
                          Compiling and Linking + | Variable Reordering for BDDs + | Saturating Increments and Decrements +
                          Cudd_addApply +
                          Basic ADD Manipulation + | Basic ADD Manipulation +
                          Cudd_addBddInterval +
                          Converting ADDs to BDDs +
                          Cudd_addBddPattern +
                          Converting ADDs to BDDs +
                          Cudd_addBddThreshold +
                          Converting ADDs to BDDs +
                          Cudd_addConst +
                          New Constants +
                          Cudd_addHarwell +
                          Background +
                          Cudd_AddHook +
                          Hooks +
                          Cudd_addIthBit +
                          Converting ADDs to BDDs +
                          Cudd_addIthVar +
                          New BDD and ADD +
                          Cudd_addNewVar +
                          New BDD and ADD +
                          Cudd_addNewVarAtLevel +
                          New BDD and ADD + | Grouping Variables +
                          Cudd_addRead +
                          Background +
                          Cudd_addTimes +
                          Basic ADD Manipulation +
                          Cudd_AutodynDisable +
                          Variable Reordering for BDDs +
                          Cudd_AutodynDisableZdd +
                          Variable Reordering for ZDDs +
                          Cudd_AutodynEnable +
                          Variable Reordering for BDDs + | Variable Reordering for BDDs +
                          Cudd_AutodynEnableZdd +
                          Variable Reordering for ZDDs +
                          Cudd_bddAnd +
                          Basic BDD Manipulation + | Basic BDD Manipulation + | Basic ADD Manipulation +
                          Cudd_bddAndLimit +
                          Timeouts and Limits +
                          Cudd_bddConstrain +
                          Nodes +
                          Cudd_bddIte +
                          Basic BDD Manipulation +
                          Cudd_bddIthVar +
                          New BDD and ADD +
                          Cudd_bddNewVar +
                          New BDD and ADD + | New BDD and ADD + | New BDD and ADD +
                          Cudd_bddNewVarAtLevel +
                          New BDD and ADD + | Grouping Variables +
                          Cudd_BddToAdd +
                          Converting ADDs to BDDs +
                          Cudd_bddXor +
                          Basic ADD Manipulation +
                          CUDD_CACHE_SLOTS +
                          Initializing and Shutting Down +
                          Cudd_CheckKeys +
                          Debugging +
                          Cudd_CheckZeroRef +
                          Debugging +
                          Cudd_CountMinterm +
                          Background +
                          Cudd_DebugCheck +
                          Debugging +
                          Cudd_DelayedDerefBdd +
                          Non Modifiable Parameters +
                          Cudd_Deref +
                          Cudd_RecursiveDeref vs. Cudd_Deref + | Saturating Increments and Decrements +
                          Cudd_DumpBlif +
                          Writing Decision Diagrams to +
                          Cudd_DumpDaVinci +
                          Writing Decision Diagrams to +
                          Cudd_DumpDot +
                          Writing Decision Diagrams to +
                          Cudd_ForeachCube +
                          Nodes + | Background +
                          Cudd_ForeachNode +
                          Nodes +
                          Cudd_HookType +
                          Hooks +
                          Cudd_Init +
                          Initializing and Shutting Down + | Initializing and Shutting Down +
                          Cudd_MakeTreeNode +
                          Grouping Variables + | Grouping Variables +
                          Cudd_MakeZddTreeNode +
                          Variable Reordering for ZDDs +
                          Cudd_Not +
                          One, Logic Zero, and +
                          Cudd_PrintInfo +
                          Gathering and Interpreting Statistics +
                          Cudd_PrintMinterm +
                          Background +
                          Cudd_Quit +
                          Initializing and Shutting Down +
                          Cudd_ReadBackground +
                          Background +
                          Cudd_ReadEpsilon +
                          Predefined Constants +
                          Cudd_ReadErrorCode +
                          NULL Return Values +
                          Cudd_ReadInvPerm +
                          Basic BDD Manipulation +
                          Cudd_ReadLogicZero +
                          One, Logic Zero, and +
                          Cudd_ReadLooseUpto +
                          Setting Parameters +
                          Cudd_ReadMaxGrowth +
                          Variable Reordering for BDDs +
                          Cudd_ReadMinusInfinity +
                          Predefined Constants +
                          Cudd_ReadOne +
                          One, Logic Zero, and +
                          Cudd_ReadPlusInfinity +
                          Predefined Constants +
                          Cudd_ReadReorderings +
                          Allowing Asynchronous Reordering +
                          Cudd_ReadSiftMaxVar +
                          Variable Reordering for BDDs +
                          Cudd_ReadTree +
                          Grouping Variables +
                          Cudd_ReadZddOne +
                          One, Logic Zero, and + | Basic ZDD Manipulation +
                          Cudd_ReadZero +
                          Predefined Constants +
                          Cudd_RecursiveDeref +
                          Nodes + | Reference Counts + | Reference Counts + | Reference Counts + | Cudd_RecursiveDeref vs. Cudd_Deref + | When Increasing the Reference + | Saturating Increments and Decrements + | Local Caches + | Debugging +
                          Cudd_RecursiveDerefZdd +
                          Nodes + | Reference Counts + | Reference Counts + | Reference Counts + | When Increasing the Reference + | Saturating Increments and Decrements +
                          Cudd_ReduceHeap +
                          Variable Reordering for BDDs + | Variable Reordering for BDDs + | Variable Reordering for BDDs +
                          Cudd_Ref +
                          Nodes + | Basic BDD Manipulation + | Reference Counts + | When Increasing the Reference +
                          Cudd_Regular +
                          Complement Arcs +
                          CUDD_REORDER_ANNEALING +
                          Variable Reordering for BDDs +
                          CUDD_REORDER_EXACT +
                          Variable Reordering for BDDs +
                          CUDD_REORDER_GENETIC +
                          Variable Reordering for BDDs +
                          CUDD_REORDER_GROUP_SIFT +
                          Variable Reordering for BDDs +
                          CUDD_REORDER_GROUP_SIFT_CONV +
                          Variable Reordering for BDDs +
                          CUDD_REORDER_NONE +
                          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                          CUDD_REORDER_RANDOM +
                          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                          CUDD_REORDER_RANDOM_PIVOT +
                          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                          CUDD_REORDER_SAME +
                          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                          CUDD_REORDER_SIFT +
                          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                          CUDD_REORDER_SIFT_CONVERGE +
                          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                          CUDD_REORDER_SYMM_SIFT +
                          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                          CUDD_REORDER_SYMM_SIFT_CONV +
                          Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                          CUDD_REORDER_WINDOW2 +
                          Variable Reordering for BDDs +
                          CUDD_REORDER_WINDOW2_CONV +
                          Variable Reordering for BDDs +
                          CUDD_REORDER_WINDOW3 +
                          Variable Reordering for BDDs +
                          CUDD_REORDER_WINDOW3_CONV +
                          Variable Reordering for BDDs +
                          CUDD_REORDER_WINDOW4 +
                          Variable Reordering for BDDs +
                          CUDD_REORDER_WINDOW4_CONV +
                          Variable Reordering for BDDs +
                          Cudd_SetEpsilon +
                          Predefined Constants +
                          Cudd_SetLooseUpTo +
                          Setting Parameters +
                          Cudd_SetMaxCacheHard +
                          Modifiable Parameters +
                          Cudd_SetMaxGrowth +
                          Variable Reordering for BDDs +
                          Cudd_SetSiftMaxVar +
                          Variable Reordering for BDDs +
                          Cudd_SetTimeLimit +
                          Timeouts and Limits +
                          Cudd_SetTree +
                          Grouping Variables +
                          Cudd_ShuffleHeap +
                          Variable Reordering for BDDs +
                          Cudd_StdPostReordHook +
                          Hooks +
                          Cudd_StdPreReordHook +
                          Hooks +
                          Cudd_SymmProfile +
                          Variable Reordering for BDDs +
                          CUDD_UNIQUE_SLOTS +
                          Initializing and Shutting Down +
                          Cudd_zddDumpDot +
                          Writing Decision Diagrams to +
                          Cudd_zddIsop +
                          Basic ZDD Manipulation +
                          Cudd_zddIthVar +
                          New ZDD Variables +
                          Cudd_zddPortFromBdd +
                          Converting BDDs to ZDDs +
                          Cudd_zddPortToBdd +
                          Converting BDDs to ZDDs +
                          Cudd_zddRealignDisable +
                          Keeping Consistent Variable Orders +
                          Cudd_zddRealignEnable +
                          Keeping Consistent Variable Orders +
                          Cudd_zddReduceHeap +
                          Variable Reordering for ZDDs +
                          Cudd_zddShuffleHeap +
                          Variable Reordering for ZDDs +
                          Cudd_zddVarsFromBddVars +
                          Converting BDDs to ZDDs + | Converting BDDs to ZDDs +
                          Cudd_zddWeakDiv +
                          Basic ZDD Manipulation +
                          cuddCacheInsert +
                          The Cache +
                          cuddCacheInsert1 +
                          The Cache +
                          cuddCacheInsert2 +
                          The Cache +
                          cuddCacheLookup +
                          The Cache +
                          cuddCacheLookup1 +
                          The Cache +
                          cuddCacheLookup2 +
                          The Cache +
                          CUDDDIR +
                          Using the CUDD Package +
                          cuddHeapProfile +
                          Debugging +
                          cuddI +
                          The Unique Table +
                          cuddInt.h +
                          Debugging +
                          cuddIZ +
                          The Unique Table +
                          cuddSatDec +
                          Saturating Increments and Decrements +
                          cuddSatInc +
                          Saturating Increments and Decrements +
                          cuddUniqueConst +
                          Reference Counts + | Reference Counts + | Reference Counts +
                          cuddUniqueInter +
                          Reference Counts + | Reference Counts + | Reference Counts + | Complement Arcs + | Complement Arcs + | Allowing Asynchronous Reordering + | Allowing Asynchronous Reordering + | Allowing Asynchronous Reordering +
                          cuddUniqueInterZdd +
                          Reference Counts + | Reference Counts + | Reference Counts + | Allowing Asynchronous Reordering +
                          DD_CACHE_PROFILE +
                          Extended Statistics and Reporting +
                          DD_DEBUG +
                          Debugging +
                          DD_STATS +
                          Extended Statistics and Reporting +
                          DD_UNIQUE_PROFILE +
                          Extended Statistics and Reporting +
                          DD_VERBOSE +
                          Extended Statistics and Reporting +
                          DdManager +
                          The Manager + | Initializing and Shutting Down +
                          DdNode +
                          Nodes + | The Cache +
                          debugging +
                          Debugging +
                          DEC Alpha +
                          Predefined Constants + | Using the CUDD Package +
                          documentation +
                          Guidelines for Documentation +
                          +
                          Description +
                          Guidelines for Documentation +
                          HTML files +
                          Guidelines for Documentation +
                          SeeAlso +
                          Guidelines for Documentation +
                          Synopsis +
                          Guidelines for Documentation +
                          +
                          dot +
                          see graph, drawing +
                          Epsilon +
                          Predefined Constants +
                          extdoc +
                          see documentation +
                          floating point +
                          Predefined Constants +
                          +
                          double (C type) +
                          Nodes +
                          IEEE Standard 754 +
                          Predefined Constants +
                          +
                          free list +
                          Reference Counts +
                          FTP +
                          The CUDD Package + | CUDD Friends + | Using the CUDD Package + | Guidelines for Documentation +
                          function +
                          +
                          characteristic +
                          Introduction + | Converting BDDs to ZDDs +
                          cover +
                          Basic ZDD Manipulation + | Converting BDDs to ZDDs + | Converting BDDs to ZDDs +
                          +
                          irredundant +
                          Basic ZDD Manipulation +
                          +
                          minterms +
                          Background + | Allowing Asynchronous Reordering +
                          ON-set +
                          Introduction +
                          sum of products +
                          Background +
                          switching +
                          Introduction + | Introduction +
                          +
                          garbage collection +
                          Nodes + | Cache + | Setting Parameters + | Reference Counts + | Reference Counts + | The Cache + | Local Caches + | The Unique Table +
                          +
                          hooks +
                          Hooks +
                          +
                          gcc +
                          Predefined Constants +
                          generator +
                          Nodes +
                          global variables +
                          The Manager +
                          graph +
                          +
                          arc capacity +
                          Background +
                          arc length +
                          Background +
                          drawing +
                          Writing Decision Diagrams to + | Writing Decision Diagrams to +
                          +
                          growth +
                          Setting Parameters +
                          gzip +
                          The CUDD Package +
                          HAVE_IEEE_754 +
                          Predefined Constants +
                          header files +
                          Variable Reordering for BDDs + | Saturating Increments and Decrements +
                          hook +
                          Hooks +
                          infinities +
                          Predefined Constants +
                          installation +
                          The CUDD Package +
                          Intel Pentium 4 +
                          The CUDD Package +
                          interface +
                          +
                          cache +
                          The Cache +
                          SIS +
                          The SIS/VIS Interface + | Using the CUDD Package +
                          VIS +
                          The SIS/VIS Interface +
                          +
                          libraries +
                          The CUDD Package +
                          +
                          cudd +
                          Compiling and Linking +
                          dddmp +
                          Saving and Restoring BDDs +
                          mtr +
                          Compiling and Linking + | Grouping Variables +
                          obj +
                          Compiling and Linking +
                          st +
                          Compiling and Linking + | The Cache +
                          util +
                          Compiling and Linking +
                          +
                          Makefile +
                          Compiling and Linking + | Predefined Constants + | Compiling and Linking +
                          manager +
                          The Manager + | The Manager + | Constant Functions +
                          matrix +
                          +
                          sparse +
                          Background +
                          +
                          maxCache +
                          Cache Sizing +
                          maxMemory +
                          Initializing and Shutting Down +
                          MinusInfinity +
                          Predefined Constants +
                          MTR_DEFAULT +
                          Grouping Variables +
                          MTR_FIXED +
                          Grouping Variables +
                          nanotrav +
                          The CUDD Package + | The CUDD Package +
                          node +
                          Nodes +
                          +
                          constant +
                          Nodes + | Constant Functions + | One, Logic Zero, and + | Predefined Constants + | Background + | New Constants + | Reference Counts + | When Increasing the Reference +
                          +
                          value +
                          Nodes +
                          +
                          dead +
                          Reference Counts + | The Cache + | The Unique Table +
                          dereference +
                          Basic ADD Manipulation +
                          reclaimed +
                          The Unique Table +
                          recycling +
                          Nodes +
                          reference +
                          Basic ADD Manipulation +
                          reference count +
                          Nodes + | Nodes + | Basic BDD Manipulation + | Basic BDD Manipulation + | Reference Counts + | Reference Counts + | Reference Counts + | When Increasing the Reference + | Saturating Increments and Decrements + | The Cache + | Local Caches + | Debugging +
                          +
                          saturated +
                          Debugging +
                          +
                          terminal +
                          see node, constant +
                          variable index +
                          Nodes +
                          +
                          numSlots +
                          Initializing and Shutting Down +
                          numVars +
                          Initializing and Shutting Down +
                          numVarsZ +
                          Initializing and Shutting Down +
                          PlusInfinity +
                          Predefined Constants + | Background +
                          projection functions +
                          Creating Variables + | New BDD and ADD + | New BDD and ADD + | New BDD and ADD + | New ZDD Variables + | Basic BDD Manipulation + | Basic ADD Manipulation + | Basic ZDD Manipulation + | Basic ZDD Manipulation + | Debugging +
                          README file +
                          The CUDD Package + | The CUDD Package +
                          reordering +
                          Introduction + | Introduction + | Nodes + | The Cache +
                          +
                          abort and retry +
                          Allowing Asynchronous Reordering +
                          asynchronous +
                          Variable Reordering for BDDs + | Allowing Asynchronous Reordering +
                          converging +
                          Variable Reordering for BDDs + | Variable Reordering for BDDs + | Variable Reordering for BDDs + | Variable Reordering for BDDs +
                          Cudd_ReorderingType +
                          Variable Reordering for BDDs +
                          dynamic +
                          Introduction + | Variable Reordering for BDDs + | Variable Reordering for ZDDs +
                          exact +
                          Variable Reordering for BDDs +
                          function wrapper +
                          Allowing Asynchronous Reordering + | Allowing Asynchronous Reordering +
                          genetic +
                          Variable Reordering for BDDs +
                          group +
                          Variable Reordering for BDDs + | Variable Reordering for BDDs +
                          hooks +
                          Hooks +
                          interruptible procedure +
                          Allowing Asynchronous Reordering +
                          of BDDs and ADDs +
                          Variable Reordering for BDDs +
                          of ZDDs +
                          Basic ZDD Manipulation + | Variable Reordering for ZDDs +
                          random +
                          Variable Reordering for BDDs +
                          sifting +
                          Variable Reordering for BDDs + | Variable Reordering for BDDs +
                          simulated annealing +
                          Variable Reordering for BDDs +
                          symmetric +
                          Variable Reordering for BDDs +
                          threshold +
                          Variable Reordering for BDDs + | Allowing Asynchronous Reordering +
                          window +
                          Variable Reordering for BDDs +
                          +
                          saturating +
                          +
                          decrements +
                          Saturating Increments and Decrements +
                          increments +
                          Saturating Increments and Decrements +
                          +
                          SISDIR +
                          Using the CUDD Package +
                          SIZEOF_INT +
                          Saturating Increments and Decrements + | Saturating Increments and Decrements +
                          SIZEOF_VOID_P +
                          Saturating Increments and Decrements + | Saturating Increments and Decrements +
                          statistical counters +
                          The Manager + | Reference Counts + | Cache Sizing +
                          statistics +
                          Gathering and Interpreting Statistics +
                          subtable +
                          Initializing and Shutting Down + | Reference Counts +
                          symmetry +
                          Variable Reordering for BDDs +
                          table +
                          +
                          computed +
                          Cache +
                          growth +
                          Setting Parameters +
                          hash +
                          The Manager + | The Unique Table +
                          unique +
                          Nodes + | The Manager + | The Manager + | Initializing and Shutting Down + | Initializing and Shutting Down + | Setting Parameters + | Variable Reordering for BDDs + | Reference Counts + | Cache Sizing + | Cache Sizing + | The Unique Table +
                          +
                          fast growth +
                          The Unique Table +
                          reward-based resizing +
                          The Unique Table +
                          slow growth +
                          The Unique Table +
                          +
                          +
                          timeout +
                          Timeouts and Limits +
                          variable +
                          +
                          groups +
                          Grouping Variables +
                          order +
                          Nodes + | New BDD and ADD +
                          permutation +
                          Nodes + | The Unique Table +
                          tree +
                          Grouping Variables + | Grouping Variables +
                          +
                          ZDD +
                          Introduction + | Nodes + | New ZDD Variables + | Basic ZDD Manipulation + | Converting BDDs to ZDDs +
                          zero +
                          +
                          arithmetic +
                          One, Logic Zero, and + | New BDD and ADD + | Converting ADDs to BDDs +
                          logical +
                          One, Logic Zero, and + | Converting ADDs to BDDs +
                          +
                          Zero-suppressed Binary Decision Diagram +
                          see ZDD + +
                          +

                          +
                          +Fabio Somenzi +2012-02-04 +
                          + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/r7x8.1.mat b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/r7x8.1.mat new file mode 100644 index 000000000..b0dd0a0a8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/r7x8.1.mat @@ -0,0 +1,53 @@ +7 9 +0 0 1 +0 1 1 +0 2 1 +0 3 4 +0 4 3 +0 5 3 +0 6 3 +0 8 3 +1 0 4 +1 1 3 +1 2 2 +1 3 4 +1 4 1 +1 5 2 +1 6 4 +1 8 3 +2 0 1 +2 1 1 +2 2 4 +2 4 2 +2 5 3 +2 6 3 +2 8 3 +3 0 2 +3 1 1 +3 3 4 +3 4 4 +3 5 1 +3 8 1 +4 0 2 +4 1 3 +4 2 2 +4 3 4 +4 4 1 +4 5 1 +4 6 2 +4 8 2 +5 0 3 +5 1 3 +5 2 4 +5 3 4 +5 4 1 +5 5 3 +5 6 3 +5 8 4 +6 1 1 +6 2 1 +6 3 4 +6 4 2 +6 5 4 +6 6 4 +6 8 2 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/r7x8.1.out b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/r7x8.1.out new file mode 100644 index 000000000..4dc72222d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/r7x8.1.out @@ -0,0 +1,396 @@ +# TestCudd Version #1.0, Release date 3/17/01 +# ./testcudd -p2 r7x8.1.mat +:name: r7x8.1.mat: 7 rows 9 columns +:1: M: 63 nodes 5 leaves 52 minterms +000000-- 1 +000001-0 1 +000001-1 4 +000010-0 4 +000010-1 3 +000011-0 2 +000011-1 4 +000100-- 3 +000101-0 3 +000110-0 1 +000110-1 2 +000111-0 4 +001000-- 1 +001001-0 4 +001010-0 2 +001010-1 1 +001011-1 4 +001100-0 2 +001100-1 3 +001101-0 3 +001110-0 4 +001110-1 1 +0100-0-0 3 +011000-0 3 +011010-0 1 +100000-0 2 +100000-1 3 +100001-0 2 +100001-1 4 +100010-- 3 +100011-- 4 +100100-- 1 +100101-0 2 +100110-0 1 +100110-1 3 +100111-0 3 +101000-1 1 +101001-0 1 +101001-1 4 +101100-0 2 +101100-1 4 +101101-0 4 +110000-0 2 +110010-0 4 +111000-0 2 + +:2: time to read the matrix = 0.00 sec +:3: C: 22 nodes 1 leaves 52 minterms +0000---- 1 +0001-0-- 1 +0001-1-0 1 +001000-- 1 +001001-0 1 +001010-- 1 +001011-1 1 +001100-- 1 +001101-0 1 +001110-- 1 +01-0-0-0 1 +1000---- 1 +1001-0-- 1 +1001-1-0 1 +101000-1 1 +101001-- 1 +101100-- 1 +101101-0 1 +1100-0-0 1 +111000-0 1 + +Testing iterator on cubes: +000000-- 1 +000001-0 1 +000001-1 4 +000010-0 4 +000010-1 3 +000011-0 2 +000011-1 4 +000100-- 3 +000101-0 3 +000110-0 1 +000110-1 2 +000111-0 4 +001000-- 1 +001001-0 4 +001010-0 2 +001010-1 1 +001011-1 4 +001100-0 2 +001100-1 3 +001101-0 3 +001110-0 4 +001110-1 1 +0100-0-0 3 +011000-0 3 +011010-0 1 +100000-0 2 +100000-1 3 +100001-0 2 +100001-1 4 +100010-- 3 +100011-- 4 +100100-- 1 +100101-0 2 +100110-0 1 +100110-1 3 +100111-0 3 +101000-1 1 +101001-0 1 +101001-1 4 +101100-0 2 +101100-1 4 +101101-0 4 +110000-0 2 +110010-0 4 +111000-0 2 + +Testing prime expansion of cubes: +-000---- 1 +-00--0-- 1 +0--0-0-0 1 +--00-0-0 1 +-0-100-- 1 +10-001-- 1 +-00----0 1 +00---0-- 1 +-1-000-0 1 +-0--01-0 1 +-0--00-1 1 +00-01--1 1 + +Testing iterator on primes (CNF): +-0-0---- 1 +-0---0-- 1 +0-0-0--- 1 +-0-----0 1 +---0-0-0 1 +0101-1-1 1 +--0-00-1 1 +1-0-10-0 1 + +Cache used slots = 58.06% (expected 58.94%) +xor1: 14 nodes 1 leaves 28 minterms +000--1-1 1 +001-11-1 1 +01---0-0 1 +100--1-1 1 +101-00-0 1 +101-01-1 1 +110--0-0 1 +111-00-0 1 + +Chosen minterm for Hamming distance test: : 9 nodes 1 leaves 1 minterms +11110010 1 + +Minimum Hamming distance = 1 +ycube: 5 nodes 1 leaves 8 minterms +-0-0-0-0 1 + +CP: 11 nodes 1 leaves 7 minterms +00-0-0-0 1 +1000-0-0 1 +101000-1 1 + +:4: ineq: 10 nodes 1 leaves 42 minterms +001000-- 1 +00101--- 1 +1000---- 1 +100100-- 1 +10011--- 1 +101----- 1 +111000-- 1 +11101--- 1 + +10------ 1 +-01----- 1 +1-1----- 1 +-0-0---- 1 +1--0---- 1 +-0--10-- 1 +--1010-- 1 +1---10-- 1 + +:4: ess: 1 nodes 1 leaves 128 minterms +-------- 1 + +:5: shortP: 7 nodes 1 leaves 2 minterms +000000-- 1 + +:5b: largest: 4 nodes 1 leaves 16 minterms +01-1---- 1 + +The value of M along the chosen shortest path is 1 +:6: shortP: 5 nodes 1 leaves 8 minterms +0000---- 1 + +Support of f: : 8 nodes 1 leaves 2 minterms +111111-1 1 + +Size of the support of f: 7 +Size of the support of f: 7 +Support of f and g: : 8 nodes 1 leaves 2 minterms +111111-1 1 + +Size of the support of f and g: 7 +Size of the support of f and g: 7 +Support common to f and g: : 5 nodes 1 leaves 16 minterms +-1-1-1-1 1 + +Support private to f: : 4 nodes 1 leaves 32 minterms +1-1-1--- 1 + +Support private to g: : 1 nodes 1 leaves 256 minterms +-------- 1 + +Average distance: 4138.57 +Number of variables = 8 Number of slots = 2304 +Number of keys = 999 Number of min dead = 9216 +walsh1: 16 nodes 2 leaves 256 minterms +-0--0--0--0- 1 +-0--0--0--10 1 +-0--0--0--11 -1 +-0--0--10-0- 1 +-0--0--10-10 1 +-0--0--10-11 -1 +-0--0--11-0- -1 +-0--0--11-10 -1 +-0--0--11-11 1 +-0--10-0--0- 1 +-0--10-0--10 1 +-0--10-0--11 -1 +-0--10-10-0- 1 +-0--10-10-10 1 +-0--10-10-11 -1 +-0--10-11-0- -1 +-0--10-11-10 -1 +-0--10-11-11 1 +-0--11-0--0- -1 +-0--11-0--10 -1 +-0--11-0--11 1 +-0--11-10-0- -1 +-0--11-10-10 -1 +-0--11-10-11 1 +-0--11-11-0- 1 +-0--11-11-10 1 +-0--11-11-11 -1 +-10-0--0--0- 1 +-10-0--0--10 1 +-10-0--0--11 -1 +-10-0--10-0- 1 +-10-0--10-10 1 +-10-0--10-11 -1 +-10-0--11-0- -1 +-10-0--11-10 -1 +-10-0--11-11 1 +-10-10-0--0- 1 +-10-10-0--10 1 +-10-10-0--11 -1 +-10-10-10-0- 1 +-10-10-10-10 1 +-10-10-10-11 -1 +-10-10-11-0- -1 +-10-10-11-10 -1 +-10-10-11-11 1 +-10-11-0--0- -1 +-10-11-0--10 -1 +-10-11-0--11 1 +-10-11-10-0- -1 +-10-11-10-10 -1 +-10-11-10-11 1 +-10-11-11-0- 1 +-10-11-11-10 1 +-10-11-11-11 -1 +-11-0--0--0- -1 +-11-0--0--10 -1 +-11-0--0--11 1 +-11-0--10-0- -1 +-11-0--10-10 -1 +-11-0--10-11 1 +-11-0--11-0- 1 +-11-0--11-10 1 +-11-0--11-11 -1 +-11-10-0--0- -1 +-11-10-0--10 -1 +-11-10-0--11 1 +-11-10-10-0- -1 +-11-10-10-10 -1 +-11-10-10-11 1 +-11-10-11-0- 1 +-11-10-11-10 1 +-11-10-11-11 -1 +-11-11-0--0- 1 +-11-11-0--10 1 +-11-11-0--11 -1 +-11-11-10-0- 1 +-11-11-10-10 1 +-11-11-10-11 -1 +-11-11-11-0- -1 +-11-11-11-10 -1 +-11-11-11-11 1 + +wtw: 14 nodes 2 leaves 16 minterms +0-00-00-00-0 16 +0-00-00-01-1 16 +0-00-01-10-0 16 +0-00-01-11-1 16 +0-01-10-00-0 16 +0-01-10-01-1 16 +0-01-11-10-0 16 +0-01-11-11-1 16 +1-10-00-00-0 16 +1-10-00-01-1 16 +1-10-01-10-0 16 +1-10-01-11-1 16 +1-11-10-00-0 16 +1-11-10-01-1 16 +1-11-11-10-0 16 +1-11-11-11-1 16 + +Average length of non-empty lists = 1 +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000 +Maximum number of variable swaps per reordering: 2000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: no +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: no +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 0 +Arc violation threshold: 0 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 4004 +**** CUDD non-modifiable parameters **** +Memory in use: 4274508 +Peak number of nodes: 2044 +Peak number of live nodes: 119 +Number of BDD variables: 9 +Number of ZDD variables: 0 +Number of cache entries: 2048 +Number of cache look-ups: 2864 +Number of cache hits: 729 +Number of cache insertions: 2301 +Number of cache collisions: 947 +Number of cache deletions: 1351 +Cache used slots = 66.11% (expected 67.49%) +Soft limit for cache size: 13312 +Number of buckets in unique table: 2560 +Used buckets in unique table: 0.51% (expected 0.51%) +Number of BDD and ADD nodes: 13 +Number of ZDD nodes: 0 +Number of dead BDD and ADD nodes: 0 +Number of dead ZDD nodes: 0 +Total number of nodes allocated: 1095 +Total number of nodes reclaimed: 967 +Garbage collections so far: 1 +Time for garbage collection: 0.00 sec +Reorderings so far: 0 +Time for reordering: 0.00 sec +total time = 0.00 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 0.0 seconds +System time 0.0 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131653K +Virtual data size = 152K + data size initialized = 18K + data size uninitialized = 1K + data size sbrk = 133K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 0 +Minor page faults = 1330 +Swaps = 0 +Input blocks = 0 +Output blocks = 16 +Context switch (voluntary) = 0 +Context switch (involuntary) = 1 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/testcudd.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/testcudd.c new file mode 100644 index 000000000..a5d4aa232 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/cudd/testcudd.c @@ -0,0 +1,1178 @@ +/**CFile*********************************************************************** + + FileName [testcudd.c] + + PackageName [cudd] + + Synopsis [Sanity check tests for some CUDD functions.] + + Description [testcudd reads a matrix with real coefficients and + transforms it into an ADD. It then performs various operations on + the ADD and on the BDD corresponding to the ADD pattern. Finally, + testcudd tests functions relate to Walsh matrices and matrix + multiplication.] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "cuddInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define TESTCUDD_VERSION "TestCudd Version #1.0, Release date 3/17/01" + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: testcudd.c,v 1.23 2012/02/05 05:30:29 fabio Exp $"; +#endif + +static const char *onames[] = { "C", "M" }; /* names of functions to be dumped */ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void usage (char * prog); +static FILE *open_file (char *filename, const char *mode); +static int testIterators (DdManager *dd, DdNode *M, DdNode *C, int pr); +static int testXor (DdManager *dd, DdNode *f, int pr, int nvars); +static int testHamming (DdManager *dd, DdNode *f, int pr); +static int testWalsh (DdManager *dd, int N, int cmu, int approach, int pr); +static int testSupport(DdManager *dd, DdNode *f, DdNode *g, int pr); + +/**AutomaticEnd***************************************************************/ + + +/**Function******************************************************************** + + Synopsis [Main function for testcudd.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +main(int argc, char * const *argv) +{ + FILE *fp; /* pointer to input file */ + char *file = (char *) ""; /* input file name */ + FILE *dfp = NULL; /* pointer to dump file */ + FILE *savefp = NULL;/* pointer to save current manager's stdout setting */ + char *dfile; /* file for DD dump */ + DdNode *dfunc[2]; /* addresses of the functions to be dumped */ + DdManager *dd; /* pointer to DD manager */ + DdNode *one; /* fast access to constant function */ + DdNode *M; + DdNode **x; /* pointers to variables */ + DdNode **y; /* pointers to variables */ + DdNode **xn; /* complements of row variables */ + DdNode **yn_; /* complements of column variables */ + DdNode **xvars; + DdNode **yvars; + DdNode *C; /* result of converting from ADD to BDD */ + DdNode *ess; /* cube of essential variables */ + DdNode *shortP; /* BDD cube of shortest path */ + DdNode *largest; /* BDD of largest cube */ + DdNode *shortA; /* ADD cube of shortest path */ + DdNode *constN; /* value returned by evaluation of ADD */ + DdNode *ycube; /* cube of the negated y vars for c-proj */ + DdNode *CP; /* C-Projection of C */ + DdNode *CPr; /* C-Selection of C */ + int length; /* length of the shortest path */ + int nx; /* number of variables */ + int ny; + int maxnx; + int maxny; + int m; + int n; + int N; + int cmu; /* use CMU multiplication */ + int pr; /* verbose printout level */ + int harwell; + int multiple; /* read multiple matrices */ + int ok; + int c; /* variable to read in options */ + int approach; /* reordering approach */ + int autodyn; /* automatic reordering */ + int groupcheck; /* option for group sifting */ + int profile; /* print heap profile if != 0 */ + int keepperm; /* keep track of permutation */ + int clearcache; /* clear the cache after each matrix */ + int blifOrDot; /* dump format: 0 -> dot, 1 -> blif, ... */ + int retval; /* return value */ + int i; /* loop index */ + unsigned long startTime; /* initial time */ + unsigned long lapTime; + int size; + unsigned int cacheSize, maxMemory; + unsigned int nvars,nslots; + + startTime = util_cpu_time(); + + approach = CUDD_REORDER_NONE; + autodyn = 0; + pr = 0; + harwell = 0; + multiple = 0; + profile = 0; + keepperm = 0; + cmu = 0; + N = 4; + nvars = 4; + cacheSize = 127; + maxMemory = 0; + nslots = CUDD_UNIQUE_SLOTS; + clearcache = 0; + groupcheck = CUDD_GROUP_CHECK7; + dfile = NULL; + blifOrDot = 0; /* dot format */ + + /* Parse command line. */ + while ((c = getopt(argc, argv, "CDHMPS:a:bcd:g:hkmn:p:v:x:X:")) + != EOF) { + switch(c) { + case 'C': + cmu = 1; + break; + case 'D': + autodyn = 1; + break; + case 'H': + harwell = 1; + break; + case 'M': +#ifdef MNEMOSYNE + (void) mnem_setrecording(0); +#endif + break; + case 'P': + profile = 1; + break; + case 'S': + nslots = atoi(optarg); + break; + case 'X': + maxMemory = atoi(optarg); + break; + case 'a': + approach = atoi(optarg); + break; + case 'b': + blifOrDot = 1; /* blif format */ + break; + case 'c': + clearcache = 1; + break; + case 'd': + dfile = optarg; + break; + case 'g': + groupcheck = atoi(optarg); + break; + case 'k': + keepperm = 1; + break; + case 'm': + multiple = 1; + break; + case 'n': + N = atoi(optarg); + break; + case 'p': + pr = atoi(optarg); + break; + case 'v': + nvars = atoi(optarg); + break; + case 'x': + cacheSize = atoi(optarg); + break; + case 'h': + default: + usage(argv[0]); + break; + } + } + + if (argc - optind == 0) { + file = (char *) "-"; + } else if (argc - optind == 1) { + file = argv[optind]; + } else { + usage(argv[0]); + } + if ((approach<0) || (approach>17)) { + (void) fprintf(stderr,"Invalid approach: %d \n",approach); + usage(argv[0]); + } + + if (pr > 0) { + (void) printf("# %s\n", TESTCUDD_VERSION); + /* Echo command line and arguments. */ + (void) printf("#"); + for (i = 0; i < argc; i++) { + (void) printf(" %s", argv[i]); + } + (void) printf("\n"); + (void) fflush(stdout); + } + + /* Initialize manager and provide easy reference to terminals. */ + dd = Cudd_Init(nvars,0,nslots,cacheSize,maxMemory); + one = DD_ONE(dd); + dd->groupcheck = (Cudd_AggregationType) groupcheck; + if (autodyn) Cudd_AutodynEnable(dd,CUDD_REORDER_SAME); + + /* Open input file. */ + fp = open_file(file, "r"); + + /* Open dump file if requested */ + if (dfile != NULL) { + dfp = open_file(dfile, "w"); + } + + x = y = xn = yn_ = NULL; + do { + /* We want to start anew for every matrix. */ + maxnx = maxny = 0; + nx = maxnx; ny = maxny; + if (pr>0) lapTime = util_cpu_time(); + if (harwell) { + if (pr > 0) (void) printf(":name: "); + ok = Cudd_addHarwell(fp, dd, &M, &x, &y, &xn, &yn_, &nx, &ny, + &m, &n, 0, 2, 1, 2, pr); + } else { + ok = Cudd_addRead(fp, dd, &M, &x, &y, &xn, &yn_, &nx, &ny, + &m, &n, 0, 2, 1, 2); + if (pr > 0) + (void) printf(":name: %s: %d rows %d columns\n", file, m, n); + } + if (!ok) { + (void) fprintf(stderr, "Error reading matrix\n"); + exit(1); + } + + if (nx > maxnx) maxnx = nx; + if (ny > maxny) maxny = ny; + + /* Build cube of negated y's. */ + ycube = DD_ONE(dd); + Cudd_Ref(ycube); + for (i = maxny - 1; i >= 0; i--) { + DdNode *tmpp; + tmpp = Cudd_bddAnd(dd,Cudd_Not(dd->vars[y[i]->index]),ycube); + if (tmpp == NULL) exit(2); + Cudd_Ref(tmpp); + Cudd_RecursiveDeref(dd,ycube); + ycube = tmpp; + } + /* Initialize vectors of BDD variables used by priority func. */ + xvars = ALLOC(DdNode *, nx); + if (xvars == NULL) exit(2); + for (i = 0; i < nx; i++) { + xvars[i] = dd->vars[x[i]->index]; + } + yvars = ALLOC(DdNode *, ny); + if (yvars == NULL) exit(2); + for (i = 0; i < ny; i++) { + yvars[i] = dd->vars[y[i]->index]; + } + + /* Clean up */ + for (i=0; i < maxnx; i++) { + Cudd_RecursiveDeref(dd, x[i]); + Cudd_RecursiveDeref(dd, xn[i]); + } + FREE(x); + FREE(xn); + for (i=0; i < maxny; i++) { + Cudd_RecursiveDeref(dd, y[i]); + Cudd_RecursiveDeref(dd, yn_[i]); + } + FREE(y); + FREE(yn_); + + if (pr>0) {(void) printf(":1: M"); Cudd_PrintDebug(dd,M,nx+ny,pr);} + + if (pr>0) (void) printf(":2: time to read the matrix = %s\n", + util_print_time(util_cpu_time() - lapTime)); + + C = Cudd_addBddPattern(dd, M); + if (C == 0) exit(2); + Cudd_Ref(C); + if (pr>0) {(void) printf(":3: C"); Cudd_PrintDebug(dd,C,nx+ny,pr);} + + /* Test iterators. */ + retval = testIterators(dd,M,C,pr); + if (retval == 0) exit(2); + + if (pr > 0) + cuddCacheProfile(dd,stdout); + + /* Test XOR */ + retval = testXor(dd,C,pr,nx+ny); + if (retval == 0) exit(2); + + /* Test Hamming distance functions. */ + retval = testHamming(dd,C,pr); + if (retval == 0) exit(2); + + /* Test selection functions. */ + CP = Cudd_CProjection(dd,C,ycube); + if (CP == NULL) exit(2); + Cudd_Ref(CP); + if (pr>0) {(void) printf("ycube"); Cudd_PrintDebug(dd,ycube,nx+ny,pr);} + if (pr>0) {(void) printf("CP"); Cudd_PrintDebug(dd,CP,nx+ny,pr);} + + if (nx == ny) { + CPr = Cudd_PrioritySelect(dd,C,xvars,yvars,(DdNode **)NULL, + (DdNode *)NULL,ny,Cudd_Xgty); + if (CPr == NULL) exit(2); + Cudd_Ref(CPr); + if (pr>0) {(void) printf(":4: CPr"); Cudd_PrintDebug(dd,CPr,nx+ny,pr);} + if (CP != CPr) { + (void) printf("CP != CPr!\n"); + } + Cudd_RecursiveDeref(dd, CPr); + } + + /* Test inequality generator. */ + { + int Nmin = ddMin(nx,ny); + int q; + DdGen *gen; + int *cube; + DdNode *f = Cudd_Inequality(dd,Nmin,2,xvars,yvars); + if (f == NULL) exit(2); + Cudd_Ref(f); + if (pr>0) { + (void) printf(":4: ineq"); + Cudd_PrintDebug(dd,f,nx+ny,pr); + if (pr>1) { + Cudd_ForeachPrime(dd,Cudd_Not(f),Cudd_Not(f),gen,cube) { + for (q = 0; q < dd->size; q++) { + switch (cube[q]) { + case 0: + (void) printf("1"); + break; + case 1: + (void) printf("0"); + break; + case 2: + (void) printf("-"); + break; + default: + (void) printf("?"); + } + } + (void) printf(" 1\n"); + } + (void) printf("\n"); + } + } + Cudd_IterDerefBdd(dd, f); + } + FREE(xvars); FREE(yvars); + + Cudd_RecursiveDeref(dd, CP); + + /* Test functions for essential variables. */ + ess = Cudd_FindEssential(dd,C); + if (ess == NULL) exit(2); + Cudd_Ref(ess); + if (pr>0) {(void) printf(":4: ess"); Cudd_PrintDebug(dd,ess,nx+ny,pr);} + Cudd_RecursiveDeref(dd, ess); + + /* Test functions for shortest paths. */ + shortP = Cudd_ShortestPath(dd, M, NULL, NULL, &length); + if (shortP == NULL) exit(2); + Cudd_Ref(shortP); + if (pr>0) { + (void) printf(":5: shortP"); Cudd_PrintDebug(dd,shortP,nx+ny,pr); + } + /* Test functions for largest cubes. */ + largest = Cudd_LargestCube(dd, Cudd_Not(C), &length); + if (largest == NULL) exit(2); + Cudd_Ref(largest); + if (pr>0) { + (void) printf(":5b: largest"); + Cudd_PrintDebug(dd,largest,nx+ny,pr); + } + Cudd_RecursiveDeref(dd, largest); + + /* Test Cudd_addEvalConst and Cudd_addIteConstant. */ + shortA = Cudd_BddToAdd(dd,shortP); + if (shortA == NULL) exit(2); + Cudd_Ref(shortA); + Cudd_RecursiveDeref(dd, shortP); + constN = Cudd_addEvalConst(dd,shortA,M); + if (constN == DD_NON_CONSTANT) exit(2); + if (Cudd_addIteConstant(dd,shortA,M,constN) != constN) exit(2); + if (pr>0) {(void) printf("The value of M along the chosen shortest path is %g\n", cuddV(constN));} + Cudd_RecursiveDeref(dd, shortA); + + shortP = Cudd_ShortestPath(dd, C, NULL, NULL, &length); + if (shortP == NULL) exit(2); + Cudd_Ref(shortP); + if (pr>0) { + (void) printf(":6: shortP"); Cudd_PrintDebug(dd,shortP,nx+ny,pr); + } + + /* Test Cudd_bddIteConstant and Cudd_bddLeq. */ + if (!Cudd_bddLeq(dd,shortP,C)) exit(2); + if (Cudd_bddIteConstant(dd,Cudd_Not(shortP),one,C) != one) exit(2); + Cudd_RecursiveDeref(dd, shortP); + + /* Experiment with support functions. */ + if (!testSupport(dd,M,ycube,pr)) { + exit(2); + } + Cudd_RecursiveDeref(dd, ycube); + + if (profile) { + retval = cuddHeapProfile(dd); + } + + size = dd->size; + + if (pr>0) { + (void) printf("Average distance: %g\n", Cudd_AverageDistance(dd)); + } + + /* Reorder if so requested. */ + if (approach != CUDD_REORDER_NONE) { +#ifndef DD_STATS + retval = Cudd_EnableReorderingReporting(dd); + if (retval == 0) { + (void) fprintf(stderr,"Error reported by Cudd_EnableReorderingReporting\n"); + exit(3); + } +#endif +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + exit(3); + } + retval = Cudd_CheckKeys(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + exit(3); + } +#endif + retval = Cudd_ReduceHeap(dd,(Cudd_ReorderingType)approach,5); + if (retval == 0) { + (void) fprintf(stderr,"Error reported by Cudd_ReduceHeap\n"); + exit(3); + } +#ifndef DD_STATS + retval = Cudd_DisableReorderingReporting(dd); + if (retval == 0) { + (void) fprintf(stderr,"Error reported by Cudd_DisableReorderingReporting\n"); + exit(3); + } +#endif +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + exit(3); + } + retval = Cudd_CheckKeys(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); + exit(3); + } +#endif + if (approach == CUDD_REORDER_SYMM_SIFT || + approach == CUDD_REORDER_SYMM_SIFT_CONV) { + Cudd_SymmProfile(dd,0,dd->size-1); + } + + if (pr>0) { + (void) printf("Average distance: %g\n", Cudd_AverageDistance(dd)); + } + + if (keepperm) { + /* Print variable permutation. */ + (void) printf("Variable Permutation:"); + for (i=0; iinvperm[i]); + } + (void) printf("\n"); + (void) printf("Inverse Permutation:"); + for (i=0; iperm[i]); + } + (void) printf("\n"); + } + + if (pr>0) {(void) printf("M"); Cudd_PrintDebug(dd,M,nx+ny,pr);} + + if (profile) { + retval = cuddHeapProfile(dd); + } + + } + + /* Dump DDs of C and M if so requested. */ + if (dfile != NULL) { + dfunc[0] = C; + dfunc[1] = M; + if (blifOrDot == 1) { + /* Only dump C because blif cannot handle ADDs */ + retval = Cudd_DumpBlif(dd,1,dfunc,NULL,(char **)onames, + NULL,dfp,0); + } else { + retval = Cudd_DumpDot(dd,2,dfunc,NULL,(char **)onames,dfp); + } + if (retval != 1) { + (void) fprintf(stderr,"abnormal termination\n"); + exit(2); + } + } + + Cudd_RecursiveDeref(dd, C); + Cudd_RecursiveDeref(dd, M); + + if (clearcache) { + if (pr>0) {(void) printf("Clearing the cache... ");} + for (i = dd->cacheSlots - 1; i>=0; i--) { + dd->cache[i].data = NULL; + } + if (pr>0) {(void) printf("done\n");} + } + if (pr>0) { + (void) printf("Number of variables = %6d\t",dd->size); + (void) printf("Number of slots = %6u\n",dd->slots); + (void) printf("Number of keys = %6u\t",dd->keys); + (void) printf("Number of min dead = %6u\n",dd->minDead); + } + + } while (multiple && !feof(fp)); + + fclose(fp); + if (dfile != NULL) { + fclose(dfp); + } + + /* Second phase: experiment with Walsh matrices. */ + if (!testWalsh(dd,N,cmu,approach,pr)) { + exit(2); + } + + /* Check variable destruction. */ + assert(cuddDestroySubtables(dd,3)); + if (pr == 0) { + savefp = Cudd_ReadStdout(dd); + Cudd_SetStdout(dd,fopen("/dev/null","a")); + } + assert(Cudd_DebugCheck(dd) == 0); + assert(Cudd_CheckKeys(dd) == 0); + if (pr == 0) { + Cudd_SetStdout(dd,savefp); + } + + retval = Cudd_CheckZeroRef(dd); + ok = retval != 0; /* ok == 0 means O.K. */ + if (retval != 0) { + (void) fprintf(stderr, + "%d non-zero DD reference counts after dereferencing\n", retval); + } + + if (pr > 0) { + (void) Cudd_PrintInfo(dd,stdout); + } + + Cudd_Quit(dd); + +#ifdef MNEMOSYNE + mnem_writestats(); +#endif + + if (pr>0) (void) printf("total time = %s\n", + util_print_time(util_cpu_time() - startTime)); + + if (pr > 0) util_print_cpu_stats(stdout); + return ok; + /* NOTREACHED */ + +} /* end of main */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints usage info for testcudd.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +usage(char *prog) +{ + (void) fprintf(stderr, "usage: %s [options] [file]\n", prog); + (void) fprintf(stderr, " -C\t\tuse CMU multiplication algorithm\n"); + (void) fprintf(stderr, " -D\t\tenable automatic dynamic reordering\n"); + (void) fprintf(stderr, " -H\t\tread matrix in Harwell format\n"); + (void) fprintf(stderr, " -M\t\tturns off memory allocation recording\n"); + (void) fprintf(stderr, " -P\t\tprint BDD heap profile\n"); + (void) fprintf(stderr, " -S n\t\tnumber of slots for each subtable\n"); + (void) fprintf(stderr, " -X n\t\ttarget maximum memory in bytes\n"); + (void) fprintf(stderr, " -a n\t\tchoose reordering approach (0-13)\n"); + (void) fprintf(stderr, " \t\t\t0: same as autoMethod\n"); + (void) fprintf(stderr, " \t\t\t1: no reordering (default)\n"); + (void) fprintf(stderr, " \t\t\t2: random\n"); + (void) fprintf(stderr, " \t\t\t3: pivot\n"); + (void) fprintf(stderr, " \t\t\t4: sifting\n"); + (void) fprintf(stderr, " \t\t\t5: sifting to convergence\n"); + (void) fprintf(stderr, " \t\t\t6: symmetric sifting\n"); + (void) fprintf(stderr, " \t\t\t7: symmetric sifting to convergence\n"); + (void) fprintf(stderr, " \t\t\t8-10: window of size 2-4\n"); + (void) fprintf(stderr, " \t\t\t11-13: window of size 2-4 to conv.\n"); + (void) fprintf(stderr, " \t\t\t14: group sifting\n"); + (void) fprintf(stderr, " \t\t\t15: group sifting to convergence\n"); + (void) fprintf(stderr, " \t\t\t16: simulated annealing\n"); + (void) fprintf(stderr, " \t\t\t17: genetic algorithm\n"); + (void) fprintf(stderr, " -b\t\tuse blif as format for dumps\n"); + (void) fprintf(stderr, " -c\t\tclear the cache after each matrix\n"); + (void) fprintf(stderr, " -d file\tdump DDs to file\n"); + (void) fprintf(stderr, " -g\t\tselect aggregation criterion (0,5,7)\n"); + (void) fprintf(stderr, " -h\t\tprints this message\n"); + (void) fprintf(stderr, " -k\t\tprint the variable permutation\n"); + (void) fprintf(stderr, " -m\t\tread multiple matrices (only with -H)\n"); + (void) fprintf(stderr, " -n n\t\tnumber of variables\n"); + (void) fprintf(stderr, " -p n\t\tcontrol verbosity\n"); + (void) fprintf(stderr, " -v n\t\tinitial variables in the unique table\n"); + (void) fprintf(stderr, " -x n\t\tinitial size of the cache\n"); + exit(2); +} /* end of usage */ + + +/**Function******************************************************************** + + Synopsis [Opens a file.] + + Description [Opens a file, or fails with an error message and exits. + Allows '-' as a synonym for standard input.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static FILE * +open_file(char *filename, const char *mode) +{ + FILE *fp; + + if (strcmp(filename, "-") == 0) { + return mode[0] == 'r' ? stdin : stdout; + } else if ((fp = fopen(filename, mode)) == NULL) { + perror(filename); + exit(1); + } + return fp; + +} /* end of open_file */ + + +/**Function******************************************************************** + + Synopsis [Tests Walsh matrix multiplication.] + + Description [Tests Walsh matrix multiplication. Return 1 if successful; + 0 otherwise.] + + SideEffects [May create new variables in the manager.] + + SeeAlso [] + +******************************************************************************/ +static int +testWalsh( + DdManager *dd /* manager */, + int N /* number of variables */, + int cmu /* use CMU approach to matrix multiplication */, + int approach /* reordering approach */, + int pr /* verbosity level */) +{ + DdNode *walsh1, *walsh2, *wtw; + DdNode **x, **v, **z; + int i, retval; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + + if (N > 3) { + x = ALLOC(DdNode *,N); + v = ALLOC(DdNode *,N); + z = ALLOC(DdNode *,N); + + for (i = N-1; i >= 0; i--) { + Cudd_Ref(x[i]=cuddUniqueInter(dd,3*i,one,zero)); + Cudd_Ref(v[i]=cuddUniqueInter(dd,3*i+1,one,zero)); + Cudd_Ref(z[i]=cuddUniqueInter(dd,3*i+2,one,zero)); + } + Cudd_Ref(walsh1 = Cudd_addWalsh(dd,v,z,N)); + if (pr>0) {(void) printf("walsh1"); Cudd_PrintDebug(dd,walsh1,2*N,pr);} + Cudd_Ref(walsh2 = Cudd_addWalsh(dd,x,v,N)); + if (cmu) { + Cudd_Ref(wtw = Cudd_addTimesPlus(dd,walsh2,walsh1,v,N)); + } else { + Cudd_Ref(wtw = Cudd_addMatrixMultiply(dd,walsh2,walsh1,v,N)); + } + if (pr>0) {(void) printf("wtw"); Cudd_PrintDebug(dd,wtw,2*N,pr);} + + if (approach != CUDD_REORDER_NONE) { +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + return(0); + } +#endif + retval = Cudd_ReduceHeap(dd,(Cudd_ReorderingType)approach,5); + if (retval == 0) { + (void) fprintf(stderr,"Error reported by Cudd_ReduceHeap\n"); + return(0); + } +#ifdef DD_DEBUG + retval = Cudd_DebugCheck(dd); + if (retval != 0) { + (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); + return(0); + } +#endif + if (approach == CUDD_REORDER_SYMM_SIFT || + approach == CUDD_REORDER_SYMM_SIFT_CONV) { + Cudd_SymmProfile(dd,0,dd->size-1); + } + } + /* Clean up. */ + Cudd_RecursiveDeref(dd, wtw); + Cudd_RecursiveDeref(dd, walsh1); + Cudd_RecursiveDeref(dd, walsh2); + for (i=0; i < N; i++) { + Cudd_RecursiveDeref(dd, x[i]); + Cudd_RecursiveDeref(dd, v[i]); + Cudd_RecursiveDeref(dd, z[i]); + } + FREE(x); + FREE(v); + FREE(z); + } + return(1); + +} /* end of testWalsh */ + +/**Function******************************************************************** + + Synopsis [Tests iterators.] + + Description [Tests iterators on cubes and nodes.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +testIterators( + DdManager *dd, + DdNode *M, + DdNode *C, + int pr) +{ + int *cube; + CUDD_VALUE_TYPE value; + DdGen *gen; + int q; + + /* Test iterator for cubes. */ + if (pr>1) { + (void) printf("Testing iterator on cubes:\n"); + Cudd_ForeachCube(dd,M,gen,cube,value) { + for (q = 0; q < dd->size; q++) { + switch (cube[q]) { + case 0: + (void) printf("0"); + break; + case 1: + (void) printf("1"); + break; + case 2: + (void) printf("-"); + break; + default: + (void) printf("?"); + } + } + (void) printf(" %g\n",value); + } + (void) printf("\n"); + } + + if (pr>1) { + (void) printf("Testing prime expansion of cubes:\n"); + if (!Cudd_bddPrintCover(dd,C,C)) return(0); + } + + if (pr>1) { + (void) printf("Testing iterator on primes (CNF):\n"); + Cudd_ForeachPrime(dd,Cudd_Not(C),Cudd_Not(C),gen,cube) { + for (q = 0; q < dd->size; q++) { + switch (cube[q]) { + case 0: + (void) printf("1"); + break; + case 1: + (void) printf("0"); + break; + case 2: + (void) printf("-"); + break; + default: + (void) printf("?"); + } + } + (void) printf(" 1\n"); + } + (void) printf("\n"); + } + + /* Test iterator on nodes. */ + if (pr>2) { + DdNode *node; + (void) printf("Testing iterator on nodes:\n"); + Cudd_ForeachNode(dd,M,gen,node) { + if (Cudd_IsConstant(node)) { +#if SIZEOF_VOID_P == 8 + (void) printf("ID = 0x%lx\tvalue = %-9g\n", + (ptruint) node / + (ptruint) sizeof(DdNode), + Cudd_V(node)); +#else + (void) printf("ID = 0x%x\tvalue = %-9g\n", + (ptruint) node / + (ptruint) sizeof(DdNode), + Cudd_V(node)); +#endif + } else { +#if SIZEOF_VOID_P == 8 + (void) printf("ID = 0x%lx\tindex = %u\tr = %u\n", + (ptruint) node / + (ptruint) sizeof(DdNode), + node->index, node->ref); +#else + (void) printf("ID = 0x%x\tindex = %u\tr = %u\n", + (ptruint) node / + (ptruint) sizeof(DdNode), + node->index, node->ref); +#endif + } + } + (void) printf("\n"); + } + return(1); + +} /* end of testIterators */ + + +/**Function******************************************************************** + + Synopsis [Tests the functions related to the exclusive OR.] + + Description [Tests the functions related to the exclusive OR. It + builds the boolean difference of the given function in three + different ways and checks that the results is the same. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +testXor(DdManager *dd, DdNode *f, int pr, int nvars) +{ + DdNode *f1, *f0, *res1, *res2; + int x; + + /* Extract cofactors w.r.t. mid variable. */ + x = nvars / 2; + f1 = Cudd_Cofactor(dd,f,dd->vars[x]); + if (f1 == NULL) return(0); + Cudd_Ref(f1); + + f0 = Cudd_Cofactor(dd,f,Cudd_Not(dd->vars[x])); + if (f0 == NULL) { + Cudd_RecursiveDeref(dd,f1); + return(0); + } + Cudd_Ref(f0); + + /* Compute XOR of cofactors with ITE. */ + res1 = Cudd_bddIte(dd,f1,Cudd_Not(f0),f0); + if (res1 == NULL) return(0); + Cudd_Ref(res1); + + if (pr>0) {(void) printf("xor1"); Cudd_PrintDebug(dd,res1,nvars,pr);} + + /* Compute XOR of cofactors with XOR. */ + res2 = Cudd_bddXor(dd,f1,f0); + if (res2 == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(0); + } + Cudd_Ref(res2); + + if (res1 != res2) { + if (pr>0) {(void) printf("xor2"); Cudd_PrintDebug(dd,res2,nvars,pr);} + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(0); + } + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,f1); + Cudd_RecursiveDeref(dd,f0); + + /* Compute boolean difference directly. */ + res1 = Cudd_bddBooleanDiff(dd,f,x); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd,res2); + return(0); + } + Cudd_Ref(res1); + + if (res1 != res2) { + if (pr>0) {(void) printf("xor3"); Cudd_PrintDebug(dd,res1,nvars,pr);} + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(0); + } + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(1); + +} /* end of testXor */ + + +/**Function******************************************************************** + + Synopsis [Tests the Hamming distance functions.] + + Description [Tests the Hammming distance functions. Returns + 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +testHamming( + DdManager *dd, + DdNode *f, + int pr) +{ + DdNode **vars, *minBdd, *zero, *scan; + int i; + int d; + int *minterm; + int size = Cudd_ReadSize(dd); + + vars = ALLOC(DdNode *, size); + if (vars == NULL) return(0); + for (i = 0; i < size; i++) { + vars[i] = Cudd_bddIthVar(dd,i); + } + + minBdd = Cudd_bddPickOneMinterm(dd,Cudd_Not(f),vars,size); + Cudd_Ref(minBdd); + if (pr > 0) { + (void) printf("Chosen minterm for Hamming distance test: "); + Cudd_PrintDebug(dd,minBdd,size,pr); + } + + minterm = ALLOC(int,size); + if (minterm == NULL) { + FREE(vars); + Cudd_RecursiveDeref(dd,minBdd); + return(0); + } + scan = minBdd; + zero = Cudd_Not(DD_ONE(dd)); + while (!Cudd_IsConstant(scan)) { + DdNode *R = Cudd_Regular(scan); + DdNode *T = Cudd_T(R); + DdNode *E = Cudd_E(R); + if (R != scan) { + T = Cudd_Not(T); + E = Cudd_Not(E); + } + if (T == zero) { + minterm[R->index] = 0; + scan = E; + } else { + minterm[R->index] = 1; + scan = T; + } + } + Cudd_RecursiveDeref(dd,minBdd); + + d = Cudd_MinHammingDist(dd,f,minterm,size); + + if (pr > 0) + (void) printf("Minimum Hamming distance = %d\n", d); + + FREE(vars); + FREE(minterm); + return(1); + +} /* end of testHamming */ + + +/**Function******************************************************************** + + Synopsis [Tests the support functions.] + + Description [Tests the support functions. Returns + 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +testSupport( + DdManager *dd, + DdNode *f, + DdNode *g, + int pr) +{ + DdNode *sb, *common, *onlyF, *onlyG; + DdNode *F[2]; + int *support; + int ret, ssize; + int size = Cudd_ReadSize(dd); + + sb = Cudd_Support(dd, f); + if (sb == NULL) return(0); + Cudd_Ref(sb); + if (pr > 0) { + (void) printf("Support of f: "); + Cudd_PrintDebug(dd,sb,size,pr); + } + Cudd_RecursiveDeref(dd, sb); + + ssize = Cudd_SupportIndices(dd, f, &support); + if (ssize == CUDD_OUT_OF_MEM) return(0); + if (pr > 0) { + (void) printf("Size of the support of f: %d\n", ssize); + } + FREE(support); + + ssize = Cudd_SupportSize(dd, f); + if (pr > 0) { + (void) printf("Size of the support of f: %d\n", ssize); + } + + F[0] = f; + F[1] = g; + sb = Cudd_VectorSupport(dd, F, 2); + if (sb == NULL) return(0); + Cudd_Ref(sb); + if (pr > 0) { + (void) printf("Support of f and g: "); + Cudd_PrintDebug(dd,sb,size,pr); + } + Cudd_RecursiveDeref(dd, sb); + + ssize = Cudd_VectorSupportIndices(dd, F, 2, &support); + if (ssize == CUDD_OUT_OF_MEM) return(0); + if (pr > 0) { + (void) printf("Size of the support of f and g: %d\n", ssize); + } + FREE(support); + + ssize = Cudd_VectorSupportSize(dd, F, 2); + if (pr > 0) { + (void) printf("Size of the support of f and g: %d\n", ssize); + } + + ret = Cudd_ClassifySupport(dd, f, g, &common, &onlyF, &onlyG); + if (ret == 0) return(0); + Cudd_Ref(common); Cudd_Ref(onlyF); Cudd_Ref(onlyG); + if (pr > 0) { + (void) printf("Support common to f and g: "); + Cudd_PrintDebug(dd,common,size,pr); + (void) printf("Support private to f: "); + Cudd_PrintDebug(dd,onlyF,size,pr); + (void) printf("Support private to g: "); + Cudd_PrintDebug(dd,onlyG,size,pr); + } + Cudd_RecursiveDeref(dd, common); + Cudd_RecursiveDeref(dd, onlyF); + Cudd_RecursiveDeref(dd, onlyG); + + return(1); + +} /* end of testSupport */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/Makefile b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/Makefile new file mode 100644 index 000000000..d84881a16 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/Makefile @@ -0,0 +1,243 @@ +#----------------------------------------------------------------------------# +# Makefile for the dddmp distribution kit # +# dddmp: Decision Diagram DuMP # +# (storage and retrieval of BDDs, ADDs and CNF formulas) # +# Revision: Version 2.0.2, February 01, 2004 # +#----------------------------------------------------------------------------# + +# Commands Available: +# make +# it makes the library libdddmp.a +# make testdddmp +# it makes the testdddmp program, which allows to test the dddmp +# package +# make clean +# it cleans dddmp +# make distclean +# it cleans dddmp (as clean) with libraries and executable +# files + +#----------------------------------------------------------------------------# +# Configuration Section # +# uncomment the desired options/sections # +#----------------------------------------------------------------------------# + +#--------------------# +# Define Directories # +#--------------------# + +# Cudd directory +WHERE = .. +#WHERE = ../cudd-2.4.0 + +# Include directory (Cudd include files) +INCLUDE = $(WHERE)/include + +#------------------------# +# Define C Compiler Used # +#------------------------# + +CC = gcc +#CC = g++ +#CC = cc +#CC = icc +#CC = ecc +#CC = /usr/ucb/cc +#CC = c89 + +.SUFFIXES: .o .c .u + +#---------------# +# Define ranlib # +#---------------# + +# For machines with ranlib and you think it is needed +RANLIB = ranlib +# For machines which either do not have ranlib or can do without it +#RANLIB = : + +#----------------------------------# +# Define Machine Independent Flags # +#----------------------------------# + +# Settings for cc +#ICFLAGS = +#ICFLAGS = -g +#ICFLAGS = -O +# Settings for optimized code with gcc +#ICFLAGS = -g -Wall +#ICFLAGS = -g -O3 -Wall +ICFLAGS = -g -O6 -Wall + +#--------------------------------# +# Define Machine Dependent Flags # +#--------------------------------# + +# When no special flags are needed +#XCFLAGS = -DHAVE_IEEE_754 -DBSD +# Linux with Gcc 2.8.1 or higher on i686. +#XCFLAGS = -mcpu=pentiumpro -malign-double -DHAVE_IEEE_754 -DBSD +# Gcc 3.3.2 or higher on i686. +XCFLAGS = -mcpu=pentium4 -malign-double -DHAVE_IEEE_754 -DBSD +# For Solaris, BSD should not be replaced by UNIX100. +#XCFLAGS = -DHAVE_IEEE_754 -DUNIX100 -DEPD_BIG_ENDIAN +# New native compiler for the Alphas; 64-bit pointers. +#XCFLAGS = -g3 -O4 -std -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8 +# New native compiler for the Alphas; 32-bit pointers. +#XCFLAGS = -g3 -O4 -std -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -xtaso -DSIZEOF_LONG=8 +# Windows95/98/NT/XP with Cygwin tools +#XCFLAGS = -mcpu=pentiumpro -malign-double -DHAVE_IEEE_754 -DHAVE_GETRLIMIT=0 -DRLIMIT_DATA_DEFAULT=67108864 + +#---------------------------------------------# +# Define Level of Self-Checking and Verbosity # +#---------------------------------------------# + +# ... for the CUDD package +#DDDEBUG = -DDD_DEBUG -DDD_VERBOSE -DDD_STATS -DDD_CACHE_PROFILE -DDD_UNIQUE_PROFILE -DDD_COUNT +DDDEBUG = + +# ... for the MTR package +#MTRDEBUG = -DMTR_DEBUG +MTRDEBUG = + +# ... for the DDDMP package +#DDDMPDEBUG = -DDDDMP_DEBUG +DDDMPDEBUG = + +#-----------------------# +# Define Loader Options # +#-----------------------# + +LDFLAGS = +# This may produce faster code on the DECstations. +#LDFLAGS = -jmpopt -Olimit 1000 +# This may be necessary under some old versions of Linux. +#LDFLAGS = -static +# This normally makes the program faster on the DEC Alphas. +#LDFLAGS = -non_shared -om +# This is for 32-bit pointers on the DEC Alphas. +#LDFLAGS = -non_shared -om -taso +#LDFLAGS = -non_shared -taso + +#-------------# +# Define PURE # +#-------------# + +PURE = +# ... as purify to link with purify. +#PURE = purify +# ... as quantify to link with quantify. +#PURE = quantify + +#------------# +# Define EXE # +#------------# + +EXE = +# ... as .exe for MS-DOS and derivatives. +#EXE = .exe + +#----------------------------------------------------------------------------# +# Files for the Package # +#----------------------------------------------------------------------------# + +P = dddmp +PSRC = dddmpStoreBdd.c dddmpStoreAdd.c dddmpStoreCnf.c \ + dddmpLoad.c dddmpLoadCnf.c \ + dddmpNodeBdd.c dddmpNodeAdd.c dddmpNodeCnf.c \ + dddmpStoreMisc.c dddmpUtil.c dddmpBinary.c dddmpConvert.c \ + dddmpDbg.c +PHDR = dddmp.h dddmpInt.h $(INCLUDE)/cudd.h $(INCLUDE)/cuddInt.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +TARGET = test$(P)$(EXE) +TARGETu = test$(P)-u + +# files for the test program +SRC = test$(P).c +OBJ = $(SRC:.c=.o) +UBJ = $(SRC:.c=.u) + +#----------------------------------------------------------------------------# +# Rules to compile and build libraries and executables # +#----------------------------------------------------------------------------# + +#MFLAG = +MFLAG = -DMNEMOSYNE +MNEMLIB = ../mnemosyne/libmnem.a + +# This is to create the lint library +LINTFLAGS = -u -n +LINTSWITCH = -o + +LIBS = ./libdddmp.a $(WHERE)/cudd/libcudd.a $(WHERE)/mtr/libmtr.a \ + $(WHERE)/st/libst.a $(WHERE)/util/libutil.a $(WHERE)/epd/libepd.a + +MNEMLIB = + +BLIBS = -kL. -kldddmp -kL$(WHERE)/cudd -klcudd -kL$(WHERE)/mtr -klmtr \ + -kL$(WHERE)/st -klst -kL$(WHERE)/util -klutil + +LINTLIBS = ./llib-ldddmp.ln $(WHERE)/cudd/llib-lcudd.ln \ + $(WHERE)/mtr/llib-lmtr.ln $(WHERE)/st/llib-lst.ln \ + $(WHERE)/util/llib-lutil.ln + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(ICFLAGS) $(XCFLAGS) $(DDDEBUG) $(MTRDEBUG) $(DDDMPDEBUG) $(LDFLAGS) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PHDR) + cc -c $< -I$(INCLUDE) $(CFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) +$(OBJ): $(PHDR) +$(UBJ): $(PHDR) + +$(TARGET): $(SRC) $(OBJ) $(PHDR) $(LIBS) $(MNEMLIB) + $(PURE) $(CC) $(ICFLAGS) $(XCFLAGS) $(DDDEBUG) $(MTRDEBUG) $(DDDMPDEBUG) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +# optimize (DECstations and Alphas only: uses u-code) +$(TARGETu): $(SRC) $(UBJ) $(PHDR) $(LIBS:.a=.b) + cc -O3 -Olimit 1000 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +lintpgm: lint + lint $(LINTFLAGS) -I$(INCLUDE) $(SRC) $(LINTLIBS) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +programs: $(TARGET) $(TARGETu) lintpgm + +#----------------------------------------------------------------------------# +# Clean the Package # +#----------------------------------------------------------------------------# + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \ + *.bak *~ tags .gdb_history *.qv *.qx + + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/README.dddmp b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/README.dddmp new file mode 100644 index 000000000..aefc5afbe --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/README.dddmp @@ -0,0 +1,64 @@ +README file for the DDDMP-2.0 package +Revision: Version 2.0.2, February 01, 2004 + + + +WHAT IS DDDMP +============= + +The DDDMP package defines formats for DD storage on file, and it contains a +set of functions to dump DDs and DD forests on file. + +In the version 1.0, only BDDs (ROBDDs) of the CUDD package (version 2.2.0 +or higher) were supported. +The version 2.0 includes supports for ADDs and CNF formulas. +The version 2.0.2 is for bug fixes. + + + +MAKE DDDMP +========== + +Before you build the libraries and programs, you need to check the +Makefile in the top directory. +Go through the definitions contained in the configuration section, and +select the desired compiler and compilation flags. +Instructions are provided in the comments of the Makefile. + +Then run "make". +This should produce the dddmplib.a library. + + + +DOCUMENTATION +============= + +Directory dddmp/doc contains HTML documentation for the package. +The recommended starting point is package.html. +Documentation in both postscript format and plain text format is also +provided. + + + +FTP SITE +======== + +The package is singularly available from the author home page: +http://staff.polito.it/{gianpiero.cabodi,stefano.quer} + + + + +FEEDBACK +======== + +Send feedback to: + +Stefano Quer & Gianpiero Cabodi +Politecnico di Torino +Dip. Automatica e Informatica +C.so Duca degli Abruzzi 24 +I-10129 Torino +Italy +E-mail: {gianpiero.cabodi,stefano.quer}@polito.it +WEB page: http://staff.polito.it/{gianpiero.cabodi,stefano.quer} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/README.testdddmp b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/README.testdddmp new file mode 100644 index 000000000..df3a265bc --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/README.testdddmp @@ -0,0 +1,79 @@ +README file for the test program of the DDDMP-2.0 package +Revision: Version 2.0.2, February 01, 2004 + + + +WHAT IS TESTDDDMP +================= + +testdddmp is a test program for the dddmp package. +Practically, it is a naive user interface to load, store and execute +operations with BDDs. +It is included to provide a sanity check for the installation of the +package and an easy tool to play with BDDs and BDD on files. + + + +MAKE TESTDDDMP +============== + +Run "make testdddmp". +This should produce the testdddmp executable file. + + + +TEST DDDMP +========== + +Run the runAllTest.script file in the exp directory. +This should run all the test?.script files in the same directory. +Each of them is specifically written to check a particular feature of +the package (e.g., store and load of BDDs, store of CNF formulas and +retrieval, etc.). +Each test?.script should terminate with a comparison with a previously +generated set of files, then with the following set of messages: + +Files 0or1.bdd and 0or1.bdd2 are identical +Files 2and3.bdd and 2and3.bdd2 are identical +... + +If so everything is OK. + +Notice that mismatches may be caused by the presence of CR - LF characters at +the end of each BDD file line. + + + +WORK WITH DDDMPTEST +=================== + +To work with dddmptest (once the executable file has been built) it is enough +to run it (no parameter is necessary). +The help command print out the main commands available. +For each command further inputs are eventually required on an interactive +basis. +BDDs and ADDs can be loaded from files by choosing the file name or they +can be directly created (randomly for example). +They can be maintained into the main memory trough an array of BDD pointers. +Operations (logical and re-ordering) can be performed on any BDD into this +array. +Eventually any of them can be stored in a file giving the file name. +BDDs can also be stored in a CNF format using three different possible +solution to store them. + + + +FEEDBACK +======== + +Send feedback to: + +Gianpiero Cabodi and Stefano Quer +Politecnico di Torino +Dip. Automatica e Informatica +C.so Duca degli Abruzzi 24 +I-10129 Torino +Italy +E-mail: {gianpiero.cabodi,stefano.quer}@polito.it +WEB page: http://staff.polito.it/{gianpiero.cabodi,stefano.quer} + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/RELEASE_NOTES b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/RELEASE_NOTES new file mode 100644 index 000000000..c8f4b9a6e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/RELEASE_NOTES @@ -0,0 +1,60 @@ +RELEASE NOTES FOR DDDMP +Revision: Version 2.0.2 +Turin, Italy, February 01, 2004 + +dddmp-2.0.2 is now available at +WEB page: http://staff.polito.it/{gianpiero.cabodi,stefano.quer} +dddmp-2.0.2 has a few bug fixes with respect to dddmp-2.0 + +Release 2.0.2 of DDDMP improves DDDMP-1.2 in the following areas: + + 1. Support to store and load ADD has been inserted in the dddmp tool + + 2. Support to store BDDs as CNF formulas has been inserted in the + dddmp tool. + As far as the storing process is concerned three possible formats + are available: + + DDDMP_CNF_MODE_NODE + store a BDD by introducing an auxiliary variable for each BDD node + + DDDMP_CNF_MODE_MAXTERM + store a BDD by following the maxterm of the represented function + + DDDMP_CNF_MODE_BEST + trade-of between the two previous solution, trying to optimize + the number of literals stored. + + As far as the loading process is concerned three possible formats + are available: + + DDDMP_CNF_MODE_NO_CONJ + Return the Clauses without Conjunction + + DDDMP_CNF_MODE_NO_QUANT + Return the sets of BDDs without Quantification + + DDDMP_CNF_MODE_CONJ_QUANT + Return the sets of BDDs AFTER Existential Quantification + + 3. Functions to load the header of a BDD/ADD/CNF file, so collecting + information regarding variables, variable ordering, etc. + This can be seen as a pre-processing step prior a possible BDD/ADD/CNF + load of the entire structure. + Moreover it can be used in a manager initialization phase. + + 4. More precise information are stored in each BDD/ADD header during + the storing phase. + In particular this information may be used to make up the exact + variable ordering present in the manager used during the storing + phase. + Full compatibility with previously versions of the files (from + dddmp-1.0 on) is guaranteed. + + 5. Miscellaneous + Debugging has been performed on different hardware architectures + + 6. The test program, testdddmp has been improved. + Now it allows to perform more operations and to better debug the + different options. + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpBinary.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpBinary.c new file mode 100644 index 000000000..a7cd67482 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpBinary.c @@ -0,0 +1,343 @@ +/**CFile********************************************************************** + + FileName [dddmpBinary.c] + + PackageName [dddmp] + + Synopsis [Input and output BDD codes and integers from/to file] + + Description [Input and output BDD codes and integers from/to file + in binary mode. + DD node codes are written as one byte. + Integers of any length are written as sequences of "linked" bytes. + For each byte 7 bits are used for data and one (MSBit) as link with + a further byte (MSB = 1 means one more byte). + Low level read/write of bytes filter , and + with escape sequences. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int WriteByteBinary(FILE *fp, unsigned char c); +static int ReadByteBinary(FILE *fp, unsigned char *cp); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes 1 byte node code] + + Description [outputs a 1 byte node code using the following format: +
                          +     Unused      : 1 bit;
                          +     V           : 2 bits;     (variable code)
                          +     T           : 2 bits;     (Then code)
                          +     Ecompl      : 1 bit;      (Else complemented)
                          +     E           : 2 bits;     (Else code)
                          +    
                          + Ecompl is set with complemented edges. + ] + + SideEffects [None] + + SeeAlso [DddmpReadCode()] + +******************************************************************************/ + +int +DddmpWriteCode ( + FILE *fp /* IN: file where to write the code */, + struct binary_dd_code code /* IN: the code to be written */ + ) +{ + unsigned char c; + int retValue; + + c = (code.Unused<<7)|(code.V<<5)|(code.T<<3)| + (code.Ecompl<<2)|(code.E); + + retValue = WriteByteBinary (fp, c); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Reads a 1 byte node code] + + Description [Reads a 1 byte node code. See DddmpWriteCode() + for code description.] + + SideEffects [None] + + SeeAlso [DddmpWriteCode()] + +******************************************************************************/ + +int +DddmpReadCode ( + FILE *fp /* IN: file where to read the code */, + struct binary_dd_code *pcode /* OUT: the read code */ + ) +{ + unsigned char c; + + if (ReadByteBinary (fp, &c) == EOF) { + return (0); + } + + pcode->Unused = c>>7; + pcode->V = (c>>5) & 3; + pcode->T = (c>>3) & 3; + pcode->Ecompl = (c>>2) & 1; + pcode->E = c & 3; + + return (1); +} + +/**Function******************************************************************** + + Synopsis [Writes a "packed integer"] + + Description [Writes an integer as a sequence of bytes (MSByte first). + For each byte 7 bits are used for data and one (LSBit) as link + with a further byte (LSB = 1 means one more byte). + ] + + SideEffects [None] + + SeeAlso [DddmpReadInt()] + +******************************************************************************/ + +int +DddmpWriteInt ( + FILE *fp /* IN: file where to write the integer */, + int id /* IN: integer to be written */ + ) +{ + char cvet[4]; + int i; + + for (i=0; i<4; i++) { + cvet[i] = (char)((id & 0x0000007f) << 1); + id >>= 7; + } + + for (i=3; (i>0) && (cvet[i] == 0); i--); + + for (; i>0; i--) { + cvet[i] |= (char)1; + if (WriteByteBinary (fp, cvet[i]) == EOF) + return (0); + } + + if (WriteByteBinary (fp, cvet[0]) == EOF) { + return (0); + } + + return (1); +} + + +/**Function******************************************************************** + + Synopsis [Reads a "packed integer"] + + Description [Reads an integer coded on a sequence of bytes. See + DddmpWriteInt() for format.] + + SideEffects [None] + + SeeAlso [DddmpWriteInt()] + +******************************************************************************/ + +int +DddmpReadInt ( + FILE *fp /* IN: file where to read the integer */, + int *pid /* OUT: the read integer */ + ) +{ + unsigned char c; + int i; + unsigned int id; + + id = 0; + for (i=0; i<4; i++) { + if (ReadByteBinary (fp, &c) == EOF) + return (0); + id = (id<<7) | (c>>1); + if ((c & 1) == 0) + break; + } + + /* Check for correct format: last char should + be found before i = 4 */ + assert(i<4); + + *pid = id; + + return (i+1); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a byte to file filtering , and ] + + Description [outputs a byte to file fp. Uses 0x00 as escape character + to filter , and . + This is done for compatibility between unix and dos/windows systems. + ] + + SideEffects [None] + + SeeAlso [ReadByteBinary()] + +******************************************************************************/ + +static int +WriteByteBinary ( + FILE *fp /* IN: file where to write the byte */, + unsigned char c /* IN: the byte to be written */ + ) +{ + unsigned char BinaryEscape; + + switch (c) { + + case 0x00: /* Escape */ + BinaryEscape = 0x00; + if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) + return (0); + c = 0x00; + break; + case 0x0a: /* */ + BinaryEscape = 0x00; + if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) + return (0); + c = 0x01; + break; + case 0x0d: /* */ + BinaryEscape = 0x00; + if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) + return (0); + c = 0x02; + break; + case 0x1a: /* */ + BinaryEscape = 0x00; + if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) + return (0); + c = 0x03; + break; + } + if (fwrite (&c, sizeof(char), 1, fp) != sizeof(char)) + return (0); + + return (1); +} + +/**Function******************************************************************** + + Synopsis [Reads a byte from file with escaped , and ] + + Description [inputs a byte to file fp. 0x00 has been used as escape character + to filter , and . This is done for + compatibility between unix and dos/windows systems. + ] + + SideEffects [None] + + SeeAlso [WriteByteBinary()] + +******************************************************************************/ + +static int +ReadByteBinary ( + FILE *fp /* IN: file where to read the byte */, + unsigned char *cp /* OUT: the read byte */ + ) +{ + + if (fread (cp, sizeof(char), 1, fp) != sizeof(char)) { + return (0); + } + + if (*cp == 0x00) { /* Escape */ + if (fread (cp, sizeof(char), 1, fp) != sizeof(char)) { + return (0); + } + + switch (*cp) { + + case 0x00: /* Escape */ + break; + case 0x01: /* */ + *cp = 0x0a; + break; + case 0x02: /* */ + *cp = 0x0d; + break; + case 0x03: /* */ + *cp = 0x1a; + break; + } + } + + return (1); +} + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpConvert.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpConvert.c new file mode 100644 index 000000000..c24292e8c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpConvert.c @@ -0,0 +1,180 @@ +/**CFile********************************************************************** + + FileName [dddmpConvert.c] + + PackageName [dddmp] + + Synopsis [Conversion between ASCII and binary formats] + + Description [Conversion between ASCII and binary formats is presently + supported by loading a BDD in the source format and storing it + in the target one. We plan to introduce ad hoc procedures + avoiding explicit BDD node generation. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Converts from ASCII to binary format] + + Description [Converts from ASCII to binary format. A BDD array is loaded and + and stored to the target file.] + + SideEffects [None] + + SeeAlso [Dddmp_Bin2Text()] + +******************************************************************************/ + +int +Dddmp_Text2Bin ( + char *filein /* IN: name of ASCII file */, + char *fileout /* IN: name of binary file */ + ) +{ + DdManager *ddMgr; /* pointer to DD manager */ + DdNode **roots; /* array of BDD roots to be loaded */ + int nRoots; /* number of BDD roots */ + int retValue; + + ddMgr = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); + if (ddMgr == NULL) { + return (0); + } + + nRoots = Dddmp_cuddBddArrayLoad(ddMgr,DDDMP_ROOT_MATCHLIST,NULL, + DDDMP_VAR_MATCHIDS,NULL,NULL,NULL, + DDDMP_MODE_TEXT,filein,NULL,&roots); + + Dddmp_CheckAndGotoLabel (nRoots<=0, + "Negative Number of Roots.", failure); + + retValue = Dddmp_cuddBddArrayStore (ddMgr,NULL,nRoots,roots,NULL, + NULL,NULL,DDDMP_MODE_BINARY,DDDMP_VARIDS,fileout,NULL); + + Dddmp_CheckAndGotoLabel (retValue<=0, + "Error code returned.", failure); + + Cudd_Quit(ddMgr); + return (1); + + failure: + printf("error converting BDD format\n"); + Cudd_Quit(ddMgr); + return (0); +} + +/**Function******************************************************************** + + Synopsis [Converts from binary to ASCII format] + + Description [Converts from binary to ASCII format. A BDD array is loaded and + and stored to the target file.] + + SideEffects [None] + + SeeAlso [Dddmp_Text2Bin()] + +******************************************************************************/ + +int +Dddmp_Bin2Text ( + char *filein /* IN: name of binary file */, + char *fileout /* IN: name of ASCII file */ + ) +{ + DdManager *ddMgr; /* pointer to DD manager */ + DdNode **roots; /* array of BDD roots to be loaded */ + int nRoots; /* number of BDD roots */ + int retValue; + + ddMgr = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); + if (ddMgr == NULL) { + return (0); + } + + nRoots = Dddmp_cuddBddArrayLoad(ddMgr,DDDMP_ROOT_MATCHLIST,NULL, + DDDMP_VAR_MATCHIDS,NULL,NULL,NULL, + DDDMP_MODE_BINARY,filein,NULL,&roots); + + Dddmp_CheckAndGotoLabel (nRoots<=0, + "Negative Number of Roots.", failure); + + retValue = Dddmp_cuddBddArrayStore (ddMgr,NULL,nRoots,roots,NULL, + NULL,NULL,DDDMP_MODE_TEXT,DDDMP_VARIDS,fileout,NULL); + + Dddmp_CheckAndGotoLabel (retValue<=0, + "Error code returned.", failure); + + Cudd_Quit(ddMgr); + return (1); + + failure: + printf("error converting BDD format\n"); + Cudd_Quit(ddMgr); + return (0); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpDbg.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpDbg.c new file mode 100644 index 000000000..88304f5af --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpDbg.c @@ -0,0 +1,166 @@ +/**CFile********************************************************************** + + FileName [dddmpDbg.c] + + PackageName [dddmp] + + Synopsis [Functions to display BDD files] + + Description [Functions to display BDD files in binary format + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Display a binary dump file in a text file] + + Description [Display a binary dump file in a text file] + + SideEffects [None] + + SeeAlso [Dddmp_cuddBddStore , Dddmp_cuddBddLoad ] + +******************************************************************************/ + +int +Dddmp_cuddBddDisplayBinary( + char *fileIn /* IN: name of binary file */, + char *fileOut /* IN: name of text file */ + ) +{ + FILE *fp, *fpo; + int id, size; + struct binary_dd_code code; + char buf[1000]; + int nnodes, i; + + fp = fopen (fileIn, "rb"); + if (fp == 0) { + return (0); + } + + fpo = fopen (fileOut, "w"); + if (fpo == 0) { + return (0); + } + + while (fgets(buf, 999,fp)!=NULL) { + fprintf (fpo, "%s", buf); + if (strncmp(buf, ".nnodes", 7) == 0) { + sscanf (buf, "%*s %d", &nnodes); + } + if (strncmp(buf, ".rootids", 8) == 0) { + break; + } + } + + for (i=1; i<=nnodes; i++) { + if (feof(fp)) { + return (0); + } + if (DddmpReadCode(fp,&code) == 0) { + return (0); + } + fprintf (fpo, "c : v %d | T %d | E %d\n", + (int)code.V, (int)code.T, + (code.Ecompl ? -(int)(code.E) : (int)(code.E))); + if (code.V == DDDMP_TERMINAL) { + continue; + } + if (code.V <= DDDMP_RELATIVE_ID) { + size = DddmpReadInt(fp,&id); + if (size == 0) { + return (0); + } + fprintf(fpo, "v(%d): %d\n", size, id); + } + if (code.T <= DDDMP_RELATIVE_ID) { + size = DddmpReadInt(fp,&id); + if (size == 0) { + return (0); + } + fprintf(fpo, "T(%d): %d\n", size, id); + } + if (code.E <= DDDMP_RELATIVE_ID) { + size = DddmpReadInt(fp,&id); + if (size == 0) { + return (0); + } + fprintf(fpo, "E(%d): %d\n", size, id); + } + + } + + fgets(buf, 999,fp); + if (strncmp(buf, ".end", 4) != 0) { + return (0); + } + + fprintf(fpo, ".end"); + + fclose(fp); + fclose(fpo); + + return (1); +} + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpDdNodeBdd.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpDdNodeBdd.c new file mode 100644 index 000000000..443ef5dbf --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpDdNodeBdd.c @@ -0,0 +1,455 @@ +/**CFile********************************************************************** + + FileName [dddmpDdNodeBdd.c] + + PackageName [dddmp] + + Synopsis [Functions to handle BDD node infos and numbering] + + Description [Functions to handle BDD node infos and numbering. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NumberNodeRecur(DdNode *f, int id); +static void RemoveFromUniqueRecur(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecur(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and number them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodes()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecur(), NumberNodeRecur(), + DddmpUnnumberDdNodes()] + +******************************************************************************/ + +int +DddmpNumberDdNodes ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int n /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int id=0, i; + + for (i=0; inext = (struct DdNode *)((ptruint)((id)<<1)); + } + + return; +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndex(), DddmpSetVisited (), DddmpVisited ()] + +******************************************************************************/ + +int +DddmpReadNodeIndex ( + DdNode *f /* IN: BDD node */ + ) +{ + +#if 0 + if (1 || !Cudd_IsConstant (f)) { +#else + if (!Cudd_IsConstant (f)) { +#endif + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisited (), DddmpClearVisited ()] + +******************************************************************************/ + +int +DddmpVisited ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisited (), DddmpClearVisited ()] + +******************************************************************************/ + +void +DddmpSetVisited ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisited (), DddmpSetVisited ()] + +******************************************************************************/ + +void +DddmpClearVisited ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecur( + DdNode *f /* IN: root of the BDD to be numbered */, + int id /* IN/OUT: index to be assigned to the node */ + ) +{ + f = Cudd_Regular(f); + + if (!DddmpVisited (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecur (cuddT (f), id); + id = NumberNodeRecur (cuddE (f), id); + } + + DddmpWriteNodeIndex (f, ++id); + DddmpClearVisited (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecur()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisited (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecur (ddMgr, cuddT (f)); + RemoveFromUniqueRecur (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisited (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursively)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUnique()] + +******************************************************************************/ + +static void +RestoreInUniqueRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + DddmpClearVisited (f); + /*f->next = NULL;*/ + return; + } + + RestoreInUniqueRecur (ddMgr, cuddT (f)); + RestoreInUniqueRecur (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + f->next = *previousP; + *previousP = f; + + return; +} + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpDdNodeCnf.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpDdNodeCnf.c new file mode 100644 index 000000000..421d920e9 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpDdNodeCnf.c @@ -0,0 +1,944 @@ +/**CFile********************************************************************** + + FileName [dddmpDdNodeCnf.c] + + PackageName [dddmp] + + Synopsis [Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs] + + Description [Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMP_DEBUG_CNF 0 + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpWriteNodeIndexCnf(DdNode *f, int *cnfIds, int id); +static int DddmpReadNodeIndexCnf(DdNode *f); +static int DddmpClearVisitedCnfRecur(DdNode *f); +static int DddmpVisitedCnf(DdNode *f); +static void DddmpSetVisitedCnf(DdNode *f); +static void DddmpClearVisitedCnf(DdNode *f); +static int NumberNodeRecurCnf(DdNode *f, int *cnfIds, int id); +static void DddmpDdNodesCheckIncomingAndScanPath(DdNode *f, int pathLengthCurrent, int edgeInTh, int pathLengthTh); +static int DddmpDdNodesNumberEdgesRecur(DdNode *f, int *cnfIds, int id); +static int DddmpDdNodesResetCountRecur(DdNode *f); +static int DddmpDdNodesCountEdgesRecur(DdNode *f); +static void RemoveFromUniqueRecurCnf(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecurCnf(DdManager *ddMgr, DdNode *f); +static int DddmpPrintBddAndNextRecur(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and numbers them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodesCnf()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecurCnf(), NumberNodeRecurCnf(), + DddmpUnnumberDdNodesCnf()] + +******************************************************************************/ + +int +DddmpNumberDdNodesCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int rootN /* IN: number of BDD roots in the array of BDDs */, + int *cnfIds /* OUT: CNF identifiers for variables */, + int id /* OUT: number of Temporary Variables Introduced */ + ) +{ + int i; + + for (i=0; i BDDs After Count Reset:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*----------------------- Count Incoming Edges ----------------------------*/ + + for (i=0; i BDDs After Count Recur:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*------------------------- Count Path Length ----------------------------*/ + + for (i=0; i BDDs After Check Incoming And Scan Path:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*-------------------- Number Nodes and Set Visited -----------------------*/ + + for (i=0; i BDDs After Count Edges Recur:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*---------------------------- Clear Visited ------------------------------*/ + +#if DDDMP_DEBUG_CNF + for (i=0; i BDDs After All Numbering Process:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif +#endif + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Restores nodes in unique table, loosing numbering] + + Description [Node indexes are no more needed. Nodes are re-linked in the + unique table. + ] + + SideEffects [None] + + SeeAlso [DddmpNumberDdNode()] + +******************************************************************************/ + +void +DddmpUnnumberDdNodesCnf( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int rootN /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int i; + + for (i=0; i Bdd %d:\n", i); + fflush (stdout); + DddmpPrintBddAndNextRecur (ddMgr, f[i]); + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Write index to node] + + Description [The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. + ] + + SideEffects [None] + + SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf () + ] + +******************************************************************************/ + +int +DddmpWriteNodeIndexCnfBis ( + DdNode *f /* IN: BDD node */, + int id /* IN: index to be written */ + ) +{ + if (!Cudd_IsConstant (f)) { + f->next = (struct DdNode *)((ptruint)((id)<<1)); + } + + return (DDDMP_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Write index to node] + + Description [The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. The index corresponds to + the BDD node variable if both the node's children are a + constant node, otherwise a new CNF variable is used. + ] + + SideEffects [None] + + SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf ()] + +*****************************************************************************/ + +static int +DddmpWriteNodeIndexCnf ( + DdNode *f /* IN: BDD node */, + int *cnfIds /* IN: possible source for the index to be written */, + int id /* IN: possible source for the index to be written */ + ) +{ + if (!Cudd_IsConstant (f)) { + if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) { + /* If Variable SET ID as Variable ID */ + f->next = (struct DdNode *)((ptruint)((cnfIds[f->index])<<1)); + } else { + f->next = (struct DdNode *)((ptruint)((id)<<1)); + id++; + } + } + + return(id); +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf ()] + +******************************************************************************/ + +static int +DddmpReadNodeIndexCnf ( + DdNode *f /* IN: BDD node */ + ) +{ + if (!Cudd_IsConstant (f)) { + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Mark ALL nodes as not visited] + + Description [Mark ALL nodes as not visited (it recurs on the node children)] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()] + +******************************************************************************/ + +static int +DddmpClearVisitedCnfRecur ( + DdNode *f /* IN: root of the BDD to be marked */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (cuddIsConstant (f)) { + return (DDDMP_SUCCESS); + } + + if (!DddmpVisitedCnf (f)) { + return (DDDMP_SUCCESS); + } + + retValue = DddmpClearVisitedCnfRecur (cuddT (f)); + retValue = DddmpClearVisitedCnfRecur (cuddE (f)); + + DddmpClearVisitedCnf (f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisitedCnf (), DddmpClearVisitedCnf ()] + +******************************************************************************/ + +static int +DddmpVisitedCnf ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpClearVisitedCnf ()] + +******************************************************************************/ + +static void +DddmpSetVisitedCnf ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()] + +******************************************************************************/ + +static void +DddmpClearVisitedCnf ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecurCnf( + DdNode *f /* IN: root of the BDD to be numbered */, + int *cnfIds /* IN: possible source for numbering */, + int id /* IN/OUT: possible source for numbering */ + ) +{ + f = Cudd_Regular(f); + + if (!DddmpVisitedCnf (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecurCnf (cuddT (f), cnfIds, id); + id = NumberNodeRecurCnf (cuddE (f), cnfIds, id); + } + + id = DddmpWriteNodeIndexCnf (f, cnfIds, id); + DddmpClearVisitedCnf (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with the right polarity. + The node is assigned to a new CNF variable only if it is a "shared" + node (i.e. the number of its incoming edges is greater than 1). + ] + + SideEffects ["visited" flags are set.] + + SeeAlso [] + +******************************************************************************/ + +static void +DddmpDdNodesCheckIncomingAndScanPath ( + DdNode *f /* IN: BDD node to be numbered */, + int pathLengthCurrent /* IN: Current Path Length */, + int edgeInTh /* IN: Max # In-Edges, after a Insert Cut Point */, + int pathLengthTh /* IN: Max Path Length (after, Insert a Cut Point) */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (DddmpVisitedCnf (f)) { + return; + } + + if (cuddIsConstant (f)) { + return; + } + + pathLengthCurrent++; + retValue = DddmpReadNodeIndexCnf (f); + + if ( ((edgeInTh >= 0) && (retValue > edgeInTh)) || + ((pathLengthTh >= 0) && (pathLengthCurrent > pathLengthTh)) + ) { + DddmpWriteNodeIndexCnfBis (f, 1); + pathLengthCurrent = 0; + } else { + DddmpWriteNodeIndexCnfBis (f, 0); + } + + DddmpDdNodesCheckIncomingAndScanPath (cuddT (f), pathLengthCurrent, + edgeInTh, pathLengthTh); + DddmpDdNodesCheckIncomingAndScanPath (cuddE (f), pathLengthCurrent, + edgeInTh, pathLengthTh); + + DddmpSetVisitedCnf (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with the inverse polarity. + Numbering follows the subsequent strategy: + * if the index = 0 it remains so + * if the index >= 1 it gets enumerated. + This implies that the node is assigned to a new CNF variable only if + it is not a terminal node otherwise it is assigned the index of + the BDD variable. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesNumberEdgesRecur ( + DdNode *f /* IN: BDD node to be numbered */, + int *cnfIds /* IN: possible source for numbering */, + int id /* IN/OUT: possible source for numbering */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (!DddmpVisitedCnf (f)) { + return (id); + } + + if (cuddIsConstant (f)) { + return (id); + } + + id = DddmpDdNodesNumberEdgesRecur (cuddT (f), cnfIds, id); + id = DddmpDdNodesNumberEdgesRecur (cuddE (f), cnfIds, id); + + retValue = DddmpReadNodeIndexCnf (f); + if (retValue >= 1) { + id = DddmpWriteNodeIndexCnf (f, cnfIds, id); + } else { + DddmpWriteNodeIndexCnfBis (f, 0); + } + + DddmpClearVisitedCnf (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Resets counter and visited flag for ALL nodes of a BDD] + + Description [Resets counter and visited flag for ALL nodes of a BDD (it + recurs on the node children). The index field of the node is + used as counter. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesResetCountRecur ( + DdNode *f /* IN: root of the BDD whose counters are reset */ + ) +{ + int retValue; + + f = Cudd_Regular (f); + + if (!DddmpVisitedCnf (f)) { + return (DDDMP_SUCCESS); + } + + if (!cuddIsConstant (f)) { + retValue = DddmpDdNodesResetCountRecur (cuddT (f)); + retValue = DddmpDdNodesResetCountRecur (cuddE (f)); + } + + DddmpWriteNodeIndexCnfBis (f, 0); + DddmpClearVisitedCnf (f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Counts the number of incoming edges for each node of a BDD] + + Description [Counts (recursively) the number of incoming edges for each + node of a BDD. This number is stored in the index field. + ] + + SideEffects ["visited" flags remain untouched.] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesCountEdgesRecur ( + DdNode *f /* IN: root of the BDD */ + ) +{ + int indexValue, retValue; + + f = Cudd_Regular (f); + + if (cuddIsConstant (f)) { + return (DDDMP_SUCCESS); + } + + if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) { + return (DDDMP_SUCCESS); + } + + indexValue = DddmpReadNodeIndexCnf (f); + + /* IF (first time) THEN recur */ + if (indexValue == 0) { + retValue = DddmpDdNodesCountEdgesRecur (cuddT (f)); + retValue = DddmpDdNodesCountEdgesRecur (cuddE (f)); + } + + /* Increment Incoming-Edge Count Flag */ + indexValue++; + DddmpWriteNodeIndexCnfBis (f, indexValue); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on son nodes. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecurCnf()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecurCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisitedCnf (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecurCnf (ddMgr, cuddT (f)); + RemoveFromUniqueRecurCnf (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisitedCnf (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursive)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUnique()] + +******************************************************************************/ + +static void +RestoreInUniqueRecurCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + DddmpClearVisitedCnf (f); + /*f->next = NULL;*/ + return; + } + + RestoreInUniqueRecurCnf (ddMgr, cuddT (f)); + RestoreInUniqueRecurCnf (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + f->next = *previousP; + *previousP = f; + + return; +} + +/**Function******************************************************************** + + Synopsis [Prints debug info] + + Description [Prints debug info for a BDD on the screen. It recurs on + node's children. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpPrintBddAndNextRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be displayed */ + ) +{ + int retValue; + DdNode *fPtr, *tPtr, *ePtr; + + fPtr = Cudd_Regular (f); + + if (Cudd_IsComplement (f)) { + fprintf (stdout, "sign=- ptr=%ld ", ((long int) fPtr)); + } else { + fprintf (stdout, "sign=+ ptr=%ld ", ((long int) fPtr)); + } + + if (cuddIsConstant (fPtr)) { + fprintf (stdout, "one\n"); + fflush (stdout); + return (DDDMP_SUCCESS); + } + + fprintf (stdout, + "thenPtr=%ld elsePtr=%ld BddId=%d CnfId=%d Visited=%d\n", + ((long int) cuddT (fPtr)), ((long int) cuddE (fPtr)), + fPtr->index, DddmpReadNodeIndexCnf (fPtr), + DddmpVisitedCnf (fPtr)); + + tPtr = cuddT (fPtr); + ePtr = cuddE (fPtr); + if (Cudd_IsComplement (f)) { + tPtr = Cudd_Not (tPtr); + ePtr = Cudd_Not (ePtr); + } + + retValue = DddmpPrintBddAndNextRecur (ddMgr, tPtr); + retValue = DddmpPrintBddAndNextRecur (ddMgr, ePtr); + + return (DDDMP_SUCCESS); +} + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpLoad.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpLoad.c new file mode 100644 index 000000000..27d9f0918 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpLoad.c @@ -0,0 +1,1486 @@ +/**CFile********************************************************************** + + FileName [dddmpLoad.c] + + PackageName [dddmp] + + Synopsis [Functions to read in bdds to file] + + Description [Functions to read in bdds to file. BDDs + are represended on file either in text or binary format under the + following rules. A file contains a forest of BDDs (a vector of + Boolean functions). BDD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to BDD + functions, followed by the list of nodes. BDD nodes are listed + according to their numbering, and in the present implementation + numbering follows a post-order strategy, in such a way that a node + is never listed before its Then/Else children. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define matchkeywd(str,key) (strncmp(str,key,strlen(key))==0) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpCuddDdArrayLoad(Dddmp_DecompType ddType, DdManager *ddMgr, Dddmp_RootMatchType rootMatchMode, char **rootmatchnames, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***pproots); +static Dddmp_Hdr_t * DddmpBddReadHeader(char *file, FILE *fp); +static void DddmpFreeHeader(Dddmp_Hdr_t *Hdr); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads a dump file representing the argument BDD.] + + Description [Reads a dump file representing the argument BDD. + Dddmp_cuddBddArrayLoad is used through a dummy array (see this + function's description for more details). + Mode, the requested input file format, is checked against + the file format. + The loaded BDDs is referenced before returning it. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddStore, Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +DdNode * +Dddmp_cuddBddLoad ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names - by IDs */, + int *varmatchauxids /* IN: array of variable auxids - by IDs */, + int *varcomposeids /* IN: array of new ids accessed - by IDs */, + int mode /* IN: requested input file format */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + DdNode *f , **tmpArray; + int i, nRoots; + + nRoots = Dddmp_cuddBddArrayLoad(ddMgr,DDDMP_ROOT_MATCHLIST,NULL, + varMatchMode,varmatchnames,varmatchauxids,varcomposeids, + mode,file,fp,&tmpArray); + + if (nRoots == 0) { + return (NULL); + } else { + f = tmpArray[0]; + if (nRoots > 1) { + fprintf (stderr, + "Warning: %d BDD roots found in file. Only first retrieved.\n", + nRoots); + for (i=1; i +
                        • varMatchMode=DDDMP_VAR_MATCHIDS

                          + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

                        • varMatchMode=DDDMP_VAR_MATCHPERMIDS

                          + is used to allow variable match according to the position in the + ordering. + +

                        • varMatchMode=DDDMP_VAR_MATCHNAMES

                          + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

                        • varMatchMode=DDDMP_VAR_MATCHIDS

                          + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

                        • varMatchMode=DDDMP_VAR_COMPOSEIDS

                          + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. + + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. + + All the loaded BDDs are referenced before returning them. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddArrayStore] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayLoad ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_RootMatchType rootMatchMode /* IN: storing mode selector */, + char **rootmatchnames /* IN: sorted names for loaded roots */, + Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by ids */, + int *varmatchauxids /* IN: array of variable auxids, by ids */, + int *varcomposeids /* IN: array of new ids, by ids */, + int mode /* IN: requested input file format */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***pproots /* OUT: array of returned BDD roots */ + ) +{ + int retValue; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Load.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Load.\n"); + fflush (stderr); + } + } +#endif +#endif + + retValue = DddmpCuddDdArrayLoad (DDDMP_BDD, ddMgr, rootMatchMode, + rootmatchnames, varMatchMode, varmatchnames, varmatchauxids, + varcomposeids, mode, file, fp, pproots); + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Load.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Load.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Reads a dump file representing the argument ADD.] + + Description [Reads a dump file representing the argument ADD. + Dddmp_cuddAddArrayLoad is used through a dummy array. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddAddStore, Dddmp_cuddAddArrayLoad] + +******************************************************************************/ + +DdNode * +Dddmp_cuddAddLoad ( + DdManager *ddMgr /* IN: Manager */, + Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names by IDs */, + int *varmatchauxids /* IN: array of variable auxids by IDs */, + int *varcomposeids /* IN: array of new ids by IDs */, + int mode /* IN: requested input file format */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + DdNode *f , **tmpArray; + int i, nRoots; + + nRoots = Dddmp_cuddAddArrayLoad (ddMgr, DDDMP_ROOT_MATCHLIST,NULL, + varMatchMode, varmatchnames, varmatchauxids, varcomposeids, + mode, file, fp, &tmpArray); + + if (nRoots == 0) { + return (NULL); + } else { + f = tmpArray[0]; + if (nRoots > 1) { + fprintf (stderr, + "Warning: %d BDD roots found in file. Only first retrieved.\n", + nRoots); + for (i=1; innodes==0, "Zero number of nodes.", + failure); + + /* + * Type, number of variables (tot and support) + */ + + *ddType = Hdr->ddType; + *nVars = Hdr->nVars; + *nsuppvars = Hdr->nsuppvars; + + /* + * Support Varnames + */ + + if (Hdr->suppVarNames != NULL) { + *suppVarNames = DDDMP_ALLOC (char *, *nsuppvars); + Dddmp_CheckAndGotoLabel (*suppVarNames==NULL, + "Error allocating memory.", failure); + + for (i=0; i<*nsuppvars; i++) { + (*suppVarNames)[i] = DDDMP_ALLOC (char, + (strlen (Hdr->suppVarNames[i]) + 1)); + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + strcpy ((*suppVarNames)[i], Hdr->suppVarNames[i]); + } + } else { + *suppVarNames = NULL; + } + + /* + * Ordered Varnames + */ + + if (Hdr->orderedVarNames != NULL) { + *orderedVarNames = DDDMP_ALLOC (char *, *nVars); + Dddmp_CheckAndGotoLabel (*orderedVarNames==NULL, + "Error allocating memory.", failure); + + for (i=0; i<*nVars; i++) { + (*orderedVarNames)[i] = DDDMP_ALLOC (char, + (strlen (Hdr->orderedVarNames[i]) + 1)); + Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + strcpy ((*orderedVarNames)[i], Hdr->orderedVarNames[i]); + } + } else { + *orderedVarNames = NULL; + } + + /* + * Variable Ids + */ + + if (Hdr->ids != NULL) { + tmpVarIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarIds==NULL, "Error allocating memory.", + failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarIds[i] = Hdr->ids[i]; + } + + *varIds = tmpVarIds; + } else { + *varIds = NULL; + } + + /* + * Variable Compose Ids + */ + + if (Hdr->permids != NULL) { + tmpVarComposeIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarComposeIds==NULL, + "Error allocating memory.", failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarComposeIds[i] = Hdr->permids[i]; + } + + *varComposeIds = tmpVarComposeIds; + } else { + *varComposeIds = NULL; + } + + /* + * Variable Auxiliary Ids + */ + + if (Hdr->auxids != NULL) { + tmpVarAuxIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarAuxIds==NULL, + "Error allocating memory.", failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarAuxIds[i] = Hdr->auxids[i]; + } + + *varAuxIds = tmpVarAuxIds; + } else { + *varAuxIds = NULL; + } + + /* + * Number of roots + */ + + *nRoots = Hdr->nRoots; + + /* + * Free and Return + */ + + if (fileToClose == 1) { + fclose (fp); + } + + DddmpFreeHeader(Hdr); + + return (DDDMP_SUCCESS); + + failure: + return (DDDMP_FAILURE); +} + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads a dump file representing the argument BDDs.] + + Description [Reads a dump file representing the argument BDDs. The header is + common to both text and binary mode. The node list is either + in text or binary format. A dynamic vector of DD pointers + is allocated to support conversion from DD indexes to pointers. + Several criteria are supported for variable match between file + and dd manager. Several changes/permutations/compositions are allowed + for variables while loading DDs. Variable of the dd manager are allowed + to match with variables on file on ids, permids, varnames, + varauxids; also direct composition between ids and + composeids is supported. More in detail: +

                            +
                          1. varMatchMode=DDDMP_VAR_MATCHIDS

                            + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

                          2. varMatchMode=DDDMP_VAR_MATCHPERMIDS

                            + is used to allow variable match according to the position in the ordering. + +

                          3. varMatchMode=DDDMP_VAR_MATCHNAMES

                            + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

                          4. varMatchMode=DDDMP_VAR_MATCHIDS

                            + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

                          5. varMatchMode=DDDMP_VAR_COMPOSEIDS

                            + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. +

                          + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddArrayStore] + +******************************************************************************/ + +static int +DddmpCuddDdArrayLoad ( + Dddmp_DecompType ddType /* IN: Selects decomp type */, + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_RootMatchType rootMatchMode /* IN: storing mode selector */, + char **rootmatchnames /* IN: sorted names for loaded roots */, + Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by ids */, + int *varmatchauxids /* IN: array of variable auxids, by ids */, + int *varcomposeids /* IN: array of new ids, by ids */, + int mode /* IN: requested input file format */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***pproots /* OUT: array BDD roots (by reference) */ + ) +{ + Dddmp_Hdr_t *Hdr = NULL; + DdNode *f = NULL; + DdNode *T = NULL; + DdNode *E = NULL; + struct binary_dd_code code; + char buf[DDDMP_MAXSTRLEN]; + int retValue, id, size, maxv; + int i, j, k, maxaux, var, vT, vE, idT, idE; + double addConstant; + int *permsupport = NULL; + int *convertids = NULL; + int *invconvertids = NULL; + int *invauxids = NULL; + char **sortedvarnames = NULL; + int nddvars, nRoots; + DdNode **pnodes = NULL; + unsigned char *pvars1byte = NULL; + unsigned short *pvars2byte = NULL; + DdNode **proots = NULL; + int fileToClose = 0; + + *pproots = NULL; + + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + nddvars = ddMgr->size; + + Hdr = DddmpBddReadHeader (NULL, fp); + + Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.", + failure); + + nRoots = Hdr->nRoots; + + if (Hdr->ddType != ddType) { + (void) fprintf (stderr, "DdLoad Error: ddType mismatch\n"); + + if (Hdr->ddType == DDDMP_BDD) + (void) fprintf (stderr, "BDD found\n"); + if (Hdr->ddType == DDDMP_ADD) + (void) fprintf (stderr, "ADD found\n"); + if (ddType == DDDMP_BDD) + (void) fprintf (stderr, "when loading a BDD\n"); + if (ddType == DDDMP_ADD) + (void) fprintf (stderr, "when loading an ADD\n"); + + fflush (stderr); + goto failure; + } + + if (Hdr->mode != mode) { + Dddmp_CheckAndGotoLabel (mode!=DDDMP_MODE_DEFAULT, + "Mode Mismatch.", failure); + mode = Hdr->mode; + } + + /* + * For each variable in the support + * compute the relative position in the ordering + * (within the support only) + */ + + permsupport = DDDMP_ALLOC (int, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (permsupport==NULL, "Error allocating memory.", + failure); + for (i=0,k=0; i < Hdr->nVars; i++) { + for (j=0; j < Hdr->nsuppvars; j++) { + if (Hdr->permids[j] == i) { + permsupport[j] = k++; + } + } + } + Dddmp_Assert (k==Hdr->nsuppvars, "k==Hdr->nsuppvars"); + + if (Hdr->suppVarNames != NULL) { + /* + * Varnames are sorted for binary search + */ + + sortedvarnames = DDDMP_ALLOC(char *, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (sortedvarnames==NULL, "Error allocating memory.", + failure); + for (i=0; insuppvars; i++) { + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + sortedvarnames[i] = Hdr->suppVarNames[i]; + } + + qsort ((void *) sortedvarnames, Hdr->nsuppvars, + sizeof(char *), QsortStrcmp); + + } + + /* + * Convertids is the array used to convert variable ids from positional + * (shrinked) ids used within the DD file. + * Positions in the file are from 0 to nsuppvars-1. + */ + + convertids = DDDMP_ALLOC (int, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (convertids==NULL, "Error allocating memory.", + failure); + + again_matchmode: + switch (varMatchMode) { + case DDDMP_VAR_MATCHIDS: + for (i=0; insuppvars; i++) { + convertids[permsupport[i]] = Hdr->ids[i]; + } + break; + case DDDMP_VAR_MATCHPERMIDS: + for (i=0; insuppvars; i++) { + convertids[permsupport[i]] = Cudd_ReadInvPerm (ddMgr, + Hdr->permids[i]); + } + break; + case DDDMP_VAR_MATCHAUXIDS: + if (Hdr->auxids == NULL) { + (void) fprintf (stderr, + "DdLoad Error: variable auxids matching requested\n"); + (void) fprintf (stderr, "but .auxids not found in BDD file\n"); + (void) fprintf (stderr, "Matching IDs forced.\n"); + fflush (stderr); + varMatchMode = DDDMP_VAR_MATCHIDS; + goto again_matchmode; + } + /* find max auxid value to alloc invaux array */ + for (i=0,maxaux= -1; imaxaux) { + maxaux = varmatchauxids[i]; + } + } + /* generate invaux array */ + invauxids = DDDMP_ALLOC (int, maxaux+1); + Dddmp_CheckAndGotoLabel (invauxids==NULL, "Error allocating memory.", + failure); + + for (i=0; i<=maxaux; i++) { + invauxids[i] = -1; + } + + for (i=0; insuppvars; i++) { + invauxids[varmatchauxids[Hdr->ids[i]]] = Hdr->ids[i]; + } + + /* generate convertids array */ + for (i=0; insuppvars; i++) { + if ((Hdr->auxids[i]>maxaux) || (invauxids[Hdr->auxids[i]]<0)) { + (void) fprintf (stderr, + "DdLoad Error: auxid %d not found in DD manager.\n", + Hdr->auxids[i]); + (void) fprintf (stderr, "ID matching forced (%d).\n", i); + (void) fprintf (stderr, + "Beware of possible overlappings with other variables\n"); + fflush (stderr); + convertids[permsupport[i]] = i; + } else { + convertids[permsupport[i]] = invauxids[Hdr->auxids[i]]; + } + } + break; + case DDDMP_VAR_MATCHNAMES: + if (Hdr->suppVarNames == NULL) { + (void) fprintf (stderr, + "DdLoad Error: variable names matching requested\n"); + (void) fprintf (stderr, "but .suppvarnames not found in BDD file\n"); + (void) fprintf (stderr, "Matching IDs forced.\n"); + fflush (stderr); + varMatchMode = DDDMP_VAR_MATCHIDS; + goto again_matchmode; + } + + /* generate invaux array */ + invauxids = DDDMP_ALLOC (int, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (invauxids==NULL, "Error allocating memory.", + failure); + + for (i=0; insuppvars; i++) { + invauxids[i] = -1; + } + + for (i=0; insuppvars)) + >=0) { + Dddmp_Assert (jnsuppvars, "jnsuppvars"); + invauxids[j] = i; + } + } + /* generate convertids array */ + for (i=0; insuppvars; i++) { + Dddmp_Assert (Hdr->suppVarNames[i]!=NULL, + "Hdr->suppVarNames[i] != NULL"); + j=FindVarname(Hdr->suppVarNames[i],sortedvarnames,Hdr->nsuppvars); + Dddmp_Assert ((j>=0) && (jnsuppvars), + "(j>=0) && (jnsuppvars)"); + if (invauxids[j]<0) { + fprintf (stderr, + "DdLoad Error: varname %s not found in DD manager.", + Hdr->suppVarNames[i]); + fprintf (stderr, "ID matching forced (%d)\n", i); + fflush (stderr); + convertids[permsupport[i]]=i; + } else { + convertids[permsupport[i]] = invauxids[j]; + } + } + break; + case DDDMP_VAR_COMPOSEIDS: + for (i=0; insuppvars; i++) { + convertids[permsupport[i]] = varcomposeids[Hdr->ids[i]]; + } + break; + } + + maxv = (-1); + for (i=0; insuppvars; i++) { + if (convertids[i] > maxv) { + maxv = convertids[i]; + } + } + + invconvertids = DDDMP_ALLOC (int, maxv+1); + Dddmp_CheckAndGotoLabel (invconvertids==NULL, "Error allocating memory.", + failure); + + for (i=0; i<=maxv; i++) { + invconvertids[i]= -1; + } + + for (i=0; insuppvars; i++) { + invconvertids[convertids[i]] = i; + } + + pnodes = DDDMP_ALLOC(DdNode *,(Hdr->nnodes+1)); + Dddmp_CheckAndGotoLabel (pnodes==NULL, "Error allocating memory.", + failure); + + if (Hdr->nsuppvars < 256) { + pvars1byte = DDDMP_ALLOC(unsigned char,(Hdr->nnodes+1)); + Dddmp_CheckAndGotoLabel (pvars1byte==NULL, "Error allocating memory.", + failure); + } + else if (Hdr->nsuppvars < 0xffff) { + pvars2byte = DDDMP_ALLOC(unsigned short,(Hdr->nnodes+1)); + Dddmp_CheckAndGotoLabel (pvars2byte==NULL, "Error allocating memory.", + failure); + } else { + (void) fprintf (stderr, + "DdLoad Error: more than %d variables. Not supported.\n", 0xffff); + fflush (stderr); + goto failure; + } + + /*-------------- Deal With Nodes ... One Row File at a Time --------------*/ + + for (i=1; i<=Hdr->nnodes; i++) { + + Dddmp_CheckAndGotoLabel (feof(fp), + "Unexpected EOF While Reading DD Nodes.", failure); + + switch (mode) { + + /* + * Text FORMAT + */ + + case DDDMP_MODE_TEXT: + + switch (Hdr->varinfo) { + case DDDMP_VARIDS: + case DDDMP_VARPERMIDS: + case DDDMP_VARAUXIDS: + case DDDMP_VARNAMES: + retValue = fscanf(fp, "%d %*s %s %d %d\n", &id, buf, &idT, &idE); + Dddmp_CheckAndGotoLabel (retValue<4, + "Error Reading Nodes in Text Mode.", failure); + break; + case DDDMP_VARDEFAULT: + retValue = fscanf(fp, "%d %s %d %d\n", &id, buf, &idT, &idE); + Dddmp_CheckAndGotoLabel (retValue<4, + "Error Reading Nodes in Text Mode.", failure); + break; + } +#ifdef DDDMP_DEBUG + Dddmp_Assert (id==i, "id == i"); +#endif + if (idT==0 && idE==0) { + /* leaf node: a constant */ + if (strcmp(buf, "1") == 0) { + pnodes[i] = Cudd_ReadOne (ddMgr); + } else { + /* this is an ADD constant ! */ + if (strcmp(buf, "0") == 0) { + pnodes[i] = Cudd_ReadZero (ddMgr); + } else { + addConstant = atof(buf); + pnodes[i] = Cudd_addConst (ddMgr, + (CUDD_VALUE_TYPE) addConstant); + } + } + + /* StQ 11.02.2004: + Bug fixed --> Reference All Nodes for ADD */ + Cudd_Ref (pnodes[i]); + Dddmp_CheckAndGotoLabel (pnodes[i]==NULL, "NULL pnodes.", + failure); + continue; + } else { +#ifdef DDDMP_DEBUG + Dddmp_Assert (idT>0, "id > 0"); +#endif + var = atoi(buf); + T = pnodes[idT]; + if(idE<0) { + idE = -idE; + E = pnodes[idE]; + E = Cudd_Not(E); + } else { + E = pnodes[idE]; + } + } + + break; + + /* + * Binary FORMAT + */ + + case DDDMP_MODE_BINARY: + + Dddmp_CheckAndGotoLabel (DddmpReadCode(fp,&code) == 0, + "Error Reading witn ReadCode.", failure); + + switch (code.V) { + case DDDMP_TERMINAL: + /* only 1 terminal presently supported */ + pnodes[i] = Cudd_ReadOne (ddMgr); + continue; + break; + case DDDMP_RELATIVE_1: + break; + case DDDMP_RELATIVE_ID: + case DDDMP_ABSOLUTE_ID: + size = DddmpReadInt (fp, &var); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + break; + } + + switch (code.T) { + case DDDMP_TERMINAL: + idT = 1; + break; + case DDDMP_RELATIVE_1: + idT = i-1; + break; + case DDDMP_RELATIVE_ID: + size = DddmpReadInt (fp, &id); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + idT = i-id; + break; + case DDDMP_ABSOLUTE_ID: + size = DddmpReadInt (fp, &idT); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + break; + } + + switch (code.E) { + case DDDMP_TERMINAL: + idE = 1; + break; + case DDDMP_RELATIVE_1: + idE = i-1; + break; + case DDDMP_RELATIVE_ID: + size = DddmpReadInt (fp, &id); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + idE = i-id; + break; + case DDDMP_ABSOLUTE_ID: + size = DddmpReadInt (fp, &idE); + Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", + failure); + break; + } + +#ifdef DDDMP_DEBUG + Dddmp_Assert (idTnsuppvars; + else { + if (pvars1byte != NULL) + vT = pvars1byte[idT]; + else if (pvars2byte != NULL) + vT = pvars2byte[idT]; + else + vT = invconvertids[T->index]; + } +#ifdef DDDMP_DEBUG + Dddmp_Assert (vT>0, "vT > 0"); + Dddmp_Assert (vT<=Hdr->nsuppvars, "vT <= Hdr->nsuppvars"); +#endif + +#ifdef DDDMP_DEBUG + Dddmp_Assert (idEnsuppvars; + else { + if (pvars1byte != NULL) + vE = pvars1byte[idE]; + else if (pvars2byte != NULL) + vE = pvars2byte[idE]; + else + vE = invconvertids[E->index]; + } +#ifdef DDDMP_DEBUG + Dddmp_Assert (vE>0, "vE > 0"); + Dddmp_Assert (vE<=Hdr->nsuppvars, "vE <= Hdr->nsuppvars"); +#endif + + switch (code.V) { + case DDDMP_TERMINAL: + case DDDMP_ABSOLUTE_ID: + break; + case DDDMP_RELATIVE_1: + var = (vTnsuppvars, "var < Hdr->nsuppvars"); +#endif + + break; + } + + if (pvars1byte != NULL) { + pvars1byte[i] = (unsigned char) var; + } else { + if (pvars2byte != NULL) { + pvars2byte[i] = (unsigned short) var; + } + } + + var = convertids[var]; + switch (ddType) { + case DDDMP_BDD: + pnodes[i] = Cudd_bddIte (ddMgr, Cudd_bddIthVar (ddMgr, var), + T, E); + break; + case DDDMP_ADD: + { + DdNode *tmp = Cudd_addIthVar (ddMgr, var); + Cudd_Ref (tmp); + pnodes[i] = Cudd_addIte (ddMgr, tmp, T, E); + Cudd_RecursiveDeref (ddMgr, tmp); + break; + } + case DDDMP_CNF: + case DDDMP_NONE: + Dddmp_Warning (1, "Wrong DD Type."); + break; + } + + cuddRef (pnodes[i]); + } + + /*------------------------ Deal With the File Tail -----------------------*/ + + fgets (buf, DDDMP_MAXSTRLEN-1,fp); + Dddmp_CheckAndGotoLabel (!matchkeywd(buf, ".end"), + "Error .end not found.", failure); + + /* Close File IFF Necessary */ + if (fileToClose) { + fclose (fp); + } + + /* BDD Roots */ + proots = DDDMP_ALLOC(DdNode *,nRoots); + Dddmp_CheckAndGotoLabel (proots==NULL, "Error allocating memory.", + failure); + + for(i=0; irootnames[j]) == 0) + break; + } + if (j>=nRoots) { + /* rootname not found */ + fprintf (stderr, "Warning: unable to match root name <%s>\n", + rootmatchnames[i]); + } + break; + case DDDMP_ROOT_MATCHLIST: + j = i; + break; + } + + id = Hdr->rootids[i]; + if (id==0) { + (void) fprintf (stderr, "DdLoad Warning: NULL root found in file\n"); + fflush (stderr); + f = NULL; + } else { + if (id<0) { + f = Cudd_Not(pnodes[-id]); + } else { + f = pnodes[id]; + } + } + proots[i] = f; + + cuddRef (f); + } /* end for i = 0..nRoots */ + + /* + * Decrease Reference for all Nodes + */ + + /* StQ 11.02.2004: + Bug fixed --> De-Reference All Nodes for ADD */ + for (i=1; i<=Hdr->nnodes; i++) { + f = pnodes[i]; + Cudd_RecursiveDeref (ddMgr, f); + } + + /* + * Free Memory: load_end label + */ + +load_end: + + DddmpFreeHeader(Hdr); + + DDDMP_FREE (pnodes); + DDDMP_FREE (pvars1byte); + DDDMP_FREE (pvars2byte); + + /* variable names are not freed because they were shared with varnames */ + DDDMP_FREE (sortedvarnames); + + DDDMP_FREE (permsupport); + DDDMP_FREE (convertids); + DDDMP_FREE (invconvertids); + DDDMP_FREE (invauxids); + + *pproots = proots; + return (nRoots); + + /* + * Failure Condition + */ + +failure: + + if (fileToClose) { + fclose (fp); + } + + nRoots = 0; /* return 0 on error ! */ + + DDDMP_FREE (proots); + + goto load_end; /* this is done to free memory */ +} + +/**Function******************************************************************** + + Synopsis [Reads a the header of a dump file representing the + argument BDDs. + ] + + Description [Reads the header of a dump file. Builds a Dddmp_Hdr_t struct + containing all infos in the header, for next manipulations. + ] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ + +static Dddmp_Hdr_t * +DddmpBddReadHeader ( + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + Dddmp_Hdr_t *Hdr = NULL; + char buf[DDDMP_MAXSTRLEN]; + int retValue, fileToClose = 0; + + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /* START HEADER */ + + Hdr = DDDMP_ALLOC (Dddmp_Hdr_t,1); + if (Hdr == NULL) { + return NULL; + } + Hdr->ver = NULL; + Hdr->mode = 0; + Hdr->ddType = DDDMP_BDD; + Hdr->varinfo = DDDMP_VARIDS; + Hdr->dd = NULL; + Hdr->nnodes = 0; + Hdr->nVars = 0; + Hdr->nsuppvars = 0; + Hdr->suppVarNames = NULL; + Hdr->orderedVarNames = NULL; + Hdr->ids = NULL; + Hdr->permids = NULL; + Hdr->auxids = NULL; + Hdr->cnfids = NULL; + Hdr->nRoots = 0; + Hdr->rootids = NULL; + Hdr->rootnames = NULL; + Hdr->nAddedCnfVar = 0; + Hdr->nVarsCnf = 0; + Hdr->nClausesCnf = 0; + + while (fscanf(fp, "%s", buf)!=EOF) { + + /* comment */ + if (buf[0] == '#') { + fgets(buf,DDDMP_MAXSTRLEN,fp); + continue; + } + + Dddmp_CheckAndGotoLabel (buf[0] != '.', + "Error; line must begin with '.' or '#'.", + failure); + + if (matchkeywd(buf, ".ver")) { + /* this not checked so far: only read */ + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading from file.", + failure); + + Hdr->ver=DddmpStrDup(buf); + Dddmp_CheckAndGotoLabel (Hdr->ver==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".add")) { + Hdr->ddType = DDDMP_ADD; + continue; + } + + if (matchkeywd(buf, ".bdd")) { + Hdr->ddType = DDDMP_BDD; + continue; + } + + if (matchkeywd(buf, ".mode")) { + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading to file.", + failure); + + Hdr->mode = buf[0]; + continue; + } + + if (matchkeywd(buf, ".varinfo")) { + int readMe; + retValue = fscanf (fp, "%d", &readMe); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + Hdr->varinfo = (Dddmp_VarInfoType) readMe; + + continue; + } + + if (matchkeywd(buf, ".dd")) { + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + Hdr->dd = DddmpStrDup (buf); + Dddmp_CheckAndGotoLabel (Hdr->dd==NULL, "Error allocating memory.", + failure); + + continue; + } + + if (matchkeywd(buf, ".nnodes")) { + retValue = fscanf (fp, "%d", &(Hdr->nnodes)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd(buf, ".nvars")) { + retValue = fscanf (fp, "%d", &(Hdr->nVars)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd(buf, ".nsuppvars")) { + retValue = fscanf (fp, "%d", &(Hdr->nsuppvars)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd(buf, ".orderedvarnames")) { + Hdr->orderedVarNames = DddmpStrArrayRead (fp, Hdr->nVars); + Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".suppvarnames") || + ((strcmp (Hdr->ver, "DDDMP-1.0") == 0) && + matchkeywd (buf, ".varnames"))) { + Hdr->suppVarNames = DddmpStrArrayRead (fp, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if matchkeywd(buf, ".ids") { + Hdr->ids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->ids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".permids")) { + Hdr->permids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->permids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".auxids")) { + Hdr->auxids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->auxids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".nroots")) { + retValue = fscanf (fp, "%d", &(Hdr->nRoots)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd(buf, ".rootids")) { + Hdr->rootids = DddmpIntArrayRead(fp,Hdr->nRoots); + Dddmp_CheckAndGotoLabel (Hdr->rootids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".rootnames")) { + Hdr->rootnames = DddmpStrArrayRead(fp,Hdr->nRoots); + Dddmp_CheckAndGotoLabel (Hdr->rootnames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd(buf, ".nodes")) { + fgets(buf,DDDMP_MAXSTRLEN,fp); + break; + } + + } + + /* END HEADER */ + + return (Hdr); + +failure: + + if (fileToClose == 1) { + fclose (fp); + } + + DddmpFreeHeader(Hdr); + + return (NULL); +} + + +/**Function******************************************************************** + + Synopsis [Frees the internal header structure.] + + Description [Frees the internal header structureby freeing all internal + fields first. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +DddmpFreeHeader ( + Dddmp_Hdr_t *Hdr /* IN: pointer to header */ + ) +{ + DDDMP_FREE (Hdr->ver); + DDDMP_FREE (Hdr->dd); + DddmpStrArrayFree (Hdr->orderedVarNames, Hdr->nVars); + DddmpStrArrayFree (Hdr->suppVarNames, Hdr->nsuppvars); + DDDMP_FREE (Hdr->ids); + DDDMP_FREE (Hdr->permids); + DDDMP_FREE (Hdr->auxids); + DDDMP_FREE (Hdr->rootids); + DddmpStrArrayFree (Hdr->rootnames, Hdr->nRoots); + + DDDMP_FREE (Hdr); + + return; +} + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpLoadCnf.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpLoadCnf.c new file mode 100644 index 000000000..35bec273b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpLoadCnf.c @@ -0,0 +1,1072 @@ +/**CFile********************************************************************** + + FileName [dddmpLoadCnf.c] + + PackageName [dddmp] + + Synopsis [Functions to read in CNF from file as BDDs.] + + Description [Functions to read in CNF from file as BDDs. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMP_MAX_CNF_ROW_LENGTH 1000 +#define DDDMP_DEBUG_CNF 0 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define matchkeywd(str,key) (strncmp(str,key,strlen(key))==0) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpCuddDdArrayLoadCnf(DdManager *ddMgr, Dddmp_RootMatchType rootmatchmode, char **rootmatchnames, Dddmp_VarMatchType varmatchmode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***rootsPtrPtr, int *nRoots); +static Dddmp_Hdr_t * DddmpBddReadHeaderCnf(char *file, FILE *fp); +static void DddmpFreeHeaderCnf(Dddmp_Hdr_t *Hdr); +static int DddmpReadCnfClauses(Dddmp_Hdr_t *Hdr, int ***cnfTable, FILE *fp); +static int DddmpCnfClauses2Bdd(Dddmp_Hdr_t *Hdr, DdManager *ddMgr, int **cnfTable, int mode, DdNode ***rootsPtrPtr); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads a dump file in a CNF format.] + + Description [Reads a dump file representing the argument BDD in a + CNF formula. + Dddmp_cuddBddArrayLoadCnf is used through a dummy array. + The results is returned in different formats depending on the + mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddLoad, Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddBddLoadCnf ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_VarMatchType varmatchmode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by IDs */, + int *varmatchauxids /* IN: array of variable auxids, by IDs */, + int *varcomposeids /* IN: array of new ids accessed, by IDs */, + int mode /* IN: computation mode */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots */, + int *nRoots /* OUT: number of BDDs returned */ + ) +{ + int i, retValue; + + retValue = Dddmp_cuddBddArrayLoadCnf (ddMgr, DDDMP_ROOT_MATCHLIST, NULL, + varmatchmode, varmatchnames, varmatchauxids, varcomposeids, mode, + file, fp, rootsPtrPtr, nRoots); + + if (retValue == DDDMP_FAILURE) { + return (DDDMP_FAILURE); + } + + if (*nRoots > 1) { + fprintf (stderr, + "Warning: %d BDD roots found in file. Only first retrieved.\n", + *nRoots); + for (i=1; i<*nRoots; i++) { + Cudd_RecursiveDeref (ddMgr, *rootsPtrPtr[i]); + } + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Reads a dump file in a CNF format.] + + Description [Reads a dump file representing the argument BDD in a + CNF formula. + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayLoadCnf ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_RootMatchType rootmatchmode/* IN: storing mode selector */, + char **rootmatchnames /* IN: sorted names for loaded roots */, + Dddmp_VarMatchType varmatchmode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by IDs */, + int *varmatchauxids /* IN: array of variable auxids, by IDs */, + int *varcomposeids /* IN: array of new ids, by IDs */, + int mode /* IN: computation Mode */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots */, + int *nRoots /* OUT: number of BDDs returned */ + ) +{ + int retValue; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During CNF Load.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During CNF Load.\n"); + fflush (stderr); + } + } +#endif +#endif + + retValue = DddmpCuddDdArrayLoadCnf (ddMgr, rootmatchmode, + rootmatchnames, varmatchmode, varmatchnames, varmatchauxids, + varcomposeids, mode, file, fp, rootsPtrPtr, nRoots); + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During CNF Load.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During CNF Load.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Reads the header of a dump file representing the argument BDDs] + + Description [Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddHeaderLoadCnf ( + int *nVars /* OUT: number of DD variables */, + int *nsuppvars /* OUT: number of support variables */, + char ***suppVarNames /* OUT: array of support variable names */, + char ***orderedVarNames /* OUT: array of variable names */, + int **varIds /* OUT: array of variable ids */, + int **varComposeIds /* OUT: array of permids ids */, + int **varAuxIds /* OUT: array of variable aux ids */, + int *nRoots /* OUT: number of root in the file */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + Dddmp_Hdr_t *Hdr; + int i, fileToClose; + char **tmpOrderedVarNames = NULL; + char **tmpSuppVarNames = NULL; + int *tmpVarIds = NULL; + int *tmpVarComposeIds = NULL; + int *tmpVarAuxIds = NULL; + + fileToClose = 0; + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + Hdr = DddmpBddReadHeaderCnf (NULL, fp); + + Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.", + failure); + + /* + * Number of variables (tot and support) + */ + + *nVars = Hdr->nVars; + *nsuppvars = Hdr->nsuppvars; + + /* + * Support Varnames + */ + + if (Hdr->suppVarNames != NULL) { + tmpSuppVarNames = DDDMP_ALLOC (char *, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpSuppVarNames==NULL, "Error allocating memory.", + failure); + + for (i=0; i<*nsuppvars; i++) { + tmpSuppVarNames[i] = DDDMP_ALLOC (char, + (strlen (Hdr->suppVarNames[i]) + 1)); + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + strcpy (tmpSuppVarNames[i], Hdr->suppVarNames[i]); + } + + *suppVarNames = tmpSuppVarNames; + } else { + *suppVarNames = NULL; + } + + /* + * Ordered Varnames + */ + + if (Hdr->orderedVarNames != NULL) { + tmpOrderedVarNames = DDDMP_ALLOC (char *, *nVars); + Dddmp_CheckAndGotoLabel (tmpOrderedVarNames==NULL, + "Error allocating memory.", failure); + + for (i=0; i<*nVars; i++) { + tmpOrderedVarNames[i] = DDDMP_ALLOC (char, + (strlen (Hdr->orderedVarNames[i]) + 1)); + Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames[i]==NULL, + "Support Variable Name Missing in File.", failure); + strcpy (tmpOrderedVarNames[i], Hdr->orderedVarNames[i]); + } + + *orderedVarNames = tmpOrderedVarNames; + } else { + *orderedVarNames = NULL; + } + + /* + * Variable Ids + */ + + if (Hdr->ids != NULL) { + tmpVarIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarIds==NULL, "Error allocating memory.", + failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarIds[i] = Hdr->ids[i]; + } + + *varIds = tmpVarIds; + } else { + *varIds = NULL; + } + + /* + * Variable Compose Ids + */ + + if (Hdr->permids != NULL) { + tmpVarComposeIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarComposeIds==NULL, + "Error allocating memory.", failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarComposeIds[i] = Hdr->permids[i]; + } + + *varComposeIds = tmpVarComposeIds; + } else { + *varComposeIds = NULL; + } + + /* + * Variable Auxiliary Ids + */ + + if (Hdr->auxids != NULL) { + tmpVarAuxIds = DDDMP_ALLOC (int, *nsuppvars); + Dddmp_CheckAndGotoLabel (tmpVarAuxIds==NULL, + "Error allocating memory.", failure); + for (i=0; i<*nsuppvars; i++) { + tmpVarAuxIds[i] = Hdr->auxids[i]; + } + + *varAuxIds = tmpVarAuxIds; + } else { + *varAuxIds = NULL; + } + + /* + * Number of roots + */ + + *nRoots = Hdr->nRoots; + + /* + * Free and Return + */ + + if (fileToClose == 1) { + fclose (fp); + } + + DddmpFreeHeaderCnf (Hdr); + + return (DDDMP_SUCCESS); + + failure: + return (DDDMP_FAILURE); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Reads a dump file representing the argument BDDs in CNF + format. + ] + + Description [Reads a dump file representing the argument BDDs in CNF + format. + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification + ] + + SideEffects [A vector of pointers to DD nodes is allocated and freed.] + + SeeAlso [Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +static int +DddmpCuddDdArrayLoadCnf ( + DdManager *ddMgr /* IN: DD Manager */, + Dddmp_RootMatchType rootmatchmode/* IN: storing mode selector */, + char **rootmatchnames /* IN: sorted names for loaded roots */, + Dddmp_VarMatchType varmatchmode /* IN: storing mode selector */, + char **varmatchnames /* IN: array of variable names, by ids */, + int *varmatchauxids /* IN: array of variable auxids, by ids */, + int *varcomposeids /* IN: array of new ids, by ids */, + int mode /* IN: computation mode */, + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */, + DdNode ***rootsPtrPtr /* OUT: array of BDD roots */, + int *nRoots /* OUT: number of BDDs returned */ + ) +{ + Dddmp_Hdr_t *Hdr = NULL; + int **cnfTable = NULL; + int fileToClose = 0; + int retValue, i; + + fileToClose = 0; + *rootsPtrPtr = NULL; + + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /*--------------------------- Read the Header -----------------------------*/ + + Hdr = DddmpBddReadHeaderCnf (NULL, fp); + + Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.", + failure); + + /*------------------------ Read the CNF Clauses ---------------------------*/ + + retValue = DddmpReadCnfClauses (Hdr, &cnfTable, fp); + + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "Read CNF Clauses Failure.", failure); + + /*------------------------- From Clauses to BDDs --------------------------*/ + + retValue = DddmpCnfClauses2Bdd (Hdr, ddMgr, cnfTable, mode, rootsPtrPtr); + + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "CNF Clauses To BDDs Failure.", failure); + + *nRoots = Hdr->nRoots; + + if (fileToClose) { + fclose (fp); + } + + for (i=0; inClausesCnf; i++) { + DDDMP_FREE (cnfTable[i]); + } + DDDMP_FREE (cnfTable); + + DddmpFreeHeaderCnf (Hdr); + + return (DDDMP_SUCCESS); + + /* + * Failure Condition + */ + +failure: + + if (fileToClose) { + fclose (fp); + } + + for (i=0; inClausesCnf; i++) { + DDDMP_FREE (cnfTable[i]); + } + DDDMP_FREE (cnfTable); + + DddmpFreeHeaderCnf (Hdr); + + /* return 0 on error ! */ + nRoots = 0; + + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Reads a the header of a dump file representing the argument + BDDs. + ] + + Description [Reads the header of a dump file. Builds a Dddmp_Hdr_t struct + containing all infos in the header, for next manipulations. + ] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ + +static Dddmp_Hdr_t * +DddmpBddReadHeaderCnf ( + char *file /* IN: file name */, + FILE *fp /* IN: file pointer */ + ) +{ + Dddmp_Hdr_t *Hdr = NULL; + char buf[DDDMP_MAXSTRLEN]; + int nv, nc, retValue, fileToClose = 0; + + if (fp == NULL) { + fp = fopen (file, "r"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /* Start Header */ + Hdr = DDDMP_ALLOC (Dddmp_Hdr_t, 1); + if (Hdr == NULL) { + return NULL; + } + + Hdr->ver = NULL; + Hdr->mode = 0; + Hdr->ddType = DDDMP_CNF; + Hdr->varinfo = DDDMP_VARIDS; + Hdr->dd = NULL; + Hdr->nnodes = 0; + Hdr->nVars = 0; + Hdr->nsuppvars = 0; + Hdr->orderedVarNames = NULL; + Hdr->suppVarNames = NULL; + Hdr->ids = NULL; + Hdr->permids = NULL; + Hdr->auxids = NULL; + Hdr->cnfids = NULL; + Hdr->nRoots = 0; + Hdr->rootids = NULL; + Hdr->rootnames = NULL; + Hdr->nAddedCnfVar = 0; + Hdr->nVarsCnf = 0; + Hdr->nClausesCnf = 0; + + while (fscanf (fp, "%s", buf) != EOF) { + + /* Init Problem Line */ + if (buf[0] == 'p') { + fscanf (fp, "%*s %d %d", &nv, &nc); + Hdr->nVarsCnf = nv; + Hdr->nClausesCnf = nc; + break; + } + + /* CNF Comment Line */ + if (buf[0] == 'c') { + if (fscanf (fp, "%s", buf) == EOF) { + break; + } + } + + /* Skip Comment? */ + if (buf[0] != '.') { + fgets (buf, DDDMP_MAXSTRLEN, fp); + continue; + } + + if (matchkeywd (buf, ".ver")) { + /* this not checked so far: only read */ + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading from file.", + failure); + + Hdr->ver=DddmpStrDup(buf); + Dddmp_CheckAndGotoLabel (Hdr->ver==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".dd")) { + retValue = fscanf (fp, "%s", buf); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + Hdr->dd = DddmpStrDup (buf); + Dddmp_CheckAndGotoLabel (Hdr->dd==NULL, "Error allocating memory.", + failure); + + continue; + } + + if (matchkeywd (buf, ".nnodes")) { + retValue = fscanf (fp, "%d", &(Hdr->nnodes)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd (buf, ".nvars")) { + retValue = fscanf (fp, "%d", &(Hdr->nVars)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd (buf, ".nsuppvars")) { + retValue = fscanf (fp, "%d", &(Hdr->nsuppvars)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd (buf, ".orderedvarnames")) { + Hdr->orderedVarNames = DddmpStrArrayRead (fp, Hdr->nVars); + Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".suppvarnames")) { + Hdr->suppVarNames = DddmpStrArrayRead (fp, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->suppVarNames==NULL, + "Error allocating memory.", failure); + + continue; + } + + if matchkeywd (buf, ".ids") { + Hdr->ids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->ids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".permids")) { + Hdr->permids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->permids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".auxids")) { + Hdr->auxids = DddmpIntArrayRead(fp,Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->auxids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".cnfids")) { + Hdr->cnfids = DddmpIntArrayRead (fp, Hdr->nsuppvars); + Dddmp_CheckAndGotoLabel (Hdr->cnfids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".nroots")) { + retValue = fscanf (fp, "%d", &(Hdr->nRoots)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + + if (matchkeywd (buf, ".rootids")) { + Hdr->rootids = DddmpIntArrayRead(fp,Hdr->nRoots); + Dddmp_CheckAndGotoLabel (Hdr->rootids==NULL, + "Error allocating memory.", failure); + + continue; + } + + if (matchkeywd (buf, ".rootnames")) { + Hdr->rootnames = DddmpStrArrayRead(fp,Hdr->nRoots); + Dddmp_CheckAndGotoLabel (Hdr->rootnames==NULL, + "Error allocating memory.", failure); + + continue; + } + + + if (matchkeywd (buf, ".nAddedCnfVar")) { + retValue = fscanf (fp, "%d", &(Hdr->nAddedCnfVar)); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", + failure); + + continue; + } + } + + /* END HEADER */ + return (Hdr); + +failure: + + if (fileToClose == 1) { + fclose (fp); + } + + DddmpFreeHeaderCnf (Hdr); + + return (NULL); +} + + +/**Function******************************************************************** + + Synopsis [Frees the internal header structure.] + + Description [Frees the internal header structure by freeing all internal + fields first. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +DddmpFreeHeaderCnf ( + Dddmp_Hdr_t *Hdr /* IN: pointer to header */ + ) +{ + if (Hdr==NULL) { + return; + } + + DDDMP_FREE (Hdr->ver); + DDDMP_FREE (Hdr->dd); + DddmpStrArrayFree (Hdr->orderedVarNames, Hdr->nVars); + DddmpStrArrayFree (Hdr->suppVarNames, Hdr->nsuppvars); + DDDMP_FREE (Hdr->ids); + DDDMP_FREE (Hdr->permids); + DDDMP_FREE (Hdr->auxids); + DDDMP_FREE (Hdr->cnfids); + DDDMP_FREE (Hdr->rootids); + DddmpStrArrayFree (Hdr->rootnames, Hdr->nRoots); + + DDDMP_FREE (Hdr); + + return; +} + +/**Function******************************************************************** + + Synopsis [Read the CNF clauses from the file in the standard DIMACS + format. + ] + + Description [Read the CNF clauses from the file in the standard DIMACS + format. Store all the clauses in an internal structure for + future transformation into BDDs. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpReadCnfClauses ( + Dddmp_Hdr_t *Hdr /* IN: file header */, + int ***cnfTable /* OUT: CNF table for clauses */, + FILE *fp /* IN: source file */ + ) +{ + char word[DDDMP_MAX_CNF_ROW_LENGTH]; + int i, j, var; + int **cnfTableLocal = NULL; + int *clause = NULL; + + cnfTableLocal = DDDMP_ALLOC (int *, Hdr->nClausesCnf); + clause = DDDMP_ALLOC (int, 2*Hdr->nVarsCnf+1); + + for (i=0; inClausesCnf; i++) { + cnfTableLocal[i] = NULL; + } + + for (i=0; i<=2*Hdr->nVarsCnf; i++) { + clause[i] = 0; + } + + i = j = 0; + do { + if (fscanf(fp, "%s", word)==EOF) { + if (j>0) { + /* force last zero */ + strcpy(word,"0"); + } + else break; + } + + /* Check for Comment */ + if (word[0] == 'c') { + /* Comment Found: Skip line */ + fgets (word, DDDMP_MAX_CNF_ROW_LENGTH-1, fp); + break; + } + + var = atoi (word); + Dddmp_Assert ((var>=(-Hdr->nVarsCnf))&&(var<=Hdr->nVarsCnf), + "Wrong num found"); + clause[j++] = var; + if (var == 0) { + cnfTableLocal[i] = DDDMP_ALLOC (int, j); + while (--j >=0) { + cnfTableLocal[i][j] = clause[j]; + } + i++; + j=0; + } + + } while (!feof(fp)); + + Dddmp_Assert (i==Hdr->nClausesCnf, + "Wrong number of clauses in file"); + +#if DDDMP_DEBUG_CNF + for (i=0; inClausesCnf; i++) { + fprintf (stdout, "[%4d] ", i); + j=0; + while ((var = cnfTableLocal[i][j++]) != 0) { + fprintf (stdout, "%d ", var); + } + fprintf (stdout, "0\n"); + } +#endif + + DDDMP_FREE (clause); + + *cnfTable = cnfTableLocal; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Transforms CNF clauses into BDDs.] + + Description [Transforms CNF clauses into BDDs. Clauses are stored in an + internal structure previously read. The results can be given in + different format according to the mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpCnfClauses2Bdd ( + Dddmp_Hdr_t *Hdr /* IN: file header */, + DdManager *ddMgr /* IN: DD Manager */, + int **cnfTable /* IN: CNF table for clauses */, + int mode /* IN: computation mode */, + DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots (by reference) */ + ) +{ + DdNode **rel = NULL; + DdNode *lit = NULL; + DdNode *tmp1 = NULL; + DdNode *tmp2 = NULL; + DdNode **rootsPtr = NULL; + DdNode *cubeAllVar = NULL; + DdNode *cubeBddVar = NULL; + DdNode *cubeCnfVar = NULL; + int i, j, k, n, var1, var2, fromLine, toLine; + + rootsPtr = NULL; + *rootsPtrPtr = NULL; + + /*-------------------------- Read The Clauses -----------------------------*/ + + rel = DDDMP_ALLOC (DdNode *, Hdr->nClausesCnf); + + cubeBddVar = Cudd_ReadOne (ddMgr); + cubeCnfVar = Cudd_ReadOne (ddMgr); + cubeAllVar = Cudd_ReadOne (ddMgr); + Cudd_Ref (cubeBddVar); + Cudd_Ref (cubeCnfVar); + Cudd_Ref (cubeAllVar); + + for (i=0; inClausesCnf; i++) { + rel[i] = Cudd_Not (Cudd_ReadOne (ddMgr)); + Cudd_Ref (rel[i]); + j=0; + while ((var1 = cnfTable[i][j++]) != 0) { + + /* Deal with the Literal */ + var2 = abs (var1); + n = (-1); + for (k=0; knsuppvars; k++) { + if (Hdr->cnfids[k] == var2) { + n = k; + break; + } + } + + if (n == (-1)) { + lit = Cudd_bddIthVar (ddMgr, var2); + + /* Create the cubes of CNF Variables */ + tmp1 = Cudd_bddAnd (ddMgr, cubeCnfVar, lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, cubeCnfVar); + cubeCnfVar = tmp1; + + } else { + lit = Cudd_bddIthVar (ddMgr, Hdr->ids[n]); + + /* Create the cubes of BDD Variables */ + tmp1 = Cudd_bddAnd (ddMgr, cubeBddVar, lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, cubeBddVar); + cubeBddVar = tmp1; + } + + /* Create the cubes of ALL Variables */ + tmp1 = Cudd_bddAnd (ddMgr, cubeAllVar, lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, cubeAllVar); + cubeAllVar = tmp1; + + /* Deal with Relations */ + if (var1<0) { + lit = Cudd_Not (lit); + } + tmp1 = Cudd_bddOr (ddMgr, rel[i], lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, rel[i]); + rel[i] = tmp1; + } + } + + /* + * Mode == 0 Return the Clauses without Conjunction + */ + + if (mode == 0) { + return (DDDMP_SUCCESS); + } + + rootsPtr = DDDMP_ALLOC (DdNode *, Hdr->nRoots); + Dddmp_CheckAndGotoLabel (rootsPtr==NULL, "Error allocating memory.", + failure); + + for (i=0; inRoots; i++) { + if (i == (Hdr->nRoots-1)) { + fromLine = Hdr->rootids[i] - 1; + toLine = Hdr->nClausesCnf; + } else { + fromLine = Hdr->rootids[i] - 1; + toLine = Hdr->rootids[i+1]; + } + + tmp1 = Cudd_ReadOne (ddMgr); + Cudd_Ref (tmp1); + for (j=fromLine; jnsuppvars; i++) { + lit = Cudd_bddIthVar (ddMgr, Hdr->ids[i]); + tmp1 = Cudd_bddAnd (ddMgr, cubeBddVar, lit); + Cudd_Ref (tmp1); + Cudd_RecursiveDeref (ddMgr, cubeBddVar); + cubeBddVar = tmp1; + } + + cubeCnfVar = Cudd_bddExistAbstract (ddMgr, cubeAllVar, cubeBddVar); +#endif + + for (i=0; inRoots; i++) { +#if DDDMP_DEBUG_CNF + fprintf (stdout, "rootsPtr Before Exist:\n"); + Cudd_PrintDebug (ddMgr, rootsPtr[i], 0, 3); +#endif + + tmp1 = Cudd_bddExistAbstract (ddMgr, rootsPtr[i], cubeCnfVar); + Cudd_RecursiveDeref (ddMgr, rootsPtr[i]); + rootsPtr[i] = tmp1; + +#if DDDMP_DEBUG_CNF + fprintf (stdout, "rootsPtr After Exist:\n"); + Cudd_PrintDebug (ddMgr, rootsPtr[i], 0, 3); +#endif + } + +#if DDDMP_DEBUG_CNF + fprintf (stdout, "cubeAllVar:\n"); + Cudd_PrintDebug (ddMgr, cubeAllVar, 0, 3); + fprintf (stdout, "cubeBddVar:\n"); + Cudd_PrintDebug (ddMgr, cubeBddVar, 0, 3); + fprintf (stdout, "cubeCnfVar:\n"); + Cudd_PrintDebug (ddMgr, cubeCnfVar, 0, 3); +#endif + + Cudd_RecursiveDeref (ddMgr, cubeAllVar); + Cudd_RecursiveDeref (ddMgr, cubeBddVar); + Cudd_RecursiveDeref (ddMgr, cubeCnfVar); + *rootsPtrPtr = rootsPtr; + + return (DDDMP_SUCCESS); + + /* + * Failure Condition + */ + +failure: + + DDDMP_FREE (rel); + DDDMP_FREE (rootsPtrPtr); + + return (DDDMP_FAILURE); +} + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpNodeAdd.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpNodeAdd.c new file mode 100644 index 000000000..6fca772f1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpNodeAdd.c @@ -0,0 +1,451 @@ +/**CFile********************************************************************** + + FileName [dddmpNodeAdd.c] + + PackageName [dddmp] + + Synopsis [Functions to handle ADD node infos and numbering] + + Description [Functions to handle ADD node infos and numbering. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NumberNodeRecurAdd(DdNode *f, int id); +static void RemoveFromUniqueRecurAdd(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecurAdd(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and number them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodes()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecurAdd (), NumberNodeRecurAdd (), + DddmpUnnumberDdNodesAdd ()] + +******************************************************************************/ + +int +DddmpNumberAddNodes ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int n /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int id=0, i; + + for (i=0; inext = (struct DdNode *)((ptruint)((id)<<1)); + } + + return; +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndexAdd (), DddmpSetVisitedAdd (), + DddmpVisitedAdd ()] + +******************************************************************************/ + +int +DddmpReadNodeIndexAdd ( + DdNode *f /* IN: BDD node */ + ) +{ + if (1 || !Cudd_IsConstant (f)) { + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisitedAdd (), DddmpClearVisitedAdd ()] + +******************************************************************************/ + +int +DddmpVisitedAdd ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedAdd (), DddmpClearVisitedAdd ()] + +******************************************************************************/ + +void +DddmpSetVisitedAdd ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedAdd (), DddmpSetVisitedAdd ()] + +******************************************************************************/ + +void +DddmpClearVisitedAdd ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecurAdd ( + DdNode *f /* IN: root of the BDD to be numbered */, + int id /* IN/OUT: index to be assigned to the node */ + ) +{ + f = Cudd_Regular(f); + + if (!DddmpVisitedAdd (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecurAdd (cuddT (f), id); + id = NumberNodeRecurAdd (cuddE (f), id); + } + + DddmpWriteNodeIndexAdd (f, ++id); + DddmpClearVisitedAdd (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. Constants remain untouched. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecurAdd ()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecurAdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisitedAdd (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecurAdd (ddMgr, cuddT (f)); + RemoveFromUniqueRecurAdd (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisitedAdd (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursively)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUniqueAdd ()] + +******************************************************************************/ + +static void +RestoreInUniqueRecurAdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + /* StQ 11.02.2004: + Bug fixed --> restore NULL within the next field */ + /*DddmpClearVisitedAdd (f);*/ + f->next = NULL; + + return; + } + + RestoreInUniqueRecurAdd (ddMgr, cuddT (f)); + RestoreInUniqueRecurAdd (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + f->next = *previousP; + *previousP = f; + + return; +} + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpNodeBdd.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpNodeBdd.c new file mode 100644 index 000000000..17f7fe39a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpNodeBdd.c @@ -0,0 +1,452 @@ +/**CFile********************************************************************** + + FileName [dddmpNodeBdd.c] + + PackageName [dddmp] + + Synopsis [Functions to handle BDD node infos and numbering] + + Description [Functions to handle BDD node infos and numbering. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NumberNodeRecurBdd(DdNode *f, int id); +static void RemoveFromUniqueRecurBdd(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecurBdd(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and number them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberBddNodes ()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecur(), NumberNodeRecur(), + DddmpUnnumberBddNodes ()] + +******************************************************************************/ + +int +DddmpNumberBddNodes ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int n /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int id=0, i; + + for (i=0; inext = (struct DdNode *)((ptruint)((id)<<1)); + } + + return; +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndexBdd (), DddmpSetVisitedBdd (), + DddmpVisitedBdd ()] + +******************************************************************************/ + +int +DddmpReadNodeIndexBdd ( + DdNode *f /* IN: BDD node */ + ) +{ + if (!Cudd_IsConstant (f)) { + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisitedBdd (), DddmpClearVisitedBdd ()] + +******************************************************************************/ + +int +DddmpVisitedBdd ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedBdd (), DddmpClearVisitedBdd ()] + +******************************************************************************/ + +void +DddmpSetVisitedBdd ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisited (), DddmpSetVisited ()] + +******************************************************************************/ + +void +DddmpClearVisitedBdd ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecurBdd ( + DdNode *f /* IN: root of the BDD to be numbered */, + int id /* IN/OUT: index to be assigned to the node */ + ) +{ + f = Cudd_Regular (f); + + if (!DddmpVisitedBdd (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecurBdd (cuddT (f), id); + id = NumberNodeRecurBdd (cuddE (f), id); + } + + DddmpWriteNodeIndexBdd (f, ++id); + DddmpClearVisitedBdd (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. Constants remain untouched. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecurBdd ()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecurBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisitedBdd (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecurBdd (ddMgr, cuddT (f)); + RemoveFromUniqueRecurBdd (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisitedBdd (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursively)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUnique()] + +******************************************************************************/ + +static void +RestoreInUniqueRecurBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + /* StQ 11.02.2004: + Bug fixed --> restore NULL within the next field */ + /*DddmpClearVisitedBdd (f);*/ + f->next = NULL; + + return; + } + + RestoreInUniqueRecurBdd (ddMgr, cuddT (f)); + RestoreInUniqueRecurBdd (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + f->next = *previousP; + *previousP = f; + + return; +} + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpNodeCnf.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpNodeCnf.c new file mode 100644 index 000000000..fa61ace69 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpNodeCnf.c @@ -0,0 +1,932 @@ +/**CFile********************************************************************** + + FileName [dddmpNodeCnf.c] + + PackageName [dddmp] + + Synopsis [Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs] + + Description [Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMP_DEBUG_CNF 0 + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpWriteNodeIndexCnfWithTerminalCheck(DdNode *f, int *cnfIds, int id); +static int DddmpClearVisitedCnfRecur(DdNode *f); +static void DddmpClearVisitedCnf(DdNode *f); +static int NumberNodeRecurCnf(DdNode *f, int *cnfIds, int id); +static void DddmpDdNodesCheckIncomingAndScanPath(DdNode *f, int pathLengthCurrent, int edgeInTh, int pathLengthTh); +static int DddmpDdNodesNumberEdgesRecur(DdNode *f, int *cnfIds, int id); +static int DddmpDdNodesResetCountRecur(DdNode *f); +static int DddmpDdNodesCountEdgesRecur(DdNode *f); +static void RemoveFromUniqueRecurCnf(DdManager *ddMgr, DdNode *f); +static void RestoreInUniqueRecurCnf(DdManager *ddMgr, DdNode *f); +static int DddmpPrintBddAndNextRecur(DdManager *ddMgr, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Removes nodes from unique table and numbers them] + + Description [Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodesCnf()). + ] + + SideEffects [Nodes are temporarily removed from unique table] + + SeeAlso [RemoveFromUniqueRecurCnf(), NumberNodeRecurCnf(), + DddmpUnnumberDdNodesCnf()] + +******************************************************************************/ + +int +DddmpNumberDdNodesCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int rootN /* IN: number of BDD roots in the array of BDDs */, + int *cnfIds /* OUT: CNF identifiers for variables */, + int id /* OUT: number of Temporary Variables Introduced */ + ) +{ + int i; + + for (i=0; i BDDs After Count Reset:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*----------------------- Count Incoming Edges ----------------------------*/ + + for (i=0; i BDDs After Count Recur:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*------------------------- Count Path Length ----------------------------*/ + + for (i=0; i BDDs After Check Incoming And Scan Path:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + /*-------------------- Number Nodes and Set Visited -----------------------*/ + + for (i=0; i BDDs After Count Edges Recur:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Restores nodes in unique table, loosing numbering] + + Description [Node indexes are no more needed. Nodes are re-linked in the + unique table. + ] + + SideEffects [None] + + SeeAlso [DddmpNumberDdNode()] + +******************************************************************************/ + +void +DddmpUnnumberDdNodesCnf( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs */, + int rootN /* IN: number of BDD roots in the array of BDDs */ + ) +{ + int i; + + for (i=0; i Bdd %d:\n", i); + fflush (stdout); + DddmpPrintBddAndNextRecur (ddMgr, f[i]); + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Write index to node] + + Description [The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. + ] + + SideEffects [None] + + SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf () + ] + +******************************************************************************/ + +int +DddmpWriteNodeIndexCnf ( + DdNode *f /* IN: BDD node */, + int id /* IN: index to be written */ + ) +{ + if (!Cudd_IsConstant (f)) { + f->next = (struct DdNode *)((ptruint)((id)<<1)); + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Returns true if node is visited] + + Description [Returns true if node is visited] + + SideEffects [None] + + SeeAlso [DddmpSetVisitedCnf (), DddmpClearVisitedCnf ()] + +******************************************************************************/ + +int +DddmpVisitedCnf ( + DdNode *f /* IN: BDD node to be tested */ + ) +{ + f = Cudd_Regular(f); + + return ((int)((ptruint)(f->next)) & (01)); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as visited] + + Description [Marks a node as visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpClearVisitedCnf ()] + +******************************************************************************/ + +void +DddmpSetVisitedCnf ( + DdNode *f /* IN: BDD node to be marked (as visited) */ + ) +{ + f = Cudd_Regular(f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01); + + return; +} + +/**Function******************************************************************** + + Synopsis [Reads the index of a node] + + Description [Reads the index of a node. LSB is skipped (used as visited + flag). + ] + + SideEffects [None] + + SeeAlso [DddmpWriteNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf ()] + +******************************************************************************/ + +int +DddmpReadNodeIndexCnf ( + DdNode *f /* IN: BDD node */ + ) +{ + if (!Cudd_IsConstant (f)) { + return ((int)(((ptruint)(f->next))>>1)); + } else { + return (1); + } +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Write index to node] + + Description [The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. The index corresponds to + the BDD node variable if both the node's children are a + constant node, otherwise a new CNF variable is used. + ] + + SideEffects [None] + + SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (), + DddmpVisitedCnf ()] + +*****************************************************************************/ + +static int +DddmpWriteNodeIndexCnfWithTerminalCheck ( + DdNode *f /* IN: BDD node */, + int *cnfIds /* IN: possible source for the index to be written */, + int id /* IN: possible source for the index to be written */ + ) +{ + if (!Cudd_IsConstant (f)) { + if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) { + /* If Variable SET ID as Variable ID */ + f->next = (struct DdNode *)((ptruint)((cnfIds[f->index])<<1)); + } else { + f->next = (struct DdNode *)((ptruint)((id)<<1)); + id++; + } + } + + return(id); +} + +/**Function******************************************************************** + + Synopsis [Mark ALL nodes as not visited] + + Description [Mark ALL nodes as not visited (it recurs on the node children)] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()] + +******************************************************************************/ + +static int +DddmpClearVisitedCnfRecur ( + DdNode *f /* IN: root of the BDD to be marked */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (cuddIsConstant (f)) { + return (DDDMP_SUCCESS); + } + + if (!DddmpVisitedCnf (f)) { + return (DDDMP_SUCCESS); + } + + retValue = DddmpClearVisitedCnfRecur (cuddT (f)); + retValue = DddmpClearVisitedCnfRecur (cuddE (f)); + + DddmpClearVisitedCnf (f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Marks a node as not visited] + + Description [Marks a node as not visited] + + SideEffects [None] + + SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()] + +******************************************************************************/ + +static void +DddmpClearVisitedCnf ( + DdNode *f /* IN: BDD node to be marked (as not visited) */ + ) +{ + f = Cudd_Regular (f); + + f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01)); + + return; +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +NumberNodeRecurCnf( + DdNode *f /* IN: root of the BDD to be numbered */, + int *cnfIds /* IN: possible source for numbering */, + int id /* IN/OUT: possible source for numbering */ + ) +{ + f = Cudd_Regular(f); + + if (!DddmpVisitedCnf (f)) { + return (id); + } + + if (!cuddIsConstant (f)) { + id = NumberNodeRecurCnf (cuddT (f), cnfIds, id); + id = NumberNodeRecurCnf (cuddE (f), cnfIds, id); + } + + id = DddmpWriteNodeIndexCnfWithTerminalCheck (f, cnfIds, id); + DddmpClearVisitedCnf (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with the right polarity. + The node is assigned to a new CNF variable only if it is a "shared" + node (i.e. the number of its incoming edges is greater than 1). + ] + + SideEffects ["visited" flags are set.] + + SeeAlso [] + +******************************************************************************/ + +static void +DddmpDdNodesCheckIncomingAndScanPath ( + DdNode *f /* IN: BDD node to be numbered */, + int pathLengthCurrent /* IN: Current Path Length */, + int edgeInTh /* IN: Max # In-Edges, after a Insert Cut Point */, + int pathLengthTh /* IN: Max Path Length (after, Insert a Cut Point) */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (DddmpVisitedCnf (f)) { + return; + } + + if (cuddIsConstant (f)) { + return; + } + + pathLengthCurrent++; + retValue = DddmpReadNodeIndexCnf (f); + + if ( ((edgeInTh >= 0) && (retValue > edgeInTh)) || + ((pathLengthTh >= 0) && (pathLengthCurrent > pathLengthTh)) + ) { + DddmpWriteNodeIndexCnf (f, 1); + pathLengthCurrent = 0; + } else { + DddmpWriteNodeIndexCnf (f, 0); + } + + DddmpDdNodesCheckIncomingAndScanPath (cuddT (f), pathLengthCurrent, + edgeInTh, pathLengthTh); + DddmpDdNodesCheckIncomingAndScanPath (cuddE (f), pathLengthCurrent, + edgeInTh, pathLengthTh); + + DddmpSetVisitedCnf (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Number nodes recursively in post-order] + + Description [Number nodes recursively in post-order. + The "visited" flag is used with the inverse polarity. + Numbering follows the subsequent strategy: + * if the index = 0 it remains so + * if the index >= 1 it gets enumerated. + This implies that the node is assigned to a new CNF variable only if + it is not a terminal node otherwise it is assigned the index of + the BDD variable. + ] + + SideEffects ["visited" flags are reset.] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesNumberEdgesRecur ( + DdNode *f /* IN: BDD node to be numbered */, + int *cnfIds /* IN: possible source for numbering */, + int id /* IN/OUT: possible source for numbering */ + ) +{ + int retValue; + + f = Cudd_Regular(f); + + if (!DddmpVisitedCnf (f)) { + return (id); + } + + if (cuddIsConstant (f)) { + return (id); + } + + id = DddmpDdNodesNumberEdgesRecur (cuddT (f), cnfIds, id); + id = DddmpDdNodesNumberEdgesRecur (cuddE (f), cnfIds, id); + + retValue = DddmpReadNodeIndexCnf (f); + if (retValue >= 1) { + id = DddmpWriteNodeIndexCnfWithTerminalCheck (f, cnfIds, id); + } else { + DddmpWriteNodeIndexCnf (f, 0); + } + + DddmpClearVisitedCnf (f); + + return (id); +} + +/**Function******************************************************************** + + Synopsis [Resets counter and visited flag for ALL nodes of a BDD] + + Description [Resets counter and visited flag for ALL nodes of a BDD (it + recurs on the node children). The index field of the node is + used as counter. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesResetCountRecur ( + DdNode *f /* IN: root of the BDD whose counters are reset */ + ) +{ + int retValue; + + f = Cudd_Regular (f); + + if (!DddmpVisitedCnf (f)) { + return (DDDMP_SUCCESS); + } + + if (!cuddIsConstant (f)) { + retValue = DddmpDdNodesResetCountRecur (cuddT (f)); + retValue = DddmpDdNodesResetCountRecur (cuddE (f)); + } + + DddmpWriteNodeIndexCnf (f, 0); + DddmpClearVisitedCnf (f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Counts the number of incoming edges for each node of a BDD] + + Description [Counts (recursively) the number of incoming edges for each + node of a BDD. This number is stored in the index field. + ] + + SideEffects ["visited" flags remain untouched.] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpDdNodesCountEdgesRecur ( + DdNode *f /* IN: root of the BDD */ + ) +{ + int indexValue, retValue; + + f = Cudd_Regular (f); + + if (cuddIsConstant (f)) { + return (DDDMP_SUCCESS); + } + + if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) { + return (DDDMP_SUCCESS); + } + + indexValue = DddmpReadNodeIndexCnf (f); + + /* IF (first time) THEN recur */ + if (indexValue == 0) { + retValue = DddmpDdNodesCountEdgesRecur (cuddT (f)); + retValue = DddmpDdNodesCountEdgesRecur (cuddE (f)); + } + + /* Increment Incoming-Edge Count Flag */ + indexValue++; + DddmpWriteNodeIndexCnf (f, indexValue); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Removes a node from unique table] + + Description [Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on on the + children of the node. Constants remain untouched. + ] + + SideEffects [Nodes are left with the "visited" flag true.] + + SeeAlso [RestoreInUniqueRecurCnf()] + +******************************************************************************/ + +static void +RemoveFromUniqueRecurCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be extracted */ + ) +{ + DdNode *node, *last, *next; + DdNode *sentinel = &(ddMgr->sentinel); + DdNodePtr *nodelist; + DdSubtable *subtable; + int pos, level; + + f = Cudd_Regular (f); + + if (DddmpVisitedCnf (f)) { + return; + } + + if (!cuddIsConstant (f)) { + + RemoveFromUniqueRecurCnf (ddMgr, cuddT (f)); + RemoveFromUniqueRecurCnf (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + node = nodelist[pos]; + last = NULL; + while (node != sentinel) { + next = node->next; + if (node == f) { + if (last != NULL) + last->next = next; + else + nodelist[pos] = next; + break; + } else { + last = node; + node = next; + } + } + + f->next = NULL; + + } + + DddmpSetVisitedCnf (f); + + return; +} + +/**Function******************************************************************** + + Synopsis [Restores a node in unique table] + + Description [Restores a node in unique table (recursive)] + + SideEffects [Nodes are not restored in the same order as before removal] + + SeeAlso [RemoveFromUnique()] + +******************************************************************************/ + +static void +RestoreInUniqueRecurCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be restored */ + ) +{ + DdNodePtr *nodelist; + DdNode *T, *E, *looking; + DdNodePtr *previousP; + DdSubtable *subtable; + int pos, level; +#ifdef DDDMP_DEBUG + DdNode *node; + DdNode *sentinel = &(ddMgr->sentinel); +#endif + + f = Cudd_Regular(f); + + if (!Cudd_IsComplement (f->next)) { + return; + } + + if (cuddIsConstant (f)) { + /* StQ 11.02.2004: + Bug fixed --> restore NULL within the next field */ + /*DddmpClearVisitedCnf (f);*/ + f->next = NULL; + + return; + } + + RestoreInUniqueRecurCnf (ddMgr, cuddT (f)); + RestoreInUniqueRecurCnf (ddMgr, cuddE (f)); + + level = ddMgr->perm[f->index]; + subtable = &(ddMgr->subtables[level]); + + nodelist = subtable->nodelist; + + pos = ddHash (cuddT (f), cuddE (f), subtable->shift); + +#ifdef DDDMP_DEBUG + /* verify uniqueness to avoid duplicate nodes in unique table */ + for (node=nodelist[pos]; node != sentinel; node=node->next) + assert(node!=f); +#endif + + T = cuddT (f); + E = cuddE (f); + previousP = &(nodelist[pos]); + looking = *previousP; + + while (T < cuddT (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + + while (T == cuddT (looking) && E < cuddE (looking)) { + previousP = &(looking->next); + looking = *previousP; + } + f->next = *previousP; + *previousP = f; + + return; +} + +/**Function******************************************************************** + + Synopsis [Prints debug info] + + Description [Prints debug info for a BDD on the screen. It recurs on + node's children. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpPrintBddAndNextRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: root of the BDD to be displayed */ + ) +{ + int retValue; + DdNode *fPtr, *tPtr, *ePtr; + + fPtr = Cudd_Regular (f); + + if (Cudd_IsComplement (f)) { + fprintf (stdout, "sign=- ptr=%ld ", ((long int) fPtr)); + } else { + fprintf (stdout, "sign=+ ptr=%ld ", ((long int) fPtr)); + } + + if (cuddIsConstant (fPtr)) { + fprintf (stdout, "one\n"); + fflush (stdout); + return (DDDMP_SUCCESS); + } + + fprintf (stdout, + "thenPtr=%ld elsePtr=%ld BddId=%d CnfId=%d Visited=%d\n", + ((long int) cuddT (fPtr)), ((long int) cuddE (fPtr)), + fPtr->index, DddmpReadNodeIndexCnf (fPtr), + DddmpVisitedCnf (fPtr)); + + tPtr = cuddT (fPtr); + ePtr = cuddE (fPtr); + if (Cudd_IsComplement (f)) { + tPtr = Cudd_Not (tPtr); + ePtr = Cudd_Not (ePtr); + } + + retValue = DddmpPrintBddAndNextRecur (ddMgr, tPtr); + retValue = DddmpPrintBddAndNextRecur (ddMgr, ePtr); + + return (DDDMP_SUCCESS); +} + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpStoreAdd.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpStoreAdd.c new file mode 100644 index 000000000..a86e39ada --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpStoreAdd.c @@ -0,0 +1,957 @@ +/**CFile********************************************************************** + FileName [dddmpStoreAdd.c] + + PackageName [dddmp] + + Synopsis [Functions to write ADDs to file.] + + Description [Functions to write ADDs to file. + ADDs are represended on file either in text or binary format under the + following rules. A file contains a forest of ADDs (a vector of + Boolean functions). ADD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to ADD + functions, followed by the list of nodes. + ADD nodes are listed according to their numbering, and in the present + implementation numbering follows a post-order strategy, in such a way + that a node is never listed before its Then/Else children. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NodeStoreRecurAdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp); +static int NodeTextStoreAdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp, int idf, int vf, int idT, int idE); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument ADD.] + + Description [Dumps the argument ADD to file. Dumping is done through + Dddmp_cuddAddArrayStore, And a dummy array of 1 ADD root is + used for this purpose. + ] + + SideEffects [Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order.] + + SeeAlso [Dddmp_cuddAddLoad Dddmp_cuddAddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddAddStore ( + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + DdNode *f /* IN: ADD root to be stored */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var ids */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + retValue = Dddmp_cuddAddArrayStore (ddMgr, ddname, 1, tmpArray, NULL, + varnames, auxids, mode, varinfo, fname, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of ADDs.] + + Description [Dumps the argument array of ADDs to file. Dumping is + either in text or binary form. see the corresponding BDD dump + function for further details. + ] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + ] + + SeeAlso [Dddmp_cuddAddStore, Dddmp_cuddAddLoad, + Dddmp_cuddAddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddAddArrayStore ( + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + int nRoots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of ADD roots to be stored */, + char **rootnames /* IN: array of root names (or NULL) */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var IDs */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + +#if 0 +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During ADD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During ADD Store.\n"); + fflush (stderr); + } + } +#endif +#endif +#endif + + retValue = DddmpCuddDdArrayStoreBdd (DDDMP_ADD, ddMgr, ddname, nRoots, f, + rootnames, varnames, auxids, mode, varinfo, fname, fp); + +#if 0 +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During ADD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During ADD Store.\n"); + fflush (stderr); + } + } +#endif +#endif +#endif + + return (retValue); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of + BDDs/ADDs. + ] + + Description [Dumps the argument array of BDDs/ADDs to file. Internal + function doing inner steps of store for BDDs and ADDs. + ADD store is presently supported only with the text format. + ] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + ] + + SeeAlso [Dddmp_cuddBddStore, Dddmp_cuddBddLoad, + Dddmp_cuddBddArrayLoad + ] + +******************************************************************************/ + +int +DddmpCuddDdArrayStoreBdd ( + Dddmp_DecompType ddType /* IN: Selects the decomp type: BDD or ADD */, + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + int nRoots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of DD roots to be stored */, + char **rootnames /* IN: array of root names (or NULL) */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var IDs */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *ids = NULL; + int *permids = NULL; + int *invpermids = NULL; + int *supportids = NULL; + int *outids = NULL; + char **outvarnames = NULL; + int nVars = ddMgr->size; + int nnodes; + int retValue; + int i, var; + int fileToClose = 0; + + /* + * Check DD Type and Mode + */ + + Dddmp_CheckAndGotoLabel (ddType==DDDMP_BDD, + "Error writing to file: BDD Type.", failure); + Dddmp_CheckAndGotoLabel (mode==DDDMP_MODE_BINARY, + "Error writing to file: ADD Type with Binary Mode.", failure); + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /* + * Force binary mode if automatic. + */ + + switch (mode) { + case DDDMP_MODE_TEXT: + case DDDMP_MODE_BINARY: + break; + case DDDMP_MODE_DEFAULT: + mode = DDDMP_MODE_BINARY; + break; + default: + mode = DDDMP_MODE_BINARY; + break; + } + + /* + * Alloc vectors for variable IDs, perm IDs and support IDs. + * +1 to include a slot for terminals. + */ + + ids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (ids==NULL, "Error allocating memory.", failure); + permids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (permids==NULL, "Error allocating memory.", failure); + invpermids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (invpermids==NULL, "Error allocating memory.", + failure); + supportids = DDDMP_ALLOC (int, nVars+1); + Dddmp_CheckAndGotoLabel (supportids==NULL, "Error allocating memory.", + failure); + + for (i=0; iindex] = scan->index; + permids[scan->index] = ddMgr->perm[scan->index]; + invpermids[ddMgr->perm[scan->index]] = scan->index; + scan = cuddT (scan); + } + Cudd_RecursiveDeref (ddMgr, support); + } + /* so that we do not try to free it in case of failure */ + support = NULL; + + /* + * Set supportids to incremental (shrinked) values following the ordering. + */ + + for (i=0, var=0; i= 0) { + supportids[invpermids[i]] = var++; + } + } + /* set a dummy id for terminal nodes */ + supportids[nVars] = var; + + /* + * Select conversion array for extra var info + */ + + switch (mode) { + case DDDMP_MODE_TEXT: + switch (varinfo) { + case DDDMP_VARIDS: + outids = ids; + break; + case DDDMP_VARPERMIDS: + outids = permids; + break; + case DDDMP_VARAUXIDS: + outids = auxids; + break; + case DDDMP_VARNAMES: + outvarnames = varnames; + break; + case DDDMP_VARDEFAULT: + break; + } + break; + case DDDMP_MODE_BINARY: + outids = NULL; + break; + } + + /* + * Number dd nodes and count them (numbering is from 1 to nnodes) + */ + + nnodes = DddmpNumberAddNodes (ddMgr, f, nRoots); + + /* + * Start Header + */ + +#ifdef DDDMP_VERSION + retValue = fprintf (fp, ".ver %s\n", DDDMP_VERSION); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); +#endif + + retValue = fprintf (fp, ".add\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".mode %c\n", mode); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (mode == DDDMP_MODE_TEXT) { + retValue = fprintf (fp, ".varinfo %d\n", varinfo); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + if (ddname != NULL) { + retValue = fprintf (fp, ".dd %s\n",ddname); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, ".nnodes %d\n", nnodes); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nvars %d\n", nVars); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nsuppvars %d\n", var); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /*------------ Write the Var Names by scanning the ids array -------------*/ + + if (varnames != NULL) { + + retValue = fprintf (fp, ".suppvarnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; i= 0) { + if (varnames[ids[i]] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. DUMMY%d generated\n", i); + fflush (stderr); + varnames[ids[i]] = DDDMP_ALLOC (char, 10); + Dddmp_CheckAndGotoLabel (varnames[ids[i]] == NULL, + "Error allocating memory.", failure); + sprintf (varnames[ids[i]], "DUMMY%d", i); + } + retValue = fprintf (fp, " %s", varnames[ids[i]]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /*--------- Write the Var SUPPORT Names by scanning the ids array ---------*/ + + if (varnames != NULL) { + retValue = fprintf (fp, ".orderedvarnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; iinvperm[i]] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. DUMMY%d generated\n", i); + fflush (stderr); + varnames[ddMgr->invperm[i]] = DDDMP_ALLOC (char, 10); + Dddmp_CheckAndGotoLabel (varnames[ddMgr->invperm[i]] == NULL, + "Error allocating memory.", failure); + sprintf (varnames[ddMgr->invperm[i]], "DUMMY%d", i); + } + + retValue = fprintf (fp, " %s", varnames[ddMgr->invperm[i]]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /*------------ Write the var ids by scanning the ids array ---------------*/ + + retValue = fprintf (fp, ".ids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; i= 0) { + retValue = fprintf (fp, " %d", i); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * Write the var permids by scanning the permids array. + */ + + retValue = fprintf (fp, ".permids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + for (i = 0; i < nVars; i++) { + if (permids[i] >= 0) { + retValue = fprintf (fp, " %d", permids[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (auxids != NULL) { + + /* + * Write the var auxids by scanning the ids array. + */ + + retValue = fprintf (fp, ".auxids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + for (i = 0; i < nVars; i++) { + if (ids[i] >= 0) { + retValue = fprintf (fp, " %d", auxids[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /* + * Write the roots info. + */ + + retValue = fprintf (fp, ".nroots %d\n", nRoots); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (rootnames != NULL) { + + /* + * Write the root names. + */ + + retValue = fprintf (fp, ".rootnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i = 0; i < nRoots; i++) { + if (rootnames[i] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. ROOT%d generated\n",i); + fflush (stderr); + rootnames[i] = DDDMP_ALLOC(char,10); + Dddmp_CheckAndGotoLabel (rootnames[i]==NULL, + "Error writing to file.", failure); + sprintf(rootnames[ids[i]], "ROOT%d",i); + } + retValue = fprintf (fp, " %s", rootnames[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, ".rootids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * Write BDD indexes of function roots. + * Use negative integers for complemented edges. + */ + + for (i = 0; i < nRoots; i++) { + if (f[i] == NULL) { + (void) fprintf (stderr, "DdStore Warning: %d-th root is NULL\n",i); + fflush (stderr); + retValue = fprintf (fp, " 0"); + } + if (Cudd_IsComplement(f[i])) { + retValue = fprintf (fp, " -%d", + DddmpReadNodeIndexAdd (Cudd_Regular (f[i]))); + } else { + retValue = fprintf (fp, " %d", + DddmpReadNodeIndexAdd (Cudd_Regular (f[i]))); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nodes\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * END HEADER + */ + + /* + * Call the function that really gets the job done. + */ + + for (i = 0; i < nRoots; i++) { + if (f[i] != NULL) { + retValue = NodeStoreRecurAdd (ddMgr, Cudd_Regular(f[i]), + mode, supportids, outvarnames, outids, fp); + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "Error writing to file.", failure); + } + } + + /* + * Write trailer and return. + */ + + retValue = fprintf (fp, ".end\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (fileToClose) { + fclose (fp); + } + + DddmpUnnumberAddNodes (ddMgr, f, nRoots); + DDDMP_FREE (ids); + DDDMP_FREE (permids); + DDDMP_FREE (invpermids); + DDDMP_FREE (supportids); + + return (DDDMP_SUCCESS); + + failure: + + if (ids != NULL) { + DDDMP_FREE (ids); + } + if (permids != NULL) { + DDDMP_FREE (permids); + } + if (invpermids != NULL) { + DDDMP_FREE (invpermids); + } + if (supportids != NULL) { + DDDMP_FREE (supportids); + } + if (support != NULL) { + Cudd_RecursiveDeref (ddMgr, support); + } + + return (DDDMP_FAILURE); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Dddmp_bddStore.] + + Description [Stores a node to file in either test or binary mode. + In text mode a node is represented (on a text line basis) as +
                            +
                          • node-index \[var-extrainfo\] var-index Then-index Else-index +
                          + + where all indexes are integer numbers and var-extrainfo + (optional redundant field) is either an integer or a string + (variable name). Node-index is redundant (due to the node + ordering) but we keep it for readability.

                          + + In binary mode nodes are represented as a sequence of bytes, + representing var-index, Then-index, and Else-index in an + optimized way. Only the first byte (code) is mandatory. + Integer indexes are represented in absolute or relative mode, + where relative means offset wrt. a Then/Else node info. + Suppose Var(NodeId), Then(NodeId) and Else(NodeId) represent + infos about a given node.

                          + + The generic "NodeId" node is stored as + +

                            +
                          • code-byte +
                          • \[var-info\] +
                          • \[Then-info\] +
                          • \[Else-info\] +
                          + + where code-byte contains bit fields + +
                            +
                          • Unused : 1 bit +
                          • Variable: 2 bits, one of the following codes +
                              +
                            • DDDMP_ABSOLUTE_ID var-info = Var(NodeId) follows +
                            • DDDMP_RELATIVE_ID Var(NodeId) is represented in relative form as + var-info = Min(Var(Then(NodeId)),Var(Else(NodeId))) -Var(NodeId) +
                            • DDDMP_RELATIVE_1 No var-info follows, because + Var(NodeId) = Min(Var(Then(NodeId)),Var(Else(NodeId)))-1 +
                            • DDDMP_TERMINAL Node is a terminal, no var info required +
                            +
                          • T : 2 bits, with codes similar to V +
                              +
                            • DDDMP_ABSOLUTE_ID Then-info = Then(NodeId) follows +
                            • DDDMP_RELATIVE_ID Then(NodeId) is represented in relative form as + Then-info = Nodeid-Then(NodeId) +
                            • DDDMP_RELATIVE_1 No info on Then(NodeId) follows, because + Then(NodeId) = NodeId-1 +
                            • DDDMP_TERMINAL Then Node is a terminal, no info required (for BDDs) +
                            +
                          • Ecompl : 1 bit, if 1 means complemented edge +
                          • E : 2 bits, with codes and meanings as for the Then edge +
                          + var-info, Then-info, Else-info (if required) are represented as unsigned + integer values on a sufficient set of bytes (MSByte first). + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +NodeStoreRecurAdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: store file */ + ) +{ + DdNode *T = NULL; + DdNode *E = NULL; + int idf = (-1); + int idT = (-1); + int idE = (-1); + int vf = (-1); + int vT = (-1); + int vE = (-1); + int retValue; + int nVars; + + nVars = ddMgr->size; + T = E = NULL; + idf = idT = idE = (-1); + +#ifdef DDDMP_DEBUG + assert(!Cudd_IsComplement(f)); + assert(f!=NULL); + assert(supportids!=NULL); +#endif + + /* If already visited, nothing to do. */ + if (DddmpVisitedAdd (f)) { + return (DDDMP_SUCCESS); + } + + /* Mark node as visited. */ + DddmpSetVisitedAdd (f); + + if (Cudd_IsConstant(f)) { + /* Check for special case: don't recur */ + idf = DddmpReadNodeIndexAdd (f); + } else { + +#ifdef DDDMP_DEBUG + /* BDDs! Only one constant supported */ + assert (!cuddIsConstant(f)); +#endif + + /* + * Recursive call for Then edge + */ + + T = cuddT(f); +#ifdef DDDMP_DEBUG + /* ROBDDs! No complemented Then edge */ + assert (!Cudd_IsComplement(T)); +#endif + /* recur */ + retValue = NodeStoreRecurAdd (ddMgr, T, mode, supportids, varnames, outids, + fp); + if (retValue != DDDMP_SUCCESS) { + return (retValue); + } + + /* + * Recursive call for Else edge + */ + + E = Cudd_Regular (cuddE (f)); + retValue = NodeStoreRecurAdd (ddMgr, E, mode, supportids, varnames, outids, + fp); + if (retValue != DDDMP_SUCCESS) { + return (retValue); + } + + /* + * Obtain nodeids and variable ids of f, T, E + */ + + idf = DddmpReadNodeIndexAdd (f); + vf = f->index; + + idT = DddmpReadNodeIndexAdd (T); + if (Cudd_IsConstant(T)) { + vT = nVars; + } else { + vT = T->index; + } + + idE = DddmpReadNodeIndexAdd (E); + if (Cudd_IsConstant(E)) { + vE = nVars; + } else { + vE = E->index; + } + } + + retValue = NodeTextStoreAdd (ddMgr, f, mode, supportids, varnames, + outids, fp, idf, vf, idT, idE); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Store One Single Node in Text Format.] + + Description [Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. + ] + + SideEffects [None] + + SeeAlso [NodeBinaryStore] + +******************************************************************************/ + +static int +NodeTextStoreAdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: Store file */, + int idf /* IN: index of the current node */, + int vf /* IN: variable of the current node */, + int idT /* IN: index of the Then node */, + int idE /* IN: index of the Else node */ + ) +{ + int retValue; + + /* + * Check for Constant + */ + + if (Cudd_IsConstant(f)) { + + if (f == Cudd_ReadOne(ddMgr)) { + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T 1 0 0\n", idf); + } else { + retValue = fprintf (fp, "%d 1 0 0\n", idf); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + if (f == Cudd_ReadZero(ddMgr)) { + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T 0 0 0\n", idf); + } else { + retValue = fprintf (fp, "%d 0 0 0\n", idf); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * A constant node different from 1: an ADD constant + */ + + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T %g 0 0\n",idf,Cudd_V(f)); + } else { + retValue = fprintf (fp, "%d %g 0 0\n",idf, Cudd_V(f)); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * ... Not A Constant + */ + + if (Cudd_IsComplement (cuddE(f))) { + idE = -idE; + } + + if (varnames != NULL) { + retValue = fprintf (fp, "%d %s %d %d %d\n", + idf, varnames[vf], supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + if (outids != NULL) { + retValue = fprintf (fp, "%d %d %d %d %d\n", + idf, outids[vf], supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + retValue = fprintf (fp, "%d %d %d %d\n", + idf, supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpStoreBdd.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpStoreBdd.c new file mode 100644 index 000000000..cdc796843 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpStoreBdd.c @@ -0,0 +1,1114 @@ +/**CFile********************************************************************** + + FileName [dddmpStoreBdd.c] + + PackageName [dddmp] + + Synopsis [Functions to write BDDs to file.] + + Description [Functions to write BDDs to file. + BDDs are represended on file either in text or binary format under the + following rules. A file contains a forest of BDDs (a vector of + Boolean functions). BDD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to BDD + functions, followed by the list of nodes. BDD nodes are listed + according to their numbering, and in the present implementation + numbering follows a post-order strategy, in such a way that a node + is never listed before its Then/Else children. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int NodeStoreRecurBdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp); +static int NodeTextStoreBdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp, int idf, int vf, int idT, int idE); +static int NodeBinaryStoreBdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp, int idf, int vf, int idT, int idE, int vT, int vE, DdNode *T, DdNode *E); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD.] + + Description [Dumps the argument BDD to file. Dumping is done through + Dddmp_cuddBddArrayStore. A dummy array of 1 BDD root is + used for this purpose. + ] + + SideEffects [Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. + ] + + SeeAlso [Dddmp_cuddBddLoad Dddmp_cuddBddArrayLoad] + +******************************************************************************/ + +int +Dddmp_cuddBddStore ( + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + DdNode *f /* IN: BDD root to be stored */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var ids */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStore (ddMgr,ddname,1,tmpArray,NULL, + varnames, auxids, mode, varinfo, fname, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of BDDs.] + + Description [Dumps the argument array of BDDs to file. Dumping is either + in text or binary form. BDDs are stored to the fp (already + open) file if not NULL. Otherwise the file whose name is + fname is opened in write mode. The header has the same format + for both textual and binary dump. Names are allowed for input + variables (vnames) and for represented functions (rnames). + For sake of generality and because of dynamic variable + ordering both variable IDs and permuted IDs are included. + New IDs are also supported (auxids). Variables are identified + with incremental numbers. according with their positiom in + the support set. In text mode, an extra info may be added, + chosen among the following options: name, ID, PermID, or an + auxiliary id. Since conversion from DD pointers to integers + is required, DD nodes are temporarily removed from the unique + hash table. This allows the use of the next field to store + node IDs. + ] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + ] + + SeeAlso [Dddmp_cuddBddStore, Dddmp_cuddBddLoad, + Dddmp_cuddBddArrayLoad + ] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStore ( + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: dd name (or NULL) */, + int nRoots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of BDD roots to be stored */, + char **rootnames /* IN: array of root names (or NULL) */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var IDs */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + retValue = DddmpCuddBddArrayStore (DDDMP_BDD, ddMgr, ddname, nRoots, f, + rootnames, varnames, auxids, mode, varinfo, fname, fp); + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of + BDDs. + ] + + Description [Dumps the argument array of BDDs to file. + Internal function doing inner steps of store for BDDs. + ] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + ] + + SeeAlso [Dddmp_cuddBddStore, Dddmp_cuddBddLoad, + Dddmp_cuddBddArrayLoad + ] + +******************************************************************************/ + +int +DddmpCuddBddArrayStore ( + Dddmp_DecompType ddType /* IN: Selects the decomp type BDD */, + DdManager *ddMgr /* IN: DD Manager */, + char *ddname /* IN: DD name (or NULL) */, + int nRoots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of DD roots to be stored */, + char **rootnames /* IN: array of root names (or NULL) */, + char **varnames /* IN: array of variable names (or NULL) */, + int *auxids /* IN: array of converted var IDs */, + int mode /* IN: storing mode selector */, + Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *ids = NULL; + int *permids = NULL; + int *invpermids = NULL; + int *supportids = NULL; + int *outids = NULL; + char **outvarnames = NULL; + int nVars = ddMgr->size; + int nnodes; + int retValue; + int i, var; + int fileToClose = 0; + + /* + * Check DD Type + */ + + Dddmp_CheckAndGotoLabel (ddType==DDDMP_ADD, + "Error writing to file: ADD Type.", failure); + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /* + * Force binary mode if automatic. + */ + + switch (mode) { + case DDDMP_MODE_TEXT: + case DDDMP_MODE_BINARY: + break; + case DDDMP_MODE_DEFAULT: + mode = DDDMP_MODE_BINARY; + break; + default: + mode = DDDMP_MODE_BINARY; + break; + } + + /* + * Alloc vectors for variable IDs, perm IDs and support IDs. + * +1 to include a slot for terminals. + */ + + ids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (ids==NULL, "Error allocating memory.", failure); + permids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (permids==NULL, "Error allocating memory.", failure); + invpermids = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (invpermids==NULL, "Error allocating memory.", + failure); + supportids = DDDMP_ALLOC (int, nVars+1); + Dddmp_CheckAndGotoLabel (supportids==NULL, "Error allocating memory.", + failure); + + for (i=0; iindex] = scan->index; + permids[scan->index] = ddMgr->perm[scan->index]; + invpermids[ddMgr->perm[scan->index]] = scan->index; + scan = cuddT (scan); + } + Cudd_RecursiveDeref (ddMgr, support); + } + /* so that we do not try to free it in case of failure */ + support = NULL; + + /* + * Set supportids to incremental (shrinked) values following the ordering. + */ + + for (i=0, var=0; i= 0) { + supportids[invpermids[i]] = var++; + } + } + /* set a dummy id for terminal nodes */ + supportids[nVars] = var; + + /* + * Select conversion array for extra var info + */ + + switch (mode) { + case DDDMP_MODE_TEXT: + switch (varinfo) { + case DDDMP_VARIDS: + outids = ids; + break; + case DDDMP_VARPERMIDS: + outids = permids; + break; + case DDDMP_VARAUXIDS: + outids = auxids; + break; + case DDDMP_VARNAMES: + outvarnames = varnames; + break; + case DDDMP_VARDEFAULT: + break; + } + break; + case DDDMP_MODE_BINARY: + outids = NULL; + break; + } + + /* + * Number dd nodes and count them (numbering is from 1 to nnodes) + */ + + nnodes = DddmpNumberBddNodes (ddMgr, f, nRoots); + + /* + * Start Header + */ + +#ifdef DDDMP_VERSION + retValue = fprintf (fp, ".ver %s\n", DDDMP_VERSION); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); +#endif + + retValue = fprintf (fp, ".mode %c\n", mode); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (mode == DDDMP_MODE_TEXT) { + retValue = fprintf (fp, ".varinfo %d\n", varinfo); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + if (ddname != NULL) { + retValue = fprintf (fp, ".dd %s\n",ddname); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, ".nnodes %d\n", nnodes); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nvars %d\n", nVars); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nsuppvars %d\n", var); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /*------------ Write the Var Names by scanning the ids array -------------*/ + + if (varnames != NULL) { + + retValue = fprintf (fp, ".suppvarnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; i= 0) { + if (varnames[ids[i]] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. DUMMY%d generated\n", i); + fflush (stderr); + varnames[ids[i]] = DDDMP_ALLOC (char, 10); + Dddmp_CheckAndGotoLabel (varnames[ids[i]] == NULL, + "Error allocating memory.", failure); + sprintf (varnames[ids[i]], "DUMMY%d", i); + } + retValue = fprintf (fp, " %s", varnames[ids[i]]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /*--------- Write the Var SUPPORT Names by scanning the ids array ---------*/ + + if (varnames != NULL) { + retValue = fprintf (fp, ".orderedvarnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; iinvperm[i]] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. DUMMY%d generated\n", i); + fflush (stderr); + varnames[ddMgr->invperm[i]] = DDDMP_ALLOC (char, 10); + Dddmp_CheckAndGotoLabel (varnames[ddMgr->invperm[i]] == NULL, + "Error allocating memory.", failure); + sprintf (varnames[ddMgr->invperm[i]], "DUMMY%d", i); + } + + retValue = fprintf (fp, " %s", varnames[ddMgr->invperm[i]]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /*------------ Write the var ids by scanning the ids array ---------------*/ + + retValue = fprintf (fp, ".ids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i=0; i= 0) { + retValue = fprintf (fp, " %d", i); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * Write the var permids by scanning the permids array. + */ + + retValue = fprintf (fp, ".permids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + for (i = 0; i < nVars; i++) { + if (permids[i] >= 0) { + retValue = fprintf (fp, " %d", permids[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (auxids != NULL) { + + /* + * Write the var auxids by scanning the ids array. + */ + + retValue = fprintf (fp, ".auxids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + for (i = 0; i < nVars; i++) { + if (ids[i] >= 0) { + retValue = fprintf (fp, " %d", auxids[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + } + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + /* + * Write the roots info. + */ + + retValue = fprintf (fp, ".nroots %d\n", nRoots); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (rootnames != NULL) { + + /* + * Write the root names. + */ + + retValue = fprintf (fp, ".rootnames"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + for (i = 0; i < nRoots; i++) { + if (rootnames[i] == NULL) { + (void) fprintf (stderr, + "DdStore Warning: null variable name. ROOT%d generated\n",i); + fflush (stderr); + rootnames[i] = DDDMP_ALLOC(char,10); + Dddmp_CheckAndGotoLabel (rootnames[i]==NULL, + "Error writing to file.", failure); + sprintf(rootnames[ids[i]], "ROOT%d",i); + } + retValue = fprintf (fp, " %s", rootnames[i]); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, ".rootids"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * Write BDD indexes of function roots. + * Use negative integers for complemented edges. + */ + + for (i = 0; i < nRoots; i++) { + if (f[i] == NULL) { + (void) fprintf (stderr, "DdStore Warning: %d-th root is NULL\n",i); + fflush (stderr); + retValue = fprintf (fp, " 0"); + } + if (Cudd_IsComplement(f[i])) { + retValue = fprintf (fp, " -%d", + DddmpReadNodeIndexBdd (Cudd_Regular (f[i]))); + } else { + retValue = fprintf (fp, " %d", + DddmpReadNodeIndexBdd (Cudd_Regular (f[i]))); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + } + + retValue = fprintf (fp, "\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + retValue = fprintf (fp, ".nodes\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + /* + * END HEADER + */ + + /* + * Call the function that really gets the job done. + */ + + for (i = 0; i < nRoots; i++) { + if (f[i] != NULL) { + retValue = NodeStoreRecurBdd (ddMgr, Cudd_Regular(f[i]), + mode, supportids, outvarnames, outids, fp); + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "Error writing to file.", failure); + } + } + + /* + * Write trailer and return. + */ + + retValue = fprintf (fp, ".end\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.", + failure); + + if (fileToClose) { + fclose (fp); + } + + DddmpUnnumberBddNodes (ddMgr, f, nRoots); + DDDMP_FREE (ids); + DDDMP_FREE (permids); + DDDMP_FREE (invpermids); + DDDMP_FREE (supportids); + + return (DDDMP_SUCCESS); + + failure: + + if (ids != NULL) { + DDDMP_FREE (ids); + } + if (permids != NULL) { + DDDMP_FREE (permids); + } + if (invpermids != NULL) { + DDDMP_FREE (invpermids); + } + if (supportids != NULL) { + DDDMP_FREE (supportids); + } + if (support != NULL) { + Cudd_RecursiveDeref (ddMgr, support); + } + + return (DDDMP_FAILURE); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Dddmp_bddStore.] + + Description [Stores a node to file in either test or binary mode. + In text mode a node is represented (on a text line basis) as +
                            +
                          • node-index \[var-extrainfo\] var-index Then-index Else-index +
                          + + where all indexes are integer numbers and var-extrainfo + (optional redundant field) is either an integer or a string + (variable name). Node-index is redundant (due to the node + ordering) but we keep it for readability.

                          + + In binary mode nodes are represented as a sequence of bytes, + representing var-index, Then-index, and Else-index in an + optimized way. Only the first byte (code) is mandatory. + Integer indexes are represented in absolute or relative mode, + where relative means offset wrt. a Then/Else node info. + Suppose Var(NodeId), Then(NodeId) and Else(NodeId) represent + infos about a given node.

                          + + The generic "NodeId" node is stored as + +

                            +
                          • code-byte +
                          • \[var-info\] +
                          • \[Then-info\] +
                          • \[Else-info\] +
                          + + where code-byte contains bit fields + +
                            +
                          • Unused : 1 bit +
                          • Variable: 2 bits, one of the following codes +
                              +
                            • DDDMP_ABSOLUTE_ID var-info = Var(NodeId) follows +
                            • DDDMP_RELATIVE_ID Var(NodeId) is represented in relative form as + var-info = Min(Var(Then(NodeId)),Var(Else(NodeId))) -Var(NodeId) +
                            • DDDMP_RELATIVE_1 No var-info follows, because + Var(NodeId) = Min(Var(Then(NodeId)),Var(Else(NodeId)))-1 +
                            • DDDMP_TERMINAL Node is a terminal, no var info required +
                            +
                          • T : 2 bits, with codes similar to V +
                              +
                            • DDDMP_ABSOLUTE_ID Then-info = Then(NodeId) follows +
                            • DDDMP_RELATIVE_ID Then(NodeId) is represented in relative form as + Then-info = Nodeid-Then(NodeId) +
                            • DDDMP_RELATIVE_1 No info on Then(NodeId) follows, because + Then(NodeId) = NodeId-1 +
                            • DDDMP_TERMINAL Then Node is a terminal, no info required (for BDDs) +
                            +
                          • Ecompl : 1 bit, if 1 means complemented edge +
                          • E : 2 bits, with codes and meanings as for the Then edge +
                          + var-info, Then-info, Else-info (if required) are represented as unsigned + integer values on a sufficient set of bytes (MSByte first). + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +NodeStoreRecurBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: store file */ + ) +{ + DdNode *T = NULL; + DdNode *E = NULL; + int idf = (-1); + int idT = (-1); + int idE = (-1); + int vf = (-1); + int vT = (-1); + int vE = (-1); + int retValue; + int nVars; + + nVars = ddMgr->size; + T = E = NULL; + idf = idT = idE = (-1); + +#ifdef DDDMP_DEBUG + assert(!Cudd_IsComplement(f)); + assert(f!=NULL); + assert(supportids!=NULL); +#endif + + /* If already visited, nothing to do. */ + if (DddmpVisitedBdd (f)) { + return (DDDMP_SUCCESS); + } + + /* Mark node as visited. */ + DddmpSetVisitedBdd (f); + + if (Cudd_IsConstant(f)) { + /* Check for special case: don't recur */ + idf = DddmpReadNodeIndexBdd (f); + } else { + +#ifdef DDDMP_DEBUG + /* BDDs! Only one constant supported */ + assert (!cuddIsConstant(f)); +#endif + + /* + * Recursive call for Then edge + */ + + T = cuddT(f); +#ifdef DDDMP_DEBUG + /* ROBDDs! No complemented Then edge */ + assert (!Cudd_IsComplement(T)); +#endif + /* recur */ + retValue = NodeStoreRecurBdd (ddMgr, T, mode, supportids, varnames, outids, + fp); + if (retValue != DDDMP_SUCCESS) { + return (retValue); + } + + /* + * Recursive call for Else edge + */ + + E = Cudd_Regular (cuddE (f)); + retValue = NodeStoreRecurBdd (ddMgr, E, mode, supportids, varnames, outids, + fp); + if (retValue != DDDMP_SUCCESS) { + return (retValue); + } + + /* + * Obtain nodeids and variable ids of f, T, E + */ + + idf = DddmpReadNodeIndexBdd (f); + vf = f->index; + + idT = DddmpReadNodeIndexBdd (T); + if (Cudd_IsConstant(T)) { + vT = nVars; + } else { + vT = T->index; + } + + idE = DddmpReadNodeIndexBdd (E); + if (Cudd_IsConstant(E)) { + vE = nVars; + } else { + vE = E->index; + } + } + + switch (mode) { + case DDDMP_MODE_TEXT: + retValue = NodeTextStoreBdd (ddMgr, f, mode, supportids, varnames, + outids, fp, idf, vf, idT, idE); + break; + case DDDMP_MODE_BINARY: + retValue = NodeBinaryStoreBdd (ddMgr, f, mode, supportids, varnames, + outids, fp, idf, vf, idT, idE, vT, vE, T, E); + break; + default: + return (DDDMP_FAILURE); + } + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Store One Single Node in Text Format.] + + Description [Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. + ] + + SideEffects [None] + + SeeAlso [NodeBinaryStoreBdd] + +******************************************************************************/ + +static int +NodeTextStoreBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: Store file */, + int idf /* IN: index of the current node */, + int vf /* IN: variable of the current node */, + int idT /* IN: index of the Then node */, + int idE /* IN: index of the Else node */ + ) +{ + int retValue = EOF; + + /* + * Check for Constant + */ + + if (Cudd_IsConstant(f)) { + + if (f == Cudd_ReadOne(ddMgr)) { + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T 1 0 0\n", idf); + } else { + retValue = fprintf (fp, "%d 1 0 0\n", idf); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + if (f == Cudd_ReadZero(ddMgr)) { + if ((varnames != NULL) || (outids != NULL)) { + retValue = fprintf (fp, "%d T 0 0 0\n", idf); + } else { + retValue = fprintf (fp, "%d 0 0 0\n", idf); + } + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * A constant node different from 1: an ADD constant + */ + + Dddmp_CheckAndReturn (((varnames!=NULL)||(outids!=NULL)), + "Error writing to file: ADD Type."); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * ... Not A Constant + */ + + if (Cudd_IsComplement (cuddE(f))) { + idE = -idE; + } + + if (varnames != NULL) { + retValue = fprintf (fp, "%d %s %d %d %d\n", + idf, varnames[vf], supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + if (outids != NULL) { + retValue = fprintf (fp, "%d %d %d %d %d\n", + idf, outids[vf], supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + retValue = fprintf (fp, "%d %d %d %d\n", + idf, supportids[vf], idT, idE); + + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } +} + +/**Function******************************************************************** + + Synopsis [Store One Single Node in Binary Format.] + + Description [Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. + Store every information as coded binary values.] + + SideEffects [None] + + SeeAlso [NodeTextStoreBdd] + +******************************************************************************/ + +static int +NodeBinaryStoreBdd ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: DD node to be stored */, + int mode /* IN: store mode */, + int *supportids /* IN: internal ids for variables */, + char **varnames /* IN: names of variables: to be stored with nodes */, + int *outids /* IN: output ids for variables */, + FILE *fp /* IN: store file */, + int idf /* IN: index of the node */, + int vf /* IN: variable of the node */, + int idT /* IN: index of the Then node */, + int idE /* IN: index of the Else node */, + int vT /* IN: variable of the Then node */, + int vE /* IN: variable of the Else node */, + DdNode *T /* IN: Then node */, + DdNode *E /* IN: Else node */ + ) +{ + int retValue, diff, var; + struct binary_dd_code code; + + /* + * Check for Constant + */ + + /* only integer ids used, varnames ignored */ + /* Terminal one is coded as DDDMP_TERMINAL, all other fields are 0 */ + if (Cudd_IsConstant(f)) { + code.Unused = 0; + code.V = DDDMP_TERMINAL; + code.T = 0; + code.E = 0; + code.Ecompl = 0; + retValue = DddmpWriteCode (fp,code); + if (retValue == EOF) { + return (DDDMP_FAILURE); + } else { + return (DDDMP_SUCCESS); + } + } + + /* + * Non terminal: output variable id + */ + + var = supportids[vf]; + diff = (supportids[vT] +#include "dddmpInt.h" + +/*-------------------------------1--------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMP_DEBUG_CNF 0 + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define GET_MAX(x,y) (x>y?x:y) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpCuddBddArrayStoreCnf(DdManager *ddMgr, DdNode **f, int rootN, Dddmp_DecompCnfStoreType mode, int noHeader, char **varNames, int *bddIds, int *bddAuxIds, int *cnfIds, int idInitial, int edgeInTh, int pathLengthTh, char *fname, FILE *fp, int *clauseNPtr, int *varNewNPtr); +static int StoreCnfNodeByNode(DdManager *ddMgr, DdNode **f, int rootN, int *bddIds, int *cnfIds, FILE *fp, int *clauseN, int *varMax, int *rootStartLine); +static int StoreCnfNodeByNodeRecur(DdManager *ddMgr, DdNode *f, int *bddIds, int *cnfIds, FILE *fp, int *clauseN, int *varMax); +static int StoreCnfOneNode(DdNode *f, int idf, int vf, int idT, int idE, FILE *fp, int *clauseN, int *varMax); +static int StoreCnfMaxtermByMaxterm(DdManager *ddMgr, DdNode **f, int rootN, int *bddIds, int *cnfIds, int idInitial, FILE *fp, int *varMax, int *clauseN, int *rootStartLine); +static int StoreCnfBest(DdManager *ddMgr, DdNode **f, int rootN, int *bddIds, int *cnfIds, int idInitial, FILE *fp, int *varMax, int *clauseN, int *rootStartLine); +static void StoreCnfMaxtermByMaxtermRecur(DdManager *ddMgr, DdNode *node, int *bddIds, int *cnfIds, FILE *fp, int *list, int *clauseN, int *varMax); +static int StoreCnfBestNotSharedRecur(DdManager *ddMgr, DdNode *node, int idf, int *bddIds, int *cnfIds, FILE *fp, int *list, int *clauseN, int *varMax); +static int StoreCnfBestSharedRecur(DdManager *ddMgr, DdNode *node, int *bddIds, int *cnfIds, FILE *fp, int *list, int *clauseN, int *varMax); +static int printCubeCnf(DdManager *ddMgr, DdNode *node, int *cnfIds, FILE *fp, int *list, int *varMax); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a CNF format. + ] + + Description [Dumps the argument BDD to file. + This task is performed by calling the function + Dddmp_cuddBddArrayStoreCnf. + ] + + SideEffects [Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. + ] + + SeeAlso [Dddmp_cuddBddArrayStoreCnf] + +******************************************************************************/ + +int +Dddmp_cuddBddStoreCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: BDD root to be stored */, + Dddmp_DecompCnfStoreType mode /* IN: format selection */, + int noHeader /* IN: do not store header iff 1 */, + char **varNames /* IN: array of variable names (or NULL) */, + int *bddIds /* IN: array of var ids */, + int *bddAuxIds /* IN: array of BDD node Auxiliary Ids */, + int *cnfIds /* IN: array of CNF var ids */, + int idInitial /* IN: starting id for cutting variables */, + int edgeInTh /* IN: Max # Incoming Edges */, + int pathLengthTh /* IN: Max Path Length */, + char *fname /* IN: file name */, + FILE *fp /* IN: pointer to the store file */, + int *clauseNPtr /* OUT: number of clause stored */, + int *varNewNPtr /* OUT: number of new variable created */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStoreCnf (ddMgr, tmpArray, 1, mode, + noHeader, varNames, bddIds, bddAuxIds, cnfIds, idInitial, edgeInTh, + pathLengthTh, fname, fp, clauseNPtr, varNewNPtr); + + Dddmp_CheckAndReturn (retValue==DDDMP_FAILURE, "Failure."); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument array of BDDs + in CNF format. + ] + + Description [Dumps the argument array of BDDs to file.] + + SideEffects [Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + Three methods are allowed: + * NodeByNode method: Insert a cut-point for each BDD node (but the + terminal nodes) + * MaxtermByMaxterm method: Insert no cut-points, i.e. the off-set of + trhe function is stored + * Best method: Tradeoff between the previous two methods. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. + The stored file can contain a file header or not depending on the + noHeader parameter (IFF 0, usual setting, the header is usually stored. + This option can be useful in storing multiple BDDs, as separate BDDs, + on the same file leaving the opening of the file to the caller. + ] + + SeeAlso [] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStoreCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDD roots to be stored */, + int rootN /* IN: # output BDD roots to be stored */, + Dddmp_DecompCnfStoreType mode /* IN: format selection */, + int noHeader /* IN: do not store header iff 1 */, + char **varNames /* IN: array of variable names (or NULL) */, + int *bddIds /* IN: array of converted var IDs */, + int *bddAuxIds /* IN: array of BDD node Auxiliary Ids */, + int *cnfIds /* IN: array of converted var IDs */, + int idInitial /* IN: starting id for cutting variables */, + int edgeInTh /* IN: Max # Incoming Edges */, + int pathLengthTh /* IN: Max Path Length */, + char *fname /* IN: file name */, + FILE *fp /* IN: pointer to the store file */, + int *clauseNPtr /* OUT: number of clause stored */, + int *varNewNPtr /* OUT: number of new variable created */ + ) +{ + int retValue2; + +#if 0 +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValue1; + + retValue1 = Cudd_DebugCheck (ddMgr); + Dddmp_CheckAndReturn (retValue1==1, + "Inconsistency Found During CNF Store."); + Dddmp_CheckAndReturn (retValue1==CUDD_OUT_OF_MEM, + "Out of Memory During CNF Store."); +#endif +#endif +#endif + + retValue2 = DddmpCuddBddArrayStoreCnf (ddMgr, f, rootN, mode, noHeader, + varNames, bddIds, bddAuxIds, cnfIds, idInitial, edgeInTh, pathLengthTh, + fname, fp, clauseNPtr, varNewNPtr); + +#if 0 +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValue1 = Cudd_DebugCheck (ddMgr); + Dddmp_CheckAndReturn (retValue1==1, + "Inconsistency Found During CNF Store."); + Dddmp_CheckAndReturn (retValue1==CUDD_OUT_OF_MEM, + "Out of Memory During CNF Store."); +#endif +#endif +#endif + + return (retValue2); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument Array of + BDDs in the CNF standard format. + ] + + Description [Dumps the argument array of BDDs/ADDs to file in CNF format. + The following arrays: varNames, bddIds, bddAuxIds, and cnfIds + fix the correspondence among variable names, BDD ids, BDD + auxiliary ids and the ids used to store the CNF problem. + All these arrays are automatically created iff NULL. + Auxiliary variable, iff necessary, are created starting from value + idInitial. + Iff idInitial is <= 0 its value is selected as the number of internal + CUDD variable + 2. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. + ] + + SideEffects [Nodes are temporarily removed from the unique hash table. + They are re-linked after the store operation in a modified + order. + ] + + SeeAlso [Dddmp_cuddBddStore] + +******************************************************************************/ + +static int +DddmpCuddBddArrayStoreCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDD roots to be stored */, + int rootN /* IN: # of output BDD roots to be stored */, + Dddmp_DecompCnfStoreType mode /* IN: format selection */, + int noHeader /* IN: do not store header iff 1 */, + char **varNames /* IN: array of variable names (or NULL) */, + int *bddIds /* IN: array of BDD node Ids (or NULL) */, + int *bddAuxIds /* IN: array of BDD Aux Ids (or NULL) */, + int *cnfIds /* IN: array of CNF ids (or NULL) */, + int idInitial /* IN: starting id for cutting variables */, + int edgeInTh /* IN: Max # Incoming Edges */, + int pathLengthTh /* IN: Max Path Length */, + char *fname /* IN: file name */, + FILE *fp /* IN: pointer to the store file */, + int *clauseNPtr /* OUT: number of clause stored */, + int *varNewNPtr /* OUT: number of new variable created */ + ) +{ + DdNode *support = NULL; + DdNode *scan = NULL; + int *bddIdsInSupport = NULL; + int *permIdsInSupport = NULL; + int *rootStartLine = NULL; + int nVar, nVarInSupport, retValue, i, j, fileToClose; + int varMax, clauseN, flagVar, intStringLength; + int bddIdsToFree = 0; + int bddAuxIdsToFree = 0; + int cnfIdsToFree = 0; + int varNamesToFree = 0; + char intString[DDDMP_MAXSTRLEN]; + char tmpString[DDDMP_MAXSTRLEN]; + fpos_t posFile1, posFile2; + + /*---------------------------- Set Initial Values -------------------------*/ + + support = scan = NULL; + bddIdsInSupport = permIdsInSupport = rootStartLine = NULL; + nVar = ddMgr->size; + fileToClose = 0; + sprintf (intString, "%d", INT_MAX); + intStringLength = strlen (intString); + + /*---------- Check if File needs to be opened in the proper mode ----------*/ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + /*--------- Generate Bdd LOCAL IDs and Perm IDs and count them ------------*/ + + /* BDD Ids */ + bddIdsInSupport = DDDMP_ALLOC (int, nVar); + Dddmp_CheckAndGotoLabel (bddIdsInSupport==NULL, "Error allocating memory.", + failure); + /* BDD PermIds */ + permIdsInSupport = DDDMP_ALLOC (int, nVar); + Dddmp_CheckAndGotoLabel (permIdsInSupport==NULL, "Error allocating memory.", + failure); + /* Support Size (Number of BDD Ids-PermIds */ + nVarInSupport = 0; + + for (i=0; iindex] = scan->index; + permIdsInSupport[scan->index] = ddMgr->perm[scan->index]; + scan = cuddT (scan); + } + Cudd_RecursiveDeref (ddMgr, support); + } + /* so that we do not try to free it in case of failure */ + support = NULL; + + /*---------------------------- Start HEADER -------------------------------*/ + + if (noHeader==0) { + + retValue = fprintf (fp, + "c # BDD stored by the DDDMP tool in CNF format\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing on file.", + failure); + fprintf (fp, "c #\n"); + } + + /*-------------------- Generate Bdd IDs IFF necessary ---------------------*/ + + if (bddIds == NULL) { + if (noHeader==0) { + fprintf (fp, "c # Warning: BDD IDs missing ... evaluating them.\n"); + fprintf (fp, "c # \n"); + fflush (fp); + } + + bddIdsToFree = 1; + bddIds = DDDMP_ALLOC (int, nVar); + Dddmp_CheckAndGotoLabel (bddIds==NULL, "Error allocating memory.", + failure); + + /* Get BDD-IDs Directly from Cudd Manager */ + for (i=0; i= 0) { + fprintf (fp, " %s", varNames[i]); + } + } + fprintf (fp, "\n"); + } + + /* Ordered Variable Names */ + if (varNames != NULL) { + fprintf (fp, "c .orderedvarnames"); + for (i=0; i= 0) { + fprintf (fp, " %d", bddIdsInSupport[i]); + } + } + fprintf (fp, "\n"); + + /* BDD Variable Permutation Ids */ + fprintf (fp, "c .permids "); + for (i=0; i= 0) { + fprintf (fp, " %d", permIdsInSupport[i]); + } + } + fprintf (fp, "\n"); + + /* BDD Variable Auxiliary Ids */ + fprintf (fp, "c .auxids "); + for (i=0; i= 0) { + fprintf (fp, " %d", bddAuxIds[i]); + } + } + fprintf (fp, "\n"); + + /* CNF Ids */ + fprintf (fp, "c .cnfids "); + for (i=0; i= 0) { + fprintf (fp, " %d", cnfIds[i]); + } + } + fprintf (fp, "\n"); + + /* Number of Roots */ + fprintf (fp, "c .nroots %d", rootN); + fprintf (fp, "\n"); + + /* Root Starting Line */ + fgetpos (fp, &posFile1); + fprintf (fp, "c .rootids"); + for (i=0; i \n", i); +#endif + if (Cudd_IsComplement (f[i])) { + retValue = fprintf (fp, "-%d 0\n", idf); + } else { + retValue = fprintf (fp, "%d 0\n", idf); + } + *varMax = GET_MAX (*varMax, idf); + *clauseN = *clauseN + 1; + + if (retValue == EOF) { + (void) fprintf (stderr, + "DdStoreCnf: Error in recursive node store\n"); + fflush (stderr); + } + } + } + } + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Dddmp_bddStore.] + + Description [Performs the recursive step of Dddmp_bddStore. + Traverse the BDD and store a CNF formula for each "terminal" node. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +StoreCnfNodeByNodeRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *f /* IN: BDD node to be stored */, + int *bddIds /* IN: BDD ids for variables */, + int *cnfIds /* IN: CNF ids for variables */, + FILE *fp /* IN: store file */, + int *clauseN /* OUT: number of clauses written in the CNF file */, + int *varMax /* OUT: maximum value of id written in the CNF file */ + ) +{ + DdNode *T, *E; + int idf, idT, idE, vf; + int retValue; + +#ifdef DDDMP_DEBUG + assert(!Cudd_IsComplement(f)); + assert(f!=NULL); +#endif + + /* If constant, nothing to do. */ + if (Cudd_IsConstant(f)) { + return (1); + } + + /* If already visited, nothing to do. */ + if (DddmpVisitedCnf (f)) { + return (1); + } + + /* Mark node as visited. */ + DddmpSetVisitedCnf (f); + + /*------------------ Non Terminal Node -------------------------------*/ + +#ifdef DDDMP_DEBUG + /* BDDs! Only one constant supported */ + assert (!cuddIsConstant(f)); +#endif + + /* + * Recursive call for Then edge + */ + + T = cuddT (f); +#ifdef DDDMP_DEBUG + /* ROBDDs! No complemented Then edge */ + assert (!Cudd_IsComplement(T)); +#endif + /* recur */ + retValue = StoreCnfNodeByNodeRecur (ddMgr, T, bddIds, cnfIds, fp, + clauseN, varMax); + if (retValue != 1) { + return(retValue); + } + + /* + * Recursive call for Else edge + */ + + E = Cudd_Regular (cuddE (f)); + retValue = StoreCnfNodeByNodeRecur (ddMgr, E, bddIds, cnfIds, fp, + clauseN, varMax); + if (retValue != 1) { + return (retValue); + } + + /* + * Obtain nodeids and variable ids of f, T, E + */ + + idf = DddmpReadNodeIndexCnf (f); + vf = f->index; + + if (bddIds[vf] != vf) { + (void) fprintf (stderr, "DdStoreCnf: Error writing to file\n"); + fflush (stderr); + return (0); + } + + idT = DddmpReadNodeIndexCnf (T); + + idE = DddmpReadNodeIndexCnf (E); + if (Cudd_IsComplement (cuddE (f))) { + idE = -idE; + } + + retValue = StoreCnfOneNode (f, idf, cnfIds[vf], idT, idE, fp, + clauseN, varMax); + + if (retValue == EOF) { + return (0); + } else { + return (1); + } +} + +/**Function******************************************************************** + + Synopsis [Store One Single BDD Node.] + + Description [Store One Single BDD Node translating it as a multiplexer.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +StoreCnfOneNode ( + DdNode *f /* IN: node to be stored */, + int idf /* IN: node CNF Index */, + int vf /* IN: node BDD Index */, + int idT /* IN: Then CNF Index with sign = inverted edge */, + int idE /* IN: Else CNF Index with sign = inverted edge */, + FILE *fp /* IN: store file */, + int *clauseN /* OUT: number of clauses */, + int *varMax /* OUT: maximun Index of variable stored */ + ) +{ + int retValue = 0; + int idfAbs, idTAbs, idEAbs; + + idfAbs = abs (idf); + idTAbs = abs (idT); + idEAbs = abs (idE); + + /*----------------------------- Check for Constant ------------------------*/ + + assert(!Cudd_IsConstant(f)); + + /*------------------------- Check for terminal nodes ----------------------*/ + + if ((idTAbs==1) && (idEAbs==1)) { + return (1); + } + + /*------------------------------ Internal Node ----------------------------*/ + +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "id=%d var=%d idT=%d idE=%d\n", + idf, vf, idT, idE); +#endif + + /* + * Then to terminal + */ + + if ((idTAbs==1) && (idEAbs!=1)) { +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "CASE 1 -->\n"); +#endif + retValue = fprintf (fp, "%d %d 0\n", + idf, -vf); + retValue = fprintf (fp, "%d %d 0\n", + idf, -idE); + retValue = fprintf (fp, "%d %d %d 0\n", + -idf, vf, idE); + *clauseN = *clauseN + 3; + + *varMax = GET_MAX (*varMax, idfAbs); + *varMax = GET_MAX (*varMax, vf); + *varMax = GET_MAX (*varMax, idEAbs); + } + + /* + * Else to terminal + */ + + if ((idTAbs!=1) && (idEAbs==1)) { + if (idE == 1) { +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "CASE 2 -->\n"); +#endif + retValue = fprintf (fp, "%d %d 0\n", + idf, vf); + retValue = fprintf (fp, "%d %d 0\n", + idf, -idT); + retValue = fprintf (fp, "%d %d %d 0\n", + -idf, -vf, idT); + } else { +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "CASE 3 -->\n"); +#endif + retValue = fprintf (fp, "%d %d 0\n", + -idf, vf); + retValue = fprintf (fp, "%d %d 0\n", + -idf, idT); + retValue = fprintf (fp, "%d %d %d 0\n", + idf, -vf, -idT); + } + + *varMax = GET_MAX (*varMax, idfAbs); + *varMax = GET_MAX (*varMax, vf); + *varMax = GET_MAX (*varMax, idTAbs); + + *clauseN = *clauseN + 3; + } + + /* + * Nor Then or Else to terminal + */ + + if ((idTAbs!=1) && (idEAbs!=1)) { +#if DDDMP_DEBUG_CNF + retValue = fprintf (fp, "CASE 4 -->\n"); +#endif + retValue = fprintf (fp, "%d %d %d 0\n", + idf, vf, -idE); + retValue = fprintf (fp, "%d %d %d 0\n", + -idf, vf, idE); + retValue = fprintf (fp, "%d %d %d 0\n", + idf, -vf, -idT); + retValue = fprintf (fp, "%d %d %d 0\n", + -idf, -vf, idT); + + *varMax = GET_MAX (*varMax, idfAbs); + *varMax = GET_MAX (*varMax, vf); + *varMax = GET_MAX (*varMax, idTAbs); + *varMax = GET_MAX (*varMax, idEAbs); + + *clauseN = *clauseN + 4; + } + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Prints a disjoint sum of products.] + + Description [Prints a disjoint sum of product cover for the function + rooted at node. Each product corresponds to a path from node a + leaf node different from the logical zero, and different from + the background value. Uses the standard output. Returns 1 if + successful, 0 otherwise. + ] + + SideEffects [None] + + SeeAlso [StoreCnfBest] + +******************************************************************************/ + +static int +StoreCnfMaxtermByMaxterm ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs to store */, + int rootN /* IN: number of BDDs in the array */, + int *bddIds /* IN: BDD Identifiers */, + int *cnfIds /* IN: corresponding CNF Identifiers */, + int idInitial /* IN: initial value for numbering new CNF variables */, + FILE *fp /* IN: file pointer */, + int *varMax /* OUT: maximum identifier of the variables created */, + int *clauseN /* OUT: number of stored clauses */, + int *rootStartLine /* OUT: line where root starts */ + ) +{ + int i, j, *list; + + list = DDDMP_ALLOC (int, ddMgr->size); + if (list == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + return (DDDMP_FAILURE); + } + + for (i=0; isize; j++) { + list[j] = 2; + } + + /* + * Set Starting Line for this Root + */ + + rootStartLine[i] = *clauseN + 1; + + StoreCnfMaxtermByMaxtermRecur (ddMgr, f[i], bddIds, cnfIds, fp, + list, clauseN, varMax); + } + } + } + + FREE (list); + + return (1); +} + +/**Function******************************************************************** + + Synopsis [Prints a disjoint sum of products with intermediate + cutting points.] + + Description [Prints a disjoint sum of product cover for the function + rooted at node intorducing cutting points whenever necessary. + Each product corresponds to a path from node a leaf + node different from the logical zero, and different from the + background value. Uses the standard output. Returns 1 if + successful, 0 otherwise. + ] + + SideEffects [None] + + SeeAlso [StoreCnfMaxtermByMaxterm] + +******************************************************************************/ + +static int +StoreCnfBest ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode **f /* IN: array of BDDs to store */, + int rootN /* IN: number of BDD in the array */, + int *bddIds /* IN: BDD identifiers */, + int *cnfIds /* IN: corresponding CNF identifiers */, + int idInitial /* IN: initial value for numbering new CNF variables */, + FILE *fp /* IN: file pointer */, + int *varMax /* OUT: maximum identifier of the variables created */, + int *clauseN /* OUT: number of stored clauses */, + int *rootStartLine /* OUT: line where root starts */ + ) +{ + int i, j, *list; + + list = DDDMP_ALLOC (int, ddMgr->size); + if (list == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + return (DDDMP_FAILURE); + } + + for (i=0; isize; j++) { + list[j] = 2; + } + + /* + * Set Starting Line for this Root + */ + + rootStartLine[i] = *clauseN + 1; + +#if DDDMP_DEBUG_CNF + fprintf (fp, "root NOT shared BDDs %d --> \n", i); +#endif + StoreCnfBestNotSharedRecur (ddMgr, f[i], 0, bddIds, cnfIds, fp, list, + clauseN, varMax); + +#if DDDMP_DEBUG_CNF + fprintf (fp, "root SHARED BDDs %d --> \n", i); +#endif + StoreCnfBestSharedRecur (ddMgr, Cudd_Regular (f[i]), bddIds, cnfIds, + fp, list, clauseN, varMax); + } + } + } + +#if DDDMP_DEBUG_CNF + fprintf (stdout, "###---> BDDs After the Storing Process:\n"); + DddmpPrintBddAndNext (ddMgr, f, rootN); +#endif + + FREE (list); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Print Maxterm.] + + Description [Performs the recursive step of Print Maxterm. + Traverse a BDD a print out a cube in CNF format each time a terminal + node is reached. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static void +StoreCnfMaxtermByMaxtermRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *node /* IN: BDD to store */, + int *bddIds /* IN: BDD identifiers */, + int *cnfIds /* IN: corresponding CNF identifiers */, + FILE *fp /* IN: file pointer */, + int *list /* IN: temporary array to store cubes */, + int *clauseN /* OUT: number of stored clauses */, + int *varMax /* OUT: maximum identifier of the variables created */ + ) +{ + DdNode *N, *Nv, *Nnv; + int retValue, index; + + N = Cudd_Regular (node); + + /* + * Terminal case: Print one cube based on the current recursion + */ + + if (cuddIsConstant (N)) { + retValue = printCubeCnf (ddMgr, node, cnfIds, fp, list, varMax); + if (retValue == DDDMP_SUCCESS) { + fprintf (fp, "0\n"); + *clauseN = *clauseN + 1; + } + return; + } + + /* + * NON Terminal case: Recur + */ + + Nv = cuddT (N); + Nnv = cuddE (N); + if (Cudd_IsComplement (node)) { + Nv = Cudd_Not (Nv); + Nnv = Cudd_Not (Nnv); + } + index = N->index; + + /* + * StQ 06.05.2003 + * Perform the optimization: + * f = (a + b)' = (a') ^ (a + b') = (a') ^ (b') + * i.e., if the THEN node is the constant ZERO then that variable + * can be forgotten (list[index] = 2) for subsequent ELSE cubes + */ + if (cuddIsConstant (Cudd_Regular (Nv)) && Nv != ddMgr->one) { + list[index] = 2; + } else { + list[index] = 0; + } + StoreCnfMaxtermByMaxtermRecur (ddMgr, Nnv, bddIds, cnfIds, fp, list, + clauseN, varMax); + + /* + * StQ 06.05.2003 + * Perform the optimization: + * f = a ^ b = (a) ^ (a' + b) = (a) ^ (b) + * i.e., if the ELSE node is the constant ZERO then that variable + * can be forgotten (list[index] = 2) for subsequent THEN cubes + */ + if (cuddIsConstant (Cudd_Regular (Nnv)) && Nnv != ddMgr->one) { + list[index] = 2; + } else { + list[index] = 1; + } + StoreCnfMaxtermByMaxtermRecur (ddMgr, Nv, bddIds, cnfIds, fp, list, + clauseN, varMax); + list[index] = 2; + + return; +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Print Best on Not Shared + sub-BDDs.] + + Description [Performs the recursive step of Print Best on Not Shared + sub-BDDs, i.e., print out information for the nodes belonging to + BDDs not shared (whose root has just one incoming edge). + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +StoreCnfBestNotSharedRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *node /* IN: BDD to store */, + int idf /* IN: Id to store */, + int *bddIds /* IN: BDD identifiers */, + int *cnfIds /* IN: corresponding CNF identifiers */, + FILE *fp /* IN: file pointer */, + int *list /* IN: temporary array to store cubes */, + int *clauseN /* OUT: number of stored clauses */, + int *varMax /* OUT: maximum identifier of the variables created */ + ) +{ + DdNode *N, *Nv, *Nnv; + int index, retValue; + DdNode *one; + + one = ddMgr->one; + + N = Cudd_Regular (node); + + /* + * Terminal case or Already Visited: + * Print one cube based on the current recursion + */ + + if (cuddIsConstant (N)) { + retValue = printCubeCnf (ddMgr, node, cnfIds, fp, list, varMax); + if (retValue == DDDMP_SUCCESS) { + if (idf != 0) { + fprintf (fp, "%d ", idf); + } + fprintf (fp, "0\n"); + *varMax = GET_MAX (*varMax, abs(idf)); + *clauseN = *clauseN + 1; + } + return (DDDMP_SUCCESS); + } + + /* + * Shared Sub-Tree: Print Cube + */ + + index = DddmpReadNodeIndexCnf (N); + if (index > 0) { + if (idf != 0) { + fprintf (fp, "%d ", idf); + } + if (Cudd_IsComplement (node)) { + retValue = fprintf (fp, "-%d ", index); + } else { + retValue = fprintf (fp, "%d ", index); + } + retValue = printCubeCnf (ddMgr, node, cnfIds, fp, list, varMax); + fprintf (fp, "0\n"); + *varMax = GET_MAX (*varMax, abs(index)); + *clauseN = *clauseN + 1; + return (DDDMP_SUCCESS); + } + + /* + * NON Terminal case: Recur + */ + + Nv = cuddT (N); + Nnv = cuddE (N); + if (Cudd_IsComplement (node)) { + Nv = Cudd_Not (Nv); + Nnv = Cudd_Not (Nnv); + } + index = N->index; + + /* + * StQ 06.05.2003 + * Perform the optimization: + * f = (a + b)' = (a') ^ (a + b') = (a') ^ (b') + * i.e., if the THEN node is the constant ZERO then that variable + * can be forgotten (list[index] = 2) for subsequent ELSE cubes + */ + if (cuddIsConstant (Cudd_Regular (Nv)) && Nv != ddMgr->one) { + list[index] = 2; + } else { + list[index] = 0; + } + StoreCnfBestNotSharedRecur (ddMgr, Nnv, idf, bddIds, cnfIds, fp, list, + clauseN, varMax); + + /* + * StQ 06.05.2003 + * Perform the optimization: + * f = a ^ b = (a) ^ (a' + b) = (a) ^ (b) + * i.e., if the ELSE node is the constant ZERO then that variable + * can be forgotten (list[index] = 2) for subsequent THEN cubes + */ + if (cuddIsConstant (Cudd_Regular (Nnv)) && Nnv != ddMgr->one) { + list[index] = 2; + } else { + list[index] = 1; + } + StoreCnfBestNotSharedRecur (ddMgr, Nv, idf, bddIds, cnfIds, fp, list, + clauseN, varMax); + list[index] = 2; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Print Best on Shared + sub-BDDs. + ] + + Description [Performs the recursive step of Print Best on Not Shared + sub-BDDs, i.e., print out information for the nodes belonging to + BDDs not shared (whose root has just one incoming edge). + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +StoreCnfBestSharedRecur ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *node /* IN: BDD to store */, + int *bddIds /* IN: BDD identifiers */, + int *cnfIds /* IN: corresponding CNF identifiers */, + FILE *fp /* IN: file pointer */, + int *list /* IN: temporary array to store cubes */, + int *clauseN /* OUT: number of stored clauses */, + int *varMax /* OUT: maximum identifier of the variables created */ + ) +{ + DdNode *nodeThen, *nodeElse; + int i, idf, index; + DdNode *one; + + one = ddMgr->one; + + Dddmp_Assert (node==Cudd_Regular(node), + "Inverted Edge during Shared Printing."); + + /* If constant, nothing to do. */ + if (cuddIsConstant (node)) { + return (DDDMP_SUCCESS); + } + + /* If already visited, nothing to do. */ + if (DddmpVisitedCnf (node)) { + return (DDDMP_SUCCESS); + } + + /* + * Shared Sub-Tree: Print Cube + */ + + idf = DddmpReadNodeIndexCnf (node); + if (idf > 0) { + /* Cheat the Recur Function about the Index of the Current Node */ + DddmpWriteNodeIndexCnf (node, 0); + +#if DDDMP_DEBUG_CNF + fprintf (fp, "Else of XNOR\n"); +#endif + for (i=0; isize; i++) { + list[i] = 2; + } + StoreCnfBestNotSharedRecur (ddMgr, Cudd_Not (node), idf, bddIds, cnfIds, + fp, list, clauseN, varMax); + +#if DDDMP_DEBUG_CNF + fprintf (fp, "Then of XNOR\n"); +#endif + for (i=0; isize; i++) { + list[i] = 2; + } + StoreCnfBestNotSharedRecur (ddMgr, node, -idf, bddIds, cnfIds, + fp, list, clauseN, varMax); + + /* Set Back Index of Current Node */ + DddmpWriteNodeIndexCnf (node, idf); + } + + /* Mark node as visited. */ + DddmpSetVisitedCnf (node); + + /* + * Recur + */ + + nodeThen = cuddT (node); + nodeElse = cuddE (node); + index = node->index; + + StoreCnfBestSharedRecur (ddMgr, Cudd_Regular (nodeThen), bddIds, cnfIds, + fp, list, clauseN, varMax); + StoreCnfBestSharedRecur (ddMgr, Cudd_Regular (nodeElse), bddIds, cnfIds, + fp, list, clauseN, varMax); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Print One Cube in CNF Format.] + + Description [Print One Cube in CNF Format. + Return DDDMP_SUCCESS if something is printed out, DDDMP_FAILURE + is nothing is printed out. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +printCubeCnf ( + DdManager *ddMgr /* IN: DD Manager */, + DdNode *node /* IN: BDD to store */, + int *cnfIds /* IN: CNF identifiers */, + FILE *fp /* IN: file pointer */, + int *list /* IN: temporary array to store cubes */, + int *varMax /* OUT: maximum identifier of the variables created */ + ) +{ + int i, retValue; + DdNode *one; + + retValue = DDDMP_FAILURE; + one = ddMgr->one; + + if (node != one) { + for (i=0; isize; i++) { + if (list[i] == 0) { + retValue = DDDMP_SUCCESS; + (void) fprintf (fp, "%d ", cnfIds[i]); + *varMax = GET_MAX(*varMax, cnfIds[i]); + } else { + if (list[i] == 1) { + retValue = DDDMP_SUCCESS; + (void) fprintf (fp, "-%d ", cnfIds[i]); + *varMax = GET_MAX(*varMax, cnfIds[i]); + } + } + } + } + + return (retValue); +} + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpStoreMisc.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpStoreMisc.c new file mode 100644 index 000000000..2dc18f046 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpStoreMisc.c @@ -0,0 +1,1641 @@ +/**CFile********************************************************************** + + FileName [dddmpStoreMisc.c] + + PackageName [dddmp] + + Synopsis [Functions to write out bdds to file in prefixed + and in Blif form.] + + Description [Functions to write out bdds to file. + BDDs are represended on file in text format. + Each node is stored as a multiplexer in a prefix notation format for + the prefix notation file or in PLA format for the blif file. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int DddmpCuddDdArrayStorePrefix(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp); +static int DddmpCuddDdArrayStorePrefixBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp); +static int DddmpCuddDdArrayStorePrefixStep(DdManager * ddMgr, DdNode * f, FILE * fp, st_table * visited, char ** names); +static int DddmpCuddDdArrayStoreBlif(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp); +static int DddmpCuddDdArrayStoreBlifBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp); +static int DddmpCuddDdArrayStoreBlifStep(DdManager *ddMgr, DdNode *f, FILE *fp, st_table *visited, char **names); +static int DddmpCuddDdArrayStoreSmv(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp); +static int DddmpCuddDdArrayStoreSmvBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp); +static int DddmpCuddDdArrayStoreSmvStep(DdManager * ddMgr, DdNode * f, FILE * fp, st_table * visited, char ** names); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a prefix notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddStore] + +******************************************************************************/ + +int +Dddmp_cuddBddStorePrefix ( + DdManager *ddMgr /* IN: DD Manager */, + int nRoots /* IN: Number of BDD roots */, + DdNode *f /* IN: BDD root to be stored */, + char **inputNames /* IN: Array of variable names */, + char **outputNames /* IN: Array of root names */, + char *modelName /* IN: Model Name */, + char *fileName /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStorePrefix (ddMgr, 1, tmpArray, + inputNames, outputNames, modelName, fileName, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a prefix notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddArrayStore] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStorePrefix ( + DdManager *ddMgr /* IN: DD Manager */, + int nroots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of BDD roots to be stored */, + char **inputNames /* IN: array of variable names (or NULL) */, + char **outputNames /* IN: array of root names (or NULL) */, + char *modelName /* IN: Model Name */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + int fileToClose = 0; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + retValue = DddmpCuddDdArrayStorePrefix (ddMgr, nroots, f, + inputNames, outputNames, modelName, fp); + + if (fileToClose) { + fclose (fp); + } + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); + + failure: + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a Blif/Exlif notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBlif. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddStorePrefix] + +******************************************************************************/ + +int +Dddmp_cuddBddStoreBlif ( + DdManager *ddMgr /* IN: DD Manager */, + int nRoots /* IN: Number of BDD roots */, + DdNode *f /* IN: BDD root to be stored */, + char **inputNames /* IN: Array of variable names */, + char **outputNames /* IN: Array of root names */, + char *modelName /* IN: Model Name */, + char *fileName /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStoreBlif (ddMgr, 1, tmpArray, + inputNames, outputNames, modelName, fileName, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a Blif/Exlif notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBLif. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddArrayStorePrefix] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStoreBlif ( + DdManager *ddMgr /* IN: DD Manager */, + int nroots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of BDD roots to be stored */, + char **inputNames /* IN: array of variable names (or NULL) */, + char **outputNames /* IN: array of root names (or NULL) */, + char *modelName /* IN: Model Name */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + int fileToClose = 0; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + retValue = DddmpCuddDdArrayStoreBlif (ddMgr, nroots, f, + inputNames, outputNames, modelName, fp); + + if (fileToClose) { + fclose (fp); + } + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); + + failure: + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a prefix notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddStore] + +******************************************************************************/ + +int +Dddmp_cuddBddStoreSmv ( + DdManager *ddMgr /* IN: DD Manager */, + int nRoots /* IN: Number of BDD roots */, + DdNode *f /* IN: BDD root to be stored */, + char **inputNames /* IN: Array of variable names */, + char **outputNames /* IN: Array of root names */, + char *modelName /* IN: Model Name */, + char *fileName /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + DdNode *tmpArray[1]; + + tmpArray[0] = f; + + retValue = Dddmp_cuddBddArrayStoreSmv (ddMgr, 1, tmpArray, + inputNames, outputNames, modelName, fileName, fp); + + return (retValue); +} + +/**Function******************************************************************** + + Synopsis [Writes a dump file representing the argument BDD in + a prefix notation.] + + Description [Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. + ] + + SideEffects [] + + SeeAlso [Dddmp_cuddBddArrayStore] + +******************************************************************************/ + +int +Dddmp_cuddBddArrayStoreSmv ( + DdManager *ddMgr /* IN: DD Manager */, + int nroots /* IN: number of output BDD roots to be stored */, + DdNode **f /* IN: array of BDD roots to be stored */, + char **inputNames /* IN: array of variable names (or NULL) */, + char **outputNames /* IN: array of root names (or NULL) */, + char *modelName /* IN: Model Name */, + char *fname /* IN: File name */, + FILE *fp /* IN: File pointer to the store file */ + ) +{ + int retValue; + int fileToClose = 0; + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + int retValueBis; + + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + /* + * Check if File needs to be opened in the proper mode. + */ + + if (fp == NULL) { + fp = fopen (fname, "w"); + Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", + failure); + fileToClose = 1; + } + + retValue = DddmpCuddDdArrayStoreSmv (ddMgr, nroots, f, + inputNames, outputNames, modelName, fp); + + if (fileToClose) { + fclose (fp); + } + +#ifdef DDDMP_DEBUG +#ifndef __alpha__ + retValueBis = Cudd_DebugCheck (ddMgr); + if (retValueBis == 1) { + fprintf (stderr, "Inconsistency Found During BDD Store.\n"); + fflush (stderr); + } else { + if (retValueBis == CUDD_OUT_OF_MEM) { + fprintf (stderr, "Out of Memory During BDD Store.\n"); + fflush (stderr); + } + } +#endif +#endif + + return (retValue); + + failure: + return (DDDMP_FAILURE); +} + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Internal function to writes a dump file representing the + argument BDD in a prefix notation.] + + Description [One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + Comments (COMMENT) are added at the beginning of the description to + describe inputs and outputs of the design. + A buffer (BUF) is add on the output to cope with complemented functions. + ] + + SideEffects [None] + + SeeAlso [DddmpCuddDdArrayStoreBlif] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStorePrefix ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + char *modelName /* IN: Model name (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nVars = ddMgr->size; + int retValue; + int i; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int, nVars); + if (sorted == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure); + } + for (i = 0; i < nVars; i++) { + sorted[i] = 0; + } + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(ddMgr,f,n); + Dddmp_CheckAndGotoLabel (support==NULL, + "Error in function Cudd_VectorSupport.", failure); + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(ddMgr,support); + /* so that we do not try to free it in case of failure */ + support = NULL; + + /* Write the header (.model .inputs .outputs). */ + if (modelName == NULL) { + retValue = fprintf (fp, "(COMMENT - model name: Unknown )\n"); + } else { + retValue = fprintf (fp, "(COMMENT - model name: %s )\n", modelName); + } + if (retValue == EOF) { + return(0); + } + + retValue = fprintf(fp, "(COMMENT - input names: "); + if (retValue == EOF) { + return(0); + } + /* Write the input list by scanning the support array. */ + for (i = 0; i < nVars; i++) { + if (sorted[i]) { + if (inputNames == NULL) { + retValue = fprintf(fp," inNode%d", i); + } else { + retValue = fprintf(fp," %s", inputNames[i]); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + } + FREE(sorted); + sorted = NULL; + retValue = fprintf(fp, " )\n"); + if (retValue == EOF) { + return(0); + } + + /* Write the .output line. */ + retValue = fprintf(fp,"(COMMENT - output names: "); + if (retValue == EOF) { + return(0); + } + for (i = 0; i < n; i++) { + if (outputNames == NULL) { + retValue = fprintf (fp," outNode%d", i); + } else { + retValue = fprintf (fp," %s", outputNames[i]); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + retValue = fprintf(fp, " )\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + + retValue = DddmpCuddDdArrayStorePrefixBody (ddMgr, n, f, inputNames, + outputNames, fp); + Dddmp_CheckAndGotoLabel (retValue==0, + "Error in function DddmpCuddDdArrayStorePrefixBody.", failure); + + return(1); + +failure: + if (sorted != NULL) { + FREE(sorted); + } + if (support != NULL) { + Cudd_RecursiveDeref(ddMgr,support); + } + return(0); +} + +/**Function******************************************************************** + + Synopsis [Internal function to writes a dump file representing the + argument BDD in a prefix notation. Writes the body of the file.] + + Description [One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + ] + + SideEffects [None] + + SeeAlso [DddmpCuddDdArrayStoreBlif] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStorePrefixBody ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + st_table *visited = NULL; + int retValue; + int i; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + Dddmp_CheckAndGotoLabel (visited==NULL, + "Error if function st_init_table.", failure); + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + retValue = DddmpCuddDdArrayStorePrefixStep (ddMgr, Cudd_Regular(f[i]), + fp, visited, inputNames); + Dddmp_CheckAndGotoLabel (retValue==0, + "Error if function DddmpCuddDdArrayStorePrefixStep.", failure); + } + + /* To account for the possible complement on the root, + ** we put either a buffer or an inverter at the output of + ** the multiplexer representing the top node. + */ + for (i=0; iindex]); + } else { + retValue = fprintf(fp, "inNode%d ", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + retValue = fprintf (fp, "node%lx) (AND (NOT ", + (unsigned long) T / (unsigned long) sizeof(DdNode)); +#else + retValue = fprintf (fp, "node%x) (AND (NOT ", + (unsigned) T / (unsigned) sizeof(DdNode)); +#endif + if (retValue == EOF) { + return(0); + } + + if (names != NULL) { + retValue = fprintf (fp, "%s", names[f->index]); + } else { + retValue = fprintf (fp, "inNode%d", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf (fp, ") (NOT node%lx)))\n", + (unsigned long) E / (unsigned long) sizeof(DdNode)); + } else { + retValue = fprintf (fp, ") node%lx))\n", + (unsigned long) E / (unsigned long) sizeof(DdNode)); + } +#else + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf (fp, ") (NOT node%x)))\n", + (unsigned) E / (unsigned) sizeof(DdNode)); + } else { + retValue = fprintf (fp, ") node%x))\n", + (unsigned) E / (unsigned) sizeof(DdNode)); + } +#endif + + if (retValue == EOF) { + return(0); + } else { + return(1); + } +} + +/**Function******************************************************************** + + Synopsis [Writes a blif file representing the argument BDDs.] + + Description [Writes a blif file representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). + DddmpCuddDdArrayStoreBlif does not close the file: This is the + caller responsibility. + DddmpCuddDdArrayStoreBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for outputNames. + It prefixes the string "NODE" to each nome to have "regular" names + for each elements. + ] + + SideEffects [None] + + SeeAlso [DddmpCuddDdArrayStoreBlifBody,Cudd_DumpBlif] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStoreBlif ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + char *modelName /* IN: Model name (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nVars = ddMgr->size; + int retValue; + int i; + + /* Build a bit array with the support of f. */ + sorted = ALLOC (int, nVars); + if (sorted == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure); + } + for (i = 0; i < nVars; i++) { + sorted[i] = 0; + } + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(ddMgr,f,n); + Dddmp_CheckAndGotoLabel (support==NULL, + "Error in function Cudd_VectorSupport.", failure); + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(ddMgr,support); + support = NULL; + /* so that we do not try to free it in case of failure */ + + /* Write the header (.model .inputs .outputs). */ + if (modelName == NULL) { + retValue = fprintf(fp,".model DD\n.inputs"); + } else { + retValue = fprintf(fp,".model %s\n.inputs", modelName); + } + if (retValue == EOF) { + return(0); + } + + /* Write the input list by scanning the support array. */ + for (i = 0; i < nVars; i++) { + if (sorted[i]) { + if (inputNames == NULL || (inputNames[i] == NULL)) { + retValue = fprintf(fp," inNode%d", i); + } else { + retValue = fprintf(fp," %s", inputNames[i]); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + } + FREE(sorted); + sorted = NULL; + + /* Write the .output line. */ + retValue = fprintf(fp,"\n.outputs"); + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + for (i = 0; i < n; i++) { + if (outputNames == NULL || (outputNames[i] == NULL)) { + retValue = fprintf(fp," outNode%d", i); + } else { + retValue = fprintf(fp," %s", outputNames[i]); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + retValue = fprintf(fp,"\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + + retValue = DddmpCuddDdArrayStoreBlifBody(ddMgr, n, f, inputNames, + outputNames, fp); + Dddmp_CheckAndGotoLabel (retValue==0, + "Error if function DddmpCuddDdArrayStoreBlifBody.", failure); + + /* Write trailer and return. */ + retValue = fprintf (fp, ".end\n"); + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + + return(1); + +failure: + if (sorted != NULL) { + FREE(sorted); + } + if (support != NULL) { + Cudd_RecursiveDeref(ddMgr,support); + } + + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Writes a blif body representing the argument BDDs.] + + Description [Writes a blif body representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). + DddmpCuddDdArrayStoreBlif does not close the file: This is the + caller responsibility. + DddmpCuddDdArrayStoreBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inputNames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for outputNames. This function prints out only + .names part. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStoreBlifBody ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + st_table *visited = NULL; + int retValue; + int i; + + /* Initialize symbol table for visited nodes. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); + Dddmp_CheckAndGotoLabel (visited==NULL, + "Error if function st_init_table.", failure); + + /* Call the function that really gets the job done. */ + for (i = 0; i < n; i++) { + retValue = DddmpCuddDdArrayStoreBlifStep (ddMgr, Cudd_Regular(f[i]), + fp, visited, inputNames); + Dddmp_CheckAndGotoLabel (retValue==0, + "Error if function DddmpCuddDdArrayStoreBlifStep.", failure); + } + + /* + * To account for the possible complement on the root, + * we put either a buffer or an inverter at the output of + * the multiplexer representing the top node. + */ + + for (i = 0; i < n; i++) { + if (outputNames == NULL) { + retValue = fprintf(fp, +#if SIZEOF_VOID_P == 8 + ".names node%lx outNode%d\n", + (unsigned long) f[i] / (unsigned long) sizeof(DdNode), i); +#else + ".names node%x outNode%d\n", + (unsigned) f[i] / (unsigned) sizeof(DdNode), i); +#endif + } else { + retValue = fprintf(fp, +#if SIZEOF_VOID_P == 8 + ".names node%lx %s\n", + (unsigned long) f[i] / (unsigned long) sizeof(DdNode), outputNames[i]); +#else + ".names node%x %s\n", + (unsigned) f[i] / (unsigned) sizeof(DdNode), outputNames[i]); +#endif + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + if (Cudd_IsComplement(f[i])) { + retValue = fprintf(fp,"0 1\n"); + } else { + retValue = fprintf(fp,"1 1\n"); + } + Dddmp_CheckAndGotoLabel (retValue==EOF, + "Error during file store.", failure); + } + + st_free_table(visited); + return(1); + +failure: + if (visited != NULL) { + st_free_table(visited); + } + return(0); +} + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of DddmpCuddDdArrayStoreBlif.] + + Description [Performs the recursive step of DddmpCuddDdArrayStoreBlif. + Traverses the BDD f and writes a multiplexer-network description to + the file pointed by fp in blif format. + f is assumed to be a regular pointer and DddmpCuddDdArrayStoreBlifStep + guarantees this assumption in the recursive calls. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStoreBlifStep ( + DdManager *ddMgr, + DdNode *f, + FILE *fp, + st_table *visited, + char **names + ) +{ + DdNode *T, *E; + int retValue; + +#ifdef DDDMP_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + /* If already visited, nothing to do. */ + if (st_is_member(visited, (char *) f) == 1) { + return(1); + } + + /* Check for abnormal condition that should never happen. */ + if (f == NULL) { + return(0); + } + + /* Mark node as visited. */ + if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) { + return(0); + } + + /* Check for special case: If constant node, generate constant 1. */ + if (f == DD_ONE(ddMgr)) { +#if SIZEOF_VOID_P == 8 + retValue = fprintf(fp, ".names node%lx\n1\n", + (unsigned long) f / (unsigned long) sizeof(DdNode)); +#else + retValue = fprintf(fp, ".names node%x\n1\n", + (unsigned) f / (unsigned) sizeof(DdNode)); +#endif + if (retValue == EOF) { + return(0); + } else { + return(1); + } + } + + /* Check whether this is an ADD. We deal with 0-1 ADDs, but not + ** with the general case. + */ + if (f == DD_ZERO(ddMgr)) { +#if SIZEOF_VOID_P == 8 + retValue = fprintf(fp, ".names node%lx\n", + (unsigned long) f / (unsigned long) sizeof(DdNode)); +#else + retValue = fprintf(fp, ".names node%x\n", + (unsigned) f / (unsigned) sizeof(DdNode)); +#endif + if (retValue == EOF) { + return(0); + } else { + return(1); + } + } + if (cuddIsConstant(f)) { + return(0); + } + + /* Recursive calls. */ + T = cuddT(f); + retValue = DddmpCuddDdArrayStoreBlifStep(ddMgr,T,fp,visited,names); + if (retValue != 1) return(retValue); + E = Cudd_Regular(cuddE(f)); + retValue = DddmpCuddDdArrayStoreBlifStep(ddMgr,E,fp,visited,names); + if (retValue != 1) return(retValue); + + /* Write multiplexer taking complement arc into account. */ + if (names != NULL) { + retValue = fprintf(fp,".names %s", names[f->index]); + } else { + retValue = fprintf(fp,".names inNode%d", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf(fp," node%lx node%lx node%lx\n11- 1\n0-0 1\n", + (unsigned long) T / (unsigned long) sizeof(DdNode), + (unsigned long) E / (unsigned long) sizeof(DdNode), + (unsigned long) f / (unsigned long) sizeof(DdNode)); + } else { + retValue = fprintf(fp," node%lx node%lx node%lx\n11- 1\n0-1 1\n", + (unsigned long) T / (unsigned long) sizeof(DdNode), + (unsigned long) E / (unsigned long) sizeof(DdNode), + (unsigned long) f / (unsigned long) sizeof(DdNode)); + } +#else + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf(fp," node%x node%x node%x\n11- 1\n0-0 1\n", + (unsigned) T / (unsigned) sizeof(DdNode), + (unsigned) E / (unsigned) sizeof(DdNode), + (unsigned) f / (unsigned) sizeof(DdNode)); + } else { + retValue = fprintf(fp," node%x node%x node%x\n11- 1\n0-1 1\n", + (unsigned) T / (unsigned) sizeof(DdNode), + (unsigned) E / (unsigned) sizeof(DdNode), + (unsigned) f / (unsigned) sizeof(DdNode)); + } +#endif + if (retValue == EOF) { + return(0); + } else { + return(1); + } +} + +/**Function******************************************************************** + + Synopsis [Internal function to writes a dump file representing the + argument BDD in a SMV notation.] + + Description [One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + Comments (COMMENT) are added at the beginning of the description to + describe inputs and outputs of the design. + A buffer (BUF) is add on the output to cope with complemented functions. + ] + + SideEffects [None] + + SeeAlso [DddmpCuddDdArrayStoreBlif] + +******************************************************************************/ + +static int +DddmpCuddDdArrayStoreSmv ( + DdManager *ddMgr /* IN: Manager */, + int n /* IN: Number of output nodes to be dumped */, + DdNode **f /* IN: Array of output nodes to be dumped */, + char **inputNames /* IN: Array of input names (or NULL) */, + char **outputNames /* IN: Array of output names (or NULL) */, + char *modelName /* IN: Model name (or NULL) */, + FILE *fp /* IN: Pointer to the dump file */ + ) +{ + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nVars = ddMgr->size; + int retValue; + int i; + + /* Build a bit array with the support of f. */ + sorted = ALLOC(int, nVars); + if (sorted == NULL) { + ddMgr->errorCode = CUDD_MEMORY_OUT; + Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure); + } + for (i = 0; i < nVars; i++) { + sorted[i] = 0; + } + + /* Take the union of the supports of each output function. */ + support = Cudd_VectorSupport(ddMgr,f,n); + Dddmp_CheckAndGotoLabel (support==NULL, + "Error in function Cudd_VectorSupport.", failure); + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(ddMgr,support); + /* so that we do not try to free it in case of failure */ + support = NULL; + + /* Write the header */ + if (modelName == NULL) { + retValue = fprintf (fp, "MODULE main -- Unknown\n"); + } else { + retValue = fprintf (fp, "MODULE main -- %s\n", modelName); + } + if (retValue == EOF) { + return(0); + } + + retValue = fprintf(fp, "IVAR\n"); + if (retValue == EOF) { + return(0); + } + + /* Write the input list by scanning the support array. */ + for (i=0; iindex]); + } else { + retValue = fprintf(fp, "inNode%d ", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + retValue = fprintf (fp, "& node%lx | ", + (unsigned long) T / (unsigned long) sizeof(DdNode)); +#else + retValue = fprintf (fp, "& node%x | ", + (unsigned) T / (unsigned) sizeof(DdNode)); +#endif + if (retValue == EOF) { + return(0); + } + + if (names != NULL) { + retValue = fprintf (fp, "!%s ", names[f->index]); + } else { + retValue = fprintf (fp, "!inNode%d ", f->index); + } + if (retValue == EOF) { + return(0); + } + +#if SIZEOF_VOID_P == 8 + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf (fp, "& !node%lx\n", + (unsigned long) E / (unsigned long) sizeof(DdNode)); + } else { + retValue = fprintf (fp, "& node%lx\n", + (unsigned long) E / (unsigned long) sizeof(DdNode)); + } +#else + if (Cudd_IsComplement(cuddE(f))) { + retValue = fprintf (fp, "& !node%x\n", + (unsigned) E / (unsigned) sizeof(DdNode)); + } else { + retValue = fprintf (fp, "& node%x\n", + (unsigned) E / (unsigned) sizeof(DdNode)); + } +#endif + + if (retValue == EOF) { + return(0); + } else { + return(1); + } +} + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpUtil.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpUtil.c new file mode 100644 index 000000000..feff43943 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/dddmpUtil.c @@ -0,0 +1,436 @@ +/**CFile********************************************************************** + + FileName [dddmpUtil.c] + + PackageName [dddmp] + + Synopsis [Util Functions for the dddmp package] + + Description [Functions to manipulate arrays.] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [String compare for qsort] + + Description [String compare for qsort] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +int +QsortStrcmp( + const void *ps1 /* IN: pointer to the first string */, + const void *ps2 /* IN: pointer to the second string */ + ) +{ + return (strcmp (*((char**)ps1),*((char **)ps2))); +} + +/**Function******************************************************************** + + Synopsis [Performs binary search of a name within a sorted array] + + Description [Binary search of a name within a sorted array of strings. + Used when matching names of variables. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +int +FindVarname ( + char *name /* IN: name to look for */, + char **array /* IN: search array */, + int n /* IN: size of the array */ + ) +{ + int d, m, u, t; + + d = 0; u = n-1; + + while (u>=d) { + m = (u+d)/2; + t=strcmp(name,array[m]); + if (t==0) + return m; + if (t<0) + u=m-1; + else + d=m+1; + } + + return (-1); +} + + +/**Function******************************************************************** + + Synopsis [Duplicates a string] + + Description [Allocates memory and copies source string] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +char * +DddmpStrDup ( + char *str /* IN: string to be duplicated */ + ) +{ + char *str2; + + str2 = DDDMP_ALLOC(char,strlen(str)+1); + if (str2 != NULL) { + strcpy (str2,str); + } + + return (str2); +} + +/**Function******************************************************************** + + Synopsis [Duplicates an array of strings] + + Description [Allocates memory and copies source array] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +char ** +DddmpStrArrayDup ( + char **array /* IN: array of strings to be duplicated */, + int n /* IN: size of the array */ + ) +{ + char **array2; + int i; + + array2 = DDDMP_ALLOC(char *, n); + if (array2 == NULL) { + (void) fprintf (stderr, "DddmpStrArrayDup: Error allocating memory\n"); + fflush (stderr); + return NULL; + } + + /* + * initialize all slots to NULL for fair FREEing in case of failure + */ + + for (i=0; i +Command Documentation + + +

                          Command Documentation


                          +
                          +
                          +Last updated on 1040218 17h15 + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/commands.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/commands.html new file mode 100644 index 000000000..2609aafcd --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/commands.html @@ -0,0 +1,12 @@ + +Command Documentation + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/credit.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/credit.html new file mode 100644 index 000000000..868097be4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/credit.html @@ -0,0 +1,15 @@ + +Credit + + + + + + + +
                          + Command Documentation + Package Documentation Generated by + the Ext system
                          + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmp-2.0-A4.ps b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmp-2.0-A4.ps new file mode 100644 index 000000000..7c1010a10 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmp-2.0-A4.ps @@ -0,0 +1,1261 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software +%%Title: dddmp-2.0.dvi +%%Pages: 10 +%%PageOrder: Ascend +%%BoundingBox: 0 0 596 842 +%%DocumentFonts: Times-Bold Times-Roman Courier Times-Italic Helvetica +%%DocumentPaperSizes: a4 +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -t a4 -f dddmp-2.0 +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2002.12.11:0557 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", +% version = "0.6", +% date = "22 June 1996", +% filename = "8r.enc", +% email = "kb@@mail.tug.org", +% address = "135 Center Hill Rd. // Plymouth, MA 02360", +% codetable = "ISO/ASCII", +% checksum = "119 662 4424", +% docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." +% @} +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both ASCII and Windows. +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there down to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics +exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub +dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} +ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict +end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ +dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 +roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def +dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} +if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} +def end + +%%EndProcSet +%%BeginProcSet: special.pro +%! +TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N +/vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N +/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N +/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ +/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho +X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B +/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ +/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known +{userdict/md get type/dicttype eq{userdict begin md length 10 add md +maxlength ge{/md md dup length 20 add dict copy def}if end md begin +/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S +atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ +itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll +transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll +curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf +pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} +if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 +-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 +get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip +yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub +neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ +noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop +90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get +neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr +1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr +2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 +-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S +TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ +Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale +}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState +save N userdict maxlength dict begin/magscale true def normalscale +currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts +/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x +psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx +psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub +TR/showpage{}N/erasepage{}N/copypage{}N/p 3 def @MacSetUp}N/doclip{ +psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 +roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath +moveto}N/endTexFig{end psf$SavedState restore}N/@beginspecial{SDict +begin/SpecialSave save N gsave normalscale currentpoint TR +@SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{ +CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto +closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx +sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR +}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse +CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury +lineto closepath clip}if/showpage{}N/erasepage{}N/copypage{}N newpath}N +/@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{end} +repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N +/@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX +currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY +moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X +/yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0 +1 startangle endangle arc savematrix setmatrix}N end + +%%EndProcSet +TeXDict begin 39158280 55380996 1000 600 600 (dddmp-2.0.dvi) +@start /Fa 143[55 1[55 7[28 2[50 99[{TeXBase1Encoding ReEncodeFont}4 +99.6264 /Helvetica rf +%DVIPSBitmapFont: Fb cmr12 12 3 +/Fb 3 53 df<14FF010713E090381F81F890383E007C01FC133F4848EB1F8049130F4848 +EB07C04848EB03E0A2000F15F0491301001F15F8A2003F15FCA390C8FC4815FEA54815FF +B3A46C15FEA56D1301003F15FCA3001F15F8A26C6CEB03F0A36C6CEB07E0000315C06D13 +0F6C6CEB1F806C6CEB3F00013E137C90381F81F8903807FFE0010090C7FC28447CC131> +48 D<143014F013011303131F13FFB5FC13E713071200B3B3B0497E497E007FB6FCA320 +4278C131>I52 D E +%EndDVIPSBitmapFont +/Fc 64[50 29[39 12[55 55 25[44 44 66 44 50 28 39 39 1[50 +50 50 72 28 44 1[28 50 50 28 44 50 44 50 50 10[61 2[50 +4[66 83 55 2[33 2[61 1[72 66 61 61 15[50 2[25 33 25 2[33 +33 37[50 2[{TeXBase1Encoding ReEncodeFont}45 99.6264 +/Times-Italic rf +%DVIPSBitmapFont: Fd cmmi12 12 3 +/Fd 3 103 df60 D<127012FCB4FCEA7FC0EA1FF0EA +07FCEA01FF38007FC0EB1FF0EB07FE903801FF809038007FE0EC1FF8EC03FE913800FF80 +ED3FE0ED0FF8ED03FF030013C0EE3FF0EE0FFCEE01FF9338007FC0EF1FF0EF07FCEF01FF +9438007FC0F01FE0A2F07FC0943801FF00EF07FCEF1FF0EF7FC04C48C7FCEE0FFCEE3FF0 +EEFFC0030390C8FCED0FF8ED3FE0EDFF80DA03FEC9FCEC1FF8EC7FE0903801FF80D907FE +CAFCEB1FF0EB7FC04848CBFCEA07FCEA1FF0EA7FC048CCFC12FC12703B3878B44C>62 +D102 +D E +%EndDVIPSBitmapFont +/Fe 134[42 2[42 42 23 32 28 1[42 42 42 65 23 2[23 42 +42 28 37 42 1[42 37 12[51 10[28 4[60 1[55 19[21 28 21 +44[{TeXBase1Encoding ReEncodeFont}26 83.022 /Times-Roman +rf +%DVIPSBitmapFont: Ff cmr7 7 2 +/Ff 2 51 df<13381378EA01F8121F12FE12E01200B3AB487EB512F8A215267BA521>49 +D<13FF000313E0380E03F0381800F848137C48137E00787F12FC6CEB1F80A4127CC7FC15 +005C143E147E147C5C495A495A5C495A010EC7FC5B5B903870018013E0EA018039030003 +0012065A001FB5FC5A485BB5FCA219267DA521>I E +%EndDVIPSBitmapFont +/Fg 103[60 26[60 1[60 60 60 60 60 60 60 60 60 60 60 60 +60 60 60 60 2[60 60 60 60 60 60 60 60 60 3[60 1[60 3[60 +60 1[60 60 1[60 60 1[60 60 3[60 1[60 1[60 60 60 1[60 +60 1[60 1[60 1[60 60 60 60 60 60 60 60 60 60 60 60 60 +60 60 5[60 38[{TeXBase1Encoding ReEncodeFont}62 99.6264 +/Courier rf +%DVIPSBitmapFont: Fh cmr8 8 2 +/Fh 2 51 df<130C133C137CEA03FC12FFEAFC7C1200B3B113FE387FFFFEA2172C7AAB23 +>49 DI E +%EndDVIPSBitmapFont +/Fi 105[50 28[50 50 2[55 33 39 44 1[55 50 55 83 28 2[28 +1[50 33 44 55 44 55 50 10[72 1[66 55 3[78 72 94 66 3[78 +1[61 66 72 72 66 72 13[50 50 50 1[28 25 33 45[{ +TeXBase1Encoding ReEncodeFont}40 99.6264 /Times-Bold +rf /Fj 139[40 1[53 1[66 60 66 100 33 2[33 3[53 3[60 23[47 +2[73 18[60 60 60 2[30 46[{TeXBase1Encoding ReEncodeFont}16 +119.552 /Times-Bold rf +%DVIPSBitmapFont: Fk cmsy10 12 1 +/Fk 1 16 df<49B4FC010F13E0013F13F8497F48B6FC4815804815C04815E04815F0A248 +15F8A24815FCA3B712FEA96C15FCA36C15F8A26C15F0A26C15E06C15C06C15806C15006C +6C13FC6D5B010F13E0010190C7FC27277BAB32>15 D E +%EndDVIPSBitmapFont +/Fl 64[44 42[44 44 24[44 50 50 72 50 50 28 39 33 50 50 +50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 6[61 1[72 +94 72 72 61 55 66 72 55 72 72 89 61 1[39 33 72 72 55 +61 72 66 66 72 3[56 1[28 28 50 50 50 50 50 50 50 50 50 +50 28 25 33 25 2[33 33 36[55 55 2[{TeXBase1Encoding ReEncodeFont}74 +99.6264 /Times-Roman rf +%DVIPSBitmapFont: Fm cmsy10 14.4 2 +/Fm 2 104 df102 +DI E +%EndDVIPSBitmapFont +/Fn 105[60 27[53 4[60 33 47 40 60 60 60 60 93 33 2[33 +1[60 40 53 60 53 60 53 7[86 4[73 66 1[86 66 3[73 2[40 +1[86 1[73 86 80 1[86 110 5[33 60 4[60 1[60 60 60 1[30 +40 30 44[{TeXBase1Encoding ReEncodeFont}42 119.552 /Times-Roman +rf /Fo 136[104 1[80 48 56 64 1[80 72 80 120 40 80 1[40 +1[72 1[64 80 64 80 72 12[96 80 104 1[88 1[104 135 3[56 +2[88 1[104 104 96 104 6[48 1[72 72 72 72 72 72 72 72 +72 1[36 46[{TeXBase1Encoding ReEncodeFont}41 143.462 +/Times-Bold rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin +%%BeginPaperSize: a4 +a4 +%%EndPaperSize + +%%EndSetup +%%Page: 1 1 +1 0 bop 472 600 a Fo(DDDMP:)35 b(Decision)f(Diagram)f(DuMP)j(package) +1480 830 y(Release)e(2.0)462 1230 y Fn(Gianpiero)c(Cabodi)2402 +1232 y(Stef)o(ano)g(Quer)1316 1506 y(Politecnico)g(di)g(T)-10 +b(orino)1024 1656 y(Dip.)30 b(di)g(Automatica)g(e)g(Informatica)1119 +1805 y(Corso)f(Duca)h(de)n(gli)g(Abruzzi)g(24)1277 1955 +y(I\22610129)e(T)-5 b(urin,)29 b(IT)-11 b(AL)f(Y)1038 +2104 y(E-mail:)38 b Fm(f)p Fn(cabodi,quer)p Fm(g)p Fn(@polito.it)-189 +2614 y Fo(1)143 b(Intr)m(oduction)-189 2837 y Fl(The)27 +b(DDDMP)h(package)f(de\002nes)h(formats)f(and)g(rules)g(to)g(store)g +(DD)g(on)g(\002le.)39 b(More)27 b(in)g(particular)g(it)g(contains)g(a) +-189 2958 y(set)e(of)g(functions)e(to)i(dump)e(\(store)i(and)g(load\))g +(DDs)f(and)h(DD)g(forests)f(on)h(\002le)g(in)f(dif)n(ferent)h(formats.) +47 3078 y(In)30 b(the)g(present)g(implementation,)f(BDDs)h(\(R)l +(OBDDs\))h(and)f(ADD)g(\(Algebraic)g(Decision)g(Diagram\))g(of)-189 +3199 y(the)g(CUDD)g(package)g(\(v)o(ersion)f(2.3.0)g(or)h(higher\))g +(are)g(supported.)45 b(These)30 b(structures)f(can)h(be)g(represented)g +(on)-189 3319 y(\002les)25 b(either)g(in)f(te)o(xt,)g(binary)-6 +b(,)24 b(or)h(CNF)g(\(DIMA)l(CS\))h(formats.)47 3439 +y(The)f(main)f(rules)h(used)f(are)i(follo)n(wing)d(rules:)-44 +3643 y Fk(\017)49 b Fl(A)30 b(\002le)h(contains)e(a)i(single)e(BDD/ADD) +h(or)g(a)h(forest)f(of)g(BDDs/ADD,)g(i.e.,)i(a)e(v)o(ector)g(of)g +(Boolean)h(func-)55 3763 y(tions.)-44 3966 y Fk(\017)49 +b Fl(Inte)o(ger)21 b(inde)o(x)o(es)f(are)i(used)f(instead)g(of)g +(pointers)g(to)g(reference)i(nodes.)29 b(BDD/ADD)21 b(nodes)g(are)h +(numbered)55 4087 y(with)j(contiguous)g(numbers,)g(from)h(1)g(to)f +(NNodes)h(\(total)f(number)h(of)g(nodes)g(on)f(a)i(\002le\).)35 +b(0)26 b(is)f(not)h(used)f(to)55 4207 y(allo)n(w)f(ne)o(gati)n(v)o(e)e +(inde)o(x)o(es)h(for)i(complemented)f(edges.)-44 4411 +y Fk(\017)49 b Fl(A)23 b(\002le)g(contains)f(a)h(header)l(,)h +(including)d(se)n(v)o(eral)h(informations)f(about)h(v)n(ariables)h(and) +f(roots)g(of)h(BDD)h(func-)55 4531 y(tions,)32 b(then)e(the)h(list)g +(of)g(nodes.)49 b(The)32 b(header)f(is)g(al)o(w)o(ays)g(represented)h +(in)f(te)o(xt)f(format)h(\(also)g(for)g(binary)55 4651 +y(\002les\).)g(BDDs,)25 b(ADDs,)f(and)h(CNF)h(\002les)f(share)g(a)g +(similar)f(format)g(header)-5 b(.)-44 4855 y Fk(\017)49 +b Fl(BDD/ADD)40 b(nodes)g(are)h(listed)f(follo)n(wing)e(their)i +(numbering,)j(which)d(is)g(produced)g(by)h(a)f(post-order)55 +4975 y(tra)n(v)o(ersal,)24 b(in)h(such)f(a)h(w)o(ay)g(that)g(a)g(node)f +(is)h(al)o(w)o(ays)f(listed)g(after)h(its)f(Then/Else)g(children.)47 +5179 y(In)32 b(the)f(sequel)g(we)g(describe)h(more)f(in)g(detail)f(the) +h(dif)n(ferent)g(formats)g(and)g(procedures)h(a)n(v)n(ailable.)49 +b(First)-189 5299 y(of)26 b(all,)f(we)h(describe)f(BDDs)h(and)g(ADDs)f +(formats)g(and)g(procedure.)33 b(Secondly)-6 b(,)26 b(we)f(concentrate) +h(on)f(CNF)i(\002les,)-189 5419 y(i.e.,)e(ho)n(w)f(to)g(translate)g(a)i +(BDD)f(or)g(a)g(forest)g(of)f(BDDs)h(into)f(a)h(CNF)h(formula)e(and)h +(vice-v)o(ersa.)1794 5800 y(1)p eop +%%Page: 2 2 +2 1 bop -189 218 a Fo(2)143 b(BDD)35 b(and)g(ADD)g(Support)-189 +441 y Fl(In)23 b(this)f(section)g(we)g(describe)h(format)g(and)f +(procedure)h(re)o(garding)f(BDDs)h(and)f(ADDs.)30 b(W)-8 +b(e)23 b(speci\002cally)g(refer)g(to)-189 562 y(BDDs)h(in)g(the)g +(description)e(as)j(ADD)e(may)h(be)g(seen)g(as)h(an)f(e)o(xtension)e +(and)i(will)f(be)h(described)g(later)-5 b(.)30 b(First)24 +b(of)g(all,)-189 682 y(we)29 b(concentrate)f(on)g(the)g(format)g(used)g +(to)g(store)g(these)g(structure,)h(then)f(we)g(describe)h(the)f +(procedure)h(a)n(v)n(ailable)-189 802 y(to)24 b(store)h(and)g(load)f +(them.)-189 1094 y Fj(2.1)119 b(F)m(ormat)-189 1281 y +Fl(BDD)30 b(dump)f(\002les)g(are)i(composed)e(of)g(tw)o(o)g(sections:) +40 b(The)29 b(header)h(and)g(the)f(list)g(of)h(nodes.)44 +b(The)30 b(header)g(has)g(a)-189 1402 y(common)c(\(te)o(xt\))h(format,) +h(while)e(the)i(list)e(of)h(nodes)g(is)g(either)g(in)g(te)o(xt)g(or)g +(binary)g(format.)38 b(In)28 b(te)o(xt)e(format)h(nodes)-189 +1522 y(are)33 b(represented)f(with)f(redundant)g(informations,)h(where) +h(the)f(main)f(goal)g(is)h(readability)-6 b(,)32 b(while)g(the)f +(purpose)-189 1642 y(of)i(binary)f(format)g(is)g(minimizing)e(the)i(o)o +(v)o(erall)f(storage)h(size)h(for)g(BDD)f(nodes.)54 b(The)32 +b(header)h(format)f(is)g(k)o(ept)-189 1763 y(common)h(to)h(te)o(xt)g +(and)g(binary)g(formats)g(for)h(sak)o(e)f(of)h(simplicity:)47 +b(No)34 b(particular)g(optimization)f(is)h(presently)-189 +1883 y(done)29 b(on)f(binary)h(\002le)g(headers,)h(whose)f(size)g(is)f +(by)h(f)o(ar)g(dominated)f(by)h(node)f(lists)g(in)g(the)h(case)g(of)g +(lar)n(ge)h(BDDs)-189 2003 y(\(se)n(v)o(eral)24 b(thousands)g(of)h(DD)f +(nodes\).)-189 2266 y Fi(2.1.1)99 b(Header)-189 2453 +y Fl(The)23 b(header)h(has)f(the)g(same)g(format)g(both)g(for)g(te)o +(xtual)f(and)i(binary)e(dump.)30 b(F)o(or)23 b(sak)o(e)g(of)h +(generality)e(and)h(because)-189 2574 y(of)f(dynamic)g(v)n(ariable)g +(ordering)g(both)f(v)n(ariable)h(IDs)g(and)g(permutations)2377 +2537 y Fh(1)2438 2574 y Fl(are)h(included.)29 b(Names)22 +b(are)h(optionally)-189 2694 y(listed)35 b(for)h(input)f(v)n(ariables)g +(and)h(for)h(the)e(stored)h(functions.)63 b(Ne)n(w)36 +b(auxiliary)f(IDs)h(are)h(also)e(allo)n(wed.)64 b(Only)-189 +2814 y(the)34 b(v)n(ariables)f(in)g(the)h(true)g(support)f(of)h(the)f +(stored)h(BDDs)g(are)h(listed.)56 b(All)34 b(information)e(on)i(v)n +(ariables)f(\(IDs,)-189 2935 y(permutations,)c(names,)i(auxiliary)e +(IDs\))h(sorted)g(by)g(IDs,)h(and)e(the)o(y)h(are)g(restricted)g(to)f +(the)h(true)g(support)f(of)h(the)-189 3055 y(dumped)22 +b(BDD,)h(while)g(IDs)g(and)f(permutations)g(are)h(referred)i(to)d(the)h +(writing)f(BDD)h(manager)-5 b(.)30 b(Names)22 b(can)i(thus)-189 +3175 y(be)h(sorted)f(by)h(v)n(ariable)f(ordering)h(by)f(permuting)g +(them)g(according)h(to)f(the)h(permutations)e(stored)h(in)h(the)f +(\002le.)47 3296 y(As)h(an)g(e)o(xample,)f(the)g(header)i(\(in)e(te)o +(xt)g(mode\))h(of)f(the)h(ne)o(xt)f(state)h(functions)e(of)i(circuit)g +(s27)f(follo)n(ws:)-189 3494 y Fg(.ver)59 b(DDDMP-2.0)-189 +3615 y(.mode)g(A)-189 3735 y(.varinfo)f(3)-189 3855 y(.dd)h(s27-delta) +-189 3976 y(.nnodes)f(16)-189 4096 y(.nvars)g(10)-189 +4216 y(.nsuppvars)g(7)-189 4337 y(.varnames)g(G0)h(G1)g(G2)h(G3)f(G5)g +(G6)h(G7)-189 4457 y(.orderedvarnames)c(G0)k(G1)f(G2)g(G3)h(G5)f(G6)g +(G7)-189 4578 y(.ids)g(0)g(1)h(2)g(3)f(4)h(5)f(6)-189 +4698 y(.permids)f(0)i(1)f(2)h(3)f(5)h(7)f(9)-189 4818 +y(.auxids)f(1)i(2)f(3)h(4)f(5)h(6)g(7)-189 4939 y(.nroots)e(3)-189 +5059 y(.rootids)g(6)i(-13)f(-16)-189 5179 y(.rootnames)f(G10)h(G11)g +(G13)47 5378 y Fl(The)25 b(lines)f(contain)g(the)h(follo)n(wing)e +(informations:)p -189 5460 1607 4 v -77 5521 a Ff(1)-40 +5551 y Fe(The)d(permutation)e(of)i(the)g(i-th)h(v)n(ariable)e(ID)h(is)h +(the)f(relati)n(v)o(e)g(position)f(of)h(the)g(v)n(ariable)f(in)i(the)f +(ordering.)1794 5800 y Fl(2)p eop +%%Page: 3 3 +3 2 bop -44 218 a Fk(\017)49 b Fl(Dddmp)24 b(v)o(ersion)f(information.) +-44 411 y Fk(\017)49 b Fl(File)25 b(mode)f(\(A)h(for)g(ASCII)h(te)o +(xt,)e(B)h(for)g(binary)g(mode\).)-44 604 y Fk(\017)49 +b Fl(V)-11 b(ar)n(-e)o(xtra-info)25 b(\(0:)30 b(v)n(ariable)24 +b(ID,)h(1:)31 b(permID,)24 b(2:)31 b(aux)25 b(ID,)g(3:)30 +b(v)n(ariable)24 b(name,)h(4)g(no)f(e)o(xtra)h(info\).)-44 +797 y Fk(\017)49 b Fl(Name)25 b(of)g(dd)f(\(optional\).)-44 +990 y Fk(\017)49 b Fl(T)-8 b(otal)24 b(number)g(of)h(nodes)g(in)f(the)h +(\002le.)-44 1183 y Fk(\017)49 b Fl(Number)24 b(of)h(v)n(ariables)f(of) +h(the)g(writing)f(DD)g(manager)-5 b(.)-44 1375 y Fk(\017)49 +b Fl(Number)24 b(of)h(v)n(ariables)f(in)h(the)f(true)h(support)f(of)h +(the)f(stored)h(DDs.)-44 1568 y Fk(\017)49 b Fl(V)-11 +b(ariable)25 b(names)f(\(optional\))g(for)h(all)g(the)f(v)n(ariables)g +(in)h(the)f(BDD/ADD)h(support.)-44 1761 y Fk(\017)49 +b Fl(V)-11 b(ariable)20 b(names)g(for)h(all)f(the)g(v)n(ariables)f(in)h +(the)g(DD)h(manager)f(during)g(the)g(storing)f(phase.)29 +b(Notice)20 b(that)g(this)55 1882 y(information)k(w)o(as)h(not)g +(stored)g(by)g(pre)n(vious)f(v)o(ersions)g(of)i(the)f(same)g(tool.)32 +b(Full)25 b(backw)o(ard)g(compatibility)55 2002 y(is)f(guaranteed)h(by) +g(the)f(present)h(implementation)d(of)j(the)g(tool.)-44 +2195 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(IDs.)-44 +2388 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(permuted)f(IDs.)-44 +2581 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(auxiliary)f(IDs)h +(\(optional\).)-44 2774 y Fk(\017)49 b Fl(Number)24 b(of)h(BDD)g +(roots.)-44 2967 y Fk(\017)49 b Fl(Inde)o(x)o(es)24 b(of)h(BDD)g(roots) +f(\(complemented)g(edges)g(allo)n(wed\).)-44 3160 y Fk(\017)49 +b Fl(Names)24 b(of)h(BDD)h(roots)e(\(optional\).)-189 +3332 y(Notice)h(that)f(a)h(\002eld)-189 3504 y Fg(.add)-189 +3676 y Fl(is)f(present)h(after)g(the)g(dddmp)f(v)o(ersion)f(for)j +(\002les)e(containing)g(ADDs.)-189 3936 y Fi(2.1.2)99 +b(T)-9 b(ext)25 b(F)n(ormat)-189 4124 y Fl(In)g(te)o(xt)f(mode)g(nodes) +g(are)i(listed)e(on)g(a)h(te)o(xt)f(line)h(basis.)30 +b(Each)25 b(a)g(node)f(is)h(represented)g(as)-189 4296 +y Fg()57 b([])f()588 +4416 y()h()-189 4588 y Fl(where)25 +b(all)g(inde)o(x)o(es)e(are)j(inte)o(ger)e(numbers.)47 +4709 y(This)h(format)g(is)g(redundant)f(\(due)i(to)f(the)g(node)g +(ordering,)g Fd(<)p Fl(Node-inde)o(x)p Fd(>)f Fl(is)g(and)i +(incremental)e(inte)o(ger\))-189 4829 y(b)n(ut)g(we)h(k)o(eep)g(it)g +(for)g(readability)-6 b(.)47 4949 y Fd(<)p Fl(V)-11 b(ar)n(-e)o +(xtra-info)p Fd(>)34 b Fl(\(optional)e(redundant)i(\002eld\))g(is)f +(either)h(an)g(inte)o(ger)f(\(ID,)h(PermID,)g(or)g(auxID\))g(or)g(a) +-189 5070 y(string)k(\(v)n(ariable)h(name\).)75 b Fd(<)p +Fl(V)-11 b(ar)n(-internal-inde)o(x)p Fd(>)38 b Fl(is)h(an)g(internal)g +(v)n(ariable)g(inde)o(x:)59 b(V)-11 b(ariables)39 b(in)g(the)g(true) +-189 5190 y(support)25 b(of)h(the)g(stored)g(BDDs)g(are)h(numbered)e +(with)g(ascending)h(inte)o(gers)f(starting)g(from)h(0,)g(and)g(follo)n +(wing)e(the)-189 5311 y(v)n(ariable)g(ordering.)31 b +Fd(<)p Fl(Then-inde)o(x)p Fd(>)23 b Fl(and)i Fd(<)p Fl(Else-inde)o(x)p +Fd(>)e Fl(are)j(signed)e(inde)o(x)o(es)f(of)i(children)f(nodes.)47 +5431 y(In)h(the)f(follo)n(wing,)f(we)i(report)f(the)g(list)g(of)h +(nodes)f(of)g(the)h(s27)f(ne)o(xt)f(state)i(functions)e(\(see)i(pre)n +(vious)e(header)-189 5551 y(e)o(xample\):)1794 5800 y(3)p +eop +%%Page: 4 4 +4 3 bop -189 218 a Fg(.nodes)-189 338 y(1)60 b(T)f(1)h(0)f(0)-189 +459 y(2)h(G7)f(6)g(1)h(-1)-189 579 y(3)g(G5)f(4)g(1)h(2)-189 +699 y(4)g(G3)f(3)g(3)h(1)-189 820 y(5)g(G1)f(1)g(1)h(4)-189 +940 y(6)g(G0)f(0)g(5)h(-1)-189 1061 y(7)g(G6)f(5)g(1)h(-1)-189 +1181 y(8)g(G5)f(4)g(1)h(-7)-189 1301 y(9)g(G6)f(5)g(1)h(-2)-189 +1422 y(10)f(G5)h(4)f(1)h(-9)-189 1542 y(11)f(G3)h(3)f(10)h(8)-189 +1662 y(12)f(G1)h(1)f(8)h(11)-189 1783 y(13)f(G0)h(0)f(5)h(12)-189 +1903 y(14)f(G2)h(2)f(1)h(-1)-189 2024 y(15)f(G2)h(2)f(1)h(-2)-189 +2144 y(16)f(G1)h(1)f(14)h(15)-189 2264 y(.end)-189 2468 +y Fl(The)27 b(list)f(is)h(enclosed)g(between)g(the)g +Fg(.nodes)f Fl(and)h Fg(.end)f Fl(lines.)37 b(First)27 +b(node)g(is)g(the)g(one)g(constant,)f(each)i(node)-189 +2588 y(contains)c(the)h(optional)e(v)n(ariable)h(name.)47 +2708 y(F)o(or)29 b(ADDs)f(more)h(than)f(one)h(constant)e(is)i(stored)f +(in)g(the)g(\002le.)43 b(Each)29 b(constant)f(has)g(the)h(same)f +(format)h(we)-189 2829 y(ha)n(v)o(e)c(just)e(analyzed)i(for)g(the)g +(BDD)g(b)n(ut)g(the)f(represented)h(v)n(alue)f(is)h(stored)f(as)h(a)g +(\003oat)g(number)-5 b(.)-189 3095 y Fi(2.1.3)99 b(Binary)25 +b(F)n(ormat)-189 3283 y Fl(The)h(binary)g(format)f(is)h(not)f(allo)n +(wed)g(for)i(ADDs.)33 b(As)26 b(a)h(consequence)f(we)g(concentrate)g +(only)f(on)h(BDDs)g(in)g(this)-189 3403 y(section.)k(In)25 +b(binary)f(mode)h(nodes)f(are)i(represented)f(as)g(a)g(sequence)g(of)g +(bytes,)f(encoding)g(tuples)-189 3606 y Fg()-189 +3727 y([])-189 3847 y([])-189 +3968 y([])-189 4171 y Fl(in)30 b(an)g(optimized)f(w)o(ay)-6 +b(.)46 b(Only)29 b(the)h(\002rst)g(byte)g(\(code\))h(is)e(mandatory)-6 +b(,)30 b(while)g(inte)o(ger)f(inde)o(x)o(es)g(are)i(represented)-189 +4291 y(in)c(absolute)f(or)h(relati)n(v)o(e)f(mode,)h(where)h(relati)n +(v)o(e)e(means)g(of)n(fset)h(with)f(respect)i(to)e(a)i(Then/Else)e +(node)h(info.)37 b(The)-189 4412 y(best)23 b(between)g(absolute)f(and)h +(relati)n(v)o(e)e(representation)i(is)f(chosen)h(and)g(relati)n(v)o(e)f +(1)h(is)f(directly)g(coded)h(in)g Fd(<)p Fl(Node-)-189 +4532 y(code)p Fd(>)e Fl(without)f(an)o(y)g(e)o(xtra)h(info.)29 +b(Suppose)21 b(V)-11 b(ar\(NodeId\),)22 b(Then\(NodeId\))f(and)g +(Else\(NodeId\))f(represent)i(infos)-189 4652 y(about)i(a)h(gi)n(v)o +(en)f(node.)30 b Fd(<)p Fl(Node-code)p Fd(>)25 b Fl(is)f(a)h(byte)g +(which)f(contains)g(the)h(follo)n(wing)e(bit)h(\002elds)h(\(MSB)g(to)g +(LSB\))-44 4856 y Fk(\017)49 b Fl(Unused)24 b(:)31 b(1)24 +b(bit)-44 5059 y Fk(\017)49 b Fl(V)-11 b(ariable:)30 +b(2)25 b(bits,)f(one)h(of)g(the)f(follo)n(wing)f(codes)171 +5288 y Fi(\226)49 b Fl(DDDMP)p 636 5288 30 4 v 35 w(ABSOLUTE)p +1191 5288 V 36 w(ID:)22 b(V)-11 b(ar\(NodeId\))22 b(is)f(represented)h +(in)g(absolute)f(form)g(as)h Fd(<)p Fl(V)-11 b(ar)n(-internal-)270 +5408 y(info)p Fd(>)24 b Fl(=)h(V)-11 b(ar\(NodeId\))25 +b(follo)n(ws)e(\(absolute)i(info\))1794 5800 y(4)p eop +%%Page: 5 5 +5 4 bop 171 218 a Fi(\226)49 b Fl(DDDMP)p 636 218 30 +4 v 35 w(RELA)-11 b(TIVE)p 1147 218 V 36 w(ID:)32 b(V)-11 +b(ar\(NodeId\))32 b(is)g(represented)g(in)f(relati)n(v)o(e)g(form)h(as) +g Fd(<)p Fl(V)-11 b(ar)n(-internal-)270 338 y(info\277)24 +b(=)h(Min\(V)-11 b(ar\(Then\(NodeId\)\),V)g(ar\(Else\(NodeId\)\)\)-V)g +(ar\(NodeId\))171 500 y Fi(\226)49 b Fl(DDDMP)p 636 500 +V 35 w(RELA)-11 b(TIVE)p 1147 500 V 36 w(1:)27 b(the)19 +b(\002eld)g Fd(<)p Fl(V)-11 b(ar)n(-internal-info)p Fd(>)18 +b Fl(does)h(not)f(follo)n(w)-6 b(,)18 b(because)h(V)-11 +b(ar\(NodeId\))270 620 y(=)25 b(Min\(V)-11 b(ar\(Then\(NodeId\)\),V)g +(ar\(Else\(NodeId\)\)\)-1)171 782 y Fi(\226)49 b Fl(DDDMP)p +636 782 V 35 w(TERMIN)m(AL:)24 b(Node)h(is)f(a)h(terminal,)f(no)g(v)n +(ar)h(info)g(required)-44 1011 y Fk(\017)49 b Fl(T)25 +b(:)f(2)h(bits,)f(with)g(codes)h(similar)e(to)i(V)171 +1214 y Fi(\226)49 b Fl(DDDMP)p 636 1214 V 35 w(ABSOLUTE)p +1191 1214 V 36 w(ID:)20 b Fd(<)p Fl(Then-info)p Fd(>)f +Fl(is)h(represented)g(in)g(absolute)f(form)h(as)g Fd(<)p +Fl(Then-info)p Fd(>)270 1334 y Fl(=)25 b(Then\(NodeId\))171 +1496 y Fi(\226)49 b Fl(DDDMP)p 636 1496 V 35 w(RELA)-11 +b(TIVE)p 1147 1496 V 36 w(ID:)28 b(Then\(NodeId\))f(is)g(represented)h +(in)g(relati)n(v)o(e)e(form)i(as)g Fd(<)p Fl(Then-info)p +Fd(>)270 1617 y Fl(=)d(Nodeid-Then\(NodeId\))171 1779 +y Fi(\226)49 b Fl(DDDMP)p 636 1779 V 35 w(RELA)-11 b(TIVE)p +1147 1779 V 36 w(1:)30 b(no)25 b Fd(<)p Fl(Then-info)p +Fd(>)f Fl(follo)n(ws,)f(because)i(Then\(NodeId\))g(=)g(NodeId-1)171 +1941 y Fi(\226)49 b Fl(DDDMP)p 636 1941 V 35 w(TERMIN)m(AL:)24 +b(Then)h(Node)f(is)h(a)g(terminal,)f(no)g(info)h(required)f(\(for)i(R)l +(OBDDs\))-44 2144 y Fk(\017)49 b Fl(Ecompl)24 b(:)30 +b(1)25 b(bit,)f(if)h(1)g(means)f(that)g(the)h(else)g(edge)g(is)f +(complemented)-44 2347 y Fk(\017)49 b Fl(E)25 b(:)f(2)h(bits,)f(with)g +(codes)h(and)f(meanings)g(as)h(for)g(the)g(Then)f(edge)-189 +2551 y(DD)35 b(node)f(codes)h(are)h(written)e(as)h(one)g(byte.)60 +b Fd(<)p Fl(V)-11 b(ar)n(-internal-inde)o(x)p Fd(>)p +Fl(,)36 b Fd(<)p Fl(Then-inde)o(x)p Fd(>)p Fl(,)g Fd(<)p +Fl(Else-inde)o(x)p Fd(>)e Fl(\(if)-189 2671 y(required\))25 +b(are)h(represented)f(as)g(unsigned)e(inte)o(ger)h(v)n(alues)g(on)h(a)g +(suf)n(\002cient)f(set)h(of)g(bytes)f(\(MSByte)h(\002rst\).)47 +2792 y(Inte)o(gers)h(of)f(an)o(y)h(length)e(are)j(written)e(as)h +(sequences)g(of)g(\224link)o(ed\224)f(bytes)g(\(MSByte)h(\002rst\).)34 +b(F)o(or)26 b(each)g(byte)-189 2912 y(7)f(bits)f(are)h(used)g(for)g +(data)g(and)f(one)h(\(MSBit\))g(as)g(link)f(with)g(a)h(further)g(byte)g +(\(MSB)g(=)g(1)g(means)f(one)h(more)g(byte\).)47 3032 +y(Lo)n(w)f(le)n(v)o(el)g(read/write)h(of)g(bytes)f(\002lters)h +Fd(<)p Fl(CR)p Fd(>)p Fl(,)g Fd(<)p Fl(LF)p Fd(>)g Fl(and)g +Fd(<)p Fl(ctrl-Z)p Fd(>)f Fl(through)g(escape)h(sequences.)-189 +3327 y Fj(2.2)119 b(Implementation)-189 3515 y Fl(Store)24 +b(and)g(load)g(for)g(single)g(Boolean)g(functions)f(and)h(arrays)g(of)g +(Boolean)g(functions)f(are)i(implemented.)k(More-)-189 +3635 y(o)o(v)o(er)l(,)37 b(the)e(current)h(presentation)f(includes)f +(functions)h(to)g(retrie)n(v)o(e)g(v)n(ariables)f(names,)k(auxiliary)d +(identi\002erss,)-189 3756 y(and)c(all)g(the)g(information)f(contained) +h(in)f(the)h(header)h(of)f(the)h(\002les.)50 b(This)30 +b(information)g(can)h(be)h(used)f(as)g(a)g(pre-)-189 +3876 y(processing)19 b(step)g(for)i(load)e(operations.)28 +b(These)20 b(functions)f(allo)n(w)f(to)i(o)o(v)o(ercome)f(fe)n(w)g +(limitations)f(of)h(the)h(pre)n(vious)-189 3997 y(implementations.)-189 +4263 y Fi(2.2.1)99 b(Storing)25 b(Decision)g(Diagrams)-189 +4450 y Fc(Dddmp)p 111 4450 V 35 w(cuddBddStor)l(e)f Fl(and)h +Fc(Dddmp)p 1195 4450 V 35 w(cuddBddArr)o(ayStor)l(e)e +Fl(are)j(the)f(tw)o(o)f(store)h(functions,)f(used)h(to)g(store)f(sin-) +-189 4571 y(gle)f(BDD)h(or)g(a)f(forest)h(of)f(BDDs,)h(respecti)n(v)o +(ely)-6 b(.)28 b(Internally)-6 b(,)23 b Fc(Dddmp)p 2275 +4571 V 35 w(cuddBddStor)l(e)f Fl(b)n(uilds)g(a)i(dummy)e(1)h(entry)-189 +4691 y(array)j(of)e(BDDs,)h(and)g(calls)g Fc(dddmp)p +1102 4691 V 35 w(cuddBddArr)o(ayStor)l(e)p Fl(.)47 4811 +y(Since)30 b(con)l(v)o(ersion)e(from)h(DD)h(pointers)e(to)h(inte)o(ger) +f(is)h(required,)i(DD)e(nodes)g(are)h(temporarily)e(remo)o(v)o(ed)-189 +4932 y(from)23 b(the)f(unique)h(hash.)29 b(This)23 b(mak)o(es)f(room)g +(in)h(their)f Fc(ne)n(xt)h Fl(\002eld)h(to)e(store)h(node)f(IDs.)30 +b(Nodes)23 b(are)h(re-link)o(ed)e(after)-189 5052 y(the)i(store)g +(operation,)g(possible)f(in)g(a)i(modi\002ed)e(order)-5 +b(.)31 b(Dumping)22 b(is)i(either)g(in)g(te)o(xt)f(or)i(binary)f(form.) +30 b(Both)24 b(a)g(\002le)-189 5173 y(pointer)31 b(\()p +Fc(fp)p Fl(\))g(and)g(a)h(\002le)g(name)f(\()p Fc(fname)p +Fl(\))h(are)g(pro)o(vided)e(as)h(inputs)f(parameters)i(to)f(store)g +(routines.)50 b(BDDs)31 b(are)-189 5293 y(stored)c(to)g(the)g(already)g +(open)h(\002le)f Fc(fp)p Fl(,)h(if)f(not)g(NULL.)g(Otherwise)f(\002le)i +(whose)f(name)g(is)g Fc(fname)g Fl(is)g(opened.)38 b(This)-189 +5413 y(is)24 b(intended)g(to)h(allo)n(w)f(either)g(DD)h(storage)g +(within)e(\002les)i(containing)f(other)g(data,)h(or)g(to)g(speci\002c)g +(\002les.)1794 5800 y(5)p eop +%%Page: 6 6 +6 5 bop -189 218 a Fi(2.2.2)99 b(Loading)25 b(Decision)g(Diagrams)-189 +405 y Fc(Dddmp)p 111 405 30 4 v 35 w(cuddBddLoad)37 b +Fl(and)h Fc(Dddmp)p 1219 405 V 35 w(cuddBddArr)o(ayLoad)f +Fl(are)h(the)g(load)g(functions,)i(which)e(read)g(a)g(BDD)-189 +526 y(dump)24 b(\002le.)47 646 y(F)o(ollo)n(wing)34 b(the)h(store)h +(function,)h(the)f(main)f(BDD)h(load)f(function,)j Fc(Dddmp)p +2813 646 V 35 w(cuddBddLoad)p Fl(,)f(is)f(imple-)-189 +767 y(mented)g(by)g(calling)f(the)h(main)g(BDD-array)h(loading)f +(function)f Fc(Dddmp)p 2466 767 V 35 w(cuddBddArr)o(ayLoad)p +Fl(.)63 b(A)37 b(dynamic)-189 887 y(v)o(ector)24 b(of)h(DD)g(pointers)f +(is)g(temporarily)g(allocated)h(to)f(support)g(con)l(v)o(ersion)f(from) +i(DD)g(inde)o(x)o(es)e(to)h(pointers.)47 1007 y(Se)n(v)o(eral)40 +b(criteria)f(are)i(supported)d(for)i(v)n(ariable)f(match)g(between)g +(\002le)h(and)g(DD)f(manager)l(,)k(practically)-189 1128 +y(allo)n(wing)37 b(v)n(ariable)h(permutations)f(or)i(compositions)d +(while)i(loading)g(DDs.)71 b(V)-11 b(ariable)39 b(match)f(between)h +(the)-189 1248 y(DD)32 b(manager)g(and)g(the)g(BDD)g(\002le)g(is)g +(optionally)e(based)i(in)f Fc(IDs)p Fl(,)j Fc(perids)p +Fl(,)f Fc(varnames)p Fl(,)g Fc(var)o(auxids)p Fl(;)g(also)f(direct)-189 +1369 y(composition)j(between)j Fc(IDs)g Fl(and)f Fc(composeids)g +Fl(is)g(supported.)68 b(The)38 b Fc(varmatc)o(hmode)e +Fl(parameter)i(is)f(used)g(to)-189 1489 y(select)27 b(mathing)e(mode.) +37 b(More)27 b(in)f(detail,)h(tw)o(o)f(match)h(modes)f(use)h(the)f +(information)g(within)f(the)i(DD)g(manager)l(,)-189 1609 +y(the)e(other)f(ones)h(use)g(e)o(xtra)f(information,)f(which)i(support) +f(an)o(y)g(v)n(ariable)g(remap)h(or)g(change)g(in)f(the)h(ordering.)-44 +1813 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 1813 +V 35 w(V)-13 b(AR)p 1272 1813 V 35 w(MA)i(TCHIDS)19 b(allo)n(ws)f +(loading)g(a)h(DD)g(k)o(eeping)f(v)n(ariable)g(IDs)h(unchanged)55 +1933 y(\(re)o(gardless)24 b(of)h(the)f(v)n(ariable)h(ordering)f(of)h +(the)g(reading)f(manager)-5 b(.)55 2095 y(This)24 b(is)g(useful,)g(for) +h(e)o(xample,)f(when)g(sw)o(apping)g(DDs)g(to)h(\002le)g(and)f +(restoring)g(them)g(later)h(from)f(\002le,)h(after)55 +2215 y(possible)e(v)n(ariable)i(reordering)g(acti)n(v)n(ations.)-44 +2419 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 2419 +V 35 w(V)-13 b(AR)p 1272 2419 V 35 w(MA)i(TCHPERMIDS)36 +b(is)e(used)h(to)f(allo)n(w)g(v)n(ariable)g(match)h(according)55 +2539 y(to)h(the)h(position)e(in)i(the)g(ordering)f(\(retrie)n(v)o(ed)g +(by)h(array)h(of)f(permutations)e(stored)h(on)h(\002le)g(and)g(within) +55 2660 y(the)h(reading)g(DD)h(manager\).)72 b(A)38 b(possible)f +(application)h(is)g(retrie)n(ving)f(BDDs)i(stored)f(after)h(dynamic)55 +2780 y(reordering,)28 b(from)g(a)g(DD)g(manager)g(where)h(all)e(v)n +(ariable)h(IDs)f(map)h(their)f(position)g(in)g(the)h(ordering,)g(and)55 +2900 y(the)d(loaded)f(BDD)h(k)o(eeps)g(the)g(ordering)f(as)h(stored)f +(on)h(\002le.)-44 3104 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p +1040 3104 V 35 w(V)-13 b(AR)p 1272 3104 V 35 w(MA)i(TCHN)m(AMES)26 +b(requires)h(a)h(not)e(NULL)h(v)n(armatchmodes)f(param-)55 +3224 y(eter;)34 b(this)c(is)g(a)h(v)o(ector)g(of)g(strings)e(in)i +(one-to-one)f(correspondence)h(with)f(v)n(ariable)h(IDs)f(of)h(the)g +(reading)55 3344 y(manager)-5 b(.)40 b(V)-11 b(ariables)28 +b(in)g(the)g(DD)g(\002le)g(read)h(are)g(matched)f(with)f(manager)h(v)n +(ariables)f(according)h(to)g(their)55 3465 y(name)35 +b(\(a)h(not)f(NULL)g(v)n(arnames)g(parameter)h(w)o(as)f(required)h +(while)f(storing)f(the)h(DD)g(\002le\).)64 b(The)35 b(most)55 +3585 y(common)c(usage)h(of)g(this)f(feature)i(is)e(in)h(combination)e +(with)i(a)g(v)n(ariable)g(ordering)g(stored)f(on)h(a)g(\002le)h(and)55 +3706 y(based)28 b(on)h(v)n(ariables)f(names.)41 b(Names)29 +b(must)e(be)i(loaded)f(in)g(an)h(array)g(of)g(strings)e(and)i(passed)f +(to)g(the)h(DD)55 3826 y(load)24 b(procedure.)-44 4029 +y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 4029 V +35 w(V)-13 b(AR)p 1272 4029 V 35 w(MA)i(TCHIDS)25 b(has)g(a)g(meaning)f +(similar)g(to)55 4150 y(DDDMP)p 421 4150 V 36 w(V)-13 +b(AR)p 654 4150 V 35 w(MA)i(TCHN)m(AMES)26 b(b)n(ut)h(inte)o(ger)f +(auxiliary)g(IDs)h(are)h(used)f(instead)f(of)h(strings.)36 +b(The)28 b(ad-)55 4270 y(ditional)23 b(not)h(NULL)h(v)n(armathauxids)e +(parameter)i(is)g(needed.)-44 4474 y Fk(\017)49 b Fl(v)n +(armatchnode=DDDMP)p 1040 4474 V 35 w(V)-13 b(AR)p 1272 +4474 V 35 w(COMPOSEIDS,)38 b(uses)f(the)f(additional)f(v)n +(arcomposeids)g(parameter)55 4594 y(as)25 b(an)g(array)g(of)g(v)n +(ariable)f(IDs)h(to)g(be)g(composed)f(with)g(IDs)g(stored)h(in)f +(\002le.)-189 4860 y Fi(2.2.3)99 b(DD)25 b(Load/Stor)n(e)h(and)f(V)-9 +b(ariable)25 b(Ordering)-189 5048 y Fl(Loading)31 b(of)i(Decision)e +(Diagrams)h(from)g(\002le)g(supports)f(dif)n(ferent)h(v)n(ariables)g +(ordering)f(strate)o(gies,)i(as)g(already)-189 5168 y(pointed)23 +b(out)h(in)g(the)h(pre)n(vious)e(section.)30 b(This)24 +b(allo)n(ws)f(or)h(e)o(xample)g(storing)f(dif)n(ferent)i(BDDs)f(each)h +(with)f(its)g(o)n(wn)-189 5288 y(v)n(ariable)29 b(ordering,)h(and)g(to) +f(mer)n(ge)h(them)f(within)f(the)i(same)f(DD)h(manager)f(by)h(means)f +(of)g(proper)h(load)f(opera-)-189 5409 y(tions.)44 b(W)-8 +b(e)30 b(suggest)f(using)f(DDDMP)p 1175 5409 V 36 w(V)-13 +b(AR)p 1408 5409 V 36 w(MA)i(TCHIDS)30 b(whene)n(v)o(er)f(IDs)g(k)o +(eeps)h(on)f(representing)h(the)f(same)-189 5529 y(entities)24 +b(while)h(changing)f(v)n(ariable)h(ordering.)31 b(If)25 +b(this)f(is)h(not)f(true,)h(v)n(ariable)g(names)g(\(if)g(a)n(v)n +(ailable\))f(or)i(auxiliary)1794 5800 y(6)p eop +%%Page: 7 7 +7 6 bop -189 218 a Fl(IDs)34 b(are)h(a)g(good)e(w)o(ay)i(to)f +(represent)g(in)l(v)n(ariant)f(attrib)n(uted)g(of)i(v)n(ariables)e +(across)h(se)n(v)o(eral)g(runs)g(with)f(dif)n(ferent)-189 +338 y(orderings.)50 b(DDDMP)p 629 338 30 4 v 35 w(V)-13 +b(AR)p 861 338 V 36 w(COMPOSEIDS)32 b(is)f(an)h(alternati)n(v)o(e)e +(solution,)h(that)g(practically)f(corresponds)h(to)-189 +459 y(cascading)23 b(DDDMP)p 593 459 V 36 w(V)-13 b(AR)p +826 459 V 36 w(MA)i(TCHIDS)23 b(and)h(v)n(ariable)f(composition)e(with) +h(a)i(gi)n(v)o(en)e(array)i(of)g(ne)n(w)f(v)n(ariables.)-189 +797 y Fo(3)143 b(CNF)35 b(Support)-189 1050 y Fj(3.1)119 +b(F)m(ormat)-189 1237 y Fl(Gi)n(v)o(en)30 b(a)h(BDD)g(representing)g(a) +g(function)f Fd(f)11 b Fl(,)32 b(we)f(de)n(v)o(elop)f(three)h(basic)g +(possible)e(w)o(ays)i(to)g(store)f(it)h(as)g(a)g(CNF)-189 +1358 y(formula.)54 b(In)33 b(each)h(method)d(the)i(set)g(of)f(clauses)h +(is)f(written)h(after)g(an)g(header)g(part.)55 b(Only)32 +b(the)h(te)o(xt)f(format)g(is)-189 1478 y(allo)n(wed.)-189 +1743 y Fi(3.1.1)99 b(Header)-189 1931 y Fl(The)23 b(header)h(part)f(of) +g(each)h(CNF)g(\002le)f(has)g(basically)g(the)f(same)h(format)g +(analyzed)g(for)h(the)f(BDD/ADD)g(\002les.)30 b(F)o(or)-189 +2051 y(e)o(xample)h(the)g Fg(.rootids)f Fl(line)h(indicates)f(the)i(be) +o(ginning)d(of)j(each)g(CNF)g(formula)f(represented)h(by)f(a)h(single) +-189 2172 y(BDD.)j(T)-8 b(o)34 b(be)g(compatible)f(with)h(the)g(DIMA)l +(CS)h(format)f(each)h(header)f(line)g(start)g(with)g(the)g(character)h +(\223c\224)g(to)-189 2292 y(indicate)24 b(a)h(comment.)-189 +2557 y Fi(3.1.2)99 b(T)-9 b(ext)25 b(F)n(ormat)-189 2745 +y Fl(The)j(\002rst)g(method,)g(which)f(we)h(call)g Fi(Single-Node-Cut)p +Fl(,)j(models)26 b(each)j(BDD)f(nodes,)h(b)n(ut)e(the)h(ones)f(with)h +(both)-189 2865 y(the)c(children)g(equal)h(to)f(the)g(constant)g(node)g +Fb(1)p Fl(,)g(as)h(a)g(multiple)o(x)o(er)-5 b(.)27 b(Each)e(multiple)o +(x)o(er)d(has)i(tw)o(o)g(data)h(inputs)e(\(i.e.,)-189 +2985 y(the)k(node)h(children\),)f(a)h(selection)f(input)f(\(i.e.,)i +(the)g(node)f(v)n(ariable\))g(and)h(one)f(output)f(\(i.e.,)i(the)g +(function)e(v)n(alue\))-189 3106 y(whose)h(v)n(alue)f(is)h(assigned)f +(to)h(an)g(additional)f(CNF)i(v)n(ariable.)37 b(The)27 +b(\002nal)h(number)e(of)h(v)n(ariables)g(is)f(equal)h(to)g(the)-189 +3226 y(number)d(of)h(original)f(BDD)h(v)n(ariables)f(plus)g(the)h +(number)f(of)h(\223internal\224)g(nodes)f(of)h(the)g(BDD.)47 +3346 y(The)k(second)f(method,)g(which)h(we)f(call)h Fi(Maxterm-Cut)p +Fl(,)h(create)g(clauses)e(starting)g(from)g Fd(f)39 b +Fl(corresponds)-189 3467 y(to)25 b(the)h(of)n(f-set)g(\(i.e.,)f(all)h +(the)g(paths-cubes)f(from)g(the)h(root)g(node)f(to)h(the)f(terminal)g +Fg(0)p Fl(\))h(of)g(the)g(function)e Fd(f)11 b Fl(.)34 +b(W)l(ithin)-189 3587 y(the)29 b(BDD)g(for)g Fd(f)11 +b Fl(,)30 b(such)f(clauses)f(are)i(found)e(by)h(follo)n(wing)e(all)i +(the)f(paths)h(from)f(the)h(root)g(node)f(of)h(the)g(BDD)g(to)-189 +3708 y(the)c(constant)f(node)g Fb(0)p Fl(.)31 b(The)25 +b(\002nal)g(number)f(of)h(v)n(ariables)f(is)g(equal)h(to)f(the)h +(number)f(of)h(original)f(BDD)h(v)n(ariables.)47 3828 +y(The)k(third)g(method,)g(which)g(we)g(call)g Fi(A)-5 +b(uxiliary-V)c(ariable-Cut)p Fl(,)30 b(is)f(a)h(trade-of)n(f)f(between) +g(the)g(\002rst)g(tw)o(o)-189 3948 y(strate)o(gies.)69 +b(Internal)37 b(v)n(ariables,)j(i.e.,)h(cutting)c(points,)j(are)e +(added)g(in)f(order)h(to)g(decompose)f(the)h(BDD)g(into)-189 +4069 y(multiple)27 b(sub-trees)i(each)h(of)f(which)f(is)h(stored)g +(follo)n(wing)e(the)h(second)h(strate)o(gy)-6 b(.)42 +b(The)29 b(trade-of)n(f)g(is)g(guided)f(by)-189 4189 +y(the)23 b(cutting)f(point)g(selection)g(strate)o(gy)-6 +b(,)22 b(and)h(we)g(e)o(xperiment)f(with)g(tw)o(o)g(methodologies.)28 +b(In)23 b(the)g(\002rst)g(method,)g(a)-189 4310 y(ne)n(w)f(CNF)h(v)n +(ariable)f(is)f(inserted)h(in)g(correspondence)g(to)g(the)g(shared)g +(nodes)g(of)g(the)h(BDD,)f(i.e.,)h(the)f(nodes)f(which)-189 +4430 y(ha)n(v)o(e)29 b(more)g(than)h(one)f(incoming)f(edge.)45 +b(This)29 b(technique,)h(albeit)e(optimizing)g(the)h(number)g(of)h +(literals)e(stored,)-189 4550 y(can)35 b(produce)g(clauses)f(with)g(a)h +(high)f(number)h(of)f(literals)1894 4514 y Fh(2)1933 +4550 y Fl(.)60 b(T)-8 b(o)35 b(a)n(v)n(oid)f(this)g(dra)o(wback,)j(the) +e(second)f(method,)-189 4671 y(introduces)28 b(all)g(the)g(pre)n +(viously)e(indicated)i(cutting)f(points)g(more)h(the)h(ones)f +(necessary)g(to)g(break)h(the)f(length)g(of)-189 4791 +y(the)d(path)f(to)h(a)g(maximum)e(\(user\))i(selected)g(v)n(alue.)47 +4911 y(Actually)-6 b(,)37 b(all)f(the)f(methods)g(described)h(abo)o(v)o +(e)e(can)j(be)e(re-conducted)h(to)g(the)f(basic)h(idea)g(of)g(possibly) +-189 5032 y(breaking)24 b(the)h(BDD)g(through)f(the)g(use)h(of)f +(additional)g(cutting)f(v)n(ariables)h(and)h(dumping)e(the)h(paths)g +(between)h(the)-189 5152 y(root)34 b(of)h(the)f(BDD,)h(the)g(cutting)e +(v)n(ariables)h(and)g(the)h(terminal)e(nodes.)60 b(Such)35 +b(internal)f(cutting)f(v)n(ariables)h(are)-189 5273 y(added)25 +b(al)o(w)o(ays)f(\(for)i(each)f(node\),)g(ne)n(v)o(er)f(or)h(sometimes) +e(respecti)n(v)o(ely)-6 b(.)p -189 5360 1607 4 v -77 +5422 a Ff(2)-40 5452 y Fe(This)27 b(v)n(alue)f(is)i(superiorly)d +(limited)h(by)g(the)h(number)e(of)h(v)n(ariables)g(of)g(the)h(BDD,)g +(i.e.,)h(the)f(longest)f(path)g(from)g(the)h(root)f(to)g(the)-189 +5551 y(terminal)19 b(node.)1794 5800 y Fl(7)p eop +%%Page: 8 8 +8 7 bop 47 218 a Fl(While)33 b(the)f Fc(Single-Node-Cut)h +Fl(method)f(minimizes)f(the)i(length)f(of)h(the)f(clauses)h(produced,)i +(b)n(ut)d(it)g(also)-189 338 y(requires)d(the)h(higher)f(number)g(of)g +(CNF)i(v)n(ariables,)e(the)h Fc(Maxterm-Cut)f Fl(technique)g(minimizes) +f(the)h(number)g(of)-189 459 y(CNF)36 b(v)n(ariables)d(required.)61 +b(This)34 b(adv)n(antage)g(is)g(counter)n(-balanced)h(by)f(the)h(f)o +(act)g(that)f(in)g(the)h(w)o(orst)f(case)h(the)-189 579 +y(number)23 b(of)g(clauses,)g(as)h(well)e(as)i(the)f(total)f(number)h +(of)g(literals,)g(produced)g(is)g(e)o(xponential)e(in)i(the)g(BDD)h +(size)f(\(in)-189 699 y(terms)28 b(of)i(number)e(of)h(nodes\).)43 +b(The)29 b(application)f(of)h(this)f(method)g(is)g(then)h(limited)e(to) +i(the)g(cases)g(in)f(which)h(the)-189 820 y(\223of)n(f-set\224)c(of)f +(the)g(represented)h(function)f Fd(f)35 b Fl(has)24 b(a)h(small)f +(cardinality)-6 b(.)29 b(The)c Fc(A)n(uxiliary-V)-11 +b(ariable-Cut)22 b Fl(strate)o(gy)h(is)-189 940 y(a)k(trade-of)n(f)h +(between)f(the)g(\002rst)g(tw)o(o)g(methods)f(and)h(the)g(ones)f(which) +h(gi)n(v)o(es)f(more)h(compact)f(results.)37 b(As)27 +b(a)h(\002nal)-189 1061 y(remark)f(notice)e(that)h(the)g(method)g(is)f +(able)i(to)f(store)g(both)f(monolithic)f(BDDs)j(and)f(conjuncti)n(v)o +(e)e(forms.)35 b(In)26 b(each)-189 1181 y(case)f(we)g(generate)h(CNF)f +(\002les)g(using)f(the)h(standard)f(DIMA)l(CS)i(format.)-189 +1365 y Fi(Example)f(1)49 b Fc(F)l(igur)l(e)20 b(1)h(shows)f(an)h(e)n +(xample)g(of)f(how)h(our)f(pr)l(ocedur)l(e)h(works)f(to)h(stor)l(e)f(a) +h(small)f(monolithic)f(BDD.)-189 1486 y(F)l(igur)l(e)j(1\(a\))h(r)l +(epr)l(esents)g(a)g(BDD)g(with)g Fb(4)g Fc(nodes.)30 +b(BDD)23 b(variables)f(ar)l(e)h(named)g(after)f(inte)l(g)o(er)g(number) +o(s)h(r)o(anging)-189 1606 y(fr)l(om)k Fb(1)h Fc(to)g +Fb(4)p Fc(,)h(to)f(have)g(an)g(easy-to-follow)f(corr)l(espondence)h +(with)g(the)g(CNF)h(variables.)40 b(F)l(igur)l(e)27 b(1\(b\),)i(\(c\))g +(and)-189 1727 y(\(d\))c(show)g(the)f(corr)l(esponding)f(CNF)j(r)l(epr) +l(esentations)d(g)o(ener)o(ated)h(by)h(our)f(thr)l(ee)h(methods.)30 +b(As)24 b(in)h(the)f(standar)l(d)-189 1847 y(format)i +Fa(p)i Fc(indicates)e(the)h(total)f(number)g(of)h(variables)f(used)h +(\()p Fb(4)g Fc(is)g(the)g(minimum)f(value)h(as)g(the)g(BDD)g(itself)f +(has)-189 1967 y Fb(4)f Fc(variables\),)e(and)i Fa(cnf)g +Fc(the)f(total)g(number)g(of)h(clauses.)47 2088 y(As)i(a)g(\002nal)f(r) +l(emark)h(notice)f(that)g(for)g(this)g(speci\002c)h(e)n(xample)g(the)f +(\223Maxterm-Cut\224)i(appr)l(oac)o(h)d(is)h(the)h(one)-189 +2208 y(whic)o(h)36 b(gives)g(the)g(most)f(compact)h(CNF)h(r)l(epr)l +(esentation)e(b)n(ut)h(also)f(the)h(clause)g(with)g(the)g(lar)l(g)o +(est)g(number)f(of)-189 2328 y(liter)o(als)23 b(\()p +Fb(4)p Fc(\).)188 2471 y + 6339814 10777681 0 0 11709153 19997655 startTexFig + 188 2471 a +%%BeginDocument: bdd.eps +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: bdd.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3c +%%CreationDate: Mon Sep 9 14:21:26 2002 +%%For: quer@pcsq (Stefano Quer) +%%BoundingBox: 0 0 178 304 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 304 moveto 0 0 lineto 178 0 lineto 178 304 lineto closepath clip newpath +-51.0 319.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawEllipse { + /endangle exch def + /startangle exch def + /yrad exch def + /xrad exch def + /y exch def + /x exch def + /savematrix mtrx currentmatrix def + x y tr xrad yrad sc 0 0 1 startangle endangle arc + closepath + savematrix setmatrix + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06299 0.06299 sc +% +% Fig objects follow +% +% Polyline +15.000 slw +n 2010 4515 m 2550 4515 l 2550 5040 l 2010 5040 l + cp gs col0 s gr +/Times-Roman ff 300.00 scf sf +2205 4875 m +gs 1 -1 sc (1) col0 sh gr +% Ellipse +n 1515 1800 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2250 900 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2970 2715 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2280 3705 270 270 0 360 DrawEllipse gs col0 s gr + +7.500 slw +% Ellipse +n 3555 3555 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2712 1726 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2430 4230 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Polyline +15.000 slw +n 2805 2910 m + 2250 3450 l gs col0 s gr +% Polyline + [90] 0 sd +gs clippath +2940 2472 m 3010 2445 l 2931 2239 l 2957 2411 l 2861 2266 l cp +eoclip +n 2460 1110 m + 2970 2445 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 2861 2266 m 2957 2411 l 2931 2239 l 2908 2284 l 2861 2266 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +1478 1511 m 1528 1568 l 1693 1422 l 1542 1506 l 1643 1366 l cp +eoclip +n 2025 1080 m + 1515 1530 l gs col0 s gr gr + +% arrowhead +n 1643 1366 m 1542 1506 l 1693 1422 l 1643 1416 l 1643 1366 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +2212 645 m 2287 645 l 2287 425 l 2250 594 l 2212 425 l cp +eoclip +n 2250 270 m + 2250 630 l gs col0 s gr gr + +% arrowhead +n 2212 425 m 2250 594 l 2287 425 l 2250 459 l 2212 425 l + cp gs 0.00 setgray ef gr col0 s +% Polyline + [90] 0 sd +gs clippath +2692 2664 m 2732 2601 l 2546 2485 l 2670 2606 l 2506 2548 l cp +eoclip +n 1710 2010 m + 2700 2625 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 2506 2548 m 2670 2606 l 2546 2485 l 2555 2534 l 2506 2548 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj + [90] 0 sd +gs clippath +2504 4653 m 2539 4720 l 2733 4616 l 2567 4663 l 2698 4550 l cp +eoclip +n 3180 2910 m 3181 2911 l 3183 2913 l 3186 2916 l 3192 2921 l 3200 2929 l + 3210 2939 l 3223 2951 l 3238 2966 l 3255 2984 l 3274 3003 l + 3295 3025 l 3317 3049 l 3339 3075 l 3362 3103 l 3385 3131 l + 3407 3161 l 3429 3192 l 3450 3225 l 3470 3258 l 3488 3293 l + 3504 3329 l 3519 3367 l 3531 3406 l 3541 3447 l 3548 3490 l + 3552 3536 l 3552 3583 l 3548 3634 l 3540 3686 l 3528 3740 l + 3510 3795 l 3490 3844 l 3467 3892 l 3441 3939 l 3413 3985 l + 3382 4028 l 3350 4070 l 3317 4110 l 3283 4148 l 3248 4184 l + 3211 4219 l 3174 4253 l 3136 4285 l 3098 4316 l 3059 4347 l + 3020 4376 l 2980 4405 l 2941 4432 l 2901 4459 l 2862 4484 l + 2824 4509 l 2787 4532 l 2751 4554 l 2717 4575 l 2686 4593 l + 2657 4610 l 2631 4626 l 2608 4639 l 2589 4650 l 2572 4659 l + 2559 4666 l 2550 4672 l + 2535 4680 l gs col0 s gr gr + [] 0 sd +% arrowhead +0 slj +n 2698 4550 m 2567 4663 l 2733 4616 l 2686 4599 l 2698 4550 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +1985 4734 m 2028 4672 l 1847 4548 l 1965 4675 l 1804 4609 l cp +eoclip +n 1350 2025 m 1349 2026 l 1348 2027 l 1345 2030 l 1340 2035 l 1334 2042 l + 1325 2051 l 1314 2063 l 1301 2078 l 1286 2095 l 1268 2114 l + 1249 2137 l 1227 2161 l 1205 2188 l 1181 2218 l 1156 2249 l + 1131 2282 l 1105 2316 l 1080 2352 l 1054 2390 l 1029 2428 l + 1005 2468 l 981 2509 l 959 2552 l 938 2595 l 918 2640 l + 900 2687 l 884 2736 l 870 2786 l 858 2839 l 848 2894 l + 841 2951 l 837 3011 l 836 3074 l 838 3139 l 845 3206 l + 855 3275 l 870 3345 l 888 3412 l 910 3477 l 934 3542 l + 961 3604 l 990 3665 l 1022 3723 l 1054 3779 l 1088 3833 l + 1124 3885 l 1160 3935 l 1198 3983 l 1236 4029 l 1275 4074 l + 1315 4118 l 1356 4160 l 1397 4201 l 1438 4241 l 1480 4280 l + 1522 4318 l 1563 4355 l 1605 4390 l 1645 4424 l 1685 4457 l + 1723 4488 l 1760 4517 l 1795 4545 l 1827 4570 l 1857 4593 l + 1884 4613 l 1909 4632 l 1930 4647 l 1947 4660 l 1962 4671 l + 1973 4679 l 1982 4686 l + 1995 4695 l gs col0 s gr gr + +% arrowhead +0 slj +n 1804 4609 m 1965 4675 l 1847 4548 l 1854 4598 l 1804 4609 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj + [90] 0 sd +gs clippath +2300 4492 m 2363 4532 l 2481 4347 l 2359 4470 l 2417 4307 l cp +eoclip +n 2340 3960 m 2341 3962 l 2344 3966 l 2348 3973 l 2354 3982 l 2362 3995 l + 2370 4010 l 2379 4028 l 2389 4046 l 2397 4066 l 2406 4088 l + 2413 4111 l 2420 4137 l 2425 4165 l 2429 4197 l 2430 4230 l + 2429 4263 l 2425 4295 l 2420 4323 l 2413 4349 l 2406 4372 l + 2397 4394 l 2389 4414 l 2379 4433 l 2370 4450 l 2362 4465 l + 2354 4478 l + 2340 4500 l gs col0 s gr gr + [] 0 sd +% arrowhead +0 slj +n 2417 4307 m 2359 4470 l 2481 4347 l 2431 4356 l 2417 4307 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +2136 4532 m 2199 4492 l 2082 4307 l 2141 4470 l 2018 4347 l cp +eoclip +n 2160 3960 m 2159 3962 l 2156 3966 l 2152 3973 l 2146 3982 l 2138 3995 l + 2130 4010 l 2121 4028 l 2111 4046 l 2103 4066 l 2094 4088 l + 2087 4111 l 2080 4137 l 2075 4165 l 2071 4197 l 2070 4230 l + 2071 4263 l 2075 4295 l 2080 4323 l 2087 4349 l 2094 4372 l + 2103 4394 l 2111 4414 l 2121 4433 l 2130 4450 l 2138 4465 l + 2146 4478 l + 2160 4500 l gs col0 s gr gr + +% arrowhead +0 slj +n 2018 4347 m 2141 4470 l 2082 4307 l 2068 4356 l 2018 4347 l + cp gs 0.00 setgray ef gr col0 s +/Times-Roman ff 300.00 scf sf +2175 990 m +gs 1 -1 sc (1) col0 sh gr +/Times-Roman ff 300.00 scf sf +1440 1890 m +gs 1 -1 sc (2) col0 sh gr +/Times-Roman ff 300.00 scf sf +2895 2805 m +gs 1 -1 sc (3) col0 sh gr +/Times-Roman ff 300.00 scf sf +2205 3795 m +gs 1 -1 sc (4) col0 sh gr +$F2psEnd +rs + +%%EndDocument + + endTexFig + 531 3990 a Fc(\(a\))1512 2504 y Fg(p)60 b(cnf)f(7)g(11)1512 +2624 y(-5)g(3)h(0)1512 2745 y(-5)f(4)h(0)1512 2865 y(5)g(-3)f(-4)g(0) +1512 2985 y(6)h(-2)f(0)1512 3106 y(6)h(-5)f(0)1512 3226 +y(-6)g(2)h(5)f(0)1512 3347 y(7)h(1)f(5)h(0)1512 3467 +y(-7)f(1)h(-5)f(0)1512 3587 y(7)h(-1)f(-6)g(0)1512 3708 +y(-7)g(-1)h(6)f(0)1512 3828 y(7)h(0)1836 3990 y Fc(\(b\))2541 +2525 y Fg(p)f(cnf)g(4)h(3)2541 2645 y(1)f(-3)h(-4)f(0)2541 +2766 y(-1)g(2)h(3)f(0)2541 2886 y(-1)g(2)h(-3)f(4)h(0)2868 +3048 y Fc(\(c\))2541 3251 y Fg(p)f(cnf)g(5)h(5)2541 3371 +y(-5)f(1)h(0)2541 3492 y(5)f(-1)h(2)f(0)2541 3612 y(-3)g(-4)g(5)h(0) +2541 3733 y(3)f(-5)h(0)2541 3853 y(-3)f(4)h(-5)f(0)2865 +3990 y Fc(\(d\))-189 4138 y Fl(Figure)46 b(1:)71 b(\(a\))47 +b(BDD;)e(\(b\))h(\223Single-Node-Cut\224)g(format;)55 +b(\(c\))46 b(\223Maxterm-Cut\224)g(format;)55 b(\(d\))45 +b(\223)-8 b(Auxiliary-)-189 4258 y(V)d(ariable-Cut\224)25 +b(F)o(ormat.)-189 4625 y Fj(3.2)119 b(Implementation)-189 +4813 y Fl(Store)25 b(and)g(Load)g(for)g(a)g(single)f(BDD)h(or)g(a)g +(forest)g(of)g(BDDs)g(is)f(currently)h(implemented.)-189 +5073 y Fi(3.2.1)99 b(Storing)25 b(Decision)g(Diagrams)f(as)g(CNF)h(F)n +(ormulas)-189 5260 y Fl(As)g(f)o(ar)g(as)g(the)g(storing)e(process)i +(is)f(concerned)i(three)f(possible)e(formats)h(are)i(a)n(v)n(ailable:) +-44 5431 y Fk(\017)49 b Fl(DDDMP)p 421 5431 30 4 v 36 +w(CNF)p 650 5431 V 36 w(MODE)p 980 5431 V 35 w(NODE:)21 +b(store)f(a)h(BDD)h(by)e(introducing)f(an)i(auxiliary)g(v)n(ariable)f +(for)h(each)g(BDD)55 5551 y(node)1794 5800 y(8)p eop +%%Page: 9 9 +9 8 bop -44 218 a Fk(\017)49 b Fl(DDDMP)p 421 218 30 +4 v 36 w(CNF)p 650 218 V 36 w(MODE)p 980 218 V 35 w(MAXTERM:)20 +b(store)g(a)h(BDD)h(by)e(follo)n(wing)f(the)h(maxterm)g(of)h(the)g +(represented)55 338 y(function)-44 542 y Fk(\017)49 b +Fl(DDDMP)p 421 542 V 36 w(CNF)p 650 542 V 36 w(MODE)p +980 542 V 35 w(BEST)-5 b(:)32 b(trade-of)f(between)h(the)f(tw)o(o)f +(pre)n(vious)g(solution,)h(trying)f(to)h(optimize)55 +662 y(the)25 b(number)f(of)h(literals)f(stored.)-189 +865 y(See)c(procedures)f(Dddmp)p 736 865 V 35 w(cuddBddStoreCnf)g(\(to) +g(store)f(a)h(single)f(BDD)i(as)e(a)i(CNF)f(formula\))g(and)g(Dddmp)p +3609 865 V 34 w(cuddBddArrayStoreCnf)-189 986 y(\(to)25 +b(store)f(an)h(array)h(of)f(BDDs)g(as)f(a)i(CNF)f(formula\).)-189 +1252 y Fi(3.2.2)99 b(Loadinf)26 b(CNF)e(F)n(ormulas)g(as)h(BDDs)-189 +1439 y Fl(As)g(f)o(ar)g(as)g(the)g(loading)e(process)i(is)f(concerned)i +(three)f(possible)e(formats)i(are)g(a)n(v)n(ailable:)-44 +1643 y Fk(\017)49 b Fl(DDDMP)p 421 1643 V 36 w(CNF)p +650 1643 V 36 w(MODE)p 980 1643 V 35 w(NO)p 1159 1643 +V 36 w(CONJ:)25 b(Return)g(the)f(Clauses)h(without)f(Conjunction)-44 +1846 y Fk(\017)49 b Fl(DDDMP)p 421 1846 V 36 w(CNF)p +650 1846 V 36 w(MODE)p 980 1846 V 35 w(NO)p 1159 1846 +V 36 w(Q)o(U)l(ANT)-5 b(:)24 b(Return)h(the)g(sets)f(of)h(BDDs)g +(without)f(Quanti\002cation)-44 2050 y Fk(\017)49 b Fl(DDDMP)p +421 2050 V 36 w(CNF)p 650 2050 V 36 w(MODE)p 980 2050 +V 35 w(CONJ)p 1264 2050 V 36 w(Q)o(U)l(ANT)-5 b(:)23 +b(Return)h(the)g(sets)f(of)h(BDDs)g(AFTER)g(Existential)e(Quanti\002-) +55 2170 y(cation)-189 2373 y(See)e(procedures)f(Dddmp)p +736 2373 V 35 w(cuddBddLoadCnf)f(\(to)h(load)f(a)i(CNF)f(formula)g(as)g +(a)g(single)f(BDD\))h(and)g(Dddmp)p 3581 2373 V 35 w +(cuddBddArrayLoadCnf)-189 2494 y(\(to)35 b(load)h(a)g(CNF)g(formula)f +(as)h(an)g(array)g(of)g(BDDs\).)63 b(See)36 b(also)g(Dddmp)p +2485 2494 V 34 w(cuddHeaderLoadCnf)h(to)e(load)g(the)-189 +2614 y(header)25 b(of)g(a)g(CNF)h(\002le)f(to)g(gather)f(information)f +(on)i(the)g(sa)n(v)o(ed)f(structure.)-189 2954 y Fo(4)143 +b(T)-13 b(est)35 b(Pr)m(ogram)f(and)h(Regr)m(ession)f(T)-13 +b(ests)-189 3177 y Fl(The)20 b Fc(testddmp.c)e Fl(\002le,)j(pro)o +(vided)d(with)h(this)f(distrib)n(ution,)g(e)o(x)o(empli\002es)g(some)h +(of)h(the)f(abo)o(v)o(e)g(features.)29 b(Moreo)o(v)o(er)l(,)-189 +3298 y(in)d(the)h Fc(e)n(xp)g Fl(e)o(xperiments)e(a)j(fe)n(w)e +(scripts,)h(named)f Fc(test\241n\277.script)f Fl(are)i(a)n(v)n(ailable) +f(for)h(a)g(sanity)f(check)h(of)g(the)g(tool)-189 3418 +y(and)e(to)f(tak)o(e)h(a)g(look)f(at)h(some)f(runs)h(e)o(x)o +(empli\002cation.)-189 3758 y Fo(5)143 b(Documentation)-189 +3981 y Fl(F)o(or)27 b(further)f(documentation)f(on)i(the)f(package)h +(see)g(the)g(on-line)f(documentation)f(automatically)g(created)i(from) +-189 4102 y(the)e(source)g(code)g(\002les.)-189 4441 +y Fo(6)143 b(Ackno)o(wledgments)-189 4665 y Fl(W)-8 b(e)19 +b(are)h(particular)f(indebted)f(with)g(F)o(abio)g(Somenzi,)i(for)f +(discussions,)f(advice,)i(and)f(for)g(including)e(the)i(DDDMP)-189 +4785 y(package)28 b(into)f(the)h(CUDD)g(distrib)n(ution.)37 +b(W)-8 b(e)29 b(also)e(thank)g(all)h(the)g(user)g(of)g(the)f(package)i +(for)f(their)f(useful)h(indi-)-189 4905 y(cation)c(and)h(comments)f(on) +g(the)h(it.)1794 5800 y(9)p eop +%%Page: 10 10 +10 9 bop -189 218 a Fo(7)143 b(FTP)35 b(Site)-189 441 +y Fl(The)25 b(package)g(is)f(singularly)g(a)n(v)n(ailable)g(from:)-189 +645 y Fg(site:)59 b(ftp.polito.it)-189 765 y(user:)g(anonymous)-189 +885 y(directory:)f(/pub/research/dddmp)-189 1089 y Fl(or)25 +b(directly)f(from)h(the)f(author)h(WEB)g(pages:)-189 +1292 y Fg(WWW:)59 b(http://www.polito.it/\230{cabodi)o(,quer)o(})-189 +1632 y Fo(8)143 b(F)l(eedback)-189 1855 y Fl(Send)25 +b(feedback)h(to:)-189 2059 y Fg(Gianpiero)58 b(Cabodi)g(&)i(Stefano)e +(Quer)-189 2179 y(Politecnico)f(di)j(Torino)-189 2300 +y(Dipartimento)d(di)i(Automatica)f(e)i(Informatica)-189 +2420 y(Corso)f(Duca)g(degli)f(Abruzzi,)g(24)-189 2540 +y(I-10129)g(Torino)-189 2661 y(Italy)-189 2781 y(E-mail:)g +({cabodi,quer}@polito.it)-189 2901 y(WWW:)h +(http://www.polito.it/\230{cabodi)o(,quer)o(})1769 5800 +y Fl(10)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmp-2.0-Letter.ps b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmp-2.0-Letter.ps new file mode 100644 index 000000000..ad51df7c2 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmp-2.0-Letter.ps @@ -0,0 +1,1260 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software +%%Title: dddmp-2.0.dvi +%%Pages: 10 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%DocumentFonts: Times-Bold Times-Roman Courier Times-Italic Helvetica +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -t letter -f dddmp-2.0 +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2002.12.11:0557 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", +% version = "0.6", +% date = "22 June 1996", +% filename = "8r.enc", +% email = "kb@@mail.tug.org", +% address = "135 Center Hill Rd. // Plymouth, MA 02360", +% codetable = "ISO/ASCII", +% checksum = "119 662 4424", +% docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." +% @} +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both ASCII and Windows. +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there down to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics +exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub +dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} +ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict +end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ +dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 +roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def +dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} +if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} +def end + +%%EndProcSet +%%BeginProcSet: special.pro +%! +TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N +/vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N +/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N +/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ +/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho +X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B +/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ +/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known +{userdict/md get type/dicttype eq{userdict begin md length 10 add md +maxlength ge{/md md dup length 20 add dict copy def}if end md begin +/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S +atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ +itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll +transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll +curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf +pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} +if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 +-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 +get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip +yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub +neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ +noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop +90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get +neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr +1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr +2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 +-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S +TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ +Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale +}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState +save N userdict maxlength dict begin/magscale true def normalscale +currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts +/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x +psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx +psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub +TR/showpage{}N/erasepage{}N/copypage{}N/p 3 def @MacSetUp}N/doclip{ +psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 +roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath +moveto}N/endTexFig{end psf$SavedState restore}N/@beginspecial{SDict +begin/SpecialSave save N gsave normalscale currentpoint TR +@SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{ +CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto +closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx +sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR +}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse +CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury +lineto closepath clip}if/showpage{}N/erasepage{}N/copypage{}N newpath}N +/@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{end} +repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N +/@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX +currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY +moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X +/yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0 +1 startangle endangle arc savematrix setmatrix}N end + +%%EndProcSet +TeXDict begin 40258431 52099146 1000 600 600 (dddmp-2.0.dvi) +@start /Fa 143[55 1[55 7[28 2[50 99[{TeXBase1Encoding ReEncodeFont}4 +99.6264 /Helvetica rf +%DVIPSBitmapFont: Fb cmr12 12 3 +/Fb 3 53 df<14FF010713E090381F81F890383E007C01FC133F4848EB1F8049130F4848 +EB07C04848EB03E0A2000F15F0491301001F15F8A2003F15FCA390C8FC4815FEA54815FF +B3A46C15FEA56D1301003F15FCA3001F15F8A26C6CEB03F0A36C6CEB07E0000315C06D13 +0F6C6CEB1F806C6CEB3F00013E137C90381F81F8903807FFE0010090C7FC28447CC131> +48 D<143014F013011303131F13FFB5FC13E713071200B3B3B0497E497E007FB6FCA320 +4278C131>I52 D E +%EndDVIPSBitmapFont +/Fc 64[50 29[39 12[55 55 25[44 44 66 44 50 28 39 39 1[50 +50 50 72 28 44 1[28 50 50 28 44 50 44 50 50 10[61 2[50 +4[66 83 55 2[33 2[61 1[72 66 61 61 15[50 2[25 33 25 2[33 +33 37[50 2[{TeXBase1Encoding ReEncodeFont}45 99.6264 +/Times-Italic rf +%DVIPSBitmapFont: Fd cmmi12 12 3 +/Fd 3 103 df60 D<127012FCB4FCEA7FC0EA1FF0EA +07FCEA01FF38007FC0EB1FF0EB07FE903801FF809038007FE0EC1FF8EC03FE913800FF80 +ED3FE0ED0FF8ED03FF030013C0EE3FF0EE0FFCEE01FF9338007FC0EF1FF0EF07FCEF01FF +9438007FC0F01FE0A2F07FC0943801FF00EF07FCEF1FF0EF7FC04C48C7FCEE0FFCEE3FF0 +EEFFC0030390C8FCED0FF8ED3FE0EDFF80DA03FEC9FCEC1FF8EC7FE0903801FF80D907FE +CAFCEB1FF0EB7FC04848CBFCEA07FCEA1FF0EA7FC048CCFC12FC12703B3878B44C>62 +D102 +D E +%EndDVIPSBitmapFont +/Fe 134[42 2[42 42 23 32 28 1[42 42 42 65 23 2[23 42 +42 28 37 42 1[42 37 12[51 10[28 4[60 1[55 19[21 28 21 +44[{TeXBase1Encoding ReEncodeFont}26 83.022 /Times-Roman +rf +%DVIPSBitmapFont: Ff cmr7 7 2 +/Ff 2 51 df<13381378EA01F8121F12FE12E01200B3AB487EB512F8A215267BA521>49 +D<13FF000313E0380E03F0381800F848137C48137E00787F12FC6CEB1F80A4127CC7FC15 +005C143E147E147C5C495A495A5C495A010EC7FC5B5B903870018013E0EA018039030003 +0012065A001FB5FC5A485BB5FCA219267DA521>I E +%EndDVIPSBitmapFont +/Fg 103[60 26[60 1[60 60 60 60 60 60 60 60 60 60 60 60 +60 60 60 60 2[60 60 60 60 60 60 60 60 60 3[60 1[60 3[60 +60 1[60 60 1[60 60 1[60 60 3[60 1[60 1[60 60 60 1[60 +60 1[60 1[60 1[60 60 60 60 60 60 60 60 60 60 60 60 60 +60 60 5[60 38[{TeXBase1Encoding ReEncodeFont}62 99.6264 +/Courier rf +%DVIPSBitmapFont: Fh cmr8 8 2 +/Fh 2 51 df<130C133C137CEA03FC12FFEAFC7C1200B3B113FE387FFFFEA2172C7AAB23 +>49 DI E +%EndDVIPSBitmapFont +/Fi 105[50 28[50 50 2[55 33 39 44 1[55 50 55 83 28 2[28 +1[50 33 44 55 44 55 50 10[72 1[66 55 3[78 72 94 66 3[78 +1[61 66 72 72 66 72 13[50 50 50 1[28 25 33 45[{ +TeXBase1Encoding ReEncodeFont}40 99.6264 /Times-Bold +rf /Fj 139[40 1[53 1[66 60 66 100 33 2[33 3[53 3[60 23[47 +2[73 18[60 60 60 2[30 46[{TeXBase1Encoding ReEncodeFont}16 +119.552 /Times-Bold rf +%DVIPSBitmapFont: Fk cmsy10 12 1 +/Fk 1 16 df<49B4FC010F13E0013F13F8497F48B6FC4815804815C04815E04815F0A248 +15F8A24815FCA3B712FEA96C15FCA36C15F8A26C15F0A26C15E06C15C06C15806C15006C +6C13FC6D5B010F13E0010190C7FC27277BAB32>15 D E +%EndDVIPSBitmapFont +/Fl 64[44 42[44 44 24[44 50 50 72 50 50 28 39 33 50 50 +50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 6[61 1[72 +94 72 72 61 55 66 72 55 72 72 89 61 1[39 33 72 72 55 +61 72 66 66 72 3[56 1[28 28 50 50 50 50 50 50 50 50 50 +50 28 25 33 25 2[33 33 36[55 55 2[{TeXBase1Encoding ReEncodeFont}74 +99.6264 /Times-Roman rf +%DVIPSBitmapFont: Fm cmsy10 14.4 2 +/Fm 2 104 df102 +DI E +%EndDVIPSBitmapFont +/Fn 105[60 27[53 4[60 33 47 40 60 60 60 60 93 33 2[33 +1[60 40 53 60 53 60 53 7[86 4[73 66 1[86 66 3[73 2[40 +1[86 1[73 86 80 1[86 110 5[33 60 4[60 1[60 60 60 1[30 +40 30 44[{TeXBase1Encoding ReEncodeFont}42 119.552 /Times-Roman +rf /Fo 136[104 1[80 48 56 64 1[80 72 80 120 40 80 1[40 +1[72 1[64 80 64 80 72 12[96 80 104 1[88 1[104 135 3[56 +2[88 1[104 104 96 104 6[48 1[72 72 72 72 72 72 72 72 +72 1[36 46[{TeXBase1Encoding ReEncodeFont}41 143.462 +/Times-Bold rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin +%%BeginPaperSize: Letter +letter +%%EndPaperSize + +%%EndSetup +%%Page: 1 1 +1 0 bop 472 600 a Fo(DDDMP:)35 b(Decision)f(Diagram)f(DuMP)j(package) +1480 830 y(Release)e(2.0)462 1230 y Fn(Gianpiero)c(Cabodi)2402 +1232 y(Stef)o(ano)g(Quer)1316 1506 y(Politecnico)g(di)g(T)-10 +b(orino)1024 1656 y(Dip.)30 b(di)g(Automatica)g(e)g(Informatica)1119 +1805 y(Corso)f(Duca)h(de)n(gli)g(Abruzzi)g(24)1277 1955 +y(I\22610129)e(T)-5 b(urin,)29 b(IT)-11 b(AL)f(Y)1038 +2104 y(E-mail:)38 b Fm(f)p Fn(cabodi,quer)p Fm(g)p Fn(@polito.it)-189 +2614 y Fo(1)143 b(Intr)m(oduction)-189 2837 y Fl(The)27 +b(DDDMP)h(package)f(de\002nes)h(formats)f(and)g(rules)g(to)g(store)g +(DD)g(on)g(\002le.)39 b(More)27 b(in)g(particular)g(it)g(contains)g(a) +-189 2958 y(set)e(of)g(functions)e(to)i(dump)e(\(store)i(and)g(load\))g +(DDs)f(and)h(DD)g(forests)f(on)h(\002le)g(in)f(dif)n(ferent)h(formats.) +47 3078 y(In)30 b(the)g(present)g(implementation,)f(BDDs)h(\(R)l +(OBDDs\))h(and)f(ADD)g(\(Algebraic)g(Decision)g(Diagram\))g(of)-189 +3199 y(the)g(CUDD)g(package)g(\(v)o(ersion)f(2.3.0)g(or)h(higher\))g +(are)g(supported.)45 b(These)30 b(structures)f(can)h(be)g(represented)g +(on)-189 3319 y(\002les)25 b(either)g(in)f(te)o(xt,)g(binary)-6 +b(,)24 b(or)h(CNF)g(\(DIMA)l(CS\))h(formats.)47 3439 +y(The)f(main)f(rules)h(used)f(are)i(follo)n(wing)d(rules:)-44 +3643 y Fk(\017)49 b Fl(A)30 b(\002le)h(contains)e(a)i(single)e(BDD/ADD) +h(or)g(a)h(forest)f(of)g(BDDs/ADD,)g(i.e.,)i(a)e(v)o(ector)g(of)g +(Boolean)h(func-)55 3763 y(tions.)-44 3966 y Fk(\017)49 +b Fl(Inte)o(ger)21 b(inde)o(x)o(es)f(are)i(used)f(instead)g(of)g +(pointers)g(to)g(reference)i(nodes.)29 b(BDD/ADD)21 b(nodes)g(are)h +(numbered)55 4087 y(with)j(contiguous)g(numbers,)g(from)h(1)g(to)f +(NNodes)h(\(total)f(number)h(of)g(nodes)g(on)f(a)i(\002le\).)35 +b(0)26 b(is)f(not)h(used)f(to)55 4207 y(allo)n(w)f(ne)o(gati)n(v)o(e)e +(inde)o(x)o(es)h(for)i(complemented)f(edges.)-44 4411 +y Fk(\017)49 b Fl(A)23 b(\002le)g(contains)f(a)h(header)l(,)h +(including)d(se)n(v)o(eral)h(informations)f(about)h(v)n(ariables)h(and) +f(roots)g(of)h(BDD)h(func-)55 4531 y(tions,)32 b(then)e(the)h(list)g +(of)g(nodes.)49 b(The)32 b(header)f(is)g(al)o(w)o(ays)g(represented)h +(in)f(te)o(xt)f(format)h(\(also)g(for)g(binary)55 4651 +y(\002les\).)g(BDDs,)25 b(ADDs,)f(and)h(CNF)h(\002les)f(share)g(a)g +(similar)f(format)g(header)-5 b(.)-44 4855 y Fk(\017)49 +b Fl(BDD/ADD)40 b(nodes)g(are)h(listed)f(follo)n(wing)e(their)i +(numbering,)j(which)d(is)g(produced)g(by)h(a)f(post-order)55 +4975 y(tra)n(v)o(ersal,)24 b(in)h(such)f(a)h(w)o(ay)g(that)g(a)g(node)f +(is)h(al)o(w)o(ays)f(listed)g(after)h(its)f(Then/Else)g(children.)47 +5179 y(In)32 b(the)f(sequel)g(we)g(describe)h(more)f(in)g(detail)f(the) +h(dif)n(ferent)g(formats)g(and)g(procedures)h(a)n(v)n(ailable.)49 +b(First)-189 5299 y(of)26 b(all,)f(we)h(describe)f(BDDs)h(and)g(ADDs)f +(formats)g(and)g(procedure.)33 b(Secondly)-6 b(,)26 b(we)f(concentrate) +h(on)f(CNF)i(\002les,)-189 5419 y(i.e.,)e(ho)n(w)f(to)g(translate)g(a)i +(BDD)f(or)g(a)g(forest)g(of)f(BDDs)h(into)f(a)h(CNF)h(formula)e(and)h +(vice-v)o(ersa.)1794 5800 y(1)p eop +%%Page: 2 2 +2 1 bop -189 218 a Fo(2)143 b(BDD)35 b(and)g(ADD)g(Support)-189 +441 y Fl(In)23 b(this)f(section)g(we)g(describe)h(format)g(and)f +(procedure)h(re)o(garding)f(BDDs)h(and)f(ADDs.)30 b(W)-8 +b(e)23 b(speci\002cally)g(refer)g(to)-189 562 y(BDDs)h(in)g(the)g +(description)e(as)j(ADD)e(may)h(be)g(seen)g(as)h(an)f(e)o(xtension)e +(and)i(will)f(be)h(described)g(later)-5 b(.)30 b(First)24 +b(of)g(all,)-189 682 y(we)29 b(concentrate)f(on)g(the)g(format)g(used)g +(to)g(store)g(these)g(structure,)h(then)f(we)g(describe)h(the)f +(procedure)h(a)n(v)n(ailable)-189 802 y(to)24 b(store)h(and)g(load)f +(them.)-189 1094 y Fj(2.1)119 b(F)m(ormat)-189 1281 y +Fl(BDD)30 b(dump)f(\002les)g(are)i(composed)e(of)g(tw)o(o)g(sections:) +40 b(The)29 b(header)h(and)g(the)f(list)g(of)h(nodes.)44 +b(The)30 b(header)g(has)g(a)-189 1402 y(common)c(\(te)o(xt\))h(format,) +h(while)e(the)i(list)e(of)h(nodes)g(is)g(either)g(in)g(te)o(xt)g(or)g +(binary)g(format.)38 b(In)28 b(te)o(xt)e(format)h(nodes)-189 +1522 y(are)33 b(represented)f(with)f(redundant)g(informations,)h(where) +h(the)f(main)f(goal)g(is)h(readability)-6 b(,)32 b(while)g(the)f +(purpose)-189 1642 y(of)i(binary)f(format)g(is)g(minimizing)e(the)i(o)o +(v)o(erall)f(storage)h(size)h(for)g(BDD)f(nodes.)54 b(The)32 +b(header)h(format)f(is)g(k)o(ept)-189 1763 y(common)h(to)h(te)o(xt)g +(and)g(binary)g(formats)g(for)h(sak)o(e)f(of)h(simplicity:)47 +b(No)34 b(particular)g(optimization)f(is)h(presently)-189 +1883 y(done)29 b(on)f(binary)h(\002le)g(headers,)h(whose)f(size)g(is)f +(by)h(f)o(ar)g(dominated)f(by)h(node)f(lists)g(in)g(the)h(case)g(of)g +(lar)n(ge)h(BDDs)-189 2003 y(\(se)n(v)o(eral)24 b(thousands)g(of)h(DD)f +(nodes\).)-189 2266 y Fi(2.1.1)99 b(Header)-189 2453 +y Fl(The)23 b(header)h(has)f(the)g(same)g(format)g(both)g(for)g(te)o +(xtual)f(and)i(binary)e(dump.)30 b(F)o(or)23 b(sak)o(e)g(of)h +(generality)e(and)h(because)-189 2574 y(of)f(dynamic)g(v)n(ariable)g +(ordering)g(both)f(v)n(ariable)h(IDs)g(and)g(permutations)2377 +2537 y Fh(1)2438 2574 y Fl(are)h(included.)29 b(Names)22 +b(are)h(optionally)-189 2694 y(listed)35 b(for)h(input)f(v)n(ariables)g +(and)h(for)h(the)e(stored)h(functions.)63 b(Ne)n(w)36 +b(auxiliary)f(IDs)h(are)h(also)e(allo)n(wed.)64 b(Only)-189 +2814 y(the)34 b(v)n(ariables)f(in)g(the)h(true)g(support)f(of)h(the)f +(stored)h(BDDs)g(are)h(listed.)56 b(All)34 b(information)e(on)i(v)n +(ariables)f(\(IDs,)-189 2935 y(permutations,)c(names,)i(auxiliary)e +(IDs\))h(sorted)g(by)g(IDs,)h(and)e(the)o(y)h(are)g(restricted)g(to)f +(the)h(true)g(support)f(of)h(the)-189 3055 y(dumped)22 +b(BDD,)h(while)g(IDs)g(and)f(permutations)g(are)h(referred)i(to)d(the)h +(writing)f(BDD)h(manager)-5 b(.)30 b(Names)22 b(can)i(thus)-189 +3175 y(be)h(sorted)f(by)h(v)n(ariable)f(ordering)h(by)f(permuting)g +(them)g(according)h(to)f(the)h(permutations)e(stored)h(in)h(the)f +(\002le.)47 3296 y(As)h(an)g(e)o(xample,)f(the)g(header)i(\(in)e(te)o +(xt)g(mode\))h(of)f(the)h(ne)o(xt)f(state)h(functions)e(of)i(circuit)g +(s27)f(follo)n(ws:)-189 3494 y Fg(.ver)59 b(DDDMP-2.0)-189 +3615 y(.mode)g(A)-189 3735 y(.varinfo)f(3)-189 3855 y(.dd)h(s27-delta) +-189 3976 y(.nnodes)f(16)-189 4096 y(.nvars)g(10)-189 +4216 y(.nsuppvars)g(7)-189 4337 y(.varnames)g(G0)h(G1)g(G2)h(G3)f(G5)g +(G6)h(G7)-189 4457 y(.orderedvarnames)c(G0)k(G1)f(G2)g(G3)h(G5)f(G6)g +(G7)-189 4578 y(.ids)g(0)g(1)h(2)g(3)f(4)h(5)f(6)-189 +4698 y(.permids)f(0)i(1)f(2)h(3)f(5)h(7)f(9)-189 4818 +y(.auxids)f(1)i(2)f(3)h(4)f(5)h(6)g(7)-189 4939 y(.nroots)e(3)-189 +5059 y(.rootids)g(6)i(-13)f(-16)-189 5179 y(.rootnames)f(G10)h(G11)g +(G13)47 5378 y Fl(The)25 b(lines)f(contain)g(the)h(follo)n(wing)e +(informations:)p -189 5460 1607 4 v -77 5521 a Ff(1)-40 +5551 y Fe(The)d(permutation)e(of)i(the)g(i-th)h(v)n(ariable)e(ID)h(is)h +(the)f(relati)n(v)o(e)g(position)f(of)h(the)g(v)n(ariable)f(in)i(the)f +(ordering.)1794 5800 y Fl(2)p eop +%%Page: 3 3 +3 2 bop -44 218 a Fk(\017)49 b Fl(Dddmp)24 b(v)o(ersion)f(information.) +-44 411 y Fk(\017)49 b Fl(File)25 b(mode)f(\(A)h(for)g(ASCII)h(te)o +(xt,)e(B)h(for)g(binary)g(mode\).)-44 604 y Fk(\017)49 +b Fl(V)-11 b(ar)n(-e)o(xtra-info)25 b(\(0:)30 b(v)n(ariable)24 +b(ID,)h(1:)31 b(permID,)24 b(2:)31 b(aux)25 b(ID,)g(3:)30 +b(v)n(ariable)24 b(name,)h(4)g(no)f(e)o(xtra)h(info\).)-44 +797 y Fk(\017)49 b Fl(Name)25 b(of)g(dd)f(\(optional\).)-44 +990 y Fk(\017)49 b Fl(T)-8 b(otal)24 b(number)g(of)h(nodes)g(in)f(the)h +(\002le.)-44 1183 y Fk(\017)49 b Fl(Number)24 b(of)h(v)n(ariables)f(of) +h(the)g(writing)f(DD)g(manager)-5 b(.)-44 1375 y Fk(\017)49 +b Fl(Number)24 b(of)h(v)n(ariables)f(in)h(the)f(true)h(support)f(of)h +(the)f(stored)h(DDs.)-44 1568 y Fk(\017)49 b Fl(V)-11 +b(ariable)25 b(names)f(\(optional\))g(for)h(all)g(the)f(v)n(ariables)g +(in)h(the)f(BDD/ADD)h(support.)-44 1761 y Fk(\017)49 +b Fl(V)-11 b(ariable)20 b(names)g(for)h(all)f(the)g(v)n(ariables)f(in)h +(the)g(DD)h(manager)f(during)g(the)g(storing)f(phase.)29 +b(Notice)20 b(that)g(this)55 1882 y(information)k(w)o(as)h(not)g +(stored)g(by)g(pre)n(vious)f(v)o(ersions)g(of)i(the)f(same)g(tool.)32 +b(Full)25 b(backw)o(ard)g(compatibility)55 2002 y(is)f(guaranteed)h(by) +g(the)f(present)h(implementation)d(of)j(the)g(tool.)-44 +2195 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(IDs.)-44 +2388 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(permuted)f(IDs.)-44 +2581 y Fk(\017)49 b Fl(V)-11 b(ariable)25 b(auxiliary)f(IDs)h +(\(optional\).)-44 2774 y Fk(\017)49 b Fl(Number)24 b(of)h(BDD)g +(roots.)-44 2967 y Fk(\017)49 b Fl(Inde)o(x)o(es)24 b(of)h(BDD)g(roots) +f(\(complemented)g(edges)g(allo)n(wed\).)-44 3160 y Fk(\017)49 +b Fl(Names)24 b(of)h(BDD)h(roots)e(\(optional\).)-189 +3332 y(Notice)h(that)f(a)h(\002eld)-189 3504 y Fg(.add)-189 +3676 y Fl(is)f(present)h(after)g(the)g(dddmp)f(v)o(ersion)f(for)j +(\002les)e(containing)g(ADDs.)-189 3936 y Fi(2.1.2)99 +b(T)-9 b(ext)25 b(F)n(ormat)-189 4124 y Fl(In)g(te)o(xt)f(mode)g(nodes) +g(are)i(listed)e(on)g(a)h(te)o(xt)f(line)h(basis.)30 +b(Each)25 b(a)g(node)f(is)h(represented)g(as)-189 4296 +y Fg()57 b([])f()588 +4416 y()h()-189 4588 y Fl(where)25 +b(all)g(inde)o(x)o(es)e(are)j(inte)o(ger)e(numbers.)47 +4709 y(This)h(format)g(is)g(redundant)f(\(due)i(to)f(the)g(node)g +(ordering,)g Fd(<)p Fl(Node-inde)o(x)p Fd(>)f Fl(is)g(and)i +(incremental)e(inte)o(ger\))-189 4829 y(b)n(ut)g(we)h(k)o(eep)g(it)g +(for)g(readability)-6 b(.)47 4949 y Fd(<)p Fl(V)-11 b(ar)n(-e)o +(xtra-info)p Fd(>)34 b Fl(\(optional)e(redundant)i(\002eld\))g(is)f +(either)h(an)g(inte)o(ger)f(\(ID,)h(PermID,)g(or)g(auxID\))g(or)g(a) +-189 5070 y(string)k(\(v)n(ariable)h(name\).)75 b Fd(<)p +Fl(V)-11 b(ar)n(-internal-inde)o(x)p Fd(>)38 b Fl(is)h(an)g(internal)g +(v)n(ariable)g(inde)o(x:)59 b(V)-11 b(ariables)39 b(in)g(the)g(true) +-189 5190 y(support)25 b(of)h(the)g(stored)g(BDDs)g(are)h(numbered)e +(with)g(ascending)h(inte)o(gers)f(starting)g(from)h(0,)g(and)g(follo)n +(wing)e(the)-189 5311 y(v)n(ariable)g(ordering.)31 b +Fd(<)p Fl(Then-inde)o(x)p Fd(>)23 b Fl(and)i Fd(<)p Fl(Else-inde)o(x)p +Fd(>)e Fl(are)j(signed)e(inde)o(x)o(es)f(of)i(children)f(nodes.)47 +5431 y(In)h(the)f(follo)n(wing,)f(we)i(report)f(the)g(list)g(of)h +(nodes)f(of)g(the)h(s27)f(ne)o(xt)f(state)i(functions)e(\(see)i(pre)n +(vious)e(header)-189 5551 y(e)o(xample\):)1794 5800 y(3)p +eop +%%Page: 4 4 +4 3 bop -189 218 a Fg(.nodes)-189 338 y(1)60 b(T)f(1)h(0)f(0)-189 +459 y(2)h(G7)f(6)g(1)h(-1)-189 579 y(3)g(G5)f(4)g(1)h(2)-189 +699 y(4)g(G3)f(3)g(3)h(1)-189 820 y(5)g(G1)f(1)g(1)h(4)-189 +940 y(6)g(G0)f(0)g(5)h(-1)-189 1061 y(7)g(G6)f(5)g(1)h(-1)-189 +1181 y(8)g(G5)f(4)g(1)h(-7)-189 1301 y(9)g(G6)f(5)g(1)h(-2)-189 +1422 y(10)f(G5)h(4)f(1)h(-9)-189 1542 y(11)f(G3)h(3)f(10)h(8)-189 +1662 y(12)f(G1)h(1)f(8)h(11)-189 1783 y(13)f(G0)h(0)f(5)h(12)-189 +1903 y(14)f(G2)h(2)f(1)h(-1)-189 2024 y(15)f(G2)h(2)f(1)h(-2)-189 +2144 y(16)f(G1)h(1)f(14)h(15)-189 2264 y(.end)-189 2468 +y Fl(The)27 b(list)f(is)h(enclosed)g(between)g(the)g +Fg(.nodes)f Fl(and)h Fg(.end)f Fl(lines.)37 b(First)27 +b(node)g(is)g(the)g(one)g(constant,)f(each)i(node)-189 +2588 y(contains)c(the)h(optional)e(v)n(ariable)h(name.)47 +2708 y(F)o(or)29 b(ADDs)f(more)h(than)f(one)h(constant)e(is)i(stored)f +(in)g(the)g(\002le.)43 b(Each)29 b(constant)f(has)g(the)h(same)f +(format)h(we)-189 2829 y(ha)n(v)o(e)c(just)e(analyzed)i(for)g(the)g +(BDD)g(b)n(ut)g(the)f(represented)h(v)n(alue)f(is)h(stored)f(as)h(a)g +(\003oat)g(number)-5 b(.)-189 3095 y Fi(2.1.3)99 b(Binary)25 +b(F)n(ormat)-189 3283 y Fl(The)h(binary)g(format)f(is)h(not)f(allo)n +(wed)g(for)i(ADDs.)33 b(As)26 b(a)h(consequence)f(we)g(concentrate)g +(only)f(on)h(BDDs)g(in)g(this)-189 3403 y(section.)k(In)25 +b(binary)f(mode)h(nodes)f(are)i(represented)f(as)g(a)g(sequence)g(of)g +(bytes,)f(encoding)g(tuples)-189 3606 y Fg()-189 +3727 y([])-189 3847 y([])-189 +3968 y([])-189 4171 y Fl(in)30 b(an)g(optimized)f(w)o(ay)-6 +b(.)46 b(Only)29 b(the)h(\002rst)g(byte)g(\(code\))h(is)e(mandatory)-6 +b(,)30 b(while)g(inte)o(ger)f(inde)o(x)o(es)g(are)i(represented)-189 +4291 y(in)c(absolute)f(or)h(relati)n(v)o(e)f(mode,)h(where)h(relati)n +(v)o(e)e(means)g(of)n(fset)h(with)f(respect)i(to)e(a)i(Then/Else)e +(node)h(info.)37 b(The)-189 4412 y(best)23 b(between)g(absolute)f(and)h +(relati)n(v)o(e)e(representation)i(is)f(chosen)h(and)g(relati)n(v)o(e)f +(1)h(is)f(directly)g(coded)h(in)g Fd(<)p Fl(Node-)-189 +4532 y(code)p Fd(>)e Fl(without)f(an)o(y)g(e)o(xtra)h(info.)29 +b(Suppose)21 b(V)-11 b(ar\(NodeId\),)22 b(Then\(NodeId\))f(and)g +(Else\(NodeId\))f(represent)i(infos)-189 4652 y(about)i(a)h(gi)n(v)o +(en)f(node.)30 b Fd(<)p Fl(Node-code)p Fd(>)25 b Fl(is)f(a)h(byte)g +(which)f(contains)g(the)h(follo)n(wing)e(bit)h(\002elds)h(\(MSB)g(to)g +(LSB\))-44 4856 y Fk(\017)49 b Fl(Unused)24 b(:)31 b(1)24 +b(bit)-44 5059 y Fk(\017)49 b Fl(V)-11 b(ariable:)30 +b(2)25 b(bits,)f(one)h(of)g(the)f(follo)n(wing)f(codes)171 +5288 y Fi(\226)49 b Fl(DDDMP)p 636 5288 30 4 v 35 w(ABSOLUTE)p +1191 5288 V 36 w(ID:)22 b(V)-11 b(ar\(NodeId\))22 b(is)f(represented)h +(in)g(absolute)f(form)g(as)h Fd(<)p Fl(V)-11 b(ar)n(-internal-)270 +5408 y(info)p Fd(>)24 b Fl(=)h(V)-11 b(ar\(NodeId\))25 +b(follo)n(ws)e(\(absolute)i(info\))1794 5800 y(4)p eop +%%Page: 5 5 +5 4 bop 171 218 a Fi(\226)49 b Fl(DDDMP)p 636 218 30 +4 v 35 w(RELA)-11 b(TIVE)p 1147 218 V 36 w(ID:)32 b(V)-11 +b(ar\(NodeId\))32 b(is)g(represented)g(in)f(relati)n(v)o(e)g(form)h(as) +g Fd(<)p Fl(V)-11 b(ar)n(-internal-)270 338 y(info\277)24 +b(=)h(Min\(V)-11 b(ar\(Then\(NodeId\)\),V)g(ar\(Else\(NodeId\)\)\)-V)g +(ar\(NodeId\))171 500 y Fi(\226)49 b Fl(DDDMP)p 636 500 +V 35 w(RELA)-11 b(TIVE)p 1147 500 V 36 w(1:)27 b(the)19 +b(\002eld)g Fd(<)p Fl(V)-11 b(ar)n(-internal-info)p Fd(>)18 +b Fl(does)h(not)f(follo)n(w)-6 b(,)18 b(because)h(V)-11 +b(ar\(NodeId\))270 620 y(=)25 b(Min\(V)-11 b(ar\(Then\(NodeId\)\),V)g +(ar\(Else\(NodeId\)\)\)-1)171 782 y Fi(\226)49 b Fl(DDDMP)p +636 782 V 35 w(TERMIN)m(AL:)24 b(Node)h(is)f(a)h(terminal,)f(no)g(v)n +(ar)h(info)g(required)-44 1011 y Fk(\017)49 b Fl(T)25 +b(:)f(2)h(bits,)f(with)g(codes)h(similar)e(to)i(V)171 +1214 y Fi(\226)49 b Fl(DDDMP)p 636 1214 V 35 w(ABSOLUTE)p +1191 1214 V 36 w(ID:)20 b Fd(<)p Fl(Then-info)p Fd(>)f +Fl(is)h(represented)g(in)g(absolute)f(form)h(as)g Fd(<)p +Fl(Then-info)p Fd(>)270 1334 y Fl(=)25 b(Then\(NodeId\))171 +1496 y Fi(\226)49 b Fl(DDDMP)p 636 1496 V 35 w(RELA)-11 +b(TIVE)p 1147 1496 V 36 w(ID:)28 b(Then\(NodeId\))f(is)g(represented)h +(in)g(relati)n(v)o(e)e(form)i(as)g Fd(<)p Fl(Then-info)p +Fd(>)270 1617 y Fl(=)d(Nodeid-Then\(NodeId\))171 1779 +y Fi(\226)49 b Fl(DDDMP)p 636 1779 V 35 w(RELA)-11 b(TIVE)p +1147 1779 V 36 w(1:)30 b(no)25 b Fd(<)p Fl(Then-info)p +Fd(>)f Fl(follo)n(ws,)f(because)i(Then\(NodeId\))g(=)g(NodeId-1)171 +1941 y Fi(\226)49 b Fl(DDDMP)p 636 1941 V 35 w(TERMIN)m(AL:)24 +b(Then)h(Node)f(is)h(a)g(terminal,)f(no)g(info)h(required)f(\(for)i(R)l +(OBDDs\))-44 2144 y Fk(\017)49 b Fl(Ecompl)24 b(:)30 +b(1)25 b(bit,)f(if)h(1)g(means)f(that)g(the)h(else)g(edge)g(is)f +(complemented)-44 2347 y Fk(\017)49 b Fl(E)25 b(:)f(2)h(bits,)f(with)g +(codes)h(and)f(meanings)g(as)h(for)g(the)g(Then)f(edge)-189 +2551 y(DD)35 b(node)f(codes)h(are)h(written)e(as)h(one)g(byte.)60 +b Fd(<)p Fl(V)-11 b(ar)n(-internal-inde)o(x)p Fd(>)p +Fl(,)36 b Fd(<)p Fl(Then-inde)o(x)p Fd(>)p Fl(,)g Fd(<)p +Fl(Else-inde)o(x)p Fd(>)e Fl(\(if)-189 2671 y(required\))25 +b(are)h(represented)f(as)g(unsigned)e(inte)o(ger)h(v)n(alues)g(on)h(a)g +(suf)n(\002cient)f(set)h(of)g(bytes)f(\(MSByte)h(\002rst\).)47 +2792 y(Inte)o(gers)h(of)f(an)o(y)h(length)e(are)j(written)e(as)h +(sequences)g(of)g(\224link)o(ed\224)f(bytes)g(\(MSByte)h(\002rst\).)34 +b(F)o(or)26 b(each)g(byte)-189 2912 y(7)f(bits)f(are)h(used)g(for)g +(data)g(and)f(one)h(\(MSBit\))g(as)g(link)f(with)g(a)h(further)g(byte)g +(\(MSB)g(=)g(1)g(means)f(one)h(more)g(byte\).)47 3032 +y(Lo)n(w)f(le)n(v)o(el)g(read/write)h(of)g(bytes)f(\002lters)h +Fd(<)p Fl(CR)p Fd(>)p Fl(,)g Fd(<)p Fl(LF)p Fd(>)g Fl(and)g +Fd(<)p Fl(ctrl-Z)p Fd(>)f Fl(through)g(escape)h(sequences.)-189 +3327 y Fj(2.2)119 b(Implementation)-189 3515 y Fl(Store)24 +b(and)g(load)g(for)g(single)g(Boolean)g(functions)f(and)h(arrays)g(of)g +(Boolean)g(functions)f(are)i(implemented.)k(More-)-189 +3635 y(o)o(v)o(er)l(,)37 b(the)e(current)h(presentation)f(includes)f +(functions)h(to)g(retrie)n(v)o(e)g(v)n(ariables)f(names,)k(auxiliary)d +(identi\002erss,)-189 3756 y(and)c(all)g(the)g(information)f(contained) +h(in)f(the)h(header)h(of)f(the)h(\002les.)50 b(This)30 +b(information)g(can)h(be)h(used)f(as)g(a)g(pre-)-189 +3876 y(processing)19 b(step)g(for)i(load)e(operations.)28 +b(These)20 b(functions)f(allo)n(w)f(to)i(o)o(v)o(ercome)f(fe)n(w)g +(limitations)f(of)h(the)h(pre)n(vious)-189 3997 y(implementations.)-189 +4263 y Fi(2.2.1)99 b(Storing)25 b(Decision)g(Diagrams)-189 +4450 y Fc(Dddmp)p 111 4450 V 35 w(cuddBddStor)l(e)f Fl(and)h +Fc(Dddmp)p 1195 4450 V 35 w(cuddBddArr)o(ayStor)l(e)e +Fl(are)j(the)f(tw)o(o)f(store)h(functions,)f(used)h(to)g(store)f(sin-) +-189 4571 y(gle)f(BDD)h(or)g(a)f(forest)h(of)f(BDDs,)h(respecti)n(v)o +(ely)-6 b(.)28 b(Internally)-6 b(,)23 b Fc(Dddmp)p 2275 +4571 V 35 w(cuddBddStor)l(e)f Fl(b)n(uilds)g(a)i(dummy)e(1)h(entry)-189 +4691 y(array)j(of)e(BDDs,)h(and)g(calls)g Fc(dddmp)p +1102 4691 V 35 w(cuddBddArr)o(ayStor)l(e)p Fl(.)47 4811 +y(Since)30 b(con)l(v)o(ersion)e(from)h(DD)h(pointers)e(to)h(inte)o(ger) +f(is)h(required,)i(DD)e(nodes)g(are)h(temporarily)e(remo)o(v)o(ed)-189 +4932 y(from)23 b(the)f(unique)h(hash.)29 b(This)23 b(mak)o(es)f(room)g +(in)h(their)f Fc(ne)n(xt)h Fl(\002eld)h(to)e(store)h(node)f(IDs.)30 +b(Nodes)23 b(are)h(re-link)o(ed)e(after)-189 5052 y(the)i(store)g +(operation,)g(possible)f(in)g(a)i(modi\002ed)e(order)-5 +b(.)31 b(Dumping)22 b(is)i(either)g(in)g(te)o(xt)f(or)i(binary)f(form.) +30 b(Both)24 b(a)g(\002le)-189 5173 y(pointer)31 b(\()p +Fc(fp)p Fl(\))g(and)g(a)h(\002le)g(name)f(\()p Fc(fname)p +Fl(\))h(are)g(pro)o(vided)e(as)h(inputs)f(parameters)i(to)f(store)g +(routines.)50 b(BDDs)31 b(are)-189 5293 y(stored)c(to)g(the)g(already)g +(open)h(\002le)f Fc(fp)p Fl(,)h(if)f(not)g(NULL.)g(Otherwise)f(\002le)i +(whose)f(name)g(is)g Fc(fname)g Fl(is)g(opened.)38 b(This)-189 +5413 y(is)24 b(intended)g(to)h(allo)n(w)f(either)g(DD)h(storage)g +(within)e(\002les)i(containing)f(other)g(data,)h(or)g(to)g(speci\002c)g +(\002les.)1794 5800 y(5)p eop +%%Page: 6 6 +6 5 bop -189 218 a Fi(2.2.2)99 b(Loading)25 b(Decision)g(Diagrams)-189 +405 y Fc(Dddmp)p 111 405 30 4 v 35 w(cuddBddLoad)37 b +Fl(and)h Fc(Dddmp)p 1219 405 V 35 w(cuddBddArr)o(ayLoad)f +Fl(are)h(the)g(load)g(functions,)i(which)e(read)g(a)g(BDD)-189 +526 y(dump)24 b(\002le.)47 646 y(F)o(ollo)n(wing)34 b(the)h(store)h +(function,)h(the)f(main)f(BDD)h(load)f(function,)j Fc(Dddmp)p +2813 646 V 35 w(cuddBddLoad)p Fl(,)f(is)f(imple-)-189 +767 y(mented)g(by)g(calling)f(the)h(main)g(BDD-array)h(loading)f +(function)f Fc(Dddmp)p 2466 767 V 35 w(cuddBddArr)o(ayLoad)p +Fl(.)63 b(A)37 b(dynamic)-189 887 y(v)o(ector)24 b(of)h(DD)g(pointers)f +(is)g(temporarily)g(allocated)h(to)f(support)g(con)l(v)o(ersion)f(from) +i(DD)g(inde)o(x)o(es)e(to)h(pointers.)47 1007 y(Se)n(v)o(eral)40 +b(criteria)f(are)i(supported)d(for)i(v)n(ariable)f(match)g(between)g +(\002le)h(and)g(DD)f(manager)l(,)k(practically)-189 1128 +y(allo)n(wing)37 b(v)n(ariable)h(permutations)f(or)i(compositions)d +(while)i(loading)g(DDs.)71 b(V)-11 b(ariable)39 b(match)f(between)h +(the)-189 1248 y(DD)32 b(manager)g(and)g(the)g(BDD)g(\002le)g(is)g +(optionally)e(based)i(in)f Fc(IDs)p Fl(,)j Fc(perids)p +Fl(,)f Fc(varnames)p Fl(,)g Fc(var)o(auxids)p Fl(;)g(also)f(direct)-189 +1369 y(composition)j(between)j Fc(IDs)g Fl(and)f Fc(composeids)g +Fl(is)g(supported.)68 b(The)38 b Fc(varmatc)o(hmode)e +Fl(parameter)i(is)f(used)g(to)-189 1489 y(select)27 b(mathing)e(mode.) +37 b(More)27 b(in)f(detail,)h(tw)o(o)f(match)h(modes)f(use)h(the)f +(information)g(within)f(the)i(DD)g(manager)l(,)-189 1609 +y(the)e(other)f(ones)h(use)g(e)o(xtra)f(information,)f(which)i(support) +f(an)o(y)g(v)n(ariable)g(remap)h(or)g(change)g(in)f(the)h(ordering.)-44 +1813 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 1813 +V 35 w(V)-13 b(AR)p 1272 1813 V 35 w(MA)i(TCHIDS)19 b(allo)n(ws)f +(loading)g(a)h(DD)g(k)o(eeping)f(v)n(ariable)g(IDs)h(unchanged)55 +1933 y(\(re)o(gardless)24 b(of)h(the)f(v)n(ariable)h(ordering)f(of)h +(the)g(reading)f(manager)-5 b(.)55 2095 y(This)24 b(is)g(useful,)g(for) +h(e)o(xample,)f(when)g(sw)o(apping)g(DDs)g(to)h(\002le)g(and)f +(restoring)g(them)g(later)h(from)f(\002le,)h(after)55 +2215 y(possible)e(v)n(ariable)i(reordering)g(acti)n(v)n(ations.)-44 +2419 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 2419 +V 35 w(V)-13 b(AR)p 1272 2419 V 35 w(MA)i(TCHPERMIDS)36 +b(is)e(used)h(to)f(allo)n(w)g(v)n(ariable)g(match)h(according)55 +2539 y(to)h(the)h(position)e(in)i(the)g(ordering)f(\(retrie)n(v)o(ed)g +(by)h(array)h(of)f(permutations)e(stored)h(on)h(\002le)g(and)g(within) +55 2660 y(the)h(reading)g(DD)h(manager\).)72 b(A)38 b(possible)f +(application)h(is)g(retrie)n(ving)f(BDDs)i(stored)f(after)h(dynamic)55 +2780 y(reordering,)28 b(from)g(a)g(DD)g(manager)g(where)h(all)e(v)n +(ariable)h(IDs)f(map)h(their)f(position)g(in)g(the)h(ordering,)g(and)55 +2900 y(the)d(loaded)f(BDD)h(k)o(eeps)g(the)g(ordering)f(as)h(stored)f +(on)h(\002le.)-44 3104 y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p +1040 3104 V 35 w(V)-13 b(AR)p 1272 3104 V 35 w(MA)i(TCHN)m(AMES)26 +b(requires)h(a)h(not)e(NULL)h(v)n(armatchmodes)f(param-)55 +3224 y(eter;)34 b(this)c(is)g(a)h(v)o(ector)g(of)g(strings)e(in)i +(one-to-one)f(correspondence)h(with)f(v)n(ariable)h(IDs)f(of)h(the)g +(reading)55 3344 y(manager)-5 b(.)40 b(V)-11 b(ariables)28 +b(in)g(the)g(DD)g(\002le)g(read)h(are)g(matched)f(with)f(manager)h(v)n +(ariables)f(according)h(to)g(their)55 3465 y(name)35 +b(\(a)h(not)f(NULL)g(v)n(arnames)g(parameter)h(w)o(as)f(required)h +(while)f(storing)f(the)h(DD)g(\002le\).)64 b(The)35 b(most)55 +3585 y(common)c(usage)h(of)g(this)f(feature)i(is)e(in)h(combination)e +(with)i(a)g(v)n(ariable)g(ordering)g(stored)f(on)h(a)g(\002le)h(and)55 +3706 y(based)28 b(on)h(v)n(ariables)f(names.)41 b(Names)29 +b(must)e(be)i(loaded)f(in)g(an)h(array)g(of)g(strings)e(and)i(passed)f +(to)g(the)h(DD)55 3826 y(load)24 b(procedure.)-44 4029 +y Fk(\017)49 b Fl(v)n(armatchnode=DDDMP)p 1040 4029 V +35 w(V)-13 b(AR)p 1272 4029 V 35 w(MA)i(TCHIDS)25 b(has)g(a)g(meaning)f +(similar)g(to)55 4150 y(DDDMP)p 421 4150 V 36 w(V)-13 +b(AR)p 654 4150 V 35 w(MA)i(TCHN)m(AMES)26 b(b)n(ut)h(inte)o(ger)f +(auxiliary)g(IDs)h(are)h(used)f(instead)f(of)h(strings.)36 +b(The)28 b(ad-)55 4270 y(ditional)23 b(not)h(NULL)h(v)n(armathauxids)e +(parameter)i(is)g(needed.)-44 4474 y Fk(\017)49 b Fl(v)n +(armatchnode=DDDMP)p 1040 4474 V 35 w(V)-13 b(AR)p 1272 +4474 V 35 w(COMPOSEIDS,)38 b(uses)f(the)f(additional)f(v)n +(arcomposeids)g(parameter)55 4594 y(as)25 b(an)g(array)g(of)g(v)n +(ariable)f(IDs)h(to)g(be)g(composed)f(with)g(IDs)g(stored)h(in)f +(\002le.)-189 4860 y Fi(2.2.3)99 b(DD)25 b(Load/Stor)n(e)h(and)f(V)-9 +b(ariable)25 b(Ordering)-189 5048 y Fl(Loading)31 b(of)i(Decision)e +(Diagrams)h(from)g(\002le)g(supports)f(dif)n(ferent)h(v)n(ariables)g +(ordering)f(strate)o(gies,)i(as)g(already)-189 5168 y(pointed)23 +b(out)h(in)g(the)h(pre)n(vious)e(section.)30 b(This)24 +b(allo)n(ws)f(or)h(e)o(xample)g(storing)f(dif)n(ferent)i(BDDs)f(each)h +(with)f(its)g(o)n(wn)-189 5288 y(v)n(ariable)29 b(ordering,)h(and)g(to) +f(mer)n(ge)h(them)f(within)f(the)i(same)f(DD)h(manager)f(by)h(means)f +(of)g(proper)h(load)f(opera-)-189 5409 y(tions.)44 b(W)-8 +b(e)30 b(suggest)f(using)f(DDDMP)p 1175 5409 V 36 w(V)-13 +b(AR)p 1408 5409 V 36 w(MA)i(TCHIDS)30 b(whene)n(v)o(er)f(IDs)g(k)o +(eeps)h(on)f(representing)h(the)f(same)-189 5529 y(entities)24 +b(while)h(changing)f(v)n(ariable)h(ordering.)31 b(If)25 +b(this)f(is)h(not)f(true,)h(v)n(ariable)g(names)g(\(if)g(a)n(v)n +(ailable\))f(or)i(auxiliary)1794 5800 y(6)p eop +%%Page: 7 7 +7 6 bop -189 218 a Fl(IDs)34 b(are)h(a)g(good)e(w)o(ay)i(to)f +(represent)g(in)l(v)n(ariant)f(attrib)n(uted)g(of)i(v)n(ariables)e +(across)h(se)n(v)o(eral)g(runs)g(with)f(dif)n(ferent)-189 +338 y(orderings.)50 b(DDDMP)p 629 338 30 4 v 35 w(V)-13 +b(AR)p 861 338 V 36 w(COMPOSEIDS)32 b(is)f(an)h(alternati)n(v)o(e)e +(solution,)h(that)g(practically)f(corresponds)h(to)-189 +459 y(cascading)23 b(DDDMP)p 593 459 V 36 w(V)-13 b(AR)p +826 459 V 36 w(MA)i(TCHIDS)23 b(and)h(v)n(ariable)f(composition)e(with) +h(a)i(gi)n(v)o(en)e(array)i(of)g(ne)n(w)f(v)n(ariables.)-189 +797 y Fo(3)143 b(CNF)35 b(Support)-189 1050 y Fj(3.1)119 +b(F)m(ormat)-189 1237 y Fl(Gi)n(v)o(en)30 b(a)h(BDD)g(representing)g(a) +g(function)f Fd(f)11 b Fl(,)32 b(we)f(de)n(v)o(elop)f(three)h(basic)g +(possible)e(w)o(ays)i(to)g(store)f(it)h(as)g(a)g(CNF)-189 +1358 y(formula.)54 b(In)33 b(each)h(method)d(the)i(set)g(of)f(clauses)h +(is)f(written)h(after)g(an)g(header)g(part.)55 b(Only)32 +b(the)h(te)o(xt)f(format)g(is)-189 1478 y(allo)n(wed.)-189 +1743 y Fi(3.1.1)99 b(Header)-189 1931 y Fl(The)23 b(header)h(part)f(of) +g(each)h(CNF)g(\002le)f(has)g(basically)g(the)f(same)h(format)g +(analyzed)g(for)h(the)f(BDD/ADD)g(\002les.)30 b(F)o(or)-189 +2051 y(e)o(xample)h(the)g Fg(.rootids)f Fl(line)h(indicates)f(the)i(be) +o(ginning)d(of)j(each)g(CNF)g(formula)f(represented)h(by)f(a)h(single) +-189 2172 y(BDD.)j(T)-8 b(o)34 b(be)g(compatible)f(with)h(the)g(DIMA)l +(CS)h(format)f(each)h(header)f(line)g(start)g(with)g(the)g(character)h +(\223c\224)g(to)-189 2292 y(indicate)24 b(a)h(comment.)-189 +2557 y Fi(3.1.2)99 b(T)-9 b(ext)25 b(F)n(ormat)-189 2745 +y Fl(The)j(\002rst)g(method,)g(which)f(we)h(call)g Fi(Single-Node-Cut)p +Fl(,)j(models)26 b(each)j(BDD)f(nodes,)h(b)n(ut)e(the)h(ones)f(with)h +(both)-189 2865 y(the)c(children)g(equal)h(to)f(the)g(constant)g(node)g +Fb(1)p Fl(,)g(as)h(a)g(multiple)o(x)o(er)-5 b(.)27 b(Each)e(multiple)o +(x)o(er)d(has)i(tw)o(o)g(data)h(inputs)e(\(i.e.,)-189 +2985 y(the)k(node)h(children\),)f(a)h(selection)f(input)f(\(i.e.,)i +(the)g(node)f(v)n(ariable\))g(and)h(one)f(output)f(\(i.e.,)i(the)g +(function)e(v)n(alue\))-189 3106 y(whose)h(v)n(alue)f(is)h(assigned)f +(to)h(an)g(additional)f(CNF)i(v)n(ariable.)37 b(The)27 +b(\002nal)h(number)e(of)h(v)n(ariables)g(is)f(equal)h(to)g(the)-189 +3226 y(number)d(of)h(original)f(BDD)h(v)n(ariables)f(plus)g(the)h +(number)f(of)h(\223internal\224)g(nodes)f(of)h(the)g(BDD.)47 +3346 y(The)k(second)f(method,)g(which)h(we)f(call)h Fi(Maxterm-Cut)p +Fl(,)h(create)g(clauses)e(starting)g(from)g Fd(f)39 b +Fl(corresponds)-189 3467 y(to)25 b(the)h(of)n(f-set)g(\(i.e.,)f(all)h +(the)g(paths-cubes)f(from)g(the)h(root)g(node)f(to)h(the)f(terminal)g +Fg(0)p Fl(\))h(of)g(the)g(function)e Fd(f)11 b Fl(.)34 +b(W)l(ithin)-189 3587 y(the)29 b(BDD)g(for)g Fd(f)11 +b Fl(,)30 b(such)f(clauses)f(are)i(found)e(by)h(follo)n(wing)e(all)i +(the)f(paths)h(from)f(the)h(root)g(node)f(of)h(the)g(BDD)g(to)-189 +3708 y(the)c(constant)f(node)g Fb(0)p Fl(.)31 b(The)25 +b(\002nal)g(number)f(of)h(v)n(ariables)f(is)g(equal)h(to)f(the)h +(number)f(of)h(original)f(BDD)h(v)n(ariables.)47 3828 +y(The)k(third)g(method,)g(which)g(we)g(call)g Fi(A)-5 +b(uxiliary-V)c(ariable-Cut)p Fl(,)30 b(is)f(a)h(trade-of)n(f)f(between) +g(the)g(\002rst)g(tw)o(o)-189 3948 y(strate)o(gies.)69 +b(Internal)37 b(v)n(ariables,)j(i.e.,)h(cutting)c(points,)j(are)e +(added)g(in)f(order)h(to)g(decompose)f(the)h(BDD)g(into)-189 +4069 y(multiple)27 b(sub-trees)i(each)h(of)f(which)f(is)h(stored)g +(follo)n(wing)e(the)h(second)h(strate)o(gy)-6 b(.)42 +b(The)29 b(trade-of)n(f)g(is)g(guided)f(by)-189 4189 +y(the)23 b(cutting)f(point)g(selection)g(strate)o(gy)-6 +b(,)22 b(and)h(we)g(e)o(xperiment)f(with)g(tw)o(o)g(methodologies.)28 +b(In)23 b(the)g(\002rst)g(method,)g(a)-189 4310 y(ne)n(w)f(CNF)h(v)n +(ariable)f(is)f(inserted)h(in)g(correspondence)g(to)g(the)g(shared)g +(nodes)g(of)g(the)h(BDD,)f(i.e.,)h(the)f(nodes)f(which)-189 +4430 y(ha)n(v)o(e)29 b(more)g(than)h(one)f(incoming)f(edge.)45 +b(This)29 b(technique,)h(albeit)e(optimizing)g(the)h(number)g(of)h +(literals)e(stored,)-189 4550 y(can)35 b(produce)g(clauses)f(with)g(a)h +(high)f(number)h(of)f(literals)1894 4514 y Fh(2)1933 +4550 y Fl(.)60 b(T)-8 b(o)35 b(a)n(v)n(oid)f(this)g(dra)o(wback,)j(the) +e(second)f(method,)-189 4671 y(introduces)28 b(all)g(the)g(pre)n +(viously)e(indicated)i(cutting)f(points)g(more)h(the)h(ones)f +(necessary)g(to)g(break)h(the)f(length)g(of)-189 4791 +y(the)d(path)f(to)h(a)g(maximum)e(\(user\))i(selected)g(v)n(alue.)47 +4911 y(Actually)-6 b(,)37 b(all)f(the)f(methods)g(described)h(abo)o(v)o +(e)e(can)j(be)e(re-conducted)h(to)g(the)f(basic)h(idea)g(of)g(possibly) +-189 5032 y(breaking)24 b(the)h(BDD)g(through)f(the)g(use)h(of)f +(additional)g(cutting)f(v)n(ariables)h(and)h(dumping)e(the)h(paths)g +(between)h(the)-189 5152 y(root)34 b(of)h(the)f(BDD,)h(the)g(cutting)e +(v)n(ariables)h(and)g(the)h(terminal)e(nodes.)60 b(Such)35 +b(internal)f(cutting)f(v)n(ariables)h(are)-189 5273 y(added)25 +b(al)o(w)o(ays)f(\(for)i(each)f(node\),)g(ne)n(v)o(er)f(or)h(sometimes) +e(respecti)n(v)o(ely)-6 b(.)p -189 5360 1607 4 v -77 +5422 a Ff(2)-40 5452 y Fe(This)27 b(v)n(alue)f(is)i(superiorly)d +(limited)h(by)g(the)h(number)e(of)h(v)n(ariables)g(of)g(the)h(BDD,)g +(i.e.,)h(the)f(longest)f(path)g(from)g(the)h(root)f(to)g(the)-189 +5551 y(terminal)19 b(node.)1794 5800 y Fl(7)p eop +%%Page: 8 8 +8 7 bop 47 218 a Fl(While)33 b(the)f Fc(Single-Node-Cut)h +Fl(method)f(minimizes)f(the)i(length)f(of)h(the)f(clauses)h(produced,)i +(b)n(ut)d(it)g(also)-189 338 y(requires)d(the)h(higher)f(number)g(of)g +(CNF)i(v)n(ariables,)e(the)h Fc(Maxterm-Cut)f Fl(technique)g(minimizes) +f(the)h(number)g(of)-189 459 y(CNF)36 b(v)n(ariables)d(required.)61 +b(This)34 b(adv)n(antage)g(is)g(counter)n(-balanced)h(by)f(the)h(f)o +(act)g(that)f(in)g(the)h(w)o(orst)f(case)h(the)-189 579 +y(number)23 b(of)g(clauses,)g(as)h(well)e(as)i(the)f(total)f(number)h +(of)g(literals,)g(produced)g(is)g(e)o(xponential)e(in)i(the)g(BDD)h +(size)f(\(in)-189 699 y(terms)28 b(of)i(number)e(of)h(nodes\).)43 +b(The)29 b(application)f(of)h(this)f(method)g(is)g(then)h(limited)e(to) +i(the)g(cases)g(in)f(which)h(the)-189 820 y(\223of)n(f-set\224)c(of)f +(the)g(represented)h(function)f Fd(f)35 b Fl(has)24 b(a)h(small)f +(cardinality)-6 b(.)29 b(The)c Fc(A)n(uxiliary-V)-11 +b(ariable-Cut)22 b Fl(strate)o(gy)h(is)-189 940 y(a)k(trade-of)n(f)h +(between)f(the)g(\002rst)g(tw)o(o)g(methods)f(and)h(the)g(ones)f(which) +h(gi)n(v)o(es)f(more)h(compact)f(results.)37 b(As)27 +b(a)h(\002nal)-189 1061 y(remark)f(notice)e(that)h(the)g(method)g(is)f +(able)i(to)f(store)g(both)f(monolithic)f(BDDs)j(and)f(conjuncti)n(v)o +(e)e(forms.)35 b(In)26 b(each)-189 1181 y(case)f(we)g(generate)h(CNF)f +(\002les)g(using)f(the)h(standard)f(DIMA)l(CS)i(format.)-189 +1365 y Fi(Example)f(1)49 b Fc(F)l(igur)l(e)20 b(1)h(shows)f(an)h(e)n +(xample)g(of)f(how)h(our)f(pr)l(ocedur)l(e)h(works)f(to)h(stor)l(e)f(a) +h(small)f(monolithic)f(BDD.)-189 1486 y(F)l(igur)l(e)j(1\(a\))h(r)l +(epr)l(esents)g(a)g(BDD)g(with)g Fb(4)g Fc(nodes.)30 +b(BDD)23 b(variables)f(ar)l(e)h(named)g(after)f(inte)l(g)o(er)g(number) +o(s)h(r)o(anging)-189 1606 y(fr)l(om)k Fb(1)h Fc(to)g +Fb(4)p Fc(,)h(to)f(have)g(an)g(easy-to-follow)f(corr)l(espondence)h +(with)g(the)g(CNF)h(variables.)40 b(F)l(igur)l(e)27 b(1\(b\),)i(\(c\))g +(and)-189 1727 y(\(d\))c(show)g(the)f(corr)l(esponding)f(CNF)j(r)l(epr) +l(esentations)d(g)o(ener)o(ated)h(by)h(our)f(thr)l(ee)h(methods.)30 +b(As)24 b(in)h(the)f(standar)l(d)-189 1847 y(format)i +Fa(p)i Fc(indicates)e(the)h(total)f(number)g(of)h(variables)f(used)h +(\()p Fb(4)g Fc(is)g(the)g(minimum)f(value)h(as)g(the)g(BDD)g(itself)f +(has)-189 1967 y Fb(4)f Fc(variables\),)e(and)i Fa(cnf)g +Fc(the)f(total)g(number)g(of)h(clauses.)47 2088 y(As)i(a)g(\002nal)f(r) +l(emark)h(notice)f(that)g(for)g(this)g(speci\002c)h(e)n(xample)g(the)f +(\223Maxterm-Cut\224)i(appr)l(oac)o(h)d(is)h(the)h(one)-189 +2208 y(whic)o(h)36 b(gives)g(the)g(most)f(compact)h(CNF)h(r)l(epr)l +(esentation)e(b)n(ut)h(also)f(the)h(clause)g(with)g(the)g(lar)l(g)o +(est)g(number)f(of)-189 2328 y(liter)o(als)23 b(\()p +Fb(4)p Fc(\).)188 2471 y + 6339814 10777681 0 0 11709153 19997655 startTexFig + 188 2471 a +%%BeginDocument: bdd.eps +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: bdd.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3c +%%CreationDate: Mon Sep 9 14:21:26 2002 +%%For: quer@pcsq (Stefano Quer) +%%BoundingBox: 0 0 178 304 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 304 moveto 0 0 lineto 178 0 lineto 178 304 lineto closepath clip newpath +-51.0 319.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawEllipse { + /endangle exch def + /startangle exch def + /yrad exch def + /xrad exch def + /y exch def + /x exch def + /savematrix mtrx currentmatrix def + x y tr xrad yrad sc 0 0 1 startangle endangle arc + closepath + savematrix setmatrix + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06299 0.06299 sc +% +% Fig objects follow +% +% Polyline +15.000 slw +n 2010 4515 m 2550 4515 l 2550 5040 l 2010 5040 l + cp gs col0 s gr +/Times-Roman ff 300.00 scf sf +2205 4875 m +gs 1 -1 sc (1) col0 sh gr +% Ellipse +n 1515 1800 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2250 900 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2970 2715 270 270 0 360 DrawEllipse gs col0 s gr + +% Ellipse +n 2280 3705 270 270 0 360 DrawEllipse gs col0 s gr + +7.500 slw +% Ellipse +n 3555 3555 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2712 1726 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2430 4230 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Polyline +15.000 slw +n 2805 2910 m + 2250 3450 l gs col0 s gr +% Polyline + [90] 0 sd +gs clippath +2940 2472 m 3010 2445 l 2931 2239 l 2957 2411 l 2861 2266 l cp +eoclip +n 2460 1110 m + 2970 2445 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 2861 2266 m 2957 2411 l 2931 2239 l 2908 2284 l 2861 2266 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +1478 1511 m 1528 1568 l 1693 1422 l 1542 1506 l 1643 1366 l cp +eoclip +n 2025 1080 m + 1515 1530 l gs col0 s gr gr + +% arrowhead +n 1643 1366 m 1542 1506 l 1693 1422 l 1643 1416 l 1643 1366 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +2212 645 m 2287 645 l 2287 425 l 2250 594 l 2212 425 l cp +eoclip +n 2250 270 m + 2250 630 l gs col0 s gr gr + +% arrowhead +n 2212 425 m 2250 594 l 2287 425 l 2250 459 l 2212 425 l + cp gs 0.00 setgray ef gr col0 s +% Polyline + [90] 0 sd +gs clippath +2692 2664 m 2732 2601 l 2546 2485 l 2670 2606 l 2506 2548 l cp +eoclip +n 1710 2010 m + 2700 2625 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 2506 2548 m 2670 2606 l 2546 2485 l 2555 2534 l 2506 2548 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj + [90] 0 sd +gs clippath +2504 4653 m 2539 4720 l 2733 4616 l 2567 4663 l 2698 4550 l cp +eoclip +n 3180 2910 m 3181 2911 l 3183 2913 l 3186 2916 l 3192 2921 l 3200 2929 l + 3210 2939 l 3223 2951 l 3238 2966 l 3255 2984 l 3274 3003 l + 3295 3025 l 3317 3049 l 3339 3075 l 3362 3103 l 3385 3131 l + 3407 3161 l 3429 3192 l 3450 3225 l 3470 3258 l 3488 3293 l + 3504 3329 l 3519 3367 l 3531 3406 l 3541 3447 l 3548 3490 l + 3552 3536 l 3552 3583 l 3548 3634 l 3540 3686 l 3528 3740 l + 3510 3795 l 3490 3844 l 3467 3892 l 3441 3939 l 3413 3985 l + 3382 4028 l 3350 4070 l 3317 4110 l 3283 4148 l 3248 4184 l + 3211 4219 l 3174 4253 l 3136 4285 l 3098 4316 l 3059 4347 l + 3020 4376 l 2980 4405 l 2941 4432 l 2901 4459 l 2862 4484 l + 2824 4509 l 2787 4532 l 2751 4554 l 2717 4575 l 2686 4593 l + 2657 4610 l 2631 4626 l 2608 4639 l 2589 4650 l 2572 4659 l + 2559 4666 l 2550 4672 l + 2535 4680 l gs col0 s gr gr + [] 0 sd +% arrowhead +0 slj +n 2698 4550 m 2567 4663 l 2733 4616 l 2686 4599 l 2698 4550 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +1985 4734 m 2028 4672 l 1847 4548 l 1965 4675 l 1804 4609 l cp +eoclip +n 1350 2025 m 1349 2026 l 1348 2027 l 1345 2030 l 1340 2035 l 1334 2042 l + 1325 2051 l 1314 2063 l 1301 2078 l 1286 2095 l 1268 2114 l + 1249 2137 l 1227 2161 l 1205 2188 l 1181 2218 l 1156 2249 l + 1131 2282 l 1105 2316 l 1080 2352 l 1054 2390 l 1029 2428 l + 1005 2468 l 981 2509 l 959 2552 l 938 2595 l 918 2640 l + 900 2687 l 884 2736 l 870 2786 l 858 2839 l 848 2894 l + 841 2951 l 837 3011 l 836 3074 l 838 3139 l 845 3206 l + 855 3275 l 870 3345 l 888 3412 l 910 3477 l 934 3542 l + 961 3604 l 990 3665 l 1022 3723 l 1054 3779 l 1088 3833 l + 1124 3885 l 1160 3935 l 1198 3983 l 1236 4029 l 1275 4074 l + 1315 4118 l 1356 4160 l 1397 4201 l 1438 4241 l 1480 4280 l + 1522 4318 l 1563 4355 l 1605 4390 l 1645 4424 l 1685 4457 l + 1723 4488 l 1760 4517 l 1795 4545 l 1827 4570 l 1857 4593 l + 1884 4613 l 1909 4632 l 1930 4647 l 1947 4660 l 1962 4671 l + 1973 4679 l 1982 4686 l + 1995 4695 l gs col0 s gr gr + +% arrowhead +0 slj +n 1804 4609 m 1965 4675 l 1847 4548 l 1854 4598 l 1804 4609 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj + [90] 0 sd +gs clippath +2300 4492 m 2363 4532 l 2481 4347 l 2359 4470 l 2417 4307 l cp +eoclip +n 2340 3960 m 2341 3962 l 2344 3966 l 2348 3973 l 2354 3982 l 2362 3995 l + 2370 4010 l 2379 4028 l 2389 4046 l 2397 4066 l 2406 4088 l + 2413 4111 l 2420 4137 l 2425 4165 l 2429 4197 l 2430 4230 l + 2429 4263 l 2425 4295 l 2420 4323 l 2413 4349 l 2406 4372 l + 2397 4394 l 2389 4414 l 2379 4433 l 2370 4450 l 2362 4465 l + 2354 4478 l + 2340 4500 l gs col0 s gr gr + [] 0 sd +% arrowhead +0 slj +n 2417 4307 m 2359 4470 l 2481 4347 l 2431 4356 l 2417 4307 l + cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +2136 4532 m 2199 4492 l 2082 4307 l 2141 4470 l 2018 4347 l cp +eoclip +n 2160 3960 m 2159 3962 l 2156 3966 l 2152 3973 l 2146 3982 l 2138 3995 l + 2130 4010 l 2121 4028 l 2111 4046 l 2103 4066 l 2094 4088 l + 2087 4111 l 2080 4137 l 2075 4165 l 2071 4197 l 2070 4230 l + 2071 4263 l 2075 4295 l 2080 4323 l 2087 4349 l 2094 4372 l + 2103 4394 l 2111 4414 l 2121 4433 l 2130 4450 l 2138 4465 l + 2146 4478 l + 2160 4500 l gs col0 s gr gr + +% arrowhead +0 slj +n 2018 4347 m 2141 4470 l 2082 4307 l 2068 4356 l 2018 4347 l + cp gs 0.00 setgray ef gr col0 s +/Times-Roman ff 300.00 scf sf +2175 990 m +gs 1 -1 sc (1) col0 sh gr +/Times-Roman ff 300.00 scf sf +1440 1890 m +gs 1 -1 sc (2) col0 sh gr +/Times-Roman ff 300.00 scf sf +2895 2805 m +gs 1 -1 sc (3) col0 sh gr +/Times-Roman ff 300.00 scf sf +2205 3795 m +gs 1 -1 sc (4) col0 sh gr +$F2psEnd +rs + +%%EndDocument + + endTexFig + 531 3990 a Fc(\(a\))1512 2504 y Fg(p)60 b(cnf)f(7)g(11)1512 +2624 y(-5)g(3)h(0)1512 2745 y(-5)f(4)h(0)1512 2865 y(5)g(-3)f(-4)g(0) +1512 2985 y(6)h(-2)f(0)1512 3106 y(6)h(-5)f(0)1512 3226 +y(-6)g(2)h(5)f(0)1512 3347 y(7)h(1)f(5)h(0)1512 3467 +y(-7)f(1)h(-5)f(0)1512 3587 y(7)h(-1)f(-6)g(0)1512 3708 +y(-7)g(-1)h(6)f(0)1512 3828 y(7)h(0)1836 3990 y Fc(\(b\))2541 +2525 y Fg(p)f(cnf)g(4)h(3)2541 2645 y(1)f(-3)h(-4)f(0)2541 +2766 y(-1)g(2)h(3)f(0)2541 2886 y(-1)g(2)h(-3)f(4)h(0)2868 +3048 y Fc(\(c\))2541 3251 y Fg(p)f(cnf)g(5)h(5)2541 3371 +y(-5)f(1)h(0)2541 3492 y(5)f(-1)h(2)f(0)2541 3612 y(-3)g(-4)g(5)h(0) +2541 3733 y(3)f(-5)h(0)2541 3853 y(-3)f(4)h(-5)f(0)2865 +3990 y Fc(\(d\))-189 4138 y Fl(Figure)46 b(1:)71 b(\(a\))47 +b(BDD;)e(\(b\))h(\223Single-Node-Cut\224)g(format;)55 +b(\(c\))46 b(\223Maxterm-Cut\224)g(format;)55 b(\(d\))45 +b(\223)-8 b(Auxiliary-)-189 4258 y(V)d(ariable-Cut\224)25 +b(F)o(ormat.)-189 4625 y Fj(3.2)119 b(Implementation)-189 +4813 y Fl(Store)25 b(and)g(Load)g(for)g(a)g(single)f(BDD)h(or)g(a)g +(forest)g(of)g(BDDs)g(is)f(currently)h(implemented.)-189 +5073 y Fi(3.2.1)99 b(Storing)25 b(Decision)g(Diagrams)f(as)g(CNF)h(F)n +(ormulas)-189 5260 y Fl(As)g(f)o(ar)g(as)g(the)g(storing)e(process)i +(is)f(concerned)i(three)f(possible)e(formats)h(are)i(a)n(v)n(ailable:) +-44 5431 y Fk(\017)49 b Fl(DDDMP)p 421 5431 30 4 v 36 +w(CNF)p 650 5431 V 36 w(MODE)p 980 5431 V 35 w(NODE:)21 +b(store)f(a)h(BDD)h(by)e(introducing)f(an)i(auxiliary)g(v)n(ariable)f +(for)h(each)g(BDD)55 5551 y(node)1794 5800 y(8)p eop +%%Page: 9 9 +9 8 bop -44 218 a Fk(\017)49 b Fl(DDDMP)p 421 218 30 +4 v 36 w(CNF)p 650 218 V 36 w(MODE)p 980 218 V 35 w(MAXTERM:)20 +b(store)g(a)h(BDD)h(by)e(follo)n(wing)f(the)h(maxterm)g(of)h(the)g +(represented)55 338 y(function)-44 542 y Fk(\017)49 b +Fl(DDDMP)p 421 542 V 36 w(CNF)p 650 542 V 36 w(MODE)p +980 542 V 35 w(BEST)-5 b(:)32 b(trade-of)f(between)h(the)f(tw)o(o)f +(pre)n(vious)g(solution,)h(trying)f(to)h(optimize)55 +662 y(the)25 b(number)f(of)h(literals)f(stored.)-189 +865 y(See)c(procedures)f(Dddmp)p 736 865 V 35 w(cuddBddStoreCnf)g(\(to) +g(store)f(a)h(single)f(BDD)i(as)e(a)i(CNF)f(formula\))g(and)g(Dddmp)p +3609 865 V 34 w(cuddBddArrayStoreCnf)-189 986 y(\(to)25 +b(store)f(an)h(array)h(of)f(BDDs)g(as)f(a)i(CNF)f(formula\).)-189 +1252 y Fi(3.2.2)99 b(Loadinf)26 b(CNF)e(F)n(ormulas)g(as)h(BDDs)-189 +1439 y Fl(As)g(f)o(ar)g(as)g(the)g(loading)e(process)i(is)f(concerned)i +(three)f(possible)e(formats)i(are)g(a)n(v)n(ailable:)-44 +1643 y Fk(\017)49 b Fl(DDDMP)p 421 1643 V 36 w(CNF)p +650 1643 V 36 w(MODE)p 980 1643 V 35 w(NO)p 1159 1643 +V 36 w(CONJ:)25 b(Return)g(the)f(Clauses)h(without)f(Conjunction)-44 +1846 y Fk(\017)49 b Fl(DDDMP)p 421 1846 V 36 w(CNF)p +650 1846 V 36 w(MODE)p 980 1846 V 35 w(NO)p 1159 1846 +V 36 w(Q)o(U)l(ANT)-5 b(:)24 b(Return)h(the)g(sets)f(of)h(BDDs)g +(without)f(Quanti\002cation)-44 2050 y Fk(\017)49 b Fl(DDDMP)p +421 2050 V 36 w(CNF)p 650 2050 V 36 w(MODE)p 980 2050 +V 35 w(CONJ)p 1264 2050 V 36 w(Q)o(U)l(ANT)-5 b(:)23 +b(Return)h(the)g(sets)f(of)h(BDDs)g(AFTER)g(Existential)e(Quanti\002-) +55 2170 y(cation)-189 2373 y(See)e(procedures)f(Dddmp)p +736 2373 V 35 w(cuddBddLoadCnf)f(\(to)h(load)f(a)i(CNF)f(formula)g(as)g +(a)g(single)f(BDD\))h(and)g(Dddmp)p 3581 2373 V 35 w +(cuddBddArrayLoadCnf)-189 2494 y(\(to)35 b(load)h(a)g(CNF)g(formula)f +(as)h(an)g(array)g(of)g(BDDs\).)63 b(See)36 b(also)g(Dddmp)p +2485 2494 V 34 w(cuddHeaderLoadCnf)h(to)e(load)g(the)-189 +2614 y(header)25 b(of)g(a)g(CNF)h(\002le)f(to)g(gather)f(information)f +(on)i(the)g(sa)n(v)o(ed)f(structure.)-189 2954 y Fo(4)143 +b(T)-13 b(est)35 b(Pr)m(ogram)f(and)h(Regr)m(ession)f(T)-13 +b(ests)-189 3177 y Fl(The)20 b Fc(testddmp.c)e Fl(\002le,)j(pro)o +(vided)d(with)h(this)f(distrib)n(ution,)g(e)o(x)o(empli\002es)g(some)h +(of)h(the)f(abo)o(v)o(e)g(features.)29 b(Moreo)o(v)o(er)l(,)-189 +3298 y(in)d(the)h Fc(e)n(xp)g Fl(e)o(xperiments)e(a)j(fe)n(w)e +(scripts,)h(named)f Fc(test\241n\277.script)f Fl(are)i(a)n(v)n(ailable) +f(for)h(a)g(sanity)f(check)h(of)g(the)g(tool)-189 3418 +y(and)e(to)f(tak)o(e)h(a)g(look)f(at)h(some)f(runs)h(e)o(x)o +(empli\002cation.)-189 3758 y Fo(5)143 b(Documentation)-189 +3981 y Fl(F)o(or)27 b(further)f(documentation)f(on)i(the)f(package)h +(see)g(the)g(on-line)f(documentation)f(automatically)g(created)i(from) +-189 4102 y(the)e(source)g(code)g(\002les.)-189 4441 +y Fo(6)143 b(Ackno)o(wledgments)-189 4665 y Fl(W)-8 b(e)19 +b(are)h(particular)f(indebted)f(with)g(F)o(abio)g(Somenzi,)i(for)f +(discussions,)f(advice,)i(and)f(for)g(including)e(the)i(DDDMP)-189 +4785 y(package)28 b(into)f(the)h(CUDD)g(distrib)n(ution.)37 +b(W)-8 b(e)29 b(also)e(thank)g(all)h(the)g(user)g(of)g(the)f(package)i +(for)f(their)f(useful)h(indi-)-189 4905 y(cation)c(and)h(comments)f(on) +g(the)h(it.)1794 5800 y(9)p eop +%%Page: 10 10 +10 9 bop -189 218 a Fo(7)143 b(FTP)35 b(Site)-189 441 +y Fl(The)25 b(package)g(is)f(singularly)g(a)n(v)n(ailable)g(from:)-189 +645 y Fg(site:)59 b(ftp.polito.it)-189 765 y(user:)g(anonymous)-189 +885 y(directory:)f(/pub/research/dddmp)-189 1089 y Fl(or)25 +b(directly)f(from)h(the)f(author)h(WEB)g(pages:)-189 +1292 y Fg(WWW:)59 b(http://www.polito.it/\230{cabodi)o(,quer)o(})-189 +1632 y Fo(8)143 b(F)l(eedback)-189 1855 y Fl(Send)25 +b(feedback)h(to:)-189 2059 y Fg(Gianpiero)58 b(Cabodi)g(&)i(Stefano)e +(Quer)-189 2179 y(Politecnico)f(di)j(Torino)-189 2300 +y(Dipartimento)d(di)i(Automatica)f(e)i(Informatica)-189 +2420 y(Corso)f(Duca)g(degli)f(Abruzzi,)g(24)-189 2540 +y(I-10129)g(Torino)-189 2661 y(Italy)-189 2781 y(E-mail:)g +({cabodi,quer}@polito.it)-189 2901 y(WWW:)h +(http://www.polito.it/\230{cabodi)o(,quer)o(})1769 5800 +y Fl(10)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllAbs.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllAbs.html new file mode 100644 index 000000000..5cd6c2a3e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllAbs.html @@ -0,0 +1,483 @@ + +dddmp package abstract + + + + + +
                          +
                          DddmpBddReadHeaderCnf() +
                          Reads a the header of a dump file representing the argument + BDDs. + +
                          DddmpBddReadHeader() +
                          Reads a the header of a dump file representing the + argument BDDs. + +
                          DddmpClearVisitedAdd() +
                          Marks a node as not visited + +
                          DddmpClearVisitedBdd() +
                          Marks a node as not visited + +
                          DddmpClearVisitedCnfRecur() +
                          Mark ALL nodes as not visited + +
                          DddmpClearVisitedCnfRecur() +
                          Mark ALL nodes as not visited + +
                          DddmpClearVisitedCnf() +
                          Marks a node as not visited + +
                          DddmpClearVisitedCnf() +
                          Marks a node as not visited + +
                          DddmpClearVisited() +
                          Marks a node as not visited + +
                          DddmpCnfClauses2Bdd() +
                          Transforms CNF clauses into BDDs. + +
                          DddmpCuddBddArrayStoreCnf() +
                          Writes a dump file representing the argument Array of + BDDs in the CNF standard format. + +
                          DddmpCuddBddArrayStore() +
                          Writes a dump file representing the argument Array of + BDDs. + +
                          DddmpCuddDdArrayLoadCnf() +
                          Reads a dump file representing the argument BDDs in CNF + format. + +
                          DddmpCuddDdArrayLoad() +
                          Reads a dump file representing the argument BDDs. + +
                          DddmpCuddDdArrayStoreBdd() +
                          Writes a dump file representing the argument Array of + BDDs/ADDs. + +
                          DddmpCuddDdArrayStoreBlifBody() +
                          Writes a blif body representing the argument BDDs. + +
                          DddmpCuddDdArrayStoreBlifStep() +
                          Performs the recursive step of DddmpCuddDdArrayStoreBlif. + +
                          DddmpCuddDdArrayStoreBlif() +
                          Writes a blif file representing the argument BDDs. + +
                          DddmpCuddDdArrayStorePrefixBody() +
                          Internal function to writes a dump file representing the + argument BDD in a prefix notation. Writes the body of the file. + +
                          DddmpCuddDdArrayStorePrefixStep() +
                          Performs the recursive step of + DddmpCuddDdArrayStorePrefixBody. + +
                          DddmpCuddDdArrayStorePrefix() +
                          Internal function to writes a dump file representing the + argument BDD in a prefix notation. + +
                          DddmpCuddDdArrayStoreSmvBody() +
                          Internal function to writes a dump file representing the + argument BDD in a SMV notation. Writes the body of the file. + +
                          DddmpCuddDdArrayStoreSmvStep() +
                          Performs the recursive step of + DddmpCuddDdArrayStoreSmvBody. + +
                          DddmpCuddDdArrayStoreSmv() +
                          Internal function to writes a dump file representing the + argument BDD in a SMV notation. + +
                          DddmpDdNodesCheckIncomingAndScanPath() +
                          Number nodes recursively in post-order + +
                          DddmpDdNodesCheckIncomingAndScanPath() +
                          Number nodes recursively in post-order + +
                          DddmpDdNodesCountEdgesAndNumber() +
                          Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. + +
                          DddmpDdNodesCountEdgesAndNumber() +
                          Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. + +
                          DddmpDdNodesCountEdgesRecur() +
                          Counts the number of incoming edges for each node of a BDD + +
                          DddmpDdNodesCountEdgesRecur() +
                          Counts the number of incoming edges for each node of a BDD + +
                          DddmpDdNodesNumberEdgesRecur() +
                          Number nodes recursively in post-order + +
                          DddmpDdNodesNumberEdgesRecur() +
                          Number nodes recursively in post-order + +
                          DddmpDdNodesResetCountRecur() +
                          Resets counter and visited flag for ALL nodes of a BDD + +
                          DddmpDdNodesResetCountRecur() +
                          Resets counter and visited flag for ALL nodes of a BDD + +
                          DddmpFreeHeaderCnf() +
                          Frees the internal header structure. + +
                          DddmpFreeHeader() +
                          Frees the internal header structure. + +
                          DddmpIntArrayDup() +
                          Duplicates an array of ints + +
                          DddmpIntArrayRead() +
                          Inputs an array of ints + +
                          DddmpIntArrayWrite() +
                          Outputs an array of ints + +
                          DddmpNumberAddNodes() +
                          Removes nodes from unique table and number them + +
                          DddmpNumberBddNodes() +
                          Removes nodes from unique table and number them + +
                          DddmpNumberDdNodesCnf() +
                          Removes nodes from unique table and numbers them + +
                          DddmpNumberDdNodesCnf() +
                          Removes nodes from unique table and numbers them + +
                          DddmpNumberDdNodes() +
                          Removes nodes from unique table and number them + +
                          DddmpPrintBddAndNextRecur() +
                          Prints debug info + +
                          DddmpPrintBddAndNextRecur() +
                          Prints debug info + +
                          DddmpPrintBddAndNext() +
                          Prints debug information + +
                          DddmpPrintBddAndNext() +
                          Prints debug information + +
                          DddmpReadCnfClauses() +
                          Read the CNF clauses from the file in the standard DIMACS + format. + +
                          DddmpReadCode() +
                          Reads a 1 byte node code + +
                          DddmpReadInt() +
                          Reads a "packed integer" + +
                          DddmpReadNodeIndexAdd() +
                          Reads the index of a node + +
                          DddmpReadNodeIndexBdd() +
                          Reads the index of a node + +
                          DddmpReadNodeIndexCnf() +
                          Reads the index of a node + +
                          DddmpReadNodeIndexCnf() +
                          Reads the index of a node + +
                          DddmpReadNodeIndex() +
                          Reads the index of a node + +
                          DddmpSetVisitedAdd() +
                          Marks a node as visited + +
                          DddmpSetVisitedBdd() +
                          Marks a node as visited + +
                          DddmpSetVisitedCnf() +
                          Marks a node as visited + +
                          DddmpSetVisitedCnf() +
                          Marks a node as visited + +
                          DddmpSetVisited() +
                          Marks a node as visited + +
                          DddmpStrArrayDup() +
                          Duplicates an array of strings + +
                          DddmpStrArrayFree() +
                          Frees an array of strings + +
                          DddmpStrArrayRead() +
                          Inputs an array of strings + +
                          DddmpStrArrayWrite() +
                          Outputs an array of strings + +
                          DddmpStrDup() +
                          Duplicates a string + +
                          DddmpUnnumberAddNodes() +
                          Restores nodes in unique table, loosing numbering + +
                          DddmpUnnumberBddNodes() +
                          Restores nodes in unique table, loosing numbering + +
                          DddmpUnnumberDdNodesCnf() +
                          Restores nodes in unique table, loosing numbering + +
                          DddmpUnnumberDdNodesCnf() +
                          Restores nodes in unique table, loosing numbering + +
                          DddmpUnnumberDdNodes() +
                          Restores nodes in unique table, loosing numbering + +
                          DddmpVisitedAdd() +
                          Returns true if node is visited + +
                          DddmpVisitedBdd() +
                          Returns true if node is visited + +
                          DddmpVisitedCnf() +
                          Returns true if node is visited + +
                          DddmpVisitedCnf() +
                          Returns true if node is visited + +
                          DddmpVisited() +
                          Returns true if node is visited + +
                          DddmpWriteCode() +
                          Writes 1 byte node code + +
                          DddmpWriteInt() +
                          Writes a "packed integer" + +
                          DddmpWriteNodeIndexAdd() +
                          Write index to node + +
                          DddmpWriteNodeIndexBdd() +
                          Write index to node + +
                          DddmpWriteNodeIndexCnfBis() +
                          Write index to node + +
                          DddmpWriteNodeIndexCnfWithTerminalCheck() +
                          Write index to node + +
                          DddmpWriteNodeIndexCnf() +
                          Write index to node + +
                          DddmpWriteNodeIndexCnf() +
                          Write index to node + +
                          DddmpWriteNodeIndex() +
                          Write index to node + +
                          Dddmp_Bin2Text() +
                          Converts from binary to ASCII format + +
                          Dddmp_Text2Bin() +
                          Converts from ASCII to binary format + +
                          Dddmp_cuddAddArrayLoad() +
                          Reads a dump file representing the argument ADDs. + +
                          Dddmp_cuddAddArrayStore() +
                          Writes a dump file representing the argument Array of ADDs. + +
                          Dddmp_cuddAddLoad() +
                          Reads a dump file representing the argument ADD. + +
                          Dddmp_cuddAddStore() +
                          Writes a dump file representing the argument ADD. + +
                          Dddmp_cuddBddArrayLoadCnf() +
                          Reads a dump file in a CNF format. + +
                          Dddmp_cuddBddArrayLoad() +
                          Reads a dump file representing the argument BDDs. + +
                          Dddmp_cuddBddArrayStoreBlif() +
                          Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
                          Dddmp_cuddBddArrayStoreCnf() +
                          Writes a dump file representing the argument array of BDDs + in CNF format. + +
                          Dddmp_cuddBddArrayStorePrefix() +
                          Writes a dump file representing the argument BDD in + a prefix notation. + +
                          Dddmp_cuddBddArrayStoreSmv() +
                          Writes a dump file representing the argument BDD in + a prefix notation. + +
                          Dddmp_cuddBddArrayStore() +
                          Writes a dump file representing the argument Array of BDDs. + +
                          Dddmp_cuddBddDisplayBinary() +
                          Display a binary dump file in a text file + +
                          Dddmp_cuddBddLoadCnf() +
                          Reads a dump file in a CNF format. + +
                          Dddmp_cuddBddLoad() +
                          Reads a dump file representing the argument BDD. + +
                          Dddmp_cuddBddStoreBlif() +
                          Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
                          Dddmp_cuddBddStoreCnf() +
                          Writes a dump file representing the argument BDD in + a CNF format. + +
                          Dddmp_cuddBddStorePrefix() +
                          Writes a dump file representing the argument BDD in + a prefix notation. + +
                          Dddmp_cuddBddStoreSmv() +
                          Writes a dump file representing the argument BDD in + a prefix notation. + +
                          Dddmp_cuddBddStore() +
                          Writes a dump file representing the argument BDD. + +
                          Dddmp_cuddHeaderLoadCnf() +
                          Reads the header of a dump file representing the argument BDDs + +
                          Dddmp_cuddHeaderLoad() +
                          Reads the header of a dump file representing the argument BDDs + +
                          FindVarname() +
                          Performs binary search of a name within a sorted array + +
                          NodeBinaryStoreBdd() +
                          Store One Single Node in Binary Format. + +
                          NodeStoreRecurAdd() +
                          Performs the recursive step of Dddmp_bddStore. + +
                          NodeStoreRecurBdd() +
                          Performs the recursive step of Dddmp_bddStore. + +
                          NodeTextStoreAdd() +
                          Store One Single Node in Text Format. + +
                          NodeTextStoreBdd() +
                          Store One Single Node in Text Format. + +
                          NumberNodeRecurAdd() +
                          Number nodes recursively in post-order + +
                          NumberNodeRecurBdd() +
                          Number nodes recursively in post-order + +
                          NumberNodeRecurCnf() +
                          Number nodes recursively in post-order + +
                          NumberNodeRecurCnf() +
                          Number nodes recursively in post-order + +
                          NumberNodeRecur() +
                          Number nodes recursively in post-order + +
                          QsortStrcmp() +
                          String compare for qsort + +
                          ReadByteBinary() +
                          Reads a byte from file with escaped , and + +
                          RemoveFromUniqueRecurAdd() +
                          Removes a node from unique table + +
                          RemoveFromUniqueRecurBdd() +
                          Removes a node from unique table + +
                          RemoveFromUniqueRecurCnf() +
                          Removes a node from unique table + +
                          RemoveFromUniqueRecurCnf() +
                          Removes a node from unique table + +
                          RemoveFromUniqueRecur() +
                          Removes a node from unique table + +
                          RestoreInUniqueRecurAdd() +
                          Restores a node in unique table + +
                          RestoreInUniqueRecurBdd() +
                          Restores a node in unique table + +
                          RestoreInUniqueRecurCnf() +
                          Restores a node in unique table + +
                          RestoreInUniqueRecurCnf() +
                          Restores a node in unique table + +
                          RestoreInUniqueRecur() +
                          Restores a node in unique table + +
                          StoreCnfBestNotSharedRecur() +
                          Performs the recursive step of Print Best on Not Shared + sub-BDDs. + +
                          StoreCnfBestSharedRecur() +
                          Performs the recursive step of Print Best on Shared + sub-BDDs. + +
                          StoreCnfBest() +
                          Prints a disjoint sum of products with intermediate + cutting points. + +
                          StoreCnfMaxtermByMaxtermRecur() +
                          Performs the recursive step of Print Maxterm. + +
                          StoreCnfMaxtermByMaxterm() +
                          Prints a disjoint sum of products. + +
                          StoreCnfNodeByNodeRecur() +
                          Performs the recursive step of Dddmp_bddStore. + +
                          StoreCnfNodeByNode() +
                          Store the BDD as CNF clauses. + +
                          StoreCnfOneNode() +
                          Store One Single BDD Node. + +
                          WriteByteBinary() +
                          Writes a byte to file filtering , and + +
                          printCubeCnf() +
                          Print One Cube in CNF Format. + +
                          () +
                          Checks for Warnings: If expr==1 it prints out the warning + on stderr. + +
                          () +
                          Checks for fatal bugs + +
                          () +
                          Checks for fatal bugs and go to the label to deal with + the error. + +
                          () +
                          Checks for fatal bugs and return the DDDMP_FAILURE flag. + +
                          () +
                          Memory Allocation Macro for DDDMP + +
                          () +
                          Memory Free Macro for DDDMP + +
                          + +
                          + +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllByFile.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllByFile.html new file mode 100644 index 000000000..f414ee60d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllByFile.html @@ -0,0 +1,13 @@ + +The dddmp package for maintainers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllByFunc.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllByFunc.html new file mode 100644 index 000000000..76671dac0 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllByFunc.html @@ -0,0 +1,13 @@ + +The dddmp package for maintainers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllDet.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllDet.html new file mode 100644 index 000000000..9d8e7ba33 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllDet.html @@ -0,0 +1,3704 @@ + +The dddmp package: all functions + + +A set of internal low-level routines of the dddmp package + doing: +
                            +
                          • read and write of node codes in binary mode, +
                          • read and write of integers in binary mode, +
                          • marking/unmarking nodes as visited, +
                          • numbering nodes. +
                          +
                          +
                          +
                          +
                          +static Dddmp_Hdr_t * 
                          +DddmpBddReadHeaderCnf(
                          +  char * file, IN: file name
                          +  FILE * fp IN: file pointer
                          +)
                          +
                          +
                          Reads the header of a dump file. Builds a Dddmp_Hdr_t struct + containing all infos in the header, for next manipulations. +

                          + +

                          Side Effects none +

                          + +

                          Defined in dddmpLoadCnf.c + +
                          +
                          +static Dddmp_Hdr_t * 
                          +DddmpBddReadHeader(
                          +  char * file, IN: file name
                          +  FILE * fp IN: file pointer
                          +)
                          +
                          +
                          Reads the header of a dump file. Builds a Dddmp_Hdr_t struct + containing all infos in the header, for next manipulations. +

                          + +

                          Side Effects none +

                          + +

                          Defined in dddmpLoad.c + +
                          +
                          +void 
                          +DddmpClearVisitedAdd(
                          +  DdNode * f IN: BDD node to be marked (as not visited)
                          +)
                          +
                          +
                          Marks a node as not visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpVisitedAdd +() +DddmpSetVisitedAdd +() + + +
                          Defined in dddmpNodeAdd.c + +
                          +
                          +void 
                          +DddmpClearVisitedBdd(
                          +  DdNode * f IN: BDD node to be marked (as not visited)
                          +)
                          +
                          +
                          Marks a node as not visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpVisited +() +DddmpSetVisited +() + + +
                          Defined in dddmpNodeBdd.c + +
                          +
                          +static int 
                          +DddmpClearVisitedCnfRecur(
                          +  DdNode * f IN: root of the BDD to be marked
                          +)
                          +
                          +
                          Mark ALL nodes as not visited (it recurs on the node children) +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpVisitedCnf +() +DddmpSetVisitedCnf +() + + +
                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +static int 
                          +DddmpClearVisitedCnfRecur(
                          +  DdNode * f IN: root of the BDD to be marked
                          +)
                          +
                          +
                          Mark ALL nodes as not visited (it recurs on the node children) +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpVisitedCnf +() +DddmpSetVisitedCnf +() + + +
                          Defined in dddmpNodeCnf.c + +
                          +
                          +static void 
                          +DddmpClearVisitedCnf(
                          +  DdNode * f IN: BDD node to be marked (as not visited)
                          +)
                          +
                          +
                          Marks a node as not visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpVisitedCnf +() +DddmpSetVisitedCnf +() + + +
                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +static void 
                          +DddmpClearVisitedCnf(
                          +  DdNode * f IN: BDD node to be marked (as not visited)
                          +)
                          +
                          +
                          Marks a node as not visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpVisitedCnf +() +DddmpSetVisitedCnf +() + + +
                          Defined in dddmpNodeCnf.c + +
                          +
                          +void 
                          +DddmpClearVisited(
                          +  DdNode * f IN: BDD node to be marked (as not visited)
                          +)
                          +
                          +
                          Marks a node as not visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpVisited +() +DddmpSetVisited +() + + +
                          Defined in dddmpDdNodeBdd.c + +
                          +
                          +static int 
                          +DddmpCnfClauses2Bdd(
                          +  Dddmp_Hdr_t * Hdr, IN: file header
                          +  DdManager * ddMgr, IN: DD Manager
                          +  int ** cnfTable, IN: CNF table for clauses
                          +  int  mode, IN: computation mode
                          +  DdNode *** rootsPtrPtr OUT: array of returned BDD roots (by reference)
                          +)
                          +
                          +
                          Transforms CNF clauses into BDDs. Clauses are stored in an + internal structure previously read. The results can be given in + different format according to the mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification +

                          + +

                          Defined in dddmpLoadCnf.c + +
                          +
                          +static int 
                          +DddmpCuddBddArrayStoreCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDD roots to be stored
                          +  int  rootN, IN: # of output BDD roots to be stored
                          +  Dddmp_DecompCnfStoreType  mode, IN: format selection
                          +  int  noHeader, IN: do not store header iff 1
                          +  char ** varNames, IN: array of variable names (or NULL)
                          +  int * bddIds, IN: array of BDD node Ids (or NULL)
                          +  int * bddAuxIds, IN: array of BDD Aux Ids (or NULL)
                          +  int * cnfIds, IN: array of CNF ids (or NULL)
                          +  int  idInitial, IN: starting id for cutting variables
                          +  int  edgeInTh, IN: Max # Incoming Edges
                          +  int  pathLengthTh, IN: Max Path Length
                          +  char * fname, IN: file name
                          +  FILE * fp, IN: pointer to the store file
                          +  int * clauseNPtr, OUT: number of clause stored
                          +  int * varNewNPtr OUT: number of new variable created
                          +)
                          +
                          +
                          Dumps the argument array of BDDs/ADDs to file in CNF format. + The following arrays: varNames, bddIds, bddAuxIds, and cnfIds + fix the correspondence among variable names, BDD ids, BDD + auxiliary ids and the ids used to store the CNF problem. + All these arrays are automatically created iff NULL. + Auxiliary variable, iff necessary, are created starting from value + idInitial. + Iff idInitial is <= 0 its value is selected as the number of internal + CUDD variable + 2. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. +

                          + +

                          Side Effects Nodes are temporarily removed from the unique hash table. + They are re-linked after the store operation in a modified + order. +

                          + +

                          See Also Dddmp_cuddBddStore + + +
                          Defined in dddmpStoreCnf.c + +
                          +
                          +int 
                          +DddmpCuddBddArrayStore(
                          +  Dddmp_DecompType  ddType, IN: Selects the decomp type BDD
                          +  DdManager * ddMgr, IN: DD Manager
                          +  char * ddname, IN: DD name (or NULL)
                          +  int  nRoots, IN: number of output BDD roots to be stored
                          +  DdNode ** f, IN: array of DD roots to be stored
                          +  char ** rootnames, IN: array of root names (or NULL)
                          +  char ** varnames, IN: array of variable names (or NULL)
                          +  int * auxids, IN: array of converted var IDs
                          +  int  mode, IN: storing mode selector
                          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument array of BDDs to file. + Internal function doing inner steps of store for BDDs. +

                          + +

                          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

                          + +

                          See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                          Defined in dddmpStoreBdd.c + +
                          +
                          +static int 
                          +DddmpCuddDdArrayLoadCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  Dddmp_RootMatchType  rootmatchmode, IN: storing mode selector
                          +  char ** rootmatchnames, IN: sorted names for loaded roots
                          +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names, by ids
                          +  int * varmatchauxids, IN: array of variable auxids, by ids
                          +  int * varcomposeids, IN: array of new ids, by ids
                          +  int  mode, IN: computation mode
                          +  char * file, IN: file name
                          +  FILE * fp, IN: file pointer
                          +  DdNode *** rootsPtrPtr, OUT: array of BDD roots
                          +  int * nRoots OUT: number of BDDs returned
                          +)
                          +
                          +
                          Reads a dump file representing the argument BDDs in CNF + format. + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddBddArrayLoad + + +
                          Defined in dddmpLoadCnf.c + +
                          +
                          +static int 
                          +DddmpCuddDdArrayLoad(
                          +  Dddmp_DecompType  ddType, IN: Selects decomp type
                          +  DdManager * ddMgr, IN: DD Manager
                          +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
                          +  char ** rootmatchnames, IN: sorted names for loaded roots
                          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names, by ids
                          +  int * varmatchauxids, IN: array of variable auxids, by ids
                          +  int * varcomposeids, IN: array of new ids, by ids
                          +  int  mode, IN: requested input file format
                          +  char * file, IN: file name
                          +  FILE * fp, IN: file pointer
                          +  DdNode *** pproots OUT: array BDD roots (by reference)
                          +)
                          +
                          +
                          Reads a dump file representing the argument BDDs. The header is + common to both text and binary mode. The node list is either + in text or binary format. A dynamic vector of DD pointers + is allocated to support conversion from DD indexes to pointers. + Several criteria are supported for variable match between file + and dd manager. Several changes/permutations/compositions are allowed + for variables while loading DDs. Variable of the dd manager are allowed + to match with variables on file on ids, permids, varnames, + varauxids; also direct composition between ids and + composeids is supported. More in detail: +
                            +
                          1. varMatchMode=DDDMP_VAR_MATCHIDS

                            + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

                          2. varMatchMode=DDDMP_VAR_MATCHPERMIDS

                            + is used to allow variable match according to the position in the ordering. + +

                          3. varMatchMode=DDDMP_VAR_MATCHNAMES

                            + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

                          4. varMatchMode=DDDMP_VAR_MATCHIDS

                            + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

                          5. varMatchMode=DDDMP_VAR_COMPOSEIDS

                            + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. +

                          + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddBddArrayStore + + +
                          Defined in dddmpLoad.c + +
                          +
                          +int 
                          +DddmpCuddDdArrayStoreBdd(
                          +  Dddmp_DecompType  ddType, IN: Selects the decomp type: BDD or ADD
                          +  DdManager * ddMgr, IN: DD Manager
                          +  char * ddname, IN: DD name (or NULL)
                          +  int  nRoots, IN: number of output BDD roots to be stored
                          +  DdNode ** f, IN: array of DD roots to be stored
                          +  char ** rootnames, IN: array of root names (or NULL)
                          +  char ** varnames, IN: array of variable names (or NULL)
                          +  int * auxids, IN: array of converted var IDs
                          +  int  mode, IN: storing mode selector
                          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument array of BDDs/ADDs to file. Internal + function doing inner steps of store for BDDs and ADDs. + ADD store is presently supported only with the text format. +

                          + +

                          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

                          + +

                          See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                          Defined in dddmpStoreAdd.c + +
                          +
                          +static int 
                          +DddmpCuddDdArrayStoreBlifBody(
                          +  DdManager * ddMgr, IN: Manager
                          +  int  n, IN: Number of output nodes to be dumped
                          +  DdNode ** f, IN: Array of output nodes to be dumped
                          +  char ** inputNames, IN: Array of input names (or NULL)
                          +  char ** outputNames, IN: Array of output names (or NULL)
                          +  FILE * fp IN: Pointer to the dump file
                          +)
                          +
                          +
                          Writes a blif body representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). + DddmpCuddDdArrayStoreBlif does not close the file: This is the + caller responsibility. + DddmpCuddDdArrayStoreBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inputNames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for outputNames. This function prints out only + .names part. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpStoreMisc.c + +
                          +
                          +static int 
                          +DddmpCuddDdArrayStoreBlifStep(
                          +  DdManager * ddMgr, 
                          +  DdNode * f, 
                          +  FILE * fp, 
                          +  st_table * visited, 
                          +  char ** names 
                          +)
                          +
                          +
                          Performs the recursive step of DddmpCuddDdArrayStoreBlif. + Traverses the BDD f and writes a multiplexer-network description to + the file pointed by fp in blif format. + f is assumed to be a regular pointer and DddmpCuddDdArrayStoreBlifStep + guarantees this assumption in the recursive calls. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpStoreMisc.c + +
                          +
                          +static int 
                          +DddmpCuddDdArrayStoreBlif(
                          +  DdManager * ddMgr, IN: Manager
                          +  int  n, IN: Number of output nodes to be dumped
                          +  DdNode ** f, IN: Array of output nodes to be dumped
                          +  char ** inputNames, IN: Array of input names (or NULL)
                          +  char ** outputNames, IN: Array of output names (or NULL)
                          +  char * modelName, IN: Model name (or NULL)
                          +  FILE * fp IN: Pointer to the dump file
                          +)
                          +
                          +
                          Writes a blif file representing the argument BDDs as a + network of multiplexers. One multiplexer is written for each BDD + node. It returns 1 in case of success; 0 otherwise (e.g., + out-of-memory, file system full, or an ADD with constants different + from 0 and 1). + DddmpCuddDdArrayStoreBlif does not close the file: This is the + caller responsibility. + DddmpCuddDdArrayStoreBlif uses a minimal unique subset of + the hexadecimal address of a node as name for it. If the argument + inames is non-null, it is assumed to hold the pointers to the names + of the inputs. Similarly for outputNames. + It prefixes the string "NODE" to each nome to have "regular" names + for each elements. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpCuddDdArrayStoreBlifBody +Cudd_DumpBlif + + +
                          Defined in dddmpStoreMisc.c + +
                          +
                          +static int 
                          +DddmpCuddDdArrayStorePrefixBody(
                          +  DdManager * ddMgr, IN: Manager
                          +  int  n, IN: Number of output nodes to be dumped
                          +  DdNode ** f, IN: Array of output nodes to be dumped
                          +  char ** inputNames, IN: Array of input names (or NULL)
                          +  char ** outputNames, IN: Array of output names (or NULL)
                          +  FILE * fp IN: Pointer to the dump file
                          +)
                          +
                          +
                          One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpCuddDdArrayStoreBlif + + +
                          Defined in dddmpStoreMisc.c + +
                          +
                          +static int 
                          +DddmpCuddDdArrayStorePrefixStep(
                          +  DdManager * ddMgr, 
                          +  DdNode * f, 
                          +  FILE * fp, 
                          +  st_table * visited, 
                          +  char ** names 
                          +)
                          +
                          +
                          Performs the recursive step of + DddmpCuddDdArrayStorePrefixBody. + Traverses the BDD f and writes a multiplexer-network description to the + file pointed by fp. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + f is assumed to be a regular pointer and the function guarantees this + assumption in the recursive calls. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpStoreMisc.c + +
                          +
                          +static int 
                          +DddmpCuddDdArrayStorePrefix(
                          +  DdManager * ddMgr, IN: Manager
                          +  int  n, IN: Number of output nodes to be dumped
                          +  DdNode ** f, IN: Array of output nodes to be dumped
                          +  char ** inputNames, IN: Array of input names (or NULL)
                          +  char ** outputNames, IN: Array of output names (or NULL)
                          +  char * modelName, IN: Model name (or NULL)
                          +  FILE * fp IN: Pointer to the dump file
                          +)
                          +
                          +
                          One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + Comments (COMMENT) are added at the beginning of the description to + describe inputs and outputs of the design. + A buffer (BUF) is add on the output to cope with complemented functions. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpCuddDdArrayStoreBlif + + +
                          Defined in dddmpStoreMisc.c + +
                          +
                          +static int 
                          +DddmpCuddDdArrayStoreSmvBody(
                          +  DdManager * ddMgr, IN: Manager
                          +  int  n, IN: Number of output nodes to be dumped
                          +  DdNode ** f, IN: Array of output nodes to be dumped
                          +  char ** inputNames, IN: Array of input names (or NULL)
                          +  char ** outputNames, IN: Array of output names (or NULL)
                          +  FILE * fp IN: Pointer to the dump file
                          +)
                          +
                          +
                          One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpCuddDdArrayStoreBlif + + +
                          Defined in dddmpStoreMisc.c + +
                          +
                          +static int 
                          +DddmpCuddDdArrayStoreSmvStep(
                          +  DdManager * ddMgr, 
                          +  DdNode * f, 
                          +  FILE * fp, 
                          +  st_table * visited, 
                          +  char ** names 
                          +)
                          +
                          +
                          Performs the recursive step of + DddmpCuddDdArrayStoreSmvBody. + Traverses the BDD f and writes a multiplexer-network description to the + file pointed by fp. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + f is assumed to be a regular pointer and the function guarantees this + assumption in the recursive calls. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpStoreMisc.c + +
                          +
                          +static int 
                          +DddmpCuddDdArrayStoreSmv(
                          +  DdManager * ddMgr, IN: Manager
                          +  int  n, IN: Number of output nodes to be dumped
                          +  DdNode ** f, IN: Array of output nodes to be dumped
                          +  char ** inputNames, IN: Array of input names (or NULL)
                          +  char ** outputNames, IN: Array of output names (or NULL)
                          +  char * modelName, IN: Model name (or NULL)
                          +  FILE * fp IN: Pointer to the dump file
                          +)
                          +
                          +
                          One multiplexer is written for each BDD node. + It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file + system full, or an ADD with constants different from 0 and 1). + It does not close the file: This is the caller responsibility. + It uses a minimal unique subset of the hexadecimal address of a node as + name for it. + If the argument inputNames is non-null, it is assumed to hold the + pointers to the names of the inputs. Similarly for outputNames. + For each BDD node of function f, variable v, then child T, and else + child E it stores: + f = v * T + v' * E + that is + (OR f (AND v T) (AND (NOT v) E)) + If E is a complemented child this results in the following + (OR f (AND v T) (AND (NOT v) (NOT E))) + Comments (COMMENT) are added at the beginning of the description to + describe inputs and outputs of the design. + A buffer (BUF) is add on the output to cope with complemented functions. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpCuddDdArrayStoreBlif + + +
                          Defined in dddmpStoreMisc.c + +
                          +
                          +static void 
                          +DddmpDdNodesCheckIncomingAndScanPath(
                          +  DdNode * f, IN: BDD node to be numbered
                          +  int  pathLengthCurrent, IN: Current Path Length
                          +  int  edgeInTh, IN: Max # In-Edges, after a Insert Cut Point
                          +  int  pathLengthTh IN: Max Path Length (after, Insert a Cut Point)
                          +)
                          +
                          +
                          Number nodes recursively in post-order. + The "visited" flag is used with the right polarity. + The node is assigned to a new CNF variable only if it is a "shared" + node (i.e. the number of its incoming edges is greater than 1). +

                          + +

                          Side Effects "visited" flags are set. +

                          + +

                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +static void 
                          +DddmpDdNodesCheckIncomingAndScanPath(
                          +  DdNode * f, IN: BDD node to be numbered
                          +  int  pathLengthCurrent, IN: Current Path Length
                          +  int  edgeInTh, IN: Max # In-Edges, after a Insert Cut Point
                          +  int  pathLengthTh IN: Max Path Length (after, Insert a Cut Point)
                          +)
                          +
                          +
                          Number nodes recursively in post-order. + The "visited" flag is used with the right polarity. + The node is assigned to a new CNF variable only if it is a "shared" + node (i.e. the number of its incoming edges is greater than 1). +

                          + +

                          Side Effects "visited" flags are set. +

                          + +

                          Defined in dddmpNodeCnf.c + +
                          +
                          +int 
                          +DddmpDdNodesCountEdgesAndNumber(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: Array of BDDs
                          +  int  rootN, IN: Number of BDD roots in the array of BDDs
                          +  int  edgeInTh, IN: Max # In-Edges, after a Insert Cut Point
                          +  int  pathLengthTh, IN: Max Path Length (after, Insert a Cut Point)
                          +  int * cnfIds, OUT: CNF identifiers for variables
                          +  int  id OUT: Number of Temporary Variables Introduced
                          +)
                          +
                          +
                          Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. +

                          + +

                          Side Effects Nodes are temporarily removed from unique table +

                          + +

                          See Also RemoveFromUniqueRecurCnf() + + +
                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +int 
                          +DddmpDdNodesCountEdgesAndNumber(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: Array of BDDs
                          +  int  rootN, IN: Number of BDD roots in the array of BDDs
                          +  int  edgeInTh, IN: Max # In-Edges, after a Insert Cut Point
                          +  int  pathLengthTh, IN: Max Path Length (after, Insert a Cut Point)
                          +  int * cnfIds, OUT: CNF identifiers for variables
                          +  int  id OUT: Number of Temporary Variables Introduced
                          +)
                          +
                          +
                          Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. +

                          + +

                          Side Effects Nodes are temporarily removed from unique table +

                          + +

                          See Also RemoveFromUniqueRecurCnf() + + +
                          Defined in dddmpNodeCnf.c + +
                          +
                          +static int 
                          +DddmpDdNodesCountEdgesRecur(
                          +  DdNode * f IN: root of the BDD
                          +)
                          +
                          +
                          Counts (recursively) the number of incoming edges for each + node of a BDD. This number is stored in the index field. +

                          + +

                          Side Effects "visited" flags remain untouched. +

                          + +

                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +static int 
                          +DddmpDdNodesCountEdgesRecur(
                          +  DdNode * f IN: root of the BDD
                          +)
                          +
                          +
                          Counts (recursively) the number of incoming edges for each + node of a BDD. This number is stored in the index field. +

                          + +

                          Side Effects "visited" flags remain untouched. +

                          + +

                          Defined in dddmpNodeCnf.c + +
                          +
                          +static int 
                          +DddmpDdNodesNumberEdgesRecur(
                          +  DdNode * f, IN: BDD node to be numbered
                          +  int * cnfIds, IN: possible source for numbering
                          +  int  id IN/OUT: possible source for numbering
                          +)
                          +
                          +
                          Number nodes recursively in post-order. + The "visited" flag is used with the inverse polarity. + Numbering follows the subsequent strategy: + * if the index = 0 it remains so + * if the index >= 1 it gets enumerated. + This implies that the node is assigned to a new CNF variable only if + it is not a terminal node otherwise it is assigned the index of + the BDD variable. +

                          + +

                          Side Effects "visited" flags are reset. +

                          + +

                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +static int 
                          +DddmpDdNodesNumberEdgesRecur(
                          +  DdNode * f, IN: BDD node to be numbered
                          +  int * cnfIds, IN: possible source for numbering
                          +  int  id IN/OUT: possible source for numbering
                          +)
                          +
                          +
                          Number nodes recursively in post-order. + The "visited" flag is used with the inverse polarity. + Numbering follows the subsequent strategy: + * if the index = 0 it remains so + * if the index >= 1 it gets enumerated. + This implies that the node is assigned to a new CNF variable only if + it is not a terminal node otherwise it is assigned the index of + the BDD variable. +

                          + +

                          Side Effects "visited" flags are reset. +

                          + +

                          Defined in dddmpNodeCnf.c + +
                          +
                          +static int 
                          +DddmpDdNodesResetCountRecur(
                          +  DdNode * f IN: root of the BDD whose counters are reset
                          +)
                          +
                          +
                          Resets counter and visited flag for ALL nodes of a BDD (it + recurs on the node children). The index field of the node is + used as counter. +

                          + +

                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +static int 
                          +DddmpDdNodesResetCountRecur(
                          +  DdNode * f IN: root of the BDD whose counters are reset
                          +)
                          +
                          +
                          Resets counter and visited flag for ALL nodes of a BDD (it + recurs on the node children). The index field of the node is + used as counter. +

                          + +

                          Defined in dddmpNodeCnf.c + +
                          +
                          +static void 
                          +DddmpFreeHeaderCnf(
                          +  Dddmp_Hdr_t * Hdr IN: pointer to header
                          +)
                          +
                          +
                          Frees the internal header structure by freeing all internal + fields first. +

                          + +

                          Defined in dddmpLoadCnf.c + +
                          +
                          +static void 
                          +DddmpFreeHeader(
                          +  Dddmp_Hdr_t * Hdr IN: pointer to header
                          +)
                          +
                          +
                          Frees the internal header structureby freeing all internal + fields first. +

                          + +

                          Defined in dddmpLoad.c + +
                          +
                          +int * 
                          +DddmpIntArrayDup(
                          +  int * array, IN: array of ints to be duplicated
                          +  int  n IN: size of the array
                          +)
                          +
                          +
                          Allocates memory and copies source array +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpUtil.c + +
                          +
                          +int * 
                          +DddmpIntArrayRead(
                          +  FILE * fp, IN: input file
                          +  int  n IN: size of the array
                          +)
                          +
                          +
                          Allocates memory and inputs source array +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpUtil.c + +
                          +
                          +int 
                          +DddmpIntArrayWrite(
                          +  FILE * fp, IN: output file
                          +  int * array, IN: array of ints
                          +  int  n IN: size of the array
                          +)
                          +
                          +
                          Outputs an array of ints to a specified file +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpUtil.c + +
                          +
                          +int 
                          +DddmpNumberAddNodes(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDDs
                          +  int  n IN: number of BDD roots in the array of BDDs
                          +)
                          +
                          +
                          Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodes()). +

                          + +

                          Side Effects Nodes are temporarily removed from unique table +

                          + +

                          See Also RemoveFromUniqueRecurAdd +() +NumberNodeRecurAdd +() +DddmpUnnumberDdNodesAdd +() + + +
                          Defined in dddmpNodeAdd.c + +
                          +
                          +int 
                          +DddmpNumberBddNodes(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDDs
                          +  int  n IN: number of BDD roots in the array of BDDs
                          +)
                          +
                          +
                          Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberBddNodes ()). +

                          + +

                          Side Effects Nodes are temporarily removed from unique table +

                          + +

                          See Also RemoveFromUniqueRecur() +NumberNodeRecur() +DddmpUnnumberBddNodes +() + + +
                          Defined in dddmpNodeBdd.c + +
                          +
                          +int 
                          +DddmpNumberDdNodesCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDDs
                          +  int  rootN, IN: number of BDD roots in the array of BDDs
                          +  int * cnfIds, OUT: CNF identifiers for variables
                          +  int  id OUT: number of Temporary Variables Introduced
                          +)
                          +
                          +
                          Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodesCnf()). +

                          + +

                          Side Effects Nodes are temporarily removed from unique table +

                          + +

                          See Also RemoveFromUniqueRecurCnf() +NumberNodeRecurCnf() +DddmpUnnumberDdNodesCnf() + + +
                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +int 
                          +DddmpNumberDdNodesCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDDs
                          +  int  rootN, IN: number of BDD roots in the array of BDDs
                          +  int * cnfIds, OUT: CNF identifiers for variables
                          +  int  id OUT: number of Temporary Variables Introduced
                          +)
                          +
                          +
                          Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodesCnf()). +

                          + +

                          Side Effects Nodes are temporarily removed from unique table +

                          + +

                          See Also RemoveFromUniqueRecurCnf() +NumberNodeRecurCnf() +DddmpUnnumberDdNodesCnf() + + +
                          Defined in dddmpNodeCnf.c + +
                          +
                          +int 
                          +DddmpNumberDdNodes(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDDs
                          +  int  n IN: number of BDD roots in the array of BDDs
                          +)
                          +
                          +
                          Node numbering is required to convert pointers to integers. + Since nodes are removed from unique table, no new nodes should + be generated before re-inserting nodes in the unique table + (DddmpUnnumberDdNodes()). +

                          + +

                          Side Effects Nodes are temporarily removed from unique table +

                          + +

                          See Also RemoveFromUniqueRecur() +NumberNodeRecur() +DddmpUnnumberDdNodes() + + +
                          Defined in dddmpDdNodeBdd.c + +
                          +
                          +static int 
                          +DddmpPrintBddAndNextRecur(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f IN: root of the BDD to be displayed
                          +)
                          +
                          +
                          Prints debug info for a BDD on the screen. It recurs on + node's children. +

                          + +

                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +static int 
                          +DddmpPrintBddAndNextRecur(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f IN: root of the BDD to be displayed
                          +)
                          +
                          +
                          Prints debug info for a BDD on the screen. It recurs on + node's children. +

                          + +

                          Defined in dddmpNodeCnf.c + +
                          +
                          +int 
                          +DddmpPrintBddAndNext(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: Array of BDDs to be displayed
                          +  int  rootN IN: Number of BDD roots in the array of BDDs
                          +)
                          +
                          +
                          Prints debug information for an array of BDDs on the screen +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +int 
                          +DddmpPrintBddAndNext(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: Array of BDDs to be displayed
                          +  int  rootN IN: Number of BDD roots in the array of BDDs
                          +)
                          +
                          +
                          Prints debug information for an array of BDDs on the screen +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpNodeCnf.c + +
                          +
                          +static int 
                          +DddmpReadCnfClauses(
                          +  Dddmp_Hdr_t * Hdr, IN: file header
                          +  int *** cnfTable, OUT: CNF table for clauses
                          +  FILE * fp IN: source file
                          +)
                          +
                          +
                          Read the CNF clauses from the file in the standard DIMACS + format. Store all the clauses in an internal structure for + future transformation into BDDs. +

                          + +

                          Defined in dddmpLoadCnf.c + +
                          +
                          +int 
                          +DddmpReadCode(
                          +  FILE * fp, IN: file where to read the code
                          +  struct binary_dd_code * pcode OUT: the read code
                          +)
                          +
                          +
                          Reads a 1 byte node code. See DddmpWriteCode() + for code description. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpWriteCode() + + +
                          Defined in dddmpBinary.c + +
                          +
                          +int 
                          +DddmpReadInt(
                          +  FILE * fp, IN: file where to read the integer
                          +  int * pid OUT: the read integer
                          +)
                          +
                          +
                          Reads an integer coded on a sequence of bytes. See + DddmpWriteInt() for format. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpWriteInt() + + +
                          Defined in dddmpBinary.c + +
                          +
                          +int 
                          +DddmpReadNodeIndexAdd(
                          +  DdNode * f IN: BDD node
                          +)
                          +
                          +
                          Reads the index of a node. LSB is skipped (used as visited + flag). +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpWriteNodeIndexAdd +() +DddmpSetVisitedAdd +() +DddmpVisitedAdd +() + + +
                          Defined in dddmpNodeAdd.c + +
                          +
                          +int 
                          +DddmpReadNodeIndexBdd(
                          +  DdNode * f IN: BDD node
                          +)
                          +
                          +
                          Reads the index of a node. LSB is skipped (used as visited + flag). +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpWriteNodeIndexBdd +() +DddmpSetVisitedBdd +() +DddmpVisitedBdd +() + + +
                          Defined in dddmpNodeBdd.c + +
                          +
                          +int 
                          +DddmpReadNodeIndexCnf(
                          +  DdNode * f IN: BDD node
                          +)
                          +
                          +
                          Reads the index of a node. LSB is skipped (used as visited + flag). +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpWriteNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
                          Defined in dddmpNodeCnf.c + +
                          +
                          +static int 
                          +DddmpReadNodeIndexCnf(
                          +  DdNode * f IN: BDD node
                          +)
                          +
                          +
                          Reads the index of a node. LSB is skipped (used as visited + flag). +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpWriteNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +int 
                          +DddmpReadNodeIndex(
                          +  DdNode * f IN: BDD node
                          +)
                          +
                          +
                          Reads the index of a node. LSB is skipped (used as visited + flag). +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpWriteNodeIndex() +DddmpSetVisited +() +DddmpVisited +() + + +
                          Defined in dddmpDdNodeBdd.c + +
                          +
                          +void 
                          +DddmpSetVisitedAdd(
                          +  DdNode * f IN: BDD node to be marked (as visited)
                          +)
                          +
                          +
                          Marks a node as visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpVisitedAdd +() +DddmpClearVisitedAdd +() + + +
                          Defined in dddmpNodeAdd.c + +
                          +
                          +void 
                          +DddmpSetVisitedBdd(
                          +  DdNode * f IN: BDD node to be marked (as visited)
                          +)
                          +
                          +
                          Marks a node as visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpVisitedBdd +() +DddmpClearVisitedBdd +() + + +
                          Defined in dddmpNodeBdd.c + +
                          +
                          +static void 
                          +DddmpSetVisitedCnf(
                          +  DdNode * f IN: BDD node to be marked (as visited)
                          +)
                          +
                          +
                          Marks a node as visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpVisitedCnf +() +DddmpClearVisitedCnf +() + + +
                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +void 
                          +DddmpSetVisitedCnf(
                          +  DdNode * f IN: BDD node to be marked (as visited)
                          +)
                          +
                          +
                          Marks a node as visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpVisitedCnf +() +DddmpClearVisitedCnf +() + + +
                          Defined in dddmpNodeCnf.c + +
                          +
                          +void 
                          +DddmpSetVisited(
                          +  DdNode * f IN: BDD node to be marked (as visited)
                          +)
                          +
                          +
                          Marks a node as visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpVisited +() +DddmpClearVisited +() + + +
                          Defined in dddmpDdNodeBdd.c + +
                          +
                          +char ** 
                          +DddmpStrArrayDup(
                          +  char ** array, IN: array of strings to be duplicated
                          +  int  n IN: size of the array
                          +)
                          +
                          +
                          Allocates memory and copies source array +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpUtil.c + +
                          +
                          +void 
                          +DddmpStrArrayFree(
                          +  char ** array, IN: array of strings
                          +  int  n IN: size of the array
                          +)
                          +
                          +
                          Frees memory for strings and the array of pointers +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpUtil.c + +
                          +
                          +char ** 
                          +DddmpStrArrayRead(
                          +  FILE * fp, IN: input file
                          +  int  n IN: size of the array
                          +)
                          +
                          +
                          Allocates memory and inputs source array +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpUtil.c + +
                          +
                          +int 
                          +DddmpStrArrayWrite(
                          +  FILE * fp, IN: output file
                          +  char ** array, IN: array of strings
                          +  int  n IN: size of the array
                          +)
                          +
                          +
                          Outputs an array of strings to a specified file +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpUtil.c + +
                          +
                          +char * 
                          +DddmpStrDup(
                          +  char * str IN: string to be duplicated
                          +)
                          +
                          +
                          Allocates memory and copies source string +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpUtil.c + +
                          +
                          +void 
                          +DddmpUnnumberAddNodes(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDDs
                          +  int  n IN: number of BDD roots in the array of BDDs
                          +)
                          +
                          +
                          Node indexes are no more needed. Nodes are re-linked in the + unique table. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpNumberDdNodeAdd +() + + +
                          Defined in dddmpNodeAdd.c + +
                          +
                          +void 
                          +DddmpUnnumberBddNodes(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDDs
                          +  int  n IN: number of BDD roots in the array of BDDs
                          +)
                          +
                          +
                          Node indexes are no more needed. Nodes are re-linked in the + unique table. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpNumberBddNode +() + + +
                          Defined in dddmpNodeBdd.c + +
                          +
                          +void 
                          +DddmpUnnumberDdNodesCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDDs
                          +  int  rootN IN: number of BDD roots in the array of BDDs
                          +)
                          +
                          +
                          Node indexes are no more needed. Nodes are re-linked in the + unique table. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpNumberDdNode() + + +
                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +void 
                          +DddmpUnnumberDdNodesCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDDs
                          +  int  rootN IN: number of BDD roots in the array of BDDs
                          +)
                          +
                          +
                          Node indexes are no more needed. Nodes are re-linked in the + unique table. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpNumberDdNode() + + +
                          Defined in dddmpNodeCnf.c + +
                          +
                          +void 
                          +DddmpUnnumberDdNodes(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDDs
                          +  int  n IN: number of BDD roots in the array of BDDs
                          +)
                          +
                          +
                          Node indexes are no more needed. Nodes are re-linked in the + unique table. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpNumberDdNode() + + +
                          Defined in dddmpDdNodeBdd.c + +
                          +
                          +int 
                          +DddmpVisitedAdd(
                          +  DdNode * f IN: BDD node to be tested
                          +)
                          +
                          +
                          Returns true if node is visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpSetVisitedAdd +() +DddmpClearVisitedAdd +() + + +
                          Defined in dddmpNodeAdd.c + +
                          +
                          +int 
                          +DddmpVisitedBdd(
                          +  DdNode * f IN: BDD node to be tested
                          +)
                          +
                          +
                          Returns true if node is visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpSetVisitedBdd +() +DddmpClearVisitedBdd +() + + +
                          Defined in dddmpNodeBdd.c + +
                          +
                          +int 
                          +DddmpVisitedCnf(
                          +  DdNode * f IN: BDD node to be tested
                          +)
                          +
                          +
                          Returns true if node is visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpSetVisitedCnf +() +DddmpClearVisitedCnf +() + + +
                          Defined in dddmpNodeCnf.c + +
                          +
                          +static int 
                          +DddmpVisitedCnf(
                          +  DdNode * f IN: BDD node to be tested
                          +)
                          +
                          +
                          Returns true if node is visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpSetVisitedCnf +() +DddmpClearVisitedCnf +() + + +
                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +int 
                          +DddmpVisited(
                          +  DdNode * f IN: BDD node to be tested
                          +)
                          +
                          +
                          Returns true if node is visited +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpSetVisited +() +DddmpClearVisited +() + + +
                          Defined in dddmpDdNodeBdd.c + +
                          +
                          +int 
                          +DddmpWriteCode(
                          +  FILE * fp, IN: file where to write the code
                          +  struct binary_dd_code  code IN: the code to be written
                          +)
                          +
                          +
                          outputs a 1 byte node code using the following format: +
                          +     Unused      : 1 bit;
                          +     V           : 2 bits;     (variable code)
                          +     T           : 2 bits;     (Then code)
                          +     Ecompl      : 1 bit;      (Else complemented)
                          +     E           : 2 bits;     (Else code)
                          +    
                          + Ecompl is set with complemented edges. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpReadCode() + + +
                          Defined in dddmpBinary.c + +
                          +
                          +int 
                          +DddmpWriteInt(
                          +  FILE * fp, IN: file where to write the integer
                          +  int  id IN: integer to be written
                          +)
                          +
                          +
                          Writes an integer as a sequence of bytes (MSByte first). + For each byte 7 bits are used for data and one (LSBit) as link + with a further byte (LSB = 1 means one more byte). +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpReadInt() + + +
                          Defined in dddmpBinary.c + +
                          +
                          +void 
                          +DddmpWriteNodeIndexAdd(
                          +  DdNode * f, IN: BDD node
                          +  int  id IN: index to be written
                          +)
                          +
                          +
                          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpReadNodeIndexAdd +() +DddmpSetVisitedAdd +() +DddmpVisitedAdd +() + + +
                          Defined in dddmpNodeAdd.c + +
                          +
                          +void 
                          +DddmpWriteNodeIndexBdd(
                          +  DdNode * f, IN: BDD node
                          +  int  id IN: index to be written
                          +)
                          +
                          +
                          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpReadNodeIndexBdd() +DddmpSetVisitedBdd +() +DddmpVisitedBdd +() + + +
                          Defined in dddmpNodeBdd.c + +
                          +
                          +int 
                          +DddmpWriteNodeIndexCnfBis(
                          +  DdNode * f, IN: BDD node
                          +  int  id IN: index to be written
                          +)
                          +
                          +
                          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpReadNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +static int 
                          +DddmpWriteNodeIndexCnfWithTerminalCheck(
                          +  DdNode * f, IN: BDD node
                          +  int * cnfIds, IN: possible source for the index to be written
                          +  int  id IN: possible source for the index to be written
                          +)
                          +
                          +
                          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. The index corresponds to + the BDD node variable if both the node's children are a + constant node, otherwise a new CNF variable is used. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpReadNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
                          Defined in dddmpNodeCnf.c + +
                          +
                          +int 
                          +DddmpWriteNodeIndexCnf(
                          +  DdNode * f, IN: BDD node
                          +  int  id IN: index to be written
                          +)
                          +
                          +
                          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpReadNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
                          Defined in dddmpNodeCnf.c + +
                          +
                          +static int 
                          +DddmpWriteNodeIndexCnf(
                          +  DdNode * f, IN: BDD node
                          +  int * cnfIds, IN: possible source for the index to be written
                          +  int  id IN: possible source for the index to be written
                          +)
                          +
                          +
                          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. The index corresponds to + the BDD node variable if both the node's children are a + constant node, otherwise a new CNF variable is used. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpReadNodeIndexCnf() +DddmpSetVisitedCnf +() +DddmpVisitedCnf +() + + +
                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +void 
                          +DddmpWriteNodeIndex(
                          +  DdNode * f, IN: BDD node
                          +  int  id IN: index to be written
                          +)
                          +
                          +
                          The index of the node is written in the "next" field of + a DdNode struct. LSB is not used (set to 0). It is used as + "visited" flag in DD traversals. +

                          + +

                          Side Effects None +

                          + +

                          See Also DddmpReadNodeIndex() +DddmpSetVisited +() +DddmpVisited +() + + +
                          Defined in dddmpDdNodeBdd.c + +
                          +
                          +int 
                          +Dddmp_Bin2Text(
                          +  char * filein, IN: name of binary file
                          +  char * fileout IN: name of ASCII file
                          +)
                          +
                          +
                          Converts from binary to ASCII format. A BDD array is loaded and + and stored to the target file. +

                          + +

                          Side Effects None +

                          + +

                          See Also Dddmp_Text2Bin() + + +
                          Defined in dddmpConvert.c + +
                          +
                          +int 
                          +Dddmp_Text2Bin(
                          +  char * filein, IN: name of ASCII file
                          +  char * fileout IN: name of binary file
                          +)
                          +
                          +
                          Converts from ASCII to binary format. A BDD array is loaded and + and stored to the target file. +

                          + +

                          Side Effects None +

                          + +

                          See Also Dddmp_Bin2Text() + + +
                          Defined in dddmpConvert.c + +
                          +
                          +int 
                          +Dddmp_cuddAddArrayLoad(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
                          +  char ** rootmatchnames, IN: sorted names for loaded roots
                          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names, by ids
                          +  int * varmatchauxids, IN: array of variable auxids, by ids
                          +  int * varcomposeids, IN: array of new ids, by ids
                          +  int  mode, IN: requested input file format
                          +  char * file, IN: file name
                          +  FILE * fp, IN: file pointer
                          +  DdNode *** pproots OUT: array of returned BDD roots
                          +)
                          +
                          +
                          Reads a dump file representing the argument ADDs. See + BDD load functions for detailed explanation. +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddBddArrayStore + + +
                          Defined in dddmpLoad.c + +
                          +
                          +int 
                          +Dddmp_cuddAddArrayStore(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  char * ddname, IN: DD name (or NULL)
                          +  int  nRoots, IN: number of output BDD roots to be stored
                          +  DdNode ** f, IN: array of ADD roots to be stored
                          +  char ** rootnames, IN: array of root names (or NULL)
                          +  char ** varnames, IN: array of variable names (or NULL)
                          +  int * auxids, IN: array of converted var IDs
                          +  int  mode, IN: storing mode selector
                          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument array of ADDs to file. Dumping is + either in text or binary form. see the corresponding BDD dump + function for further details. +

                          + +

                          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

                          + +

                          See Also Dddmp_cuddAddStore +Dddmp_cuddAddLoad +Dddmp_cuddAddArrayLoad + + +
                          Defined in dddmpStoreAdd.c + +
                          +
                          +DdNode * 
                          +Dddmp_cuddAddLoad(
                          +  DdManager * ddMgr, IN: Manager
                          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names by IDs
                          +  int * varmatchauxids, IN: array of variable auxids by IDs
                          +  int * varcomposeids, IN: array of new ids by IDs
                          +  int  mode, IN: requested input file format
                          +  char * file, IN: file name
                          +  FILE * fp IN: file pointer
                          +)
                          +
                          +
                          Reads a dump file representing the argument ADD. + Dddmp_cuddAddArrayLoad is used through a dummy array. +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddAddStore +Dddmp_cuddAddArrayLoad + + +
                          Defined in dddmpLoad.c + +
                          +
                          +int 
                          +Dddmp_cuddAddStore(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  char * ddname, IN: DD name (or NULL)
                          +  DdNode * f, IN: ADD root to be stored
                          +  char ** varnames, IN: array of variable names (or NULL)
                          +  int * auxids, IN: array of converted var ids
                          +  int  mode, IN: storing mode selector
                          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument ADD to file. Dumping is done through + Dddmp_cuddAddArrayStore, And a dummy array of 1 ADD root is + used for this purpose. +

                          + +

                          Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

                          + +

                          See Also Dddmp_cuddAddLoad +Dddmp_cuddAddArrayLoad + + +
                          Defined in dddmpStoreAdd.c + +
                          +
                          +int 
                          +Dddmp_cuddBddArrayLoadCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  Dddmp_RootMatchType  rootmatchmode, IN: storing mode selector
                          +  char ** rootmatchnames, IN: sorted names for loaded roots
                          +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names, by IDs
                          +  int * varmatchauxids, IN: array of variable auxids, by IDs
                          +  int * varcomposeids, IN: array of new ids, by IDs
                          +  int  mode, IN: computation Mode
                          +  char * file, IN: file name
                          +  FILE * fp, IN: file pointer
                          +  DdNode *** rootsPtrPtr, OUT: array of returned BDD roots
                          +  int * nRoots OUT: number of BDDs returned
                          +)
                          +
                          +
                          Reads a dump file representing the argument BDD in a + CNF formula. +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddBddArrayLoad + + +
                          Defined in dddmpLoadCnf.c + +
                          +
                          +int 
                          +Dddmp_cuddBddArrayLoad(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
                          +  char ** rootmatchnames, IN: sorted names for loaded roots
                          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names, by ids
                          +  int * varmatchauxids, IN: array of variable auxids, by ids
                          +  int * varcomposeids, IN: array of new ids, by ids
                          +  int  mode, IN: requested input file format
                          +  char * file, IN: file name
                          +  FILE * fp, IN: file pointer
                          +  DdNode *** pproots OUT: array of returned BDD roots
                          +)
                          +
                          +
                          Reads a dump file representing the argument BDDs. The header is + common to both text and binary mode. The node list is either + in text or binary format. A dynamic vector of DD pointers + is allocated to support conversion from DD indexes to pointers. + Several criteria are supported for variable match between file + and dd manager. Several changes/permutations/compositions are allowed + for variables while loading DDs. Variable of the dd manager are allowed + to match with variables on file on ids, permids, varnames, + varauxids; also direct composition between ids and + composeids is supported. More in detail: +
                            +
                          1. varMatchMode=DDDMP_VAR_MATCHIDS

                            + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

                          2. varMatchMode=DDDMP_VAR_MATCHPERMIDS

                            + is used to allow variable match according to the position in the + ordering. + +

                          3. varMatchMode=DDDMP_VAR_MATCHNAMES

                            + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

                          4. varMatchMode=DDDMP_VAR_MATCHIDS

                            + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

                          5. varMatchMode=DDDMP_VAR_COMPOSEIDS

                            + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. +

                          + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. + + All the loaded BDDs are referenced before returning them. +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddBddArrayStore + + +
                          Defined in dddmpLoad.c + +
                          +
                          +int 
                          +Dddmp_cuddBddArrayStoreBlif(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  int  nroots, IN: number of output BDD roots to be stored
                          +  DdNode ** f, IN: array of BDD roots to be stored
                          +  char ** inputNames, IN: array of variable names (or NULL)
                          +  char ** outputNames, IN: array of root names (or NULL)
                          +  char * modelName, IN: Model Name
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBLif. + A dummy array of 1 BDD root is used for this purpose. +

                          + +

                          See Also Dddmp_cuddBddArrayStorePrefix + + +
                          Defined in dddmpStoreMisc.c + +
                          +
                          +int 
                          +Dddmp_cuddBddArrayStoreCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDD roots to be stored
                          +  int  rootN, IN: # output BDD roots to be stored
                          +  Dddmp_DecompCnfStoreType  mode, IN: format selection
                          +  int  noHeader, IN: do not store header iff 1
                          +  char ** varNames, IN: array of variable names (or NULL)
                          +  int * bddIds, IN: array of converted var IDs
                          +  int * bddAuxIds, IN: array of BDD node Auxiliary Ids
                          +  int * cnfIds, IN: array of converted var IDs
                          +  int  idInitial, IN: starting id for cutting variables
                          +  int  edgeInTh, IN: Max # Incoming Edges
                          +  int  pathLengthTh, IN: Max Path Length
                          +  char * fname, IN: file name
                          +  FILE * fp, IN: pointer to the store file
                          +  int * clauseNPtr, OUT: number of clause stored
                          +  int * varNewNPtr OUT: number of new variable created
                          +)
                          +
                          +
                          Dumps the argument array of BDDs to file. +

                          + +

                          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + Three methods are allowed: + * NodeByNode method: Insert a cut-point for each BDD node (but the + terminal nodes) + * MaxtermByMaxterm method: Insert no cut-points, i.e. the off-set of + trhe function is stored + * Best method: Tradeoff between the previous two methods. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. + The stored file can contain a file header or not depending on the + noHeader parameter (IFF 0, usual setting, the header is usually stored. + This option can be useful in storing multiple BDDs, as separate BDDs, + on the same file leaving the opening of the file to the caller. +

                          + +

                          Defined in dddmpStoreCnf.c + +
                          +
                          +int 
                          +Dddmp_cuddBddArrayStorePrefix(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  int  nroots, IN: number of output BDD roots to be stored
                          +  DdNode ** f, IN: array of BDD roots to be stored
                          +  char ** inputNames, IN: array of variable names (or NULL)
                          +  char ** outputNames, IN: array of root names (or NULL)
                          +  char * modelName, IN: Model Name
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                          + +

                          See Also Dddmp_cuddBddArrayStore + + +
                          Defined in dddmpStoreMisc.c + +
                          +
                          +int 
                          +Dddmp_cuddBddArrayStoreSmv(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  int  nroots, IN: number of output BDD roots to be stored
                          +  DdNode ** f, IN: array of BDD roots to be stored
                          +  char ** inputNames, IN: array of variable names (or NULL)
                          +  char ** outputNames, IN: array of root names (or NULL)
                          +  char * modelName, IN: Model Name
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                          + +

                          See Also Dddmp_cuddBddArrayStore + + +
                          Defined in dddmpStoreMisc.c + +
                          +
                          +int 
                          +Dddmp_cuddBddArrayStore(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  char * ddname, IN: dd name (or NULL)
                          +  int  nRoots, IN: number of output BDD roots to be stored
                          +  DdNode ** f, IN: array of BDD roots to be stored
                          +  char ** rootnames, IN: array of root names (or NULL)
                          +  char ** varnames, IN: array of variable names (or NULL)
                          +  int * auxids, IN: array of converted var IDs
                          +  int  mode, IN: storing mode selector
                          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument array of BDDs to file. Dumping is either + in text or binary form. BDDs are stored to the fp (already + open) file if not NULL. Otherwise the file whose name is + fname is opened in write mode. The header has the same format + for both textual and binary dump. Names are allowed for input + variables (vnames) and for represented functions (rnames). + For sake of generality and because of dynamic variable + ordering both variable IDs and permuted IDs are included. + New IDs are also supported (auxids). Variables are identified + with incremental numbers. according with their positiom in + the support set. In text mode, an extra info may be added, + chosen among the following options: name, ID, PermID, or an + auxiliary id. Since conversion from DD pointers to integers + is required, DD nodes are temporarily removed from the unique + hash table. This allows the use of the next field to store + node IDs. +

                          + +

                          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

                          + +

                          See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                          Defined in dddmpStoreBdd.c + +
                          +
                          +int 
                          +Dddmp_cuddBddDisplayBinary(
                          +  char * fileIn, IN: name of binary file
                          +  char * fileOut IN: name of text file
                          +)
                          +
                          +
                          Display a binary dump file in a text file +

                          + +

                          Side Effects None +

                          + +

                          See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad + + +
                          Defined in dddmpDbg.c + +
                          +
                          +int 
                          +Dddmp_cuddBddLoadCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names, by IDs
                          +  int * varmatchauxids, IN: array of variable auxids, by IDs
                          +  int * varcomposeids, IN: array of new ids accessed, by IDs
                          +  int  mode, IN: computation mode
                          +  char * file, IN: file name
                          +  FILE * fp, IN: file pointer
                          +  DdNode *** rootsPtrPtr, OUT: array of returned BDD roots
                          +  int * nRoots OUT: number of BDDs returned
                          +)
                          +
                          +
                          Reads a dump file representing the argument BDD in a + CNF formula. + Dddmp_cuddBddArrayLoadCnf is used through a dummy array. + The results is returned in different formats depending on the + mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                          Defined in dddmpLoadCnf.c + +
                          +
                          +DdNode * 
                          +Dddmp_cuddBddLoad(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names - by IDs
                          +  int * varmatchauxids, IN: array of variable auxids - by IDs
                          +  int * varcomposeids, IN: array of new ids accessed - by IDs
                          +  int  mode, IN: requested input file format
                          +  char * file, IN: file name
                          +  FILE * fp IN: file pointer
                          +)
                          +
                          +
                          Reads a dump file representing the argument BDD. + Dddmp_cuddBddArrayLoad is used through a dummy array (see this + function's description for more details). + Mode, the requested input file format, is checked against + the file format. + The loaded BDDs is referenced before returning it. +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddBddStore +Dddmp_cuddBddArrayLoad + + +
                          Defined in dddmpLoad.c + +
                          +
                          +int 
                          +Dddmp_cuddBddStoreBlif(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  int  nRoots, IN: Number of BDD roots
                          +  DdNode * f, IN: BDD root to be stored
                          +  char ** inputNames, IN: Array of variable names
                          +  char ** outputNames, IN: Array of root names
                          +  char * modelName, IN: Model Name
                          +  char * fileName, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBlif. + A dummy array of 1 BDD root is used for this purpose. +

                          + +

                          See Also Dddmp_cuddBddStorePrefix + + +
                          Defined in dddmpStoreMisc.c + +
                          +
                          +int 
                          +Dddmp_cuddBddStoreCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f, IN: BDD root to be stored
                          +  Dddmp_DecompCnfStoreType  mode, IN: format selection
                          +  int  noHeader, IN: do not store header iff 1
                          +  char ** varNames, IN: array of variable names (or NULL)
                          +  int * bddIds, IN: array of var ids
                          +  int * bddAuxIds, IN: array of BDD node Auxiliary Ids
                          +  int * cnfIds, IN: array of CNF var ids
                          +  int  idInitial, IN: starting id for cutting variables
                          +  int  edgeInTh, IN: Max # Incoming Edges
                          +  int  pathLengthTh, IN: Max Path Length
                          +  char * fname, IN: file name
                          +  FILE * fp, IN: pointer to the store file
                          +  int * clauseNPtr, OUT: number of clause stored
                          +  int * varNewNPtr OUT: number of new variable created
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + This task is performed by calling the function + Dddmp_cuddBddArrayStoreCnf. +

                          + +

                          Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

                          + +

                          See Also Dddmp_cuddBddArrayStoreCnf + + +
                          Defined in dddmpStoreCnf.c + +
                          +
                          +int 
                          +Dddmp_cuddBddStorePrefix(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  int  nRoots, IN: Number of BDD roots
                          +  DdNode * f, IN: BDD root to be stored
                          +  char ** inputNames, IN: Array of variable names
                          +  char ** outputNames, IN: Array of root names
                          +  char * modelName, IN: Model Name
                          +  char * fileName, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                          + +

                          See Also Dddmp_cuddBddStore + + +
                          Defined in dddmpStoreMisc.c + +
                          +
                          +int 
                          +Dddmp_cuddBddStoreSmv(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  int  nRoots, IN: Number of BDD roots
                          +  DdNode * f, IN: BDD root to be stored
                          +  char ** inputNames, IN: Array of variable names
                          +  char ** outputNames, IN: Array of root names
                          +  char * modelName, IN: Model Name
                          +  char * fileName, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                          + +

                          See Also Dddmp_cuddBddStore + + +
                          Defined in dddmpStoreMisc.c + +
                          +
                          +int 
                          +Dddmp_cuddBddStore(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  char * ddname, IN: DD name (or NULL)
                          +  DdNode * f, IN: BDD root to be stored
                          +  char ** varnames, IN: array of variable names (or NULL)
                          +  int * auxids, IN: array of converted var ids
                          +  int  mode, IN: storing mode selector
                          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. Dumping is done through + Dddmp_cuddBddArrayStore. A dummy array of 1 BDD root is + used for this purpose. +

                          + +

                          Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

                          + +

                          See Also Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                          Defined in dddmpStoreBdd.c + +
                          +
                          +int 
                          +Dddmp_cuddHeaderLoadCnf(
                          +  int * nVars, OUT: number of DD variables
                          +  int * nsuppvars, OUT: number of support variables
                          +  char *** suppVarNames, OUT: array of support variable names
                          +  char *** orderedVarNames, OUT: array of variable names
                          +  int ** varIds, OUT: array of variable ids
                          +  int ** varComposeIds, OUT: array of permids ids
                          +  int ** varAuxIds, OUT: array of variable aux ids
                          +  int * nRoots, OUT: number of root in the file
                          +  char * file, IN: file name
                          +  FILE * fp IN: file pointer
                          +)
                          +
                          +
                          Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. +

                          + +

                          See Also Dddmp_cuddBddArrayLoad + + +
                          Defined in dddmpLoadCnf.c + +
                          +
                          +int 
                          +Dddmp_cuddHeaderLoad(
                          +  Dddmp_DecompType * ddType, OUT: selects the proper decomp type
                          +  int * nVars, OUT: number of DD variables
                          +  int * nsuppvars, OUT: number of support variables
                          +  char *** suppVarNames, OUT: array of support variable names
                          +  char *** orderedVarNames, OUT: array of variable names
                          +  int ** varIds, OUT: array of variable ids
                          +  int ** varComposeIds, OUT: array of permids ids
                          +  int ** varAuxIds, OUT: array of variable aux ids
                          +  int * nRoots, OUT: number of root in the file
                          +  char * file, IN: file name
                          +  FILE * fp IN: file pointer
                          +)
                          +
                          +
                          Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. +

                          + +

                          See Also Dddmp_cuddBddArrayLoad + + +
                          Defined in dddmpLoad.c + +
                          +
                          +int 
                          +FindVarname(
                          +  char * name, IN: name to look for
                          +  char ** array, IN: search array
                          +  int  n IN: size of the array
                          +)
                          +
                          +
                          Binary search of a name within a sorted array of strings. + Used when matching names of variables. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpUtil.c + +
                          +
                          +static int 
                          +NodeBinaryStoreBdd(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f, IN: DD node to be stored
                          +  int  mode, IN: store mode
                          +  int * supportids, IN: internal ids for variables
                          +  char ** varnames, IN: names of variables: to be stored with nodes
                          +  int * outids, IN: output ids for variables
                          +  FILE * fp, IN: store file
                          +  int  idf, IN: index of the node
                          +  int  vf, IN: variable of the node
                          +  int  idT, IN: index of the Then node
                          +  int  idE, IN: index of the Else node
                          +  int  vT, IN: variable of the Then node
                          +  int  vE, IN: variable of the Else node
                          +  DdNode * T, IN: Then node
                          +  DdNode * E IN: Else node
                          +)
                          +
                          +
                          Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. + Store every information as coded binary values. +

                          + +

                          Side Effects None +

                          + +

                          See Also NodeTextStoreBdd + + +
                          Defined in dddmpStoreBdd.c + +
                          +
                          +static int 
                          +NodeStoreRecurAdd(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f, IN: DD node to be stored
                          +  int  mode, IN: store mode
                          +  int * supportids, IN: internal ids for variables
                          +  char ** varnames, IN: names of variables: to be stored with nodes
                          +  int * outids, IN: output ids for variables
                          +  FILE * fp IN: store file
                          +)
                          +
                          +
                          Stores a node to file in either test or binary mode. + In text mode a node is represented (on a text line basis) as +
                            +
                          • node-index [var-extrainfo] var-index Then-index Else-index +
                          + + where all indexes are integer numbers and var-extrainfo + (optional redundant field) is either an integer or a string + (variable name). Node-index is redundant (due to the node + ordering) but we keep it for readability.

                          + + In binary mode nodes are represented as a sequence of bytes, + representing var-index, Then-index, and Else-index in an + optimized way. Only the first byte (code) is mandatory. + Integer indexes are represented in absolute or relative mode, + where relative means offset wrt. a Then/Else node info. + Suppose Var(NodeId), Then(NodeId) and Else(NodeId) represent + infos about a given node.

                          + + The generic "NodeId" node is stored as + +

                            +
                          • code-byte +
                          • [var-info] +
                          • [Then-info] +
                          • [Else-info] +
                          + + where code-byte contains bit fields + +
                            +
                          • Unused : 1 bit +
                          • Variable: 2 bits, one of the following codes +
                              +
                            • DDDMP_ABSOLUTE_ID var-info = Var(NodeId) follows +
                            • DDDMP_RELATIVE_ID Var(NodeId) is represented in relative form as + var-info = Min(Var(Then(NodeId)),Var(Else(NodeId))) -Var(NodeId) +
                            • DDDMP_RELATIVE_1 No var-info follows, because + Var(NodeId) = Min(Var(Then(NodeId)),Var(Else(NodeId)))-1 +
                            • DDDMP_TERMINAL Node is a terminal, no var info required +
                            +
                          • T : 2 bits, with codes similar to V +
                              +
                            • DDDMP_ABSOLUTE_ID Then-info = Then(NodeId) follows +
                            • DDDMP_RELATIVE_ID Then(NodeId) is represented in relative form as + Then-info = Nodeid-Then(NodeId) +
                            • DDDMP_RELATIVE_1 No info on Then(NodeId) follows, because + Then(NodeId) = NodeId-1 +
                            • DDDMP_TERMINAL Then Node is a terminal, no info required (for BDDs) +
                            +
                          • Ecompl : 1 bit, if 1 means complemented edge +
                          • E : 2 bits, with codes and meanings as for the Then edge +
                          + var-info, Then-info, Else-info (if required) are represented as unsigned + integer values on a sufficient set of bytes (MSByte first). +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpStoreAdd.c + +
                          +
                          +static int 
                          +NodeStoreRecurBdd(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f, IN: DD node to be stored
                          +  int  mode, IN: store mode
                          +  int * supportids, IN: internal ids for variables
                          +  char ** varnames, IN: names of variables: to be stored with nodes
                          +  int * outids, IN: output ids for variables
                          +  FILE * fp IN: store file
                          +)
                          +
                          +
                          Stores a node to file in either test or binary mode. + In text mode a node is represented (on a text line basis) as +
                            +
                          • node-index [var-extrainfo] var-index Then-index Else-index +
                          + + where all indexes are integer numbers and var-extrainfo + (optional redundant field) is either an integer or a string + (variable name). Node-index is redundant (due to the node + ordering) but we keep it for readability.

                          + + In binary mode nodes are represented as a sequence of bytes, + representing var-index, Then-index, and Else-index in an + optimized way. Only the first byte (code) is mandatory. + Integer indexes are represented in absolute or relative mode, + where relative means offset wrt. a Then/Else node info. + Suppose Var(NodeId), Then(NodeId) and Else(NodeId) represent + infos about a given node.

                          + + The generic "NodeId" node is stored as + +

                            +
                          • code-byte +
                          • [var-info] +
                          • [Then-info] +
                          • [Else-info] +
                          + + where code-byte contains bit fields + +
                            +
                          • Unused : 1 bit +
                          • Variable: 2 bits, one of the following codes +
                              +
                            • DDDMP_ABSOLUTE_ID var-info = Var(NodeId) follows +
                            • DDDMP_RELATIVE_ID Var(NodeId) is represented in relative form as + var-info = Min(Var(Then(NodeId)),Var(Else(NodeId))) -Var(NodeId) +
                            • DDDMP_RELATIVE_1 No var-info follows, because + Var(NodeId) = Min(Var(Then(NodeId)),Var(Else(NodeId)))-1 +
                            • DDDMP_TERMINAL Node is a terminal, no var info required +
                            +
                          • T : 2 bits, with codes similar to V +
                              +
                            • DDDMP_ABSOLUTE_ID Then-info = Then(NodeId) follows +
                            • DDDMP_RELATIVE_ID Then(NodeId) is represented in relative form as + Then-info = Nodeid-Then(NodeId) +
                            • DDDMP_RELATIVE_1 No info on Then(NodeId) follows, because + Then(NodeId) = NodeId-1 +
                            • DDDMP_TERMINAL Then Node is a terminal, no info required (for BDDs) +
                            +
                          • Ecompl : 1 bit, if 1 means complemented edge +
                          • E : 2 bits, with codes and meanings as for the Then edge +
                          + var-info, Then-info, Else-info (if required) are represented as unsigned + integer values on a sufficient set of bytes (MSByte first). +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpStoreBdd.c + +
                          +
                          +static int 
                          +NodeTextStoreAdd(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f, IN: DD node to be stored
                          +  int  mode, IN: store mode
                          +  int * supportids, IN: internal ids for variables
                          +  char ** varnames, IN: names of variables: to be stored with nodes
                          +  int * outids, IN: output ids for variables
                          +  FILE * fp, IN: Store file
                          +  int  idf, IN: index of the current node
                          +  int  vf, IN: variable of the current node
                          +  int  idT, IN: index of the Then node
                          +  int  idE IN: index of the Else node
                          +)
                          +
                          +
                          Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. +

                          + +

                          Side Effects None +

                          + +

                          See Also NodeBinaryStore + + +
                          Defined in dddmpStoreAdd.c + +
                          +
                          +static int 
                          +NodeTextStoreBdd(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f, IN: DD node to be stored
                          +  int  mode, IN: store mode
                          +  int * supportids, IN: internal ids for variables
                          +  char ** varnames, IN: names of variables: to be stored with nodes
                          +  int * outids, IN: output ids for variables
                          +  FILE * fp, IN: Store file
                          +  int  idf, IN: index of the current node
                          +  int  vf, IN: variable of the current node
                          +  int  idT, IN: index of the Then node
                          +  int  idE IN: index of the Else node
                          +)
                          +
                          +
                          Store 1 0 0 for the terminal node. + Store id, left child pointer, right pointer for all the other nodes. +

                          + +

                          Side Effects None +

                          + +

                          See Also NodeBinaryStoreBdd + + +
                          Defined in dddmpStoreBdd.c + +
                          +
                          +static int 
                          +NumberNodeRecurAdd(
                          +  DdNode * f, IN: root of the BDD to be numbered
                          +  int  id IN/OUT: index to be assigned to the node
                          +)
                          +
                          +
                          Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

                          + +

                          Side Effects "visited" flags are reset. +

                          + +

                          Defined in dddmpNodeAdd.c + +
                          +
                          +static int 
                          +NumberNodeRecurBdd(
                          +  DdNode * f, IN: root of the BDD to be numbered
                          +  int  id IN/OUT: index to be assigned to the node
                          +)
                          +
                          +
                          Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

                          + +

                          Side Effects "visited" flags are reset. +

                          + +

                          Defined in dddmpNodeBdd.c + +
                          +
                          +static int 
                          +NumberNodeRecurCnf(
                          +  DdNode * f, IN: root of the BDD to be numbered
                          +  int * cnfIds, IN: possible source for numbering
                          +  int  id IN/OUT: possible source for numbering
                          +)
                          +
                          +
                          Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

                          + +

                          Side Effects "visited" flags are reset. +

                          + +

                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +static int 
                          +NumberNodeRecurCnf(
                          +  DdNode * f, IN: root of the BDD to be numbered
                          +  int * cnfIds, IN: possible source for numbering
                          +  int  id IN/OUT: possible source for numbering
                          +)
                          +
                          +
                          Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

                          + +

                          Side Effects "visited" flags are reset. +

                          + +

                          Defined in dddmpNodeCnf.c + +
                          +
                          +static int 
                          +NumberNodeRecur(
                          +  DdNode * f, IN: root of the BDD to be numbered
                          +  int  id IN/OUT: index to be assigned to the node
                          +)
                          +
                          +
                          Number nodes recursively in post-order. + The "visited" flag is used with inverse polarity, because all nodes + were set "visited" when removing them from unique. +

                          + +

                          Side Effects "visited" flags are reset. +

                          + +

                          Defined in dddmpDdNodeBdd.c + +
                          +
                          +int 
                          +QsortStrcmp(
                          +  const void * ps1, IN: pointer to the first string
                          +  const void * ps2 IN: pointer to the second string
                          +)
                          +
                          +
                          String compare for qsort +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpUtil.c + +
                          +
                          +static int 
                          +ReadByteBinary(
                          +  FILE * fp, IN: file where to read the byte
                          +  unsigned char * cp OUT: the read byte
                          +)
                          +
                          +
                          inputs a byte to file fp. 0x00 has been used as escape character + to filter , and . This is done for + compatibility between unix and dos/windows systems. +

                          + +

                          Side Effects None +

                          + +

                          See Also WriteByteBinary() + + +
                          Defined in dddmpBinary.c + +
                          +
                          +static void 
                          +RemoveFromUniqueRecurAdd(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f IN: root of the BDD to be extracted
                          +)
                          +
                          +
                          Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. Constants remain untouched. +

                          + +

                          Side Effects Nodes are left with the "visited" flag true. +

                          + +

                          See Also RestoreInUniqueRecurAdd +() + + +
                          Defined in dddmpNodeAdd.c + +
                          +
                          +static void 
                          +RemoveFromUniqueRecurBdd(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f IN: root of the BDD to be extracted
                          +)
                          +
                          +
                          Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. Constants remain untouched. +

                          + +

                          Side Effects Nodes are left with the "visited" flag true. +

                          + +

                          See Also RestoreInUniqueRecurBdd +() + + +
                          Defined in dddmpNodeBdd.c + +
                          +
                          +static void 
                          +RemoveFromUniqueRecurCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f IN: root of the BDD to be extracted
                          +)
                          +
                          +
                          Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on on the + children of the node. Constants remain untouched. +

                          + +

                          Side Effects Nodes are left with the "visited" flag true. +

                          + +

                          See Also RestoreInUniqueRecurCnf() + + +
                          Defined in dddmpNodeCnf.c + +
                          +
                          +static void 
                          +RemoveFromUniqueRecurCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f IN: root of the BDD to be extracted
                          +)
                          +
                          +
                          Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on son nodes. +

                          + +

                          Side Effects Nodes are left with the "visited" flag true. +

                          + +

                          See Also RestoreInUniqueRecurCnf() + + +
                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +static void 
                          +RemoveFromUniqueRecur(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f IN: root of the BDD to be extracted
                          +)
                          +
                          +
                          Removes a node from the unique table by locating the proper + subtable and unlinking the node from it. It recurs on the + children of the node. +

                          + +

                          Side Effects Nodes are left with the "visited" flag true. +

                          + +

                          See Also RestoreInUniqueRecur() + + +
                          Defined in dddmpDdNodeBdd.c + +
                          +
                          +static void 
                          +RestoreInUniqueRecurAdd(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f IN: root of the BDD to be restored
                          +)
                          +
                          +
                          Restores a node in unique table (recursively) +

                          + +

                          Side Effects Nodes are not restored in the same order as before removal +

                          + +

                          See Also RemoveFromUniqueAdd +() + + +
                          Defined in dddmpNodeAdd.c + +
                          +
                          +static void 
                          +RestoreInUniqueRecurBdd(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f IN: root of the BDD to be restored
                          +)
                          +
                          +
                          Restores a node in unique table (recursively) +

                          + +

                          Side Effects Nodes are not restored in the same order as before removal +

                          + +

                          See Also RemoveFromUnique() + + +
                          Defined in dddmpNodeBdd.c + +
                          +
                          +static void 
                          +RestoreInUniqueRecurCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f IN: root of the BDD to be restored
                          +)
                          +
                          +
                          Restores a node in unique table (recursive) +

                          + +

                          Side Effects Nodes are not restored in the same order as before removal +

                          + +

                          See Also RemoveFromUnique() + + +
                          Defined in dddmpDdNodeCnf.c + +
                          +
                          +static void 
                          +RestoreInUniqueRecurCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f IN: root of the BDD to be restored
                          +)
                          +
                          +
                          Restores a node in unique table (recursive) +

                          + +

                          Side Effects Nodes are not restored in the same order as before removal +

                          + +

                          See Also RemoveFromUnique() + + +
                          Defined in dddmpNodeCnf.c + +
                          +
                          +static void 
                          +RestoreInUniqueRecur(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f IN: root of the BDD to be restored
                          +)
                          +
                          +
                          Restores a node in unique table (recursively) +

                          + +

                          Side Effects Nodes are not restored in the same order as before removal +

                          + +

                          See Also RemoveFromUnique() + + +
                          Defined in dddmpDdNodeBdd.c + +
                          +
                          +static int 
                          +StoreCnfBestNotSharedRecur(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * node, IN: BDD to store
                          +  int  idf, IN: Id to store
                          +  int * bddIds, IN: BDD identifiers
                          +  int * cnfIds, IN: corresponding CNF identifiers
                          +  FILE * fp, IN: file pointer
                          +  int * list, IN: temporary array to store cubes
                          +  int * clauseN, OUT: number of stored clauses
                          +  int * varMax OUT: maximum identifier of the variables created
                          +)
                          +
                          +
                          Performs the recursive step of Print Best on Not Shared + sub-BDDs, i.e., print out information for the nodes belonging to + BDDs not shared (whose root has just one incoming edge). +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpStoreCnf.c + +
                          +
                          +static int 
                          +StoreCnfBestSharedRecur(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * node, IN: BDD to store
                          +  int * bddIds, IN: BDD identifiers
                          +  int * cnfIds, IN: corresponding CNF identifiers
                          +  FILE * fp, IN: file pointer
                          +  int * list, IN: temporary array to store cubes
                          +  int * clauseN, OUT: number of stored clauses
                          +  int * varMax OUT: maximum identifier of the variables created
                          +)
                          +
                          +
                          Performs the recursive step of Print Best on Not Shared + sub-BDDs, i.e., print out information for the nodes belonging to + BDDs not shared (whose root has just one incoming edge). +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpStoreCnf.c + +
                          +
                          +static int 
                          +StoreCnfBest(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDDs to store
                          +  int  rootN, IN: number of BDD in the array
                          +  int * bddIds, IN: BDD identifiers
                          +  int * cnfIds, IN: corresponding CNF identifiers
                          +  int  idInitial, IN: initial value for numbering new CNF variables
                          +  FILE * fp, IN: file pointer
                          +  int * varMax, OUT: maximum identifier of the variables created
                          +  int * clauseN, OUT: number of stored clauses
                          +  int * rootStartLine OUT: line where root starts
                          +)
                          +
                          +
                          Prints a disjoint sum of product cover for the function + rooted at node intorducing cutting points whenever necessary. + Each product corresponds to a path from node a leaf + node different from the logical zero, and different from the + background value. Uses the standard output. Returns 1 if + successful, 0 otherwise. +

                          + +

                          Side Effects None +

                          + +

                          See Also StoreCnfMaxtermByMaxterm + + +
                          Defined in dddmpStoreCnf.c + +
                          +
                          +static void 
                          +StoreCnfMaxtermByMaxtermRecur(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * node, IN: BDD to store
                          +  int * bddIds, IN: BDD identifiers
                          +  int * cnfIds, IN: corresponding CNF identifiers
                          +  FILE * fp, IN: file pointer
                          +  int * list, IN: temporary array to store cubes
                          +  int * clauseN, OUT: number of stored clauses
                          +  int * varMax OUT: maximum identifier of the variables created
                          +)
                          +
                          +
                          Performs the recursive step of Print Maxterm. + Traverse a BDD a print out a cube in CNF format each time a terminal + node is reached. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpStoreCnf.c + +
                          +
                          +static int 
                          +StoreCnfMaxtermByMaxterm(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDDs to store
                          +  int  rootN, IN: number of BDDs in the array
                          +  int * bddIds, IN: BDD Identifiers
                          +  int * cnfIds, IN: corresponding CNF Identifiers
                          +  int  idInitial, IN: initial value for numbering new CNF variables
                          +  FILE * fp, IN: file pointer
                          +  int * varMax, OUT: maximum identifier of the variables created
                          +  int * clauseN, OUT: number of stored clauses
                          +  int * rootStartLine OUT: line where root starts
                          +)
                          +
                          +
                          Prints a disjoint sum of product cover for the function + rooted at node. Each product corresponds to a path from node a + leaf node different from the logical zero, and different from + the background value. Uses the standard output. Returns 1 if + successful, 0 otherwise. +

                          + +

                          Side Effects None +

                          + +

                          See Also StoreCnfBest + + +
                          Defined in dddmpStoreCnf.c + +
                          +
                          +static int 
                          +StoreCnfNodeByNodeRecur(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f, IN: BDD node to be stored
                          +  int * bddIds, IN: BDD ids for variables
                          +  int * cnfIds, IN: CNF ids for variables
                          +  FILE * fp, IN: store file
                          +  int * clauseN, OUT: number of clauses written in the CNF file
                          +  int * varMax OUT: maximum value of id written in the CNF file
                          +)
                          +
                          +
                          Performs the recursive step of Dddmp_bddStore. + Traverse the BDD and store a CNF formula for each "terminal" node. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpStoreCnf.c + +
                          +
                          +static int 
                          +StoreCnfNodeByNode(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: BDD array to be stored
                          +  int  rootN, IN: number of BDDs in the array
                          +  int * bddIds, IN: BDD ids for variables
                          +  int * cnfIds, IN: CNF ids for variables
                          +  FILE * fp, IN: store file
                          +  int * clauseN, IN/OUT: number of clauses written in the CNF file
                          +  int * varMax, IN/OUT: maximum value of id written in the CNF file
                          +  int * rootStartLine OUT: CNF line where root starts
                          +)
                          +
                          +
                          Store the BDD as CNF clauses. + Use a multiplexer description for each BDD node. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpStoreCnf.c + +
                          +
                          +static int 
                          +StoreCnfOneNode(
                          +  DdNode * f, IN: node to be stored
                          +  int  idf, IN: node CNF Index
                          +  int  vf, IN: node BDD Index
                          +  int  idT, IN: Then CNF Index with sign = inverted edge
                          +  int  idE, IN: Else CNF Index with sign = inverted edge
                          +  FILE * fp, IN: store file
                          +  int * clauseN, OUT: number of clauses
                          +  int * varMax OUT: maximun Index of variable stored
                          +)
                          +
                          +
                          Store One Single BDD Node translating it as a multiplexer. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpStoreCnf.c + +
                          +
                          +static int 
                          +WriteByteBinary(
                          +  FILE * fp, IN: file where to write the byte
                          +  unsigned char  c IN: the byte to be written
                          +)
                          +
                          +
                          outputs a byte to file fp. Uses 0x00 as escape character + to filter , and . + This is done for compatibility between unix and dos/windows systems. +

                          + +

                          Side Effects None +

                          + +

                          See Also ReadByteBinary() + + +
                          Defined in dddmpBinary.c + +
                          +
                          +static int 
                          +printCubeCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * node, IN: BDD to store
                          +  int * cnfIds, IN: CNF identifiers
                          +  FILE * fp, IN: file pointer
                          +  int * list, IN: temporary array to store cubes
                          +  int * varMax OUT: maximum identifier of the variables created
                          +)
                          +
                          +
                          Print One Cube in CNF Format. + Return DDDMP_SUCCESS if something is printed out, DDDMP_FAILURE + is nothing is printed out. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpStoreCnf.c + +
                          +
                          + 
                          +(
                          +    
                          +)
                          +
                          +
                          Checks for Warnings: If expr==1 it prints out the warning + on stderr. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmp.h + +
                          +
                          + 
                          +(
                          +    
                          +)
                          +
                          +
                          Checks for fatal bugs and go to the label to deal with + the error. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmp.h + +
                          +
                          + 
                          +(
                          +    
                          +)
                          +
                          +
                          Checks for fatal bugs and return the DDDMP_FAILURE flag. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmp.h + +
                          +
                          + 
                          +(
                          +    
                          +)
                          +
                          +
                          Conditional safety assertion. It prints out the file + name and line number where the fatal error occurred. + Messages are printed out on stderr. +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmp.h + +
                          +
                          + 
                          +(
                          +    
                          +)
                          +
                          +
                          Memory Allocation Macro for DDDMP +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpInt.h + +
                          +
                          + 
                          +(
                          +    
                          +)
                          +
                          +
                          Memory Free Macro for DDDMP +

                          + +

                          Side Effects None +

                          + +

                          Defined in dddmpInt.h + + +
                          +
                          +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllFile.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllFile.html new file mode 100644 index 000000000..2664d07f4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpAllFile.html @@ -0,0 +1,679 @@ + +The dddmp package: files + + +
                          +
                          dddmp.h +
                          External header file +
                          dddmpInt.h +
                          Internal header file +
                          dddmpBinary.c +
                          Input and output BDD codes and integers from/to file +
                          dddmpConvert.c +
                          Conversion between ASCII and binary formats +
                          dddmpDbg.c +
                          Functions to display BDD files +
                          dddmpDdNodeBdd.c +
                          Functions to handle BDD node infos and numbering +
                          dddmpDdNodeCnf.c +
                          Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs +
                          dddmpLoad.c +
                          Functions to read in bdds to file +
                          dddmpLoadCnf.c +
                          Functions to read in CNF from file as BDDs. +
                          dddmpNodeAdd.c +
                          Functions to handle ADD node infos and numbering +
                          dddmpNodeBdd.c +
                          Functions to handle BDD node infos and numbering +
                          dddmpNodeCnf.c +
                          Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs +
                          dddmpStoreAdd.c +
                          Functions to write ADDs to file. +
                          dddmpStoreBdd.c +
                          Functions to write BDDs to file. +
                          dddmpStoreCnf.c +
                          Functions to write out BDDs to file in a CNF format +
                          dddmpStoreMisc.c +
                          Functions to write out bdds to file in prefixed + and in Blif form. +
                          dddmpUtil.c +
                          Util Functions for the dddmp package +

                          +

                          dddmp.h

                          +External header file

                          +By: Gianpiero Cabodi and Stefano Quer

                          +

                          +
                          () +
                          Checks for fatal bugs + +
                          () +
                          Checks for Warnings: If expr==1 it prints out the warning + on stderr. + +
                          () +
                          Checks for fatal bugs and return the DDDMP_FAILURE flag. + +
                          () +
                          Checks for fatal bugs and go to the label to deal with + the error. + +
                          +
                          +

                          dddmpInt.h

                          +Internal header file

                          +By: Gianpiero Cabodi and Stefano Quer

                          +

                          +
                          () +
                          Memory Allocation Macro for DDDMP + +
                          () +
                          Memory Free Macro for DDDMP + +
                          +
                          +

                          dddmpBinary.c

                          +Input and output BDD codes and integers from/to file

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Input and output BDD codes and integers from/to file + in binary mode. + DD node codes are written as one byte. + Integers of any length are written as sequences of "linked" bytes. + For each byte 7 bits are used for data and one (MSBit) as link with + a further byte (MSB = 1 means one more byte). + Low level read/write of bytes filter , and + with escape sequences.

                          +

                          +
                          DddmpWriteCode() +
                          Writes 1 byte node code + +
                          DddmpReadCode() +
                          Reads a 1 byte node code + +
                          DddmpWriteInt() +
                          Writes a "packed integer" + +
                          DddmpReadInt() +
                          Reads a "packed integer" + +
                          WriteByteBinary() +
                          Writes a byte to file filtering , and + +
                          ReadByteBinary() +
                          Reads a byte from file with escaped , and + +
                          +
                          +

                          dddmpConvert.c

                          +Conversion between ASCII and binary formats

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Conversion between ASCII and binary formats is presently + supported by loading a BDD in the source format and storing it + in the target one. We plan to introduce ad hoc procedures + avoiding explicit BDD node generation.

                          +

                          +
                          Dddmp_Text2Bin() +
                          Converts from ASCII to binary format + +
                          Dddmp_Bin2Text() +
                          Converts from binary to ASCII format + +
                          +
                          +

                          dddmpDbg.c

                          +Functions to display BDD files

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Functions to display BDD files in binary format

                          +

                          +
                          Dddmp_cuddBddDisplayBinary() +
                          Display a binary dump file in a text file + +
                          +
                          +

                          dddmpDdNodeBdd.c

                          +Functions to handle BDD node infos and numbering

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Functions to handle BDD node infos and numbering.

                          +

                          +
                          DddmpNumberDdNodes() +
                          Removes nodes from unique table and number them + +
                          DddmpUnnumberDdNodes() +
                          Restores nodes in unique table, loosing numbering + +
                          DddmpWriteNodeIndex() +
                          Write index to node + +
                          DddmpReadNodeIndex() +
                          Reads the index of a node + +
                          DddmpVisited() +
                          Returns true if node is visited + +
                          DddmpSetVisited() +
                          Marks a node as visited + +
                          DddmpClearVisited() +
                          Marks a node as not visited + +
                          NumberNodeRecur() +
                          Number nodes recursively in post-order + +
                          RemoveFromUniqueRecur() +
                          Removes a node from unique table + +
                          RestoreInUniqueRecur() +
                          Restores a node in unique table + +
                          +
                          +

                          dddmpDdNodeCnf.c

                          +Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs.

                          +

                          +
                          DddmpNumberDdNodesCnf() +
                          Removes nodes from unique table and numbers them + +
                          DddmpDdNodesCountEdgesAndNumber() +
                          Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. + +
                          DddmpUnnumberDdNodesCnf() +
                          Restores nodes in unique table, loosing numbering + +
                          DddmpPrintBddAndNext() +
                          Prints debug information + +
                          DddmpWriteNodeIndexCnfBis() +
                          Write index to node + +
                          DddmpWriteNodeIndexCnf() +
                          Write index to node + +
                          DddmpReadNodeIndexCnf() +
                          Reads the index of a node + +
                          DddmpClearVisitedCnfRecur() +
                          Mark ALL nodes as not visited + +
                          DddmpVisitedCnf() +
                          Returns true if node is visited + +
                          DddmpSetVisitedCnf() +
                          Marks a node as visited + +
                          DddmpClearVisitedCnf() +
                          Marks a node as not visited + +
                          NumberNodeRecurCnf() +
                          Number nodes recursively in post-order + +
                          DddmpDdNodesCheckIncomingAndScanPath() +
                          Number nodes recursively in post-order + +
                          DddmpDdNodesNumberEdgesRecur() +
                          Number nodes recursively in post-order + +
                          DddmpDdNodesResetCountRecur() +
                          Resets counter and visited flag for ALL nodes of a BDD + +
                          DddmpDdNodesCountEdgesRecur() +
                          Counts the number of incoming edges for each node of a BDD + +
                          RemoveFromUniqueRecurCnf() +
                          Removes a node from unique table + +
                          RestoreInUniqueRecurCnf() +
                          Restores a node in unique table + +
                          DddmpPrintBddAndNextRecur() +
                          Prints debug info + +
                          +
                          +

                          dddmpLoad.c

                          +Functions to read in bdds to file

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Functions to read in bdds to file. BDDs + are represended on file either in text or binary format under the + following rules. A file contains a forest of BDDs (a vector of + Boolean functions). BDD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to BDD + functions, followed by the list of nodes. BDD nodes are listed + according to their numbering, and in the present implementation + numbering follows a post-order strategy, in such a way that a node + is never listed before its Then/Else children.

                          +

                          +
                          Dddmp_cuddBddLoad() +
                          Reads a dump file representing the argument BDD. + +
                          Dddmp_cuddBddArrayLoad() +
                          Reads a dump file representing the argument BDDs. + +
                          Dddmp_cuddAddLoad() +
                          Reads a dump file representing the argument ADD. + +
                          Dddmp_cuddAddArrayLoad() +
                          Reads a dump file representing the argument ADDs. + +
                          Dddmp_cuddHeaderLoad() +
                          Reads the header of a dump file representing the argument BDDs + +
                          DddmpCuddDdArrayLoad() +
                          Reads a dump file representing the argument BDDs. + +
                          DddmpBddReadHeader() +
                          Reads a the header of a dump file representing the + argument BDDs. + +
                          DddmpFreeHeader() +
                          Frees the internal header structure. + +
                          +
                          +

                          dddmpLoadCnf.c

                          +Functions to read in CNF from file as BDDs.

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Functions to read in CNF from file as BDDs.

                          +

                          +
                          Dddmp_cuddBddLoadCnf() +
                          Reads a dump file in a CNF format. + +
                          Dddmp_cuddBddArrayLoadCnf() +
                          Reads a dump file in a CNF format. + +
                          Dddmp_cuddHeaderLoadCnf() +
                          Reads the header of a dump file representing the argument BDDs + +
                          DddmpCuddDdArrayLoadCnf() +
                          Reads a dump file representing the argument BDDs in CNF + format. + +
                          DddmpBddReadHeaderCnf() +
                          Reads a the header of a dump file representing the argument + BDDs. + +
                          DddmpFreeHeaderCnf() +
                          Frees the internal header structure. + +
                          DddmpReadCnfClauses() +
                          Read the CNF clauses from the file in the standard DIMACS + format. + +
                          DddmpCnfClauses2Bdd() +
                          Transforms CNF clauses into BDDs. + +
                          +
                          +

                          dddmpNodeAdd.c

                          +Functions to handle ADD node infos and numbering

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Functions to handle ADD node infos and numbering.

                          +

                          +
                          DddmpNumberAddNodes() +
                          Removes nodes from unique table and number them + +
                          DddmpUnnumberAddNodes() +
                          Restores nodes in unique table, loosing numbering + +
                          DddmpWriteNodeIndexAdd() +
                          Write index to node + +
                          DddmpReadNodeIndexAdd() +
                          Reads the index of a node + +
                          DddmpVisitedAdd() +
                          Returns true if node is visited + +
                          DddmpSetVisitedAdd() +
                          Marks a node as visited + +
                          DddmpClearVisitedAdd() +
                          Marks a node as not visited + +
                          NumberNodeRecurAdd() +
                          Number nodes recursively in post-order + +
                          RemoveFromUniqueRecurAdd() +
                          Removes a node from unique table + +
                          RestoreInUniqueRecurAdd() +
                          Restores a node in unique table + +
                          +
                          +

                          dddmpNodeBdd.c

                          +Functions to handle BDD node infos and numbering

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Functions to handle BDD node infos and numbering.

                          +

                          +
                          DddmpNumberBddNodes() +
                          Removes nodes from unique table and number them + +
                          DddmpUnnumberBddNodes() +
                          Restores nodes in unique table, loosing numbering + +
                          DddmpWriteNodeIndexBdd() +
                          Write index to node + +
                          DddmpReadNodeIndexBdd() +
                          Reads the index of a node + +
                          DddmpVisitedBdd() +
                          Returns true if node is visited + +
                          DddmpSetVisitedBdd() +
                          Marks a node as visited + +
                          DddmpClearVisitedBdd() +
                          Marks a node as not visited + +
                          NumberNodeRecurBdd() +
                          Number nodes recursively in post-order + +
                          RemoveFromUniqueRecurBdd() +
                          Removes a node from unique table + +
                          RestoreInUniqueRecurBdd() +
                          Restores a node in unique table + +
                          +
                          +

                          dddmpNodeCnf.c

                          +Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Functions to handle BDD node infos and numbering + while storing a CNF formula from a BDD or an array of BDDs.

                          +

                          +
                          DddmpNumberDdNodesCnf() +
                          Removes nodes from unique table and numbers them + +
                          DddmpDdNodesCountEdgesAndNumber() +
                          Removes nodes from unique table and numbers each node according + to the number of its incoming BDD edges. + +
                          DddmpUnnumberDdNodesCnf() +
                          Restores nodes in unique table, loosing numbering + +
                          DddmpPrintBddAndNext() +
                          Prints debug information + +
                          DddmpWriteNodeIndexCnf() +
                          Write index to node + +
                          DddmpVisitedCnf() +
                          Returns true if node is visited + +
                          DddmpSetVisitedCnf() +
                          Marks a node as visited + +
                          DddmpReadNodeIndexCnf() +
                          Reads the index of a node + +
                          DddmpWriteNodeIndexCnfWithTerminalCheck() +
                          Write index to node + +
                          DddmpClearVisitedCnfRecur() +
                          Mark ALL nodes as not visited + +
                          DddmpClearVisitedCnf() +
                          Marks a node as not visited + +
                          NumberNodeRecurCnf() +
                          Number nodes recursively in post-order + +
                          DddmpDdNodesCheckIncomingAndScanPath() +
                          Number nodes recursively in post-order + +
                          DddmpDdNodesNumberEdgesRecur() +
                          Number nodes recursively in post-order + +
                          DddmpDdNodesResetCountRecur() +
                          Resets counter and visited flag for ALL nodes of a BDD + +
                          DddmpDdNodesCountEdgesRecur() +
                          Counts the number of incoming edges for each node of a BDD + +
                          RemoveFromUniqueRecurCnf() +
                          Removes a node from unique table + +
                          RestoreInUniqueRecurCnf() +
                          Restores a node in unique table + +
                          DddmpPrintBddAndNextRecur() +
                          Prints debug info + +
                          +
                          +

                          dddmpStoreAdd.c

                          +Functions to write ADDs to file.

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Functions to write ADDs to file. + ADDs are represended on file either in text or binary format under the + following rules. A file contains a forest of ADDs (a vector of + Boolean functions). ADD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to ADD + functions, followed by the list of nodes. + ADD nodes are listed according to their numbering, and in the present + implementation numbering follows a post-order strategy, in such a way + that a node is never listed before its Then/Else children.

                          +

                          +
                          Dddmp_cuddAddStore() +
                          Writes a dump file representing the argument ADD. + +
                          Dddmp_cuddAddArrayStore() +
                          Writes a dump file representing the argument Array of ADDs. + +
                          DddmpCuddDdArrayStoreBdd() +
                          Writes a dump file representing the argument Array of + BDDs/ADDs. + +
                          NodeStoreRecurAdd() +
                          Performs the recursive step of Dddmp_bddStore. + +
                          NodeTextStoreAdd() +
                          Store One Single Node in Text Format. + +
                          +
                          +

                          dddmpStoreBdd.c

                          +Functions to write BDDs to file.

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Functions to write BDDs to file. + BDDs are represended on file either in text or binary format under the + following rules. A file contains a forest of BDDs (a vector of + Boolean functions). BDD nodes are numbered with contiguous numbers, + from 1 to NNodes (total number of nodes on a file). 0 is not used to + allow negative node indexes for complemented edges. A file contains + a header, including information about variables and roots to BDD + functions, followed by the list of nodes. BDD nodes are listed + according to their numbering, and in the present implementation + numbering follows a post-order strategy, in such a way that a node + is never listed before its Then/Else children.

                          +

                          +
                          Dddmp_cuddBddStore() +
                          Writes a dump file representing the argument BDD. + +
                          Dddmp_cuddBddArrayStore() +
                          Writes a dump file representing the argument Array of BDDs. + +
                          DddmpCuddBddArrayStore() +
                          Writes a dump file representing the argument Array of + BDDs. + +
                          NodeStoreRecurBdd() +
                          Performs the recursive step of Dddmp_bddStore. + +
                          NodeTextStoreBdd() +
                          Store One Single Node in Text Format. + +
                          NodeBinaryStoreBdd() +
                          Store One Single Node in Binary Format. + +
                          +
                          +

                          dddmpStoreCnf.c

                          +Functions to write out BDDs to file in a CNF format

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Functions to write out BDDs to file in a CNF format.

                          +

                          +
                          Dddmp_cuddBddStoreCnf() +
                          Writes a dump file representing the argument BDD in + a CNF format. + +
                          Dddmp_cuddBddArrayStoreCnf() +
                          Writes a dump file representing the argument array of BDDs + in CNF format. + +
                          DddmpCuddBddArrayStoreCnf() +
                          Writes a dump file representing the argument Array of + BDDs in the CNF standard format. + +
                          StoreCnfNodeByNode() +
                          Store the BDD as CNF clauses. + +
                          StoreCnfNodeByNodeRecur() +
                          Performs the recursive step of Dddmp_bddStore. + +
                          StoreCnfOneNode() +
                          Store One Single BDD Node. + +
                          StoreCnfMaxtermByMaxterm() +
                          Prints a disjoint sum of products. + +
                          StoreCnfBest() +
                          Prints a disjoint sum of products with intermediate + cutting points. + +
                          StoreCnfMaxtermByMaxtermRecur() +
                          Performs the recursive step of Print Maxterm. + +
                          StoreCnfBestNotSharedRecur() +
                          Performs the recursive step of Print Best on Not Shared + sub-BDDs. + +
                          StoreCnfBestSharedRecur() +
                          Performs the recursive step of Print Best on Shared + sub-BDDs. + +
                          printCubeCnf() +
                          Print One Cube in CNF Format. + +
                          +
                          +

                          dddmpStoreMisc.c

                          +Functions to write out bdds to file in prefixed + and in Blif form.

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Functions to write out bdds to file. + BDDs are represended on file in text format. + Each node is stored as a multiplexer in a prefix notation format for + the prefix notation file or in PLA format for the blif file.

                          +

                          +
                          Dddmp_cuddBddStorePrefix() +
                          Writes a dump file representing the argument BDD in + a prefix notation. + +
                          Dddmp_cuddBddArrayStorePrefix() +
                          Writes a dump file representing the argument BDD in + a prefix notation. + +
                          Dddmp_cuddBddStoreBlif() +
                          Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
                          Dddmp_cuddBddArrayStoreBlif() +
                          Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
                          Dddmp_cuddBddStoreSmv() +
                          Writes a dump file representing the argument BDD in + a prefix notation. + +
                          Dddmp_cuddBddArrayStoreSmv() +
                          Writes a dump file representing the argument BDD in + a prefix notation. + +
                          DddmpCuddDdArrayStorePrefix() +
                          Internal function to writes a dump file representing the + argument BDD in a prefix notation. + +
                          DddmpCuddDdArrayStorePrefixBody() +
                          Internal function to writes a dump file representing the + argument BDD in a prefix notation. Writes the body of the file. + +
                          DddmpCuddDdArrayStorePrefixStep() +
                          Performs the recursive step of + DddmpCuddDdArrayStorePrefixBody. + +
                          DddmpCuddDdArrayStoreBlif() +
                          Writes a blif file representing the argument BDDs. + +
                          DddmpCuddDdArrayStoreBlifBody() +
                          Writes a blif body representing the argument BDDs. + +
                          DddmpCuddDdArrayStoreBlifStep() +
                          Performs the recursive step of DddmpCuddDdArrayStoreBlif. + +
                          DddmpCuddDdArrayStoreSmv() +
                          Internal function to writes a dump file representing the + argument BDD in a SMV notation. + +
                          DddmpCuddDdArrayStoreSmvBody() +
                          Internal function to writes a dump file representing the + argument BDD in a SMV notation. Writes the body of the file. + +
                          DddmpCuddDdArrayStoreSmvStep() +
                          Performs the recursive step of + DddmpCuddDdArrayStoreSmvBody. + +
                          +
                          +

                          dddmpUtil.c

                          +Util Functions for the dddmp package

                          +By: Gianpiero Cabodi and Stefano Quer

                          +Functions to manipulate arrays.

                          +

                          +
                          QsortStrcmp() +
                          String compare for qsort + +
                          FindVarname() +
                          Performs binary search of a name within a sorted array + +
                          DddmpStrDup() +
                          Duplicates a string + +
                          DddmpStrArrayDup() +
                          Duplicates an array of strings + +
                          DddmpStrArrayRead() +
                          Inputs an array of strings + +
                          DddmpStrArrayWrite() +
                          Outputs an array of strings + +
                          DddmpStrArrayFree() +
                          Frees an array of strings + +
                          DddmpIntArrayDup() +
                          Duplicates an array of ints + +
                          DddmpIntArrayRead() +
                          Inputs an array of ints + +
                          DddmpIntArrayWrite() +
                          Outputs an array of ints + +
                          +
                          +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpDesc.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpDesc.html new file mode 100644 index 000000000..a27b1847f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpDesc.html @@ -0,0 +1,28 @@ + +The dddmp package: Overview + + +

                          The dddmp package

                          +

                          Functions to read in and write out BDDs, ADDs + and CNF formulas from and to files.

                          +

                          By Gianpiero Cabodi and Stefano Quer

                          + + + +
                          + + + +
                          + +Last updated on 1040218 17h14 + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpDoc.txt b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpDoc.txt new file mode 100644 index 0000000000000000000000000000000000000000..5912f35f54c29c1caf93c15e3b802fc8e0e0aba1 GIT binary patch literal 32768 zcmeHQ|9f0TxnI3j_Bnc`T$)1fFAiUn05y%+N`z3;BrOS~CAI;AB4(4_G;24z%kHM6 z-d^t(Dy&!_Xw|5dE?P7|ivbD*sP=hg{;~V{yfd?3l5A#y`sfdxWY5l=_kBO}&dhse z&b()K&e%*!C6me7yvir0jwBAJqG;b-cB+)lWs9nmQ-xF_snS`M$R^cOg>)&Ua&sls zKR8(2uJ+)l7)TsAuuo0r3bS*WL{Uu_a#!Pr&EQT8c0m$l4)T-R7y=J zvN`p=xl|!iA;8E3Ql;s1CROZ0wtDeyrBYpLa3<0}N4hsz+O2vMYNn8yzVBu!)t*dd zFjeZBDa}TiTLxLqA5G0AlS3#~sxXpEByUz@dk)^eckI5K_eXn%58S-FcPf`m?OuQ|)L=Jw`B8;*wlpv|nHtDW zt3q^4B~vOjHCI5vcuZ##nSq(q)DeXS>AD>?g^<*LReef5B?*7%Voe;|9(Ce`)W-hQ zY_4!j?JJ~GYJXx1)lX#x2M445qx`}Vib>>0`}PcvJbZAkn$9E+cSTehZDng~HC^wtV9%iGdRPrzz12jspX{bo_zfj_L(4=>83{A2}4ISLOuenJg zv`OZchU&MqKk(4t-rb$I_wE>YC_=1v#~##ft%fYYokwesXpa=LF{OMwQc`tILaeSQ z@v%l3ZD5sPLIIOsAbP-4HOs~^qtm1)l6b;KAkL@XFi7#m<9coQbQ=p zv^tt7q!W{wlmbH}JloZzc{LVm;4;tXe}Hc)H=EBDQv##^F&q&N-v{n7Ct{7DPbshf zjB)78BKBu8swGO4Kh~tP$R4;yYBmC2HZe=Q z%ln2$9&2J04wcU_`)nyyAk$#-KrZYr69v-_#B?^T^gwHW{tc6r* zu8>V7rNIli9Qxpcd-vw;Sg^ZmM>03H!w+`**a6diaV-f0vrwv(&U8(wgcXr9axfRo zA2-F_+1@(Uj_Qt2FRQ+24-&WIGo#GkHg7|uIG0Zqic^JjzEng9Se%1c$SS z=JNT>T}r=ch0SmE`-KQ&l9kVAQnRUSDUm^Gb59i$7&6YIK9=>HUMGi;5(2Z=i|Wv{ z7e}2p%1?q^#pe`{3?d!nGrN?2LrD)f{`ix-ZUP0$*D{|?aJ-vMl+sg)Ob&%glyU`M z0ZxJFTcQCwQT>k6XNcYiQaF|`q@$yWQfjW4O5m0WWx=h0zQ8Z1NItVO;t7JNTOQ5@DH+#6ompF+af$QmN<+$I;=+7Pz-mPU+I_3 zYuChJVx&d(3oKG$WP!|NBKuTA=?l?M%%9BJ9-alaJ<9~ba29+hVz+)PVxPdEKhT$x z=EE<cD*ZPrVJ>dc@0rs~lt?GYvahhQRA%n*9J!Yr_c{G% z^GlkQDhVwD88+nUW2pjea}pV)-?sLv^jrGuPSzSOVj<;ut2_tW$)U<%8mz0gZG(-0 zZ)_%!$R^lmAW1N%%q!-?7h{01G-ay#olTMb5*7%h5$W&K?@Ah^U0*e?eZk74VXZ=E zx9Awg(vzuDBCERfMJu6S>4|#olz7R}l&6j0?wyvQ^n1{dSA+T86MDg1zLxczE@e_v ziDD{~Dxr+54U0ICwNflRjM1g))@7d8uj+G;k~o)56pK+YeVARAgyHPN+4OW8moaRN z_HQnm3;ImyX5=_0l;o83O|?Wek;J3{vxP$XFq@!wER(@Nn4S_VP|D&ZhsDZR2K|OP zdq7ts0~N*xRA)tSPdYN$EA&uMQB8O&McX?%^Tlk0^NZS{q-|47r{_iOK4AA zfKp3Ko4;)Scx@xMt)$3Tl{3QO>?0h?N@8b}RBF4eHW}h%W`+8ls&_Mw&ZJ9G>QEln z2rP}koG`E5Yfez?DG*ad%p6ioJ(l*Z=PW8wM8*G|GRM+j7|uSHK8VT_W8_)0R5ZWr zwe$iA=;R{QCr?=JL#SFsOOitV>{|1>E`JHMW9edq4=Wy{G6ZNqdO=@|qC2igh$1`5 z>Q86y8cWTWI^{|fz3gEimpz&)V6>CT-z4k+LkDiO_Z%7+9(JR$t=I;k)zNk4H(+U+ z;RG?(nE|by00l8tO^`&*Rg@OgU`iQdn&XP3d+V7$G&?hrfYL`yZhLqZt5H05sA&q>$umV_{zH^t9c*PXJ4FyL*mjkTe- zWo>&lo#{ksV`q%NPj3=yPHg0>@jY3nG_8F(e!>h_M{~AoQtP{V>~tE;c0wHjS(25+rKq_8Ht+z1FvL+CbYQKqhUODN z{}%lR%_3`3LH7c@3n7eFo?Ge4Fny)>A%qd~PFSZx%{38%Lpkfd1^NuudN7(j7a>6J zGg;5QvD&c_!fH~k?)X^G=@EkRYBjn=TKhyoXq=&l_eI<$0iQ_-tl6>B(y0=Hq1VM( zZ7a7+2m&5Xh7G+kE{j%QO-`FuOgtaF^#G5X2v`_;dTdOoJ&14soC%d^1Ba0H4g~>f z4w6-#qE&vP5YGCJB$lVyjTFLxK$DxPg_kJ=<7dt;^A=915Q_6~!9CU5M-{@bZn&Te zD+B`fRuP9boW(g%q(aw$}bJo4@yuh0p?CG|n{OQ4FCl&$SLVt4Ynp76NJE zg2VVBK2f5J*InSgsRgk_zJ?RgJvhAofnI2YkO3~AJ^?@{y^3-|Nl&fLf|Ngz5ULyB$W zwrp@(hG5|ET+gW)@M(rnLk`e3JA>8!(Dl8cA!Ro5m#*s~g@-hRS#zgu=uHiwh_{su zzOlbG1Ota`oBmklwLxg#T??aePf%LJiRXI*cdket4HZtjz+6YO*4yixy&(kTv#uxD zYTn=r4gvY+4~^bp3)0{)4uMdcwcg~luH+ET`p)L{9L?52Oy}@j@Dc|c#MUhg|FH8E zb1_n)|biyHcpNDL4vy35L>6+^Z}gqL+9hs82H?CrH(& zKvw3(j!+9LESiA0(&sEcj!Zzh2hysCYdK1ANJ&a)mt>8D@U=MTOAw#H6JuEkVovLq zY?AEeG-&gnnF^sZ_c0Yx66_*-e&=RP6d_yH=Qk;HUcYstq=mXmsZP+wISbWQF0cp$ zFj)~VKC#~|%hBghVx|~&?g~Q9gVikQ3!4;OWK1!PK%*h^>kg>%7Lt2yDhLMFBqS#& zIZsJ*-kjTF(}X<^qN$RK=j|XTu@XVjA!N@-5ZDW0Rsa)^bCPS8AHFee(=n3Ilf0xq z+KM>HJ7w_|)1h1_+$4Y#fI100r9Z}Jk>vb6E-Az_;VL#~sL+Cb5eRlxe!ou(#Km2k z> zQzTY{h>+H0nXs5YY@vX~Hs`**84W`HRhX!XAiK>_}Gi zE9hv<-?zrGCP^v$u0RsHqTk&FFGG(@lUU-NEkgIVsA#Bu>Y&YX@LQSFKSC@GK zLDLmh6goqUP{`>x=K%XdP~fgY3_f;bU6xfv)jcjvRJ}qfE*e}w?}6pqeK#T*L=_3j zn*|oJf;CK|lpoTsx}*@7?%oUz^8xB*AJ0D$0(NY~rIZAi16GfHuvHBbW64yvxU{Fj zM$w{|Kn;#kVp=tB43;8`wpZOC^&pqHISruWyv!vDk{SYSl(doiLj?eLvjB1^nDu7D;b zkYq@4CnXrmJ)7fLUHQkYN>>T8WM19kPLR$gfj9@U8b^w@s+Yp}bzTv5Kp5Q5Y>jt= zXv*lEY%&I74{}kW!_s&Nypb0|=gb>htSmDbrMi_IPLz?0zJ!TCk|9X&Gt5x9ibT(2 z09cgKz>#zrG+ba6Wbs%C4p86q+{D$36kalw4rMBU&g+kSTFA>FEAw+utB-~6mTR20 z{Uu2lQvnP*X>^$5-$(2eZrRvrBQ50WchIp^^gRrsFm-)X3D18 z5jW>2JJiIzV3DNIgLfmV*ddG_sv}M>4J>g9TH7?xI&qUWZ(it7$3eu}L8ZVuS7NcxN?cE})*-flSB^ z{sJ>;<7NSOKDa9#gd?q6T1t`xH%s^6_GeMnoK1cq85o70f()PMGA zfySD2==lI{CDCg?ZazdsmCc7C?b@Jp|T}eJM3HljX|idiEo;b{+NOKM3K7 z%%LNy9~~Ya1;0=SVQe@%@Z%!`xo;`_)}?2zuCwc2FF1C-2d*s-A!H zdrKQ_I95yrE8Z`e*ROA9FtkwRCp~5ZkmONMdu{c?OxyZ4Y3l$?btmrem*Fs;nNjKy zmZtn<2oWr>wM*vB>v6XZi3RiaweinU)@kX$)x5h4@#$cn;TT0zT#B}0y)=3yJPc5y z4zvwLy`=rduO8&jYxy6z!>87!!fU4?G-V&E43TS+Xh6ak#>rlJhduWRRc@uQUin62 z9;g;1eRZ{=ZzH=0%5P^y+{V^);Gam@)v9iCb^F;=T~EbEkFHa_Niu)etuL!R7c@U0s-mFK>=x zo>dF*-uwcI_SE)#JD*Yt_wQ=xaUA%uKW9P20xeKqf6avS^?a+piN;`-P4&9CjoafV z(%Hg#alL3>xehlA=InK_T~mc0)l|L!3#P`sX5~8Ro@(Wxa7cd(?X~wA&FkO#sQvzg zN_*iU-eSV6euG|&kPYf~ucK}|%6e5l`*$d}&z{3-gsVB$FRayd^Xb!9YxQcaemd*9 zYB^Ue=c?tjs)4Il$JMK&m2GT%{;K6%wVaJDq!snbS&o{-E+Yv2>16sKzDCXY_FPiO z^vk>9JgrHp;}0_hC+Wa6*D|Z)Atk}9Pds>FqEU!zHC#HE#f}(Z4D*5hSidYQ#E>(E z;DY+n_3`UsqDmow9pBWTMK!-RFXha;5xi624PrO53ljGeVHg}pXVay0!lrB`gz%(_ zNA{`=yuJ*k{Gc+wz6LQ*QI3Li2#n1&@(`W_-Ak`7r?r>*zHto-X0aZ^896WML&)Os z5MnYdY)%Z@p`0^s>pyRbS@l4J#+O;Iu^97s^bkC?Jh2TY%!m5f-kZMYcpp6!%4=h3 z*ah}IaaqAteFUY#qtVM$0h^pap;3H7c^m=HS}BX6)NSUBxd?-=HDw46jqUx^X#8R> zgPla2#j7qXVfh&WJS7B%ErIZ$f?;rA7Q3PV+BLm?8eRan+iH{$lvfH!SoDSsn>^Cc zjJ`yi8X<%v%$7gbUq~gq1>N1I;NU=UHi1n`CTdnuF(;1ecdm(12TQA&5KcTfhb@`p z1WjoBf15ui^J{thKQ$s1;HrvQpPg)Mkg|GY;_nu~|$ zzbIfr;qxe$(O~*;P(Sdb(c^MIp69lR|L&2m-^S$~$jXv%F;|$x){fXa&Bj_D!NRS9 z`e(e%txw!#{=mw26p=I^!bPuF4&YH|2#`F$!z1Euy#!$n1Tw^!_qWB-lgNn~EC4Vs z#c)^%FRdUGJ1G5{efV_;K!$J;j^GZ|wRzkUYie6R*>Q}g;{8)!}vj#9Z6Y_e1T%p;;|%eF7ApJ@@pTDb z*lI$`e9#f!ENzEV6Zyx=QLp%j zE{yWZc44BO$I|GGpY{T%?vy>I&epq~M{e)}SlsdB zdO}w*GWnnv!_x=PYsw9lV-^|{i^2PRg80Eu0QK^u2L@$nqMk4d!8Hnv+|`MC*~|(? zRP!OQ#xdrgZTkzi1qZP0lJ&SQmKxlQg4W57xRcQp#M6@O*WVawQLG zlcX}>(P-K?>{$!SAIbKZr?FD^oVj4{9H?&y z%L;dP;oGeplC_`uJQc!f^Xua_&6{I$Za>#iBK!6{kabq(BB`3*k|R$uungwZ%^_XE zV)i=6pQt zNW$KPQT=<@kRC&(((JFTzWqFp0TP|K59n-9Y>9{On<;2ny`=AUneJ;$m`bpl70;Xn zGRp@y$2}&yOdtA!-J<0*Rdjq_2wI|BsD;Kv9}*!mQDmw~Pc$Yl8EPP5opc*$H6(03 zj`*$k=w-%yfQtePim}nVKhgSohKo)y#B<;NTDS?ZKJ$+)@x!o zDE=M-Bo7J(?md)P;MH{-Vx9OfX!?pxIVQB*H;JT0TGsIPpBVSv0TKn@bih-VMHB|13X&qf*K|yG=cY@9#6d zoV+1!Z)~1Hasqu=H@?3aD)u+QB))_@@x2|NPDFegndJ$9K994qdeD?nyTRU%Jdj|6 zWAcis_o=-8W!+(hb?g{T?g*)8J!#|S#cj2E8#kA?#q|qt80!~t80V({QdDHvhhMFX z<2(FIl^Q3w<@Y~*h|rXj`PDY1&my9$ILx5A+N#96D6vFgcA*3Kpn+e*IoLeLaY>`q z`ViR@E;TLsgL>8JMS#{@7rwK1l;Rx)t{PmR=It%24X@7uFypZhkWOHJhi_`hZmL6C zi=!NzOmFcwiJu4T%i%5`JdjzI--JS%VTMhPW{}YhtqdFWtz(vtZi_zS(Z_yFuY6Vr3vI_rUW!^DoH^rQ!oU;en!ymO01Y^BP zFfZZB-1F9z?4&(OJ(?>dkqDyI!Cv?}cC34e08X}sHEth51hKrpqxu&&o7cY>qaVaS zzCZ);c>{+%{9Nn$el*anW-;h(Ymdukj0T2X-Gn5vQS-d8UC?Djb_A=ISJ@2u1YRnb z)~eAR_In@V<2-?2{`A!t?qKf^fq}&e@M2bZjt4I2GPe-GMIrm4dyWQ@}lxZ+8<10VEwNPQuMC`@2y7-C26f~oBCQ512}Twb-k3HOik zd+k`pwfhl$ioKA~wN^W7t%^DB-z_-Jk(-I|{wFx_%RrxRd^$8PKP9(NZ49H1QG{rJ zG&}iu`~!$^G#C$6D|l=$3kk?R6T{(T@QEIOpUPPUTUJ-l%(W4xBClexknJ4xB0DY@ z^hzFA2NJv5P+NZINW1~oa^*6VdXXS582LFj z&2t!^Huj*kZ2a}J?=c7$jn1$gmmC`gjq$5(aYQ6^&-fU+{{A+e4%g-mvR#3{ z#)dfgHy>esXm4W7tN5Mi3xL)yhN`K775w+&V}AE}%t+Shw)`egR^_$b)@Rv9O$HGQ zy#5it?{P1+;dX=AXRT?AHIccJn^QGy_x0KLSrcWOy8VBevY&c?HPO*;t@h8Y(9gDi znkeeGPW!i4wCSq3!mZA$hW*j)GDnrFu(KBzm9M6K^y;s(X|P6nDRVo{8F_gx-;CI5 z*UnIX@<}%J@w5X(@siajSy}LbG zB}(JQpkEy55995g*nA$ZW!|u&Jkh?|yXnQ$eAQBW!hA!x>K#R$VQ)!PJp z3>>B8)oooCh3^Y*PdMRTDlTt9#fz-5{WrJnY)`np!KdgBrMcFjpVI3aH(zpI3ysF@ zUOv~pZP!qGBhEY9d8u6&T!b9k?bf8}qRL=ChRWs($M`97J7Ly2Han)#m9Rl^ikAy7 zOZ24h!Eo{A-sx$)Ww3aUI*`lSEAb{NxOw+lZUKWMJbdpq`24x?lM8l=4Byg4@Y-Y9 zRKDCtGTv~xlPzB<^s;k5i|Pt8nZ(6yRb+2EeM{9 z0;La|g7uM#tyA=KAj`L7$JCsvD<169Cd_{%$YUDw7H9}8>W*Z(c;w+C%U(8Vq#C5JT z-Gd`eGQ#}(SbH%<;JZYLK`%00_`rk1zDk~%j3E;64pcd2Gh4Ba@X b|H3R}$q;wm<>{I!fLyZ%TR+|Ay=(s;!vX;I literal 0 HcmV?d00001 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpExt.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpExt.html new file mode 100644 index 000000000..fe026ec6f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpExt.html @@ -0,0 +1,13 @@ + +The dddmp Package for Programmers + + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpExtAbs.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpExtAbs.html new file mode 100644 index 000000000..612554f58 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpExtAbs.html @@ -0,0 +1,91 @@ + +dddmp package abstract + + + + + +
                          +
                          Dddmp_Bin2Text() +
                          Converts from binary to ASCII format + +
                          Dddmp_Text2Bin() +
                          Converts from ASCII to binary format + +
                          Dddmp_cuddAddArrayLoad() +
                          Reads a dump file representing the argument ADDs. + +
                          Dddmp_cuddAddArrayStore() +
                          Writes a dump file representing the argument Array of ADDs. + +
                          Dddmp_cuddAddLoad() +
                          Reads a dump file representing the argument ADD. + +
                          Dddmp_cuddAddStore() +
                          Writes a dump file representing the argument ADD. + +
                          Dddmp_cuddBddArrayLoadCnf() +
                          Reads a dump file in a CNF format. + +
                          Dddmp_cuddBddArrayLoad() +
                          Reads a dump file representing the argument BDDs. + +
                          Dddmp_cuddBddArrayStoreBlif() +
                          Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
                          Dddmp_cuddBddArrayStoreCnf() +
                          Writes a dump file representing the argument array of BDDs + in CNF format. + +
                          Dddmp_cuddBddArrayStorePrefix() +
                          Writes a dump file representing the argument BDD in + a prefix notation. + +
                          Dddmp_cuddBddArrayStoreSmv() +
                          Writes a dump file representing the argument BDD in + a prefix notation. + +
                          Dddmp_cuddBddArrayStore() +
                          Writes a dump file representing the argument Array of BDDs. + +
                          Dddmp_cuddBddDisplayBinary() +
                          Display a binary dump file in a text file + +
                          Dddmp_cuddBddLoadCnf() +
                          Reads a dump file in a CNF format. + +
                          Dddmp_cuddBddLoad() +
                          Reads a dump file representing the argument BDD. + +
                          Dddmp_cuddBddStoreBlif() +
                          Writes a dump file representing the argument BDD in + a Blif/Exlif notation. + +
                          Dddmp_cuddBddStoreCnf() +
                          Writes a dump file representing the argument BDD in + a CNF format. + +
                          Dddmp_cuddBddStorePrefix() +
                          Writes a dump file representing the argument BDD in + a prefix notation. + +
                          Dddmp_cuddBddStoreSmv() +
                          Writes a dump file representing the argument BDD in + a prefix notation. + +
                          Dddmp_cuddBddStore() +
                          Writes a dump file representing the argument BDD. + +
                          Dddmp_cuddHeaderLoadCnf() +
                          Reads the header of a dump file representing the argument BDDs + +
                          Dddmp_cuddHeaderLoad() +
                          Reads the header of a dump file representing the argument BDDs + +
                          + +
                          + +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpExtDet.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpExtDet.html new file mode 100644 index 000000000..38fb590a4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpExtDet.html @@ -0,0 +1,693 @@ + +The dddmp package + + +
                          +
                          +
                          +int 
                          +Dddmp_Bin2Text(
                          +  char * filein, IN: name of binary file
                          +  char * fileout IN: name of ASCII file
                          +)
                          +
                          +
                          Converts from binary to ASCII format. A BDD array is loaded and + and stored to the target file. +

                          + +

                          Side Effects None +

                          + +

                          See Also Dddmp_Text2Bin() + + +
                          +
                          +int 
                          +Dddmp_Text2Bin(
                          +  char * filein, IN: name of ASCII file
                          +  char * fileout IN: name of binary file
                          +)
                          +
                          +
                          Converts from ASCII to binary format. A BDD array is loaded and + and stored to the target file. +

                          + +

                          Side Effects None +

                          + +

                          See Also Dddmp_Bin2Text() + + +
                          +
                          +int 
                          +Dddmp_cuddAddArrayLoad(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
                          +  char ** rootmatchnames, IN: sorted names for loaded roots
                          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names, by ids
                          +  int * varmatchauxids, IN: array of variable auxids, by ids
                          +  int * varcomposeids, IN: array of new ids, by ids
                          +  int  mode, IN: requested input file format
                          +  char * file, IN: file name
                          +  FILE * fp, IN: file pointer
                          +  DdNode *** pproots OUT: array of returned BDD roots
                          +)
                          +
                          +
                          Reads a dump file representing the argument ADDs. See + BDD load functions for detailed explanation. +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddBddArrayStore + + +
                          +
                          +int 
                          +Dddmp_cuddAddArrayStore(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  char * ddname, IN: DD name (or NULL)
                          +  int  nRoots, IN: number of output BDD roots to be stored
                          +  DdNode ** f, IN: array of ADD roots to be stored
                          +  char ** rootnames, IN: array of root names (or NULL)
                          +  char ** varnames, IN: array of variable names (or NULL)
                          +  int * auxids, IN: array of converted var IDs
                          +  int  mode, IN: storing mode selector
                          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument array of ADDs to file. Dumping is + either in text or binary form. see the corresponding BDD dump + function for further details. +

                          + +

                          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

                          + +

                          See Also Dddmp_cuddAddStore +Dddmp_cuddAddLoad +Dddmp_cuddAddArrayLoad + + +
                          +
                          +DdNode * 
                          +Dddmp_cuddAddLoad(
                          +  DdManager * ddMgr, IN: Manager
                          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names by IDs
                          +  int * varmatchauxids, IN: array of variable auxids by IDs
                          +  int * varcomposeids, IN: array of new ids by IDs
                          +  int  mode, IN: requested input file format
                          +  char * file, IN: file name
                          +  FILE * fp IN: file pointer
                          +)
                          +
                          +
                          Reads a dump file representing the argument ADD. + Dddmp_cuddAddArrayLoad is used through a dummy array. +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddAddStore +Dddmp_cuddAddArrayLoad + + +
                          +
                          +int 
                          +Dddmp_cuddAddStore(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  char * ddname, IN: DD name (or NULL)
                          +  DdNode * f, IN: ADD root to be stored
                          +  char ** varnames, IN: array of variable names (or NULL)
                          +  int * auxids, IN: array of converted var ids
                          +  int  mode, IN: storing mode selector
                          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument ADD to file. Dumping is done through + Dddmp_cuddAddArrayStore, And a dummy array of 1 ADD root is + used for this purpose. +

                          + +

                          Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

                          + +

                          See Also Dddmp_cuddAddLoad +Dddmp_cuddAddArrayLoad + + +
                          +
                          +int 
                          +Dddmp_cuddBddArrayLoadCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  Dddmp_RootMatchType  rootmatchmode, IN: storing mode selector
                          +  char ** rootmatchnames, IN: sorted names for loaded roots
                          +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names, by IDs
                          +  int * varmatchauxids, IN: array of variable auxids, by IDs
                          +  int * varcomposeids, IN: array of new ids, by IDs
                          +  int  mode, IN: computation Mode
                          +  char * file, IN: file name
                          +  FILE * fp, IN: file pointer
                          +  DdNode *** rootsPtrPtr, OUT: array of returned BDD roots
                          +  int * nRoots OUT: number of BDDs returned
                          +)
                          +
                          +
                          Reads a dump file representing the argument BDD in a + CNF formula. +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddBddArrayLoad + + +
                          +
                          +int 
                          +Dddmp_cuddBddArrayLoad(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  Dddmp_RootMatchType  rootMatchMode, IN: storing mode selector
                          +  char ** rootmatchnames, IN: sorted names for loaded roots
                          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names, by ids
                          +  int * varmatchauxids, IN: array of variable auxids, by ids
                          +  int * varcomposeids, IN: array of new ids, by ids
                          +  int  mode, IN: requested input file format
                          +  char * file, IN: file name
                          +  FILE * fp, IN: file pointer
                          +  DdNode *** pproots OUT: array of returned BDD roots
                          +)
                          +
                          +
                          Reads a dump file representing the argument BDDs. The header is + common to both text and binary mode. The node list is either + in text or binary format. A dynamic vector of DD pointers + is allocated to support conversion from DD indexes to pointers. + Several criteria are supported for variable match between file + and dd manager. Several changes/permutations/compositions are allowed + for variables while loading DDs. Variable of the dd manager are allowed + to match with variables on file on ids, permids, varnames, + varauxids; also direct composition between ids and + composeids is supported. More in detail: +
                            +
                          1. varMatchMode=DDDMP_VAR_MATCHIDS

                            + allows the loading of a DD keeping variable IDs unchanged + (regardless of the variable ordering of the reading manager); this + is useful, for example, when swapping DDs to file and restoring them + later from file, after possible variable reordering activations. + +

                          2. varMatchMode=DDDMP_VAR_MATCHPERMIDS

                            + is used to allow variable match according to the position in the + ordering. + +

                          3. varMatchMode=DDDMP_VAR_MATCHNAMES

                            + requires a non NULL varmatchnames parameter; this is a vector of + strings in one-to-one correspondence with variable IDs of the + reading manager. Variables in the DD file read are matched with + manager variables according to their name (a non NULL varnames + parameter was required while storing the DD file). + +

                          4. varMatchMode=DDDMP_VAR_MATCHIDS

                            + has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary + IDs are used instead of strings; the additional non NULL + varmatchauxids parameter is needed. + +

                          5. varMatchMode=DDDMP_VAR_COMPOSEIDS

                            + uses the additional varcomposeids parameter is used as array of + variable ids to be composed with ids stored in file. +

                          + + In the present implementation, the array varnames (3), varauxids (4) + and composeids (5) need to have one entry for each variable in the + DD manager (NULL pointers are allowed for unused variables + in varnames). Hence variables need to be already present in the + manager. All arrays are sorted according to IDs. + + All the loaded BDDs are referenced before returning them. +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddBddArrayStore + + +
                          +
                          +int 
                          +Dddmp_cuddBddArrayStoreBlif(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  int  nroots, IN: number of output BDD roots to be stored
                          +  DdNode ** f, IN: array of BDD roots to be stored
                          +  char ** inputNames, IN: array of variable names (or NULL)
                          +  char ** outputNames, IN: array of root names (or NULL)
                          +  char * modelName, IN: Model Name
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBLif. + A dummy array of 1 BDD root is used for this purpose. +

                          + +

                          See Also Dddmp_cuddBddArrayStorePrefix + + +
                          +
                          +int 
                          +Dddmp_cuddBddArrayStoreCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode ** f, IN: array of BDD roots to be stored
                          +  int  rootN, IN: # output BDD roots to be stored
                          +  Dddmp_DecompCnfStoreType  mode, IN: format selection
                          +  int  noHeader, IN: do not store header iff 1
                          +  char ** varNames, IN: array of variable names (or NULL)
                          +  int * bddIds, IN: array of converted var IDs
                          +  int * bddAuxIds, IN: array of BDD node Auxiliary Ids
                          +  int * cnfIds, IN: array of converted var IDs
                          +  int  idInitial, IN: starting id for cutting variables
                          +  int  edgeInTh, IN: Max # Incoming Edges
                          +  int  pathLengthTh, IN: Max Path Length
                          +  char * fname, IN: file name
                          +  FILE * fp, IN: pointer to the store file
                          +  int * clauseNPtr, OUT: number of clause stored
                          +  int * varNewNPtr OUT: number of new variable created
                          +)
                          +
                          +
                          Dumps the argument array of BDDs to file. +

                          + +

                          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. + Three methods are allowed: + * NodeByNode method: Insert a cut-point for each BDD node (but the + terminal nodes) + * MaxtermByMaxterm method: Insert no cut-points, i.e. the off-set of + trhe function is stored + * Best method: Tradeoff between the previous two methods. + Auxiliary variables, i.e., cut points are inserted following these + criterias: + * edgeInTh + indicates the maximum number of incoming edges up to which + no cut point (auxiliary variable) is inserted. + If edgeInTh: + * is equal to -1 no cut point due to incoming edges are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node with a single + incoming edge, i.e., each node, (NodeByNode method). + * is equal to n a cut point is inserted for each node with (n+1) + incoming edges. + * pathLengthTh + indicates the maximum length path up to which no cut points + (auxiliary variable) is inserted. + If the path length between two nodes exceeds this value, a cut point + is inserted. + If pathLengthTh: + * is equal to -1 no cut point due path length are inserted + (MaxtermByMaxterm method.) + * is equal to 0 a cut point is inserted for each node (NodeByNode + method). + * is equal to n a cut point is inserted on path whose length is + equal to (n+1). + Notice that the maximum number of literals in a clause is equal + to (pathLengthTh + 2), i.e., for each path we have to keep into + account a CNF variable for each node plus 2 added variables for + the bottom and top-path cut points. + The stored file can contain a file header or not depending on the + noHeader parameter (IFF 0, usual setting, the header is usually stored. + This option can be useful in storing multiple BDDs, as separate BDDs, + on the same file leaving the opening of the file to the caller. +

                          + +

                          +
                          +int 
                          +Dddmp_cuddBddArrayStorePrefix(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  int  nroots, IN: number of output BDD roots to be stored
                          +  DdNode ** f, IN: array of BDD roots to be stored
                          +  char ** inputNames, IN: array of variable names (or NULL)
                          +  char ** outputNames, IN: array of root names (or NULL)
                          +  char * modelName, IN: Model Name
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                          + +

                          See Also Dddmp_cuddBddArrayStore + + +
                          +
                          +int 
                          +Dddmp_cuddBddArrayStoreSmv(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  int  nroots, IN: number of output BDD roots to be stored
                          +  DdNode ** f, IN: array of BDD roots to be stored
                          +  char ** inputNames, IN: array of variable names (or NULL)
                          +  char ** outputNames, IN: array of root names (or NULL)
                          +  char * modelName, IN: Model Name
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                          + +

                          See Also Dddmp_cuddBddArrayStore + + +
                          +
                          +int 
                          +Dddmp_cuddBddArrayStore(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  char * ddname, IN: dd name (or NULL)
                          +  int  nRoots, IN: number of output BDD roots to be stored
                          +  DdNode ** f, IN: array of BDD roots to be stored
                          +  char ** rootnames, IN: array of root names (or NULL)
                          +  char ** varnames, IN: array of variable names (or NULL)
                          +  int * auxids, IN: array of converted var IDs
                          +  int  mode, IN: storing mode selector
                          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument array of BDDs to file. Dumping is either + in text or binary form. BDDs are stored to the fp (already + open) file if not NULL. Otherwise the file whose name is + fname is opened in write mode. The header has the same format + for both textual and binary dump. Names are allowed for input + variables (vnames) and for represented functions (rnames). + For sake of generality and because of dynamic variable + ordering both variable IDs and permuted IDs are included. + New IDs are also supported (auxids). Variables are identified + with incremental numbers. according with their positiom in + the support set. In text mode, an extra info may be added, + chosen among the following options: name, ID, PermID, or an + auxiliary id. Since conversion from DD pointers to integers + is required, DD nodes are temporarily removed from the unique + hash table. This allows the use of the next field to store + node IDs. +

                          + +

                          Side Effects Nodes are temporarily removed from the unique hash + table. They are re-linked after the store operation in a + modified order. +

                          + +

                          See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                          +
                          +int 
                          +Dddmp_cuddBddDisplayBinary(
                          +  char * fileIn, IN: name of binary file
                          +  char * fileOut IN: name of text file
                          +)
                          +
                          +
                          Display a binary dump file in a text file +

                          + +

                          Side Effects None +

                          + +

                          See Also Dddmp_cuddBddStore +Dddmp_cuddBddLoad + + +
                          +
                          +int 
                          +Dddmp_cuddBddLoadCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  Dddmp_VarMatchType  varmatchmode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names, by IDs
                          +  int * varmatchauxids, IN: array of variable auxids, by IDs
                          +  int * varcomposeids, IN: array of new ids accessed, by IDs
                          +  int  mode, IN: computation mode
                          +  char * file, IN: file name
                          +  FILE * fp, IN: file pointer
                          +  DdNode *** rootsPtrPtr, OUT: array of returned BDD roots
                          +  int * nRoots OUT: number of BDDs returned
                          +)
                          +
                          +
                          Reads a dump file representing the argument BDD in a + CNF formula. + Dddmp_cuddBddArrayLoadCnf is used through a dummy array. + The results is returned in different formats depending on the + mode selection: + IFF mode == 0 Return the Clauses without Conjunction + IFF mode == 1 Return the sets of BDDs without Quantification + IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                          +
                          +DdNode * 
                          +Dddmp_cuddBddLoad(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  Dddmp_VarMatchType  varMatchMode, IN: storing mode selector
                          +  char ** varmatchnames, IN: array of variable names - by IDs
                          +  int * varmatchauxids, IN: array of variable auxids - by IDs
                          +  int * varcomposeids, IN: array of new ids accessed - by IDs
                          +  int  mode, IN: requested input file format
                          +  char * file, IN: file name
                          +  FILE * fp IN: file pointer
                          +)
                          +
                          +
                          Reads a dump file representing the argument BDD. + Dddmp_cuddBddArrayLoad is used through a dummy array (see this + function's description for more details). + Mode, the requested input file format, is checked against + the file format. + The loaded BDDs is referenced before returning it. +

                          + +

                          Side Effects A vector of pointers to DD nodes is allocated and freed. +

                          + +

                          See Also Dddmp_cuddBddStore +Dddmp_cuddBddArrayLoad + + +
                          +
                          +int 
                          +Dddmp_cuddBddStoreBlif(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  int  nRoots, IN: Number of BDD roots
                          +  DdNode * f, IN: BDD root to be stored
                          +  char ** inputNames, IN: Array of variable names
                          +  char ** outputNames, IN: Array of root names
                          +  char * modelName, IN: Model Name
                          +  char * fileName, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStoreBlif. + A dummy array of 1 BDD root is used for this purpose. +

                          + +

                          See Also Dddmp_cuddBddStorePrefix + + +
                          +
                          +int 
                          +Dddmp_cuddBddStoreCnf(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  DdNode * f, IN: BDD root to be stored
                          +  Dddmp_DecompCnfStoreType  mode, IN: format selection
                          +  int  noHeader, IN: do not store header iff 1
                          +  char ** varNames, IN: array of variable names (or NULL)
                          +  int * bddIds, IN: array of var ids
                          +  int * bddAuxIds, IN: array of BDD node Auxiliary Ids
                          +  int * cnfIds, IN: array of CNF var ids
                          +  int  idInitial, IN: starting id for cutting variables
                          +  int  edgeInTh, IN: Max # Incoming Edges
                          +  int  pathLengthTh, IN: Max Path Length
                          +  char * fname, IN: file name
                          +  FILE * fp, IN: pointer to the store file
                          +  int * clauseNPtr, OUT: number of clause stored
                          +  int * varNewNPtr OUT: number of new variable created
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + This task is performed by calling the function + Dddmp_cuddBddArrayStoreCnf. +

                          + +

                          Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

                          + +

                          See Also Dddmp_cuddBddArrayStoreCnf + + +
                          +
                          +int 
                          +Dddmp_cuddBddStorePrefix(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  int  nRoots, IN: Number of BDD roots
                          +  DdNode * f, IN: BDD root to be stored
                          +  char ** inputNames, IN: Array of variable names
                          +  char ** outputNames, IN: Array of root names
                          +  char * modelName, IN: Model Name
                          +  char * fileName, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                          + +

                          See Also Dddmp_cuddBddStore + + +
                          +
                          +int 
                          +Dddmp_cuddBddStoreSmv(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  int  nRoots, IN: Number of BDD roots
                          +  DdNode * f, IN: BDD root to be stored
                          +  char ** inputNames, IN: Array of variable names
                          +  char ** outputNames, IN: Array of root names
                          +  char * modelName, IN: Model Name
                          +  char * fileName, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. + Dumping is done through Dddmp_cuddBddArrayStorePrefix. + A dummy array of 1 BDD root is used for this purpose. +

                          + +

                          See Also Dddmp_cuddBddStore + + +
                          +
                          +int 
                          +Dddmp_cuddBddStore(
                          +  DdManager * ddMgr, IN: DD Manager
                          +  char * ddname, IN: DD name (or NULL)
                          +  DdNode * f, IN: BDD root to be stored
                          +  char ** varnames, IN: array of variable names (or NULL)
                          +  int * auxids, IN: array of converted var ids
                          +  int  mode, IN: storing mode selector
                          +  Dddmp_VarInfoType  varinfo, IN: extra info for variables in text mode
                          +  char * fname, IN: File name
                          +  FILE * fp IN: File pointer to the store file
                          +)
                          +
                          +
                          Dumps the argument BDD to file. Dumping is done through + Dddmp_cuddBddArrayStore. A dummy array of 1 BDD root is + used for this purpose. +

                          + +

                          Side Effects Nodes are temporarily removed from unique hash. They are + re-linked after the store operation in a modified order. +

                          + +

                          See Also Dddmp_cuddBddLoad +Dddmp_cuddBddArrayLoad + + +
                          +
                          +int 
                          +Dddmp_cuddHeaderLoadCnf(
                          +  int * nVars, OUT: number of DD variables
                          +  int * nsuppvars, OUT: number of support variables
                          +  char *** suppVarNames, OUT: array of support variable names
                          +  char *** orderedVarNames, OUT: array of variable names
                          +  int ** varIds, OUT: array of variable ids
                          +  int ** varComposeIds, OUT: array of permids ids
                          +  int ** varAuxIds, OUT: array of variable aux ids
                          +  int * nRoots, OUT: number of root in the file
                          +  char * file, IN: file name
                          +  FILE * fp IN: file pointer
                          +)
                          +
                          +
                          Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. +

                          + +

                          See Also Dddmp_cuddBddArrayLoad + + +
                          +
                          +int 
                          +Dddmp_cuddHeaderLoad(
                          +  Dddmp_DecompType * ddType, OUT: selects the proper decomp type
                          +  int * nVars, OUT: number of DD variables
                          +  int * nsuppvars, OUT: number of support variables
                          +  char *** suppVarNames, OUT: array of support variable names
                          +  char *** orderedVarNames, OUT: array of variable names
                          +  int ** varIds, OUT: array of variable ids
                          +  int ** varComposeIds, OUT: array of permids ids
                          +  int ** varAuxIds, OUT: array of variable aux ids
                          +  int * nRoots, OUT: number of root in the file
                          +  char * file, IN: file name
                          +  FILE * fp IN: file pointer
                          +)
                          +
                          +
                          Reads the header of a dump file representing the argument BDDs. + Returns main information regarding DD type stored in the file, + the variable ordering used, the number of variables, etc. + It reads only the header of the file NOT the BDD/ADD section. +

                          + +

                          See Also Dddmp_cuddBddArrayLoad + + + +
                          +
                          +Last updated on 1040218 17h14 + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpTitle.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpTitle.html new file mode 100644 index 000000000..25a369433 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/dddmpTitle.html @@ -0,0 +1,17 @@ + +The dddmp package: Title + + + + + + + + +
                          + Programmer view + Maintainer by function + Maintainer by file
                          + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/packages.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/packages.html new file mode 100644 index 000000000..27e4ace19 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/packages.html @@ -0,0 +1,12 @@ + +Package Documentation + + + + + + + + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/pkgIndex.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/pkgIndex.html new file mode 100644 index 000000000..f2efd6bc8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/doc/pkgIndex.html @@ -0,0 +1,13 @@ + +Package Documentation + +

                          Package Documentation


                          + + + + +
                          dddmpFunctions to read in and write out BDDs, ADDs +
                          +
                          +Last updated on 1040218 17h15 + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/0.add b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/0.add new file mode 100644 index 000000000..ba6bb3dcf --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/0.add @@ -0,0 +1,21 @@ +.ver DDDMP-2.0 +.add +.mode A +.varinfo 0 +.nnodes 5 +.nvars 3 +.nsuppvars 2 +.suppvarnames DUMMY1 DUMMY2 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 +.ids 1 2 +.permids 1 2 +.auxids 1 2 +.nroots 1 +.rootids 5 +.nodes +1 T 1 0 0 +2 T 2 0 0 +3 T 0 0 0 +4 2 1 2 3 +5 1 0 1 4 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/0.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/0.bdd new file mode 100644 index 000000000..5092978ef --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/0.bdd @@ -0,0 +1,19 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 5 +.nvars 50 +.nsuppvars 3 +.suppvarnames DUMMY1 DUMMY2 DUMMY3 +.ids 1 2 3 +.permids 1 2 3 +.auxids 1 2 3 +.nroots 1 +.rootids -5 +.nodes +1 T 1 0 0 +2 3 2 1 -1 +3 2 1 1 2 +4 2 1 1 -2 +5 1 0 3 4 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/0or1.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/0or1.bdd new file mode 100644 index 000000000..4fda5f20f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/0or1.bdd @@ -0,0 +1,119 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 104 +.nvars 50 +.nsuppvars 16 +.suppvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY6 DUMMY7 DUMMY8 DUMMY9 DUMMY10 DUMMY11 DUMMY12 DUMMY13 DUMMY14 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 +.ids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -104 +.nodes +1 T 1 0 0 +2 22 15 1 -1 +3 21 14 1 -2 +4 20 13 1 3 +5 19 12 1 4 +6 20 13 3 1 +7 21 14 1 2 +8 20 13 1 7 +9 19 12 6 8 +10 18 11 5 9 +11 17 10 1 10 +12 18 11 1 9 +13 17 10 1 12 +14 16 9 11 13 +15 20 13 7 -1 +16 21 14 2 -1 +17 20 13 16 -3 +18 19 12 15 -17 +19 21 14 2 1 +20 20 13 19 7 +21 19 12 6 20 +22 18 11 18 21 +23 17 10 1 22 +24 16 9 23 13 +25 18 11 18 9 +26 17 10 1 25 +27 16 9 26 13 +28 15 8 24 27 +29 12 7 28 27 +30 11 6 28 29 +31 11 6 28 27 +32 10 5 30 31 +33 4 4 14 32 +34 3 3 33 -1 +35 2 2 33 34 +36 19 12 1 8 +37 18 11 5 36 +38 17 10 1 37 +39 16 9 38 1 +40 19 12 1 20 +41 18 11 18 40 +42 17 10 1 41 +43 16 9 42 1 +44 18 11 18 36 +45 17 10 1 44 +46 16 9 45 1 +47 15 8 43 46 +48 12 7 47 46 +49 11 6 47 48 +50 11 6 47 46 +51 10 5 49 50 +52 4 4 39 51 +53 3 3 1 -52 +54 2 2 52 -53 +55 1 1 35 54 +56 20 13 16 -1 +57 21 14 1 -1 +58 20 13 1 57 +59 19 12 56 -58 +60 18 11 59 -9 +61 17 10 1 -60 +62 19 12 56 -8 +63 18 11 62 -9 +64 17 10 1 -63 +65 16 9 61 64 +66 21 14 2 -2 +67 20 13 66 1 +68 20 13 16 -57 +69 19 12 67 68 +70 18 11 69 -21 +71 17 10 1 -70 +72 16 9 71 64 +73 18 11 69 -9 +74 17 10 1 -73 +75 16 9 74 64 +76 15 8 72 75 +77 12 7 76 75 +78 11 6 76 77 +79 11 6 76 75 +80 10 5 78 79 +81 4 4 65 80 +82 3 3 81 -1 +83 2 2 81 82 +84 18 11 59 -36 +85 17 10 1 -84 +86 18 11 62 -1 +87 17 10 1 -86 +88 16 9 85 87 +89 18 11 69 -40 +90 17 10 1 -89 +91 16 9 90 87 +92 18 11 69 -36 +93 17 10 1 -92 +94 16 9 93 87 +95 15 8 91 94 +96 12 7 95 94 +97 11 6 95 96 +98 11 6 95 94 +99 10 5 97 98 +100 4 4 88 99 +101 3 3 1 -100 +102 2 2 100 -101 +103 1 1 83 102 +104 0 0 55 103 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/1.add b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/1.add new file mode 100644 index 000000000..ab6ab4d94 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/1.add @@ -0,0 +1,28 @@ +.ver DDDMP-2.0 +.add +.mode A +.varinfo 0 +.nnodes 12 +.nvars 50 +.nsuppvars 4 +.suppvarnames DUMMY1 DUMMY2 DUMMY3 DUMMY4 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY6 DUMMY7 DUMMY8 DUMMY9 DUMMY10 DUMMY11 DUMMY12 DUMMY13 DUMMY14 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 +.ids 1 2 3 4 +.permids 1 2 3 4 +.auxids 2 3 4 0 +.nroots 1 +.rootids 12 +.nodes +1 T 0 0 0 +2 T 2 0 0 +3 4 3 1 2 +4 T 1 0 0 +5 4 3 4 1 +6 3 2 3 5 +7 4 3 2 4 +8 3 2 7 3 +9 2 1 6 8 +10 3 2 5 7 +11 2 1 10 6 +12 1 0 9 11 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/1.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/1.bdd new file mode 100644 index 000000000..98977dd76 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/1.bdd @@ -0,0 +1,110 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 96 +.nvars 50 +.nsuppvars 14 +.suppvarnames DUMMY0 DUMMY1 DUMMY4 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.ids 0 1 4 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 4 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 4 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -96 +.nodes +1 T 1 0 0 +2 22 13 1 -1 +3 21 12 1 -2 +4 20 11 1 3 +5 19 10 1 4 +6 20 11 3 1 +7 21 12 1 2 +8 20 11 1 7 +9 19 10 6 8 +10 18 9 5 9 +11 17 8 1 10 +12 18 9 1 9 +13 17 8 1 12 +14 16 7 11 13 +15 20 11 7 -1 +16 21 12 2 -1 +17 20 11 16 -3 +18 19 10 15 -17 +19 21 12 2 1 +20 20 11 19 7 +21 19 10 6 20 +22 18 9 18 21 +23 17 8 1 22 +24 16 7 23 13 +25 18 9 18 9 +26 17 8 1 25 +27 16 7 26 13 +28 15 6 24 27 +29 12 5 28 27 +30 11 4 28 29 +31 11 4 28 27 +32 10 3 30 31 +33 4 2 14 32 +34 19 10 1 8 +35 18 9 5 34 +36 17 8 1 35 +37 16 7 36 1 +38 19 10 1 20 +39 18 9 18 38 +40 17 8 1 39 +41 16 7 40 1 +42 18 9 18 34 +43 17 8 1 42 +44 16 7 43 1 +45 15 6 41 44 +46 12 5 45 44 +47 11 4 45 46 +48 11 4 45 44 +49 10 3 47 48 +50 4 2 37 49 +51 1 1 33 50 +52 20 11 16 -1 +53 21 12 1 -1 +54 20 11 1 53 +55 19 10 52 -54 +56 18 9 55 -9 +57 17 8 1 -56 +58 19 10 52 -8 +59 18 9 58 -9 +60 17 8 1 -59 +61 16 7 57 60 +62 21 12 2 -2 +63 20 11 62 1 +64 20 11 16 -53 +65 19 10 63 64 +66 18 9 65 -21 +67 17 8 1 -66 +68 16 7 67 60 +69 18 9 65 -9 +70 17 8 1 -69 +71 16 7 70 60 +72 15 6 68 71 +73 12 5 72 71 +74 11 4 72 73 +75 11 4 72 71 +76 10 3 74 75 +77 4 2 61 76 +78 18 9 55 -34 +79 17 8 1 -78 +80 18 9 58 -1 +81 17 8 1 -80 +82 16 7 79 81 +83 18 9 65 -38 +84 17 8 1 -83 +85 16 7 84 81 +86 18 9 65 -34 +87 17 8 1 -86 +88 16 7 87 81 +89 15 6 85 88 +90 12 5 89 88 +91 11 4 89 90 +92 11 4 89 88 +93 10 3 91 92 +94 4 2 82 93 +95 1 1 77 94 +96 0 0 51 95 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/2.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/2.bdd new file mode 100644 index 000000000..00b7cf3e4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/2.bdd @@ -0,0 +1,118 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 104 +.nvars 50 +.nsuppvars 16 +.suppvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.ids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -104 +.nodes +1 T 1 0 0 +2 22 15 1 -1 +3 21 14 1 -2 +4 20 13 1 3 +5 19 12 1 4 +6 20 13 3 1 +7 21 14 1 2 +8 20 13 1 7 +9 19 12 6 8 +10 18 11 5 9 +11 17 10 1 10 +12 18 11 1 9 +13 17 10 1 12 +14 16 9 11 13 +15 20 13 7 -1 +16 21 14 2 -1 +17 20 13 16 -3 +18 19 12 15 -17 +19 21 14 2 1 +20 20 13 19 7 +21 19 12 6 20 +22 18 11 18 21 +23 17 10 1 22 +24 16 9 23 13 +25 18 11 18 9 +26 17 10 1 25 +27 16 9 26 13 +28 15 8 24 27 +29 12 7 28 27 +30 11 6 28 29 +31 11 6 28 27 +32 10 5 30 31 +33 4 4 14 32 +34 3 3 1 33 +35 2 2 1 34 +36 19 12 1 8 +37 18 11 5 36 +38 17 10 1 37 +39 16 9 38 1 +40 19 12 1 20 +41 18 11 18 40 +42 17 10 1 41 +43 16 9 42 1 +44 18 11 18 36 +45 17 10 1 44 +46 16 9 45 1 +47 15 8 43 46 +48 12 7 47 46 +49 11 6 47 48 +50 11 6 47 46 +51 10 5 49 50 +52 4 4 39 51 +53 3 3 52 1 +54 2 2 1 53 +55 1 1 35 54 +56 20 13 16 -1 +57 21 14 1 -1 +58 20 13 1 57 +59 19 12 56 -58 +60 18 11 59 -9 +61 17 10 1 -60 +62 19 12 56 -8 +63 18 11 62 -9 +64 17 10 1 -63 +65 16 9 61 64 +66 21 14 2 -2 +67 20 13 66 1 +68 20 13 16 -57 +69 19 12 67 68 +70 18 11 69 -21 +71 17 10 1 -70 +72 16 9 71 64 +73 18 11 69 -9 +74 17 10 1 -73 +75 16 9 74 64 +76 15 8 72 75 +77 12 7 76 75 +78 11 6 76 77 +79 11 6 76 75 +80 10 5 78 79 +81 4 4 65 80 +82 3 3 1 81 +83 2 2 1 82 +84 18 11 59 -36 +85 17 10 1 -84 +86 18 11 62 -1 +87 17 10 1 -86 +88 16 9 85 87 +89 18 11 69 -40 +90 17 10 1 -89 +91 16 9 90 87 +92 18 11 69 -36 +93 17 10 1 -92 +94 16 9 93 87 +95 15 8 91 94 +96 12 7 95 94 +97 11 6 95 96 +98 11 6 95 94 +99 10 5 97 98 +100 4 4 88 99 +101 3 3 100 1 +102 2 2 1 101 +103 1 1 83 102 +104 0 0 55 103 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/2and3.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/2and3.bdd new file mode 100644 index 000000000..650c45492 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/2and3.bdd @@ -0,0 +1,76 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 61 +.nvars 50 +.nsuppvars 16 +.suppvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY6 DUMMY7 DUMMY8 DUMMY9 DUMMY10 DUMMY11 DUMMY12 DUMMY13 DUMMY14 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 +.ids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 2 3 4 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -61 +.nodes +1 T 1 0 0 +2 22 15 1 -1 +3 21 14 1 2 +4 20 13 3 -1 +5 21 14 2 -1 +6 20 13 5 -1 +7 19 12 4 -6 +8 21 14 2 1 +9 20 13 8 1 +10 19 12 1 9 +11 18 11 7 10 +12 17 10 1 11 +13 16 9 12 1 +14 19 12 4 1 +15 18 11 14 1 +16 17 10 1 15 +17 16 9 16 1 +18 15 8 13 17 +19 18 11 7 1 +20 17 10 1 19 +21 16 9 20 1 +22 15 8 21 17 +23 12 7 18 22 +24 11 6 18 23 +25 11 6 23 22 +26 10 5 24 25 +27 4 4 1 26 +28 3 3 1 27 +29 2 2 1 28 +30 3 3 27 1 +31 2 2 1 30 +32 1 1 29 31 +33 19 12 6 -1 +34 18 11 33 -1 +35 17 10 1 -34 +36 21 14 2 -2 +37 20 13 36 1 +38 19 12 37 6 +39 18 11 38 -10 +40 17 10 1 -39 +41 16 9 40 35 +42 19 12 37 -1 +43 18 11 42 -1 +44 17 10 1 -43 +45 16 9 44 35 +46 15 8 41 45 +47 18 11 38 -1 +48 17 10 1 -47 +49 16 9 48 35 +50 15 8 49 45 +51 12 7 46 50 +52 11 6 46 51 +53 11 6 51 50 +54 10 5 52 53 +55 4 4 35 54 +56 3 3 1 55 +57 2 2 1 56 +58 3 3 55 1 +59 2 2 1 58 +60 1 1 57 59 +61 0 0 32 60 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/3.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/3.bdd new file mode 100644 index 000000000..33d6ddf54 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/3.bdd @@ -0,0 +1,304 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 290 +.nvars 50 +.nsuppvars 17 +.suppvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY10 DUMMY11 DUMMY12 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 +.ids 0 1 2 3 4 5 10 11 12 15 16 17 18 19 20 21 22 +.permids 0 1 2 3 4 5 10 11 12 15 16 17 18 19 20 21 22 +.auxids 0 1 2 3 4 5 10 11 12 15 16 17 18 19 20 21 22 +.nroots 1 +.rootids -290 +.nodes +1 T 1 0 0 +2 22 16 1 -1 +3 21 15 2 1 +4 20 14 3 1 +5 19 13 4 1 +6 18 12 1 5 +7 17 11 1 6 +8 20 14 2 1 +9 19 13 8 1 +10 18 12 1 9 +11 17 11 1 10 +12 5 5 7 11 +13 21 15 1 2 +14 20 14 13 -1 +15 21 15 2 -1 +16 20 14 15 -1 +17 19 13 14 -16 +18 20 14 3 -1 +19 21 15 1 -1 +20 20 14 19 -1 +21 19 13 18 -20 +22 18 12 17 21 +23 17 11 1 22 +24 20 14 13 -15 +25 19 13 24 1 +26 20 14 3 -15 +27 19 13 26 1 +28 18 12 25 27 +29 17 11 1 28 +30 16 10 23 29 +31 19 13 14 1 +32 19 13 18 1 +33 18 12 31 32 +34 17 11 1 33 +35 16 10 34 29 +36 15 9 30 35 +37 19 13 18 -16 +38 18 12 17 37 +39 17 11 1 38 +40 16 10 39 29 +41 15 9 40 35 +42 12 8 36 41 +43 11 7 36 42 +44 11 7 42 36 +45 10 6 43 44 +46 20 14 2 -1 +47 19 13 46 -20 +48 18 12 17 47 +49 17 11 1 48 +50 20 14 2 -15 +51 19 13 50 1 +52 18 12 25 51 +53 17 11 1 52 +54 16 10 49 53 +55 19 13 46 1 +56 18 12 31 55 +57 17 11 1 56 +58 16 10 57 53 +59 15 9 54 58 +60 19 13 46 -16 +61 18 12 17 60 +62 17 11 1 61 +63 16 10 62 53 +64 15 9 63 58 +65 12 8 59 64 +66 11 7 59 65 +67 11 7 65 59 +68 10 6 66 67 +69 5 5 45 68 +70 4 4 12 69 +71 21 15 2 -2 +72 20 14 71 1 +73 19 13 72 1 +74 18 12 1 73 +75 17 11 1 74 +76 20 14 1 13 +77 19 13 72 76 +78 18 12 1 77 +79 17 11 1 78 +80 16 10 75 79 +81 20 14 15 1 +82 19 13 81 1 +83 18 12 1 82 +84 17 11 1 83 +85 19 13 81 76 +86 18 12 1 85 +87 17 11 1 86 +88 16 10 84 87 +89 5 5 80 88 +90 20 14 71 -1 +91 19 13 90 -20 +92 18 12 17 91 +93 17 11 1 92 +94 20 14 71 -15 +95 19 13 94 76 +96 18 12 25 95 +97 17 11 1 96 +98 16 10 93 97 +99 19 13 90 1 +100 18 12 31 99 +101 17 11 1 100 +102 16 10 101 97 +103 15 9 98 102 +104 19 13 90 -16 +105 18 12 17 104 +106 17 11 1 105 +107 16 10 106 97 +108 15 9 107 102 +109 12 8 103 108 +110 11 7 103 109 +111 11 7 109 103 +112 10 6 110 111 +113 19 13 16 -20 +114 18 12 17 113 +115 17 11 1 114 +116 20 14 15 -15 +117 19 13 116 76 +118 18 12 25 117 +119 17 11 1 118 +120 16 10 115 119 +121 19 13 16 1 +122 18 12 31 121 +123 17 11 1 122 +124 16 10 123 119 +125 15 9 120 124 +126 19 13 16 -16 +127 18 12 17 126 +128 17 11 1 127 +129 16 10 128 119 +130 15 9 129 124 +131 12 8 125 130 +132 11 7 125 131 +133 11 7 131 125 +134 10 6 132 133 +135 5 5 112 134 +136 4 4 89 135 +137 3 3 70 136 +138 5 5 75 84 +139 19 13 94 1 +140 18 12 25 139 +141 17 11 1 140 +142 16 10 93 141 +143 16 10 101 141 +144 15 9 142 143 +145 16 10 106 141 +146 15 9 145 143 +147 12 8 144 146 +148 11 7 144 147 +149 11 7 147 144 +150 10 6 148 149 +151 19 13 116 1 +152 18 12 25 151 +153 17 11 1 152 +154 16 10 115 153 +155 16 10 123 153 +156 15 9 154 155 +157 16 10 128 153 +158 15 9 157 155 +159 12 8 156 158 +160 11 7 156 159 +161 11 7 159 156 +162 10 6 160 161 +163 5 5 150 162 +164 4 4 138 163 +165 3 3 70 164 +166 2 2 137 165 +167 1 1 70 166 +168 19 13 16 -1 +169 18 12 168 -5 +170 17 11 1 -169 +171 18 12 168 -9 +172 17 11 1 -171 +173 5 5 170 172 +174 19 13 72 16 +175 18 12 174 -21 +176 17 11 1 -175 +177 20 14 71 15 +178 19 13 177 -1 +179 18 12 178 -27 +180 17 11 1 -179 +181 16 10 176 180 +182 19 13 72 -1 +183 18 12 182 -32 +184 17 11 1 -183 +185 16 10 184 180 +186 15 9 181 185 +187 18 12 174 -37 +188 17 11 1 -187 +189 16 10 188 180 +190 15 9 189 185 +191 12 8 186 190 +192 11 7 186 191 +193 11 7 191 186 +194 10 6 192 193 +195 18 12 174 -47 +196 17 11 1 -195 +197 18 12 178 -51 +198 17 11 1 -197 +199 16 10 196 198 +200 18 12 182 -55 +201 17 11 1 -200 +202 16 10 201 198 +203 15 9 199 202 +204 18 12 174 -60 +205 17 11 1 -204 +206 16 10 205 198 +207 15 9 206 202 +208 12 8 203 207 +209 11 7 203 208 +210 11 7 208 203 +211 10 6 209 210 +212 5 5 194 211 +213 4 4 173 212 +214 18 12 168 -73 +215 17 11 1 -214 +216 18 12 168 -77 +217 17 11 1 -216 +218 16 10 215 217 +219 18 12 168 -82 +220 17 11 1 -219 +221 18 12 168 -85 +222 17 11 1 -221 +223 16 10 220 222 +224 5 5 218 223 +225 18 12 174 -91 +226 17 11 1 -225 +227 18 12 178 -95 +228 17 11 1 -227 +229 16 10 226 228 +230 18 12 182 -99 +231 17 11 1 -230 +232 16 10 231 228 +233 15 9 229 232 +234 18 12 174 -104 +235 17 11 1 -234 +236 16 10 235 228 +237 15 9 236 232 +238 12 8 233 237 +239 11 7 233 238 +240 11 7 238 233 +241 10 6 239 240 +242 18 12 174 -113 +243 17 11 1 -242 +244 18 12 178 -117 +245 17 11 1 -244 +246 16 10 243 245 +247 18 12 182 -121 +248 17 11 1 -247 +249 16 10 248 245 +250 15 9 246 249 +251 18 12 174 -126 +252 17 11 1 -251 +253 16 10 252 245 +254 15 9 253 249 +255 12 8 250 254 +256 11 7 250 255 +257 11 7 255 250 +258 10 6 256 257 +259 5 5 241 258 +260 4 4 224 259 +261 3 3 213 260 +262 5 5 215 220 +263 18 12 178 -139 +264 17 11 1 -263 +265 16 10 226 264 +266 16 10 231 264 +267 15 9 265 266 +268 16 10 235 264 +269 15 9 268 266 +270 12 8 267 269 +271 11 7 267 270 +272 11 7 270 267 +273 10 6 271 272 +274 18 12 178 -151 +275 17 11 1 -274 +276 16 10 243 275 +277 16 10 248 275 +278 15 9 276 277 +279 16 10 252 275 +280 15 9 279 277 +281 12 8 278 280 +282 11 7 278 281 +283 11 7 281 278 +284 10 6 282 283 +285 5 5 273 284 +286 4 4 262 285 +287 3 3 213 286 +288 2 2 261 287 +289 1 1 213 288 +290 0 0 167 289 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd new file mode 100644 index 000000000..fb774baab --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 3 +.nnodes 35 +.nvars 50 +.nsuppvars 15 +.suppvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +.orderedvarnames V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 3 5 15 17 19 23 43 45 47 73 75 77 95 97 99 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 V50 14 1 -1 +3 V49 13 1 2 +4 V48 12 3 1 +5 V48 12 1 -1 +6 V48 12 2 1 +7 V39 11 5 -6 +8 V49 13 1 -1 +9 V48 12 8 1 +10 V39 11 9 4 +11 V38 10 7 -10 +12 V37 9 1 -11 +13 V38 10 5 -9 +14 V37 9 1 -13 +15 V24 8 12 14 +16 V37 9 1 -7 +17 V37 9 1 -5 +18 V24 8 16 17 +19 V23 7 15 18 +20 V22 6 19 1 +21 V23 7 14 17 +22 V22 6 21 1 +23 V12 5 20 22 +24 V10 4 23 1 +25 V22 6 18 1 +26 V12 5 20 25 +27 V10 4 26 1 +28 V9 3 24 27 +29 V12 5 20 1 +30 V10 4 29 1 +31 V10 4 20 1 +32 V9 3 30 31 +33 V8 2 28 32 +34 V3 1 4 33 +35 V2 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis1 b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis1 new file mode 100644 index 000000000..220059d0c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis1 @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 35 +.nvars 150 +.nsuppvars 15 +.suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 49 14 1 -1 +3 48 13 1 2 +4 47 12 3 1 +5 47 12 1 -1 +6 47 12 2 1 +7 38 11 5 -6 +8 48 13 1 -1 +9 47 12 8 1 +10 38 11 9 4 +11 37 10 7 -10 +12 36 9 1 -11 +13 37 10 5 -9 +14 36 9 1 -13 +15 23 8 12 14 +16 36 9 1 -7 +17 36 9 1 -5 +18 23 8 16 17 +19 22 7 15 18 +20 21 6 19 1 +21 22 7 14 17 +22 21 6 21 1 +23 11 5 20 22 +24 9 4 23 1 +25 21 6 18 1 +26 11 5 20 25 +27 9 4 26 1 +28 8 3 24 27 +29 11 5 20 1 +30 9 4 29 1 +31 9 4 20 1 +32 8 3 30 31 +33 7 2 28 32 +34 2 1 4 33 +35 1 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis2 b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis2 new file mode 100644 index 000000000..220059d0c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis2 @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 35 +.nvars 150 +.nsuppvars 15 +.suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 49 14 1 -1 +3 48 13 1 2 +4 47 12 3 1 +5 47 12 1 -1 +6 47 12 2 1 +7 38 11 5 -6 +8 48 13 1 -1 +9 47 12 8 1 +10 38 11 9 4 +11 37 10 7 -10 +12 36 9 1 -11 +13 37 10 5 -9 +14 36 9 1 -13 +15 23 8 12 14 +16 36 9 1 -7 +17 36 9 1 -5 +18 23 8 16 17 +19 22 7 15 18 +20 21 6 19 1 +21 22 7 14 17 +22 21 6 21 1 +23 11 5 20 22 +24 9 4 23 1 +25 21 6 18 1 +26 11 5 20 25 +27 9 4 26 1 +28 8 3 24 27 +29 11 5 20 1 +30 9 4 29 1 +31 9 4 20 1 +32 8 3 30 31 +33 7 2 28 32 +34 2 1 4 33 +35 1 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis3 b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis3 new file mode 100644 index 000000000..220059d0c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis3 @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 35 +.nvars 150 +.nsuppvars 15 +.suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 49 14 1 -1 +3 48 13 1 2 +4 47 12 3 1 +5 47 12 1 -1 +6 47 12 2 1 +7 38 11 5 -6 +8 48 13 1 -1 +9 47 12 8 1 +10 38 11 9 4 +11 37 10 7 -10 +12 36 9 1 -11 +13 37 10 5 -9 +14 36 9 1 -13 +15 23 8 12 14 +16 36 9 1 -7 +17 36 9 1 -5 +18 23 8 16 17 +19 22 7 15 18 +20 21 6 19 1 +21 22 7 14 17 +22 21 6 21 1 +23 11 5 20 22 +24 9 4 23 1 +25 21 6 18 1 +26 11 5 20 25 +27 9 4 26 1 +28 8 3 24 27 +29 11 5 20 1 +30 9 4 29 1 +31 9 4 20 1 +32 8 3 30 31 +33 7 2 28 32 +34 2 1 4 33 +35 1 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis4 b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis4 new file mode 100644 index 000000000..220059d0c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.bdd.bis4 @@ -0,0 +1,50 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 35 +.nvars 150 +.nsuppvars 15 +.suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 T 1 0 0 +2 49 14 1 -1 +3 48 13 1 2 +4 47 12 3 1 +5 47 12 1 -1 +6 47 12 2 1 +7 38 11 5 -6 +8 48 13 1 -1 +9 47 12 8 1 +10 38 11 9 4 +11 37 10 7 -10 +12 36 9 1 -11 +13 37 10 5 -9 +14 36 9 1 -13 +15 23 8 12 14 +16 36 9 1 -7 +17 36 9 1 -5 +18 23 8 16 17 +19 22 7 15 18 +20 21 6 19 1 +21 22 7 14 17 +22 21 6 21 1 +23 11 5 20 22 +24 9 4 23 1 +25 21 6 18 1 +26 11 5 20 25 +27 9 4 26 1 +28 8 3 24 27 +29 11 5 20 1 +30 9 4 29 1 +31 9 4 20 1 +32 8 3 30 31 +33 7 2 28 32 +34 2 1 4 33 +35 1 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.cnf b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.cnf new file mode 100644 index 000000000..d1a946c2d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.cnf @@ -0,0 +1,130 @@ +c # BDD stored by the DDDMP tool in CNF format +c # +c # Warning: AUX IDs missing ... equal to BDD IDs. +c # +c .ver DDDMP-2.0 +c .nnodes 35 +c .nvars 50 +c .nsuppvars 15 +c .suppvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +c .orderedvarnames V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +c .ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .cnfids 2 3 8 9 10 12 22 23 24 37 38 39 48 49 50 +c .nroots 1 +c .rootids 1 +c .nAddedCnfVar 31 +c # +c # Init CNF Clauses +c # +p cnf 130 108 +100 -49 0 +100 -50 0 +-100 49 50 0 +101 48 0 +101 -100 0 +-101 -48 100 0 +102 48 0 +102 -50 0 +-102 -48 50 0 +103 39 102 0 +-103 39 -102 0 +103 -39 -48 0 +-103 -39 48 0 +104 48 0 +104 -49 0 +-104 -48 49 0 +105 39 -101 0 +-105 39 101 0 +105 -39 -104 0 +-105 -39 104 0 +106 38 105 0 +-106 38 -105 0 +106 -38 -103 0 +-106 -38 103 0 +107 -37 0 +107 106 0 +-107 37 -106 0 +108 38 104 0 +-108 38 -104 0 +108 -38 -48 0 +-108 -38 48 0 +109 -37 0 +109 108 0 +-109 37 -108 0 +110 24 -109 0 +-110 24 109 0 +110 -24 -107 0 +-110 -24 107 0 +111 -37 0 +111 103 0 +-111 37 -103 0 +112 -37 0 +112 48 0 +-112 37 -48 0 +113 24 -112 0 +-113 24 112 0 +113 -24 -111 0 +-113 -24 111 0 +114 23 -113 0 +-114 23 113 0 +114 -23 -110 0 +-114 -23 110 0 +115 22 0 +115 -114 0 +-115 -22 114 0 +116 23 -112 0 +-116 23 112 0 +116 -23 -109 0 +-116 -23 109 0 +117 22 0 +117 -116 0 +-117 -22 116 0 +118 12 -117 0 +-118 12 117 0 +118 -12 -115 0 +-118 -12 115 0 +119 10 0 +119 -118 0 +-119 -10 118 0 +120 22 0 +120 -113 0 +-120 -22 113 0 +121 12 -120 0 +-121 12 120 0 +121 -12 -115 0 +-121 -12 115 0 +122 10 0 +122 -121 0 +-122 -10 121 0 +123 9 -122 0 +-123 9 122 0 +123 -9 -119 0 +-123 -9 119 0 +124 12 0 +124 -115 0 +-124 -12 115 0 +125 10 0 +125 -124 0 +-125 -10 124 0 +126 10 0 +126 -115 0 +-126 -10 115 0 +127 9 -126 0 +-127 9 126 0 +127 -9 -125 0 +-127 -9 125 0 +128 8 -127 0 +-128 8 127 0 +128 -8 -123 0 +-128 -8 123 0 +129 3 -128 0 +-129 3 128 0 +129 -3 -101 0 +-129 -3 101 0 +130 -2 0 +130 -129 0 +-130 2 129 0 +-130 0 +c # End of Cnf From dddmp-2.0 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.cnf.bis b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.cnf.bis new file mode 100644 index 000000000..d4faf78e8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.cnf.bis @@ -0,0 +1,130 @@ +c # BDD stored by the DDDMP tool in CNF format +c # +c # Warning: AUX IDs missing ... equal to BDD IDs. +c # +c .ver DDDMP-2.0 +c .nnodes 35 +c .nvars 150 +c .nsuppvars 15 +c .suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +c .orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +c .ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .cnfids 2 3 8 9 10 12 22 23 24 37 38 39 48 49 50 +c .nroots 1 +c .rootids 1 +c .nAddedCnfVar 31 +c # +c # Init CNF Clauses +c # +p cnf 130 108 +100 -49 0 +100 -50 0 +-100 49 50 0 +101 48 0 +101 -100 0 +-101 -48 100 0 +102 48 0 +102 -50 0 +-102 -48 50 0 +103 39 102 0 +-103 39 -102 0 +103 -39 -48 0 +-103 -39 48 0 +104 48 0 +104 -49 0 +-104 -48 49 0 +105 39 -101 0 +-105 39 101 0 +105 -39 -104 0 +-105 -39 104 0 +106 38 105 0 +-106 38 -105 0 +106 -38 -103 0 +-106 -38 103 0 +107 -37 0 +107 106 0 +-107 37 -106 0 +108 38 104 0 +-108 38 -104 0 +108 -38 -48 0 +-108 -38 48 0 +109 -37 0 +109 108 0 +-109 37 -108 0 +110 24 -109 0 +-110 24 109 0 +110 -24 -107 0 +-110 -24 107 0 +111 -37 0 +111 103 0 +-111 37 -103 0 +112 -37 0 +112 48 0 +-112 37 -48 0 +113 24 -112 0 +-113 24 112 0 +113 -24 -111 0 +-113 -24 111 0 +114 23 -113 0 +-114 23 113 0 +114 -23 -110 0 +-114 -23 110 0 +115 22 0 +115 -114 0 +-115 -22 114 0 +116 23 -112 0 +-116 23 112 0 +116 -23 -109 0 +-116 -23 109 0 +117 22 0 +117 -116 0 +-117 -22 116 0 +118 12 -117 0 +-118 12 117 0 +118 -12 -115 0 +-118 -12 115 0 +119 10 0 +119 -118 0 +-119 -10 118 0 +120 22 0 +120 -113 0 +-120 -22 113 0 +121 12 -120 0 +-121 12 120 0 +121 -12 -115 0 +-121 -12 115 0 +122 10 0 +122 -121 0 +-122 -10 121 0 +123 9 -122 0 +-123 9 122 0 +123 -9 -119 0 +-123 -9 119 0 +124 12 0 +124 -115 0 +-124 -12 115 0 +125 10 0 +125 -124 0 +-125 -10 124 0 +126 10 0 +126 -115 0 +-126 -10 115 0 +127 9 -126 0 +-127 9 126 0 +127 -9 -125 0 +-127 -9 125 0 +128 8 -127 0 +-128 8 127 0 +128 -8 -123 0 +-128 -8 123 0 +129 3 -128 0 +-129 3 128 0 +129 -3 -101 0 +-129 -3 101 0 +130 -2 0 +130 -129 0 +-130 2 129 0 +-130 0 +c # End of Cnf From dddmp-2.0 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.max1 b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.max1 new file mode 100644 index 000000000..d9a498414 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.max1 @@ -0,0 +1,125 @@ +c # BDD stored by the DDDMP tool in CNF format +c # +c # Warning: AUX IDs missing ... equal to BDD IDs. +c # +c .ver DDDMP-2.0 +c .nnodes 35 +c .nvars 150 +c .nsuppvars 15 +c .suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +c .orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +c .ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .cnfids 2 3 8 9 10 12 22 23 24 37 38 39 48 49 50 +c .nroots 1 +c .rootids 1 +c .nAddedCnfVar 0 +c # +c # Init CNF Clauses +c # +p cnf 50 103 +3 8 9 10 0 +3 8 9 22 0 +3 8 9 23 24 48 0 +3 8 9 23 24 -37 0 +3 8 9 23 -24 39 48 0 +3 8 9 23 -24 39 -50 0 +3 8 9 23 -24 -39 48 0 +3 8 9 23 -24 -37 0 +3 8 9 -23 24 38 48 0 +3 8 9 -23 24 38 -49 0 +3 8 9 -23 24 -38 48 0 +3 8 9 -23 24 -37 0 +3 8 9 -23 -24 38 39 48 0 +3 8 9 -23 -24 38 39 -50 0 +3 8 9 -23 -24 38 39 -49 0 +3 8 9 -23 -24 38 -39 48 0 +3 8 9 -23 -24 38 -39 -49 0 +3 8 9 -23 -24 -38 39 48 0 +3 8 9 -23 -24 -38 39 -50 0 +3 8 9 -23 -24 -38 -39 48 0 +3 8 9 -23 -24 -37 0 +3 8 -9 10 0 +3 8 -9 12 0 +3 8 -9 22 0 +3 8 -9 23 24 48 0 +3 8 -9 23 24 -37 0 +3 8 -9 23 -24 39 48 0 +3 8 -9 23 -24 39 -50 0 +3 8 -9 23 -24 -39 48 0 +3 8 -9 23 -24 -37 0 +3 8 -9 -23 24 38 48 0 +3 8 -9 -23 24 38 -49 0 +3 8 -9 -23 24 -38 48 0 +3 8 -9 -23 24 -37 0 +3 8 -9 -23 -24 38 39 48 0 +3 8 -9 -23 -24 38 39 -50 0 +3 8 -9 -23 -24 38 39 -49 0 +3 8 -9 -23 -24 38 -39 48 0 +3 8 -9 -23 -24 38 -39 -49 0 +3 8 -9 -23 -24 -38 39 48 0 +3 8 -9 -23 -24 -38 39 -50 0 +3 8 -9 -23 -24 -38 -39 48 0 +3 8 -9 -23 -24 -37 0 +3 -8 9 10 0 +3 -8 9 12 22 0 +3 -8 9 12 24 48 0 +3 -8 9 12 24 -37 0 +3 -8 9 12 -24 39 48 0 +3 -8 9 12 -24 39 -50 0 +3 -8 9 12 -24 -39 48 0 +3 -8 9 12 -24 -37 0 +3 -8 9 -12 22 0 +3 -8 9 -12 23 24 48 0 +3 -8 9 -12 23 24 -37 0 +3 -8 9 -12 23 -24 39 48 0 +3 -8 9 -12 23 -24 39 -50 0 +3 -8 9 -12 23 -24 -39 48 0 +3 -8 9 -12 23 -24 -37 0 +3 -8 9 -12 -23 24 38 48 0 +3 -8 9 -12 -23 24 38 -49 0 +3 -8 9 -12 -23 24 -38 48 0 +3 -8 9 -12 -23 24 -37 0 +3 -8 9 -12 -23 -24 38 39 48 0 +3 -8 9 -12 -23 -24 38 39 -50 0 +3 -8 9 -12 -23 -24 38 39 -49 0 +3 -8 9 -12 -23 -24 38 -39 48 0 +3 -8 9 -12 -23 -24 38 -39 -49 0 +3 -8 9 -12 -23 -24 -38 39 48 0 +3 -8 9 -12 -23 -24 -38 39 -50 0 +3 -8 9 -12 -23 -24 -38 -39 48 0 +3 -8 9 -12 -23 -24 -37 0 +3 -8 -9 10 0 +3 -8 -9 12 22 0 +3 -8 -9 12 23 48 0 +3 -8 -9 12 23 -37 0 +3 -8 -9 12 -23 38 48 0 +3 -8 -9 12 -23 38 -49 0 +3 -8 -9 12 -23 -38 48 0 +3 -8 -9 12 -23 -37 0 +3 -8 -9 -12 22 0 +3 -8 -9 -12 23 24 48 0 +3 -8 -9 -12 23 24 -37 0 +3 -8 -9 -12 23 -24 39 48 0 +3 -8 -9 -12 23 -24 39 -50 0 +3 -8 -9 -12 23 -24 -39 48 0 +3 -8 -9 -12 23 -24 -37 0 +3 -8 -9 -12 -23 24 38 48 0 +3 -8 -9 -12 -23 24 38 -49 0 +3 -8 -9 -12 -23 24 -38 48 0 +3 -8 -9 -12 -23 24 -37 0 +3 -8 -9 -12 -23 -24 38 39 48 0 +3 -8 -9 -12 -23 -24 38 39 -50 0 +3 -8 -9 -12 -23 -24 38 39 -49 0 +3 -8 -9 -12 -23 -24 38 -39 48 0 +3 -8 -9 -12 -23 -24 38 -39 -49 0 +3 -8 -9 -12 -23 -24 -38 39 48 0 +3 -8 -9 -12 -23 -24 -38 39 -50 0 +3 -8 -9 -12 -23 -24 -38 -39 48 0 +3 -8 -9 -12 -23 -24 -37 0 +-3 48 0 +-3 -50 0 +-3 -49 0 +-2 0 +c # End of Cnf From dddmp-2.0 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.max2 b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.max2 new file mode 100644 index 000000000..d9a498414 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4.max2 @@ -0,0 +1,125 @@ +c # BDD stored by the DDDMP tool in CNF format +c # +c # Warning: AUX IDs missing ... equal to BDD IDs. +c # +c .ver DDDMP-2.0 +c .nnodes 35 +c .nvars 150 +c .nsuppvars 15 +c .suppvarnames V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +c .orderedvarnames V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +c .ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .auxids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +c .cnfids 2 3 8 9 10 12 22 23 24 37 38 39 48 49 50 +c .nroots 1 +c .rootids 1 +c .nAddedCnfVar 0 +c # +c # Init CNF Clauses +c # +p cnf 50 103 +3 8 9 10 0 +3 8 9 22 0 +3 8 9 23 24 48 0 +3 8 9 23 24 -37 0 +3 8 9 23 -24 39 48 0 +3 8 9 23 -24 39 -50 0 +3 8 9 23 -24 -39 48 0 +3 8 9 23 -24 -37 0 +3 8 9 -23 24 38 48 0 +3 8 9 -23 24 38 -49 0 +3 8 9 -23 24 -38 48 0 +3 8 9 -23 24 -37 0 +3 8 9 -23 -24 38 39 48 0 +3 8 9 -23 -24 38 39 -50 0 +3 8 9 -23 -24 38 39 -49 0 +3 8 9 -23 -24 38 -39 48 0 +3 8 9 -23 -24 38 -39 -49 0 +3 8 9 -23 -24 -38 39 48 0 +3 8 9 -23 -24 -38 39 -50 0 +3 8 9 -23 -24 -38 -39 48 0 +3 8 9 -23 -24 -37 0 +3 8 -9 10 0 +3 8 -9 12 0 +3 8 -9 22 0 +3 8 -9 23 24 48 0 +3 8 -9 23 24 -37 0 +3 8 -9 23 -24 39 48 0 +3 8 -9 23 -24 39 -50 0 +3 8 -9 23 -24 -39 48 0 +3 8 -9 23 -24 -37 0 +3 8 -9 -23 24 38 48 0 +3 8 -9 -23 24 38 -49 0 +3 8 -9 -23 24 -38 48 0 +3 8 -9 -23 24 -37 0 +3 8 -9 -23 -24 38 39 48 0 +3 8 -9 -23 -24 38 39 -50 0 +3 8 -9 -23 -24 38 39 -49 0 +3 8 -9 -23 -24 38 -39 48 0 +3 8 -9 -23 -24 38 -39 -49 0 +3 8 -9 -23 -24 -38 39 48 0 +3 8 -9 -23 -24 -38 39 -50 0 +3 8 -9 -23 -24 -38 -39 48 0 +3 8 -9 -23 -24 -37 0 +3 -8 9 10 0 +3 -8 9 12 22 0 +3 -8 9 12 24 48 0 +3 -8 9 12 24 -37 0 +3 -8 9 12 -24 39 48 0 +3 -8 9 12 -24 39 -50 0 +3 -8 9 12 -24 -39 48 0 +3 -8 9 12 -24 -37 0 +3 -8 9 -12 22 0 +3 -8 9 -12 23 24 48 0 +3 -8 9 -12 23 24 -37 0 +3 -8 9 -12 23 -24 39 48 0 +3 -8 9 -12 23 -24 39 -50 0 +3 -8 9 -12 23 -24 -39 48 0 +3 -8 9 -12 23 -24 -37 0 +3 -8 9 -12 -23 24 38 48 0 +3 -8 9 -12 -23 24 38 -49 0 +3 -8 9 -12 -23 24 -38 48 0 +3 -8 9 -12 -23 24 -37 0 +3 -8 9 -12 -23 -24 38 39 48 0 +3 -8 9 -12 -23 -24 38 39 -50 0 +3 -8 9 -12 -23 -24 38 39 -49 0 +3 -8 9 -12 -23 -24 38 -39 48 0 +3 -8 9 -12 -23 -24 38 -39 -49 0 +3 -8 9 -12 -23 -24 -38 39 48 0 +3 -8 9 -12 -23 -24 -38 39 -50 0 +3 -8 9 -12 -23 -24 -38 -39 48 0 +3 -8 9 -12 -23 -24 -37 0 +3 -8 -9 10 0 +3 -8 -9 12 22 0 +3 -8 -9 12 23 48 0 +3 -8 -9 12 23 -37 0 +3 -8 -9 12 -23 38 48 0 +3 -8 -9 12 -23 38 -49 0 +3 -8 -9 12 -23 -38 48 0 +3 -8 -9 12 -23 -37 0 +3 -8 -9 -12 22 0 +3 -8 -9 -12 23 24 48 0 +3 -8 -9 -12 23 24 -37 0 +3 -8 -9 -12 23 -24 39 48 0 +3 -8 -9 -12 23 -24 39 -50 0 +3 -8 -9 -12 23 -24 -39 48 0 +3 -8 -9 -12 23 -24 -37 0 +3 -8 -9 -12 -23 24 38 48 0 +3 -8 -9 -12 -23 24 38 -49 0 +3 -8 -9 -12 -23 24 -38 48 0 +3 -8 -9 -12 -23 24 -37 0 +3 -8 -9 -12 -23 -24 38 39 48 0 +3 -8 -9 -12 -23 -24 38 39 -50 0 +3 -8 -9 -12 -23 -24 38 39 -49 0 +3 -8 -9 -12 -23 -24 38 -39 48 0 +3 -8 -9 -12 -23 -24 38 -39 -49 0 +3 -8 -9 -12 -23 -24 -38 39 48 0 +3 -8 -9 -12 -23 -24 -38 39 -50 0 +3 -8 -9 -12 -23 -24 -38 -39 48 0 +3 -8 -9 -12 -23 -24 -37 0 +-3 48 0 +-3 -50 0 +-3 -49 0 +-2 0 +c # End of Cnf From dddmp-2.0 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4bis.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4bis.bdd new file mode 100644 index 000000000..fc242f3c1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4bis.bdd @@ -0,0 +1,47 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 3 +.nnodes 35 +.nvars 50 +.nsuppvars 15 +.ids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +.nroots 1 +.rootids -35 +.nodes +1 1 0 0 +2 14 1 -1 +3 13 1 2 +4 12 3 1 +5 12 1 -1 +6 12 2 1 +7 11 5 -6 +8 13 1 -1 +9 12 8 1 +10 11 9 4 +11 10 7 -10 +12 9 1 -11 +13 10 5 -9 +14 9 1 -13 +15 8 12 14 +16 9 1 -7 +17 9 1 -5 +18 8 16 17 +19 7 15 18 +20 6 19 1 +21 7 14 17 +22 6 21 1 +23 5 20 22 +24 4 23 1 +25 6 18 1 +26 5 20 25 +27 4 26 1 +28 3 24 27 +29 5 20 1 +30 4 29 1 +31 4 20 1 +32 3 30 31 +33 2 28 32 +34 1 4 33 +35 0 1 34 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4xor5.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4xor5.bdd new file mode 100644 index 000000000..9967a6767 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/4xor5.bdd @@ -0,0 +1,120 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 105 +.nvars 50 +.nsuppvars 18 +.suppvarnames DUMMY1 DUMMY2 DUMMY7 DUMMY8 DUMMY9 DUMMY11 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +.orderedvarnames DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 DUMMY5 DUMMY6 DUMMY7 DUMMY8 DUMMY9 DUMMY10 DUMMY11 DUMMY12 DUMMY13 DUMMY14 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 +.ids 1 2 7 8 9 11 19 20 21 22 23 24 36 37 38 47 48 49 +.permids 1 2 7 8 9 11 19 20 21 22 23 24 36 37 38 47 48 49 +.auxids 1 2 7 8 9 11 19 20 21 22 23 24 36 37 38 47 48 49 +.nroots 1 +.rootids 105 +.nodes +1 T 1 0 0 +2 24 11 1 -1 +3 23 10 1 -2 +4 22 9 3 -2 +5 21 8 4 -2 +6 23 10 1 -1 +7 22 9 6 -1 +8 21 8 7 -1 +9 20 7 5 8 +10 23 10 2 -1 +11 22 9 2 10 +12 21 8 11 2 +13 23 10 2 -2 +14 22 9 3 -13 +15 21 8 4 14 +16 20 7 12 15 +17 19 6 9 -16 +18 49 17 1 -1 +19 48 16 1 18 +20 47 15 19 1 +21 24 11 20 -20 +22 23 10 20 -21 +23 22 9 22 -21 +24 21 8 23 -21 +25 23 10 20 -20 +26 22 9 25 -20 +27 21 8 26 -20 +28 20 7 24 27 +29 23 10 21 -20 +30 22 9 21 29 +31 21 8 30 21 +32 23 10 21 -21 +33 22 9 22 -32 +34 21 8 23 33 +35 20 7 31 34 +36 19 6 28 -35 +37 47 15 1 -1 +38 47 15 18 1 +39 38 14 37 -38 +40 48 16 1 -1 +41 47 15 40 1 +42 38 14 41 20 +43 37 13 39 -42 +44 36 12 1 -43 +45 37 13 37 -41 +46 36 12 1 -45 +47 24 11 46 -46 +48 23 10 44 -47 +49 36 12 1 -39 +50 24 11 49 -49 +51 36 12 1 -37 +52 24 11 51 -51 +53 23 10 50 52 +54 22 9 48 -53 +55 21 8 54 -2 +56 23 10 44 -46 +57 23 10 49 51 +58 22 9 56 -57 +59 21 8 58 -1 +60 20 7 55 59 +61 24 11 44 -44 +62 23 10 61 47 +63 23 10 50 -51 +64 22 9 62 63 +65 21 8 64 2 +66 21 8 54 14 +67 20 7 65 66 +68 19 6 60 -67 +69 23 10 46 -47 +70 22 9 69 -52 +71 21 8 70 -2 +72 23 10 46 -46 +73 22 9 72 -51 +74 21 8 73 -1 +75 20 7 71 74 +76 23 10 52 -51 +77 22 9 47 76 +78 21 8 77 2 +79 21 8 70 14 +80 20 7 78 79 +81 19 6 75 -80 +82 11 5 68 81 +83 9 4 82 17 +84 23 10 49 -52 +85 22 9 84 -53 +86 21 8 85 -2 +87 23 10 49 -51 +88 22 9 87 -57 +89 21 8 88 -1 +90 20 7 86 89 +91 22 9 53 63 +92 21 8 91 2 +93 21 8 85 14 +94 20 7 92 93 +95 19 6 90 -94 +96 11 5 68 95 +97 9 4 96 17 +98 8 3 83 97 +99 11 5 68 17 +100 9 4 99 17 +101 9 4 68 17 +102 8 3 100 101 +103 7 2 98 102 +104 2 1 36 103 +105 1 0 17 104 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/5.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/5.bdd new file mode 100644 index 000000000..198f6bfa7 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/5.bdd @@ -0,0 +1,31 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 17 +.nvars 50 +.nsuppvars 6 +.suppvarnames DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 +.ids 19 20 21 22 23 24 +.permids 19 20 21 22 23 24 +.auxids 19 20 21 22 23 24 +.nroots 1 +.rootids 17 +.nodes +1 T 1 0 0 +2 24 5 1 -1 +3 23 4 1 -2 +4 22 3 3 -2 +5 21 2 4 -2 +6 23 4 1 -1 +7 22 3 6 -1 +8 21 2 7 -1 +9 20 1 5 8 +10 23 4 2 -1 +11 22 3 2 10 +12 21 2 11 2 +13 23 4 2 -2 +14 22 3 3 -13 +15 21 2 4 14 +16 20 1 12 15 +17 19 0 9 -16 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/composeids.txt b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/composeids.txt new file mode 100644 index 000000000..d79ce9c60 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/composeids.txt @@ -0,0 +1,20 @@ +0 +2 +4 +6 +8 +10 +12 +14 +16 +18 +20 +22 +24 +26 +28 +30 +32 +34 +36 +38 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/one.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/one.bdd new file mode 100644 index 000000000..836566fbe --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/one.bdd @@ -0,0 +1,13 @@ +.ver DDDMP-1.0 +.mode A +.varinfo 0 +.nnodes 1 +.nvars 100 +.nsuppvars 0 +.ids +.permids +.nroots 1 +.rootids 1 +.nodes +1 T 1 0 0 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/runAllTest.out b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/runAllTest.out new file mode 100644 index 000000000..321532e3c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/runAllTest.out @@ -0,0 +1,269 @@ +--------------------------------------------------------------------------- +--------------------- TESTING Load and Write Header ----------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> DD TYPE: DDDMP_BDD +Number of variables: 50 +Number of support variables: 15 +suppVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +orderedVarNames: V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varAuxIds: 3 5 15 17 19 23 43 45 47 73 75 77 95 97 99 +varAuxIds for ALL Manager Variables: -1 3 5 -1 -1 -1 -1 15 17 19 -1 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 43 45 47 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 73 75 77 -1 -1 -1 -1 -1 -1 -1 -1 95 97 99 +Number of roots: 1 +TestDddmp> File : TestDddmp> DD TYPE: DDDMP_ADD +Number of variables: 3 +Number of support variables: 2 +suppVarNames: DUMMY1 DUMMY2 +orderedVarNames: DUMMY0 DUMMY1 DUMMY2 +varIds: 1 2 +varIds for ALL Manager Variables: -1 1 2 +varComposeIds: 1 2 +varComposeIds for ALL Manager Variables: -1 1 2 +varAuxIds: 1 2 +varAuxIds for ALL Manager Variables: -1 1 2 +Number of roots: 1 +TestDddmp> File : TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 50 +Number of support variables: 15 +suppVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +orderedVarNames: V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +Number of roots: 1 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +-------------------- TESTING Load BDD from DDDMP-1.0 ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> DD TYPE: DDDMP_BDD +Number of variables: 10 +Number of support variables: 7 +suppVarNames: G0 G1 G2 G3 G5 G6 G7 +orderedVarNames: G0 G1 G2 G3 G5 G6 G7 DUMMY7 DUMMY8 DUMMY9 +varIds: 0 1 2 3 4 5 6 +varIds for ALL Manager Variables: 0 1 2 3 4 5 6 -1 -1 -1 +varComposeIds: 0 1 2 3 4 6 8 +varComposeIds for ALL Manager Variables: 0 1 2 3 4 6 8 -1 -1 -1 +varAuxIds: 0 1 2 3 4 5 6 +varAuxIds for ALL Manager Variables: 0 1 2 3 4 5 6 -1 -1 -1 +Number of roots: 3 +TestDddmp> File : Which Array of BDDs [0..19]: TestDddmp> File : Which Array of BDDs [0..19]: Storing Array of BDDs in file s27deltaDddmp1.bdd.tmp ... +done. +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +----------------------- TESTING basic Load/Store ... ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 0.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 1.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 0or1.bdd.tmp ... +TestDddmp> File : Which BDDs [0..19]: Loading 2.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 3.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 2and3.bdd.tmp ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 5.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 4xor5.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +---------- TESTING Load/Store with sifting, varnames & varauxids ---------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Storing 4a.bdd.tmp ... +TestDddmp> Reordering Approach (1..17): TestDddmp> File : Which BDDs [0..19]: Storing 4b.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +------------------------- ... END PHASE 1 ... ----------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> Variable matchmode: +Match IDs (1) +Match permIDs (2) +Match names (must have been loaded) (3) +Match auxids (must have been loaded) (4) +Match composeids (must have been loaded) (5) +Your choice: TestDddmp> File : Which BDDs [0..19]: Loading 4b.bdd.tmp ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Storing 4c.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load ADD and Store ADD ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 0.add ... +Load: +-01 2 +-1- 1 +TestDddmp> File : Which BDDs [0..19]: Storing 0.add.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 1.add ... +Load: +-0001--------------------------------------------- 1 +-0010--------------------------------------------- 2 +-0100--------------------------------------------- 1 +-0101--------------------------------------------- 2 +-0111--------------------------------------------- 1 +-1000--------------------------------------------- 2 +-1010--------------------------------------------- 1 +-1011--------------------------------------------- 2 +-1101--------------------------------------------- 1 +-1110--------------------------------------------- 2 +TestDddmp> File : Which BDDs [0..19]: Storing 1.add.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load BDD and Store CNF ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.cnf.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +--------------------- TESTING Load CNF and Store BDD ---------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.cnf.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load BDD and Store CNF ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.node1.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.max1.tmp ... +Number of Clauses Stored = 103 +Number of New Variable Created Storing = 0 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.node2.tmp ... +Number of Clauses Stored = 114 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.node3.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.max2.tmp ... +Number of Clauses Stored = 103 +Number of New Variable Created Storing = 0 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.best1.tmp ... +Number of Clauses Stored = 53 +Number of New Variable Created Storing = 7 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.best2.tmp ... +Number of Clauses Stored = 69 +Number of New Variable Created Storing = 12 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +--------------------------------------------------------------------------- +--------------------- TESTING Load CNF and Store BDD ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.node2.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.node2.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.node3.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.node3.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.best1.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.best1.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.best2.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.best2.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/runAllTest.script b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/runAllTest.script new file mode 100644 index 000000000..8d792ef42 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/runAllTest.script @@ -0,0 +1,11 @@ +# !/bin/sh +# +# Run All Test Files +# +./test1.script +./test2.script +./test3.script +./test4.script +./test5.script +./test6.script +./test7.script diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27RP1.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27RP1.bdd new file mode 100644 index 000000000..56532603a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27RP1.bdd @@ -0,0 +1,18 @@ +# MONO +.ver DDDMP-1.0 +.mode A +.varinfo 3 +.nnodes 3 +.nvars 10 +.nsuppvars 2 +.varnames G5 G6 +.ids 4 5 +.permids 4 6 +.auxids 4 5 +.nroots 1 +.rootids -3 +.nodes +1 T 1 0 0 +2 5 1 1 -1 +3 4 0 2 -1 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27deltaDddmp1.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27deltaDddmp1.bdd new file mode 100644 index 000000000..11a595687 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27deltaDddmp1.bdd @@ -0,0 +1,31 @@ +.ver DDDMP-1.0 +.mode A +.varinfo 0 +.dd s27adelta.bdd +.nnodes 16 +.nvars 10 +.nsuppvars 7 +.varnames G0 G1 G2 G3 G5 G6 G7 +.ids 0 1 2 3 4 5 6 +.permids 0 1 2 3 4 6 8 +.auxids 0 1 2 3 4 5 6 +.nroots 3 +.rootids 6 -13 -16 +.nodes +1 T 1 0 0 +2 6 6 1 -1 +3 4 4 1 2 +4 3 3 3 1 +5 1 1 1 4 +6 0 0 5 -1 +7 5 5 1 -1 +8 4 4 1 -7 +9 5 5 1 -2 +10 4 4 1 -9 +11 3 3 10 8 +12 1 1 8 11 +13 0 0 5 12 +14 2 2 1 -1 +15 2 2 1 -2 +16 1 1 14 15 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27deltaDddmp1.bdd.bis b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27deltaDddmp1.bdd.bis new file mode 100644 index 000000000..b7fb86bfe --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27deltaDddmp1.bdd.bis @@ -0,0 +1,31 @@ +.ver DDDMP-2.0 +.mode A +.varinfo 0 +.nnodes 16 +.nvars 10 +.nsuppvars 7 +.suppvarnames G0 G1 G2 G3 G5 G6 G7 +.orderedvarnames G0 G1 G2 G3 G5 G6 G7 DUMMY7 DUMMY8 DUMMY9 +.ids 0 1 2 3 4 5 6 +.permids 0 1 2 3 4 5 6 +.auxids 0 1 2 3 4 5 6 +.nroots 3 +.rootids 6 -13 -16 +.nodes +1 T 1 0 0 +2 6 6 1 -1 +3 4 4 1 2 +4 3 3 3 1 +5 1 1 1 4 +6 0 0 5 -1 +7 5 5 1 -1 +8 4 4 1 -7 +9 5 5 1 -2 +10 4 4 1 -9 +11 3 3 10 8 +12 1 1 8 11 +13 0 0 5 12 +14 2 2 1 -1 +15 2 2 1 -2 +16 1 1 14 15 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27deltaDddmp2.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27deltaDddmp2.bdd new file mode 100644 index 000000000..d247bd1fd --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/s27deltaDddmp2.bdd @@ -0,0 +1,32 @@ +.ver DDDMP-1.0 +.mode A +.varinfo 0 +.dd s27adelta.bdd +.nnodes 16 +.nvars 10 +.nsuppvars 7 +.orderedvarnames G0 G1 G2 G3 G5 G6 G7 TMP1 TMP2 TMP3 +.suppvarnames G0 G1 G2 G3 G5 G6 G7 +.ids 0 1 2 3 4 5 6 +.permids 0 1 2 3 4 6 8 +.auxids 0 1 2 3 4 5 6 +.nroots 3 +.rootids 6 -13 -16 +.nodes +1 T 1 0 0 +2 6 6 1 -1 +3 4 4 1 2 +4 3 3 3 1 +5 1 1 1 4 +6 0 0 5 -1 +7 5 5 1 -1 +8 4 4 1 -7 +9 5 5 1 -2 +10 4 4 1 -9 +11 3 3 10 8 +12 1 1 8 11 +13 0 0 5 12 +14 2 2 1 -1 +15 2 2 1 -2 +16 1 1 14 15 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test1.out b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test1.out new file mode 100644 index 000000000..96b2a3ac3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test1.out @@ -0,0 +1,44 @@ +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load and Write Header ----------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> DD TYPE: DDDMP_BDD +Number of variables: 50 +Number of support variables: 15 +suppVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +orderedVarNames: V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varAuxIds: 3 5 15 17 19 23 43 45 47 73 75 77 95 97 99 +varAuxIds for ALL Manager Variables: -1 3 5 -1 -1 -1 -1 15 17 19 -1 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 43 45 47 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 73 75 77 -1 -1 -1 -1 -1 -1 -1 -1 95 97 99 +Number of roots: 1 +TestDddmp> File : TestDddmp> DD TYPE: DDDMP_ADD +Number of variables: 3 +Number of support variables: 2 +suppVarNames: DUMMY1 DUMMY2 +orderedVarNames: DUMMY0 DUMMY1 DUMMY2 +varIds: 1 2 +varIds for ALL Manager Variables: -1 1 2 +varComposeIds: 1 2 +varComposeIds for ALL Manager Variables: -1 1 2 +varAuxIds: 1 2 +varAuxIds for ALL Manager Variables: -1 1 2 +Number of roots: 1 +TestDddmp> File : TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 50 +Number of support variables: 15 +suppVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 +orderedVarNames: V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 +Number of roots: 1 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test1.script b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test1.script new file mode 100644 index 000000000..843e3650c --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test1.script @@ -0,0 +1,26 @@ +# !/bin/sh +# +# Check Header Load/Store for BDD/ADD/CNFs: +# Load Header +# Write Information on Standard Output +# +rm -f *.*.tmp +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load and Write Header -----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END +mi +50 +hlb +4.bdd +hw +hlb +0.add +hw +hlc +4.cnf +hw +mq +quit +END +echo "-------------------------------- ... END ----------------------------------" diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test2.out b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test2.out new file mode 100644 index 000000000..22d6e39d1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test2.out @@ -0,0 +1,23 @@ +rm: No match. +--------------------------------------------------------------------------- +-------------------- TESTING Load BDD from DDDMP-1.0 ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> DD TYPE: DDDMP_BDD +Number of variables: 10 +Number of support variables: 7 +suppVarNames: G0 G1 G2 G3 G5 G6 G7 +orderedVarNames: G0 G1 G2 G3 G5 G6 G7 DUMMY7 DUMMY8 DUMMY9 +varIds: 0 1 2 3 4 5 6 +varIds for ALL Manager Variables: 0 1 2 3 4 5 6 -1 -1 -1 +varComposeIds: 0 1 2 3 4 6 8 +varComposeIds for ALL Manager Variables: 0 1 2 3 4 6 8 -1 -1 -1 +varAuxIds: 0 1 2 3 4 5 6 +varAuxIds for ALL Manager Variables: 0 1 2 3 4 5 6 -1 -1 -1 +Number of roots: 3 +TestDddmp> File : Which Array of BDDs [0..19]: TestDddmp> File : Which Array of BDDs [0..19]: Storing Array of BDDs in file s27deltaDddmp1.bdd.tmp ... +done. +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test2.script b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test2.script new file mode 100644 index 000000000..f719ed2bb --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test2.script @@ -0,0 +1,30 @@ +# !/bin/sh +# +# Check BDDs from DDDMP-1.0: +# Load an Array of BDDs from DDDMP-1.0 +# Store them +# +rm -f *.*.tmp +echo "---------------------------------------------------------------------------" +echo "-------------------- TESTING Load BDD from DDDMP-1.0 ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END +mi +10 +hlb +s27deltaDddmp1.bdd +hw +bal +s27deltaDddmp1.bdd +0 +bas +s27deltaDddmp1.bdd.tmp +0 +mq +quit +END +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief s27deltaDddmp1.bdd.tmp s27deltaDddmp1.bdd.bis +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test3.out b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test3.out new file mode 100644 index 000000000..0c296c095 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test3.out @@ -0,0 +1,18 @@ +rm: No match. +--------------------------------------------------------------------------- +----------------------- TESTING basic Load/Store ... ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 0.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 1.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 0or1.bdd.tmp ... +TestDddmp> File : Which BDDs [0..19]: Loading 2.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 3.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 2and3.bdd.tmp ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Loading 5.bdd ... +TestDddmp> Operation [or,and,xor,!,buf(=)] : Source1 [0..19]: Source2 [0..19]: Destination [0..19]: TestDddmp> File : Which BDDs [0..19]: Storing 4xor5.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test3.script b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test3.script new file mode 100644 index 000000000..408496c2d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test3.script @@ -0,0 +1,69 @@ +# !/bin/sh +# +# BDD check: +# Load BDDs +# Make some operations +# Store BDDs +# +rm -f *.*.tmp +echo "---------------------------------------------------------------------------" +echo "----------------------- TESTING basic Load/Store ... ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END +mi +50 +hlb +0or1.bdd +bl +0.bdd +0 +bl +1.bdd +1 +op +or +0 +1 +2 +bs +0or1.bdd.tmp +2 +bl +2.bdd +2 +bl +3.bdd +3 +op +and +2 +3 +4 +bs +2and3.bdd.tmp +4 +hlb +4xor5.bdd +bl +4.bdd +4 +bl +5.bdd +5 +op +xor +4 +5 +6 +bs +4xor5.bdd.tmp +6 +mq +quit +END +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 0or1.bdd 0or1.bdd.tmp +diff --brief 2and3.bdd 2and3.bdd.tmp +diff --brief 4xor5.bdd 4xor5.bdd.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test4.out b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test4.out new file mode 100644 index 000000000..367602d90 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test4.out @@ -0,0 +1,24 @@ +rm: No match. +--------------------------------------------------------------------------- +---------- TESTING Load/Store with sifting, varnames & varauxids ---------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Storing 4a.bdd.tmp ... +TestDddmp> Reordering Approach (1..17): TestDddmp> File : Which BDDs [0..19]: Storing 4b.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +------------------------- ... END PHASE 1 ... ----------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> Variable matchmode: +Match IDs (1) +Match permIDs (2) +Match names (must have been loaded) (3) +Match auxids (must have been loaded) (4) +Match composeids (must have been loaded) (5) +Your choice: TestDddmp> File : Which BDDs [0..19]: Loading 4b.bdd.tmp ... +TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Storing 4c.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test4.script b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test4.script new file mode 100644 index 000000000..2c50992b1 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test4.script @@ -0,0 +1,56 @@ +# !/bin/sh +# +# BDD Check: +# Load BDDs +# Make some operations (with reordering) +# Store BDDs +# +rm -f *.*/tmp +echo "---------------------------------------------------------------------------" +echo "---------- TESTING Load/Store with sifting, varnames & varauxids ----------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END1 +mi +50 +onl +varnames.ord +bl +4.bdd +4 +oil +varauxids.ord +bs +4a.bdd.tmp +4 +dr +4 +bs +4b.bdd.tmp +4 +mq +quit +END1 +echo "------------------------- ... END PHASE 1 ... -----------------------------" +./../testdddmp << END2 +mi +50 +onl +varnames.ord +slm +3 +bl +4b.bdd.tmp +4 +oil +varauxids.ord +bs +4c.bdd.tmp +4 +mq +quit +END2 +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 4.bdd 4a.bdd.tmp +diff --brief 4a.bdd.tmp 4c.bdd.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test5.out b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test5.out new file mode 100644 index 000000000..a883f515f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test5.out @@ -0,0 +1,28 @@ +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load ADD and Store ADD ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 0.add ... +Load: +-01 2 +-1- 1 +TestDddmp> File : Which BDDs [0..19]: Storing 0.add.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 1.add ... +Load: +-0001--------------------------------------------- 1 +-0010--------------------------------------------- 2 +-0100--------------------------------------------- 1 +-0101--------------------------------------------- 2 +-0111--------------------------------------------- 1 +-1000--------------------------------------------- 2 +-1010--------------------------------------------- 1 +-1011--------------------------------------------- 2 +-1101--------------------------------------------- 1 +-1110--------------------------------------------- 2 +TestDddmp> File : Which BDDs [0..19]: Storing 1.add.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test5.script b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test5.script new file mode 100644 index 000000000..9676c944e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test5.script @@ -0,0 +1,42 @@ +# !/bin/sh +# +# Check ADD: +# Load an ADD +# Store the same ADD +# Compare the two +# (done twice on a small - 0.add - and a medium - 1.add - ADD). +# +rm -f *.tmp* +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load ADD and Store ADD ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END1 +mi +3 +hlb +0.add +al +0.add +0 +as +0.add.tmp +0 +mq +mi +50 +hlb +1.add +al +1.add +1 +as +1.add.tmp +1 +mq +quit +END1 +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 0.add 0.add.tmp +diff --brief 1.add 1.add.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test6.out b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test6.out new file mode 100644 index 000000000..f10b48490 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test6.out @@ -0,0 +1,31 @@ +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load BDD and Store CNF ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.cnf.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +--------------------- TESTING Load CNF and Store BDD ---------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.cnf.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test6.script b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test6.script new file mode 100644 index 000000000..0b4295e29 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test6.script @@ -0,0 +1,50 @@ +# !/bin/sh +# +# Check CNF (short check - only NodeByNode method involved): +# Load BDDs +# Store corresponding CNF +# Read CNF +# Store corresponding BDD +# Compare original and final BDDs +# +rm -f *.tmp* +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load BDD and Store CNF ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END1 +mi +150 +hlc +4.cnf.bis +bl +4.bdd +0 +cs +4.cnf.tmp +0 +N +100 +mq +quit +END1 +echo "--------------------- TESTING Load CNF and Store BDD ----------------------" +./../testdddmp << END2 +mi +150 +hlc +4.cnf.bis +cl +4.cnf.tmp +0 +hw +bs +4.bdd.tmp +0 +mq +quit +END2 +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 4.cnf.bis 4.cnf.tmp +diff --brief 4.bdd.bis1 4.bdd.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.*.tmp diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test7.out b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test7.out new file mode 100644 index 000000000..d5cd7d3e0 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test7.out @@ -0,0 +1,102 @@ +rm: No match. +--------------------------------------------------------------------------- +--------------------- TESTING Load BDD and Store CNF ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.bdd ... +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.node1.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Initial ID : Storing 4.max1.tmp ... +Number of Clauses Stored = 103 +Number of New Variable Created Storing = 0 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.node2.tmp ... +Number of Clauses Stored = 114 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.node3.tmp ... +Number of Clauses Stored = 108 +Number of New Variable Created Storing = 31 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.max2.tmp ... +Number of Clauses Stored = 103 +Number of New Variable Created Storing = 0 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.best1.tmp ... +Number of Clauses Stored = 53 +Number of New Variable Created Storing = 7 +TestDddmp> File : Which BDDs [0..19]: Format (Node=N, Maxterm=M, Best=B) : Max Number of Edges (Insert cut-point from there on) : Max BDD-Path Length (Insert cut-point from there on) : Initial ID : Storing 4.best2.tmp ... +Number of Clauses Stored = 69 +Number of New Variable Created Storing = 12 +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +--------------------------------------------------------------------------- +--------------------- TESTING Load CNF and Store BDD ---------------------- +--------------------------------------------------------------------------- +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.node2.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.node2.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.node3.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.node3.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.best1.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.best1.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +#./../testdddmp Version 2.0.2 (use command help) +TestDddmp> Number of Variables: TestDddmp> File : TestDddmp> File : Which BDDs [0..19]: Loading 4.best2.tmp ... +TestDddmp> DD TYPE: DDDMP_CNF +Number of variables: 150 +Number of support variables: 15 +suppVarNames: V3 V8 V23 V24 V37 V39 DUMMY21 DUMMY22 DUMMY23 DUMMY36 DUMMY37 DUMMY38 DUMMY47 DUMMY48 DUMMY49 +orderedVarNames: V2 V3 V8 V9 V10 V12 V22 V23 V24 V37 V38 V39 V48 V49 V50 DUMMY15 DUMMY16 DUMMY17 DUMMY18 DUMMY19 DUMMY20 DUMMY21 DUMMY22 DUMMY23 DUMMY24 DUMMY25 DUMMY26 DUMMY27 DUMMY28 DUMMY29 DUMMY30 DUMMY31 DUMMY32 DUMMY33 DUMMY34 DUMMY35 DUMMY36 DUMMY37 DUMMY38 DUMMY39 DUMMY40 DUMMY41 DUMMY42 DUMMY43 DUMMY44 DUMMY45 DUMMY46 DUMMY47 DUMMY48 DUMMY49 DUMMY50 DUMMY51 DUMMY52 DUMMY53 DUMMY54 DUMMY55 DUMMY56 DUMMY57 DUMMY58 DUMMY59 DUMMY60 DUMMY61 DUMMY62 DUMMY63 DUMMY64 DUMMY65 DUMMY66 DUMMY67 DUMMY68 DUMMY69 DUMMY70 DUMMY71 DUMMY72 DUMMY73 DUMMY74 DUMMY75 DUMMY76 DUMMY77 DUMMY78 DUMMY79 DUMMY80 DUMMY81 DUMMY82 DUMMY83 DUMMY84 DUMMY85 DUMMY86 DUMMY87 DUMMY88 DUMMY89 DUMMY90 DUMMY91 DUMMY92 DUMMY93 DUMMY94 DUMMY95 DUMMY96 DUMMY97 DUMMY98 DUMMY99 DUMMY100 DUMMY101 DUMMY102 DUMMY103 DUMMY104 DUMMY105 DUMMY106 DUMMY107 DUMMY108 DUMMY109 DUMMY110 DUMMY111 DUMMY112 DUMMY113 DUMMY114 DUMMY115 DUMMY116 DUMMY117 DUMMY118 DUMMY119 DUMMY120 DUMMY121 DUMMY122 DUMMY123 DUMMY124 DUMMY125 DUMMY126 DUMMY127 DUMMY128 DUMMY129 DUMMY130 DUMMY131 DUMMY132 DUMMY133 DUMMY134 DUMMY135 DUMMY136 DUMMY137 DUMMY138 DUMMY139 DUMMY140 DUMMY141 DUMMY142 DUMMY143 DUMMY144 DUMMY145 DUMMY146 DUMMY147 DUMMY148 DUMMY149 +varIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varComposeIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varComposeIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +varAuxIds: 1 2 7 8 9 11 21 22 23 36 37 38 47 48 49 +varAuxIds for ALL Manager Variables: -1 1 2 -1 -1 -1 -1 7 8 9 -1 11 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 22 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 36 37 38 -1 -1 -1 -1 -1 -1 -1 -1 47 48 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +Number of roots: 1 +TestDddmp> File : Which BDDs [0..19]: Storing 4.best2.bdd.tmp ... +TestDddmp> Quitting CUDD Manager. +TestDddmp> End of test. +----------------------------- ... RESULTS ... ----------------------------- +-------------------------------- ... END ---------------------------------- diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test7.script b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test7.script new file mode 100644 index 000000000..dcef83f49 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/test7.script @@ -0,0 +1,150 @@ +# !/bin/sh +# +# Check CNF (long check - all methods involved): +# Load BDDs +# Store corresponding CNF in different format: +# NodeByNode method -> file 4.node1.tmp +# MaxtermByMaxterm -> file 4.max1.tmp +# Best with different options: +# MaxEdge=-1 MaxPath= 0 -> similar to NodeByNode -> file 4.node2.tmp +# MaxEdge= 0 MaxPath=-1 -> similar to NodeByNode -> file 4.node3.tmp +# MaxEdge=-1 MaxPath=-1 -> = MaxtermByMaxterm -> file 4.max2.tmp +# MaxEdge= 1 MaxPath=-1 -> = Original Best -> file 4.best1.tmp +# MaxEdge= 1 MaxPath= 2 -> = Original Best, With Path Shorter than 3 +# file 4.best2.tmp +# Read CNF +# Store corresponding BDD +# Compare original and final BDDs +# +rm -f *.tmp* +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load BDD and Store CNF ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END1 +mi +150 +hlc +4.cnf.bis +bl +4.bdd +0 +cs +4.node1.tmp +0 +N +100 +cs +4.max1.tmp +0 +M +100 +cs +4.node2.tmp +0 +B +-1 +0 +100 +cs +4.node3.tmp +0 +B +0 +-1 +100 +cs +4.max2.tmp +0 +B +-1 +-1 +100 +cs +4.best1.tmp +0 +B +1 +-1 +100 +cs +4.best2.tmp +0 +B +1 +2 +100 +mq +quit +END1 +echo "---------------------------------------------------------------------------" +echo "--------------------- TESTING Load CNF and Store BDD ----------------------" +echo "---------------------------------------------------------------------------" +./../testdddmp << END2 +mi +150 +hlc +4.node2.tmp +cl +4.node2.tmp +0 +hw +bs +4.node2.bdd.tmp +0 +mq +quit +END2 +./../testdddmp << END3 +mi +150 +hlc +4.node3.tmp +cl +4.node3.tmp +0 +hw +bs +4.node3.bdd.tmp +0 +mq +quit +END3 +./../testdddmp << END4 +mi +150 +hlc +4.best1.tmp +cl +4.best1.tmp +0 +hw +bs +4.best1.bdd.tmp +0 +mq +quit +END4 +./../testdddmp << END5 +mi +150 +hlc +4.best2.tmp +cl +4.best2.tmp +0 +hw +bs +4.best2.bdd.tmp +0 +mq +quit +END5 +echo "----------------------------- ... RESULTS ... -----------------------------" +diff --brief 4.max1 4.max1.tmp +diff --brief 4.max2 4.max2.tmp +diff --brief 4.bdd.bis1 4.node2.bdd.tmp +diff --brief 4.bdd.bis2 4.node3.bdd.tmp +diff --brief 4.bdd.bis3 4.best1.bdd.tmp +diff --brief 4.bdd.bis4 4.best2.bdd.tmp +echo "-------------------------------- ... END ----------------------------------" +rm -f *.tmp* diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/varauxids.ord b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/varauxids.ord new file mode 100644 index 000000000..7927325e9 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/varauxids.ord @@ -0,0 +1,50 @@ +1 +3 +5 +7 +9 +11 +13 +15 +17 +19 +21 +23 +25 +27 +29 +31 +33 +35 +37 +39 +41 +43 +45 +47 +49 +51 +53 +55 +57 +59 +61 +63 +65 +67 +69 +71 +73 +75 +77 +79 +81 +83 +85 +87 +89 +91 +93 +95 +97 +99 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/varnames.ord b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/varnames.ord new file mode 100644 index 000000000..febe1b0a9 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/varnames.ord @@ -0,0 +1,50 @@ +V1 +V2 +V3 +V4 +V5 +V6 +V7 +V8 +V9 +V10 +V11 +V12 +V13 +V14 +V15 +V16 +V17 +V18 +V19 +V20 +V21 +V22 +V23 +V24 +V25 +V26 +V27 +V28 +V29 +V30 +V31 +V32 +V33 +V34 +V35 +V36 +V37 +V38 +V39 +V40 +V41 +V42 +V43 +V44 +V45 +V46 +V47 +V48 +V49 +V50 diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/zero.bdd b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/zero.bdd new file mode 100644 index 000000000..cc4717d31 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/exp/zero.bdd @@ -0,0 +1,13 @@ +.ver DDDMP-1.0 +.mode A +.varinfo 0 +.nnodes 1 +.nvars 100 +.nsuppvars 0 +.ids +.permids +.nroots 1 +.rootids -1 +.nodes +1 T 1 0 0 +.end diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/testdddmp.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/testdddmp.c new file mode 100644 index 000000000..6879dccb6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/dddmp/testdddmp.c @@ -0,0 +1,2279 @@ +/**CFile********************************************************************** + + FileName [testdddmp.c] + + PackageName [dddmp] + + Synopsis [A simple test function for Dddmp package] + + Description [This program constitutes a simple test program + for the dddmp library (version 2.0). + A simple interactive command selection allow the users to perform the + main operation on BDDs, ADDs, and CNF, such as loading and storing. + It can work also as a BDD calculators. + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2004 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#include +#include +#include "dddmpInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DDDMPTEST_MAX_FILENAME_LENGTH 256 +#define DDDMPTEST_MAX_STRING_LENGTH 80 +#define DDDMPTEST_MAX_OPERAND 20 +#define DDDMPTEST_MAX_VARIABLE 50 +#define DDDMP_MAX_BDDARRAY_LEN 1000 + +/**Enum************************************************************************ + + Synopsis [Message type for output messages] + + Description [Type supported by the output function to print-out + the proper message. + ] + +******************************************************************************/ + +typedef enum { + /* Int Messages */ + DDDMP_MESSAGE_MANAGER_VAR, + DDDMP_MESSAGE_BDD, + DDDMP_MESSAGE_BDD_ARRAY, + DDDMP_MESSAGE_SOURCE1, + DDDMP_MESSAGE_SOURCE2, + DDDMP_MESSAGE_DESTINATION, + DDDMP_MESSAGE_CUBE, + DDDMP_MESSAGE_INDEX, + DDDMP_MESSAGE_I_ID, + DDDMP_MESSAGE_EDGE_MAX, + DDDMP_MESSAGE_LENGHT_MAX, + DDDMP_MESSAGE_REORDERING, + /* String Messages */ + DDDMP_MESSAGE_PROMPT, + DDDMP_MESSAGE_FILE, + DDDMP_MESSAGE_OP, + DDDMP_MESSAGE_FORMAT +} Dddmp_MessageType; + +#if !defined(RAND_MAX) && defined(sun) && defined(sparc) +#define RAND_MAX 2147483647 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct dddmpVarInfo { + /* + * Local Information + */ + + int nDdVars; /* Local Manager Number of Variables */ + char **rootNames; /* Root Names */ + + /* + * Header File Information + */ + + Dddmp_DecompType ddType; + + int nVars; /* File Manager Number of Variables */ + int nSuppVars; /* File Structure Number of Variables */ + + int varNamesFlagUpdate; /* 0 to NOT Update */ + char **suppVarNames; + char **orderedVarNames; + + int varIdsFlagUpdate; /* 0 to NOT Update */ + int *varIds; /* File ids - nSuppVars size */ + int *varIdsAll; /* ALL ids - nVars size */ + + int varComposeIdsFlagUpdate; /* 0 to NOT Update */ + int *varComposeIds; /* File permids - nSuppVars size */ + int *varComposeIdsAll; /* ALL permids - nVars size */ + + int varAuxIdsFlagUpdate; /* 0 to NOT Update */ + int *varAuxIds; /* File auxids - nSuppVars size */ + int *varAuxIdsAll; /* ALL auxids - nVars size */ + + int nRoots; +} dddmpVarInfo_t; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +Dddmp_RootMatchType rootmatchmode; +Dddmp_VarMatchType varmatchmode; +Dddmp_VarInfoType varoutinfo; +char varname[DDDMPTEST_MAX_STRING_LENGTH]; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdManager *ManagerInit (dddmpVarInfo_t *varInfo); +static void ManagerQuit (DdManager **ddMgr, dddmpVarInfo_t *varInfo); +static int OneCreate(DdManager *ddMgr, DdNode **operandBdd); +static int BddZeroCreate(DdManager *ddMgr, DdNode **operandBdd); +static int LeafCreate(DdManager *ddMgr, DdNode **operandBdd); +static int BddCreate(DdManager *ddMgr, DdNode **operandBdd); +static int A2B(void); +static int B2A(void); +static int HeaderLoadBdd(dddmpVarInfo_t *varInfo); +static int HeaderLoadCnf(dddmpVarInfo_t *varInfo); +static int HeaderWrite(dddmpVarInfo_t *varInfo); +static int Help(void); +static int OrderNamesLoad(dddmpVarInfo_t *varInfo); +static int IntArrayLoad(dddmpVarInfo_t *varInfo, const char *mode); +static int BddLoad(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int BddArrayLoad(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int AddLoad(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int AddArrayLoad(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int BddLoadCnf(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int BddArrayLoadCnf(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int Operation(DdManager *ddMgr, DdNode **operandBdd); +static int BddStore(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int BddArrayStore(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int AddStore(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int AddArrayStore(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int BddStoreCnf(DdManager *ddMgr, DdNode **operandBdd, dddmpVarInfo_t *varInfo); +static int BddArrayStoreCnf(DdManager *ddMgr, DdNode ***operandBddArray, int *operandBddArraySize, dddmpVarInfo_t *varInfo); +static int DynamicReordering(DdManager *ddMgr); +static int SetLoadMatchmode(); +static int CompleteInfoStruct(Dddmp_DecompType ddType, int nVars, int nSuppVars, char **suppVarNames, char **orderedVarNames, int *varIds, int *varComposeIds, int *varAuxIds, int nRoots, dddmpVarInfo_t *varInfo); +static void ReadInt(Dddmp_MessageType message, int *i); +static void ReadString(Dddmp_MessageType message, char string[]); + +/**AutomaticEnd***************************************************************/ + +int +main( + int argc, + char **argv + ) +{ + DdManager *ddMgr = NULL; + DdNode **operandBdd = NULL; + DdNode ***operandBddArray = NULL; + int *operandBddArraySize = NULL; + char *row = NULL; + dddmpVarInfo_t varInfo; + int i; + + /*--------------------- Echo command line and arguments -------------------*/ + + fprintf (stdout, "#"); + for (i=0; i1) { + Help(); + } + + /*-------------------------- Init Array of BDDs ---------------------------*/ + + rootmatchmode = DDDMP_ROOT_MATCHLIST; +#if 1 + varmatchmode = DDDMP_VAR_MATCHIDS; +#else + varmatchmode = DDDMP_VAR_MATCHNAMES; +#endif + varoutinfo = DDDMP_VARIDS; + + row = DDDMP_ALLOC (char, DDDMPTEST_MAX_STRING_LENGTH); + Dddmp_CheckAndReturn (row==NULL, "Allocation error."); + + operandBdd = DDDMP_ALLOC (DdNode *, DDDMPTEST_MAX_OPERAND); + Dddmp_CheckAndReturn (operandBdd==NULL, "Allocation error."); + + operandBddArray = DDDMP_ALLOC (DdNode **, DDDMPTEST_MAX_OPERAND); + Dddmp_CheckAndReturn (operandBddArray==NULL, "Allocation error."); + + operandBddArraySize = DDDMP_ALLOC (int, DDDMPTEST_MAX_OPERAND); + Dddmp_CheckAndReturn (operandBddArraySize==NULL, "Allocation error."); + + for (i=0; inDdVars = nVars; + + varInfo->rootNames = NULL; + varInfo->ddType = DDDMP_NONE; + varInfo->nVars = (-1); + varInfo->nSuppVars = (-1); + varInfo->varNamesFlagUpdate = 1; + varInfo->suppVarNames = NULL; + varInfo->orderedVarNames = NULL; + varInfo->varIdsFlagUpdate = 1; + varInfo->varIds = NULL; + varInfo->varIdsAll = NULL; + varInfo->varComposeIdsFlagUpdate = 1; + varInfo->varComposeIds = NULL; + varInfo->varComposeIdsAll = NULL; + varInfo->varAuxIdsFlagUpdate = 1; + varInfo->varAuxIds = NULL; + varInfo->varAuxIdsAll = NULL; + varInfo->nRoots = (-1); + + /*------------------------------ Init DD Manager --------------------------*/ + + ddMgr = Cudd_Init (nVars, 0, CUDD_UNIQUE_SLOTS, + CUDD_CACHE_SLOTS, 0); + + Dddmp_CheckAndReturn (ddMgr==NULL, "DdManager NOT inizializated."); + + return (ddMgr); +} + +/**Function******************************************************************** + + Synopsis [Quit a CUDD Manager.] + + Description [Quit a CUDD Manager.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +ManagerQuit ( + DdManager **ddMgrPtr /* IN: CUDD Manager */, + dddmpVarInfo_t *varInfo /* IN: Internal Manager */ + ) +{ + if (*ddMgrPtr == NULL) { + return; + } + + fprintf (stdout, "Quitting CUDD Manager.\n"); + Cudd_Quit (*ddMgrPtr); + *ddMgrPtr = NULL; + + DddmpStrArrayFree (varInfo->rootNames, varInfo->nRoots); + DddmpStrArrayFree (varInfo->suppVarNames, varInfo->nSuppVars); + DddmpStrArrayFree (varInfo->orderedVarNames, varInfo->nVars); + DDDMP_FREE (varInfo->varIds); + DDDMP_FREE (varInfo->varIdsAll); + DDDMP_FREE (varInfo->varComposeIds); + DDDMP_FREE (varInfo->varComposeIdsAll); + DDDMP_FREE (varInfo->varAuxIds); + DDDMP_FREE (varInfo->varAuxIdsAll); + + varInfo->nDdVars = (-1); + varInfo->rootNames = NULL; + varInfo->ddType = DDDMP_NONE; + varInfo->nVars = (-1); + varInfo->nSuppVars = (-1); + varInfo->varNamesFlagUpdate = 1; + varInfo->suppVarNames = NULL; + varInfo->orderedVarNames = NULL; + varInfo->varIdsFlagUpdate = 1; + varInfo->varIds = NULL; + varInfo->varIdsAll = NULL; + varInfo->varComposeIdsFlagUpdate = 1; + varInfo->varComposeIds = NULL; + varInfo->varComposeIdsAll = NULL; + varInfo->varAuxIdsFlagUpdate = 1; + varInfo->varAuxIds = NULL; + varInfo->varAuxIdsAll = NULL; + varInfo->nRoots = (-1); + + return; +} + +/**Function******************************************************************** + + Synopsis [Create a One-BDD Leaf.] + + Description [Create a One-BDD Leaf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +OneCreate( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* In/OUT: Array of operand */ + ) +{ + int i; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_BDD, &i); + + operandBdd[i] = Cudd_ReadOne (ddMgr); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Create a Zero-BDD Leaf.] + + Description [Create a Zero-BDD Leaf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddZeroCreate( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN/OUT: array of operand */ + ) +{ + int i; + DdNode *one = NULL; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_BDD, &i); + + one = Cudd_ReadOne(ddMgr); + operandBdd[i] = Cudd_Not(one); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Create a One-Node BDD.] + + Description [Create a One-Node BDD.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +LeafCreate( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN/OUT: Array of operandBdd */ + ) +{ + int i, j; + DdNode *f = NULL; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_BDD, &i); + ReadInt (DDDMP_MESSAGE_INDEX, &j); + + f = Cudd_bddIthVar (ddMgr, j); + Cudd_Ref(f); + operandBdd[i] = f; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Create a BDD.] + + Description [Create a BDD: Variable index and number of cubes selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddCreate ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* array of operandBdd */ + ) +{ + DdNode **vet, *f, *g, *h; + int nb, nv, vi0, vi1, nc, i, j; + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_BDD, &nb); + + fprintf (stdout, "Variables Index [n-m] (m-n = number of variables): "); + fgets (row, DDDMPTEST_MAX_STRING_LENGTH, stdin); + sscanf (row, "%d-%d", &vi0, &vi1); + nv = vi1-vi0+1; + + ReadInt (DDDMP_MESSAGE_CUBE, &nc); + + /* Leaf Creation */ + vet = DDDMP_ALLOC (DdNode *, nv); + for (i=0; i 0.5 ) { + h = Cudd_bddAnd (ddMgr, g, vet[j]); + } else { + h = Cudd_bddAnd (ddMgr, g, Cudd_Not (vet[j])); + } + Cudd_Ref (h); + Cudd_RecursiveDeref (ddMgr, g); + g = h; + } + h = Cudd_bddOr (ddMgr, f, g); + Cudd_Ref (h); + Cudd_RecursiveDeref (ddMgr, f); + Cudd_RecursiveDeref (ddMgr, g); + f = h; + } + + operandBdd[nb] = f; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Transform a BDD from the ASCII to the Binary format].] + + Description [Input and Output file selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +A2B( + void +) +{ + fprintf (stderr, "Not yet Implemented!!!\n"); + + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Transform a BDD from the Binary to the ASCII format].] + + Description [Input and Output file selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +B2A( + void +) +{ + fprintf (stderr, "Not yet Implemented!!!\n"); + + return (DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Read the Header of a file containing a BDD.] + + Description [File name Selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +HeaderLoadBdd ( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + Dddmp_DecompType ddType; + int retValue, nRoots, nVars, nSuppVars; + int *tmpVarIds = NULL; + int *tmpVarAuxIds = NULL; + int *tmpVarComposeIds = NULL; + char **tmpOrderedVarNames = NULL; + char **tmpSuppVarNames = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + + retValue = Dddmp_cuddHeaderLoad (&ddType, &nVars, &nSuppVars, + &tmpSuppVarNames, &tmpOrderedVarNames, &tmpVarIds, &tmpVarComposeIds, + &tmpVarAuxIds, &nRoots, fileName, NULL); + + if (retValue == DDDMP_FAILURE) { + return (DDDMP_FAILURE); + } + + /*---------------------------- Tail Operations ----------------------------*/ + + CompleteInfoStruct (ddType, nVars, nSuppVars, + tmpSuppVarNames, tmpOrderedVarNames, tmpVarIds, tmpVarComposeIds, + tmpVarAuxIds, nRoots, varInfo); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Read the Header of a file containing a CNF formula.] + + Description [File name Selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +HeaderLoadCnf ( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + int retValue, nRoots, nVars, nSuppVars; + int *tmpVarIds = NULL; + int *tmpVarComposeIds = NULL; + int *tmpVarAuxIds = NULL; + char **tmpOrderedVarNames = NULL; + char **tmpSuppVarNames = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + + retValue = Dddmp_cuddHeaderLoadCnf (&nVars, &nSuppVars, + &tmpSuppVarNames, &tmpOrderedVarNames, &tmpVarIds, &tmpVarComposeIds, + &tmpVarAuxIds, &nRoots, fileName, NULL); + + if (retValue == DDDMP_FAILURE) { + return (DDDMP_FAILURE); + } + + /*---------------------------- Tail Operations ----------------------------*/ + + CompleteInfoStruct (DDDMP_CNF, nVars, nSuppVars, + tmpSuppVarNames, tmpOrderedVarNames, tmpVarIds, tmpVarComposeIds, + tmpVarAuxIds, nRoots, varInfo); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Read the Header of a filke containing a BDD.] + + Description [File name Selection.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +HeaderWrite( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + int i; + + switch (varInfo->ddType) { + case DDDMP_BDD: + fprintf (stdout, "DD TYPE: DDDMP_BDD\n"); + break; + case DDDMP_ADD: + fprintf (stdout, "DD TYPE: DDDMP_ADD\n"); + break; + case DDDMP_CNF: + fprintf (stdout, "DD TYPE: DDDMP_CNF\n"); + break; + case DDDMP_NONE: + fprintf (stdout, "DD TYPE: NONE - Error\n"); + break; + } + + fprintf (stdout, "Number of variables: %d\n", varInfo->nVars); + fprintf (stdout, "Number of support variables: %d\n", varInfo->nSuppVars); + + if (varInfo->suppVarNames != NULL) { + fprintf (stdout, "suppVarNames: "); + for (i=0; inSuppVars; i++) { + if (varInfo->suppVarNames[i] != NULL) { + fprintf (stdout, "%s ", varInfo->suppVarNames[i]); + } + } + fprintf (stdout, "\n"); + } + + if (varInfo->orderedVarNames != NULL) { + fprintf (stdout, "orderedVarNames: "); + for (i=0; inVars; i++) { + if (varInfo->orderedVarNames[i] != NULL) { + fprintf (stdout, "%s ", varInfo->orderedVarNames[i]); + } + } + fprintf (stdout, "\n"); + } + + if (varInfo->varIds != NULL) { + fprintf (stdout, "varIds: "); + for (i=0; inSuppVars; i++) { + fprintf (stdout, "%d ", varInfo->varIds[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varIdsAll != NULL) { + fprintf (stdout, "varIds for ALL Manager Variables: "); + for (i=0; inVars; i++) { + fprintf (stdout, "%d ", varInfo->varIdsAll[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varComposeIds != NULL) { + fprintf (stdout, "varComposeIds: "); + for (i=0; inSuppVars; i++) { + fprintf (stdout, "%d ", varInfo->varComposeIds[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varComposeIdsAll != NULL) { + fprintf (stdout, "varComposeIds for ALL Manager Variables: "); + for (i=0; inVars; i++) { + fprintf (stdout, "%d ", varInfo->varComposeIdsAll[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varAuxIds != NULL) { + fprintf (stdout, "varAuxIds: "); + for (i=0; inSuppVars; i++) { + fprintf (stdout, "%d ", varInfo->varAuxIds[i]); + } + fprintf (stdout, "\n"); + } + + if (varInfo->varAuxIdsAll != NULL) { + fprintf (stdout, "varAuxIds for ALL Manager Variables: "); + for (i=0; inVars; i++) { + fprintf (stdout, "%d ", varInfo->varAuxIdsAll[i]); + } + fprintf (stdout, "\n"); + } + + fprintf (stdout, "Number of roots: %d\n", varInfo->nRoots); + + fflush (stdout); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Print the Help messages.] + + Description [Print the Help messages.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +Help( + void + ) +{ + fprintf (stdout, "Commands:\n"); + fprintf (stdout, "MAIN\n"); + + fprintf (stdout, "\thelp : Print this set of messages.\n"); + fprintf (stdout, "\tquit : Quit the test program.\n"); + + fprintf (stdout, "MANAGER OPERATIONs\n"); + + fprintf (stdout, + "\thmi : Manager Init (To do BEFORE any BDD/ADD operation).\n"); + fprintf (stdout, "\thmq : Manager Quit.\n"); + + fprintf (stdout, "LOAD\n"); + + fprintf (stdout, "\thlb : Load the header from a BDD/ADD file.\n"); + fprintf (stdout, "\thlc : Load the header from a CNF file.\n"); + fprintf (stdout, "\tbl : Load a BDD from a file.\n"); + fprintf (stdout, "\tbal : Load an Array-BDD from a file.\n"); + fprintf (stdout, "\tal : Load an ADD from a file.\n"); + fprintf (stdout, "\taal : Load an Array-ADD from a file.\n"); + fprintf (stdout, "\tcl : Load a CNF Formula from a file.\n"); + fprintf (stdout, "\tcal : Load an Array of CNF Formulas from a file.\n"); + + fprintf (stdout, "STORE\n"); + + fprintf (stdout, + "\thw : (Header) Write variable information on stdout.\n"); + fprintf (stdout, "\tbs : Store a BDD into a file.\n"); + fprintf (stdout, "\tbas : Store an Array-BDD from a file.\n"); + fprintf (stdout, "\tas : Store an ADD into a file.\n"); + fprintf (stdout, "\taas : Store an Array-ADD into a file.\n"); + fprintf (stdout, "\tcs : Store BDD as a CNF formula.\n"); + fprintf (stdout, "\tcas : Store and Array of BDDs as a CNF formula.\n"); + + fprintf (stdout, "MISC\n"); + + fprintf (stdout, "\tdr : Activate Dynamic Reordering.\n"); + fprintf (stdout, "\tonl : Load the order from a file (varNames).\n"); + fprintf (stdout, "\toil : Load the order from a file (varAuxIds).\n"); + fprintf (stdout, "\tcil : Load compose IDs from a file.\n"); + fprintf (stdout, "\tslm : Set Load matchmode for variables.\n"); + fprintf (stdout, + "\top : Operation (or, and, xor, not, =) between BDDs.\n"); + fprintf (stdout, "\toc : Create a terminal-one BDD.\n"); + fprintf (stdout, "\tzc : Create a terminal-zero BDD.\n"); + fprintf (stdout, "\tlc : Create a single variable BDD (1 node).\n"); + fprintf (stdout, "\tbc : Create a random BDD.\n"); + + fprintf (stdout, "NOT YET IMPLEMENTED\n"); + + fprintf (stdout, + "\ta2b : Convert a file from the ASCII format to the binary one.\n"); + fprintf (stdout, + "\tb2a : Convert a file from the binary format to the ASCII one.\n"); + + fprintf (stdout, "HINT\n"); + + fprintf (stdout, + " Command 'mi' has to be the first instruction to build:\n"); + fprintf (stdout, " a) The CUDD manager.\n"); + fprintf (stdout, + " b) The internal manager (containing name and variable IDs).\n"); + fprintf (stdout, + " After that load an header file with 'hlb' or 'hlc' to have proper\n"); + fprintf (stdout, + " names and ids for each subsequent load/store operation.\n"); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load the BDD order from a file (varNames).] + + Description [Load the BDD order from a file (varNames). + Force the orderedVarNames field of the varInfo structure, + i.e., the local manager, to be stucked to this array of values. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +OrderNamesLoad( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + FILE *fp = NULL; + int i; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + char tmpBuf[DDDMPTEST_MAX_STRING_LENGTH]; + char tmpName[DDDMPTEST_MAX_STRING_LENGTH]; + char **tmpOrderedVarNames = NULL; + + /*------------------------- Red New Var Names Array ----------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + + fp = fopen (fileName, "r"); + Dddmp_CheckAndReturn (fp==NULL, "Cannot open file."); + + varoutinfo = DDDMP_VARNAMES; + tmpOrderedVarNames = DDDMP_ALLOC (char *, varInfo->nDdVars); + + i=0; + while (fgets (tmpBuf, DDDMPTEST_MAX_STRING_LENGTH, fp)!=NULL) { + if (tmpBuf[0]=='#') { + continue; + } + + if (i>=varInfo->nDdVars) { + fprintf (stdout, + "Number of variables in files higher than DD manager vars (%d)\n", + varInfo->nDdVars); + fprintf (stdout, "Exceeding variables ignored\n"); + fprintf (stdout, + "You might increase the DDDMPTEST_MAX_VARIABLE constant\n"); + break; + } + + sscanf (tmpBuf, "%s", tmpName); + tmpOrderedVarNames[i] = DDDMP_ALLOC (char, (strlen (tmpName) + 1)); + if (tmpOrderedVarNames[i]==NULL) { + fprintf (stdout, "Error allocating memory\n"); + } else { + strcpy (tmpOrderedVarNames[i], tmpName); + } + i++; + } + + for ( ;inDdVars; i++) { + tmpOrderedVarNames[i] = NULL; + } + + fclose(fp); + + /*----------------------- Free and Set Var Names Array --------------------*/ + + DddmpStrArrayFree (varInfo->orderedVarNames, varInfo->nVars); + varInfo->orderedVarNames = tmpOrderedVarNames; + varInfo->nVars = varInfo->nDdVars; + + /* DO NOT ALLOW FURTHER UPDATES */ + varInfo->varNamesFlagUpdate = 0; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load the BDD order from a file (varauxids).] + + Description [Load the BDD order from a file (varauxids). + Force the + varAuxIds and varAuxIdsAll + or the + varComposeIds and varComposeIdsAll + fields of the varInfo structure, i.e., the local manager, to be + stucked to this array of values. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +IntArrayLoad ( + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */, + const char *mode + ) +{ + FILE *fp = NULL; + int i; + int *tmpArray1 = NULL; + int *tmpArray2 = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + char buf[DDDMPTEST_MAX_STRING_LENGTH]; + + ReadString (DDDMP_MESSAGE_FILE, fileName); + + fp = fopen(fileName, "r"); + Dddmp_CheckAndReturn (fp==NULL, "Cannot open file."); + + tmpArray1 = DDDMP_ALLOC (int, varInfo->nDdVars); + tmpArray2 = DDDMP_ALLOC (int, varInfo->nDdVars); + Dddmp_CheckAndReturn (tmpArray1==NULL, "Error allocating memory."); + Dddmp_CheckAndReturn (tmpArray2==NULL, "Error allocating memory."); + + i=0; + while (fgets(buf, DDDMPTEST_MAX_STRING_LENGTH, fp)!=NULL) { + if (buf[0]=='#') { + continue; + } + if (i>=varInfo->nDdVars) { + fprintf (stdout, + "Number of variables in files higher than DD manager vars (%d)\n", + varInfo->nDdVars); + fprintf (stdout, "Exceeding variables ignored.\n"); + fprintf (stdout, "(Increase the DDDMPTEST_MAX_VARIABLE constant.)\n"); + break; + } + sscanf(buf, "%d", &tmpArray1[i]); + sscanf(buf, "%d", &tmpArray2[i++]); + } + + for (;inDdVars;i++) { + tmpArray1[i]= -1; + tmpArray2[i]= -1; + } + + fclose(fp); + + if (strcmp (mode, "oil") == 0) { + varInfo->varAuxIds = tmpArray1; + varInfo->varAuxIdsAll = tmpArray2; + + /* DO NOT ALLOW FURTHER UPDATES */ + varInfo->varAuxIdsFlagUpdate = 0; + } else { + if (strcmp (mode, "cil") == 0) { + varInfo->varComposeIds = tmpArray1; + varInfo->varComposeIdsAll = tmpArray2; + + /* DO NOT ALLOW FURTHER UPDATES */ + varInfo->varComposeIdsFlagUpdate = 0; + } + } + + varInfo->nVars = varInfo->nDdVars; + varInfo->nSuppVars = varInfo->nDdVars; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load a BDD from a file.] + + Description [Load a BDD from a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddLoad ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN: Operand BDD */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode *f = NULL; + int i; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD, &i); + + /*-------------------------------- Load BDD -------------------------------*/ + + fprintf (stdout, "Loading %s ...\n", fileName); + + f = Dddmp_cuddBddLoad (ddMgr, varmatchmode, varInfo->orderedVarNames, + varInfo->varIdsAll, varInfo->varComposeIdsAll, DDDMP_MODE_DEFAULT, + fileName, NULL); + + if (f==NULL) { + fprintf (stderr, "Dddmp Test Error : %s is not loaded from file\n", + fileName); + } else { + operandBdd[i] = f; + } + + /*---------------------------- Tail Operations ----------------------------*/ + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load an array of BDDs from a file.] + + Description [Load an array of BDDs from a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddArrayLoad( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand BDD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode **bddArray = NULL; + int i, j, nRoots; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + /*---------------------------- Load BDDs ----------------------------------*/ + + nRoots = Dddmp_cuddBddArrayLoad (ddMgr, rootmatchmode, + varInfo->rootNames, varmatchmode, + varInfo->orderedVarNames, varInfo->varIdsAll, varInfo->varComposeIdsAll, + DDDMP_MODE_DEFAULT, fileName, NULL, &bddArray); + + Dddmp_CheckAndReturn (nRoots>DDDMP_MAX_BDDARRAY_LEN, + "DDDMP_MAX_BDDARRAY_LEN exceeded by BDD array len (increase it)."); + + if (nRoots<=0) { + return (DDDMP_FAILURE); + } + + varInfo->nRoots = nRoots; + operandBddArray[i] = DDDMP_ALLOC (DdNode *, nRoots); + Dddmp_CheckAndReturn (operandBddArray[i]==NULL, "Allocation error."); + + for (j=0; jorderedVarNames, + varInfo->varIdsAll, varInfo->varComposeIdsAll, DDDMP_MODE_DEFAULT, + fileName, NULL); + + if (f==NULL) { + fprintf (stderr, "Dddmp Test Error : %s is not loaded from file\n", + fileName); + } else { + operandBdd[i] = f; + } + + /*---------------------------- Tail Operations ----------------------------*/ + + fprintf (stdout, "Load:\n"); + Cudd_PrintMinterm (ddMgr, f); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Load an array of ADDs from a file.] + + Description [Load an array of ADDs from a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +AddArrayLoad( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand BDD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + int i, j, nRoots; + DdNode **bddArray = NULL; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + /*------------------------------- Load ADDs -------------------------------*/ + + nRoots = Dddmp_cuddAddArrayLoad (ddMgr, rootmatchmode, + varInfo->rootNames, varmatchmode, + varInfo->orderedVarNames, varInfo->varIdsAll, varInfo->varComposeIdsAll, + DDDMP_MODE_DEFAULT, fileName, NULL, &bddArray); + + Dddmp_CheckAndReturn (nRoots>DDDMP_MAX_BDDARRAY_LEN, + "DDDMP_MAX_BDDARRAY_LEN exceeded by BDD array len (increase it)."); + + if (nRoots<=0) { + return (DDDMP_FAILURE); + } + + varInfo->nRoots = nRoots; + operandBddArray[i] = DDDMP_ALLOC (DdNode *, nRoots); + Dddmp_CheckAndReturn (operandBddArray[i]==NULL, "Allocation error."); + + for (j=0; jorderedVarNames, varInfo->varAuxIdsAll, varInfo->varComposeIdsAll, + loadingMode, fileName, NULL, &rootsPtr, &nRoots); + + Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE, + "Dddmp Test: Load From File Error.\n", failure); + + operandBdd[i] = rootsPtr[0]; + + /*---------------------------- Tail Operations ----------------------------*/ + + /* Free array */ + DDDMP_FREE (rootsPtr); + + return (DDDMP_SUCCESS); + + failure: + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Load a CNF formula from a file, and create an array of + BDDs. + ] + + Description [Load a CNF formula from a file, and create an array of + BDDs. + ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddArrayLoadCnf ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand BDD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode **rootsPtr = NULL; + Dddmp_DecompCnfLoadType loadingMode = DDDMP_CNF_MODE_CONJ_QUANT; + int i, j, nRoots, retValue; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + /*--------------------------- Loading BDDs --------------------------------*/ + + retValue = Dddmp_cuddBddArrayLoadCnf (ddMgr, rootmatchmode, + varInfo->rootNames, varmatchmode, + varInfo->orderedVarNames, varInfo->varIdsAll, varInfo->varComposeIdsAll, + loadingMode, fileName, NULL, &rootsPtr, &nRoots); + + Dddmp_CheckAndReturn (nRoots>DDDMP_MAX_BDDARRAY_LEN, + "DDDMP_MAX_BDDARRAY_LEN exceeded by BDD array len (increase it)."); + + if (nRoots<=0) { + return (DDDMP_FAILURE); + } + + varInfo->nRoots = nRoots; + operandBddArray[i] = DDDMP_ALLOC (DdNode *, nRoots); + Dddmp_CheckAndReturn (operandBddArray[i]==NULL, "Allocation error."); + + for (j=0; jorderedVarNames, + varInfo->varAuxIdsAll, DDDMP_MODE_TEXT, varoutinfo, fileName, NULL); + + Dddmp_CheckAndGotoLabel (retValue!=DDDMP_SUCCESS, "BDD NOT stored.", + failure); + + return (DDDMP_SUCCESS); + + failure: + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Store an Array of BDD in a file.] + + Description [Store an Array of BDD in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddArrayStore ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand BDD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + int i, retValue, nRoots; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + nRoots = operandBddArraySize[i]; + + /*----------------------------- Store BDDs -------------------------------*/ + + fprintf (stdout, "Storing Array of BDDs in file %s ...\n", fileName); + fflush (stdout); + + retValue = Dddmp_cuddBddArrayStore (ddMgr, NULL, nRoots, operandBddArray[i], + NULL, varInfo->orderedVarNames, varInfo->varAuxIdsAll, DDDMP_MODE_TEXT, + DDDMP_VARIDS, fileName, NULL); + + Dddmp_CheckAndGotoLabel (retValue!=DDDMP_SUCCESS, "BDD NOT stored.", + failure); + fprintf (stdout, "done.\n"); + + return (DDDMP_SUCCESS); + + failure: + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Store an ADD in a file.] + + Description [Store an ADD in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +AddStore( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN: operand Bdd */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode *f; + int i, retValue; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD, &i); + + fprintf (stdout, "Storing %s ...\n", fileName); + fflush (stdout); + f = operandBdd[i]; + +#if 0 + /* StQ Patch - CREATE temporary ADD to Store */ + f = Cudd_addResidue (ddMgr, 4, 3, 1, 1); + fprintf (stderr, "Store:\n"); + Cudd_PrintMinterm (ddMgr, f); + /* end ... StQ Patch */ +#endif + + retValue = Dddmp_cuddAddStore (ddMgr, NULL, f, varInfo->orderedVarNames, + varInfo->varAuxIdsAll, DDDMP_MODE_TEXT, varoutinfo, fileName, NULL); + + Dddmp_CheckAndReturn (retValue!=DDDMP_SUCCESS, "BDD NOT stored."); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Store a BDD in a file.] + + Description [Store a BDD in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +AddArrayStore ( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand ADD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo + ) +{ + int i, retValue, nRoots; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &i); + + nRoots = operandBddArraySize[i]; + + fprintf (stdout, "Storing Array of BDDs in file %s ...\n", fileName); + fflush (stdout); + + retValue = Dddmp_cuddAddArrayStore (ddMgr, NULL, nRoots, operandBddArray[i], + NULL, varInfo->orderedVarNames, varInfo->varAuxIdsAll, DDDMP_MODE_TEXT, + DDDMP_VARIDS, fileName, NULL); + + Dddmp_CheckAndReturn (retValue!=DDDMP_SUCCESS, "BDD NOT stored."); + + fprintf (stdout, "done.\n"); + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Store a BDD as CNF format in a file.] + + Description [Store a BDD as CNF format in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddStoreCnf( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode **operandBdd /* IN: Array of operand ADD */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + DdNode *f = NULL; + Dddmp_DecompCnfStoreType storingMode = DDDMP_CNF_MODE_BEST; + int noHeader = 0; + int i, nVars, retValue, idInitial, varNewN, clauseNewN; + int edgeInTh = (-1); + int pathLengthTh = (-1); + int *tmpBddIds = NULL; + int *tmpCnfIds = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD, &i); + ReadString (DDDMP_MESSAGE_FORMAT, row); + + switch (row[0]) { + case 'N': + storingMode = DDDMP_CNF_MODE_NODE; + break; + case 'M': + storingMode = DDDMP_CNF_MODE_MAXTERM; + break; + case 'B': + storingMode = DDDMP_CNF_MODE_BEST; + ReadInt (DDDMP_MESSAGE_EDGE_MAX, &edgeInTh); + ReadInt (DDDMP_MESSAGE_LENGHT_MAX, &pathLengthTh); + break; + } + ReadInt (DDDMP_MESSAGE_I_ID, &idInitial); + + fprintf (stdout, "Storing %s ...\n", fileName); + fflush (stdout); + + f = operandBdd[i]; + + nVars = varInfo->nDdVars; + + /*------------ From BDD and CNF ids to Proper Array of ids ----------------*/ + + tmpBddIds = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (tmpBddIds==NULL, "Error allocating memory.", + failure); + tmpCnfIds = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndGotoLabel (tmpBddIds==NULL, "Error allocating memory.", + failure); + + for (i=0; iorderedVarNames, tmpBddIds, NULL, tmpCnfIds, idInitial, + edgeInTh, pathLengthTh, fileName, NULL, &clauseNewN, &varNewN); + + Dddmp_CheckAndGotoLabel (retValue!=DDDMP_SUCCESS, "BDD NOT stored.", + failure); + + fprintf (stdout, "Number of Clauses Stored = %d\n", clauseNewN); + fprintf (stdout, "Number of New Variable Created Storing = %d\n", + varNewN); + fflush (stdout); + + DDDMP_FREE (tmpBddIds); + DDDMP_FREE (tmpCnfIds); + + return (DDDMP_SUCCESS); + + failure: + DDDMP_FREE (tmpBddIds); + DDDMP_FREE (tmpCnfIds); + + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Store a BDD as CNF format in a file.] + + Description [Store a BDD as CNF format in a file.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +BddArrayStoreCnf( + DdManager *ddMgr /* IN: CUDD Manager */, + DdNode ***operandBddArray /* IN: Array of operand ADD */, + int *operandBddArraySize /* IN: Number of ADD in the Array */, + dddmpVarInfo_t *varInfo /* IN/OUT: Variable Information */ + ) +{ + Dddmp_DecompCnfStoreType storingMode = DDDMP_CNF_MODE_BEST; + int noHeader = 0; + int i, nVars, bddN, retValue, idInitial, varNewN, clauseNewN; + int edgeInTh = (-1); + int pathLengthTh = (-1); + int *tmpBddIds = NULL; + int *tmpCnfIds = NULL; + char fileName[DDDMPTEST_MAX_FILENAME_LENGTH]; + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadString (DDDMP_MESSAGE_FILE, fileName); + ReadInt (DDDMP_MESSAGE_BDD_ARRAY, &bddN); + ReadString (DDDMP_MESSAGE_FORMAT, row); + switch (row[0]) { + case 'N': + storingMode = DDDMP_CNF_MODE_NODE; + break; + case 'M': + storingMode = DDDMP_CNF_MODE_MAXTERM; + break; + case 'B': + storingMode = DDDMP_CNF_MODE_BEST; + ReadInt (DDDMP_MESSAGE_EDGE_MAX, &edgeInTh); + ReadInt (DDDMP_MESSAGE_LENGHT_MAX, &pathLengthTh); + break; + } + ReadInt (DDDMP_MESSAGE_I_ID, &idInitial); + + nVars = varInfo->nDdVars; + + /*------------ From BDD and CNF ids to Proper Array of ids ----------------*/ + + tmpBddIds = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (tmpBddIds==NULL, "Allocation error."); + tmpCnfIds = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (tmpCnfIds==NULL, "Allocation error."); + + for (i=0; iorderedVarNames, + tmpBddIds, NULL, tmpCnfIds, idInitial, edgeInTh, pathLengthTh, fileName, + NULL, &varNewN, &clauseNewN); + + Dddmp_CheckAndGotoLabel (retValue!=DDDMP_SUCCESS, "BDD NOT stored.", + failure); + + fprintf (stdout, "Number of Clauses Stored = %d\n", clauseNewN); + fprintf (stdout, "Number of New Variable Created Storing = %d\n", + varNewN); + fflush (stdout); + + DDDMP_FREE (tmpBddIds); + DDDMP_FREE (tmpCnfIds); + + return (DDDMP_SUCCESS); + + failure: + DDDMP_FREE (tmpBddIds); + DDDMP_FREE (tmpCnfIds); + + return(DDDMP_FAILURE); +} + +/**Function******************************************************************** + + Synopsis [Dynamic Reordering BDDs.] + + Description [Dynamic Reordering BDDs using one of the allowed CUDD + methods.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +DynamicReordering ( + DdManager *ddMgr /* IN: CUDD Manager */ + ) +{ + Cudd_ReorderingType approach = CUDD_REORDER_SIFT; + int method; + + /*------------------------ Read Operation Operands ------------------------*/ + + ReadInt (DDDMP_MESSAGE_REORDERING, &method); + approach = (Cudd_ReorderingType) method; + + Cudd_ReduceHeap (ddMgr, approach, 5); + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Selects variable matching mode.] + + Description [Selects variable matching mode.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +SetLoadMatchmode ( + ) +{ + int sel; + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + fprintf (stdout, "Variable matchmode:\n"); + fprintf (stdout, "Match IDs (1)\n"); + fprintf (stdout, "Match permIDs (2)\n"); + fprintf (stdout, "Match names (must have been loaded) (3)\n"); + fprintf (stdout, "Match auxids (must have been loaded) (4)\n"); + fprintf (stdout, "Match composeids (must have been loaded) (5)\n"); + fprintf (stdout, "Your choice: "); + fflush (stdout); + + fgets (row, DDDMPTEST_MAX_STRING_LENGTH, stdin); + sscanf (row, "%d", &sel); + + switch (sel) { + case 1: + varmatchmode = DDDMP_VAR_MATCHIDS; + break; + case 2: + varmatchmode = DDDMP_VAR_MATCHPERMIDS; + break; + case 3: + varmatchmode = DDDMP_VAR_MATCHNAMES; + break; + case 4: + varmatchmode = DDDMP_VAR_MATCHAUXIDS; + break; + case 5: + varmatchmode = DDDMP_VAR_COMPOSEIDS; + break; + default: + fprintf (stderr, "Wrong choice!\n"); + break; + } + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Complete the internal manager structure for subsequent + BDD/ADD/CNF operations. + ] + + Description [Complete the internal manager structure for subsequent + BDD/ADD/CNF operations. + The phylosophy is simple: to have proper names and ids it is necessary + to load an header before each actual load/store operation. + An header load should initialize variable names, variable ids, + variable compose ids, and variable auxiliary ids for all variables + stored in the file. + This information has to be extended for all variables in the + *current* CUDD manager (before any store operation). + CompleteInfoStruct does this job. + Arrays varIds, varComposeIds, and varAuxIds contain information for + all the variable in the BDD/ADD/CNF while arrays varIdsAll, + varComposeIdsAll, and varAuxIdsAll contain information for *all* + variable in the current CUDD manager. + ] + + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static int +CompleteInfoStruct ( + Dddmp_DecompType ddType /* IN: selects the proper decomp type */, + int nVars /* IN: number of DD variables */, + int nSuppVars /* IN: number of support variables */, + char **suppVarNames /* IN: array of support variable names */, + char **orderedVarNames /* IN: array of variable names */, + int *varIds /* IN: array of variable ids */, + int *varComposeIds /* IN: array of permids ids */, + int *varAuxIds /* IN: array of variable aux ids */, + int nRoots /* IN: number of root in the file */, + dddmpVarInfo_t *varInfo /* IN: Variable Information */ + ) +{ + int i; + char tmpString[DDDMPTEST_MAX_STRING_LENGTH]; + + /*------------------------- Updates Variable Names ------------------------*/ + + DddmpStrArrayFree (varInfo->suppVarNames, varInfo->nSuppVars); + varInfo->suppVarNames = suppVarNames; + + if (varInfo->varNamesFlagUpdate == 1) { + + DddmpStrArrayFree (varInfo->orderedVarNames, varInfo->nVars); + + if (orderedVarNames != NULL) { + varInfo->orderedVarNames = orderedVarNames; + } else { + varInfo->orderedVarNames = DDDMP_ALLOC (char *, nVars); + Dddmp_CheckAndReturn (varInfo->orderedVarNames==NULL, + "Allocation error."); + + for (i=0; iorderedVarNames[i] = NULL; + } + + if (varInfo->suppVarNames != NULL) { + for (i=0; iorderedVarNames[i] = DDDMP_ALLOC (char, + (strlen (varInfo->suppVarNames[i]) + 1)); + strcpy (varInfo->orderedVarNames[i], varInfo->suppVarNames[i]); + } + } + + for (i=0; iorderedVarNames[i] == NULL) { + sprintf (tmpString, "DUMMY%d", i); + varInfo->orderedVarNames[i] = DDDMP_ALLOC (char, + (strlen (tmpString) + 1)); + strcpy (varInfo->orderedVarNames[i], tmpString); + } + } + } + } + + /*------------------------------ Updates IDs ------------------------------*/ + + DDDMP_FREE (varInfo->varIds); + varInfo->varIds = varIds; + + if (varInfo->varIdsFlagUpdate == 1) { + + /* Free Previously Allocated Memory */ + DDDMP_FREE (varInfo->varIdsAll); + + /* Allocate New Memory and Check */ + varInfo->varIdsAll = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (varInfo->varIdsAll==NULL, "Allocation error."); + + /* Set New Values */ + for (i=0; ivarIdsAll[i] = (-1); + } + + if (varInfo->varIds != NULL) { + for (i=0; ivarIdsAll[varInfo->varIds[i]] = varInfo->varIds[i]; + } + } + } + + + /*-------------------------- Updates Compose IDs --------------------------*/ + + DDDMP_FREE (varInfo->varComposeIds); + varInfo->varComposeIds = varComposeIds; + + if (varInfo->varComposeIdsFlagUpdate == 1) { + + /* Free Previously Allocated Memory */ + DDDMP_FREE (varInfo->varComposeIdsAll); + + /* Allocate New Memory and Check */ + varInfo->varComposeIdsAll = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (varInfo->varComposeIdsAll==NULL, + "Allocation error."); + + /* Set New Values */ + for (i=0; ivarComposeIdsAll[i] = (-1); + } + + if (varInfo->varComposeIds != NULL) { + for (i=0; ivarComposeIdsAll[varInfo->varIds[i]] = + varInfo->varComposeIds[i]; + } + } + } + + /*------------------------- Updates Auxiliary IDs -------------------------*/ + + DDDMP_FREE (varInfo->varAuxIds); + varInfo->varAuxIds = varAuxIds; + + if (varInfo->varAuxIdsFlagUpdate == 1) { + + /* Free Previously Allocated Memory */ + DDDMP_FREE (varInfo->varAuxIdsAll); + + /* Allocate New Memory and Check */ + varInfo->varAuxIdsAll = DDDMP_ALLOC (int, nVars); + Dddmp_CheckAndReturn (varInfo->varAuxIdsAll==NULL, "Allocation error."); + + /* Set New Values */ + for (i=0; ivarAuxIdsAll[i] = (-1); + } + + if (varInfo->varAuxIds != NULL) { + for (i=0; ivarAuxIdsAll[varInfo->varIds[i]] = varInfo->varAuxIds[i]; + } + } + } + + /*----------------------------- Updates Sizes -----------------------------*/ + + varInfo->ddType = ddType; + varInfo->nVars = nVars; + varInfo->nSuppVars = nSuppVars; + Dddmp_CheckAndReturn (varInfo->nDdVarsnVars, + "Local Manager with Not Enough Variables."); + varInfo->nRoots = nRoots; + + return (DDDMP_SUCCESS); +} + +/**Function******************************************************************** + + Synopsis [Reads an integer value from standard input.] + + Description [Reads an integer value from standard input.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +ReadInt ( + Dddmp_MessageType message, + int *i + ) +{ + char row[DDDMPTEST_MAX_FILENAME_LENGTH]; + + switch (message) { + case DDDMP_MESSAGE_MANAGER_VAR: + fprintf (stdout, "Number of Variables: "); + break; + case DDDMP_MESSAGE_BDD: + fprintf (stdout, "Which BDDs [0..%d]: ", + DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_BDD_ARRAY: + fprintf (stdout, "Which Array of BDDs [0..%d]: ", + DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_CUBE: + fprintf (stdout, "How many cubes [1..]: "); + break; + case DDDMP_MESSAGE_INDEX: + fprintf (stdout, "Index: "); + break; + case DDDMP_MESSAGE_SOURCE1: + fprintf (stdout, "Source1 [0..%d]: ", DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_SOURCE2: + fprintf (stdout, "Source2 [0..%d]: ", DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_DESTINATION: + fprintf (stdout, "Destination [0..%d]: ", DDDMPTEST_MAX_OPERAND-1); + break; + case DDDMP_MESSAGE_I_ID: + fprintf (stdout, "Initial ID : "); + break; + case DDDMP_MESSAGE_EDGE_MAX: + fprintf (stdout, + "Max Number of Edges (Insert cut-point from there on) : "); + break; + case DDDMP_MESSAGE_LENGHT_MAX: + fprintf (stdout, + "Max BDD-Path Length (Insert cut-point from there on) : "); + break; + case DDDMP_MESSAGE_REORDERING: + fprintf (stdout, "Reordering Approach (1..17): "); + break; + default: + fprintf (stdout, "Input Generic Integer: "); + break; + } + fflush (stdout); + + fgets (row, DDDMPTEST_MAX_STRING_LENGTH, stdin); + sscanf (row, "%d", i); + fflush (stdin); + + return; +} + + +/**Function******************************************************************** + + Synopsis [Reads a string from standard input.] + + Description [Reads a string from standard input.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ + +static void +ReadString ( + Dddmp_MessageType message, + char string[] + ) +{ + char localString[DDDMPTEST_MAX_STRING_LENGTH]; + + switch (message) { + case DDDMP_MESSAGE_PROMPT: + fprintf (stdout, "TestDddmp> "); + break; + case DDDMP_MESSAGE_FILE: + fprintf (stdout, "File : "); + break; + case DDDMP_MESSAGE_OP: + fprintf (stdout, "Operation [or,and,xor,!,buf(=)] : "); + break; + case DDDMP_MESSAGE_FORMAT: + fprintf (stdout, "Format (Node=N, Maxterm=M, Best=B) : "); + break; + default: + fprintf (stdout, "Input Generic String : "); + break; + } + fflush (stdout); + + fgets (localString, DDDMPTEST_MAX_STRING_LENGTH, stdin); + sscanf (localString, "%s", string); + fflush (stdin); + + return; +} + + + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/epd/Makefile b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/epd/Makefile new file mode 100644 index 000000000..3b26bc9a9 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/epd/Makefile @@ -0,0 +1,64 @@ +# $Id$ +# +# epd -- extended precision +#--------------------------------------------------------------------------- +.SUFFIXES: .c .o .u + +CC = gcc +RANLIB = ranlib + +MFLAG = +ICFLAGS = -g -O6 -Wall +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) + +LINTFLAGS = -u -n + +# this is to create the lint library +LINTSWITCH = -o + +P = epd +PSRC = epd.c +PHDR = epd.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) + +WHERE = .. +INCLUDE = $(WHERE)/include + +#--------------------------- + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PSRC) $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +clean: + rm -f *.o *.u .pure *.warnings + +distclean: clean + rm -f lib*.a lib$(P).b llib-l$(P).ln tags *~ *.bak *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/epd/epd.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/epd/epd.c new file mode 100644 index 000000000..14f314fab --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/epd/epd.c @@ -0,0 +1,1344 @@ +/**CFile*********************************************************************** + + FileName [epd.c] + + PackageName [epd] + + Synopsis [Arithmetic functions with extended double precision.] + + Description [] + + SeeAlso [] + + Author [In-Ho Moon] + + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: epd.c,v 1.10 2004/08/13 18:20:30 fabio Exp $] + +******************************************************************************/ + +#include +#include +#include +#include +#include "util.h" +#include "epd.h" + + +/**Function******************************************************************** + + Synopsis [Allocates an EpDouble struct.] + + Description [Allocates an EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +EpDouble * +EpdAlloc(void) +{ + EpDouble *epd; + + epd = ALLOC(EpDouble, 1); + return(epd); +} + + +/**Function******************************************************************** + + Synopsis [Compares two EpDouble struct.] + + Description [Compares two EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdCmp(const char *key1, const char *key2) +{ + EpDouble *epd1 = (EpDouble *) key1; + EpDouble *epd2 = (EpDouble *) key2; + if (epd1->type.value != epd2->type.value || + epd1->exponent != epd2->exponent) { + return(1); + } + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Frees an EpDouble struct.] + + Description [Frees an EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdFree(EpDouble *epd) +{ + FREE(epd); +} + + +/**Function******************************************************************** + + Synopsis [Converts an arbitrary precision double value to a string.] + + Description [Converts an arbitrary precision double value to a string.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdGetString(EpDouble *epd, char *str) +{ + double value; + int exponent; + char *pos; + + if (IsNanDouble(epd->type.value)) { + sprintf(str, "NaN"); + return; + } else if (IsInfDouble(epd->type.value)) { + if (epd->type.bits.sign == 1) + sprintf(str, "-Inf"); + else + sprintf(str, "Inf"); + return; + } + + assert(epd->type.bits.exponent == EPD_MAX_BIN || + epd->type.bits.exponent == 0); + + EpdGetValueAndDecimalExponent(epd, &value, &exponent); + sprintf(str, "%e", value); + pos = strstr(str, "e"); + if (exponent >= 0) { + if (exponent < 10) + sprintf(pos + 1, "+0%d", exponent); + else + sprintf(pos + 1, "+%d", exponent); + } else { + exponent *= -1; + if (exponent < 10) + sprintf(pos + 1, "-0%d", exponent); + else + sprintf(pos + 1, "-%d", exponent); + } +} + + +/**Function******************************************************************** + + Synopsis [Converts double to EpDouble struct.] + + Description [Converts double to EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdConvert(double value, EpDouble *epd) +{ + epd->type.value = value; + epd->exponent = 0; + EpdNormalize(epd); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply(EpDouble *epd1, double value) +{ + EpDouble epd2; + double tmp; + int exponent; + + if (EpdIsNan(epd1) || IsNanDouble(value)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || IsInfDouble(value)) { + int sign; + + EpdConvert(value, &epd2); + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + EpdMakeInf(epd1, sign); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + + EpdConvert(value, &epd2); + tmp = epd1->type.value * epd2.type.value; + exponent = epd1->exponent + epd2.exponent; + epd1->type.value = tmp; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply2(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd1, sign); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + value = epd1->type.value * epd2->type.value; + exponent = epd1->exponent + epd2->exponent; + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply2Decimal(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd1, sign); + return; + } + + value = epd1->type.value * epd2->type.value; + exponent = epd1->exponent + epd2->exponent; + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalizeDecimal(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd3, sign); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + epd3->type.value = epd1->type.value * epd2->type.value; + epd3->exponent = epd1->exponent + epd2->exponent; + EpdNormalize(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Multiplies two arbitrary precision double values.] + + Description [Multiplies two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMultiply3Decimal(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd3, sign); + return; + } + + epd3->type.value = epd1->type.value * epd2->type.value; + epd3->exponent = epd1->exponent + epd2->exponent; + EpdNormalizeDecimal(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Divides two arbitrary precision double values.] + + Description [Divides two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdDivide(EpDouble *epd1, double value) +{ + EpDouble epd2; + double tmp; + int exponent; + + if (EpdIsNan(epd1) || IsNanDouble(value)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || IsInfDouble(value)) { + int sign; + + EpdConvert(value, &epd2); + if (EpdIsInf(epd1) && IsInfDouble(value)) { + EpdMakeNan(epd1); + } else if (EpdIsInf(epd1)) { + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + EpdMakeInf(epd1, sign); + } else { + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + EpdMakeZero(epd1, sign); + } + return; + } + + if (value == 0.0) { + EpdMakeNan(epd1); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + + EpdConvert(value, &epd2); + tmp = epd1->type.value / epd2.type.value; + exponent = epd1->exponent - epd2.exponent; + epd1->type.value = tmp; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Divides two arbitrary precision double values.] + + Description [Divides two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdDivide2(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + EpdMakeNan(epd1); + } else if (EpdIsInf(epd1)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd1, sign); + } else { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeZero(epd1, sign); + } + return; + } + + if (epd2->type.value == 0.0) { + EpdMakeNan(epd1); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + value = epd1->type.value / epd2->type.value; + exponent = epd1->exponent - epd2->exponent; + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Divides two arbitrary precision double values.] + + Description [Divides two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdDivide3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd3); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + EpdMakeNan(epd3); + } else if (EpdIsInf(epd1)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeInf(epd3, sign); + } else { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + EpdMakeZero(epd3, sign); + } + return; + } + + if (epd2->type.value == 0.0) { + EpdMakeNan(epd3); + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + epd3->type.value = epd1->type.value / epd2->type.value; + epd3->exponent = epd1->exponent - epd2->exponent; + EpdNormalize(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Adds two arbitrary precision double values.] + + Description [Adds two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdAdd(EpDouble *epd1, double value) +{ + EpDouble epd2; + double tmp; + int exponent, diff; + + if (EpdIsNan(epd1) || IsNanDouble(value)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || IsInfDouble(value)) { + int sign; + + EpdConvert(value, &epd2); + if (EpdIsInf(epd1) && IsInfDouble(value)) { + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + if (sign == 1) + EpdMakeNan(epd1); + } else if (EpdIsInf(&epd2)) { + EpdCopy(&epd2, epd1); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + + EpdConvert(value, &epd2); + if (epd1->exponent > epd2.exponent) { + diff = epd1->exponent - epd2.exponent; + if (diff <= EPD_MAX_BIN) + tmp = epd1->type.value + epd2.type.value / pow((double)2.0, (double)diff); + else + tmp = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2.exponent) { + diff = epd2.exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) + tmp = epd1->type.value / pow((double)2.0, (double)diff) + epd2.type.value; + else + tmp = epd2.type.value; + exponent = epd2.exponent; + } else { + tmp = epd1->type.value + epd2.type.value; + exponent = epd1->exponent; + } + epd1->type.value = tmp; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Adds two arbitrary precision double values.] + + Description [Adds two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdAdd2(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent, diff; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + if (sign == 1) + EpdMakeNan(epd1); + } else if (EpdIsInf(epd2)) { + EpdCopy(epd2, epd1); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + if (epd1->exponent > epd2->exponent) { + diff = epd1->exponent - epd2->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value + + epd2->type.value / pow((double)2.0, (double)diff); + } else + value = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2->exponent) { + diff = epd2->exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value / pow((double)2.0, (double)diff) + + epd2->type.value; + } else + value = epd2->type.value; + exponent = epd2->exponent; + } else { + value = epd1->type.value + epd2->type.value; + exponent = epd1->exponent; + } + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Adds two arbitrary precision double values.] + + Description [Adds two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + double value; + int exponent, diff; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd3); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + if (sign == 1) + EpdMakeNan(epd3); + else + EpdCopy(epd1, epd3); + } else if (EpdIsInf(epd1)) { + EpdCopy(epd1, epd3); + } else { + EpdCopy(epd2, epd3); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + if (epd1->exponent > epd2->exponent) { + diff = epd1->exponent - epd2->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value + + epd2->type.value / pow((double)2.0, (double)diff); + } else + value = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2->exponent) { + diff = epd2->exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value / pow((double)2.0, (double)diff) + + epd2->type.value; + } else + value = epd2->type.value; + exponent = epd2->exponent; + } else { + value = epd1->type.value + epd2->type.value; + exponent = epd1->exponent; + } + epd3->type.value = value; + epd3->exponent = exponent; + EpdNormalize(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Subtracts two arbitrary precision double values.] + + Description [Subtracts two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdSubtract(EpDouble *epd1, double value) +{ + EpDouble epd2; + double tmp; + int exponent, diff; + + if (EpdIsNan(epd1) || IsNanDouble(value)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || IsInfDouble(value)) { + int sign; + + EpdConvert(value, &epd2); + if (EpdIsInf(epd1) && IsInfDouble(value)) { + sign = epd1->type.bits.sign ^ epd2.type.bits.sign; + if (sign == 0) + EpdMakeNan(epd1); + } else if (EpdIsInf(&epd2)) { + EpdCopy(&epd2, epd1); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + + EpdConvert(value, &epd2); + if (epd1->exponent > epd2.exponent) { + diff = epd1->exponent - epd2.exponent; + if (diff <= EPD_MAX_BIN) + tmp = epd1->type.value - epd2.type.value / pow((double)2.0, (double)diff); + else + tmp = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2.exponent) { + diff = epd2.exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) + tmp = epd1->type.value / pow((double)2.0, (double)diff) - epd2.type.value; + else + tmp = epd2.type.value * (double)(-1.0); + exponent = epd2.exponent; + } else { + tmp = epd1->type.value - epd2.type.value; + exponent = epd1->exponent; + } + epd1->type.value = tmp; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Subtracts two arbitrary precision double values.] + + Description [Subtracts two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdSubtract2(EpDouble *epd1, EpDouble *epd2) +{ + double value; + int exponent, diff; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd1); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + if (sign == 0) + EpdMakeNan(epd1); + } else if (EpdIsInf(epd2)) { + EpdCopy(epd2, epd1); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + if (epd1->exponent > epd2->exponent) { + diff = epd1->exponent - epd2->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value - + epd2->type.value / pow((double)2.0, (double)diff); + } else + value = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2->exponent) { + diff = epd2->exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value / pow((double)2.0, (double)diff) - + epd2->type.value; + } else + value = epd2->type.value * (double)(-1.0); + exponent = epd2->exponent; + } else { + value = epd1->type.value - epd2->type.value; + exponent = epd1->exponent; + } + epd1->type.value = value; + epd1->exponent = exponent; + EpdNormalize(epd1); +} + + +/**Function******************************************************************** + + Synopsis [Subtracts two arbitrary precision double values.] + + Description [Subtracts two arbitrary precision double values.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) +{ + double value; + int exponent, diff; + + if (EpdIsNan(epd1) || EpdIsNan(epd2)) { + EpdMakeNan(epd3); + return; + } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { + int sign; + + if (EpdIsInf(epd1) && EpdIsInf(epd2)) { + sign = epd1->type.bits.sign ^ epd2->type.bits.sign; + if (sign == 0) + EpdCopy(epd1, epd3); + else + EpdMakeNan(epd3); + } else if (EpdIsInf(epd1)) { + EpdCopy(epd1, epd1); + } else { + sign = epd2->type.bits.sign ^ 0x1; + EpdMakeInf(epd3, sign); + } + return; + } + + assert(epd1->type.bits.exponent == EPD_MAX_BIN); + assert(epd2->type.bits.exponent == EPD_MAX_BIN); + + if (epd1->exponent > epd2->exponent) { + diff = epd1->exponent - epd2->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value - + epd2->type.value / pow((double)2.0, (double)diff); + } else + value = epd1->type.value; + exponent = epd1->exponent; + } else if (epd1->exponent < epd2->exponent) { + diff = epd2->exponent - epd1->exponent; + if (diff <= EPD_MAX_BIN) { + value = epd1->type.value / pow((double)2.0, (double)diff) - + epd2->type.value; + } else + value = epd2->type.value * (double)(-1.0); + exponent = epd2->exponent; + } else { + value = epd1->type.value - epd2->type.value; + exponent = epd1->exponent; + } + epd3->type.value = value; + epd3->exponent = exponent; + EpdNormalize(epd3); +} + + +/**Function******************************************************************** + + Synopsis [Computes arbitrary precision pow of base 2.] + + Description [Computes arbitrary precision pow of base 2.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdPow2(int n, EpDouble *epd) +{ + if (n <= EPD_MAX_BIN) { + EpdConvert(pow((double)2.0, (double)n), epd); + } else { + EpDouble epd1, epd2; + int n1, n2; + + n1 = n / 2; + n2 = n - n1; + EpdPow2(n1, &epd1); + EpdPow2(n2, &epd2); + EpdMultiply3(&epd1, &epd2, epd); + } +} + + +/**Function******************************************************************** + + Synopsis [Computes arbitrary precision pow of base 2.] + + Description [Computes arbitrary precision pow of base 2.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdPow2Decimal(int n, EpDouble *epd) +{ + if (n <= EPD_MAX_BIN) { + epd->type.value = pow((double)2.0, (double)n); + epd->exponent = 0; + EpdNormalizeDecimal(epd); + } else { + EpDouble epd1, epd2; + int n1, n2; + + n1 = n / 2; + n2 = n - n1; + EpdPow2Decimal(n1, &epd1); + EpdPow2Decimal(n2, &epd2); + EpdMultiply3Decimal(&epd1, &epd2, epd); + } +} + + +/**Function******************************************************************** + + Synopsis [Normalize an arbitrary precision double value.] + + Description [Normalize an arbitrary precision double value.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdNormalize(EpDouble *epd) +{ + int exponent; + + if (IsNanOrInfDouble(epd->type.value)) { + epd->exponent = 0; + return; + } + + exponent = EpdGetExponent(epd->type.value); + if (exponent == EPD_MAX_BIN) + return; + exponent -= EPD_MAX_BIN; + epd->type.bits.exponent = EPD_MAX_BIN; + epd->exponent += exponent; +} + + +/**Function******************************************************************** + + Synopsis [Normalize an arbitrary precision double value.] + + Description [Normalize an arbitrary precision double value.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdNormalizeDecimal(EpDouble *epd) +{ + int exponent; + + if (IsNanOrInfDouble(epd->type.value)) { + epd->exponent = 0; + return; + } + + exponent = EpdGetExponentDecimal(epd->type.value); + epd->type.value /= pow((double)10.0, (double)exponent); + epd->exponent += exponent; +} + + +/**Function******************************************************************** + + Synopsis [Returns value and decimal exponent of EpDouble.] + + Description [Returns value and decimal exponent of EpDouble.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdGetValueAndDecimalExponent(EpDouble *epd, double *value, int *exponent) +{ + EpDouble epd1, epd2; + + if (EpdIsNanOrInf(epd)) + return; + + if (EpdIsZero(epd)) { + *value = 0.0; + *exponent = 0; + return; + } + + epd1.type.value = epd->type.value; + epd1.exponent = 0; + EpdPow2Decimal(epd->exponent, &epd2); + EpdMultiply2Decimal(&epd1, &epd2); + + *value = epd1.type.value; + *exponent = epd1.exponent; +} + +/**Function******************************************************************** + + Synopsis [Returns the exponent value of a double.] + + Description [Returns the exponent value of a double.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdGetExponent(double value) +{ + int exponent; + EpDouble epd; + + epd.type.value = value; + exponent = epd.type.bits.exponent; + return(exponent); +} + + +/**Function******************************************************************** + + Synopsis [Returns the decimal exponent value of a double.] + + Description [Returns the decimal exponent value of a double.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdGetExponentDecimal(double value) +{ + char *pos, str[24]; + int exponent; + + sprintf(str, "%E", value); + pos = strstr(str, "E"); + sscanf(pos, "E%d", &exponent); + return(exponent); +} + + +/**Function******************************************************************** + + Synopsis [Makes EpDouble Inf.] + + Description [Makes EpDouble Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMakeInf(EpDouble *epd, int sign) +{ + epd->type.bits.mantissa1 = 0; + epd->type.bits.mantissa0 = 0; + epd->type.bits.exponent = EPD_EXP_INF; + epd->type.bits.sign = sign; + epd->exponent = 0; +} + + +/**Function******************************************************************** + + Synopsis [Makes EpDouble Zero.] + + Description [Makes EpDouble Zero.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMakeZero(EpDouble *epd, int sign) +{ + epd->type.bits.mantissa1 = 0; + epd->type.bits.mantissa0 = 0; + epd->type.bits.exponent = 0; + epd->type.bits.sign = sign; + epd->exponent = 0; +} + + +/**Function******************************************************************** + + Synopsis [Makes EpDouble NaN.] + + Description [Makes EpDouble NaN.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdMakeNan(EpDouble *epd) +{ + epd->type.nan.mantissa1 = 0; + epd->type.nan.mantissa0 = 0; + epd->type.nan.quiet_bit = 1; + epd->type.nan.exponent = EPD_EXP_INF; + epd->type.nan.sign = 1; + epd->exponent = 0; +} + + +/**Function******************************************************************** + + Synopsis [Copies a EpDouble struct.] + + Description [Copies a EpDouble struct.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void +EpdCopy(EpDouble *from, EpDouble *to) +{ + to->type.value = from->type.value; + to->exponent = from->exponent; +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is Inf.] + + Description [Checks whether the value is Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdIsInf(EpDouble *epd) +{ + return(IsInfDouble(epd->type.value)); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is Zero.] + + Description [Checks whether the value is Zero.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdIsZero(EpDouble *epd) +{ + if (epd->type.value == 0.0) + return(1); + else + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is NaN.] + + Description [Checks whether the value is NaN.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdIsNan(EpDouble *epd) +{ + return(IsNanDouble(epd->type.value)); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is NaN or Inf.] + + Description [Checks whether the value is NaN or Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +EpdIsNanOrInf(EpDouble *epd) +{ + return(IsNanOrInfDouble(epd->type.value)); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is Inf.] + + Description [Checks whether the value is Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +IsInfDouble(double value) +{ + EpType val; + + val.value = value; + if (val.bits.exponent == EPD_EXP_INF && + val.bits.mantissa0 == 0 && + val.bits.mantissa1 == 0) { + if (val.bits.sign == 0) + return(1); + else + return(-1); + } + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is NaN.] + + Description [Checks whether the value is NaN.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +IsNanDouble(double value) +{ + EpType val; + + val.value = value; + if (val.nan.exponent == EPD_EXP_INF && + val.nan.sign == 1 && + val.nan.quiet_bit == 1 && + val.nan.mantissa0 == 0 && + val.nan.mantissa1 == 0) { + return(1); + } + return(0); +} + + +/**Function******************************************************************** + + Synopsis [Checks whether the value is NaN or Inf.] + + Description [Checks whether the value is NaN or Inf.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +IsNanOrInfDouble(double value) +{ + EpType val; + + val.value = value; + if (val.nan.exponent == EPD_EXP_INF && + val.nan.mantissa0 == 0 && + val.nan.mantissa1 == 0 && + (val.nan.sign == 1 || val.nan.quiet_bit == 0)) { + return(1); + } + return(0); +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cudd.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cudd.h new file mode 100644 index 000000000..d60d0c8f8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cudd.h @@ -0,0 +1,1082 @@ +/**CHeaderFile***************************************************************** + + FileName [cudd.h] + + PackageName [cudd] + + Synopsis [The University of Colorado decision diagram package.] + + Description [External functions and data strucures of the CUDD package. +
                            +
                          • To turn on the gathering of statistics, define DD_STATS. +
                          • To link with mis, define DD_MIS. +
                          + Modified by Abelardo Pardo to interface it to VIS. + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: cudd.h,v 1.180 2012/02/05 01:07:18 fabio Exp $] + +******************************************************************************/ + +#ifndef _CUDD +#define _CUDD + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include "mtr.h" +#include "epd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define CUDD_VERSION "2.5.0" + +#ifndef SIZEOF_VOID_P +#define SIZEOF_VOID_P 4 +#endif +#ifndef SIZEOF_INT +#define SIZEOF_INT 4 +#endif +#ifndef SIZEOF_LONG +#define SIZEOF_LONG 4 +#endif + +#define CUDD_TRUE 1 +#define CUDD_FALSE 0 + +#define CUDD_VALUE_TYPE double +#define CUDD_OUT_OF_MEM -1 +/* The sizes of the subtables and the cache must be powers of two. */ +#define CUDD_UNIQUE_SLOTS 256 /* initial size of subtables */ +#define CUDD_CACHE_SLOTS 262144 /* default size of the cache */ + +/* Constants for residue functions. */ +#define CUDD_RESIDUE_DEFAULT 0 +#define CUDD_RESIDUE_MSB 1 +#define CUDD_RESIDUE_TC 2 + +/* CUDD_MAXINDEX is defined in such a way that on 32-bit and 64-bit +** machines one can cast an index to (int) without generating a negative +** number. +*/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define CUDD_MAXINDEX (((DdHalfWord) ~0) >> 1) +#else +#define CUDD_MAXINDEX ((DdHalfWord) ~0) +#endif + +/* CUDD_CONST_INDEX is the index of constant nodes. Currently this +** is a synonim for CUDD_MAXINDEX. */ +#define CUDD_CONST_INDEX CUDD_MAXINDEX + +/* These constants define the digits used in the representation of +** arbitrary precision integers. The configurations tested use 8, 16, +** and 32 bits for each digit. The typedefs should be in agreement +** with these definitions. +*/ +#if SIZEOF_LONG == 8 +#define DD_APA_BITS 32 +#define DD_APA_BASE (1L << DD_APA_BITS) +#define DD_APA_HEXPRINT "%08x" +#else +#define DD_APA_BITS 16 +#define DD_APA_BASE (1 << DD_APA_BITS) +#define DD_APA_HEXPRINT "%04x" +#endif +#define DD_APA_MASK (DD_APA_BASE - 1) + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/**Enum************************************************************************ + + Synopsis [Type of reordering algorithm.] + + Description [Type of reordering algorithm.] + +******************************************************************************/ +typedef enum { + CUDD_REORDER_SAME, + CUDD_REORDER_NONE, + CUDD_REORDER_RANDOM, + CUDD_REORDER_RANDOM_PIVOT, + CUDD_REORDER_SIFT, + CUDD_REORDER_SIFT_CONVERGE, + CUDD_REORDER_SYMM_SIFT, + CUDD_REORDER_SYMM_SIFT_CONV, + CUDD_REORDER_WINDOW2, + CUDD_REORDER_WINDOW3, + CUDD_REORDER_WINDOW4, + CUDD_REORDER_WINDOW2_CONV, + CUDD_REORDER_WINDOW3_CONV, + CUDD_REORDER_WINDOW4_CONV, + CUDD_REORDER_GROUP_SIFT, + CUDD_REORDER_GROUP_SIFT_CONV, + CUDD_REORDER_ANNEALING, + CUDD_REORDER_GENETIC, + CUDD_REORDER_LINEAR, + CUDD_REORDER_LINEAR_CONVERGE, + CUDD_REORDER_LAZY_SIFT, + CUDD_REORDER_EXACT +} Cudd_ReorderingType; + + +/**Enum************************************************************************ + + Synopsis [Type of aggregation methods.] + + Description [Type of aggregation methods.] + +******************************************************************************/ +typedef enum { + CUDD_NO_CHECK, + CUDD_GROUP_CHECK, + CUDD_GROUP_CHECK2, + CUDD_GROUP_CHECK3, + CUDD_GROUP_CHECK4, + CUDD_GROUP_CHECK5, + CUDD_GROUP_CHECK6, + CUDD_GROUP_CHECK7, + CUDD_GROUP_CHECK8, + CUDD_GROUP_CHECK9 +} Cudd_AggregationType; + + +/**Enum************************************************************************ + + Synopsis [Type of hooks.] + + Description [Type of hooks.] + +******************************************************************************/ +typedef enum { + CUDD_PRE_GC_HOOK, + CUDD_POST_GC_HOOK, + CUDD_PRE_REORDERING_HOOK, + CUDD_POST_REORDERING_HOOK +} Cudd_HookType; + + +/**Enum************************************************************************ + + Synopsis [Type of error codes.] + + Description [Type of error codes.] + +******************************************************************************/ +typedef enum { + CUDD_NO_ERROR, + CUDD_MEMORY_OUT, + CUDD_TOO_MANY_NODES, + CUDD_MAX_MEM_EXCEEDED, + CUDD_TIMEOUT_EXPIRED, + CUDD_INVALID_ARG, + CUDD_INTERNAL_ERROR +} Cudd_ErrorType; + + +/**Enum************************************************************************ + + Synopsis [Group type for lazy sifting.] + + Description [Group type for lazy sifting.] + +******************************************************************************/ +typedef enum { + CUDD_LAZY_NONE, + CUDD_LAZY_SOFT_GROUP, + CUDD_LAZY_HARD_GROUP, + CUDD_LAZY_UNGROUP +} Cudd_LazyGroupType; + + +/**Enum************************************************************************ + + Synopsis [Variable type.] + + Description [Variable type. Currently used only in lazy sifting.] + +******************************************************************************/ +typedef enum { + CUDD_VAR_PRIMARY_INPUT, + CUDD_VAR_PRESENT_STATE, + CUDD_VAR_NEXT_STATE +} Cudd_VariableType; + + +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +typedef unsigned int DdHalfWord; +#else +typedef unsigned short DdHalfWord; +#endif + +typedef struct DdNode DdNode; + +typedef struct DdChildren { + struct DdNode *T; + struct DdNode *E; +} DdChildren; + +/* The DdNode structure is the only one exported out of the package */ +struct DdNode { + DdHalfWord index; + DdHalfWord ref; /* reference count */ + DdNode *next; /* next pointer for unique table */ + union { + CUDD_VALUE_TYPE value; /* for constant nodes */ + DdChildren kids; /* for internal nodes */ + } type; +}; + +typedef struct DdManager DdManager; + +typedef struct DdGen DdGen; + +/* These typedefs for arbitrary precision arithmetic should agree with +** the corresponding constant definitions above. */ +#if SIZEOF_LONG == 8 +typedef unsigned int DdApaDigit; +typedef unsigned long int DdApaDoubleDigit; +#else +typedef unsigned short int DdApaDigit; +typedef unsigned int DdApaDoubleDigit; +#endif +typedef DdApaDigit * DdApaNumber; + +/* Return type for function computing two-literal clauses. */ +typedef struct DdTlcInfo DdTlcInfo; + +/* Type of hook function. */ +typedef int (*DD_HFP)(DdManager *, const char *, void *); +/* Type of priority function */ +typedef DdNode * (*DD_PRFP)(DdManager * , int, DdNode **, DdNode **, + DdNode **); +/* Type of apply operator. */ +typedef DdNode * (*DD_AOP)(DdManager *, DdNode **, DdNode **); +/* Type of monadic apply operator. */ +typedef DdNode * (*DD_MAOP)(DdManager *, DdNode *); +/* Types of cache tag functions. */ +typedef DdNode * (*DD_CTFP)(DdManager *, DdNode *, DdNode *); +typedef DdNode * (*DD_CTFP1)(DdManager *, DdNode *); +/* Type of memory-out function. */ +typedef void (*DD_OOMFP)(long); +/* Type of comparison function for qsort. */ +typedef int (*DD_QSFP)(const void *, const void *); + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if the node is a constant node.] + + Description [Returns 1 if the node is a constant node (rather than an + internal node). All constant nodes have the same index + (CUDD_CONST_INDEX). The pointer passed to Cudd_IsConstant may be either + regular or complemented.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define Cudd_IsConstant(node) ((Cudd_Regular(node))->index == CUDD_CONST_INDEX) + + +/**Macro*********************************************************************** + + Synopsis [Complements a DD.] + + Description [Complements a DD by flipping the complement attribute of + the pointer (the least significant bit).] + + SideEffects [none] + + SeeAlso [Cudd_NotCond] + +******************************************************************************/ +#define Cudd_Not(node) ((DdNode *)((long)(node) ^ 01)) + + +/**Macro*********************************************************************** + + Synopsis [Complements a DD if a condition is true.] + + Description [Complements a DD if condition c is true; c should be + either 0 or 1, because it is used directly (for efficiency). If in + doubt on the values c may take, use "(c) ? Cudd_Not(node) : node".] + + SideEffects [none] + + SeeAlso [Cudd_Not] + +******************************************************************************/ +#define Cudd_NotCond(node,c) ((DdNode *)((long)(node) ^ (c))) + + +/**Macro*********************************************************************** + + Synopsis [Returns the regular version of a pointer.] + + Description [] + + SideEffects [none] + + SeeAlso [Cudd_Complement Cudd_IsComplement] + +******************************************************************************/ +#define Cudd_Regular(node) ((DdNode *)((unsigned long)(node) & ~01)) + + +/**Macro*********************************************************************** + + Synopsis [Returns the complemented version of a pointer.] + + Description [] + + SideEffects [none] + + SeeAlso [Cudd_Regular Cudd_IsComplement] + +******************************************************************************/ +#define Cudd_Complement(node) ((DdNode *)((unsigned long)(node) | 01)) + + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if a pointer is complemented.] + + Description [] + + SideEffects [none] + + SeeAlso [Cudd_Regular Cudd_Complement] + +******************************************************************************/ +#define Cudd_IsComplement(node) ((int) ((long) (node) & 01)) + + +/**Macro*********************************************************************** + + Synopsis [Returns the then child of an internal node.] + + Description [Returns the then child of an internal node. If + node is a constant node, the result is unpredictable.] + + SideEffects [none] + + SeeAlso [Cudd_E Cudd_V] + +******************************************************************************/ +#define Cudd_T(node) ((Cudd_Regular(node))->type.kids.T) + + +/**Macro*********************************************************************** + + Synopsis [Returns the else child of an internal node.] + + Description [Returns the else child of an internal node. If + node is a constant node, the result is unpredictable.] + + SideEffects [none] + + SeeAlso [Cudd_T Cudd_V] + +******************************************************************************/ +#define Cudd_E(node) ((Cudd_Regular(node))->type.kids.E) + + +/**Macro*********************************************************************** + + Synopsis [Returns the value of a constant node.] + + Description [Returns the value of a constant node. If + node is an internal node, the result is unpredictable.] + + SideEffects [none] + + SeeAlso [Cudd_T Cudd_E] + +******************************************************************************/ +#define Cudd_V(node) ((Cudd_Regular(node))->type.value) + + +/**Macro*********************************************************************** + + Synopsis [Returns the current position in the order of variable + index.] + + Description [Returns the current position in the order of variable + index. This macro is obsolete and is kept for compatibility. New + applications should use Cudd_ReadPerm instead.] + + SideEffects [none] + + SeeAlso [Cudd_ReadPerm] + +******************************************************************************/ +#define Cudd_ReadIndex(dd,index) (Cudd_ReadPerm(dd,index)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the cubes of a decision diagram.] + + Description [Iterates over the cubes of a decision diagram f. +
                            +
                          • DdManager *manager; +
                          • DdNode *f; +
                          • DdGen *gen; +
                          • int *cube; +
                          • CUDD_VALUE_TYPE value; +
                          + Cudd_ForeachCube allocates and frees the generator. Therefore the + application should not try to do that. Also, the cube is freed at the + end of Cudd_ForeachCube and hence is not available outside of the loop.

                          + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_GenFree + Cudd_IsGenEmpty Cudd_AutodynDisable] + +******************************************************************************/ +#define Cudd_ForeachCube(manager, f, gen, cube, value)\ + for((gen) = Cudd_FirstCube(manager, f, &cube, &value);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : CUDD_TRUE;\ + (void) Cudd_NextCube(gen, &cube, &value)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the primes of a Boolean function.] + + Description [Iterates over the primes of a Boolean function producing + a prime and irredundant cover. +

                            +
                          • DdManager *manager; +
                          • DdNode *l; +
                          • DdNode *u; +
                          • DdGen *gen; +
                          • int *cube; +
                          + The Boolean function is described by an upper bound and a lower bound. If + the function is completely specified, the two bounds coincide. + Cudd_ForeachPrime allocates and frees the generator. Therefore the + application should not try to do that. Also, the cube is freed at the + end of Cudd_ForeachPrime and hence is not available outside of the loop.

                          + CAUTION: It is a mistake to change a diagram on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_ForeachCube Cudd_FirstPrime Cudd_NextPrime Cudd_GenFree + Cudd_IsGenEmpty] + +******************************************************************************/ +#define Cudd_ForeachPrime(manager, l, u, gen, cube)\ + for((gen) = Cudd_FirstPrime(manager, l, u, &cube);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : CUDD_TRUE;\ + (void) Cudd_NextPrime(gen, &cube)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the nodes of a decision diagram.] + + Description [Iterates over the nodes of a decision diagram f. +

                            +
                          • DdManager *manager; +
                          • DdNode *f; +
                          • DdGen *gen; +
                          • DdNode *node; +
                          + The nodes are returned in a seemingly random order. + Cudd_ForeachNode allocates and frees the generator. Therefore the + application should not try to do that.

                          + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_ForeachCube Cudd_FirstNode Cudd_NextNode Cudd_GenFree + Cudd_IsGenEmpty Cudd_AutodynDisable] + +******************************************************************************/ +#define Cudd_ForeachNode(manager, f, gen, node)\ + for((gen) = Cudd_FirstNode(manager, f, &node);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : CUDD_TRUE;\ + (void) Cudd_NextNode(gen, &node)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the paths of a ZDD.] + + Description [Iterates over the paths of a ZDD f. +

                            +
                          • DdManager *manager; +
                          • DdNode *f; +
                          • DdGen *gen; +
                          • int *path; +
                          + Cudd_zddForeachPath allocates and frees the generator. Therefore the + application should not try to do that. Also, the path is freed at the + end of Cudd_zddForeachPath and hence is not available outside of the loop.

                          + CAUTION: It is assumed that dynamic reordering will not occur while + there are open generators. It is the user's responsibility to make sure + that dynamic reordering does not occur. As long as new nodes are not created + during generation, and dynamic reordering is not called explicitly, + dynamic reordering will not occur. Alternatively, it is sufficient to + disable dynamic reordering. It is a mistake to dispose of a diagram + on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_zddFirstPath Cudd_zddNextPath Cudd_GenFree + Cudd_IsGenEmpty Cudd_AutodynDisable] + +******************************************************************************/ +#define Cudd_zddForeachPath(manager, f, gen, path)\ + for((gen) = Cudd_zddFirstPath(manager, f, &path);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : CUDD_TRUE;\ + (void) Cudd_zddNextPath(gen, &path)) + + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern DdNode * Cudd_addNewVar (DdManager *dd); +extern DdNode * Cudd_addNewVarAtLevel (DdManager *dd, int level); +extern DdNode * Cudd_bddNewVar (DdManager *dd); +extern DdNode * Cudd_bddNewVarAtLevel (DdManager *dd, int level); +extern DdNode * Cudd_addIthVar (DdManager *dd, int i); +extern DdNode * Cudd_bddIthVar (DdManager *dd, int i); +extern DdNode * Cudd_zddIthVar (DdManager *dd, int i); +extern int Cudd_zddVarsFromBddVars (DdManager *dd, int multiplicity); +extern DdNode * Cudd_addConst (DdManager *dd, CUDD_VALUE_TYPE c); +extern int Cudd_IsNonConstant (DdNode *f); +extern unsigned long Cudd_ReadStartTime(DdManager *unique); +extern unsigned long Cudd_ReadElapsedTime(DdManager *unique); +extern void Cudd_SetStartTime(DdManager *unique, unsigned long st); +extern void Cudd_ResetStartTime(DdManager *unique); +extern unsigned long Cudd_ReadTimeLimit(DdManager *unique); +extern void Cudd_SetTimeLimit(DdManager *unique, unsigned long tl); +extern void Cudd_UpdateTimeLimit(DdManager * unique); +extern void Cudd_IncreaseTimeLimit(DdManager * unique, unsigned long increase); +extern void Cudd_UnsetTimeLimit(DdManager *unique); +extern int Cudd_TimeLimited(DdManager *unique); +extern void Cudd_AutodynEnable (DdManager *unique, Cudd_ReorderingType method); +extern void Cudd_AutodynDisable (DdManager *unique); +extern int Cudd_ReorderingStatus (DdManager *unique, Cudd_ReorderingType *method); +extern void Cudd_AutodynEnableZdd (DdManager *unique, Cudd_ReorderingType method); +extern void Cudd_AutodynDisableZdd (DdManager *unique); +extern int Cudd_ReorderingStatusZdd (DdManager *unique, Cudd_ReorderingType *method); +extern int Cudd_zddRealignmentEnabled (DdManager *unique); +extern void Cudd_zddRealignEnable (DdManager *unique); +extern void Cudd_zddRealignDisable (DdManager *unique); +extern int Cudd_bddRealignmentEnabled (DdManager *unique); +extern void Cudd_bddRealignEnable (DdManager *unique); +extern void Cudd_bddRealignDisable (DdManager *unique); +extern DdNode * Cudd_ReadOne (DdManager *dd); +extern DdNode * Cudd_ReadZddOne (DdManager *dd, int i); +extern DdNode * Cudd_ReadZero (DdManager *dd); +extern DdNode * Cudd_ReadLogicZero (DdManager *dd); +extern DdNode * Cudd_ReadPlusInfinity (DdManager *dd); +extern DdNode * Cudd_ReadMinusInfinity (DdManager *dd); +extern DdNode * Cudd_ReadBackground (DdManager *dd); +extern void Cudd_SetBackground (DdManager *dd, DdNode *bck); +extern unsigned int Cudd_ReadCacheSlots (DdManager *dd); +extern double Cudd_ReadCacheUsedSlots (DdManager * dd); +extern double Cudd_ReadCacheLookUps (DdManager *dd); +extern double Cudd_ReadCacheHits (DdManager *dd); +extern double Cudd_ReadRecursiveCalls (DdManager * dd); +extern unsigned int Cudd_ReadMinHit (DdManager *dd); +extern void Cudd_SetMinHit (DdManager *dd, unsigned int hr); +extern unsigned int Cudd_ReadLooseUpTo (DdManager *dd); +extern void Cudd_SetLooseUpTo (DdManager *dd, unsigned int lut); +extern unsigned int Cudd_ReadMaxCache (DdManager *dd); +extern unsigned int Cudd_ReadMaxCacheHard (DdManager *dd); +extern void Cudd_SetMaxCacheHard (DdManager *dd, unsigned int mc); +extern int Cudd_ReadSize (DdManager *dd); +extern int Cudd_ReadZddSize (DdManager *dd); +extern unsigned int Cudd_ReadSlots (DdManager *dd); +extern double Cudd_ReadUsedSlots (DdManager * dd); +extern double Cudd_ExpectedUsedSlots (DdManager * dd); +extern unsigned int Cudd_ReadKeys (DdManager *dd); +extern unsigned int Cudd_ReadDead (DdManager *dd); +extern unsigned int Cudd_ReadMinDead (DdManager *dd); +extern unsigned int Cudd_ReadReorderings (DdManager *dd); +extern unsigned int Cudd_ReadMaxReorderings (DdManager *dd); +extern void Cudd_SetMaxReorderings (DdManager *dd, unsigned int mr); +extern long Cudd_ReadReorderingTime (DdManager * dd); +extern int Cudd_ReadGarbageCollections (DdManager * dd); +extern long Cudd_ReadGarbageCollectionTime (DdManager * dd); +extern double Cudd_ReadNodesFreed (DdManager * dd); +extern double Cudd_ReadNodesDropped (DdManager * dd); +extern double Cudd_ReadUniqueLookUps (DdManager * dd); +extern double Cudd_ReadUniqueLinks (DdManager * dd); +extern int Cudd_ReadSiftMaxVar (DdManager *dd); +extern void Cudd_SetSiftMaxVar (DdManager *dd, int smv); +extern int Cudd_ReadSiftMaxSwap (DdManager *dd); +extern void Cudd_SetSiftMaxSwap (DdManager *dd, int sms); +extern double Cudd_ReadMaxGrowth (DdManager *dd); +extern void Cudd_SetMaxGrowth (DdManager *dd, double mg); +extern double Cudd_ReadMaxGrowthAlternate (DdManager * dd); +extern void Cudd_SetMaxGrowthAlternate (DdManager * dd, double mg); +extern int Cudd_ReadReorderingCycle (DdManager * dd); +extern void Cudd_SetReorderingCycle (DdManager * dd, int cycle); +extern MtrNode * Cudd_ReadTree (DdManager *dd); +extern void Cudd_SetTree (DdManager *dd, MtrNode *tree); +extern void Cudd_FreeTree (DdManager *dd); +extern MtrNode * Cudd_ReadZddTree (DdManager *dd); +extern void Cudd_SetZddTree (DdManager *dd, MtrNode *tree); +extern void Cudd_FreeZddTree (DdManager *dd); +extern unsigned int Cudd_NodeReadIndex (DdNode *node); +extern int Cudd_ReadPerm (DdManager *dd, int i); +extern int Cudd_ReadPermZdd (DdManager *dd, int i); +extern int Cudd_ReadInvPerm (DdManager *dd, int i); +extern int Cudd_ReadInvPermZdd (DdManager *dd, int i); +extern DdNode * Cudd_ReadVars (DdManager *dd, int i); +extern CUDD_VALUE_TYPE Cudd_ReadEpsilon (DdManager *dd); +extern void Cudd_SetEpsilon (DdManager *dd, CUDD_VALUE_TYPE ep); +extern Cudd_AggregationType Cudd_ReadGroupcheck (DdManager *dd); +extern void Cudd_SetGroupcheck (DdManager *dd, Cudd_AggregationType gc); +extern int Cudd_GarbageCollectionEnabled (DdManager *dd); +extern void Cudd_EnableGarbageCollection (DdManager *dd); +extern void Cudd_DisableGarbageCollection (DdManager *dd); +extern int Cudd_DeadAreCounted (DdManager *dd); +extern void Cudd_TurnOnCountDead (DdManager *dd); +extern void Cudd_TurnOffCountDead (DdManager *dd); +extern int Cudd_ReadRecomb (DdManager *dd); +extern void Cudd_SetRecomb (DdManager *dd, int recomb); +extern int Cudd_ReadSymmviolation (DdManager *dd); +extern void Cudd_SetSymmviolation (DdManager *dd, int symmviolation); +extern int Cudd_ReadArcviolation (DdManager *dd); +extern void Cudd_SetArcviolation (DdManager *dd, int arcviolation); +extern int Cudd_ReadPopulationSize (DdManager *dd); +extern void Cudd_SetPopulationSize (DdManager *dd, int populationSize); +extern int Cudd_ReadNumberXovers (DdManager *dd); +extern void Cudd_SetNumberXovers (DdManager *dd, int numberXovers); +extern unsigned int Cudd_ReadOrderRandomization(DdManager * dd); +extern void Cudd_SetOrderRandomization(DdManager * dd, unsigned int factor); +extern unsigned long Cudd_ReadMemoryInUse (DdManager *dd); +extern int Cudd_PrintInfo (DdManager *dd, FILE *fp); +extern long Cudd_ReadPeakNodeCount (DdManager *dd); +extern int Cudd_ReadPeakLiveNodeCount (DdManager * dd); +extern long Cudd_ReadNodeCount (DdManager *dd); +extern long Cudd_zddReadNodeCount (DdManager *dd); +extern int Cudd_AddHook (DdManager *dd, DD_HFP f, Cudd_HookType where); +extern int Cudd_RemoveHook (DdManager *dd, DD_HFP f, Cudd_HookType where); +extern int Cudd_IsInHook (DdManager * dd, DD_HFP f, Cudd_HookType where); +extern int Cudd_StdPreReordHook (DdManager *dd, const char *str, void *data); +extern int Cudd_StdPostReordHook (DdManager *dd, const char *str, void *data); +extern int Cudd_EnableReorderingReporting (DdManager *dd); +extern int Cudd_DisableReorderingReporting (DdManager *dd); +extern int Cudd_ReorderingReporting (DdManager *dd); +extern int Cudd_PrintGroupedOrder(DdManager * dd, const char *str, void *data); +extern int Cudd_EnableOrderingMonitoring(DdManager *dd); +extern int Cudd_DisableOrderingMonitoring(DdManager *dd); +extern int Cudd_OrderingMonitoring(DdManager *dd); +extern Cudd_ErrorType Cudd_ReadErrorCode (DdManager *dd); +extern void Cudd_ClearErrorCode (DdManager *dd); +extern FILE * Cudd_ReadStdout (DdManager *dd); +extern void Cudd_SetStdout (DdManager *dd, FILE *fp); +extern FILE * Cudd_ReadStderr (DdManager *dd); +extern void Cudd_SetStderr (DdManager *dd, FILE *fp); +extern unsigned int Cudd_ReadNextReordering (DdManager *dd); +extern void Cudd_SetNextReordering (DdManager *dd, unsigned int next); +extern double Cudd_ReadSwapSteps (DdManager *dd); +extern unsigned int Cudd_ReadMaxLive (DdManager *dd); +extern void Cudd_SetMaxLive (DdManager *dd, unsigned int maxLive); +extern unsigned long Cudd_ReadMaxMemory (DdManager *dd); +extern void Cudd_SetMaxMemory (DdManager *dd, unsigned long maxMemory); +extern int Cudd_bddBindVar (DdManager *dd, int index); +extern int Cudd_bddUnbindVar (DdManager *dd, int index); +extern int Cudd_bddVarIsBound (DdManager *dd, int index); +extern DdNode * Cudd_addExistAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_addUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_addOrAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_addApply (DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g); +extern DdNode * Cudd_addPlus (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addTimes (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addThreshold (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addSetNZ (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addDivide (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addMinus (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addMinimum (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addMaximum (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addOneZeroMaximum (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addDiff (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addAgreement (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addOr (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addNand (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addNor (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addXor (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addXnor (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addNotEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addGreaterThan (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addGreaterThanEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addLessThan (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addLessThanEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addMonadicApply (DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f); +extern DdNode * Cudd_addLog (DdManager * dd, DdNode * f); +extern DdNode * Cudd_addEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addNotEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addGreaterThan (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addGreaterThanEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addLessThan (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addLessThanEquals (DdManager *dd, DdNode **f, DdNode **g); +extern DdNode * Cudd_addFindMax (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addFindMin (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addIthBit (DdManager *dd, DdNode *f, int bit); +extern DdNode * Cudd_addScalarInverse (DdManager *dd, DdNode *f, DdNode *epsilon); +extern DdNode * Cudd_addIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * Cudd_addIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * Cudd_addEvalConst (DdManager *dd, DdNode *f, DdNode *g); +extern int Cudd_addLeq (DdManager * dd, DdNode * f, DdNode * g); +extern DdNode * Cudd_addCmpl (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addNegate (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addRoundOff (DdManager *dd, DdNode *f, int N); +extern DdNode * Cudd_addWalsh (DdManager *dd, DdNode **x, DdNode **y, int n); +extern DdNode * Cudd_addResidue (DdManager *dd, int n, int m, int options, int top); +extern DdNode * Cudd_bddAndAbstract (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube); +extern DdNode * Cudd_bddAndAbstractLimit (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, unsigned int limit); +extern int Cudd_ApaNumberOfDigits (int binaryDigits); +extern DdApaNumber Cudd_NewApaNumber (int digits); +extern void Cudd_ApaCopy (int digits, DdApaNumber source, DdApaNumber dest); +extern DdApaDigit Cudd_ApaAdd (int digits, DdApaNumber a, DdApaNumber b, DdApaNumber sum); +extern DdApaDigit Cudd_ApaSubtract (int digits, DdApaNumber a, DdApaNumber b, DdApaNumber diff); +extern DdApaDigit Cudd_ApaShortDivision (int digits, DdApaNumber dividend, DdApaDigit divisor, DdApaNumber quotient); +extern unsigned int Cudd_ApaIntDivision (int digits, DdApaNumber dividend, unsigned int divisor, DdApaNumber quotient); +extern void Cudd_ApaShiftRight (int digits, DdApaDigit in, DdApaNumber a, DdApaNumber b); +extern void Cudd_ApaSetToLiteral (int digits, DdApaNumber number, DdApaDigit literal); +extern void Cudd_ApaPowerOfTwo (int digits, DdApaNumber number, int power); +extern int Cudd_ApaCompare (int digitsFirst, DdApaNumber first, int digitsSecond, DdApaNumber second); +extern int Cudd_ApaCompareRatios (int digitsFirst, DdApaNumber firstNum, unsigned int firstDen, int digitsSecond, DdApaNumber secondNum, unsigned int secondDen); +extern int Cudd_ApaPrintHex (FILE *fp, int digits, DdApaNumber number); +extern int Cudd_ApaPrintDecimal (FILE *fp, int digits, DdApaNumber number); +extern int Cudd_ApaPrintExponential (FILE * fp, int digits, DdApaNumber number, int precision); +extern DdApaNumber Cudd_ApaCountMinterm (DdManager *manager, DdNode *node, int nvars, int *digits); +extern int Cudd_ApaPrintMinterm (FILE *fp, DdManager *dd, DdNode *node, int nvars); +extern int Cudd_ApaPrintMintermExp (FILE * fp, DdManager * dd, DdNode * node, int nvars, int precision); +extern int Cudd_ApaPrintDensity (FILE * fp, DdManager * dd, DdNode * node, int nvars); +extern DdNode * Cudd_UnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality); +extern DdNode * Cudd_OverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality); +extern DdNode * Cudd_RemapUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality); +extern DdNode * Cudd_RemapOverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality); +extern DdNode * Cudd_BiasedUnderApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0); +extern DdNode * Cudd_BiasedOverApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0); +extern DdNode * Cudd_bddExistAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_bddExistAbstractLimit(DdManager * manager, DdNode * f, DdNode * cube, unsigned int limit); +extern DdNode * Cudd_bddXorExistAbstract (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube); +extern DdNode * Cudd_bddUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * Cudd_bddBooleanDiff (DdManager *manager, DdNode *f, int x); +extern int Cudd_bddVarIsDependent (DdManager *dd, DdNode *f, DdNode *var); +extern double Cudd_bddCorrelation (DdManager *manager, DdNode *f, DdNode *g); +extern double Cudd_bddCorrelationWeights (DdManager *manager, DdNode *f, DdNode *g, double *prob); +extern DdNode * Cudd_bddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); + extern DdNode * Cudd_bddIteLimit (DdManager *dd, DdNode *f, DdNode *g, DdNode *h, unsigned int limit); +extern DdNode * Cudd_bddIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * Cudd_bddIntersect (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddAnd (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddAndLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); +extern DdNode * Cudd_bddOr (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddOrLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); +extern DdNode * Cudd_bddNand (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddNor (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddXor (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddXnor (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_bddXnorLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); +extern int Cudd_bddLeq (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_addBddThreshold (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value); +extern DdNode * Cudd_addBddStrictThreshold (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value); +extern DdNode * Cudd_addBddInterval (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper); +extern DdNode * Cudd_addBddIthBit (DdManager *dd, DdNode *f, int bit); +extern DdNode * Cudd_BddToAdd (DdManager *dd, DdNode *B); +extern DdNode * Cudd_addBddPattern (DdManager *dd, DdNode *f); +extern DdNode * Cudd_bddTransfer (DdManager *ddSource, DdManager *ddDestination, DdNode *f); +extern int Cudd_DebugCheck (DdManager *table); +extern int Cudd_CheckKeys (DdManager *table); +extern DdNode * Cudd_bddClippingAnd (DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction); +extern DdNode * Cudd_bddClippingAndAbstract (DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction); +extern DdNode * Cudd_Cofactor (DdManager *dd, DdNode *f, DdNode *g); +extern int Cudd_CheckCube (DdManager *dd, DdNode *g); +extern DdNode * Cudd_bddCompose (DdManager *dd, DdNode *f, DdNode *g, int v); +extern DdNode * Cudd_addCompose (DdManager *dd, DdNode *f, DdNode *g, int v); +extern DdNode * Cudd_addPermute (DdManager *manager, DdNode *node, int *permut); +extern DdNode * Cudd_addSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n); +extern DdNode * Cudd_bddPermute (DdManager *manager, DdNode *node, int *permut); +extern DdNode * Cudd_bddVarMap (DdManager *manager, DdNode *f); +extern int Cudd_SetVarMap (DdManager *manager, DdNode **x, DdNode **y, int n); +extern DdNode * Cudd_bddSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n); +extern DdNode * Cudd_bddAdjPermuteX (DdManager *dd, DdNode *B, DdNode **x, int n); +extern DdNode * Cudd_addVectorCompose (DdManager *dd, DdNode *f, DdNode **vector); +extern DdNode * Cudd_addGeneralVectorCompose (DdManager *dd, DdNode *f, DdNode **vectorOn, DdNode **vectorOff); +extern DdNode * Cudd_addNonSimCompose (DdManager *dd, DdNode *f, DdNode **vector); +extern DdNode * Cudd_bddVectorCompose (DdManager *dd, DdNode *f, DdNode **vector); +extern int Cudd_bddApproxConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts); +extern int Cudd_bddApproxDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts); +extern int Cudd_bddIterConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts); +extern int Cudd_bddIterDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts); +extern int Cudd_bddGenConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts); +extern int Cudd_bddGenDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts); +extern int Cudd_bddVarConjDecomp (DdManager *dd, DdNode * f, DdNode ***conjuncts); +extern int Cudd_bddVarDisjDecomp (DdManager *dd, DdNode * f, DdNode ***disjuncts); +extern DdNode * Cudd_FindEssential (DdManager *dd, DdNode *f); +extern int Cudd_bddIsVarEssential (DdManager *manager, DdNode *f, int id, int phase); +extern DdTlcInfo * Cudd_FindTwoLiteralClauses (DdManager * dd, DdNode * f); +extern int Cudd_PrintTwoLiteralClauses (DdManager * dd, DdNode * f, char **names, FILE *fp); +extern int Cudd_ReadIthClause (DdTlcInfo * tlc, int i, DdHalfWord *var1, DdHalfWord *var2, int *phase1, int *phase2); +extern void Cudd_tlcInfoFree (DdTlcInfo * t); +extern int Cudd_DumpBlif (DdManager *dd, int n, DdNode **f, char **inames, char **onames, char *mname, FILE *fp, int mv); +extern int Cudd_DumpBlifBody (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp, int mv); +extern int Cudd_DumpDot (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern int Cudd_DumpDaVinci (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern int Cudd_DumpDDcal (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern int Cudd_DumpFactoredForm (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern DdNode * Cudd_bddConstrain (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_bddRestrict (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_bddNPAnd (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_addConstrain (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode ** Cudd_bddConstrainDecomp (DdManager *dd, DdNode *f); +extern DdNode * Cudd_addRestrict (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode ** Cudd_bddCharToVect (DdManager *dd, DdNode *f); +extern DdNode * Cudd_bddLICompaction (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_bddSqueeze (DdManager *dd, DdNode *l, DdNode *u); +extern DdNode * Cudd_bddMinimize (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * Cudd_SubsetCompress (DdManager *dd, DdNode *f, int nvars, int threshold); +extern DdNode * Cudd_SupersetCompress (DdManager *dd, DdNode *f, int nvars, int threshold); +extern MtrNode * Cudd_MakeTreeNode (DdManager *dd, unsigned int low, unsigned int size, unsigned int type); +extern int Cudd_addHarwell (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, DdNode ***xn, DdNode ***yn_, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy, int pr); +extern DdManager * Cudd_Init (unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory); +extern void Cudd_Quit (DdManager *unique); +extern int Cudd_PrintLinear (DdManager *table); +extern int Cudd_ReadLinear (DdManager *table, int x, int y); +extern DdNode * Cudd_bddLiteralSetIntersection (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_addMatrixMultiply (DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz); +extern DdNode * Cudd_addTimesPlus (DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz); +extern DdNode * Cudd_addTriangle (DdManager *dd, DdNode *f, DdNode *g, DdNode **z, int nz); +extern DdNode * Cudd_addOuterSum (DdManager *dd, DdNode *M, DdNode *r, DdNode *c); +extern DdNode * Cudd_PrioritySelect (DdManager *dd, DdNode *R, DdNode **x, DdNode **y, DdNode **z, DdNode *Pi, int n, DdNode * (*)(DdManager *, int, DdNode **, DdNode **, DdNode **)); +extern DdNode * Cudd_Xgty (DdManager *dd, int N, DdNode **z, DdNode **x, DdNode **y); +extern DdNode * Cudd_Xeqy (DdManager *dd, int N, DdNode **x, DdNode **y); +extern DdNode * Cudd_addXeqy (DdManager *dd, int N, DdNode **x, DdNode **y); +extern DdNode * Cudd_Dxygtdxz (DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z); +extern DdNode * Cudd_Dxygtdyz (DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z); +extern DdNode * Cudd_Inequality (DdManager * dd, int N, int c, DdNode ** x, DdNode ** y); +extern DdNode * Cudd_Disequality (DdManager * dd, int N, int c, DdNode ** x, DdNode ** y); +extern DdNode * Cudd_bddInterval (DdManager * dd, int N, DdNode ** x, unsigned int lowerB, unsigned int upperB); +extern DdNode * Cudd_CProjection (DdManager *dd, DdNode *R, DdNode *Y); +extern DdNode * Cudd_addHamming (DdManager *dd, DdNode **xVars, DdNode **yVars, int nVars); +extern int Cudd_MinHammingDist (DdManager *dd, DdNode *f, int *minterm, int upperBound); +extern DdNode * Cudd_bddClosestCube (DdManager *dd, DdNode * f, DdNode *g, int *distance); +extern int Cudd_addRead (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, DdNode ***xn, DdNode ***yn_, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy); +extern int Cudd_bddRead (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy); +extern void Cudd_Ref (DdNode *n); +extern void Cudd_RecursiveDeref (DdManager *table, DdNode *n); +extern void Cudd_IterDerefBdd (DdManager *table, DdNode *n); +extern void Cudd_DelayedDerefBdd (DdManager * table, DdNode * n); +extern void Cudd_RecursiveDerefZdd (DdManager *table, DdNode *n); +extern void Cudd_Deref (DdNode *node); +extern int Cudd_CheckZeroRef (DdManager *manager); +extern int Cudd_ReduceHeap (DdManager *table, Cudd_ReorderingType heuristic, int minsize); +extern int Cudd_ShuffleHeap (DdManager *table, int *permutation); +extern DdNode * Cudd_Eval (DdManager *dd, DdNode *f, int *inputs); +extern DdNode * Cudd_ShortestPath (DdManager *manager, DdNode *f, int *weight, int *support, int *length); +extern DdNode * Cudd_LargestCube (DdManager *manager, DdNode *f, int *length); +extern int Cudd_ShortestLength (DdManager *manager, DdNode *f, int *weight); +extern DdNode * Cudd_Decreasing (DdManager *dd, DdNode *f, int i); +extern DdNode * Cudd_Increasing (DdManager *dd, DdNode *f, int i); +extern int Cudd_EquivDC (DdManager *dd, DdNode *F, DdNode *G, DdNode *D); +extern int Cudd_bddLeqUnless (DdManager *dd, DdNode *f, DdNode *g, DdNode *D); +extern int Cudd_EqualSupNorm (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr); +extern DdNode * Cudd_bddMakePrime (DdManager *dd, DdNode *cube, DdNode *f); +extern DdNode * Cudd_bddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f); +extern DdNode * Cudd_bddLargestPrimeUnate(DdManager *dd , DdNode *f, DdNode *phaseBdd); +extern double * Cudd_CofMinterm (DdManager *dd, DdNode *node); +extern DdNode * Cudd_SolveEqn (DdManager * bdd, DdNode *F, DdNode *Y, DdNode **G, int **yIndex, int n); +extern DdNode * Cudd_VerifySol (DdManager * bdd, DdNode *F, DdNode **G, int *yIndex, int n); +extern DdNode * Cudd_SplitSet (DdManager *manager, DdNode *S, DdNode **xVars, int n, double m); +extern DdNode * Cudd_SubsetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold); +extern DdNode * Cudd_SupersetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold); +extern DdNode * Cudd_SubsetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit); +extern DdNode * Cudd_SupersetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit); +extern void Cudd_SymmProfile (DdManager *table, int lower, int upper); +extern unsigned int Cudd_Prime (unsigned int p); +extern int Cudd_Reserve(DdManager *manager, int amount); +extern int Cudd_PrintMinterm (DdManager *manager, DdNode *node); +extern int Cudd_bddPrintCover (DdManager *dd, DdNode *l, DdNode *u); +extern int Cudd_PrintDebug (DdManager *dd, DdNode *f, int n, int pr); +extern int Cudd_DagSize (DdNode *node); +extern int Cudd_EstimateCofactor (DdManager *dd, DdNode * node, int i, int phase); +extern int Cudd_EstimateCofactorSimple (DdNode * node, int i); +extern int Cudd_SharingSize (DdNode **nodeArray, int n); +extern double Cudd_CountMinterm (DdManager *manager, DdNode *node, int nvars); +extern int Cudd_EpdCountMinterm (DdManager *manager, DdNode *node, int nvars, EpDouble *epd); +extern double Cudd_CountPath (DdNode *node); +extern double Cudd_CountPathsToNonZero (DdNode *node); +extern int Cudd_SupportIndices(DdManager * dd, DdNode * f, int **indices); +extern DdNode * Cudd_Support (DdManager *dd, DdNode *f); +extern int * Cudd_SupportIndex (DdManager *dd, DdNode *f); +extern int Cudd_SupportSize (DdManager *dd, DdNode *f); +extern int Cudd_VectorSupportIndices(DdManager * dd, DdNode ** F, int n, int **indices); +extern DdNode * Cudd_VectorSupport (DdManager *dd, DdNode **F, int n); +extern int * Cudd_VectorSupportIndex (DdManager *dd, DdNode **F, int n); +extern int Cudd_VectorSupportSize (DdManager *dd, DdNode **F, int n); +extern int Cudd_ClassifySupport (DdManager *dd, DdNode *f, DdNode *g, DdNode **common, DdNode **onlyF, DdNode **onlyG); +extern int Cudd_CountLeaves (DdNode *node); +extern int Cudd_bddPickOneCube (DdManager *ddm, DdNode *node, char *string); +extern DdNode * Cudd_bddPickOneMinterm (DdManager *dd, DdNode *f, DdNode **vars, int n); +extern DdNode ** Cudd_bddPickArbitraryMinterms (DdManager *dd, DdNode *f, DdNode **vars, int n, int k); +extern DdNode * Cudd_SubsetWithMaskVars (DdManager *dd, DdNode *f, DdNode **vars, int nvars, DdNode **maskVars, int mvars); +extern DdGen * Cudd_FirstCube (DdManager *dd, DdNode *f, int **cube, CUDD_VALUE_TYPE *value); +extern int Cudd_NextCube (DdGen *gen, int **cube, CUDD_VALUE_TYPE *value); +extern DdGen * Cudd_FirstPrime(DdManager *dd, DdNode *l, DdNode *u, int **cube); +extern int Cudd_NextPrime(DdGen *gen, int **cube); +extern DdNode * Cudd_bddComputeCube (DdManager *dd, DdNode **vars, int *phase, int n); +extern DdNode * Cudd_addComputeCube (DdManager *dd, DdNode **vars, int *phase, int n); +extern DdNode * Cudd_CubeArrayToBdd (DdManager *dd, int *array); +extern int Cudd_BddToCubeArray (DdManager *dd, DdNode *cube, int *array); +extern DdGen * Cudd_FirstNode (DdManager *dd, DdNode *f, DdNode **node); +extern int Cudd_NextNode (DdGen *gen, DdNode **node); +extern int Cudd_GenFree (DdGen *gen); +extern int Cudd_IsGenEmpty (DdGen *gen); +extern DdNode * Cudd_IndicesToCube (DdManager *dd, int *array, int n); +extern void Cudd_PrintVersion (FILE *fp); +extern double Cudd_AverageDistance (DdManager *dd); +extern long Cudd_Random (void); +extern void Cudd_Srandom (long seed); +extern double Cudd_Density (DdManager *dd, DdNode *f, int nvars); +extern void Cudd_OutOfMem (long size); +extern int Cudd_zddCount (DdManager *zdd, DdNode *P); +extern double Cudd_zddCountDouble (DdManager *zdd, DdNode *P); +extern DdNode * Cudd_zddProduct (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddUnateProduct (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddWeakDiv (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddDivide (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddWeakDivF (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddDivideF (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * Cudd_zddComplement (DdManager *dd, DdNode *node); +extern MtrNode * Cudd_MakeZddTreeNode (DdManager *dd, unsigned int low, unsigned int size, unsigned int type); +extern DdNode * Cudd_zddIsop (DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I); +extern DdNode * Cudd_bddIsop (DdManager *dd, DdNode *L, DdNode *U); +extern DdNode * Cudd_MakeBddFromZddCover (DdManager *dd, DdNode *node); +extern int Cudd_zddDagSize (DdNode *p_node); +extern double Cudd_zddCountMinterm (DdManager *zdd, DdNode *node, int path); +extern void Cudd_zddPrintSubtable (DdManager *table); +extern DdNode * Cudd_zddPortFromBdd (DdManager *dd, DdNode *B); +extern DdNode * Cudd_zddPortToBdd (DdManager *dd, DdNode *f); +extern int Cudd_zddReduceHeap (DdManager *table, Cudd_ReorderingType heuristic, int minsize); +extern int Cudd_zddShuffleHeap (DdManager *table, int *permutation); +extern DdNode * Cudd_zddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * Cudd_zddUnion (DdManager *dd, DdNode *P, DdNode *Q); +extern DdNode * Cudd_zddIntersect (DdManager *dd, DdNode *P, DdNode *Q); +extern DdNode * Cudd_zddDiff (DdManager *dd, DdNode *P, DdNode *Q); +extern DdNode * Cudd_zddDiffConst (DdManager *zdd, DdNode *P, DdNode *Q); +extern DdNode * Cudd_zddSubset1 (DdManager *dd, DdNode *P, int var); +extern DdNode * Cudd_zddSubset0 (DdManager *dd, DdNode *P, int var); +extern DdNode * Cudd_zddChange (DdManager *dd, DdNode *P, int var); +extern void Cudd_zddSymmProfile (DdManager *table, int lower, int upper); +extern int Cudd_zddPrintMinterm (DdManager *zdd, DdNode *node); +extern int Cudd_zddPrintCover (DdManager *zdd, DdNode *node); +extern int Cudd_zddPrintDebug (DdManager *zdd, DdNode *f, int n, int pr); +extern DdGen * Cudd_zddFirstPath (DdManager *zdd, DdNode *f, int **path); +extern int Cudd_zddNextPath (DdGen *gen, int **path); +extern char * Cudd_zddCoverPathToString (DdManager *zdd, int *path, char *str); +extern DdNode * Cudd_zddSupport(DdManager * dd, DdNode * f); +extern int Cudd_zddDumpDot (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp); +extern int Cudd_bddSetPiVar (DdManager *dd, int index); +extern int Cudd_bddSetPsVar (DdManager *dd, int index); +extern int Cudd_bddSetNsVar (DdManager *dd, int index); +extern int Cudd_bddIsPiVar (DdManager *dd, int index); +extern int Cudd_bddIsPsVar (DdManager *dd, int index); +extern int Cudd_bddIsNsVar (DdManager *dd, int index); +extern int Cudd_bddSetPairIndex (DdManager *dd, int index, int pairIndex); +extern int Cudd_bddReadPairIndex (DdManager *dd, int index); +extern int Cudd_bddSetVarToBeGrouped (DdManager *dd, int index); +extern int Cudd_bddSetVarHardGroup (DdManager *dd, int index); +extern int Cudd_bddResetVarToBeGrouped (DdManager *dd, int index); +extern int Cudd_bddIsVarToBeGrouped (DdManager *dd, int index); +extern int Cudd_bddSetVarToBeUngrouped (DdManager *dd, int index); +extern int Cudd_bddIsVarToBeUngrouped (DdManager *dd, int index); +extern int Cudd_bddIsVarHardGroup (DdManager *dd, int index); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _CUDD */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cuddBdd.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cuddBdd.h new file mode 100644 index 000000000..2a688d761 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cuddBdd.h @@ -0,0 +1,382 @@ +/**CHeaderFile***************************************************************** + + FileName [cuddBdd.h] + + PackageName [cudd] + + Synopsis [Defines interface for the CU package to work with the + ucb interface.] + + Description [] + + Author [Abelardo Pardo] + + Copyright [Copyright (c) 1994-1996 The Univ. of Colorado. + All rights reserved. + + Permission is hereby granted, without written agreement and without license + or royalty fees, to use, copy, modify, and distribute this software and its + documentation for any purpose, provided that the above copyright notice and + the following two paragraphs appear in all copies of this software. + + IN NO EVENT SHALL THE UNIVERSITY OF COLORADO BE LIABLE TO ANY PARTY FOR + DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + COLORADO HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + THE UNIVERSITY OF COLORADO SPECIFICALLY DISCLAIMS ANY WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN + "AS IS" BASIS, AND THE UNIVERSITY OF COLORADO HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.] + + Revision [$Id: cuddBdd.h,v 1.2 1996/07/30 20:42:04 bobbie Exp $] + +******************************************************************************/ + +#ifndef _BDD +#define _BDD + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include "var_set.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +#define boolean int +/* + * foreach macro in the most misesque tradition + * bdd_gen_free always returns 0 + * + * CAUTION: in the context of the port to the CUDD package, it is assumed that + * dynamic reordering will not occur while there are open generators. It is + * the user's responsibility to make sure dynamic reordering doesn't occur. + * As long as new nodes are not created during generation, and you don't + * explicitly call dynamic reordering, you should be okay. + */ + +/* + * foreach_bdd_cube(fn, gen, cube) + * bdd_t *fn; + * bdd_gen *gen; + * array_t *cube; - return + * + * foreach_bdd_cube(fn, gen, cube) { + * ... + * } + */ +#define foreach_bdd_cube(fn, gen, cube)\ + for((gen) = bdd_first_cube(fn, &cube);\ + bdd_is_gen_empty(gen) ? bdd_gen_free(gen) : TRUE;\ + (void) bdd_next_cube(gen, &cube)) + +/* + * foreach_bdd_node(fn, gen, node) + * bdd_t *fn; + * bdd_gen *gen; + * bdd_node *node; - return + */ +#define foreach_bdd_node(fn, gen, node)\ + for((gen) = bdd_first_node(fn, &node);\ + bdd_is_gen_empty(gen) ? bdd_gen_free(gen) : TRUE;\ + (void) bdd_next_node(gen, &node)) + +/* + * Default settings. + */ +#define BDD_NO_LIMIT ((1<<30)-2) +#define BDD_DFLT_ITE_ON TRUE +#define BDD_DFLT_ITE_RESIZE_AT 75 +#define BDD_DFLT_ITE_MAX_SIZE 1000000 +#define BDD_DFLT_ITE_CONST_ON TRUE +#define BDD_DFLT_ITE_CONST_RESIZE_AT 75 +#define BDD_DFLT_ITE_CONST_MAX_SIZE 1000000 +#define BDD_DFLT_ADHOC_ON TRUE +#define BDD_DFLT_ADHOC_RESIZE_AT 0 +#define BDD_DFLT_ADHOC_MAX_SIZE 10000000 +#define BDD_DFLT_GARB_COLLECT_ON TRUE +#define BDD_DFLT_DAEMON NIL(void) +#define BDD_DFLT_MEMORY_LIMIT BDD_NO_LIMIT +#define BDD_DFLT_NODE_RATIO 2.0 +#define BDD_DFLT_INIT_BLOCKS 10 + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct DdManager bdd_manager; /* referenced via a pointer only */ +typedef unsigned int bdd_variableId; /* the id of the variable in a bdd node */ +typedef struct DdNode bdd_node; /* referenced via a pointer only */ +typedef int bdd_literal; /* integers in the set { 0, 1, 2 } */ + +/* This is to avoid problems with the mnemosyne library, which redefines +** free. +*/ +#ifdef MNEMOSYNE +#undef free +#endif + +typedef struct bdd_t { + boolean free; /* TRUE if this is free, FALSE otherwise ... */ + bdd_node *node; /* ptr to the top node of the function */ + bdd_manager *mgr; /* the manager */ +} bdd_t; + +/* + * Initialization data structure. Not supported in CMU package. + */ +typedef struct bdd_mgr_init { + struct { + boolean on; /* TRUE/FALSE: is the cache on */ + unsigned int resize_at; /* percentage at which to resize (e.g. 85% is 85); doesn't apply to adhoc */ + unsigned int max_size; /* max allowable number of buckets; for adhoc, max allowable number of entries */ + } ITE_cache, + ITE_const_cache, + adhoc_cache; + struct { + boolean on; /* TRUE/FALSE: is the garbage collector on */ + } garbage_collector; + struct { + void (*daemon)(); /* used for callback when memory limit exceeded */ + unsigned int limit; /* upper bound on memory allocated by the manager; in megabytes */ + } memory; + struct { + float ratio; /* allocate new bdd_nodes to achieve ratio of used to unused nodes */ + unsigned int init_blocks; /* number of bdd_nodeBlocks initially allocated */ + } nodes; +} bdd_mgr_init; + +/* + * Match types for BDD minimization. + */ +typedef enum { + BDD_MIN_TSM, /* two-side match */ + BDD_MIN_OSM, /* one-side match */ + BDD_MIN_OSDM /* one-side DC match */ +} bdd_min_match_type_t; + +/* + * Statistics and Other Queries + */ +typedef struct bdd_cache_stats { + unsigned int hits; + unsigned int misses; + unsigned int collisions; + unsigned int inserts; +} bdd_cache_stats; + +typedef struct bdd_stats { + struct { + bdd_cache_stats hashtable; /* the unique table; collisions and inserts fields not used */ + bdd_cache_stats itetable; + bdd_cache_stats consttable; + bdd_cache_stats adhoc; + } cache; /* various cache statistics */ + struct { + unsigned int calls; + struct { + unsigned int trivial; + unsigned int cached; + unsigned int full; + } returns; + } ITE_ops, + ITE_constant_ops, + adhoc_ops; + struct { + unsigned int total; + } blocks; /* bdd_nodeBlock count */ + struct { + unsigned int used; + unsigned int unused; + unsigned int total; + unsigned int peak; + } nodes; /* bdd_node count */ + struct { + unsigned int used; + unsigned int unused; + unsigned int total; + unsigned int blocks; + } extptrs; /* bdd_t count */ + struct { + unsigned int times; /* the number of times the garbage-collector has run */ + unsigned int nodes_collected; /* cumulative number of nodes collected over life of manager */ + long runtime; /* cumulative CPU time spent garbage collecting */ + } gc; + struct { + int first_sbrk; /* value of sbrk at start of manager; used to analyze memory usage */ + int last_sbrk; /* value of last sbrk (see "man sbrk") fetched; used to analyze memory usage */ + unsigned int manager; + unsigned int nodes; + unsigned int hashtable; + unsigned int ext_ptrs; + unsigned int ITE_cache; + unsigned int ITE_const_cache; + unsigned int adhoc_cache; + unsigned int total; + } memory; /* memory usage */ +} bdd_stats; + +/* + * Traversal of BDD Formulas + */ + +typedef struct bdd_gen bdd_gen; + +/* + * These are the hooks for stuff that uses bdd's + * + * There are three hooks, and users may use them in whatever + * way they wish; these hooks are guaranteed to never be used + * by the bdd package. + */ +typedef struct bdd_external_hooks { + char *network; + char *mdd; + char *undef1; +} bdd_external_hooks; + +/* + * Dynamic reordering. + */ +typedef enum { + BDD_REORDER_SIFT, + BDD_REORDER_WINDOW, + BDD_REORDER_NONE, + BDD_REORDER_SAME, + BDD_REORDER_RANDOM, + BDD_REORDER_RANDOM_PIVOT, + BDD_REORDER_SIFT_CONVERGE, + BDD_REORDER_SYMM_SIFT, + BDD_REORDER_SYMM_SIFT_CONV, + BDD_REORDER_WINDOW2, + BDD_REORDER_WINDOW3, + BDD_REORDER_WINDOW4, + BDD_REORDER_WINDOW2_CONV, + BDD_REORDER_WINDOW3_CONV, + BDD_REORDER_WINDOW4_CONV, + BDD_REORDER_GROUP_SIFT, + BDD_REORDER_GROUP_SIFT_CONV, + BDD_REORDER_ANNEALING, + BDD_REORDER_GENETIC +} bdd_reorder_type_t; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/* + * BDD Manager Allocation And Destruction + */ +extern void bdd_end (bdd_manager *); +extern void bdd_register_daemon (bdd_manager *, void (*daemon)()); +extern void bdd_set_mgr_init_dflts (bdd_mgr_init *); +extern bdd_manager *bdd_start (int); +extern bdd_manager *bdd_start_with_params (int, bdd_mgr_init *); + +/* + * BDD Variable Allocation + */ +extern bdd_t *bdd_create_variable (bdd_manager *); +extern bdd_t *bdd_get_variable (bdd_manager *, bdd_variableId); + +/* + * BDD Formula Management + */ +extern bdd_t *bdd_dup (bdd_t *); +extern void bdd_free (bdd_t *); + +/* + * Operations on BDD Formulas + */ +extern bdd_t *bdd_and (bdd_t *, bdd_t *, boolean, boolean); +extern bdd_t *bdd_and_smooth (bdd_t *, bdd_t *, array_t *); +extern bdd_t *bdd_between (bdd_t *, bdd_t *); +extern bdd_t *bdd_cofactor (bdd_t *, bdd_t *); +extern bdd_t *bdd_compose (bdd_t *, bdd_t *, bdd_t *); +extern bdd_t *bdd_consensus (bdd_t *, array_t *); +extern bdd_t *bdd_cproject (bdd_t *, array_t *); +extern bdd_t *bdd_else (bdd_t *); +extern bdd_t *bdd_ite (bdd_t *, bdd_t *, bdd_t *, boolean, boolean, boolean); +extern bdd_t *bdd_minimize (bdd_t *, bdd_t *); +extern bdd_t *bdd_minimize_with_params (bdd_t *, bdd_t *, bdd_min_match_type_t, boolean, boolean, boolean); +extern bdd_t *bdd_not (bdd_t *); +extern bdd_t *bdd_one (bdd_manager *); +extern bdd_t *bdd_or (bdd_t *, bdd_t *, boolean, boolean); +extern bdd_t *bdd_smooth (bdd_t *, array_t *); +extern bdd_t *bdd_substitute (bdd_t *, array_t *, array_t *); +extern bdd_t *bdd_then (bdd_t *); +extern bdd_t *bdd_top_var (bdd_t *); +extern bdd_t *bdd_xnor (bdd_t *, bdd_t *); +extern bdd_t *bdd_xor (bdd_t *, bdd_t *); +extern bdd_t *bdd_zero (bdd_manager *); + +/* + * Queries about BDD Formulas + */ +extern boolean bdd_equal (bdd_t *, bdd_t *); +extern boolean bdd_is_cube (bdd_t *); +extern boolean bdd_is_tautology (bdd_t *, boolean); +extern boolean bdd_leq (bdd_t *, bdd_t *, boolean, boolean); + +extern double bdd_count_onset (bdd_t *, array_t *); +extern bdd_manager *bdd_get_manager (bdd_t *); +extern bdd_node *bdd_get_node (bdd_t *, boolean *); +extern void bdd_get_stats (bdd_manager *, bdd_stats *); +extern var_set_t *bdd_get_support (bdd_t *); +extern array_t *bdd_get_varids (array_t *); +extern unsigned int bdd_num_vars (bdd_manager *); +extern void bdd_print (bdd_t *); +extern void bdd_print_stats (bdd_stats, FILE *); +extern int bdd_size (bdd_t *); +extern bdd_variableId bdd_top_var_id (bdd_t *); +extern bdd_t *bdd_create_variable_after (bdd_manager *, bdd_variableId); +extern bdd_variableId bdd_get_id_from_level (bdd_manager *, long); +extern long bdd_top_var_level (bdd_manager *, bdd_t *); + +extern int bdd_gen_free (bdd_gen *); + +/* + * These are NOT to be used directly; only indirectly in the macros. + */ +extern bdd_gen *bdd_first_cube (bdd_t *, array_t **); +extern boolean bdd_next_cube (bdd_gen *, array_t **); +extern bdd_gen *bdd_first_node (bdd_t *, bdd_node **); +extern boolean bdd_next_node (bdd_gen *, bdd_node **); +extern boolean bdd_is_gen_empty (bdd_gen *); + +/* + * Miscellaneous + */ +extern void bdd_set_gc_mode (bdd_manager *, boolean); + +extern bdd_external_hooks *bdd_get_external_hooks (bdd_manager *); + +extern void bdd_dynamic_reordering (bdd_manager *, bdd_reorder_type_t); + +extern int bdd_read_reordering_flag (bdd_manager *); + +#ifdef __cplusplus +} +#endif + +#endif /* _BDD */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cuddInt.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cuddInt.h new file mode 100644 index 000000000..398b057f7 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cuddInt.h @@ -0,0 +1,1188 @@ +/**CHeaderFile***************************************************************** + + FileName [cuddInt.h] + + PackageName [cudd] + + Synopsis [Internal data structures of the CUDD package.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: cuddInt.h,v 1.142 2012/02/05 01:07:19 fabio Exp $] + +******************************************************************************/ + +#ifndef _CUDDINT +#define _CUDDINT + + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#ifdef DD_MIS +#include "array.h" +#include "list.h" +#include "st.h" +#include "espresso.h" +#include "node.h" +#ifdef SIS +#include "graph.h" +#include "astg.h" +#endif +#include "network.h" +#endif + +#include +#include "cudd.h" +#include "st.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) +# define DD_INLINE __inline__ +# if (__GNUC__ >2 || __GNUC_MINOR__ >=7) +# define DD_UNUSED __attribute__ ((__unused__)) +# else +# define DD_UNUSED +# endif +#else +# if defined(__cplusplus) +# define DD_INLINE inline +# else +# define DD_INLINE +# endif +# define DD_UNUSED +#endif + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define DD_MAXREF ((DdHalfWord) ~0) + +#define DD_DEFAULT_RESIZE 10 /* how many extra variables */ + /* should be added when resizing */ +#define DD_MEM_CHUNK 1022 + +/* These definitions work for CUDD_VALUE_TYPE == double */ +#define DD_ONE_VAL (1.0) +#define DD_ZERO_VAL (0.0) +#define DD_EPSILON (1.0e-12) + +/* The definitions of +/- infinity in terms of HUGE_VAL work on +** the DECstations and on many other combinations of OS/compiler. +*/ +#ifdef HAVE_IEEE_754 +# define DD_PLUS_INF_VAL (HUGE_VAL) +#else +# define DD_PLUS_INF_VAL (10e301) +# define DD_CRI_HI_MARK (10e150) +# define DD_CRI_LO_MARK (-(DD_CRI_HI_MARK)) +#endif +#define DD_MINUS_INF_VAL (-(DD_PLUS_INF_VAL)) + +#define DD_NON_CONSTANT ((DdNode *) 1) /* for Cudd_bddIteConstant */ + +/* Unique table and cache management constants. */ +#define DD_MAX_SUBTABLE_DENSITY 4 /* tells when to resize a subtable */ +/* gc when this percent are dead (measured w.r.t. slots, not keys) +** The first limit (LO) applies normally. The second limit applies when +** the package believes more space for the unique table (i.e., more dead +** nodes) would improve performance, and the unique table is not already +** too large. The third limit applies when memory is low. +*/ +#define DD_GC_FRAC_LO DD_MAX_SUBTABLE_DENSITY * 0.25 +#define DD_GC_FRAC_HI DD_MAX_SUBTABLE_DENSITY * 1.0 +#define DD_GC_FRAC_MIN 0.2 +#define DD_MIN_HIT 30 /* resize cache when hit ratio + above this percentage (default) */ +#define DD_MAX_LOOSE_FRACTION 5 /* 1 / (max fraction of memory used for + unique table in fast growth mode) */ +#define DD_MAX_CACHE_FRACTION 3 /* 1 / (max fraction of memory used for + computed table if resizing enabled) */ +#define DD_STASH_FRACTION 64 /* 1 / (fraction of memory set + aside for emergencies) */ +#define DD_MAX_CACHE_TO_SLOTS_RATIO 4 /* used to limit the cache size */ + +/* Variable ordering default parameter values. */ +#define DD_SIFT_MAX_VAR 1000 +#define DD_SIFT_MAX_SWAPS 2000000 +#define DD_DEFAULT_RECOMB 0 +#define DD_MAX_REORDER_GROWTH 1.2 +#define DD_FIRST_REORDER 4004 /* 4 for the constants */ +#define DD_DYN_RATIO 2 /* when to dynamically reorder */ + +/* Primes for cache hash functions. */ +#define DD_P1 12582917 +#define DD_P2 4256249 +#define DD_P3 741457 +#define DD_P4 1618033999 + +/* Cache tags for 3-operand operators. These tags are stored in the +** least significant bits of the cache operand pointers according to +** the following scheme. The tag consists of two hex digits. Both digits +** must be even, so that they do not interfere with complementation bits. +** The least significant one is stored in Bits 3:1 of the f operand in the +** cache entry. Bit 1 is always 1, so that we can differentiate +** three-operand operations from one- and two-operand operations. +** Therefore, the least significant digit is one of {2,6,a,e}. The most +** significant digit occupies Bits 3:1 of the g operand in the cache +** entry. It can by any even digit between 0 and e. This gives a total +** of 5 bits for the tag proper, which means a maximum of 32 three-operand +** operations. */ +#define DD_ADD_ITE_TAG 0x02 +#define DD_BDD_AND_ABSTRACT_TAG 0x06 +#define DD_BDD_XOR_EXIST_ABSTRACT_TAG 0x0a +#define DD_BDD_ITE_TAG 0x0e +#define DD_ADD_BDD_DO_INTERVAL_TAG 0x22 +#define DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG 0x26 +#define DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG 0x2a +#define DD_BDD_COMPOSE_RECUR_TAG 0x2e +#define DD_ADD_COMPOSE_RECUR_TAG 0x42 +#define DD_ADD_NON_SIM_COMPOSE_TAG 0x46 +#define DD_EQUIV_DC_TAG 0x4a +#define DD_ZDD_ITE_TAG 0x4e +#define DD_ADD_ITE_CONSTANT_TAG 0x62 +#define DD_ADD_EVAL_CONST_TAG 0x66 +#define DD_BDD_ITE_CONSTANT_TAG 0x6a +#define DD_ADD_OUT_SUM_TAG 0x6e +#define DD_BDD_LEQ_UNLESS_TAG 0x82 +#define DD_ADD_TRIANGLE_TAG 0x86 +#define DD_BDD_MAX_EXP_TAG 0x8a + +/* Generator constants. */ +#define CUDD_GEN_CUBES 0 +#define CUDD_GEN_PRIMES 1 +#define CUDD_GEN_NODES 2 +#define CUDD_GEN_ZDD_PATHS 3 +#define CUDD_GEN_EMPTY 0 +#define CUDD_GEN_NONEMPTY 1 + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +struct DdGen { + DdManager *manager; + int type; + int status; + union { + struct { + int *cube; + CUDD_VALUE_TYPE value; + } cubes; + struct { + int *cube; + DdNode *ub; + } primes; + struct { + int size; + } nodes; + } gen; + struct { + int sp; + DdNode **stack; + } stack; + DdNode *node; +}; + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/* Hooks in CUDD are functions that the application registers with the +** manager so that they are called at appropriate times. The functions +** are passed the manager as argument; they should return 1 if +** successful and 0 otherwise. +*/ +typedef struct DdHook { /* hook list element */ + DD_HFP f; /* function to be called */ + struct DdHook *next; /* next element in the list */ +} DdHook; + +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +typedef long ptrint; +typedef unsigned long ptruint; +#else +typedef int ptrint; +typedef unsigned int ptruint; +#endif + +typedef DdNode *DdNodePtr; + +/* Generic local cache item. */ +typedef struct DdLocalCacheItem { + DdNode *value; +#ifdef DD_CACHE_PROFILE + ptrint count; +#endif + DdNode *key[1]; +} DdLocalCacheItem; + +/* Local cache. */ +typedef struct DdLocalCache { + DdLocalCacheItem *item; + unsigned int itemsize; + unsigned int keysize; + unsigned int slots; + int shift; + double lookUps; + double minHit; + double hits; + unsigned int maxslots; + DdManager *manager; + struct DdLocalCache *next; +} DdLocalCache; + +/* Generic hash item. */ +typedef struct DdHashItem { + struct DdHashItem *next; + ptrint count; + DdNode *value; + DdNode *key[1]; +} DdHashItem; + +/* Local hash table */ +typedef struct DdHashTable { + unsigned int keysize; + unsigned int itemsize; + DdHashItem **bucket; + DdHashItem *nextFree; + DdHashItem **memoryList; + unsigned int numBuckets; + int shift; + unsigned int size; + unsigned int maxsize; + DdManager *manager; +} DdHashTable; + +typedef struct DdCache { + DdNode *f,*g; /* DDs */ + ptruint h; /* either operator or DD */ + DdNode *data; /* already constructed DD */ +#ifdef DD_CACHE_PROFILE + ptrint count; +#endif +} DdCache; + +typedef struct DdSubtable { /* subtable for one index */ + DdNode **nodelist; /* hash table */ + int shift; /* shift for hash function */ + unsigned int slots; /* size of the hash table */ + unsigned int keys; /* number of nodes stored in this table */ + unsigned int maxKeys; /* slots * DD_MAX_SUBTABLE_DENSITY */ + unsigned int dead; /* number of dead nodes in this table */ + unsigned int next; /* index of next variable in group */ + int bindVar; /* flag to bind this variable to its level */ + /* Fields for lazy sifting. */ + Cudd_VariableType varType; /* variable type (ps, ns, pi) */ + int pairIndex; /* corresponding variable index (ps <-> ns) */ + int varHandled; /* flag: 1 means variable is already handled */ + Cudd_LazyGroupType varToBeGrouped; /* tells what grouping to apply */ +} DdSubtable; + +struct DdManager { /* specialized DD symbol table */ + /* Constants */ + DdNode sentinel; /* for collision lists */ + DdNode *one; /* constant 1 */ + DdNode *zero; /* constant 0 */ + DdNode *plusinfinity; /* plus infinity */ + DdNode *minusinfinity; /* minus infinity */ + DdNode *background; /* background value */ + /* Computed Table */ + DdCache *acache; /* address of allocated memory for cache */ + DdCache *cache; /* the cache-based computed table */ + unsigned int cacheSlots; /* total number of cache entries */ + int cacheShift; /* shift value for cache hash function */ + double cacheMisses; /* number of cache misses (since resizing) */ + double cacheHits; /* number of cache hits (since resizing) */ + double minHit; /* hit percentage above which to resize */ + int cacheSlack; /* slots still available for resizing */ + unsigned int maxCacheHard; /* hard limit for cache size */ + /* Unique Table */ + int size; /* number of unique subtables */ + int sizeZ; /* for ZDD */ + int maxSize; /* max number of subtables before resizing */ + int maxSizeZ; /* for ZDD */ + DdSubtable *subtables; /* array of unique subtables */ + DdSubtable *subtableZ; /* for ZDD */ + DdSubtable constants; /* unique subtable for the constants */ + unsigned int slots; /* total number of hash buckets */ + unsigned int keys; /* total number of BDD and ADD nodes */ + unsigned int keysZ; /* total number of ZDD nodes */ + unsigned int dead; /* total number of dead BDD and ADD nodes */ + unsigned int deadZ; /* total number of dead ZDD nodes */ + unsigned int maxLive; /* maximum number of live nodes */ + unsigned int minDead; /* do not GC if fewer than these dead */ + double gcFrac; /* gc when this fraction is dead */ + int gcEnabled; /* gc is enabled */ + unsigned int looseUpTo; /* slow growth beyond this limit */ + /* (measured w.r.t. slots, not keys) */ + unsigned int initSlots; /* initial size of a subtable */ + DdNode **stack; /* stack for iterative procedures */ + double allocated; /* number of nodes allocated */ + /* (not during reordering) */ + double reclaimed; /* number of nodes brought back from the dead */ + int isolated; /* isolated projection functions */ + int *perm; /* current variable perm. (index to level) */ + int *permZ; /* for ZDD */ + int *invperm; /* current inv. var. perm. (level to index) */ + int *invpermZ; /* for ZDD */ + DdNode **vars; /* projection functions */ + int *map; /* variable map for fast swap */ + DdNode **univ; /* ZDD 1 for each variable */ + int linearSize; /* number of rows and columns of linear */ + long *interact; /* interacting variable matrix */ + long *linear; /* linear transform matrix */ + /* Memory Management */ + DdNode **memoryList; /* memory manager for symbol table */ + DdNode *nextFree; /* list of free nodes */ + char *stash; /* memory reserve */ +#ifndef DD_NO_DEATH_ROW + DdNode **deathRow; /* queue for dereferencing */ + int deathRowDepth; /* number of slots in the queue */ + int nextDead; /* index in the queue */ + unsigned deadMask; /* mask for circular index update */ +#endif + /* General Parameters */ + CUDD_VALUE_TYPE epsilon; /* tolerance on comparisons */ + /* Dynamic Reordering Parameters */ + int reordered; /* flag set at the end of reordering */ + unsigned int reorderings; /* number of calls to Cudd_ReduceHeap */ + unsigned int maxReorderings;/* maximum number of calls to Cudd_ReduceHeap */ + int siftMaxVar; /* maximum number of vars sifted */ + int siftMaxSwap; /* maximum number of swaps per sifting */ + double maxGrowth; /* maximum growth during reordering */ + double maxGrowthAlt; /* alternate maximum growth for reordering */ + int reordCycle; /* how often to apply alternate threshold */ + int autoDyn; /* automatic dynamic reordering flag (BDD) */ + int autoDynZ; /* automatic dynamic reordering flag (ZDD) */ + Cudd_ReorderingType autoMethod; /* default reordering method */ + Cudd_ReorderingType autoMethodZ; /* default reordering method (ZDD) */ + int realign; /* realign ZDD order after BDD reordering */ + int realignZ; /* realign BDD order after ZDD reordering */ + unsigned int nextDyn; /* reorder if this size is reached */ + unsigned int countDead; /* if 0, count deads to trigger reordering */ + MtrNode *tree; /* variable group tree (BDD) */ + MtrNode *treeZ; /* variable group tree (ZDD) */ + Cudd_AggregationType groupcheck; /* used during group sifting */ + int recomb; /* used during group sifting */ + int symmviolation; /* used during group sifting */ + int arcviolation; /* used during group sifting */ + int populationSize; /* population size for GA */ + int numberXovers; /* number of crossovers for GA */ + unsigned int randomizeOrder; /* perturb the next reordering threshold */ + DdLocalCache *localCaches; /* local caches currently in existence */ + char *hooks; /* application-specific field (used by vis) */ + DdHook *preGCHook; /* hooks to be called before GC */ + DdHook *postGCHook; /* hooks to be called after GC */ + DdHook *preReorderingHook; /* hooks to be called before reordering */ + DdHook *postReorderingHook; /* hooks to be called after reordering */ + FILE *out; /* stdout for this manager */ + FILE *err; /* stderr for this manager */ + Cudd_ErrorType errorCode; /* info on last error */ + unsigned long startTime; /* start time in milliseconds */ + unsigned long timeLimit; /* CPU time limit */ + /* Statistical counters. */ + unsigned long memused; /* total memory allocated for the manager */ + unsigned long maxmem; /* target maximum memory */ + unsigned long maxmemhard; /* hard limit for maximum memory */ + int garbageCollections; /* number of garbage collections */ + unsigned long GCTime; /* total time spent in garbage collection */ + unsigned long reordTime; /* total time spent in reordering */ + double totCachehits; /* total number of cache hits */ + double totCacheMisses; /* total number of cache misses */ + double cachecollisions; /* number of cache collisions */ + double cacheinserts; /* number of cache insertions */ + double cacheLastInserts; /* insertions at the last cache resizing */ + double cachedeletions; /* number of deletions during garbage coll. */ +#ifdef DD_STATS + double nodesFreed; /* number of nodes returned to the free list */ + double nodesDropped; /* number of nodes killed by dereferencing */ +#endif + unsigned int peakLiveNodes; /* maximum number of live nodes */ +#ifdef DD_UNIQUE_PROFILE + double uniqueLookUps; /* number of unique table lookups */ + double uniqueLinks; /* total distance traveled in coll. chains */ +#endif +#ifdef DD_COUNT + double recursiveCalls; /* number of recursive calls */ +#ifdef DD_STATS + double nextSample; /* when to write next line of stats */ +#endif + double swapSteps; /* number of elementary reordering steps */ +#endif +#ifdef DD_MIS + /* mis/verif compatibility fields */ + array_t *iton; /* maps ids in ddNode to node_t */ + array_t *order; /* copy of order_list */ + lsHandle handle; /* where it is in network BDD list */ + network_t *network; + st_table *local_order; /* for local BDDs */ + int nvars; /* variables used so far */ + int threshold; /* for pseudo var threshold value*/ +#endif +}; + +typedef struct Move { + DdHalfWord x; + DdHalfWord y; + unsigned int flags; + int size; + struct Move *next; +} Move; + +/* Generic level queue item. */ +typedef struct DdQueueItem { + struct DdQueueItem *next; + struct DdQueueItem *cnext; + void *key; +} DdQueueItem; + +/* Level queue. */ +typedef struct DdLevelQueue { + void *first; + DdQueueItem **last; + DdQueueItem *freelist; + DdQueueItem **buckets; + int levels; + int itemsize; + int size; + int maxsize; + int numBuckets; + int shift; +} DdLevelQueue; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Adds node to the head of the free list.] + + Description [Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions.] + + SideEffects [None] + + SeeAlso [cuddAllocNode cuddDynamicAllocNode cuddDeallocMove] + +******************************************************************************/ +#define cuddDeallocNode(unique,node) \ + (node)->next = (unique)->nextFree; \ + (unique)->nextFree = node; + +/**Macro*********************************************************************** + + Synopsis [Adds node to the head of the free list.] + + Description [Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions.] + + SideEffects [None] + + SeeAlso [cuddDeallocNode cuddDynamicAllocNode] + +******************************************************************************/ +#define cuddDeallocMove(unique,node) \ + ((DdNode *)(node))->ref = 0; \ + ((DdNode *)(node))->next = (unique)->nextFree; \ + (unique)->nextFree = (DdNode *)(node); + + +/**Macro*********************************************************************** + + Synopsis [Increases the reference count of a node, if it is not + saturated.] + + Description [Increases the reference count of a node, if it is not + saturated. This being a macro, it is faster than Cudd_Ref, but it + cannot be used in constructs like cuddRef(a = b()).] + + SideEffects [none] + + SeeAlso [Cudd_Ref] + +******************************************************************************/ +#define cuddRef(n) cuddSatInc(Cudd_Regular(n)->ref) + + +/**Macro*********************************************************************** + + Synopsis [Decreases the reference count of a node, if it is not + saturated.] + + Description [Decreases the reference count of node. It is primarily + used in recursive procedures to decrease the ref count of a result + node before returning it. This accomplishes the goal of removing the + protection applied by a previous cuddRef. This being a macro, it is + faster than Cudd_Deref, but it cannot be used in constructs like + cuddDeref(a = b()).] + + SideEffects [none] + + SeeAlso [Cudd_Deref] + +******************************************************************************/ +#define cuddDeref(n) cuddSatDec(Cudd_Regular(n)->ref) + + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if the node is a constant node.] + + Description [Returns 1 if the node is a constant node (rather than an + internal node). All constant nodes have the same index + (CUDD_CONST_INDEX). The pointer passed to cuddIsConstant must be regular.] + + SideEffects [none] + + SeeAlso [Cudd_IsConstant] + +******************************************************************************/ +#define cuddIsConstant(node) ((node)->index == CUDD_CONST_INDEX) + + +/**Macro*********************************************************************** + + Synopsis [Returns the then child of an internal node.] + + Description [Returns the then child of an internal node. If + node is a constant node, the result is unpredictable. + The pointer passed to cuddT must be regular.] + + SideEffects [none] + + SeeAlso [Cudd_T] + +******************************************************************************/ +#define cuddT(node) ((node)->type.kids.T) + + +/**Macro*********************************************************************** + + Synopsis [Returns the else child of an internal node.] + + Description [Returns the else child of an internal node. If + node is a constant node, the result is unpredictable. + The pointer passed to cuddE must be regular.] + + SideEffects [none] + + SeeAlso [Cudd_E] + +******************************************************************************/ +#define cuddE(node) ((node)->type.kids.E) + + +/**Macro*********************************************************************** + + Synopsis [Returns the value of a constant node.] + + Description [Returns the value of a constant node. If + node is an internal node, the result is unpredictable. + The pointer passed to cuddV must be regular.] + + SideEffects [none] + + SeeAlso [Cudd_V] + +******************************************************************************/ +#define cuddV(node) ((node)->type.value) + + +/**Macro*********************************************************************** + + Synopsis [Finds the current position of variable index in the + order.] + + Description [Finds the current position of variable index in the + order. This macro duplicates the functionality of Cudd_ReadPerm, + but it does not check for out-of-bounds indices and it is more + efficient.] + + SideEffects [none] + + SeeAlso [Cudd_ReadPerm] + +******************************************************************************/ +#define cuddI(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->perm[(index)]) + + +/**Macro*********************************************************************** + + Synopsis [Finds the current position of ZDD variable index in the + order.] + + Description [Finds the current position of ZDD variable index in the + order. This macro duplicates the functionality of Cudd_ReadPermZdd, + but it does not check for out-of-bounds indices and it is more + efficient.] + + SideEffects [none] + + SeeAlso [Cudd_ReadPermZdd] + +******************************************************************************/ +#define cuddIZ(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->permZ[(index)]) + + +/**Macro*********************************************************************** + + Synopsis [Hash function for the unique table.] + + Description [] + + SideEffects [none] + + SeeAlso [ddCHash ddCHash2] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddHash(f,g,s) \ +((((unsigned)(ptruint)(f) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (s)) +#else +#define ddHash(f,g,s) \ +((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Hash function for the cache.] + + Description [] + + SideEffects [none] + + SeeAlso [ddHash ddCHash2] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddCHash(o,f,g,h,s) \ +((((((unsigned)(ptruint)(f) + (unsigned)(ptruint)(o)) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2 + \ + (unsigned)(ptruint)(h)) * DD_P3) >> (s)) +#else +#define ddCHash(o,f,g,h,s) \ +((((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2 + \ + (unsigned)(h)) * DD_P3) >> (s)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Hash function for the cache for functions with two + operands.] + + Description [] + + SideEffects [none] + + SeeAlso [ddHash ddCHash] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define ddCHash2(o,f,g,s) \ +(((((unsigned)(ptruint)(f) + (unsigned)(ptruint)(o)) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (s)) +#else +#define ddCHash2(o,f,g,s) \ +(((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s)) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Clears the 4 least significant bits of a pointer.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define cuddClean(p) ((DdNode *)((ptruint)(p) & ~0xf)) + + +/**Macro*********************************************************************** + + Synopsis [Computes the minimum of two numbers.] + + Description [] + + SideEffects [none] + + SeeAlso [ddMax] + +******************************************************************************/ +#define ddMin(x,y) (((y) < (x)) ? (y) : (x)) + + +/**Macro*********************************************************************** + + Synopsis [Computes the maximum of two numbers.] + + Description [] + + SideEffects [none] + + SeeAlso [ddMin] + +******************************************************************************/ +#define ddMax(x,y) (((y) > (x)) ? (y) : (x)) + + +/**Macro*********************************************************************** + + Synopsis [Computes the absolute value of a number.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define ddAbs(x) (((x)<0) ? -(x) : (x)) + + +/**Macro*********************************************************************** + + Synopsis [Returns 1 if the absolute value of the difference of the two + arguments x and y is less than e.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#define ddEqualVal(x,y,e) (ddAbs((x)-(y))<(e)) + + +/**Macro*********************************************************************** + + Synopsis [Saturating increment operator.] + + Description [] + + SideEffects [none] + + SeeAlso [cuddSatDec] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define cuddSatInc(x) ((x)++) +#else +#define cuddSatInc(x) ((x) += (x) != (DdHalfWord)DD_MAXREF) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Saturating decrement operator.] + + Description [] + + SideEffects [none] + + SeeAlso [cuddSatInc] + +******************************************************************************/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define cuddSatDec(x) ((x)--) +#else +#define cuddSatDec(x) ((x) -= (x) != (DdHalfWord)DD_MAXREF) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Returns the constant 1 node.] + + Description [] + + SideEffects [none] + + SeeAlso [DD_ZERO DD_PLUS_INFINITY DD_MINUS_INFINITY] + +******************************************************************************/ +#define DD_ONE(dd) ((dd)->one) + + +/**Macro*********************************************************************** + + Synopsis [Returns the arithmetic 0 constant node.] + + Description [Returns the arithmetic 0 constant node. This is different + from the logical zero. The latter is obtained by + Cudd_Not(DD_ONE(dd)).] + + SideEffects [none] + + SeeAlso [DD_ONE Cudd_Not DD_PLUS_INFINITY DD_MINUS_INFINITY] + +******************************************************************************/ +#define DD_ZERO(dd) ((dd)->zero) + + +/**Macro*********************************************************************** + + Synopsis [Returns the plus infinity constant node.] + + Description [] + + SideEffects [none] + + SeeAlso [DD_ONE DD_ZERO DD_MINUS_INFINITY] + +******************************************************************************/ +#define DD_PLUS_INFINITY(dd) ((dd)->plusinfinity) + + +/**Macro*********************************************************************** + + Synopsis [Returns the minus infinity constant node.] + + Description [] + + SideEffects [none] + + SeeAlso [DD_ONE DD_ZERO DD_PLUS_INFINITY] + +******************************************************************************/ +#define DD_MINUS_INFINITY(dd) ((dd)->minusinfinity) + + +/**Macro*********************************************************************** + + Synopsis [Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL.] + + Description [Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL. + Furthermore, if x <= DD_MINUS_INF_VAL/2, x is set to + DD_MINUS_INF_VAL. Similarly, if DD_PLUS_INF_VAL/2 <= x, x is set to + DD_PLUS_INF_VAL. Normally this macro is a NOOP. However, if + HAVE_IEEE_754 is not defined, it makes sure that a value does not + get larger than infinity in absolute value, and once it gets to + infinity, stays there. If the value overflows before this macro is + applied, no recovery is possible.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +#ifdef HAVE_IEEE_754 +#define cuddAdjust(x) +#else +#define cuddAdjust(x) ((x) = ((x) >= DD_CRI_HI_MARK) ? DD_PLUS_INF_VAL : (((x) <= DD_CRI_LO_MARK) ? DD_MINUS_INF_VAL : (x))) +#endif + + +/**Macro*********************************************************************** + + Synopsis [Extract the least significant digit of a double digit.] + + Description [Extract the least significant digit of a double digit. Used + in the manipulation of arbitrary precision integers.] + + SideEffects [None] + + SeeAlso [DD_MSDIGIT] + +******************************************************************************/ +#define DD_LSDIGIT(x) ((x) & DD_APA_MASK) + + +/**Macro*********************************************************************** + + Synopsis [Extract the most significant digit of a double digit.] + + Description [Extract the most significant digit of a double digit. Used + in the manipulation of arbitrary precision integers.] + + SideEffects [None] + + SeeAlso [DD_LSDIGIT] + +******************************************************************************/ +#define DD_MSDIGIT(x) ((x) >> DD_APA_BITS) + + +/**Macro*********************************************************************** + + Synopsis [Outputs a line of stats.] + + Description [Outputs a line of stats if DD_COUNT and DD_STATS are + defined. Increments the number of recursive calls if DD_COUNT is + defined.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +#ifdef DD_COUNT +#ifdef DD_STATS +#define statLine(dd) dd->recursiveCalls++; \ +if (dd->recursiveCalls == dd->nextSample) {(void) fprintf(dd->err, \ +"@%.0f: %u nodes %u live %.0f dropped %.0f reclaimed\n", dd->recursiveCalls, \ +dd->keys, dd->keys - dd->dead, dd->nodesDropped, dd->reclaimed); \ +dd->nextSample += 250000;} +#else +#define statLine(dd) dd->recursiveCalls++; +#endif +#else +#define statLine(dd) +#endif + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern DdNode * cuddAddExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * cuddAddUnivAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * cuddAddOrAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * cuddAddApplyRecur (DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g); +extern DdNode * cuddAddMonadicApplyRecur (DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f); +extern DdNode * cuddAddScalarInverseRecur (DdManager *dd, DdNode *f, DdNode *epsilon); +extern DdNode * cuddAddIteRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddAddCmplRecur (DdManager *dd, DdNode *f); +extern DdNode * cuddAddNegateRecur (DdManager *dd, DdNode *f); +extern DdNode * cuddAddRoundOffRecur (DdManager *dd, DdNode *f, double trunc); +extern DdNode * cuddUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality); +extern DdNode * cuddRemapUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality); +extern DdNode * cuddBiasedUnderApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0); +extern DdNode * cuddBddAndAbstractRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube); +extern int cuddAnnealing (DdManager *table, int lower, int upper); +extern DdNode * cuddBddExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube); +extern DdNode * cuddBddXorExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube); +extern DdNode * cuddBddBooleanDiffRecur (DdManager *manager, DdNode *f, DdNode *var); +extern DdNode * cuddBddIteRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddBddIntersectRecur (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddBddAndRecur (DdManager *manager, DdNode *f, DdNode *g); +extern DdNode * cuddBddXorRecur (DdManager *manager, DdNode *f, DdNode *g); +extern DdNode * cuddBddTransfer (DdManager *ddS, DdManager *ddD, DdNode *f); +extern DdNode * cuddAddBddDoPattern (DdManager *dd, DdNode *f); +extern int cuddInitCache (DdManager *unique, unsigned int cacheSize, unsigned int maxCacheSize); +extern void cuddCacheInsert (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data); +extern void cuddCacheInsert2 (DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data); +extern void cuddCacheInsert1 (DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f, DdNode *data); +extern DdNode * cuddCacheLookup (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddCacheLookupZdd (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddCacheLookup2 (DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g); +extern DdNode * cuddCacheLookup1 (DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f); +extern DdNode * cuddCacheLookup2Zdd (DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g); +extern DdNode * cuddCacheLookup1Zdd (DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f); +extern DdNode * cuddConstantLookup (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h); +extern int cuddCacheProfile (DdManager *table, FILE *fp); +extern void cuddCacheResize (DdManager *table); +extern void cuddCacheFlush (DdManager *table); +extern int cuddComputeFloorLog2 (unsigned int value); +extern int cuddHeapProfile (DdManager *dd); +extern void cuddPrintNode (DdNode *f, FILE *fp); +extern void cuddPrintVarGroups (DdManager * dd, MtrNode * root, int zdd, int silent); +extern DdNode * cuddBddClippingAnd (DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction); +extern DdNode * cuddBddClippingAndAbstract (DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction); +extern void cuddGetBranches (DdNode *g, DdNode **g1, DdNode **g0); +extern DdNode * cuddCofactorRecur (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddBddComposeRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *proj); +extern DdNode * cuddAddComposeRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *proj); +extern int cuddExact (DdManager *table, int lower, int upper); +extern DdNode * cuddBddConstrainRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddBddRestrictRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddBddNPAndRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddAddConstrainRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddAddRestrictRecur (DdManager *dd, DdNode *f, DdNode *c); +extern DdNode * cuddBddLICompaction (DdManager *dd, DdNode *f, DdNode *c); +extern int cuddGa (DdManager *table, int lower, int upper); +extern int cuddTreeSifting (DdManager *table, Cudd_ReorderingType method); +extern int cuddZddInitUniv (DdManager *zdd); +extern void cuddZddFreeUniv (DdManager *zdd); +extern void cuddSetInteract (DdManager *table, int x, int y); +extern int cuddTestInteract (DdManager *table, int x, int y); +extern int cuddInitInteract (DdManager *table); +extern DdLocalCache * cuddLocalCacheInit (DdManager *manager, unsigned int keySize, unsigned int cacheSize, unsigned int maxCacheSize); +extern void cuddLocalCacheQuit (DdLocalCache *cache); +extern void cuddLocalCacheInsert (DdLocalCache *cache, DdNodePtr *key, DdNode *value); +extern DdNode * cuddLocalCacheLookup (DdLocalCache *cache, DdNodePtr *key); +extern void cuddLocalCacheClearDead (DdManager *manager); +extern int cuddIsInDeathRow (DdManager *dd, DdNode *f); +extern int cuddTimesInDeathRow (DdManager *dd, DdNode *f); +extern void cuddLocalCacheClearAll (DdManager *manager); +#ifdef DD_CACHE_PROFILE +extern int cuddLocalCacheProfile (DdLocalCache *cache); +#endif +extern DdHashTable * cuddHashTableInit (DdManager *manager, unsigned int keySize, unsigned int initSize); +extern void cuddHashTableQuit (DdHashTable *hash); +extern void cuddHashTableGenericQuit (DdHashTable *hash); +extern int cuddHashTableInsert (DdHashTable *hash, DdNodePtr *key, DdNode *value, ptrint count); +extern DdNode * cuddHashTableLookup (DdHashTable *hash, DdNodePtr *key); +extern int cuddHashTableInsert1 (DdHashTable *hash, DdNode *f, DdNode *value, ptrint count); +extern DdNode * cuddHashTableLookup1 (DdHashTable *hash, DdNode *f); +extern int cuddHashTableInsert2 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *value, ptrint count); +extern DdNode * cuddHashTableLookup2 (DdHashTable *hash, DdNode *f, DdNode *g); +extern int cuddHashTableInsert3 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h, DdNode *value, ptrint count); +extern DdNode * cuddHashTableLookup3 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h); +extern int cuddHashTableGenericInsert(DdHashTable * hash, DdNode * f, void * value); +extern void * cuddHashTableGenericLookup(DdHashTable * hash, DdNode * f); +extern DdLevelQueue * cuddLevelQueueInit (int levels, int itemSize, int numBuckets); +extern void cuddLevelQueueQuit (DdLevelQueue *queue); +extern void * cuddLevelQueueFirst(DdLevelQueue * queue, void * key, int level); +extern void * cuddLevelQueueEnqueue (DdLevelQueue *queue, void *key, int level); +extern void cuddLevelQueueDequeue (DdLevelQueue *queue, int level); +extern int cuddLinearAndSifting (DdManager *table, int lower, int upper); +extern int cuddLinearInPlace (DdManager * table, int x, int y); +extern void cuddUpdateInteractionMatrix (DdManager * table, int xindex, int yindex); +extern int cuddInitLinear (DdManager *table); +extern int cuddResizeLinear (DdManager *table); +extern DdNode * cuddBddLiteralSetIntersectionRecur (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddCProjectionRecur (DdManager *dd, DdNode *R, DdNode *Y, DdNode *Ysupp); +extern DdNode * cuddBddClosestCube (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE bound); +extern void cuddReclaim (DdManager *table, DdNode *n); +extern void cuddReclaimZdd (DdManager *table, DdNode *n); +extern void cuddClearDeathRow (DdManager *table); +extern void cuddShrinkDeathRow (DdManager *table); +extern DdNode * cuddDynamicAllocNode (DdManager *table); +extern int cuddSifting (DdManager *table, int lower, int upper); +extern int cuddSwapping (DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic); +extern int cuddNextHigh (DdManager *table, int x); +extern int cuddNextLow (DdManager *table, int x); +extern int cuddSwapInPlace (DdManager *table, int x, int y); +extern int cuddBddAlignToZdd (DdManager *table); +extern DdNode * cuddBddMakePrime (DdManager *dd, DdNode *cube, DdNode *f); +extern DdNode * cuddSolveEqnRecur (DdManager *bdd, DdNode *F, DdNode *Y, DdNode **G, int n, int *yIndex, int i); +extern DdNode * cuddVerifySol (DdManager *bdd, DdNode *F, DdNode **G, int *yIndex, int n); +#ifdef ST_INCLUDED +extern DdNode* cuddSplitSetRecur (DdManager *manager, st_table *mtable, int *varSeen, DdNode *p, double n, double max, int index); +#endif +extern DdNode * cuddSubsetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold); +extern DdNode * cuddSubsetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit); +extern int cuddSymmCheck (DdManager *table, int x, int y); +extern int cuddSymmSifting (DdManager *table, int lower, int upper); +extern int cuddSymmSiftingConv (DdManager *table, int lower, int upper); +extern DdNode * cuddAllocNode (DdManager *unique); +extern DdManager * cuddInitTable (unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int looseUpTo); +extern void cuddFreeTable (DdManager *unique); +extern int cuddGarbageCollect (DdManager *unique, int clearCache); +extern DdNode * cuddZddGetNode (DdManager *zdd, int id, DdNode *T, DdNode *E); +extern DdNode * cuddZddGetNodeIVO (DdManager *dd, int index, DdNode *g, DdNode *h); +extern DdNode * cuddUniqueInter (DdManager *unique, int index, DdNode *T, DdNode *E); +extern DdNode * cuddUniqueInterIVO (DdManager *unique, int index, DdNode *T, DdNode *E); +extern DdNode * cuddUniqueInterZdd (DdManager *unique, int index, DdNode *T, DdNode *E); +extern DdNode * cuddUniqueConst (DdManager *unique, CUDD_VALUE_TYPE value); +extern void cuddRehash (DdManager *unique, int i); +extern void cuddShrinkSubtable (DdManager *unique, int i); +extern int cuddInsertSubtables (DdManager *unique, int n, int level); +extern int cuddDestroySubtables (DdManager *unique, int n); +extern int cuddResizeTableZdd (DdManager *unique, int index); +extern void cuddSlowTableGrowth (DdManager *unique); +extern int cuddP (DdManager *dd, DdNode *f); +#ifdef ST_INCLUDED +extern enum st_retval cuddStCountfree (char *key, char *value, char *arg); +extern int cuddCollectNodes (DdNode *f, st_table *visited); +#endif +extern DdNodePtr * cuddNodeArray (DdNode *f, int *n); +extern int cuddWindowReorder (DdManager *table, int low, int high, Cudd_ReorderingType submethod); +extern DdNode * cuddZddProduct (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddUnateProduct (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddWeakDiv (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddWeakDivF (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddDivide (DdManager *dd, DdNode *f, DdNode *g); +extern DdNode * cuddZddDivideF (DdManager *dd, DdNode *f, DdNode *g); +extern int cuddZddGetCofactors3 (DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd); +extern int cuddZddGetCofactors2 (DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0); +extern DdNode * cuddZddComplement (DdManager *dd, DdNode *node); +extern int cuddZddGetPosVarIndex(DdManager * dd, int index); +extern int cuddZddGetNegVarIndex(DdManager * dd, int index); +extern int cuddZddGetPosVarLevel(DdManager * dd, int index); +extern int cuddZddGetNegVarLevel(DdManager * dd, int index); +extern int cuddZddTreeSifting (DdManager *table, Cudd_ReorderingType method); +extern DdNode * cuddZddIsop (DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I); +extern DdNode * cuddBddIsop (DdManager *dd, DdNode *L, DdNode *U); +extern DdNode * cuddMakeBddFromZddCover (DdManager *dd, DdNode *node); +extern int cuddZddLinearSifting (DdManager *table, int lower, int upper); +extern int cuddZddAlignToBdd (DdManager *table); +extern int cuddZddNextHigh (DdManager *table, int x); +extern int cuddZddNextLow (DdManager *table, int x); +extern int cuddZddUniqueCompare (int *ptr_x, int *ptr_y); +extern int cuddZddSwapInPlace (DdManager *table, int x, int y); +extern int cuddZddSwapping (DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic); +extern int cuddZddSifting (DdManager *table, int lower, int upper); +extern DdNode * cuddZddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h); +extern DdNode * cuddZddUnion (DdManager *zdd, DdNode *P, DdNode *Q); +extern DdNode * cuddZddIntersect (DdManager *zdd, DdNode *P, DdNode *Q); +extern DdNode * cuddZddDiff (DdManager *zdd, DdNode *P, DdNode *Q); +extern DdNode * cuddZddChangeAux (DdManager *zdd, DdNode *P, DdNode *zvar); +extern DdNode * cuddZddSubset1 (DdManager *dd, DdNode *P, int var); +extern DdNode * cuddZddSubset0 (DdManager *dd, DdNode *P, int var); +extern DdNode * cuddZddChange (DdManager *dd, DdNode *P, int var); +extern int cuddZddSymmCheck (DdManager *table, int x, int y); +extern int cuddZddSymmSifting (DdManager *table, int lower, int upper); +extern int cuddZddSymmSiftingConv (DdManager *table, int lower, int upper); +extern int cuddZddP (DdManager *zdd, DdNode *f); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _CUDDINT */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cuddObj.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cuddObj.h new file mode 100644 index 000000000..726476448 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/cuddObj.h @@ -0,0 +1,768 @@ +/**CHeaderFile*************************************************************** + + FileName [cuddObj.hh] + + PackageName [cudd] + + Synopsis [Class definitions for C++ object-oriented encapsulation of + CUDD.] + + Description [Class definitions for C++ object-oriented encapsulation of + CUDD.] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: cuddObj.hh,v 1.13 2012/02/05 01:06:40 fabio Exp fabio $] + +******************************************************************************/ + +#ifndef _CPPCUDD +#define _CPPCUDD + +#if defined (__GNUC__) +#if (__GNUC__ >2 || __GNUC_MINOR__ >=7) && !defined(UNUSED) +#define UNUSED __attribute__ ((unused)) +#else +#define UNUSED +#endif +#else +#define UNUSED +#endif + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include +#include +#include +#include "cudd.h" + +/*---------------------------------------------------------------------------*/ +/* Type definitions */ +/*---------------------------------------------------------------------------*/ +class BDD; +class ADD; +class ZDD; +class Cudd; + +typedef void (*PFC)(std::string); // handler function type + +/*---------------------------------------------------------------------------*/ +/* Class definitions */ +/*---------------------------------------------------------------------------*/ + +/**Class*********************************************************************** + + Synopsis [Class for reference counting of CUDD managers.] + + Description [] + + SeeAlso [Cudd DD ABDD ADD BDD ZDD] + +******************************************************************************/ +class Capsule { + friend class DD; + friend class ABDD; + friend class BDD; + friend class ADD; + friend class ZDD; + friend class Cudd; +private: + DdManager *manager; + PFC errorHandler; + PFC timeoutHandler; + bool verbose; + int ref; +}; + + +/**Class*********************************************************************** + + Synopsis [Base class for all decision diagrams in CUDD.] + + Description [] + + SeeAlso [Cudd ABDD ADD BDD ZDD] + +******************************************************************************/ +class DD { + friend class ABDD; + friend class BDD; + friend class ADD; + friend class ZDD; +private: + Capsule *p; + DdNode *node; + inline DdManager * checkSameManager(const DD &other) const; + inline void checkReturnValue(const DdNode *result) const; + inline void checkReturnValue(const int result, const int expected = 1) + const; +public: + DD(); + DD(Capsule *cap, DdNode *ddNode); + DD(Cudd const & manager, DdNode *ddNode); + DD(const DD &from); + virtual ~DD(); + operator bool() const { return node; } + DdManager *manager() const; + DdNode * getNode() const; + DdNode * getRegularNode() const; + int nodeCount() const; + unsigned int NodeReadIndex() const; + +}; // DD + + +/**Class*********************************************************************** + + Synopsis [Class for ADDs and BDDs.] + + Description [] + + SeeAlso [Cudd ADD BDD] + +******************************************************************************/ +class ABDD : public DD { + friend class BDD; + friend class ADD; + friend class Cudd; +public: + ABDD(); + ABDD(Capsule *cap, DdNode *bddNode); + ABDD(Cudd const & manager, DdNode *ddNode); + ABDD(const ABDD &from); + virtual ~ABDD(); + bool operator==(const ABDD &other) const; + bool operator!=(const ABDD &other) const; + void print(int nvars, int verbosity = 1) const; + DdApaNumber ApaCountMinterm(int nvars, int * digits) const; + void ApaPrintMinterm(int nvars, FILE * fp = stdout) const; + void EpdPrintMinterm(int nvars, FILE * fp = stdout) const; + bool IsOne() const; + bool IsCube() const; + BDD FindEssential() const; + void PrintTwoLiteralClauses(char ** names, FILE * fp = stdout) const; + BDD ShortestPath(int * weight, int * support, int * length) const; + BDD LargestCube(int * length = 0) const; + int ShortestLength(int * weight) const; + bool EquivDC(const ABDD& G, const ABDD& D) const; + double * CofMinterm() const; + void PrintMinterm() const; + double CountMinterm(int nvars) const; + double CountPath() const; + BDD Support() const; + int SupportSize() const; + std::vector SupportIndices() const; + void ClassifySupport(const ABDD& g, BDD* common, BDD* onlyF, BDD* onlyG) + const; + int CountLeaves() const; + DdGen * FirstCube(int ** cube, CUDD_VALUE_TYPE * value) const; + double Density(int nvars) const; + +}; // ABDD + + +/**Class*********************************************************************** + + Synopsis [Class for BDDs.] + + Description [] + + SeeAlso [Cudd] + +******************************************************************************/ +class BDD : public ABDD { + friend class Cudd; +public: + BDD(); + BDD(Capsule *cap, DdNode *bddNode); + BDD(Cudd const & manager, DdNode *ddNode); + BDD(const BDD &from); + BDD operator=(const BDD& right); + bool operator<=(const BDD& other) const; + bool operator>=(const BDD& other) const; + bool operator<(const BDD& other) const; + bool operator>(const BDD& other) const; + BDD operator!() const; + BDD operator~() const; + BDD operator*(const BDD& other) const; + BDD operator*=(const BDD& other); + BDD operator&(const BDD& other) const; + BDD operator&=(const BDD& other); + BDD operator+(const BDD& other) const; + BDD operator+=(const BDD& other); + BDD operator|(const BDD& other) const; + BDD operator|=(const BDD& other); + BDD operator^(const BDD& other) const; + BDD operator^=(const BDD& other); + BDD operator-(const BDD& other) const; + BDD operator-=(const BDD& other); + bool IsZero() const; + BDD AndAbstract(const BDD& g, const BDD& cube, unsigned int limit = 0) + const; + BDD UnderApprox( + int numVars, + int threshold = 0, + bool safe = false, + double quality = 1.0) const; + BDD OverApprox( + int numVars, + int threshold = 0, + bool safe = false, + double quality = 1.0) const; + BDD RemapUnderApprox(int numVars, int threshold = 0, double quality = 1.0) + const; + BDD RemapOverApprox(int numVars, int threshold = 0, double quality = 1.0) + const; + BDD BiasedUnderApprox(const BDD& bias, int numVars, int threshold = 0, + double quality1 = 1.0, double quality0 = 1.0) const; + BDD BiasedOverApprox(const BDD& bias, int numVars, int threshold = 0, + double quality1 = 1.0, double quality0 = 1.0) const; + BDD ExistAbstract(const BDD& cube, unsigned int limit = 0) const; + BDD XorExistAbstract(const BDD& g, const BDD& cube) const; + BDD UnivAbstract(const BDD& cube) const; + BDD BooleanDiff(int x) const; + bool VarIsDependent(const BDD& var) const; + double Correlation(const BDD& g) const; + double CorrelationWeights(const BDD& g, double * prob) const; + BDD Ite(const BDD& g, const BDD& h, unsigned int limit = 0) const; + BDD IteConstant(const BDD& g, const BDD& h) const; + BDD Intersect(const BDD& g) const; + BDD And(const BDD& g, unsigned int limit = 0) const; + BDD Or(const BDD& g, unsigned int limit = 0) const; + BDD Nand(const BDD& g) const; + BDD Nor(const BDD& g) const; + BDD Xor(const BDD& g) const; + BDD Xnor(const BDD& g, unsigned int limit = 0) const; + bool Leq(const BDD& g) const; + ADD Add() const; + BDD Transfer(Cudd& destination) const; + BDD ClippingAnd(const BDD& g, int maxDepth, int direction) const; + BDD ClippingAndAbstract(const BDD& g, const BDD& cube, int maxDepth, + int direction) const; + BDD Cofactor(const BDD& g) const; + BDD Compose(const BDD& g, int v) const; + BDD Permute(int * permut) const; + BDD SwapVariables(std::vector x, std::vector y) const; + BDD AdjPermuteX(std::vector x) const; + BDD VectorCompose(std::vector vector) const; + void ApproxConjDecomp(BDD* g, BDD* h) const; + void ApproxDisjDecomp(BDD* g, BDD* h) const; + void IterConjDecomp(BDD* g, BDD* h) const; + void IterDisjDecomp(BDD* g, BDD* h) const; + void GenConjDecomp(BDD* g, BDD* h) const; + void GenDisjDecomp(BDD* g, BDD* h) const; + void VarConjDecomp(BDD* g, BDD* h) const; + void VarDisjDecomp(BDD* g, BDD* h) const; + bool IsVarEssential(int id, int phase) const; + BDD Constrain(const BDD& c) const; + BDD Restrict(const BDD& c) const; + BDD NPAnd(const BDD& g) const; + std::vector ConstrainDecomp() const; + std::vector CharToVect() const; + BDD LICompaction(const BDD& c) const; + BDD Squeeze(const BDD& u) const; + BDD Minimize(const BDD& c) const; + BDD SubsetCompress(int nvars, int threshold) const; + BDD SupersetCompress(int nvars, int threshold) const; + BDD LiteralSetIntersection(const BDD& g) const; + BDD PrioritySelect(std::vector x, std::vector y, + std::vector z, const BDD& Pi, DD_PRFP Pifunc) const; + BDD CProjection(const BDD& Y) const; + int MinHammingDist(int *minterm, int upperBound) const; + BDD Eval(int * inputs) const; + BDD Decreasing(int i) const; + BDD Increasing(int i) const; + bool LeqUnless(const BDD& G, const BDD& D) const; + BDD MakePrime(const BDD& F) const; + BDD MaximallyExpand(const BDD& ub, const BDD& f); + BDD LargestPrimeUnate(const BDD& phases); + BDD SolveEqn(const BDD& Y, BDD* G, int ** yIndex, int n) const; + BDD VerifySol(BDD* G, int * yIndex, int n) const; + BDD SplitSet(std::vector xVars, double m) const; + BDD SubsetHeavyBranch(int numVars, int threshold) const; + BDD SupersetHeavyBranch(int numVars, int threshold) const; + BDD SubsetShortPaths(int numVars, int threshold, bool hardlimit = false) const; + BDD SupersetShortPaths(int numVars, int threshold, bool hardlimit = false) const; + void PrintCover() const; + void PrintCover(const BDD& u) const; + int EstimateCofactor(int i, int phase) const; + int EstimateCofactorSimple(int i) const; + void PickOneCube(char * string) const; + BDD PickOneMinterm(std::vector vars) const; + DdGen * FirstNode(BDD* fnode) const; + BDD zddIsop(const BDD& U, ZDD* zdd_I) const; + BDD Isop(const BDD& U) const; + ZDD PortToZdd() const; + +}; // BDD + + +/**Class*********************************************************************** + + Synopsis [Class for ADDs.] + + Description [] + + SeeAlso [Cudd] + +******************************************************************************/ +class ADD : public ABDD { + friend class Cudd; +public: + ADD(); + ADD(Capsule *cap, DdNode *bddNode); + ADD(Cudd const & manager, DdNode *ddNode); + ADD(const ADD &from); + ADD operator=(const ADD& right); + // Relational operators + bool operator<=(const ADD& other) const; + bool operator>=(const ADD& other) const; + bool operator<(const ADD& other) const; + bool operator>(const ADD& other) const; + // Arithmetic operators + ADD operator-() const; + ADD operator*(const ADD& other) const; + ADD operator*=(const ADD& other); + ADD operator+(const ADD& other) const; + ADD operator+=(const ADD& other); + ADD operator-(const ADD& other) const; + ADD operator-=(const ADD& other); + // Logical operators + ADD operator~() const; + ADD operator&(const ADD& other) const; + ADD operator&=(const ADD& other); + ADD operator|(const ADD& other) const; + ADD operator|=(const ADD& other); + bool IsZero() const; + ADD ExistAbstract(const ADD& cube) const; + ADD UnivAbstract(const ADD& cube) const; + ADD OrAbstract(const ADD& cube) const; + ADD Plus(const ADD& g) const; + ADD Times(const ADD& g) const; + ADD Threshold(const ADD& g) const; + ADD SetNZ(const ADD& g) const; + ADD Divide(const ADD& g) const; + ADD Minus(const ADD& g) const; + ADD Minimum(const ADD& g) const; + ADD Maximum(const ADD& g) const; + ADD OneZeroMaximum(const ADD& g) const; + ADD Diff(const ADD& g) const; + ADD Agreement(const ADD& g) const; + ADD Or(const ADD& g) const; + ADD Nand(const ADD& g) const; + ADD Nor(const ADD& g) const; + ADD Xor(const ADD& g) const; + ADD Xnor(const ADD& g) const; + ADD Log() const; + ADD FindMax() const; + ADD FindMin() const; + ADD IthBit(int bit) const; + ADD ScalarInverse(const ADD& epsilon) const; + ADD Ite(const ADD& g, const ADD& h) const; + ADD IteConstant(const ADD& g, const ADD& h) const; + ADD EvalConst(const ADD& g) const; + bool Leq(const ADD& g) const; + ADD Cmpl() const; + ADD Negate() const; + ADD RoundOff(int N) const; + ADD Equals(const ADD& g) const; + ADD NotEquals(const ADD& g) const; + ADD LessThan(const ADD& g) const; + ADD LessThanOrEqual(const ADD& g) const; + ADD GreaterThan(const ADD& g) const; + ADD GreaterThanOrEqual(const ADD& g) const; + BDD BddThreshold(CUDD_VALUE_TYPE value) const; + BDD BddStrictThreshold(CUDD_VALUE_TYPE value) const; + BDD BddInterval(CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper) const; + BDD BddIthBit(int bit) const; + BDD BddPattern() const; + ADD Cofactor(const ADD& g) const; + ADD Compose(const ADD& g, int v) const; + ADD Permute(int * permut) const; + ADD SwapVariables(std::vector x, std::vector y) const; + ADD VectorCompose(std::vector vector) const; + ADD NonSimCompose(std::vector vector) const; + ADD Constrain(const ADD& c) const; + ADD Restrict(const ADD& c) const; + ADD MatrixMultiply(const ADD& B, std::vector z) const; + ADD TimesPlus(const ADD& B, std::vector z) const; + ADD Triangle(const ADD& g, std::vector z) const; + ADD Eval(int * inputs) const; + bool EqualSupNorm(const ADD& g, CUDD_VALUE_TYPE tolerance, int pr) const; + +}; // ADD + + +/**Class*********************************************************************** + + Synopsis [Class for ZDDs.] + + Description [] + + SeeAlso [Cudd] + +******************************************************************************/ +class ZDD : public DD { + friend class Cudd; +public: + ZDD(Capsule *cap, DdNode *bddNode); + ZDD(); + ZDD(const ZDD &from); + ~ZDD(); + ZDD operator=(const ZDD& right); + bool operator==(const ZDD& other) const; + bool operator!=(const ZDD& other) const; + bool operator<=(const ZDD& other) const; + bool operator>=(const ZDD& other) const; + bool operator<(const ZDD& other) const; + bool operator>(const ZDD& other) const; + void print(int nvars, int verbosity = 1) const; + ZDD operator*(const ZDD& other) const; + ZDD operator*=(const ZDD& other); + ZDD operator&(const ZDD& other) const; + ZDD operator&=(const ZDD& other); + ZDD operator+(const ZDD& other) const; + ZDD operator+=(const ZDD& other); + ZDD operator|(const ZDD& other) const; + ZDD operator|=(const ZDD& other); + ZDD operator-(const ZDD& other) const; + ZDD operator-=(const ZDD& other); + int Count() const; + double CountDouble() const; + ZDD Product(const ZDD& g) const; + ZDD UnateProduct(const ZDD& g) const; + ZDD WeakDiv(const ZDD& g) const; + ZDD Divide(const ZDD& g) const; + ZDD WeakDivF(const ZDD& g) const; + ZDD DivideF(const ZDD& g) const; + double CountMinterm(int path) const; + BDD PortToBdd() const; + ZDD Ite(const ZDD& g, const ZDD& h) const; + ZDD Union(const ZDD& Q) const; + ZDD Intersect(const ZDD& Q) const; + ZDD Diff(const ZDD& Q) const; + ZDD DiffConst(const ZDD& Q) const; + ZDD Subset1(int var) const; + ZDD Subset0(int var) const; + ZDD Change(int var) const; + void PrintMinterm() const; + void PrintCover() const; + BDD Support() const; + +}; // ZDD + + +/**Class*********************************************************************** + + Synopsis [Class for CUDD managers.] + + Description [] + + SeeAlso [DD] + +******************************************************************************/ +class Cudd { + friend class DD; + friend class ABDD; + friend class BDD; + friend class ADD; + friend class ZDD; +private: + Capsule *p; +public: + Cudd( + unsigned int numVars = 0, + unsigned int numVarsZ = 0, + unsigned int numSlots = CUDD_UNIQUE_SLOTS, + unsigned int cacheSize = CUDD_CACHE_SLOTS, + unsigned long maxMemory = 0); + Cudd(const Cudd& x); + ~Cudd(); + PFC setHandler(PFC newHandler) const; + PFC getHandler() const; + PFC setTimeoutHandler(PFC newHandler) const; + PFC getTimeoutHandler() const; + DdManager *getManager() const {return p->manager;} + inline void makeVerbose() const {p->verbose = 1;} + inline void makeTerse() {p->verbose = 0;} + inline bool isVerbose() const {return p->verbose;} + inline void checkReturnValue(const DdNode *result) const; + inline void checkReturnValue(const int result) const; + Cudd& operator=(const Cudd& right); + void info() const; + BDD bddVar() const; + BDD bddVar(int index) const; + BDD bddOne() const; + BDD bddZero() const; + ADD addVar() const; + ADD addVar(int index) const; + ADD addOne() const; + ADD addZero() const; + ADD constant(CUDD_VALUE_TYPE c) const; + ADD plusInfinity() const; + ADD minusInfinity() const; + ZDD zddVar(int index) const; + ZDD zddOne(int i) const; + ZDD zddZero() const; + ADD addNewVarAtLevel(int level) const; + BDD bddNewVarAtLevel(int level) const; + void zddVarsFromBddVars(int multiplicity) const; + unsigned long ReadStartTime() const; + unsigned long ReadElapsedTime() const; + void SetStartTime(unsigned long st) const; + void ResetStartTime() const; + unsigned long ReadTimeLimit() const; + void SetTimeLimit(unsigned long tl) const; + void UpdateTimeLimit() const; + void IncreaseTimeLimit(unsigned long increase) const; + void UnsetTimeLimit() const; + bool TimeLimited() const; + void AutodynEnable(Cudd_ReorderingType method) const; + void AutodynDisable() const; + bool ReorderingStatus(Cudd_ReorderingType * method) const; + void AutodynEnableZdd(Cudd_ReorderingType method) const; + void AutodynDisableZdd() const; + bool ReorderingStatusZdd(Cudd_ReorderingType * method) const; + bool zddRealignmentEnabled() const; + void zddRealignEnable() const; + void zddRealignDisable() const; + bool bddRealignmentEnabled() const; + void bddRealignEnable() const; + void bddRealignDisable() const; + ADD background() const; + void SetBackground(ADD bg) const; + unsigned int ReadCacheSlots() const; + double ReadCacheUsedSlots() const; + double ReadCacheLookUps() const; + double ReadCacheHits() const; + unsigned int ReadMinHit() const; + void SetMinHit(unsigned int hr) const; + unsigned int ReadLooseUpTo() const; + void SetLooseUpTo(unsigned int lut) const; + unsigned int ReadMaxCache() const; + unsigned int ReadMaxCacheHard() const; + void SetMaxCacheHard(unsigned int mc) const; + int ReadSize() const; + int ReadZddSize() const; + unsigned int ReadSlots() const; + unsigned int ReadKeys() const; + unsigned int ReadDead() const; + unsigned int ReadMinDead() const; + unsigned int ReadReorderings() const; + unsigned int ReadMaxReorderings() const; + void SetMaxReorderings(unsigned int mr) const; + long ReadReorderingTime() const; + int ReadGarbageCollections() const; + long ReadGarbageCollectionTime() const; + int ReadSiftMaxVar() const; + void SetSiftMaxVar(int smv) const; + int ReadSiftMaxSwap() const; + void SetSiftMaxSwap(int sms) const; + double ReadMaxGrowth() const; + void SetMaxGrowth(double mg) const; + MtrNode * ReadTree() const; + void SetTree(MtrNode * tree) const; + void FreeTree() const; + MtrNode * ReadZddTree() const; + void SetZddTree(MtrNode * tree) const; + void FreeZddTree() const; + int ReadPerm(int i) const; + int ReadPermZdd(int i) const; + int ReadInvPerm(int i) const; + int ReadInvPermZdd(int i) const; + BDD ReadVars(int i) const; + CUDD_VALUE_TYPE ReadEpsilon() const; + void SetEpsilon(CUDD_VALUE_TYPE ep) const; + Cudd_AggregationType ReadGroupcheck() const; + void SetGroupcheck(Cudd_AggregationType gc) const; + bool GarbageCollectionEnabled() const; + void EnableGarbageCollection() const; + void DisableGarbageCollection() const; + bool DeadAreCounted() const; + void TurnOnCountDead() const; + void TurnOffCountDead() const; + int ReadRecomb() const; + void SetRecomb(int recomb) const; + int ReadSymmviolation() const; + void SetSymmviolation(int symmviolation) const; + int ReadArcviolation() const; + void SetArcviolation(int arcviolation) const; + int ReadPopulationSize() const; + void SetPopulationSize(int populationSize) const; + int ReadNumberXovers() const; + void SetNumberXovers(int numberXovers) const; + unsigned int ReadOrderRandomization() const; + void SetOrderRandomization(unsigned int factor) const; + unsigned long ReadMemoryInUse() const; + long ReadPeakNodeCount() const; + long ReadNodeCount() const; + long zddReadNodeCount() const; + void AddHook(DD_HFP f, Cudd_HookType where) const; + void RemoveHook(DD_HFP f, Cudd_HookType where) const; + bool IsInHook(DD_HFP f, Cudd_HookType where) const; + void EnableReorderingReporting() const; + void DisableReorderingReporting() const; + bool ReorderingReporting() const; + int ReadErrorCode() const; + void ClearErrorCode() const; + FILE *ReadStdout() const; + void SetStdout(FILE *) const; + FILE *ReadStderr() const; + void SetStderr(FILE *) const; + unsigned int ReadNextReordering() const; + void SetNextReordering(unsigned int) const; + double ReadSwapSteps() const; + unsigned int ReadMaxLive() const; + void SetMaxLive(unsigned int) const; + unsigned long ReadMaxMemory() const; + void SetMaxMemory(unsigned long) const; + int bddBindVar(int) const; + int bddUnbindVar(int) const; + bool bddVarIsBound(int) const; + ADD Walsh(std::vector x, std::vector y); + ADD addResidue(int n, int m, int options, int top); + int ApaNumberOfDigits(int binaryDigits) const; + DdApaNumber NewApaNumber(int digits) const; + void ApaCopy(int digits, DdApaNumber source, DdApaNumber dest) const; + DdApaDigit ApaAdd(int digits, DdApaNumber a, DdApaNumber b, DdApaNumber + sum) const; + DdApaDigit ApaSubtract(int digits, DdApaNumber a, DdApaNumber b, + DdApaNumber diff) const; + DdApaDigit ApaShortDivision(int digits, DdApaNumber dividend, DdApaDigit + divisor, DdApaNumber quotient) const; + void ApaShiftRight(int digits, DdApaDigit in, DdApaNumber a, DdApaNumber + b) const; + void ApaSetToLiteral(int digits, DdApaNumber number, DdApaDigit literal) + const; + void ApaPowerOfTwo(int digits, DdApaNumber number, int power) const; + void ApaPrintHex(FILE * fp, int digits, DdApaNumber number) const; + void ApaPrintDecimal(FILE * fp, int digits, DdApaNumber number) const; + void DebugCheck(); + void CheckKeys(); + MtrNode * MakeTreeNode(unsigned int low, unsigned int size, unsigned int type) const; + // void Harwell(FILE * fp, ADD* E, ADD** x, ADD** y, ADD** xn, ADD** yn_, int * nx, int * ny, int * m, int * n, int bx, int sx, int by, int sy, int pr); + void PrintLinear(); + int ReadLinear(int x, int y); + BDD Xgty(std::vector z, std::vector x, std::vector y); + BDD Xeqy(std::vector x, std::vector y); + ADD Xeqy(std::vector x, std::vector y); + BDD Dxygtdxz(std::vector x, std::vector y, std::vector z); + BDD Dxygtdyz(std::vector x, std::vector y, std::vector z); + BDD Inequality(int c, std::vector x, std::vector y); + BDD Disequality(int c, std::vector x, std::vector y); + BDD Interval(std::vector x, unsigned int lowerB, unsigned int upperB); + ADD Hamming(std::vector xVars, std::vector yVars); + // void Read(FILE * fp, ADD* E, ADD** x, ADD** y, ADD** xn, ADD** yn_, int * nx, int * ny, int * m, int * n, int bx, int sx, int by, int sy); + // void Read(FILE * fp, BDD* E, BDD** x, BDD** y, int * nx, int * ny, int * m, int * n, int bx, int sx, int by, int sy); + void ReduceHeap(Cudd_ReorderingType heuristic, int minsize); + void ShuffleHeap(int * permutation); + void SymmProfile(int lower, int upper) const; + unsigned int Prime(unsigned int pr) const; + void Reserve(int amount) const; + int SharingSize(DD* nodes, int n) const; + int SharingSize(const std::vector& v) const; + BDD bddComputeCube(BDD * vars, int * phase, int n) const; + ADD addComputeCube(ADD * vars, int * phase, int n); + int NextNode(DdGen * gen, BDD * nnode); + BDD IndicesToCube(int * array, int n); + void PrintVersion(FILE * fp) const; + double AverageDistance() const; + long Random() const; + void Srandom(long seed) const; + MtrNode * MakeZddTreeNode(unsigned int low, unsigned int size, unsigned int type); + void zddPrintSubtable() const; + void zddReduceHeap(Cudd_ReorderingType heuristic, int minsize); + void zddShuffleHeap(int * permutation); + void zddSymmProfile(int lower, int upper) const; + void DumpDot( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + void DumpDaVinci( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + void DumpBlif( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + char * mname = 0, + FILE * fp = stdout, + int mv = 0) const; + void DumpDDcal( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + void DumpFactoredForm( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + BDD VectorSupport(const std::vector& roots) const; + std::vector + SupportIndices(const std::vector& roots) const; + int nodeCount(const std::vector& roots) const; + int VectorSupportSize(const std::vector& roots) const; + void DumpDot( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + void DumpDaVinci( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + BDD VectorSupport(const std::vector& roots) const; + int VectorSupportSize(const std::vector& roots) const; + void DumpDot( + const std::vector& nodes, + char ** inames = 0, + char ** onames = 0, + FILE * fp = stdout) const; + +}; // Cudd + + +extern void defaultError(std::string message); + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/dddmp.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/dddmp.h new file mode 100644 index 000000000..7228fe7ff --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/dddmp.h @@ -0,0 +1,330 @@ +/**CHeaderFile***************************************************************** + + FileName [dddmp.h] + + PackageName [dddmp] + + Synopsis [Functions to read in and write out BDDs, ADDs + and CNF formulas from and to files.] + + Description [] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2002 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#ifndef _DDDMP +#define _DDDMP + +#if 0 +#define DDDMP_DEBUG +#endif + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#include "util.h" +#include "cudd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* + * Dddmp format version + */ + +#define DDDMP_VERSION "DDDMP-2.0" + +/* + * Returned values (for theorically ALL the function of the package) + */ + +#define DDDMP_FAILURE ((int) 0) +#define DDDMP_SUCCESS ((int) 1) + +/* + * Format modes for DD (BDD and ADD) files + */ + +#define DDDMP_MODE_TEXT ((int)'A') +#define DDDMP_MODE_BINARY ((int)'B') +#define DDDMP_MODE_DEFAULT ((int)'D') + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/**Enum************************************************************************ + + Synopsis [Format modes for storing CNF files] + + Description [Type supported for storing BDDs into CNF + formulas. + Used internally to select the proper storing format: + DDDMP_CNF_MODE_NODE: create a CNF temporary variables for + each BDD node + DDDMP_CNF_MODE_MAXTERM: no temporary variables + DDDMP_CNF_MODE_BEST: trade-off between the two previous methods + ] + +******************************************************************************/ + +typedef enum { + DDDMP_CNF_MODE_NODE, + DDDMP_CNF_MODE_MAXTERM, + DDDMP_CNF_MODE_BEST +} Dddmp_DecompCnfStoreType; + +/**Enum************************************************************************ + + Synopsis [Format modes for loading CNF files.] + + Description [Type supported for loading CNF formulas into BDDs. + Used internally to select the proper returning format: + ] + +******************************************************************************/ + +typedef enum { + DDDMP_CNF_MODE_NO_CONJ, + DDDMP_CNF_MODE_NO_QUANT, + DDDMP_CNF_MODE_CONJ_QUANT +} Dddmp_DecompCnfLoadType; + +/**Enum************************************************************************ + + Synopsis [Type for supported decomposition types.] + + Description [Type for supported decomposition types. + Used internally to select the proper type (bdd, add, ...). + Given externally as information fule content. + ] + +******************************************************************************/ + +typedef enum { + DDDMP_BDD, + DDDMP_ADD, + DDDMP_CNF, + DDDMP_NONE +} Dddmp_DecompType; + + +/**Enum************************************************************************ + + Synopsis [Type for variable extra info.] + + Description [Type for variable extra info. Used to specify info stored + in text mode.] + +******************************************************************************/ + +typedef enum { + DDDMP_VARIDS, + DDDMP_VARPERMIDS, + DDDMP_VARAUXIDS, + DDDMP_VARNAMES, + DDDMP_VARDEFAULT +} Dddmp_VarInfoType; + +/**Enum************************************************************************ + + Synopsis [Type for variable matching in BDD load.] + + Description [] + +******************************************************************************/ + +typedef enum { + DDDMP_VAR_MATCHIDS, + DDDMP_VAR_MATCHPERMIDS, + DDDMP_VAR_MATCHAUXIDS, + DDDMP_VAR_MATCHNAMES, + DDDMP_VAR_COMPOSEIDS +} Dddmp_VarMatchType; + +/**Enum************************************************************************ + + Synopsis [Type for BDD root matching in BDD load.] + + Description [] + +******************************************************************************/ + +typedef enum { + DDDMP_ROOT_MATCHNAMES, + DDDMP_ROOT_MATCHLIST +} Dddmp_RootMatchType; + +typedef struct Dddmp_Hdr_s Dddmp_Hdr_t; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Checks for fatal bugs] + + Description [Conditional safety assertion. It prints out the file + name and line number where the fatal error occurred. + Messages are printed out on stderr. + ] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#ifdef DDDMP_DEBUG +# define Dddmp_Assert(expr,errMsg) \ + { \ + if ((expr) == 0) { \ + fprintf (stderr, "FATAL ERROR: %s\n", errMsg); \ + fprintf (stderr, " File %s -> Line %d\n", \ + __FILE__, __LINE__); \ + fflush (stderr); \ + exit (DDDMP_FAILURE); \ + } \ + } +#else +# define Dddmp_Assert(expr,errMsg) \ + {} +#endif + +/**Macro*********************************************************************** + + Synopsis [Checks for Warnings: If expr==1 it prints out the warning + on stderr.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#define Dddmp_Warning(expr,errMsg) \ + { \ + if ((expr) == 1) { \ + fprintf (stderr, "WARNING: %s\n", errMsg); \ + fprintf (stderr, " File %s -> Line %d\n", \ + __FILE__, __LINE__); \ + fflush (stderr); \ + } \ + } + +/**Macro*********************************************************************** + + Synopsis [Checks for fatal bugs and return the DDDMP_FAILURE flag.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#define Dddmp_CheckAndReturn(expr,errMsg) \ + { \ + if ((expr) == 1) { \ + fprintf (stderr, "FATAL ERROR: %s\n", errMsg); \ + fprintf (stderr, " File %s -> Line %d\n", \ + __FILE__, __LINE__); \ + fflush (stderr); \ + return (DDDMP_FAILURE); \ + } \ + } + +/**Macro*********************************************************************** + + Synopsis [Checks for fatal bugs and go to the label to deal with + the error. + ] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#define Dddmp_CheckAndGotoLabel(expr,errMsg,label) \ + { \ + if ((expr) == 1) { \ + fprintf (stderr, "FATAL ERROR: %s\n", errMsg); \ + fprintf (stderr, " File %s -> Line %d\n", \ + __FILE__, __LINE__); \ + fflush (stderr); \ + goto label; \ + } \ + } + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern int Dddmp_Text2Bin(char *filein, char *fileout); +extern int Dddmp_Bin2Text(char *filein, char *fileout); +extern int Dddmp_cuddBddDisplayBinary(char *fileIn, char *fileOut); +extern DdNode * Dddmp_cuddBddLoad(DdManager *ddMgr, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp); +extern int Dddmp_cuddBddArrayLoad(DdManager *ddMgr, Dddmp_RootMatchType rootMatchMode, char **rootmatchnames, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***pproots); +extern DdNode * Dddmp_cuddAddLoad(DdManager *ddMgr, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp); +extern int Dddmp_cuddAddArrayLoad(DdManager *ddMgr, Dddmp_RootMatchType rootMatchMode, char **rootmatchnames, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***pproots); +extern int Dddmp_cuddHeaderLoad (Dddmp_DecompType *ddType, int *nVars, int *nsuppvars, char ***suppVarNames, char ***orderedVarNames, int **varIds, int **composeIds, int **auxIds, int *nRoots, char *file, FILE *fp); +extern int Dddmp_cuddBddLoadCnf(DdManager *ddMgr, Dddmp_VarMatchType varmatchmode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***rootsPtrPtr, int *nRoots); +extern int Dddmp_cuddBddArrayLoadCnf(DdManager *ddMgr, Dddmp_RootMatchType rootmatchmode, char **rootmatchnames, Dddmp_VarMatchType varmatchmode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***rootsPtrPtr, int *nRoots); +extern int Dddmp_cuddHeaderLoadCnf (int *nVars, int *nsuppvars, char ***suppVarNames, char ***orderedVarNames, int **varIds, int **composeIds, int **auxIds, int *nRoots, char *file, FILE *fp); +extern int Dddmp_cuddAddStore(DdManager *ddMgr, char *ddname, DdNode *f, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int Dddmp_cuddAddArrayStore(DdManager *ddMgr, char *ddname, int nRoots, DdNode **f, char **rootnames, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int Dddmp_cuddBddStore(DdManager *ddMgr, char *ddname, DdNode *f, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int Dddmp_cuddBddArrayStore(DdManager *ddMgr, char *ddname, int nRoots, DdNode **f, char **rootnames, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int Dddmp_cuddBddStoreCnf(DdManager *ddMgr, DdNode *f, Dddmp_DecompCnfStoreType mode, int noHeader, char **varNames, int *bddIds, int *bddAuxIds, int *cnfIds, int idInitial, int edgeInTh, int pathLengthTh, char *fname, FILE *fp, int *clauseNPtr, int *varNewNPtr); +extern int Dddmp_cuddBddArrayStoreCnf(DdManager *ddMgr, DdNode **f, int rootN, Dddmp_DecompCnfStoreType mode, int noHeader, char **varNames, int *bddIds, int *bddAuxIds, int *cnfIds, int idInitial, int edgeInTh, int pathLengthTh, char *fname, FILE *fp, int *clauseNPtr, int *varNewNPtr); +extern int Dddmp_cuddBddStorePrefix(DdManager *ddMgr, int nRoots, DdNode *f, char **inputNames, char **outputNames, char *modelName, char *fileName, FILE *fp); +extern int Dddmp_cuddBddArrayStorePrefix(DdManager *ddMgr, int nroots, DdNode **f, char **inputNames, char **outputNames, char *modelName, char *fname, FILE *fp); +extern int Dddmp_cuddBddStoreBlif(DdManager *ddMgr, int nRoots, DdNode *f, char **inputNames, char **outputNames, char *modelName, char *fileName, FILE *fp); +extern int Dddmp_cuddBddArrayStoreBlif(DdManager *ddMgr, int nroots, DdNode **f, char **inputNames, char **outputNames, char *modelName, char *fname, FILE *fp); +extern int Dddmp_cuddBddStoreSmv(DdManager *ddMgr, int nRoots, DdNode *f, char **inputNames, char **outputNames, char *modelName, char *fileName, FILE *fp); +extern int Dddmp_cuddBddArrayStoreSmv(DdManager *ddMgr, int nroots, DdNode **f, char **inputNames, char **outputNames, char *modelName, char *fname, FILE *fp); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/dddmpInt.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/dddmpInt.h new file mode 100644 index 000000000..7d0f54dfc --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/dddmpInt.h @@ -0,0 +1,216 @@ +/**CHeaderFile***************************************************************** + + FileName [dddmpInt.h] + + PackageName [dddmp] + + Synopsis [Low level functions to read in and write out bdds to file] + + Description [A set of internal low-level routines of the dddmp package + doing: +

                            +
                          • read and write of node codes in binary mode, +
                          • read and write of integers in binary mode, +
                          • marking/unmarking nodes as visited, +
                          • numbering nodes. +
                          + ] + + Author [Gianpiero Cabodi and Stefano Quer] + + Copyright [ + Copyright (c) 2002 by Politecnico di Torino. + All Rights Reserved. This software is for educational purposes only. + Permission is given to academic institutions to use, copy, and modify + this software and its documentation provided that this introductory + message is not removed, that this software and its documentation is + used for the institutions' internal research and educational purposes, + and that no monies are exchanged. No guarantee is expressed or implied + by the distribution of this code. + Send bug-reports and/or questions to: + {gianpiero.cabodi,stefano.quer}@polito.it. + ] + +******************************************************************************/ + +#ifndef _DDDMPINT +#define _DDDMPINT + +#include "dddmp.h" +#include "cuddInt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/* constants for code fields */ +#define DDDMP_TERMINAL 0 +#define DDDMP_ABSOLUTE_ID 1 +#define DDDMP_RELATIVE_ID 2 +#define DDDMP_RELATIVE_1 3 + +#define DDDMP_MAXSTRLEN 500 + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + +/**Struct********************************************************************** + Synopsis [used in binary mode to store code info of a dd node] + Description [V , T , E store the mode used to represent variable, Then + and Else indexes. An index is either an absolute + ( DDDMP_ABSOLUTE_ID ), + a relative numbers ( DDDMP_RELATIVE_ID , DDDMP_RELATIVE_1 ) or + a terminal node ( DDDMP_TERMINAL ) . + Ecomp is used for the complemented edge attribute. + ] + SideEffect [none] + SeeAlso [DddmpWriteCode DddmpReadCode] +******************************************************************************/ + +struct binary_dd_code { + unsigned Unused : 1; + unsigned V : 2; + unsigned T : 2; + unsigned Ecompl : 1; + unsigned E : 2; +}; + +/**Struct********************************************************************* + + Synopsis [BDD file header] + + Description [Structure containing the BDD header file infos] + +******************************************************************************/ + +struct Dddmp_Hdr_s { + char *ver; + char mode; + Dddmp_DecompType ddType; + Dddmp_VarInfoType varinfo; + char *dd; + int nnodes; + int nVars; + int nsuppvars; + char **orderedVarNames; + char **suppVarNames; + int *ids; + int *permids; + int *auxids; + int *cnfids; + int nRoots; + int *rootids; + char **rootnames; + int nAddedCnfVar; + int nVarsCnf; + int nClausesCnf; +}; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Memory Allocation Macro for DDDMP] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#ifdef ALLOC +# define DDDMP_ALLOC(type, num) ALLOC(type,num) +#else +# define DDDMP_ALLOC(type, num) \ + ((type *) malloc(sizeof(type) * (num))) +#endif + +/**Macro*********************************************************************** + + Synopsis [Memory Free Macro for DDDMP] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ + +#ifdef FREE +#define DDDMP_FREE(p) (FREE(p)) +#else +#define DDDMP_FREE(p) \ + ((p)!=NULL)?(free(p)):0) +#endif + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern int DddmpWriteCode(FILE *fp, struct binary_dd_code code); +extern int DddmpReadCode(FILE *fp, struct binary_dd_code *pcode); +extern int DddmpWriteInt(FILE *fp, int id); +extern int DddmpReadInt(FILE *fp, int *pid); +extern int DddmpNumberAddNodes(DdManager *ddMgr, DdNode **f, int n); +extern void DddmpUnnumberAddNodes(DdManager *ddMgr, DdNode **f, int n); +extern void DddmpWriteNodeIndexAdd(DdNode *f, int id); +extern int DddmpReadNodeIndexAdd(DdNode *f); +extern int DddmpVisitedAdd(DdNode *f); +extern void DddmpSetVisitedAdd(DdNode *f); +extern void DddmpClearVisitedAdd(DdNode *f); +extern int DddmpNumberBddNodes(DdManager *ddMgr, DdNode **f, int n); +extern void DddmpUnnumberBddNodes(DdManager *ddMgr, DdNode **f, int n); +extern void DddmpWriteNodeIndexBdd(DdNode *f, int id); +extern int DddmpReadNodeIndexBdd(DdNode *f); +extern int DddmpVisitedBdd(DdNode *f); +extern void DddmpSetVisitedBdd(DdNode *f); +extern void DddmpClearVisitedBdd(DdNode *f); +extern int DddmpNumberDdNodesCnf(DdManager *ddMgr, DdNode **f, int rootN, int *cnfIds, int id); +extern int DddmpDdNodesCountEdgesAndNumber(DdManager *ddMgr, DdNode **f, int rootN, int edgeInTh, int pathLengthTh, int *cnfIds, int id); +extern void DddmpUnnumberDdNodesCnf(DdManager *ddMgr, DdNode **f, int rootN); +extern int DddmpPrintBddAndNext(DdManager *ddMgr, DdNode **f, int rootN); +extern int DddmpWriteNodeIndexCnf(DdNode *f, int id); +extern int DddmpVisitedCnf(DdNode *f); +extern void DddmpSetVisitedCnf(DdNode *f); +extern int DddmpReadNodeIndexCnf(DdNode *f); +extern int DddmpCuddDdArrayStoreBdd(Dddmp_DecompType ddType, DdManager *ddMgr, char *ddname, int nRoots, DdNode **f, char **rootnames, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int DddmpCuddBddArrayStore(Dddmp_DecompType ddType, DdManager *ddMgr, char *ddname, int nRoots, DdNode **f, char **rootnames, char **varnames, int *auxids, int mode, Dddmp_VarInfoType varinfo, char *fname, FILE *fp); +extern int QsortStrcmp(const void *ps1, const void *ps2); +extern int FindVarname(char *name, char **array, int n); +extern char * DddmpStrDup(char *str); +extern char ** DddmpStrArrayDup(char **array, int n); +extern char ** DddmpStrArrayRead(FILE *fp, int n); +extern int DddmpStrArrayWrite(FILE *fp, char **array, int n); +extern void DddmpStrArrayFree(char **array, int n); +extern int * DddmpIntArrayDup(int *array, int n); +extern int * DddmpIntArrayRead(FILE *fp, int n); +extern int DddmpIntArrayWrite(FILE *fp, int *array, int n); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/epd.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/epd.h new file mode 100644 index 000000000..4b538c016 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/epd.h @@ -0,0 +1,200 @@ +/**CHeaderFile***************************************************************** + + FileName [epd.h] + + PackageName [epd] + + Synopsis [The University of Colorado extended double precision package.] + + Description [arithmetic functions with extended double precision.] + + SeeAlso [] + + Author [In-Ho Moon] + + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: epd.h,v 1.9 2004/08/13 18:20:30 fabio Exp $] + +******************************************************************************/ + +#ifndef _EPD +#define _EPD + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define EPD_MAX_BIN 1023 +#define EPD_MAX_DEC 308 +#define EPD_EXP_INF 0x7ff + +/*---------------------------------------------------------------------------*/ +/* Structure declarations */ +/*---------------------------------------------------------------------------*/ + +/**Struct********************************************************************** + + Synopsis [IEEE double struct.] + + Description [IEEE double struct.] + + SeeAlso [] + +******************************************************************************/ +#ifdef EPD_BIG_ENDIAN +struct IeeeDoubleStruct { /* BIG_ENDIAN */ + unsigned int sign: 1; + unsigned int exponent: 11; + unsigned int mantissa0: 20; + unsigned int mantissa1: 32; +}; +#else +struct IeeeDoubleStruct { /* LITTLE_ENDIAN */ + unsigned int mantissa1: 32; + unsigned int mantissa0: 20; + unsigned int exponent: 11; + unsigned int sign: 1; +}; +#endif + +/**Struct********************************************************************** + + Synopsis [IEEE double NaN struct.] + + Description [IEEE double NaN struct.] + + SeeAlso [] + +******************************************************************************/ +#ifdef EPD_BIG_ENDIAN +struct IeeeNanStruct { /* BIG_ENDIAN */ + unsigned int sign: 1; + unsigned int exponent: 11; + unsigned int quiet_bit: 1; + unsigned int mantissa0: 19; + unsigned int mantissa1: 32; +}; +#else +struct IeeeNanStruct { /* LITTLE_ENDIAN */ + unsigned int mantissa1: 32; + unsigned int mantissa0: 19; + unsigned int quiet_bit: 1; + unsigned int exponent: 11; + unsigned int sign: 1; +}; +#endif + +/**Struct********************************************************************** + + Synopsis [Extended precision double to keep very large value.] + + Description [Extended precision double to keep very large value.] + + SeeAlso [] + +******************************************************************************/ +union EpTypeUnion { + double value; + struct IeeeDoubleStruct bits; + struct IeeeNanStruct nan; +}; + +struct EpDoubleStruct { + union EpTypeUnion type; + int exponent; +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ +typedef struct EpDoubleStruct EpDouble; +typedef struct IeeeDoubleStruct IeeeDouble; +typedef struct IeeeNanStruct IeeeNan; +typedef union EpTypeUnion EpType; + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern EpDouble *EpdAlloc(void); +extern int EpdCmp(const char *key1, const char *key2); +extern void EpdFree(EpDouble *epd); +extern void EpdGetString(EpDouble *epd, char *str); +extern void EpdConvert(double value, EpDouble *epd); +extern void EpdMultiply(EpDouble *epd1, double value); +extern void EpdMultiply2(EpDouble *epd1, EpDouble *epd2); +extern void EpdMultiply2Decimal(EpDouble *epd1, EpDouble *epd2); +extern void EpdMultiply3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdMultiply3Decimal(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdDivide(EpDouble *epd1, double value); +extern void EpdDivide2(EpDouble *epd1, EpDouble *epd2); +extern void EpdDivide3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdAdd(EpDouble *epd1, double value); +extern void EpdAdd2(EpDouble *epd1, EpDouble *epd2); +extern void EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdSubtract(EpDouble *epd1, double value); +extern void EpdSubtract2(EpDouble *epd1, EpDouble *epd2); +extern void EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdPow2(int n, EpDouble *epd); +extern void EpdPow2Decimal(int n, EpDouble *epd); +extern void EpdNormalize(EpDouble *epd); +extern void EpdNormalizeDecimal(EpDouble *epd); +extern void EpdGetValueAndDecimalExponent(EpDouble *epd, double *value, int *exponent); +extern int EpdGetExponent(double value); +extern int EpdGetExponentDecimal(double value); +extern void EpdMakeInf(EpDouble *epd, int sign); +extern void EpdMakeZero(EpDouble *epd, int sign); +extern void EpdMakeNan(EpDouble *epd); +extern void EpdCopy(EpDouble *from, EpDouble *to); +extern int EpdIsInf(EpDouble *epd); +extern int EpdIsZero(EpDouble *epd); +extern int EpdIsNan(EpDouble *epd); +extern int EpdIsNanOrInf(EpDouble *epd); +extern int IsInfDouble(double value); +extern int IsNanDouble(double value); +extern int IsNanOrInfDouble(double value); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* _EPD */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/mnemosyne.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/mnemosyne.h new file mode 100644 index 000000000..910af91d5 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/mnemosyne.h @@ -0,0 +1,73 @@ +/************************************************************************ + * * + * Copyright (c) 1985 by * + * Digital Equipment Corporation, Maynard, MA * + * All rights reserved. * + * * + * The information in this software is subject to change without * + * notice and should not be construed as a commitment by Digital * + * Equipment Corporation. * + * * + * Digital assumes no responsibility for the use or reliability * + * of its software on equipment which is not supplied by Digital. * + * * + * Redistribution and use in source and binary forms are permitted * + * provided that the above copyright notice and this paragraph are * + * duplicated in all such forms and that any documentation, * + * advertising materials, and other materials related to such * + * distribution and use acknowledge that the software was developed * + * by Digital Equipment Corporation. The name of Digital Equipment * + * Corporation may not be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.* + * Do not take internally. In case of accidental ingestion, contact * + * your physician immediately. * + * * + ************************************************************************/ + +#ifndef _INCL_MNEMOSYNE_H + +/* +/fats/tools/hsv/mnemosyne/mnemosyne.h,v 1.1.1.1 1995/06/06 18:18:28 fabio Exp +*/ + + +/* +main include file for the mnemosyne memory allocation tracker. this file +provides some pre-processor fakes for malloc(), realloc() and family, +as well as forward declarations for the mnemosyne functions. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + +/* these disguise mnemosyne calls as calls to malloc and family */ +#ifndef NOFAKEMALLOC +#define malloc(siz) mnem_malloc(siz,__FILE__,__LINE__) +#define calloc(siz,cnt) mnem_calloc(siz,cnt,__FILE__,__LINE__) +#define realloc(ptr,siz) mnem_realloc(ptr,siz,__FILE__,__LINE__) +#define free(ptr) mnem_free(ptr,__FILE__,__LINE__) +#endif + + +#ifdef MALLOC_IS_VOIDSTAR +typedef void *mall_t; +#else +typedef char *mall_t; +#endif + +extern mall_t mnem_malloc(); +extern mall_t mnem_calloc(); +extern mall_t mnem_realloc(); +extern void mnem_free(); + +/* some internal functions and oddimentia */ +extern int mnem_recording(); +extern int mnem_setrecording(); +extern void mnem_setlog(); +extern int mnem_writestats(); + +#define _INCL_MNEMOSYNE_H +#endif diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/mtr.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/mtr.h new file mode 100644 index 000000000..9cbb2d3a4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/mtr.h @@ -0,0 +1,187 @@ +/**CHeaderFile***************************************************************** + + FileName [mtr.h] + + PackageName [mtr] + + Synopsis [Multiway-branch tree manipulation] + + Description [This package provides two layers of functions. Functions + of the lower level manipulate multiway-branch trees, implemented + according to the classical scheme whereby each node points to its + first child and its previous and next siblings. These functions are + collected in mtrBasic.c.

                          + Functions of the upper layer deal with group trees, that is the trees + used by group sifting to represent the grouping of variables. These + functions are collected in mtrGroup.c.] + + SeeAlso [The CUDD package documentation; specifically on group + sifting.] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: mtr.h,v 1.17 2012/02/05 01:06:19 fabio Exp $] + +******************************************************************************/ + +#ifndef __MTR +#define __MTR + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef SIZEOF_VOID_P +#define SIZEOF_VOID_P 4 +#endif +#ifndef SIZEOF_INT +#define SIZEOF_INT 4 +#endif + +#if defined(__GNUC__) +#define MTR_INLINE __inline__ +# if (__GNUC__ >2 || __GNUC_MINOR__ >=7) +# define MTR_UNUSED __attribute__ ((unused)) +# else +# define MTR_UNUSED +# endif +#else +#define MTR_INLINE +#define MTR_UNUSED +#endif + +/* Flag definitions */ +#define MTR_DEFAULT 0x00000000 +#define MTR_TERMINAL 0x00000001 +#define MTR_SOFT 0x00000002 +#define MTR_FIXED 0x00000004 +#define MTR_NEWNODE 0x00000008 + +/* MTR_MAXHIGH is defined in such a way that on 32-bit and 64-bit +** machines one can cast a value to (int) without generating a negative +** number. +*/ +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +#define MTR_MAXHIGH (((MtrHalfWord) ~0) >> 1) +#else +#define MTR_MAXHIGH ((MtrHalfWord) ~0) +#endif + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +typedef unsigned int MtrHalfWord; +#else +typedef unsigned short MtrHalfWord; +#endif + +typedef struct MtrNode { + MtrHalfWord flags; + MtrHalfWord low; + MtrHalfWord size; + MtrHalfWord index; + struct MtrNode *parent; + struct MtrNode *child; + struct MtrNode *elder; + struct MtrNode *younger; +} MtrNode; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/* Flag manipulation macros */ +#define MTR_SET(node, flag) (node->flags |= (flag)) +#define MTR_RESET(node, flag) (node->flags &= ~ (flag)) +#define MTR_TEST(node, flag) (node->flags & (flag)) + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern MtrNode * Mtr_AllocNode (void); +extern void Mtr_DeallocNode (MtrNode *node); +extern MtrNode * Mtr_InitTree (void); +extern void Mtr_FreeTree (MtrNode *node); +extern MtrNode * Mtr_CopyTree (MtrNode *node, int expansion); +extern void Mtr_MakeFirstChild (MtrNode *parent, MtrNode *child); +extern void Mtr_MakeLastChild (MtrNode *parent, MtrNode *child); +extern MtrNode * Mtr_CreateFirstChild (MtrNode *parent); +extern MtrNode * Mtr_CreateLastChild (MtrNode *parent); +extern void Mtr_MakeNextSibling (MtrNode *first, MtrNode *second); +extern void Mtr_PrintTree (MtrNode *node); +extern MtrNode * Mtr_InitGroupTree (int lower, int size); +extern MtrNode * Mtr_MakeGroup (MtrNode *root, unsigned int low, unsigned int high, unsigned int flags); +extern MtrNode * Mtr_DissolveGroup (MtrNode *group); +extern MtrNode * Mtr_FindGroup (MtrNode *root, unsigned int low, unsigned int high); +extern int Mtr_SwapGroups (MtrNode *first, MtrNode *second); +extern void Mtr_ReorderGroups(MtrNode *treenode, int *permutation); + +extern void Mtr_PrintGroups (MtrNode *root, int silent); + extern int Mtr_PrintGroupedOrder(MtrNode * root, int *invperm, FILE *fp); +extern MtrNode * Mtr_ReadGroups (FILE *fp, int nleaves); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* __MTR */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/mtrInt.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/mtrInt.h new file mode 100644 index 000000000..00b2e9969 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/mtrInt.h @@ -0,0 +1,92 @@ +/**CHeaderFile***************************************************************** + + FileName [mtrInt.h] + + PackageName [mtr] + + Synopsis [Internal data structures of the mtr package] + + Description [In this package all definitions are external.] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: mtrInt.h,v 1.3 2012/02/05 01:06:19 fabio Exp $] + +******************************************************************************/ + +#ifndef _MTRINT +#define _MTRINT + +#include "mtr.h" + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + +#endif /* _MTRINT */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/st.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/st.h new file mode 100644 index 000000000..dbb14bbeb --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/st.h @@ -0,0 +1,232 @@ +/**CHeaderFile***************************************************************** + + FileName [st.h] + + PackageName [st] + + Synopsis [Symbol table package.] + + Description [The st library provides functions to create, maintain, + and query symbol tables.] + + SeeAlso [] + + Author [] + + Copyright [] + + Revision [$Id: st.h,v 1.10 2004/01/02 07:40:31 fabio Exp fabio $] + +******************************************************************************/ + +#ifndef ST_INCLUDED +#define ST_INCLUDED + +/*---------------------------------------------------------------------------*/ +/* Nested includes */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define ST_DEFAULT_MAX_DENSITY 5 +#define ST_DEFAULT_INIT_TABLE_SIZE 11 +#define ST_DEFAULT_GROW_FACTOR 2.0 +#define ST_DEFAULT_REORDER_FLAG 0 +#define ST_OUT_OF_MEM -10000 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef struct st_table_entry st_table_entry; +struct st_table_entry { + char *key; + char *record; + st_table_entry *next; +}; + +typedef struct st_table st_table; +struct st_table { + int (*compare)(const char *, const char *); + int (*hash)(char *, int); + int num_bins; + int num_entries; + int max_density; + int reorder_flag; + double grow_factor; + st_table_entry **bins; +}; + +typedef struct st_generator st_generator; +struct st_generator { + st_table *table; + st_table_entry *entry; + int index; +}; + +enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE}; + +typedef enum st_retval (*ST_PFSR)(char *, char *, char *); + +typedef int (*ST_PFICPCP)(const char *, const char *); /* type for comparison function */ + +typedef int (*ST_PFICPI)(char *, int); /* type for hash function */ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**Macro*********************************************************************** + + Synopsis [Checks whethere `key' is in `table'.] + + Description [Returns 1 if there is an entry under `key' in `table', 0 + otherwise.] + + SideEffects [None] + + SeeAlso [st_lookup] + +******************************************************************************/ +#define st_is_member(table,key) st_lookup(table,key,(char **) 0) + + +/**Macro*********************************************************************** + + Synopsis [Returns the number of entries in the table `table'.] + + Description [Returns the number of entries in the table `table'.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +#define st_count(table) ((table)->num_entries) + + +/**Macro*********************************************************************** + + Synopsis [Iteration macro.] + + Description [An iteration macro which loops over all the entries in + `table', setting `key' to point to the key and `value' to the + associated value (if it is not nil). `gen' is a generator variable + used internally. Sample usage: +

                          +     	char *key, *value;
                          +  
                          +
                          +	st_generator *gen;
                          +  
                          +
                          +
                          +	st_foreach_item(table, gen, &key, &value) {
                          +  
                          +
                          +	    process_item(value);
                          +  
                          +
                          +	}
                          +  
                          + ] + + SideEffects [None] + + SeeAlso [st_foreach_item_int st_foreach] + +******************************************************************************/ +#define st_foreach_item(table, gen, key, value) \ + for(gen=st_init_gen(table); st_gen(gen,key,value) || (st_free_gen(gen),0);) + + +/**Macro*********************************************************************** + + Synopsis [Iteration macro.] + + Description [An iteration macro which loops over all the entries in + `table', setting `key' to point to the key and `value' to the + associated value (if it is not nil). `value' is assumed to be a + pointer to an integer. `gen' is a generator variable used + internally. Sample usage: +
                          +     	char *key;
                          +  
                          +
                          +	int value;
                          +  
                          +
                          +	st_generator *gen;
                          +  
                          +
                          +
                          +	st_foreach_item_int(table, gen, &key, &value) {
                          +  
                          +
                          +	    process_item(value);
                          +  
                          +
                          +	}
                          +  
                          + ] + + SideEffects [None] + + SeeAlso [st_foreach_item st_foreach] + +******************************************************************************/ +#define st_foreach_item_int(table, gen, key, value) \ + for(gen=st_init_gen(table); st_gen_int(gen,key,value) || (st_free_gen(gen),0);) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Function prototypes */ +/*---------------------------------------------------------------------------*/ + +extern st_table *st_init_table_with_params (ST_PFICPCP, ST_PFICPI, int, int, double, int); +extern st_table *st_init_table (ST_PFICPCP, ST_PFICPI); +extern void st_free_table (st_table *); +extern int st_lookup (st_table *, void *, void *); +extern int st_lookup_int (st_table *, void *, int *); +extern int st_insert (st_table *, void *, void *); +extern int st_add_direct (st_table *, void *, void *); +extern int st_find_or_add (st_table *, void *, void *); +extern int st_find (st_table *, void *, void *); +extern st_table *st_copy (st_table *); +extern int st_delete (st_table *, void *, void *); +extern int st_delete_int (st_table *, void *, int *); +extern int st_foreach (st_table *, ST_PFSR, char *); +extern int st_strhash (char *, int); +extern int st_numhash (char *, int); +extern int st_ptrhash (char *, int); +extern int st_numcmp (const char *, const char *); +extern int st_ptrcmp (const char *, const char *); +extern st_generator *st_init_gen (st_table *); +extern int st_gen (st_generator *, void *, void *); +extern int st_gen_int (st_generator *, void *, int *); +extern void st_free_gen (st_generator *); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* ST_INCLUDED */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/util.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/util.h new file mode 100644 index 000000000..52c998839 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/include/util.h @@ -0,0 +1,204 @@ +/* $Id: util.h,v 1.10 2012/02/05 05:34:04 fabio Exp fabio $ */ + +#ifndef UTIL_H +#define UTIL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) +# define UTIL_INLINE __inline__ +# if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +# define UTIL_UNUSED __attribute__ ((unused)) +# else +# define UTIL_UNUSED +# endif +#else +# define UTIL_INLINE +# define UTIL_UNUSED +#endif + +#ifndef SIZEOF_VOID_P +#define SIZEOF_VOID_P 4 +#endif +#ifndef SIZEOF_INT +#define SIZEOF_INT 4 +#endif +#ifndef SIZEOF_LONG +#define SIZEOF_LONG 4 +#endif + +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 +typedef long util_ptrint; +#else +typedef int util_ptrint; +#endif + +/* #define USE_MM */ /* choose libmm.a as the memory allocator */ + +/* these are too entrenched to get away with changing the name */ +#define strsav util_strsav +//#include + +#define NIL(type) ((type *) 0) + +#if defined(USE_MM) || defined(MNEMOSYNE) +/* + * assumes the memory manager is either libmm.a or libmnem.a + * libmm.a: + * - allows malloc(0) or realloc(obj, 0) + * - catches out of memory (and calls MMout_of_memory()) + * - catch free(0) and realloc(0, size) in the macros + * libmnem.a: + * - reports memory leaks + * - is used in conjunction with the mnemalyse postprocessor + */ +#ifdef MNEMOSYNE +#include "mnemosyne.h" +#define ALLOC(type, num) \ + ((num) ? ((type *) malloc(sizeof(type) * (num))) : \ + ((type *) malloc(sizeof(long)))) +#else +#define ALLOC(type, num) \ + ((type *) malloc(sizeof(type) * (num))) +#endif +#define REALLOC(type, obj, num) \ + (obj) ? ((type *) realloc((char *) obj, sizeof(type) * (num))) : \ + ((type *) malloc(sizeof(type) * (num))) +#define FREE(obj) \ + ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) +#else +/* + * enforce strict semantics on the memory allocator + * - when in doubt, delete the '#define USE_MM' above + */ +#define ALLOC(type, num) \ + ((type *) MMalloc((long) sizeof(type) * (long) (num))) +#define REALLOC(type, obj, num) \ + ((type *) MMrealloc((char *) (obj), (long) sizeof(type) * (long) (num))) +#define FREE(obj) \ + ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) +#endif + + +/* Ultrix (and SABER) have 'fixed' certain functions which used to be int */ +#if defined(ultrix) || defined(SABER) || defined(aiws) || defined(hpux) || defined(apollo) || defined(__osf__) || defined(__SVR4) || defined(__GNUC__) +#define VOID_OR_INT void +#define VOID_OR_CHAR void +#else +#define VOID_OR_INT int +#define VOID_OR_CHAR char +#endif + + +/* No machines seem to have much of a problem with these */ +#include +//#include + + +/* Some machines fail to define some functions in stdio.h */ +#if !defined(__STDC__) && !defined(__cplusplus) +extern FILE *popen(), *tmpfile(); +extern int pclose(); +#endif + + +/* most machines don't give us a header file for these */ +#if (defined(__STDC__) || defined(__cplusplus) || defined(ultrix)) && !defined(MNEMOSYNE) || defined(__SVR4) +# include +#else +# ifndef _IBMR2 + extern VOID_OR_INT abort(), exit(); +# endif +# if !defined(MNEMOSYNE) && !defined(_IBMR2) + extern VOID_OR_INT free (void *); + extern VOID_OR_CHAR *malloc(), *realloc(); +# endif + extern char *getenv(); + extern int system(); + extern double atof(); +#endif + + +/* some call it strings.h, some call it string.h; others, also have memory.h */ +#if defined(__STDC__) || defined(__cplusplus) || defined(_IBMR2) || defined(ultrix) +#include +#else +/* ANSI C string.h -- 1/11/88 Draft Standard */ +extern char *strcpy(), *strncpy(), *strcat(), *strncat(), *strerror(); +extern char *strpbrk(), *strtok(), *strchr(), *strrchr(), *strstr(); +extern int strcoll(), strxfrm(), strncmp(), strlen(), strspn(), strcspn(); +extern char *memmove(), *memccpy(), *memchr(), *memcpy(), *memset(); +extern int memcmp(), strcmp(); +#endif + + +#ifdef __STDC__ +#include +#else +#ifndef NDEBUG +#define assert(ex) {\ + if (! (ex)) {\ + (void) fprintf(stderr,\ + "Assertion failed: file %s, line %d\n\"%s\"\n",\ + __FILE__, __LINE__, "ex");\ + (void) fflush(stdout);\ + abort();\ + }\ +} +#else +#define assert(ex) ; +#endif +#endif + + +#define fail(why) {\ + (void) fprintf(stderr, "Fatal error: file %s, line %d\n%s\n",\ + __FILE__, __LINE__, why);\ + (void) fflush(stdout);\ + abort();\ +} + + +#ifdef lint +#undef putc /* correct lint '_flsbuf' bug */ +#undef ALLOC /* allow for lint -h flag */ +#undef REALLOC +#define ALLOC(type, num) (((type *) 0) + (num)) +#define REALLOC(type, obj, num) ((obj) + (num)) +#endif + + +/* These arguably do NOT belong in util.h */ +#define ABS(a) ((a) < 0 ? -(a) : (a)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + + +#ifndef USE_MM +extern char *MMalloc (long); +extern void MMout_of_memory (long); +extern void (*MMoutOfMemory) (long); +extern char *MMrealloc (char *, long); +#endif + +extern long util_cpu_time (void); +extern char *util_path_search (char const *); +extern char *util_file_search (char const *, char *, char const *); +extern int util_pipefork (char * const *, FILE **, FILE **, int *); +extern void util_print_cpu_stats (FILE *); +extern char *util_print_time (unsigned long); +extern int util_save_image (char const *, char const *); +extern char *util_strsav (char const *); +extern char *util_tilde_expand (char const *); +extern void util_restart (char const *, char const *, int); + + +extern unsigned long getSoftDataLimit (void); + +#ifdef __cplusplus +} +#endif + +#endif /* UTIL_H */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/Makefile b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/Makefile new file mode 100644 index 000000000..3c593a2a3 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/Makefile @@ -0,0 +1,53 @@ +# $Id$ +# +# Makefile for the Mnemosyne memory allocation tracker. +# +# Marcus J. Ranum, 1990 +# +#Options: +# define MALLOC_IS_VOIDSTAR if your system's malloc is declared as a (void *) +# otherwise, it is assumed to be a (char *). a "mall_t" is typedeffed in +# mnemconf.h and mnemosyne.h to implement this. +OPTNS = -DMALLOC_IS_VOIDSTAR +#OPTNS = + +CC = cc +RANLIB = ranlib + +#compiler flags +CFLAGS = -g $(OPTNS) $(XCFLAGS) + +#loader flags +LDFLGS = + +HDRS = mnemosyne.h mnemconf.h + +all: mnemalyse libmnem.a + +mnemalyse: mnemalyse.o + $(CC) $(LDFLGS) -o $@ mnemalyse.o + +libmnem.a: mnemosyne.o + ar rcv $@ mnemosyne.o + $(RANLIB) $@ + +mtest: mtest.o libmnem.a + $(CC) $(LDFLGS) -o $@ mtest.o libmnem.a + +runmtest: all mtest + @echo "running memory waster" + mtest + @echo "press return for symbol list"; read ff + @cat mnem.syms + @echo "press return for waste analysis"; read ff + mnemalyse + +clean: + rm -f mtest core *.o mnem.dat mnem.syms + +distclean: clean + rm -f *.bak *~ libmnem.a mnemalyse + + +mnemosyne.o: Makefile mnemosyne.c $(HDRS) +mnemalyse.o: Makefile mnemalyse.c $(HDRS) diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/README b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/README new file mode 100644 index 000000000..182bbd29e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/README @@ -0,0 +1,39 @@ + + This is a set of tools designed to help find memory leaks in +programs, and to locate memory-hogging functions. It's implemented as +a wrapper library that goes around malloc/free/etc, and an include file +that "intercepts" calls to malloc/free/etc and makes them call the +wrappers. Thus, you can get extensive memory profiling and leak +detection by just adding one #include directive at the top of your +file and recompiling/linking. + + Unlike some similar tools I've seen in the past, this makes +sure that it keeps its on-disk data current, so that if the program +is crashed or interrupted, the results still have some validity. The +on-disk data is as compacted as I could make it, to give a chance of +this being useable in debugging big memory pigs. It adds some cost +in performance and memory size (since it keeps its own in-memory +symbol tables) but since it's only a debugging tool, I think the +cost is worth the benefit. This library can also be used to track +only allocations in a single module, or set of modules, and doesn't +interfere with calls to the "real" malloc() that are made in other +library routines. + + Every effort has been made to ensure that the code is +portable and won't interfere with running code - it should just +plug in or out. The biggest hindrances are forward declarations of +malloc() [which the preprocessor gleefully turns into syntax errors +for you] and structure elements named "free". The code has been +tested under Ultrix on DEC Risc and VAX systems, and under SunOS +on a Motorola platform. Please send patches, suggestions, etc, +to the author, who will probably not have time to do anything with +them. + +Compiling and building: + You may wish to edit the Makefile and glance at mnemconf.h, +then simply type "make". "make mtest" will build a simple test program +that will give you an idea of how things work. "make runmtest" will +run the test and do analysis on it. + +Marcus J. Ranum +mjr@decuac.dec.com diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mnemalyse.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mnemalyse.c new file mode 100644 index 000000000..60d2b914e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mnemalyse.c @@ -0,0 +1,197 @@ +/************************************************************************ + * * + * Copyright (c) 1985 by * + * Digital Equipment Corporation, Maynard, MA * + * All rights reserved. * + * * + * The information in this software is subject to change without * + * notice and should not be construed as a commitment by Digital * + * Equipment Corporation. * + * * + * Digital assumes no responsibility for the use or reliability * + * of its software on equipment which is not supplied by Digital. * + * * + * Redistribution and use in source and binary forms are permitted * + * provided that the above copyright notice and this paragraph are * + * duplicated in all such forms and that any documentation, * + * advertising materials, and other materials related to such * + * distribution and use acknowledge that the software was developed * + * by Digital Equipment Corporation. The name of Digital Equipment * + * Corporation may not be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.* + * Do not take internally. In case of accidental ingestion, contact * + * your physician immediately. * + * * + ************************************************************************/ + +/* DO NOT INCLUDE "mnemosyne.h" !!! */ +#include +#include +#include +#include + +static char rcsid[] = "/fats/tools/hsv/mnemosyne/mnemalyse.c,v 1.1.1.1 1995/06/06 18:18:28 fabio Exp"; + +#include "mnemconf.h" + +extern char *index(); + +/* +post-processor to interpret memory allocation maps and search for +pointers that were allocated but never freed. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + +/* +simple and braindead, read in the ".lines" file, and store it in a +table by number. then read the pointer map, and crossref any unfreed +pointers. simple as dereferencing NULL... + +this could use some cleaning and buffing, but it's damn effective as +it is. again, fancier symbol table routines would make this faster, +but who gives a damn? it only has to be faster than finding memory +leaks by hand... +*/ + +struct xsym { + char *dat; + int lnum; + int map; + struct xsym *nxt; +}; + + + +main() +{ + register struct xsym *sp; + register struct xsym *zp; + struct ptr p; + struct xsym *shash[HASHSIZ]; + char inbuf[BUFSIZ]; + FILE *lp; + int fd; + + /* statistics */ + int ptrcnt = 0; + int ptrbad = 0; + int ptrlos = 0; + + /* to chop up lines */ + char *cpmap; + char *cpcalls; + char *cpave; + char *cplnum; + char *cpfnam; + + for(fd = 0; fd < HASHSIZ; fd++) + shash[fd] = (struct xsym *)0; + + if((lp = fopen(LINESFILE,"r")) == (FILE *)0) { + perror(LINESFILE); + exit(1); + } + + if((fd = open(PTRFILE,O_RDONLY|O_RDWR)) < 0) { + perror(PTRFILE); + exit(1); + } + + /* this is ugly, but I refuse to trust !@(#&U!@#&! sscanf() */ + while((cpmap = fgets(inbuf,sizeof(inbuf),lp)) != (char *)0) { + if(inbuf[0] == '#') + continue; + + sp = (struct xsym *)malloc(sizeof(struct xsym)); + if(sp == (struct xsym *)0) { + perror("malloc"); + exit(1); + } + sp->lnum = sp->map = 0; + + if((cpcalls = index(cpmap,'\t')) != (char *)0) + *cpcalls++ = '\0'; + + if((cpave = index(cpcalls,'\t')) != (char *)0) + *cpave++ = '\0'; + + if((cplnum = index(cpave,'\t')) != (char *)0) + *cplnum++ = '\0'; + + if((cpfnam = index(cplnum,'\t')) != (char *)0) + *cpfnam++ = '\0'; + + /* setup symbol */ + sp->map = atoi(cpmap); + + if(cplnum == (char *)0) + sp->lnum = -1; + else + sp->lnum = atoi(cplnum); + + if(cpfnam != (char *)0) { + char *x; + if((x = index(cpfnam,'\n')) != (char *)0) + *x = '\0'; + + sp->dat = malloc((unsigned)(strlen(cpfnam) + 1)); + if(sp->dat == (char *)0) { + perror("malloc"); + exit(1); + } + (void)strcpy(sp->dat,cpfnam); + } else + sp->dat = "unknown"; + + /* check to make sure it is not already in table */ + zp = shash[sp->map % HASHSIZ]; + while(zp != (struct xsym *)0) { + if(zp->map == sp->map) { + (void)fprintf(stderr, + "mnemalyse: duplicate map entry ignored"); + (void)fprintf(stderr, + " (point at both %s and %s)\n",sp->dat,zp->dat); + (void)free(sp); + + /* can't free dat - may not be malloced! */ + sp = (struct xsym *)0; + break; + } + zp = zp->nxt; + } + + /* shrug, link it in */ + if(sp != (struct xsym *)0) { + sp->nxt = shash[sp->map % HASHSIZ]; + shash[sp->map % HASHSIZ] = sp; + } + } + (void)fclose(lp); + + while(read(fd,(char *)&(p.dsk),sizeof(p.dsk)) == sizeof(p.dsk)) { + + /* if the pointer was not deallocated, note it */ + if(p.dsk.siz != 0) { + zp = shash[p.dsk.smap % HASHSIZ]; + while(zp != (struct xsym *)0) { + if(zp->map == p.dsk.smap) { + printf("%d bytes missing %s line:%d\n", + p.dsk.siz,zp->dat,zp->lnum); + } + zp = zp->nxt; + } + ptrbad++; + ptrlos += p.dsk.siz; + } + ptrcnt++; + } + + printf("%d pointers, %d lost totalling %d bytes\n", + ptrcnt,ptrbad,ptrlos); + exit(0); +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mnemconf.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mnemconf.h new file mode 100644 index 000000000..5aa568d2f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mnemconf.h @@ -0,0 +1,89 @@ +/************************************************************************ + * * + * Copyright (c) 1985 by * + * Digital Equipment Corporation, Maynard, MA * + * All rights reserved. * + * * + * The information in this software is subject to change without * + * notice and should not be construed as a commitment by Digital * + * Equipment Corporation. * + * * + * Digital assumes no responsibility for the use or reliability * + * of its software on equipment which is not supplied by Digital. * + * * + * Redistribution and use in source and binary forms are permitted * + * provided that the above copyright notice and this paragraph are * + * duplicated in all such forms and that any documentation, * + * advertising materials, and other materials related to such * + * distribution and use acknowledge that the software was developed * + * by Digital Equipment Corporation. The name of Digital Equipment * + * Corporation may not be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.* + * Do not take internally. In case of accidental ingestion, contact * + * your physician immediately. * + * * + ************************************************************************/ + +#ifndef _INCL_MNEMCONF_H + +/* +/fats/tools/hsv/mnemosyne/mnemconf.h,v 1.1.1.1 1995/06/06 18:18:29 fabio Exp +*/ + +/* +site specific and shared internal data structures used by mnemosyne. +the only data structure that may need to be shared is the struct ptr, +which is defined herein. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + + +/* if your machine has malloc and all declared as a (void *) not a (char *) */ +#ifdef MALLOC_IS_VOIDSTAR +typedef void *mall_t; +#else +typedef char *mall_t; +#endif + + +/* size of internal hash tables - don't go wild - this is slow anyhow */ +#define HASHSIZ 2027 + + +/* names of files to write */ +#define LINESFILE "mnem.syms" +#define PTRFILE "mnem.dat" + +/* +extern mall_t malloc(); +extern mall_t realloc(); +extern mall_t calloc(); +extern void free(); +*/ + +/* +storage for a pointer map entry - the only data structure we share +a whole mess of these get written to mnem.dat as calls to malloc and +whatnot are made. the distinction between an *allocated* pointer and +and unallocated one is that 'siz' is 0 in freed ptrs. this is used +by the post-processor to look for memory leaks. +*/ +struct ptr { + mall_t ptr; /* pointer to allocated memory */ + int map; /* this pointer's map # */ + struct ptr *next; + + /* only part that gets written to the disk */ + struct { + unsigned siz; /* size allocated (or 0) */ + int smap; /* symbol map # */ + } dsk; +}; + +#define _INCL_MNEMCONF_H +#endif diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mnemosyne.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mnemosyne.c new file mode 100644 index 000000000..3b5985126 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mnemosyne.c @@ -0,0 +1,674 @@ +/************************************************************************ + * * + * Copyright (c) 1985 by * + * Digital Equipment Corporation, Maynard, MA * + * All rights reserved. * + * * + * The information in this software is subject to change without * + * notice and should not be construed as a commitment by Digital * + * Equipment Corporation. * + * * + * Digital assumes no responsibility for the use or reliability * + * of its software on equipment which is not supplied by Digital. * + * * + * Redistribution and use in source and binary forms are permitted * + * provided that the above copyright notice and this paragraph are * + * duplicated in all such forms and that any documentation, * + * advertising materials, and other materials related to such * + * distribution and use acknowledge that the software was developed * + * by Digital Equipment Corporation. The name of Digital Equipment * + * Corporation may not be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.* + * Do not take internally. In case of accidental ingestion, contact * + * your physician immediately. * + * * + ************************************************************************/ + +/* DO NOT INCLUDE "mnemosyne.h" !!! */ +#include +#include +//#include +#include +#include +#include +#include + +/* shared stuff - and decl of struct ptr */ +#include "mnemconf.h" + +static char rcsid[] = "/fats/tools/hsv/mnemosyne/mnemosyne.c,v 1.1.1.1 1995/06/06 18:18:28 fabio Exp"; + + +/* +malloc() realloc() and family wrappers - these functions manage a set +of data files that are updated whenever a pointer is allocated or freed, +as well as gathering stats about dynamic memory use and leakage. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + +/* +there is some egregious use of globals, void functions, and whatnot +in this code. it is mostly due to the constraint that nothing must +be visible to the outside, and that the code must be structurally +simple. error checking is pitched out the window in spots, since an +error in the mnemosyne code should not affect whatever is being +instrumented if at all possible. this means no errors, no signals, +nothing. (this message brought to you by my ego, in case you think +I don't know how to write better code than this) :) + +mjr, hacking on Christmas, 1990. +*/ + +#define REC_UNINIT 000 +#define REC_INITTED 001 +#define REC_ERR 002 +#define REC_ON 010 +#define REC_ONOFF 020 +static int rec_state = REC_UNINIT; + +/* +this method of storing the symbol maps is not the most efficient, but +then that's not important here, since all we're trying to do is find +memory leaks. if you choose to improve the symbol management to use +bucketed hash tables, please contact the author and the code will be +updated :) - besides, since we do file I/O every time you malloc or +free something, there's no way in hell this is going to set any new +records for speed. +*/ + + +/* storage for code/line # entry */ +struct sym { + char *labl; + int lineno; + int mapno; + int mallcnt; + float avsiz; + struct sym *next; +}; + + + +/* static symbol map */ +static struct { + FILE *fp; + FILE *log; + int fd; + + long nalloc; /* count of allocations */ + long nrlloc; /* count of re-allocations */ + long nfree; /* count of frees */ + long nbfree; /* count of bad frees */ + long ninuse; /* known allocated memory in use */ + float avgsiz; /* average malloc size */ + + /* one entry per pointer returned by malloc */ + int pmap; /* current next ptr map to alloc */ + struct ptr *phash[HASHSIZ]; + + /* one entry per line of code that calls malloc/realloc, etc */ + int lmap; /* current next line map to alloc */ + struct sym *shash[HASHSIZ]; /* hash access */ +} map; + + + + +/* print a locale record with checks for closed log file */ +static void +ploc(lab,lin,siz) +char *lab; +int lin; +int siz; +{ + if(map.log == (FILE *)0) + return; + if(lab != (char *)0) + (void)fprintf(map.log," \"%s\"",lab); + else + (void)fprintf(map.log," unknown"); + if(lin != -1) + (void)fprintf(map.log," line:%d",lin); + if(siz != -1) + (void)fprintf(map.log," size:%d",siz); +} + + + + +/* print a symbol map entry with checks for closed log file */ +static void +psym(s) +struct sym *s; +{ + if(map.log == (FILE *)0) + return; + (void)fprintf(map.log," \"%s\"",s->labl); + if(s->lineno != -1) + (void)fprintf(map.log," line:%d",s->lineno); +} + + + + +/* output a warning message with checks for closed log file */ +static void +pmsg(s) +char *s; +{ + if(map.log == (FILE *)0) + return; + (void)fprintf(map.log,"%s",s); +} + + + + +/* save an entry to the .lines file */ +static void +savesym(s) +struct sym *s; +{ + if(map.fp == (FILE *)0) + return; + + (void)fprintf(map.fp,"%d\t%d\t%.1f\t%d\t%s\n", + s->mapno,s->mallcnt,s->avsiz,s->lineno,s->labl); +} + + + + +/* save an entry in the pointer map file */ +static void +saveptr(p) +register struct ptr *p; +{ +/* if(lseek(map.fd,(off_t)(p->map * sizeof(p->dsk)),0) != + (off_t)(p->map * sizeof(p->dsk))) { + pmsg("mnemosyne: cannot seek in pointer map file\n"); + rec_state |= REC_ERR; + return; + } + + if(write(map.fd,(char *)&(p->dsk),sizeof(p->dsk)) != sizeof(p->dsk)) { + pmsg("mnemosyne: cannot write in pointer map file\n"); + rec_state |= REC_ERR; + return; + }*/ +} + + + + +/* initialize everything - symbol tables, files, and maps */ +static void +initmap() +{ + register int xp; + + if(rec_state & REC_INITTED) + return; + + if((map.fp = fopen(LINESFILE,"w")) == (FILE *)0) + return; + if((map.fd = open(PTRFILE,O_RDWR|O_CREAT|O_TRUNC,0600)) < 0) { + (void)fclose(map.fp); + return; + } + + map.log = stderr; + map.lmap = map.pmap = 0; + map.nalloc = map.nrlloc = map.nfree = map.nbfree = 0L; + map.ninuse = 0L; + map.avgsiz = 0.0; + + for(xp = 0; xp < HASHSIZ; xp++) { + map.phash[xp] = (struct ptr *)0; + map.shash[xp] = (struct sym *)0; + } + + rec_state = REC_INITTED | REC_ON; +} + + + + +/* set logging to a FILE * */ +void +mnem_setlog(fp) +FILE *fp; +{ + map.log = fp; +} + + + + +/* return state of the recorder */ +int +mnem_recording() +{ + return((rec_state & REC_ON) && !(rec_state & REC_ERR)); +} + + + + +/* turn on or off recording */ +int +mnem_setrecording(val) +int val; +{ + if(!(rec_state & REC_INITTED)) + initmap(); + + if(val) + rec_state |= REC_ON; + else + rec_state &= ~REC_ON; + + if(map.fp != (FILE *)0) + (void)fflush(map.fp); + + rec_state |= REC_ONOFF; + return(0); +} + + + + +/* lookup a pointer record - search pointer hash table */ +static struct ptr * +lookupptr(ptr) +mall_t ptr; +{ + register struct ptr *p; + + /* this probably give simply terrible hash performance */ + p = map.phash[(unsigned long)ptr % HASHSIZ]; + while(p != (struct ptr *)0) { + if(ptr == p->ptr) + return(p); + p = p->next; + } + return((struct ptr *)0); +} + + + + +/* + * polynomial conversion ignoring overflows + * [this seems to work remarkably well, in fact better + * then the ndbm hash function. Replace at your own risk] + * use: 65599 nice. + * 65587 even better. + * author: oz@nexus.yorku.ca + */ +static unsigned int +dbm_hash(str) +register char *str; +{ + register unsigned int n = 0; + + while(*str != '\0') + n = *str++ + 65599 * n; + return(n); +} + + + + +/* lookup a line/source entry by name (search hash table) */ +static struct sym * +lookupsymbyname(nam,lin) +char *nam; +int lin; +{ + register struct sym *s; + char *p = nam; + + if(p == (char *)0) + p = "unknown"; + + s = map.shash[(dbm_hash(p) + lin) % HASHSIZ]; + while(s != (struct sym *)0) { + if(!strcmp(s->labl,nam) && s->lineno == lin) + return(s); + s = s->next; + } + + return((struct sym *)0); +} + + + + +/* lookup a line/source entry by number (exhaustively search hash table) */ +static struct sym * +lookupsymbynum(num) +int num; +{ + register struct sym *s; + register int x; + + for(x = 0; x < HASHSIZ; x++) { + s = map.shash[x]; + while(s != (struct sym *)0) { + if(s->mapno == num) + return(s); + s = s->next; + } + } + return((struct sym *)0); +} + + + +/* stuff a pointer's value in the pointer map table */ +static void +storeptr(ptr,siz,lab,lin) +mall_t ptr; +int siz; +char *lab; +int lin; +{ + register struct ptr *p; + register struct sym *s; + int hv; + + /* + is there is no existing symbol entry for this line of code... + we must needs make one - and painful it is... + */ + if((s = lookupsymbyname(lab,lin)) == (struct sym *)0) { + s = (struct sym *)malloc(sizeof(struct sym)); + if(s == (struct sym *)0) { + pmsg("mnemosyne: cannot allocate sym entry\n"); + rec_state |= REC_ERR; + return; + } + + /* + this is funky - since we know the label is (?) + compiled-in, we can just keep a pointer to it, + rather than copying our own version of it. + */ + if(lab != (char *)0) + s->labl = lab; + else + s->labl = "unknown"; + + s->mapno = map.lmap++; + + /* add sym to hash table */ + s->next = map.shash[hv = ((dbm_hash(s->labl) + lin) % HASHSIZ)]; + map.shash[hv] = s; + + s->lineno = lin; + s->mallcnt = 1; + s->avsiz = siz; + savesym(s); + } else { + /* found an already defined symbol. store some averages */ + s->avsiz = ((s->avsiz * s->mallcnt) + siz) / (s->mallcnt + 1); + (s->mallcnt)++; + } + + p = lookupptr(ptr); + if(p != (struct ptr *)0 && p->dsk.siz != 0) { + struct sym *x; + + pmsg("pointer re-allocated without being freed"); + ploc(lab,lin,(int)siz); + if((x = lookupsymbynum(p->dsk.smap)) != (struct sym *)0) { + pmsg(" last allocated "); + psym(x); + } + pmsg("\n"); + } + + /* heavy sigh. no entry for this pointer. make one. */ + if(p == (struct ptr *)0) { + p = (struct ptr *)malloc(sizeof(struct ptr)); + if(p == (struct ptr *)0) { + pmsg("mnemosyne: cannot expand pointer table\n"); + rec_state |= REC_ERR; + return; + } + + /* link it in */ + p->next = map.phash[(unsigned long)ptr % HASHSIZ]; + map.phash[(unsigned long)ptr % HASHSIZ] = p; + } + + /* if we get to here (hazoo! hazaa!) both 's' and 'p' are OK */ + p->ptr = ptr; + p->dsk.siz = siz; + p->dsk.smap = s->mapno; + p->map = map.pmap++; + + /* store the size */ + map.ninuse += siz; + + saveptr(p); +} + + + + +/* +mark a pointer as now being free. note that a 1 is returned IF +the actual value should NOT be really passed to free() +*/ +static int +freeptr(ptr,lab,lin) +mall_t ptr; +char *lab; +int lin; +{ + register struct ptr *p; + + p = lookupptr(ptr); + if(p == (struct ptr *)0) { + pmsg("pointer freed that was never allocated"); + ploc(lab,lin,-1); + pmsg("\n"); + return(1); + } + + if(p != (struct ptr *)0 && p->dsk.siz == 0) { + struct sym *x; + + pmsg("pointer re-freed when already free"); + ploc(lab,lin,-1); + if((x = lookupsymbynum(p->dsk.smap)) != (struct sym *)0) { + pmsg(" last allocated:"); + psym(x); + } + pmsg("\n"); + return(1); + } + + /* get some free */ + map.ninuse -= p->dsk.siz; + + /* write in the map that it is free */ + p->dsk.siz = 0; + saveptr(p); + + return(0); +} + + + + +/* pretend we are malloc() */ +mall_t +mnem_malloc(siz,lab,lin) +unsigned siz; +char *lab; +int lin; +{ + mall_t ret; + + if(!(rec_state & REC_INITTED)) + initmap(); + + if((ret = malloc(siz)) == (mall_t)0) { + pmsg("malloc returned null pointer at"); + ploc(lab,lin,(int)siz); + pmsg("\n"); + return(ret); + } + + if((rec_state & REC_ON) && !(rec_state & REC_ERR)) + storeptr(ret,(int)siz,lab,lin); + + map.avgsiz = ((map.avgsiz * map.nalloc) + siz) / (map.nalloc + 1); + map.nalloc++; + return(ret); +} + + + + +/* pretend we are calloc() */ +mall_t +mnem_calloc(cnt,siz,lab,lin) +unsigned cnt; +unsigned siz; +char *lab; +int lin; +{ + mall_t ret; + + if(!(rec_state & REC_INITTED)) + initmap(); + + if((ret = calloc(cnt,siz)) == (mall_t)0) { + pmsg("calloc returned null pointer at"); + ploc(lab,lin,(int)(siz * cnt)); + pmsg("\n"); + return(ret); + } + + if((rec_state & REC_ON) && !(rec_state & REC_ERR)) + storeptr(ret,(int)(cnt * siz),lab,lin); + + map.avgsiz = ((map.avgsiz * map.nalloc) + siz) / (map.nalloc + 1); + map.nalloc++; + return(ret); +} + + + + +/* pretend we are realloc() */ +mall_t +mnem_realloc(ptr,siz,lab,lin) +mall_t ptr; +unsigned siz; +char *lab; +int lin; +{ + mall_t ret; + + if(!(rec_state & REC_INITTED)) + initmap(); + + if((ret = realloc(ptr,siz)) == (mall_t)0) { + pmsg("realloc returned null pointer at"); + ploc(lab,lin,(int)siz); + pmsg("\n"); + return(ret); + } + + if((rec_state & REC_ON) && !(rec_state & REC_ERR)) { + if(!freeptr(ptr,lab,lin)) + storeptr(ret,(int)siz,lab,lin); + } + + map.nrlloc++; + return(ret); +} + + + + + +/* pretend we are free() */ +void +mnem_free(ptr,lab,lin) +mall_t ptr; +char *lab; +int lin; +{ + if(!(rec_state & REC_INITTED)) + initmap(); + + if((rec_state & REC_ON) && !(rec_state & REC_ERR)) + if(freeptr(ptr,lab,lin) == 0) { + (void)free(ptr); + map.nfree++; + } else + map.nbfree++; +} + + + + +/* dump everything we know about nothing in particular */ +int +mnem_writestats() +{ + register struct sym *s; + register int x; + + if(map.fp == (FILE *)0) + return(-1); + + (void)fseek(map.fp,0L,0); + + /* dump our life's story */ + (void)fprintf(map.fp,"#total allocations:%ld\n",map.nalloc); + (void)fprintf(map.fp,"#total re-allocations:%ld\n",map.nrlloc); + (void)fprintf(map.fp,"#total frees:%ld\n",map.nfree); + + if(map.nbfree != 0L) + (void)fprintf(map.fp,"#bad/dup frees:%ld\n",map.nbfree); + + (void)fprintf(map.fp,"#total allocated never freed:%ld\n",map.ninuse); + + (void)fprintf(map.fp,"#average size of allocations:%.1f\n",map.avgsiz); + + /* note if we detected an internal error */ + if(rec_state & REC_ERR) + (void)fprintf(map.fp, + "#(figures likely inaccurate due to error)\n"); + + /* note if the system was on all the time ? */ + if(!(rec_state & REC_ON) || (rec_state & REC_ONOFF)) + (void)fprintf(map.fp, + "#(figures likely inaccurate as recording was off)\n"); + + /* write the legend */ + (void)fprintf(map.fp,"#map#\tcalls\tave\tline#\tfile\n"); + + for(x = 0; x < HASHSIZ; x++) { + s = map.shash[x]; + while(s != (struct sym *)0) { + savesym(s); + s = s->next; + } + } + + (void)fflush(map.fp); + return(0); +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mtest.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mtest.c new file mode 100644 index 000000000..5a51a0a04 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mnemosyne/mtest.c @@ -0,0 +1,38 @@ +#include "mnemosyne.h" + +static char rcsid[] = "/fats/tools/hsv/mnemosyne/mtest.c,v 1.1.1.1 1995/06/06 18:18:27 fabio Exp"; + +/* +test harness/demo of mnemosyne library. deliberately leaks memory on the +floor, double frees, frees unallocated memory, etc. + + Marcus J. Ranum, 1990. (mjr@decuac.dec.com) +*/ + + +main() +{ + char *d = "foobar"; + char *xx; + int x; + + xx = malloc(922); + xx = malloc(123); + + /* huh ? */ + xx = malloc(-9); + + /* waste some memory */ + for(x = 1; x < 8; x++) + xx = malloc(x); + + /* free something we don't own */ + free(d); + + /* double free something */ + free(xx); + free(xx); + + /* not necessary - this triggers a better printout of statistics */ + mnem_writestats(); +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/Makefile b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/Makefile new file mode 100644 index 000000000..b62b7c5da --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/Makefile @@ -0,0 +1,96 @@ +# $Id: Makefile,v 1.2 1994/10/03 23:30:34 fabio Exp fabio $ +# +# mtr - multiway-branching tree package +#--------------------------- +.SUFFIXES: .o .c .u + +CC = cc +RANLIB = ranlib +PURE = +# Define EXE as .exe for MS-DOS and derivatives. +EXE = +#EXE = .exe + +MFLAG = +ICFLAGS = -g +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) +MTRDEBUG = -DMTR_STATS -DMTR_VERBOSE -DMTR_DEBUG + +LINTFLAGS = -u -n -DMTR_STATS -DMTR_VERBOSE -DMTR_DEBUG + +# this is to create the lint library +LINTSWITCH = -o + +LDFLAGS = + +WHERE = .. + +INCLUDE = $(WHERE)/include + +P = mtr +PSRC = mtrBasic.c mtrGroup.c +PHDR = mtr.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +SRC = test$(P).c +HDR = +OBJ = $(SRC:.c=.o) +UBJ = $(SRC:.c=.u) +TARGET = test$(P)$(EXE) +TARGETu = test$(P)-u + +LIBS = ./libmtr.a $(WHERE)/util/libutil.a + +BLIBS = -kL. -klmtr -kL$(WHERE)/util -klutil + +MNEMLIB = + +LINTLIBS = llib-l$(P).ln + +#--------------------------- + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PSRC) $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) $(MTRDEBUG) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) +$(OBJ): $(PHDR) +$(UBJ): $(PHDR) + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +$(TARGET): $(POBJ) $(OBJ) $(LIBS) $(MNEMLIB) + $(PURE) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +$(TARGETu): $(SRC) $(PSRC) $(PHDR) $(UBJ) $(PUBJ) $(LIBS:.a=.b) + cc -O3 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \ + *.bak *~ tags *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/Makefile.sis b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/Makefile.sis new file mode 100644 index 000000000..d920cabf7 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/Makefile.sis @@ -0,0 +1,83 @@ +# $Id$ +# +# Cudd - DD package +#--------------------------- +.SUFFIXES: .o .c .u + +RANLIB = ranlib + +CAD = /projects/octtools/octtools/$(MACHINE) +SIS = .. +LINTCREATEFLAG = -C + +# files for the package +P = mtr +PSRC = mtrBasic.c mtrGroup.c +PHDR = mtr.h +POBJ = $(PSRC:.c=.o) + +# files for the test program +TARGET = test$(P) +SRC = test$(P).c +OBJ = $(SRC:.c=.o) +HDR = + +LIBS = ../util/libutil.a +LINTLIBS= ../util/llib-lutil.ln +INCLUDE = -I$(CAD)/include -I$(SIS)/include + +CFLAGS = -g $(INCLUDE) +LDFLAGS = -g +LINTFLAGS = $(INCLUDE) ${LINTEXTRAS} + +#------------------------------------------------------ + +$(TARGET): $(PHDR) $(OBJ) $(POBJ) $(LIBS) + $(CC) $(LDFLAGS) -o $(TARGET) $(OBJ) $(POBJ) $(LIBS) + +lint: $(PSRC) $(PHDR) $(SRC) $(HDR) + lint $(LINTFLAGS) $(SRC) $(PSRC) $(LINTLIBS) + +install: lib$(P).a llib-l$(P).ln + +lib$(P).a: $(POBJ) + ar cr $@ $? + $(RANLIB) $@ + +unpack: lib$(P).a + @for i in $(POBJ); do \ + ln -s $(SIS)/$(P)/$$i $(SIS)/unpack; \ + done + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) ${LINTCREATEFLAG}$(P) -n $(PSRC) + +clean: + rm -f $(TARGET) *.a *.ln *.o \ + [Tt]ags [Mm]ake.out lint malloc.out gmon.out __.SYMDEF + +tags: _force + @for i in $(PSRC) $(PHDR); do \ + cwd=`pwd`; ctags -a $$cwd/$$i; + done; + +strip_depend: + sed '/^#--DO NOT CHANGE ANYTHING AFTER THIS LINE/,$$d' Makefile >mktemp + mv mktemp Makefile + +depend: + sed '/^#--DO NOT CHANGE ANYTHING AFTER THIS LINE/,$$d' Makefile >mktemp + echo '#--DO NOT CHANGE ANYTHING AFTER THIS LINE' >>mktemp + $(CAD)/bin/cc-M $(CFLAGS) $(PSRC) | \ + sed 's|$(CAD)|$$(CAD)|g' | \ + grep -v '/usr/include' >>mktemp + mv mktemp Makefile + +#-------------------------- IBM 3090 support ----------------- +IBMHOST = opua +IBMDIST = /users2/sis +ibmdist: $(PSRC) $(PHDR) + rdist -Richw $(PSRC) $(PHDR) $(IBMHOST):$(IBMDIST) +#------------------------------------------------------------- +_force: + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtr.doc b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtr.doc new file mode 100644 index 000000000..2815d2948 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtr.doc @@ -0,0 +1,252 @@ +The mtr package + +Multiway-branch tree manipulation + +Fabio Somenzi + +********************************************************************** + +Mtr_AllocNode() Allocates new tree node. + +Mtr_CopyTree() Makes a copy of tree. + +Mtr_CreateFirstChild() Creates a new node and makes it the first child + of parent. + +Mtr_CreateLastChild() Creates a new node and makes it the last child + of parent. + +Mtr_DeallocNode() Deallocates tree node. + +Mtr_DissolveGroup() Merges the children of `group' with the + children of its parent. + +Mtr_FindGroup() Finds a group with size leaves starting at low, + if it exists. + +Mtr_FreeTree() Disposes of tree rooted at node. + +Mtr_InitGroupTree() Allocate new tree. + +Mtr_InitTree() Initializes tree with one node. + +Mtr_MakeFirstChild() Makes child the first child of parent. + +Mtr_MakeGroup() Makes a new group with size leaves starting at + low. + +Mtr_MakeLastChild() Makes child the last child of parent. + +Mtr_MakeNextSibling() Makes second the next sibling of first. + +Mtr_PrintGroups() Prints the groups as a parenthesized list. + +Mtr_PrintTree() Prints a tree, one node per line. + +Mtr_ReadGroups() Reads groups from a file and creates a group + tree. + +Mtr_SwapGroups() Swaps two children of a tree node. + +********************************************************************** + +This package provides two layers of functions. Functions of the lower level +manipulate multiway-branch trees, implemented according to the classical +scheme whereby each node points to its first child and its previous and +next siblings. These functions are collected in mtrBasic.c. Functions +of the upper layer deal with group trees, that is the trees used by group +sifting to represent the grouping of variables. These functions are +collected in mtrGroup.c. + +MtrNode * +Mtr_AllocNode( + +) + Allocates new tree node. Returns pointer to node. + + Side Effects: None + +MtrNode * +Mtr_CopyTree( + MtrNode * node, + int expansion +) + Makes a copy of tree. If parameter expansion is greater than 1, it will + expand the tree by that factor. It is an error for expansion to be less than + 1. Returns a pointer to the copy if successful; NULL otherwise. + + Side Effects: None + +MtrNode * +Mtr_CreateFirstChild( + MtrNode * parent +) + Creates a new node and makes it the first child of parent. Returns pointer + to new child. + + Side Effects: None + +MtrNode * +Mtr_CreateLastChild( + MtrNode * parent +) + Creates a new node and makes it the last child of parent. Returns pointer to + new child. + + Side Effects: None + +void +Mtr_DeallocNode( + MtrNode * node node to be deallocated +) + Deallocates tree node. + + Side Effects: None + +MtrNode * +Mtr_DissolveGroup( + MtrNode * group group to be dissolved +) + Merges the children of `group' with the children of its parent. Disposes of + the node pointed by group. If group is the root of the group tree, this + procedure leaves the tree unchanged. Returns the pointer to the parent of + `group' upon successful termination; NULL otherwise. + + Side Effects: None + +MtrNode * +Mtr_FindGroup( + MtrNode * root, root of the group tree + unsigned int low, lower bound of the group + unsigned int size upper bound of the group +) + Finds a group with size leaves starting at low, if it exists. This procedure + relies on the low and size fields of each node. It also assumes that the + children of each node are sorted in order of increasing low. Returns the + pointer to the root of the group upon successful termination; NULL + otherwise. + + Side Effects: None + +void +Mtr_FreeTree( + MtrNode * node +) + Disposes of tree rooted at node. + + Side Effects: None + +MtrNode * +Mtr_InitGroupTree( + int lower, + int size +) + Allocate new tree with one node, whose low and size fields are specified by + the lower and size parameters. Returns pointer to tree root. + + Side Effects: None + +MtrNode * +Mtr_InitTree( + +) + Initializes tree with one node. Returns pointer to node. + + Side Effects: None + +void +Mtr_MakeFirstChild( + MtrNode * parent, + MtrNode * child +) + Makes child the first child of parent. + + Side Effects: None + +MtrNode * +Mtr_MakeGroup( + MtrNode * root, root of the group tree + unsigned int low, lower bound of the group + unsigned int size, upper bound of the group + unsigned int flags flags for the new group +) + Makes a new group with size leaves starting at low. If the new group + intersects an existing group, it must either contain it or be contained by + it. This procedure relies on the low and size fields of each node. It also + assumes that the children of each node are sorted in order of increasing + low. In case of a valid request, the flags of the new group are set to the + value passed in `flags.' This can also be used to change the flags of an + existing group. Returns the pointer to the root of the new group upon + successful termination; NULL otherwise. If the group already exists, the + pointer to its root is returned. + + Side Effects: None + +void +Mtr_MakeLastChild( + MtrNode * parent, + MtrNode * child +) + Makes child the last child of parent. + + Side Effects: None + +void +Mtr_MakeNextSibling( + MtrNode * first, + MtrNode * second +) + Makes second the next sibling of first. Second becomes a child of the parent + of first. + + Side Effects: None + +void +Mtr_PrintGroups( + MtrNode * root, root of the group tree + int silent flag to check tree syntax only +) + Prints the groups as a parenthesized list. After each group, the group's + flag are printed, preceded by a `|'. For each flag (except MTR_TERMINAL) a + character is printed. F: MTR_FIXED N: MTR_NEWNODE S: + MTR_SOFT The second argument, silent, if different from 0, causes + Mtr_PrintGroups to only check the syntax of the group tree. + + Side Effects: None + +void +Mtr_PrintTree( + MtrNode * node +) + Prints a tree, one node per line. + + Side Effects: None + +MtrNode * +Mtr_ReadGroups( + FILE * fp, file pointer + int nleaves number of leaves of the new tree +) + Reads groups from a file and creates a group tree. Each group is specified + by three fields: low size flags. Low and size are (short) + integers. Flags is a string composed of the following characters (with + associated translation): D: MTR_DEFAULT F: MTR_FIXED N: + MTR_NEWNODE S: MTR_SOFT T: MTR_TERMINAL Normally, the only + flags that are needed are D and F. Groups and fields are separated by white + space (spaces, tabs, and newlines). Returns a pointer to the group tree if + successful; NULL otherwise. + + Side Effects: None + +int +Mtr_SwapGroups( + MtrNode * first, first node to be swapped + MtrNode * second second node to be swapped +) + Swaps two children of a tree node. Adjusts the high and low fields of the + two nodes and their descendants. The two children must be adjacent. However, + first may be the younger sibling of second. Returns 1 in case of success; 0 + otherwise. + + Side Effects: None + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrAllAbs.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrAllAbs.html new file mode 100644 index 000000000..9a59faada --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrAllAbs.html @@ -0,0 +1,72 @@ + +mtr package abstract (Internal) + + +

                          mtr package abstract (Internal)

                          +

                          Internal data structures of the mtr package

                          +
                          + + + +
                          +
                          Mtr_AllocNode() +
                          Allocates new tree node. + +
                          Mtr_CopyTree() +
                          Makes a copy of tree. + +
                          Mtr_CreateFirstChild() +
                          Creates a new node and makes it the first child of parent. + +
                          Mtr_CreateLastChild() +
                          Creates a new node and makes it the last child of parent. + +
                          Mtr_DeallocNode() +
                          Deallocates tree node. + +
                          Mtr_DissolveGroup() +
                          Merges the children of `group' with the children of its parent. + +
                          Mtr_FindGroup() +
                          Finds a group with size leaves starting at low, if it exists. + +
                          Mtr_FreeTree() +
                          Disposes of tree rooted at node. + +
                          Mtr_InitGroupTree() +
                          Allocate new tree. + +
                          Mtr_InitTree() +
                          Initializes tree with one node. + +
                          Mtr_MakeFirstChild() +
                          Makes child the first child of parent. + +
                          Mtr_MakeGroup() +
                          Makes a new group with size leaves starting at low. + +
                          Mtr_MakeLastChild() +
                          Makes child the last child of parent. + +
                          Mtr_MakeNextSibling() +
                          Makes second the next sibling of first. + +
                          Mtr_PrintGroups() +
                          Prints the groups as a parenthesized list. + +
                          Mtr_PrintTree() +
                          Prints a tree, one node per line. + +
                          Mtr_ReadGroups() +
                          Reads groups from a file and creates a group tree. + +
                          Mtr_SwapGroups() +
                          Swaps two children of a tree node. + +
                          + +
                          + +Generated automatically by extdoc on 970123 + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrAllDet.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrAllDet.html new file mode 100644 index 000000000..e7b789074 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrAllDet.html @@ -0,0 +1,317 @@ + +The mtr package (Internal) + + +

                          The mtr package (Internal)

                          +

                          Internal data structures of the mtr package

                          +

                          +
                          + + +
                          + + +In this package all definitions are external. + + +
                          + + +
                          + +
                          +MtrNode * 
                          +Mtr_AllocNode(
                          +    
                          +)
                          +
                          +
                          Allocates new tree node. Returns pointer to node. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_DeallocNode + + +
                          +MtrNode * 
                          +Mtr_CopyTree(
                          +  MtrNode * node, 
                          +  int  expansion 
                          +)
                          +
                          +
                          Makes a copy of tree. If parameter expansion is greater than 1, it will expand the tree by that factor. It is an error for expansion to be less than 1. Returns a pointer to the copy if successful; NULL otherwise. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_InitTree + + +
                          +MtrNode * 
                          +Mtr_CreateFirstChild(
                          +  MtrNode * parent 
                          +)
                          +
                          +
                          Creates a new node and makes it the first child of parent. Returns pointer to new child. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_MakeFirstChild +Mtr_CreateLastChild + + +
                          +MtrNode * 
                          +Mtr_CreateLastChild(
                          +  MtrNode * parent 
                          +)
                          +
                          +
                          Creates a new node and makes it the last child of parent. Returns pointer to new child. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_MakeLastChild +Mtr_CreateFirstChild + + +
                          +void 
                          +Mtr_DeallocNode(
                          +  MtrNode * node node to be deallocated
                          +)
                          +
                          +
                          Deallocates tree node. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_AllocNode + + +
                          +MtrNode * 
                          +Mtr_DissolveGroup(
                          +  MtrNode * group group to be dissolved
                          +)
                          +
                          +
                          Merges the children of `group' with the children of its parent. Disposes of the node pointed by group. If group is the root of the group tree, this procedure leaves the tree unchanged. Returns the pointer to the parent of `group' upon successful termination; NULL otherwise. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_MakeGroup + + +
                          +MtrNode * 
                          +Mtr_FindGroup(
                          +  MtrNode * root, root of the group tree
                          +  unsigned int  low, lower bound of the group
                          +  unsigned int  size upper bound of the group
                          +)
                          +
                          +
                          Finds a group with size leaves starting at low, if it exists. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. Returns the pointer to the root of the group upon successful termination; NULL otherwise. +

                          + +

                          Side Effects None +

                          + +

                          +void 
                          +Mtr_FreeTree(
                          +  MtrNode * node 
                          +)
                          +
                          +
                          Disposes of tree rooted at node. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_InitTree + + +
                          +MtrNode * 
                          +Mtr_InitGroupTree(
                          +  int  lower, 
                          +  int  size 
                          +)
                          +
                          +
                          Allocate new tree with one node, whose low and size fields are specified by the lower and size parameters. Returns pointer to tree root. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_InitTree +Mtr_FreeTree + + +
                          +MtrNode * 
                          +Mtr_InitTree(
                          +    
                          +)
                          +
                          +
                          Initializes tree with one node. Returns pointer to node. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_FreeTree +Mtr_InitGroupTree + + +
                          +void 
                          +Mtr_MakeFirstChild(
                          +  MtrNode * parent, 
                          +  MtrNode * child 
                          +)
                          +
                          +
                          Makes child the first child of parent. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_MakeLastChild +Mtr_CreateFirstChild + + +
                          +MtrNode * 
                          +Mtr_MakeGroup(
                          +  MtrNode * root, root of the group tree
                          +  unsigned int  low, lower bound of the group
                          +  unsigned int  size, upper bound of the group
                          +  unsigned int  flags flags for the new group
                          +)
                          +
                          +
                          Makes a new group with size leaves starting at low. If the new group intersects an existing group, it must either contain it or be contained by it. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. In case of a valid request, the flags of the new group are set to the value passed in `flags.' This can also be used to change the flags of an existing group. Returns the pointer to the root of the new group upon successful termination; NULL otherwise. If the group already exists, the pointer to its root is returned. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_DissolveGroup +Mtr_ReadGroups +Mtr_FindGroup + + +
                          +void 
                          +Mtr_MakeLastChild(
                          +  MtrNode * parent, 
                          +  MtrNode * child 
                          +)
                          +
                          +
                          Makes child the last child of parent. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_MakeFirstChild +Mtr_CreateLastChild + + +
                          +void 
                          +Mtr_MakeNextSibling(
                          +  MtrNode * first, 
                          +  MtrNode * second 
                          +)
                          +
                          +
                          Makes second the next sibling of first. Second becomes a child of the parent of first. +

                          + +

                          Side Effects None +

                          + +

                          +void 
                          +Mtr_PrintGroups(
                          +  MtrNode * root, root of the group tree
                          +  int  silent flag to check tree syntax only
                          +)
                          +
                          +
                          Prints the groups as a parenthesized list. After each group, the group's flag are printed, preceded by a `|'. For each flag (except MTR_TERMINAL) a character is printed.
                          • F: MTR_FIXED
                          • N: MTR_NEWNODE
                          • S: MTR_SOFT
                          The second argument, silent, if different from 0, causes Mtr_PrintGroups to only check the syntax of the group tree. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_PrintTree + + +
                          +void 
                          +Mtr_PrintTree(
                          +  MtrNode * node 
                          +)
                          +
                          +
                          Prints a tree, one node per line. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_PrintGroups + + +
                          +MtrNode * 
                          +Mtr_ReadGroups(
                          +  FILE * fp, file pointer
                          +  int  nleaves number of leaves of the new tree
                          +)
                          +
                          +
                          Reads groups from a file and creates a group tree. Each group is specified by three fields: low size flags. Low and size are (short) integers. Flags is a string composed of the following characters (with associated translation):
                          • D: MTR_DEFAULT
                          • F: MTR_FIXED
                          • N: MTR_NEWNODE
                          • S: MTR_SOFT
                          • T: MTR_TERMINAL
                          Normally, the only flags that are needed are D and F. Groups and fields are separated by white space (spaces, tabs, and newlines). Returns a pointer to the group tree if successful; NULL otherwise. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_InitGroupTree +Mtr_MakeGroup + + +
                          +int 
                          +Mtr_SwapGroups(
                          +  MtrNode * first, first node to be swapped
                          +  MtrNode * second second node to be swapped
                          +)
                          +
                          +
                          Swaps two children of a tree node. Adjusts the high and low fields of the two nodes and their descendants. The two children must be adjacent. However, first may be the younger sibling of second. Returns 1 in case of success; 0 otherwise. +

                          + +

                          Side Effects None +

                          + + +

                          + +
                          + +Generated automatically by extdoc on 970123 + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrExtAbs.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrExtAbs.html new file mode 100644 index 000000000..9f48acbad --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrExtAbs.html @@ -0,0 +1,72 @@ + +mtr package abstract + + +

                          mtr package abstract

                          +

                          Multiway-branch tree manipulation

                          +
                          + + + +
                          +
                          Mtr_AllocNode() +
                          Allocates new tree node. + +
                          Mtr_CopyTree() +
                          Makes a copy of tree. + +
                          Mtr_CreateFirstChild() +
                          Creates a new node and makes it the first child of parent. + +
                          Mtr_CreateLastChild() +
                          Creates a new node and makes it the last child of parent. + +
                          Mtr_DeallocNode() +
                          Deallocates tree node. + +
                          Mtr_DissolveGroup() +
                          Merges the children of `group' with the children of its parent. + +
                          Mtr_FindGroup() +
                          Finds a group with size leaves starting at low, if it exists. + +
                          Mtr_FreeTree() +
                          Disposes of tree rooted at node. + +
                          Mtr_InitGroupTree() +
                          Allocate new tree. + +
                          Mtr_InitTree() +
                          Initializes tree with one node. + +
                          Mtr_MakeFirstChild() +
                          Makes child the first child of parent. + +
                          Mtr_MakeGroup() +
                          Makes a new group with size leaves starting at low. + +
                          Mtr_MakeLastChild() +
                          Makes child the last child of parent. + +
                          Mtr_MakeNextSibling() +
                          Makes second the next sibling of first. + +
                          Mtr_PrintGroups() +
                          Prints the groups as a parenthesized list. + +
                          Mtr_PrintTree() +
                          Prints a tree, one node per line. + +
                          Mtr_ReadGroups() +
                          Reads groups from a file and creates a group tree. + +
                          Mtr_SwapGroups() +
                          Swaps two children of a tree node. + +
                          + +
                          + +Generated automatically by extdoc on 970123 + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrExtDet.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrExtDet.html new file mode 100644 index 000000000..8300c3d6a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/doc/mtrExtDet.html @@ -0,0 +1,324 @@ + +The mtr package + + +

                          The mtr package

                          +

                          Multiway-branch tree manipulation

                          +

                          +
                          + + +
                          + + +This package provides two layers of functions. Functions + of the lower level manipulate multiway-branch trees, implemented + according to the classical scheme whereby each node points to its + first child and its previous and next siblings. These functions are + collected in mtrBasic.c.

                          + Functions of the upper layer deal with group trees, that is the trees + used by group sifting to represent the grouping of variables. These + functions are collected in mtrGroup.c. + + +


                          + + +
                          + +
                          +MtrNode * 
                          +Mtr_AllocNode(
                          +    
                          +)
                          +
                          +
                          Allocates new tree node. Returns pointer to node. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_DeallocNode + + +
                          +MtrNode * 
                          +Mtr_CopyTree(
                          +  MtrNode * node, 
                          +  int  expansion 
                          +)
                          +
                          +
                          Makes a copy of tree. If parameter expansion is greater than 1, it will expand the tree by that factor. It is an error for expansion to be less than 1. Returns a pointer to the copy if successful; NULL otherwise. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_InitTree + + +
                          +MtrNode * 
                          +Mtr_CreateFirstChild(
                          +  MtrNode * parent 
                          +)
                          +
                          +
                          Creates a new node and makes it the first child of parent. Returns pointer to new child. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_MakeFirstChild +Mtr_CreateLastChild + + +
                          +MtrNode * 
                          +Mtr_CreateLastChild(
                          +  MtrNode * parent 
                          +)
                          +
                          +
                          Creates a new node and makes it the last child of parent. Returns pointer to new child. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_MakeLastChild +Mtr_CreateFirstChild + + +
                          +void 
                          +Mtr_DeallocNode(
                          +  MtrNode * node node to be deallocated
                          +)
                          +
                          +
                          Deallocates tree node. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_AllocNode + + +
                          +MtrNode * 
                          +Mtr_DissolveGroup(
                          +  MtrNode * group group to be dissolved
                          +)
                          +
                          +
                          Merges the children of `group' with the children of its parent. Disposes of the node pointed by group. If group is the root of the group tree, this procedure leaves the tree unchanged. Returns the pointer to the parent of `group' upon successful termination; NULL otherwise. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_MakeGroup + + +
                          +MtrNode * 
                          +Mtr_FindGroup(
                          +  MtrNode * root, root of the group tree
                          +  unsigned int  low, lower bound of the group
                          +  unsigned int  size upper bound of the group
                          +)
                          +
                          +
                          Finds a group with size leaves starting at low, if it exists. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. Returns the pointer to the root of the group upon successful termination; NULL otherwise. +

                          + +

                          Side Effects None +

                          + +

                          +void 
                          +Mtr_FreeTree(
                          +  MtrNode * node 
                          +)
                          +
                          +
                          Disposes of tree rooted at node. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_InitTree + + +
                          +MtrNode * 
                          +Mtr_InitGroupTree(
                          +  int  lower, 
                          +  int  size 
                          +)
                          +
                          +
                          Allocate new tree with one node, whose low and size fields are specified by the lower and size parameters. Returns pointer to tree root. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_InitTree +Mtr_FreeTree + + +
                          +MtrNode * 
                          +Mtr_InitTree(
                          +    
                          +)
                          +
                          +
                          Initializes tree with one node. Returns pointer to node. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_FreeTree +Mtr_InitGroupTree + + +
                          +void 
                          +Mtr_MakeFirstChild(
                          +  MtrNode * parent, 
                          +  MtrNode * child 
                          +)
                          +
                          +
                          Makes child the first child of parent. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_MakeLastChild +Mtr_CreateFirstChild + + +
                          +MtrNode * 
                          +Mtr_MakeGroup(
                          +  MtrNode * root, root of the group tree
                          +  unsigned int  low, lower bound of the group
                          +  unsigned int  size, upper bound of the group
                          +  unsigned int  flags flags for the new group
                          +)
                          +
                          +
                          Makes a new group with size leaves starting at low. If the new group intersects an existing group, it must either contain it or be contained by it. This procedure relies on the low and size fields of each node. It also assumes that the children of each node are sorted in order of increasing low. In case of a valid request, the flags of the new group are set to the value passed in `flags.' This can also be used to change the flags of an existing group. Returns the pointer to the root of the new group upon successful termination; NULL otherwise. If the group already exists, the pointer to its root is returned. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_DissolveGroup +Mtr_ReadGroups +Mtr_FindGroup + + +
                          +void 
                          +Mtr_MakeLastChild(
                          +  MtrNode * parent, 
                          +  MtrNode * child 
                          +)
                          +
                          +
                          Makes child the last child of parent. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_MakeFirstChild +Mtr_CreateLastChild + + +
                          +void 
                          +Mtr_MakeNextSibling(
                          +  MtrNode * first, 
                          +  MtrNode * second 
                          +)
                          +
                          +
                          Makes second the next sibling of first. Second becomes a child of the parent of first. +

                          + +

                          Side Effects None +

                          + +

                          +void 
                          +Mtr_PrintGroups(
                          +  MtrNode * root, root of the group tree
                          +  int  silent flag to check tree syntax only
                          +)
                          +
                          +
                          Prints the groups as a parenthesized list. After each group, the group's flag are printed, preceded by a `|'. For each flag (except MTR_TERMINAL) a character is printed.
                          • F: MTR_FIXED
                          • N: MTR_NEWNODE
                          • S: MTR_SOFT
                          The second argument, silent, if different from 0, causes Mtr_PrintGroups to only check the syntax of the group tree. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_PrintTree + + +
                          +void 
                          +Mtr_PrintTree(
                          +  MtrNode * node 
                          +)
                          +
                          +
                          Prints a tree, one node per line. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_PrintGroups + + +
                          +MtrNode * 
                          +Mtr_ReadGroups(
                          +  FILE * fp, file pointer
                          +  int  nleaves number of leaves of the new tree
                          +)
                          +
                          +
                          Reads groups from a file and creates a group tree. Each group is specified by three fields: low size flags. Low and size are (short) integers. Flags is a string composed of the following characters (with associated translation):
                          • D: MTR_DEFAULT
                          • F: MTR_FIXED
                          • N: MTR_NEWNODE
                          • S: MTR_SOFT
                          • T: MTR_TERMINAL
                          Normally, the only flags that are needed are D and F. Groups and fields are separated by white space (spaces, tabs, and newlines). Returns a pointer to the group tree if successful; NULL otherwise. +

                          + +

                          Side Effects None +

                          + +

                          See Also Mtr_InitGroupTree +Mtr_MakeGroup + + +
                          +int 
                          +Mtr_SwapGroups(
                          +  MtrNode * first, first node to be swapped
                          +  MtrNode * second second node to be swapped
                          +)
                          +
                          +
                          Swaps two children of a tree node. Adjusts the high and low fields of the two nodes and their descendants. The two children must be adjacent. However, first may be the younger sibling of second. Returns 1 in case of success; 0 otherwise. +

                          + +

                          Side Effects None +

                          + + +

                          + +
                          + +Generated automatically by extdoc on 970123 + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/mtrBasic.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/mtrBasic.c new file mode 100644 index 000000000..f91c63430 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/mtrBasic.c @@ -0,0 +1,450 @@ +/**CFile*********************************************************************** + + FileName [mtrBasic.c] + + PackageName [mtr] + + Synopsis [Basic manipulation of multiway branching trees.] + + Description [External procedures included in this module: +
                            +
                          • Mtr_AllocNode() +
                          • Mtr_DeallocNode() +
                          • Mtr_InitTree() +
                          • Mtr_FreeTree() +
                          • Mtr_CopyTree() +
                          • Mtr_MakeFirstChild() +
                          • Mtr_MakeLastChild() +
                          • Mtr_CreateFirstChild() +
                          • Mtr_CreateLastChild() +
                          • Mtr_MakeNextSibling() +
                          • Mtr_PrintTree() +
                          + ] + + SeeAlso [cudd package] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "mtrInt.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] MTR_UNUSED = "$Id: mtrBasic.c,v 1.15 2012/02/05 01:06:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Allocates new tree node.] + + Description [Allocates new tree node. Returns pointer to node.] + + SideEffects [None] + + SeeAlso [Mtr_DeallocNode] + +******************************************************************************/ +MtrNode * +Mtr_AllocNode(void) +{ + MtrNode *node; + + node = ALLOC(MtrNode,1); + return node; + +} /* Mtr_AllocNode */ + + +/**Function******************************************************************** + + Synopsis [Deallocates tree node.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_AllocNode] + +******************************************************************************/ +void +Mtr_DeallocNode( + MtrNode * node /* node to be deallocated */) +{ + FREE(node); + return; + +} /* end of Mtr_DeallocNode */ + + +/**Function******************************************************************** + + Synopsis [Initializes tree with one node.] + + Description [Initializes tree with one node. Returns pointer to node.] + + SideEffects [None] + + SeeAlso [Mtr_FreeTree Mtr_InitGroupTree] + +******************************************************************************/ +MtrNode * +Mtr_InitTree(void) +{ + MtrNode *node; + + node = Mtr_AllocNode(); + if (node == NULL) return(NULL); + + node->parent = node->child = node->elder = node->younger = NULL; + node->flags = 0; + + return(node); + +} /* end of Mtr_InitTree */ + + +/**Function******************************************************************** + + Synopsis [Disposes of tree rooted at node.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_InitTree] + +******************************************************************************/ +void +Mtr_FreeTree( + MtrNode * node) +{ + if (node == NULL) return; + if (! MTR_TEST(node,MTR_TERMINAL)) Mtr_FreeTree(node->child); + Mtr_FreeTree(node->younger); + Mtr_DeallocNode(node); + return; + +} /* end of Mtr_FreeTree */ + + +/**Function******************************************************************** + + Synopsis [Makes a copy of tree.] + + Description [Makes a copy of tree. If parameter expansion is greater + than 1, it will expand the tree by that factor. It is an error for + expansion to be less than 1. Returns a pointer to the copy if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Mtr_InitTree] + +******************************************************************************/ +MtrNode * +Mtr_CopyTree( + MtrNode * node, + int expansion) +{ + MtrNode *copy; + + if (node == NULL) return(NULL); + if (expansion < 1) return(NULL); + copy = Mtr_AllocNode(); + if (copy == NULL) return(NULL); + copy->parent = copy->elder = copy->child = copy->younger = NULL; + if (node->child != NULL) { + copy->child = Mtr_CopyTree(node->child, expansion); + if (copy->child == NULL) { + Mtr_DeallocNode(copy); + return(NULL); + } + } + if (node->younger != NULL) { + copy->younger = Mtr_CopyTree(node->younger, expansion); + if (copy->younger == NULL) { + Mtr_FreeTree(copy); + return(NULL); + } + } + copy->flags = node->flags; + copy->low = node->low * expansion; + copy->size = node->size * expansion; + copy->index = node->index * expansion; + if (copy->younger) copy->younger->elder = copy; + if (copy->child) { + MtrNode *auxnode = copy->child; + while (auxnode != NULL) { + auxnode->parent = copy; + auxnode = auxnode->younger; + } + } + return(copy); + +} /* end of Mtr_CopyTree */ + + +/**Function******************************************************************** + + Synopsis [Makes child the first child of parent.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_MakeLastChild Mtr_CreateFirstChild] + +******************************************************************************/ +void +Mtr_MakeFirstChild( + MtrNode * parent, + MtrNode * child) +{ + child->parent = parent; + child->younger = parent->child; + child->elder = NULL; + if (parent->child != NULL) { +#ifdef MTR_DEBUG + assert(parent->child->elder == NULL); +#endif + parent->child->elder = child; + } + parent->child = child; + return; + +} /* end of Mtr_MakeFirstChild */ + + +/**Function******************************************************************** + + Synopsis [Makes child the last child of parent.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_MakeFirstChild Mtr_CreateLastChild] + +******************************************************************************/ +void +Mtr_MakeLastChild( + MtrNode * parent, + MtrNode * child) +{ + MtrNode *node; + + child->younger = NULL; + + if (parent->child == NULL) { + parent->child = child; + child->elder = NULL; + } else { + for (node = parent->child; + node->younger != NULL; + node = node->younger); + node->younger = child; + child->elder = node; + } + child->parent = parent; + return; + +} /* end of Mtr_MakeLastChild */ + + +/**Function******************************************************************** + + Synopsis [Creates a new node and makes it the first child of parent.] + + Description [Creates a new node and makes it the first child of + parent. Returns pointer to new child.] + + SideEffects [None] + + SeeAlso [Mtr_MakeFirstChild Mtr_CreateLastChild] + +******************************************************************************/ +MtrNode * +Mtr_CreateFirstChild( + MtrNode * parent) +{ + MtrNode *child; + + child = Mtr_AllocNode(); + if (child == NULL) return(NULL); + + child->child = NULL; + child->flags = 0; + Mtr_MakeFirstChild(parent,child); + return(child); + +} /* end of Mtr_CreateFirstChild */ + + +/**Function******************************************************************** + + Synopsis [Creates a new node and makes it the last child of parent.] + + Description [Creates a new node and makes it the last child of parent. + Returns pointer to new child.] + + SideEffects [None] + + SeeAlso [Mtr_MakeLastChild Mtr_CreateFirstChild] + +******************************************************************************/ +MtrNode * +Mtr_CreateLastChild( + MtrNode * parent) +{ + MtrNode *child; + + child = Mtr_AllocNode(); + if (child == NULL) return(NULL); + + child->child = NULL; + child->flags = 0; + Mtr_MakeLastChild(parent,child); + return(child); + +} /* end of Mtr_CreateLastChild */ + + +/**Function******************************************************************** + + Synopsis [Makes second the next sibling of first.] + + Description [Makes second the next sibling of first. Second becomes a + child of the parent of first.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Mtr_MakeNextSibling( + MtrNode * first, + MtrNode * second) +{ + second->parent = first->parent; + second->elder = first; + second->younger = first->younger; + if (first->younger != NULL) { + first->younger->elder = second; + } + first->younger = second; + return; + +} /* end of Mtr_MakeNextSibling */ + + +/**Function******************************************************************** + + Synopsis [Prints a tree, one node per line.] + + Description [] + + SideEffects [None] + + SeeAlso [Mtr_PrintGroups] + +******************************************************************************/ +void +Mtr_PrintTree( + MtrNode * node) +{ + if (node == NULL) return; + (void) fprintf(stdout, +#if SIZEOF_VOID_P == 8 + "N=0x%-8lx C=0x%-8lx Y=0x%-8lx E=0x%-8lx P=0x%-8lx F=%x L=%u S=%u\n", + (unsigned long) node, (unsigned long) node->child, + (unsigned long) node->younger, (unsigned long) node->elder, + (unsigned long) node->parent, node->flags, node->low, node->size); +#else + "N=0x%-8x C=0x%-8x Y=0x%-8x E=0x%-8x P=0x%-8x F=%x L=%hu S=%hu\n", + (unsigned) node, (unsigned) node->child, + (unsigned) node->younger, (unsigned) node->elder, + (unsigned) node->parent, node->flags, node->low, node->size); +#endif + if (!MTR_TEST(node,MTR_TERMINAL)) Mtr_PrintTree(node->child); + Mtr_PrintTree(node->younger); + return; + +} /* end of Mtr_PrintTree */ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/mtrGroup.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/mtrGroup.c new file mode 100644 index 000000000..4269cf848 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/mtrGroup.c @@ -0,0 +1,877 @@ +/**CFile*********************************************************************** + + FileName [mtrGroup.c] + + PackageName [mtr] + + Synopsis [Functions to support group specification for reordering.] + + Description [External procedures included in this module: +
                            +
                          • Mtr_InitGroupTree() +
                          • Mtr_MakeGroup() +
                          • Mtr_DissolveGroup() +
                          • Mtr_FindGroup() +
                          • Mtr_SwapGroups() +
                          • Mtr_ReorderGroups() +
                          • Mtr_PrintGroups() +
                          • Mtr_ReadGroups() +
                          + Static procedures included in this module: +
                            +
                          • mtrShiftHL +
                          + ] + + SeeAlso [cudd package] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "mtrInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] MTR_UNUSED = "$Id: mtrGroup.c,v 1.21 2012/02/05 01:06:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int mtrShiftHL (MtrNode *node, int shift); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Allocate new tree.] + + Description [Allocate new tree with one node, whose low and size + fields are specified by the lower and size parameters. + Returns pointer to tree root.] + + SideEffects [None] + + SeeAlso [Mtr_InitTree Mtr_FreeTree] + +******************************************************************************/ +MtrNode * +Mtr_InitGroupTree( + int lower, + int size) +{ + MtrNode *root; + + root = Mtr_InitTree(); + if (root == NULL) return(NULL); + root->flags = MTR_DEFAULT; + root->low = lower; + root->size = size; + return(root); + +} /* end of Mtr_InitGroupTree */ + + +/**Function******************************************************************** + + Synopsis [Makes a new group with size leaves starting at low.] + + Description [Makes a new group with size leaves starting at low. + If the new group intersects an existing group, it must + either contain it or be contained by it. This procedure relies on + the low and size fields of each node. It also assumes that the + children of each node are sorted in order of increasing low. In + case of a valid request, the flags of the new group are set to the + value passed in `flags.' Returns the pointer to the root of the new + group upon successful termination; NULL otherwise. If the group + already exists, the pointer to its root is returned.] + + SideEffects [None] + + SeeAlso [Mtr_DissolveGroup Mtr_ReadGroups Mtr_FindGroup] + +******************************************************************************/ +MtrNode * +Mtr_MakeGroup( + MtrNode * root /* root of the group tree */, + unsigned int low /* lower bound of the group */, + unsigned int size /* size of the group */, + unsigned int flags /* flags for the new group */) +{ + MtrNode *node, + *first, + *last, + *previous, + *newn; + + /* Sanity check. */ + if (size == 0) + return(NULL); + + /* Check whether current group includes new group. This check is + ** necessary at the top-level call. In the subsequent calls it is + ** redundant. */ + if (low < (unsigned int) root->low || + low + size > (unsigned int) (root->low + root->size)) + return(NULL); + + /* At this point we know that the new group is contained + ** in the group of root. We have two possible cases here: + ** - root is a terminal node; + ** - root has children. */ + + /* Root has no children: create a new group. */ + if (root->child == NULL) { + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->parent = root; + newn->elder = newn->younger = newn->child = NULL; + root->child = newn; + return(newn); + } + + /* Root has children: Find all children of root that are included + ** in the new group. If the group of any child entirely contains + ** the new group, call Mtr_MakeGroup recursively. */ + previous = NULL; + first = root->child; /* guaranteed to be non-NULL */ + while (first != NULL && low >= (unsigned int) (first->low + first->size)) { + previous = first; + first = first->younger; + } + if (first == NULL) { + /* We have scanned the entire list and we need to append a new + ** child at the end of it. Previous points to the last child + ** of root. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->parent = root; + newn->elder = previous; + previous->younger = newn; + newn->younger = newn->child = NULL; + return(newn); + } + /* Here first is non-NULL and low < first->low + first->size. */ + if (low >= (unsigned int) first->low && + low + size <= (unsigned int) (first->low + first->size)) { + /* The new group is contained in the group of first. */ + newn = Mtr_MakeGroup(first, low, size, flags); + return(newn); + } else if (low + size <= first->low) { + /* The new group is entirely contained in the gap between + ** previous and first. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->child = NULL; + newn->parent = root; + newn->elder = previous; + newn->younger = first; + first->elder = newn; + if (previous != NULL) { + previous->younger = newn; + } else { + root->child = newn; + } + return(newn); + } else if (low < (unsigned int) first->low && + low + size < (unsigned int) (first->low + first->size)) { + /* Trying to cut an existing group: not allowed. */ + return(NULL); + } else if (low > first->low) { + /* The new group neither is contained in the group of first + ** (this was tested above) nor contains it. It is therefore + ** trying to cut an existing group: not allowed. */ + return(NULL); + } + + /* First holds the pointer to the first child contained in the new + ** group. Here low <= first->low and low + size >= first->low + + ** first->size. One of the two inequalities is strict. */ + last = first->younger; + while (last != NULL && + (unsigned int) (last->low + last->size) < low + size) { + last = last->younger; + } + if (last == NULL) { + /* All the chilren of root from first onward become children + ** of the new group. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->child = first; + newn->parent = root; + newn->elder = previous; + newn->younger = NULL; + first->elder = NULL; + if (previous != NULL) { + previous->younger = newn; + } else { + root->child = newn; + } + last = first; + while (last != NULL) { + last->parent = newn; + last = last->younger; + } + return(newn); + } + + /* Here last != NULL and low + size <= last->low + last->size. */ + if (low + size - 1 >= (unsigned int) last->low && + low + size < (unsigned int) (last->low + last->size)) { + /* Trying to cut an existing group: not allowed. */ + return(NULL); + } + + /* First and last point to the first and last of the children of + ** root that are included in the new group. Allocate a new node + ** and make all children of root between first and last chidren of + ** the new node. Previous points to the child of root immediately + ** preceeding first. If it is NULL, then first is the first child + ** of root. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->child = first; + newn->parent = root; + if (previous == NULL) { + root->child = newn; + } else { + previous->younger = newn; + } + newn->elder = previous; + newn->younger = last->younger; + if (last->younger != NULL) { + last->younger->elder = newn; + } + last->younger = NULL; + first->elder = NULL; + for (node = first; node != NULL; node = node->younger) { + node->parent = newn; + } + + return(newn); + +} /* end of Mtr_MakeGroup */ + + +/**Function******************************************************************** + + Synopsis [Merges the children of `group' with the children of its + parent.] + + Description [Merges the children of `group' with the children of its + parent. Disposes of the node pointed by group. If group is the + root of the group tree, this procedure leaves the tree unchanged. + Returns the pointer to the parent of `group' upon successful + termination; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Mtr_MakeGroup] + +******************************************************************************/ +MtrNode * +Mtr_DissolveGroup( + MtrNode * group /* group to be dissolved */) +{ + MtrNode *parent; + MtrNode *last; + + parent = group->parent; + + if (parent == NULL) return(NULL); + if (MTR_TEST(group,MTR_TERMINAL) || group->child == NULL) return(NULL); + + /* Make all children of group children of its parent, and make + ** last point to the last child of group. */ + for (last = group->child; last->younger != NULL; last = last->younger) { + last->parent = parent; + } + last->parent = parent; + + last->younger = group->younger; + if (group->younger != NULL) { + group->younger->elder = last; + } + + group->child->elder = group->elder; + if (group == parent->child) { + parent->child = group->child; + } else { + group->elder->younger = group->child; + } + + Mtr_DeallocNode(group); + return(parent); + +} /* end of Mtr_DissolveGroup */ + + +/**Function******************************************************************** + + Synopsis [Finds a group with size leaves starting at low, if it exists.] + + Description [Finds a group with size leaves starting at low, if it + exists. This procedure relies on the low and size fields of each + node. It also assumes that the children of each node are sorted in + order of increasing low. Returns the pointer to the root of the + group upon successful termination; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +MtrNode * +Mtr_FindGroup( + MtrNode * root /* root of the group tree */, + unsigned int low /* lower bound of the group */, + unsigned int size /* upper bound of the group */) +{ + MtrNode *node; + +#ifdef MTR_DEBUG + /* We cannot have a non-empty proper subgroup of a singleton set. */ + assert(!MTR_TEST(root,MTR_TERMINAL)); +#endif + + /* Sanity check. */ + if (size < 1) return(NULL); + + /* Check whether current group includes the group sought. This + ** check is necessary at the top-level call. In the subsequent + ** calls it is redundant. */ + if (low < (unsigned int) root->low || + low + size > (unsigned int) (root->low + root->size)) + return(NULL); + + if (root->size == size && root->low == low) + return(root); + + if (root->child == NULL) + return(NULL); + + /* Find all chidren of root that are included in the new group. If + ** the group of any child entirely contains the new group, call + ** Mtr_MakeGroup recursively. */ + node = root->child; + while (low >= (unsigned int) (node->low + node->size)) { + node = node->younger; + } + if (low + size <= (unsigned int) (node->low + node->size)) { + /* The group is contained in the group of node. */ + node = Mtr_FindGroup(node, low, size); + return(node); + } else { + return(NULL); + } + +} /* end of Mtr_FindGroup */ + + +/**Function******************************************************************** + + Synopsis [Swaps two children of a tree node.] + + Description [Swaps two children of a tree node. Adjusts the high and + low fields of the two nodes and their descendants. The two children + must be adjacent. However, first may be the younger sibling of second. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Mtr_SwapGroups( + MtrNode * first /* first node to be swapped */, + MtrNode * second /* second node to be swapped */) +{ + MtrNode *node; + MtrNode *parent; + int sizeFirst; + int sizeSecond; + + if (second->younger == first) { /* make first first */ + node = first; + first = second; + second = node; + } else if (first->younger != second) { /* non-adjacent */ + return(0); + } + + sizeFirst = first->size; + sizeSecond = second->size; + + /* Swap the two nodes. */ + parent = first->parent; + if (parent == NULL || second->parent != parent) return(0); + if (parent->child == first) { + parent->child = second; + } else { /* first->elder != NULL */ + first->elder->younger = second; + } + if (second->younger != NULL) { + second->younger->elder = first; + } + first->younger = second->younger; + second->elder = first->elder; + first->elder = second; + second->younger = first; + + /* Adjust the high and low fields. */ + if (!mtrShiftHL(first,sizeSecond)) return(0); + if (!mtrShiftHL(second,-sizeFirst)) return(0); + + return(1); + +} /* end of Mtr_SwapGroups */ + + +/**Function******************************************************************** + + Synopsis [Fix variable tree at the end of tree sifting.] + + Description [Fix the levels in the variable tree sorting siblings + according to them. It should be called on a non-NULL tree. It then + maintains this invariant. It applies insertion sorting to the list of + siblings The order is determined by permutation, which is used to find + the new level of the node index. Index must refer to the first variable + in the group.] + + SideEffects [The tree is modified.] + + SeeAlso [] + +******************************************************************************/ +void +Mtr_ReorderGroups( + MtrNode *treenode, + int *permutation) +{ + MtrNode *auxnode; + /* Initialize sorted list to first element. */ + MtrNode *sorted = treenode; + sorted->low = permutation[sorted->index]; + if (sorted->child != NULL) + Mtr_ReorderGroups(sorted->child, permutation); + + auxnode = treenode->younger; + while (auxnode != NULL) { + MtrNode *rightplace; + MtrNode *moving = auxnode; + auxnode->low = permutation[auxnode->index]; + if (auxnode->child != NULL) + Mtr_ReorderGroups(auxnode->child, permutation); + rightplace = auxnode->elder; + /* Find insertion point. */ + while (rightplace != NULL && auxnode->low < rightplace->low) + rightplace = rightplace->elder; + auxnode = auxnode->younger; + if (auxnode != NULL) { + auxnode->elder = moving->elder; + auxnode->elder->younger = auxnode; + } else { + moving->elder->younger = NULL; + } + if (rightplace == NULL) { /* Move to head of sorted list. */ + sorted->elder = moving; + moving->elder = NULL; + moving->younger = sorted; + sorted = moving; + } else { /* Splice. */ + moving->elder = rightplace; + moving->younger = rightplace->younger; + if (rightplace->younger != NULL) + rightplace->younger->elder = moving; + rightplace->younger = moving; + } + } + /* Fix parent. */ + if (sorted->parent != NULL) + sorted->parent->child = sorted; + +} /* end of Mtr_ReorderGroups */ + + +/**Function******************************************************************** + + Synopsis [Prints the groups as a parenthesized list.] + + Description [Prints the groups as a parenthesized list. After each + group, the group's flag are printed, preceded by a `|'. For each + flag (except MTR_TERMINAL) a character is printed. +
                            +
                          • F: MTR_FIXED +
                          • N: MTR_NEWNODE +
                          • S: MTR_SOFT +
                          + The second argument, silent, if different from 0, causes + Mtr_PrintGroups to only check the syntax of the group tree. + ] + + SideEffects [None] + + SeeAlso [Mtr_PrintTree] + +******************************************************************************/ +void +Mtr_PrintGroups( + MtrNode * root /* root of the group tree */, + int silent /* flag to check tree syntax only */) +{ + MtrNode *node; + + assert(root != NULL); + assert(root->younger == NULL || root->younger->elder == root); + assert(root->elder == NULL || root->elder->younger == root); +#if SIZEOF_VOID_P == 8 + if (!silent) (void) printf("(%u",root->low); +#else + if (!silent) (void) printf("(%hu",root->low); +#endif + if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) { + if (!silent) (void) printf(","); + } else { + node = root->child; + while (node != NULL) { + assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size)); + assert(node->parent == root); + Mtr_PrintGroups(node,silent); + node = node->younger; + } + } + if (!silent) { +#if SIZEOF_VOID_P == 8 + (void) printf("%u", root->low + root->size - 1); +#else + (void) printf("%hu", root->low + root->size - 1); +#endif + if (root->flags != MTR_DEFAULT) { + (void) printf("|"); + if (MTR_TEST(root,MTR_FIXED)) (void) printf("F"); + if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N"); + if (MTR_TEST(root,MTR_SOFT)) (void) printf("S"); + } + (void) printf(")"); + if (root->parent == NULL) (void) printf("\n"); + } + assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0); + return; + +} /* end of Mtr_PrintGroups */ + + +/**Function******************************************************************** + + Synopsis [Prints the variable order as a parenthesized list.] + + Description [Prints the variable order as a parenthesized list. After each + group, the group's flag are printed, preceded by a `|'. For each + flag (except MTR_TERMINAL) a character is printed. +
                            +
                          • F: MTR_FIXED +
                          • N: MTR_NEWNODE +
                          • S: MTR_SOFT +
                          + The second argument, gives the map from levels to variable indices. + ] + + SideEffects [None] + + SeeAlso [Mtr_PrintGroups] + +******************************************************************************/ +int +Mtr_PrintGroupedOrder( + MtrNode * root /* root of the group tree */, + int *invperm /* map from levels to indices */, + FILE *fp /* output file */) +{ + MtrNode *child; + MtrHalfWord level; + int retval; + + assert(root != NULL); + assert(root->younger == NULL || root->younger->elder == root); + assert(root->elder == NULL || root->elder->younger == root); + retval = fprintf(fp,"("); + if (retval == EOF) return(0); + level = root->low; + child = root->child; + while (child != NULL) { + assert(child->low >= root->low && (child->low + child->size) <= (root->low + root->size)); + assert(child->parent == root); + while (level < child->low) { + retval = fprintf(fp,"%d%s", invperm[level], (level < root->low + root->size - 1) ? "," : ""); + if (retval == EOF) return(0); + level++; + } + retval = Mtr_PrintGroupedOrder(child,invperm,fp); + if (retval == 0) return(0); + level += child->size; + if (level < root->low + root->size - 1) { + retval = fprintf(fp,","); + if (retval == EOF) return(0); + } + child = child->younger; + } + while (level < root->low + root->size) { + retval = fprintf(fp,"%d%s", invperm[level], (level < root->low + root->size - 1) ? "," : ""); + if (retval == EOF) return(0); + level++; + } + if (root->flags != MTR_DEFAULT) { + retval = fprintf(fp,"|"); + if (retval == EOF) return(0); + if (MTR_TEST(root,MTR_FIXED)) { + retval = fprintf(fp,"F"); + if (retval == EOF) return(0); + } + if (MTR_TEST(root,MTR_NEWNODE)) { + retval = fprintf(fp,"N"); + if (retval == EOF) return(0); + } + if (MTR_TEST(root,MTR_SOFT)) { + retval = fprintf(fp,"S"); + if (retval == EOF) return(0); + } + } + retval = fprintf(fp,")"); + if (retval == EOF) return(0); + if (root->parent == NULL) { + retval = fprintf(fp,"\n"); + if (retval == EOF) return(0); + } + assert((root->flags &~(MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0); + return(1); + +} /* end of Mtr_PrintGroupedOrder */ + + +/**Function******************************************************************** + + Synopsis [Reads groups from a file and creates a group tree.] + + Description [Reads groups from a file and creates a group tree. + Each group is specified by three fields: + + low size flags. + + Low and size are (short) integers. Flags is a string composed of the + following characters (with associated translation): +
                            +
                          • D: MTR_DEFAULT +
                          • F: MTR_FIXED +
                          • N: MTR_NEWNODE +
                          • S: MTR_SOFT +
                          • T: MTR_TERMINAL +
                          + Normally, the only flags that are needed are D and F. Groups and + fields are separated by white space (spaces, tabs, and newlines). + Returns a pointer to the group tree if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Mtr_InitGroupTree Mtr_MakeGroup] + +******************************************************************************/ +MtrNode * +Mtr_ReadGroups( + FILE * fp /* file pointer */, + int nleaves /* number of leaves of the new tree */) +{ + int low; + int size; + int err; + unsigned int flags; + MtrNode *root; + MtrNode *node; + char attrib[8*sizeof(unsigned int)+1]; + char *c; + + root = Mtr_InitGroupTree(0,nleaves); + if (root == NULL) return NULL; + + while (! feof(fp)) { + /* Read a triple and check for consistency. */ + err = fscanf(fp, "%d %d %s", &low, &size, attrib); + if (err == EOF) { + break; + } else if (err != 3) { + Mtr_FreeTree(root); + return(NULL); + } else if (low < 0 || low+size > nleaves || size < 1) { + Mtr_FreeTree(root); + return(NULL); + } else if (strlen(attrib) > 8 * sizeof(MtrHalfWord)) { + /* Not enough bits in the flags word to store these many + ** attributes. */ + Mtr_FreeTree(root); + return(NULL); + } + + /* Parse the flag string. Currently all flags are permitted, + ** to make debugging easier. Normally, specifying NEWNODE + ** wouldn't be allowed. */ + flags = MTR_DEFAULT; + for (c=attrib; *c != 0; c++) { + switch (*c) { + case 'D': + break; + case 'F': + flags |= MTR_FIXED; + break; + case 'N': + flags |= MTR_NEWNODE; + break; + case 'S': + flags |= MTR_SOFT; + break; + case 'T': + flags |= MTR_TERMINAL; + break; + default: + return NULL; + } + } + node = Mtr_MakeGroup(root, (MtrHalfWord) low, (MtrHalfWord) size, + flags); + if (node == NULL) { + Mtr_FreeTree(root); + return(NULL); + } + } + + return(root); + +} /* end of Mtr_ReadGroups */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Adjusts the low fields of a node and its descendants.] + + Description [Adjusts the low fields of a node and its + descendants. Adds shift to low of each node. Checks that no + out-of-bounds values result. Returns 1 in case of success; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +mtrShiftHL( + MtrNode * node /* group tree node */, + int shift /* amount by which low should be changed */) +{ + MtrNode *auxnode; + int low; + + low = (int) node->low; + + + low += shift; + + if (low < 0 || low + (int) (node->size - 1) > (int) MTR_MAXHIGH) return(0); + + node->low = (MtrHalfWord) low; + + if (!MTR_TEST(node,MTR_TERMINAL) && node->child != NULL) { + auxnode = node->child; + do { + if (!mtrShiftHL(auxnode,shift)) return(0); + auxnode = auxnode->younger; + } while (auxnode != NULL); + } + + return(1); + +} /* end of mtrShiftHL */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/test.groups b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/test.groups new file mode 100644 index 000000000..fbedcaf1e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/test.groups @@ -0,0 +1,5 @@ +0 6 D +6 6 F +0 2 D +2 2 D +4 2 D diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/testmtr.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/testmtr.c new file mode 100644 index 000000000..54f069d56 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/mtr/testmtr.c @@ -0,0 +1,270 @@ +/**CFile*********************************************************************** + + FileName [testmtr.c] + + PackageName [mtr] + + Synopsis [Test program for the mtr package.] + + Description [] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + +******************************************************************************/ + +#include "util.h" +#include "mtr.h" + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] MTR_UNUSED = "$Id: testmtr.c,v 1.5 2012/02/05 06:10:35 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define TESTMTR_VERSION\ + "TestMtr Version #0.6, Release date 2/6/12" + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void usage (char *prog); +static FILE * open_file (const char *filename, const char *mode); + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Main program for testmtr.] + + Description [Main program for testmtr. Performs initialization. + Reads command line options and network(s). Builds some simple trees + and prints them out.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +main( + int argc, + char ** argv) +{ + MtrNode *root, + *node; + int i, + c, + pr = 0; + FILE *fp; + const char *file = NULL; + + (void) printf("# %s\n", TESTMTR_VERSION); + /* Echo command line and arguments. */ + (void) printf("#"); + for(i = 0; i < argc; i++) { + (void) printf(" %s", argv[i]); + } + (void) printf("\n"); + (void) fflush(stdout); + + while ((c = getopt(argc, argv, "Mhp:")) != EOF) { + switch(c) { + case 'M': +#ifdef MNEMOSYNE + (void) mnem_setrecording(0); +#endif + break; + case 'p': + pr = atoi(optarg); + break; + case 'h': + default: + usage(argv[0]); + break; + } + } + + if (argc - optind == 0) { + file = "-"; + } else if (argc - optind == 1) { + file = argv[optind]; + } else { + usage(argv[0]); + } + + /* Create and print a simple tree. */ + root = Mtr_InitTree(); + root->flags = 0; + node = Mtr_CreateFirstChild(root); + node->flags = 1; + node = Mtr_CreateLastChild(root); + node->flags = 2; + node = Mtr_CreateFirstChild(root); + node->flags = 3; + node = Mtr_AllocNode(); + node->flags = 4; + Mtr_MakeNextSibling(root->child,node); + Mtr_PrintTree(root); + Mtr_FreeTree(root); + (void) printf("#------------------------\n"); + + /* Create an initial tree in which all variables belong to one group. */ + root = Mtr_InitGroupTree(0,12); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + node = Mtr_MakeGroup(root,0,6,MTR_DEFAULT); + node = Mtr_MakeGroup(root,6,6,MTR_DEFAULT); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + for (i = 0; i < 6; i+=2) { + node = Mtr_MakeGroup(root,(unsigned) i,(unsigned) 2,MTR_DEFAULT); + } + node = Mtr_MakeGroup(root,0,12,MTR_FIXED); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + /* Print a partial tree. */ + (void) printf("# "); + Mtr_PrintGroups(root->child,pr == 0); (void) printf("\n"); + node = Mtr_FindGroup(root,0,6); + node = Mtr_DissolveGroup(node); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + node = Mtr_FindGroup(root,4,2); + if (!Mtr_SwapGroups(node,node->younger)) { + (void) printf("error in Mtr_SwapGroups\n"); + exit(3); + } + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); + Mtr_FreeTree(root); + (void) printf("#------------------------\n"); + + /* Create a group tree with fixed subgroups. */ + root = Mtr_InitGroupTree(0,4); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + node = Mtr_MakeGroup(root,0,2,MTR_FIXED); + node = Mtr_MakeGroup(root,2,2,MTR_FIXED); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + Mtr_FreeTree(root); + (void) printf("#------------------------\n"); + + /* Open input file. */ + fp = open_file(file, "r"); + root = Mtr_ReadGroups(fp,12); + Mtr_PrintTree(root); (void) printf("# "); + Mtr_PrintGroups(root,pr == 0); (void) printf("\n"); + + Mtr_FreeTree(root); + +#ifdef MNEMOSYNE + mnem_writestats(); +#endif + + exit(0); + /* NOTREACHED */ + +} /* end of main */ + + +/**Function******************************************************************** + + Synopsis [Prints usage message and exits.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +static void +usage( + char * prog) +{ + (void) fprintf(stderr, "usage: %s [options] [file]\n", prog); + (void) fprintf(stderr, " -M\t\tturns off memory allocation recording\n"); + (void) fprintf(stderr, " -h\t\tprints this message\n"); + (void) fprintf(stderr, " -p n\t\tcontrols verbosity\n"); + exit(2); + +} /* end of usage */ + + +/**Function******************************************************************** + + Synopsis [Opens a file.] + + Description [Opens a file, or fails with an error message and exits. + Allows '-' as a synonym for standard input.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static FILE * +open_file( + const char * filename, + const char * mode) +{ + FILE *fp; + + if (strcmp(filename, "-") == 0) { + return mode[0] == 'r' ? stdin : stdout; + } else if ((fp = fopen(filename, mode)) == NULL) { + perror(filename); + exit(1); + } + return(fp); + +} /* end of open_file */ + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/Makefile.sis b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/Makefile.sis new file mode 100644 index 000000000..fb0c3e64d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/Makefile.sis @@ -0,0 +1,97 @@ +# $Id$ +# +# Cudd - DD package +#--------------------------- +.SUFFIXES: .o .c .u + +RANLIB = ranlib + +CAD = /projects/octtools/octtools/$(MACHINE) +SIS = .. +LINTCREATEFLAG = -C + +# files for the package +P = bdd +PSRC = cuddAPI.c cuddAddAbs.c cuddAddApply.c cuddAddFind.c cuddAddIte.c \ + cuddAddInv.c cuddAddNeg.c cuddAddWalsh.c cuddAndAbs.c \ + cuddAnneal.c cuddApa.c cuddApprox.c cuddBddAbs.c cuddBddCorr.c \ + cuddBddIte.c cuddBddPort.c cuddBridge.c cuddCache.c cuddCheck.c \ + cuddClip.c cuddCof.c cuddCompose.c cuddDecomp.c cuddEssent.c \ + cuddExact.c cuddExport.c cuddGenCof.c \ + cuddGenetic.c cuddGroup.c cuddHarwell.c cuddInit.c cuddInteract.c \ + cuddLCache.c cuddLevelQ.c cuddLinear.c cuddLiteral.c \ + cuddMatMult.c cuddPriority.c cuddPwPt.c \ + cuddRead.c cuddRef.c cuddReorder.c cuddSat.c cuddSign.c \ + cuddSolve.c cuddSplit.c cuddSubsetHB.c cuddSubsetSP.c cuddSymmetry.c \ + cuddTable.c cuddUtil.c cuddWindow.c cuddZddCount.c cuddZddFuncs.c \ + cuddZddGroup.c cuddZddIsop.c cuddZddLin.c cuddZddMisc.c \ + cuddZddPort.c cuddZddReord.c cuddZddSetop.c cuddZddSymm.c \ + cuddZddUtil.c +POBJ = $(PSRC:.c=.o) +PHDR = cudd.h cuddInt.h cuddBdd.h + +# files for the test program +TARGET = testcudd +SRC = testcudd.c +OBJ = $(SRC:.c=.o) +HDR = + +LIBS = ../util/libutil.a ../st/libst.a +LINTLIBS= ../util/llib-lutil.ln ../st/llib-lst.ln +INCLUDE = -I$(CAD)/include -I$(SIS)/include + +CFLAGS = -g $(INCLUDE) +LDFLAGS = -g +LINTFLAGS = $(INCLUDE) ${LINTEXTRAS} + +#------------------------------------------------------ + +$(TARGET): $(PHDR) $(OBJ) $(POBJ) $(LIBS) + $(CC) $(LDFLAGS) -o $(TARGET) $(OBJ) $(POBJ) $(LIBS) + +lint: $(PSRC) $(PHDR) $(SRC) $(HDR) + lint $(LINTFLAGS) $(SRC) $(PSRC) $(LINTLIBS) + +install: lib$(P).a llib-l$(P).ln + +lib$(P).a: $(POBJ) + ar cr $@ $? + $(RANLIB) $@ + +unpack: lib$(P).a + @for i in $(POBJ); do \ + ln -s $(SIS)/$(P)/$$i $(SIS)/unpack; \ + done + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) ${LINTCREATEFLAG}$(P) -n $(PSRC) + +clean: + rm -f $(TARGET) *.a *.ln *.o \ + [Tt]ags [Mm]ake.out lint malloc.out gmon.out __.SYMDEF *~ + +tags: _force + @for i in $(PSRC) $(PHDR); do \ + cwd=`pwd`; ctags -a $$cwd/$$i; + done; + +strip_depend: + sed '/^#--DO NOT CHANGE ANYTHING AFTER THIS LINE/,$$d' Makefile >mktemp + mv mktemp Makefile + +depend: + sed '/^#--DO NOT CHANGE ANYTHING AFTER THIS LINE/,$$d' Makefile >mktemp + echo '#--DO NOT CHANGE ANYTHING AFTER THIS LINE' >>mktemp + $(CAD)/bin/cc-M $(CFLAGS) $(PSRC) | \ + sed 's|$(CAD)|$$(CAD)|g' | \ + grep -v '/usr/include' >>mktemp + mv mktemp Makefile + +#-------------------------- IBM 3090 support ----------------- +IBMHOST = opua +IBMDIST = /users2/sis +ibmdist: $(PSRC) $(PHDR) + rdist -Richw $(PSRC) $(PHDR) $(IBMHOST):$(IBMDIST) +#------------------------------------------------------------- +_force: + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/cuddBddPort.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/cuddBddPort.c new file mode 100644 index 000000000..7b97956c6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/cuddBddPort.c @@ -0,0 +1,1954 @@ +/**CFile*********************************************************************** + + FileName [cuddBddPort.c] + + PackageName [cudd] + + Synopsis [SIS interface to the Decision Diagram Package of the + University of Colorado.] + + Description [This file implements an interface between the functions in + the Berkeley BDD package and the functions provided by the CUDD (decision + diagram) package from the University of Colorado. The CUDD package is a + generic implementation of a decision diagram data structure. For the time + being, only Boole expansion is implemented and the leaves in the + in the nodes can be the constants zero, one or any arbitrary value.] + + Author [Abelardo Pardo] + + Copyright [Copyright (c) 1994-1996 The Univ. of Colorado. + All rights reserved. + + Permission is hereby granted, without written agreement and without license + or royalty fees, to use, copy, modify, and distribute this software and its + documentation for any purpose, provided that the above copyright notice and + the following two paragraphs appear in all copies of this software. + + IN NO EVENT SHALL THE UNIVERSITY OF COLORADO BE LIABLE TO ANY PARTY FOR + DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + COLORADO HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + THE UNIVERSITY OF COLORADO SPECIFICALLY DISCLAIMS ANY WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN + "AS IS" BASIS, AND THE UNIVERSITY OF COLORADO HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.] + +******************************************************************************/ + +#include "util.h" +#include "array.h" +#include "st.h" + +#ifdef EXTERN +#undef EXTERN +#endif +#define EXTERN +#include "cuddInt.h" +#include "cuddBdd.h" + + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +struct bdd_gen { + bdd_manager *manager; + DdGen *ddGen; + array_t *cube; +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBddPort.c,v 1.11 1996/05/08 06:13:08 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static bdd_t * bdd_construct_bdd_t (DdManager *mgr, DdNode * fn); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Terminates the bdd package.] + + SideEffects [] + +******************************************************************************/ +void +bdd_end(mgr) +bdd_manager *mgr; +{ + if (mgr->hooks != NULL) FREE(mgr->hooks); + Cudd_Quit(mgr); + +} /* end of bdd_end */ + + +/**Function******************************************************************** + + Synopsis [Initialize manager with the options given in mgr_init.] + + SideEffects [] + +******************************************************************************/ +void +bdd_set_mgr_init_dflts(mgr_init) +bdd_mgr_init *mgr_init; +{ + fprintf(stderr,"CU DD Package: bdd_set_mgr_init_dflts translated to no-op\n"); + return; + +} /* end of bdd_set_mgr_init_dflts */ + + +/**Function******************************************************************** + + Synopsis [Starts the manager with nvariables variables.] + + SideEffects [] + +******************************************************************************/ +bdd_manager * +bdd_start(nvariables) +int nvariables; +{ + DdManager *mgr; + bdd_external_hooks *hooks; + + mgr = Cudd_Init((unsigned int)nvariables,0,CUDD_UNIQUE_SLOTS, + CUDD_CACHE_SLOTS,0); + + hooks = ALLOC(bdd_external_hooks,1); + hooks->mdd = hooks->network = hooks->undef1 = (char *) 0; + mgr->hooks = (char *) hooks; + + return (bdd_manager *)mgr; + +} /* end of bdd_start */ + + +/**Function******************************************************************** + + Synopsis [Starts the manager with parameters.] + + SideEffects [] + +******************************************************************************/ +bdd_manager * +bdd_start_with_params(nvariables, mgr_init) +int nvariables; +bdd_mgr_init *mgr_init; +{ + fprintf(stderr,"CU DD Package: bdd_start_with_parameters bypassed\n"); + return (bdd_manager *)Cudd_Init((unsigned int)nvariables,0, + CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); + +} /* end of bdd_start_with_params */ + + +/**Function******************************************************************** + + Synopsis [Creates a new variable in the manager.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_create_variable(mgr) +bdd_manager *mgr; +{ + DdNode *var; + DdManager *dd = (DdManager *) mgr; + DdNode *one = DD_ONE(dd); + + if (dd->size >= CUDD_MAXINDEX -1) return(NULL); + do { + dd->reordered = 0; + var = cuddUniqueInter(dd,dd->size,one,Cudd_Not(one)); + } while (dd->reordered == 1); + + if (var == NULL) return(NULL); + cuddRef(var); + return(bdd_construct_bdd_t(dd,var)); + +} /* end of bdd_create_variable */ + + +/**Function******************************************************************** + + Synopsis [Creates a new variable and positions it after the + variable with the specified index.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_create_variable_after(mgr, after_id) +bdd_manager *mgr; +bdd_variableId after_id; +{ + DdNode *var; + DdManager *dd = (DdManager *) mgr; + int level; + + if (after_id >= dd->size) return(NULL); + level = 1 + dd->perm[after_id]; + var = Cudd_bddNewVarAtLevel(dd,level); + if (var == NULL) return(NULL); + cuddRef(var); + return(bdd_construct_bdd_t(dd,var)); + +} /* end of bdd_create_variable_after */ + + +/**Function******************************************************************** + + Synopsis [Returns the BDD representing the variable with given ID.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_get_variable(mgr, variable_ID) +bdd_manager *mgr; +bdd_variableId variable_ID; /* unsigned int */ +{ + DdNode *var; + DdManager *dd = (DdManager *) mgr; + DdNode *one = DD_ONE(dd); + + if (variable_ID >= CUDD_MAXINDEX -1) return(NULL); + do { + dd->reordered = 0; + var = cuddUniqueInter(dd,(int)variable_ID,one,Cudd_Not(one)); + } while (dd->reordered == 1); + + if (var == NULL) return(NULL); + cuddRef(var); + return(bdd_construct_bdd_t(dd,var)); + +} /* end of bdd_get_variable */ + + +/**Function******************************************************************** + + Synopsis [Creates a copy of the BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_dup(f) +bdd_t *f; +{ + cuddRef(f->node); + return(bdd_construct_bdd_t((DdManager *)f->mgr,f->node)); + +} /* end of bdd_dup */ + + +/**Function******************************************************************** + + Synopsis [Deletes the BDD of f.] + + SideEffects [] + +******************************************************************************/ +void +bdd_free(f) +bdd_t *f; +{ + if (f == NULL) { + fail("bdd_free: trying to free a NULL bdd_t"); + } + + if (f->free == TRUE) { + fail("bdd_free: trying to free a freed bdd_t"); + } + + Cudd_RecursiveDeref((DdManager *)f->mgr,f->node); + /* This is a bit overconservative. */ + f->node = 0; + f->mgr = 0; + f->free = 0; + FREE(f); + return; + +} /* end of bdd_free */ + + +/**Function******************************************************************** + + Synopsis [And of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_and(f, g, f_phase, g_phase) +bdd_t *f; +bdd_t *g; +boolean f_phase; +boolean g_phase; +{ + DdManager *dd; + DdNode *newf,*newg,*fandg; + bdd_t *result; + + /* Make sure both BDDs belong to the same manager. */ + assert(f->mgr == g->mgr); + + /* Modify the phases of the operands according to the parameters. */ + if (!f_phase) { + newf = Cudd_Not(f->node); + } else { + newf = f->node; + } + if (!g_phase) { + newg = Cudd_Not(g->node); + } else { + newg = g->node; + } + + /* Perform the AND operation */ + dd = (DdManager *)f->mgr; + fandg = Cudd_bddAnd((DdManager *)f->mgr,newf,newg); + if (fandg == NULL) return(NULL); + cuddRef(fandg); + result = bdd_construct_bdd_t(dd,fandg); + + return(result); + +} /* end of bdd_and */ + + +/**Function******************************************************************** + + Synopsis [Abstracts variables from the product of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_and_smooth(f, g, smoothing_vars) +bdd_t *f; +bdd_t *g; +array_t *smoothing_vars; /* of bdd_t *'s */ +{ + int i; + bdd_t *variable; + DdNode *cube,*tmpDd,*result; + DdManager *mgr; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + /* The Boulder package needs the smothing variables passed as a cube. + ** Therefore we must build that cube from the indices of variables + ** in the array before calling the procedure. + */ + mgr = (DdManager *)f->mgr; + Cudd_Ref(cube = DD_ONE(mgr)); + for (i = 0; i < array_n(smoothing_vars); i++) { + variable = array_fetch(bdd_t *,smoothing_vars,i); + + /* Make sure the variable belongs to the same manager. */ + assert(mgr == variable->mgr); + + tmpDd = Cudd_bddAnd(mgr,cube,variable->node); + if (tmpDd == NULL) { + Cudd_RecursiveDeref(mgr,cube); + return(NULL); + } + cuddRef(tmpDd); + Cudd_RecursiveDeref(mgr, cube); + cube = tmpDd; + } + + /* Perform the smoothing */ + result = Cudd_bddAndAbstract(mgr,f->node,g->node,cube); + if (result == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(result); + /* Get rid of temporary results. */ + Cudd_RecursiveDeref(mgr, cube); + + /* Build the bdd_t structure for the result */ + return(bdd_construct_bdd_t(mgr,result)); + +} /* end of bdd_and_smooth */ + + +/**Function******************************************************************** + + Synopsis [Return a minimum size BDD between bounds.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_between(f_min, f_max) +bdd_t *f_min; +bdd_t *f_max; +{ + bdd_t *temp, *ret; + + temp = bdd_or(f_min, f_max, 1, 0); + ret = bdd_minimize(f_min, temp); + bdd_free(temp); + return(ret); + +} /* end of bdd_between */ + + +/**Function******************************************************************** + + Synopsis [Computes the cofactor of f with respect to g.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_cofactor(f, g) +bdd_t *f; +bdd_t *g; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager */ + assert(f->mgr == g->mgr); + + /* We use Cudd_bddConstrain instead of Cudd_Cofactor for generality. */ + result = Cudd_bddConstrain((DdManager *)f->mgr,f->node,g->node); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t((DdManager *)f->mgr,result)); + +} /* end of bdd_cofactor */ + + +/**Function******************************************************************** + + Synopsis [Functional composition of a function by a variable.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_compose(f, v, g) +bdd_t *f; +bdd_t *v; +bdd_t *g; +{ + DdNode *result; + + /* Make sure all operands belong to the same manager. */ + assert(f->mgr == g->mgr); + assert(f->mgr == v->mgr); + + result = Cudd_bddCompose(f->mgr,f->node,g->node,(int)Cudd_Regular(v->node)->index); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_compose */ + + +/**Function******************************************************************** + + Synopsis [Universal Abstraction of Variables.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_consensus(f, quantifying_vars) +bdd_t *f; +array_t *quantifying_vars; /* of bdd_t *'s */ +{ + int i; + bdd_t *variable; + DdNode *cube,*tmpDd,*result; + bdd_manager *mgr; + + /* The Boulder package needs the smothing variables passed as a cube. + ** Therefore we must build that cube from the indices of the variables + ** in the array before calling the procedure. + */ + mgr = f->mgr; + Cudd_Ref(cube = DD_ONE(mgr)); + for (i = 0; i < array_n(quantifying_vars); i++) { + variable = array_fetch(bdd_t *,quantifying_vars,i); + + /* Make sure the variable belongs to the same manager */ + assert(mgr == variable->mgr); + + tmpDd = Cudd_bddAnd(mgr,cube,variable->node); + if (tmpDd == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(tmpDd); + Cudd_RecursiveDeref(mgr, cube); + cube = tmpDd; + } + + /* Perform the consensus */ + result = Cudd_bddUnivAbstract(mgr,f->node,cube); + if (result == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(result); + /* Get rid of temporary results */ + Cudd_RecursiveDeref(mgr, cube); + + /* Build the bdd_t structure for the result */ + return(bdd_construct_bdd_t(mgr,result)); + +} /* end of bdd_consensus */ + + +/**Function******************************************************************** + + Synopsis [The compatible projection function.] + + Description [The compatible projection function. The reference minterm + is chosen based on the phases of the quantifying variables. If all + variables are in positive phase, the minterm 111...111 is used as + reference.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_cproject(f, quantifying_vars) +bdd_t *f; +array_t *quantifying_vars; /* of bdd_t* */ +{ + DdManager *dd; + DdNode *cube; + DdNode *res; + bdd_t *fi; + int nvars, i; + + if (f == NULL) { + fail ("bdd_cproject: invalid BDD"); + } + + nvars = array_n(quantifying_vars); + if (nvars <= 0) { + fail("bdd_cproject: no projection variables"); + } + dd = f->mgr; + + cube = DD_ONE(dd); + cuddRef(cube); + for (i = nvars - 1; i >= 0; i--) { + DdNode *tmpp; + fi = array_fetch(bdd_t *, quantifying_vars, i); + tmpp = Cudd_bddAnd(dd,fi->node,cube); + if (tmpp == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(tmpp); + Cudd_RecursiveDeref(dd,cube); + cube = tmpp; + } + + res = Cudd_CProjection(dd,f->node,cube); + if (res == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,cube); + + return(bdd_construct_bdd_t(dd,res)); + +} /* end of bdd_cproject */ + + +/**Function******************************************************************** + + Synopsis [ITE.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_ite(i, t, e, i_phase, t_phase, e_phase) +bdd_t *i; +bdd_t *t; +bdd_t *e; +boolean i_phase; +boolean t_phase; +boolean e_phase; +{ + DdNode *newi,*newt,*newe,*ite; + + /* Make sure both bdds belong to the same mngr */ + assert(i->mgr == t->mgr); + assert(i->mgr == e->mgr); + + /* Modify the phases of the operands according to the parameters */ + if (!i_phase) { + newi = Cudd_Not(i->node); + } else { + newi = i->node; + } + if (!t_phase) { + newt = Cudd_Not(t->node); + } else { + newt = t->node; + } + if (!e_phase) { + newe = Cudd_Not(e->node); + } else { + newe = e->node; + } + + /* Perform the ITE operation */ + ite = Cudd_bddIte(i->mgr,newi,newt,newe); + if (ite == NULL) return(NULL); + cuddRef(ite); + return(bdd_construct_bdd_t(i->mgr,ite)); + +} /* end of bdd_ite */ + + +/**Function******************************************************************** + + Synopsis [Restric operator as described in Coudert et al. ICCAD90.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_minimize(f, c) +bdd_t *f; +bdd_t *c; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == c->mgr); + + result = Cudd_bddRestrict(f->mgr,f->node,c->node); + if (result == NULL) return(NULL); + cuddRef(result); + + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_minimize */ + + +/**Function******************************************************************** + + Synopsis [Parametrized version of the Restrict operator.] + + Description [Parametrized version of the Restrict operator. Currently + defaults to bdd_minimize.] + + SideEffects [] + +******************************************************************************/ +/*ARGSUSED*/ +bdd_t * +bdd_minimize_with_params(f, c, match_type, compl, no_new_vars, return_min) +bdd_t *f; +bdd_t *c; +bdd_min_match_type_t match_type; +boolean compl; +boolean no_new_vars; +boolean return_min; +{ + return(bdd_minimize(f,c)); + +} /* end of bdd_minimize_with_params */ + + +/**Function******************************************************************** + + Synopsis [Negation.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_not(f) +bdd_t *f; +{ + DdNode *result; + + Cudd_Ref(result = Cudd_Not(f->node)); + return(bdd_construct_bdd_t((DdManager *)f->mgr,result)); + +} /* end of bdd_not */ + + +/**Function******************************************************************** + + Synopsis [Returns the one BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_one(mgr) +bdd_manager *mgr; +{ + DdNode *result; + + Cudd_Ref(result = DD_ONE((DdManager *)mgr)); + return(bdd_construct_bdd_t((DdManager *)mgr,result)); + +} /* end of bdd_one */ + + +/**Function******************************************************************** + + Synopsis [Or of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_or(f, g, f_phase, g_phase) +bdd_t *f; +bdd_t *g; +boolean f_phase; +boolean g_phase; +{ + DdNode *newf,*newg,*forg; + bdd_t *result; + + /* Make sure both bdds belong to the same mngr */ + assert(f->mgr == g->mgr); + + /* Modify the phases of the operands according to the parameters */ + if (f_phase) { + newf = Cudd_Not(f->node); + } else { + newf = f->node; + } + if (g_phase) { + newg = Cudd_Not(g->node); + } else { + newg = g->node; + } + + /* Perform the OR operation */ + forg = Cudd_bddAnd(f->mgr,newf,newg); + if (forg == NULL) return(NULL); + forg = Cudd_Not(forg); + cuddRef(forg); + result = bdd_construct_bdd_t(f->mgr,forg); + + return(result); + +} /* end of bdd_or */ + + +/**Function******************************************************************** + + Synopsis [Existential abstraction of variables.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_smooth(f, smoothing_vars) +bdd_t *f; +array_t *smoothing_vars; /* of bdd_t *'s */ +{ + int i; + bdd_t *variable; + DdNode *cube,*tmpDd,*result; + bdd_manager *mgr; + + /* The Boulder package needs the smothing variables passed as a cube. + ** Therefore we must build that cube from the indices of the variables + ** in the array before calling the procedure. + */ + mgr = f->mgr; + Cudd_Ref(cube = DD_ONE(mgr)); + for (i = 0; i < array_n(smoothing_vars); i++) { + variable = array_fetch(bdd_t *,smoothing_vars,i); + + /* Make sure the variable belongs to the same manager. */ + assert(mgr == variable->mgr); + + tmpDd = Cudd_bddAnd(mgr,cube,variable->node); + if (tmpDd == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(tmpDd); + Cudd_RecursiveDeref(mgr, cube); + cube = tmpDd; + } + + /* Perform the smoothing */ + result = Cudd_bddExistAbstract(mgr,f->node,cube); + if (result == NULL) { + Cudd_RecursiveDeref(mgr, cube); + return(NULL); + } + cuddRef(result); + + /* Get rid of temporary results */ + Cudd_RecursiveDeref(mgr, cube); + + /* Build the bdd_t structure for the result */ + return(bdd_construct_bdd_t(mgr,result)); + +} /* end of bdd_smooth */ + + +/**Function******************************************************************** + + Synopsis [Permutes the variables.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_substitute(f, old_array, new_array) +bdd_t *f; +array_t *old_array; /* of bdd_t *'s */ +array_t *new_array; /* of bdd_t *'s */ +{ + int maxOld; + int i,varIndex,from,to; + int *permut; + bdd_t *variable; + DdNode *result; + + /* Make sure both arrays have the same number of elements. */ + assert(array_n(old_array) == array_n(new_array)); + + /* Detect what is the highest index of variable to rename. */ + maxOld = 0; + for (i = 0; i < array_n(old_array); i++) { + variable = array_fetch(bdd_t *, old_array, i); + /* Make sure the variable belongs to this manager. */ + assert(f->mgr == variable->mgr); + + varIndex = Cudd_Regular(variable->node)->index; + if (varIndex > maxOld) { + maxOld = varIndex; + } + } + maxOld++; + + /* Allocate and fill the array with the trivial permutation. */ + permut = ALLOC(int, maxOld); + for (i = 0; i < maxOld; i++) permut[i] = i; + + /* Modify the permutation by looking at both arrays old and new. */ + for (i = 0; i < array_n(old_array); i++) { + variable = array_fetch(bdd_t *, old_array, i); + from = Cudd_Regular(variable->node)->index; + variable = array_fetch(bdd_t *, new_array, i); + /* Make sure the variable belongs to this manager. */ + assert(f->mgr == variable->mgr); + + to = Cudd_Regular(variable->node)->index; + permut[from] = to; + } + + result = Cudd_bddPermute(f->mgr,f->node,permut); + FREE(permut); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_substitute */ + + +/**Function******************************************************************** + + Synopsis [Returns the Then branch of the BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_then(f) +bdd_t *f; +{ + DdNode *result; + + result = Cudd_T(f->node); + result = Cudd_NotCond(result,Cudd_IsComplement(f->node)); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_then */ + + +/**Function******************************************************************** + + Synopsis [Returns the else branch of a BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_else(f) +bdd_t *f; +{ + DdNode *result; + + result = Cudd_E(f->node); + result = Cudd_NotCond(result,Cudd_IsComplement(f->node)); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_else */ + + +/**Function******************************************************************** + + Synopsis [Returns the BDD of the top variable.] + + Description [Returns the BDD of the top variable of the argument. If + the argument is constant, it returns the constant function itself.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_top_var(f) +bdd_t *f; +{ + DdNode *result; + + if (Cudd_IsConstant(f->node)) { + result = f->node; + } else { + result = f->mgr->vars[Cudd_Regular(f->node)->index]; + } + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_top_var */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive nor of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_xnor(f, g) +bdd_t *f; +bdd_t *g; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + result = Cudd_bddIte(f->mgr,f->node,g->node,Cudd_Not(g->node)); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_xnor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive or of two BDDs.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_xor(f, g) +bdd_t *f; +bdd_t *g; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + result = Cudd_bddIte(f->mgr,f->node,Cudd_Not(g->node),g->node); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_xor */ + + +/**Function******************************************************************** + + Synopsis [Returns the constant zero BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_zero(mgr) +bdd_manager *mgr; +{ + DdNode *result; + + Cudd_Ref(result = Cudd_Not(DD_ONE((mgr)))); + return(bdd_construct_bdd_t(mgr,result)); + +} /* end of bdd_zero */ + + +/**Function******************************************************************** + + Synopsis [Equality check.] + + SideEffects [] + +******************************************************************************/ +boolean +bdd_equal(f, g) +bdd_t *f; +bdd_t *g; +{ + return(f->node == g->node); + +} /* end of bdd_equal */ + + +/**Function******************************************************************** + + Synopsis [Returns a BDD included in the intersection of f and g.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_intersects(f, g) +bdd_t *f; +bdd_t *g; +{ + DdNode *result; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + result = Cudd_bddIntersect(f->mgr,f->node,g->node); + if (result == NULL) return(NULL); + cuddRef(result); + return(bdd_construct_bdd_t(f->mgr,result)); + +} /* end of bdd_intersects */ + + +/**Function******************************************************************** + + Synopsis [Checks a BDD for tautology.] + + SideEffects [] + +******************************************************************************/ +boolean +bdd_is_tautology(f, phase) +bdd_t *f; +boolean phase; +{ + if (phase) { + return(f->node == DD_ONE(f->mgr)); + } else { + return(f->node == Cudd_Not(DD_ONE(f->mgr))); + } + +} /* end of bdd_is_tautology */ + + +/**Function******************************************************************** + + Synopsis [Tests for containment of f in g.] + + SideEffects [] + +******************************************************************************/ +boolean +bdd_leq(f, g, f_phase, g_phase) +bdd_t *f; +bdd_t *g; +boolean f_phase; +boolean g_phase; +{ + DdNode *newf, *newg; + + /* Make sure both operands belong to the same manager. */ + assert(f->mgr == g->mgr); + + if (f_phase) { + newf = f->node; + } else { + newf = Cudd_Not(f->node); + } + if (g_phase) { + newg = g->node; + } else { + newg = Cudd_Not(g->node); + } + + return(Cudd_bddLeq(f->mgr,newf,newg)); + +} /* end of bdd_leq */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms in the on set.] + + SideEffects [] + +******************************************************************************/ +double +bdd_count_onset(f, var_array) +bdd_t *f; +array_t *var_array; /* of bdd_t *'s */ +{ + return(Cudd_CountMinterm(f->mgr,f->node,array_n(var_array))); + +} /* end of bdd_count_onset */ + + +/**Function******************************************************************** + + Synopsis [Obtains the manager of the BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_manager * +bdd_get_manager(f) +bdd_t *f; +{ + return(f->mgr); + +} /* end of bdd_get_manager */ + + +/**Function******************************************************************** + + Synopsis [Returns the node of the BDD.] + + SideEffects [Sets is_complemented.] + +******************************************************************************/ +bdd_node * +bdd_get_node(f, is_complemented) +bdd_t *f; +boolean *is_complemented; /* return */ +{ + if (Cudd_IsComplement(f->node)) { + *is_complemented = TRUE; + return(Cudd_Regular(f->node)); + } + *is_complemented = FALSE; + return(f->node); + +} /* end of bdd_get_node */ + + +/**Function******************************************************************** + + Synopsis [Returns the free field of the BDD.] + + SideEffects [] + +******************************************************************************/ +int +bdd_get_free(f) +bdd_t *f; +{ + return (f->free); + +} /* end of bdd_get_free */ + + +/**Function******************************************************************** + + Synopsis [Obtains some statistics of the BDD package.] + + SideEffects [Sets stats.] + +******************************************************************************/ +/*ARGSUSED*/ +void +bdd_get_stats(mgr, stats) +bdd_manager *mgr; +bdd_stats *stats; /* return */ +{ + stats->nodes.total = mgr->keys; + stats->nodes.used = mgr->keys - mgr->dead; + stats->nodes.unused = mgr->dead; + stats->cache.itetable.hits = (unsigned int) Cudd_ReadCacheHits(mgr); + stats->cache.itetable.misses = (unsigned int) + (Cudd_ReadCacheLookUps(mgr) - Cudd_ReadCacheHits(mgr)); + stats->cache.itetable.collisions = mgr->cachecollisions; + stats->cache.itetable.inserts = mgr->cacheinserts; + stats->gc.times = Cudd_ReadGarbageCollections(mgr); + return; + +} /* end of bdd_get_stats */ + + +/**Function******************************************************************** + + Synopsis [Obtains the support of the BDD.] + + SideEffects [] + +******************************************************************************/ +var_set_t * +bdd_get_support(f) +bdd_t *f; +{ + DdNode *support, *scan; + var_set_t *result; + + support = Cudd_Support(f->mgr,f->node); + if (support == NULL) return(NULL); + cuddRef(support); + + result = var_set_new((int) f->mgr->size); + scan = support; + while (!cuddIsConstant(scan)) { + var_set_set_elt(result, scan->index); + scan = cuddT(scan); + } + Cudd_RecursiveDeref(f->mgr,support); + + return(result); + +} /* end of bdd_get_support */ + + +/**Function******************************************************************** + + Synopsis [Obtains the array of indices of an array of variables.] + + SideEffects [] + +******************************************************************************/ +array_t * +bdd_get_varids(var_array) +array_t *var_array; +{ + int i; + int index; + bdd_t *var; + array_t *result = array_alloc(int,array_n(var_array)); + + for (i = 0; i < array_n(var_array); i++) { + var = array_fetch(bdd_t *, var_array, i); + index = Cudd_Regular(var->node)->index; + (void) array_insert_last(int, result, index); + } + return(result); + +} /* end of bdd_get_varids */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of variables in the manager.] + + SideEffects [] + +******************************************************************************/ +unsigned int +bdd_num_vars(mgr) +bdd_manager *mgr; +{ + return(mgr->size); + +} /* end of bdd_num_vars */ + + +/**Function******************************************************************** + + Synopsis [Prints the BDD.] + + SideEffects [] + +******************************************************************************/ +void +bdd_print(f) +bdd_t *f; +{ + (void) cuddP(f->mgr,f->node); + +} /* end of bdd_print */ + + +/**Function******************************************************************** + + Synopsis [Prints statistics about the package.] + + SideEffects [] + +******************************************************************************/ +void +bdd_print_stats(stats, file) +bdd_stats stats; +FILE *file; +{ +#ifndef DD_STATS + fprintf(stderr,"CU DD package: bdd_print_stats: Statistics turned off. No output\n"); +#else + fprintf(file,"CU DD Package Statistics\n"); + fprintf(file," Cache hits : %d\n",stats.cache.itetable.hits); + fprintf(file," Cache misses : %d\n",stats.cache.itetable.misses); + fprintf(file," Cache collisions : %d\n",stats.cache.itetable.collisions); + fprintf(file," Cache inserts: %d\n",stats.cache.itetable.inserts); +#endif + return; + +} /* end of bdd_print_stats */ + + +/**Function******************************************************************** + + Synopsis [Computes the number of nodes of a BDD.] + + SideEffects [] + +******************************************************************************/ +int +bdd_size(f) +bdd_t *f; +{ + return(Cudd_DagSize(f->node)); + +} /* end of bdd_size */ + + +/**Function******************************************************************** + + Synopsis [Accesses the id of the top variable.] + + SideEffects [] + +******************************************************************************/ +bdd_variableId +bdd_top_var_id(f) +bdd_t *f; +{ + return(Cudd_Regular(f->node)->index); + +} /* end of bdd_top_var_id */ + + +/**Function******************************************************************** + + Synopsis [Accesses the external_hooks field of the manager.] + + SideEffects [] + +******************************************************************************/ +bdd_external_hooks * +bdd_get_external_hooks(mgr) +bdd_manager *mgr; +{ + return((bdd_external_hooks *)(mgr->hooks)); + +} /* end of bdd_get_external_hooks */ + + +/**Function******************************************************************** + + Synopsis [Registers a new hook with the manager.] + + SideEffects [] + +******************************************************************************/ +/*ARGSUSED*/ +void +bdd_register_daemon(mgr, daemon) +bdd_manager *mgr; +void (*daemon)(); +{ + fprintf(stderr,"CU DD Package: bdd_register_daemon translated to no-op.\n"); + return; + +} /* end of bdd_register_daemon */ + + +/**Function******************************************************************** + + Synopsis [Turns on or off garbage collection.] + + SideEffects [] + +******************************************************************************/ +void +bdd_set_gc_mode(mgr, no_gc) +bdd_manager *mgr; +boolean no_gc; +{ + if (no_gc) { + Cudd_DisableGarbageCollection(mgr); + } else { + Cudd_EnableGarbageCollection(mgr); + } + return; + +} /* end of bdd_set_gc_mode */ + + +/**Function******************************************************************** + + Synopsis [Reorders the BDD pool.] + + SideEffects [] + +******************************************************************************/ +void +bdd_dynamic_reordering(mgr, algorithm_type) +bdd_manager *mgr; +bdd_reorder_type_t algorithm_type; +{ + switch (algorithm_type) { + case BDD_REORDER_SIFT: + mgr->autoMethod = CUDD_REORDER_SIFT; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW: + case BDD_REORDER_WINDOW4: + mgr->autoMethod = CUDD_REORDER_WINDOW4; + mgr->autoDyn = 1; + break; + case BDD_REORDER_NONE: + mgr->autoDyn = 0; + break; + case BDD_REORDER_SAME: + mgr->autoDyn = 1; + break; + case BDD_REORDER_RANDOM: + mgr->autoMethod = CUDD_REORDER_RANDOM; + mgr->autoDyn = 1; + break; + case BDD_REORDER_RANDOM_PIVOT: + mgr->autoMethod = CUDD_REORDER_RANDOM_PIVOT; + mgr->autoDyn = 1; + break; + case BDD_REORDER_SIFT_CONVERGE: + mgr->autoMethod = CUDD_REORDER_SIFT_CONVERGE; + mgr->autoDyn = 1; + break; + case BDD_REORDER_SYMM_SIFT: + mgr->autoMethod = CUDD_REORDER_SYMM_SIFT; + mgr->autoDyn = 1; + break; + case BDD_REORDER_SYMM_SIFT_CONV: + mgr->autoMethod = CUDD_REORDER_SYMM_SIFT_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW2: + mgr->autoMethod = CUDD_REORDER_WINDOW2; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW3: + mgr->autoMethod = CUDD_REORDER_WINDOW3; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW2_CONV: + mgr->autoMethod = CUDD_REORDER_WINDOW2_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW3_CONV: + mgr->autoMethod = CUDD_REORDER_WINDOW3_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_WINDOW4_CONV: + mgr->autoMethod = CUDD_REORDER_WINDOW4_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_GROUP_SIFT: + mgr->autoMethod = CUDD_REORDER_GROUP_SIFT; + mgr->autoDyn = 1; + break; + case BDD_REORDER_GROUP_SIFT_CONV: + mgr->autoMethod = CUDD_REORDER_GROUP_SIFT_CONV; + mgr->autoDyn = 1; + break; + case BDD_REORDER_ANNEALING: + mgr->autoMethod = CUDD_REORDER_ANNEALING; + mgr->autoDyn = 1; + break; + case BDD_REORDER_GENETIC: + mgr->autoMethod = CUDD_REORDER_GENETIC; + mgr->autoDyn = 1; + break; + default: + fprintf(stderr,"CU DD Package: Reordering algorithm not considered\n"); + } + +} /* end of bdd_dynamic_reordering */ + + +/**Function******************************************************************** + + Synopsis [Calls reordering explicitly.] + + SideEffects [] + +******************************************************************************/ +void +bdd_reorder(mgr) +bdd_manager *mgr; +{ + (void) Cudd_ReduceHeap(mgr,mgr->autoMethod,10); /* 10 = whatever (Verbatim from file ddTable.c) */ + return; + +} /* end of bdd_reorder */ + + +/**Function******************************************************************** + + Synopsis [Read the number of reorderings the package has performed + so far.] + + SideEffects [] + +******************************************************************************/ +int +bdd_read_reorderings(mgr) +bdd_manager *mgr; +{ + return Cudd_ReadReorderings((DdManager *)mgr); + +} /* end of bdd_read_reorderings */ + + +/**Function******************************************************************** + + Synopsis [Gets the id variable for one level in the BDD.] + + SideEffects [] + +******************************************************************************/ +bdd_variableId +bdd_get_id_from_level(mgr, level) +bdd_manager *mgr; +long level; +{ + return(mgr->invperm[level]); + +} /* end of bdd_get_id_from_level */ + + +/**Function******************************************************************** + + Synopsis [Gets the level of the top variable of the BDD.] + + SideEffects [] + +******************************************************************************/ +long +bdd_top_var_level(mgr, fn) +bdd_manager *mgr; +bdd_t *fn; +{ + return((long) cuddI(mgr,Cudd_Regular(fn->node)->index)); + +} /* end of bdd_top_var_level */ + + +/**Function******************************************************************** + + Synopsis [Returns TRUE if the argument BDD is a cube; FALSE + otherwise.] + + SideEffects [] + +******************************************************************************/ +boolean +bdd_is_cube(f) +bdd_t *f; +{ + struct DdManager *manager; + + if (f == NULL) { + fail("bdd_is_cube: invalid BDD"); + } + if (f->free) fail ("Freed BDD passed to bdd_is_cube"); + manager = (DdManager *) f->mgr; + return((boolean)cuddCheckCube(manager,f->node)); + +} /* end of bdd_is_cube */ + + +/**Function******************************************************************** + + Synopsis [Calls the garbage collector explicitly.] + + SideEffects [] + +******************************************************************************/ +void +bdd_gc(mgr) +bdd_manager *mgr; +{ + cuddGarbageCollect(mgr,1); + +} /* end of bdd_gc */ + + +/**Function******************************************************************** + + Synopsis [Computes the shared size of an array of BDDs.] + + Description [Computes the shared size of an array of BDDs. Returns + CUDD_OUT_OF_MEM in case of failure.] + + SideEffects [] + +******************************************************************************/ +long +bdd_size_multiple(bddArray) +array_t *bddArray; +{ + DdNode **nodeArray; + bdd_t *bddUnit; + long result; + int i; + + nodeArray = ALLOC(DdNode *, array_n(bddArray)); + if (nodeArray == NULL) return(CUDD_OUT_OF_MEM); + for (i = 0; i < array_n(bddArray); i++) { + bddUnit = array_fetch(bdd_t *, bddArray, i); + nodeArray[i] = bddUnit->node; + } + + result = Cudd_SharingSize(nodeArray,array_n(bddArray)); + + /* Clean up */ + FREE(nodeArray); + + return(result); + +} /* end of bdd_size_multiple */ + + +/**Function******************************************************************** + + Synopsis [Returns the first cube of the function. + A generator is also returned, which will iterate over the rest.] + + Description [Defines an iterator on the onset of a BDD. Two routines + are provided: bdd_first_cube, which extracts one cube from a BDD and + returns a bdd_gen structure containing the information necessary to + continue the enumeration; and bdd_next_cube, which returns 1 if + another cube was found, and 0 otherwise. A cube is represented as an + array of bdd_literal (which are integers in {0, 1, 2}), where 0 + represents negated literal, 1 for literal, and 2 for don't care. + Returns a disjoint cover. A third routine is there to clean up.] + + SideEffects [] + + SeeAlso [bdd_next_cube bdd_gen_free] + +******************************************************************************/ +bdd_gen * +bdd_first_cube(fn, cube) +bdd_t *fn; +array_t **cube; /* of bdd_literal */ +{ + bdd_manager *manager; + bdd_gen *gen; + int i; + int *icube; + CUDD_VALUE_TYPE value; + + /* Make sure we receive a valid bdd_t. (So to speak.) */ + assert(fn != 0); + + manager = fn->mgr; + + /* Initialize the generator. */ + gen = ALLOC(bdd_gen,1); + if (gen == NULL) return(NULL); + gen->manager = manager; + + gen->cube = array_alloc(bdd_literal, manager->size); + if (gen->cube == NULL) { + fail("Bdd Package: Out of memory in bdd_first_cube"); + } + + gen->ddGen = Cudd_FirstCube(manager,fn->node,&icube,&value); + if (gen->ddGen == NULL) { + fail("Cudd Package: Out of memory in bdd_first_cube"); + } + + if (!Cudd_IsGenEmpty(gen->ddGen)) { + /* Copy icube to the array_t cube. */ + for (i = 0; i < manager->size; i++) { + int myconst = icube[i]; + array_insert(bdd_literal, gen->cube, i, myconst); + } + *cube = gen->cube; + } + + return(gen); + +} /* end of bdd_first_cube */ + + +/**Function******************************************************************** + + Synopsis [Gets the next cube on the generator. Returns {TRUE, + FALSE} when {more, no more}.] + + SideEffects [] + + SeeAlso [bdd_first_cube bdd_gen_free] + +******************************************************************************/ +boolean +bdd_next_cube(gen, cube) +bdd_gen *gen; +array_t **cube; /* of bdd_literal */ +{ + int retval; + int *icube; + CUDD_VALUE_TYPE value; + int i; + + retval = Cudd_NextCube(gen->ddGen,&icube,&value); + if (!Cudd_IsGenEmpty(gen->ddGen)) { + /* Copy icube to the array_t cube. */ + for (i = 0; i < gen->manager->size; i++) { + int myconst = icube[i]; + array_insert(bdd_literal, gen->cube, i, myconst); + } + *cube = gen->cube; + } + + return(retval); + +} /* end of bdd_next_cube */ + + +/**Function******************************************************************** + + Synopsis [Gets the first node in the BDD and returns a generator.] + + SideEffects [] + + SeeAlso [bdd_next_node] + +******************************************************************************/ +bdd_gen * +bdd_first_node(fn, node) +bdd_t *fn; +bdd_node **node; /* return */ +{ + bdd_manager *manager; + bdd_gen *gen; + + /* Make sure we receive a valid bdd_t. (So to speak.) */ + assert(fn != 0); + + manager = fn->mgr; + + /* Initialize the generator. */ + gen = ALLOC(bdd_gen,1); + if (gen == NULL) return(NULL); + gen->manager = manager; + gen->cube = NULL; + + gen->ddGen = Cudd_FirstNode(manager,fn->node,node); + if (gen->ddGen == NULL) { + fail("Cudd Package: Out of memory in bdd_first_node"); + } + + return(gen); + +} /* end of bdd_first_node */ + + +/**Function******************************************************************** + + Synopsis [Gets the next node in the BDD. Returns {TRUE, FALSE} when + {more, no more}.] + + SideEffects [] + + SeeAlso [bdd_first_node] + +******************************************************************************/ +boolean +bdd_next_node(gen, node) +bdd_gen *gen; +bdd_node **node; /* return */ +{ + return(Cudd_NextNode(gen->ddGen,node)); + +} /* end of bdd_next_node */ + + +/**Function******************************************************************** + + Synopsis [Frees up the space used by the generator. Returns an int + so that it is easier to fit in a foreach macro. Returns 0 (to make it + easy to put in expressions).] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +bdd_gen_free(gen) +bdd_gen *gen; +{ + if (gen->cube != NULL) array_free(gen->cube); + Cudd_GenFree(gen->ddGen); + FREE(gen); + return(0); + +} /* end of bdd_gen_free */ + + +/**Function******************************************************************** + + Synopsis [Queries the status of a generator.] + + Description [Queries the status of a generator. Returns 1 if the + generator is empty or NULL; 0 otherswise.] + + SideEffects [] + + SeeAlso [bdd_first_cube bdd_next_cube bdd_first_node bdd_next_node + bdd_gen_free] + +******************************************************************************/ +boolean +bdd_is_gen_empty(gen) +bdd_gen *gen; +{ + return(Cudd_IsGenEmpty(gen->ddGen)); + +} /* end of bdd_is_gen_empty */ + + +/**Function******************************************************************** + + Synopsis [Function that creates a variable of a given index.] + + SideEffects [] + +******************************************************************************/ +bdd_t * +bdd_var_with_index(manager, index) +bdd_manager *manager; +int index; +{ + DdNode *var; + + var = Cudd_bddIthVar(manager, index); + cuddRef(var); + return(bdd_construct_bdd_t(manager, var)); + +} /* end of bdd_var_with_index */ + + +/**Function******************************************************************** + + Synopsis [Temporary function that is empty.] + + SideEffects [] + +******************************************************************************/ +/*ARGSUSED*/ +void +bdd_new_var_block(f, n) +bdd_t *f; +long n; +{ + return; + +} /* end of bdd_new_var_block */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Builds the bdd_t structure.] + + Description [Builds the bdd_t structure from manager and node. + Assumes that the reference count of the node has already been + increased.] + + SideEffects [] + +******************************************************************************/ +static bdd_t * +bdd_construct_bdd_t(mgr,fn) +DdManager *mgr; +DdNode * fn; +{ + bdd_t *result; + + result = ALLOC(bdd_t, 1); + if (result == NULL) { + Cudd_RecursiveDeref(mgr,fn); + return(NULL); + } + result->mgr = mgr; + result->node = fn; + result->free = FALSE; + return(result); + +} /* end of bdd_construct_bdd_t */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/cuddPwPt.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/cuddPwPt.c new file mode 100644 index 000000000..823f7b966 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/cuddPwPt.c @@ -0,0 +1,147 @@ +/**CFile*********************************************************************** + + FileName [cuddPwPt.c] + + PackageName [cudd] + + Synopsis [Emulation functions for the power package in SIS.] + + Description [This file contains functions that are necessary for the + power package in SIS. This package directly calls a few functions of + the CMU BDD package. Therefore, functions with identical names and + equivalent functionality are provided here. + External procedures included in this file: +
                            +
                          • cmu_bdd_zero() +
                          • cmu_bdd_one() +
                          • cmu_bdd_if_index() +
                          + Internal procedures included in this module: +
                            +
                          • +
                          ] + + Author [Fabio Somenzi] + + Copyright [This file was created at the University of Colorado at + Boulder. The University of Colorado at Boulder makes no warranty + about the suitability of this software for any purpose. It is + presented on an AS IS basis.] + +******************************************************************************/ + +#include "util.h" +#include "array.h" +#include "st.h" +#include "cuddInt.h" +#include "cuddBdd.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddPwPt.c,v 1.3 1997/01/18 19:43:19 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Returns a pointer to the one constant.] + + Description [Returns a pointer to the one constant. Used by the power + package in SIS. For new code, use Cudd_ReadOne instead.] + + SideEffects [None] + + SeeAlso [Cudd_ReadOne] + +******************************************************************************/ +bdd_node * +cmu_bdd_one(dd) +bdd_manager *dd; +{ + return((bdd_node *)((DdManager *)dd)->one); + +} /* end of cmu_bdd_one */ + + +/**Function******************************************************************** + + Synopsis [Returns a pointer to the zero constant.] + + Description [Returns a pointer to the zero constant. Used by the power + package in SIS. For new code, use Cudd_ReadZero instead.] + + SideEffects [None] + + SeeAlso [Cudd_ReadZero] + +******************************************************************************/ +bdd_node * +cmu_bdd_zero(dd) +bdd_manager *dd; +{ + return((bdd_node *)Cudd_Not(((DdManager *)dd)->one)); + +} /* end of cmu_bdd_zero */ + + +/**Function******************************************************************** + + Synopsis [Returns the index of the top variable in a BDD.] + + Description [Returns the index of the top variable in a BDD. Used by + the power package in SIS. For new code, use Cudd_ReadIndex instead.] + + SideEffects [None] + + SeeAlso [Cudd_ReadIndex] + +******************************************************************************/ +int +cmu_bdd_if_index(dd, node) +bdd_manager *dd; +bdd_node *node; +{ + return(Cudd_Regular(node)->index); + +} /* end of cmu_bdd_if_index */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/st.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/st.c new file mode 100644 index 000000000..426c79c5a --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/st.c @@ -0,0 +1,554 @@ +/* + * Revision Control Information + * + * /projects/hsis/CVS/utilities/st/st.c,v + * serdar + * 1.1 + * 1993/07/29 01:00:13 + * + */ +#include +#include "util.h" +#include "st.h" + +#define ST_NUMCMP(x,y) ((x) != (y)) +#define ST_NUMHASH(x,size) (ABS((long)x)%(size)) +#define ST_PTRHASH(x,size) ((int)((unsigned long)(x)>>2)%size) +#define EQUAL(func, x, y) \ + ((((func) == st_numcmp) || ((func) == st_ptrcmp)) ?\ + (ST_NUMCMP((x),(y)) == 0) : ((*func)((x), (y)) == 0)) + + +#define do_hash(key, table)\ + ((int)((table->hash == st_ptrhash) ? ST_PTRHASH((key),(table)->num_bins) :\ + (table->hash == st_numhash) ? ST_NUMHASH((key), (table)->num_bins) :\ + (*table->hash)((key), (table)->num_bins))) + +static int rehash (st_table *); + +st_table * +st_init_table_with_params( + ST_PFICPCP compare, + ST_PFICPI hash, + int size, + int density, + double grow_factor, + int reorder_flag) +{ + int i; + st_table *newt; + + newt = ALLOC(st_table, 1); + if (newt == NIL(st_table)) { + return NIL(st_table); + } + newt->compare = (int (*)(const char *, const char *)) compare; + newt->hash = (int (*)(char *, int)) hash; + newt->num_entries = 0; + newt->max_density = density; + newt->grow_factor = grow_factor; + newt->reorder_flag = reorder_flag; + if (size <= 0) { + size = 1; + } + newt->num_bins = size; + newt->bins = ALLOC(st_table_entry *, size); + if (newt->bins == NIL(st_table_entry *)) { + FREE(newt); + return NIL(st_table); + } + for(i = 0; i < size; i++) { + newt->bins[i] = 0; + } + return newt; +} + +st_table * +st_init_table(ST_PFICPCP compare, ST_PFICPI hash) +{ + return st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE, + ST_DEFAULT_MAX_DENSITY, + ST_DEFAULT_GROW_FACTOR, + ST_DEFAULT_REORDER_FLAG); +} + +void +st_free_table(st_table *table) +{ + register st_table_entry *ptr, *next; + int i; + + for(i = 0; i < table->num_bins ; i++) { + ptr = table->bins[i]; + while (ptr != NIL(st_table_entry)) { + next = ptr->next; + FREE(ptr); + ptr = next; + } + } + FREE(table->bins); + FREE(table); +} + +#define PTR_NOT_EQUAL(table, ptr, user_key)\ +(ptr != NULL && !EQUAL(table->compare, user_key, (ptr)->key)) + +#define FIND_ENTRY(table, hash_val, key, ptr, last) \ + (last) = &(table)->bins[hash_val];\ + (ptr) = *(last);\ + while (PTR_NOT_EQUAL((table), (ptr), (key))) {\ + (last) = &(ptr)->next; (ptr) = *(last);\ + }\ + if ((ptr) != NULL && (table)->reorder_flag) {\ + *(last) = (ptr)->next;\ + (ptr)->next = (table)->bins[hash_val];\ + (table)->bins[hash_val] = (ptr);\ + } + +int +st_lookup(st_table *table, char *key, char **value) +{ + int hash_val; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (value != NIL(char *)) { + *value = ptr->record; + } + return 1; + } +} + +int +st_lookup_int(st_table *table, char *key, int *value) +{ + int hash_val; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (value != NIL(int)) { + *value = (int) (util_ptrint) ptr->record; + } + return 1; + } +} + +/* This macro does not check if memory allocation fails. Use at you own risk */ +#define ADD_DIRECT(table, key, value, hash_val, newt)\ +{\ + if (table->num_entries/table->num_bins >= table->max_density) {\ + rehash(table);\ + hash_val = do_hash(key,table);\ + }\ + \ + newt = ALLOC(st_table_entry, 1);\ + \ + newt->key = key;\ + newt->record = value;\ + newt->next = table->bins[hash_val];\ + table->bins[hash_val] = newt;\ + table->num_entries++;\ +} + +int +st_insert(st_table *table, char *key, char *value) +{ + int hash_val; + st_table_entry *newt; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + if (table->num_entries/table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + hash_val = do_hash(key, table); + } + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = key; + newt->record = value; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + return 0; + } else { + ptr->record = value; + return 1; + } +} + +int +st_add_direct(st_table *table, char *key, char *value) +{ + int hash_val; + st_table_entry *newt; + + hash_val = do_hash(key, table); + if (table->num_entries / table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + } + hash_val = do_hash(key, table); + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = key; + newt->record = value; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + return 1; +} + +int +st_find_or_add(st_table *table, char *key, char ***slot) +{ + int hash_val; + st_table_entry *newt, *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + if (table->num_entries / table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + hash_val = do_hash(key, table); + } + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = key; + newt->record = (char *) 0; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + if (slot != NIL(char **)) *slot = &newt->record; + return 0; + } else { + if (slot != NIL(char **)) *slot = &ptr->record; + return 1; + } +} + +int +st_find(st_table *table, char *key, char ***slot) +{ + int hash_val; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (slot != NIL(char **)) { + *slot = &ptr->record; + } + return 1; + } +} + +static int +rehash(st_table *table) +{ + register st_table_entry *ptr, *next, **old_bins; + int i, old_num_bins, hash_val, old_num_entries; + + /* save old values */ + old_bins = table->bins; + old_num_bins = table->num_bins; + old_num_entries = table->num_entries; + + /* rehash */ + table->num_bins = (int) (table->grow_factor * old_num_bins); + if (table->num_bins % 2 == 0) { + table->num_bins += 1; + } + table->num_entries = 0; + table->bins = ALLOC(st_table_entry *, table->num_bins); + if (table->bins == NIL(st_table_entry *)) { + table->bins = old_bins; + table->num_bins = old_num_bins; + table->num_entries = old_num_entries; + return ST_OUT_OF_MEM; + } + /* initialize */ + for (i = 0; i < table->num_bins; i++) { + table->bins[i] = 0; + } + + /* copy data over */ + for (i = 0; i < old_num_bins; i++) { + ptr = old_bins[i]; + while (ptr != NIL(st_table_entry)) { + next = ptr->next; + hash_val = do_hash(ptr->key, table); + ptr->next = table->bins[hash_val]; + table->bins[hash_val] = ptr; + table->num_entries++; + ptr = next; + } + } + FREE(old_bins); + + return 1; +} + +st_table * +st_copy(st_table *old_table) +{ + st_table *new_table; + st_table_entry *ptr, *newptr, *next, *newt; + int i, j, num_bins = old_table->num_bins; + + new_table = ALLOC(st_table, 1); + if (new_table == NIL(st_table)) { + return NIL(st_table); + } + + *new_table = *old_table; + new_table->bins = ALLOC(st_table_entry *, num_bins); + if (new_table->bins == NIL(st_table_entry *)) { + FREE(new_table); + return NIL(st_table); + } + for(i = 0; i < num_bins ; i++) { + new_table->bins[i] = NIL(st_table_entry); + ptr = old_table->bins[i]; + while (ptr != NIL(st_table_entry)) { + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + for (j = 0; j <= i; j++) { + newptr = new_table->bins[j]; + while (newptr != NIL(st_table_entry)) { + next = newptr->next; + FREE(newptr); + newptr = next; + } + } + FREE(new_table->bins); + FREE(new_table); + return NIL(st_table); + } + *newt = *ptr; + newt->next = new_table->bins[i]; + new_table->bins[i] = newt; + ptr = ptr->next; + } + } + return new_table; +} + +int +st_delete(st_table *table, char **keyp, char **value) +{ + int hash_val; + char *key = *keyp; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr ,last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } + + *last = ptr->next; + if (value != NIL(char *)) *value = ptr->record; + *keyp = ptr->key; + FREE(ptr); + table->num_entries--; + return 1; +} + +int +st_delete_int(st_table *table, int *keyp, char **value) +{ + int hash_val; + char *key = (char *) (util_ptrint) *keyp; + register st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr ,last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } + + *last = ptr->next; + if (value != NIL(char *)) *value = ptr->record; + *keyp = (int) (util_ptrint) ptr->key; + FREE(ptr); + table->num_entries--; + return 1; +} + +int +st_foreach(st_table *table, ST_PFSR func, char *arg) +{ + st_table_entry *ptr, **last; + enum st_retval retval; + int i; + + for(i = 0; i < table->num_bins; i++) { + last = &table->bins[i]; ptr = *last; + while (ptr != NIL(st_table_entry)) { + retval = (*func)(ptr->key, ptr->record, arg); + switch (retval) { + case ST_CONTINUE: + last = &ptr->next; ptr = *last; + break; + case ST_STOP: + return 0; + case ST_DELETE: + *last = ptr->next; + table->num_entries--; /* cstevens@ic */ + FREE(ptr); + ptr = *last; + } + } + } + return 1; +} + +int +st_strhash(char *string, int modulus) +{ + register int val = 0; + register int c; + + while ((c = *string++) != '\0') { + val = val*997 + c; + } + + return ((val < 0) ? -val : val)%modulus; +} + +int +st_numhash(char *x, int size) +{ + return ST_NUMHASH(x, size); +} + +int +st_ptrhash(char *x, int size) +{ + return ST_PTRHASH(x, size); +} + +int +st_numcmp(const char *x, const char *y) +{ + return ST_NUMCMP(x, y); +} + +int +st_ptrcmp(const char *x, const char *y) +{ + return ST_NUMCMP(x, y); +} + +st_generator * +st_init_gen(st_table *table) +{ + st_generator *gen; + + gen = ALLOC(st_generator, 1); + if (gen == NIL(st_generator)) { + return NIL(st_generator); + } + gen->table = table; + gen->entry = NIL(st_table_entry); + gen->index = 0; + return gen; +} + + +int +st_gen(st_generator *gen, char **key_p, char **value_p) +{ + register int i; + + if (gen->entry == NIL(st_table_entry)) { + /* try to find next entry */ + for(i = gen->index; i < gen->table->num_bins; i++) { + if (gen->table->bins[i] != NIL(st_table_entry)) { + gen->index = i+1; + gen->entry = gen->table->bins[i]; + break; + } + } + if (gen->entry == NIL(st_table_entry)) { + return 0; /* that's all folks ! */ + } + } + *key_p = gen->entry->key; + if (value_p != 0) { + *value_p = gen->entry->record; + } + gen->entry = gen->entry->next; + return 1; +} + + +int +st_gen_int(st_generator *gen, char **key_p, long *value_p) +{ + register int i; + + if (gen->entry == NIL(st_table_entry)) { + /* try to find next entry */ + for(i = gen->index; i < gen->table->num_bins; i++) { + if (gen->table->bins[i] != NIL(st_table_entry)) { + gen->index = i+1; + gen->entry = gen->table->bins[i]; + break; + } + } + if (gen->entry == NIL(st_table_entry)) { + return 0; /* that's all folks ! */ + } + } + *key_p = gen->entry->key; + if (value_p != NIL(long)) { + *value_p = (long) gen->entry->record; + } + gen->entry = gen->entry->next; + return 1; +} + + +void +st_free_gen(st_generator *gen) +{ + FREE(gen); +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/st.h b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/st.h new file mode 100644 index 000000000..a1d86192e --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/sis/st.h @@ -0,0 +1,97 @@ +/* + * Revision Control Information + * + * /projects/hsis/CVS/utilities/st/st.h,v + * serdar + * 1.1 + * 1993/07/29 01:00:21 + * + */ +/* LINTLIBRARY */ + +/* /projects/hsis/CVS/utilities/st/st.h,v 1.1 1993/07/29 01:00:21 serdar Exp */ + +#ifndef ST_INCLUDED +#define ST_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct st_table_entry st_table_entry; +struct st_table_entry { + char *key; + char *record; + st_table_entry *next; +}; + +typedef struct st_table st_table; +struct st_table { + int (*compare)(const char *, const char *); + int (*hash)(char *, int); + int num_bins; + int num_entries; + int max_density; + int reorder_flag; + double grow_factor; + st_table_entry **bins; +}; + +typedef struct st_generator st_generator; +struct st_generator { + st_table *table; + st_table_entry *entry; + int index; +}; + +#define st_is_member(table,key) st_lookup(table,key,(char **) 0) +#define st_count(table) ((table)->num_entries) + +enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE}; + +typedef enum st_retval (*ST_PFSR)(char *, char *, char *); +typedef int (*ST_PFICPCP)(const char *, const char *); /* type for comparison function */ +typedef int (*ST_PFICPI)(char *, int); /* type for hash function */ + +extern st_table *st_init_table_with_params (ST_PFICPCP, ST_PFICPI, int, int, double, int); +extern st_table *st_init_table (ST_PFICPCP, ST_PFICPI); +extern void st_free_table (st_table *); +extern int st_lookup (st_table *, char *, char **); +extern int st_lookup_int (st_table *, char *, int *); +extern int st_insert (st_table *, char *, char *); +extern int st_add_direct (st_table *, char *, char *); +extern int st_find_or_add (st_table *, char *, char ***); +extern int st_find (st_table *, char *, char ***); +extern st_table *st_copy (st_table *); +extern int st_delete (st_table *, char **, char **); +extern int st_delete_int (st_table *, int *, char **); +extern int st_foreach (st_table *, ST_PFSR, char *); +extern int st_strhash (char *, int); +extern int st_numhash (char *, int); +extern int st_ptrhash (char *, int); +extern int st_numcmp (const char *, const char *); +extern int st_ptrcmp (const char *, const char *); +extern st_generator *st_init_gen (st_table *); +extern int st_gen (st_generator *, char **, char **); +extern int st_gen_int (st_generator *, char **, long *); +extern void st_free_gen (st_generator *); + + +#define ST_DEFAULT_MAX_DENSITY 5 +#define ST_DEFAULT_INIT_TABLE_SIZE 11 +#define ST_DEFAULT_GROW_FACTOR 2.0 +#define ST_DEFAULT_REORDER_FLAG 0 + +#define st_foreach_item(table, gen, key, value) \ + for(gen=st_init_gen(table); st_gen(gen,key,value) || (st_free_gen(gen),0);) + +#define st_foreach_item_int(table, gen, key, value) \ + for(gen=st_init_gen(table); st_gen_int(gen,key,value) || (st_free_gen(gen),0);) + +#define ST_OUT_OF_MEM -10000 + +#ifdef __cplusplus +} +#endif + +#endif /* ST_INCLUDED */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/Makefile b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/Makefile new file mode 100644 index 000000000..5fdc949c6 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/Makefile @@ -0,0 +1,64 @@ +# $Id: Makefile,v 1.3 2004/01/01 06:53:06 fabio Exp fabio $ +# +# st -- hash table package +#--------------------------------------------------------------------------- +.SUFFIXES: .c .o .u + +CC = gcc +RANLIB = ranlib + +MFLAG = +ICFLAGS = -g -O6 -Wall +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) + +LINTFLAGS = -u -n + +# this is to create the lint library +LINTSWITCH = -o + +P = st +PSRC = st.c +PHDR = st.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) + +WHERE = .. +INCLUDE = $(WHERE)/include + +#--------------------------- + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +clean: + rm -f *.o *.u .pure *.warnings + +distclean: clean + rm -f lib*.a lib$(P).b llib-l$(P).ln tags *~ *.bak *.qv *.qx diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stAllAbs.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stAllAbs.html new file mode 100644 index 000000000..927c116bc --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stAllAbs.html @@ -0,0 +1,96 @@ + +st package abstract (Internal) + + +

                          st package abstract (Internal)

                          +

                          +
                          + + + +
                          +
                          st_add_direct() +
                          Place 'value' in 'table' under the key 'key'. + +
                          st_copy() +
                          Return a copy of old_table and all its members. + +
                          st_count() +
                          Returns the number of entries in the table `table'. + +
                          st_delete_int() +
                          Delete the entry with the key pointed to by `keyp'. + +
                          st_delete() +
                          Delete the entry with the key pointed to by `keyp'. + +
                          st_find_or_add() +
                          Lookup `key' in `table'. + +
                          st_find() +
                          Lookup `key' in `table'. + +
                          st_foreach_item_int() +
                          Iteration macro. + +
                          st_foreach_item() +
                          Iteration macro. + +
                          st_foreach() +
                          Iterates over the elements of a table. + +
                          st_free_gen() +
                          Reclaims the resources associated with `gen'. + +
                          st_free_table() +
                          Free a table. + +
                          st_gen_int() +
                          Returns the next (key, value) pair in the generation sequence. + +
                          st_gen() +
                          returns the next (key, value) pair in the generation sequence. + +
                          st_init_gen() +
                          Initializes a generator. + +
                          st_init_table_with_params() +
                          Create a table with given parameters. + +
                          st_init_table() +
                          Create and initialize a table. + +
                          st_insert() +
                          Insert value in table under the key 'key'. + +
                          st_is_member() +
                          Checks whethere `key' is in `table'. + +
                          st_lookup_int() +
                          Lookup up `key' in `table'. + +
                          st_lookup() +
                          Lookup up `key' in `table'. + +
                          st_numcmp() +
                          Number comparison function. + +
                          st_numhash() +
                          Number hash function. + +
                          st_ptrcmp() +
                          Pointer comparison function. + +
                          st_ptrhash() +
                          Pointer hash function. + +
                          st_strhash() +
                          String hash function. + +
                          + +
                          + +Generated automatically by extdoc on 20040102 + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stAllDet.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stAllDet.html new file mode 100644 index 000000000..e56d8834d --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stAllDet.html @@ -0,0 +1,462 @@ + +The st package (Internal) + + +

                          The st package (Internal)

                          +

                          +

                          +
                          + + +
                          + + + + + +
                          + + +
                          + +
                          +int 
                          +st_add_direct(
                          +  st_table * table, 
                          +  void * key, 
                          +  void * value 
                          +)
                          +
                          +
                          Place 'value' in 'table' under the key 'key'. This is done without checking if 'key' is in 'table' already. This should only be used if you are sure there is not already an entry for 'key', since it is undefined which entry you would later get from st_lookup or st_find_or_add. Returns 1 if successful; ST_OUT_OF_MEM otherwise. +

                          + +

                          Side Effects None +

                          + +

                          +st_table * 
                          +st_copy(
                          +  st_table * old_table 
                          +)
                          +
                          +
                          Return a copy of old_table and all its members. (st_table *) 0 is returned if there was insufficient memory to do the copy. +

                          + +

                          Side Effects None +

                          + +

                          + 
                          +st_count(
                          +   table 
                          +)
                          +
                          +
                          Returns the number of entries in the table `table'. +

                          + +

                          Side Effects None +

                          + +

                          +int 
                          +st_delete_int(
                          +  st_table * table, 
                          +  void * keyp, 
                          +  int * value 
                          +)
                          +
                          +
                          Delete the entry with the key pointed to by `keyp'. `value' must be a pointer to an integer. If the entry is found, 1 is returned, the variable pointed by `keyp' is set to the actual key and the variable pointed by `value' is set to the corresponding entry. (This allows the freeing of the associated storage.) If the entry is not found, then 0 is returned and nothing is changed. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_delete + + +
                          +int 
                          +st_delete(
                          +  st_table * table, 
                          +  void * keyp, 
                          +  void * value 
                          +)
                          +
                          +
                          Delete the entry with the key pointed to by `keyp'. If the entry is found, 1 is returned, the variable pointed by `keyp' is set to the actual key and the variable pointed by `value' is set to the corresponding entry. (This allows the freeing of the associated storage.) If the entry is not found, then 0 is returned and nothing is changed. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_delete_int + + +
                          +int 
                          +st_find_or_add(
                          +  st_table * table, 
                          +  void * key, 
                          +  void * slot 
                          +)
                          +
                          +
                          Lookup `key' in `table'. If not found, create an entry. In either case set slot to point to the field in the entry where the value is stored. The value associated with `key' may then be changed by accessing directly through slot. Returns 1 if an entry already existed, 0 if it did not exist and creation was successful; ST_OUT_OF_MEM otherwise. As an example:
                           char **slot; 
                           char *key; 
                           char *value = (char *) item_ptr <-- ptr to a malloc'd structure 
                           if (st_find_or_add(table, key, &slot) == 1) { 
                           FREE(*slot); <-- free the old value of the record 
                           } 
                           *slot = value; <-- attach the new value to the record 
                          This replaces the equivelent code:
                           if (st_lookup(table, key, &ovalue) == 1) { 
                           FREE(ovalue); 
                           } 
                           st_insert(table, key, value); 
                          +

                          + +

                          Side Effects None +

                          + +

                          See Also st_find + + +
                          +int 
                          +st_find(
                          +  st_table * table, 
                          +  void * key, 
                          +  void * slot 
                          +)
                          +
                          +
                          Like st_find_or_add, but does not create an entry if one is not found. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_find_or_add + + +
                          + 
                          +st_foreach_item_int(
                          +   table, 
                          +   gen, 
                          +   key, 
                          +   value 
                          +)
                          +
                          +
                          An iteration macro which loops over all the entries in `table', setting `key' to point to the key and `value' to the associated value (if it is not nil). `value' is assumed to be a pointer to an integer. `gen' is a generator variable used internally. Sample usage:
                           char *key; 
                           int value; 
                           st_generator *gen; 
                           st_foreach_item_int(table, gen, &key, &value) { 
                           process_item(value); 
                           } 
                          +

                          + +

                          Side Effects None +

                          + +

                          See Also st_foreach_item +st_foreach + + +
                          + 
                          +st_foreach_item(
                          +   table, 
                          +   gen, 
                          +   key, 
                          +   value 
                          +)
                          +
                          +
                          An iteration macro which loops over all the entries in `table', setting `key' to point to the key and `value' to the associated value (if it is not nil). `gen' is a generator variable used internally. Sample usage:
                           char *key, *value; 
                           st_generator *gen; 
                           st_foreach_item(table, gen, &key, &value) { 
                           process_item(value); 
                           } 
                          +

                          + +

                          Side Effects None +

                          + +

                          See Also st_foreach_item_int +st_foreach + + +
                          +int 
                          +st_foreach(
                          +  st_table * table, 
                          +  ST_PFSR  func, 
                          +  char * arg 
                          +)
                          +
                          +
                          For each (key, value) record in `table', st_foreach call func with the arguments
                           (*func)(key, value, arg) 
                          If func returns ST_CONTINUE, st_foreach continues processing entries. If func returns ST_STOP, st_foreach stops processing and returns immediately. If func returns ST_DELETE, then the entry is deleted from the symbol table and st_foreach continues. In the case of ST_DELETE, it is func's responsibility to free the key and value, if necessary.

                          The routine returns 1 if all items in the table were generated and 0 if the generation sequence was aborted using ST_STOP. The order in which the records are visited will be seemingly random. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_foreach_item +st_foreach_item_int + + +
                          +void 
                          +st_free_gen(
                          +  st_generator * gen 
                          +)
                          +
                          +
                          After generating all items in a generation sequence, this routine must be called to reclaim the resources associated with `gen'. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_gen + + +
                          +void 
                          +st_free_table(
                          +  st_table * table 
                          +)
                          +
                          +
                          Any internal storage associated with table is freed. It is the user's responsibility to free any storage associated with the pointers he placed in the table (by perhaps using st_foreach). +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table +st_init_table_with_params + + +
                          +int 
                          +st_gen_int(
                          +  st_generator * gen, 
                          +  void * key_p, 
                          +  int * value_p 
                          +)
                          +
                          +
                          Given a generator returned by st_init_gen(), this routine returns the next (key, value) pair in the generation sequence. `value_p' must be a pointer to an integer. The pointer `value_p' can be zero which means no value will be returned. When there are no more items in the generation sequence, the routine returns 0. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_gen + + +
                          +int 
                          +st_gen(
                          +  st_generator * gen, 
                          +  void * key_p, 
                          +  void * value_p 
                          +)
                          +
                          +
                          Given a generator returned by st_init_gen(), this routine returns the next (key, value) pair in the generation sequence. The pointer `value_p' can be zero which means no value will be returned. When there are no more items in the generation sequence, the routine returns 0. While using a generation sequence, deleting any (key, value) pair other than the one just generated may cause a fatal error when st_gen() is called later in the sequence and is therefore not recommended. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_gen_int + + +
                          +st_generator * 
                          +st_init_gen(
                          +  st_table * table 
                          +)
                          +
                          +
                          Returns a generator handle which when used with st_gen() will progressively return each (key, value) record in `table'. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_free_gen + + +
                          +st_table * 
                          +st_init_table_with_params(
                          +  ST_PFICPCP  compare, 
                          +  ST_PFICPI  hash, 
                          +  int  size, 
                          +  int  density, 
                          +  double  grow_factor, 
                          +  int  reorder_flag 
                          +)
                          +
                          +
                          The full blown table initializer. compare and hash are the same as in st_init_table. density is the largest the average number of entries per hash bin there should be before the table is grown. grow_factor is the factor the table is grown by when it becomes too full. size is the initial number of bins to be allocated for the hash table. If reorder_flag is non-zero, then every time an entry is found, it is moved to the top of the chain.

                          st_init_table(compare, hash) is equivelent to

                           st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE, ST_DEFAULT_MAX_DENSITY, ST_DEFAULT_GROW_FACTOR, ST_DEFAULT_REORDER_FLAG); 
                          +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table +st_free_table + + +
                          +st_table * 
                          +st_init_table(
                          +  ST_PFICPCP  compare, 
                          +  ST_PFICPI  hash 
                          +)
                          +
                          +
                          Create and initialize a table with the comparison function compare_fn and hash function hash_fn. compare_fn is
                           int compare_fn(const char *key1, const char *key2) 
                          It returns <,=,> 0 depending on whether key1 <,=,> key2 by some measure.

                          hash_fn is

                           int hash_fn(char *key, int modulus) 
                          It returns a integer between 0 and modulus-1 such that if compare_fn(key1,key2) == 0 then hash_fn(key1) == hash_fn(key2).

                          There are five predefined hash and comparison functions in st. For keys as numbers:

                           st_numhash(key, modulus) { return (unsigned int) key % modulus; } 
                           st_numcmp(x,y) { return (int) x - (int) y; } 
                          For keys as pointers:
                           st_ptrhash(key, modulus) { return ((unsigned int) key/4) % modulus } 
                           st_ptrcmp(x,y) { return (int) x - (int) y; } 
                          For keys as strings:
                           st_strhash(x,y) - a reasonable hashing function for strings 
                           strcmp(x,y) - the standard library function 
                          It is recommended to use these particular functions if they fit your needs, since st will recognize certain of them and run more quickly because of it. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table_with_params +st_free_table + + +
                          +int 
                          +st_insert(
                          +  st_table * table, 
                          +  void * key, 
                          +  void * value 
                          +)
                          +
                          +
                          Insert value in table under the key 'key'. Returns 1 if there was an entry already under the key; 0 if there was no entry under the key and insertion was successful; ST_OUT_OF_MEM otherwise. In either of the first two cases the new value is added. +

                          + +

                          Side Effects None +

                          + +

                          + 
                          +st_is_member(
                          +   table, 
                          +   key 
                          +)
                          +
                          +
                          Returns 1 if there is an entry under `key' in `table', 0 otherwise. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_lookup + + +
                          +int 
                          +st_lookup_int(
                          +  st_table * table, 
                          +  void * key, 
                          +  int * value 
                          +)
                          +
                          +
                          Lookup up `key' in `table'. If an entry is found, 1 is returned and if `value' is not nil, the variable it points to is set to the associated integer value. If an entry is not found, 0 is return and the variable pointed by `value' is unchanged. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_lookup + + +
                          +int 
                          +st_lookup(
                          +  st_table * table, 
                          +  void * key, 
                          +  void * value 
                          +)
                          +
                          +
                          Lookup up `key' in `table'. If an entry is found, 1 is returned and if `value' is not nil, the variable it points to is set to the associated value. If an entry is not found, 0 is returned and the variable pointed by value is unchanged. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_lookup_int + + +
                          +int 
                          +st_numcmp(
                          +  const char * x, 
                          +  const char * y 
                          +)
                          +
                          +
                          integer number comparison function. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table +st_numhash + + +
                          +int 
                          +st_numhash(
                          +  char * x, 
                          +  int  size 
                          +)
                          +
                          +
                          Integer number hash function. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table +st_numcmp + + +
                          +int 
                          +st_ptrcmp(
                          +  const char * x, 
                          +  const char * y 
                          +)
                          +
                          +
                          Pointer comparison function. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table +st_ptrhash + + +
                          +int 
                          +st_ptrhash(
                          +  char * x, 
                          +  int  size 
                          +)
                          +
                          +
                          Pointer hash function. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table +st_ptrcmp + + +
                          +int 
                          +st_strhash(
                          +  char * string, 
                          +  int  modulus 
                          +)
                          +
                          +
                          String hash function. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table + + + +
                          + +
                          + +Generated automatically by extdoc on 20040102 + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stExtAbs.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stExtAbs.html new file mode 100644 index 000000000..5302461fa --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stExtAbs.html @@ -0,0 +1,96 @@ + +st package abstract + + +

                          st package abstract

                          +

                          Symbol table package.

                          +
                          + + + +
                          +
                          st_add_direct() +
                          Place 'value' in 'table' under the key 'key'. + +
                          st_copy() +
                          Return a copy of old_table and all its members. + +
                          st_count() +
                          Returns the number of entries in the table `table'. + +
                          st_delete_int() +
                          Delete the entry with the key pointed to by `keyp'. + +
                          st_delete() +
                          Delete the entry with the key pointed to by `keyp'. + +
                          st_find_or_add() +
                          Lookup `key' in `table'. + +
                          st_find() +
                          Lookup `key' in `table'. + +
                          st_foreach_item_int() +
                          Iteration macro. + +
                          st_foreach_item() +
                          Iteration macro. + +
                          st_foreach() +
                          Iterates over the elements of a table. + +
                          st_free_gen() +
                          Reclaims the resources associated with `gen'. + +
                          st_free_table() +
                          Free a table. + +
                          st_gen_int() +
                          Returns the next (key, value) pair in the generation sequence. + +
                          st_gen() +
                          returns the next (key, value) pair in the generation sequence. + +
                          st_init_gen() +
                          Initializes a generator. + +
                          st_init_table_with_params() +
                          Create a table with given parameters. + +
                          st_init_table() +
                          Create and initialize a table. + +
                          st_insert() +
                          Insert value in table under the key 'key'. + +
                          st_is_member() +
                          Checks whethere `key' is in `table'. + +
                          st_lookup_int() +
                          Lookup up `key' in `table'. + +
                          st_lookup() +
                          Lookup up `key' in `table'. + +
                          st_numcmp() +
                          Number comparison function. + +
                          st_numhash() +
                          Number hash function. + +
                          st_ptrcmp() +
                          Pointer comparison function. + +
                          st_ptrhash() +
                          Pointer hash function. + +
                          st_strhash() +
                          String hash function. + +
                          + +
                          + +Generated automatically by extdoc on 20040102 + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stExtDet.html b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stExtDet.html new file mode 100644 index 000000000..43cb6f464 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/doc/stExtDet.html @@ -0,0 +1,463 @@ + +The st package + + +

                          The st package

                          +

                          Symbol table package.

                          +

                          +
                          + + +
                          + + +The st library provides functions to create, maintain, + and query symbol tables. + + +
                          + + +
                          + +
                          +int 
                          +st_add_direct(
                          +  st_table * table, 
                          +  void * key, 
                          +  void * value 
                          +)
                          +
                          +
                          Place 'value' in 'table' under the key 'key'. This is done without checking if 'key' is in 'table' already. This should only be used if you are sure there is not already an entry for 'key', since it is undefined which entry you would later get from st_lookup or st_find_or_add. Returns 1 if successful; ST_OUT_OF_MEM otherwise. +

                          + +

                          Side Effects None +

                          + +

                          +st_table * 
                          +st_copy(
                          +  st_table * old_table 
                          +)
                          +
                          +
                          Return a copy of old_table and all its members. (st_table *) 0 is returned if there was insufficient memory to do the copy. +

                          + +

                          Side Effects None +

                          + +

                          + 
                          +st_count(
                          +   table 
                          +)
                          +
                          +
                          Returns the number of entries in the table `table'. +

                          + +

                          Side Effects None +

                          + +

                          +int 
                          +st_delete_int(
                          +  st_table * table, 
                          +  void * keyp, 
                          +  int * value 
                          +)
                          +
                          +
                          Delete the entry with the key pointed to by `keyp'. `value' must be a pointer to an integer. If the entry is found, 1 is returned, the variable pointed by `keyp' is set to the actual key and the variable pointed by `value' is set to the corresponding entry. (This allows the freeing of the associated storage.) If the entry is not found, then 0 is returned and nothing is changed. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_delete + + +
                          +int 
                          +st_delete(
                          +  st_table * table, 
                          +  void * keyp, 
                          +  void * value 
                          +)
                          +
                          +
                          Delete the entry with the key pointed to by `keyp'. If the entry is found, 1 is returned, the variable pointed by `keyp' is set to the actual key and the variable pointed by `value' is set to the corresponding entry. (This allows the freeing of the associated storage.) If the entry is not found, then 0 is returned and nothing is changed. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_delete_int + + +
                          +int 
                          +st_find_or_add(
                          +  st_table * table, 
                          +  void * key, 
                          +  void * slot 
                          +)
                          +
                          +
                          Lookup `key' in `table'. If not found, create an entry. In either case set slot to point to the field in the entry where the value is stored. The value associated with `key' may then be changed by accessing directly through slot. Returns 1 if an entry already existed, 0 if it did not exist and creation was successful; ST_OUT_OF_MEM otherwise. As an example:
                           char **slot; 
                           char *key; 
                           char *value = (char *) item_ptr <-- ptr to a malloc'd structure 
                           if (st_find_or_add(table, key, &slot) == 1) { 
                           FREE(*slot); <-- free the old value of the record 
                           } 
                           *slot = value; <-- attach the new value to the record 
                          This replaces the equivelent code:
                           if (st_lookup(table, key, &ovalue) == 1) { 
                           FREE(ovalue); 
                           } 
                           st_insert(table, key, value); 
                          +

                          + +

                          Side Effects None +

                          + +

                          See Also st_find + + +
                          +int 
                          +st_find(
                          +  st_table * table, 
                          +  void * key, 
                          +  void * slot 
                          +)
                          +
                          +
                          Like st_find_or_add, but does not create an entry if one is not found. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_find_or_add + + +
                          + 
                          +st_foreach_item_int(
                          +   table, 
                          +   gen, 
                          +   key, 
                          +   value 
                          +)
                          +
                          +
                          An iteration macro which loops over all the entries in `table', setting `key' to point to the key and `value' to the associated value (if it is not nil). `value' is assumed to be a pointer to an integer. `gen' is a generator variable used internally. Sample usage:
                           char *key; 
                           int value; 
                           st_generator *gen; 
                           st_foreach_item_int(table, gen, &key, &value) { 
                           process_item(value); 
                           } 
                          +

                          + +

                          Side Effects None +

                          + +

                          See Also st_foreach_item +st_foreach + + +
                          + 
                          +st_foreach_item(
                          +   table, 
                          +   gen, 
                          +   key, 
                          +   value 
                          +)
                          +
                          +
                          An iteration macro which loops over all the entries in `table', setting `key' to point to the key and `value' to the associated value (if it is not nil). `gen' is a generator variable used internally. Sample usage:
                           char *key, *value; 
                           st_generator *gen; 
                           st_foreach_item(table, gen, &key, &value) { 
                           process_item(value); 
                           } 
                          +

                          + +

                          Side Effects None +

                          + +

                          See Also st_foreach_item_int +st_foreach + + +
                          +int 
                          +st_foreach(
                          +  st_table * table, 
                          +  ST_PFSR  func, 
                          +  char * arg 
                          +)
                          +
                          +
                          For each (key, value) record in `table', st_foreach call func with the arguments
                           (*func)(key, value, arg) 
                          If func returns ST_CONTINUE, st_foreach continues processing entries. If func returns ST_STOP, st_foreach stops processing and returns immediately. If func returns ST_DELETE, then the entry is deleted from the symbol table and st_foreach continues. In the case of ST_DELETE, it is func's responsibility to free the key and value, if necessary.

                          The routine returns 1 if all items in the table were generated and 0 if the generation sequence was aborted using ST_STOP. The order in which the records are visited will be seemingly random. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_foreach_item +st_foreach_item_int + + +
                          +void 
                          +st_free_gen(
                          +  st_generator * gen 
                          +)
                          +
                          +
                          After generating all items in a generation sequence, this routine must be called to reclaim the resources associated with `gen'. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_gen + + +
                          +void 
                          +st_free_table(
                          +  st_table * table 
                          +)
                          +
                          +
                          Any internal storage associated with table is freed. It is the user's responsibility to free any storage associated with the pointers he placed in the table (by perhaps using st_foreach). +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table +st_init_table_with_params + + +
                          +int 
                          +st_gen_int(
                          +  st_generator * gen, 
                          +  void * key_p, 
                          +  int * value_p 
                          +)
                          +
                          +
                          Given a generator returned by st_init_gen(), this routine returns the next (key, value) pair in the generation sequence. `value_p' must be a pointer to an integer. The pointer `value_p' can be zero which means no value will be returned. When there are no more items in the generation sequence, the routine returns 0. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_gen + + +
                          +int 
                          +st_gen(
                          +  st_generator * gen, 
                          +  void * key_p, 
                          +  void * value_p 
                          +)
                          +
                          +
                          Given a generator returned by st_init_gen(), this routine returns the next (key, value) pair in the generation sequence. The pointer `value_p' can be zero which means no value will be returned. When there are no more items in the generation sequence, the routine returns 0. While using a generation sequence, deleting any (key, value) pair other than the one just generated may cause a fatal error when st_gen() is called later in the sequence and is therefore not recommended. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_gen_int + + +
                          +st_generator * 
                          +st_init_gen(
                          +  st_table * table 
                          +)
                          +
                          +
                          Returns a generator handle which when used with st_gen() will progressively return each (key, value) record in `table'. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_free_gen + + +
                          +st_table * 
                          +st_init_table_with_params(
                          +  ST_PFICPCP  compare, 
                          +  ST_PFICPI  hash, 
                          +  int  size, 
                          +  int  density, 
                          +  double  grow_factor, 
                          +  int  reorder_flag 
                          +)
                          +
                          +
                          The full blown table initializer. compare and hash are the same as in st_init_table. density is the largest the average number of entries per hash bin there should be before the table is grown. grow_factor is the factor the table is grown by when it becomes too full. size is the initial number of bins to be allocated for the hash table. If reorder_flag is non-zero, then every time an entry is found, it is moved to the top of the chain.

                          st_init_table(compare, hash) is equivelent to

                           st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE, ST_DEFAULT_MAX_DENSITY, ST_DEFAULT_GROW_FACTOR, ST_DEFAULT_REORDER_FLAG); 
                          +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table +st_free_table + + +
                          +st_table * 
                          +st_init_table(
                          +  ST_PFICPCP  compare, 
                          +  ST_PFICPI  hash 
                          +)
                          +
                          +
                          Create and initialize a table with the comparison function compare_fn and hash function hash_fn. compare_fn is
                           int compare_fn(const char *key1, const char *key2) 
                          It returns <,=,> 0 depending on whether key1 <,=,> key2 by some measure.

                          hash_fn is

                           int hash_fn(char *key, int modulus) 
                          It returns a integer between 0 and modulus-1 such that if compare_fn(key1,key2) == 0 then hash_fn(key1) == hash_fn(key2).

                          There are five predefined hash and comparison functions in st. For keys as numbers:

                           st_numhash(key, modulus) { return (unsigned int) key % modulus; } 
                           st_numcmp(x,y) { return (int) x - (int) y; } 
                          For keys as pointers:
                           st_ptrhash(key, modulus) { return ((unsigned int) key/4) % modulus } 
                           st_ptrcmp(x,y) { return (int) x - (int) y; } 
                          For keys as strings:
                           st_strhash(x,y) - a reasonable hashing function for strings 
                           strcmp(x,y) - the standard library function 
                          It is recommended to use these particular functions if they fit your needs, since st will recognize certain of them and run more quickly because of it. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table_with_params +st_free_table + + +
                          +int 
                          +st_insert(
                          +  st_table * table, 
                          +  void * key, 
                          +  void * value 
                          +)
                          +
                          +
                          Insert value in table under the key 'key'. Returns 1 if there was an entry already under the key; 0 if there was no entry under the key and insertion was successful; ST_OUT_OF_MEM otherwise. In either of the first two cases the new value is added. +

                          + +

                          Side Effects None +

                          + +

                          + 
                          +st_is_member(
                          +   table, 
                          +   key 
                          +)
                          +
                          +
                          Returns 1 if there is an entry under `key' in `table', 0 otherwise. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_lookup + + +
                          +int 
                          +st_lookup_int(
                          +  st_table * table, 
                          +  void * key, 
                          +  int * value 
                          +)
                          +
                          +
                          Lookup up `key' in `table'. If an entry is found, 1 is returned and if `value' is not nil, the variable it points to is set to the associated integer value. If an entry is not found, 0 is return and the variable pointed by `value' is unchanged. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_lookup + + +
                          +int 
                          +st_lookup(
                          +  st_table * table, 
                          +  void * key, 
                          +  void * value 
                          +)
                          +
                          +
                          Lookup up `key' in `table'. If an entry is found, 1 is returned and if `value' is not nil, the variable it points to is set to the associated value. If an entry is not found, 0 is returned and the variable pointed by value is unchanged. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_lookup_int + + +
                          +int 
                          +st_numcmp(
                          +  const char * x, 
                          +  const char * y 
                          +)
                          +
                          +
                          integer number comparison function. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table +st_numhash + + +
                          +int 
                          +st_numhash(
                          +  char * x, 
                          +  int  size 
                          +)
                          +
                          +
                          Integer number hash function. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table +st_numcmp + + +
                          +int 
                          +st_ptrcmp(
                          +  const char * x, 
                          +  const char * y 
                          +)
                          +
                          +
                          Pointer comparison function. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table +st_ptrhash + + +
                          +int 
                          +st_ptrhash(
                          +  char * x, 
                          +  int  size 
                          +)
                          +
                          +
                          Pointer hash function. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table +st_ptrcmp + + +
                          +int 
                          +st_strhash(
                          +  char * string, 
                          +  int  modulus 
                          +)
                          +
                          +
                          String hash function. +

                          + +

                          Side Effects None +

                          + +

                          See Also st_init_table + + + +
                          + +
                          + +Generated automatically by extdoc on 20040102 + + diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/st.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/st.c new file mode 100644 index 000000000..dd76fa591 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/st/st.c @@ -0,0 +1,1065 @@ +/**CFile*********************************************************************** + + FileName [st.c] + + PackageName [st] + + Synopsis [Symbol table package.] + + Description [The st library provides functions to create, maintain, + and query symbol tables.] + + SeeAlso [] + + Author [] + + Copyright [] + +******************************************************************************/ + +#include "util.h" +#include "st.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] UTIL_UNUSED = " $Id: st.c,v 1.12 2010/04/22 19:00:55 fabio Exp fabio $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#define ST_NUMCMP(x,y) ((x) != (y)) + +#define ST_NUMHASH(x,size) ((unsigned long)(x)%(size)) + +#if SIZEOF_VOID_P == 8 +#define st_shift 3 +#else +#define st_shift 2 +#endif + +#define ST_PTRHASH(x,size) ((unsigned int)((unsigned long)(x)>>st_shift)%size) + +#define EQUAL(func, x, y) \ + ((((func) == st_numcmp) || ((func) == st_ptrcmp)) ?\ + (ST_NUMCMP((x),(y)) == 0) : ((*func)((x), (y)) == 0)) + +#define do_hash(key, table)\ + ((int)((table->hash == st_ptrhash) ? ST_PTRHASH((char *)(key),(table)->num_bins) :\ + (table->hash == st_numhash) ? ST_NUMHASH((char *)(key), (table)->num_bins) :\ + (*table->hash)((char *)(key), (table)->num_bins))) + +#define PTR_NOT_EQUAL(table, ptr, user_key)\ +(ptr != NIL(st_table_entry) && !EQUAL(table->compare, (char *)user_key, (ptr)->key)) + +#define FIND_ENTRY(table, hash_val, key, ptr, last) \ + (last) = &(table)->bins[hash_val];\ + (ptr) = *(last);\ + while (PTR_NOT_EQUAL((table), (ptr), (key))) {\ + (last) = &(ptr)->next; (ptr) = *(last);\ + }\ + if ((ptr) != NIL(st_table_entry) && (table)->reorder_flag) {\ + *(last) = (ptr)->next;\ + (ptr)->next = (table)->bins[hash_val];\ + (table)->bins[hash_val] = (ptr);\ + } + +/* This macro does not check if memory allocation fails. Use at you own risk */ +#define ADD_DIRECT(table, key, value, hash_val, newt)\ +{\ + if (table->num_entries/table->num_bins >= table->max_density) {\ + rehash(table);\ + hash_val = do_hash(key,table);\ + }\ + \ + newt = ALLOC(st_table_entry, 1);\ + \ + newt->key = (char *)key;\ + newt->record = value;\ + newt->next = table->bins[hash_val];\ + table->bins[hash_val] = newt;\ + table->num_entries++;\ +} + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int rehash (st_table *); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Create and initialize a table.] + + Description [Create and initialize a table with the comparison function + compare_fn and hash function hash_fn. compare_fn is +
                          +	int compare_fn(const char *key1, const char *key2)
                          +  
                          + It returns <,=,> 0 depending on whether key1 <,=,> key2 by some measure.

                          + hash_fn is +

                          +	int hash_fn(char *key, int modulus)
                          +  
                          + It returns a integer between 0 and modulus-1 such that if + compare_fn(key1,key2) == 0 then hash_fn(key1) == hash_fn(key2).

                          + There are five predefined hash and comparison functions in st. + For keys as numbers: +

                          +	 st_numhash(key, modulus) { return (unsigned int) key % modulus; }
                          +  
                          +
                          +	 st_numcmp(x,y) { return (int) x - (int) y; }
                          +  
                          + For keys as pointers: +
                          +	 st_ptrhash(key, modulus) { return ((unsigned int) key/4) % modulus }
                          +  
                          +
                          +	 st_ptrcmp(x,y) { return (int) x - (int) y; }
                          +  
                          + For keys as strings: +
                          +         st_strhash(x,y) - a reasonable hashing function for strings
                          +  
                          +
                          +	 strcmp(x,y) - the standard library function
                          +  
                          + It is recommended to use these particular functions if they fit your + needs, since st will recognize certain of them and run more quickly + because of it.] + + SideEffects [None] + + SeeAlso [st_init_table_with_params st_free_table] + +******************************************************************************/ +st_table * +st_init_table(ST_PFICPCP compare, ST_PFICPI hash) +{ + return st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE, + ST_DEFAULT_MAX_DENSITY, + ST_DEFAULT_GROW_FACTOR, + ST_DEFAULT_REORDER_FLAG); + +} /* st_init_table */ + + +/**Function******************************************************************** + + Synopsis [Create a table with given parameters.] + + Description [The full blown table initializer. compare and hash are + the same as in st_init_table. density is the largest the average + number of entries per hash bin there should be before the table is + grown. grow_factor is the factor the table is grown by when it + becomes too full. size is the initial number of bins to be allocated + for the hash table. If reorder_flag is non-zero, then every time an + entry is found, it is moved to the top of the chain.

                          + st_init_table(compare, hash) is equivelent to +

                          +  st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE,
                          +			    ST_DEFAULT_MAX_DENSITY,
                          +			    ST_DEFAULT_GROW_FACTOR,
                          +			    ST_DEFAULT_REORDER_FLAG);
                          +  
                          + ] + + SideEffects [None] + + SeeAlso [st_init_table st_free_table] + +******************************************************************************/ +st_table * +st_init_table_with_params( + ST_PFICPCP compare, + ST_PFICPI hash, + int size, + int density, + double grow_factor, + int reorder_flag) +{ + int i; + st_table *newt; + + newt = ALLOC(st_table, 1); + if (newt == NIL(st_table)) { + return NIL(st_table); + } + newt->compare = compare; + newt->hash = hash; + newt->num_entries = 0; + newt->max_density = density; + newt->grow_factor = grow_factor; + newt->reorder_flag = reorder_flag; + if (size <= 0) { + size = 1; + } + newt->num_bins = size; + newt->bins = ALLOC(st_table_entry *, size); + if (newt->bins == NIL(st_table_entry *)) { + FREE(newt); + return NIL(st_table); + } + for(i = 0; i < size; i++) { + newt->bins[i] = 0; + } + return newt; + +} /* st_init_table_with_params */ + + +/**Function******************************************************************** + + Synopsis [Free a table.] + + Description [Any internal storage associated with table is freed. + It is the user's responsibility to free any storage associated + with the pointers he placed in the table (by perhaps using + st_foreach).] + + SideEffects [None] + + SeeAlso [st_init_table st_init_table_with_params] + +******************************************************************************/ +void +st_free_table(st_table *table) +{ + st_table_entry *ptr, *next; + int i; + + for(i = 0; i < table->num_bins ; i++) { + ptr = table->bins[i]; + while (ptr != NIL(st_table_entry)) { + next = ptr->next; + FREE(ptr); + ptr = next; + } + } + FREE(table->bins); + FREE(table); + +} /* st_free_table */ + + +/**Function******************************************************************** + + Synopsis [Lookup up `key' in `table'.] + + Description [Lookup up `key' in `table'. If an entry is found, 1 is + returned and if `value' is not nil, the variable it points to is set + to the associated value. If an entry is not found, 0 is returned + and the variable pointed by value is unchanged.] + + SideEffects [None] + + SeeAlso [st_lookup_int] + +******************************************************************************/ +int +st_lookup(st_table *table, void *key, void *value) +{ + int hash_val; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (value != NIL(void)) { + *(char **)value = ptr->record; + } + return 1; + } + +} /* st_lookup */ + + +/**Function******************************************************************** + + Synopsis [Lookup up `key' in `table'.] + + Description [Lookup up `key' in `table'. If an entry is found, 1 is + returned and if `value' is not nil, the variable it points to is + set to the associated integer value. If an entry is not found, 0 is + return and the variable pointed by `value' is unchanged.] + + SideEffects [None] + + SeeAlso [st_lookup] + +******************************************************************************/ +int +st_lookup_int(st_table *table, void *key, int *value) +{ + int hash_val; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (value != NIL(int)) { + *value = (int) (long) ptr->record; + } + return 1; + } + +} /* st_lookup_int */ + + +/**Function******************************************************************** + + Synopsis [Insert value in table under the key 'key'.] + + Description [Insert value in table under the key 'key'. Returns 1 + if there was an entry already under the key; 0 if there was no entry + under the key and insertion was successful; ST_OUT_OF_MEM otherwise. + In either of the first two cases the new value is added.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +st_insert(st_table *table, void *key, void *value) +{ + int hash_val; + st_table_entry *newt; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + if (table->num_entries/table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + hash_val = do_hash(key, table); + } + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = (char *)key; + newt->record = (char *)value; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + return 0; + } else { + ptr->record = (char *)value; + return 1; + } + +} /* st_insert */ + + +/**Function******************************************************************** + + Synopsis [Place 'value' in 'table' under the key 'key'.] + + Description [Place 'value' in 'table' under the key 'key'. This is + done without checking if 'key' is in 'table' already. This should + only be used if you are sure there is not already an entry for + 'key', since it is undefined which entry you would later get from + st_lookup or st_find_or_add. Returns 1 if successful; ST_OUT_OF_MEM + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +st_add_direct(st_table *table, void *key, void *value) +{ + int hash_val; + st_table_entry *newt; + + hash_val = do_hash(key, table); + if (table->num_entries / table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + } + hash_val = do_hash(key, table); + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = (char *)key; + newt->record = (char *)value; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + return 1; + +} /* st_add_direct */ + + +/**Function******************************************************************** + + Synopsis [Lookup `key' in `table'.] + + Description [Lookup `key' in `table'. If not found, create an + entry. In either case set slot to point to the field in the entry + where the value is stored. The value associated with `key' may then + be changed by accessing directly through slot. Returns 1 if an + entry already existed, 0 if it did not exist and creation was + successful; ST_OUT_OF_MEM otherwise. As an example: +
                          +      char **slot;
                          +  
                          +
                          +      char *key;
                          +  
                          +
                          +      char *value = (char *) item_ptr <-- ptr to a malloc'd structure
                          +  
                          +
                          +      if (st_find_or_add(table, key, &slot) == 1) {
                          +  
                          +
                          +	 FREE(*slot); <-- free the old value of the record
                          +  
                          +
                          +      }
                          +  
                          +
                          +      *slot = value;  <-- attach the new value to the record
                          +  
                          + This replaces the equivelent code: +
                          +      if (st_lookup(table, key, &ovalue) == 1) {
                          +  
                          +
                          +         FREE(ovalue);
                          +  
                          +
                          +      }
                          +  
                          +
                          +      st_insert(table, key, value);
                          +  
                          + ] + + SideEffects [None] + + SeeAlso [st_find] + +******************************************************************************/ +int +st_find_or_add(st_table *table, void *key, void *slot) +{ + int hash_val; + st_table_entry *newt, *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + if (table->num_entries / table->num_bins >= table->max_density) { + if (rehash(table) == ST_OUT_OF_MEM) { + return ST_OUT_OF_MEM; + } + hash_val = do_hash(key, table); + } + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + return ST_OUT_OF_MEM; + } + newt->key = (char *)key; + newt->record = (char *) 0; + newt->next = table->bins[hash_val]; + table->bins[hash_val] = newt; + table->num_entries++; + if (slot != NIL(void)) *(char ***)slot = &newt->record; + return 0; + } else { + if (slot != NIL(void)) *(char ***)slot = &ptr->record; + return 1; + } + +} /* st_find_or_add */ + + +/**Function******************************************************************** + + Synopsis [Lookup `key' in `table'.] + + Description [Like st_find_or_add, but does not create an entry if + one is not found.] + + SideEffects [None] + + SeeAlso [st_find_or_add] + +******************************************************************************/ +int +st_find(st_table *table, void *key, void *slot) +{ + int hash_val; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr, last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } else { + if (slot != NIL(void)) { + *(char ***)slot = &ptr->record; + } + return 1; + } + +} /* st_find */ + + +/**Function******************************************************************** + + Synopsis [Return a copy of old_table and all its members.] + + Description [Return a copy of old_table and all its members. + (st_table *) 0 is returned if there was insufficient memory to do + the copy.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +st_table * +st_copy(st_table *old_table) +{ + st_table *new_table; + st_table_entry *ptr, *newptr, *next, *newt; + int i, j, num_bins = old_table->num_bins; + + new_table = ALLOC(st_table, 1); + if (new_table == NIL(st_table)) { + return NIL(st_table); + } + + *new_table = *old_table; + new_table->bins = ALLOC(st_table_entry *, num_bins); + if (new_table->bins == NIL(st_table_entry *)) { + FREE(new_table); + return NIL(st_table); + } + for(i = 0; i < num_bins ; i++) { + new_table->bins[i] = NIL(st_table_entry); + ptr = old_table->bins[i]; + while (ptr != NIL(st_table_entry)) { + newt = ALLOC(st_table_entry, 1); + if (newt == NIL(st_table_entry)) { + for (j = 0; j <= i; j++) { + newptr = new_table->bins[j]; + while (newptr != NIL(st_table_entry)) { + next = newptr->next; + FREE(newptr); + newptr = next; + } + } + FREE(new_table->bins); + FREE(new_table); + return NIL(st_table); + } + *newt = *ptr; + newt->next = new_table->bins[i]; + new_table->bins[i] = newt; + ptr = ptr->next; + } + } + return new_table; + +} /* st_copy */ + + +/**Function******************************************************************** + + Synopsis [Delete the entry with the key pointed to by `keyp'.] + + Description [Delete the entry with the key pointed to by `keyp'. If + the entry is found, 1 is returned, the variable pointed by `keyp' is + set to the actual key and the variable pointed by `value' is set to + the corresponding entry. (This allows the freeing of the associated + storage.) If the entry is not found, then 0 is returned and nothing + is changed.] + + SideEffects [None] + + SeeAlso [st_delete_int] + +******************************************************************************/ +int +st_delete(st_table *table, void *keyp, void *value) +{ + int hash_val; + char *key = *(char **)keyp; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr ,last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } + + *last = ptr->next; + if (value != NIL(void)) *(char **)value = ptr->record; + *(char **)keyp = ptr->key; + FREE(ptr); + table->num_entries--; + return 1; + +} /* st_delete */ + + +/**Function******************************************************************** + + Synopsis [Delete the entry with the key pointed to by `keyp'.] + + Description [Delete the entry with the key pointed to by `keyp'. + `value' must be a pointer to an integer. If the entry is found, 1 + is returned, the variable pointed by `keyp' is set to the actual key + and the variable pointed by `value' is set to the corresponding + entry. (This allows the freeing of the associated storage.) If the + entry is not found, then 0 is returned and nothing is changed.] + + SideEffects [None] + + SeeAlso [st_delete] + +******************************************************************************/ +int +st_delete_int(st_table *table, void *keyp, int *value) +{ + int hash_val; + char *key = *(char **)keyp; + st_table_entry *ptr, **last; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, hash_val, key, ptr ,last); + + if (ptr == NIL(st_table_entry)) { + return 0; + } + + *last = ptr->next; + if (value != NIL(int)) *value = (int) (long) ptr->record; + *(char **)keyp = ptr->key; + FREE(ptr); + table->num_entries--; + return 1; + +} /* st_delete_int */ + + +/**Function******************************************************************** + + Synopsis [Iterates over the elements of a table.] + + Description [For each (key, value) record in `table', st_foreach + call func with the arguments +
                          +	  (*func)(key, value, arg)
                          +  
                          + If func returns ST_CONTINUE, st_foreach continues processing + entries. If func returns ST_STOP, st_foreach stops processing and + returns immediately. If func returns ST_DELETE, then the entry is + deleted from the symbol table and st_foreach continues. In the case + of ST_DELETE, it is func's responsibility to free the key and value, + if necessary.

                          + + The routine returns 1 if all items in the table were generated and 0 + if the generation sequence was aborted using ST_STOP. The order in + which the records are visited will be seemingly random.] + + SideEffects [None] + + SeeAlso [st_foreach_item st_foreach_item_int] + +******************************************************************************/ +int +st_foreach(st_table *table, ST_PFSR func, char *arg) +{ + st_table_entry *ptr, **last; + enum st_retval retval; + int i; + + for(i = 0; i < table->num_bins; i++) { + last = &table->bins[i]; ptr = *last; + while (ptr != NIL(st_table_entry)) { + retval = (*func)(ptr->key, ptr->record, arg); + switch (retval) { + case ST_CONTINUE: + last = &ptr->next; ptr = *last; + break; + case ST_STOP: + return 0; + case ST_DELETE: + *last = ptr->next; + table->num_entries--; /* cstevens@ic */ + FREE(ptr); + ptr = *last; + } + } + } + return 1; + +} /* st_foreach */ + + +/**Function******************************************************************** + + Synopsis [String hash function.] + + Description [String hash function.] + + SideEffects [None] + + SeeAlso [st_init_table] + +******************************************************************************/ +int +st_strhash(char *string, int modulus) +{ + int val = 0; + int c; + + while ((c = *string++) != '\0') { + val = val*997 + c; + } + + return ((val < 0) ? -val : val)%modulus; + +} /* st_strhash */ + + +/**Function******************************************************************** + + Synopsis [Number hash function.] + + Description [Integer number hash function.] + + SideEffects [None] + + SeeAlso [st_init_table st_numcmp] + +******************************************************************************/ +int +st_numhash(char *x, int size) +{ + return ST_NUMHASH(x, size); + +} /* st_numhash */ + + +/**Function******************************************************************** + + Synopsis [Pointer hash function.] + + Description [Pointer hash function.] + + SideEffects [None] + + SeeAlso [st_init_table st_ptrcmp] + +******************************************************************************/ +int +st_ptrhash(char *x, int size) +{ + return ST_PTRHASH(x, size); + +} /* st_ptrhash */ + + +/**Function******************************************************************** + + Synopsis [Number comparison function.] + + Description [integer number comparison function.] + + SideEffects [None] + + SeeAlso [st_init_table st_numhash] + +******************************************************************************/ +int +st_numcmp(const char *x, const char *y) +{ + return ST_NUMCMP(x, y); + +} /* st_numcmp */ + + +/**Function******************************************************************** + + Synopsis [Pointer comparison function.] + + Description [Pointer comparison function.] + + SideEffects [None] + + SeeAlso [st_init_table st_ptrhash] + +******************************************************************************/ +int +st_ptrcmp(const char *x, const char *y) +{ + return ST_NUMCMP(x, y); + +} /* st_ptrcmp */ + + +/**Function******************************************************************** + + Synopsis [Initializes a generator.] + + Description [Returns a generator handle which when used with + st_gen() will progressively return each (key, value) record in + `table'.] + + SideEffects [None] + + SeeAlso [st_free_gen] + +******************************************************************************/ +st_generator * +st_init_gen(st_table *table) +{ + st_generator *gen; + + gen = ALLOC(st_generator, 1); + if (gen == NIL(st_generator)) { + return NIL(st_generator); + } + gen->table = table; + gen->entry = NIL(st_table_entry); + gen->index = 0; + return gen; + +} /* st_init_gen */ + + +/**Function******************************************************************** + + Synopsis [returns the next (key, value) pair in the generation + sequence. ] + + Description [Given a generator returned by st_init_gen(), this + routine returns the next (key, value) pair in the generation + sequence. The pointer `value_p' can be zero which means no value + will be returned. When there are no more items in the generation + sequence, the routine returns 0. + + While using a generation sequence, deleting any (key, value) pair + other than the one just generated may cause a fatal error when + st_gen() is called later in the sequence and is therefore not + recommended.] + + SideEffects [None] + + SeeAlso [st_gen_int] + +******************************************************************************/ +int +st_gen(st_generator *gen, void *key_p, void *value_p) +{ + int i; + + if (gen->entry == NIL(st_table_entry)) { + /* try to find next entry */ + for(i = gen->index; i < gen->table->num_bins; i++) { + if (gen->table->bins[i] != NIL(st_table_entry)) { + gen->index = i+1; + gen->entry = gen->table->bins[i]; + break; + } + } + if (gen->entry == NIL(st_table_entry)) { + return 0; /* that's all folks ! */ + } + } + *(char **)key_p = gen->entry->key; + if (value_p != NIL(void)) { + *(char **)value_p = gen->entry->record; + } + gen->entry = gen->entry->next; + return 1; + +} /* st_gen */ + + +/**Function******************************************************************** + + Synopsis [Returns the next (key, value) pair in the generation + sequence.] + + Description [Given a generator returned by st_init_gen(), this + routine returns the next (key, value) pair in the generation + sequence. `value_p' must be a pointer to an integer. The pointer + `value_p' can be zero which means no value will be returned. When + there are no more items in the generation sequence, the routine + returns 0.] + + SideEffects [None] + + SeeAlso [st_gen] + +******************************************************************************/ +int +st_gen_int(st_generator *gen, void *key_p, int *value_p) +{ + int i; + + if (gen->entry == NIL(st_table_entry)) { + /* try to find next entry */ + for(i = gen->index; i < gen->table->num_bins; i++) { + if (gen->table->bins[i] != NIL(st_table_entry)) { + gen->index = i+1; + gen->entry = gen->table->bins[i]; + break; + } + } + if (gen->entry == NIL(st_table_entry)) { + return 0; /* that's all folks ! */ + } + } + *(char **)key_p = gen->entry->key; + if (value_p != NIL(int)) { + *value_p = (int) (long) gen->entry->record; + } + gen->entry = gen->entry->next; + return 1; + +} /* st_gen_int */ + + +/**Function******************************************************************** + + Synopsis [Reclaims the resources associated with `gen'.] + + Description [After generating all items in a generation sequence, + this routine must be called to reclaim the resources associated with + `gen'.] + + SideEffects [None] + + SeeAlso [st_init_gen] + +******************************************************************************/ +void +st_free_gen(st_generator *gen) +{ + FREE(gen); + +} /* st_free_gen */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Rehashes a symbol table.] + + Description [Rehashes a symbol table.] + + SideEffects [None] + + SeeAlso [st_insert] + +******************************************************************************/ +static int +rehash(st_table *table) +{ + st_table_entry *ptr, *next, **old_bins; + int i, old_num_bins, hash_val, old_num_entries; + + /* save old values */ + old_bins = table->bins; + old_num_bins = table->num_bins; + old_num_entries = table->num_entries; + + /* rehash */ + table->num_bins = (int) (table->grow_factor * old_num_bins); + if (table->num_bins % 2 == 0) { + table->num_bins += 1; + } + table->num_entries = 0; + table->bins = ALLOC(st_table_entry *, table->num_bins); + if (table->bins == NIL(st_table_entry *)) { + table->bins = old_bins; + table->num_bins = old_num_bins; + table->num_entries = old_num_entries; + return ST_OUT_OF_MEM; + } + /* initialize */ + for (i = 0; i < table->num_bins; i++) { + table->bins[i] = 0; + } + + /* copy data over */ + for (i = 0; i < old_num_bins; i++) { + ptr = old_bins[i]; + while (ptr != NIL(st_table_entry)) { + next = ptr->next; + hash_val = do_hash(ptr->key, table); + ptr->next = table->bins[hash_val]; + table->bins[hash_val] = ptr; + table->num_entries++; + ptr = next; + } + } + FREE(old_bins); + + return 1; + +} /* rehash */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/Makefile b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/Makefile new file mode 100644 index 000000000..61543baee --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/Makefile @@ -0,0 +1,64 @@ +# $Id$ +# +# util -- miscellaneous utility routines +#--------------------------------------------------------------------------- +.SUFFIXES: .c .o .u + +CC = gcc +RANLIB = ranlib + +FLAGS = -DUNIX +MFLAG = +ICFLAGS = -g +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) + +LINTFLAGS = -u -n + +# this is to create the lint library +LINTSWITCH = -o + +P = util +PSRC = cpu_time.c cpu_stats.c safe_mem.c strsav.c texpand.c \ + ptime.c prtime.c pipefork.c pathsearch.c stub.c datalimit.c +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +PHDR = util.h + +WHERE = .. +INCLUDE = $(WHERE)/include + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(FLAGS) $(CFLAGS) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PHDR) + cc -j $< -I$(INCLUDE) $(FLAGS) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +clean: + rm -f *.o *.u core *.warnings + +distclean: clean + rm -f lib$(P).a lib$(P).b llib-l$(P).ln tags *.bak *~ .pure diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/cpu_stats.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/cpu_stats.c new file mode 100644 index 000000000..40117d463 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/cpu_stats.c @@ -0,0 +1,89 @@ +/* LINTLIBRARY */ + +#include "util.h" + + +#ifdef BSD +#include +#include +#include + +#if defined(_IBMR2) +#define etext _etext +#define edata _edata +#define end _end +#endif + +extern int end, etext, edata; + +#endif + +void +util_print_cpu_stats(FILE *fp) +{ +#ifdef BSD + struct rusage rusage; + struct rlimit rlp; + long text, data, vm_limit, vm_soft_limit; + double user, system, scale; + char hostname[257]; + long vm_text, vm_init_data, vm_uninit_data, vm_sbrk_data; + + /* Get the hostname */ + (void) gethostname(hostname, 256); + hostname[256] = '\0'; /* just in case */ + + /* Get the virtual memory sizes */ + vm_text = (long) (((long) (&etext)) / 1024.0 + 0.5); + vm_init_data = (long) (((long) (&edata) - (long) (&etext)) / 1024.0 + 0.5); + vm_uninit_data = (long) (((long) (&end) - (long) (&edata)) / 1024.0 + 0.5); + vm_sbrk_data = (long) (((long) sbrk(0) - (long) (&end)) / 1024.0 + 0.5); + + /* Get virtual memory limits */ + (void) getrlimit(RLIMIT_DATA, &rlp); + vm_limit = (long) (rlp.rlim_max / 1024.0 + 0.5); + vm_soft_limit = (long) (rlp.rlim_cur / 1024.0 + 0.5); + + /* Get usage stats */ + (void) getrusage(RUSAGE_SELF, &rusage); + user = rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec/1.0e6; + system = rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec/1.0e6; + scale = (user + system)*100.0; + if (scale == 0.0) scale = 0.001; + + (void) fprintf(fp, "Runtime Statistics\n"); + (void) fprintf(fp, "------------------\n"); + (void) fprintf(fp, "Machine name: %s\n", hostname); + (void) fprintf(fp, "User time %6.1f seconds\n", user); + (void) fprintf(fp, "System time %6.1f seconds\n\n", system); + + text = (int) (rusage.ru_ixrss / scale + 0.5); + data = (int) ((rusage.ru_idrss + rusage.ru_isrss) / scale + 0.5); + (void) fprintf(fp, "Average resident text size = %5ldK\n", text); + (void) fprintf(fp, "Average resident data+stack size = %5ldK\n", data); + (void) fprintf(fp, "Maximum resident size = %5ldK\n\n", + rusage.ru_maxrss/2); + (void) fprintf(fp, "Virtual text size = %5ldK\n", + vm_text); + (void) fprintf(fp, "Virtual data size = %5ldK\n", + vm_init_data + vm_uninit_data + vm_sbrk_data); + (void) fprintf(fp, " data size initialized = %5ldK\n", + vm_init_data); + (void) fprintf(fp, " data size uninitialized = %5ldK\n", + vm_uninit_data); + (void) fprintf(fp, " data size sbrk = %5ldK\n", + vm_sbrk_data); + (void) fprintf(fp, "Virtual memory limit = %5ldK (%ldK)\n\n", + vm_soft_limit, vm_limit); + + (void) fprintf(fp, "Major page faults = %ld\n", rusage.ru_majflt); + (void) fprintf(fp, "Minor page faults = %ld\n", rusage.ru_minflt); + (void) fprintf(fp, "Swaps = %ld\n", rusage.ru_nswap); + (void) fprintf(fp, "Input blocks = %ld\n", rusage.ru_inblock); + (void) fprintf(fp, "Output blocks = %ld\n", rusage.ru_oublock); + (void) fprintf(fp, "Context switch (voluntary) = %ld\n", rusage.ru_nvcsw); + (void) fprintf(fp, "Context switch (involuntary) = %ld\n", rusage.ru_nivcsw); +#else + (void) fprintf(fp, "Usage statistics not available\n"); +#endif +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/cpu_time.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/cpu_time.c new file mode 100644 index 000000000..2a4be9240 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/cpu_time.c @@ -0,0 +1,76 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + +#ifdef IBM_WATC /* IBM Waterloo-C compiler (same as bsd 4.2) */ +#define void int +#define BSD +#endif + +#ifdef BSD +#include +#include +#include +#endif + +#if defined(UNIX60) || defined(UNIX100) || defined(__CYGWIN32__) +#include +#include +#endif + +#ifdef vms /* VAX/C compiler -- times() with 100 HZ clock */ +#include +#include +#endif + + + +/* + * util_cpu_time -- return a long which represents the elapsed processor + * time in milliseconds since some constant reference + */ +long +util_cpu_time() +{ + long t = 0; + +#ifdef BSD + struct rusage rusage; + (void) getrusage(RUSAGE_SELF, &rusage); + t = (long) rusage.ru_utime.tv_sec*1000 + rusage.ru_utime.tv_usec/1000; +#endif + +#ifdef IBMPC + long ltime; + (void) time(<ime); + t = ltime * 1000; +#endif + +#ifdef UNIX60 /* times() with 60 Hz resolution */ + struct tms buffer; + times(&buffer); + t = buffer.tms_utime * 16.6667; +#endif + +#ifdef UNIX100 + struct tms buffer; /* times() with 100 Hz resolution */ + times(&buffer); + t = buffer.tms_utime * 10; +#endif + +#ifdef __CYGWIN32__ + /* Works under Windows NT but not Windows 95. */ + struct tms buffer; /* times() with 1000 Hz resolution */ + times(&buffer); + t = buffer.tms_utime; +#endif + +#ifdef vms + tbuffer_t buffer; /* times() with 100 Hz resolution */ + times(&buffer); + t = buffer.proc_user_time * 10; +#endif + + return t; +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/datalimit.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/datalimit.c new file mode 100644 index 000000000..ee3be5579 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/datalimit.c @@ -0,0 +1,50 @@ +/* $Id: datalimit.c,v 1.5 2007/08/24 18:17:31 fabio Exp fabio $ */ + +#ifndef HAVE_SYS_RESOURCE_H +#define HAVE_SYS_RESOURCE_H 1 +#endif +#ifndef HAVE_SYS_TIME_H +#define HAVE_SYS_TIME_H 1 +#endif +#ifndef HAVE_GETRLIMIT +#define HAVE_GETRLIMIT 1 +#endif + +#if HAVE_SYS_RESOURCE_H == 1 +#if HAVE_SYS_TIME_H == 1 +#include +#endif +//#include +#endif + +#ifndef RLIMIT_DATA_DEFAULT +#define RLIMIT_DATA_DEFAULT 67108864 /* assume 64MB by default */ +#endif + +#ifndef EXTERN +# ifdef __cplusplus +# define EXTERN extern "C" +# else +# define EXTERN extern +# endif +#endif + +EXTERN unsigned long getSoftDataLimit(void); + +unsigned long +getSoftDataLimit(void) +{ +#if HAVE_SYS_RESOURCE_H == 1 && HAVE_GETRLIMIT == 1 && defined(RLIMIT_DATA) + struct rlimit rl; + int result; + + result = getrlimit(RLIMIT_DATA, &rl); + if (result != 0 || rl.rlim_cur == RLIM_INFINITY) + return((unsigned long) RLIMIT_DATA_DEFAULT); + else + return((unsigned long) rl.rlim_cur); +#else + return((unsigned long) RLIMIT_DATA_DEFAULT); +#endif + +} /* end of getSoftDataLimit */ diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/pathsearch.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/pathsearch.c new file mode 100644 index 000000000..67c34b868 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/pathsearch.c @@ -0,0 +1,94 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + +static int check_file (char const *, char const *); + +char * +util_path_search(char const *prog) +{ +#ifdef UNIX + return util_file_search(prog, getenv("PATH"), (char *) "x"); +#else + return util_file_search(prog, NIL(char), (char *) "x"); +#endif +} + + +char * +util_file_search( + char const *file, /* file we're looking for */ + char *path, /* search path, colon separated */ + char const *mode /* "r", "w", or "x" */) +{ + int quit; + char *buffer, *filename, *save_path, *cp; + + if (path == 0 || strcmp(path, "") == 0) { + path = (char *) "."; /* just look in the current directory */ + } + + save_path = path = strsav(path); + quit = 0; + do { + cp = strchr(path, ':'); + if (cp != 0) { + *cp = '\0'; + } else { + quit = 1; + } + + /* cons up the filename out of the path and file name */ + if (strcmp(path, ".") == 0) { + buffer = strsav(file); + } else { + buffer = ALLOC(char, strlen(path) + strlen(file) + 4); + (void) sprintf(buffer, "%s/%s", path, file); + } + filename = util_tilde_expand(buffer); + FREE(buffer); + + /* see if we can access it */ + if (check_file(filename, mode)) { + FREE(save_path); + return filename; + } + FREE(filename); + path = ++cp; + } while (! quit); + + FREE(save_path); + return 0; +} + + +static int +check_file(char const *filename, char const *mode) +{ +#ifdef UNIX + int access_mode = /*F_OK*/ 0; + + if (strcmp(mode, "r") == 0) { + access_mode = /*R_OK*/ 4; + } else if (strcmp(mode, "w") == 0) { + access_mode = /*W_OK*/ 2; + } else if (strcmp(mode, "x") == 0) { + access_mode = /*X_OK*/ 1; + } + return access(filename, access_mode) == 0; +#else + FILE *fp; + int got_file; + + if (strcmp(mode, "x") == 0) { + mode = "r"; + } + fp = fopen(filename, mode); + got_file = (fp != 0); + if (fp != 0) { + (void) fclose(fp); + } + return got_file; +#endif +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/pipefork.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/pipefork.c new file mode 100644 index 000000000..ead02d43b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/pipefork.c @@ -0,0 +1,93 @@ +/* + * Revision Control Information + * + * $Id: pipefork.c,v 1.7 2012/02/05 05:34:04 fabio Exp fabio $ + * + */ +/* LINTLIBRARY */ + +#include "util.h" +#include + +/* + * util_pipefork - fork a command and set up pipes to and from + * + * Rick L Spickelmier, 3/23/86 + * Richard Rudell, 4/6/86 + * Rick L Spickelmier, 4/30/90, got rid of slimey vfork semantics + * + * Returns: + * 1 for success, with toCommand and fromCommand pointing to the streams + * 0 for failure + */ + +/* ARGSUSED */ +int +util_pipefork( + char * const *argv, /* normal argv argument list */ + FILE **toCommand, /* pointer to the sending stream */ + FILE **fromCommand, /* pointer to the reading stream */ + int *pid) +{ +#ifdef UNIX + int forkpid, waitPid; + int topipe[2], frompipe[2]; + char buffer[1024]; + int status; + + /* create the PIPES... + * fildes[0] for reading from command + * fildes[1] for writing to command + */ + if (pipe(topipe)) return(0); + if (pipe(frompipe)) return(0); + +#ifdef __CYGWIN32__ + if ((forkpid = fork()) == 0) { +#else + if ((forkpid = vfork()) == 0) { +#endif + /* child here, connect the pipes */ + (void) dup2(topipe[0], fileno(stdin)); + (void) dup2(frompipe[1], fileno(stdout)); + + (void) close(topipe[0]); + (void) close(topipe[1]); + (void) close(frompipe[0]); + (void) close(frompipe[1]); + + (void) execvp(argv[0], argv); + (void) sprintf(buffer, "util_pipefork: can not exec %s", argv[0]); + perror(buffer); + (void) _exit(1); + } + + if (pid) { + *pid = forkpid; + } + +#ifdef __CYGWIN32__ + waitPid = waitpid(-1, &status, WNOHANG); +#else + waitPid = wait3(&status, WNOHANG, NULL); +#endif + + /* parent here, use slimey vfork() semantics to get return status */ + if (waitPid == forkpid && WIFEXITED(status)) { + return 0; + } + if ((*toCommand = fdopen(topipe[1], "w")) == NULL) { + return 0; + } + if ((*fromCommand = fdopen(frompipe[0], "r")) == NULL) { + return 0; + } + (void) close(topipe[0]); + (void) close(frompipe[1]); + return 1; +#else + (void) fprintf(stderr, + "util_pipefork: not implemented on your operating system\n"); + return 0; +#endif +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/prtime.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/prtime.c new file mode 100644 index 000000000..236eafb75 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/prtime.c @@ -0,0 +1,21 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + + +/* + * util_print_time -- massage a long which represents a time interval in + * milliseconds, into a string suitable for output + * + * Hack for IBM/PC -- avoids using floating point + */ + +char * +util_print_time(unsigned long t) +{ + static char s[40]; + + (void) sprintf(s, "%lu.%02lu sec", t/1000, (t%1000)/10); + return s; +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/ptime.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/ptime.c new file mode 100644 index 000000000..4510857be --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/ptime.c @@ -0,0 +1,9 @@ +/* LINTLIBRARY */ +#include "util.h" + +/* backwards compatibility */ +long +ptime() +{ + return util_cpu_time(); +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/restart.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/restart.c new file mode 100644 index 000000000..b81dcb8c8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/restart.c @@ -0,0 +1,137 @@ +#include +#include "util.h" + +#if (defined(sun) && ! defined(sparc)) || defined(vax) + +#include +#include +#include + +static char *save_stack_base; +static char *stack_lo_addr; +static char *stack_hi_addr; +static int stack_size; + +static int restart_global_flag; +static char *old_file_name; +static char *new_file_name; + +char *util_save_sp; /* set by util_restart_save_state() */ +extern char *sbrk(); + +static void +grow_stack() +{ + int i, space[256]; + + for(i = 0; i < 256; i++) { + space[i] = 0; + } + if ((char *) &i > stack_lo_addr) { + grow_stack(); + } +} + + +/* ARGSUSED */ +static int +handle_sigquit(int sig, int code, struct sigcontext *scp) +{ + if (util_restart_save_state()) { + /* we are restarting ! -- return from signal */ + + } else { + /* copy stack to user data space */ + stack_lo_addr = util_save_sp; + stack_size = stack_hi_addr - stack_lo_addr + 1; + save_stack_base = sbrk(stack_size); + (void) memcpy(save_stack_base, stack_lo_addr, stack_size); + + /* write a new executable */ + (void) fprintf(stderr, "Writing executable %s ...\n", new_file_name); + (void) util_save_image(old_file_name, new_file_name); + + /* terminate if signal was a QUIT */ + if (sig == SIGQUIT) { + (void) _exit(1); + } + } +} + + +static void +restart_program() +{ + (void) fprintf(stderr, "Continuing execution ...\n"); + + /* create the stack */ + grow_stack(); + +#ifdef vax + asm("movl _util_save_sp,sp"); +#endif +#ifdef sun + asm("movl _util_save_sp,sp"); +#endif + + /* copy the stack back from user space */ + (void) memcpy(stack_lo_addr, save_stack_base, stack_size); + + /* remove the sbrk for the stack */ + if (sbrk(-stack_size) < 0) { + perror("sbrk"); + } + + util_restart_restore_state(); /* jump back into handle_sigquit() */ +} + +void +util_restart(char const *old, char const *neW, int interval) +{ + struct itimerval itimer; + +#ifdef vax +#ifdef ultrix + stack_hi_addr = (char *) 0x7fffe3ff; /* ultrix */ +#else + stack_hi_addr = (char *) 0x7fffebff; /* bsd 4.3 */ +#endif +#endif +#ifdef sun + stack_hi_addr = (char *) 0x0effffff; /* Sun OS 3.2, 3.4 */ +#endif + + old_file_name = old; + new_file_name = neW; + + (void) signal(SIGQUIT, handle_sigquit); + + if (interval > 0) { + (void) signal(SIGVTALRM, handle_sigquit); + itimer.it_interval.tv_sec = interval; + itimer.it_interval.tv_usec = 0; + itimer.it_value.tv_sec = interval; + itimer.it_value.tv_usec = 0; + if (setitimer(ITIMER_VIRTUAL, &itimer, (struct itimerval *) 0) < 0) { + perror("setitimer"); + exit(1); + } + } + + if (restart_global_flag) { + restart_program(); + } + restart_global_flag = 1; +} + +#else + +/* ARGSUSED */ +void +util_restart(char const *old, char const *neW, int interval) +{ + (void) fprintf(stderr, + "util_restart: not supported on your operating system/hardware\n"); +} + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/safe_mem.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/safe_mem.c new file mode 100644 index 000000000..597cc892b --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/safe_mem.c @@ -0,0 +1,97 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + +/* + * These are interface routines to be placed between a program and the + * system memory allocator. + * + * It forces well-defined semantics for several 'borderline' cases: + * + * malloc() of a 0 size object is guaranteed to return something + * which is not 0, and can safely be freed (but not dereferenced) + * free() accepts (silently) an 0 pointer + * realloc of a 0 pointer is allowed, and is equiv. to malloc() + * For the IBM/PC it forces no object > 64K; note that the size argument + * to malloc/realloc is a 'long' to catch this condition + * + * The function pointer MMoutOfMemory() contains a vector to handle a + * 'out-of-memory' error (which, by default, points at a simple wrap-up + * and exit routine). + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern char *MMalloc(long); +extern void MMout_of_memory(long); +extern char *MMrealloc(char *, long); + +void (*MMoutOfMemory)(long) = MMout_of_memory; + +#ifdef __cplusplus +} +#endif + + +/* MMout_of_memory -- out of memory for lazy people, flush and exit */ +void +MMout_of_memory(long size) +{ + (void) fflush(stdout); + (void) fprintf(stderr, "\nout of memory allocating %lu bytes\n", + (unsigned long) size); + exit(1); +} + + +char * +MMalloc(long size) +{ + char *p; + +#ifdef IBMPC + if (size > 65000L) { + if (MMoutOfMemory != (void (*)(long)) 0 ) (*MMoutOfMemory)(size); + return NIL(char); + } +#endif + if (size == 0) size = sizeof(long); + if ((p = (char *) malloc((unsigned long) size)) == NIL(char)) { + if (MMoutOfMemory != 0 ) (*MMoutOfMemory)(size); + return NIL(char); + } + return p; +} + + +char * +MMrealloc(char *obj, long size) +{ + char *p; + +#ifdef IBMPC + if (size > 65000L) { + if (MMoutOfMemory != 0 ) (*MMoutOfMemory)(size); + return NIL(char); + } +#endif + if (obj == NIL(char)) return MMalloc(size); + if (size <= 0) size = sizeof(long); + if ((p = (char *) realloc(obj, (unsigned long) size)) == NIL(char)) { + if (MMoutOfMemory != 0 ) (*MMoutOfMemory)(size); + return NIL(char); + } + return p; +} + + +void +MMfree(char *obj) +{ + if (obj != 0) { + free(obj); + } +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/saveimage.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/saveimage.c new file mode 100644 index 000000000..32332ef40 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/saveimage.c @@ -0,0 +1,229 @@ +/* LINTLIBRARY */ + + +/* + * saveimage.c -- + * + * Function to save an executable copy of the current process's + * image in a file. + * + */ + +#include +#include "util.h" + +#ifdef BSD +#include +#include +#include +#include + +extern int errno; + +#define BUFSIZE 8192 + +extern long lseek(); /* For lint */ +extern int getpagesize(); +extern char *sbrk(); + +static int copy_file(); +static int pad_file(); + + +int +util_save_image(char const *orig_file_name, char const *save_file_name) +{ + int origFd = -1, saveFd = -1; + char *start_data, *end_data, *start_text, *end_round; + struct exec old_hdr, new_hdr; + struct stat old_stat; + int n, page_size, length_text, length_data; + + if ((origFd = open(orig_file_name, 0)) < 0) { + perror(orig_file_name); + (void) fprintf(stderr, "Cannot open original a.out file\n"); + goto bad; + } + + if (fstat(origFd, &old_stat) < 0) { + perror(orig_file_name); + (void) fprintf(stderr, "Cannot stat original a.out file\n"); + goto bad; + } + + /* + * Read the a.out header from the original file. + */ + if (read(origFd, (char *) &old_hdr, sizeof(old_hdr)) != sizeof(old_hdr)) { + perror(orig_file_name); + (void) fprintf(stderr, "Cannot read original a.out header\n"); + goto bad; + } + if (N_BADMAG(old_hdr)) { + (void) fprintf(stderr, "File %s has a bad magic number (%o)\n", + orig_file_name, old_hdr.a_magic); + goto bad; + } + if (old_hdr.a_magic != ZMAGIC) { + (void) fprintf(stderr, "File %s is not demand-paged\n", orig_file_name); + goto bad; + } + + /* + * Open the output file. + */ + if (access(save_file_name, /* F_OK */ 0) == 0) { + (void) unlink(save_file_name); + } + if ((saveFd = creat(save_file_name, 0777)) < 0) { + if (errno == ETXTBSY) { + (void) unlink(save_file_name); + saveFd = creat(save_file_name, 0777); + } + if (saveFd < 0) { + perror(save_file_name); + (void) fprintf(stderr, "Cannot create save file.\n"); + goto bad; + } + } + + /* + * Find out how far the data segment extends. + */ + new_hdr = old_hdr; + end_data = sbrk(0); + page_size = getpagesize(); + n = ((((int) end_data) + page_size - 1) / page_size) * page_size; + end_round = (char *) n; + if (end_round > end_data) { + end_data = sbrk(end_round - end_data); + } + +#ifdef vax + start_text = 0; + length_text = new_hdr.a_text; + start_data = (char *) old_hdr.a_text; + length_data = end_data - start_data; +#endif vax +#ifdef sun + start_text = (char *) N_TXTADDR(old_hdr) + sizeof(old_hdr); + length_text = old_hdr.a_text - sizeof(old_hdr); + start_data = (char *) N_DATADDR(old_hdr); + length_data = end_data - start_data; +#endif sun + new_hdr.a_data = end_data - start_data; + new_hdr.a_bss = 0; + + /* + * First, the header plus enough pad to extend up to N_TXTOFF. + */ + if (write(saveFd, (char *) &new_hdr, (int) sizeof(new_hdr)) != + sizeof(new_hdr)) { + perror("write"); + (void) fprintf(stderr, "Error while copying header.\n"); + goto bad; + } + if (! pad_file(saveFd, N_TXTOFF(old_hdr) - sizeof(new_hdr))) { + (void) fprintf(stderr, "Error while padding.\n"); + goto bad; + } + + + /* + * Copy our text segment + */ + if (write(saveFd, start_text, length_text) != length_text) { + perror("write"); + (void) fprintf(stderr, "Error while copying text segment.\n"); + goto bad; + } + + + /* + * Copy our data segment + */ + if (write(saveFd, start_data, length_data) != length_data) { + perror("write"); + (void) fprintf(stderr, "Error while copying data segment.\n"); + goto bad; + } + + /* + * Copy the symbol table and everything else. + * This takes us to the end of the original file. + */ + (void) lseek(origFd, (long) N_SYMOFF(old_hdr), 0); + if (! copy_file(origFd, saveFd, old_stat.st_size - N_SYMOFF(old_hdr))) { + (void) fprintf(stderr, "Error while copying symbol table.\n"); + goto bad; + } + (void) close(origFd); + (void) close(saveFd); + return 1; + +bad: + if (origFd >= 0) (void) close(origFd); + if (saveFd >= 0) (void) close(saveFd); + return 0; +} + + +static int +copy_file(inFd, outFd, nbytes) +int inFd, outFd; +unsigned long nbytes; +{ + char buf[BUFSIZE]; + int nread, ntoread; + + while (nbytes > 0) { + ntoread = nbytes; + if (ntoread > sizeof buf) ntoread = sizeof buf; + if ((nread = read(inFd, buf, ntoread)) != ntoread) { + perror("read"); + return (0); + } + if (write(outFd, buf, nread) != nread) { + perror("write"); + return (0); + } + nbytes -= nread; + } + + return (1); +} + + +static int +pad_file(outFd, nbytes) +int outFd; +int nbytes; +{ + char buf[BUFSIZE]; + int nzero; + + nzero = (nbytes > sizeof(buf)) ? sizeof(buf) : nbytes; + bzero(buf, nzero); + while (nbytes > 0) { + nzero = (nbytes > sizeof(buf)) ? sizeof(buf) : nbytes; + if (write(outFd, buf, nzero) != nzero) { + perror("write"); + return (0); + } + nbytes -= nzero; + } + + return (1); +} +#else + +/* ARGSUSED */ +int +util_save_image(char const *orig_file_name, char const *save_file_name) +{ + (void) fprintf(stderr, + "util_save_image: not implemented on your operating system\n"); + return 0; +} + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/state.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/state.c new file mode 100644 index 000000000..ef830aa74 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/state.c @@ -0,0 +1,82 @@ +#ifdef lint +util_restart_save_state() +{ + return 0; +} + + +util_restart_restore_state() +{ +} + +#else + +static char rcsid[] = "$Id: state.c,v 1.1 1997/11/04 22:38:50 fabio Exp $"; + +#ifdef vax +int util_restart_state[32]; + +util_restart_save_state() +{ + asm("movl sp,_util_save_sp"); + asm("movl r1,_util_restart_state"); + asm("movl r2,_util_restart_state+4"); + asm("movl r3,_util_restart_state+8"); + asm("movl r4,_util_restart_state+12"); + asm("movl r5,_util_restart_state+16"); + asm("movl r6,_util_restart_state+20"); + asm("movl r7,_util_restart_state+24"); + asm("movl r8,_util_restart_state+28"); + asm("movl r9,_util_restart_state+32"); + asm("movl r10,_util_restart_state+36"); + asm("movl r11,_util_restart_state+40"); + asm("movl 8(fp),_util_restart_state+44"); + asm("movl 12(fp),_util_restart_state+48"); + asm("movl 16(fp),_util_restart_state+52"); + asm("movl $0,r0"); +} + +util_restart_restore_state() +{ + asm("movl _util_restart_state,r1"); + asm("movl _util_restart_state+4,r2"); + asm("movl _util_restart_state+8,r3"); + asm("movl _util_restart_state+12,r4"); + asm("movl _util_restart_state+16,r5"); + asm("movl _util_restart_state+20,r6"); + asm("movl _util_restart_state+24,r7"); + asm("movl _util_restart_state+28,r8"); + asm("movl _util_restart_state+32,r9"); + asm("movl _util_restart_state+36,r10"); + asm("movl _util_restart_state+40,r11"); + asm("movl _util_restart_state+44,ap"); + asm("movl _util_restart_state+48,fp"); + asm("addl3 fp,$4,sp"); + asm("movl _util_restart_state+52,r0"); + asm("jmp (r0)"); +} +#endif + + +#if defined(sun) && ! defined(sparc) +int util_restart_state[32]; + +util_restart_save_state() +{ + asm("movel sp,_util_save_sp"); + asm("movel sp@,_util_restart_state"); + asm("movel sp@(0x4),_util_restart_state+4"); + asm("moveml #0xFFFF,_util_restart_state+8"); + return 0; +} + +util_restart_restore_state() +{ + asm("moveml _util_restart_state+8,#0xFFFF"); + asm("movel _util_restart_state+4,sp@(0x4)"); + asm("movel _util_restart_state,sp@"); + return 1; +} +#endif + +#endif diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/strsav.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/strsav.c new file mode 100644 index 000000000..454e237c4 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/strsav.c @@ -0,0 +1,14 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + + +/* + * util_strsav -- save a copy of a string + */ +char * +util_strsav(char const *s) +{ + return strcpy(ALLOC(char, strlen(s)+1), s); +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/stub.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/stub.c new file mode 100644 index 000000000..93f57e67f --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/stub.c @@ -0,0 +1,82 @@ +/* LINTLIBRARY */ + +#ifdef LACK_SYS5 + +char * +memcpy(s1, s2, n) +char *s1, *s2; +int n; +{ + extern bcopy(); + bcopy(s2, s1, n); + return s1; +} + +char * +memset(s, c, n) +char *s; +int c; +int n; +{ + extern bzero(); + register int i; + + if (c == 0) { + bzero(s, n); + } else { + for(i = n-1; i >= 0; i--) { + *s++ = c; + } + } + return s; +} + +char * +strchr(s, c) +char *s; +int c; +{ + extern char *index(); + return index(s, c); +} + +char * +strrchr(s, c) +char *s; +int c; +{ + extern char *rindex(); + return rindex(s, c); +} + + +#endif + +#ifndef UNIX +#include + +FILE * +popen(string, mode) +const char *string; +const char *mode; +{ + (void) fprintf(stderr, "popen not supported on your operating system\n"); + return NULL; +} + + +int +pclose(fp) +FILE *fp; +{ + (void) fprintf(stderr, "pclose not supported on your operating system\n"); + return -1; +} +#endif + +/* put something here in case some compilers abort on empty files ... */ +int +util_do_nothing() +{ + return 1; +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/test-res.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/test-res.c new file mode 100644 index 000000000..e7af9c9fd --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/test-res.c @@ -0,0 +1,57 @@ +#include +#include "util.h" + + +main(argc, argv, environ) +int argc; +char **argv; +char **environ; +{ + int i; + char **ep, *prog; + + prog = util_path_search(argv[0]); + if (prog == NIL(char)) { + (void) fprintf(stderr, "Cannot find current executable\n"); + exit(1); + } + util_restart(prog, "a.out", 0); + + i = recur(10); + (void) fprintf(stderr, "terminated normally with i = %d\n", i); + + (void) printf("argc is %d\n", argc); + + for(i = 0, ep = argv; *ep != 0; i++, ep++) { + (void) printf("%08x (%08x-%08x)\targv[%d]:\t%s\n", + ep, *ep, *ep + strlen(*ep), i, *ep); + } + + i = 0; + for(i = 0, ep = environ; *ep != 0; ep++, i++) { + (void) printf("%08x (%08x-%08x)\tenviron[%d]:\t%s\n", + ep, *ep, *ep + strlen(*ep), i, *ep); + } + + (void) fprintf(stderr, "returning with status=4\n"); + return 4; +} + + +recur(cnt) +{ + int i, j, sum; + + if (cnt > 0) { + return recur(cnt-1); + } else { + sum = 0; + for(j = 0; j < 20; j++) { + for(i = 0; i < 100000; i++) { + sum += 1; + } + (void) printf("done loop %d\n", j); + } + return sum; + } +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/test-sav.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/test-sav.c new file mode 100644 index 000000000..3140671be --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/test-sav.c @@ -0,0 +1,39 @@ +#include +#include "util.h" + + +/* ARGSUSED */ +static int +saveit(prog, file2) +char *prog, *file2; +{ + char *file1; + + /* get current executable name by searching the path ... */ + file1 = util_path_search(prog); + if (file1 == 0) { + (void) fprintf(stderr, "cannot locate current executable\n"); + return 1; + } + + /* users name for the new executable -- perform tilde-expansion */ + if (! util_save_image(file1, file2)) { + (void) fprintf(stderr, "error occured during save ...\n"); + return 1; + } + FREE(file1); + return 0; +} + +int restart; + +main(argc, argv) +char **argv; +{ + if (restart) { + (void) printf("restarted ...\n"); + exit(0); + } + restart = 1; + exit(saveit(argv[0], "foobar")); +} diff --git a/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/texpand.c b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/texpand.c new file mode 100644 index 000000000..c14defee8 --- /dev/null +++ b/resources/3rdparty/cudd-2.5.0/CUDD_Win32/CUDD_Win32/util/texpand.c @@ -0,0 +1,57 @@ +/* LINTLIBRARY */ + +#include +#include "util.h" + +#ifdef BSD +#include +#endif + + +char * +util_tilde_expand(char const *fname) +{ +#ifdef BSD + struct passwd *userRecord; + char username[256], *filename; + register int i, j; + + filename = ALLOC(char, strlen(fname) + 256); + + /* Clear the return string */ + i = 0; + filename[0] = '\0'; + + /* Tilde? */ + if (fname[0] == '~') { + j = 0; + i = 1; + while ((fname[i] != '\0') && (fname[i] != '/')) { + username[j++] = fname[i++]; + } + username[j] = '\0'; + + if (username[0] == '\0') { + /* ~/ resolves to home directory of current user */ + if ((userRecord = getpwuid(getuid())) != 0) { + (void) strcat(filename, userRecord->pw_dir); + } else { + i = 0; + } + } else { + /* ~user/ resolves to home directory of 'user' */ + if ((userRecord = getpwnam(username)) != 0) { + (void) strcat(filename, userRecord->pw_dir); + } else { + i = 0; + } + } + } + + /* Concantenate remaining portion of file name */ + (void) strcat(filename, fname + i); + return filename; +#else + return strsav(fname); +#endif +} From d3c80dca1653f79dc58ad1d38e29f23df1300598 Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 20 May 2013 21:48:19 +0200 Subject: [PATCH 140/152] Updated CMakeLists.txt - Added more sub-folders in the source-structure - Added an option for MSVC to use /bigobj with the Compiler as PrismParser.cpp bloats the object instance count - Edited CUDD Link Targets for MSVC Edited SymbolicModelAdapter.h, added an alternative implementation for log2 (NOT part of C90, not of Cxx!) Edited Program.cpp, promoted vars from int to uint to conquer warnings related to loss of precision Likewise in DeterministicSparseTransitionParser.cpp, IntegerConstantExpression.h Edited storm.cpp, reimplemented Usage-Query for non-Unix platforms. Edited CuddUtility.h, added an include for int Type definitions as they do not fall from the sky Edited ErrorHandling.h. reimplemented ErrorHandling for non-Unix platforms. Backtraces can not yet be provided. --- CMakeLists.txt | 41 ++++++++++++++++--- src/adapters/SymbolicModelAdapter.h | 13 +++++- src/ir/Program.cpp | 14 +++---- .../expressions/IntegerConstantExpression.h | 2 +- .../DeterministicSparseTransitionParser.cpp | 2 +- src/storm.cpp | 36 ++++++++++++++-- src/utility/CuddUtility.h | 2 + src/utility/ErrorHandling.h | 38 +++++++++++++++-- src/utility/OsDetection.h | 15 +++++++ 9 files changed, 140 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a78fb8925..bec5a07dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,6 +90,8 @@ elseif(MSVC) message(STATUS "Using MSVC") # required for GMM to compile, ugly error directive in their code add_definitions(/D_SCL_SECURE_NO_DEPRECATE) + # required as the PRCTL Parser bloats object files (COFF) beyond their maximum size (see http://msdn.microsoft.com/en-us/library/8578y171(v=vs.110).aspx) + add_definitions(/bigobj) else(CLANG) message(STATUS "Using CLANG") # As CLANG is not set as a variable, we need to set it in case we have not matched another compiler. @@ -120,13 +122,19 @@ file(GLOB_RECURSE STORM_MAIN_FILE ${PROJECT_SOURCE_DIR}/src/storm.cpp) set(STORM_SOURCES "${STORM_SOURCES_WITHOUT_MAIN};${STORM_MAIN_FILE}") file(GLOB_RECURSE STORM_ADAPTERS_FILES ${PROJECT_SOURCE_DIR}/src/adapters/*.h ${PROJECT_SOURCE_DIR}/src/adapters/*.cpp) file(GLOB_RECURSE STORM_EXCEPTIONS_FILES ${PROJECT_SOURCE_DIR}/src/exceptions/*.h ${PROJECT_SOURCE_DIR}/src/exceptions/*.cpp) -file(GLOB_RECURSE STORM_FORMULA_FILES ${PROJECT_SOURCE_DIR}/src/formula/*.h ${PROJECT_SOURCE_DIR}/src/formula/*.cpp) +file(GLOB STORM_FORMULA_FILES ${PROJECT_SOURCE_DIR}/src/formula/*.h ${PROJECT_SOURCE_DIR}/src/formula/*.cpp) +file(GLOB_RECURSE STORM_FORMULA_ABSTRACT_FILES ${PROJECT_SOURCE_DIR}/src/formula/abstract/*.h ${PROJECT_SOURCE_DIR}/src/formula/abstract/*.cpp) +file(GLOB_RECURSE STORM_FORMULA_CSL_FILES ${PROJECT_SOURCE_DIR}/src/formula/Csl/*.h ${PROJECT_SOURCE_DIR}/src/formula/Csl/*.cpp) +file(GLOB_RECURSE STORM_FORMULA_LTL_FILES ${PROJECT_SOURCE_DIR}/src/formula/Ltl/*.h ${PROJECT_SOURCE_DIR}/src/formula/Ltl/*.cpp) +file(GLOB_RECURSE STORM_FORMULA_PRCTL_FILES ${PROJECT_SOURCE_DIR}/src/formula/Prctl/*.h ${PROJECT_SOURCE_DIR}/src/formula/Prctl/*.cpp) file(GLOB_RECURSE STORM_MODELCHECKER_FILES ${PROJECT_SOURCE_DIR}/src/modelchecker/*.h ${PROJECT_SOURCE_DIR}/src/modelchecker/*.cpp) file(GLOB_RECURSE STORM_MODELS_FILES ${PROJECT_SOURCE_DIR}/src/models/*.h ${PROJECT_SOURCE_DIR}/src/models/*.cpp) -file(GLOB_RECURSE STORM_PARSER_FILES ${PROJECT_SOURCE_DIR}/src/parser/*.h ${PROJECT_SOURCE_DIR}/src/parser/*.cpp) +file(GLOB STORM_PARSER_FILES ${PROJECT_SOURCE_DIR}/src/parser/*.h ${PROJECT_SOURCE_DIR}/src/parser/*.cpp) +file(GLOB_RECURSE STORM_PARSER_PRISMPARSER_FILES ${PROJECT_SOURCE_DIR}/src/parser/prismparser/*.h ${PROJECT_SOURCE_DIR}/src/parser/prismparser/*.cpp) file(GLOB_RECURSE STORM_STORAGE_FILES ${PROJECT_SOURCE_DIR}/src/storage/*.h ${PROJECT_SOURCE_DIR}/src/storage/*.cpp) file(GLOB_RECURSE STORM_UTILITY_FILES ${PROJECT_SOURCE_DIR}/src/utility/*.h ${PROJECT_SOURCE_DIR}/src/utility/*.cpp) -file(GLOB_RECURSE STORM_IR_FILES ${PROJECT_SOURCE_DIR}/src/ir/*.h ${PROJECT_SOURCE_DIR}/src/ir/*.cpp) +file(GLOB STORM_IR_FILES ${PROJECT_SOURCE_DIR}/src/ir/*.h ${PROJECT_SOURCE_DIR}/src/ir/*.cpp) +file(GLOB_RECURSE STORM_IR_EXPRESSIONS_FILES ${PROJECT_SOURCE_DIR}/src/ir/expressions/*.h ${PROJECT_SOURCE_DIR}/src/ir/expressions/*.cpp) # Test Sources # Note that the tests also need the source files, except for the main file @@ -138,12 +146,18 @@ source_group(main FILES ${STORM_MAIN_FILE}) source_group(adapters FILES ${STORM_ADAPTERS_FILES}) source_group(exceptions FILES ${STORM_EXCEPTIONS_FILES}) source_group(formula FILES ${STORM_FORMULA_FILES}) +source_group(formula\\abstract FILES ${STORM_FORMULA_ABSTRACT_FILES}) +source_group(formula\\csl FILES ${STORM_FORMULA_CSL_FILES}) +source_group(formula\\ltl FILES ${STORM_FORMULA_LTL_FILES}) +source_group(formula\\prctl FILES ${STORM_FORMULA_PRCTL_FILES}) source_group(modelchecker FILES ${STORM_MODELCHECKER_FILES}) source_group(models FILES ${STORM_MODELS_FILES}) source_group(parser FILES ${STORM_PARSER_FILES}) +source_group(parser\\prismparser FILES ${STORM_PARSER_PRISMPARSER_FILES}) source_group(storage FILES ${STORM_STORAGE_FILES}) source_group(utility FILES ${STORM_UTILITY_FILES}) source_group(ir FILES ${STORM_IR_FILES}) +source_group(ir\\expressions FILES ${STORM_IR_EXPRESSIONS_FILES}) source_group(functional-test FILES ${STORM_FUNCTIONAL_TEST_FILES}) source_group(performance-test FILES ${STORM_PERFORMANCE_TEST_FILES}) @@ -236,6 +250,14 @@ target_link_libraries(storm ${Boost_LIBRARIES}) target_link_libraries(storm-functional-tests ${Boost_LIBRARIES}) target_link_libraries(storm-performance-tests ${Boost_LIBRARIES}) +if (MSVC) + # Add the DebugHelper DLL + set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} Dbghelp.lib") + target_link_libraries(storm "Dbghelp.lib") + target_link_libraries(storm-functional-tests "Dbghelp.lib") + target_link_libraries(storm-performance-tests "Dbghelp.lib") +endif(MSVC) + if (USE_INTELTBB) target_link_libraries(storm tbb tbbmalloc) target_link_libraries(storm-functional-tests tbb tbbmalloc) @@ -318,9 +340,16 @@ if (LOG4CPLUS_INCLUDE_DIR) endif(LOG4CPLUS_INCLUDE_DIR) if (CUDD_LIBRARY_DIRS) - target_link_libraries(storm "-lobj -lcudd -lmtr -lst -lutil -lepd") - target_link_libraries(storm-functional-tests "-lobj -lcudd -lmtr -lst -lutil -lepd") - target_link_libraries(storm-performance-tests "-lobj -lcudd -lmtr -lst -lutil -lepd") + if (MSVC) + set(cuddMsvcLibs "optimized" "${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/CUDD_Win32/x64/Release/CUDD_Win32.lib" "debug" "${PROJECT_SOURCE_DIR}/resources/3rdparty/cudd-2.5.0/CUDD_Win32/x64/Debug/CUDD_Win32.lib") + target_link_libraries(storm ${cuddMsvcLibs}) + target_link_libraries(storm-functional-tests ${cuddMsvcLibs}) + target_link_libraries(storm-performance-tests ${cuddMsvcLibs}) + else () + target_link_libraries(storm "-lobj -lcudd -lmtr -lst -lutil -lepd") + target_link_libraries(storm-functional-tests "-lobj -lcudd -lmtr -lst -lutil -lepd") + target_link_libraries(storm-performance-tests "-lobj -lcudd -lmtr -lst -lutil -lepd") + endif () endif(CUDD_LIBRARY_DIRS) if (THREADS_FOUND) diff --git a/src/adapters/SymbolicModelAdapter.h b/src/adapters/SymbolicModelAdapter.h index 06b7dd37f..819133a23 100644 --- a/src/adapters/SymbolicModelAdapter.h +++ b/src/adapters/SymbolicModelAdapter.h @@ -16,6 +16,7 @@ #include "cuddObj.hh" #include #include +#include namespace storm { @@ -138,6 +139,16 @@ private: SymbolicExpressionAdapter rowExpressionAdapter; SymbolicExpressionAdapter columnExpressionAdapter; + // As log2 is not part of C90, only of C99 which no Compiler fully supports, this feature is unavailable on MSVC + inline double log2(uint_fast64_t number) { +# include "src/utility/OsDetection.h" +# ifndef WINDOWS + return std::log2(number); +# else + return std::log(number) / std::log(2); +# endif + } + ADD* getInitialStateDecisionDiagram(storm::ir::Program const& program) { ADD* initialStates = cuddUtility->getOne(); for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { @@ -258,7 +269,7 @@ private: throw storm::exceptions::WrongFormatException() << "Range of variable " << integerVariable.getName() << " is empty or negativ."; } - uint_fast64_t numberOfDecisionDiagramVariables = static_cast(std::ceil(std::log2(integerRange))); + uint_fast64_t numberOfDecisionDiagramVariables = static_cast(std::ceil(log2(integerRange))); std::vector allRowDecisionDiagramVariablesForVariable; std::vector allColumnDecisionDiagramVariablesForVariable; diff --git a/src/ir/Program.cpp b/src/ir/Program.cpp index 96ad94b2b..c854bc645 100644 --- a/src/ir/Program.cpp +++ b/src/ir/Program.cpp @@ -119,24 +119,24 @@ std::map> P } std::string Program::getVariableString() const { - std::map bools; - std::map ints; - unsigned maxInt = 0, maxBool = 0; + std::map bools; + std::map ints; + uint_fast64_t maxInt = 0, maxBool = 0; for (Module module: this->modules) { - for (unsigned int i = 0; i < module.getNumberOfBooleanVariables(); i++) { + for (uint_fast64_t i = 0; i < module.getNumberOfBooleanVariables(); i++) { storm::ir::BooleanVariable var = module.getBooleanVariable(i); bools[var.getIndex()] = var.getName(); if (var.getIndex() >= maxBool) maxBool = var.getIndex()+1; } - for (unsigned int i = 0; i < module.getNumberOfIntegerVariables(); i++) { + for (uint_fast64_t i = 0; i < module.getNumberOfIntegerVariables(); i++) { storm::ir::IntegerVariable var = module.getIntegerVariable(i); ints[var.getIndex()] = var.getName(); if (var.getIndex() >= maxInt) maxInt = var.getIndex()+1; } } std::stringstream ss; - for (unsigned int i = 0; i < maxBool; i++) ss << bools[i] << "\t"; - for (unsigned int i = 0; i < maxInt; i++) ss << ints[i] << "\t"; + for (uint_fast64_t i = 0; i < maxBool; i++) ss << bools[i] << "\t"; + for (uint_fast64_t i = 0; i < maxInt; i++) ss << ints[i] << "\t"; return ss.str(); } diff --git a/src/ir/expressions/IntegerConstantExpression.h b/src/ir/expressions/IntegerConstantExpression.h index c4ad56ed7..1cc3450e5 100644 --- a/src/ir/expressions/IntegerConstantExpression.h +++ b/src/ir/expressions/IntegerConstantExpression.h @@ -62,7 +62,7 @@ public: return defined; } - int getValue() { + int_fast64_t getValue() { return value; } diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp index 62e6481cc..d28e1c0d3 100644 --- a/src/parser/DeterministicSparseTransitionParser.cpp +++ b/src/parser/DeterministicSparseTransitionParser.cpp @@ -59,7 +59,7 @@ uint_fast64_t DeterministicSparseTransitionParser::firstPass(char* buf, uint_fas * Check all transitions for non-zero diagonal entries and deadlock states. */ int_fast64_t lastRow = -1; - int_fast64_t row, col; + uint_fast64_t row, col; uint_fast64_t readTransitionCount = 0; bool rowHadDiagonalEntry = false; double val; diff --git a/src/storm.cpp b/src/storm.cpp index 548399d38..3c3d47679 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -45,17 +45,47 @@ #include "src/exceptions/InvalidSettingsException.h" -#include -#include #include #include void printUsage() { +#ifndef WINDOWS struct rusage ru; getrusage(RUSAGE_SELF, &ru); std::cout << "Memory Usage: " << ru.ru_maxrss << "kB" << std::endl; - std::cout << "CPU time: " << ru.ru_utime.tv_sec << "." << std::setw(3) << std::setfill('0') << ru.ru_utime.tv_usec/1000 << " seconds" << std::endl; + std::cout << "CPU Time: " << ru.ru_utime.tv_sec << "." << std::setw(3) << std::setfill('0') << ru.ru_utime.tv_usec/1000 << " seconds" << std::endl; +#else + HANDLE hProcess = GetCurrentProcess (); + FILETIME ftCreation, ftExit, ftUser, ftKernel; + PROCESS_MEMORY_COUNTERS pmc; + if (GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc))) { + std::cout << "Memory Usage: " << std::endl; + std::cout << "\tPageFaultCount: " << pmc.PageFaultCount << std::endl; + std::cout << "\tPeakWorkingSetSize: " << pmc.PeakWorkingSetSize << std::endl; + std::cout << "\tWorkingSetSize: " << pmc.WorkingSetSize << std::endl; + std::cout << "\tQuotaPeakPagedPoolUsage: " << pmc.QuotaPeakPagedPoolUsage << std::endl; + std::cout << "\tQuotaPagedPoolUsage: " << pmc.QuotaPagedPoolUsage << std::endl; + std::cout << "\tQuotaPeakNonPagedPoolUsage: " << pmc.QuotaPeakNonPagedPoolUsage << std::endl; + std::cout << "\tQuotaNonPagedPoolUsage: " << pmc.QuotaNonPagedPoolUsage << std::endl; + std::cout << "\tPagefileUsage:" << pmc.PagefileUsage << std::endl; + std::cout << "\tPeakPagefileUsage: " << pmc.PeakPagefileUsage << std::endl; + } + + GetProcessTimes (hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser); + + ULARGE_INTEGER uLargeInteger; + uLargeInteger.LowPart = ftKernel.dwLowDateTime; + uLargeInteger.HighPart = ftKernel.dwHighDateTime; + double kernelTime = uLargeInteger.QuadPart / 10000.0; // 100 ns Resolution to milliseconds + uLargeInteger.LowPart = ftUser.dwLowDateTime; + uLargeInteger.HighPart = ftUser.dwHighDateTime; + double userTime = uLargeInteger.QuadPart / 10000.0; + + std::cout << "CPU Time: " << std::endl; + std::cout << "\tKernel Time: " << std::setprecision(3) << kernelTime << std::endl; + std::cout << "\tUser Time: " << std::setprecision(3) << userTime << std::endl; +#endif } diff --git a/src/utility/CuddUtility.h b/src/utility/CuddUtility.h index 8102eb012..2832884a2 100644 --- a/src/utility/CuddUtility.h +++ b/src/utility/CuddUtility.h @@ -10,6 +10,8 @@ #include "cuddObj.hh" +#include "boost/integer/integer_mask.hpp" + namespace storm { namespace utility { diff --git a/src/utility/ErrorHandling.h b/src/utility/ErrorHandling.h index ea65ab03a..b832b7c69 100644 --- a/src/utility/ErrorHandling.h +++ b/src/utility/ErrorHandling.h @@ -8,9 +8,9 @@ #ifndef ERRORHANDLING_H #define ERRORHANDLING_H +#include "src/utility/OsDetection.h" #include -#include -#include + /* * Demangles the given string. This is needed for the correct display of backtraces. @@ -22,16 +22,42 @@ std::string demangle(char const* symbol) { // Attention: sscanf format strings rely on the size being 128. char temp[128]; - char* demangled; - // Check for C++ symbol. + // Check for C++ symbol, on Non-MSVC Only if (sscanf(symbol, "%*[^(]%*[^_]%127[^)+]", temp) == 1) { +#ifndef WINDOWS + char* demangled; if (NULL != (demangled = abi::__cxa_demangle(temp, NULL, NULL, &status))) { std::string result(demangled); free(demangled); return result; } +#else + DWORD error; + HANDLE hProcess; + + SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); + + hProcess = GetCurrentProcess(); + + if (!SymInitialize(hProcess, NULL, TRUE)) { + // SymInitialize failed + error = GetLastError(); + LOG4CPLUS_ERROR(logger, "SymInitialize returned error : " << error); + return FALSE; + } else { + char demangled[1024]; + if (UnDecorateSymbolName(temp, demangled, sizeof(demangled), UNDNAME_COMPLETE)) { + return std::string(demangled); + } else { + // UnDecorateSymbolName failed + DWORD error = GetLastError(); + LOG4CPLUS_ERROR(logger, "UnDecorateSymbolName returned error: " << error); + } + } +#endif } + // Check for C symbol. if (sscanf(symbol, "%127s", temp) == 1) { return temp; @@ -50,6 +76,7 @@ void signalHandler(int sig) { #define SIZE 128 LOG4CPLUS_FATAL(logger, "The program received signal " << sig << ". The following backtrace shows the status upon reception of the signal."); +#ifndef WINDOWS void *buffer[SIZE]; char **strings; int nptrs; @@ -68,6 +95,9 @@ void signalHandler(int sig) { LOG4CPLUS_FATAL(logger, nptrs-j << ": " << demangle(strings[j])); } free(strings); +#else + LOG4CPLUS_WARN(logger, "No Backtrace Support available on Platform Windows!"); +#endif LOG4CPLUS_FATAL(logger, "Exiting."); exit(2); } diff --git a/src/utility/OsDetection.h b/src/utility/OsDetection.h index bc459d40c..8fb6c7c6e 100644 --- a/src/utility/OsDetection.h +++ b/src/utility/OsDetection.h @@ -4,17 +4,32 @@ #if defined __linux__ || defined __linux # define LINUX # include +#include // Required by ErrorHandling.h +#include // Required by ErrorHandling.h +#include // Required by storm.cpp, Memory Usage +#include // Required by storm.cpp, Memory Usage #elif defined TARGET_OS_MAC || defined __apple__ || defined __APPLE__ # define MACOSX # define _DARWIN_USE_64_BIT_INODE # include # include +# include // Required by ErrorHandling.h +# include // Required by ErrorHandling.h +# include // Required by storm.cpp, Memory Usage +# include // Required by storm.cpp, Memory Usage #elif defined _WIN32 || defined _WIN64 # define WINDOWS # define NOMINMAX # include # include +# include +# include # define strncpy strncpy_s +# define sscanf sscanf_s + +// This disables Warning C4250 - Diamond Inheritance Dominance +#pragma warning(disable:4250) + #else # error Could not detect Operating System #endif From 6920e1ccdd81f0bc2b4ce4adf65d9c1ae96679da Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 22 May 2013 11:15:44 +0200 Subject: [PATCH 141/152] Added static_casts and changed some types to signed instead of unsigned to eliminate some warnings of MSVC. --- src/adapters/SymbolicExpressionAdapter.h | 8 ++++---- src/adapters/SymbolicModelAdapter.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/adapters/SymbolicExpressionAdapter.h b/src/adapters/SymbolicExpressionAdapter.h index 2e07bae83..fd23864b7 100644 --- a/src/adapters/SymbolicExpressionAdapter.h +++ b/src/adapters/SymbolicExpressionAdapter.h @@ -158,12 +158,12 @@ public: } storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); - stack.push(new ADD(*cuddUtility->getConstant(expression->getValue()))); + stack.push(new ADD(*cuddUtility->getConstant(static_cast(expression->getValue())))); } virtual void visit(storm::ir::expressions::IntegerLiteral* expression) { storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance(); - stack.push(new ADD(*cuddUtility->getConstant(expression->getValueAsInt(nullptr)))); + stack.push(new ADD(*cuddUtility->getConstant(static_cast(expression->getValueAsInt(nullptr))))); } virtual void visit(storm::ir::expressions::UnaryBooleanFunctionExpression* expression) { @@ -211,8 +211,8 @@ public: int64_t low = expression->getLowerBound()->getValueAsInt(nullptr); int64_t high = expression->getUpperBound()->getValueAsInt(nullptr); - for (uint_fast64_t i = low; i <= high; ++i) { - cuddUtility->setValueAtIndex(result, i - low, variables, i); + for (int_fast64_t i = low; i <= high; ++i) { + cuddUtility->setValueAtIndex(result, i - low, variables, static_cast(i)); } } diff --git a/src/adapters/SymbolicModelAdapter.h b/src/adapters/SymbolicModelAdapter.h index 819133a23..0ab93ac4d 100644 --- a/src/adapters/SymbolicModelAdapter.h +++ b/src/adapters/SymbolicModelAdapter.h @@ -81,8 +81,8 @@ public: int_fast64_t low = integerVariable.getLowerBound()->getValueAsInt(nullptr); int_fast64_t high = integerVariable.getUpperBound()->getValueAsInt(nullptr); - for (uint_fast64_t i = low; i <= high; ++i) { - cuddUtility->setValueAtIndex(temporary, i - low, variableToColumnDecisionDiagramVariableMap[assignmentPair.first], i); + for (int_fast64_t i = low; i <= high; ++i) { + cuddUtility->setValueAtIndex(temporary, i - low, variableToColumnDecisionDiagramVariableMap[assignmentPair.first], static_cast(i)); } ADD* result = new ADD(*updateExpr * *guard); @@ -194,7 +194,7 @@ private: cuddUtility->dumpDotToFile(newReachableStates, "reach1.add"); - newReachableStates = cuddUtility->permuteVariables(newReachableStates, allColumnDecisionDiagramVariables, allRowDecisionDiagramVariables, allDecisionDiagramVariables.size()); + newReachableStates = cuddUtility->permuteVariables(newReachableStates, allColumnDecisionDiagramVariables, allRowDecisionDiagramVariables, static_cast(allDecisionDiagramVariables.size())); *newReachableStates += *reachableStates; newReachableStates = new ADD(newReachableStates->GreaterThan(*cuddUtility->getZero())); @@ -232,7 +232,7 @@ private: int_fast64_t low = integerVariable.getLowerBound()->getValueAsInt(nullptr); int_fast64_t high = integerVariable.getUpperBound()->getValueAsInt(nullptr); - for (uint_fast64_t i = low; i <= high; ++i) { + for (int_fast64_t i = low; i <= high; ++i) { cuddUtility->setValueAtIndices(identity, i - low, i - low, variableToRowDecisionDiagramVariableMap[integerVariable.getName()], variableToColumnDecisionDiagramVariableMap[integerVariable.getName()], 1); From 28facf903470d94f6e60f2424db72619d414d22a Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 22 May 2013 14:07:13 +0200 Subject: [PATCH 143/152] Fixed bug in iterator. --- src/storage/SparseMatrix.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/SparseMatrix.h b/src/storage/SparseMatrix.h index a968f7ee5..850daf382 100644 --- a/src/storage/SparseMatrix.h +++ b/src/storage/SparseMatrix.h @@ -71,7 +71,7 @@ public: * * @param matrix The matrix on which this iterator operates. */ - ConstRowsIterator(SparseMatrix const& matrix, uint_fast64_t rowIndex = 0) : matrix(matrix), posIndex(0), rowIndex(0) { + ConstRowsIterator(SparseMatrix const& matrix, uint_fast64_t row = 0) : matrix(matrix), posIndex(matrix.rowIndications[row]), rowIndex(row) { // Intentionally left empty. } From 92fe0519241453933f80d261d233b2ef439c7634 Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 22 May 2013 14:07:54 +0200 Subject: [PATCH 144/152] Added some newlines. --- src/modelchecker/GmmxxMdpPrctlModelChecker.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modelchecker/GmmxxMdpPrctlModelChecker.h b/src/modelchecker/GmmxxMdpPrctlModelChecker.h index 3b340dadf..d742d55ed 100644 --- a/src/modelchecker/GmmxxMdpPrctlModelChecker.h +++ b/src/modelchecker/GmmxxMdpPrctlModelChecker.h @@ -68,9 +68,11 @@ private: // Now perform matrix-vector multiplication as long as we meet the bound of the formula. for (uint_fast64_t i = 0; i < n; ++i) { gmm::mult(*gmmxxMatrix, x, multiplyResult); + if (b != nullptr) { gmm::add(*b, multiplyResult); } + if (this->minimumOperatorStack.top()) { storm::utility::reduceVectorMin(multiplyResult, &x, nondeterministicChoiceIndices); } else { @@ -119,7 +121,7 @@ private: // Compute x' = A*x + b. gmm::mult(*gmmxxMatrix, *currentX, multiplyResult); gmm::add(b, multiplyResult); - + // Reduce the vector x' by applying min/max for all non-deterministic choices. if (this->minimumOperatorStack.top()) { storm::utility::reduceVectorMin(multiplyResult, newX, nondeterministicChoiceIndices); From 64a27bb871b055fa67e99be454db3dd2395c6d84 Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 22 May 2013 14:56:26 +0200 Subject: [PATCH 145/152] Performance improvement for our matrix multiplication. --- src/storage/SparseMatrix.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/storage/SparseMatrix.h b/src/storage/SparseMatrix.h index 850daf382..566629f3c 100644 --- a/src/storage/SparseMatrix.h +++ b/src/storage/SparseMatrix.h @@ -961,12 +961,12 @@ public: // product of the corresponding row with the input vector. // Note that only the end iterator has to be moved by one row, because the other iterator // is automatically moved forward one row by the inner loop. - for (uint_fast64_t i = 0; i < result.size(); ++i, elementIte.moveToNextRow()) { - result[i] = storm::utility::constGetZero(); + for (auto it = result.begin(), ite = result.end(); it != ite; ++it, elementIte.moveToNextRow()) { + *it = storm::utility::constGetZero(); // Perform the scalar product. for (; elementIt != elementIte; ++elementIt) { - result[i] += elementIt.value() * vector[elementIt.column()]; + *it += elementIt.value() * vector[elementIt.column()]; } } } From 6b90439424f76d423b4938f5b0de29b37ee76f2a Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 22 May 2013 14:57:47 +0200 Subject: [PATCH 146/152] Added functional test for the SparseMdpPrctlModelChecker. Fixed performance tests. --- .../SparseMdpPrctlModelCheckerTest.cpp | 259 ++++++++++++++++++ test/functional/storm-functional-tests.cpp | 32 +-- .../GmmxxDtmcPrctModelCheckerTest.cpp | 4 +- .../GmmxxMdpPrctModelCheckerTest.cpp | 12 +- .../SparseMdpPrctlModelCheckerTest.cpp | 244 +++++++++++++++++ test/performance/storm-performance-tests.cpp | 29 +- 6 files changed, 524 insertions(+), 56 deletions(-) create mode 100644 test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp create mode 100644 test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp diff --git a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp new file mode 100644 index 000000000..6efb4653a --- /dev/null +++ b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp @@ -0,0 +1,259 @@ +#include "gtest/gtest.h" +#include "storm-config.h" + +#include "src/utility/Settings.h" +#include "src/modelchecker/SparseMdpPrctlModelChecker.h" +#include "src/parser/AutoParser.h" + +TEST(SparseMdpPrctlModelCheckerTest, Dice) { + storm::settings::Settings* s = storm::settings::instance(); + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew"); + + ASSERT_EQ(parser.getType(), storm::models::MDP); + + std::shared_ptr> mdp = parser.getModel>(); + + ASSERT_EQ(mdp->getNumberOfStates(), 169u); + ASSERT_EQ(mdp->getNumberOfTransitions(), 436u); + + storm::modelchecker::SparseMdpPrctlModelChecker mc(*mdp); + + storm::property::prctl::Ap* apFormula = new storm::property::prctl::Ap("two"); + storm::property::prctl::Eventually* eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + storm::property::prctl::ProbabilisticNoBoundOperator* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + std::vector* result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + ASSERT_LT(std::abs((*result)[0] - 0.0277777612209320068), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("two"); + eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_LT(std::abs((*result)[0] - 0.0277777612209320068), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("three"); + eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_LT(std::abs((*result)[0] - 0.0555555224418640136), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("three"); + eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_LT(std::abs((*result)[0] - 0.0555555224418640136), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("four"); + eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_LT(std::abs((*result)[0] - 0.083333283662796020508), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("four"); + eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_LT(std::abs((*result)[0] - 0.083333283662796020508), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("done"); + storm::property::prctl::ReachabilityReward* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + storm::property::prctl::RewardNoBoundOperator* rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, true); + + result = mc.checkNoBoundOperator(*rewardFormula); + + ASSERT_LT(std::abs((*result)[0] - 7.3333294987678527832), s->get("precision")); + + delete rewardFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("done"); + reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, false); + + result = mc.checkNoBoundOperator(*rewardFormula);; + + ASSERT_LT(std::abs((*result)[0] - 7.3333294987678527832), s->get("precision")); + + delete rewardFormula; + delete result; + + storm::parser::AutoParser stateRewardParser(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", ""); + + ASSERT_EQ(stateRewardParser.getType(), storm::models::MDP); + + std::shared_ptr> stateRewardMdp = stateRewardParser.getModel>(); + + storm::modelchecker::SparseMdpPrctlModelChecker stateRewardModelChecker(*stateRewardMdp); + + apFormula = new storm::property::prctl::Ap("done"); + reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, true); + + result = stateRewardModelChecker.checkNoBoundOperator(*rewardFormula); + + ASSERT_LT(std::abs((*result)[0] - 7.3333294987678527832), s->get("precision")); + + delete rewardFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("done"); + reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, false); + + result = stateRewardModelChecker.checkNoBoundOperator(*rewardFormula); + + ASSERT_LT(std::abs((*result)[0] - 7.3333294987678527832), s->get("precision")); + + delete rewardFormula; + delete result; + + storm::parser::AutoParser stateAndTransitionRewardParser(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew"); + + ASSERT_EQ(stateAndTransitionRewardParser.getType(), storm::models::MDP); + + std::shared_ptr> stateAndTransitionRewardMdp = stateAndTransitionRewardParser.getModel>(); + + storm::modelchecker::SparseMdpPrctlModelChecker stateAndTransitionRewardModelChecker(*stateAndTransitionRewardMdp); + + apFormula = new storm::property::prctl::Ap("done"); + reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, true); + + result = stateAndTransitionRewardModelChecker.checkNoBoundOperator(*rewardFormula); + + ASSERT_LT(std::abs((*result)[0] - (2 * 7.3333294987678527832)), s->get("precision")); + + delete rewardFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("done"); + reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, false); + + result = stateAndTransitionRewardModelChecker.checkNoBoundOperator(*rewardFormula); + + ASSERT_LT(std::abs((*result)[0] - (2 * 7.3333294987678527832)), s->get("precision")); + + delete rewardFormula; + delete result; +} + +TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { + storm::settings::Settings* s = storm::settings::instance(); + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.trans.rew"); + + ASSERT_EQ(parser.getType(), storm::models::MDP); + + std::shared_ptr> mdp = parser.getModel>(); + + ASSERT_EQ(mdp->getNumberOfStates(), 3172u); + ASSERT_EQ(mdp->getNumberOfTransitions(), 7144u); + + storm::modelchecker::SparseMdpPrctlModelChecker mc(*mdp); + + storm::property::prctl::Ap* apFormula = new storm::property::prctl::Ap("elected"); + storm::property::prctl::Eventually* eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + storm::property::prctl::ProbabilisticNoBoundOperator* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + std::vector* result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + storm::property::prctl::BoundedEventually* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 25); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, true); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 0.0625), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 25); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, false); + + result = mc.checkNoBoundOperator(*probFormula); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 0.0625), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + storm::property::prctl::ReachabilityReward* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + storm::property::prctl::RewardNoBoundOperator* rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, true); + + result = mc.checkNoBoundOperator(*rewardFormula);; + + ASSERT_LT(std::abs((*result)[0] - 4.28568908480604982), s->get("precision")); + + delete rewardFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, false); + + result = mc.checkNoBoundOperator(*rewardFormula);; + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 4.2856904354441400784), s->get("precision")); + + delete rewardFormula; + delete result; +} diff --git a/test/functional/storm-functional-tests.cpp b/test/functional/storm-functional-tests.cpp index abfb5a125..f2ebcc8a4 100644 --- a/test/functional/storm-functional-tests.cpp +++ b/test/functional/storm-functional-tests.cpp @@ -31,39 +31,21 @@ void setUpLogging() { } /*! - * Function that parses the command line options. - * @param argc The argc argument of main(). - * @param argv The argv argument of main(). - * @return True iff the program should continue to run after parsing the options. + * Creates an empty settings object as the standard instance of the Settings class. */ -bool parseOptions(int const argc, char const * const argv[]) { - storm::settings::Settings* s = nullptr; - try { - storm::settings::Settings::registerModule>(); - s = storm::settings::newInstance(argc, argv, nullptr, true); - } catch (storm::exceptions::InvalidSettingsException& e) { - std::cout << "Could not recover from settings error: " << e.what() << "." << std::endl; - std::cout << std::endl << storm::settings::help; - return false; - } - - if (s->isSet("help")) { - std::cout << storm::settings::help; - return false; - } - - return true; +void createEmptyOptions() { + storm::settings::Settings::registerModule>(); + const char* newArgv[] = {"storm-performance-tests"}; + storm::settings::Settings* s = storm::settings::newInstance(1, newArgv, nullptr, true); } int main(int argc, char* argv[]) { setUpLogging(); - if (!parseOptions(argc, argv)) { - return 0; - } + createEmptyOptions(); std::cout << "StoRM (Functional) Testing Suite" << std::endl; testing::InitGoogleTest(&argc, argv); - + int result = RUN_ALL_TESTS(); logger.closeNestedAppenders(); diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp index bf0a72403..8eabed62f 100644 --- a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp @@ -4,7 +4,7 @@ #include "src/modelchecker/GmmxxDtmcPrctlModelChecker.h" #include "src/parser/AutoParser.h" -TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { +TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", ""); @@ -65,7 +65,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { } -TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { +TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.pick.trans.rew"); diff --git a/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp index 971c7ec09..c67fa0080 100644 --- a/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp @@ -5,7 +5,7 @@ #include "src/modelchecker/GmmxxMdpPrctlModelChecker.h" #include "src/parser/AutoParser.h" -TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { +TEST(GmmxxMdpPrctlModelCheckerTest, AsynchronousLeader) { storm::settings::Settings* s = storm::settings::instance(); storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.trans.rew"); @@ -107,7 +107,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { delete result; } -TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { +TEST(GmmxxMdpPrctlModelCheckerTest, Consensus) { storm::settings::Settings* s = storm::settings::instance(); s->set("maxiter", 20000); @@ -164,8 +164,8 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { result = mc.checkNoBoundOperator(*probFormula); LOG4CPLUS_WARN(logger, "Done."); - ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[31168] - 0.5282872761373342829216), s->get("precision")); + ASSERT_NE(nullptr, result); + ASSERT_LT(std::abs((*result)[31168] - 0.52932863686144482340267813924583606421947479248047), s->get("precision")); delete probFormula; delete result; @@ -182,7 +182,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[31168] - 0.10343451035775527713), s->get("precision")); + ASSERT_LT(std::abs((*result)[31168] - 0.1041409700076474653673841), s->get("precision")); delete probFormula; delete result; @@ -238,7 +238,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) { LOG4CPLUS_WARN(logger, "Done."); ASSERT_NE(nullptr, result); - ASSERT_LT(std::abs((*result)[31168] - 2179.014847073392047605011), s->get("precision")); + ASSERT_LT(std::abs((*result)[31168] - 2183.1424220082612919213715), s->get("precision")); delete rewardFormula; delete result; diff --git a/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp new file mode 100644 index 000000000..961996899 --- /dev/null +++ b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp @@ -0,0 +1,244 @@ +#include "gtest/gtest.h" +#include "storm-config.h" + +#include "src/utility/Settings.h" +#include "src/modelchecker/SparseMdpPrctlModelChecker.h" +#include "src/parser/AutoParser.h" + +TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { + storm::settings::Settings* s = storm::settings::instance(); + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.trans.rew"); + + ASSERT_EQ(parser.getType(), storm::models::MDP); + + std::shared_ptr> mdp = parser.getModel>(); + + ASSERT_EQ(mdp->getNumberOfStates(), 2095783u); + ASSERT_EQ(mdp->getNumberOfTransitions(), 7714385u); + + storm::modelchecker::SparseMdpPrctlModelChecker mc(*mdp); + + storm::property::prctl::Ap* apFormula = new storm::property::prctl::Ap("elected"); + storm::property::prctl::Eventually* eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + storm::property::prctl::ProbabilisticNoBoundOperator* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F elected] on asynchronous_leader/leader7..."); + std::vector* result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_NE(nullptr, result); + ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); + + LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F elected] on asynchronous_leader/leader7..."); + result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 1), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + storm::property::prctl::BoundedEventually* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 25); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, true); + + LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F<=25 elected] on asynchronous_leader/leader7..."); + result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 0), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 25); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, false); + + LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F<=25 elected] on asynchronous_leader/leader7..."); + result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_NE(nullptr, result); + ASSERT_LT(std::abs((*result)[0] - 0), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + storm::property::prctl::ReachabilityReward* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + storm::property::prctl::RewardNoBoundOperator* rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, true); + + LOG4CPLUS_WARN(logger, "Model Checking Rmin=? [F elected] on asynchronous_leader/leader7..."); + result = mc.checkNoBoundOperator(*rewardFormula); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_LT(std::abs((*result)[0] - 6.172433512), s->get("precision")); + + delete rewardFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("elected"); + reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, false); + + LOG4CPLUS_WARN(logger, "Model Checking Rmax=? [F elected] on asynchronous_leader/leader7..."); + result = mc.checkNoBoundOperator(*rewardFormula); + LOG4CPLUS_WARN(logger, "Done"); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[0] - 6.1724344), s->get("precision")); + + delete rewardFormula; + delete result; +} + +TEST(SparseMdpPrctlModelCheckerTest, Consensus) { + storm::settings::Settings* s = storm::settings::instance(); + // Increase the maximal number of iterations, because the solver does not converge otherwise. + s->set("maxiter", 20000); + + storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", ""); + + ASSERT_EQ(parser.getType(), storm::models::MDP); + + std::shared_ptr> mdp = parser.getModel>(); + + ASSERT_EQ(mdp->getNumberOfStates(), 63616u); + ASSERT_EQ(mdp->getNumberOfTransitions(), 213472u); + + storm::modelchecker::SparseMdpPrctlModelChecker mc(*mdp); + + storm::property::prctl::Ap* apFormula = new storm::property::prctl::Ap("finished"); + storm::property::prctl::Eventually* eventuallyFormula = new storm::property::prctl::Eventually(apFormula); + storm::property::prctl::ProbabilisticNoBoundOperator* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F finished] on consensus/coin4_6..."); + std::vector* result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_NE(nullptr, result); + + ASSERT_LT(std::abs((*result)[31168] - 1), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + storm::property::prctl::Ap* apFormula2 = new storm::property::prctl::Ap("all_coins_equal_0"); + storm::property::prctl::And* andFormula = new storm::property::prctl::And(apFormula, apFormula2); + eventuallyFormula = new storm::property::prctl::Eventually(andFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F finished & all_coins_equal_0] on consensus/coin4_6..."); + result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_NE(nullptr, result); + ASSERT_LT(std::abs((*result)[31168] - 0.43742828319177884388579), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + apFormula2 = new storm::property::prctl::Ap("all_coins_equal_1"); + andFormula = new storm::property::prctl::And(apFormula, apFormula2); + eventuallyFormula = new storm::property::prctl::Eventually(andFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); + + LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F finished & all_coins_equal_1] on consensus/coin4_6..."); + result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_NE(nullptr, result); + ASSERT_LT(std::abs((*result)[31168] - 0.52932863686144482340267813924583606421947479248047), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + apFormula2 = new storm::property::prctl::Ap("agree"); + storm::property::prctl::Not* notFormula = new storm::property::prctl::Not(apFormula2); + andFormula = new storm::property::prctl::And(apFormula, notFormula); + eventuallyFormula = new storm::property::prctl::Eventually(andFormula); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(eventuallyFormula, false); + + LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F finished & !agree] on consensus/coin4_6..."); + result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_NE(nullptr, result); + ASSERT_LT(std::abs((*result)[31168] - 0.1041409700076474653673841), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + storm::property::prctl::BoundedEventually* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 50); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, true); + + LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F<=50 finished] on consensus/coin4_6..."); + result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_NE(nullptr, result); + ASSERT_LT(std::abs((*result)[31168] - 0), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + boundedEventuallyFormula = new storm::property::prctl::BoundedEventually(apFormula, 50); + probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator(boundedEventuallyFormula, false); + + LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F<=50 finished] on consensus/coin4_6..."); + result = mc.checkNoBoundOperator(*probFormula); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_NE(nullptr, result); + ASSERT_LT(std::abs((*result)[31168] - 0), s->get("precision")); + + delete probFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + storm::property::prctl::ReachabilityReward* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + storm::property::prctl::RewardNoBoundOperator* rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, true); + + LOG4CPLUS_WARN(logger, "Model Checking Rmin=? [F finished] on consensus/coin4_6..."); + result = mc.checkNoBoundOperator(*rewardFormula); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_NE(nullptr, result); + ASSERT_LT(std::abs((*result)[31168] - 1725.5933133943854045), s->get("precision")); + + delete rewardFormula; + delete result; + + apFormula = new storm::property::prctl::Ap("finished"); + reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward(apFormula); + rewardFormula = new storm::property::prctl::RewardNoBoundOperator(reachabilityRewardFormula, false); + + LOG4CPLUS_WARN(logger, "Model Checking Rmax=? [F finished] on consensus/coin4_6..."); + result = mc.checkNoBoundOperator(*rewardFormula); + LOG4CPLUS_WARN(logger, "Done."); + + ASSERT_NE(nullptr, result); + ASSERT_LT(std::abs((*result)[31168] - 2183.1424220082612919213715), s->get("precision")); + + delete rewardFormula; + delete result; + +} \ No newline at end of file diff --git a/test/performance/storm-performance-tests.cpp b/test/performance/storm-performance-tests.cpp index 49983a9e1..b35e4f1aa 100644 --- a/test/performance/storm-performance-tests.cpp +++ b/test/performance/storm-performance-tests.cpp @@ -31,34 +31,17 @@ void setUpLogging() { } /*! - * Function that parses the command line options. - * @param argc The argc argument of main(). - * @param argv The argv argument of main(). - * @return True iff the program should continue to run after parsing the options. + * Creates an empty settings object as the standard instance of the Settings class. */ -bool parseOptions(int const argc, char const * const argv[]) { - storm::settings::Settings* s = nullptr; - try { - storm::settings::Settings::registerModule>(); - s = storm::settings::newInstance(argc, argv, nullptr, true); - } catch (storm::exceptions::InvalidSettingsException& e) { - // Ignore this case. - return true; - } - - if (s->isSet("help")) { - std::cout << storm::settings::help; - return false; - } - - return true; +void createEmptyOptions() { + storm::settings::Settings::registerModule>(); + const char* newArgv[] = {"storm-performance-tests"}; + storm::settings::Settings* s = storm::settings::newInstance(1, newArgv, nullptr, true); } int main(int argc, char* argv[]) { setUpLogging(); - if (!parseOptions(argc, argv)) { - return 0; - } + createEmptyOptions(); std::cout << "StoRM (Performance) Testing Suite" << std::endl; testing::InitGoogleTest(&argc, argv); From cd3706707d36613621f5e8370a2981f3c9a2f102 Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 22 May 2013 15:01:38 +0200 Subject: [PATCH 147/152] Corrected test names and corresponding file names. --- ...elCheckerTest.cpp => EigenDtmcPrctlModelCheckerTest.cpp} | 6 +++--- ...elCheckerTest.cpp => GmmxxDtmcPrctlModelCheckerTest.cpp} | 6 +++--- ...delCheckerTest.cpp => GmmxxMdpPrctlModelCheckerTest.cpp} | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) rename test/functional/modelchecker/{EigenDtmcPrctModelCheckerTest.cpp => EigenDtmcPrctlModelCheckerTest.cpp} (97%) rename test/functional/modelchecker/{GmmxxDtmcPrctModelCheckerTest.cpp => GmmxxDtmcPrctlModelCheckerTest.cpp} (97%) rename test/functional/modelchecker/{GmmxxMdpPrctModelCheckerTest.cpp => GmmxxMdpPrctlModelCheckerTest.cpp} (99%) diff --git a/test/functional/modelchecker/EigenDtmcPrctModelCheckerTest.cpp b/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp similarity index 97% rename from test/functional/modelchecker/EigenDtmcPrctModelCheckerTest.cpp rename to test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp index ced6139cb..9740a16be 100644 --- a/test/functional/modelchecker/EigenDtmcPrctModelCheckerTest.cpp +++ b/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp @@ -6,7 +6,7 @@ #include "src/modelchecker/EigenDtmcPrctlModelChecker.h" #include "src/parser/AutoParser.h" -TEST(EigenDtmcPrctModelCheckerTest, Die) { +TEST(EigenDtmcPrctlModelCheckerTest, Die) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/die/die.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/die/die.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/die/die.coin_flips.trans.rew"); @@ -66,7 +66,7 @@ TEST(EigenDtmcPrctModelCheckerTest, Die) { delete result; } -TEST(EigenDtmcPrctModelCheckerTest, Crowds) { +TEST(EigenDtmcPrctlModelCheckerTest, Crowds) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/crowds/crowds5_5.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/crowds/crowds5_5.lab", "", ""); @@ -114,7 +114,7 @@ TEST(EigenDtmcPrctModelCheckerTest, Crowds) { delete result; } -TEST(EigenDtmcPrctModelCheckerTest, SynchronousLeader) { +TEST(EigenDtmcPrctlModelCheckerTest, SynchronousLeader) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); storm::parser::AutoParser parser(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/synchronous_leader/leader4_8.tra", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/synchronous_leader/leader4_8.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/synchronous_leader/leader4_8.pick.trans.rew"); diff --git a/test/functional/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp similarity index 97% rename from test/functional/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp rename to test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp index e3eb08b68..7d202bb27 100644 --- a/test/functional/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp +++ b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp @@ -5,7 +5,7 @@ #include "src/modelchecker/GmmxxDtmcPrctlModelChecker.h" #include "src/parser/AutoParser.h" -TEST(GmmxxDtmcPrctModelCheckerTest, Die) { +TEST(GmmxxDtmcPrctlModelCheckerTest, Die) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/die/die.tra", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.coin_flips.trans.rew"); @@ -72,7 +72,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Die) { delete result; } -TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { +TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.lab", "", ""); @@ -126,7 +126,7 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) { delete result; } -TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) { +TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { storm::settings::Settings* s = storm::settings::instance(); s->set("fix-deadlocks"); storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.pick.trans.rew"); diff --git a/test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxMdpPrctlModelCheckerTest.cpp similarity index 99% rename from test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp rename to test/functional/modelchecker/GmmxxMdpPrctlModelCheckerTest.cpp index 32cf5b9a4..e32096bcd 100644 --- a/test/functional/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp +++ b/test/functional/modelchecker/GmmxxMdpPrctlModelCheckerTest.cpp @@ -5,7 +5,7 @@ #include "src/modelchecker/GmmxxMdpPrctlModelChecker.h" #include "src/parser/AutoParser.h" -TEST(GmmxxMdpPrctModelCheckerTest, Dice) { +TEST(GmmxxMdpPrctlModelCheckerTest, Dice) { storm::settings::Settings* s = storm::settings::instance(); storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew"); @@ -169,7 +169,7 @@ TEST(GmmxxMdpPrctModelCheckerTest, Dice) { delete result; } -TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) { +TEST(GmmxxMdpPrctlModelCheckerTest, AsynchronousLeader) { storm::settings::Settings* s = storm::settings::instance(); storm::parser::AutoParser parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.trans.rew"); From cae3d6cc6af9c38d1907ed620350fdb2d7f0eaa6 Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 22 May 2013 15:18:59 +0200 Subject: [PATCH 148/152] Renamed PrismParser directory to prismparser. --- src/parser/{PrismParser => prismparser}/BaseGrammar.h | 0 .../{PrismParser => prismparser}/BooleanExpressionGrammar.cpp | 0 .../{PrismParser => prismparser}/BooleanExpressionGrammar.h | 0 .../ConstBooleanExpressionGrammar.cpp | 0 .../{PrismParser => prismparser}/ConstBooleanExpressionGrammar.h | 0 .../{PrismParser => prismparser}/ConstDoubleExpressionGrammar.cpp | 0 .../{PrismParser => prismparser}/ConstDoubleExpressionGrammar.h | 0 .../ConstIntegerExpressionGrammar.cpp | 0 .../{PrismParser => prismparser}/ConstIntegerExpressionGrammar.h | 0 src/parser/{PrismParser => prismparser}/IdentifierGrammars.cpp | 0 src/parser/{PrismParser => prismparser}/IdentifierGrammars.h | 0 src/parser/{PrismParser => prismparser}/Includes.h | 0 .../{PrismParser => prismparser}/IntegerExpressionGrammar.cpp | 0 .../{PrismParser => prismparser}/IntegerExpressionGrammar.h | 0 src/parser/{PrismParser => prismparser}/PrismGrammar.cpp | 0 src/parser/{PrismParser => prismparser}/PrismGrammar.h | 0 src/parser/{PrismParser => prismparser}/Tokens.h | 0 src/parser/{PrismParser => prismparser}/VariableState.cpp | 0 src/parser/{PrismParser => prismparser}/VariableState.h | 0 19 files changed, 0 insertions(+), 0 deletions(-) rename src/parser/{PrismParser => prismparser}/BaseGrammar.h (100%) rename src/parser/{PrismParser => prismparser}/BooleanExpressionGrammar.cpp (100%) rename src/parser/{PrismParser => prismparser}/BooleanExpressionGrammar.h (100%) rename src/parser/{PrismParser => prismparser}/ConstBooleanExpressionGrammar.cpp (100%) rename src/parser/{PrismParser => prismparser}/ConstBooleanExpressionGrammar.h (100%) rename src/parser/{PrismParser => prismparser}/ConstDoubleExpressionGrammar.cpp (100%) rename src/parser/{PrismParser => prismparser}/ConstDoubleExpressionGrammar.h (100%) rename src/parser/{PrismParser => prismparser}/ConstIntegerExpressionGrammar.cpp (100%) rename src/parser/{PrismParser => prismparser}/ConstIntegerExpressionGrammar.h (100%) rename src/parser/{PrismParser => prismparser}/IdentifierGrammars.cpp (100%) rename src/parser/{PrismParser => prismparser}/IdentifierGrammars.h (100%) rename src/parser/{PrismParser => prismparser}/Includes.h (100%) rename src/parser/{PrismParser => prismparser}/IntegerExpressionGrammar.cpp (100%) rename src/parser/{PrismParser => prismparser}/IntegerExpressionGrammar.h (100%) rename src/parser/{PrismParser => prismparser}/PrismGrammar.cpp (100%) rename src/parser/{PrismParser => prismparser}/PrismGrammar.h (100%) rename src/parser/{PrismParser => prismparser}/Tokens.h (100%) rename src/parser/{PrismParser => prismparser}/VariableState.cpp (100%) rename src/parser/{PrismParser => prismparser}/VariableState.h (100%) diff --git a/src/parser/PrismParser/BaseGrammar.h b/src/parser/prismparser/BaseGrammar.h similarity index 100% rename from src/parser/PrismParser/BaseGrammar.h rename to src/parser/prismparser/BaseGrammar.h diff --git a/src/parser/PrismParser/BooleanExpressionGrammar.cpp b/src/parser/prismparser/BooleanExpressionGrammar.cpp similarity index 100% rename from src/parser/PrismParser/BooleanExpressionGrammar.cpp rename to src/parser/prismparser/BooleanExpressionGrammar.cpp diff --git a/src/parser/PrismParser/BooleanExpressionGrammar.h b/src/parser/prismparser/BooleanExpressionGrammar.h similarity index 100% rename from src/parser/PrismParser/BooleanExpressionGrammar.h rename to src/parser/prismparser/BooleanExpressionGrammar.h diff --git a/src/parser/PrismParser/ConstBooleanExpressionGrammar.cpp b/src/parser/prismparser/ConstBooleanExpressionGrammar.cpp similarity index 100% rename from src/parser/PrismParser/ConstBooleanExpressionGrammar.cpp rename to src/parser/prismparser/ConstBooleanExpressionGrammar.cpp diff --git a/src/parser/PrismParser/ConstBooleanExpressionGrammar.h b/src/parser/prismparser/ConstBooleanExpressionGrammar.h similarity index 100% rename from src/parser/PrismParser/ConstBooleanExpressionGrammar.h rename to src/parser/prismparser/ConstBooleanExpressionGrammar.h diff --git a/src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp b/src/parser/prismparser/ConstDoubleExpressionGrammar.cpp similarity index 100% rename from src/parser/PrismParser/ConstDoubleExpressionGrammar.cpp rename to src/parser/prismparser/ConstDoubleExpressionGrammar.cpp diff --git a/src/parser/PrismParser/ConstDoubleExpressionGrammar.h b/src/parser/prismparser/ConstDoubleExpressionGrammar.h similarity index 100% rename from src/parser/PrismParser/ConstDoubleExpressionGrammar.h rename to src/parser/prismparser/ConstDoubleExpressionGrammar.h diff --git a/src/parser/PrismParser/ConstIntegerExpressionGrammar.cpp b/src/parser/prismparser/ConstIntegerExpressionGrammar.cpp similarity index 100% rename from src/parser/PrismParser/ConstIntegerExpressionGrammar.cpp rename to src/parser/prismparser/ConstIntegerExpressionGrammar.cpp diff --git a/src/parser/PrismParser/ConstIntegerExpressionGrammar.h b/src/parser/prismparser/ConstIntegerExpressionGrammar.h similarity index 100% rename from src/parser/PrismParser/ConstIntegerExpressionGrammar.h rename to src/parser/prismparser/ConstIntegerExpressionGrammar.h diff --git a/src/parser/PrismParser/IdentifierGrammars.cpp b/src/parser/prismparser/IdentifierGrammars.cpp similarity index 100% rename from src/parser/PrismParser/IdentifierGrammars.cpp rename to src/parser/prismparser/IdentifierGrammars.cpp diff --git a/src/parser/PrismParser/IdentifierGrammars.h b/src/parser/prismparser/IdentifierGrammars.h similarity index 100% rename from src/parser/PrismParser/IdentifierGrammars.h rename to src/parser/prismparser/IdentifierGrammars.h diff --git a/src/parser/PrismParser/Includes.h b/src/parser/prismparser/Includes.h similarity index 100% rename from src/parser/PrismParser/Includes.h rename to src/parser/prismparser/Includes.h diff --git a/src/parser/PrismParser/IntegerExpressionGrammar.cpp b/src/parser/prismparser/IntegerExpressionGrammar.cpp similarity index 100% rename from src/parser/PrismParser/IntegerExpressionGrammar.cpp rename to src/parser/prismparser/IntegerExpressionGrammar.cpp diff --git a/src/parser/PrismParser/IntegerExpressionGrammar.h b/src/parser/prismparser/IntegerExpressionGrammar.h similarity index 100% rename from src/parser/PrismParser/IntegerExpressionGrammar.h rename to src/parser/prismparser/IntegerExpressionGrammar.h diff --git a/src/parser/PrismParser/PrismGrammar.cpp b/src/parser/prismparser/PrismGrammar.cpp similarity index 100% rename from src/parser/PrismParser/PrismGrammar.cpp rename to src/parser/prismparser/PrismGrammar.cpp diff --git a/src/parser/PrismParser/PrismGrammar.h b/src/parser/prismparser/PrismGrammar.h similarity index 100% rename from src/parser/PrismParser/PrismGrammar.h rename to src/parser/prismparser/PrismGrammar.h diff --git a/src/parser/PrismParser/Tokens.h b/src/parser/prismparser/Tokens.h similarity index 100% rename from src/parser/PrismParser/Tokens.h rename to src/parser/prismparser/Tokens.h diff --git a/src/parser/PrismParser/VariableState.cpp b/src/parser/prismparser/VariableState.cpp similarity index 100% rename from src/parser/PrismParser/VariableState.cpp rename to src/parser/prismparser/VariableState.cpp diff --git a/src/parser/PrismParser/VariableState.h b/src/parser/prismparser/VariableState.h similarity index 100% rename from src/parser/PrismParser/VariableState.h rename to src/parser/prismparser/VariableState.h From ad86c22249097d6c8d0ffb79b8a102dc5974d365 Mon Sep 17 00:00:00 2001 From: gereon Date: Thu, 23 May 2013 13:22:44 +0200 Subject: [PATCH 149/152] Replaced positional arguments by --explicit and --symbolic. --- src/storm.cpp | 56 ++++++++++++++++++++++------------------ src/utility/Settings.cpp | 14 +++++----- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/src/storm.cpp b/src/storm.cpp index 548399d38..932f66a5d 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -283,32 +283,38 @@ int main(const int argc, const char* argv[]) { // Now, the settings are receivd and the model is parsed. storm::settings::Settings* s = storm::settings::instance(); - storm::parser::AutoParser parser(s->getString("trafile"), s->getString("labfile"), s->getString("staterew"), s->getString("transrew")); - - LOG4CPLUS_DEBUG(logger, s->getString("matrixlib")); - - - // Depending on the model type, the respective model checking procedure is chosen. - switch (parser.getType()) { - case storm::models::DTMC: - LOG4CPLUS_INFO(logger, "Model was detected as DTMC"); - checkDtmc(parser.getModel>()); - break; - case storm::models::MDP: - LOG4CPLUS_INFO(logger, "Model was detected as MDP"); - checkMdp(parser.getModel>()); - break; - case storm::models::CTMC: - case storm::models::CTMDP: - // Continuous time model checking is not implemented yet - LOG4CPLUS_ERROR(logger, "The model type you selected is not supported in this version of storm."); - break; - case storm::models::Unknown: - default: - LOG4CPLUS_ERROR(logger, "The model type could not be determined correctly."); - break; + if (s->isSet("explicit")) { + std::vector args = s->get>("explicit"); + storm::parser::AutoParser parser(args[0], args[1], s->getString("staterew"), s->getString("transrew")); + + LOG4CPLUS_DEBUG(logger, s->getString("matrixlib")); + + + // Depending on the model type, the respective model checking procedure is chosen. + switch (parser.getType()) { + case storm::models::DTMC: + LOG4CPLUS_INFO(logger, "Model was detected as DTMC"); + checkDtmc(parser.getModel>()); + break; + case storm::models::MDP: + LOG4CPLUS_INFO(logger, "Model was detected as MDP"); + checkMdp(parser.getModel>()); + break; + case storm::models::CTMC: + case storm::models::CTMDP: + // Continuous time model checking is not implemented yet + LOG4CPLUS_ERROR(logger, "The model type you selected is not supported in this version of storm."); + break; + case storm::models::Unknown: + default: + LOG4CPLUS_ERROR(logger, "The model type could not be determined correctly."); + break; + } + } + if (s->isSet("symbolic")) { + std::string arg = s->getString("symbolic"); + Pr } - cleanUp(); diff --git a/src/utility/Settings.cpp b/src/utility/Settings.cpp index ae0db6f4b..1a071d3c0 100644 --- a/src/utility/Settings.cpp +++ b/src/utility/Settings.cpp @@ -54,10 +54,6 @@ Settings::Settings(int const argc, char const * const argv[], char const * const // Initially fill description objects. this->initDescriptions(); - // Take care of positional arguments. - Settings::positional.add("trafile", 1); - Settings::positional.add("labfile", 1); - // Check module triggers, add corresponding options. std::map< std::string, std::list< std::string > > options; @@ -122,6 +118,12 @@ Settings::Settings(int const argc, char const * const argv[], char const * const } } +void checkExplicit(const std::vector& filenames) { + if (filenames.size() != 2) { + throw storm::exceptions::InvalidSettingsException() << "--explicit must be given exactly two filenames"; + } +} + /*! * Initially fill options_description objects. */ @@ -135,8 +137,8 @@ void Settings::initDescriptions() { ("trace", "be extremely verbose, expect lots of output") ("logfile,l", bpo::value(), "name of the log file") ("configfile,c", bpo::value(), "name of config file") - ("trafile", bpo::value()->required(), "name of the .tra file") - ("labfile", bpo::value()->required(), "name of the .lab file") + ("explicit", bpo::value>()->notifier(&checkExplicit), "name of transition and labeling file") + ("symbolic", bpo::value(), "name of prism file") ("prctl", bpo::value(), "text file containing prctl formulas") ("csl", bpo::value(), "text file containing csl formulas") ("ltl", bpo::value(), "text file containing ltl formulas") From cb14f2e771c66864cd580a58badcf7069c56e5eb Mon Sep 17 00:00:00 2001 From: gereon Date: Thu, 23 May 2013 17:52:13 +0200 Subject: [PATCH 150/152] Made choiceIndices work in ExplicitModelAdapter, added code to somehow use --symbolic (parse model, show model information) --- src/adapters/ExplicitModelAdapter.cpp | 6 ++++-- src/adapters/ExplicitModelAdapter.h | 1 + src/parser/PrismParser.cpp | 2 +- src/parser/prismparser/PrismGrammar.cpp | 16 ++++++++-------- src/parser/prismparser/PrismGrammar.h | 18 +++++++++--------- src/storm.cpp | 5 ++++- 6 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index 298400acb..177d0f601 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -73,8 +73,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { case storm::ir::Program::MDP: { std::shared_ptr> matrix = this->buildNondeterministicMatrix(); - std::shared_ptr> choiceIndices; - return std::shared_ptr>(new storm::models::Mdp(matrix, stateLabeling, choiceIndices, stateRewards, this->transitionRewards)); + return std::shared_ptr>(new storm::models::Mdp(matrix, stateLabeling, this->choiceIndices, stateRewards, this->transitionRewards)); break; } case storm::ir::Program::CTMDP: @@ -493,9 +492,12 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { this->transitionRewards = std::shared_ptr>(new storm::storage::SparseMatrix(this->numberOfChoices, allStates.size())); this->transitionRewards->initialize(this->numberOfTransitions); } + this->choiceIndices = std::shared_ptr>(new std::vector()); + this->choiceIndices->reserve(allStates.size()); // Build matrix. uint_fast64_t nextRow = 0; for (uint_fast64_t state = 0; state < this->allStates.size(); state++) { + this->choiceIndices->push_back(transitionMap[state].size()); for (auto choice : transitionMap[state]) { for (auto it : choice.second) { result->addNextValue(nextRow, it.first, it.second); diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 1fe2e29a4..d9b66de5f 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -190,6 +190,7 @@ private: std::unordered_map stateToIndexMap; uint_fast64_t numberOfTransitions; uint_fast64_t numberOfChoices; + std::shared_ptr> choiceIndices; std::shared_ptr> transitionRewards; /*! diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 8057eda18..cba3867e7 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -9,7 +9,7 @@ #include "src/utility/OsDetection.h" -#include "src/parser/PrismParser/PrismGrammar.h" +#include "src/parser/prismparser/PrismGrammar.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" diff --git a/src/parser/prismparser/PrismGrammar.cpp b/src/parser/prismparser/PrismGrammar.cpp index 86f1319b9..ced118dce 100644 --- a/src/parser/prismparser/PrismGrammar.cpp +++ b/src/parser/prismparser/PrismGrammar.cpp @@ -9,14 +9,14 @@ #include "src/utility/OsDetection.h" -#include "src/parser/PrismParser/Includes.h" -#include "src/parser/PrismParser/BooleanExpressionGrammar.h" -#include "src/parser/PrismParser/ConstBooleanExpressionGrammar.h" -#include "src/parser/PrismParser/ConstDoubleExpressionGrammar.h" -#include "src/parser/PrismParser/ConstIntegerExpressionGrammar.h" -#include "src/parser/PrismParser/IntegerExpressionGrammar.h" -#include "src/parser/PrismParser/IdentifierGrammars.h" -#include "src/parser/PrismParser/VariableState.h" +#include "src/parser/prismparser/Includes.h" +#include "src/parser/prismparser/BooleanExpressionGrammar.h" +#include "src/parser/prismparser/ConstBooleanExpressionGrammar.h" +#include "src/parser/prismparser/ConstDoubleExpressionGrammar.h" +#include "src/parser/prismparser/ConstIntegerExpressionGrammar.h" +#include "src/parser/prismparser/IntegerExpressionGrammar.h" +#include "src/parser/prismparser/IdentifierGrammars.h" +#include "src/parser/prismparser/VariableState.h" // Needed for file IO. #include diff --git a/src/parser/prismparser/PrismGrammar.h b/src/parser/prismparser/PrismGrammar.h index 97033f506..5844659be 100644 --- a/src/parser/prismparser/PrismGrammar.h +++ b/src/parser/prismparser/PrismGrammar.h @@ -10,15 +10,15 @@ // All classes of the intermediate representation are used. #include "src/ir/IR.h" -#include "src/parser/PrismParser/Includes.h" -#include "src/parser/PrismParser/Tokens.h" -#include "src/parser/PrismParser/IdentifierGrammars.h" -#include "src/parser/PrismParser/VariableState.h" -#include "src/parser/PrismParser/ConstBooleanExpressionGrammar.h" -#include "src/parser/PrismParser/ConstDoubleExpressionGrammar.h" -#include "src/parser/PrismParser/ConstIntegerExpressionGrammar.h" -#include "src/parser/PrismParser/BooleanExpressionGrammar.h" -#include "src/parser/PrismParser/IntegerExpressionGrammar.h" +#include "src/parser/prismparser/Includes.h" +#include "src/parser/prismparser/Tokens.h" +#include "src/parser/prismparser/IdentifierGrammars.h" +#include "src/parser/prismparser/VariableState.h" +#include "src/parser/prismparser/ConstBooleanExpressionGrammar.h" +#include "src/parser/prismparser/ConstDoubleExpressionGrammar.h" +#include "src/parser/prismparser/ConstIntegerExpressionGrammar.h" +#include "src/parser/prismparser/BooleanExpressionGrammar.h" +#include "src/parser/prismparser/IntegerExpressionGrammar.h" // Used for file input. #include diff --git a/src/storm.cpp b/src/storm.cpp index bd2dfff57..76d0f38ca 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -343,7 +343,10 @@ int main(const int argc, const char* argv[]) { } if (s->isSet("symbolic")) { std::string arg = s->getString("symbolic"); - Pr + storm::parser::PrismParser parser; + storm::adapters::ExplicitModelAdapter adapter(parser.parseFile(arg)); + std::shared_ptr> model = adapter.getModel(); + model->printModelInformationToStream(std::cout); } cleanUp(); From cd9e2ba5492145bdc3d92e5d5a4a04904f62de20 Mon Sep 17 00:00:00 2001 From: gereon Date: Mon, 27 May 2013 13:22:44 +0200 Subject: [PATCH 151/152] Some minor cleanups, added lot of documentation in prismparser --- src/adapters/ExplicitModelAdapter.cpp | 57 +++++---- src/adapters/ExplicitModelAdapter.h | 52 +++++++-- src/parser/prismparser/BaseGrammar.h | 110 +++++++++++++++++- .../prismparser/BooleanExpressionGrammar.h | 10 ++ .../ConstBooleanExpressionGrammar.cpp | 26 +---- .../ConstBooleanExpressionGrammar.h | 9 +- .../ConstDoubleExpressionGrammar.cpp | 25 +--- .../ConstDoubleExpressionGrammar.h | 8 +- .../ConstIntegerExpressionGrammar.h | 3 + src/parser/prismparser/IdentifierGrammars.h | 8 +- .../prismparser/IntegerExpressionGrammar.h | 8 ++ src/parser/prismparser/PrismGrammar.cpp | 6 +- src/parser/prismparser/PrismGrammar.h | 1 + src/parser/prismparser/Tokens.h | 17 ++- src/parser/prismparser/VariableState.h | 73 +++++++++++- 15 files changed, 310 insertions(+), 103 deletions(-) diff --git a/src/adapters/ExplicitModelAdapter.cpp b/src/adapters/ExplicitModelAdapter.cpp index 177d0f601..b7aef607c 100644 --- a/src/adapters/ExplicitModelAdapter.cpp +++ b/src/adapters/ExplicitModelAdapter.cpp @@ -26,36 +26,39 @@ namespace storm { namespace adapters { -ExplicitModelAdapter::ExplicitModelAdapter(storm::ir::Program program) : program(program), - booleanVariables(), integerVariables(), booleanVariableToIndexMap(), integerVariableToIndexMap(), - allStates(), stateToIndexMap(), numberOfTransitions(0), numberOfChoices(0), transitionRewards(nullptr), transitionMap() { - this->initializeVariables(); - storm::settings::Settings* s = storm::settings::instance(); - this->precision = s->get("precision"); -} - -ExplicitModelAdapter::~ExplicitModelAdapter() { - this->clearInternalState(); -} - - std::shared_ptr> ExplicitModelAdapter::getModel(std::string const & rewardModelName) { + ExplicitModelAdapter::ExplicitModelAdapter(storm::ir::Program program) : program(program), + booleanVariables(), integerVariables(), booleanVariableToIndexMap(), integerVariableToIndexMap(), + allStates(), stateToIndexMap(), numberOfTransitions(0), numberOfChoices(0), transitionRewards(nullptr), transitionMap() { + // Get variables from program. + this->initializeVariables(); + storm::settings::Settings* s = storm::settings::instance(); + this->precision = s->get("precision"); + } + ExplicitModelAdapter::~ExplicitModelAdapter() { + this->clearInternalState(); + } + std::shared_ptr> ExplicitModelAdapter::getModel(std::string const & rewardModelName) { + // Initialize rewardModel. + this->rewardModel = nullptr; + if (rewardModelName != "") { + this->rewardModel = std::unique_ptr(new storm::ir::RewardModel(this->program.getRewardModel(rewardModelName))); + } + + // State expansion, build temporary map, compute transition rewards. this->buildTransitionMap(); - + + // Compute labeling. std::shared_ptr stateLabeling = this->getStateLabeling(this->program.getLabels()); + + // Compute state rewards. std::shared_ptr> stateRewards = nullptr; - - this->rewardModel = nullptr; - if (rewardModelName != "") { - this->rewardModel = std::unique_ptr(new storm::ir::RewardModel(this->program.getRewardModel(rewardModelName)));; - if (this->rewardModel != nullptr) { - if (this->rewardModel->hasStateRewards()) { - stateRewards = this->getStateRewards(this->rewardModel->getStateRewards()); - } - } + if ((this->rewardModel != nullptr) && this->rewardModel->hasStateRewards()) { + stateRewards = this->getStateRewards(this->rewardModel->getStateRewards()); } + // Build and return actual model. switch (this->program.getModelType()) { case storm::ir::Program::DTMC: @@ -107,8 +110,10 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { std::shared_ptr> ExplicitModelAdapter::getStateRewards(std::vector const & rewards) { std::shared_ptr> results(new std::vector(this->allStates.size())); for (uint_fast64_t index = 0; index < this->allStates.size(); index++) { + (*results)[index] = 0; for (auto reward: rewards) { - (*results)[index] = reward.getReward(this->allStates[index]); + // Add this reward to the state. + (*results)[index] += reward.getReward(this->allStates[index]); } } return results; @@ -116,11 +121,13 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { std::shared_ptr ExplicitModelAdapter::getStateLabeling(std::map> labels) { std::shared_ptr results(new storm::models::AtomicPropositionsLabeling(this->allStates.size(), labels.size())); + // Initialize labeling. for (auto it: labels) { results->addAtomicProposition(it.first); } for (uint_fast64_t index = 0; index < this->allStates.size(); index++) { for (auto label: labels) { + // Add label to state, if guard is true. if (label.second->getValueAsBool(this->allStates[index])) { results->addAtomicPropositionToState(label.first, index); } @@ -132,6 +139,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { void ExplicitModelAdapter::initializeVariables() { uint_fast64_t numberOfIntegerVariables = 0; uint_fast64_t numberOfBooleanVariables = 0; + // Count number of variables. for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { numberOfIntegerVariables += program.getModule(i).getNumberOfIntegerVariables(); numberOfBooleanVariables += program.getModule(i).getNumberOfBooleanVariables(); @@ -140,6 +148,7 @@ ExplicitModelAdapter::~ExplicitModelAdapter() { this->booleanVariables.resize(numberOfBooleanVariables); this->integerVariables.resize(numberOfIntegerVariables); + // Create variables. for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { storm::ir::Module const& module = program.getModule(i); diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index d9b66de5f..a69d7382c 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -53,17 +53,25 @@ public: class ExplicitModelAdapter { public: + /*! + * Initialize adapter with given program. + */ ExplicitModelAdapter(storm::ir::Program program); ~ExplicitModelAdapter(); + /*! + * Convert program to an AbstractModel. + * The model will be of the type specified in the program. + * The model will contain rewards that are specified by the given reward model. + * @param rewardModelName Name of reward model to be added to the model. + * @return Model resulting from the program. + */ std::shared_ptr> getModel(std::string const & rewardModelName = ""); private: double precision; - // First some generic routines to operate on states. - /*! * Set some boolean variable in the given state object. * @param state State to be changed. @@ -78,6 +86,11 @@ private: * @param value New value. */ static void setValue(StateType* const state, uint_fast64_t const index, int_fast64_t const value); + /*! + * Transforms a state into a somewhat readable string. + * @param state State. + * @return String representation of the state. + */ static std::string toString(StateType const * const state); /*! * Apply an update to the given state and return the resulting new state object. @@ -103,7 +116,18 @@ private: */ void initializeVariables(); + /*! + * Calculate state reward for every reachable state based on given reward models. + * @param rewards List of state reward models. + * @return Reward for every state. + */ std::shared_ptr> getStateRewards(std::vector const & rewards); + + /*! + * Determines the labels for every reachable state, based on a list of available labels. + * @param labels Mapping from label names to boolean expressions. + * @returns The resulting labeling. + */ std::shared_ptr getStateLabeling(std::map> labels); /*! @@ -168,29 +192,41 @@ private: std::shared_ptr> buildNondeterministicMatrix(); /*! - * Build matrix from model. Starts with all initial states and explores the reachable state space. - * While exploring, the transitions are stored in a temporary map. - * Afterwards, we transform this map into the actual matrix. - * @return result matrix. + * Generate internal transition map from given model. + * Starts with all initial states and explores the reachable state space. */ void buildTransitionMap(); + /*! + * Clear all members that are initialized during the computation. + */ void clearInternalState(); // Program that should be converted. storm::ir::Program program; + // List of all boolean variables. std::vector booleanVariables; + // List of all integer variables. std::vector integerVariables; + // Maps boolean variable names to their index. std::map booleanVariableToIndexMap; + // Maps integer variable names to their index. std::map integerVariableToIndexMap; - // Members that are filled during the conversion. + //// Members that are filled during the conversion. + // Selected reward model. std::unique_ptr rewardModel; + // List of all reachable states. std::vector allStates; + // Maps states to their index (within allStates). std::unordered_map stateToIndexMap; + // Number of transitions. uint_fast64_t numberOfTransitions; + // Number of choices. (Is number of rows in matrix of nondeterministic model.) uint_fast64_t numberOfChoices; - std::shared_ptr> choiceIndices; + // Number of choices for each state. + std::shared_ptr> choiceIndices; + // Rewards for transitions. std::shared_ptr> transitionRewards; /*! diff --git a/src/parser/prismparser/BaseGrammar.h b/src/parser/prismparser/BaseGrammar.h index 345a377e0..e0c5d4df8 100644 --- a/src/parser/prismparser/BaseGrammar.h +++ b/src/parser/prismparser/BaseGrammar.h @@ -16,11 +16,23 @@ namespace storm { namespace parser { namespace prism { + /*! + * This is the base class for all expression grammars. + * It takes care of implementing a singleton, stores a VariableState and implements some common helper routines. + */ template class BaseGrammar { public: + /*! + * Constructor. + */ BaseGrammar(std::shared_ptr& state) : state(state) {} + /*! + * Create and return a new instance of class T, usually the subclass. + * @param state VariableState to be given to the constructor. + * @returns Instance of class T. + */ static T& instance(std::shared_ptr state = nullptr) { if (BaseGrammar::instanceObject == nullptr) { BaseGrammar::instanceObject = std::shared_ptr(new T(state)); @@ -29,26 +41,55 @@ namespace prism { return *BaseGrammar::instanceObject; } + /*! + * Clear the cached instance. + */ static void resetInstance() { BaseGrammar::instanceObject = nullptr; } + /*! + * Notify the cached object, that we will begin with the second parsing run. + */ static void secondRun() { if (BaseGrammar::instanceObject != nullptr) { BaseGrammar::instanceObject->prepareSecondRun(); } } + /*! + * Create a new boolean literal with the given value. + * @param value Value of the literal. + * @returns Boolean literal. + */ std::shared_ptr createBoolLiteral(const bool value) { return std::shared_ptr(new BooleanLiteral(value)); } + /*! + * Create a new double literal with the given value. + * @param value Value of the literal. + * @returns Double literal. + */ std::shared_ptr createDoubleLiteral(const double value) { return std::shared_ptr(new DoubleLiteral(value)); } + /*! + * Create a new integer literal with the given value. + * @param value Value of the literal. + * @returns Integer literal. + */ std::shared_ptr createIntLiteral(const int_fast64_t value) { return std::shared_ptr(new IntegerLiteral(value)); } + /*! + * Create a new plus expression. If addition is true, it will be an addition, otherwise a subtraction. + * @param left Left operand. + * @param addition Flag for addition or subtraction. + * @param right Right operand. + * @param type Return type. + * @returns Plus expression. + */ std::shared_ptr createPlus(const std::shared_ptr left, bool addition, const std::shared_ptr right, BaseExpression::ReturnType type) { if (addition) { return std::shared_ptr(new BinaryNumericalFunctionExpression(type, left, right, BinaryNumericalFunctionExpression::PLUS)); @@ -56,16 +97,43 @@ namespace prism { return std::shared_ptr(new BinaryNumericalFunctionExpression(type, left, right, BinaryNumericalFunctionExpression::MINUS)); } } + /*! + * Create a new double plus expression. If addition is true, it will be an addition, otherwise a subtraction. + * @param left Left operand. + * @param addition Flag for addition or subtraction. + * @param right Right operand. + * @returns Double plus expression. + */ std::shared_ptr createDoublePlus(const std::shared_ptr left, bool addition, const std::shared_ptr right) { return this->createPlus(left, addition, right, BaseExpression::double_); } + /*! + * Create a new integer plus expression. If addition is true, it will be an addition, otherwise a subtraction. + * @param left Left operand. + * @param addition Flag for addition or subtraction. + * @param right Right operand. + * @returns Integer plus expression. + */ std::shared_ptr createIntPlus(const std::shared_ptr left, bool addition, const std::shared_ptr right) { return this->createPlus(left, addition, right, BaseExpression::int_); } + /*! + * Create a new integer multiplication expression. + * @param left Left operand. + * @param right Right operand. + * @returns Integer multiplication expression. + */ std::shared_ptr createIntMult(const std::shared_ptr left, const std::shared_ptr right) { return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::int_, left, right, BinaryNumericalFunctionExpression::TIMES)); } + /*! + * Create a new integer multiplication expression. If multiplication is true, it will be an multiplication, otherwise a division. + * @param left Left operand. + * @param addition Flag for multiplication or division. + * @param right Right operand. + * @returns Integer multiplication expression. + */ std::shared_ptr createDoubleMult(const std::shared_ptr left, bool multiplication, const std::shared_ptr right) { if (multiplication) { return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::TIMES)); @@ -73,29 +141,69 @@ namespace prism { return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::DIVIDE)); } } - + /*! + * Create a new binary relation expression. + * @param left Left operand. + * @param relationType Type of binary relation. + * @param right Right operand. + * @returns Binary relation expression. + */ std::shared_ptr createRelation(std::shared_ptr left, BinaryRelationExpression::RelationType relationType, std::shared_ptr right) { return std::shared_ptr(new BinaryRelationExpression(left, right, relationType)); } + /*! + * Create a new negation expression. + * @param child Expression to be negated. + * @returns Negation expression. + */ std::shared_ptr createNot(std::shared_ptr child) { return std::shared_ptr(new UnaryBooleanFunctionExpression(child, UnaryBooleanFunctionExpression::NOT)); } + /*! + * Create a new And expression. + * @param left Left operand. + * @param right Right operand. + * @returns And expression. + */ std::shared_ptr createAnd(std::shared_ptr left, std::shared_ptr right) { //std::cerr << "Creating " << left->toString() << " & " << right->toString() << std::endl; return std::shared_ptr(new BinaryBooleanFunctionExpression(left, right, BinaryBooleanFunctionExpression::AND)); } + /*! + * Create a new Or expression. + * @param left Left operand. + * @param right Right operand. + * @returns Or expression. + */ std::shared_ptr createOr(std::shared_ptr left, std::shared_ptr right) { return std::shared_ptr(new BinaryBooleanFunctionExpression(left, right, BinaryBooleanFunctionExpression::OR)); } + /*! + * Retrieve boolean variable by name. + * @param name Variable name. + * @returns Boolean variable. + */ std::shared_ptr getBoolVariable(const std::string name) { return state->getBooleanVariable(name); } + /*! + * Retrieve integer variable by name. + * @param name Variable name. + * @returns Integer variable. + */ std::shared_ptr getIntVariable(const std::string name) { return state->getIntegerVariable(name); } + /*! + * Base method to switch to second run. This does nothing. + * Any subclass that needs to do something in order to proceed to the second run should override this method. + */ virtual void prepareSecondRun() {} protected: + /*! + * Pointer to variable state. + */ std::shared_ptr state; private: diff --git a/src/parser/prismparser/BooleanExpressionGrammar.h b/src/parser/prismparser/BooleanExpressionGrammar.h index 9e976e64d..4f94dffbf 100644 --- a/src/parser/prismparser/BooleanExpressionGrammar.h +++ b/src/parser/prismparser/BooleanExpressionGrammar.h @@ -19,9 +19,16 @@ namespace storm { namespace parser { namespace prism { +/*! + * This grammar parses (non constant) boolean expressions as used in prism models. + */ class BooleanExpressionGrammar : public qi::grammar(), Skipper, Unused>, public BaseGrammar { public: BooleanExpressionGrammar(std::shared_ptr& state); + /*! + * Switch to second run. + * Variable names may be any valid identifier in the first run, but only defined variables in the second run. + */ virtual void prepareSecondRun(); private: @@ -33,6 +40,9 @@ private: qi::rule(), Skipper> relativeExpression; qi::rule(), Skipper> booleanVariableExpression; + /*! + * Parser relation operators. + */ storm::parser::prism::relationalOperatorStruct relations_; }; diff --git a/src/parser/prismparser/ConstBooleanExpressionGrammar.cpp b/src/parser/prismparser/ConstBooleanExpressionGrammar.cpp index 203894638..ffa0b219b 100644 --- a/src/parser/prismparser/ConstBooleanExpressionGrammar.cpp +++ b/src/parser/prismparser/ConstBooleanExpressionGrammar.cpp @@ -6,47 +6,31 @@ namespace storm { namespace parser { namespace prism { - std::shared_ptr ConstBooleanExpressionGrammar::createRelation(std::shared_ptr left, BinaryRelationExpression::RelationType relationType, std::shared_ptr right) { - return std::shared_ptr(new BinaryRelationExpression(left, right, relationType)); - } - std::shared_ptr ConstBooleanExpressionGrammar::createNot(std::shared_ptr child) { - return std::shared_ptr(new UnaryBooleanFunctionExpression(child, UnaryBooleanFunctionExpression::NOT)); - } - std::shared_ptr ConstBooleanExpressionGrammar::createAnd(std::shared_ptr left, std::shared_ptr right) { - return std::shared_ptr(new BinaryBooleanFunctionExpression(left, right, BinaryBooleanFunctionExpression::AND)); - } - std::shared_ptr ConstBooleanExpressionGrammar::createOr(std::shared_ptr left, std::shared_ptr right) { - return std::shared_ptr(new BinaryBooleanFunctionExpression(left, right, BinaryBooleanFunctionExpression::OR)); - } - std::shared_ptr ConstBooleanExpressionGrammar::createLiteral(const bool value) { - return std::shared_ptr(new BooleanLiteral(value)); - } - ConstBooleanExpressionGrammar::ConstBooleanExpressionGrammar(std::shared_ptr& state) : ConstBooleanExpressionGrammar::base_type(constantBooleanExpression), BaseGrammar(state) { constantBooleanExpression %= constantOrExpression; constantBooleanExpression.name("constant boolean expression"); - constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::bind(&ConstBooleanExpressionGrammar::createOr, this, qi::_val, qi::_1)]; + constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::bind(&BaseGrammar::createOr, this, qi::_val, qi::_1)]; constantOrExpression.name("constant boolean expression"); - constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::bind(&ConstBooleanExpressionGrammar::createAnd, this, qi::_val, qi::_1)]; + constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::bind(&BaseGrammar::createAnd, this, qi::_val, qi::_1)]; constantAndExpression.name("constant boolean expression"); - constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::bind(&ConstBooleanExpressionGrammar::createNot, this, qi::_1)]; + constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::bind(&BaseGrammar::createNot, this, qi::_1)]; constantNotExpression.name("constant boolean expression"); constantAtomicBooleanExpression %= (constantRelativeExpression | qi::lit("(") >> constantBooleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression); constantAtomicBooleanExpression.name("constant boolean expression"); - constantRelativeExpression = (ConstIntegerExpressionGrammar::instance(this->state) >> relations_ >> ConstIntegerExpressionGrammar::instance(this->state))[qi::_val = phoenix::bind(&ConstBooleanExpressionGrammar::createRelation, this, qi::_1, qi::_2, qi::_3)]; + constantRelativeExpression = (ConstIntegerExpressionGrammar::instance(this->state) >> relations_ >> ConstIntegerExpressionGrammar::instance(this->state))[qi::_val = phoenix::bind(&BaseGrammar::createRelation, this, qi::_1, qi::_2, qi::_3)]; constantRelativeExpression.name("constant boolean expression"); booleanConstantExpression %= (this->state->booleanConstants_ | booleanLiteralExpression); booleanConstantExpression.name("boolean constant or literal"); - booleanLiteralExpression = qi::bool_[qi::_val = phoenix::bind(&ConstBooleanExpressionGrammar::createLiteral, this, qi::_1)]; + booleanLiteralExpression = qi::bool_[qi::_val = phoenix::bind(&BaseGrammar::createBoolLiteral, this, qi::_1)]; booleanLiteralExpression.name("boolean literal"); } } diff --git a/src/parser/prismparser/ConstBooleanExpressionGrammar.h b/src/parser/prismparser/ConstBooleanExpressionGrammar.h index 4c8a5f7fb..f47c95bb5 100644 --- a/src/parser/prismparser/ConstBooleanExpressionGrammar.h +++ b/src/parser/prismparser/ConstBooleanExpressionGrammar.h @@ -17,6 +17,9 @@ namespace storm { namespace parser { namespace prism { +/*! + * This grammar parses constant boolean expression as used in prism models. + */ class ConstBooleanExpressionGrammar : public qi::grammar(), Skipper, Unused>, public BaseGrammar { public: ConstBooleanExpressionGrammar(std::shared_ptr& state); @@ -33,12 +36,6 @@ private: qi::rule(), Skipper> booleanLiteralExpression; storm::parser::prism::relationalOperatorStruct relations_; - - std::shared_ptr createRelation(std::shared_ptr left, BinaryRelationExpression::RelationType relationType, std::shared_ptr right); - std::shared_ptr createNot(std::shared_ptr child); - std::shared_ptr createAnd(std::shared_ptr left, std::shared_ptr right); - std::shared_ptr createOr(std::shared_ptr left, std::shared_ptr right); - std::shared_ptr createLiteral(const bool value); }; diff --git a/src/parser/prismparser/ConstDoubleExpressionGrammar.cpp b/src/parser/prismparser/ConstDoubleExpressionGrammar.cpp index ddd1341f5..1927909e1 100644 --- a/src/parser/prismparser/ConstDoubleExpressionGrammar.cpp +++ b/src/parser/prismparser/ConstDoubleExpressionGrammar.cpp @@ -4,25 +4,6 @@ namespace storm { namespace parser { namespace prism { - - std::shared_ptr ConstDoubleExpressionGrammar::createLiteral(double value) { - return std::shared_ptr(new DoubleLiteral(value)); - } - std::shared_ptr ConstDoubleExpressionGrammar::createPlus(const std::shared_ptr left, bool addition, const std::shared_ptr right) { - if (addition) { - return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::PLUS)); - } else { - return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::MINUS)); - } - } - std::shared_ptr ConstDoubleExpressionGrammar::createMult(const std::shared_ptr left, bool multiplication, const std::shared_ptr right) { - if (multiplication) { - return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::TIMES)); - } else { - return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::DIVIDE)); - } - } - ConstDoubleExpressionGrammar::ConstDoubleExpressionGrammar(std::shared_ptr& state) : ConstDoubleExpressionGrammar::base_type(constantDoubleExpression), BaseGrammar(state) { @@ -30,11 +11,11 @@ ConstDoubleExpressionGrammar::ConstDoubleExpressionGrammar(std::shared_ptr> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantDoubleMultExpression) - [qi::_val = phoenix::bind(&ConstDoubleExpressionGrammar::createPlus, this, qi::_val, qi::_a, qi::_1)]; + [qi::_val = phoenix::bind(&BaseGrammar::createDoublePlus, this, qi::_val, qi::_a, qi::_1)]; constantDoublePlusExpression.name("constant double expression"); constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> constantAtomicDoubleExpression) - [qi::_val = phoenix::bind(&ConstDoubleExpressionGrammar::createMult, this, qi::_val, qi::_a, qi::_1)]; + [qi::_val = phoenix::bind(&BaseGrammar::createDoubleMult, this, qi::_val, qi::_a, qi::_1)]; constantDoubleMultExpression.name("constant double expression"); constantAtomicDoubleExpression %= (qi::lit("(") >> constantDoubleExpression >> qi::lit(")") | doubleConstantExpression); @@ -43,7 +24,7 @@ ConstDoubleExpressionGrammar::ConstDoubleExpressionGrammar(std::shared_ptrstate->doubleConstants_ | this->state->integerConstants_ | doubleLiteralExpression); doubleConstantExpression.name("double constant or literal"); - doubleLiteralExpression = qi::double_[qi::_val = phoenix::bind(&ConstDoubleExpressionGrammar::createLiteral, this, qi::_1)]; + doubleLiteralExpression = qi::double_[qi::_val = phoenix::bind(&BaseGrammar::createDoubleLiteral, this, qi::_1)]; doubleLiteralExpression.name("double literal"); } diff --git a/src/parser/prismparser/ConstDoubleExpressionGrammar.h b/src/parser/prismparser/ConstDoubleExpressionGrammar.h index 9d70f9877..a964ec367 100644 --- a/src/parser/prismparser/ConstDoubleExpressionGrammar.h +++ b/src/parser/prismparser/ConstDoubleExpressionGrammar.h @@ -16,11 +16,13 @@ namespace storm { namespace parser { namespace prism { +/*! + * This grammar parses constant double expressions as used in prism models. + */ class ConstDoubleExpressionGrammar : public qi::grammar(), Skipper, Unused>, public BaseGrammar { public: ConstDoubleExpressionGrammar(std::shared_ptr& state); - private: qi::rule(), Skipper, Unused> constantDoubleExpression; qi::rule(), qi::locals, Skipper> constantDoublePlusExpression; @@ -28,10 +30,6 @@ private: qi::rule(), Skipper> constantAtomicDoubleExpression; qi::rule(), Skipper> doubleConstantExpression; qi::rule(), Skipper> doubleLiteralExpression; - - std::shared_ptr createLiteral(double value); - std::shared_ptr createPlus(const std::shared_ptr left, bool addition, const std::shared_ptr right); - std::shared_ptr createMult(const std::shared_ptr left, bool multiplication, const std::shared_ptr right); }; diff --git a/src/parser/prismparser/ConstIntegerExpressionGrammar.h b/src/parser/prismparser/ConstIntegerExpressionGrammar.h index 847892e10..c7360553e 100644 --- a/src/parser/prismparser/ConstIntegerExpressionGrammar.h +++ b/src/parser/prismparser/ConstIntegerExpressionGrammar.h @@ -16,6 +16,9 @@ namespace storm { namespace parser { namespace prism { +/*! + * This grammar parses constant integer expressions as used in prism models. + */ class ConstIntegerExpressionGrammar : public qi::grammar(), Skipper, Unused>, public BaseGrammar { public: ConstIntegerExpressionGrammar(std::shared_ptr& state); diff --git a/src/parser/prismparser/IdentifierGrammars.h b/src/parser/prismparser/IdentifierGrammars.h index 936ee732a..5305cf277 100644 --- a/src/parser/prismparser/IdentifierGrammars.h +++ b/src/parser/prismparser/IdentifierGrammars.h @@ -16,13 +16,19 @@ namespace storm { namespace parser { namespace prism { + /*! + * This grammar parses a (possibly used) identifier as used in a prism models. + */ class IdentifierGrammar : public qi::grammar, public BaseGrammar { public: IdentifierGrammar(std::shared_ptr& state); private: qi::rule identifierName; }; - + + /*! + * This grammar parses an used identifier as used in a prism models. + */ class FreeIdentifierGrammar : public qi::grammar, public BaseGrammar { public: FreeIdentifierGrammar(std::shared_ptr& state); diff --git a/src/parser/prismparser/IntegerExpressionGrammar.h b/src/parser/prismparser/IntegerExpressionGrammar.h index 0f44b0d01..5bc842192 100644 --- a/src/parser/prismparser/IntegerExpressionGrammar.h +++ b/src/parser/prismparser/IntegerExpressionGrammar.h @@ -19,9 +19,17 @@ namespace storm { namespace parser { namespace prism { +/*! + * This grammar parses a (non constant) integer expressions as used in prism models. + */ class IntegerExpressionGrammar : public qi::grammar(), Skipper, Unused>, public BaseGrammar { public: IntegerExpressionGrammar(std::shared_ptr& state); + + /*! + * Switch to second run. + * Variable names may be any valid identifier in the first run, but only defined variables in the second run. + */ virtual void prepareSecondRun(); private: diff --git a/src/parser/prismparser/PrismGrammar.cpp b/src/parser/prismparser/PrismGrammar.cpp index ced118dce..7189c8a03 100644 --- a/src/parser/prismparser/PrismGrammar.cpp +++ b/src/parser/prismparser/PrismGrammar.cpp @@ -63,19 +63,19 @@ void PrismGrammar::addBoolAssignment(const std::string& variable, std::shared_pt } Module PrismGrammar::renameModule(const std::string& name, const std::string& oldname, std::map& mapping) { this->state->moduleNames_.add(name, name); - Module* old = this->state->moduleMap_.find(oldname); + Module* old = this->moduleMap_.find(oldname); if (old == nullptr) { LOG4CPLUS_ERROR(logger, "Renaming module failed: module " << oldname << " does not exist!"); throw "Renaming module failed"; } Module res(*old, name, mapping, this->state); - this->state->moduleMap_.at(name) = res; + this->moduleMap_.at(name) = res; return res; } Module PrismGrammar::createModule(const std::string name, std::vector& bools, std::vector& ints, std::map& boolids, std::map intids, std::vector commands) { this->state->moduleNames_.add(name, name); Module res(name, bools, ints, boolids, intids, commands); - this->state->moduleMap_.at(name) = res; + this->moduleMap_.at(name) = res; return res; } diff --git a/src/parser/prismparser/PrismGrammar.h b/src/parser/prismparser/PrismGrammar.h index 5844659be..a512befb9 100644 --- a/src/parser/prismparser/PrismGrammar.h +++ b/src/parser/prismparser/PrismGrammar.h @@ -54,6 +54,7 @@ public: private: std::shared_ptr state; + struct qi::symbols moduleMap_; // The starting point of the grammar. qi::rule< diff --git a/src/parser/prismparser/Tokens.h b/src/parser/prismparser/Tokens.h index bd246d358..bbf7e8418 100644 --- a/src/parser/prismparser/Tokens.h +++ b/src/parser/prismparser/Tokens.h @@ -12,9 +12,10 @@ namespace storm { namespace parser { namespace prism { - - // A structure mapping the textual representation of a model type to the model type - // representation of the intermediate representation. + /*! + * A structure mapping the textual representation of a model type to the model type + * representation of the intermediate representation. + */ struct modelTypeStruct : qi::symbols { modelTypeStruct() { add @@ -27,7 +28,9 @@ namespace prism { }; - // A structure defining the keywords that are not allowed to be chosen as identifiers. + /*! + * A structure defining the keywords that are not allowed to be chosen as identifiers. + */ struct keywordsStruct : qi::symbols { keywordsStruct() { add @@ -48,8 +51,10 @@ namespace prism { } }; - // A structure mapping the textual representation of a binary relation to the representation - // of the intermediate representation. + /*! + * A structure mapping the textual representation of a binary relation to the representation + * of the intermediate representation. + */ struct relationalOperatorStruct : qi::symbols { relationalOperatorStruct() { add diff --git a/src/parser/prismparser/VariableState.h b/src/parser/prismparser/VariableState.h index 620c029ff..1d13cc270 100644 --- a/src/parser/prismparser/VariableState.h +++ b/src/parser/prismparser/VariableState.h @@ -23,43 +23,104 @@ using namespace storm::ir::expressions; template std::ostream& operator<<(std::ostream& out, qi::symbols& symbols); +/*! + * This class contains the state that is needed during the parsing of a prism model. + */ struct VariableState : public storm::ir::VariableAdder { -public: VariableState(bool firstRun = true); - -public: + + /*! + * Indicator, if we are still in the first run. + */ bool firstRun; + /*! + * A parser for all reserved keywords. + */ keywordsStruct keywords; - // Used for indexing the variables. + /*! + * Internal counter for the index of the next new boolean variable. + */ uint_fast64_t nextBooleanVariableIndex; + /*! + * Internal counter for the index of the next new integer variable. + */ uint_fast64_t nextIntegerVariableIndex; // Structures mapping variable and constant names to the corresponding expression nodes of // the intermediate representation. struct qi::symbols> integerVariables_, booleanVariables_; struct qi::symbols> integerConstants_, booleanConstants_, doubleConstants_; - struct qi::symbols moduleMap_; // A structure representing the identity function over identifier names. struct variableNamesStruct : qi::symbols { } integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_, localBooleanVariables_, localIntegerVariables_, assignedLocalBooleanVariables_, assignedLocalIntegerVariables_; -public: + + /*! + * Add a new boolean variable with the given name. + * @param name Name of the variable. + * @return Index of the variable. + */ uint_fast64_t addBooleanVariable(const std::string& name); + /*! + * Add a new integer variable with the given name and constraints. + * @param name Name of the variable. + * @param lower Lower bound for the variable value. + * @param upper Upper bound for the variable value. + * @return Index of the variable. + */ uint_fast64_t addIntegerVariable(const std::string& name, const std::shared_ptr lower, const std::shared_ptr upper); + /*! + * Retrieve boolean Variable with given name. + * @param name Variable name. + * @returns Variable. + */ std::shared_ptr getBooleanVariable(const std::string& name); + /*! + * Retrieve integer Variable with given name. + * @param name Variable name. + * @returns Variable. + */ std::shared_ptr getIntegerVariable(const std::string& name); + /*! + * Retrieve any Variable with given name. + * @param name Variable name. + * @returns Variable. + */ std::shared_ptr getVariable(const std::string& name); + /*! + * Perform operations necessary for a module renaming. + * This includes creating new variables and constants. + * @param renaming String mapping for renaming operation. + */ void performRenaming(const std::map& renaming); + /*! + * Start with a new module. + * Clears sets of local variables. + */ void startModule(); + /*! + * Check if given string is a free identifier. + * @param s String. + * @returns If s is a free identifier. + */ bool isFreeIdentifier(std::string& s) const; + /*! + * Check if given string is a valid identifier. + * @param s String. + * @returns If s is a valid identifier. + */ bool isIdentifier(std::string& s) const; + /*! + * Prepare state to proceed to second parser run. + * Clears constants. + */ void prepareForSecondRun(); }; From 21e6ee70b9e0923b62b25a831ee25c23d84c0244 Mon Sep 17 00:00:00 2001 From: Lanchid Date: Tue, 28 May 2013 12:03:16 +0200 Subject: [PATCH 152/152] Added static asserts to ensure that sub formulas are formulas ;) --- src/formula/abstract/And.h | 5 +++++ src/formula/abstract/BoundedEventually.h | 4 ++++ src/formula/abstract/BoundedNaryUntil.h | 4 ++++ src/formula/abstract/BoundedUntil.h | 4 ++++ src/formula/abstract/Eventually.h | 4 ++++ src/formula/abstract/Globally.h | 4 ++++ src/formula/abstract/Next.h | 4 ++++ src/formula/abstract/Not.h | 4 ++++ src/formula/abstract/Or.h | 4 ++++ src/formula/abstract/PathBoundOperator.h | 4 ++++ src/formula/abstract/PathNoBoundOperator.h | 6 ++++++ src/formula/abstract/ProbabilisticBoundOperator.h | 4 ++++ src/formula/abstract/ProbabilisticNoBoundOperator.h | 5 +++++ src/formula/abstract/RewardBoundOperator.h | 4 ++++ src/formula/abstract/RewardNoBoundOperator.h | 5 +++++ src/formula/abstract/StateBoundOperator.h | 4 ++++ src/formula/abstract/StateNoBoundOperator.h | 5 +++++ src/formula/abstract/SteadyStateBoundOperator.h | 4 ++++ src/formula/abstract/SteadyStateNoBoundOperator.h | 5 +++++ src/formula/abstract/TimeBoundedEventually.h | 5 +++++ src/formula/abstract/TimeBoundedUntil.h | 5 +++++ src/formula/abstract/Until.h | 4 ++++ 22 files changed, 97 insertions(+) diff --git a/src/formula/abstract/And.h b/src/formula/abstract/And.h index 3442d62a9..34d4109e2 100644 --- a/src/formula/abstract/And.h +++ b/src/formula/abstract/And.h @@ -12,6 +12,7 @@ #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/ForwardDeclarations.h" #include +#include namespace storm { namespace property { @@ -38,6 +39,10 @@ namespace abstract { template class And : public virtual AbstractFormula { + // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::And has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor. diff --git a/src/formula/abstract/BoundedEventually.h b/src/formula/abstract/BoundedEventually.h index 420dbfff4..25a710b5b 100644 --- a/src/formula/abstract/BoundedEventually.h +++ b/src/formula/abstract/BoundedEventually.h @@ -41,6 +41,10 @@ namespace abstract { template class BoundedEventually : public virtual AbstractFormula { + // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::BoundedEventually has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/BoundedNaryUntil.h b/src/formula/abstract/BoundedNaryUntil.h index ccfe2ab17..04d4cc53e 100644 --- a/src/formula/abstract/BoundedNaryUntil.h +++ b/src/formula/abstract/BoundedNaryUntil.h @@ -45,6 +45,10 @@ namespace abstract { template class BoundedNaryUntil : public virtual AbstractFormula { + // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::BoundedNaryUntil has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/BoundedUntil.h b/src/formula/abstract/BoundedUntil.h index 33cc4f87a..d7ba66a37 100644 --- a/src/formula/abstract/BoundedUntil.h +++ b/src/formula/abstract/BoundedUntil.h @@ -39,6 +39,10 @@ namespace abstract { template class BoundedUntil : public virtual AbstractFormula { + // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::BoundedUntil has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/Eventually.h b/src/formula/abstract/Eventually.h index aa706c311..54754df52 100644 --- a/src/formula/abstract/Eventually.h +++ b/src/formula/abstract/Eventually.h @@ -38,6 +38,10 @@ namespace abstract { template class Eventually : public virtual AbstractFormula { + // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::Eventually has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/Globally.h b/src/formula/abstract/Globally.h index 4e0ab0f22..6d3ddb4aa 100644 --- a/src/formula/abstract/Globally.h +++ b/src/formula/abstract/Globally.h @@ -39,6 +39,10 @@ namespace abstract { template class Globally : public virtual AbstractFormula { + // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::Globally has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/Next.h b/src/formula/abstract/Next.h index 0688e518b..bf049ad1b 100644 --- a/src/formula/abstract/Next.h +++ b/src/formula/abstract/Next.h @@ -38,6 +38,10 @@ namespace abstract { template class Next : public virtual AbstractFormula { + // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::Next has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/Not.h b/src/formula/abstract/Not.h index 6c92e7672..473ca7c64 100644 --- a/src/formula/abstract/Not.h +++ b/src/formula/abstract/Not.h @@ -36,6 +36,10 @@ namespace abstract { template class Not : public virtual AbstractFormula { + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::Not has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/Or.h b/src/formula/abstract/Or.h index 569939c2c..071173c4a 100644 --- a/src/formula/abstract/Or.h +++ b/src/formula/abstract/Or.h @@ -36,6 +36,10 @@ namespace abstract { template class Or : public virtual AbstractFormula { + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::Or has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor. diff --git a/src/formula/abstract/PathBoundOperator.h b/src/formula/abstract/PathBoundOperator.h index 03454b3c5..39f038e30 100644 --- a/src/formula/abstract/PathBoundOperator.h +++ b/src/formula/abstract/PathBoundOperator.h @@ -48,6 +48,10 @@ namespace abstract { template class PathBoundOperator : public virtual AbstractFormula, public OptimizingOperator { + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::PathBoundOperator has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Constructor for non-optimizing operator. diff --git a/src/formula/abstract/PathNoBoundOperator.h b/src/formula/abstract/PathNoBoundOperator.h index 827b6cfa1..509c12cf3 100644 --- a/src/formula/abstract/PathNoBoundOperator.h +++ b/src/formula/abstract/PathNoBoundOperator.h @@ -51,6 +51,12 @@ namespace abstract { */ template class PathNoBoundOperator: public virtual AbstractFormula, public OptimizingOperator { + + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::PathNoBoundOperator has to be a subtype of storm::property::abstract::AbstractFormula"); + + public: /*! * Empty constructor diff --git a/src/formula/abstract/ProbabilisticBoundOperator.h b/src/formula/abstract/ProbabilisticBoundOperator.h index d940dccc2..d9b14b183 100644 --- a/src/formula/abstract/ProbabilisticBoundOperator.h +++ b/src/formula/abstract/ProbabilisticBoundOperator.h @@ -44,6 +44,10 @@ namespace abstract { template class ProbabilisticBoundOperator : public PathBoundOperator { + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::ProbabilisticBoundOperator has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/ProbabilisticNoBoundOperator.h b/src/formula/abstract/ProbabilisticNoBoundOperator.h index e1f837ee9..9b276f976 100644 --- a/src/formula/abstract/ProbabilisticNoBoundOperator.h +++ b/src/formula/abstract/ProbabilisticNoBoundOperator.h @@ -49,6 +49,11 @@ namespace abstract { */ template class ProbabilisticNoBoundOperator: public PathNoBoundOperator { + + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::ProbabilisticNoBoundOperator has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/RewardBoundOperator.h b/src/formula/abstract/RewardBoundOperator.h index 5df7be02c..961c11f21 100644 --- a/src/formula/abstract/RewardBoundOperator.h +++ b/src/formula/abstract/RewardBoundOperator.h @@ -39,6 +39,10 @@ namespace abstract { template class RewardBoundOperator : public PathBoundOperator { + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::RewardBoundOperator has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/RewardNoBoundOperator.h b/src/formula/abstract/RewardNoBoundOperator.h index f9dbae5b7..72fb06f6f 100644 --- a/src/formula/abstract/RewardNoBoundOperator.h +++ b/src/formula/abstract/RewardNoBoundOperator.h @@ -48,6 +48,11 @@ namespace abstract { */ template class RewardNoBoundOperator: public PathNoBoundOperator { + + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::RewardNoBoundOperator has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/StateBoundOperator.h b/src/formula/abstract/StateBoundOperator.h index c2f869b9e..56f6b86d9 100644 --- a/src/formula/abstract/StateBoundOperator.h +++ b/src/formula/abstract/StateBoundOperator.h @@ -43,6 +43,10 @@ namespace abstract { template class StateBoundOperator : public virtual AbstractFormula { + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::StateBoundOperator has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! diff --git a/src/formula/abstract/StateNoBoundOperator.h b/src/formula/abstract/StateNoBoundOperator.h index 9696f597d..2fb40145f 100644 --- a/src/formula/abstract/StateNoBoundOperator.h +++ b/src/formula/abstract/StateNoBoundOperator.h @@ -49,6 +49,11 @@ namespace abstract { */ template class StateNoBoundOperator: public virtual AbstractFormula { + + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::StateNoBoundOperator has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/SteadyStateBoundOperator.h b/src/formula/abstract/SteadyStateBoundOperator.h index 2c5d33bd4..3bbb7f88c 100644 --- a/src/formula/abstract/SteadyStateBoundOperator.h +++ b/src/formula/abstract/SteadyStateBoundOperator.h @@ -32,6 +32,10 @@ namespace abstract { template class SteadyStateBoundOperator : public StateBoundOperator { + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::SteadyStateBoundOperator has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/SteadyStateNoBoundOperator.h b/src/formula/abstract/SteadyStateNoBoundOperator.h index 4831c1743..88fe73ead 100644 --- a/src/formula/abstract/SteadyStateNoBoundOperator.h +++ b/src/formula/abstract/SteadyStateNoBoundOperator.h @@ -29,6 +29,11 @@ namespace abstract { */ template class SteadyStateNoBoundOperator: public StateNoBoundOperator { + + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::SteadyStateNoBoundOperator has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor diff --git a/src/formula/abstract/TimeBoundedEventually.h b/src/formula/abstract/TimeBoundedEventually.h index 362692ba4..23d0fd74f 100644 --- a/src/formula/abstract/TimeBoundedEventually.h +++ b/src/formula/abstract/TimeBoundedEventually.h @@ -25,6 +25,11 @@ namespace abstract { */ template class TimeBoundedEventually: public storm::property::abstract::TimeBoundedOperator { + + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::TimeBoundedEventually has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /** * Simple constructor: Only sets the bounds diff --git a/src/formula/abstract/TimeBoundedUntil.h b/src/formula/abstract/TimeBoundedUntil.h index 823ac8fd0..146c82cd1 100644 --- a/src/formula/abstract/TimeBoundedUntil.h +++ b/src/formula/abstract/TimeBoundedUntil.h @@ -25,6 +25,11 @@ namespace abstract { */ template class TimeBoundedUntil: public TimeBoundedOperator { + + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::TimeBoundedUntil has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /** * Constructor providing bounds only; diff --git a/src/formula/abstract/Until.h b/src/formula/abstract/Until.h index 5037ad018..1df330926 100644 --- a/src/formula/abstract/Until.h +++ b/src/formula/abstract/Until.h @@ -38,6 +38,10 @@ namespace abstract { template class Until : public virtual AbstractFormula { + // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. + static_assert(std::is_base_of, FormulaType>::value, + "Instantiaton of FormulaType for storm::property::abstract::Until has to be a subtype of storm::property::abstract::AbstractFormula"); + public: /*! * Empty constructor